From 9966985d896629eede849a84f18e406d1164a16c Mon Sep 17 00:00:00 2001
From: William Joye <wjoye@cfa.harvard.edu>
Date: Tue, 18 Oct 2016 13:31:11 -0400
Subject: Squashed 'tcl8.6/' content from commit fcdc201

git-subtree-dir: tcl8.6
git-subtree-split: fcdc2019beb26eb8141c5ffc289e8de28bd07aa5
---
 .fossil-settings/binary-glob                       |     3 +
 .fossil-settings/crnl-glob                         |    10 +
 .fossil-settings/encoding-glob                     |    10 +
 .fossil-settings/ignore-glob                       |    24 +
 .project                                           |    11 +
 .settings/org.eclipse.core.resources.prefs         |     2 +
 .settings/org.eclipse.core.runtime.prefs           |     2 +
 ChangeLog                                          |  8856 +++++
 ChangeLog.1999                                     |  2634 ++
 ChangeLog.2000                                     |  2539 ++
 ChangeLog.2001                                     |  3629 ++
 ChangeLog.2002                                     |  4741 +++
 ChangeLog.2003                                     |  3349 ++
 ChangeLog.2004                                     |  4619 +++
 ChangeLog.2005                                     |  3822 ++
 ChangeLog.2007                                     |  5921 +++
 ChangeLog.2008                                     |  3796 ++
 README                                             |   185 +
 changes                                            |  8700 +++++
 compat/README                                      |     6 +
 compat/dirent.h                                    |    21 +
 compat/dirent2.h                                   |    53 +
 compat/dlfcn.h                                     |    58 +
 compat/fake-rfc2553.c                              |   266 +
 compat/fake-rfc2553.h                              |   170 +
 compat/fixstrtod.c                                 |    36 +
 compat/float.h                                     |    14 +
 compat/gettod.c                                    |    30 +
 compat/memcmp.c                                    |    64 +
 compat/mkstemp.c                                   |    78 +
 compat/opendir.c                                   |   110 +
 compat/stdlib.h                                    |    36 +
 compat/string.h                                    |    57 +
 compat/strncasecmp.c                               |   136 +
 compat/strstr.c                                    |    70 +
 compat/strtod.c                                    |   252 +
 compat/strtol.c                                    |    77 +
 compat/strtoul.c                                   |   214 +
 compat/unistd.h                                    |    76 +
 compat/waitpid.c                                   |   168 +
 compat/zlib/CMakeLists.txt                         |   249 +
 compat/zlib/ChangeLog                              |  1472 +
 compat/zlib/FAQ                                    |   368 +
 compat/zlib/INDEX                                  |    68 +
 compat/zlib/Makefile                               |     5 +
 compat/zlib/Makefile.in                            |   288 +
 compat/zlib/README                                 |   115 +
 compat/zlib/adler32.c                              |   179 +
 compat/zlib/amiga/Makefile.pup                     |    69 +
 compat/zlib/amiga/Makefile.sas                     |    68 +
 compat/zlib/as400/bndsrc                           |   215 +
 compat/zlib/as400/compile.clp                      |   110 +
 compat/zlib/as400/readme.txt                       |   115 +
 compat/zlib/as400/zlib.inc                         |   451 +
 compat/zlib/compress.c                             |    80 +
 compat/zlib/configure                              |   831 +
 compat/zlib/contrib/README.contrib                 |    78 +
 compat/zlib/contrib/ada/buffer_demo.adb            |   106 +
 compat/zlib/contrib/ada/mtest.adb                  |   156 +
 compat/zlib/contrib/ada/read.adb                   |   156 +
 compat/zlib/contrib/ada/readme.txt                 |    65 +
 compat/zlib/contrib/ada/test.adb                   |   463 +
 compat/zlib/contrib/ada/zlib-streams.adb           |   225 +
 compat/zlib/contrib/ada/zlib-streams.ads           |   114 +
 compat/zlib/contrib/ada/zlib-thin.adb              |   141 +
 compat/zlib/contrib/ada/zlib-thin.ads              |   450 +
 compat/zlib/contrib/ada/zlib.adb                   |   701 +
 compat/zlib/contrib/ada/zlib.ads                   |   328 +
 compat/zlib/contrib/ada/zlib.gpr                   |    20 +
 compat/zlib/contrib/amd64/amd64-match.S            |   452 +
 compat/zlib/contrib/asm686/README.686              |    51 +
 compat/zlib/contrib/asm686/match.S                 |   357 +
 compat/zlib/contrib/blast/Makefile                 |     8 +
 compat/zlib/contrib/blast/README                   |     4 +
 compat/zlib/contrib/blast/blast.c                  |   446 +
 compat/zlib/contrib/blast/blast.h                  |    75 +
 compat/zlib/contrib/blast/test.pk                  |   Bin 0 -> 8 bytes
 compat/zlib/contrib/blast/test.txt                 |     1 +
 compat/zlib/contrib/delphi/ZLib.pas                |   557 +
 compat/zlib/contrib/delphi/ZLibConst.pas           |    11 +
 compat/zlib/contrib/delphi/readme.txt              |    76 +
 compat/zlib/contrib/delphi/zlibd32.mak             |    99 +
 compat/zlib/contrib/dotzlib/DotZLib.build          |    33 +
 compat/zlib/contrib/dotzlib/DotZLib.chm            |   Bin 0 -> 72726 bytes
 compat/zlib/contrib/dotzlib/DotZLib.sln            |    21 +
 .../zlib/contrib/dotzlib/DotZLib/AssemblyInfo.cs   |    58 +
 .../zlib/contrib/dotzlib/DotZLib/ChecksumImpl.cs   |   202 +
 .../zlib/contrib/dotzlib/DotZLib/CircularBuffer.cs |    83 +
 compat/zlib/contrib/dotzlib/DotZLib/CodecBase.cs   |   198 +
 compat/zlib/contrib/dotzlib/DotZLib/Deflater.cs    |   106 +
 compat/zlib/contrib/dotzlib/DotZLib/DotZLib.cs     |   288 +
 compat/zlib/contrib/dotzlib/DotZLib/DotZLib.csproj |   141 +
 compat/zlib/contrib/dotzlib/DotZLib/GZipStream.cs  |   301 +
 compat/zlib/contrib/dotzlib/DotZLib/Inflater.cs    |   105 +
 compat/zlib/contrib/dotzlib/DotZLib/UnitTests.cs   |   274 +
 compat/zlib/contrib/dotzlib/LICENSE_1_0.txt        |    23 +
 compat/zlib/contrib/dotzlib/readme.txt             |    58 +
 compat/zlib/contrib/gcc_gvmat64/gvmat64.S          |   574 +
 compat/zlib/contrib/infback9/README                |     1 +
 compat/zlib/contrib/infback9/infback9.c            |   615 +
 compat/zlib/contrib/infback9/infback9.h            |    37 +
 compat/zlib/contrib/infback9/inffix9.h             |   107 +
 compat/zlib/contrib/infback9/inflate9.h            |    47 +
 compat/zlib/contrib/infback9/inftree9.c            |   324 +
 compat/zlib/contrib/infback9/inftree9.h            |    61 +
 compat/zlib/contrib/inflate86/inffas86.c           |  1157 +
 compat/zlib/contrib/inflate86/inffast.S            |  1368 +
 compat/zlib/contrib/iostream/test.cpp              |    24 +
 compat/zlib/contrib/iostream/zfstream.cpp          |   329 +
 compat/zlib/contrib/iostream/zfstream.h            |   128 +
 compat/zlib/contrib/iostream2/zstream.h            |   307 +
 compat/zlib/contrib/iostream2/zstream_test.cpp     |    25 +
 compat/zlib/contrib/iostream3/README               |    35 +
 compat/zlib/contrib/iostream3/TODO                 |    17 +
 compat/zlib/contrib/iostream3/test.cc              |    50 +
 compat/zlib/contrib/iostream3/zfstream.cc          |   479 +
 compat/zlib/contrib/iostream3/zfstream.h           |   466 +
 compat/zlib/contrib/masmx64/bld_ml64.bat           |     2 +
 compat/zlib/contrib/masmx64/gvmat64.asm            |   553 +
 compat/zlib/contrib/masmx64/inffas8664.c           |   186 +
 compat/zlib/contrib/masmx64/inffasx64.asm          |   396 +
 compat/zlib/contrib/masmx64/readme.txt             |    31 +
 compat/zlib/contrib/masmx86/bld_ml32.bat           |     2 +
 compat/zlib/contrib/masmx86/inffas32.asm           |  1080 +
 compat/zlib/contrib/masmx86/match686.asm           |   479 +
 compat/zlib/contrib/masmx86/readme.txt             |    27 +
 compat/zlib/contrib/minizip/Makefile               |    25 +
 compat/zlib/contrib/minizip/Makefile.am            |    45 +
 compat/zlib/contrib/minizip/MiniZip64_Changes.txt  |     6 +
 compat/zlib/contrib/minizip/MiniZip64_info.txt     |    74 +
 compat/zlib/contrib/minizip/configure.ac           |    32 +
 compat/zlib/contrib/minizip/crypt.h                |   131 +
 compat/zlib/contrib/minizip/ioapi.c                |   247 +
 compat/zlib/contrib/minizip/ioapi.h                |   208 +
 compat/zlib/contrib/minizip/iowin32.c              |   461 +
 compat/zlib/contrib/minizip/iowin32.h              |    28 +
 compat/zlib/contrib/minizip/make_vms.com           |    25 +
 compat/zlib/contrib/minizip/miniunz.c              |   660 +
 compat/zlib/contrib/minizip/miniunzip.1            |    63 +
 compat/zlib/contrib/minizip/minizip.1              |    46 +
 compat/zlib/contrib/minizip/minizip.c              |   520 +
 compat/zlib/contrib/minizip/minizip.pc.in          |    12 +
 compat/zlib/contrib/minizip/mztools.c              |   291 +
 compat/zlib/contrib/minizip/mztools.h              |    37 +
 compat/zlib/contrib/minizip/unzip.c                |  2125 ++
 compat/zlib/contrib/minizip/unzip.h                |   437 +
 compat/zlib/contrib/minizip/zip.c                  |  2007 +
 compat/zlib/contrib/minizip/zip.h                  |   362 +
 compat/zlib/contrib/pascal/example.pas             |   599 +
 compat/zlib/contrib/pascal/readme.txt              |    76 +
 compat/zlib/contrib/pascal/zlibd32.mak             |    99 +
 compat/zlib/contrib/pascal/zlibpas.pas             |   276 +
 compat/zlib/contrib/puff/Makefile                  |    42 +
 compat/zlib/contrib/puff/README                    |    63 +
 compat/zlib/contrib/puff/puff.c                    |   840 +
 compat/zlib/contrib/puff/puff.h                    |    35 +
 compat/zlib/contrib/puff/pufftest.c                |   165 +
 compat/zlib/contrib/puff/zeros.raw                 |   Bin 0 -> 2517 bytes
 compat/zlib/contrib/testzlib/testzlib.c            |   275 +
 compat/zlib/contrib/testzlib/testzlib.txt          |    10 +
 compat/zlib/contrib/untgz/Makefile                 |    14 +
 compat/zlib/contrib/untgz/Makefile.msc             |    17 +
 compat/zlib/contrib/untgz/untgz.c                  |   674 +
 compat/zlib/contrib/vstudio/readme.txt             |    65 +
 compat/zlib/contrib/vstudio/vc10/miniunz.vcxproj   |   310 +
 .../contrib/vstudio/vc10/miniunz.vcxproj.filters   |    22 +
 compat/zlib/contrib/vstudio/vc10/minizip.vcxproj   |   307 +
 .../contrib/vstudio/vc10/minizip.vcxproj.filters   |    22 +
 compat/zlib/contrib/vstudio/vc10/testzlib.vcxproj  |   420 +
 .../contrib/vstudio/vc10/testzlib.vcxproj.filters  |    58 +
 .../zlib/contrib/vstudio/vc10/testzlibdll.vcxproj  |   310 +
 .../vstudio/vc10/testzlibdll.vcxproj.filters       |    22 +
 compat/zlib/contrib/vstudio/vc10/zlib.rc           |    32 +
 compat/zlib/contrib/vstudio/vc10/zlibstat.vcxproj  |   473 +
 .../contrib/vstudio/vc10/zlibstat.vcxproj.filters  |    77 +
 compat/zlib/contrib/vstudio/vc10/zlibvc.def        |   143 +
 compat/zlib/contrib/vstudio/vc10/zlibvc.sln        |   135 +
 compat/zlib/contrib/vstudio/vc10/zlibvc.vcxproj    |   657 +
 .../contrib/vstudio/vc10/zlibvc.vcxproj.filters    |   118 +
 compat/zlib/contrib/vstudio/vc11/miniunz.vcxproj   |   314 +
 compat/zlib/contrib/vstudio/vc11/minizip.vcxproj   |   311 +
 compat/zlib/contrib/vstudio/vc11/testzlib.vcxproj  |   426 +
 .../zlib/contrib/vstudio/vc11/testzlibdll.vcxproj  |   314 +
 compat/zlib/contrib/vstudio/vc11/zlib.rc           |    32 +
 compat/zlib/contrib/vstudio/vc11/zlibstat.vcxproj  |   464 +
 compat/zlib/contrib/vstudio/vc11/zlibvc.def        |   143 +
 compat/zlib/contrib/vstudio/vc11/zlibvc.sln        |   117 +
 compat/zlib/contrib/vstudio/vc11/zlibvc.vcxproj    |   688 +
 compat/zlib/contrib/vstudio/vc9/miniunz.vcproj     |   565 +
 compat/zlib/contrib/vstudio/vc9/minizip.vcproj     |   562 +
 compat/zlib/contrib/vstudio/vc9/testzlib.vcproj    |   852 +
 compat/zlib/contrib/vstudio/vc9/testzlibdll.vcproj |   565 +
 compat/zlib/contrib/vstudio/vc9/zlib.rc            |    32 +
 compat/zlib/contrib/vstudio/vc9/zlibstat.vcproj    |   835 +
 compat/zlib/contrib/vstudio/vc9/zlibvc.def         |   143 +
 compat/zlib/contrib/vstudio/vc9/zlibvc.sln         |   144 +
 compat/zlib/contrib/vstudio/vc9/zlibvc.vcproj      |  1156 +
 compat/zlib/crc32.c                                |   425 +
 compat/zlib/crc32.h                                |   441 +
 compat/zlib/deflate.c                              |  1967 +
 compat/zlib/deflate.h                              |   346 +
 compat/zlib/doc/algorithm.txt                      |   209 +
 compat/zlib/doc/rfc1950.txt                        |   619 +
 compat/zlib/doc/rfc1951.txt                        |   955 +
 compat/zlib/doc/rfc1952.txt                        |   675 +
 compat/zlib/doc/txtvsbin.txt                       |   107 +
 compat/zlib/examples/README.examples               |    49 +
 compat/zlib/examples/enough.c                      |   572 +
 compat/zlib/examples/fitblk.c                      |   233 +
 compat/zlib/examples/gun.c                         |   702 +
 compat/zlib/examples/gzappend.c                    |   504 +
 compat/zlib/examples/gzjoin.c                      |   449 +
 compat/zlib/examples/gzlog.c                       |  1059 +
 compat/zlib/examples/gzlog.h                       |    91 +
 compat/zlib/examples/zlib_how.html                 |   545 +
 compat/zlib/examples/zpipe.c                       |   205 +
 compat/zlib/examples/zran.c                        |   409 +
 compat/zlib/gzclose.c                              |    25 +
 compat/zlib/gzguts.h                               |   209 +
 compat/zlib/gzlib.c                                |   634 +
 compat/zlib/gzread.c                               |   594 +
 compat/zlib/gzwrite.c                              |   577 +
 compat/zlib/infback.c                              |   640 +
 compat/zlib/inffast.c                              |   340 +
 compat/zlib/inffast.h                              |    11 +
 compat/zlib/inffixed.h                             |    94 +
 compat/zlib/inflate.c                              |  1512 +
 compat/zlib/inflate.h                              |   122 +
 compat/zlib/inftrees.c                             |   306 +
 compat/zlib/inftrees.h                             |    62 +
 compat/zlib/make_vms.com                           |   867 +
 compat/zlib/msdos/Makefile.bor                     |   115 +
 compat/zlib/msdos/Makefile.dj2                     |   104 +
 compat/zlib/msdos/Makefile.emx                     |    69 +
 compat/zlib/msdos/Makefile.msc                     |   112 +
 compat/zlib/msdos/Makefile.tc                      |   100 +
 compat/zlib/nintendods/Makefile                    |   126 +
 compat/zlib/nintendods/README                      |     5 +
 compat/zlib/old/Makefile.emx                       |    69 +
 compat/zlib/old/Makefile.riscos                    |   151 +
 compat/zlib/old/README                             |     3 +
 compat/zlib/old/descrip.mms                        |    48 +
 compat/zlib/old/os2/Makefile.os2                   |   136 +
 compat/zlib/old/os2/zlib.def                       |    51 +
 compat/zlib/old/visual-basic.txt                   |   160 +
 compat/zlib/qnx/package.qpg                        |   141 +
 compat/zlib/test/example.c                         |   601 +
 compat/zlib/test/infcover.c                        |   671 +
 compat/zlib/test/minigzip.c                        |   651 +
 compat/zlib/treebuild.xml                          |   116 +
 compat/zlib/trees.c                                |  1226 +
 compat/zlib/trees.h                                |   128 +
 compat/zlib/uncompr.c                              |    59 +
 compat/zlib/watcom/watcom_f.mak                    |    43 +
 compat/zlib/watcom/watcom_l.mak                    |    43 +
 compat/zlib/win32/DLL_FAQ.txt                      |   397 +
 compat/zlib/win32/Makefile.bor                     |   110 +
 compat/zlib/win32/Makefile.gcc                     |   182 +
 compat/zlib/win32/Makefile.msc                     |   163 +
 compat/zlib/win32/README-WIN32.txt                 |   103 +
 compat/zlib/win32/README.txt                       |    60 +
 compat/zlib/win32/USAGE.txt                        |    89 +
 compat/zlib/win32/VisualC.txt                      |     3 +
 compat/zlib/win32/zdll.lib                         |   Bin 0 -> 15658 bytes
 compat/zlib/win32/zlib.def                         |    86 +
 compat/zlib/win32/zlib1.dll                        |   Bin 0 -> 107520 bytes
 compat/zlib/win32/zlib1.rc                         |    40 +
 compat/zlib/win64/libz.dll.a                       |   Bin 0 -> 46874 bytes
 compat/zlib/win64/zdll.lib                         |   Bin 0 -> 15288 bytes
 compat/zlib/win64/zlib1.dll                        |   Bin 0 -> 112640 bytes
 compat/zlib/zconf.h                                |   511 +
 compat/zlib/zconf.h.cmakein                        |   513 +
 compat/zlib/zconf.h.in                             |   511 +
 compat/zlib/zlib.3                                 |   151 +
 compat/zlib/zlib.3.pdf                             |   Bin 0 -> 8734 bytes
 compat/zlib/zlib.h                                 |  1768 +
 compat/zlib/zlib.map                               |    83 +
 compat/zlib/zlib.pc.cmakein                        |    13 +
 compat/zlib/zlib.pc.in                             |    13 +
 compat/zlib/zlib2ansi                              |   152 +
 compat/zlib/zutil.c                                |   324 +
 compat/zlib/zutil.h                                |   253 +
 doc/Access.3                                       |    71 +
 doc/AddErrInfo.3                                   |   312 +
 doc/Alloc.3                                        |    92 +
 doc/AllowExc.3                                     |    44 +
 doc/AppInit.3                                      |    83 +
 doc/AssocData.3                                    |    87 +
 doc/Async.3                                        |   161 +
 doc/BackgdErr.3                                    |    78 +
 doc/Backslash.3                                    |    47 +
 doc/BoolObj.3                                      |    95 +
 doc/ByteArrObj.3                                   |    91 +
 doc/CallDel.3                                      |    67 +
 doc/Cancel.3                                       |    74 +
 doc/ChnlStack.3                                    |    97 +
 doc/Class.3                                        |   237 +
 doc/CmdCmplt.3                                     |    34 +
 doc/Concat.3                                       |    51 +
 doc/CrtChannel.3                                   |   928 +
 doc/CrtChnlHdlr.3                                  |    89 +
 doc/CrtCloseHdlr.3                                 |    55 +
 doc/CrtCommand.3                                   |   143 +
 doc/CrtFileHdlr.3                                  |    91 +
 doc/CrtInterp.3                                    |   150 +
 doc/CrtMathFnc.3                                   |   162 +
 doc/CrtObjCmd.3                                    |   302 +
 doc/CrtSlave.3                                     |   236 +
 doc/CrtTimerHdlr.3                                 |    76 +
 doc/CrtTrace.3                                     |   191 +
 doc/DString.3                                      |   153 +
 doc/DetachPids.3                                   |    75 +
 doc/DictObj.3                                      |   234 +
 doc/DoOneEvent.3                                   |   106 +
 doc/DoWhenIdle.3                                   |    87 +
 doc/DoubleObj.3                                    |    64 +
 doc/DumpActiveMemory.3                             |    68 +
 doc/Encoding.3                                     |   558 +
 doc/Ensemble.3                                     |   219 +
 doc/Environment.3                                  |    38 +
 doc/Eval.3                                         |   211 +
 doc/Exit.3                                         |   140 +
 doc/ExprLong.3                                     |   106 +
 doc/ExprLongObj.3                                  |   106 +
 doc/FileSystem.3                                   |  1644 +
 doc/FindExec.3                                     |    63 +
 doc/GetCwd.3                                       |    52 +
 doc/GetHostName.3                                  |    27 +
 doc/GetIndex.3                                     |   104 +
 doc/GetInt.3                                       |    86 +
 doc/GetOpnFl.3                                     |    58 +
 doc/GetStdChan.3                                   |    86 +
 doc/GetTime.3                                      |   109 +
 doc/GetVersion.3                                   |    48 +
 doc/Hash.3                                         |   334 +
 doc/Init.3                                         |    34 +
 doc/InitStubs.3                                    |    89 +
 doc/IntObj.3                                       |   152 +
 doc/Interp.3                                       |   134 +
 doc/Limit.3                                        |   192 +
 doc/LinkVar.3                                      |   207 +
 doc/ListObj.3                                      |   251 +
 doc/Load.3                                         |    70 +
 doc/Method.3                                       |   251 +
 doc/NRE.3                                          |   328 +
 doc/Namespace.3                                    |   165 +
 doc/Notifier.3                                     |   635 +
 doc/OOInitStubs.3                                  |    54 +
 doc/Object.3                                       |   352 +
 doc/ObjectType.3                                   |   256 +
 doc/OpenFileChnl.3                                 |   648 +
 doc/OpenTcp.3                                      |   169 +
 doc/Panic.3                                        |    89 +
 doc/ParseArgs.3                                    |   198 +
 doc/ParseCmd.3                                     |   467 +
 doc/PkgRequire.3                                   |    97 +
 doc/Preserve.3                                     |   110 +
 doc/PrintDbl.3                                     |    51 +
 doc/RecEvalObj.3                                   |    53 +
 doc/RecordEval.3                                   |    55 +
 doc/RegConfig.3                                    |   111 +
 doc/RegExp.3                                       |   383 +
 doc/SaveResult.3                                   |   120 +
 doc/SetChanErr.3                                   |   140 +
 doc/SetErrno.3                                     |    66 +
 doc/SetRecLmt.3                                    |    53 +
 doc/SetResult.3                                    |   255 +
 doc/SetVar.3                                       |   249 +
 doc/Signal.3                                       |    41 +
 doc/Sleep.3                                        |    34 +
 doc/SourceRCFile.3                                 |    32 +
 doc/SplitList.3                                    |   188 +
 doc/SplitPath.3                                    |    97 +
 doc/StaticPkg.3                                    |    70 +
 doc/StdChannels.3                                  |   120 +
 doc/StrMatch.3                                     |    49 +
 doc/StringObj.3                                    |   387 +
 doc/SubstObj.3                                     |    68 +
 doc/TCL_MEM_DEBUG.3                                |    80 +
 doc/Tcl.n                                          |   275 +
 doc/TclZlib.3                                      |   276 +
 doc/Tcl_Main.3                                     |   196 +
 doc/Thread.3                                       |   242 +
 doc/ToUpper.3                                      |    88 +
 doc/TraceCmd.3                                     |   150 +
 doc/TraceVar.3                                     |   380 +
 doc/Translate.3                                    |    71 +
 doc/UniCharIsAlpha.3                               |    91 +
 doc/UpVar.3                                        |    74 +
 doc/Utf.3                                          |   259 +
 doc/WrongNumArgs.3                                 |    79 +
 doc/after.n                                        |   151 +
 doc/append.n                                       |    49 +
 doc/apply.n                                        |   102 +
 doc/array.n                                        |   187 +
 doc/bgerror.n                                      |    93 +
 doc/binary.n                                       |   908 +
 doc/break.n                                        |    47 +
 doc/case.n                                         |    60 +
 doc/catch.n                                        |   125 +
 doc/cd.n                                           |    43 +
 doc/chan.n                                         |   850 +
 doc/class.n                                        |   136 +
 doc/clock.n                                        |   938 +
 doc/close.n                                        |   108 +
 doc/concat.n                                       |    58 +
 doc/continue.n                                     |    47 +
 doc/copy.n                                         |    66 +
 doc/coroutine.n                                    |   205 +
 doc/dde.n                                          |   189 +
 doc/define.n                                       |   404 +
 doc/dict.n                                         |   445 +
 doc/encoding.n                                     |   115 +
 doc/eof.n                                          |    61 +
 doc/error.n                                        |    78 +
 doc/eval.n                                         |    84 +
 doc/exec.n                                         |   452 +
 doc/exit.n                                         |    51 +
 doc/expr.n                                         |   475 +
 doc/fblocked.n                                     |    67 +
 doc/fconfigure.n                                   |   289 +
 doc/fcopy.n                                        |   182 +
 doc/file.n                                         |   549 +
 doc/fileevent.n                                    |   156 +
 doc/filename.n                                     |   178 +
 doc/flush.n                                        |    45 +
 doc/for.n                                          |    87 +
 doc/foreach.n                                      |   104 +
 doc/format.n                                       |   285 +
 doc/gets.n                                         |    71 +
 doc/glob.n                                         |   267 +
 doc/global.n                                       |    58 +
 doc/history.n                                      |   102 +
 doc/http.n                                         |   647 +
 doc/if.n                                           |    88 +
 doc/incr.n                                         |    61 +
 doc/info.n                                         |   777 +
 doc/interp.n                                       |   910 +
 doc/join.n                                         |    44 +
 doc/lappend.n                                      |    49 +
 doc/lassign.n                                      |    60 +
 doc/library.n                                      |   320 +
 doc/lindex.n                                       |   125 +
 doc/linsert.n                                      |    55 +
 doc/list.n                                         |    56 +
 doc/llength.n                                      |    55 +
 doc/lmap.n                                         |    85 +
 doc/load.n                                         |   196 +
 doc/lrange.n                                       |    78 +
 doc/lrepeat.n                                      |    38 +
 doc/lreplace.n                                     |    86 +
 doc/lreverse.n                                     |    34 +
 doc/lsearch.n                                      |   220 +
 doc/lset.n                                         |   146 +
 doc/lsort.n                                        |   274 +
 doc/man.macros                                     |   267 +
 doc/mathfunc.n                                     |   305 +
 doc/mathop.n                                       |   310 +
 doc/memory.n                                       |   115 +
 doc/msgcat.n                                       |   651 +
 doc/my.n                                           |    56 +
 doc/namespace.n                                    |   969 +
 doc/next.n                                         |   208 +
 doc/object.n                                       |   128 +
 doc/open.n                                         |   430 +
 doc/package.n                                      |   370 +
 doc/packagens.n                                    |    50 +
 doc/pid.n                                          |    48 +
 doc/pkgMkIndex.n                                   |   233 +
 doc/platform.n                                     |    86 +
 doc/platform_shell.n                               |    57 +
 doc/prefix.n                                       |   116 +
 doc/proc.n                                         |   128 +
 doc/puts.n                                         |    98 +
 doc/pwd.n                                          |    39 +
 doc/re_syntax.n                                    |   858 +
 doc/read.n                                         |    89 +
 doc/refchan.n                                      |   411 +
 doc/regexp.n                                       |   208 +
 doc/registry.n                                     |   218 +
 doc/regsub.n                                       |   192 +
 doc/rename.n                                       |    45 +
 doc/return.n                                       |   326 +
 doc/safe.n                                         |   359 +
 doc/scan.n                                         |   293 +
 doc/seek.n                                         |    92 +
 doc/self.n                                         |   152 +
 doc/set.n                                          |    75 +
 doc/socket.n                                       |   235 +
 doc/source.n                                       |    71 +
 doc/split.n                                        |    93 +
 doc/string.n                                       |   485 +
 doc/subst.n                                        |   164 +
 doc/switch.n                                       |   186 +
 doc/tailcall.n                                     |    69 +
 doc/tclsh.1                                        |   149 +
 doc/tcltest.n                                      |  1259 +
 doc/tclvars.n                                      |   566 +
 doc/tell.n                                         |    48 +
 doc/throw.n                                        |    48 +
 doc/time.n                                         |    47 +
 doc/tm.n                                           |   308 +
 doc/trace.n                                        |   426 +
 doc/transchan.n                                    |   160 +
 doc/try.n                                          |   103 +
 doc/unknown.n                                      |    91 +
 doc/unload.n                                       |   172 +
 doc/unset.n                                        |    68 +
 doc/update.n                                       |    65 +
 doc/uplevel.n                                      |   103 +
 doc/upvar.n                                        |   122 +
 doc/variable.n                                     |   100 +
 doc/vwait.n                                        |   246 +
 doc/while.n                                        |    65 +
 doc/zlib.n                                         |   466 +
 generic/README                                     |     3 +
 generic/regc_color.c                               |   856 +
 generic/regc_cvec.c                                |   147 +
 generic/regc_lex.c                                 |  1195 +
 generic/regc_locale.c                              |  1260 +
 generic/regc_nfa.c                                 |  3213 ++
 generic/regcomp.c                                  |  2225 ++
 generic/regcustom.h                                |   155 +
 generic/rege_dfa.c                                 |   805 +
 generic/regerror.c                                 |   129 +
 generic/regerrs.h                                  |    20 +
 generic/regex.h                                    |   305 +
 generic/regexec.c                                  |  1335 +
 generic/regfree.c                                  |    60 +
 generic/regfronts.c                                |    91 +
 generic/regguts.h                                  |   453 +
 generic/tcl.decls                                  |  2391 ++
 generic/tcl.h                                      |  2665 ++
 generic/tclAlloc.c                                 |   759 +
 generic/tclAssembly.c                              |  4331 +++
 generic/tclAsync.c                                 |   355 +
 generic/tclBasic.c                                 |  9055 +++++
 generic/tclBinary.c                                |  2988 ++
 generic/tclCkalloc.c                               |  1328 +
 generic/tclClock.c                                 |  2079 ++
 generic/tclCmdAH.c                                 |  2953 ++
 generic/tclCmdIL.c                                 |  4533 +++
 generic/tclCmdMZ.c                                 |  4881 +++
 generic/tclCompCmds.c                              |  3511 ++
 generic/tclCompCmdsGR.c                            |  3188 ++
 generic/tclCompCmdsSZ.c                            |  4485 +++
 generic/tclCompExpr.c                              |  2806 ++
 generic/tclCompile.c                               |  4474 +++
 generic/tclCompile.h                               |  1908 +
 generic/tclConfig.c                                |   408 +
 generic/tclDTrace.d                                |   225 +
 generic/tclDate.c                                  |  2914 ++
 generic/tclDecls.h                                 |  3918 ++
 generic/tclDictObj.c                               |  3664 ++
 generic/tclDisassemble.c                           |  1636 +
 generic/tclEncoding.c                              |  3649 ++
 generic/tclEnsemble.c                              |  3665 ++
 generic/tclEnv.c                                   |   744 +
 generic/tclEvent.c                                 |  1624 +
 generic/tclExecute.c                               | 10754 ++++++
 generic/tclFCmd.c                                  |  1513 +
 generic/tclFileName.c                              |  2658 ++
 generic/tclFileSystem.h                            |    74 +
 generic/tclGet.c                                   |   156 +
 generic/tclGetDate.y                               |  1130 +
 generic/tclHash.c                                  |  1116 +
 generic/tclHistory.c                               |   230 +
 generic/tclIO.c                                    | 11250 ++++++
 generic/tclIO.h                                    |   297 +
 generic/tclIOCmd.c                                 |  2027 +
 generic/tclIOGT.c                                  |  1441 +
 generic/tclIORChan.c                               |  3292 ++
 generic/tclIORTrans.c                              |  3427 ++
 generic/tclIOSock.c                                |   291 +
 generic/tclIOUtil.c                                |  4874 +++
 generic/tclIndexObj.c                              |  1489 +
 generic/tclInt.decls                               |  1261 +
 generic/tclInt.h                                   |  4862 +++
 generic/tclIntDecls.h                              |  1370 +
 generic/tclIntPlatDecls.h                          |   567 +
 generic/tclInterp.c                                |  4825 +++
 generic/tclLink.c                                  |   636 +
 generic/tclListObj.c                               |  2040 +
 generic/tclLiteral.c                               |  1233 +
 generic/tclLoad.c                                  |  1179 +
 generic/tclLoadNone.c                              |   129 +
 generic/tclMain.c                                  |   961 +
 generic/tclNamesp.c                                |  5101 +++
 generic/tclNotify.c                                |  1141 +
 generic/tclOO.c                                    |  3037 ++
 generic/tclOO.decls                                |   218 +
 generic/tclOO.h                                    |   147 +
 generic/tclOOBasic.c                               |  1245 +
 generic/tclOOCall.c                                |  1537 +
 generic/tclOODecls.h                               |   234 +
 generic/tclOODefineCmds.c                          |  2677 ++
 generic/tclOOInfo.c                                |  1530 +
 generic/tclOOInt.h                                 |   607 +
 generic/tclOOIntDecls.h                            |   166 +
 generic/tclOOMethod.c                              |  1763 +
 generic/tclOOStubInit.c                            |    78 +
 generic/tclOOStubLib.c                             |    71 +
 generic/tclObj.c                                   |  4519 +++
 generic/tclOptimize.c                              |   444 +
 generic/tclPanic.c                                 |   170 +
 generic/tclParse.c                                 |  2534 ++
 generic/tclParse.h                                 |    17 +
 generic/tclPathObj.c                               |  2693 ++
 generic/tclPipe.c                                  |  1135 +
 generic/tclPkg.c                                   |  1923 +
 generic/tclPkgConfig.c                             |   135 +
 generic/tclPlatDecls.h                             |   122 +
 generic/tclPort.h                                  |    43 +
 generic/tclPosixStr.c                              |  1211 +
 generic/tclPreserve.c                              |   473 +
 generic/tclProc.c                                  |  2782 ++
 generic/tclRegexp.c                                |  1074 +
 generic/tclRegexp.h                                |    52 +
 generic/tclResolve.c                               |   424 +
 generic/tclResult.c                                |  1755 +
 generic/tclScan.c                                  |  1079 +
 generic/tclStrToD.c                                |  5039 +++
 generic/tclStringObj.c                             |  3128 ++
 generic/tclStringRep.h                             |    97 +
 generic/tclStringTrim.h                            |    43 +
 generic/tclStubInit.c                              |  1420 +
 generic/tclStubLib.c                               |   127 +
 generic/tclStubLibTbl.c                            |    58 +
 generic/tclTest.c                                  |  7483 ++++
 generic/tclTestObj.c                               |  1495 +
 generic/tclTestProcBodyObj.c                       |   309 +
 generic/tclThread.c                                |   538 +
 generic/tclThreadAlloc.c                           |  1185 +
 generic/tclThreadJoin.c                            |   316 +
 generic/tclThreadStorage.c                         |   373 +
 generic/tclThreadTest.c                            |  1211 +
 generic/tclTimer.c                                 |  1293 +
 generic/tclTomMath.decls                           |   238 +
 generic/tclTomMath.h                               |   832 +
 generic/tclTomMathDecls.h                          |   518 +
 generic/tclTomMathInt.h                            |     3 +
 generic/tclTomMathInterface.c                      |   310 +
 generic/tclTomMathStubLib.c                        |    79 +
 generic/tclTrace.c                                 |  3271 ++
 generic/tclUniData.c                               |  1614 +
 generic/tclUtf.c                                   |  2062 ++
 generic/tclUtil.c                                  |  4485 +++
 generic/tclVar.c                                   |  6382 ++++
 generic/tclZlib.c                                  |  4017 ++
 generic/tommath.h                                  |     1 +
 library/auto.tcl                                   |   651 +
 library/clock.tcl                                  |  4547 +++
 library/dde/pkgIndex.tcl                           |     7 +
 library/encoding/ascii.enc                         |    20 +
 library/encoding/big5.enc                          |  1516 +
 library/encoding/cp1250.enc                        |    20 +
 library/encoding/cp1251.enc                        |    20 +
 library/encoding/cp1252.enc                        |    20 +
 library/encoding/cp1253.enc                        |    20 +
 library/encoding/cp1254.enc                        |    20 +
 library/encoding/cp1255.enc                        |    20 +
 library/encoding/cp1256.enc                        |    20 +
 library/encoding/cp1257.enc                        |    20 +
 library/encoding/cp1258.enc                        |    20 +
 library/encoding/cp437.enc                         |    20 +
 library/encoding/cp737.enc                         |    20 +
 library/encoding/cp775.enc                         |    20 +
 library/encoding/cp850.enc                         |    20 +
 library/encoding/cp852.enc                         |    20 +
 library/encoding/cp855.enc                         |    20 +
 library/encoding/cp857.enc                         |    20 +
 library/encoding/cp860.enc                         |    20 +
 library/encoding/cp861.enc                         |    20 +
 library/encoding/cp862.enc                         |    20 +
 library/encoding/cp863.enc                         |    20 +
 library/encoding/cp864.enc                         |    20 +
 library/encoding/cp865.enc                         |    20 +
 library/encoding/cp866.enc                         |    20 +
 library/encoding/cp869.enc                         |    20 +
 library/encoding/cp874.enc                         |    20 +
 library/encoding/cp932.enc                         |   801 +
 library/encoding/cp936.enc                         |  2162 ++
 library/encoding/cp949.enc                         |  2128 ++
 library/encoding/cp950.enc                         |  1499 +
 library/encoding/dingbats.enc                      |    20 +
 library/encoding/ebcdic.enc                        |    19 +
 library/encoding/euc-cn.enc                        |  1397 +
 library/encoding/euc-jp.enc                        |  1353 +
 library/encoding/euc-kr.enc                        |  1533 +
 library/encoding/gb12345.enc                       |  1414 +
 library/encoding/gb1988.enc                        |    20 +
 library/encoding/gb2312-raw.enc                    |  1380 +
 library/encoding/gb2312.enc                        |  1397 +
 library/encoding/iso2022-jp.enc                    |    12 +
 library/encoding/iso2022-kr.enc                    |     7 +
 library/encoding/iso2022.enc                       |    14 +
 library/encoding/iso8859-1.enc                     |    20 +
 library/encoding/iso8859-10.enc                    |    20 +
 library/encoding/iso8859-13.enc                    |    20 +
 library/encoding/iso8859-14.enc                    |    20 +
 library/encoding/iso8859-15.enc                    |    20 +
 library/encoding/iso8859-16.enc                    |    20 +
 library/encoding/iso8859-2.enc                     |    20 +
 library/encoding/iso8859-3.enc                     |    20 +
 library/encoding/iso8859-4.enc                     |    20 +
 library/encoding/iso8859-5.enc                     |    20 +
 library/encoding/iso8859-6.enc                     |    20 +
 library/encoding/iso8859-7.enc                     |    20 +
 library/encoding/iso8859-8.enc                     |    20 +
 library/encoding/iso8859-9.enc                     |    20 +
 library/encoding/jis0201.enc                       |    20 +
 library/encoding/jis0208.enc                       |  1319 +
 library/encoding/jis0212.enc                       |  1159 +
 library/encoding/koi8-r.enc                        |    20 +
 library/encoding/koi8-u.enc                        |    20 +
 library/encoding/ksc5601.enc                       |  1516 +
 library/encoding/macCentEuro.enc                   |    20 +
 library/encoding/macCroatian.enc                   |    20 +
 library/encoding/macCyrillic.enc                   |    20 +
 library/encoding/macDingbats.enc                   |    20 +
 library/encoding/macGreek.enc                      |    20 +
 library/encoding/macIceland.enc                    |    20 +
 library/encoding/macJapan.enc                      |   785 +
 library/encoding/macRoman.enc                      |    20 +
 library/encoding/macRomania.enc                    |    20 +
 library/encoding/macThai.enc                       |    20 +
 library/encoding/macTurkish.enc                    |    20 +
 library/encoding/macUkraine.enc                    |    20 +
 library/encoding/shiftjis.enc                      |   690 +
 library/encoding/symbol.enc                        |    20 +
 library/encoding/tis-620.enc                       |    20 +
 library/history.tcl                                |   311 +
 library/http/http.tcl                              |  1541 +
 library/http/pkgIndex.tcl                          |     2 +
 library/http1.0/http.tcl                           |   377 +
 library/http1.0/pkgIndex.tcl                       |    11 +
 library/init.tcl                                   |   818 +
 library/msgcat/msgcat.tcl                          |  1210 +
 library/msgcat/pkgIndex.tcl                        |     2 +
 library/msgs/af.msg                                |    49 +
 library/msgs/af_za.msg                             |     6 +
 library/msgs/ar.msg                                |    54 +
 library/msgs/ar_in.msg                             |     6 +
 library/msgs/ar_jo.msg                             |    39 +
 library/msgs/ar_lb.msg                             |    39 +
 library/msgs/ar_sy.msg                             |    39 +
 library/msgs/be.msg                                |    52 +
 library/msgs/bg.msg                                |    52 +
 library/msgs/bn.msg                                |    49 +
 library/msgs/bn_in.msg                             |     6 +
 library/msgs/ca.msg                                |    50 +
 library/msgs/cs.msg                                |    54 +
 library/msgs/da.msg                                |    52 +
 library/msgs/de.msg                                |    54 +
 library/msgs/de_at.msg                             |    35 +
 library/msgs/de_be.msg                             |    53 +
 library/msgs/el.msg                                |    52 +
 library/msgs/en_au.msg                             |     7 +
 library/msgs/en_be.msg                             |     7 +
 library/msgs/en_bw.msg                             |     6 +
 library/msgs/en_ca.msg                             |     7 +
 library/msgs/en_gb.msg                             |     7 +
 library/msgs/en_hk.msg                             |     8 +
 library/msgs/en_ie.msg                             |     7 +
 library/msgs/en_in.msg                             |     8 +
 library/msgs/en_nz.msg                             |     7 +
 library/msgs/en_ph.msg                             |     8 +
 library/msgs/en_sg.msg                             |     6 +
 library/msgs/en_za.msg                             |     6 +
 library/msgs/en_zw.msg                             |     6 +
 library/msgs/eo.msg                                |    54 +
 library/msgs/es.msg                                |    52 +
 library/msgs/es_ar.msg                             |     6 +
 library/msgs/es_bo.msg                             |     6 +
 library/msgs/es_cl.msg                             |     6 +
 library/msgs/es_co.msg                             |     6 +
 library/msgs/es_cr.msg                             |     6 +
 library/msgs/es_do.msg                             |     6 +
 library/msgs/es_ec.msg                             |     6 +
 library/msgs/es_gt.msg                             |     6 +
 library/msgs/es_hn.msg                             |     6 +
 library/msgs/es_mx.msg                             |     6 +
 library/msgs/es_ni.msg                             |     6 +
 library/msgs/es_pa.msg                             |     6 +
 library/msgs/es_pe.msg                             |     6 +
 library/msgs/es_pr.msg                             |     6 +
 library/msgs/es_py.msg                             |     6 +
 library/msgs/es_sv.msg                             |     6 +
 library/msgs/es_uy.msg                             |     6 +
 library/msgs/es_ve.msg                             |     6 +
 library/msgs/et.msg                                |    52 +
 library/msgs/eu.msg                                |    47 +
 library/msgs/eu_es.msg                             |     7 +
 library/msgs/fa.msg                                |    47 +
 library/msgs/fa_in.msg                             |    52 +
 library/msgs/fa_ir.msg                             |     9 +
 library/msgs/fi.msg                                |    50 +
 library/msgs/fo.msg                                |    47 +
 library/msgs/fo_fo.msg                             |     7 +
 library/msgs/fr.msg                                |    52 +
 library/msgs/fr_be.msg                             |     7 +
 library/msgs/fr_ca.msg                             |     7 +
 library/msgs/fr_ch.msg                             |     7 +
 library/msgs/ga.msg                                |    47 +
 library/msgs/ga_ie.msg                             |     7 +
 library/msgs/gl.msg                                |    47 +
 library/msgs/gl_es.msg                             |     6 +
 library/msgs/gv.msg                                |    47 +
 library/msgs/gv_gb.msg                             |     6 +
 library/msgs/he.msg                                |    52 +
 library/msgs/hi.msg                                |    39 +
 library/msgs/hi_in.msg                             |     6 +
 library/msgs/hr.msg                                |    50 +
 library/msgs/hu.msg                                |    54 +
 library/msgs/id.msg                                |    47 +
 library/msgs/id_id.msg                             |     6 +
 library/msgs/is.msg                                |    50 +
 library/msgs/it.msg                                |    54 +
 library/msgs/it_ch.msg                             |     6 +
 library/msgs/ja.msg                                |    44 +
 library/msgs/kl.msg                                |    47 +
 library/msgs/kl_gl.msg                             |     7 +
 library/msgs/ko.msg                                |    55 +
 library/msgs/ko_kr.msg                             |     8 +
 library/msgs/kok.msg                               |    39 +
 library/msgs/kok_in.msg                            |     6 +
 library/msgs/kw.msg                                |    47 +
 library/msgs/kw_gb.msg                             |     6 +
 library/msgs/lt.msg                                |    52 +
 library/msgs/lv.msg                                |    52 +
 library/msgs/mk.msg                                |    52 +
 library/msgs/mr.msg                                |    39 +
 library/msgs/mr_in.msg                             |     6 +
 library/msgs/ms.msg                                |    47 +
 library/msgs/ms_my.msg                             |     6 +
 library/msgs/mt.msg                                |    27 +
 library/msgs/nb.msg                                |    52 +
 library/msgs/nl.msg                                |    50 +
 library/msgs/nl_be.msg                             |     7 +
 library/msgs/nn.msg                                |    52 +
 library/msgs/pl.msg                                |    52 +
 library/msgs/pt.msg                                |    50 +
 library/msgs/pt_br.msg                             |     7 +
 library/msgs/ro.msg                                |    52 +
 library/msgs/ru.msg                                |    52 +
 library/msgs/ru_ua.msg                             |     6 +
 library/msgs/sh.msg                                |    52 +
 library/msgs/sk.msg                                |    52 +
 library/msgs/sl.msg                                |    52 +
 library/msgs/sq.msg                                |    54 +
 library/msgs/sr.msg                                |    52 +
 library/msgs/sv.msg                                |    52 +
 library/msgs/sw.msg                                |    49 +
 library/msgs/ta.msg                                |    39 +
 library/msgs/ta_in.msg                             |     6 +
 library/msgs/te.msg                                |    47 +
 library/msgs/te_in.msg                             |     8 +
 library/msgs/th.msg                                |    54 +
 library/msgs/tr.msg                                |    50 +
 library/msgs/uk.msg                                |    52 +
 library/msgs/vi.msg                                |    50 +
 library/msgs/zh.msg                                |    55 +
 library/msgs/zh_cn.msg                             |     7 +
 library/msgs/zh_hk.msg                             |    28 +
 library/msgs/zh_sg.msg                             |     8 +
 library/msgs/zh_tw.msg                             |     8 +
 library/opt/optparse.tcl                           |  1072 +
 library/opt/pkgIndex.tcl                           |    12 +
 library/package.tcl                                |   747 +
 library/parray.tcl                                 |    28 +
 library/platform/pkgIndex.tcl                      |     3 +
 library/platform/platform.tcl                      |   397 +
 library/platform/shell.tcl                         |   241 +
 library/reg/pkgIndex.tcl                           |     9 +
 library/safe.tcl                                   |  1133 +
 library/tclIndex                                   |    75 +
 library/tcltest/pkgIndex.tcl                       |    12 +
 library/tcltest/tcltest.tcl                        |  3420 ++
 library/tm.tcl                                     |   375 +
 library/tzdata/Africa/Abidjan                      |     6 +
 library/tzdata/Africa/Accra                        |    52 +
 library/tzdata/Africa/Addis_Ababa                  |     5 +
 library/tzdata/Africa/Algiers                      |    39 +
 library/tzdata/Africa/Asmara                       |     5 +
 library/tzdata/Africa/Asmera                       |     5 +
 library/tzdata/Africa/Bamako                       |     5 +
 library/tzdata/Africa/Bangui                       |     5 +
 library/tzdata/Africa/Banjul                       |     5 +
 library/tzdata/Africa/Bissau                       |     7 +
 library/tzdata/Africa/Blantyre                     |     5 +
 library/tzdata/Africa/Brazzaville                  |     5 +
 library/tzdata/Africa/Bujumbura                    |     5 +
 library/tzdata/Africa/Cairo                        |   132 +
 library/tzdata/Africa/Casablanca                   |   230 +
 library/tzdata/Africa/Ceuta                        |   258 +
 library/tzdata/Africa/Conakry                      |     5 +
 library/tzdata/Africa/Dakar                        |     5 +
 library/tzdata/Africa/Dar_es_Salaam                |     5 +
 library/tzdata/Africa/Djibouti                     |     5 +
 library/tzdata/Africa/Douala                       |     5 +
 library/tzdata/Africa/El_Aaiun                     |   219 +
 library/tzdata/Africa/Freetown                     |     5 +
 library/tzdata/Africa/Gaborone                     |     5 +
 library/tzdata/Africa/Harare                       |     5 +
 library/tzdata/Africa/Johannesburg                 |    11 +
 library/tzdata/Africa/Juba                         |     5 +
 library/tzdata/Africa/Kampala                      |     5 +
 library/tzdata/Africa/Khartoum                     |    39 +
 library/tzdata/Africa/Kigali                       |     5 +
 library/tzdata/Africa/Kinshasa                     |     5 +
 library/tzdata/Africa/Lagos                        |     6 +
 library/tzdata/Africa/Libreville                   |     5 +
 library/tzdata/Africa/Lome                         |     5 +
 library/tzdata/Africa/Luanda                       |     5 +
 library/tzdata/Africa/Lubumbashi                   |     5 +
 library/tzdata/Africa/Lusaka                       |     5 +
 library/tzdata/Africa/Malabo                       |     5 +
 library/tzdata/Africa/Maputo                       |     6 +
 library/tzdata/Africa/Maseru                       |     5 +
 library/tzdata/Africa/Mbabane                      |     5 +
 library/tzdata/Africa/Mogadishu                    |     5 +
 library/tzdata/Africa/Monrovia                     |     8 +
 library/tzdata/Africa/Nairobi                      |     9 +
 library/tzdata/Africa/Ndjamena                     |     8 +
 library/tzdata/Africa/Niamey                       |     5 +
 library/tzdata/Africa/Nouakchott                   |     5 +
 library/tzdata/Africa/Ouagadougou                  |     5 +
 library/tzdata/Africa/Porto-Novo                   |     5 +
 library/tzdata/Africa/Sao_Tome                     |     5 +
 library/tzdata/Africa/Timbuktu                     |     5 +
 library/tzdata/Africa/Tripoli                      |    34 +
 library/tzdata/Africa/Tunis                        |    39 +
 library/tzdata/Africa/Windhoek                     |   222 +
 library/tzdata/America/Adak                        |   276 +
 library/tzdata/America/Anchorage                   |   276 +
 library/tzdata/America/Anguilla                    |     5 +
 library/tzdata/America/Antigua                     |     5 +
 library/tzdata/America/Araguaina                   |    60 +
 library/tzdata/America/Argentina/Buenos_Aires      |    67 +
 library/tzdata/America/Argentina/Catamarca         |    68 +
 library/tzdata/America/Argentina/ComodRivadavia    |     5 +
 library/tzdata/America/Argentina/Cordoba           |    67 +
 library/tzdata/America/Argentina/Jujuy             |    67 +
 library/tzdata/America/Argentina/La_Rioja          |    69 +
 library/tzdata/America/Argentina/Mendoza           |    68 +
 library/tzdata/America/Argentina/Rio_Gallegos      |    68 +
 library/tzdata/America/Argentina/Salta             |    66 +
 library/tzdata/America/Argentina/San_Juan          |    69 +
 library/tzdata/America/Argentina/San_Luis          |    68 +
 library/tzdata/America/Argentina/Tucuman           |    69 +
 library/tzdata/America/Argentina/Ushuaia           |    68 +
 library/tzdata/America/Aruba                       |     5 +
 library/tzdata/America/Asuncion                    |   259 +
 library/tzdata/America/Atikokan                    |    12 +
 library/tzdata/America/Atka                        |     5 +
 library/tzdata/America/Bahia                       |    68 +
 library/tzdata/America/Bahia_Banderas              |   222 +
 library/tzdata/America/Barbados                    |    15 +
 library/tzdata/America/Belem                       |    35 +
 library/tzdata/America/Belize                      |    60 +
 library/tzdata/America/Blanc-Sablon                |    12 +
 library/tzdata/America/Boa_Vista                   |    40 +
 library/tzdata/America/Bogota                      |     9 +
 library/tzdata/America/Boise                       |   281 +
 library/tzdata/America/Buenos_Aires                |     5 +
 library/tzdata/America/Cambridge_Bay               |   252 +
 library/tzdata/America/Campo_Grande                |   257 +
 library/tzdata/America/Cancun                      |    47 +
 library/tzdata/America/Caracas                     |    10 +
 library/tzdata/America/Catamarca                   |     5 +
 library/tzdata/America/Cayenne                     |     7 +
 library/tzdata/America/Cayman                      |     5 +
 library/tzdata/America/Chicago                     |   369 +
 library/tzdata/America/Chihuahua                   |   221 +
 library/tzdata/America/Coral_Harbour               |     5 +
 library/tzdata/America/Cordoba                     |     5 +
 library/tzdata/America/Costa_Rica                  |    15 +
 library/tzdata/America/Creston                     |     8 +
 library/tzdata/America/Cuiaba                      |   257 +
 library/tzdata/America/Curacao                     |     7 +
 library/tzdata/America/Danmarkshavn                |    39 +
 library/tzdata/America/Dawson                      |   256 +
 library/tzdata/America/Dawson_Creek                |    64 +
 library/tzdata/America/Denver                      |   291 +
 library/tzdata/America/Detroit                     |   272 +
 library/tzdata/America/Dominica                    |     5 +
 library/tzdata/America/Edmonton                    |   284 +
 library/tzdata/America/Eirunepe                    |    41 +
 library/tzdata/America/El_Salvador                 |    10 +
 library/tzdata/America/Ensenada                    |     5 +
 library/tzdata/America/Fort_Nelson                 |   151 +
 library/tzdata/America/Fort_Wayne                  |     5 +
 library/tzdata/America/Fortaleza                   |    48 +
 library/tzdata/America/Glace_Bay                   |   273 +
 library/tzdata/America/Godthab                     |   246 +
 library/tzdata/America/Goose_Bay                   |   338 +
 library/tzdata/America/Grand_Turk                  |    82 +
 library/tzdata/America/Grenada                     |     5 +
 library/tzdata/America/Guadeloupe                  |     5 +
 library/tzdata/America/Guatemala                   |    14 +
 library/tzdata/America/Guayaquil                   |     7 +
 library/tzdata/America/Guyana                      |     9 +
 library/tzdata/America/Halifax                     |   361 +
 library/tzdata/America/Havana                      |   285 +
 library/tzdata/America/Hermosillo                  |    21 +
 library/tzdata/America/Indiana/Indianapolis        |   234 +
 library/tzdata/America/Indiana/Knox                |   285 +
 library/tzdata/America/Indiana/Marengo             |   236 +
 library/tzdata/America/Indiana/Petersburg          |   247 +
 library/tzdata/America/Indiana/Tell_City           |   234 +
 library/tzdata/America/Indiana/Vevay               |   213 +
 library/tzdata/America/Indiana/Vincennes           |   234 +
 library/tzdata/America/Indiana/Winamac             |   240 +
 library/tzdata/America/Indianapolis                |     5 +
 library/tzdata/America/Inuvik                      |   249 +
 library/tzdata/America/Iqaluit                     |   250 +
 library/tzdata/America/Jamaica                     |    29 +
 library/tzdata/America/Jujuy                       |     5 +
 library/tzdata/America/Juneau                      |   276 +
 library/tzdata/America/Kentucky/Louisville         |   314 +
 library/tzdata/America/Kentucky/Monticello         |   279 +
 library/tzdata/America/Knox_IN                     |     5 +
 library/tzdata/America/Kralendijk                  |     5 +
 library/tzdata/America/La_Paz                      |     8 +
 library/tzdata/America/Lima                        |    16 +
 library/tzdata/America/Los_Angeles                 |   317 +
 library/tzdata/America/Louisville                  |     5 +
 library/tzdata/America/Lower_Princes               |     5 +
 library/tzdata/America/Maceio                      |    52 +
 library/tzdata/America/Managua                     |    21 +
 library/tzdata/America/Manaus                      |    39 +
 library/tzdata/America/Marigot                     |     5 +
 library/tzdata/America/Martinique                  |     9 +
 library/tzdata/America/Matamoros                   |   219 +
 library/tzdata/America/Mazatlan                    |   222 +
 library/tzdata/America/Mendoza                     |     5 +
 library/tzdata/America/Menominee                   |   274 +
 library/tzdata/America/Merida                      |   216 +
 library/tzdata/America/Metlakatla                  |   212 +
 library/tzdata/America/Mexico_City                 |   228 +
 library/tzdata/America/Miquelon                    |   234 +
 library/tzdata/America/Moncton                     |   342 +
 library/tzdata/America/Monterrey                   |   218 +
 library/tzdata/America/Montevideo                  |    92 +
 library/tzdata/America/Montreal                    |     5 +
 library/tzdata/America/Montserrat                  |     5 +
 library/tzdata/America/Nassau                      |   279 +
 library/tzdata/America/New_York                    |   369 +
 library/tzdata/America/Nipigon                     |   264 +
 library/tzdata/America/Nome                        |   276 +
 library/tzdata/America/Noronha                     |    48 +
 library/tzdata/America/North_Dakota/Beulah         |   279 +
 library/tzdata/America/North_Dakota/Center         |   279 +
 library/tzdata/America/North_Dakota/New_Salem      |   279 +
 library/tzdata/America/Ojinaga                     |   222 +
 library/tzdata/America/Panama                      |     7 +
 library/tzdata/America/Pangnirtung                 |   252 +
 library/tzdata/America/Paramaribo                  |    10 +
 library/tzdata/America/Phoenix                     |    17 +
 library/tzdata/America/Port-au-Prince              |    49 +
 library/tzdata/America/Port_of_Spain               |     6 +
 library/tzdata/America/Porto_Acre                  |     5 +
 library/tzdata/America/Porto_Velho                 |    35 +
 library/tzdata/America/Puerto_Rico                 |    10 +
 library/tzdata/America/Rainy_River                 |   264 +
 library/tzdata/America/Rankin_Inlet                |   248 +
 library/tzdata/America/Recife                      |    48 +
 library/tzdata/America/Regina                      |    58 +
 library/tzdata/America/Resolute                    |   248 +
 library/tzdata/America/Rio_Branco                  |    37 +
 library/tzdata/America/Rosario                     |     5 +
 library/tzdata/America/Santa_Isabel                |     5 +
 library/tzdata/America/Santarem                    |    36 +
 library/tzdata/America/Santiago                    |   289 +
 library/tzdata/America/Santo_Domingo               |    21 +
 library/tzdata/America/Sao_Paulo                   |   258 +
 library/tzdata/America/Scoresbysund                |   246 +
 library/tzdata/America/Shiprock                    |     5 +
 library/tzdata/America/Sitka                       |   275 +
 library/tzdata/America/St_Barthelemy               |     5 +
 library/tzdata/America/St_Johns                    |   372 +
 library/tzdata/America/St_Kitts                    |     5 +
 library/tzdata/America/St_Lucia                    |     5 +
 library/tzdata/America/St_Thomas                   |     5 +
 library/tzdata/America/St_Vincent                  |     5 +
 library/tzdata/America/Swift_Current               |    29 +
 library/tzdata/America/Tegucigalpa                 |    12 +
 library/tzdata/America/Thule                       |   224 +
 library/tzdata/America/Thunder_Bay                 |   272 +
 library/tzdata/America/Tijuana                     |   285 +
 library/tzdata/America/Toronto                     |   365 +
 library/tzdata/America/Tortola                     |     5 +
 library/tzdata/America/Vancouver                   |   320 +
 library/tzdata/America/Virgin                      |     5 +
 library/tzdata/America/Whitehorse                  |   256 +
 library/tzdata/America/Winnipeg                    |   316 +
 library/tzdata/America/Yakutat                     |   276 +
 library/tzdata/America/Yellowknife                 |   252 +
 library/tzdata/Antarctica/Casey                    |    10 +
 library/tzdata/Antarctica/Davis                    |    12 +
 library/tzdata/Antarctica/DumontDUrville           |     8 +
 library/tzdata/Antarctica/Macquarie                |    97 +
 library/tzdata/Antarctica/Mawson                   |     7 +
 library/tzdata/Antarctica/McMurdo                  |     5 +
 library/tzdata/Antarctica/Palmer                   |   252 +
 library/tzdata/Antarctica/Rothera                  |     6 +
 library/tzdata/Antarctica/South_Pole               |     5 +
 library/tzdata/Antarctica/Syowa                    |     6 +
 library/tzdata/Antarctica/Troll                    |   196 +
 library/tzdata/Antarctica/Vostok                   |     6 +
 library/tzdata/Arctic/Longyearbyen                 |     5 +
 library/tzdata/Asia/Aden                           |     5 +
 library/tzdata/Asia/Almaty                         |    57 +
 library/tzdata/Asia/Amman                          |   246 +
 library/tzdata/Asia/Anadyr                         |    72 +
 library/tzdata/Asia/Aqtau                          |    59 +
 library/tzdata/Asia/Aqtobe                         |    58 +
 library/tzdata/Asia/Ashgabat                       |    31 +
 library/tzdata/Asia/Ashkhabad                      |     5 +
 library/tzdata/Asia/Baghdad                        |    59 +
 library/tzdata/Asia/Bahrain                        |     5 +
 library/tzdata/Asia/Baku                           |    74 +
 library/tzdata/Asia/Bangkok                        |     7 +
 library/tzdata/Asia/Barnaul                        |    73 +
 library/tzdata/Asia/Beirut                         |   270 +
 library/tzdata/Asia/Bishkek                        |    57 +
 library/tzdata/Asia/Brunei                         |     7 +
 library/tzdata/Asia/Calcutta                       |     5 +
 library/tzdata/Asia/Chita                          |    72 +
 library/tzdata/Asia/Choibalsan                     |   222 +
 library/tzdata/Asia/Chongqing                      |     5 +
 library/tzdata/Asia/Chungking                      |     5 +
 library/tzdata/Asia/Colombo                        |    13 +
 library/tzdata/Asia/Dacca                          |     5 +
 library/tzdata/Asia/Damascus                       |   280 +
 library/tzdata/Asia/Dhaka                          |    14 +
 library/tzdata/Asia/Dili                           |    10 +
 library/tzdata/Asia/Dubai                          |     6 +
 library/tzdata/Asia/Dushanbe                       |    29 +
 library/tzdata/Asia/Gaza                           |   278 +
 library/tzdata/Asia/Harbin                         |     5 +
 library/tzdata/Asia/Hebron                         |   277 +
 library/tzdata/Asia/Ho_Chi_Minh                    |    14 +
 library/tzdata/Asia/Hong_Kong                      |    75 +
 library/tzdata/Asia/Hovd                           |   221 +
 library/tzdata/Asia/Irkutsk                        |    72 +
 library/tzdata/Asia/Istanbul                       |     5 +
 library/tzdata/Asia/Jakarta                        |    13 +
 library/tzdata/Asia/Jayapura                       |     8 +
 library/tzdata/Asia/Jerusalem                      |   272 +
 library/tzdata/Asia/Kabul                          |     7 +
 library/tzdata/Asia/Kamchatka                      |    71 +
 library/tzdata/Asia/Karachi                        |    16 +
 library/tzdata/Asia/Kashgar                        |     5 +
 library/tzdata/Asia/Kathmandu                      |     7 +
 library/tzdata/Asia/Katmandu                       |     5 +
 library/tzdata/Asia/Khandyga                       |    73 +
 library/tzdata/Asia/Kolkata                        |    10 +
 library/tzdata/Asia/Krasnoyarsk                    |    71 +
 library/tzdata/Asia/Kuala_Lumpur                   |    13 +
 library/tzdata/Asia/Kuching                        |    24 +
 library/tzdata/Asia/Kuwait                         |     5 +
 library/tzdata/Asia/Macao                          |     5 +
 library/tzdata/Asia/Macau                          |    46 +
 library/tzdata/Asia/Magadan                        |    72 +
 library/tzdata/Asia/Makassar                       |     9 +
 library/tzdata/Asia/Manila                         |    15 +
 library/tzdata/Asia/Muscat                         |     5 +
 library/tzdata/Asia/Nicosia                        |   257 +
 library/tzdata/Asia/Novokuznetsk                   |    71 +
 library/tzdata/Asia/Novosibirsk                    |    73 +
 library/tzdata/Asia/Omsk                           |    71 +
 library/tzdata/Asia/Oral                           |    58 +
 library/tzdata/Asia/Phnom_Penh                     |     5 +
 library/tzdata/Asia/Pontianak                      |    13 +
 library/tzdata/Asia/Pyongyang                      |    10 +
 library/tzdata/Asia/Qatar                          |     7 +
 library/tzdata/Asia/Qyzylorda                      |    57 +
 library/tzdata/Asia/Rangoon                        |     9 +
 library/tzdata/Asia/Riyadh                         |     6 +
 library/tzdata/Asia/Saigon                         |     5 +
 library/tzdata/Asia/Sakhalin                       |    74 +
 library/tzdata/Asia/Samarkand                      |    32 +
 library/tzdata/Asia/Seoul                          |    27 +
 library/tzdata/Asia/Shanghai                       |    23 +
 library/tzdata/Asia/Singapore                      |    14 +
 library/tzdata/Asia/Srednekolymsk                  |    71 +
 library/tzdata/Asia/Taipei                         |    46 +
 library/tzdata/Asia/Tashkent                       |    32 +
 library/tzdata/Asia/Tbilisi                        |    60 +
 library/tzdata/Asia/Tehran                         |   229 +
 library/tzdata/Asia/Tel_Aviv                       |     5 +
 library/tzdata/Asia/Thimbu                         |     5 +
 library/tzdata/Asia/Thimphu                        |     7 +
 library/tzdata/Asia/Tokyo                          |    16 +
 library/tzdata/Asia/Tomsk                          |    73 +
 library/tzdata/Asia/Ujung_Pandang                  |     5 +
 library/tzdata/Asia/Ulaanbaatar                    |   221 +
 library/tzdata/Asia/Ulan_Bator                     |     5 +
 library/tzdata/Asia/Urumqi                         |     6 +
 library/tzdata/Asia/Ust-Nera                       |    71 +
 library/tzdata/Asia/Vientiane                      |     5 +
 library/tzdata/Asia/Vladivostok                    |    71 +
 library/tzdata/Asia/Yakutsk                        |    71 +
 library/tzdata/Asia/Yekaterinburg                  |    72 +
 library/tzdata/Asia/Yerevan                        |    70 +
 library/tzdata/Atlantic/Azores                     |   349 +
 library/tzdata/Atlantic/Bermuda                    |   259 +
 library/tzdata/Atlantic/Canary                     |   247 +
 library/tzdata/Atlantic/Cape_Verde                 |     9 +
 library/tzdata/Atlantic/Faeroe                     |     5 +
 library/tzdata/Atlantic/Faroe                      |   245 +
 library/tzdata/Atlantic/Jan_Mayen                  |     5 +
 library/tzdata/Atlantic/Madeira                    |   350 +
 library/tzdata/Atlantic/Reykjavik                  |    73 +
 library/tzdata/Atlantic/South_Georgia              |     6 +
 library/tzdata/Atlantic/St_Helena                  |     5 +
 library/tzdata/Atlantic/Stanley                    |    75 +
 library/tzdata/Australia/ACT                       |     5 +
 library/tzdata/Australia/Adelaide                  |   273 +
 library/tzdata/Australia/Brisbane                  |    23 +
 library/tzdata/Australia/Broken_Hill               |   275 +
 library/tzdata/Australia/Canberra                  |     5 +
 library/tzdata/Australia/Currie                    |   273 +
 library/tzdata/Australia/Darwin                    |    15 +
 library/tzdata/Australia/Eucla                     |    25 +
 library/tzdata/Australia/Hobart                    |   281 +
 library/tzdata/Australia/LHI                       |     5 +
 library/tzdata/Australia/Lindeman                  |    28 +
 library/tzdata/Australia/Lord_Howe                 |   244 +
 library/tzdata/Australia/Melbourne                 |   272 +
 library/tzdata/Australia/NSW                       |     5 +
 library/tzdata/Australia/North                     |     5 +
 library/tzdata/Australia/Perth                     |    25 +
 library/tzdata/Australia/Queensland                |     5 +
 library/tzdata/Australia/South                     |     5 +
 library/tzdata/Australia/Sydney                    |   272 +
 library/tzdata/Australia/Tasmania                  |     5 +
 library/tzdata/Australia/Victoria                  |     5 +
 library/tzdata/Australia/West                      |     5 +
 library/tzdata/Australia/Yancowinna                |     5 +
 library/tzdata/Brazil/Acre                         |     5 +
 library/tzdata/Brazil/DeNoronha                    |     5 +
 library/tzdata/Brazil/East                         |     5 +
 library/tzdata/Brazil/West                         |     5 +
 library/tzdata/CET                                 |   265 +
 library/tzdata/CST6CDT                             |   278 +
 library/tzdata/Canada/Atlantic                     |     5 +
 library/tzdata/Canada/Central                      |     5 +
 library/tzdata/Canada/East-Saskatchewan            |     5 +
 library/tzdata/Canada/Eastern                      |     5 +
 library/tzdata/Canada/Mountain                     |     5 +
 library/tzdata/Canada/Newfoundland                 |     5 +
 library/tzdata/Canada/Pacific                      |     5 +
 library/tzdata/Canada/Saskatchewan                 |     5 +
 library/tzdata/Canada/Yukon                        |     5 +
 library/tzdata/Chile/Continental                   |     5 +
 library/tzdata/Chile/EasterIsland                  |     5 +
 library/tzdata/Cuba                                |     5 +
 library/tzdata/EET                                 |   251 +
 library/tzdata/EST                                 |     5 +
 library/tzdata/EST5EDT                             |   278 +
 library/tzdata/Egypt                               |     5 +
 library/tzdata/Eire                                |     5 +
 library/tzdata/Etc/GMT                             |     5 +
 library/tzdata/Etc/GMT+0                           |     5 +
 library/tzdata/Etc/GMT+1                           |     5 +
 library/tzdata/Etc/GMT+10                          |     5 +
 library/tzdata/Etc/GMT+11                          |     5 +
 library/tzdata/Etc/GMT+12                          |     5 +
 library/tzdata/Etc/GMT+2                           |     5 +
 library/tzdata/Etc/GMT+3                           |     5 +
 library/tzdata/Etc/GMT+4                           |     5 +
 library/tzdata/Etc/GMT+5                           |     5 +
 library/tzdata/Etc/GMT+6                           |     5 +
 library/tzdata/Etc/GMT+7                           |     5 +
 library/tzdata/Etc/GMT+8                           |     5 +
 library/tzdata/Etc/GMT+9                           |     5 +
 library/tzdata/Etc/GMT-0                           |     5 +
 library/tzdata/Etc/GMT-1                           |     5 +
 library/tzdata/Etc/GMT-10                          |     5 +
 library/tzdata/Etc/GMT-11                          |     5 +
 library/tzdata/Etc/GMT-12                          |     5 +
 library/tzdata/Etc/GMT-13                          |     5 +
 library/tzdata/Etc/GMT-14                          |     5 +
 library/tzdata/Etc/GMT-2                           |     5 +
 library/tzdata/Etc/GMT-3                           |     5 +
 library/tzdata/Etc/GMT-4                           |     5 +
 library/tzdata/Etc/GMT-5                           |     5 +
 library/tzdata/Etc/GMT-6                           |     5 +
 library/tzdata/Etc/GMT-7                           |     5 +
 library/tzdata/Etc/GMT-8                           |     5 +
 library/tzdata/Etc/GMT-9                           |     5 +
 library/tzdata/Etc/GMT0                            |     5 +
 library/tzdata/Etc/Greenwich                       |     5 +
 library/tzdata/Etc/UCT                             |     5 +
 library/tzdata/Etc/UTC                             |     5 +
 library/tzdata/Etc/Universal                       |     5 +
 library/tzdata/Etc/Zulu                            |     5 +
 library/tzdata/Europe/Amsterdam                    |   310 +
 library/tzdata/Europe/Andorra                      |   237 +
 library/tzdata/Europe/Astrakhan                    |    71 +
 library/tzdata/Europe/Athens                       |   268 +
 library/tzdata/Europe/Belfast                      |     5 +
 library/tzdata/Europe/Belgrade                     |   250 +
 library/tzdata/Europe/Berlin                       |   274 +
 library/tzdata/Europe/Bratislava                   |     5 +
 library/tzdata/Europe/Brussels                     |   316 +
 library/tzdata/Europe/Bucharest                    |   268 +
 library/tzdata/Europe/Budapest                     |   282 +
 library/tzdata/Europe/Busingen                     |     5 +
 library/tzdata/Europe/Chisinau                     |   272 +
 library/tzdata/Europe/Copenhagen                   |   264 +
 library/tzdata/Europe/Dublin                       |   359 +
 library/tzdata/Europe/Gibraltar                    |   328 +
 library/tzdata/Europe/Guernsey                     |     5 +
 library/tzdata/Europe/Helsinki                     |   248 +
 library/tzdata/Europe/Isle_of_Man                  |     5 +
 library/tzdata/Europe/Istanbul                     |   306 +
 library/tzdata/Europe/Jersey                       |     5 +
 library/tzdata/Europe/Kaliningrad                  |    85 +
 library/tzdata/Europe/Kiev                         |   251 +
 library/tzdata/Europe/Kirov                        |    70 +
 library/tzdata/Europe/Lisbon                       |   351 +
 library/tzdata/Europe/Ljubljana                    |     5 +
 library/tzdata/Europe/London                       |   372 +
 library/tzdata/Europe/Luxembourg                   |   313 +
 library/tzdata/Europe/Madrid                       |   294 +
 library/tzdata/Europe/Malta                        |   299 +
 library/tzdata/Europe/Mariehamn                    |     5 +
 library/tzdata/Europe/Minsk                        |    76 +
 library/tzdata/Europe/Monaco                       |   315 +
 library/tzdata/Europe/Moscow                       |    83 +
 library/tzdata/Europe/Nicosia                      |     5 +
 library/tzdata/Europe/Oslo                         |   271 +
 library/tzdata/Europe/Paris                        |   314 +
 library/tzdata/Europe/Podgorica                    |     5 +
 library/tzdata/Europe/Prague                       |   272 +
 library/tzdata/Europe/Riga                         |   258 +
 library/tzdata/Europe/Rome                         |   301 +
 library/tzdata/Europe/Samara                       |    73 +
 library/tzdata/Europe/San_Marino                   |     5 +
 library/tzdata/Europe/Sarajevo                     |     5 +
 library/tzdata/Europe/Simferopol                   |    82 +
 library/tzdata/Europe/Skopje                       |     5 +
 library/tzdata/Europe/Sofia                        |   258 +
 library/tzdata/Europe/Stockholm                    |   250 +
 library/tzdata/Europe/Tallinn                      |   254 +
 library/tzdata/Europe/Tirane                       |   263 +
 library/tzdata/Europe/Tiraspol                     |     5 +
 library/tzdata/Europe/Ulyanovsk                    |    73 +
 library/tzdata/Europe/Uzhgorod                     |   254 +
 library/tzdata/Europe/Vaduz                        |     5 +
 library/tzdata/Europe/Vatican                      |     5 +
 library/tzdata/Europe/Vienna                       |   271 +
 library/tzdata/Europe/Vilnius                      |   252 +
 library/tzdata/Europe/Volgograd                    |    72 +
 library/tzdata/Europe/Warsaw                       |   296 +
 library/tzdata/Europe/Zagreb                       |     5 +
 library/tzdata/Europe/Zaporozhye                   |   252 +
 library/tzdata/Europe/Zurich                       |   250 +
 library/tzdata/GB                                  |     5 +
 library/tzdata/GB-Eire                             |     5 +
 library/tzdata/GMT                                 |     5 +
 library/tzdata/GMT+0                               |     5 +
 library/tzdata/GMT-0                               |     5 +
 library/tzdata/GMT0                                |     5 +
 library/tzdata/Greenwich                           |     5 +
 library/tzdata/HST                                 |     5 +
 library/tzdata/Hongkong                            |     5 +
 library/tzdata/Iceland                             |     5 +
 library/tzdata/Indian/Antananarivo                 |     5 +
 library/tzdata/Indian/Chagos                       |     7 +
 library/tzdata/Indian/Christmas                    |     6 +
 library/tzdata/Indian/Cocos                        |     6 +
 library/tzdata/Indian/Comoro                       |     5 +
 library/tzdata/Indian/Kerguelen                    |     6 +
 library/tzdata/Indian/Mahe                         |     6 +
 library/tzdata/Indian/Maldives                     |     7 +
 library/tzdata/Indian/Mauritius                    |    10 +
 library/tzdata/Indian/Mayotte                      |     5 +
 library/tzdata/Indian/Reunion                      |     6 +
 library/tzdata/Iran                                |     5 +
 library/tzdata/Israel                              |     5 +
 library/tzdata/Jamaica                             |     5 +
 library/tzdata/Japan                               |     5 +
 library/tzdata/Kwajalein                           |     5 +
 library/tzdata/Libya                               |     5 +
 library/tzdata/MET                                 |   265 +
 library/tzdata/MST                                 |     5 +
 library/tzdata/MST7MDT                             |   278 +
 library/tzdata/Mexico/BajaNorte                    |     5 +
 library/tzdata/Mexico/BajaSur                      |     5 +
 library/tzdata/Mexico/General                      |     5 +
 library/tzdata/NZ                                  |     5 +
 library/tzdata/NZ-CHAT                             |     5 +
 library/tzdata/Navajo                              |     5 +
 library/tzdata/PRC                                 |     5 +
 library/tzdata/PST8PDT                             |   278 +
 library/tzdata/Pacific/Apia                        |   188 +
 library/tzdata/Pacific/Auckland                    |   285 +
 library/tzdata/Pacific/Bougainville                |    10 +
 library/tzdata/Pacific/Chatham                     |   258 +
 library/tzdata/Pacific/Chuuk                       |     6 +
 library/tzdata/Pacific/Easter                      |   268 +
 library/tzdata/Pacific/Efate                       |    26 +
 library/tzdata/Pacific/Enderbury                   |     8 +
 library/tzdata/Pacific/Fakaofo                     |     7 +
 library/tzdata/Pacific/Fiji                        |   191 +
 library/tzdata/Pacific/Funafuti                    |     6 +
 library/tzdata/Pacific/Galapagos                   |     7 +
 library/tzdata/Pacific/Gambier                     |     6 +
 library/tzdata/Pacific/Guadalcanal                 |     6 +
 library/tzdata/Pacific/Guam                        |     8 +
 library/tzdata/Pacific/Honolulu                    |    11 +
 library/tzdata/Pacific/Johnston                    |     5 +
 library/tzdata/Pacific/Kiritimati                  |     8 +
 library/tzdata/Pacific/Kosrae                      |     8 +
 library/tzdata/Pacific/Kwajalein                   |     8 +
 library/tzdata/Pacific/Majuro                      |     7 +
 library/tzdata/Pacific/Marquesas                   |     6 +
 library/tzdata/Pacific/Midway                      |     5 +
 library/tzdata/Pacific/Nauru                       |     9 +
 library/tzdata/Pacific/Niue                        |     8 +
 library/tzdata/Pacific/Norfolk                     |    10 +
 library/tzdata/Pacific/Noumea                      |    12 +
 library/tzdata/Pacific/Pago_Pago                   |     9 +
 library/tzdata/Pacific/Palau                       |     6 +
 library/tzdata/Pacific/Pitcairn                    |     7 +
 library/tzdata/Pacific/Pohnpei                     |     6 +
 library/tzdata/Pacific/Ponape                      |     5 +
 library/tzdata/Pacific/Port_Moresby                |     7 +
 library/tzdata/Pacific/Rarotonga                   |    32 +
 library/tzdata/Pacific/Saipan                      |     5 +
 library/tzdata/Pacific/Samoa                       |     5 +
 library/tzdata/Pacific/Tahiti                      |     6 +
 library/tzdata/Pacific/Tarawa                      |     6 +
 library/tzdata/Pacific/Tongatapu                   |    14 +
 library/tzdata/Pacific/Truk                        |     5 +
 library/tzdata/Pacific/Wake                        |     6 +
 library/tzdata/Pacific/Wallis                      |     6 +
 library/tzdata/Pacific/Yap                         |     5 +
 library/tzdata/Poland                              |     5 +
 library/tzdata/Portugal                            |     5 +
 library/tzdata/ROC                                 |     5 +
 library/tzdata/ROK                                 |     5 +
 library/tzdata/Singapore                           |     5 +
 library/tzdata/SystemV/AST4                        |     5 +
 library/tzdata/SystemV/AST4ADT                     |     5 +
 library/tzdata/SystemV/CST6                        |     5 +
 library/tzdata/SystemV/CST6CDT                     |     5 +
 library/tzdata/SystemV/EST5                        |     5 +
 library/tzdata/SystemV/EST5EDT                     |     5 +
 library/tzdata/SystemV/HST10                       |     5 +
 library/tzdata/SystemV/MST7                        |     5 +
 library/tzdata/SystemV/MST7MDT                     |     5 +
 library/tzdata/SystemV/PST8                        |     5 +
 library/tzdata/SystemV/PST8PDT                     |     5 +
 library/tzdata/SystemV/YST9                        |     5 +
 library/tzdata/SystemV/YST9YDT                     |     5 +
 library/tzdata/Turkey                              |     5 +
 library/tzdata/UCT                                 |     5 +
 library/tzdata/US/Alaska                           |     5 +
 library/tzdata/US/Aleutian                         |     5 +
 library/tzdata/US/Arizona                          |     5 +
 library/tzdata/US/Central                          |     5 +
 library/tzdata/US/East-Indiana                     |     5 +
 library/tzdata/US/Eastern                          |     5 +
 library/tzdata/US/Hawaii                           |     5 +
 library/tzdata/US/Indiana-Starke                   |     5 +
 library/tzdata/US/Michigan                         |     5 +
 library/tzdata/US/Mountain                         |     5 +
 library/tzdata/US/Pacific                          |     5 +
 library/tzdata/US/Pacific-New                      |     5 +
 library/tzdata/US/Samoa                            |     5 +
 library/tzdata/UTC                                 |     5 +
 library/tzdata/Universal                           |     5 +
 library/tzdata/W-SU                                |     5 +
 library/tzdata/WET                                 |   251 +
 library/tzdata/Zulu                                |     5 +
 library/word.tcl                                   |   152 +
 libtommath/LICENSE                                 |     4 +
 libtommath/bn.ilg                                  |     6 +
 libtommath/bn.ind                                  |    82 +
 libtommath/bn.pdf                                  |   Bin 0 -> 340921 bytes
 libtommath/bn.tex                                  |  1835 +
 libtommath/bn_error.c                              |    43 +
 libtommath/bn_fast_mp_invmod.c                     |   144 +
 libtommath/bn_fast_mp_montgomery_reduce.c          |   168 +
 libtommath/bn_fast_s_mp_mul_digs.c                 |   103 +
 libtommath/bn_fast_s_mp_mul_high_digs.c            |    94 +
 libtommath/bn_fast_s_mp_sqr.c                      |   110 +
 libtommath/bn_mp_2expt.c                           |    44 +
 libtommath/bn_mp_abs.c                             |    39 +
 libtommath/bn_mp_add.c                             |    49 +
 libtommath/bn_mp_add_d.c                           |   109 +
 libtommath/bn_mp_addmod.c                          |    37 +
 libtommath/bn_mp_and.c                             |    53 +
 libtommath/bn_mp_clamp.c                           |    40 +
 libtommath/bn_mp_clear.c                           |    40 +
 libtommath/bn_mp_clear_multi.c                     |    30 +
 libtommath/bn_mp_cmp.c                             |    39 +
 libtommath/bn_mp_cmp_d.c                           |    40 +
 libtommath/bn_mp_cmp_mag.c                         |    51 +
 libtommath/bn_mp_cnt_lsb.c                         |    49 +
 libtommath/bn_mp_copy.c                            |    64 +
 libtommath/bn_mp_count_bits.c                      |    41 +
 libtommath/bn_mp_div.c                             |   288 +
 libtommath/bn_mp_div_2.c                           |    64 +
 libtommath/bn_mp_div_2d.c                          |    93 +
 libtommath/bn_mp_div_3.c                           |    75 +
 libtommath/bn_mp_div_d.c                           |   110 +
 libtommath/bn_mp_dr_is_modulus.c                   |    39 +
 libtommath/bn_mp_dr_reduce.c                       |    90 +
 libtommath/bn_mp_dr_setup.c                        |    28 +
 libtommath/bn_mp_exch.c                            |    30 +
 libtommath/bn_mp_expt_d.c                          |    53 +
 libtommath/bn_mp_exptmod.c                         |   108 +
 libtommath/bn_mp_exptmod_fast.c                    |   316 +
 libtommath/bn_mp_exteuclid.c                       |    78 +
 libtommath/bn_mp_fread.c                           |    63 +
 libtommath/bn_mp_fwrite.c                          |    48 +
 libtommath/bn_mp_gcd.c                             |   101 +
 libtommath/bn_mp_get_int.c                         |    41 +
 libtommath/bn_mp_grow.c                            |    53 +
 libtommath/bn_mp_init.c                            |    42 +
 libtommath/bn_mp_init_copy.c                       |    28 +
 libtommath/bn_mp_init_multi.c                      |    55 +
 libtommath/bn_mp_init_set.c                        |    28 +
 libtommath/bn_mp_init_set_int.c                    |    27 +
 libtommath/bn_mp_init_size.c                       |    44 +
 libtommath/bn_mp_invmod.c                          |    39 +
 libtommath/bn_mp_invmod_slow.c                     |   171 +
 libtommath/bn_mp_is_square.c                       |   105 +
 libtommath/bn_mp_jacobi.c                          |   101 +
 libtommath/bn_mp_karatsuba_mul.c                   |   163 +
 libtommath/bn_mp_karatsuba_sqr.c                   |   117 +
 libtommath/bn_mp_lcm.c                             |    56 +
 libtommath/bn_mp_lshd.c                            |    63 +
 libtommath/bn_mp_mod.c                             |    44 +
 libtommath/bn_mp_mod_2d.c                          |    51 +
 libtommath/bn_mp_mod_d.c                           |    23 +
 libtommath/bn_mp_montgomery_calc_normalization.c   |    55 +
 libtommath/bn_mp_montgomery_reduce.c               |   114 +
 libtommath/bn_mp_montgomery_setup.c                |    55 +
 libtommath/bn_mp_mul.c                             |    62 +
 libtommath/bn_mp_mul_2.c                           |    78 +
 libtommath/bn_mp_mul_2d.c                          |    81 +
 libtommath/bn_mp_mul_d.c                           |    75 +
 libtommath/bn_mp_mulmod.c                          |    36 +
 libtommath/bn_mp_n_root.c                          |   128 +
 libtommath/bn_mp_neg.c                             |    36 +
 libtommath/bn_mp_or.c                              |    46 +
 libtommath/bn_mp_prime_fermat.c                    |    58 +
 libtommath/bn_mp_prime_is_divisible.c              |    46 +
 libtommath/bn_mp_prime_is_prime.c                  |    79 +
 libtommath/bn_mp_prime_miller_rabin.c              |    99 +
 libtommath/bn_mp_prime_next_prime.c                |   166 +
 libtommath/bn_mp_prime_rabin_miller_trials.c       |    48 +
 libtommath/bn_mp_prime_random_ex.c                 |   121 +
 libtommath/bn_mp_radix_size.c                      |    83 +
 libtommath/bn_mp_radix_smap.c                      |    20 +
 libtommath/bn_mp_rand.c                            |    51 +
 libtommath/bn_mp_read_radix.c                      |    88 +
 libtommath/bn_mp_read_signed_bin.c                 |    37 +
 libtommath/bn_mp_read_unsigned_bin.c               |    51 +
 libtommath/bn_mp_reduce.c                          |    96 +
 libtommath/bn_mp_reduce_2k.c                       |    57 +
 libtommath/bn_mp_reduce_2k_l.c                     |    58 +
 libtommath/bn_mp_reduce_2k_setup.c                 |    43 +
 libtommath/bn_mp_reduce_2k_setup_l.c               |    40 +
 libtommath/bn_mp_reduce_is_2k.c                    |    48 +
 libtommath/bn_mp_reduce_is_2k_l.c                  |    40 +
 libtommath/bn_mp_reduce_setup.c                    |    30 +
 libtommath/bn_mp_rshd.c                            |    68 +
 libtommath/bn_mp_set.c                             |    25 +
 libtommath/bn_mp_set_int.c                         |    44 +
 libtommath/bn_mp_shrink.c                          |    36 +
 libtommath/bn_mp_signed_bin_size.c                 |    23 +
 libtommath/bn_mp_sqr.c                             |    54 +
 libtommath/bn_mp_sqrmod.c                          |    37 +
 libtommath/bn_mp_sqrt.c                            |   142 +
 libtommath/bn_mp_sub.c                             |    55 +
 libtommath/bn_mp_sub_d.c                           |    89 +
 libtommath/bn_mp_submod.c                          |    38 +
 libtommath/bn_mp_to_signed_bin.c                   |    29 +
 libtommath/bn_mp_to_signed_bin_n.c                 |    27 +
 libtommath/bn_mp_to_unsigned_bin.c                 |    44 +
 libtommath/bn_mp_to_unsigned_bin_n.c               |    27 +
 libtommath/bn_mp_toom_mul.c                        |   280 +
 libtommath/bn_mp_toom_sqr.c                        |   222 +
 libtommath/bn_mp_toradix.c                         |    71 +
 libtommath/bn_mp_toradix_n.c                       |    84 +
 libtommath/bn_mp_unsigned_bin_size.c               |    24 +
 libtommath/bn_mp_xor.c                             |    47 +
 libtommath/bn_mp_zero.c                            |    32 +
 libtommath/bn_prime_tab.c                          |    57 +
 libtommath/bn_reverse.c                            |    35 +
 libtommath/bn_s_mp_add.c                           |   105 +
 libtommath/bn_s_mp_exptmod.c                       |   248 +
 libtommath/bn_s_mp_mul_digs.c                      |    86 +
 libtommath/bn_s_mp_mul_high_digs.c                 |    77 +
 libtommath/bn_s_mp_sqr.c                           |    80 +
 libtommath/bn_s_mp_sub.c                           |    85 +
 libtommath/bncore.c                                |    32 +
 libtommath/booker.pl                               |   265 +
 libtommath/callgraph.txt                           | 11913 ++++++
 libtommath/changes.txt                             |   403 +
 libtommath/demo/demo.c                             |   736 +
 libtommath/demo/timing.c                           |   315 +
 libtommath/dep.pl                                  |   123 +
 libtommath/etc/2kprime.1                           |     2 +
 libtommath/etc/2kprime.c                           |    75 +
 libtommath/etc/drprime.c                           |    59 +
 libtommath/etc/drprimes.28                         |    25 +
 libtommath/etc/drprimes.txt                        |     9 +
 libtommath/etc/makefile                            |    50 +
 libtommath/etc/makefile.icc                        |    67 +
 libtommath/etc/makefile.msvc                       |    23 +
 libtommath/etc/mersenne.c                          |   140 +
 libtommath/etc/mont.c                              |    41 +
 libtommath/etc/pprime.c                            |   396 +
 libtommath/etc/prime.1024                          |   414 +
 libtommath/etc/prime.512                           |   205 +
 libtommath/etc/timer.asm                           |    37 +
 libtommath/etc/tune.c                              |   138 +
 libtommath/gen.pl                                  |    17 +
 libtommath/logs/README                             |    13 +
 libtommath/logs/add.log                            |    16 +
 libtommath/logs/addsub.png                         |   Bin 0 -> 6253 bytes
 libtommath/logs/expt.log                           |     7 +
 libtommath/logs/expt.png                           |   Bin 0 -> 6604 bytes
 libtommath/logs/expt_2k.log                        |     5 +
 libtommath/logs/expt_2kl.log                       |     4 +
 libtommath/logs/expt_dr.log                        |     7 +
 libtommath/logs/graphs.dem                         |    17 +
 libtommath/logs/index.html                         |    24 +
 libtommath/logs/invmod.log                         |     0
 libtommath/logs/invmod.png                         |   Bin 0 -> 4917 bytes
 libtommath/logs/mult.log                           |    84 +
 libtommath/logs/mult.png                           |   Bin 0 -> 6769 bytes
 libtommath/logs/mult_kara.log                      |    84 +
 libtommath/logs/sqr.log                            |    84 +
 libtommath/logs/sqr_kara.log                       |    84 +
 libtommath/logs/sub.log                            |    16 +
 libtommath/makefile                                |   186 +
 libtommath/makefile.bcc                            |    44 +
 libtommath/makefile.cygwin_dll                     |    51 +
 libtommath/makefile.icc                            |   116 +
 libtommath/makefile.msvc                           |    40 +
 libtommath/makefile.shared                         |   102 +
 libtommath/mess.sh                                 |     4 +
 libtommath/mtest/logtab.h                          |    19 +
 libtommath/mtest/mpi-config.h                      |    85 +
 libtommath/mtest/mpi-types.h                       |    15 +
 libtommath/mtest/mpi.c                             |  3979 ++
 libtommath/mtest/mpi.h                             |   225 +
 libtommath/mtest/mtest.c                           |   304 +
 libtommath/pics/design_process.sxd                 |   Bin 0 -> 6950 bytes
 libtommath/pics/design_process.tif                 |   Bin 0 -> 79042 bytes
 libtommath/pics/expt_state.sxd                     |   Bin 0 -> 6869 bytes
 libtommath/pics/expt_state.tif                     |   Bin 0 -> 87540 bytes
 libtommath/pics/makefile                           |    35 +
 libtommath/pics/primality.tif                      |   Bin 0 -> 85512 bytes
 libtommath/pics/radix.sxd                          |   Bin 0 -> 6181 bytes
 libtommath/pics/sliding_window.sxd                 |   Bin 0 -> 6787 bytes
 libtommath/pics/sliding_window.tif                 |   Bin 0 -> 53880 bytes
 libtommath/poster.out                              |     0
 libtommath/poster.pdf                              |   Bin 0 -> 37822 bytes
 libtommath/poster.tex                              |    35 +
 libtommath/pre_gen/mpi.c                           |  9048 +++++
 libtommath/pretty.build                            |    66 +
 libtommath/tombc/grammar.txt                       |    35 +
 libtommath/tommath.h                               |   579 +
 libtommath/tommath.out                             |   139 +
 libtommath/tommath.pdf                             |   Bin 0 -> 1194158 bytes
 libtommath/tommath.src                             |  6350 ++++
 libtommath/tommath.tex                             |  6691 ++++
 libtommath/tommath_class.h                         |   995 +
 libtommath/tommath_superclass.h                    |    72 +
 license.terms                                      |    40 +
 macosx/GNUmakefile                                 |   208 +
 macosx/README                                      |   174 +
 macosx/Tcl-Common.xcconfig                         |    37 +
 macosx/Tcl-Debug.xcconfig                          |    20 +
 macosx/Tcl-Info.plist.in                           |    36 +
 macosx/Tcl-Release.xcconfig                        |    20 +
 macosx/Tcl.xcode/default.pbxuser                   |   200 +
 macosx/Tcl.xcode/project.pbxproj                   |  2934 ++
 macosx/Tcl.xcodeproj/default.pbxuser               |   211 +
 macosx/Tcl.xcodeproj/project.pbxproj               |  3039 ++
 macosx/Tclsh-Info.plist.in                         |    36 +
 macosx/configure.ac                                |    11 +
 macosx/tclMacOSXBundle.c                           |   312 +
 macosx/tclMacOSXFCmd.c                             |   721 +
 macosx/tclMacOSXNotify.c                           |  2037 +
 pkgs/README                                        |    57 +
 pkgs/package.list.txt                              |    35 +
 tests/README                                       |   107 +
 tests/aaa_exit.test                                |    54 +
 tests/all.tcl                                      |    22 +
 tests/append.test                                  |   323 +
 tests/appendComp.test                              |   476 +
 tests/apply.test                                   |   321 +
 tests/assemble.test                                |  3378 ++
 tests/assemble1.bench                              |    85 +
 tests/assocd.test                                  |    68 +
 tests/async.test                                   |   216 +
 tests/autoMkindex.test                             |   372 +
 tests/basic.test                                   |   987 +
 tests/binary.test                                  |  2849 ++
 tests/case.test                                    |    89 +
 tests/chan.test                                    |   275 +
 tests/chanio.test                                  |  7742 ++++
 tests/clock.test                                   | 36974 +++++++++++++++++++
 tests/cmdAH.test                                   |  1665 +
 tests/cmdIL.test                                   |   745 +
 tests/cmdInfo.test                                 |   107 +
 tests/cmdMZ.test                                   |   355 +
 tests/compExpr-old.test                            |   677 +
 tests/compExpr.test                                |   396 +
 tests/compile.test                                 |  1056 +
 tests/concat.test                                  |    57 +
 tests/config.test                                  |    60 +
 tests/coroutine.test                               |   753 +
 tests/dcall.test                                   |    43 +
 tests/dict.test                                    |  2065 ++
 tests/dstring.test                                 |   439 +
 tests/encoding.test                                |   610 +
 tests/env.test                                     |   349 +
 tests/error.test                                   |  1211 +
 tests/eval.test                                    |    89 +
 tests/event.test                                   |   961 +
 tests/exec.test                                    |   715 +
 tests/execute.test                                 |  1088 +
 tests/expr-old.test                                |  1208 +
 tests/expr.test                                    |  7194 ++++
 tests/fCmd.test                                    |  2608 ++
 tests/fileName.test                                |  1633 +
 tests/fileSystem.test                              |   956 +
 tests/for-old.test                                 |    71 +
 tests/for.test                                     |  1360 +
 tests/foreach.test                                 |   294 +
 tests/format.test                                  |   581 +
 tests/get.test                                     |   101 +
 tests/history.test                                 |   255 +
 tests/http.test                                    |   668 +
 tests/http11.test                                  |   675 +
 tests/httpd                                        |   236 +
 tests/httpd11.tcl                                  |   255 +
 tests/httpold.test                                 |   293 +
 tests/if-old.test                                  |   162 +
 tests/if.test                                      |  1282 +
 tests/incr-old.test                                |    92 +
 tests/incr.test                                    |   522 +
 tests/indexObj.test                                |   166 +
 tests/info.test                                    |  2421 ++
 tests/init.test                                    |   195 +
 tests/interp.test                                  |  3666 ++
 tests/io.test                                      |  8670 +++++
 tests/ioCmd.test                                   |  3843 ++
 tests/ioTrans.test                                 |  2093 ++
 tests/iogt.test                                    |   955 +
 tests/join.test                                    |    55 +
 tests/lindex.test                                  |   458 +
 tests/link.test                                    |   310 +
 tests/linsert.test                                 |   119 +
 tests/list.test                                    |   134 +
 tests/listObj.test                                 |   209 +
 tests/llength.test                                 |    41 +
 tests/lmap.test                                    |   471 +
 tests/load.test                                    |   248 +
 tests/lrange.test                                  |   100 +
 tests/lrepeat.test                                 |    84 +
 tests/lreplace.test                                |   240 +
 tests/lsearch.test                                 |   528 +
 tests/lset.test                                    |   481 +
 tests/lsetComp.test                                |   431 +
 tests/macOSXFCmd.test                              |   181 +
 tests/macOSXLoad.test                              |    33 +
 tests/main.test                                    |  1297 +
 tests/mathop.test                                  |  1340 +
 tests/misc.test                                    |    74 +
 tests/msgcat.test                                  |  1085 +
 tests/namespace-old.test                           |   861 +
 tests/namespace.test                               |  3282 ++
 tests/notify.test                                  |   327 +
 tests/nre.test                                     |   451 +
 tests/obj.test                                     |   635 +
 tests/oo.test                                      |  3737 ++
 tests/ooNext2.test                                 |  1065 +
 tests/opt.test                                     |   245 +
 tests/package.test                                 |  1279 +
 tests/parse.test                                   |  1138 +
 tests/parseExpr.test                               |  1079 +
 tests/parseOld.test                                |   552 +
 tests/pid.test                                     |    57 +
 tests/pkgMkIndex.test                              |   698 +
 tests/platform.test                                |    84 +
 tests/proc-old.test                                |   517 +
 tests/proc.test                                    |   396 +
 tests/pwd.test                                     |    31 +
 tests/reg.test                                     |  1229 +
 tests/regexp.test                                  |  1133 +
 tests/regexpComp.test                              |   997 +
 tests/registry.test                                |   691 +
 tests/remote.tcl                                   |   159 +
 tests/rename.test                                  |   192 +
 tests/resolver.test                                |   206 +
 tests/result.test                                  |   147 +
 tests/safe.test                                    |   846 +
 tests/scan.test                                    |   853 +
 tests/security.test                                |    45 +
 tests/set-old.test                                 |   940 +
 tests/set.test                                     |   568 +
 tests/socket.test                                  |  2413 ++
 tests/source.test                                  |   312 +
 tests/split.test                                   |    88 +
 tests/stack.test                                   |    62 +
 tests/string.test                                  |  2004 +
 tests/stringComp.test                              |   798 +
 tests/stringObj.test                               |   491 +
 tests/subst.test                                   |   311 +
 tests/switch.test                                  |   772 +
 tests/tailcall.test                                |   696 +
 tests/tcltest.test                                 |  1837 +
 tests/thread.test                                  |  1443 +
 tests/timer.test                                   |   605 +
 tests/tm.test                                      |   245 +
 tests/trace.test                                   |  2686 ++
 tests/unixFCmd.test                                |   441 +
 tests/unixFile.test                                |    65 +
 tests/unixForkEvent.test                           |    45 +
 tests/unixInit.test                                |   402 +
 tests/unixNotfy.test                               |   102 +
 tests/unknown.test                                 |    65 +
 tests/unload.test                                  |   313 +
 tests/uplevel.test                                 |   305 +
 tests/upvar.test                                   |   588 +
 tests/utf.test                                     |   452 +
 tests/util.test                                    |  4028 ++
 tests/var.test                                     |   993 +
 tests/while-old.test                               |   119 +
 tests/while.test                                   |   702 +
 tests/winConsole.test                              |    48 +
 tests/winDde.test                                  |   491 +
 tests/winFCmd.test                                 |  1465 +
 tests/winFile.test                                 |   224 +
 tests/winNotify.test                               |   162 +
 tests/winPipe.test                                 |   454 +
 tests/winTime.test                                 |    66 +
 tests/zlib.test                                    |   926 +
 tools/Makefile.in                                  |    67 +
 tools/README                                       |    25 +
 tools/checkLibraryDoc.tcl                          |   293 +
 tools/configure                                    |  2170 ++
 tools/configure.in                                 |    35 +
 tools/encoding/Makefile                            |   110 +
 tools/encoding/README                              |     5 +
 tools/encoding/ascii.txt                           |    95 +
 tools/encoding/big5.txt                            | 13904 +++++++
 tools/encoding/cjk.inf                             |  4467 +++
 tools/encoding/cp1250.txt                          |   274 +
 tools/encoding/cp1251.txt                          |   274 +
 tools/encoding/cp1252.txt                          |   274 +
 tools/encoding/cp1253.txt                          |   274 +
 tools/encoding/cp1254.txt                          |   274 +
 tools/encoding/cp1255.txt                          |   274 +
 tools/encoding/cp1256.txt                          |   274 +
 tools/encoding/cp1257.txt                          |   274 +
 tools/encoding/cp1258.txt                          |   274 +
 tools/encoding/cp437.txt                           |   273 +
 tools/encoding/cp737.txt                           |   273 +
 tools/encoding/cp775.txt                           |   274 +
 tools/encoding/cp850.txt                           |   273 +
 tools/encoding/cp852.txt                           |   273 +
 tools/encoding/cp855.txt                           |   274 +
 tools/encoding/cp857.txt                           |   274 +
 tools/encoding/cp860.txt                           |   274 +
 tools/encoding/cp861.txt                           |   274 +
 tools/encoding/cp862.txt                           |   274 +
 tools/encoding/cp863.txt                           |   274 +
 tools/encoding/cp864.txt                           |   274 +
 tools/encoding/cp865.txt                           |   274 +
 tools/encoding/cp866.txt                           |   274 +
 tools/encoding/cp869.txt                           |   274 +
 tools/encoding/cp874.txt                           |   274 +
 tools/encoding/cp932.txt                           |  7998 ++++
 tools/encoding/cp936.txt                           | 22065 +++++++++++
 tools/encoding/cp949.txt                           | 17322 +++++++++
 tools/encoding/cp950.txt                           | 13777 +++++++
 tools/encoding/dingbats.txt                        |   250 +
 tools/encoding/ebcdic.txt                          |   289 +
 tools/encoding/gb12345.txt                         |  7604 ++++
 tools/encoding/gb1988.txt                          |   158 +
 tools/encoding/gb2312.txt                          |  7513 ++++
 tools/encoding/iso2022-jp.esc                      |    10 +
 tools/encoding/iso2022-kr.esc                      |     5 +
 tools/encoding/iso2022.esc                         |    12 +
 tools/encoding/iso8859-1.txt                       |   303 +
 tools/encoding/iso8859-10.txt                      |   303 +
 tools/encoding/iso8859-13.txt                      |   299 +
 tools/encoding/iso8859-14.txt                      |   301 +
 tools/encoding/iso8859-15.txt                      |   303 +
 tools/encoding/iso8859-16.txt                      |   299 +
 tools/encoding/iso8859-2.txt                       |   303 +
 tools/encoding/iso8859-3.txt                       |   296 +
 tools/encoding/iso8859-4.txt                       |   303 +
 tools/encoding/iso8859-5.txt                       |   303 +
 tools/encoding/iso8859-6.txt                       |   260 +
 tools/encoding/iso8859-7.txt                       |   302 +
 tools/encoding/iso8859-8.txt                       |   270 +
 tools/encoding/iso8859-9.txt                       |   307 +
 tools/encoding/jis0201.txt                         |   202 +
 tools/encoding/jis0208.txt                         |  6940 ++++
 tools/encoding/jis0212.txt                         |  6141 +++
 tools/encoding/koi8-r.txt                          |   302 +
 tools/encoding/ksc5601.txt                         |  8262 +++++
 tools/encoding/macCentEuro.txt                     |   319 +
 tools/encoding/macCroatian.txt                     |   347 +
 tools/encoding/macCyrillic.txt                     |   344 +
 tools/encoding/macDingbats.txt                     |   260 +
 tools/encoding/macGreek.txt                        |   338 +
 tools/encoding/macIceland.txt                      |   365 +
 tools/encoding/macJapan.txt                        |  7598 ++++
 tools/encoding/macRoman.txt                        |   364 +
 tools/encoding/macRomania.txt                      |   285 +
 tools/encoding/macThai.txt                         |   299 +
 tools/encoding/macTurkish.txt                      |   334 +
 tools/encoding/macUkraine.txt                      |   279 +
 tools/encoding/shiftjis.txt                        |  7096 ++++
 tools/encoding/symbol.txt                          |   265 +
 tools/encoding/tis-620.txt                         |   263 +
 tools/encoding/txt2enc.c                           |   251 +
 tools/eolFix.tcl                                   |    80 +
 tools/feather.bmp                                  |   Bin 0 -> 2102 bytes
 tools/findBadExternals.tcl                         |    53 +
 tools/fix_tommath_h.tcl                            |   102 +
 tools/genStubs.tcl                                 |  1179 +
 tools/index.tcl                                    |   199 +
 tools/installData.tcl                              |    50 +
 tools/loadICU.tcl                                  |   619 +
 tools/makeTestCases.tcl                            |  1180 +
 tools/man2help.tcl                                 |   141 +
 tools/man2help2.tcl                                |  1033 +
 tools/man2html.tcl                                 |   185 +
 tools/man2html1.tcl                                |   258 +
 tools/man2html2.tcl                                |   927 +
 tools/man2tcl.c                                    |   424 +
 tools/mkdepend.tcl                                 |   420 +
 tools/regexpTestLib.tcl                            |   263 +
 tools/str2c                                        |    59 +
 tools/tcl.hpj.in                                   |    19 +
 tools/tclZIC.tcl                                   |  1373 +
 tools/tclsh.svg                                    |    67 +
 tools/tcltk-man2html-utils.tcl                     |  1629 +
 tools/tcltk-man2html.tcl                           |   752 +
 tools/tsdPerf.c                                    |    59 +
 tools/tsdPerf.tcl                                  |    24 +
 tools/uniClass.tcl                                 |   130 +
 tools/uniParse.tcl                                 |   411 +
 tools/white.bmp                                    |   Bin 0 -> 20522 bytes
 unix/Makefile.in                                   |  2117 ++
 unix/README                                        |   169 +
 unix/aclocal.m4                                    |     1 +
 unix/configure                                     | 20272 ++++++++++
 unix/configure.in                                  |   998 +
 unix/dltest/Makefile.in                            |   110 +
 unix/dltest/README                                 |     4 +
 unix/dltest/pkga.c                                 |   145 +
 unix/dltest/pkgb.c                                 |   190 +
 unix/dltest/pkgc.c                                 |   170 +
 unix/dltest/pkgd.c                                 |   170 +
 unix/dltest/pkge.c                                 |    54 +
 unix/dltest/pkgooa.c                               |   141 +
 unix/dltest/pkgua.c                                |   341 +
 unix/install-sh                                    |   528 +
 unix/installManPage                                |   117 +
 unix/ldAix                                         |    58 +
 unix/tcl.m4                                        |  3138 ++
 unix/tcl.pc.in                                     |    15 +
 unix/tcl.spec                                      |    52 +
 unix/tclAppInit.c                                  |   169 +
 unix/tclConfig.h.in                                |   511 +
 unix/tclConfig.sh.in                               |   169 +
 unix/tclLoadAix.c                                  |   630 +
 unix/tclLoadDl.c                                   |   274 +
 unix/tclLoadDyld.c                                 |   717 +
 unix/tclLoadNext.c                                 |   217 +
 unix/tclLoadOSF.c                                  |   235 +
 unix/tclLoadShl.c                                  |   224 +
 unix/tclUnixChan.c                                 |  1937 +
 unix/tclUnixCompat.c                               |  1022 +
 unix/tclUnixEvent.c                                |    95 +
 unix/tclUnixFCmd.c                                 |  2517 ++
 unix/tclUnixFile.c                                 |  1243 +
 unix/tclUnixInit.c                                 |  1078 +
 unix/tclUnixNotfy.c                                |  1493 +
 unix/tclUnixPipe.c                                 |  1327 +
 unix/tclUnixPort.h                                 |   725 +
 unix/tclUnixSock.c                                 |  1665 +
 unix/tclUnixTest.c                                 |   782 +
 unix/tclUnixThrd.c                                 |   823 +
 unix/tclUnixThrd.h                                 |    19 +
 unix/tclUnixTime.c                                 |   541 +
 unix/tclXtNotify.c                                 |   667 +
 unix/tclXtTest.c                                   |   134 +
 unix/tclooConfig.sh                                |    19 +
 win/Makefile.in                                    |   882 +
 win/README                                         |    99 +
 win/aclocal.m4                                     |     1 +
 win/buildall.vc.bat                                |   103 +
 win/cat.c                                          |    41 +
 win/coffbase.txt                                   |    43 +
 win/configure                                      |  6296 ++++
 win/configure.in                                   |   464 +
 win/makefile.bc                                    |   594 +
 win/makefile.vc                                    |  1239 +
 win/nmakehlp.c                                     |   697 +
 win/rules.vc                                       |   698 +
 win/tcl.dsp                                        |  1567 +
 win/tcl.dsw                                        |    29 +
 win/tcl.hpj.in                                     |    19 +
 win/tcl.m4                                         |  1299 +
 win/tcl.rc                                         |    57 +
 win/tclAppInit.c                                   |   338 +
 win/tclConfig.sh.in                                |   180 +
 win/tclWin32Dll.c                                  |   801 +
 win/tclWinChan.c                                   |  1588 +
 win/tclWinConsole.c                                |  1502 +
 win/tclWinDde.c                                    |  1901 +
 win/tclWinError.c                                  |   428 +
 win/tclWinFCmd.c                                   |  1968 +
 win/tclWinFile.c                                   |  3204 ++
 win/tclWinInit.c                                   |   721 +
 win/tclWinInt.h                                    |    89 +
 win/tclWinLoad.c                                   |   402 +
 win/tclWinNotify.c                                 |   608 +
 win/tclWinPipe.c                                   |  3167 ++
 win/tclWinPort.h                                   |   571 +
 win/tclWinReg.c                                    |  1547 +
 win/tclWinSerial.c                                 |  2297 ++
 win/tclWinSock.c                                   |  3376 ++
 win/tclWinTest.c                                   |   663 +
 win/tclWinThrd.c                                   |  1102 +
 win/tclWinTime.c                                   |  1165 +
 win/tclooConfig.sh                                 |    19 +
 win/tclsh.exe.manifest.in                          |    53 +
 win/tclsh.ico                                      |   Bin 0 -> 57022 bytes
 win/tclsh.rc                                       |    82 +
 2050 files changed, 997531 insertions(+)
 create mode 100644 .fossil-settings/binary-glob
 create mode 100644 .fossil-settings/crnl-glob
 create mode 100644 .fossil-settings/encoding-glob
 create mode 100644 .fossil-settings/ignore-glob
 create mode 100644 .project
 create mode 100644 .settings/org.eclipse.core.resources.prefs
 create mode 100644 .settings/org.eclipse.core.runtime.prefs
 create mode 100644 ChangeLog
 create mode 100644 ChangeLog.1999
 create mode 100644 ChangeLog.2000
 create mode 100644 ChangeLog.2001
 create mode 100644 ChangeLog.2002
 create mode 100644 ChangeLog.2003
 create mode 100644 ChangeLog.2004
 create mode 100644 ChangeLog.2005
 create mode 100644 ChangeLog.2007
 create mode 100644 ChangeLog.2008
 create mode 100644 README
 create mode 100644 changes
 create mode 100644 compat/README
 create mode 100644 compat/dirent.h
 create mode 100644 compat/dirent2.h
 create mode 100644 compat/dlfcn.h
 create mode 100644 compat/fake-rfc2553.c
 create mode 100644 compat/fake-rfc2553.h
 create mode 100644 compat/fixstrtod.c
 create mode 100644 compat/float.h
 create mode 100644 compat/gettod.c
 create mode 100644 compat/memcmp.c
 create mode 100644 compat/mkstemp.c
 create mode 100644 compat/opendir.c
 create mode 100644 compat/stdlib.h
 create mode 100644 compat/string.h
 create mode 100644 compat/strncasecmp.c
 create mode 100644 compat/strstr.c
 create mode 100644 compat/strtod.c
 create mode 100644 compat/strtol.c
 create mode 100644 compat/strtoul.c
 create mode 100644 compat/unistd.h
 create mode 100644 compat/waitpid.c
 create mode 100644 compat/zlib/CMakeLists.txt
 create mode 100644 compat/zlib/ChangeLog
 create mode 100644 compat/zlib/FAQ
 create mode 100644 compat/zlib/INDEX
 create mode 100644 compat/zlib/Makefile
 create mode 100644 compat/zlib/Makefile.in
 create mode 100644 compat/zlib/README
 create mode 100644 compat/zlib/adler32.c
 create mode 100644 compat/zlib/amiga/Makefile.pup
 create mode 100644 compat/zlib/amiga/Makefile.sas
 create mode 100644 compat/zlib/as400/bndsrc
 create mode 100644 compat/zlib/as400/compile.clp
 create mode 100644 compat/zlib/as400/readme.txt
 create mode 100644 compat/zlib/as400/zlib.inc
 create mode 100644 compat/zlib/compress.c
 create mode 100755 compat/zlib/configure
 create mode 100644 compat/zlib/contrib/README.contrib
 create mode 100644 compat/zlib/contrib/ada/buffer_demo.adb
 create mode 100644 compat/zlib/contrib/ada/mtest.adb
 create mode 100644 compat/zlib/contrib/ada/read.adb
 create mode 100644 compat/zlib/contrib/ada/readme.txt
 create mode 100644 compat/zlib/contrib/ada/test.adb
 create mode 100644 compat/zlib/contrib/ada/zlib-streams.adb
 create mode 100644 compat/zlib/contrib/ada/zlib-streams.ads
 create mode 100644 compat/zlib/contrib/ada/zlib-thin.adb
 create mode 100644 compat/zlib/contrib/ada/zlib-thin.ads
 create mode 100644 compat/zlib/contrib/ada/zlib.adb
 create mode 100644 compat/zlib/contrib/ada/zlib.ads
 create mode 100644 compat/zlib/contrib/ada/zlib.gpr
 create mode 100644 compat/zlib/contrib/amd64/amd64-match.S
 create mode 100644 compat/zlib/contrib/asm686/README.686
 create mode 100644 compat/zlib/contrib/asm686/match.S
 create mode 100644 compat/zlib/contrib/blast/Makefile
 create mode 100644 compat/zlib/contrib/blast/README
 create mode 100644 compat/zlib/contrib/blast/blast.c
 create mode 100644 compat/zlib/contrib/blast/blast.h
 create mode 100644 compat/zlib/contrib/blast/test.pk
 create mode 100644 compat/zlib/contrib/blast/test.txt
 create mode 100644 compat/zlib/contrib/delphi/ZLib.pas
 create mode 100644 compat/zlib/contrib/delphi/ZLibConst.pas
 create mode 100644 compat/zlib/contrib/delphi/readme.txt
 create mode 100644 compat/zlib/contrib/delphi/zlibd32.mak
 create mode 100644 compat/zlib/contrib/dotzlib/DotZLib.build
 create mode 100644 compat/zlib/contrib/dotzlib/DotZLib.chm
 create mode 100644 compat/zlib/contrib/dotzlib/DotZLib.sln
 create mode 100644 compat/zlib/contrib/dotzlib/DotZLib/AssemblyInfo.cs
 create mode 100644 compat/zlib/contrib/dotzlib/DotZLib/ChecksumImpl.cs
 create mode 100644 compat/zlib/contrib/dotzlib/DotZLib/CircularBuffer.cs
 create mode 100644 compat/zlib/contrib/dotzlib/DotZLib/CodecBase.cs
 create mode 100644 compat/zlib/contrib/dotzlib/DotZLib/Deflater.cs
 create mode 100644 compat/zlib/contrib/dotzlib/DotZLib/DotZLib.cs
 create mode 100644 compat/zlib/contrib/dotzlib/DotZLib/DotZLib.csproj
 create mode 100644 compat/zlib/contrib/dotzlib/DotZLib/GZipStream.cs
 create mode 100644 compat/zlib/contrib/dotzlib/DotZLib/Inflater.cs
 create mode 100644 compat/zlib/contrib/dotzlib/DotZLib/UnitTests.cs
 create mode 100644 compat/zlib/contrib/dotzlib/LICENSE_1_0.txt
 create mode 100644 compat/zlib/contrib/dotzlib/readme.txt
 create mode 100644 compat/zlib/contrib/gcc_gvmat64/gvmat64.S
 create mode 100644 compat/zlib/contrib/infback9/README
 create mode 100644 compat/zlib/contrib/infback9/infback9.c
 create mode 100644 compat/zlib/contrib/infback9/infback9.h
 create mode 100644 compat/zlib/contrib/infback9/inffix9.h
 create mode 100644 compat/zlib/contrib/infback9/inflate9.h
 create mode 100644 compat/zlib/contrib/infback9/inftree9.c
 create mode 100644 compat/zlib/contrib/infback9/inftree9.h
 create mode 100644 compat/zlib/contrib/inflate86/inffas86.c
 create mode 100644 compat/zlib/contrib/inflate86/inffast.S
 create mode 100644 compat/zlib/contrib/iostream/test.cpp
 create mode 100644 compat/zlib/contrib/iostream/zfstream.cpp
 create mode 100644 compat/zlib/contrib/iostream/zfstream.h
 create mode 100644 compat/zlib/contrib/iostream2/zstream.h
 create mode 100644 compat/zlib/contrib/iostream2/zstream_test.cpp
 create mode 100644 compat/zlib/contrib/iostream3/README
 create mode 100644 compat/zlib/contrib/iostream3/TODO
 create mode 100644 compat/zlib/contrib/iostream3/test.cc
 create mode 100644 compat/zlib/contrib/iostream3/zfstream.cc
 create mode 100644 compat/zlib/contrib/iostream3/zfstream.h
 create mode 100644 compat/zlib/contrib/masmx64/bld_ml64.bat
 create mode 100644 compat/zlib/contrib/masmx64/gvmat64.asm
 create mode 100644 compat/zlib/contrib/masmx64/inffas8664.c
 create mode 100644 compat/zlib/contrib/masmx64/inffasx64.asm
 create mode 100644 compat/zlib/contrib/masmx64/readme.txt
 create mode 100644 compat/zlib/contrib/masmx86/bld_ml32.bat
 create mode 100644 compat/zlib/contrib/masmx86/inffas32.asm
 create mode 100644 compat/zlib/contrib/masmx86/match686.asm
 create mode 100644 compat/zlib/contrib/masmx86/readme.txt
 create mode 100644 compat/zlib/contrib/minizip/Makefile
 create mode 100644 compat/zlib/contrib/minizip/Makefile.am
 create mode 100644 compat/zlib/contrib/minizip/MiniZip64_Changes.txt
 create mode 100644 compat/zlib/contrib/minizip/MiniZip64_info.txt
 create mode 100644 compat/zlib/contrib/minizip/configure.ac
 create mode 100644 compat/zlib/contrib/minizip/crypt.h
 create mode 100644 compat/zlib/contrib/minizip/ioapi.c
 create mode 100644 compat/zlib/contrib/minizip/ioapi.h
 create mode 100644 compat/zlib/contrib/minizip/iowin32.c
 create mode 100644 compat/zlib/contrib/minizip/iowin32.h
 create mode 100644 compat/zlib/contrib/minizip/make_vms.com
 create mode 100644 compat/zlib/contrib/minizip/miniunz.c
 create mode 100644 compat/zlib/contrib/minizip/miniunzip.1
 create mode 100644 compat/zlib/contrib/minizip/minizip.1
 create mode 100644 compat/zlib/contrib/minizip/minizip.c
 create mode 100644 compat/zlib/contrib/minizip/minizip.pc.in
 create mode 100644 compat/zlib/contrib/minizip/mztools.c
 create mode 100644 compat/zlib/contrib/minizip/mztools.h
 create mode 100644 compat/zlib/contrib/minizip/unzip.c
 create mode 100644 compat/zlib/contrib/minizip/unzip.h
 create mode 100644 compat/zlib/contrib/minizip/zip.c
 create mode 100644 compat/zlib/contrib/minizip/zip.h
 create mode 100644 compat/zlib/contrib/pascal/example.pas
 create mode 100644 compat/zlib/contrib/pascal/readme.txt
 create mode 100644 compat/zlib/contrib/pascal/zlibd32.mak
 create mode 100644 compat/zlib/contrib/pascal/zlibpas.pas
 create mode 100644 compat/zlib/contrib/puff/Makefile
 create mode 100644 compat/zlib/contrib/puff/README
 create mode 100644 compat/zlib/contrib/puff/puff.c
 create mode 100644 compat/zlib/contrib/puff/puff.h
 create mode 100644 compat/zlib/contrib/puff/pufftest.c
 create mode 100644 compat/zlib/contrib/puff/zeros.raw
 create mode 100644 compat/zlib/contrib/testzlib/testzlib.c
 create mode 100644 compat/zlib/contrib/testzlib/testzlib.txt
 create mode 100644 compat/zlib/contrib/untgz/Makefile
 create mode 100644 compat/zlib/contrib/untgz/Makefile.msc
 create mode 100644 compat/zlib/contrib/untgz/untgz.c
 create mode 100644 compat/zlib/contrib/vstudio/readme.txt
 create mode 100644 compat/zlib/contrib/vstudio/vc10/miniunz.vcxproj
 create mode 100644 compat/zlib/contrib/vstudio/vc10/miniunz.vcxproj.filters
 create mode 100644 compat/zlib/contrib/vstudio/vc10/minizip.vcxproj
 create mode 100644 compat/zlib/contrib/vstudio/vc10/minizip.vcxproj.filters
 create mode 100644 compat/zlib/contrib/vstudio/vc10/testzlib.vcxproj
 create mode 100644 compat/zlib/contrib/vstudio/vc10/testzlib.vcxproj.filters
 create mode 100644 compat/zlib/contrib/vstudio/vc10/testzlibdll.vcxproj
 create mode 100644 compat/zlib/contrib/vstudio/vc10/testzlibdll.vcxproj.filters
 create mode 100644 compat/zlib/contrib/vstudio/vc10/zlib.rc
 create mode 100644 compat/zlib/contrib/vstudio/vc10/zlibstat.vcxproj
 create mode 100644 compat/zlib/contrib/vstudio/vc10/zlibstat.vcxproj.filters
 create mode 100644 compat/zlib/contrib/vstudio/vc10/zlibvc.def
 create mode 100644 compat/zlib/contrib/vstudio/vc10/zlibvc.sln
 create mode 100644 compat/zlib/contrib/vstudio/vc10/zlibvc.vcxproj
 create mode 100644 compat/zlib/contrib/vstudio/vc10/zlibvc.vcxproj.filters
 create mode 100644 compat/zlib/contrib/vstudio/vc11/miniunz.vcxproj
 create mode 100644 compat/zlib/contrib/vstudio/vc11/minizip.vcxproj
 create mode 100644 compat/zlib/contrib/vstudio/vc11/testzlib.vcxproj
 create mode 100644 compat/zlib/contrib/vstudio/vc11/testzlibdll.vcxproj
 create mode 100644 compat/zlib/contrib/vstudio/vc11/zlib.rc
 create mode 100644 compat/zlib/contrib/vstudio/vc11/zlibstat.vcxproj
 create mode 100644 compat/zlib/contrib/vstudio/vc11/zlibvc.def
 create mode 100644 compat/zlib/contrib/vstudio/vc11/zlibvc.sln
 create mode 100644 compat/zlib/contrib/vstudio/vc11/zlibvc.vcxproj
 create mode 100644 compat/zlib/contrib/vstudio/vc9/miniunz.vcproj
 create mode 100644 compat/zlib/contrib/vstudio/vc9/minizip.vcproj
 create mode 100644 compat/zlib/contrib/vstudio/vc9/testzlib.vcproj
 create mode 100644 compat/zlib/contrib/vstudio/vc9/testzlibdll.vcproj
 create mode 100644 compat/zlib/contrib/vstudio/vc9/zlib.rc
 create mode 100644 compat/zlib/contrib/vstudio/vc9/zlibstat.vcproj
 create mode 100644 compat/zlib/contrib/vstudio/vc9/zlibvc.def
 create mode 100644 compat/zlib/contrib/vstudio/vc9/zlibvc.sln
 create mode 100644 compat/zlib/contrib/vstudio/vc9/zlibvc.vcproj
 create mode 100644 compat/zlib/crc32.c
 create mode 100644 compat/zlib/crc32.h
 create mode 100644 compat/zlib/deflate.c
 create mode 100644 compat/zlib/deflate.h
 create mode 100644 compat/zlib/doc/algorithm.txt
 create mode 100644 compat/zlib/doc/rfc1950.txt
 create mode 100644 compat/zlib/doc/rfc1951.txt
 create mode 100644 compat/zlib/doc/rfc1952.txt
 create mode 100644 compat/zlib/doc/txtvsbin.txt
 create mode 100644 compat/zlib/examples/README.examples
 create mode 100644 compat/zlib/examples/enough.c
 create mode 100644 compat/zlib/examples/fitblk.c
 create mode 100644 compat/zlib/examples/gun.c
 create mode 100644 compat/zlib/examples/gzappend.c
 create mode 100644 compat/zlib/examples/gzjoin.c
 create mode 100644 compat/zlib/examples/gzlog.c
 create mode 100644 compat/zlib/examples/gzlog.h
 create mode 100644 compat/zlib/examples/zlib_how.html
 create mode 100644 compat/zlib/examples/zpipe.c
 create mode 100644 compat/zlib/examples/zran.c
 create mode 100644 compat/zlib/gzclose.c
 create mode 100644 compat/zlib/gzguts.h
 create mode 100644 compat/zlib/gzlib.c
 create mode 100644 compat/zlib/gzread.c
 create mode 100644 compat/zlib/gzwrite.c
 create mode 100644 compat/zlib/infback.c
 create mode 100644 compat/zlib/inffast.c
 create mode 100644 compat/zlib/inffast.h
 create mode 100644 compat/zlib/inffixed.h
 create mode 100644 compat/zlib/inflate.c
 create mode 100644 compat/zlib/inflate.h
 create mode 100644 compat/zlib/inftrees.c
 create mode 100644 compat/zlib/inftrees.h
 create mode 100644 compat/zlib/make_vms.com
 create mode 100644 compat/zlib/msdos/Makefile.bor
 create mode 100644 compat/zlib/msdos/Makefile.dj2
 create mode 100644 compat/zlib/msdos/Makefile.emx
 create mode 100644 compat/zlib/msdos/Makefile.msc
 create mode 100644 compat/zlib/msdos/Makefile.tc
 create mode 100644 compat/zlib/nintendods/Makefile
 create mode 100644 compat/zlib/nintendods/README
 create mode 100644 compat/zlib/old/Makefile.emx
 create mode 100644 compat/zlib/old/Makefile.riscos
 create mode 100644 compat/zlib/old/README
 create mode 100644 compat/zlib/old/descrip.mms
 create mode 100644 compat/zlib/old/os2/Makefile.os2
 create mode 100644 compat/zlib/old/os2/zlib.def
 create mode 100644 compat/zlib/old/visual-basic.txt
 create mode 100644 compat/zlib/qnx/package.qpg
 create mode 100644 compat/zlib/test/example.c
 create mode 100644 compat/zlib/test/infcover.c
 create mode 100644 compat/zlib/test/minigzip.c
 create mode 100644 compat/zlib/treebuild.xml
 create mode 100644 compat/zlib/trees.c
 create mode 100644 compat/zlib/trees.h
 create mode 100644 compat/zlib/uncompr.c
 create mode 100644 compat/zlib/watcom/watcom_f.mak
 create mode 100644 compat/zlib/watcom/watcom_l.mak
 create mode 100644 compat/zlib/win32/DLL_FAQ.txt
 create mode 100644 compat/zlib/win32/Makefile.bor
 create mode 100644 compat/zlib/win32/Makefile.gcc
 create mode 100644 compat/zlib/win32/Makefile.msc
 create mode 100644 compat/zlib/win32/README-WIN32.txt
 create mode 100644 compat/zlib/win32/README.txt
 create mode 100644 compat/zlib/win32/USAGE.txt
 create mode 100644 compat/zlib/win32/VisualC.txt
 create mode 100644 compat/zlib/win32/zdll.lib
 create mode 100644 compat/zlib/win32/zlib.def
 create mode 100755 compat/zlib/win32/zlib1.dll
 create mode 100644 compat/zlib/win32/zlib1.rc
 create mode 100644 compat/zlib/win64/libz.dll.a
 create mode 100644 compat/zlib/win64/zdll.lib
 create mode 100755 compat/zlib/win64/zlib1.dll
 create mode 100644 compat/zlib/zconf.h
 create mode 100644 compat/zlib/zconf.h.cmakein
 create mode 100644 compat/zlib/zconf.h.in
 create mode 100644 compat/zlib/zlib.3
 create mode 100644 compat/zlib/zlib.3.pdf
 create mode 100644 compat/zlib/zlib.h
 create mode 100644 compat/zlib/zlib.map
 create mode 100644 compat/zlib/zlib.pc.cmakein
 create mode 100644 compat/zlib/zlib.pc.in
 create mode 100644 compat/zlib/zlib2ansi
 create mode 100644 compat/zlib/zutil.c
 create mode 100644 compat/zlib/zutil.h
 create mode 100644 doc/Access.3
 create mode 100644 doc/AddErrInfo.3
 create mode 100644 doc/Alloc.3
 create mode 100644 doc/AllowExc.3
 create mode 100644 doc/AppInit.3
 create mode 100644 doc/AssocData.3
 create mode 100644 doc/Async.3
 create mode 100644 doc/BackgdErr.3
 create mode 100644 doc/Backslash.3
 create mode 100644 doc/BoolObj.3
 create mode 100644 doc/ByteArrObj.3
 create mode 100644 doc/CallDel.3
 create mode 100644 doc/Cancel.3
 create mode 100644 doc/ChnlStack.3
 create mode 100644 doc/Class.3
 create mode 100644 doc/CmdCmplt.3
 create mode 100644 doc/Concat.3
 create mode 100644 doc/CrtChannel.3
 create mode 100644 doc/CrtChnlHdlr.3
 create mode 100644 doc/CrtCloseHdlr.3
 create mode 100644 doc/CrtCommand.3
 create mode 100644 doc/CrtFileHdlr.3
 create mode 100644 doc/CrtInterp.3
 create mode 100644 doc/CrtMathFnc.3
 create mode 100644 doc/CrtObjCmd.3
 create mode 100644 doc/CrtSlave.3
 create mode 100644 doc/CrtTimerHdlr.3
 create mode 100644 doc/CrtTrace.3
 create mode 100644 doc/DString.3
 create mode 100644 doc/DetachPids.3
 create mode 100644 doc/DictObj.3
 create mode 100644 doc/DoOneEvent.3
 create mode 100644 doc/DoWhenIdle.3
 create mode 100644 doc/DoubleObj.3
 create mode 100644 doc/DumpActiveMemory.3
 create mode 100644 doc/Encoding.3
 create mode 100644 doc/Ensemble.3
 create mode 100644 doc/Environment.3
 create mode 100644 doc/Eval.3
 create mode 100644 doc/Exit.3
 create mode 100644 doc/ExprLong.3
 create mode 100644 doc/ExprLongObj.3
 create mode 100644 doc/FileSystem.3
 create mode 100644 doc/FindExec.3
 create mode 100644 doc/GetCwd.3
 create mode 100644 doc/GetHostName.3
 create mode 100644 doc/GetIndex.3
 create mode 100644 doc/GetInt.3
 create mode 100644 doc/GetOpnFl.3
 create mode 100644 doc/GetStdChan.3
 create mode 100644 doc/GetTime.3
 create mode 100644 doc/GetVersion.3
 create mode 100644 doc/Hash.3
 create mode 100644 doc/Init.3
 create mode 100644 doc/InitStubs.3
 create mode 100644 doc/IntObj.3
 create mode 100644 doc/Interp.3
 create mode 100644 doc/Limit.3
 create mode 100644 doc/LinkVar.3
 create mode 100644 doc/ListObj.3
 create mode 100644 doc/Load.3
 create mode 100644 doc/Method.3
 create mode 100644 doc/NRE.3
 create mode 100644 doc/Namespace.3
 create mode 100644 doc/Notifier.3
 create mode 100644 doc/OOInitStubs.3
 create mode 100644 doc/Object.3
 create mode 100644 doc/ObjectType.3
 create mode 100644 doc/OpenFileChnl.3
 create mode 100644 doc/OpenTcp.3
 create mode 100644 doc/Panic.3
 create mode 100644 doc/ParseArgs.3
 create mode 100644 doc/ParseCmd.3
 create mode 100644 doc/PkgRequire.3
 create mode 100644 doc/Preserve.3
 create mode 100644 doc/PrintDbl.3
 create mode 100644 doc/RecEvalObj.3
 create mode 100644 doc/RecordEval.3
 create mode 100644 doc/RegConfig.3
 create mode 100644 doc/RegExp.3
 create mode 100644 doc/SaveResult.3
 create mode 100644 doc/SetChanErr.3
 create mode 100644 doc/SetErrno.3
 create mode 100644 doc/SetRecLmt.3
 create mode 100644 doc/SetResult.3
 create mode 100644 doc/SetVar.3
 create mode 100644 doc/Signal.3
 create mode 100644 doc/Sleep.3
 create mode 100644 doc/SourceRCFile.3
 create mode 100644 doc/SplitList.3
 create mode 100644 doc/SplitPath.3
 create mode 100644 doc/StaticPkg.3
 create mode 100644 doc/StdChannels.3
 create mode 100644 doc/StrMatch.3
 create mode 100644 doc/StringObj.3
 create mode 100644 doc/SubstObj.3
 create mode 100644 doc/TCL_MEM_DEBUG.3
 create mode 100644 doc/Tcl.n
 create mode 100644 doc/TclZlib.3
 create mode 100644 doc/Tcl_Main.3
 create mode 100644 doc/Thread.3
 create mode 100644 doc/ToUpper.3
 create mode 100644 doc/TraceCmd.3
 create mode 100644 doc/TraceVar.3
 create mode 100644 doc/Translate.3
 create mode 100644 doc/UniCharIsAlpha.3
 create mode 100644 doc/UpVar.3
 create mode 100644 doc/Utf.3
 create mode 100644 doc/WrongNumArgs.3
 create mode 100644 doc/after.n
 create mode 100644 doc/append.n
 create mode 100644 doc/apply.n
 create mode 100644 doc/array.n
 create mode 100644 doc/bgerror.n
 create mode 100644 doc/binary.n
 create mode 100644 doc/break.n
 create mode 100644 doc/case.n
 create mode 100644 doc/catch.n
 create mode 100644 doc/cd.n
 create mode 100644 doc/chan.n
 create mode 100644 doc/class.n
 create mode 100644 doc/clock.n
 create mode 100644 doc/close.n
 create mode 100644 doc/concat.n
 create mode 100644 doc/continue.n
 create mode 100644 doc/copy.n
 create mode 100644 doc/coroutine.n
 create mode 100644 doc/dde.n
 create mode 100644 doc/define.n
 create mode 100644 doc/dict.n
 create mode 100644 doc/encoding.n
 create mode 100644 doc/eof.n
 create mode 100644 doc/error.n
 create mode 100644 doc/eval.n
 create mode 100644 doc/exec.n
 create mode 100644 doc/exit.n
 create mode 100644 doc/expr.n
 create mode 100644 doc/fblocked.n
 create mode 100644 doc/fconfigure.n
 create mode 100644 doc/fcopy.n
 create mode 100644 doc/file.n
 create mode 100644 doc/fileevent.n
 create mode 100644 doc/filename.n
 create mode 100644 doc/flush.n
 create mode 100644 doc/for.n
 create mode 100644 doc/foreach.n
 create mode 100644 doc/format.n
 create mode 100644 doc/gets.n
 create mode 100644 doc/glob.n
 create mode 100644 doc/global.n
 create mode 100644 doc/history.n
 create mode 100644 doc/http.n
 create mode 100644 doc/if.n
 create mode 100644 doc/incr.n
 create mode 100644 doc/info.n
 create mode 100644 doc/interp.n
 create mode 100644 doc/join.n
 create mode 100644 doc/lappend.n
 create mode 100644 doc/lassign.n
 create mode 100644 doc/library.n
 create mode 100644 doc/lindex.n
 create mode 100644 doc/linsert.n
 create mode 100644 doc/list.n
 create mode 100644 doc/llength.n
 create mode 100644 doc/lmap.n
 create mode 100644 doc/load.n
 create mode 100644 doc/lrange.n
 create mode 100644 doc/lrepeat.n
 create mode 100644 doc/lreplace.n
 create mode 100644 doc/lreverse.n
 create mode 100644 doc/lsearch.n
 create mode 100644 doc/lset.n
 create mode 100644 doc/lsort.n
 create mode 100644 doc/man.macros
 create mode 100644 doc/mathfunc.n
 create mode 100644 doc/mathop.n
 create mode 100644 doc/memory.n
 create mode 100644 doc/msgcat.n
 create mode 100644 doc/my.n
 create mode 100644 doc/namespace.n
 create mode 100644 doc/next.n
 create mode 100644 doc/object.n
 create mode 100644 doc/open.n
 create mode 100644 doc/package.n
 create mode 100644 doc/packagens.n
 create mode 100644 doc/pid.n
 create mode 100644 doc/pkgMkIndex.n
 create mode 100644 doc/platform.n
 create mode 100644 doc/platform_shell.n
 create mode 100644 doc/prefix.n
 create mode 100644 doc/proc.n
 create mode 100644 doc/puts.n
 create mode 100644 doc/pwd.n
 create mode 100644 doc/re_syntax.n
 create mode 100644 doc/read.n
 create mode 100644 doc/refchan.n
 create mode 100644 doc/regexp.n
 create mode 100644 doc/registry.n
 create mode 100644 doc/regsub.n
 create mode 100644 doc/rename.n
 create mode 100644 doc/return.n
 create mode 100644 doc/safe.n
 create mode 100644 doc/scan.n
 create mode 100644 doc/seek.n
 create mode 100644 doc/self.n
 create mode 100644 doc/set.n
 create mode 100644 doc/socket.n
 create mode 100644 doc/source.n
 create mode 100644 doc/split.n
 create mode 100644 doc/string.n
 create mode 100644 doc/subst.n
 create mode 100644 doc/switch.n
 create mode 100644 doc/tailcall.n
 create mode 100644 doc/tclsh.1
 create mode 100644 doc/tcltest.n
 create mode 100644 doc/tclvars.n
 create mode 100644 doc/tell.n
 create mode 100644 doc/throw.n
 create mode 100644 doc/time.n
 create mode 100644 doc/tm.n
 create mode 100644 doc/trace.n
 create mode 100644 doc/transchan.n
 create mode 100644 doc/try.n
 create mode 100644 doc/unknown.n
 create mode 100644 doc/unload.n
 create mode 100644 doc/unset.n
 create mode 100644 doc/update.n
 create mode 100644 doc/uplevel.n
 create mode 100644 doc/upvar.n
 create mode 100644 doc/variable.n
 create mode 100644 doc/vwait.n
 create mode 100644 doc/while.n
 create mode 100644 doc/zlib.n
 create mode 100644 generic/README
 create mode 100644 generic/regc_color.c
 create mode 100644 generic/regc_cvec.c
 create mode 100644 generic/regc_lex.c
 create mode 100644 generic/regc_locale.c
 create mode 100644 generic/regc_nfa.c
 create mode 100644 generic/regcomp.c
 create mode 100644 generic/regcustom.h
 create mode 100644 generic/rege_dfa.c
 create mode 100644 generic/regerror.c
 create mode 100644 generic/regerrs.h
 create mode 100644 generic/regex.h
 create mode 100644 generic/regexec.c
 create mode 100644 generic/regfree.c
 create mode 100644 generic/regfronts.c
 create mode 100644 generic/regguts.h
 create mode 100644 generic/tcl.decls
 create mode 100644 generic/tcl.h
 create mode 100644 generic/tclAlloc.c
 create mode 100644 generic/tclAssembly.c
 create mode 100644 generic/tclAsync.c
 create mode 100644 generic/tclBasic.c
 create mode 100644 generic/tclBinary.c
 create mode 100644 generic/tclCkalloc.c
 create mode 100644 generic/tclClock.c
 create mode 100644 generic/tclCmdAH.c
 create mode 100644 generic/tclCmdIL.c
 create mode 100644 generic/tclCmdMZ.c
 create mode 100644 generic/tclCompCmds.c
 create mode 100644 generic/tclCompCmdsGR.c
 create mode 100644 generic/tclCompCmdsSZ.c
 create mode 100644 generic/tclCompExpr.c
 create mode 100644 generic/tclCompile.c
 create mode 100644 generic/tclCompile.h
 create mode 100644 generic/tclConfig.c
 create mode 100644 generic/tclDTrace.d
 create mode 100644 generic/tclDate.c
 create mode 100644 generic/tclDecls.h
 create mode 100644 generic/tclDictObj.c
 create mode 100644 generic/tclDisassemble.c
 create mode 100644 generic/tclEncoding.c
 create mode 100644 generic/tclEnsemble.c
 create mode 100644 generic/tclEnv.c
 create mode 100644 generic/tclEvent.c
 create mode 100644 generic/tclExecute.c
 create mode 100644 generic/tclFCmd.c
 create mode 100644 generic/tclFileName.c
 create mode 100644 generic/tclFileSystem.h
 create mode 100644 generic/tclGet.c
 create mode 100644 generic/tclGetDate.y
 create mode 100644 generic/tclHash.c
 create mode 100644 generic/tclHistory.c
 create mode 100644 generic/tclIO.c
 create mode 100644 generic/tclIO.h
 create mode 100644 generic/tclIOCmd.c
 create mode 100644 generic/tclIOGT.c
 create mode 100644 generic/tclIORChan.c
 create mode 100644 generic/tclIORTrans.c
 create mode 100644 generic/tclIOSock.c
 create mode 100644 generic/tclIOUtil.c
 create mode 100644 generic/tclIndexObj.c
 create mode 100644 generic/tclInt.decls
 create mode 100644 generic/tclInt.h
 create mode 100644 generic/tclIntDecls.h
 create mode 100644 generic/tclIntPlatDecls.h
 create mode 100644 generic/tclInterp.c
 create mode 100644 generic/tclLink.c
 create mode 100644 generic/tclListObj.c
 create mode 100644 generic/tclLiteral.c
 create mode 100644 generic/tclLoad.c
 create mode 100644 generic/tclLoadNone.c
 create mode 100644 generic/tclMain.c
 create mode 100644 generic/tclNamesp.c
 create mode 100644 generic/tclNotify.c
 create mode 100644 generic/tclOO.c
 create mode 100644 generic/tclOO.decls
 create mode 100644 generic/tclOO.h
 create mode 100644 generic/tclOOBasic.c
 create mode 100644 generic/tclOOCall.c
 create mode 100644 generic/tclOODecls.h
 create mode 100644 generic/tclOODefineCmds.c
 create mode 100644 generic/tclOOInfo.c
 create mode 100644 generic/tclOOInt.h
 create mode 100644 generic/tclOOIntDecls.h
 create mode 100644 generic/tclOOMethod.c
 create mode 100644 generic/tclOOStubInit.c
 create mode 100644 generic/tclOOStubLib.c
 create mode 100644 generic/tclObj.c
 create mode 100644 generic/tclOptimize.c
 create mode 100644 generic/tclPanic.c
 create mode 100644 generic/tclParse.c
 create mode 100644 generic/tclParse.h
 create mode 100644 generic/tclPathObj.c
 create mode 100644 generic/tclPipe.c
 create mode 100644 generic/tclPkg.c
 create mode 100644 generic/tclPkgConfig.c
 create mode 100644 generic/tclPlatDecls.h
 create mode 100644 generic/tclPort.h
 create mode 100644 generic/tclPosixStr.c
 create mode 100644 generic/tclPreserve.c
 create mode 100644 generic/tclProc.c
 create mode 100644 generic/tclRegexp.c
 create mode 100644 generic/tclRegexp.h
 create mode 100644 generic/tclResolve.c
 create mode 100644 generic/tclResult.c
 create mode 100644 generic/tclScan.c
 create mode 100644 generic/tclStrToD.c
 create mode 100644 generic/tclStringObj.c
 create mode 100644 generic/tclStringRep.h
 create mode 100644 generic/tclStringTrim.h
 create mode 100644 generic/tclStubInit.c
 create mode 100644 generic/tclStubLib.c
 create mode 100644 generic/tclStubLibTbl.c
 create mode 100644 generic/tclTest.c
 create mode 100644 generic/tclTestObj.c
 create mode 100644 generic/tclTestProcBodyObj.c
 create mode 100644 generic/tclThread.c
 create mode 100644 generic/tclThreadAlloc.c
 create mode 100644 generic/tclThreadJoin.c
 create mode 100644 generic/tclThreadStorage.c
 create mode 100644 generic/tclThreadTest.c
 create mode 100644 generic/tclTimer.c
 create mode 100644 generic/tclTomMath.decls
 create mode 100644 generic/tclTomMath.h
 create mode 100644 generic/tclTomMathDecls.h
 create mode 100644 generic/tclTomMathInt.h
 create mode 100644 generic/tclTomMathInterface.c
 create mode 100644 generic/tclTomMathStubLib.c
 create mode 100644 generic/tclTrace.c
 create mode 100644 generic/tclUniData.c
 create mode 100644 generic/tclUtf.c
 create mode 100644 generic/tclUtil.c
 create mode 100644 generic/tclVar.c
 create mode 100644 generic/tclZlib.c
 create mode 100644 generic/tommath.h
 create mode 100644 library/auto.tcl
 create mode 100755 library/clock.tcl
 create mode 100644 library/dde/pkgIndex.tcl
 create mode 100644 library/encoding/ascii.enc
 create mode 100644 library/encoding/big5.enc
 create mode 100644 library/encoding/cp1250.enc
 create mode 100644 library/encoding/cp1251.enc
 create mode 100644 library/encoding/cp1252.enc
 create mode 100644 library/encoding/cp1253.enc
 create mode 100644 library/encoding/cp1254.enc
 create mode 100644 library/encoding/cp1255.enc
 create mode 100644 library/encoding/cp1256.enc
 create mode 100644 library/encoding/cp1257.enc
 create mode 100644 library/encoding/cp1258.enc
 create mode 100644 library/encoding/cp437.enc
 create mode 100644 library/encoding/cp737.enc
 create mode 100644 library/encoding/cp775.enc
 create mode 100644 library/encoding/cp850.enc
 create mode 100644 library/encoding/cp852.enc
 create mode 100644 library/encoding/cp855.enc
 create mode 100644 library/encoding/cp857.enc
 create mode 100644 library/encoding/cp860.enc
 create mode 100644 library/encoding/cp861.enc
 create mode 100644 library/encoding/cp862.enc
 create mode 100644 library/encoding/cp863.enc
 create mode 100644 library/encoding/cp864.enc
 create mode 100644 library/encoding/cp865.enc
 create mode 100644 library/encoding/cp866.enc
 create mode 100644 library/encoding/cp869.enc
 create mode 100644 library/encoding/cp874.enc
 create mode 100644 library/encoding/cp932.enc
 create mode 100644 library/encoding/cp936.enc
 create mode 100644 library/encoding/cp949.enc
 create mode 100644 library/encoding/cp950.enc
 create mode 100644 library/encoding/dingbats.enc
 create mode 100644 library/encoding/ebcdic.enc
 create mode 100644 library/encoding/euc-cn.enc
 create mode 100644 library/encoding/euc-jp.enc
 create mode 100644 library/encoding/euc-kr.enc
 create mode 100644 library/encoding/gb12345.enc
 create mode 100644 library/encoding/gb1988.enc
 create mode 100644 library/encoding/gb2312-raw.enc
 create mode 100644 library/encoding/gb2312.enc
 create mode 100644 library/encoding/iso2022-jp.enc
 create mode 100644 library/encoding/iso2022-kr.enc
 create mode 100644 library/encoding/iso2022.enc
 create mode 100644 library/encoding/iso8859-1.enc
 create mode 100644 library/encoding/iso8859-10.enc
 create mode 100644 library/encoding/iso8859-13.enc
 create mode 100644 library/encoding/iso8859-14.enc
 create mode 100644 library/encoding/iso8859-15.enc
 create mode 100644 library/encoding/iso8859-16.enc
 create mode 100644 library/encoding/iso8859-2.enc
 create mode 100644 library/encoding/iso8859-3.enc
 create mode 100644 library/encoding/iso8859-4.enc
 create mode 100644 library/encoding/iso8859-5.enc
 create mode 100644 library/encoding/iso8859-6.enc
 create mode 100644 library/encoding/iso8859-7.enc
 create mode 100644 library/encoding/iso8859-8.enc
 create mode 100644 library/encoding/iso8859-9.enc
 create mode 100644 library/encoding/jis0201.enc
 create mode 100644 library/encoding/jis0208.enc
 create mode 100644 library/encoding/jis0212.enc
 create mode 100644 library/encoding/koi8-r.enc
 create mode 100644 library/encoding/koi8-u.enc
 create mode 100644 library/encoding/ksc5601.enc
 create mode 100644 library/encoding/macCentEuro.enc
 create mode 100644 library/encoding/macCroatian.enc
 create mode 100644 library/encoding/macCyrillic.enc
 create mode 100644 library/encoding/macDingbats.enc
 create mode 100644 library/encoding/macGreek.enc
 create mode 100644 library/encoding/macIceland.enc
 create mode 100644 library/encoding/macJapan.enc
 create mode 100644 library/encoding/macRoman.enc
 create mode 100644 library/encoding/macRomania.enc
 create mode 100644 library/encoding/macThai.enc
 create mode 100644 library/encoding/macTurkish.enc
 create mode 100644 library/encoding/macUkraine.enc
 create mode 100644 library/encoding/shiftjis.enc
 create mode 100644 library/encoding/symbol.enc
 create mode 100644 library/encoding/tis-620.enc
 create mode 100644 library/history.tcl
 create mode 100644 library/http/http.tcl
 create mode 100644 library/http/pkgIndex.tcl
 create mode 100644 library/http1.0/http.tcl
 create mode 100644 library/http1.0/pkgIndex.tcl
 create mode 100644 library/init.tcl
 create mode 100644 library/msgcat/msgcat.tcl
 create mode 100644 library/msgcat/pkgIndex.tcl
 create mode 100644 library/msgs/af.msg
 create mode 100644 library/msgs/af_za.msg
 create mode 100644 library/msgs/ar.msg
 create mode 100644 library/msgs/ar_in.msg
 create mode 100644 library/msgs/ar_jo.msg
 create mode 100644 library/msgs/ar_lb.msg
 create mode 100644 library/msgs/ar_sy.msg
 create mode 100644 library/msgs/be.msg
 create mode 100644 library/msgs/bg.msg
 create mode 100644 library/msgs/bn.msg
 create mode 100644 library/msgs/bn_in.msg
 create mode 100644 library/msgs/ca.msg
 create mode 100644 library/msgs/cs.msg
 create mode 100644 library/msgs/da.msg
 create mode 100644 library/msgs/de.msg
 create mode 100644 library/msgs/de_at.msg
 create mode 100644 library/msgs/de_be.msg
 create mode 100644 library/msgs/el.msg
 create mode 100644 library/msgs/en_au.msg
 create mode 100644 library/msgs/en_be.msg
 create mode 100644 library/msgs/en_bw.msg
 create mode 100644 library/msgs/en_ca.msg
 create mode 100644 library/msgs/en_gb.msg
 create mode 100644 library/msgs/en_hk.msg
 create mode 100644 library/msgs/en_ie.msg
 create mode 100644 library/msgs/en_in.msg
 create mode 100644 library/msgs/en_nz.msg
 create mode 100644 library/msgs/en_ph.msg
 create mode 100644 library/msgs/en_sg.msg
 create mode 100644 library/msgs/en_za.msg
 create mode 100644 library/msgs/en_zw.msg
 create mode 100644 library/msgs/eo.msg
 create mode 100644 library/msgs/es.msg
 create mode 100644 library/msgs/es_ar.msg
 create mode 100644 library/msgs/es_bo.msg
 create mode 100644 library/msgs/es_cl.msg
 create mode 100644 library/msgs/es_co.msg
 create mode 100644 library/msgs/es_cr.msg
 create mode 100644 library/msgs/es_do.msg
 create mode 100644 library/msgs/es_ec.msg
 create mode 100644 library/msgs/es_gt.msg
 create mode 100644 library/msgs/es_hn.msg
 create mode 100644 library/msgs/es_mx.msg
 create mode 100644 library/msgs/es_ni.msg
 create mode 100644 library/msgs/es_pa.msg
 create mode 100644 library/msgs/es_pe.msg
 create mode 100644 library/msgs/es_pr.msg
 create mode 100644 library/msgs/es_py.msg
 create mode 100644 library/msgs/es_sv.msg
 create mode 100644 library/msgs/es_uy.msg
 create mode 100644 library/msgs/es_ve.msg
 create mode 100644 library/msgs/et.msg
 create mode 100644 library/msgs/eu.msg
 create mode 100644 library/msgs/eu_es.msg
 create mode 100644 library/msgs/fa.msg
 create mode 100644 library/msgs/fa_in.msg
 create mode 100644 library/msgs/fa_ir.msg
 create mode 100644 library/msgs/fi.msg
 create mode 100644 library/msgs/fo.msg
 create mode 100644 library/msgs/fo_fo.msg
 create mode 100644 library/msgs/fr.msg
 create mode 100644 library/msgs/fr_be.msg
 create mode 100644 library/msgs/fr_ca.msg
 create mode 100644 library/msgs/fr_ch.msg
 create mode 100644 library/msgs/ga.msg
 create mode 100644 library/msgs/ga_ie.msg
 create mode 100644 library/msgs/gl.msg
 create mode 100644 library/msgs/gl_es.msg
 create mode 100644 library/msgs/gv.msg
 create mode 100644 library/msgs/gv_gb.msg
 create mode 100644 library/msgs/he.msg
 create mode 100644 library/msgs/hi.msg
 create mode 100644 library/msgs/hi_in.msg
 create mode 100644 library/msgs/hr.msg
 create mode 100644 library/msgs/hu.msg
 create mode 100644 library/msgs/id.msg
 create mode 100644 library/msgs/id_id.msg
 create mode 100644 library/msgs/is.msg
 create mode 100644 library/msgs/it.msg
 create mode 100644 library/msgs/it_ch.msg
 create mode 100644 library/msgs/ja.msg
 create mode 100644 library/msgs/kl.msg
 create mode 100644 library/msgs/kl_gl.msg
 create mode 100644 library/msgs/ko.msg
 create mode 100644 library/msgs/ko_kr.msg
 create mode 100644 library/msgs/kok.msg
 create mode 100644 library/msgs/kok_in.msg
 create mode 100644 library/msgs/kw.msg
 create mode 100644 library/msgs/kw_gb.msg
 create mode 100644 library/msgs/lt.msg
 create mode 100644 library/msgs/lv.msg
 create mode 100644 library/msgs/mk.msg
 create mode 100644 library/msgs/mr.msg
 create mode 100644 library/msgs/mr_in.msg
 create mode 100644 library/msgs/ms.msg
 create mode 100644 library/msgs/ms_my.msg
 create mode 100644 library/msgs/mt.msg
 create mode 100644 library/msgs/nb.msg
 create mode 100644 library/msgs/nl.msg
 create mode 100644 library/msgs/nl_be.msg
 create mode 100644 library/msgs/nn.msg
 create mode 100644 library/msgs/pl.msg
 create mode 100644 library/msgs/pt.msg
 create mode 100644 library/msgs/pt_br.msg
 create mode 100644 library/msgs/ro.msg
 create mode 100644 library/msgs/ru.msg
 create mode 100644 library/msgs/ru_ua.msg
 create mode 100644 library/msgs/sh.msg
 create mode 100644 library/msgs/sk.msg
 create mode 100644 library/msgs/sl.msg
 create mode 100644 library/msgs/sq.msg
 create mode 100644 library/msgs/sr.msg
 create mode 100644 library/msgs/sv.msg
 create mode 100644 library/msgs/sw.msg
 create mode 100644 library/msgs/ta.msg
 create mode 100644 library/msgs/ta_in.msg
 create mode 100644 library/msgs/te.msg
 create mode 100644 library/msgs/te_in.msg
 create mode 100644 library/msgs/th.msg
 create mode 100644 library/msgs/tr.msg
 create mode 100644 library/msgs/uk.msg
 create mode 100644 library/msgs/vi.msg
 create mode 100644 library/msgs/zh.msg
 create mode 100644 library/msgs/zh_cn.msg
 create mode 100644 library/msgs/zh_hk.msg
 create mode 100644 library/msgs/zh_sg.msg
 create mode 100644 library/msgs/zh_tw.msg
 create mode 100644 library/opt/optparse.tcl
 create mode 100644 library/opt/pkgIndex.tcl
 create mode 100644 library/package.tcl
 create mode 100644 library/parray.tcl
 create mode 100644 library/platform/pkgIndex.tcl
 create mode 100644 library/platform/platform.tcl
 create mode 100644 library/platform/shell.tcl
 create mode 100755 library/reg/pkgIndex.tcl
 create mode 100644 library/safe.tcl
 create mode 100644 library/tclIndex
 create mode 100644 library/tcltest/pkgIndex.tcl
 create mode 100644 library/tcltest/tcltest.tcl
 create mode 100644 library/tm.tcl
 create mode 100644 library/tzdata/Africa/Abidjan
 create mode 100644 library/tzdata/Africa/Accra
 create mode 100644 library/tzdata/Africa/Addis_Ababa
 create mode 100644 library/tzdata/Africa/Algiers
 create mode 100644 library/tzdata/Africa/Asmara
 create mode 100644 library/tzdata/Africa/Asmera
 create mode 100644 library/tzdata/Africa/Bamako
 create mode 100644 library/tzdata/Africa/Bangui
 create mode 100644 library/tzdata/Africa/Banjul
 create mode 100644 library/tzdata/Africa/Bissau
 create mode 100644 library/tzdata/Africa/Blantyre
 create mode 100644 library/tzdata/Africa/Brazzaville
 create mode 100644 library/tzdata/Africa/Bujumbura
 create mode 100644 library/tzdata/Africa/Cairo
 create mode 100644 library/tzdata/Africa/Casablanca
 create mode 100644 library/tzdata/Africa/Ceuta
 create mode 100644 library/tzdata/Africa/Conakry
 create mode 100644 library/tzdata/Africa/Dakar
 create mode 100644 library/tzdata/Africa/Dar_es_Salaam
 create mode 100644 library/tzdata/Africa/Djibouti
 create mode 100644 library/tzdata/Africa/Douala
 create mode 100644 library/tzdata/Africa/El_Aaiun
 create mode 100644 library/tzdata/Africa/Freetown
 create mode 100644 library/tzdata/Africa/Gaborone
 create mode 100644 library/tzdata/Africa/Harare
 create mode 100644 library/tzdata/Africa/Johannesburg
 create mode 100644 library/tzdata/Africa/Juba
 create mode 100644 library/tzdata/Africa/Kampala
 create mode 100644 library/tzdata/Africa/Khartoum
 create mode 100644 library/tzdata/Africa/Kigali
 create mode 100644 library/tzdata/Africa/Kinshasa
 create mode 100644 library/tzdata/Africa/Lagos
 create mode 100644 library/tzdata/Africa/Libreville
 create mode 100644 library/tzdata/Africa/Lome
 create mode 100644 library/tzdata/Africa/Luanda
 create mode 100644 library/tzdata/Africa/Lubumbashi
 create mode 100644 library/tzdata/Africa/Lusaka
 create mode 100644 library/tzdata/Africa/Malabo
 create mode 100644 library/tzdata/Africa/Maputo
 create mode 100644 library/tzdata/Africa/Maseru
 create mode 100644 library/tzdata/Africa/Mbabane
 create mode 100644 library/tzdata/Africa/Mogadishu
 create mode 100644 library/tzdata/Africa/Monrovia
 create mode 100644 library/tzdata/Africa/Nairobi
 create mode 100644 library/tzdata/Africa/Ndjamena
 create mode 100644 library/tzdata/Africa/Niamey
 create mode 100644 library/tzdata/Africa/Nouakchott
 create mode 100644 library/tzdata/Africa/Ouagadougou
 create mode 100644 library/tzdata/Africa/Porto-Novo
 create mode 100644 library/tzdata/Africa/Sao_Tome
 create mode 100644 library/tzdata/Africa/Timbuktu
 create mode 100644 library/tzdata/Africa/Tripoli
 create mode 100644 library/tzdata/Africa/Tunis
 create mode 100644 library/tzdata/Africa/Windhoek
 create mode 100644 library/tzdata/America/Adak
 create mode 100644 library/tzdata/America/Anchorage
 create mode 100644 library/tzdata/America/Anguilla
 create mode 100644 library/tzdata/America/Antigua
 create mode 100644 library/tzdata/America/Araguaina
 create mode 100644 library/tzdata/America/Argentina/Buenos_Aires
 create mode 100644 library/tzdata/America/Argentina/Catamarca
 create mode 100644 library/tzdata/America/Argentina/ComodRivadavia
 create mode 100644 library/tzdata/America/Argentina/Cordoba
 create mode 100644 library/tzdata/America/Argentina/Jujuy
 create mode 100644 library/tzdata/America/Argentina/La_Rioja
 create mode 100644 library/tzdata/America/Argentina/Mendoza
 create mode 100644 library/tzdata/America/Argentina/Rio_Gallegos
 create mode 100644 library/tzdata/America/Argentina/Salta
 create mode 100644 library/tzdata/America/Argentina/San_Juan
 create mode 100644 library/tzdata/America/Argentina/San_Luis
 create mode 100644 library/tzdata/America/Argentina/Tucuman
 create mode 100644 library/tzdata/America/Argentina/Ushuaia
 create mode 100644 library/tzdata/America/Aruba
 create mode 100644 library/tzdata/America/Asuncion
 create mode 100644 library/tzdata/America/Atikokan
 create mode 100644 library/tzdata/America/Atka
 create mode 100644 library/tzdata/America/Bahia
 create mode 100644 library/tzdata/America/Bahia_Banderas
 create mode 100644 library/tzdata/America/Barbados
 create mode 100644 library/tzdata/America/Belem
 create mode 100644 library/tzdata/America/Belize
 create mode 100644 library/tzdata/America/Blanc-Sablon
 create mode 100644 library/tzdata/America/Boa_Vista
 create mode 100644 library/tzdata/America/Bogota
 create mode 100644 library/tzdata/America/Boise
 create mode 100644 library/tzdata/America/Buenos_Aires
 create mode 100644 library/tzdata/America/Cambridge_Bay
 create mode 100644 library/tzdata/America/Campo_Grande
 create mode 100644 library/tzdata/America/Cancun
 create mode 100644 library/tzdata/America/Caracas
 create mode 100644 library/tzdata/America/Catamarca
 create mode 100644 library/tzdata/America/Cayenne
 create mode 100644 library/tzdata/America/Cayman
 create mode 100644 library/tzdata/America/Chicago
 create mode 100644 library/tzdata/America/Chihuahua
 create mode 100644 library/tzdata/America/Coral_Harbour
 create mode 100644 library/tzdata/America/Cordoba
 create mode 100644 library/tzdata/America/Costa_Rica
 create mode 100644 library/tzdata/America/Creston
 create mode 100644 library/tzdata/America/Cuiaba
 create mode 100644 library/tzdata/America/Curacao
 create mode 100644 library/tzdata/America/Danmarkshavn
 create mode 100644 library/tzdata/America/Dawson
 create mode 100644 library/tzdata/America/Dawson_Creek
 create mode 100644 library/tzdata/America/Denver
 create mode 100644 library/tzdata/America/Detroit
 create mode 100644 library/tzdata/America/Dominica
 create mode 100644 library/tzdata/America/Edmonton
 create mode 100644 library/tzdata/America/Eirunepe
 create mode 100644 library/tzdata/America/El_Salvador
 create mode 100644 library/tzdata/America/Ensenada
 create mode 100644 library/tzdata/America/Fort_Nelson
 create mode 100644 library/tzdata/America/Fort_Wayne
 create mode 100644 library/tzdata/America/Fortaleza
 create mode 100644 library/tzdata/America/Glace_Bay
 create mode 100644 library/tzdata/America/Godthab
 create mode 100644 library/tzdata/America/Goose_Bay
 create mode 100644 library/tzdata/America/Grand_Turk
 create mode 100644 library/tzdata/America/Grenada
 create mode 100644 library/tzdata/America/Guadeloupe
 create mode 100644 library/tzdata/America/Guatemala
 create mode 100644 library/tzdata/America/Guayaquil
 create mode 100644 library/tzdata/America/Guyana
 create mode 100644 library/tzdata/America/Halifax
 create mode 100644 library/tzdata/America/Havana
 create mode 100644 library/tzdata/America/Hermosillo
 create mode 100644 library/tzdata/America/Indiana/Indianapolis
 create mode 100644 library/tzdata/America/Indiana/Knox
 create mode 100644 library/tzdata/America/Indiana/Marengo
 create mode 100644 library/tzdata/America/Indiana/Petersburg
 create mode 100644 library/tzdata/America/Indiana/Tell_City
 create mode 100644 library/tzdata/America/Indiana/Vevay
 create mode 100644 library/tzdata/America/Indiana/Vincennes
 create mode 100644 library/tzdata/America/Indiana/Winamac
 create mode 100644 library/tzdata/America/Indianapolis
 create mode 100644 library/tzdata/America/Inuvik
 create mode 100644 library/tzdata/America/Iqaluit
 create mode 100644 library/tzdata/America/Jamaica
 create mode 100644 library/tzdata/America/Jujuy
 create mode 100644 library/tzdata/America/Juneau
 create mode 100644 library/tzdata/America/Kentucky/Louisville
 create mode 100644 library/tzdata/America/Kentucky/Monticello
 create mode 100644 library/tzdata/America/Knox_IN
 create mode 100644 library/tzdata/America/Kralendijk
 create mode 100644 library/tzdata/America/La_Paz
 create mode 100644 library/tzdata/America/Lima
 create mode 100644 library/tzdata/America/Los_Angeles
 create mode 100644 library/tzdata/America/Louisville
 create mode 100644 library/tzdata/America/Lower_Princes
 create mode 100644 library/tzdata/America/Maceio
 create mode 100644 library/tzdata/America/Managua
 create mode 100644 library/tzdata/America/Manaus
 create mode 100644 library/tzdata/America/Marigot
 create mode 100644 library/tzdata/America/Martinique
 create mode 100644 library/tzdata/America/Matamoros
 create mode 100644 library/tzdata/America/Mazatlan
 create mode 100644 library/tzdata/America/Mendoza
 create mode 100644 library/tzdata/America/Menominee
 create mode 100644 library/tzdata/America/Merida
 create mode 100644 library/tzdata/America/Metlakatla
 create mode 100644 library/tzdata/America/Mexico_City
 create mode 100644 library/tzdata/America/Miquelon
 create mode 100644 library/tzdata/America/Moncton
 create mode 100644 library/tzdata/America/Monterrey
 create mode 100644 library/tzdata/America/Montevideo
 create mode 100644 library/tzdata/America/Montreal
 create mode 100644 library/tzdata/America/Montserrat
 create mode 100644 library/tzdata/America/Nassau
 create mode 100644 library/tzdata/America/New_York
 create mode 100644 library/tzdata/America/Nipigon
 create mode 100644 library/tzdata/America/Nome
 create mode 100644 library/tzdata/America/Noronha
 create mode 100644 library/tzdata/America/North_Dakota/Beulah
 create mode 100644 library/tzdata/America/North_Dakota/Center
 create mode 100644 library/tzdata/America/North_Dakota/New_Salem
 create mode 100644 library/tzdata/America/Ojinaga
 create mode 100644 library/tzdata/America/Panama
 create mode 100644 library/tzdata/America/Pangnirtung
 create mode 100644 library/tzdata/America/Paramaribo
 create mode 100644 library/tzdata/America/Phoenix
 create mode 100644 library/tzdata/America/Port-au-Prince
 create mode 100644 library/tzdata/America/Port_of_Spain
 create mode 100644 library/tzdata/America/Porto_Acre
 create mode 100644 library/tzdata/America/Porto_Velho
 create mode 100644 library/tzdata/America/Puerto_Rico
 create mode 100644 library/tzdata/America/Rainy_River
 create mode 100644 library/tzdata/America/Rankin_Inlet
 create mode 100644 library/tzdata/America/Recife
 create mode 100644 library/tzdata/America/Regina
 create mode 100644 library/tzdata/America/Resolute
 create mode 100644 library/tzdata/America/Rio_Branco
 create mode 100644 library/tzdata/America/Rosario
 create mode 100644 library/tzdata/America/Santa_Isabel
 create mode 100644 library/tzdata/America/Santarem
 create mode 100644 library/tzdata/America/Santiago
 create mode 100644 library/tzdata/America/Santo_Domingo
 create mode 100644 library/tzdata/America/Sao_Paulo
 create mode 100644 library/tzdata/America/Scoresbysund
 create mode 100644 library/tzdata/America/Shiprock
 create mode 100644 library/tzdata/America/Sitka
 create mode 100644 library/tzdata/America/St_Barthelemy
 create mode 100644 library/tzdata/America/St_Johns
 create mode 100644 library/tzdata/America/St_Kitts
 create mode 100644 library/tzdata/America/St_Lucia
 create mode 100644 library/tzdata/America/St_Thomas
 create mode 100644 library/tzdata/America/St_Vincent
 create mode 100644 library/tzdata/America/Swift_Current
 create mode 100644 library/tzdata/America/Tegucigalpa
 create mode 100644 library/tzdata/America/Thule
 create mode 100644 library/tzdata/America/Thunder_Bay
 create mode 100644 library/tzdata/America/Tijuana
 create mode 100644 library/tzdata/America/Toronto
 create mode 100644 library/tzdata/America/Tortola
 create mode 100644 library/tzdata/America/Vancouver
 create mode 100644 library/tzdata/America/Virgin
 create mode 100644 library/tzdata/America/Whitehorse
 create mode 100644 library/tzdata/America/Winnipeg
 create mode 100644 library/tzdata/America/Yakutat
 create mode 100644 library/tzdata/America/Yellowknife
 create mode 100644 library/tzdata/Antarctica/Casey
 create mode 100644 library/tzdata/Antarctica/Davis
 create mode 100644 library/tzdata/Antarctica/DumontDUrville
 create mode 100644 library/tzdata/Antarctica/Macquarie
 create mode 100644 library/tzdata/Antarctica/Mawson
 create mode 100644 library/tzdata/Antarctica/McMurdo
 create mode 100644 library/tzdata/Antarctica/Palmer
 create mode 100644 library/tzdata/Antarctica/Rothera
 create mode 100644 library/tzdata/Antarctica/South_Pole
 create mode 100644 library/tzdata/Antarctica/Syowa
 create mode 100644 library/tzdata/Antarctica/Troll
 create mode 100644 library/tzdata/Antarctica/Vostok
 create mode 100644 library/tzdata/Arctic/Longyearbyen
 create mode 100644 library/tzdata/Asia/Aden
 create mode 100644 library/tzdata/Asia/Almaty
 create mode 100644 library/tzdata/Asia/Amman
 create mode 100644 library/tzdata/Asia/Anadyr
 create mode 100644 library/tzdata/Asia/Aqtau
 create mode 100644 library/tzdata/Asia/Aqtobe
 create mode 100644 library/tzdata/Asia/Ashgabat
 create mode 100644 library/tzdata/Asia/Ashkhabad
 create mode 100644 library/tzdata/Asia/Baghdad
 create mode 100644 library/tzdata/Asia/Bahrain
 create mode 100644 library/tzdata/Asia/Baku
 create mode 100644 library/tzdata/Asia/Bangkok
 create mode 100644 library/tzdata/Asia/Barnaul
 create mode 100644 library/tzdata/Asia/Beirut
 create mode 100644 library/tzdata/Asia/Bishkek
 create mode 100644 library/tzdata/Asia/Brunei
 create mode 100644 library/tzdata/Asia/Calcutta
 create mode 100644 library/tzdata/Asia/Chita
 create mode 100644 library/tzdata/Asia/Choibalsan
 create mode 100644 library/tzdata/Asia/Chongqing
 create mode 100644 library/tzdata/Asia/Chungking
 create mode 100644 library/tzdata/Asia/Colombo
 create mode 100644 library/tzdata/Asia/Dacca
 create mode 100644 library/tzdata/Asia/Damascus
 create mode 100644 library/tzdata/Asia/Dhaka
 create mode 100644 library/tzdata/Asia/Dili
 create mode 100644 library/tzdata/Asia/Dubai
 create mode 100644 library/tzdata/Asia/Dushanbe
 create mode 100644 library/tzdata/Asia/Gaza
 create mode 100644 library/tzdata/Asia/Harbin
 create mode 100644 library/tzdata/Asia/Hebron
 create mode 100644 library/tzdata/Asia/Ho_Chi_Minh
 create mode 100644 library/tzdata/Asia/Hong_Kong
 create mode 100644 library/tzdata/Asia/Hovd
 create mode 100644 library/tzdata/Asia/Irkutsk
 create mode 100644 library/tzdata/Asia/Istanbul
 create mode 100644 library/tzdata/Asia/Jakarta
 create mode 100644 library/tzdata/Asia/Jayapura
 create mode 100644 library/tzdata/Asia/Jerusalem
 create mode 100644 library/tzdata/Asia/Kabul
 create mode 100644 library/tzdata/Asia/Kamchatka
 create mode 100644 library/tzdata/Asia/Karachi
 create mode 100644 library/tzdata/Asia/Kashgar
 create mode 100644 library/tzdata/Asia/Kathmandu
 create mode 100644 library/tzdata/Asia/Katmandu
 create mode 100644 library/tzdata/Asia/Khandyga
 create mode 100644 library/tzdata/Asia/Kolkata
 create mode 100644 library/tzdata/Asia/Krasnoyarsk
 create mode 100644 library/tzdata/Asia/Kuala_Lumpur
 create mode 100644 library/tzdata/Asia/Kuching
 create mode 100644 library/tzdata/Asia/Kuwait
 create mode 100644 library/tzdata/Asia/Macao
 create mode 100644 library/tzdata/Asia/Macau
 create mode 100644 library/tzdata/Asia/Magadan
 create mode 100644 library/tzdata/Asia/Makassar
 create mode 100644 library/tzdata/Asia/Manila
 create mode 100644 library/tzdata/Asia/Muscat
 create mode 100644 library/tzdata/Asia/Nicosia
 create mode 100644 library/tzdata/Asia/Novokuznetsk
 create mode 100644 library/tzdata/Asia/Novosibirsk
 create mode 100644 library/tzdata/Asia/Omsk
 create mode 100644 library/tzdata/Asia/Oral
 create mode 100644 library/tzdata/Asia/Phnom_Penh
 create mode 100644 library/tzdata/Asia/Pontianak
 create mode 100644 library/tzdata/Asia/Pyongyang
 create mode 100644 library/tzdata/Asia/Qatar
 create mode 100644 library/tzdata/Asia/Qyzylorda
 create mode 100644 library/tzdata/Asia/Rangoon
 create mode 100644 library/tzdata/Asia/Riyadh
 create mode 100644 library/tzdata/Asia/Saigon
 create mode 100644 library/tzdata/Asia/Sakhalin
 create mode 100644 library/tzdata/Asia/Samarkand
 create mode 100644 library/tzdata/Asia/Seoul
 create mode 100644 library/tzdata/Asia/Shanghai
 create mode 100644 library/tzdata/Asia/Singapore
 create mode 100644 library/tzdata/Asia/Srednekolymsk
 create mode 100644 library/tzdata/Asia/Taipei
 create mode 100644 library/tzdata/Asia/Tashkent
 create mode 100644 library/tzdata/Asia/Tbilisi
 create mode 100644 library/tzdata/Asia/Tehran
 create mode 100644 library/tzdata/Asia/Tel_Aviv
 create mode 100644 library/tzdata/Asia/Thimbu
 create mode 100644 library/tzdata/Asia/Thimphu
 create mode 100644 library/tzdata/Asia/Tokyo
 create mode 100644 library/tzdata/Asia/Tomsk
 create mode 100644 library/tzdata/Asia/Ujung_Pandang
 create mode 100644 library/tzdata/Asia/Ulaanbaatar
 create mode 100644 library/tzdata/Asia/Ulan_Bator
 create mode 100644 library/tzdata/Asia/Urumqi
 create mode 100644 library/tzdata/Asia/Ust-Nera
 create mode 100644 library/tzdata/Asia/Vientiane
 create mode 100644 library/tzdata/Asia/Vladivostok
 create mode 100644 library/tzdata/Asia/Yakutsk
 create mode 100644 library/tzdata/Asia/Yekaterinburg
 create mode 100644 library/tzdata/Asia/Yerevan
 create mode 100644 library/tzdata/Atlantic/Azores
 create mode 100644 library/tzdata/Atlantic/Bermuda
 create mode 100644 library/tzdata/Atlantic/Canary
 create mode 100644 library/tzdata/Atlantic/Cape_Verde
 create mode 100644 library/tzdata/Atlantic/Faeroe
 create mode 100644 library/tzdata/Atlantic/Faroe
 create mode 100644 library/tzdata/Atlantic/Jan_Mayen
 create mode 100644 library/tzdata/Atlantic/Madeira
 create mode 100644 library/tzdata/Atlantic/Reykjavik
 create mode 100644 library/tzdata/Atlantic/South_Georgia
 create mode 100644 library/tzdata/Atlantic/St_Helena
 create mode 100644 library/tzdata/Atlantic/Stanley
 create mode 100644 library/tzdata/Australia/ACT
 create mode 100644 library/tzdata/Australia/Adelaide
 create mode 100644 library/tzdata/Australia/Brisbane
 create mode 100644 library/tzdata/Australia/Broken_Hill
 create mode 100644 library/tzdata/Australia/Canberra
 create mode 100644 library/tzdata/Australia/Currie
 create mode 100644 library/tzdata/Australia/Darwin
 create mode 100644 library/tzdata/Australia/Eucla
 create mode 100644 library/tzdata/Australia/Hobart
 create mode 100644 library/tzdata/Australia/LHI
 create mode 100644 library/tzdata/Australia/Lindeman
 create mode 100644 library/tzdata/Australia/Lord_Howe
 create mode 100644 library/tzdata/Australia/Melbourne
 create mode 100644 library/tzdata/Australia/NSW
 create mode 100644 library/tzdata/Australia/North
 create mode 100644 library/tzdata/Australia/Perth
 create mode 100644 library/tzdata/Australia/Queensland
 create mode 100644 library/tzdata/Australia/South
 create mode 100644 library/tzdata/Australia/Sydney
 create mode 100644 library/tzdata/Australia/Tasmania
 create mode 100644 library/tzdata/Australia/Victoria
 create mode 100644 library/tzdata/Australia/West
 create mode 100644 library/tzdata/Australia/Yancowinna
 create mode 100644 library/tzdata/Brazil/Acre
 create mode 100644 library/tzdata/Brazil/DeNoronha
 create mode 100644 library/tzdata/Brazil/East
 create mode 100644 library/tzdata/Brazil/West
 create mode 100644 library/tzdata/CET
 create mode 100644 library/tzdata/CST6CDT
 create mode 100644 library/tzdata/Canada/Atlantic
 create mode 100644 library/tzdata/Canada/Central
 create mode 100644 library/tzdata/Canada/East-Saskatchewan
 create mode 100644 library/tzdata/Canada/Eastern
 create mode 100644 library/tzdata/Canada/Mountain
 create mode 100644 library/tzdata/Canada/Newfoundland
 create mode 100644 library/tzdata/Canada/Pacific
 create mode 100644 library/tzdata/Canada/Saskatchewan
 create mode 100644 library/tzdata/Canada/Yukon
 create mode 100644 library/tzdata/Chile/Continental
 create mode 100644 library/tzdata/Chile/EasterIsland
 create mode 100644 library/tzdata/Cuba
 create mode 100644 library/tzdata/EET
 create mode 100644 library/tzdata/EST
 create mode 100644 library/tzdata/EST5EDT
 create mode 100644 library/tzdata/Egypt
 create mode 100644 library/tzdata/Eire
 create mode 100644 library/tzdata/Etc/GMT
 create mode 100644 library/tzdata/Etc/GMT+0
 create mode 100644 library/tzdata/Etc/GMT+1
 create mode 100644 library/tzdata/Etc/GMT+10
 create mode 100644 library/tzdata/Etc/GMT+11
 create mode 100644 library/tzdata/Etc/GMT+12
 create mode 100644 library/tzdata/Etc/GMT+2
 create mode 100644 library/tzdata/Etc/GMT+3
 create mode 100644 library/tzdata/Etc/GMT+4
 create mode 100644 library/tzdata/Etc/GMT+5
 create mode 100644 library/tzdata/Etc/GMT+6
 create mode 100644 library/tzdata/Etc/GMT+7
 create mode 100644 library/tzdata/Etc/GMT+8
 create mode 100644 library/tzdata/Etc/GMT+9
 create mode 100644 library/tzdata/Etc/GMT-0
 create mode 100644 library/tzdata/Etc/GMT-1
 create mode 100644 library/tzdata/Etc/GMT-10
 create mode 100644 library/tzdata/Etc/GMT-11
 create mode 100644 library/tzdata/Etc/GMT-12
 create mode 100644 library/tzdata/Etc/GMT-13
 create mode 100644 library/tzdata/Etc/GMT-14
 create mode 100644 library/tzdata/Etc/GMT-2
 create mode 100644 library/tzdata/Etc/GMT-3
 create mode 100644 library/tzdata/Etc/GMT-4
 create mode 100644 library/tzdata/Etc/GMT-5
 create mode 100644 library/tzdata/Etc/GMT-6
 create mode 100644 library/tzdata/Etc/GMT-7
 create mode 100644 library/tzdata/Etc/GMT-8
 create mode 100644 library/tzdata/Etc/GMT-9
 create mode 100644 library/tzdata/Etc/GMT0
 create mode 100644 library/tzdata/Etc/Greenwich
 create mode 100644 library/tzdata/Etc/UCT
 create mode 100644 library/tzdata/Etc/UTC
 create mode 100644 library/tzdata/Etc/Universal
 create mode 100644 library/tzdata/Etc/Zulu
 create mode 100644 library/tzdata/Europe/Amsterdam
 create mode 100644 library/tzdata/Europe/Andorra
 create mode 100644 library/tzdata/Europe/Astrakhan
 create mode 100644 library/tzdata/Europe/Athens
 create mode 100644 library/tzdata/Europe/Belfast
 create mode 100644 library/tzdata/Europe/Belgrade
 create mode 100644 library/tzdata/Europe/Berlin
 create mode 100644 library/tzdata/Europe/Bratislava
 create mode 100644 library/tzdata/Europe/Brussels
 create mode 100644 library/tzdata/Europe/Bucharest
 create mode 100644 library/tzdata/Europe/Budapest
 create mode 100644 library/tzdata/Europe/Busingen
 create mode 100644 library/tzdata/Europe/Chisinau
 create mode 100644 library/tzdata/Europe/Copenhagen
 create mode 100644 library/tzdata/Europe/Dublin
 create mode 100644 library/tzdata/Europe/Gibraltar
 create mode 100644 library/tzdata/Europe/Guernsey
 create mode 100644 library/tzdata/Europe/Helsinki
 create mode 100644 library/tzdata/Europe/Isle_of_Man
 create mode 100644 library/tzdata/Europe/Istanbul
 create mode 100644 library/tzdata/Europe/Jersey
 create mode 100644 library/tzdata/Europe/Kaliningrad
 create mode 100644 library/tzdata/Europe/Kiev
 create mode 100644 library/tzdata/Europe/Kirov
 create mode 100644 library/tzdata/Europe/Lisbon
 create mode 100644 library/tzdata/Europe/Ljubljana
 create mode 100644 library/tzdata/Europe/London
 create mode 100644 library/tzdata/Europe/Luxembourg
 create mode 100644 library/tzdata/Europe/Madrid
 create mode 100644 library/tzdata/Europe/Malta
 create mode 100644 library/tzdata/Europe/Mariehamn
 create mode 100644 library/tzdata/Europe/Minsk
 create mode 100644 library/tzdata/Europe/Monaco
 create mode 100644 library/tzdata/Europe/Moscow
 create mode 100644 library/tzdata/Europe/Nicosia
 create mode 100644 library/tzdata/Europe/Oslo
 create mode 100644 library/tzdata/Europe/Paris
 create mode 100644 library/tzdata/Europe/Podgorica
 create mode 100644 library/tzdata/Europe/Prague
 create mode 100644 library/tzdata/Europe/Riga
 create mode 100644 library/tzdata/Europe/Rome
 create mode 100644 library/tzdata/Europe/Samara
 create mode 100644 library/tzdata/Europe/San_Marino
 create mode 100644 library/tzdata/Europe/Sarajevo
 create mode 100644 library/tzdata/Europe/Simferopol
 create mode 100644 library/tzdata/Europe/Skopje
 create mode 100644 library/tzdata/Europe/Sofia
 create mode 100644 library/tzdata/Europe/Stockholm
 create mode 100644 library/tzdata/Europe/Tallinn
 create mode 100644 library/tzdata/Europe/Tirane
 create mode 100644 library/tzdata/Europe/Tiraspol
 create mode 100644 library/tzdata/Europe/Ulyanovsk
 create mode 100644 library/tzdata/Europe/Uzhgorod
 create mode 100644 library/tzdata/Europe/Vaduz
 create mode 100644 library/tzdata/Europe/Vatican
 create mode 100644 library/tzdata/Europe/Vienna
 create mode 100644 library/tzdata/Europe/Vilnius
 create mode 100644 library/tzdata/Europe/Volgograd
 create mode 100644 library/tzdata/Europe/Warsaw
 create mode 100644 library/tzdata/Europe/Zagreb
 create mode 100644 library/tzdata/Europe/Zaporozhye
 create mode 100644 library/tzdata/Europe/Zurich
 create mode 100644 library/tzdata/GB
 create mode 100644 library/tzdata/GB-Eire
 create mode 100644 library/tzdata/GMT
 create mode 100644 library/tzdata/GMT+0
 create mode 100644 library/tzdata/GMT-0
 create mode 100644 library/tzdata/GMT0
 create mode 100644 library/tzdata/Greenwich
 create mode 100644 library/tzdata/HST
 create mode 100644 library/tzdata/Hongkong
 create mode 100644 library/tzdata/Iceland
 create mode 100644 library/tzdata/Indian/Antananarivo
 create mode 100644 library/tzdata/Indian/Chagos
 create mode 100644 library/tzdata/Indian/Christmas
 create mode 100644 library/tzdata/Indian/Cocos
 create mode 100644 library/tzdata/Indian/Comoro
 create mode 100644 library/tzdata/Indian/Kerguelen
 create mode 100644 library/tzdata/Indian/Mahe
 create mode 100644 library/tzdata/Indian/Maldives
 create mode 100644 library/tzdata/Indian/Mauritius
 create mode 100644 library/tzdata/Indian/Mayotte
 create mode 100644 library/tzdata/Indian/Reunion
 create mode 100644 library/tzdata/Iran
 create mode 100644 library/tzdata/Israel
 create mode 100644 library/tzdata/Jamaica
 create mode 100644 library/tzdata/Japan
 create mode 100644 library/tzdata/Kwajalein
 create mode 100644 library/tzdata/Libya
 create mode 100644 library/tzdata/MET
 create mode 100644 library/tzdata/MST
 create mode 100644 library/tzdata/MST7MDT
 create mode 100644 library/tzdata/Mexico/BajaNorte
 create mode 100644 library/tzdata/Mexico/BajaSur
 create mode 100644 library/tzdata/Mexico/General
 create mode 100644 library/tzdata/NZ
 create mode 100644 library/tzdata/NZ-CHAT
 create mode 100644 library/tzdata/Navajo
 create mode 100644 library/tzdata/PRC
 create mode 100644 library/tzdata/PST8PDT
 create mode 100644 library/tzdata/Pacific/Apia
 create mode 100644 library/tzdata/Pacific/Auckland
 create mode 100644 library/tzdata/Pacific/Bougainville
 create mode 100644 library/tzdata/Pacific/Chatham
 create mode 100644 library/tzdata/Pacific/Chuuk
 create mode 100644 library/tzdata/Pacific/Easter
 create mode 100644 library/tzdata/Pacific/Efate
 create mode 100644 library/tzdata/Pacific/Enderbury
 create mode 100644 library/tzdata/Pacific/Fakaofo
 create mode 100644 library/tzdata/Pacific/Fiji
 create mode 100644 library/tzdata/Pacific/Funafuti
 create mode 100644 library/tzdata/Pacific/Galapagos
 create mode 100644 library/tzdata/Pacific/Gambier
 create mode 100644 library/tzdata/Pacific/Guadalcanal
 create mode 100644 library/tzdata/Pacific/Guam
 create mode 100644 library/tzdata/Pacific/Honolulu
 create mode 100644 library/tzdata/Pacific/Johnston
 create mode 100644 library/tzdata/Pacific/Kiritimati
 create mode 100644 library/tzdata/Pacific/Kosrae
 create mode 100644 library/tzdata/Pacific/Kwajalein
 create mode 100644 library/tzdata/Pacific/Majuro
 create mode 100644 library/tzdata/Pacific/Marquesas
 create mode 100644 library/tzdata/Pacific/Midway
 create mode 100644 library/tzdata/Pacific/Nauru
 create mode 100644 library/tzdata/Pacific/Niue
 create mode 100644 library/tzdata/Pacific/Norfolk
 create mode 100644 library/tzdata/Pacific/Noumea
 create mode 100644 library/tzdata/Pacific/Pago_Pago
 create mode 100644 library/tzdata/Pacific/Palau
 create mode 100644 library/tzdata/Pacific/Pitcairn
 create mode 100644 library/tzdata/Pacific/Pohnpei
 create mode 100644 library/tzdata/Pacific/Ponape
 create mode 100644 library/tzdata/Pacific/Port_Moresby
 create mode 100644 library/tzdata/Pacific/Rarotonga
 create mode 100644 library/tzdata/Pacific/Saipan
 create mode 100644 library/tzdata/Pacific/Samoa
 create mode 100644 library/tzdata/Pacific/Tahiti
 create mode 100644 library/tzdata/Pacific/Tarawa
 create mode 100644 library/tzdata/Pacific/Tongatapu
 create mode 100644 library/tzdata/Pacific/Truk
 create mode 100644 library/tzdata/Pacific/Wake
 create mode 100644 library/tzdata/Pacific/Wallis
 create mode 100644 library/tzdata/Pacific/Yap
 create mode 100644 library/tzdata/Poland
 create mode 100644 library/tzdata/Portugal
 create mode 100644 library/tzdata/ROC
 create mode 100644 library/tzdata/ROK
 create mode 100644 library/tzdata/Singapore
 create mode 100644 library/tzdata/SystemV/AST4
 create mode 100644 library/tzdata/SystemV/AST4ADT
 create mode 100644 library/tzdata/SystemV/CST6
 create mode 100644 library/tzdata/SystemV/CST6CDT
 create mode 100644 library/tzdata/SystemV/EST5
 create mode 100644 library/tzdata/SystemV/EST5EDT
 create mode 100644 library/tzdata/SystemV/HST10
 create mode 100644 library/tzdata/SystemV/MST7
 create mode 100644 library/tzdata/SystemV/MST7MDT
 create mode 100644 library/tzdata/SystemV/PST8
 create mode 100644 library/tzdata/SystemV/PST8PDT
 create mode 100644 library/tzdata/SystemV/YST9
 create mode 100644 library/tzdata/SystemV/YST9YDT
 create mode 100644 library/tzdata/Turkey
 create mode 100644 library/tzdata/UCT
 create mode 100644 library/tzdata/US/Alaska
 create mode 100644 library/tzdata/US/Aleutian
 create mode 100644 library/tzdata/US/Arizona
 create mode 100644 library/tzdata/US/Central
 create mode 100644 library/tzdata/US/East-Indiana
 create mode 100644 library/tzdata/US/Eastern
 create mode 100644 library/tzdata/US/Hawaii
 create mode 100644 library/tzdata/US/Indiana-Starke
 create mode 100644 library/tzdata/US/Michigan
 create mode 100644 library/tzdata/US/Mountain
 create mode 100644 library/tzdata/US/Pacific
 create mode 100644 library/tzdata/US/Pacific-New
 create mode 100644 library/tzdata/US/Samoa
 create mode 100644 library/tzdata/UTC
 create mode 100644 library/tzdata/Universal
 create mode 100644 library/tzdata/W-SU
 create mode 100644 library/tzdata/WET
 create mode 100644 library/tzdata/Zulu
 create mode 100644 library/word.tcl
 create mode 100644 libtommath/LICENSE
 create mode 100644 libtommath/bn.ilg
 create mode 100644 libtommath/bn.ind
 create mode 100644 libtommath/bn.pdf
 create mode 100644 libtommath/bn.tex
 create mode 100644 libtommath/bn_error.c
 create mode 100644 libtommath/bn_fast_mp_invmod.c
 create mode 100644 libtommath/bn_fast_mp_montgomery_reduce.c
 create mode 100644 libtommath/bn_fast_s_mp_mul_digs.c
 create mode 100644 libtommath/bn_fast_s_mp_mul_high_digs.c
 create mode 100644 libtommath/bn_fast_s_mp_sqr.c
 create mode 100644 libtommath/bn_mp_2expt.c
 create mode 100644 libtommath/bn_mp_abs.c
 create mode 100644 libtommath/bn_mp_add.c
 create mode 100644 libtommath/bn_mp_add_d.c
 create mode 100644 libtommath/bn_mp_addmod.c
 create mode 100644 libtommath/bn_mp_and.c
 create mode 100644 libtommath/bn_mp_clamp.c
 create mode 100644 libtommath/bn_mp_clear.c
 create mode 100644 libtommath/bn_mp_clear_multi.c
 create mode 100644 libtommath/bn_mp_cmp.c
 create mode 100644 libtommath/bn_mp_cmp_d.c
 create mode 100644 libtommath/bn_mp_cmp_mag.c
 create mode 100644 libtommath/bn_mp_cnt_lsb.c
 create mode 100644 libtommath/bn_mp_copy.c
 create mode 100644 libtommath/bn_mp_count_bits.c
 create mode 100644 libtommath/bn_mp_div.c
 create mode 100644 libtommath/bn_mp_div_2.c
 create mode 100644 libtommath/bn_mp_div_2d.c
 create mode 100644 libtommath/bn_mp_div_3.c
 create mode 100644 libtommath/bn_mp_div_d.c
 create mode 100644 libtommath/bn_mp_dr_is_modulus.c
 create mode 100644 libtommath/bn_mp_dr_reduce.c
 create mode 100644 libtommath/bn_mp_dr_setup.c
 create mode 100644 libtommath/bn_mp_exch.c
 create mode 100644 libtommath/bn_mp_expt_d.c
 create mode 100644 libtommath/bn_mp_exptmod.c
 create mode 100644 libtommath/bn_mp_exptmod_fast.c
 create mode 100644 libtommath/bn_mp_exteuclid.c
 create mode 100644 libtommath/bn_mp_fread.c
 create mode 100644 libtommath/bn_mp_fwrite.c
 create mode 100644 libtommath/bn_mp_gcd.c
 create mode 100644 libtommath/bn_mp_get_int.c
 create mode 100644 libtommath/bn_mp_grow.c
 create mode 100644 libtommath/bn_mp_init.c
 create mode 100644 libtommath/bn_mp_init_copy.c
 create mode 100644 libtommath/bn_mp_init_multi.c
 create mode 100644 libtommath/bn_mp_init_set.c
 create mode 100644 libtommath/bn_mp_init_set_int.c
 create mode 100644 libtommath/bn_mp_init_size.c
 create mode 100644 libtommath/bn_mp_invmod.c
 create mode 100644 libtommath/bn_mp_invmod_slow.c
 create mode 100644 libtommath/bn_mp_is_square.c
 create mode 100644 libtommath/bn_mp_jacobi.c
 create mode 100644 libtommath/bn_mp_karatsuba_mul.c
 create mode 100644 libtommath/bn_mp_karatsuba_sqr.c
 create mode 100644 libtommath/bn_mp_lcm.c
 create mode 100644 libtommath/bn_mp_lshd.c
 create mode 100644 libtommath/bn_mp_mod.c
 create mode 100644 libtommath/bn_mp_mod_2d.c
 create mode 100644 libtommath/bn_mp_mod_d.c
 create mode 100644 libtommath/bn_mp_montgomery_calc_normalization.c
 create mode 100644 libtommath/bn_mp_montgomery_reduce.c
 create mode 100644 libtommath/bn_mp_montgomery_setup.c
 create mode 100644 libtommath/bn_mp_mul.c
 create mode 100644 libtommath/bn_mp_mul_2.c
 create mode 100644 libtommath/bn_mp_mul_2d.c
 create mode 100644 libtommath/bn_mp_mul_d.c
 create mode 100644 libtommath/bn_mp_mulmod.c
 create mode 100644 libtommath/bn_mp_n_root.c
 create mode 100644 libtommath/bn_mp_neg.c
 create mode 100644 libtommath/bn_mp_or.c
 create mode 100644 libtommath/bn_mp_prime_fermat.c
 create mode 100644 libtommath/bn_mp_prime_is_divisible.c
 create mode 100644 libtommath/bn_mp_prime_is_prime.c
 create mode 100644 libtommath/bn_mp_prime_miller_rabin.c
 create mode 100644 libtommath/bn_mp_prime_next_prime.c
 create mode 100644 libtommath/bn_mp_prime_rabin_miller_trials.c
 create mode 100644 libtommath/bn_mp_prime_random_ex.c
 create mode 100644 libtommath/bn_mp_radix_size.c
 create mode 100644 libtommath/bn_mp_radix_smap.c
 create mode 100644 libtommath/bn_mp_rand.c
 create mode 100644 libtommath/bn_mp_read_radix.c
 create mode 100644 libtommath/bn_mp_read_signed_bin.c
 create mode 100644 libtommath/bn_mp_read_unsigned_bin.c
 create mode 100644 libtommath/bn_mp_reduce.c
 create mode 100644 libtommath/bn_mp_reduce_2k.c
 create mode 100644 libtommath/bn_mp_reduce_2k_l.c
 create mode 100644 libtommath/bn_mp_reduce_2k_setup.c
 create mode 100644 libtommath/bn_mp_reduce_2k_setup_l.c
 create mode 100644 libtommath/bn_mp_reduce_is_2k.c
 create mode 100644 libtommath/bn_mp_reduce_is_2k_l.c
 create mode 100644 libtommath/bn_mp_reduce_setup.c
 create mode 100644 libtommath/bn_mp_rshd.c
 create mode 100644 libtommath/bn_mp_set.c
 create mode 100644 libtommath/bn_mp_set_int.c
 create mode 100644 libtommath/bn_mp_shrink.c
 create mode 100644 libtommath/bn_mp_signed_bin_size.c
 create mode 100644 libtommath/bn_mp_sqr.c
 create mode 100644 libtommath/bn_mp_sqrmod.c
 create mode 100644 libtommath/bn_mp_sqrt.c
 create mode 100644 libtommath/bn_mp_sub.c
 create mode 100644 libtommath/bn_mp_sub_d.c
 create mode 100644 libtommath/bn_mp_submod.c
 create mode 100644 libtommath/bn_mp_to_signed_bin.c
 create mode 100644 libtommath/bn_mp_to_signed_bin_n.c
 create mode 100644 libtommath/bn_mp_to_unsigned_bin.c
 create mode 100644 libtommath/bn_mp_to_unsigned_bin_n.c
 create mode 100644 libtommath/bn_mp_toom_mul.c
 create mode 100644 libtommath/bn_mp_toom_sqr.c
 create mode 100644 libtommath/bn_mp_toradix.c
 create mode 100644 libtommath/bn_mp_toradix_n.c
 create mode 100644 libtommath/bn_mp_unsigned_bin_size.c
 create mode 100644 libtommath/bn_mp_xor.c
 create mode 100644 libtommath/bn_mp_zero.c
 create mode 100644 libtommath/bn_prime_tab.c
 create mode 100644 libtommath/bn_reverse.c
 create mode 100644 libtommath/bn_s_mp_add.c
 create mode 100644 libtommath/bn_s_mp_exptmod.c
 create mode 100644 libtommath/bn_s_mp_mul_digs.c
 create mode 100644 libtommath/bn_s_mp_mul_high_digs.c
 create mode 100644 libtommath/bn_s_mp_sqr.c
 create mode 100644 libtommath/bn_s_mp_sub.c
 create mode 100644 libtommath/bncore.c
 create mode 100644 libtommath/booker.pl
 create mode 100644 libtommath/callgraph.txt
 create mode 100644 libtommath/changes.txt
 create mode 100644 libtommath/demo/demo.c
 create mode 100644 libtommath/demo/timing.c
 create mode 100644 libtommath/dep.pl
 create mode 100644 libtommath/etc/2kprime.1
 create mode 100644 libtommath/etc/2kprime.c
 create mode 100644 libtommath/etc/drprime.c
 create mode 100644 libtommath/etc/drprimes.28
 create mode 100644 libtommath/etc/drprimes.txt
 create mode 100644 libtommath/etc/makefile
 create mode 100644 libtommath/etc/makefile.icc
 create mode 100644 libtommath/etc/makefile.msvc
 create mode 100644 libtommath/etc/mersenne.c
 create mode 100644 libtommath/etc/mont.c
 create mode 100644 libtommath/etc/pprime.c
 create mode 100644 libtommath/etc/prime.1024
 create mode 100644 libtommath/etc/prime.512
 create mode 100644 libtommath/etc/timer.asm
 create mode 100644 libtommath/etc/tune.c
 create mode 100644 libtommath/gen.pl
 create mode 100644 libtommath/logs/README
 create mode 100644 libtommath/logs/add.log
 create mode 100644 libtommath/logs/addsub.png
 create mode 100644 libtommath/logs/expt.log
 create mode 100644 libtommath/logs/expt.png
 create mode 100644 libtommath/logs/expt_2k.log
 create mode 100644 libtommath/logs/expt_2kl.log
 create mode 100644 libtommath/logs/expt_dr.log
 create mode 100644 libtommath/logs/graphs.dem
 create mode 100644 libtommath/logs/index.html
 create mode 100644 libtommath/logs/invmod.log
 create mode 100644 libtommath/logs/invmod.png
 create mode 100644 libtommath/logs/mult.log
 create mode 100644 libtommath/logs/mult.png
 create mode 100644 libtommath/logs/mult_kara.log
 create mode 100644 libtommath/logs/sqr.log
 create mode 100644 libtommath/logs/sqr_kara.log
 create mode 100644 libtommath/logs/sub.log
 create mode 100644 libtommath/makefile
 create mode 100644 libtommath/makefile.bcc
 create mode 100644 libtommath/makefile.cygwin_dll
 create mode 100644 libtommath/makefile.icc
 create mode 100644 libtommath/makefile.msvc
 create mode 100644 libtommath/makefile.shared
 create mode 100644 libtommath/mess.sh
 create mode 100644 libtommath/mtest/logtab.h
 create mode 100644 libtommath/mtest/mpi-config.h
 create mode 100644 libtommath/mtest/mpi-types.h
 create mode 100644 libtommath/mtest/mpi.c
 create mode 100644 libtommath/mtest/mpi.h
 create mode 100644 libtommath/mtest/mtest.c
 create mode 100644 libtommath/pics/design_process.sxd
 create mode 100644 libtommath/pics/design_process.tif
 create mode 100644 libtommath/pics/expt_state.sxd
 create mode 100644 libtommath/pics/expt_state.tif
 create mode 100644 libtommath/pics/makefile
 create mode 100644 libtommath/pics/primality.tif
 create mode 100644 libtommath/pics/radix.sxd
 create mode 100644 libtommath/pics/sliding_window.sxd
 create mode 100644 libtommath/pics/sliding_window.tif
 create mode 100644 libtommath/poster.out
 create mode 100644 libtommath/poster.pdf
 create mode 100644 libtommath/poster.tex
 create mode 100644 libtommath/pre_gen/mpi.c
 create mode 100644 libtommath/pretty.build
 create mode 100644 libtommath/tombc/grammar.txt
 create mode 100644 libtommath/tommath.h
 create mode 100644 libtommath/tommath.out
 create mode 100644 libtommath/tommath.pdf
 create mode 100644 libtommath/tommath.src
 create mode 100644 libtommath/tommath.tex
 create mode 100644 libtommath/tommath_class.h
 create mode 100644 libtommath/tommath_superclass.h
 create mode 100644 license.terms
 create mode 100644 macosx/GNUmakefile
 create mode 100644 macosx/README
 create mode 100644 macosx/Tcl-Common.xcconfig
 create mode 100644 macosx/Tcl-Debug.xcconfig
 create mode 100644 macosx/Tcl-Info.plist.in
 create mode 100644 macosx/Tcl-Release.xcconfig
 create mode 100644 macosx/Tcl.xcode/default.pbxuser
 create mode 100644 macosx/Tcl.xcode/project.pbxproj
 create mode 100644 macosx/Tcl.xcodeproj/default.pbxuser
 create mode 100644 macosx/Tcl.xcodeproj/project.pbxproj
 create mode 100644 macosx/Tclsh-Info.plist.in
 create mode 100644 macosx/configure.ac
 create mode 100644 macosx/tclMacOSXBundle.c
 create mode 100644 macosx/tclMacOSXFCmd.c
 create mode 100644 macosx/tclMacOSXNotify.c
 create mode 100644 pkgs/README
 create mode 100644 pkgs/package.list.txt
 create mode 100644 tests/README
 create mode 100644 tests/aaa_exit.test
 create mode 100644 tests/all.tcl
 create mode 100644 tests/append.test
 create mode 100644 tests/appendComp.test
 create mode 100644 tests/apply.test
 create mode 100644 tests/assemble.test
 create mode 100644 tests/assemble1.bench
 create mode 100644 tests/assocd.test
 create mode 100644 tests/async.test
 create mode 100644 tests/autoMkindex.test
 create mode 100644 tests/basic.test
 create mode 100644 tests/binary.test
 create mode 100644 tests/case.test
 create mode 100644 tests/chan.test
 create mode 100644 tests/chanio.test
 create mode 100644 tests/clock.test
 create mode 100644 tests/cmdAH.test
 create mode 100644 tests/cmdIL.test
 create mode 100644 tests/cmdInfo.test
 create mode 100644 tests/cmdMZ.test
 create mode 100644 tests/compExpr-old.test
 create mode 100644 tests/compExpr.test
 create mode 100644 tests/compile.test
 create mode 100644 tests/concat.test
 create mode 100644 tests/config.test
 create mode 100644 tests/coroutine.test
 create mode 100644 tests/dcall.test
 create mode 100644 tests/dict.test
 create mode 100644 tests/dstring.test
 create mode 100644 tests/encoding.test
 create mode 100644 tests/env.test
 create mode 100644 tests/error.test
 create mode 100644 tests/eval.test
 create mode 100644 tests/event.test
 create mode 100644 tests/exec.test
 create mode 100644 tests/execute.test
 create mode 100644 tests/expr-old.test
 create mode 100644 tests/expr.test
 create mode 100644 tests/fCmd.test
 create mode 100644 tests/fileName.test
 create mode 100644 tests/fileSystem.test
 create mode 100644 tests/for-old.test
 create mode 100644 tests/for.test
 create mode 100644 tests/foreach.test
 create mode 100644 tests/format.test
 create mode 100644 tests/get.test
 create mode 100644 tests/history.test
 create mode 100644 tests/http.test
 create mode 100644 tests/http11.test
 create mode 100644 tests/httpd
 create mode 100644 tests/httpd11.tcl
 create mode 100644 tests/httpold.test
 create mode 100644 tests/if-old.test
 create mode 100644 tests/if.test
 create mode 100644 tests/incr-old.test
 create mode 100644 tests/incr.test
 create mode 100644 tests/indexObj.test
 create mode 100644 tests/info.test
 create mode 100644 tests/init.test
 create mode 100644 tests/interp.test
 create mode 100644 tests/io.test
 create mode 100644 tests/ioCmd.test
 create mode 100644 tests/ioTrans.test
 create mode 100644 tests/iogt.test
 create mode 100644 tests/join.test
 create mode 100644 tests/lindex.test
 create mode 100644 tests/link.test
 create mode 100644 tests/linsert.test
 create mode 100644 tests/list.test
 create mode 100644 tests/listObj.test
 create mode 100644 tests/llength.test
 create mode 100644 tests/lmap.test
 create mode 100644 tests/load.test
 create mode 100644 tests/lrange.test
 create mode 100644 tests/lrepeat.test
 create mode 100644 tests/lreplace.test
 create mode 100644 tests/lsearch.test
 create mode 100644 tests/lset.test
 create mode 100644 tests/lsetComp.test
 create mode 100644 tests/macOSXFCmd.test
 create mode 100644 tests/macOSXLoad.test
 create mode 100644 tests/main.test
 create mode 100644 tests/mathop.test
 create mode 100644 tests/misc.test
 create mode 100644 tests/msgcat.test
 create mode 100644 tests/namespace-old.test
 create mode 100644 tests/namespace.test
 create mode 100644 tests/notify.test
 create mode 100644 tests/nre.test
 create mode 100644 tests/obj.test
 create mode 100644 tests/oo.test
 create mode 100644 tests/ooNext2.test
 create mode 100644 tests/opt.test
 create mode 100644 tests/package.test
 create mode 100644 tests/parse.test
 create mode 100644 tests/parseExpr.test
 create mode 100644 tests/parseOld.test
 create mode 100644 tests/pid.test
 create mode 100644 tests/pkgMkIndex.test
 create mode 100644 tests/platform.test
 create mode 100644 tests/proc-old.test
 create mode 100644 tests/proc.test
 create mode 100644 tests/pwd.test
 create mode 100644 tests/reg.test
 create mode 100644 tests/regexp.test
 create mode 100644 tests/regexpComp.test
 create mode 100644 tests/registry.test
 create mode 100644 tests/remote.tcl
 create mode 100644 tests/rename.test
 create mode 100644 tests/resolver.test
 create mode 100644 tests/result.test
 create mode 100644 tests/safe.test
 create mode 100644 tests/scan.test
 create mode 100644 tests/security.test
 create mode 100644 tests/set-old.test
 create mode 100644 tests/set.test
 create mode 100644 tests/socket.test
 create mode 100644 tests/source.test
 create mode 100644 tests/split.test
 create mode 100644 tests/stack.test
 create mode 100644 tests/string.test
 create mode 100644 tests/stringComp.test
 create mode 100644 tests/stringObj.test
 create mode 100644 tests/subst.test
 create mode 100644 tests/switch.test
 create mode 100644 tests/tailcall.test
 create mode 100644 tests/tcltest.test
 create mode 100644 tests/thread.test
 create mode 100644 tests/timer.test
 create mode 100644 tests/tm.test
 create mode 100644 tests/trace.test
 create mode 100644 tests/unixFCmd.test
 create mode 100644 tests/unixFile.test
 create mode 100644 tests/unixForkEvent.test
 create mode 100644 tests/unixInit.test
 create mode 100644 tests/unixNotfy.test
 create mode 100644 tests/unknown.test
 create mode 100644 tests/unload.test
 create mode 100644 tests/uplevel.test
 create mode 100644 tests/upvar.test
 create mode 100644 tests/utf.test
 create mode 100644 tests/util.test
 create mode 100644 tests/var.test
 create mode 100644 tests/while-old.test
 create mode 100644 tests/while.test
 create mode 100644 tests/winConsole.test
 create mode 100644 tests/winDde.test
 create mode 100644 tests/winFCmd.test
 create mode 100644 tests/winFile.test
 create mode 100644 tests/winNotify.test
 create mode 100644 tests/winPipe.test
 create mode 100644 tests/winTime.test
 create mode 100644 tests/zlib.test
 create mode 100644 tools/Makefile.in
 create mode 100644 tools/README
 create mode 100755 tools/checkLibraryDoc.tcl
 create mode 100755 tools/configure
 create mode 100644 tools/configure.in
 create mode 100644 tools/encoding/Makefile
 create mode 100644 tools/encoding/README
 create mode 100644 tools/encoding/ascii.txt
 create mode 100644 tools/encoding/big5.txt
 create mode 100644 tools/encoding/cjk.inf
 create mode 100644 tools/encoding/cp1250.txt
 create mode 100644 tools/encoding/cp1251.txt
 create mode 100644 tools/encoding/cp1252.txt
 create mode 100644 tools/encoding/cp1253.txt
 create mode 100644 tools/encoding/cp1254.txt
 create mode 100644 tools/encoding/cp1255.txt
 create mode 100644 tools/encoding/cp1256.txt
 create mode 100644 tools/encoding/cp1257.txt
 create mode 100644 tools/encoding/cp1258.txt
 create mode 100644 tools/encoding/cp437.txt
 create mode 100644 tools/encoding/cp737.txt
 create mode 100644 tools/encoding/cp775.txt
 create mode 100644 tools/encoding/cp850.txt
 create mode 100644 tools/encoding/cp852.txt
 create mode 100644 tools/encoding/cp855.txt
 create mode 100644 tools/encoding/cp857.txt
 create mode 100644 tools/encoding/cp860.txt
 create mode 100644 tools/encoding/cp861.txt
 create mode 100644 tools/encoding/cp862.txt
 create mode 100644 tools/encoding/cp863.txt
 create mode 100644 tools/encoding/cp864.txt
 create mode 100644 tools/encoding/cp865.txt
 create mode 100644 tools/encoding/cp866.txt
 create mode 100644 tools/encoding/cp869.txt
 create mode 100644 tools/encoding/cp874.txt
 create mode 100644 tools/encoding/cp932.txt
 create mode 100644 tools/encoding/cp936.txt
 create mode 100644 tools/encoding/cp949.txt
 create mode 100644 tools/encoding/cp950.txt
 create mode 100644 tools/encoding/dingbats.txt
 create mode 100644 tools/encoding/ebcdic.txt
 create mode 100644 tools/encoding/gb12345.txt
 create mode 100644 tools/encoding/gb1988.txt
 create mode 100644 tools/encoding/gb2312.txt
 create mode 100644 tools/encoding/iso2022-jp.esc
 create mode 100644 tools/encoding/iso2022-kr.esc
 create mode 100644 tools/encoding/iso2022.esc
 create mode 100644 tools/encoding/iso8859-1.txt
 create mode 100644 tools/encoding/iso8859-10.txt
 create mode 100644 tools/encoding/iso8859-13.txt
 create mode 100644 tools/encoding/iso8859-14.txt
 create mode 100644 tools/encoding/iso8859-15.txt
 create mode 100644 tools/encoding/iso8859-16.txt
 create mode 100644 tools/encoding/iso8859-2.txt
 create mode 100644 tools/encoding/iso8859-3.txt
 create mode 100644 tools/encoding/iso8859-4.txt
 create mode 100644 tools/encoding/iso8859-5.txt
 create mode 100644 tools/encoding/iso8859-6.txt
 create mode 100644 tools/encoding/iso8859-7.txt
 create mode 100644 tools/encoding/iso8859-8.txt
 create mode 100644 tools/encoding/iso8859-9.txt
 create mode 100644 tools/encoding/jis0201.txt
 create mode 100644 tools/encoding/jis0208.txt
 create mode 100644 tools/encoding/jis0212.txt
 create mode 100644 tools/encoding/koi8-r.txt
 create mode 100644 tools/encoding/ksc5601.txt
 create mode 100644 tools/encoding/macCentEuro.txt
 create mode 100644 tools/encoding/macCroatian.txt
 create mode 100644 tools/encoding/macCyrillic.txt
 create mode 100644 tools/encoding/macDingbats.txt
 create mode 100644 tools/encoding/macGreek.txt
 create mode 100644 tools/encoding/macIceland.txt
 create mode 100644 tools/encoding/macJapan.txt
 create mode 100644 tools/encoding/macRoman.txt
 create mode 100644 tools/encoding/macRomania.txt
 create mode 100644 tools/encoding/macThai.txt
 create mode 100644 tools/encoding/macTurkish.txt
 create mode 100644 tools/encoding/macUkraine.txt
 create mode 100644 tools/encoding/shiftjis.txt
 create mode 100644 tools/encoding/symbol.txt
 create mode 100644 tools/encoding/tis-620.txt
 create mode 100644 tools/encoding/txt2enc.c
 create mode 100644 tools/eolFix.tcl
 create mode 100644 tools/feather.bmp
 create mode 100755 tools/findBadExternals.tcl
 create mode 100755 tools/fix_tommath_h.tcl
 create mode 100644 tools/genStubs.tcl
 create mode 100644 tools/index.tcl
 create mode 100644 tools/installData.tcl
 create mode 100755 tools/loadICU.tcl
 create mode 100755 tools/makeTestCases.tcl
 create mode 100644 tools/man2help.tcl
 create mode 100644 tools/man2help2.tcl
 create mode 100644 tools/man2html.tcl
 create mode 100644 tools/man2html1.tcl
 create mode 100644 tools/man2html2.tcl
 create mode 100644 tools/man2tcl.c
 create mode 100644 tools/mkdepend.tcl
 create mode 100644 tools/regexpTestLib.tcl
 create mode 100644 tools/str2c
 create mode 100644 tools/tcl.hpj.in
 create mode 100755 tools/tclZIC.tcl
 create mode 100644 tools/tclsh.svg
 create mode 100644 tools/tcltk-man2html-utils.tcl
 create mode 100755 tools/tcltk-man2html.tcl
 create mode 100644 tools/tsdPerf.c
 create mode 100644 tools/tsdPerf.tcl
 create mode 100644 tools/uniClass.tcl
 create mode 100644 tools/uniParse.tcl
 create mode 100644 tools/white.bmp
 create mode 100644 unix/Makefile.in
 create mode 100644 unix/README
 create mode 100644 unix/aclocal.m4
 create mode 100755 unix/configure
 create mode 100644 unix/configure.in
 create mode 100644 unix/dltest/Makefile.in
 create mode 100644 unix/dltest/README
 create mode 100644 unix/dltest/pkga.c
 create mode 100644 unix/dltest/pkgb.c
 create mode 100644 unix/dltest/pkgc.c
 create mode 100644 unix/dltest/pkgd.c
 create mode 100644 unix/dltest/pkge.c
 create mode 100644 unix/dltest/pkgooa.c
 create mode 100644 unix/dltest/pkgua.c
 create mode 100755 unix/install-sh
 create mode 100755 unix/installManPage
 create mode 100755 unix/ldAix
 create mode 100644 unix/tcl.m4
 create mode 100644 unix/tcl.pc.in
 create mode 100644 unix/tcl.spec
 create mode 100644 unix/tclAppInit.c
 create mode 100644 unix/tclConfig.h.in
 create mode 100644 unix/tclConfig.sh.in
 create mode 100644 unix/tclLoadAix.c
 create mode 100644 unix/tclLoadDl.c
 create mode 100644 unix/tclLoadDyld.c
 create mode 100644 unix/tclLoadNext.c
 create mode 100644 unix/tclLoadOSF.c
 create mode 100644 unix/tclLoadShl.c
 create mode 100644 unix/tclUnixChan.c
 create mode 100644 unix/tclUnixCompat.c
 create mode 100644 unix/tclUnixEvent.c
 create mode 100644 unix/tclUnixFCmd.c
 create mode 100644 unix/tclUnixFile.c
 create mode 100644 unix/tclUnixInit.c
 create mode 100644 unix/tclUnixNotfy.c
 create mode 100644 unix/tclUnixPipe.c
 create mode 100644 unix/tclUnixPort.h
 create mode 100644 unix/tclUnixSock.c
 create mode 100644 unix/tclUnixTest.c
 create mode 100644 unix/tclUnixThrd.c
 create mode 100644 unix/tclUnixThrd.h
 create mode 100644 unix/tclUnixTime.c
 create mode 100644 unix/tclXtNotify.c
 create mode 100644 unix/tclXtTest.c
 create mode 100644 unix/tclooConfig.sh
 create mode 100644 win/Makefile.in
 create mode 100644 win/README
 create mode 100644 win/aclocal.m4
 create mode 100644 win/buildall.vc.bat
 create mode 100644 win/cat.c
 create mode 100644 win/coffbase.txt
 create mode 100755 win/configure
 create mode 100644 win/configure.in
 create mode 100644 win/makefile.bc
 create mode 100644 win/makefile.vc
 create mode 100644 win/nmakehlp.c
 create mode 100644 win/rules.vc
 create mode 100644 win/tcl.dsp
 create mode 100644 win/tcl.dsw
 create mode 100644 win/tcl.hpj.in
 create mode 100644 win/tcl.m4
 create mode 100644 win/tcl.rc
 create mode 100644 win/tclAppInit.c
 create mode 100644 win/tclConfig.sh.in
 create mode 100644 win/tclWin32Dll.c
 create mode 100644 win/tclWinChan.c
 create mode 100644 win/tclWinConsole.c
 create mode 100644 win/tclWinDde.c
 create mode 100644 win/tclWinError.c
 create mode 100644 win/tclWinFCmd.c
 create mode 100755 win/tclWinFile.c
 create mode 100644 win/tclWinInit.c
 create mode 100644 win/tclWinInt.h
 create mode 100644 win/tclWinLoad.c
 create mode 100644 win/tclWinNotify.c
 create mode 100644 win/tclWinPipe.c
 create mode 100644 win/tclWinPort.h
 create mode 100644 win/tclWinReg.c
 create mode 100644 win/tclWinSerial.c
 create mode 100644 win/tclWinSock.c
 create mode 100644 win/tclWinTest.c
 create mode 100644 win/tclWinThrd.c
 create mode 100644 win/tclWinTime.c
 create mode 100644 win/tclooConfig.sh
 create mode 100644 win/tclsh.exe.manifest.in
 create mode 100644 win/tclsh.ico
 create mode 100644 win/tclsh.rc

diff --git a/.fossil-settings/binary-glob b/.fossil-settings/binary-glob
new file mode 100644
index 0000000..ca85874
--- /dev/null
+++ b/.fossil-settings/binary-glob
@@ -0,0 +1,3 @@
+*.bmp
+*.gif
+*.png
diff --git a/.fossil-settings/crnl-glob b/.fossil-settings/crnl-glob
new file mode 100644
index 0000000..c014320
--- /dev/null
+++ b/.fossil-settings/crnl-glob
@@ -0,0 +1,10 @@
+tools/tcl.hpj.in
+tools/tcl.wse.in
+win/buildall.vc.bat
+win/coffbase.txt
+win/makefile.bc
+win/makefile.vc
+win/rules.vc
+win/tcl.dsp
+win/tcl.dsw
+win/tcl.hpj.in
diff --git a/.fossil-settings/encoding-glob b/.fossil-settings/encoding-glob
new file mode 100644
index 0000000..c014320
--- /dev/null
+++ b/.fossil-settings/encoding-glob
@@ -0,0 +1,10 @@
+tools/tcl.hpj.in
+tools/tcl.wse.in
+win/buildall.vc.bat
+win/coffbase.txt
+win/makefile.bc
+win/makefile.vc
+win/rules.vc
+win/tcl.dsp
+win/tcl.dsw
+win/tcl.hpj.in
diff --git a/.fossil-settings/ignore-glob b/.fossil-settings/ignore-glob
new file mode 100644
index 0000000..9ed86b1
--- /dev/null
+++ b/.fossil-settings/ignore-glob
@@ -0,0 +1,24 @@
+*.a
+*.dll
+*.dylib
+*.exe
+*.exp
+*.lib
+*.o
+*.obj
+*.res
+*.sl
+*.so
+*/Makefile
+*/config.cache
+*/config.log
+*/config.status
+*/tclConfig.sh
+*/tclsh*
+*/tcltest*
+*/versions.vc
+unix/dltest.marker
+unix/tcl.pc
+unix/pkgs/*
+win/pkgs/*
+win/tcl.hpj
diff --git a/.project b/.project
new file mode 100644
index 0000000..358cc74
--- /dev/null
+++ b/.project
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>tcl8.6</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+	</buildSpec>
+	<natures>
+	</natures>
+</projectDescription>
diff --git a/.settings/org.eclipse.core.resources.prefs b/.settings/org.eclipse.core.resources.prefs
new file mode 100644
index 0000000..99f26c0
--- /dev/null
+++ b/.settings/org.eclipse.core.resources.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+encoding/<project>=UTF-8
diff --git a/.settings/org.eclipse.core.runtime.prefs b/.settings/org.eclipse.core.runtime.prefs
new file mode 100644
index 0000000..5a0ad22
--- /dev/null
+++ b/.settings/org.eclipse.core.runtime.prefs
@@ -0,0 +1,2 @@
+eclipse.preferences.version=1
+line.separator=\n
diff --git a/ChangeLog b/ChangeLog
new file mode 100644
index 0000000..e2881a0
--- /dev/null
+++ b/ChangeLog
@@ -0,0 +1,8856 @@
+A NOTE ON THE CHANGELOG:
+Starting in early 2011, Tcl source code has been under the management of
+fossil, hosted at http://core.tcl.tk/tcl/ .  Fossil presents a "Timeline"
+view of changes made that is superior in every way to a hand edited log file.
+Because of this, many Tcl developers are now out of the habit of maintaining
+this log file.  You may still find useful things in it, but the Timeline is
+a better first place to look now.
+============================================================================
+
+2013-09-19  Don Porter  <dgp@users.sourceforge.net>
+
+	*** 8.6.1 TAGGED FOR RELEASE ***
+
+	* generic/tcl.h:	Bump version number to 8.6.1.
+	* library/init.tcl:
+	* unix/configure.in:
+	* win/configure.in:
+	* unix/tcl.spec:
+	* README:
+
+	* unix/configure:	autoconf-2.59
+	* win/configure:
+
+2013-09-19  Donal Fellows  <dkf@users.sf.net>
+
+	* doc/next.n (METHOD SEARCH ORDER): Bug [3606943]: Corrected
+	description of method search order.
+
+2013-09-18  Donal Fellows  <dkf@users.sf.net>
+
+	Bump TclOO version to 1.0.1 for release.
+
+2013-09-17  Donal Fellows  <dkf@users.sf.net>
+
+	* generic/tclBinary.c (BinaryEncodeUu, BinaryDecodeUu): [Bug 2152292]:
+	Corrected implementation of the core of uuencode handling so that the
+	line length processing is correctly applied.
+	***POTENTIAL INCOMPATIBILITY***
+	Existing code that was using the old versions and working around the
+	limitations will now need to do far less. The -maxlen option now has
+	strict limits on the range of supported lengths; this is a limitation
+	of the format itself.
+
+2013-09-09  Donal Fellows  <dkf@users.sf.net>
+
+	* generic/tclOOMethod.c (CloneProcedureMethod): [Bug 3609693]: Strip
+	the internal representation of method bodies during cloning in order
+	to ensure that any bound references to instance variables are removed.
+
+2013-09-01  Donal Fellows  <dkf@users.sf.net>
+
+	* generic/tclBinary.c (BinaryDecodeHex): [Bug b98fa55285]: Ensure that
+	whitespace at the end of a string don't cause the decoder to drop the
+	last decoded byte.
+
+2013-08-03  Donal Fellows  <dkf@users.sf.net>
+
+	* library/auto.tcl: [Patch 3611643]: Allow TclOO classes to be found
+	by the autoloading mechanism.
+
+2013-08-02  Donal Fellows  <dkf@users.sf.net>
+
+	* generic/tclOODefineCmds.c (ClassSuperSet): Bug [9d61624b3d]: Stop
+	crashes when emptying the superclass slot, even when doing elaborate
+	things with metaclasses.
+
+2013-08-01  Harald Oehlmann  <oehhar@users.sf.net>
+
+	* tclUnixNotify.c (Tcl_InitNotifier): Bug [a0bc856dcd]: Start notifier
+	thread again if we were forked, to solve Rivet bug 55153.
+
+2013-07-05  Kevin B. Kenny  <kennykb@acm.org>
+
+	* library/tzdata/Africa/Casablanca:
+	* library/tzdata/America/Asuncion:
+	* library/tzdata/Antarctica/Macquarie:
+	* library/tzdata/Asia/Gaza:
+	* library/tzdata/Asia/Hebron:
+	* library/tzdata/Asia/Jerusalem:
+	http://www.iana.org/time-zones/repository/releases/tzdata2013d.tar.gz
+
+2013-07-03  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* unix/tclXtNotify.c: Bug [817249]: bring tclXtNotify.c up to date with
+	Tcl_SetNotifier() change.
+
+2013-07-02  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* unix/tcl.m4:  Bug [32afa6e256]: dirent64 check is incorrect in tcl.m4
+	* unix/configure: (thanks to Brian Griffin)
+
+2013-06-27  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tclConfig.c: Bug [9b2e636361]: Tcl_CreateInterp() needs
+	* generic/tclMain.c:   initialized encodings.
+
+2013-06-18  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tclEvent.c: Bug [3611974]: InitSubsystems multiple thread
+	issue.
+
+2013-06-17  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/regc_locale.c: Bug [a876646efe]: re_expr character class
+	[:cntrl:] should contain \u0000 - \u001f
+
+2013-06-09  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclCompCmdsSZ.c (TclCompileTryCmd): [Bug 779d38b996]:
+	Rewrote the [try] compiler to generate better code in some cases and
+	to behave correctly in others; when an error happens during the
+	processing of an exception-trap clause or a finally clause, the
+	*original* return options are now captured in a -during option, even
+	when fully compiled.
+
+2013-06-05  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclExecute.c (INST_EXPAND_DROP): [Bugs 2835313, 3614226]:
+	New opcode to allow resetting the stack to get rid of an expansion,
+	restoring the stack to a known state in the process.
+	* generic/tclCompile.c, generic/tclCompCmds.c: Adjusted the compilers
+	for [break] and [continue] to get stack cleanup right in the majority
+	of cases.
+	* tests/for.test (for-7.*): Set of tests for these evil cases.
+
+2013-06-04  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* unix/tcl.m4: Eliminate NO_VIZ macro as current zlib uses HAVE_HIDDEN
+	instead. One more last-moment fix for FreeBSD by Pietro Cerutti
+
+2013-06-03  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclExecute.c: fix for perf bug detected by Kieran
+	(https://groups.google.com/forum/?fromgroups#!topic/comp.lang.tcl/vfpI3bc-DkQ),
+	diagnosed by dgp to be a close relative of [Bug 781585], which was
+	fixed by commit	[f46fb50cb3]. This bug was introduced by myself in
+	commit [cbfe055d8c].
+
+2013-06-03  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclCompCmds.c (TclCompileBreakCmd, TclCompileContinueCmd):
+	Added code to allow [break] and [continue] to be issued as a jump (in
+	the most common cases) rather than using the more expensive exception
+	processing path in the bytecode engine. [Bug 3614226]: Partial fix for
+	the issues relating to cleaning up the stack when dealing with [break]
+	and [continue].
+
+2013-05-27 Harald Oehlmann  <oehhar@users.sf.net>
+
+	* library/msgcat/msgcat.tcl: [Bug 3036566]: Also get locale from
+	registry key HCU\Control Panel\Desktop : PreferredUILanguages to honor
+	installed language packs on Vista+.
+	Bumped msgcat version to 1.5.2
+
+2013-05-22  Andreas Kupries  <andreask@activestate.com>
+
+	* tclCompile.c: Removed duplicate const qualifier causing the HP
+	native cc to error out.
+
+2013-05-22  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclUtf.c (TclUtfCasecmp): [Bug 3613609]: Replace problematic
+	uses of strcasecmp with a proper UTF-8-aware version. Affects both
+	[lsearch -nocase] and [lsort -nocase].
+
+2013-05-22  Donal K. Fellows  <dkf@users.sf.net>
+
+	* doc/file.n: [Bug 3613671]: Added note to portability section on the
+	fact that [file owned] does not produce useful results on Windows.
+
+2013-05-20  Donal K. Fellows  <dkf@users.sf.net>
+
+	* unix/tclUnixFCmd.c (DefaultTempDir): [Bug 3613567]: Corrected logic
+	for checking return code of access() system call, which was inverted.
+
+2013-05-19  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* unix/tcl.m4:     Fix for FreeBSD, and remove support for older
+	* unix/configure:  FreeBSD versions. Patch by Pietro Cerutti.
+
+2013-05-18  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclCompCmdsGR.c: Split tclCompCmds.c again to keep size of
+	code down.
+
+2013-05-16  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tclBasic.c: Add panic in order to detect incompatible
+	mingw32 sys/stat.h and sys/time.h headers.
+
+2013-05-13  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* compat/zlib/*: Upgrade to zlib 1.2.8
+
+2013-05-10  Donal K. Fellows  <dkf@users.sf.net>
+
+	Optimizations and general bytecode generation improvements.
+	* generic/tclCompCmds.c (TclCompileAppendCmd, TclCompileLappendCmd):
+	(TclCompileReturnCmd): Make these generate bytecode in more cases.
+	(TclCompileListCmd): Make this able to push a literal when it can.
+	* generic/tclCompile.c (TclSetByteCodeFromAny, PeepholeOptimize):
+	Added checks to see if we can apply some simple cross-command-boundary
+	optimizations, and defined a small number of such optimizations.
+	(TclCompileScript): Added the special ability to compile the list
+	command with expansion ([list {*}blah]) into bytecode that does not
+	call an external command.
+
+2013-05-06  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tclStubInit.c: Add support for Cygwin64, which has a 64-bit
+	* generic/tclDecls.h: "long" type. Binary compatibility with win64
+	requires that all stub entries use 32-bit long's, therefore the need
+	for various wrapper functions/macros. For Tcl 9 a better solution is
+	needed, but that cannot be done without introducing binary
+	incompatibility.
+
+2013-04-30  Andreas Kupries  <andreask@activestate.com>
+
+	* library/platform/platform.tcl (::platform::LibcVersion):
+	* library/platform/pkgIndex.tcl: Followup to the 2013-01-30 change.
+	The RE become too restrictive again. SuSe added a timestamp after the
+	version. Loosened up a bit. Bumped package to version 1.0.12.
+
+2013-04-29  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclCompCmds.c (TclCompileArraySetCmd): Generate better code
+	when the list of things to set is a literal.
+
+2013-04-25  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tclDecls.h: Implement Tcl_NewBooleanObj, Tcl_DbNewBooleanObj
+	and Tcl_SetBooleanObj as macros using Tcl_NewIntObj, Tcl_DbNewLongObj
+	and Tcl_SetIntObj. Starting with Tcl 8.5, this is exactly the same, it
+	only eliminates code duplication.
+	* generic/tclInt.h: Eliminate use of NO_WIDE_TYPE everywhere: It's
+	exactly the same as TCL_WIDE_INT_IS_LONG
+
+2013-04-19  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tclDecls.h: Implement many Tcl_*Var* functions and
+	Tcl_GetIndexFromObj as (faster/stack-saving) macros around resp their
+	Tcl_*Var*2 equivalent and Tcl_GetIndexFromObjStruct.
+
+2013-04-12  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tclDecls.h: Implement Tcl_Pkg* functions as
+	(faster/stack-saving) macros around Tcl_Pkg*Ex functions.
+
+2013-04-08  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/regc_color.c:	[Bug 3610026]: Stop crash when the number of
+	* generic/regerrs.h:	"colors" in a regular expression overflows a
+	* generic/regex.h:	short int.  Thanks to Heikki Linnakangas for
+	* generic/regguts.h:	the report and the patch.
+	* tests/regexp.test:
+
+2013-04-04  Reinhard Max  <max@suse.de>
+
+	* library/http/http.tcl (http::geturl): Allow URLs that don't have a
+	path, but a query query, e.g. http://example.com?foo=bar
+	* Bump the http package to 2.8.7.
+
+2013-03-22  Venkat Iyer <venkat@comit.com>
+	* library/tzdata/Africa/Cairo: Update to tzdata2013b.
+	* library/tzdata/Africa/Casablanca:
+	* library/tzdata/Africa/Gaborone:
+	* library/tzdata/Africa/Tripoli:
+	* library/tzdata/America/Asuncion:
+	* library/tzdata/America/Barbados:
+	* library/tzdata/America/Bogota:
+	* library/tzdata/America/Costa_Rica:
+	* library/tzdata/America/Curacao:
+	* library/tzdata/America/Nassau:
+	* library/tzdata/America/Port-au-Prince:
+	* library/tzdata/America/Santiago:
+	* library/tzdata/Antarctica/Palmer:
+	* library/tzdata/Asia/Aden:
+	* library/tzdata/Asia/Hong_Kong:
+	* library/tzdata/Asia/Muscat:
+	* library/tzdata/Asia/Rangoon:
+	* library/tzdata/Asia/Shanghai:
+	* library/tzdata/Atlantic/Bermuda:
+	* library/tzdata/Europe/Vienna:
+	* library/tzdata/Pacific/Easter:
+	* library/tzdata/Pacific/Fiji:
+	* library/tzdata/Asia/Khandyga: (new)
+	* library/tzdata/Asia/Ust-Nera: (new)
+	* library/tzdata/Europe/Busingen: (new)
+
+2013-03-21  Don Porter  <dgp@users.sourceforge.net>
+
+	* library/auto.tcl: [Bug 2102614]: Add ensemble indexing support to
+	* tests/autoMkindex.test: [auto_mkindex].  Thanks Brian Griffin.
+
+2013-03-19  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclFCmd.c: [Bug 3597000]: Consistent [file copy] result.
+	* tests/fileSystem.test:
+
+2013-03-19  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* win/tclWinFile.c: [Bug 3608360]: Incompatible behaviour of "file
+	exists".
+
+2013-03-18  Donal K. Fellows  <dkf@users.sf.net>
+
+	* tests/cmdAH.test (cmdAH-19.12): [Bug 3608360]: Added test to ensure
+	that we never ever allow [file exists] to do globbing.
+
+2013-03-12  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* unix/tcl.m4: Patch by Andrew Shadura, providing better support for
+	three architectures they have in Debian.
+
+2013-03-11  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclCompile.c:	[Bugs 3607246,3607372]: Unbalanced refcounts
+	* generic/tclLiteral.c:	of literals in the global literal table.
+
+2013-03-06  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/regc_nfa.c:	[Bugs 3604074,3606683]: Rewrite of the
+	* generic/regcomp.c:	fixempties() routine (and supporting routines)
+	to completely eliminate the infinite loop hazard. Thanks to Tom Lane
+	for the much improved solution.
+
+2013-02-28  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclLiteral.c:	Revise TclReleaseLiteral() to tolerate a NULL
+	interp argument.
+
+	* generic/tclCompile.c:	Update callers and revise mistaken comments.
+	* generic/tclProc.c:
+
+2013-02-27  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/regcomp.c:	[Bug 3606139]: missing error check allows
+	* tests/regexp.test:    regexp to crash Tcl. Thanks to Tom Lane for
+	providing the test-case and the patch.
+
+2013-02-26  Donal K. Fellows  <dkf@users.sf.net>
+
+	* tests/chanio.test (chan-io-28.7): [Bug 3605120]: Stop test from
+	hanging when run standalone.
+
+2013-02-26  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tclObj.c: Don't panic if Tcl_ConvertToType is called for a
+	type that doesn't have a setFromAnyProc, create a proper error message.
+
+2013-02-25  Donal K. Fellows  <dkf@users.sf.net>
+
+	* tests/binary.test (binary-41.*): [Bug 3605721]: Test independence
+	fixes. Thanks to Rolf Ade for pointing out the problem.
+
+2013-02-25  Don Porter  <dgp@users.sourceforge.net>
+
+	* tests/assocd.test:	[Bugs 3605719,3605720]: Test independence.
+	* tests/basic.test:	Thanks Rolf Ade for patches.
+
+2013-02-23  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* compat/fake-rfc2553.c: [Bug 3599194]: compat/fake-rfc2553.c is
+	broken.
+
+2013-02-22  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclAssembly.c:	Shift more burden of smart cleanup
+	* generic/tclCompile.c:		onto the TclFreeCompileEnv() routine.
+	Stop crashes when the hookProc raises an error.
+
+2013-02-20  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclNamesp.c:	[Bug 3605447]: Make sure the -clear option
+	* tests/namespace.test:	to [namespace export] always clears, whether
+	or not new export patterns are specified.
+
+2013-02-20  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* win/tclWinDde.c: [Bug 3605401]: Compiler error with latest mingw-w64
+	headers.
+
+2013-02-19  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tclTrace.c:  [Bug 2438181]: Incorrect error reporting in
+	* tests/trace.test:    traces. Test-case and fix provided by Poor
+	Yorick.
+
+2013-02-15  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/regc_nfa.c:	[Bug 3604074]: Fix regexp optimization to
+	* tests/regexp.test:	stop hanging on the expression
+	((((((((a)*)*)*)*)*)*)*)* .  Thanks to Bjørn Grathwohl for discovery.
+
+2013-02-14  Harald Oehlmann  <oehhar@users.sf.net>
+
+	* library/msgcat/msgcat.tcl: [Bug 3604576]: Catch missing registry
+	entry "HCU\Control Panel\International".
+	Bumped msgcat version to 1.5.1
+
+2013-02-11  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclZlib.c (ZlibTransformOutput): [Bug 3603553]: Ensure that
+	data gets written to the underlying stream by compressing transforms
+	when the amount of data to be written is one buffer's-worth; problem
+	was particularly likely to occur when compressing large quantities of
+	not-very-compressible data. Many thanks to Piera Poggio (vampiera) for
+	reporting.
+
+2013-02-09  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclOOBasic.c (TclOO_Object_VarName): [Bug 3603695]: Change
+	the way that the 'varname' method is implemented so that there are no
+	longer problems with interactions due to the resolver. Thanks to
+	Taylor Venable <tcvena@gmail.com> for identifying the problem.
+
+2013-02-08  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/regc_nfa.c (duptraverse): [Bug 3603557]: Increase the
+	maximum depth of recursion used when duplicating an automaton in
+	response to encountering a "wild" RE that hit the previous limit.
+	Allow the limit (DUPTRAVERSE_MAX_DEPTH) to be set by defining its
+	value in the Makefile. Problem reported by Jonathan Mills.
+
+2013-02-05  Don Porter  <dgp@users.sourceforge.net>
+
+	* win/tclWinFile.c:	[Bug 3603434]: Make sure TclpObjNormalizePath()
+	properly declares "a:/" to be normalized, even when no "A:" drive is
+	present on the system.
+
+2013-02-05  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclLoadNone.c (TclpLoadMemory): [Bug 3433012]: Added dummy
+	version of this function to use in the event that a platform thinks it
+	can load from memory but cannot actually do so due to it being
+	disabled at configuration time.
+
+2013-02-04  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclCompCmds.c (TclCompileArraySetCmd): [Bug 3603163]: Stop
+	crash in weird case where [eval] is used to make [array set] get
+	confused about whether there is a local variable table or not. Thanks
+	to Poor Yorick for identifying a reproducible crashing case.
+
+2013-01-30  Andreas Kupries  <andreask@activestate.com>
+
+	* library/platform/platform.tcl (::platform::LibcVersion): See
+	* library/platform/pkgIndex.tcl: [Bug 3599098]: Fixed the RE
+	* unix/Makefile.in: extracting the version to avoid issues with
+	* win/Makefile.in: recent changes to the glibc banner. Now targeting a
+	less variable part of the string. Bumped package to version 1.0.11.
+
+2013-01-28  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclCompCmds.c (TclCompileArraySetCmd)
+	(TclCompileArrayUnsetCmd, TclCompileDictAppendCmd)
+	(TclCompileDictCreateCmd, CompileDictEachCmd, TclCompileDictIncrCmd)
+	(TclCompileDictLappendCmd, TclCompileDictMergeCmd)
+	(TclCompileDictUnsetCmd, TclCompileDictUpdateCmd)
+	(TclCompileDictWithCmd, TclCompileInfoCommandsCmd):
+	* generic/tclCompCmdsSZ.c (TclCompileStringMatchCmd)
+	(TclCompileStringMapCmd): Improve the code generation in cases where
+	full compilation is impossible but a full ensemble invoke is provably
+	not necessary.
+
+2013-01-26  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* unix/tclUnixCompat.c: [Bug 3601804]: platformCPUID segmentation
+	fault on Darwin.
+
+2013-01-23  Donal K. Fellows  <dkf@users.sf.net>
+
+	* library/http/http.tcl (http::geturl): [Bug 2911139]: Do not do vwait
+	for connect to avoid reentrancy problems (except when operating
+	without a -command option). Internally, this means that all sockets
+	created by the http package will always be operated in asynchronous
+	mode.
+
+2013-01-21  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tclInt.decls: Put back Tcl[GS]etStartupScript(Path|FileName)
+	in private stub table, so extensions using this (like Tk 8.4) will
+	continue to work in all Tcl 8.x versions. Extensions using this
+	still cannot be compiled against Tcl 8.6 headers.
+
+2013-01-18  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tclPort.h: [Bug 3598300]: unix: tcl.h does not include
+	sys/stat.h
+
+2013-01-17  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclCompCmds.c (PushVarName): [Bug 3600328]: Added mechanism
+	for suppressing compilation of variables when we couldn't cope with
+	the results. Useful for some [array] subcommands.
+	* generic/tclEnsemble.c (CompileToCompiledCommand): Must restore the
+	compilation environment when a command compiler fails.
+
+2013-01-16  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclZlib.c (TclZlibInit): [Bug 3601086]: Register the config
+	info in the iso8859-1 encoding as that is guaranteed to be present.
+
+2013-01-16  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* Makefile.in:   Allow win32 build with -DTCL_NO_DEPRECATED, just as
+	* generic/tcl.h: in the UNIX build. Define Tcl_EvalObj and
+	* generic/tclDecls.h: Tcl_GlobalEvalObj as macros, even when
+	* generic/tclBasic.c: TCL_NO_DEPRECATED is defined, so Tk can benefit
+	from it too.
+
+2013-01-14  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* win/tcl.m4: More flexible search for win32 tclConfig.sh, backported
+	from TEA (not actually used in Tcl, only for Tk)
+
+2013-01-14  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tclInt.decls: Put back Tcl_[GS]etStartupScript in internal
+	stub table, so extensions using this, compiled against 8.5 headers
+	still run in Tcl 8.6.
+
+2013-01-13  Alexandre Ferrieux  <ferrieux@users.sourceforge.net>
+
+	* doc/fileevent.n: [Bug 3436609]: Clarify readable fileevent "false
+	positives" in the case of multibyte encodings/transforms.
+
+2013-01-13  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tclIntDecls.h: If TCL_NO_DEPRECATED is defined, make sure
+	that TIP #139 functions all are taken from the public stub table, even
+	if the inclusion is through tclInt.h.
+
+2013-01-12  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tclInt.decls: Put back TclBackgroundException in internal
+	stub table, so extensions using this, compiled against 8.5 headers
+	still run in Tcl 8.6.
+
+2013-01-09  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* library/http/http.tcl: [Bug 3599395]: http assumes status line is a
+	proper Tcl list.
+
+2013-01-08  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* win/tclWinFile.c: [Bug 3092089]: [file normalize] can remove path
+	components.	[Bug 3587096]: win vista/7: "can't find init.tcl" when
+	called via junction without folder list access.
+
+2013-01-07  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tclOOStubLib.c: Restrict the stub library to only use
+	* generic/tclTomMathStubLib.c: Tcl_PkgRequireEx, Tcl_ResetResult and
+	Tcl_AppendResult, not any other function. This puts least restrictions
+	on eventual Tcl 9 stubs re-organization, and it works on the widest
+	range of Tcl versions.
+
+2013-01-06  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* library/http/http.tcl: Don't depend on Spencer-specific regexp
+	* tests/env.test: syntax (/u and /U) any more in unrelated places.
+	* tests/exec.test:
+	Bump http package to 2.8.6.
+
+2013-01-04  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclEnsemble.c (CompileBasicNArgCommand): Added very simple
+	compiler (which just compiles to a normal invoke of the implementation
+	command) for many ensemble subcommands where we can prove that there
+	is no way for scripts to detect the difference even through error
+	handling or [info level]/[info frame]. This improves the code produced
+	from some ensembles (e.g., [info], [string]) to the point where the
+	ensemble is now not normally seen at the bytecode level at all.
+
+2013-01-04  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclInt.h:      Insure that PURIFY builds cannot exploit the
+	* generic/tclExecute.c:  Tcl stack to hide mem defects.
+
+2013-01-03  Donal K. Fellows  <dkf@users.sf.net>
+
+	* doc/fconfigure.n, doc/CrtChannel.3: Updated to reflect the fact that
+	the minimum buffer size is one byte, not ten. Identified by Schelte
+	Bron on the Tcler's Chat.
+
+	* generic/tclExecute.c (TEBCresume:INST_INVOKE_REPLACE):
+	* generic/tclEnsemble.c (TclCompileEnsemble): Added new mechanism to
+	allow for more efficient dispatch of non-bytecode-compiled subcommands
+	of bytecode-compiled ensembles. This can provide substantial speed
+	benefits in some cases.
+
+2013-01-02  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclEnsemble.c:  Remove stray calls to Tcl_Alloc and friends:
+	* generic/tclExecute.c:   the core should only use ckalloc to allow
+	* generic/tclIORTrans.c:  MEM_DEBUG to work properly.
+	* generic/tclTomMathInterface.c:
+
+2012-12-31  Donal K. Fellows  <dkf@users.sf.net>
+
+	* doc/string.n: Noted the obsolescence of the 'bytelength',
+	'wordstart' and 'wordend' subcommands, and moved them to later in the
+	file.
+
+2012-12-27  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tclListObj.c: [Bug 3598580]: Tcl_ListObjReplace may release
+	deleted elements too early.
+
+2012-12-22  Alexandre Ferrieux  <ferrieux@users.sourceforge.net>
+
+	* generic/tclUtil.c: [Bug 3598150]: Stop leaking allocated space when
+	objifying a zero-length DString. Spotted by afredd.
+
+2012-12-21  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* unix/dltest/pkgb.c:  Inline compat Tcl_GetDefaultEncodingDir.
+	* generic/tclStubLib.c: Eliminate unnecessary static HasStubSupport()
+	and isDigit() functions, just do the same inline.
+
+2012-12-18  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclCompCmdsSZ.c (TclSubstCompile): Improved the sequence of
+	instructions issued for [subst] when dealing with simple variable
+	references.
+
+2012-12-14  Don Porter  <dgp@users.sourceforge.net>
+
+	*** 8.6.0 TAGGED FOR RELEASE ***
+
+	* changes: updates for 8.6.0
+
+2012-12-13  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclZlib.c:	Repair same issue with misusing the
+	* tests/zlib.test:	'fire and forget' nature of Tcl_ObjSetVar2
+	in the new TIP 400 implementation.
+
+2012-12-13  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclCmdAH.c:	(CatchObjCmdCallback): do not decrRefCount
+	* tests/cmdAH.test:	the newValuePtr sent to Tcl_ObjSetVar2:
+	TOSV2 is 'fire and forget', it decrs on its own.
+	Fix for [Bug 3595576], found by andrewsh.
+
+2012-12-13  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tcl.h: Fix Tcl_DecrRefCount macro such that it doesn't
+	access its objPtr parameter twice any more.
+
+2012-12-11  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tcl.h:	Bump version number to 8.6.0.
+	* library/init.tcl:
+	* unix/configure.in:
+	* win/configure.in:
+	* unix/tcl.spec:
+	* README:
+
+	* unix/configure:	autoconf-2.59
+	* win/configure:
+
+2012-12-10  Donal K. Fellows  <dkf@users.sf.net>
+
+	* tools/tcltk-man2html.tcl (plus-pkgs): Increased robustness of
+	version number detection code to deal with packages whose names are
+	prefixes of other packages.
+	* unix/Makefile.in (dist): Added pkgs/package.list.txt to distribution
+	builds to ensure that 'make html' will work better.
+
+2012-12-09  Alexandre Ferrieux  <ferrieux@users.sourceforge.net>
+
+	* tests/chan.test: Clean up unwanted eofchar side-effect of chan-4.6
+	leading to a spurious "'" at end of chan.test under certain conditions
+	(see [Bug 3389289] and [Bug 3389251]).
+
+	* doc/expr.n: [Bug 3594188]: Clarifications about commas.
+
+2012-12-08  Alexandre Ferrieux  <ferrieux@users.sourceforge.net>
+
+	* generic/tclIO.c: Fix busyloop at exit under TCL_FINALIZE_ON_EXIT
+	when there are unflushed nonblocking channels.  Thanks Miguel for
+	spotting.
+
+2012-12-07  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* unix/dltest/pkgb.c:  Turn pkgb.so into a Tcl9 interoperability test
+        library: Whatever Tcl9 looks like, loading pkgb.so in Tcl 9 should
+        either result in an error-message, either succeed, but never crash.
+
+2012-11-28  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclZlib.c (ZlibStreamSubcmd): [Bug 3590483]: Use a mechanism
+	for complex option resolution that has fewer problems with more
+	finicky compilers.
+
+2012-11-26  Reinhard Max  <max@suse.de>
+
+	* unix/tclUnixSock.c: Factor out creation of the -sockname and
+	-peername lists from TcpGetOptionProc() to TcpHostPortList().  Make it
+	robust against implementations of getnameinfo() that error out if
+	reverse mapping fails instead of falling back to the numeric
+	representation.
+
+2012-11-20  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclBinary.c (BinaryDecode64): [Bug 3033307]: Corrected
+	handling of trailing whitespace when decoding base64. Thanks to Anton
+	Kovalenko for reporting, and Andy Goth for the fix and tests.
+
+2012-11-19  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclExecute.c (INST_STR_RANGE_IMM): [Bug 3588366]: Corrected
+	implementation of bounds restriction for end-indexed compiled [string
+	range]. Thanks to Emiliano Gavilan for diagnosis and fix.
+
+2012-11-15  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	IMPLEMENTATION OF TIP#416
+
+	New Options for 'load': -global and -lazy
+
+	* generic/tcl.h:
+	* generic/tclLoad.c
+	* unix/tclLoadDl.c
+	* unix/tclLoadDyld.c
+	* tests/load.test
+	* doc/Load.3
+	* doc/load.n
+
+2012-11-14  Donal K. Fellows  <dkf@users.sf.net>
+
+	* unix/tclUnixFCmd.c (TclUnixOpenTemporaryFile): [Bug 2933003]: Factor
+	out all the code to do temporary file creation so that it is possible
+	to make it correct in one place. Allow overriding of the back-stop
+	default temporary file location at compile time by setting the
+	TCL_TEMPORARY_FILE_DIRECTORY #def to a string containing the directory
+	name (defaults to "/tmp" as that is the most common default).
+
+2012-11-13  Joe Mistachkin  <joe@mistachkin.com>
+
+	* win/tclWinInit.c: also search for the library directory (init.tcl,
+	encodings, etc) relative to the build directory associated with the
+	source checkout.
+
+2012-11-10  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclBasic.c:   re-enable bcc-tailcall, after fixing an
+	* generic/tclExecute.c: infinite loop in the TCL_COMPILE_DEBUG mode
+
+
+2012-11-07  Kevin B. Kenny  <kennykb@acm.org>
+
+	* library/tzdata/Africa/Casablanca:
+	* library/tzdata/America/Araguaina:
+	* library/tzdata/America/Bahia:
+	* library/tzdata/America/Havana:
+	* library/tzdata/Asia/Amman:
+	* library/tzdata/Asia/Gaza:
+	* library/tzdata/Asia/Hebron:
+	* library/tzdata/Asia/Jerusalem:
+	* library/tzdata/Pacific/Apia:
+	* library/tzdata/Pacific/Fakaofo:
+	* library/tzdata/Pacific/Fiji:		Import tzdata2012i.
+
+2012-11-06  Donal K. Fellows  <dkf@users.sf.net>
+
+	* library/http/http.tcl (http::Finish): [Bug 3581754]: Ensure that
+	callbacks are done at most once to prevent problems with timeouts on a
+	keep-alive connection (combined with reentrant http package use)
+	causing excessive stack growth. Not a fix for the underlying problem,
+	but ensures that pain will be mostly kept away from users.
+	Bump http package to 2.8.5.
+
+2012-11-05  Donal K. Fellows  <dkf@users.sf.net>
+
+	Added bytecode compilation of many Tcl commands. Some of these are
+	total compilations and some are only partial (i.e., only compile in
+	some cases). The (sub-)commands affected are:
+	* array: exists, set, unset
+	* dict: create, exists, merge
+	* format: (simple cases only)
+	* info: commands, coroutine, level, object
+	* info object: class, isa object, namespace
+	* namespace: current, code, qualifiers, tail, which
+	* regsub: (only cases convertable to simple [string map])
+	* self: (only no-argument and [self object] cases)
+	* string: first, last, map, range
+	* tailcall:
+	* yield:
+
+	[This was work originally done on the 'dkf-compile-misc-info' branch.]
+
+2012-11-05  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	IMPLEMENTATION OF TIP#413
+
+	Align the [string trim] and [string is space] commands, such that
+	[string trim] by default trims all characters for which [string is
+	space] returns 1, augmented with the NUL character.
+
+	* generic/tclUtf.c: Add NEL, BOM and two more characters to [string is
+	space]
+	* generic/tclCmdMZ.c: Modify [string trim] for Unicode modifications.
+	* generic/regc_locale.c: Regexp engine must match [string is space]
+	* doc/string.n
+	* tests/string.test
+	***POTENTIAL INCOMPATIBILITY***
+	Code that relied on characters not previously trimmed being not
+	removed will notice a difference; it is believed that this is rare,
+	but a workaround to get the behavior in Tcl 8.5 is to use " \t\n\r" as
+	an explicit trim set.
+
+2012-10-31  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* win/Makefile.in:   Dde version number to 1.4.0, ready for Tcl 8.6.0rc1
+	* win/makefile.vc
+	* win/tclWinDde.c
+	* library/dde/pkgIndex.tcl
+	* tests/winDde.test
+
+2012-10-24  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclCompCmds.c (TclCompileDictUnsetCmd): Added compilation of
+	the [dict unset] command (for scalar var in LVT only).
+
+2012-10-23  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tclInt.h:       Add "flags" parameter from Tcl_LoadFile to
+	* generic/tclIOUtil.c:    to various internal functions, so these
+	* generic/tclLoadNone.c:  flags are available through the whole
+	* unix/tclLoad*.c:        filesystem for (future) internal use.
+	* win/tclWinLoad.c:
+
+2012-10-17  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclBasic.c (TclNRCoroutineObjCmd): insure that numlevels
+	are properly set, fix bug discovered by dkf and reported at
+	http://code.activestate.com/lists/tcl-core/12213/
+
+2012-10-16  Donal K. Fellows  <dkf@users.sf.net>
+
+	IMPLEMENTATION OF TIP#405
+
+	New commands for applying a transformation to the elements of a list
+	to produce another list (the [lmap] command) and to the mappings of a
+	dictionary to produce another dictionary (the [dict map] command). In
+	both cases, a [continue] will cause the skipping of an element/pair,
+	and a [break] will terminate the construction early and successfully.
+
+	* generic/tclCmdAH.c (Tcl_LmapObjCmd, TclNRLmapCmd): Implementation of
+	the new [lmap] command, based on (and sharing much of) [foreach].
+	* generic/tclDictObj.c (DictMapNRCmd): Implementation of the new [dict
+	map] subcommand, based on (and sharing much of) [dict for].
+	* generic/tclCompCmds.c (TclCompileLmapCmd, TclCompileDictMapCmd):
+	Compilation engines for [lmap] and [dict map].
+
+	IMPLEMENTATION OF TIP#400
+
+	* generic/tclZlib.c: Allow the specification of a compression
+	dictionary (a binary blob used to seed the compression engine) in both
+	streams and channel transformations. Also some reorganization to allow
+	for getting gzip header dictionaries and controlling buffering levels
+	in channel transformations (allowing a trade-off between formal
+	correctness and speed).
+	(Tcl_ZlibStreamSetCompressionDictionary): New C API to allow setting
+	the compression dictionary without using a Tcl script.
+
+2012-10-14  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tclDictObj.c: [Bug 3576509]: ::tcl::Bgerror crashes with
+	* generic/tclEvent.c:    invalid arguments. Better fix, which helps
+	for all Tcl_DictObjGet() calls in Tcl's source code.
+
+2012-10-13  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tclEvent.c: [Bug 3576509]: tcl::Bgerror crashes with invalid
+	arguments
+
+2012-10-06  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* win/Makefile.in: [Bug 2459774]: tcl/win/Makefile.in not compatible
+	with msys 0.8.
+
+2012-10-03  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclIO.c:	When checking for std channels being closed,
+	compare the channel state, not the channel itself so that stacked
+	channels do not cause trouble.
+
+2012-09-26  Reinhard Max  <max@suse.de>
+
+	* generic/tclIOSock.c (TclCreateSocketAddress): Work around a bug in
+	getaddrinfo() on OSX that caused name resolution to fail for [socket
+	-server foo -myaddr localhost 0].
+
+2012-09-20  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* win/configure.in: New import libraries for zlib 1.2.7, usable for
+	* win/configure:    all win32/win64 compilers
+	* compat/zlib/win32/zdll.lib:
+	* compat/zlib/win64/zdll.lib:
+
+	* win/tclWinDde.c: [FRQ 3527238]: Full unicode support for dde. Dde
+	version is now 1.4.0b2.
+	***POTENTIAL INCOMPATIBILITY***
+
+2012-09-19  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tcl.h:  Make Tcl_Interp a fully opaque structure if
+	TCL_NO_DEPRECATED is set (TIP 330 and 336).
+	* win/nmakehlp.c: Let "nmakehlp -V" start searching digits after the
+	found match (suggested by Harald Oehlmann).
+
+2012-09-19  Harald Oehlmann  <oehhar@users.sf.net>
+
+	IMPLEMENTATION OF TIP#412.
+
+	* library/msgcat/msgcat.tcl:	dynamic locale change with mc file
+	* library/clock.tcl:            load on locale change.
+	clock uses new msgcat features.
+
+2012-09-07  Harald Oehlmann  <oehhar@users.sf.net>
+
+	*** 8.6b3 TAGGED FOR RELEASE ***
+
+	IMPLEMENTATION OF TIP#404.
+
+	* library/msgcat/msgcat.tcl:	[FRQ 3544988]: New commands [mcflset]
+	* library/msgcat/pkgIndex.tcl:	and [mcflmset] to set mc entries with
+	* unix/Makefile.in:		implicit message file locale.
+	* win/Makefile.in:		Bump to 1.5.0.
+
+2012-08-25  Donal K. Fellows  <dkf@users.sf.net>
+
+	* library/msgs/uk.msg: [Bug 3561330]: Use the correct full name of
+	March in Ukrainian. Thanks to Mikhail Teterin for reporting.
+
+2012-08-23  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tclBinary.c: [Bug 3496014]: Unecessary memset() in
+	Tcl_SetByteArrayObj().
+
+2012-08-20  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclPathObj.c:	[Bug 3559678]: Fix bad filename normalization
+	when the last component is the empty string.
+
+2012-08-20  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* win/tclWinPort.h:  Remove wrapper macro for ntohs(): unnecessary,
+	because it doesn't require an initialized winsock_2 library. See:
+	<http://msdn.microsoft.com/en-us/library/windows/desktop/ms740075%28v=vs.85%29.aspx>
+	* win/tclWinSock.c:
+	* generic/tclStubInit.c:
+
+2012-08-17  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* win/nmakehlp.c: Add "-V<num>" option, in order to be able to detect
+	partial version numbers.
+
+2012-08-15  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* win/buildall.vc.bat: Only build the threaded builds by default
+	* win/rules.vc:        Some code cleanup
+
+2010-08-13  Stuart Cassoff  <stwo@users.sourceforge.net>
+
+	* unix/tclUnixCompat.c: [Bug 3555454]: Rearrange a bit to quash
+	'declared but never defined' compiler warnings.
+
+2012-08-13  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* compat/zlib/win64/zlib1.dll:  Add 64-bit build of zlib1.dll, and use
+	* compat/zlib/win64/zdll.lib:   it for the dynamic mingw-w64 build.
+	* win/Makefile.in:
+	* win/configure.in:
+	* win/configure:
+
+2012-08-09  Reinhard Max  <max@suse.de>
+
+	* tests/http.test: Fix http-3.29 for machines without IPv6 support.
+
+2010-08-08  Stuart Cassoff  <stwo@users.sourceforge.net>
+
+	* unix/tclUnixCompat.c: Change one '#ifdef' to '#if defined()' for
+	improved consistency within the file.
+
+2012-08-08  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tclfileName.c: [Bug #1536227]: Cygwin network pathname
+	* tests/fileName.test:   support
+
+2012-08-07  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclIOUtil.c:	[Bug 3554250]: Overlooked one field of cleanup
+	in the thread exit handler for the filesystem subsystem.
+
+2012-07-31  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclInterp.c (Tcl_GetInterpPath):
+	* unix/tclUnixPipe.c (TclGetAndDetachPids, Tcl_PidObjCmd):
+	* win/tclWinPipe.c (TclGetAndDetachPids, Tcl_PidObjCmd):
+	Purge use of Tcl_AppendElement, and corrected conversion of PIDs to
+	integer objects.
+
+2012-07-31  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* win/nmakehlp.c:  Add -Q option from sampleextension.
+	* win/Makefile.in: [FRQ 3544967]: Missing objectfiles in static lib
+	* win/makefile.vc: (Thanks to Jos Decoster).
+
+2012-07-29  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* win/Makefile.in:  No longer build tcltest.exe to run the tests,
+	but use tclsh86.exe in combination with tcltest86.dll to do that.
+	* tests/*.test:     load tcltest86.dll if necessary.
+
+2012-07-28  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* tests/clock.test:    [Bug 3549770]: Multiple test failures running
+	* tests/registry.test: tcltest outside build tree
+	* tests/winDde.test:
+
+2012-07-27  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tclUniData.c:   Support Unicode 6.2 (Add Turkish lira sign)
+	* generic/regc_locale.c:
+
+2012-07-25  Alexandre Ferrieux  <ferrieux@users.sourceforge.net>
+
+	* win/tclWinPipe.c: [Bug 3547994]: Abandon the synchronous Windows
+	pipe driver to its fate when needed to honour TIP#398.
+
+2012-07-24  Trevor Davel  <twylite@crypt.co.za>
+
+	* win/tclWinSock.c: [Bug: 3545363]: Loop over multiple underlying file
+	descriptors for a socket where required (TcpCloseProc, SocketProc).
+	Refactor socket/descriptor setup to manage linked list operations in
+	one place. Fix memory leak in socket close (TcpCloseProc) and related
+	dangling pointers in SocketEventProc.
+
+2012-07-19  Reinhard Max  <max@suse.de>
+
+	* win/tclWinSock.c (TcpAccept): [Bug: 3545363]: Use a large enough
+	buffer for accept()ing IPv6 connections. Fix conversion of host and
+	port for passing to the accept proc to be independent of the IP
+	version.
+
+2012-07-23  Alexandre Ferrieux  <ferrieux@users.sourceforge.net>
+
+	* generic/tclIO.c: [Bug 3545365]: Never try a bg-flush  on a dead
+	channel, just like before 2011-08-17.
+
+2012-07-19  Joe Mistachkin  <joe@mistachkin.com>
+
+	* generic/tclTest.c: Fix several more missing mutex-locks in
+	TestasyncCmd.
+
+2012-07-19  Alexandre Ferrieux  <ferrieux@users.sourceforge.net>
+
+	* generic/tclTest.c: [Bug 3544685]: Missing mutex-lock in
+	TestasyncCmd since 2011-08-19. Unbounded gratitude to Stuart
+	Cassoff for spotting it.
+
+2012-07-17  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* win/makefile.vc: [Bug 3544932]: Visual studio compiler check fails
+
+2012-07-16  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclUtil.c (UpdateStringOfEndOffset): [Bug 3544658]: Stop
+	1-byte overrun in memcpy, that object placement rules made harmless
+	but which still caused compiler complaints.
+
+2012-07-16  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* library/reg/pkgIndex.tcl:  Make registry 1.3 package dynamically
+	loadable when ::tcl::pkgconfig is available.
+
+2012-07-11  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* win/tclWinReg.c: [Bug 3362446]: registry keys command fails
+	with 8.5/8.6. Follow Microsofts example better in order to prevent
+	problems when using HKEY_PERFORMANCE_DATA.
+
+2012-07-10  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* unix/tclUnixNotfy.c: [Bug 3541646]: Don't panic on triggerPipe
+	overrun.
+
+2012-07-10  Donal K. Fellows  <dkf@users.sf.net>
+
+	* win/tclWinSock.c (InitializeHostName): Corrected logic that
+	extracted the name of the computer from the gethostname call so that
+	it would use the name on success, not failure. Also ensured that the
+	buffer size is exactly that recommended by Microsoft.
+
+2012-07-08  Reinhard Max  <max@suse.de>
+
+	* library/http/http.tcl: [Bug 3531209]: Add fix and test for URLs that
+	* tests/http.test: 	 contain literal IPv6 addresses.
+
+2012-07-05  Don Porter  <dgp@users.sourceforge.net>
+
+	* unix/tclUnixPipe.c:	[Bug 1189293]: Make "<<" binary safe.
+	* win/tclWinPipe.c:
+
+2012-07-03  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclUtil.c (TclDStringAppendObj, TclDStringAppendDString):
+	* generic/tclInt.h (TclDStringAppendLiteral, TclDStringClear):
+	* generic/tclCompile.h (TclDStringAppendToken): Added wrappers to make
+	common cases of appending to Tcl_DStrings simpler to write. Prompted
+	by looking at [FRQ 1357401] (these are an _internal_ implementation of
+	that FRQ).
+
+2012-06-29  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* library/msgcat/msgcat.tcl:   Add tn, ro_MO and ru_MO to msgcat.
+
+2012-06-29  Harald Oehlmann <oehhar@users.sf.net>
+
+	* library/msgcat/msgcat.tcl:	[Bug 3536888]: Locale guessing of
+	* library/msgcat/pkgIndex.tcl:	msgcat fails on (some) Windows 7. Bump
+	* unix/Makefile.in:		to 1.4.5
+	* win/Makefile.in:
+
+2012-06-29  Donal K. Fellows  <dkf@users.sf.net>
+
+	* doc/GetIndex.3: Reinforced the description of the requirement for
+	the tables of names to index over to be static, following posting to
+	tcl-core by Brian Griffin about a bug caused by Tktreectrl not obeying
+	this rule correctly. This does not represent a functionality change,
+	merely a clearer documentation of a long-standing constraint.
+
+2012-06-26  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* unix/tcl.m4:       Let Cygwin shared build link with
+	* unix/configure.in: zlib1.dll, not cygz.dll (two less
+	* unix/configure:    dependencies on cygwin-specific dll's)
+	* unix/Makefile.in:
+
+2012-06-26  Reinhard Max  <max@suse.de>
+
+	* generic/tclIOSock.c: Use EAI_SYSTEM only if it exists.
+	* unix/tclUnixSock.c:
+
+2012-06-25  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclFileSystem.h:	[Bug 3024359]: Make sure that the
+	* generic/tclIOUtil.c:	per-thread cache of the list of file systems
+	* generic/tclPathObj.c:	currently registered is only updated at times
+	when no active loops are traversing it.  Also reduce the amount of
+	epoch storing and checking to where it can make a difference.
+
+2012-06-25  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclCmdAH.c (EncodingDirsObjCmd): [Bug 3537605]: Do the right
+	thing when reporting errors with the number of arguments.
+
+2012-06-25  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tclfileName.c: [Patch 1536227]: Cygwin network pathname
+	* tests/fileName.test:   support.
+
+2012-06-23  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* unix/tclUnixNotfy.c: [Bug 3508771]: Cygwin notifier for handling
+	win32 events.
+
+2012-06-22  Reinhard Max  <max@suse.de>
+
+	* generic/tclIOSock.c: Rework the error message generation of [socket],
+	* unix/tclUnixSock.c:  so that the error code of getaddrinfo is used
+	* win/tclWinSock.c:    instead of errno unless it is EAI_SYSTEM.
+
+2012-06-21  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* win/tclWinReg.c:	[Bug 3362446]: registry keys command fails
+	* tests/registry.test:	with 8.5/8.6
+
+2012-06-11  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclBasic.c:	[Bug 3532959]: Make sure the lifetime
+	* generic/tclProc.c:	management of entries in the linePBodyPtr
+	* tests/proc.test:	hash table can tolerate either order of
+	teardown, interp first, or Proc first.
+
+2012-06-08  Don Porter  <dgp@users.sourceforge.net>
+
+	* unix/configure.in:	Update autogoo for gettimeofday().
+	* unix/tclUnixPort.h:	Thanks Joe English.
+	* unix/configure:	autoconf 2.13
+
+	* unix/tclUnixPort.h:	[Bug 3530533]: Centralize #include <pthread.h>
+	* unix/tclUnixThrd.c:	in the tclUnixPort.h header so that old unix
+	systems that need inclusion in all compilation units are supported.
+
+2012-06-08  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* win/tclWinDde.c:    Revise the "null data" check: null strings are
+	possible, but empty binary arrays are not.
+	* tests/winDde.test:  Add test-case (winDde-9.4) for transferring
+	null-strings with dde. Convert tests to tcltest-2 syntax.
+
+2012-06-06  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclZlib.c (TclZlibInit): Declare that Tcl is publishing the
+	zlib package (version 2.0) as part of its bootstrap process. This will
+	have an impact on tclkit (which includes zlib 1.1) but otherwise be
+	very low impact.
+
+2012-06-06  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* unix/tclUnixInit.c: On Cygwin, use win32 API in stead of uname()
+	to determine the tcl_platform variables.
+
+2012-05-31  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tclZlib.c:  [Bug 3530536]: zlib-7.4 fails on IRIX64
+	* tests/zlib.test:
+	* doc/zlib.n:         Document that [stream checksum] doesn't do
+	what's expected for "inflate" and "deflate" formats
+
+2012-05-31  Donal K. Fellows  <dkf@users.sf.net>
+
+	* library/safe.tcl (safe::AliasFileSubcommand): Don't assume that
+	slaves have corresponding commands, as that is not true for
+	sub-subinterpreters (used in Tk's test suite).
+
+	* doc/safe.n: [Bug 1997845]: Corrected formatting so that generated
+	HTML can link properly.
+
+	* tests/socket.test (socket*-13.1): Prevented intermittent test
+	failure due to race condition.
+
+2012-05-29  Donal K. Fellows  <dkf@users.sf.net>
+
+	* doc/expr.n, doc/mathop.n: [Bug 2931407]: Clarified semantics of
+	division and remainder operators.
+
+2012-05-29  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* win/tclWinDde.c:    [Bug 3525762]: Encoding handling in dde.
+	* win/Makefile.in:    Fix "make genstubs" when cross-compiling on UNIX
+
+2012-05-28  Donal K. Fellows  <dkf@users.sf.net>
+
+	* library/safe.tcl (safe::AliasFileSubcommand): [Bug 3529949]: Made a
+	more sophisticated method for preventing information leakage; it
+	changes references to "~user" into "./~user", which is safe.
+
+2012-05-25  Donal K. Fellows  <dkf@users.sf.net>
+
+	* doc/namespace.n, doc/Ensemble.3: [Bug 3528418]: Document what is
+	going on with respect to qualification of command prefixes in ensemble
+	subcommand maps.
+
+	* generic/tclIO.h (SYNTHETIC_EVENT_TIME): Factored out the definition
+	of the amount of time that should be waited before firing a synthetic
+	event on a channel.
+
+2012-05-25  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* win/tclWinDde.c: [Bug 473946]: Special characters were not correctly
+	sent, now for XTYP_EXECUTE as well as XTYP_REQUEST.
+	* win/Makefile.in: Fix "make genstubs" when cross-compiling on UNIX
+
+2012-05-24  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* tools/genStubs.tcl:  Take cygwin handling of X11 into account.
+	* generic/tcl*Decls.h: re-generated
+	* generic/tclStubInit.c:  Implement TclpIsAtty, Cygwin only.
+	* doc/dde.n: Doc fix: "dde execute iexplore" doesn't work
+	without -async, because iexplore doesn't return a value
+
+2012-05-24  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* tools/genStubs.tcl:   Let cygwin share stub table with win32
+	* win/tclWinSock.c:     implement TclpInetNtoa for win32
+	* generic/tclInt.decls: Revert most of [3caedf05df], since when
+	  we let cygwin share the win32 stub table this is no longer necessary
+	* generic/tcl*Decls.h:  re-generated
+	* doc/dde.n:            1.3 -> 1.4
+
+2012-05-23  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclZlib.c (ZlibTransformInput): [Bug 3525907]: Ensure that
+	decompressed input is flushed through the transform correctly when the
+	input stream gets to the end. Thanks to Alexandre Ferrieux and Andreas
+	Kupries for their work on this.
+
+2012-05-21  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclFileName.c:	When using Tcl_SetObjLength() calls to
+	* generic/tclPathObj.c:		grow and shrink the objPtr->bytes
+	buffer, care must be taken that the value cannot possibly become pure
+	Unicode.  Calling Tcl_AppendToObj() has the possibility of making such
+	a conversion.  Bug found while valgrinding the trunk.
+
+2012-05-21  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	IMPLEMENTATION OF TIP#106
+
+	* win/tclWinDde.c:		Added encoding-related abilities to
+	* library/dde/pkgIndex.tcl:	the [dde] command. The dde package's
+	* tests/winDde.test:		version is now 1.4.0.
+	* doc/dde.n:
+
+2012-05-20  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclOOBasic.c (TclOO_Class_Constructor): [Bug 2023112]: Cut
+	the amount of hackiness in class constructors, and refactor some of
+	the error message handling from [oo::define] to be saner in the face
+	of odd happenings.
+
+2012-05-17  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclCmdMZ.c (Tcl_SwitchObjCmd): [Bug 3106532]: Corrected
+	resulting indexes from -indexvar option to be usable with [string
+	range]; this was always the intention (and is consistent with [regexp
+	-indices] too).
+	***POTENTIAL INCOMPATIBILITY***
+	Uses of [switch -regexp -indexvar] that previously compensated for the
+	wrong offsets (by subtracting 1 from the end indices) now do not need
+	to do so as the value is correct.
+
+	* library/safe.tcl (safe::InterpInit): Ensure that the module path is
+	constructed in the correct order.
+	(safe::AliasGlob): [Bug 2964715]: More extensive handling of what
+	globbing is required to support package loading.
+
+	* doc/expr.n: [Bug 3525462]: Corrected statement about what happens
+	when comparing "0y" and "0x12"; the previously documented behavior was
+	actually a subtle bug (now long-corrected).
+
+2012-05-16  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclCmdAH.c (TclMakeFileCommandSafe): [Bug 3445787]: Improve
+	the compatibility of safe interpreters' version of 'file' with that of
+	unsafe interpreters.
+	* library/safe.tcl (::safe::InterpInit): Teach the safe-interp scripts
+	about how to expose 'file' properly.
+
+2012-05-13  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* win/tclWinDde.c:   Protect against receiving strings without ending
+	\0, as external applications (or Tcl with TIP #106) could generate
+	that.
+
+2012-05-10  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* win/tclWinDde.c: [Bug 473946]: Special characters not correctly sent
+	* library/dde/pkgIndex.tcl:  Increase version to 1.3.3
+
+2012-05-10  Alexandre Ferrieux  <ferrieux@users.sourceforge.net>
+
+	* {win,unix}/configure{,.in}: [Bug 2812981]: Clean up bundled
+	packages' build directory from within Tcl's ./configure, to avoid
+	stale configuration.
+
+2012-05-09  Andreas Kupries  <andreask@activestate.com>
+
+	* generic/tclIORChan.c: [Bug 3522560]: Fixed the crash, enabled the
+	test case. Modified [chan postevent] to properly inject the event(s)
+	into the owner thread's event queue for execution in the correct
+	context. Renamed the ForwardOpTo...Thread() function to match with our
+	terminology.
+
+	* tests/ioCmd.test: [Bug 3522560]: Added a test which crashes the core
+	if it were not disabled as knownBug. For a reflected channel
+	transfered to a different thread the [chan postevent] run in the
+	handler thread tries to execute the owner threads's fileevent scripts
+	by itself, wrongly reaching across thread boundaries.
+
+2012-04-28  Alexandre Ferrieux  <ferrieux@users.sourceforge.net>
+
+	* generic/tclIO.c: Properly close nonblocking channels even when
+	not flushing them.
+
+2012-05-03  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* compat/zlib/*: Upgrade to zlib 1.2.7 (pre-built dll is still 1.2.5,
+	will be upgraded as soon as the official build is available)
+
+2012-05-03  Don Porter  <dgp@users.sourceforge.net>
+
+	* tests/socket.test:	[Bug 3428754]: Test socket-14.2 tolerate
+	[socket -async] connection that connects synchronously.
+
+	* unix/tclUnixSock.c:	[Bug 3428753]: Fix [socket -async] connections
+	that manage to connect synchronously.
+
+2012-05-02  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/configure.in:    Better detection and implementation for
+	* generic/configure:       cpuid instruction on Intel-derived
+	* generic/tclUnixCompat.c: processors, both 32-bit and 64-bit.
+	* generic/tclTest.c:       Move cpuid testcase from win-specific to
+	* win/tclWinTest.c:        generic tests, as it should work on all
+	* tests/platform.test:     Intel-related platforms now.
+
+2012-04-30  Alexandre Ferrieux  <ferrieux@users.sourceforge.net>
+
+	* tests/ioCmd.test: [Bug 3522560]: Tame deadlocks in broken refchan
+	tests.
+
+2012-04-28  Alexandre Ferrieux  <ferrieux@users.sourceforge.net>
+
+	IMPLEMENTATION OF TIP#398
+
+	* generic/tclIO.c: Quickly Exit with Non-Blocking Blocked Channels
+	* tests/io.test  : *** POTENTIAL INCOMPATIBILITY ***
+	* doc/close.n    : (compat flag available)
+
+2012-04-27  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tclPort.h:    Move CYGWIN-specific stuff from tclPort.h to
+	* generic/tclEnv.c:     tclUnixPort.h, where it belongs.
+	* unix/tclUnixPort.h:
+	* unix/tclUnixFile.c:
+
+2012-04-27  Donal K. Fellows  <dkf@users.sf.net>
+
+	* library/init.tcl (auto_execok): Allow shell builtins to be detected
+	even if they are upper-cased.
+
+2012-04-26  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tclStubInit.c:    Get rid of _ANSI_ARGS_ and CONST
+	* generic/tclIO.c:
+	* generic/tclIOCmd.c:
+	* generic/tclTest.c:
+	* unix/tclUnixChan.c:
+
+2012-04-25  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclUtil.c (TclDStringToObj): Added internal function to make
+	the fairly-common operation of converting a DString into an Obj a more
+	efficient one; for long strings, it can just transfer the ownership of
+	the buffer directly. Replaces this:
+	   obj=Tcl_NewStringObj(Tcl_DStringValue(&ds),Tcl_DStringLength(&ds));
+	   Tcl_DStringFree(&ds);
+	with this:
+	   obj=TclDStringToObj(&ds);
+
+2012-04-24  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tclInt.decls:      [Bug 3508771]: load tclreg.dll in cygwin
+				     tclsh
+	* generic/tclIntPlatDecls.h: Implement TclWinGetSockOpt,
+	* generic/tclStubInit.c:     TclWinGetServByName and TclWinCPUID for
+	* generic/tclUnixCompat.c:   Cygwin.
+	* unix/configure.in:
+	* unix/configure:
+	* unix/tclUnixCompat.c:
+
+2012-04-18  Kevin B. Kenny  <kennykb@acm.org>
+
+	* library/tzdata/Africa/Casablanca:
+	* library/tzdata/America/Port-au-Prince:
+	* library/tzdata/Asia/Damascus:
+	* library/tzdata/Asia/Gaza:
+	* library/tzdata/Asia/Hebron: tzdata2012c
+
+2012-04-16  Donal K. Fellows  <dkf@users.sf.net>
+
+	* doc/FileSystem.3 (Tcl_FSOpenFileChannelProc): [Bug 3518244]: Fixed
+	documentation of this filesystem callback function; it must not
+	register its created channel - that's the responsibility of the caller
+	of Tcl_FSOpenFileChannel - as that leads to reference leaks.
+
+2012-04-15  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclEnsemble.c (NsEnsembleImplementationCmdNR):
+	* generic/tclIOUtil.c (Tcl_FSEvalFileEx): Cut out levels of the C
+	stack by going direct to the relevant internal evaluation function.
+
+	* generic/tclZlib.c (ZlibTransformSetOption): [Bug 3517696]: Make
+	flushing work correctly in a pushed compressing channel transform.
+
+2012-04-12  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tclInt.decls:      [Bug 3514475]: Remove TclpGetTimeZone and
+	* generic/tclIntDecls.h:     TclpGetTZName
+	* generic/tclIntPlatDecls.h:
+	* generic/tclStubInit.c:
+	* unix/tclUnixTime.c:
+	* unix/tclWinTilemc:
+
+2012-04-11  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* win/tclWinInit.c:     [Bug 3448512]: clock scan "1958-01-01" fails
+	* win/tcl.m4:           only in debug compilation.
+	* win/configure:
+	* unix/tcl.m4:          Use NDEBUG consistantly meaning: no debugging.
+	* unix/configure:
+	* generic/tclBasic.c:
+	* library/dde/pkgIndex.tcl:  Use [::tcl::pkgconfig get debug] instead
+	* library/reg/pkgIndex.tcl:  of [info exists ::tcl_platform(debug)]
+
+2012-04-10  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tcl.h (TCL_DEPRECATED_API): [Bug 2458976]: Added macro that
+	can be used to mark parts of Tcl's API as deprecated. Currently only
+	used for fields of Tcl_Interp, which TIPs 330 and 336 have deprecated
+	with a migration strategy; we want to encourage people to move away
+	from those fields.
+
+2012-04-09  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclOODefineCmds.c (ClassVarsSet, ObjVarsSet): [Bug 3396896]:
+	Ensure that the lists of variable names used to drive variable
+	resolution will never have the same name twice.
+
+	* generic/tclVar.c (AppendLocals): [Bug 2712377]: Fix problem with
+	reporting of declared variables in methods. It's really a problem with
+	how [info vars] interacts with variable resolvers; this is just a bit
+	of a hack so it is no longer a big problem.
+
+2012-04-04  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclOO.c (Tcl_NewObjectInstance, TclNRNewObjectInstance):
+	[Bug 3514761]: Fixed bogosity with automated argument description
+	handling when constructing an instance of a class that is itself a
+	member of an ensemble. Thanks to Andreas Kupries for identifying that
+	this was a problem case at all!
+	(Tcl_CopyObjectInstance): Fix potential bleed-over of ensemble
+	information into [oo::copy].
+
+2012-04-04  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* win/tclWinSock.c:	[Bug 510001]: TclSockMinimumBuffers needs
+	* generic/tclIOSock.c:	platform implementation.
+	* generic/tclInt.decls:
+	* generic/tclIntDecls.h:
+	* generic/tclStubInit.c:
+
+2012-04-03  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tclStubInit.c: Remove the TclpGetTZName implementation for
+	* generic/tclIntDecls.h: Cygwin (from 2012-04-02 commit), re-generated
+	* generic/tclIntPlatDecls.h:
+
+2012-04-02  Donal K. Fellows  <dkf@users.sf.net>
+
+	IMPLEMENTATION OF TIP#396.
+
+	* generic/tclBasic.c (builtInCmds, TclNRYieldToObjCmd): Convert the
+	formerly-unsupported yieldm and yieldTo commands into [yieldto].
+
+2012-04-02  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tclInt.decls: [Bug 3508771]: load tclreg.dll in cygwin tclsh
+	* generic/tclIntPlatDecls.h: Implement TclWinGetTclInstance,
+	* generic/tclStubInit.c:     TclpGetTZName, and various more
+	win32-specific internal functions for Cygwin, so win32 extensions
+	using those can be loaded in the cygwin version of tclsh.
+
+2012-03-30  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* unix/tcl.m4:        [Bug 3511806]: Compiler checks too early
+	* unix/configure.in:  This change allows to build the cygwin and
+	* unix/tclUnixPort.h: mingw32 ports of Tcl/Tk to build out-of-the-box
+	* win/tcl.m4:         using a native or cross-compiler.
+	* win/configure.in:
+	* win/tclWinPort.h:
+	* win/README          Document how to build win32 or win64 executables
+	with Linux, Cygwin or Darwin.
+
+2012-03-29  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tclCmdMZ.c (StringIsCmd): Faster mem-leak free
+	implementation of [string is entier].
+
+2012-03-27  Donal K. Fellows  <dkf@users.sf.net>
+
+	IMPLEMENTATION OF TIP#395.
+
+	* generic/tclCmdMZ.c (StringIsCmd): Implementation of the [string is
+	entier] check. Code by Jos Decoster.
+
+2012-03-27  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tcl.h:      [Bug 3508771]: Wrong Tcl_StatBuf used on MinGW.
+	* generic/tclFCmd.c:  [Bug 2015723]: Duplicate inodes from file stat
+	* generic/tclCmdAH.c: on windows (but now for cygwin as well).
+	* generic/tclOODefineCmds.c: minor gcc warning
+	* win/tclWinPort.h:   Use lower numbers, preventing integer overflow.
+	Remove the workaround for mingw-w64 [Bug 3407992]. It's long fixed.
+
+2012-03-27  Donal K. Fellows  <dkf@users.sf.net>
+
+	IMPLEMENTATION OF TIP#397.
+
+	* generic/tclOO.c (Tcl_CopyObjectInstance): [Bug 3474460]: Make the
+	target object name optional when copying classes. [RFE 3485060]: Add
+	callback method ("<cloned>") so that scripted control over copying is
+	easier.
+	***POTENTIAL INCOMPATIBILITY***
+	If you'd previously been using the "<cloned>" method name, this now
+	has a standard semantics and call interface. Only a problem if you are
+	also using [oo::copy].
+
+2012-03-26  Donal K. Fellows  <dkf@users.sf.net>
+
+	IMPLEMENTATION OF TIP#380.
+
+	* doc/define.n, doc/object.n, generic/tclOO.c, generic/tclOOBasic.c:
+	* generic/tclOOCall.c, generic/tclOODefineCmds.c, generic/tclOOInt.h:
+	* tests/oo.test: Switch definitions of lists of things in objects and
+	classes to a slot-based approach, which gives a lot more flexibility
+	and programmability at the script-level. Introduce new [::oo::Slot]
+	class which is the implementation of these things.
+
+	***POTENTIAL INCOMPATIBILITY***
+	The unknown method handler now may be asked to deal with the case
+	where no method name is provided at all. The default implementation
+	generates a compatible error message, and any override that forces the
+	presence of a first argument (i.e., a method name) will continue to
+	function as at present as well, so this is a pretty small change.
+
+	* generic/tclOOBasic.c (TclOO_Object_Destroy): Made it easier to do a
+	tailcall inside a normally-invoked destructor; prevented leakage out
+	to calling command.
+
+2012-03-25  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tclInt.decls:      [Bug 3508771]: load tclreg.dll in cygwin
+	* generic/tclIntPlatDecls.h: tclsh. Implement TclWinConvertError,
+	* generic/tclStubInit.c:     TclWinConvertWSAError, and various more
+	* unix/Makefile.in:          win32-specific internal functions for
+	* unix/tcl.m4:               Cygwin, so win32 extensions using those
+	* unix/configure:            can be loaded in the cygwin version of
+	* win/tclWinError.c:         tclsh.
+
+2012-03-23  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tclInt.decls:       Revert some cygwin-related signature
+	* generic/tclIntPlatDecls.h:  changes from [835f8e1e9d] (2010-01-22).
+	* win/tclWinError.c:          They were an attempt to make the cygwin
+	                              port compile again, but since cygwin is
+	                              based on unix this serves no purpose any
+	                              more.
+	* win/tclWinSerial.c:         Use EAGAIN in stead of EWOULDBLOCK,
+	* win/tclWinSock.c:           because in VS10+ the value of
+	                              EWOULDBLOCK is no longer the same as
+	                              EAGAIN.
+	* unix/Makefile.in:           Add tclWinError.c to the CYGWIN build.
+	* unix/tcl.m4:
+	* unix/configure:
+
+2012-03-20  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tcl.decls:         [Bug 3508771]: load tclreg.dll in cygwin
+	* generic/tclInt.decls:      tclsh. Implement TclWinGetPlatformId,
+	* generic/tclIntPlatDecls.h: Tcl_WinUtfToTChar, Tcl_WinTCharToUtf (and
+	* generic/tclPlatDecls.h:    a dummy TclWinCPUID) for Cygwin, so win32
+	* generic/tclStubInit.c:     extensions using those can be loaded in
+	* unix/tclUnixCompat.c:      the cygwin version of tclsh.
+
+2012-03-19  Venkat Iyer <venkat@comit.com>
+
+	* library/tzdata/America/Atikokan: Update to tzdata2012b.
+	* library/tzdata/America/Blanc-Sablon:
+	* library/tzdata/America/Dawson_Creek:
+	* library/tzdata/America/Edmonton:
+	* library/tzdata/America/Glace_Bay:
+	* library/tzdata/America/Goose_Bay:
+	* library/tzdata/America/Halifax:
+	* library/tzdata/America/Havana:
+	* library/tzdata/America/Moncton:
+	* library/tzdata/America/Montreal:
+	* library/tzdata/America/Nipigon:
+	* library/tzdata/America/Rainy_River:
+	* library/tzdata/America/Regina:
+	* library/tzdata/America/Santiago:
+	* library/tzdata/America/St_Johns:
+	* library/tzdata/America/Swift_Current:
+	* library/tzdata/America/Toronto:
+	* library/tzdata/America/Vancouver:
+	* library/tzdata/America/Winnipeg:
+	* library/tzdata/Antarctica/Casey:
+	* library/tzdata/Antarctica/Davis:
+	* library/tzdata/Antarctica/Palmer:
+	* library/tzdata/Asia/Yerevan:
+	* library/tzdata/Atlantic/Stanley:
+	* library/tzdata/Pacific/Easter:
+	* library/tzdata/Pacific/Fakaofo:
+	* library/tzdata/America/Creston: (new)
+
+2012-03-19  Reinhard Max  <max@suse.de>
+
+	* unix/tclUnixSock.c (Tcl_OpenTcpServer): Use the values returned
+	by getaddrinfo() for all three arguments to socket() instead of
+	only using ai_family. Try to keep the most meaningful error while
+	iterating over the result list, because using the last error can
+	be misleading.
+
+2012-03-15  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tcl.h: [Bug 3288345]: Wrong Tcl_StatBuf used on Cygwin
+	* unix/tclUnixFile.c:
+	* unix/tclUnixPort.h:
+	* win/cat.c:           Remove cygwin stuff no longer needed
+	* win/tclWinFile.c:
+	* win/tclWinPort.h:
+
+2012-03-12  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* win/tclWinFile.c: [Bug 3388350]: mingw64 compiler warnings
+
+2012-03-11  Donal K. Fellows  <dkf@users.sf.net>
+
+	* doc/*.n, doc/*.3: A number of small spelling and wording fixes.
+
+2012-03-08  Donal K. Fellows  <dkf@users.sf.net>
+
+	* doc/info.n:   Various minor fixes (prompted by Andreas Kupries
+	* doc/socket.n: detecting a spelling mistake).
+
+2012-03-07  Andreas Kupries  <andreask@activestate.com>
+
+	* library/http/http.tcl: [Bug 3498327]: Generate upper-case
+	* library/http/pkgIndex.tcl: hexadecimal output for compliance
+	* tests/http.test: with RFC 3986. Bumped version to 2.8.4.
+	* unix/Makefile.in:
+	* win/Makefile.in:
+
+2012-03-06  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* win/tclWinPort.h: Compatibility with older Visual Studio versions.
+
+2012-03-04  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tclLoad.c: Patch from the cygwin folks
+	* unix/tcl.m4:
+	* unix/configure: (re-generated)
+
+2012-03-02  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclBinary.c (Tcl_SetByteArrayObj): [Bug 3496014]: Only zero
+	out the memory block if it is not being immediately overwritten. (Our
+	caller might still overwrite, but we should at least avoid
+	known-useless work.)
+
+2012-02-29  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tclIOUtil.c:	[Bug 3466099]: BOM in Unicode
+	* generic/tclEncoding.c:
+	* tests/source.test:
+
+2012-02-23  Donal K. Fellows  <dkf@users.sf.net>
+
+	* tests/reg.test (14.21-23): Add tests relating to Bug 1115587. Actual
+	bug is characterised by test marked with 'knownBug'.
+
+2012-02-17  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tclIOUtil.c: [Bug 2233954]: AIX: compile error
+	* unix/tclUnixPort.h:
+
+2012-02-16  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclExecute.c (INST_LIST_RANGE_IMM): Enhance implementation
+	so that shortening a (not multiply-referenced) list by lopping the end
+	off with [lrange] or [lreplace] is efficient.
+
+2012-02-15  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclCompCmds.c (TclCompileLreplaceCmd): Added a compilation
+	strategy for [lreplace] that tackles the cases which are equivalent to
+	a static [lrange].
+	(TclCompileLrangeCmd): Add compiler for [lrange] with constant indices
+	so we can take advantage of existing TCL_LIST_RANGE_IMM opcode.
+	(TclCompileLindexCmd): Improve coverage of constant-index-style
+	compliation using technique developed for [lrange] above.
+
+	(TclCompileDictForCmd): [Bug 3487626]: Fix crash in compilation of
+	[dict for] when its implementation command is used directly rather
+	than through the ensemble.
+
+2012-02-09  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclStringObj.c:	Converted the memcpy() calls in append
+	operations to memmove() calls.  This adds safety in the case of
+	overlapping copies, and improves performance on some benchmarks.
+
+2012-02-06  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclEnsemble.c: [Bug 3485022]: TclCompileEnsemble() avoid
+	* tests/trace.test:	compile when exec traces set.
+
+2012-02-06  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclTrace.c:  [Bug 3484621]: Ensure that execution traces on
+	* tests/trace.test:    bytecoded commands bump the interp's compile
+	epoch.
+
+2012-02-02  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tclUniData.c: [FRQ 3464401]: Support Unicode 6.1
+	* generic/regc_locale.c:
+
+2012-02-02  Don Porter  <dgp@users.sourceforge.net>
+
+	* win/tclWinFile.c:	[Bugs 2974459,2879351,1951574,1852572,
+	1661378,1613456]: Revisions to the NativeAccess() routine that queries
+	file permissions on Windows native filesystems.  Meant to fix numerous
+	bugs where [file writable|readable|executable] "lies" about what
+	operations are possible, especially when the file resides on a Samba
+	share.
+
+2012-02-01  Donal K. Fellows  <dkf@users.sf.net>
+
+	* doc/AddErrInfo.3: [Bug 3482614]: Documentation nit.
+
+2012-01-30  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclCompCmds.c (TclCompileCatchCmd): Added a more efficient
+	bytecode generator for the case where 'catch' is used without any
+	variable arguments; don't capture the result just to discard it.
+
+2012-01-26  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclCmdAH.c:		[Bug 3479689]: New internal routine
+	* generic/tclFCmd.c:		TclJoinPath(). Refactor all the
+	* generic/tclFileName.c:	*Join*Path* routines to give them more
+	* generic/tclInt.h:		useful interfaces that are easier to
+	* generic/tclPathObj.c:		manage getting the refcounts right.
+
+2012-01-26  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclPathObj.c:	[Bug 3475569]: Add checks for unshared values
+	before calls demanding them.  [Bug 3479689]: Stop memory corruption
+	when shimmering 0-refCount value to "path" type.
+
+2012-01-25  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclOO.c (Tcl_CopyObjectInstance): [Bug 3474460]: When
+	copying an object, make sure that the configuration of the variable
+	resolver is also duplicated.
+
+2012-01-22  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* tools/uniClass.tcl:    [FRQ 3473670]: Various Unicode-related
+	* tools/uniParse.tcl:    speedups/robustness. Enhanced tools to be
+	* generic/tclUniData.c:  able to handle characters > 0xffff. Done in
+	* generic/tclUtf.c:      all branches in order to simplify merges for
+	* generic/regc_locale.c: new Unicode versions (such as 6.1)
+
+2012-01-22  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclDictObj.c (DictExistsCmd): [Bug 3475264]: Ensure that
+	errors only ever happen when insufficient arguments are supplied, and
+	not when a path doesn't exist or a dictionary is poorly formatted (the
+	two cases can't be easily distinguished).
+
+2012-01-21  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tcl.h:        [Bug 3474726]: Eliminate detection of struct
+	* generic/tclWinPort.h: _stat32i64, just use _stati64 in combination
+	* generic/tclFCmd.c:    with _USE_32BIT_TIME_T, which is the same
+	* generic/tclTest.c:    then. Only keep _stat32i64 usage for cygwin,
+	* win/configure.in:     so it will not conflict with cygwin's own
+	* win/configure:	struct stat.
+
+2012-01-21  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclCmdMZ.c:	[Bug 3475667]: Prevent buffer read overflow.
+	Thanks to "sebres" for the report and fix.
+
+2012-01-17  Donal K. Fellows  <dkf@users.sf.net>
+
+	* doc/dict.n (dict with): [Bug 3474512]: Explain better what is going
+	on when a dictionary key and the dictionary variable collide.
+
+2012-01-13  Donal K. Fellows  <dkf@users.sf.net>
+
+	* library/http/http.tcl (http::Connect): [Bug 3472316]: Ensure that we
+	only try to read the socket error exactly once.
+
+2012-01-12  Donal K. Fellows  <dkf@users.sf.net>
+
+	* doc/tclvars.n: [Bug 3466506]: Document more environment variables.
+
+2012-01-09  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tclUtf.c:      [Bug 3464428]: [string is graph \u0120] was
+	* generic/regc_locale.c: wrong. Add table for Unicode [:cntrl:] class.
+	* tools/uniClass.tcl:    Generate Unicode [:cntrl:] class table.
+	* tests/utf.test:
+
+2012-01-08  Kevin B. Kenny  <kennykb@acm.org>
+
+	* library/clock.tcl (ReadZoneinfoFile): [Bug 3470928]: Corrected a bug
+	* tests/clock.test (clock-56.4):        where loading zoneinfo would
+	fail if one timezone abbreviation was a proper tail of another, and
+	zic used the same bytes of the file to represent both of them. Added a
+	test case for the bug, using the same data that caused the observed
+	failure "in the wild."
+
+2011-12-30  Venkat Iyer <venkat@comit.com>
+
+	* library/tzdata/America/Bahia:		Update to Olson's tzdata2011n
+	* library/tzdata/America/Havana:
+	* library/tzdata/Europe/Kiev:
+	* library/tzdata/Europe/Simferopol:
+	* library/tzdata/Europe/Uzhgorod:
+	* library/tzdata/Europe/Zaporozhye:
+	* library/tzdata/Pacific/Fiji:
+
+2011-12-23  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tclUtf.c: [Bug 3464428]: [string is graph \u0120] is wrong.
+	* generic/tclUniData.c:
+	* generic/regc_locale.c:
+	* tests/utf.test:
+	* tools/uniParse.tcl:   Clean up some unused stuff, and be more robust
+	against changes in UnicodeData.txt syntax
+
+2011-12-13  Andreas Kupries  <andreask@activestate.com>
+
+	* generic/tclCompile.c (TclInitAuxDataTypeTable): Extended to register
+	the DictUpdateInfo structure as an AuxData type. For use by tbcload,
+	tclcompiler.
+
+2011-12-11  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/regc_locale.c: [Bug 3457031]: Some Unicode 6.0 chars not
+	* tests/utf.test:        in [:print:] class
+
+2011-12-07  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* tools/uniParse.tcl:    [Bug 3444754]: string tolower \u01c5 is wrong
+	* generic/tclUniData.c:
+	* tests/utf.test:
+
+2011-11-30  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* library/tcltest/tcltest.tcl: [Bug 967195]: Make tcltest work
+	when tclsh is compiled without using the setargv() function on mingw.
+
+2011-11-29  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* win/Makefile.in: don't install tommath_(super)?class.h
+	* unix/Makefile.in: don't install directories like 8.2 and 8.3
+	* generic/tclTomMath.h: [Bug 2991415]: move include tclInt.h from
+	* generic/tclTomMathInt.h: tclTomMath.h to tclTomMathInt.h
+
+2011-11-25  Donal K. Fellows  <dkf@users.sf.net>
+
+	* library/history.tcl (history): Simplify the dance of variable
+	management used when chaining to the implementation command.
+
+2011-11-22  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclExecute.c (TclCompileObj): Simplify and de-indent the
+	logic so that it is easier to comprehend.
+
+2011-11-22  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* win/tclWinPort.h: [Bug 3354324]: Windows: [file mtime] sets wrong
+	* win/tclWinFile.c: time (VS2005+ only).
+	* generic/tclTest.c:
+
+2011-11-20  Joe Mistachkin  <joe@mistachkin.com>
+
+	* tests/thread.test: Remove unnecessary [after] calls from the thread
+	tests.  Make error message matching more robust for tests that may
+	have built-in race conditions.  Test thread-7.26 must first unset all
+	thread testing related variables.  Revise results of the thread-7.28
+	through thread-7.31 tests to account for the fact they are canceled
+	via a script sent to the thread asynchronously, which then impacts the
+	error message handling.  Attempt to manually drain the event queue for
+	the main thread after joining the test thread to make sure no stray
+	events are processed at the wrong time on the main thread.  Revise all
+	the synchronization and comparison semantics related to the thread id
+	and error message.
+
+2011-11-18  Joe Mistachkin  <joe@mistachkin.com>
+
+	* tests/thread.test: Remove all use of thread::release from the thread
+	7.x tests, replacing it with a script that can easily cause "stuck"
+	threads to self-destruct for those test cases that require it.  Also,
+	make the error message handling far more robust by keeping track of
+	every asynchronous error.
+
+2011-11-17  Joe Mistachkin  <joe@mistachkin.com>
+
+	* tests/thread.test: Refactor all the remaining thread-7.x tests that
+	were using [testthread].  Note that this test file now requires the
+	very latest version of the Thread package to pass all tests.  In
+	addition, the thread-7.18 and thread-7.19 tests have been flagged as
+	knownBug because they cannot pass without modifications to the [expr]
+	command, persuant to TIP #392.
+
+2011-11-17  Joe Mistachkin  <joe@mistachkin.com>
+
+	* generic/tclThreadTest.c: For [testthread cancel], avoid creating a
+	new Tcl_Obj when the default script cancellation result is desired.
+
+2011-11-11  Donal K. Fellows  <dkf@users.sf.net>
+
+	* win/tclWinConsole.c: Refactor common thread handling patterns.
+
+2011-11-11  Alexandre Ferrieux  <ferrieux@users.sourceforge.net>
+
+	* tests/zlib.test: [Bug 3428756]: Use nonblocking writes in
+	single-threaded IO tests to avoid deadlocks when going beyond OS
+	buffers.  Tidy up [chan configure] flags across zlib.test.
+
+2011-11-03  Donal K. Fellows  <dkf@users.sf.net>
+
+	* unix/tclUnixCompat.c (TclpGetPwNam, TclpGetPwUid, TclpGetGrNam)
+	(TclpGetGrGid): Use the elaborate memory management scheme outlined on
+	http://www.opengroup.org/austin/docs/austin_328.txt to handle Tcl's
+	use of standard reentrant versions of the passwd/group access
+	functions so that everything can work on all BSDs. Problem identified
+	by Stuart Cassoff.
+
+2011-10-20  Don Porter  <dgp@users.sourceforge.net>
+
+	* library/http/http.tcl:        Bump to version 2.8.3
+	* library/http/pkgIndex.tcl:
+	* unix/Makefile.in:
+	* win/Makefile.in:
+
+	* changes:	Updates toward 8.6b3 release.
+
+2011-10-20  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclLiteral.c (TclInvalidateCmdLiteral): [Bug 3418547]:
+	Additional code for handling the invalidation of literals.
+	* generic/tclBasic.c (Tcl_CreateObjCommand, Tcl_CreateCommand)
+	(TclRenameCommand, Tcl_ExposeCommand): The four additional places that
+	need extra care when dealing with literals.
+	* generic/tclTest.c (TestInterpResolverCmd): Additional test machinery
+	for interpreter resolvers.
+
+2011-10-18  Reinhard Max  <max@suse.de>
+
+	* library/clock.tcl (::tcl::clock::GetSystemTimeZone): Cache the time
+	zone only if it was detected by one of the expensive methods.
+	Otherwise after unsetting TCL_TZ or TZ the previous value will still
+	be used.
+
+2011-10-15  Venkat Iyer <venkat@comit.com>
+
+	* library/tzdata/America/Sitka: Update to Olson's tzdata2011l
+	* library/tzdata/Pacific/Fiji:
+	* library/tzdata/Asia/Hebron: (New)
+
+2011-10-11  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* win/tclWinFile.c:    [Bug 2935503]: Incorrect mode field returned by
+	[file stat] command.
+
+2011-10-09  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclCompCmds.c (TclCompileDictWithCmd): Corrected handling of
+	qualified names, and added spacial cases for empty bodies (used when
+	[dict with] is just used for extracting variables).
+
+2011-10-07  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tcl.h:        Fix gcc warnings (discovered with latest
+	* generic/tclIORChan.c: mingw, based on gcc 4.6.1)
+	* tests/env.test:       Fix env.test, when running under wine 1.3.
+
+2011-10-06  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclDictObj.c (TclDictWithInit, TclDictWithFinish):
+	* generic/tclCompCmds.c (TclCompileDictWithCmd): Experimental
+	compilation for the [dict with] subcommand, using parts factored out
+	from the interpreted version of the command.
+
+2011-10-05  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* win/tclWinInt.h:   Remove tclWinProcs, as it is no longer
+	* win/tclWin32Dll.c: being used.
+
+2011-10-03  Venkat Iyer <venkat@comit.com>
+
+	* library/tzdata/Africa/Dar_es_Salaam: Update to Olson's tzdata2011k
+	* library/tzdata/Africa/Kampala:
+	* library/tzdata/Africa/Nairobi:
+	* library/tzdata/Asia/Gaza:
+	* library/tzdata/Europe/Kaliningrad:
+	* library/tzdata/Europe/Kiev:
+	* library/tzdata/Europe/Minsk:
+	* library/tzdata/Europe/Simferopol:
+	* library/tzdata/Europe/Uzhgorod:
+	* library/tzdata/Europe/Zaporozhye:
+	* library/tzdata/Pacific/Apia:
+
+2011-09-29  Donal K. Fellows  <dkf@users.sf.net>
+
+	* tools/tcltk-man2html.tcl, tools/tcltk-man2html-utils.tcl: More
+	refactoring so that more of the utility code is decently out of the
+	way. Adjusted the header-material generator so that version numbers
+	are only included in locations where there is room.
+
+2011-09-28  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tclOO.h:      [RFE 3010352]: make all TclOO API functions
+	* generic/tclOODecls.h: MODULE_SCOPE
+	* generic/tclOOIntDecls.h:
+
+2011-09-27  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclIndexObj.c (Tcl_ParseArgsObjv): [Bug 3413857]: Corrected
+	the memory management for the code parsing arguments when returning
+	"large" numbers of arguments. Also unbroke the TCL_ARGV_AUTO_REST
+	macro in passing.
+
+2011-09-26  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclCmdAH.c (TclMakeFileCommandSafe): [Bug 3211758]: Also
+	make the main [file] command hidden by default in safe interpreters,
+	because that's what existing code expects. This will reduce the amount
+	which the code breaks, but not necessarily eliminate it...
+
+2011-09-23  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclIORTrans.c: More revisions to get finalization of
+	ReflectedTransforms correct, including adopting a "dead" field as was
+	done in tclIORChan.c.
+
+	* tests/thread.test:	Stop using the deprecated thread management
+	commands of the tcltest package.  The test suite ought to provide
+	these tools for itself.  They do not belong in a testing harness.
+
+2011-09-22  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclCmdIL.c:	Revise [info frame] so that it stops creating
+	cycles in the iPtr->cmdFramePtr stack.
+
+2011-09-22  Donal K. Fellows  <dkf@users.sf.net>
+
+	* doc/re_syntax.n: [Bug 2903743]: Add more magic so that we can do at
+	least something sane on Solaris.
+	* tools/tcltk-man2html-utils.tcl (process-text): Teach the HTML
+	generator how to handle this magic.
+
+2011-09-21  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclThreadTest.c: Revise the thread exit handling of the
+	[testthread] command so that it properly maintains the per-process
+	data structures even when the thread exits for reasons other than the
+	[testthread exit] command.
+
+2011-09-21  Alexandre Ferrieux  <ferrieux@users.sourceforge.net>
+
+	* unix/tclIO.c: [Bug 3412487]: Now short reads are allowed in
+	synchronous fcopy, avoid mistaking them as nonblocking ones.
+
+2011-09-21  Andreas Kupries  <andreask@activestate.com>
+
+	* generic/tclIORTrans.c (ForwardOpToOwnerThread): Fixed the missing
+	initialization of the 'dsti' field. Reported by Don Porter, on chat.
+
+2011-09-20  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclIORChan.c: Re-using the "interp" field to signal a dead
+	channel (via NULL value) interfered with conditional cleanup tasks
+	testing for "the right interp". Added a new field "dead" to perform
+	the dead channel signalling task so the corrupted logic is avoided.
+
+	* generic/tclIORTrans.c: Revised ReflectClose() and
+	FreeReflectedTransform() so that we stop leaking ReflectedTransforms,
+	yet free all Tcl_Obj values in the same thread that alloced them.
+
+2011-09-19  Don Porter  <dgp@users.sourceforge.net>
+
+	* tests/ioTrans.test:	Conversion from [testthread] to Thread package
+	stops most memory leaks.
+
+	* tests/thread.test:	Plug most memory leaks in thread.test.
+	Constrain the rest to be skipped during `make valgrind'.  Tests using
+	the [testthread cancel] testing command are leaky.  Corrections wait
+	for either addition of [thread::cancel] to the Thread package, or
+	improvements to the [testthread] testing command to make leak-free
+	versions of these tests possible.
+
+	* generic/tclIORChan.c:	Plug all memory leaks in ioCmd.test exposed
+	* tests/ioCmd.test:	by `make valgrind'.
+	* unix/Makefile.in:
+
+2011-09-16  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	IMPLEMENTATION OF TIP #388
+
+	* doc/Tcl.n:
+	* doc/re_syntax.n:
+	* generic/regc_lex.c:
+	* generic/regcomp.c:
+	* generic/regcustom.h:
+	* generic/tcl.h:
+	* generic/tclParse.c:
+	* tests/reg.test:
+	* tests/utf.test:
+
+2011-09-16  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclProc.c (ProcWrongNumArgs): [Bugs 3400658,3408830]:
+	Corrected the handling of procedure error messages (found by TclOO).
+
+2011-09-16  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tcl.h:        Don't change Tcl_UniChar type when
+	* generic/regcustom.h:  TCL_UTF_MAX == 4 (not supported anyway)
+
+2011-09-16  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclProc.c (ProcWrongNumArgs): [Bugs 3400658,3408830]:
+	Ensemble-like rewriting of error messages is complex, and TclOO (in
+	combination with iTcl) hits the most tricky cases.
+
+	* library/http/http.tcl (http::geturl): [Bug 3391977]: Ensure that the
+	-headers option overrides the -type option (important because -type
+	has a default that is not always appropriate, and the header must not
+	be duplicated).
+
+2011-09-15  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclCompExpr.c: [Bug 3408408]: Partial improvement by sharing
+	as literals the computed values of constant subexpressions when we can
+	do so without incurring the cost of string rep generation.
+
+2011-09-13  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclUtil.c:	[Bug 3390638]: Workaround broken Solaris
+	Studio cc optimizer.  Thanks to Wolfgang S. Kechel.
+
+	* generic/tclDTrace.d:	[Bug 3405652]: Portability workaround for
+	broken system DTrace support.  Thanks to Dagobert Michelson.
+
+2011-09-12  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* win/tclWinPort.h: [Bug 3407070]: tclPosixStr.c won't build with
+	EOVERFLOW==E2BIG
+
+2011-09-11  Don Porter  <dgp@users.sourceforge.net>
+
+	* tests/thread.test:	Convert [testthread] use to Thread package use
+	in thread-6.1.  Eliminates a memory leak in `make valgrind`.
+
+	* tests/socket.test:	[Bug 3390699]: Convert [testthread] use to
+	Thread package use in socket_*-13.1.  Eliminates a memory leak in
+	`make valgrind`.
+
+2011-09-09  Don Porter  <dgp@users.sourceforge.net>
+
+	* tests/chanio.test:	[Bug 3389733]: Convert [testthread] use to
+	* tests/io.test:	Thread package use in *io-70.1.  Eliminates a
+	memory leak in `make valgrind`.
+
+2011-09-07  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclCompExpr.c: [Bug 3401704]: Allow function names like
+	* tests/parseExpr.test:	 influence(), nanobot(), and 99bottles() that
+	have been parsed as missing operator syntax errors before with the
+	form NUMBER + FUNCTION.
+	***POTENTIAL INCOMPATIBILITY***
+
+2011-09-06  Venkat Iyer <venkat@comit.com>
+
+	* library/tzdata/America/Goose_Bay: Update to Olson's tzdata2011i
+	* library/tzdata/America/Metlakatla:
+	* library/tzdata/America/Resolute:
+	* library/tzdata/America/St_Johns:
+	* library/tzdata/Europe/Kaliningrad:
+	* library/tzdata/Pacific/Apia:
+	* library/tzdata/Pacific/Honolulu:
+	* library/tzdata/Africa/Juba: (new)
+
+2011-09-06  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tcl.h:   [RFE 1711975]: Tcl_MainEx() (like Tk_MainEx())
+	* generic/tclDecls.h:
+	* generic/tclMain.c:
+
+2011-09-02  Don Porter  <dgp@users.sourceforge.net>
+
+	* tests/http.test:	Convert [testthread] use to Thread package use.
+	Eliminates memory leak seen in `make valgrind`.
+
+2011-09-01  Alexandre Ferrieux  <ferrieux@users.sourceforge.net>
+
+	* unix/tclUnixSock.c: [Bug 3401422]: Cache script-level changes to the
+	nonblocking flag of an async client socket in progress, and commit
+	them on completion.
+
+2011-09-01  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclStrToD.c:	[Bug 3402540]: Corrections to TclParseNumber()
+	* tests/binary.test:	to make it reject invalid Nan(Hex) strings.
+
+	* tests/scan.test:	[scan Inf %g] is portable; remove constraint.
+
+2011-08-30  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclInterp.c (SlaveCommandLimitCmd, SlaveTimeLimitCmd):
+	[Bug 3398794]: Ensure that low-level conditions in the limit API are
+	enforced at the script level through errors, not a Tcl_Panic. This
+	means that interpreters cannot read their own limits (writing already
+	did not work).
+
+2011-08-30  Reinhard Max  <max@suse.de>
+
+	* unix/tclUnixSock.c (TcpWatchProc): [Bug 3394732]: Put back the check
+	for server sockets.
+
+2011-08-29  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclIORTrans.c: Leak of ReflectedTransformMap.
+
+2011-08-27  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclStringObj.c:  [RFE 3396731]: Revise the [string reverse]
+	* tests/string.test:	implementation to operate on the representation
+	that comes in, avoid conversion to other reps.
+
+2011-08-23  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclIORChan.c:	[Bug 3396948]: Leak of ReflectedChannelMap.
+
+2011-08-19  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclIORTrans.c: [Bugs 3393279, 3393280]: ReflectClose(.) is
+	missing Tcl_EventuallyFree() calls at some of its exits.
+
+	* generic/tclIO.c: [Bugs 3394654, 3393276]: Revise FlushChannel() to
+	account for the possibility that the ChanWrite() call might recycle
+	the buffer out from under us.
+
+	* generic/tclIO.c: Preserve the chanPtr during FlushChannel so that
+	channel drivers don't yank it away before we're done with it.
+
+2011-08-19  Alexandre Ferrieux  <ferrieux@users.sourceforge.net>
+
+	* generic/tclTest.c: [Bug 2981154]: async-4.3 segfault.
+	* tests/async.test:  [Bug 1774689]: async-4.3 sometimes fails.
+
+2011-08-18  Alexandre Ferrieux  <ferrieux@users.sourceforge.net>
+
+	* generic/tclIO.c: [Bug 3096275]: Sync fcopy buffers input.
+
+2011-08-18  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tclUniData.c: [Bug 3393714]: Overflow in toupper delta
+	* tools/uniParse.tcl:
+	* tests/utf.test:
+
+2011-08-17  Alexandre Ferrieux  <ferrieux@users.sourceforge.net>
+
+	* generic/tclIO.c:  [Bug 2946474]: Consistently resume backgrounded
+	* tests/ioCmd.test: flushes+closes when exiting.
+
+2011-08-17  Alexandre Ferrieux  <ferrieux@users.sourceforge.net>
+
+	* doc/interp.n: Document TIP 378's one-way-ness.
+
+2011-08-17  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclGet.c: [Bug 3393150]: Overlooked free of intreps.
+	(It matters for bignums!)
+
+2011-08-16  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclCompile.c: [Bug 3392070]: More complete prevention of
+	Tcl_Obj reference cycles when producing an intrep of ByteCode.
+
+2011-08-16  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclListObj.c (TclLindexList, TclLsetFlat): Silence warnings
+	about (unreachable) cases of uninitialized variables.
+	* generic/tclCmdIL.c (SelectObjFromSublist): Improve the generation of
+	* generic/tclIndexObj.c (Tcl_ParseArgsObjv): messages through the use
+	* generic/tclVar.c (ArrayStartSearchCmd):    of Tcl_ObjPrintf.
+
+2011-08-15  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclBasic.c: [Bug 3390272]: Leak of [info script] value.
+
+2011-08-15  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tclPosixStr.c:    [Bug 3388350]: mingw64 compiler warnings
+	* win/tclWinPort.h:
+	* win/configure.in:
+	* win/configure:
+
+2011-08-14  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* doc/FindExec.3: [Patch 3124554]: Move WishPanic from Tk to Tcl
+	* doc/Panic.3     Added Documentation
+
+2011-08-12  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclPathObj.c:	[Bug 3389764]: Eliminate possibility that dup
+	of a "path" value can create reference cycle.
+
+2011-08-12  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclZlib.c (ZlibTransformOutput): [Bug 3390073]: Return the
+	correct length of written data for a compressing transform.
+
+2011-08-10 Alexandre Ferrieux  <ferrieux@users.sourceforge.net>
+
+	* generic/tclTestObj.c: [Bug 3386721]: Allow multiple [load]ing of the
+	Tcltest package.
+
+2011-08-09 Alexandre Ferrieux  <ferrieux@users.sourceforge.net>
+
+	* generic/tclBasic.c: [Bug 2919042]: Restore "valgrindability" of Tcl
+	* generic/tclEvent.c: that was lost by the streamlining of [exit], by
+	* generic/tclExecute.c: conditionally forcing a full Finalize:
+	* generic/tclInt.h:  use -DPURIFY or ::env(TCL_FINALIZE_ON_EXIT)
+
+2011-08-09 Alexandre Ferrieux  <ferrieux@users.sourceforge.net>
+
+	* generic/tclCompCmds.c: [Bug 3386417]: Avoid a reference loop between
+	* generic/tclInt.h:      the bytecode and its companion errostack
+	* generic/tclResult.c:   when compiling a syntax error.
+
+2011-08-09  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* win/tclWinConsole.c: [Bug 3388350]: mingw64 compiler warnings
+	* win/tclWinDde.c:
+	* win/tclWinPipe.c:
+	* win/tclWinSerial.c:
+
+2011-08-09  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tclInt.h: Change the signature of TclParseHex(), such that
+	* generic/tclParse.c: it can now parse up to 8 hex characters.
+
+2011-08-08  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclZlib.c (ZlibStreamCmd): Make the -buffersize option to
+	'$zstream add' function correctly instead of having its value just be
+	discarded unceremoniously. Also generate error codes from more of the
+	code, not just the low-level code but also the Tcl infrastructure.
+
+2011-08-07  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclOOInfo.c (InfoClassCallCmd): [Bug 3387082]: Plug memory
+	leak in call chain introspection.
+
+2011-08-06  Kevin B, Kenny  <kennykb@acm.org>
+
+	* generic/tclAssemnbly.c: [Bug 3384840]: Plug another memory leak.
+	* generic/tclStrToD.c: [Bug 3386975]: Plug another memory leak.
+
+2011-08-05  Kevin B. Kenny  <kennykb@acm.org>
+
+	* generic/tclStrToD.c: [Bug 3386975]: Plugged a memory leak in
+	double->string conversion.
+
+2011-08-05  Don Porter  <dgp@users.sourceforge.net>
+
+	*** 8.6b2 TAGGED FOR RELEASE ***
+
+	* changes:	Updates for 8.6b2 release.
+
+2011-08-05  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclAssembly.c (AssembleOneLine): Ensure that memory isn't
+	leaked when an unknown instruction is encountered. Also simplify code
+	through use of Tcl_ObjPrintf in error message generation.
+
+	* generic/tclZlib.c (ZlibTransformClose): [Bug 3386197]: Plug a memory
+	leak found by Miguel with valgrind, and ensure that the correct
+	direction's buffers are released.
+
+2011-08-04  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclVar.c (TclPtrSetVar): Fix valgrind-detected error when
+	newValuePtr is the interp's result obj.
+
+2011-08-04  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclAssembly.c (FreeAssemblyEnv): [Bug 3384840]: Plug another
+	possible memory leak due to over-complex code for freeing the table of
+	labels.
+
+2011-08-04  Reinhard Max  <max@suse.de>
+
+	* generic/tclIOSock.c (TclCreateSocketAddress): Don't bother using
+	AI_ADDRCONFIG for now, as it was causing problems in various
+	situations.
+
+2011-08-04  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclAssembly.c (AssembleOneLine, GetBooleanOperand)
+	(GetIntegerOperand, GetListIndexOperand, FindLocalVar): [Bug 3384840]:
+	A Tcl_Obj is allocated by GetNextOperand, so callers of it must not
+	hold a reference to one in the 'out' parameter when calling it. This
+	was causing a great many memory leaks.
+	* tests/assemble.test (assemble-51.*): Added group of memory leak
+	tests.
+
+2011-08-02  Don Porter  <dgp@users.sourceforge.net>
+
+	* changes:	Updates for 8.6b2 release.
+	* tools/tcltk-man2html.tcl: Variable substitution botch.
+
+2011-08-02  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclObj.c (Tcl_DbIncrRefCount, Tcl_DbDecrRefCount)
+	(Tcl_DbIsShared): [Bug 3384007]: Fix the panic messages so they share
+	what should be shared and have the right number of spaces.
+
+2011-08-01  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclProc.c (TclProcCompileProc): [Bug 3383616]: Fix for leak
+	of resolveInfo when recompiling procs. Thanks go to Gustaf Neumann for
+	detecting the bug and providing the fix.
+
+2011-08-01  Donal K. Fellows  <dkf@users.sf.net>
+
+	* doc/tclvars.n (EXAMPLES): Added some examples of how some of the
+	standard global variables can be used, following prompting by a
+	request by Robert Hicks.
+
+	* tools/tcltk-man2html.tcl (plus-pkgs): [Bug 3382474]: Added code to
+	determine the version number of contributed packages from their
+	directory names so that HTML documentation builds are less confusing.
+
+2011-07-29  Donal K. Fellows  <dkf@users.sf.net>
+
+	* tools/tcltk-man2html.tcl (ensemble_commands, remap_link_target):
+	Small enhancements to improve cross-linking with contributed packages.
+	* tools/tcltk-man2html-utils.tcl (insert-cross-references): Enhance to
+	cope with contributed packages' C API.
+
+2011-07-28  Reinhard Max  <max@suse.de>
+
+	* unix/tcl.m4 (SC_TCL_IPV6): Fix AC_DEFINE invocation for
+	NEED_FAKE_RFC2553.
+	* unix/configure:	autoconf-2.59
+
+2011-07-28  Don Porter  <dgp@users.sourceforge.net>
+
+	* changes:	Updates for 8.6b2 release.
+
+	* library/tzdata/Asia/Anadyr: Update to Olson's tzdata2011h
+	* library/tzdata/Asia/Irkutsk:
+	* library/tzdata/Asia/Kamchatka:
+	* library/tzdata/Asia/Krasnoyarsk:
+	* library/tzdata/Asia/Magadan:
+	* library/tzdata/Asia/Novokuznetsk:
+	* library/tzdata/Asia/Novosibirsk:
+	* library/tzdata/Asia/Omsk:
+	* library/tzdata/Asia/Sakhalin:
+	* library/tzdata/Asia/Vladivostok:
+	* library/tzdata/Asia/Yakutsk:
+	* library/tzdata/Asia/Yekaterinburg:
+	* library/tzdata/Europe/Kaliningrad:
+	* library/tzdata/Europe/Moscow:
+	* library/tzdata/Europe/Samara:
+	* library/tzdata/Europe/Volgograd:
+	* library/tzdata/America/Kralendijk: (new)
+	* library/tzdata/America/Lower_Princes: (new)
+
+2011-07-26  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclOO.c (initScript): Ensure that TclOO is properly found by
+	all the various package mechanisms (by adding a dummy ifneeded script)
+	and not just some of them.
+
+2011-07-21  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* win/tclWinPort.h: [Bug 3372130]: Fix hypot math function with MSVC10
+
+2011-07-19  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclUtil.c:	[Bug 3371644]: Repair failure to properly handle
+	* tests/util.test: (length == -1) scanning in TclConvertElement().
+	Thanks to Thomas Sader and Alexandre Ferrieux.
+
+2011-07-19  Donal K. Fellows  <dkf@users.sf.net>
+
+	* doc/*.3, doc/*.n: Many small fixes to documentation as part of
+	project to improve quality of generated HTML docs.
+
+	* tools/tcltk-man2html.tcl (remap_link_target): More complete set of
+	definitions of link targets, especially for major C API types.
+	* tools/tcltk-man2html-utils.tcl (output-IP-list, cross-reference):
+	Update to generation to produce proper HTML bulleted and enumerated
+	lists.
+
+2011-07-19 Alexandre Ferrieux  <ferrieux@users.sourceforge.net>
+
+	* doc/upvar.n: Undocument long gone limitation of [upvar].
+
+2011-07-18  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tcl.h:	Bump version number to 8.6b2.
+	* library/init.tcl:
+	* unix/configure.in:
+	* win/configure.in:
+	* unix/tcl.spec:
+	* tools/tcl.wse.in:
+	* README:
+
+	* unix/configure:	autoconf-2.59
+	* win/configure:
+
+2011-07-15  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclCompile.c: Avoid segfaults when RecordByteCodeStats() is
+	called in a deleted interp.
+
+	* generic/tclCompile.c: [Bug 467523, 3357771]: Prevent circular
+	references in values with ByteCode intreps.  They can lead to memory
+	leaks.
+
+2011-07-14  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclOOCall.c (TclOORenderCallChain): [Bug 3365156]: Remove
+	stray refcount bump that caused a memory leak.
+
+2011-07-12  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclUnixSock.c:  [Bug 3364777]: Stop segfault caused by
+	reading from struct after it had been freed.
+
+2011-07-11  Joe Mistachkin  <joe@mistachkin.com>
+
+	* generic/tclExecute.c: [Bug 3339502]: Correct cast for CURR_DEPTH to
+	silence compiler warning.
+
+2011-07-08  Donal K. Fellows  <dkf@users.sf.net>
+
+	* doc/http.n: [FRQ 3358415]: State what RFC defines HTTP/1.1.
+
+2011-07-07  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclBasic.c: Add missing INT2PTR
+
+2011-07-03  Donal K. Fellows  <dkf@users.sf.net>
+
+	* doc/FileSystem.3: Corrected statements about ctime field of 'struct
+	stat'; that was always the time of the last metadata change, not the
+	time of creation.
+
+2011-07-02  Kevin B. Kenny  <kennykb@acm.org>
+
+	* generic/tclStrToD.c:
+	* generic/tclTomMath.decls:
+	* generic/tclTomMathDecls.h:
+	* macosx/Tcl.xcode/project.pbxproj:
+	* macosx/Tcl.xcodeproj/project.pbxproj:
+	* tests/util.test:
+	* unix/Makefile.in:
+	* win/Makefile.in:
+	* win/Makefile.vc:
+	[Bug 3349507]: Fix a bug where bignum->double conversion is "round up"
+	and not "round to nearest" (causing expr double(1[string repeat 0 23])
+	not to be 1e+23).
+
+2011-06-28  Reinhard Max  <max@suse.de>
+
+	* unix/tclUnixSock.c (CreateClientSocket): [Bug 3325339]: Fix and
+	simplify posting of the writable fileevent at the end of an
+	asynchronous connection attempt. Improve comments for some of the
+	trickery around [socket -async].
+
+	* tests/socket.test: Adjust tests to the async code changes. Add more
+	tests for corner cases of async sockets.
+
+2011-06-22  Andreas Kupries  <andreask@activestate.com>
+
+	* library/platform/pkgIndex.tcl: Updated to platform 1.0.10. Added
+	* library/platform/platform.tcl: handling of the DEB_HOST_MULTIARCH
+	* unix/Makefile.in: location change for libc.
+	* win/Makefile.in:
+
+	* generic/tclInt.h: Fixed the inadvertently committed disabling of
+	stack checks, see my 2010-11-15 commit.
+
+2011-06-22  Reinhard Max  <max@suse.de>
+
+	Merge from rmax-ipv6-branch:
+	* unix/tclUnixSock.c: Fix [socket -async], so that all addresses
+	returned by getaddrinfo() are tried, not just the first one. This
+	requires the event loop to be running while the async connection is in
+	progress. ***POTENTIAL INCOMPATIBILITY***
+	* tests/socket.test: Add a test for the above.
+	* doc/socket: Document the fact that -async needs the event loop
+	* generic/tclIOSock.c: AI_ADDRCONFIG is broken on HP-UX
+
+2011-06-21  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclLink.c:	[Bug 3317466]: Prevent multiple links to a
+	single Tcl variable when calling Tcl_LinkVar().
+
+2011-06-13  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclStrToD.c:  [Bug 3315098]: Mem leak fix from Gustaf
+	Neumann.
+
+2011-06-08  Andreas Kupries  <andreask@activestate.com>
+
+	* generic/tclExecute.c: Reverted the fix for [Bug 3274728] committed
+	on 2011-04-06 and replaced with one which is 64bit-safe. The existing
+	fix crashed tclsh on Windows 64bit.
+
+2011-06-08  Donal K. Fellows  <dkf@users.sf.net>
+
+	* tests/fileSystem.test: Reduce the amount of use of duplication of
+	complex code to perform common tests, and convert others to do the
+	test result check directly using Tcltest's own primitives.
+
+2011-06-06  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* tests/socket.test: Add test constraint, so 6.2 and 6.3 don't fail
+	when the machine does not have support for ip6. Follow-up to checkin
+	from 2011-05-11 by rmax.
+
+2011-06-02  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclBasic.c:	Removed TclCleanupLiteralTable(), and old
+	* generic/tclInt.h:	band-aid routine put in place while a fix for
+	* generic/tclLiteral.c:	[Bug 994838] took shape.  No longer needed.
+
+2011-06-02  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclInt.h (TclInvalidateNsCmdLookup): [Bug 3185407]: Extend
+	the set of epochs that are potentially bumped when a command is
+	created, for a slight performance drop (in some circumstances) and
+	improved semantics.
+
+2011-06-01  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclBasic.c: Using the two free data elements in NRCommand to
+	store objc and objv - useful for debugging.
+
+2011-06-01  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tclUtil.c:   Fix for [Bug 3309871]: Valgrind finds: invalid
+	read in TclMaxListLength().
+
+2011-05-31  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclInt.h:	  Use a complete growth algorithm for lists so
+	* generic/tclListObj.c:	  that length limits do not overconstrain by a
+	* generic/tclStringObj.c: factor of 2.  [Bug 3293874]: Fix includes
+	* generic/tclUtil.c:	  rooting all growth routines by default on a
+	common tunable parameter TCL_MIN_GROWTH.
+
+2011-05-25  Don Porter  <dgp@users.sourceforge.net>
+
+	* library/msgcat/msgcat.tcl:	Bump to msgcat 1.4.4.
+	* library/msgcat/pkgIndex.tcl:
+	* unix/Makefile.in:
+	* win/Makefile.in:
+
+2011-05-25  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclOO.h (TCLOO_VERSION): Bump version.
+
+	IMPLEMENTATION OF TIP#381.
+
+	* doc/next.n, doc/ooInfo.n, doc/self.n, generic/tclOO.c,
+	* generic/tclOOBasic.c, generic/tclOOCall.c, generic/tclOOInfo.c,
+	* generic/tclOOInt.h, tests/oo.test, tests/ooNext2.test: Added
+	introspection of call chains ([self call], [info object call], [info
+	class call]) and ability to skip ahead in chain ([nextto]).
+
+2011-05-24  Venkat Iyer <venkat@comit.com>
+
+	* library/tzdata/Africa/Cairo: Update to Olson tzdata2011g
+
+2011-05-24  Donal K. Fellows  <dkf@users.sf.net>
+
+	* library/msgcat/msgcat.tcl (msgcat::mcset, msgcat::mcmset): Remove
+	some useless code; [dict set] builds dictionary levels for us.
+
+2011-05-17  Andreas Kupries  <andreask@activestate.com>
+
+	* generic/tclCompile.c (TclFixupForwardJump): Tracked down and fixed
+	* generic/tclBasic.c (TclArgumentBCEnter): the cause of a violation of
+	my assertion that 'ePtr->nline == objc' in TclArgumentBCEnter.  When a
+	bytecode was grown during jump fixup the pc -> command line mapping
+	was not updated. When things aligned just wrong the mapping would
+	direct command A to the data for command B, with a different number of
+	arguments.
+
+2011-05-11  Reinhard Max  <max@suse.de>
+
+	* unix/tclUnixSock.c (TcpWatchProc): No need to check for server
+	sockets here, as the generic server code already takes care of that.
+	* tests/socket.test (accept): Add tests to make sure that this remains
+	so.
+
+2011-05-10  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclInt.h:     New internal routines TclScanElement() and
+	* generic/tclUtil.c:    TclConvertElement() are rewritten guts of
+	machinery to produce string rep of lists.  The new routines avoid and
+	correct [Bug 3173086].  See comments for much more detail.
+
+	* generic/tclDictObj.c:         Update all callers.
+	* generic/tclIndexObj.c:
+	* generic/tclListObj.c:
+	* generic/tclUtil.c:
+	* tests/list.test:
+
+2011-05-09  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclNamesp.c (NamespacePathCmd): Convert to use Tcl_Obj API
+	* generic/tclPkg.c (Tcl_PackageObjCmd):   for result generation in
+	* generic/tclTimer.c (Tcl_AfterObjCmd):   [after info], [namespace
+	path] and [package versions].
+
+2011-05-09  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclListObj.c:	Revise empty string tests so that we avoid
+	potentially expensive string rep generations, especially for dicts.
+
+2011-05-07  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclLoad.c (TclGetLoadedPackages): Convert to use Tcl_Obj API
+	for result generation.
+
+2011-05-07  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclInt.h: Fix USE_TCLALLOC so that it can be enabled without
+	* unix/Makefile.in: editing the Makefile.
+
+2011-05-05  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclListObj.c:	Stop generating string rep of dict when
+	converting to list.  Tolerate NULL interps more completely.
+
+2011-05-03  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclUtil.c:	Tighten Tcl_SplitList().
+	* generic/tclListObj.c:	Tighten SetListFromAny().
+	* generic/tclDictObj.c:	Tighten SetDictFromAny().
+	* tests/join.test:
+	* tests/mathop.test:
+
+2011-05-02  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclCmdMZ.c:	Revised TclFindElement() interface. The final
+	* generic/tclDictObj.c:	argument had been bracePtr, the address of a
+	* generic/tclListObj.c:	boolean var, where the caller can be told
+	* generic/tclParse.c:	whether or not the parsed list element was
+	* generic/tclUtil.c:	enclosed in braces.  In practice, no callers
+	really care about that.  What the callers really want to know is
+	whether the list element value exists as a literal substring of the
+	string being parsed, or whether a call to TclCopyAndCollpase() is
+	needed to produce the list element value.  Now the final argument is
+	changed to do what callers actually need. This is a better fit for the
+	calls in tclParse.c, where now a good deal of post-processing checking
+	for "naked backslashes" is no longer necessary.
+	***POTENTIAL INCOMPATIBILITY***
+	For any callers calling in via the internal stubs table who really do
+	use the final argument explicitly to check for the enclosing brace
+	scenario.  Simply looking for the braces where they must be is the
+	revision available to those callers, and it will backport cleanly.
+
+	* tests/parse.test:	Tests for expanded literals quoting detection.
+
+	* generic/tclCompCmdsSZ.c:	New TclFindElement() is also a better
+	fit for the [switch] compiler.
+
+	* generic/tclInt.h:	Replace TclCountSpaceRuns() with
+	* generic/tclListObj.c:	TclMaxListLength() which is the function we
+	* generic/tclUtil.c:	actually want.
+	* generic/tclCompCmdsSZ.c:
+
+	* generic/tclCompCmdsSZ.c: Rewrite of parts of the switch compiler to
+	better use the powers of TclFindElement() and do less parsing on its
+	own.
+
+2011-04-28  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclInt.h:	New utility routines:
+	* generic/tclParse.c:	TclIsSpaceProc() and TclCountSpaceRuns()
+	* generic/tclUtil.c:
+
+	* generic/tclCmdMZ.c:	Use new routines to replace calls to isspace()
+	* generic/tclListObj.c:	and their /* INTL */ risk.
+	* generic/tclStrToD.c:
+	* generic/tclUtf.c:
+	* unix/tclUnixFile.c:
+
+	* generic/tclStringObj.c:	Improved reaction to out of memory.
+
+2011-04-27  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclCmdMZ.c:	TclFreeIntRep() correction & cleanup.
+	* generic/tclExecute.c:
+	* generic/tclIndexObj.c:
+	* generic/tclInt.h:
+	* generic/tclListObj.c:
+	* generic/tclNamesp.c:
+	* generic/tclResult.c:
+	* generic/tclStringObj.c:
+	* generic/tclVar.c:
+
+	* generic/tclListObj.c:	FreeListInternalRep() cleanup.
+
+2011-04-21  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclInt.h:	Use macro to set List intreps.
+	* generic/tclListObj.c:
+
+	* generic/tclCmdIL.c:	Limits on list length were too strict.
+	* generic/tclInt.h:	Revised panics to errors where possible.
+	* generic/tclListObj.c:
+	* tests/lrepeat.test:
+
+	* generic/tclCompile.c:	Make sure SetFooFromAny routines react
+	* generic/tclIO.c:	reasonably when passed a NULL interp.
+	* generic/tclIndexObj.c:
+	* generic/tclListObj.c:
+	* generic/tclNamesp.c:
+	* generic/tclObj.c:
+	* generic/tclProc.c:
+	* macosx/tclMacOSXFCmd.c:
+
+2011-04-21  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tcl.h:       fix for [Bug 3288345]: Wrong Tcl_StatBuf
+	* generic/tclInt.h:    used on MinGW. Make sure that all _WIN32
+	* win/tclWinFile.c:    compilers use exactly the same layout
+	* win/configure.in:    for Tcl_StatBuf - the one used by MSVC6 -
+	* win/configure:       in all situations.
+
+2011-04-19  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclConfig.c:	Reduce internals access in the implementation
+	of [<foo>::pkgconfig list].
+
+2011-04-18  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclCmdIL.c:	Use ListRepPtr(.) and other cleanup.
+	* generic/tclConfig.c:
+	* generic/tclListObj.c:
+
+	* generic/tclInt.h:	Define and use macros that test whether a Tcl
+	* generic/tclBasic.c:	list value is canonical.
+	* generic/tclUtil.c:
+
+2011-04-18  Donal K. Fellows  <dkf@users.sf.net>
+
+	* doc/dict.n: [Bug 3288696]: Command summary was confusingly wrong
+	when it came to [dict filter] with a 'value' filter.
+
+2011-04-16  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclFCmd.c (TclFileAttrsCmd): Add comments to make this code
+	easier to understand. Added a panic to handle the case where the VFS
+	layer does something odd.
+
+2011-04-13  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclUtil.c:	[Bug 3285375]: Rewrite of Tcl_Concat*()
+	routines to prevent segfaults on buffer overflow.  Build them out of
+	existing primitives already coded to handle overflow properly.  Uses
+	the new TclTrim*() routines.
+
+	* generic/tclCmdMZ.c:	New internal utility routines TclTrimLeft()
+	* generic/tclInt.h:	and TclTrimRight().  Refactor the
+	* generic/tclUtil.c:	[string trim*] implementations to use them.
+
+2011-04-13  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclVar.c: [Bug 2662380]: Fix crash caused by appending to a
+	variable with a write trace that unsets it.
+
+2011-04-13  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclUtil.c (Tcl_ConcatObj): [Bug 3285375]: Make the crash
+	less mysterious through the judicious use of a panic. Not yet properly
+	fixed, but at least now clearer what the failure mode is.
+
+2011-04-12  Don Porter  <dgp@users.sourceforge.net>
+
+	* tests/string.test:	Test for [Bug 3285472]. Not buggy in trunk.
+
+2011-04-12  Venkat Iyer <venkat@comit.com>
+
+	* library/tzdata/Atlantic/Stanley: Update to Olson tzdata2011f
+
+2011-04-12  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclBasic.c: Fix for [Bug 2440625], kbk's patch
+
+2011-04-11  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclBasic.c:
+	* tests/coroutine.test: [Bug 3282869]: Ensure that 'coroutine eval'
+	runs the initial command in the proper context.
+
+2011-04-11  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tcl.h:    Fix for [Bug 3281728]: Tcl sources from 2011-04-06
+	* unix/tcl.m4:      do not build on GCC9 (RH9)
+	* unix/configure:
+
+2011-04-08  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* win/tclWinPort.h: Fix for [Bug 3280043]: win2k: unresolved DLL
+	* win/configure.in: imports.
+	* win/configure
+
+2011-04-06  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclExecute.c (TclCompileObj): Earlier return if Tip280
+	gymnastics not needed.
+
+	* generic/tclExecute.c: Fix for [Bug 3274728]: making *catchTop an
+	unsigned long.
+
+2011-04-06  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* unix/tclAppInit.c:  Make symbols "main" and "Tcl_AppInit"
+	MODULE_SCOPE: there is absolutely no reason for exporting them.
+	* unix/tcl.m4:        Don't use -fvisibility=hidden with static
+	* unix/configure      libraries (--disable-shared)
+
+2011-04-06  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclFCmd.c, macosx/tclMacOSXFCmd.c, unix/tclUnixChan.c,
+	* unix/tclUnixFCmd.c, win/tclWinChan.c, win/tclWinDde.c,
+	* win/tclWinFCmd.c, win/tclWinLoad.c, win/tclWinPipe.c,
+	* win/tclWinReg.c, win/tclWinSerial.c, win/tclWinSock.c: More
+	generation of error codes (most platform-specific parts not already
+	using Tcl_PosixError).
+
+2011-04-05  Venkat Iyer <venkat@comit.com>
+
+	* library/tzdata/Africa/Casablanca: Update to Olson's tzdata2011e
+	* library/tzdata/America/Santiago:
+	* library/tzdata/Pacific/Easter:
+	* library/tzdata/America/Metlakatla: (new)
+	* library/tzdata/America/North_Dakota/Beulah: (new)
+	* library/tzdata/America/Sitka: (new)
+
+2011-04-04  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclOO.c, generic/tclOOBasic.c, generic/tclOODefineCmds.c
+	* generic/tclOOInfo.c, generic/tclOOMethod.c: More generation of
+	error codes (TclOO miscellany).
+
+	* generic/tclCmdAH.c, generic/tclCmdIL.c: More generation of error
+	codes (miscellaneous commands mostly already handled).
+
+2011-04-04  Don Porter  <dgp@users.sourceforge.net>
+
+	* README:	[Bug 3202030]: Updated README files, repairing broken
+	* macosx/README:URLs and removing other bits that were clearly wrong.
+	* unix/README:	Still could use more eyeballs on the detailed build
+	* win/README:	advice on various plaforms.
+
+2011-04-04  Donal K. Fellows  <dkf@users.sf.net>
+
+	* library/init.tcl (tcl::mathfunc::rmmadwiw): Disable by default to
+	make test suite work.
+
+	* generic/tclBasic.c, generic/tclStringObj.c, generic/tclTimer.c,
+	* generic/tclTrace.c, generic/tclUtil.c: More generation of error
+	codes ([format], [after], [trace], RE optimizer).
+
+2011-04-04  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tclCmdAH.c:  Better error-message in case of errors
+	* generic/tclCmdIL.c:  related to setting a variable. This fixes
+	* generic/tclDictObj.c: a warning: "Why make your own error
+	* generic/tclScan.c:   message? Why?"
+	* generic/tclTest.c:
+	* test/error.test:
+	* test/info.test:
+	* test/scan.test:
+	* unix/tclUnixThrd.h:  Remove this unused header file.
+
+2011-04-03  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclNamesp.c, generic/tclObj.c, generic/tclPathObj.c:
+	* generic/tclPipe.c, generic/tclPkg.c, generic/tclProc.c:
+	* generic/tclScan.c: More generation of error codes (namespace
+	creation, path normalization, pipeline creation, package handling,
+	procedures, [scan] formats)
+
+2011-04-02  Kevin B. Kenny  <kennykb@acm.org>
+
+	* generic/tclStrToD.c (QuickConversion): Replaced another couple
+	of 'double' declarations with 'volatile double' to work around
+	misrounding issues in mingw-gcc 3.4.5.
+
+2011-04-02  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclInterp.c, generic/tclListObj.c, generic/tclLoad.c:
+	More generation of errorCodes ([interp], [lset], [load], [unload]).
+
+	* generic/tclEvent.c, generic/tclFileName.c: More generation of
+	errorCode information (default [bgerror] and [glob]).
+
+2011-04-01  Reinhard Max  <max@suse.de>
+
+	* library/init.tcl: TIP#131 implementation.
+
+2011-03-31  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclGetDate.y, generic/tclDate.c (TclClockOldscanObjCmd):
+	More generation of errorCode information.
+
+2011-03-28  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclCmdMZ.c, generic/tclConfig.c, generic/tclUtil.c: More
+	generation of errorCode information, notably when lists are mis-parsed
+
+	* generic/tclCmdMZ.c (Tcl_RegexpObjCmd, Tcl_RegsubObjCmd): Use the
+	error messages generated by the variable management code rather than
+	creating our own.
+
+2011-03-27  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclBasic.c (TclNREvalObjEx): fix performance issue, notably
+	apparent in tclbench's "LIST lset foreach". Many thanks to Twylite for
+	patiently researching the issue and explaining it to me: a missing
+	Tcl_ResetObjResult that causes unwanted sharing of the current result
+	Tcl_Obj.
+
+2011-03-26  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclNamesp.c (Tcl_Export, Tcl_Import, DoImport): More
+	generation of errorCode information.
+
+	* generic/tclCompExpr.c, generic/tclCompile.c, generic/tclExecute.c:
+	* generic/tclListObj.c, generic/tclNamesp.c, generic/tclObj.c:
+	* generic/tclStringObj.c, generic/tclUtil.c: Reduce the number of
+	casts used to manage Tcl_Obj internal representations.
+
+2011-03-24  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tcl.h (ckfree,etc.): Restored C++ usability to the memory
+	allocation and free macros.
+
+2011-03-24  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclFCmd.c (TclFileAttrsCmd): Ensure that any reference to
+	temporary index tables is squelched immediately rather than hanging
+	around to trip us up in the future.
+
+2011-03-23  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclObj.c: Exploit HAVE_FAST_TSD for the deletion context in
+	TclFreeObj()
+
+2011-03-22  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclThreadAlloc.c: Simpler initialization of Cache under
+	HAVE_FAST_TSD, from mig-alloc-reform.
+
+2011-03-21  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* unix/tclLoadDl.c:    [Bug 3216070]: Loading extension libraries
+	* unix/tclLoadDyld.c:  from embedded Tcl applications.
+	***POTENTIAL INCOMPATIBILITY***
+	For extensions which rely on symbols from other extensions being
+	present in the global symbol table. For an example and some discussion
+	of workarounds, see http://stackoverflow.com/q/8330614/301832
+
+2011-03-21  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclCkAlloc.c:
+	* generic/tclInt.h: Remove one level of allocator indirection in
+	non-memdebug builds, imported from mig-alloc-reform.
+
+2011-03-20  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclThreadAlloc.c: Imported HAVE_FAST_TSD support from
+	mig-alloc-reform. The feature has to be enabled by hand: no autoconf
+	support has been added. It is not clear how universal a build using
+	this will be: it also requires some loader support.
+
+2011-03-17  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclCompExpr.c (ParseExpr): Generate errorCode information on
+	failure to parse expressions.
+
+2011-03-17  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tclMain.c: [Patch 3124683]: Reorganize the platform-specific
+	stuff in (tcl|tk)Main.c.
+
+2011-03-16  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tclCkalloc.c: [Bug 3197864]: Pointer truncation on Win64
+	TCL_MEM_DEBUG builds.
+
+2011-03-16  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclBasic.c:	Some rewrites to eliminate calls to isspace()
+	* generic/tclParse.c:	and their /* INTL */ risk.
+	* generic/tclProc.c:
+
+2011-03-16  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* unix/tcl.m4:    Make SHLIB_LD_LIBS='${LIBS}' the default and
+	* unix/configure: set to "" on per-platform necessary basis.
+	Backported from TEA, but kept all original platform code which was
+	removed from TEA.
+
+2011-03-14  Kevin B. Kenny  <kennykb@acm.org>
+
+	* tools/tclZIC.tcl (onDayOfMonth): Allow for leading zeroes in month
+	and day so that tzdata2011d parses correctly.
+	* library/tzdata/America/Havana:
+	* library/tzdata/America/Juneau:
+	* library/tzdata/America/Santiago:
+	* library/tzdata/Europe/Istanbul:
+	* library/tzdata/Pacific/Apia:
+	* library/tzdata/Pacific/Easter:
+	* library/tzdata/Pacific/Honolulu:  tzdata2011d
+
+	* generic/tclAssembly.c (BBEmitInstInt1): Changed parameter data types
+	in an effort to silence a MSVC warning reported by Ashok P. Nadkarni.
+	Unable to test, since both forms work on my machine in VC2005, 2008,
+	2010, in both release and debug builds.
+	* tests/tclTest.c (TestdstringCmd): Restored MSVC buildability broken
+	by [5574bdd262], which changed the effective return type of 'ckalloc'
+	from 'char*' to 'void*'.
+
+2011-03-13  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclExecute.c: remove TEBCreturn()
+
+2011-03-12  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tcl.h (ckalloc,ckfree,ckrealloc): Moved casts into these
+	macro so that they work with VOID* (which is a void* on all platforms
+	which Tcl actually builds on) and unsigned int for the length
+	parameters, removing the need for MANY casts across the rest of Tcl.
+	Note that this is a strict source-level-only change, so size_t cannot
+	be used (would break binary compatibility on 64-bit platforms).
+
+2011-03-12  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* win/tclWinFile.c: [Bug 3185609]: File normalization corner case
+	of ... broken with -DUNICODE
+
+2011-03-11  Donal K. Fellows  <dkf@users.sf.net>
+
+	* tests/unixInit.test: Make better use of tcltest2.
+
+2011-03-10  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclBasic.c, generic/tclCompCmds.c, generic/tclEnsemble.c:
+	* generic/tclInt.h, generic/tclNamesp.c, library/auto.tcl:
+	* tests/interp.test, tests/namespace.test, tests/nre.test:
+	Converted the [namespace] command into an ensemble. This has the
+	consequence of making it vital for Tcl code that wishes to work with
+	namespaces to _not_ delete the ::tcl namespace.
+	***POTENTIAL INCOMPATIBILITY***
+
+	* library/tcltest/tcltest.tcl (loadIntoSlaveInterpreter): Added this
+	command to handle connecting tcltest to a slave interpreter. This adds
+	in the hook (inside the tcltest namespace) that allows the tests run
+	in the child interpreter to be reported as part of the main sequence
+	of test results. Bumped version of tcltest to 2.3.3.
+	* tests/init.test, tests/package.test: Adapted these test files to use
+	the new feature.
+
+	* generic/tclAlloc.c, generic/tclCmdMZ.c, generic/tclCompExpr.c:
+	* generic/tclCompile.c, generic/tclEnv.c, generic/tclEvent.c:
+	* generic/tclIO.c, generic/tclIOCmd.c, generic/tclIORChan.c:
+	* generic/tclIORTrans.c, generic/tclLiteral.c, generic/tclNotify.c:
+	* generic/tclParse.c, generic/tclStringObj.c, generic/tclUtil.c:
+	* generic/tclZlib.c, unix/tclUnixFCmd.c, unix/tclUnixNotfy.c:
+	* unix/tclUnixPort.h, unix/tclXtNotify.c: Formatting fixes, mainly to
+	comments, so code better fits the style in the Engineering Manual.
+
+2011-03-09  Donal K. Fellows  <dkf@users.sf.net>
+
+	* tests/incr.test: Update more of the test suite to use Tcltest 2.
+
+2011-03-09  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclNamesp.c:	[Bug 3202171]: Tighten the detector of nested
+	* tests/namespace.test:	[namespace code] quoting that the quoted
+	scripts function properly even in a namespace that contains a custom
+	"namespace" command.
+
+	* doc/tclvars.n:	Formatting fix.  Thanks to Pat Thotys.
+
+2011-03-09  Donal K. Fellows  <dkf@users.sf.net>
+
+	* tests/dstring.test, tests/init.test, tests/link.test: Update more of
+	the test suite to use Tcltest 2.
+
+2011-03-08  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tclBasic.c: Fix gcc warnings: variable set but not used
+	* generic/tclProc.c:
+	* generic/tclIORChan.c:
+	* generic/tclIORTrans.c:
+	* generic/tclAssembly.c:  Fix gcc warning: comparison between signed
+	and unsigned integer expressions
+
+2011-03-08  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclInt.h:	Remove TclMarkList() routine, an experimental
+	* generic/tclUtil.c:	dead-end from the 8.5 alpha days.
+
+	* generic/tclResult.c (ResetObjResult): [Bug 3202905]: Correct failure
+	to clear invalid intrep.  Thanks to Colin McDonald.
+
+2011-03-08  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclAssembly.c, tests/assemble.test: Migrate to use a style
+	more consistent with the rest of Tcl.
+
+2011-03-06  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclBasic.c:	More replacements of Tcl_UtfBackslash() calls
+	* generic/tclCompile.c:	with TclParseBackslash() where possible.
+	* generic/tclCompCmdsSZ.c:
+	* generic/tclParse.c:
+	* generic/tclUtil.c:
+
+	* generic/tclUtil.c (TclFindElement):	[Bug 3192636]: Guard escape
+	sequence scans to not overrun the string end.
+
+2011-03-05  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclParse.c (TclParseBackslash): [Bug 3200987]: Correct
+	* tests/parse.test:	trunction checks in \x and \u substitutions.
+
+2011-03-05  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclExecute.c (TclStackFree): insure that the execStack
+	satisfies "at most one free stack after the current one" when
+	consecutive reallocs caused the creation of intervening stacks.
+
+2011-03-05  Kevin B. Kenny  <kennykb@acm.org>
+
+	* generic/tclAssembly.c (new file):
+	* generic/tclBasic.c (Tcl_CreateInterp):
+	* generic/tclInt.h:
+	* tests/assemble.test (new file):
+	* unix/Makefile.in:
+	* win/Makefile.in:
+	* win/makefile.vc:  Merged dogeen-assembler-branch into HEAD. Since
+	all functional changes are in the tcl::unsupported namespace, there's
+	no reason to sequester this code on a separate branch.
+
+2011-03-05  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclExecute.c: Cleaner mem management for TEBCdata
+
+	* generic/tclExecute.c:
+	* tests/nre.test: Renamed BottomData to TEBCdata, so that the name
+	refers to what it is rather than to its storage location.
+
+	* generic/tclBasic.c:     Renamed struct TEOV_callback to the more
+	* generic/tclCompExpr.c:  descriptive NRE_callback.
+	* generic/tclCompile.c:
+	* generic/tclExecute.c:
+	* generic/tclInt.decls:
+	* generic/tclInt.h:
+	* generic/tclIntDecls.h:
+	* generic/tclTest.c:
+
+2011-03-04  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclOOMethod.c (ProcedureMethodCompiledVarConnect)
+	(ProcedureMethodCompiledVarDelete): [Bug 3185009]: Keep references to
+	resolved object variables so that an unset doesn't leave any dangling
+	pointers for code to trip over.
+
+2011-03-01  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclBasic.c (TclNREvalObjv): Missing a variable declaration
+	in commented out non-optimised code, left for ref in checkin
+	[b97b771b6d]
+
+2011-03-03  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclResult.c (Tcl_AppendResultVA):	Use the directive
+	USE_INTERP_RESULT [TIP 330] to force compat with interp->result
+	access, instead of the improvised hack USE_DIRECT_INTERP_RESULT_ACCESS
+	from releases past.
+
+2011-03-01  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclCompCmdsSZ.c (TclCompileThrowCmd, TclCompileUnsetCmd):
+	fix leaks
+
+	* generic/tclBasic.c:       This is [Patch 3168398],
+	* generic/tclCompCmdsSZ.c:  Joe Mistachkin's optimisation
+	* generic/tclExecute.c:     of Tip #285
+	* generic/tclInt.decls:
+	* generic/tclInt.h:
+	* generic/tclIntDecls.h:
+	* generic/tclInterp.c:
+	* generic/tclOODecls.h:
+	* generic/tclStubInit.c:
+	* win/makefile.vc:
+
+	* generic/tclExecute.c (ExprObjCallback): Fix object leak
+
+	* generic/tclExecute.c (TEBCresume): Store local var array and
+	constants in automatic vars to reduce indirection, slight perf
+	increase
+
+	* generic/tclOOCall.c (TclOODeleteContext): Added missing '*' so that
+	trunk compiles.
+
+	* generic/tclBasic.c (TclNRRunCallbacks): [Patch 3168229]: Don't do
+	the trampoline dance for commands that do not have an nreProc.
+
+2011-03-01  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclOO.c (Tcl_NewObjectInstance, TclNRNewObjectInstance)
+	(TclOOObjectCmdCore, FinalizeObjectCall):
+	* generic/tclOOBasic.c (TclOO_Object_Destroy, AfterNRDestructor):
+	* generic/tclOOCall.c (TclOODeleteContext, TclOOGetCallContext):
+	Reorganization of call context reference count management so that code
+	is (mostly) simpler.
+
+2011-01-26  Donal K. Fellows  <dkf@users.sf.net>
+
+	* doc/RegExp.3: [Bug 3165108]: Corrected documentation of description
+	of subexpression info in Tcl_RegExpInfo structure.
+
+2011-01-25  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tclPreserve.c:  Don't miss 64-bit address bits in panic
+				  message.
+	* win/tclWinChan.c:       Fix various gcc-4.5.2 64-bit warning
+	* win/tclWinConsole.c:    messages, e.g. by using full 64-bits for
+	* win/tclWinDde.c:	  socket fd's
+	* win/tclWinPipe.c:
+	* win/tclWinReg.c:
+	* win/tclWinSerial.c:
+	* win/tclWinSock.c:
+	* win/tclWinThrd.c:
+
+2011-01-19  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* tools/genStubs.tcl: [FRQ 3159920]: Tcl_ObjPrintf() crashes with
+	* generic/tcl.decls   bad format specifier.
+	* generic/tcl.h:
+	* generic/tclDecls.h:
+
+2011-01-18  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclOOMethod.c (PushMethodCallFrame): [Bug 3001438]: Make
+	sure that the cmdPtr field of the procPtr is correct and relevant at
+	all times so that [info frame] can report sensible information about a
+	frame after a return to it from a recursive call, instead of probably
+	crashing (depending on what else has overwritten the Tcl stack!)
+
+2011-01-18  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tclBasic.c:      Various mismatches between Tcl_Panic
+	* generic/tclCompCmds.c:   format string and its arguments,
+	* generic/tclCompCmdsSZ.c: discovered thanks to [Bug 3159920]
+	* generic/tclCompExpr.c:
+	* generic/tclEnsemble.c:
+	* generic/tclPreserve.c:
+	* generic/tclTest.c:
+
+2011-01-17  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tclIOCmd.c: [Bug 3148192]: Commands "read/puts" incorrectly
+	* tests/chanio.test:  interpret parameters. Improved error-message
+	* tests/io.test       regarding legacy form.
+	* tests/ioCmd.test
+
+2011-01-15  Kevin B. Kenny  <kennykb@acm.org>
+
+	* doc/tclvars.n:
+	* generic/tclStrToD.c:
+	* generic/tclUtil.c (Tcl_PrintDouble):
+	* tests/util.test (util-16.*): [Bug 3157475]: Restored full Tcl 8.4
+	compatibility for the formatting of floating point numbers when
+	$::tcl_precision is not zero. Added compatibility tests to make sure
+	that excess trailing zeroes are suppressed for all eight major code
+	paths.
+
+2011-01-12  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* win/tclWinFile.c:   Use _vsnprintf in stead of vsnprintf, because
+	MSVC 6 doesn't have it. Reported by andreask.
+	* win/tcl.m4:         handle --enable-64bit=ia64 for gcc
+	* win/configure.in:   more accurate test for correct <intrin.h>
+	* win/configure:      (autoconf-2.59)
+	* win/tclWin32Dll.c:  VS 2005 64-bit does not have intrin.h, and
+	* generic/tclPanic.c: does not need it.
+
+2011-01-07  Kevin B. Kenny  <kennykb@acm.org>
+
+	* tests/util.test (util-15.*): Added test cases for floating point
+	conversion of the largest denormal and the smallest normal number, to
+	avoid any possibility of the failure suffered by PHP in the last
+	couple of days. (They didn't fail, so no actual functional change.)
+
+2011-01-05  Donal K. Fellows  <dkf@users.sf.net>
+
+	* tests/package.test, tests/pkg.test: Coalesce these tests into one
+	file that is concerned with the package system. Convert to use
+	tcltest2 properly.
+	* tests/autoMkindex.test, tests/pkgMkIndex.test: Convert to use
+	tcltest2 properly.
+
+2011-01-01  Donal K. Fellows  <dkf@users.sf.net>
+
+	* tests/cmdAH.test, tests/cmdMZ.test, tests/compExpr.test,
+	* tests/compile.test, tests/concat.test, tests/eval.test,
+	* tests/fileName.test, tests/fileSystem.test, tests/interp.test,
+	* tests/lsearch.test, tests/namespace-old.test, tests/namespace.test,
+	* tests/oo.test, tests/proc.test, tests/security.test,
+	* tests/switch.test, tests/unixInit.test, tests/var.test,
+	* tests/winDde.test, tests/winPipe.test: Clean up of tests and
+	conversion to tcltest 2. Target has been to get init and cleanup code
+	out of the test body and into the -setup/-cleanup stanzas.
+
+	* tests/execute.test (execute-11.1): [Bug 3142026]: Added test that
+	fails (with a crash) in an unfixed memdebug build on 64-bit systems.
+
+2010-12-31  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclCmdIL.c (SortElement): Use unions properly in the
+	definition of this structure so that there is no need to use nasty
+	int/pointer type punning. Made it clearer what the purposes of the
+	various parts of the structure are.
+
+2010-12-31  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* unix/dltest/*.c: [Bug 3148192]: Fix broken [load] tests by ensuring
+	that the affected files are never compiled with -DSTATIC_BUILD.
+
+2010-12-30  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclExecute.c (GrowEvaluationStack): Off-by-one error in
+	sizing the new allocation - was ok in comment but wrong in the code.
+	Triggered by [Bug 3142026] which happened to require exactly one more
+	than what was in existence.
+
+2010-12-26  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclCmdIL.c (Tcl_LsortObjCmd): Fix crash when multiple -index
+	options are used. Simplified memory handling logic.
+
+2010-12-20  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* win/tclWin32Dll.c:    [Patch 3059922]: fixes for mingw64 - gcc4.5.1
+	tdm64-1: completed for all environments.
+
+2010-12-20  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* win/configure.in:   Explicitely test for intrinsics support in
+	compiler, before assuming only MSVC has it.
+	* win/configure:      (autoconf-2.59)
+	* generic/tclPanic.c:
+
+2010-12-19  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* win/tclWin32Dll.c:    [Patch 3059922]: fixes for mingw64 - gcc4.5.1
+	tdm64-1: Fixed for gcc, not yet for MSVC 64-bit.
+
+2010-12-17  Stuart Cassoff  <stwo@users.sourceforge.net>
+
+	* unix/Makefile.in:  Remove unwanted/obsolete 'ddd' target.
+
+2010-12-17  Stuart Cassoff  <stwo@users.sourceforge.net>
+
+	* unix/Makefile.in:	Clean up '.PHONY:' targets: Arrange those
+				common to Tcl and Tk as in Tk's Makefile.in,
+				add any missing ones and remove duplicates.
+
+2010-12-17  Stuart Cassoff  <stwo@users.sourceforge.net>
+
+	* unix/Makefile.in:  [Bug 2446711]: Remove 'allpatch' target.
+
+2010-12-17  Stuart Cassoff  <stwo@users.sourceforge.net>
+
+	* unix/Makefile.in:  [Bug 2537626]: Use 'rpmbuild', not 'rpm'.
+
+2010-12-16  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tclPanic.c:  [Patch 3124554]: Move WishPanic from Tk to Tcl
+	* win/tclWinFile.c:    Better communication with debugger, if present.
+
+2010-12-15  Kevin B. Kenny  <kennykb@acm.org>
+
+	[dogeen-assembler-branch]
+
+	* tclAssembly.c:
+	* assemble.test: 	Reworked beginCatch/endCatch handling to
+	enforce the more severe (but more correct) restrictions on catch
+	handling that appeared in the discussion of [Bug 3098302] and in
+	tcl-core traffic beginning about 2010-10-29.
+
+2010-12-15  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tclPanic.c:    Restore abort() as it was before.
+	* win/tclWinFile.c:      [Patch 3124554]: Use ExitProcess() here, like
+	in wish.
+
+2010-12-14  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tcl.h: [Bug 3137454]: Tcl CVS HEAD does not build on GCC 3.
+
+2010-12-14  Reinhard Max  <max@suse.de>
+
+	* win/tclWinSock.c (CreateSocket):         Swap the loops over
+	* unix/tclUnixSock.c (CreateClientSocket): local and remote addresses,
+	so that the system's address preference for the remote side decides
+	which family gets tried first. Cleanup and clarify some of the
+	comments.
+
+2010-12-13  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tcl.h:    [Bug 3135271]: Link error due to hidden
+	* unix/tcl.m4:      symbols (CentOS 4.2)
+	* unix/configure:   (autoconf-2.59)
+	* win/tclWinFile.c:  Undocumented feature, only meant to be used by
+	Tk_Main. See [Patch 3124554]: Move WishPanic from Tk to Tcl
+
+2010-12-12  Stuart Cassoff  <stwo@users.sourceforge.net>
+
+	* unix/tcl.m4: Better building on OpenBSD.
+	* unix/configure: (autoconf-2.59)
+
+2010-12-10  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tcl.h:       [Bug 3129448]: Possible over-allocation on
+	* generic/tclCkalloc.c: 64-bit platforms, part 2
+	* generic/tclCompile.c:
+	* generic/tclHash.c:
+	* generic/tclInt.h:
+	* generic/tclIO.h:
+	* generic/tclProc.c:
+
+2010-12-10 Alexandre Ferrieux  <ferrieux@users.sourceforge.net>
+
+	* generic/tclIO.c: Make sure [fcopy -size ... -command ...] always
+	* tests/io.test:   calls the callback asynchronously, even for size
+			   zero.
+
+2010-12-10  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tclBinary.c:  Fix gcc -Wextra warning: missing initializer
+	* generic/tclCmdAH.c:
+	* generic/tclCmdIL.c:
+	* generic/tclCmdMZ.c:
+	* generic/tclDictObj.c:
+	* generic/tclIndexObj.c:
+	* generic/tclIOCmd.c:
+	* generic/tclVar.c:
+	* win/tcl.m4:               Fix manifest-generation for 64-bit gcc
+				    (mingw-w64)
+	* win/configure.in:         Check for availability of intptr_t and
+				    uintptr_t
+	* win/configure:            (autoconf-2.59)
+	* generic/tclInt.decls:     Change 1st param of TclSockMinimumBuffers
+	* generic/tclIntDecls.h:    to ClientData, and TclWin(Get|Set)SockOpt
+	* generic/tclIntPlatDecls.h:to SOCKET, because on Win64 those are
+	* generic/tclIOSock.c:	    64-bit, which does not fit.
+	* win/tclWinSock.c:
+	* unix/tclUnixSock.c:
+
+2010-12-09  Donal K. Fellows  <dkf@users.sf.net>
+
+	* tests/fCmd.test: Improve sanity of constraints now that we don't
+	support anything before Windows 2000.
+
+	* generic/tclCmdAH.c (TclInitFileCmd, TclMakeFileCommandSafe, ...):
+	Break up [file] into an ensemble. Note that the ensemble is safe in
+	itself, but the majority of its subcommands are not.
+	* generic/tclFCmd.c (FileCopyRename,TclFileDeleteCmd,TclFileAttrsCmd)
+	(TclFileMakeDirsCmd): Adjust these subcommand implementations to work
+	inside an ensemble.
+	(TclFileLinkCmd, TclFileReadLinkCmd, TclFileTemporaryCmd): Move these
+	subcommand implementations from tclCmdAH.c, where they didn't really
+	belong.
+	* generic/tclIOCmd.c (TclChannelNamesCmd): Move to more appropriate
+	source file.
+	* generic/tclEnsemble.c (TclMakeEnsemble): Start of code to make
+	partially-safe ensembles. Currently does not function as expected due
+	to various shortcomings in how safe interpreters are constructed.
+	* tests/cmdAH.test, tests/fCmd.test, tests/interp.test: Test updates
+	to take into account systematization of error messages.
+
+	* tests/append.test, tests/appendComp.test: Clean up tests so that
+	they don't leave things in the global environment (detected when doing
+	-singleproc testing).
+
+2010-12-07  Donal K. Fellows  <dkf@users.sf.net>
+
+	* tests/fCmd.test, tests/safe.test, tests/uplevel.test,
+	* tests/upvar.test, tests/var.test: Convert more tests to tcltest2 and
+	factor them to be easier to understand.
+
+	* generic/tclStrToD.c: Tidy up code so that more #ifdef-fery is
+	quarantined at the front of the file and function headers follow the
+	modern Tcl style.
+
+2010-12-06  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tclBinary.c:  [Bug 3129448]: Possible over-allocation on
+	* generic/tclCkalloc.c: 64-bit platforms.
+	* generic/tclTrace.c:
+
+2010-12-05  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* unix/tcl.m4: [Patch 3116490]: Cross-compile support for unix
+	* unix/configure: (autoconf-2.59)
+
+2010-12-03  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* generic/tclUtil.c (TclReToGlob): Add extra check for multiple inner
+	*s that leads to poor recursive glob matching, defer to original RE
+	instead.  tclbench RE var backtrack.
+
+2010-12-03  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tclUtil.c:   Silence gcc warning when using -Wwrite-strings
+	* generic/tclStrToD.c: Silence gcc warning for non-IEEE platforms
+	* win/Makefile.in:  [Patch 3116490]: Cross-compile Tcl mingw32 on unix
+	* win/tcl.m4:       This makes it possible to cross-compile Tcl/Tk for
+	* win/configure.in: Windows (either 32-bit or 64-bit) out-of-the-box
+	* win/configure:    on UNIX, using mingw-w64 build tools (If Itcl,
+	tdbc and Thread take over the latest tcl.m4, they can do that too).
+
+2010-12-01  Kevin B. Kenny  <kennykb@acm.org>
+
+	* generic/tclStrToD.c (SetPrecisionLimits, TclDoubleDigits):
+	[Bug 3124675]: Added meaningless initialization of 'i', 'ilim' and
+	'ilim1' to silence warnings from the C compiler about possible use of
+	uninitialized variables, Added a panic to the 'switch' that assigns
+	them, to assert that the 'default' case is impossible.
+
+2010-12-01  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tclBasic.c: Fix gcc 64-bit warnings: cast from pointer to
+	* generic/tclHash.c:  integer of different size.
+	* generic/tclTest.c:
+	* generic/tclThreadTest.c:
+	* generic/tclStrToD.c: Fix gcc(-4.5.2) warning: 'static' is not at
+	beginning of declaration.
+	* generic/tclPanic.c: Allow Tcl_Panic() to enter the debugger on win32
+	* generic/tclCkalloc.c: Use Tcl_Panic() in stead of duplicating the
+	code.
+
+2010-11-30  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* generic/tclInt.decls, generic/tclInt.h, generic/tclIntDecls.h:
+	* generic/tclStubInit.c: TclFormatInt restored at slot 24
+	* generic/tclUtil.c (TclFormatInt): restore TclFormatInt func from
+	2005-07-05 macro-ization. Benchmarks indicate it is faster, as a key
+	int->string routine (e.g. int-indexed arrays).
+
+2010-11-29 Alexandre Ferrieux  <ferrieux@users.sourceforge.net>
+
+	* generic/tclBasic.c: Patch by Miguel, providing a
+	[::tcl::unsupported::inject coroname command args], which prepends
+	("injects") arbitrary code to a suspended coro's future resumption.
+	Neat for debugging complex coros without heavy instrumentation.
+
+2010-11-29  Kevin B. Kenny  <kennykb@acm.org>
+
+	* generic/tclInt.decls:
+	* generic/tclInt.h:
+	* generic/tclStrToD.c:
+	* generic/tclTest.c:
+	* generic/tclTomMath.decls:
+	* generic/tclUtil.c:
+	* tests/util.test:
+	* unix/Makefile.in:
+	* win/Makefile.in:
+	* win/makefile.vc: Rewrite of Tcl_PrintDouble and TclDoubleDigits that
+	(a) fixes a severe performance problem with floating point shimmering
+	reported by Karl Lehenbauer, (b) allows TclDoubleDigits to generate
+	the digit strings for 'e' and 'f' format, so that it can be used for
+	tcl_precision != 0 (and possibly later for [format]), (c) fixes [Bug
+	3120139] by making TclPrintDouble inherently locale-independent, (d)
+	adds test cases to util.test for correct rounding in difficult cases
+	of TclDoubleDigits where fixed- precision results are requested. (e)
+	adds test cases to util.test for the controversial aspects of [Bug
+	3105247]. As a side effect, two more modules from libtommath
+	(bn_mp_set_int.c and bn_mp_init_set_int.c) are brought into the build,
+	since the new code uses them.
+
+	* generic/tclIntDecls.h:
+	* generic/tclStubInit.c:
+	* generic/tclTomMathDecls.h:	Regenerated.
+
+2010-11-24  Donal K. Fellows  <dkf@users.sf.net>
+
+	* tests/chanio.test, tests/iogt.test, tests/ioTrans.test: Convert more
+	tests to tcltest2 and factor them to be easier to understand.
+
+2010-11-20  Donal K. Fellows  <dkf@users.sf.net>
+
+	* tests/chanio.test: Converted many tests to tcltest2 by marking the
+	setup and cleanup parts as such.
+
+2010-11-19  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* win/tclWin32Dll.c: Fix gcc warnings: unused variable 'registration'
+	* win/tclWinChan.c:
+	* win/tclWinFCmd.c:
+
+2010-11-18  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* win/tclAppInit.c: [FRQ 491789]: "setargv() doesn't support a unicode
+	cmdline" now implemented for cygwin and mingw32 too.
+	* tests/main.test: No longer disable tests Tcl_Main-1.4 and 1.6 on
+	Windows, because those now work on all supported platforms.
+	* win/configure.in:  Set NO_VIZ=1 when zlib is compiled in libtcl,
+	this resolves compiler warnings in 64-bit and static builds.
+	* win/configure (regenerated)
+
+2010-11-18  Donal K. Fellows  <dkf@users.sf.net>
+
+	* doc/file.n: [Bug 3111298]: Typofix.
+
+	* tests/oo.test: [Bug 3111059]: Added testing that neatly trapped this
+	issue.
+
+2010-11-18  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclNamesp.c: [Bug 3111059]: Fix leak due to bad looping
+	construct.
+
+2010-11-17  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* win/tcl.m4: [FRQ 491789]: "setargv() doesn't support a unicode
+	cmdline" now implemented for mingw-w64
+	* win/configure    (re-generated)
+
+2010-11-16  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* win/tclAppInit.c:Bring compilation under mingw-w64 a bit closer
+	* win/cat.c:       to reality. See for what's missing:
+	* win/tcl.m4:      <https://sourceforge.net/apps/trac/mingw-w64/wiki/Unicode%20apps>
+	* win/configure:   (re-generated)
+	* win/tclWinPort.h: [Bug 3110161]: Extensions using TCHAR don't
+	compile on VS2005 SP1
+
+2010-11-15  Andreas Kupries  <andreask@activestate.com>
+
+	* doc/interp.n: [Bug 3081184]: TIP #378.
+	* doc/tclvars.n: Performance fix for TIP #280.
+	* generic/tclBasic.c:
+	* generic/tclExecute.c:
+	* generic/tclInt.h:
+	* generic/tclInterp.c:
+	* tests/info.test:
+	* tests/interp.test:
+
+2010-11-10  Andreas Kupries  <andreask@activestate.com>
+
+	* changes:	Updates for 8.6b2 release.
+
+2010-11-09  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclOOMethod.c (ProcedureMethodVarResolver): [Bug 3105999]:
+	* tests/oo.test:	Make sure that resolver structures that are
+				only temporarily needed get squelched.
+
+2010-11-05  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tclMain.c: Thanks, Kevin, for the fix, but this how it was
+	supposed to be (TCL_ASCII_MAIN is only supposed to be defined on
+	WIN32).
+
+2010-11-05  Kevin B. Kenny  <kennykb@acm.org>
+
+	* generic/tclMain.c: Added missing conditional on _WIN32 around code
+	that messes around with the definition of _UNICODE, to correct a badly
+	broken Unix build from Jan's last commit.
+
+2010-11-04  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tclDecls.h:	[FRQ 491789]: "setargv() doesn't support a
+	* generic/tclMain.c:	unicode cmdline" implemented for Tcl on MSVC++
+	* doc/Tcl_Main.3:
+	* win/tclAppInit.c:
+	* win/makefile.vc:
+	* win/Makefile.in:
+	* win/tclWin32Dll.c:	Eliminate minor MSVC warning TCHAR -> char
+				conversion
+
+2010-11-04  Reinhard Max  <max@suse.de>
+
+	* tests/socket.test: Run the socket tests three times with the address
+	family set to any, inet, and inet6 respectively. Use constraints to
+	skip the tests if a family is found to be unsupported or not
+	configured on the local machine. Adjust the tests to dynamically adapt
+	to the address family that is being tested.
+
+	Rework some of the tests to speed them up by avoiding (supposedly)
+	unneeded [after]s.
+
+2010-11-04  Stuart Cassoff  <stwo@users.sourceforge.net>
+
+	* unix/Makefile.in:	[Patch 3101127]: Installer Improvements.
+	* unix/install-sh:
+
+2010-11-04  Donal K. Fellows  <dkf@users.sf.net>
+
+	* tests/error.test (error-19.13): Another variation on testing for
+	issues in [try] compilation.
+
+	* doc/Tcl.n (Variable substitution): [Bug 3099086]: Increase clarity
+	of explanation of what characters are actually permitted in variable
+	substitutions. Note that this does not constitute a change of
+	behavior; it is just an improvement of explanation.
+
+2010-11-04  Don Porter  <dgp@users.sourceforge.net>
+
+	* changes:	Updates for 8.6b2 release.  (Thanks Andreas Kupries)
+
+2010-11-03  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* win/tclWinFcmd.c:    [FRQ 2965056]: Windows build with -DUNICODE
+	* win/tclWinFile.c:    (more clean-ups for pre-win2000 stuff)
+	* win/tclWinReg.c:
+
+2010-11-03  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclCmdMZ.c (TryPostBody):  Ensure that errors when setting
+	* tests/error.test (error-19.1[12]): message/opt capture variables get
+					     reflected properly to the caller.
+
+2010-11-03  Kevin B. Kenny  <kennykb@acm.org>
+
+	* generic/tclCompCmds.c (TclCompileCatchCmd): [Bug 3098302]:
+	* tests/compile.test (compile-3.6): Reworked the compilation of the
+	[catch] command so as to avoid placing any code that might throw an
+	exception (specifically, any initial substitutions or any stores to
+	result or options variables) between the BEGIN_CATCH and END_CATCH but
+	outside the exception range.  Added a test case that panics on a stack
+	smash if the change is not made.
+
+2010-11-01  Stuart Cassoff  <stwo@users.sourceforge.net>
+
+	* library/safe.tcl:	Improved handling of non-standard module path
+	* tests/safe.test:	lists, empty path lists in particular.
+
+2010-11-01  Kevin B. Kenny  <kennykb@acm.org>
+
+	* library/tzdata/Asia/Hong_Kong:
+	* library/tzdata/Pacific/Apia:
+	* library/tzdata/Pacific/Fiji:   Olson's tzdata2010o.
+
+2010-10-29  Alexandre Ferrieux  <ferrieux@users.sourceforge.net>
+
+	* generic/tclTimer.c:	[Bug 2905784]: Stop small [after]s from
+				wasting CPU while keeping accuracy.
+
+2010-10-28  Kevin B. Kenny  <kennykb@acm.org>
+
+	[dogeen-assembler-branch]
+	* generic/tclAssembly.c:
+	* tests/assembly.test (assemble-31.*): Added jump tables.
+
+2010-10-28  Don Porter  <dgp@users.sourceforge.net>
+
+	* tests/http.test:	[Bug 3097490]: Make http-4.15 pass in
+				isolation.
+
+	* unix/tclUnixSock.c:	[Bug 3093120]: Prevent calls of
+				freeaddrinfo(NULL) which can crash some
+				systems.  Thanks Larry Virden.
+
+2010-10-26  Reinhard Max  <max@suse.de>
+
+	* Changelog.2008: Split off from Changelog.
+	* generic/tclIOSock.c (TclCreateSocketAddress): The interp != NULL
+	check is needed for ::tcl::unsupported::socketAF as well.
+
+2010-10-26  Donal K. Fellows  <dkf@users.sf.net>
+
+	* unix/tclUnixSock.c (TcpGetOptionProc): Prevent crash if interp is
+	* win/tclWinSock.c (TcpGetOptionProc):   NULL (a legal situation).
+
+2010-10-26  Reinhard Max  <max@suse.de>
+
+	* unix/tclUnixSock.c (TcpGetOptionProc): Added support for
+	::tcl::unsupported::noReverseDNS, which if set to any value, prevents
+	[fconfigure -sockname] and [fconfigure -peername] from doing
+	reverse DNS queries.
+
+2010-10-24  Kevin B. Kenny  <kennykb@acm.org>
+
+	[dogeen-assembler-branch]
+	* generic/tclAssembly.c:
+	* tests/assembly.test (assemble-17.15): Reworked branch handling so
+	that forward branches can use jump1 (jumpTrue1, jumpFalse1). Added
+	test cases that the forward branches will expand to jump4, jumpTrue4,
+	jumpFalse4 when needed.
+
+2010-10-23  Kevin B. Kenny  <kennykb@acm.org>
+
+	[dogeen-assembler-branch]
+	* generic/tclAssembly.h (removed):
+				Removed file that was included in only one
+				source file.
+	* generictclAssembly.c:	Inlined tclAssembly.h.
+
+2010-10-17  Alexandre Ferrieux  <ferrieux@users.sourceforge.net>
+
+	* doc/info.n:            [Patch 2995655]:
+	* generic/tclBasic.c:    Report inner contexts in [info errorstack]
+	* generic/tclCompCmds.c:
+	* generic/tclCompile.c:
+	* generic/tclCompile.h:
+	* generic/tclExecute.c:
+	* generic/tclInt.h:
+	* generic/tclNamesp.c:
+	* tests/error.test:
+	* tests/result.test:
+
+2010-10-20  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclCompCmds.c (TclCompileDictForCmd): Update the compilation
+	* generic/tclCompile.c (tclInstructionTable):	of [dict for] so that
+	* generic/tclExecute.c (TEBCresume):		it no longer makes any
+	use of INST_DICT_DONE now that's not needed, and make it clearer in
+	the implementation of the instruction that it's just a deprecated form
+	of unset operation. Followup to my commit of 2010-10-16.
+
+2010-10-19  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclZlib.c (Tcl_ZlibStreamGet): [Bug 3081008]: Ensure that
+	when a bytearray gets its internals entangled with zlib for more than
+	a passing moment, that bytearray will never be shimmered away. This
+	increases the amount of copying but is simple to get right, which is a
+	reasonable trade-off.
+
+	* generic/tclStringObj.c (Tcl_AppendObjToObj): Added some special
+	cases so that most of the time when you build up a bytearray by
+	appending, it actually ends up being a bytearray rather than
+	shimmering back and forth to string.
+
+	* tests/http11.test (check_crc): Use a simpler way to express the
+	functionality of this procedure.
+
+	* generic/tclZlib.c: Purge code that wrote to the object returned by
+	Tcl_GetObjResult, as we don't want to do that anti-pattern no more.
+
+2010-10-18  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* tools/uniParse.tcl:   [Bug 3085863]: tclUniData was 9 years old;
+	Ignore non-BMP characters and fix comment about UnicodeData.txt file.
+	* generic/regcomp.c:    Fix comment
+	* tests/utf.test:       Add some Unicode 6 testcases
+
+2010-10-17  Alexandre Ferrieux  <ferrieux@users.sourceforge.net>
+
+	* doc/info.n:           Document [info errorstack] faithfully.
+
+2010-10-16  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclExecute.c (ReleaseDictIterator): Factored out the release
+	of the bytecode-level dictionary iterator information so that the
+	side-conditions on instruction issuing are simpler.
+
+2010-10-15  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/reg_locale.c: [Bug 3085863]: tclUniData 9 years old: Updated
+	* generic/tclUniData.c: Unicode tables to latest UnicodeData.txt,
+	* tools/uniParse.tcl:   corresponding with Unicode 6.0 (except for
+				out-of-range chars > 0xFFFF)
+
+2010-10-13  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclCompile.c:	Alternative fix for [Bugs 467523,983660] where
+	* generic/tclExecute.c:	sharing of empty scripts is allowed again.
+
+2010-10-13  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* win/tclWinThrd.h: (removed) because it is just empty en used nowhere
+	* win/tcl.dsp
+
+2010-10-12  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* tools/uniClass.tcl:    Spacing and comments: let uniClass.tcl
+	* generic/regc_locale.c: generation match better the current
+				 (hand-modified) regc_locale.c
+	* tools/uniParse.tcl:    Generate proper const qualifiers for
+	* generic/tclUniData.c:  tclUniData.c
+
+2010-10-12  Reinhard Max  <max@suse.de>
+
+	* unix/tclUnixSock.c (CreateClientSocket): [Bug 3084338]: Fix a
+	memleak and refactor the calls to freeaddrinfo().
+
+2010-10-11  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* win/tclWinDde.c:    [FRQ 2965056]: Windows build with -DUNICODE
+	* win/tclWinReg.c:
+	* win/tclWinTest.c:   More cleanups
+	* win/tclWinFile.c:   Add netapi32 to the link line, so we no longer
+	* win/tcl.m4:         have to use LoadLibrary to access those
+			      functions.
+	* win/makefile.vc:
+	* win/configure:      (Re-generate with autoconf-2.59)
+	* win/rules.vc        Update for VS10
+
+2010-10-09  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclExecute.c: Fix overallocation of exec stack in TEBC (due
+	to mixing numwords and numbytes)
+
+2010-10-08  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tclIOSock.c: On Windows, use gai_strerrorA
+
+2010-10-06  Don Porter  <dgp@users.sourceforge.net>
+
+	* tests/winPipe.test:	Test hygiene with makeFile and removeFile.
+
+	* generic/tclCompile.c:	[Bug 3081065]: Prevent writing to the intrep
+	* tests/subst.test:	fields of a freed Tcl_Obj.
+
+2010-10-06  Kevin B. Kenny  <kennykb@acm.org>
+
+	[dogeen-assembler-branch]
+
+	* generic/tclAssembly.c:
+	* generic/tclAssembly.h:
+	* tests/assemble.test: Added catches. Still needs a lot of testing.
+
+2010-10-02  Kevin B. Kenny  <kennykb@acm.org>
+
+	[dogeen-assembler-branch]
+
+	* generic/tclAssembly.c:
+	* generic/tclAssembly.h:
+	* tests/assemble.test: Added dictAppend, dictIncrImm, dictLappend,
+	dictSet, dictUnset, nop, regexp, nsupvar, upvar, and variable.
+
+2010-10-02  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclExecute.c (TEBCresume): [Bug 3079830]: Added invalidation
+	of string representations of dictionaries in some cases.
+
+2010-10-01  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* generic/tclExecute.c (EvalStatsCmd): change 'evalstats' to return
+	data to interp by default, or if given an arg, use that as filename to
+	output to (accepts 'stdout' and 'stderr').  Fix output to print used
+	inst count data.
+	* generic/tclCkalloc.c: Change TclDumpMemoryInfo sig to allow objPtr
+	* generic/tclInt.decls: as well as FILE* as output.
+	* generic/tclIntDecls.h:
+
+2010-10-01  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclBasic.c, generic/tclClock.c, generic/tclEncoding.c,
+	* generic/tclEnv.c, generic/tclLoad.c, generic/tclNamesp.c,
+	* generic/tclObj.c, generic/tclRegexp.c, generic/tclResolve.c,
+	* generic/tclResult.c, generic/tclUtil.c, macosx/tclMacOSXFCmd.c:
+	More purging of strcpy() from locations where we already know the
+	length of the data being copied.
+
+2010-10-01  Kevin B. Kenny  <kennykb@acm.org>
+
+	[dogeen-assembler-branch]
+
+	* tests/assemble.test:
+	* generic/tclAssemble.h:
+	* generic/tclAssemble.c:  Added listIn, listNotIn, and dictGet.
+
+2010-09-30  Kevin B. Kenny  <kennykb@acm.org>
+
+	[dogeen-assembler-branch]
+
+	* tests/assemble.test:   Added tryCvtToNumeric and several more list
+	* generic/tclAssemble.c: operations.
+	* generic/tclAssemble.h:
+
+2010-09-29  Kevin B. Kenny  <kennykb@acm.org>
+
+	[dogeen-assembler-branch]
+
+	* tests/assemble.test:   Completed conversion of tests to a
+	* generic/tclAssemble.c: "white box" structure that follows the
+	C code. Added missing safety checks on the operands of 'over' and
+	'reverse' so that negative operand counts don't smash the stack.
+
+2010-09-29  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* unix/configure:	Re-generate with autoconf-2.59
+	* win/configure:
+	* generic/tclMain.c:	Make compilable with -DUNICODE as well
+
+2010-09-28  Reinhard Max  <max@suse.de>
+
+	TIP #162 IMPLEMENTATION
+
+	* doc/socket.n:		Document the changes to the [socket] and
+				[fconfigure] commands.
+
+	* generic/tclInt.h:	Introduce TclCreateSocketAddress() as a
+	* generic/tclIOSock.c:	replacement for the platform-dependent
+	* unix/tclUnixSock.c:	TclpCreateSocketAddress() functions. Extend
+	* unix/tclUnixChan.c:	the [socket] and [fconfigure] commands to
+	* unix/tclUnixPort.h:	behave as proposed in TIP #162. This is the
+	* win/tclWinSock.c:	core of what is required to support the use of
+	* win/tclWinPort.h:	IPv6 sockets in Tcl.
+
+	* compat/fake-rfc2553.c: A compat implementation of the APIs defined
+	* compat/fake-rfc2553.h: in RFC-2553 (getaddrinfo() and friends) on
+				 top of the existing gethostbyname() etc.
+	* unix/configure.in:	 Test whether the fake-implementation is
+	* unix/tcl.m4:		 needed.
+	* unix/Makefile.in:	 Add a compile target for fake-rfc2553.
+
+	* win/configure.in:	Allow cross-compilation by default.
+
+	* tests/socket.test:	Improve the test suite to make more use of
+	* tests/remote.tcl:	randomized ports to reduce interference with
+				tests running in parallel or other services on
+				the machine.
+
+2010-09-28  Kevin B. Kenny  <kennykb@acm.org>
+
+	[dogeen-assembler-branch]
+
+	* tests/assemble.test: Added more "white box" tests.
+	* generic/tclAssembly.c: Added the error checking and reporting
+	for undefined labels. Revised code so that no pointers into the
+	bytecode sequence are held (because the sequence can move!),
+	that no Tcl_HashEntry pointers are held (because the hash table
+	doesn't guarantee their stability!) and to eliminate the BBHash
+	table, which is merely additional information indexed by jump
+	labels and can just as easily be held in the 'label' structure.
+	Renamed shared structures to CamelCase, and renamed 'label' to
+	JumpLabel because other types of labels may eventually be possible.
+
+2010-09-27  Kevin B. Kenny  <kennykb@acm.org>
+
+	[dogeen-assembler-branch]
+
+	* tests/assemble.test: Added more "white box" tests.
+	* generic/tclAssembly.c: Fixed bugs exposed by the new tests.
+	(a) [eval] and [expr] had incorrect stack balance computed if
+	the arg was not a simple word. (b) [concat] accepted a negative
+	operand count. (c) [invoke] accepted a zero or negative operand
+	count. (d) more misspelt error messages.
+	Also replaced a funky NRCallTEBC with the new call
+	TclNRExecuteByteCode, necessitated by a merge with changes on the
+	HEAD.
+
+2010-09-26  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclBasic.c:    [Patch 3072080] (minus the itcl
+	* generic/tclCmdIL.c:    update): a saner NRE.
+	* generic/tclCompExpr.c:
+	* generic/tclCompile.c:  This makes TclNRExecuteByteCode (ex TEBC)
+	* generic/tclCompile.h:  to be a normal NRE citizen: it loses its
+	* generic/tclExecute.c:  special status.
+	* generic/tclInt.decls:  The logic flow within the BC engine is
+	* generic/tclInt.h:      simplified considerably.
+	* generic/tclIntDecls.h:
+	* generic/tclObj.c:
+	* generic/tclProc.c:
+	* generic/tclTest.c:
+
+	* generic/tclVar.c: Use the macro HasLocalVars everywhere
+
+2010-09-26  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclOOMethod.c (ProcedureMethodVarResolver): avoid code
+	duplication, let the runtime var resolver call the compiled var
+	resolver.
+
+2010-09-26  Kevin B. Kenny  <kennykb@acm.org>
+
+	[dogeen-assembler-branch]
+
+	* tests/assemble.test:	Added many new tests moving toward a more
+	comprehensive test suite for the assembler.
+	* generic/tclAssembly.c:	Fixed bugs exposed by the new tests:
+	(a) [bitnot] and [not] had incorrect operand counts. (b)
+	INST_CONCAT cannot concatenate zero objects. (c) misspelt error
+	messages. (d) the "assembly code" internal representation lacked
+	a duplicator, which caused double-frees of the Bytecode object
+	if assembly code ever was duplicated.
+
+2010-09-25  Kevin B. Kenny   <kennykb@acm.org>
+
+	[dogeen-assembler-branch]
+
+	* generic/tclAssembly.c:	Massive refactoring of the assembler
+	* generic/tclAssembly.h:	to use a Tcl-like syntax (and use
+	* tests/assemble.test:		Tcl_ParseCommand to parse it). The
+	* tests/assemble1.bench:	refactoring also ensures that
+	Tcl_Tokens in the assembler have string ranges inside the source
+	code, which allows for [eval] and [expr] assembler directives
+	that simply call TclCompileScript and TclCompileExpr recursively.
+
+2010-09-24  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* tests/stringComp.test: improved string eq/cmp test coverage
+	* generic/tclExecute.c (TclExecuteByteCode): merge INST_STR_CMP and
+	INST_STR_EQ/INST_STR_NEQ paths.  Speeds up eq/ne/[string eq] with
+	obj-aware comparisons and eq/==/ne/!= with length equality check.
+
+2010-09-24  Andreas Kupries  <andreask@activestate.com>
+
+	* tclWinsock.c: [Bug 3056775]: Fixed race condition between thread and
+	internal co-thread access of a socket's structure because of the
+	thread not using the socketListLock in TcpAccept(). Added
+	documentation on how the module works to the top.
+
+2010-09-23  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tclDecls.h: Make Tcl_SetPanicProc and Tcl_GetStringResult
+	* unix/tclAppInit.c:  callable without stubs, just as Tcl_SetVar.
+	* win/tclAppInit.c:
+
+2010-09-23  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclCmdAH.c:   Fix cases where value returned by
+	* generic/tclEvent.c:   Tcl_GetReturnOptions() was leaked.
+	* generic/tclMain.c:    Thanks to Jeff Hobbs for discovery of the
+	anti-pattern to seek and destroy.
+
+2010-09-23  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* unix/tclAppInit.c:  Make compilable with -DUNICODE (not activated
+	* win/tclAppInit.c:   yet), many clean-ups in comments.
+
+2010-09-22  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclExecute: [Bug 3072640]: One more DECACHE_STACK_INFO() was
+	missing.
+
+	* tests/execute.test: Added execute-10.3 for [Bug 3072640]. The test
+	causes a mem failure.
+
+	* generic/tclExecute: Protect all possible writes to ::errorInfo or
+	::errorCode with DECACHE_STACK_INFO(), as they could run traces. The
+	new calls to be protected are Tcl_ResetResult(), Tcl_SetErrorCode(),
+	IllegalExprOperandType(), TclExprFloatError(). The error was triggered
+	by [Patch 3072080].
+
+2010-09-22  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* win/tcl.m4:		Add kernel32 to LIBS, so the link line for
+	* win/configure:	mingw is exactly the same as for MSVC++.
+
+2010-09-21  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* generic/tclExecute.c (TclExecuteByteCode):
+	* generic/tclOOMethod.c (ProcedureMethodCompiledVarConnect):
+	* generic/tclVar.c (TclLookupSimpleVar, CompareVarKeys):
+	* generic/tclPathObj.c (Tcl_FSGetNormalizedPath, Tcl_FSEqualPaths):
+	* generic/tclIOUtil.c (TclFSCwdPointerEquals): peephole opt
+	* generic/tclResult.c (TclMergeReturnOptions): Use memcmp where
+	applicable as possible speedup on some libc variants.
+
+2010-09-21  Kevin B. Kenny  <kennykb@acm.org>
+
+	[BRANCH: dogeen-assembler-branch]
+
+	* generic/tclAssembly.c (new file):
+	* generic/tclAssembly.h:
+	* generic/tclBasic.c (builtInCmds, Tcl_CreateInterp):
+	* generic/tclInt.h:
+	* tests/assemble.test (new file):
+	* tests/assemble1.bench (new file):
+	* unix/Makefile.in:
+	* win/Makefile.in:
+	* win/Makefile.vc:
+		Initial commit of Ozgur Dogan Ugurlu's (SF user: dogeen)
+		assembler for the Tcl bytecode language.
+
+2010-09-21  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* win/tclWinFile.c:   Fix declaration after statement.
+	* win/tcl.m4:         Add -Wdeclaration-after-statement, so this
+	* win/configure:      mistake cannot happen again.
+	* win/tclWinFCmd.c:   [Bug 3069278]: Breakage on head Windows
+	* win/tclWinPipe.c:   triggered by install-tzdata, final fix
+
+2010-09-20  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* win/tclWinFCmd.c: Eliminate tclWinProcs->useWide everywhere, since
+	* win/tclWinFile.c: the value is always "1" on platforms >win95
+	* win/tclWinPipe.c:
+
+2010-09-19  Donal K. Fellows  <dkf@users.sf.net>
+
+	* doc/file.n (file readlink): [Bug 3070580]: Typofix.
+
+2010-09-18  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* win/tclWinFCmd.c [Bug 3069278]: Breakage on head Windows triggered
+	by install-tzdata. Temporary don't compile this with -DUNICODE, while
+	investigating this bug.
+
+2010-09-16  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* win/tclWinFile.c: Remove define of FINDEX_INFO_LEVELS as all
+	supported versions of compilers should now have it.
+
+	* unix/Makefile.in: Do not pass current build env vars when using
+	NATIVE_TCLSH in targets.
+
+2010-09-16  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tclDecls.h:    Make Tcl_FindExecutable() work in UNICODE
+	* generic/tclEncoding.c: compiles (windows-only) as well as ASCII.
+	* generic/tclStubInit.c: Needed for [FRQ 491789]: setargv() doesn't
+	support a unicode cmdline.
+
+2010-09-15  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclBinary.c (TclAppendBytesToByteArray): [Bug 3067036]: Make
+	sure we never try to double zero repeatedly to get a buffer size. Also
+	added a check for sanity on the size of buffer being appended.
+
+2010-09-15  Don Porter  <dgp@users.sourceforge.net>
+
+	* unix/Makefile.in:	Revise `make dist` target to tolerate the
+	case of zero bundled packages.
+
+2010-09-15  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* tools/genStubs.tcl:   [Patch 3034251]: Backport ttkGenStubs.tcl
+	* generic/tcl.decls:    features to genStubs.tcl. Make the "generic"
+	* generic/tclInt.decls: argument in the *.decls files optional
+	* generic/tclOO.decls:  (no change to any tcl*Decls.h files)
+	* generic/tclTomMath.decls:
+	This allows genStubs.tcl to generate the ttk stub files as well, while
+	keeping full compatibility with existing *.decls files.
+
+2010-09-14  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* win/tclWinPort.h:  Allow all Win2000+ API entries in Tcl
+	* win/tclWin32Dll.c: Eliminate dynamical loading of advapi23 and
+	kernel32 symbols.
+
+2010-09-13  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* win/tclWinChan.c:      Various clean-ups, converting from
+	* win/tclWinConsole.c:   tclWinProc->xxxProc directly to Xxx
+	* win/tclWinInit.c:      (no change in functionality)
+	* win/tclWinLoad.c:
+	* win/tclWinSerial.c:
+	* win/tclWinSock.c:
+	* tools/genStubs.tcl:    Add scspec feature from ttkGenStubs.tcl
+	  (no change in output for *Decls.h files)
+
+2010-09-10  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* win/tclWin32Dll.c: Partly revert yesterday's change, to make it work
+	on VC++ 6.0 again.
+
+2010-09-10  Donal K. Fellows  <dkf@users.sf.net>
+
+	* doc/regsub.n: [Bug 3063568]: Fix for gotcha in example due to Tcl's
+	special handling of backslash-newline. Makes example slightly less
+	pure, but more useful.
+
+2010-09-09  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* win/makefile.vc:   Mingw should always link with -ladvapi32.
+	* win/tcl.m4:
+	* win/configure:     (regenerated)
+	* win/tclWinInt.h:   Remove ascii variant of tkWinPocs table, it is
+	* win/tclWin32Dll.c: no longer necessary. Fix CreateProcess signature
+	* win/tclWinPipe.c:  and remove unused GetModuleFileName and lstrcpy.
+	* win/tclWinPort.h:  Mingw/cygwin fixes: <tchar.h> should always be
+	included, and fix conflict in various macro values: Always force the
+	same values as in VC++.
+
+2010-09-08  Don Porter  <dgp@users.sourceforge.net>
+
+	* win/tclWinChan.c:	[Bug 3059922]: #ifdef protections to permit
+	* win/tclWinFCmd.c:     builds with mingw on amd64 systems. Thanks to
+				"mescalinum" for reporting and testing.
+
+2010-09-08  Andreas Kupries  <andreask@activestate.com>
+
+	* doc/tm.n: Added underscore to the set of characters accepted in
+	module names. This is true for quite some time in the code, this
+	change catches up the documentation.
+
+2010-09-03  Donal K. Fellows  <dkf@users.sf.net>
+
+	* tools/tcltk-man2html.tcl (plus-pkgs): Improve the package
+	documentation search pattern to support the doctoos-generated
+	directory structure.
+	* tools/tcltk-man2html-utils.tcl (output-name): Made this more
+	resilient against misformatted NAME sections, induced by import of
+	Thread package documentation into Tcl doc tree.
+
+2010-09-02  Andreas Kupries  <andreask@activestate.com>
+
+	* doc/glob.n: Fixed documentation ambiguity regarding the handling
+	of -join.
+
+	* library/safe.tcl (safe::AliasGlob): Fixed another problem, the
+	option -join does not stop option processing in the core builtin, so
+	the emulation must not do that either.
+
+2010-09-01  Andreas Kupries  <andreas_kupries@users.sourceforge.net>
+
+	* library/safe.tcl (safe::AliasGlob): Moved the command extending the
+	actual glob command with a -directory flag to when we actually have a
+	proper untranslated path,
+
+2010-09-01  Andreas Kupries  <andreask@activestate.com>
+
+	* generic/tclExecute.c: [Bug 3057639]: Applied patch by Jeff to make
+	* generic/tclVar.c:	the behaviour of lappend in bytecompiled mode
+	* tests/append.test:	consistent with direct-eval and 'append'
+	* tests/appendComp.test: generally. Added tests (append*-9.*)
+	showing the difference.
+
+2010-08-31  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* win/rules.vc:               Typo (thanks to Twylite discovering
+				      this)
+	* generic/tclStubLib.c:       Revert to previous version: MSVC++ 6.0
+	* generic/tclTomMathStubLib.c:cannot handle the new construct.
+	* generic/tcl.decls           [Patch 2997642]: Many type casts needed
+	* generic/tclDecls.h:         when using Tcl_Pkg* API. Remaining part.
+	* generic/tclPkg.c:
+	* generic/tclBasic.c:
+	* generic/tclTomMathInterface.c:
+	* doc/PkgRequire.3
+
+2010-08-31  Andreas Kupries  <andreask@activestate.com>
+
+	* win/tcl.m4: Applied patch by Jeff fixing issues with the manifest
+	handling on Win64.
+	* win/configure: Regenerated.
+
+2010-08-30  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclBasic.c:    [Bugs 3046594,3047235,3048771]: New
+	* generic/tclCmdAH.c:    implementation for [tailcall] command: it now
+	* generic/tclCmdMZ.c:    schedules the command and returns TCL_RETURN.
+	* generic/tclExecute.c:  This fixes all issues with [catch] and [try].
+	* generic/tclInt.h:      Thanks dgp for exploring the dark corners.
+	* generic/tclNamesp.c:   More thorough testing is required.
+	* tests/tailcall.test:
+
+2010-08-30  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* win/Makefile.in:   [FRQ 2965056]: Windows build with -DUNICODE
+	* win/rules.vc:
+	* win/tclWinFCmd.c:  Make sure that allocated TCHAR arrays are
+	* win/tclWinFile.c:  always properly aligned as wchar_t, and
+	* win/tclWinPipe.c:  not bigger than necessary.
+	* win/tclWinSock.c:
+	* win/tclWinDde.c:   Those 3 files are not converted yet to be
+	* win/tclWinReg.c:   built with -DUNICODE, so add a TODO.
+	* win/tclWinTest.c:
+	* generic/tcl.decls:  [Patch 2997642]: Many type casts needed when
+	* generic/tclDecls.h: using Tcl_Pkg* API. Partly.
+	* generic/tclPkg.c:
+	* generic/tclStubLib.c: Demonstration how this change can benefit
+				code.
+	* generic/tclTomMathStubLib.c:
+	* doc/PkgRequire.3:
+
+2010-08-29  Donal K. Fellows  <dkf@users.sf.net>
+
+	* doc/dict.n: [Bug 3046999]: Corrected cross reference to array
+	manpage to refer to (correct) existing subcommand.
+
+2010-08-26  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* unix/configure, unix/tcl.m4: SHLIB_LD_LIBS='${LIBS}' for OSF1-V*.
+	Add /usr/lib64 to set of auto-search dirs. [Bug 1230554]
+	(SC_PATH_X): Correct syntax error when xincludes not found.
+
+	* win/Makefile.in (VC_MANIFEST_EMBED_DLL VC_MANIFEST_EMBED_EXE):
+	* win/configure, win/configure.in, win/tcl.m4: SC_EMBED_MANIFEST
+	macro and --enable-embedded-manifest configure arg added to support
+	manifest embedding where we know the magic.  Help prevents DLL hell
+	with MSVC8+.
+
+2010-08-24  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tcl.decls: [Bug 3007895]: Tcl_(Find|Create)HashEntry
+	* generic/tclHash.c: stub entries can never be called.
+	* generic/tclDecls.h:
+	* generic/tclStubInit.c: [Patch 2994165]: Change signature of
+	Tcl_FSGetNativePath and TclpDeleteFile follow-up: move stub entry back
+	to original location.
+
+2010-08-23  Kevin B. Kenny  <kennykb@acm.org>
+
+	* library/tzdata/Africa/Cairo:
+	* library/tzdata/Asia/Gaza: Olson's tzdata2010l.
+
+2010-08-22  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tclBasic.c:  [Patch 3009403]: Signature of Tcl_GetHashKey,
+	* generic/tclBinary.c: Tcl_(Create|Find)HashEntry follow-up:
+	* generic/tclCmdIL.c:  Remove many type casts which are no longer
+	* generic/tclCompile.c:necessary as a result of this signature change.
+	* generic/tclDictObj.c:
+	* generic/tclEncoding.c:
+	* generic/tclExecute.c:
+	* generic/tclInterp.c:
+	* generic/tclIOCmd.c:
+	* generic/tclObj.c:
+	* generic/tclProc.c:
+	* generic/tclTest.c:
+	* generic/tclTrace.c:
+	* generic/tclUtil.c:
+	* generic/tclVar.c:
+
+2010-08-21  Donal K. Fellows  <dkf@users.sf.net>
+
+	* doc/linsert.n: [Bug 3045123]: Make description of what is actually
+	happening more accurate.
+
+2010-08-21  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* tools/genStubs.tcl: [Patch 3034251]: Backport ttkGenStubs.tcl
+	features to genStubs.tcl, partly: Use void (*reserved$i)(void) = 0
+	instead of void *reserved$i = NULL for unused stub entries, in case
+	pointer-to-function and pointer-to-object are different sizes.
+	* generic/tcl*Decls.h:   (regenerated)
+	* generic/tcl*StubInit.c:(regenerated)
+
+2010-08-20  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* doc/Method.3:   Fix definition of Tcl_MethodType.
+
+2010-08-19  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclTrace.c (TraceExecutionObjCmd, TraceCommandObjCmd)
+	(TraceVariableObjCmd): [Patch 3048354]: Use memcpy() instead of
+	strcpy() to avoid buffer overflow; we have the correct length of data
+	to copy anyway since we've just allocated the target buffer.
+
+2010-08-18  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* tools/genStubs.tcl: [Patch 3034251]: Backport ttkGenStubs.tcl
+	features to genStubs.tcl, partly: remove unneeded ifdeffery and put
+	C++ guard around stubs pointer definition.
+	* generic/*Decls.h:   (regenerated)
+
+2010-08-18  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclBasic.c:   New redesign of [tailcall]: find
+	* generic/tclExecute.c: errors early on, so that errorInfo
+	* generic/tclInt.h:     contains the proper info [Bug 3047235]
+	* generic/tclNamesp.c:
+
+	* generic/tclCmdAH.c (TclNRTryObjCmd): [Bug 3046594]: Block
+	tailcalling out of the body of a non-bc'ed [try].
+
+	* generic/tclBasic.c:    Redesign of [tailcall] to
+	* generic/tclCmdAH.c:    (a) fix [Bug 3047235]
+	* generic/tclCompile.h:  (b) enable fix for [Bug 3046594]
+	* generic/tclExecute.c:  (c) enable recursive tailcalls
+	* generic/tclInt.h:
+	* generic/tclNamesp.c:
+	* tests/tailcall.test:
+
+2010-08-18  Donal K. Fellows  <dkf@users.sf.net>
+
+	* library/safe.tcl (AliasGlob): [Bug 3004191]: Restore safe [glob] to
+	working condition.
+
+2010-08-15  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclProc.c (ProcWrongNumArgs): [Bug 3045010]: Make the
+	handling of passing the wrong number of arguments to [apply] somewhat
+	less verbose when a lambda term is present.
+
+2010-08-14  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* compat/unicows:    Remove completely, see [FRQ 2819611].
+	* doc/FileSystem.3: [Patch 2994165]: Change signature of
+	* generic/tcl.decls  Tcl_FSGetNativePath and TclpDeleteFile
+	* generic/tclDecls.h:
+	* generic/tclIOUtil.c:
+	* generic/tclStubInit.c:
+	* generic/tclInt.h:
+	* unix/tclUnixFCmd.c:
+	* win/tclWinFCmd.c:
+	* doc/Hash.3: [Patch 3009403]: Signature of Tcl_GetHashKey,
+	* generic/tcl.h:     Tcl_(Create|Find)HashEntry
+
+2010-08-11  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* unix/ldAix: Remove ancient (pre-4.2) AIX support
+	* unix/configure: Regen with ac-2.59
+	* unix/configure.in, unix/tclConfig.sh.in, unix/Makefile.in:
+	* unix/tcl.m4 (AIX): Remove the need for ldAIX, replace with
+	-bexpall/-brtl.  Remove TCL_EXP_FILE (export file) and other baggage
+	that went with it.  Remove pre-4 AIX build support.
+
+2010-08-11  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclBasic.c (TclNRYieldToObjCmd):
+	* tests/coroutine.test: Fixed bad copypasta snafu. Thanks to Andy Goth
+	for finding the bug.
+
+2010-08-10  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* generic/tclUtil.c (TclByteArrayMatch): Patterns may not be
+	null-terminated, so account for that.
+
+2010-08-09  Don Porter  <dgp@users.sourceforge.net>
+
+	* changes:	Updates for 8.6b2 release.
+
+2010-08-04  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* win/Makefile.in, win/makefile.bc, win/makefile.vc, win/tcl.dsp:
+	* win/tclWinPipe.c (TclpCreateProcess):
+	* win/stub16.c (removed): Removed Win9x tclpip8x.dll build and 16-bit
+	application loader stub support.  Win9x is no longer supported.
+
+	* win/tclWin32Dll.c (TclWinInit): Hard-enforce Windows 9x as an
+	unsupported platform with a panic.  Code to support it still exists in
+	other files (to go away in time), but new APIs are being used that
+	don't exist on Win9x.
+
+	* unix/tclUnixFCmd.c: Adjust license header as per
+	ftp://ftp.cs.berkeley.edu/pub/4bsd/README.Impt.License.Change
+
+	* license.terms: Fix DFARs note for number-adjusted rights clause
+
+	* win/tclWin32Dll.c (asciiProcs, unicodeProcs):
+	* win/tclWinLoad.c (TclpDlopen): 'load' use LoadLibraryEx with
+	* win/tclWinInt.h (TclWinProcs): LOAD_WITH_ALTERED_SEARCH_PATH to
+	prefer dependent DLLs in same dir as loaded DLL.
+
+	* win/Makefile.in (%.${OBJEXT}): better implicit rules support
+
+2010-08-04  Andreas Kupries  <andreask@activestate.com>
+
+	* generic/tclIORChan.c: [Bug 3034840]: Fixed reference counting in
+	* generic/tclIORTrans.c: InvokeTclMethod and callers.
+	* tests/ioTrans.test:
+
+2010-08-03  Andreas Kupries  <andreask@activestate.com>
+
+	* tests/var.test (var-19.1): [Bug 3037525]: Added test demonstrating
+	the local hashtable deletion crash and fix.
+
+	* tests/info.test (info-39.1): Added forward copy of test in 8.5
+	branch about [Bug 2933089]. Should not fail, and doesn't, after
+	updating the line numbers to the changed position.
+
+2010-08-02  Kevin B. Kenny  <kennykb@users.sf.net>
+
+	* library/tzdata/America/Bahia_Banderas:
+	* library/tzdata/Pacific/Chuuk:
+	* library/tzdata/Pacific/Pohnpei:
+	* library/tzdata/Africa/Cairo:
+	* library/tzdata/Europe/Helsinki:
+	* library/tzdata/Pacific/Ponape:
+	* library/tzdata/Pacific/Truk:
+	* library/tzdata/Pacific/Yap:			Olson's tzdata2010k.
+
+2010-08-02  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclVar.c: Correcting bad port of [Bug 3037525] fix
+
+2010-07-28  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclVar.c: [Bug 3037525]: Lose fickle optimisation in
+	TclDeleteVars (used for runtime-created locals) that caused crash.
+
+2010-07-29  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* compat/zlib/win32/README.txt: Official build of zlib1.dll 1.2.5 is
+	* compat/zlib/win32/USAGE.txt:  finally available, so put it in.
+	* compat/zlib/win32/zlib1.dll:
+
+2010-07-25  Donal K. Fellows  <dkf@users.sf.net>
+
+	* doc/http.n: Corrected description of location of one of the entries
+	in the state array.
+
+2010-07-24  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tclDecls.h: [Bug 3029891]: Functions that don't belong in
+	* generic/tclTest.c:  the stub table.
+	* generic/tclBasic.c: From [Bug 3030870] make itcl 3.x built with
+	pre-8.6 work in 8.6: Relax the relation between Tcl_CallFrame and
+	CallFrame.
+
+2010-07-16  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclBasic.c: Added more errorCode setting.
+
+2010-07-15  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclExecute.c (TclExecuteByteCode): Ensure that [dict get]
+	* generic/tclDictObj.c (DictGetCmd): always generates an errorCode on
+	a failure to look up an entry.
+
+2010-07-11  Pat Thoyts  <patthoyts@users.sourceforge.net>
+
+	* unix/configure: (regenerated)
+	* unix/configure.in: For the NATIVE_TCLSH variable use the autoconf
+	* unix/Makefile.in:  SC_PROG_TCLSH to try and find a locally installed
+	native binary. This avoids manually fixing up when cross compiling. If
+	there is not one, revert to using the build product.
+
+2010-07-02  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclInt.decs:	Reverted to the original TIP 337
+	implementation on what to do with the obsolete internal stub for
+	TclBackgroundException() (eliminate it!)
+	* generic/tclIntDecls.h:	make genstubs
+	* generic/tclStubInit.c:
+
+2010-07-02  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tclInt.decls:  [Bug 803489]: Tcl_FindNamespace problem in
+	* generic/tclIntDecls.h: the Stubs table
+	* generic/tclStubInit.c:
+
+2010-07-02  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclExecute.c (IllegalExprOperandType): [Bug 3024379]: Made
+	sure that errors caused by an argument to an operator being outside
+	the domain of the operator all result in ::errorCode being ARITH
+	DOMAIN and not NONE.
+
+2010-07-01  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* win/rules.vc:              [Bug 3020677]: wish can't link reg1.2
+	* tools/checkLibraryDoc.tcl: formatting, spacing, cleanup unused
+	* tools/eolFix.tcl:          variables; no change in generated output
+	* tools/fix_tommath_h.tcl:
+	* tools/genStubs.tcl:
+	* tools/index.tcl:
+	* tools/man2help2.tcl:
+	* tools/regexpTestLib.tcl:
+	* tools/tsdPerf.tcl:
+	* tools/uniClass.tcl:
+	* tools/uniParse.tcl:
+
+2010-07-01  Donal K. Fellows  <dkf@users.sf.net>
+
+	* doc/mathop.n: [Bug 3023165]: Fix typo that was preventing proper
+	rendering of the exclusive-or operator.
+
+2010-06-28  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tclPosixStr.c: [Bug 3019634]: errno.h and tclWinPort.h have
+	conflicting definitions. Added messages for ENOTRECOVERABLE, EOTHER,
+	ECANCELED and EOWNERDEAD, and fixed various typing mistakes in other
+	messages.
+
+2010-06-25  Reinhard Max  <max@suse.de>
+
+	* tests/socket.test: Prevent a race condition during shutdown of the
+	remote test server that can cause a hang when the server is being run
+	in verbose mode.
+
+2010-06-24  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* win/tclWinPort.h: [Bug 3019634]: errno.h and tclWinPort.h have
+	conflicting definitions.
+
+		***POTENTIAL INCOMPATIBILITY***
+	On win32, the correspondence between errno and the related error
+	message, as handled by Tcl_ErrnoMsg() changes. The error message is
+	kept the same, but the corresponding errno value might change.
+
+2010-06-22  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclCmdIL.c (Tcl_LsetObjCmd): [Bug 3019351]: Corrected wrong
+	args message.
+
+2010-06-21  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* unix/tclLoadDl.c:    Eliminate various unnecessary type casts, use
+	* unix/tclLoadNext.c:  function typedefs whenever possible
+	* unix/tclUnixChan.c:
+	* unix/tclUnixFile.c:
+	* unix/tclUnixNotfy.c:
+	* unix/tclUnixSock.c:
+	* unix/tclUnixTest.c:
+	* unix/tclXtTest.c:
+	* generic/tclZlib.c:   Remove hack needed for zlib 1.2.3 on win32
+
+2010-06-18  Donal K. Fellows  <dkf@users.sf.net>
+
+	* library/init.tcl (auto_execok): [Bug 3017997]: Add .cmd to the
+	default list of extensions that we can execute interactively.
+
+2010-06-16  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* tools/loadICU.tcl:   [Bug 3016135]: Traceback using clock format
+	* library/msgs/he.msg: with locale of he_IL.
+
+	* generic/tcl.h:       Simplify Tcl_AppInit and *_Init definitions,
+	* generic/tclInt.h:    spacing. Change TclpThreadCreate and
+	* generic/tcl.decls:   Tcl_CreateThread signature, making clear that
+	* generic/tclDecls.h:  "proc" is a function pointer, as in all other
+	* generic/tclEvent.c:  "proc" function parameters.
+	* generic/tclTestProcBodyObj.c:
+	* win/tclWinThrd.c:
+	* unix/tclUnixThrd.c:
+	* doc/Thread.3:
+	* doc/Class.3:         Fix Tcl_ObjectMetadataType definition.
+
+2010-06-14  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* unix/Makefile.in:    Fix compilation of xttest with 8.6 changes
+	* unix/tclXtNotify.c:
+	* unix/tclXtTest.c:
+	* generic/tclPipe.c:   Fix gcc warning (with -fstrict-aliasing=2)
+	* library/auto.tcl:    Spacing and style fixes.
+	* library/history.tcl:
+	* library/init.tcl:
+	* library/package.tcl:
+	* library/safe.tcl:
+	* library/tm.tcl:
+
+2010-06-13  Donal K. Fellows  <dkf@users.sf.net>
+
+	* tools/tcltk-man2html.tcl (make-man-pages): [Bug 3015327]: Make the
+	title of a manual page be stored relative to its resulting directory
+	name as well as its source filename. This was caused by both Tcl and a
+	contributed package ([incr Tcl]) defining an Object.3. Also corrected
+	the joining of strings in titles to avoid extra braces.
+
+2010-06-09  Andreas Kupries  <andreask@activestate.com>
+
+	* library/platform/platform.tcl: Added OSX Intel 64bit
+	* library/platform/pkgIndex.tcl: Package updated to version 1.0.9.
+	* unix/Makefile.in:
+	* win/Makefile.in:
+
+2010-06-09  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* tools/tsdPerf.c:    Fix export of symbol Tsdperf_Init, when using
+	-fvisibility=hidden. Make two functions static, eliminate some
+	unnecessary type casts.
+	* tools/configure.in: Update to Tcl 8.6
+	* tools/configure:    (regenerated)
+	* tools/.cvsignore    new file
+
+2010-06-07  Alexandre Ferrieux  <ferrieux@users.sourceforge.net>
+
+	* generic/tclExecute.c: Ensure proper reset of [info errorstack] even
+	* generic/tclNamesp.c:  when compiling constant expr's with errors.
+
+2010-06-05  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclBasic.c:   [Bug 3008307]: make callerPtr chains be
+	* generic/tclExecute.c: traversable accross coro boundaries. Add the
+	special coroutine CallFrame (partially reverting commit of
+	2009-12-10), as it is needed for coroutines that do not push a CF, eg,
+	those with [eval] as command. Thanks to Colin McCormack (coldstore)
+	and Alexandre Ferrieux for the hard work on this.
+
+2010-06-03  Alexandre Ferrieux  <ferrieux@users.sourceforge.net>
+
+	* generic/tclNamesp.c: Safer (and faster) computation of [uplevel]
+	* tests/error.test:    offsets in TIP 348. Toplevel offsets no longer
+	* tests/result.test:   overestimated.
+
+2010-06-02  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tclOO.h:  BUILD_tcloo is never defined (leftover)
+	* win/makefile.bc:  Don't set BUILD_tcloo (leftover)
+	See also entry below: 2008-06-01  Joe Mistachkin
+
+2010-06-01  Alexandre Ferrieux  <ferrieux@users.sourceforge.net>
+
+	* generic/tclNamesp.c: Fix computation of [uplevel] offsets in TIP 348
+	* tests/error.test:    Only depend on callerPtr chaining now.
+	* tests/result.test:   Needed for upcoming coro patch.
+
+2010-05-31  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tclVar.c:        Eliminate some casts to (Tcl_HashTable *)
+	* generic/tclExecute.c:
+	* tests/fileSystem.test:   Fix filesystem-5.1 test failure on CYGWIN
+
+2010-05-28  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tclInt.h: [Patch 3008541]: Order of TIP #348 fields in
+	Interp structure
+
+2010-05-28  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclCompCmdsSZ.c (IssueTryFinallyInstructions): [3007374]:
+	Corrected error in handling of catch contexts to prevent crash with
+	chained handlers.
+
+	* generic/tclExecute.c (TclExecuteByteCode): Restore correct operation
+	of instruction-level execution tracing (had been broken by NRE).
+
+2010-05-27  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* library/opt/optParse.tcl: Don't generate spaces at the end of a
+	* library/opt/pkgIndex.tcl: line, eliminate ';' at line end, bump to
+	* tools/uniParse.tcl:       v0.4.6
+	* generic/tclUniData.c:
+	* tests/opt.test:
+	* tests/safe.test:
+
+2010-05-21  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* tools/installData.tcl: Make sure that copyDir only receives
+	normalized paths, otherwise it might result in a crash on CYGWIN.
+	Restyle according to the Tcl style guide.
+	* generic/tclStrToD.c: [Bug 3005233]: Fix for build on OpenBSD vax
+
+2010-05-19  Alexandre Ferrieux  <ferrieux@users.sourceforge.net>
+
+	* tests/dict.test: Add missing tests for [Bug 3004007], fixed under
+	the radar on 2010-02-24 (dkf): EIAS violation in list-dict conversions
+
+2010-05-19  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/regcomp.c:     Don't use arrays of length 1, just use a
+	* generic/tclFileName.c: single element then, it makes code more
+	* generic/tclLoad.c:     readable. (Here it even prevents a type cast)
+
+2010-05-17  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tclStrToD.c: [Bug 2996549]: Failure in expr.test on Win32
+
+2010-05-17  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclCmdIL.c (TclInfoFrame): Change this code to use
+	Tcl_GetCommandFullName rather than rolling its own. Discovered during
+	the hunting of [Bug 3001438] but unlikely to be a fix.
+
+2010-05-11  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* win/tclWinConsole.c: [Patch 2997087]: Unnecessary type casts.
+	* win/tclWinDde.c:
+	* win/tclWinLoad.c:
+	* win/tclWinNotify.c:
+	* win/tclWinSerial.c:
+	* win/tclWinSock.c:
+	* win/tclWinTime.c:
+	* win/tclWinPort.h: Don't duplicate CYGWIN timezone #define from
+			    tclPort.h
+
+2010-05-07  Andreas Kupries  <andreask@activestate.com>
+
+	* library/platform/platform.tcl: Fix cpu name for Solaris/Intel 64bit.
+	* library/platform/pkgIndex.tcl: Package updated to version 1.0.8.
+	* unix/Makefile.in:
+	* win/Makefile.in:
+
+2010-05-06  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tclPkg.c:   Unnecessary type casts, see [Patch 2997087]
+
+2010-05-04  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* win/tclWinNotify.c:	TCHAR-related fixes, making those two files
+	* win/tclWinSock.c:	compile fine when TCHAR != char. Please see
+	comments in [FRQ 2965056] (2965056-1.patch).
+
+2010-05-03  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tclIORChan.c:   Use "tclIO.h" and "tclTomMathDecls.h"
+	* generic/tclIORTrans.c:  everywhere
+	* generic/tclTomMath.h:
+	* tools/fix_tommath_h.tcl:
+	* libtommath/tommath.h:   Formatting (# should always be first char on
+				  line)
+	* win/tclAppInit.c:       For MINGW/CYGWIN, use GetCommandLineA
+				  explicitly.
+	* unix/.cvsignore:        Add pkg, *.dll
+
+	* libtommath/tommath.h:       CONSTify various useful internal
+	* libtommath/bn_mp_cmp_d.c:   functions (TclBignumToDouble, TclCeil,
+	* libtommath/bn_mp_cmp_mag.c: TclFloor), and related tommath functions
+	* libtommath/bn_mp_cmp.c:
+	* libtommath/bn_mp_copy.c:
+	* libtommath/bn_mp_count_bits.c:
+	* libtommath/bn_mp_div_2d.c:
+	* libtommath/bn_mp_mod_2d.c:
+	* libtommath/bn_mp_mul_2d.c:
+	* libtommath/bn_mp_neg.c:
+	* generic/tclBasic.c:        Handle TODO: const correctness ?
+	* generic/tclInt.h:
+	* generic/tclStrToD.c:
+	* generic/tclTomMath.decls:
+	* generic/tclTomMath.h:
+	* generic/tclTomMathDecls.h:
+
+2010-04-30  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tcl.h:	Bump patchlevel to 8.6b1.2 to distinguish
+	* library/init.tcl:	CVS snapshots from earlier snapshots as well
+	* unix/configure.in:	as the 8.6b1 and 8.6b2 releases.
+	* win/configure.in:
+
+	* unix/configure:	autoconf-2.59
+	* win/configure:
+
+	* generic/tclBinary.c (TclAppendBytesToByteArray):	Add comments
+	* generic/tclInt.h (TclAppendBytesToByteArray):	placing overflow
+	protection responsibility on caller.  Convert "len" argument to signed
+	int which any value already vetted for overflow issues will fit into.
+	* generic/tclStringObj.c:	Update caller; standardize panic msg.
+
+	* generic/tclBinary.c (UpdateStringOfByteArray): [Bug 2994924]:	Add
+	panic when the generated string representation would grow beyond Tcl's
+	size limits.
+
+2010-04-30  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclBinary.c (TclAppendBytesToByteArray): Add extra armour
+	against buffer overflows.
+
+	* generic/tclBasic.c (NRInterpCoroutine): Corrected handling of
+	* tests/coroutine.test (coroutine-6.4):   arguments to deal with
+						  trickier cases.
+
+2010-04-30  Miguel Sofer  <msofer@users.sf.net>
+
+	* tests/coroutine.test: testing coroutine arguments after [yield]:
+	check that only 0/1 allowed
+
+2010-04-30  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclBasic.c (NRInterpCoroutine): Corrected handling of
+	arguments to deal with trickier cases.
+
+	* generic/tclCompCmds.c (TclCompileVariableCmd): Slightly tighter
+	issuing of instructions.
+
+	* generic/tclExecute.c (TclExecuteByteCode): Add peephole optimization
+	of the fact that INST_DICT_FIRST and INST_DICT_NEXT always have a
+	conditional jump afterwards.
+
+	* generic/tclBasic.c (TclNRYieldObjCmd, TclNRYieldmObjCmd)
+	(NRInterpCoroutine): Replace magic values for formal argument counts
+	for coroutine command implementations with #defines, for an increase
+	in readability.
+
+2010-04-30  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tclMain.c: Unnecessary TCL_STORAGE_CLASS re-definition. It
+	was used for an ancient dummy reference to Tcl_LinkVar(), but that's
+	already gone since 2002-05-29.
+
+2010-04-29  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclCompExpr.c: Slight change in the literal sharing
+	* generic/tclCompile.c:  mechanism to avoid shimmering of
+	* generic/tclCompile.h:  command names.
+	* generic/tclLiteral.c:
+
+2010-04-29  Andreas Kupries  <andreask@activestate.com>
+
+	* library/platform/platform.tcl: Another stab at getting the /lib,
+	* library/platform/pkgIndex.tcl: /lib64 difference right for linux.
+	* unix/Makefile.in:		 Package updated to version 1.0.7.
+	* win/Makefile.in:
+
+2010-04-29  Kevin B. Kenny  <kennykb@acm.org>
+
+	* library/tzdata/Antarctica/Macquarie:
+	* library/tzdata/Africa/Casablanca:
+	* library/tzdata/Africa/Tunis:
+	* library/tzdata/America/Santiago:
+	* library/tzdata/America/Argentina/San_Luis:
+	* library/tzdata/Antarctica/Casey:
+	* library/tzdata/Antarctica/Davis:
+	* library/tzdata/Asia/Anadyr:
+	* library/tzdata/Asia/Damascus:
+	* library/tzdata/Asia/Dhaka:
+	* library/tzdata/Asia/Gaza:
+	* library/tzdata/Asia/Kamchatka:
+	* library/tzdata/Asia/Karachi:
+	* library/tzdata/Asia/Taipei:
+	* library/tzdata/Europe/Samara:
+	* library/tzdata/Pacific/Apia:
+	* library/tzdata/Pacific/Easter:
+	* library/tzdata/Pacific/Fiji:   Olson's tzdata2010i.
+
+2010-04-29  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclBinary.c (TclAppendBytesToByteArray): [Bug 2992970]: Make
+	* generic/tclStringObj.c (Tcl_AppendObjToObj): an append of a byte
+	array to another into an efficent operation. The problem was the (lack
+	of) a proper growth management strategy for the byte array.
+
+2010-04-29  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* compat/dirent2.h:	Include "tcl.h", not <tcl.h>, like everywhere
+	* compat/dlfcn.h:	else, to ensure that the version in the Tcl
+	* compat/stdlib.h:	distribution is used, not some version from
+	* compat/string.h:	somewhere else.
+	* compat/unistd.h:
+
+2010-04-28  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* win/Makefile.in:	Remove unused @MAN2TCLFLAGS@
+	* win/tclWinPort.h:	Move <limits.h> include from tclInt.h to
+	* generic/tclInt.h:	tclWinPort.h, and eliminate unneeded
+	* generic/tclEnv.c:	<stdlib.h>, <stdio.h> and <string.h>, which
+				are already in tclInt.h
+	* generic/regcustom.h:	Move "tclInt.h" from regcustom.h up to
+	* generic/regex.h:	regex.h.
+	* generic/tclAlloc.c:	Unneeded <stdio.h> include.
+	* generic/tclExecute.c:	Fix gcc warning: comparison between signed and
+				unsigned.
+
+2010-04-28  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclInt.h (TclIsVarDirectUnsettable): Corrected flags so that
+	deletion of traces is not optimized out...
+
+	* generic/tclExecute.c (ExecuteExtendedBinaryMathOp)
+	(TclCompareTwoNumbers,ExecuteExtendedUnaryMathOp,TclExecuteByteCode):
+	[Patch 2981677]: Move the less common arithmetic operations (i.e.,
+	exponentiation and operations on non-longs) out of TEBC for a big drop
+	in the overall size of the stack frame for most code. Net effect on
+	speed is minimal (slightly faster overall in tclbench). Also extended
+	the number of places where TRESULT handling is replaced with a jump to
+	dedicated code.
+
+2010-04-27  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclExecute.c (TclExecuteByteCode): Rearrange location of an
+	assignment to shorten the object code.
+
+2010-04-27  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tclIOUtil.c (Tcl_FSGetNativePath): [Bug 2992292]:
+	tclIOUtil.c assignment type mismatch compiler warning
+	* generic/regguts.h:     If tclInt.h or tclPort.h is already
+	* generic/tclBasic.c:    included, don't include <limits.h>
+	* generic/tclExecute.c:  again. Follow-up to [Bug 2991415]:
+	* generic/tclIORChan.c:  tclport.h #included before limits.h
+	* generic/tclIORTrans.c: See comments in [Bug 2991415]
+	* generic/tclObj.c:
+	* generic/tclOOInt.h:
+	* generic/tclStrToD.c:
+	* generic/tclTomMath.h:
+	* generic/tclTomMathInterface.c:
+	* generic/tclUtil.c:
+	* compat/strtod.c:
+	* compat/strtol.c:
+
+2010-04-27  Kevin B. Kenny  <kennykb@acm.org>
+
+	* unix/tclLoadDl.c (FindSymbol): [Bug 2992295]: Simplified the logic
+	so that the casts added in Donal Fellows's change for the same bug are
+	no longer necessary.
+
+2010-04-26  Donal K. Fellows  <dkf@users.sf.net>
+
+	* unix/tclLoadDl.c (FindSymbol): [Bug 2992295]: Added an explicit cast
+	because auto-casting between function and non-function types is never
+	naturally warning-free.
+
+	* generic/tclStubInit.c:   Add a small amount of gcc-isms (with #ifdef
+	* generic/tclOOStubInit.c: guards) to ensure that warnings are issued
+	when these files are older than the various *.decls files.
+
+2010-04-25  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclBasic.c:    Add unsupported [yieldm] command. Credit
+	* generic/tclInt.h:      Lars Hellstrom for the basic idea.
+
+2010-04-24  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclBasic.c:    Modify api of TclSpliceTailcall() to fix
+	* generic/tclExecute.c:  [yieldTo], which had not survived the latest
+	* generic/tclInt.h:      mods to tailcall. Thanks kbk for detecting
+	the problem.
+
+2010-04-23  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* unix/tclUnixPort.h: [Bug 2991415]: tclport.h #included before
+	limits.h
+
+2010-04-22  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tclPlatDecls.h:  Move TCHAR fallback typedef from tcl.h to
+	* generic/tcl.h:           tclPlatDecls.h (as suggested by dgp)
+	* generic/tclInt.h:        fix typo
+	* generic/tclIOUtil.c:     Eliminate various unnecessary
+	* unix/tclUnixFile.c:      type casts.
+	* unix/tclUnixPipe.c:
+	* win/tclWinChan.c:
+	* win/tclWinFCmd.c:
+	* win/tclWinFile.c:
+	* win/tclWinLoad.c:
+	* win/tclWinPipe.c:
+
+2010-04-20  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tclTest.c:  Use function prototypes from the FS API.
+	* compat/zlib/*:      Upgrade to zlib 1.2.5
+
+2010-04-19  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclExecute.c (TclExecuteByteCode): Improve commenting and
+	reduce indentation for the Invocation Block.
+
+2010-04-18  Donal K. Fellows  <dkf@users.sf.net>
+
+	* doc/unset.n: [Bug 2988940]: Fix typo.
+
+2010-04-15  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* win/tclWinPort.h:       Move inclusion of <tchar.h> from
+	* generic/tcl.h:          tclPlatDecls.h to tclWinPort.h, where it
+	* generic/tclPlatDecls.h: belongs. Add fallback in tcl.h, so TCHAR is
+				  available in win32 always.
+
+2010-04-15  Donal K. Fellows  <dkf@users.sf.net>
+
+	* doc/try.n: [Bug 2987551]: Fix typo.
+
+2010-04-14  Andreas Kupries  <andreask@activestate.com>
+
+	* library/platform/platform.tcl: Linux platform identification:
+	* library/platform/pkgIndex.tcl: Check /lib64 for existence of files
+	* unix/Makefile.in: matching libc* before accepting it as base
+	* win/Makefile.in:  directory. This can happen on weirdly installed
+	32bit systems which have an empty or partially filled /lib64 without
+	an actual libc. Bumped to version 1.0.6.
+
+2010-04-13  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* win/tclWinPort.h: Fix [Patch 2986105]: conditionally defining
+	* win/tclWinFile.c: strcasecmp/strncasecmp
+	* win/tclWinLoad.c: Fix gcc warning: comparison of unsigned expression
+	>= 0 is always true
+
+2010-04-08  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclCompCmdsSZ.c (TclSubstCompile): If the first token does
+	not result in a *guaranteed* push of a Tcl_Obj on the stack, we must
+	push an empty object. Otherwise it is possible to get to a 'concat1'
+	or 'done' without enough values on the stack, resulting in a crash.
+	Thanks to Joe Mistachkin for identifying a script that could trigger
+	this case.
+
+2010-04-07  Donal K. Fellows  <dkf@users.sf.net>
+
+	* doc/catch.n, doc/info.n, doc/return.n: Formatting.
+
+2010-04-06  Donal K. Fellows  <dkf@users.sf.net>
+
+	* doc/Load.3: Minor corrections of formatting and cross links.
+
+2010-04-06  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* win/configure:       (regenerate with autoconf-2.59)
+	* unix/configure:
+	* unix/installManPage: [Bug 2982540]: configure and install* script
+	* unix/install-sh:     files should always have LF line ending.
+	* doc/Load.3:          Fix signature of Tcl_LoadFile in documentation.
+
+2010-04-05  Alexandre Ferrieux  <ferrieux@users.sourceforge.net>
+
+	TIP #348 IMPLEMENTATION
+
+	* generic/tclBasic.c: [Patch 2868499]: Substituted error stack
+	* generic/tclCmdIL.c:
+	* generic/tclInt.h:
+	* generic/tclNamesp.c:
+	* generic/tclResult.c:
+	* doc/catch.n:
+	* doc/info.n:
+	* doc/return.n:
+	* tests/cmdMZ.test:
+	* tests/error.test:
+	* tests/execute.test:
+	* tests/info.test:
+	* tests/init.test:
+	* tests/result.test:
+
+2010-04-05  Donal K. Fellows  <dkf@users.sf.net>
+
+	* unix/tcl.m4 (SC_ENABLE_THREADS): Flip the default for whether to
+	* win/tcl.m4 (SC_ENABLE_THREADS):  build in threaded mode. Part of
+	* win/rules.vc:			   TIP #364.
+
+	* unix/tclLoadDyld.c (FindSymbol): Better human-readable error message
+	generation to match code in tclLoadDl.c.
+
+2010-04-04  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclIOUtil.c, unix/tclLoadDl.c: Minor changes to enforce
+	Engineering Manual style rules.
+
+	* doc/FileSystem.3, doc/Load.3: Documentation for TIP#357.
+
+	* macosx/tclMacOSXBundle.c (OpenResourceMap): [Bug 2981528]: Only
+	define this function when HAVE_COREFOUNDATION is defined.
+
+2010-04-02  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tcl.decls (Tcl_LoadFile): Add missing "const" in signature,
+	* generic/tclIOUtil.c (Tcl_LoadFile): and some formatting fixes
+	* generic/tclDecls.h:  (regenerated)
+
+2010-04-02  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclIOUtil.c (Tcl_LoadFile): Corrections to previous commit
+	* unix/tclLoadDyld.c (TclpDlopen):    to make it build on OSX.
+
+2010-04-02  Kevin B. Kenny  <kennykb@acm.org>
+
+	TIP #357 IMPLEMENTATION
+	TIP #362 IMPLEMENTATION
+
+	* generic/tclStrToD.c: [Bug 2952904]: Defer creation of the smallest
+	floating point number until it is actually used. (This change avoids a
+	bogus syslog message regarding a 'floating point software assist
+	fault' on SGI systems.)
+
+	* library/reg/pkgIndex.tcl:	[TIP #362]: Fixed first round of bugs
+	* tests/registry.test:		resulting from the recent commits of
+	* win/tclWinReg.c:		changes in support of the referenced
+					TIP.
+
+	* generic/tcl.decls:		[TIP #357]: First round of changes
+	* generic/tclDecls.h:		to export Tcl_LoadFile,
+	* generic/tclIOUtil.c:		Tcl_FindSymbol, and Tcl_FSUnloadFile
+	* generic/tclInt.h:		to the public API.
+	* generic/tclLoad.c:
+	* generic/tclLoadNone.c:
+	* generic/tclStubInit.c:
+	* tests/fileSystem.test:
+	* tests/load.test:
+	* tests/unload.test:
+	* unix/tclLoadDl.c:
+	* unix/tclLoadDyld.c:
+	* unix/tclLoadNext.c:
+	* unix/tclLoadOSF.c:
+	* unix/tclLoadShl.c:
+	* unix/tclUnixPipe.c:
+	* win/Makefile.in:
+	* win/tclWinLoad.c:
+
+2010-03-31  Donal K. Fellows  <dkf@users.sf.net>
+
+	* doc/registry.n: Added missing documentation of TIP#362 flags.
+
+	* doc/package.n: [Bug 2980210]: Document the arguments taken by
+	the [package present] command correctly.
+
+	* doc/Thread.3: Added some better documentation of how to create and
+	use a thread using the C-level thread API, based on realization that
+	no such tutorial appeared to exist.
+
+2010-03-31  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* test/cmdMZ.test:    [FRQ 2974744]: share exception codes (ObjType?):
+	* test/error.test:    Revised test cases, making sure that abbreviated
+	* test/proc-old.test: codes are checked resulting in an error, and
+	                      checking for the exact error message.
+
+2010-03-30  Andreas Kupries  <andreask@activestate.com>
+
+	* generic/tclIORChan.c (ReflectClose, ReflectInput, ReflectOutput,
+	(ReflectSeekWide, ReflectWatch, ReflectBlock, ReflectSetOption,
+	(ReflectGetOption, ForwardProc): [Bug 2978773]: Preserve
+	ReflectedChannel* structures across handler invokations, to avoid
+	crashes when the handler implementation induces nested callbacks and
+	destruction of the channel deep inside such a nesting.
+
+2010-03-30  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclObj.c (Tcl_GetCommandFromObj):     [Bug 2979402]: Reorder
+	the validity tests on internal rep of a "cmdName" value to avoid
+	invalid reads reported by valgrind.
+
+2010-03-30  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tclIndexObj:	[FRQ 2974744]: share exception codes
+	* generic/tclResult.c:	further optimization, making use of indexType.
+	* generic/tclZlib.c:    [Bug 2979399]: uninitialized value troubles
+
+2010-03-30  Donal K. Fellows  <dkf@users.sf.net>
+
+	TIP #362 IMPLEMENTATION
+
+	* win/tclWinReg.c: [Patch 2960976]: Apply patch from Damon Courtney to
+	* tests/registry.test:	allow the registry command to be told to work
+	* win/Makefile.in:	with both 32-bit and 64-bit registries. Bump
+	* win/configure.in:	version of registry package to 1.3.
+	* win/makefile.bc:
+	* win/makefile.vc:
+	* win/configure:	autoconf-2.59
+
+2010-03-29  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* unix/tcl.m4:            Only test for -visibility=hidden with gcc
+	                          (Second remark in [Bug 2976508])
+	* unix/configure:         regen
+
+2010-03-29  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclStringObj.c:       Fix array overrun in test format-1.12
+	caught by valgrind testing.
+
+2010-03-27  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tclInt.h:	[FRQ 2974744]: share exception codes
+	* generic/tclResult.c:	(ObjType?)
+	* generic/tclCmdMZ.c:
+	* generic/tclCompCmdsSZ.c:
+
+2010-03-26  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tclExecute.c: [Bug 2976508]: Tcl HEAD fails on HP-UX
+
+2010-03-25  Donal K. Fellows  <dkf@users.sf.net>
+
+	* unix/tclUnixFCmd.c (TclUnixCopyFile): [Bug 2976504]: Corrected
+	number of arguments to fstatfs() call.
+
+	* macosx/tclMacOSXBundle.c, macosx/tclMacOSXFCmd.c:
+	* macosx/tclMacOSXNotify.c: Reduce the level of ifdeffery in the
+	functions of these files to improve readability. They need to be
+	audited for whether complexity can be removed based on the minimum
+	supported version of OSX, but that requires a real expert.
+
+2010-03-24  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclResult.c:  [Bug 2383005]: Revise [return -errorcode] so
+	* tests/result.test:    that it rejects illegal non-list values.
+
+2010-03-24  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclOOInfo.c (InfoObjectMethodTypeCmd)
+	(InfoClassMethodTypeCmd): Added introspection of method types so that
+	it is possible to find this info out without using errors.
+	* generic/tclOOMethod.c (procMethodType): Now that introspection can
+	reveal the name of method types, regularize the name of normal methods
+	to be the name of the definition type used to create them.
+
+	* tests/async.test (async-4.*): Reduce obscurity of these tests by
+	putting the bulk of the code for them inside the test body with the
+	help of [apply].
+
+	* generic/tclCmdMZ.c (TryPostBody, TryPostHandler): Make sure that the
+	[try] command does not trap unwinding due to limits.
+
+2010-03-23  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclCmdMZ.c:	[Bug 2973361]: Revised fix for computing
+	indices of script arguments to [try].
+
+2010-03-23  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tclCmdMZ.c:      Make error message in "try" implementation
+	* generic/tclCompCmdsSZ.c: exactly the same as the one in "return"
+	* tests/error.test:
+	* libtommath/mtests/mpi.c: Single "const" addition
+
+2010-03-22  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclCmdMZ.c:	[Bug 2973361]: Compute the correct integer
+	values to identify the argument indices of the various script
+	arguments to [try]. Passing in -1 led to invalid memory reads.
+
+2010-03-20  Donal K. Fellows  <dkf@users.sf.net>
+
+	* doc/exec.n: Make it a bit clearer that there is an option to run a
+	pipeline in the background.
+
+	* generic/tclIOCmd.c (Tcl_FcopyObjCmd):		Lift the restriction
+	* generic/tclIO.c (TclCopyChannel, CopyData):	on the [fcopy] command
+	* generic/tclIO.h (CopyState):			that forced it to only
+	copy up to 2GB per script-level callback. Now it is anything that can
+	fit in a (signed) 64-bit integer. Problem identified by Frederic
+	Bonnet on comp.lang.tcl. Note that individual low-level reads and
+	writes are still smaller as the optimal buffer size is smaller.
+
+2010-03-20  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* win/stub16.c:         Don't hide that we use the ASCII API here.
+	                        (does someone still use that?)
+	* win/tclWinPipe.c:     2 unnecessary type casts.
+
+2010-03-19  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclCompCmdsSZ.c (TclCompileThrowCmd): Added compilation for
+	the [throw] command.
+
+2010-03-18  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclListObj.c:	[Bug 2971669]: Prevent in overflow trouble in
+	* generic/tclTestObj.c:	ListObjReplace operations. Thanks to kbk for
+	* tests/listObj.test:	fix and test.
+
+2010-03-18  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclCompCmdsSZ.c (IssueTryFinallyInstructions):
+	[Bug 2971921]: Corrected jump so that it doesn't skip into the middle
+	of an instruction! Tightened the instruction issuing. Moved endCatch
+	calls closer to their point that they guard, ensuring correct ordering
+	of result values.
+
+2010-03-17  Andreas Kupries  <andreask@activestate.com>
+
+	* generic/tclIORTrans.c (ReflectInput, ReflectOutput)
+	(ReflectSeekWide): [Bug 2921116]: Added missing TclEventuallyFree
+	calls for preserved ReflectedTransform* structures. Reworked
+	ReflectInput to preserve the structure for its whole life, not only in
+	InvokeTclMethod.
+
+	* generic/tclIO.c (Tcl_GetsObj): [Bug 2921116]: Regenerate topChan,
+	may have been changed by a self-modifying transformation.
+
+	* tests/ioTrans/test (iortrans-4.8, iortrans-4.9, iortrans-5.11)
+	(iortrans-7.4, iortrans-8.3): New test cases.
+
+2010-03-16  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* compat/zlib/*:	Upgrade zlib to version 1.2.4.
+	* win/makefile.vc:
+	* unix/Makefile.in:
+	* win/tclWinChan.c:	Don't cast away "const" without reason.
+
+2010-03-12  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* win/makefile.vc: [Bug 2967340]: Static build was failing.
+	* win/.cvsignore:
+
+2010-03-10  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tclTest.c:	Remove unnecessary '&' decoration for
+	* generic/tclIOUtil.c:	function pointers
+	* win/tclWin32Dll.c:	Double declaration of TclNativeDupInternalRep
+	* unix/tclIOUtil.c:
+	* unix/dltest/.cvsignore: Ignore *.so here
+
+2010-03-09  Andreas Kupries  <andreask@activestate.com>
+
+	* generic/tclIORChan.c: [Bug 2936225]: Thanks to Alexandre Ferrieux
+	* doc/refchan.n:    <ferrieux@users.sourceforge.net> for debugging and
+	* tests/ioCmd.test: fixing the problem. It is the write-side
+	equivalent to the bug fixed 2009-08-06.
+
+2010-03-09  Don Porter  <dgp@users.sourceforge.net>
+
+	* library/tzdata/America/Matamoros: New locale
+	* library/tzdata/America/Ojinaga: New locale
+	* library/tzdata/America/Santa_Isabel: New locale
+	* library/tzdata/America/Asuncion:
+	* library/tzdata/America/Tijuana:
+	* library/tzdata/Antarctica/Casey:
+	* library/tzdata/Antarctica/Davis:
+	* library/tzdata/Antarctica/Mawson:
+	* library/tzdata/Asia/Dhaka:
+	* library/tzdata/Pacific/Fiji:
+	Olson tzdata2010c.
+
+2010-03-07  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tclTest.c:	  Test that tclOO stubs are present in stub
+				  library
+	* generic/tclOOMethod.c:  Applied missing part of [Patch 2961556]
+	* win/tclWinInt.h:	  Change all tclWinProcs signatures to use
+	* win/tclWin32Dll.c:	  TCHAR* in stead of WCHAR*. This is meant
+	* win/tclWinDde.c:	  as preparation to make [Enh 2965056]
+	* win/tclWinFCmd.c:	  possible at all.
+	* win/tclWinFile.c:
+	* win/tclWinPipe.c:
+	* win/tclWinSock.c:
+
+2010-03-06  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tclStubLib.c:	Remove presence of tclTomMathStubsPtr here.
+	* generic/tclTest.c:	Test that tommath stubs are present in stub
+				library.
+
+2010-03-05  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclIORTrans.c (ForwardProc): [Bug 2964425]: When cleaning
+	the stables, it is sometimes necessary to do more than the minimum. In
+	this case, rationalizing the variables for a forwarded limit? method
+	required removing an extra Tcl_DecrRefCount too.
+
+	* generic/tclOO.h, generic/tclOOInt.h: [Patch 2961556]: Change TclOO
+	to use the same style of function typedefs as Tcl, as this is about
+	the last chance to get this right.
+
+	***POTENTIAL INCOMPATIBILITY***
+	Source code that uses function typedefs from TclOO will need to update
+	variables and argument definitions so that pointers to the function
+	values are used instead. Binary compatibility is not affected.
+
+	* generic/*.c, generic/tclInt.h, unix/*.c, macosx/*.c: Applied results
+	of doing a Code Audit. Principal changes:
+	  * Use do { ... } while (0) in macros
+	  * Avoid shadowing one local variable with another
+	  * Use clearer 'foo.bar++;' instead of '++foo.bar;' where result not
+	    required (i.e., semantically equivalent); clarity is increased
+	    because it is bar that is incremented, not foo.
+	  * Follow Engineering Manual rules on spacing and declarations
+
+2010-03-04  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclOO.c (ObjectRenamedTrace): [Bug 2962664]: Add special
+	handling so that when the class of classes is deleted, so is the class
+	of objects. Immediately.
+
+	* generic/tclOOInt.h (ROOT_CLASS): Add new flag for specially marking
+	the root class. Simpler and more robust than the previous technique.
+
+2010-03-04  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tclGetDate.y:    3 unnecessary MODULE_SCOPE
+	* generic/tclDate.c:       symbols
+	* generic/tclStubLib.c:    Split tommath stub lib
+	* generic/tclTomMathStubLib.c:  in separate file.
+	* win/makefile.bc:
+	* win/Makefile.in:
+	* win/makefile.vc:
+	* win/tcl.dsp:
+	* unix/Makefile.in:
+	* unix/tcl.m4:          Cygwin only gives warning
+	* unix/configure:       using -fvisibility=hidden
+	* compat/strncasecmp.c: A few more const's
+	* compat/strtod.c:
+	* compat/strtoul.c:
+
+2010-03-03  Andreas Kupries <andreask@activestate.com>
+
+	* doc/refchan.n: Followup to ChangeLog entry 2009-10-07
+	(generic/tclIORChan.c). Fixed the documentation to explain that errno
+	numbers are operating system dependent, and reworked the associated
+	example.
+
+2010-03-02  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* unix/tcl.m4:     [FRQ 2959069]: Support for -fvisibility=hidden
+	* unix/configure   (regenerated with autoconf-2.59)
+
+2010-03-01  Alexandre Ferrieux  <ferrieux@users.sourceforge.net>
+
+	* unix/tclUnixSock.c: Refrain from a possibly lengthy reverse-DNS
+	lookup on 0.0.0.0 when calling [fconfigure -sockname] on an
+	universally-bound (default) server socket.
+
+	* generic/tclIndexObj.c: fix [AT 86258]: special-casing of empty
+	tables when generating error messages for [::tcl::prefix match].
+
+2010-02-28  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclCmdIL.c: More additions of {TCL LOOKUP} error-code
+	generation to various subcommands of [info] as part of long-term
+	project to classify all Tcl's generated errors.
+
+2010-02-28  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tclStubInit.c: [Bug 2959713]: Link error with gcc 4.1
+
+2010-02-27  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclCmdMZ.c (StringFirstCmd, StringLastCmd): [Bug 2960021]:
+	Only search for the needle in the haystack when the needle isn't
+	larger than the haystack. Prevents an odd crash from sometimes
+	happening when things get mixed up (a common programming error).
+
+	* generic/tclMain.c (Tcl_Main): [Bug 801429]: Factor out the holding
+	of the client-installed main loop function into thread-specific data.
+
+	***POTENTIAL INCOMPATIBILITY***
+	Code that previously tried to set the main loop from another thread
+	will now fail. On the other hand, there is a fairly high probability
+	that such programs would have been failing before due to the lack of
+	any kind of inter-thread memory barriers guarding accesses to this
+	part of Tcl's state.
+
+2010-02-26  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclCompCmds.c:   Split this file into two pieces to make it
+	* generic/tclCompCmdsSZ.c: easier to work with. It's still two very
+				   long files even after the split.
+
+2010-02-26  Reinhard Max  <max@suse.de>
+
+	* doc/safe.n: Name the installed file after the command it documents.
+	Use "Safe Tcl" instead of the "Safe Base", "Safe Tcl" mixture.
+
+2010-02-26  Donal K. Fellows  <dkf@users.sf.net>
+
+	* unix/Makefile.in (NATIVE_TCLSH): Added this variable to allow for
+	better control of what tclsh to use for various scripts when doing
+	cross compiling. An imperfect solution, but works.
+
+	* unix/installManPage: Remap non-alphanumeric sequences in filenames
+	to single underscores (especially colons).
+
+2010-02-26  Pat Thoyts  <patthoyts@users.sourceforge.net>
+
+	* tests/zlib.test: Add tests for [Bug 2818131] which was crashing with
+	mismatched zlib algorithms used in combination with gets. This issue
+	has been fixed by Andreas's last commit.
+
+2010-02-25  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tclHash.c:	[FRQ 2958832]: Further speed-up of the
+	* generic/tclLiteral.c:	ouster-hash function.
+	* generic/tclObj.c:
+	* generic/tclCkalloc.c:	Eliminate various unnecessary (ClientData)
+	* generic/tclTest.c:	type casts.
+	* generic/tclTestObj.c:
+	* generic/tclTestProcBodyObj.c:
+	* unix/tclUnixTest.c:
+	* unix/tclUnixTime.c:
+	* unix/tclXtTest.c:
+
+2010-02-24  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclDictObj.c (SetDictFromAny): Prevent the list<->dict
+	* generic/tclListObj.c (SetListFromAny): conversion code from taking
+	too many liberties. Stops loss of duplicate keys in some scenarios.
+	Many thanks to Jean-Claude Wippler for finding this.
+
+	* generic/tclExecute.c (TclExecuteByteCode): Reduce ifdef-fery and
+	size of activation record. More variables shared across instructions
+	than before.
+
+	* doc/socket.n: [Bug 2957688]: Clarified that [socket -server] works
+	with a command prefix. Extended example to show this in action.
+
+2010-02-22  Andreas Kupries  <andreask@activestate.com>
+
+	* generic/tclZlib.c (ZlibTransformInput): [Bug 2762041]: Added a hack
+	to work around the general problem, early EOF recognition based on the
+	base-channel, instead of the data we have ready for reading in the
+	transform. Long-term we need a proper general fix (likely tracking EOF
+	on each level of the channel stack), with attendant complexity.
+	Furthermore, Z_BUF_ERROR can be ignored, and must be when feeding the
+	zlib code with single characters.
+
+2010-02-22  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* unix/tclUnixPort.h:   Remove unnecessary EXTERN's, which already are
+	                        in the global stub table.
+	* unix/configure.in:    Use @EXEEXT@ in stead of @EXT_SUFFIX@
+	* unix/tcl.m4:
+	* unix/Makefile.in:     Use -DBUILD_tcl for CYGWIN
+	* unix/configure:       (regenerated)
+	* unix/dltest/pkg*.c:   Use EXTERN to control CYGWIN exported symbols
+	* generic/tclCmdMZ.c:   Remove some unnecessary type casts.
+	* generic/tclCompCmds.c:
+	* generic/tclTest.c:
+	* generic/tclUtil.c:
+
+2010-02-21  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* tests/regexp.test: Add test cases back ported from Jacl regexp work.
+
+2010-02-21  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tclDate.c:    Some more const tables.
+	* generic/tclGetDate.y:
+	* generic/regc_lex.c:
+	* generic/regerror.c:
+	* generic/tclStubLib.c:
+	* generic/tclBasic.c:   Fix [Bug 2954959] expr abs(0.0) is -0.0
+	* tests/expr.test:
+
+2010-02-20  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclCompCmds.c (TclCompileStringLenCmd): Make [string length]
+	of a constant string be handled better (i.e., handle backslashes too).
+
+2010-02-19  Stuart Cassoff  <stwo@users.sourceforge.net>
+
+	* tcl.m4: Correct compiler/linker flags for threaded builds on
+	OpenBSD.
+	* configure: (regenerated).
+
+2010-02-19  Donal K. Fellows  <dkf@users.sf.net>
+
+	* unix/installManPage: [Bug 2954638]: Correct behaviour of manual page
+	installer. Also added armouring to check that assumptions about the
+	initial state are actually valid (e.g., look for existing input file).
+
+2010-02-17  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclHash.c (HashStringKey):	Restore these hash functions
+	* generic/tclLiteral.c (HashString):	to use the classic algorithm.
+	* generic/tclObj.c (TclHashObjKey):	Community felt normal case
+	speed to be more important than resistance to malicious cases. For
+	now, hashes that need to deal with the malicious case can use a custom
+	hash table and install their own hash function, though that is not
+	functionality exposed to the script level.
+
+	* generic/tclCompCmds.c (TclCompileDictUpdateCmd): Stack depth must be
+	correctly described when compiling a body to prevent crashes in some
+	debugging modes.
+
+2010-02-16  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tclInt.h: Change order of various struct members,
+	fixing potential binary incompatibility with Tcl 8.5
+
+2010-02-16  Donal K. Fellows  <dkf@users.sf.net>
+
+	* unix/configure.in, generic/tclIOUtil.c (Tcl_Stat): Updated so that
+	we do not assume that all unix systems have the POSIX blkcnt_t type,
+	since OpenBSD apparently does not.
+
+	* generic/tclLiteral.c (HashString): Missed updating to FNV in one
+	place; the literal table (a copy of the hash table code...)
+
+2010-02-15  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* tools/genStubs.tcl:   Reverted earlier rename from tcl*Stubs to
+	* generic/tclBasic.c:   tcl*ConstStubs, it's not necessary at all.
+	* generic/tclOO.c:
+	* generic/tclTomMathInterface.c:
+	* generic/tclStubInit.c: (regenerated)
+	* generic/tclOOStubInit.c: (regenerated)
+	* generic/tclEnsemble.c:Fix signed-unsigned mismatch
+	* win/tclWinInt.h:      make tclWinProcs "const"
+	* win/tclWin32Dll.c:
+	* win/tclWinFCmd.c:     Eliminate all internal Tcl_WinUtfToTChar
+	* win/tclWinFile.c:     and Tcl_WinTCharToUtf calls, needed
+	* win/tclWinInit.c:     for mslu support.
+	* win/tclWinLoad.c:
+	* win/tclWinPipe.c:
+	* win/tclWinSerial.c:
+	* win/.cvsignore:
+	* compat/unicows/readme.txt:  [FRQ 2819611]: Add first part of MSLU
+	* compat/unicows/license.txt: support.
+	* compat/unicows/unicows.lib:
+
+2010-02-15  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclOO.c (AllocObject, SquelchedNsFirst, ObjectRenamedTrace):
+	* generic/tclNamesp.c (Tcl_DeleteNamespace): [Bug 2950259]: Revised
+	the namespace deletion code to provide an additional internal callback
+	that gets triggered early enough in namespace deletion to allow TclOO
+	destructors to run sanely. Adjusted TclOO to take advantage of this,
+	so making tearing down an object by killing its namespace appear to
+	work seamlessly, which is needed for Itcl. (Note that this is not a
+	feature that will ever be backported to 8.5, and it remains not a
+	recommended way of deleting an object.)
+
+2010-02-13  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclCompCmds.c (TclCompileSwitchCmd): Divided the [switch]
+	compiler into three pieces (after the model of [try]): a parser, an
+	instruction-issuer for chained tests, and an instruction-issuer for
+	jump tables.
+
+	* generic/tclEnsemble.c: Split the ensemble engine out into its own
+	file rather than keeping it mashed together with the namespace code.
+
+2010-02-12  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* win/tcl.m4:		Use -pipe for gcc on win32
+	* win/configure:	(mingw/cygwin) (regenerated)
+	* win/.cvsignore:	Add .lib, .exp and .res here
+
+2010-02-11  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* tests/list.test: Add tests for explicit \0 in a string argument to
+	the list command.
+
+2010-02-11  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclIOCmd.c (Tcl_OpenObjCmd): [Bug 2949740]: Make sure that
+	we do not try to put a NULL pipeline channel into binary mode.
+
+2010-02-11  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	[Bug 2826551, Patch 2948425]: Assorted regexp bugs related to -all,
+	-line and -start options and newlines.
+	* generic/tclCmdMZ.c (Tcl_RegexpObjCmd): If -offset is given, treat it
+	as the start of the line if the previous character was a newline. Fix
+	nasty edge case where a zero length match would not advance the index.
+	* tests/regexp.test: Add regression tests back ported from Jacl.
+	Checks for a number of issues related to -line and newline handling. A
+	few of tests were broken before the patch and continue to be broken,
+	marked as knownBug.
+
+2010-02-11  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclOO.c (ObjectRenamedTrace): [Bug 2949397]: Prevent
+	destructors from running on the two core class objects when the whole
+	interpreter is being destroyed.
+
+2010-02-09  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclCompCmds.c (TclCompileTryCmd, IssueTryInstructions)
+	(IssueTryFinallyInstructions): Added compiler for the [try] command.
+	It is split into three pieces that handle the parsing of the tokens,
+	the issuing of instructions for finally-free [try], and the issuing of
+	instructions for [try] with finally; there are enough differences
+	between the all cases that it was easier to split the code rather than
+	have a single function do the whole thing.
+
+2010-02-09  Alexandre Ferrieux  <ferrieux@users.sourceforge.net>
+
+	* tools/genStubs.tcl: Remove dependency on 8.5+ idiom "in" in
+	expressions.
+
+2010-02-08  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclZlib.c (Tcl_ZlibDeflate, Tcl_ZlibInflate): [Bug 2947783]:
+	Make sure that the result is an unshared object before appending to it
+	so that nothing crashes if it is shared (use in Tcl code was not
+	affected by this, but use from C was an issue).
+
+2010-02-06  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclHash.c (HashStringKey):	Replace Tcl's crusty old hash
+	* generic/tclObj.c (TclHashObjKey):	function with the algorithm
+	due to Fowler, Noll and Vo. This is slightly faster (assuming the
+	presence of hardware multiply) and has somewhat better distribution
+	properties of the resulting hash values. Note that we only ever used
+	the 32-bit version of the FNV algorithm; Tcl's core hash engine
+	assumes that hash values are simple unsigned ints.
+
+	***POTENTIAL INCOMPATIBILITY***
+	Code that depends on hash iteration order (especially tests) may well
+	be disrupted by this. Where a definite order is required, the fix is
+	usually to just sort the results after extracting them from the hash.
+	Where this is insufficient, the code that has ceased working was
+	always wrong and was only working by chance.
+
+2010-02-05  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclCompCmds.c (TclCompileErrorCmd): Added compilation of the
+	[error] command. No new bytecodes.
+
+2010-02-05  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* tools/genStubs.tcl:	Follow-up to earlier commit today:
+	          Eliminate the need for an extra Stubs Pointer for adressing
+	          a static stub table: Just change the exported table from
+	          static to MODULE_SCOPE.
+	* generic/tclBasic.c
+	* generic/tclOO.c
+	* generic/tclTomMathInterface.c
+	* generic/tcl*Decls.h (regenerated)
+	* generic/tclStubInit.c (regenerated)
+	* generic/tclOOStubInit.c (regenerated)
+	* generic/tclTest.c (minor formatting)
+
+2010-02-05  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclVar.c: More consistency in errorcode generation.
+
+	* generic/tclOOBasic.c (TclOO_Object_Destroy): Rewrote to be NRE-aware
+	when calling destructors. Note that there is no guarantee that
+	destructors will always be called in an NRE context; that's a feature
+	of the 'destroy' method only.
+
+	* generic/tclEncoding.c: Add 'const' to many function-internal vars
+	that are never pointing to things that are written to.
+
+2010-02-05  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* tools/genStubs.tcl:	Follow-up to [2010-01-29] commit:
+		prevent space within stub table function parameters if the
+		parameter type is a pointer.
+	* win/tclWinInt.h:	Minor Formatting
+	* generic/tcl.h:	VOID -> void and other formatting
+	* generic/tclInt.h:	Minor formatting
+	* generic/tclInt.decls: Change signature of TclNRInterpProcCore,
+	* generic/tclOO.decls:	and TclOONewProc(Instance|)MethodEx,
+	* generic/tclProc.c:	indicating that errorProc is a function,
+	* generic/tclOOMethod.c:pointer, and other formatting
+	* generic/tcl*Decls.h:	(regenerated)
+	* generic/tclVar.c:	gcc warning(line 3703): 'pattern' may be used
+				uninitialized in this function
+				gcc warning(line 3788): 'matched' may be used
+				uninitialized in this function
+
+2010-02-04  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclVar.c: Added more use of error-codes and reduced the
+	stack overhead of older interfaces.
+	(ArrayGetCmd): Stop silly crash when using a trivial pattern due to
+	error in conversion to ensemble.
+	(ArrayNamesCmd): Use the object RE interface for faster matching.
+
+2010-02-03  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclVar.c (ArrayUnsetCmd): More corrections.
+
+2010-02-02  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclVar.c: Turned the [array] command into a true ensemble.
+
+	* generic/tclOO.c (AllocObject, MyDeleted): A slightly faster way to
+	handle the deletion of [my] is with a standard delete callback. This
+	is because it doesn't require an additional memory allocation during
+	object creation. Also reduced the amount of string manipulation
+	performed during object creation to further streamline memory
+	handling; this is not backported to the 8.5 package as it breaks a
+	number of abstractions.
+
+	* generic/tclOOBasic.c (TclOO_Object_Destroy): [Bug 2944404]: Do not
+	crash when a destructor deletes the object that is executing that
+	destructor.
+
+2010-02-01  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclVar.c (Tcl_ArrayObjCmd): [Bug 2939073]: Stop the [array
+	unset] command from having dangling pointer problems when an unset
+	trace deletes the element that is going to be processed next. Many
+	thanks to Alexandre Ferrieux for the bulk of this fix.
+
+	* generic/regexec.c (ccondissect, crevdissect): [Bug 2942697]: Rework
+	these functions so that certain pathological patterns are matched much
+	more rapidly. Many thanks to Tom Lane for dianosing this issue and
+	providing an initial patch.
+
+2010-01-30  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclCompile.c (tclInstructionTable):	Bytecode instructions
+	* generic/tclCompCmds.c (TclCompileUnsetCmd):	to allow the [unset]
+	* generic/tclExecute.c (TclExecuteByteCode):	command to be compiled
+	with the compiler being a complete compilation for all compile-time
+	decidable uses.
+
+	* generic/tclVar.c (TclPtrUnsetVar): Var reference version of the code
+	to unset a variable. Required for INST_UNSET bytecodes.
+
+2010-01-29  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tcl.h: [Bug 2942081]: Reverted Tcl_ThreadDataKey type change
+				Changed some Tcl_CallFrame fields from "char *"
+				to "void *". This saves unnecessary space on
+				Cray's (and it's simply more correct).
+
+	* tools/genStubs.tcl:	No longer generate a space after "*" and
+				immediately after a function name, so the
+				format of function definitions in tcl*Decls.h
+				match all other tcl*.h header files.
+	* doc/ParseArgs.3:	Change Tcl_ArgvFuncProc, Tcl_ArgvGenFuncProc
+	* generic/tcl.h:	and GetFrameInfoValueProc to be function
+	* generic/tclInt.h:	definitions, not pointers, for consistency
+	* generic/tclOOInt.h:	with all other Tcl function definitions.
+	* generic/tclIndexObj.c:
+	* generic/regguts.h:	CONST -> const
+	* generic/tcl.decls:	Formatting
+	* generic/tclTomMath.decls: Formatting
+	* generic/tclDecls.h:	(regenerated)
+	* generic/tclIntDecls.h:
+	* generic/tclIntPlatDecls.h:
+	* generic/tclOODecls.h:
+	* generic/tclOOIntDecls.h:
+	* generic/tclPlatDecls.h:
+	* generic/tclTomMathDecls.h:
+
+2010-01-28  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclOOBasic.c (TclOO_Object_Destroy): Move the execution of
+	destructors to a point where they can produce an error. This will not
+	work for all destructors, but it does mean that more failing calls of
+	them will be caught.
+	* generic/tclOO.c (AllocObject, MyDeletedTrace, ObjectRenamedTrace):
+	(ObjectNamespaceDeleted): Stop various ways of getting at commands
+	with dangling pointers to the object. Also increases the reliability
+	of calling of destructors (though most destructors won't benefit; when
+	an object is deleted namespace-first, its destructors are not run in a
+	nice state as the namespace is partially gone).
+
+2010-01-25  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tclOOStubInit.c:   Remove double includes (which causes a
+	* generic/tclOOStubLib.c:    warning in CYGWIN compiles)
+	* unix/.cvsignore:	     add confdefs.h
+
+2010-01-22  Donal K. Fellows  <dkf@users.sf.net>
+
+	* doc/proc.n: [Bug 1970629]: Define a bit better what the current
+	namespace of a procedure is.
+
+2010-01-22  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tclInt.decls:	     Don't use DWORD and HANDLE here.
+	* generic/tclIntPlatDecls.h:
+	* generic/tcl.h:	     Revert [2009-12-21] change, instead
+	* generic/tclPort.h:	     resolve the CYGWIN inclusion problems by
+	* win/tclWinPort.h:	     re-arranging the inclusions at other
+				     places.
+	* win/tclWinError.c
+	* win/tclWinPipe.c
+	* win/tcl.m4:		     Make cygwin configuration error into
+	* win/configure.in:	     a warning: CYGWIN compilation works
+	* win/configure:	     although there still are test failures.
+
+2010-01-22  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclExecute.c (TclExecuteByteCode): Improve error code
+	generation from some of the tailcall-related bits of TEBC.
+
+2010-01-21  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclCompile.h: [Bug 2910748]: NRE-enable direct eval on BC
+	* generic/tclExecute.c: spoilage.
+	* tests/nre.test:
+
+2010-01-19  Donal K. Fellows  <dkf@users.sf.net>
+
+	* doc/dict.n: [Bug 2929546]: Clarify just what [dict with] and [dict
+	update] are doing with variables.
+
+2010-01-18  Andreas Kupries  <andreask@activestate.com>
+
+	* generic/tclIO.c (CreateScriptRecord): [Bug 2918110]: Initialize
+	the EventScriptRecord (esPtr) fully before handing it to
+	Tcl_CreateChannelHandler for registration. Otherwise a reflected
+	channel calling 'chan postevent' (== Tcl_NotifyChannel) in its
+	'watchProc' will cause the function 'TclChannelEventScriptInvoker'
+	to be run on an uninitialized structure.
+
+2010-01-18  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclStringObj.c (Tcl_AppendFormatToObj): [Bug 2932421]: Stop
+	the [format] command from causing argument objects to change their
+	internal representation when not needed. Thanks to Alexandre Ferrieux
+	for this fix.
+
+2010-01-13  Donal K. Fellows  <dkf@users.sf.net>
+
+	* tools/tcltk-man2html.tcl:	  More factoring out of special cases
+	* tools/tcltk-man2html-utils.tcl: so that they are described outside
+	the engine file. Now there is only one real set of special cases in
+	there, to handle the .SO/.OP/.SE directives.
+
+2010-01-13  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tcl.h:      Fix TCL_LL_MODIFIER for Cygwin
+	* generic/tclEnv.c:   Fix CYGWIN compilation problems,
+	* generic/tclInt.h:   and remove some unnecessary
+	* generic/tclPort.h:  double includes.
+	* generic/tclPlatDecls.h:
+	* win/cat.c:
+	* win/tclWinConsole.c:
+	* win/tclWinFCmd.c:
+	* win/tclWinFile.c:
+	* win/tclWinPipe.c:
+	* win/tclWinSerial.c:
+	* win/tclWinThrd.c:
+	* win/tclWinPort.h:   Put win32 includes first
+	* unix/tclUnixChan.c: Forgot one CONST change
+
+2010-01-12  Donal K. Fellows  <dkf@users.sf.net>
+
+	* tools/tcltk-man2html.tcl: Make the generation of the list of things
+	to process the docs from simpler and more flexible. Also factored out
+	the lists of special cases.
+
+2010-01-10  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* win/tclWinDde.c:      VC++ 6.0 doesn't have
+	* win/tclWinReg.c:      PDWORD_PTR
+	* win/tclWinThrd.c:     Fix various minor gcc warnings.
+	* win/tclWinTime.c:
+	* win/tclWinConsole.c:  Put channel type definitions
+	* win/tclWinChan.c:     in static const memory
+	* win/tclWinPipe.c:
+	* win/tclWinSerial.c:
+	* win/tclWinSock.c:
+	* generic/tclIOGT.c:
+	* generic/tclIORChan.c:
+	* generic/tclIORTrans.c:
+	* unix/tclUnixChan.c:
+	* unix/tclUnixPipe.c:
+	* unix/tclUnixSock.c:
+	* unix/configure:       (regenerated with autoconf 2.59)
+	* tests/info.test:      Make test independant from
+	                        tcltest implementation.
+
+2010-01-10  Donal K. Fellows  <dkf@users.sf.net>
+
+	* tests/namespace.test (namespace-51.17): [Bug 2898722]: Demonstrate
+	that there are still bugs in the handling of resolution epochs. This
+	bug is not yet fixed.
+
+	* tools/tcltk-man2html.tcl:	  Split the man->html converter into
+	* tools/tcltk-man2html-utils.tcl: two pieces for easier maintenance.
+	Also made it much less verbose in its printed messages by default.
+
+2010-01-09  Donal K. Fellows  <dkf@users.sf.net>
+
+	* tools/tcltk-man2html.tcl: Added basic support for building the docs
+	for contributed packages into the HTML versions. Prompted by question
+	on Tcler's Chat by Tom Krehbiel. Note that there remain problems in
+	the documentation generated due to errors in the contributed docs.
+
+2010-01-05  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclPathObj.c (TclPathPart):   [Bug 2918610]: Correct
+	* tests/fileName.test (filename-14.31): inconsistency between the
+	string rep and the intrep of a path value created by [file rootname].
+	Thanks to Vitaly Magerya for reporting.
+
+2010-01-03  Donal K. Fellows  <dkf@users.sf.net>
+
+	* unix/tcl.m4 (SC_CONFIG_CFLAGS): [Bug 1636685]: Use the configuration
+	for modern FreeBSD suggested by the FreeBSD porter.
+
+2010-01-03  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclBasic.c:	[Bug 2724403]: Fix leak of coroutines on
+	* generic/tclCompile.h: namespace deletion. Added a test for this
+	* generic/tclNamesp.c:	leak, and also a test for leaks on namespace
+	* tests/coroutine.test: deletion.
+	* tests/namespace.test:
+
+2009-12-30  Donal K. Fellows  <dkf@users.sf.net>
+
+	* library/safe.tcl (AliasSource): [Bug 2923613]: Make the safer
+	* tests/safe.test (safe-8.9):	  [source] handle a [return] at the
+					  end of the file correctly.
+
+2009-12-30  Miguel Sofer  <msofer@users.sf.net>
+
+	* library/init.tcl (unknown): [Bug 2824981]: Fix infinite recursion of
+	::unknown when [set] is undefined.
+
+2009-12-29  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclHistory.c (Tcl_RecordAndEvalObj): Reduce the amount of
+	allocation and deallocation of memory by caching objects in the
+	interpreter assocData table.
+
+	* generic/tclObj.c (Tcl_GetCommandFromObj): Rewrite the logic so that
+	it does not require making assignments part way through an 'if'
+	condition, which was deeply unclear.
+
+	* generic/tclInterp.c (Tcl_MakeSafe): [Bug 2895741]: Make sure that
+	the min() and max() functions are supported in safe interpreters.
+
+2009-12-29  Pat Thoyts  <patthoyts@users.sourceforge.net>
+
+	* generic/tclBinary.c:	[Bug 2922555]: Handle completely invalid input
+	* tests/binary.test:	to the decode methods.
+
+2009-12-28  Donal K. Fellows  <dkf@users.sf.net>
+
+	* unix/Makefile.in (trace-shell, trace-test): [FRQ 1083288]: Added
+	targets to allow easier tracing of shell and test invokations.
+
+	* unix/configure.in: [Bug 942170]:	Detect the st_blocks field of
+	* generic/tclCmdAH.c (StoreStatData):	'struct stat' correctly.
+	* generic/tclFileName.c (Tcl_GetBlocksFromStat):
+	* generic/tclIOUtil.c (Tcl_Stat):
+
+	* generic/tclInterp.c (TimeLimitCallback): [Bug 2891362]: Ensure that
+	* tests/interp.test (interp-34.13):	   the granularity ticker is
+	reset when we check limits because of the time limit event firing.
+
+2009-12-27  Donal K. Fellows  <dkf@users.sf.net>
+
+	* doc/namespace.n (SCOPED SCRIPTS): [Bug 2921538]: Updated example to
+	not be quite so ancient.
+
+2009-12-25  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tclCmdMZ.c:      CONST -> const
+	* generic/tclParse.c
+
+2009-12-23  Donal K. Fellows  <dkf@users.sf.net>
+
+	* library/safe.tcl (AliasSource, AliasExeName): [Bug 2913625]: Stop
+	information about paths from leaking through [info script] and [info
+	nameofexecutable].
+
+2009-12-23  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* unix/tcl.m4:		Install libtcl8.6.dll in bin directory
+	* unix/Makefile.in:
+	* unix/configure:	(regenerated)
+
+2009-12-22  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclCmdIL.c (Tcl_LsortObjCmd): [Bug 2918962]: Stop crash when
+	-index and -stride are used together.
+
+2009-12-21  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tclThreadStorage.c: Fix gcc warning, using gcc-4.3.4 on
+				      cygwin: missing initializer
+	* generic/tclOOInt.h:	      Prevent conflict with DUPLICATE
+				      definition in WINAPI's nb30.h
+	* generic/rege_dfa.c:	      Fix macro conflict on CYGWIN: don't use
+				      "small".
+	* generic/tcl.h:	      Include <winsock2.h> before <stdio.h> on
+				      CYGWIN
+	* generic/tclPathObj.c
+	* generic/tclPort.h
+	* tests/env.test:	      Don't unset WINDIR and TERM, it has a
+				      special meaning on CYGWIN (both in UNIX
+				      and WIN32 mode!)
+	* generic/tclPlatDecls.h:     Include <tchar.h> through tclPlatDecls.h
+	* win/tclWinPort.h:	      stricmp -> strcasecmp
+	* win/tclWinDde.c:	      _wcsicmp -> wcscasecmp
+	* win/tclWinFile.c
+	* win/tclWinPipe.c
+	* win/tclWinSock.c
+	* unix/tcl.m4:		      Add dynamic loading support to CYGWIN
+	* unix/configure (regenerated)
+	* unix/Makefile.in
+
+2009-12-19  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclBasic.c:	[Bug 2917627]: Fix for bad cmd resolution by
+	* tests/coroutine.test:	coroutines. Thanks to schelte for finding it.
+
+2009-12-16  Donal K. Fellows  <dkf@users.sf.net>
+
+	* library/safe.tcl (::safe::AliasGlob): Upgrade to correctly support a
+	larger fraction of [glob] functionality, while being stricter about
+	directory management.
+
+2009-12-11  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tclTest.c:	Fix gcc warning: ignoring return value of
+	* unix/tclUnixNotify.c:	"write", declared with attribute
+	* unix/tclUnixPipe.c:	warn_unused_result.
+	* generic/tclInt.decls:	CONSTify functions TclpGetUserHome and
+	* generic/tclIntDecls.h:TclSetPreInitScript (TIP #27)
+	* generic/tclInterp.c:
+	* win/tclWinFile.c:
+	* unix/tclUnixFile.c:
+
+2009-12-16  Donal K. Fellows  <dkf@users.sf.net>
+
+	* doc/tm.n: [Bug 1911342]: Formatting rewrite to avoid bogus crosslink
+	to the list manpage when generating HTML.
+
+	* library/msgcat/msgcat.tcl (Init): [Bug 2913616]: Do not use platform
+	tests that are not needed and which don't work in safe interpreters.
+
+2009-12-14  Donal K. Fellows  <dkf@users.sf.net>
+
+	* doc/file.n (file tempfile): [Bug 2388866]: Note that this only ever
+	creates files on the native filesystem. This is a design feature.
+
+2009-12-13  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclBasic.c:	Release TclPopCallFrame() from its
+	* generic/tclExecute.c:	tailcall-management duties
+	* generic/tclNamesp.c:
+
+	* generic/tclBasic.c:	Moving TclBCArgumentRelease call from
+	* generic/tclExecute.c:	TclNRTailcallObjCmd to TEBC, so that the
+	pairing of the Enter and Release calls is clearer.
+
+2009-12-12  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclTest.c (TestconcatobjCmd): [Bug 2895367]: Stop memory
+	leak when testing. We don't need extra noise of this sort when
+	tracking down real problems!
+
+2009-12-11  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tclBinary.c:	Fix gcc warning, using gcc-4.3.4 on cygwin
+	* generic/tclCompExpr.c:warning: array subscript has type 'char'
+	* generic/tclPkg.c:
+	* libtommath/bn_mp_read_radix.c:
+	* win/makefile.vc:	[Bug 2912773]: Revert to version 1.203
+	* unix/tclUnixCompat.c:	Fix gcc warning: signed and unsigned type
+				in conditional expression.
+
+2009-12-11  Donal K. Fellows  <dkf@users.sf.net>
+
+	* tools/tcltk-man2html.tcl (long-toc, cross-reference): [FRQ 2897296]:
+	Added cross links to sections within manual pages.
+
+2009-12-11  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclBasic.c:   [Bug 2806407]: Full nre-enabling of coroutines
+	* generic/tclExecute.c:
+
+	* generic/tclBasic.c: Small cleanup
+
+	* generic/tclExecute.c: Fix panic in http11.test caused by buggy
+	earlier commits in coroutine management.
+
+2009-12-10  Andreas Kupries  <andreask@activestate.com>
+
+	* generic/tclObj.c (TclContinuationsEnter): [Bug 2895323]: Updated
+	comments to describe when the function can be entered for the same
+	Tcl_Obj* multiple times. This is a continuation of the 2009-11-10
+	entry where a memory leak was plugged, but where not sure if that was
+	just a band-aid to paper over some other error. It isn't, this is a
+	legal situation.
+
+2009-12-10  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclBasic.c:   Reducing the # of moving parts for coroutines
+	* generic/tclExecute.c: by delegating more to tebc; eliminate the
+	special coroutine CallFrame.
+
+2009-12-09  Andreas Kupries  <andreask@activestate.com>
+
+	* generic/tclIO.c: [Bug 2901998]: Applied Alexandre Ferrieux's patch
+	fixing the inconsistent buffered I/O. Tcl's I/O now flushes buffered
+	output before reading, discards buffered input before writing, etc.
+
+2009-12-09  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclBasic.c: Ensure right lifetime of varFrame's (objc,objv)
+	for coroutines.
+
+	* generic/tclExecute.c: Code regrouping
+
+2009-12-09  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclBasic.c: Added some of the missing setting of errorcode
+	values.
+
+2009-12-08  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclExecute.c (TclStackFree): Improved panic msg.
+
+2009-12-08  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclBasic.c:   Partial nre-enabling of coroutines. The
+	* generic/tclExecute.c: initial call still requires its own
+	* generic/tclInt.h:     instance of tebc, but on resume coros can
+	execute in the caller's tebc.
+
+	* generic/tclExecute.c (TEBC): Silence warning about pcAdjustment.
+
+2009-12-08  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclExecute.c (TclExecuteByteCode): Make the dict opcodes
+	more sparing in their use of C variables, to reduce size of TEBC
+	activiation record a little bit.
+
+2009-12-07  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclExecute.c (TEBC): Grouping "slow" variables into structs,
+	to reduce register pressure and help the compiler with variable
+	allocation.
+
+2009-12-07  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclExecute.c: Start cleaning the TEBC stables
+	* generic/tclInt.h:
+
+	* generic/tclCmdIL.c:   [Bug 2910094]: Fix by aku
+	* tests/coroutine.test:
+
+	* generic/tclBasic.c: Arrange for [tailcall] to be created with the
+	other builtins: was being created in a separate call, leftover from
+	pre-tip days.
+
+2009-12-07  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclStrToD.c: [Bug 2902010]: Correct conditional compile
+	directives to better detect the toolchain that needs extra work for
+	proper underflow treatment instead of merely detecting the MIPS
+	platform.
+
+2009-12-07  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclBasic.c: [Patch 2910056]: Add ::tcl::unsupported::yieldTo
+	* generic/tclInt.h:
+
+2009-12-07  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclCmdMZ.c (TryPostBody): [Bug 2910044]: Close off memory
+	leak in [try] when a variable-free handler clause is present.
+
+2009-12-05  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclBasic.c:   Small changes for clarity in tailcall
+	* generic/tclExecute.c: and coroutine code.
+	* tests/coroutine.test:
+
+	* tests/tailcall.test: Remove some old unused crud; improved the
+	stack depth tests.
+
+	* generic/tclBasic.c:  Fixed things so that you can tailcall
+	* generic/tclNamesp.c: properly out of a coroutine.
+	* tests/tailcall.test:
+
+	* generic/tclInterp.c: Fixed tailcalls for same-interp aliases (no
+	test)
+
+2009-12-03  Donal K. Fellows  <dkf@users.sf.net>
+
+	* library/safe.tcl (::safe::AliasEncoding): Make the safe encoding
+	command behave more closely like the unsafe one (for safe ops).
+	(::safe::AliasGlob): [Bug 2906841]: Clamp down on evil use of [glob]
+	in safe interpreters.
+	* tests/safe.test: Rewrite to use tcltest2 better.
+
+2009-12-02  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* tools/genStubs.tcl:	Add support for win32 CALLBACK functions and
+	remove obsolete "emitStubs" and "genStubs" functions.
+	* win/Makefile.in:	Use tcltest86.dll for all tests, and add
+	.PHONY rules to preemptively stop trouble that plagued Tk from hitting
+	Tcl too.
+
+2009-11-30  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tcl.h:	Don't use EXPORT for Tcl_InitStubs
+	* win/Makefile.in:	Better dependancies in case of static build.
+
+2009-11-30  Donal K. Fellows  <dkf@users.sf.net>
+
+	* doc/Tcl.n: [Bug 2901433]: Improved description of expansion to
+	mention that it is using list syntax.
+
+2009-11-27  Kevin B. Kenny  <kennykb@acm.org>
+
+	* win/tclAppInit.c (Tcl_AppInit): [Bug 2902965]: Reverted Jan's change
+	that added a call to Tcl_InitStubs. The 'tclsh' and 'tcltest' programs
+	are providers, not consumers of the Stubs table, and should not link
+	with the Stubs library, but only with the main Tcl library. (In any
+	case, the presence of Tcl_InitStubs broke the build.)
+
+2009-11-27  Donal K. Fellows  <dkf@users.sf.net>
+
+	* doc/BoolObj.3, doc/Class.3, doc/CrtChannel.3, doc/DictObj.3:
+	* doc/DoubleObj.3, doc/Ensemble.3, doc/Environment.3:
+	* doc/FileSystem.3, doc/Hash.3, doc/IntObj.3, doc/Limit.3:
+	* doc/Method.3, doc/NRE.3, doc/ObjectType.3, doc/PkgRequire.3:
+	* doc/SetChanErr.3, doc/SetResult.3: [Patch 2903921]: Many small
+	spelling fixes from Larry Virden.
+
+	BUMP VERSION OF TCLOO TO 0.6.2. Too many people need accumulated small
+	versions and bugfixes, so the version-bump removes confusion.
+
+	* generic/tclOOBasic.c (TclOO_Object_LinkVar): [Bug 2903811]: Remove
+	unneeded restrictions on who can usefully call this method.
+
+2009-11-26  Donal K. Fellows  <dkf@users.sf.net>
+
+	* unix/Makefile.in: Add .PHONY rules and documentation to preemptively
+	stop trouble that plagued Tk from hitting Tcl too, and to make the
+	overall makefile easier to understand. Some reorganization too to move
+	related rules closer together.
+
+2009-11-26  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* win/Makefile.in:	[Bug 2902965]: Fix stub related changes that
+	* win/makefile.vc:	caused tclkit build to break.
+	* win/tclAppInit.c
+	* unix/tcl.m4
+	* unix/Makefile.in
+	* unix/tclAppInit.c
+	* unix/configure:	(regenerated)
+
+2009-11-25  Kevin B. Kenny  <kennykb@acm.org>
+
+	* win/Makefile.in:	Added a 'test-tcl' rule that is identical to
+	'test' except that it does not go spelunking in 'pkgs/'. (This rule
+	has existed in unix/Makefile.in for some time.)
+
+2009-11-25  Stuart Cassoff  <stwo@users.sf.net>
+
+	* unix/configure.in:	[Patch 2892871]: Remove unneeded
+	* unix/tcl.m4:		AC_STRUCT_TIMEZONE and use
+	* unix/tclConfig.h.in:	AC_CHECK_MEMBERS([struct stat.st_blksize])
+	* unix/tclUnixFCmd.c:	instead of AC_STRUCT_ST_BLKSIZE.
+	* unix/configure:	Regenerated with autoconf-2.59.
+
+2009-11-24  Andreas Kupries  <andreask@activestate.com>
+
+	* library/tclIndex: Manually redone the part of tclIndex dealing with
+	safe.tcl and tm.tcl. This part passes the testsuite. Note that
+	automatic regeneration of this part is not possible because it wrongly
+	puts 'safe::Setup' on the list, and wrongly leaves out 'safe::Log'
+	which is more dynamically created than the generator expects.
+
+	Further note that the file "clock.tcl" is explicitly loaded by
+	"init.tcl", the first time the clock command is invoked. The relevant
+	code can be found at line 172ff, roughly, the definition of the
+	procedure 'clock'. This means none of the procedures of this file
+	belong in the tclIndex. Another indicator that automatic regeneration
+	of tclIndex is ill-advised.
+
+2009-11-24  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclOO.c (FinalizeAlloc, Tcl_NewObjectInstance):
+	[Bug 2903011]: Make it an error to destroy an object in a constructor,
+	and also make sure that an object is not deleted twice in the error
+	case.
+
+2009-11-24  Pat Thoyts  <patthoyts@users.sourceforge.net>
+
+	* tests/fCmd.test: [Bug 2893771]: Teach [file stat] to handle locked
+	* win/tclWinFile.c: files so that [file exists] no longer lies.
+
+2009-11-23  Kevin Kenny  <kennykb@acm.org>
+
+	* tests/fCmd.test (fCmd-30.1): Changed registry location of the 'My
+	Documents' folder to the one that's correct for Windows 2000, XP,
+	Server 2003, Vista, Server 2008, and Windows 7. (See
+	http://support.microsoft.com/kb/310746)
+
+2009-11-23  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* win/tclWinDde.c:	#undef STATIC_BUILD, in order to make sure
+	* win/tclWinReg.c:	that Xxxxx_Init is always exported even when
+	* generic/tclTest.c:	Tcl is built static (otherwise we cannot
+				create a DLL).
+	* generic/tclThreadTest.c: Make all functions static, except
+				TclThread_Init.
+	* tests/fCmd.test:	Enable fCmd-30.1 when registry is available.
+	* win/tcl.m4:		Fix ${SHLIB_LD_LIBS} definition, fix conflicts
+	* win/Makefile.in:	Simplifications related to tcl.m4 changes.
+	* win/configure.in:	Between static libraries and import library on
+				windows.
+	* win/configure:	(regenerated)
+	* win/makefile.vc:	Add stub library to necessary link lines.
+
+2009-11-23  Kevin B. Kenny  <kennykb@acm.org>
+
+	* generic/tclThreadTest.c (NewTestThread): [Bug 2901803]: Further
+	machinations to get NewTestThread actually to launch the thread, not
+	just compile.
+
+2009-11-22  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclThreadTest.c (NewTestThread): [Bug 2901803]: Fix small
+	error in function naming which blocked a threaded test build.
+
+2009-11-19  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* win/Makefile.in:	Create tcltest86.dll as dynamic Tcltest
+				package.
+	* generic/tclTest.c:	Remove extraneous prototypes, follow-up to
+	* generic/tclTestObj.c:	[Bug 2883850]
+	* tests/chanio.test:	Test-cases for fixed [Bug 2849797]
+	* tests/io.test:
+	* tests/safe.test:	Fix safe-10.1 and safe-10.4 test cases, making
+				the wrong assumption that Tcltest is a static
+				package.
+	* generic/tclEncoding.c:[Bug 2857044]: Updated freeIntRepProc routines
+	* generic/tclVar.c:	so that they set the typePtr field to NULL so
+				that the Tcl_Obj is not left in an
+				inconsistent state.
+	* unix/tcl.m4:		[Patch 2883533]: tcl.m4 support for Haiku OS
+	* unix/configure:	autoconf-2.59
+
+2009-11-19  Don Porter  <dgp@users.sourceforge.net>
+
+	* unix/tclAppInit.c:	[Bug 2883850, 2900542]: Repair broken build of
+	* win/tclAppInit.c:	the tcltest executable.
+
+2009-11-19  Donal K. Fellows  <dkf@users.sf.net>
+
+	* library/auto.tcl (tcl_findLibrary):
+	* library/clock.tcl (MakeUniquePrefixRegexp, MakeParseCodeFromFields)
+	(SetupTimeZone, ProcessPosixTimeZone):	Restored the use of a literal
+	* library/history.tcl (HistAdd):	'then' when following a multi-
+	* library/safe.tcl (interpConfigure):	line test expresssion. It's an
+	* library/tm.tcl (UnknownHandler):	aid to readability then.
+
+2009-11-19  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tclInt.h:      Make all internal initialization
+	* generic/tclTest.c:     routines MODULE_SCOPE
+	* generic/tclTestObj.c:
+	* generic/tclTestProcBodyObj.c:
+	* generic/tclThreadTest.c:
+	* unix/Makefile.in:      Fix [Bug 2883850]: pkgIndex.tcl doesn't
+	* unix/tclAppInit.c:     get created with static Tcl build
+	* unix/tclXtTest.c:
+	* unix/tclXtNotify.c:
+	* unix/tclUnixTest.c:
+	* win/Makefile.in:
+	* win/tcl.m4:
+	* win/configure:         (regenerated)
+	* win/tclAppInit.c:
+	* win/tclWinDde.c:       Always compile with Stubs.
+	* win/tclWinReg.c:
+	* win/tclWinTest.c:
+
+2009-11-18  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* doc/CrtChannel.3:	[Bug 2849797]: Fix channel name inconsistences
+	* generic/tclIORChan.c:	as suggested by DKF.
+	* generic/tclIO.c:	Minor *** POTENTIAL INCOMPATIBILITY ***
+				because Tcl_CreateChannel() and derivatives
+				now sometimes ignore their "chanName"
+				argument.
+
+	* generic/tclAsync.c:	Eliminate various gcc warnings (with -Wextra)
+	* generic/tclBasic.c
+	* generic/tclBinary.c
+	* generic/tclCmdAH.c
+	* generic/tclCmdIL.c
+	* generic/tclCmdMZ.c
+	* generic/tclCompile.c
+	* generic/tclDate.c
+	* generic/tclExecute.c
+	* generic/tclDictObj.c
+	* generic/tclIndexObj.c
+	* generic/tclIOCmd.c
+	* generic/tclIOUtil.c
+	* generic/tclIORTrans.c
+	* generic/tclOO.c
+	* generic/tclZlib.c
+	* generic/tclGetDate.y
+	* win/tclWinInit.c
+	* win/tclWinChan.c
+	* win/tclWinConsole.c
+	* win/tclWinNotify.c
+	* win/tclWinReg.c
+	* library/auto.tcl:		Eliminate "then" keyword
+	* library/clock.tcl
+	* library/history.tcl
+	* library/safe.tcl
+	* library/tm.tcl
+	* library/http/http.tcl:	Eliminate unnecessary spaces
+	* library/http1.0/http.tcl
+	* library/msgcat/msgcat.tcl
+	* library/opt/optparse.tcl
+	* library/platform/platform.tcl
+	* tools/tcltk-man2html.tcl
+	* tools/tclZIC.tcl
+	* tools/tsdPerf.c
+
+2009-11-17  Andreas Kupries  <andreask@activestate.com>
+
+	* unix/tclUnixChan.c (TtyParseMode): Partial undo of Donal's tidy-up
+	from a few days ago (2009-11-9, not in ChangeLog). It seems that
+	strchr is apparently a macro on AIX and reacts badly to pre-processor
+	directives in its arguments.
+
+2009-11-16  Alexandre Ferrieux  <ferrieux@users.sourceforge.net>
+
+	* generic/tclEncoding.c:  [Bug 2891556]: Fix and improve test to
+	* generic/tclTest.c:	  detect similar manifestations in the future.
+	* tests/encoding.test:    Add tcltest support for finalization.
+
+2009-11-15  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* win/tclWinDde.c: Avoid gcc compiler warning by explicitly casting
+	DdeCreateStringHandle argument.
+
+2009-11-12  Andreas Kupries  <andreask@activestate.com>
+
+	* generic/tclIO.c (CopyData): [Bug 2895565]: Dropped bogosity which
+	* tests/io.test: used the number of _written_ bytes or character to
+	update the counters for the read bytes/characters. New test io-53.11.
+	This is a forward port from the 8.5 branch.
+
+2009-11-11  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclClock.c (TclClockInit):    Do not create [clock] support
+	commands in safe interps.
+
+2009-11-11  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* library/http/http.tcl (http::geturl): [Bug 2891171]: URL checking
+	too strict when using multiple question marks.
+	* tests/http.test
+	* library/http/pkgIndex.tcl:  Bump to http 2.8.2
+	* unix/Makefile.in:
+	* win/Makefile.in:
+
+2009-11-11  Alexandre Ferrieux  <ferrieux@users.sourceforge.net>
+
+	* generic/tclIO.c: Fix [Bug 2888099] (close discards ENOSPC error) by
+	saving the errno from the first of two FlushChannel()s. Uneasy to
+	test; might need specific channel drivers. Four-hands with aku.
+
+2009-11-10  Pat Thoyts  <patthoyts@users.sourceforge.net>
+
+	* tests/winFCmd.test: Cleanup directories that have been set chmod
+	000. On Windows7 and Vista we really have no access and these were
+	getting left behind.
+	A few tests were changed to reflect the intent of the test where
+	setting a directory chmod 000 should prevent any modification. This
+	restriction was ignored on XP but is honoured on Vista
+
+2009-11-10  Andreas Kupries  <andreask@activestate.com>
+
+	* generic/tclBasic.c: Plug another leak in TCL_EVAL_DIRECT evaluation.
+	Forward port from Tcl 8.5 branch, change by Don Porter.
+
+	* generic/tclObj.c: [Bug 2895323]: Plug memory leak in
+	TclContinuationsEnter(). Forward port from Tcl 8.5 branch, change by
+	Don Porter.
+
+2009-11-09  Stuart Cassoff  <stwo@users.sf.net>
+
+	* win/README: [bug 2459744]: Removed outdated Msys + Mingw info.
+
+2009-11-09  Andreas Kupries  <andreask@activestate.com>
+
+	* generic/tclBasic.c (TclEvalObjEx): Moved the #280 decrement of
+	refCount for the file path out of the branch after the whole
+	conditional, closing a memory leak. Added clause on structure type to
+	prevent seg.faulting. Forward port from valgrinding the Tcl 8.5
+	branch.
+
+	* tests/info.test: Resolve ambiguous resolution of variable "res".
+	Forward port from 8.5
+
+2009-11-08  Donal K. Fellows  <dkf@users.sf.net>
+
+	* doc/string.n (bytelength): Noted that this command is not a good
+	thing to use, and suggested a better alternatve. Also factored out the
+	description of the indices into its own section.
+
+2009-11-07  Pat Thoyts  <patthoyts@users.sourceforge.net>
+
+	* tests/fCmd.test: [Bug 2891026]: Exclude tests using chmod 555
+	directories on vista and win7. The current user has access denied and
+	so cannot rename the directory without admin privileges.
+
+2009-11-06  Andreas Kupries  <andreask@activestate.com>
+
+	* library/safe.tcl (::safe::Setup): Added documentation of the
+	contents of the state array. Also killed the 'InterpState' procedure
+	with its upleveled variable/upvar combination, and replaced all uses
+	with 'namespace upvar'.
+
+2009-11-05  Andreas Kupries  <andreask@activestate.com>
+
+	* library/safe.tcl: A series of patches which bring the SafeBase up to
+	date with code guidelines, Tcl's features, also eliminating a number
+	of inefficiencies along the way.
+	(1) Changed all procedure names to be fully qualified.
+	(2) Moved the procedures out of the namespace eval. Kept their
+	locations. IOW, broke the namespace eval apart into small sections not
+	covering the procedure definitions.
+	(3) Reindented the code. Just lots of whitespace changes.
+	Functionality unchanged.
+	(4) Moved the multiple namespace eval's around. Command export at the
+	top, everything else (var decls, argument parsing setup) at the
+	bottom.
+	(5) Moved the argument parsing setup into a procedure called when the
+	code is loaded. Easier management of temporary data.
+	(6) Replaced several uses of 'Set' with calls to the new procedure
+	'InterpState' and direct access to the per-slave state array.
+	(7) Replaced the remaining uses of 'Set' and others outside of the
+	path/token handling, and deleted a number of procedures related to
+	state array access which are not used any longer.
+	(8) Converted the path token system to cache normalized paths and path
+	<-> token conversions. Removed more procedures not used any longer.
+	Removed the test cases 4.3 and 4.4 from safe.test. They were testing
+	the now deleted command "InterpStateName".
+	(9) Changed the log command setup so that logging is compiled out
+	completely when disabled (default).
+	(10) Misc. cleanup. Inlined IsInterp into CheckInterp, its only user.
+	Consistent 'return -code error' for error reporting. Updated to use
+	modern features (lassign, in/ni, dicts). The latter are used to keep a
+	reverse path -> token map and quicker check of existence.
+	(11) Fixed [Bug 2854929]: Recurse into all subdirs under all TM root
+	dirs and put them on the access path.
+
+2009-11-02  Kevin B. Kenny  <kennykb@acm.org>
+
+	* library/tzdata/Asia/Novokuznetsk: New tzdata locale for Kemerovo
+	oblast', which now keeps Novosibirsk time and not Kranoyarsk time.
+	* library/tzdata/Asia/Damascus: Syrian DST changes.
+	* library/tzdata/Asia/Hong_Kong: Hong Kong historic DST corrections.
+	Olson tzdata2009q.
+
+2009-11-02  Donal K. Fellows  <dkf@users.sf.net>
+
+	* doc/object.n (DESCRIPTION): Substantive revision to make it clearer
+	what the fundamental semantics of an object actually are.
+
+2009-11-01  Joe Mistachkin  <joe@mistachkin.com>
+
+	* doc/Cancel.3: Minor cosmetic fixes.
+	* win/makefile.vc: Make htmlhelp target work again.  An extra set of
+	double quotes around the definition of the HTML help compiler tool
+	appears to be required.  Previously, there was one set of double
+	quotes around the definition of the tool and one around the actual
+	invocation.  This led to confusion because it was the only such tool
+	path to include double quotes around its invocation.  Also, it was
+	somewhat inflexible in the event that somebody needed to override the
+	tool command to include arguments.  Therefore, even though it may look
+	"wrong", there are now two double quotes on either side of the tool
+	path definition.  This fixes the problem that currently prevents the
+	htmlhelp target from building and maintains flexibility in case
+	somebody needs to override it via the command line or an environment
+	variable.
+
+2009-11-01  Joe English  <jenglish@users.sourceforge.net>
+
+	* doc/Eval.3, doc/Cancel.3: Move TIP#285 routines out of Eval.3 into
+	their own manpage.
+
+2009-10-31  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclBasic.c (ExprRoundFunc): [Bug 2889593]: Correctly report
+	the expected number of arguments when generating an error for round().
+
+2009-10-30  Pat Thoyts  <patthoyts@users.sourceforge.net>
+
+	* tests/tcltest.test: When creating the notwritabledir we deny the
+	current user access to delete the file. We must grant this right when
+	we cleanup. Required on Windows 7 when the user does not automatically
+	have administrator rights.
+
+2009-10-29  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tcl.h:        Changed the typedef for the mp_digit type
+	from:
+		typedef unsigned long mp_digit;
+	to:
+		typedef unsigned int mp_digit;
+	For 32-bit builds where "long" and "int" are two names for the same
+	thing, this is no change at all.  For 64-bit builds, though, this
+	causes the dp[] array of an mp_int to be made up of 32-bit elements
+	instead of 64-bit elements.  This is a huge improvement because
+	details elsewhere in the mp_int implementation cause only 28 bits of
+	each element to be actually used storing number data.  Without this
+	change bignums are over 50% wasted space on 64-bit systems.  [Bug
+	2800740].
+
+	***POTENTIAL INCOMPATIBILITY***
+	For 64-bit builds, callers of routines with (mp_digit) or (mp_digit *)
+	arguments *will*, and callers of routines with (mp_int *) arguments
+	*may* suffer both binary and stubs incompatibilities with Tcl releases
+	8.5.0 - 8.5.7.  Such possibilities should be checked, and if such
+	incompatibilities are present, suitable [package require] requirements
+	on the Tcl release should be put in place to keep such built code
+	[load]-ing only in Tcl interps that are compatible.
+
+2009-10-29  Donal K. Fellows  <dkf@users.sf.net>
+
+	* tests/dict.test: Make variable-clean and simplify tests by utilizing
+	the fact that dictionaries have defined orders.
+
+	* generic/tclZlib.c (TclZlibCmd): Remove accidental C99-ism which
+	reportedly makes the AIX native compiler choke.
+
+2009-10-29  Kevin B. Kenny  <kennykb@acm.org>
+
+	* library/clock.tcl (LocalizeFormat):
+	* tests/clock.test (clock-67.1):
+	[Bug 2819334]: Corrected a problem where '%%' followed by a letter in
+	a format group could expand recursively: %%R would turn into %%H:%M:%S
+
+2009-10-28  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclLiteral.c:	[Bug 2888044]: Fixed 2 bugs.
+	* tests/info.test:	First, as noted in the comments of the
+	TclCleanupLiteralTable routine, since the teardown of the intrep of
+	one Tcl_Obj can cause the teardown of others in the same table, the
+	full table cleanup must be done with care, but the code did not
+	contain the same care demanded in the comment.  Second, recent
+	additions to the info.test file had poor hygiene, leaving an array
+	variable ::a lying around, which breaks later interp.test tests during
+	a -singleproc 1 run of the test suite.
+
+2009-10-28  Kevin B. Kenny  <kennykb@acm.org>
+
+	* tests/fileName.test (fileName-20.[78]): Corrected poor test
+	hygiene (failure to save and restore the working directory) that
+	caused these two tests to fail on Windows (and [Bug 2806250] to be
+	reopened).
+
+2009-10-27  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclPathObj.c: [Bug 2884203]: Missing refcount on cached
+	normalized path caused crashes.
+
+2009-10-27  Kevin B. Kenny  <kennykb@acm.org>
+
+	* library/clock.tcl (ParseClockScanFormat): [Bug 2886852]: Corrected a
+	problem where [clock scan] didn't load the timezone soon enough when
+	processing a time format that lacked a complete date.
+	* tests/clock.test (clock-66.1):
+	Added a test case for the above bug.
+	* library/tzdata/America/Argentina/Buenos_Aires:
+	* library/tzdata/America/Argentina/Cordoba:
+	* library/tzdata/America/Argentina/San_Luis:
+	* library/tzdata/America/Argentina/Tucuman:
+	New DST rules for Argentina. (Olson's tzdata2009p.)
+
+2009-10-26  Don Porter  <dgp@users.sourceforge.net>
+
+	* unix/Makefile.in:	Remove $(PACKAGE).* and prototype from the
+	`make distclean` target.  Completes 2009-10-20 commit.
+
+2009-10-24  Kevin B. Kenny  <kennykb@acm.org>
+
+	* library/clock.tcl (ProcessPosixTimeZone):
+	Corrected a regression in the fix to [Bug 2207436] that caused
+	[clock] to apply EU daylight saving time rules in the US.
+	Thanks to Karl Lehenbauer for reporting this regression.
+	* tests/clock.test (clock-52.4):
+	Added a regression test for the above bug.
+	* library/tzdata/Asia/Dhaka:
+	* library/tzdata/Asia/Karachi:
+	New DST rules for Bangladesh and Pakistan. (Olson's tzdata2009o.)
+
+2009-10-23  Andreas Kupries  <andreask@activestate.com>
+
+	* generic/tclIO.c (FlushChannel): Skip OutputProc for low-level
+	0-length writes. When closing pipes which have already been closed
+	not skipping leads to spurious SIG_PIPE signals. Reported by
+	Mikhail Teterin <mi+thun@aldan.algebra.com>.
+
+2009-10-22  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclOOBasic.c (TclOO_Object_VarName): [Bug 2883857]: Allow
+	the passing of array element names through this method.
+
+2009-10-21  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclPosixStr.c: [Bug 2882561]: Work around oddity on Haiku OS
+	where SIGSEGV and SIGBUS are the same value.
+
+	* generic/tclTrace.c (StringTraceProc): [Bug 2881259]: Added back cast
+	to work around silly bug in MSVC's handling of auto-casting.
+
+2009-10-20  Don Porter  <dgp@users.sourceforge.net>
+
+	* unix/Makefile.in:	Removed the long outdated and broken targets
+	package-* that were for building Solaris packages.  Appears that the
+	pieces needed for these targets to function have never been present in
+	the current era of Tcl development and belong completely to Tcl
+	pre-history.
+
+2009-10-19  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclIO.c:      [Patch 2107634]: Revised ReadChars and
+	FilterInputBytes routines to permit reads to continue up to the string
+	limits of Tcl values.  Before revisions, large read attempts could
+	panic when as little as half the limiting value length was reached.
+	Thanks to Sean Morrison and Bob Parker for their roles in the fix.
+
+2009-10-18  Joe Mistachkin  <joe@mistachkin.com>
+
+	* generic/tclObj.c (TclDbDumpActiveObjects, TclDbInitNewObj)
+	(Tcl_DbIncrRefCount, Tcl_DbDecrRefCount, Tcl_DbIsShared):
+	[Bug 2871908]: Enforce separation of concerns between the lineCLPtr
+	and objThreadMap thread specific data members.
+
+2009-10-18  Joe Mistachkin  <joe@mistachkin.com>
+
+	* tests/thread.test (thread-4.[345]): [Bug 1565466]: Correct tests to
+	save their error state before the final call to threadReap just in
+	case it triggers an "invalid thread id" error.  This error can occur
+	if one or more of the target threads has exited prior to the attempt
+	to send it an asynchronous exit command.
+
+2009-10-17  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclVar.c (UnsetVarStruct, TclDeleteNamespaceVars)
+	(TclDeleteCompiledLocalVars, DeleteArray):
+	* generic/tclTrace.c (Tcl_UntraceVar2): [Bug 2629338]: Stop traces
+	that are deleted part way through (a feature used by tdom) from
+	causing freed memory to be accessed.
+
+2009-10-08  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclDictObj.c (DictIncrCmd): [Bug 2874678]: Don't leak any
+	bignums when doing [dict incr] with a value.
+	* tests/dict.test (dict-19.3): Memory leak detection code.
+
+2009-10-07  Andreas Kupries  <andreask@activestate.com>
+
+	* generic/tclObj.c: [Bug 2871908]: Plug memory leaks of objThreadMap
+	and lineCLPtr hashtables.  Also make the names of the continuation
+	line information initialization and finalization functions more
+	consistent. Patch supplied by Joe Mistachkin <joe@mistachkin.com>.
+
+	* generic/tclIORChan.c (ErrnoReturn): Replace hardwired constant 11
+	with proper errno #define, EAGAIN. What was I thinking? The BSD's have
+	a different errno assignment and break with the hardwired number.
+	Reported by emiliano on the chat.
+
+2009-10-06  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclInterp.c (SlaveEval): Agressive stomping of internal reps
+	was added as part of the NRE patch of 2008-07-13.  This doesn't appear
+	to actually be needed, and it hurts quite a bit when large lists lose
+	their intreps and require reparsing.  Thanks to Ashok Nadkarni for
+	reporting the problem.
+
+	* generic/tclTomMathInt.h (new): Public header tclTomMath.h had
+	* generic/tclTomMath.h:	dependence on private headers, breaking use
+	* generic/tommath.h:	by extensions [Bug 1941434].
+
+2009-10-05  Andreas Kupries  <andreask@activestate.com>
+
+	* library/safe.tcl (AliasGlob): Fixed conversion of catch to
+	try/finally, it had an 'on ok msg' branch missing, causing a silent
+	error immediately, and bogus glob results, breaking search for Tcl
+	modules.
+
+2009-10-04  Daniel Steffen  <das@users.sourceforge.net>
+
+	* macosx/tclMacOSXBundle.c:	[Bug 2569449]: Workaround CF memory
+	* unix/tclUnixInit.c:		managment bug in Mac OS X 10.4 &
+					earlier.
+
+2009-10-02  Kevin B. Kenny  <kennykb@acm.org>
+
+	* library/tzdata/Africa/Cairo:
+	* library/tzdata/Asia/Gaza:
+	* library/tzdata/Asia/Karachi:
+	* library/tzdata/Pacific/Apia:	Olson's tzdata2009n.
+
+2009-09-29  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclDictObj.c:		[Bug 2857044]: Updated freeIntRepProc
+	* generic/tclExecute.c:		routines so that they set the typePtr
+	* generic/tclIO.c:		field to NULL so that the Tcl_Obj is
+	* generic/tclIndexObj.c:	not left in an inconsistent state.
+	* generic/tclInt.h:
+	* generic/tclListObj.c:
+	* generic/tclNamesp.c:
+	* generic/tclOOCall.c:
+	* generic/tclObj.c:
+	* generic/tclPathObj.c:
+	* generic/tclProc.c:
+	* generic/tclRegexp.c:
+	* generic/tclStringObj.c:
+
+	* generic/tclAlloc.c:           Cleaned up various routines in the
+	* generic/tclCkalloc.c:         call stacks for memory allocation to
+	* generic/tclInt.h:             guarantee that any size values computed
+	* generic/tclThreadAlloc.c:     are within the domains of the routines
+	they get passed to.  [Bugs 2557696 and 2557796].
+
+2009-09-28  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclCmdMZ.c:	Replaced TclProcessReturn() calls with
+	* tests/error.test:	Tcl_SetReturnOptions() calls as a simple fix
+	for [Bug 2855247].  Thanks to Anton Kovalenko for the report and fix.
+	Additional fixes for other failures demonstrated by new tests.
+
+2009-09-27  Don Porter  <dgp@users.sourceforge.net>
+
+	* tests/error.test (error-15.8.*):	Coverage tests illustrating
+	flaws in the propagation of return options by [try].
+
+2009-09-26  Donal K. Fellows  <dkf@users.sf.net>
+
+	* unix/tclooConfig.sh, win/tclooConfig.sh: [Bug 2026844]: Added dummy
+	versions of tclooConfig.sh that make it easier to build extensions
+	against both Tcl8.5+TclOO-standalone and Tcl8.6.
+
+2009-09-24  Don Porter  <dgp@users.sourceforge.net>
+
+	TIP #356 IMPLEMENTATION
+
+	* generic/tcl.decls:	Promote internal routine TclNRSubstObj()
+	* generic/tclCmdMZ.c:	to public Tcl_NRSubstObj().  Still needs docs.
+	* generic/tclCompile.c:
+	* generic/tclInt.h:
+
+	* generic/tclDecls.h:	make genstubs
+	* generic/tclStubInit.c:
+
+2009-09-23  Miguel Sofer  <msofer@users.sf.net>
+
+	* doc/namespace.n: the description of [namespace unknown] failed
+	to mention [namespace path]: fixed. Thx emiliano.
+
+2009-09-21  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* tests/regexp.test: Added check for error message from
+	unbalanced [] in regexp. Added additional simple test cases
+	of basic regsub command.
+
+2009-09-21  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclCompile.c:	Correct botch in the conversion of
+	Tcl_SubstObj().  Thanks to Kevin Kenny for detection and report.
+
+2009-09-17  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclCompile.c:	Re-implement Tcl_SubstObj() as a simple
+	* generic/tclParse.c:	wrapper around TclNRSubstObj().  This has
+	* tests/basic.test:	the effect of caching compiled bytecode in
+	* tests/parse.test:	the value to be substituted.  Note that
+	Tcl_SubstObj() now exists only for extensions.  Tcl itself no longer
+	makes any use of it.  Note also that TclSubstTokens() is now reachable
+	only by Tcl_EvalEx() and Tcl_ParseVar() so tests aiming to test its
+	functioning needed adjustment to still have the intended effect.
+
+2009-09-16  Alexandre Ferrieux  <ferrieux@users.sourceforge.net>
+
+	* generic/tclObj.c:   Extended ::tcl::unsupported::representation.
+
+2009-09-11  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclBasic.c:	Completed the NR-enabling of [subst].
+	* generic/tclCmdMZ.c:	[Bug 2314561].
+	* generic/tclCompCmds.c:
+	* generic/tclCompile.c:
+	* generic/tclInt.h:
+	* tests/coroutine.test:
+	* tests/parse.test:
+
+2009-09-11  Donal K. Fellows  <dkf@users.sf.net>
+
+	* tests/http.test: Added in cleaning up of http tokens for each test
+	to reduce amount of global-variable pollution.
+
+2009-09-10  Donal K. Fellows  <dkf@users.sf.net>
+
+	* library/http/http.tcl (http::Event): [Bug 2849860]: Handle charset
+	names in double quotes; some servers like generating them like that.
+
+2009-09-07  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclParse.c:	[Bug 2850901]: Corrected line counting error
+	* tests/into.test:	in multi-command script substitutions.
+
+2009-09-07  Daniel Steffen  <das@users.sourceforge.net>
+
+	* generic/tclExecute.c:	Fix potential uninitialized variable use and
+	* generic/tclFCmd.c:	null dereference flagged by clang static
+	* generic/tclProc.c:	analyzer.
+	* generic/tclTimer.c:
+	* generic/tclUtf.c:
+
+	* generic/tclExecute.c:	Silence false positives from clang static
+	* generic/tclIO.c:	analyzer about potential null dereference.
+	* generic/tclScan.c:
+	* generic/tclCompExpr.c:
+
+2009-09-04  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclCompCmds.c (TclCompileSubstCmd): [Bug 2314561]:
+	* generic/tclBasic.c:	Added a bytecode compiler routine for the
+	* generic/tclCmdMZ.c:	[subst] command. This is a partial solution to
+	* generic/tclCompile.c:	the need to NR-enable [subst] since bytecode
+	* generic/tclCompile.h:	execution is already NR-enabled. Two new
+	* generic/tclExecute.c:	bytecode instructions, INST_NOP and
+	* generic/tclInt.h:	INST_RETURN_CODE_BRANCH were added to support
+	* generic/tclParse.c:	the new routine.  INST_RETURN_CODE_BRANCH is
+	* tests/basic.test:	likely to be useful in any future effort to
+	* tests/info.test:	add a bytecode compiler routine for [try].
+	* tests/parse.test:
+
+2009-09-03  Donal K. Fellows  <dkf@users.sf.net>
+
+	* doc/LinkVar.3: [Bug 2844962]: Added documentation of issues relating
+	to use of this API in a multi-threaded environment.
+
+2009-09-01  Andreas Kupries  <andreask@activestate.com>
+
+	* generic/tclIORTrans.c (ReflectInput): Remove error response to
+	0-result from method 'limit?' of transformations. Return the number of
+	copied bytes instead, which is possibly nothing. The latter then
+	triggers EOF handling in the higher layers, making the 0-result of
+	limit? the way to inject artificial EOF's into the data stream.
+
+2009-09-01  Don Porter  <dgp@users.sourceforge.net>
+
+	* library/tcltest/tcltest.tcl:  Bump to tcltest 2.3.2 after revision
+	* library/tcltest/pkgIndex.tcl: to verbose error message.
+	* unix/Makefile.in:
+	* win/Makefile.in:
+
+2009-08-27  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclStringObj.c:       [Bug 2845535]: A few more string
+	overflow cases in [format].
+
+2009-08-25  Andreas Kupries  <andreask@activestate.com>
+
+	* generic/tclBasic.c (Tcl_CreateInterp, Tcl_EvalTokensStandard)
+	(Tcl_EvalEx, TclEvalEx, TclAdvanceContinuations, TclNREvalObjEx):
+	* generic/tclCmdMZ.c (Tcl_SwitchObjCmd, TclListLines):
+	* generic/tclCompCmds.c (*):
+	* generic/tclCompile.c (TclSetByteCodeFromAny, TclInitCompileEnv)
+	(TclFreeCompileEnv, TclCompileScript, TclCompileTokens):
+	* generic/tclCompile.h (CompileEnv):
+	* generic/tclInt.h (ContLineLoc, Interp):
+	* generic/tclObj.c (ThreadSpecificData, ContLineLocFree)
+	(TclThreadFinalizeObjects, TclInitObjSubsystem, TclContinuationsEnter,
+	(TclContinuationsEnterDerived, TclContinuationsCopy, TclFreeObj)
+	(TclContinuationsGet):
+	* generic/tclParse.c (TclSubstTokens, Tcl_SubstObj):
+	* generic/tclProc.c (TclCreateProc):
+	* generic/tclVar.c (TclPtrSetVar):
+	* tests/info.test (info-30.0-24):
+
+	Extended the parser, compiler, and execution engine with code and
+	attendant data structures tracking the position of continuation lines
+	which are not visible in the resulting script Tcl_Obj*'s, to properly
+	account for them while counting lines for #280.
+
+2009-08-24  Daniel Steffen  <das@users.sourceforge.net>
+
+	* generic/tclInt.h: Annotate Tcl_Panic as noreturn for clang static
+	analyzer in PURIFY builds, replacing preprocessor/assert technique.
+
+	* macosx/tclMacOSXNotify.c: Fix multiple issues with nested event loops
+	when CoreFoundation notifier is running in embedded mode. (Fixes
+	problems in TkAqua Cocoa reported by Youness Alaoui on tcl-mac)
+
+2009-08-21  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclFileName.c: Correct regression in [Bug 2837800] fix.
+	* tests/fileName.test:
+
+2009-08-20  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclFileName.c: [Bug 2837800]: Correct the result produced by
+	[glob */test] when * matches something like ~foo.
+
+	* generic/tclPathObj.c: [Bug 2806250]: Prevent the storage of strings
+	starting with ~ in the "tail" part (normPathPtr field) of the path
+	intrep when PATHFLAGS != 0.  This establishes the assumptions relied
+	on elsewhere that the name stored there is a relative path.  Also
+	refactored to make an AppendPath() routine instead of the cut/paste
+	stanzas that were littered throughout.
+
+2009-08-20  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclCmdIL.c (TclNRIfObjCmd): [Bug 2823276]: Make [if]
+	NRE-safe on all arguments when interpreted.
+	(Tcl_LsortObjCmd): Close off memory leak.
+
+2009-08-19  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclCmdAH.c (TclNRForObjCmd, etc.): [Bug 2823276]: Make [for]
+	and [while] into NRE-safe commands, even when interpreted.
+
+2009-08-18  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclPathObj.c: [Bug 2837800]: Added NULL check to prevent
+	* tests/fileName.test:  crashes during [glob].
+
+2009-08-16  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* unix/dltest/pkge.c:  const addition
+	* unix/tclUnixThrd.c:  Use <pthread.h> in stead of "pthread.h"
+	* win/tclWinDde.c:     Eliminate some more gcc warnings
+	* win/tclWinReg.c:
+	* generic/tclInt.h:    Change ForIterData, make it const-safe.
+	* generic/tclCmdAH.c:
+
+2009-08-12  Don Porter  <dgp@users.sourceforge.net>
+
+	TIP #353 IMPLEMENTATION
+
+	* doc/NRE.3:		New public routine Tcl_NRExprObj() permits
+	* generic/tcl.decls:	extension commands to evaluate Tcl expressions
+	* generic/tclBasic.c:	in NR-enabled command procedures.
+	* generic/tclCmdAH.c:
+	* generic/tclExecute.c:
+	* generic/tclInt.h:
+	* generic/tclObj.c:
+	* tests/expr.test:
+
+	* generic/tclDecls.h:		make genstubs
+	* generic/tclStubInit.c:
+
+2009-08-06  Andreas Kupries  <andreask@activestate.com>
+
+	* doc/refchan.n [Bug 2827000]: Extended the implementation of
+	* generic/tclIORChan.c: reflective channels (TIP 219, method
+	* tests/ioCmd.test: 'read'), enabling handlers to signal EAGAIN to
+	indicate 'no data, but not at EOF either', and other system
+	errors. Updated documentation, extended testsuite (New test cases
+	iocmd*-23.{9,10}).
+
+2009-08-02  Miguel Sofer  <msofer@users.sf.net>
+
+	* tests/coroutine.test: fix testfile cleanup
+
+2009-08-02  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclObj.c (Tcl_RepresentationCmd): Added an unsupported
+	command for reporting the representation of an object. Result string
+	is deliberately a bit obstructive so that people are not encouraged to
+	make code that depends on it; it's a debugging tool only!
+
+	* unix/tclUnixFCmd.c (GetOwnerAttribute, SetOwnerAttribute)
+	(GetGroupAttribute, SetGroupAttribute): [Bug 1942222]: Stop calling
+	* unix/tclUnixFile.c (TclpGetUserHome): endpwent() and endgrent();
+	they've been unnecessary for ages.
+
+2009-08-02  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* win/tclWin32Dll.c: Eliminate TclWinResetInterfaceEncodings, since it
+	* win/tclWinInit.c:  does exactly the same as TclWinEncodingsCleanup,
+	* win/tclWinInt.h:   make sure that tclWinProcs and
+			     tclWinTCharEncoding are always set and reset
+			     concurrently.
+	* win/tclWinFCmd.c:  Correct check for win95
+
+2009-07-31  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclStringObj.c: [Bug 2830354]:	Corrected failure to
+	* tests/format.test:		grow buffer when format spec request
+	large width floating point values.  Thanks to Clemens Misch.
+
+2009-07-26  Donal K. Fellows  <dkf@users.sf.net>
+
+	* library/auto.tcl (tcl_findLibrary, auto_mkindex):
+	* library/package.tcl (pkg_mkIndex, tclPkgUnknown, MacOSXPkgUnknown):
+	* library/safe.tcl (interpAddToAccessPath, interpDelete, AliasGlob):
+	(AliasSource, AliasLoad, AliasEncoding):
+	* library/tm.tcl (UnknownHandler): Simplify by swapping some [catch]
+	gymnastics for use of [try].
+
+2009-07-26 Alexandre Ferrieux  <ferrieux@users.sourceforge.net>
+
+	* tools/genStubs.tcl: Forced LF translation when generating .h's to
+	avoid spurious diffs when regenerating on a Windows box.
+
+2009-07-26  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* win/Makefile.in: [Bug 2827066]: msys build --enable-symbols broken
+	* win/tcl.m4:	   And modified the same for unicows.dll, as a
+	* win/configure:   preparation for [Enh 2819611].
+
+2009-07-25  Donal K. Fellows  <dkf@users.sf.net>
+
+	* library/history.tcl (history): Reworked the history mechanism in
+	terms of ensembles, rather than the ad hoc ensemble-lite mechanism
+	used previously.
+
+2009-07-24  Donal K. Fellows  <dkf@users.sf.net>
+
+	* doc/self.n (self class): [Bug 2704302]: Add some text to make it
+	clearer how to get the name of the current object's class.
+
+2009-07-23  Andreas Kupries  <andreask@activestate.com>
+
+	* generic/tclIO.c (Tcl_GetChannelHandle): [Bug 2826248]: Do not crash
+	* generic/tclPipe.c (FileForRedirect): for getHandleProc == NULL, this
+	is allowed. Provide a nice error message in the bypass area. Updated
+	caller to check the bypass for a mesage. Bug reported by Andy
+	Sonnenburg <andy22286@users.sourceforge.net>
+
+2009-07-23  Joe Mistachkin  <joe@mistachkin.com>
+
+	* generic/tclNotify.c: [Bug 2820349]: Ensure that queued events are
+	freed once processed.
+
+2009-07-22  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* macosx/tclMacOSXFCmd.c: CONST -> const
+	* generic/tclGetDate.y:
+	* generic/tclDate.c:
+	* generic/tclLiteral.c: (char *) cast in ckfree call
+	* generic/tclPanic.c: [Feature Request 2814786]: remove TclpPanic
+	* generic/tclInt.h
+	* unix/tclUnixPort.h
+	* win/tclWinPort.h
+
+2009-07-22 Alexandre Ferrieux  <ferrieux@users.sourceforge.net>
+
+	* generic/tclEvent.c: [Bug 2001201 again]: Refined the 20090617 patch
+	on [exit] streamlining, so that it now correctly calls thread exit
+	handlers for the calling thread, including <Destroy> bindings in Tk.
+
+2009-07-21  Kevin B. Kenny  <kennykb@acm.org>
+
+	* library/tzdata/Asia/Dhaka:
+	* library/tzdata/Indian/Mauritius: Olson's tzdata2009k.
+
+2009-07-20  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclCmdMZ.c (StringIsCmd): Reorganize so that [string is] is
+	more efficient when parsing things that are correct, at a cost of
+	making the empty string test slightly more costly. With this, the cost
+	of doing [string is integer -strict $x] matches [catch {expr {$x+0}}]
+	in the successful case, and greatly outstrips it in the failing case.
+
+2009-07-19  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclOO.decls, generic/tclOO.c (Tcl_GetObjectName): Expose a
+	function for efficiently returning the current name of an object.
+
+2009-07-18  Daniel Steffen  <das@users.sourceforge.net>
+
+	* unix/Makefile.in: Define NDEBUG in optimized (non-symbols) build to
+	disable NRE assert()s and threaded allocator range checks.
+
+2009-07-16  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclBinary.c:	Removed unused variables.
+	* generic/tclCmdIL.c:
+	* generic/tclCompile.c:
+	* generic/tclExecute.c:
+	* generic/tclHash.c:
+	* generic/tclIOUtil.c:
+	* generic/tclVar.c:
+
+	* generic/tclBasic.c:	Silence compiler warnings about ClientData.
+	* generic/tclProc.c:
+
+	* generic/tclScan.c:    Typo in ACCEPT_NAN configuration.
+
+	* generic/tclStrToD.c:  [Bug 2819200]: Set floating point control
+	register on MIPS systems so that the gradual underflow expected by Tcl
+	is in effect.
+
+2009-07-15  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclInt.h (Namespace):		   Added machinery to allow
+	* generic/tclNamesp.c (many functions):	   reduction of memory used
+	* generic/tclResolve.c (BumpCmdRefEpochs): by namespaces. Currently
+	#ifdef'ed out because of compatibility concerns.
+
+	* generic/tclInt.decls: Added four functions for better integration
+	with itcl-ng.
+
+2009-07-14  Kevin B. Kenny  <kennykb@acm.org>
+
+	* generic/tclInt.h (TclNRSwitchObjCmd):
+	* generic/tclBasic.c (builtInCmds):
+	* generic/tclCmdMZ.c (Tcl_SwitchObjCmd):
+	* tests/switch.test (switch-15.1):
+	[Bug 2821401]: Make non-bytecoded [switch] command aware of NRE.
+
+2009-07-13  Andreas Kupries  <andreask@activestate.com>
+
+	* generic/tclCompile.c (TclInitCompileEnv, EnterCmdWordIndex)
+	(TclCleanupByteCode, TclCompileScript):
+	* generic/tclExecute.c (TclCompileObj, TclExecuteByteCode):
+	* tclCompile.h (ExtCmdLoc):
+	* tclInt.h (ExtIndex, CFWordBC, CmdFrame):
+	* tclBasic.c (DeleteInterpProc, TclArgumentBCEnter)
+	(TclArgumentBCRelease, TclArgumentGet, SAVE_CONTEXT)
+	(RESTORE_CONTEXT, NRCoroutineExitCallback, TclNRCoroutineObjCmd):
+	* generic/tclCmdAH.c (TclNRForObjCmd, TclNRForIterCallback,
+	(ForNextCallback):
+	* generic/tclCmdMZ.c (TclNRWhileObjCmd):
+
+	Extended the bytecode compiler initialization to recognize the
+	compilation of whole files (NRE enabled 'source' command) and switch
+	to the counting of absolute lines in that case.
+
+	Further extended the bytecode compiler to track the start line in the
+	generated information, and modified the bytecode execution to
+	recompile an object if the location as per the calling context doesn't
+	match the location saved in the bytecode. This part could be optimized
+	more by using more memory to keep all possibilities which occur
+	around, or by just adjusting the location information instead of a
+	total recompile.
+
+	Reworked the handling of literal command arguments in bytecode to be
+	saved (compiler) and used (execution) per command (See the
+	TCL_INVOKE_STK* instructions), and not per the whole bytecode. This,
+	and the previous change remove the problems with location data caused
+	by literal sharing (across whole files, but also proc bodies).
+	Simplified the associated datastructures (ExtIndex is gone, as is the
+	function EnterCmdWordIndex).
+
+	The last change causes the hashtable 'lineLABCPtr' to be state which
+	has to be kept per coroutine, like the CmdFrame stack. Reworked the
+	coroutine support code to create, delete and switch the information as
+	needed. Further reworked the tailcall command as well, it has to pop
+	its own arguments when run in a bytecode context to keep a proper
+	stack in 'lineLABCPtr'.
+
+	Fixed the mishandling of line information in the NRE-enabled 'for' and
+	'while' commands introduced when both were made to share their
+	iteration callbacks without taking into account that the loop body is
+	found in different words of the command. Introduced a separate data
+	structure to hold all the callback information, as we went over the
+	limit of 4 direct client-data values for NRE callbacks.
+
+	The above fixes [Bug 1605269].
+
+2009-07-12  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclCmdMZ.c (StringIndexCmd, StringEqualCmd, StringCmpCmd):
+	* generic/tclExecute.c (TclExecuteByteCode): [Bug 2637173]: Factor out
+	* generic/tclInt.h (TclIsPureByteArray):     the code to determine if
+	* generic/tclUtil.c (TclStringMatchObj):     it is safe to work with
+	byte arrays directly, so that we get the check correct _once_.
+
+	* generic/tclOOCall.c (TclOOGetCallContext): [Bug 1895546]: Changed
+	* generic/tclOO.c (TclOOObjectCmdCore):	     the way that the cache is
+	managed so that when itcl does cunning things, those cunning things
+	can be cached properly.
+
+2009-07-11  Donal K. Fellows  <dkf@users.sf.net>
+
+	* doc/vwait.n: Substantially increased the discussion of issues and
+	work-arounds relating to nested vwaits, following discussion on the
+	tcl-core mailing list on the topic.
+
+2009-07-10  Pat Thoyts  <patthoyts@users.sourceforge.net>
+
+	* tests/zlib.test:   ZlibTransformClose may be called with a NULL
+	* generic/tclZlib.c: interpreter during finalization and
+	Tcl_SetChannelError requires a list. Added some tests to ensure error
+	propagation from the zlib library to the interp.
+
+2009-07-09  Pat Thoyts  <patthoyts@users.sourceforge.net>
+
+	* tests/zlib.test: [Bug 2818131]: Added tests and fixed a typo that
+	broke [zlib push] for deflate format.
+
+2009-07-09  Donal K. Fellows  <dkf@users.sf.net>
+
+	* compat/mkstemp.c (mkstemp): [Bug 2819227]: Use rand() for random
+	numbers as it is more portable.
+
+2009-07-05  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclZlib.c (ZlibTransformWatch): Correct the handling of
+	events so that channel transforms work with things like an asynch
+	[chan copy]. Problem reported by Pat Thoyts.
+
+2009-07-01  Pat Thoyts  <patthoyts@users.sourceforge.net>
+
+	* win/tclWinInt.h:   [Bug 2806622]: Handle the GetUserName API call
+	* win/tclWin32Dll.c: via the tclWinProcs indirection structure. This
+	* win/tclWinInit.c:  fixes a problem obtaining the username when the
+	USERNAME environment variable is unset.
+
+2009-06-30  Daniel Steffen  <das@users.sourceforge.net>
+
+	* generic/tclInt.h:		Add assert macros for clang static
+	* generic/tclPanic.c:		analyzer and redefine Tcl_Panic to
+	* generic/tclStubInit.c:	assert after panic in clang PURIFY
+					builds.
+
+	* generic/tclCmdIL.c:		Add clang assert for false positive
+					from static analyzer.
+
+2009-06-26  Daniel Steffen  <das@users.sourceforge.net>
+
+	* macosx/Tcl-Common.xcconfig:	 Update projects for Xcode 3.1 and
+	* macosx/Tcl.xcode/*:		 3.2, standardize on gcc 4.2, remove
+	* macosx/Tcl.xcodeproj/*:	 obsolete configurations and pre-Xcode
+	* macosx/Tcl.pbproj/* (removed): project.
+
+	* macosx/README:		 Update project docs, cleanup.
+
+	* unix/Makefile.in:		 Update dist target for project
+					 changes.
+
+2009-06-24  Donal K. Fellows  <dkf@users.sf.net>
+
+	* tests/oo.test (oo-19.1): [Bug 2811598]: Make more resilient.
+
+2009-06-24  Pat Thoyts  <patthoyts@users.sourceforge.net>
+
+	* tests/http11.test: [Bug 2811492]: Clean up procs after testing.
+
+2009-06-18  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclCkalloc.c (MemoryCmd): [Bug 988703]:
+	* generic/tclObj.c (ObjData, TclFinalizeThreadObjects): Add mechanism
+	for discovering what Tcl_Objs are allocated when built for memory
+	debugging. Developed by Joe Mistachkin.
+
+2009-06-17 Alexandre Ferrieux  <ferrieux@users.sourceforge.net>
+
+	* generic/tclEvent.c: Applied a patch by George Peter Staplin
+	drastically reducing the ambition of [exit] wrt finalization, and
+	thus solving many multi-thread teardown issues. [Bugs 2001201,
+	486399, and possibly 597575, 990457, 1437595, 2750491]
+
+2009-06-15  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclStringObj.c: sprintf() -> Tcl_ObjPrintf() conversion.
+
+2009-06-15  Reinhard Max  <max@suse.de>
+
+	* unix/tclUnixPort.h: Move all socket-related code from tclUnixChan.c
+	* unix/tclUnixChan.c: to tclUnixSock.c.
+	* unix/tclUnixSock.c:
+
+2009-06-15  Donal K. Fellows  <dkf@users.sf.net>
+
+	* tools/tcltk-man2html.tcl (make-man-pages): [Patch 557486]: Apply
+	last remaining meaningful part of this patch, a clean up of some
+	closing tags.
+
+2009-06-13  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclCompile.c: [Bug 2802881]: The value stashed in
+	* generic/tclProc.c:    iPtr->compiledProcPtr when compiling a proc
+	* tests/execute.test:   survives too long. We only need it there long
+	enough for the right TclInitCompileEnv() call to re-stash it into
+	envPtr->procPtr.  Once that is done, the CompileEnv controls.  If we
+	let the value of iPtr->compiledProcPtr linger, though, then any other
+	bytecode compile operation that takes place will also have its
+	CompileEnv initialized with it, and that's not correct.  The value is
+	meant to control the compile of the proc body only, not other compile
+	tasks that happen along.  Thanks to Carlos Tasada for discovering and
+	reporting the problem.
+
+2009-06-10  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclStringObj.c:       [Bug 2801413]: Revised [format] to not
+	overflow the integer calculations computing the length of the %ll
+	formats of really big integers.  Also added protections so that
+	[format]s that would produce results overflowing the maximum string
+	length of Tcl values throw a normal Tcl error instead of a panic.
+
+	* generic/tclStringObj.c:	[Bug 2803109]: Corrected failures to
+	deal with the "pure unicode" representation of an empty string.
+	Thanks to Julian Noble for reporting the problem.
+
+2006-06-09  Kevin B. Kenny  <kennykb@acm.org>
+
+	* generic/tclGetDate.y: Fixed a thread safety bug in the generated
+	* library/clock.tcl:    Bison parser (needed a %pure-parser
+	* tests/clock.test:     declaration to avoid static variables).
+				Discovered that the %pure-parser declaration
+	                        allowed for returning the Bison error message
+	                        to the Tcl caller in the event of a syntax
+	                        error, so did so.
+	* generic/tclDate.c: bison 2.3
+
+2006-06-08  Kevin B. Kenny  <kennykb@acm.org>
+
+	* library/tzdata/Asia/Dhaka: New DST rule for Bangladesh. (Olson's
+	tzdata2009i.)
+
+2009-06-08  Donal K. Fellows  <dkf@users.sf.net>
+
+	* doc/copy.n: Fix error in example spotted by Venkat Iyer.
+
+2009-06-02  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclExecute.c: Replace dynamically-initialized table with a
+	table of static constants in the lookup table for exponent operator
+	computations that fit in a 64 bit integer result.
+
+	* generic/tclExecute.c: [Bug 2798543]: Corrected implementations and
+	selection logic of the INST_EXPON instruction.
+
+2009-06-01  Don Porter  <dgp@users.sourceforge.net>
+
+	* tests/expr.test:      [Bug 2798543]: Added many tests demonstrating
+	the broken cases.
+
+009-05-30  Kevin B. Kenny  <kennykb@acm.org>
+
+	* library/tzdata/Africa/Cairo:
+	* library/tzdata/Asia/Amman: Olson's tzdata2009h.
+
+2009-05-29  Andreas Kupries  <andreask@activestate.com>
+
+	* library/platform/platform.tcl: Fixed handling of cpu ia64,
+	* library/platform/pkgIndex.tcl: taking ia64_32 into account
+	* unix/Makefile.in: now. Bumped version to 1.0.5. Updated the
+	* win/Makefile.in: installation commands.
+
+2009-05-26 Alexandre Ferrieux  <ferrieux@users.sourceforge.net>
+
+	* doc/expr.n: Fixed documentation of the right-associativity of
+	the ** operator. (spotted by kbk)
+
+2009-05-14  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclOOInfo.c (InfoObjectNsCmd): Added introspection mechanism
+	for finding out what an object's namespace is. Experience suggests
+	that it is just too useful to be able to do without it.
+
+2009-05-12  Donal K. Fellows  <dkf@users.sf.net>
+
+	* doc/vwait.n: Added more words to make it clear just how bad it is to
+	nest [vwait]s.
+
+	* compat/mkstemp.c: Add more headers to make this file build on IRIX
+	6.5. Thanks to Larry McVoy for this.
+
+2009-05-08  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclOO.c (TclNRNewObjectInstance):  [Bug 2414858]: Add a
+	* generic/tclBasic.c (TclPushTailcallPoint): marker to the stack of
+	NRE callbacks at the right point so that tailcall works correctly in a
+	constructor.
+
+	* tests/exec.test (cat): [Bug 2788468]: Adjust the scripted version of
+	cat so that it does not perform transformations on the data it is
+	working with, making it more like the standard Unix 'cat' program.
+
+2009-05-07  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclObj.c (Tcl_GetCommandFromObj): [Bug 2785893]: Ensure that
+	a command in a deleted namespace can't be found through a cached name.
+
+	* generic/tclBasic.c:    Let coroutines start with a much smaller
+	* generic/tclCompile.h:  stack: 200 words (previously was 2000, the
+	* generic/tclExecute.c:  same as interps).
+
+2009-05-07  Donal K. Fellows  <dkf@users.sf.net>
+
+	* tests/env.test (printenvScript, env-4.3, env-4.5): [Bug 1513659]:
+	* tests/exec.test (exec-2.6): These tests had subtle dependencies on
+	being on platforms that were either ISO 8859-1 or UTF-8. Stabilized
+	the results by forcing the encoding.
+
+2009-05-06  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclCmdMZ.c:	[Bug 2582327]: Improve overflow error message
+	from [string repeat].
+
+	* tests/interp.test: interp-20.50 test for Bug 2486550.
+
+2009-05-04  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclOO.c (InitFoundation, AllocObject, AllocClass):
+	* generic/tclOODefineCmds.c (InitDefineContext): Make sure that when
+	support namespaces are deleted, nothing bad can subsequently happen.
+	Issue spotted by Don Porter.
+
+2009-05-03  Donal K. Fellows  <dkf@users.sf.net>
+
+	* doc/Tcl.n: [Bug 2538432]: Clarified exact treatment of ${arr(idx)}
+	form of variable substitution. This is not a change of behavior, just
+	an improved description of the current situation.
+
+2009-04-30  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclBasic.c (TclObjInvoke): [Bug 2486550]: Make sure that a
+	null objProc is not used, use Tcl_NRCallObjProc instead.
+
+2009-05-01  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* win/configure.in   Fix 64-bit detection for zlib on Win64
+	* win/configure      (regenerated)
+
+2009-04-28  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* unix/tcl.m4, unix/configure (SC_CONFIG_CFLAGS): harden the check to
+	add _r to CC on AIX with threads.
+
+2009-04-27  Donal K. Fellows  <dkf@users.sf.net>
+
+	* doc/concat.n (EXAMPLES): [Bug 2780680]: Rewrote so that the spacing
+	of result messages is correct. (The exact way they were wrong was
+	different when rendered through groff or as HTML, but it was still
+	wrong both ways.)
+
+2009-04-27  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tclIndexObj.c:  Reset internal INTERP_ALTERNATE_WRONG_ARGS
+	* generic/tclIOCmd.c:     flag inside the Tcl_WrongNumArgs function,
+	                          so the caller no longer has to do the reset.
+
+2009-04-24  Stuart Cassoff  <stwo@users.sf.net>
+
+	* unix/Makefile.in: [Patch 2769530]: Don't chmod/exec installManPage.
+
+2009-04-19  Pat Thoyts  <patthoyts@users.sourceforge.net>
+
+	* library/http/http.tcl: [Bug 2715421]: Removed spurious newline added
+	* tests/http11.test:     after POST and added tests to detect excess
+	* tests/httpd11.tcl:     bytes being POSTed.
+	* library/http/pkgIndex.tcl:
+	* makefiles:             package version now 2.8.1
+
+2009-04-15  Donal K. Fellows  <dkf@users.sf.net>
+
+	* doc/chan.n, doc/close.n: Tidy up documentation of TIP #332.
+
+2009-04-14  Kevin B. Kenny  <kennykb@acm.org>
+
+	* library/tzdata/Asia/Karachi: Updated rules for Pakistan Summer
+				       Time (Olson's tzdata2009f)
+
+2009-04-11  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclOOMethod.c (InvokeForwardMethod): Clarify the resolution
+	behaviour of the name of the command that is forwarded to: it's now
+	resolved using the object's namespace as context, which is much more
+	useful than the previous (somewhat random) behaviour of using the
+	caller's current namespace.
+
+2009-04-10  Pat Thoyts  <patthoyts@users.sourceforge.net>
+
+	* library/http/http.tcl:     Improved HTTP/1.1 support and added
+	* library/http/pkgIndex.tcl: specific HTTP/1.1 testing to ensure
+	* tests/http11.test:         we handle chunked+gzip for the various
+	* tests/httpd11.test:        modes (normal, -channel and -handler)
+	* makefiles:                 package version set to 2.8.0
+
+2009-04-10  Daniel Steffen  <das@users.sourceforge.net>
+
+	* unix/tclUnixChan.c:		TclUnixWaitForFile(): use FD_* macros
+	* macosx/tclMacOSXNotify.c:	to manipulate select masks (Cassoff).
+					[FRQ 1960647] [Bug 3486554]
+
+	* unix/tclLoadDyld.c:		Use RTLD_GLOBAL instead of RTLD_LOCAL.
+					[Bug 1961211]
+
+	* macosx/tclMacOSXNotify.c:	revise CoreFoundation notifier to allow
+					embedding into applications that
+					already have a CFRunLoop running and
+					want to run the tcl event loop via
+					Tcl_ServiceModeHook(TCL_SERVICE_ALL).
+
+	* macosx/tclMacOSXNotify.c:	add CFRunLoop based Tcl_Sleep() and
+	* unix/tclUnixChan.c:		TclUnixWaitForFile() implementations
+	* unix/tclUnixEvent.c:		and disable select() based ones in
+					CoreFoundation builds.
+
+	* unix/tclUnixNotify.c:		simplify, sync with tclMacOSXNotify.c.
+
+	* generic/tclInt.decls: 	add TclMacOSXNotifierAddRunLoopMode()
+	* generic/tclIntPlatDecls.h:	internal API, regen.
+	* generic/tclStubInit.c:
+
+	* unix/configure.in (Darwin):	use Darwin SUSv3 extensions if
+					available; remove /Network locations
+					from default tcl package search path
+					(NFS mounted locations and thus slow).
+	* unix/configure:		autoconf-2.59
+	* unix/tclConfig.h.in:		autoheader-2.59
+
+	* macosx/tclMacOSXBundle.c:	on Mac OS X 10.4 and later, replace
+					deprecated NSModule API by dlfcn API.
+
+2009-04-10  Donal K. Fellows  <dkf@users.sf.net>
+
+	* doc/StringObj.3: [Bug 2089279]: Corrected example so that it works
+	on 64-bit machines as well.
+
+2009-04-10  Pat Thoyts  <patthoyts@users.sourceforge.net>
+
+	* tests/http.test: [Bug 26245326]: Added specific check for problem
+	* tests/httpd: (return incomplete HTTP response header).
+
+2009-04-08  Kevin B. Kenny  <kennykb@acm.org>
+
+	* tools/tclZIC.tcl: Always emit files with Unix line termination.
+	* library/tzdata: Olson's tzdata2009e
+
+2009-04-09  Don Porter  <dgp@users.sourceforge.net>
+
+	* library/http/http.tcl:	[Bug 26245326]: Handle incomplete
+	lines in the "connecting" state. Thanks to Sergei Golovan.
+
+2009-04-08  Andreas Kupries  <andreask@activestate.com>
+
+	* library/platform/platform.tcl: Extended the darwin sections to add
+	* library/platform/pkgIndex.tcl: a kernel version number to the
+	* unix/Makefile.in: identifier for anything from Leopard (10.5) on up.
+	* win/Makefile.in: Extended patterns for same. Extended cpu
+	* doc/platform.n: recognition for 64bit Tcl running on a 32bit kernel
+	on a 64bit processor (By Daniel Steffen). Bumped version to 1.0.4.
+	Updated Makefiles.
+
+2009-04-08  Don Porter  <dgp@users.sourceforge.net>
+
+	* library/tcltest/tcltest.tcl:  [Bug 2570363]: Converted [eval]s (some
+	* library/tcltest/pkgIndex.tcl: unsafe!) to {*} in tcltest package.
+	* unix/Makefile.in:     => tcltest 2.3.1
+	* win/Makefile.in:
+
+2009-04-07  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclStringObj.c:	Correction so that value of
+	TCL_GROWTH_MIN_ALLOC is everywhere expressed in bytes as comment
+	claims.
+
+2009-04-04  Donal K. Fellows  <dkf@users.sf.net>
+
+	* doc/vwait.n: [Bug 1910136]: Extend description and examples to make
+	it clearer just how this command interprets variable names.
+
+2009-03-30  Don Porter  <dgp@users.sourceforge.net>
+
+	* doc/Alloc.3: [Bug 2556263]:	Size argument is "unsigned int".
+
+2009-03-27  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclPathObj.c (TclPathPart): [Bug 2710920]: TclPathPart()
+	* tests/fileName.test:	was computing the wrong results for both [file
+	dirname] and [file tail] on "path" arguments with the PATHFLAGS != 0
+	intrep and with an empty string for the "joined-on" part.
+
+2009-03-25  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* doc/tclsh.1:		 Bring doc and tools in line with
+	* tools/installData.tcl: http://wiki.tcl.tk/812
+	* tools/str2c
+	* tools/tcltk-man2html.tcl
+
+2009-03-25  Donal K. Fellows  <dkf@users.sf.net>
+
+	* doc/coroutine.n: [Bug 2152285]: Added basic documentation for the
+	coroutine and yield commands.
+
+2009-03-24  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclOOBasic.c (TclOOSelfObjCmd): [Bug 2704302]: Make 'self
+	class' better defined in the context of objects that change class.
+
+	* generic/tclVar.c (Tcl_UpvarObjCmd): [Bug 2673163] (ferrieux)
+	* generic/tclProc.c (TclObjGetFrame): Make the upvar command more able
+	to handle its officially documented syntax.
+
+2009-03-22  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclBasic.c: [Bug 2502037]: NR-enable the handling of unknown
+	commands.
+
+2009-03-21  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclBasic.c:   Fixed "leaks" in aliases, imports and
+	* generic/tclInt.h:     ensembles. Only remaining known leak is in
+	* generic/tclInterp.c:  ensemble unknown dispatch (as it not
+	* generic/tclNamesp.c:  NR-enabled)
+	* tests/tailcall.test:
+
+	* tclInt.h: comments
+
+	* tests/tailcall.test: Added tests to show that [tailcall] does not
+	currently always execute in constant space: interp-alias, ns-imports
+	and ensembles "leak" as of this commit.
+
+	* tests/nre.test: [foreach] has been NR-enabled for a while, the test
+	was marked 'knownBug': unmark it.
+
+	* generic/tclBasic.c:   Fix for (among others) [Bug 2699087]
+	* generic/tclCmdAH.c:   Tailcalls now perform properly even from
+	* generic/tclExecute.c: within [eval]ed scripts.
+	* generic/tclInt.h:     More tests missing, as well as proper
+	exploration and testing of the interaction with "redirectors" like
+	interp-alias (suspect that it does not happen in constant space)
+	and pure-eval commands.
+
+	* generic/tclExecute.c: Proper fix for [Bug 2415422]. Reenabled
+	* tests/nre.test:       the failing assertion that was disabled on
+	2008-12-18: the assertion is correct, the fault was in the
+	management of expansions.
+
+	* generic/tclExecute.c:  Fix both test and code for tailcall
+	* tests/tailcall.test:   from within a compiled [eval] body.
+
+	* tests/tailcall.test: Slightly improved tests
+
+2009-03-20  Don Porter  <dgp@users.sourceforge.net>
+
+	* tests/stringObj.test:         [Bug 2597185]: Test stringObj-6.9
+	checks that Tcl_AppendStringsToObj() no longer crashes when operating
+	on a pure unicode value.
+
+	* generic/tclExecute.c (INST_CONCAT1):  [Bug 2669109]: Panic when
+	appends overflow the max length of a Tcl value.
+
+2009-03-19  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tcl.h:
+	* generic/tclInt.h:
+	* generic/tclBasic.c:
+	* generic/tclExecute.c:
+	* generic/tclNamesp.c (Tcl_PopCallFrame): Rewritten tailcall
+	implementation, ::unsupported::atProcExit is (temporarily?) gone. The
+	new approach is much simpler, and also closer to being correct. This
+	commit fixes [Bug 2649975] and [Bug 2695587].
+
+	* tests/coroutine.test:    Moved the tests to their own files,
+	* tests/tailcall.test:     removed the unsupported.test. Added
+	* tests/unsupported.test:  tests for the fixed bugs.
+
+2009-03-19  Donal K. Fellows  <dkf@users.sf.net>
+
+	* doc/tailcall.n: Added documentation for tailcall command.
+
+2009-03-18  Don Porter  <dgp@users.sourceforge.net>
+
+	* win/tclWinFile.c (TclpObjNormalizePath):	[Bug 2688184]:
+	Corrected Tcl_Obj leak. Thanks to Joe Mistachkin for detection and
+	patch.
+
+	* generic/tclVar.c (TclLookupSimpleVar):	[Bug 2689307]: Shift
+	all calls to Tcl_SetErrorCode() out of TclLookupSimpleVar and onto its
+	callers, where control with TCL_LEAVE_ERR_MSG flag is more easily
+	handled.
+
+2009-03-16  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclCmdMZ.c (TryPostBody): [Bug 2688063]: Extract information
+	from list before getting rid of last reference to it.
+
+2009-03-15  Joe Mistachkin  <joe@mistachkin.com>
+
+	* generic/tclThread.c: [Bug 2687952]: Modify fix for TSD leak to match
+	* generic/tclThreadStorage.c: Tcl 8.5 (and prior) allocation semantics
+
+2009-03-15  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclThreadStorage.c (TSDTableDelete):	[Bug 2687952]: Ensure
+	* generic/tclThread.c (Tcl_GetThreadData):	that structures in
+	Tcl's TSD system are all freed. Use the correct matching allocator.
+
+	* generic/tclPosixStr.c (Tcl_SignalId,Tcl_SignalMsg): [Patch 1513655]:
+	Added support for SIGINFO, which is present on BSD platforms.
+
+2009-03-14  Donal K. Fellows  <dkf@users.sf.net>
+
+	* unix/tcl.pc.in (new file):		[Patch 2243948] (hat0)
+	* unix/configure.in, unix/Makefile.in: Added support for reporting
+	Tcl's public build configuration via the pkg-config system. TEA is
+	still the official mechanism though, in part because pkg-config is not
+	universally supported across all Tcl's supported platforms.
+
+2009-03-11  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclBasic.c (TclNRCoroutineObjCmd): fix Tcl_Obj leak.
+	Diagnosis and fix thanks to GPS.
+
+2009-03-09  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclCmdMZ.c (Tcl_TryObjCmd, TclNRTryObjCmd): Moved the
+	implementation of [try] from Tcl code into C. Still lacks a bytecode
+	version, but should be better than what was before.
+
+2009-03-04  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclZlib.c (TclZlibCmd): Checksums are defined to be unsigned
+	32-bit integers, use Tcl_WideInt to pass to scripts. [Bug 2662434]
+	(ZlibStreamCmd, ChanGetOption): A few other related corrections.
+
+2009-02-27  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tcl.decls:    [Bug 218977]: Tcl_DbCkfree needs return value
+	* generic/tclCkalloc.c
+	* generic/tclDecls.h:   (regenerated)
+	* generic/tclInt.decls: don't use CONST84/CONST86 here
+	* generic/tclCompile.h: don't use CONST86 here, comment fixing.
+	* generic/tclIO.h:      don't use CONST86 here, comment fixing.
+	* generic/tclIntDecls.h (regenerated)
+
+2009-02-25  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclUtil.c (TclStringMatchObj):	[Bug 2637173]: Revised
+	the branching on the strObj->typePtr so that untyped values get
+	converted to the "string" type and pass through the Unicode matcher.
+	[Bug 2613766]: Also added checks to only perform "bytearray"
+	optimization on pure bytearray values.
+
+	* generic/tclCmdMZ.c:	Since Tcl_GetCharLength() has its own
+	* generic/tclExecute.c:	optimizations for the tclByteArrayType, stop
+	having the callers do them.
+
+2009-02-24  Donal K. Fellows  <dkf@users.sf.net>
+
+	* doc/clock.n, doc/fblocked.n, doc/format.n, doc/lsort.n,
+	* doc/pkgMkIndex.n, doc/regsub.n, doc/scan.n, doc/tclvars.n:
+	General minor documentation improvements.
+
+	* library/http/http.tcl (geturl, Eof): Added support for 8.6's built
+	in zlib routines.
+
+2009-02-22  Alexandre Ferrieux  <ferrieux@users.sourceforge.net>
+
+	* tests/lrange.test:	Revert commits of 2008-07-23. Those were speed
+	* tests/binary.test:	tests, that are inherently brittle.
+
+2009-02-21  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclStringObj.c:	Several revisions to the shimmering
+	patterns between Unicode and UTF string reps.  Most notably the
+	call: objPtr = Tcl_NewUnicodeObj(...,0); followed by a loop of calls:
+	Tcl_AppendUnicodeToObj(objPtr, u, n); will now grow and append to
+	the Unicode representation.  Before this commit, the sequence would
+	convert each append to UTF and perform the append to the UTF rep.
+	This is puzzling and likely a bug.  The performance of [string map]
+	is significantly improved by this change (according to the MAP
+	collection of benchmarks in tclbench).  Just in case there was some
+	wisdom in the old ways that I missed, I left in the ability to restore
+	the old patterns with a #define COMPAT 1 at the top of the file.
+
+2009-02-20  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclPathObj.c:	[Bug 2571597]: Fixed mistaken logic in
+	* tests/fileName.test:	TclFSGetPathType() that assumed (not
+	"absolute") => "relative". This is a false assumption on Windows,
+	where "volumerelative" is another possibility.
+
+2009-02-18  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclStringObj.c:	Simplify the logic of the
+	Tcl_*SetObjLength() routines.
+
+	* generic/tclStringObj.c:	Rewrite GrowStringBuffer() so that it
+	has parallel structure with GrowUnicodeBuffer().  The revision permits
+	allocation attempts to continue all the way up to failure, with no
+	gap. It also directly manipulates the String and Tcl_Obj internals
+	instead of inefficiently operating via Tcl_*SetObjLength() with all of
+	its extra protections and underdocumented special cases.
+
+	* generic/tclStringObj.c:	Another round of simplification on
+	the allocation macros.
+
+2009-02-17  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* win/tcl.m4, win/configure: Check if cl groks _WIN64 already to
+	avoid CC manipulation that can screw up later configure checks.
+	Use 'd'ebug runtime in 64-bit builds.
+
+2009-02-17  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclStringObj.c:	Pare back the length of the unicode
+	array in a non-extended String struct to one Tcl_UniChar, meant to
+	hold the terminating NUL character.  Non-empty unicode strings are
+	then stored by extending the String struct by stringPtr->maxChars
+	additional slots in that array with sizeof(Tcl_UniChar) bytes per
+	slot. This revision makes the allocation macros much simpler.
+
+	* generic/tclStringObj.c:	Factor out common GrowUnicodeBuffer()
+	and solve overflow and growth algorithm fallbacks in it.
+
+	* generic/tclStringObj.c:	Factor out common GrowStringBuffer().
+
+	* generic/tclStringObj.c:	Convert Tcl_AppendStringsToObj into
+	* tests/stringObj.test:		a radically simpler implementation
+	where we just loop over calls to Tcl_AppendToObj.  This fixes [Bug
+	2597185].  It also creates a *** POTENTIAL INCOMPATIBILITY *** in
+	that T_ASTO can now allocate more space than is strictly required,
+	like all the other Tcl_Append* routines.  The incompatibility was
+	detected by test stringObj-6.5, which I've updated to reflect the
+	new behavior.
+
+	* generic/tclStringObj.c:	Revise buffer growth implementation
+	in ExtendStringRepWithUnicode.  Use cheap checks to determine that
+	no reallocation is necessary without cost of computing the precise
+	number of bytes needed.  Also make use of the string growth algortihm
+	in the case of repeated appends.
+
+2009-02-16  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tclZlib.c:	Hack needed for official zlib1.dll build.
+	* win/configure.in:	fix [Feature Request 2605263] use official
+	* win/Makefile.in:	zlib build.
+	* win/configure:	(regenerated)
+	* compat/zlib/zdll.lib:	new files
+	* compat/zlib/zlib1.dll:
+
+	* win/Makefile.in:  [Bug 2605232]: tdbc doesn't build when Tcl is
+	compiled with --disable-shared.
+
+2009-02-15  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclStringObj.c:	[Bug 2603158]: Added protections from
+	* generic/tclTestObj.c:		invalid memory accesses when we append
+	* tests/stringObj.test:		(some part of) a Tcl_Obj to itself.
+	Added the appendself and appendself2 subcommands to the
+	[teststringobj] testing command and added tests to the test suite.
+
+	* generic/tclStringObj.c:	Factor out duplicate code from
+	Tcl_AppendObjToObj.
+
+	* generic/tclStringObj.c:	Replace the 'size_t uallocated' field
+	of the String struct, storing the number of bytes allocated to store
+	the Tcl_UniChar array, with an 'int maxChars' field, storing the
+	number of Tcl_UniChars that may be stored in the allocated space.
+	This reduces memory requirement a small bit, and makes some range
+	checks simpler to code.
+	* generic/tclTestObj.c:	Replace the [teststringobj ualloc] testing
+	* tests/stringObj.test:	command with [teststringobj maxchars] and
+	update the tests.
+
+	* generic/tclStringObj.c:	Removed limitation in
+	Tcl_AppendObjToObj where the char length of the result was only
+	computed if the appended string was all single byte characters.
+	This limitation was in place to dodge a bug in Tcl_GetUniChar.
+	With that bug gone, we can take advantage of always recording the
+	length of append results when we know it.
+
+2009-02-14  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclStringObj.c:	Revisions so that we avoid creating
+	the strange representation of an empty string with
+	objPtr->bytes == NULL and stringPtr->hasUnicode == 0.  Instead in
+	the situations where that was being created, create a traditional
+	two-legged stork representation (objPtr->bytes = tclEmptyStringRep
+	and stringPtr->hasUnicode = 1).  In the situations where the strange
+	rep was treated differently, continue to do so by testing
+	stringPtr->numChars == 0 to detect it.  These changes make the code
+	more conventional so easier for new maintainers to pick up.  Also
+	sets up further simplifications.
+
+	* generic/tclTestObj.c:	Revise updates to [teststringobj] so we don't
+	get blocked by MODULE_SCOPE limits.
+
+2009-02-12  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclStringObj.c:	Rewrites of the routines
+	Tcl_GetCharLength, Tcl_GetUniChar, Tcl_GetUnicodeFromObj,
+	Tcl_GetRange, and TclStringObjReverse to use the new macro, and
+	to more simply and clearly split the cases depending on whether
+	a valid unicode rep is present or needs to be created.
+	New utility routine UnicodeLength(), to compute the length of unicode
+	buffer arguments when no length is passed in, with built-in
+	overflow protection included.  Update three callers to use it.
+
+	* generic/tclInt.h:	New macro TclNumUtfChars meant to be a faster
+	replacement for a full Tcl_NumUtfChars() call when the string has all
+	single-byte characters.
+
+	* generic/tclStringObj.c:	Simplified Tcl_GetCharLength by
+	* generic/tclTestObj.c:		removing code that did nothing.
+	Added early returns from Tcl_*SetObjLength when the desired length
+	is already present; adapted test command to the change.
+
+	* generic/tclStringObj.c:	Re-implemented AppendUtfToUnicodeRep
+	so that we no longer pass through Tcl_DStrings which have their own
+	sets of problems when lengths overflow the int range.  Now AUTUR and
+	FillUnicodeRep share a common core routine.
+
+2009-02-12  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclOODefineCmds.c (TclOOGetDefineCmdContext): Use the
+	correct field in the Interp structure for retrieving the frame to get
+	the context object so that people can extend [oo::define] without deep
+	shenanigans. Bug found by Federico Ferri.
+
+2009-02-11  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclStringObj.c:	Re-implemented AppendUnicodeToUtfRep
+	so that we no longer pass through Tcl_DStrings which have their own
+	sets of problems when lengths overflow the int range.  Now AUTUR and
+	UpdateStringOfString share a common core routine.
+
+	* generic/tclStringObj.c:	Changed type of the 'allocated' field
+	* generic/tclTestObj.c:		of the String struct (and the
+	TestString counterpart) from size_t to int since only int values are
+	ever stored in it.
+
+2009-02-10  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tclEncoding.c: Eliminate some unnessary type casts
+	* generic/tclEvent.c:    some internal const decorations
+	* generic/tclExecute.c:  spacing
+	* generic/tclIndexObj.c:
+	* generic/tclInterp.c:
+	* generic/tclIO.c:
+	* generic/tclIOCmd.c:
+	* generic/tclIORChan.c:
+	* generic/tclIOUtil.c:
+	* generic/tclListObj.c:
+	* generic/tclLiteral.c:
+	* generic/tclNamesp.c:
+	* generic/tclObj.c:
+	* generic/tclOOBasic.c:
+	* generic/tclPathObj.c:
+	* generic/tclPkg.c:
+	* generic/tclProc.c:
+	* generic/tclRegexp.c:
+	* generic/tclScan.c:
+	* generic/tclStringObj.c:
+	* generic/tclTest.c:
+	* generic/tclTestProcBodyObj.c:
+	* generic/tclThread.c:
+	* generic/tclThreadTest.c:
+	* generic/tclTimer.c:
+	* generic/tclTrace.c:
+	* generic/tclUtil.c:
+	* generic/tclVar.c:
+	* generic/tclStubInit.c: (regenerated)
+
+2009-02-10  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* unix/tcl.m4: [Bug 2502365]: Building of head on HPUX is broken when
+	using the native CC.
+	* unix/configure: (autoconf-2.59)
+
+2009-02-10  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclObj.c (Tcl_GetString):	Added comments and validity
+	checks following the call to an UpdateStringProc.
+
+	* generic/tclStringObj.c: Reduce code duplication in Tcl_GetUnicode*.
+	Restrict AppendUtfToUtfRep to non-negative length appends.
+	Convert all Tcl_InvalidateStringRep() calls into macros.
+	Simplify Tcl_AttemptSetObjLength by removing unreachable code.
+	Simplify SetStringFromAny() by removing unreachable and duplicate code.
+	Simplify Tcl_SetObjLength by removing unreachable code.
+	Removed handling of (objPtr->bytes != NULL) from UpdateStringOfString,
+	which is only called when objPtr->bytes is NULL.
+
+2009-02-09  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tclCompile.c: [Bug 2555129]: const compiler warning (as
+	error) in tclCompile.c
+
+2009-02-07  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclZlib.c (TclZlibCmd): [Bug 2573172]: Ensure that when
+	invalid subcommand name is given, the list of valid subcommands is
+	produced. This gives a better experience when using the command
+	interactively.
+
+2009-02-05  Joe Mistachkin  <joe@mistachkin.com>
+
+	* generic/tclInterp.c: [Bug 2544618]: Fix argument checking for
+	[interp cancel].
+	* unix/Makefile.in: Fix build issue with zlib on FreeBSD (and possibly
+	other platforms).
+
+2009-02-05  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclCmdMZ.c (StringIndexCmd, StringRangeCmd, StringLenCmd):
+	Simplify the implementation of some commands now that the underlying
+	string API knows more about bytearrays.
+
+	* generic/tclExecute.c (TclExecuteByteCode): [Bug 2568434]: Make sure
+	that INST_CONCAT1 will not lose string reps wrongly.
+
+	* generic/tclStringObj.c (Tcl_AppendObjToObj): Special-case the
+	appending of one bytearray to another, which can be extremely rapid.
+	Part of scheme to address [Bug 1665628] by making the basic string
+	operations more efficient on byte arrays.
+	(Tcl_GetCharLength, Tcl_GetUniChar, Tcl_GetRange): More special casing
+	work for bytearrays.
+
+2009-02-04  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclStringObj.c: [Bug 2561794]: Added overflow protections to
+	the AppendUtfToUtfRep routine to either avoid invalid arguments and
+	crashes, or to replace them with controlled panics.
+
+	* generic/tclCmdMZ.c:	[Bug 2561746]: Prevent crashes due to int
+	overflow of the length of the result of [string repeat].
+
+2009-02-03  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* macosx/tclMacOSXFCmd.c: Eliminate some unnessary type casts
+	* unix/tclLoadDyld.c:	  some internal const decorations
+	* unix/tclUnixCompat.c:	  spacing
+	* unix/tclUnixFCmd.c
+	* unix/tclUnixFile.c
+	* win/tclWinDde.c
+	* win/tclWinFCmd.c
+	* win/tclWinInit.c
+	* win/tclWinLoad.c
+	* win/tclWinPipe.c
+	* win/tclWinReg.c
+	* win/tclWinTest.c
+	* generic/tclBasic.c
+	* generic/tclBinary.c
+	* generic/tclCmdAH.c
+	* generic/tclCmdIL.c
+	* generic/tclCmdMZ.c
+	* generic/tclCompCmds.c
+	* generic/tclDictObj.c
+
+2009-02-03  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclObj.c (tclCmdNameType): [Bug 2558422]: Corrected the type
+	of this structure so that extensions that write it (yuk!) will still
+	be able to function correctly.
+
+2009-02-03  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclStringObj.c (SetUnicodeObj):	[Bug 2561488]:
+	Corrected failure of Tcl_SetUnicodeObj() to panic on a shared object.
+	Also factored out common code to reduce duplication.
+
+	* generic/tclObj.c (Tcl_GetStringFromObj): Reduce code duplication.
+
+2009-02-02  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclInterp.c:	Reverted the conversion of [interp] into an
+	* tests/interp.test:	ensemble.  Such conversion is not necessary
+	* tests/nre.test:	(or even all that helpful) in the NRE-enabling
+	of [interp invokehidden], and it has other implications -- including
+	significant forkage of the 8.5 and 8.6 implementations -- that are
+	better off avoided if there's no gain.
+
+	* generic/tclStringObj.c (STRING_NOMEM):  [Bug 2494093]: Add missing
+	cast of NULL to (char *) that upsets some compilers.
+
+	* generic/tclStringObj.c (Tcl_(Attempt)SetObjLength):	[Bug 2553906]:
+	Added protections against callers asking for negative lengths.  It is
+	likely when this happens that an integer overflow is to blame.
+
+2009-02-01  David Gravereaux  <davygrvy@pobox.com>
+
+	* win/makefile.vc: Allow nmake flags such as -a (rebuild all) to pass
+	down to the pkgs targets, too.
+
+2009-01-30  Donal K. Fellows  <dkf@users.sf.net>
+
+	* doc/chan.n: [Bug 1216074]: Added another extended example.
+
+	* doc/refchan.n: Added an example of how to build a scripted channel.
+
+2009-01-29  Donal K. Fellows  <dkf@users.sf.net>
+
+	* tests/stringObj.test: [Bug 2006888]: Remove non-ASCII chars from
+	non-comment locations in the file, making it work more reliably in
+	locales with a non-Latin-1 default encoding.
+
+	* generic/tclNamesp.c (Tcl_FindCommand): [Bug 2519474]: Ensure that
+	the path is not searched when the TCL_NAMESPACE_ONLY flag is given.
+
+	* generic/tclOODecls.h (Tcl_OOInitStubs): [Bug 2537839]: Make the
+	declaration of this macro work correctly in the non-stub case.
+
+2009-01-29  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclInterp.c:	Convert the [interp] command into a
+	* tests/interp.test:	[namespace ensemble].  Work in progress
+	* tests/nre.test:	to NRE-enable the [interp invokehidden]
+	subcommand.
+
+2009-01-29  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclNamesp.c (TclMakeEnsemble): [Bug 2529117]: Make this
+	function behave more sensibly when presented with a fully-qualified
+	name, rather than doing strange stuff.
+
+2009-01-28  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclBasic.c (TclInvokeObjectCommand): Made this understand
+	what to do if it ends up being used on a command with no objProc; that
+	shouldn't happen, but...
+
+	* generic/tclNamesp.c (TclMakeEnsemble): [Bug 2529157]: Made this
+	understand NRE command implementations better.
+	* generic/tclDictObj.c (DictForCmd): Eliminate unnecessary command
+	implementation.
+
+2009-01-27  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclOODefineCmds.c (Tcl_ClassSetConstructor):
+	[Bug 2531577]: Ensure that caches of constructor chains are cleared
+	when the constructor is changed.
+
+2009-01-26  Alexandre Ferrieux  <ferrieux@users.sourceforge.net>
+
+	* generic/tclInt.h:   [Bug 1028264]: WSACleanup() too early.
+	* generic/tclEvent.c: The fix introduces "late exit handlers" for
+	* win/tclWinSock.c:   similar late process-wide cleanups.
+
+2009-01-26  Alexandre Ferrieux  <ferrieux@users.sourceforge.net>
+
+	* win/tclWinSock.c: [Bug 2446662]: Resync Win behavior on RST with
+	that of unix (EOF).
+
+2009-01-26  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclZlib.c (ChanClose): [Bug 2536400]: Only generate error
+	messages in the interpreter when the thread is not being closed down.
+
+2009-01-23  Donal K. Fellows  <dkf@users.sf.net>
+
+	* doc/zlib.n: Added a note that 'zlib push' is reversed by 'chan pop'.
+
+2009-01-22  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tclCompile.h:	CONSTify TclPrintInstruction (TIP #27)
+	* generic/tclCompile.c
+	* generic/tclInt.h:	CONSTify TclpNativeJoinPath (TIP #27)
+	* generic/tclFileName.c
+	* generic/tcl.decls:	{unix win} is equivalent to {generic}
+	* generic/tclInt.decls
+	* generic/tclDecls.h:	(regenerated)
+	* generic/tclIntDecls.h
+	* generic/tclGetDate.y:	Single internal const decoration.
+	* generic/tclDate.c:
+
+2009-01-22  Kevin B. Kenny  <kennykb@acm.org>
+
+	* unix/tcl.m4: Corrected a typo ($(SHLIB_VERSION) should be
+	${SHLIB_VERSION}).
+	* unix/configure: Autoconf 2.59
+
+2009-01-21  Andreas Kupries  <andreask@activestate.com>
+
+	* generic/tclIORChan.c (ReflectClose): [Bug 2458202]:
+	* generic/tclIORTrans.c (ReflectClose): Closing a channel may supply
+	NULL for the 'interp'. Test for finalization needs to be different,
+	and one place has to pull the interp out of the channel instead.
+
+2009-01-21  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclStringObj.c: New fix for [Bug 2494093] replaces the
+	flawed attempt committed 2009-01-09.
+
+2009-01-19  Kevin B. Kenny  <kennykb@acm.org>
+
+	* unix/Makefile.in: [Patch 907924]:Added a CONFIG_INSTALL_DIR
+	* unix/tcl.m4:      parameter so that distributors can control where
+	tclConfig.sh goes. Made the installation of 'ldAix' conditional upon
+	actually being on an AIX system. Allowed for downstream packagers to
+	customize SHLIB_VERSION on BSD-derived systems. Thanks to Stuart
+	Cassoff for his help.
+	* unix/configure: Autoconf 2.59
+
+2009-01-19  David Gravereaux  <davygrvy@pobox.com>
+
+	* win/build.vc.bat: Improved tools detection and error message
+	* win/makefile.vc: Reorganized the $(TCLOBJ) file list into seperate
+	parts for easier maintenance. Matched all sources built using -GL to
+	both $(lib) and $(link) to use -LTCG and avoid a warning message.
+	Addressed the over-building nature of the htmlhelp target by moving
+	from a pseudo target to a real target dependent on the entire docs/
+	directory contents.
+	* win/nmakehlp.c: Removed -g option and GrepForDefine() func as it
+	isn't being used anymore. The -V option method is much better.
+
+2009-01-16  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tcl.h:	Bump patchlevel to 8.6b1.1 to distinguish
+	* library/init.tcl:	CVS snapshots from the 8.6b1 and 8.6b2 releases
+	* unix/configure.in:	and to deal with the fact that the 8.6b1
+	* win/configure.in:	version of init.tcl will not [source] in the
+	HEAD version of Tcl.
+
+	* unix/configure:	autoconf-2.59
+	* win/configure:
+
+2009-01-14  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclBasic.c (Tcl_DeleteCommandFromToken):	Reverted most
+	of the substance of my 2009-01-12 commit. NULLing the objProc field of
+	a Command when deleting it is important so that tests for certain
+	classes of commands don't return false positives when applied to
+	deleted command tokens. Overall change is now just replacement of a
+	false comment with a true one.
+
+2009-01-13  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* unix/tcl.m4: [Bug 2502365]: Building of head on HPUX is broken when
+	using the native CC.
+	* unix/configure (autoconf-2.59)
+
+2009-01-13  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclCmdMZ.c (Tcl_ThrowObjCmd):	Move implementation of [throw]
+	* library/init.tcl (throw):		to C from Tcl.
+
+2009-01-12  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclBasic.c (Tcl_DeleteCommandFromToken): One consequence of
+	the NRE rewrite is that there are now situations where a NULL objProc
+	field in a Command struct is perfectly normal. Removed an outdated
+	comment in Tcl_DeleteCommandFromToken that claimed we use
+	cmdPtr->objPtr==NULL as a test of command validity. In fact we use
+	cmdPtr->flags&CMD_IS_DELETED to perform that test. Also removed the
+	setting to NULL, since any extension following the advice of the old
+	comment is going to be broken by NRE anyway, and needs to shift to
+	flag-based testing (or stop intruding into such internal matters).
+	Part of [Bug 2486550].
+
+2009-01-09  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclStringObj.c (STRING_SIZE): [Bug 2494093]: Corrected
+	failure to limit memory allocation requests to the sizes that can be
+	supported by Tcl's memory allocation routines.
+
+2009-01-09  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclNamesp.c (NamespaceEnsembleCmd): [Bug 1558654]: Error out
+	when someone gives wrong # of args to [namespace ensemble create].
+
+2009-01-08  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclStringObj.c (STRING_UALLOC): [Bug 2494093]: Added missing
+	parens required to get correct results out of things like
+	STRING_UALLOC(num + append).
+
+2009-01-08  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclDictObj.c, generic/tclIndexObj.c, generic/tclListObj.c,
+	* generic/tclObj.c, generic/tclStrToD.c, generic/tclUtil.c,
+	* generic/tclVar.c: Generate errorcodes for the error cases which
+	approximate to "I can't interpret that string as one of those" and
+	"You gave me the wrong number of arguments".
+
+2009-01-07  Donal K. Fellows  <dkf@users.sf.net>
+
+	* doc/dict.n: [Tk Bug 2491235]: Added more examples.
+
+	* tests/oo.test (oo-22.1): Adjusted test to be less dependent on the
+	specifics of how [info frame] reports general frame information, and
+	instead to focus on what methods add to it; that's really what the
+	test is about anyway.
+
+2009-01-06  Don Porter  <dgp@users.sourceforge.net>
+
+	* tests/stringObj.test:	Revise tests that demand a NULL Tcl_ObjType
+	in certain values to construct those values with [testdstring] so
+	there's no lack of robustness depending on the shimmer history of
+	shared literals.
+
+2009-01-06  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclDictObj.c (DictIncrCmd): Corrected twiddling in internals
+	of dictionaries so that literals can't get destroyed.
+
+	* tests/expr.test: [Bug 2006879]: Eliminate non-ASCII char.
+
+	* generic/tclOOInfo.c (InfoObjectMethodsCmd,InfoClassMethodsCmd):
+	[Bug 2489836]: Only delete pointers that were actually allocated!
+
+	* generic/tclOO.c (TclNRNewObjectInstance, Tcl_NewObjectInstance):
+	[Bug 2481109]: Perform search for existing commands in right context.
+
+2009-01-05  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclCmdMZ.c (TclNRSourceObjCmd): [Bug 2412068]: Make
+	* generic/tclIOUtil.c (TclNREvalFile):    implementation of the
+	[source] command be NRE enabled so that [yield] inside a script
+	sourced in a coroutine can work.
+
+2009-01-04  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclCmdAH.c: Tidy up spacing and code style.
+
+2009-01-03  Kevin B. Kenny  <kennykb@acm.org>
+
+	* library/clock.tcl (tcl::clock::add): Fixed error message formatting
+	in the case where [clock add] is presented with a bad switch.
+	* tests/clock.test (clock-65.1) Added a test case for the above
+	problem [Bug 2481670].
+
+2009-01-02  Donal K. Fellows  <dkf@users.sf.net>
+
+	* unix/tcl.m4 (SC_CONFIG_CFLAGS): [Bug 878333]: Force the use of the
+	compatibility version of mkstemp() on IRIX.
+	* unix/configure.in, unix/Makefile.in (mkstemp.o):
+	* compat/mkstemp.c (new file): [Bug 741967]: Added a compatibility
+	implementation of the mkstemp() function, which is apparently needed
+	on some platforms.
+
+	******************************************************************
+	*** CHANGELOG ENTRIES FOR 2008 IN "ChangeLog.2008"             ***
+	*** CHANGELOG ENTRIES FOR 2006-2007 IN "ChangeLog.2007"        ***
+	*** CHANGELOG ENTRIES FOR 2005 IN "ChangeLog.2005"             ***
+	*** CHANGELOG ENTRIES FOR 2004 IN "ChangeLog.2004"             ***
+	*** CHANGELOG ENTRIES FOR 2003 IN "ChangeLog.2003"             ***
+	*** CHANGELOG ENTRIES FOR 2002 IN "ChangeLog.2002"             ***
+	*** CHANGELOG ENTRIES FOR 2001 IN "ChangeLog.2001"             ***
+	*** CHANGELOG ENTRIES FOR 2000 IN "ChangeLog.2000"             ***
+	*** CHANGELOG ENTRIES FOR 1999 AND EARLIER IN "ChangeLog.1999" ***
+	******************************************************************
diff --git a/ChangeLog.1999 b/ChangeLog.1999
new file mode 100644
index 0000000..3bf4e9a
--- /dev/null
+++ b/ChangeLog.1999
@@ -0,0 +1,2634 @@
+1999-12-22  Jeff Hobbs  <hobbs@scriptics.com>
+
+	* changes: updated changes file
+	* tools/tclSplash.bmp: updated to show 8.3
+
+1999-12-21  Jeff Hobbs  <hobbs@scriptics.com>
+
+	* README:
+	* generic/tcl.h:
+	* mac/README:
+	* unix/configure.in:
+	* tools/tcl.wse.in:
+	* win/README.binary:
+	* win/configure.in: updated to patch level 8.3b1
+
+	* unix/Makefile.in: added -srcdir=... for 'make html'
+
+	* doc/Hash.3: fixed reference to ckfree [Bug 3912]
+	* doc/RegExp.3: fixed calling params for Tcl_RegExecFromObj
+	* doc/open.n: fixed minor formatting errors
+	* doc/string.n: fixed minor formatting errors
+
+	* doc/lsort.n: added -unique docs
+	* tests/cmdIL.test:
+	* generic/tclCmdIL.c: added -unique option to lsort
+
+	* generic/tclThreadTest.c: changed thread ids to longs [Bug 3902]
+
+	* mac/tclMacOSA.c: fixed applescript for I18N [Bug 3644]
+
+	* win/mkd.bat:
+	* win/rmd.bat: removed necessity of tag.txt [Bug 3874]
+
+	* win/tclWinThrd.c: changed CreateThread to _beginthreadex and
+	ExitThread to _endthreadex
+
+1999-12-12  Jeff Hobbs  <hobbs@scriptics.com>
+
+	* doc/glob.n:
+	* tests/fileName.test:
+	* generic/tclInt.decls:
+	* generic/tclInt.h:
+	* generic/tclIntDecls.h:
+	* generic/tclStubInit.c:
+	* generic/tclEncoding.c:
+	* generic/tclFileName.c:
+	* mac/tclMacFile.c:
+	* unix/tclUnixFile.c:
+	* win/tclWinFile.c: enhanced the glob command with the new options
+	-types -path -directory and -join. Deprecated TclpMatchFiles with
+	TclpMatchFilesTypes, extended TclGlob and TclDoGlob and added
+	GlobTypeData structure. [Bug 2363]
+
+1999-12-10  Jeff Hobbs  <hobbs@scriptics.com>
+
+	* tests/var.test:
+	* generic/tclCompile.c: fixed problem where setting to {} array would
+	intermittently not work. [Bug 3339] (Fontaine)
+
+	* generic/tclCmdMZ.c:
+	* generic/tclExecute.c: optimized INST_TRY_CVT_TO_NUMERIC to recognize
+	boolean objects. [Bug 2815] (Spjuth)
+
+	* tests/info.test:
+	* tests/parseOld.test:
+	* generic/tclCmdAH.c:
+	* generic/tclProc.c: changed Tcl_UplevelObjCmd (uplevel) and
+	Tcl_EvalObjCmd (eval) to use TCL_EVAL_DIRECT in the single arg case as
+	well, to take advantage of potential pure list input optimization.
+	This means that it won't get byte compiled though, which should be
+	acceptable.
+	* generic/tclBasic.c: made Tcl_EvalObjEx pure list object aware in the
+	TCL_EVAL_DIRECT case for efficiency.
+	* generic/tclUtil.c: made Tcl_ConcatObj pure list object aware, and
+	return a list object in that case [Bug 2098 2257]
+
+	* generic/tclMain.c: changed Tcl_Main to not constantly reuse the
+	commandPtr object (interactive case) as it could be shared. (Fellows)
+
+	* unix/configure.in:
+	* unix/tcl.m4:
+	* unix/tclUnixPipe.c: removed checking for compatible vfork function
+	and use of the vfork function. Modern VM systems rarely suffer any
+	performance degradation when fork is used, and it solves multiple
+	problems with vfork. Users that still want vfork can add -Dfork=vfork
+	to the compile flags. [Bug 942 2228 1312]
+
+1999-12-09  Jeff Hobbs  <hobbs@scriptics.com>
+
+	* win/aclocal.m4: made it just include tcl.m4
+
+	* doc/exec.n:
+	* doc/open.n:
+	* win/tclWin32Dll.c:
+	* win/tclWinChan.c:
+	* win/tclWinFCmd.c:
+	* win/tclWinInit.c:
+	* win/tclWinPipe.c:
+	* win/tclWinSock.c: removed all code that supported Win32s. It was no
+	longer officially supported, and likely didn't work anyway.
+	* win/makefile.vc: removed 16 bit stuff, cleaned up.
+
+	* win/tcl16.rc:
+	* win/tclWin16.c:
+	* win/winDumpExts.c: these files have been removed from the source
+	tree (no longer necessary to build)
+
+1999-12-07  Jeff Hobbs  <hobbs@scriptics.com>
+
+	* tests/io.test: removed 'knownBug' tests that were for unsupported0,
+	which is now fcopy (that already has tests)
+
+	* mac/tclMacPort.h: added utime.h include
+
+	* generic/tclDate.c:
+	* unix/Makefile.in: fixed make gendate to swap const with CONST so it
+	uses the Tcl defined CONST type [Bug 3521]
+
+	* generic/tclIO.c: removed panic that could occur in FlushChannel when
+	a "blocking" channel would receive EAGAIN, instead treating it the
+	same as non-blocking. [Bug 3773]
+
+	* generic/tclUtil.c: fixed Tcl_ScanCountedElement to not step beyond
+	the end of the counted string. [Bug 3336]
+
+1999-12-03  Jeff Hobbs  <hobbs@scriptics.com>
+
+	* doc/load.n: added note about NT's buggy handling of './' with
+	LoadLibrary
+
+	* library/http2.1/http.tcl: fixed error handling in http::Event. [Bug
+	3752]
+
+	* tests/env.test: removed knownBug limitation from working test
+	* tests/all.tcl: ensured that ::tcltest::testsDirectory would be set
+	to an absolute path
+
+	* tests/expr-old.test:
+	* tests/parseExpr.test:
+	* tests/string.test:
+	* generic/tclGet.c:
+	* generic/tclInt.h:
+	* generic/tclObj.c:
+	* generic/tclParseExpr.c:
+	* generic/tclUtil.c:
+	* generic/tclExecute.c: added TclCheckBadOctal routine to enhance
+	error message checking for when users use invalid octal numbers (like
+	08), as well as replumbed the Expr*Funcs with a new VerifyExprObjType
+	to simplify type handling. [Bug 2467]
+
+	* tests/expr.test:
+	* generic/tclCompile.c: fixed 'bad code length' error for 'expr +
+	{[incr]}' case, with new test case [Bug 3736] and seg fault on 'expr
+	+ {[error]}' (different cause) that was caused by a correct
+	optimization that didn't correctly track how it was modifying the
+	source string in the opt. The optimization was removed, which means
+	that:
+		expr 1 + {[string length abc]}
+	will be not be compiled inline as before, but this should be written:
+		expr {1 + [string length abc]}
+	which will be compiled inline for speed. This prevents:
+		expr 1 + {[mindless error]}
+	from seg faulting, and only affects optimizations for degenerate cases
+	[Bug 3737]
+
+1999-12-01  Scott Redman <redman@scriptics.com>
+
+	* generic/tcl.decls:
+	* generic/tclMain.c:
+	* unix/tclAppInit.c:
+	* win/tclAppInit.c: Added two new internal functions,
+	TclSetStartupScriptFileName() and TclGetStartupScriptFileName() and
+	added hooks into the main() code for supporting TclPro and other "big"
+	shells more easily without requiring a copy of the main() code.
+
+	* generic/tclEncoding.c:
+	* generic/tclEvent.c: Moved encoding-related startup code from
+	tclEvent.c into the more appropriate tclEncoding.c.
+
+1999-11-30  Jeff Hobbs  <hobbs@scriptics.com>
+
+	* generic/tclIO.c: fix from Kupries for	Tcl_UnstackChannel that
+	correctly handles resetting translation and encoding.
+
+	* generic/tclLoad.c: #def'd out the unloading of DLLs at finalize time
+	for Unix in TclFinalizeLoad. [Bug 2560 3373] Should be parametrized
+	to allow for user to specify unload or not.
+
+	* win/tclWinTime.c: fixed handling of %Z on NT for time zones that
+	don't have DST.
+
+1999-11-29  Jeff Hobbs  <hobbs@scriptics.com>
+
+	* library/dde1.1/pkgIndex.tcl:
+	* library/reg1.0/pkgIndex.tcl: added supported for debugged versions
+	of the libraries
+
+	* unix/tclUnixPipe.c: fixed PipeBlockModeProc to properly set
+	isNonBlocking flag on pipe. [Bug 1356 710]
+	removed spurious fcntl call from PipeBlockModeProc
+
+	* tests/scan.test:
+	* generic/tclScan.c: fixed scan where %[..] didn't match anything and
+	added test case. [Bug 3700]
+
+1999-11-24  Jeff Hobbs  <hobbs@scriptics.com>
+
+	* doc/open.n:
+	* win/tclWinSerial.c: adopted patch from Schroedter to handle
+	fconfigure $sock -lasterror on Windows. [RFE 3368]
+
+	* generic/tclCmdIL.c: made SORTMODE_INTEGER work with Longs [Bug 3652]
+
+1999-11-23  Scott Stanton  <stanton@scriptics.com>
+
+	* library/tcltest1.0/tcltest.tcl: Fixed bug where tcltest output went
+	to stdout instead of the specified output file in some cases.
+
+1999-11-19  Jeff Hobbs  <hobbs@scriptics.com>
+
+	* generic/tclProc.c: backed out change from 1999-11-18 as it could
+	affect return string from upvar as well.
+
+	* tools/tcl.wse.in: added tcltest1.0 library to distribution list
+
+	* doc/http.n:
+	* library/http2.1/http.tcl:
+	* library/http2.1/pkgIndex.tcl: updated http package to 2.2
+
+1999-11-18  Jeff Hobbs  <hobbs@scriptics.com>
+
+	* unix/tcl.m4: added defined for _THREAD_SAFE in --enable-threads
+	case; added check for pthread_mutex_init in libc; in AIX case, with
+	--enable-threads ${CC}_r is used; fixed flags when using gcc on SCO
+
+	* generic/tclProc.c: corrected error reporting for default case at the
+	global level for uplevel command.
+
+	* generic/tclIOSock.c: changed int to size_t type for len in
+	TclSockMinimumBuffers.
+
+	* generic/tclCkalloc.c: fixed Tcl_DbCkfree to return a value on NULL
+	input. [Bug 3400]
+
+	* generic/tclStringObj.c: fixed support for passing in negative length
+	to Tcl_SetUnicodeObj, et al handling routines. [Bug 3380]
+
+	* doc/scan.n:
+	* tests/scan.test:
+	* generic/tclScan.c: finished support for inline scan by supporting
+	XPG identifiers.
+
+	* doc/http.n:
+	* library/http2.1/http.tcl: added register and unregister commands to
+	http:: package (better support for tls/SSL), as well as -type argument
+	to http::geturl. [RFE 2617]
+
+	* generic/tclBasic.c: removed extra decr of numLevels in Tcl_EvalObjEx
+	that could cause seg fault. (mjansen@wendt.de)
+
+	* generic/tclEvent.c: fixed possible lack of MutexUnlock in
+	Tcl_DeleteExitHandler. [Bug 3545]
+
+	* unix/tcl.m4: Added better pthreads library check and inclusion of
+	_THREAD_SAFE in --enable-threads case
+	Added support for gcc config on SCO
+
+	* doc/glob.n: added note about ..../ glob behavior on Win9*
+	* doc/tcltest.n: fixed minor example errors. [Bug 3551]
+
+1999-11-17 Brent Welch <welch@scriptics.com>
+
+	* library/http2.1/http.tcl: Correctly fixed the -timeout problem
+	mentioned in the 10-29 change. Also added error handling for failed
+	writes on the socket during the protocol.
+
+1999-11-09  Jeff Hobbs  <hobbs@scriptics.com>
+
+	* doc/open.n: corrected docs for 'a' open mode.
+
+	* generic/tclIOUtil.c: changed Tcl_Alloc to ckalloc
+
+	* generic/tclInt.h:
+	* generic/tclObj.c: rolled back changes from 1999-10-29
+	Purify noted new leaks with that code
+
+	* generic/tclParse.c: added code in Tcl_ParseBraces to test for
+	possible unbalanced open brace in a comment
+
+	* library/init.tcl: removed the installed binary directory from the
+	auto_path variable
+
+	* tools/tcl.wse.in: updated to 8.3a1, fixed install of twind.tcl and
+	koi8-r.enc files
+
+	* unix/tcl.m4: added recognition of pthreads library for AIX
+
+1999-10-29  Brent Welch <welch@scriptics.com>
+
+	* generic/tclInt.h: Modified the TclNewObj and TclDecrRefCount in two
+	ways. First, in the case of TCL_THREADS, we do not use the special
+	Tcl_Obj allocator because that is a source of lock contention. Second,
+	general code cleanup to eliminate duplicated code. In particular,
+	TclDecrRefCount now uses TclFreeObj instead of duplicating that code,
+	so it is now identical to Tcl_DecrRefCount.
+
+	* generic/tclObj.c: Changed Tcl_NewObj so it uses the TclNewObj macro
+	instead of duplicating the code. Adjusted TclFreeObj so it understands
+	the TCL_THREADS case described above.
+
+	* library/http2.1/http.tcl: Fixed a bug in the handling of the
+	state(status) variable when the -timeout flag is specified. Previously
+	it was possible to leave the status undefined instead of empty, which
+	caused errors in http::status
+
+1999-10-28  Jeff Hobbs  <hobbs@scriptics.com>
+
+	* unix/aclocal.m4: made it just include tcl.m4
+
+	* library/tcltest1.0/tcltest.tcl: updated makeFile to return full
+	pathname of file created
+
+	* generic/tclStringObj.c: fixed Tcl_AppendStringsToObjVA so it only
+	iterates once over the va_list (avoiding a memcpy of it, which is not
+	portable).
+
+	* generic/tclEnv.c: fixed possible ABR error in environ array
+
+	* tests/scan.test:
+	* generic/tclScan.c: added support for use of inline scan, XPG3
+	currently not included
+
+	* tests/incr.test:
+	* tests/set.test:
+	* generic/tclCompCmds.c: fixed improper bytecode handling of 'eval
+	{set array($unknownvar) 5}' (also for incr). [Bug 3184]
+
+	* win/tclWinTest.c: added testvolumetype command, as atime is
+	completely ignored for Windows FAT file systems
+	* win/tclWinPort.h: added sys/utime.h to includes
+	* unix/tclUnixPort.h: added utime.h to includes
+	* doc/file.n:
+	* tests/cmdAH.test:
+	* generic/tclCmdAH.c: added time arguments to atime and mtime file
+	command methods (support 'touch' functionality)
+
+1999-10-20  Jeff Hobbs  <hobbs@scriptics.com>
+
+	* unix/tclUnixNotfy.c: fixed event/io threading problems by making
+	triggerPipe non-blocking. [Bug 2792]
+
+	* library/tcltest1.0/tcltest.tcl:
+	* generic/tclThreadTest.c: fixed mem leaks in threads
+
+	* generic/tclResult.c: fixed Tcl_AppendResultVA so it only iterates
+	once over the va_list (avoiding a memcpy of it, which is not
+	portable).
+
+	* generic/regc_color.c: fixed mem leak and assertion, from HS
+
+	* generic/tclCompile.c: removed savedChar trick that appeared to be
+	causing a segv when the literal table was released
+
+	* tests/string.test:
+	* generic/tclCmdMZ.c: fixed [string index] to return ByteArrayObj when
+	indexing into one (test case string-5.16). [Bug 2871]
+
+	* library/http2.1/http.tcl: protected gets with catch. [Bug 2665]
+
+1999-10-19  Jennifer Hom  <jenn@scriptics.com>
+
+	* tests/tcltest.test:
+	* doc/tcltest.n:
+	* library/tcltest1.0/tcltest.tcl: Removed the extra return at the end
+	of the tcltest.tcl file, added version information about tcl.
+
+	Applied patches sent in by Andreas Kupries to add helper procs for
+	debug output, add 3 new flags (-testsdir, -load, -loadfile), and
+	internally refactors common code for dealing with paths into separate
+	procedures. [Bug 2838, 2842]
+
+	Merged code from core-8-2-1 branch that changes the checks for the
+	value of tcl_interactive to also incorporate a check for the existence
+	of the variable.
+
+	* tests/autoMkindex.test:
+	* tests/pkgMkIndex.test: Explicitly cd to ::tcltest::testsDirectory at
+	the beginning of the test run
+
+	* tests/basic.test: Use version information defined in tcltest instead
+	of hardcoded version number
+
+	* tests/socket.test: package require tcltest before attempting to use
+	variable defined in tcltest namespace
+
+	* tests/unixInit.test:
+	* tests/unixNotfy.test: Added explicit exits needed to avoid problems
+	when the tests area run in wish.
+
+1999-10-12  Jim Ingham  <jingham@scriptics.com>
+
+	* mac/tclMacLoad.c: Stupid bug - we converted the filename to
+	external, but used the unconverted version.
+	* mac/tclMacFCmd.c: Fix a merge error in the bug fix for [Bug 2869]
+
+1999-10-12  Jeff Hobbs  <hobbs@scriptics.com>
+
+	* generic/regc_color.c:
+	* generic/regc_cvec.c:
+	* generic/regc_lex.c:
+	* generic/regc_locale.c:
+	* generic/regcomp.c:
+	* generic/regcustom.h:
+	* generic/regerrs.h:
+	* generic/regex.h:
+	* generic/regexec.c:
+	* generic/regguts.h:
+	* generic/tclRegexp.c:
+	* generic/tclTest.c:
+	* tests/reg.test: updated to Henry Spencer's new regexp engine
+	(mid-Sept 99). Should greatly reduce stack space reqs.
+
+	* library/tcltest1.0/pkgIndex.tcl: fixed procs in pkgIndex.tcl file
+
+	* generic/tclEnv.c: fixed mem leak with putenv and DStrings
+	* doc/Encoding.3: corrected docs
+	* tests/basic.test: updated test cases for 8.3
+	* tests/encoding.test: fixed test case that change system encoding to
+	a double-byte one (this causes a bogus mem read error for purify)
+	* unix/Makefile.in: purify has to use -best-effort to instrument
+	* unix/tclAppInit.c: identified potential mem leak when compiling
+	tcltest (not critical)
+	* unix/tclUnixPipe.c: fixed mem leak in TclpCreateProcess when doing
+	alloc between vfork and execvp.
+	* unix/tclUnixTest.c: fixed mem leak in findexecutable test command
+
+1999-10-05  Jeff Hobbs  <hobbs@scriptics.com>
+
+	* {win,mac,unix,tools,}/README:
+	* win/README.binary:
+	* win/makefile.vc:
+	* {win,unix}/configure.in:
+	* generic/tcl.h:
+	* library/init.tcl: updated to 8.3a1 from 8.2.0.
+
+	* library/http2.1/http.tcl: fixed possible use of global c var.
+
+	* win/tclWinReg.c: fixed registry command to properly 'get'
+	HKEY_PERFORMANCE_DATA root key data. Needs more work.
+
+	* generic/tclNamesp.c:
+	* generic/tclVar.c:
+	* generic/tclCmdIL.c: fixed comment typos
+
+	* mac/tclMacFCmd.c: fixed filename stuff to support UTF-8. [Bug 2869]
+
+	* win/tclWinSerial.c: changed SerialSetOptionProc to return TCL_OK by
+	default. (patch from Rolf Schroedter)
+
+1999-09-21  Jennifer Hom  <jenn@scriptics.com>
+
+	* library/tcltest1.0/tcltest.tcl: Applied patches sent in by Andreas
+	Kupries to fix typos in comments and ::tcltest::grep, fix hook
+	redefinition problems, and change "string compare" to "string equal".
+	[Bug 2836, 2837, 2839, 2840]
+
+1999-09-20  Jeff Hobbs  <hobbs@scriptics.com>
+
+	* tests/env.test:
+	* unix/Makefile.in: added support for AIX LIBPATH env var. [Bug 2793]
+	removed second definition of INCLUDE_INSTALL_DIR (the one that
+	referenced @includedir@) [Bug 2805]
+	* unix/dltest/Makefile.in: added -lc to LIBS. [Bug 2794]
+
+1999-09-16  Jeff Hobbs  <hobbs@scriptics.com>
+
+	* tests/timer.test: changed after delay in timer test 6.29 from 1 to
+	10. [Bug 2796]
+
+	* tests/pkg.test:
+	* generic/tclPkg.c: fixed package version check to disallow 1.2..3
+	[Bug 2539]
+
+	* unix/Makefile.in: fixed gendate target - this never worked since RCS
+	was intro'd.
+	* generic/tclGetDate.y: updated to reflect previous changes to
+	tclDate.c (leap year calc) and added CEST and UCT time zone
+	recognition. Fixed 4 missing UCHAR() casts. [Bug 2717, 954, 1245,
+	1249]
+
+	* generic/tclCkalloc.c: changed Tcl_DumpActiveMemory to really dump to
+	stderr and close it [Bug 725] and changed Tcl_Ckrealloc and
+	Tcl_Ckfree to not bomb when NULL was passed in [Bug 1719] and changed
+	Tcl_Alloc, et al to not panic when a alloc request for zero came
+	through and NULL was returned (valid on AIX, Tru64) [Bug 2795, etc]
+
+	* tests/clock.test:
+	* doc/clock.n:
+	* generic/tclClock.c: added -milliseconds switch to clock clicks to
+	guarantee that the return value of clicks is in the millisecs
+	granularity. [Bug 2682, 1332]
+
+1999-09-15  Jeff Hobbs  <hobbs@scriptics.com>
+
+	* generic/tclIOCmd.c: fixed potential core dump in conjunction with
+	stacked channels with result obj manipulation in Tcl_ReadChars. [Bug
+	2623]
+
+	* tests/format.test:
+	* generic/tclCmdAH.c: fixed translation of %0#s in format. [Bug 2605]
+
+	* doc/msgcat.n: fixed \\ bug in example. [Bug 2548]
+
+	* unix/tcl.m4:
+	* unix/aclocal.m4: added fix for FreeBSD-[1-2] recognition [Bug 2070]
+	and fix for IRIX SHLIB_LB_LIBS. [Bug 2610]
+
+	* doc/array.n:
+	* tests/var.test:
+	* tests/set.test:
+	* generic/tclVar.c: added an array unset operation, with docs and
+	tests. Variation of [Bug 1775]. Added fix in TclArraySet to check
+	when trying to set in a non-existent namespace. [Bug 2613]
+
+1999-09-14  Jeff Hobbs  <hobbs@scriptics.com>
+
+	* tests/linsert.test:
+	* doc/linsert.n:
+	* generic/tclCmdIL.c: fixed end-int interpretation of linsert to
+	correctly calculate value for end, added test and docs. [Bug 2693]
+
+	* doc/regexp.n:
+	* doc/regsub.n:
+	* tests/regexp.test:
+	* generic/tclCmdMZ.c: add -start switch to regexp and regsub with docs
+	and tests
+
+	* doc/switch.n: added proper use of comments to example.
+	* generic/tclCmdMZ.c: changed switch to complain when an error occurs
+	that seems to be due to a misplaced comment.
+
+	* generic/tclCmdMZ.c: fixed illegal ref for \[0-9] substitutions in
+	regsub. [Bug 2723]
+
+	* generic/tclCmdMZ.c: changed [string equal] to return an Int type
+	object (was a Boolean)
+
+1999-09-01  Jennifer Hom  <jenn@scriptics.com>
+
+	* library/tcltest1.0/tcltest.tcl: Process command-line arguments only
+	::tcltest doesn't have a child namespace (requires that command-line
+	args are processed in that namespace)
+
+1999-09-01  Jeff Hobbs  <hobbs@scriptics.com>
+
+	* generic/tclParseExpr.c: changed '"' to '\"' to make FreeBSD happy.
+	[Bug 2625]
+	* generic/tclProc.c: moved static buf to better location and changed
+	static msg that would overflow in ProcessProcResultCode [Bug 2483]
+	and added Tcl_DStringFree to Tcl_ProcObjCmd. Also reworked size of
+	static buffers.
+	* tests/stringObj.test: added test 9.11
+	* generic/tclStringObj.c: changed Tcl_AppendObjToObj to properly
+	handle the 1-byte dest and mixed src case where both had had Unicode
+	string len checks made on them. [Bug 2678]
+	* unix/aclocal.m4:
+	* unix/tcl.m4: adjusted fix from 8-21 to add -bnoentry to the AIX-*
+	case and readjusted the range
+
+1999-08-31  Jennifer Hom  <jenn@scriptics.com>
+
+	* library/tcltest1.0/tcltest.tcl:
+	* doc/tcltest.n:
+	* tests/README: Modified testConstraints variable so that it isn't
+	unset every time ::tcltest::initConstraints is called and cleaned up
+	documentation in the README file and the man page.
+
+1999-08-27  Jennifer Hom  <jenn@scriptics.com>
+
+	* tests/env.test:
+	* tests/exec.test:
+	* tests/io.test:
+	* tests/event.test:
+	* tests/tcltest.test: Added 'exit' calls to scripts that the tests
+	themselves write, and removed accidental checkin of knownBugThreaded
+	constraints for Solaris and Linux.
+
+	* library/tcltest1.0/tcltest.tcl: Modified tcltest so that variables
+	are only initialized to their default values if they did not
+	previously exist.
+
+1999-08-26  Jennifer Hom  <jenn@scriptics.com>
+
+	* tests/tcltest.test:
+	* library/tcltest1.0/tcltest.tcl: Added a -args flag that sets a
+	variable named ::tcltest::parameters based on whatever's being sent in
+	as the argument to the -args flag.
+
+1999-08-23  Jennifer Hom  <jenn@scriptics.com>
+
+	* tests/tcltest.test: Added additional tests for -tmpdir, marked all
+	tests that use exec as unixOrPc.
+
+	* tests/encoding.test:
+	* tests/interp.test:
+	* tests/macFCmd.test:
+	* tests/parseOld.test:
+	* tests/regexp.test: Applied patches from Jim Ingham to add encoding
+	to a Mac only interp test, change an error message in macFCmd.tet, put
+	a comment in parseOld.test, fix tests using the testencoding path
+	command, and put unixOrPc constraints on tests that use exec.
+
+1999-08-21  Jeff Hobbs  <hobbs@scriptics.com>
+
+	* unix/aclocal.m4: Changed AIX-4.[2-9] check to AIX-4.[1-9] [Bug 1909]
+
+1999-08-20  Jeff Hobbs  <hobbs@scriptics.com>
+
+	* generic/tclPosixStr.c: fixed typo. [Bug 2592]
+
+	* doc/*: fixed various nroff bugs in man pages. [Bug 2503 2588]
+
+1999-08-19  Jeff Hobbs  <hobbs@scriptics.com>
+
+	* win/README.binary: fixed version info and some typos. [Bug 2561]
+
+	* doc/interp.n: updated list of commands available in a safe
+	interpreter. [Bug 2526]
+
+	* generic/tclIO.c: changed Tcl_GetChannelNames* to use style guide
+	headers (pleases HP cc)
+
+1999-08-18  Jeff Hobbs  <hobbs@scriptics.com>
+
+	* doc/Eval.3: fixed doc on input args. [Bug 2114]
+
+	* doc/OpenFileChnl.3:
+	* doc/file.n:
+	* tests/cmdAH.test:
+	* tclIO.c:
+	* tclCmdAH.c: added "file channels ?pattern?" tcl command, with
+	associated Tcl_GetChannelNames and Tcl_GetChannelNamesEx public C APIs
+	(added to tcl.decls as well), with docs and tests.
+
+	* tests/expr.test:
+	* generic/tclCompile.c: add TCL_TOKEN_VARIABLE to the part types that
+	cause differed compilation for exprs, to correct the expr
+	double-evaluation problem for vars. Added test cases. Related to [Bug
+	732]
+
+	* unix/Makefile.in: changed the dependency structure so that install-*
+	is dependent on * (ie - install-binaries is dependent on binaries).
+
+	* library/auto.tcl:
+	* library/init.tcl:
+	* library/ldAout.tcl:
+	* library/package.tcl:
+	* library/safe.tcl:
+	* library/word.tcl:
+	* library/http2.1/http.tcl:
+	* library/msgcat1.0/msgcat.tcl: updated libraries to better Tcl style
+	guide (no more string comparisons with == or !=, spacing changes).
+
+1999-08-05  Jim Ingham  <jingham@cygnus.com>
+
+	* mac/tclMacProjects.sea.hqx: Rearrange the projects so that the build
+	directory is separate from the sources. Much more convenient!
+
+1999-08-13  Scott Redman <redman@scriptics.com>
+
+	* /: 8.2.0 tagged for final release
+
+1999-08-12  Scott Stanton  <stanton@scriptics.com>
+
+	* win/Makefile.in: Added COMPILE_DEBUG_FLAGS macro to make it easier
+	to turn on compiler tracing.
+
+	* tests/parse.test:
+	* generic/tclParse.c: Fixed bug in Tcl_EvalEx where the termOffset was
+	not being updated in cases where the evaluation returned a non TCL_OK
+	error code. [Bug 2535]
+
+1999-08-12  Scott Redman  <redman@scriptics.com>
+
+	* win/tclWinSerial.c: Applied patch from Petteri Kettunen to remove
+	compiler warning.
+
+1999-08-10  Scott Redman  <redman@scriptics.com>
+
+	* generic/tclAlloc.c:
+	* generic/tclCmdIL.c:
+	* generic/tclIO.c:
+	* generic/tclThread.c:
+	* win/tclWinThrd.c:
+	* unix/tclUnixThrd.c: Fixed Brent's changes so that they work on
+	Windows (and he fixed the bug in the Unix thread implementation).
+
+1999-08-09  Brent Welch  <welch@scriptics.com>
+
+	* generic/tcl.decls:
+	* generic/tclAlloc.c:
+	* generic/tclCkalloc.c:
+	* generic/tclCmdIL.c:
+	* generic/tclDecls.h:
+	* generic/tclIO.c:
+	* generic/tclInt.decls:
+	* generic/tclIntDecls.h:
+	* generic/tclStubInit.c:
+	* generic/tclVar.c:
+	* mac/tclMacThrd.c:
+	* unix/tclUnixThrd.c:
+	* win/tclWinThrd.c: Added use of Tcl_GetAllocMutex to tclAlloc.c and
+	tclCkalloc.c so they can be linked against alternate thread packages.
+	Added Tcl_GetChannelNames to tclIO.c. Added TclVarTraceExists hook so
+	"info exists" triggers read traces exactly like it did in Tcl 7.6.
+	Stubs table changes to reflect new internal and external APIs.
+
+1999-08-09  Jeff Hobbs  <hobbs@scriptics.com>
+
+	* tests/string.test: added largest_int proc to adapt for >32 bit
+	machines and int overflow testing.
+	* tests/tcltest.test: fixed minor error in 8.2 result (from dgp)
+
+	* doc/Object.3: clarified Tcl_DecrRefCount docs. [Bug 1952]
+	* doc/array.n: clarified array pattern docs. [Bug 1330]
+	* doc/clock.n: fixed clock docs. [Bug 693]
+	* doc/lindex.n: clarified to account for new end-int behavior.
+	* doc/string.n: fixed formatting errors. [Bug 2188 2189]
+	* doc/tclvars.n: fixed doc error. [Bug 2042]
+	* library/init.tcl: fixed path handling in auto_execok (it could miss
+	including the normal path on some Windows machines). [Bug 1276]
+
+1999-08-05  Jeff Hobbs  <hobbs@scriptics.com>
+
+	* doc/tclvars.n: Made it clear that tcl_pkgPath was not set for
+	Windows (already mentioned in init.tcl). [Bug 2455]
+	* generic/tclLiteral.c: fixed reference to bytes that might not be
+	null terminated (using objPtr->bytes, which is). [Bug 2496]
+	* library/http2.1/http.tcl: Made use of "i" in init section use local
+	var and start at 0 (was 1). [Bug 2502]
+
+1999-08-04  Scott Stanton  <stanton@scriptics.com>
+
+	* tests/reg.test: Added test for REG_EXPECT bug fixed by Henry's
+	patch.
+
+	* generic/regc_nfa.c:
+	* generic/regcomp.c:
+	* generic/rege_dfa.c:
+	* generic/regexec.c:
+	* generic/regguts.h: Applied patches supplied by Henry Spencer to
+	greatly enhance the performance of certain classes of regular
+	expressions. [Bug 2440, 2447]
+
+1999-08-03  Scott Redman  <redman@scriptics.com>
+
+	* win/tclWinInt.h: Remove function declarations in header that was
+	moved to tclInt.decls file in previous changes.
+
+1999-08-02  Scott Redman  <redman@scriptics.com>
+
+	* unix/configure.in:
+	* win/configure.in: Change beta level to b2.
+
+	* generic/tcl.h:
+	* generic/tcl.decls:
+	* generic/tclDecls.h:
+	* generic/tclInt.h:
+	* generic/tclInt.decls:
+	* generic/tclIntDecls.h:
+	* generic/tclRegexp.h:
+	* generic/tclStubInit.c: Move some exported public and internal
+	functions to the stub tables. Removed functions that are in the stub
+	tables (from this and previous changes) from the original header
+	files.
+
+1999-08-01  Scott Redman  <redman@scriptics.com>
+
+	* win/tclWinSock.c: Added comment block to SocketThread() function.
+	Added code to avoid calling TerminateThread(), but instead to send a
+	message to the socket event window to tell it to terminate its thread.
+
+1999-07-30  Jennifer Hom  <jenn@scriptics.com>
+
+	* tests/tcltest.test:
+	* library/tcltest1.0/tcltest.tcl: Exit with non-zero status if there
+	were problems with the way the test suite was started (e.g. wrong #
+	arguments).
+
+1999-07-30  Jeff Hobbs  <hobbs@scriptics.com>
+
+	* generic/tclInt.decls: added declaractions necessary for the Tcl test
+	code to work wth stubs. [Bug 2445]
+
+1999-07-30  Scott Redman  <redman@scriptics.com>
+
+	* win/tclWinPipe.c:
+	* win/Makefile.in: Fixing launching of 16-bit apps on Win9x from wish.
+	The command line was primed with tclpip82.dll, but it was ignored.
+	Fixed that, then fixed the gmake makefile to build tclpip82.dll as an
+	executable.
+
+	* win/tclWinSock.c: Applied small patch to get thread-specific data
+	after initializing the socket driver.
+
+	* unix/tclUnixThrd.c: Applied patch to fix threads on Irix 6.5. Patch
+	from James Dennett. [Bug 2450]
+
+	* tests/info.test: Enable test for tclParse.c change (info complete).
+
+1999-07-30  Jeff Hobbs  <hobbs@scriptics.com>
+
+	* tclIO.c: added fix for Kupries' trf patch. [Bug 2386]
+
+	* tclParse.c: fixed bug in info complete regarding nested square
+	brackets. [Bug 2382, 2466]
+
+1999-07-29  Scott Redman  <redman@scriptics.com>
+
+	* win/tclWinChan.c: Allow tcl to open CON and NUL, even for std
+	channels. Checking for bad/unusable std channels was moved to Tk since
+	its only purpose was to check whether to use the Tk Console Window for
+	the std channels. [Bug 2393 2392 2209 2458]
+
+	* unix/mkLinks.tcl: Applied patch to avoid linking pack.n to
+	pack-old.n. Patch from Don Porter. [Bug 2469]
+
+	* doc/Encoding.n: Applied patch to fix typo in .SH NAME line. Patch
+	from Don Porter. [Bug 2451]
+
+	* win/tclWinSock.c: Free Win32 Event handles when destroying the
+	socket helper thread.
+
+1999-07-28  Jennifer Hom  <jenn@scriptics.com>
+
+	* tests/tcltest.test:
+	* library/tcltest1.0/tcltest.tcl: Fixed the condition under which
+	::tcltest::PrintError had an infinite loop problem and added a test
+	case for it. Added an optional argument to ::tcltest::getMatchingFiles
+	telling it where to search for test files.
+
+1999-07-27  Scott Redman  <redman@scriptics.com>
+
+	* tools/tclSplash.bmp: Updated Windows installer bitmap to ready
+	Tcl/Tk Version 8.2.
+
+1999-07-26  Scott Redman  <redman@scriptics.com>
+
+	* tests/tcltest.test: Need to close the new core file, there seems to
+	be a hang in threaded WinNT if the file isn't closed. Open issue, need
+	to fix that hang.
+
+	* tests/httpold.test: Add time delay in response from Http server so
+	that test cases can properly detect timeout conditions with threads
+	enabled on multi-CPU WinNT.
+
+	* tests/winFCmd.test: Test case winFcmd-1.33 was looking for
+	c:\windows, which may not exist. Instead, create a new directory on
+	c:\ and use it for the test.
+
+	* win/tclWinConsole.c:
+	* win/tclWinPipe.c:
+	* win/tclWinSock.c: Fix terminating helper threads by holding any
+	mutexes from the primary thread while waiting for the helper thread to
+	terminate. Without these changes, the test suite hangs on WinNT with 2
+	CPUs and threads enabled. Open issue, seems to be a sporadic hang on
+	dual CPU systems still (very rare).
+
+1999-07-26  Jennifer Hom  <jenn@scriptics.com>
+
+	* tests/tcltest.test:
+	* library/tcltest1.0/tcltest.tcl:
+	* doc/tcltest.n: Cleaned up code in ::tcltest::PrintError, revised
+	documentation, and added tests for the tcltest package.
+
+1999-07-23  Scott Redman  <redman@scriptics.com>
+
+	* tests/info.test:
+	* generic/tclParse.c: Removed patch for info command, breaks test
+	cases on Unix. Patch was bad and needs to be redone properly. [Bug
+	2382]
+
+1999-07-22  Scott Redman  <redman@scriptics.com>
+
+	* Changed version to 8.2b2.
+
+	* win/tclWinSock.c: Fixed hang with threads enabled, fixed semaphores
+	with threads disabled.
+
+	* win/safe.test: Fixed safe-6.3 with threads enabled.
+
+	* win/Makefile.in: Fixed calling of tcltest to fix safe.test failures
+	due to path TCL_LIBRARY path.
+
+	* win/tclWinPort.h: Block out include of sys/*.h in order to build
+	extensions with MetroWerks compiler for Win32. [Bug 2385]
+
+	* generic/tclCmdMZ.c:
+	* generic/tclIO.c: Fix ANSI-style prototypes based on patch from
+	Ulrich Ring. [Bug 2391]
+
+	* unix/Makefile.in: Need to make install-sh executable before calling
+	(with chmod +x). [Bug 2413]
+
+	* tests/var.test:
+	* generic/tclVar.c: Fixed bug that caused a seg. fault when using
+	"array set a(b) {}", which is a bad array name anyway. Now the "array
+	set" command will return an error in this case. Added test case and
+	fixed existing test. [Bug 2427]
+
+1999-07-21  Scott Redman  <redman@scriptics.com>
+
+	* tests/info.test:
+	* generic/tclParse.c: Applied patch to fix "info complete" for the
+	string {[a [b]}. Patch from Peter Spjuth. [Bug 2382]
+
+	* doc/Utf.3:
+	* generic/tcl.decls:
+	* generic/tclDecls.h:
+	* generic/tclUtf.c: Changed function declarations in
+	non-platform-specific public APIs to use "unsigned long" instead of
+	"size_t", which may not be defined on certain compilers (rather than
+	include sys/types.h, which may not exist).
+
+	* unix/Makefile.in: Added the Windows configure script to the
+	distribution file list, already shipping configure.in and the .m4
+	files, but needed the configure script itself.
+
+	* win/makefile.vc: Changed version number of DDE package in VC++
+	makefile to use 1.1 instead of 1.0.
+
+	* doc/open.n: Added documentation of \\.\comX notation for opening
+	serial ports on Windows (alternative to comX:).
+
+	* tests/ioCmd.test:
+	* doc/open.n:
+	* win/tclWinSerial.c: Applied patch from Rolf Schroedter to add
+	-pollinterval option to fconfigure to modify the maxblocktime used in
+	the fileevent polling. Added documentation and fixed the test case as
+	well.
+
+	* win/tclWinSock.c: Modified 8.1.0 version of the Win32 socket driver
+	to move the handling of the socket event window in a separate thread.
+	It also turned out that Win95 & Win98 were, in some cases, getting
+	multiple FD_ACCEPTs but only handling one. Added a count for the
+	FD_ACCEPT to take care of this. Tested on NT4 SP3, NT4 SP4, Win95, and
+	Win98. [Bug 2178 2256 2259 2329 2323 2355]
+
+1999-07-21  Jerry Peek  <jpeek@scriptics.com>
+
+	* README: Small tweaks to clean up typos and wording.
+
+1999-07-20  Melissa Hirschl  <hershey@matisse.scriptics.com>
+
+	* generic/tclInitScript.h:
+	* unix/tclUnixInit.c: merged code with 8.0.5. We now use an
+	intermediate global tcl var "tclDefaultLibrary" to keep the
+	"tcl_library" var from being set by the default value in the Makefile.
+	Also fixed a bug in which caused the value of TCL_LIBRARY env var to
+	be ignored.
+	* unix/tclWinInit.c: just updated some comments.
+
+1999-07-19  Melissa Hirschl  <hershey@matisse.scriptics.com>
+
+	* library/http2.1/http.tcl: updated -useragent text to say version
+	2.1.
+
+1999-07-16  Scott Redman  <redman@scriptics.com>
+
+	* generic/tcl.decls:
+	* generic/tclDecls.h:
+	* generic/tclStubInit.c: Add Tcl_SetNotifier to stub table. [Bug 2364]
+
+	* unix/aclocal.m4:
+	* unix/tcl.m4: Add check for Alpha/Linux to correct the IEEE floating
+	flag to the compiler, should be -mieee. Patch from Don Porter.
+
+	* tools/tcl.hpj.in: Change version number of .cnt file referenced in
+	.HPJ file.
+
+1999-07-15  Scott Redman  <redman@scriptics.com>
+
+	* tools/tcl.wse.in: Fixed naming of target files for Windows.
+
+1999-07-14  Jerry Peek  <jpeek@scriptics.com>
+
+	* doc/re_syntax.n: Deleted sentence as suggested by Scott S.
+
+1999-07-12  Jerry Peek  <jpeek@scriptics.com>
+
+	* doc/re_syntax.n: Removed two notes to myself (oops), cleaned up
+	wording, fixed changebars, made two examples easier to read.
+
+1999-07-11  Scott Redman  <redman@scriptics.com>
+
+	* win/makefile.vc: Since the makefile.vc should continue to work while
+	we're working out bugs/issues in the new TEA-style
+	autoconf/configure/gmake build mechanism for Windows, the version
+	numbers of the Tcl libraries need to remain in sync. Modified the
+	version numbers in the makefile to reflect the change to 8.2b1.
+
+1999-07-09  Scott Redman  <redman@scriptics.com>
+
+	* win/configure.in: Eval DLLSUFFIX, LIBSUFFIX, and EXESUFFIX in the
+	configure script so that substitutions get expanded before being
+	placed in the Makefile. The "d" portion for debug libraries and DLLs
+	was not being set properly.
+
+1999-07-08  Scott Stanton  <stanton@scriptics.com>
+
+	* tests/string.test:
+	* generic/tclCmdMZ.c: Fixed bug in string range bounds checking code.
+
+1999-07-08  Jennifer Hom  <jenn@scriptics.com>
+
+	* doc/tcltest.n:
+	* library/tcltest1.0/tcltest.tcl: Removed -asidefromdir and
+	-relateddir flags, removed unused ::tcltest::dotests proc, cleaned up
+	implementation of core file checking, and fixed the code that checks
+	for 1-letter flag abbreviations.
+
+1999-07-08  Scott Stanton  <stanton@scriptics.com>
+
+	* win/Makefile.in: Added tcltest target so runtest works properly.
+	Added missing names to the clean/distclean targets.
+
+	* tests/reg.test:
+	* generic/rege_dfa.c: Applied fix supplied by Henry Spencer for bug in
+	DFA state caching under lookahead conditions. [Bug 2318]
+
+1999-07-07  Scott Stanton  <stanton@scriptics.com>
+
+	* doc/fconfigure.n: Clarified default buffering behavior for the
+	standard channels. [Bug 2335]
+
+1999-07-06  Scott Redman  <redman@scriptics.com>
+
+	* win/tclWinSerial.c: New implementation of serial port driver from
+	Rolf Shroedter (Rolf.Schroedter@dlr.de) that allows more than one byte
+	to be read from the port. Implemented using polling instead of
+	threads, there is a max. 10ms latency between checking the port for
+	file events. [Bug 1980 2217]
+
+1999-07-06  Brent Welch  <welch@scriptics.com>
+
+	* library/http2.0/http.tcl: Fixed the -timeout option so it handles
+	timeouts that occur during connection attempts to hosts that are down
+	(the only case that really matters!)
+
+1999-07-03  Brent Welch  <welch@scriptics.com>
+
+	* doc/ChnlStack.3:
+	* generic/tcl.decls:
+	* generic/tclIO.c: Added a new variant of the "Trf patch" from Andreas
+	Kupres that adds new C APIs Tcl_StackChannel, Tcl_UnstackChannel, and
+	Tcl_GetStackedChannel.
+
+1999-07-03  Brent Welch  <welch@scriptics.com>
+
+	* generic/tclNotify.c:
+	* unix/tclUnixNotfy.c:
+	* unix/tclXtTest.c:
+	* unix/tclXtNotify.c:
+	* win/tclWinNotify.c:
+	* mac/tclMacNotify.c: Added Tcl_SetNotifier and the associated hook
+	points in the notifiers to be able to replace the notifier calls at
+	runtime. The Xt notifier and test program use this hook.
+
+1999-07-03  Brent Welch  <welch@scriptics.com>
+
+	* generic/tclParse.c: Changed parsing of variable names to allow empty
+	array names. Now "$(foo)" is a variable reference! Previous you had to
+	use something like $::(foo), which is slower. This change is requested
+	by Jean-Luc Fontaine for his STOOOP package.
+
+1999-07-01  Scott Redman  <redman@scriptics.com>
+
+	* generic/tclCmdAH.c:
+	* generic/tclFCmd.c: Call TclStat instead of TclpStat in order to
+	allow Tcl_Stat hooks to work properly.
+
+1999-06-29  Jennifer Hom  <jenn@scriptics.com>
+
+	* library/tcltest1.0/pkgIndex.tcl:
+	* library/tcltest1.0/tcltest.tcl:
+	* doc/tcltest.n:
+	* tests/all.tcl: Added -preservecore, -limitconstraints, -help, -file,
+	-notfile, -relateddir and -asidefromdir flags to the tcltest package
+	along with exported proc ::tcltest::getMatchingFiles. The
+	documentation was modified to match and all.tcl was modified to use
+	the new functionality instead of implementing -file itself.
+
+1999-06-28  Scott Redman  <redman@scriptics.com>
+
+	* generic/tclIndexObj.c:
+	* doc/GetIndex.3:
+	* tests/binary.test:
+	* tests/winDde.test: Applied patch from Peter Hardie (with changes) to
+	fix problem with Tcl_GetIndexFromObj() when the key being passed is
+	the empty string. It used to match "" and return TCL_OK, but it should
+	have returned TCL_ERROR instead. Added test case to "binary" and "dde"
+	commands to check the behavior. Added documentation note as well.
+
+1999-06-26  Scott Redman  <redman@scriptics.com>
+
+	* win/tclWinDde.c: Applied patch from Peter Hardie to add poke command
+	to dde. Also rev'd version of dde package to 1.1. [Bug 1738]
+
+1999-06-25  Jennifer Hom  <jenn@scriptics.com>
+
+	* unix/Makefile.in:
+	* win/Makefile.in:
+	* library/tcltest1.0/pkgIndex.tcl:
+	* library/tcltest1.0/tcltest.tcl:
+	* library/tcltest1.0: Added initial implementation of the Tcl test
+	harness package. This package was based on the defs.tcl file that was
+	part of the tests directory. Reversed the way that tests were
+	evaluated to fix a problem with false passes.
+
+	* doc/tcltest.n: Added documentation for the tcltest package.
+
+	* tests/README:
+	* tests/defs.tcl:
+	* tests/all.tcl: Modified all test files (tests/*.test) and all.tcl to
+	use the new tcltest package and removed references to the defs.tcl
+	file. Modified the README file to point to the man page for tcltest.
+
+1999-06-25  Scott Stanton  <stanton@scriptics.com>
+
+	* tests/reg.test:
+	* generic/regexec.c: Fixed bugs in non-greedy quantifiers.
+
+1999-06-23  Jerry Peek  <jpeek@scriptics.com>
+
+	* doc/re_syntax.n:
+	* doc/switch.n:
+	* doc/lsearch.n:
+	* doc/RegExp.3:
+	* doc/regexp.n:
+	* doc/regsub.n: Moved information about syntax of 8.1 regular
+	expressions from regexp(n) manpage into new re_syntax(n) page. Added
+	pointers from other manpages to new re_syntax(n) page.
+
+1999-06-23  Scott Stanton  <stanton@scriptics.com>
+
+	* unix/Makefile.in: Changed install-doc to install-man.
+
+	* tools/uniParse.tcl:
+	* tools/uniClass.tcl:
+	* tools/README:
+	* tests/string.test:
+	* generic/regc_locale.c:
+	* generic/tclUniData.c:
+	* generic/tclUtf.c:
+	* doc/string.n: Updated Unicode character tables to reflect latest
+	Unicode 2.1 data. Also rationalized "regexp" and "string is"
+	definitions of character classes.
+
+1999-06-21  Scott Stanton  <stanton@scriptics.com>
+
+	* unix/tclUnixThrd.c (TclpThreadCreate): Fixed memory leak where
+	thread attributes were not being released. [Bug 2254]
+
+1999-06-17  Scott Stanton  <stanton@scriptics.com>
+
+	* tests/regexp.test:
+	* generic/tclCmdMZ.c:
+	* generic/tclCmdIL.c: Changed to use new regexp interfaces. Added
+	-expanded, -line, -linestop, and -lineanchor switches to regsub.
+
+	* doc/RegExp.3: Documented the new regexp interfaces and the
+	compile/execute flags.
+
+	* generic/tclTest.c:
+	* generic/tclRegexp.h:
+	* generic/tclRegexp.c:
+	* generic/tcl.h:
+	* generic/tcl.decls: Renamed Tcl_RegExpMatchObj to Tcl_RegExpExecObj
+	and added a new Tcl_RegExpMatchObj that is equivalent to
+	Tcl_RegExpMatch. Added public macros for the regexp compile/execute
+	flags. Changed to store either an object pointer or a string pointer
+	in the TclRegexp structure. Changed to avoid adding a reference to the
+	object or copying the string.
+
+	* generic/regcomp.c: lint
+
+	* tests/reg.test:
+	* generic/regex.h:
+	* generic/regc_lex.c: Added REG_BOSONLY flag to allow Expect to
+	iterate through a string an only find matches that start at the
+	current position within the string.
+
+1999-06-16  Michael Thomas  <wart@scriptics.com>
+
+	* unix/configure.in:
+	* unix/Makefile.in:
+	* unix/tcl.m4:
+	* unix/aclocal.m4: Numerous build changes to make Tcl conform to the
+	proposed TEA spec
+
+1999-06-16  Melissa Hirschl  <hershey@matisse.scriptics.com>
+
+	* generic/tclVar.c (Tcl_VariableObjCmd): fixed premature increment in
+	loop that was causing out-of-bounds reads on array "varName".
+
+1999-06-16  Scott Stanton  <stanton@scriptics.com>
+
+	* tests/execute.test:
+	* generic/tclExecute.c (TclExecuteByteCode): Fixed crash caused by a
+	bug in INST_LOAD_SCALAR1 where the scalar index was read as a signed 1
+	byte value instead of unsigned. [Bug 2243]
+
+1999-06-14  Melissa Hirschl  <hershey@matisse.scriptics.com>
+
+	* doc/StringObj.3
+	* test/stringObj.test
+	* unix/Makefile.in
+	* win/Makefile.in
+	* win/makefile.vc
+	* generic/tclStringObj.c:
+	Merged String and Unicode object types. Added new functions to the
+	puplic API: Tcl_NewUnicodeObj, Tcl_SetUnicodeObj, Tcl_GetUnicode,
+	Tcl_GetUniChar, Tcl_GetCharLength, Tcl_GetRange,
+	Tcl_AppendUnicodeToObj.
+
+1999-06-09  Scott Stanton  <stanton@scriptics.com>
+
+	* generic/tclUnicodeObj.c: Lots of cleanup and simplification. Fixed
+	several memory bugs. Added TclAppendUnicodeToObj.
+
+	* generic/tclInt.h: Added declarations for various Unicode string
+	functions.
+
+	* generic/tclRegexp.c:
+	* generic/tclCmdMZ.c: Changed to use new Unicode string interfaces for
+	better performance.
+
+	* generic/tclRegexp.h:
+	* generic/tclRegexp.c:
+	* generic/tcl.h:
+	* generic/tcl.decls: Added Tcl_RegExpMatchObj and Tcl_RegExpGetInfo
+	calls to access lower level regexp API. These features are needed by
+	Expect. This is a preliminary implementation pending final review and
+	cleanup.
+
+	* generic/tclCmdMZ.c:
+	* tests/string.test: Fixed bug where string map failed on null strings
+
+	* generic/regexec.c:
+	* unix/tclUnixNotfy.c: lint
+
+	* tools/genStubs.tcl: Changed to always write output in LF mode.
+
+1999-06-08  Scott Stanton  <stanton@scriptics.com>
+
+	* win/tclWinSock.c: Rolled back to the 8.1.0 implementation because of
+	serious problems with the new driver. Basically no incoming socket
+	connections would be reported to a server port. The 8.1.1 code needs
+	to be redesigned and fixed correctly.
+
+1999-06-07  Melissa Hirschl  <hershey@matisse.scriptics.com>
+
+	* tests/string.test:
+	* generic/tclVar.c (Tcl_SetVar2Ex):
+	* generic/tclStringObj.c (Tcl_AppendObjToObj):
+	* generic/tclCmdMZ.c (Tcl_StringObjCmd): optimized the string index,
+	string length, string range, and append command in cases where the
+	object's internal rep is a bytearray. Objects with other internal reps
+	are converted to have the new unicode internal rep.
+
+	* unix/Makefile.in:
+	* win/Makefile.in:
+	* win/Makefile.vc:
+	* tests/unicode.test:
+	* generic/tclInt.h:
+	* generic/tclObj.c:
+	* generic/tclUnicodeObj.c: added a new object type to store the
+	unicode representation of a string.
+
+	* generic/tclTestObj.c: added the objtype option to the testobj
+	command. This option returns the name of the type of internal rep an
+	object has.
+
+1999-06-04  Scott Stanton  <stanton@scriptics.com>
+
+	* win/configure.in:
+	* win/Makefile.in: Windows build now handles static/dynamic
+	debug/nodebug builds and supports the standard targets using Cygwin
+	user tools plus GNU make and autoconf.
+
+1999-06-03  Scott Stanton  <stanton@scriptics.com>
+
+	* generic/tclCmdMZ.c (Tcl_StringObjCmd):
+	* tests/string.test: Fixed bug where string equal/compare -nocase
+	reported wrong result on null strings. [Bug 2138]
+
+1999-06-02  Scott Stanton  <stanton@scriptics.com>
+
+	* generic/tclUtf.c (Tcl_UtfNcasecmp): Fixed incorrect computation of
+	relative ordering. [Bug 2135]
+
+1999-06-01  Scott Stanton  <stanton@scriptics.com>
+
+	* unix/configure.in: Fixed various small configure.in patches
+	submitted by Jan Nijtmans. [Bug 2121]
+
+	* tests/reg.test:
+	* generic/regc_color.c:
+	* generic/regc_cvec.c:
+	* generic/regc_lex.c:
+	* generic/regc_locale.c:
+	* generic/regc_nfa.c:
+	* generic/regcomp.c:
+	* generic/regcustom.h:
+	* generic/rege_dfa.c:
+	* generic/regerror.c:
+	* generic/regerrs.h:
+	* generic/regex.h:
+	* generic/regexec.c:
+	* generic/regfree.c:
+	* generic/regfronts.c:
+	* generic/regguts.h:
+	* generic/tclCmdMZ.c:
+	* generic/tclRegexp.c:
+	* generic/tclRegexp.h:
+	* generic/tclTest.c: Applied Henry Spencer's latest regexp patches
+	that fix an infinite loop bug and add support for testing whether a
+	string could match with additional input. [Bug 2117]
+
+1999-05-28  Scott Stanton  <stanton@scriptics.com>
+
+	* generic/tclObj.c: Changed to eliminate use of isupper/tolower in
+	favor of the Unicode versions.
+
+	* win/Makefile.in:
+	* win/configure.in: Added preliminary TEA implementation.
+
+	* win/tclWinDde.c: Fixed bug where dde calls were being passed an
+	invalid dde handle because Initialize had not been called. [Bug 2124]
+
+1999-05-26  Scott Redman  <redman@scriptic.com>
+
+	* generic/tclThreadTest.c: Fixed race condition in testthread code
+	that showed up in the WinNT test suite intermittently.
+
+	* win/tclWinSock.c: Fixed a hang in the WinNT socket driver, wake up
+	the socket thread every 100ms to check for events on the sockets that
+	did not wake up the thread (race condition).
+
+1999-05-24  Scott Stanton  <stanton@scriptics.com>
+
+	* tools/genStubs.tcl: Changed to allow a list of platforms instead of
+	just one at a time.
+
+	* generic/tcl.decls:
+	* generic/tclCmdMZ.c:
+	* generic/tclDecls.h:
+	* generic/tclInt.decls:
+	* generic/tclIntDecls.h:
+	* generic/tclPort.h:
+	* generic/tclStubInit.c:
+	* generic/tclStubLib.c: Various header file related changes and other
+	lint to try to get the Mac builds working.
+
+1999-05-21  Scott Redman  <redman@scriptics.com>
+
+	* win/tclWinPipe.c: Fix bug when launching command.com on Win95/98.
+	Need to wait for the procInfo.hProcess of the process that was
+	created, not the hProcess of the current process. [Bug 2105]
+
+1999-05-20  Scott Redman  <redman@scriptics.com>
+
+	* library/init.tcl: Add the directory where the executable is, and the
+	../lib directory relative to that, to the auto_path variable.
+
+1999-05-19  Scott Stanton  <stanton@scriptics.com>
+
+	Merged in various changes submitted by Jeff Hobbs:
+
+	* generic/tcl.decls:
+	* generic/tclUtf.c: Added Tcl_UniCharIs* functions for control, graph,
+	print, and punct classes.
+
+	* generic/tclUtil.c:
+	* doc/StrMatch.3: Added Tcl_StringCaseMatch() implementation to
+	support case-insensitive globbing.
+
+	* doc/string.n:
+	* unix/mkLinks:
+	* tests/string.test:
+	* generic/tclCmdMZ.c: Added additional character class tests, added
+	-nocase switch to "string match", changed string first/last to use
+	offsets.
+
+1999-05-19  Scott Redman  <redman@scriptics.com>
+
+	* generic/tcl.h: Add extern "C" block around entire header file for
+	C++ compilers to fix linkage issues. Submitted by Don Porter and Paul
+	Duffin.
+
+	* generic/tclRegexp.c: Fix bug when the regexp cache is empty and an
+	empty pattern is used in regexp ( such as {} or "" ).
+
+1999-05-18  Scott Stanton  <stanton@scriptics.com>
+
+	* win/tclWinChan.c: Modified initialization code to avoid inherenting
+	closed or invalid channels. If the standard input is anything other
+	than a console, file, serial port, or pipe, then we fall back to the
+	standard Tk window console.
+
+1999-05-14  Scott Stanton  <stanton@scriptics.com>
+
+	* generic/tclCmdAH.c (Tcl_ForObjCmd): Fixed crash caused by failure to
+	reset the result before evaluating the test expression.
+
+1999-05-14  Bryan Surles  <surles@scriptics.com>
+
+	* generic/tclBasic.c (Tcl_CreateInterp): Added introspection variable
+	for threaded interps. If the interp was compiled with threads enabled,
+	the tcl_platform(threaded) variable will exist.
+
+1999-05-14  Scott Redman  <redman@scriptics.com>
+
+	* generic/tclDate.c: Applied patch to fix 100-year and 400-year
+	boundaries in leap year code, from Isaac Hollander. [Bug 2066]
+
+1999-05-13  Scott Stanton  <stanton@scriptics.com>
+
+	* unix/Makefile.in:
+	* unix/tclAppInit.c: Minor cleanup related to Xt notifier.
+
+	* unix/tclUnixInit.c (TclpSetInitialEncodings): Tcl now looks for an
+	encoding subfield in the LANG/LC_ALL variables in cases where the
+	locale is not found in the locale table. Ensure that setlocale() is
+	called at least once so X11 will initialize properly. Also, forces the
+	LC_NUMERIC locale to be "C" so numeric processing in scripts is not
+	affected by the current locale setting. [Bug 1989]
+
+	* generic/tclRegexp.c: Increased per-thread regexp cache to 30 slots.
+	This seems to be about the right number for larger applications like
+	exmh. [Bug 1063]
+
+1999-05-12  Scott Stanton  <stanton@scriptics.com>
+
+	* doc/tclsh.1: Updated references to rc script names to accurately
+	reflect the platform differences on Windows.
+
+	* tests/regexp.test:
+	* generic/tclInt.h:
+	* generic/tclBasic.c:
+	* generic/tclRegexp.h:
+	* generic/tclRegexp.c: Replaced the per-interpreter regexp cache with
+	a per-thread cache. Changed the Regexp object to take advantage of
+	this extra cache. Added a reference count to the TclRegexp type so
+	regexps can be shared by multiple objects. Removed the per-interp
+	regexp cache from the interpreter. Now regexps can be used with no
+	need for an interpreter. [Bug 1063]
+
+	* win/tclWinInit.c (TclpSetVariables): Avoid calling GetUserName if
+	the value can be determined from the USERNAME environment variable.
+	GetUserName is very slow.
+
+1999-05-07  Scott Stanton  <stanton@scriptics.com>
+
+	* win/winDumpExts.c:
+	* win/makefile.vc: Removed incorrect patch. [Bug 1998]
+
+	* generic/tcl.decls: Replaced const with CONST.
+
+	* generic/tclResult.c (Tcl_AppendResultVA):
+	* generic/tclStringObj.c (Tcl_AppendStringsToObjVA): Fixed to copy
+	arglist using memcpy instead of assignment so it works properly on
+	OS/390. [Bug 1997]
+
+	* generic/tclLoadNone.c: Updated to use current interfaces, added
+	TclpUnloadFile. [Bug 2003]
+
+	* win/winDumpExts.c:
+	* win/makefile.vc: Changed to emit library name in defs file. [Bug
+	1998]
+
+	* unix/configure.in: Added fix for OS/390. [Bug 1976]
+
+1999-05-06  Scott Stanton  <stanton@scriptics.com>
+
+	* tests/string.test:
+	* generic/tclCmdMZ.c:
+	* doc/string.n: Fixed bug in string equal/compare code when using
+	-length option. Cleaned up docs a bit more.
+
+	* tests/http.test: Unset "data" array before running tests to avoid
+	failures due to previous tests.
+
+	* doc/string.n:
+	* tests/cmdIL.test:
+	* tests/cmdMZ.test:
+	* tests/error.test:
+	* tests/ioCmd.test:
+	* tests/lindex.test:
+	* tests/linsert.test:
+	* tests/lrange.test:
+	* tests/lreplace.test:
+	* tests/string.test:
+	* tests/cmdIL.test:
+	* generic/tclUtil.c:
+	* generic/tclCmdMZ.c: Replaced "string icompare/iequal" with -nocase
+	and -length switches to "string compare/equal". Added a -nocase option
+	to "string map". Changed index syntax to allow integer or
+	end?-integer? instead of a full expression. This is much simpler with
+	safeTcl scripts since it avoids double substitution issues.
+
+	* doc/Utf.3:
+	* generic/tclStubInit.c:
+	* generic/tclDecls.h:
+	* generic/tclUtf.c:
+	* generic/tcl.decls: Added Tcl_UtfNcmp and Tcl_UtfNcasecmp.
+
+1999-05-05  Scott Stanton  <stanton@scriptics.com>
+
+	* win/makefile.vc: Added encoding directory to install-libraries
+	target.
+
+1999-05-03  Scott Stanton  <stanton@scriptics.com>
+
+	* doc/string.n:
+	* tests/cmdMZ.test:
+	* tests/string.test:
+	* generic/tclCmdMZ.c (Tcl_StringObjCmd): Changed "string length" to
+	avoid regenerating the string rep of a ByteArray object.
+
+	* tests/cmdIL.test:
+	* tests/cmdMZ.test:
+	* tests/error.test:
+	* tests/lindex.test:
+	* tests/linsert.test:
+	* tests/lrange.test:
+	* tests/lreplace.test:
+	* tests/string.test:
+	* generic/tclCmdMZ.c (Tcl_StringObjCmd):
+	* generic/tclUtil.c (TclGetIntForIndex): Applied Jeff Hobbs's string
+	patch which includes the following changes [Bug 1845]:
+	- string compare now takes optional length arg (for strncmp behavior)
+	- added string equal (just a few lines of code blended in with string
+	  compare)
+	- added string icompare/iequal for case-insensitive comparisons
+	- string index's index can now be ?end[+-]?expression
+	  I made this change in the private TclGetIntForIndex, which means
+	  that the list commands also benefit, as well as string range, et al.
+	- added [string repeat string count]
+	  Repeats given string number of times
+	- added string replace, string equiv to lreplace
+	  (quasi opposite of string range):
+		string replace first last ?string?
+	  Example of use, replacing end of string with ... should the string
+	  be more than 16 chars long:
+		string replace $string 16 end "..."
+	  This just returns the string len < 16, so it will only affect the
+	  long strings.
+	- added optional first and last args to string to*
+	  This allows you to just affect certain regions of a string with the
+	  command (like just capping the first letter). I found the original
+	  totitle to be too draconian to be useful.
+	- added [string map charMap string]
+	  where charMap is a {from to from to} list that equates to what one
+	  might get from [array get]. Each and can be multiple chars (or none
+	  at all). For Tcl/CGI users, this is a MAJOR speed booster.
+
+	* generic/tclParse.c (Tcl_ParseCommand): Changed to avoid modifying
+	eval'ed strings that are already null terminated. [Bug 1793]
+
+	* tests/binary.test:
+	* generic/tclBinary.c (DupByteArrayInternalRep): Fixed bug where type
+	was not being set in duplicated object. [Bug 1975, 2047]
+
+1999-04-30  Scott Stanton  <stanton@scriptics.com>
+
+	* Changed version to 8.1.1.
+
+1999-04-30  Scott Stanton  <stanton@scriptics.com>
+
+	* Merged changes from 8.1.0 branch:
+
+	* generic/tclParse.c: Fixed memory leak in CommandComplete.
+
+	* generic/tclPlatDecls.h:
+	* generic/tclIntPlatDecls.h:
+	* generic/tclIntDecls.h:
+	* generic/tclDecls.h:
+	* tools/genStubs.tcl: Added 'extern "C" {}' block around the stub
+	table pointer declaration so the stub library can be used from C++.
+	[Bug 1934]
+
+	* Lots of documentation and other release engineering fixes.
+
+1999-04-28  Scott Stanton  <stanton@scriptics.com>
+
+	* mac/tclMacResource.c:
+	* generic/tclListObj.c:
+	* generic/tclObj.c:
+	* generic/tclStringObj.c: Changed to avoid freeing the string
+	representation before freeing the internal rep. This helps with
+	debugging since the string rep will still be valid when the free proc
+	is invoked.
+
+1999-04-27  Scott Stanton  <stanton@scriptics.com>
+
+	* generic/tclLiteral.c (TclHideLiteral): Fixed so hidden literals get
+	duplicated to avoid accidental sharing in the global object table.
+
+1999-04-23  Scott Stanton  <stanton@scriptics.com>
+
+	* generic/tclStubInit.c:
+	* tools/genStubs.tcl: Changed to avoid the need for forward
+	declarations in stub initializers.
+
+1999-04-23  Scott Stanton  <stanton@scriptics.com>
+
+	* library/encoding/koi8-r.enc:
+	* tools/encoding/koi8-r.txt: Added support for the koi8-r Cyrillic
+	encoding. [Bug 1771]
+
+1999-04-22  Scott Stanton  <stanton@scriptics.com>
+
+	* win/tclWinFCmd.c:
+	* win/tclWin32Dll.c: Changed uses of "try" to "__try", since that is
+	the actual keyword. This eliminates the need for some -D flags from
+	the makefile.
+
+	* generic/tclPort.h: Added include of tcl.h since it defines various
+	Windows macros that are needed before deciding which platform porting
+	file to use.
+
+	* generic/tclEvent.c: lint
+
+	* win/tclWinInit.c (TclpInitPlatform): Added call to TclWinInit when
+	building a static library since DllMain will not be invoked. This
+	could break old code that explicitly called TclWinInit, but should be
+	simpler in the long run.
+
+1999-04-22  Scott Stanton  <stanton@scriptics.com>
+
+	* generic/tclInt.h:
+	* generic/tclInt.decls:
+	* generic/tclCompile.c: Added TclSetByteCodeFromAny that takes a hook
+	procedure to invoke after compilation but before the byte codes are
+	emitted. This makes it possible to do postprocessing on the compiled
+	byte codes before the ByteCode is generated.
+
+	* generic/tclLiteral.c: Added TclHideLiteral and TclAddLiteralObj to
+	make it possible to create local unshared literal objects.
+
+	* win/tclWinInit.c:
+	* unix/tclUnixInit.c: Changed initial search path to match that
+	found used by tcl_findLibrary.
+
+1999-04-22  Scott Redman  <redman@scriptics.com>
+
+	* win/tclWinPort.h:
+	* win/tclWinSock.c: Added code to use WinSock 2.0 API on NT to avoid
+	creating a window to handle sockets. API not available on Win95 and
+	needs to be fixed on Win98, until then continue to use the older
+	(window-based) scheme on those two OSes.
+
+1999-04-15  Scott Stanton  <stanton@scriptics.com>
+
+	* Merged 8.1 back into the main trunk
+
+1999-04-13  Scott Stanton  <stanton@scriptics.com>
+
+	* library/encoding/gb2312.enc:
+	* library/encoding/euc-cn.enc:
+	* tools/encoding/gb2312.txt:
+	* tools/encoding/cp950.txt:
+	* tools/encoding/Makefile: Restored the double byte definition of
+	GB2312 and added the EUC-CN encoding. EUC-CN is a variant of GB2312
+	that shifts the characters into bytes with the high bit set and
+	includes ASCII as a subset. [Bug 632]
+
+1999-04-13  Scott Redman  <redman@scriptics.com>
+
+	* win/tclWinSock.c: Apply patch to allow write access to a socket if
+	FD_WRITE is sent but FD_CONNECT is not. Some strange problem with
+	either Win32 or a socket driver. [Bug 1664 1776]
+
+1999-04-09  Scott Redman  <redman@scriptics.com>
+
+	* unix/tclUnixNotfy.c: Fixed notifier deadlock situation when the pipe
+	used to talk back notifier thread is filled with data. When calling
+	the write() function to feed data down that pipe, unlock the
+	notifierMutex to allow the notifier to wake up again. Found as a
+	result of the focus.test for Tk hanging. [Bug 1700]
+
+1999-04-06  Scott Stanton  <stanton@scriptics.com>
+
+	* tests/unixNotfy.test: Fixed hang in tests when built with thread
+	support.
+
+	* tests/httpold.test: Fixed broken test that didn't wait long enough
+	for events to arrive.
+
+	* tests/unixInit.test: Fixed race condition in test.
+
+	* tests/unixInit.test:
+	* tests/fileName.test: Minor test nits.
+
+	* unix/tclUnixInit.c (TclpSetInitialEncodings): Fixed bad initial
+	encoding string.
+
+1999-04-06  Bryan Surles  <surles@scriptics.com>
+
+	* generic/tclVar.c:
+	* generic/tclEnv.c: Moved the "array set" C level code into a common
+	routine (TclArraySet). The TclSetupEnv routine now uses this API to
+	create an env array w/ no elements.
+
+	* generic/tclEnv.c:
+	* generic/tclWinInit.h:
+	* generic/tclUnixInit.h:
+	* generic/tclInt.h: Made the Env module I18N compliant. Changed the
+	FindVariable routine to TclpFindVariable, that now does a case
+	insensitive string comparison on Windows, and not on UNIX. [Bug 1299,
+	1500]
+
+1999-04-05  Scott Stanton  <stanton@scriptics.com>
+
+	* tests/io.test: Minor test cleanup.
+
+	* generic/tclEncoding.c (Tcl_CreateEncoding): Minor lint to make it
+	easier to compile on Digital-unix. [Bug 1659]
+
+	* unix/configure.in:
+	* unix/tclUnixPort.h: Applied patch for OS/390 to handle lack of
+	sys/param.h. [Bug 1725]
+
+	* unix/configure.in: Fixed BSD/OS 4.* configuration to support shared
+	libraries properly. [Bug 1730]
+
+1999-04-05  Scott Redman  <redman@scriptics.com>
+
+	* win/tclWinDde.c: decrease timeout value for DDE calls to 30k. [Bug
+	1639]
+
+	* generic/tcl.decls:
+	* generic/tcl.h:
+	* generic/tclDecls.h:
+	* generic/tclInt.decls:
+	* generic/tclInt.h:
+	* generic/tclIntDecls.h:
+	* generic/tclStubInit.c:
+	* generic/tclUtil.c: Added more functions to the Tcl stubs table,
+	including all Tcl_ functions not already in it (except Cmd functions)
+	and Tcl_GetCwd() and Tcl_Chdir() (new functions).
+
+	* tests/safe.test:
+	* doc/safe.n:
+	* generic/tclBasic.c:
+	* library/safe.tcl: The encoding command is not safe as-is, so create
+	a safe alias to mask out the "encoding system <name>" but allow all
+	other uses including "encoding system". Added test cases and updated
+	the man page for Safe Tcl.
+
+1999-04-05  Scott Stanton  <stanton@scriptics.com>
+
+	* tests/winTime.test:
+	* win/tclWinTime.c: Fixed crash in clock command that occurred when
+	manipulating negative time values in timezones east of GMT. [Bug
+	1142, 1458]
+
+	* tests/platform.test:
+	* tests/fileName.test: Fixed broken tests.
+
+	* generic/tclFileName.c: Moved global regexps into thread local
+	storage.
+
+	* tests/socket.test: Changed so tests don't reuse sockets, since
+	Windows is slow to release sockets.
+
+	* win/tclWinConsole.c:
+	* win/tclWinPipe.c:
+	* win/tclWinSerial.c: Fixed race condition where background threads
+	were terminated while they still held a lock in the notifier.
+
+1999-04-02  Scott Stanton  <stanton@scriptics.com>
+
+	* tests/http.test: Fixed bad test initialization code.
+
+	* generic/tclThreadTest.c (ThreadExitProc): Fixed bug where static
+	memory was being returned instead of a dynamically allocated result in
+	error cases.
+
+1999-04-02  Scott Redman  <redman@scriptics.com>
+
+	* doc/dde.n:
+	* tools/tcl.wse.in:
+	* win/makefile.vc:
+	* win/pkgIndex.tcl:
+	* win/tclWinDde.c: Add new DDE package, code removed from Tk now
+	separated into its own package. Changed DDE-based send code into "dde
+	eval" command. Can be loaded into tclsh (not just wish). Windows only.
+
+1999-04-02  Scott Stanton  <stanton@scriptics.com>
+
+	* tests/expr.test:
+	* tests/for-old.test:
+	* tests/for.test:
+	* tests/foreach.test:
+	* tests/format.test:
+	* tests/httpold.test:
+	* tests/if.test:
+	* tests/init.test:
+	* tests/interp.test:
+	* tests/while.test: Added some tests for known bugs (marked with
+	knownBug constraint), and cleaned up a few bad tests.
+
+	* generic/regc_locale.c:
+	* generic/regcustom.h:
+	* generic/tcl.decls:
+	* generic/tclCmdIL.c:
+	* generic/tclCmdMZ.c:
+	* generic/tclInt.h:
+	* generic/tclRegexp.c:
+	* generic/tclScan.c:
+	* generic/tclTest.c:
+	* generic/tclUtf.c:
+	* win/tclWinFCmd.c:
+	* win/tclWinFile.c: Made various Unicode utility functions public. The
+	following functions were made public and added to the stubs table:
+		Tcl_UtfToUniCharDString, Tcl_UniCharToUtfDString,
+		Tcl_UniCharLen, Tcl_UniCharNcmp, Tcl_UniCharIsAlnum,
+		Tcl_UniCharIsAlpha, Tcl_UniCharIsDigit, Tcl_UniCharIsLower,
+		Tcl_UniCharIsSpace, Tcl_UniCharIsUpper, Tcl_UniCharIsWordChar
+
+1999-04-01  Scott Stanton  <stanton@scriptics.com>
+
+	* tests/registry.test:
+	* win/tclWinReg.c: Internationalized the registry code. It now uses
+	Unicode interfaces on NT. [Bug 1197]
+
+	* tests/parse.test:
+	* generic/tclParse.c: Fixed crash due to multiple frees in parser
+	during error cleanup when parsing commands with more tokens than will
+	fit in the static area of the parse structure. [Bug 1681]
+
+	* generic/tclInt.h: Removed duplicate declarations.
+
+	* generic/tclInt.decls:
+	* generic/tcl.decls: Added Tcl_WinUtfToTChar and Tcl_WinTCharToUtf to
+	the tclPlat table.
+
+1999-04-01  Scott Redman  <redman@scriptics.com>
+
+	* generic/tcl.decls:
+	* generic/tcl.h:
+	* generic/tclBasic.c:
+	* generic/tclDecls.h:
+	* generic/StubInit.c:
+	* tools/genStubs.tcl:
+	* unix/Makefile.in:
+	* win/makefile.vc: Applied patch from Jan Nijtmans to fix Ultrix
+	multiple symbol definition problem. Now, even Tcl includes a copy of
+	the Tcl stub library. Also fixed TCL_MEM_DEBUG mode (for Tk).
+
+1999-03-31  Scott Redman  <redman@scriptics.com>
+
+	* win/tclWinConsole.c: WinNT has a bug when reading a single character
+	from the console. Rewrote the code for the console to read an entire
+	line at a time using the reader thread.
+
+1999-03-30  Scott Stanton  <stanton@scriptics.com>
+
+	* unix/Makefile.in: Removed trailing backslash that broke the "depend"
+	target.
+
+	* unix/tclUnixInit.c (TclpSetInitialEncodings): Changed to avoid
+	calling setlocale(). We now look directly at env(LANG) and
+	env(LC_CTYPE) instead. [Bug 1636]
+
+	* generic/tclFileName.c:
+	* generic/tclDecls.h:
+	* generic/tcl.decls: Removed CONST from Tcl_JoinPath and
+	Tcl_TranslateFileName because it changes the signature of Tcl_JoinPath
+	in an incompatible manner.
+
+	* generic/tclInt.h:
+	* generic/tclLoad.c (TclFinalizeLoad):
+	* generic/tclEvent.c (Tcl_Finalize): Defer unloading of loadable
+	modules until all exit handlers have been invoked. [Bug 998, 1273,
+	1573, 1593]
+
+1999-03-29  Scott Stanton  <stanton@scriptics.com>
+
+	* generic/tclFileName.c:
+	* generic/tclDecls.h:
+	* generic/tcl.decls: Added CONST to Tcl_JoinPath and
+	Tcl_TranslateFileName.
+
+1999-03-29  Scott Redman  <redman@scriptics.com>
+
+	* tools/genStubs.tcl:
+	* unix/configure.in:
+	* unix/Makefile.in:
+	* win/makefile.vc:
+	* generic/tcl.h:
+	* generic/tclBasic.c:
+	* generic/tclDecls.h:
+	* generic/tclIntDecls.h:
+	* generic/tclPlatDecls.h:
+	* generic/tclIntPlatDecls.h: Removed the stub functions and changed
+	the stub macros to just use the name without params. Pass &tclStubs
+	into the interp (don't use tclStubsPtr because of collisions with the
+	stubs on Solaris).
+
+1999-03-27  Scott Redman  <redman@scriptics.com>
+
+	* win/makefile.bc: Removed makefile for Borland compiler, no longer
+	supported.
+
+1999-03-26  Scott Redman  <redman@scriptics.com>
+
+	* win/tclWinSerial.c:
+	* win/tclWinConsole.c:
+	* win/tclWinPipe.c: Don't close the Win32 handle for a channel if it's
+	a stdio handle (GetStdHandle()) during shutdown of a thread to prevent
+	it from destroying the stdio of other threads.
+
+1999-03-26  Suresh Ankolekar  <suresh@scriptics.com>
+
+	* unix/configure.in: --nameble-shared is now the default and build Tcl
+	as a shared library; specify --disable-shared to build a static Tcl
+	library and shell.
+
+1999-03-25  Scott Stanton  <stanton@scriptics.com>
+
+	* tests/interp.test:
+	* generic/tclInterp.c (AliasObjCmd): Changed so aliases are invoked at
+	current scope in the target interpreter instead of at the global
+	scope. This was an incompatibility introduced in 8.1 that is being
+	removed. [Bug 1153, 1556]
+
+	* library/encoding/big5.enc:
+	* library/encoding/gb2312.enc:
+	* tools/encoding/big5.enc:
+	* tools/encoding/gb2312.enc: Added ASCII to big5 and gb2312 encodings.
+	[Bug 632]
+
+	* generic/tclPkg.c (Tcl_PkgRequireEx): Fixed broken clientData
+	initialization in package code.
+
+	* unix/Makefile.in (dist): Added tcl.decls and tclInt.decls to source
+	distribution. [Bug 1571]
+
+	* doc/Thread.3: Updated documentation of Tcl_MutexLock to indicate
+	that the recursive locking behavior is undefined. On Windows, it does
+	not block, on Unix it deadlocks. [Bug 1275]
+
+1999-03-24  Scott Stanton  <stanton@scriptics.com>
+
+	* tests/execute.test:
+	* generic/tclExecute.c (TclExecuteByteCode): Fixed expression code
+	that incorrectly returned floating point values for integers if the
+	internal rep happened to be a double. Now we check to see if the
+	object has a string rep that looks like an integer before using the
+	double internal rep. [Bug 1516]
+
+1999-03-24  Scott Redman  <redman@scriptics.com>
+
+	* generic/tclAlloc.c:
+	* generic/tclEncoding.c:
+	* generic/tclProc.c:
+	* unix/tclUnixTime.c:
+	* win/tclWinSerial.c: Fixed compilation warnings/errors for VC++ 5.0
+	and 6.0 and HP-UX native compiler without -Aa or -Ae. [Bug 1323 1518
+	1324 1583 1585 1586]
+
+	* win/tclWinSock.c: Make sockets thread-safe on Windows. The current
+	implementation uses windows to handle events on the socket, one for
+	each thread (thread local storage). Previously, there was only one
+	window shared between threads, which didn't work. [Bug 1326]
+
+1999-03-23  Scott Stanton  <stanton@scriptics.com>
+
+	* tools/tcl.wse: Fixed file association to look in the right place for
+	the wish icon. [Bug 1544]
+
+	* tests/winNotify.test:
+	* tests/ioCmd.test:
+	* tests/event.test: Changed to use new style conditionals.
+
+	* tests/encoding.test: Fixed nonportable test.
+
+	* unix/dltest/configure.in:
+	* unix/dltest/Makefile.in: Added missing DBGX macros. [Bug 1564]
+
+	* tests/winNotify.test:
+	* mac/tclMacNotify.c:
+	* win/tclWinNotify.c:
+	* unix/tclUnixNotfy.c:
+	* generic/tclNotify.c: Added a new Tcl_ServiceModeHook interface that
+	is invoked whenever the service mode changes. This is needed to allow
+	the Windows notifier to create a communication window the first time
+	Tcl is about to enter an external modal event loop instead of at
+	startup time. This will avoid the various problems that people have
+	been seeing where the system hangs when tclsh is running outside of
+	the event loop. [Bug 783]
+
+	* generic/tclInt.h:
+	* generic/tcl.decls: Renamed TclpAlertNotifier back to
+	Tcl_AlertNotifier since it is part of the public notifier driver API.
+
+1999-03-23  Scott Redman  <redman@scriptics.com>
+
+	* win/tclWinSerial.c: Fixed problem with fileevent on the serial port
+	and nonblocking mode. Gets no longer hangs, fileevents fire whenever
+	there is any character data on the port.
+
+	* tests/winConsole.test:
+	* win/tclWinConsole.c: Fixed problem with fileevents and gets from a
+	console stdin. Previously, fileevents were firing before an entire
+	line was available for reading, which meant that when you did a gets
+	or read, it blocked (even in nonblocking mode). Now, it should work
+	the same as Unix: fileevents fire when an entire line is ready, and
+	gets and read do not block in non-blocking mode. Added an interactive
+	test case to check for this.
+
+1999-03-22  Scott Stanton  <stanton@scriptics.com>
+
+	* tests/reg.test:
+	* generic/regc_color.c: Applied regexp bug fix from Henry Spencer.
+
+1999-03-19  Scott Redman  <redman@scriptics.com>
+
+	* generic/tclCmdIL.c: Fixed the initialization of an array so that the
+	Sun 5.0 C compiler wouldn't complain.
+
+	* unix/configure.in: Added support for --enable-64bit. For now, this
+	is only supported on Solaris 7 64bit (SunOS 5.7) using the Sun
+	compiler (not gcc).
+
+1999-03-18  Scott Stanton  <stanton@scriptics.com>
+
+	* win/tclWinChan.c (TclpOpenFileChannel, Tcl_MakeFileChannel): Changed
+	to only test for console or comm handles when the type is
+	FILE_TYPE_CHAR to avoid useless tests on simple files. Also reordered
+	tests so consoles are tested first as this is more common.
+
+	* win/makefile.vc: Regularized usage of mkd and rmd and rm.
+
+	* library/encoding/shiftjis.enc:
+	* tools/encoding/shiftjis.txt: Missing/incorrect characters in
+	shift-jis table. [Bug 1008, 1526]
+
+	* generic/tclInt.decls:
+	* generic/tcl.decls: Eliminated use of "string" and "list" from
+	argument lists to avoid conflicts with C++ STL. [Bug 1181]
+
+	* win/tclWinFile.c (TclpMatchFiles): Changed to ignore the
+	FS_CASE_IS_PRESERVED bit and always return exactly what we get from
+	the system.
+
+1999-03-17  Scott Stanton  <stanton@GASPODE>
+
+	* win/README.binary:
+	* win/README:
+	* unix/configure.in:
+	* generic/tcl.h:
+	* README: Updated version to 8.1b3.
+
+1999-03-14  Scott Stanton  <stanton@GASPODE>
+
+	* win/tclWinConsole.c:
+	* win/tclWinPipe.c:
+	* win/tclWinSerial.c: Changed so channel drivers wait for the
+	reader/writer threads to exit before returning during a close
+	operation. This ensures that the main thread is the last thread to
+	exit, so the process return value is set properly.
+
+	* generic/tclIntDecls.h:
+	* generic/tclIntPlatDecls.h:
+	* generic/tclIntPlatStubs.c:
+	* generic/tclIntStubs.c:
+	* generic/tclPlatDecls.h:
+	* generic/tclPlatStubs.c:
+	* generic/tclStubInit.c:
+	* generic/tclStubs.c: Fixed bad eol characters.
+
+	* generic/tclInt.decls: Changed "const" to "CONST" in declarations for
+	better portability.
+
+	* generic/tcl.decls: Renamed panic and panicVA to Tcl_Panic and
+	Tcl_PanicVA in the stub files.
+
+	* generic/tclInterp.c (Tcl_MakeSafe): Remove tcl_platform(user) from
+	safe interps.
+
+1999-03-11  Scott Stanton  <stanton@GASPODE>
+
+	* unix/Makefile.in:
+	* unix/configure.in: Include compat files in the stub library in
+	addition to the main library. Compat files are now built for dynamic
+	use in all cases.
+
+	* generic/tcl.h: Changed magic number so it doesn't match the plus
+	patch, at Jan's request.
+
+	* unix/tclConfig.sh.in:
+	* unix/dltest/Makefile.in:
+	* unix/dltest/configure.in:
+	* unix/dltest/pkga.c:
+	* unix/dltest/pkgb.c:
+	* unix/dltest/pkgc.c:
+	* unix/dltest/pkgd.c:
+	* unix/dltest/pkge.c:
+	* unix/dltest/pkgf.c: Changed package tests to build against the stubs
+	library.
+
+1999-03-10  Scott Stanton  <stanton@GASPODE>
+
+	* generic/tcl.h:
+	* generic/tcl.decls: Changed Tcl_ReleaseType from an enum to macros so
+	it can be used in .rc files. Added Tcl_GetString.
+
+	* mac/tclMacNotify.c:
+	* generic/tclNotify.c:
+	* generic/tclInt.h:
+	* win/tclWinNotify.c:
+	* generic/tcl.h: Renamed Tcl_AlertNotifier to TclpAlertNotifier.
+
+	* generic/tclInt.decls: Added TclWinAddProcess to make it possible for
+	expect to use Tcl_WaitForPid(). This patch is from Gordon Chaffee.
+
+	* mac/tclMacPort.h:
+	* win/tclWinInit.c:
+	* unix/tclUnixPort.h:
+	* generic/tclAsync.c: Added TclpAsyncMark to fix bug in async handling
+	on Windows where async events don't wake up the event loop. This patch
+	comes from Gordon Chaffee.
+
+	* generic/tcl.decls: Fixed declarations of reserved slots.
+
+1999-03-10  Scott Redman  <redman@scriptic.com>
+
+	* generic/tclCompile.h: Ensure that the ByteCode struct is binary
+	compatible with the version in 8.0.6.
+
+	* generic/tcl.h:
+	* generic/tclBasic.c: Add Tcl_GetVersion() function to the public C
+	API to allow programs to check the version number of the Tcl library
+	at runtime. Also added an enum to clarify the release level (alpha,
+	beta, final).
+
+1999-03-09  Scott Stanton  <stanton@GASPODE>
+
+	* Integrated changes from Tcl 8.0 including:
+		stubs mechanism
+		configure patches from Jan Nijtmans
+		rename of panic to Tcl_Panic
+
+1999-03-08  Lee Bernhard  <lfb@scriptics.com>
+
+	* win/tclWin32Dll.c: Removed Dll instance from thread-local storage.
+
+1999-03-08  Scott Stanton  <stanton@GASPODE>
+
+	* generic/tcl.h: Moved Tcl_Mutex, etc. macros above the inclusion of
+	tclDecls.h to avoid macro conflicts.
+
+	* generic/tclInt.h:
+	* generic/regc_color.c:
+	* generic/regcomp.c:
+	* generic/tclCmdIL.c:
+	* generic/tclCmdAH.c:
+	* generic/tclIOCmd.c:
+	* generic/tclParse.c:
+	* generic/tclStringObj.c:
+	* unix/tclUnixNotfy.c: Cleaned up various compiler warnings,
+	eliminated UCHAR bugs.
+
+	* unix/tclUnixNotfy.c:
+	* unix/tclUnixThrd.c:
+	* generic/tclThreadTest.c:
+	* mac/tclMacThrd.c: Changed TclpCondition*() to Tcl_Condition*().
+
+	* INTEGRATED PATCHES FROM 8.0.6:
+
+	* generic/tcl.decls:
+	* generic/tcl.h:
+	* generic/tclBasic.c:
+	* generic/tclDecls.h:
+	* generic/tclInt.decls:
+	* generic/tclInt.h:
+	* generic/tclIntDecls.h:
+	* generic/tclIntPlatDecls.h:
+	* generic/tclIntPlatStubs.c:
+	* generic/tclIntStubs.c:
+	* generic/tclPlatDecls.h:
+	* generic/tclPlatStubs.c:
+	* generic/tclStubInit.c:
+	* generic/tclStubLib.c:
+	* generic/tclStubs.c:
+	* tools/genStubs.tcl:
+	* unix/configure.in:
+	* unix/Makefile.in:
+	* unix/tclConfig.sh.in:
+	* win/makefile.vc:
+	* win/tclWinPort.h: Added Tcl stubs implementation. There are now two
+	new macros USE_TCL_STUBS and USE_TCL_STUB_PROCS that enable use of
+	stubs and disable stub macros respectively. All of the public and
+	private function declarations from tcl.h and tclInt.h have moved into
+	the *.decls files and the *Stubs.c and *Decls.h files are generated
+	using the genStubs.tcl script.
+
+	* unix/Makefile.in:
+	* unix/configure.in:
+	* unix/ldAix: Enhanced AIX shared library support.
+
+	* win/tclWinSock.c: Removed a bunch of extraneous PASCAL FAR
+	attributes from internal functions.
+
+	* win/tclWinReg.c: Changed registry package to use stubs mechanism so
+	it no longer depends on the specific version of Tcl.
+
+	* doc/AddErrInfo.3:
+	* doc/Eval.3:
+	* doc/PkgRequire.3:
+	* doc/SetResult.3:
+	* doc/StringObj.3:
+	* generic/tcl.h:
+	* generic/tclBasic.c:
+	* generic/tclPanic.c:
+	* generic/tclStringObj.c:
+	* generic/tclUtil.c:
+	* unix/mkLinks: Added va_list versions of all VARARGS functions so
+	they can be invoked from the stub functions.
+
+	* doc/package.n:
+	* doc/PkgRequire.3:
+	* generic/tclPkg.c: Added Tcl_PkgProvideEx, Tcl_RequireEx,
+	Tcl_PresentEx, and Tcl_PkgPresent. Added "package present" command.
+
+	* generic/tclFileName.c:
+	* mac/tclMacFile.c:
+	* mac/tclMacShLib.exp:
+	* unix/tclUnixFile.c:
+	* win/tclWinFile.c: Changed so TclGetUserHome is defined on all
+	platforms, even though it is currently a noop on mac and windows, and
+	renamed it to TclpGetUserHome.
+
+	* generic/tclPanic.c:
+	* generic/panic.c: Renamed panic to Tcl_Panic.
+
+1999-02-25  Scott Redman  <redman@scriptics.com>
+
+	* win/makefile.vc: Added tclWinConsole.c and tclWinSerial.c
+
+	* win/tclWinConsole.c: New code to properly deal with fileevents and
+	nonblocking mode on consoles.
+
+	* win/tclWinSerial.c: New code to properly deal with fileevents and
+	nonblocking mode on serial ports.
+
+	* win/tclWinPipe.c:
+	* win/tclWinPort.h: Exported functions to allow creation of pipe
+	channels from tclWinChan.c
+
+	* win/tclWinChan.c: Check the type of a channel, including for the
+	standard (stdin/stdout/stderr), and use the correct channel type to
+	create the channel (file, serial, console, or pipe).
+
+1999-02-11  Scott Stanton  <stanton@GASPODE>
+
+	* README:
+	* generic/tcl.h:
+	* win/README.binary:
+	* win/README:
+	* unix/configure.in:
+	* mac/README: Updated version numbers to 8.1b2.
+
+1999-02-10  Scott Stanton  <stanton@GASPODE>
+
+	* library/auto.tcl: Fixed auto_mkindex so it handles .tbc files. Did
+	some general cleanup to handle bad eval statements that didn't use
+	"list".
+
+	* unix/mkLinks:
+	* doc/SetVar.3:
+	* generic/tcl.h:
+	* generic/tclVar.c: Restored Tcl_ObjGetVar2 and Tcl_ObjSetVar2 from
+	8.0. Renamed Tcl_Get/SetObjVar2 to Tcl_GetVar2Ex and Tcl_SetVar2Ex.
+
+1999-02-10  Scott Stanton  <stanton@GASPODE>
+
+	INTEGRATED PATCHES FROM 8.0.5b2:
+
+	* test/winPipe.test: Changed to remove echoArgs.tcl temporary file
+	when done.
+
+	* tests/cmdAH.test:
+	* generic/tclFileName.c (TclGetExtension): Changed behavior so the
+	split happens at the last period in the name instead of the first
+	period of the last run of periods. So, "foo..o" is split into "foo."
+	and ".o" now. [Bug 1126]
+
+	* win/makefile.vc: Added better support for paths with spaces in the
+	name. Added .lib and support .dlls to the install-binaries target.
+	Added generate of a pkgIndex.tcl script to the install-libraries
+	target.
+
+	* win/tclAppInit.c:
+	* unix/tclAppInit.c:
+	* mac/tclMacAppInit.c:
+	* generic/tclTest.c: Changed some EXTERN declarations to extern since
+	they are not defining exported interfaces. This avoids generating
+	useless declspec() attributes and makes the windows makefile simpler.
+
+	* generic/tcl.h: Moved Tcl_AppInit declaration to end and cleared out
+	TCL_STORAGE_CLASS so it is not declared with a declspec().
+
+	* tests/interp.test:
+	* generic/tclInterp.c (DeleteAlias): Changed to use
+	Tcl_DeleteCommandFromToken so we handle renames properly. This avoids
+	senseless panic. [Bug 736]
+
+	* unix/tclUnixChan.c:
+	* win/tclWinSock.c:
+	* doc/socket.n: Applied Gordon Chaffee's patch to handle failures
+	during asynchronous socket connection operations. This adds a new
+	"-error" fconfgure option to socket channels. [Bug 893]
+
+	* generic/tclProc.c:
+	* generic/tclNamesp.c:
+	* generic/tclInt.h:
+	* generic/tclCmdIL.c:
+	* generic/tclBasic.c:
+	* generic/tclVar.c: Applied patch from Viktor Dukhovni to rationalize
+	TCL_LEAVE_ERR_MSG behavior when creating variables.
+
+	* generic/tclVar.c: Fixed bug in namespace tail computation. Fixed bug
+	where upvar could resurrect a namespace variable whose namespace had
+	been deleted.
+
+	* generic/tclCompile.c (TclCompileExprCmd): Eliminated yet another
+	bogus optimization in expression compilation.
+
+	* unix/configure.in: Added branch for BSD/OS-4* to shared library case
+	statement. [Bug 975]
+	Fixed to correctly handle IRIX 6.5 n32 library support. [Bug 1117]
+
+	* win/winDumpExts.c: Patched to be pickier about stripping @'s. [Bug
+	920]
+
+	* library/http2.0/http.tcl: Added catch around eof test in CopyDone
+	since the user may have already called http::reset. [Bug 1108]
+
+	* unix/configure.in: Changed Linux and IRIX to set SHLIB_LIBS to LIBS
+	so shared libraries are linked with the system libraries. [Bug 1018]
+
+	* generic/tclCompile.c (CompileExprWord): Fixed exception stack
+	overflow bug caused by missing statement. [Bug 928]
+
+	* generic/tclIOCmd.c:
+	* generic/tclBasic.c: Objectified the "open" command. [Bug 1113]
+
+	* generic/tclPosixStr.c (Tcl_ErrnoId, Tcl_ErrnoMsg): When using egcs,
+	ENOTSUP and EOPNOTSUPP are the same, so now we handle that case. [Bug
+	1137]
+
+	* library/init.tcl: Various small changes requested by Jan Nijtmans.
+	- If the variable $tcl_library contains the empty string, this empty
+	  string will be put in $auto_path. This is not useful at all, it only
+	  slows down later package processing.
+	- If the variable tcl_pkgPath is not set, the "unset __dir" fails.
+	  Thich makes init.tcl totally unusable. Better put a "catch" around
+	  it.
+	- In the function tcl_findLibraries, the "string match" function only
+	  works correctly if $tcl_patchLevel is in one of the forms "?.?a?",
+	  "?.?b?" or "?.?.?". Could a "regexp" be used instead, then it allows
+	  anything to be appended to the patchLevel string. And it is more
+	  efficient.
+	- The tclPkgSetup function assumes that if $type != "load" then the
+	  type must be "source". This needn't be true. Some users want to add
+	  their own setup types.
+	[RFE 1138] [Bug 978]
+
+	* win/tclWinReg.c:
+	* doc/registry.n: Added support for HKEY_PERFORMANCE_DATA and
+	HKEY_DYN_DATA keys. [Bug 1109]
+
+	* win/tclWinInit.c (TclPlatformInit): Added code to ensure tcl_pkgPath
+	is set to "" when no registry entry is found. [Bug 978]
+
+1999-02-01  Scott Stanton  <stanton@GASPODE>
+
+	* generic/tclBasic.c:
+	* generic/tclCmdAH.c:
+	* generic/tclCmdIL.c:
+	* generic/tclCmdMZ.c:
+	* generic/tclExecute.c:
+	* generic/tclHistory.c:
+	* generic/tclIO.c:
+	* generic/tclIOUtil.c:
+	* generic/tclInterp.c:
+	* generic/tclMain.c:
+	* generic/tclNamesp.c:
+	* generic/tclParse.c:
+	* generic/tclProc.c:
+	* generic/tclTest.c:
+	* generic/tclTimer.c:
+	* generic/tcl.h: Made eval interfaces compatible with 8.0 by renaming
+	Tcl_EvalObj to Tcl_EvalObjEx, renaming Tcl_Eval2 to Tcl_EvalEx and
+	restoring Tcl_EvalObj and Tcl_GlobalEvalObj interfaces so they match
+	Tcl 8.0.
+
+1999-01-28  Scott Stanton  <stanton@GASPODE>
+
+	* Merged Tcl 8.0.5b1 changes.
+
+	* generic/tclUtil.c (Tcl_DStringSetLength): Changed so the buffer
+	overallocates in a manner similar to Tcl_DStringAppend. This should
+	improve performance for TclUniCharToUtfDString.
+
+1998-12-11    === Tcl 8.1b1 Release ===
+
+1998-12-10  Scott Stanton  <stanton@GASPODE>
+
+	* Fixed lots of files that used TCL_THREAD instead of TCL_THREADS.
+
+	* generic/tclEncoding.c (Tcl_FreeEncoding): Moved most of the code
+	into a static FreeEncoding routine that does not grab the
+	encodingMutex to avoid deadlocks/races when called from other routines
+	that already have the mutex.
+
+1998-12-09  Scott Stanton  <stanton@GASPODE>
+
+	* library/msgcat1.0/msgcat.tcl: Fixed bad export list, fixed so all
+	locale strings are converted to lower case, including file names.
+
+	* generic/regcomp.c (makescan): Fixed bug in longest match case that
+	caused anchored patterns to fail. [Bug 897]
+
+1998-12-08  Scott Stanton  <stanton@GASPODE>
+
+	* library/msgcat1.0/msgcat.tcl: changed mc to invoke mcunknown in the
+	calling context, changed locale lookups to be case insensitive
+
+1998-12-07  Scott Stanton  <stanton@GASPODE>
+
+	* generic/tclAlloc.c (TclpRealloc): Fixed a memory allocation bug
+	where big blocks that were reallocated into a different heap location
+	were not being placed into the bigBlocks list. [Bug 933]
+
+	* tests/msgcat.test: Added message catalog test suite.
+
+	* library/msgcat1.0/msgcat.tcl: minor bug fixes, integrated latest
+	changes from Mark Harrison.
+
+1998-12-04  Scott Stanton  <stanton@GASPODE>
+
+	* library/msgcat1.0/msgcat.tcl: Changed code to conform to Tcl coding
+	standards. Changed to use file join for portability.
+
+	* library/msgcat1.0: Added initial implementaion of Tcl message
+	catalog package contributed by Mark Harrison.
+
+1998-12-03  Scott Stanton  <stanton@GASPODE>
+
+	* win/tclWinPipe.c (BuildCommandLine): Fixed bug that kept arguments
+	containing spaces from being properly quoted.
+
+	* tests/defs: Changed so auto_path is set to only contain the Tcl
+	library directory. This keeps the tests from accidentally picking up
+	stuff in installed packages.
+
+	* generic/tclUtil.c (Tcl_StringMatch): Changed to match 8.0 behavior
+	in corner case where there is no closing bracket.
+
+1998-12-02  Scott Stanton  <stanton@GASPODE>
+
+	* win/tclWinPipe.c (TclpCreateCommandChannel): Changed reader/writer
+	threads to have THREAD_PRIORITY_HIGHEST so they will have a chance to
+	run whenever there is something to do.
+
+	* generic/tclIO.c (WriteBytes, WriteChars): Fixed so extraneous
+	flushes do not happen in line mode.
+	(TranslateOutputEOL): Made translation more efficient in line mode and
+	fixed a buffer overflow bug in CRLF translation. [Bug 887]
+
+1998-12-02  Brent Welch  <welch@SAGE>
+
+	* Updated patchlevel to 8.1b1
+
+1998-12-02  Scott Stanton  <stanton@GASPODE>
+
+	* generic/regc_color.c (subcolor): Added check for error case to avoid
+	an out of bounds array reference.
+
+	* generic/tclCmdAH.c (Tcl_EncodingObjCmd): Changed to avoid using
+	Tcl_DStringResult because it is not binary clean.
+
+	* generic/tclParse.c (Tcl_ParseCommand): Fixed bug in comment parsing
+	where a trailing comment looked like an incomplete command.
+
+1998-12-02  Brent Welch  <welch@SAGE>
+
+	* Merged changes from 8.0.4, especially the new pkg_mkIndex
+
+1998-12-01  Scott Stanton  <stanton@GASPODE>
+
+	* generic/tclIO.c (Tcl_ReadChars): Added a call to UpdateInterest so
+	we don't block when there is data sitting in the buffers.
+
+	* generic/tclTest.c (TestevalobjvObjCmd): Updated for EvalObjv change.
+
+	* tests/parse.test: Updated tests for EvalObjv change.
+
+	* generic/tclParse.c (EvalObjv, Tcl_EvalObjv): Changed Tcl_EvalObjv
+	interface to remove string and length arguments, preserved original
+	interface as EvalObjv for internal use.
+
+	* generic/tcl.h: Changed Tcl_EvalObjv interface to remove string and
+	length arguments.
+
+	* doc/Eval.3: Updated documentation for Tcl_EvalObjv to remove string
+	and length arguments.
+
+	* generic/tclCompCmds.c (TclCompileForeachCmd): Fixed code that
+	corrupted the exceptDepth value in the compile environment when
+	foreach failed to compile inline. [Bug 884]
+
+	* library/encoding/euc-kr.enc:
+	* library/encoding/ksc5601.enc:
+	* tools/encoding/ksc5601.txt:
+	* unix/tclUnixInit.c: Added support for Korean EUC.
+
+	* win/tclWinChan.c (TclpGetDefaultStdChannel): added check for a
+	failure during Tcl_MakeFileChannel.
+
+1998-11-30  Scott Stanton  <stanton@GASPODE>
+
+	* unix/tclUnixNotfy.c (Tcl_WaitForEvent): Fixed hang that occurs when
+	trying to close a pipe that is currently being waited on by the
+	notifier thread. [Bug 607]
+
+	* unix/tclUnixFCmd.c (GetPermissionsAttribute): Increase size of
+	returnString buffer to avoid overflow. [Bug 584]
+
+	* generic/tclThreadTest.c (TclThreadSend): Fixed memory leak due to
+	use of TCL_VOLATILE instead of TCL_DYNAMIC.
+
+	* generic/tclThread.c (TclRememberSyncObject): Fixed memory leak
+	caused by failure to reuse condition variables.
+
+	* unix/tclUnixNotfy.c (Tcl_AlertNotifier, Tcl_WaitForEvent,
+	(NotifierThreadProc, Tcl_InitNotifier): Fixed race condition caused by
+	incorrect use of condition variables when sending messages between
+	threads. [Bug 607]
+
+	* generic/tclTestObj.c (TeststringobjCmd): MAX_STRINGS was off by one
+	so the strings array was too small.
+
+	* generic/tclCkalloc.c (Tcl_DbCkfree): Moved mutex lock so
+	ValidateMemory is done inside the mutex to avoid a race condition when
+	validate_memory is enabled. [Bug 880]
+
+1998-11-23  Scott Stanton  <stanton@GASPODE>
+
+	* regexec.c: more performance tuning from Henry Spencer.
+
+1998-11-17  Scott Stanton  <stanton@GASPODE>
+
+	* tclScan.c: moved "scan" implementation out of tclCmdMZ.c and added
+	Unicode support. This required a complete reimplementation of the
+	command to avoid using scanf(), which isn't Unicode aware. Two new
+	features were added in the process: %n to return the current number of
+	characters consumed, and XPG3-style %n$ argument order specifiers
+	similar to those provided by the "format" command. [Bug 833]
+
+	* tclAlloc.c: changed so allocated memory is always 8-byte aligned to
+	improve memory performance and to ensure that it will work on systems
+	that don't like accessing 4-byte aligned values (e.g. Solaris and
+	HP-UX). [Bug 834]
+
+1998-11-06  Scott Stanton  <stanton@GASPODE>
+
+	* tclVar.c (TclGetIndexedScalar): Fixed bug 796, var name was getting
+	lost before being passed to CallTraces.
+
+1998-10-21  Scott Stanton  <stanton@GASPODE>
+
+	* added "encoding" command
+
+	* Moved internal regexp declarations from tclInt.h to tclRegexp.h
+
+	* integrated regexp updates from Henry Spencer
+
+1998-10-15  Scott Stanton  <stanton@GASPODE>
+
+	* tclUtf.c: added Unicode character table support
+
+	* tclInt.h: added TclUniCharIsWordChar
+
+	* tclCmdMZ.c (Tcl_StringObjCmd): added "totitle" subcommand, changed
+	"wordend" and "wordstart" to properly handle Unicode word characters
+	and connector punctuation
+
+1998-10-05  Scott Stanton  <stanton@GASPODE>
+
+	* auto.tcl, package.tcl: fixed SCCS strings
+
+	* tclIndex: updated index to reflect 8.1 files
+
+	* tclCompile.c (TclCompileScript): changed to avoid modifying the
+	input string in place because name lookup operations could have
+	arbitrary side effects
+
+	* tclInterp.c: added guard against deleting current interpreter
+
+	* tclMacFile.c, tclUnixFile.c, tclWinFile.c, tclFileName.c: added
+	warnings around code that modifies strings in place
+
+	* tclExecute.c: fixed off-by-one copying error, fixed merge bugs
+
+	* tclEvent.c: changed so USE_TCLALLOC is tested for value instead of
+	definition
+
+	* tclCompCmds.c: replaced SCCS strings, added warnings around code
+	that modifies strings in place
+
+	* interp.test: added test for interp deleting itself
+
+1998-09-30  Scott Stanton  <stanton@GASPODE>
+
+	* makefile.vc: fixed so TCL_LIBRARY is set before running tcltest
+
+	* tclWin32Dll.c: removed TclpFinalize, cleanup of merges
diff --git a/ChangeLog.2000 b/ChangeLog.2000
new file mode 100644
index 0000000..0d20eaf
--- /dev/null
+++ b/ChangeLog.2000
@@ -0,0 +1,2539 @@
+2000-12-14  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclExecute.c:
+	* tests/expr-old.test: Re-wrote Tcl's [expr rand()] and [expr
+	srand($seed)] implementations, fixing a range error on some 64-bit
+	platforms. Added tests that detect the bug. The rewrite changes the
+	seed -> sequence map on 64-bit platforms, only for seed >= 2^31, a
+	slight incompatibility. [Bug 121072, Patch 102781]
+
+2000-12-10  Don Porter  <dgp@users.sourceforge.net>
+
+	* library/init.tcl:
+	* library/msgcat/msgcat.tcl:
+	* library/msgcat/pkgIndex.tcl:
+	* library/opt/optparse.tcl:
+	* library/opt/pkgIndex.tcl: Where [uplevel] is used in a proc to
+	evaluate a Tcl built-in command in the caller's context, the built-in
+	commands are now fully namespace-qualified. This prevents problems
+	when the caller context is in a namespace where the built-in command
+	name has been used by a command in the namespace. (For example,
+	[::ns::set] might be called instead of the intended [::set]). [Bug
+	119422, Patch 102545]
+
+2000-12-09  Jeff Hobbs  <jhobbs@interwoven.com>
+
+	* win/tclWinTime.c (CalibrationThread): added lint return value to
+	prevent compiler warning. [Bug 125005]
+
+	* docs/scan.n:
+	* tests/scan.test:
+	* generic/tclScan.c (Tcl_ScanObjCmd): changed %o and %x to use strtoul
+	instead of strtol to correctly preserve scan<>format conversion of
+	large integers. [Patch 102663, Bug 124600]
+
+	* generic/tclExecute.c (TclExecuteByteCode): Commited patch fixing
+	handling of {!<boolean>} in expressions. [Patch 102702]
+
+2000-12-08  Jeff Hobbs  <jhobbs@interwoven.com>
+
+	* library/init.tcl: Added support for PATHEXT variable in auto_execok,
+	recognizing the proper set of executable extensions on Windows. [Patch
+	102719]
+
+2000-12-08  Andreas Kupries  <a.kupries@westend.com>
+
+	* generic/tclEncoding.c (LoadTableEncoding): Changed dangerous code to
+	something less critical. This fixes [Bug 119417], part A without
+	affecting the speed when loading encodings.
+
+2000-12-08  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* doc/open.n: Added xref to fconfigure and advice on the opening of
+	binary files. Should help prevent a recurrence of bugs like [Bug
+	124558]
+
+2000-12-07  Jeff Hobbs  <jhobbs@interwoven.com>
+
+	* generic/tcl.h: added note about need to updated
+	library/dde/pkgIndex.tcl with minor version increment.
+
+	* library/dde/pkgIndex.tcl: updated to use 84 version to reflect the
+	makefile. Should probably be updated to use its real version at some
+	point. [Patch 102560, Bug 119421]
+
+2000-12-06  Eric Melski  <ericm@ajubasolutions.com>
+
+	* generic/tcl.h (attemptckalloc): Fixed typo for #define of
+	attemptckalloc (was defined to Tcl_AttempDbCkalloc, should have been
+	Tcl_AttemptDbCkalloc). [Bug 124384]
+
+	* generic/tclCkalloc.c: Added TCL_MEM_DEBUG versions of
+	Tcl_AttemptDbCkrealloc and Tcl_AttemptDbCkalloc. [Bug 124384].
+
+2000-11-24  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* generic/tclExecute.c (TclExecuteByteCode): Logical negation "!"  can
+	now handle string booleans, provided those values are placed in
+	variables.
+
+	* tests/expr.test (expr-13.17): Check that [expr {!$var}] can negate
+	the string-versions of booleans "yes", "false", etc.
+
+	* library/tcltest/tcltest.tcl (getMatchingFiles,
+	(getMatchingDirectories):
+	* tools/man2html.tcl (doDir):
+	* tools/man2help.tcl (doDir):
+	* library/package.tcl (tclPkgUnknown,tclMacPkgSearch):
+	* library/safe.tcl (AddSubDirs): [glob] uses -directory instead of
+	unsafe [file join]. [Bug 123313]
+
+	* generic/tclIndexObj.c:
+	* generic/tclTestObj.c (TestindexobjCmd): Changed internal
+	representation of index objects to fix [Bug 119082]; fix shouldn't be
+	visible to outside world...
+
+	* generic/tclTest.c (TestGetIndexFromObjStructObjCmd):
+	* tests/indexObj.test: (indexObj-6.*) Added to test for presence of
+	[Bug 119082].
+
+2000-11-23  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* generic/tclCmdIL.c (Tcl_LsortObjCmd): Fixed memory leak from [Bug
+	119398]
+
+	* library/init.tcl (unknown): Added specific level parameters to
+	all uplevel invokations to boost performance; didn't dare touch
+	the "namespace inscope" stuff though, since it looks sensitive
+	to me!  Should fix [Bug 123217], though testing is tricky...
+
+2000-11-21  Andreas Kupries  <a.kupries@westend.com>
+
+	All of the changes below are described in TIP #7 ~ Specification and
+	result from the application of the patch contained therein. Creator of
+	the patch is Kevin Kenny <kennykb@crd.ge.com>. The patch used here is
+	actually a bit different. Two MS specific constant values (format
+	FOOui64) were replaced with a more portable formatting of the values
+	and an additional cast to LONGLONG. My cross-compiling gcc was unable
+	to process the original form. [Patch 102459]
+
+	* tclWinTime.c: Add to the static data a set of variables that manage
+	the phase-locked techniques, including a ''CRITICAL_SECTION'' to guard
+	them so that multi-threaded code is stable.
+
+	* tclWinTime.c: Modify ''TclpGetSeconds'' to call ''TclpGetTime'' and
+	return the 'seconds' portion of the result. This change is necessary
+	to make sure that the two times are consistent near the rollover from
+	one second to another.
+
+	* tclWinTime.c: Modify ''TclpGetClicks'' to use TclpGetTime to
+	determine the click count as a number of microseconds.
+
+	* tclWinTime.c: Modify ''TclpGetTime'' to return the time as M*Q+B,
+	where Q is the result of ''QueryPerformanceCounter'', and M and B are
+	variables maintained by the phase-locked loop to keep the result as
+	close as possible to the system clock. The ''TclpGetTime'' call will
+	also launch the phase-lock management in a separate thread the first
+	time that it is invoked. If the performance counter is unavailable, or
+	if its frequency is not one of the two common 8254-compatible rates,
+	then ''TclpGetTime'' will return the result of ''ftime'' as it does in
+	Tcl 8.3.2.
+
+	* tclWinTime.c: Add the clock calibration procedure. The calibration
+	is somewhat complex; to save space, the reader is referred to the
+	reference implementation for the details of how the time base and
+	frequency are maintained.
+
+	* tclWinNotify.c: Modify ''Tcl_Sleep'' to test that the process has,
+	in fact, slept for the requisite time by calling ''TclpGetTime'' and
+	comparing with the desired time. Otherwise, roundoff errors may cause
+	the process to awaken early.
+
+	* tclWinTest.c: Add a ''testwinclock'' command. This command returns a
+	four element list comprising the seconds and microseconds portions of
+	the system clock and the seconds and microseconds portions of the Tcl
+	clock.
+
+	* winTime.test: Add to the test suite a test that makes sure that the
+	Tcl clock stays within 1.1 ms of the system clock over the duration of
+	the test.
+
+2000-11-21  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* doc/global.n:
+	* doc/upvar.n:
+	* doc/variable.n: Improved documentation to mention that variables so
+	created are listed in [info locals] and added a few more cross-links
+	between these commands. [Bug 119387]
+
+2000-11-17  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* tests/safe.test: (safe-4.3):
+	* generic/tclVar.c (TclLookupVar): Changed again. Now passes all the
+	tests, though one needed modifying since it required the wrong answer.
+	(Why on earth do we have inline modification of argument strings? This
+	sort of thing is horrendous to debug and doesn't work well in a
+	multithreaded environment!) [Bug 119192]
+
+	* tests/var.test: (var-1.19) If my attempts to fix the problem aren't
+	right yet, my attempts to describe it look pretty good to me...
+
+2000-11-16  Andreas Kupries  <a.kupries@westend.com>
+
+	* win/tclWinPort.h (line 69): Changed reference to winsock2.h into
+	winsock.h. This was a leftover from a foray into using winsock version
+	2 (History lesson from Scott Redman and Jeff Hobbs). This code was no
+	problem when compiling Tcl itself, but could trip extensions. [Bug
+	122568]
+
+2000-11-15  Jeff Hobbs  <jeff.hobbs@acm.org>
+
+	* unix/Makefile.in: removed bp.c references (hasn't existed in a long
+	time). Corrected 'make dist' to make dist with unversioned library
+	directories (same as out of cvs), so make install works correctly with
+	either source tree.
+
+2000-11-15  Jeff Hobbs  <jeff.hobbs@acm.org>
+
+	* generic/tclVar.c (TclLookupVar): reverted fix below as it broke all
+	other array unset error reporting.  Bug 119192 is still open.
+
+2000-11-15  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* generic/tclVar.c (TclLookupVar): Changed references to part2 to use
+	elName instead in various error message generating spots. [Bug 119192]
+
+2000-11-03  David Gravereaux  <davygrvy@ajubasolutions.com>
+
+	* win/.cvsignore: Removed 'configure' from the glob list now that it's
+	included.
+
+2000-11-03  Jeff Hobbs  <hobbs@ajubasolutions.com>
+
+	8.4a2 RELEASE
+
+	* unix/Makefile.in (install-libraries, dist):
+	* win/makefile.vc (install-libraries):
+	* win/Makefile.in (install-libraries): updated to install unversioned
+	library directories into versioned directories.
+
+	* tools/tcl.wse.in: updated for unversioning of library dirs
+
+	* unix/mkLinks: updated mkLinks with latest doc updates
+
+	* doc/Tcl_Main.3: added docs for Tcl_SetMainLoop
+
+	* generic/tclStubInit.c:
+	* generic/tclDecls.h:
+	* generic/tcl.decls: added Tcl_SetMainLoop proc that allows people to
+	set a main loop that will run for tclsh.
+	* generic/tcl.h: added Tcl_MainLoopProc typedef
+	* generic/tclMain.c (Tcl_SetMainLoop, StdinProc, Prompt): new
+	StdinProc and Prompt static procs and Tcl_SetMainLoop stubs proc. The
+	first two handle a fileevent based prompt (taken from tkMain.c).
+	Tcl_SetMainLoop enables the interactive setting of a main loop
+	procedure. This enables Tk to be a loadable package.
+
+2000-11-02  David Gravereaux  <davygrvy@ajubasolutions.com>
+
+	* generic/tclEvent.c: tclLibraryPath Tcl_Obj didn't have a way to
+	share its data among threads. This caused Tcl_Init() to always fail in
+	threads. Added a way to pass the data around with a global char*.
+	[BUG: 5301]
+
+2000-11-02  Jeff Hobbs  <hobbs@ajubasolutions.com>
+
+	* unix/configure:
+	* unix/dltest/configure:
+	* win/configure:
+	* tools/configure: checked in configure scripts so people doing CVS
+	checkouts aren't required to have autoconf. Changes to configure.in in
+	the future will require the corresponding configure script to also be
+	re-autoconf'ed and checked in.
+
+	* win/makefile.vc:
+	* win/tcl.m4: makefile fixes for Win64 support
+
+	* generic/tclIndexObj.c (Tcl_GetIndexFromObjStruct): minor cast
+	changes.
+
+2000-11-01  Jeff Hobbs  <hobbs@ajubasolutions.com>
+
+	* unix/tcl.m4: removed use of -lbsd and -ldl for AIX-5.
+
+	* tests/subst.test: added tests for non-zero return code handling by
+	subst.
+	* generic/tclParse.c (Tcl_EvalEx): corrected handling of non-zero,
+	non-error return code cases for subst. [Bug 119829]
+
+	* generic/tclVar.c (TclVarTraceExists): Corrected excessive mem use
+	when info exists was called on a non-existent array element. [Bug
+	119213, 119336]
+
+2000-10-30  David Gravereaux  <davygrvy@ajubasolutions.com>
+
+	* win/configure.in:
+	* win/Makefile.in:
+	* win/makefile.vc:
+	* win/tcl.rc:
+	* win/tclsh.rc: Added logic to derive filenames better in the resource
+	scripts based on compile options.
+
+2000-10-30  Jeff Hobbs  <hobbs@ajubasolutions.com>
+
+	* unix/tclUnixInit.c: added default encoding map from "ja_JP.eucJP" to
+	"euc-jp". (takahashi)
+
+	* tests/clock.test: corrected clock-2.* test numbering
+
+	* unix/configure.in (SC_TCL_LINK_LIBS): removed code that was
+	commented out (it had been moved to tcl.m4's SC_TCL_LINK_LIBS
+	already).
+
+	* unix/tcl.m4: consolidated gettimeofday check for AIX.
+
+2000-10-27  Jeff Hobbs  <hobbs@ajubasolutions.com>
+
+	* unix/configure.in:
+	* unix/tcl.m4: added support for AIX-5.
+
+	* generic/tclIO.c (Tcl_NotifyChannel): removed #ifdef around code for
+	old channel structures, placed preserve/release around statePtr
+	* generic/tclIO.c (CloseChannel): the statePtr for a channel was not
+	being freed when the last channel in a stack was freed, causing a mem
+	leak.
+
+	* unix/tclUnixChan.c: updated channel types to strict
+	TCL_CHANNEL_VERSION_2 style to avoid compiler warnings. They work
+	either way, but this avoids compiler warnings (that worries people).
+
+2000-10-27  Jennifer Hom  <jenn@ajubasolutions.com>
+
+	* library/tcltest1.0/tcltest.tcl: Removed a cd into the test directory
+	in runAllTests that screwed up the temporary directory setting,
+	effectively preventing users from running tests on multiple platforms
+	at the same time.
+
+2000-10-26  David Gravereaux <davygrvy@ajubasolutions.com>
+
+	* win/tclWinFile.c (TclpMatchFilesTypes): NULL was being set to "attr"
+	which was a DWORD. Changed NULL to zero because a 'void *' can't be
+	set to a DWORD to avoid the compiler warning.
+
+2000-10-24  Jennifer Hom  <jenn@ajubasolutions.com>
+
+	* tests/all.tcl: Removed support for tcltest 1.0.
+
+	* tests/tcltest.test:
+	* library/tcltest1.0/tcltest.tcl:
+	* library/tcltest1.0/pkgIndex.tcl:
+	* docs/tcltest.n: Moved tcltest2 code so that it's the standard
+	version of tcltest. Removed all tcltest2 files (tests/tcltest2.test,
+	library/tcltest1.0/tcltest2.tcl, docs/tcltest2.n).
+
+2000-10-20  Jeff Hobbs  <hobbs@ajubasolutions.com>
+
+	* win/tclWinFile.c (TclpMatchFilesTypes): made the stat call only
+	occur when necessary (for 'glob' command). Significantly speeds up
+	glob command from 8.3. [BUG: 6216]
+
+2000-10-19  Jennifer Hom  <jenn@ajubasolutions.com>
+
+	* library/tcltest1.0/tcltest2.tcl:
+	* tests/tcltest2
+	* doc/tcltest2.n: Code and documentation cleanup. Modified -verbose to
+	take list of keywords as well as string of letters. Removed Tcl
+	version information from tcltest. Removed tcltest::grep from tcltest
+	package. Added optional 3rd directory argument to
+	makeFile/makeDirectory and removeFile/removeDirectory.
+
+	* tests/basic.test: Changed references to tcltest::tclVersion to
+	hardcoded numbers.
+	* generic/tcl.h: Changed reference to tcltest2.tcl and tcltest.tcl in
+	comments to tests/basic.test.
+
+2000-10-06  David Gravereaux  <davygrvy@ajubasolutions.com>
+
+	* win/tclWinChan.c: moved Win2K bug case test with GetStdHandle() from
+	TclpGetDefaultStdChannel into Tcl_MakeFileChannel to enable a more
+	general method in detecting invalid OS handles rather than just a
+	specific known case. [BUG: 5971]
+
+2000-10-06  Jeff Hobbs  <hobbs@ajubasolutions.com>
+
+	* tests/cmdAH.test: extra tests for 'file channels' that include
+	multiple interpreter tests and channel sharing
+	* generic/tclIO.c (Tcl_GetChannelNamesEx): corrected function (and
+	consequently 'file channels') to return channels that are actually
+	registered for this specific interp, rather than this thread.
+
+	* doc/CrtChannel.3: fixed spelling mistakes
+
+2000-09-29  Jennifer Hom  <jenn@ajubasolutions.com>
+
+	* library/tcltest1.0/tcltest2.tcl:
+	* tests/tcltest2.test:
+	* doc/tcltest2.n: Modified the new form of the test command to accept
+	both attribute-value pairs and command line options. Updated the tests
+	and the documentation for this new format. Also changed the option
+	names for the test command.
+
+2000-09-29  Jeff Hobbs  <hobbs@scriptics.com>
+
+	* win/tclWinSerial.c (SerialGetOptionProc): corrected reporting of
+	space parity on Windows (Eason) [Bug 6057].
+
+	* win/Makefile.in: commented use of TESTFLAGS
+	* unix/Makefile.in: added TESTFLAGS to test target to conform with
+	Windows makefile and TEA style.
+
+	* tests/stack.test: prevented possible crash on systems with low
+	default stacksize (Tru64, AIX) in infinite recursion test. A solution
+	to check remaining stack space in the core is best, but hard to do in
+	a cross-platform manner.
+
+	* generic/tclIOGT.c (FLUSH_DELAY): renamed DELAY define to FLUSH_DELAY
+	to avoid defn conflict using Tru64's cc.
+
+2000-09-28  Jeff Hobbs  <hobbs@ajubasolutions.com>
+
+	* tools/tcl.wse.in: added tclPlatDecls.h and tkPlatDecls.h to the
+	Windows .exe install.
+
+	* tests/fCmd.test (fCmd-6.20): corrected test to remove c:/tcl8975@
+	after creating it.
+
+	* tests/fileName.test: cleaned up the testing of glob patterns for
+	c:/globTest (Windows) to directly create/remove directory.
+
+2000-09-27  Jeff Hobbs  <hobbs@ajubasolutions.com>
+
+	* generic/tcl.decls:
+	* generic/tclIO.c: updated Tcl_IsChannelShared,
+	Tcl_IsChannelRegistered, Tcl_CutChannel, Tcl_SpliceChannel,
+	Tcl_IsChannelExisting, and Tcl_ClearChannelHandlers to conform to the
+	new stacked channel implementation. Their stub slots were also moved
+	to give preference to the new 8.3.2 stub functions. This will cause an
+	incompatability with 8.4a1 only.
+	(StopCopy): fixed a bug introduced by a partial fix in 8.3.2 that
+	didn't set nonBlocking correctly when resetting the flags for the
+	write side. [Bug: 6261]
+
+	* doc/ChnlStack.3:
+	* doc/CrtChannel.3:
+	* generic/tcl.decls:
+	* generic/tcl.h:
+	* generic/tclDecls.h:
+	* generic/tclIO.c:
+	* generic/tclIO.h:
+	* generic/tclIOGT.c:
+	* generic/tclInt.decls:
+	* generic/tclIntDecls.h:
+	* generic/tclStubInit.c:
+	* generic/tclTest.c:
+	* tests/iogt.test:
+	* unix/Makefile.in:
+	* win/Makefile.in:
+	* win/makefile.vc:
+	* win/tclConfig.sh.in:
+	* win/tclWinChan.c:
+	* win/tclWinConsole.c:
+	* win/tclWinPipe.c:
+	* win/tclWinSerial.c:
+	* win/tclWinSock.c: Up-port of changes made in 8.3.2 to 8.4a2 code
+	base. Most of these changes relate to the rewrite of the stacked
+	channel implementation, with a few config related fixes.
+
+	Following is an asynchronous include of the applicable ChangeLog
+	entries from 8.3.2.
+
+	********************************************************
+	** START OF ASYNCHRONOUS UP-PORT LOG (8.3.2 -> 8.4a2) **
+	********************************************************
+
+2000-08-07  Jeff Hobbs  <hobbs@scriptics.com>
+
+	* doc/ChnlStack.3:
+	* doc/CrtChannel.3: updated the docs to be aware of the
+	TCL_CHANNEL_VERSION_2 style of Tcl channels.
+
+	* generic/tclIO.c (Tcl_CreateChannel): added assertion to verify that
+	the new channel versioning will be binary compatible with older
+	channel drivers.
+
+2000-08-05  Jeff Hobbs  <hobbs@scriptics.com>
+
+	* generic/tclIOGT.c (TclChannelTransform): fixed segfault that would
+	occur when transforming a channel with a proc that did not yet exist.
+	(Kupries)
+
+	* generic/tclTest.c (TestChannelCmd): added some lint init'ing of
+	statePtr and chan vars.
+
+2000-07-26  Jeff Hobbs  <hobbs@scriptics.com>
+
+	Merged core-8-3-1-io-rewrite back into core-8-3-1-branch. The
+	core-8-3-1-io-rewrite branch should now be considered defunct.
+
+	* generic/tclStubInit.c:
+	* generic/tclDecls.h:
+	* generic/tcl.decls:
+	* generic/tcl.h:
+	* generic/tclIO.c: moved the Tcl_Channel* macros from tcl.h to tclIO.c
+	and made them proper stubbed functions. These are: Tcl_ChannelName,
+	Tcl_ChannelVersion, Tcl_ChannelBlockModeProc, Tcl_ChannelCloseProc,
+	Tcl_ChannelClose2Proc, Tcl_ChannelInputProc, Tcl_ChannelOutputProc,
+	Tcl_ChannelSeekProc, Tcl_ChannelSetOptionProc,
+	Tcl_ChannelGetOptionProc, Tcl_ChannelWatchProc,
+	Tcl_ChannelGetHandleProc, Tcl_ChannelFlushProc, and
+	Tcl_ChannelHandlerProc. These should be used to access the
+	Tcl_ChannelType structure instead of direct pointer dereferencing.
+
+	* tests/iogt.test: added RCS string, marked tests 2.* to be unixOnly
+	due to underlying system differences.
+
+2000-07-25 Andreas Kupries <a.kupries@westend.com>
+
+	* tests/iogt.test: (line 866f) New tests iogt-6.[01], highlighting
+	buffering trouble when stacking and unstacking transformations.
+	iogt-6.0 is solved, see the changes below. iogt-6.1 remains, for now,
+	due to the perceived complexity of solutions.
+
+	* generic/tclIO.h: (line 139f) struct Channel, added a buffer queue,
+	to hold data pushed back when stacking a transformation.
+
+	* generic/tclIO.c:
+	(line 91f, line 7434f) New internal function 'CopyBuffer'.  Derived
+	from 'CopyAndTranslateBuffer', with translation removed.
+	(line 1025f, line 1212f): Initialization of new queue.
+	(line 1164f, Tcl_StackChannel): Pushback of input queue.
+	(line 1293f, Tcl_UnstackChannel): Discard input and pushback.
+	(line 3748f, Tcl_ReadRaw): Modified to use data in the push back area
+	before going to the driver. Uses 'CopyBuffer', s.a.
+	(line 4702f, GetInput): Modified to use data in the push back area
+	before going to the driver.
+ 	(line 4867f, Tcl_Seek): Modified to take pushback of the topmost
+	channel in a stack into account.
+	(line 5620f, Tcl_InputBuffered): See above. Added
+	'Tcl_ChannelBuffered'. Analog to 'Tcl_InputBuffered' but for the
+	buffer area in the channel.
+
+	* generic/tcl.decls: New public API 'Tcl_ChannelBuffered'. S.a.
+
+2000-07-17  Jeff Hobbs  <hobbs@scriptics.com>
+
+	* unix/Makefile.in:
+	* win/Makefile.in:
+	* win/makefile.vc: added tclIOGT.c to objects list to compile.
+
+	* generic/tclStubInit.c:
+	* generic/tclIntDecls.h:
+	* generic/tclInt.decls: commented out internal decls for
+	TclTestChannelCmd and TclTestChannelEventCmd as they were moved to
+	tclTest.c. Added new decls for TclChannelEventScriptInvoker and
+	TclChannelTransform.
+
+	* generic/tclIO.c (CloseChannel): stopped masking out of the
+	TCL_READABLE|TCL_WRITABLE bits from the state flags in CloseChannel,
+	instead adding extra intelligence to CheckChannelErrors with a new
+	CHANNEL_RAW_MODE bit for special behavior when called from Raw channel
+	APIs.
+
+2000-07-13  Jeff Hobbs  <hobbs@scriptics.com>
+
+	* generic/tclIO.c (StackSetBlockMode): moved set of chanPtr outside of
+	blockModeProc check to avoid infinite loop when blockModeProc was
+	NULL. Updated TransformSeekProc to not call Tcl_Seek directly
+	(Kupries).
+
+	* win/tclWinChan.c: updated fileChannelType to v2 channel struct
+	* win/tclWinConsole.c: updated consoleChannelType to v2 channel struct
+	* win/tclWinPipe.c: updated pipeChannelType to v2 channel struct
+	* win/tclWinSerial.c: updated serialChannelType to v2 channel struct
+	* win/tclWinSock.c: updated tcpChannelType to v2 channel struct
+
+2000-07-11  Brent Welch	<welch@ajubasolutions.com>
+
+	* win/tclConfig.sh.in (TCL_LIBS): Cleaned up unix-specific autoconf
+	variables.
+
+2000-07-11  Jeff Hobbs  <hobbs@scriptics.com>
+
+	* tests/iogt.test: made tests [345].0 not run by default as they were
+	failing in the new design, but I'm not convinced that the returned
+	result isn't correct.
+
+	* generic/tclDecls.h:
+	* generic/tclStubInit.c:
+	* generic/tcl.decls: added Tcl_GetTopChannel C API that returns the
+	current top channel of a channel stack. Tcl_GetChannel was changed
+	earlier to return the bottommost channel of a stack because that is
+	the one that is guaranteed to stay around the longest, and this was
+	needed to compensate for certain operations that want to look at the
+	state of the main channel. Most channel APIs already compensate for
+	grabbing the top, so it shouldn't be needed often.
+
+	* generic/tclIO.c (Tcl_StackChannel, Tcl_UnstackChannel): Added
+	flushing of buffers (Kupries), removed use of DownChannel macro, added
+	Tcl_GetTopChannel public API to get to the top channel of the channel
+	stack (necessary for TLS). Rewrote Tcl_NotifyChannel for new channel
+	design (Kupries). Did some code cleanup in the transform code.
+	tclIO.c must still be broken into bits (separate out test code and
+	giot code, create tclIO.h).
+
+2000-07-10  Andreas Kupries <a.kupries@westend.com>
+
+	* tests/iogt.test: Reverted some earlier changes as a fix by Jeff
+	revived the original and correct behaviour. IOW, the tests showed a
+	genuine error and I didn't see it :(.
+
+	* generic/tclIO.c (Tcl_Read|Write_Raw): Changed to directly use the
+	drivers and not DoRead|DoWrite. The latter use the buffering system,
+	encoding and eol-translation and this wreaks havoc with the data going
+	through the transformations. Both procedures use CheckForchannelErrors
+	and let it believe that there is no background copy in progress or
+	else stacked channels could not be used for that.
+
+	* generic/tclIO.c (TclCopyChannel, CopyData): Moved access to the
+	topmost channel from the first to the second procedure to make the
+	decision about that at the last possible time (Callbacks can change
+	the stacking).
+
+	test suite: failures of iogt-[345].0
+
+2000-07-06  Jeff Hobbs  <hobbs@scriptics.com>
+
+	* tests/iogt.test: new tests for stacked channel stuff based off new
+	'testchannel transform|unstack' code (Kupries IOGT extension).
+	* generic/tcl.decls:
+	* generic/tcl.h:
+	* generic/tclDecls.h:
+	* generic/tclStubsInit.c:
+	* generic/tclIO.c: complete rewrite of Tcl Channel code for stacked
+	channels. Channels are now designed to work in a more stacked fashion
+	with a shared ChannelState data structure.
+
+2000-06-02  Jeff Hobbs  <hobbs@scriptics.com>
+
+	* generic/tclIO.c (CloseChannel): removed the &ing out of
+	(TCL_READABLE|TCL_WRITABLE) from the flags, as CloseChannel does this
+	on the next pass through for the top channel, and it appeared to be
+	causing hangs by not allowing the final flush.
+
+2000-06-01  Jeff Hobbs  <hobbs@scriptics.com>
+
+	* generic/tclIO.c (CloseChannel): Rewrote CloseChannel code to unstack
+	a channel during the close process. Fixed a refcount bug in
+	Tcl_UnstackChannel. [Bug: 5623]
+	(CloseChannel): further extended CloseChannel in the stacked case to
+	effect certain operations on the next channel that would have been
+	done in Tcl_Close.  Also added CHANNEL_CLOSED and removed
+	(TCL_READABLE|TCL_WRITABLE) bits from chanPtr->flags. Changed final
+	reset of the WatchProc to check the chanDownPtr's (next) interestMask.
+
+	******************************************************
+	** END OF ASYNCHRONOUS UP-PORT LOG (8.3.2 -> 8.4a2) **
+	******************************************************
+
+2000-09-20  Jeff Hobbs  <hobbs@scriptics.com>
+
+	* tests/socket.test: removed doTestsWithRemoteServer constraint from
+	socket-12.*. It requires 'exec', not a remote server. Cleaned up some
+	coding errors.
+
+2000-09-20  Jennifer Hom  <jenn@ajubasolutions.com>
+
+	* library/tcltest1.0/pkgIndex.tcl: Updated to load tcltest 2.0.
+	* library/tcltest1.0/tcltest2.tcl: New version of tcltest.
+	Cleanup of command line parsing: allows users to specify command line
+	arguments through an environment variable named TCLTEST_OPTIONS [RFE:
+	3748], does not respond to incorrect arguments, and forces usage of
+	entire flag name when using command line arguments. Defines accessor
+	procs for all tcltest variables. Allows users to use 'return' in test
+	scripts. Allow users to specify whether test files should be sourced
+	or run in a separate process. 'all.tcl' code moved to tcltest package.
+	'test' proc modified to use attribute-value pairs. Allow users to
+	specify what return codes, output, and errors can be compared and
+	whether these values should be compared using regexp, glob, or exact
+	matching. makeDirectory & removeDirectory now operate with respect to
+	temporaryDirectory [Bug: 6001]. Test results from tests run in slave
+	interpreters are now included in test totals [Bug: 1493]. Test files
+	that return error values are now reported.
+	* tests/all.tcl: Added code to check for the tcltest version loaded;
+	modified to figure out which tests to run based on the tcltest version
+	loaded.
+	* tests/tcltest.test: Modified to explicitly load version 1.0 of
+	tcltest.
+	* tests/tcltest2.test: New test suite for tcltest; includes all of the
+	old tests plus new ones reflecting changes made for version 2.0.
+	* tests/cmdAH.test: Added singleTestInterp constraint to cmdAH-31.2;
+	this test does not run if tests aren't sourced into a single
+	interpreter.
+	* tests/socket.test: Fixed two tests that were referencing variables
+	outside of scope.
+
+	* tools/tcl.wse.in: Added code to install tcltest2.tcl.
+
+	* doc/tcltest2.n: New documentation for tcltest version 2.0. Removes
+	documentation for tcltest namespace variables. Adds documentation for
+	new tcltest procs.
+
+	* unix/mkLinks: Added code to link to tcltest2.n.
+
+	* generic/tcl.h: Added comment to modify tcltest2.tcl as well as
+	tcltest.tcl for version changes.
+
+2000-09-19  Eric Melski  <ericm@ajubasolutions.com>
+
+	* generic/tclCmdMZ.c (Tcl_RegexpObjCmd): When using -all, all attempts
+	after the first to match the regexp against the string should include
+	the TCL_REG_NOTBOL flag, to avoid erroneously matching ^ in the middle
+	of the string. Added code to set this flag after the first pass
+	through the matching loop. [Bug: 6284].
+
+2000-09-19  David Gravereaux  <davygrvy@ajubasolutions.com>
+
+	* doc/Eval.3: Added a note about the script argument to Tcl_Eval()
+	should be in UTF-8 or risk implied conversion errors when possible
+	combinations of upper ascii can be valid UTF-8 special codes.
+
+2000-09-17  Eric Melski  <ericm@ajubasolutions.com>
+
+	* tests/cmdIL.test: Added a test for fix for [Bug: 6212].
+
+	* generic/tclCmdIL.c (Tcl_LsortObjCmd): Applied patch from [Bug:
+	6212], which corrected an error in the handling of the -index option.
+
+2000-09-14  Eric Melski  <ericm@ajubasolutions.com>
+
+	* doc/Alloc.3: Added entries for Tcl_AttemptAlloc, Tcl_AttempRealloc.
+
+	* doc/StringObj.3: Added entry for Tcl_AttemptSetObjLength.
+
+	* generic/tclDecls.h:
+	* generic/tclStubInit.c: Regen'ed stubs files from new tcl.decls.
+
+	* generic/tcl.decls: Added stubs for the Tcl_Attempt* memory
+	allocators and for Tcl_AttemptSetObjLength.
+
+	* generic/tcl.h: Added #define's for attemptckalloc, attemptckrealloc,
+	which map to the Tcl_Attempt* memory allocators.
+
+	* generic/tclCkalloc.c: Added non-panic'ing versions of Tcl_Alloc,
+	Tcl_Realloc, etc.; these are called Tcl_AttemptAlloc,
+	Tcl_AttemptRealloc, etc. These are used by Tcl_AttemptSetObjLength and
+	the string obj append functions.
+
+	* generic/tclStringObj.c: Modified string growth algorithm to use
+	doubling algorithm as long as possible, and only fall back when that
+	fails. Added Tcl_AttemptSetObjLength, and modified
+	AppendUnicodeToUnicodeRep, AppendUtfToUtfRep, and
+	Tcl_AppendStringsToObjVA to support this.
+
+2000-09-07  David Gravereaux <davygrvy@ajubasolutions.com>
+
+	* win/.cvsignore: changed the glob patterns a bit to exclude VC++
+	project conversion backups.
+
+	* win/tclWinPipe.c: Stage-1 bug fix for TR#2460 "exec leaks memory".
+	Added more logic around the close-down of the pipe reader thread so as
+	to avoid, at all cost, a TerminateThread. Most cases with exec are
+	fixed, but I don't consider 2460 done yet. Closing down the read side
+	of a pipe before the child process, doesn't really fit the windows
+	model. [BUG: 2460]
+
+2000-09-07  Jeff Hobbs  <hobbs@scriptics.com>
+
+	* doc/trace.n: minor doc cleanup
+
+2000-09-06  André Pönitz <poenitz@htwm.de>
+
+	* doc/*.n: added or changed "SEE ALSO:" section
+
+2000-09-06  Jeff Hobbs  <hobbs@scriptics.com>
+
+	* win/tclWinLoad.c (TclpLoadFile): added special message for
+	ERROR_PROC_NOT_FOUND exception in loading a dll.
+	* win/tclWinError.c: changed ERROR_PROC_NOT_FOUND to map from ESRCH
+	(POSIX: no such process) to EINVAL because there is no good mapping
+	for "procedure not found".
+
+	* README:
+	* generic/tcl.h:
+	* library/tcltest1.0/tcltest.tcl:
+	* tools/tcl.wse.in:
+	* tools/tcltk-man2html.tcl:
+	* unix/configure.in:
+	* unix/tcl.spec:
+	* win/README.binary:
+	* win/configure.in: updated patchlevel to 8.4a2
+
+	* unix/tclUnixPipe.c (TclpCreateProcess): Removed WNOHANG from
+	Tcl_WaitPid call in error case of process creation on Unix, as it
+	would lead to defunct processes. [Bug: 6148]
+
+	* tests/string.test: extended string repeat tests
+	* generic/tclCmdMZ.c (Tcl_StringObjCmd): changed STR_REPEAT to
+	preallocate the full space of the final string, avoided repeated
+	appends.
+
+	* doc/source.n:
+	* doc/Eval.3: added extra note about how to safe use ^Z in code, as it
+	is now a cross-platform (was just Windows) EOF char.
+
+2000-09-05  Jeff Hobbs  <hobbs@scriptics.com>
+
+	* generic/tclHash.c: fixed pedantic warning of incorrectly placed
+	#endif
+
+	* generic/tclExecute.c (TclExecuteByteCode): INST_STR_INDEX fixed
+	pedantic cast warning.
+	Corrected support for building with -DTCL_COMPILE_STATS.
+	Added efficiency check of object equality.
+
+2000-08-29  Eric Melski  <ericm@ajubasolutions.com>
+
+	* generic/tclStringObj.c: Applied patch from Gerhard Hintermayer to
+	provide a more conservative string growth algorithm for strings larger
+	than one megabyte; this allows more efficient use of memory for very
+	large strings.
+
+2000-08-25  Eric Melski  <ericm@ajubasolutions.com>
+
+	* tests/trace.test: Extended array tracing tests.
+
+	* doc/trace.n: Clarified information about when array traces will be
+	fired.
+
+	* generic/tclVar.c (Tcl_ArrayObjCmd): Corrected call to CallTraces
+	(for TCL_TRACE_ARRAY) to only be called when the variable is either an
+	array or is undefined, to ensure that array traces do not fire for
+	scalar variables.
+
+2000-08-24  Eric Melski  <ericm@ajubasolutions.com>
+
+	* doc/man.macros: Tweaked tab settings for .SO (Standard Options)
+	sections, based on suggestion from Peter Spjuth.
+
+2000-08-24  Mo DeJong  <mdejong@redhat.com>
+
+	* unix/README: Update to account for removal of --enable-gcc.
+	* unix/configure.in:
+	* unix/tcl.m4 (SC_ENABLE_GCC): Remove --enable-gcc option.
+	* win/README: Add note about building with Cygwin.
+	* win/configure.in:
+	* win/tcl.m4 (SC_ENABLE_GCC): Remove --enable-gcc option. Remove quick
+	hack that provided cross compile support for windows builds.
+
+2000-08-24  Eric Melski  <ericm@ajubasolutions.com>
+
+	Overall change: Added support for command rename/delete traces and new
+	trace syntax, from patch from Vince Darley. Added support for array
+	traces for variables. [RFE: 5048, 5967].
+
+	* doc/trace.n: Updated documentation for new syntax; flagged old
+	syntax as deprecated; added documentation for command rename/delete
+	traces and variable array traces.
+
+	* tests/trace.test: Updated tests for new trace syntax; new tests for
+	command rename/delete traces; new tests for array traces.
+
+	* generic/tclVar.c: Support for new trace syntax; support for
+	TCL_TRACE_ARRAY.
+
+	* generic/tclStubInit.c:
+	* generic/tclDecls.h:
+	* generic/tcl.decls: Stub functions for command rename/delete traces.
+
+	* generic/tcl.h:
+	* generic/tclInt.h:
+	* generic/tclBasic.c: Support for command traces.
+
+	* generic/tclCmdMZ.c (TclTraceVariableObjCmd): Patched to support new
+	[trace] syntax:
+	trace {add|remove|list} {variable|command} name ops command
+	Added support for command traces (rename, delete operations).
+	Added support for TCL_TRACE_ARRAY at Tcl level (array operation for
+	variable traces).
+
+2000-08-20  Eric Melski  <ericm@ajubasolutions.com>
+
+	* generic/tclVar.c: Added check for non-arrays for [array statistics]
+	command (patch from Mark Patton).
+
+2000-08-19  David Gravereaux <davygrvy@ajubasolutions.com>
+
+	* generic/tclPlatDecls.h: without a previous '#include <windows.h>',
+	tclPlatDecls.h can't be parsed due to a missing definition of TCHAR.
+	Added a check to include it when not defined.
+
+	***POSSIBLE OBSCURE BUG*** could be caused when the compile flags for
+	the core happen to be different than a project who uses these publics
+	regarding -D_MBCS and -D_UNICODE. This added check might have to be
+	revisited later with a better understanding of the reprocusions. I
+	think TCHAR should be replaced with it's expansion.
+
+2000-08-18  David Gravereaux <davygrvy@ajubasolutions.com>
+
+	* win/.cvsignore (added): provides a cleaner build environment with
+	graphical CVS clients.
+
+2000-08-15  Eric Melski  <ericm@ajubasolutions.com>
+
+	* library/tcltest1.0/tcltest.tcl: Set debug level in
+	tcltest::restoreState to 2, for consistancy with the debug level in
+	tcltest::saveState [Bug: 4505].
+
+2000-08-14  Eric Melski  <ericm@ajubasolutions.com>
+
+	* win/makefile.vc:
+	* win/Makefile.in:
+	* unix/Makefile.in: Added tclPlatDecls.h to the list of installed
+	headers, for more complete stubs support. [Bug: 5241].
+
+	* generic/tcl.h: Added #include "tclPlatDecls.h" to get
+	platform-specific stubs declarations (Tcl_WinTCharToUtf, etc)
+	[Bug: 5241].
+
+	* README: Updated link for instructions on compiling Tcl from sources
+	to point to correct location (http://dev.scriptics.com/doc/... instead
+	of http://dev.scriptics.com/support/...).
+
+2000-08-11  Eric Melski  <ericm@ajubasolutions.com>
+
+	* generic/tclEnv.c (TclUnsetEnv): Changed declaration of length
+	variable from "unsigned int" to "int", to match usage when passed to
+	TclpFindVariable [Bug: 6126].
+
+2000-08-10  Eric Melski  <ericm@ajubasolutions.com>
+
+	* library/msgcat1.0/pkgIndex.tcl: Bumped version number to 1.2 [Bug:
+	6100].
+
+	* library/msgcat1.0/msgcat.tcl: Removed erroneous [package forget] in
+	msgcat namespace initializer. Bumped version number to 1.2 [Bug: 6100]
+
+2000-08-10  David Gravereaux <davygrvy@ajubasolutions.com>
+
+	* generic/tclObj.c: r1.15 accidentally changed a global mutex name
+	tclObjMutex to ObjMutex.  Put the correct name back.
+
+2000-08-07  Eric Melski  <ericm@ajubasolutions.com>
+
+	* tests/indexObj.test: Added tests using the [testwrongnumargs]
+	command to test Tcl_WrongNumArgs.
+
+	* generic/tclTest.c (TestWrongNumArgsObjCmd): Added test function for
+	the Tcl_WrongNumArgs function.
+
+	* generic/tclIndexObj.c (Tcl_WrongNumArgs): Corrected algorithm to not
+	insert a space before the message component when objc == 0 [Bug: 6078]
+
+2000-07-27  Mo DeJong  <mdejong@redhat.com>
+
+	* win/configure.in: TCL_STUB_LIB_FLAG should not include ${TCL_DBGX}
+	in win/tclConfig.sh, fix that.
+
+2000-07-25  David Gravereaux  <davygrvy@ajubasolutions.com>
+
+	* doc/Async.3:
+	* generic/tclAsync.c:
+	* generic/tclInt.decls:
+	* generic/tclIntPlatDecls.h:
+	* generic/tclStubInit.c:
+	* generic/tclTest.c:
+	* mac/tclMacPort.h:
+	* unix/tclUnixPort.h:
+	* win/tclWinInit.c: Thread-safe rewrite for tclAsync.c. Added notifier
+	alerting on all platforms as it was only working on Win before.
+	Removed older Win hacks that would end-up waking the wrong notifier in
+	the presence of a threaded build. All tests pass as before. New test
+	cases will be added soon for the new behavior. [BUG: 5791]
+
+2000-07-25  Eric Melski  <ericm@ajubasolutions.com>
+
+	* generic/tclVar.c (CallTraces): Added check for VAR_TRACE_ACTIVE on
+	the array containing the variable before executing traces on that
+	array, to conform with normal variable traces and the documentation,
+	which states that while executing a trace, other traces on that
+	variable are disabled. [Bug: 6049].
+
+	* win/tclWinPipe.c (BuildCommandLine): Added Tcl_DStringFree call to
+	prevent potential memory leaks [Bug: 6041].
+
+2000-07-24  Eric Melski  <ericm@ajubasolutions.com>
+
+	* doc/msgcat.n: Added documentation about the selection of the default
+	locale on Windows.
+
+2000-07-23  Joe English  <jenglish@flightlab.com>
+
+	* doc/AddErrInfo.3:
+	* doc/ChnlStack.3:
+	* doc/Exit.3:
+	* doc/GetIndex.3:
+	* doc/Notifier.3:
+	* doc/Object.3:
+	* doc/RegExp.3:
+	* doc/SetResult.3:
+	* doc/SplitList.3:
+	* doc/Thread.3:  Added missing entries to NAME section.
+
+	* doc/AddErrInfo.3:
+	* doc/CrtObjCmd.3:
+	* doc/RecEvalObj.3: Changed Tcl_EvalObj to Tcl_EvalObjEx
+
+2000-07-21  Eric Melski  <ericm@ajubasolutions.com>
+
+	* generic/tclStubInit.c:
+	* generic/tclObj.c:
+	* generic/tclInt.h:
+	* generic/tclHash.c:
+	* generic/tclDecls.h:
+	* generic/tcl.h:
+	* generic/tcl.decls:
+	* doc/Hash.3: Reapplied patch from Paul Duffin to extend hash tables
+	to allow custom key types, such as Tcl_Obj *'s, and others.
+
+	* doc/binary.n: Noted that the example in the introduction assumes a
+	32-bit system [Bug: 6035].
+
+2000-07-21  Mo DeJong  <mdejong@redhat.com>
+
+	* win/configure.in: Define ${prefix} and ${exec_prefix} like
+	unix/configure.in. Fix or add TCL_SRC_DIR, TCL_STUB_LIB_FILE,
+	TCL_STUB_LIB_FLAG, TCL_BUILD_STUB_LIB_SPEC, TCL_STUB_LIB_SPEC,
+	TCL_BUILD_STUB_LIB_PATH, TCL_STUB_LIB_PATH.
+
+2000-07-20  Eric Melski  <ericm@ajubasolutions.com>
+
+	* generic/tclStubInit.c:
+	* generic/tclObj.c:
+	* generic/tclInt.h:
+	* generic/tclHash.c:
+	* generic/tclDecls.h:
+	* generic/tcl.h:
+	* generic/tcl.decls:
+	* doc/Hash.3: Reverted patch from Paul Duffin to extend hash tables to
+	allow custom key types, such as Tcl_Obj *'s, and others; it seems to
+	break Tk.
+
+2000-07-19  Eric Melski  <ericm@ajubasolutions.com>
+
+	* generic/tclStubInit.c:
+	* generic/tclObj.c:
+	* generic/tclInt.h:
+	* generic/tclHash.c:
+	* generic/tclDecls.h:
+	* generic/tcl.h:
+	* generic/tcl.decls:
+	* doc/Hash.3: Applied patch from Paul Duffin to extend hash tables to
+	allow custom key types, such as Tcl_Obj *'s, and others.
+
+	* tests/pkgMkIndex.test: Added tests for pkg_compareExtension.
+
+	* library/package.tcl: Enhanced pkg_compareExtension to handle Unixes
+	which tack the version number on to the end of library names (eg,
+	foo.so.1.2); such filenames will be correctly matched. (Patch from
+	Vince Darley).
+
+	* win/makefile.vc: Applied patch from Don Porter to provide better
+	nmake support for NT/Alpha [RFE: 5938].
+
+2000-07-18  Mo DeJong  <mdejong@redhat.com>
+
+	* unix/configure.in:
+	* unix/tcl.m4:
+	* win/tcl.m4: Properly quote arguments to m4 macros. This allows Tcl
+	to work with the new version of autoconf.
+
+2000-07-18  Eric Melski  <ericm@ajubasolutions.com>
+
+	* tests/opt.test: Removed references to Lfirst, Lrest functions.
+
+	* library/opt0.4/optparse.tcl: Applied patch from Chris Nelson, which
+	replaces the [Lfirst] function with an inline [lindex ... 0] and
+	[Lrest] with [lrange ... 1 end], for better performance. [RFE: 6019]
+
+2000-07-18  Eric Melski  <ericm@scriptics.com>
+
+	* compat/string.h: Fixed function prototypes for strpbrk and strtok
+	[Bug: 6020].
+
+2000-07-17  David Gravereaux  <davygrvy@ajubasolutions.com>
+
+	* win/tclWinChan.c: Win2K OS bug with GetStdHandle(STD_OUTPUT_HANDLE)
+	giving the wrong answer. This made TclpGetDefaultStdChannel grab what
+	it thought was a valid native stdout handle. Added a new WriteFile()
+	test to make sure it's really valid. This OS bug doesn't affect the
+	shells. Only -subsystem:windows (aka WinMain) application that
+	dynamically load tclXX.dll [BUG: 5971]
+
+2000-07-17  Eric Melski  <ericm@scriptics.com>
+
+	* library/msgcat1.0/msgcat.tcl:
+	* doc/msgcat.n:
+	* tests/msgcat.test: Applied patches from Chris Nelson, to provide the
+	mcmset function, which allows the translator to set multiple string
+	translations in a single function call, rather than requiring many
+	calls to mcset. [RFE: 6000, 5993]. In addition, these patches correct
+	mcload to use utf-8 encoding on when reading message catalog files,
+	and provides for better default behavior for determining the locale on
+	a Windows system.
+
+2000-07-17  Mo DeJong  <mdejong@redhat.com>
+
+	* unix/tcl.m4 (SC_ENABLE_GCC): Don't set CC=gcc before running
+	AC_PROG_CC if CC is already set.
+
+2000-07-13  André Pönitz <poenitz@mathematik.tu-chemnitz.de>
+
+	* doc/lappend.n:
+	* doc/lindex.n:
+	* doc/linsert.n:
+	* doc/list.n:
+	* doc/llength.n:
+	* doc/lrange.n:
+	* doc/lreplace.n:
+	* doc/lsearch.n:
+	* doc/lsort.n: Added SEE ALSO sections.
+
+2000-07-07  Mo DeJong  <mdejong@redhat.com>
+
+	* win/configure.in: Fix definition of TCL_SRC_DIR so that it matches
+	the Unix version.
+	* win/tclConfig.sh.in: Removed duplicate variables.
+
+2000-07-06  Eric Melski  <ericm@scriptics.com>
+
+	* tests/msgcat.test:
+	* library/msgcat1.0/msgcat.tcl: Applied patch from Christian Krone, to
+	provide extended args support for msgcat::unknown, which is used for
+	strings without a known translation in the current locale [Bug: 5984].
+
+2000-06-29  Eric Melski  <ericm@scriptics.com>
+
+	* doc/msgcat.n: Doc's for mcmax function.
+
+	* library/msgcat1.0/msgcat.tcl: Applied patches from Laurent Duperval,
+	to add mcmax function, which computes the length of the longest of
+	several translated strings. Bumped version number to 1.1.
+
+2000-06-27  Eric Melski  <ericm@scriptics.com>
+
+	* tests/stringObj.test: Tweaked tests to avoid hardcoded high-ASCII
+	characters (which will fail in multibyte locales); instead used \uXXXX
+	syntax. [Bug: 3842].
+
+2000-06-26  Eric Melski  <ericm@scriptics.com>
+
+	* doc/package.n: Corrected information about [package forget]
+	arguments [Bug: 5418].
+
+2000-06-23  Eric Melski  <ericm@scriptics.com>
+
+	* doc/Hash.3: Added documentation patch for Tcl_Obj *'s as keys in Tcl
+	hash tables [RFE: 5934].
+
+	* generic/tcl.h:
+	* generic/tclHash.c: Applied patch from [RFE: 5934], which extends Tcl
+	hash tables to allow Tcl_Obj *'s as the key.
+
+2000-06-20  Eric Melski  <ericm@ajubasolutions.com>
+
+	* tests/opt.test:
+	* library/opt0.4/optparse.tcl: Applied patch from [Bug: 5922], which
+	corrected an incorrect use of [string match].
+
+	* unix/tclConfig.sh.in:
+	* win/tclConfig.sh.in: Applied patch from [Bug: 5921], which corrects a
+	typo in the comments in these files.
+
+2000-06-19  Eric Melski  <ericm@scriptics.com>
+
+	* doc/RegExp.3: Replaced instances of "Tcl_GetRegExpInfo" with
+	"Tcl_RegExpGetInfo", the correct name of the function [Bug: 5901].
+
+2000-06-13  Eric Melski  <ericm@scriptics.com>
+
+	* win/tcl.m4:
+	* win/configure.in:
+	* win/Makefile.in: Applied patch from [RFE: 5844], to extend support
+	for mingw compile environment on Windows.
+
+	* win/tclWinDde.c:
+	* win/tclWinInit.c:
+	* win/tclWinNotify.c:
+	* win/tclWinPipe.c:
+	* win/tclWinReg.c:
+	* win/tclWinThrd.c: Applied patch from [Bug: 5794], to fix compiler
+	warnings when using mingw on Windows.
+
+2000-05-31  Jeff Hobbs  <hobbs@scriptics.com>
+
+	* tests/set-old.test:
+	* doc/unset.n:
+	* generic/tclVar.c (Tcl_UnsetObjCmd): added -nocomplain and -- options
+	to unset, to allow for a silent unset operation.
+
+2000-05-31  Eric Melski  <ericm@scriptics.com>
+
+	* generic/tclVar.c (Tcl_ArrayObjCmd): Added support for regexp and
+	exact matching for [array names] command. [RFE: 3684].
+
+	* doc/array.n: Added documentation for [array names
+	-exact/-regexp/-glob] [RFE: 3684].
+
+	* tests/set-old.test: Added tests for [array names
+	-exact/-regexp/-glob] [RFE: 3684].
+
+2000-06-06  Jeff Hobbs  <hobbs@scriptics.com>
+
+	8.4a1 RELEASE
+
+	* generic/tclExecute.c (TclExecuteByteCode INST_STR_CMP): added test
+	of iResult return from memcmp, as memcmp isn't required to return only
+	-1,0,1.
+
+2000-06-03  Jeff Hobbs  <hobbs@scriptics.com>
+
+	* generic/tclIndexObj.c (Tcl_GetIndexFromObjStruct): Corrected caching
+	of the index ptr to account for offsets != sizeof(char *). [Bug: 5153]
+
+2000-05-29  Sandeep Tamhankar <sandeep@scriptics.com>
+
+	* tests/http.test
+	* doc/http.n
+	* library/http2.3/http.tcl: Fixed bug 5741, where unsuccessful geturl
+	calls sometimes leaked memory and resources (sockets). Also, switched
+	around some of the logic so that http::wait never throws an exception.
+	This is because in an asynchronous geturl, the command callback will
+	probably end up doing all the error handling anyway, and in an
+	asynchronous situation, the user expects to check the state when the
+	transaction completes, as opposed to being thrown an exception.	For
+	the http package, this menas the user can check http::status for
+	"error" and http::error for the error message after doing the
+	http::wait.
+
+2000-05-27  Jeff Hobbs  <hobbs@scriptics.com>
+
+	* tests/info.test:
+	* doc/info.n:
+	* generic/tclIOUtil.c (Tcl_EvalFile):
+	* generic/tclCmdIL.c (InfoScriptCmd): added ability to set the info
+	script return value [info script ?newFileName?]. This will be
+	beneficial for virtual file system programs. [Bug: 4225]
+
+2000-05-26  Jeff Hobbs  <hobbs@scriptics.com>
+
+	* generic/tclCmdMZ.c (Tcl_RegsubObjCmd): reworked to operate in
+	Unicode, tweaked for performance.
+	(Tcl_StringObjCmd) changed STR_FIRST/STR_LAST error message to
+	something more understandable, reworked STR_FIRST, STR_LAST, STR_MAP,
+	STR_MATCH, STR_RANGE, STR_REPLACE to operate in Unicode. Removed
+	inneffectual STR_RANGE "special" ByteArray support. Optimized STR_MAP
+	algorithm, especially optimized for one-pair case. Fixed possible mem
+	overrun in STR_INDEX bytearray case.
+
+	* generic/tclCompExpr.c: changed INST_STREQ -> INST_STR_EQ,
+	INST_STRNEQ -> INST_STR_NEQ
+	* generic/tclCompile.c: added streq, strneq, strcmp, strlen &
+	strmatch to the compiled stats instructionTable
+	* generic/tclCompile.h: added instructions INST_STR_CMP,
+	INST_STR_INDEX, INST_STR_MATCH
+	* generic/tclCompCmds.c: added byte compiler support for [string
+	compare|match|index].
+	* generic/tclExecute.c: Changed INST_STR_(N)EQ to return an Int object
+	and not bother trying to reuse the top stack object. Added
+	INST_STR_CMP, INST_STR_INDEX, INST_STR_MATCH bytecode ops. Extended
+	evalstats output info with Tcl_IsShared stat info.
+
+	* generic/tclInt.h:
+	* generic/tclObj.c (Tcl_DbIsShared): added support for checking result
+	of Tcl_IsShared in evalstats (TCL_COMPILE_STATS).
+
+	* generic/tclStringObj.c (Tcl_AppendUnicodeToObj): removed dead code.
+	(AppendUnicodeToUnicodeRep) removed overallocation by extra
+	sizeof(Tcl_UniChar) multiplier.
+
+	* tests/string.test: added string map tests for the one-pair case,
+	corrected tests to reflect improved error messages in first/last.
+	Added tests against mem overrun in string index bytearray case.
+
+2000-05-23  Eric Melski  <ericm@scriptics.com>
+
+	* generic/tclInt.h: Added function prototypes for TclCompileStringCmd
+	and TclCompileReturnCmd.
+
+	* generic/tclCompile.h: Added definition of INST_STRLEN opcode and
+	updated LAST_INST_OPCODE value.
+
+	* generic/tclBasic.c: Added information about TclCompileStringCmd and
+	TclCompileReturnCmd to BuiltInCmds table.
+
+	* generic/tclExecute.c (TclExecuteByteCode): Added support for the
+	INST_STRLEN opcode.
+
+	* generic/tclCompCmds.c (TclCompileStringCmd): Basic implementation of
+	byte-compiled [string] command. Not all subcommands are implemented;
+	those that are not an out-line compiled.
+
+	(TclCompileReturnCmd): Byte-compiled implementation of [return]
+	command. Only "simple" returns are byte-compiled; in particular, if
+	the -code, -errorinfo or -errorcode flags are used, the command is not
+	byte-compiled.
+
+2000-05-22  Jeff Hobbs  <hobbs@scriptics.com>
+
+	* doc/scan.n:
+	* doc/array.n: minor doc fixes [Bug: 5396]
+
+	* generic/tclEnv.c: cast cleanup [Bug: 5624]
+	* win/tclWinConsole.c: cast and header cleanup [Bug: 5625]
+	* win/tclWinSerial.c: cast cleanup [Bug: 5626]
+	* win/tclWinFCmd.c: cast cleanup [Bug: 5627]
+
+2000-05-19  Jeff Hobbs  <hobbs@scriptics.com>
+
+	* generic/tclTest.c:
+	* generic/tclIO.c: moved channel test commands from tclIO.c to
+	tclTest.c.
+	* generic/tclIO.h: new file, split out from tclIO.c to allow test
+	commands to be moved to tclTest.c.
+
+	* generic/tclStubInit.c:
+	* generic/tclIntDecls.h:
+	* generic/tclInt.decls: removed TclTestChannel*Cmd from internal stubs
+	table and added TclChannelEventScriptInvoker to the internal stubs
+	table so it can be used from the test code.
+
+2000-05-18  Eric Melski  <ericm@scriptics.com>
+
+	* tests/clock.test: Added test for "2 days 2 hours ago" style
+	specifications.
+
+	* generic/tclDate.c: Regenerated from tclGetDate.y.
+
+	* generic/tclGetDate.y: Tweaked grammar to properly handle the "ago"
+	keyword when it follows multiple relative unit specifiers, as in "2
+	days 2 hours ago". [Bug: 5497]
+
+2000-05-18  Jeff Hobbs  <hobbs@scriptics.com>
+
+	* win/{tcl.m4,Makefile.in,configure.in}: added support for mingw
+	compile env and cross-compiling. [Bug: 5499]
+
+	* generic/tclClock.c (FormatClock): correct code to handle locale
+	specific return values from strftime, if any. [Bug: 3345]
+
+	* unix/tclUnixInit.c (TclpSetInitialEncodings): attempt to correct
+	setlocale calls for XIM support and locale issues. [BUG: 5422 3345
+	4236 2522 2521]
+
+2000-05-17  Jeff Hobbs  <hobbs@scriptics.com>
+
+	* library/init.tcl (auto_import): added check to see if a valid
+	pattern was coming in, to avoid simple error cases [Bug: 3326]
+
+	* doc/regsub.n: correct regsub docs [Bug: 5346]
+
+2000-05-15  Eric Melski  <ericm@scriptics.com>
+
+	* library/history.tcl: Corrected an off-by-one error in HistIndex,
+	which was causing [history redo] to start its search at the wrong
+	event index. [Bug: 1269].
+
+2000-05-10  Jeff Hobbs  <hobbs@scriptics.com>
+
+	* generic/tclPosixStr.c (Tcl_SignalMsg): clarified #defines for Linux
+	on Sparc to compile correctly. [Bug: 5364]
+
+	* doc/namespace.n:
+	* tests/namespace.test:
+	* generic/tclNamesp.c (Tcl_NamespaceObjCmd): added 'namespace exists'
+	command. [Bug: 4665]
+
+	* doc/source.n:
+	* doc/Eval.3:
+	* tests/source.test:
+	* generic/tclIOUtil.c (Tcl_EvalFile): added explicit \32 (^Z) eofchar
+	(affects Tcl_EvalFile in C, "source" in Tcl). This was implicit on
+	Windows already, and is now cross-platform to allow for scripted
+	documents.
+
+2000-05-09  Andreas Kupries  <a.kupries@westend.com>
+	operating as proxy for David Gravereaux <davygrvy@pobox.com>
+
+	* win/tclWinThrd.c (TclpInitLock, TclpMasterLock): Added missing
+	initialization of joinLock.
+
+2000-05-09  Eric Melski  <ericm@scriptics.com>
+
+	* tests/lsearch.test:
+	* doc/lsearch.n:
+	* generic/tclCmdIL.c (Tcl_LsearchObjCmd): Extended [lsearch] to
+	support sorted list searching and typed list searching. [RFE: 4098].
+
+2000-05-08  Jeff Hobbs  <hobbs@scriptics.com>
+
+	* doc/expr.n:
+	* tests/expr.test:
+	* tests/expr-old.test: added tests for 'eq' and 'ne'
+	* generic/tclExecute.c:
+	* generic/tclCompile.h: added INST_STREQ and INST_STRNEQ opcodes that
+	do strict string comparisons.
+	* generic/tclCompExpr.c: added 'eq' and 'ne' string comparison
+	operators.
+	* generic/tclParseExpr.c (GetLexeme): added 'eq' and 'ne' expr parse
+	terms (string (in)equality check).
+
+	* generic/tclCmdIL.c (Tcl_LinsertObjCmd): made use of
+	Tcl_DuplicateObj where code was otherwise duplicated. Made special
+	case of inserting one element at the end work again (where index ==
+	len).
+	(Tcl_LreplaceObjCmd): moved Tcl_DuplicateObj call lower and cleaned
+	up use of other arguments.
+
+	* generic/tclObj.c (Tcl_DuplicateObj): simplified code to call
+	TclInitStringRep, which the code was just duplicating in part.
+
+	* doc/Utf.3:
+	* generic/tclStubInit.c:
+	* generic/tcl.decls:
+	* generic/tclDecls.h:
+	* generic/tclUtf.c: Added new functions Tcl_UniCharNcasecmp and
+	Tcl_UniCharCaseMatch (unicode parallel to Tcl_StringCaseMatch)
+	* generic/tclUtil.c: rewrote Tcl_StringCaseMatch algorithm for
+	optimization and made Tcl_StringMatch just call Tcl_StringCaseMatch
+	* tests/string.test: extended string match tests
+
+2000-05-08  Eric Melski  <ericm@scriptics.com>
+
+	* tests/set-old.test:
+	* doc/array.n:
+	* generic/tclVar.c: Added [array statistics] command [RFE: 4557]
+
+2000-05-06  Andreas Kupries <a.kupries@westend.com>
+	operating as proxy for David Gravereaux <davygrvy@pobox.com>
+
+	* tclThreadJoin.c: Fixed several places with missing a & in arguments
+	to calls of Tcl_Mutex(Un)lock and Tcl_ConditionNotify functions.
+
+2000-05-02  Jeff Hobbs  <hobbs@scriptics.com>
+
+	* README:
+	* generic/tcl.h:
+	* library/init.tcl:
+	* library/reg1.0/pkgIndex.tcl:
+	* library/tcltest1.0/tcltest.tcl:
+	* mac/README:
+	* tools/tcl.hpj.in:
+	* tools/tcl.wse.in:
+	* unix/README:
+	* unix/configure.in:
+	* unix/tcl.spec:
+	* win/README:
+	* win/README.binary:
+	* win/configure.in:
+	* win/makefile.vc:
+	* win/tcl.m4: updated patchlevel to 8.4a1
+
+	* tests/compile.test:
+	* tests/init.test:
+	* tests/proc.test:
+	* tests/proc-old.test:
+	* tests/rename.test:
+	* generic/tclProc.c: reworked error return for procedures with
+	incorrect args to be like the C Tcl_WrongNumArgs, where a "wrong #
+	args: ..." message is printed out with the args list.
+
+	* unix/Makefile.in: add tclsh.ico and tcl.spec to dist target
+
+2000-05-02  Andreas Kupries <a.kupries@westend.com>
+
+	Overall changes:
+	  (1) Implementation of joinable threads for all platforms.
+	  (2) Additional API's for channels. Required to allow the thread
+	      extension to move channels between threads.
+
+	* generic/tcl.decls (lines 1360f): Added Tcl_JoinThread,
+	Tcl_IsChannelShared, Tcl_IsChannelRegistered, Tcl_CutChannel,
+	Tcl_SpliceChannel, Tcl_IsChannelExisting and Tcl_ClearChannelHandlers
+	(slots 394 to 400).
+
+	* generic/tclIO.c: Implemented Tcl_IsChannelRegistered,
+	Tcl_IsChannelShared, Tcl_CutChannel, Tcl_SpliceChannel,
+	Tcl_IsChannelExisting and Tcl_ClearChannelHandlers.  Tcl_CutChannel
+	uses code from CloseChannel. Replaced this code by a call to
+	Tcl_CutChannel. Replaced several code fragments adding channels to
+	the channel list with calls to Tcl_SpliceChannel. Removed now unused
+	variables from CloseChannel and Tcl_UnstackChannel.
+	Tcl_ClearChannelHandlers uses code from Tcl_Close. Replaced this code
+	by a call to Tcl_ClearChannelHandlers. Removed now unused variables
+	from Tcl_Close. Added the subcommands 'cut', 'forgetch', 'splice' and
+	'isshared' to the test code (TclTestChannelCmd).
+
+	* unix/tclUnixThread.c: Implemented Tcl_JoinThread using the
+	pthread-functionality.
+
+	* win/tclWinThrd.c: Fixed several small typos in comments.
+	Implemented Tcl_JoinThread using a platform independent emulation
+	layer (see generic/tclThreadJoin.c below). Added 'joinLock' to
+	serialize Tcl_CreateThread and TclpExitThread to prevent a race for
+	joinable threads.
+
+	* mac/tclMacThrd.c: Implemented Tcl_JoinThread using a platform
+	independent emulation layer (see generic/tclThreadJoin.c below). Due
+	to the cooperative nature of threading on this platform the race
+	mentioned above is not present.
+
+	* generic/tclThreadJoin.c: New file. Contains a platform independent
+	emulation layer helping in the implementation of joinable threads for
+	the win and mac platforms.
+
+	* generic/tclInt.h: Added declarations for TclJoinThread,
+	TclRememberJoinableThread and TclSignalExitThread. These procedures
+	define the API of the emulation layer for joinable threads (see
+	generic/tclThreadJoin.c above).
+
+	* win/Makefile.in:
+	* win/makefile.vc: Added generic/tclTheadJoin.o to the rules.
+
+	* mac/: I don't know to which file generic/tclTheadJoin.o has to be
+	added to so that it compiles. Sorry.
+
+	* unix/tclUnixChan.c: #ifdef'd the thread-local list of file channels
+	as it prevents us from transfering channels. To restore this we may
+	need an extended interface to drivers in the future. Target:
+	9.0. Found while testing the new transfer of channels. The information
+	in this list for a channel was left behind and then crashed the system
+	during finalization.
+
+	* generic/tclThreadTest.c: Added -joinable flag to 'testthread
+	create'. Added subcommand 'testthread join'.
+
+	* doc/CrtChannel.3: Added documentation for Tcl_IsChannelRegistered,
+	Tcl_IsChannelShared, Tcl_CutChannel, Tcl_SpliceChannel,
+	Tcl_IsChannelExisting and Tcl_ClearChannelHandlers.
+
+	* doc/Thread.3: Added documentation for Tcl_JoinThread.
+
+	* tests/thread.test: Added tests for joining of threads.
+
+2000-04-27  Eric Melski  <ericm@scriptics.com>
+
+	* doc/library.n: Added entries for auto_qualify and auto_import
+	[Bug: 1271].
+
+	* doc/Init.3: Manual entry for Tcl_Init [Bug: 1820].
+
+	* doc/expr.n: Added documentation for each of the math library
+	functions that expr supports [Bug: 1054].
+
+2000-04-26  Eric Melski  <ericm@scriptics.com>
+
+	* doc/memory.n: Man page for Tcl "memory" command, which is created
+	when TCL_MEM_DEBUG is defined at compile time.
+
+	* doc/TCL_MEM_DEBUG.3: Man page with overall information about
+	TCL_MEM_DEBUG usage.
+
+	* doc/DumpActiveMemory.3: Man page for Tcl_DumpActiveMemory,
+	Tcl_InitMemory, and Tcl_ValidateAllMemory [Bug: 1816, 1835].
+
+	* generic/tclCkalloc.c: Fixed some function headers.
+
+	* unix/mkLinks: Regen'd with new mkLinks.tcl.
+
+	* unix/mkLinks.tcl: Fixed indentation, made link setup more
+	intelligent (only do one existance test per man page, instead of one
+	per function).
+
+	* doc/library.n: Fixed .SH NAME macro to include each function
+	documented on the page, so that mkLinks will know about the functions
+	listed there, and so that the Windows help file index will get set up
+	correctly [Bug: 1898, 5273].
+
+2000-04-26  Jeff Hobbs  <hobbs@scriptics.com>
+
+	8.3.1 RELEASE
+
+	* README:
+	* mac/README:
+	* tools/tcl.wse.in:
+	* unix/README:
+	* unix/tcl.spec:
+	* win/README:
+	* win/README.binary: Updating URLs to reference dev.scriptics.com
+
+2000-04-25  Jeff Hobbs  <hobbs@scriptics.com>
+
+	* unix/Makefile.in:
+	* win/Makefile.in:
+	* win/makefile.vc: updated for http change and some cleanup
+	* library/http2.[13]: moved dir http2.1 to http2.3 to match version
+
+	* doc/Utf.3: clarified docs for Tcl_(UniChar|Utf)AtIndex
+
+	* unix/tclUnixThrd.c: removed {}s around PTHREAD_MUTEX_INITIALIZER
+	[Bug: 5254]
+
+	* unix/tclLoadDyld.c (TclpLoadFile): removed use of interp->result
+
+2000-04-25  Eric Melski  <ericm@scriptics.com>
+
+	* unix/mkLinks:
+	* doc/AddErrInfo.3: Added information about Tcl_LogCommandInfo
+	[Bug: 1818].
+
+2000-04-24  Eric Melski  <ericm@scriptics.com>
+
+	* unix/mkLinks:
+	* doc/OpenFileChnl.3: Added man entry for Tcl_Ungets [Bug: 1834].
+
+	* unix/mkLinks:
+	* doc/SourceRCFile.3: Man page for Tcl_SourceRCFile [Bug: 1833].
+
+	* unix/mkLinks:
+	* doc/ParseCmd.3: Added documentation for Tcl_ParseVar [Bug: 1828].
+
+2000-04-24  Jeff Hobbs  <hobbs@scriptics.com>
+
+	* unix/tclUnixNotfy.c (Tcl_FinalizeNotifier, NotifierThreadProc):
+	added write of 'q' into triggerPipe for notifier in threaded case, so
+	that Tcl doesn't hang when children are still running [Bug: 4139]
+
+	* unix/tclUnixThrd.c (Tcl_MutexLock): minor comment fixes.
+
+2000-04-23  Jim Ingham  <jingham@cygnus.com>
+
+	These changes make some error handling marginally better for Mac
+	sockets. It is still somewhat flakey, however.
+
+	* mac/tclMacSock.c (TcpClose): Add timeouts to the close - these don't
+	seem to be honored, however. Use a separate PB for the release, since
+	an async connect socket will still be using the original buffer. Make
+	sure TCPRelease returns noErr before freeing the recvBuff. If the call
+	returns an error, then the buffer is not right.
+	* mac/tclMacSock.c (CreateSocket): Add timeouts to the async create.
+	These don't seem to trigger, however. Sigh...
+	* mac/tclMacSock.c (WaitForSocketEvent): If an TCP_ASYNC_CONNECT
+	socket errors out, then return EWOULDBLOCK & error out.
+	* mac/tclMacSock.c (NotifyRoutine): Added a NotifyRoutine for
+	experimenting with MacTCP.
+
+2000-04-22  Jim Ingham <jingham@cygnus.com>
+
+	* library/package.tcl (tclPkgUnknown): Fixed a typo in the Mac package
+	search part of tclPkgUnknown.
+
+2000-04-21  Sandeep Tamhankar <sandeep@scriptics.com>
+
+	* library/http2.1/http.tcl: Fixed a newly introduced bug where if
+	there's a -command callback and something goes wrong, geturl threw an
+	exception, called the callback, and unset the token. I changed it so
+	that it will not call the callback when throwing an exception (so the
+	caller only finds out about a given error from one place).  Also,
+	fixed http::ncode so that it actually gives you back the http return
+	code (i.e. 200, 404, etc.) instead of the first digit of the version
+	of HTTP being used (i.e. 1).
+
+2000-04-21  Brent Welch <welch@scriptics.com>
+
+	* library/http2.1/http.tcl: More thrashing with the "server closes
+	without reading post data" scenario. Reverted to the previous filevent
+	configuratiuon, which seems to work better with small amounts of post
+	data.
+
+2000-04-20  Jeff Hobbs  <hobbs@scriptics.com>
+
+	* generic/tclAlloc.c: wrapped caddr_t define to not be done on Unix
+	* unix/tclUnixPort.h: added Tclp*Alloc defines to allow the use of
+	USE_TCLALLOC on Unix. [Bug: 4731]
+
+2000-04-19  Jeff Hobbs  <hobbs@scriptics.com>
+
+	* library/dde1.1/pkgIndex.tcl:
+	* library/reg1.0/pkgIndex.tcl:
+	* win/tclWinChan.c:
+	* win/tclWinThrd.c: converted CRLF to LF the */tcl.hpj.in files were
+	not converted, as it confuses hcw locally. [Bug: 5096]
+
+	* win/Makefile.in: expanded cleanup target for help files
+
+	* doc/Thread.3: minor macro cleanup
+
+	* generic/tclFileName.c (SplitUnixPath): added support for QNX node
+	ids.
+
+2000-04-18  Jeff Hobbs  <hobbs@scriptics.com>
+
+	* README:
+	* generic/tcl.h:
+	* tools/tcl.wse.in:
+	* unix/configure.in:
+	* unix/tcl.spec:
+	* win/configure.in:
+	* win/README.binary: bumped version to 8.3.1
+
+	* win/tcl.hpj.in: updated copyright date
+
+	* generic/tclEnv.c: environment support for Mac OS/X
+	* unix/tclUnixPort.h: environment support for Mac OS/X
+	* unix/tclLoadDyld.c: new file for Mac OS/X dl functions
+	* unix/Makefile.in: added install-strip target; bindir, libdir,
+	mandir, includedir vars; tclLoadDyld.c target [Bug: 2527]
+
+	* unix/tclUnixChan.c (CreateSocket): force a socket back into blocking
+	mode (default state) after a -async connect succeeds. [Bug: 4388]
+
+	* generic/tclEvent.c (TclInitSubsystems): Moved tclLibraryPath to
+	thread-local storage to prevent thread-related race condition.
+	[Bug: 5033]
+	* unix/tclAppInit.c (main): removed #ifdef TCL_TEST that sets the
+	library path as it was unnecessary and conflicts with move of
+	tclLibraryPath to thread-local storage.
+
+2000-04-18  Scott Redman  <redman@scriptics.com>
+
+	* win/Makefile.in:
+	* win/tcl.rc:
+	* win/tclsh.rc:
+	* win/tclsh.ico:  Modified copyright dates in Windows resource files.
+	Added an icon for tclsh.exe.
+
+2000-04-17  Brent Welch <welch@scriptics.com>
+
+	* generic/tcl.h, generic/tclThreadTest.c, unix/tclUnixThrd.c,
+	* win/tclWinThread.c, mac/tclMacThread.c: Added Tcl_CreateThreadType
+	and TCL_RETURN_THREAD_TYPE macros for declaring the NewThread callback
+	proc.
+
+2000-04-14  Jeff Hobbs  <hobbs@scriptics.com>
+
+	* unix/tclUnixChan.c (TtyParseMode): Only allow setting mark/space
+	parity on platforms that support it [Bug: 5089]
+
+	* generic/tclBasic.c (Tcl_GetVersion): adjusted use of major/minor to
+	not conflict with global decl on some systems [Bug: 2882]
+
+	* doc/AppInit.3:
+	* doc/Async.3:
+	* doc/BackgdErr.3:
+	* doc/CrtChannel.3:
+	* doc/CrtInterp.3:
+	* doc/CrtMathFnc.3:
+	* doc/DString.3:
+	* doc/Eval.3:
+	* doc/ExprLong.3:
+	* doc/GetInt.3:
+	* doc/GetOpnFl.3:
+	* doc/Interp.3:
+	* doc/LinkVar.3:
+	* doc/OpenFileChnl.3:
+	* doc/OpenTcp.3:
+	* doc/PkgRequire.3:
+	* doc/RecordEval.3:
+	* doc/SetResult.3:
+	* doc/SplitList.3:
+	* doc/StaticPkg.3:
+	* doc/TraceVar.3:
+	* doc/Translate.3:
+	* doc/UpVar.3:
+	* doc/load.n: removed or updated references to interp->result use.
+
+2000-04-13  Jeff Hobbs  <hobbs@scriptics.com>
+
+	* doc/regexp.n: doc clarification [Bug: 5037]
+	* doc/update.n: typo fix [Bug: 4996]
+
+	* unix/tcl.m4 (SC_ENABLE_THREADS): enhanced the detection of
+	pthread_mutex_init [Bug: 4359] and (SC_CONFIG_CFLAGS) added
+	--enable-64bit-vis switch for Sparc VIS compilation [Bug: 4995]
+
+2000-04-12  Jeff Hobbs  <hobbs@scriptics.com>
+
+	* doc/dde.n: corrected dde poke docs. [Bug: 4991]
+
+2000-04-11  Eric Melski  <ericm@scriptics.com>
+
+	* win/tclWinPipe.c: Added "CONST" keyword to declaration of char
+	*native in TclpCreateTempFile, to supress compiler warnings.
+
+2000-04-10  Brent Welch <welch@scriptics.com>
+
+	* generic/tcl.h: Fixed Tcl_CreateThread declaration.
+	* library/tcltest1.0/tcltest.tcl: Fixed the "mainThread"
+	initialization to work with either testthread or the thread extension
+	* unix/tclUnixThrd.c: Fixed compiler warning when compiling with
+	-DTCL_THREADS
+
+2000-04-10  Eric Melski  <ericm@scriptics.com>
+
+	* win/tclWinPipe.c (TclpCreateTempFile): Added conversion of contents
+	string from UTF to native encoding [Bug: 4030].
+
+	* tests/regexp.test: Added tests for infinite looping in [regexp
+	-all].
+
+	* generic/tclCmdMZ.c: Fixed infinite loop bug with [regexp -all]
+	[Bug: 4981].
+
+	* tests/*.test: Changed all occurances of "namespace import
+	::tcltest" to "namespace import -force ::tcltest" [Bug: 3948].
+
+2000-04-09  Brent Welch <welch@scriptics.com>
+
+	* lib/httpd2.1/http.tcl: Worked on the "server closes before reading
+	post data" case, which unfortunately causes different error cases on
+	Solaris, which can read the reply, and Linux and Windows, which cannot
+	read anything. This is all in the loop-back case - client and server
+	on the same host. Also unified the error handling so the "ioerror"
+	status goes away and errors are reflected in a more uniform way.
+	Updated the man page to document the behavior.
+
+2000-04-09  Jeff Hobbs  <hobbs@scriptics.com>
+
+	* tests/reg.test (matchexpected): corrected tests to use tcltest
+	constraint types to skip certain tests.
+
+	* generic/tclBasic.c (Tcl_SetCommandInfo): comment fix
+
+	* unix/tclUnixThrd.c (Tcl_CreateThread): moved TCL_THREADS ifdef
+	inside of func as it is declared for non-threads builds as well. In
+	the non-threads case, it always returns TCL_ERROR (couldn't create
+	thread).
+
+2000-04-08  Andreas Kupries <a.kupries@westend.com>
+
+	* Overall change: Definition of a public API for the creation of
+	new threads.
+
+	* generic/tclInt.h (line 1802f): Removed the definition of
+	'TclpThreadCreate'. (line 793f) Removed the definition of
+	'Tcl_ThreadCreateProc'.
+
+	* generic/tcl.h (line 388f): Readded the definition of
+	'Tcl_ThreadCreateProc'. Added Win32 stuff send in by David Graveraux
+	<davygrvy@bigfoot.com> to that too (__stdcall, ...). Added macros for
+	the default stacksize and allowed flags.
+
+	* generic/tcl.decls (line 1356f): Added definition of
+	'Tcl_CreateThread', slot 393 of the stub table. Two new arguments in
+	the public API, for stacksize and flags.
+
+	* win/tclWinThrd.c:
+	* mac/tclMacThrd.c: Renamed TclpThreadCreate to Tcl_CreateThread,
+	added handling of the stacksize. Flags are currently ignored.
+
+	* unix/tclUnixThrd.c: See above, but handles joinable flag. Ignores
+	the specified stacksize if the macro HAVE_PTHREAD_ATTR_SETSTACKSIZE is
+	not defined.
+
+	* generic/tclThreadTest.c (line 363): See below.
+
+	* unix/tclUnixNotfy.c (line 210): Adapted to the changes above. Uses
+	default stacksize and no flags now.
+
+	* unic/tcl.m4 (line 382f): Added a check for
+	'pthread_attr_setstacksize' to detect platforms not implementing this
+	feature of pthreads. If it is implemented, configure will define the
+	macro HAVE_PTHREAD_ATTR_SETSTACKSIZE (See unix/tclUnixThrd.c too).
+
+	* doc/Thread.3: Added Tcl_CreateThread and its arguments to the list
+	of described functions. Removed stuff about not providing a public
+	C-API for thread-creation.
+
+2000-04-07  Jeff Hobbs  <hobbs@scriptics.com>
+
+	* doc/binary.n: clarified docs on sign extension in binary scan [Bug:
+	3466]
+
+	* library/tcltest1.0/tcltest.tcl (initConstraints): removed win32s
+	references (no longer supported)
+
+	* tests/fCmd.test: marked test 8.1 knownBug because it is dangerous on
+	poorly configured systems [Bug: 3881] and added 8.2 to keep essence of
+	8.1 tested.
+
+2000-04-05  Andreas Kupries <a.kupries@westend.com>
+
+	* generic/tclIO.c (Tcl_UnstackChannel, line 1831): Forcing interest
+	mask to the correct value after an unstack and re-initialization of
+	the notifier via the watchProc. Without this the first fileevent after
+	an unstack will come through and be processed, but no more. [Bug: ??].
+
+2000-03-04  Brent Welch  <welch@scriptics.com>
+
+	* {win,unix}/Makefile.in: added dependency of tclStubInit.c on
+	tcl.decls and tclInt.decls
+	* generic/tclThread.c: Tweak so this compiles w/out TCL_THREADS
+	* generic/{tcl.decls,tclStubInit.c}:  Just touched the tcl.decls and
+	regenerated the tclStubInit.c file
+
+2000-03-29  Sandeep Tamhankar <sandeep@scriptics.com>
+
+	* library/http2.1/http.tcl: For the -querychannel option, fconfigure
+	the socket to be binary so that we don't translate anything while
+	reading the data. This is because we determine the content length of
+	the data on the channel by using seek (to the end of the file) and
+	tell on the file handle, and we need the content-length to match the
+	amount of data actually sent, and translation can affect the number of
+	bytes posted.
+
+2000-04-03  Andreas Kupries <a.kupries@westend.com>
+
+	* Overall change: Definition of public API's for the finalization of
+	conditions and mutexes. [Bug: 4199].
+
+	* generic/tclInt.h: Removed definitions of TclFinalizeMutex and
+	TclFinalizeCondition.
+
+	* generic/tcl.decls: Added declarations of Tcl_MutexFinalize and
+	Tcl_ConditionFinalize.
+
+	* generic/tclThread.c: Renamed TclFinalizeMutex to Tcl_MutexFinalize.
+	Renamed TclFinalizeCondition to Tcl_ConditionFinalize.
+
+	* generic/tclNotify.c: Changed usage of TclFinalizeMutex to
+	Tcl_MutexFinalize.
+
+	* unix/tclUnixNotfy.c:
+	* generic/tclThreadTest.c: Changed usages of TclFinalizeCondition to
+	Tcl_ConditionFinalize.
+
+	* generic/tcl.h: Added empty macros for Tcl_MutexFinalize and
+	Tcl_ConditionFinalize, to be used when the core is compiled without
+	threads.
+
+	* doc/Thread.3:	Added description the new API's.
+
+2000-04-03  Jeff Hobbs  <hobbs@scriptics.com>
+
+	* generic/tclCmdIL.c (InfoVarsCmd): checked for non-NULL procPtr to
+	prevent itcl info override crash [Bug: 4064]
+
+	* tests/foreach.test:
+	* tests/namespace.test:
+	* tests/var.test: Added lsorts to avoid random sorted return
+	problems. [Bug: 2682]
+
+	* tests/fileName.test: fixed 14.1 test fragility [Bug: 1482]
+
+	* tools/man2help2.tcl: fixed winhelp cross-linking error [Bug: 4156]
+	improved translation to winhelp [Bug: 3679]
+
+	* unix/Makefile.in (MAN_INSTALL_DIR): patch to accept --mandir
+	correctly [Bug: 4085]
+
+	* unix/dltest/pkg[a-e].c: Cleaned up test packages [Bug: 2293]
+
+2000-04-03  Eric Melski  <ericm@scriptics.com>
+
+	* unix/tclUnixFCmd.c (SetGroupAttribute):
+	* unix/tclUnixFCmd.c (SetOwnerAttribute): Added (uid_t) and (gid_t)
+	casts to avoid compiler warnings.
+
+2000-03-31  Eric Melski  <ericm@scriptics.com>
+
+	* generic/tclGet.c (Tcl_GetDouble): Added additional conditions to
+	error test (previously only errno was checked, but the return value of
+	strtod() should be checked as well). [Bug: 4118]
+
+	* tests/exec.test: Added test for proper conversion of UTF data when
+	used with "<< $dataWithUTF" on exec's.
+
+	* unix/tclUnixPipe.c (TclpCreateTempFile): Added
+	Tcl_UtfToExternalDString call, so that if there is UTF content in the
+	string it will be properly converted to the system encoding before
+	being written [Bug: 4030].
+	(TclpCreateTempFile): Added a check on the return value of tmpnam;
+	some systems (Linux, for example) will start to return NULL after
+	tmpnam has been called TMP_MAX times; not checking for this can have
+	bad results (overwriting temp files, core dumps, etc.)
+
+2000-03-30  Jeff Hobbs  <hobbs@scriptics.com>
+
+	* generic/tclBasic.c (Tcl_DeleteCommandFromToken): Added comments
+	noting the need to pair ckalloc with ckfree. [Bug: 4262]
+
+	* generic/tclInt.decls:
+	* generic/tclIntPlatDecls.h:
+	* generic/tclStubInit.c:
+	* win/tclWin32Dll.c: removed TclWinSynchSpawn (vestige of Win32s
+	support).
+
+	* win/tclWinReg.c: made use of TclWinGetPlatformId instead of getting
+	info again
+
+	* win/tclWinPort.h:
+	* win/Makefile.in:
+	* win/configure.in:
+	* win/tcl.m4: Added support for gcc/mingw on Windows [Bug: 4234]
+
+2000-03-29  Jeff Hobbs  <hobbs@scriptics.com>
+
+	* generic/tclCompile.c (TclCleanupByteCode): made ByteCode cleanup
+	more aware of TCL_BYTECODE_PRECOMPILED flagged structs (gen'd by
+	tbcload), to correctly clean them up.
+
+	* generic/tclClock.c (FormatClock): moved check for empty format
+	earlier, commented 0 result return value
+
+2000-03-29  Sandeep Tamhankar <sandeep@scriptics.com>
+
+	* library/http2.1/http.tcl: Removed an unnecessary fileevent statement
+	from the error processing part of the Write method. Also, fixed two
+	potential memory leaks in wait and reset, in which the state array
+	wasn't being unset before throwing an exception. Prior to this
+	version, Brent checked in a fix to catch a fileevent statement that
+	was sometimes causing a stack trace when geturl was called with
+	-timeout. I believe Brent's fix is necessary because TLS closes bad
+	sockets for secure connections, and the fileevent was trying to act on
+	a socket that no longer existed.
+
+2000-03-27  Jeff Hobbs  <hobbs@scriptics.com>
+
+	* tests/httpd: removed unnecessary 'puts stderr "Post Dispatch"'
+
+	* tests/namespace.test:
+	* generic/tclNamesp.c (Tcl_Export): added a uniq'ing test to the
+	export list so only one instance of each export pattern would exist in
+	the list.
+
+	* generic/tclExecute.c (TclExecuteByteCode): optimized case for the
+	empty string in ==/!= comparisons
+
+2000-03-27  Eric Melski  <ericm@scriptics.com>
+
+	* unix/tclUnixChan.c: Added (off_t) type casts in lseek() call [Bug:
+	4409].
+
+	* unix/tclLoadAout.c:
+	* unix/tclUnixPipe.c: Added (off_t) type casts in lseek() calls [Bug:
+	4410].
+
+2000-03-22  Sandeep Tamhankar <sandeep@scriptics.com>
+
+	* library/http2.1/http.tcl: Fixed a bug where string query data that
+	was bigger than queryblocksize would get duplicate characters at block
+	boundaries.
+
+2000-03-22  Sandeep Tamhankar <sandeep@scriptics.com>
+
+	* library/http2.1/http.tcl: Fixed bug 4463, where we were getting a
+	stack trace if we tried to publish a project to a good host but a port
+	where there was no server listening.  It turned out the problem was a
+	stray fileevent that needed to be cleared.  Also, fixed a bug where
+	http::code could stack trace if called on a bad token (one which
+	didn't represent a successful geturl) by adding an http element to the
+	state array in geturl.
+
+2000-03-21  Eric Melski  <ericm@scriptics.com>
+
+	* tests/clock.test: Modified some tests that were not robust with
+	respect to the time zone in which they were run and were thus failing.
+
+	* doc/clock.n: Clarified meaning of -gmt with respect to -base when
+	used with [clock scan] (-gmt does not affect the interpretation of
+	-base).
+
+2000-03-19  Sandeep Tamhankar <sandeep@scriptics.com>
+
+	* library/http2.1/http.tcl: geturl used to throw an exception when the
+	connection failed; I accidentally returned a token with the error
+	info, breaking backwards compatibility. I changed it back to throwing
+	an exception, but unsetting the state array first (thus still
+	eliminating the original memory leak problem).
+
+2000-03-19  Sandeep Tamhankar <sandeep@scriptics.com>
+
+	* library/http2.1/http.tcl: Added -querychannel option and altered
+	some of Brent's modifications to allow asynchronous posts (via
+	-command). Also modified -queryprogress so that it calls the query
+	callback as <callback> <token> <total size> <current size> to be
+	consistent with -progress. Added -queryblocksize option with default
+	8192 bytes for post blocksize. Fixed a bunch of potential memory leaks
+	for the case when geturl receives bad args or can't open a socket,
+	etc. Overall, the package really rocks now.
+
+	* doc/http.n: Added -queryblocksize, -querychannel, and
+	-queryprogress. Also, changed the description of -blocksize, which
+	states that the -progress callback will be called for each block, to
+	now qualify that with an "if -progress is specified".
+
+	* tests/http.test: Added a querychannel test for synchronous and
+	asynchronous posts, altered the queryprogress test such that the
+	callback conforms to the -progress format. Also, had to use the
+	-queryblocksize option to do the post 16K at a time to match Brent's
+	expected results (and to test that -queryblocksize works).
+
+2000-03-15  Brent Welch <welch@scriptics.com>
+
+	* library/http2.1/http.tcl: Added -queryprogress callback to
+	http::geturl and also changed it so that writing the post data is
+	event driven if the queryprogress callback or a timeout is given.
+	This allows a timeout to occur when writing lots of post data. The
+	queryprogress callback is called after each block of query data is
+	posted. It has the same signature as the -progress callback.
+
+2000-03-06  Eric Melski  <ericm@scriptics.com>
+
+	* library/package.tcl: Applied patch from Bug: 2570; rather than
+	setting geometry of slave interp to 0x0 when Tk was loaded, it now
+	does "wm withdraw .". Both remove the main window from the display,
+	but the former caused some internal structures to get initialized to
+	zero, which caused crashes with some extensions.
+
+2000-03-02  Jeff Hobbs  <hobbs@scriptics.com>
+
+	* library/package.tcl (tclPkgUnknown): extended to allow recognizes
+	changes in the auto_path while sourcing in other pkgIndex.tcl files
+
+	* doc/FindExec.3: fixed doc for declaration of Tcl_FindExecutable
+	[Bug: 4275]
+
+	* generic/tclFileName.c (Tcl_TranslateFileName): Applied patch from
+	Newman to significantly speedup file split/join on Windows (replaces
+	regexp with custom parser). [Bug: 2867]
+
+	* win/README.binary: change mailing lists from @consortium.org to
+	@scriptics.com [Bug: 4173]
+
+2000-02-28  Eric Melski  <ericm@scriptics.com>
+
+	* tests/clock.test: Added test for ISO bases < 100000
+
+	* generic/tclDate.c: (generated on Solaris)
+	* generic/tclGetDate.y: Changed condition for deciding if a number is
+	an ISO 8601 base from number >= 100000 to numberOfDigits >= 6.
+	Previously it would fail to recognize 000000 as an ISO base.
+
+2000-02-14  Eric Melski  <ericm@scriptics.com>
+
+	* unix/Makefile.in: Added rpm target to generate Tcl binary RPM.
+
+	* unix/tcl.spec: RPM specification file for a Tcl binary RPM for
+	Linux.
+
+2000-02-10  Jeff Hobbs  <hobbs@scriptics.com>
+
+	8.3.0 RELEASE
+
+	* changes: updated for 8.3.0 release
+
+	* doc/load.n: added notes about dll load errors on Windows
+
+	* unix/README:
+	* unix/Makefile.in (dist): removed porting.notes and porting.old from
+	distribution and CVS.  The information was very outdated. Now refer to
+	http://dev.scriptics.com/services/support/platforms.html
+
+	* tests/unixInit.test: fixed japanese LANG encoding test [Bug: 3549]
+
+	* unix/configure.in:
+	* unix/tcl.m4: correct CFLAG_WARNING setting, fixed gcc config for
+	AIX, added -export-dynamic to LDFLAGS for FreeBSD-3+ [Bug: 2998]
+
+	* win/tclWinLoad.c (TclpLoadFile): improved error message for load
+	failures, could perhaps be even more intelligent.
+
+2000-02-09  Jim Ingham	 <jingham@cygnus.com>
+
+	* mac/tclMacSock.c: Don't panic when you get an error closing an async
+	socket. This doesn't seem to hurt anything, and we return the error so
+	the caller can do the right thing.
+
+	New Files:
+	* mac/MW_TclHeader.h:
+	* mac/MW_TclTestHeader.h:
+	* mac/MW_TclTestHeader.pch:
+	* mac/MW_TclAppleScriptHeader.h: More convenient to use .h prefix
+	files in the preference panels...
+
+	The above are curtesy of Daniel Steffen (steffen@math.mq.edu.au)
+
+2000-02-08  Eric Melski  <ericm@scriptics.com>
+
+	* tests/clock.test: Added tests for "next monthname" constructs.
+	* generic/tclDate.c:
+	* generic/tclGetDate.y (Message): Added a grammar rule for "next
+	monthname" so that we can handle "next january" and similar constructs
+	(bug #4146).
+
+2000-02-08  Jeff Hobbs  <hobbs@scriptics.com>
+
+	* README:
+	* tools/tcl.wse.in:
+	* unix/configure.in:
+	* win/configure.in:
+	* win/README:
+	* win/README.binary:
+	* generic/tcl.h (TCL_RELEASE_SERIAL): Moved to 8.3.0 patchlevel
+
+	* doc/library.n:
+	* library/auto.tcl: fixed crufty puts code and docs [Bug: 4122]
+
+	* library/tcltest1.0/tcltest.tcl: correctly protected searchDirectory
+	list to allow dirnames with spaces
+
+	* unix/tcl.m4: changed all -fpic to -fPIC
+
+	* generic/tclDecls.h:
+	* generic/tcl.decls: change Tcl_GetOpenFile to use decl of 'int
+	forWriting' instead of 'int write' to avoid shadowing [Bug: 4121]
+
+	* tests/httpold.test: changed test script to source in the httpd
+	server procs from httpd instead of having its own set.
+
+	* tests/httpd: improved query support in test httpd to handle fix in
+	http.tcl. [Bug: 4089 change 2000-02-01]
+
+	* unix/README: fixed notes about --enable-shared and add note about
+	--disable-shared.
+
+2000-02-07  Eric Melski  <ericm@scriptics.com>
+
+	* tests/package.test:
+	* library/tclIndex:
+	* library/package.tcl: Renamed ::package namespace to ::pkg.
+
+2000-02-03  Eric Melski <ericm@scriptics.com>
+
+	* doc/Package.n:
+	* doc/packagens.n: Renamed Package.n -> packagens.n because Windows
+	can't deal with case-sensitive names.
+
+2000-02-02  Jeff Hobbs  <hobbs@scriptics.com>
+
+	* tests/regexp.test: added tests for -all and -inline switches
+	* doc/regexp.n: added docs for -all and -inline switches
+	* generic/tclCmdMZ.c (Tcl_RegexpObjCmd): added extra comments for new
+	-all and -inline switches to regexp command
+
+2000-02-01  Eric Melski  <ericm@scriptics.com>
+
+	* library/init.tcl: Applied patch from rfe 1734 regarding auto_load
+	errors not setting error message and errorInfo properly.
+
+2000-02-01  Jeff Hobbs  <hobbs@scriptics.com>
+
+	* win/Makefile.in (install-*): reduced verbosity of install
+
+	* generic/tclFileName.c (Tcl_JoinPath): improved support for special
+	QNX node id prefixes in pathnames [Bug: 4053]
+
+	* library/http1.0/http.tcl:
+	* library/http2.1/http.tcl: The query data POSTed was newline
+	terminated when it shouldn't be altered [Bug: 4089]
+
+2000-01-31  Eric Melski  <ericm@scriptics.com>
+
+	* tests/package.test:
+	* library/tclIndex:
+	* library/package.tcl: Added ::package namespace and ::package::create
+	function.
+
+	* library/init.tcl: Fixed problem with auto_load and determining if
+	commands were loaded.
+
+	* library/auto.tcl: "Fixed" issues with $ in files to be auto indexed.
+
+	* doc/Package.n: New man page for package::create function.
+
+	* doc/pkgMkIndex.n: Added additional information.
+
+	* doc/library.n: Added additional qualification regarding auto_mkindex.
+
+2000-01-28  Eric Melski  <ericm@scriptics.com>
+
+	* tests/pkg/magicchar2.tcl:
+	* tests/autoMkindex.test: Test for auto loader fix (bug #2480).
+
+	* library/init.tcl: auto_load was using [info commands $name] to
+	determine if a given command was available; if the command name had *
+	or [] it, this would fail because info commands uses glob-style
+	matching. This is fixed. (Bug #2480).
+
+	* tests/pkg/spacename.tcl:
+	* tests/pkgMkIndex.test: Tests for fix for bug #2360.
+
+	* library/package.tcl: Fixed to extract only the first element of the
+	list returned by auto_qualify (bug #2360).
+
+	* tests/pkg/magicchar.tcl:
+	* tests/autoMkindex.test: Test for fix for bug #2611.
+
+	* library/auto.tcl: Fixed the regular expression that performs $
+	escaping before sourcing a file to index. It was erroneously adding \
+	escapes even to $'s that were already escaped, effectively
+	"un-escaping" those $'s. (bug #2611).
+
+2000-01-27  Eric Melski  <ericm@scriptics.com>
+
+	* tests/autoMkindex.test:
+	* library/auto.tcl: Applied patch (with slight modification) from bug
+	#2701: auto_mkIndex uses platform dependent file paths. Added test for
+	fix.
+
+2000-01-27  Jennifer Hom  <jenn@scriptics.com>
+
+	* library/tcltest1.0/tcltest.tcl: Changed NormalizePath to
+	normalizePath and exported it as a public proc. This proc creates an
+	absolute path given the name of the variable containing the path to
+	modify. The path is modified in place.
+	* library/tcltest1.0/pkgIndex.tcl: Added normalizePath.
+	* tests/all.tcl: Changed code to use normalizePath.
+
+2000-01-27  Eric Melski  <ericm@scriptics.com>
+
+	* tests/pkg/samename.tcl: test file for bug #1983
+
+	* tests/pkgMkIndex.test:
+	* doc/pkgMkIndex.n:
+	* library/package.tcl: Per rfe #4097, optimized creation of direct
+	load packages to bypass computing the list of commands added by the
+	new package. Also made direct loading the default, and added a -lazy
+	option.
+	Fixed bug #1983, dealing with pkg_mkIndex incorrectly handling
+	situations with two procs by the same name but in different namespaces
+	(ie, foo::baz and bar::baz).
+
+2000-01-26  Eric Melski  <ericm@scriptics.com>
+
+	* generic/tclNamesp.c: Undid fix for #956, which broke backwards
+	compatibility.
+
+	* doc/variable.n:
+	* doc/trace.n:
+	* doc/namespace.n:
+	* doc/info.n: Added further information about differences between
+	"namespace which" and "info exists".
+
+	* doc/SetErrno.3: Added descriptions of ErrnoId() and ErrnoMsg()
+	functions.
+
+2000-01-25  Jeff Hobbs  <hobbs@scriptics.com>
+
+	* unix/tcl.m4: modified EXTRA_CFLAGS to add -DHAVE_TZSET for OSF1-V*
+	and ULTRIX-4.* when not using gcc. Also added higher min stack size
+	for OSF1-V* when building with threads. [Bug: 4063]
+
+	* generic/tclClock.c (FormatClock): inlined resultPtr, as it
+	conflicted with var creation for HAVE_TZSET #def [Bug: 4063]
+
+	* generic/tclCmdIL.c (Tcl_LsortObjCmd): fixed potential leak when
+	calling lsort -command with bad command [Bug: 4067]
+
+	* generic/tclFileName.c (Tcl_JoinPath): added support for special QNX
+	node id prefixes in pathnames [Bug: 4053]
+
+	* doc/ListObj.3: clarified Tcl_ListObjGetElements docs [Bug: 4080]
+
+	* doc/glob.n: clarified Mac path separator determination docs.
+
+	* win/makefile.vc: added some support for building helpfile on Windows
+
+2000-01-23  Jeff Hobbs  <hobbs@scriptics.com>
+
+	* library/init.tcl (auto_execok): added 'start' to list of recognized
+	built-in commands for COMSPEC on NT. [Bug: 2858]
+
+	* unix/tclUnixPort.h: moved include of <utime.h> lower since some
+	systems (UTS) require sys/types.h to be included first [Bug: 4031]
+
+	* unix/tclUnixChan.c (CreateSocketAddress): changed comparison with -1
+	to 0xFFFFFFFF, to ensure 32 bit comparison even on 64 bit systems.
+	[Bug: 3878]
+
+	* generic/tclFileName.c: improved guessing of path separator for the
+	Mac. (Darley)
+
+	* generic/tclInt.h:
+	* generic/tcl.decls: moved Tcl_ProcObjCmd to stubs table [Bug: 3827]
+	and removed 'register' from stub definition of
+	Tcl_AppendUnicodeToObj [Bug: 4038]
+
+2000-01-21  Eric Melski  <ericm@scriptics.com>
+
+	* unix/mkLinks:
+	* doc/GetHostName.3: Man page for Tcl_GetHostName (bug #1817).
+
+	* doc/lreplace.n: Corrected man page with respect to treatment of
+	empty lists, and "prettied up" the page. (bug #1705).
+
+2000-01-20  Eric Melski  <ericm@scriptics.com>
+
+	* tests/namespace.test: Added test for undefined variables with
+	namespace which (bug #956).
+
+	* generic/tclNamesp.c: Added check for undefined variables in
+	NamespaceWhichCmd (bug #956).
+
+	* tests/var.test: Added tests for corrected variable behavior (bug
+	#981).
+
+	* doc/upvar.n: Expanded explanation of upvar behavior with respect to
+	variable traces. (bugs 3917 1433 2110).
+
+	* generic/tclVar.c: Changed behavior of variable command when name
+	refers to an element in an array (ie, "variable foo(x)") to always
+	return an error, regardless of existance of that element in the array
+	(now behavior is consistant with docs too) (bug #981).
+
+2000-01-20  Jeff Hobbs  <hobbs@scriptics.com>
+
+	* generic/tclCmdIL.c (InfoBodyCmd): made [info body] return a string
+	if the body has been bytecompiled.
+	* generic/tclBasic.c (Tcl_EvalObjEx): added pedantic check for
+	originating proc body of bytecompiled code, #def'd out as the change
+	for [info body] should make it unnecessary
+
+	* unix/tclUnixNotfy.c (Tcl_InitNotifier): added cast for tsdPtr
+
+	* tests/set.test: added test for complex array elem name compiling
+	* generic/tclCompCmds.c (TclCompileSetCmd): Fixed parsing of array
+	elements during compiling, and slightly optimised same [Bug: 3889]
+
+	* doc/tclvars.n: added definitions for tcl_(non)wordchars
+
+	* doc/vwait.n: added notes about requirement for vwait var being
+	globally scoped [Bug: 3329]
+
+	* library/word.tcl: changed tcl_(non)wordchars settings to use new
+	unicode regexp char class escapes instead of char sequences
+
+2000-01-14  Eric Melski  <ericm@scriptics.com>
+
+	* tests/var.test: Added a test for the array multiple delete
+	protection in Tcl_UnsetVar2.
+
+	* generic/tclVar.c: Added protection in Tcl_UnsetVar2 against attempts
+	to multiply delete arrays when unsetting them (bug #3453). This could
+	happen if there was an unset trace on an array element and the trace
+	proc made a global or upvar link to the array, and then the array was
+	unset at the global level. See the bug reference for more information.
+
+	* unix/tclUnixTime.c: New clock format format.
+
+	* compat/strftime.c: New clock format format.
+
+	* generic/tclGetDate.y: New clock scan format.
+
+2000-01-13  Jeff Hobbs  <hobbs@scriptics.com>
+
+	* changes: updated changes file to reflect 8.3b2 mods
+
+	* README:
+	* generic/tcl.h:
+	* tools/tcl.wse.in:
+	* unix/configure.in:
+	* unix/tcl.m4:
+	* win/README.binary:
+	* win/configure.in: updated to patchlevel 8.3b2
+
+	* generic/regexec.c: added var initialization to prevent compiler
+	warning
+
+2000-01-13  Eric Melski  <ericm@scriptics.com>
+
+	* tests/cmdIL.test: Added tests for lsort -dictionary with characters
+	that occur between Z and a in ASCII.
+
+	* generic/tclCmdIL.c: Modified DictionaryCompare function (used by
+	lsort -dictionary) to do upper/lower case equivalency before doing
+	character comparisons, instead of after. This fixes bug #1357, in
+	which lsort -dictionary [list ` AA c CC] and lsort -dictionary [list
+	AA c ` CC] gave different (and both wrong) results.
+
+2000-01-12  Eric Melski  <ericm@scriptics.com>
+
+	* tests/clock.test: Added tests for "next <day-of-week>" and
+	"<day-of-week>"
+	Added tests for "monday 1 week ago", etc, from RFE #3671.
+
+	* doc/tests/clock.test: Added numerous tests for clock scan.
+
+	* doc/generic/tclGetDate.y: Fixed some shift/reduce conflicts in clock
+	grammar.
+
+	* doc/doc/clock.n: Added documentation for new supported clock scan
+	formats and additional explanation of daylight savings time correction
+	algorithm.
+
+2000-01-12  Jeff Hobbs  <hobbs@scriptics.com>
+
+	* doc/file.n:
+	* tests/unixFCmd.test:
+	* unix/tclUnixFCmd.c: added support for symbolic permissions setting
+	in SetPermissionsAttribute (file attr $file -perm ...) [Bug: 3970]
+
+	* generic/tclClock.c: fixed support for 64bit handling of clock values
+	[Bug: 1806]
+
+	* generic/tclThreadTest.c: upped a buffer size to hold double
+
+	* tests/info.test:
+	* generic/tclCmdIL.c: fixed 'info procs ::namesp::*' behavior (Dejong)
+
+	* generic/tclNamesp.c: made imported commands also import their
+	compile proc [Bug: 2100]
+
+	* tests/expr.test:
+	* unix/Makefile.in:
+	* unix/configure.in:
+	* unix/tcl.m4: recognize strtod bug on Tru64 v5.0 [Bug: 3378] and
+	added tests to prevent unnecessary chmod +x in sources while
+	installing, as well as more intelligent setsockopt/gethostbyname
+	checks [Bug: 3366, 3389]
+
+	* unix/tclUnixThrd.c: added compile time support (through use of the
+	TCL_THREAD_STACK_MIN define) for increasing the default stack size for
+	a thread. [Bug: 3797, 1966]
+
+2000-01-11  Eric Melski  <ericm@scriptics.com>
+
+	* generic/tclGetDate.y: Added comments for the Convert function. Added
+	a fix for daylight savings time handling for relative time spans of
+	days, weeks or fortnights. (bug 3441, 3868).
+
+	* generic/tclDate.c: Fixed compiler warning issues.
+
+2000-01-10  Jeff Hobbs  <hobbs@scriptics.com>
+
+	* compat/waitpid.c: use pid_t type instead of int [Bug: 3999]
+
+	* tests/utf.test: fixed test that allowed \8 as octal value
+	* generic/tclUtf.c: changed Tcl_UtfBackslash to not allow non-octal
+	digits (8,9) in \ooo substs. [Bug: 3975]
+
+	* generic/tcl.h: noted need to change win/tcl.m4 and
+	tools/tclSplash.bmp for minor version changes
+
+	* library/http2.1/http.tcl: trim value for $state(meta) key
+
+	* unix/tclUnixFile.c: fixed signature style on functions
+
+	* unix/Makefile.in: made sure tcl.m4 would be installed with dist
+
+	* unix/tcl.m4: added ELF support for NetBSD [Bug: 3959]
+
+2000-01-10  Eric Melski  <ericm@scriptics.com>
+
+	* generic/tclGetDate.y: Added rules for ISO 8601 formats (BUG #847):
+	CCYY-MM-DD
+	CCYYMMDD
+	YY-MM-DD
+	YYMMDD
+	CCYYMMDDTHHMMSS
+	CCYYMMDD HHMMSS
+	CCYYMMDDTHH:MM:SS
+	Fixed "clock scan <number>" to scan the number as an hour for the
+	current day, rather than a minute after 00:00 for the current day
+	(bug #2732).
+
+2000-01-07  Eric Melski  <ericm@scriptics.com>
+
+	* generic/tclClock.c: Changed switch in Tcl_ClockObjCmd to use
+	enumerated values instead of constants. (ie, COMMAND_SCAN instead of
+	3).
diff --git a/ChangeLog.2001 b/ChangeLog.2001
new file mode 100644
index 0000000..06e7c36
--- /dev/null
+++ b/ChangeLog.2001
@@ -0,0 +1,3629 @@
+2001-12-28  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* library/init.tcl: make sure env(COMSPEC) on Windows is executed with
+	the right case, as it may otherwise fail inexplicably.
+
+2001-12-28  Don Porter <dgp@users.sourceforge.net>
+
+	* generic/tclCkalloc.c (MemoryCmd, TclFinalizeMemorySubsystem): Added
+	the [memory onexit] command, intended to replace [checkmem].
+
+	* doc/DumpActiveMemory.3:
+	* doc/memory.n: Updated documentation for [memory] and related
+	matters. [Bug 487677]
+
+	* mac/tclMacBOAMain.c (Tcl_Main, CheckmemCmd): Removed all the
+	machinery for the [checkmem] command that is completely duplicated by
+	code in generic/tclCkalloc.c.
+
+	* generic/tclBinary.c:
+	* generic/tclListObj.c:
+	* generic/tclObj.c:
+	* generic/tclStringObj.c: Removed references to [checkmem] in
+	comments, referencing [memory active] instead, since it is
+	documented.
+
+2001-12-28  Daniel Steffen <das@users.sourceforge.net>
+
+	* mac/tclMacInit.c:
+	* mac/tclMacTclCode.r: synced up tclInit features to unix/win:
+	implemented TclSetPreInitScript support, use of existing tclInit proc
+	if defined, check of default encoding dir if set. Changed script
+	library resource names to lowercase (i.e. same as corresponding
+	files). Used Tcl_JoinPath instead of string append. Check that system
+	encoding could be loaded before utf translating the LibraryPath.
+	* mac/tclMacApplication.r:
+	* mac/tclMacLibrary.r:
+	* mac/tclMacOSA.r:
+	* mac/tclMacResource.r: minor version resources cleanup
+
+2001-12-21  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* unix/tcl.m4 (SC_PATH_TCLCONFIG, SC_PATH_TKCONFIG):
+	Search for config file using exec_prefix instead of prefix when no
+	--with-tcl or --with-tk argument is used. [Bug 492418]
+
+2001-12-21  Daniel Steffen <das@users.sourceforge.net>
+
+	* unix/tcl.m4: fixed incorrect SHLIB_LD_LIBS setting for MacOSX /
+	Darwin.
+	* unix/configure: Regen.
+	* unix/mkLinks.tcl: improved case-insensitive filesystem support.
+	* unix/mkLinks: Regen.
+
+2001-12-19  Don Porter <dgp@users.sourceforge.net>
+
+	* unix/Makefile.in (dist): corrected use of eolFix.tcl on working
+	files. It should operate on distributed files. [Bug 495120]
+
+2001-12-19  David Gravereaux <davygrvy@pobox.com>
+
+	* tools/tcl.wse.in: Fix for [Bug 495120]. tcl.wse.in was stored in cvs
+	with improper <eol>. This resulted in corrupted <eol> when checked-out
+	on translating CVS clients such as windows (CRCRLF) and mac (CRCR).
+
+2001-12-19  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* unix/configure:
+	* unix/tcl.m4 (SC_CONFIG_CFLAGS): Update SunOS 5.[0-6] target so that
+	correct linker options are passed to gcc or ld. [Tk Bug 220863]
+
+2001-12-19  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* unix/README: Update to account for changes in the unix/dltest
+	directory, the way autoconf is run, and the new "make shell" target.
+
+2001-12-19  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* unix/Makefile.in: Rename dltest to dlpkgs to fix problem where lib
+	files were not getting built because dltest/ directory already
+	existed.
+
+2001-12-19  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* win/tclWinSerial.c (SerialCheckProc): corrected time calculations to
+	be unsigned. (schroedter)
+
+2001-12-18  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* unix/Makefile.in: Define new dltest target that simply does a cd to
+	dltest/ before running make. There is no need for the separate
+	configure script that was previously being used.
+	* unix/configure: Regen.
+	* unix/configure.in: Subst into dltest/Makefile.
+	* unix/dltest/Makefile.in: Define LIBS using DL_LIBS, LIBS, and
+	MATH_LIBS variables instead of TCL_LIBS variable from tclConfig.sh.
+	* unix/dltest/README: Update readme to account for new configure free
+	implementation.
+	* unix/dltest/configure: Removed.
+	* unix/dltest/configure.in: Removed.
+
+2001-12-18  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* generic/tcl.h (TCL_STUB_MAGIC): Added cast to force type to be an
+	int and get rid of a persistent and pointless warning with SunPro
+	compiler.
+
+	* generic/tclCkalloc.c (Tcl_AttemptDbCkalloc,Tcl_AttemptDbCkrealloc):
+	* generic/tcl.decls (Tcl_AttemptDbCkalloc,Tcl_AttemptDbCkrealloc):
+	Made the file parameters to these functions into CONST char *, like
+	they always should have been to match the other Tcl*Db* API functions.
+
+2001-12-17  Andreas Kupries  <andreas_kupries@users.sourceforge.net>
+
+	* Applied [Bug 219311] on behalf of Rolf Schroedter
+	<schroedter@users.sourceforge.net> to prevent fcopy on serial ports
+	from flooding the event queue.
+
+2001-12-11  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* doc/CrtInterp.3:
+	* generic/tclBasic.c: docs and comments corrections. [Bug 493412]
+	Bug & patch by Don Porter.
+
+2001-12-14  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* win/tclWinNotify.c (Tcl_FinalizeNotifier): Stop Tcl on Windows from
+	crashing when shutdown from a non-Tcl thread. Fixes [Bug 217982]
+	[orig. 5804] reported by Hugh Vu and Gene Leache. I'm not convinced
+	that the shutdown process is right even with this, but it was
+	definitely wrong without...
+
+2001-12-13  Andreas Kupries  <andreas_kupries@users.sourceforge.net>
+
+	* win/tclWinSock.c (TcpGetOptionProc): Fix for [Bug 478565] reported
+	by an unknown person. Bypasses all calls to "gethostbyaddr" for
+	address "0.0.0.0" to prevent delays on Win/NT.
+
+2001-12-12  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* doc/Preserve.3: doc'd TCL_DYNAMIC use. [Patch 483989] (porter)
+
+2001-12-12  Andreas Kupries  <andreas_kupries@users.sourceforge.net>
+
+	* generic/tclIO.c (Tcl_GetsObj): Applied patch for [Bug 491341] as
+	provided by Don Porter <dgp@users.sourceforge.net>. Fixes the
+	assumption of having an empty Tcl_Obj to work with.
+
+2001-12-11  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* generic/tclCompCmds.c:
+	* generic/tclCompile.c:
+	* generic/tclExecute.c: consistency patch, to make all instructions
+	that pop a variable number of Tcl_Obj's off the execution stack take
+	the number of popped objects as first operand. Modified *only* the new
+	instructions INST_LIST_INDEX_MULTI and INST_LSET_FLAT, so this has no
+	effect on bytecodes generated up to tcl8.4a3 inclusive.
+
+	* generic/tclExecute.c: fix debug messages in INST_LSET_LIST.
+
+	* generic/tclCompCmds.c (TclCompileLindexCmd):
+	* generic/tclCompExpr.c (CompileMathFuncCall): removed the last two
+	overestimates of the necessary stack depth for bytecodes in the fix of
+	[Bug 483611]
+
+2001-12-10  Andreas Kupries  <andreas_kupries@users.sourceforge.net>
+
+	* unix/tclUnixPipe.c (TclpCreateProcess): Applied Don Porter's patch
+	fixing [Bug 437489].
+
+2001-12-10  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* generic/tclEvent.c:
+	* tests/event.test: fix background error reporting in the absence of a
+	bgerror proc [Bug 219142].
+
+2001-12-10  Don Porter <dgp@users.sourceforge.net>
+
+	* doc/Access.3:
+	* doc/CrtChannel.3:
+	* doc/DString.3:
+	* doc/ExprLong.3:
+	* doc/FileSystem.3:
+	* doc/GetStdChan.3:
+	* doc/OpenFileChnl.3:
+	* doc/StdChannels.3:
+	* doc/TCL_MEM_DEBUG.3:
+	* doc/Tcl_Main.3:
+	* doc/Utf.3:
+	* doc/file.n:
+	* doc/tclsh.1:  Several typo and formatting corrections discovered
+	during conversion to TMML. Thanks to Joe English. [Patch 490514]
+	* unix/mkLinks: 'make mklinks'
+
+2001-12-10  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* generic/tclCompCmds.c:
+	* generic/tclCompExpr.c:
+	* generic/tclCompile.c:
+	* generic/tclCompile.h:
+	* generic/tclExecute.c:
+	* generic/tclProc.c: fixed the calculation of the maximal stack depth
+	required by bytecodes. [Bug 483611]
+
+2001-12-07  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* generic/tclVar.c:
+	* tests/trace.test: restored consistency in refCount accounting by
+	array traces [Bug 4484339], submitted by Don Porter.
+
+2001-12-06  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* tests/parseExpr.test, tests/for.test, tests/expr.test:
+	* tests/expr-old.test, tests/compile.test, tests/compExpr.test
+	* tests/compExpr-old.test: Kept up to date with syntax errors.
+	* generic/tclParseExpr.c (ParsePrimaryExpr): Rewrote to give even
+	better syntax errors in the fairly common case of an identifier
+	without decorations by guessing based on the currently available
+	functions. Also made messages consistent between memdebug and ordinary
+	builds.
+
+2001-12-05  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* generic/tclVar.c:
+	* tests/trace.test: new algorithm for [array get], safe when there are
+	traces that modify the array. [Bug 449893]
+
+2001-12-04  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* tests/compExpr-old.test, tests/compExpr.test, tests/compile.test:
+	* tests/expr-old.test, tests/expr.test, tests/for.test:
+	* tests/while.test, tests/if.test: Rewrite to handle more specific
+	syntax errors.
+	* tests/parseExpr.test: Rewrite to get rid of dup test numbers and
+	handle more specific syntax errors.
+	* generic/tclParseExpr.c (LogSyntaxError): Added a detail message
+	argument to help explain what the syntax error is.
+	(Tcl_ParseExpr, ParseCondExpr, ParsePrimaryExpr): Added detail
+	messages.
+	(UNKNOWN_CHAR): New lexeme for characters that are always illegal in
+	expressions outside strings.
+
+2001-12-03  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* doc/expr.n: Various documentation improvements in relation to the
+	function calls. Includes fix for [Bug 487704] submitted by Devin Eyre.
+
+2001-12-03  David Gravereaux <davygrvy@pobox.com>
+
+	* win/makefile.vc: Some install target bugs repaired along with
+	$(TCLSTUBLIB) added to the dependencies rather than implicit through
+	the dde and reg extensions which don't happen to always require it for
+	some build types.
+
+2001-11-30  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* generic/tclVar.c: Tcl_Preserve'ing VarTrace structures to avoid
+	memory corruption. Patch for [Bug 484334] provided by Don Porter
+
+2001-11-29  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* tests/namespace.test: modified namespace-41.2, added 41.3
+	{knownbug} after discussion with Don Porter and Kevin Kenny.
+
+2001-11-29  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* tests/namespace.test: added namespace-41.2, a simpler test for
+	[Bug 231259]
+
+2001-11-29  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* generic/tclBinary.c (BINARY_SCAN_MAX_CACHE, Tcl_BinaryObjCmd,
+	(ScanNumber): Added caching scheme to reduce number of object
+	allocations when doing scans of large repetitive binary strings. See
+	comments in file for reasoning behind implementation. Suggested by
+	Miguel Sofer in [Patch 429916], but independently implemented.
+
+2001-11-28  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* doc/regsub.n, doc/regexp.n: Converted dangling references to
+	METASYNTAX section into references to the re_syntax manual page.
+
+2001-11-27  D. Richard Hipp   <drh@hwaci.com>
+
+	* win/tclWinFCmd.c: Fix a coredump in the filename normalizer code for
+	Win95/98.
+
+2001-11-27  David Gravereaux <davygrvy@pobox.com>
+
+	* win/makefile.vc: Removed the Tk reference for the 'winhelp' target.
+	Converge at install will need to be the solution for Tk and all other
+	extensions.
+
+2001-11-27  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* tests/cmdAH.test (cmdAH-24.2): Made test less sensitive to OS
+	preemption, but perfection isn't practical. [Bug 463189, reported by
+	Don Porter]
+
+	* tests/switch.test (switch-9.*): Added tests to exercise more of the
+	argument checking.  (switch-7.2,switch-7.3): Test changed behaviour
+	slightly.
+	* generic/tclCmdMZ.c (Tcl_SwitchObjCmd): Reworked argument parsing to
+	be stricter about what it accepts. This should make uses of the
+	[switch] command be more maintainable. [Bug 475397, reported by Don
+	Porter]
+
+2001-11-26  Don Porter <dgp@users.sourceforge.net>
+
+	* generic/tclIntPlatDecls.h: 'make genstubs' after changes in
+	2001-11-23 commit from Daniel Steffen.
+
+2001-11-24  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* unix/Makefile.in: Add comments to better describe TCL_EXE and when
+	it should be available.
+	* win/Makefile.in: Add TCL_EXE variable to be used by rules like `make
+	genstubs`. Don't set TCL_LIBRARY before running `make genstubs` since
+	we will be running with a tclsh from the PATH not the one we build.
+
+2001-11-24  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* win/configure: Regen.
+	* win/tcl.m4 (SC_CONFIG_CFLAGS): Add comctl32.lib to wish link libs.
+	This change was originally added to Tk on 2001-11-09 but was not
+	committed to Tcl.
+
+2001-11-23  Daniel Steffen <das@users.sourceforge.net>
+
+	* unix/Makefile.in:
+	* unix/configure.in:
+	* unix/install-sh:
+	* unix/mkLinks:
+	* unix/mkLinks.tcl:
+	* unix/tclLoadDyld.c:
+	* unix/tclMtherr.c: Mac OSX support: build system, dynamic code loading
+	and support for case-insensitive filesystems in mkLinks. [Patch 435258]
+
+2001-11-23  Daniel Steffen <das@users.sourceforge.net>
+
+	Up-port to 8.4 of mac code changes for 8.3.3 & various new changes for
+	8.4, some already backported to 8.3.4. [Patch 435658]
+
+	* generic/tclObj.c: added #include to fix missing prototype errors
+
+	* generic/tcl.h: MAC_TCL: addition of ConditionalMacros.h and use of
+	DLLIMPORT and DLLEXPORT like on other platforms. ( => no longer need
+	the .exp files and can remove use of #pragma export that never worked
+	well)
+	removed line continuation in #if clause as this breaks the mac
+	resource compiler (note that *.r files include tcl.h)
+
+	* mac/tclMacFile.c: fixed bug in permission checking code
+
+	* mac/tclMacLoad.c: corrected utf8 handling, comparison of package
+	names to code fragment names changed to only match on the length of
+	package name, this allows for fragment names with version numbers
+	appended.
+
+	* mac/tclMacInt.h:
+	* generic/tclInt.h:
+	* mac/tclMacTime.c:
+	* generic/tclIOUtil.c: moved declaration of TclpGetGMTOffset()
+
+	* mac/tclMacShLib.exp:
+	* mac/tclMacOSA.exp:
+	* mac/tclMacMSLPrefix.h: removed files
+
+	* unix/Makefile.in: removed reference to .exp files
+
+	* mac/MW_TclBuildLibHeader.h:
+	* mac/MW_TclBuildLibHeader.pch:
+	* mac/MW_TclHeaderCommon.h:
+	* mac/MW_TclStaticHeader.h:
+	* mac/MW_TclStaticHeader.pch: new precompiled header files
+
+	* mac/MW_TclAppleScriptHeader.pch:
+	* mac/MW_TclHeader.pch:
+	* mac/MW_TclTestHeader.pch:
+	* mac/tclMacCommonPch.h: revised precompiled header handling: now
+	include a common header file 'MW_TclHeaderCommon.h' from all .pch
+	files, the .pch files themselves now only setup #defines (e.g.
+	BUILD_tcl, STATIC_BUILD, TCL_DEBUG, TCL_THREADS) like in makefiles on
+	other platforms.
+
+	* mac/tclMac.h:
+	* mac/tclMacPort.h:
+	* mac/tclMacInt.h: use of BUILD_tcl and TCL_STORAGE_CLASS like on other
+	platforms, standardize #include'd files to what's done on other
+	platforms, removed use of #pragma export.
+
+	* mac/tcltkMacBuildSupport.sea.hqx: new archive of mac build support
+	files & suggested build environment directory hierarchy:
+	'Building MacTclTk' & 'CW Pro6 changes' readme's.
+	projects for MoreFiles 1.5.2 static & shared libraries.
+	project & sources for 'pseudoCarbonSupport', see below.
+	included XML versions of the projects for CW Pro5 or Pro7 users.
+
+	* mac/tclMacProjects.sea.hqx: updated mac build project files:
+	build support for CodeWarrior Pro6, UnivIntf 3.4 & shared runtime
+	libraries: the MSL libraries and MoreFiles are no longer compiled into
+	Tcl.shlb, all non-static binaries now use the Pro6 shared runtime
+	libraries and MoreFiles.shlb.  These shlbs are merged into the standard
+	Wish and TclShell, but 3rd party applications linking with Tcl.shlb or
+	Tk.shlb need to setup access to them.  (see the "(sh-ppc)" targets
+	for how to do this.)
+	included XML versions of the projects for CW Pro5 or Pro7 users.
+	use compat/strtod.c instead of MSL's strtod()
+	use WASTE versions of MSL for tcl test target to avoid text buffer
+	cutoff at 32k.
+	Merging the full MSL.shlb and the other shlbs into Wish & TclShell
+	makes them a bit larger than before, use unmerged binaries to avoid
+	copying the shared code with every application, e.g. when deploying
+	numerous Wish based droplets.
+	Note that using CW Pro5 to compile extensions is in principle still
+	possible, but need to link with Pro6 runtime libraries.
+	Tclapplescript now loads and runs on CFM68k.
+	Highly experimental "pseudoCarbon" support for Tcl only on OS 8/9:
+	binaries in "Build:(Carbon):" link against CarbonLib instead of
+	InterfaceLib, however the actual code has not been carbonized! i.e. it
+	will not run on OSX and may not even run properly with CarbonLib.
+	This should in principle allow you to build & test OS9 CFM Carbon
+	binaries that need to link with Tcl.shlb. On OSX you can use the
+	native Tcl.framework, but you have to build a MachO binary as there
+	is no CFM glue lib for Tcl.framework.
+	the library pseudoCarbonSupport.shlb manually loads the symbols from
+	InterfaceLib that are not in CarbonLib but are needed by the
+	uncarbonized code in Tcl.shlb and TclShell.
+
+	* generic/tclMain.c: MAC_TCL: workaround for broken/non-standard isatty
+	on MW Pro6, #include <unistd.h> instead of defining isatty
+
+	* mac/tclMacPort.h: MW Pro6 changes for MSL fcntl.h, stat.h & isatty
+
+	* mac/tclMacAppInit.c: add EXTERN to InstallConsole to enable DLL
+	export via the TCL_STORAGE_CLASS mechanism.
+
+	* mac/tclMacFCmd.c: fix for FSpDirectoryCopy API change
+
+	* mac/tclMacLibrary.c: emit compile time error when
+	TCL_REGISTER_LIBRARY and USE_TCL_STUBS are both defined at the same
+	time in an extension, this use is not currently supported and will
+	result in a crash when dynamically loading the extension.
+
+	* mac/tclMacApplication.r:
+	* mac/tclMacLibrary.r:
+	* mac/tclMacOSA.r:
+	* mac/tclMacResource.r: fixed obsolete copyrights/dates in version
+	strings; updated version strings to standard usage; added support for
+	'(Support Libraries)' subfolder for shared runtime libraries in
+	unmerged binaries; commented out demo setting of "Tcl Environment
+	Variables"; reorganized resources among these files to avoid multiple
+	copies in applications and shared libraries, the script libraries are
+	now no longer duplicated in Tclsh but are only included in the
+	resources of Tcl.shlb.
+
+	* mac/tclMacChan.c:
+	* mac/tclMacSock.c: cast for *BlockMode
+
+	* mac/tclMacUtil.c:
+	* mac/tclMacMath.h: removed obsolete hypot() definition
+
+	* generic/tclIntPlatDecls.h:
+	* generic/tclInt.decls:
+	* generic/tclStubInit.c:
+	* mac/tclMacNotify.c:
+	* mac/tclMacOSA.c:
+	* mac/tclMacUtil.c:
+	* generic/tclThreadTest.c: renamed routines conflicting with standard
+	Apple or MoreFiles headers (at compile or link time):
+	GetGlobalMouse         -> GetGlobalMouseTcl
+	FSpGetDirectoryID      -> FSpGetDirectoryIDTcl
+	FSpOpenResFileCompat   -> FSpOpenResFileCompatTcl
+	FSpCreateResFileCompat -> FSpCreateResFileCompatTcl
+	NewThread              -> NewTestThread
+	the renamed MoreFiles *Tcl routines are just wrappers calling into the
+	MoreFiles DLL.
+
+	* mac/tclMacCommonPch.h:
+	* mac/tclMacThrd.c:
+	* mac/tclMacPanic.c: removed OLDROUTINENAMES define, renamed obsolete
+	apple API names to modern equivalents; UH3.4 support: added #include
+	<ControlDefinitions.h>, updated New*Proc() calls to New*UPP().
+
+	* mac/tclMacUnix.c: added missing (Tcl_Obj ***) cast to
+	Tcl_ListObjGetElements call
+
+	* mac/tclMacAlloc.c: modernized TclpSysAlloc() to use temporary memory
+	instead of system heap memory when available (MacOS >= 7.5 and
+	possibly earlier, use of system heap has been discouraged for a long
+	time and has many disadvantages, e.g. memory isn't paged out, and
+	errors can very easily bring the system down); fixed crashing bug in
+	TclpSysRealloc() and CleanUpExitProc() where memory was being accessed
+	after having been deallocated; fixed memory leak in (de)allocation
+	code (for every block ever allocated with TclpSysAlloc, a Ptr was
+	leaked), if temporary memory is available, don't track allocated
+	memory, instead use RecoverHandle() to get Handle from Ptr, otherwise
+	use doubly linked list to correctly track memory and free all
+	allocated memory; added new option for ConfigureMemory:
+	MEMORY_DONT_USE_TEMPMEM, disables use of temporary memory even when it
+	would be available, only necessary when writing e.g. a driver (using
+	tcl??); increased fraction of application heap reserved for OS
+	routines to 512K
+
+	* compat/strftime.c:
+	* mac/tclMacTime.c:
+	* mac/tclMacPort.h:
+	* generic/tclInt.decls:
+	* generic/tclIntPlatDecls.h:
+	* generic/tclStubInit.c: timezone support for mac via TclpGetTZName()
+	like on windows, using an inverse timezone table adapted from
+	tclDate.c to map gmtoffset in seconds gotten from the MacOS APIs to a
+	timezone string, as there is no good way to get this info from MacOS.
+	I had to make up some unusual timezones and arbitrarily decide on the
+	most standard of the multiple choices available for every timezone.
+
+	* generic/tclExecute.c: workaround for a MSL bug/misfeature: for very
+	small floats, MSL can return errno ERANGE but a non-zero value (<
+	LDBL_MIN however)
+
+	* mac/tclMacAppInit.c: support for WASTE text library using temporary
+	memory, setting has no effect if WASTE is not used.
+
+	* mac/tclMacPanic.c: removed duplicate code from generic/tclPanic.c
+	and added that file to projects instead.
+
+	* tests/all.tcl: set tcltest::singleProcess 1 as multiple processes
+	are not available on the mac.
+
+	* tests/cmdAH.test: access time not available on the mac, skip the
+	atime touch test
+
+	* tests/appendComp.test:
+	* tests/cmdMZ.test:
+	* tests/compile.test:
+	* tests/exec.test:
+	* tests/fileName.test:
+	* tests/lset.test:
+	* tests/namespace.test:
+	* tests/tcltest.test: added missing cleanups/tests/catches that caused
+	tests to fail on the mac.
+
+	* doc/tclvars.n: doc bug, env(PWD) should be env(HOME) [Bug 463834]
+
+2001-11-21  Don Porter	<dgp@users.sourceforge.net>
+
+	* tests/trace.test (trace-8.8): Corrected test for Bug 219393.
+
+	* generic/tclBasic.c (Tcl_DeleteCommandFromToken,CallCommandTraces):
+	* generic/tclCmdMZ>c (Tcl_UntraceCommand):  Added Tcl_Preserve and
+	Tcl_Release calls to prevent deletion of CommandTrace structures until
+	all callers are done using them, preventing memory corruption. [Bug
+	453805]
+
+2001-11-20  Kevin B. Kenny  <kennykb@users.sourceforge.net>
+
+	* doc/GetTime.3 (Tcl_GetTime):
+	* generic/tcl.decls (Tcl_GetTime):
+	* generic/tclClock.c (Tcl_ClockObjCmd):
+	* generic/tclCompile.c (TclCleanupByteCode, TclInitByteCodeObj):
+	* generic/tclCmdMZ.c (Tcl_TimeObjCmd):
+	* generic/tclUtil.c (TclpGetTime):
+	* generic/tclTest.c (GetTimesCmd):
+	* generic/tclTimer.c (Tcl_CreateTimerHandler, TimerSetupProc,
+	(TimerCheckProc, TimerHandlerEventProc):
+	* mac/tclMacNotify.c (Tcl_SetTimer):
+	* mac/tclMacShLib.exp (Tcl_GetTime):
+	* mac/tclMacTime.c (Tcl_GetTime):
+	* unix/tclUnixChan.c (TclUnixWaitForFile):
+	* unix/tclUnixEvent.c (Tcl_Sleep):
+	* unix/tclUnixThrd.c (Tcl_ConditionWait):
+	* unix/tclUnixTime.c (Tcl_GetTime):
+	* win/tclWinNotify.c (Tcl_Sleep):
+	* win/tclWinTest.c (TestwinclockCmd):
+	* win/tclWinTime.c (TclpGetSeconds, TclpGetClicks, Tcl_GetTime):
+	Changed all uses of TclpGetTime to Tcl_GetTime. Added Tcl_GetTime to
+	the Stubs table and the library documentation. Added a TclpGetTime in
+	tclUtil.c for backward compatibility of extensions. [Patch 483500,
+	TIP#73]
+
+	* generic/tclCmdMZ.c (Tcl_TimeObjCmd): Corrected an error in the
+	[time] command that caused incorrect results to be returned if the
+	total duration of all iterations exceeded 2**31 microseconds. [Bug
+	478847]
+
+	* generic/tclInt.decls:
+	* generic/tclInt.h:
+	* generic/tclStubInit.h: Reran 'make genstubs'
+
+2001-11-20  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* generic/tclBasic.c
+	* generic/tclCompile.h:
+	* generic/tclExecute.c: moving all code relative to bytecodes from
+	tclBasic.c to tclExecute.c - the functions RecordTracebackInfo and
+	Tcl_ExprObj went to tclExecute.c, and new interface function was
+	defined (TclCompEvalObj).
+	The final objective of this sequence of moves is to provide a clean,
+	clear-cut interface between Tcl's core and the compiler/engine
+	subsystem.
+
+2001-11-20  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* generic/tclBasic.c
+	* generic/tclCompile.h:
+	* generic/tclExecute.c: factoring out of common code in tclBasic.c
+	(new function TclInterpReady defined: it resets the interp's result,
+	then checks that it hasn't been deleted and that the nesting level is
+	acceptable). Passed the responsibility of calling it to the *callers*
+	of TclEvalObjvInternal.
+
+2001-11-20  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* generic/tclBasic.c
+	* generic/tclExecute.c: a better variant of the previous-to-last
+	commit (restoring numLevels computations). The managing of the levels
+	now has to be done by the *callers* of TclEvalObjvInternal
+
+2001-11-20  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* generic/tclExecute.c: missing variable declaration under
+	TCL_COMPILE_DEBUG.
+
+2001-11-20  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* generic/tclExecute.c:
+	* generic/tclProc.c: restoring the computations of iPtr->numLevels to
+	the original logic (previous to buggy modifs on 2001-11-16).
+
+2001-11-20  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* tools/eolFix.tcl (new-file):
+	* unix/Makefile.in: added EOL correction for Windows bat files to
+	dist target. [Bug 219409] (davygrvy)
+
+	* unix/tclUnixInit.c (TclpSetInitialEncodings): update of patch from
+	2001-11-16 that uses the old Tcl encoding check mechanism as a
+	fallback to the original. Also added a TCL_DEFAULT_ENCODING #define
+	(defaults to iso8859-1). Tcl will first try setlocale and nl_langinfo,
+	and if that fails, guess based on certain LANG|LC_* env vars. [Patch
+	418645]
+
+2001-11-19  David Gravereaux <davygrvy@pobox.com>
+
+	* win/buildall.vc.bat:  Added useful comments.
+
+2001-11-19  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* tests/compile.test: added a test for bug [Bug 483309]
+
+2001-11-19  Vince Darley  <vincentdarley@users.sourceforge.net>
+
+	* win/tclWinFile.c:
+	* win/tclWinFCmd.c:
+	* win/tclWin32Dll.c:
+	* doc/file.n:
+	* tests/winFCmd.test: improved speed of file normalization for
+	Win95/98, and clarified docs on differences in file normalization
+	between NT/2000 and the older operating systems. Added test to ensure
+	normalization is correct.
+
+2001-11-19  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* generic/tclBasic.c:
+	* generic/tclParse.c: Code reorganisation. Moved all evaluation
+	functions from tclParse.c to tclBasic.c, so that now tclParse.c deals
+	exclusively with parsing and all evaluations are done by code in
+	tclBasic.c. The functions moved are: TclEvalObjvInternal,
+	Tcl_EvalObjv, Tcl_LogCommandInfo, Tcl_EvalTokensStandard,
+	Tcl_EvalTokens, Tcl_EvalEx, Tcl_Eval, Tcl_EvalObj and
+	Tcl_GlobalEvalObj.
+
+2001-11-19  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* tests/trace.test (trace-8.8): Added adapted version of [Bug 219393]
+	as new test; the test won't reliably show up the old problem unless it
+	is being run under something like Purify, but something is better than
+	nothing...
+
+	* generic/tclVar.c (Tcl_TraceVar2, Tcl_UntraceVar2): Added missing
+	mask bits for trace result type and a check for a nonsense flag
+	combination.
+	* generic/tclCmdMZ.c (TraceVarProc): Added missing test for NULL when
+	deleting a trace that doesn't cause an error.
+
+	* doc/TraceVar.3: Added documentation for change due to TIP#68.
+
+	* generic/tclCmdMZ.c (TraceVarInfo): Removed problematic errMsg field
+	from structure.
+	(TraceVarProc): Removed references to errMsg field and changed
+	handling of errors so that they returned a Tcl_Obj* containing the
+	error string. This minimizes the number of calls to the memory
+	management subsystem.
+	(TclTraceCommandObjCmd, TraceCommandProc): Removed references to
+	errMsg field which was never used in command traces in any case.
+	(Tcl_TraceObjCmd, TclTraceVariableObjCmd): Removed references to
+	errMsg field and made variable traces register with
+	TCL_TRACE_RESULT_OBJECT bit set.
+
+	* generic/tcl.h (TCL_TRACE_RESULT_DYNAMIC,TCL_TRACE_RESULT_OBJECT):
+	New constants to define how to handle the strings returned from trace
+	callbacks [TIP#68]
+	* generic/tclVar.c (CallTraces, Tcl_GetVar2Ex, TclGetIndexedScalar,
+	(TclGetElementOfIndexedArray, Tcl_SetVar2Ex, TclSetIndexedScalar,
+	(TclSetElementOfIndexedArray, Tcl_UnsetVar2, Tcl_ArrayObjCmd,
+	(TclDeleteVars, TclDeleteCompiledLocalVars, DeleteArray,
+	(TclVarTraceExists): Support for those new trace flags.
+
+2001-11-19  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* generic/tclCompCmds.c: patch for [Bug 483309] (petasis).
+
+2001-11-16  Kevin B. Kenny  <kennykb@users.sourceforge.net>
+
+	* generic/tclListObj.c: removed a C++-style comment that was
+	inadvertently left in the source code.
+
+2001-11-16  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* tests/interp.test:
+	* generic/tclInterp.c (SlaveObjCmd): Corrected argument checking for
+	'$interp alias|aliases|issafe'. [Patch 479560] (thoyts, hobbs)
+
+	* unix/tclUnixInit.c: added HAVE_LANGINFO code block.
+	* unix/configure: regened
+	* unix/configure.in: added SC_ENABLE_LANGINFO call
+	* unix/tcl.m4: made SHLIB_LD_LIBS='${LIBS}' for FreeBSD* (meyer)
+	Added modified version of Wagner patch to make use of nl_langinfo
+	where possible to determine Unix platform encoding, instead of the
+	inflexible built-in system. This is used by default when possible, and
+	can be disabled with --enable-langinfo=no. [Patch 418645] (hobbs,
+	wagner)
+
+2001-11-16  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* generic/tclCompile.h:
+	* generic/tclExecute.c:
+	* generic/tclObj.c: moved Tcl_GetCommandFromObj and all defining code
+	for tclCmdNameType objects to tclObj.c (from tclExecute.c). This code
+	has nothing to do with bytecodes.
+
+2001-11-16  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* generic/tclBasic.c:
+	* generic/tclCompile.h:
+	* generic/tclExecute.c:
+	* generic/tclParse.c:
+	* generic/tclProc.c:
+	* tests/stack.test: consolidation of duplicated code (in
+	TclExecuteByteCode and EvalObjv); renaming of EvalObjv to TclEvalObjv
+	as it is not static anymore; restored consistency of level counts
+	between compiled and directly evaled code. [Bug 480896]
+
+2001-11-12  David Gravereaux <davygrvy@pobox.com>
+
+	* win/makefile.vc:
+	* win/rules.vc:  Small bug fixes.
+
+	* win/README: added some docs pointing to the docs in makefile.vc for
+	it's use.
+
+2001-10-17  Kevin B. Kenny  <kennykb@users.sourceforge.net>
+
+	* doc/lappend.n:
+	* doc/lindex.n:
+	* doc/linsert.n:
+	* doc/list.n:
+	* doc/llength.n:
+	* doc/lrange.n:
+	* doc/lsearch.n:
+	* doc/lset.n (new-file):
+	* doc/lsort.n:
+	* generic/tclBasic.c (builtInCmds, Tcl_EvalObjEx):
+	* generic/tclCmdIL.c (Tcl_LindexObjCmd, Tcl_LindexList):
+	(Tcl_LindexFlat, Tcl_LsetObjCmd):
+	* generic/tclCompCmds.c (Tcl_CompileLindexCmd, Tcl_CompileLsetCmd):
+	* generic/tclCompile.c:
+	* generic/tclCompile.h:
+	* generic/tclExecute.c (TclExecuteByteCode):
+	* generic/tclInt.decls:
+	* generic/tclInt.h:
+	* generic/tclIntDecls.h:
+	* generic/tclListObj.c (TclLsetList, TclLsetFlat, TclSetListElement):
+	* generic/tclObj.c (TclInitObjSubsystem):
+	* generic/tclStubInit.c:
+	* generic/tclTestObj.c (TestobjCmd):
+	* generic/tclUtil.c (TclGetIntForIndex, SetEndOffsetFromAny):
+	* generic/tclVar.c (Tcl_LappendObjCmd):
+	* tests/lindex.test:
+	* tests/lset.test (new-file):
+	* tests/lsetComp.test (new-file):
+	* tests/obj.test:
+	* tests/string.test:
+	* tests/stringComp.test:
+	Reference implementation of TIP's #22, #33 and #45. Adds the ability
+	of the [lindex] command to have multiple index arguments, and adds the
+	[lset] command. Both commands are byte-code compiled. [Patch 471874]
+	(work by Kenny, commited by Hobbs)
+
+2001-11-12  David Gravereaux <davygrvy@pobox.com>
+
+	* win/buildall.vc.bat(new):
+	* win/makefile.vc:  Small fix with deriving the "OriginalFilename"
+	string in the .rc scripts. Added a quick batchfile for building the
+	entire thing.
+
+2001-11-12  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* doc/FileSystem.3:
+	* doc/file.n:
+	* doc/tcltest.n: converted use of \' to more reasonable format.
+
+2001-11-10  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* unix/Makefile.in:
+	* win/Makefile.in: Add "make gdb" target. This target can run tclsh
+	inside either gdb or insight.
+
+2001-11-10  David Gravereaux <davygrvy@pobox.com>
+
+	* win/makefile.vc:  Added a check to make sure one runs the makefile
+	from the /win directory only.
+
+	* win/mkd.bat:
+	* win/rmd.bat:  Changes from Llyod Lim for better stability.
+	[Patch 456759]
+
+2001-11-09  David Gravereaux <davygrvy@pobox.com>
+
+	* win/makefile.vc:
+	* win/tcl.dsp:  winhelp target fixes for non-NT systems. It seems
+	NMAKE under these remembers changed directories during commands. A new
+	tcltest feature from Peter Spjuth <peter.spjuth@space.se> to specify a
+	pattern file from the commandline and redirecting output to a file
+	when not under NT with it's scrollback console. Then it replays it,
+	piped through more. Added 2 new static "configurations" to tcl.dsp.
+	I could keep adding more, but I think we should leave it up to the
+	user for customizing it.
+
+	Sticky-points left:  'profile' option.
+
+2001-11-09  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* doc/FileSystem.3:
+	* doc/StdChannels.3:
+	* doc/file.n:
+	* doc/tcltest.n:
+	* tools/man2help.tcl:
+	* tools/man2help2.tcl: fixed winhelp generation problems
+	[Patch 480268]
+
+	* unix/configure:
+	* unix/tcl.m4: added -lc to AIX libs, fixed path to ldAix
+
+2001-11-09  Don Porter	<dgp@users.sourceforge.net>
+
+	* tests/var.test:
+	* generic/tclVar.c: Corrected bug in [global] when dealing with
+	variable names matching :*. [Bug 480176]
+
+2001-11-08  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	Fixup stack size under OSF1. [Patch 474790]
+
+	* unix/configure: Regen.
+	* unix/tcl.m4: Add HAVE_PTHREAD_ATTR_SETSTACKSIZE define to
+	EXTRA_CFLAGS to adjust initial stack size.
+
+2001-11-08  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	Enable thread support under FreeBSD. [Bug 473708]
+
+	* unix/configure: Regen.
+	* unix/tcl.m4 (SC_ENABLE_THREADS): Check for pthread functions in
+	libc_r and enable thread support if found.
+	* unix/dltest/Makefile.in: Set SHLIB_LD_LIBS and use it in the
+	Makefile to properly link a shared library.
+
+2001-11-08  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* unix/Makefile.in:
+	* unix/dltest/Makefile.in: Avoid adding libc to the LIBS variable
+	since it is not needed when linking with CC. If required when linking
+	with LD it should be done on a case by case basis in tcl.m4.
+
+2001-11-08  David Gravereaux <davygrvy@pobox.com>
+
+	* win/rules.vc:
+	* win/makefile.vc:  Fixed install target to adjust for the different
+	build types. Added a 'linkexten' option to link the win extensions
+	inside the shell when built static. Placed win/tclAppInit.c patch in
+	SF patch DB for approval. 'profile' option not hooked in yet.
+	Everything else know is done.
+
+	* win/tcl.dsp(new):
+	* win/tcl.dsw(new):  Simple MsDev stub project files that calls
+	makefile.vc. Will help run Tcl in the debugger easier without
+	confusing MsDev for where the .pdb files are.
+
+2001-11-07  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* unix/Makefile.in:
+	* win/Makefile.in: Print a message indicating that the user should run
+	"make genstubs" when the generated tclStubInit.c file is out of date.
+	We can't regenerate automatically since there may be no tclsh on the
+	system and that would cause bootstrap problems. [Bug 465874]
+
+2001-11-07  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	Define TCL_INCLUDE_SPEC in tclConfig.sh. It should be included by
+	extensions that need to find Tcl include headers in the install
+	location. The user can override the include install dir with
+	--includedir so we need to record this information for extensions.
+	[Bug 421835]
+
+	* unix/configure: Regen.
+	* unix/configure.in: Define TCL_INCLUDE_SPEC.
+	* unix/tclConfig.sh.in: Define TCL_INCLUDE_SPEC.
+	* win/configure: Regen.
+	* win/configure.in: Define TCL_INCLUDE_SPEC.
+	* win/tclConfig.sh.in: Define TCL_INCLUDE_SPEC.
+
+2001-11-07  David Gravereaux <davygrvy@pobox.com>
+
+	* win/rules.vc:
+	* win/makefile.vc: Dropped the NOMSVCRT macro and put it on the option
+	list instead. It makes more sense to me this way as NOMSVCRT=0 would
+	only be the valid setting. Fixed the dde and reg extension for
+	building static. Improved, but not perfected, the winhelp target.
+
+2001-11-07  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* win/README: Change minimum VC++ version to 5.X since 4.X is known
+	not to work.
+	Indicate that Mingw is required and building with Cygwin gcc is not
+	supported. Include instructions that indicate how to install Mingw and
+	what URLs folks should use to download the supported version of Mingw.
+	* win/configure: Regen.
+	* win/configure.in: Error out if user tries to compile the Windows
+	version of Tcl with Cygwin gcc. Users should compile with Mingw gcc
+	instead.
+
+2001-11-06  Andreas Kupries  <andreas_kupries@users.sourceforge.net>
+
+	* generic/tclIO.c (ReadChars): Fixed [Bug 478856] reported by Stuart
+	Cassoff <stwo@users.sourceforge.net>. The bug caused loss of
+	fileevents when [read]ing less data from the channel than buffered.
+	Due to an empty input buffer the flag CHANNEL_NEED_MORE_DATA was set
+	but never reset, causing the I/O system to wait for more data instead
+	of using a timer to synthesize fileevents and to flush the pending
+	data out of the buffers.
+
+2001-11-06  David Gravereaux <davygrvy@pobox.com>
+
+	* win/rules.vc (new):
+	* win/makefile.vc:  Complete over/under rewrite to support numerous
+	build options all from the commandline itself without needing to edit
+	the makefile. Now requires vcvars32.bat to be run prior to running
+	nmake for bootstraping the environment. Fully doc'd usage for it is in
+	makefile.vc. Commentary welcome. Sticky points left are:
+
+	1) winhelp target shows errors in the converting script.
+	2) .rc scripts aren't getting the right #defines to build the correct
+	   "OriginalFilename" strings. (have patch, won't commit yet)
+	3) Naming convention with suffixes describing the buildtype are 'tsdx'
+	   which will need public acceptance. ie. tclsh84tsx.exe is a (t)
+	   threaded shell (s) statically linked to the core and (x) uses
+	   msvcrt instead of libcmt.
+
+2001-11-04  Vince Darley  <vincentdarley@users.sourceforge.net>
+
+	* library/init.tcl: made filesystem fallback proc ::tcl::CopyDirectory
+	more robust to vagaries of non-native filesystems.
+
+2001-11-02  Vince Darley  <vincentdarley@users.sourceforge.net>
+
+	* doc/file.n:
+	* generic/tclIOUtil.c: updated documentation and comments to clarify
+	behaviour of 'file copy' wrt soft links.
+
+2001-10-29  Vince Darley  <vincentdarley@users.sourceforge.net>
+
+	* win/tclWinFile.c: fix to '-types {f r}' bug in TclpMatchInDirectory
+	(which could cause a UMR, as well as returning wrong results). Also
+	improved API for 'stat' to resolve [Bug 219258].
+	* win/tclWin32Dll.c
+	* win/tclWinInt.h: addition of improved stat API to internal lookup
+	table.
+	* tests/fileName.test: two new tests for the above bug.
+	* generic/tclIOUtil.c: some cleanup of comments and #ifdefs
+
+2001-10-29  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* unix/tclUnixFile.c (TclpMatchInDirectory): Argument to access() was
+	entryPtr->d_name instead of nativeEntry which failed when trying to
+	check access for files in other than the current directory. [Bug
+	475941, reported by Georgios Petasis]
+
+2001-10-25  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* unix/tclUnixChan.c: Added stateUpdated member to struct TtyState.
+	(TtyCloseProc,TtySetOptionProc,TtyInit): Use stateUpdated member of
+	TtyState to decide whether it is necessary to reset a serial port when
+	Tcl closes it. Blindly resetting can cause Tcl to be sent an
+	unexpected SIGTSTP when it is executing in the background [Bug 471374,
+	reported by Chris Nelson]
+
+2001-10-22  Andreas Kupries  <andreas_kupries@users.sourceforge.net>
+
+	* doc/ObjectType.3: Minor documentation fix, reported by David N.
+	Welton <davidw@users.sourceforge.net> directly to me.
+
+2001-10-22  Vince Darley  <vincentdarley@users.sourceforge.net>
+
+	* win/tclWinFCmd.c: fix to stop test suite from hanging process under
+	some versions of WinNT. [Bug 466102] (Kevin Kenny)
+
+2001-10-18  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* tests/clock.test (clock-8.1):
+	* generic/tclDate.c (RelativeMonth):
+	* generic/tclGetDate.y (RelativeMonth): corrected off-by-one-day error
+	in clock scan with relative months and years during swing hours. [Bug
+	413397, Patch 414024] (lavana)
+
+2001-10-18  Vince Darley  <vincentdarley@users.sourceforge.net>
+
+	* generic/tclIOUtil.c: fix to bug in Tcl_FSChdir shown up by recent
+	tclkit builds.
+
+2001-10-17  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* unix/tclUnixPipe.c (PipeInputProc, PipeOutputProc): do immediate
+	retry when error is returned with errno == EINTR. [Bug 415131] (leger)
+
+2001-10-16  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* unix/tclLoadAout.c (TclGuessPackageName): removed unused vars and
+	fixed warnings. [Bug 446622] (lim)
+
+2001-10-15  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* generic/tclProc.c: changing a memcmp to strncmp to avoid a memory
+	error detected by purify (thanks Jeff); modify style to agrre with the
+	style guide.
+
+2001-10-15  Andreas Kupries  <andreas_kupries@users.sourceforge.net>
+
+	* generic/tclInt.decls (TclExpandCodeArray,TclGetInstructionTable):
+	Added to internal stubs table. Tclcompiler (Tclpro project) needs them
+	if used as loadable package under Windows. Changed signatures. We
+	don't want to describe compiler internal structures in "tclInt.h".
+
+	* generic/tclCompile.h: S.a. Removed function declarations.
+	* generic/tclCompile.c: S.a. Adapted to changed signatures.
+
+2001-10-15  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* unix/configure:
+	* unix/configure.in:
+	* win/configure:
+	* win/configure.in:
+	* win/tcl.m4: reworked to be a little cleaner in comparison to each
+	other, and to AC_SUBST even empty vars for win/tclConfig.sh
+
+	* generic/tclFileName.c: minor code cleanup
+
+	* generic/tcl.h: moved #define of WIN32 to tcl.h where __WIN32__ is
+	defined and added #ifndef check.
+
+	* doc/open.n: moved all fconfigure option docs to fconfigure.n
+	* doc/fconfigure.n: added serial config options
+
+	* win/tclWinChan.c:
+	* win/tclWinPort.h:
+	* win/tclWinSerial.c: added TIP #35 Windows enhancements for serial
+	configuration. [Patch 438509] (schroedter)
+
+2001-10-15  Vince Darley  <vincentdarley@users.sourceforge.net>
+
+	* generic/tclFCmd.c: fix to memory leak in TclFileDeleteCmd on
+	certain error conditions.
+	* doc/FileSystem.3: fix to typo.
+
+2001-10-12  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* library/encoding/ebcdic.enc:
+	* tools/encoding/ebcdic.txt: EBCDIC charset mapping.
+	[Patch 219323] (nijtmans)
+
+	* library/encoding/tis-620.enc:
+	* tools/encoding/tis-620.txt: TIS-620 charset mapping.
+	[Patch 467423] (poonlap)
+
+	* tests/http.test: added removeFile for outdata
+
+	* tests/ioCmd.test: added catch around file removal, as Windows file
+	locking throws errors.
+
+	* tests/socket.test (socket-7.2): corrected to work on Win2K.
+
+2001-10-12  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* tests/compile.test: new tests for [Bug 467523]; they are only
+	effective if TCL_MEM_DEBUG was set during compilation.
+
+2001-10-11  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* generic/tclLiteral.c (TclReleaseLiteral): insured that
+	self-referential bytecodes are properly cleaned up on interpreter
+	deletion [Bug 467523] (Ronnie Brunner)
+
+2001-10-10  David Gravereaux  <davygrvy@pobox.com>
+
+	* win/tclWinPort.h:  #include <winsock2.h> needed to get moved to
+	after #include <windows.h> or wierd misunderstandings took place when
+	-D_WIN32_WINNT=0x0400 is set for outside code that requires knowledge
+	of Tcl innards. General header macro magic applied liberally...
+
+2001-10-10  Don Porter	<dgp@users.sourceforge.net>
+
+	* tests/unixInit.test:	Corrected restore of ::env(LANG).
+
+2001-10-09  Jeff Hobbs	<jeffh@ActiveState.com>
+
+	* generic/tclFileName.c (Tcl_SplitPath): corrected mem leak intro'd
+	with VFS code where the result obj from Tcl_FSSplitPath was not
+	getting freed.
+
+2001-10-09  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* generic/tclLiteral.c: (TclReleaseLiteral) reverted previous patch
+	for [Bug 467523] - cure is worse than the illness.
+
+2001-10-05  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* generic/tclLiteral.c: (TclReleaseLiteral) insured that
+	self-referential bytecodes are properly cleaned up on interpreter
+	deletion. [Bug 467523] (Ronnie Brunner)
+
+2001-10-04  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* tools/configure:
+	* tools/configure.in: noted 8.4 as default Tcl version
+
+	* library/encoding/cp936.enc:
+	* library/encoding/cp949.enc:
+	* library/encoding/cp950.enc:
+	* library/encoding/iso8859-16.enc:
+	* library/encoding/macCroatian.enc:
+	* library/encoding/macCyrillic.enc:
+	* library/encoding/macGreek.enc:
+	* library/encoding/macIceland.enc:
+	* library/encoding/macRoman.enc:
+	* library/encoding/macTurkish.enc:
+	* tools/encoding/cp1250.txt:
+	* tools/encoding/cp1251.txt:
+	* tools/encoding/cp1252.txt:
+	* tools/encoding/cp1253.txt:
+	* tools/encoding/cp1254.txt:
+	* tools/encoding/cp1255.txt:
+	* tools/encoding/cp1256.txt:
+	* tools/encoding/cp1257.txt:
+	* tools/encoding/cp1258.txt:
+	* tools/encoding/cp874.txt:
+	* tools/encoding/cp932.txt:
+	* tools/encoding/cp936.txt:
+	* tools/encoding/cp949.txt:
+	* tools/encoding/cp950.txt:
+	* tools/encoding/iso8859-1.txt:
+	* tools/encoding/iso8859-10.txt:
+	* tools/encoding/iso8859-13.txt:
+	* tools/encoding/iso8859-14.txt:
+	* tools/encoding/iso8859-15.txt:
+	* tools/encoding/iso8859-16.txt:
+	* tools/encoding/iso8859-2.txt:
+	* tools/encoding/iso8859-3.txt:
+	* tools/encoding/iso8859-4.txt:
+	* tools/encoding/iso8859-5.txt:
+	* tools/encoding/iso8859-6.txt:
+	* tools/encoding/iso8859-7.txt:
+	* tools/encoding/iso8859-8.txt:
+	* tools/encoding/iso8859-9.txt:
+	* tools/encoding/koi8-r.txt:
+	* tools/encoding/macCentEuro.txt:
+	* tools/encoding/macCroatian.txt:
+	* tools/encoding/macCyrillic.txt:
+	* tools/encoding/macGreek.txt:
+	* tools/encoding/macIceland.txt:
+	* tools/encoding/macRoman.txt:
+	* tools/encoding/macTurkish.txt:
+	Updated encodings with latest mappings from www.unicode.org. This did
+	not include some Mac encodings that have special multi-unichar
+	translations now (like symbols, dingbats and japanese). Also does not
+	include big5, gb or euc* as those have different formats in the latest
+	Unicode version that need new conversion tools. Not all related .enc
+	files changed as some had been updates separately.
+
+2001-10-03  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* generic/tclEvent.c (Tcl_FinalizeThread): moved freeing of
+	tclLibraryPath to before the thread exit handlers are called. Slight
+	modification to change on 2001-09-24.
+
+2001-10-01  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* win/configure: regen'ed
+	* win/tcl.m4:
+	* win/makefile.vc: added Win64 SDK RC1 compilation support
+	* win/Makefile.in: added $(LDFLAGS_CONSOLE) to TCLSH, TCLTEST and
+	PIPE_DLL_FILE targets to get the link flags
+
+	* win/tclWinInit.c: minor 64bit casts
+
+2001-10-01  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* generic/tclCmdIL.c:
+	* generic/tclCmdMZ.c:
+	* generic/tclParseExpr.c: removed unnecessary inclusion of
+	tclCompile.h and made a small modification in (InfoBodyCmd) to improve
+	the isolation of the compiler/engine subsystem.
+
+2001-09-29  Vince Darley  <vincentdarley@users.sourceforge.net>
+
+	* generic/tclIOUtil.c:
+	* doc/FileSystem.3: corrected and clarified documentation for
+	'Tcl_FSListVolumes(Proc)'. No code changes.
+
+2001-09-28  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* doc/FindExec.3: added a comment not to change the working directory
+	before calling Tcl_GetNameOfExecutable. [Bug 219215]
+
+2001-09-28  Kevin Kenny   <kennykb@users.sourceforge.net>
+
+	* generic/tclIO.c: added two more '(ClientData)' casts on calls to
+	Tcl_Preserve and Tcl_Release -- ones that Vince apparently missed.
+
+2001-09-28  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* doc/lsort.n: Improved doc...
+	* generic/tclCmdIL.c (Tcl_LsortObjCmd, SortCompare): Made
+	offset-from-end indexing work, and factored out some "magic numbers"
+	for easier understanding. [Bug 465674]
+	* tests/cmdIL.test (cmdIL-1.26): Added test for offset-from-end
+	indexing for lsort.
+
+2001-09-28  Vince Darley  <vincentdarley@users.sourceforge.net>
+
+	* win/tclWinFCmd.c:
+	* unix/tclUnixFCmd.c: fix to performance issue reported by jcw in
+	which 'access("")' is called unnecessarily when normalizing any
+	absolute path.
+	* generic/tclIO.c: added '(ClientData)' cast to calls to
+	Tcl_(Preserve|Release) newly introduced, fixing compile error on
+	Windows.
+
+2001-09-27  Don Porter  <dgp@users.sourceforge.net>
+
+	* doc/FileSystem.3 (Tcl_FSLoadFile):
+	* generic/tcl.decls (Tcl_FSLoadFile):
+	* generic/tcl.h (Tcl_FSLoadFileProc):
+	* generic/tclInt.h (TclpLoadFile):
+	* generic/tclIOUtil.c (Tcl_FSLoadFile):
+	* generic/tclLoadNone.c (TclpLoadFile):
+	* generic/tclTest.c (TestReportLoadFile):
+	* library/ldAout.tcl:
+	* mac/tclMacLoad.c (TclpLoadFile):
+	* unix/tclLoadAix.c (TclpLoadFile):
+	* unix/tclLoadAout.c (TclpLoadFile):
+	* unix/tclLoadDl.c (TclpLoadFile):
+	* unix/tclLoadDld.c (TclpLoadFile):
+	* unix/tclLoadDyld.c (TclpLoadFile):
+	* unix/tclLoadNext.c (TclpLoadFile):
+	* unix/tclLoadOSF.c (TclpLoadFile):
+	* unix/tclLoadShl.c (TclpLoadFile):
+	* win/tclWinLoad.c (TclpLoadFile):
+	* win/tclWinFCmd.c (DoRemoveJustDirectory):  More CONST poisoning
+	fixes from the 2001-09-24 TIP 27 changes. CONST-ified Tcl_FSLoadFile
+	and TclpLoadFile. Report and patch from Kevin Kenny. [Bug 465833]
+
+	* generic/tclIO.c (ChannelTimerProc):  Added Tcl_Preserve() and
+	Tcl_Release() to fix segfault introduced by the 2001-09-26 changes.
+	[Bug 465494]
+
+	* doc/TCL_MEM_DEBUG.3:  Updated out-of-date reference to #define
+	GUARD_SIZE.
+
+	* doc/UpVar.3 (Tcl_UpVar,Tcl_UpVar2):
+	* generic/tcl.decls (Tcl_UpVar,Tcl_UpVar2):
+	* generic/tclInt.decls (TclFindProc,TclGetFrame):
+	* generic/tclInt.h (TclFindProc,TclGetFrame,TclLookupVar,
+	(TclPrecTraceProc,TclProcInterpProc}):
+	* generic/tclProc.c (TclGetFrame,TclFindProc):
+	* generic/tclVar.c (Tcl_UpVar,Tcl_UpVar2,MakeUpvar):  Updated APIs in
+	generic/tclProc.c and generic/tclVar.c according to the guidelines of
+	TIP 27. [Patch 465442]
+
+	* generic/tclDecls.h:
+	* generic/tclIntDecls.h: make genstubs
+
+2001-09-26  Andreas Kupries  <andreas_kupries@users.sourceforge.net>
+
+	* doc/fileevent.n: Accepted [Patch 465279] adding an example to the
+	fileevent manpage. Minor modifications to get a better formatting.
+	Report and patch by David N. Welton <davidw@users.sourceforge.net>.
+
+	* The changes below fix [Bug 462317] where Expect tried to read more
+	than was in the buffers and then blocked in the OS call as its pty
+	channel driver provides no blockmodeproc through which the OS could be
+	notified of blocking-behaviour. Because of this the general I/O core
+	has to take more care than usual to preserve the semantics of
+	non-blocking channels.
+
+	The problem was reported by "Kevin O'Gorman" <kevin@kosmanor.com>.
+
+	* generic/tclIO.c (Tcl_ReadRaw): Do not read from the driver if the
+	channel is non-blocking and the fileevent causing the read was
+	generated by a timer. We do not know if there is data available from
+	the OS. Instead of going to the OS for more and potentially blocking
+	we simply signal EWOULDBLOCK to the higher levels to cause the system
+	to wait for true fileevents.
+	(GetInput): Same as before.
+	(ChannelTimerProc): Added set and clear of CHANNEL_TIMER_FEV.
+
+	* generic/tclIO.h (CHANNEL_TIMER_FEV): New flag for channels. Is set
+	if a fileevent was generated by a timer, the channel is not blocking
+	and the driver did not provide a blockmodeproc. In that case the I/O
+	core has to be especially careful about going to the driver for more
+	data.
+
+2001-09-26  Don Porter  <dgp@users.sourceforge.net>
+
+	* doc/SplitPath.3 (Tcl_GetPathType):
+	* generic/tcl.decls (Tcl_GetPathType):
+	* generic/tclFileName.c (Tcl_GetPathType):
+	* win/tclWinFile.c (TclpMatchInDirectory, NativeStat):  Vince Darley
+	reports the 2001-09-24 TIP 27 changes left the win directory CONST
+	poisoned. These changes should fix that.
+
+	* generic/tclDecls.h: make genstubs
+
+2001-09-25  Don Porter  <dgp@users.sourceforge.net>
+
+	* doc/GetInt.3:
+	* generic/tclInt.h (TclGetLong deleted):
+	* generic/tcl.decls:
+	* generic/tclInt.decls:
+	* generic/tclGet.c:  Updated APIs in generic/tclGet.c according to the
+	guidelines of TIP 27. [Patch 464674]
+
+	* generic/tclDecls.h:
+	* generic/tclIntDecls.h: make genstubs
+
+2001-09-25  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* generic/tclVar.c: removed comments referring to unused flag
+	TCL_PARSE_PART1.
+
+2001-09-24  Don Porter  <dgp@users.sourceforge.net>
+
+	* doc/Concat.3:
+	* doc/DString.3:
+	* doc/SplitList.3:
+	* generic/tclInt.h (TclCheckBadOctal):
+	* generic/tcl.decls:
+	* generic/tclInt.decls:
+	* generic/tclEncoding.c (OpenEncodingFile):
+	* generic/tclMain.c (Tcl_Main):
+	* generic/tclUtil.c:
+	* unix/tclLoadDl.c (TclpLoadFile):  Updated APIs in generic/tclUtil.c
+	according to the guidelines of TIP 27. [Patch 464553]
+
+	* generic/tclDecls.h:
+	* generic/tclIntDecls.h: make genstubs
+
+2001-09-24  Andreas Kupries  <andreas_kupries@users.sourceforge.net>
+
+	The change below fixes [Bug 464380]. The bug was reported by Ronnie
+	Brunner <rbrunner@users.sourceforge.net>. He also provided the patch.
+
+	* generic/tclEvent.c (Tcl_Finalize): Moved release of 'tclLibraryPath'
+	to Tcl_FinalizeThread.
+	(Tcl_FinalizeThread): See above, new place for release of
+	'tclLibraryPath'.
+
+2001-09-24  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* tools/encoding/cp1252.txt: File was missing part of the encoding
+	[euro, ZCaron and zcaron].
+
+	* doc/OpenFileChnl.3: Add docs for Tcl_OutputBuffered; remove some old
+	changebars.
+
+2001-09-21  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* generic/tclExecute.c (TclExecuteByteCode): corrected INST_STR_CMP
+	else case for strings to pass true utf char length to Tcl_UtfNCmp.
+
+2001-09-20  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* win/tclWinInit.c: added extra processor definitions. (mstacy)
+
+	* win/tclWinSock.c (SocketThread): corrected pointer cast for _WIN64.
+
+	* win/tclWinNotify.c: removed unnecessary winsock include (it is
+	already in from tclWinPort.h).
+
+	* win/tclWinPort.h: changed winsock.h include to winsock2.h. Reverses
+	change from 2000-11-16, but is necessary for WIN64. Extensions should
+	comply with defined OS words, or use #ifndef.
+
+2001-09-20  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* tests/socket.test: removed dependence on being run from same dir as
+	remote.tcl, which only now needs to be in the same dir as this file.
+	[Bug 219326]
+
+2001-09-19  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* generic/tclTest.c (TestcmdtokenCmd): corrected pointer
+	storage/retrieval for 64bit machines.
+
+	* generic/tclCmdAH.c (Tcl_FormatObjCmd):
+	* generic/tclScan.c (Tcl_ScanObjCmd): corrected handling of format and
+	scan on 64-bit machines. [Bug 412696] (rmax)
+
+	* unix/configure: regen'ed
+	* unix/tcl.m4: added --enable-64bit support for HP-11 with the 64-bit
+	kernel.
+
+	* tests/basic.test:
+	* tests/cmdInfo.test: improved skip reporting of missing commands
+
+	* tests/winFCmd.test: simplified error check for winFCmd-7.9
+
+	* tests/winPipe.test: removed obsolete cat16 tests
+
+	* generic/tclExecute.c (TclExecuteByteCode): fixed invalid usage of
+	valuePtr in TRACE_WITH_OBJ in INST_EVAL_STK case. [Bug 462594] Changed
+	INST_STR_CMP instruction to promote to Unicode strings only when one
+	of the strings is already of Unicode type.
+
+	* generic/tclExecute.c (TclExecuteByteCode):
+	* generic/tclCompile.c (instructionTable):
+	* generic/tclCompCmds.c (TclCompileStringCmd): INST_STR_MATCH -
+	Updated to Int1 instruction type and added special case to use
+	INST_STR_EQ instead when no glob chars are specified in a static
+	string.
+
+	* tests/{for.test,foreach.test,if.test,while.test}:
+	* generic/tclCompCmds.c (TclCompileForCmd, TclCompileForeachCmd,
+	TclCompileIfCmd, TclCompileWhileCmd): Corrected the overaggressive
+	compiling of loop bodies enclosed in ""s.  [Bug 219166] (msofer)
+
+2001-09-19  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* generic/tclExecute.c: insured that execution stack errors are also
+	detected at abnormal returns.
+
+2001-09-19  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* doc/socket.n: Added documentation to mention what happens when a
+	server socket is created with port=0. Removed an old change bar, and
+	no new change bar because Tcl has always behaved this way as it is
+	really a poorly-documented standards-defined OS feature.
+
+	* tests/util.test (util-8.1): Test derived from code to detect the
+	problem, but the test always works in the C locale, so beware if you
+	are maintaining the code.
+	* generic/tclUtil.c (TclNeedSpace): Rewrote to be UTF-8 aware. [Bug
+	411825, but not that patch which would have added extra spaces if
+	there was a real non-ASCII space involved.]
+
+2001-09-18 Andreas Kupries  <andreas_kupries@users.sourceforge.net>
+
+	* generic/tclIOCmd.c (Tcl_PutsObjCmd): Rewritten to have saner and
+	faster argument handling. [Bug 123552], [Patch 402564] (fellows)
+
+2001-09-18  Don Porter  <dgp@users.sourceforge.net>
+
+	* unix/configure: Regen.
+	* unix/tcl.m4 (SC_CONFIG_CFLAGS): On Linux, disable inlining when one
+	of the compat/*.c routines is to be linked in. [Patch 440891]
+
+2001-09-17  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* generic/tcl.h: removed forced #define USE_TCLALLOC 1 for Windows.
+	This means the native system allocator will be used by default. This
+	should be binary and source compatible with extensions, as Tcl_Alloc
+	is a properly stubbed function.
+
+2001-09-17  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* generic/tclExecute.c: corrected small bug in [Patch 456668] - the
+	varFramePtr was not restored in one possible exit.
+
+2001-09-17  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* doc/tclvars.n:
+	* generic/tclCompile.c:
+	* generic/tclCompile.h:
+	* generic/tclExecute.c:
+	* generic/tclProc.c: disabled all compile and execution tracing
+	functionality in standard builds; TCL_COMPILE_DEBUG is now necessary
+	to enable it. [Bug 451858]
+
+2001-09-14  Andreas Kupries <andreas_kupries@users.sourceforge.net>
+
+	* doc/gets.n:
+	* doc/read.n:
+	* doc/puts.n:
+	* doc/flush.n:
+	* doc/fconfigure.n:
+	* doc/flush.n:
+	* doc/eof.n:
+	* doc/seek.n:
+	* doc/tell.n:
+	* doc/close.n:
+	* doc/fileevent.n: Added references to the Tcl standard channels. Item
+	[219250], reported by David LeBlanc <whisper@oz.net>. Thanks to
+	Christopher Nelson <chris@pinebush.com> for doing editorial work.
+
+2001-09-13  Andreas Kupries  <andreas_kupries@users.sourceforge.net>
+
+	* win/Makefile.in:
+	* win/configure.in:
+	* win/makefile.bc:
+	* win/makefile.vc:
+	* library/dde/pkgIndex.tcl: Fixed version numbers from bogus tcl
+	versions to independent versions for dde and registry packages.
+
+2001-09-13  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* tests/regexp.test (regexp-20.1):
+	* generic/tclCmdMZ.c (Tcl_RegsubObjCmd): had to adjust fix from
+	2001-08-06 to actually duplicate the objects in certain cases. This is
+	really a place where feather would have been essential. [Bug 461322]
+
+	* generic/tclUtf.c (Tcl_UtfPrev): corrected to return the proper
+	location when the middle of a UTF-8 byte was passed in [Tk Bug 450504]
+
+	* ChangeLog.1999:
+	* ChangeLog: broke changes from 199x into ChangeLog.1999 to reduce
+	size of the main ChangeLog.
+
+2001-09-13  Andreas Kupries <andreas_kupries@users.sourceforge.net>
+
+	* tests/ioCmd.test: Changed the computation of the result for
+	iocmd-8.1[123] so that the tests work for single- and multi-process
+	execution of the testsuite. Depending on the choice of the user stdout
+	is a tty or not and thus reports different channel options. Fixes
+	[460993] reported by Don Porter.
+
+2001-09-13  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* doc/ParseCmd.3:
+	* generic/tcl.decls:
+	* generic/tclCmdMZ.c (Tcl_SubstObjCmd):
+	* generic/tclDecls.h:
+	* generic/tclParse.c:
+	* generic/tclStubInit.c:
+	* tests/parse.test: Deprecate the use of Tcl_EvalTokens, replaced by
+	the new Tcl_EvalTokensStandard. The new function performs the same
+	duties but adheres to the standard return convention for Tcl
+	evaluations; the deprecated function could only return TCL_OK or
+	TCL_ERROR, which caused [Bug 219384] and [Bug 455151]. This patch
+	implements [TIP 56].
+
+2001-09-12  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* unix/configure: Regen.
+	* unix/tcl.m4: Invert the logic that checks for $GCC. Instead of
+	checking for "$GCC" = "no" we check for "$GCC" != "yes" or simply swap
+	the true and false blocks of code in an if statement. That way if GCC
+	is set to "" everything will still work. [Bug 460991]
+
+2001-09-12  Don Porter <msofer@users.sourceforge.net>
+
+	* tests/appendComp.test:
+	* tests/lsearch.test:
+	* tests/namespace.test:
+	* tests/rename.test:
+	* tests/split.test:  Corrected tests to better isolate tests in one
+	file from influencing tests in other files. [Bug 460591]
+
+2001-09-12  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* generic/tcl.decls: reserved stub #481 for the implementation of
+	[TIP 56]
+
+2001-09-11  Andreas Kupries <andreas_kupries@users.sourceforge.net>
+
+	* doc/OpenFileChnl.3: Added documentation for Tcl_WriteRaw and
+	Tcl_ReadRaw [Bug 414929].
+
+	* doc/CrtChannel.3: Added documentation for Tcl_ChannelBuffered and
+	Tcl_GetTopChannel [Bug 414929].
+
+	* The changes below are a fix for [Bug 219253].
+
+	* tests/socket.test: Removed _most_ instances of hardwired port
+	numbers for listening sockets. Remaining are the ports in all tests
+	with constraint 'doTestsWithRemoteServer'. These seem to be designed
+	for a more controlled environment and are usually skipped when running
+	the testsuite.
+
+	* tests/io.test: Removed all instances of hardwired port numbers for
+	listening sockets.
+
+2001-09-10  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* generic/tclEvent.c (TclInExit): Corrected handling of tsd in late
+	stages of finalization. [Bug 419449] (darley)
+
+	* tests/stack.test:
+	* generic/tclInterp.c (AliasObjCmd): Check the numLevels to ensure
+	that we aren't hitting some alias loop condition. [Bug 443184]
+
+2001-09-10  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* unix/configure: Regen.
+	* unix/tcl.m4 (SC_CONFIG_CFLAGS): Don't include . characters in the
+	Tcl library name when building on FreeBSD 3.X and later systems.
+	[Patch 450725]
+
+2001-09-10  Andreas Kupries <andreas_kupries@users.sourceforge.net>
+
+	* doc/tclsh.1:
+	* doc/Tcl_Main.3:
+	* doc/CrtChannel.3:
+	* doc/OpenFileChnl.3:
+	* doc/GetStdChan.3: Enhanced the manpages with cross-references to
+	the new manpage and more explanations how these functions deal with
+	the standard channels in various situations.
+
+	* doc/StdChannels.3: New manpage describing handling of the standard
+	channels by the Tcl library. [Bug 402725]
+
+2001-09-10  Don Porter <dgp@users.sourceforge.net>
+
+	* unix/mkLinks (Tcl_FSLink): Updated to reflect 2001-08-23 file system
+	changes.
+
+	* unix/tclLoadShl.c:  Added #include of tclInt.h; access to Tcl
+	internals, notably TclpUnloadFile(), is required. Thanks to Bob
+	Techentin for report and patch. [Bug 459305]
+
+	* generic/tclInitScript.h (initScript):
+	* win/tclWinInit.c (TCL_REGISTRY_KEY, TclpSetVariables):  Removed
+	vestiges of Tcl's old initialization from registry variables. [Bug
+	455645]
+
+2001-09-10  Andreas Kupries <andreas_kupries@users.sourceforge.net>
+
+	* generic/tclInt.decls: Also added 'TclWinFlushDirtyChannels' to the
+	  internal platform specific stub table.
+
+	* win/tclWinFile.c (TclpObjStat): Now added the call to
+	'TclWinFlushDirtyChannels' to this function. I don't know where my
+	head was last thursday (2001-09-06), but the call was actually added
+	to 'TclpObjChdir', i.e. the implementation of [cd]. Corrected this
+	now. Thanks to Vince Darley for spotting this.
+
+2001-09-10  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* generic/tclProc.c:
+	* tests/proc.test: made [proc] bytecompile a no-op for procs defined
+	with _args_ as single argument and an empty body. [FRQ 451441]
+
+2001-09-09  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* unix/Makefile.in:
+	* win/Makefile.in: Use () around variable name instead of {}. Use
+	TCLTEST variable directly instead of depending on the tcltest alias.
+
+2001-09-09  David Gravereaux <davygrvy@pobox.com>
+
+	* generic/tcl.h:
+	* generic/tclPlatDecls.h: Reminder from David Cuthbert
+	<dacut@kanga.org> that I hadn't finished the Borland compatibility
+	stuff. [Patch 436116]
+
+2001-09-09  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* tests/cmdAH.test: Modify cmdAH-20.5 and cmdAH-24.8 to display the
+	file atime or mtime results if the test fails.
+
+2001-09-08  David Gravereaux <davygrvy@pobox.com>
+
+	* win/mkd.bat:
+	* win/rmd.bat: made these text files, text files again. [Patch 451333]
+
+2001-09-08  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* win/mkd.bat:
+	* win/rmd.bat: Apply binary property (cvs admin -kb) to files and
+	convert to CRLF linefeed format to fix the VC++ build. [Bug 219409]
+
+2001-09-08 Vince Darley <vincentdarley@users.sourceforge.net>
+
+	* generic/tclInt.h:
+	* generic/tclFCmd.c:
+	* doc/FileSystem.3:
+	* generic/tclIOUtil.c: removed Tcl_FSCopyFile fallback to channel
+	copying, since the channels will not have access to interpreters and
+	the channel copying currently requires an interp. Code which required
+	cross-platform copies always has interpreters, so that solves the
+	problem. Fixes bug in TclKit.
+
+2001-09-07  David Gravereaux <davygrvy@pobox.com>
+
+	* win/tcl.m4: Added -link50compat option so a VC6 linker makes a VC5
+	(pre sp3) compatible import library. [Bug 219257]
+
+2001-09-07  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* win/tclWinThrd.c (TclpThreadExit): Cast status argument to
+	_endthreadex to unsigned instead of DWORD to match the Win32 function
+	prototype.
+
+2001-09-06  Andreas Kupries <andreas_kupries@users.sourceforge.net>
+
+	* All the changes below serve to fix bug [219148] which reports a 80x
+	performance hit for file I/O on Win* systems. On my system it was
+	closer to a 120x hit. Problem report by Uwe Traum <no email address
+	available>.
+
+	The fix goes like this: The obstacle is 'FlushFileBuffers', executed
+	whenever Tcl writes data to the OS, as Tcl has to wait for the disk to
+	complete I/O, and disks are slow. We remove that obstacle. This opens
+	another problem, [file size] reports back wrong numbers. So for [file
+	size] we add the call back in. As optimization we keep track of the
+	channels which were written to and flush only these.
+
+	* win/tclWinFile.c (TclpObjStat): Added a call to
+	'TclWinFlushDirtyChannels'. This ensures that [file size] and related
+	commands report the correct size of a file even if Tcl has recently
+	written to it. Unixoid OS's always report the correct size even for
+	files with pending data, but Win* syssystem don't. They only report
+	what is actually on disk.
+
+	* win/tclWinInt.h: Added declaration of 'TclWinFlushDirtyChannels',
+	making it available to other parts of the tcl core.
+
+	* win/tclWinChan.c (TclWinFlushDirtyChannels): New, internal,
+	procedure. Goes through the list of open file channels and forces the
+	OS to flush its file buffers for all which were written to since the
+	last call of this function. This is an expensive operation as Tcl has
+	to wait for the OS to complete actual writes to the disk.
+
+	(FileInfo): Added dirty flag required by the procedure above.
+
+	(FileOutputProc): Removed flushing of file buffers, setting the dirty
+	flag instead. This means that the previously incurred delays do not
+	happen anymore.
+
+	(TclWinOpenFileChannel): Added initialization of 'dirty' flag.
+
+2001-09-06  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* doc/http.n: noted -binary, charset and coding state keys.
+	* tests/http.test:
+	* library/http/pkgIndex.tcl:
+	* library/http/http.tcl (geturl): correctly get charset parameter
+	and convert text according to specified encoding (if known). RFC
+	iso8859-1 is used by default. Also recognize Content-encoding to see
+	if we should do binary translation. Added a CYA -binary switch for the
+	cases that were missed. [Bugs 219211, 219399]
+
+	* tests/ioUtil.test: changed to make better use of constraints and
+	remove knownBug constraints that weren't valid.
+
+2001-09-06  Don Porter  <dgp@users.sourceforge.net>
+
+	* tests/unixInit.test (unixInit-3.2): Updated test to support newer
+	HP-UX releases that properly report euc-jp as the system encoding for
+	Japanese. Bug report and patch verification by Bob Techentin. [Bug
+	453883]
+
+	* doc/http.n:
+	* library/http/*.tcl:
+	* tools/tcl.wse.in:
+	* tools/tclmin.wse:
+	* unix/Makefile.in:
+	* win/{Mm}akefile.*:  Updated http package to version 2.4, reflecting
+	the new features just added.
+
+2001-09-06 Vince Darley <vincentdarley@users.sourceforge.net>
+
+	* generic/tclTest.c: tests of old-fs hooks no longer cause problems in
+	threaded builds. Also removed unused unload proc.
+	* generic/tcl.decls:
+	* generic/tclIOUtilc: added Tcl_FSMountsChanged so that a vfs can
+	inform the filesystem that the filesystem epoch must be changed (since
+	cached filesystems may now be incorrect). Fixes problem running tclvfs
+	extension.
+	* library/tcltest/tcltest.tcl: if tests aren't in a native filesystem,
+	then don't use pipes to run them. [Bug 458741]
+
+2001-09-06  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* generic/tcl.decls (479 generic):
+	* generic/tclIO.c (Tcl_Seek,Tcl_Tell,Tcl_OutputBuffered): Added public
+	function to return the size of the output buffer and reworked other
+	channel functions to use this shared functionality and that of
+	Tcl_InputBuffered() too. [TIP#49, Rolf Schroedter]
+
+2001-09-05  David Gravereaux <davygrvy@pobox.com>
+
+	* generic/tclPlatDecls.h:  Another small trim finalizing Borland
+	support.
+
+	* win/tclWinPipe.c:
+	* win/tclWinPort.h:  More Borland compatibility fixes. Changed EDQUOT
+	#define from 49 to 69. Borland had a clash as it was already using
+	this number. Upon advice from Helmut Giese, EDQUOT has been found in
+	other header files #defined as 69. [Patch 436116]
+
+	* win/.cvsignore:  A few more glob patterns added.
+
+	* win/makefile.bc (new):  Borland lives once more! rejoice..
+	* generic/tclAlloc.c: Small Borland compatibility fix.
+	* win/tclWinTime.c:  More Borland compatibility fixes. [Patch 436116]
+
+2001-09-05 Vince Darley <vincentdarley@users.sourceforge.net>
+
+	* tests/winFCmd.test: made notWin2000 constraint false if not running
+	on Windows at all.
+
+2001-09-04  David Gravereaux <davygrvy@pobox.com>
+
+	* win/tclWinThrd.c:  Revisited _beginthreadex() stuff. Instead of
+	assuming a c-runtime implimentation of _beginthreadex normal, I
+	reversed the logic to not assume, and use when is by explicitly
+	needing to add runtimes that support it such as Borland.
+
+	* generic/tcl.h:
+	* generic/tclPlatDecls.h:  Borland compatibility change so ClientData
+	was properly typed as a void* and TCHAR would not be defined twice.
+
+	* generic/tcl.h:  Removed a small mistake from before. Changes to the
+	EXTERN macro for proper Borland compatibility will have to see a TIP.
+	What's this with the MS compiler:
+
+		__declspec(dllexport) int func (int a, int b);
+
+	will have to be this with Borland:
+
+		int __cdecl __export func (int a, int b);
+
+	The order of the attribute needs to be after the return type.
+
+2001-09-04  Don Porter  <dgp@users.sourceforge.net>
+
+	* compat/strtod.c (strtod):  Fixed failure to handle expressions like
+	3eq2 and failure to set errno on overflow. [Bug 440894]
+
+2001-09-04  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* generic/tclProc.c:
+	* tests/proc.test: made [proc] check that formal args have simple
+	names. [Bug 458548]
+
+2001-09-04 Vince Darley <vincentdarley@users.sourceforge.net>
+
+	Minor bug fixes in filesystem, plus small vfs changes as a result of
+	enabling the test filesystem to work properly.
+	* tests/fileName.test: ensure new test cleans up after itself
+	* doc/filename.n:
+	* generic/tclFileName.c: improved Mac path handling and document why
+	[Bug 421842] on Windows handling of UNC paths is not valid.
+	Documentation and code now much clearer on what is and is not a UNC
+	path.
+	* doc/FileSystem.3:
+	* unix/tclUnixPipe.c:
+	* generic/tclFCmd.c:
+	* generic/tclIOUtil.c: fixed error message, fixed [Bug 453512] about
+	dangerous use of tmpnam, replaced with mkstemp. Documented all the
+	changes.
+	* generic/tclTest.c: made test vfs fully functional as a 'reporting
+	filesystem'.
+	* generic/tcl.stubs:
+	* generic/tcl.h:
+	* generic/tclInt.h:
+	* generic/tclIOUtil.c:
+	* doc/file.n:
+	* various platform-specific 'TclpLoadFile': fixed comments about
+	unload behaviour, and completed objectification of loading. Required
+	change to Tcl_Filesystem lookup table, so incompatible with 8.4a3, but
+	not older versions of Tcl. The change also allows 'link' and
+	'reporting' filesystems to function correctly when loading files.
+	Implementation of 'file delete -force' copes with case where cwd is
+	inside the directory. Moved overlooked Tcl_FSGetPathType from internal
+	to external API. Made sure filesystems which are registered and then
+	unregistered are only freed when all references to them are gone.
+	Documented changes.
+	* unix/tclUnixFCmd.c: when deleting directories recursively, make sure
+	permissions are ok. Together with the above, this fixes [Bug 219139]
+	* tests/winFCmd.test: differentiated test results for win2k versus
+	not. This fixes [Bug: 219239]
+	* tests/fCmd.test: added tests for 'file delete -force' where the cwd
+	is inside, and when permissions are inadequate.
+
+2001-09-04  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* generic/tclCompile.c: fixed incorrect operands for INST_LIST [Bug
+	458241] (David Cuthbert, dacut@users.sourceforge.net)
+
+2001-09-03  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* generic/tclExecute.c (TclExecuteByteCode): fixed missing comma in
+	debug macro.
+
+2001-09-03  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* doc/ExprLongObj.3: Fixed error in documentation of argument type to
+	Tcl_ExprObj [Bug 457435]
+
+2001-09-02  David Gravereaux <davygrvy@pobox.com>
+
+	* win/tclWinThrd.c:  Portability fix for Cygwin who's c-runtime,
+	not surprisingly, doesn't have the MSVCRT specific _beginthreadex /
+	_endthreadex pair. This might have to be revisited for proper Borland,
+	lcc32, Watcom and other support as well. [Patch 444255]
+
+	* win/tclWinThrd.c:  Moved FinalizeConditionEvent() proto to within
+	the main #ifdef TCL_THREADS block to avoid mingw warning about it
+	being there but unused.
+
+	* win/makefile.vc:  Added -Zl (zee el) to tclStubLib.c compile line to
+	make sure the tclstub84.lib static library is built without requiring
+	a specific C-runtime library at link-time for the end-use developer.
+	It has been noted on c.l.t that this trips many first time users
+	trying to make extensions. [Patch 403533]
+
+2001-08-31  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* generic/tclInt.h: added TclCompileListCmd header
+	* generic/tclBasic.c: added TclCompileListCmd compile proc
+	* generic/tclCompCmds.c (TclCompileListCmd): function to compile the
+	'list' command at parse time.
+	* generic/tclExecute.c (TclExecuteByteCode): definition of INST_LIST
+	bytecode.
+
+	* doc/StringObj.3: added words of warning to use Tcl_ResetResult with
+	the Tcl_Append* functions.
+
+	* tests/compile.test: added compile-11.* interp result checks
+	* generic/tclUtil.c (TclGetIntForIndex): added Tcl_ResetResult before
+	Tcl_AppendStringsToObj to prevent shared object crash when called from
+	bcc instruction. The Tcl_Append* calls that append to the result
+	object that are invoked by bcc insts must remember to call
+	Tcl_ResetResult because the bcc doesn't do this for us. [Bug 456892]
+
+2001-08-30  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* generic/tclIndexObj.c: fixed some casting problems that upset Crays.
+	[Bug 419528] (andreasen)
+
+2001-08-30  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tcl.h: Silence warning from Sun compiler. [Bug 454374]
+
+2001-08-30  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* generic/tclExecute.c: allow cached fully-qualified command names to
+	be usable from different namespaces within the same interpreter
+	without forcing a new lookup. This speeds up scripts that pass command
+	names in variables ("this" in some OO packages). [Patch 456668]
+
+2001-08-30 Vince Darley <vincentdarley@users.sourceforge.net>
+
+	Further fs updates. After examining the most common Tcl extensions
+	(TclX, BLT, Tk, TclPro, Mktclapp), it has been determined that only
+	TclpGetCwd and the Access/Stat/Open insert/delete hooks of the
+	internal fs functions are ever used. The remaining functions from
+	Tcl's internal interfaces have therefore been removed, since Tcl now
+	exports a more suitable public API (Tcl_FS...)
+
+	* generic/tclInt.stubs:
+	* generic/tclInt.h: updated for removed internal functions. Some new
+	internal functions have been put in tclInt.h (and not exported in the
+	stub table because good public equivalents exist).
+	* generic/tclTest.c: some test functions used the internal private
+	APIs. These tests have been retained, but modified to use public APIs.
+	Also objectified the internal filesystem tests.
+	* win/tclWinFile.c: removed TclpStat, TclpAccess and refactored code
+	to use NativeAccess, NativeStat. This should speed up stat, access and
+	glob commands.
+	* win/tclWinFCmd.c: removed all TclpCopy/Rename/Delete File/Directory
+	string-based procedures which aren't used any more. Improved
+	efficiency of some other procedures. Ensure that filename conversions
+	with a NULL interp do not crash Tcl.
+	* mac/tclMacFCmd.c: wrapped long lines and cleaned up
+	TclpObjNormalizePath, removed all TclpCopy/Rename/Delete
+	File/Directory string-based procedures which aren't used any more.
+	* mac/tclMacFile.c: removed obsolete TclpStat, TclpAccess, TclpChdir,
+	etc.
+	* unix/tclUnixFCmd.c: removed use of TclpAccess, removed all
+	TclpCopy/Rename/Delete File/Directory string-based procedures which
+	aren't used any more.
+	* unix/tclUnixFile.c: removed obsolete TclpStat, TclpAccess,
+	TclpChdir, etc.
+	* tcl(Unix|Mac|Win)Chan.c: objectified TclpOpenFileChannel.
+	* various 'load' implementations all objectified.
+	* generic/tclFileName.c: removed redundant code.
+	* generic/tclIOUtil.c: removed TclStat, TclAccess, TclpListVolumes.
+	Fix to MatchInDirectory at the root of a volume. Also improved some
+	documentation, and improved default path joining behaviour for virtual
+	filesystems, especially regarding '~'.
+	* tests/fileName.test: added tests to check for bugs fixed above.
+	* doc/FileName.3: improved documentation
+
+2001-08-30  David Gravereaux <davygrvy@pobox.com>
+
+	* generic/tclAsync.c:
+	* generic/tclEvent.c:
+	* generic/tclInt.h: Improper cleanup of asyncMutex in tclAsync.c
+	repaired. TclFinalizeSynchronization() was trying to remove a
+	registered mutex that was dumped earlier when the TSD it was stored in
+	was cleared. This was only surfacing on *nix. Windows was being masked
+	by mutexes not actually being returned to the system! That was
+	repaired in a previous patch. Needed to add a private
+	TclFinalizeAsync() to tclAsync.c and called from Tcl_FinalizeThread().
+	Pheww.. Is this done yet? [Bug 414419] requested by Rob Ratcliff
+	<rrr6399@futuretek.com>
+
+2001-08-28  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* generic/tclCompCmds.c (TclPushVarName): noted 'static' defn.
+	[Bug 453872]
+
+2001-08-26  Don Porter <dgp@users.sourceforge.net>
+
+	* library/auto.tcl (tcl_findLibrary):
+	* tests/unixInit.test (unixInit-2.{1,9}):
+	* unix/tclUnixInit.c (TclpInitLibraryPath):
+	* win/tclWinInit.c (TclpInitLibraryPath):  Corrected inconsistency
+	between  the search path for script libraries and the directory name
+	$DISTNAME into which distributions built by 'make test' unpack. [Bug
+	455642]
+
+2001-08-24  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* tests/stringComp.test: added string-1.3
+	* generic/tclCompCmds.c (TclCompileStringCmd): changed to return
+	TCL_OUT_LINE_COMPILE instead of TCL_ERROR when compiling and an
+	unknown string method is called. This is necessary as the string
+	command may be never called, or not until 'string' is redefined.
+
+2001-08-24 Vince Darley <vincentdarley@users.sourceforge.net>
+
+	* doc/glob.n: documented windows-style path issue with glob.
+	[Bug 219392]
+	* doc/filename.n: documented windows path/file length limitation.
+	[Bug 454597]
+
+2001-08-24  Don Porter <dgp@users.sourceforge.net>
+
+	* tests/unixInit.test (unixInit-2.9): Corrected expected result to
+	match Tcl's quirky construction of its init library path.
+
+2001-08-23  Andreas Kupries <andreas_kupries@users.sourceforge.net>
+
+	* win/tclWinPipe.c (BuildCommandLine): Fixed [Bug 432499]. Part of the
+	code used the non-absolute path to the executable to determine
+	quoting. This failed if the absolute path contained spaces, but the
+	application name itself not. This bug caused no trouble on Win NT 5,
+	but does for other variants in the Win* family. Report and fix due to
+	Ken Poole <kenpoole@users.sourceforge.net>.
+
+2001-08-23  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* unix/configure:
+	* unix/tcl.m4: added QNX-6 build support. [Bug 219410] (loverso)
+
+	* unix/tclUnixFCmd.c:
+	* generic/tclIOUtil.c:
+	* generic/tclFileName.c: corrected minor compiler warnings.
+
+2001-08-23 Vince Darley <vincentdarley@users.sourceforge.net>
+
+	Variety of small filesystem and vfs issues fixed or improved. The new
+	fs code allows many new opportunities for efficiency improvements
+	through the objectified API. The main changes integrated here are such
+	efficiency improvements. Some limitations of the original
+	implementation have also now been lifted. Meanwhile a variety of fs
+	bugs (some old, some new) have also been fixed.
+
+	* generic/tclFileName.c: Made Tcl_FSSplitPath more efficient, and
+	removed some static string-based procedures which are no longer used.
+	Much more objectification. Tcl_FSJoinPath is now very efficient and
+	more aware of virtual filesystems. Clarified where the Mac-specific
+	code attempts to interpret Unix-style paths. Modified TclDoGlob to use
+	lstat not access to fix [Bug 434876] (L. Virden)
+
+	* tcl(Win|Unix|Mac)FCmd.c:
+	* tcl(Win|Unix|Mac)File.c: replaced TclpListVolumes with
+	TclpObjListVolumes with different signature, updated code due to more
+	efficient signature of Tcl_FSGetTranslatedPath. Used cached native
+	paths where possible to improve efficiency -- this was completed on
+	MacOS, but on Unix and Win the traversal functions make the task much
+	more complex, so there are still some improvements possible there.
+	Removed unused TclpNormalizePath which had been left in tclWinFCmd.c.
+	Objectified all 'file attributes' functions. Fixed the new [Bug
+	451571, Bruce Stephens] which is most obvious on Unix, but could occur
+	on MacOS or Windows. This bug actually existed in Tcl 8.3.x but was
+	only made obvious by the recent filesystem overhaul when the code was
+	exercised more heavily.
+	* tests/fileName.test: Three new tests to exercise the above bug, and
+	make sure it is fixed correctly.
+	* unix/tclUnixFile.c: avoid panic in glob when a link doesn't point
+	anywhere. It would probably be good to define exactly what Tcl should
+	do in circumstances like these, and make sure mac/win/unix all behave
+	accordingly. [Bug 417111] (Hemang Lavana). Also fixed
+	misleading/obsolete comment in the code.
+	* generic/tcl.stubs: changed signature of Tcl_FSGetTranslatedPath and
+	added Tcl_FSGetTranslatedStringPath.
+	These changes allow further optimisations in the FS code.
+	* generic/tcl.h: changed signature of Tcl_FSListVolumes so that it
+	doesn't require a Tcl interpreter plus result. Renamed Tcl_FSReadLink
+	to Tcl_FSLink with additional argument so we can support making links
+	in the future. [Patch: 450340]
+	* generic/tclInt.h: added declaration for TclpObjListVolumes.
+	Objectified internal call signatures for 'file attributes' functions,
+	and added an internal objectified get path type function.
+	* generic/tclIOUtil.c: added the moved function TclpListVolumes which
+	calls platform specific code (needed for backwards compatibility), and
+	improved efficiency of parts of the FS (particularly file
+	normalization). Much less copying and memory allocation is required
+	now. added new GetPathType so that changes in 'file volumes' can
+	actually affect files' types, and objectified more code. Made current
+	code work with test suite artificially changing current platform.
+	Added 'static' keywords where required.
+	* generic/tclIO.c:
+	* generic/tclTest.c: Added 'static' keywords, fixing [Bug 453872] (Bob
+	Techentin)
+	* generic/tclCmdAH.c: file command implementation updated for API
+	changes, removed unnecessary special-case SplitPath static function,
+	since it no longer helps prevent code duplication. Moved setting of
+	interpreter result to each individual location that actually required
+	it, to avoid very large code separation between reading and setting
+	the result.
+	* doc/FileSystem.3: updated documentation for the new or changed APIs,
+	and clarified some issues.
+	* doc/SplitPath.3: added pointer to newer APIs in FileSystem.3
+	* doc/filename.n: clarified current implementation of tilde support on
+	Mac/Win.  [Bug 453514] (Sergey Kuzmin)
+	* doc/glob.n: improved documentation for '-directory' and '-path'
+	options.
+
+	There are now many private, obsolete, platform-specific 'Tclp'
+	string-based filesystem APIs which could be removed. We should check
+	whether any of these are used by extensions and, at least in Tcl 9,
+	remove them.
+
+	The above changes signify a ***POTENTIAL INCOMPATIBILITY*** with
+	8.4a3, since signatures of two functions in the new API have changed,
+	but not with older versions of Tcl.
+
+2001-08-23  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* generic/tclBinary.c (FormatNumber): Extract a long from the object
+	and not an int, to stop [binary format] from being unable to format
+	some input numbers on architectures where sizeof(int) is less than
+	sizeof(long) (particularly Alpha). [tiprender Bug 441861]
+
+	* tests/format.test: Converted conditional execution of tests into a
+	test constraint.
+
+2001-08-22  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* win/Makefile.in:
+	* win/makefile.vc: updated install target for dde1.2
+	* doc/dde.n: fixed dde man page (which was totally incorrect).
+	* tests/winDde.test:
+	* win/tclWinDde.c (Tcl_DdeObjCmd): added -binary option to dde request
+	command to allow for returning binary data. [Bug 227482]
+	Updated dde to 1.2
+
+	* tests/tcltest.test: added unixExecs constraint to files that used
+	'grep' in the test. [Bug 453143]
+
+	* library/tcltest/tcltest.tcl: fixed stdio constraint test. [Patch
+	454050] (stanton)
+	Simplified unixExecs constraint test.
+
+2001-08-22  Don Porter <dgp@users.sourceforge.net>
+
+	* tests/ioUtil.test (ioUtil-3.*): Corrected errors in tests revealed
+	by fix of overagressive compiler. [Bug 451200]
+
+2001-08-21  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* generic/tclCompCmds.c:
+	* tests/compile.test: Fixed overagressive compilation of [catch]: it
+	was catching errors at substitution time. [Bug 219184]
+
+2001-08-21  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* tests/tcltest.test (tcltest-12.2): fixed test that would break when
+	env vars weren't Tcl list friendly [Patch 454046] (stanton)
+
+2001-08-20  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* library/http/http.tcl (geturl): added port number to Host: header to
+	comply with HTTP/1.1 spec (RFC 2068). [Bug 452217]
+
+2001-08-16  David Gravereaux <davygrvy@pobox.com>
+
+	* tools/tcl.wse.in:
+	* tools/tcl.hpj.in:
+	* win/tcl.hpj.in:  Removed -kb storage in CVS to ensure these text
+	files are checked-out in the translation mode CVS is in. Setting these
+	as binary as part of an effort to make sure they are always in CRLF,
+	no matter what the CVS translation, is bypassing how CVS works and is
+	confusing.
+
+	* tools/genStubs.tcl:  Removed LF-only output. Having to reconvert
+	back to CRLF before committing to CVS was giving me a headache. [Bug
+	451333]
+
+	* win/makefile.vc: replaced $(WINDIR) with $(include32) for the
+	.rc.res inference rule. winver.h wasn't getting included. [Bug 445630]
+
+2001-08-14  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* generic/tclBasic.c: make the intial maxNestingDepth of an
+	interpreter be MAX_NESTING_DEPTH instead of a hardwired value. [Bug
+	232564]
+
+2001-08-13  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* tests/trace.test: Corrected test numbers. [Bug 449794]
+
+2001-08-12  Mo DeJong  <mdejong@redhat.com>
+
+	* unix/configure: Regen.
+	* unix/configure.in:
+	* unix/tcl.m4: Use GCC variable set by AC_PROG_CC instead of defining
+	our own using_gcc variable.
+
+2001-08-11  Vince Darley <vincentdarley@users.sourceforge.net>
+
+	Variety of small issues introduced by the vfs code fixed:
+	* generic/tclIOUtil.c: uninitialised read.
+	* generic/tclFCmd.c: possible memory leak in file delete with error
+	condition.
+
+2001-08-10  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* generic/tclVar.c:
+	* tests/trace.test: Insure that [array] traces work correctly for
+	undefined variables. [Bug 449094]
+
+2001-08-09  Mo DeJong  <mdejong@redhat.com>
+
+	* unix/Makefile.in: Delete the unused getcwd.o target. [Bug 440942]
+
+2001-08-08  Don Porter <dgp@users.sourceforge.net>
+
+	* library/dde/pkgIndex.tcl:
+	* library/http/http.tcl:
+	* library/http/pkgIndex.tcl:
+	* library/msgcat/msgcat.tcl:
+	* library/msgcat/pkgIndex.tcl:
+	* library/opt/optparse.tcl:
+	* library/opt/pkgIndex.tcl:
+	* library/reg/pkgIndex.tcl:
+	* library/tcltest/tcltest.tcl:
+	* library/tcltest/pkgIndex.tcl: Added checks for package dependencies.
+	Bumped patchlevels of changed packages: http 2.3.2, msgcat 1.2.2,
+	opt 0.4.3, tcltest 2.0.1. [Patch 448931]
+
+	* README:
+	* generic/tcl.h:
+	* tools/tcl.wse.in:
+	* unix/configure:
+	* unix/configure.in:
+	* unix/tcl.spec:
+	* win/README.binary:
+	* win/configure:
+	* win/configure.in: Bumped up patchlevel to 8.4a4 to distinguish CVS
+	snapshots from the 8.4a3 release. This does not necessarily mean there
+	will be an 8.4a4 release. [Bug 448938]
+
+2001-08-06  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	8.4a3 RELEASE
+
+	* changes:
+	* README:
+	* mac/README:
+	* unix/README:
+	* win/README.binary: updated for 8.4a3 release
+
+	* generic/tclFileName.c (Tcl_FSSplitPath): update to Tcl style guide.
+
+	* generic/tclFCmd.c (FileCopyRename): fixed mem leak in introduction
+	of vfs code where a new Tcl_Obj wasn't freed.
+
+	* generic/tclCmdMZ.c (Tcl_RegexpObjCmd, Tcl_RegsubObjCmd): reordered
+	the retrieval of arguments to avoid shimmering bug when the pattern
+	and string referenced the same object.
+
+	* unix/configure: regenerated
+	* unixE/tcl.m4: added GNU (HURD) configuration target.
+	[Patch 442974] (brinkmann)
+
+	* win/README: made note of URL for Windows compilation notes
+
+	* win/tclWinThrd.c (TclpFinalizeMutex, TclpFinalizeCondition): added
+	DeleteCriticalSection calls for cleanup [Patch 419683]
+
+	* unix/tclUnixPipe.c (TclpCreateTempFile): fixed use of tmpnam,
+	which is dangerous. [Patch 442636] (lim)
+	The use of tmpnam in TclpTempFileName must still be changed.
+
+	* tests/http.test (http-4.14): fixed variable error return.
+	[Bug 424252]
+
+2001-08-03  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* win/configure: regenerated
+	* win/tcl.m4: fixed DLLSUFFIX definition to always be ${DBGX}.dll.
+	This is necessary for TEA compliant builds that build shared against a
+	static-built Tcl.
+	* win/Makefile.in ($(TCLSH)): added $(TCL_STUB_LIB_FILE) to build
+	target, otherwise it wouldn't get generated in a static build.
+
+2001-08-06  Andreas Kupries <andreas_kupries@users.sourceforge.net>
+
+	* generic/tclIOCmd.c (Tcl_GetsObjCmd): Applied patch from [Bug 442665]
+	to fix the bug reported by it. The function can corrupt a freed object
+	if it is called with objc == 3. This is because it retrieves resultPtr
+	and does not increment its reference count, but then calls
+	Tcl_ObjSetVar2, which causes the retrieved resultPtr object to be
+	released.
+
+2001-08-06  Don Porter <dgp@users.sourceforge.net>
+
+	* doc/tclsh.1: Added note that the tclsh program is frequently
+	installed with the Tcl version numer as part of the name. [Patch
+	402725]
+
+	* generic/tclPkg.c:
+	* tests/pkg.test:  [package forget] now forgets all of the package
+	arguments it receives, not stopping when a package is not found. [Bug
+	415273]
+
+2001-08-02  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* generic/tclIOUtil.c (Tcl_FSMatchInDirectory): corrected
+	uninitialized value.
+
+2001-08-02  Mo DeJong  <mdejong@redhat.com>
+
+	* generic/tclPlatDecls.h:
+	* win/tclWinPort.h: Revert <tchar.h> related changes made to improve
+	Cygwin support on 2001-07-18. This change ended up breaking the VC++
+	build because of conflicts between Windows APIs and internal Tk APIs.
+
+2001-08-01  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* unix/tclUnixFCmd.c: minor casts to eliminate warnings. (lim)
+	[Patch 440218]
+
+	* tests/parseOld.test: changed some tests that required testwordend to
+	exist to skip in a proper tcltest manner. [Bug 442663]
+
+	* library/http/http.tcl (http::mapReply): the regsub'ing of \n and \t
+	to escape them was unnecessary.
+
+2001-07-31  Vince Darley <vincentdarley@users.sourceforge.net>
+
+	Changes from TIP#17 "Redo Tcl's filesystem"
+	The following files were impacted:
+	* doc/Access.3:
+	* doc/FileSystem.3:
+	* doc/OpenFileChnl.3:
+	* doc/file.n:
+	* doc/glob.n:
+	* generic/tcl.decls:
+	* generic/tcl.h:
+	* generic/tclCmdAH.c:
+	* generic/tclCmdIL.c:
+	* generic/tclCmdMZ.c:
+	* generic/tclDate.c:
+	* generic/tclDecls.h:
+	* generic/tclEncoding.c:
+	* generic/tclFCmd.c:
+	* generic/tclFileName.c:
+	* generic/tclGetDate.y:
+	* generic/tclIO.c:
+	* generic/tclIOCmd.c:
+	* generic/tclIOUtil.c:
+	* generic/tclInt.decls:
+	* generic/tclInt.h:
+	* generic/tclIntDecls.h:
+	* generic/tclLoad.c:
+	* generic/tclStubInit.c:
+	* generic/tclTest.c:
+	* generic/tclUtil.c:
+	* library/init.tcl:
+	* mac/tclMacFCmd.c:
+	* mac/tclMacFile.c:
+	* mac/tclMacInit.c:
+	* mac/tclMacPort.h:
+	* mac/tclMacResource.c:
+	* mac/tclMacTime.c:
+	* tests/cmdAH.test:
+	* tests/event.test:
+	* tests/fCmd.test:
+	* tests/fileName.test:
+	* tests/io.test:
+	* tests/ioCmd.test:
+	* tests/proc-old.test:
+	* tests/registry.test:
+	* tests/unixFCmd.test:
+	* tests/winDde.test:
+	* tests/winFCmd.test:
+	* unix/mkLinks:
+	* unix/tclUnixFCmd.c:
+	* unix/tclUnixFile.c:
+	* unix/tclUnixInit.c:
+	* unix/tclUnixPipe.c:
+	* win/tclWinFCmd.c:
+	* win/tclWinFile.c:
+	* win/tclWinInit.c:
+	* win/tclWinPipe.c:
+
+2001-07-24  Mo DeJong  <mdejong@redhat.com>
+
+	* win/tclWinThrd.c (Tcl_CreateThread): Close Windows HANDLE returned
+	by _beginthreadex. The MS documentation states that this handle is not
+	closed by a later call to _endthreadex.
+
+2001-07-21  Don Porter  <dgp@users.sourceforge.net>
+
+	* doc/pkgMkindex.n:
+	* library/package.tcl:  Corrected documentation and usage message of
+	[pkg_mkIndex].
+
+2001-07-18  Mo DeJong  <mdejong@redhat.com>
+
+	* generic/tclPlatDecls.h: Define TCHAR by including windows.h instead
+	of tchar.h since Cygwin does not support the tchar.h header. Include
+	CHECK_UNICODE_CALLS logic from tclWinPort.h.
+	* win/tclWinPort.h: Remove CHECK_UNICODE_CALLS logic. Remove include
+	of windows.h since this now done it tclPlatDecls.h.
+	* win/tclWinReg.c: Remove duplicate include of windows.h.
+
+2001-07-18  Andreas Kupries <andreas_kupries@users.sourceforge.net>
+
+	* generic/tclIO.c: Aftermath to [Bug 427196]. Squash empty buffers if
+	they are smaller than the requested buffersize, to prevent reusage of
+	old buffers and to honor changes in the requested buffersize made by
+	the user.
+
+2001-07-17  Mo DeJong  <mdejong@redhat.com>
+
+	* win/tclWinFile.c (TclpReadlink): Add Cygwin specific definition for
+	the TclpReadlink function. This method implements reading of symbolic
+	links when build with Cygwin.
+
+2001-07-17  Mo DeJong  <mdejong@redhat.com>
+
+	* win/tclWinPort.h: Add Cygwin specific defines for environ and
+	timezone variables.
+
+2001-07-17  Andreas Kupries <andreas_kupries@users.sourceforge.net>
+
+	* generic/tclIO.c (GetInput): Fixed [Bug 427196]. Memory was
+	overwritten because a buffer was used after a change of the requested
+	buffersize together with that requested buffersize and not its actual
+	size, which was smaller. Note that the continous reuse of the smaller
+	buffer negatively impacts performance. The system never allocates a
+	buffer with the newly requested bigger buffersize.
+
+2001-07-16  Mo DeJong  <mdejong@redhat.com>
+
+	* generic/tcl.h: Define __WIN32__ when __CYGWIN__ or __MINGW32__ is
+	defined.
+	* generic/tclAlloc.c: Define caddr_t when compiling with VC++ or
+	mingw. This type is already defined when compiling with Cygwin.
+
+2001-07-16  Mo DeJong  <mdejong@redhat.com>
+
+	* win/tclWinConsole.c:
+	* win/tclWinPipe.c:
+	* win/tclWinPort.h:
+	* win/tclWinSerial.c:
+	* win/tclWinThrd.c:
+	Remove unnecessary #includes of dos.h, direct.h, and tchar.h. This
+	will help the Cygwin porting effort since these headers do not exist
+	under Cygwin.
+
+2001-07-16  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* win/tclWinPipe.c (PipeClose2Proc): constrained the mutex lock to
+	just the TerminateThread call and waiting for termination. (jsmith)
+
+	* generic/tclCmdMZ.c: Removed extra copy of the SCAN_* macros
+	#defined in generic/tclScan.c. [Bug 441230] (porter)
+
+2001-07-12  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* tests/unixInit.test (unixInit-2.8): Added extra constraint,
+	notInstalledInTmp, to stop this test from damaging installations in
+	/tmp; not much fun to have to reinstall the Tcl library every time you
+	run the test suite!
+
+	* tests/subst.test (subst-10.*): Updated tests to check new behaviour
+	for 'break' in command substitutions.
+	(subst-1.2,subst-7.1): Error messages changed.
+	* doc/SubstObj.3: New file, to document Tcl_SubstObj.
+	* doc/subst.n: Improved and updated documentation for 'subst' to help
+	support the changed behaviour.
+	* generic/tcl.decls (generic-437): Declaration for Tcl_SubstObj
+	* generic/tcl.h (TCL_SUBST_*): Added flags for Tcl_SubstObj.
+	* generic/tclCmdMZ.c (Tcl_SubstObj,Tcl_SubstObjCmd): Divided into two
+	parts to allow people to access the innards of 'subst' and changed the
+	behaviour when command substitutions do a 'break' to be different from
+	'continue'. Also now works with objects, which allows for some nifty
+	optimisations with variable substitutions and a slight improvement
+	with command substitutions. [TIP#36]
+
+2001-07-10  Mo DeJong  <mdejong@redhat.com>
+
+	* unix/Makefile.in: Add AR variable for use in STLIB_LD.
+	* unix/configure: Regen.
+	* unix/configure.in: Use STLIB_LD when defining MAKE_LIB and
+	MAKE_STUB_LIB. Subst RANLIB and AR.
+	* unix/tcl.m4 (SC_CONFIG_CFLAGS): Add doc comment about STLIB_LD
+	command. Check ${AR} env var when setting STLIB_LD and delay
+	evaluation until make time.
+	* win/configure: Regen.
+	* win/tcl.m4 (SC_CONFIG_CFLAGS): Delay evaluation of ${AR} in STLIB_LD
+	and add flags to better match the Unix implementation. Don't bother
+	defining AR when using VC++ since it is not used.
+
+2001-07-06  Mo DeJong  <mdejong@redhat.com>
+
+	* win/configure: Regen.
+	* win/tcl.m4 (SC_CONFIG_CFLAGS): Pass -e _WinMain@16 in addition to
+	the -mwindows flag to work around a problem with ld when it
+	incorrectly use main() as the executable entry point when both
+	WinMain() and main() are available.
+
+2001-07-06  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* tests/cmdAH.test: Added leading zero to file modes to work around
+	fault in HPUX strtol() which ignores the base parameter. [Bug 438808]
+
+2001-07-05  Mo DeJong  <mdejong@redhat.com>
+
+	* win/Makefile.in: Subst DEPARG directly instead of relying on a
+	variable. This will make Cygwin builds faster since an extra exec will
+	be avoided.
+	* win/configure: Regen.
+	* win/configure.in: Subst DEPARG.
+	* win/tcl.m4 (SC_CONFIG_CFLAGS): Move AC_MSG_CHECKING after the
+	AC_CHECK_PROG so that status messages do not get mixed together. Set
+	DEPARG based on the results of the cygpath check so that we avoid
+	using an extra exec when it is not needed. Use ac_cv_cygwin status
+	flag instead of looking at the output of gcc -v, which works in the
+	case where -mno-cygwin is set in the CFLAGS.
+
+2001-07-04  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* README:
+	* mac/README:
+	* unix/README:
+	* win/README:
+	* win/README.binary: updated READMEs with purls
+
+2001-07-03  Mo DeJong  <mdejong@redhat.com>
+
+	* win/Makefile.in: Remove PATHTYPE variable.
+	* win/configure: Regen.
+	* win/configure.in: Don't subst PATHTYPE.
+	* win/tcl.m4 (SC_CONFIG_CFLAGS): Remove PATHTYPE variable. Set CYGPATH
+	to "cygpath -w" if the cygpath executable is found on the path. This
+	approach works for native Cygwin builds and cross compiles.
+
+2001-07-03  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* tests/var.test:
+	* generic/tclVar.c (Tcl_VariableObjCmd): added patch to check for
+	number of args. [Patch 426038]
+
+	* generic/tclVar.c (Tcl_GetVar2Ex): added ability to recognize
+	TCL_TRACE_READS flags to cause creation of part1 in TclLookupVar to
+	make sure newly created array will get read traces triggered
+	appropriately. This is called by Tcl_ObjGetVar2, Tcl_GetVar, and
+	Tcl_GetVar2.
+	(TclSetIndexedScalar, TclSetElementOfIndexedArray): added read trace
+	triggering for lappend case.
+	(Tcl_LappendObjCmd): pass TCL_TRACE_READS to Tcl_ObjGetVar2 to trigger
+	possible read traces for new arrays.
+
+	* generic/tclExecute.c (TclExecuteByteCode): added TCL_TRACE_READS
+	flag to INST_LAPPEND(_ARRAY)_STK case to trigger read traces for newly
+	created arrays. Removed unnecessary #ifdef for TCL_COMPILE_DEBUG in
+	INST_LOAD_SCALAR1 case.
+
+	* tests/append.test:
+	* tests/appendComp.test: added tests for read trace triggering for
+	append and lappend.
+
+2001-07-03  Mo DeJong  <mdejong@redhat.com>
+
+	* tests/clock.test (clock-2.5): Adjust test so that it passes when the
+	time slice is 60 msecs, now passes under Windows 98.
+
+2001-07-03  Mo DeJong  <mdejong@redhat.com>
+
+	* win/tcl.m4 (SC_CONFIG_CFLAGS): Don't pass the v flag to ${AR} when
+	using gcc, verbose output is not needed.
+
+2001-07-03  Don Porter  <dgp@users.sourceforge.net>
+
+	* tests/unixInit.test (unixInit-2.8):  Changed test back to using
+	installation layout, adding comments explaining why the test writes to
+	the directories it does, and checks to avoid destroying other files in
+	/tmp.
+
+2001-07-03  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* tests/unixInit.test (unixInit-1.2): Fixed faults reported in
+	[Bug 438070] - well, at least enough to work on Solaris - and added
+	comments that should make what is going on in the test clearer.
+
+2001-07-02  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* tests/util.test: added util-4.6
+	* generic/tclUtil.c (Tcl_ConcatObj): Corrected walking backwards over
+	utf-8 chars. [Bug 227512]
+
+2001-07-02  Don Porter  <dgp@users.sourceforge.net>
+
+	* tests/unixInit.test (unixInit-2.8):  Corrected test for all absolute
+	pathnames in library path when executable is installed near root
+	directory to use correct development directory layout. [Bug 438014]
+
+	* tests/unixInit.test (unixInit-2.9):
+	* unix/tclUnixInit.c (TclpInitLibraryPath):
+	* win/tclWinInit.c (TclpInitLibraryPath):  Corrected buggy
+	construction of search path entries relative to executable. Added test
+	for bad construction. [Bug 438014]
+
+2001-06-28  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* generic/tclNamesp.c: Correction to faulty patch from [Bug 231259]
+
+2001-06-28  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* tests/unixInit.test (unixInit-1.2): Modified so as not to require a
+	local echo service, which fails on many systems which have that turned
+	off for security reasons...
+
+2001-06-27  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* generic/tclInt.h:
+	* generic/tclObj.c:
+	* unix/Makefile.in: added a -DPURIFY mode that makes Tcl_Obj's
+	allocated and free singularly (instead of in alloc in blocks and never
+	free) to allow checkers like Purify to operate better.
+
+	* library/encoding/koi8-u.enc: added koi8-u (Ukranian variant)
+	encoding.
+
+	* tests/subst.test:
+	* generic/tclUtf.c (Tcl_UtfBackslash): Corrected backslash handling of
+	multibyte utf-8 chars. [Bug 217987]
+
+	* generic/tclCmdIL.c (InfoProcsCmd): fixed potential mem leak in info
+	procs that created objects without using them.
+
+	* generic/tclCompCmds.c (TclCompileStringCmd): fixed mem leak when
+	string command failed to parse the subcommand.
+
+	* doc/interp.n:
+	* doc/unknown.n: updated notes about what is in a safe interp. [Bug
+	218605]
+
+2001-06-27  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* tests/event.test (event-11.5): Removed hard-coded port number which
+	could fail on some systems. [Bug 436727]
+
+2001-06-26  Mo DeJong  <mdejong@redhat.com>
+
+	* unix/Makefile.in:
+	* win/Makefile.in: Add `make shell` target. This target will set the
+	proper env vars before invoking tclsh from the build directory.
+
+2001-06-26  Mo DeJong  <mdejong@redhat.com>
+
+	* win/Makefile.in: Use : to separate VPATH entries. This works for
+	both Cygwin builds and cross builds, the VPSEP variable is simply
+	unneeded complexity.
+	* win/configure: Regen.
+	* win/configure.in: Don't subst VPSEP.
+	* win/tcl.m4 (SC_CONFIG_CFLAGS): Remove VPSEP variable.
+
+2001-06-26  Mo DeJong  <mdejong@redhat.com>
+
+	* unix/configure: Regen.
+	* unix/configure.in: Fix last checkin by removing export since that
+	only works in bash.
+	* win/configure: Regen.
+	* win/configure.in: Ditto.
+
+2001-06-26  Mo DeJong  <mdejong@redhat.com>
+
+	* unix/configure: Regen.
+	* unix/configure.in: Set CFLAGS to "" if the user did not set CFLAGS
+	in the env. This keeps AC_PROG_CC from adding "-g -O2" to the CFLAGS
+	by default.
+	* win/configure: Regen.
+	* win/configure.in: Ditto.
+
+2001-06-25  Mo DeJong  <mdejong@redhat.com>
+
+	* win/configure: Regen.
+	* win/configure.in: Use RC_DEFINE flag from tcl.m4.
+	* win/tcl.m4 (SC_CONFIG_CFLAGS): Set RC_DEFINE flag based on the
+	compiler in use.
+
+2001-06-25  Mo DeJong  <mdejong@redhat.com>
+
+	* win/tcl.m4 (SC_CONFIG_CFLAGS): Link to the imm32 library when
+	building with mingw gcc.
+
+2001-06-25  Mo DeJong  <mdejong@redhat.com>
+
+	* win/configure: Regen.
+	* win/tcl.m4 (SC_CONFIG_CFLAGS): When building with gcc, don't attempt
+	to link with LD or support dllwrap. Simply require a recent version of
+	Cygwin gcc or Mingw gcc that supports -shared. When linking, use gcc
+	instead of ld since gcc automatically includes libs like -lmsvcrt.
+
+2001-06-22  Mo DeJong  <mdejong@redhat.com>
+
+	* win/configure: Regen.
+	* win/configure.in: Add resource compiler fix from 8.3.3 to fix
+	compiling with mingw.
+
+2001-06-22  Mo DeJong  <mdejong@redhat.com>
+
+	* win/configure: Regen.
+	* win/tcl.m4: Fix silly typo in last checkin.
+
+2001-06-22  Mo DeJong  <mdejong@redhat.com>
+
+	* unix/Makefile.in: Set CFLAGS to @CFLAGS@ and @CFLAGS_DEFAULT@. Set
+	LDFLAGS to @LDFLAGS@ and @LDFLAGS_DEFAULT@. Add LDFLAGS_DEBUG and
+	LDFLAGS_OPTIMIZE to match the way CFLAGS_DEFAULT works. This will
+	support user set CFLAGS or LDFLAGS at configure time.
+	* unix/configure: Regen.
+	* unix/configure.in: Don't set CFLAGS to CFLAGS_DEFAULT, instead
+	subst CFLAGS_DEFAULT into the Makefile. Add AC_SUBST for
+	CFLAGS_DEFAULT, LDFLAGS_DEFAULT, LDFLAGS_DEBUG, and LDFLAGS_OPTIMIZE.
+	* unix/tcl.m4 (SC_ENABLE_SYMBOLS): Modify LDFLAGS_DEFAULT so that it
+	uses a Makefile variable just like CFLAGS_DEFAULT.
+	* win/Makefile.in: Set CFLAGS to @CFLAGS@ and @CFLAGS_DEFAULT@. Set
+	LDFLAGS to @LDFLAGS@ and @LDFLAGS_DEFAULT@. This will support user set
+	CFLAGS or LDFLAGS at configure time.
+	* win/configure: Regen.
+	* win/configure.in: Don't set CFLAGS or LDFLAGS, instead subst
+	CFLAGS_DEFAULT and LDFLAGS_DEFAULT into the Makefile.
+	* win/tcl.m4 (SC_ENABLE_SYMBOLS): Modify LDFLAGS_DEFAULT so that it
+	uses a Makefile variable just like CFLAGS_DEFAULT.
+
+2001-06-22  Mo DeJong  <mdejong@redhat.com>
+
+	* win/configure:
+	* win/tcl.m4 (SC_CONFIG_CFLAGS): Don't set LDFLAGS_DEBUG to -g or
+	LDFLAGS_OPTIMIZE to -O when compiling with gcc. These flags are not
+	needed and can cause problems with the Cygwin version of ld.
+
+2001-06-18  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* tests/unixInit.test (unixInit-1.2,unixInit-2.8): Added test for code
+	described below, and fixed a couple of errors that caused problems
+	during testing; the code to determine the installedTcl constraint was
+	wrong, and test unixInit-2.8 assumed that /tmp/lib was free for use
+	and could be deleted, which clashed nastily with my installation and
+	made other tests fail unnecessarily!
+
+	* unix/tclUnixChan.c (TtyInit,TclpOpenFileChannel,
+	(Tcl_MakeFileChannel,TclpGetDefaultStdChannel): Alterations so that
+	the standard channels - stdin, stdout and stderr - have the correct
+	type and fconfigure options. This required making the initialisation
+	of serial lines a little more sophisticated to make the console behave
+	correctly in interactive mode... [Bug 219137 and duplicates]
+
+2001-06-16  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclInt.decls:
+	* generic/tclInt.h:
+	* generic/tclPanic.c (Tcl_PanicVA):
+	* mac/tclMacAppInit.c (main):
+	* mac/tclMacPanic.c (TclpPanic):
+	* unix/tclUnixPort.h:
+	* win/tclWinPort.h: Replaced TclMacSetPanic with TclpPanic for setting
+	a platform-specific panic handler. TclpPanic is NULL on Unix and
+	Windows. Fixes broken wish on Mac due to earlier patches. [Patch
+	415648]
+
+	* generic/tclIntPlatDecls.h:
+	* generic/tclStubInit.c: `make gentubs` after above changes.
+
+2001-06-13  Don Porter  <dgp@users.sourceforge.net>
+
+	* mac/tclMacAppInit.c (main, Macintosh_Init):
+	* mac/tclMacBOAAppInit.c (main):
+	* mac/tclMacPanic.c: Applied patches from Dan Steffen correcting
+	problems on the Macintosh in the 2001-06-08 changes.
+
+2001-06-12  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* tests/regexp.test (regexp-18.12):
+	* generic/tclCmdMZ.c (Tcl_RegexpObjCmd): Fixed so that submatches
+	that do not match always have index pair {-1 -1} [Bug 219232]
+
+2001-06-08  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tcl.h:
+	* generic/tcl.decls:
+	* generic/tclPanic.c: Added CONST to Tcl_*Panic* public interfaces.
+	[Patch 415648, TIP 27]
+
+	* generic/tclInt.decls:
+	* mac/tclMacAppInit.c (main):
+	* mac/tclMacBOAAppInit.c (main):
+	* mac/tclMacPanic.c: Modified special Mac implementations of
+	Tcl_*Panic* to be exact copies of the generic implementations. Added
+	TclMacSetPanic. The generic implementations should be used directly,
+	rather than copies, but that requires further changes by someone
+	familiar with the Mac build systems. [Patch 415648]
+
+	* generic/tclDecls.h:
+	* generic/tclIntPlatDecls.h:
+	* generic/tclStubInit.c: `make gentubs` after above changes.
+
+	* doc/Panic.3:
+	* unix/mkLinks:  New file documenting Tcl_*Panic* public interfaces,
+	followed by `make mklinks`. [Patch 415648, Bug 219170, Bug 414936]
+
+2001-06-03  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* generic/tclUtil.c (Tcl_DStringAppendElement): patch to save an
+	extra strlen call. [Bug 428572]
+
+2001-05-30  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* generic/tclExecute.c (TclExecuteByteCode): Added two casts to
+	INST_STR_CMP implementation to get rid of a couple warnings from the
+	SUNWspro C compiler.
+
+	* generic/tclBasic.c (Tcl_GetMathFuncInfo,Tcl_ListMathFuncs):
+	* generic/tclCmdIL.c (Tcl_InfoObjCmd,InfoFunctionsCmd):
+	* generic/tcl.decls (generic table, positions 435+436):
+	* tests/info.test:
+	* doc/CrtMathFnc.3:
+	* doc/info.n: Changes due to TIP #15 "Functions to List and Detail
+	Math Functions"
+
+2001-05-28  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* library/init.tcl (unknown): removed errant " in error message
+
+2001-05-27  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* generic/regc_locale.c: updated character class range data for
+	Unicode v3.1.0 compliance.
+	* generic/tclUniData.c: regenerated from Unicode v3.1.0 data file (new
+	as of 2001-05-16). This brings Tcl to current unicode compliance.
+
+	* tests/utf.test: added tests to check unicode 3 compliance
+
+	* unix/Makefile.in (tclUtf.o): added tclUniData.c dependency.
+
+	* tools/uniClass.tcl: added comments to output format and the script
+	for clarification.
+
+	* tools/uniParse.tcl: corrected filename output and GetDelta macro to
+	use 'info' as param (was 'infO')
+
+2001-05-26  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* generic/tclVar.c (tclArraySearchType,SetArraySearchObj,
+	(ParseSearchId): Added code to speed up array searching by reducing
+	the amount of parsing needed for searchIds.
+
+	* generic/tclObj.c (TclInitObjSubsystem):
+	* generic/tclIndexObj.c (Tcl_GetIndexFromObjStruct):
+	* generic/tclNamesp.c (TclInitNamespaceSubsystem):
+	* generic/tclInt.h: Moved some Tcl_ObjType initialisation to
+	TclInitObjSubsystem to be with the bulk of the rest. [Patch 424851]
+	Committed by Miguel Sofer <mig@utdt.edu>
+
+2001-05-23  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* tests/io.test: changed io-52.[9-11] to not be platform sensitive
+	with EOL translation.
+
+	* library/encoding/cp1250.enc:
+	* library/encoding/cp1251.enc:
+	* library/encoding/cp1252.enc:
+	* library/encoding/cp1253.enc:
+	* library/encoding/cp1254.enc:
+	* library/encoding/cp1255.enc:
+	* library/encoding/cp1256.enc:
+	* library/encoding/cp1257.enc:
+	* library/encoding/cp1258.enc:
+	* library/encoding/cp874.enc:
+	* library/encoding/iso8859-6.enc:
+	* library/encoding/iso8859-7.enc:
+	* library/encoding/iso8859-8.enc:
+	* library/encoding/iso8859-10.enc (new):
+	* library/encoding/iso8859-13.enc (new):
+	* library/encoding/iso8859-14.enc (new): updated encoding tables based
+	on http://www.unicode.org/Public/MAPPINGS/. (kuhn)
+
+2001-05-23  Mo DeJong  <mdejong@redhat.com>
+
+	* unix/tcl.m4 (SC_PATH_TCLCONFIG): Fix comments, and typo in cached
+	variable name.
+
+2001-05-23  Mo DeJong  <mdejong@redhat.com>
+
+	* unix/tcl.m4 (SC_LOAD_TKCONFIG): Remove use of undefined TCLCONFIG
+	variable and call AC_MSG_RESULT to print the checking result.
+	* win/tcl.m4: Ditto.
+
+2001-05-22  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* generic/tclObj.c (TclAllocateFreeObjects): simplified
+	objSizePlusPadding to use sizeof(Tcl_Obj) (max) Corrected use of
+	tclObjsAlloced/Freed/Shared in TCL_MEM_DEBUG compile.
+
+2001-05-22  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* generic/tclExecute.c: removed Tcl_DuplicateObj in INST_DUP
+
+2001-05-21  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* tests/tcltest.test (tcltest-19.1): fixed failing test that was
+	getting affected by Windows env handling of empty valued elements.
+
+	* unix/tcl.m4: added more common install directories in which to
+	search for *Config.sh. [Bug 419812]
+
+	* tests/cmdMZ.test (cmdMZ-1.4): added notLinux constraint to test to
+	prevent failure message on Linux due to OS caching bug.
+
+	* tests/httpd (httpdRespond): added response to timeout value in query
+	string.
+
+	* tests/http.test: removed unused notLinux constraint setting
+
+	* generic/tclRegexp.c (Tcl_RegExpExecObj): added use of
+	Tcl_GetUnicodeFromObj.
+
+2001-05-19  Andreas Kupries <andreas_kupries@users.sourceforge.net>
+
+	* Note that "tclbench" (see project "tcllib") was extended with
+	performance benchmarks for [fcopy] too.
+
+	* doc/fcopy.n: Updated to reflect the extended behaviour of 'fcopy'.
+
+	* tests/io.test: Added tests 'io-52.9', 'io-52.10' and 'io-52.11' to
+	test the handling of encodings by 'fcopy' / 'TclCopychannel'. [Bug
+	209210]
+
+	* generic/tclIO.c: Split of both 'Tcl_ReadChars' and 'Tcl_WriteChars'
+	into a public error checking and an internal working part. The public
+	functions now use the new internal ones. The new functions are
+	'DoReadChars' and 'DoWriteChars'. Extended 'CopyData' to use the new
+	functions 'DoXChars' when required by the encodings on the input and
+	output channels. [Bug 209210]
+
+2001-05-16  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* library/history.tcl (tcl::HistAdd): prevent empty calls from being
+	added to the history (arndt)
+
+	* tests/error.test: updated error-1.3 message to account for string
+	index being compiled at toplevel.
+	* tests/appendComp.test:
+	* tests/stringComp.test: new files for extended bytecode testing
+
+	* generic/tclBasic.c: added new CompileProc invocations to basic
+	command initialization.
+	* generic/tclCompCmds.c: added new compile commands for append,
+	lappend, lindex and llength. Refactored set and incr compile commands
+	to use new TclPushVarName function for handling the varname component
+	during compilation (also used by append and lappend). Changed string
+	compile command to compile toplevel code as well (when possible).
+	* generic/tclCompile.c: added new instruction enums
+	* generic/tclCompile.h: added debug info for new instructions
+	* generic/tclExecute.c (TclExecuteByteCode): moved elemPtr to toplevel
+	var (oft-used). Added definitions for new bytecode instructions
+	INST_LIST_INDEX, INST_LIST_LENGTH, INST_APPEND_SCALAR1,
+	INST_APPEND_SCALAR4, INST_APPEND_ARRAY1, INST_APPEND_ARRAY4,
+	INST_APPEND_ARRAY_STK, INST_APPEND_STK, INST_LAPPEND_SCALAR1,
+	INST_LAPPEND_SCALAR4, INST_LAPPEND_ARRAY1, INST_LAPPEND_ARRAY4,
+	INST_LAPPEND_ARRAY_STK, INST_LAPPEND_STK.
+	Refactored repititious code for reuse with INST_LOAD_STK (same as
+	INST_LOAD_SCALAR_STK), INST_STORE_STK (same as INST_STORE_SCALAR_STK).
+	Updated INST_STR_CMP with style of fix of 2001-04-06 Fellows
+	[Bug 219201] as that fix only affected the runtime eval'ed "string"
+	(string compare is normally byte-compiled now). We may want to back
+	these out for speed in the future, noting the problems with \x00
+	comparisons in the docs.
+	* generic/tclInt.h: declarations for new compile commands.
+	* generic/tclVar.c: change TclGetIndexedScalar,
+	TclGetElementOfIndexedArray, TclSetElementOfIndexedArray and
+	TclSetIndexedScalar to use flags. The Set functions now support
+	TCL_APPEND_ELEMENT and TCL_LIST_ELEMENT as well.
+	* generic/tclInt.decls:
+	* generic/tclIntDecls.h: minor signature changes for above.
+
+	* generic/tclCmdMZ.c: made use of new Tcl_GetUnicodeFromObj.
+
+2001-05-16  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* doc/console.n: Deleted. Put it in the wrong source tree! D'oh!
+
+2001-05-15  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* generic/tcl.decls:
+	* generic/tclDecls.h:
+	* generic/tclStubInit.c:
+	* generic/tclStringObj.c (Tcl_GetUnicodeFromObj): new function to
+	parallel Tcl_GetStringFromObj (fix of an API oversight).
+
+	* unix/tclUnixPipe.c: updated pipeChannelType to TCL_CHANNEL_VERSION_2
+	type specification.
+
+	* tests/fileName.test: corrected tests not to fail on win when a
+	C:/test dir exists.
+
+	* generic/tclFileName.c (ExtractWinRoot): corrected ABR error
+
+2001-05-15  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* tests/lindex.test: added test for nested braces [Patch 423617]
+
+2001-05-15  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* generic/tclInt.h:
+	* generic/tclNamesp.c: invalidate all bytecodes in a namespace if a
+	new command shadows a bytecoded command.
+	* tests/namespace.test:
+	Patched from [Bug 231259]
+
+2001-05-15  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* doc/console.n: Created. It seems very odd to me that the console
+	implementation is part of the Tcl distribution and not part of Tk, but
+	given the location of the source, the documentation must obviously
+	match up...
+
+2001-05-14  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* generic/tclCmdMZ.c (Tcl_StringObjCmd):
+	* tests/string.test (string-4.14): Negative string indices should not
+	be added as offsets to the result of [string first] but instead be
+	treated as referring to the start of the string. [Bug 423581]
+
+2001-05-11  Mo DeJong  <mdejong@redhat.com>
+
+	* unix/Makefile.in: Add a LDFLAGS variable to the Makefile instead of
+	directly substing @LDFLAGS@.
+	* unix/configure: Regen.
+	* unix/tcl.m4: Fix CFLAGS_DEFAULT so that the name of a Makefile
+	variable is passed as @CFLAGS@.
+	* win/Makefile.in: Move the setting of CFLAGS higher up in the
+	Makefile.
+	* win/configure: Regen.
+	* win/configure.in: Use dnl to comment out macros so that they are not
+	accidently expanded.
+	* win/tcl.m4: Fix CFLAGS_DEFAULT so that the name of a Makefile
+	variable is passed as @CFLAGS@.
+
+2001-05-07  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* generic/tclExecute.c: insure different rand() seeds in different
+	threads. [Bug 416643]
+
+2001-05-03  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* tests/tcltest.test: removed extraneous 'c' (doh!) [Bug: 414031]
+
+	* tools/tcltk-man2html.tcl: removed use of 'exec' for portability and
+	fixed up code.
+
+2001-05-03  Don Porter  <dgp@users.sourceforge.net>
+
+	* doc/library.n:
+	* library/init.tcl:
+	* tests/autoMkindex.t*: Modified [auto_import] to apply pattern
+	matching in the [namespace import] style. [Bug 420186]
+	***POTENTIAL INCOMPATIBILITY*** for any callers of [auto_import] from
+	outside Tcl that expect the pattern matching to be like that of
+	[string match].
+
+2001-05-03  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* generic/tclParse.c:
+	* tests/namespace.test: Insure consistent behaviour of the [unknown]
+	command: when a command is unknown, it is always processed by
+	[::unknown], ignoring any namespace proc which happens to be called
+	"unknown" [Patch 421166, Bug 420507]
+
+2001-05-02  Don Porter  <dgp@users.sourceforge.net>
+
+	* tools/genStubs.tcl: Add a package require of Tcl 8 at the beginning
+	of the script so that the script will print a descriptive error
+	message when run in an old Tcl 7 shell.
+
+2001-04-27  Kevin Kenny	<kennykb@crd.ge.com>
+
+	* generic/tclInt.decls:
+	* generic/tclInt.h:
+	* generic/tclCmdIL.c:
+	* generic/tclProc.c:
+	* generic/tclVar.c: Added another collection of missing CONSTs related
+	to TclGetNamespaceForQualName.
+	* generic/tclIntDecls.h: Regenerated.
+
+2001-04-25  Mo DeJong  <mdejong@redhat.com>
+
+	* unix/configure: Regen.
+	* unix/tcl.m4: Subst TCL_THREADS into tclConfig.sh.
+	* unix/tclConfig.sh.in: Add TCL_THREADS variable.
+	* win/configure: Regen.
+	* win/tcl.m4: Subst TCL_THREADS into tclConfig.sh.
+	* win/tclConfig.sh.in: Add TCL_THREADS variable.
+
+2001-04-25  Mo DeJong  <mdejong@redhat.com>
+
+	* unix/configure: Regen.
+	* unix/configure.in: Use $@ in MAKE_LIB and MAKE_STUB_LIB commands
+	instead of using a delayed subst variable. Replace instances of
+	STUB_LIB_FILE with TCL_STUB_LIB_FILE.
+
+2001-04-25  Mo DeJong  <mdejong@redhat.com>
+
+	* unix/Makefile.in: Use TCL_STUB_LIB_FILE instead of STUB_LIB_FILE.
+	* unix/configure: Regen.
+	* unix/configure.in: Don't subst STUB_LIB_FILE, use TCL_STUB_LIB_FILE
+	instead.
+
+2001-04-25  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* tools/encoding/iso8859-15.txt:
+	* library/encoding/iso8859-15.enc: Oops! Got the full encoding wrong.
+	Should be fixed now...
+
+	* tools/encoding/iso8859-15.txt:
+	* library/encoding/iso8859-15.enc:
+	* tools/tcl.wse.in: Added ISO 8859-15 (a.k.a. Latin-1 + Euro currency
+	symbol) support.
+
+	* generic/tclNamesp.c:
+	* generic/tclBasic.c (TclRenameCommand): Missing CONST from several
+	declarations relating to use of TclGetNamespaceForQualName
+
+2001-04-24  Kevin B. Kenny    <kennykb@acm.org>
+
+	* doc/AssocData.3:
+	* doc/CrtCommand.3:
+	* doc/CrtMathFnc.3:
+	* doc/CrtObjCmd.3:
+	* doc/ExprLong.3:
+	* generic/tclBasic.c:
+	* generic/tclCmdMZ.c:
+	* doc/CrtSlave.3:
+	* generic/tclNamesp.c:
+	* generic/tcl.decls:
+	* generic/tcl.h:
+	* generic/tclInt.decls:
+	* generic/tclInt.h: (TIP #27) Another round of CONST changes, this
+	time adding CONST to the API's exported from tclBasic.c. [Patch
+	415179]
+	***POTENTIAL INCOMPATIBILITY*** from 8.4a2, in which Vince Darley's
+	changes to command tracing were added. A const has been added to the
+	type signature of one of the parameters to Tcl_CommandTraceProc.
+
+2001-04-10  Kevin B. Kenny    <kennykb@acm.org>
+
+	* unix/tclUnixTime.c: Altered code to use memcpy instead of
+	structure assigments in an effort to achieve better K&R
+	compatibility.
+
+2001-04-10  Kevin B. Kenny    <kennykb@acm.org>
+
+	* unix/tclUnixTime.c: Fixed silly typo in calls to 'gmtime' and
+	'localtime' that broke the Linux build.
+
+2001-04-09  Kevin B. Kenny    <kennykb@acm.org>
+
+	* unix/tclLoadShl.c: Added DYNAMIC_PATH to the load flags so that the
+	SHLIB_PATH will be searched for other libraries. [Bug 219140]
+
+2001-04-09  Kevin B. Kenny    <kennykb@acm.org>
+
+	* unix/tcl.m4: Added _REENTRANT to Solaris build so that thread safe
+	library routines are included.
+	* unix/configure: Re-ran 'autoconf' with changed tcl.m4
+	* tclUnixTime.c: Modified for thread safety of 'gmtime' and
+	'localtime' system calls. [Bugs 219136 and 232558]
+
+2001-04-09  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* tests/expr.test (expr-21.*): Tests to check below fix.
+	* generic/tclParseExpr.c (GetLexeme): Now recognises the
+	non-numeric boolean literals for what they are. It no longer makes
+	sense for anyone to create functions with the same name as one of
+	them, but this was true in 7.* as well [Bug 217777; finally!]
+
+2001-04-07  Miguel Sofer <msofer@users.sourceforge.net>
+
+	* generic/tclExecute.c: Avoid panic when there are extra items in the
+	tcl stack. [Bug 406709, Patch 414470]
+	* tests/foreach.test: test to exercise the patch
+
+2001-04-07  Miguel Sofer <msofer@users.sourceforge.net>
+
+	* doc/namespace.n: document correct functionality
+	* generic/tclNamesp.c: corrected behaviour of [namespace code]
+	[Bug 219385, Patch 403530]
+	* library/init.tcl:
+	* tests/namespace-old.test: test correct functionality
+	* tests/namespace.test: test correct functionality
+
+2001-04-07  Andreas Kupries  <andreas_kupries@users.sourceforge.net>
+
+	* unix/Makefile.in (checkdoc): New target, checking the definitions as
+	found in the compiled library against the manpages to find
+	undocumented public functionality.
+
+	* unix/mkLinks: Updated to include the new manpage.
+
+	* doc/UniCharIsAlpha.3: New manpage documenting the Unicode
+	character classification APIs. [Bug 218720]
+
+2001-04-07  Andreas Kupries  <andreas_kupries@users.sourceforge.net>
+
+	* unix/mkLinks: Updated to incorporate the changes below.
+
+	* doc/StringObj.3: Added 'Tcl_AttemptSetObjLength' to the NAME
+	section. [Bug 414435]
+
+	* doc/Alloc.3: Added both 'Tcl_AttemptAlloc' and 'Tcl_AttemptRealloc'
+	to the NAME section. [Bug 414435]
+
+	* doc/Utf.3: Added both 'Tcl_UniCharCaseMatch' and
+	'Tcl_UniCharNcasecmp' to the NAME section. [Bug 414435]
+
+2001-04-06  Don Porter  <dgp@users.sourceforge.net>
+
+	* library/init.tcl:
+	* tests/init.test:  Modified processing of $::errorInfo by [unknown]
+	when the auto-loaded command throws an error to better cover the
+	tracks of auto-loading. [Bug 219280, Patch 403551]
+
+2001-04-06  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* doc/read.n: Added section on "USE WITH SERIAL PORTS" to resolve
+	[Bug 219402]
+
+	* tests/string.test (string-2.30): Test for this case
+	* generic/tclCmdMZ.c (Tcl_StringObjCmd, STR_COMPARE branch): Fixed
+	problem caused by Utf-rep of \x00 being more than Utf-rep of \x01
+	fooling memcmp by forcing everything through Utf-based comparisons.
+	Added optimizations for case where objects have a string/unicode-rep
+	or a bytearray-rep (i.e. where we can perform comparisons on
+	fixed-size units). [Bug 219201]
+	* generic/tclUtf.c (Tcl_UtfNcmp): Corrected seriously erroneous
+	comment.
+
+2001-04-05  Andreas Kupries  <andreas_kupries@users.sourceforge.net>
+
+	* doc/Macintosh.3: Removed duplicates from .SH line. [Bug 413983]
+
+2001-04-05  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* generic/tclCmdMZ.c (Tcl_StringObjCmd): Fixed so will compile
+	with K&R compilers. [Patch 413844, Bug 413847]
+
+2001-04-04  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclMain.c:  Patch from Kevin Kenny to restore support of
+	pre-ANSI compilers. [Bug 413846, Patch 413842]
+
+2001-04-04  Andreas Kupries  <andreas_kupries@users.sourceforge.net>
+
+	* unix/mkLinks: Updated to contain the new manpage.
+
+	* doc/Environment.3: New manpage, describes Tcl_PutEnv. [Bug 219171]
+
+	* doc/Macintosh.3: New manpage describing the macintosh specific parts
+	of the public API. [Bug 219169]
+
+2001-04-04  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* unix/configure:
+	* unix/tcl.m4: extended test of termios vs. termio vs. sgtty to
+	better detect result on Linux and when certain configure
+	redirections are being used. [Patch 402923; Bug 227412, 219194] (max)
+
+2001-04-04  Andreas Kupries  <andreas_kupries@users.sourceforge.net>
+
+	* generic/tclTest.c:
+	* tests/io.tests: TIP #10 followup correcting a problem with the
+	original patch because of the lack of 'testthread id' for a
+	non-threaded compilation.
+
+2001-04-04  Kevin Kenny <kennykb@acm.org>
+
+	* doc/ByteArrObj.3:
+	* doc/DumpActiveMemory.3:
+	* doc/InitStubs.3:
+	* doc/PkgRequire.3:
+	* doc/StringObj.3:
+	* generic/tcl.decls:
+	* generic/tcl.h:
+	* generic/tclBinary.c:
+	* generic/tclCkalloc.c:
+	* generic/tclDecls.h:
+	* generic/tclListObj.c:
+	* generic/tclObj.c:
+	* generic/tclPkg.c:
+	* generic/tclStringObj.c:
+	* generic/tclStubLib.c: (TIP#27) Changed a number of Tcl API's to
+	accept "CONST char*" in place of simple "char*". (kennykb) [Patch
+	404026]
+
+2001-04-04  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* generic/tclListObj.c (Tcl_SetListObj): set objPtr->length = 0 in
+	empty object case to maintain sanctity of Tcl_Obj bytes/length
+	pairing. [Patch 405998] (porter)
+
+2001-04-03  Andreas Kupries  <andreas_kupries@users.sourceforge.net>
+
+	* unix/mkLinks: Added 'Signal.3', 'Tcl_WaitPid'.
+
+	* doc/DetachPids.3: Added description of 'Tcl_WaitPid' [Bug 219173].
+
+	* doc/Signal.3: New man page describing the public API procedures
+	'Tcl_SignalId' and 'Tcl_SignalMsg'. [Bug 219172]
+
+2001-04-02  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* README:
+	* win/README:
+	* win/README.binary: further notes corrections.
+
+	* win/configure:
+	* win/tcl.m4 (SHLIB_LD):  added -incremental:no. [Bug 219381]
+
+2001-04-01  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* README:
+	* mac/README:
+	* win/README:
+	* win/README.binary:
+	* unix/README: updated patchlevel information to 8.4a3 and updated
+	links and notes.
+
+	* generic/tcl.h:
+	* tools/tcl.wse.in:
+	* win/configure.in (VER):
+	* win/configure:
+	* unix/configure:
+	* unix/configure.in (VER):
+	* unix/tcl.spec: updated patchlevel information to 8.4a3
+
+2001-03-30  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* generic/tclCkalloc.c (TclFinalizeMemorySubsystem): set curTagPtr
+	to NULL to allow for reuse.
+	* generic/tclEvent.c (Tcl_Finalize): moved the tsdPtr initialization
+	inside the subsystemsInitialized check to prevent it potentially
+	getting called twice during finalization.
+	[Patch 403532, Bug 219391] (wu)
+
+	* generic/tclThreadTest.c (Tcl_ThreadObjCmd): cast fixes
+	* generic/tclTest.c (TestChannelCmd): added cast to mollify Windows
+	debug build.
+
+	* win/tclWinSock.c (SocketEventProc): Fixed race condition in
+	readability of socket on Windows. [Patch 410674, Bug 219205, 219333]
+
+	* win/tcl.m4: added imm32.lib to LIBS_GUI for Tk IME support.
+
+	* win/Makefile.in (install-libraries): removed extra \s that broke
+	the target.
+	(install-doc): improved install-* targets to use their base build
+	dependency.
+
+2001-03-30  Andreas Kupries  <andreas_kupries@users.sourceforge.net>
+
+	* All of the changes below belong to TIP #10 [Tcl I/O Enhancement:
+	Thread-Aware Channels]. See also [Patch 403358] at SF.
+
+	* generic/tclIO.h (struct ChannelState, line 236f): Extended the
+	structure with a new field of type 'Tcl_ThreadId' to hold the id of
+	the thread currently managing all channels with this state.
+
+	Note: This structure is shared by all channels in a stack of
+	transformations.
+
+	* generic/tclIO.c (Tcl_CreateChannel, lines 1058-1065): Modified to
+	store the Id of the current thread in the 'ChannelState' of the new
+	channel.
+
+	* generic/tclIO.c (Tcl_SpliceChannel, lines 2265-2270): Modified in
+	the same manner as 'Tcl_CreateChannel' as the channel will be managed
+	by the current thread afterward.
+
+	* generic/tclIO.c   (Tcl_GetChannelThread, lines 1478-1503):
+	* generic/tcl.decls (Tcl_GetChannelThread, lines 1504-1506): New API
+	function to retrieve the Id of the managing thread from a channel.
+	Implementation and declaration.
+
+	* generic/tclTest.c (TestChannelCmd, lines 4520-4532): Added
+	subcommand 'mthread' to query a channel about its managing thread.
+
+2001-03-29  Mo DeJong  <mdejong@redhat.com>
+
+	* tests/interp.test: Print out warning when testinterpdelete command
+	is not defined. Add tests that checks to make sure a child interp
+	inherits the parent's cwd.
+
+2001-03-29  Jeff Hobbs  <jeffh@gimlet.activestate.com>
+
+	* doc/tcltest.n: corrected incorrect macro usage.
+
+	* doc/lsort.n: corrected unbalanced nroff macros.
+
+	* unix/tclUnixPipe.c (TclpCreateTempFile): prevent potential race
+	condition and security leak in tmp filename creation.
+	[Patch 402924] (max)
+
+	* unix/configure:
+	* unix/tcl.m4: corrected IRIX-5.x config to not use -n32.
+	[Patch 403626] (english)
+
+	* unix/tclUnixThrd.c (Tcl_ConditionWait): fixed handling of timeout
+	for threads (corrects excessive CPU usage issue for Tk on Unix in
+	threaded Tcl environment). [Bug 411603] (ruppert)
+
+2001-03-29  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* doc/lsort.n: Added some notes that clarify the behaviour of
+	[lsort] as well as a whole bunch of examples.  [Bug 219202]
+
+2001-03-27  Jeff Hobbs  <jeffh@gimlet.activestate.com>
+
+	* doc/Alloc.3: corrected docs to note that Tcl_Attempt* return char
+	*'s, not ints. [Bug 411388]
+
+	* tests/regexp.test (regexp-19.1):
+	* generic/tclCmdMZ.c (Tcl_RegsubObjCmd): fixed handling of nulls in
+	subspec value.
+
+2001-03-26  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclDecls.h (Tcl_InitCustomHashTable):  Correction to patch
+	from 2001-01-18;  tclDecls.h was not generated using 'make genstubs'.
+
+2001-03-26  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* win/tclWinInt.h (tclWinTCharEncoding): Removed as now a static
+	variable in win/tclWin32Dll.c instead.
+
+2001-03-23  Jeff Hobbs  <jeffh@activestate.com>
+
+	* generic/tclVar.c (Tcl_ArrayObjCmd): Corrected retrieval of resultPtr
+	to prevent possible corruption.
+
+	* generic/tclNamesp.c (Tcl_Import): Correctly freed a DString.
+	[Patch 403755] (lavana)
+
+2001-03-15  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* tests/set-old.test (set-old-7.2): Changed error behaviour of
+	[unset] to agree with documentation, so must change test as well.
+
+2001-03-14  Don Porter  <dgp@users.sourceforge.net>
+
+	* library/package.tcl (pkg_mkIndex):  Added patch from Vince Darley to
+	make [pkg_mkIndex -verbose] even more verbose. [Bug 219349, Patch
+	403529]
+
+2001-03-13  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* doc/info.n: Improved documentation for [info hostname]. [Bug 403840]
+
+	* generic/tclVar.c (Tcl_UnsetObjCmd): Made command behave as
+	documented [issue remaining from Bug 405769]
+
+	* generic/tclCmdMZ.c (Tcl_StringObjCmd): A missing {return TCL_OK;}
+	was causing memory corruption. [Bug 408002]
+
+	* generic/tclExecute.c (TclDeleteExecEnv, GrowEvaluationStack,
+	(TclExecuteByteCode): Added some casts to ClientData that are
+	apparently needed on some architectures.
+
+2001-03-12  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* tests/string.test: Fixed some test numberings and added a test.
+	[Patch 403229]
+
+2001-03-06  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* generic/tclVar.c (Tcl_UnsetObjCmd): Rewrote argument parser to avoid
+	a read off the end of the argument array that could occur when
+	executing something like [unset -nocomplain] was executed. Improved
+	the error message given when too few arguments are given (-nocomplain
+	should obviously be *before* --, not after it) and also modified the
+	test suite to take account of that and the documentation to use the
+	same improvement. [Bug 405769]
+
+2001-03-02  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* generic/tclExecute.c (TclExecuteByteCode): Fixed bug that could pass
+	pointers to freed memory to command implementations, which most
+	obviously caused some weird behaviour with [info level], but could
+	have caused problems with user code and command traces too. [Bug
+	404865, Patch 405436]
+
+2001-02-23  msofer  <msofer@users.sourceforge.net>
+
+	* no changes; fixing up the missing comment in the previous one.
+	Sorry.
+
+2001-02-23  msofer  <msofer@ant.utdt>
+
+	* /cvsroot/tcl/tcl/tests/execute.test: added test for evaluation of an
+	expression in a variable; evals once by compiling, second time using
+	the previous compilation
+
+2001-02-18  Kevin B. Kenny  <kennykb@acm.org>
+
+	* doc/clock.n: Updated documentation to reflect the addition of
+	compat/strftime.c, including the correct formatting of ISO-8601:1988
+	fiscal week number (%V).
+
+2001-02-15  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* generic/tclCmdMZ.c (Tcl_SplitObjCmd): Improved efficiency of
+	splitting strings into individual characters by adding hash so that
+	only one Tcl_Obj per character is created. Improves performance of
+	splitting of short strings and makes a huge difference to splitting of
+	long strings, such as is done in the mime package in tcllib. [Bug
+	131523]
+
+2001-01-31  Don Porter  <dgp@users.sourceforge.net>
+
+	* win/makefile.vc (install-libraries):  Corrected misdirected install
+	directory for the msgcat 1.2 package.
+
+2001-01-30  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclIO.c (CopyData): Moved code that updates the count of how
+	many bytes are left to copy. Corrects bug that when writing occurs in
+	the background, the copy loop could be escaped without updating the
+	count, causing CopyData() to try to copy more bytes than the toRead
+	value originally passed to TclCopyChannel(), leading to hangs and
+	misreporting of number of bytes copied. [Bug 118203, Patch 103432]
+
+2001-01-18  Andreas Kupries  <a.kupries@westend.com>
+
+	Everything below belongs together, it fixes [Bug 123153]
+
+	* generic/tcl.h (line 342): A bit more explanation about the default
+	value for TCL_PRESERVE_BINARY_COMPATABILITY.
+
+	* generic/tcl.h (line 1208): Define the macro 'Tcl_InitHashTable' only
+	when TCL_PRESERVE_BINARY_COMPATIBILITY is not set as it kills binary
+	compatibility to 8.3 and earlier versions. This is the main part of
+	the patch/change.
+
+	* generic/tcl.decls (line 1469):
+	* generic/tclHash.c (Tcl_InitHashTable):
+	* generic/tclHash.c (Tcl_InitHashTableEx):
+	* generic/tclObj.c (Tcl_InitObjHashTable): Changed
+	'Tcl_InitHashTableEx' to 'Tcl_InitCustomHashTable'. This change is
+	more of an estethical nature, replacing the ubiquitous 'Ex' suffix
+	with a more meaningful name. The introduced binary incompatibility is
+	deemed acceptable as it is between alpha versions.  Updated callers.
+
+	* doc/Hash.3:
+	* unix/mkLinks: Changed 'Tcl_InitHashTableEx' to
+	'Tcl_InitCustomHashTable'.
+
+2001-01-10  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* tests/winPipe.test (winpipe-1.20):
+	* tests/winDde.test (createChildProcess):
+	* tests/pkgMkIndex.test (pkgtest::createIndex): Removed assumption
+	that paths contain no spaces which causes problems with both [eval]
+	and [open |...] due to the well-known differences between lists and
+	strings. Fixes [Bug 119406]
+
+2001-01-04  Don Porter  <dgp@users.sourceforge.net>
+
+	* tests/unixInit.test:
+	* unix/tclUnixInit.c (TclpInitLibraryPath):
+	* win/tclWinInit.c (TclpInitLibraryPath):  Several entries in the
+	library path ($tcl_libPath) are determined relative to the absolute
+	path of the executable. When the executable is installed in or near
+	the root directory of the file system, relative pathnames were being
+	incorrectly generated, and in the worst case, memory access violations
+	were crashing the program. [Bug 119416, Patch 102972]
+
+	******************************************************************
+	*** CHANGELOG ENTRIES FOR 2000 IN "ChangeLog.2000"             ***
+	*** CHANGELOG ENTRIES FOR 1999 AND EARLIER IN "ChangeLog.1999" ***
+	******************************************************************
diff --git a/ChangeLog.2002 b/ChangeLog.2002
new file mode 100644
index 0000000..30b8b17
--- /dev/null
+++ b/ChangeLog.2002
@@ -0,0 +1,4741 @@
+2002-12-18  David Gravereaux  <davygrvy@pobox.com>
+
+	* win/makefile.vc: some uses of xcopy swapped to the @$(CPY) macro.
+	Reported by Joe Mistachkin <joe@mistachkin.com>.
+
+2002-12-17  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* generic/tclNotify.c (TclFinalizeNotifier, Tcl_SetServiceMode):
+	(Tcl_ThreadAlert): Check that the stub functions are non-NULL before
+	calling them. They could be set to NULL by Tcl_SetNotifier.
+
+2002-12-16  David Gravereaux  <davygrvy@pobox.com>
+
+	* generic/tclPipe.c (TclCleanupChildren):
+	* tests/winPipe.test:
+	* win/tclWinPipe.c (Tcl_WaitPid):
+	* win/tclWinTest.c:  Gave Tcl_WaitPid the ability to return a Win32
+	exception code translated into a posix style SIG*. This allows [close]
+	to report "CHILDKILLED" without the meaning getting lost in a
+	truncated exit code. In TclCleanupChildren(), TclpGetPid() had to get
+	moved to before Tcl_WaitPid() as the the handle is removed from the
+	list taking away the ability to get the process id after the wait is
+	done. This shouldn't effect the unix implimentaion unless waitpid is
+	called with a pid of zero, meaning "any". I don't think it is..
+
+2002-12-13  Don Porter  <dgp@users.sourceforge.net>
+
+	* unix/configure.in:	Updated configure of CVS snapshots to reflect
+	* win/configure.in:	the 8.4.1.1 patchlevel.
+
+	* unix/configure:	autoconf
+	* win/configure		autoconf
+
+2002-12-11  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclProc.c (ProcessProcResultCode): Fix failure to propagate
+	negative return codes up the call stack. [Bug 647307]
+	* tests/proc.test (proc-6.1): Test for Bug 647307
+
+	* generic/tclParseExpr.c (TclParseInteger):  Return 1 for the string
+	"0x" (recognize leading "0" as an integer). [Bug 648441]
+	* tests/parseExpr.test (parseExpr-19.1): Test for Bug 648441.
+
+2002-12-09  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* win/tclWinThrd.c (TclpMasterUnlock):
+	* generic/tclThread.c (TclFinalizeThreadData): TclpMasterUnlock must
+	exist and be called unconditional of TCL_THREADS. [Bug 651139]
+
+2002-12-08  David Gravereaux  <davygrvy@pobox.com>
+
+	* win/tclWinSock.c (SocketThreadExitHandler, InitSockets):  Check
+	that the tsdPtr is valid before dereferencing as we call it from the
+	exit handler, too [Bug 650353]. Another WSAStartup() loaded version
+	comparison byte swap issue fixed. Although 0x0101 byte swapped is
+	still 0x0101, properly claiming which is major/minor is more correct.
+
+2002-12-06  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* generic/tclStubInit.c: regen
+	* generic/tclIntPlatDecls.h: regen
+	* generic/tclInt.decls: added TclWinResetInterface
+
+	* win/tclWin32Dll.c (TclWinResetInterfaces):
+	* win/tclWinInit.c (TclpSetInitialEncodings, WinEncodingsCleanup):
+	add exit handler that resets the encoding information to a state where
+	we can reuse Tcl. Following these changes, it is possible to reuse Tcl
+	(following Tcl_FindExecutable or Tcl_CreateInterp) following a
+	Tcl_Finalize.
+
+	* generic/tclIOUtil.c (TclFinalizeFilesystem): reset statics to their
+	original values on finalize to allow reuse of the library.
+
+2002-12-04  David Gravereaux  <davygrvy@pobox.com>
+
+	* win/tclWinPipe.c: reverted back to -r1.27 due to numerous test
+	failures that need to be resolved first. The idea was good, but the
+	details aren't.
+
+2002-12-04  David Gravereaux  <davygrvy@pobox.com>
+
+	* win/tclWinPipe.c (Tcl_WaitPid):  When a process exits with an
+	exception, pass this notice on to the caller with a SIG* code rather
+	than truncating the exit code and missing the meaning. This allows
+	TclCleanupChildren() to report "CHILDKILLED".
+
+	This has a different behavior than unix in that closing the read pipe
+	to a process sends the SIGPIPE signal which is returned as a SIGPIPE
+	exit status. On windows, we send the process a CTRL_BREAK_EVENT and
+	get back a CONTROL_C_EXIT which is documented to mean a SIGINT which
+	seems wrong as a system, but is the correct exit status.
+
+2002-12-04  Vince Darley  <vincentdarley@users.sourceforge.net>
+
+	* generic/tclIOUtil.c: fix to redirected 'load' in virtual filesystem
+	for some Unix systems.
+
+	* generic/tclEvent.c: the filesystem must be cleaned up before the
+	encoding subsystem because it needs access to encodings. Fixes crash
+	on exit observed in embedded applications.
+
+	* generic/tclTestObj.c: patch omitted from previous change of
+	2002-11-13
+
+2002-12-03  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* generic/tclStubLib.c (Tcl_InitStubs): prevent the cached check of
+	tclStubsPtr to allow for repeated load/unload of the Tcl dll by
+	hosting apps. [Bug 615304]
+
+2002-12-03  David Gravereaux  <davygrvy@pobox.com>
+
+	* win/tclAppInit.c (sigHandler): Protect from trying to close a NULL
+	handle.
+
+	* win/tclWinPipe.c (PipeClose2Proc, TclpCreateProcess): Send a real
+	Win32 signal (CTRL_C_EVENT) when the read channel is brought down to
+	alert the child to close on its side. Start the process with
+	CREATE_NEW_PROCESS_GROUP to allow the ability to send these signals.
+	The following test case now brings down the child without the use of
+	an external [kill] command.
+
+	% set p [open "|[info name]" w+]
+	file8d5380
+	% pid $p
+	2876
+	% close $p     <- now doesn't block in Tcl_WaitPid()
+	%
+
+	* win/tclWinPipe.c (PipeClose2Proc): Changed CTRL_C_EVENT to
+	CTRL_BREAK_EVENT as it can't be ignored by the child and proved to
+	work on [open "|netstat 1" w+] where CTRL_C_EVENT didn't.
+
+2002-11-27  David Gravereaux  <davygrvy@pobox.com>
+
+	* win/tclWinPort.h: Don't turn off winsock prototypes!  TclX didn't
+	like it. Even though the core doesn't use the prototypes, do offer
+	them.
+
+	* win/tclWinSock.c: Removed shutdown() from the function table as it
+	wasn't referenced anywhere and cleaned-up some casting that that
+	wasn't needed.
+
+	* win/tclWinSock.c: WSAStartup() loaded version comparison error which
+	resulted in 2.0 looking less than 1.1.
+
+	* win/tclWinChan.c (Tcl_MakeFileChannel): return of DuplicateHandle()
+	incorrectly used. [Bug 618852]
+
+2002-11-26  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* generic/tclEncoding.c (TclFinalizeEncodingSubsystem): properly
+	cleanup all encodings by using Tcl_FirstHashEntry in the while loop.
+
+	* unix/Makefile.in (valgrind): add simple valgrind target
+
+	* tests/exec.test: unset path var to allow singleproc testing
+
+	* generic/tclInterp.c (AliasCreate): preserve/release interps to
+	prevent possible FMR error in bad alias cases.
+
+2002-11-26  David Gravereaux  <davygrvy@pobox.com>
+
+	* win/tclWinPort.h:
+	* win/tclWinSock.c:  This patch does two things:
+
+	1) Cleans-up the winsock typedefs by using the typedefs provided by
+	winsock2.h. This has no effect on how winsock is initialized; just
+	makes the source code easier to read. [Patch 561305 561301]
+
+	2) Revamps how the socket message handler thread is brought up and
+	down to allow for cleaner exits without the use of TerminateThread().
+	TerminateThread is evil. No attempt has been made to resolve [Bug
+	593810] which may need a new channel driver version for adding a
+	registering function within the transfered thread to init the handler
+	thread. IOW, initialization of the TSD structure is getting bypassed
+	through the thread extension's [thread::transfer] command.
+
+2002-11-26  David Gravereaux  <davygrvy@pobox.com>
+
+	* win/tclWinConsole.c:
+	* win/tclWinPipe.c:
+	* win/tclWinSerial.c:
+	* win/tclWinSock.c:
+	* win/tclWinThrd.c:
+	* win/tclWinTime.c:  General cleanup of all worker threads used by the
+	channel drivers. Eliminates the normal case where the worker thread is
+	terminated ('cept the winsock one). Instead, use kernel events to
+	signal a clean exit. Only when the worker thread is blocked on an I/O
+	call is the thread terminated. Essentially, this makes all other
+	channel worker threads behave like the PipeReaderThread() function for
+	it's cleaner exit behavior. This appears to fix [Bug 597924] but needs
+	3rd party confirmation to close the issue.
+
+2002-11-26  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* win/README: Update msys build env URL. This release #4 build both
+	tcl and tk without problems.
+
+2002-11-22  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* library/init.tcl:         code cleanup to reduce use of
+	* library/opt/optparse.tcl: string compare
+
+	* tests/interp.test: interp-14.4
+	* generic/tclInterp.c (TclPreventAliasLoop): prevent seg fault when
+	creating an alias command over the interp name. [Bug 641195]
+
+2002-11-18  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* generic/tclUtil.c (SetEndOffsetFromAny): handle integer offset
+	after the "end-" prefix.
+
+	* generic/get.test:
+	* generic/string.test:
+	* generic/tclObj.c (SetIntFromAny, SetWideIntFromAny):
+	* generic/tclGet.c (TclGetLong, Tcl_GetInt): simplify sign handling
+	before calling strtoul(l). [Bug 634856]
+
+2002-11-18  David Gravereaux  <davygrvy@pobox.com>
+
+	* win/tclWinThrd.c (Tcl_CreateThread/TclpThreadExit): Fixed improper
+	compiler macros that missed the VC++ compiler. This resulted in VC++
+	builds using CreateThread()/ExitThread() in place of the proper
+	_beginthreadex()/_endthreadex(). This was a large error and am
+	surprised I missed seeing it earlier.
+
+2002-11-13  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* generic/regexpComp.test: added tests 22.*
+	* generic/tclCompCmds.c (TclCompileRegexpCmd): add left and right
+	anchoring (^ and $) recognition and check starting or ending .* to
+	extend the number of REs that can be compiled to string match or
+	string equal.
+
+2002-11-13  Vince Darley  <vincentdarley@users.sourceforge.net>
+
+	* generic/tclCmdMZ.c:
+	* tests/trace.test: applied patch from Hemang Levana to fix [Bug
+	615043] in execution traces with 'return -code error'.
+
+	* generic/tclTestObj.c:
+	* tests/stringObj.test: added 'knownBug' test for [Bug 635200]
+	* generic/tclStringObj.c: corrected typos in comments
+
+	* generic/tclFileName.c:
+	* tests/fileName.test: applied patch for bug reported against tclvfs
+	concerning handling of Windows serial ports like 'com1', 'lpt3' by the
+	virtual filesystem code.
+
+	* doc/RegExp.3: clarification of the 'extendMatch' return values.
+
+2002-11-11  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* generic/tclUtil.c (Tcl_Backslash): use TclUtfToUniChar.
+	(Tcl_StringCaseMatch): use TclUtfToUniChar and add further
+	optimizations for the one-byte/char case.
+
+	* generic/tclUtf.c: make use of TclUtfToUniChar macro throughout the
+	functions, and add extra optimization to Tcl_NumUtfChars for
+	one-byte/char case.
+
+	* generic/tclVar.c (DisposeTraceResult, CallVarTraces): add proper
+	static declarations.
+
+	* generic/tclStringObj.c (Tcl_GetCharLength): optimize for the ascii
+	char case.
+	(Tcl_GetUniChar): remove unnecessary use of Tcl_UtfToUniChar.
+	(FillUnicodeRep): Use TclUtfToUniChar.
+
+	* generic/tclHash.c (HashStringKey): move string++ lower to save an
+	instruction.
+
+	* generic/tclExecute.c (TclExecuteByteCode): improve INST_STR_CMP to
+	use memcmp in the one-byte/char case, also use direct index for
+	INST_STR_INDEX in that case.
+
+	* generic/tclEncoding.c (UtfToUtfProc, UtfToUnicodeProc):
+	(TableFromUtfProc, EscapeFromUtfProc): Use TclUtfToUniChar.
+	(UnicodeToUtfProc, TableToUtfProc): add 1-byte char optimizations for
+	Tcl_UniCharToUtf call. These improve encoded channel conversion speeds
+	by up to 20%.
+
+	* tests/split.test: added 1-char string split tests
+	* generic/tclCmdMZ.c (Tcl_SplitObjCmd): Use TclUtfToUniChar. Also
+	added a special case for single-ascii-char splits.
+	(Tcl_StringObjCmd): Use TclUtfToUniChar. For STR_RANGE, support
+	getting ranges of ByteArrays (reverts change from 2000-05-26).
+	(TraceExecutionProc) add proper static declaration.
+
+	* generic/tclInt.h: add macro version of Tcl_UtfToUniChar
+	(TclUtfToUniChar) that does the one-byte utf-char check without
+	calling Tcl_UtfToUniChar, for use by the core. This brings notable
+	speedups for primarily ascii string handling.
+
+	* generic/tcl.h (TCL_PATCH_LEVEL): bump to 8.4.1.1 for patchlevel
+	only. This interim number will only be reflected by [info patchlevel].
+
+2002-11-11  Kevin Kenny  <kennykb@acm.org>
+
+	* doc/Tcl.n: Corrected indentation of the new language. Oops.
+
+2002-11-10  Kevin Kenny <kennykb@acm.org>
+
+	* doc/Tcl.n: Added language to the Endekalogue to make it clear that
+	substitutions always take place from left to right. [Bug 635644]
+
+2002-11-06  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* changes: Note TclInExit TclInThreadExit changes.
+	* generic/tclEvent.c (TclInExit, TclInThreadExit): Split out
+	functionality of TclInExit to make it clear which one should be called
+	in each situation.
+	* generic/tclInt.decls: Declare TclInThreadExit.
+	* generic/tclIntDecls.h: Regen.
+	* generic/tclStubInit.c: Regen.
+	* mac/tclMacChan.c (StdIOClose):
+	* unix/tclUnixChan.c (FileCloseProc):
+	* win/tclWinChan.c (FileCloseProc):
+	* win/tclWinConsole.c (ConsoleCloseProc):
+	* win/tclWinPipe.c (TclpCloseFile):
+	* win/tclWinSerial.c (SerialCloseProc): Invoke the new TclInThreadExit
+	method instead of TclInExit.
+
+2002-11-06  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* unix/configure: Regen.
+	* unix/tcl.m4 (SC_CONFIG_CFLAGS): Generate a fatal configure error if
+	no ar program can be found on the path. [Bug 582039]
+	* win/configure: Regen.
+	* win/configure.in: Check that AR, RANLIB, and RC are found on the
+	path when building with gcc.
+
+2002-11-03  David Gravereaux <davygrvy@pobox.com>
+
+	* win/tclAppInit.c:  Calls Registry_Init() and Dde_Init() when
+	STATIC_BUILD and TCL_USE_STATIC_PACKAGES macros are set.
+
+	* win/makefile.vc:
+	* win/rules.vc:  linkexten option now sets the TCL_USE_STATIC_PACKAGES
+	macro which also adds the registry and dde object files to the link
+	of the shell. [Patch 479697] Also factored some additional macros that
+	will be helpful for extension authors. Version grepping of tcl.h will
+	need to be added to complete this.
+
+	* win/buildall.vc.bat: Added more descriptive commentary.
+
+2002-11-01  David Gravereaux <davygrvy@pobox.com>
+
+	* win/tclWinReg.c:  Changed the Tcl_PkgProvide() line to declare the
+	registry extension at version 1.1 from 1.0.
+
+2002-10-31  Andreas Kupries  <andreask@activestate.com>
+
+	* library/word.tcl: Changed $tcl_platform to $::tcl_platform to avoid
+	possible scope trouble.
+
+2002-10-29  Vince Darley  <vincentdarley@users.sourceforge.net>
+
+	* win/tclWinInt.h:
+	* win/tclWin32Dll.c: added comments about certain NULL function
+	pointers which will be filled in when Tcl_FindExecutable is called, so
+	that users don't report invalid bugs on this topic. (No code changes
+	at all).
+
+2002-10-29  Daniel Steffen  <das@users.sourceforge.net>
+
+	* unix/tclLoadDyld.c (TclpFindSymbol): pass all dyld error messages
+	upstream [Bug 627546].
+
+2002-10-28  Andreas Kupries  <andreask@activestate.com>
+
+	* library/dde/pkgIndex.tcl:
+	* library/reg/pkgIndex.tcl: Changed the hardwired debug suffix (d) to
+	the correct suffix (g).
+
+2002-10-28  Don Porter  <dgp@users.sourceforge.net>
+
+	* library/auto.tcl:	Converted the Mac-specific [package unknown]
+	* library/init.tcl:	behavior to use a chaining mechanism to extend
+	* library/package.tcl:	the default [tclPkgUnknown]. [Bug 627660]
+	* library/tclIndex:	[Patch 624509] (steffen)
+
+2002-10-26  David Gravereaux <davygrvy@pobox.com>
+
+	* win/makefile.vc: xcopy on NT 4.0 doesn't support the /Y switch
+	(overwrite). Added logic to handle this. [Bug 618019]
+
+2002-10-23  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* generic/tclInt.h: Removed definitions of obsolete HistoryEvent and
+	HistoryRev structures (the history mechanism has been written in Tcl
+	for some time now.)
+
+2002-10-22  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	*** 8.4.1 TAGGED FOR RELEASE ***
+
+	* changes: updated for 8.4.1 release
+
+	* win/Makefile.in: removed @MEM_DEBUG_FLAGS@ subst.
+	* win/configure: regen
+	* win/configure.in: removed SC_ENABLE_MEMDEBUG call
+	* win/tcl.m4: replaced SC_ENABLE_MEMDEBUG with a more intelligent
+	SC_ENABLE_SYMBOLS that takes yes|no|mem|compile|all as options now.
+
+2002-10-22  Daniel Steffen  <das@users.sourceforge.net>
+
+	* library/auto.tcl (tcl_findLibrary):
+	* library/package.tcl (tclPkgUnknown): on macosx, search inside the
+	Resources/Scripts subdirectory of any potential package directory.
+	* macosx/Tcl.pbproj/project.pbxproj: add standard Frameworks dirs to
+	TCL_PACKAGE_PATH make argument.
+	* unix/tclUnixInit.c (TclpSetVariables): on macosx, add embedded
+	framework dirs to tcl_pkgPath: @executable_path/../Frameworks and
+	@executable_path/../PrivateFrameworks (if they exist), as well as the
+	dirs in DYLD_FRAMEWORK_PATH (if set). [Patch 624509]
+	use standard MAXPATHLEN instead of literal 1024
+
+2002-10-22  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* doc/StringObj.3, doc/Object.3: Documented that Tcl_Obj's standard
+	string form is a modified UTF-8; apparently, this was not mentioned
+	anywhere in the main docs, and lead to [Bug 624919].
+
+2002-10-21  Daniel Steffen  <das@users.sourceforge.net>
+
+	* macosx/Tcl.pbproj/project.pbxproj: bumped version to 8.4.1
+	* generic/tcl.h: Added reminder comment to edit
+	macosx/Tcl.pbproj/project.pbxproj when version number changes.
+
+2002-10-18  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* library/reg/pkgIndex.tcl:
+	* win/configure:
+	* win/configure.in:
+	* win/Makefile.in:
+	* win/makefile.vc:
+	* win/makefile.bc:    Updated to reg1.1
+
+	* doc/registry.n:      Added support for broadcasting changes to the
+	* tests/registry.test: registry Environment. Noted proper code in the
+	* win/tclWinReg.c:     docs. [Patch 625453]
+
+	* unix/Makefile.in (dist): add any mac/tcl*.sea.hqx files
+
+2002-10-17  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclVar.c:	Fixed code that check for proper # of args to
+	* tests/var.test:	[array names]. Added test. [Bug 624755]
+
+2002-10-16  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* win/configure:                 add workaround for cygwin windres
+	* win/tcl.m4 (SC_CONFIG_CFLAGS): problem. [Patch 624010] (howell)
+
+2002-10-15  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* README: added archives.tcl.tk note
+
+	* unix/configure:
+	* unix/tcl.m4: Correct AIX-5 ppc build flags. Correct HP 11 64-bit gcc
+	building. [Patch 601051] (martin)
+
+2002-10-15  Vince Darley  <vincentdarley@users.sourceforge.net>
+
+	* generic/tclCmdMZ.c:
+	* tests/trace.test: applied patch from Hemang Levana to fix [Bug
+	615043] in execution traces with idle tasks firing.
+
+2002-10-14  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* generic/tclEnv.c (Tcl_PutEnv): correct possible mem leak. [Patch
+	623269] (brouwers)
+
+2002-10-11  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* generic/tcl.h: Need a different strategy through the maze of
+	#defines to let people building with Cygwin build correctly. Also made
+	some comments less misleading...
+
+2002-10-10  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* README: fixed minor nits [Bug 607776] (virden)
+
+	* win/configure:
+	* win/tcl.m4: enable USE_THREAD_ALLOC (new threaded allocator) by
+	default in cygwin configure on Windows.
+
+2002-10-10  Don Porter  <dgp@users.sourceforge.net>
+
+	* doc/Tcl.n:	Clarified that namespace separators are legal in the
+			variable names during $-subtitution. [Bug 615139]
+
+	* doc/regexp.n:	Typo correction. Thanks Ronnie Brunner. [Bug 606826]
+
+2002-10-10  Vince Darley  <vincentdarley@users.sourceforge.net>
+
+	* unix/tclLoadAout.c
+	* unix/tclLoadDl.c
+	* unix/tclLoadDld.c
+	* unix/tclLoadDyld.c
+	* unix/tclLoadNext.c
+	* unix/tclLoadOSF.c
+	* unix/tclLoadShl.c
+	* win/tclWinLoad.c: allow either full paths or simply dll names to be
+	specified when loading files (the latter will be looked up by the OS
+	on your PATH/LD_LIBRARY_PATH as appropriate). Fixes [Bug 611108]
+
+2002-10-09  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* unix/README: doc'ed --enable-symbols options.
+	* unix/Makefile.in: removed @MEM_DEBUG_FLAGS@ subst.
+	* unix/configure: regen
+	* unix/configure.in: removed SC_ENABLE_MEMDEBUG call
+	* unix/tcl.m4: replaced SC_ENABLE_MEMDEBUG with a more intelligent
+	SC_ENABLE_SYMBOLS that takes yes|no|mem|compile|all as options now.
+
+2002-10-09  Kevin B. Kenny  <kennykb@acm.org>
+
+	* win/tclWinTime.c: Added code to set an exit handler that terminates
+	the thread that calibrates the performance counter, so that the thread
+	won't outlive unloading the Tcl DLL. [Bug 620735]
+
+2002-10-09  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* doc/binary.n: More clarification of [binary scan]'s behaviour.
+
+2002-10-09  Daniel Steffen  <das@users.sourceforge.net>
+
+	* generic/tclIntDecls.h: fixed botched regen.
+
+2002-10-09  Daniel Steffen  <das@users.sourceforge.net>
+
+	* generic/tclInt.decls: made TclSetPreInitScript() declaration
+	generic as it is used on mac & aqua as well.
+	* generic/tclIntDecls.h:
+	* generic/tclStubInit.c: regen.
+	* generic/tclCompile.h: added prototype for TclCompileVariableCmd.
+
+	* mac/tclMacPort.h: removed incorrect <fcntl.h> definitions and
+	obsolete <stat.h> definitions.
+	* mac/tclMacChan.c: removed obsolete GetOpenMode() and replaced
+	associated constants with the <fcntl.h> analogues (they existing defs
+	were inconsistent with <fcntl.h> which was causing havoc when
+	Tcl_GetOpenMode was used instead of private GetOpenMode).
+
+	* mac/tclMacFCmd.c: removed GenerateUniqueName(), use equivalent (and
+	identically named) routine from MoreFiles instead.
+
+	* mac/tclMacLoad.c: CONSTification, fixes to Vince's last changes.
+
+	* mac/tclMacFile.c:
+	* mac/tclMacTest.c:
+	* mac/tclMacUnix.c: CONSTification.
+
+	* mac/tclMacOSA.c: CONSTification, sprintf fixes, UH 3.4.x changes;
+	fix for missing autoname token from TclOSACompileCmd. (bdesgraupes)
+	* mac/AppleScript.html(AppleScript delete): doc fix. (bdesgraupes)
+
+	* mac/tcltkMacBuildSupport.sea.hqx: updated MoreFiles to 1.5.3,
+	updated build instructions for 8.4.
+	* mac/tclMacProjects.sea.hqx: rebuilt archive.
+
+2002-10-09  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* doc/Alloc.3: Added a note to mention that attempting to allocate a
+	zero-length block can return NULL. [Tk Bug 619544]
+
+2002-10-04  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* doc/binary.n: Doc improvements [Patch 616480]
+
+	* tests/fCmd.test, tests/winFCmd.test:
+	* tools/eolFix.tcl, tools/genStubs.tcl: [file exist] -> [file exists]
+	Thanks to David Welton.
+
+2002-10-03  Don Porter  <dgp@users.sourceforge.net>
+
+	* doc/tcltest.n: fixed typo [Bug 618018]. Thanks to "JJM".
+
+2002-10-03  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* tools/man2help2.tcl:
+	* tests/http.test, tests/httpd, tests/httpold.test:
+	* tests/env.test, tests/binary.test, tests/autoMkindex.test:
+	* library/init.tcl, library/http/http.tcl: [info exist] should really
+	be [info exists]. [Bug 602566]
+
+	* doc/lsearch.n: Better specification of what happens when -sorted is
+	mixed with other options. [Bug 617816]
+
+2002-10-01  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* generic/tclProc.c (TclCreateProc): mask out VAR_UNDEFINED for
+	precompiled locals to support 8.3 precompiled code.
+	(Tcl_ProcObjCmd): correct 2002-09-26 fix to look for tclProcBodyType.
+
+2002-10-01  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* doc/socket.n: Mentioned that ports may be specified as serivce names
+	as well as integers. [Bug 616843]
+
+2002-09-30  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* generic/tclCompCmds.c (TclCompileRegexpCmd): correct the checking
+	for bad re's that didn't terminate the re string. Resultant compiles
+	were correct, but much slower than necessary.
+
+2002-09-29  David Gravereaux <davygrvy@pobox.com>
+
+	* win/tclAppInit.c: Added proper exiting conditions using Win32
+	console signals. This handles the existing lack of a Ctrl+C exit to
+	call exit handlers when built for thread support. Also, properly
+	handles exits from other conditions such as CTRL_CLOSE_EVENT,
+	CTRL_LOGOFF_EVENT, and CTRL_SHUTDOWN_EVENT signals. In all cases,
+	exit handlers will be called. [Bug 219355]
+
+	* win/makefile.vc: Added missing tclThreadAlloc.c to the build rules
+	and defines USE_THREAD_ALLOC when TCL_THREADS is defined to get the
+	new behavior by default.
+
+2002-09-27  Don Porter  <dgp@users.sourceforge.net>
+
+	* README:		Bumped to version 8.4.1 to avoid confusion of
+	* generic/tcl.h:	CVS snapshots with the actual 8.4.0 release.
+	* tools/tcl.wse.in:
+	* unix/configure.in:
+	* unix/tcl.spec:
+	* win/configure.in:
+
+	* unix/configure:	autoconf
+	* win/configure:
+
+2002-09-26  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* unix/configure: regen.
+	* unix/tcl.m4: improve AIX-4/5 64bit compilation support.
+
+	* generic/tclProc.c (Tcl_ProcObjCmd): correct overeager optimization
+	of noop proc to handle the precompiled case. (sofer)
+
+	* unix/ldAix (nmopts): add -X32_64 to make it work for 32 or 64bit
+	mode compilation.
+
+	* library/encoding/koi8-u.enc: removed extraneous spaces that confused
+	encoding reader. [Bug 615115]
+
+	* unix/Makefile.in: generate source dists with -src designator and do
+	not generate .Z anymore (just .gz and .zip).
+
+2002-09-18  Mumit Khan <khan@nanotech.wisc.edu>
+
+	Added basic Cygwin support.
+
+	* win/tcl.m4 (SC_PATH_TCLCONFIG): Support one-tree build.
+	(SC_PATH_TKCONFIG): Likewise.
+	(SC_PROG_TCLSH): Likewise.
+	(SC_CONFIG_CFLAGS): Assume real Cygwin port and remove -mno-cygwin
+	flags. Add -mwin32 to extra_cflags and extra_ldflags. Remove ``-e
+	_WinMain@16'' from LDFLAGS_WINDOW.
+	* win/configure.in: Allow Cygwin build.
+	(SEH test): Define to be 1 instead of empty value.
+	(EXCEPTION_DISPOSITION): Add test.
+	* win/configure: Regenerate.
+
+	* generic/tcl.h: Don't explicitly define __WIN32__ for Cygwin, let the
+	user decide whether to use Windows or POSIX personality.
+	(TCL_WIDE_INT_TYPE, TCL_LL_MODIFIER, struct Tcl_StatBuf): Define for
+	Cygwin.
+	* generic/tclEnv.c (Tcl_CygwinPutenv): putenv replacement for Cygwin.
+	* generic/tclFileName.c (Tcl_TranslateFileName): Convert POSIX to
+	native format.
+	(TclDoGlob): Likewise.
+	* generic/tclPlatDecls.h (TCHAR): Define for Cygwin.
+	* win/tclWinPort.h (putenv, TclpSysAlloc, TclpSysFree,
+	(TclpSysRealloc): Define for Cygwin.
+
+2002-09-26  Daniel Steffen  <das@users.sourceforge.net>
+
+	* macosx/Makefile: preserve environment value of INSTALL_ROOT. When
+	embedding only use deployment build. Force relink before embedded
+	build to ensure new linker flags are picked up.
+
+	* macosx/Tcl.pbproj/project.pbxproj: add symbolic links to debug lib,
+	stub libs and tclConfig.sh in framework toplevel. Configure target
+	dependency fix. Fix to 'clean' action. Added private tcl headers to
+	framework. Install tclsh symbolic link. Html doc build works when no
+	installed tclsh available. Made html doc structure in framework more
+	like in Apple frameworks.
+
+2002-09-24  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* unix/tcl.m4 (SC_TCL_64BIT_FLAGS): Yet more robust 64-bit value
+	detection to close [Bug 613117] on more systems.
+
+	* generic/tclCompile.c (TclPrintSource): More CONSTifying.
+	* generic/tclExecute.c (EvalStatsCmd): Object-ify to reduce warnings.
+	Thanks to 'CoderX2' on the chat for bringing this to my attention...
+
+	* unix/tcl.m4: Forgot to define TCL_WIDE_INT_IS_LONG at the
+	appropriate moment. I believe this is the cause of [Bug 613117]
+
+	* doc/lset.n: Changed 'list' to 'varName' for consistency with lappend
+	documentation. Thanks to Glenn Jackman [Bug 611719]
+
+2002-09-22  Don Porter  <dgp@users.sourceforge.net>
+
+	* library/tcltest/tcltest.tcl:  Corrected [puts -nonewline] within
+	test bodies. Thanks to Harald Kirsch. [Bug 612786, Patch 612788] Also
+	corrected reporting of body return code. Thanks to David Taback [Bug
+	611922]
+	* library/tcltest/pkgIndex.tcl: Bump to version 2.2.1.
+	* tests/tcltest.test: added tests for these bugs.
+
+2002-09-15  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* unix/configure: Regen.
+	* unix/tcl.m4 (SC_CONFIG_CFLAGS): Add PEEK_XCLOSEIM define under
+	Linux. This is used by Tk to double check that an X input context is
+	cleaned up before it is closed.
+
+2002-09-12  David Gravereaux <davygrvy@pobox.com>
+
+	* win/coffbase.txt: Added BLT to the virtual base address listings
+	table should BLT's build tools decide to use it.
+
+2002-09-12  Daniel Steffen  <das@users.sourceforge.net>
+
+	* generic/tcl.h:
+	* mac/tclMacApplication.r:
+	* mac/tclMacLibrary.r:
+	* mac/tclMacResource.r: unified use of the two equivalent resource
+	compiler header inclusion defines RC_INVOKED and RESOURCE_INCLUDED,
+	now use RC_INVOKED throughout.
+
+2002-09-10  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* unix/README: Add note about building extensions with the same
+	compiler Tcl was built with. [Tk Bug 592096]
+
+2002-09-10  Daniel Steffen  <das@users.sourceforge.net>
+
+	* macosx/Tcl.pbproj/project.pbxproj: disabled building html
+	documentation during embedded build.
+
+2002-09-10  Daniel Steffen  <das@users.sourceforge.net>
+
+	* unix/Makefile.in: added DYLIB_INSTALL_DIR variable for macosx and
+	set it to default value ${LIB_RUNTIME_DIR}
+	* unix/tcl.m4 (Darwin): use DYLIB_INSTALL_DIR instead of
+	LIB_RUNTIME_DIR in the -install_name argument to ld.
+	* unix/configure: regen.
+
+	* macosx/Tcl.pbproj/project.pbxproj:
+	* macosx/Makefile: added support for building Tcl as an embedded
+	framework, i.e. using an dyld install_name containing
+	@executable_path/../Frameworks via the new DYLIB_INSTALL_DIR
+	unix/Makefile variable.
+
+2002-09-10  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	*** 8.4.0 TAGGED FOR RELEASE ***
+
+2002-09-06  Don Porter  <dgp@users.sourceforge.net>
+
+	* doc/file.n:  Format correction, and clarified [file normalize]
+	returns an absolute path.
+
+	* doc/tcltest.n:  Added examples section, as long promised.
+
+2002-09-06  Reinhard Max  <max@suse.de>
+
+	* tests/tcltest.test: Added nonRoot flag to tests 8.3, 8.4, and 8.12.
+
+2002-09-05  Don Porter  <dgp@users.sourceforge.net>
+
+	* doc/tcltest.n:  Clarified phrasing.
+
+	* generic/tclBasic.c (TclRenameCommand,CallCommandTraces):
+	* tests/trace.test (trace-27.1): Corrected memory leak when a rename
+	trace deleted the command being traced. Test added. Thanks to Hemang
+	Lavana for the fix. [Bug 604609]
+
+	* generic/tclVar.c (TclDeleteVars):  Corrected logic for setting the
+	TCL_INTERP_DESTROYED flag when calling variable traces. [Tk Bug 605121]
+
+2002-09-04  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* generic/tclVar.c (DeleteArray): leak plug [Bug 604239]. Thanks to
+	dkf and dgp for the long and difficult discussion in the chat.
+
+2002-09-03  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* generic/tclVar.c (Tcl_UpVar2): code cleanup to not use goto
+
+	* unix/configure: remove -pthread from LIBS on FreeBSD in thread
+	* unix/tcl.m4:    enabled build. [Bug 602849]
+
+2002-09-03  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* generic/tclInterp.c (AliasCreate): a Tcl_Obj was leaked on error
+	return from TclPreventAliasLoop.
+
+2002-09-03  Daniel Steffen  <das@users.sourceforge.net>
+
+	* macosx/Tcl.pbproj/project.pbxproj: Bumped version number to 8.4.0
+	and updated copyright info.
+
+2002-09-03  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* generic/tclVar.c (Tcl_UpVar2): a Tcl_Obj was being leaked on error
+	return from TclGetFrame.
+
+2002-09-03  Don Porter  <dgp@users.sourceforge.net>
+
+	* changes:  Updated changes for 8.4.0 release.
+
+2002-09-02  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* unix/tclUnixFile.c (TclpObjLink): removed unnecessary/unfreed extra
+	native char*.
+
+	* unix/tclUnixChan.c (Tcl_MakeTcpClientChannel): make sure to init
+	flags field of TcpState ptr to 0.
+
+	* unix/configure:
+	* unix/tcl.m4: added 64-bit gcc compilation support on HP-11.
+	[Patch 601051] (martin)
+
+	* README:		Bumped version number to 8.4.0
+	* generic/tcl.h:
+	* tools/tcl.wse.in:
+	* unix/configure:
+	* unix/configure.in:
+	* unix/tcl.spec:
+	* win/README.binary:
+	* win/configure:
+	* win/configure.in:
+
+	* generic/tclInterp.c (SlaveCreate): make sure that the memory and
+	checkmem commands are initialized in non-safe slave interpreters when
+	TCL_MEM_DEBUG is used. [Bug 583445]
+
+	* win/tclWinConsole.c (ConsoleCloseProc): only wait on writable pipe
+	if there was something to write. This may prevent infinite wait on
+	exit.
+
+	* tests/exec.test: marked exec-18.1 unixOnly until the Windows
+	incompatability (in the test, not the core) can be resolved.
+
+	* tests/http.test (http-3.11): added close $fp that was causing an
+	error on Windows because the file was not closed before deleting.
+
+	* unix/tclUnixInit.c (Tcl_MacOSXGetLibraryPath): made this static
+	function only appear when HAVE_CFBUNDLE is defined.
+
+2002-08-31  Daniel Steffen  <das@users.sourceforge.net>
+
+	* unix/tcl.m4: added TK_SHLIB_LD_EXTRAS analogue of existing
+	TCL_SHLIB_LD_EXTRAS for linker settings only used when linking Tk.
+
+	* unix/configure: regen
+
+2002-08-31  Daniel Steffen  <das@users.sourceforge.net>
+
+	*** macosx-8-4-branch merged into the mainline [Patch 602770] ***
+
+	* generic/tcl.decls: added new macosx specific entry to stubs table.
+
+	* tools/genStubs.tcl: added generation of platform guards for
+	macosx. This is a little more complex than it seems, because MacOS X
+	IS "unix" plus a little bit, for the purposes of Tcl. BUT
+	unfortunately, Tk uses "unix" to mean X11. So added platform keys for
+	macosx (the little added to "unix"), "aqua" and "x11" to distinguish
+	these for Tk.
+
+	* generic/tcl.h: added a #ifnded RESOURCE_INCLUDED so that tcl.h can
+	be passed to the resource compiler.
+
+	* generic/tcl.h:
+	* generic/tclNotify.c: added a few Notifier procs, to be able to
+	modify more bits of the Tcl notifier dynamically. Required to get Mac
+	OS X Tk to live on top of the Tcl Unix threaded notifier. Changes the
+	size of the Tcl_NotifierProcs structure, but doesn't move any elements
+	around.
+
+	* unix/tclUnixNotfy.c: moved the call to Tcl_ConditionNotify till
+	AFTER we are done mucking with the pointer swap. Fixes cases where the
+	thread waiting on the condition wakes & accesses the waitingListPtr
+	before it gets reset, causing a hang.
+
+	* library/auto.tcl (tcl_findLibrary): added checking the directories
+	in the tcl_pkgPath for library files on macosx to enable support of
+	the standard Mac OSX library locations.
+
+	* unix/Makefile.in:
+	* unix/configure.in:
+	* unix/tcl.m4: added MAC_OSX_DIR. Added PLAT_OBJS to the OBJS: there
+	are some MacOS X specific files now for Tcl, and when I get the
+	resource & applescript stuff ported over, and restore support for
+	FindFiles, etc, there will be a few more. Added LD_LIBRARY_PATH_VAR
+	configure variable to avoid having to set all possible LD_LIBRARY_PATH
+	analogues on all platforms. LD_LIBRARY_PATH_VAR is "LD_LIBRARY_PATH"
+	by default, "LIBPATH" on AIX, "SHLIB_PATH" on HPUX and
+	"DYLD_LIBRARY_PATH" on Mac OSX. Added configure option to package Tcl
+	as a framework on Mac OSX.
+
+	* macosx/tclMacOSXBundle.c (new): support for finding Tcl extension
+	packaged as 'bundles' in the standard Mac OSX library locations.
+
+	* unix/tclUnixInit.c: added support for findig the tcl script library
+	inside Tcl packaged as a framework on Mac OSX.
+
+	* macosx/Tcl.pbproj/jingham.pbxuser (new):
+	* macosx/Tcl.pbproj/project.pbxproj (new): project for Apple's
+	ProjectBuilder IDE.
+
+	* macosx/Makefile (new): simple makefile for building the project from
+	the command line via the ProjectBuilder tool 'pbxbuild'.
+
+	* unix/configure:
+	* generic/tclStubInit.c:
+	* generic/tclPlatDecls.h: regen
+
+2002-08-29  Andreas Kupries  <andreas_kupries@users.sourceforge.net>
+
+	* win/tclWinThrd.c (TclpFinalizeThreadData, TclWinFreeAllocCache):
+	Applied patch for [Bug 599428], provided by Miguel Sofer
+	<msofer@users.sourceforge.net>.
+
+2002-08-28  David Gravereaux <davygrvy@pobox.com>
+
+	* generic/tclEnv.c:
+	* unix/configure.in:
+	* win/tclWinPort.h:  putenv() on some systems copies the buffer rather
+	than taking reference to it. This causes memory leaks and is know to
+	effect mswindows (msvcrt) and NetBSD 1.5.2 . This patch tests for this
+	behavior and turns on -DHAVE_PUTENV_THAT_COPIES=1 when approriate.
+	Thanks to David Welton for assistance. [Bug 414910]
+
+	* unix/configure: regen'd
+
+2002-08-28  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* doc/eval.n: Added mention of list command and corrected "SEE ALSO".
+
+	* unix/configure.in: Cache handling of ac_cv_type_socklen_t was wrong.
+	[Bug 600931] reported by John Ellson. Fixed by putting the brackets
+	where they belong.
+
+2002-08-26  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* generic/tclCompCmds.c: fix for [Bug 599788] (error in element name
+	causing segfault), reported by Tom Wilkason. Fixed by copying the
+	tokens instead of the source string.
+
+2002-08-26  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* generic/tclThreadAlloc.c: small optimisation, reducing the new
+	allocator's overhead.
+
+2002-08-23  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* generic/tclObj.c (USE_THREAD_ALLOC): fixed leak [Bug 597936]. Thanks
+	to Zoran Vasiljevic.
+
+2002-08-23  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* generic/tclThreadAlloc.c (USE_THREAD_ALLOC): moving objects between
+	caches as a block, instead of one-by-one.
+
+2002-08-22  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* generic/tclBasic.c:
+	* generic/tclCmdMZ.c: fix for freed memory r/w in delete traces [Bug
+	589863], patch by Hemang Lavana.
+
+2002-08-20  Andreas Kupries  <andreas_kupries@users.sourceforge.net>
+
+	* win/Makefile.in (CFLAGS):
+	* unix/Makefile.in (MEM_DEBUG_FLAGS): Added usage of @MEM_DEBUG_FLAGS@.
+	* win/configure.in:
+	* unix/configure.in: Added usage of SC_ENABLE_MEMDEBUG.
+	* win/tcl.m4:
+	* unix/tcl.m4: Added macro SC_ENABLE_MEMDEBUG. Allows a user of
+	configure to (de)activate memory validation and debugging
+	(TCL_MEM_DEBUG). No need to modify the makefile anymore.
+
+2002-08-20  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclCkalloc.c:	CONSTified MemoryCmd and CheckmemCmd.
+
+	* README:		Bumped version number to 8.4b3 to distinguish
+	* generic/tcl.h:	HEAD from the 8.4b2 release.
+	* tools/tcl.wse.in:
+	* unix/configure.in:
+	* unix/tcl.spec:
+	* win/README.binary:
+	* win/configure.in:
+
+	* unix/configure:	autoconf
+	* win/configure:
+
+	* library/http/http.tcl:	Corrected installation directory of
+	* library/msgcat/msgcat.tcl:	the package tcltest 2.2. Added
+	* library/opt/optparse.tcl:	comments in other packages to remind
+	* library/tcltest/tcltest.tcl:	that installation directories need
+	* unix/Makefile.in:		updates to match increasing version
+	* win/Makefile.in:		numbers. [Bug 597450]
+	* win/makefile.bc:
+	* win/makefile.vc:
+
+2002-08-19  Andreas Kupries  <andreas_kupries@users.sourceforge.net>
+
+	* unix/tclUnixTest.c (TestfilehandlerCmd): Changed readable/writable
+	to the more common readable|writable. Fixes [Bug 596034] reported by
+	Larry Virden <lvirden@users.sourceforge.net>.
+
+2002-08-16  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* tests/fCmd.test: Added test to make sure that the cause of the
+	problem is detectable with an unpatched Tcl.
+	* doc/ObjectType.3: Added note on the root cause of this problem to
+	the documentation, since it is possible for user code to trigger this
+	sort of behaviour too.
+	* generic/tclIOUtil.c (SetFsPathFromAny): Objects should only have
+	their old representation deleted when we know that we are about to
+	install a new one. This stops a weird TclX bug under Linux with
+	certain kinds of memory debugging enabled which essentally came down
+	to a double-free of a string.
+
+2002-08-14  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* generic/tclInt.h:
+	* generic/tclObj.c: (code cleanup) factored the parts in the macros
+	TclNewObj() / TclDecrRefCount() into a common part for all
+	memory allocators and two new macros TclAllocObjStorage() /
+	TclFreeObjStorage() that are specific to each allocator and fully
+	describe the differences. Removed allocator-specific code from
+	tclObj.c by using the macros.
+
+2002-08-12  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* generic/tclCmdMZ.c: fixing UMR in delete traces, [Bug 589863].
+
+2002-08-08  David Gravereaux <davygrvy@pobox.com>
+
+	* tools/man2help.tcl: Fixed $argv handling bug where if -bitmap wasn't
+	specified $argc was off by one.
+
+2002-08-08  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* tests/uplevel.test: added 6.1 to test [uplevel] with shadowed
+	commands [Bug 524383]
+
+	* tests/subst.test: added 5.8-10 as further tests for [Bug 495207]
+
+2002-08-08  Don Porter  <dgp@users.sourceforge.net>
+
+	* tests/README: Noted removal of defs.tcl.
+
+2002-08-08  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* doc/lsearch.n: corrected lsearch docs to use -inline in examples.
+
+	*** 8.4b2 TAGGED FOR RELEASE ***
+
+	* tests/fCmd.test:
+	* tests/unixFCmd.test: updated tests for new link copy behavior.
+	* generic/tclFCmd.c (CopyRenameOneFile): changed the behavior to
+	follow links to endpoints and copy that file/directory instead of just
+	copying the surface link. This means that trying to copy a link that
+	has no endpoint (danling link) is an error. [Patch 591647] (darley)
+	(CopyRenameOneFile): this is currently disabled by default until
+	further issues with such behavior (like relative links) can be
+	handled correctly.
+
+	* tests/README: slight wording improvements
+
+2002-08-07  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* docs/BoolObj.3: added description of valid string reps for a
+	boolean object. [Bug 584794]
+	* generic/tclObj.c: optimised Tcl_GetBooleanFromObj and
+	SetBooleanFromAny to avoid parsing the string rep when it can be
+	avoided. [Bugs 584650, 472576]
+
+2002-08-07  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* generic/tclCompile.h:
+	* generic/tclObj.c: making tclCmdNameType static ([Bug 584567], Don
+	Porter).
+
+2002-08-07  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* generic/tclObj.c (Tcl_NewObj): added conditional code for
+	USE_THREAD_ALLOC; objects allocated through Tcl_NewObj() were
+	otherwise being leaked. [Bug 587488] reported by Sven Sass.
+
+2002-08-06  Daniel Steffen  <das@users.sourceforge.net>
+
+	* generic/tclInt.decls:
+	* unix/tclUnixThrd.c: Added stubs and implementations for
+	non-threaded build for the tclUnixThrd.c procs TclpReaddir,
+	TclpLocaltime, TclpGmtime and TclpInetNtoa. Fixes link errors in
+	stubbed & threaded extensions that include tclUnixPort.h and use any
+	of the procs readdir, localtime, gmtime or inet_ntoa (e.g. TclX 8.4)
+	[Bug 589526]
+	* generic/tclIntPlatDecls.h:
+	* generic/tclStubInit.c: Regen.
+
+2002-08-05  Don Porter  <dgp@users.sourceforge.net>
+
+	* library/tcltest/tcltest.tcl:	The setup and cleanup scripts are now
+	* library/tcltest/pkgIndex.tcl:	skipped when a test is skipped, fixing
+	* tests/tcltest.test:		[Bug 589859]. Test for bug added, and
+	corrected tcltest package bumped to version 2.2.
+
+	* generic/tcl.decls:	Restored Tcl_Concat to return (char *). Like
+	* generic/tclDecls.h:	Tcl_Merge, it transfers ownership of a dynamic
+	* generic/tclUtil.c:	allocated string to the caller.
+
+2002-08-04  Don Porter  <dgp@users.sourceforge.net>
+
+	* doc/CmdCmplt.3:	Applied Patch 585105 to fully CONST-ify all
+	* doc/Concat.3:		remaining public interfaces of Tcl. Notably,
+	* doc/CrtCommand.3:	the parser no longer writes on the string it
+	* doc/CrtSlave.3:	is parsing, so it is no longer necessary for
+	* doc/CrtTrace.3:	Tcl_Eval() to be given a writable string. Also
+	* doc/Eval.3:		the refactoring of the Tcl_*Var* routines by
+	* doc/ExprLong.3:	by Miguel Sofer is included, so that the
+	* doc/LinkVar.3:	"part1" argument for them no longer needs to
+	* doc/ParseCmd.3:	be writable either.
+	* doc/SetVar.3:
+	* doc/TraceVar.3:
+	* doc/UpVar.3:		Compatibility support has been enhanced so
+	* generic/tcl.decls:	that a #define of USE_NON_CONST will remove
+	* generic/tcl.h:	all possible source incompatibilities with the
+	* generic/tclBasic.c:	8.3 version of the header file(s). The new
+	* generic/tclCmdMZ.c:	#define of USE_COMPAT_CONST now does what
+	* generic/tclCompCmds.c:USE_NON_CONST used to do -- disable only those
+	* generic/tclCompExpr.c:new CONST's that introduce irreconcilable
+	* generic/tclCompile.c:	incompatibilities.
+	* generic/tclCompile.h:
+	* generic/tclDecls.h:	Several bugs are also fixed by this patch.
+	* generic/tclEnv.c:	[Bugs 584051,580433] [Patches 585105,582429]
+	* generic/tclEvent.c:
+	* generic/tclInt.decls:
+	* generic/tclInt.h:
+	* generic/tclIntDecls.h:
+	* generic/tclInterp.c:
+	* generic/tclLink.c:
+	* generic/tclObj.c:
+	* generic/tclParse.c:
+	* generic/tclParseExpr.c:
+	* generic/tclProc.c:
+	* generic/tclTest.c:
+	* generic/tclUtf.c:
+	* generic/tclUtil.c:
+	* generic/tclVar.c:
+	* mac/tclMacTest.c:
+	* tests/expr-old.test:
+	* tests/parseExpr.test:
+	* unix/tclUnixTest.c:
+	* unix/tclXtTest.c:
+	* win/tclWinTest.c:
+
+2002-08-01  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* generic/tclExecute.c: bugfix (reading freed memory). Testsuite
+	passed on linux/i386, compile-13.1 hung on linux/alpha.
+
+2002-08-01  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* generic/tclExecute.c: added a reference count for the complete
+	execution stack, instead of Tcl_Preserve/Tcl_Release.
+
+2002-08-01  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* generic/tclCkalloc.c (TclFinalizeMemorySubsystem): Don't lock the
+	ckalloc mutex before invoking the Tcl_DumpActiveMemory function since
+	it also locks the same mutex. This code is only executed when "memory
+	onexit filename" has been executed and Tcl is compiled with
+	-DTCL_MEM_DEBUG.
+
+2002-08-01  Reinhard Max  <max@suse.de>
+
+	* win/tclWinPort.h: The windows headers don't provide socklen_t, so we
+	have to do it.
+
+2002-07-31  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* generic/tclInt.h (USE_THREAD_ALLOC): for unshared objects,
+	TclDecrRefCount now frees the internal rep before the string rep -
+	just like the non-macro Tcl_DecrRefCount/TclFreeObj [Bug 524802]. For
+	the other allocators the fix was done on 2002-03-06.
+
+2002-07-31  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* generic/tclInterp.c: signed/unsigned comparison warning fixed
+	(Vince Darley).
+
+2002-07-31  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* unix/tcl.m4 (SC_BUGGY_STRTOD): Enabled caching of test results.
+
+	* unix/tcl.m4 (SC_BUGGY_STRTOD): Solaris 2.8 still has a buggy
+	strtod() implementation; make sure we detect it.
+
+	* tests/expr.test (expr-22.*): Marked as non-portable because it seems
+	that these tests have an annoying tendency to fail in unexpected ways.
+	[Bugs 584825, 584950, 585986]
+
+2002-07-30  Andreas Kupries  <andreas_kupries@users.sourceforge.net>
+
+	* tests/io.test:
+	* generic/tclIO.c (WriteChars): Added flag to break out of loop if
+	nothing of the input is consumed at all, to prevent infinite looping
+	of called with a non-UTF-8 string. Fixes Bug 584603 (partially). Added
+	new test "io-60.1". Might need additional changes to Tcl_Main so that
+	unprintable results are printed as binary data.
+
+2002-07-29  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* unix/Makefile.in: Use CC_SEARCH_FLAGS instead of LD_SEARCH_FLAGS
+	when linking with ${CC}.
+	* unix/configure: Regen.
+	* unix/configure.in: Don't subst CC_SEARCH_FLAGS or LD_SEARCH_FLAGS
+	since this is now done in tcl.m4.
+	* unix/tcl.m4 (SC_CONFIG_CFLAGS): Document and set CC_SEARCH_FLAGS
+	whenever LD_SEARCH_FLAGS is set. [Patch 588290]
+
+2002-07-29  Reinhard Max  <max@suse.de>
+
+	* unix/tcl.m4 (SC_SERIAL_PORT): Fixed detection for cases when
+                                        configure's stdin is not a tty.
+
+	* unix/tclUnixPort.h:
+	* generic/tclIOSock.c:          Changed size_t to socklen_t in
+                                        socket-related function calls.
+
+	* unix/configure.in:            Added test and fallback definition
+                                        for socklen_t.
+
+	* unix/configure:               generated.
+
+2002-07-29  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* generic/tclObj.c: fixed a comment
+
+	* generic/tcl.h:
+	* generic/tclBasic.c:
+	* generic/tclInterp.c: added the new flag TCL_EVAL_INVOKE to the
+	interface of the Tcl_Eval* functions, removing the
+	TCL_EVAL_NO_TRACEBACK added yesterday: alias invocations not only
+	require no tracebacks, but also look up the command name in the global
+	scope - see new test interp-9.4
+	* tests/interp.test: added 9.3 to test for safety of aliases to hidden
+	commands, 9.4 to test for correct command lookup scope.
+
+2002-07-29  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* generic/regc_locale.c (cclass): [[:xdigit:]] is only a defined
+	concept on western characters, so should not allow any unicode digit,
+	and hence number of ranges in [[:xdigit:]] is fixed.
+	* tests/reg.test: Added test to detect the bug.
+	* generic/regc_cvec.c (newcvec): Corrected initial size value in
+	character vector structure. [Bug 578363] Many thanks to
+	pvgoran@users.sf.net for tracking this down.
+
+2002-07-28  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* generic/tcl.h:
+	* generic/tclBasic.c: added the new flag TCL_EVAL_NO_TRACEBACK to the
+	interface of the Tcl_Eval* functions. Modified the error message for
+	too many nested evaluations.
+	* generic/tclInterp.h: changed the Alias struct to be of variable
+	length and store the prefix arguments directly (instead of a pointer
+	to a Tcl_Obj list). Made AliasObjCmd call Tcl_EvalObjv instead of
+	TclObjInvoke - thus making aliases trigger execution traces [Bug
+	582522].
+	* tests/interp.test:
+	* tests/stack.test: adapted to the new error message.
+	* tests/trace.test: added tests for aliases firing the exec traces.
+
+2002-07-27  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* unix/Makefile.in: Revert fix for Tcl bug 529801 since it was
+	incorrect and broke the build on other systems. Fix [Bug 587299]. Add
+	MAJOR_VERSION, MINOR_VERSION, PATCH_LEVEL, SHLIB_LD_FLAGS,
+	SHLIB_LD_LIBS, CC_SEARCH_FLAGS, LD_SEARCH_FLAGS, and LIB_FILE
+	variables to support more generic library build/install rules.
+	* unix/configure: Regen.
+	* unix/configure.in: Move AC_PROG_RANLIB into tcl.m4. Move shared
+	build test and setting of MAKE_LIB and MAKE_STUB_LIB into tcl.m4. Move
+	subst of a number of variables into tcl.m4 where they are defined.
+	* unix/tcl.m4 (SC_ENABLE_SYMBOLS, SC_CONFIG_CFLAGS): Subst vars where
+	they are defined. Add MAKE_LIB, MAKE_STUB_LIB, INSTALL_LIB, and
+	INSTALL_STUB_LIB rules to deal with the ugly details of running ranlib
+	on static libs at build and install time. Replace TCL_SHLIB_LD_EXTRAS
+	with SHLIB_LD_FLAGS and use it when building a shared library.
+	* unix/tclConfig.sh.in: Add TCL_CC_SEARCH_FLAGS.
+
+2002-07-26  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* generic/tclExecute.c: fixed Tcl_Obj leak in code corresponding to
+	the macro NEXT_INST_V(x, 0, 1) [Bug 587495].
+
+2002-07-26  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* generic/tclVar.c (TclObjLookupVar): leak fix and improved comments.
+
+2002-07-26  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* generic/tclVar.c (TclLookupVar): removed early returns that
+	prevented the parens from being restored. Also removed goto label as
+	it was not necessary.
+
+2002-07-24  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* generic/tclExecute.c:
+	* tests/expr-old.test: fix for erroneous error messages in [expr],
+	[Bug 587140] reported by Martin Lemburg.
+
+2002-07-25  Joe English  <jenglish@users.sourceforge.net>
+
+	* generic/tclProc.c: fix for [Tk Bug 219218] "error handling with
+	bgerror in Tk"
+
+2002-07-24  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* generic/tclExecute.c: restoring full TCL_COMPILE_DEBUG
+	functionality.
+
+2002-07-24  Don Porter  <dgp@users.sourceforge.net>
+
+	* tests/unixInit.test: relaxed unixInit-3.1 to accept iso8859-15 as a
+	valid C encoding. [Bug 575336]
+
+2002-07-24  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* generic/tclExecute.c: restoring the tcl_traceCompile functionality
+	while I repair tcl_traceExec. The core now compiles and runs also
+	under TCL_COMPILE_DEBUG, but execution in the bytecode engine can
+	still not be traced.
+
+2002-07-24  Daniel Steffen  <das@users.sourceforge.net>
+
+	* unix/Makefile.in:
+	* unix/configure.in: corrected fix for [Bug 529801]: ranlib only
+	needed for static builds on Mac OS X.
+	* unix/configure: Regen.
+	* unix/tclLoadDyld.c: fixed small bugs introduced by Vince,
+	implemented library unloading correctly (needs OS X 10.2).
+
+2002-07-23  Joe English  <jenglish@users.sourceforge.net>
+
+	* doc/OpenFileChnl.3: (Updates from Larry Virden)
+	* doc/open.n:
+	* doc/tclsh.1: Fix section numbers in Unix man page references.
+	* doc/lset.n:  In EXAMPLES section, include command to set the initial
+	value used in subsequent examples.
+	* doc/http.n: Package version updated to 2.4.
+
+2002-07-23  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* unix/configure: Regen.
+	* unix/tcl.m4 (SC_CONFIG_CFLAGS): Enable 64 bit compilation when using
+	the native compiler on a 64 bit version of IRIX. [Bug 219220]
+
+2002-07-23  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* unix/Makefile.in: Combine ranlib tests and avoid printing unless
+	ranlib is actually run.
+
+2002-07-23  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* unix/tcl.m4 (SC_PATH_X): Set XINCLUDES to "" instead of "# no
+	special path needed" or "# no include files found" when x headers
+	cannot be located.
+
+2002-07-22  Vince Darley  <vincentdarley@users.sourceforge.net>
+
+	* generic/tclIOUtil.c: made tclNativeFilesystem static (since 07-19
+	changes removed its usage elsewhere), and added comments about its
+	usage.
+	* generic/tclLoad.c:
+	* generic/tcl.h:
+	* generic/tcl.decls:
+	* doc/FileSystem.3: converted last load-related ClientData parameter
+	to Tcl_LoadHandle opaque structure, removing a couple of casts in the
+	process.
+
+	* generic/tclInt.h: removed tclNativeFilesystem declaration since it
+	is now static again.
+
+2002-07-22  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* tests/expr.test (expr-22.*): Added tests to help detect the
+	corrected handling.
+	* generic/tclExecute.c (IllegalExprOperandType): Improved error
+	message generated when attempting to manipulate Inf and NaN values.
+	* generic/tclParseExpr.c (GetLexeme): Allowed parser to recognise
+	'Inf' as a floating-point number. [Bug 218000]
+
+2002-07-21  Don Porter  <dgp@users.sourceforge.net>
+
+	* tclIOUtil.c: Silence compiler warning. [Bug 584408].
+
+2002-07-19  Vince Darley  <vincentdarley@users.sourceforge.net>
+
+	* generic/tclIOUtil.c: fix to GetFilesystemRecord
+	* win/tclWinFile.c:
+	* unix/tclUnixFile.c: fix to subtle problem with links shown up by
+	latest tclkit builds.
+
+2002-07-19  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* unix/configure:
+	* unix/configure.in:
+	* win/configure:
+	* win/configure.in: Add AC_PREREQ(2.13) in an attempt to make it more
+	clear that the configure scripts must be generated with autoconf
+	version 2.13. [Bug 583573]
+
+2002-07-19  Vince Darley  <vincentdarley@users.sourceforge.net>
+
+	* unix/Makefile.in: fix to build on MacOS X [Bug 529801], bug report
+	and fix from jcw.
+
+2002-07-19  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* win/tclWinSerial.c (no_timeout): Made this variable static.
+
+	* generic/tclExecute.c, generic/tclCompile.c, generic/tclBasic.c:
+	* generic/tclCompile.h (builtinFuncTable, instructionTable): Added
+	prefix to these symbols because they are visible outside the Tcl
+	library.
+
+	* generic/tclCompExpr.c (operatorTable):
+	* unix/tclUnixTime.c (tmKey):
+	* generic/tclIOUtil.c (theFilesystemEpoch, filesystemWantToModify,
+	filesystemIteratorsInProgress, filesystemOkToModify): Made these
+	variables static.
+
+	* unix/tclUnixFile.c:		Renamed nativeFilesystem to
+	* win/tclWinFile.c:		tclNativeFilesystem and declared
+	* generic/tclIOUtil.c:		it properly in tclInt.h
+	* generic/tclInt.h:
+
+	* generic/tclUtf.c (totalBytes): Made this array static and const.
+
+	* generic/tclParse.c (typeTable): Made this array static and const.
+	(Tcl_ParseBraces): Simplified error handling case so that scans are
+	only performed when needed, and flags are simpler too.
+
+	* license.terms: Added AS to list of copyright holders; it's only
+	fair for the current gatekeepers to be listed here!
+
+	* tests/cmdMZ.test: Renamed constraint for clarity. [Bug 583427]
+	Added tests for the [time] command, which was previously only
+	indirectly tested!
+
+2002-07-18  Vince Darley  <vincentdarley@users.sourceforge.net>
+
+	* generic/tclInt.h:
+	* generic/tcl.h:
+	* */*Load*.c: added comments on changes of 07/17 and replaced
+	clientData with Tcl_LoadHandle in all locations.
+
+	* generic/tclFCmd.c:
+	* tests/fileSystem.test: fixed a 'knownBug' with 'file attributes ""'
+	* tests/winFCmd.test:
+	* tests/winPipe.test:
+	* tests/fCmd.test:
+	* tessts/winFile.test: added 'pcOnly' constraint to some tests to make
+	for more useful 'tests skipped' log from running all tests on
+	non-Windows platforms.
+
+2002-07-17  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* generic/tclBasic.c (CallCommandTraces): delete traces now receive
+	the FQ old name of the command. [Bug 582532] (Don Porter)
+
+2002-07-18  Vince Darley  <vincentdarley@users.sourceforge.net>
+
+	* tests/ioUtil.test: added constraints to 1.4,2.4 so they don't run
+	outside of tcltest. [Bugs 583276, 583277]
+
+2002-07-17  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* generic/tclVar.c (DupParsedVarName): nasty bug fixed, reported by
+	Vince Darley.
+
+2002-07-17  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* generic/tclVar.c (TclPtrIncrVar): missing CONST in declarations,
+	inconsistent with tclInt.h. Thanks to Vince Darley for reporting, boo
+	to gcc for not complaining.
+
+2002-07-17  Vince Darley  <vincentdarley@users.sourceforge.net>
+
+	* generic/tclInt.h:
+	* generic/tclIOUtil.c:
+	* generic/tclLoadNone.c:
+	* unix/tclLoadAout.c:
+	* unix/tclLoadDl.c:
+	* unix/tclLoadDld.c:
+	* unix/tclLoadDyld.c:
+	* unix/tclLoadNext.c:
+	* unix/tclLoadOSF.c:
+	* unix/tclLoadShl.c:
+	* mac/tclMacLoad.c:
+	* win/tclWinLoad.c: modified to move more functionality to the generic
+	code and avoid duplication. Partial replacement of internal uses of
+	clientData with opaque Tcl_LoadHandle. A little further work still
+	needed, but significant changes are done.
+
+2002-07-17  D. Richard Hipp    <drh@hwaci.com>
+
+	* library/msgcat/msgcat.tcl: fix a comment that was causing problems
+	for programs (ex: mktclapp) that embed the initialization scripts in
+	strings.
+
+2002-07-17  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* generic/tclInt.decls:
+	* generic/tclIntDecls.h:
+	* generic/tclStubInit.c:
+	* generic/tclVar.c: removing the now redundant functions to access
+	indexed variables: Tcl(Get|Set|Incr)IndexedScalar() and
+	Tcl(Get|Set|Incr)ElementOfIndexedArray().
+
+2002-07-17  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* generic/tclExecute.c (TclExecuteByteCode): Minor fixes to make this
+	file compile with SunPro CC...
+
+2002-07-17  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* generic/tclExecute.c: modified to do variable lookup explicitly, and
+	then either inlining the variable access or else calling the new
+	TclPtr(Set|Get|Incr)Var functions in tclVar.c
+	* generic/tclInt.h: declare some functions previously local to
+	tclVar.c for usage by TEBC.
+	* generic/tclVar.c: removed local declarations; moved all special
+	accessor functions for indexed variables to the end of the file -
+	they are unused and ready for removal, but left there for the time
+	being as they are in the internal stubs table.
+
+	** WARNING FOR BYTECODE MAINTAINERS **
+	TCL_COMPILE_DEBUG is currently not functional; will be fixed ASAP.
+
+2002-07-16  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* unix/Makefile.in:
+	* win/Makefile.in: Add a more descriptive warning in the event `make
+	genstubs` needs to be rerun.
+
+2002-07-16  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* unix/Makefile.in: Use dltest.marker file to keep track of when the
+	dltest package is up to date. This fixes [Bug 575768] since tcltest is
+	no longer linked every time.
+	* unix/dltest/Makefile.in: Create ../dltest.marker after a successful
+	`make all` run in dltest.
+
+2002-07-16  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* unix/configure: Regen.
+	* unix/configure.in: Remove useless subst of TCL_BIN_DIR.
+
+2002-07-15  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* generic/tclVar.c: inaccurate comment fixed
+
+2002-07-15  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* generic/tclBasic.c (Tcl_AddObjErrorInfo):
+	* generic/tclExecute.c (TclUpdateReturnInfo):
+	* generic/tclInt.h:
+	* generic/tclProc.c:
+	Added two Tcl_Obj to the ExecEnv structure to hold the fully qualified
+	names "::errorInfo" and "::errorCode" to cache the addresses of the
+	corresponding variables. The two most frequent setters of these
+	variables now profit from the new variable name caching.
+
+2002-07-15  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* generic/tclVar.c: refactorisation to reuse already looked-up Var
+	pointers; definition of three new Tcl_Obj types to cache variable name
+	parsing and lookup for later reuse; modification of internal functions
+	to profit from the caching.
+
+	* generic/tclInt.decls:
+	* generic/tclInt.h:
+	* generic/tclIntDecls.h:
+	* generic/tclNamesp.c: adding CONST qualifiers to variable names
+	passed to Tcl_FindNamespaceVar and to variable resolvers; adding CONST
+	qualifier to the 'msg' argument to TclLookupVar. Needed to avoid code
+	duplication in the new tclVar.c code.
+
+	* tests/set-old.test:
+	* tests/var.test: slight modification of error messages due to the
+	modifications in the tclVar.c code.
+
+2002-07-15  Don Porter  <dgp@users.sourceforge.net>
+
+	* tests/unixInit.test:	Improved constraints to protect /tmp. [Bug
+	581403]
+
+2002-07-15  Vince Darley  <vincentdarley@users.sourceforge.net>
+
+	* tests/winFCmd.test: renamed 'win2000' and 'notWin2000' to more
+	appropriate constraint names.
+	* win/tclWinFile.c: updated comments to reflect 07-11 changes.
+	* win/tclWinFCmd.c: made ConvertFileNameFormat static again, since no
+	longer used in tclWinFile.c
+	* mac/tclMacFile.c: completed TclpObjLink implementation which was
+	previously lacking.
+	* generic/tclIOUtil.c: comment cleanup and code speedup.
+
+2002-07-14  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclInt.h:	Removed declarations that duplicated entries
+	in the (internal) stub table.
+
+	* library/tcltest/tcltest.tcl:  Corrected errors in handling of
+	configuration options -constraints and -limitconstraints.
+
+	* README:		Bumped HEAD to version 8.4b2 so we can
+	* generic/tcl.h:	distinguish it from the 8.4b1 release.
+	* tools/tcl.wse.in:
+	* unix/configure*:
+	* unix/tcl.spec:
+	* win/README.binary:
+	* win/configure*:
+
+2002-07-11  Vince Darley  <vincentdarley@users.sourceforge.net>
+
+	* doc/file.n:
+	* win/tclWinFile.c: on Win 95/98/ME the long form of the path is used
+	as a normalized form. This is required because short forms are not a
+	robust representation. The file normalization function has been sped
+	up, but more performance gains might be possible, if speed is still an
+	issue on these platforms.
+
+2002-07-11  Don Porter  <dgp@users.sourceforge.net>
+
+	* library/tcltest/tcltest.tcl: Corrected reaction to existing but
+	false ::tcl_interactive.
+
+	* doc/Hash.3: Overlooked CONST documentation update.
+
+2002-07-11  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* generic/tclCkalloc.c: ckalloc() and friends take the block size as
+	an unsigned, so we should use %ud when reporting it in fprintf() and
+	panic().
+
+2002-07-11  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* generic/tclCompile.c: now setting local vars undefined at compile
+	time, instead of waiting until the proc is initialized.
+	* generic/tclProc.c: use macro TclSetVarUndefined instead of directly
+	setting the flag.
+
+2002-07-11  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* tests/cmdAH.test: [file attr -perm] is Unix-only, so add [catch]
+	when not inside a suitably-protected test.
+
+2002-07-10  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* tests/unixFCmd.test, tests/fileName.test:
+	* tests/fCmd.test: Removed [exec] of Unix utilities that have
+	equivalents in standard Tcl. [Bug 579268] Also simplified some of
+	unixFCmd.test while I was at it.
+
+2002-07-10  Don Porter  <dgp@users.sourceforge.net>
+
+	* tests/tcltest.test:  Greatly reduced the number of [exec]s, using
+	slave interps instead.
+	* library/tcltest/tcltest.tcl:  Fixed bug uncovered in the conversion
+	where a message was written to stdout instead of [outputChannel].
+
+	* tests/basic.test:	Cleaned up, constrained, and reduced the
+	* tests/compile.test:	amount of [exec] usage in the test suite.
+	* tests/encoding.test:
+	* tests/env.test:
+	* tests/event.test:
+	* tests/exec.test:
+	* tests/io.test:
+	* tests/ioCmd.test:
+	* tests/regexp.test:
+	* tests/regexpComp.test:
+	* tests/socket.test:
+	* tests/tcltest.test:
+	* tests/unixInit.test:
+	* tests/winDde.test:
+	* tests/winPipe.test:
+
+2002-07-10  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* tests/cmdAH.test: Removed [exec] of Unix utilities. [Bug 579211]
+
+	* tests/expr.test: Added tests to make sure that this works.
+	* generic/tclExecute.c (ExprCallMathFunc): Functions should also be
+	able to return wide-ints. [Bug 579284]
+
+2002-07-08  Andreas Kupries  <andreas_kupries@users.sourceforge.net>
+
+	* tests/socket.test: Fixed [Bug 578164]. The original reason for the
+	was a DNS outage while running the testsuite. Changed [info hostname]
+	to 127.0.0.1 to bypass DNS, knowing that we operate on the local host.
+
+2002-07-08  Don Porter  <dgp@users.sourceforge.net>
+
+	* doc/tcltest.n:		Fixed incompatibility in [viewFile].
+	* library/tcltest/tcltest.tcl:	Corrected docs. Bumped to 2.2.1.
+	* library/tcltest/pkgIndex.tcl: [Bug 578163]
+
+2002-07-08  Vince Darley  <vincentdarley@users.sourceforge.net>
+
+	* tests/cmdAH.test:
+	* tests/fCmd.test:
+	* tests/fileName.test: tests which rely on 'file link' need a
+	constraint so they don't run on older Windows OS. [Bug 578158]
+	* generic/tclIOUtil.c:
+	* generic/tcl.h:
+	* generic/tclInt.h:
+	* generic/tclTest.c:
+	* mac/tclMacChan.c:
+	* unix/tclUnixChan.c:
+	* win/tclWinChan.c:
+	* doc/FileSystem.3: cleaned up internal handling of
+	Tcl_FSOpenFileChannel to remove duplicate code, and make writing
+	external vfs's clearer and easier. No functionality change. Also
+	clarify that objects with refCount zero should not be passed in to the
+	Tcl_FS API, and prevent segfaults from occuring on such user errors.
+	[Bug 578617]
+
+2002-07-06  Don Porter  <dgp@users.sourceforge.net>
+
+	* tests/pkgMkIndex.test:  Constrained tests of [load] package indexing
+	to those platforms where the testing shared libraries have been built.
+	[Bug 578166]
+
+2002-07-05  Don Porter  <dgp@users.sourceforge.net>
+
+	* changes: added recent changes
+
+2002-07-05  Reinhard Max  <max@suse.de>
+
+	* generic/tclClock.c (FormatClock): Convert the format string to UTF8
+	before calling TclpStrftime, so that non-ASCII characters don't get
+	mangled when the result string is being converted back.
+	* tests/clock.test: Added a test for that.
+
+2002-07-05  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* unix/Makefile.in (ro-test,ddd,GDB,DDD): Created new targets to
+	allow running the test suite with a read-only current directory,
+	running under ddd instead of gdb, and factored out some executable
+	names for broken sites (like mine) where gdb and ddd are installed
+	with non-standard names...
+
+	* tests/httpold.test: Altered test names to httpold-* to avoid clashes
+	with http.test, and stopped tests from failing when the current
+	directory is not writable...
+
+	* tests/event.test:		Stop these tests from failing when the
+	* tests/ioUtil.test:		current directory is not writable...
+	* tests/regexp.test:
+	* tests/regexpComp.test:
+	* tests/source.test:
+	* tests/unixFile.test:
+	* tests/unixNotfy.test:
+
+	* tests/unixFCmd.test:		Trying to make these test-files not
+	* tests/macFCmd.test:		bomb out with an error when the
+	* tests/http.test:		current directory is not writable...
+	* tests/fileName.test:
+	* tests/env.test:
+
+2002-07-05  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	*** 8.4b1 TAGGED FOR RELEASE ***
+
+2002-07-04  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* tests/cmdMZ.test (cmdMZ-1.4):
+	* tests/cmdAH.test: More fixing of writable-current-dir assumption.
+	[Bug 575824]
+
+2002-07-04  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* tests/basic.test: Same issue as below; fixed [Bug 575817]
+
+2002-07-04  Andreas Kupries  <andreas_kupries@users.sourceforge.net>
+
+	* tests/socket.test:
+	* tests/winPipe.test:
+	* tests/pid.test: Fixed [Bug 575848]. See below for a description the
+	general problem.
+
+	* All the bugs below are instances of the same problem: The testsuite
+	assumes [pwd] = [temporaryDirectory] and writable.
+
+	* tests/iogt.test: Fixed [Bug 575860].
+	* tests/io.test:   Fixed [Bug 575862].
+	* tests/exec.test:
+	* tests/ioCmd.test: Fixed [Bug 575836].
+
+2002-07-03  Don Porter  <dgp@users.sourceforge.net>
+
+	* tests/pkg1/direct1.tcl: removed
+	* tests/pkg1/pkgIndex.tcl: removed
+	* tests/pkgMkIndex.test:  Imported auxilliary files from tests/pkg1
+	into the test file pkgMkIndex.test itself. Formatting fixes.
+
+	* unix/Makefile.in: removed tests/pkg/* from `make dist`
+
+	* tests/pkg/circ1.tcl: removed
+	* tests/pkg/circ2.tcl: removed
+	* tests/pkg/circ3.tcl: removed
+	* tests/pkg/global.tcl: removed
+	* tests/pkg/import.tcl: removed
+	* tests/pkg/pkg1.tcl: removed
+	* tests/pkg/pkg2_a.tcl: removed
+	* tests/pkg/pkg2_b.tcl: removed
+	* tests/pkg/pkg3.tcl: removed
+	* tests/pkg/pkg4.tcl: removed
+	* tests/pkg/pkg5.tcl: removed
+	* tests/pkg/pkga.tcl: removed
+	* tests/pkg/samename.tcl: removed
+	* tests/pkg/simple.tcl: removed
+	* tests/pkg/spacename.tcl: removed
+	* tests/pkg/std.tcl: removed
+	* tests/pkgMkIndex.test: Fixed [Bug 575857] where this test file
+	expected to be able to write to [file join [testsDirectory] pkg]. Part
+	of the fix was to import several auxilliary files into the test file
+	itself.
+
+	* tests/main.test:	Cheap fix for [Bugs 575851, 575858]. Avoid
+	* tests/tcltest.test:	non-writable . by [cd [temporaryDirectory]].
+
+	* library/auto.tcl: Fix [tcl_findLibrary] to be sure it sets $varName
+	only if a successful library script is found. [Bug 577033]
+
+2002-07-03  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* generic/tclCompCmds.c (TclCompileCatchCmd): return
+	TCL_OUT_LINE_COMPILE instead of TCL_ERROR: let the failure happen at
+	runtime so that it can be caught [Bug 577015].
+
+2002-07-02  Joe English  <jenglish@users.sourceforge.net>
+
+	* doc/tcltest.n: Markup fixes, spellcheck.
+
+2002-07-02  Don Porter  <dgp@users.sourceforge.net>
+
+	* doc/tcltest.n: more refinements of the documentation.
+
+	* library/tcltest/tcltest.tcl: Added trace to be sure the stdio
+	constraint is updated whenever the [interpreter] changes.
+
+	* doc/tcltest.n:		Reverted [makeFile] and [viewFile] to
+	* library/tcltest/tcltest.tcl:	their former behavior, and documented
+	* tests/cmdAH.test:		it. Corrected misspelling of hook
+	* tests/event.test:		procedure. Restored tests.
+	* tests/http.test:
+	* tests/io.test:
+
+	* library/tcltest/tcltest.tcl: Simplified logic of [GetMatchingFiles]
+	and [GetMatchingDirectories], removing special case processing.
+
+	* doc/tcltest.n: More documentation updates. Reference sections are
+	complete. Only examples need adding.
+
+2002-07-02  Vince Darley  <vincentdarley@users.sourceforge.net>
+
+	* tests/fCmd.test:
+	* generic/tclCmdAH.c: clearer error msgs for 'file link', as per the
+	man page.
+
+2002-07-01  Joe English  <jenglish@users.sourceforge.net>
+
+	* doc/Access.3:
+	* doc/AddErrInfo.3:
+	* doc/Alloc.3:
+	* doc/Backslash.3:
+	* doc/CrtChannel.3:
+	* doc/CrtSlave.3:
+	* doc/Encoding.3:
+	* doc/Eval.3:
+	* doc/FileSystem.3:
+	* doc/Notifier.3:
+	* doc/OpenFileChnl.3:
+	* doc/ParseCmd.3:
+	* doc/RegExp.3:
+	* doc/Tcl_Main.3:
+	* doc/Thread.3:
+	* doc/TraceCmd.3:
+	* doc/Utf.3:
+	* doc/WrongNumArgs.3:
+	* doc/binary.n:
+	* doc/clock.n:
+	* doc/expr.n:
+	* doc/fconfigure.n:
+	* doc/glob.n:
+	* doc/http.n:
+	* doc/interp.n:
+	* doc/lsearch.n:
+	* doc/lset.n:
+	* doc/msgcat.n:
+	* doc/packagens.n:
+	* doc/pkgMkIndex.n:
+	* doc/registry.n:
+	* doc/resource.n:
+	* doc/safe.n:
+	* doc/scan.n:
+	* doc/tclvars.n:  Spell-check, fixed typos (Updates from Larry Virden).
+
+2002-07-01  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* unix/tcl.m4 (SC_CONFIG_CFLAGS): Made Solaris use gcc for linking
+	when building with gcc to resolve problems with undefined symbols
+	being present when tcl library used with non-gcc linker at later
+	stage. Symbols were compiler-generated, so it is the compiler's
+	business to define them. [Bug 541181]
+
+2002-07-01  Don Porter  <dgp@users.sourceforge.net>
+
+	* doc/tcltest.n: more work in progress updating tcltest docs.
+
+	* library/tcltest/tcltest.tcl: Change [configure -match] to stop
+	treating an empty list as a list of the single pattern "*". Changed
+	the default value to [list *] so default operation remains the same.
+
+	* tests/pkg/samename.tcl: restored. needed by pkgMkIndex.test.
+
+	* library/tcltest/tcltest.tcl: restored writeability testing of
+	-tmpdir, augmented by a special exception for the deafault value.
+
+2002-07-01  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* doc/concat.n: Documented the *real* behaviour of [concat]!
+
+2002-06-30  Don Porter  <dgp@users.sourceforge.net>
+
+	* doc/tcltest.n: more work in progress updating tcltest docs.
+
+	* tests/README:		Updated the instructions on running and
+	* tests/cmdMZ.test:	adding to the test suite. Also updated
+	* tests/encoding.test:	several tests, mostly to correctly create
+	* tests/fCmd.test:	and destroy any temporary files in the
+	* tests/info.test:	[temporaryDirectory] of tcltest.
+	* tests/interp.test:
+
+	* library/tcltest/tcltest.tcl:	Stopped checking for writeability of
+	-tmpdir value because no default directory can be guaranteed to be
+	writeable.
+
+	* tests/autoMkindex.tcl: removed.
+	* tests/pkg/samename.tcl: removed.
+	* tests/pkg/magicchar.tcl: removed.
+	* tests/pkg/magicchar2.tcl: removed.
+	* tests/autoMkindex.test: Updated auto_mkIndex tests to use [makeFile]
+	and [removeFile] so tests are done in [temporaryDirecotry] where write
+	access is guaranteed.
+
+	* library/tcltest/tcltest.tcl:	Fixed [makeFile] and [viewFile] to
+	* tests/cmdAH.test:		accurately reflect a file's contents.
+	* tests/event.test:		Updated tests that depended on buggy
+	* tests/http.test:		behavior. Also added warning messages
+	* tests/io.test:		to "-debug 1" operations to debug test
+	* tests/iogt.test:		calls to (make|remove)(File|Directory)
+
+	* unix/mkLinks: `make mklinks` on 6-27 commits.
+
+2002-06-28  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* generic/tclCompile.h: modified the macro TclEmitPush to not call its
+	first argument repeatedly or pass it to other macros, [Bug 575194]
+	reported by Peter Spjuth.
+
+2002-06-28  Don Porter  <dgp@users.sourceforge.net>
+
+	* docs/tcltest.n:	Doc revisions in progress.
+	* library/tcltest/tcltest.tcl: Corrected -testdir default value. Was
+	not reliable, and disagreed with docs! Thanks to Hemang Lavana. [Bug
+	575150]
+
+2002-06-28  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* unix/tclUnixThrd.c:	Renamed the Tcl_Platform* #defines to TclOS*
+	* unix/tclUnixPipe.c:	because they are only used internally. Also
+	* unix/tclUnixFile.c:	stopped double-#def of TclOSlstat [Bug 566099,
+	* unix/tclUnixFCmd.c:	post-rename]
+	* unix/tclUnixChan.c:
+	* unix/tclUnixPort.h:
+
+	* doc/string.n: Improved documentation for [string last] along lines
+	described in [Bug 574799] so it indicates that the supplied index
+	marks the end of the search space.
+
+2002-06-27  Don Porter  <dgp@users.sourceforge.net>
+
+	* doc/dde.n:		Work in progress updating the documentation
+	* doc/http.n:		of the packages that come bundled with
+	* doc/msgcat.n:		the Tcl source distribution, notably tcltest.
+	* doc/registry.n:
+	* doc/tcltest.n:
+
+	* library/tcltest/tcltest.tcl:  Made sure that the TCLTEST_OPTIONS
+	environment variablle configures tcltest at package load time.
+
+2002-06-26  Vince Darley  <vincentdarley@users.sourceforge.net>
+
+	* tests/fileSystem.test:
+	* generic/tclIOUtil.c: fix to handling of empty paths "" which are not
+	claimed by any filesystem [Bug 573758]. Ensure good error messages
+	are given in all cases.
+	* tests/cmdAH.test:
+	* unix/tclUnixFCmd.c: fix to bug reported as part of [Patch 566669].
+	Thanks to Taguchi, Takeshi for the report.
+
+2002-06-26  Reinhard Max  <max@suse.de>
+
+	* unix/tclUnixTime.c: Make [clock format] respect locale settings.
+	* tests/clock.test:   [Bug 565880]. ***POTENTIAL INCOMPATIBILITY***
+
+2002-06-26  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* doc/CrtInterp.3:
+	* doc/StringObj.3: clarifications by Don Porter, [Bug 493995] and [Bug
+	500930].
+
+2002-06-24  Don Porter  <dgp@users.sourceforge.net>
+
+	* library/tcltest/tcltest.tcl:	Corrected suppression of -verbose skip
+	* tests/tcltest.test:		and start by [test -output]. Also
+	corrected test suite errors exposed by corrected code. [Bug 564656]
+
+2002-06-25  Reinhard Max  <max@suse.de>
+
+	* unix/tcl.m4:       New macro SC_CONFIG_MANPAGES.
+	* unix/configure.in: Added support for symlinks and compression when
+	* unix/Makefile.in:  installing the manpages. [Patch 518052]
+	* unix/mkLinks.tcl:  Default is still hardlinks and no compression.
+
+	* unix/mkLinks:      generated
+	* unix/configure:
+
+	* unix/README:       Added documentation for the new features.
+
+	* unix/tcl.m4 (SC_PATH_TCLCONFIG): Replaced ${exec_prefix}/lib by
+	${libdir}.
+
+2002-06-25  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* generic/tclUtil.c (TclGetIntForIndex): Fix of critical [Bug 533364]
+	generated when the index is bad and the result is a shared object. The
+	T_ASTO(T_GOR, ...) idiom likely exists elsewhere though. Also removed
+	some cruft that just complicated things to no advantage.
+	(SetEndOffsetFromAny): Same fix, though this wasn't on the path
+	excited by the bug.
+
+2002-06-24  Don Porter  <dgp@users.sourceforge.net>
+
+	* library/tcltest/tcltest.tcl:	Implementation of TIP 101. Adds abd
+	* tests/parseOld.test:		exports a [configure] command from
+	* tests/tcltest.test:		tcltest.
+
+2002-06-22  Don Porter  <dgp@users.sourceforge.net>
+
+	* changes: updated changes file for 8.4b1 release.
+
+	* library/tcltest/tcltest.tcl:	Corrections to tcltest and the Tcl
+	* tests/basic.test:		test suite so that a test with options
+	* tests/cmdInfo.test:		-constraints knownBug
+	* tests/compile.test:		-limitConstraints 1 only tests the
+	* tests/encoding.test:		knownBug tests. Mostly involves
+	* tests/env.test:		replacing direct access to the
+	* tests/event.test:		testConstraints array with calls to
+	* tests/exec.test:		the testConstraint command (which
+	* tests/execute.test:		requires tcltest version 2)
+	* tests/fCmd.test:
+	* tests/format.test:
+	* tests/http.test:
+	* tests/httpold.test:
+	* tests/ioUtil.test:
+	* tests/link.test:
+	* tests/load.test:
+	* tests/namespace.test:
+	* tests/pkgMkIndex.test:
+	* tests/reg.test:
+	* tests/result.test:
+	* tests/scan.test:
+	* tests/stack.test:
+
+2002-06-22  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* tools/tcl.wse.in (Disk Label), unix/tcl.spec (version):
+	* win/README.binary, README, win/configure.in, unix/configure.in:
+	* generic/tcl.h (TCL_RELEASE_*, TCL_PATCH_LEVEL): Bump to beta1.
+
+2002-06-21  Joe English  <jenglish@users.sourceforge.net>
+
+	* generic/tclCompExpr.c:
+	* generic/tclParseExpr.c: LogSyntaxError() should reset the
+	interpreter result [Bug 550142 "Tcl_ExprObj -> abort"]
+
+2002-06-21  Don Porter  <dgp@users.sourceforge.net>
+
+	* unix/Makefile.in:	Updated all package install directories
+	* win/Makefile.in:	to match current Major.minor versions
+	* win/makefile.bc:	of the packages. Added tcltest package
+	* win/makefile.vc:	to installation on Windows.
+
+	* library/init.tcl:  Corrected comments and namespace style issues.
+	Thanks to Bruce Stephens. [Bug 572025]
+
+2002-06-21  Vince Darley  <vincentdarley@users.sourceforge.net>
+
+	* tests/cmdAH.test:          Added TIP#99 implementation of 'file
+	* tests/fCmd.test:           link'. Supports creation of symbolic and
+	* tests/fileName.test:       hard links in the native filesystems and
+	* tests/fileSystem.test:     in vfs's, when the individual filesystem
+	* generic/tclTest.c:         supports the concept.
+	* generic/tclCmdAH.c:
+	* generic/tclIOUtil.c:
+	* generic/tcl.h:
+	* generic/tcl.decls:
+	* doc/FileSystem.3:
+	* doc/file.n:
+	* mac/tclMacFile.c:
+	* unix/tclUnixFile.c:
+	* win/tclWinFile.c: Also enhanced speed of 'file normalize' on
+	Windows.
+
+2002-06-20  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* generic/tclBasic.c (TclEvalObjvInternal): fix for [Bug 571385] in
+	the implementation of TIP#62 (command tracing). Vince Darley, Hemang
+	Lavana & Don Porter: thanks.
+
+2002-06-20  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* generic/tclExecute.c (TclCompEvalObj): clarified and simplified the
+	logic for compilation/recompilation.
+
+2002-06-19  Joe English  <jenglish@users.sourceforge.net>
+
+	* doc/file.n: Fixed indentation. No substantive changes.
+
+2002-06-19  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* generic/tclCmdMZ.c (Tcl_RegexpObjCmd): get the resultPtr again as
+	the Tcl_ObjSetVar2 may cause the result to change. [Patch 558324]
+	(watson)
+
+2002-06-19  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* generic/tclExecute.c (TEBC): removing unused "for(;;)" loop;
+	improved comments; re-indentation.
+
+2002-06-18  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* generic/tclExecute.c (TEBC):
+	- elimination of duplicated code in the non-immediate INST_INCR
+	  instructions.
+	- elimination of 103 (!) TclDecrRefCount macros. The different
+	  instructions now jump back to a common "DecrRefCount zone" at the
+	  top of the loop. The macro "ADJUST_PC" was replaced by two macros
+	  "NEXT_INST_F" and "NEXT_INST_V" that take three params
+	  (pcAdjustment, # of stack objects to discard, resultObjPtr handling
+	  flag). The only instructions that retain a TclDecrRefCount are
+	  INST_POP (for speed), the common code for the non-immediate
+	  INST_INCR, INST_FOREACH_STEP and the two INST_LSET.
+
+	The object size of tclExecute.o was reduced by approx 20% since the
+	start of the consolidation drive, while making room for some peep-hole
+	optimisation at runtime.
+
+2002-06-18  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* generic/tclExecute.c (TEBC, INST_DONE): small bug in the panic code
+	for tcl-stack corruption.
+
+2002-06-17  David Gravereaux <davygrvy@pobox.com>
+
+	Trims to support the removal of RESOURCE_INCLUDED from rc scripts from
+	[FRQ 565088].
+
+	* generic/tcl.h: moved the #ifndef RC_INVOKED start block up in the
+	file. rc scripts don't need to know thread mutexes.
+
+	* win/tcl.rc:
+	* win/tclsh.rc: removed the #define RESOURCE_INCLUDED to let the
+	built-in -DRC_INVOKED to the work.
+
+2002-06-17  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* doc/CrtTrace.3:        Added TIP#62 implementation of command
+	* doc/trace.n:           execution tracing [FRQ 462580] (lavana).
+	* generic/tcl.h:         This includes enter/leave tracing as well
+	* generic/tclBasic.c:    as inter-procedure stepping.
+	* generic/tclCmdMZ.c:
+	* generic/tclCompile.c:
+	* generic/tclExecute.c:
+	* generic/tclInt.decls:
+	* generic/tclInt.h:
+	* generic/tclIntDecls.h:
+	* generic/tclStubInit.c:
+	* generic/tclVar.c:
+	* tests/trace.test:
+
+2002-06-17  Andreas Kupries  <andreas_kupries@users.sourceforge.net>
+
+	* win/tclWinPipe.c (BuildCommandLine): Fixed [Bug 554068] ([exec] on
+	windows did not treat { in filenames well.). Bug reported by Vince
+	Darley <vincentdarley@users.sourceforge.net>, patch provided by Vince
+	too.
+
+2002-06-17  Joe English  <jenglish@users.sourceforge.net>
+
+	* generic/tcl.h: #ifdef logic for K&R C backwards compatibility
+	changed to assume modern C by default. See [FRQ 565088] for full
+	details.
+
+2002-06-17  Don Porter  <dgp@users.sourceforge.net>
+
+	* doc/msgcat.n: Corrected en_UK references to en_GB. UK is not a
+	country designation recognized in ISO 3166.
+
+	* library/msgcat/msgcat.tcl:  More Windows Registry locale codes from
+	Bruno Haible.
+
+	* doc/msgcat.n:
+	* library/msgcat/msgcat.tcl:
+	* library/msgcat/pkgIndex.tcl:
+	* tests/msgcat.test:  Revised locale initialization to interpret
+	environment variable locale values according to XPG4, and to recognize
+	the LC_ALL and LC_MESSAGES values over that of LANG. Also added many
+	Windows Registry locale values to those recognized by msgcat. Revised
+	tests and docs. Bumped to version 1.3. Thanks to Bruno Haible for the
+	report and assistance crafting the solution. [Bug 525522, 525525]
+
+2002-06-16  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* generic/tclCompile.c (TclCompileTokens): a better algorithm for the
+	previous bug fix.
+
+2002-06-16  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* generic/tclCompile.c (TclCompileTokens):
+	* tests/compile.test: [Bug 569438] in the processing of dollar
+	variables; report by Georgios Petasis.
+
+2002-06-16  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* generic/tclExecute.c: bug in the consolidation of the INCR_..._STK
+	instructions; the bug could not be exercised as the (faulty)
+	instruction INST_INCR_ARRAY_STK was never compiled-in (related to [Bug
+	569438]).
+
+2002-06-14  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* generic/tclExecute.c (TclExecuteByteCode): runtime peep-hole
+	optimisation of variables (INST_STORE, INST_INCR) and commands
+	(INST_INVOKE); faster check for the existence of a catch.
+	(TclExecuteByteCode): runtime peep-hole optimisation of comparisons.
+	(TclExecuteByteCode): runtime peep-hole optimisation of INST_FOREACH -
+	relies on peculiarities of the code produced by the bytecode compiler.
+
+2002-06-14  David Gravereaux <davygrvy@pobox.com>
+
+	* win/rules.vc: The test for compiler optimizations was in error.
+	Thanks goes to Roy Terry <royterry@earthlink.net> for his assistance
+	with this.
+
+2002-06-14  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* doc/trace.n, tests/trace.test:
+	* generic/tclCmdMZ.c (Tcl_TraceObjCmd,TclTraceCommandObjCmd)
+	(TclTraceVariableObjCmd): Changed references to "trace list" to
+	"trace info" as mandated by TIP#102.
+
+2002-06-13  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* generic/tclExecute.c (TclExecuteByteCode): consolidated code for the
+	conditional branch instructions.
+
+2002-06-13  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* generic/tclExecute.c (TclExecuteByteCode): fixed the previous patch;
+	wouldn't compile with TCL_COMPILE_DEBUG set.
+
+2002-06-13  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* generic/tclExecute.c (TclExecuteByteCode): consolidated the handling
+	of exception returns to INST_INVOKE and INST_EVAL, as well as most of
+	the code for INST_CONTINUE and INST_BREAK, in the new jump target
+	"processExceptionReturn".
+
+2002-06-13  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* generic/tclExecute.c (TclExecuteByteCode): consolidated variable
+	handling opcodes, replaced redundant code with some 'goto'. All
+	store/append/lappend opcodes on the same data type now share the main
+	code; same with incr opcodes.
+	* generic/tclVar.c: added the bit TCL_TRACE_READS to the possible
+	flags to Tcl_SetVar2Ex - it causes read traces to be fired prior to
+	setting the variable. This is used in the core for [lappend].
+
+	***NOTE*** the usage of TCL_TRACE_READS in Tcl_(Obj)?GetVar.* is not
+	documented; there, it causes the call to create the variable if it
+	does not exist. The new usage in Tcl_(Obj)?SetVar.* remains
+	undocumented too ...
+
+2002-06-13  Vince Darley  <vincentdarley@users.sourceforge.net>
+
+	* tests/fCmd.test:
+	* tests/winFile.test:
+	* tests/fileSystem.test:
+	* generic/tclTest.c:
+	* generic/tclCmdAH.c:
+	* generic/tclIOUtil.c:
+	* doc/FileSystem.3:
+	* mac/tclMacFile.c:
+	* unix/tclUnixFile.c:
+	* win/tclWinFile.c: fixed up further so both compiles and actually
+	works with VC++ 5 or 6.
+	* win/tclWinInt.h:
+	* win/tclWin32Dll.c: cleaned up code and vfs tests and added tests for
+	the internal changes of 2002-06-12, to see whether WinTcl on NTFS can
+	coexist peacefully with links in the filesystem. Added new test
+	command 'testfilelink' to enable the newer code to be tested.
+	* tests/fCmd.test: (made certain tests of 'testfilelink' not run on
+	unix).
+
+2002-06-12  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* tclBasic.c (Tcl_DeleteTrace): fixed [Bug 568123] (thanks to Hemang
+	Lavana)
+
+2002-06-12  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* win/tclWinFile.c: corrected the symbolic link handling code to allow
+	it to compile. Added real definition of REPARSE_DATA_BUFFER (found in
+	winnt.h). Most of the added definitions appear to have correct,
+	cross-Win-version equivalents in winnt.h and should be removed, but
+	just making things "work" for now.
+
+2002-06-12  Vince Darley  <vincentdarley@users.sourceforge.net>
+
+	* generic/tclIOUtil.c:
+	* generic/tcl.decls:
+	* generic/tclDecls.h: made code for Tcl_FSNewNativePath agree with man
+	pages.
+
+	* doc/FileSystem.3: clarified the circumstances under which certain
+	functions are called in the presence of symlinks.
+
+	* win/tclWinFile.c:
+	* win/tclWinPort.h:
+	* win/tclWinInt.h:
+	* win/tclWinFCmd.c:  Fix for Windows to allow 'file lstat', 'file
+	type', 'glob -type l', 'file copy', 'file delete', 'file normalize',
+	and all VFS code to work correctly in the presence of symlinks
+	(previously Tcl's behaviour was not very well defined). This also
+	fixes possible serious problems in all versions of WinTcl where 'file
+	delete' on a NTFS symlink could delete the original, not the symlink.
+	Note: symlinks cannot yet be created in pure Tcl.
+
+2002-06-11  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* generic/tclBasic.c:
+	* generic/tclCompCmds.c:
+	* generic/tclInt.h: reverted the new compilation functions; replaced
+	by a more general approach described below.
+
+	* generic/tclCompCmds.c:
+	* generic/tclCompile.c: made *all* compiled variable access attempts
+	create an indexed variable - even get or incr without previous set.
+	This allows indexed access to local variables that are created and set
+	at runtime, for example by [global], [upvar], [variable], [regexp],
+	[regsub].
+
+2002-06-11  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* doc/global.n:
+	* doc/info.n:
+	* test/info.test:
+	* generic/tclCmdIL.c: fix for [Bug 567386], [info locals] was
+	reporting some linked variables.
+
+	* generic/tclBasic.c:
+	* generic/tclCompCmds.c:
+	* generic/tclInt.h: added compile functions for [global], [variable]
+	and [upvar]. They just declare the new local variables, the commands
+	themselves are not compiled-in. This gives a notably faster read
+	access to these linked variables.
+
+2002-06-11  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* generic/tclExecute.c: optimised algorithm for exception range
+	lookup; part of [Patch 453709].
+
+2002-06-10  Vince Darley  <vincentdarley@users.sourceforge.net>
+
+	* unix/tclUnixFCmd.c: fixed [Bug 566669]
+	* generic/tclIOUtil.c: improved and sped up handling of native paths
+	(duplication and conversion to normalized paths), particularly on
+	Windows.
+	* modified part of above commit, due to problems on Linux. Will
+	re-examine bug report and evaluate more closely.
+
+2002-06-07  Don Porter  <dgp@users.sourceforge.net>
+
+	* tests/tcltest.test:  More corrections to test suite so that tests of
+	failing [test]s don't show up themselves as failing tests.
+
+2002-06-07  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* generic/tclExecute.c: Tidied up headers in relation to float.h to
+	cut the cruft and ensure DBL_MAX is defined since doubles seem to be
+	the same size everywhere; if the assumption isn't true, the variant
+	platforms had better have run configure...
+
+	* unix/tclUnixPort.h (EOVERFLOW): Added code to define it if it
+	wasn't previously defined. Also some other general tidying and adding
+	of comments. [Bugs 563122, 564595]
+	* compat/tclErrno.h: Added definition for EOVERFLOW copied from
+	Solaris headers; I've been unable to find any uses of EFTYPE, which
+	was the error code previously occupying the slot, in Tcl, or any
+	definition of it in the Solaris headers.
+
+2002-06-06  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* unix/dltest/Makefile.in: Remove hard coded CFLAGS=-g and add
+	CFLAGS_DEBUG, CFLAGS_OPTIMIZE, and CFLAGS_DEFAULT varaibles. [Bug
+	565488]
+
+2002-06-06  Don Porter  <dgp@users.sourceforge.net>
+
+	* tests/tcltest.test:  Corrections to test suite so that tests of
+	failing [test]s don't show up themselves as failing tests.
+
+	* tests/io.test: Fixed up namespace variable resolution issues
+	revealed by running test suite with "-singleproc 1".
+
+	* doc/tcltest.n:
+	* library/tcltest/tcltest.tcl:
+	* tests/tcltest.test: Several updates to tcltest.
+	  1) changed to lazy initialization of test constraints
+	  2) deprecated [initConstraintsHook]
+	  3) repaired badly broken [limitConstraints].
+	  4) deprecated [threadReap] and [mainThread]
+	[Patch 512214, Bug 558742, Bug 461000, Bug 534903]
+
+2002-06-06  Daniel Steffen  <das@users.sourceforge.net>
+
+	* unix/tclUnixThrd.c (TclpReaddir, TclpLocaltime, TclpGmtime): added
+	mutex wrapped calls to readdir, localtime & gmtime in case their
+	thread-safe *_r counterparts are not available.
+	* unix/tcl.m4: added configure check for readdir_r
+	* unix/tcl.m4 (Darwin): set TCL_DEFAULT_ENCODING to utf-8 on MacOSX
+	(where posix file apis expect utf-8, not iso8859-1).
+	* unix/configure: regen
+	* unix/Makefile.in: set DYLD_LIBRARY_PATH in parallel to
+	LD_LIBRARY_PATH for MacOSX dynamic linker.
+	* generic/tclEnv.c (TclSetEnv): fix env var setting on MacOSX (adapted
+	from [Patch 524352] by jkbonfield).
+
+2002-06-05  Don Porter  <dgp@users.sourceforge.net>
+
+	* doc/Tcl_Main.3: Documented $tcl_rcFileName and added more
+	clarifications about the intended use of Tcl_Main(). [Bug 505651]
+
+2002-06-05  Daniel Steffen  <das@users.sourceforge.net>
+
+	* generic/tclFileName.c (TclGlob): mac specific fix to recent changes
+	in 'glob -tails' handling.
+	* mac/tclMacPort.h:
+	* mac/tclMacChan.c: fixed TIP#91 bustage.
+	* mac/tclMacResource.c (Tcl_MacConvertTextResource): added utf
+	conversion of text resource contents.
+	* tests/macFCmd.test (macFCmd-1.2): allow CWIE creator.
+
+2002-06-04  Don Porter  <dgp@users.sourceforge.net>
+
+	* library/tcltest/tcltest.tcl:
+	* tests/init.test:
+	* tests/tcltest.test:	Added more TIP 85 tests from Arjen Markus.
+	Converted tcltest.test to use a private namespace. Fixed bugs in
+	[tcltest::Eval] revealed by calling [tcltest::test] from a non-global
+	namespace, and namespace errors in init.test.
+
+2002-06-04  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* win/README: Update msys+mingw URL.
+
+2002-06-03  Don Porter  <dgp@users.sourceforge.net>
+
+	* doc/tcltest.n:
+	* library/tcltest/tcltest.tcl:
+	* library/tcltest/pkgIndex.tcl:
+	* tests/tcltest.test:  Implementation of TIP 85. Allows tcltest users
+	to add new legal values of the -match option to [test], associating
+	each with a Tcl command that does the matching of expected results
+	with actual results of tests. Thanks to Arjen Markus. => tcltest 2.1
+	[Patch 521362]
+
+2002-06-03  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* doc/namespace.n: added description of [namepace forget] behaviour
+	for unqualified patterns. [Bug 559268]
+
+2002-06-03  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* generic/tclExecute.c: reverting an accidental modification in the
+	last commit.
+
+2002-06-03  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* doc/Tcl.n: clarify the empty variable name issue ([Bug 549285]
+	reported by Tom Krehbiel, patch by Don Porter).
+
+2002-05-31  Don Porter  <dgp@users.sourceforge.net>
+
+	* library/package.tcl:  Fixed leak of slave interp in [pkg_mkIndex].
+	Thanks to Helmut for report. [Bug 550534]
+
+	* tests/io.test:
+	* tests/main.test:  Use the "stdio" constraint to control whether an
+	[open "|[interpreter]"] is attempted.
+
+	* generic/tclExecute.c (TclMathInProgress,TclExecuteByteCode
+	(ExprCallMathFunc):
+	* generic/tclInt.h (TclMathInProgress):
+	* unix/Makefile.in (tclMtherr.*):
+	* unix/configure.in (NEED_MATHERR):
+	* unix/tclAppInit.c (matherr):
+	* unix/tclMtherr.c (removed file):
+	* win/tclWinMtherr.c (_matherr): Removed internal routine
+	TclMathInProgress and Unix implementation of matherr(). These are now
+	obsolete, dealing with very old versions of the C math library.
+	Windows version is retained in case Borland compilers require it, but
+	it is inactive. Thanks to Joe English. [Bug 474335, Patch 555635]
+
+	* unix/configure: regen
+
+2002-05-30  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* generic/tclCompExpr.c:
+	* generic/tclCompile.c:
+	* generic/tclCompile.h: removed exprIsJustVarRef and
+	exprIsComparison from the ExprInfo and CompileEnv structs. These
+	were set, but not used since dec 1999 [Bug 562383].
+
+2002-05-30  Vince Darley  <vincentdarley@users.sourceforge.net>
+
+	* generic/tclFileName.c (TclGlob): fix to longstanding 'knownBug' in
+	fileName tests 15.2-15.4, and fix to a new Tcl 8.4 bug in certain uses
+	of 'glob -tails'.
+	* tests/fileName.test: removed 'knownBug' flag from some tests, added
+	some new tests for above bugs.
+
+2002-05-29  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* unix/configure: regen'ed
+	* unix/configure.in: replaced bigendian check with autoconf standard
+	AC_C_BIG_ENDIAN, which defined WORDS_BIGENDIAN on bigendian systems.
+	* generic/tclUtf.c (Tcl_UniCharNcmp):
+	* generic/tclInt.h (TclUniCharNcmp): use WORDS_BIGENDIAN instead of
+	TCL_OPTIMIZE_UNICODE_COMPARE to enable memcmp alternative.
+
+	* generic/tclExecute.c (TclExecuteByteCode INST_STR_CMP):
+	* generic/tclCmdMZ.c (Tcl_StringObjCmd): changed the case for choosing
+	the Tcl_UniCharNcmp compare to when both objs are of StringType, as
+	benchmarks show that is the optimal check (both bigendian and
+	littleendian systems).
+
+2002-05-29  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclMain.c: Removed "dummy" reference to Tcl_LinkVar. It is
+	no longer needed since Tcl_Main() now actually calls Tcl_LinkVar().
+	Thanks to Joe English for pointing that out.
+
+2002-05-29  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* generic/tclExecute.c (TclExecuteByteCode):
+	* generic/tclCmdMZ.c (Tcl_StringObjCmd): Use the macro version.
+	* generic/tclInt.h (TclUniCharNcmp): Optimised still further with a
+	macro for use in sensitive places like tclExecute.c
+
+	* generic/tclUtf.c (Tcl_UniCharNcmp): Use new flag to figure out when
+	we can use an optimal comparison scheme, and default to the old scheme
+	in other cases which is at least safe.
+	* unix/configure.in (TCL_OPTIMIZE_UNICODE_COMPARE): New optional flag
+	that indicates when we can use memcmp() to compare Unicode strings
+	(i.e. when the high-byte of a Tcl_UniChar precedes the low-byte.)
+
+2002-05-29  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* generic/tclInt.decls:
+	* generic/tclIntDecls.h:
+	* generic/tclStubInit.c:
+	* generic/tclUtf.c: added TclpUtfNcmp2 private command that
+	mirrors Tcl_UtfNcmp, but takes n in bytes, not utf-8 chars. This
+	provides a faster alternative for comparing utf strings	internally.
+	(Tcl_UniCharNcmp, Tcl_UniCharNcasecmp): removed the explicit end of
+	string check as it wasn't correct for the function (by doc and logic).
+
+	* generic/tclCmdMZ.c (Tcl_StringObjCmd): reworked the string equal
+	comparison code to use TclpUtfNcmp2 as well as short-circuit for
+	equal objects or unequal length strings in the equal case.
+	Removed the use of goto and streamlined the other parts.
+
+	* generic/tclExecute.c (TclExecuteByteCode): added check for object
+	equality in the comparison instructions. Added short-circuit for !=
+	length strings in INST_EQ, INST_NEQ and INST_STR_CMP. Reworked
+	INST_STR_CMP to use TclpUtfNcmp2 where appropriate, and only use
+	Tcl_UniCharNcmp when at least one of the objects is a Unicode obj with
+	no utf bytes.
+
+	* generic/tclCompCmds.c (TclCompileStringCmd): removed error creation
+	in code that no longer throws an error.
+
+	* tests/string.test:
+	* tests/stringComp.test: added more string comparison checks.
+
+	* tests/clock.test: better qualified 9.1 constraint check for %s.
+
+2002-05-28  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* generic/tclThreadAlloc.c (TclpRealloc, TclpFree): protect
+	against the case when NULL is based.
+
+	* tests/clock.test: added clock-9.1
+	* compat/strftime.c:
+	* generic/tclClock.c:
+	* generic/tclInt.decls:
+	* generic/tclIntDecls.h:
+	* unix/tclUnixTime.c: fix for Windows msvcrt mem leak caused by using
+	an env(TZ) setting trick for in clock format -gmt 1. This also makes
+	%s seem to work correctly with -gmt 1 as well as making it a lot
+	faster by avoid the env(TZ) hack. TclpStrftime now takes useGMT as an
+	arg. [Bug 559376]
+
+2002-05-28  Vince Darley  <vincentdarley@users.sourceforge.net>
+
+	* generic/tclIOUtil.c: fixes to Tcl_FSLoadFile when called on a file
+	inside a vfs. This should avoid leaving temporary files sitting
+	around on exit. [Bug 545579]
+
+2002-05-27  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* win/tclWinError.c: Added comment on conversion of
+	ERROR_NEGATIVE_SEEK because that is a mapping that really belongs,
+	and not a catch-all case.
+	* win/tclWinPort.h (EOVERFLOW): Should be either EFBIG or EINVAL
+	* generic/tclPosixStr.c (Tcl_ErrnoId, Tcl_ErrnoMsg): EOVERFLOW can
+	potentially be a synonym for EINVAL.
+
+2002-05-24  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	=== Changes due to TIP#91 ===
+
+	* win/tclWinPort.h: Added declaration of EOVERFLOW.
+	* doc/CrtChannel.3: Added documentation of wideSeekProc.
+	* generic/tclIOGT.c (TransformSeekProc, TransformWideSeekProc):
+	Adapted to use the new channel mechanism.
+	* unix/tclUnixChan.c (FileSeekProc, FileWideSeekProc): Renamed
+	FileSeekProc to FileWideSeekProc and created new FileSeekProc which
+	has the old-style interface and which errors out with EOVERFLOW when
+	the returned file position can't fit into the return type (int for
+	historical reasons).
+	* win/tclWinChan.c (FileSeekProc, FileWideSeekProc): Renamed
+	FileSeekProc to FileWideSeekProc and created new FileSeekProc which
+	has the old-style interface and which errors out with EOVERFLOW when
+	the returned file position can't fit into the return type (int for
+	historical reasons).
+	* mac/tclMacChan.c (FileSeek): Reverted to old interface; Macs lack
+	large-file support because I can't see how to add it.
+	* generic/tclIO.c (Tcl_Seek, Tcl_Tell): Given these functions
+	knowledge of the new arrangement of channel types.
+	(Tcl_ChannelVersion): Added recognition of new version code.
+	(HaveVersion): New function to do version checking.
+	(Tcl_ChannelBlockModeProc, Tcl_ChannelFlushProc)
+	(Tcl_ChannelHandlerProc): Made these functions use HaveVersion for
+	ease of future maintainability.
+	(Tcl_ChannelBlockModeProc): Obvious lookup function.
+	* generic/tcl.h (Tcl_ChannelType): New wideSeekProc field, and
+	seekProc type restored to old interpretation.
+	(TCL_CHANNEL_VERSION_3): New channel version.
+
+2002-05-24  Andreas Kupries  <andreas_kupries@users.sourceforge.net>
+
+	* tests/winPipe.test: Applied patch for [Bug 549617]. Patch and bug
+	report by Kevin Kenny <kennykb@users.sourceforge.net>.
+
+	* win/tclWinSock.c (TcpWatchProc): Fixed [Bug 557878]. We are not
+	allowed to mess with the watch mask if the socket is a server socket.
+	I believe that the original reporter is George Peter Staplin.
+
+2002-05-21  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* unix/configure: Regen.
+	* unix/configure.in: Invoke SC_ENABLE_SHARED before calling
+	SC_CONFIG_CFLAGS so that the SHARED_BUILD variable can be checked
+	inside SC_CONFIG_CFLAGS.
+	* unix/tcl.m4 (SC_CONFIG_CFLAGS): Pass -non_shared instead of -shared
+	to ld when configured with --disable-shared under OSF. [Bug 540390]
+
+2002-05-20  Daniel Steffen  <das@users.sourceforge.net>
+
+	* generic/tclInt.h: added prototype for TclpFilesystemPathType().
+	* mac/tclMacChan.c: use MSL provided creator type if available instead
+	of the default 'MPW '.
+
+2002-05-16  Joe English  <jenglish@users.sf.net>
+
+	* doc/CrtObjCmd.3: Added Tcl_GetCommandFromObj, Tcl_GetCommandFullName
+	[Bugs 547987, 414921]
+
+2002-05-14  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* unix/tclUnixChan.c (TtyOutputProc): #if/#endif-ed this function out
+	to stop compiler warnings. Also much general tidying of comments in
+	this file and removal of whitespace from blank lines.
+
+2002-05-13  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* unix/tclUnixChan.c (SETBREAK): Solaris thinks ioctl() takes a signed
+	second argument, and Linux thinks ioctl() takes an unsigned second
+	argument. So need a longer definition of this macro to get neither to
+	spew warnings...
+
+2002-05-13  Vince Darley  <vincentdarley@users.sourceforge.net>
+
+	* generic/tclEvent.c:
+	* generic/tclIOUtil.c:
+	* generic/tclInt.h: clean up all memory allocated by the filesystem,
+	via introduction of 'TclFinalizeFilesystem'.
+	Move TclFinalizeLoad into TclFinalizeFilesystem so we can be sure it
+	is called at just the right time.
+	Fix bad comment also. [Bug 555078 and 'fs' part of 543549]
+	* win/tclWinChan.c: fix comment referring to wrong function.
+
+2002-05-10  Don Porter  <dgp@users.sourceforge.net>
+
+	* tests/load.test:
+	* tests/safe.test:
+	* tests/tcltest.test: Corrected some list-quoting issues and other
+	matters that cause tests to fail when the patch includes special
+	characters. Report from Vince Darley. [Bug 554068]
+
+2002-05-08    David Gravereaux <davygrvy@pobox.com>
+
+	* doc/file.n:
+	* tools/man2tcl.c:
+	* tools/man2help2.tcl:  Thanks to Peter Spjuth
+	<peter.spjuth@space.se>, again. My prior fix for single-quote macro
+	mis-understanding was wrong. Reverted to reimpliment the 'macro2' proc
+	which handles single-quote macros and restored file.n text arrangement
+	to avoid single-quotes on the first line. Sorry for all the confusion.
+
+2002-05-08  David Gravereaux <davygrvy@pobox.com>
+
+	* tools/man2tcl.c:
+	* tools/man2help2.tcl: Proper source of macro error misunderstanding
+	single-quote as the leading macro command found and repaired.
+
+	* doc/file.n: Reverted to prior state before I messed with it.
+
+2002-05-08  Don Porter  <dgp@users.sourceforge.net>
+
+	* library/tcltest/tcltest.tcl: Corrected [uplevel] quoting when
+	[source]-ing test script in subdirectories.
+	* tests/fileName.test:
+	* tests/load.test:
+	* tests/main.test:
+	* tests/tcltest.test:
+	* tests/unixInit.test: Fixes to test suite when there's a space in the
+	working path. Thanks to Kevin Kenny.
+
+2002-05-07  David Gravereaux <davygrvy@pobox.com>
+
+	-- Changes from Peter Spjuth <peter.spjuth@space.se>
+	* tools/man2tcl.c: Increased line buffer size and a bail-out if that
+	should ever be over-run.
+	* tools/man2help.tcl: Include Courier New font in rtf header.
+	* tools/man2help2.tcl: Improved handling of CS/CE fields. Use Courier
+	New for code samples and indent better.
+
+	* doc/file.n:
+	* doc/TraceCmd.3:  winhelp conversion tools where understanding
+	a ' as the first character on a line to be an unknown macro.
+	Not knowing how to repair tools/man2tcl.c, I decided to rearrange
+	the text in the docs instead.
+
+2002-05-07  Vince Darley  <vincentdarley@users.sourceforge.net>
+
+	* generic/tclFileName.c: fix to similar segfault when using 'glob
+	-types nonsense -dir dirname -join * *'. [Bug 553320]
+
+	* doc/FileSystem.3: further documentation on vfs.
+	* tests/cmdAH.test:
+	* tests/fileSystem.test:
+	* tests/pkgMkindex.test: Fix to testsuite bugs when running out of
+	directory whose name contains '{' or '['.
+
+2002-05-07  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* tests/basic.test: Fix for [Bug 549607]
+	* tests/encoding.test: Fix for [Bug 549610]
+	These are testsuite bugs that caused failures when the filename
+	contained spaces. Report & fix by Kevin Kenny.
+
+2002-05-02  Vince Darley  <vincentdarley@users.sourceforge.net>
+
+	* generic/tclFileName.c: fix to freeing a bad object (i.e. segfault)
+	when using 'glob -types nonsense -dir dirname'.
+	* generic/tclWinFile.c: fix to [Bug 551306], also wrapped some long
+	lines.
+	* tests/fileName.test: added several tests for the above bugs.
+	* doc/FileSystem.3: clarified documentation on refCount requirements
+	of the object returned by the path type function.
+	* generic/tclIOUtil.c:
+	* win/tclWinFile.c:
+	* unix/tclUnixFile.c:
+	* mac/tclMacFile.c: moved TclpFilesystemPathType to the platform-
+	specific directories, so we can add missing platform-specific
+	implementations. On Windows, 'file system' now returns useful results
+	like "native NTFS", "native FAT" for that system. Unix and MacOS still
+	only return "native".
+	* doc/file.n: clarified documentation.
+	* tests/winFile.test: test for 'file system' returning correct values.
+	* tests/fileSystem.test: test for 'file system' returning correct
+	values. Clean up after failed previous test run.
+
+2002-04-26  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* unix/configure:
+	* unix/tcl.m4: change HP-11 SHLIB_LD_LIBS from "" to ${LIBS} so that
+	the .sl knows its dependent libs.
+
+2002-04-26  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* tests/obj.test (obj-11.[56]): Test conversion to boolean more
+	thoroughly.
+	* generic/tclObj.c (SetBooleanFromAny): Was not calling an integer
+	parsing function on native 64-bit platforms! [Bug 548686]
+
+2002-04-24  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* generic/tclInt.h: corrected TclRememberJoinableThread decl to use
+	VOID instead of void.
+	* generic/tclThreadJoin.c: noted that this code isn't needed on Unix.
+
+2002-04-23  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* doc/exec.n:
+	* doc/tclvars.n: doc updates [Patch 509426] (gravereaux)
+
+2002-04-24  Daniel Steffen  <das@users.sourceforge.net>
+
+	* mac/tclMacResource.r: added check of TCLTK_NO_LIBRARY_TEXT_RESOURCES
+	#define to allow disabling the inclusion of the tcl library code in
+	the resource fork of Tcl executables and shared libraries.
+
+2002-04-23  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* doc/TraceCmd.3: New file that documents Tcl_CommandTraceInfo,
+	Tcl_TraceCommand and Tcl_UntraceCommand [Bug 414927]
+
+2002-04-22  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* generic/tclAlloc.c:
+	* generic/tclInt.h:
+	* generic/tclThreadAlloc.c (new):
+	* unix/Makefile.in:
+	* unix/tclUnixThrd.c:
+	* win/Makefile.in:
+	* win/tclWinInt.h:
+	* win/tclWinThrd.c: added new threaded allocator contributed by AOL
+	that significantly reduces lock contention when multiple threads are
+	in use. Only Windows and Unix implementations are ready, and the
+	Windows one may need work. It is only used by default on Unix for now,
+	and requires that USE_THREAD_ALLOC be defined (--enable-threads on
+	Unix will define this).
+
+	* generic/tclIOUtil.c (Tcl_FSRegister, Tcl_FSUnregister): corrected
+	calling of Tcl_ConditionWait to ensure that there would be a condition
+	to wait upon.
+
+	* generic/tclCmdAH.c (Tcl_FileObjCmd): added cast in FILE_SIZE.
+
+	* win/tclWinFCmd.c (DoDeleteFile): check return of setattr API calls
+	in file deletion for correct Win32 API handling.
+
+	* win/Makefile.in: correct dependencies for shell, gdb, runtest
+	targets.
+
+	* doc/clock.n:
+	* compat/strftime.c (_fmt): change strftime to correctly handle
+	localized %c, %x and %X on Windows. Added some notes about how the
+	other values could be further localized.
+
+2002-04-19  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclMain.c (Tcl_Main):  Free the memory allocated for the
+	startup script path. [Bug 543549]
+
+	* library/msgcat/msgcat.tcl:  [mcmax] wasn't using the caller's
+	namespace when determining the max translated length. Also made
+	revisions for better use of namespace variables and more efficient
+	[uplevel]s.
+
+	* doc/msgcat.n:
+	* library/msgcat/msgcat.tcl:
+	* library/msgcat/pkgIndex.tcl:  Added [mcload] to the export list of
+	msgcat; bumped to 1.2.3. [Bug 544727]
+
+2002-04-20  Daniel Steffen  <das@users.sourceforge.net>
+
+	* generic/tclInt.decls:
+	* generic/tclIntPlatDecls.h:
+	* generic/tclStubInit.c:
+	* mac/tclMacFCmd.c:
+	* mac/tclMacFile.c:
+	* mac/tclMacUtil.c: Modified TclpObjNormalizePath to be alias file
+	aware, and replaced various calls to FSpLocationFrom*Path by calls to
+	new alias file aware versions FSpLLocationFrom*Path. The alias file
+	aware routines don't resolve the last component of a path if it is an
+	alias. This allows [file copy/delete] etc. to act correctly on alias
+	files. (c.f. discussion in [Bug 511666])
+
+2002-04-19  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* tests/lindex.test (lindex-3.7):
+	* generic/tclUtil.c (TclGetIntForIndex): Stopped indexes from hitting
+	wide ints. [Bug 526717]
+
+2002-04-18  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* generic/tclNamesp.c:
+	* tests/info.test: [Bug 545325] info level didn't report namespace
+	eval, bug report by Richard Suchenwirth.
+
+2002-04-18  Don Porter  <dgp@users.sourceforge.net>
+
+	* doc/subst.n:  Clarified documentation on handling unusual return
+	codes during substitution, and on variable substitutions implied by
+	command substitution, and vice versa. [Bug 536838]
+
+2002-04-18  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* generic/tclCmdIL.c (InfoBodyCmd):
+	* tests/info.test (info-2.6): Proc bodies without string reps would
+	report as empty. [Bug 545644]
+
+	* generic/tclCmdMZ.c (Tcl_SubstObj): More clarification for comment on
+	behaviour when substitutions are not well-formed, prompted by [Bug
+	536831]; alas, removing the ill-defined behaviour is a lot of work.
+
+2002-04-18  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* generic/tclExecute.c:
+	* tests/expr-old.test: fix for [Bug 542588] (Phil Ehrens), where "too
+	large integers" were reported as "floating-point value" in [expr]
+	error messages.
+
+2002-04-17  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* generic/tclEncoding.c (EscapeFromUtfProc):
+	* generic/tclIO.c (WriteChars, Tcl_Close): corrected the handling of
+	outputting end escapes for escape-based encodings.
+	[Bug 526524] (yamamoto)
+
+2002-04-17  Don Porter  <dgp@users.sourceforge.net>
+
+	* doc/tcltest.n:  Removed [saveState] and [restoreState] from tcltest
+	2 documentation, effectively deprecating them. [Bug 495660]
+	* library/tcltest/tcltest.tcl: Made separate export for commands kept
+	only for tcltest 1 compatibility.
+
+	* tests/iogt.test: Revised to run tests in a namespace, rather than
+	use the useless and buggy [saveState] and [restoreState] commands of
+	tcltest. Updated to use tcltest 2 as well. [Patch 544911]
+
+2002-04-16  Don Porter  <dgp@users.sourceforge.net>
+
+	* tests/io.test: Revised to run tests in a namespace, rather than use
+	the useless and buggy [saveState] and [restoreState] commands of
+	tcltest. Updated to use tcltest 2 as well. [Patch 544546]
+
+2002-04-15  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* generic/tclProc.c:
+	* tests/proc-old.test: Improved stack trace for TCL_BREAK and
+	TCL_CONTINUE returns from procs. Patch by Don Porter [Bug 536955].
+
+	* generic/tclExecute.c:
+	* tests/compile.test: made bytecodes check for a catch before
+	returning; the compiled [return] is otherwise non-catchable. [Bug
+	542142] reported by Andreas Kupries.
+
+2002-04-15  Don Porter  <dgp@users.sourceforge.net>
+
+	* tests/socket.test:  Increased timeout values so that tests have
+	time to successfully complete even on slow/busy machines. [Bug 523470]
+
+	* doc/tcltest.n:
+	* library/tcltest/tcltest.tcl:
+	* tests/tcltest.test:  Revised [tcltest::test] to return errors when
+	called with invalid syntax and to accept exactly two arguments as
+	documented. Improved error messages. [Bug 497446, Patch 513983]
+	***POTENTIAL INCOMPATIBILITY***: Incompatible with previous tcltest
+	2.* releases, found only in alpha releases of Tcl 8.4.
+
+2002-04-11  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* generic/tclNotify.c (TclFinalizeNotifier): remove remaining
+	unserviced events on finalization.
+
+	* win/tcl.m4: Enabled COFF as well as CV style debug info with
+	--enable-symbols to allow Dr. Watson users to see function info. More
+	info on debugging levels can be obtained at:
+	http://msdn.microsoft.com/library/en-us/dnvc60/html/gendepdebug.asp
+
+	* tests/ioCmd.test: fixed iocmd-8.15 to have mac and unixPc variants.
+
+	* generic/tclParse.c (Tcl_ParseVar): conditionally incr obj refcount
+	to prevent possible mem leak.
+
+2002-04-08  Daniel Steffen  <das@users.sourceforge.net>
+
+	* generic/tcl.h: no <sys/types.h> on mac.
+	* mac/tclMacFile.c: minor fixes to Vince's changes from 03-24.
+	* mac/tclMacOSA.c:
+	* mac/tclMacResource.c: added missing Tcl_UtfToExternalDString
+	conversions of resource file names.
+	* mac/tclMacSock.c (TcpGetOptionProc): fixed bug introduced by Andreas
+	on 02-25; changed strcmp's to strncmp's so that option comparison
+	behaves like on other platforms.
+	* mac/tcltkMacBuildSupport.sea.hqx (CW Pro6 changes): added support to
+	allow Tk to hookup C library stderr/stdout to TkConsole.
+	* tests/basic.test:
+	* tests/cmdAH.test:
+	* tests/encoding.test:
+	* tests/fileSystem.test:
+	* tests/ioCmd.test: fixed tests failing on mac: check for existence of
+	[exec], changed some result strings.
+
+2002-04-06  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* unix/tclUnixFCmd.c (Realpath): added a little extra code to
+	initialize a realpath arg when compiling in PURIFY mode in order to
+	prevent spurious purify warnings. We should really create our own
+	realpath implementation, but this will at least quiet purify for now.
+
+2002-04-05  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclCmdMZ.c (Tcl_SubstObj):
+	* tests/subst.test:  Corrected [subst] so that return codes TCL_BREAK
+	and TCL_CONTINUE returned by variable substitution have the same
+	effect as when those codes are returned by command substitution. [Bug
+	536879]
+
+2002-04-03  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* library/tcltest/tcltest.tcl: added getMatchingFiles back (alias to
+	GetMatchingFiles), which was a public function in tcltest 1.0.
+
+2002-04-01  Vince Darley  <vincentdarley@users.sourceforge.net>
+
+	* generic/tclEnv.c:
+	* generic/tclIOUtil.c: invalidate filesystem cache when the user
+	changes env(HOME). Fixes [Bug 535621]. Also cleaned up some of the
+	documentation.
+	* tests/fileSystem.test: added test for bug just fixed.
+
+2002-04-01  Kevin Kenny  <kennykb@acm.org>
+
+	* win/tclWinTime.c (Tcl_GetTime): made the checks of clock frequency
+	more permissive to cope with the fact that Win98SE is observed to
+	return 1.19318 in place of 1.193182 for the performance counter
+	frequency.
+
+2002-03-29  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* generic/tclCmdMZ.c (Tcl_TraceObjCmd, TraceVarProc)
+	(TraceCommandProc, TclTraceCommandObjCmd):  corrected potential
+	double-free of traces on variables by flagging in Trace*Proc that it
+	will free the var in case the eval wants to delete the var trace as
+	well. [Bug 536937] Also converted Tcl_UntraceVar -> Tcl_UntraceVar2
+	and Tcl_Eval to Tcl_EvalEx in Trace*Proc for slight efficiency
+	improvement.
+
+2002-03-29  Don Porter  <dgp@users.sourceforge.net>
+
+	* doc/AllowExc.3:
+	* generic/tclBasic.c (Tcl_EvalObjv,Tcl_EvalEx,Tcl_EvalObjEx):
+	* generic/tclCompile.h (TclCompEvalObj):
+	* generic/tclExecute.c (TclCompEvalObj,TclExecuteByteCode):
+	* tests/basic.test: Corrected problems with Tcl_AllowExceptions having
+	influence over the wrong scope of Tcl_*Eval* calls. Patch from Miguel
+	Sofer. Report from Jean-Claude Wippler. [Bug 219181]
+
+2002-03-28  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclVar.c: Refactored CallTraces to collect repeated handling
+	of its returned value into CallTraces itself.
+
+2002-03-28  David Gravereaux <davygrvy@pobox.com>
+
+	* tools/feather.bmp:
+	* tools/man2help.tcl:
+	* tools/man2help2.tcl:
+	* win/makefile.vc: More winhelp target fixups. Added a feather bitmap
+	to the non-scrollable area and changed the color to be yellow from a
+	plain white. The colors can be whatever we want them to be, but
+	thought I would start with something bold. [Bug 527941]
+
+	* doc/SetVar.3:
+	* doc/TraceVar.3:
+	* doc/UpVar.3:  .AP macro syntax repair.
+
+2002-03-27  David Gravereaux <davygrvy@pobox.com>
+
+	* tools/man2help.tcl:
+	* win/makefile.vc:  winhelp target now copies all needed files from
+	tools/ to a workarea under $(OUT_DIR) and builds it from there. No
+	build cruft is left in tools/ anymore. All paths used in man2help.tcl
+	are now relative to where the script is. [Bug 527941]
+
+2002-03-27  David Gravereaux <davygrvy@pobox.com>
+
+	* win/.cvsignore:
+	* win/buildall.vc.bat:
+	* win/coffbase.txt:
+	* win/makefile.vc:
+	* win/nmakehlp.c (new):
+	* win/rules.vc:  First draft fix for [Bug 527941]. More changes need
+	to done to the makehelp target to get to stop leaving build files in
+	the tools/ directory. This does not address the syntax errors in the
+	man files. Having the contents of tcl.hpj(.in) inside makefile.vc
+	allows for version numbers to be replaced with macros.
+
+	The new nmakehlp.c is built by rules.vc in preprocessing and removes
+	the need to use tricky shell syntax that wasn't compatible on Win9x
+	systems. Clean targets made Win9x complient. This is a first draft
+	repair for [Bug 533862].
+
+2002-03-28  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* generic/tclBasic.c (Tcl_EvalEx): passing the correct commandSize to
+	TclEvalObjvInternal. [Bug 219362], fix by David Knoll.
+
+2002-03-28  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* generic/tclBasic.c (Tcl_EvalEx):
+	* tests/basic.test: avoid exceptional returns at level 0. [Bug 219181]
+
+2002-03-27  Don Porter  <dgp@users.sourceforge.net>
+
+	* doc/tcltest.n ([mainThread]):
+	* library/tcltest/tcltest.tcl:
+	* tests/tcltest.test:  Major code cleanup to deal with whitespace,
+	coding conventions, and namespace issues, with several minor bugs
+	fixed in the process.
+
+	* tests/main.test: Added missing [after cancel]s.
+
+2002-03-25  Don Porter  <dgp@users.sourceforge.net>
+
+	* tests/main.test: Removed workarounds for Bug 495977.
+
+	* library/tcltest/tcltest.tcl:  Keep the value of $::auto_path
+	unchanged, so that the tcltest package can test code that depends on
+	auto-loading. If a testing application needs $::auto_path pruned, it
+	should do that itself. [Bug 495726]
+	Improve the processing of the -constraints option to [test] so that
+	constraint lists can have arbitrary whitespace, and non-lists don't
+	blow things up. [Bug 495977]
+	Corrected faulty variable initialization. [Bug 534845]
+
+2002-03-25  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* doc/CrtTrace.3: small doc correction
+	* generic/tclBasic.c (Tcl_DeleteTrace): Allow NULL callback on trace
+	deletions. [Bug 534728] (Hemang Lavana)
+
+2002-03-24  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* generic/tclBasic.c (Tcl_EvalObjv): replaced obscure, incorrect code
+	as described in [Bug 533907] (Don Porter).
+
+2002-03-24  Don Porter  <dgp@users.sourceforge.net>
+
+	* library/tcltest/tcltest.tcl:  Use [interpreter] to set/query the
+	executable currently running the tcltest package. [Bug 454050]
+
+	* library/tcltest/tcltest.tcl:  Allow non-proc commands to be used as
+	the customization hooks. [Bug 495662]
+
+2002-03-24  Vince Darley  <vincentdarley@users.sourceforge.net>
+
+	* generic/tclFilename.c:
+	* generic/tclFCmd.c:
+	* generic/tclTest.c:
+	* generic/tcl.h:
+	* generic/tclIOUtil.c:
+	* win/tclWinFile.c:
+	* win/tclWinFCmd.c:
+	* win/tclWinPipe.c:
+	* unix/tclUnixFile.c:
+	* unix/tclUnixFCmd.c:
+	* mac/tclMacFile.c:
+	* doc/FileSystem.3:
+	* doc/file.n:
+	* tests/cmdAH.test:
+	* tests/fileName.test:
+	* tests/fileSystem.test: (new file)
+	* tests/winFCmd.test: fix [Bug 511666] and [Bug 511658], and improved
+	documentation of some aspects of the filesystem, particularly
+	'Tcl_FSMatchInDirectory' which now might match a single file/directory
+	only, and 'file normalize' which wasn't very clear before. Removed
+	inconsistency betweens docs and the Tcl_Filesystem structure. Also
+	fixed [Bug 523217] and corrected file normalization on Unix so that
+	it expands symbolic links. Added some new tests of the filesystem
+	code (in the new file 'fileSystem.test'), and some extra tests for
+	correct handling of symbolic links. Fix to [Bug 530960] which shows up
+	on Win98. Made comparison with ".com" case insensitive in tclWinPipe.c
+
+	***POTENTIAL INCOMPATIBILITY***: But only between alpha releases
+	(users of the new Tcl_Filesystem lookup table in Tcl 8.4a4 need to
+	handle the new way in which Tcl may call Tcl_FSMatchInDirectory, and
+	'file normalize' on unix now behaves correctly). Only known impact is
+	with the 'tclvfs' extension.
+
+2002-03-22  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* tests/basic.test (basic-46.1): adding test for [Bug 533758], fixed
+	earlier today.
+
+2002-03-22  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* win/tclWinInt.h: moved undef of TCL_STORAGE_CLASS. [Bug 478579]
+
+2002-03-22  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* generic/tclBasic.c (Tcl_EvalObjEx):
+	* generic/tclExecute.c (TclCompEvalObj): fixed the errorInfo for
+	return codes other than (TCL_OK, TCL_ERROR) to runLevel 0.[Bug 533758]
+	Removed the static RecordTracebackInfo(), as its functionality is
+	easily replicated by Tcl_LogCommandInfo. Bug and redundancy noted by
+	Don Porter.
+
+2002-03-21  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* doc/expr.n: Improved documentation for ceil and floor. [Bug 530535]
+
+2002-03-20  Don Porter  <dgp@users.sourceforge.net>
+
+	* doc/SetVar.3:
+	* doc/TraceVar.3:
+	* doc/UpVar.3:
+	* generic/tcl.h (Tcl_VarTraceProc):
+	* generic/tcl.decls (Tcl_GetVar2, Tcl_SetVar2, Tcl_TraceVar2,
+	(Tcl_UnsetVar2, Tcl_UntraceVar2, Tcl_UpVar2, Tcl_VarTraceInfo2,
+	(Tcl_GetVar2Ex, TclSetVar2Ex):
+	* generic/tclCmdMZ.c (TraceVarProc):
+	* generic/tclEnv.c (EnvTraceProc):
+	* generic/tclEvent.c (VwaitVarProc):
+	* generic/tclInt.decls (TclLookupVar,TclPrecTraceProc):
+	* generic/tclLink.c (LinkTraceProc):
+	* generic/tclUtil.c (TclPrecTraceProc):
+	* generic/tclVar.c (CallTraces, MakeUpvar, VarErrMsg, TclLookupVar,
+	(Tcl_GetVar2, Tcl_SetVar2, Tcl_TraceVar2, Tcl_UnsetVar2,
+	(Tcl_UntraceVar2, Tcl_UpVar2, Tcl_VarTraceInfo2, Tcl_GetVar2Ex,
+	(TclSetVar2Ex): Updated interfaces of generic/tclVar.c according to
+	TIP 27. In particular, the "part2" arguments were CONSTified. [Patch
+	532642]
+	* generic/tclDecls.h:
+	* generic/tclIntDecls.h: make genstubs
+
+2002-03-15  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* tests/compile.test (compile-12.3): Test to detect bug 530320.
+	* generic/tclCompile.c (TclCompileTokens): Fixed buffer overrun
+	reported in bug 530320.
+
+2002-03-14  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* win/configure: Regen.
+	* win/configure.in: Add configure time test for SEH support in the
+	compiler.
+	* win/tclWin32Dll.c (ESP, EBP, TclpCheckStackSpace,
+	(_except_checkstackspace_handler):
+	* win/tclWinChan.c (ESP, EBP, Tcl_MakeFileChannel,
+	(_except_makefilechannel_handler):
+	* win/tclWinFCmd.c (ESP, EBP, DoRenameFile, DoCopyFile,
+	(_except_dorenamefile_handler, _except_docopyfile_handler):
+	Implement SEH support under gcc using inline asm. Tcl and Tk should
+	now compile with Mingw 1.1. [Patch 525746]
+
+2002-03-14  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* win/tclWinFCmd.c (DoRenameFile, DoCopyFile): Handle an SEH exception
+	with EXCEPTION_EXECUTE_HANDLER instead of restarting the faulting
+	instruction with EXCEPTION_CONTINUE_EXECUTION. [Bug 466102] provides
+	an example of how restarting could send Tcl into an infinite loop.
+	[Patch 525746]
+
+2002-03-11  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* win/tclWinFCmd.c (DoRenameFile, DoCopyFile, DoDeleteFile,
+	(DoRemoveJustDirectory): Make sure we don't pass NULL or "" as a path
+	name to Win32 API functions since this was crashing under Windows 98.
+
+2002-03-11  Don Porter  <dgp@users.sourceforge.net>
+
+	* library/tcltest/tcltest.tcl:
+	* library/tcltest/pkgIndex.tcl: Bumped tcltest package to 2.0.2.
+
+2002-03-11  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* library/tcltest/tcltest.tcl (getMatchingFiles): Pass a proper list
+	to foreach to avoid munging a Windows patch like D:\Foo\Bar into
+	D:FooBar before the glob.
+
+2002-03-11  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* generic/tclEncoding.c: Fix typo in comment.
+	* generic/tclIO.c (DoReadChars, ReadBytes, ReadChars): Use NULL value
+	instead of pointer set to NULL to make things more clear. Reorder
+	arguments so that they match the function signatures. Cleanup little
+	typos and add more descriptive comment.
+
+2002-03-08  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* win/README: Update to indicate that Mingw 1.1 is required to build
+	Tcl. Add section describing new msys based build process. Update
+	Cygwin build instructions so users know where to find Mingw 1.1.
+
+2002-03-08  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* win/tclWinFCmd.c (DoCopyFile): correctly set retval to TCL_OK.
+
+2002-03-07  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* win/tclWin32Dll.c (TclpCheckStackSpace):
+	* win/tclWinFCmd.c (DoRenameFile, DoCopyFile): Replace hard coded
+	constants with Win32 symbolic names. Move control flow statements out
+	of __try blocks since the documentation indicates it is frowned upon.
+
+2002-03-07  Don Porter  <dgp@users.sourceforge.net>
+
+	* doc/interp.n:
+	* generic/tclInterp.c (Tcl_InterpObjCmd, SlaveObjCmd,
+	(SlaveRecursionLimit):
+	* generic/tclTest.c:
+	* tests/interp.test: Added the [interp recursionlimit] command to
+	set/query the recursion limit of an interpreter. Proposal and
+	implementation from Stephen Trier. [TIP 87, Patch 522849]
+
+2002-03-06  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* generic/tcl.h, tools/tcl.wse.in, unix/configure.in,
+	* unix/tcl.spec, win/README.binary, win/configure.in, README:
+	Bumped patchlevel; this might need to change in the future, but it
+	will help us distinguish between the CVS version and the most recent
+	released version.
+
+2002-03-06  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* generic/tclInt.h: for unshared objects, TclDecrRefCount now frees
+	the internal rep before the string rep - just like the non-macro
+	Tcl_DecrRefCount/TclFreeObj. [Bug 524802]
+
+2002-03-06  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* doc/lsearch.n: Documentation of new features, plus examples.
+	* tests/lsearch.test: Tests of new features.
+	* generic/tclCmdIL.c (Tcl_LsearchObjCmd): TIP#80 support. See
+	http://purl.org/tcl/tip/80 for details.
+
+2002-03-05  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	*** 8.4a4 TAGGED FOR RELEASE ***
+
+	* unix/tclUnixChan.c: initial remedy for [Bug 525783] flush problem
+	introduced by TIP #35. This may not satisfy true serial channels, but
+	it restores the correct flushing of std* channels on exit.
+
+	* unix/README: added --enable-langinfo doc.
+
+	* unix/tcl.spec:
+	* tools/tcl.wse.in: fixed URL refs to use www.tcl.tk or SF.
+
+2002-03-04  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* README:
+	* mac/README:
+	* unix/Makefile.in:
+	* unix/README:
+	* win/README:
+	* win/README.binary: updated to use www.tcl.tk URL.
+
+	* unix/Makefile.in: added older ChangeLogs to dist target.
+
+	* tests/io.test:
+	* tests/encoding.test: corrected iso2022 encoding results.
+	added encoding-24.*
+	* generic/tclEncoding.c (EscapeFromUtfProc): corrected output of
+	escape codes as per RFC 1468. [Patch 474358] (taguchi)
+	(TclFinalizeEncodingSubsystem): corrected potential double-free
+	when encodings were finalized on exit. [Bugs 219314, 524674]
+
+2002-03-01  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* library/encoding/iso2022-jp.enc:
+	* library/encoding/iso2022.enc:
+	* tools/encoding/iso2022-jp.esc:
+	* tools/encoding/iso2022.esc: gave <ESC>$B precedence over <ESC>$@,
+	based on comments (point 1) in [Bug 219283] (rfc 1468)
+
+	* tests/encoding.test: added encoding-23.* tests
+	* generic/tclIO.c (FilterInputBytes): reset the TCL_ENCODING_START
+	flags in the ChannelState when using 'gets'. [Bug 523988]
+	Also reduced the value of ENCODING_LINESIZE from 30 to 20 as this
+	seems to improve the performance of 'gets' according to tclbench.
+
+2002-02-28  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* generic/tclCmdMZ.c (TraceCommandProc): ensure that TraceCommandInfo
+	structure was also deleted when a command was deleted to prevent a
+	mem leak.
+
+	* generic/tclBasic.c (Tcl_CreateObjTrace): set tracePtr->flags
+	correctly.
+
+	* generic/tclTimer.c (TimerExitProc): remove remaining events in
+	tls on thread exit.
+
+2002-02-28  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* generic/tclNamesp.c: allow cached fully-qualified namespace names to
+	be usable from different namespaces within the same interpreter
+	without forcing a new lookup [Patch 458872].
+
+2002-02-28  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* generic/tclExecute.c: Replaced a few direct stack accesses with the
+	POP_OBJECT() macro [Bug 507181] (Don Porter).
+
+2002-02-27  Don Porter  <dgp@users.sourceforge.net>
+
+	* doc/GetIndex.3:
+	* generic/tcl.decls (Tcl_GetIndexFromObjStruct):
+	* generic/tclIndexObj.c (Tcl_GetIndexFromObjStruct):  Revised the
+	prototype of the Tcl_GetIndexFromObjStruct to take its struct table as
+	a (CONST VOID *) argument, better describing what it is, maintaining
+	source compatibility, and adding CONST correctness according to TIP
+	27. Thanks to Joe English for an elegant solution. [Bug 520304]
+
+	* generic/tclDecls.h: make genstubs
+
+	* generic/tclMain.c (Tcl_Main,StdinProc):  Corrected some reference
+	count management errors on the interactive command Tcl_Obj found by
+	Purify. Thanks to Jeff Hobbs for the report and assistance.
+
+2002-02-27  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* generic/tclBasic.c (Tcl_EvalTokensStandard): corrected mem leak in
+	error case.
+
+	* generic/tclTest.c (TestStatProc[123]): correct harmless UMRs.
+
+	* generic/tclLink.c (Tcl_LinkVar): correct mem leak in error case.
+
+2002-02-27  Andreas Kupries  <andreas_kupries@users.sourceforge.net>
+
+	* tests/socket.test (2.7): Accepted and applied patch for [Bug 523470]
+	provided by Don Porter <dgp@users.sourceforge.net> to avoid timing
+	problems in that test.
+
+	* unix/tclUnixChan.c (TclpOpenFileChannel): Added code to regonize
+	"/dev/tty" (by name) and to not handle it as tty / serial line. This
+	is the controlling terminal and is special. Setting it into raw mode
+	as is done for other tty's is a bad idea. This is a hackish fix for
+	expect [Bug 520624]. The fix has limitation: Tcl_MakeFileChannel
+	handles tty's specially too, but is unable to recognize /dev/tty as it
+	only gets a file descriptor, and no name for it.
+
+2002-02-26  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* generic/tclCmdAH.c (StoreStatData): corrected mem leak.
+
+	* generic/tclCmdMZ.c (Tcl_RegsubObjCmd): prevent obj leak in
+	remedial regsub case.
+
+	* generic/tclFileName.c (Tcl_TranslateFileName): decr refcount for
+	error case to prevent mem leak.
+
+	* generic/tclVar.c (Tcl_ArrayObjCmd): removed extra obj allocation.
+
+	* unix/tclUnixSock.c (Tcl_GetHostName): added an extra
+	gethostbyname check to guard against failure with truncated
+	names returned by uname.
+
+	* unix/configure:
+	* unix/tcl.m4 (SC_SERIAL_PORT): added sys/modem.h check and defined
+	_XOPEN_SOURCE_EXTENDED for HP-11 to get updated header decls.
+
+	* unix/tclUnixChan.c: added Unix implementation of TIP #35, serial
+	port support. [Patch 438509] (schroedter)
+
+2002-02-26  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* generic/tclCmpCmds.c: (bugfix to the bugfix, hopefully the last)
+	Bugfix to the new [for] compiling code: was setting a exceptArray
+	parameter using another param which wasn't yet initialised, thus
+	filling it with noise.
+
+2002-02-25  Andreas Kupries  <andreas_kupries@users.sourceforge.net>
+
+	* mac/tclMacSock.c (TcpGetOptionProc): Changed to recognize the option
+	"-error". Essentially ignores the option, always returning an empty
+	string.
+
+2002-02-25  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* doc/Alloc.3:
+	* doc/LinkVar.3:
+	* doc/ObjectType.3:
+	* doc/PkgRequire.3:
+	* doc/Preserve.3:
+	* doc/TCL_MEM_DEBUG.3: Updated documentation to describe the ckalloc,
+	ckfree, ckrealloc, attemptckalloc, and attemptckrealloc macros, and
+	to accurately describe when and how they are used. [Bug 497459] (dgp)
+
+	* generic/tclHash.c (AllocArrayEntry, AllocStringEntry):
+	Before invoking ckalloc when creating a Tcl_HashEntry,
+	check that the amount of memory being allocated is
+	at least as large as sizeof(Tcl_HashEntry). The previous
+	code was allocating memory regions that were one
+	or two bytes short. [Bug 521950] (dejong)
+
+2002-02-25  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* generic/tclBasic.c (Tcl_EvalEx): avoiding a buffer overrun
+	reported by Joe English, and restoring tcl7.6 behaviour for
+	[subst]: badly terminated nested scripts will raise an error
+	and not be evaluated. [Bug 495207]
+
+2002-02-25  Don Porter  <dgp@users.sourceforge.net>
+
+	* unix/tclUnixPort.h: corrected strtoll prototype mismatch on Tru64.
+	* compat/strtod.c (strtod): simplified #includes
+	* compat/strtol.c (strtol): gather result in a long before returning
+	as a long: necessary on platforms where sizeof(int) != sizeof(long).
+
+2002-02-25  Daniel Steffen  <das@users.sourceforge.net>
+
+	* unix/tclLoadDyld.c: updated to use Mac OS X 10.1 dyld APIs that
+	have more libdl-like semantics. [Bug 514392]
+
+2002-02-25  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* generic/tclCompCmds: fixing a bug in patch dated 2002-02-22, in the
+	code for [for] and [while]. Under certain conditions, for long bodies,
+	the exception range parameters were badly computed. Tests forthcoming:
+	I still can't reproduce the conditions in the testsuite (!), although
+	the bug (with assorted segfault or panic!)  can be triggered from the
+	console or with the new parse.bench in tclbench.
+
+2002-02-25  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* compat/strtoul.c, compat/strtol.c, compat/strtod.c: Added UCHAR,
+	CONST and #includes to clean up GCC output.
+
+2002-02-23  Don Porter  <dgp@users.sourceforge.net>
+
+	* compat/strtoull.c (strtoull):
+	* compat/strtoll.c (strtoll):
+	* compat/strtoul.c (strtoul): Fixed failure to handle leading
+	sign symbols '+' and '-' and '0X' and raise overflow errors.
+	[Bug 440916]  Also corrects prototype and errno problems.
+
+2002-02-23  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* configure: Regen.
+	* unix/tcl.m4 (SC_CONFIG_CFLAGS): Link with -n32 instead of -32 when
+	building on IRIX64-6.* system. [Bug 521707]
+
+2002-02-22  Don Porter <dgp@users.sourceforge.net>
+
+	* generic/tclInt.h:
+	* generic/tclObj.c: renamed global variable emptyString ->
+	tclEmptyString because it is no longer static.
+	* generic/tclPkg.c: Fix for panic when library is loaded on a
+	platform without backlinking without proper use of stubs. [Bug 476537]
+
+2002-02-22  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* tests/regexpComp.test: updated regexp-11.[1-4] to match changes in
+	regexp.test for new regsub syntax
+
+	* unix/configure:
+	* unix/tcl.m4: added --enable-64bit support for AIX-4 (using -q64
+	flag) when using IBM's xlc compiler.
+
+	* tests/safe.test: updated safe-8.5 and safe-8.7
+	* library/safe.tcl (CheckFileName): removed the limit on
+	sourceable file names (was only *.tcl or tclIndex files with no more
+	than one dot and 14 chars). There is enough internal protection in a
+	safe interpreter already. [Tk Bug 521560]
+
+2002-02-22  Miguel Sofer  <msofer@users.sourceforge.net>
+
+	* generic/tclCompCmds: [FR 465811]. Optimising [if], [for] and [while]
+	for constant conditions; in addition, [for] and [while] are now
+	compiled with the "loop rotation" optimisation (thanks to Kevin
+	Kenny).
+
+2002-02-22  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	--- TIP#76 CHANGES ---
+	* generic/tclCmdMZ.c (Tcl_RegsubObjCmd): Final-argument-less
+	[regsub] returns the modified string.
+	* doc/regsub.n: Updated docs.
+	* tests/regexp.test: Updated and added tests.
+
+	* compat/strtoll.c (strtoll):
+	* compat/strtoull.c (strtoull):
+	* unix/tclUnixPort.h:
+	* win/tclWinPort.h: Const-ing 64-bit compatability declarations. Note
+	that the return pointer is non-const because it is entirely legal for
+	the functions to be called from somewhere that owns the string being
+	passed. Fixes problem reported by Larry Virden.
+
+2002-02-21  David Gravereaux <davygrvy@pobox.com>
+
+	* win/mkd.bat (removed):
+	* win/coffbase.txt (new):
+	* win/makefile.bc:
+	* win/makefile.vc:  Changed the 'setup' target to stop using the
+	mkd.bat file and just make the directory right in the rule. Same
+	change to makefile.bc. Neither configure.in nor Makefile.in use it.
+
+	coffbase.txt will be the master list for our "prefered base addresses"
+	set by the linker. This should improve load-time (NT only) by avoiding
+	relocations. Submissions to the list by extension authors are
+	encouraged.
+
+	Added a 'tidy' target to compliment 'clean' and 'hose' to remove just
+	the outputs. Also removed the $(winlibs) macro as it wasn't being
+	used.
+
+	Stuff left to do:
+	1) get the winhelp target to stop building in the tools/ directory.
+	2) stop using rmd.bat
+	3) add more dependacy rules.
+
+	* win/tclAppInit.c:  Reverted back to -r1.6, as the header file change
+	to tclPort.h won't allow for easy embedded support outside of the
+	source dist. Thanks to Don Porter for pointing this out to me.
+
+2002-02-21  David Gravereaux <davygrvy@pobox.com>
+
+	* win/makefile.vc:
+	* win/rules.vc:  Added a new "loimpact" option that sets the
+	-ws:aggressive linker option. Off by default. It's said to keep the
+	heap use low at the expense of alloc speed.
+
+	* win/tclAppInit.c: Changed #include "tcl.h" to be tclPort.h to remove
+	the raw windows.h include. tclPort.h brings in windows.h already and
+	lessens the pre-compiled-header mush and the randomly useless #pragma
+	comment (lib,...) references throughout the big windows.h tree (as
+	observed at high linker warning levels).
+
+2002-02-21  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* generic/tcl.h: Better guessing of LP64/ILP32 architecture, but now
+	sensitive to presence of (suitable) <limits.h>
+
+2002-02-20  Don Porter <dgp@users.sourceforge.net>
+
+	* generic/tcl.decls (Tcl_RegExpRange,Tcl_GetIndexFromObjStruct):
+	Overlooked a few source incompatibilities. Now using CONST84.
+	* generic/tclDecls.h: make genstubs
+	* generic/tcl.h (Tcl_CmdObjTraceProc): silence warning from Sun
+	Workshop compiler.
+
+2002-02-20  David Gravereaux <davygrvy@pobox.com>
+
+	* win/buildall.vc.bat:
+	* win/makefile.vc:
+	* win/rules.vc: General clean-ups. Added compiler and linker tests for
+	a) the pentium 0x0F errata, b) optimizing (not all have this), and c)
+	linker v6 section alignment confusion. All these are tested first to
+	make sure any D4002 or LNK1117 warnings aren't displayed. The pentium
+	0x0F errata is a recommended switch. The v5 linker's section alignment
+	default is 512, but the v6 linker was changed to 4096 in an attempt to
+	speed loading on Win98. I changed the default to always be 512 across
+	both linkers, unless linking statically, then 4096 is used for the
+	claimed speed effect. Using a 512 alignment saves 12k bytes of dead
+	space in the DLL.
+
+	Added IA64 B-stepping errata switch when the compiler supports it.
+
+	Added profiling to $(lflags) when requested and also removed the
+	explict -entry option as the default works fine as is.
+
+	Removed win/tclWinInit.c from the special case section to let it use
+	the common implicit rule as the $(EXTFLAGS) macro it had was never
+	referenced anywhere.
+
+2002-02-20  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* generic/tcl.h: Added code to guess the correct settings for
+	TCL_WIDE_INT_IS_LONG and TCL_WIDE_INT_TYPE when configure doesn't tell
+	us them, as can happen with extensions.
+
+2002-02-19  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* doc/format.n: Updated docs to list the specification.
+	* generic/tclCmdAH.c (Tcl_FormatObjCmd): Made behaviour on 64-bit
+	platforms correctly meet the specification, that %d works with the
+	native word-sized integer, instead of trying to guess (wrongly)
+	from the value being passed.
+
+2002-02-19  Don Porter <dgp@users.sourceforge.net>
+
+	* changes: First draft of updated changes for 8.4a4 release.
+
+2002-02-15  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* unix/tclUnixPort.h: add strtoll/strtoull declarations for
+	platforms that do not define them.
+
+	* generic/tclIndexObj.c (STRING_AT): removed ptrdiff_t cast and
+	use of VOID* in default case (GNU-ism).
+
+2002-02-15  Kevin Kenny  <kennykb@acm.org>
+
+	* compat/strtoll.c:
+	* compat/strtoul.c:
+	* compat/strtoull.c:
+	* generic/tclIOUtil.c:
+	* generic/tclPosixStr.c:
+	* generic/tclTest.c:
+	* generic/tclTestObj.c:
+	* tests/get.test:
+	* win/Makefile.vc: Further tweaks to the TIP 72 patch to make it
+	compile under VC++.
+
+2002-02-15  Andreas Kupries  <andreas_kupries@users.sourceforge.net>
+
+	* tclExecute.c:
+	* tclIOGT.c:
+	* tclIndexObj.c: Touchups to the TIP 72 patch to make it compileable
+	under Windows again. The changes are not complete, there is one nasty
+	regarding _stati64
+
+2002-02-15  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	+----------------------+
+	| TIP #72 IMPLEMENTED. |
+	+----------------------+
+
+	There are a lot of changes from this TIP, so please see
+	http://purl.org/tcl/tip/72.html for discussion of
+	backward-compatability issues, but the main ones modifications are in:
+
+	* generic/tcl.h: New types.
+	* generic/tcl.decls: New public functions.
+	* generic/tclExecute.c: 64-bit aware bytecode engine.
+	* generic/tclBinary.c: 64-bit handling in [binary] command.
+	* generic/tclScan.c: 64-bit handling in [scan] command.
+	* generic/tclCmdAH.c: 64-bit handling in [file] and [format]
+	commands.
+	* generic/tclBasic.c: New "wordSize" entry in ::tcl_platform.
+	* generic/tclFCmd.c: Large-file support (with many consequences.)
+	* generic/tclIO.c: Large-file support (with many consequences.)
+	* compat/strtoll.c, compat/strtoull.c: New support functions.
+	* unix/tcl.m4, unix/configure: 64-bit support and greatly enhanced
+	cacheing.
+
+	Most other changes, including all those in doc/* and test/* as well as
+	the majority in the platform directories, follow on from these.
+
+	Also coming out of the woodwork:
+	* generic/tclIndex.c: Better support for Cray PVP.
+	* win/tclWinMtherr.c: Better Borland support.
+
+	Note that, in a number of places through the Unix part of the platform
+	support, there are Tcl_Platform* references. These are expanded into
+	the correct way to call that particular underlying function, i.e. with
+	or without a '64' suffix, and should be used by people working on the
+	core in preference to the API functions they overlay so that the code
+	remains portable depending on the presence or absence of 64-bit
+	support on the underlying platform.
+
+	***POTENTIAL INCOMPATIBILITY***: Extracted from the TIP
+
+	SUMMARY OF INCOMPATIBILITIES AND FIXES
+	======================================
+
+	The behaviour of expressions containing constants that appear positive
+	but which have a negative internal representation will change, as
+	these will now usually be interpreted as wide integers. This is always
+	fixable by replacing the constant with int(constant).
+
+	Extensions creating new channel types will need to be altered as
+	different types are now in use in those areas. The change to the
+	declaration of Tcl_FSStat and Tcl_FSLstat (which are the new preferred
+	API in any case) are less serious as no non-alpha releases have been
+	made yet with those API functions.
+
+	Scripts that are lax about the use of the l modifier in format and
+	scan will probably need to be rewritten. This should be very uncommon
+	though as previously it had absolutely no effect.
+
+	Extensions that create new math functions that take more than one
+	argument will need to be recompiled (the size of Tcl_Value changes),
+	and functions that accept arguments of any type (TCL_EITHER) will need
+	to be rewritten to handle wide integer values. (I do not expect this
+	to affect many extensions at all.)
+
+2002-02-14  Andreas Kupries  <andreas_kupries@users.sourceforge.net>
+
+	* generic/tclIOCmd.c (Tcl_GetsObjCmd): Trivial fix for [Bug 517503], a
+	memory leak reported by Miguel Sofer <msofer@users.sf.net>. The leak
+	happens if an error occurs for "set var [gets $chan]" and leak one
+	empty object.
+
+2002-02-12  David Gravereaux <davygrvy@pobox.com>
+
+	* djgpp/ (new directory)
+	* djgpp/Makefile (new):
+	* unix/tclAppInit.c:
+	* unix/tclMtherr.c:
+	* unix/tclUnixFCmd.c:
+	* unix/tclUnixFile.c:
+	* unix/tclUnixInit.c:
+	* unix/tclUnixPort.h:  Early stage of DJGPP support for building Tcl
+	on DOS. Dynamic loading isn't working, yet. Requires watt32 for the
+	TCP/IP stack. No autoconf, yet. Barely tested, but makes a working exe
+	that runs Tcl in protected-mode, flat memory. [exec] and pipes will
+	need the most work as multi-tasking on DOS has to be carefully.
+
+2002-02-10  Kevin Kenny  <kennykb@acm.org>
+
+	* doc/CrtObjCmd.3:
+	* doc/CrtTrace.3:
+	* generic/tcl.decls:
+	* generic/tcl.h:
+	* generic/tclBasic.c:
+	* generic/tclInt.h:
+	* generic/tclTest.c:
+	* tests/basic.test: Added Tcl_CreateObjTrace,
+	Tcl_GetCommandInfoFromToken and Tcl_SetCommandInfoFromToken.
+	(TIPs #32 and #79.)
+
+	* generic/tclDecls.h:
+	* generic/tclStubInit.c: Regenerated Stubs tables.
+
+2002-02-08  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* unix/configure:
+	* unix/tcl.m4: added -pthread for FreeBSD to EXTRA_CFLAGS and
+	LDFLAGS. Also triggered nodots only for FreeBSD-3. Added
+	AC_DEFINE(_POSIX_PTHREAD_SEMANTICS) for Solaris.
+
+	* unix/tclUnixPort.h:
+	* unix/tclUnixThrd.c: added thread-safe versions of readdir,
+	localtime, gmtime and inet_ntoa for threaded build. (jgdavidson)
+
+	* generic/tclScan.c (Tcl_ScanObjCmd): prevented ckfree being called on
+	a pointer to NULL.
+
+2002-02-07  Don Porter <dgp@users.sourceforge.net>
+
+	* doc/DString.3:
+	* doc/Encoding.3:
+	* doc/GetCwd.3:
+	* doc/SplitPath.3:
+	* doc/Translate.3:
+	* doc/Utf.3:
+	* generic/tcl.decls:
+	* generic/tcl.h:
+	* generic/tclEncoding.c:
+	* generic/tclEnv.c:
+	* generic/tclFileName.c:
+	* generic/tclIOUtil.c:
+	* generic/tclUtf.c:
+	* generic/tclUtil.c:
+	* mac/tclMacInit.c:
+	* unix/tclUnixFile.c:
+	* unix/tclUnixInit.c:
+	* unix/tclUnixPipe.c:
+	* win/tclWin32Dll.c:
+	* win/tclWinFCmd.c:
+	* win/tclWinFile.c:
+	* win/tclWinInit.c: Partial TIP 27 rollback. Following routines
+	restored to return (char *): Tcl_DStringAppend,
+	Tcl_DStringAppendElement, Tcl_JoinPath, Tcl_TranslateFileName,
+	Tcl_ExternalToUtfDString, Tcl_UtfToExternalDString,
+	Tcl_UniCharToUtfDString, Tcl_GetCwd, Tcl_WinTCharToUtf. Also restored
+	Tcl_WinUtfToTChar to return (TCHAR *) and Tcl_UtfToUniCharDString to
+	return (Tcl_UniChar *). Modified some callers. This change recognizes
+	that Tcl_DStrings are de-facto white-box objects.
+
+	* generic/tclDecls.h:
+	* generic/tclPlatDecls.h: make genstubs
+
+	* generic/tclCmdMZ.c: corrected use of C++-style comment.
+
+2002-02-06  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* tests/scan.test:
+	* generic/tclScan.c (Tcl_ScanObjCmd): corrected scan 0x... %x handling
+	that didn't accept the 0x as a prelude to a base 16 number. [Bug
+	495213]
+
+	* generic/tclCompCmds.c (TclCompileRegexpCmd): made early check for
+	bad RE to stop checking further.
+
+	* generic/tclCmdMZ.c (Tcl_RegsubObjCmd): added special case to search
+	for simple 'string map' style regsub calls. Delayed creation of
+	resultPtr object until an initial match is made, as the input string
+	object can then be reused for no matches.
+	(Tcl_StringObjCmd): optimization improvements to the STR_MAP
+	algorithm for zero-length and nocase cases.
+
+	* tests/regexp.test:
+	* tests/regexpComp.test: extra code coverage tests.
+
+	* tests/string.test: added 10.18 and 10.19 extra tests.
+
+	* generic/regc_locale.c (casecmp): slight performance improvement.
+
+2002-02-05  Don Porter <dgp@users.sourceforge.net>
+
+	* library/http/http.tcl:
+	* library/http/pkgIndex.tcl:  Corrected use of http::error when
+	::error was intended. Bump to http 2.4.2.
+
+2002-02-04  Andreas Kupries  <andreas_kupries@users.sourceforge.net>
+
+	* unix/tclUnixChan.c (FileOutputProc): Fixed [bug 465765] reported by
+	Dale Talcott <daletalcott@users.sourceforge.net>. Avoid writing
+	nothing into a file as STREAM based implementations will consider this
+	a EOF (if the file is a pipe). Not done in the generic layer as this
+	type of writing is actually useful to check the state of a socket.
+
+	* doc/open.n: Fixed [Bug 511540], added cross-reference to 'pid' as
+	the command to use to retrieve the pid of a command pipeline created
+	via 'open'.
+
+2002-02-01  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* generic/tclCmdMZ.c (Tcl_RegexpObjCmd): handle quirky about case
+	earlier to avoid shimmering problem.
+
+2002-02-01  Andreas Kupries  <andreas_kupries@users.sourceforge.net>
+
+	* tests/io.test: io-39.22 split into two tests, one platform
+	dependent, the other not. -eofchar is not empty on the windows
+	platform.
+
+2002-02-01  Vince Darley <vincentdarley@users.sourceforge.net>
+
+	* generic/tclTest.c: fix to picky windows compiler problem with the
+	'MainLoop' function declaration.
+
+2002-01-31  Andreas Kupries  <andreas_kupries@users.sourceforge.net>
+
+	* win/tclWinFCmd.c: TIP 27: Applied patch fixing CONST warnings on
+	behalf of Don Porter <dgp@users.sourceforge.net>.
+
+2002-01-30  Don Porter <dgp@users.sourceforge.net>
+
+	* generic/tcl.decls:
+	* generic/tcl.h:
+	* generic/tclInt.h: For each interface identified in the TIP 27
+	changes below as a POTENTIAL INCOMPATIBILITY, the source of the
+	incompatibility has been parameterized so that it can be removed. When
+	compiling extension code against the Tcl header files, use the
+	compiler flag -DUSE_NON_CONST to remove the irresolvable source
+	incompatibilities introduced by the TIP 27 changes. Resolvable changes
+	are left for extension authors to resolve.
+	* generic/tclDecls.h: make genstubs
+
+2002-01-30  Vince Darley <vincentdarley@users.sourceforge.net>
+
+	* doc/FileSystem.3: added documentation for 3 public functions which
+	had been overlooked. [Bug 507701]
+	* unix/mkLinks: make mklinks
+
+2002-01-29  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* tests/regexpComp.test:
+	* generic/tclCompCmds.c (TclCompileRegexpCmd): enhanced to support
+	-nocase and -- options.
+
+2002-01-28  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* unix/tcl.m4 (SC_LOAD_TCLCONFIG):
+	* win/tcl.m4 (SC_LOAD_TCLCONFIG): Set TCL_LIB_SPEC, TCL_STUB_LIB_SPEC,
+	and TCL_STUB_LIB_PATH to the values of TCL_BUILD_LIB_SPEC,
+	TCL_BUILD_STUB_LIB_SPEC, and TCL_BUILD_STUB_LIB_PATH when tclConfig.sh
+	is loaded from the build directory. A Tcl extension should make use of
+	the non-build versions of these variables since they will work in both
+	cases. This modification was described in TIP 34.
+
+2002-01-28  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* win/tclWinReg.c (regConnectRegistryProc,RecursiveDeleteKey)
+	(DeleteKey,GetKeyNames,GetType,GetValue,OpenSubKey,SetValue):
+	redid the CONSTification as previous changes caused failing tests.
+
+	* tests/regexpComp.test (new):
+	* generic/tclInt.h:
+	* generic/tclBasic.c: added TclCompileRegexpCmd entry
+	* generic/tclCompCmds.c (TclCompileStringCmd): corrected to return
+	TCL_OUT_LINE_COMPILE instead of TCL_ERROR for parsing errors, so
+	it only throws the error for runtime compile, in case the user
+	modifies 'string'.
+	(TclCompileRegexpCmd): first try at a byte-compiled regexp command. It
+	handles static strings and ^$ bounded static strings.
+	(TclCompileAppendCmd): made TclPushVarName call always use
+	TCL_CREATE_VAR as numWords is always > 2 at that point.
+
+	* generic/tclExecute.c (TclExecuteByteCode:INST_LIST): correct
+	possibly dangerous decr in macro call.
+
+	* win/tclWinInit.c (TclpFindVariable): CONSTification touch-up
+
+	* win/tclWinReg.c (OpenSubKey): corrected bug introduced in
+	CONSTification that dropped pointer reference.
+
+	* ChangeLog.2000 (new file):
+	* ChangeLog: broke changes from 2000 into ChangeLog.2000 to reduce
+	size of the main ChangeLog.
+
+2002-01-28  David Gravereaux <davygrvy@pobox.com>
+
+	* generic/tclPlatDecls.h:  Added preprocessor logic to force a
+	typedef of TCHAR when __STDC__ is defined when using the uncommon
+	-Za compiler switch with the microsoft compiler.
+
+2002-01-27  Don Porter <dgp@users.sourceforge.net>
+
+	* doc/package.n: Documented global namespace context for script
+	evaluation by [package require].
+
+2002-01-27  Daniel Steffen  <das@users.sourceforge.net>
+
+	* generic/tclInt.decls:
+	* generic/tclIntPlatDecls.h:
+	* mac/tclMacChan.c:
+	* mac/tclMacFCmd.c:
+	* mac/tclMacFile.c:
+	* mac/tclMacInit.c:
+	* mac/tclMacLoad.c:
+	* mac/tclMacResource.c:
+	* mac/tclMacSock.c: TIP 27 CONSTification induced changes
+
+	* tests/event.test:
+	* tests/main.test: added catches/constraints to test that
+	use features that don't exist on the mac.
+
+2002-01-25  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	Make -eofchar and -translation options read only for server sockets.
+	[Bug 496733]
+
+	* generic/tclIO.c (Tcl_GetChannelOption, Tcl_SetChannelOption):
+	Instead of returning nothing for the -translation option on a server
+	socket, always return "auto". Return the empty string enclosed in
+	quotes for the -eofchar option on a server socket. Fixup -eofchar
+	usage message so that it matches the implementation.
+	* tests/io.test: Add -eofchar tests and -translation tests to ensure
+	options are read only on server sockets.
+	* tests/socket.test: Update tests to account for -eofchar and
+	-translation option changes.
+
+2002-01-25  Don Porter <dgp@users.sourceforge.net>
+
+	* compat/strstr.c (strstr):
+	* generic/tclCmdAH.c (Tcl_FormatObjCmd):
+	* generic/tclCmdIL.c (InfoNameOfExecutableCmd):
+	* generic/tclEnv.c (ReplaceString):
+	* generic/tclFileName.c (ExtractWinRoot):
+	* generic/tclIO.c (FlushChannel,Tcl_BadChannelOption):
+	* generic/tclStringObj.c (AppendUnicodeToUtfRep):
+	* generic/tclThreadTest.c (TclCreateThread):
+	* generic/tclUtf.c (Tcl_UtfPrev):
+	* mac/tclMacFCmd.c (TclpObjListVolumes):
+	* mac/tclMacResource.c (TclMacRegisterResourceFork,
+	(BuildResourceForkList):
+	* win/tclWinInit.c (AppendEnvironment):  Sought out and eliminated
+	instances of CONST-casting that are no longer needed after the
+	TIP 27 effort.
+
+	* Following is [Patch 501006]
+	* generic/tclInt.decls (Tcl_AddInterpResolvers, Tcl_Export,
+	(Tcl_FindNamespace, Tcl_GetInterpResolvers, Tcl_ForgetImport,
+	(Tcl_Import, Tcl_RemoveInterpResolvers):
+	* generic/tclNamesp.c (Tcl_Export, Tcl_Import, Tcl_ForgetImport,
+	(Tcl_FindNamespace):
+	* generic/tclResolve.c (Tcl_AddInterpResolvers,Tcl_GetInterpResolvers,
+	(Tcl_RemoveInterpResolvers): Updated APIs in generic/tclResolve.c and
+	generic/tclNamesp.c according to the guidelines of TIP 27.
+	* generic/tclIntDecls.h: make genstubs
+
+	* Following is [Patch 505630]
+	* doc/AddErrorInfo.3:
+	* generic/tcl.decls (Tcl_LogCommandInfo):
+	* generic/tclBasic.c (Tcl_LogCommandInfo): Updated interfaces
+	of generic/tclBasic.cc according to TIP 27.
+	* generic/tclDecls.h: make genstubs
+
+	* Following is [Patch 506818]
+	* doc/Hash.3:
+	* generic/tcl.decls (Tcl_HashStats):
+	* generic/tclHash.c (Tcl_HashStats):  Updated APIs of generic/tclHash.c
+	according to guidelines of TIP 27.
+	* generic/tclDecls.h: make genstubs
+	* generic/tclVar.c (Tcl_ArrayObjCmd): Updated callers.
+
+	* Following is [Patch 506807]
+	* doc/ObjectType.3:
+	* generic/tcl.decls (Tcl_GetObjType):
+	* generic/tclObj.c (Tcl_GetObjType): Updated APIs of generic/tclObj.c
+	according to guidelines of TIP 27.
+	* generic/tclDecls.h: make genstubs
+
+	* Following is [Patch 507304]
+	* doc/Encoding.3:
+	* generic/tcl.decls (Tcl_WinUtfToTChar,Tcl_WinTCharToUtf):
+	* win/tclWin32Dll.c (Tcl_WinUtfToTChar,Tcl_WinTCharToUtf):
+	Updated interfaces in win/tclWin32Dll.c according to TIP 27.
+	* generic/tclPlatDecls.h: make genstubs
+	* generic/tclIOUtil.c (TclpNativeToNormalized):
+	* win/tclWinFCmd.c (TclpObjNormalizePath):
+	* win/tclWinFile.c (TclpFindExecutable,TclpMatchInDirectory,
+	(NativeIsExec,NativeStat):
+	* win/tclWinLoad.c (TclpLoadFile):
+	* win/tclWinPipe.c (TclpOpenFile,ApplicationType):
+	* win/tclWinReg.c (regConnectRegistryProc,RecursiveDeleteKey,DeleteKey,
+	(GetKeyNames,GetType,GetValue,OpenSubKey,SetValue):
+	* win/tclWinSerial.c (SerialSetOptionProc): Update callers.
+
+	* Following is [Patch 505072]
+	* doc/Concat.3:
+	* doc/Encoding.3:
+	* doc/Filesystem.3:
+	* doc/Macintosh.3:
+	* doc/OpenFileChnl.3
+	* doc/SetResult.3:
+	* doc/SetVar.3:
+	* doc/SplitList.3:
+	* doc/SplitPath.3:
+	* doc/Translate.3:
+	* generic/tcl.h (Tcl_FSMatchInDirectoryProc):
+	* generic/tclInt.h (TclpMatchInDirectory):
+	* generic/tcl.decls (Tcl_Concat,Tcl_GetStringResult,Tcl_GetVar,
+	(Tcl_GetVar2,Tcl_JoinPath,Tcl_Merge,Tcl_OpenCommandChannel,Tcl_SetVar,
+	(Tcl_SetVar2,Tcl_SplitList,Tcl_SplitPath,Tcl_TranslateFileName,
+	(Tcl_ExternalToUtfDString,Tcl_GetEncodingName,Tcl_UtfToExternalDString,
+	(Tcl_GetDefaultEncodingDir,Tcl_SetDefaultEncodingDir,
+	(Tcl_FSMatchInDirectory,Tcl_MacEvalResource,Tcl_MacFindResource):
+	* generic/tclInt.decls (TclCreatePipeline,TclGetEnv,TclpGetCwd,
+	(TclpCreateProcess):
+	* mac/tclMacFile.c (TclpGetCwd):
+	* generic/tclEncoding.c (Tcl_GetDefaultEncodingDir,
+	(Tcl_SetDefaultEncodingDir,Tcl_GetEncodingName,
+	(Tcl_ExternalToUtfDString,Tcl_UtfToExternalDString, OpenEncodingFile,
+	(LoadEscapeEncoding):
+	* generic/tclFileName.c (DoTildeSubst,Tcl_JoinPath,Tcl_SplitPath,
+	(Tcl_TranslateFileName):
+	* generic/tclIOUtil.c (Tcl_FSMatchInDirectory):
+	* generic/tclPipe.c (FileForRedirect,TclCreatePipeline,
+	(Tcl_OpenCommandChannel):
+	* generic/tclResult.c (Tcl_GetStringResult):
+	* generic/tclUtil.c (Tcl_Concat,Tcl_SplitList,Tcl_Merge):
+	* generic/tclVar.c (Tcl_GetVar,Tcl_GetVar2,Tcl_SetVar,Tcl_SetVar2):
+	* mac/tclMacResource.c (Tcl_MacEvalResource,Tcl_MacFindResource):
+	Updated interfaces of generic/tclEncoding, generic/tclFilename.c,
+	generic/tclIOUtil.c, generic/tclPipe.c, generic/tclResult.c,
+	generic/tclUtil.c, generic/tclVar.c and mac/tclMacResource.c according
+	to TIP 27. Tcl_TranslateFileName rewritten as wrapper around VFS-aware
+	version.
+	***POTENTIAL INCOMPATIBILITY***
+	Includes source incompatibilities: argv arguments of Tcl_Concat,
+	Tcl_JoinPath, Tcl_OpenCommandChannel, Tcl_Merge; argvPtr arguments of
+	Tcl_SplitList and Tcl_SplitPath.
+	* generic/tclDecls.h:
+	* generic/tclIntDecls.h: make genstubs
+
+	* generic/tclCkalloc.c (MemoryCmd):
+	* generic/tclClock.c (FormatClock):
+	* generic/tclCmdAH.c (Tcl_CaseObjCmd,Tcl_EncodingObjCmd,Tcl_FileObjCmd):
+	* generic/tclCmdIL.c (InfoLibraryCmd,InfoPatchLevelCmd,
+	(InfoTclVersionCmd):
+	* generic/tclCompCmds.c (TclCompileForeachCmd):
+	* generic/tclCompCmds.h (TclCompileForeachCmd):
+	* generic/tclCompile.c (TclFindCompiledLocal):
+	* generic/tclEnv.c (TclSetupEnv,TclSetEnv,Tcl_PutEnv,TclGetEnv,
+	(EnvTraceProc):
+	* generic/tclEvent.c (Tcl_BackgroundError):
+	* generic/tclIO.c (Tcl_BadChannelOption,Tcl_SetChannelOption):
+	* generic/tclIOCmd.c (Tcl_ExecObjCmd,Tcl_OpenObjCmd):
+	* generic/tclIOSock.c (TclSockGetPort):
+	* generic/tclIOUtil.c (SetFsPathFromAny):
+	* generic/tclLink.c (LinkTraceProc):
+	* generic/tclMain.c (Tcl_Main):
+	* generic/tclNamesp.c (TclTeardownNamespace):
+	* generic/tclProc.c (TclCreateProc):
+	* generic/tclTest.c (TestregexpObjCmd,TesttranslatefilenameCmd,
+	(TestchmodCmd,GetTimesCmd,TestsetCmd,TestOpenFileChannelProc1,
+	(TestOpenFileChannelProc2,TestOpenFileChannelProc3,AsyncHandlerProc,
+	(TestpanicCmd):
+	* generic/tclThreadTest.c (ThreadErrorProc,ThreadEventProc):
+	* generic/tclUtil.c (TclPrecTraceProc):
+	* mac/tclMacFCmd.c (GetFileSpecs):
+	* mac/tclMacFile.c (TclpMatchInDirectory):
+	* mac/tclMacInit.c (TclpInitLibraryPath,Tcl_SourceRCFile):
+	* mac/tclMacOSA.c (tclOSAStore,tclOSALoad):
+	* mac/tclMacResource.c (Tcl_MacEvalResource):
+	* unix/tclUnixFCmd.c (TclpObjNormalizePath):
+	* unix/tclUnixFile.c (TclpMatchInDirectory,TclpGetUserHome,TclpGetCwd,
+	(TclpReadLink):
+	* unix/tclUnixInit.c (TclpInitLibraryPath,TclpSetVariables,
+	(Tcl_SourceRCFile):
+	* unix/tclUnixPipe.c (TclpOpenFile,TclpCreateTempFile,
+	(TclpCreateProcess):
+	* win/tclWinFile.c (TclpGetCwd,TclpMatchInDirectory):
+	* win/tclWinInit.c (TclpInitLibraryPath,Tcl_SourceRCFile,
+	(TclpSetVariables):
+	* win/tclWinPipe.c (TclpCreateProcess): Updated callers.
+
+2002-01-24  Don Porter <dgp@users.sourceforge.net>
+
+	* generic/tclIOUtil.c (SetFsPathFromAny):  Corrected tilde-substitution
+	of pathnames where > 1 separator follows the ~. [Bug 504950]
+
+2002-01-24  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* library/http/pkgIndex.tcl:
+	* library/http/http.tcl: don't add port in default case to handle
+	broken servers. http bumped to 2.4.1  [Bug 504508]
+
+2002-01-23  Andreas Kupries  <andreas_kupries@users.sourceforge.net>
+
+	* unix/mkLinks: Regenerated.
+	* doc/CrtChannel.3:
+	* doc/ChnlStack.3: Moved documentation for 'Tcl_GetTopChannel' from
+	'CrtChannel' to 'ChnlStack'. Added documentation of
+	'Tcl_GetStackedChannel'. [Bug 506147] reported by Mark Patton
+	<msp@users.sourceforge.net>.
+
+2002-01-23  Don Porter <dgp@users.sourceforge.net>
+
+	* win/tclWinFile.c (NativeAccess,NativeStat,NativeIsExec,
+	(TclpGetUserHome):
+	* win/tclWinPort.h (TclWinSerialReopen):
+	* win/tclWinSerial.c (TclWinSerialReopen):
+	* win/tclWinSock.c (Tcl_OpenTcpServer):  Corrections to earlier TIP 27
+	changes. Thanks to Andreas Kupries for the feedback.
+	* generic/tclPlatDecls.h: make genstubs
+
+	* doc/GetHostName.3:
+	* doc/GetOpnFl.3:
+	* doc/OpenTcp.3:
+	* tcl.decls (Tcl_GetHostName,Tcl_GetOpenFile,Tcl_OpenTcpClient,
+	(Tcl_OpenTclServer):
+	* mac/tclMacSock.c (CreateSocket,Tcl_OpenTcpClient,Tcl_OpenTcpServer,
+	(Tcl_GetHostName,GetHostFromString):
+	* unix/tclUnixChan.c (CreateSocket,CreateSocketAddress,
+	(Tcl_OpenTcpClient,Tcl_OpenTcpServer,Tcl_GetOpenFile):
+	* unix/tclUnixSock.c (Tcl_GetHostName):
+	* win/tclWinSock.c (CreateSocket,CreateSocketAddress,
+	(Tcl_OpenTcpClient,Tcl_OpenTcpServer,Tcl_GetHostName):
+	Updated socket interfaces according to TIP 27.
+	* generic/tclCmdIL.c (InfoHostnameCmd): Updated callers.
+	* generic/tclDecls.h: make genstubs
+
+2002-01-21  David Gravereaux <davygrvy@pobox.com>
+
+	* generic/tclLoadNone.c: TclpLoadFile() didn't match proto of typedef
+	Tcl_FSLoadFileProc. OK'd by vincentdarley. [Patch 502488]
+
+2002-01-21  Andreas Kupries  <andreas_kupries@users.sourceforge.net>
+
+	* generic/tclIO.c (WriteChars): Fix for [Bug 506297], reported by
+	Martin Forssen <ruric@users.sourceforge.net>. The encoding chosen in
+	the script exposing the bug writes out three intro characters when
+	TCL_ENCODING_START is set, but does not consume any input as
+	TCL_ENCODING_END is cleared. As some output was generated the
+	enclosing loop calls UtfToExternal again, again with START set. Three
+	more characters in the out and still no use of input ... To break this
+	infinite loop we remove TCL_ENCODING_START from the set of flags after
+	the first call (no condition is required, the later calls remove an
+	unset flag, which is a no-op). This causes the subsequent calls to
+	UtfToExternal to consume and convert the actual input.
+
+2002-01-21  Don Porter <dgp@users.sourceforge.net>
+
+	* generic/tclTest.c: Converted declarations of TestReport file system
+	to more portable form. [Bug 501417]
+
+	* generic/tcl.decls (Tcl_TraceCommand,Tcl_UntraceCommand,
+	(Tcl_CommandTraceInfo):
+	* generic/tclCmdMZ.c (Tcl_TraceCommand,Tcl_UntraceCommand,
+	(Tcl_CommandTraceInfo): Updated APIs in generic/tclCmdMZ.c according
+	to the guidelines of TIP 27.
+	* generic/tclDecls.h: make genstubs
+
+2002-01-18  Don Porter <dgp@users.sourceforge.net>
+
+	* win/tclWinChan.c:
+	* win/tclWinFCmd.c:
+	* win/tclWinFile.c: Overlooked callers of Tcl_FSGetNativePath
+
+	* win/tclWinDde.c:
+	* win/tclWinReg.c: Overlooked callers of Tcl_GetIndexFromObj
+
+2002-01-18  Daniel Steffen  <das@users.sourceforge.net>
+
+	* generic/tclThreadTest.c:
+	* mac/tclMacChan.c:
+	* mac/tclMacFCmd.c:
+	* mac/tclMacFile.c:
+	* mac/tclMacLoad.c:
+	* mac/tclMacResource.c: TIP 27 CONSTification broke the mac build in a
+	number of places.
+
+2002-01-17  Andreas Kupries  <andreas_kupries@users.sourceforge.net>
+
+	* generic/tclIOCmd.c (Tcl_GetsObjCmd): Fixed [Bug 504642] as reported
+	by Brian Griffin <bgriffin@users.sourceforge.net>, using his
+	patch. Before the patch the generic I/O layer held an unannounced
+	reference to the interp result to store the read line into. This
+	unfortunately has disastrous results if the channel driver executes a
+	tcl script to perform its operation, this freeing the interp
+	result. In that case we are dereferencing essentially a dangling
+	reference. It is not truly dangling because the object is in the free
+	list, but this only causes us to smash the free list and have the
+	error occur later somewhere else. The patch simply creates a new
+	object for the line and later sets it into the interp result when we
+	are done with reading.
+
+2002-01-16  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* unix/tcl.m4 (SC_LOAD_TCLCONFIG):
+	* win/tcl.m4 (SC_LOAD_TCLCONFIG): Subst TCL_DBGX into
+	TCL_STUB_LIB_FILE and TCL_STUB_LIB_FLAG variables so that an extension
+	does not need to subst TCL_DBGX into its makefile. [Tk Bug 504356]
+
+2002-01-16  Don Porter <dgp@users.sourceforge.net>
+
+	* doc/FileSystem.3:
+	* doc/GetCwd.3:
+	* doc/GetIndex.3:
+	* generic/tcl.decls (Tcl_GetIndexFromObj, Tcl_GetIndexFromObjStruct,
+	(Tcl_GetCwd, Tcl_FSFileAttrStrings, Tcl_FSGetNativePath,
+	(Tcl_FSGetTranslatedStringPath):
+	* generic/tcl.h (Tcl_FSFileAttrStringsProc):
+	* generic/tclFCmd.c (TclFileAttrsCmd):
+	* generic/tclIOUtil.c (Tcl_GetCwd,NativeFileAttrStrings,
+	(Tcl_FSFileAttrStrings,Tcl_FSGetTranslatedStringPath,
+	(Tcl_FSGetNativePath):
+	* generic/tclIndexObj.c (Tcl_GetIndexFromObj,
+	(Tcl_GetIndexFromObjStruct):
+	More TIP 27 updates in tclIOUtil.c and tclIndexObj.c that were
+	overlooked before. [Patch 504671]
+	***POTENTIAL INCOMPATIBILITY***
+	Includes a source incompatibility in the tablePtr arguments of the
+	Tcl_GetIndexFromObj* routines.
+	* generic/tclDecls.h: make genstubs
+
+	* generic/tclBinary.c (Tcl_BinaryObjCmd):
+	* generic/tclClock.c (Tcl_ClockObjCmd):
+	* generic/tclCmdAH.c (Tcl_EncodingObjCmd, Tcl_FileObjCmd):
+	* generic/tclCmdIL.c (Tcl_InfoObjCmd,Tcl_LsearchObjCmd,Tcl_LsortObjCmd):
+	* generic/tclCmdMZ.c (Tcl_TraceObjCmd,Tcl_RegexpObjCmd,Tcl_RegsubObjCmd,
+	(Tcl_StringObjCmd,Tcl_SubstObjCmd,Tcl_SwitchObjCmd,
+	(TclTraceCommandObjCmd,TclTraceVariableObjCmd):
+	* generic/tclCompCmds.c (TclCompileStringCmd):
+	* generic/tclEvent.c (Tcl_UpdateObjCmd):
+	* generic/tclFileName.c (Tcl_GlobObjCmd):
+	* generic/tclIO.c (Tcl_FileEventObjCmd):
+	* generic/tclIOCmd.c (Tcl_SeekObjCmd,Tcl_ExecObjCmd,Tcl_SocketObjCmd,
+	(Tcl_FcopyObjCmd):
+	* generic/tclInterp.c (Tcl_InterpObjCmd,SlaveObjCmd):
+	* generic/tclNamesp.c (Tcl_NamespaceObjCmd):
+	* generic/tclPkg.c (Tcl_PackageObjCmd):
+	* generic/tclTest.c (Tcltest_Init,TestencodingObjCmd,TestgetplatformCmd,
+	(TestlocaleCmd,TestregexpObjCmd,TestsaveresultCmd,
+	(TestGetIndexFromObjStructObjCmd,TestReportFileAttrStrings):
+	* generic/tclTestObj.c (TestindexObjCmd,TeststringObjCmd):
+	* generic/tclTimer.c (Tcl_AfterObjCmd):
+	* generic/tclVar.c (Tcl_ArrayObjCmd):
+	* mac/tclMacFCmd.c (SetFileFinderAttributes):
+	* unix/tclUnixChan.c (TclpOpenFileChannel):
+	* unix/tclUnixFCmd.c (tclpFileAttrStrings):
+	* unix/tclUnixFile.c (TclpObjAccess,TclpObjChdir,TclpObjStat,
+	(TclpObjLstat):
+	* win/tclWinFCmd.c (tclpFileAttrStrings): Updated callers.
+
+	* doc/RegExp.3:
+	* doc/Utf.3:
+	* generic/tcl.decls:
+	* generic/tclInt.decls:
+	* generic/tclRegexp.c:
+	* generic/tclUtf.c:  Updated APIs in generic/tclUtf.c and
+	generic/tclRegexp.c according to the guidelines of TIP 27.
+	[Patch 471509]
+
+	* generic/regc_locale.c (element,cclass):
+	* generic/tclCmdMZ.c (Tcl_StringObjCmd):
+	* generic/tclFileName.c (TclpGetNativePathType,SplitMacPath):
+	* generic/tclIO.c (ReadChars):
+	* mac/tclMacLoad.c (TclpLoadFile):
+	* win/tclWinFile.c (TclpGetUserHome): Updated callers.
+
+	* generic/tclDecls.h:
+	* generic/tclIntDecls.h: make genstubs
+
+	* doc/ParseCmd.3 (Tcl_ParseVar):
+	* generic/tcl.decls (Tcl_ParseVar):
+	* generic/tclParse.c (Tcl_ParseVar):
+	* generic/tclTest.c (TestparsevarObjCmd): Updated APIs in
+	generic/tclParse.c according to the guidelines of TIP 27. Updated
+	callers. [Patch 501046]
+	* generic/tclDecls.h: make genstubs
+
+	* generic/tcl.decls (Tcl_RecordAndEval):
+	* generic/tclDecls.h: make genstubs
+	* generic/tclHistory.c (Tcl_RecordAndEval): Updated APIs in
+	generic/tclHistory.c according to the guidelines of TIP 27.
+	[Patch 504091]
+
+	* doc/CrtSlave.3:
+	* generic/tcl.decls (Tcl_CreateAlias, Tcl_CreateAliasObj,
+	(Tcl_CreateSlave, Tcl_GetAlias, Tcl_GetAliasObj, Tcl_GetSlave):
+	* generic/tclInterp.c (Tcl_CreateAlias, Tcl_CreateAliasObj,
+	(Tcl_CreateSlave, Tcl_GetAlias, Tcl_GetAliasObj, Tcl_GetSlave):
+	Updated APIs in the file generic/tclInterp.c according to the
+	guidelines of TIP 27. [Patch 501371]
+	***POTENTIAL INCOMPATIBILITY***
+	Includes a source incompatibility in the targetCmdPtr arguments of the
+	Tcl_GetAlias* routines.
+
+	* generic/tclDecls.h: make genstubs
+
+2002-01-15  Don Porter <dgp@users.sourceforge.net>
+
+	* doc/SetErrno.3 (Tcl_ErrnoMsg): Corrected documentation for
+	Tcl_ErrnoMsg; it takes an integer argument. Thanks to Georgios
+	Petasis. [Bug 468183]
+
+	* doc/AddErrInfo.3 (Tcl_PosixError):
+	* doc/Eval.3 (Tcl_EvalFile):
+	* doc/FileSystem.c (Tcl_FSOpenFileChannel,Tcl_FSOpenFileChannelProc):
+	* doc/OpenFileChnl.3 (Tcl_OpenFileChannel):
+	* doc/SetErrno.3 (Tcl_ErrnoId,Tcl_ErrnoMsg):
+	* doc/Signal.3 (Tcl_SignalId,Tcl_SignalMsg):
+	* generic/tcl.decls (Tcl_ErrnoId,TclErrnoMsg,Tcl_EvalFile,
+	(Tcl_OpenFileChannel,Tcl_PosixError,Tcl_SignalId,Tcl_SignalMsg,
+	(Tcl_FSOpenFileChannel):
+	* generic/tcl.h (Tcl_FSOpenFileChannelProc):
+	* generic/tclIO.c (FlushChannel):
+	* generic/tclIOUtil.c (Tcl_OpenFileChannel,Tcl_EvalFile,TclGetOpenMode,
+	(Tcl_PosixError,Tcl_FSOpenFileChannel):
+	* generic/tclInt.decls (TclGetOpenMode):
+	* generic/tclInt.h (TclOpenFileChannelProc_,TclGetOpenMode,
+	(TclpOpenFileChannel):
+	* generic/tclPipe.c (TclCleanupChildren):
+	* generic/tclPosixStr.c (Tcl_ErrnoId,Tcl_ErrnoMsg,Tcl_SignalId,
+	(Tcl_SignalMsg):
+	* generic.tclTest.c (PretendTclpOpenFileChannel,
+	(TestOpenFileChannelProc1,TestOpenFileChannelProc2,
+	(TestOpenFileChannelProc3,TestReportOpenFileChannel):
+	* mac/tclMacChan.c (TclpOpenFileChannel):
+	* unix/tclUnixChan.c (TclpOpenFileChannel):
+	* win/tclWinChan.c (TclpOpenFileChannel): Updated APIs in
+	generic/tclIOUtil.c and generic/tclPosixStr.c according to the
+	guidelines of TIP 27. Updated callers. [Patch 499196]
+
+	* generic/tclDecls.h:
+	* generic/tclIntDecls.h: make genstubs
+
+	* doc/CrtChannel.3:
+	* doc/OpenFileChnl.3:
+	* generic/tcl.decls:
+	* generic/tclIO.h:
+	* generic/tclIO.c (DoWrite, Tcl_RegisterChannel, Tcl_GetChannel,
+	(Tcl_CreateChannel, Tcl_GetChannelName, CloseChannel, Tcl_Write,
+	(Tcl_WriteRaw, Tcl_Ungets, Tcl_BadChannelOption, Tcl_GetChannelOption,
+	(Tcl_SetChannelOption, Tcl_GetChannelNamesEx, Tcl_ChannelName):
+	Updated APIs in the file generic/tclIO.c according to the guidelines
+	of TIP 27. Several minor documentation corrections as well.
+	[Patch 503565]
+	* generic/tclDecls.h: make genstubs
+
+	* generic/tcl.h (Tcl_DriverOutputProc, Tcl_DriverGetOptionProc,
+	(Tcl_DriverSetOptionProc):
+	* generic/tclIOGT.c (TransformOutputProc, TransformGetOptionProc,
+	(TransformSetOptionProc):
+	* mac/tclMacChan.c (FileOutput, StdIOOutput):
+	* man/tclMacSock.c (TcpGetOptionProc, TcpOutput):
+	* unix/tclUnixChan.c (FileOutputProc, TcpGetOptionProc, TcpOutputProc,
+	(TtyGetOptionProc, TtySetOptionProc):
+	* unix/tclUnixPipe.c (PipeOuputProc):
+	* win/tclWinChan.c (FileOutputProc):
+	* win/tclWinConsole.c (ConsleOutputProc):
+	* win/tclWinPipe.c (PipeOuputProc):
+	* win/tclWinSerial.c (SerialOutputProc, SerialGetOptionProc,
+	(SerialSetOptionProc):
+	* win/tclWinSock.c (TcpGetOptionProc, TcpOutput): Updated channel
+	driver interface according to the guidelines of TIP 27. See also
+	[Bug 500348].
+
+	* doc/CrtChannel.3:
+	* generic/tcl.h:
+	* generic/tclIO.c:
+	* generic/tclIO.h:
+	* generic/tclInt.h:
+	* tools/checkLibraryDoc.tcl:
+	Moved Tcl_EolTranslation enum declaration from generic/tcl.h to
+	generic/tclInt.h (renamed to TclEolTranslation). It is not used
+	anywhere in Tcl's public interface.
+
+2002-01-14  Don Porter <dgp@users.sourceforge.net>
+
+	* doc/GetIndex.3:
+	* doc/WrongNumArgs.3:
+	* generic/tcl.decls (Tcl_GetIndexFromObj, Tcl_GetIndexFromObjStruct,
+	(Tcl_WrongNumArgs):
+	* generic/tclIndexObj.c (Tcl_GetIndexFromObj,Tcl_GetIndexFromObjStruct,
+	(Tcl_WrongNumArgs): Updated APIs in the file generic/tclIndexObj.c
+	according to the guidelines of TIP 27. [Patch 501491]
+	* generic/tclDecls.h: make genstubs
+
+2002-01-11  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* unix/configure: Regen.
+	* unix/configure.in:
+	* win/configure: Regen.
+	* win/configure.in: Use ${libdir} instead of ${exec_prefix}/lib
+	to properly support the --libdir option to configure. [Bug 489370]
+
+2002-01-11  Andreas Kupries  <andreas_kupries@users.sourceforge.net>
+
+	* win/tclWinSerial.c (SerialSetOptionProc): Applied patch for [Bug
+	500348] supplied by Rolf Schroedter <schroedter@users.sf.net>. The
+	function modified the contents of the the 'value' string and now does
+	not do this anymore. This is a followup to the change made on
+	2001-12-17.
+
+2002-01-11  David Gravereaux <davygrvy@pobox.com>
+
+	* win/makefile.vc: Removed -GD compiler option. It was intended for
+	future use, but MS is again changing the future at their whim. The
+	D4002 warning was harmless though, but someone using VC .NET logged it
+	as a concern. [Bug 501565]
+
+2002-01-11  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* unix/Makefile.in: Burn Tcl build directory into tcltest executable
+	to avoid crashes caused by ld loading a previously installed version
+	of the tcl shared library. [Bug 218110]
+
+2002-01-10  Don Porter <dgp@users.sourceforge.net>,
+	Kevin Kenny <kennykb@users.sourceforge.net>
+
+	* unix/tclLoadDld.c (TclpLoadFile):  syntax error: unbalanced parens.
+	Kevin notes that it's far from clear that this file is ever included
+	in an actual build; Linux without dlopen appears to be a nonexistent
+	configuration.
+
+2002-01-08  Don Porter <dgp@users.sourceforge.net>,
+	Kevin Kenny <kennykb@users.sourceforge.net>
+
+	* doc/StaticPkg.3 (Tcl_StaticPackage):
+	* generic/tcl.decls (Tcl_StaticPackage):
+	* generic/tclDecls.h (Tcl_StaticPackage):
+	* generic/tclInt.decls (TclGuessPackageName):
+	* generic/tclInt.h (TclGuessPackageName):
+	* generic/tclLoad.c (Tcl_StaticPackage):
+	* generic/tclLoadNone.c (TclGuessPackageName):
+	* mac/tclMacLoad.c (TclGuessPackageName):
+	* unix/tclLoadAout.c (TclGuessPackageName):
+	* unix/tclLoadDl.c (TclGuessPackageName):
+	* unix/tclLoadDld.c (TclGuessPackageName):
+	* unix/tclLoadDyld.c (TclGuessPackageName):
+	* unix/tclLoadNext.c (TclGuessPackageName):
+	* unix/tclLoadOSF.c (TclGuessPackageName):
+	* unix/tclLoadShl.c (TclGuessPackageName):
+	* win/tclWinLoad.c (TclGuessPackageName):  Updated APIs in the files
+	*/tcl*Load*.c according to the guidelines of TIP 27. [Patch 501096]
+
+2002-01-09  Don Porter <dgp@users.sourceforge.net>
+
+	* generic/tclTest.c (MainLoop):
+	* tests/main.test (Tcl_Main-1.{3,4,5,6}):  Corrected some non-portable
+	tests from the new Tcl_Main changes. Thanks to Kevin Kenny.
+
+2002-01-07  Don Porter <dgp@users.sourceforge.net>
+
+	* generic/tclEvent.c (TclInExit):
+	* generic/tclIOUtil.c (SetFsPathFromAbsoluteNormalized,
+	(SetFsPathFromAny,Tcl_FSNewNativePath,DupFsPathInternalRep):
+	* generic/tclListObj.c (TclLsetList,TclLsetFlat):  Added some type
+	casts to satisfy picky compilers.
+
+	* generic/tclMain.c:  Bug fix: neglected the NULL case in
+	TclGetStartupScriptFileName(). Broke Tk/wish.
+
+2002-01-05  Don Porter <dgp@users.sourceforge.net>
+
+	* doc/Tcl_Main.3:
+	* generic/tclMain.c:  Substantial rewrite and expanded documentation
+	of Tcl_Main to correct a number of bugs and flaws:
+
+	  - Interactive Tcl_Main can now enter a main loop, exit that loop and
+	    continue interactive operations. The loop may even exit in the
+	    midst of interactive command typing without loss of the partial
+	    command. [Bugs 486453, 474131]
+	  - Tcl_Main now gracefully handles deletion of its master
+	    interpreter.
+	  - Interactive Tcl_Main can now operate with non-blocking stdin
+	  - Interactive Tcl_Main can now detect EOF on stdin even in
+	    mid-command. [Bug 491341]
+	  - Added VFS-aware internal routines for managing the startup script
+	    selection.
+	  - Tcl variable 'tcl_interactive' is now linked to C variable 'tty'
+	    so that one can disable/enable interactive prompts at the script
+	    level when there is no startup script. This is meant for use by
+	    the test suite.
+	  - Consistent use of the Tcl libraries standard channels as returned
+	    by Tcl_GetStdChannel(); as opposed to the channels named 'stdin',
+	    'stdout', and 'stderr' in the master interp, which can be
+	    different or unavailable.
+	  - Tcl_Main now calls Tcl_Exit() if evaluation of [exit] in the
+	    master interpreter returns, assuring Tcl_Main does not return.
+	  - Documented Tcl_Main's absence from public stub table
+	  - Documented that Tcl_Main does not return.
+	  - Documented Tcl variables set by Tcl_Main.
+	  - All prompts are done from a single procedure, Prompt.
+	  - Use of Tcl_Obj-enabled interfaces everywhere.
+
+	* generic/tclInt.decls (TclGetStartupScriptPath,
+	(TclSetStartupScriptPath): New internal VFS-aware routines for
+	managing the startup script of Tcl_Main.
+	* generic/tclIntDecls.h:
+	* generic/tclStubInit.c: make genstubs
+
+	* generic/tclTest.c (TestsetmainloopCmd,TestexitmainloopCmd,
+	(Tcltest_Init,TestinterpdeleteCmd):
+	* tests/main.test (new):  Added new file to test suite that thoroughly
+	tests generic/tclMain.c; added some new test commands for testing
+	Tcl_SetMainLoop().
+
+2002-01-04  Don Porter <dgp@users.sourceforge.net>
+
+	* doc/Alloc.3:
+	* doc/Concat.3:
+	* doc/CrtMathFnc.3:
+	* doc/Hash.3:
+	* doc/Interp.3:
+	* doc/LinkVar.3:
+	* doc/ObjectType.3:
+	* doc/PkgRequire.3:
+	* doc/Preserve.3:
+	* doc/SetResult.3:
+	* doc/SplitList.3:
+	* doc/SplitPath.3:
+	* doc/TCL_MEM_DEBUG.3: Updated documentation to describe the ckalloc,
+	ckfree, ckrealloc, attemptckalloc, and attemptckrealloc macros, and
+	to accurately describe when and how they are used. [Bug 497459]
+
+	* generic/tclThreadJoin.c (TclRememberJoinableThread,TclJoinThread):
+	Replaced Tcl_Alloc and Tcl_Free calls with ckalloc and ckfree so that
+	memory debugging is supported.
+
+2002-01-04  Daniel Steffen <das@users.sourceforge.net>
+
+	* mac/tclMacTime.c (TclpGetTZName): fix for daylight savings TZName bug
+
+2002-01-03  Don Porter <dgp@users.sourceforge.net>
+
+	* doc/FileSystem.3:
+	* generic/tclIOUtil.c: Updated some old uses of "fileName" to
+	new VFS terminology, "pathPtr".
+
+2002-01-03  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* tests/basic.test (basic-39.4): Greatly simplified test while
+	still leaving it so that it crashes when run without the fix to
+	the [foreach] implementation.
+	* generic/tclCmdAH.c (Tcl_ForeachObjCmd): Stopped [Bug 494348] from
+	happening by not trying to be so clever with cacheing; if nothing
+	untoward is happening anyway, the less efficient technique will
+	only add a few instruction cycles (one function call and a few
+	derefs/assigns per list per iteration, with no change in the
+	number of tests) and if something odd *is* going on, the code is
+	now far more robust.
+
+	* tests/basic.test (basic-39.4): Reproducable script from [Bug 494348]
+
+2002-01-02  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* tests/util.test (Wrapper_Tcl_StringMatch,util-5.*): Rewrote so the
+	test is performed with the right internal function since [string
+	match] no longer uses Tcl_StringCaseMatch internally.
+
+	* tests/string.test (string-11.51):
+	* generic/tclUtf.c (Tcl_UniCharCaseMatch):
+	* generic/tclUtil.c (Tcl_StringCaseMatch): Fault with matching
+	case-insensitive non-ASCII patterns containing upper case characters.
+	[Bug 233257]
+
+	******************************************************************
+	*** CHANGELOG ENTRIES FOR 2001 IN "ChangeLog.2001"             ***
+	*** CHANGELOG ENTRIES FOR 2000 IN "ChangeLog.2000"             ***
+	*** CHANGELOG ENTRIES FOR 1999 AND EARLIER IN "ChangeLog.1999" ***
+	******************************************************************
diff --git a/ChangeLog.2003 b/ChangeLog.2003
new file mode 100644
index 0000000..c586ba9
--- /dev/null
+++ b/ChangeLog.2003
@@ -0,0 +1,3349 @@
+2003-12-25  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* win/tclWin32Dll.c (DllMain): Add HAVE_NO_SEH blocks in place of
+	__try and __except statements to support gcc builds. This is needed
+	after David's changes on 2003-12-21. [Patch 858493]
+
+2003-12-23  David Gravereaux <davygrvy@pobox.com>
+
+	* generic/tclAlloc.c:	All uses of 'panic' (the macro) changed to
+	* generic/tclBasic.c:	'Tcl_Panic' (the function). The #define of
+	* generic/tclBinary.c:	panic in tcl.h clearly states it is deprecated
+	* generic/tclCkalloc.c:	in the comments. [Patch 865264]
+	* generic/tclCmdAH.c:
+	* generic/tclCmdIL.c:
+	* generic/tclCmdMZ.c:
+	* generic/tclCompCmds.c:
+	* generic/tclCompExpr.c:
+	* generic/tclCompile.c:
+	* generic/tclConfig.c:
+	* generic/tclDictObj.c:
+	* generic/tclEncoding.c:
+	* generic/tclEvent.c:
+	* generic/tclExecute.c:
+	* generic/tclHash.c:
+	* generic/tclInterp.c:
+	* generic/tclIO.c:
+	* generic/tclIOCmd.c:
+	* generic/tclIOUtil.c:
+	* generic/tclListObj.c:
+	* generic/tclLiteral.c:
+	* generic/tclNamesp.c:
+	* generic/tclObj.c:
+	* generic/tclParse.c:
+	* generic/tclPathObj.c:
+	* generic/tclPkg.c:
+	* generic/tclPreserve.c:
+	* generic/tclProc.c:
+	* generic/tclStringObj.c:
+	* generic/tclTest.c:
+	* generic/tclThreadAlloc.c:
+	* generic/tclTimer.c:
+	* generic/tclTrace.c:
+	* generic/tclVar.c:
+	* mac/tclMacChan.c:
+	* mac/tclMacOSA.c:
+	* mac/tclMacResource.c:
+	* mac/tclMacSock.c
+	* mac/tclMacThrd.c:
+	* unix/tclUnixChan.c:
+	* unix/tclUnixNotfy.c:
+	* unix/tclUnixThrd.c:
+	* unix/tclXtNotify.c:
+	* win/tclWin32Dll.c:
+	* win/tclWinChan.c:
+	* win/tclWinFCmd.c:
+	* win/tclWinNotify.c:
+	* win/tclWinPipe.c:
+	* win/tclWinSock.c:
+	* win/tclWinThrd.c:
+
+	* generic/tclInt.h:  Deprecated use of Tcl_Ckalloc changed to
+	Tcl_Alloc in the TclAllocObjStorage macro.
+
+2003-12-22  David Gravereaux <davygrvy@pobox.com>
+
+	* win/nmakehlp.c:
+	* win/rules.vc:  New feature for extensions that use rules.vc. Now
+	reads header files for version strings. No more hard coding
+	TCL_VERSION = 8.5 and having to edit it when you swap cores.
+
+	* win/makefile.vc: VERSION macro now set by reading tcl.h for it.
+
+	* generic/tcl.h: Removed note that makefile.vc needs to have a version
+	number changed.
+
+2003-12-21  David Gravereaux <davygrvy@pobox.com>
+
+	* win/tclWin32Dll.c: Structured Exception Handling added around
+	Tcl_Finalize called from DllMain's DLL_PROCESS_DETACH. We can't be
+	100% assured that Tcl is being unloaded by the OS in a stable
+	condition and we need to protect the exit handlers should the stack be
+	in a hosed state. AT&T style assembly for SEH under MinGW has not been
+	added yet. This is a first part change for [Patch 858493]
+
+2003-12-17  Daniel Steffen  <das@users.sourceforge.net>
+
+	* generic/tclBinary.c (DeleteScanNumberCache): fixed crashing bug when
+	numeric scan-value cache contains NULL value.
+
+2003-12-17  Vince Darley  <vincentdarley@users.sourceforge.net>
+
+	* generic/tclCmdAH.c:
+	* unix/tclUnixFile.c:
+	* win/tclWinFCmd.c:
+	* tests/fCmd.test:
+	* tests/fileSystem.test:
+	* doc/file.n: final fix to support for relative links and its
+	implications on normalization and other parts of the filesystem code.
+	Fixes [Bug 859251] and some Windows problems with recursive file
+	delete/copy and symbolic links.
+
+2003-12-17  Vince Darley  <vincentdarley@users.sourceforge.net>
+
+	* generic/tclPathObj.c:
+	* tests/fileSystem.test: fix and tests for [Bug 860402] in new file
+	normalization code.
+
+2003-12-17  Zoran Vasiljevic  <zv@archiware.com>
+
+	* generic/tclIOUtil.c: fixed 2 memory (object) leaks. [Bug 839519]
+
+	* generic/tclPathObj.c: fixed Tcl_FSGetTranslatedPath to always return
+	properly refcounted path object. [Bug 861515]
+
+2003-12-16  Vince Darley  <vincentdarley@users.sourceforge.net>
+
+	* tests/fCmd.test: marking fCmd-9.14.2, as nonPortable, since on
+	Solaris one can change the name of the current directory with 'file
+	rename'.
+	* doc/FileSystem.3: clarified documentation on ownership of return
+	objects/strings of some Tcl_FS* calls.
+
+2003-12-16  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* generic/tclThreadAlloc.c (binfo): Made variable file-local.
+
+2003-12-15  David Gravereaux <davygrvy@pobox.com>
+
+	* win/tcl.rc:
+	* win/tclsh.rc: Slight modification to the STRINGIFY macro to support
+	Borland's rc tool.
+
+	* win/tclWinFile.c (TclpUtime) : utimbuf struct not a problem with
+	Borland.
+
+	* win/tclWinTime.c (TclpGetDate) : Borland's localtime() has a slight
+	behavioral difference.
+
+	From Helmut Giese <hgiese@ratiosoft.com> [Patch 758097].
+
+2003-12-14  David Gravereaux <davygrvy@pobox.com>
+
+	* generic/tclInt.decls: commented-out entry for TclpCheckStackSpace,
+	removing it from the Stubs table. It's already declared in tclInt.h
+	and labeled as a function that is not to be exported. Regened tables.
+
+2003-12-14  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* generic/tclCmdMZ.c (Tcl_SwitchObjCmd): TIP#75 Implementation
+	* tests/switch.test:	Can now get submatch information when using
+	* doc/switch.n:		-regexp matching in [switch].
+
+2003-12-14  Vince Darley  <vincentdarley@users.sourceforge.net>
+
+	* generic/tclPathObj.c: complete rewrite of generic file normalization
+	code to cope with links followed by '..'. [Bug 849514], and parts of
+	[Bug 859251]
+
+2003-12-12  David Gravereaux <davygrvy@pobox.com>
+
+	* win/tclWinChan.c: Win32's SetFilePointer() takes LONGs not DWORDs (a
+	signed/unsigned mismatch). Redid local vars to avoid all casting
+	except where truly required.
+
+2003-12-12  Vince Darley  <vincentdarley@users.sourceforge.net>
+
+	* generic/tclCmdAH.c: fix to normalization of non-existent user name
+	('file normalize ~nobody') [Bug 858937]
+	* doc/file.n: clarify behaviour of 'file link' when the target is not
+	an absolute path.
+	* doc/filename.n: correct documentation to say that Windows Tcl does
+	handle '~user', for recent Windows releases, and clarified distinction
+	between MacOS 'classic' and MacOS X.
+	* doc/glob.n: clarification of glob's behaviour when returning
+	filenames starting with a '~'.
+
+	* tests/fileSystem.test:
+	* tests/fileName.test: new tests added for the normalization problem
+	above and other recentlt reported issues.
+
+	* win/tclWinFile.c: corrected unclear comments
+
+	* unix/tclUnixFile.c: allow creation of relative links. [Bug 833713]
+
+2003-12-11  David Gravereaux <davygrvy@pobox.com>
+
+	* win/tclWinSock.c (SocketThreadExitHandler) : added a TerminateThread
+	fallback just in case the socket handler thread is really in a paused
+	state. This can happen when Tcl is being unloaded by the OS from an
+	exception handler. See MSDN docs on DllMain, it states this behavior.
+
+2003-12-09  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* unix/configure:
+	* unix/tcl.m4: updated OpenBSD build configuration based on
+	[Patch #775246] (cassoff)
+
+2003-12-09  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* unix/tclUnixPort.h:	#ifdef'd out declarations of errno which are
+	* tools/man2tcl.c:	known to cause problems with recent glibc.
+				[Bug 852369]
+
+2003-12-09  Vince Darley  <vincentdarley@users.sourceforge.net>
+
+	* win/tclWinFile.c: fix to NT file permissions code [Bug 855923]
+	* tests/winFile.test: added tests for NT file permissions - patch and
+	test scripts supplied by Benny.
+
+	* tests/winFCmd.test: fixed one test for when not running in C:/
+
+2003-12-02  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* generic/tclBinary.c (DeleteScanNumberCache, ScanNumber): Made the
+	numeric scan-value cache have proper references to the objects within
+	it so strange patterns of writes won't cause references to freed
+	objects. Thanks to Paul Obermeir for the report. [Bug 851747]
+
+2003-12-01  Miguel Sofer <msofer@users.sf.net>
+
+	* doc/lset.n: fix typo [Bug 852224]
+
+2003-11-24  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclParse.c:	Corrected faulty check for trailing white
+	space in {expand} parsing. Thanks Andreas Leitgeb. [Bug 848262]
+	* tests/parse.test: 	New tests for the bug.
+
+2003-11-24  Vince Darley  <vincentdarley@users.sourceforge.net>
+
+	* generic/tclPathObj.c: fix to [Bug 845778] - Infinite recursion on
+	[cd] (Windows only bug), for which new tests have just been added.
+
+2003-11-21  Don Porter	<dgp@users.sourceforge.net>
+
+	* tests/winFCmd.test (winFCmd-16.10,11): Merged new tests from
+	core-8-4-branch.
+
+2003-11-20  Miguel Sofer <msofer@users.sf.net>
+
+	* generic/tclVar.c: fix flag bit collision between LOOKUP_FOR_UPVAR
+	and TCL_PARSE_PART1 (deprecated) [Bug 835020]
+
+2003-11-19  Don Porter	<dgp@users.sourceforge.net>
+
+	* tests/compile.test (compile-16.22.0):	Improved test for the recent
+	fix for Bug 845412.
+
+2003-11-19  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* generic/tclCompile.c (TclCompileScript): Added a guard for the
+	expansion code so that long non-expanding commands don't get expansion
+	infrastructure inserted in them, especially when that infrastructure
+	isn't initialised. [Bug 845412]
+
+2003-11-18  David Gravereaux <davygrvy@pobox.com>
+
+	* contrib/djgpp/Makefile:		Changes from Victor Wagner
+	* contrib/djgpp/langinfo.c (new):	<vitus@45.free.net> for better
+	* contrib/djgpp/langinfo.h (new):	DJGPP support.
+	* unix/tclUnixInit.c:			.
+	* unix/tclUnixChan.c:			.
+	* unix/tclUnixFCmd.c:			.
+
+2003-11-17  Don Porter	<dgp@users.sourceforge.net>
+
+	* tests/reg.test: Added tests for [Bugs 230589, 504785, 505048, 840258]
+	recently fixed by 2003-11-15 commit to regcomp.c by Pavel Goran. His
+	notes on the fix: This bug results from an error in code that splits
+	states into "progress" and "no-progress" ones. This error causes an
+	interesting situation with the pre-collected single-linked list of
+	states to be splitted: many items were added to the list, but only
+	several of them are accessible from the list beginning, since the
+	"tmp" member of struct state (which is used here to hold a pointer to
+	the next list item) gets overwritten, which results in a "looped"
+	chain. As a result, not all of states are splitted, and one state is
+	splitted two times, causing incorrect "no-progress" flag values.
+
+2003-11-16  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* generic/tclExecute.c (TclExecuteByteCode): Make sure that
+	Tcl_AsyncInvoke is called regularly when processing bytecodes.
+	* generic/tclTest.c (AsyncThreadProc, TestasyncCmd): Extended testing
+	harness to send an asynchronous marking without relying on UNIX
+	signals.
+	* tests/async.test (async-4.*): Tests to check that async events are
+	handled by the bytecode core. [Bug 746722]
+
+2003-11-15  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* generic/tclTest.c (TestHashSystemHashCmd): Removed 'const' modifier
+	from hash type structure; it should be const and the hash code assumes
+	it behaves like const, but that's not how the API is defined. Like
+	this, we are following in the same footsteps as Tcl_RegisterObjType()
+	which has the same conditions on its argument. Stops VC++5.2 warning.
+	[Bug 842511]
+
+2003-11-14  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* generic/tclHash.c (Tcl_DeleteHashTable,Tcl_HashStats,RebuildTable):
+	* generic/tclTest.c (TestHashSystemHashCmd): TIP#138 implementation,
+	* tests/misc.test:	plus a new chunk of stuff to test the hash
+				functions more thoroughly in the test suite.
+				[Patch 731356, modified]
+
+	* doc/Tcl.n: Updated Tcl version number and changebars.
+
+2003-11-14  Don Porter	<dgp@users.sourceforge.net>
+
+	* doc/ParseCmd.3:	Implementation of TIP 157.  Adds recognition
+	* doc/Tcl.n:		of the new leading {expand} syntax on words.
+	* generic/tcl.h:	Parses such words as the new Tcl_Token type
+	* generic/tclBasic.c:	TCL_TOKEN_EXPAND_WORD. Updated Tcl_EvalEx and
+	* generic/tclCompile.c: the bytecode compiler/execution engine to
+	* generic/tclCompile.h:	recognize the new token type. New opcodes
+	* generic/tclExecute.c:	INST_LIST_VERIFY and INST_INVOKE_EXP and a new
+	* generic/tclParse.c:	operand type OPERAND_ULIST1 are defined. Docs
+	* generic/tclTest.c:	and tests are included.
+	* tests/basic.test:
+	* tests/compile.test:
+	* tests/parse.test:
+
+	* library/auto.tcl:	Replaced several [eval]s used to perform
+	* library/package.tcl:	argument expansion with the new syntax. In the
+	* library/safe.tcl:	test files lindex.test and lset.test, replaced
+	* tests/cmdInfo.test:	use of [eval] to force direct string
+	* tests/encoding.test:	evaluation with use of [testevalex] which more
+	* tests/execute.test:	directly and robustly serves the same purpose.
+	* tests/fCmd.test:
+	* tests/http.test:
+	* tests/init.test:
+	* tests/interp.test:
+	* tests/io.test:
+	* tests/ioUtil.test:
+	* tests/iogt.test:
+	* tests/lindex.test:
+	* tests/lset.test:
+	* tests/namespace-old.test:
+	* tests/namespace.test:
+	* tests/pkg.test:
+	* tests/pkgMkIndex.test:
+	* tests/proc.test:
+	* tests/reg.test:
+	* tests/trace.test:
+	* tests/upvar.test:
+	* tests/winConsole.test:
+	* tests/winFCmd.test:
+
+2003-11-12  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* tests/cmdMZ.test (cmdMZ-1.4): change to nonPortable as more systems
+	are using permissions caching, and this isn't really a Tcl controlled
+	issue.
+
+2003-11-11  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* unix/configure:
+	* unix/tcl.m4: improve AIX --enable-64bit handling
+	remove -D__NO_STRING_INLINES -D__NO_MATH_INLINES from CFLAGS_OPTIMIZE
+	on Linux. Make default opt -O2 (was -O).
+
+2003-11-11  David Gravereaux <davygrvy@pobox.com>
+
+	* contrib/djgpp/Makefile:  Suggested changes from vitus@45.free.net
+	(Victor Wagner)
+
+	* unix/tclUnixPort.h:  added socklen_t typedef for DJGPP
+
+2003-11-10  Don Porter	<dgp@users.sourceforge.net>
+
+	* unix/tclUnixInit.c (TclpInitLibraryPath):
+	* win/tclWinInit.c (TclpInitLibraryPath):	Fix for [Bug 832657]
+	that should not run afoul of startup constraints.
+
+	* library/dde/pkgIndex.tcl:	Added safeguards so that registry and
+	* library/reg/pkgIndex.tcl:	dde packages are not offered on
+	* win/tclWinDde.c:		non-Windows platforms. Bumped to
+	* win/tclWinReg.c:		registry 1.1.3 and dde 1.3.
+	* win/Makefile.in:
+	* win/configure.in:
+	* win/makefile.bc:
+	* win/makefile.vc:
+
+	* win/configure:	autoconf (2.57)
+
+2003-11-10  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* tests/cmdIL.test: Stopped cmdIL-5.5 from stomping over the test
+	command, and updated the tests to use some tcltest2 features in
+	relation to cleanup. [Bug 838384]
+
+2003-11-10  Vince Darley  <vincentdarley@users.sourceforge.net>
+
+	* generic/tclCmdAH.c:
+	* tests/fCmd.test: fix to misleading error message in 'file link'.
+	[Bug 836208]
+
+2003-11-07  Vince Darley  <vincentdarley@users.sourceforge.net>
+
+	* generic/tclIOUtil.c: fix to compiler warning/error with some
+	compilers. [Bug 835918]
+
+2003-11-07  Daniel Steffen  <das@users.sourceforge.net>
+
+	* macosx/Makefile: optimized builds define NDEBUG to turn off
+	ThreadAlloc range checking.
+
+2003-11-05  Don Porter	<dgp@users.sourceforge.net>
+
+	* tests/unixInit.test (unixInit-2.10):  New test to expose [Bug 832657]
+	failure of TclpInitLibraryPath() to properly handle .. in the path
+	of the executable.
+
+2003-11-04  Daniel Steffen  <das@users.sourceforge.net>
+
+	* macosx/Makefile: added 'test' target.
+
+2003-11-03  Vince Darley  <vincentdarley@users.sourceforge.net>
+
+	* generic/tclIOUtil.c
+	* generic/tclInt.h: added comments and re-arranged code to clarify
+	distinction between Tcl_LoadHandle, ClientData for 'load'ed code, and
+	point out limitations of the design introduced with Tcl 8.4.
+
+	* unix/tclUnixFile.c: fix to memory leak
+
+	* generic/tclCmdIL.c: removed warning on Windows.
+
+2003-11-01  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* generic/tclCmdIL.c (Tcl_LrepeatObjCmd): Check for sensible list
+	lengths and allow for soft failure of the memory subsystem in the
+	[lconcat] command [Bug 829027]. Uses direct list creation to avoid
+	extra copies when working near the limit of available memory. Also
+	reorganized to encourage optimizing compilers to optimize heavily.
+	* generic/tclListObj.c (TclNewListObjDirect): New list constructor
+	that does not copy the array of objects. Useful for creating
+	potentially very large lists or where you are about to throw away the
+	array argument which is being used in its entirety.
+
+2003-10-28  Miguel Sofer <msofer@users.sf.net>
+
+	* generic/tclExecute.c (NEXT_INST macros): replaced macro variable
+	"result" by "resultHandling" to avoid confusion.
+
+2003-10-23  Andreas Kupries  <andreask@activestate.com>
+
+	* unix/tclUnixChan.c (Tcl_MakeFileChannel): Applied [Patch 813606]
+	fixing [Bug 813087]. Detection of sockets was off for Mac OS X which
+	implements pipes as local sockets. The new code ensures that only IP
+	sockets are detected as such.
+
+	* win/tclWinSock.c (TcpWatchProc): Watch for FD_CLOSE too when asked
+	for writable events by the generic layer.
+	(SocketEventProc): Generate a writable event too when a close is
+	detected.
+
+	  Together the changes fix [Bug 599468].
+
+2003-10-23  Vince Darley  <vincentdarley@users.sourceforge.net>
+
+	* tests/resource.test:
+	* mac/tclMacResource.c: fix to resource freeing problem in 'resource'
+	command reported by Bernard Desgraupes.
+
+	* doc/FileSystem.3: updated documentation for 'glob' fix on 2003-10-13
+	below
+
+2003-10-22  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* generic/tclCmdAH.c (Tcl_FileObjCmd): Changed FILE_ prefix to FCMD_
+	to stop symbol/#def clashes on Cygwin/Mingw32 on NT. [Bug 822528]
+
+2003-10-21   Daniel Steffen  <das@users.sourceforge.net>
+
+	* tools/tcltk-man2html.tcl: fixed incorrect html generated for
+	.IP/.TP lists, now use <DL><DT>...<DD>...<P><DT>...<DD>...</DL>
+	instead of illegal  <DL><P><DT>...<DD>...<P><DT>...<DD>...</DL>.
+	Added skipping of directives directly after .TP to avoid them being
+	used as item descriptions, e.g. .TP\n.VS in clock.n.
+
+2003-10-21  Andreas Kupries  <andreask@pliers.activestate.com>
+
+	* win/tclWinPipe.c (BuildCommandLine): Applied the patch coming with
+	[Bug 805605] to the code, fixing the incorrect use of ispace noted by
+	Ronald Dauster <ronaldd@users.sourceforge.net>.
+
+2003-10-20  Kevin B. Kenny  <kennykb@users.sourceforge.net>
+
+	* doc/msgcat.n:
+	* library/msgcat/msgcat.tcl (mclocale,mcload):
+	* tools/tcl.wse.in:
+	* unix/Makefile.in:     Implementation of TIP#156, add a "root locale"
+	* win/makefile.bc:      to the 'msgcat' package. Advanced msgcat
+	* win/Makefile.in:      version number to 1.4
+	* win/Makefile.vc:
+
+2003-10-15  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* generic/tclCmdIL.c (SortInfo,etc): Reorganized so that SortInfo
+	carries an array of integer indices instead of a Tcl list. This nips
+	shimmering problems in the bud and simplifies SelectObjFromSublist at
+	the cost of making setup slightly more complex. [Bug 823768]
+
+2003-10-14  David Gravereaux <davygrvy@pobox.com>
+
+	* win/tclAppInit.c (sigHandler): Punt gracefully if exitToken has
+	already been destroyed.
+
+2003-10-14  Vince Darley  <vincentdarley@users.sourceforge.net>
+
+	* generic/tclCmdMZ.c:
+	* tests/regexp.test: fix to [Bug 823524] in regsub; added three new
+	tests.
+
+2003-10-14  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclBasic.c (TclAppendObjToErrorInfo):	New internal routine
+	that appends a Tcl_Obj to the errorInfo, saving the caller the trouble
+	of extracting the string rep.
+
+	* generic/tclStringObj.c (TclAppendLimitedToObj):	New internal
+	routine that supports truncated appends with optional ellipsis marking.
+	This single routine supports UTF-8-safe truncated appends needed in
+	several places throughout the Tcl source code, mostly for error and
+	stack messages. Clean fix for [Bug 760872].
+
+	* generic/tclInt.h:	Declarations for new internal routines.
+
+	* generic/tclCmdMZ.c:	Updated callers to use the new routines.
+	* generic/tclCompExpr.c:
+	* generic/tclCompile.c:
+	* generic/tclExecute.c:
+	* generic/tclIOUtil.c:
+	* generic/tclNamesp.c:
+	* generic/tclObj.c:
+	* generic/tclParseExpr.c:
+	* generic/tclProc.c:
+	* generic/tclStringObj.c:
+	* mac/tclMacResource.c:
+
+	* library/init.tcl:	Updated ::errorInfo cleanup in [unknown] to
+	reflect slight modifications to Tcl_LogCommandInfo(). Corrects failing
+	init-4.* tests.
+
+2003-10-14  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	TIP#127 IMPLEMENTATION FROM JOE MICHAEL SCHLENKER
+
+	* generic/tclCmdIL.c (SelectObjFromSublist): Element selection engine.
+	* generic/tclCmdIL.c (Tcl_LsearchObjCmd, Tcl_LsortObjCmd):
+	* tests/lsearch.test:	Set up and use of element selection engine,
+	* tests/cmdIL.test:	plus tests and documentation.
+	* doc/lsearch.n:	Based on [Patch 693836]
+	* doc/lsort.n:
+
+2003-10-13  Vince Darley  <vincentdarley@users.sourceforge.net>
+
+	* generic/tcl.h:
+	* generic/tclFileName.c:
+	* generic/tclIOUtil.c:
+	* generic/tclPathObj.c:
+	* generic/tclTest.c:
+	* mac/tclMacFile.c:
+	* tests/fileName.test: better tests for [Bug 813273]
+	* unix/tclUnixFCmd.c:
+	* unix/tclUnixFile.c:
+	* win/tclWin32Dll.c:
+	* win/tclWinFCmd.c:
+	* win/tclWinFile.c:
+	* win/tclFileInt.h:
+
+	Fixed [Bug 800106] in which 'glob' was incapable of merging the
+	results of a directory listing (real or virtual) and any virtual
+	filesystem mountpoints in that directory (the latter were ignored).
+	This meant boundaries between different filesystems were not seamless
+	(e.g. 'glob */*' across a filesystem boundary was wrong). Added new
+	entry to Tcl_GlobTypeData in a totally backwards compatible way. To
+	allow listing of mounts, registered filesystems must support the
+	'TCL_GLOB_TYPE_MOUNT' flag. If this is not supported (e.g. in tclvfs
+	1.2) then mounts will simply not be listed for that filesystem.
+
+	Fixed [Bug 749876] 'file writable/readable/etc' (NativeAccess) using
+	correct permission checking code for Windows NT/2000/XP where more
+	complex user-based security/access priveleges are available,
+	particularly on shared volumes. The performance impact of this extra
+	checking will need further investigation. Note: Win 95,98,ME have no
+	support for this.
+
+	Also made better use of normalized rather than translated paths in the
+	platform specific code.
+
+2003-10-12  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* unix/tclUnixTest.c (TestalarmCmd): don't bother checking return
+	value of alarm. [Bug #664755] (english)
+
+2003-10-09  Pat Thoyts  <patthoyts@users.sourceforge.net>
+
+	* win/makefile.vc:  Applied patches for bug #801467 by Joe Mistachkin
+	* win/tclAppInit.c: to fix incompatible TCL_MEM_DEBUG handling in
+	* generic/tclObj.c: Win32 VC builds.
+
+2003-10-08  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclBasic.c:	Save and restore the iPtr->flag bits that
+	control the state of errorCode and errorInfo management when calling
+	"leave" execution traces, so that all error information of the traced
+	command is still available whether traced or not. [Bug 760947]
+	Thanks to Yahalom Emet.
+
+2003-10-08  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* generic/tclTest.c (TestNumUtfCharsCmd): Command to allow finer
+	access to Tcl_NumUtfChars for testing.
+	* generic/tclUtf.c (Tcl_NumUtfChars): Corrected string length
+	determining when the length parameter is negative; the terminator is a
+	zero byte, not (necessarily) a \u0000 character. [Bug 769812]
+
+2003-10-07  Don Porter	<dgp@users.sourceforge.net>
+
+	* tests/cmdAH.test:
+	* tests/exec.test:		Corrected temporary file management
+	* tests/fileSystem.test:	issues uncovered by -debug 1 test
+	* tests/io.test:		operations. Also backported some
+	* tests/ioCmd.test:		other fixes from the HEAD.
+	* tests/main.test:
+	* tests/pid.test:		[Bugs 675605, 675655, 675659]
+	* tests/socket.test:
+	* tests/source.test:
+
+	* tests/fCmd.test:	Run tests with the [temporaryDirectory] as the
+	current directory, so that tests can depend on ability to write files.
+	[Bug 575837]
+
+	* doc/OpenFileChnl.3:	Updated Tcl_Tell and Tcl_Seek documentation to
+	reflect that they now return Tcl_WideInt (TIP 72). [Bug 787537]
+
+	* tests/io.test:	Corrected several tests that failed when paths
+	* tests/ioCmd.test:	included regexp-special chars. [Bug 775394]
+
+2003-10-06  Jeff Hobbs	<jeffh@ActiveState.com>
+
+	* win/configure:
+	* win/tcl.m4: removed incorrect checks for existence of optimization.
+	TCL_CFG_OPTIMIZED is now defined whenever the user does not build with
+	--enable-symbols.
+
+2003-10-06  Don Porter	<dgp@users.sourceforge.net>
+
+	* tests/regexp.test:		Matched [makeFile] with [removeFile].
+	* tests/regexpComp.test:	[Bug 675652]
+
+	* tests/fCmd.test (fCmd-8.2):	Test only that tilde-substitution
+	happens, not for any particular result. [Bug 685991]
+
+	* unix/tcl.m4 (SC_PATH_TCLCONFIG):	Corrected search path so that
+	alpha and beta releases of Tcl are not favored. [Bug 608698]
+
+	* tests/reg.test:	Corrected duplicate test names.
+	* tests/resource.test:	[Bugs 710370, 710358]
+	* tests/dict.test:
+
+	* tests/dict.test:	Updated [package require tcltest] lines to
+	* tests/fileSystem.test:	indiciate that these test files
+	* tests/lrepeat.test:	use features of tcltest 2.  [Bug 706114]
+	* tests/notify.test:
+	* tests/parseExpr.test:
+	* tests/unixNotfy.test:
+	* tests/winDde.test:
+
+2003-10-04  Miguel Sofer <msofer@users.sf.net>
+
+	* generic/tclExecute.c (TEBC):
+	* tests/execute.test (execute-8.2): fix for [Bug 816641] - faulty
+	execution and catch stack management.
+
+2003-10-03  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclBasic.c:	Fixed error in ref count management of command
+	* generic/tclCmdMZ.c:	and execution traces that caused access to
+	freed memory in trace-32.1. [Bug 811483]
+
+2003-10-02  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclTrace.c: Corrected comingling of introspection results of
+	[trace info command] and [trace info execution]. [Bug 807243]
+	Thanks to Mark Saye.
+
+2003-10-01  Daniel Steffen  <das@users.sourceforge.net>
+
+	* macosx/Makefile: fixed redo prebinding bug when DESTDIR="".
+	* mac/tclMacResource.c: fixed possible NULL dereference (bdesgraupes).
+
+2003-09-29  Vince Darley  <vincentdarley@users.sourceforge.net>
+
+	* generic/tclPathObj.c:
+	* tests/fileName.test: fix to inconsistent handling of backslash
+	path separators on Windows in 'file join' [Bug 813273]
+
+2003-09-29  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* generic/tclPathObj.c (TclNativePathInFilesystem,TclFSGetPathType):
+	* generic/tclIOUtil.c (TclNativeDupInternalRep,TclGetPathType): Rename
+	to make sure function names won't interfere with other non-Tcl code
+	(reported by George Staplin)
+
+	TIP#121 IMPLEMENTATION FROM JOE MISTACHKIN
+
+	* generic/tclEvent.c (Tcl_SetExitProc,Tcl_Exit): Implementation of
+	application exit handler scheme.
+	* generic/tcl.decls (Tcl_SetExitProc): Public declaration.
+	* doc/Exit.3: Documentation of new API function.
+
+	TIP#112 IMPLEMENTATION
+
+	* generic/tclNamesp.c: Core of implementation.
+	* generic/tclInt.h (Namespace,TclInvalidateNsCmdLookup): Add command
+	list epoch counter and list of ensembles to namespace structure, and
+	define a macro to ease update of the epoch counter.
+	* generic/tclBasic.c (Tcl_CreateObjCommand,etc.): Update epoch counter
+	when list of commands in a namespace changes.
+	* generic/tclObj.c (TclInitObjSubsystem): Register ensemble subcommand
+	type.
+	* tests/namespace.test (42.1-47.6): Tests.
+	* doc/namespace.n: Documentation.
+
+	* library/http/http.tcl (geturl): Correctly check the type of
+	boolean-valued options. [Bug 811170]
+
+	* unix/tcl.m4 (SC_ENABLE_FRAMEWORK): Added note to make it clearer
+	that this is an OSX feature, not a general Unix feature. [Bug 619440]
+
+2003-09-28  David Gravereaux <davygrvy@pobox.com>
+
+	* win/tclWinPipe.c: The windows port of expect can call
+	TclWinAddProcess before any of the other pipe functions. Added a
+	missing PipeInit() call to make sure the initialization happens.
+
+2003-09-25  Daniel Steffen  <das@users.sourceforge.net>
+
+	* macosx/Makefile: ensure SYMROOT exists if OBJROOT is overridden on
+	command line. Replaced explict use of /usr/bin by ${BINDIR}.
+
+2003-09-24  Vince Darley  <vincentdarley@users.sourceforge.net>
+
+	* library/package.tcl (tcl::MacPkgUnknown, tcl::MacOSXPkgUnknown):
+	Minor performance tweaks to reduce the number of [file] invocations.
+	Meant to improve startup times, at least a little bit. (The generic
+	equivalent patch was applied on 2003-02-21).
+
+2003-09-24  Vince Darley  <vincentdarley@users.sourceforge.net>
+
+	* trace.test: removed 'knownBug' from a test which doesn't illustrate
+	a bug, just a bad test.
+
+2003-09-23  Miguel Sofer <msofer@users.sf.net>
+
+	* generic/tclExecute.c:
+	* generic/tclInt.h: changed the evaluation-stack addressing mode, from
+	array-style to pointer-style; the catch stack and evaluation stack are
+	now contiguous in memory. [Patch 457449]
+
+2003-09-23  Don Porter  <dgp@users.sourceforge.net>
+
+	* tests/trace.test (trace-31,32-*):  Added tests for [Bug 807243] and
+	[Bug 811483].
+
+	* library/init.tcl (auto_load, auto_import):  Expanded Eric Melski's
+	2000-01-28 fix for [Bug 218871] to all potentially troubled uses of
+	[info commands] on input data, where glob-special characters could
+	cause problems.
+
+2003-09-20  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* tests/expr.test (expr-23.4): Prevented accidental wrapping round of
+	exponential operation; it isn't portable, and not what I intended to
+	test either. [Bug 808244]
+
+2003-09-19  Miguel Sofer <msofer@users.sf.net>
+
+	* generic/tclExecute.c: adding (DE)CACHE_STACK_INFO() pairs to protect
+	all calls that may cause traces on ::errorInfo or ::errorCode to
+	corrupt the stack. [Bug 804681]
+
+2003-09-17  Vince Darley  <vincentdarley@users.sourceforge.net>
+
+	* tclPathObj.c: fix to test-suite problem introduced by the bug fix
+	below. No problem in ordinary code, just test suite code which
+	manually adjusts tclPlatform. [Bug 808247]
+
+2003-09-16  Vince Darley  <vincentdarley@users.sourceforge.net>
+
+	* doc/filename.n: documentation of Windows-specific feature as
+        discussed in [Bug 541989]
+	* generic/tclPathObj.c: fix for normalization of volume-relative paths
+	[Bug 767834]
+        * tests/winFCmd.test: new tests for both of the above.
+	* tests/cmdAH.test: fix for AFS problem in test suite [Bug 748960]
+
+2003-09-13  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	TIP#123 IMPLEMENTATION BASED ON WORK BY ARJEN MARKUS
+
+	* generic/tclCompile.h (INST_EXPON):		Implementation of
+	* generic/tclCompile.c (tclInstructionTable):	exponential operator.
+	* generic/tclCompExpr.c (operatorTable):
+	* generic/tclParseExpr.c (ParseExponentialExpr, GetLexeme):
+	* generic/tclExecute.c (TclExecuteByteCode, ExponWide, ExponLong):
+	(IllegalExprOperandType):
+	* tests/expr.test:
+	* tests/compExpr-old.test:
+	* doc/expr.n:
+
+2003-09-10  Don Porter  <dgp@users.sourceforge.net>
+
+	* library/opt/optparse.tcl:	Latest revisions caused [OptGuessType]
+	to guess "int" instead of "string" for empty strings. Missed the
+	required "-strict" option to [string is]. Thanks to Revar Desmera.
+	[Bug 803968]
+
+2003-09-08  David Gravereaux <davygrvy@pobox.com>
+
+	* win/tclWinLoad.c (TclpDlopen): Changed the error message for
+	ERROR_PROC_NOT_FOUND to be a bit more helpful in giving us clues.
+	"can't find specified procedure" means a function in the import table,
+	for implicit loading, couldn't be resolved and that's why the load
+	failed.
+
+2003-09-04  Don Porter  <dgp@users.sourceforge.net>
+
+	* doc/Tcl_Main.3:
+	* doc/FileSystem.3:				Implementation of
+	* doc/source.n:					TIPs 137/151. Adds a
+	* doc/tclsh.1:					-encoding option to
+	* generic/tcl.decls:				the [source] command
+	* generic/tclCmdMZ.c (Tcl_SourceObjCmd):	and a new C routine,
+	* generic/tclIOUtil.c (Tcl_FSEvalFileEx):	Tcl_FSEvalFileEx(),
+	* generic/tclMain.c (Tcl_Main):			that provides C access
+	* mac/tclMacResource.c (Tcl_MacSourceObjCmd):	to the same function.
+	* tests/cmdMZ.test:				Also adds command line
+	* tests/main.test:	option handling in Tcl_Main() so that tclsh
+	* tests/source.test:	and other apps built on Tcl_Main() respect a
+	-encoding command line option before a script filename. Docs and tests
+	updated as well. [Patch 742683]
+	This is a ***POTENTIAL INCOMPATIBILITY*** only for those C programs
+	that embed Tcl, build on Tcl_Main(), and make use of Tcl_Main's former
+	ability to pass a leading "-encoding" option to interactive shell
+	operations.
+
+	* generic/tclInt.decls:				Added internal stub
+	* generic/tclMain.c (Tcl*StartupScript*):	table entries for two
+	new functions Tcl_SetStartupScript() and Tcl_GetStartupScript() that
+	set/get the path and encoding for the startup script to be evaluated
+	by either Tcl_Main() or Tk_Main(). Given public names in anticipation
+	of their exposure by a followup TIP.
+
+	* generic/tclDecls.h:		make genstubs
+	* generic/tclIntDecls.h:
+	* generic/tclStubInit.c:
+
+2003-09-04  Don Porter  <dgp@users.sourceforge.net>
+
+	* doc/SplitList.3:	Implementation of TIP 148.  Fixes [Bug 489537].
+	* generic/tcl.h:	Updated Tcl_ConvertCountedElement() to quote
+	* generic/tclUtil.c:	the leading "#" character of all list elements
+	unless the TCL_DONT_QUOTE_HASH flag is passed in.
+
+	* generic/tclDictObj.c:	Updated Tcl_ConvertCountedElement() callers
+	* generic/tclListObj.c:	to pass in the TCL_DONT_QUOTE_HASH flags
+	* generic/tclResult.c:	when appropriate.
+
+2003-08-31  Don Porter  <dgp@users.sourceforge.net>
+
+	* doc/return.n:	Updated [return] docs to cover new TIP 90 features.
+
+	* doc/break.n:		Added SEE ALSO references to return.n
+	* doc/continue.n:
+
+2003-09-01  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* doc/Namespace.3: Basic documentation for the TIP#139 functions. This
+	will need improving, but the basic bits are there at least.
+
+2003-08-31  Don Porter  <dgp@users.sourceforge.net>
+
+	* doc/catch.n:	Updated [catch] docs to cover new TIP 90 features.
+
+2003-08-29  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclCmdAH.c:	Corrected bug in TIP 90 implementation where
+	* tests/cmdMZ.test:	the default -errorcode NONE value was not
+	copied into the return options dictionary. This correction modified
+	one test result.
+
+2003-08-27  David Gravereaux <davygrvy@pobox.com>
+
+	* compat/strftime.c (_fmt): Removed syst array intializer that
+	couldn't take variables within it under the watcom compiler:
+	'Initializers must be constant'. I believe Borland has this strictness
+	as well. VC++ must be non-standard about this.
+
+	Changed Win32 platform #ifdef from 'WIN32' to '__WIN32__' as this is
+	the correct one to use across the Tcl sources. Even though we do force
+	it in tcl.h, the true parent one is __WIN32__.
+
+	Added missing CONST'ification usage to match prototype listed in
+	tclInt.decls.
+
+	* win/tclWinPort.h:  Added a block for OpenWatcom adjustments that
+	fixes 1) the same issue Mo did for MinGW lack of missing LPFN_*
+	typedefs in their WINE derived <winsock2.h> and 2) The need to be
+	strict about how the char type needs to be signed by default.
+
+	* win/tclWinSock.c:  Added OpenWatcom to the commentary about the
+	#ifdef HAVE_NO_LPFN_DECLS block.
+
+	* win/tclWinTime.c:  Changed use of '_timezone' to 'timezone' as this
+	difference is already adjusted for in tclWinPort.h. Removed
+	unreferenced posixEpoch file-scope global.
+
+	* win/tclWinFile.c (WinReadLinkDirectory): Fix for 'Initializers must
+	be constant' with the driveSpec array using OpenWatcom.
+
+2003-08-27  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclUtil.c:	Corrected [Bug 411825] and other bugs in
+	TclNeedSpace() where non-breaking space (\u00A0) and backslash-escaped
+	spaces were handled incorrectly.
+	* tests/util.test:	Added new tests util-8.[2-6].
+
+2003-08-26  David Gravereaux <davygrvy@pobox.com>
+
+	* generic/tcl.h: Added some support for the LCC-Win32 compiler.
+	Unfortunetly, this compiler has a bug in its preprocessor and can't
+	build Tcl even with this minor patch. Also added some support for the
+	OpenWatcom compiler. A new win/makefile.wc to follow soon.
+
+2003-08-25  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* tools/genStubs.tcl (genStubs::makeDecl): A more subtle way of
+	generating stubbed declarations allows us to have declarations of a
+	function in multiple interfaces simultaneously.
+
+	* generic/tcl.decls: Duplicated some namespace declarations from
+	tclInt.decls here, as mandated by TIP #139. This is OK since the
+	declarations match and will end up using the declarations in the
+	public code from now on because of #include ordering. Keeping the old
+	declarations in tclInt.decls; there's no need to gratuitously break
+	compatability for those extensions which are already clients of the
+	namespace code.
+
+2003-08-23  Zoran Vasiljevic  <zoran@archiwrae.com>
+
+	* generic/tclIOUtil.c: merged fixes for thread-unsafe handling of
+	filesystem records [Bug 753315]. This also fixed the [Bug 788780]
+	* generic/tclPathObj.c: merged fixes for thread-unsafe handling of
+	filesystem records. [Bug 753315]
+
+	* generic/tclFileSystem.h: merged fixes for thread-unsafe handling of
+	filesystem records. [Bug 753315]
+
+2003-08-19  Pat Thoyts  <patthoyts@users.sourceforge.net>
+
+	* win/tclWinSerial.c (SerialErrorStr): Fixed a syntax error created in
+	the previous code cleanup.
+
+2003-08-19  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* win/tclWinSerial.c: Adjusted commenting and spacing usage to follow
+	the principles of the Style Guide better.
+
+2003-08-18  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* win/configure: Regen.
+	* win/tcl.m4 (SC_ENABLE_SYMBOLS): Use test instead of -eq, which does
+	not work. [Bug 781109]
+
+2003-08-13  Chengye Mao <chengye.geo@yahoo.com>
+
+	* win/tclWinPipe.c: fixed a bug in BuildCommandLine. This bug built a
+	command line with a missing space between tclpipe.dll and the
+	following arguments. It caused error in Windows 98 when exec
+	command.com (e.g. dir). [Bug 789040]
+
+2003-08-11  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	TIP #136 IMPLEMENTATION from Simon Geard <simon.geard@ntlworld.com>
+	* generic/tclCmdIL.c (Tcl_LrepeatObjCmd): Adapted version of Simon's
+	* doc/lrepeat.n:			  patch, updated to the HEAD
+	* tests/lrepeat.test:			  and matching the core style.
+	* generic/tclBasic.c (buildIntCmds):	Splice into core.
+	* generic/tclInt.h:
+	* doc/list.n:				Cross-reference.
+
+2003-08-06  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* win/tclWinInit.c: recognize amd64 and ia32_on_win64 cpus.
+
+2003-08-06  Don Porter  <dgp@users.sourceforge.net>
+
+	* library/msgcat/msgcat.tcl:	Added escape so that non-Windows
+	* library/msgcat/pkgIndex.tcl:	platforms do not try to use the
+	registry package. This can save a costly and pointless package search.
+	Bumped to 1.3.1. Thanks to Dave Bodenstab. [Bug 781609]
+
+2003-08-05  Miguel Sofer <msofer@users.sf.net>
+
+	* generic/tclExecute.c (INST_INVOKE, INST_EVAL, INST_PUSH_RESULT):
+	added a Tcl_ResetResult(interp) at each point where the interp's
+	result is pushed onto the stack, to avoid keeping an extra reference
+	that may cause costly Tcl_Obj duplication. Detected by Franco Violi,
+	analyzed by Peter Spjuth and Donal Fellows. [Bug 781585]
+
+2003-07-28  Vince Darley  <vincentdarley@users.sourceforge.net>
+
+	* doc/FileSystem.3:
+	* doc/Translate.3: better documentation of Tcl_TranslateFileName and
+	related functions. [Bug 775220]
+
+2003-07-24  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* generic/tcl.h: Revert change made on 2003-07-21 since it made the
+	sizeof(Tcl_Obj) different for regular vs mem debug builds.
+	* generic/tclInt.h: Define TclDecrRefCount in terms of
+	Tcl_DbDecrRefCount which removes one layer of inderection.
+	* generic/tclObj.c (TclDbInitNewObj, Tcl_DbIncrRefCount,
+	(Tcl_DbDecrRefCount, Tcl_DbIsShared): Define ThreadSpecificData that
+	contains a hashtable. The table is used to ensure that a Tcl_Obj is
+	only acted upon in the thread that allocated it. This checking code is
+	enabled only when mem debug and threads are enabled.
+
+2003-07-24  Don Porter  <dgp@users.sourceforge.net>
+
+	* tests/async.test:	Added several tests that demonstrate [Bug
+	* tests/basic.test:	489537], Tcl's longstanding failure to
+	* tests/dict.test:	properly quote any leading '#' character when
+	* tests/dstring.test:	generating the string rep of a list so that
+	* tests/list.test:	the comment-power of that character is hidden
+	* tests/parse.test:	from any [eval], in order to satisfy the
+	* tests/util.test:	documentation that [list] does [eval]-safe
+				quoting.
+
+2003-07-24  Reinhard Max  <max@suse.de>
+
+	* library/package.tcl: Fixed a typo that broke pkg_mkIndex -verbose.
+	* tests/pkgMkIndex.test: Added a test for [pkg_mkIndex -verbose].
+
+	* ChangeLog.2002 (new file):
+	* ChangeLog: broke changes from 2002 into ChangeLog.2002 to reduce
+	size of the main ChangeLog.
+
+2003-07-23  Daniel Steffen  <das@users.sourceforge.net>
+
+	* unix/Makefile.in: changes to html-tcl & html-tk targets for
+	compatibility with non-gnu makes.
+
+	* unix/Makefile.in: added macosx/README to dist target.
+
+2003-07-23  Pat Thoyts  <patthoyts@users.sourceforge.net>
+
+	* win/tclWinReg.c (OpenSubKey): Fixed bug 775976 which causes the
+	registry set command to fail when built with VC7.
+	* library/reg/pkgIndex.tcl: Incremented the version to 1.1.2.
+
+2003-07-21  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	Check that the thread incrementing or decrementing the ref count of a
+	Tcl_Obj is the thread that originally allocated the thread. This fail
+	fast behavior will catch programming errors that allow a single
+	Tcl_Obj to be accessed from multiple threads.
+
+	* generic/tcl.h (Tcl_Obj): Add allocThread member to Tcl_Obj. This
+	member records the thread id the Tcl_Obj was allocated. It is used to
+	check that any future ref count incr or decr is done from the same
+	thread that allocated the Tcl_Obj. This member is defined only when
+	threads and mem debug are enabled.
+	* generic/tclInt.h (TclNewObj, TclDbNewObj, TclDecrRefCount):
+	Define TclNewObj and TclDbNewObj using TclDbInitNewObj when mem debug
+	is enabled. This fixes a problem where TclNewObj calls did not work
+	the same as TclDbNewObj when mem debug was enabled.
+	* generic/tclObj.c (TclDbInitNewObj, Tcl_DbIncrRefCount,
+	(Tcl_DbDecrRefCount): Add new helper to init Tcl_Obj members when mem
+	debug is enabled. Init the allocThread member in TclDbInitNewObj and
+	check it in Tcl_DbIncrRefCount and Tcl_DbDecrRefCount to make sure a
+	Tcl_Obj allocated in one thread is not being acted upon in another
+	thread.
+
+2003-07-21  Vince Darley  <vincentdarley@users.sourceforge.net>
+
+	* test/cmdAH.test: ensure certain tests run in local filesystem. [Bug
+	748960]
+
+2003-07-18  Daniel Steffen  <das@users.sourceforge.net>
+
+	* macosx/Makefile: added option to allow installing manpages in
+	addition to default html help.
+
+2003-07-18  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* doc/Utf.3: Tightened up documentation of Tcl_UtfNext and Tcl_UtfPrev
+	to better match the behaviour. [Bug 769895]
+
+2003-07-18  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* library/http/pkgIndex.tcl: upped to http v2.4.4
+	* library/http/http.tcl: add support for user:pass info in URL.
+	* tests/http.test:       [Bug 759888] (shiobara)
+
+2003-07-18  Don Porter  <dgp@users.sourceforge.net>
+
+	* doc/tcltest.n:                Restored the [Eval] proc to replace
+	* library/tcltest/tcltest.tcl:  the [::puts] command when either the
+	-output or -error option for [test] is in use, in order to capture
+	data written to the output or error channels for comparison against
+	what is expected.  This is easier to document and agrees better with
+	most user expectations than the previous attempt to replace [puts]
+	only in the caller's namespace.  Documentation made more precise on
+	the subject.  [Bug 706359]
+
+	* doc/AddErrInfo.3:	Improved consistency of documentation by
+	* doc/CrtTrace.3:      	using "null" everywhere to refer to the
+	* doc/Encoding.3:      	character '\0', and using "NULL" everywhere
+	* doc/Eval.3:          	to refer to the value of a pointer that points
+	* doc/GetIndex.3:      	to nowhere. Also dropped references to ASCII
+	* doc/Hash.3:          	that are no longer true, and standardized on
+	* doc/LinkVar.3:       	the hyphenated spelling of "null-terminated".
+	* doc/Macintosh.3:
+	* doc/OpenFileChnl.3:
+	* doc/SetVar.3:
+	* doc/StringObj.3:
+	* doc/Utf.3:
+
+	* doc/CrtSlave.3 (Tcl_MakeSafe):  Removed warning about possible
+	deprecation (no TIP on that).
+
+2003-07-17  Daniel Steffen  <das@users.sourceforge.net>
+
+	* unix/tclUnixFCmd.c: fix for compilation errors on platforms where
+	configure detects non-functional chflags(). [Bug 748946]
+
+	* macosx/Makefile: Rewrote buildsystem for Mac OS X framework build
+	to be purely make driven; in order to become independent of Apple's
+	closed-source IDE and build tool. The changes are intended to be
+	transparent to the Makefile user, all existing make targets and cmd
+	line variable overrides should continue to work. Changed build to only
+	include tcl specific html help in Tcl.framework, the tk specific html
+	help is now included in Tk.framework. Added var to allow overriding of
+	tclsh used during html help building (Landon Fuller).
+
+	* macosx/Tcl.pbproj/project.pbxproj:
+	* macosx/Tcl.pbproj/jingham.pbxuser: Changed to purely call through to
+	the make driven buildsystem; Tcl.framework is no longer assembled by
+	ProjectBuilder.
+	Set default SYMROOT in target options to simplify setting up PB
+	(manually setting common build folder for tcl & tk no longer needed).
+
+	* tools/tcltk-man2html.tcl: Added options to allow building only the
+	tcl or tk html help files; the default behaviour with none of the new
+	options is to build both, as before.
+
+	* unix/Makefile.in: Added targets for building only the tcl or tk help
+
+	* macosx/README (new): Tcl specific excerpts of tk/macosx/README.
+
+	* generic/tcl.h: Updated reminder comment about editing
+	macosx/Tcl.pbproj/project.pbxproj when version number changes.
+
+2003-07-16  Mumit Khan  <khan@nanotech.wisc.edu>
+
+	* generic/tclPathObj.c (SetFsPathFromAny): Add Cygwin specific code to
+	convert POSIX filename to native format.
+	* generic/tclFileName.c (Tcl_TranslateFileName): And remove from here.
+	(TclDoGlob): Adjust for cygwin and append / for dirs instead of \
+	* win/tclWinFile.c (TclpObjChdir): Use chdir on Cygwin.
+	[Patch 679315]
+
+2003-07-16  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* library/safe.tcl (FileInAccessPath): normalize paths before
+	comparison. [Bug 759607] (myers)
+
+	* unix/tclUnixNotfy.c (NotifierThreadProc): correct size of found and
+	word vars from int to long. [Bug 767578] (hgo)
+
+	* generic/tcl.h:       Add recognition of -DTCL_UTF_MAX=6 on the make
+	* generic/regcustom.h: line to support UCS-4 mode. No config arg at
+	this time, as it is not the recommended build mode.
+
+	* generic/tclPreserve.c: In Result and Preserve'd routines, do not
+	* generic/tclUtil.c:     assume that ckfree == free, as that is not
+	* generic/tclResult.c:   always true. [Bug 756791] (fuller)
+
+2003-07-16  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* doc/CrtSlave.3 (Tcl_MakeSafe): Updated documentation to strongly
+	discourage use. IMHO code outside the core that uses this function is
+	a bug... [Bug 655300]
+
+2003-07-16  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclFileName.c (Tcl_GlobObjCmd):	[Bug 771840]
+	* generic/tclPathObj.c (Tcl_FSConvertToPathType):[Bug 771947]
+	* unix/tclUnixFCmd.c (GetModeFromPermString):	[Bug 771949]
+	Silence compiler warnings about unreached lines.
+
+	* library/tcltest/tcltest.tcl (ProcessFlags):	Corrected broken call
+	* library/tcltest/pkgIndex.tcl:			to [lrange]. Bumped to
+	version 2.2.4. [Bug 772333]
+
+2003-07-15  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* unix/dltest/pkga.c (Pkga_EqObjCmd): Fix typo that was causing a
+	crash in load.test.
+
+2003-07-15  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* doc/array.n: Make sure docs are synched with the 8.4 release.
+
+2003-07-15  Don Porter  <dgp@users.sourceforge.net>
+
+	* doc/http.n:  Updated SYNOPSIS to match actual syntax of commands.
+	[Bug 756112]
+
+	* unix/dltest/pkga.c:	Updated to not use Tcl_UtfNcmp and counted
+	strings instead of strcmp (not defined in any #include'd header) and
+	presumed NULL-terminated strings.
+
+	* generic/tclCompCmds.c (TclCompileIfCmd):  Prior fix of Bug 711371 on
+	2003-04-07 introduced a buffer overflow. Corrected. [Bug 771613]
+
+2003-07-15  Kevin B. Kenny  <kennykb@acm.org>
+
+	* win/rules.vc: Added a missing $(OPTDEFINES) which broke the build if
+	STATS=memdbg was specified.
+
+2003-07-15  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* generic/tclCmdIL.c (SortCompare): Cleared up confusing error
+	message. [Bug 771539]
+
+2003-07-11  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* tests/binary.test (binary-46.*): Tests to help enforce the current
+	behaviour.
+	* doc/binary.n: Documented that [binary format a] and [binary scan a]
+	do encoding conversion by dropping high bytes, unlike the rest of the
+	core. [Bug 735364]
+
+2003-07-11  Don Porter  <dgp@users.sourceforge.net>
+
+	* library/package.tcl:  Corrected [pkg_mkIndex] bug reported on
+	comp.lang.tcl. The indexer was searching for newly indexed packages
+	instead of newly provided packages.
+
+2003-07-08  Vince Darley  <vincentdarley@users.sourceforge.net>
+
+	* tests/winFCmd.test: fix for five tests under win98 [Bug 767679]
+
+2003-07-07  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* doc/array.n: add examples from Welton
+
+2003-06-23  Vince Darley  <vincentdarley@users.sourceforge.net>
+
+	* doc/file.n: clarification of 'file tail' behaviour [Bug 737977]
+
+2003-07-04  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* doc/expr.n: Tighten up the wording of some operations. [Bug 758488]
+
+	* tests/cmdAH.test: Made tests of [file mtime] work better on FAT
+	filesystems. [Patch 760768]  Also a little general cleanup.
+
+	* generic/tclCmdMZ.c (Tcl_StringObjCmd): Made [string map] accept
+	dictionaries for maps.  This is much trickier than it looks, since map
+	entry ordering is significant. [Bug 759936]
+
+	* generic/tclVar.c (Tcl_ArrayObjCmd, TclArraySet): Made [array get]
+	and [array set] work with dictionaries, producing them and consuming
+	them. Note that for compatability reasons, you will never get a dict
+	from feeding a string literal to [array set] since that alters the
+	trace behaviour of "multi-key" sets. [Bug 759935]
+
+2003-06-23  Vince Darley  <vincentdarley@users.sourceforge.net>
+
+	* generic/tclTrace.c: fix to Window debug build compilation error.
+
+2003-06-27  Don Porter  <dgp@users.sourceforge.net>
+
+	* tests/init.test: Added [cleanupTests] to report results of tests
+	* tests/pkg.test:  that run in slave interps.  [Bugs 761334,761344]
+
+	* tests/http.test: Used more reliable path to find httpd script.
+
+2003-06-25  Don Porter  <dgp@users.sourceforge.net>
+
+	* tests/init.test:  Added tests init-4.6.* to illustrate [Bug 760872]
+
+2003-06-25  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* generic/tclTrace.c: New file, factoring out of virtually all the
+	various trace-related things from tclBasic.c and tclCmdMZ.c with the
+	goal of making this a separate maintenance area.
+
+2003-06-25  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* unix/configure: Regen.
+	* unix/tcl.m4 (SC_CONFIG_CFLAGS): Add -ieee when compiling with cc and
+	add -mieee when compiling with gcc under OSF1-V5 "Tru64" systems. [Bug
+	748957]
+
+2003-06-24  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* doc/encoding.n: Corrected the docs to say that [source] uses the
+	system encoding, which it always did anyway (since 8.1) [Bug 742100]
+
+2003-06-24  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* generic/tclHash.c (Tcl_HashStats): Prevented occurrence of
+	division-by-zero problems.  [Bug 759749]
+
+2003-06-24  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* unix/tclUnixPort.h: #undef inet_ntoa before #define to avoid
+	compiler warning under freebsd. [Bug 745844]
+
+2003-06-23  Pat Thoyts  <patthoyts@users.sourceforge.net>
+
+	* doc/dde.n:                 Committed TIP #135 which changes the
+	* win/tclWinDde.c:           -exact option to -force. Also cleaned a
+	* tests/winDde.test:         bug in the tests.
+	* library/dde/pkgIndex.tcl:  Incremented version to 1.2.5
+
+	* doc/dde.n:                 Committed TIP #120 which provides the
+	* win/tclWinDde.c:           dde package for safe interpreters.
+	* tests/winDde.test:         Incremented package version to 1.2.4
+	* library/dde/pkgIndex.tcl:
+
+2003-06-23  Vince Darley  <vincentdarley@users.sourceforge.net>
+
+	* generic/tclFCmd.c: fix to bad error message when trying to do 'file
+	copy foo ""'. [Bug 756951]
+	* tests/fCmd.test: added two new tests for the bug.
+
+	* win/tclWinFile.c:
+	* win/tclWin32Dll.c: recommitted some filesystem globbing speed-ups,
+	but disabled some on the older Win 95/98/ME where they don't seem to
+	work.
+
+	* doc/FileSystem.3: documentation fix [Bug 720634]
+
+2003-06-18  Miguel Sofer <msofer@users.sf.net>
+
+	* generic/tclNamesp.c (Tcl_Export): removed erroneous comments. [Bug
+	756744]
+
+2003-06-17  Vince Darley  <vincentdarley@users.sourceforge.net>
+
+	* win/makefile.vc:  fixes to check-in below so compilation now works
+	again on Windows.
+
+	* generic/tclCmdMZ.c:
+	* tests/regexp.test: fixing of bugs related to regexp and regsub
+	matching of empty strings. Addition of a number of new tests. [Bug
+	755335]
+
+2003-06-16  Andreas Kupries  <andreask@activestate.com>
+
+	* win/Makefile.in:  Haven't heard back from David for a week. Now
+	* win/configure:    committing the remaining changes.
+	* win/configure.in: Note: In active contact with Helmut Giese about
+	* win/makefile.vc:  the borland relatedchanges. This part will see
+	* win/rules.vc:     future updates.
+	* win/tcl.m4:
+	* win/makefile.bc:
+
+2003-06-10  Andreas Kupries  <andreask@activestate.com>
+
+	* generic/tclConfig.c (ASSOC_KEY): Changed the key to
+	"tclPackageAboutDict" (tcl prefix) to make collisions with the keys of
+	other packages more unlikely.
+
+2003-06-10  Miguel Sofer <msofer@users.sf.net>
+
+	* generic/tclBasic.c:
+	* generic/tclExecute.c: let TclExecuteObjvInternal call
+	TclInterpReady instead of relying on its callers to do so; fix for the
+	part of [Bug 495830] that is new in 8.4.
+	* tests/interp.test: Added tests 18.9 (knownbug) and 18.10
+
+2003-06-09  Andreas Kupries  <andreask@activestate.com>
+
+	* generic/tcl.decls:  Ported the changes from the
+	* generic/tcl.h:      'tip-59-implementation' branch into the CVS
+	* generic/tclBasic.c: head. Regenerated stub table. Regenerated the
+	* generic/tclInt.h:   configure's scripts, with help from Joe English.
+	* generic/tclDecls.h:
+	* generic/tclStubInit.c:
+	* generic/tclConfig.c:
+	* generic/tclPkgConfig.c:
+	* unix/Makefile.in:
+	* unix/configure.in:  The changes in the windows section are not yet
+	* unix/tcl.m4:        committed, they await feedback from David
+	* unix/mkLinks:       Gravereaux.
+	* doc/RegConfig.3:
+	* mac/tclMacPkgConfig.c:
+	* tests/config.test:
+
+2003-06-09  Don Porter  <dgp@users.sourceforge.net>
+
+	* string.test (string-4.15): Added test for [string first] bug
+	reported in Tcl 8.3, where test for all-single-byte-encoded strings
+	was not reliable.
+
+2003-06-04  Joe Mistachkin  <joe@mistachkin.com>
+
+	* tools/man2help.tcl: Added duplicate help section checking and
+	* tools/index.tcl:    corrected a comment typo for the getTopics proc
+	in index.tcl. [Bug 748700]
+
+2003-06-02  Vince Darley  <vincentdarley@users.sourceforge.net>
+
+	* win/tclWinFCmd.c:
+	* tests/fCmd.test: fix to [Bug #747575] in which a bad error message
+	is given when trying to rename a busy directory to one with the same
+	prefix, but not the same name. Added three new tests.
+
+2003-05-23  D. Richard Hipp <drh@hwaci.com>
+
+	* win/tclWinTime.c: Add tests to detect and avoid a division by zero
+	in the windows precision timer calibration logic.
+
+2003-05-23  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclObj.c (tclCmdNameType):  Converted internal rep
+	management of the cmdName Tcl_ObjType the opposite way, to always use
+	the twoPtrValue instead of always using the otherValuePtr. Previous
+	fix on 2003-05-12 broke several extensions that wanted to poke around
+	with the twoPtrValue.ptr2 value of a cmdName Tcl_Obj, like TclBlend
+	and e4graph. [Bug 726018]
+	Thanks to George Petasis for the bug report and Jacob Levy for testing
+	assistance.
+
+2003-05-23  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* unix/mkLinks: Set the var S to "" at the top of the file to avoid
+	error when user has set S to something. [Tk Bug 739833]
+
+2003-05-22  Daniel Steffen  <das@users.sourceforge.net>
+
+	* macosx/Tcl.pbproj/project.pbxproj: added missing references to new
+	source files tclPathObj.c and tclMacOSXFCmd.c.
+
+	* macosx/tclMacOSXBundle.c: fixed a problem that caused only the first
+	call to Tcl_MacOSXOpenVersionedBundleResources() for a given bundle
+	identifier to succeed. This caused the tcl runtime library not to be
+	found in all interps created after the inital one.
+
+2003-05-19  Kevin B. Kenny  <kennykb@hippolyta>
+
+	* unix/tclUnixTime.c: Corrected a bug in conversion of non-ASCII
+	chars in the format string.
+
+2003-05-19  Daniel Steffen  <das@users.sourceforge.net>
+
+	* macosx/Tcl.pbproj/project.pbxproj: changed tclConfig.sh location in
+	versioned framework subdirectories to be identical to location in
+	framework toplevel; fixed stub library symbolic links to be tcl
+	version specific.
+
+	* unix/tclUnixTime.c: fixed typo.
+
+2003-05-18  Kevin Kenny  <kennykb@acm.org>
+
+	* compat/strftime.c:  Modified TclpStrftime to return its result in
+	* generic/tclClock.c: UTF-8 encoding, and removed the conversion from
+	* mac/tclMacTime.c:   system encoding to UTF-8 from [clock format].
+	* unix/tclUnixTime.c: Needed to avoid double conversion of the
+	* win/tclWinTime.c:   timezone name on Windows systems. [Bug 624408]
+
+2003-05-16  Pat Thoyts  <patthoyts@users.sourceforge.net>
+
+	* library/dde/pkgIndex.tcl:  Applied TIP #130 which provides for
+	* tests/winDde.test:         unique dde server names. Added some more
+	* win/tclWinDde.c:           tests. Fixes [Bug 219293]
+
+	* doc/dde.n: Updated documentation re TIP #130.
+	* tests/winDde.test: Applied patch for [Bug 738929] by KKB and changed
+	to new-style tests.
+
+2003-05-16  Kevin B. Kenny  <kennykb@acm.org>
+
+	* unix/Makefile.in:	Removed one excess source file tclDToA.c
+
+2003-05-16  Daniel Steffen  <das@users.sourceforge.net>
+
+	* macosx/Tcl.pbproj/project.pbxproj: updated copyright year.
+
+2003-05-15  Kevin B. Kenny  <kennykb@acm.org>
+
+	* generic/tclGetDate.y: added further hackery to the yacc
+	* generic/tclDate.c:    post-processing to arrange for the code to set
+	* unix/Makefile.in:     up exit handlers to free the stacks. [Bug
+				736425]
+
+2003-05-15  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* win/tclWinFile.c (TclpMatchInDirectory): revert glob code to r1.44
+	as 2003-04-11 optimizations broke Windows98 glob'ing.
+
+	* doc/socket.n: nroff font handling correction
+
+	* library/encoding/gb2312-raw.enc (new): This is the original
+	gb2312.enc renamed to allow for it to still be used. This is needed by
+	Tk (unix) because X fonts with gb2312* charsets really do want the
+	original gb2312 encoding. [Bug 557030]
+
+2003-05-14  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* generic/tclCmdAH.c (Tcl_FormatObjCmd): Stop unwarranted demotion of
+	wide values to longs by formatting of int values. [Bug 699060]
+
+2003-05-14  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* library/encoding/gb2312.enc: copy euc-cn.enc over original
+	gb2312.enc. gb2312.enc appeared to not work as expected, and most uses
+	of gb2312 really mean euc-cn (which may be the cause of the problem).
+	[Bug 557030]
+
+2003-05-14  Daniel Steffen  <das@users.sourceforge.net>
+
+	Implementation of TIP 118:
+
+	* generic/tclFCmd.c (TclFileAttrsCmd): return the list of attributes
+	that can be retrieved without error for a given file, instead of
+	aborting the whole command when any error occurs.
+
+	* unix/tclUnixFCmd.c: added support for new file attributes and for
+	copying Mac OS X file attributes & resource fork during [file copy].
+
+	* generic/tclInt.decls: added declarations of new external commands
+	needed by new file attributes support in tclUnixFCmd.c.
+
+	* macosx/tclMacOSXFCmd.c (new): Mac OS X specific implementation of
+	new file attributes and of attribute & resource fork copying.
+
+	* mac/tclMacFCmd.c: added implementation of -rsrclength attribute &
+	fixes to other attributes for consistency with OSX implementation.
+
+	* mac/tclMacResource.c: fixes to OSType handling.
+
+	* doc/file.n: documentation of [file attributes] changes.
+
+	* unix/configure.in: check for APIs needed by new file attributes.
+
+	* unix/Makefile.in:
+	* unix/tcl.m4: added new platform specifc tclMacOSXFCmd.c source.
+
+	* unix/configure:
+	* generic/tclStubInit.c:
+	* generic/tclIntPlatDecls.h: regen.
+
+	* tools/genStubs.tcl: fixes to completely broken code trying to
+	prevent overlap of "aqua", "macosx", "x11" and "unix" stub entries.
+
+	* tests/unixFCmd.test: added tests of -readonly attribute.
+
+	* tests/macOSXFCmd.test (new): tests of macosx file attributes and of
+	preservation of attributes & resource fork during [file copy].
+
+	* tests/macFCmd.test: restore -readonly attribute of test dir, as
+	otherwise its removal can fail on unices supporting -readonly.
+
+2003-05-13  David Gravereaux <davygrvy@pobox.com>
+
+	* generic/tclEnv.c: Another putenv() copy behavior problem repaired
+	when compiling on windows and using microsoft's runtime. [Bug 736421]
+
+2003-05-13  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* generic/tclIOUtil.c: ensure cd is thread-safe.
+	[Bug 710642] (vasiljevic)
+
+2003-05-13  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* generic/tclEvent.c (Tcl_Finalize): Removed unused variable to reduce
+	compiler warnings. [Bug 664745]
+
+2003-05-13  Joe Mistachkin  <joe@mistachkin.com>
+
+	* generic/tcl.decls:  Changed Tcl_JoinThread parameter name from
+	* generic/tclDecls.h: "id" to "threadId". [Bug 732477]
+	* unix/tclUnixThrd.c:
+	* win/tclWinThrd.c:
+	* mac/tclMacThrd.c:
+
+2003-05-13  Daniel Steffen  <das@users.sourceforge.net>
+
+	* generic/tcl.decls:
+	* macosx/tclMacOSXBundle.c: added extended version of the
+	Tcl_MacOSXOpenBundleResources() API taking an extra version number
+	argument: Tcl_MacOSXOpenVersionedBundleResources(). This is needed to
+	be able to access bundle resources in versioned frameworks such as Tcl
+	and Tk, otherwise if multiple versions were installed, only the latest
+	version's resources could be accessed. [Bug 736774]
+
+	* unix/tclUnixInit.c (Tcl_MacOSXGetLibraryPath): use new versioned
+	bundle resource API to get tcl runtime library for TCL_VERSION. [Bug
+	736774]
+
+	* generic/tclPlatDecls.h:
+	* generic/tclStubInit.c: regen.
+
+	* unix/tclUnixPort.h: worked around the issue of realpath() not
+	being thread-safe on Mac OS X by defining NO_REALPATH for threaded
+	builds on Mac OS X. [Bug 711232]
+
+2003-05-12  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* tests/cmdAH.test: General clean-up of tests so that all
+	tcltest-specific commands are protected by constraints and all
+	platforms see the same number of tests. [Bug 736431]
+
+2003-05-12  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclInterp.c: (AliasObjCmd):   Added refCounting of the words
+	* tests/interp.test (interp-33.1):      of the target of an interp
+	alias during its execution. Also added test. [Bug 730244]
+
+	* generic/tclBasic.c (TclInvokeObjectCommand):  objv[argc] is no
+	longer set to NULL (Tcl_CreateObjCommand docs already say that it
+	should not be accessed).
+
+	* tests/cmdMZ.test:  Forgot to import [temporaryDirectory].
+
+	* generic/tclObj.c (tclCmdNameType):  Corrected variable use of the
+	otherValuePtr or the twoPtrValue.ptr1 fields to store a
+	(ResolvedCmdName *) as the internal rep. [Bug 726018]
+
+	* doc/Eval.3:  Corrected prototype for Tcl_GlobalEvalObj [Bug 727622].
+
+2003-05-12  Miguel Sofer <msofer@users.sf.net>
+
+	* generic/tclVar.c (TclObjLookupVar): [Bug 735335] temporary fix,
+	disabling usage of tclNsVarNameType.
+	* tests/var.test (var-15.1): test for [Bug 735335]
+
+2003-05-10  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* win/tclWinSerial.c (SerialCloseProc): correct mem leak on closing a
+	Windows serial port [Bug 718002] (schroedter)
+
+	* generic/tclCmdMZ.c (Tcl_StringObjCmd): prevent string repeat crash
+	when overflow sizes were given (throws error). [Bug 714106]
+
+2003-05-09  Joe Mistachkin <joe@mistachkin.com>
+
+	* generic/tclThreadAlloc.c (TclFreeAllocCache): Fixed memory leak
+	caused by treating cachePtr as a TLS index. [Bug 731754]
+
+	* win/tclAppInit.c (Tcl_AppInit): Fixed memory leaks caused by not
+	freeing the memory allocated by setargv and the async handler created
+	by Tcl_AppInit. An exit handler has been created that takes care of
+	both leaks. In addition, Tcl_AppInit now uses ckalloc instead of
+	Tcl_Alloc to allow for easier leak tracking and to be more consistent
+	with the rest of the Tcl core. [Bugs 733156, 733221]
+
+	* tools/encoding/txt2enc.c (main): Fixed memory leak caused by failing
+	to free the memory used by the toUnicode array of strings [Bug 733221]
+
+2003-05-09  Miguel Sofer <msofer@users.sf.net>
+
+	* generic/tclCompile.c (TclCompileScript):
+	* tests/compile.test (compile-3.5): corrected wrong test and
+	behaviour in the earlier fix for [Bug 705406]; Don Porter reported
+	this as [Bug 735055], and provided the solution.
+
+2003-05-09  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* generic/tclCmdMZ.c (Tcl_ReturnObjCmd): The array of strings passed
+	to Tcl_GetIndexFromObj must be NULL terminated. [Bug 735186]
+	Thanks to Joe Mistachkin for spotting this.
+
+2003-05-07  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* doc/trace.n: Fixed very strange language in the documentation for
+	'trace add execution'. [Bug 729821]
+
+	* generic/tclCmdMZ.c (Tcl_TraceObjCmd): Made error message for 'trace
+	info' more consistent with documentation. [Bug 706961]
+
+	* generic/tclDictObj.c (DictInfoCmd): Fixed memory leak caused by
+	confusion about string ownership.  [Bug 731706]
+
+2003-05-05  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclBasic.c:		Implementation of TIP 90, which
+	* generic/tclCmdAH.c:		extends the [catch] and [return]
+	* generic/tclCompCmds.c:	commands to enable creation of a
+	* generic/tclExecute.c:		proc that is a replacement for
+	* generic/tclInt.h:		[return]. [Patch 531640]
+	* generic/tclProc.c:
+	* generic/tclResult.c:
+	* tests/cmdAH.test:
+	* tests/cmdMZ.test:
+	* tests/error.test:
+	* tests/proc-old.test:
+
+	* library/tcltest/tcltest.tcl: The -returnCodes option to [test]
+	failed to recognize the symbolic name "ok" for return code 0.
+
+2003-05-05  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* generic/tclBasic.c (Tcl_HideCommand): Fixed error message for
+	grammar and spelling.
+
+2003-04-28  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* generic/tclDictObj.c (DictIncrCmd): Updated to reflect the behaviour
+	with wide increments of the normal [incr] command.
+	* generic/tclInt.decls: Added TclIncrWideVar2 to internal stub table
+	and cleaned up.
+	* tests/incr.test (incr-3.*):
+	* generic/tclVar.c (TclIncrWideVar2, TclPtrIncrWideVar):
+	* generic/tclExecute.c (TclExecuteByteCode):
+	* generic/tclCmdIL.c (Tcl_IncrObjCmd): Make [incr] work when trying to
+	increment by wide values. [Bug 728838]
+
+	* generic/tclCompCmds.c (TclCompileSwitchCmd): Default mode of
+	operation of [switch] is exact matching. [Bug 727563]
+
+2003-04-25  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclBasic.c:  Tcl_EvalObjv() failed to honor the
+	TCL_EVAL_GLOBAL flag when resolving command names. Tcl_EvalEx passed a
+	string rep including leading whitespace and comments to
+	TclEvalObjvInternal().
+
+2003-04-25  Andreas Kupries  <andreask@activestate.com>
+
+	* win/tclWinThrd.c: Applied SF patch #727271. This patch changes the
+	code to catch any errors returned by the windows functions handling
+	TLS ASAP instead of waiting to get some mysterious crash later on due
+	to bogus pointers. Patch provided by Joe Mistachkin.
+
+	This is a stop-gap measure to deal with the low number of ?TLS slots
+	provided by some of the variants of Windows (60-80).
+
+2003-04-24  Vince Darley  <vincentdarley@users.sourceforge.net>
+
+	* generic/tclFileName.c: fix to bug reported privately by Jeff where,
+	for example, 'glob -path {[tcl]} *' gets confused by the leading
+	special character (which is escaped internally), and instead lists
+	files in '/'. Bug only occurs on Windows where '\' is also a directory
+	separator.
+	* tests/fileName.test: added test for the above bug.
+
+2003-04-22  Andreas Kupries  <andreask@activestate.com>
+
+	* The changes below fix SF bugs [593810], and [718045].
+
+	* generic/tclIO.c (Tcl_CutChannel, Tcl_SpliceChannel): Invoke
+	TclpCutSockChannel and TclpSpliceSockChannel.
+
+	* generic/tclInt.h: Declare TclpCutSockChannel and
+	TclpSpliceSockChannel.
+
+	* unix/tclUnixSock.c (TclpCutSockChannel, TclpSpliceSockChannel):
+	Dummy functions, on unix the sockets are _not_ handled specially.
+
+	* mac/tclMacSock.c (TclpCutSockChannel, TclpSpliceSockChannel):
+	* win/tclWinSock.c (TclpCutSockChannel, TclpSpliceSockChannel): New
+	functions to handle socket specific cut/splice operations: auto-init
+	of socket system for thread on splice, management of the module
+	internal per-thread list of sockets, management of association of
+	sockets with HWNDs for event notification.
+
+	* win/tclWinSock.c (NewSocketInfo): Extended initialization
+	assignments to cover all items of the structure. During debugging of
+	the new code mentioned above I found that two fileds could contain
+	bogus data.
+
+	* win/tclWinFile.c: Added #undef HAVE_NO_FINDEX_ENUMS before
+	definition because when compiling in debug mode the compiler complains
+	about a redefinition, and this warning is also treated as an error.
+
+2003-04-21  Don Porter  <dgp@users.sourceforge.net>
+
+	* library/tcltest/tcltest.tcl:  When the return code of a test does
+	not meet expectations, report that as the reason for test failure, and
+	do not attempt to check the test result for correctness. [Bug 725253]
+
+2003-04-18  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* win/tclWinInt.h (VER_PLATFORM_WIN32_CE): conditionally define.
+	* win/tclWinInit.c: recognize Windows CE as a Win platform. This just
+	recognizes CE - full support will come later.
+
+	* win/configure: regen
+	* win/configure.in (SHELL): force it to /bin/sh as autoconf 2.5x
+	uses /bin/bash, which can fail to find exes in the path (ie: lib).
+
+	* generic/tclExecute.c (ExprCallMathFunc): remove incorrect
+	extraneous cast from Tcl_WideAsDouble.
+
+2003-04-18  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* doc/open.n:		Moved serial port options from [fconfigure] to
+	* doc/fconfigure.n:	[open] as it is up to the creator of a channel
+				to describe the channel's special config
+				options. [Bug 679010]
+
+2003-04-16  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tcl.h:	Made changes so that the "wideInt" Tcl_ObjType
+	* generic/tclObj.c:	is defined on all platforms, even those where
+	* generic/tclPort.h:	TCL_WIDE_INT_IS_LONG is defined. Also made the
+	Tcl_Value struct have a wideValue field on all platforms. This is a
+	***POTENTIAL INCOMPATIBILITY*** for TCL_WIDE_INT_IS_LONG platforms
+	because that struct changes size. This is the same TIP 72
+	incompatibility that was seen on other platforms at the 8.4.0 release,
+	when this change should have happened as well. [Bug 713562]
+
+	* generic/tclInt.h:  New internal macros TclGetWide() and
+	TclGetLongFromWide() to deal with both forms of the "wideInt"
+	Tcl_ObjType, so that conditional TCL_WIDE_INT_IS_LONG code is confined
+	to the header file.
+
+	* generic/tclCmdAH.c:	Replaced most coding that was conditional
+	* generic/tclCmdIL.c:	on TCL_WIDE_INT_IS_LONG with code that
+	* generic/tclExecute.c: works across platforms, sometimes using
+	* generic/tclTest.c:	the new macros above to do it.
+	* generic/tclUtil.c:
+	* generic/tclVar.c:
+
+2003-04-17  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* doc/socket.n: Added a paragraph to remind people to specify their
+	encodings when using sockets. [Bug 630621]
+
+2003-04-16  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* doc/CrtMathFnc.3: Functions also have to deal with wide ints, but
+	this was not documented. [Bug 709720]
+
+2003-04-16  Vince Darley  <vincentdarley@users.sourceforge.net>
+
+	* generic/tclPathObj.c: removed undesired 'static' for function which
+	is now shared (previously it was duplicated).
+
+2003-04-15  Joe English  <jenglish@users.sourceforge.net>
+
+	* doc/namespace.n: added example section "SCOPED SCRIPTS", supplied by
+	Kevin Kenny. [Bug 219183]
+
+2003-04-15  Kevin Kenny  <kennykb@acm.org>
+
+	* makefile.vc: Updated makefile.vc to conform with Mo DeJong's changes
+	to Makefile.in and tclWinPipe.c on 2003-04-14. Now passes TCL_PIPE_DLL
+	in place of TCL_DBGX.
+	* win/tclWinTime.c: Corrected use of types to make compilation
+	compatible with VC++5.
+
+2003-04-15  Vince Darley  <vincentdarley@users.sourceforge.net>
+
+	* generic/tclIOUtil.c: finished check-in from yesterday, removing
+	duplicate function definition.
+
+2003-04-14  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclClock.c:	Corrected compiler warnings.
+	* generic/tclTest.c:
+
+2003-04-14  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* win/Makefile.in: Don't define TCL_DBGX symbol for every compile.
+	Instead, define TCL_PIPE_DLL only when compiling tclWinPipe.c. This
+	will break other build systems, so they will need to remove the
+	TCL_DBGX define and replace it with a define for TCL_PIPE_DLL.
+	* win/tclWinPipe.c (TclpCreateProcess): Remove PREFIX_IDENT and
+	DEBUG_IDENT from top of file. Use TCL_PIPE_DLL passed in from build
+	env instead of trying to construct the dll name from already defined
+	symbols. This approach is more flexible and better in the long run.
+
+2003-04-14  Kevin Kenny  <kennykb@acm.org>
+
+	* win/tclWinFile.c: added conditionals to restore compilation on
+	VC++6, which was broken by recent changes.
+
+2003-04-14  Vince Darley  <vincentdarley@users.sourceforge.net>
+
+	* generic/tclIOUtil.c:
+	* generic/tclPathObj.c:
+	* generic/tclFileSystem.h: overlooked one function which was
+	duplicated, so this is now shared between modules.
+	* win/tclWinFile.c: allow this file to compile with VC++ 5.2 again
+	since Mingw build fixes broke that.
+
+2003-04-13  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* win/configure: Regen.
+	* win/configure.in: Add check for FINDEX_INFO_LEVELS from winbase.h,
+	known to be a problem in VC++ 5.2. Define HAVE_NO_FINDEX_ENUMS if the
+	define does not exist.
+	* win/tclWinFile.c: Put declarations for FINDEX_INFO_LEVELS and
+	FINDEX_SEARCH_OPS inside a check for HAVE_NO_FINDEX_ENUMS so that
+	these are not declared twice. This fixes the Mingw build.
+	* win/tclWinTime.c: Rework the init of timeInfo so that the number or
+	initializers matches the declaration. This was broken under Mingw. Add
+	cast to avoid compile warning when calling the AccumulateSample
+	function.
+
+2003-04-12  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* win/Makefile.in (GENERIC_OBJS): add missing tclPathObj.c
+
+2003-04-12  Kevin Kenny  <kennykb@acm.org>
+
+	* doc/clock.n:
+	* generic/tclClock.c (Tcl_ClockObjCmd):
+	* tests/clock.test: Implementation of TIP #124. Also renumbered test
+	cases to avoid duplicates. [Bug 710310]
+	* tests/winTime.test:
+	* win/tclWinTest.c (TestwinclockCmd, TestwinsleepCmd):
+	* win/tclWinTime.c (Tcl_WinTime, UpdateTimeEachSecond,
+	(ResetCounterSamples, AccumulateSample, SAMPLES, TimeInfo): Made
+	substantial changes to the phase-locked loop (replaced an IIR filter
+	with an FIR one) in a quest for improved loop stability (Bug not
+	logged at SF, but cited in private communication from Jeff Hobbs).
+
+2003-04-11  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclCmdMZ.c (Tcl_StringObjCmd,STR_IS_INT):  Corrected
+	inconsistent results of [string is integer] observed on systems where
+	sizeof(long) != sizeof(int). [Bug 718878]
+	* tests/string.test: Added tests for Bug 718878.
+	* doc/string.n: Clarified that [string is integer] accepts 32-bit
+	integers.
+
+2003-04-11  Andreas Kupries  <andreask@activestate.com>
+
+	* generic/tclIO.c (UpdateInterest): When dropping interest in
+	TCL_READABLE now dropping interest in TCL_EXCEPTION too. This fixes a
+	bug where Expect detects eof on a file prematurely on solaris 2.6 and
+	higher. A much more complete explanation is in the code itself (40
+	lines of comments for a one-line change :)
+
+2003-04-11  Vince Darley  <vincentdarley@users.sourceforge.net>
+
+	* tests/cmdAH.test: fix test suite problem if /home is a symlink. [Bug
+	703264]
+	* generic/tclIOUtil.c: fix bad error message with 'cd ""'. [Bug
+	704917]
+	* win/tclWinFile.c, win/tclWin32Dll.c:
+	* win/tclWinInt.h: allow Tcl to differentiate between reparse points
+	which are symlinks and mounted volumes, and correctly handle the
+	latter. This involves some elaborate code to find the actual drive
+	letter (if possible) corresponding to a mounted volume. [Bug 697862]
+	* tests/fileSystem.test: add constraints to stop tests running in
+	ordinary tcl interpreter. [Bug 705675]
+
+	* generic/tclIOUtil.c:
+	* generic/tclPathObj.c: (new file)
+	* generic/tclFileSystem.h: (new file)
+	* win/makefile.vc:
+	Split path object handling out of the virtual filesystem layer, into
+	tclPathObj.c. This refactoring cleans up the internal filesystem code,
+	and will make any future optimisations and forthcoming better
+	thread-safety much easier.
+
+	* generic/tclTest.c:
+	* tests/reg.test: added some 'knownBug' tests for problems in Tcl's
+	regexp code with the TCL_REG_CAN_MATCH flag (see Bug 703709). Code too
+	impenetrable to fix right now, but a fix is needed for tip113 to work
+	correctly.
+
+	* tests/fCmd.test
+	* win/tclWinFile.c: added some filesystem optimisation to the 'glob'
+	implementation, and some new tests.
+
+	* generic/tclCmdMZ.c: fix typo in comment
+
+	* tests/winFile.test:
+	* tests/ioUtil.test:
+	* tests/unixFCmd.test: renumbered tests with duplicate numbers. [Bug
+	710361]
+
+2003-04-10  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* doc/binary.n: Fixed typo in [binary format w] desc. [Bug 718543]
+
+2003-04-08  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* generic/tclCmdAH.c (Tcl_ErrorObjCmd): Strings are only empty if
+	they have zero length, not if their first byte is zero, so fix test
+	guarding Tcl_AddObjErrorInfo to take this into account. [Bug
+	reported by Don Porter; no bug-id.]
+
+2003-04-07  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclCompCmds.c (TclCompileIfCmd):  Corrected string limits of
+	arguments interpolated in error messages. [Bug 711371]
+
+	* generic/tclCmdMZ.c (TraceExecutionProc):  Added missing
+	Tcl_DiscardResult() call to avoid memory leak.
+
+2003-04-07  Donal K. Fellows  <zzcgudf@ernie.mvc.mcc.ac.uk>
+
+	* generic/tclDictObj.c (Tcl_DictObjCmd): Stopped compilers from
+	moaning about switch fall-through.  [Bug 716327]
+	(DictFilterCmd): Yet more warning killing, this time reported by
+	Miguel Sofer by private chat.
+
+2003-04-07  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* tests/dict.test (dict-2.6):
+	* generic/tclDictObj.c (Tcl_NewDictObj, Tcl_DbNewDictObj): Oops!
+	Failed to fully initialise the Dict structure.
+	(DictIncrCmd): Moved valueAlreadyInDictionary label to stop compiler
+	complaints. [Bug 715751]
+
+	* generic/tclDictObj.c (DictIncrCmd): Followed style in the rest of
+	the core by commenting out wide-specific operations on platforms where
+	wides are longs, and used longs more thoroughly than ints through
+	[dict incr] anyway to forestall further bugs.
+	* generic/tclObj.c: Made sure there's always a tclWideIntType
+	implementation available, not that it is always useful. [Bug 713562]
+
+2003-04-05  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* generic/tclDictObj.c: Removed commented out notes on declarations to
+	be moved to elsewhere in the Tcl core.
+
+	* generic/tclInt.h:	Final stages of plumbing in.
+	* generic/tclBasic.c:
+	* generic/tclObj.c (TclInitObjSubsystem):
+
+	* unix/Makefile.in, win/Makefile.in, win/makefile.[bv]c: Build support.
+	* generic/tcl.decls: Added dict public API to stubs table.
+	* generic/tcl.h (Tcl_DictSearch): Added declaration of structure to
+	allow user code to iterate over dictionaries.
+
+	* doc/DictObj.3:	New files containing dictionary implementation
+	* doc/dict.n:		documentation and tests as as mandated by TIP
+	* generic/tclDictObj.c: #111.
+	* tests/dict.test:
+
+2003-04-03  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* unix/configure:
+	* unix/tcl.m4 (SC_CONFIG_CFLAGS): Don't set TCL_LIBS if it is already
+	set to support use of TCL_LIBS var from tclConfig.sh in the Tk
+	configure script.
+
+2003-04-03  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* unix/Makefile.in: Don't subst MATH_LIBS, LIBS, and DL_LIBS
+	separately. Instead, just subst TCL_LIBS since it includes the
+	others.
+	* unix/configure: Regen.
+	* unix/tcl.m4 (SC_CONFIG_CFLAGS, SC_TCL_LINK_LIBS): Set and subst
+	TCL_LIBS in SC_CONFIG_CFLAGS instead of SC_TCL_LINK_LIBS. Don't subst
+	MATH_LIBS since it is now covered by TCL_LIBS.
+	* unix/tclConfig.sh.in: Use TCL_LIBS instead of DL_LIBS, LIBS, and
+	MATH_LIBS.
+	* unix/dltest/Makefile.in: Ditto.
+
+2003-04-03  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclCompCmds.c (TclCompileReturnCmd):  Now that [return]
+	compiles to INST_RETURN, it is safe to compile even outside a proc.
+
+2003-04-02  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* win/configure: Regen.
+	* win/configure.in: Set stub lib flag based on new LIBFLAGSUFFIX
+	variable.
+	* win/tcl.m4 (SC_CONFIG_CFLAGS): Set new LIBFLAGSUFFIX that works like
+	LIBSUFFIX, it is used when creating library names. The previous
+	implementation would generate -ltclstub85 instead of -ltclstub85s when
+	configured with --disable-shared.
+
+2003-04-02  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclParse.c (TclSubstTokens):  Moved declaration of
+	utfCharBytes to beginning of procedure so that it does not go out of
+	scope (get free()d) while append is still pointing to it. [Bugs
+	703167, 713754]
+
+2003-04-01  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* unix/configure: Regen.
+	* unix/tcl.m4 (SC_CONFIG_CFLAGS): Check for inet_ntoa in -lbind inside
+	the BeOS block since doing it later broke the build under SuSE 7.3.
+	[Bug 713128]
+
+2003-04-01  Don Porter  <dgp@users.sourceforge.net>
+
+	* tests/README:  Direct [source] of *.test files is no longer
+	recommended. The tests/*.test files should only be evaluated under the
+	control of the [runAllTests] command in tests/all.tcl.
+
+	* generic/tclExecute.c (INST_RETURN):  Bytecompiled [return] failed to
+	reset iPtr->returnCode, causing tests parse-18.17 and parse-18.21 to
+	fail strangely.
+	* tests/parse.test (parse-18.21):  Corrected now functioning test.
+	Added further coverage tests.
+
+2003-03-31  Don Porter  <dgp@users.sourceforge.net>
+
+	* tests/parse.test (parse-18.*):  Coverage tests for the new
+	implementation of Tcl_SubstObj(). Note that tests parse-18.17 and
+	parse-18.21 demonstrate some bugs left to fix in the current code.
+
+2003-03-27  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* unix/configure: Regen.
+	* unix/tcl.m4 (SC_CONFIG_CFLAGS): Use -Wl,--export-dynamic instead of
+	-rdynamic for LDFLAGS. The -rdynamic is not documented so it seems
+	better to pass the --export-dynamic flag to the linker. [Patch 573395]
+
+2003-03-27  Miguel Sofer <msofer@users.sf.net>
+
+	* tests/encoding.test:
+	* tests/proc-old.test:
+	* tests/set-old.test: Altered test numers to eliminate duplicates,
+	[Bugs 710313, 710320, 710352]
+
+2003-03-27  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* tests/parseOld.test:	Altered test numers to eliminate duplicates.
+	* tests/parse.test:	[Bugs 710365, 710369]
+	* tests/expr-old.test:
+	* tests/expr.test:
+
+	* tests/utf.test:	Altered test numers to eliminate duplicates.
+	* tests/trace.test:	[Bugs 710322, 710327, 710349, 710363]
+	* tests/lsearch.test:
+	* tests/list.test:
+	* tests/info.test:
+	* tests/incr-old.test:
+	* tests/if-old.test:
+	* tests/format.test:
+	* tests/foreach.test:
+
+2003-03-26  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* unix/configure: Regen.
+	* unix/tcl.m4 (SC_CONFIG_CFLAGS, SC_TCL_LINK_LIBS): Add BeOS system to
+	SC_CONFIG_CFLAGS. Check for inet_ntoa in -lbind, needed for BeOS.
+
+2003-03-26  Don Porter  <dgp@users.sourceforge.net>
+
+	* doc/tcltest.n:
+	* library/tcltest/tcltest.tcl:  Added reporting during [configure
+	-debug 1] operations to warn about multiple uses of the same test
+	name. [FRQ 576693]
+
+	* tests/msgcat.test (msgcat-2.2.1): changed test name to avoid
+	duplication. [Bug 710356]
+
+	* unix/dltest/pkg?.c:  Changed all Tcl_InitStubs calls to pass
+	argument exact = 0, so that rebuilds are not required when Tcl
+	bumps to a new version.  [Bug 701926]
+
+2003-03-24  Miguel Sofer <msofer@users.sf.net>
+
+	* generic/tclVar.c:
+	* tests/var.test: fixing ObjMakeUpvar's lookup algorithm for the
+	created local variable. [Bug 631741] (Chris Darroch) and [Bug 696893]
+	(David Hilker)
+
+2003-03-24  Pat Thoyts  <patthoyts@users.sourceforge.net>
+
+	* library/dde/pkgIndex.tcl: bumped version to 1.2.2 in tclWinDde.c,
+	now adding here too.
+
+2003-03-22  Kevin Kenny  <kennykb@acm.org>
+
+	* library/dde/pkgIndex.tcl:
+	* library/reg/pkgIndex.tcl: Fixed a bug where [package require dde]
+	or [package require registry] attempted to load the release version
+	of the DLL into a debug build. [Bug 708218] Thanks to Joe Mistachkin
+	for the patch.
+	* win/makefile.vc: Added quoting around the script name in the 'test'
+	target; Joe Mistachkin insists that he has a configuration that fails
+	to launch tcltest without it, and it appears harmless otherwise.
+
+2003-03-22  Pat Thoyts  <patthoyts@users.sourceforge.net>
+
+	* win/tclWinDde.c: Make dde services conform the the documentation
+	such that giving only a topic name really returns all services with
+	that topic. [Bug 219155]
+	Prevent hangup caused by dde server applications failing to process
+	messages. [Bug 707822]
+	* tests/winDde.test: Corrected labels and added a test for search by
+	topic name.
+
+2003-03-20  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclInt.h (tclOriginalNotifier):
+	* generic/tclStubInit.c (tclOriginalNotifier):
+	* mac/tclMacNotify.c (Tcl_SetTimer,Tcl_WaitForEvent):
+	* unix/tclUnixNotfy.c (Tcl_SetTimer,Tcl_WaitForEvent,
+	(Tcl_CreateFileHandler,Tcl_DeleteFileHandler):
+	* win/tclWinNotify.c (Tcl_SetTimer,Tcl_WaitForEvent):  Some linkers
+	apparently use a different representation for a pointer to a function
+	within the same compilation unit and a pointer to a function in a
+	different compilation unit. This causes checks like those in the
+	original notifier procedures to fall into infinite loops. The fix is
+	to store pointers to the original notifier procedures in a struct
+	defined in the same compilation unit as the stubs tables, and compare
+	against those values. [Bug 707174]
+
+	* generic/tclInt.h:  Removed definition of ParseValue struct that is
+	no longer used.
+
+2003-03-19  Miguel Sofer <msofer@users.sf.net>
+
+	* generic/tclCompile.c:
+	* tests/compile.test: bad command count on TCL_OUT_LINE_COMPILE.
+	[Bug 705406] (Don Porter)
+
+2003-03-19  Don Porter  <dgp@users.sourceforge.net>
+
+	* library/auto.tcl:		Replaced [regexp] and [regsub] with
+	* library/history.tcl:		[string map] where possible.  Thanks
+	* library/ldAout.tcl:		to David Welton. [Bugs 667456,667558]
+	* library/safe.tcl:		Bumped to http 2.4.3, opt 0.4.5, and
+	* library/http/http.tcl:	tcltest 2.2.3.
+	* library/http/pkgIndex.tcl:
+	* library/opt/optparse.tcl:
+	* library/opt/pkgIndex.tcl:
+	* library/tcltest/tcltest.tcl:
+	* library/tcltest/pkgIndex.tcl:
+	* tools/genStubs.tcl:
+	* tools/tcltk-man2html.tcl:
+	* unix/mkLinks.tcl:
+
+	* doc/Eval.3 (Tcl_EvalObjEx):			Corrected CONST and
+	* doc/ParseCmd.3 (Tcl_EvalTokensStandard):	return type errors in
+	documentation. [Bug 683994]
+
+	* generic/tclCompCmds.c (TclCompileReturnCmd):  Alternative fix for
+	* generic/tclCompile.c (INST_RETURN):	[Bug 633204] that uses a new
+	* generic/tclCompile.h (INST_RETURN):	bytecode INST_RETURN to
+	* generic/tclExecute.c (INST_RETURN):	properly bytecode the [return]
+	command to something that returns TCL_RETURN.
+
+2003-03-18  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* win/configure: Regen.
+	* win/configure.in: Don't run the AC_CYGWIN macro since it uses
+	AC_CANONICAL_HOST under autoconf 2.5X. Just check to see if __CYGWIN__
+	is defined by the compiler and set the ac_cv_cygwin variable based on
+	that. [Bug 705912]
+
+2003-03-18  Kevin Kenny  <kennykb@users.sourceforge.net>
+
+	* tests/registry.test: Changed the conditionals to avoid an abort if
+	[testlocale] is missing, as when running the test in tclsh rather than
+	tcltest. [Bug 705677]
+
+2003-03-18  Daniel Steffen  <das@users.sourceforge.net>
+
+	* tools/tcltk-man2html.tcl: added support for building 'make html'
+	from inside distribution directories named with 8.x.x version numbers.
+	tcltk-man2html now uses the latest tcl8.x.x resp. tk8.x.x directories
+	found inside its --srcdir argument.
+
+2003-03-17  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* tests/format.test: Renumber tests, a bunch of tests all had the same
+	id.
+
+2003-03-17  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* doc/lsearch.n:	Altered documentation of -ascii options so
+	* doc/lsort.n:		they don't specify that they operate on ASCII
+				strings, which they never did anyway. [Bug
+				703807]
+
+2003-03-14  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* generic/tclCmdAH.c (Tcl_FormatObjCmd): Only add the modifier that
+	indicates we've got a wide int when we're formatting in an integer
+	style.  Stops some libc's from going mad. [Bug 702622] Also tidied
+	whitespace.
+
+2003-03-13  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* win/tcl.m4 (SC_WITH_TCL): Port version number fix that was made in
+	tk instead of tcl sources.
+
+2003-03-13  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	Require autoconf 2.57 or newer, see TIP 34 for a detailed explanation
+	of why this is good. This will no doubt break the build on some
+	platforms, let the flaming begin.
+
+	* tools/configure: Regen with autoconf 2.57.
+	* tools/configure.in: Require autoconf 2.57.
+	* unix/configure: Regen with autoconf 2.57.
+	* unix/configure.in: Require autoconf 2.57.
+	Apply AC_LIBOBJ changes from patch 529884.
+	* unix/tcl.m4: Ditto.
+	* win/configure: Regen with autoconf 2.57.
+	* win/configure.in: Require autoconf 2.57.
+	Don't subst LIBOBJS since this happens by default, this avoids an
+	autoconf error.
+
+2003-03-12  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclBasic.c (Tcl_EvalTokensStandard):
+	* generic/tclCmdMZ.c (Tcl_SubstObj):
+	* generic/tclCompCmds.c (TclCompileSwitchCmd):
+	* generic/tclCompExpr.c (CompileSubExpr):
+	* generic/tclCompile.c (TclSetByteCodeFromAny,TclCompileScript,
+	(TclCompileTokens,TclCompileCmdWord):
+	* generic/tclCompile.h (TclCompileScript):
+	* generic/tclExecute.c (TclCompEvalObj):
+	* generic/tclInt.h (Interp,TCL_BRACKET_TERM,TclSubstTokens):
+	* generic/tclParse.c (ParseTokens,Tcl_SubstObj,TclSubstTokens):
+	* tests/subst.test (2.4, 8.7, 8.8, 11.4, 11.5):
+	Substantial refactoring of Tcl_SubstObj to make use of the same
+	parsing and substitution procedures as normal script evaluation.
+	Tcl_SubstObj() moved to tclParse.c. New routine TclSubstTokens()
+	created in tclParse.c which implements all substantial functioning of
+	Tcl_EvalTokensStandard(). TclCompileScript() loses its "nested"
+	argument, the Tcl_Interp struct loses its termOffset field and the
+	TCL_BRACKET_TERM flag in the evalFlags field, all of which were only
+	used (indirectly) by Tcl_SubstObj(). Tests subst-8.7,8.8,11.4,11.5
+	modified to accomodate the only behavior change: reporting of parse
+	errors now takes precedence over [return] and [continue] exceptions.
+	All other behavior should remain compatible. [RFE 536831,684982] [Bug
+	685106]
+
+	* generic/tcl.h:        Removed TCL_PREFIX_IDENT and TCL_DEBUG_IDENT
+	* win/tclWinPipe.c:     from tcl.h -- they are not part of Tcl's
+	public interface.  Put them in win/tclWinPipe.c where they are used.
+
+	* generic/tclInterp.c (Tcl_InterpObjCmd):       Corrected and added
+	* tests/interp.test (interp-2.13):              test for option
+	parsing beyond objc for [interp create --]. Thanks to Marco Maggi.
+	[Bug 702383]
+
+2003-03-11  Kevin Kenny  <kennykb@users.sourceforge.net>
+
+	* win/makefile.vc: Added two missing uses of $(DBGX) so that
+	tclpip8x.dll loads without panicking on Win9x.
+
+2003-03-09  Kevin Kenny  <kennykb@users.sourceforge.net>
+
+	* generic/tclTest.c (TestChannelCmd): Removed an unused local variable
+	that caused compilation problems on some platforms.
+
+2003-03-08  Don Porter  <dgp@users.sourceforge.net>
+
+	* doc/tcltest.n:  Added missing "-body" to example. Thanks to Helmut
+	Giese. [Bug 700011]
+
+2003-03-07  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* tests/io.test:
+	* tests/ioCmd.test: Define a fcopy constraint and add it to the
+	constraint list of any test that depends on the fcopy command. This is
+	only useful to Jacl which does not support fcopy.
+
+2003-03-07  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* tests/encoding.test: Name temp files *.tcltestout instead of *.out
+	so that when they are removed later, we don't accidently toast any
+	files named *.out that the user has created in the build directory.
+
+2003-03-07  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* generic/tclCmdAH.c (Tcl_FileObjCmd): Fix the setting of a file's
+	mtime and atime on 64-bit platforms. [Bug 698146]
+
+2003-03-06  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* tests/io.test: Doh! Undo accidental commenting out of a couple of
+	tests.
+
+2003-03-06  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* tests/io.test: Define a fileevent constraint and add it to the
+	constraint list of any test that depends on the fileevent command.
+	This is only useful to Jacl which does not support fileevent.
+
+2003-03-06  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* tests/io.test: Define an openpipe constraint and add it to the
+	constraint list of any test that creates a pipe using the open
+	command. This is only useful to Jacl which does not support pipes.
+
+2003-03-06  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/TclUtf.c (Tcl_UniCharNcasecmp):       Corrected failure to
+	* tests/utf.test (utf-25.*):    properly compare Unicode strings of
+	different case in a case insensitive manner.  [Bug 699042]
+
+2003-03-06  Kevin Kenny  <kennykb@users.sourceforge.net>
+
+	* generic/tclCompCmds.c (TclCompileSwitchCmd):
+	Replaced a non-portable 'bzero' with a portable 'memset'. [Bug 698442]
+
+2003-03-06  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* generic/tclIO.c (Tcl_Seek, Tcl_OutputBuffered): If there is data
+	buffered in the statePtr->curOutPtr member then set the BUFFER_READY
+	flag in Tcl_Seek. This is needed so that the next call to FlushChannel
+	will write any buffered bytes before doing the seek. The existing code
+	would set the BUFFER_READY flag inside the Tcl_OutputBuffered
+	function. This was a programming error made when Tcl_OutputBuffered
+	was originally created in CVS revision 1.35. The setting of the
+	BUFFER_READY flag should not have been included in the
+	Tcl_OutputBuffered function.
+	* generic/tclTest.c (TestChannelCmd): Use the Tcl_InputBuffered and
+	Tcl_OutputBuffered util methods to query the amount of buffered input
+	and output.
+
+2003-03-06  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* generic/tclIO.c (Tcl_Flush): Compare the nextAdded member of the
+	ChannelBuffer to the nextRemoved member to determine if any output has
+	been buffered. The previous check against the value 0 seems to have
+	just been a coding error. See other methods like Tcl_OutputBuffered
+	for examples where nextAdded is compared to nextRemoved to find the
+	number of bytes buffered.
+
+2003-03-06  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* generic/tclIO.c (Tcl_GetsObj): Check that the eol pointer has not
+	gone past the end of the string when in auto translation mode and the
+	INPUT_SAW_CR flag is set. The previous code worked because the end of
+	string value \0 was being compared to \n, this patch just skips that
+	pointless check.
+
+2003-03-06  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* generic/tclIO.c (WriteBytes, WriteChars, Tcl_GetsObj, ReadBytes):
+	Rework calls to TranslateOutputEOL to make it clear that a boolean
+	value is being returned. Add some comments in an effort to make the
+	code more clear. This patch makes no functional changes.
+
+2003-03-06  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* generic/tclIO.c (Tcl_SetChannelOption): Invoke the
+	Tcl_SetChannelBufferSize method as a result of changing the
+	-buffersize option to fconfigure. The previous implementation used
+	some inlined code that reset the buffer size to the default size
+	instead of ignoring the request as implemented in
+	Tcl_SetChannelBufferSize.
+	* tests/io.test: Update test case so that it actually checks the
+	implementation of Tcl_SetChannelBufferSize.
+
+2003-03-05  David Gravereaux  <davygrvy@pobox.com>
+
+	* win/rules.vc: updated default tcl version to 8.5.
+
+2003-03-05  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* generic/tclCompCmds.c (TclCompileSwitchCmd): First attempt at a
+	bytecode-compiled switch command. It only handles the most common case
+	of switching, but that should be enough for this to speed up a lot of
+	people's code. It is expected that the speed gains come from two
+	things: better handling of the switch itself, and integrated
+	compilation of the arms instead of embedding separate bytecode
+	sequences (i.e. better local variable handling.)
+	* tests/switch.test (switch-10.*): Tests of both uncompiled and
+	compiled switch behaviour. [Patch #644819]
+
+	* generic/tclCompile.h (TclFixupForwardJumpToHere): Additional macro
+	to make the most common kind of jump fixup a bit easier.
+
+2003-03-04  Don Porter	<dgp@users.sourceforge.net>
+
+	* README:				Bumped version number of
+	* generic/tcl.h:			Tcl to 8.5a0.
+	* library/init.tcl:
+	* mac/README:
+	* macosx/Tcl.pbproj/project.pbxproj:
+	* tests/basic.test:
+	* tools/configure.in:
+	* tools/tcl.hpj.in:
+	* tools/tcl.wse.in:
+	* unix/configure.in:
+	* unix/tcl.spec:
+	* win/README:
+	* win/README.binary:
+	* win/configure.in:
+	* win/makefile.bc:
+	* win/makefile.vc:
+	* win/tcl.m4:
+
+	* tools/configure:	autoconf
+	* unix/configure:
+	* win/configure:
+
+2003-03-03  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	*** 8.4.2 TAGGED FOR RELEASE ***
+
+2003-03-03  Daniel Steffen  <das@users.sourceforge.net>
+
+	Mac OS Classic specific fixes:
+	* generic/tclIOUtil.c (TclNewFSPathObj): on TCL_PLATFORM_MAC, skip
+	potential directory separator at the beginning of addStrRep.
+	* mac/tclMacChan.c (OpenFileChannel, CommonWatch): followup fixes to
+	cut and splice implementation for file channels.
+	* mac/tclMacFile.c (TclpUtime): pass native path to utime().
+	* mac/tclMacFile.c (TclpObjLink): correctly implemented creation of
+	alias files via new static proc CreateAliasFile().
+	* mac/tclMacPort.h: define S_ISLNK macro to fix stat'ing of links.
+	* mac/tclMacUtil.c (FSpLocationFromPathAlias): fix to enable stat'ing
+	of broken links.
+
+2003-03-03  Kevin Kenny  <kennykb@users.sourceforge.net>
+
+	* win/Makefile.vc: corrected bug introduced by 'g' for debug builds.
+
+2003-03-03  Don Porter	<dgp@users.sourceforge.net>
+
+	* library/dde/pkgIndex.tcl:	dde bumped to version 1.2.1 for
+	* win/tclWinDde.c:		bundled release with Tcl 8.4.2
+
+	* library/reg/pkgIndex.tcl:	registry bumped to version 1.1.1 for
+	* win/tclWinReg.c:		bundled release with Tcl 8.4.2
+
+	* library/opt/pkgIndex.tcl:	updated package index to version 0.4.4
+
+2003-02-28  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* win/configure:
+	* win/configure.in: check for 'g' for debug build type, not 'd'.
+	* win/rules.vc (DBGX): correct to use 'g' for nmake win makefile to
+	match the cygwin makefile for debug builds. [Bug 635107]
+
+2003-02-28  Vince Darley  <vincentdarley@users.sourceforge.net>
+
+	* doc/file.n: subcommand is 'file volumes' not 'file volume'
+
+2003-02-27  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* generic/tclIOUtil.c (MakeFsPathFromRelative): removed dead code
+	check of typePtr (darley).
+
+	* tests/winTime.test: added note about PCI hardware dependency issues
+	with high performance clock.
+
+2003-02-27  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* tests/lsearch.test (lsearch-10.7):
+	* generic/tclCmdIL.c (Tcl_LsearchObjCmd): Stopped -start option from
+	causing an option when used with an empty list. [Bug 694232]
+
+2003-02-26  Chengye Mao <chengye.geo@yahoo.com>
+
+	* win/tclWinInit.c: fixed a bug in TclpSetVariables by initializing
+	dwUserNameLen with the sizeof(szUserName) before calling GetUserName.
+	Don't know if this bug has been recorded: it caused crash in starting
+	Tcl or wish in Windows.
+
+2003-02-26  Jeff Hobbs	<jeffh@ActiveState.com>
+
+	* generic/tclCmdMZ.c (TraceCommandProc): Fix mem leak when deleting a
+	command that had trace on it. [Bug 693564] (sofer)
+
+2003-02-25  Don Porter	<dgp@users.sourceforge.net>
+
+	* doc/pkgMkIndex.n:	Modified [pkg_mkIndex] to use -nocase matching
+	* library/package.tcl:	of -load patterns, to better accomodate common
+	user errors due to confusion between [package names] names and [info
+	loaded] names.
+
+2003-02-25  Andreas Kupries  <andreask@pliers.activestate.com>
+
+	* tests/pid.test: See below [Bug 678412].
+	* tests/io.test: Made more robust against spaces in paths [Bug 678400]
+
+2003-02-25  Miguel Sofer <msofer@users.sf.net>
+
+	* tests/execute.test: cleaning up testobj's at the end, to avoid
+	  leak warning by valgrind.
+
+2003-02-22  Zoran Vasiljevic  <zoran@archiwrae.com>
+
+	* generic/tclEvent.c (Tcl_FinalizeThread): Fix [Bug 571002]
+
+2003-02-21  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* tests/binary.test (binary-44.[34]):
+	* generic/tclBinary.c (ScanNumber): Fixed problem with unwanted
+	sign-bit propagation when scanning wide ints. [Bug 690774]
+
+2003-02-21  Daniel Steffen  <das@users.sourceforge.net>
+
+	* mac/tclMacChan.c (TclpCutFileChannel, TclpSpliceFileChannel):
+	Implemented missing cut and splice procs for file channels.
+
+2003-02-21  Don Porter  <dgp@users.sourceforge.net>
+
+	* library/package.tcl (tclPkgUnknown):  Minor performance tweaks to
+	reduce the number of [file] invocations. Meant to improve startup
+	times, at least a little bit. [Patch 687906]
+
+2003-02-20  Daniel Steffen  <das@users.sourceforge.net>
+
+	* unix/tcl.m4:
+	* unix/tclUnixPipe.c: (macosx) use vfork() instead of fork() to create
+	new processes, as recommended by Apple (vfork can be up to 100 times
+	faster thank fork on macosx).
+	* unix/configure: regen.
+
+2003-02-20  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* generic/tclEncoding.c (LoadTableEncoding):
+	* library/encoding/cp932.enc:      Correct jis round-trip encoding
+	* library/encoding/euc-jp.enc:     by adding 'R' type to .enc files.
+	* library/encoding/iso2022-jp.enc: [Patch 689341] (koboyasi, taguchi)
+	* library/encoding/jis0208.enc:
+	* library/encoding/shiftjis.enc:
+	* tests/encoding.test:
+
+	* unix/tclUnixChan.c (Tcl_MakeTcpClientChannel): add
+	MakeTcpClientChannelMode that takes actual mode flags to avoid hang on
+	OS X (may be OS X bug, but patch works x-plat). [Bug 689835] (steffen)
+
+2003-02-20  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* doc/regsub.n: Typo fix [Bug 688943]
+
+2003-02-19  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* unix/tclUnixThrd.c (TclpReaddir):
+	* unix/tclUnixPort.h: update to Bug 689100 patch to ensure that there
+	is a defined value of MAXNAMLEN (aka NAME_MAX in POSIX) and that we
+	have some buffer allocated.
+
+2003-02-19  Daniel Steffen  <das@users.sourceforge.net>
+
+	* generic/tclStringObj.c: restored Tcl_SetObjLength() side-effect of
+	always invalidating unicode rep (if the obj has a string rep). Added
+	hasUnicode flag to String struct, allows decoupling of validity of
+	unicode rep from buffer size allocated to it (improves memory
+	allocation efficiency). [Bugs 686782, 671138, 635200]
+
+	* macosx/Tcl.pbproj/project.pbxproj:
+	* macosx/Makefile: reworked embedded build to no longer require
+	relinking but to use install_name_tool instead to change the
+	install_names for embedded frameworks. [Bug 644510]
+
+	* macosx/Tcl.pbproj/project.pbxproj: preserve mod dates when running
+	'make install' to build framework (avoids bogus rebuilds of dependent
+	frameworks because tcl headers appear changed).
+
+	* tests/ioCmd.test (iocmd-1.8): fix failure when system encoding is
+	utf-8: use iso8859-1 encoding explicitly.
+
+2003-02-18  Miguel Sofer <msofer@users.sf.net>
+
+	* generic/tclCompile.c (TclCompileExprWords): remove unused variable
+	"range" [Bug 664743]
+	* generic/tclExecute.c (ExprSrandFunc): remove unused variable
+	"result" [Bug 664743]
+	* generic/tclStringObj.c (UpdateStringOfString): remove unused
+	variable "length" [Bug 664751]
+	* tests/execute.test (execute-7.30): fix for [Bug 664775]
+
+2003-02-18  Andreas Kupries  <andreask@activestate.com>
+
+	* unix/tcl.m4: [Bug #651811] Added definition of _XOPEN_SOURCE and
+	linkage of 'xnet' library to HP 11 branch. This kills a lot of
+	socket-related failures in the testsuite when Tcl was compiled in 64
+	bit mode (both PA-RISC 2.0W, and IA 64).
+
+	* unix/configure: Regenerated.
+
+2003-02-18  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* generic/tclIO.c (HaveVersion): correctly decl static
+
+	* unix/tclUnixThrd.c (TclpReaddir): reduce size of name string in tsd
+	to NAME_MAX instead of PATH_MAX. [Bug 689100] (waters)
+
+2003-02-18  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* unix/configure: Regen.
+	* unix/tcl.m4 (SC_ENABLE_THREADS): Make sure -lpthread gets passed on
+	the link line when checking for the pthread_attr_setstacksize symbol.
+
+2003-02-18  Vince Darley  <vincentdarley@users.sourceforge.net>
+
+	* generic/tclTest.c: cleanup of new 'simplefs' test code, and better
+	documentation.
+
+2003-02-17  Miguel Sofer <msofer@users.sf.net>
+
+	* generic/tclBasic.c (TclRenameCommand): fixing error in previous
+	commit.
+
+2003-02-17  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* generic/tclExecute.c (TclExecuteByteCode INST_STR_MATCH):
+	* generic/tclCmdMZ.c (Tcl_StringObjCmd STR_MATCH):
+	* generic/tclUtf.c (TclUniCharMatch):
+	* generic/tclInt.decls:  add private TclUniCharMatch function that
+	* generic/tclIntDecls.h: does string match on counted unicode
+	* generic/tclStubInit.c: strings. Tcl_UniCharCaseMatch has the failing
+	* tests/string.test:     that it can't handle strings or patterns with
+	* tests/stringComp.test: embedded NULLs. Added tests that actually try
+	strings/pats with NULLs. TclUniCharMatch should be TIPed and made
+	public in the next minor version rev.
+
+2003-02-17  Miguel Sofer <msofer@users.sf.net>
+
+	* generic/tclBasic.c (TclRenameCommand): 'oldFullName' object was not
+	being freed on all function exits, causing a memory leak. [Bug 684756]
+
+2003-02-17  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* generic/tclIO.c (Tcl_GetsObj): Minor change so that eol is only
+	assigned at the top of the TCL_TRANSLATE_AUTO case block. The other
+	cases assign eol so this does not change any functionality.
+
+2003-02-17  Kevin Kenny  <kennykb@users.sourceforge.net>
+
+	* tests/notify.test: Removed Windows line terminators. [Bug 687913].
+
+2003-02-15  Miguel Sofer <msofer@users.sf.net>
+
+	* generic/tclBasic.c (Tcl_EvalEx):
+	* generic/tclCompExpr.c (CompileSubExpr):
+	* generic/tclCompile.c (TclCompileScript):
+	* generic/tclParse.c (Tcl_ParseCommand, ParseTokens):
+	* generic/tclParseExpr.c (ParsePrimaryExpr):
+	* tests/basic.test (47.1):
+	* tests/main.test (3.4):
+	* tests/misc.test (1.2):
+	* tests/parse.test (6.18):
+	* tests/parseExpr.test (15.35):
+	* tests/subst.test (8.6): Don Porter's fix for bad parsing of nested
+	scripts. [Bug 681841]
+
+2003-02-15  Kevin Kenny  <kennykb@users.sourceforge.net>
+
+	* tests/notify.test (new-file):
+	* generic/tclTest.c (TclTest_Init, EventtestObjCmd, EventtestProc,
+	(EventTestDeleteProc):
+	* generic/tclNotify.c (Tcl_DeleteEvents): Fixed Tcl_DeleteEvents not
+	to get a pointer smash when deleting the last event in the queue.
+	Added test code in 'tcltest' and a new file of test cases
+	'notify.test' to exercise this functionality; several of the new test
+	cases fail for the original code and pass for the corrected code. [Bug
+	673714]
+
+	* unix/tclUnixTest.c (TestfilehandlerCmd): Corrected a couple of typos
+	in error messages. [Bug 596027]
+
+2003-02-14  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* README:		Bumped to version 8.4.2.
+	* generic/tcl.h:
+	* tools/tcl.wse.in:
+	* unix/configure:
+	* unix/configure.in:
+	* unix/tcl.m4:
+	* unix/tcl.spec:
+	* win/README.binary:
+	* win/configure:
+	* win/configure.in:
+	* macosx/Tcl.pbproj/project.pbxproj:
+
+	* generic/tclStringObj.c (Tcl_GetCharLength): perf tweak
+
+	* unix/tcl.m4: correct HP-UX ia64 --enable-64bit build flags
+
+2003-02-14  Kevin Kenny  <kennykb@users.sourceforge.net>
+
+	* win/tclWinTime.c: Added code to test and compensate for forward
+	leaps of the performance counter. See the MSDN Knowledge Base article
+	Q274323 for the hardware problem that makes this necessary on certain
+	machines.
+	* tests/winTime.test: Revised winTime-2.1 - it had a tolerance of
+	thousands of seconds, rather than milliseconds. (What's six orders of
+	magnitude among friends?) Both the above changes are triggered by a
+	problem reported at:
+	http://aspn.activestate.com/ASPN/Mail/Message/ActiveTcl/1536811
+	although the developers find it difficult to believe that it accounts
+	for the observed behavior and suspect a fault in the RTC chip.
+
+2003-02-13  Kevin Kenny  <kennykb@users.sourceforge.net>
+
+	* win/tclWinInit.c: Added conversion from the system encoding to
+	tcl_platform(user), so that it works with non-ASCII7 user names. [Bug
+	685926]
+
+	* doc/tclsh.1: Added language to describe the handling of the
+	end-of-file character \u001a embedded in a script file. [Bug 685485]
+
+2003-02-11  Vince Darley  <vincentdarley@users.sourceforge.net>
+
+	* tests/fileName.test:
+	* unix/tclUnixFile.c: fix for [Bug 685445] when using 'glob -l' on
+	broken symbolic links. Added two new tests for this bug.
+
+2003-02-11  Kevin Kenny  <kennykb@users.sourceforge.net>
+
+	* tests/http.test: Corrected a problem where http-4.14 would fail when
+	run in an environment with a proxy server. Replaced references to
+	scriptics.com by tcl.tk.
+
+2003-02-11  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* tests/lsearch.test:
+	* generic/tclCmdIL.c (Tcl_LsearchObjCmd): protect against the case
+	that lsearch -regepx list and pattern objects are equal.
+
+	* tests/stringObj.test:
+	* generic/tclStringObj.c (Tcl_GetCharLength): correct ascii char opt
+	of 2002-11-11 to not stop early on \x00. [Bug 684699]
+
+	* tests.parse.test: remove excess EOF whitespace
+
+	* generic/tclParse.c (CommandComplete): more paranoid check to break
+	on (p >= end) instead of just (p == end).
+
+2003-02-11  Miguel Sofer <msofer@users.sf.net>
+
+	* generic/tclParse.c (CommandComplete):
+	* tests/parse.test: fix for [Bug 684744], by Don Porter.
+
+2003-02-11  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* generic/tclIOUtil.c (Tcl_FSJoinPath, Tcl_FSGetNormalizedPath):
+	(UpdateStringOfFsPath): revert the cwdLen == 0 check and instead
+	follow a different code path in Tcl_FSJoinPath.
+	(Tcl_FSConvertToPathType, Tcl_FSGetNormalizedPath):
+	(Tcl_FSGetFileSystemForPath): Update string rep of path objects before
+	freeing the internal object. (darley)
+
+	* tests/fileSystem.test: added test 8.3
+	* generic/tclIOUtil.c (Tcl_FSGetNormalizedPath):
+	(UpdateStringOfFsPath): handle the cwdLen == 0 case
+
+	* unix/tclUnixFile.c (TclpMatchInDirectory): simplify the hidden file
+	match check.
+
+2003-02-10  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* win/configure:
+	* win/configure.in: Generate error when attempting to build under
+	Cygwin. The Cygwin port of Tcl/Tk does not build and people are filing
+	bug reports under the mistaken impression that someone is actually
+	maintaining the Cygwin port. A post to comp.lang.tcl asking someone to
+	volunteer as an area maintainer has generated no results. Closing bugs
+	680840, 630199, and 634772 and marking as "Won't fix".
+
+2003-02-10  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* doc/append.n: Return value was not documented. [Bug 683188]
+
+2003-02-10  Vince Darley  <vincentdarley@users.sourceforge.net>
+
+	* doc/FileSystem.3:
+	* generic/tclIOUtil.c:
+	* generic/tclInt.h:
+	* tests/fileSystem.test:
+	* unix/tclUnixFCmd.c:
+	* unix/tclUnixFile.c:
+	* win/tclWinFile.c: further filesystem optimization, applying [Patch
+	682500]. In particular, these code examples are faster now:
+	    foreach f $flist { if {[file exists $f]} {file stat $f arr;...}}
+	    foreach f [glob -dir $dir *] { # action and/or recursion on $f }
+	    cd $dir
+	    foreach f [glob *] { # action and/or recursion on $f }
+	    cd ..
+
+	* generic/tclTest.c: Fix for [Bug 683181] where test suite left files
+	in 'tmp'.
+
+2003-02-08  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* library/safe.tcl: code cleanup of eval and string comp use.
+
+2003-02-07  Vince Darley  <vincentdarley@users.sourceforge.net>
+
+	* win/tclWinFCmd.c: cleanup long lines
+	* win/tclWinFile.c: sped up pure 'glob' by a factor of 2.5
+	('foreach f [glob *] { file exists $f }' is still slow)
+	* tests/fileSystem.text:
+	* tests/fileName.test: added new tests to ensure correct behaviour in
+	optimized filesystem code.
+
+2003-02-07  Vince Darley  <vincentdarley@users.sourceforge.net>
+
+	* generic/tclTest.c:
+	* tests/fileSystem.text: fixed test 7.2 to avoid a possible crash, and
+	not change the pwd.
+
+	* tests/http.text: added comment to test 4.15, that it may fail if you
+	use a proxy server.
+
+2003-02-06  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* generic/tclCompCmds.c (TclCompileIncrCmd):
+	* tests/incr.test: Don't include the text "(increment expression)" in
+	the errorInfo generated by the compiled version of the incr command
+	since it does not match the message generated by the non-compiled
+	version of incr. It is also not possible to match this error output
+	under Jacl, which does not support a compiler.
+
+2003-02-06  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* generic/tclExecute.c (TclExecuteByteCode): When an error is
+	encountered reading the increment value during a compiled call to
+	incr, add a "(reading increment)" error string to the errorInfo
+	variable. This makes the errorInfo variable set by the compiled incr
+	command match the value set by the non-compiled version.
+	* tests/incr-old.test: Change errorInfo result for the compiled incr
+	command case to match the modified implementation.
+	* tests/incr.test: Add tests to make sure the compiled and
+	non-compiled errorInfo messages are the same.
+
+2003-02-06  Don Porter  <dgp@users.sourceforge.net>
+
+	* library/tcltest/tcltest.tcl:  Filename arguments to [outputChannel]
+	and [errorChannel] (also -outfile and -errfile) were [open]ed but
+	never [closed]. Also, [cleanupTests] could remove output or error
+	files. [Bug 676978].
+	* library/tcltest/pkgIndex.tcl: Bumped to version 2.2.2.
+
+2003-02-05  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* tests/interp.test:
+	* tests/set-old.test: Run test cases that depend on hash order through
+	lsort so that the tests also pass under Jacl. Does not change test
+	results under Tcl.
+
+2003-02-04  Vince Darley  <vincentdarley@users.sourceforge.net>
+
+	* generic/tclIOUtil.c:
+	* generic/tclEvent.c:
+	* generic/tclInt.h:
+	* mac/tclMacFCmd.c:
+	* unix/tclUnixFCmd.c:
+	* win/tclWin32Dll.c:
+	* win/tclWinFCmd.c:
+	* win/tclWinInit.c:
+	* win/tclWinInt.h:
+	* tests/fileSystem.test: fix to finalization/unloading/encoding issues
+	to make filesystem much less dependent on encodings for its cleanup,
+	and therefore allow it to be finalized later in the exit process. This
+	fixes fileSystem.test-7.1. Also fixed one more bug in setting of
+	modification dates of files which have undergone cross-platform
+	copies. [Patch 676271]
+
+	* tests/basic.test:
+	* tests/exec.test:
+	* tests/fileName.test:
+	* tests/io.test: fixed some test failures when tests are run from a
+	directory containing spaces.
+
+	* tests/fileSystem.test:
+	* generic/tclTest.c: added regression test for the modification date
+	setting of cross-platform file copies.
+
+2003-02-03  Kevin Kenny  <kennykb@users.sourceforge.net>
+
+	* generic/tclBasic.c: Changed [trace add command] so that 'rename'
+	callbacks get fully qualified names of the command. [Bug 651271].
+	***POTENTIAL INCOMPATIBILITY***
+	* tests/trace.test: Modified the test cases for [trace add command] to
+	expect fully qualified names on the 'rename' callbacks. Added a case
+	for renaming a proc within a namespace.
+	* doc/trace.n: Added language about use of fully qualified names in
+	trace callbacks.
+
+2003-02-01  Kevin Kenny  <kennykb@users.sourceforge.net>
+
+	* generic/tclCompCmds.c: Removed an unused variable that caused
+	compiler warnings on SGI. [Bug 664379]
+
+	* generic/tclLoad.c: Changed the code so that if Tcl_StaticPackage is
+	called to report the same package as being loaded in two interps, it
+	shows up in [info loaded {}] in both of them (previously, it didn't
+	appear in the static package list in the second).
+
+	* tests/load.test Added regression test for the above bug. [Bug
+	670042]
+
+	* generic/tclClock.c: Fixed a bug that incorrectly allowed [clock
+	clicks {}] and [clock clicks -] to be accepted as if they were [clock
+	clicks -milliseconds].
+
+	* tests/clock.test: Added regression tests for the above bug. [Bug
+	675356]
+
+	* tests/unixNotfy.test: Added cleanup of working files. [Bug 675609]
+
+	* doc/Tcl.n: Added headings to the eleven paragraphs, to improve
+	formatting in the tools that attempt to extract tables of contents
+	from the manual pages. [Bug 627455]
+
+	* generic/tclClock.c: Expanded mutex protection around the setting of
+	env(TZ) and the thread-unsafe call to tzset(). [Bug 656660]
+
+2003-01-31  Don Porter  <dgp@users.sourceforge.net>
+
+	* tests/tcltest.test: Cleaned up management of file/directory
+	creation/deletion to improve "-debug 1" output. [Bug 675614]
+	The utility [slave] command failed to properly [list]-quote a
+	constructed [open] command, causing failure when the pathname
+	contained whitespace. [Bug 678415]
+
+	* tests/main.test: Stopped main.test from deleting existing file. Test
+	suite should not delete files that already exist. [Bug 675660]
+
+2003-01-28  Don Porter  <dgp@users.sourceforge.net>
+
+	* tests/main.test: Constrain tests that do not work on Windows. [Bug
+	674387]
+
+2003-01-28  Vince Darley  <vincentdarley@users.sourceforge.net>
+
+	* generic/tclIOUtil.c: fix to setting modification date in
+	TclCrossFilesystemCopy. Also added 'panic' in
+	Tcl_FSGetFileSystemForPath under illegal calling circumstances which
+	lead to hard-to-track-down bugs.
+
+	* generic/tclTest.c: added test suite code to allow exercising a
+	vfs-crash-on-exit bug in Tcl's finalization caused by the encodings
+	being cleaned up before unloading occurs.
+	* tests/fileSystem.test: added new 'knownBug' test 7.1 to demonstrate
+	the crash on exit.
+
+2003-01-28  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* generic/tcl.h: Add TCL_PREFIX_IDENT and TCL_DEBUG_IDENT, used only
+	by TclpCreateProcess.
+	* unix/Makefile.in: Define TCL_DBGX.
+	* win/Makefile.in: Define TCL_DBGX.
+	* win/tclWinPipe.c (TclpCreateProcess): Check that the Tcl pipe dll
+	actually exists in the Tcl bin directory and panic if it is not found.
+	Incorporate TCL_DBGX into the Tcl pipe dll name. This fixes a really
+	mysterious error that would show up when exec'ing a 16 bit application
+	under Win95 or Win98 when Tcl was compiled with symbols. The error
+	seemed to indicate that the executable could not be found, but it was
+	actually the Tcl pipe dll that could not be found.
+
+2003-01-26  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* win/README: Update msys+mingw URL to release 6. This version bundles
+	gcc 3.
+
+2003-01-26  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* win/configure: Regen.
+	* win/configure.in: Add test that checks to see if the compiler can
+	cast to a union type.
+	* win/tclWinTime.c: Squelch compiler warning about union initializer
+	by casting to union type when compiling with gcc.
+
+2003-01-25  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* generic/tclIO.c (Tcl_CutChannel, Tcl_SpliceChannel): Invoke
+	TclpCutFileChannel and TclpSpliceFileChannel.
+	* generic/tclInt.h: Declare TclpCutFileChannel and
+	TclpSpliceFileChannel.
+	* unix/tclUnixChan.c (FileCloseProc, TclpOpenFileChannel,
+	(Tcl_MakeFileChannel, TclpCutFileChannel, TclpSpliceFileChannel):
+	Implement thread load data cut and splice for file channels. This
+	avoids an invalid memory ref when compiled with -DDEPRECATED.
+	* win/tclWinChan.c (FileCloseProc, TclpCutFileChannel,
+	(TclpSpliceFileChannel): Implement thread load data cut and splice for
+	file channels. This avoids an invalid memory ref that was showing up
+	in the thread extension.
+
+2003-01-25  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* win/tclWin32Dll.c (TclpCheckStackSpace, squelch_warnings):
+	* win/tclWinChan.c (Tcl_MakeFileChannel, squelch_warnings):
+	* win/tclWinFCmd.c (DoRenameFile, DoCopyFile, squelch_warnings):
+	Re-implement inline ASM SEH handlers for gcc. The esp and ebp
+	registers are now saved on the stack instead of in global variables so
+	that the code is thread safe. Add additional checks when TCL_MEM_DEBUG
+	is defined to be sure the values were recovered from the stack
+	properly. Remove squelch_warnings functions and add a dummy call in
+	the handler methods to squelch compiler warnings.
+
+2003-01-25  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* win/configure:
+	* win/configure.in: Define HAVE_ALLOCA_GCC_INLINE when we detect that
+	no alloca function is found in malloc.h and we are compiling with GCC.
+	Remove HAVE_NO_ALLOC_DECL define.
+	* win/tclWin32Dll.c (TclpCheckStackSpace): Don't define alloca as a
+	cdecl function. Doing this caused a tricky runtime bug because the
+	_alloca function expects the size argument to be passed in a register
+	and not on the stack. To fix this problem, we use inline ASM when
+	compiling with gcc to invoke _alloca with the size argument loaded
+	into a register.
+
+2003-01-24  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* win/tclWinDde.c (Dde_Init): clarified use of tsdPtr.
+	(DdeServerProc): better refcount handling of returnPackagePtr.
+
+	* generic/tclEvent.c (Tcl_Finalize): revert finalize change on
+	2002-12-04 to correct the issue with extensions that have TSD needing
+	to finalize that before they are unloaded. This issue needs further
+	clarification.
+
+	* tests/unixFCmd.test: only do groups check on unix
+
+2003-01-24  Vince Darley  <vincentdarley@users.sourceforge.net>
+
+	* generic/tclStringObj.c: proper fixes for Tcl_SetObjLength and
+	Tcl_AttemptSetObjectLength dealing with string objects with both
+	pure-unicode and normal internal representations. Previous fix didn't
+	handle all cases correctly.
+	* generic/tclIO.c: Add 'Tcl_GetString()' to ensure the object has a
+	valid 'objPtr->bytes' field before manipulating it directly.
+
+	This fixes [Bug 635200] and [Bug 671138], but may reduce performance
+	of Unicode string handling in some cases. A further patch will be
+	applied to address this, once the code is known to be correct.
+
+2003-01-24  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* win/configure: Regen.
+	* win/configure.in: Add test to see if alloca is undefined in
+	malloc.h.
+	* win/tclWin32Dll.c (TclpCheckStackSpace): Rework the SEH exception
+	handler logic to avoid using the stack since alloca will modify the
+	stack. This was causing a nasty bug that would set the exception
+	handler to 0 because it tried to pop the previous exception handler
+	off the top of the stack.
+
+2003-01-23  Donal K. Fellows  <fellowsd@cs.man.ac.uk>
+
+	* doc/lset.n: Fixed fault in return values from lset in documentation
+	examples [SF Bug #658463] and tidied up a bit at the same time.
+
+2003-01-21  Joe English  <jenglish@users.sourceforge.net>
+
+	* doc/namespace.n (namespace inscope): Clarified documentation
+	[Patch 670110]
+
+2003-01-21  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* win/configure: Regen.
+	* win/tcl.m4 (SC_CONFIG_CFLAGS): Set SHLIB_SUFFIX so that
+	TCL_SHLIB_SUFFIX will be set to a useful value in the generated
+	tclConfig.sh. Set SHLIB_LD_LIBS to "" or '${LIBS}' based on the
+	--enable-shared flag. This matches the UNIX implementation.
+
+2003-01-18  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* generic/tclCkalloc.c: change %ud to %u as appropriate.
+
+2003-01-17  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* win/tclWinDde.c (DdeServerProc): Deallocate the Tcl_Obj returned by
+	ExecuteRemoteObject if it was not saved in a connection object.
+
+2003-01-17  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* generic/tcl.h: Revert earlier change that defined TCL_WIDE_INT_TYPE
+	as long long and TCL_LL_MODIFIER as L when compiling with mingw. This
+	change ended up causing some test case failures when compiling with
+	mingw.
+	* generic/tclObj.c (UpdateStringOfWideInt): Describe the warning
+	generated by mingw and why it needs to be ignored so that someone is
+	not tempted to "fix" this problem again in the future.
+
+2003-01-16  Vince Darley  <vincentdarley@users.sourceforge.net>
+
+	* generic/tclStringObj.c: Tcl_SetObjLength fix for when the object has
+	a unicode string rep. [Bug 635200]
+	* tests/stringObj.test: removed 'knownBug' constraint from test 14.1
+	now that this bug is fixed.
+
+	* generic/tclInt.h:
+	* generic/tclBasic.c:
+	* generic/tclCmdMZ.z:
+	* tests/trace.test: execution and command tracing bug fixes and
+	cleanup. In particular fixed [Bug 655645], [Bug 615043], [Bug 571385]
+	  - fixed some subtle cleanup problems with tracing. This required
+	    replacing Tcl_Preserve/Tcl_Release with a more robust refCount
+	    approach. Solves at least one known crash caused by memory
+	    corruption.
+	  - fixed some confusion in the code between new style traces (Tcl
+	    8.4) and the very limited 'Tcl_CreateTrace' which existed before.
+	  - made behaviour consistent with documentation (several tests even
+	    contradicted the documentation before).
+	  - fixed some minor error message details
+	  - added a number of new tests
+
+2003-01-16  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* win/tclWinSerial.c (SerialOutputProc): add casts for bytesWritten to
+	allow strict compilation (no warnings).
+
+	* tests/winDde.test:
+	* win/tclWinDde.c (Tcl_DdeObjCmd): Prevent crash when empty service
+	name is passed to 'dde eval' and goto errorNoResult in request and
+	poke error cases to free up any allocated data.
+
+2003-01-16  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* win/tclWin32Dll.c (squelch_warnings): Squelch compiler warnings from
+	SEH ASM code.
+	* win/tclWinChan.c (squelch_warnings): Squelch compiler warnings from
+	SEH ASM code.
+	* win/tclWinDde.c: Add casts to avoid compiler warnings. Pass pointer
+	to DWORD instead of int to avoid compiler warnings.
+	* win/tclWinFCmd.c (squelch_warnings): Add casts and fixup decls to
+	avoid compiler warnings. Squelch compiler warnings from SEH ASM code.
+	* win/tclWinFile.c: Add casts and fixup decls to avoid compiler
+	warnings. Remove unused variable.
+	* win/tclWinNotify.c: Declare as DWORD instead of int to avoid
+	compiler warning.
+	* win/tclWinReg.c: Add casts to avoid compiler warning. Fix assignment
+	in if expression bug.
+	* win/tclWinSerial.c: Add casts to avoid compiler warnings. Remove
+	unused variable.
+	* win/tclWinSock.c: Add casts and fixup decls to avoid compiler
+	warnings.
+
+2003-01-14  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* generic/tclClock.c (FormatClock): corrected typo that incorrectly
+	conditionally defined savedTZEnv and savedTimeZone.
+
+2003-01-13  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	Fix mingw build problems and compiler warnings.
+
+	* generic/tcl.h: Add if defined(__MINGW32__) check to code that sets
+	the TCL_WIDE_INT_TYPE and TCL_LL_MODIFIER.
+	* generic/tclClock.c (FormatClock): Don't define savedTimeZone and
+	savedTZEnv if we are not going to use them.
+	* generic/tclEnv.c: Add cast to avoid warning.
+	* win/tclWinChan.c: Use DWORD instead of int to avoid compiler warning
+	* win/tclWinThrd.c: Only define allocLock, allocLockPtr, and dataKey
+	when TCL_THREADS is defined. This avoid a compiler warning about
+	unused variables.
+
+2003-01-12  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* win/README: Update msys + mingw URL, the new release includes the
+	released 1.0.8 version of msys which includes a number of bug fixes.
+
+2003-01-12  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* win/configure: Regen.
+	* win/tcl.m4 (SC_CONFIG_CFLAGS): Pull in addition of shell32.lib to
+	LIBS_GUI that was added to the Tk tcl.m4 but never made it back into
+	the Tcl version.
+
+2003-01-12  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* generic/tcl.h: Skip Tcl's define of CHAR, SHORT, and LONG when
+	HAVE_WINNT_IGNORE_VOID is defined. This avoids a bunch of compiler
+	warnings when building with Cygwin or Mingw.
+	* win/configure: Regen.
+	* win/configure.in: Define HAVE_WINNT_IGNORE_VOID when we detect a
+	winnt.h that still defines CHAR, SHORT, and LONG when VOID has already
+	been defined.
+	* win/tcl.m4 (SC_LOAD_TCLCONFIG): Subst the TCL_DEFS loaded from
+	tclConfig.sh so that Tcl defines can make it into the Tk Makefile.
+
+2003-01-12  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* win/configure: Regen.
+	* win/configure.in: Check for typedefs like LPFN_ACCEPT in winsock2.h
+	and define HAVE_NO_LPFN_DECLS if not found.
+	* win/tclWinSock.c: Define LPFN_* typedefs if HAVE_NO_LPFN_DECLS is
+	defined. This fixes the build under Mingw and Cygwin, it was broken by
+	the changes made on 2002-11-26.
+
+2003-01-10  Vince Darley  <vincentdarley@users.sourceforge.net>
+
+	* generic/tclIOUtil.c:
+	* win/tclWinInt.h:
+	* win/tclWinInit.c: fix to new WinTcl crash on exit with vfs,
+	introduced on 2002-12-06. Encodings must be cleaned up after the
+	filesystem.
+
+	* win/makefile.vc: fix to minor VC++ 5.2 syntax problem
+
+2003-01-09  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclCompCmds.c (TclCompileReturnCmd):  Corrected off-by-one
+	problem with recent commit. [Bug 633204]
+
+2003-01-09  Vince Darley  <vincentdarley@users.sourceforge.net>
+
+	* generic/tclFileName.c: remove unused variable 'macSpecialCase'
+	[Bug 664749]
+
+	* generic/tclIOUtil.c:
+	* generic/tclInt.h:
+	* unix/tclUnixFile.c:
+	* mac/tclMacFile.c:
+	* win/tclWinFile.c:
+	* win/tclWinInt.h:
+	* win/tclWin32Dll.c:
+	* tests/cmdAH.test: fix to non-ascii chars in paths when setting mtime
+	and atime through 'file (a|m)time $path $time'. [Bug 634151]
+
+2003-01-08  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclExecute.c (TclExprFloatError):  Use the IS_NAN macro for
+	greater clarity of code.
+
+2003-01-07  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclCompCmds.c (TclCompileReturnCmd):
+	* tests/compile.test:	Corrects failure of bytecompiled [catch
+	{return}] to have result TCL_RETURN (not TCL_OK) [Bug 633204]. This
+	patch is a workaround for 8.4.X. A new opcode INST_RETURN is a better
+	long term solution for 8.5 and later.
+
+2003-01-04  David Gravereaux  <davygrvy@pobox.com>
+
+	* win/makefile.vc:
+	* win/rules.vc:  Fixed INSTALLDIR macro problem that blanked itself by
+	accident causing the install target to put the tree at the root of the
+	drive built on. Whoops..
+
+	Renamed the 'linkexten' option to be 'staticpkg'. Added 'thrdalloc' to
+	allow the switching _on_ of the thread allocator. Under testing, I
+	found it not to be benificial under windows for the purpose of the
+	application I was using it for. It was more important for this app
+	that resources for tcl threads be returned to the system rather than
+	saved/moved to the global recycler. Be extra clean or extra fast for
+	the default threaded build? Let's move to clean and allow it to be
+	switched on for users who find it benificial for their use of threads.
+
+	******************************************************************
+	*** CHANGELOG ENTRIES FOR 2002 IN "ChangeLog.2002"             ***
+	*** CHANGELOG ENTRIES FOR 2001 IN "ChangeLog.2001"             ***
+	*** CHANGELOG ENTRIES FOR 2000 IN "ChangeLog.2000"             ***
+	*** CHANGELOG ENTRIES FOR 1999 AND EARLIER IN "ChangeLog.1999" ***
+	******************************************************************
diff --git a/ChangeLog.2004 b/ChangeLog.2004
new file mode 100644
index 0000000..82acd5c
--- /dev/null
+++ b/ChangeLog.2004
@@ -0,0 +1,4619 @@
+2004-12-29  Jeff Hobbs	<jeffh@ActiveState.com>
+
+	* win/tcl.m4, win/configure: update MSVC CFLAGS_OPT to -O2, remove -Gs
+	(included in -O2) and -GD (outdated). Use "link -lib" instead of "lib"
+	binary and remove -YX for MSVC7 portability. Add -fomit-frame-pointer
+	for gcc OPT compiles. [Bug 1092952, 1091967] Align LIBS_GUI with Tk
+	head needs.
+
+2004-12-29  Kevin B. Kenny  <kennykb@acm.org>
+
+	* generic/tclDate.c: Regen
+	* generic/tclGetDate.y (TclDatelex): Fixed a problem where a
+	four-digit group with >=2 leading zeroes appeared to be a two-digit
+	group, leading to misinterpreting the time 0012 as 1200. [Bug 1090413]
+	* library/clock.tcl: Added code to interpret correctly months outside
+	the range 01-12 as reduced modulo 12 with a corresponding adjustment
+	to the year. [Bug 1092789]
+	* tests/clock.test: Added regression test cases for the above two bugs
+	* unix/Makefile.in: Added --no-lines to the 'bison' command line to
+	* win/Makefile.in: help constrain the number of diffs in a cvs checkin
+
+2004-12-24  Miguel Sofer <msofer@users.sf.net>
+
+	* generic/tclCompile.c:
+	* generic/tclCompile.h:
+	* generic/tclExecute.c:
+	* generic/tclInt.h:
+	* generic/tclLiteral.c:
+	* generic/tclProc.c:
+	Avoid sharing cmdName literals accross namespaces, and generalise
+	usage of the TclRegisterNewLiteral macro. [Patch 1090905]
+
+2004-12-20  Miguel Sofer <msofer@users.sf.net>
+
+	* generic/tclCompile.c: moved TclInitCompiledLocals to tclProc.c
+	* generic/tclProc.c: new static InitCompiledLocals to allow for a
+	single pass over the proc's arguments at proc load time (instead of
+	two as previously). TclObjInterpProc() now allocates the
+	compiledLocals on the tcl execution stack, using the new
+	TclStackAlloc/Free functions.
+
+2004-12-16  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* generic/tclInterp.c (Tcl_LimitSetTime, TimeLimitCallback):
+	(TclLimitRemoveAllHandlers, TclInitLimitSupport): Set a timer event to
+	trigger when the time limit runs out. All the time limit actually does
+	is check to see if the time limit has been exceeded, but this is
+	enough to fix [Bug 1085023].
+	* generic/tclInt.h (struct Interp): Added a field to hold the token
+	for the timer event handler associated with the current time limit.
+	* generic/tclEvent.c (Tcl_UpdateObjCmd, Tcl_VwaitObjCmd): Add error
+	message when limit exceeded.
+	* tests/interp.test (interp-34.[89]): Check that time limits handle
+	the two cases reported in [Bug 1085023]
+
+	* generic/tclTimer.c (TclCreateAbsoluteTimerHandler): New internal
+	function that allows setting a timer handler that will be triggered at
+	(or after) a specific time instead of at some number of milliseconds
+	in the future. This is a candidate for future exposure via a TIP.
+
+2004-12-15  Miguel Sofer <msofer@users.sf.net>
+
+	* generic/tclBasic.c:
+	* generic/tclExecute.c:
+	* generic/tclInt.decls:
+	* generic/tclIntDecls.h:
+	* generic/tclNamesp.c:
+	* generic/tclProc.c:
+	* generic/tclStubInit.c:
+	* generic/tclTest.c: Added two new functions to allocate memory from
+	the execution stack (TclStackAlloc, TclStackFree). Added functions
+	TclPushStackFrame and TclPopStackFrame that do the work of
+	Tcl_PushCallFrame and Tcl_PopCallFrame, but using frames allocated in
+	the execution stack - i.e., heap instead of C-stack. The core uses
+	these two new functions exclusively; the old ones remain for backwards
+	compat, as at least two popular extensions (itcl, xotcl) are known to
+	use them.
+
+2004-12-14  Miguel Sofer <msofer@users.sf.net>
+
+	* generic/tclCmdIL.c:
+	* generic/tclInt.h:
+	* generic/tclProc.c:
+	* generic/tclVar.c: changing the isProcCallFrame field of the
+	CallFrame struct from a 0/1 field to flags. Should be perfectly
+	backwards compatible.
+
+2004-12-14  Don Porter	<dgp@users.sourceforge.net>
+
+	* unix/configure.in: Added special processing to remove "$U" from
+	libraries in the LIBOBJS value. This is an auto-make-ism we need to
+	avoid. [Bug 1081541]
+
+	* unix/configure: autoconf-2.57
+
+2004-12-13  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tcl.h: Restored extern "C" guards so that C++ code sees
+	function pointer typedef linkage consistent with earlier Tcl releases.
+	[Bug 1082349]
+
+	* generic/tclEncoding.c: Plugged some memory leaks. Thanks to Rolf Ade
+	* generic/tclUtil.c:	 for reports and testing [Bug 1083082]
+
+2004-12-13  Kevin B. Kenny  <kennykb@acm.org>
+
+	* doc/clock.n: Clarify that the [clock scan] command does not accept
+	the full range of ISO8601 point-in-time formats. [Bug 1075433]
+
+2004-12-12  Miguel Sofer <msofer@users.sf.net>
+
+	* generic/tclVar.c (TclArrayObjCmd - ARRAY_NAMES): leaking an object
+	[Bug 1084111] - thanks to Rolf Ade.
+
+2004-12-12  Miguel Sofer <msofer@users.sf.net>
+
+	* generic/tclObj.c (TclSetCmdNameObj): special handling for fully
+	qualified command names (as in fix [Patch 456668]).
+
+2004-12-11  Miguel Sofer <msofer@users.sf.net>
+
+	* generic/tclInt.h:
+	* generic/tclNamesp.c: converting the static function
+	GetNamespaceFromObj() to MODULE_SCOPE TclGetNamespaceFromObj().
+
+2004-12-10  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* tools/tcl.wse.in, unix/tcl.spec, win/README.binary, README:
+	* win/configure.in, unix/configure.in, generic/tcl.h:
+	Bumped version number to 8.5a3 to distinguish HEAD of CVS development
+	from the recent 8.5a2 release.
+
+2004-12-10  Miguel Sofer <msofer@users.sf.net>
+
+	* generic/tclCompile.c (TclInitCompiledLocals):
+	* generic/tclCompile.h:
+	* generic/tclInt.h:
+	* generic/tclProc.c (TclObjInterpProc, TclCreateProc): optimised
+	loops that initialise a proc's arguments and compiled local
+	variables, removing tests from inner loops.
+
+2004-12-10  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclInt.h: Move ensemble API decls here from tclNamesp.c
+
+2004-12-09  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* generic/tclNamesp.c (TclMakeEnsembleCmd, TclSetEnsemble*)
+	(TclSetEnsemble*, TclFindEnsemble): Build an internal API for creating
+	and manipulating ensembles; they can be deleted using the normal
+	command-deletion API.
+
+	* doc/Async.3: Reword for better grammar, better nroff and get the
+	flag name right. (Reported by David Welton.)
+
+2004-12-07  Don Porter	<dgp@users.sourceforge.net>
+
+	* tests/unixInit.test (2.1-4): Added constraints so that when a value
+	of TCL_LIBRARY is required for process initialization, we skip the
+	tests that mess with that value.
+
+2004-12-07  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	*** 8.5a2 TAGGED FOR RELEASE ***
+
+	* unix/Makefile.in: add library/{tzdata,msgs} to dist target (kbk)
+
+	* doc/foreach.n: Adjust tabs to be friendlier to some HTML
+	converters. [Bug 1078760]
+
+2004-12-06  Jeff Hobbs	<jeffh@ActiveState.com>
+
+	* unix/tclUnixNotfy.c (NotifierThreadProc): init numFdBits
+	[Bug 1079286]
+
+	* doc/error.n, doc/SaveResult.3, doc/Thread.3: minor nroff typos
+
+2004-12-06  Don Porter	<dgp@users.sourceforge.net>
+
+	* tests/safe.test:	Trim auto_path to improve performance [1080039]
+
+	* tests/msgcat.test:	makeFile/removeFile cleanup [1079117]
+
+2004-12-04  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclEncoding.c:	Different fix for [Bug 1077005].
+	* generic/tclEvent.c:	Broke apart TclpSetInitialEncodings() on
+	* generic/tclInt.h:	Windows into TclpSetInterfaces(), that is
+	* unix/tclUnixInit.c:	fundamentally essential, and the initialization
+	* win/tclWinInit.c:	of the system encoding, which is not. Made
+	the TclpSetInterfaces call part of TclInitSubsystems so it cannot be
+	overlooked.
+
+2004-12-03  Jeff Hobbs	<jeffh@ActiveState.com>
+
+	* changes: updated for 8.5a2 release
+
+2004-12-02  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclUtil.c (TclSetProcessGlobalValue): Handle the case where
+	a ProcessGlobalValue might be assigned to itself.
+
+	* generic/tclEncoding.c (MakeFileMap): Correct refcounting errors
+	managing values returned by TclPathPart (with refCount of 1!) that led
+	to a memory leak. [Bug 1077474].
+
+2004-12-02  Vince Darley  <vincentdarley@users.sourceforge.net>
+
+	* generic/tclPathObj.c:  fix and new tests for [Bug 1074671] to ensure
+	* tests/fileSystem.test: tilde paths are not returned specially by
+	'glob'.
+
+2004-12-02  Kevin B. Kenny  <kennykb@acm.org>
+
+	* win/Makefile.in: Added a 'sed' in the setting of ROOT_DIR_NATIVE to
+	compensate for a bug in cygpath (at least version 1.36) that leaves a
+	trailing backslash on the end of the converted path.
+
+2004-12-02  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* generic/tclInterp.c (Alias,Target,Master): Rewrote these so that the
+	aliases that refer to an interpreter are stored in a list and not a
+	hashtable (which was only ever a convenience, and forced the use of a
+	global mutex to generate keys!) [FRQ 1077210]
+	* generic/tclNamesp.c (numNsCreated): Moved into thread-local storage
+	to remove a global mutex. [FRQ 1077210]
+
+2004-12-01  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclUtil.c (TclGetProcessGlobalValue): Narrowed the scope of
+	mutex locks.
+
+	* generic/tclUtil.c:		Updated Tcl_GetNameOfExecutable() to
+	* generic/tclEncoding.c:	make use of a ProcessGlobalValue for
+	* generic/tclEvent.c:		storing the executable name. Added
+	internal routines Tcl(Get|Set)ObjNameOfExecutable() to access that
+	storage in Tcl_Obj, rather than string format.
+
+	* unix/tclUnixFile.c:	Rewrote TclpFindExecutable() to use
+	* win/tclWinFile.c:	TclSetObjNameOfExecutable to store the
+	executable name it computes.
+
+	* generic/tclInt.h:	Added internal stub entries for
+	* generic/tclInt.decls: TclpFindExecutable and
+	Tcl(Get|Set)ObjNameOfExecutable.
+
+	* generic/tclIntDecls.h: make genstubs
+	* generic/tclStubInit.c:
+
+	* generic/tclCmdIL.c:	Retrieve executable name in Tcl_Obj form
+	* win/tclWinPipe.c:	instead of string form.
+
+	* unix/tclUnixTest.c:	Update [testfindexecutable] command to use new
+	internal interfaces.
+
+	* generic/tclEncoding.c:	Moved TclpSetInitialEncodings() call
+	from Tcl_FindExecutable() into TclInitEncodingSubsystem(). This is
+	important on Windows where it establishes whether the "ascii" or
+	"unicode" set of system routines will be used, and that needs to be
+	done earlier to support filesystem operations. [Bug 1077005]
+
+2004-12-01  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* tests/winDde.test: Rewritten to use tcltest2 features more
+	thoroughly (reducing the [catch] count!) and fix the problem with
+	winDde-6.1 being out of synch with the implementation.
+
+2004-11-30  Don Porter	<dgp@users.sourceforge.net>
+
+	* library/init.tcl ([unknown]): Restored the save/restore of the
+	variables ::errorCode and ::errorInfo. This is needed when the
+	[::bgerror] command is auto-loaded (as it is by Tk).
+
+	Patch 976520 reworks several of the details involved with
+	startup/initialization of the Tcl library, focused on the activities
+	of Tcl_FindExecutable().
+
+	* generic/tclIO.c:	Removed bogus claim in comment that encoding
+	"iso8859-1" is "built-in" to Tcl.
+
+	* generic/tclInt.h:	Created a new struct ProcessGlobalValue,
+	* generic/tclUtil.c:	routines Tcl(Get|Set)ProcessGlobalValue, and
+	function type TclInitProcessGlobalValueProc. Together, these take care
+	of the housekeeping for "values" (things that can be held in a
+	Tcl_Obj) that are global across a whole process. That is, they are
+	shared among multiple threads, and epoch and mutex protection must
+	govern the validity of cached copies maintained in each thread.
+
+	* generic/tclNotify.c:	Modified TclInitNotifier() to tolerate being
+	called multiple times in the same thread.
+	* generic/tclEvent.c:	Dropped the unused argv0 argument to
+	TclInitSubsystems(). Removed machinery to unsure only one
+	TclInitNotifier() call per thread, now that that is safe. Converted
+	Tcl(Get|Set)LibraryPath to use a ProcessGlobalValue, and moved them to
+	tclEncoding.c.
+	* generic/tclBasic.c:	Updated caller.
+
+	* generic/tclInt.h:	TclpFindExecutable now returns void.
+	* unix/tclUnixFile.c:
+	* win/tclWinFile.c:
+	* win/tclWinPipe.c:
+
+	* generic/tclEncoding.c: Built new encoding search initialization on a
+	foundation of ProcessGlobalValues, exposing new routines
+	Tcl(Get|Set)EncodingSearchPath. A cache of a map from encoding name to
+	directory pathname keeps track of where encodings are available for
+	loading. Tcl_FindExecutable greatly simplified into just three
+	function calls. The "library path" is now misnamed, as its only
+	remaining purpose is as a foundation for the default encoding search
+	path.
+
+	* generic/tclInterp.c:	Inlined the initScript that is evaluated by
+	Tcl_Init(). Added verification after initScript evaluation that Tcl
+	can find its installed *.enc files, and that it has initialized
+	[encoding system] in agreement with what the environment expects.
+	[tclInit] no longer driven by the value of $::tcl_libPath; it largely
+	constructs its own search path now, rather than attempt to share one
+	with the encoding system.
+
+	* unix/tclUnixInit.c:	TclpSetInitialEncodings factored so that a new
+	* win/tclWinInit.c:	routine TclpGetEncodingNameFromEnvironment can
+	reveal that Tcl thinks the [encoding system] should be, even when an
+	incomplete encoding search path, or a missing *.enc file won't allow
+	that initialization to succeed. TclpInitLibraryPath reworked as an
+	initializer of a ProcessGlobalValue.
+
+	* unix/tclUnixTest.c:	Update implementations of [testfindexecutable],
+	[testgetdefenc], and [testsetdefenc].
+
+	* tests/unixInit.test:	Corrected tests to operate properly even when
+	a value of TCL_LIBRARY is required to find encodings.
+
+	* generic/tclInt.decls: New internal stubs: TclGetEncodingSearchPath,
+	TclSetEncodingSearchPath, TclpGetEncodingNameFromEnvironment. These
+	are candidates for public exposure by future TIPs.
+
+	* generic/tclIntDecls.h: make genstubs
+	* generic/tclStubInit.c:
+
+	* generic/tclTest.c:	Updated [testencoding] to use
+	* tests/encoding.test:	Tcl(Get|Set)EncodingSearchPath.	 Updated tests.
+
+2004-11-30  Kevin B. Kenny  <kennykb@acm.org>
+
+	* library/clock.tcl: Corrected the regular expressions that match a
+	time zone to allow for time zones specified as +HH or -HH.
+	* tests/clock.test: Added regression test case for the above issue.
+	Thanks to Rolf Ade for reporting this issue [http://wiki.tcl.tk/13094]
+	* win/tclWinDde.c (Tcl_DdeObjCmd): Corrected a typo that caused a
+	compilation failure on VC++.
+
+2004-11-29  Andreas Kupries <andreask@activestate.com>
+
+	* win/Makefile.in (install-libraries): Brought entry '2004-10-26 Don
+	Porter (Tcl Modules)' into the windows world, actually the
+	win/configure buildsystem. The other windows buildsystems (.vc, .bc)
+	still have to be updated as well.
+
+2004-11-26  Andreas Kupries <andreask@activestate.com>
+
+	* win/tclWinDde.c (ExecuteRemoteObject): Removed bogus semicolon found
+	at the end of the header for the function definition, terminating it
+	early and preventing a compile. This is likely a fix for '2004-11-25
+	Donal'. I have to conclude that it is also unknown if the other
+	changes to this file actually pass the testsuite. Running testsuite
+	... They don't. winDde-6.1 fails. This is only a message discrepance,
+	i.e. not too bad. Leaving resolution of that to Pat and Donal.
+
+2004-11-26  Don Porter	<dgp@users.sourceforge.net>
+
+	* library/auto.tcl (tcl_findLibrary): Made sure the uniquifying
+	operations on the search path does not also normalize. [Bug 1072136]
+
+2004-11-26  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* unix/configure.in: Simplify the code to check for correctness of
+	strstr, strtoul and strtod.
+	* unix/tcl.m4 (SC_TCL_CHECK_BROKEN_FUNC): Split a complex stanza out
+	of configure.in into its own function. Also force it to do the right
+	thing with cacheing of results of AC_TRY_RUN to deal with issue raised
+	in [Patch 1073524]
+
+	* doc/foreach.n: Added simple example. [FRQ 1073334]
+
+2004-11-25  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* generic/tclProc.c (TclObjInterpProc):	    Make it so that only
+	* generic/tclIndexObj.c (Tcl_WrongNumArgs): [proc] instances do
+	* tests/indexObj.test (indexObj-5.7):	    quoting of their first
+	arguments, so keeping [Bug 942757] fixed and making [Bug 1066837] be
+	fixed as well. Done with a load of #ifdef-ery because this hack is so
+	ugly nobody should keep it around once Itcl's fixed.
+
+2004-11-25  Reinhard Max  <max@suse.de>
+
+	* tests/tcltest.test: The order in which [glob] returns the file names
+	is undefined, so tests should not depend on it.
+
+2004-11-25  Zoran Vasiljevic <vasiljevic@users.sf.net>
+
+	* doc/Thread.3:
+	* doc/Notifier.3: Added changes from the core-8-4-branch
+
+2004-11-25  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* doc/dde.n: Synchronized the documentation of the commands with the
+	header of the docs and what the package actually does. Thanks to
+	Andreas Kupries for spotting this.
+	* win/tclWinDde.c (Tcl_DdeObjCmd): Much cleanup of argument parsing
+	code.
+
+2004-11-24  David Gravereaux <davygrvy@pobox.com>
+
+	* generic/tclPort.h: Relative include of tclWinPort.h returned as it
+	was requiring me set -I$(tcl_root)/win for my extensions that need to
+	include tclInt.h and doesn't appear to serve any purpose for windows
+	builds.
+
+2004-11-24  Kevin B. Kenny  <kennykb@acm.org>
+
+	* unix/tcl.m4 (SC_ENABLE_THREADS): Corrected bad check for 3-argument
+	readdir_r [Bug 1001325].
+	* unix/configure: Regenerated.
+	* unix/tclUnixNotfy.c: Corrected all uses of 'select' to manage their
+	masks using the FD_CLR, FD_ISSET, FD_SET, and FD_ZERO macros rather
+	than bit-whacking that failed under Solaris-Sparc-64. [Bug 1071807]
+	* win/tclWinInit.c (TclpInitLibraryPath): Removed unused vars 'pathc'
+	and 'pathv' that caused compilation problems on VC++ with
+	--enable-symbols.
+
+2004-11-24  Don Porter	<dgp@users.sourceforge.net>
+
+	* unix/tcl.m4 (SC_ENABLE_THREADS): Corrected failure to determine the
+	number of arguments for readdir_r on SunOS systems. [Bug 1071701]
+
+	* unix/configure:	autoconf-2.57
+
+	* generic/tclCmdIL.c (InfoVarsCmd):	Corrected segfault in new
+	* tests/info.test (info-19.6):	trivial matching branch [Bug 1072654]
+
+2004-11-24  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* tools/man2html.tcl, tools/man2html1.tcl: Update to use Tcl 8.4.
+	* tools/man2html2.tcl: Fix broken .SS handling.
+
+2004-11-23  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* unix/Makefile.in: Add (commented-out) code to integrate tclConfig.h
+	into the dependency tree and 'make distclean'. [Bug 1068171]
+
+	* generic/tclResult.c (Tcl_AppendResultVA): Remove call to
+	Tcl_GetStringResult to speed up repeated calls to Tcl_AppendResult
+	with the side effect that code that wants to access interp->result
+	should always call Tcl_GetStringResult first. See [Patch 1041072]
+	discussion for more details.
+
+2004-11-22  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* unix/configure: Regen.
+	* unix/tcl.m4 (SC_TCL_64BIT_FLAGS): Define HAVE_TYPE_OFF64_T only when
+	off64_t, open64(), and lseek64() are defined. IRIX 5.3 is known to not
+	include an open64 function. [Bug 1030465]
+
+2004-11-22  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* unix/configure: Regen.
+	* unix/tcl.m4 (SC_ENABLE_THREADS): Check for a 2 argument version of
+	readdir_r that is known to exists under IRIX 5.3.
+	* unix/tclUnixThrd.c (TclpReaddir): Use either 2 arg or 3 arg version
+	of readdir_r. [Bug 1001325]
+
+2004-11-22  Don Porter	<dgp@users.sourceforge.net>
+
+	* unix/tclUnixInit.c (TclpInitLibraryPath): Purged dead code that used
+	* win/tclWinInit.c (TclpInitLibraryPath):  to extend the "library
+	path". Search path construction for init.tcl is now done within the
+	[tclInit] proc.
+	* generic/tclInterp.c:	Restored several directories to the search
+	* tests/unixInit.test:	path used to locate init.tcl within [tclInit].
+	This change does not restore any directories to the encoding search
+	path, so should still avoid the price of an unreasonably large number
+	of filesystem accesses during encoding initialization at startup
+	[Bug 976438]
+
+2004-11-22  Vince Darley  <vincentdarley@users.sourceforge.net>
+
+	* generic/tclPathObj.c: fix and new test for [Bug 1043129] in the
+	* tests/fileSystem.test: treatment of backslashes in file join on
+	Windows.
+
+2004-11-21  Don Porter	<dgp@users.sourceforge.net>
+
+	* doc/AddErrInfo.3:	Typo corrections (Thanks Daniel South).
+	* doc/interp.n:
+
+2004-11-19  Don Porter	<dgp@users.sourceforge.net>
+
+	* doc/AddErrInfo.3:	Docs for Tcl_(Get|Set)ReturnOptions. [TIP 227]
+
+	* doc/AddErrInfo.3:
+	* doc/Async.3:		Documentation updates to replace references
+	* doc/BackgdErr.3:	to global variable ::errorInfo and ::errorCode
+	* doc/SaveResult.3:	and to the ::bgerror command with references
+	* doc/after.n:		to their preferred replacements, the
+	* doc/bgerror.n:	-errorinfo and -errorcode return options,
+	* doc/error.n:		the Tcl_*InterpState routines, and the
+	* doc/exec.n:		[interp bgerror] command.
+	* doc/exit.n:
+	* doc/fileevent.n:
+	* doc/interp.n:
+	* doc/return.n:
+	* doc/tclvars.n:
+	* doc/update.n:
+
+	* tests/unixInit.test: Removed "knownBug" constraints to prompt bug
+	fixing before 8.5a2 release.
+
+2004-11-19  Daniel Steffen  <das@users.sourceforge.net>
+
+	* macosx/Makefile:
+	* unix/configure.in:
+	* unix/tclUnixInit.c (MacOSXGetLibraryPath): changed detection of tcl
+	framework build when determining tclLibPath from overloaded
+	TCL_LIBRARY to configuration define TCL_FRAMEWORK. [Bug 1068088]
+
+	* unix/configure: autoconf-2.57
+	* unix/tclConfig.h.in: autoheader-2.57
+
+2004-11-18  Don Porter	<dgp@users.sourceforge.net>
+
+	* doc/SaveResult.3:	Documentation for Tcl_*InterpState (TIP 226).
+
+	* generic/tclEvent.c (HandleBgErrors):	Simplified program flow.
+
+	* tests/basic.test:	Updated functional (not testing) uses of
+	* tests/io.test:	[bgerror] to make use of [interp bgerror].
+	* tests/socket.test:
+	* tests/timer.test:
+
+	* tests/interp.test (interp-36.*):	[interp bgerror] tests.
+
+	* generic/tclInterp.c:	Corrected [interp bgerror] error messages.
+
+2004-11-18  Reinhard Max  <max@suse.de>
+
+	* unix/tcl.m4 (SC_CONFIG_MANPAGES): Applied an improved version of
+	* unix/configure.in:		    [Patch 996085], that introduces
+	* unix/Makefile.in:		    --enable-man-suffix.
+
+	* unix/installManPage:		    added
+	* unix/mkLinks.tcl:		    removed
+	* unix/mkLinks:			    removed
+	* unix/configure:		    generated
+
+	* unix/Makefile.in:		    Don't install tclConfig.h .
+
+2004-11-17  Don Porter	<dgp@users.sourceforge.net>
+
+	* unix/configure.in: The change below reveals that the public data
+	type Tcl_StatBuf relies on config information. For now, disabled the
+	use of the tclConfig.h file until its full impact on Tcl's interface
+	can be assessed.
+
+	* unix/configure:	autoconf-2.57
+
+	* generic/tcl.h:	Moved the #include "tclConfig.h" out of
+	* generic/tclInt.h:	tcl.h.	The config settings are not part of
+	* generic/tclPort.:	the public interface, and having it there
+	breaks compiled against uninstalled Tcl and extensions using
+	autoconf-2.5*.
+
+2004-11-16  Jeff Hobbs	<jeffh@ActiveState.com>
+
+	* unix/tclUnixChan.c (TtySetOptionProc): fixed crash configuring
+	-ttycontrol on a channel. [Bug 1067708]
+
+2004-11-16  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclIOUtil.c (TclFSEpochOk): There were two code paths via
+	which the thread copy of filesystemEpoch could be synched with the
+	master copy, but only one kept the filesystem list cache up to date.
+	Fix routes everything through a single code path. [Bug 1035775].
+
+2004-11-16  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* unix/tcl.m4 (SC_CONFIG_CFLAGS): Stop architecture flags to 'ld' from
+	getting lost when [load] is disabled. [Bug 1016796]
+
+2004-11-16  Daniel Steffen  <das@users.sourceforge.net>
+
+	* generic/tcl.h:
+	* unix/configure.in: changed HAVE_CONFIG_H to HAVE_TCL_CONFIG_H.
+
+	* unix/configure: autoconf-2.57
+
+2004-11-15  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclInt.h: Added comment warning that the old ERR_IN_PROGRESS
+	and ERROR_CODE_SET flag values should not be re-used for the sake of
+	those extensions that have accessed them.
+
+	* generic/tclCmdMZ.c (Tcl_TraceObjCmd): Fixed Bug 1065378 which failed
+	* tests/trace.test (trace-33.1):	to permit a variable trace
+	created with [trace variable] to be destroyed with [trace remove].
+	Thanks to Keith Vetter for the report.
+
+2004-11-15  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* doc/tclvars.n: Added section to documentation on global variables
+	that are specific to tclsh and wish. [Patch 1065732]
+
+2004-11-12  Jeff Hobbs	<jeffh@ActiveState.com>
+
+	* generic/tclEncoding.c (TableFromUtfProc): correct crash condition
+	when TCL_UTF_MAX == 6. [Bug 1004065]
+
+2004-11-12  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* doc/interp.n: Basic documentation of the TIP#221 API.
+
+2004-11-12  Don Porter	<dgp@users.sourceforge.net>
+
+	TIP #221 IMPLEMENTATION
+	* generic/tclBasic.c:	Define [::tcl::Bgerror] in new interps.
+	* generic/tclEvent.c:	Update Tcl_BackgroundError to make use of the
+				registered [interp bgerror] command.
+	* generic/tclInterp.c:	New [interp bgerror] subcommand.
+	* tests/interp.test:	syntax tests updated.
+
+	TIP #226 IMPLEMENTATION
+	* generic/tcl.decls:	Stubs for Tcl_(Save|Restore|Discard)InterpState
+	* generic/tcl.h:	New public opaque type, Tcl_InterpState.
+	* generic/tclInt.h:	Drop old private declarations. Add
+				Tcl(Get|Set)BgErrorHandler
+	* generic/tclResult.c:	Tcl_*InterpState implementations.
+	* generic/tclDictObj.c:	Update callers.
+	* generic/tclIOGT.c:
+	* generic/tclTrace.c:
+
+	TIP #227 IMPLEMENTATION
+	* generic/tcl.decls:	Stubs for Tcl_(Get|Set)ReturnOptions.
+	* generic/tclInt.h:	Drop old private declarations.
+	* generic/tclResult.c:	Tcl_*ReturnOptions implementations.
+	* generic/tclCmdAH.c:	Update callers.
+	* generic/tclMain.c:
+
+	* generic/tclDecls.h:	make genstubs
+	* generic/tclStubInit.c:
+
+	* unix/tclAppInit.c:	Removed tclConfig.h #include, now that tcl.h
+				takes care of it for us.
+
+	* generic/tclInt.h:	Moved verification of ptrdiff_t typedef from
+	* generic/tclExecute.c: multiple .c files into one common header where
+	* generic/tclVar.c:	it is verifiably after tclConfig.h inclusion.
+
+2004-11-12  Daniel Steffen  <das@users.sourceforge.net>
+
+	* generic/tcl.h:
+	* generic/tclInt.h:
+	* unix/Makefile.in: include tclConfig.h from tcl.h and install it as a
+	public header. Normalized compiler include path order to
+	-I${BUILD_DIR} -I${UNIX_DIR} -I${GENERIC_DIR}.
+
+	* unix/dltest/Makefile.in: add ${BUILD_DIR}/.. to include path to pick
+	up tclConfig.h.
+
+	* unix/tclUnixInit.c: moved check for HAVE_CFBUNDLE define after
+	#include "tclInt.h" to ensure tclConfig.h has been included.
+
+2004-11-12  Reinhard Max  <max@suse.de>
+
+	* unix/config.h.in:
+	* unix/tclConfig.h.in:	renamed
+
+	* unix/Makefile.in:	Completed support for config header,
+	* unix/configure.in:	fixed building outside of the unix dir,
+	* unix/tclAppinit.c:	and reflected the name change of config.h.
+	* generic/tclInt.h:
+
+	* unix/configure:	generated
+
+2004-11-12  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* unix/config.h.in:	Allow configure to put all the C #defs into
+	* unix/configure.in:	a file (called config.h) so that Unix builds
+	* unix/tcl.m4:		now take far fewer lines of scrollback to
+	* unix/Makefile.in:	proceed (making it less likely that any errors
+	* generic/tclInt.h:	or warnings will get missed).
+	* unix/tclAppInit.c:	Part of the TIP#34 upgrades.
+
+	* unix/tcl.m4, unix/tclUnixPort.h: Check for pthread_attr_get_np in
+	<pthread.h> before forcing the use of <pthread_np.h> to make things
+	work on NetBSD 2.0. [Bug 1064882]
+
+	* doc/binary.n, doc/upvar.n: More minor fixes.
+
+2004-11-12  Daniel Steffen  <das@users.sourceforge.net>
+
+	* doc/CrtChannel.3:
+	* doc/Interp.3:
+	* doc/Limit.3:
+	* doc/binary.n:
+	* doc/dict.n:
+	* doc/tm.n:
+	* doc/upvar.n: fixed *roff errors uncovered by running 'make html'.
+
+	* tools/tcltk-man2html.tcl: added faked support for bullet point
+	lists, i.e. *nroff ".IP \(bu" syntax.
+
+2004-11-11  Daniel Steffen  <das@users.sourceforge.net>
+
+	* tests/fCmd.test:
+	* unix/tclUnixFCmd.c (TraverseUnixTree): added option to rewind() the
+	readdir() loop whenever the source hierarchy has been modified by
+	traverseProc (e.g. by deleting files); this is required to ensure
+	complete traversal of the source hierarchy on certain filesystems like
+	HFS+. Added test for failing recursive delete on Mac OS X that was due
+	to this. [Bug 1034337]
+
+	* generic/tclListObj.c (Tcl_ListObjReplace): use memmove() instead of
+	manual copy loop to shift list elements. Decreases time spent in
+	Tcl_ListObjReplace() from 5.2% to 1.7% of overall runtime of tclbench
+	on a ppc 7455 (i.e. 200% speed increase). [Patch 1064243]
+
+	* generic/tclHash.c: hoisted some constant pointer dereferences out of
+	loops to eliminate redundant loads that the gcc optimizer didn't deal
+	with. Decreases time spend in Tcl_FindHashEntry() by 10% over a full
+	run of the tcl testuite on a ppc 7455. [Patch 1064243]
+
+	* tests/fileName.test:
+	* tests/fileSystem.test:
+	* tests/io.test:
+	* tests/msgcat.test:
+	* tests/tcltest.test:
+	* tests/unixInit.test: fixed bugs causing failures when running tests
+	with -tmpdir arg not set to working dir.
+
+	* macosx/Makefile: corrected path to html help inside framework.
+	Prevent parallel make from building several targets at the same time.
+
+	* macosx/tclMacOSXFCmd.c (struct fileinfobuf): force struct to be
+	packed to prevent failures when builing with -malign=natural.
+
+2004-11-10  Andreas Kupries <andreask@activestate.com>
+
+	* unix/tclUnixChan.c: [Bug 727786]. Exterminated the code marked
+	DEPRECATED. This code has not been used in over a year now, and we
+	have no complaints.
+
+2004-11-08  David Gravereaux <davygrvy@pobox.com>
+
+	* win/tclWinPipe.c: The pipe channel driver now respects the -blocking
+	option when closing is the same way the UNIX side works. This is to
+	avoid a hung shell when exiting due to open pipes that refuse to close
+	in a graceful manner.
+	* doc/open.n: Added a note about -blocking 0 and lack of exit status
+	as it had never been documented. [Bug 947693]
+
+	***POTENTIAL INCOMPATIBILITY***
+
+	Scripts that use async pipes on windows, must (like the UNIX side) set
+	-blocking to 1 before calling [close] to receive the exit status.
+
+2004-11-07  David Gravereaux <davygrvy@pobox.com>
+
+	* tests/winFile.test: added contraint to winFile-4.0 to prevent it
+	being run on NT4 [Bug 981829]
+
+2004-11-05  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* tests/reg.test: Major reorganization so that this file is much
+	easier for a normal Tcl maintainer to comprehend. The test flags are
+	still very cryptic, but they appear to have to be that way. The number
+	of skipped tests has increased, but now the skipped tests have much
+	more meaningful content.
+
+	* tests/tm.test (genpaths): Add a [file normalize] so we pick up
+	Windows drive letters, etc. [Bug 1053568]
+
+2004-11-04  Don Porter	<dgp@users.sourceforge.net>
+
+	* changes:	Updates toward an 8.5a2 release.
+
+2004-11-03  Kevin B. Kenny  <kennykb@acm.org>
+
+	* library/clock.tcl (FreeScan): Fixed a bug where scanning "Monday"
+	with a base time other than midnight incorrectly carried the base time
+	forward.
+
+	* test/clock.test (clock-33.{5,5a}): Made the test failure more
+	informative.
+
+	* tests/clock.test (clock-34.{28,44,45,46}): Removed 'knownBug'
+	constraints from tests that no longer fail.
+
+	Thanks to Don Porter for reporting these.
+
+2004-11-03  David Gravereaux <davygrvy@pobox.com>
+
+	* generic/tcl.h:		Moved the preprocessor logic
+	* generic/tclDecls.h:		from tclInt.h of setting the
+	* generic/tclInt.h:		TCL_STORAGE_CLASS macro to the
+	* generic/tclIntDecls.h:	tcl*Decls.h files now that no
+	* generic/tclIntPlatDecls.h:	use of EXTERN is left in tclInt.h.
+	* generic/tclPlatDecls.h:	Proto for Tcl_Main moved in tcl.h
+	* win/tclWinPort.h:		to prior the inclusion of the Stubs
+	headers as they are now resetting TCL_STORAGE_CLASS. Removed
+	extraineous reset from tclWinPort.h. [Patch 1055668]
+
+	* generic/tclCompile.h: Removed extrainious reset of TCL_STORAGE_CLASS
+	missed in my last edit.
+
+2004-11-03  Don Porter	<dgp@users.sourceforge.net>
+
+	* library/init.tcl ([unknown]): Corrections to the 2004-10-25 mods to
+	Aunt ??? in [unknown]. Flaws revealed by Itcl test suite, which still
+	apparently relies on this brokenness. Also added comment suggesting
+	the error message that any code using this hack *ought* to receive in
+	reply.
+
+	* generic/tclTrace.c (TclCallVarTraces):  Improved ability to debug
+	* tests/incr-old.test (incr-old-2.6):	  errors during variable
+	* tests/incr.test (incr-{1,2}.28):	  traces by preserving the
+	* tests/set.test (set-{2,4}.4):		  -errorinfo data.
+	* tests/trace.test (trace-33.1):	  [Bug 527164]
+
+2004-11-02  David Gravereaux <davygrvy@pobox.com>
+
+	* generic/tclInt.h: added a check for #ifdef __cplusplus around the
+	#define of MODULE_SCOPE. About the only time it would be problem is
+	when someone is statically linking to Tcl and accessing internals from
+	a C++ file and has name mangling issues from the lack of "C" after
+	'extern' [Patch 1055668].
+	* generic/tclCompile.h: Exchanged use of the EXTERN macro to the new
+	MODULE_SCOPE macro. Lowered exported internals count by 35. [Patch
+	1055668]
+	* win/tclWinInt.h:
+	* win/tclWinPort.h: exported internals dropped by a count of 14.
+	* generic/tclFileSystem.h: Added use of MODULE_SCOPE on protos.
+	* generic/tclRegexp.h: manipulating TCL_STORAGE_CLASS unnecessary.
+
+2004-11-02  Don Porter	<dgp@users.sourceforge.net>
+
+	* library/tcltest/tcltest.tcl:		Corrected some misleading
+	* tests/tcltest.test (tcltest-26.1,2):	displays of ::errorInfo and
+	::errorCode information when the -setup, -body, and/or -cleanup scripts
+	return an unexpected return code. Thanks to Robert Seeger for the fix.
+	[RFE 1017151].
+
+2004-11-02  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* generic/tclExecute.c (TclExecuteByteCode): Improved version of the
+	NaN fix from Miguel Sofer. [Bug 761471]
+
+2004-11-02  Kevin Kenny	 <kennykb@acm.org>
+
+	* library/tzdata/America/Cuiaba: Change to DST rules for
+	* library/tzdata/America/Havana: autumn of 2004.
+	[ftp://elsie.nci.nih.gov/pub/tzdata2004g.tar.gz]
+
+	* tools/tclZIC.tcl: Updated to be compatible with recent changes in
+	library/clock.tcl.
+
+2004-11-02  Vince Darley  <vincentdarley@users.sourceforge.net>
+
+	* win/tclWinFile.c: Simplify TclpUtime to use Tcl_FSGetNativePath, and
+	add comments.
+
+2004-11-02  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* generic/tclInt.h: Change uses of EXTERN to MODULE_SCOPE (defined in
+	this file too to be 'extern' if not overridden) as nothing declared in
+	tclInt.h is supposed to be visible outside the Tcl core. If there *is*
+	anything that extensions are actually using, we can open this up later
+	on. [Patch 1055668]
+
+	* doc/CrtChannel.3 (Tcl_GetChannelMode): Add synopsis. [Bug 1058446]
+
+2004-11-01  Kevin B. Kenny  <kennykb@acm.org>
+
+	* win/tclWinFile.c (FromCTime, TclpUtime): Replaced a call to the
+	Posix 'utime' function with calls to Windows-API equivalents, to avoid
+	a bug where the VC++ versions misconvert times across a Daylight
+	Saving Time boundary. [Bug 926106]
+	* win/tclWinInt.h (TclWinProcs):
+	* win/tclWin32Dll.c (asciiProcs, unicodeProcs): Removed now-unused
+	reference to 'utime'.
+	* tests/cmdAH.test (cmdAH-24.12): Added test case for the above bug.
+
+2004-11-01  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* generic/tclExecute.c (TclExecuteByteCode): Make INST_EQ and friends
+	handle NaN correctly in all cases. [Bug 761471]
+
+	* generic/tclNamesp.c (NamespaceInscopeCmd): Make the error message
+	generation the same as in NamespaceEvalCmd().
+	(Tcl_Import): Rationalized to use Tcl_EvalObjv().
+
+2004-10-31  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* tests/io.test (io-40.3): Convert umask2 test constraint into a form
+	that most people will be able to satisfy.
+
+	* tests/cmdAH.test (cmdAH-8.45): Removed broken test constraint. It
+	didn't do what it was intended to do, and it implied the other correct
+	constraint. [Bug 1053908]
+
+	* generic/tclCmdIL.c (InfoGlobalsCmd):
+	* tests/info.test (info-8.4): Strip leading global-namespace
+	specifiers from the pattern argument. [Bug 1057461]
+
+2004-10-30  Kevin Kenny	 <kennykb@acm.org>
+
+	* generic/clock.c: Replaced WIN32 macro with __WIN32__. [Bug 1054357].
+	Thanks to David Gravereaux for the patch.
+	* win/tclWinFile.c: Removed a long-standing bug that causes incorrect
+	conversion between file time and UTC time if the file time is recorded
+	in a different Daylight Saving Time status than the current one. [Bug
+	926106]
+
+2004-10-29  Don Porter	<dgp@users.sourceforge.net>
+
+	* library/tcltest/tcltest.tcl:	Correct reaction to errors in the
+	obsolete processCmdLineArgsHook.	[Bug 1055673]
+	* library/tcltest/pkgIndex.tcl:	Bump to tcltest 2.2.7
+	* unix/Makefile.in:
+	* tests/all.tcl:	Update to use [tcltest::configure].
+
+2004-10-29  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* library/tm.tcl (::tcl::tm::*): Use the core proc engine to generate
+	the wrong-num-args error messages for the path ensemble.
+
+	Ensembles can now (sometimes) rewrite the error messages of their
+	subcommands so they appear more like the arguments that the user
+	passed to the ensemble. Below is a description of changes involved in
+	doing this.
+
+	* tests/namespace.test (namespace-50.*): Tests of ensemble subcommand
+	error message rewriting.
+	* generic/tclProc.c (TclObjInterpProc): Make procedures implement
+	their wrong-num-args message using Tcl_WrongNumArgs instead of
+	something baked-at-home.
+	* generic/tclNamesp.c (TclIsEnsemble, NsEnsembleImplementationCmd):
+	Added test of ensemble-hood (available to rest of core) and made
+	ensembles set up the rewriting for Tcl_WrongNumArgs to take advantage
+	of.
+	* generic/tclInt.h (Interp.ensembleRewrite): Extra fields.
+	* generic/tclIndexObj.c (Tcl_WrongNumArgs): Add knowledge of what is
+	going on in ensembles' command rewriting so this command can generate
+	the right error message itself.
+	* generic/tclBasic.c (Tcl_CreateInterp, TclEvalObjvInternal): Added
+	code to initialize (as empty) the rewriting fields and reset them when
+	we leak outside an ensemble implementation.
+
+2004-10-28  Miguel Sofer <msofer@users.sf.net>
+
+	* generic/tclExecute.c (INST_START_CMD):
+	* tests/execute.test (execute-8.3): fix for execution stack corruption
+	[Bug 1055676]. Credit dgp for detective work and fix.
+
+2004-10-27  Don Porter	<dgp@users.sourceforge.net>
+
+	* tests/socket.test (socket-13.1):	Balanced [makeFile] and
+	[removeFile] commands.
+
+	* tests/clock.test:	Correct duplicate test names.
+	* tests/namespace.test:
+	* tests/string.test:
+	* tests/io.test (io-50.4):	Use namespace variables.
+
+2004-10-27  David Gravereaux <davygrvy@pobox.com>
+
+	* generic/tclInt.decls:	  The following 9 functions were moved from
+	* generic/tclInt.h:	  tclInt.h to the private/int Stubs table for
+	* generic/tclIntDecls.h:  use by the test suite. As tclTest.obj is
+	* generic/tclStubInit.c:  linked to the shell, these functions need
+	"blessed" status so as to always be exported from the library. Being
+	placed in the Stubs table guarantees this [Bug 1054748]:
+		TclpObjRemoveDirectory,	TclpObjCopyDirectory,
+		TclpObjCreateDirectory,	TclpObjDeleteFile,
+		TclpObjCopyFile,	TclpObjRenameFile,
+		TclpObjStat,		TclpObjAccess,
+		TclpOpenFileChannel
+
+	* tests/registry.test:	Fixed test files to load the correct
+	* tests/winDde.test:	registry and dde packages by using the info
+	* win/Makefile.in:	from makefiles to tell tcltest where to load
+	* win/makefile.vc:	them from. This avoids grabbing the wrong
+	package from $auto_path which might be the install point rather than
+	the dev location. Kudos to Jennifer Hom for adding -load and
+	-loadfile to the tcltest package. [Bug 926088]
+
+	* win/tclWinThrd.c (TclFinalizeLock): release the critical section
+	before deleting it. [Bug 731778]
+
+	* generic/tcl.h: Removed the file level 'extern "C" {' and the
+	coresponding closing block as it serves no purpose given that all the
+	function prototypes have the proper extern usage already.
+
+	* unix/tclAppInit.c:	When built as tcltest, TclThread_Init was
+	* win/tclAppInit.c:	getting called twice. First by Tcltest_Init,
+	then again in Tcl_AppInit. The call from Tcl_AppInit is now removed.
+
+2004-10-27  Andreas Kupries <andreask@activestate.com>
+
+	* tests/tm.test:  Expanded on the testsuite entered by Donal.
+	* library/tm.tcl: Even found bugs, these have been corrected.
+
+2004-10-26  Kevin Kenny <kennykb@acm.org>
+
+	* tests/format.test (format-19.1): Additional regression test for [Bug
+	868489].
+
+2004-10-27  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* doc/*.n: Many small general documentation fixes.
+
+2004-10-26  David Gravereaux <davygrvy@pobox.com>
+
+	* generic/tclPipe.c (TclCleanupChildren): bad cast of resolvedPid
+	caused PIDs on win95 to go negative. winpipe-4.2 brought this to the
+	surface. Fixed with sprintf in place of TclFormatInt. Thanks to hgiese
+	[Patch 767676]
+
+2004-10-26  Andreas Kupries <andreask@activestate.com>
+
+	* library/tm.tcl (::tcl::tm::Defaults): Added a second [file dirname]
+	around the location of the executable. This fixes [Bug 1038705].
+	Instable of a bogus "foo/bin/lib" we now have the correct "foo/lib" as
+	a base path for modules.
+
+2004-10-26  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclParse.c (Tcl_SubstObj):	Fix for failed subst-12.3 test
+	* tests/subst.test (subst-12.3-5):	More tests for Bug 1036649.
+
+	* unix/Makefile.in (install-libraries): Updated the installation of
+	the http, msgcat, and tcltest packages to install as Tcl Modules on
+	Unix systems. Other platform Makefiles still need updating. [Patch
+	1054370]
+
+	* tests/basic.test:	Added missing constraints.
+	* tests/compile.test:
+	* tests/fileSystem.test:
+
+	* tests/init.test (init-2.8):	Updated to not rely on http package.
+
+2004-10-26  Miguel Sofer <msofer@users.sf.net>
+
+	* generic/tclInt.h:
+	* generic/tclVar.c: removed more direct references to the VAR flags,
+	replaced with access macros.
+
+2004-10-26  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* doc/expr.n: Clarified that non-num/non-bool literals require
+	quoting. [Bug 1027849]. Also listed booleans as acceptable values.
+
+2004-10-26  Kevin B. Kenny <kennykb@acm.org>
+
+	* library/clock.tcl (FreeScan): Fixed a bug that caused relative days
+	of the week in free-form [clock scan] to be evaluated in the wrong
+	time zone.
+	* tests/clock.test (clock-31.[456]): Made sure that there isn't an
+	env(TZ) or env(TCL_TZ) lying around that will override the time zone
+	that we're trying to establish with the simulated registry.
+	Both problems reported as [Bug 1054101].
+
+2004-10-25  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* doc/string.n (map): Rewrote to clarify that we don't just map single
+	characters. [Bug 1048005]
+	* doc/info.n (procs): Clarified that the pattern argument may have
+	namespace separators in it. [Bug 1047928]
+
+	* tests/cmdAH.test (cmdAH-8.45): Simplify in the hope that the reasons
+	for [Bug 1053908] will become clearer.
+
+2004-10-25  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclExecute.c (IllegalExprOperandType,TclExecuteByteCode):
+	Removed several DECACHE_INFO/CACHE_INFO pairs that are no longer
+	needed for protection because routines like Tcl_SetErrorCode() and
+	Tcl_AddErrorInfo() can no longer re-enter bytecode execution.
+
+	* generic/tclResult.c (TclProcessReturn): Bug fix. Be sure that a
+	missing -errorinfo option when code == TCL_ERROR causes the errorInfo
+	field to get reset.
+
+	* tests/thread.test (thread-4.4): Test depended on a ::errorInfo value
+	initialized to "". Added code to test to setup that requirement.
+
+	* library/auto.tcl:	Purged Tcl's script library of all
+	* library/clock.tcl:	remaining references to global vars
+	* library/init.tcl:	::errorInfo and ::errorCode.
+
+	* generic/tclMain.c (Tcl_Main): Updated to make use of
+	TclGetReturnOptions instead of ::errorInfo variable.
+
+	* generic/tclInterp.c (tclInit): Bug fix. Access dict variables with
+	[dict get], not array syntax.
+
+2004-10-25  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* tests/tm.test: Rewrote the tests to actually perform syntax checks
+	on the public API. Added a new test (currently failing) to indicate
+	that the test suite is not complete yet.
+	* library/tm.tcl (path): Rewrote to turn this command into an ensemble
+	to make it faster and simpler.
+
+2004-10-24  Miguel Sofer <msofer@users.sf.net>
+
+	* generic/tclCmdIL.c:
+	* generic/tclExecute.c:
+	* generic/tclInt.h:
+	* generic/tclTrace.c: defined new macros to get/set the flags of
+	variables. The only files that still access the flag values directly
+	are tclCompCmds.c, tclCompile.c, tclProc.c and tclVar.c
+
+2004-10-24  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclBasic.c (Tcl_LogCommandInfo,Tcl_AddObjErrorInfo): Shift
+	the initialization of errorCode to NONE to more central location.
+
+	* generic/tclEvent.c (BgError,Tcl_BackgroundError,HandleBgErrors):
+	Rewrite to build on the new TclGet/SetReturnOptions routines.
+
+	* generic/tclResult.c (TclGetReturnOptions): Add call to
+	Tcl_AddObjErrorInfo to be sure error fields are initialized.
+
+	* generic/tclResult.c (TclTransferResult): Rewrite to build on the new
+	TclGet/SetReturnOptions routines.
+
+2004-10-22  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* doc/tm.n: Tightened up the documentation.
+	* tests/tm.test: Created (with partially dummy content) so TIP#189 can
+	be marked Final.
+
+	* generic/tclNamesp.c (NsEnsembleImplementationCmd): Make ensembles
+	cut their implementations out of error traces. This is the right thing
+	to do more often than not.
+
+2004-10-22  Kevin B. Kenny  <kennykb@acm.org>
+
+	* library/clock.tcl: Fixed a typo where the fallback time zone became
+	::localtime instead of :localtime. Fixed a bug where time zone names
+	containing hyphens could not be loaded.
+	* tests/clock.test: Added regression test cases that covers both bugs.
+	Thanks to Todd M. Helfter <tmh@jumpgate.itsp.purdue.edu> for finding
+	these bugs.
+
+2004-10-22  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* generic/tclExecute.c (TclCompEvalObj, Tcl_ExprObj):
+	* generic/tclProc.c (TclProcCompileProc): Always call object
+	freeIntRepProc's in the same way.
+
+2004-10-22  Miguel Sofer <msofer@users.sf.net>
+
+	* generic/tclVar.c: fixed bug in commit of 2004-07-23, which was
+	causing a leak of Proc structures and failure of compile-12.1. Two
+	lines were 'zombies' from the previous way localVarNames worked.
+	Credit dgp for finding this.
+
+2004-10-21  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclInt.h (Interp):
+	* generic/tclBasic.c (Tcl_CreateInterp,Tcl_DeleteInterp):
+	* generic/tclResult.c (GetKeys,ReleaseKeys,etc.): Moved the key values
+	of the return options dictionary out of private fields of the Interp
+	struct and into thread-static values managed in tclResult.c.
+
+	* generic/tclCmdAH.c (Tcl_CatchObjCmd, Tcl_ErrorObjCmd): Updated to
+	call the new TclGet/SetReturnOptions routines to do much of their
+	work.
+
+	* generic/tclInt.h (TclGetReturnOptions,TclSetReturnOptions):
+	* generic/tclResult.c (TclGetReturnOptions,TclSetReturnOptions): New
+	utility routines to get/set the return options of an interp. Intent is
+	that these routines will be converted to public routines after TIP
+	approval.
+
+	* generic/tclCmdMZ.c (TclProcessReturn,TclMergeReturnOptions):
+	* generic/tclResult.c (TclProcessReturn,TclMergeReturnOptions): Move
+	internal utility routines from tclCmdMZ.c to tclResult.c.
+
+	* generic/tclBasic.c (Tcl_CreateInterp, Tcl_DeleteInterp):
+	* generic/tclResult.c (TclTransferResult): Rework so that
+	iPtr->returnOpts can be NULL when there are no special options.
+
+	* generic/tclResult.c (TclRestoreInterpState): Plug potential memory
+	leak.
+
+2004-10-21  Kevin B. Kenny  <kennykb@acm.org>
+
+	* generic/tclBasic.c: Various changes to [clock format] that,
+	* generic/tclClock.c: together, make it roughly twice as fast
+	* generic/tclInt.h:   while all tests in the test suite
+	* library/clock.tcl:  continue to pass.
+
+2004-10-20  Andreas Kupries <andreask@activestate.com>
+
+	* win/Makefile.in (install-msgs):   Fixed a problem with the
+	* win/Makefile.in (install-tzdata): installation of timezone data and
+	message catalogs. They used the installed tcl library directory, not
+	the source library. Before it was installed. Switched to source lib
+	dir. Thanks to Kevin for the help in figuring this out.
+
+2004-10-20  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclThreadTest.c (ThreadEventProc): Corrected subtle bug
+	where the returned (char *) from Tcl_GetStringResult(interp) continued
+	to be used without copying or refcounting, while activity on the
+	interp continued. That's not safe, and recent changes demonstrated the
+	lack of safety with failing tests thread-4.3 and thread-4.5.
+
+2004-10-19  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* generic/tclDictObj.c (DictWithCmd): Make sure all paths (that are
+	not themselves error paths) do not lose the result code.
+
+2004-10-19  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclInt.h (Tcl*InterpState):		New internal routines
+	* generic/tclResult.c (Tcl*InterpState):	TclSaveInterpState,
+	TclRestoreInterpState, and TclDiscardInterpState are superior
+	replacements for Tcl_(Save|Restore|Discard)Result. Intent is that
+	these routines will be converted to public routines after TIP
+	approval. Interfaces for these routines were shamelessly stolen from
+	Itcl.
+
+	* generic/tclBasic.c (TclEvalObjvInternal):
+	* generic/tclDictObj.c (DictUpdateCmd, DictWithCmd):
+	* generic/tclIOGT.c (ExecuteCallback):
+	* generic/tclTrace.c (Trace*Proc,TclCheck*Traces,TclCallVarTraces):
+	Callers of Tcl_*Result updated to call the new routines. The calls
+	were relocated in several cases to perform save/restore operations
+	only when needed.
+
+	* generic/tclEvent.c (HandleBgErrors):
+	* generic/tclFCmd.c (CopyRenameOneFile): Calls to Tcl_*Result that
+	were eliminated because they appeared to serve no useful purpose,
+	typically saving/restoring an error message, only to throw it away.
+
+2004-10-18  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclBasic.c (Tcl_CreateInterp,Tcl_DeleteInterp):
+	* generic/tclCmdAH.c (Tcl_CatchObjCmd):
+	* generic/tclCmdMZ.c (TclMergeReturnOptions,TclProcessReturn):
+	* generic/tclCompCmds.c (TclCompileReturnCmd):
+	* generic/tclExecute.c (TclCompEvalObj):
+	* generic/tclInt.h (Interp):
+	* generic/tclProc.c (TclUpdateReturnInfo): Place primary storage of
+	the -level and -code information in private fields of the Interp
+	struct, rather than in a DictObj. This should significantly improve
+	performance of TclUpdateReturnInfo.
+
+2004-10-17  Miguel Sofer <msofer@users.sf.net>
+
+	* generic/tclResult.c: removed unused variable [Bug 1048588]. Thanks
+	to Daniel South.
+
+2004-10-15  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclCmdMZ.c (TclProcessReturn):	Now that primary
+	* generic/tclProc.c (TclUpdateReturnInfo):	storage for the
+	errorInfo and errorCode values are internal fields, we can set them at
+	the time of the [return] command, and not have to wait until the
+	specified number of "-level"s have popped.
+
+	* generic/tclBasic.c (Tcl_CreateInterp, Tcl_DeleteInterp)
+	(TclEvalObjvInternal, Tcl_LogCommandInfo, TclAddObjErrorInfo):
+	* generic/tclCmdAH.c (Tcl_CatchObjCmd):
+	* generic/tclEvent.c (BgError, ErrAssocData, Tcl_BackgroundError)
+	(HandleBgErrors, BgErrorDeleteProc):
+	* generic/tclExecute.c (TclCreateExecEnv, TclDeleteExecEnv):
+	* generic/tclIOUtil.c (comments only):
+	* generic/tclInt.h (ExecEnv,Interp, ERR_IN_PROGRESS):
+	* generic/tclInterp.c ([tclInit]):
+	* generic/tclMain.c (comments only):
+	* generic/tclNamesp.c (Tcl_CreateNamespace, Tcl_DeleteNamespace)
+	(TclTeardownNamespace):
+	* generic/tclProc.c (TclUpdateReturnInfo):
+	* generic/tclResult.c (Tcl_ResetResult, TclTransferResult):
+	* generic/tclTrace.c (CallVarTraces):
+	Reworked management of the "errorInfo" data of an interp. That
+	information is now primarily stored in a new private (Tcl_Obj *) field
+	of the Interp struct, rather than using a global variable ::errorInfo
+	as the primary storage. The ERR_IN_PROGRESS flag bit value is no
+	longer required to manage the value in its new location, and is
+	removed. Variable traces are established to support compatibility for
+	any code expecting the ::errorInfo variable to hold the information.
+
+	***POTENTIAL INCOMPATIBILITY***
+	Code that sets traces on the ::errorInfo variable may notice a
+	difference in timing of the firing of those traces. Code that uses the
+	value ERR_IN_PROGRESS.
+
+2004-10-14  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	TIP#217 IMPLEMENTATION
+
+	* generic/tclCmdIL.c (Tcl_LsortObjCmd): Add -indices option from James
+	Salsman. [Patch 1017532]
+
+	* generic/tclUtil.c (TclMatchIsTrivial): Detect degenerate cases of
+	glob matching that let us avoid scanning through hash tables.
+	* generic/tclCmdIL.c (InfoCommandsCmd, InfoGlobalsCmd, InfoProcsCmd):
+	(InfoVarsCmd): Use this to speed up some [info] subcommands.
+
+2004-10-12  Kevin B. Kenny  <kennykb@acm.org>
+
+	* library/tzdata/America/Campo_Grande:
+	* library/tzdata/America/Cuiaba:
+	* library/tzdata/America/Sao_Paulo
+	* library/tzdata/America/Argentina/Mendoza:
+	* library/tzdata/America/Argentina/San_Juan:
+	Synchronized to Olson's 'tzdata2004e'.
+
+2004-10-08  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	TIP#201 AND TIP#212 IMPLEMENTATIONS
+
+	* doc/dict.n, doc/expr.n: Documentation for new functionality.
+	* tests/expr.test: Basic tests of 'in' and 'ni' behaviour.
+	* tests/dict.test (dict-21.*,dict-22.*): Tests for [dict update] and
+	[dict with].
+	* generic/tclExecute.c (TclExecuteByteCode): Implementation of the
+	INST_LIST_IN and INST_LIST_NOT_IN bytecodes.
+	* generic/tclParseExpr.c (GetLexeme): Parse the 'in' and 'ni'
+	operators for TIP#201.
+	* generic/tclDictObj.c (DictUpdateCmd,DictWithCmd): Core of
+	implementation of TIP#212; docs and tests still to do...
+
+2004-10-07  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclTest.c (TestsetobjerrorcodeCmd):  Simplified.
+
+2004-10-07  Vince Darley  <vincentdarley@users.sourceforge.net>
+
+	* generic/tclFileName.c:
+	* generic/tclFileSystem.h:
+	* generic/tclIOUtil.c:
+	* generic/tclPathObj.c:
+	* unix/tclUnixFile.c:
+	* win/tclWinFile.c:
+	* tests/fileName.test:
+	* tests/winFCmd.test: code reorganization for better generic/platform
+	code splitting [Bug 925620] removing the need for several #ifdef's,
+	and tests and fix for an unreported Windows glob problem ('glob -dir
+	C: -tails *').
+
+2004-10-07  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* *.3: Convert CONST to const and VOID to void so we document how
+	people should actually use the Tcl API and not the compatability hacks
+	that it has to have.
+
+	* doc/man.macros, *.3: Update .AS macro so it can know how wide to
+	make the third column of the argument list. Update documentation for C
+	API (only users) to take advantage of this.
+
+	* doc/FileSystem.3: Formatting fixes for greater documentation
+	clarity.
+
+2004-10-06  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* generic/tclFileName.c (DoGlob, TclGlob): Stop messy sharing of
+	interpreter result and instead use a private object for collecting the
+	result of the glob. This simplifies TclGlob quite a lot.
+	* generic/tclIOUtil.c (Tcl_FSMatchInDirectory): Simplify by removing
+	some nesting. Also standardize variable names.
+	(FsAddMountsToGlobResult): Force updates to the list to be done
+	in-place, putting a side-condition of non-shared-ness on the resultPtr
+	argument to Tcl_FSMatchInDirectory, but everything would have broken
+	before if that was shared *anyway*.
+
+	* generic/tclEncoding.c (LoadTableEncoding): Removed reference to Tcl
+	interpreter; it wasn't needed as direct object use is more efficient.
+
+	* generic/tclPathObj.c: Made this file follow the style rules in the
+	Engineering Manual more closely, and also take advantage of the
+	internal object manipulation macros more.
+
+	* generic/tclCmdMZ.c (Tcl_SwitchObjCmd): Reorganized to have fewer
+	magic flag variables and to separate the code that scans for a match
+	from the code that processes a match body.
+
+2004-10-06  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclBasic.c:
+	* generic/tclBinary.c:
+	* generic/tclCmdAH.c:
+	* generic/tclCmdIL.c:
+	* generic/tclCmdMZ.c:
+	* generic/tclCompExpr.c:
+	* generic/tclDictObj.c:
+	* generic/tclEncoding.c:
+	* generic/tclExecute.c:
+	* generic/tclFCmd.c:
+	* generic/tclHistory.c:
+	* generic/tclIndexObj.c:
+	* generic/tclInterp.c:
+	* generic/tclIO.c:
+	* generic/tclIOCmd.c:
+	* generic/tclNamesp.c:
+	* generic/tclObj.c:
+	* generic/tclPkg.c:
+	* generic/tclResult.c:
+	* generic/tclScan.c:
+	* generic/tclTimer.c:
+	* generic/tclTrace.c:
+	* generic/tclUtil.c:
+	* generic/tclVar.c:
+	* unix/tclUnixFCmd.c:
+	* unix/tclUnixPipe.c:
+	* win/tclWinDde.c:
+	* win/tclWinFCmd.c:
+	* win/tclWinPipe.c:
+	* win/tclWinReg.c:
+	It is a poor practice to directly set or append to the value of the
+	objResult of an interp, because that value might be shared, and in
+	that circumstance a Tcl_Panic() will be the result. Searched for
+	example of this practice and replaced with safer alternatives, often
+	using the Tcl_AppendResult() routine that dkf just rehabilitated.
+	* library/dde/pkgIndex.tcl: Bump to dde 1.3.1
+	* library/reg/pkgIndex.tcl: Bump to registry 1.1.5
+
+2004-10-06  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* doc/SetResult.3: Made Tcl_AppendResult non-deprecated; better that
+	people use it than most of the common alternatives!
+	* generic/tclResult.c (Tcl_AppendResultVA): Make this work better with
+	Tcl_Objs. [Patch 1041072]
+	(Tcl_SetResult, Tcl_AppendElement): Change string to stringPtr to
+	avoid C++ keywords.
+
+2004-10-05  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclBasic.c (TclObjInvoke): More simplification of the
+	TclObjInvoke routine toward unification with the rest of the
+	evaluation stack.
+
+	* generic/tclBasic.c (Tcl_CreateInterp, Tcl_DeleteInterp)
+	(TclEvalObjvInternal, Tcl_LogCommandInfo):
+	* generic/tclCmdAH.c (Tcl_CatchObjCmd):
+	* generic/tclEvent.c (BgError, Tcl_BackgroundError, HandleBgErrors):
+	* generic/tclInt.h (Interp, ERROR_CODE_SET):
+	* generic/tclNamesp.c (Tcl_CreateNamespace, Tcl_DeleteNamespace)
+	(TclTeardownNamespace):
+	* generic/tclResult.c (Tcl_ResetResult, Tcl_SetObjErrorCode)
+	(TclTransferResult):
+	* generic/tclTrace.c (CallVarTraces):
+	Reworked management of the "errorCode" data of an interp. That
+	information is now primarily stored in a new private (Tcl_Obj *) field
+	of the Interp struct, rather than using a global variable ::errorCode
+	as the primary storage. The ERROR_CODE_SET flag bit value is no longer
+	required to manage the value in its new location, and is removed.
+	Variable traces are established to support compatibility for any code
+	expecting the ::errorCode variable to hold the information.
+
+	***POTENTIAL INCOMPATIBILITY***
+	Code that sets traces on the ::errorCode variable may notice a
+	difference in timing of the firing of those traces.
+
+	* generic/tclNamesp.c (Tcl_PopCallFrame): Removed Bug 1038021
+	workaround. That bug is now fixed.
+
+2004-10-04  Kevin B. Kenny  <kennykb@acm.org>
+
+	* tests/clock.test (clock-34.*): Removed an antibug that forced
+	comparison of [clock scan] results with the :localtime time zone. Now
+	that [clock scan] uses the current time zone instead, the antibug
+	caused several tests to fail. [Bug 1038554]
+
+2004-10-04  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* generic/tclParseExpr.c (GetLexeme): Ensure that the 'eq' and 'ne'
+	operators are followed by non-alphabetic characters so lexemes can't
+	run together. [Bug 884830]
+
+	* doc/DictObj.3, doc/dict.n: Clarified that a dictionary is not
+	order-preserving. [Bug 1032243] Also added another example to show off
+	more ways of using a dictionary and a few other formatting
+	improvements.
+
+2004-10-02  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* generic/tclDictObj.c (TraceDictPath, Tcl_DictObjPutKeyList): Add
+	support for automatic creation of dictionary paths since that is what
+	everyone seems to actually expect of the API! [Bug 1037235]
+	(Tcl_DictObjNext): Make calling this after Tcl_DictObjDone non-fatal
+	as that simplifies a number of internal APIs. This doesn't break any
+	existing working code as it is a case which previously caused a panic.
+
+2004-10-02  Don Porter	<dgp@users.sourceforge.net>
+
+	* tests/namespace.test (namespace-8.7):	Another test for save/restore
+	of ::errorInfo and ::errorCode during global namespace teardown.
+
+2004-10-01  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* generic/tclProc.c (TclObjGetFrame, Tcl_UplevelObjCmd):
+	* generic/tclVar.c (Tcl_UpvarObjCmd): Cache stackframe level
+	references in the level object for speed.
+
+2004-09-30  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclBasic.c (Tcl_CreateInterp):
+	* generic/tclInt.h (Interp): Removed the flag bit value
+	EXPR_INITIALIZED. It was set during interp creation and never tested.
+	Whatever purpose it had is in the past.
+
+	* generic/tclBasic.c (Tcl_EvalObjEx):	Removed the flag bit value
+	* generic/tclInt.h (Interp):	        USE_EVAL_DIRECT. It was used
+	* generic/tcLTest.c (TestevalexObjCmd): only in the testing command
+	* tests/parser.test (parse-9.2):        [testevalex] and nothing in
+	the test suite made use of the capability it enabled.
+
+	* generic/tclBasic.c (Tcl_AddObjErrorInfo): More re-organization
+	* generic/tclCmdAH.c (Tcl_ErrorObjCmd):	    of the management of
+	* generic/tclCmdMZ.c (TclProcessReturn):    the errorCode value.
+	* tests/error.test (error-6.4-9):
+
+	* generic/tclNamespace.c (TclTeardownNamespace): Tcl_Obj-ified
+	* tests/namespace.test (namespace-8.5,6):	 the save/restore of
+	::errorInfo and ::errorCode during global namespace teardown. Revised
+	the comment to clarify why this is done, and added tests that will
+	fail if this is not done.
+
+	* generic/tclResult.c (TclTransferResult): Added safety checks so that
+	unexpected undefined ::errorInfo or ::errorCode will not lead to a
+	segfault.
+
+	* generic/tclTrace.c (TclCallVarTraces):  Save/restore the flag values
+	* tests/var.test (var-16.1):	          that define part of the
+	interpreter state during variable traces. [Bug 1038021].
+
+2004-09-30  Miguel Sofer <msofer@users.sf.net>
+
+	* tests/subst.test (12.1-2): added tests for [Bug 1036649]
+
+2004-09-29  Don Porter	<dgp@users.sourceforge.net>
+
+	* tests/basic.test (49.*): New tests for TCL_EVAL_GLOBAL.
+
+2004-09-29  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* generic/tclVar.c (TclObjLookupVar, TclObjLookupVar):
+	(TclObjUnsetVar2, SetArraySearchObj):
+	* generic/tclUtil.c (SetEndOffsetFromAny):
+	* generic/tclStringObj.c (Tcl_SetStringObj):
+	(Tcl_SetUnicodeObj, SetStringFromAny):
+	* generic/tclResult.c (ResetObjResult):
+	* generic/tclRegexp.c (Tcl_GetRegExpFromObj):
+	* generic/tclPathObj.c (TclFSMakePathRelative, SetFsPathFromAny):
+	(TclFSMakePathFromNormalized, Tcl_FSNewNativePath):
+	* generic/tclObj.c (TclFreeObj, Tcl_SetBooleanObj, SetBooleanFromAny):
+	(Tcl_SetDoubleObj, SetDoubleFromAny, Tcl_SetIntObj):
+	(SetIntOrWideFromAny, Tcl_SetLongObj, SetWideIntFromAny):
+	(Tcl_SetWideIntObj, TclSetCmdNameObj, SetCmdNameFromAny):
+	* generic/tclNamesp.c (SetNsNameFromAny, MakeCachedEnsembleCommand):
+	* generic/tclListObj.c (Tcl_SetListObj, SetListFromAny):
+	* generic/tclIndexObj.c (Tcl_GetIndexFromObjStruct):
+	* generic/tclDictObj.c (SetDictFromAny):
+	* generic/tclCompile.c (TclInitByteCodeObj):
+	* generic/tclBinary.c (Tcl_SetByteArrayObj, SetByteArrayFromAny):
+	* generic/tclInt.h (TclFreeIntRep): Factorize out deletion of object
+	internal representation to a shared macro, so simplifying much code.
+
+2004-09-27  Miguel Sofer <msofer@users.sf.net>
+
+	* generic/tclBasic.c (TclObjInvoke): fix for bogus gcc warning about
+	uninitialised variable.
+
+2004-09-27  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclBasic.c:	Removed internal routines TclInvoke,
+	* generic/tclInt.decls: TclGlobalInvoke, TclObjInvokeGlobal and the
+	* tests/basic.test:	portion of TclObjInvoke that handles calls
+	without TCL_INVOKE_HIDDEN enabled. None of this code is called any
+	longer within the core, and the superior public interface,
+	Tcl_EvalObjv, is available for any external callers.
+
+	* generic/tclIntDecls.h:	make genstubs
+	* generic/tclStubInit.c:
+
+	* generic/tclEvent.c (HandleBgErrors): Updated [bgerror] invocations
+	to make use of Tcl_Obj based routines, dropping the calls to
+	TclGlobalInvoke()
+
+2004-09-27  Vince Darley  <vincentdarley@users.sourceforge.net>
+
+	* generic/tclFileName.c:
+	* generic/tclFileSystem.h:
+	* generic/tclIOUtil.c:
+	* generic/tclPathObj.c:
+	* tests/cmdAH.test:
+	* tests/fileSystem.test:
+	* tests/winFCmd.test: fix to bad error message with 'cd' on windows,
+	when permissions are inadequate [Bug 1035462] and to treatment of a
+	volume-relative pwd on Windows [Bug 1018980].
+
+	* doc/FileSystem.3: added missing Tcl_GlobTypeData documentation [Bug
+	935853]
+
+2004-09-27  Kevin Kenny	 <kennykb@acm.org>
+
+	* compat/strftime.c (Removed):
+	* generic/tclClock.c (removed TclClockOldscanObjCmd):
+	* generic/tclDate.c (Regenerated):
+	* generic/tclGetDate.y:
+	* generic/tclInt.decls (removed TclGetDate and TclpStrftime):
+	* generic/tclInt.h (removed TclGetDateInfo):
+	* generic/tclIntDecls.h (Regenerated):
+	* generic/tclStubInit.c (Regenerated):
+	* library/clock.tcl:
+	* unix/tclUnixTime.c (removed TclpStrftime):
+	* win/Makefile.in:
+	* win/makefile.bc:
+	* win/makefile.bc:
+	* win/tcl.dsp:
+	Continued refactoring of [clock] for TIP 173 changes. Broke the
+	free-form parser apart so that the Bison parser is responsible for
+	only parsing, while clock.tcl handles relative times like "next
+	Thursday", "next January". This change is needed to make timezones
+	other than :localtime and :Etc/UTC work with free-form scanning. This
+	change closes out the issue identified as being "for another day" in
+	my log message of 2004-09-08. The refactored code also eliminates the
+	last known references to TclpStrftime and TclGetDate, so those
+	routines (including compat/strftime.c) have been removed. The
+	refactoring also has the benefit that all storage in the Bison parser
+	is now on the C stack, eliminating any need for mutex protection
+	around [clock scan]. Also, changed the Makefiles so that 'make
+	gendate' is available on Windows as well as Unix.
+
+	* generic/tclCmdAH.c (Tcl_FormatObjCmd): Removed some grubby
+	* generic/tclObj.c (SetBooleanFromAny):	 work-around code that was
+	needed only because of Bug 868489.
+
+	* generic/tclBasic.c (TclObjInvoke): Removed three unused variables to
+	silence a compiler warning in VC++.
+
+2004-09-27  Vince Darley  <vincentdarley@users.sourceforge.net>
+
+	* doc/FileSystem.3: fix to small typo.
+
+2004-09-26  Miguel Sofer <msofer@users.sf.net>
+
+	* generic/tclCompCmds.c:
+	* generic/tclCompExpr.c:
+	* generic/tclCompile.c:
+	* generic/tclCompile.h:
+	* generic/tclInt.h:
+	* generic/tclProc.c:
+	* tests/compExpr-old.test:
+	* tests/compExpr.test:
+	* tests/expr.test:
+	* tests/for.test:
+	* tests/if.test:
+	* tests/incr.test:
+	* tests/while.test:
+	Report compilation errors at runtime, [Patch 1033689] by dgp.
+
+2004-09-23  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* unix/dltest/Makefile.in (clean): Fixup make clean rule so that it
+	does not delete all files when SHLIB_SUFFIX is set to the empty string
+	in a static build. [Bug 1016726]
+
+2004-09-23  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclBasic.c:	Corrections to the 2004-09-21 commit
+	* generic/tclExecute.c:	regarding ERR_ALREADY_LOGGED. That commit
+	* generic/tclNamesp.c:	caused Tk test send-10.7 to fail. Added
+	* tests/namespace.test (25.7,8): tests in the Tcl test suite
+	* tests/pkg.test (2.25,26):	 to catch this error without the aid
+	of Tk in the future.
+
+	* generic/tclCmdAH.c (Tcl_ExprObjCmd):	Simplified the TclObjCmdProc
+	of [expr] with a call to Tcl_ConcatObj.
+
+2004-09-22  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclCmdMZ.c (TclProcessReturn):	Support the -errorline
+	* generic/tclCompile.c (TclCompileScript):	option to [return].
+	* tests/compile.test (16.23.*):	Use that capability to defer reporting
+	* tests/misc.test (1.2):	of parse errors until runtime. Updated
+	tests to reflect change. [Bug 1032805]
+
+2004-09-22  Miguel Sofer <msofer@users.sf.net>
+
+	* generic/tclExecute.c (INST_START_CMD):
+	* tests/proc.test (7.2-3): fix for [Bug 729692] was incorrect whenever
+	a loop exception was returned.
+
+2004-09-22  Kevin B. Kenny  <kennykb@acm.org>
+
+	* library/tzdata/America/Montevideo: Updated to reflect
+	ftp://elsie.nci.nih.gov/pub/tzdata2004d.tar.gz. (Changes to
+	Asia/Jerusalem were in the comments only.) [Routine maintenance - no
+	bug] Spanish-language description of the change at
+	http://www.presidencia.gub.uy/decretos/2004091502.htm
+
+2004-09-21  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclCompCmds.c:	Tolerate [append] syntax errors
+	* tests/appendComp.test (8.1):	at compile time, and allow runtime to
+	raise the error (or succeed if a redefined [append] allows).
+
+	* generic/tclBasic.c:	Reworked management of the interp flag
+	* generic/tclCompile.c:	ERR_ALREADY_LOGGED, to reduce its exposure.
+	* generic/tclExecute.c: Still left several referebces that are just
+	* generic/tclNamesp.c:	too nice on performace to do away with.	These
+	changes also resolve an inconsistency in the ::errorInfo values
+	produced by [namespace eval x error foo bar] and [namespace eval x
+	{error foo bar}].
+
+	* generic/tclExecute.c (TclCompEvalObj):	Simplified the
+	TclCompEvalObj routine. Much housekeeping now reliably happens
+	elsewhere. [Patch 1031949]
+
+2004-09-21  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* doc/interp.n: Tighten up wording on how [interp eval] and [interp
+	invokehidden] operate w.r.t. stack frames. [Bug 926590]
+
+2004-09-20  Don Porter	<dgp@users.sourceforge.net>
+
+	* tests/error.test (error-6.2,3):	Added more tests to verify
+	::errorCode setting by/after a [catch].
+
+2004-09-19  Miguel Sofer <msofer@users.sf.net>
+
+	* generic/tclCmdAH.c: removed outdated comment [Bug 1029518].
+
+2004-09-18  David Gravereaux <davygrvy@pobox.com>
+
+	* win/tclAppInit.c: Dde package can load into a safe interp. Claim
+	this fact for the Tcl_StaticPackage() call when the shell is built
+	with the TCL_USE_STATIC_PACKAGES option.
+
+2004-09-18  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* generic/tclExecute.c (TEBC-INST_LSHIFT,INST_RSHIFT): Ensure that
+	large shifts end up shifting correctly. [Bug 868467]
+
+	* doc/FileSystem.3, doc/OpenFileChnl.3: More documentation fixes from
+	Mikhail Kolesnitchenko. [Patch 1022527]
+	* doc/*: Standardize highlighting of symbols defined in tcl.h
+
+2004-09-17  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclBasic.c (Tcl_AddObjErrorInfo, Tcl_LogCommandInfo):
+	* generic/tclCmdAH.c ([catch], [error]):
+	* generic/tclCmdMZ.c ([return]):
+	* generic/tclProc.c (TclUpdateReturnInfo):
+	* generic/tclResult.c (Tcl_SetErrorCodeVA, Tcl_SetObjErrorCode)
+	(TclTransferResult):	Refactored so that all errorCode setting flows
+	through Tcl_SetObjErrorCode(). This greatly reduces the number of
+	different places in the code that need to know details about an
+	internal bitflag field of the Interp struct. Also places errorCode
+	setting in one place for easier future mods.
+
+2004-09-17  Kevin B.Kenny  <kennykb@acm.org>
+
+	* generic/tclDate.c:	Revised tclGetDate.y to use bison instead of
+	* generic/tclGetDate.y: yacc to build the parser, eliminating all the
+	* generic/tclInt.h:	complicated hackery involving 'sed'
+	* unix/Makefile.in:	postprocessing. Rebuilt the parser.
+
+2004-09-14  Kevin B. Kenny  <kennykb@acm.org>
+
+	* generic/tclClock.c (ClockOldscanObjCmd): Silenced a compiler warning
+	(long passed as a param where unsigend long was expected). 'Unsigned
+	long' is wrong, but the fix is really to change the signature of
+	TclGetDate to return a structure of its 'yy' variables and then do the
+	remaining work inside clock.tcl. But, as I said on 2004-09-08, that's
+	a job for another day. [Bug 1027993]
+
+2004-09-10  Miguel Sofer <msofer@users.sf.net>
+
+	* doc/interp.n:
+	* generic/tclInterp.c (TclPreventAliasLoop, AliasCreate):
+	* tests/interp.test (17.4-6, 19.3-4): fixing problems with renaming of
+	aliases [Bugs 707104 1026493]. Fix designed by dgp.
+
+2004-09-13  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* generic/tclNamesp.c (NsEnsembleImplementationCmd): Add token field
+	to internal rep of EnsembleCmdRep structure so that we can check it to
+	see if the subcommand object is really being used with the same
+	ensemble. [Bug 1026903]
+
+2004-09-11  Kevin B. Kenny  <kennykb@acm.org>
+
+	* generic/tclClock.c (TclMktimeObjCmd): Corrected a bad check for
+	error return from 'mktime'.
+	* generic/tclObj.c (Tcl_GetIntFromObj): Corrected a problem where
+	demoting a wide to an int failed on a big-endian machine. [Bug
+	1026125].
+	* tests/clock.test (clock-43.1): Added regression test for error
+	return from 'mktime'.
+
+2004-09-11  Miguel Sofer <msofer@users.sf.net>
+
+	* generic/tclExecute.c (INST_CONCAT1): fix for [Bug 1025834]; avoid
+	unnecessary string copies.
+
+2004-09-10  David Gravereaux <davyrgvy@pobox.com>
+
+	* tests/tcltest.test: tcltest-12.3-4 needed to have
+	::tcltest::loadScript set to empty in their -setup
+
+2004-09-10  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* generic/tclObj.c (SetIntOrWideFromAny): Rewritten integral value
+	parsing code so that values do not flip so easily between numeric
+	representations. Thanks to KBK for this! [Bug 868489]
+
+	* generic/tclIO.c (Tcl_Seek): Make sure wide seeks do not fail to set
+	::errorCode on error. [Bug 1025359]
+
+2004-09-10  Andreas Kupries  <andreask@activestate.com>
+
+	* generic/tcl.h: Micro formatting fixes.
+	* generic/tclIOGT.c: Channel version fixed, must be 3, to have
+	wideseekProc. Thanks to David Graveraux <davygrvy@pobox.com>.
+
+2004-09-11  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclNamespace.c (TclGetNamespaceForQualName): Resolved
+	longstanding inconsistency in the treatment of the TCL_NAMESPACE_ONLY
+	flag revealed by testing the 2004-09-09 commits against Itcl.
+	TCL_NAMESPACE_ONLY now acts as specified in the pre-function comment,
+	forcing resolution in the passed in context namespace. It has been
+	incorrectly forcing resolution in the interp's current namespace.
+
+2004-09-10  Kevin Kenny	 <kennykb@acm.org>
+
+	* library/clock.tcl: Fixed a bug where %z always put a plus sign on
+	the time zone in :localtime.
+	* tests/clock.test: Added test case for the above bug.
+
+2004-09-10  Miguel Sofer <msofer@users.sf.net>
+
+	* generic/tclExecute.c (INST_CONCAT1): added a peephole optimisation
+	for concatting an empty string. This enables replacing the idiom 'K $x
+	[set x {}]' by '$x[set x {}]' for fastest execution.
+
+2004-09-09  David Gravereaux <davygrvy@pobox.com>
+
+	* win/tclWinConsole.c: Calls to WriteFile and WriteConsoleA changed to
+	WriteConsole for simplicity.
+
+2004-09-09  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclNamesp.c (Tcl_ForgetImport):	Corrected faulty
+
+	* tests/namespace.test: logic that relied exclusively on string
+	matching and failed in the presence of [rename]s. [Bug 560297] Also
+	corrected faulty prevention of [namespace import] cycles. [Bug 1017299]
+
+2004-09-08  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclBasic.c (Tcl_CreateInterp):	Removed obsolete field
+	for storing the string-based command procedure of built-in commands.
+	We no longer have any string-based built-in commands!
+
+2004-09-08  Kevin B. Kenny <kennykb@acm.org>
+
+	* compat/strftime.c (_conv): Corrected a problem where hour 0 would
+	format as a blank format group with %k.
+	* doc/clock.n: Corrected a buglet in the header information. [Bug
+	1024058]
+	* generic/tclClock.c (TclClockMktimeObjCmd): Fixed a bug where the
+	month was scanned incorrectly in -timezone :localtime.
+	* tests/clock.test (clock-34.*,clock-40.1, clock-41.1): Adjusted the
+	clock-34.* test cases so that the consistency check is performed in
+	:localtime rather than the current time zone. This change allows
+	dealing with issues where the C library has a different idea of DST
+	conversion than Tcl. (Real fix would be to break TclGetDate into
+	separate parser and time converter, and do the time conversion in
+	clock.tcl. That's for another day.) Added regression test case for the
+	bug where month was scanned incorrectly in -timezone :localtime. [Bug
+	1023779] Added regression test case for %k at the zero hour.
+
+2004-09-07  David Gravereaux <davygrvy@pobox.com>
+
+	* win/makefile.vc: some quoting needed to be removed as it was
+	breaking with VC7. [Bug 1023150]
+
+2004-09-07  Kevin B. Kenny  <kennykb@acm.org>
+
+	* doc/clock.n: Documented the default -format, and changed references
+	to a (nonexistent) msgcat command to refer to the msgcat package. [Bug
+	1023870]
+	* generic/tclTimer.c: Removed a premature optimisation that attempted
+	to store the assoc data in the client data; the optimisation caused a
+	bug that [after] would overwrite its imports. [Bug 1016167]
+	* library/clock.tcl (InitTZData, ClearCaches): Changed so that the
+	in-memory time zone :UTC (and its aliases) always gets reinitialised,
+	in case tzdata is absent. [Bug 1019537, 1023779]
+	* library/tzdata/*: Regenerated.
+	* tests/clock.test (clock-31.*, clock-39.1): Corrected a problem where
+	the 'system' locale tests fail on a non-English Windows machine. [Bug
+	1023761]. Added a test to make sure that alias time zones load
+	correctly. [Bug 1023779].
+	* tests/timer.test (timer-1.1, timer-2.1): Changed to (one hopes!) be
+	more resilient on an overloaded system, if [after 200] sleeps for 300
+	ms or longer.
+	* tools/tclZIC.tcl (writeLinks): Corrected a problem where alias time
+	zone names were written incorrectly, causing them to fail to load at
+	run time. [Bug 1023779].
+	* win/tclWinTime.c (Tcl_GetTime): Eliminated CPUID tests on Win64 -
+	assuming that HAL vendors now do a better job of keeping the
+	performance counters synchronized among CPU's. [Bug 1020445]
+
+2004-09-06  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* doc/tclvars.n, doc/tcltest.n, doc/tclsh.1, doc/safe.n, doc/expr.n
+	* doc/WrongNumArgs.3, doc/Utf.3, doc/TraceVar.3, doc/Thread.3
+	* doc/TCL_MEM_DEBUG.3, doc/SubstObj.3, doc/StdChannels.3
+	* doc/SetResult.3, doc/RegExp.3, doc/RegConfig.3, doc/RecEvalObj.3
+	* doc/PrintDbl.3, doc/ParseCmd.3, doc/Panic.3, doc/ObjectType.3
+	* doc/Object.3, doc/Namespace.3, doc/Interp.3, doc/IntObj.3
+	* doc/Hash.3, doc/GetOpnFl.3, doc/GetIndex.3, doc/Eval.3
+	* doc/Encoding.3, doc/DoubleObj.3, doc/DictObj.3, doc/CrtTimerHdlr.3
+	* doc/CrtObjCmd.3, doc/CrtMathFnc.3, doc/CrtCommand.3, doc/CrtChannel.3
+	* doc/ChnlStack.3, doc/ByteArrObj.3, doc/AssocData.3, doc/Alloc.3:
+	More documentation fixes from Mikhail Kolesnitchenko. [Patch 1022527]
+
+2004-09-03  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* unix/tclUnixFCmd.c: Stop NULL interp arguments from triggering a
+	crash when an error happens. [Bug 1020538]
+
+2004-09-02  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* doc/lsearch.n: Clarified meaning of -dictionary. [Bug 759545]
+
+2004-09-02  Vince Darley  <vincentdarley@users.sourceforge.net>
+
+	* win/makefile.vc: clock.tcl needs to be installed.
+
+2004-09-01  Jeff Hobbs	<jeffh@ActiveState.com>
+
+	* win/tclWinReg.c (BroadcastValue): WIN64 cast corrections
+
+	* win/tclWinDde.c (DdeClientWindowProc):
+	(DdeServicesOnAck, DdeEnumWindowsCallback): WIN64 corrections
+
+	* win/tclWin32Dll.c (TclWinCPUID): need _asm for WIN64 (Itanium),
+	until we have it, just return unknown. [Bug 1020445]
+
+2004-09-01  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* doc/regsub.n, doc/RegConfig.3, doc/Environment.3:
+	* doc/CrtChannel.3, doc/safe.n: Use correct abbreviations.
+
+2004-08-31  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* doc/trace.n, doc/socket.n, doc/registry.n, doc/pid.n:
+	* doc/namespace.n, doc/msgcat.n, doc/lsort.n, doc/lsearch.n:
+	* doc/linsert.n, doc/info.n, doc/http.n, doc/history.n:
+	* doc/format.n, doc/file.n, doc/exec.n, doc/dde.n, doc/clock.n:
+	* doc/catch.n, doc/binary.n: More spelling and grammar fixes from
+	Mikhail Kolesnitchenko. [Patch 1018486]
+
+2004-08-31  Vince Darley  <vincentdarley@users.sourceforge.net>
+
+	* doc/FileSystem.3:
+	* generic/tclIOUtil.c: Clarified documentation regarding ability of a
+	filesystem to say that it doesn't support a given operation using the
+	EXDEV posix error code (copyFileProc, renameFileProc, etc), and
+	updated one piece of code to ensure correct behaviour when an
+	operation is not supported [Bug 1017072]
+
+	* tests/fCmd.test: fix to test suite problem [Bug 1002884]
+
+2004-08-31  Daniel Steffen  <das@users.sourceforge.net>
+
+	* unix/Makefile.in (install-libraries): portable sh fix.
+
+2004-08-30  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* generic/tclCmdMZ.c (Tcl_StringObjCmd): Stop [string map] from
+	crashing when its map and input string are the same object.
+
+2004-08-27  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* generic/tclNamesp.c (FindEnsemble): Factor out the code to convert a
+	command name into an ensemble configuration and add support for
+	ignoring [namespace import] link chains. [Bug 1017022]
+	(NamespaceWhichCmd): Rework to use newer option parsing API.
+
+2004-08-27  Daniel Steffen  <das@users.sourceforge.net>
+
+	* unix/Makefile.in: added customization of default module path roots
+	via TCL_MODULE_PATH makefile variable.
+	* macosx/Makefile: add platform standard locations to default module
+	path roots. [Patch 942881]
+
+	* tests/env.test: macosx fixes.
+
+2004-08-25  Don Porter	<dgp@users.sourceforge.net>
+
+	* tests/timer.test (timer-10.1):	Test for Bug 1016167.
+	* generic/tclTimer.c: Workaround for situation when a [namespace
+	import] causes the objv[0] value to be something other than what
+	Tcl_AfterObjCmd expects. [Bug 1016167].
+
+2004-08-25  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* generic/tclNamesp.c (NsEnsembleImplementationCmd): Use the ensemble
+	command token to get the name of the ensemble for passing to the
+	-unknown handler instead of relying on objv[0], which may contain
+	useless info in the presence of [namespace import]. Problem found by
+	Don Porter when investigating [Bug 1016167].
+
+2004-08-24  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclProc.c:		The routine TclProcInterpProc was a
+	* generic/tclTestProcBodyObj.c: specific instance of the general
+	service already provided by TclObjInvokeProc. Removed
+	TclProcInterpProc and TclGetInterpProc from the code...
+
+	* generic/tclInt.decls:	...and from the internal stubs table.
+	* generic/tclIntDecls.h
+	* generic/tclStubInit.c
+
+2004-08-24  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* doc/string.n: Added clarifying note.
+
+2004-08-23  Don Porter	<dgp@users.sourceforge.net>
+
+	* library/auto.tcl:	Updated [tcl_findLibrary] search path to
+	include any [<pkg>::pkgconfig get scriptdir,runtime] directory, as
+	well as the $::auto_path. [RFE 695441]
+
+2004-08-21  Kevin B. Kenny  <kennykb@acm.org>
+
+	* tests/clock.test (clock-38.1): Changed TZ setting to specify CET in
+	excruciating detail to deal with systems that lack the Posix defaults
+	for DST changes (and to be formally correct with the change dates for
+	CET).
+
+2004-08-19  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* generic/tclScan.c (Tcl_ScanObjCmd, ValidateFormat): Ensure that the
+	%ld conversion works correctly on 64-bit platforms. [Bug 1011860]
+
+2004-08-19  Kevin Kenny	 <kennykb@acm.org>
+
+	* library/clock.tcl (format): Changed default timezone format from
+	alphabetic to numeric to produce scannable times in more locales.
+	* tests/clock.test (clock-37.1): Removed now-unused 'needPST'
+	constraint and the comments that refer to it.
+
+2004-08-18  Andreas Kupries  <andreask@activestate.com>
+
+	* library/init.tcl: Integrated TIP #189. We source a separate file
+	(see below), instead of inlining the contents of that file. This
+	should beeasier to maintain, and easier to backport/install in 8.4
+	installations.
+
+	Note: Usage of Tcl Modules is restricted to non-safe interps. It
+	cannot be loaded into a safe interp.
+
+	* library/tm.tcl: New file, the v2 reference implementation for TIP
+	#189, Tcl Modules.
+
+	* doc/tm.n: New file, documentation for Tcl Modules, based on the TIP.
+
+	* unix/mkLinks: Regenerated.
+	* win/makefile.vc: Added tm.tcl to list of files to install.
+
+2004-08-18  Kevin Kenny	 <kennykb@acm.org>
+
+	* tests/httpd (httpdRespond): Corrected an abuse of the [clock]
+	command that caused test failures for some values of [clock clicks].
+
+	* doc/clock.n
+	* generic/tclBasic.c (Tcl_CreateInterp, Tcl_HideUnsafeCommands):
+	* generic/tclClock.c (all):
+	* generic/tclInt.h:
+	* generic/tclInterp.c (CreateSlave):
+	* library/clock.tcl: (new file)
+	* library/init.tcl (clock):
+	* library/msgs/*.msg:(new files)
+	* library/tzdata/*:
+	* library/tzdata/*/*:
+	* library/tzdata/*/*/*: (new files)
+	* tools/installData.tcl: (new file)
+	* tools/loadICU.tcl: (new file)
+	* tools/makeTestCases.tcl: (new file)
+	* tools/tclZIC.tcl: (new file)
+	* unix/Makefile.in:
+	* unix/configure: (regenerated)
+	* unix/tcl.m4:
+	* tests/clock.test (all):
+	* win/Makefile.in:
+	* win/Makefile.vc:
+		Implementation of TIPs #173 and #209.
+
+	The [clock] command is now a Tcl ensemble, with most of its
+	functionality written in Tcl and callouts to C code only to access
+	low-level functions such as localtime, mktime and tzset.
+
+	In addition to the functionality changes called out in the two TIPs,
+	it is worth noting that the [clock] command in a safe slave
+	interpreter is now an alias to the [clock] command in the master, and
+	that [clock] is otherwise not expected to function entirely correctly
+	in safe interps. C code that simply does Tcl_MakeSafe needs to be
+	aware that [clock] may need special handling. (It appears unlikely
+	that such code actually exists.)
+
+	One incompatibility of note is that if the time zone cannot be
+	determined from the TZ, TCL_TZ environment variables, or from the
+	Windows control panel, so that the C library must be used for date and
+	time conversions, then times outside the range of time_t will fail;
+	they used to return bad data silently.
+
+	Many thanks to all the many people who assisted with testing,
+	debugging, criticism of the specification, and localisation. Deserving
+	of particular mention are Joe English, Clif Flynt, Donal K. Fellows,
+	Jeff Hobbs, Cameron Laird, Arjen Markus, Reinhard Max, Christopher
+	Nelson, Steve Offutt, Donald G. Porter, Pascal Scheffers, Peter da
+	Silva and Richard Suchenwirth-Bauersachs.
+
+	*** POTENTIAL INCOMPATIBILITY ***
+
+2004-08-16  Miguel Sofer <msofer@users.sf.net>
+
+	* doc/SetVar.3:
+	* generic/tclTest.c (TestseterrorcodeCmd):
+	* generic/tclVar.c (TclPtrSetVar):
+	* tests/result.test (result-4.*, result-5.*): [Bug 1008314] detected
+	and fixed by dgp.
+
+2004-08-13  Don Porter	<dgp@users.sourceforge.net>
+
+	* library/msgcat/msgcat.tcl:	Added checks to prevent [mclocale]
+	* tests/msgcat.test:	from registering filesystem paths to possibly
+	malicious code to be evaluated by a later [mcload].
+
+2004-08-10  Zoran Vasiljevic <vasiljevic@users.sf.net>
+
+	* unix/tclUnixThrd.c (TclpThreadCreate): changed handling of the
+	returned thread ID since broken on 64-bit systems (Cray). Thanks to
+	Rob Ratcliff for reporting the bug.
+
+2004-08-03  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* generic/tclNamesp.c (MakeCachedEnsembleCommand): Initialize the
+	epoch field cached in the subcommand. [Bug 989298]
+	(NsEnsembleImplementationCmd): Plug a leak (thanks to Miguel Sofer for
+	spotting it with valgrind) and reduce the number of goto labels to
+	make the code clearer.
+
+2004-08-02  Don Porter	<dgp@users.sourceforge.net>
+
+	* library/package.tcl (pkg_mkIndex):	Updated [pkg_mkIndex] to make
+	use of [glob -directory $dir -tails] and return options.
+
+	TIP#207 IMPLEMENTATION
+
+	* doc/interp.n:		Added support for a -namespace option to the
+	* generic/tclBasic.c:	[interp invokehidden] command.	Also added an
+	* generic/tclInt.h:	internal routine TclObjInvokeNamespace() and
+	* generic/tclInterp.c:	corrected the flag names TCL_FIND_ONLY_NS and
+	* generic/tclNamesp.c:	TCL_CREATE_NS_IF_UNKNOWN that are passed to the
+	* generic/tclTrace.c:	internal routine TclGetNamespaceForQualName().
+	* tests/interp.test:	[Patch 981841]
+
+	* generic/tclLiteral.c (TclCleanupLiteralTable):	Corrected
+	* tests/compile.test (compile-12.4):	flawed deletion of literal
+	internal reps that could lead to accessing of freed memory. Thanks to
+	Kevin Kenny for test case and fix [Bug 1001997].
+
+2004-07-30  Don Porter	<dgp@users.sourceforge.net>
+
+	* tests/safe.test (safe-2.1):  Disabled senseless test.	 [Bug 999612]
+
+	* library/auto.tcl (auto_reset):  Removed "protected" list of commands
+	from [auto_reset]. All entries in the auto_index can be re-loaded.
+	* library/package.tcl: Updated comment to reflect 2004-07-28 commit.
+
+	* generic/tclEvent.c (Tcl_Finalize):	Re-organized Tcl_Finalize so
+	that Tcl_ExitProc's that call Tcl_Finalize recursively do not cause
+	deadlock. [Patch 999084 fixes Tk Bug 714956]
+
+2004-07-30  Daniel Steffen  <das@users.sourceforge.net>
+
+	* unix/configure:
+	* unix/tcl.m4 (SC_CONFIG_CFLAGS): Darwin: instead of setting PLAT_OBJS
+	to explict object files in tcl.m4, refer to MAC_OSX_OBJS makefile var.
+	* unix/Makefile.in: added MAC_OSX_OBJS variable.
+
+2004-07-29  Don Porter	<dgp@users.sourceforge.net>
+
+	* library/package.tcl: [::pkg::create] is now an alias. Test safe-2.1
+	will now fail until Bug 999612 is corrected.
+
+2004-07-28  Don Porter	<dgp@users.sourceforge.net>
+
+	* library/package.tcl:		Moved private command
+	* library/tclIndex:		[pkg_compareExtension] into ::tcl::Pkg.
+	* tests/pkg_mkIndex.test:	Also moved implementation of
+	[::pkg::create] to [::tcl::Pkg::Create].
+
+2004-07-25  Pat Thoyts	<patthoyts@users.sourceforge.net>
+
+	* tests/io.test: Make io-61.1 create file as binary to pass on Win32
+
+2004-07-23  Miguel Sofer <msofer@users.sf.net>
+
+	* generic/tclVar.c: simplify tclLocalVarNameType, removing the
+	reference to the corresponding proc. The reference is now seen as
+	unnecessary, and it may cause leaking circular references under some
+	circumstances (see for example [Bug 994838]).
+
+2004-07-22  Don Porter	<dgp@users.sourceforge.net>
+
+	* tests/eofchar.data (removed): Test io-61.1 now generates its own
+	* tests/io.test:	file of test data as needed.
+
+2004-07-20  Jeff Hobbs	<jeffh@ActiveState.com>
+
+	* generic/tclEvent.c:	    Correct threaded obj allocator to
+	* generic/tclInt.h:	    fully cleanup on exit and allow for
+	* generic/tclThreadAlloc.c: reinitialization. [Bug 736426]
+	* unix/tclUnixThrd.c:	    (mistachkin, kenny)
+	* win/tclWinThrd.c:
+
+2004-07-21  Kevin Kenny	 <kennykb@acm.org>
+
+	* generic/tclBasic.c (DeleteInterpProc):
+	* generic/tclLiteral.c (TclCleanupLiteralTable):
+	* generic/tclInt.h: added a TclCleanupLiteralTable function, called
+	from DeleteInterpProc, that frees internal representations of shared
+	literals early when an interpreter is being deleted. This change
+	corrects a number of memory mismanagement issues in the cases where
+	the internal representation of one literal contains a reference to
+	another, and avoids conditions such as resolved variable names
+	referring to procedure and namespace contexts that no longer exist.
+	[Bug 994838]
+
+2004-07-20  Daniel Steffen  <das@users.sourceforge.net>
+
+	* unix/Makefile.in:
+	* win/Makefile.in: added 'install-private-headers' makefile target to
+	allow optionally installing private tcl headers. [FR 922727]
+
+	* macosx/Makefile: use new 'install-private-headers' target to install
+	private headers into framework. [FR 922727]
+
+	* unix/tclUnixFile.c (NativeMatchType): added support for readonly
+	matching of user immutable files (where available).
+
+	* macosx/tclMacOSXBundle.c: dynamically acquire address for
+	CFBundleOpenBundleResourceMap symbol, since it is only present in full
+	CoreFoundation on Mac OS X and not in CFLite on pure Darwin.
+
+2004-07-19  Zoran Vasiljevic <vasiljevic@users.sf.net>
+
+	* win/tclwinThrd.c: redefined MASTER_LOCK to call TclpMasterLock.
+	Fixes [Bug 987967]
+
+2004-07-17  Vince Darley  <vincentdarley@users.sourceforge.net>
+
+	* generic/tclIOUtil.c: fix to rare 'cd' infinite loop in normalization
+	with vfs [Bug 991420].
+	* tests/fileSystem.test: added test for above bug.
+
+	* doc/FileSystem.3: clarified documentation of posix error codes in
+	'remove directory' FS proc - 'EEXIST' is used to signify a non-empty
+	directory error (bug reported against tclvfs).
+
+2004-07-16  Jeff Hobbs	<jeffh@ActiveState.com>
+
+	* unix/Makefile.in, unix/tcl.m4:     move (C|LD)FLAGS after their
+	* unix/configure.in, unix/configure: _DEFAULT to allow for env setting
+	to override m4 switches. Move SC_MISSING_POSIX_HEADERS up and
+	consolidate calls to limit redundancy in configure.
+	(CFLAGS_WARNING): Remove -Wconversion
+	(SC_ENABLE_THREADS): Set m4 to force threaded build when built against
+	a threaded Tcl core.
+
+2004-07-16  Andreas Kupries  <andreask@activestate.com>
+
+	* generic/tclIOCmd.c (Tcl_FcopyObjCmd): Corrected a typo in the
+	generation of error messages and simplified by reusing data in a
+	variable instead of retrieving the string again. Fixes [Bug 835289].
+
+	* doc/OpenFileChnl.3: Added description of the behaviour of
+	Tcl_ReadChars when its 'charsToRead' argument is set to -1. Fixes [Bug
+	934511].
+
+	* doc/CrtCommand.3: Added note that the arguments given to the command
+	proc of a Tcl_CreateCommand are in utf8 since Tcl 8.1. Closing [Patch
+	414778].
+
+	* doc/ChnlStack.3: Removed the declaration that the interp argument to
+	Tcl_(un)StackChannel can be NULL. This fixes [Bug 881220], reported by
+	Marco Maggi <marcomaggi@users.sourceforge.net>.
+
+	* tests/socket.test: Accepted two new testcases by Stuart Casoff
+	<stwo@users.sourceforge.net> checking that -server and -async don't go
+	together [Bug 796534].
+
+	* unix/tclUnixNotfy.c (NotifierThreadProc): Accepted Joe Mistachkin's
+	patch for [Bug 990500], properly closing the notifier thread when its
+	exits.
+
+2004-07-15  Andreas Kupries  <andreask@activestate.com>
+
+	* unix/tclUnixThrd.c (TclpFinalizeMutex): Accepted Joe Mistachkin's
+	patch for [Bug 990453], closing leakage of mutexes. They were not
+	destroyed properly upon finalization.
+
+2004-07-15  Andreas Kupries  <andreask@activestate.com>
+
+	* generic/tclIO.h (CHANNEL_INCLOSE):	   New flag. Set in
+	* generic/tclIO.c (Tcl_UnregisterChannel): 'Tcl_Close' while the
+	* generic/tclIO.c (Tcl_Close):		   close callbacks are
+	run. Checked in 'Tcl_Close' and 'Tcl_Unregister' to prevent recursive
+	call of 'close' in the close-callbacks. This is a possible error made
+	by implementors of virtual filesystems based on 'tclvfs', thinking
+	that they have to close the channel in the close handler for the
+	filesystem.
+
+2004-07-14  Andreas Kupries  <andreask@activestate.com>
+
+	* generic/tclIO.c:
+	* generic/tclIO.h:
+	* Not reverting, but #ifdef'ing the changes from May 19, 2004 out of
+	the core. This removes the ***POTENTIAL INCOMPATIBILITY*** for channel
+	drivers it introduced. This has become possible due to Expect gaining
+	a BlockModeProc and now handling blockingg and non-blocking modes
+	correctly. Thus [SF Tcl Bug 943274] is still fixed if a recent enough
+	version of Expect is used.
+
+	* doc/CrtChannel.3: Added warning about usage of a channel without a
+	BlockModeProc.
+
+2004-07-15  Andreas Kupries  <andreask@pliers.activestate.com>
+
+	* generic/tclIOCmd.c (Tcl_PutsObjCmd): Added length check to the old
+	depreceated newline syntax, to ensure that only "nonewline" is
+	accepted. [Tcl SF Bug 985869], reported by Joe Mistachkin
+	<mistachkin@users.sourceforge.net>.
+
+2004-07-15  Zoran Vasiljevic <vasiljevic@users.sf.net>
+
+	* generic/tclEvent.c (Tcl_Finalize): stuffed memory leak incurred by
+	re-initializing of TSD slots after the last call to
+	TclFinalizeThreadData (done from within Tcl_FinalizeThread()). We
+	basically just repeat the TclFinalizeThreadData() once more before
+	tearing down TSD keys in TclFinalizeSynchronization(). There should be
+	more elaborate mechanism in place for handling such issues, based on
+	thread cleanup handlers registered on the OS level. Such change
+	requires much more work and would also require TIP because some
+	visible parts of Tcl API would have to be modified. In the meantime,
+	this will do.
+
+	* generic/tclNotify.c (TclFinalizeNotifier): Added conditional
+	notifier finalization based on the fact that an TclInitNotifier has
+	been called for the current thread. This fixes the [Bug 770053] again.
+	Hopefully this time w/o unwanted side-effects.
+
+2004-07-15  Kevin Kenny	 <kennykb@acm.org>
+
+	* generic/tclLiteral.c (TclReleaseLiteral): Removed unused variable
+	'codePtr' to silence a message from VC++.
+
+2004-07-15  Miguel Sofer <msofer@users.sf.net>
+
+	* generic/tclCompile.c (TclCompileScript):
+	* generic/tclLiteral.c (TclReleaseLiteral): fix for [Bug 467523],
+	which resurfaced with the latest changes. The previous strategy was to
+	have special code in TclReleaseLiteral to handle the self-references
+	generated by empty scripts. The new approach avoids the self-reference
+	altogether, by having empty scripts return an unshared literal.
+
+2004-07-15  Zoran Vasiljevic <vasiljevic@users.sf.net>
+
+	* generic/tclEvent.c (NewThreadProc): Backout of changes to fix the
+	[Bug 770053]. See SF bugreport for more info.
+
+2004-07-11  Miguel Sofer <msofer@users.sf.net>
+
+	* generic/tclBasic.c (Tcl_EvalEx): leak fix by dgp, release
+	objv[objectsUsed] on error.
+
+2004-07-11  Miguel Sofer <msofer@users.sf.net>
+
+	* generic/tclParse.c (Tcl_SubstObj): leak fix by dgp, release result
+	on error.
+
+2004-07-11  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* generic/tclNamesp.c (BuildEnsembleConfig): Don't forget to clean out
+	references when deleting the hash table.
+	* generic/tclDictObj.c (Tcl_DictObjRemoveKeyList): Oops, forgot to
+	delete value object when removing the hash entry. [Bug 989093 in part]
+
+2004-07-11  Miguel Sofer <msofer@users.sf.net>
+
+	* generic/tclExecute.c (TEBC): fixed leak of expandNestList objs when
+	there is an error while an expansion is in progress (code added at
+	checkForCatch).
+
+2004-07-11  Vince Darley  <vincentdarley@users.sourceforge.net>
+
+	* generic/tclIOUtil.c: fix to 'cd' bug when vfs is active [tclvfs Bug
+	986944] - this bug recently introduced by some threading fixes. Need
+	to work out how to add tests for this.
+
+2004-07-10  Kevin Kenny	 <kennykb@acm.org>
+
+	* tests/clock.test (clock-2.11): Changed the test so that it isn't an
+	infinite loop when run under valgrind on a slow virtual machine.
+	Thanks to Miguel Sofer for the bug report. Also put in code to restore
+	env(LC_TIME) after tests complete, silencing a warning from 'make
+	TESTFLAGS="-debug 1" test'.
+
+2004-07-08  Miguel Sofer <msofer@users.sf.net>
+
+	* generic/tclBasic.c (DeleteInterpProc): reverted the modification of
+	3 days ago, as the leak of [Bug 983660] is now handled by the change
+	in TclCleanupByteCode.
+	* generic/tclCompile.c (TclCleanupByteCode): let each bytecode remove
+	its references to literals at interp deletion, without updating the
+	dying literal table.
+	* generic/tclLiteral.c (TclDeleteLiteralTable): with the above change
+	to TclCleanupByteCode, this function now removes a single reference to
+	the literal object and cleans up its own structures.
+
+2004-07-08  Kevin Kenny	 <kennykb@acm.org>
+
+	* win/tclWinInit.c (AppendEnvironment): Silenced a compilation warning
+	about a type mismatch.
+
+2004-07-07  Miguel Sofer <msofer@users.sf.net>
+
+	* generic/tclCompile.c (TclCompileScript): fix for [Bug 458361].
+	Single-word scripts are compiled with an unshared cmdName to avoid
+	shimmering between bytecode and cmdName reps.
+
+2004-07-07  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclCmdMZ.c (TclMergeReturnOptions):  Simplified logic and
+	removed potential memory leak. [Bug 986257].
+
+2004-07-07  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* tools/man2help2.tcl (setTabs, IPmacro): Added support for the more
+	advanced *roff macros used in Tk's doc/bind.n
+
+	* generic/tclObj.c (TclInitObjSubsystem): Declare all current object
+	types.
+
+2004-07-06  Don Porter	<dgp@users.sourceforge.net>
+
+	* tests/cmdMZ.test (cmdMZ-return-2.17): Added a test that a word
+	containing backslash-quoted value is treated correctly.
+
+	* generic/tclCompile.c (TclWordKnownAtCompileTime): [Bug 986196]
+	Corrected flaw above and the flaw that caused TCL_TOKEN_SIMPLE_WORDs
+	to have their original word value copied ( "{a b}" ) rather than the
+	actual value ( "a b" ). Thanks to Kevin Kenny for report and tests.
+
+2004-07-06  Kevin B. Kenny  <kennykb@acm.org>
+
+	* tests/cmdMZ.test (cmdMZ-return-2.15,cmdMZ-return-2.16): Added a test
+	that a return code containing spaces is correctly returned.
+
+2004-07-06  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* tools/man2html2.tcl (IPmacro, setTabs): Added support for the more
+	advanced *roff macros used in Tk's doc/bind.n
+
+2004-07-05  Miguel Sofer <msofer@users.sf.net>
+
+	* generic/tclBasic.c (DeleteInterpProc): fix for [Bug 983660], found
+	by pspjuth. Tear down the global namespace before freeing the interp
+	handle, to allow the bytecodes to free their non-shared literals.
+	* generic/tclLiteral.c (TclReleaseLiteral): moved special code for
+	self-ref so that it is also used for non-shared literals. Possible bug
+	found by inspection.
+
+2004-07-03  Miguel Sofer <msofer@users.sf.net>
+
+	* generic/tclExecute.c (ExprRoundFunc):
+	* tests/expr-old.test (39.1): added support for wide integers to
+	round(); [Bug 908375], reported by Hemang Lavana.
+
+2004-07-03  Miguel Sofer <msofer@users.sf.net>
+
+	* generic/tclCompile.h:
+	* generic/tclInt.decls:
+	* generic/tclIntDecls.h:
+	* generic/tclStubInit.c: Moved declaration of TclCompEvalObj() from
+	tclCompile.h to the internal stubs table, for compiler
+	experimentation.
+
+2004-07-02  Jeff Hobbs	<jeffh@ActiveState.com>
+
+	* generic/regcomp.c (stid): correct minor pointer size error
+
+	* generic/tclPipe.c (TclCreatePipeline): applied TIP #202 patch that
+	* doc/exec.n, tests/exec.test:		 adds 2>@1 as a special case
+	redirection of stderr to the result output.
+
+2004-07-02  Kevin B. Kenny  <kennykb@acm.org>
+
+	* tests/io.test: Changed several tests to run the event loop rather
+	than just calling [update] periodically, avoiding intermittent
+	failures (usually in io-29.32) that stemmed from unreaped processes on
+	Windows.
+	* tests/winPipe.test (winpipe-1.11): Fixed a bug that caused test to
+	fail if the path name of the working directory contained whitespace
+	[Bug 678430]
+
+2004-07-01  Vince Darley  <vincentdarley@users.sourceforge.net>
+
+	* tests/fileSystem.test: Added test for [Bug 970529]
+
+2004-07-01  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* win/README.binary, win/README: Updated references to Tcl and Tk 8.4
+	to point to 8.5 instead. Thanks to Theo Verelst for spotting this.
+	* generic/tcl.h: Added note to help prevent those changes from getting
+	missed in the future.
+
+	* doc/Namespace.3, doc/load.n, doc/Limit.3: Typo fixes and remove
+	duplicate documentation. [Bug 983146]
+
+2004-06-30  Don Porter	<dgp@users.sourceforge.net>
+
+	* tests/fileSystem.test: Minor correction to new fileSystem-9.X tests
+	so that they clean up temporary directories correctly.
+
+2004-06-30  Vince Darley  <vincentdarley@users.sourceforge.net>
+
+	* doc/filename.n: clarified behaviour concerning trailing slashes in
+	filenames [Bug 971976]
+
+	* win/tclWinFile.c:
+	* tests/fileSystem.test: fix and tests for [Bug 979879]
+
+2004-06-30  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	TIP#188 IMPLEMENTATION
+
+	* doc/string.n, tests/string.test:	 Add 'wideinteger' to things
+	* generic/tclCmdMZ.c (Tcl_StringObjCmd): that can be tested for with
+	the [string is] subcommand. [Patch 940915, by Kevin Kenny]
+
+2004-06-29  Don Porter	<dgp@users.sourceforge.net>
+
+	* win/tclWinInit.c:	Corrected reference counting flaw in recent
+	changes. Thanks to Pat Thoyts. [Bug 981893].
+
+2004-06-29  Vince Darley  <vincentdarley@users.sourceforge.net>
+
+	* win/tclWin32Dll.c: fix to compilation with VC++ 5.2
+
+2004-06-29  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* library/safe.tcl: Make sure that the temporary variable is local to
+	the namespace and not inadvertently global. [Bug 981733]
+
+2004-06-24  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* tests/unixNotfy.test: Modified constraints so that testing with a
+	threaded tclsh (not tcltest) will not hang.
+
+2004-06-23  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclThreadStorage.c: Corrected type casting errors that led
+	to calculation of a negative index value, thus accesses outside the
+	threadStorageCache array, thus memory corruption. Crash observed on
+	Mac OS X platform.
+
+2004-06-23  Joe Mistachkin  <joe@mistachkin.com>
+
+	* generic/tclThread.c: Implements platform independent thread storage
+	* generic/tclThreadStorage.c: mechanism and fixes associated bugs on
+	platforms where there is limited thread local storage space
+	(Win98/WinNT4). [Patch 976496]
+
+	* generic/tclInt.decls:
+	* generic/tclIntDecls.h: Added thread storage functions to the
+	* generic/tclStubInit.c: internal stubs table.
+
+	* unix/Makefile.in:
+	* unix/configure:
+	* unix/tcl.m4:
+	* win/makefile.vc:
+	* win/rules.vc:
+	* win/Makefile.in: Modified the unix, VC++, and Cygwin build systems
+	* win/configure: to include the new "tclThreadStorage.c" and the new
+	* win/tcl.m4: USE_THREAD_STORAGE define.
+
+2004-06-23  Pat Thoyts	<patthoyts@users.sourceforge.net>
+
+	* tests/io.test: Added -force to 18.1 and 18.2. This was failing on
+	WinXP.
+
+	* tests/winFCmd.test: Added a cleanup to winFCmd-16.11 to avoid a
+	failure in 16.12.
+
+	* tests/eofchar.data: Added -kb option to ensure a binary checkout to
+	win32 systems. This fixes a failure in io-61.1
+
+	* win/makefile.vc: fix for [Bug 977369] about launching tclsh to
+	generate a tclConfig.sh with the nmake build system
+
+2004-06-23  Kevin B. Kenny  <kennykb@acm.org>
+
+	* tests/winDde.test (createChildProcess): Added a 200-ms delay (with
+	the event loop live) when shutting down the test DDE server process.
+	With the delay in place, nuisance failures of tests winDde-4.2, -6.5,
+	and -6.6 appear to be much less frequent. [Bug 957449]
+
+2004-06-23  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* tests/*.test: Standardize use of platform constraints.
+
+	* unix/tclUnixInit.c (GetStackSize, TclpCheckStackSpace):
+	* unix/tclUnixThrd.c (TclpThreadGetStackSize): Added code to check
+	whether the C stack is about to be exceeded, from [Patch 746378] by
+	Joe Mistachkin but with substantial revisions.
+
+2004-06-22  Kevin Kenny	 <kennykb@acm.org>
+
+	* generic/tclEvent.c (NewThreadProc): Fixed broken build on Windows
+	caused by missing TCL_THREAD_CREATE_RETURN.
+
+	* tests/stack.test (stack-3.1): Corrected nuisance error in threaded
+	builds.
+
+2004-06-22  Zoran Vasiljevic <vasiljevic@users.sf.net>
+
+	* generic/tclEvent.c:
+	* generic/tclInt.h:
+	* unix/tclUnixNotfy.c:
+	* unix/tclUnixThrd.c:
+	* win/tclWinThrd.c: [Bug 770053]. See bug report for more information
+	about what it does.
+
+	* tests/unixNotfy.test: rewritten to use tcltest::threadReap to
+	gracefully wait for the test thread to exit. Otherwise we got a race
+	condition with main thread exiting before the test thread. This
+	exposed the long-standing Tcl lib issue with resource
+	garbage-collection on application exit.
+
+2004-06-21  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* win/tclWin32Dll.c (DllMain, _except_dllmain_detach_handler)
+	(TclpCheckStackSpace, _except_checkstackspace_handler)
+	(TclWinCPUID, _except_TclWinCPUID_detach_handler):
+	* win/tclWinChan.c (Tcl_MakeFileChannel)
+	(_except_makefilechannel_handler):
+	* win/tclWinFCmd.c (DoRenameFile, _except_dorenamefile_handler)
+	(DoCopyFile, _except_docopyfile_handler):
+	Rework pushing of exception handler function pointer so that compiling
+	with gcc -O3 works. Remove empty function call to avoid compiler
+	warning. Mark the DllMain function as noinline to avoid compiler error
+	from duplicated asm labels in generated code.
+
+2004-06-21  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* generic/tclThreadAlloc.c (Ptr2Block): Rewrote so as to maximize the
+	chance of detecting and reporting a memory inconsistency without
+	relying on things being consistent. [Bug 975895]
+
+2004-06-18  Don Porter	<dgp@users.sourceforge.net>
+
+	* tests/load.test:	Relaxed strictness of error message matching
+	for test load-2.3 so that it will pass on Mac OSX.
+
+	* generic/tclEncoding.c: Static TclFindEncodings -> FindEncodings.
+	* generic/tclInt.h:	Updated TclpFindExecutable() so that failed
+	* generic/tclUtil.c:	attempts to find the executable are saved
+	* unix/tclUnixFile.c:	just as successful finds are. [Patch 966053]
+	* unix/tclUnixTest.c:
+
+2004-06-18  Kevin B. Kenny  <kennykb@acm.org>
+
+	* tests/winFCmd.test (winFCmd-16.12): Changed test to compute the
+	target directory, so as not to fail if the user's HOME isn't the root.
+
+2004-06-19  Daniel Steffen  <das@users.sourceforge.net>
+
+	* unix/tcl.m4: autoconf 2.5 fixes in Darwin section.
+	* unix/configure: autoconf-2.57
+
+2004-06-18  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* unix/tclUnixInit.c (localeTable): Added some more locale to encoding
+	mapping info from Jim Huang <jserv@kaffe.org>
+
+	* generic/tclInt.h (PendingObjData,TclFreeObjMacro,etc):
+	* generic/tclObj.c (TclFreeObj): Added scheme for making TclFreeObj()
+	avoid blowing up the C stack when freeing up very large object trees.
+	[Bug 886231]
+
+	* win/tclWinInit.c (SetDefaultLibraryDir): Fix logic, simplify and add
+	comments.
+
+2004-06-17  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclObj.c:	Added missing space in panic message.
+
+	* win/tclWinInit.c:	Inform [tclInit] about the default library
+	directory via the ::tclDefaultLibrary variable. This should correct a
+	problem with my 2004-06-11 commit. Better solutions still in the
+	works. Thanks to Joe Mistachkin for pointing out the breakage.
+
+2004-06-16  Don Porter	<dgp@users.sourceforge.net>
+
+	* doc/library.n:	Moved variables ::auto_oldpath and
+	* library/auto.tcl:	::unknown_pending into ::tcl namespace.
+	* library/init.tcl:	[Bugs 808319, 948794]
+
+2004-06-15  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* doc/binary.n: Added some notes to the documentation of the 'a'
+	format to address the point raised in [RFE 768852].
+
+2004-06-15  Jeff Hobbs	<jeffh@ActiveState.com>
+
+	* unix/tclConfig.sh.in (TCL_EXTRA_CFLAGS): set to @CFLAGS@, which is
+	the configure-time CFLAGS. Addendum to m4 change on 2004-05-26.
+
+2004-06-14  Kevin Kenny	 <kennykb@acm.org>
+
+	* win/Makefile.in: Corrected compilation flags for tclPkgConfig.c so
+	that it doesn't require Stubs.
+	* generic/tclBasic.c (Tcl_CreateInterp): Removed comment stating that
+	TclInitEmbeddedConfigurationInformation needs Stubs; with the change
+	above, the comment is now erroneous.
+
+2004-06-11  Don Porter	<dgp@users.sourceforge.net>
+
+	* doc/Encoding.3:	Removed bogus claims about tcl_libPath.
+
+	* generic/tclInterp.c (Tcl_Init):	Stopped setting the
+	tcl_libPath variable. [tclInit] can get all its directories without it.
+
+	* tests/unixInit.test:	Modified test code that made use of
+	tcl_libPath variable.
+
+	* unix/tclUnixInit.c:	Stopped setting the tclDefaultLibrary variable,
+	execept on the Mac OS X platform with HAVE_CFBUNDLE. In that
+	configuration we should seek some way to make use of the TIP 59
+	facilities and get rid of that usage of tclDefaultLibrary as well.
+
+	* generic/tclInterp.c:	Updated [tclInit] to make $env(TCL_LIBRARY) an
+	absolute path, and to include the scriptdir,runtime configuration value
+	on the search path for init.tcl.
+
+	* unix/tclUnixInit.c:	The routines Tcl_Init() and TclSourceRCFile()
+	* win/tclWinInit.c:	had identical implementations for both win and
+	* generic/tclInterp.c:	unix. Moved to a single generic implementation.
+	* generic/tclMain.c:
+	* library/init.tcl:
+	* generic/tclInitScript.h (removed):
+	* unix/Makefile.in:
+	* win/tcl.dsp:
+
+	* unix/configure.in:	Updated TCL_PACKAGE_PATH value to handle
+	* win/configure.in:	--libdir configuration.
+
+	* unix/configure.in:	autoconf-2.57
+	* win/configure.in:
+
+	* generic/tclBasic.c (Tcl_CreateInterp): Moved call to
+	TclInitEmbeddedConfigurationInformation() earlier in
+	Tcl_CreateInterp() so that other parts of interp creation and
+	initialization may access and use the config values.
+
+2004-06-11  Kevin Kenny	 <kennykb@acm.org>
+
+	* win/tclAppInit.c: Restored the 'setargv' procedure when compiling
+	with mingw. Apparently, the command line parsing in mingw doesn't work
+	as well as that in vc++, and the result was (1) that winPipe-8.19
+	failed, and (2) that 'make test' would work at all only with
+	TESTFLAGS='-singleproc 1'. [Bug 967195]
+
+2004-06-10  Zoran Vasiljevic <vasiljevic@users.sf.net>
+
+	* generic/tclIOUtil.c: removed forceful setting of the private cached
+	current working directory rep from within the Tcl_FSChdir(). We
+	delegate this task to the Tcl_FSGetCwd() which does this task anyway.
+	The relevant code is still present but disabled temporarily until the
+	change proves correct. The Tcl test suite passes all test with the
+	given change so I suppose it is good enough.
+
+2004-06-10  Don Porter	<dgp@users.sourceforge.net>
+
+	* unix/tclUnixInit.c (TclpInitLibraryPath):	Disabled addition of
+	* win/tclWinInit.c (TclpInitLibraryPath):	relative-to-executable
+	directories to the library search path. A first step in reform of
+	Tcl's startup process.
+
+	***POTENTIAL INCOMPATIBILITY***
+	Attempts to directly run ./tclsh or ./tcltest out of a build directory
+	will either fail, or will make use of an installed script library in
+	preference to the one in the source tree. Use `make shell` or `make
+	runtest` instead.
+
+	* tests/unixInit.test:	Modified tests to suit above changes.
+
+	* generic/tclPathObj.c:	Corrected [file tail] results when operating
+	on a path produced by TclNewFSPathObj(). [Bug 970529]
+
+2004-06-09  Zoran Vasiljevic <vasiljevic@users.sf.net>
+
+	* generic/tclIOUtil.c: partially corrected [Bug 932314]. Also
+	corrected return values of Tcl_FSChdir() to reflect those of the
+	underlying platform-specific call. Originally, return codes were mixed
+	with those of Tcl.
+
+2004-06-08  Miguel Sofer <msofer@users.sf.net>
+
+	* generic/tclCompile.c:
+	* generic/tclExecute.c: handle warning [Bug 969066]
+
+2004-06-08  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* generic/tclHash.c (RebuildTable): Move declaration of variable so it
+	is only declared when it is used. [Bug 969068]
+
+2004-06-07  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* doc/lsearch.n: Added correct option to example. [Bug 968219]
+
+2004-06-05  Kevin B. Kenny  <kennykb@acm.org>
+
+	* generic/tcl.h: Corrected Tcl_WideInt declarations so that the mingw
+	build works again.
+	* generic/tclDecls.h:			Changes to the tests for clock
+	* generic/tclInt.decls:			frequency in Tcl_WinTime so
+	* generic/tclIntDecls.h:		that any clock frequency is
+	* generic/tclIntPlatDecls.h:		accepted provided that all
+	* generic/tclPlatDecls.h:		CPU's in the system share a
+	* generic/tclStubInit.c:		common chip, and hence,
+	* tests/platform.test (platform-1.3):	presumably, a common clock.
+	* win/tclWin32Dll.c (TclWinCPUID):	This change necessitated a
+	* win/tclWinTest.c (TestwincpuidCmd)	small burst of assembly code
+	* win/tclWinTime.c (Tcl_GetTime):	to read CPU ID information,
+	which was added as TclWinCPUID in the internal Stubs. To test this
+	code in the common case of a single-processor machine, a
+	'testwincpuid' command was added to tclWinTest.c, and a test case in
+	platform.test. Thanks to Jeff Godfrey and Richard Suchenwirth for
+	reporting this bug. [Bug 976722]
+
+2004-06-04  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tcl.h:	Restored #include <stdio.h> to tcl.h,
+	rejecting the "fix" for "Bug" 945570. Tcl_FSSeek() needs the values of
+	SEEK_SET, etc. and too many extensions rely on tcl.h providing stdio.h
+	for them.
+
+2004-06-02  Jeff Hobbs	<jeffh@ActiveState.com>
+
+	* win/tclWinFile.c (TclpFindExecutable): when using GetModuleFileNameA
+	(Win9x), convert from CP_ACP to WCHAR then convert back to utf8.
+	Adjunct to 2004-04-07 fix.
+
+2004-06-02  David Gravereaux <davygrvy@pobox.com>
+
+	* tests/winPipe.test (winpipe-6.1): blocking set to 1 before closing
+	to ensure we get an exitcode. The windows pipe channel driver doesn't
+	differentiate between a blocking and non-blocking close just yet, but
+	will soon. Part of [Bug 947693]
+
+2004-06-02  Vince Darley  <vincentdarley@users.sourceforge.net>
+
+	* doc/file.n: fix to documentation of 'file volumes' (Bug 962435)
+
+2004-06-01  David Gravereaux <davygrvy@pobox.com>
+
+	* win/makefile.vc: check for either MSDEVDIR or MSVCDIR being in the
+	environment, for VC7. [Bug 942214]
+
+	* generic/tclIO.c (Tcl_SetChannelOption): -buffersize wasn't
+	understanding hexidecimal notation nor was reporting number conversion
+	errors. The behavior to silently ignore settings outside the
+	acceptable range of Tcl_SetChannelBufferSize (<10 or >1M) is
+	unchanged. This silent ignoring behavior might be up for review soon.
+
+2004-05-30  David Gravereaux <davygrvy@pobox.com>
+
+	* win/tclWinPipe.c:
+	* win/tclWinPort.h:  Reworked the win implementation of Tcl_WaitPid to
+	support exitcodes in the 'signed short' range. Even though this range
+	is non-portable, it is valid on windows. Detection of exception codes
+	are now more accurate. Previously, an application that exited with
+	ExitProcess((DWORD)-1); was improperly reported as exiting with
+	SIGABRT.
+
+2004-05-30  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* generic/tclInterp.c: Added comments describing the purposes of each
+	function in the limit implementation and rewrote the names of some
+	non-public functions for greater clarity of purpose.
+	* doc/interp.n: Added note about what happens when a limited
+	interpreter creates a slave interpreter.
+	* doc/Limit.3: Added manual page for the resource limit subsystem's C
+	API. [Bug 953903]
+
+2004-05-29  Joe English	 <jenglish@users.sourceforge.net>
+
+	* doc/global.n, doc/interp.n, doc/lrange.n: Fix minor markup errors.
+
+2004-05-28  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* doc/*.n: Added examples to many (too many to list) more man pages.
+
+2004-05-25  Miguel Sofer <msofer@users.sf.net>
+
+	* generic/tclExecute.c:
+	* generic/tclVar.c: using (ptrdiff_t) instead of (int) casting to
+	correct compiler warnings [Bug 961657], reported by Bob Techentin.
+
+2004-05-27  Kevin B. Kenny  <kennykb@acm.org>
+
+	* tests/clock.test: Added a single test for the presence of %G in
+	[clock format], and conditioned out the clock-10.x series if they're
+	all going to fail because of a broken strftime() call. [Bug 961714]
+
+2004-05-27  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* generic/tclHash.c (CompareStringKeys): Added #ifdef to allow people
+	to instruct this function to use strcmp(). [FRQ 951168]
+
+	* generic/tclVar.c: Moved declarations into #if guards so they only
+	happen when required.
+	* unix/tclUnixPort.h: Guard declaration of strtod() so it is only
+	enabled when we don't have a declaration in stdlib.h
+	* unix/tclUnixThrd.c (Tcl_CreateThread):	Added declarations
+	* unix/tclUnixTest.c (AlarmHandler):		and casts so that
+	* unix/tclUnixChan.c (TtyModemStatusStr):	all functions are
+	* generic/tclScan.c (Tcl_ScanObjCmd):		defined before use
+	* generic/tclDictObj.c (InvalidateDictChain):	and no cross-type
+	* generic/tclCmdMZ.c (Tcl_StringObjCmd):	uses are performed.
+
+	The overall effect is to make building with gcc with the additional
+	flags -Wstrict-prototypes -Wmissing-prototypes produce no increase in
+	the total number of warnings (except for main(), which is undeclared
+	for traditional reasons.)
+
+2004-05-26  Jeff Hobbs	<jeffh@ActiveState.com>
+
+	* unix/Makefile.in:  Rework configure ordering to TCL_LINK_LIBS,
+	* unix/tcl.m4:	     ENABLE_SHARED, CONFIG_CFLAGS, & ENABLE_SYMBOLS
+	* unix/configure:    before TCL_EARLY_FLAGS and TCL_64BIT_FLAGS
+	* unix/configure.in: (about 400 lines earlier) in configure.in. This
+	forces CFLAGS configuration to be done before many tests, which is
+	needed for 64-bit builds and may affect other builds. Also make
+	CONFIG_CFLAGS append to CFLAGS directly instead of using EXTRA_CFLAGS,
+	and have LDFLAGS append to any existing value. [Bug 874058]
+	* unix/dltest/Makefile.in: change EXTRA_CFLAGS to DEFS
+
+2004-05-26  Don Porter	<dgp@users.sourceforge.net>
+
+	* library/tcltest/tcltest.tcl:	Correction to debug prints and testing
+	* library/tcltest/pkgIndex.tcl:	if TCLTEST_OPTIONS value. Corrected
+	* tests/tcltest.test:		double increment of numTestFiles in
+	-singleproc 1 configurations. Updated tcltest-19.1 to tcltest 2.1
+	behavior. Corrected tcltest-25.3 to not falsely report a failure in
+	tcltest.test. Bumped to tcltest 2.2.6. [Bugs 960560, 960926]
+
+2004-05-25  Jeff Hobbs	<jeffh@ActiveState.com>
+
+	* doc/http.n (http::config): add -urlencoding option (default utf-8)
+	* library/http/http.tcl:     that specifies encoding conversion of
+	* library/http/pkgIndex.tcl: args for http::formatQuery. Previously
+	* tests/http.test:	     undefined, RFC 2718 says it should be
+	utf-8. 'http::config -urlencoding {}' returns previous behavior, which
+	will throw errors processing non-latin-1 chars. Bumped http package to
+	2.5.0.
+
+2004-05-25  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* generic/tclInterp.c (DeleteScriptLimitCallback): Move all deletion
+	of script callback hash table entries to happen here so the entries
+	are correctly removed at the right time. [Bug 960410]
+
+2004-05-25  Miguel Sofer <msofer@users.sf.net>
+
+	* docs/global.n: added details for qualified variable names [Bug
+	959831]
+
+2004-05-25  Miguel Sofer <msofer@users.sf.net>
+
+	* generic/tclNamesp.c (Tcl_FindNamespaceVar):
+	* tests/namespace.test (namespace-17.10-12): reverted commit of
+	2004-05-23 and removed the tests, as it interferes with the varname
+	resolver and there are apps that break (AlphaTk). A fix will have to
+	wait for Tcl9.
+
+	* generic/tclVar.c: Caching of namespace variables disabled: no simple
+	way was found to avoid interfering with the resolver's idea of
+	variable existence. A cached varName may keep a variable's name in the
+	namespace's hash table, which is the resolver's criterion for
+	existence.
+
+	* tests/namespace.c (namespace-17.10): testing for interference
+	between varname caching and name resolver.
+
+2004-05-25  Kevin Kenny	 <kennykb@acm.org>
+
+	* tests/winFCmd.test: Correct test for the presence of a CD-ROM so
+	that it doesn't misdetect some other sort of filesystem with a
+	write-protected root as being a CD-ROM drive. [Bug 918267]
+
+2004-05-25  Don Porter	<dgp@users.sourceforge.net>
+
+	* tests/winPipe.test:	Protect against path being set
+	* tests/unixInit.test:	Unset path when done.
+	* tests/unload.test (unload-3.1): Verify [pkgb_sub] does not exist.
+	Delete interps when done.
+	* tests/stringComp.test:	stop re-use of string.test test names
+	* tests/regexpComp.test:	stop re-use of regexp.test test names
+	* tests/namespace.test (namespace-46.3): Verify [p] does not exist.
+	* tests/http.test:	Clear away the custom [bgerror] when done.
+	* tests/io.test:	Take care to use namespace variables.
+	* tests/autoMkindex.test (autoMkindex-5.2): Use variable "result"
+	that gets cleaned up.
+	* tests/exec.test:	Clean up the "path" array.
+	* tests/interp.test (interp-9.3): Initialize res, so prior values
+	cannot make the test fail.
+	* tests/execute.test (execute-8.1):  Updated to remove the trace set
+	on ::errorInfo. When left in place, that trace can cause later tests
+	to fail.
+
+2004-05-25  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* generic/tclBasic.c: Removed references to Tcl_RenameCommand from
+	* generic/tcl.h:      comments. [Bug 848440, second part]
+
+	* tests/fCmd.test: Rewrote tests that failed consistently on NFS so
+	they either succeed (through slightly more liberal matching of the
+	results) or are constrained to not run. [Bug 931312]
+
+	* doc/bgerror.n: Use idiomatic open flags for working with log
+	files. [Bug 959602]
+
+2004-05-24  Jeff Hobbs	<jeffh@ActiveState.com>
+
+	* generic/tclExecute.c (VerifyExprObjType): use GET_WIDE_OR_INT to
+	properly have tclIntType used for smaller values. This corrects [TclX
+	Bug 896727] and any other 3rd party extension that created math
+	functions but was not yet WIDE_INT aware in them.
+
+2004-05-24  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* generic/tclInterp.c (TclInitLimitSupport): Made limits work on
+	platforms where sizeof(void*)!=sizeof(int). [Bug 959193]
+
+2004-05-24 Miguel Sofer <msofer@users.sf.net>
+
+	* doc/set.n: accurate description of name resolution process,
+	referring to namespace.n for details [Bug 959180]
+
+2004-05-23  Miguel Sofer <msofer@users.sf.net>
+
+	* generic/tclNamesp.c (Tcl_FindNamespaceVar): [Bug 959052] fixed,
+	insuring that no "zombie" variables are found.
+	* generic/tclVar.c (TclLookupSimpleVar): comments re [Bug 736729]
+	(predecessor of [Bug 959052]) removed.
+	* tests/namespace.test: added tests 17.10-12
+
+	The patch modifies non-documented behaviour, and passes every test in
+	the testsuite. However, scripts relying on the old behaviour may
+	break.
+	Note that the only behaviour change concerns the creative writing of
+	unset variables. More precisely, which variable will be created when
+	neither a namespace variable nor a global variable by that name
+	exists, as defined by [info vars]. The new behaviour is that the
+	namespace resolution process deems a variable to exist exactly when
+	[info vars] finds it - ie, either it has value, or else it was "fixed"
+	by a call to [variable].
+	Note: this patch was removed on 2002-05-25.
+
+2004-05-22  Miguel Sofer <msofer@users.sf.net>
+
+	* generic/tclVar.c (TclObjLookupVar, TclObjUnsetVar2): fix for new (in
+	tcl8.4) exteriorisations of [Bug 736729] due to the use of
+	tclNsVarNameType obj types. Reenabling the use of this objType ("VAR
+	ref absolute" benchmark down to 66 ms, from 230). Added comments in
+	TclLookupSimpleVar explaining my current understanding of [Bug
+	736729].
+
+2004-05-22  Miguel Sofer <msofer@users.sf.net>
+
+	* generic/tclVar.c: fix for [Bug 735335]. The use of tclNsVarNameType
+	objs is still disabled, pending resolution of [Bug 736729].
+
+2004-05-21  Miguel Sofer <msofer@users.sf.net>
+
+	* tests/namespace.test (namespace-41.3): removed the {knownBug}
+	constraint: [Bug 231259] is closed since nov 2001, and the fix of [Bug
+	729692] (INST_START_CMD) makes the test succeed.
+
+2004-05-21  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* generic/tclExecute.c (TclExecuteByteCode): Move a few declarations a
+	short distance so pre-C99 compilers can cope. Also fix so
+	TCL_COMPILE_DEBUG path compiles...
+
+2004-05-21  Miguel Sofer <msofer@users.sf.net>
+
+	* generic/tclExecute.c (TclExecuteByteCode): reorganised TEBC
+	automatic variables, defining them in tight blocks instead of at the
+	function level. This has three purposes:
+	- it simplifies the analysis of individual instructions
+	- it is preliminary work to the non-recursive engine
+	- it allows a better register allocation by the optimiser; under
+	gcc3.3, this results in up to 10% runtime in some tests
+
+2004-05-20  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* generic/tclInterp.c (TclLimitRemoveAllHandlers):
+	* generic/tclBasic.c (DeleteInterpProc):
+	* tests/interp.test (interp-34.7): Ensure that all limit callbacks are
+	deleted when their interpreters are deleted. [Bug 956083]
+
+2004-05-19  Kevin B. Kenny  <kennykb@acm.org>
+
+	* win/tclWinFile.c (TclpMatchInDirectory): fix for an issue where
+	there was a sneak path from Tcl_DStringFree to SetErrorCode(0). The
+	result was that the error code could be reset between a call to
+	FindFirstFileEx and the check of its status return, leading to a
+	bizarre error return of {POSIX unknown {No error}}. (Found in
+	unplanned test - no incident logged at SourceForge.)
+
+2004-05-19  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* tests/interp.test (interp-34.3): Rewrite this test to see if a time
+	limit can catch a tight bytecode loop, a maximally aggressive
+	denial-of-service attack.
+	* generic/tclInterp.c (Tcl_LimitCheck): Fix the sense of checks to see
+	whether a time limit has been extended.
+
+	* tests/*.test: Many minor fixes, including ensuring that every test
+	is run (so constraints control whether the test is doing anything) and
+	making sure that constraints are always set using the API instead of
+	poking around inside tcltest's internal datastructures. Also got rid
+	of all trailing whitespace lines from the test suite!
+
+2004-05-19  Andreas Kupries  <andreask@activestate.com>
+
+	* generic/tclIO.c: Fixed [SF Tcl Bug 943274]. This is the same problem
+	* generic/tclIO.h: as [SF Tcl Bug 462317], see ChangeLog entry
+	2001-09-26. The fix done at that time is incomplete. It is possible to
+	get around it if the actual read operation is defered and not executed
+	in the event handler itself. Instead of tracking if we are in an read
+	caused by a synthesized fileevent we now track if the OS has delivered
+	a true event = actual data and bypass the driver if a read finds that
+	there is no actual data waiting. The flag is cleared by a short or
+	full read.
+
+	***POTENTIAL INCOMPATIBILITY*** for channel drivers.
+
+2004-05-17  Vince Darley  <vincentdarley@users.sourceforge.net>
+
+	* generic/tclPathObj.c: fix to (Bug 956063) in 'file dirname'.
+	* tests/cmdAH.test: added test for this bug.
+
+	* doc/FileSystem.3: better documentation of refCount requirements of
+	some FS functions (Bug 956126)
+
+2004-05-19  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* generic/tclTest.c (TestgetintCmd): Made the tests in get.test check
+	* tests/get.test:		     Tcl_GetInt() since the core now
+					     avoids that function.
+
+2004-05-18  Kevin B. Kenny  <kennykb@acm.org>
+
+	* compat/strftime.c (_fmt, ISO8601Week):
+	* doc/clock.n:
+	* tests/clock.test: Major rework to the handling of ISO8601 week
+	numbers. Now passes all the %G and %V test cases on Windows, Linux and
+	Solaris [Bugs 500285, 500389, and 852944]
+
+2004-05-18  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* doc/append.n, doc/upvar.n: Added example.
+
+2004-05-18  David Gravereaux <davygrvy@pobox.com>
+
+	* win/makefile.vc: now generates a tclConfig.sh from Pat Thoyts [Patch
+	909911]
+
+2004-05-18  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* doc/lsearch.n: Improve clarity (based on [Patch 955361] by Peter
+	Spjuth)
+
+	* tools/man2help2.tcl (macro,SHmacro): Added support for subsection
+	(.SS) header macros.
+
+	* doc/interp.n: Added user documentation for the TIP#143 resource
+	limits and some examples.
+
+	* generic/tclInterp.c (Tcl_LimitCheck, Tcl_LimitTypeReset): Reset the
+	limit-exceeded flag when removing a limit.
+
+2004-05-18  Miguel Sofer <msofer@users.sf.net>
+
+	* generic/tclExecute.c (TclExecuteByteCode): added comments to
+	classify the variables according to their use in TEBC.
+
+2004-05-17  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* doc/global.n, doc/uplevel.n: Added an example.
+
+	* tests/info.test (info-3.1): Corrected test result back to what it
+	used to be in Tcl 7.* now that command counts are being correctly kept
+
+	* generic/tclExecute.c (TEBC:INST_START_CMD): Make sure that the
+	command-count is always advanced. Allows TIP#143 limits to tell that
+	work is being done.
+
+	* doc/list.n: Updated example to fit with the unified format.
+	* doc/seek.n: Added some examples.
+
+2004-05-17  Vince Darley  <vincentdarley@users.sourceforge.net>
+
+	* win/tclWinFile.c:
+	* tests/cmdAH.test: fix to (Bug 954263) where 'file executable' was
+	case-sensitive.
+
+2004-05-17  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* doc/OpenFileChnl.3: Documented type of 'offset' argument to Tcl_Seek
+	was wrong. [Bug 953374]
+
+2004-05-16  Miguel Sofer <msofer@users.sf.net>
+
+	* generic/tclExecute.c (TclExecuteByteCode): remove one level of
+	indirection for compiledLocals addressing.
+
+2004-05-16  Miguel Sofer <msofer@users.sf.net>
+
+	* generic/tclExecute.c (INST_CALL_FUNC1): bugfix; restored
+	(DE)CACHE_STACK_INFO pair around the call - the user defined math
+	function could cause a recursive call to TEBC.
+
+2004-05-16  Miguel Sofer <msofer@users.sf.net>
+
+	* generic/tclBasic.c (Tcl_DeleteInterp):
+	* generic/tclExecute.c (INST_START_CMD): interp deletion now modifies
+	the compileEpoch, eliminating the need for the check for interp
+	deletion in INST_START_CMD.
+
+2004-05-16  Miguel Sofer <msofer@users.sf.net>
+
+	* generic/tclCompile.h:
+	* generic/tclCompile.c:
+	* generic/tclExecute.c: changed implementation of {expand}, last
+	chance while in alpha as ...
+
+	***POTENTIAL INCOMPATIBILITY***
+	Scripts precompiled with ProComp under previous tcl8.5a versions may
+	malfunction due to changed instruction numbers for
+	INST_LIST_INDEX_IMM, INST_LIST_RANGE_IMM and INST_START_CMD.
+
+2004-05-14  Kevin B. Kenny  <kennykb@acm.org>
+
+	* generic/tclInt.decls:	     Promoted TclpLocaltime and TclpGmtime
+	* generic/tclIntDecls.h:     from Unix-specific stubs to the generic
+	* generic/tclIntPlatDecls.h: internal Stubs table. Reran 'genstubs'
+	* generic/tclStubInit.c:
+	* unix/tclUnixPort.h:
+
+	* generic/tclClock.c: Changed a buggy 'GMT' timezone specification
+			      to the correct 'GMT0'. [Bug 922848]
+
+	* unix/tclUnixThrd.c: Moved TclpGmtime and TclpLocaltime to
+			      unix/tclUnixTime.c where they belong.
+
+	* unix/tclUnixTime.c (TclpGmtime, TclpLocaltime, TclpGetTimeZone,
+			      ThreadSafeGMTime [removed],
+			      ThreadSafeLocalTime [removed],
+			      SetTZIfNecessary, CleanupMemory):
+	Restructured to make sure that the same mutex protects all calls to
+	localtime, gmtime, and tzset. Added a check in front of those calls to
+	make sure that the TZ env var hasn't changed since the last call to
+	tzset, and repeat tzset if necessary. [Bug 942078] Removed a buggy
+	test of the Daylight Saving Time information in 'gettimeofday' in
+	favor of applying 'localtime' to a known value. [Bug 922848]
+
+	* tests/clock.test (clock-3.14): Added test to make sure that changes
+	to $env(TZ) take effect immediately.
+
+	* win/tclWinTime.c (TclpLocaltime, TclpGmtime): Added porting layer
+	for 'localtime' and 'gmtime' calls.
+
+2004-05-14  Miguel Sofer <msofer@users.sf.net>
+
+	* generic/tclExecute.c:
+	* generic/tclCompile.h: the math functions receive a pointer to top of
+	the stack (tosPtr) instead of the execution environment (eePtr). First
+	step towards a change in the execution stack management - it is now
+	only used within TEBC.
+
+2004-05-13  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	TIP#143 IMPLEMENTATION
+
+	* generic/tclExecute.c (TclCompEvalObj, TclExecuteByteCode):
+	* generic/tclBasic.c (TclEvalObjvInternal): Enable limit checking.
+	* generic/tclInterp.c (Tcl_Limit*): Public limit API.
+	* generic/tcl.decls:
+	* tests/interp.test: Basic tests of command limits.
+
+	* doc/binary.n:		TIP#129 IMPLEMENTATION [Patch 858211]
+	* generic/tclBinary.c:	Note that the test suite probably has many more
+	* tests/binary.test:	failures now due to alterations in constraints.
+
+2004-05-12  Miguel Sofer <msofer@users.sf.net>
+
+	Optimisations for INST_START_CMD [Bug 926164].
+	* generic/tclCompile.c (TclCompileScript): avoid emitting
+	INST_START_CMD as the first instruction in a bytecoded Tcl_Obj. It is
+	not needed, as the checks are done before calling TEBC.
+	* generic/tclExecute.c (TclExecuteByteCode): runtime peephole
+	optimisation: check at INST_POP if the next instruction is
+	INST_START_CMD, in which case we fall through.
+
+2004-05-11  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* doc/split.n, doc/join.n: Updated examples and added more.
+
+2004-05-11  Vince Darley  <vincentdarley@users.sourceforge.net>
+
+	* doc/glob.n: documented behaviour of symbolic links with 'glob -types
+	d' (Bug 951489)
+
+2004-05-11  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* doc/scan.n: Updated the examples to be clearer about their relevance
+	to the scan command.
+
+2004-05-10  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* doc/scan.n: Added examples.
+
+2004-05-10  David Gravereaux <davygrvy@pobox.com>
+
+	* win/tclWinPipe.c (BuildCommandLine): Moved non-obvious appending
+	logic to outside the loop and added commentary for its purpose. Also
+	use the existence of contents in the linePtr rather than the scratch
+	DString post the append, as this more clear.
+
+	(TclpCreateProcess): When under NT, with no console, and executing a
+	DOS application, the path priming does not need an ending space as
+	BuildCommandLine() will do this for us.
+
+2004-05-08  Vince Darley  <vincentdarley@users.sourceforge.net>
+
+	* generic/tclFileName.c:
+	* generic/tclIOUtil.c: remove some compiler warnings on MacOS X.
+
+2004-05-07  Chengye Mao <chengye.geo@yahoo.com>
+
+	* win/tclWinPipe.c: refixed bug 789040 re-entered in rev 1.41. Let's
+	be careful and don't re-enter previously fixed bugs.
+
+2004-05-08  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* doc/format.n: Added examples.
+
+2004-05-07  Miguel Sofer <msofer@users.sf.net>
+
+	* doc/unset.n: added upvar.n to the "see also" list
+
+2004-05-07  Reinhard Max  <max@suse.de>
+
+	* generic/tclEncoding.c:
+	* tests/encoding.test: added support and tests for translating
+	embedded null characters between real nullbytes and the internal
+	representation on input/output [Bug 949905].
+
+2004-05-07  Vince Darley  <vincentdarley@users.sourceforge.net>
+
+	* generic/tclFileName.c:
+	* generic/tclIOUtil.c:
+	* generic/tclFileSystem.h:
+	* tests/fileSystem.test: fix for [Bug 943995], in which vfs-registered
+	root volumes were not handled correctly as glob patterns in all
+	circumstances.
+
+2004-05-06  Miguel Sofer <msofer@users.sf.net>
+
+	* generic/tclInt.h:
+	* generic/tclObj.c (TclFreeObj): made TclFreeObj use the new macro
+	TclFreeObjMacro(), so that the allocation and freeing of Tcl_Obj is
+	defined in a single spot (the macros in tclInt.h), with the exception
+	of the TCL_MEM_DEBUG case.
+	The #ifdef logic for the corresponding macros has been reformulated to
+	make it clearer.
+
+2004-05-05  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* doc/break.n, doc/continue.n, doc/for.n, doc/while.n: More examples.
+
+2004-05-05  Don Porter	<dgp@users.sourceforge.net>
+
+	* tests/unixInit.test (unixInit-2.10):	Test correction for Mac OSX.
+	Be sure to consistently compare normalized path names. Thanks to
+	Steven Abner (tauvan). [Bug 948177]
+
+2004-05-05  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* doc/CrtObjCmd.3: Remove reference to Tcl_RenameCommand; there is no
+	such API. [Bug 848440]
+
+2004-05-05  David Gravereaux <davygrvy@pobox.com>
+
+	* win/tclWinSock.c (SocketEventProc) : connect errors should fire both
+	the readable and writable handlers because this is how it works on
+	UNIX [Bug 794839]
+
+	* generic/tclEncoding.c (TclFinalizeEncodingSubsystem):
+	FreeEncoding(systemEncoding); moved to before the hash table iteration
+	as it was causing a double free attempt under some conditions.
+
+	* win/coffbase.txt: Added the tls extension to the list of preferred
+	load addresses.
+
+2004-05-04  Jeff Hobbs	<jeffh@ActiveState.com>
+
+	* tests/fileSystem.test (filesystem-1.39): replace 'file volumes'
+	* tests/fileName.test (filename-12.9,10):  lindex with direct C:/
+	hard-coded because A:/ was being used and that is empty for most.
+
+	* tests/winFCmd.test (winFCmd-16.12): test volumerelative $HOME
+
+2004-05-04  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclAlloc.c:		Make sure Tclp*Alloc* routines get
+	* generic/tclInt.h:		declared in the TCL_MEM_DEBUG and
+	* generic/tclThreadAlloc.c:	TCL_THREADS configuration. [Bug 947564]
+
+	* tests/tcltest.test:	Test corrections for Mac OSX. Thanks to Steven
+	Abner (tauvan). [Bug 947440]
+
+2004-05-04  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* generic/tclEvent.c (TclSetLibraryPath): Suppress a warning.
+
+2004-05-03  Andreas Kupries  <andreask@activestate.com>
+
+	* Applied [Patch 868853], fixing a mem leak in TtySetOptionProc.
+	Report and Patch provided by Stuart Cassoff <stwo@users.sf.net>.
+
+2004-05-03  Miguel Sofer <msofer@users.sf.net>
+
+	* generic/tclProc.c (TclCreateProc): comments corrected.
+
+2004-05-03  Miguel Sofer <msofer@users.sf.net>
+
+	* generic/tclCompile.c (TclCompileScript): setting the compilation
+	namespace outside of the loop.
+
+2004-05-03  Miguel Sofer <msofer@users.sf.net>
+
+	* generic/tclCompile.c:
+	* generic/tclInt.h: reverted fix for [Bug 926445] of 2004-04-02,
+	restoring TCL_ALIGN to the header file. Todd Helfter reported that the
+	macro is required by tbcload.
+
+2004-05-03  Kevin Kenny	 <kennykb@acm.org>
+
+	* win/tclWin32Dll.c (TclpCheckStackSpace):
+	* tests/stack.test (stack-3.1): Fix for undetected stack overflow in
+	TclReExec on Windows. [Bug 947070]
+
+2004-05-03  Don Porter	<dgp@users.sourceforge.net>
+
+	* library/init.tcl:	Corrected unique prefix matching of
+	interactive command completion in [unknown]. [Bug 946952]
+
+2004-05-02  Miguel Sofer <msofer@users.sf.net>
+
+	* generic/tclProc.c (TclObjInvokeProc):
+	* tests/proc.test (proc-3.6): fix for bad quoting of multi-word proc
+	names in error messages [Bug 942757]
+
+2004-04-30  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* doc/glob.n, doc/incr.n, doc/set.n:	More examples.
+	* doc/if.n, doc/rename.n, doc/time.n:
+
+2004-04-30  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclInt.h:		Replaced Kevin Kenny's temporary
+	* generic/tclThreadAlloc.c:	fix for Bug 945447 with a cleaner,
+	more permanent replacement.
+
+2004-04-30  Kevin B. Kenny   <kennykb@acm.org>
+
+	* generic/tclThreadAlloc.c: Added a temporary (or so I hope!)
+	inclusion of "tclWinInt.h" to avoid problems when compiling on
+	Win32-VC++ with --enable-threads. [Bug 945447]
+
+2004-04-30  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* doc/puts.n: Added a few examples.
+
+2004-04-29  Don Porter	<dgp@users.sourceforge.net>
+
+	* tests/execute.test (execute-8.2):	Avoid crashes when there is
+	limited system stack space (threads-enabled).
+
+2004-04-28  Miguel Sofer <msofer@users.sf.net>
+
+	* doc/global.n:
+	* doc/upvar.n:
+	* generic/tclVar.c (ObjMakeUpvar):
+	* tests/upvar.test (upvar-8.11):
+	* tests/var.test (var-3.11): Avoid creation of unusable variables:
+	[Bug 600812] [TIP 184].
+
+2004-04-28  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* doc/lsearch.n: Fixed fault in documentation of -index option [943448]
+
+2004-04-26  Don Porter	<dgp@users.sourceforge.net>
+
+	* unix/tclUnixFCmd.c (TclpObjNormalizePath):  Corrected improper
+	positioning of returned checkpoint. [Bug 941108]
+
+2004-04-26  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* doc/open.n, doc/close.n: Updated (thanks to David Welton) to be
+	clearer about pipeline errors and added example to open(n) that shows
+	simple pipeline use. [Patches 941377,941380]
+
+	* doc/DictObj.3: Added warning about the use of Tcl_DictObjDone and an
+	example of use of iteration. [Bug 940843]
+
+	* doc/Thread.3: Reworked to remove references to testing interfaces
+	and instead promote the use of the Thread package. [Patch 932527]
+	Also reworked and reordered the page for better readability.
+
+2004-04-25  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tcl.h:	Removed obsolete declarations and #include's.
+	* generic/tclInt.h:	[Bugs 926459, 926486]
+
+2004-04-24  David Gravereaux <davygrvy@pobox.com>
+
+	* win/tclWin32Dll.c (DllMain): Added DisableThreadLibraryCalls() for
+	the DLL_PROCESS_ATTACH case. We're not interested in knowing about
+	DLL_THREAD_ATTACH, so disable the notices.
+
+2004-04-24  Daniel Steffen  <das@users.sourceforge.net>
+
+	* generic/tclPort.h:
+	* macosx/Makefile:
+	* unix/Makefile.in: followup on tcl header reform [FR 922727]: removed
+	use of relative #include paths in tclPort.h to allow installation of
+	private headers outside of tcl source tree; added 'unix' dir to
+	compiler header search path; add newly required tcl private headers to
+	Tcl.framework on Mac OSX.
+
+2004-04-23  Andreas Kupries  <andreask@activestate.com>
+
+	* generic/tclIO.c (Tcl_SetChannelOption): Fixed [SF Tcl Bug 930851].
+	When changing the eofchar we have to zap the related flags to prevent
+	them from prematurely aborting the next read.
+
+2004-04-25  Vince Darley  <vincentdarley@users.sourceforge.net>
+
+	* generic/tclPathObj.c: fix to [Bug 940281]. Tcl_FSJoinPath will now
+	always return a valid Tcl_Obj when the input is valid.
+	* generic/tclIOUtil.c: fix to [Bug 931823] for a more consistent
+	Tcl_FSPathSeparator() implementation which allows filesystems not to
+	implement their Tcl_FSFilesystemSeparatorProc if they wish to use the
+	default '/'. Also fixed associated memory leak seen with, e.g., tclvfs
+	package.
+	* doc/FileSystem.3: documented Tcl_FSJoinPath return values more
+	clearly, and Tcl_FSFilesystemSeparatorProc requirements.
+
+2004-04-23  David Gravereaux <davygrvy@pobox.com>
+
+	* win/tclWin32Dll.c: Removed my mistake from 4/19 of adding an exit
+	handler to TclWinInit. TclWinEncodingsCleanup called from
+	TclFinalizeFilesystem does the Tcl_FreeEncoding for us.
+
+	* win/tclWinChan.c (Tcl_MakeFileChannel): Case for CloseHandle
+	returning zero and not throwing a
+	RaiseException(EXCEPTION_INVALID_HANDLE) now being done.
+
+2004-04-22  David Gravereaux <davygrvy@pobox.com>
+
+	* generic/tclEvent.c: TclSetLibraryPath's use of caching the stringrep
+	of the pathPtr object to TclGetLibraryPath called from another thread
+	was ineffective if the original's stringrep had been invalidated as
+	what happens when it gets muted to a list.
+
+	* win/tclWinTime.c: If the Tcl_ExitProc (StopCalibration) is called
+	from the stack frame of DllMain's PROCESS_DETACH, the wait operation
+	should timeout and continue.
+
+	* generic/tclInt.h:
+	* generic/tclThread.c:
+	* generic/tclEvent.c:
+	* unix/tclUnixThrd.c:
+	* win/tclWinThrd.c: Provisions made so masterLock, initLock, allocLock
+	and joinLock mutexes can be recovered during Tcl_Finalize.
+
+2004-04-22  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* doc/switch.n: Reworked the examples to be more systematically named
+	and to cover some TIP#75 capabilities.
+
+	* doc/cd.n: Documentation clarification from David Welton.
+
+	* doc/exec.n: Added some examples, Windows ones from Arjen Markus and
+	Unix ones by myself.
+
+2004-04-21  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* doc/Hash.3: Added note to Tcl_{First,Next}HashEntry docs that
+	deleting the element they return is supported (and is in fact the only
+	safe update you can do to the structure of a hashtable while an
+	iteration is going over it.)
+
+	* doc/bgerror.n: Added example from David Welton. [Patch 939473]
+
+	* doc/after.n: Added examples from David Welton. [Patch 938820]
+
+2004-04-19  David Gravereaux <davygrvy@pobox.com>
+
+	* win/tclWin32Dll.c: Added an exit handler in TclWinInit() so
+	tclWinTCharEncoding could be freed during Tcl_Finalize().
+
+	* generic/tclEncoding.c: Added FreeEncoding(systemEncoding) in
+	TclFinalizeEncodingSubsystem because its ref count was incremented in
+	TclInitEncodingSubsystem.
+
+2004-04-19  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* doc/read.n: Added example from David Welton. [Patch 938056]
+
+2004-04-19  Kevin B. Kenny   <kennykb@acm.org>
+
+	* generic/tclObj.c (Tcl_GetDoubleFromObj) Corrected "short circuit"
+	conversion of int to double. Reported by Jeff Hobbs on the Tcl'ers
+	Chat.
+
+2004-04-16  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* doc/lreplace.n, doc/lrange.n, doc/llength.n:	More examples for
+	* doc/linsert.n, doc/lappend.n:			the documentation.
+
+2004-04-16  Vince Darley  <vincentdarley@users.sourceforge.net>
+
+	* doc/FileSystem.3: Corrected documentation of Tcl_FSUtime, and the
+	corresponding filesystem driver Tcl_FSUtimeProc. [Bug 935838]
+
+2004-04-16  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* doc/socket.n: Added example from [Patch 936245].
+	* doc/gets.n: Added example based on [Patch 935911].
+
+2004-04-15  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* generic/tclClock.c (Tcl_ClockObjCmd): Minor fault in a [clock
+	clicks] error message.
+
+2004-04-07  Jeff Hobbs	<jeffh@ActiveState.com>
+
+	* win/tclWinInit.c (TclpSetInitialEncodings): note that WIN32_CE is
+	also a unicode platform.
+	* generic/tclEncoding.c (TclFindEncodings, Tcl_FindExecutable):
+	* generic/tclInt.h:			    Correct handling of UTF
+	* unix/tclUnixInit.c (TclpInitLibraryPath): data that is actually
+	* win/tclWinFile.c (TclpFindExecutable):    "clean", allowing the
+	* win/tclWinInit.c (TclpInitLibraryPath):   loading of Tcl from paths
+	that contain multi-byte chars on Windows [Bug 920667]
+
+	* win/configure:    define TCL_LIB_FLAG, TCL_BUILD_LIB_SPEC,
+	* win/configure.in: TCL_LIB_SPEC, TCL_PACKAGE_PATH in tclConfig.sh.
+
+2004-04-06  Don Porter	<dgp@users.sourceforge.net>
+
+	Patch 922727 committed.	 Implements three changes:
+
+	* generic/tclInt.h:	Reworked the Tcl header files into a clean
+	* unix/tclUnixPort.h:	hierarchy where tcl.h < tclPort.h < tclInt.h
+	* win/tclWinInt.h:	and every C source file should #include
+	* win/tclWinPort.h:	at most one of those files to satisfy its
+	declaration needs. tclWinInt.h and tclWinPort.h also better organized
+	so that tclWinPort.h includes the Windows implementation of
+	cross-platform declarations, while tclWinInt.h makes declarations that
+	are available on Windows only.
+
+	* generic/tclBinary.c (TCL_NO_MATH):	Deleted the generic/tclMath.h
+	* generic/tclMath.h (removed):		header file. The internal Tcl
+	* macosx/Makefile (PRIVATE_HEADERS):	header, tclInt.h, has a
+	* win/tcl.dsp:				#include <math.h> directly,
+	and file external to Tcl needing libm should do the same.
+
+	* win/Makefile.in (WIN_OBJS):	Deleted the win/tclWinMtherr.c file.
+	* win/makefile.bc (TCLOBJS):	It's a vestige from matherr() days
+	* win/makefile.vc (TCLOBJS):	gone by.
+	* win/tcl.dsp:
+	* win/tclWinMtherr.c (removed):
+
+	End Patch 922727.
+
+	* tests/unixInit.test (unixInit-3.1):	Default encoding on Darwin
+	systems is utf-8. Thanks to Steven Abner (tauvan). [Bug 928808]
+
+2004-04-06  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* tests/cmdAH.test (cmdAH-18.2): Added constraint because
+	access(...,X_OK) is defined to be permitted to be meaningless when
+	running as root, and OSX exhibits this. [Bug 929892]
+
+2004-04-02  Miguel Sofer <msofer@users.sf.net>
+
+	* generic/tclCompile.c:
+	* generic/tclInt.h: removed the macro TCL_ALIGN() from tclInt.h,
+	replaced by the static macro ALIGN() in tclCompile.c [Bug 926445]
+
+2004-04-02  Miguel Sofer <msofer@users.sf.net>
+
+	* generic/tclCompile.h: removed redundant #ifdef _TCLINT [Bug 928415],
+	reported by tauvan.
+
+2004-04-02  Don Porter	<dgp@users.sourceforge.net>
+
+	* tests/tcltest.test: Corrected constraint typos: "nonRoot" ->
+	"notRoot". Thanks to Steven Abner (tauvan). [Bug 928353]
+
+2004-04-01  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclInt.h:  Removed obsolete tclBlockTime* declarations. [Bug
+	926454]
+
+2004-04-01  Vince Darley  <vincentdarley@users.sourceforge.net>
+
+	* generic/tclIOUtil.c: Fix to privately reported vfs bug with 'glob
+	-type d -dir . *' across a vfs boundary. No tests for this are
+	currently possible without effectively moving tclvfs into Tcl's test
+	suite.
+
+2004-03-31  Don Porter	<dgp@users.sourceforge.net>
+
+	* doc/msgcat.n:	Clarified message catalog file encodings. [Bug 811457]
+	* library/msgcat/msgcat.tcl: Updated internals to make use of [dict]s
+	to store message catalog data and to use [source -encoding utf-8] to
+	access catalog files. Thanks to Michael Sclenker. [Patch 875055, RFE
+	811459] Corrected [mcset] to be able to successfully set a translation
+	to the empty string. [mcset $loc $src {}] was incorrectly set the $loc
+	translation of $src back to $src. Also changed [ConvertLocale] to
+	minimally require a non-empty "language" part in the locale value. If
+	not, an error raised prompts [Init] to keep looking for a valid locale
+	value, or ultimately fall back on the "C" locale. [Bug 811461].
+	* library/msgcat/pkgIndex.tcl:	Bump to msgcat 1.4.1.
+
+2004-03-30  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* generic/tclHash.c (HashStringKey): Cleaned up. This function is not
+	faster, but it is a little bit clearer.
+	* generic/tclLiteral.c (HashString): Applied logic from HashObjKey.
+	* generic/tclObj.c (HashObjKey): Rewrote to fix fault which hashed
+	every single-character object to the same hash bucket. The new code is
+	shorter, simpler, clearer, and (happily) faster.
+
+2004-03-30  Miguel Sofer <msofer@users.sf.net>
+
+	* generic/tclExecute.c (TEBC): reverting to the previous method for
+	async tests in TEBC, as the new method turned out to be too costly.
+	Async tests now run every 64 instructions.
+
+2004-03-30  Miguel Sofer <msofer@users.sf.net>
+
+	* generic/tclCompile.c:	    New instruction code INST_START_CMD that
+	* generic/tclCompile.h:	    allows checking the bytecode's validity
+	* generic/tclExecute.c:	    [Bug 729692] and the interp's readyness
+	* tests/interp.test (18.9): [Bug 495830] before running the command.
+	* tests/proc.test (7.1):    It also changes the mechanics of the async
+	* tests/rename.test (6.1):  tests in TEBC, doing it now at command
+	start instead of every 16 instructions.
+
+2004-03-30  Vince Darley  <vincentdarley@users.sourceforge.net>
+
+	* generic/tclFileName.c:  Fix to Windows glob where the pattern is a
+	* generic/tclIOUtil.c:	  volume relative path or a network share [Bug
+	* tests/fileName.test:	  898238]. On windows 'glob' will now return
+	* tests/fileSystem.test:  the results of 'glob /foo/bar' and 'glob
+	\\foo\\bar' as 'C:/foo/bar', i.e. a correct absolute path (rather than
+	a volume relative path).
+
+	Note that the test suite does not test commands like
+	'glob //Machine/Shared/*' (on a network share).
+
+2004-03-30  Vince Darley  <vincentdarley@users.sourceforge.net>
+
+	* generic/tclPathObj.c:	  Fix to filename bugs recently
+	* tests/fileName.test:	  introduced [Bug 918320].
+
+2004-03-29  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclMain.c (Tcl_Main, StdinProc):	Append newline only
+	* tests/basic.test (basic-46.1):		to incomplete scripts
+	as part of multi-line script construction. Do not add an extra
+	trailing newline to the complete script. [Bug 833150]
+
+2004-03-28  Miguel Sofer <msofer@users.sf.net>
+
+	* generic/tclCompile.c (TclCompileScript): corrected possible segfault
+	when a compilation returns TCL_OUTLINE_COMPILE after having grown the
+	compile environment [Bug 925121].
+
+2004-03-27  Miguel Sofer <msofer@users.sf.net>
+
+	* doc/array.n: added documentation for trace-realted behaviour of
+	'array get' [Bug 449893]
+
+2004-03-26  Don Porter	<dgp@users.sourceforge.net>
+
+	* README:		Bumped version number to 8.5a2 to distinguish
+	* tools/tcl.wse.in:	HEAD of CVS development from the recent 8.5a1
+	* unix/configure.in:	release.
+	* unix/tcl.spec:
+	* win/README.binary:
+	* win/configure.in:
+
+	* unix/configure:	autoconf-2.57
+	* win/configure:
+
+2004-03-26  Vince Darley  <vincentdarley@users.sourceforge.net>
+
+	* generic/tclPathObj.c:	  Fix to Windows-only volume relative path
+	* tests/fileSystem.test:  normalization. [Bug 923568]. Also fixed
+	another volume relative bug found while testing.
+
+2004-03-24  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* generic/tclNamesp.c (NsEnsembleImplementationCmd): Fix messed up
+	handling of strncmp result which just happened to work in some libc
+	implementations. [Bug 922752]
+
+2004-03-23  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* doc/StringObj.3: Inverted the sense of the documentation of how the
+	bytes parameter is documented to match behaviour. [Bug 921464]
+
+2004-03-19  Kevin B. Kenny   <kennykb@acm.org>
+
+	* compat/strtoll.c:
+	* compat/strtoull.c:
+	* generic/tclIntDecls.h:
+	* generic/tclMain.c:
+	* generic/tclObj.c:
+	* win/tclWinDde.c:
+	* win/tclWinReg.c:
+	* win/tclWinTime.c:	   Made HEAD build on Windows VC++ again.
+
+2004-03-19  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* generic/tclIntDecls.h: Made HEAD build on Solaris again by applying
+	fix recommended by Don Porter.
+
+2004-03-18  Reinhard Max  <max@suse.de>
+
+	* generic/tclIntDecls.h: Removed TclpTime_t. It wasn't really needed,
+	* generic/tclInt.h:	 but caused warnings related to
+	* generic/tclInt.decls:	 strict aliasing with GCC 3.3.
+	* generic/tclClock.c:
+	* generic/tclDate.c:
+	* generic/tclGetDate.y:
+	* win/tclWinTime.c:
+	* unix/tclUnixTime.c:
+
+	* generic/tclNamesp.c:	 Added temporary pointer variables to work
+	* generic/tclStubLib.c:	 around warnings related to
+	* unix/tclUnixChan.c:	 strict aliasing with GCC 3.3.
+
+	* unix/tcl.m4:		 Removed -Wno-strict-aliasing.
+
+2004-03-18  Daniel Steffen  <das@users.sourceforge.net>
+
+	Removed support for Mac OS Classic platform [Patch 918142]
+
+	* README:
+	* compat/string.h:
+	* doc/Encoding.3:
+	* doc/FileSystem.3:
+	* doc/Init.3:
+	* doc/Macintosh.3 (removed):
+	* doc/OpenFileChnl.3:
+	* doc/OpenTcp.3:
+	* doc/SourceRCFile.3:
+	* doc/Thread.3:
+	* doc/clock.n:
+	* doc/exec.n:
+	* doc/fconfigure.n:
+	* doc/file.n:
+	* doc/filename.n:
+	* doc/glob.n:
+	* doc/open.n:
+	* doc/puts.n:
+	* doc/resource.n (removed):
+	* doc/safe.n:
+	* doc/source.n:
+	* doc/tclvars.n:
+	* doc/unload.n:
+	* generic/README:
+	* generic/tcl.decls:
+	* generic/tcl.h:
+	* generic/tclAlloc.c:
+	* generic/tclBasic.c:
+	* generic/tclCmdAH.c:
+	* generic/tclDate.c:
+	* generic/tclDecls.h:
+	* generic/tclFCmd.c:
+	* generic/tclFileName.c:
+	* generic/tclGetDate.y:
+	* generic/tclIOCmd.c:
+	* generic/tclIOUtil.c:
+	* generic/tclInitScript.h:
+	* generic/tclInt.decls:
+	* generic/tclInt.h:
+	* generic/tclIntDecls.h:
+	* generic/tclIntPlatDecls.h:
+	* generic/tclMain.c:
+	* generic/tclMath.h:
+	* generic/tclNotify.c:
+	* generic/tclPathObj.c:
+	* generic/tclPlatDecls.h:
+	* generic/tclPort.h:
+	* generic/tclStubInit.c:
+	* generic/tclTest.c:
+	* generic/tclThreadJoin.c:
+	* library/auto.tcl:
+	* library/init.tcl:
+	* library/package.tcl:
+	* library/safe.tcl:
+	* library/tclIndex:
+	* mac/AppleScript.html (removed):
+	* mac/Background.doc (removed):
+	* mac/MW_TclAppleScriptHeader.h (removed):
+	* mac/MW_TclAppleScriptHeader.pch (removed):
+	* mac/MW_TclBuildLibHeader.h (removed):
+	* mac/MW_TclBuildLibHeader.pch (removed):
+	* mac/MW_TclHeader.h (removed):
+	* mac/MW_TclHeader.pch (removed):
+	* mac/MW_TclHeaderCommon.h (removed):
+	* mac/MW_TclStaticHeader.h (removed):
+	* mac/MW_TclStaticHeader.pch (removed):
+	* mac/MW_TclTestHeader.h (removed):
+	* mac/MW_TclTestHeader.pch (removed):
+	* mac/README (removed):
+	* mac/bugs.doc (removed):
+	* mac/libmoto.doc (removed):
+	* mac/morefiles.doc (removed):
+	* mac/porting.notes (removed):
+	* mac/tclMac.h (removed):
+	* mac/tclMacAETE.r (removed):
+	* mac/tclMacAlloc.c (removed):
+	* mac/tclMacAppInit.c (removed):
+	* mac/tclMacApplication.r (removed):
+	* mac/tclMacBOAAppInit.c (removed):
+	* mac/tclMacBOAMain.c (removed):
+	* mac/tclMacChan.c (removed):
+	* mac/tclMacCommonPch.h (removed):
+	* mac/tclMacDNR.c (removed):
+	* mac/tclMacEnv.c (removed):
+	* mac/tclMacExit.c (removed):
+	* mac/tclMacFCmd.c (removed):
+	* mac/tclMacFile.c (removed):
+	* mac/tclMacInit.c (removed):
+	* mac/tclMacInt.h (removed):
+	* mac/tclMacInterupt.c (removed):
+	* mac/tclMacLibrary.c (removed):
+	* mac/tclMacLibrary.r (removed):
+	* mac/tclMacLoad.c (removed):
+	* mac/tclMacMath.h (removed):
+	* mac/tclMacNotify.c (removed):
+	* mac/tclMacOSA.c (removed):
+	* mac/tclMacOSA.r (removed):
+	* mac/tclMacPanic.c (removed):
+	* mac/tclMacPkgConfig.c (removed):
+	* mac/tclMacPort.h (removed):
+	* mac/tclMacProjects.sea.hqx (removed):
+	* mac/tclMacResource.c (removed):
+	* mac/tclMacResource.r (removed):
+	* mac/tclMacSock.c (removed):
+	* mac/tclMacTclCode.r (removed):
+	* mac/tclMacTest.c (removed):
+	* mac/tclMacThrd.c (removed):
+	* mac/tclMacThrd.h (removed):
+	* mac/tclMacTime.c (removed):
+	* mac/tclMacUnix.c (removed):
+	* mac/tclMacUtil.c (removed):
+	* mac/tcltkMacBuildSupport.sea.hqx (removed):
+	* tests/all.tcl:
+	* tests/binary.test:
+	* tests/cmdAH.test:
+	* tests/cmdMZ.test:
+	* tests/fCmd.test:
+	* tests/fileName.test:
+	* tests/fileSystem.test:
+	* tests/interp.test:
+	* tests/io.test:
+	* tests/ioCmd.test:
+	* tests/load.test:
+	* tests/macFCmd.test (removed):
+	* tests/osa.test (removed):
+	* tests/resource.test (removed):
+	* tests/socket.test:
+	* tests/source.test:
+	* tests/unload.test:
+	* tools/cvtEOL.tcl (removed):
+	* tools/genStubs.tcl:
+	* unix/Makefile.in:
+	* unix/README:
+	* unix/mkLinks:
+	* unix/tcl.spec:
+	* win/README.binary:
+	* win/tcl.dsp:
+
+2004-03-17  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* doc/lsearch.n: Improved examples on the advanced capabilities of
+	lsearch (with the right options, set element removal can be done)
+	following discussion on tkchat.
+
+2004-03-16  Don Porter	<dgp@users.sourceforge.net>
+
+	* doc/catch.n:	Compiled [catch] no longer fails to catch syntax
+	errors. Removed the claims in the documentation that it does.
+	* doc/return.n:	Updated example to use [dict merge].
+
+2004-03-16  Jeff Hobbs	<jeffh@ActiveState.com>
+
+	* unix/configure, unix/tcl.m4: add -Wno-strict-aliasing for GCC to
+	suppress useless type puning warnings.
+
+2004-03-16  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* doc/file.n: *roff formatting fix. [Bug 917171]
+
+2004-03-15  David Gravereaux <davygrvy@pobox.com>
+
+	* win/tclWinNotify.c: Fixed a mistake where the return value of
+	MsgWaitForMultipleObjectsEx for "a message is in the queue" wasn't
+	accurate. I removed the check on the case result==(WAIT_OBJECT_0 + 1)
+	This was having the error of falling into GetMessage and waiting there
+	by accident, which wasn't alertable through Tcl_AlertNotifier. I'll do
+	some more study on this and try to find-out why.
+
+2004-03-12  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	IMPLEMENTATION OF TIP#163
+	* generic/tclDictObj.c (DictMergeCmd):	This is based on work by Joe
+	* tests/dict.test (dict-20.*):		English in Tcl [FRQ 745851]
+	* doc/dict.n:				but not exactly.
+
+2004-03-10  Kevin B. Kenny <kennykb@acm.org>
+
+	* generic/tclGetDate.y (TclGetDate): Fix so that [clock scan
+	<timeOfDay> -gmt true] uses the GMT base date instead of the local
+	one. [Bug 913513]
+	* tests/clock.test: Added test cases for wrong ISO8601 week number
+	[Bug 500285] and wrong GMT base date [Bug 913513]. Several tests still
+	fail on Windows, and these are actual faults in [clock scan]. Fix is
+	still pending.
+	* generic/tclDate.c: Regenerated.
+
+2004-03-08  Vince Darley  <vincentdarley@users.sourceforge.net>
+
+	* generic/tclFileName.c:  Fix to 'glob -path' near the root
+	* tests/fileName.test:	  of the filesystem. [Bug 910525]
+
+2004-03-08  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclParse.c (TclParseInit):	Modified TclParseInit so
+	* generic/tclTest.c ([testexprparser]): that Tcl_Parse initialization
+	conforms to documented promised about what fields will not be
+	modified by what Tcl_Parse* routines. [Bug 910595]
+
+2004-03-05  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* win/configure: Regen.
+	* win/configure.in: Check for define of MWMO_ALERTABLE in winuser.h.
+	* win/tclWinPort.h: If MWMO_ALERTABLE is not defined in winuser.h then
+	define it. This is needed for Mingw.
+
+2004-03-05  Kevin B. Kenny <kennykb@acm.org>
+
+	* generic/tclTest.c: Modified TesteventObjCmd to use a
+	Tcl_QueuePosition in place of an 'int' for the enumerated queue
+	position, to avoid a compiler warning on SGI. [Bug 771960]
+
+2004-03-05  Kevin B. Kenny <kennykb@acm.org>
+
+	* tests/registry.test: Applied fix from [Patch 910174] to make the test
+	for an English-language system include any country code, rather than
+	just English-United States.1252. Thanks to Pat Thoyts for the changes.
+
+2004-03-04  Pat Thoyts	<patthoyts@users.sourceforge.net>
+
+	* tests/registry.test: Applied fixed from [Bug 766159] to skip two
+	tests on Win98 that depend on a Unicode registry (NT specific).
+
+2004-03-04  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclInt.h (TclParseInit):	Factored the common code
+	* generic/tclParse.c (TclParseInit):	for initializing a Tcl_Parse
+	* generic/tclParseExpr.c:		struct into one routine.
+
+2004-03-04  Pat Thoyts	<patthoyts@users.sourceforge.net>
+
+	* library/reg/pkgIndex.tcl:  Added TIP #100 support to the
+	* win/tclWinReg.c:	     registry package [patch 903831]
+	This provides a Windows test of the TIP #100 mechanism and a sample to
+	show how unloading an extension can be done.
+
+2004-03-04  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* unix/dltest/pkgua.c: Fix minor syntax problems. [Bug 909288]
+
+2004-03-03  Jeff Hobbs	<jeffh@ActiveState.com>
+
+	*** 8.5a1 TAGGED FOR RELEASE ***
+
+	* changes: updated for 8.5a1
+
+2004-03-03  David Gravereaux <davygrvy@pobox.com>
+
+	* win/makefile.vc: default environment variable for VC++ is %MSDevDir%
+	not %MSVCDir%, although vcvars32.bat sets both.
+
+	* win/tclWinNotify.c (Tcl_WaitForEvent) : Allows an idling notifier to
+	service "Asynchronous Procedure Calls" from its wait state. Only
+	useful for extension authors who decide they might want to try
+	"completion routines" with WriteFileEx(), as an example. From
+	experience, I recommend that "completion ports" should be used instead
+	as the execution of the callbacks are more managable.
+
+2004-03-01  Jeff Hobbs	<jeffh@ActiveState.com>
+
+	* README:	    update patchlevel to 8.5a1
+	* generic/tcl.h:
+	* tools/tcl.wse.in, tools/tclSplash.bmp:
+	* unix/configure, unix/configure.in, unix/tcl.spec:
+	* win/README.binary, win/configure, win/configure.in:
+
+	* unix/tcl.m4: update HP-11 build libs setup
+
+2004-03-01  Don Porter	<dgp@users.sourceforge.net>
+
+	* unix/tcl.m4 (SC_CONFIG_CFLAGS):	Allow 64-bit enabling on
+	IRIX64-6.5* systems. [Bug 218561]
+	* unix/configure:	autoconf-2.57
+
+	* generic/tclTrace.c (TclCheckInterpTraces):	The TIP 62
+	* generic/tclTest.c (TestcmdtraceCmd):	implementation introduced a
+	* tests/trace.test (trace-29.10):	bug by testing the CallFrame
+	level instead of the iPtr->numLevels level when deciding what traces
+	created by Tcl_Create(Obj)Trace to call. Added test to expose the
+	error, and made fix. [FRQ 462580]
+
+2004-02-28  Vince Darley  <vincentdarley@users.sourceforge.net>
+
+	* tests/fileSystem.test: fix to Tcl Bug 905163.
+	* tests/fileName.test: fix to Tcl Bug 904705.
+
+	* doc/{various}.n: removed 'the the' typos.
+
+2004-02-26  Daniel Steffen  <das@users.sourceforge.net>
+
+	* macosx/Makefile: fixed copyright year in Tcl.framework Info.plist
+
+2004-02-25  Don Porter	<dgp@users.sourceforge.net>
+
+	* tests/basic.test:	Made several tests more robust to the
+	* tests/cmdMZ.test:	list-quoting of path names that might contain
+	* tests/exec.test:	Tcl-special chars like { or [. Should help us
+	* tests/io.test:	sort out [Bug 554068]
+	* tests/pid.test:
+	* tests/socket.test:
+	* tests/source.test:
+	* tests/unixInit.test:
+
+2004-02-25  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* generic/tclLoad.c (Tcl_LoadObjCmd): Missing dereference caused
+	segfault with non-loadable extension. [Bug 904307]
+
+	* unix/tclUnixChan.c (TcpGetOptionProc): Stop memory leak with very
+	long hostnames. [Bug 888777]
+
+2004-02-25  Pat Thoyts	<patthoyts@users.sourceforge.net>
+
+	* win/tclWinDde.c: Removed some gcc warnings - except for the
+	-Wconversion warning for GetGlobalAtomName. gcc is just wrong about
+	this.
+
+2004-02-24  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	IMPLEMENTATION OF TIP#100 FROM GEORGIOS PETASIS
+	* generic/tclLoad.c (Tcl_UnloadObjCmd): Implementation.
+	* tests/unload.test:			Test suite.
+	* unix/dltest/pkgua.c:			Helper for test suite.
+	* doc/unload.n:				Documentation.
+	Also assorted changes (mostly small) to several other files.
+
+2004-02-23  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* generic/regc_locale.c (cclass): Buffer was having its size reset
+	instead of being released => memleak. [Bug 902562]
+
+2004-02-21  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* generic/tclLoad.c (Tcl_LoadObjCmd): Fixed memory leak due to an
+	improper error exit route.
+
+2004-02-20  David Gravereaux <davygrvy@pobox.com>
+
+	* win/tclWinSock.c (SocketThreadExitHandler): Don't call
+	TerminateThread when WaitForSingleObject returns a timeout.
+	Tcl_Finalize called from DllMain will pause all threads. Trust that
+	the thread will get the close notice at a later time if it does ever
+	wake up before being cleaned up by the system anyway.
+
+2004-02-17  Don Porter	<dgp@users.sourceforge.net>
+
+	* doc/tcltest.n:
+	* library/tcltest/tcltest.tcl:	Changed -verbose default value to
+	{body error} so that detailed information on unexpected errors in
+	tests is provided by default, even after the fix for [Bug 725253]
+
+2004-02-17  Jeff Hobbs	<jeffh@ActiveState.com>
+
+	* tests/unixInit.test (unixInit-7.1):
+	* unix/tclUnixInit.c (TclpInitPlatform): ensure the std fds exist to
+	prevent crash condition [Bug 772288]
+
+2004-02-17  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* generic/tclCompCmds.c (TclCompileSwitchCmd): Bozo mistake in memory
+	releasing order when in an error case. [Bug 898910]
+
+2004-02-16  Jeff Hobbs	<jeffh@ActiveState.com>
+
+	* generic/tclTrace.c (TclTraceExecutionObjCmd)
+	(TclTraceCommandObjCmd): fix possible mem leak in trace info.
+
+2004-02-12  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* win/tclWinInit.c (AppendEnvironment): Use the tail component of the
+	passed in lib path instead of just blindly using lib+4. That worked
+	when lib was "lib/..." but fails for other values. Thanks go to
+	Patrick Samson for pointing this out.
+
+2004-02-10  David Gravereaux  <davygrvy@pobox.com>
+
+	* win/nmakehlp.c: better macro grepping logic.
+
+2004-02-07  David Gravereaux  <davygrvy@pobox.com>
+
+	* win/makefile.vc:
+	* win/rules.vc:
+	* win/tcl.rc:
+	* win/tclsh.rc: Added an 'unchecked' option to the OPTS macro so a
+	core built with symbols can be linked to the non-debug enabled C
+	run-time. As per discussion with Kevin Kenny. Called like this:
+
+		nmake -af makefile.vc OPTS=unchecked,symbols
+
+	This clarifies the meaning of the 'g' naming suffix to mean only that
+	the binary requires the debug enabled C run-time. Whether the binary
+	contains symbols or not is a different condition.
+
+2004-02-06  Don Porter	<dgp@users.sourceforge.net>
+
+	* doc/clock.n:	Removed reference to non-existent [file ctime].
+
+2004-02-05  David Gravereaux  <davygrvy@pobox.com>
+
+	* docs/tclvars.n: Added clarification of the tcl_platform(debug) var
+	that it only refers to the flavor of the C run-time, and not whether
+	the core contains symbols.
+
+2004-02-05  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclFileName.c (SkipToChar): Corrected CONST and type-casting
+	issues that caused compiler warnings.
+
+2004-02-04  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclCmdAH.c (StoreStatData): Removed improper refcount
+	decrement of the varName parameter. This error was causing segfaults
+	following test cmdAH-28.7.
+
+	* library/tcltest/tcltest.tcl: Corrected references to non-existent
+	$name variable in [cleanupTests]. [Bug 833637]
+
+2004-02-03  Don Porter	<dgp@users.sourceforge.net>
+
+	* library/tcltest/tcltest.tcl:	Corrected parsing of single command
+	line argument (option with missing value) [Bug 833910]
+	* library/tcltest/pkgIndex.tcl:	Bump to version 2.2.5.
+
+2004-02-02  David Gravereaux <davygrvy@pobox.com>
+
+	* generic/tclIO.c (Tcl_Ungets): Fixes improper filling of the channel
+	buffer. This is the buffer before the splice. [Bug 405995]
+
+2004-02-01  David Gravereaux <davygrvy@pobox.com>
+
+	* tests/winPipe.test: more pass-thru commandline verifications.
+	* win/tclWinPipe.c (BuildCommandLine): Special case quoting for '{'
+	not required by the c-runtimes's parse_cmdline().
+	* win/tclAppInit.c: Removed our custom setargv() in favor of the work
+	provided by the c-runtime. [Bug 672938]
+
+	* win/nmakehlp.c: defensive techniques to avoid static buffer
+	overflows and a couple envars upsetting invokations of cl.exe and
+	link.exe. [Bug 885537]
+
+	* tests/winPipe.test: Added proof that BuildCommandLine() is not doing
+	the "N backslashes followed a quote -> insert N * 2 + 1 backslashes
+	then a quote" rule needed for the crt's parse_cmdline().
+	* win/tclWinPipe.c: Fixed BuildCommandLine() to pass the new cases.
+
+2004-01-30  David Gravereaux <davygrvy@pobox.com>
+
+	* win/makefile.vc: Use the -GZ compiler switch when building for
+	symbols. This is supposed to emulate the release build better to avoid
+	hiding problems that only show themselves in a release build.
+
+2004-01-29  Vince Darley  <vincentdarley@users.sourceforge.net>
+
+	* generic/tclPathObj.c: fix to [Bug 883143] in file normalization
+
+2004-01-29  Vince Darley  <vincentdarley@users.sourceforge.net>
+
+	* doc/file.n:
+	* generic/tclFCmd.c
+	* generic/tclTest.c
+	* library/init.tcl
+	* mac/tclMacFile.c
+	* tests/fileSystem.test: fix to [Bug 886352] where 'file copy -force'
+	had inconsistent behaviour wrt target files with insufficient
+	permissions, particular from vfs->native fs. Behaviour of '-force' is
+	now always consistent (and now consistent with behaviour of 'file
+	delete -force'). Added new tests and documentation and cleaned up the
+	'simplefs' test filesystem.
+
+	* generic/tclIOUtil.c
+	* unix/tclUnixFCmd.c
+	* unix/tclUnixFile.c
+	* win/tclWinFile.c: made native filesystems more robust to C code
+	which asks for mount lists.
+
+	* generic/tclPathObj.c: fix to [Bug 886607] removing warning/error
+	with some compilers.
+
+2004-01-28  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* generic/tclObj.c (SetBooleanFromAny): Rewrite to do more efficient
+	string->bool conversion.
+	Many other minor whitespace/style fixes to this file too.
+
+2004-01-27  David Gravereaux <davygrvy@pobox.com>
+
+	* win/nmakehlp.c: Use '.\nul' as the sourcefile name instead of 'nul'
+	so VC 5.2 doesn't try searching the path for it and failing with a
+	possible dialogbox popping up about having to add a CD to an empty
+	drive. Also added a SetErrorMode() call to disable any dialogs that
+	cl.exe or link.exe might create. [Bug 885537]
+
+2004-01-22  Vince Darley  <vincentdarley@users.sourceforge.net>
+
+	* doc/file.n: clarified documentation of 'file system' [Bug 883825]
+	* tests/fCmd.test: improved test result in failure case.
+
+2004-01-22  Vince Darley  <vincentdarley@users.sourceforge.net>
+
+	* tests/fileSystem.test: 3 new tests
+	* generic/tclPathObj.c: fix to [Bug 879555] in file normalization.
+	* doc/filename.n: small clarification to Windows behaviour with
+	filenames like '.....', 'a.....', '.....a'.
+
+	* generic/tclIOUtil.c: slight improvement to native cwd caching on
+	Windows.
+
+2004-01-21  David Gravereaux <davygrvy@pobox.com>
+
+	* doc/Panic.3:	Mentions of 'panic' and 'panicVA' removed from the
+	documentation.
+
+2004-01-21  Vince Darley  <vincentdarley@users.sourceforge.net>
+
+	* doc/FileSystem.3:
+	* generic/tcl.decls:
+	* generic/tclCmdAH.c
+	* generic/tclDecls.h
+	* generic/tclFCmd.c
+	* generic/tclFileName.c
+	* generic/tclFileSystem.h
+	* generic/tclIOUtil.c
+	* generic/tclInt.decls
+	* generic/tclInt.h
+	* generic/tclIntDecls.h
+	* generic/tclPathObj.c
+	* generic/tclStubInit.c
+	* generic/tclTest.c
+	* mac/tclMacFile.c
+	* tests/fileName.test
+	* tests/fileSystem.test
+	* tests/winFCmd.test
+	* unix/tclUnixFile.c
+	* win/tclWin32Dll.c
+	* win/tclWinFCmd.c
+	* win/tclWinFile.c
+	* win/tclWinInt.h
+
+	Three main issues accomplished: (1) cleaned up variable names in the
+	filesystem code so that 'pathPtr' is used throughout. (2) applied a
+	round of filesystem optimisation with better handling and caching of
+	relative and absolute paths, requiring fewer conversions. (3)
+	clarifications to the documentation, particularly regarding the
+	acceptable refCounts of objects. Some new tests added. Tcl benchmarks
+	show a significant improvement over 8.4.5, and on Windows typically a
+	small improvement over 8.3.5 (Unix still appears to require
+	optimisation). TCL_FILESYSTEM_VERSION_2 introduced, but for internal
+	use only. There should be no public incompatibilities from these
+	changes. Thanks to dgp for extensive testing.
+
+2004-01-19  David Gravereaux <davygrvy@pobox.com>
+
+	* win/tclWinPipe.c (Tcl_WaitPid): Fixed a thread-safety problem with
+	the process list. The delayed cut operation after the wait was going
+	stale by being outside the list lock. It now cuts within the lock and
+	does a locked splice for when it needs to instead. [Bug 859820]
+
+2004-01-18  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* generic/tclCompile.c, generic/tclCompile.h: Two new opcodes,
+	INST_LIST_INDEX_IMM and INST_LIST_RANGE_IMM, that have operand(s) of
+	new type OPERAND_IDX4 which represents indexes into things like lists
+	(and perhaps other things eventually.)
+	* generic/tclExecute.c (TclExecuteByteCode): Implementation of the new
+	opcodes. INST_LIST_INDEX_IMM does a simple [lindex] with either front-
+	or end-based simple indexing. INST_LIST_RANGE_IMM does an [lrange]
+	with front- or end-based simple indexing for both the reference to the
+	first and last items in the range.
+	* generic/tclCompCmds.c (TclCompileLassignCmd): Generate bytecode for
+	the [lassign] command.
+
+2004-01-17  David Gravereaux <davygrvy@pobox.com>
+
+	* win/tclWinInit.c: added #pragma comment(lib, "advapi32.lib") when
+	compiling under VC++ so we don't need to specify it when linking.
+
+2004-01-17  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* generic/tclCmdIL.c (Tcl_LassignObjCmd): Add more shimmering
+	protection for when the list is also one of the variables.
+
+	BASIC IMPLEMENTATION OF TIP#57
+	* generic/tclCmdIL.c (Tcl_LassignObjCmd): Implementation of the
+	[lassign] command that takes full advantage of Tcl's object API.
+	* doc/lassign.n: New file documenting the command.
+	* tests/cmdIL.test (cmdIL-6.*): Test suite for the command.
+
+2004-01-15  David Gravereaux <davygrvy@pobox.com>
+
+	* win/tclWinReg.c: Placed the requirement for advapi.lib into the
+	object file itself with #pragma comment (lib, ...) when built with
+	VC++. This will simplify linking for users of the static library.
+
+	* win/rules.vc: Added new 'fullwarn' to the CHECKS commandline macro;
+	sets $(FULLWARNINGS).
+
+	* win/makefile.vc: Removed 'advapi.lib' from $(baselibs). Added new
+	logic to crank-up the warning levels for both compile and link when
+	$(FULLWARNINGS) is set. Some clean-up with how the resource files are
+	built and how -DTCL_USE_STATIC_PACKAGES is sent when compiling the
+	shells.
+
+	* win/tclAppInit.c: Small change in how TCL_USE_STATIC_PACKAGES is
+	used.
+
+	* win/tcl.rc:
+	* win/tclsh.rc: Some clean-up with how the resource files are built.
+	Fixed 'OriginalFilename' problem that still thought a debug suffix was
+	still 'd', now is 'g'.
+
+2004-01-14  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* generic/tclDictObj.c (TraceDictPath, DictExistsCmd): Adjusted
+	behaviour of [dict exists] so a failure to look up a dictionary along
+	the path of dicts doesn't trigger an error. This is how it was
+	documented to behave previously... [Bug 871387]
+
+	* generic/tclDictObj.c: Assorted dict fixes from Peter Spjuth relating
+	to [Bug 876170].
+	(SetDictFromAny): Make sure that lists retain their ordering even when
+	converted to dictionaries and back.
+	(TraceDictPath): Correct object reference count handling!
+	(DictReplaceCmd, DictRemoveCmd): Stop object leak.
+	(DictIncrCmd,DictLappendCmd,DictAppendCmd,DictSetCmd,DictUnsetCmd):
+	Simpler handling of reference counts when assigning to variables.
+	* tests/dict.test (dict-19.2): Memory leak stress test
+
+2004-01-13  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclCmdMZ.c (Tcl_SwitchObjCmd):  Silence compiler warnings.
+
+	Patch 876451: restores performance of [return]. Also allows forms such
+	as [return -code error $msg] to be bytecompiled.
+
+	* generic/tclInt.h:	Factored Tcl_ReturnObjCmd() into two pieces:
+	* generic/tclCmdMZ.c:	TclMergeReturnOptions(), which can parse the
+	options to [return], check their validity, and create the
+	corresponding return options dictionary, and TclProcessReturn(), which
+	takes that return options dictionary and performs the [return]
+	operation.
+
+	* generic/tclCompCmds.c: Rewrote TclCompileReturnCmd() to call
+	TclMergeReturnOptions() at compile time so the return options
+	dictionary is computed at compile time (when it is fully known). The
+	dictionary is pushed on the stack along with the result, and the code
+	and level values are included in the bytecode as operands. Also
+	supports optimized compilation of un-[catch]ed [return]s from procs
+	with default options into the INST_DONE instruction.
+
+	* generic/tclExecute.c: Rewrote INST_RETURN instruction to retrieve
+	the code and level operands, pop the return options from the stack,
+	and call TclProcessReturn() to perform the [return] operation.
+
+	* generic/tclCompile.h:	New utilities include TclEmitInt4 macro
+	* generic/tclCompile.c:	and TclWordKnownAtCompileTime().
+
+	End Patch 876451.
+
+	* generic/tclFileName.c (Tcl_GlobObjCmd): Latest changes to management
+	of the interp result by Tcl_GetIndexFromObj() exposed improper interp
+	result management in the [glob] command procedure. Corrected by
+	adopting the Tcl_SetObjResult(Tcl_NewStringObj) pattern. This stopped
+	a segfault in test filename-11.36. [Bug 877677]
+
+2004-01-13  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* generic/tclIndexObj.c (Tcl_GetIndexFromObjStruct, Tcl_WrongNumArgs):
+	Create fresh objects instead of using the one currently in the
+	interpreter, which isn't guaranteed to be fresh and unshared. The cost
+	for the core will be minimal because of the object cache, and this
+	fixes [Bug 875395].
+
+2004-01-12  Miguel Sofer <msofer@users.sf.net>
+
+	* generic/tclCompExpr.c (CompileLandOrLorExpr): cosmetic changes.
+
+2004-01-12  Miguel Sofer <msofer@users.sf.net>
+
+	* generic/tclCompExpr.c (CompileLandOrLorExpr): new logic, fewer
+	instructions. As a side effect, the instructions INST_LOR and
+	INST_LAND are now never used.
+	* generic/tclExecute.c (INST_JUMP*): small optimisation; fix a bug in
+	debug code.
+
+2004-01-11  David Gravereaux <davygrvy@pobox.com>
+
+	* win/tclWinThrd.c (Tcl_ConditionNotify): condPtr must be dereferenced
+	to see if there are waiters else uninitialized datum is manipulated.
+	[Bug 849007 789338 745068]
+
+2004-01-09  David Gravereaux <davygrvy@pobox.com>
+
+	* generic/tcl.h: Renamed and deprecated #defines moved to within the
+	#ifndef TCL_NO_DEPRECATED block. This allows us to build Tcl to check
+	for deprecated functions in use, such as panic() and Tcl_Ckalloc(). By
+	request from DKF. Extensions that build with -DTCL_NO_DEPRECATED now
+	have these macros as restricted.
+	***POTENTIAL INCOMPATIBILITY***
+
+	* win/makefile.vc:
+	* win/rules.vc:	 Added -DTCL_NO_DEPRECATED usage to makefile.vc.
+	Called like this:   nmake -af makefile.vc CHECKS=nodep
+
+2004-01-09  Vince Darley  <vincentdarley@users.sourceforge.net>
+
+	* generic/tclIOUtil.c: fix to infinite loop in TclFinalizeFilesystem
+	[Bug 873311]
+
+	******************************************************************
+	*** CHANGELOG ENTRIES FOR 2003 IN "ChangeLog.2003"	       ***
+	*** CHANGELOG ENTRIES FOR 2002 IN "ChangeLog.2002"	       ***
+	*** CHANGELOG ENTRIES FOR 2001 IN "ChangeLog.2001"	       ***
+	*** CHANGELOG ENTRIES FOR 2000 IN "ChangeLog.2000"	       ***
+	*** CHANGELOG ENTRIES FOR 1999 AND EARLIER IN "ChangeLog.1999" ***
+	******************************************************************
diff --git a/ChangeLog.2005 b/ChangeLog.2005
new file mode 100644
index 0000000..0d1d7cf
--- /dev/null
+++ b/ChangeLog.2005
@@ -0,0 +1,3822 @@
+2005-12-30  Kevin B. Kenny  <kennykb@acm.org>
+
+	* generic/tclStubLib.c: Corrected a typo in "missing Stubs table
+	pointer."
+
+2005-12-27  Kevin B. Kenny  <kennykb@acm.org>
+
+	* generic/tcl.decls:  Destubbed TclTomMathInitializeStubs - it is in
+	* generic/tcl.h:      the stub library, not the main shared
+	* generic/tclBasic.c: library. Exported Tcl_InitBignumFromDouble.
+	* generic/tclExecute.c:
+	* generic/tclInt.h:
+	* generic/tclStrToD.c:
+
+	* generic/tclDecls.h:
+	* generic/tclStubLib.c:
+	* generic/tclStubInit.c: Regenerated.
+
+	* generic/clock.tcl: Reverted to using the time zone abbreviation and
+	not its name to "stop the bleeding" on [Bug 1386377]. This is *not* a
+	good long-term solution, but there may not be one.
+
+	* libtommath/bn_mp_sqrt.c: Improved the initial approximation to the
+	square root, roughly doubling the speed of the routine. (This is a
+	local change that needs to be communicated to Tom.)
+
+	* win/Makefile.in: Corrected a bug where tommath_class.h and
+	tommath_superclass.h were not installed, making it impossible for
+	client code to compile against the tommath stubs.
+
+	* library/tzdata: Updated to Olson's tzdata2005r. (Latest changes to
+	Daylight Saving Time in Canada, plus redefinition of the Posix-style
+	zones [e.g., EST5EDT] to be locale-independent.)
+
+	* libtommath: Updated to Tom St.Denis's release 0.37.
+
+2005-12-20  Donal K. Fellows  <donal.k.fellows@manchester.ac.uk>
+
+	* generic/tclThreadAlloc.c (Tcl_GetMemoryInfo): Format values as longs
+	and not ints, so they are less likely to wrap on 64-bit machines.
+
+2005-12-19  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclCmdMZ.c:	Modified [string is double] to use
+	* tests/string.test:	TclParseNumber() to parse trailing whitespace.
+	Ensures consistency, and makes it easier to cleanup after invalid
+	internal reps left behind by parsing [Bugs 1360532 1382287].
+
+	* generic/tclParseExpr.c:	Added TCL_PARSE_NO_WHITESPACE to
+	* generic/tclScan.c:	TclParseNumber() calls since [scan] and [expr]
+	* tests/scan.test:	parsing don't want spaces in parsed numbers.
+
+	* generic/tclInt.h:	Added TCL_PARSE_NO_WHITESPACE flag to the
+	* generic/tclStrToD.c:	TclParseNumber() interface.
+
+2005-12-19  Donal K. Fellows  <donal.k.fellows@manchester.ac.uk>
+
+	* doc/Tcl.n: Clarify what is going on in variable substitution
+	following thread on comp.lang.tcl.
+
+2005-12-18  Donal K. Fellows  <donal.k.fellows@manchester.ac.uk>
+
+	* generic/tclCompCmds.c (TclCompileDictCmd): Ensure that we only do an
+	'endCatch' when there's a preceding 'beginCatch'. [Bug 1382528] Many
+	thanks to Anton Kovalenko for finding this and pointing out that it was
+	a catch stack handling problem!
+
+2005-12-14  Daniel Steffen  <das@users.sourceforge.net>
+
+	* generic/tclIOUtil.c: workaround gcc warning "comparison is always
+	* generic/tclTest.c:   false due to limited range of data type".
+
+	* macosx/Tcl.xcode/project.pbxproj:
+	* macosx/Tcl.xcodeproj/project.pbxproj:
+	* unix/Makefile.in: add new tclTomMath* files.
+
+	* generic/tclBasic.c: replace panic with Tcl_Panic.
+
+2005-12-13  Kevin B. Kenny  <kennykb@acm.org>
+
+	* generic/tcl.decls:    Added changes to export an additional stubs
+	* generic/tclBasic.c:   table to represent the 'libtommath' routines
+	* generic/tclDecls.h:   that Tcl uses and export them to callers.
+	* generic/tclInt.decls: Reran 'genstubs'
+	* generic/tclInt.h:
+	* generic/tclIntDecls.h:
+	* generic/tclIntPlatDecls.h:
+	* generic/tclStubInit.c:
+	* generic/tclStubLib.c:
+	* generic/tclTomMath.decls:
+	* generic/tclTomMath.h:
+	* generic/tclTomMathDecls.h:
+	* generic/tclTomMathInterface.c:
+	* generic/tommath.h:
+	* tools/fix_tommath_h.tcl:
+	* unix/Makefile.in:
+	* win/Makefile.in:
+	* win/makefile.vc:
+
+	* generic/tclClock.c:   Made changes to silence a number of compiler
+	* generic/tclIO.c:	warnings when building with mingw.
+	* generic/tclIORChan.c:
+	* generic/tclLink.c:
+	* generic/tclListObj.c:
+	* generic/tclObj.c:
+	* generic/tclParseExpr.c:
+	* generic/tclProc.c:
+	* generic/tclTimer.c:
+	* win/tclWinChan.c:
+	* win/tclWinConsole.c:
+	* win/tclWinDde.c:
+	* win/tclWinFCmd.c:
+	* win/tclWinFile.c:
+	* win/tclWinReg.c:
+	* win/tclWinSock.c:
+
+2005-12-13  Donal K. Fellows  <donal.k.fellows@manchester.ac.uk>
+
+	* generic/tclExecute.c (TEBC:DICT_FIRST,DICT_DONE): Only decrease the
+	references to the dictionary once the iteration completes. Do this by
+	storing the dict in the iterator context variable. [Bug 1379349] Thanks
+	to Ulrich Ring and Tobias Hippler for finding this.
+
+2005-12-12  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* unix/tcl.m4, unix/configure: Fix sh quoting error reported in
+	bash-3.1+ [Bug 1377619] (schafer)
+
+2005-12-12  Kevin B. Kenny  <kennykb@acm.org>
+
+	* doc/mathfunc.n: Changed two examples from the incorrect 'tcl::math::'
+	to 'tcl::mathfunc::' [Bug 1378818]
+
+2005-12-09  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* win/configure: Regen.
+	* win/tcl.m4 (SC_CONFIG_CFLAGS): Define MACHINE for gcc builds. The
+	lack of a definition of this variable in the manifest file was causing
+	a runtime error in wish built with gcc.
+
+2005-12-09  Donal K. Fellows  <donal.k.fellows@manchester.ac.uk>
+
+	* tests/lsearch.test (lsearch-10.8..10):  If the -start is off the end,
+	* generic/tclCmdIL.c (Tcl_LsearchObjCmd): searching should find nothing
+	at all. [Bug 1374778]
+
+2005-12-08  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* win/Makefile.in, win/makefile.vc: Add Win x64 and CE build support
+	* win/tcl.m4, win/configure:        CE still requires C code fixes.
+
+	* generic/tcl.h: use struct __stat64 (not _stat64) for MSC_VER >= 1400
+	(i.e. latest Platform SDK).
+
+2005-12-07  Donal K. Fellows  <donal.k.fellows@manchester.ac.uk>
+
+	* doc/socket.n: Cross-referenced the socket documentation better to the
+	fconfigure documentation on the topic of asynch sockets.
+	* doc/fconfigure.n: Added keyword to documentation of -blocking option
+	so that people looking for "asynch" can find it as well.
+
+2005-12-05  Daniel Steffen  <das@users.sourceforge.net>
+
+	* unix/tclUnixPort.h (Darwin): fix incorrect __DARWIN_UNIX03 configure
+	overrides that were originally copied from Darwin CVS (rdar://3693001)
+
+2005-12-05  Kevin B. Kenny  <kennykb@acm.org>
+
+	* tools/tclZIC.tcl: Updated to reflect changes in calling sequence when
+	GetJulianDateFromEraYearMonthDay moved to C.
+	* library/tzdata: Regenerated from Olson's tzdata2005p.tar.gz - the
+	'systemv' changes appear not to affect Tcl's processing of the dates.
+
+2005-12-05  Daniel Steffen  <das@users.sourceforge.net>
+
+	* unix/configure.in: move check for fts API to configure.in and run it
+	* unix/tcl.m4:       on all platforms, since Linux glibc2 and *BSDs
+	also have this; using fts is more efficient than a recursive
+	opendir/readdir.
+	* unix/tclUnixFCmd.c (TraverseUnixTree): add support to fts code for
+	platforms with stat64.
+	* unix/configure:
+	* unix/tclConfig.h.in: regen.
+
+2005-12-05  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* unix/configure:     Use fts file API on Darwin if available.
+	* unix/tcl.m4:        Addresses file delete issues in readdir noted
+	* unix/tclUnixFCmd.c: in [Bug 1034337]. (steffen)
+	Remove redundant stat call for each file in DoCopyFile. (steffen)
+
+2005-12-02  Kevin B. Kenny  <kennykb@acm.org>
+
+	* generic/tclClock.c: Moved a tiny bit more of [clock format] from run
+	* library/clock.tcl: time to compile time, and fixed a l10n bug in the
+	process. [Bug 1371446]. Also, conditoned the call to SetupTimeZone to
+	speed the common case where TZData($timezone) already exists, and
+	achieved a puny speedup by making ::tcl::clock::getenv not throw
+	errors.
+	* unix/Makefile.in: Made some changes to support a 'make' command that
+	is present on some antiquated versions of Solaris.
+
+2005-12-01  Kevin B. Kenny  <kennykb@acm.org>
+
+	* library/clock.tcl: Continued rationalizing the code, eliminating
+	numerous redundant [mc] calls. Added another time boost by precompiling
+	a [::format] command to do the bulk of the work of [clock format].
+
+2005-12-01  Donal K. Fellows  <donal.k.fellows@manchester.ac.uk>
+
+	* unix/Makefile.in: Add remaining dependency info. While automated
+	maintenance of this information would be good, having it at all is much
+	better than a poke in the eye with a sharp stick...
+
+2005-12-01  Daniel Steffen  <das@users.sourceforge.net>
+
+	* generic/tclClock.c: fix warning.
+
+	* unix/tcl.m4 (Darwin): fix error when MACOSX_DEPLOYMENT_TARGET unset
+	* unix/configure: regen.
+
+2005-11-30  Donal K. Fellows  <donal.k.fellows@manchester.ac.uk>
+
+	* unix/Makefile.in: Add dependency information relating to tclCompile.h
+	since when the list of opcodes changes it is usually useful to rebuild
+	everything that depends on it (but which is nonetheless a small
+	fraction of the total set of Tcl source files).
+
+	***POTENTIAL INCOMPATIBILITY*** for bytecode savers/loaders. See below
+
+	* generic/tclCompCmds.c (TclCompileSwitchCmd): Arrange for very simple
+	[switch] invokations to be compiled into hash lookups into jump tables;
+	only a very specific kind of [switch] can be safely compiled this way,
+	but that happens to be the most common kind. This makes around 5-10%
+	difference to the speed of execution of clock.test.
+	* generic/tclExecute.c (TEBC:INST_JUMP_TABLE): New instruction to allow
+	for jumps to locations looked up in a hashtable. Requires a new AuxData
+	type, tclJumptableInfoType (supported by the functions DupJumptableInfo
+	and FreeJumptableInfo in tclCompCmds.c) so anything that saves bytecode
+	containing this *must* be updated!
+
+2005-11-30  Kevin Kenny  <kennykb@acm.org>
+
+	* generic/tclClock.c: Fixed a bad refcount in previous commit that led
+	to a corrupted heap. Also silenced a warning that some compilers gave
+	about the excessively long constant for JULIAN_SEC_POSIX_EPOCH. Also
+	fixed a bug where [clock format] would fail in the :localtime zone for
+	times before the Posix Epoch. Thanks to Miguel Sofer for pointing out
+	all of these. Also rationalized the code a little bit by moving parts
+	of [clock scan] into C, eliminating some code that was duplicated in
+	the C and Tcl layers.
+
+2005-11-29  Kevin Kenny  <kennykb@acm.org>
+
+	* generic/tclBasic.c:	Moved a big part of [clock format] down
+	* generic/tclClock.c:   to the C level in order to make it go faster.
+	* generic/tclInt.h:     Preliminary measurements suggest that it
+	* generic/clock.tcl:    more than doubles in speed with this change.
+
+2005-11-29  Donal K. Fellows  <donal.k.fellows@manchester.ac.uk>
+
+	* generic/tclCmdIL.c (Tcl_LsearchObjCmd): Allow [lsearch -regexp] to
+	process REs that contain backreferences. This expensive mode of
+	operation is only used if the RE would otherwise cause a compilation
+	failure. [Bug 1366683]
+
+2005-11-28  Kevin Kenny  <kennykb@acm.org>
+
+	* tools/tclZIC.tcl (convertTimeOfDay): Corrected a typo that caused
+	wrong DST transitions in any time zone where the transition is
+	specified as local Standard Time (as opposed to wall-clock or UTC).
+	(Also updated the code to be bignum-safe.)
+	* tests/clock.test (clock-51.1): Added regression test for the above.
+	* library/tzdata: Updated to Olson's 'tzdata2005o' (changes for Cuba,
+	Nicaragua, Jordan, and Georgia) and regenerated. Thanks to Paul
+	Mackerras for reporting this problem.
+
+2005-11-27  Daniel Steffen  <das@users.sourceforge.net>
+
+	* unix/tcl.m4 (Darwin): add 64bit support, check for Tiger copyfile(),
+	add CFLAGS to SHLIB_LD to support passing -isysroot in env(CFLAGS) to
+	configure (flag can't be present twice, so can't be in both CFLAGS and
+	LDFLAGS during configure), don't use -prebind when deploying on 10.4,
+	define TCL_IO_TRACK_OS_FOR_DRIVER_WITH_BAD_BLOCKING (rdar://3171542).
+	(SC_ENABLE_LANGINFO, SC_TIME_HANDLER): add/fix caching, fix obsolete
+	autoconf macros. Sync with tk/unix/tcl.m4.
+
+	* unix/configure.in: fix obsolete autoconf macros, sync gratuitous
+	formatting/ordering differences with tk/unix/configure.in.
+
+	* unix/Makefile.in: add CFLAGS to tclsh/tcltest link to make executable
+	linking the same as during configure (needed to avoid losing any linker
+	relevant flags in CFLAGS, in particular flags that cannot be in
+	LDFLAGS). Avoid concurrent linking of tclsh and compiling of
+	tclTestInit.o or xtTestInit.o during parallel make.
+	(checkstubs, checkdoc, checkexports): dependency and Darwin fixes
+	(dist): add new macosx files.
+
+	* unix/tclLoadDyld.c (TclpDlopen): use NSADDIMAGE_OPTION_WITH_SEARCHING
+	on second NSAddImage only. [Bug 1204237]
+	(TclGuessPackageName): should not be MODULE_SCOPE.
+	(TclpLoadMemory): ppc64 and endian (i386) fixes, add support for
+	loading universal (fat) bundles from memory.
+
+	* unix/tclUnixFCmd.c:
+	* macosx/tclMacOSXFCmd.c: ppc64 and endian (i386) fixes.
+	(TclMacOSXCopyFileAttributes): add support for new Tiger copyfile() API
+	to enable copying of xattrs & ACLs by [file copy].
+
+	* generic/tcl.h: add Darwin specifc configure overrides for TCL_WIDE
+	defines to support fat compiles of ppc and ppc64 at the same time,
+	(replaces Darwin CVS fix by emoy, rdar://3693001). add/correct location
+	of version numbers in macosx files.
+
+	* generic/tclInt.h: clarify fat compile comment.
+
+	* unix/tclUnixPort.h: add Darwin specifc configure overrides to support
+	fat compiles, where configure runs only once for multiple architectures
+	(replaces Darwin CVS fix by emoy, rdar://3693001).
+
+	* macosx/tclMacOSXBundle.c:
+	* macosx/tclMacOSXNotify.c:
+	* unix/tclUnixNotfy.c:
+	* unix/tclUnixPort.h: fix #include order to support compile time
+	override of HAVE_COREFOUNDATION in tclUnixPort.h when building for
+	ppc64
+
+	* macosx/Tcl.pbproj/default.pbxuser (new file):
+	* macosx/Tcl.pbproj/jingham.pbxuser:
+	* macosx/Tcl.pbproj/project.pbxproj:
+	* macosx/Tcl.xcode/default.pbxuser (new file):
+	* macosx/Tcl.xcode/project.pbxproj (new file):
+	* macosx/Tcl.xcodeproj/default.pbxuser (new file):
+	* macosx/Tcl.xcodeproj/project.pbxproj (new file): new/updated
+	projects for Xcode 2.2 on 10.4, Xcode 1.5 on 10.3 & ProjectBuilder on
+	10.2, with native tcltest targets and support for universal (fat)
+	compiles.
+
+	* macosx/README: clarification/cleanup, document new Xcode projects and
+	universal (fat) builds via CFLAGS (i.e. all of ppc ppc64 i386 at once).
+
+	* unix/Makefile.in:
+	* unix/aclocal.m4:
+	* unix/configure.in:
+	* unix/dltest/Makefile.in:
+	* macosx/configure.ac (new file): add support for inclusion of
+	unix/configure.in by macosx/configure.ac, allows generation of a config
+	headers enabled configure script in macosx (required by Xcode
+	projects).
+
+	* macosx/GNUmakefile: rename from Makefile to avoid overwriting by
+	configure run in tcl/macosx, add support for reusing configure cache,
+	build target fixes, remove GENERIC_FLAGS override now handled by
+	tcl.m4.
+
+	* generic/tcl.decls: add Tcl_Main declaration as comment to avoid
+	'checkstubs' target complaining about it missing from stubs.
+
+	* generic/regex.h:
+	* generic/tclDate.c:
+	* generic/tclEnv.c:
+	* generic/tclGetDate.y:
+	* generic/tclIOUtil.c:
+	* generic/tclObj.c:
+	* generic/tclStubInit.c:
+	* generic/tclStubLib.c:
+	* generic/tclPathObj.c:
+	* generic/tclThreadAlloc.c:
+	* generic/tclThreadStorage.c:
+	* generic/tclTrace.c:
+	* generic/tclVar.c:
+	* generic/tommath.h:
+	* tools/fix_tommath_h.tcl:
+	* unix/tclUnixFCmd.c: ensure externally visible symbols not contained
+	in stubs table are declared as MODULE_SCOPE (or as static if not used
+	outside of own source file). These changes allow 'make checkstubs' to
+	complete without error on Darwin with gcc 4.
+
+	* generic/rege_dfa.c (getvacant):
+	* generic/regexec.c (cfind):
+	* generic/tclCompExpr.c (CompileSubExpr):
+	* generic/tclNamesp.c (NamespaceEnsembleCmd):
+	* unix/tclUnixChan.c (TclUnixWaitForFile): initialise variables to
+	silence gcc 4 warnings.
+
+	* generic/tclExecute.c (TclExecuteByteCode): fix unused variable
+	warning when NO_WIDE_TYPE is defined.
+
+	* generic/regguts.h: only #define NDEBUG if not already #defined.
+
+	* unix/tclUnixNotfy.c:
+	* macosx/tclMacOSXNotify.c: sync whitespace & comments.
+
+	* unix/tclUnixPort.h:
+	* win/tclWinPort.h: remove declaration of obsolete&unused TclpMutex
+	API.
+
+	* unix/configure:
+	* unix/tclConfig.h.in: regen.
+
+2005-11-21  Andreas Kupries  <andreask@activestate.com>
+
+	* unix/Makefile.in (install-libraries): Updated Makefile to new
+	* win/Makefile.in (install-libraries):  version of the http package.
+	This fixes the ifneeded/provide mismatch reported when trying to
+	require http. Should we maybe try to automatically extract the version
+	number from the http code to prevent future breakage ?
+
+	This follows the update of the version number by dgp on Nov 15 (No
+	entry found in the ChangeLog).
+
+2005-11-20  Joe English  <jenglish@users.sourceforge.net>
+
+	* generic/tclStubLib.c: Don't set tclStubsPtr to 0 when
+	Tcl_PkgRequireEx() fails [Fix for [Bug 1091431] "Tcl_InitStubs failure
+	crashes wish"]
+
+2005-11-18  Miguel Sofer  <msofer@users.sf.net>
+
+	* tests/trace.test (trace-34.5): [Bug 1047286], added a second test
+	illustrating the role of "ns in callStack" in the ns's visibility
+	during deletion traces.
+
+2005-11-18  Kevin B. Kenny  <kennykb@acm.org>
+
+	* doc/clock.n: Restored several missing lines near the %w format group
+	so that %w and %W are documented with their actual behaviour. [Bug
+	1359183]
+
+2005-11-18  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* generic/tclIO.c (TclFinalizeIOSubsystem): preserve statePtr until we
+	retrieve the next statePtr from it.
+
+2005-11-18  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclObj.c (GetBignumFromObj): replace NULL with
+	tclEmptyStringRep to stop memcpy from complaining in a debug build
+	(the corresponding branch is eliminated by the optimiser otherwise).
+
+2005-11-18  Andreas Kupries  <andreask@activestate.com>
+
+	* generic/tclIO.c (TclFinalizeIOSubsystem): Applied Pat Thoyts' patch
+	for [Bug 1359094]. This moves the retrieval of the next channel state
+	to the end of the loop, as the called closeproc may close other
+	channels, i.e. modify the list we are iterating, invalidating any
+	pointer retrieved earlier.
+
+2005-11-18  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclListObj.c:	Restored the SetListFromAny routine to the
+	* generic/tclObj.c:	"list" Tcl_ObjType, and restored the
+	Tcl_RegisterObjType() call for "list". This addresses the needs of some
+	"bridge" extensions to examine whether the Tcl_ObjType of a Tcl_Obj is
+	that of the "list" Tcl_ObjType.
+
+2005-11-18  Donal K. Fellows  <donal.k.fellows@manchester.ac.uk>
+
+	* library/http/http.tcl (http::geturl): Improved syntactic validation
+	of URLs, and better error messages in some cases. [Bug 1358369]
+
+2005-11-17  Miguel Sofer  <msofer@users.sf.net>
+
+	* tests/namespace.test: fix comment
+
+2005-11-14  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclStrToD.c:	More data in the "can't happen" Tcl_Panic to
+	aid debugging.
+
+	* generic/tclBasic.c (CallCommandTraces): Save/restore the interp
+	result during traces to fix [Bug 1355342].
+
+2005-11-13  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclInt.h:
+	* generic/tclNamesp.c:
+	* tests/namespace.test: fix for [Bug 1354540] and [Bug 1355942]. The
+	new tests 7.3-6 and the modified 51.13 fail due to the unrelated [Bug
+	1355342]
+
+	* tests/trace.test: added tests 20.13-16 for [Bug 1355342]
+
+2005-11-12  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclBasic.c (Tcl_DeleteCommandFromToken):
+	* generic/tclObj.c (Tcl_GetCommandFromObj): more partial fixes for
+	[Bug 1354540] - making sure that cached references to a command being
+	deleted cannot be made reusable by a delete trace.
+
+2005-11-12  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclNamesp.c (Tcl_FindCommand): Do not find commands in dead
+	namespaces on the path. Partial fix for [Bug 1354540].
+
+2005-11-11  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclInt.h:	Revised TclParseNumber interface to enable
+	* generic/tclScan.c:	revision to the [scan] command implementation
+	* generic/tclStrToD.c:	to permit tests scan-4.44,55 to pass again.
+	[Bug 1348067].
+
+2005-11-11  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclBasic.c (Tcl_DeleteCommandFromToken):
+	* generic/tclObj.c (Tcl_GetCommandFromObj): bump the cmd epoch early
+	to insure that cached references to this command are invalidated.
+	Partial fix for [Bug 1352734] - at least insures that namespace-51.13
+	does not cause a panic. The test is still marked as knownbug, pending
+	resolution of what is actually the correct return value ([Bug
+	1354540])
+
+2005-11-09  Kevin B. Kenny  <kennykb@acm.org>
+
+	* generic/tclTimer.c: Changed [after] so that it behaves correctly
+	* tests/timer.test:   with negative arguments [Bug 1350293] and
+	arguments that overflow a 32-bit word. [Bug 1350291]
+
+2005-11-08  Don Porter  <dgp@users.sourceforge.net>
+
+	* tests/compile.test:	Updated tests with changed behavior
+	* tests/execute.test:	due to addition of bignums.
+	* tests/expr-old.test:
+	* tests/expr.test:
+	* tests/parseExpr.test:
+	* tests/platform.test:
+	* tests/string.test:
+
+2005-11-08  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* unix/tclUnixFCmd.c (MAX_READDIR_UNLINK_THRESHOLD): reduce to 130
+	based on errors seen on OS X 10.3 with lots of links in a dir.
+	[Bug 1034337 followup]
+
+2005-11-09  Donal K. Fellows  <donal.k.fellows@manchester.ac.uk>
+
+	* unix/Makefile.in (gdb-test): Added a new target to make it easier to
+	run the test suite inside a debugger.
+
+2005-11-08  Don Porter  <dgp@users.sourceforge.net>
+
+	* tests/compExpr-old.test:	Updated tests with changed behavior due
+	to addition of bignums.
+
+	* tests/expr.test:      Portable tests expr-46.13-18 [Bug 1341368]
+
+	* generic/tclPkg.c:	Corrected inconsistencies in the value returned
+	* tests/pkg.test:	by Tcl_PkgRequire(Ex) so that the returned
+	values will always agree with what is stored in the package database.
+	This way repeated calls to Tcl_PkgRequire(Ex) have the same results.
+	Thanks to Hemang Lavana. [Bug 1162286].
+
+2005-11-08  Donal K. Fellows  <donal.k.fellows@manchester.ac.uk>
+
+	* generic/tclTrace.c (TraceVarEx): Factor out heart of Tcl_TraceVar2
+	(TclTraceVariableObjCmd,TraceVarProc): Use the new internal API to
+	arrange for the clientData to be cleaned up at the same time as the
+	rest of the main trace record. This simplifies the code a bit at the
+	same time.
+
+2005-11-07  Miguel Sofer  <msofer@users.sf.net>
+
+	* tests/trace.test (trace-13.2-4): added tests to detect leak, see [Bug
+	1348775]. The recently added trace-8.9 test is now 13.4.
+
+2005-11-07  Donal K. Fellows  <donal.k.fellows@manchester.ac.uk>
+
+	* tests/dict.test (dict-19.2): arrange for the stress testing code to
+	only stress test the dict code and not the trace code as well. [Bug
+	1342858]
+
+2005-11-05  Miguel Sofer  <msofer@users.sf.net>
+
+	* tests/trace.test (trace-8.9): added test to detect leak, see [Bug
+	1348775].
+
+2005-11-04  Pat Thoyts  <patthoyts@users.sourceforge.net>
+
+	* win/tclWinPort.h:  Applied [Patch 1267871] by Matt Newman for
+	* win/tclWinPipe.c:  extended error code support on Windows.
+	* tests/exec.test:   Tests for extended error codes.
+	* generic/tclPipe.c: Permit long codes (platform macros permitting).
+
+2005-11-04  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclBinary.c:
+	* generic/tclCmdAH.c:
+	* generic/tclCmdIL.c:
+	* generic/tclCmdMZ.c:
+	* generic/tclDictObj.c:
+	* generic/tclExecute.c:
+	* generic/tclIOCmd.c:
+	* generic/tclLink.c:
+	* generic/tclTest.c:
+	* generic/tclVar.c: fix for [Bug 1334947]. The functions TclPtrSetVar,
+	Tcl_ObjSetVar2 and Tcl_SetVar2Ex now always consume the newValuePtr
+	argument - i.e., they will free a 0-refCount object if they failed to
+	set the variable. Fixed all callers in the core.
+
+2005-11-04  Kevin Kenny  <kennykb@acm.org>
+
+	* generic/tclGetDate.y: Added abbreviations for the Korean
+	* library/clock.tcl:    timezone. [Patch 1298737]
+	* generic/tclDate.c:    Regenerated.
+
+	* tools/findBadExternals.tcl: Added this script, which locates external
+	symbols that do not begin with 'Tcl' or 'tcl' and hence might be in
+	conflict with other link libraries. Thanks to George Peter Staplin for
+	the idea and the initial version of the script. [Bug 1263012]
+
+	* unix/Makefile.in: Trimmed a bunch of fat out of the tommath/
+	directory in 'make dist'. [RFE 1333318]
+
+	* unix/tcl.m4: Added code to enable [load] on LynxOS. Thanks to
+	heidibr@users.sf.net for the patch. [Bug 1163896]. Removed the last
+	vestiges of GNU dld from the Unix build [RFE 1071992].
+
+	* unix/tclLoadDld.c: Removed.
+	* unix/configure: Regenerated.
+
+2005-11-04  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclInt.h:
+	* generic/tclNamesp.c:
+	* generic/tclVar.c:
+	* tests/trace.test: fix for [Bugs 1338280/1337229]; changed to use the
+	same approach as the 8.4 patch in the ticket (i.e., removed the patch
+	committed on 2005-31-10).
+
+2005-11-03  Pat Thoyts  <patthoyts@users.sourceforge.net>
+
+	* win/tclWin32Dll.c:   Applied [Patch 1256872] to provide unicode
+	* win/tclWinConsole.c: support in the console on suitable systems.
+	* win/tclWinInt.h:     Patch by Anton Kovalenko
+
+2005-11-02  Pat Thoyts  <patthoyts@users.sourceforge.net>
+
+	Applied [Patch 1096916] to support building with MSVC 8.
+	* generic/regerror.c: Avoid use of reserved word.
+	* generic/tcl.h:      Select the right Tcl_Stat structure
+	* generic/tclDate.c:  Casts to handle 64 bit time_t case.
+	* tests/env.test:     Include essential envvar on Win32
+	* win/nmakehlp.c:     Handle new return codes.
+	* win/makefile.vc:    Use the selected options.
+	* win/rules.vc:       Check options are applicable
+	* win/tclWinPort.h:   Disable deprecated function warnings
+	* win/tclWinSock.c:   Provide default value to avoid warning.
+	* win/tclWinTime.c:   Add casts to handle 64bit time_t type.
+
+2005-11-01  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclTrace.c (TclCheckExecutionTraces): Corrected mistaken
+	assumption that all command traces are set at the script level.
+	Report/fix from Jacques H. de Villiers. [Bug 1337941]
+
+	* tests/unixNotfy.test (1.1,2):	Update error message whitespace to
+	match changes in code.
+
+	* tests/expr-old.test (expr-32.52): Use int(.) to restrict result of
+	left shift to the C long range.
+
+	* expr.test (expr-46.13): Added test that illustrates shortcoming of
+	[Patch 1340260].
+
+2005-10-31  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclNamesp.c: fix for [Bugs 1338280/1337229]. Thanks Don.
+	* tests/trace.test: fix duplicate test numbers
+
+2005-10-31  Donal K. Fellows  <donal.k.fellows@manchester.ac.uk>
+
+	* win/tclWinSerial.c (SerialSetOptionProc): Cleaned up option parsing
+	to produce more informative error messages and separate error and
+	non-error code paths better.
+	* tests/ioCmd.test (iocmd-8-19): Updated.
+
+2005-10-29  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclTrace.c (TraceVarProc): [Bug 1337229], partial fix. Ensure
+	that a second call with TCL_TRACE_DESTROYED does not lead to a second
+	call to Tcl_EventuallyFree(). It is still true that that second call
+	should not happen, so the bug is not completely fixed.
+	* tests/trace.test (test-18.3-4): added tests for [Bug 1337229] and
+	[Bug 1338280].
+
+2005-10-23  Vince Darley  <vincentdarley@sourceforge.net>
+
+	* generic/tclFileName.c: fix to memory leak in glob [Bug 1335006] Obj
+	leak detection and patch by Eric Melbardis.
+
+	* tests/fCmd.test:
+	* win/tclWinFile.c: where appropriate windows API is available, try to
+	set 'nlink' and 'ino' stat fields (previously they were always 0). [Bug
+	1325803]
+
+2005-10-22  Miguel Sofer  <msofer@users.sf.net>
+
+	* tests/foreach.test (foreach-8.1): added test for [Bug 1189274]
+
+2005-10-22  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclExecute.c (INST_INCR_*): fixed [Bug 1334570]. Obj leak
+	detection and patch by Eric Melbardis.
+
+2005-10-21  Kevin B. Kenny  <kennykb@acm.org>
+
+	* generic/tclStrToD.c (RefineApproximation): Plugged a memory leak
+	where two intermediate results were not freed on one return path. [Bug
+	1334461]. Thanks to Eric Melbardis for the patch.
+
+2005-10-21  Donal K. Fellows  <dkf@users.sf.net>
+
+	* doc/binary.n: Clarify that virtually all code that uses the 'h'
+	format in [binary scan] should be using the 'H' format instead. It is
+	nearly always a bug to use the other!
+
+2005-10-20  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclListObj.c (TclLsetFlat):
+	* tests/lset.test (lset-10.3): fixed handling of unshared lists with
+	shared sublists, [Bug 1333036] reported by neuronstorm.
+
+2005-10-19  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclIORChan.c (PassReceivedError,PassReceivedErrorInterp):
+	Fix crash caused by passing -1 as the length to TclNewStringObj(). Only
+	Tcl_NewStringObj (the function call, not the macro) handles that sort
+	of thing correctly. This makes ioCmd.test pass again.
+
+2005-10-19  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclClock.c:		Removed some dead code.
+	* generic/tclCmdIL.c:
+	* generic/tclCompCmds.c:
+	* generic/tclDictObj.c:
+	* generic/tclExecute.c:
+	* generic/tclLiteral.c:
+	* generic/tclParseExpr.c:
+	* generic/tclScan.c:
+	* generic/tclUtil.c:
+	* generic/tclVar.c:
+
+2005-10-19  Donal K. Fellows  <donal.k.fellows@manchester.ac.uk>
+
+	* generic/tclIORChan.c: General cleanup, removing checks that are
+	unnecessary due to the general contracts of other functions in the
+	core, converting to using ANSI declarations, etc. Note that nearly the
+	whole file has changed, but it is often just cosmetic.
+
+2005-10-19  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclExecute.c (INST_DICT_APPEND, INST_DICT_LAPPEND): fixed
+	faulty peephole optimisation that can cause crashes, [Bug 1331475]
+	reported by Aric Bills.
+
+2005-10-18  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclExecute.c: Added optimization for I32L64 systems to avoid
+	using bignums to perform int multiplies. The improvement shows up most
+	dramatically in tclbench's matrix.bench.
+
+2005-10-15  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclExecute.c:	Restored some optimizations of the
+	INST_INCR_SCALAR1_IMM opcode.
+
+2005-10-14  Zoran Vasiljevic  <vasiljevic@users.sourceforge.net>
+
+	* generic/tclIO.c (Tcl_ClearChannelHandlers): removed change dated
+	2005-10-04 (see below). Look into [Bug 1323992] for detailed
+	discussion.
+
+	* generic/tcl.h: Fixed bad definition of CRTEXPORT which should have
+	been CRTIMPORT rather. This broke compilation of generic/tclMain.c and
+	was probably introduced by mistake while applying the fix for [Bug
+	1256937] below.
+
+2005-10-14  Kevin Kenny  <kennykb@acm.org>
+
+	* generic/tclExecute.c (TclIncrObj, TclExecuteByteCode): Tidied up a
+	couple of infelicitous do {...} while(0) constructs.
+
+2005-10-14  Pat Thoyts  <patthoyts@users.sourceforge.net>
+
+	* generic/tcl.h:     Fix for [Bug 1256937] - correctly decorate
+	* generic/tclMain.c: imported functions from msvcrt in static builds.
+
+2005-10-13  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* tests/format.test: "Forward"-port of test updates relating to [Bug
+	1284178]. The bug itself was fixed by TIP#237.
+
+2005-10-13  Zoran Vasiljevic  <vasiljevic@users.sourceforge.net>
+
+	* generic/tclIO.c (Tcl_ClearChannelHandlers): temporary ifdef
+	TCL_THREADS changes done to de-activate pending event processing when
+	channel is being closed/cutted.
+
+2005-10-13  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclExecute.c:	Removed obsolete use of NO_ERRNO_H.
+	* tools/man2tcl.c:
+	* unix/tcl.m4:
+	* unix/tclConfig.h.in:
+	* win/configure.in:
+
+	* unix/configure:	autoconf-2.59
+	* win/configure:
+
+	* compat/tclErrno.h:	Removed obsolete file.
+
+	* generic/tclStrToD.c (TclParseNumber): Missing goto caused crash when
+	parsing "Na". [Bug 1325833]
+
+2005-10-12  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclExecute.c (GetNumberFromObj):	Restored some lost
+	optimizations for empty string values. We avoid cost of a call to
+	TclParseNumber just to tell us an empty string isn't a number.
+
+2005-10-12  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclPathObj.c (SetFsPathFromAny): TclGetString macro must not
+	be combined with post-increment arguments. [Bug 1325099]
+
+2005-10-12  Kevin Kenny  <kennykb@acm.org>
+
+	* generic/tclExecute.c (Tcl_ExecuteByteCode, TclIncrObj): Several
+	common cases inlined in hopes of gaining a little performance in [incr]
+
+2005-10-10  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclCompCmds.c: New convenience macro CompileTokens().
+
+2005-10-10  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclExecute.c: Corrections to the NO_WIDE_TYPE build. Also
+	added missing "break" to a switch that broke wide XOR operations.
+
+2005-10-10  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* generic/tclInterp.c (DeleteScriptLimitCallback)
+	(SetScriptLimitCallback): Improve the interlocking between the script
+	limit callback record and the hash table of current such records, to
+	prevent crashes in callbacks that create callbacks.
+	(Tcl_LimitSetTime): Reset the correct flag. Problem reported by
+	Nicolas Castagne <castagne@imag.fr> on comp.lang.tcl
+
+2005-10-10  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclExecute.c: Fixing errors in last commit. (Two commits, the
+	second removes wrong comment).
+
+2005-10-09  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclBasic.c:
+	* generic/tclExecute.c:
+	* generic/tclStrToD.c:
+	* generic/tclStringObj.c: Initialise variables to avoid compiler
+	warnings ([Bug 1320818] among others).
+
+2005-10-08  Don Porter  <dgp@users.sourceforge.net>
+
+	TIP#237 IMPLEMENTATION
+
+	[kennykb-numerics-branch] Resynchronized with the HEAD; at this
+	checkpoint [-rkennykb-numerics-branch-20051008], the HEAD and
+	kennykb-numerics-branch contain identical code.
+
+	[kennykb-numerics-branch]	Merge updates from HEAD
+
+	* generic/tclExecute.c: More performance macros and special handling of
+	the wide integer type for performance on 32-bit systems.
+
+2005-10-07  Don Porter  <dgp@users.sourceforge.net>
+
+	[kennykb-numerics-branch]
+
+	* generic/tclExecute.c:	Macro GetNumberFromObj() is version of
+	TclGetNumberFromObj() that saves a function call for common uses.
+
+	* generic/tclInt.h:	Made #undef NO_WIDE_TYPE the default on 32-bit
+	systems. Being able to use 64-bit values without leaping to mp_int
+	should help with performance.
+
+	* generic/tclObj.c:	Bug fixes in the #undef NO_WIDE_TYPE
+	* generic/tclExecute.c:	configuration.
+
+	* generic/tclExecute.c: Improved performance of comparison opcodes and
+	bitwise operations and removed yet more dead code.
+
+2005-10-07  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* unix/tclUnixFCmd.c (TraverseUnixTree): Adjust 2004-11-11 change to
+	* tests/fCmd.test (fCmd-20.2):           account for NFS special files
+	with a readdir rewind threshold. [Bug 1034337]
+
+2005-10-06  Don Porter  <dgp@users.sourceforge.net>
+
+	[kennykb-numerics-branch]
+
+	* generic/tclExecute.c:	Improved performance of INST_RSHIFT and
+	INST_LSHIFT.
+
+2005-10-05  Don Porter  <dgp@users.sourceforge.net>
+
+	[kennykb-numerics-branch]
+
+	* generic/tclExecute.c: Improved performance of INST_MULT, INST_DIV,
+	INST_ADD, and INST_SUB and replaced a "goto... label" with a "break
+	from loop" in TclIncrObj() and removed some dead code.
+
+2005-10-05  Andreas Kupries  <andreask@activestate.com>
+
+	* generic/tclPipe.c (TclCreatePipeline): Fixed [Bug 1109294]. Applied
+	the patch provided by David Gravereaux.
+
+	* doc/CrtChannel.3: Fixed [Bug 1104682], by application of David
+	Welton's patch for it, and added a note about wideSeekProc.
+
+	* generic/tclIORChan.c (RcClose): Removed unreachable panic/return
+	statements. This fixes the remainder of [Bug 1286256].
+
+2005-10-05  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* tests/env.test (env-6.1):
+	* win/tclWinPort.h: define USE_PUTENV_FOR_UNSET 1
+	* generic/tclEnv.c (TclSetEnv, TclUnsetEnv): add USE_PUTENV_FOR_UNSET
+	to existing USE_PUTENV define to account for various systems that have
+	putenv(), but can't unset env vars with it. Note difference between
+	Windows and Linux for actually unsetting the env var (use of '=').
+	Correct the resizing of the environ array. We assume that we are in
+	full ownership, but that's not correct.[Bug 979640]
+
+2005-10-04  Don Porter  <dgp@users.sourceforge.net>
+
+	[kennykb-numerics-branch]
+	* generic/tclExecute.c: Updated TclIncrObj() to more efficiently add
+	native long integers. Also updated IllegalExprOperandType and the
+	INST_UMINUS, INST_UPLUS, INST_BITNOT, and INST_TRY_CVT_TO_NUMERIC
+	sections for performance.
+
+	* generic/tclBasic.c: Updated more callers to make use of
+	TclGetNumberFromObj. Removed some dead code.
+
+2005-10-04  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* win/tclWinSerial.c (SerialSetOptionProc): free argv [Bug 1067708]
+
+	* tests/http.test:              do not URI encode -._~ according
+	* library/http/http.tcl (init): to RFC3986. [Bug 1182373] (aho)
+
+	* unix/tclLoadShl.c (TclpDlopen): use DYNAMIC_PATH on second shl_load
+	only. [Bug 1204237]
+
+	* doc/scan.n: scan %[] requires "one or more chars" [Bug 1277503]
+
+	* tests/winFile.test (getuser): allow valid Windows usernames. [Bug
+	1311285]
+
+	* generic/tclParse.c (Tcl_ParseCommand): add code that recognizes {} in
+	addition to {expand} for word expansion (make with
+	-DALLOW_EMPTY_EXPAND).
+
+2005-10-04  Zoran Vasiljevic  <vasiljevic@users.sourceforge.net>
+
+	* generic/tclIO.c (Tcl_ClearChannelHandlers): now deletes any
+	outstanding timer for the channel. Also, prevents events still in the
+	event queue from triggering on the current channel.
+
+	* generic/tclTimer.c (Tcl_DeleteTimerHandler): bail out early if passed
+	NULL argument.
+
+2005-10-03  Don Porter  <dgp@users.sourceforge.net>
+
+	[kennykb-numerics-branch]
+
+	* generic/tclBasic.c:	Re-implemented ExprRoundFunc and
+	ExprEntierFunc to use TclGetNumberFromObj.
+
+	* generic/tclInt.h:	Added new routine TclGetNumberFromObj to
+	* generic/tclObj.c:	provide efficient access to the actual
+	internal rep of a numeric Tcl_Obj without conversions.
+
+2005-10-03  Kevin Kenny  <kennykb@acm.org>
+
+	* tools/loadICU.tcl:  Changed the file names of message catalogs to
+			      lowercase.
+	* tools/makeTestCases.tcl:
+	* library/tzdata/*:   Olson's tzdata2005n.tar.gz. Includes new DST
+	rules for USA and a number of changes to other locales.
+	* tests/clock.test:   Regenerated for new US DST rules.
+
+2005-09-30  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclMain.c: Separate encoding conversion of command line
+	arguments from list formatting. [Bug 1306162].
+
+2005-09-30  Don Porter  <dgp@users.sourceforge.net>
+
+	[kennykb-numerics-branch]
+
+	* generic/tclStringObj.c:	Bug fix: Missing cast to large enough
+	integral size before << operations led to broken [format %llx] results.
+	Thanks to Robert Henry for reporting the bug.
+
+2005-09-29  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* doc/mathfunc.n:   implementation for TIP #255, expr min/max
+	* library/init.tcl:
+	* tests/info.test, tests/expr-old.test:
+
+2005-09-27  Don Porter  <dgp@users.sourceforge.net>
+
+	[kennykb-numerics-branch]
+
+	* generic/tcl.h:	Changed name of the new Tcl_Obj intrep field
+	* generic/tclObj.c:	from "bignumValue" to "ptrAndLongRep" as
+	* generic/tclProc.c:	described in TIP 237, and more suitable for
+	other more general uses.
+
+2005-09-27  Donal K. Fellows  <donal.k.fellows@manchester.ac.uk>
+
+	* tests/binary.test (binary-14.18): Added test for [Bug 1116542] though
+	the bug itself was already fixed by unrelated changes.
+
+2005-09-26  Kevin Kenny  <kennykb@acm.org>
+
+	[kennykb-numerics-branch] Merge updates from HEAD.
+
+2005-09-26  Kevin Kenny  <kennykb@acm.org>
+
+	* libtommath/:                   Updated to release 0.36.
+	* generic/tommath.h:             Regenerated.
+	* generic/tclTomMathInterface.h: Added ten missing aliases for mp_*
+	functions to avoid namespace pollution in Tcl's exported symbols. [Bug
+	1263012]
+
+2005-09-23  Don Porter  <dgp@users.sourceforge.net>
+
+	[kennykb-numerics-branch]
+
+	* unix/Makefile.in:	Added -DMP_PREC=4 switch to all compiles so
+	* win/Makefile.in:	that minimum memory requirements of mp_int's
+	* win/makefile.vc:	will not be quite so large. [Bug 1299153].
+
+	* generic/tclStrToD.c:	Fixed memory leak. [Bug 1299803].
+	* generic/tclObj.c:
+
+2005-09-20  Don Porter  <dgp@users.sourceforge.net>
+
+	[kennykb-numerics-branch]
+
+	* generic/tclExecute.c:	Revise TclIncrObj() to call
+	Tcl_GetBignumAndClearObj.
+
+	* generic/tcl.decls:	Add Tcl_GetBignumAndClearObj.
+	* generic/tclObj.c:
+
+	* generic/tclDecls.h:	make genstubs
+	* generic/tclStubInit.c:
+
+2005-09-16  Don Porter  <dgp@users.sourceforge.net>
+
+	[kennykb-numerics-branch]
+
+	* generic/tclInt.h:		 Added TclBNInitBigNumFromWideInt() so
+	* generic/tclTomMathInterface.c: that every caller isn't required to
+	duplicate the sign logic to use the unsigned interface.
+
+	* generic/tclBasic.c:	Reduce the number of places where Tcl intrudes
+	* generic/tclExecute.c:	into the internal format details of the mp_int
+	* generic/tclObj.c:	struct.
+	* generic/tclStrToD.c:
+	* generic/tcLStringObj.c:
+
+	* generic/tclTomMath.h:	Added mp_cmp_d to routines from libtommath
+	* unix/Makefile.in:	used by Tcl.
+	* win/Makefile.in:
+	* win/makefile.vc:
+
+	* libtommath/bn_mp_add_d.c: Bug fix. For mp_add_d(&a, d, &c), when &a
+	has the value -d, then the value &c computed should be zero, but
+	mp_add_d was producing an inconsistent zero value with a sign field of
+	MP_NEG, something like a value of -0, which other routines in
+	libtommath can't handle.
+
+	* generic/tclExecute.c:	Dropped all creation of "bigOne" values and
+	just use tommath routines that accept the value "1" directly.
+
+2005-09-15  Miguel Sofer  <msofer@users.sf.net>
+
+	* doc/ParseCmd.3: copy/paste fix [Bug 1292427]
+
+2005-09-15  Don Porter  <dgp@users.sourceforge.net>
+
+	[kennykb-numerics-branch]	Merge updates from HEAD.
+
+	* generic/tclStringObj.c (TclAppendFormattedObjs):	Revision to
+	eliminate one round of string copying.
+
+	* generic/tclBasic.c:	More callers of TclObjPrintf and
+	* generic/tclCkalloc.c:	TclFormatToErrorInfo.
+	* generic/tclCmdMZ.c:
+	* generic/tclExecute.c:
+	* generic/tclIORChan.c:
+	* generic/tclMain.c:
+	* generic/tclProc.c:
+	* generic/tclTimer.c:
+	* generic/tclUtil.c:
+	* unix/tclUnixFCmd.c
+
+	* unix/configure:	autoconf-2.59
+
+2005-09-15  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* unix/tcl.m4 (SC_TCL_EARLY_FLAGS): Added extra hack to allow Tcl to
+	transparently open large files on RHEL 3. [Bug 1287638]
+
+2005-09-14  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclStringObj.c:	Bug fixes: ObjPrintfVA needed to
+	support "*" fields and needed to interpret precision limits on %s
+	conversions as a maximum number of bytes, not Tcl_UniChars, to take
+	from the (char *) argument.
+
+	* generic/tclBasic.c:	Updated several callers to use
+	* generic/tclCkalloc.c: TclFormatToErrorInfo() and/or
+	* generic/tclCmdAH.c:	TclObjPrintf().
+	* generic/tclCmdIL.c:
+	* generic/tclCmdMZ.c:
+	* generic/tclDictObj.c:
+	* generic/tclExecute.c:
+	* generic/tclIORChan.c:
+	* generic/tclIOUtil.c:
+	* generic/tclNamesp.c:
+	* generic/tclProc.c:
+
+	* library/init.tcl:	Keep [unknown] in sync with errorInfo
+	formatting rules.
+
+2005-09-13  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclBasic.c:	First caller of TclFormatToErrorInfo.
+
+	* generic/tclInt.h:		Using stdarg.h conventions, add more
+	* generic/tclStringObj.c:	fixed arguments to TclFormatObj() and
+	TclObjPrintf(). Added new routine TclFormatToErrorInfo().
+
+	* generic/tcl.h:	Explicitly standardized on the use of stdarg.h
+	* generic/tclBasic.c:	conventions for functions with variable number
+	* generic/tclInt.h:	of arguments. Support for varargs.h has been
+	* generic/tclPanic.c:	implicitly gone for some time now. All
+	* generic/tclResult.c:	TCL_VARARGS* macros purged from Tcl sources,
+	* generic/tclStringObj.c:	leaving only some deprecated #define's
+	* tools/genStubs.tcl:	in tcl.h for the sake of older extensions.
+
+	* generic/tclDecls.h:	make genstubs
+
+	* doc/AddErrInfo.3:	Replaced all documented requirement for use of
+	* doc/Eval.3:		TCL_VARARGS_START() with requirement for use of
+	* doc/Panic.3:		va_start().
+	* doc/SetResult.3:
+	* doc/StringObj.3:
+
+2005-09-12  Don Porter  <dgp@users.sourceforge.net>
+
+	[kennykb-numerics-branch]	Merge updates from HEAD.
+
+	* generic/tclCmdAH.c:		Added support for the "ll" width
+	* generic/tclStringObj.c:	specifier to [format].
+
+	* generic/tclStringObj.c (TclAppendFormattedObjs):	Bug fix: make
+	sure %ld formats force the collection of a wide value, when the value
+	could be a different long.
+
+2005-09-09  Andreas Kupries  <andreask@activestate.com>
+
+	* generic/tclIORChan.c (RcDecodeEventMask): Added missing type
+	declaration for the parameter 'mask'. This fixes the [Bug 1286256]. The
+	other warning can be removed only by removing the panic/return code.
+
+2005-09-09  Don Porter  <dgp@users.sourceforge.net>
+
+	[kennykb-numerics-branch]	Merge updates from HEAD.
+
+2005-09-09  Kevin Kenny  <kennykb@acm.org>
+
+	* generic/tclStringObj.c:  Added two missing casts to silence messages
+	from MSVC6.
+
+2005-09-09  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclInt.h:		New internal routine TclObjPrintf()
+	* generic/tclStringObj.c:	is similar to TclFormatObj() but
+	accepts arguments in non-Tcl_Obj format.
+
+	* generic/tclInt.h:		New internal routines TclFormatObj()
+	* generic/tclStringObj.c:	and TclAppendFormattedObjs() to offer
+	sprintf()-like means to append to Tcl_Obj. Work in progress toward
+	[RFE 572392].
+
+	* generic/tclCmdAH.c:	Compiler directive NEW_FORMAT when #define'd
+	directs the [format] command to be implemented in terms of the new
+	TclAppendFormattedObjs() routine.
+
+2005-09-08  Donal K. Fellows  <donal.k.fellows@manchester.ac.uk>
+
+	TIP#254 IMPLEMENTATION
+
+	* generic/tclLink.c (LinkTraceProc,ObjValue): Added many new of C var
+	* generic/tcl.h:			      to link to, making it
+	* doc/LinkVar.3:			      easier to seamlessly
+	* generic/tclTest.c (TestlinkCmd):	      couple C code and Tcl
+	* tests/link.test:			      scripts in an
+	application. [Patch 1242844]
+
+2005-09-07  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclUtf.c (Tcl_UniCharToUtf):	Corrected handling of negative
+	* tests/utf.test (utf-1.5):	    Tcl_UniChar input value. Incorrect
+	handling was producing byte sequences outside of Tcl's legal internal
+	encoding. [Bug 1283976].
+
+2005-09-06  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* generic/tclInt.h (List): Added flag to keep track of whether a list
+	* generic/tclListObj.c:    with a string rep is provably canonical.
+	* generic/tclUtil.c (Tcl_ConcatObj):  Do efficient concatenation and
+	* generic/tclBasic.c (Tcl_EvalObjEx): evaluation when the list is
+	canonical, and not just when the list is pure. This should make the
+	"pure list" hacking introduced in 8.3 much more robust.
+
+2005-09-05  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* generic/tclObj.c (pendingObjDataKey): Added missing 'static' to stop
+	symbol from leaking outside the Tcl library. [Bug 1263012]
+
+2005-09-02  Don Porter  <dgp@users.sourceforge.net>
+
+	[kennykb-numerics-branch]
+
+	* generic/tclScan.c:	Bug fix: The %o, %x, %i formats of [scan] must
+	not accept any 0b or 0o prefixes. [scan $s %o] must continue to work
+	even with KILL_OCTAL enabled.
+
+	* generic/tclInt.h:	Added TCL_PARSE_SCAN_PREFIXES to the flags
+	* generic/tclStrToD.c:	accepted by TclParseNumber.
+
+2005-09-01  Andreas Kupries  <andreask@activestate.com>
+
+	* unix/tclUnixSock.c (InitializeHostName): Synchronized use of static
+	modifier in declaration and definition of function.
+
+	* unix/tclUnixChan.c (FileTruncateProc): Synchronized use of static
+	modifier in declaration and definition of function.
+
+	* generic/tclResult.c (ReleaseKeys): Synchronized use of static
+	modifier in declaration and definition of function.
+
+	* generic/tclListObj.c (NewListIntRep): Synchronized use of static
+	modifier in declaration and definition of function.
+
+	* generic/tclEncoding.c (InitializeEncodingSearchPath): Synchronized
+	use of static modifier in declaration and definition of function.
+
+	* generic/tclEncoding.c (FillEncodingFileMap): Synchronized use of
+	static modifier in declaration and definition of function.
+
+	* generic/tclIORChan.c (RcNewHandle): Synchronized use of static
+	modifier in declaration and definition of function.
+
+2005-09-01  Don Porter  <dgp@users.sourceforge.net>
+
+	[kennykb-numerics-branch]
+
+	* generic/tclObj.c:	TclParseNumber calls meant to parse an integer
+	value now pass the TCL_PARSE_INTEGER_ONLY flag.
+
+	* generic/tclScan.c:	Extended [scan] to accept the %lld, %llo, %llx,
+	and %lli formats. Numeric scanning is now done via TclParseNumber calls
+
+	* generic/tclInt.h:	Extended TclParseNumber to accept new flag
+	* generic/tclStrToD.c:	values TCL_PARSE_INTEGER_ONLY,
+	TCL_PARSE_OCTAL_ONLY, and TCL_PARSE_HEXIDECIMAL_ONLY, to give caller
+	more control over the parsing rules.
+
+2005-08-31  Vince Darley  <vincentdarley@sourceforge.net>
+
+	* doc/FileSystem.3:
+	* unix/tclUnixFile.c:
+	* windows/tclWinFile.c: clarify that Tcl_FSMatchInDirectory may be
+	called with a NULL interpreter, and fix the code so this is allowed.
+	Tcl's core itself (tclEncoding.c:FillEncodingFileMap()) calls this
+	with a NULL interpreter.
+
+2005-08-30  Don Porter  <dgp@users.sourceforge.net>
+
+	[kennykb-numerics-branch]
+
+	* generic/tclObj.c:	Extended bignum support to include bignums so
+	large they will not pack into a Tcl_Obj. When they outgrow Tcl's string
+	rep length limits, a panic will result.
+
+	* generic/tclTomMath.h:	Added mp_sqrt to routines from
+	* unix/Makefile.in:	libtommath used by Tcl.
+	* win/Makefile.in:
+	* win/makefile.vc:
+
+	* generic/tclBasic.c:	Extended sqrt(.) so that range covers the
+	entire double range, accepting as many bignums in the domain as that
+	will allow.
+
+2005-08-29  Andreas Kupries  <andreask@activestate.com>
+
+	* library/tm.tcl (::tcl::tm::roots): Accepted Don Porter's patch for
+	[Bug 1189657]. Syncs the implementation to the specification (TIP #189)
+
+2005-08-29  Don Porter  <dgp@users.sourceforge.net>
+
+	[kennykb-numerics-branch]	Merge updates from HEAD.
+
+	* generic/tclBasic.c:	Restored round(.) to the Tcl 8.4 rules.
+
+2005-08-29  Kevin Kenny  <kennykb@acm.org>
+
+	* generic/tclBasic.c (ExprMathFunc): Restored "round away from zero"
+	* tests/expr.test (expr-46.*):       behaviour to the "round" function.
+	Added test cases for the behavior, including the awkward case of a
+	number whose fractional part is 1/2-1/2ulp. [Bug 1275043]
+
+2005-08-26  Andreas Kupries  <andreask@activestate.com>
+
+	* generic/tclIO.c: Moved Tcl_{Cut,Splice}Channel to
+	{Cut,Splice}Channel for internal use, and created new public functions
+	for Tcl_{Cut,Splice}Channel which walk the whole stack of
+	transformations and invoke the necessary thread actions. Added code to
+	Tcl_(Un)StackChannel to properly invoke the thread actions when pushing
+	and popping transformations on/from a channel.
+
+2005-08-26  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* generic/tclNamesp.c (NamespaceEnsembleCmd): Reset the result after
+	creating an ensemble to clear any result object sharing (potentially
+	caused by delete traces) so that we can safely return the name of the
+	ensemble. Previously, this caused crashes in Snit's test suite.
+
+2005-08-25  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* generic/tclListObj.c (UpdateStringOfList): Stop uncontrolled and
+	unsafe crashes from happening when working with very large string
+	representations. [Bug 1267380]
+
+	* generic/tclExecute.c (TEBC:INST_DICT_LAPPEND): Stop dropping a
+	duplicated object on the floor, which was a memory leak (and a wrong
+	result too). Thanks to Andreas Kupries for reporting this.
+
+2005-08-25  Don Porter  <dgp@users.sourceforge.net>
+
+	[kennykb-numerics-branch] Merge updates from HEAD
+
+	* generic/tclExecute.c: Bug fix. INST_RSHIFT: shift of negative values
+	produced incorrect results.
+
+	* generic/tclExecute.c: Bug fix. INST_*SHIFT opcodes stack management.
+	[expr 0<<6] should be 0, not 6.
+
+	* generic/tclBasic.c: Extended the domain of round(.) to all non-Inf,
+	non-NaN doubles, using bignums for the result as needed.
+
+2005-08-24  Andreas Kupries  <andreask@activestate.com>
+
+	TIP#219 IMPLEMENTATION
+
+	* doc/SetChanErr.3: ** New File **. Documentation of the new channel
+	API functions.
+	* generic/tcl.decls:  Stub declarations of the new channel API.
+	* generic/tclDecls.h: Regenerated
+	* generic/tclStubInit.c:
+
+	* tclIORChan.c: ** New File **. Implementation of the reflected
+	channel.
+	* generic/tclInt.h: Integration of reflected channel and new error
+	* generic/tclIO.c:  propagation into the generic I/O core.
+	* generic/tclIOCmd.c:
+	* generic/tclIO.h:
+	* library/init.tcl:
+
+	* tests/io.test:    Extended testsuite.
+	* tests/ioCmd.test:
+	* tests/chan.test:
+	* generic/tclTest.c:
+	* generic/tclThreadTest.c:
+
+	* unix/Makefile.in: Integration into the build machinery.
+	* win/Makefile.in:
+	* win/Makefile.vc:
+
+2005-08-24  Kevin Kenny  <kennykb@acm.org>
+
+	* generic/tclStrToD.c (Tcl_DoubleDigits): Fixed the corner cases of
+	* tests/binary.test (binary-65.*)         formatting floating point
+	numbers with the largest and smallest possible significands, and added
+	test cases for them.
+
+2005-08-24  Kevin Kenny  <kennykb@users.sourceforge.net>
+
+	[kennykb-numerics-branch]
+
+	* generic/tclExecute.c: Corrected some TRACE bugs that prevented
+	compilation with --enable-symbols=all.
+	* generic/tclStrToD.c: Revised commentary to prepare for a renaming of
+	the file, removed some dead code, and fixed a bug where
+	TclBignumToDouble failed on huge negative numbers.
+	* tests/binary.test (binary-65.*): Added missing 'ieeeFloatingPoint'
+	to large/small significand tests.
+	* tests/expr.test (expr-45.*) Added missing braces around expressions.
+
+2005-08-24  Don Porter  <dgp@users.sourceforge.net>
+
+	[kennykb-numerics-branch]
+
+	* generic/tclBasic.c:	Revised implementation of the ceil(.) and
+	* generic/tclInt.h:	floor(.) math functions in light of the
+	* generic/tclStrToD.c:	revised comparison operators, so that it is
+	always true that ($x <= ceil($x)) and ($x >= floor($x)). The simple
+	approach of "convert to double and call ceil() or floor()" could not
+	guarantee that.
+
+	* generic/tclExecute.c:	Bug fix: TclBignumToDouble return -Inf when
+	appropriate. Removed declarations of removed routines.
+
+	* generic/tclExecute.c: Revised the type promotion rules of the
+	comparison operators so that they form proper equivalence classes over
+	the set of numeric strings.
+
+2005-08-23  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* unix/configure.in:
+	* win/configure: Regen.
+	* win/configure.in: Update minimum autoconf version to 2.59.
+
+2005-08-23  Kevin Kenny  <kennykb@users.sourceforge.net>
+
+	[kennykb-numerics-branch]
+
+	* generic/tclCmdMZ.c (Tcl_StringObjCmd):
+	* generic/tclInt.h:
+	* generic/tclObj.c (Tcl_GetBooleanFromObj, SetDoubleFromAny,
+	Tcl_GetLongFromObj, Tcl_GetWideIntFromObj, Tcl_GetBignumFromObj):
+	* generic/tclParseExpr.c (GetLexeme):
+	* generic/tclScan.c (Tcl_ScanObjCmd):
+	* generic/tclStrToD.c (TclParseNumber):
+	* tests/binary.test (binary-62.1-65.7):
+	* tests/expr.test (expr-40.1-42.1):
+	* scan.test (scan-14.1,14.2):
+	Modified Tcl_ParseNumber to accept an argument to force interpretation
+	as decimal, and modified [scan] to use it. Corrected a bug where Not a
+	Number with hexadecimal information bits returned consistently
+	incorrect values. #ifdef-ed out some code that is needed only for IBM
+	hexadecimal floating point. Fixed bugs in code to handle the corner
+	cases of smallest and largest significands. Added test cases to improve
+	test coverage in generic/tclStrToD.c. Added test cases for 0b notation
+	(TIP #114). Removed TclStrToD, and the static functions that it calls,
+	which are now dead code (TclParseNumber now does all input
+	floating-point conversions.)
+
+2005-08-23  Don Porter  <dgp@users.sourceforge.net>
+
+	[kennykb-numerics-branch]
+
+	* generic/tclStrToD.c:	Bug fix: set shift magnitude properly whether
+	we're expanding to mp_int type or not.
+
+	* generic/tclExecute.c:	Bug fix: ACCEPT_NAN under INST_UMINUS.
+
+	* generic/tclStrToD.c:	New macros TIP_114_FORMATS and KILL_OCTAL to
+	configure acceptance of 0o and 0b numbers and rejection of "leading
+	zero as octal".
+
+	* generic/tclBasic.c:	Re-used the guts of int(.) and wide(.) math
+	functions to perform conversions in OldMathFuncProc.
+
+	* generic/tclBasic.c:	Support for ACCEPT_NAN.
+	* generic/tclExecute.c:
+
+	* generic/tclInt.decls:	Restored TclExprFloatError to internal stubs
+	* generic/tclBasic.c:	table, and moved definition back to
+	* generic/tclExecute.c:	tclExecute.c from tclBasic.c to handle #undef
+	ACCEPT_NAN.
+
+	* generic/tclIntDecls.h:	make genstubs
+	* generic/tclStubInit.c:
+
+	* generic/tclInt.h:	New internal macros TclIsNaN and TclIsInfinite
+	* generic/tclBasic.c:	replace the IS_NAN and IS_INF macros scattered
+	* generic/tclExecute.c:	here and there.
+	* generic/tclObj.c:
+	* generic/tclStrToD.c:
+	* generic/tclUtil.c:
+
+2005-08-22  Daniel Steffen  <das@users.sourceforge.net>
+
+	* unix/tclConfig.h.in: autoheader-2.59.
+
+2005-08-22  Don Porter  <dgp@users.sourceforge.net>
+
+	[kennykb-numerics-branch]
+
+	* generic/tclInt.h:	New ACCEPT_NAN macro to mark code that
+	* generic/tclCmdAH.c:	supports or disables accepting of the NaN
+	* generic/tclExecute.c:	value at various points.
+	* generic/tclLink.c:
+
+	* generic/tclStrToD.c:	Bug fix. Parsing of +/- Infinity was reversed.
+
+	* generic/tclTestObj.c:	Disabled unused [testconvertobj] command.
+
+	* generic/tclBasic:	Added [expr {entier(.)}]. Rewrote int(.) and
+	wide(.) to use the same guts, accepting all non-Inf doubles as
+	arguments.
+
+	* generic/tclInt.h:	New routine TclInitBignumFromDouble.
+	* generic/tclStrToD.c:	Modified to return code and write error
+	message.
+
+	* generic/tclInt.h:	TCL_WIDE_INT_IS_LONG implies NO_WIDE_TYPE.
+	* generic/tclObj.c:	Removed now unnecessary tests of the
+	* generic/tclStrToD.c:	TCL_WIDE_INT_IS_LONG definition.
+
+	* generic/tclInt.h:	New internal routine TclSetBignumIntRep
+	* generic/tclObj.c:	consolidates packing of bignum value into a
+	* generic/tclStrToD.c:	Tcl_Obj within one source code file.
+
+	* tests/expr.test:	Corrected the wideIs64bit constraint.
+	* tests/format.test:
+	* tests/scan.test:
+
+2005-08-21  Don Porter  <dgp@users.sourceforge.net>
+
+	[kennykb-numerics-branch]
+
+	* generic/tclInt.h:		Moved TclParseInteger to tclUtil.c and
+	* generic/tclParseExpr.c:	made it static.
+	* generic/tclUtil.c:
+
+	* generic/tclInt.decls:	Moved TclExprFloatError to tclBasic.c and made
+	* generic/tclBasic.c:	it static.
+	* generic/tclExecute.c:
+
+	* generitc/tclIntDecls.h:	make genstubs
+	* generic/tclStubInit.c:
+
+	* generic/tclExecute.c:	errno, IS_NAN, IS_INF, LLD no longer called in
+	this file; dropped/disabled support for them.
+
+	* generic/tclCompExpr.c:	errno no longer used in these files;
+	* generic/tclParseExpr.c:	dropped support "hack" for it.
+
+	* generic/tclStrToD.c:	Disabled out of date support "hack" for errno.
+
+	* generic/tclBasic.c:	Eliminated VerifyExprObjType. Initialize errno
+	to zero in OldMathFuncProc.
+
+2005-08-19  Don Porter  <dgp@users.sourceforge.net>
+
+	[kennykb-numerics-branch]
+
+	* generic/tclBasic.c:	Updated OldMathFuncProc and ExprAbsFunc to do
+	less invasion into numeric Tcl_Obj internals. Made ExprDoubleFunc,
+	ExprIntFunc, ExprWideFunc, and ExprRoundFunc bignum-aware. Revised
+	ExprSrandFunc error message.
+
+	* generic/tclProc.c:	Wrapped a few tclWideIntType uses in
+	* generic/tclCmdMZ.c:	#ifndef NO_WIDE_TYPE.
+
+	* generic/tclInt.h:	#define'd NO_WIDE_TYPE.
+
+	* generic/tclVar.c:	Replaced TclPtrIncrVar and TclPtrIncrWideVar
+	* generic/tclInt.h:	with TclPtrIncrObjVar and replaced TclIncrVar2
+	* generic/tclInt.decls:	and TclIncrWideVar2 with TclIncrObjVar2. New
+	routines call on TclIncrObj to do the work.
+
+	* generic/tclIntDecls.h:	make genstubs
+	* generic/tclStubInit.c:
+
+	* generic/tclCmdIL.c:	Rework Tcl_IncrObjCmd and the INST_*INCR*
+	* generic/tclExecute.c:	opcodes to use the new routines.
+
+2005-08-18  Don Porter  <dgp@users.sourceforge.net>
+
+	[kennykb-numerics-branch]
+
+	* generic/tclExecute.c:		Fixed string rep invalidation bug in
+	* tests/dict.test (dict-11.17):	INST_DICT_INCR_IMM rewrite.
+
+	* generic/tclDictObj.c:	DictIncrCmd rewrite to use TclIncrObj.
+
+	* generic/tclInt.h:	TclIncrObj static -> internal
+	* generic/tclExecute.c:
+
+2005-08-17  George Peter Staplin  <GeorgePS@XMission.com>
+
+	* generic/tclBasic.c: eliminate a namespace clash caused by
+	BuiltinFuncTable not being static.
+
+	* generic/tclObj.c: fix a namespace clash caused by a missing
+	static for pendingObjData.
+
+2005-08-17  Kevin Kenny  <kennykb@acm.org>
+
+	* generic/tclEvent.c (Tcl_Finalize): Removed a copy-and-paste accident
+	that caused a (mostly harmless) double finalize of the load and
+	filesystem subsystems.
+	* tests/clock.test: Eliminated the bad test clock-43.1, and split
+	clock-50.1 into two tests, with a more permissive check on the error
+	message for an out-of-range value.
+
+2005-08-17  Kevin Kenny  <kennykb@users.sourceforge.net>
+
+	[kennykb-numerics-branch]
+
+	* generic/tclBasic.c (Tcl_Expr{Long,Double}{,Obj}): Updated to
+	* generic/tclTest.c:                                deal with
+	* tests/expr-old.test:                              bignums (well,
+	* tests/expr.test:                                  mostly).
+	Added a missing "errno=0;" in ExprUnaryFunc so that spurious error
+	returns aren't detected.
+	Added test cases for Tcl_Expr* and Tcl_Expr*Obj because there was very
+	poor test coverage in those areas.
+	* generic/tclParseExpr.c: Reworked parsing of numbers to call
+	TclParseNumber rather than trying to do things locally.
+	* generic/tclStrToD.c: Corrected a comment. Changed so that *endPtrPtr
+	does not include any trailing whitespace.
+
+2005-08-17  Don Porter  <dgp@users.sourceforge.net>
+
+	[kennykb-numerics-branch]
+
+	* generic/tclExecute.c: New routine TclIncrObj to centralize the
+	increment operation needed in many places. Updated INST_DICT_INCR_IMM
+	to make use of it.
+
+2005-08-16  Don Porter  <dgp@users.sourceforge.net>
+
+	[kennykb-numerics-branch]
+
+	* generic/tclExecute.c:	Made bit shifting opcodes and INST_MOD
+	bignum-aware.
+
+	* tests/scan.test:	Making << bignum-aware means that repeated
+	* tests/string.test:	left shifting cannot turn a positive into a
+	negative. Revised [int_range] and [largest_int] utility commands in the
+	test suite that relied on that happening. Without revision they became
+	infinite loops.
+
+	* generic/tclExecute.c:	Made binary bitwise opcodes bignum-aware.
+
+	* generic/tclTomMath.h:	Added mp_or and mp_xor to routines from
+	* unix/Makefile.in:	libtommath used by Tcl.
+	* win/Makefile.in:
+	* win/makefile.vc:
+
+2005-08-15  Don Porter  <dgp@users.sourceforge.net>
+
+	[kennykb-numerics-branch]	Updates from HEAD.
+	* generic/tclExecute.c:	More revisions to IllegalExprOperandType.
+	Merged INST_BITNOT with INST_UMINUS and make it bignum-aware according
+	to the rule: ~a = -a - 1. Disabled unused code and noted more TODOs.
+
+	* generic/tclInt.decls: Disabled TclLooksLikeInt() and all callers.
+	* generic/tclUtil.c:
+	* generic/tclCompCmds.c:
+
+	* generic/tclBasic.c:	Rewrite of VerifyExprObjType().
+
+	* generic/tclIntDecls.h:	make genstubs
+	* generic/tclStubInit.c:
+
+	* generic/tclExecute.c: Updated execution of comparison bytecodes to
+	be bignum-aware, routing string compares through INST_STR_CMP.
+
+2005-08-14  Don Porter  <dgp@users.sourceforge.net>
+
+	[kennykb-numerics-branch]
+
+	* generic/tclExecute.c: Updated execution of arithmetic bytecodes to
+	be bignum-aware, and to allow calculations on NaN to produce a NaN
+	result. INST_UMINUS updated to call mp_neg.
+
+	* generic/tclTomMath.h:	Added mp_and, mp_expt_d, and mp_neg to
+	* unix/Makefile.in:	routines from libtommath used by Tcl.
+	* win/Makefile.in:
+	* win/makefile.vc:
+
+2005-08-13  Don Porter  <dgp@users.sourceforge.net>
+
+	[kennykb-numerics-branch]
+
+	* generic/tclObj.c:	Extended Bignum auto-narrowing to auto-narrow
+	to tclWideIntType when appropriate; this helps keep things working as
+	the bytecode execution code is migrated to supporting bignums.
+
+	* generic/tclExecute.c:	Major overhaul of IllegalExprOperandType.
+	Changed several TclNewFooObj() calls to more logically appropriate
+	ones. Added several TODO comments marking opportunies for future work.
+	Made more use of the eePtr->constants. Made INST_UMINUS bignum aware.
+
+2005-08-12  Don Porter  <dgp@users.sourceforge.net>
+
+	[kennykb-numerics-branch]
+
+	* generic/tclExecute.c: Simplify doCondJump. Use eePtr->constants as
+	result of INST_DICT_NEXT, INST_LAND, and INST_LOR. Separate INST_LNOT
+	from INST_UMINUS and simplify.
+
+2005-08-12  Kevin Kenny  <kennykb@acm.org>
+
+	* generic/tclClock.c (MktimeObjCmd):
+	* library/clock.tcl (GetSystemTimeZone, LoadZoneinfoFile)
+	(ReadZoneinfoFile):
+	* tests/clock.test (clock-50.1):
+	Added functionality to read /etc/localtime if it exists, so that Tcl's
+	time can track system time on Linux even if TZ is not set. Changed
+	::tcl::clock::Mktime to check for failure, and added a test case that
+	mimics failure but is really success.
+
+2005-08-11  Don Porter  <dgp@users.sourceforge.net>
+
+	[kennykb-numerics-branch]
+
+	* generic/tclExecute.c: Rewrite of INST_LAND/INST_LOR to take advantage
+	of loss of "pure double" issues. Merged INST_UPLUS with
+	INST_TRY_CVT_TO_NUMERIC and updated to use improved rules for impure
+	"double"s as well.
+
+	* generic/tclStrToD.c:	Restored conditional generation of
+	tclWideIntType values by TclParseNumber so that Tcl's not completely
+	broken while bignum calculation support is incomplete. The NO_WIDE_TYPE
+	macro can be used to disable this.
+
+	* generic/tclBasic.c (ExprAbsFunc): First pass making [expr abs(.)]
+	bignum-aware.
+
+2005-08-11  Kevin Kenny  <kennykb@acm.org>
+
+	* generic/tclEvent.c:         Eliminated the USE_THREAD_STORAGE option
+	* generic/tclInt.h:           (which is on in every build generated by
+	* generic/tclThread.c:        by the standard configurator).
+	* generic/tclThreadStorage.c: Eliminated the code for thread specific
+	* unix/configure:             data without USE_THREAD_STORAGE and
+	* unix/tcl.m4:                radically refactored the code for
+	* unix/tclConfig.h.in:        USE_THREAD_STORAGE so that it has fewer
+	* unix/tclUnixThrd.c:         dependencies on the order of
+	* win/configure:              finalization. (Also, made 'make
+	* win/Makefile.in:            distclean' on Windows clean just a little
+	* win/rules.vc:               bit cleaner.)
+	* win/tcl.m4:
+	* win/tclWinThrd.c:
+
+2005-08-10  Don Porter  <dgp@users.sourceforge.net>
+
+	[kennykb-numerics-branch]
+
+	* generic/tclTomMath.h:	Added mp_shrink, mp_to_unsigned_bin,
+	* unix/Makefile.in:	mp_to_unsigned_bin_n, and mp_unsigned_bin_size
+	* win/Makefile.in:	to routines from libtommath used by Tcl.
+	* win/makefile.vc:
+
+	* generic/tommath.h:	make gentommath_h
+
+	* generic/tclObj.c:	Substantial rewrite to make all number parsing
+	flow through TclParseNumber(). Also established the NO_WIDE_TYPE and
+	BIGNUM_AUTO_NARROW #ifdef's to help track the assumptions of different
+	portions of the code.
+
+	* generic/tclInt.h:	Added NO_WIDE_TYPE #ifdefs
+
+2005-08-10  Kevin Kenny  <kennykb@acm.org>
+
+	* generic/tclEvent.c (Tcl_Finalize): Pushed Tcl_FinalizeLoad and
+	Tcl_ResetFilesystem down after Tcl_FinalizeThreadAlloc because we can't
+	unload DLL's until after their TSD keys are finalized. (Note that we'll
+	still see aborts if an unloaded DLL has TSD - that still needs to be
+	fixed.
+
+	* tests/compExpr-old.test (compExpr-3.8): Made tests conditional on
+	* tests/expr.test (expr-3.8):             'unix' because they get
+	stack overflows on Win32 threaded builds,
+
+2005-08-09  Vince Darley  <vincentdarley@users.sourceforge.net>
+
+	* generic/tclPathObj.c: fix to [file rootname] bug in optimized code
+	path reported on comp.lang.tcl.
+
+2005-08-08  Don Porter  <dgp@users.sourceforge.net>
+
+	[kennykb-numerics-branch]
+
+	* generic/tclObj.c:	Replaced some goto's with loops and started
+	use of BIGNUM_AUTO_NARROW and NO_WIDE_TYPE.
+
+2005-08-06  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* generic/tclThreadStorage.c: Stop exposing the guts of the thread
+	storage system through the internal stubs table. Client code should
+	always use the standard API.
+
+2005-08-05  Don Porter  <dgp@users.sourceforge.net>
+
+	[kennykb-numerics-branch]
+	* generic/tclObj.c:	Rewrote Tcl_GetDoubleFromObj().
+
+2005-08-05  Donal K. Fellows  <dkf@users.sf.net>
+
+	* unix/tclUnixInit.c (localeTable): Solaris uses a non-standard name
+	for the cp1251 charset. Thanks to Victor Wagner for reporting this.
+	[Bug 1252475]
+
+2005-08-05  Kevin Kenny  <kennykb@users.sourceforge.net>
+
+	* win/makefile.vc: Removed unused file ldAout.tcl.
+	* win/makefile.bc: [Bug 1244361]
+
+	* tests/binary.test: Cleaned up testing for scanning of NaN. [Bug
+	1246264]
+
+	* generic/tclBasic.c (ExprAbsFunc): Added code to handle the corner
+	* tests/expr.test (expr-38.1):      case of applying 'abs' to the
+	smallest 32-bit integer. [Bug 1241572]
+
+2005-08-04  Andreas Kupries  <andreask@activestate.com>
+
+	* generic/tclIO.c (CloseChannel): Fixed comment nit, added apparently
+	missing word to complete a sentence.
+
+	* generic/tclObj.c (Tcl_DbDecrRefCount): Fixed whitespace nit in panic
+	message.
+
+2005-08-04  Don Porter  <dgp@users.sourceforge.net>
+
+	[kennykb-numerics-branch] Updated from HEAD
+
+	* generic/tclObj.c:	Rewrote Tcl_GetBooleanFromObj() and supporting
+	routines to make use of TclParseNumber. This reduces the potential
+	number of times a string value must be scanned.
+
+	* generic/tclObj.c:	Simplified routines that manage the typeTable.
+	Deleted the UpdateStringOfBoolean() routine, that can never be called.
+
+2005-08-03  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclCompExpr.c:	Untangled some dependencies in the
+	* generic/tclEvent.c:		order of finalization routines.
+	* generic/tclInt.h:		[Bug 1251399]
+	* generic/tclObj.c:
+
+2005-08-02  Don Porter	<dgp@users.sourceforge.net>
+
+	[kennykb-numerics-branch] Updated from HEAD
+
+2005-07-30  Daniel Steffen  <das@users.sourceforge.net>
+
+	* unix/tclLoadDyld.c (TclpDlopen, TclpLoadMemory): workarounds for
+	bugs/changes in behaviour in Mac OS X 10.4 Tiger.
+
+2005-07-29  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclCmdIL.c (InfoGlobalsCmd): Even in high-speed mode, still
+	have to take care with non-existant variables. [Bug 1247135]
+
+2005-07-28  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* win/README: Update link to msys_mingw8.zip.
+
+2005-07-28  Don Porter	<dgp@users.sourceforge.net>
+
+	* tests/compExpr-old.test:	Still more conversion of "nonPortable"
+	* tests/error.test:		tests into tests with constraints that
+	* tests/expr-old.test:		describe the limits of their
+	* tests/expr.test:		portability. Also more consolidation
+	* tests/fileName.test:		of constraint synonyms.
+	* tests/format.test:		wideis64bit, 64bitInts => wideIs64bit
+	* tests/get.test:		wideIntegerUnparsed => wideIs32bit
+	* tests/load.test:		wideIntExpressions => wideBiggerThanInt
+	* tests/obj.test:
+	* tests/parseExpr.test:		Dropped "roundOffBug" constraint that
+	* tests/string.test:		protected from buggy sprintf.
+
+2005-07-28  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclPipe.c (TclCreatePipeline): Arrange for POSIX systems to
+	* unix/tclUnixPipe.c (TclpOpenFile):	 use the O_APPEND flag for
+	* tests/exec.test (exec-19.1):		 files opened in a pipeline
+	like ">>this". Note that Windows cannot support such access; there is
+	no equivalent flag on the handle that can be set at the kernel-call
+	level. The test is unix-specific in every way. [Bug 1245953]
+
+2005-07-27  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclUtil.c:	Converted the $::tcl_precision value to be kept
+	per-thread to prevent different threads from stomping on each others'
+	formatting prescriptions.
+
+	***POTENTIAL INCOMPATIBILITY*** Multi-threaded programs that set the
+	value of ::tcl_precision will now have to set it in each thread.
+
+	* tests/expr.test:	Consolidated equivalent constraints into
+	* tests/fileName.test:	single definitions and (more precise) names:
+	* tests/get.test:	longis32bit, 32bit, !intsAre64bit => longIs32bit
+	* tests/listObj.test:	empty => emptyTest; winOnly => win
+	* tests/obj.test:	intsAre64bit => longIs64bit
+	Also updated some "nonPortable" tests to use constraints that mark
+	precisely what about them isn't portable, so the tests can run where
+	they work.
+
+	* library/init.tcl ([unknown]): Corrected return code handling in the
+	portions of [unknown] that expand incomplete commands during
+	interactive operations. [Bug 1214462].
+
+2005-07-26  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* unix/configure: Regen.
+	* unix/configure.in: Check for a $prefix/share directory and add it the
+	the package if found. This will check for Tcl packages in
+	/usr/local/share when Tcl is configured with the default dist install.
+	[Patch 1231015]
+
+2005-07-26  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclBasic.c (Tcl_CallWhenDeleted):	Converted to use
+	per-thread counter, rather than a process global one that required
+	mutex protection. [RFE 1077194]
+
+	* generic/tclNamesp.c (TclTeardownNamespace):	Re-ordering so that
+	* tests/trace.test (trace-34.4):	command delete traces fire
+	while the command still exists. [Bug 1047286]
+
+2005-07-24  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* unix/configure: Regen.
+	* unix/tcl.m4 (SC_PROG_TCLSH, SC_BUILD_TCLSH):
+	* win/configure: Regen.
+	* win/tcl.m4 (SC_PROG_TCLSH, SC_BUILD_TCLSH): Split confused search
+	for tclsh on PATH and build and install locations into two macros.
+	SC_PROG_TCLSH searches just the PATH. SC_BUILD_TCLSH determines the
+	name of the tclsh executable in the Tcl build directory. [Bug 1160114]
+	[Patch 1244153]
+
+2005-07-23  Don Porter	<dgp@users.sourceforge.net>
+
+	* library/auto.tcl:	Updates to the Tcl script library to make use
+	* library/history.tcl:	of Tcl 8.4 features. Forward port of
+	* library/init.tcl:	appropriate portions of [Patch 1237755].
+	* library/package.tcl:
+	* library/safe.tcl:
+	* library/word.tcl:
+
+2005-07-23  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* tests/string.test: Add string is tests for functionality that was not
+	tested.
+	* win/README: Update msys + mingw URL. Remove old Cygwin + mingw info.
+
+2005-07-23  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclExecute.c (INST_DICT_*): stop 2 compiler warnings for
+	uninitialised variables.
+
+2005-07-23  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclExecute.c (TEBC:INST_DICT_INCR_IMM): Fix the incrementor
+	to work correctly with wide values.
+
+2005-07-21  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclCompCmds.c (TclCompileDictCmd): First run at a compiler
+	* generic/tclExecute.c (TclExecuteByteCode): for dictionaries. Also
+	added an instruction to support 'finally'-like clauses, exposed more of
+	the dict guts to the rest of the core, and defined a few tests to
+	exercise more obscure parts of the compiler's operation that were bugs
+	during development.
+
+2005-07-21  Kevin B. Kenny  <kennykb@acm.org>
+
+	* library/ldAout.tcl (***REMOVED***):	Removed support for ancient
+	* unix/configure:			BSD's, IRIX 4, RISCos and
+	* unix/Makefile.in:			Ultrix. Removed two files whose
+	* unix/tcl.m4:				code is used only on those
+	* unix/tclLoadAout.c (***REMOVED***):	antique platforms.
+
+	***POTENTIAL INCOMPATIBILITY*** if anyone actually uses those
+	platforms; it is to be noted though, that an error in the installer has
+	actually not caused a necessary file to be installed on those platforms
+	in several releases, and nobody's complained.
+
+2005-07-16  Kevin B. Kenny  <kennykb@acm.org>
+
+	* generic/tclStrToD.c (RefineResult):  Plugged a stupid memory leak in
+	RefineResult (called from Tcl_StrToD). [Tk Bug 1227781]
+
+2005-07-15  Kevin B. Kenny  <kennykb@acm.org>
+
+	* generic/tclClock.c (TclClockLocaltimeObjCmd,ThreadSafeLocalTime):
+	* library/clock.tcl (GuessWindowsTimeZone, ClearCaches):
+	* tests/clock.test (clock-49.1, clock-49.2):
+	Handle correctly the case where localtime() returns NULL to report a
+	conversion error. Also handle the case where the Windows registry
+	contains timezone values that can be mapped to a tzdata file name but
+	the corresponding file does not exist or is corrupted, by falling back
+	on a Posix timezone string instead; this last case will avoid calls to
+	localtime() in starpacks on Windows. [Bug 1237907]
+
+2005-07-14  Donal K. Fellows  <donal.k.fellows@manchester.ac.uk>
+
+	* generic/tclCompile.c: Update to follow style guidelines.
+	(TclPrintInstruction): Reorganize to do better printing out of bytecode
+	with far fewer "special hacks" for particular opcodes.
+	* generic/tclCompile.h: Requires two new opcode types.
+
+2005-07-13  Don Porter	<dgp@users.sourceforge.net>
+
+	* unix/tclUnixSock.c:	Use a ProcessGlobalValue to store the value
+	* win/tclWinSock.c:	returned by Tcl_GetHostName() ([info
+	hostname]). Also re-order initialization of the value on Windows to
+	favor GetComputerName() over gethostname() as a source of the
+	information.
+
+2005-07-12  Kevin Kenny  <kennykb@acm.org>
+
+	[kennykb-numerics-branch] Updated from HEAD
+
+	* generic/tclCmdMZ.c (Tcl_StringObjCmd):
+	* generic/tclInt.h:
+	* generic/tclObj.c (Tcl_GetDoubleFromObj, SetDoubleFromAny)
+	(Tcl_GetIntFromObj, SetIntOrWideFromAny):
+	* generic/tclStrToD.c (TclParseNumber, etc.):
+	* tclTomMathInterface.c (TclBNInitBignumFromWideUInt):
+	* tests/obj.test (obj-1.1, obj-2.2, obj-3.1, obj-3.2):
+
+	Initial attempt at an implementation of TIP #249, comprising a unified
+	parser and modifications to the Tcl_Get*FromObj routines to use it.
+	Further integration of the parser is necessary and planned.
+
+2005-07-12  Donal K. Fellows  <dkf@users.sf.net>
+
+	* doc/lsearch.n: Clarify documentation of -exact option; wording was
+	open to misinterpretation by non-English speakers.
+
+2005-07-11  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclExecute.c: General style cleanup.
+
+2005-07-08  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* generic/tclExecute.c (TclExecuteByteCode): Reimplement long and wide
+	type integer division and modulus operations so that the smallest and
+	largest integer values are handled properly. The divide operation is
+	more efficient since it no longer does a modulus or negation and only
+	checks for a remainder when the quotient will be a negative number.
+	The modulus operation is now a bit more complex because of a number of
+	special cases dealing with the smallest and largest integers.
+	* tests/expr.test: Add test cases for division and modulus operations
+	on the smallest and largest integer values for 32 and 64 bit types.
+	[Patch 1230205]
+
+2005-07-06  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclLink.c:	Simplified LinkTraceProc [Bug 1208108].
+
+2005-07-05  Don Porter	<dgp@users.sourceforge.net>
+
+	* unix/Makefile.in:	Purged use of TCLTESTARGS [RFE 1161550].
+
+	* generic/tclUtil.c:	Converted TclFormatInt() into a macro.
+	* generic/tclInt.decls:	[RFE 1194015]
+	* generic/tclInt.h:
+
+	* generic/tclIntDecls.h:	make genstubs
+	* generic/tclStubInit.c:
+
+	* generic/tclNamesp.c:	Allow for [namespace import] of a command
+	* tests/namespace.test:	over a previous [namespace import] of itself
+	without throwing an error. [RFE 1230597]
+
+2005-07-04  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclDictObj.c (DictForCmd, DictFilterCmd): Interlocking of
+	dictionary internal representations is now done in the core of the dict
+	iterator. Purge the last attempts at doing it at a higher level as they
+	didn't work and were no longer needed.
+
+2005-07-01  Zoran Vasiljevic  <vasiljevic@users.sourceforge.net>
+
+	* unix/tclUnixNotfy.c: protect against spurious wake-ups while waiting
+	on the condition variable when tearing down the notifier thread [Bug
+	1222872].
+
+2005-06-28  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* generic/tclExecute.c (TclExecuteByteCode): When parsing an integer
+	operand for a unary minus expression operator, check for a wide integer
+	that is actually LONG_MIN. If found, convert back to a long int type.
+	* tests/expr.test: Add constraint for 32bit long int type and 64bit
+	wide int type. Add tests that parse the smallest/largest long int and
+	wide int values.
+
+2005-06-24  Kevin Kenny  <kennykb@acm.org>
+
+	* generic/tclEvent.c (Tcl_Finalize):
+	* generic/tclInt.h:
+	* generic/tclPreserve.c (TclFinalizePreserve): Changed the finalization
+	logic so that Tcl_Preserve finalizes after exit handlers run; a lot of
+	code called from Tk's exit handlers presumes that Tcl_Preserve will
+	still work even from an exit handler.
+
+2005-06-24  Don Porter	<dgp@users.sourceforge.net>
+
+	* library/auto.tcl:	Make file safe to re-[source] without
+	destroying registered auto_mkindex_parser hooks.
+
+2005-06-23  Kevin Kenny  <kennykb@acm.org>
+
+	* win/tclWinChan.c: More rewriting of __asm__ blocks that implement
+	* win/tclWinFCmd.c: SEH in GCC, because mingw's gcc 3.4.2 is not as
+	forgiving of violations committed by the old code and caused panics.
+	[Bug 1225957]
+
+2005-06-23  Daniel Steffen  <das@users.sourceforge.net>
+
+	* tools/tcltk-man2html.tcl: fixed useversion glob pattern to accept
+	multi-digit patchlevels.
+
+2005-06-22  Don Porter	<dgp@users.sourceforge.net>
+
+	* win/tclWinFile.c: Potential buffer overflow. [Bug 1225571] Thanks to
+	Pat Thoyts for discovery and fix.
+
+2005-06-22  Kevin Kenny  <kennykb@acm.org>
+
+	* generic/tclInt.h:			    Changed the finalization
+	* generic/tclEvent.c (Tcl_Finalize):	    logic to defer the
+	* generic/tclIO.c (TclFinalizeIOSubsystem): shutdown of the pipe
+	* unix/tclUnixPipe.c (TclFinalizePipes):    management until after all
+	* win/tclWinPipe.c (TclFinalizePipes):	    channels have been closed,
+	in order to avoid a situation where the Windows PipeCloseProc2 would
+	re-establish the exit handler after exit handlers had already run,
+	corrupting the heap. [Bug 1225727] Also corrected a potential read of
+	uninitialized memory in PipeClose2Proc [Bug 1225044]
+
+2005-06-21  Andreas Kupries  <andreask@activestate.com>
+
+	* generic/tclInt.h: Followup to change made on 2005-06-18 by Daniel
+	Steffen. There are compilers (*) who error out on the redefinition of
+	WORDS_BIGENDIAN. We have to undef the previous definition (on the
+	command line) first to make this acceptable. (*): AIX native.
+
+2005-06-21  Kevin B. Kenny  <kennykb@acm.org>
+
+	* generic/tclFileName.c: Changed [file split] and [file join] to treat
+	Windows drive letters similarly to ~ syntax and make sure that they
+	appear with "./" in front when they are in intermediate components of
+	the path. [Bug 1194458]
+	* tests/fileName.test: Added test for the above bug.
+
+2005-06-21  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclBasic.c:	Added missing walk of the list of active
+	* generic/tclTrace.c:	traces to cleanup references to traces being
+	* generic/tclInt.h:	deleted. [Bug 1201035] Made the walk of the
+	* tests/trace.test (trace-34.*): active trace list aware of the
+	direction of trace scanning, so the proper correction can be made.
+	[Bug 1224585]
+
+2005-06-21  Donal K. Fellows  <dkf@users.sf.net>
+
+	* unix/tcl.m4 (SC_ENABLE_SYMBOLS): Only enable the 'compile' special
+	debugging feature when requested in configure.in; removes irrelevant
+	junk from the configure files of extensions that use Tcl's tcl.m4.
+
+2005-06-20  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclCompile.h (INST_PUSH_RETURN_OPTIONS): New opcode to allow
+	* generic/tclCompCmds.c (TclCompileCatchCmd):	   compilation of
+	* generic/tclCompile.c:				   TIP#90 catch [Bug
+	* generic/tclExecute.c (TclExecuteByteCode):	   1219112]
+
+	* generic/tclCompCmds.c (TclCompileSwitchCmd): Ensure we spill to the
+	command form in all cases where it generates an error.
+
+2005-06-20  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* generic/tclCmdMZ.c (Tcl_SwitchObjCmd): Generate an error if a mode
+	argument like -exact is passed more than once to the switch command.
+	The previous implementation silently accepted invalid switch
+	invocations like [switch -exact -glob $str ...].
+	* tests/for.test: Check some error cases when invoking continue and
+	break inside a for loop next script.
+	* tests/switch.test: Add checks for shortened version of a mode
+	argument like -exact. Add test for more than one mode argument. Add
+	test for odd case of passing a variable as a body script.
+
+2005-06-18  Daniel Steffen  <das@users.sourceforge.net>
+
+	* generic/tclInt.h: ensure WORDS_BIGENDIAN is defined correctly with
+	fat compiles on Darwin (i.e. ppc and i386 at the same time), the
+	configure AC_C_BIGENDIAN check is not sufficient in this case because a
+	single run of the compiler builds for two architectures with different
+	endianness.
+
+	* unix/tcl.m4 (Darwin): add -headerpad_max_install_names to LDFLAGS to
+	ensure we can always relocate binaries with install_name_tool.
+
+	* unix/configure: autoconf-2.59
+
+2005-06-18  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* generic/tclCmdAH.c (Tcl_FormatObjCmd): Fix for [Bug 1154163]; only
+	* tests/format.test: insert 'l' modifier when it is needed.
+
+2005-06-17  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclTimer.c (AfterDelay): Split out the code to manage
+	synchronous-delay [after] commands.
+	* tests/interp.test (interp-34.10): Time limits and synch-delay [after]
+	did not mix well... [Bug 1221395]
+
+2005-06-14  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclBasic.c (Tcl_DeleteCommandFromToken): Only delete a
+	* tests/namespace.test (namespace-49.2): command from the hashtable on
+	reentrant processing if it has not been already deleted; at least three
+	deletes of the same command are possible. [Bug 1220058]
+	* generic/tclTrace.c (TraceCommandProc): Remove bogus error message
+	creation when traces trigger in situations where the command has
+	already been deleted.
+
+2005-06-13  Vince Darley  <vincentdarley@users.sourceforge.net>
+
+	* generic/tclFCmd.c: correct fix to file mkdir 2005-06-09 [Bug 1219176]
+
+2005-06-12  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclCompCmds.c: Factor out some common idioms into named forms
+	for greater clarity.
+
+2005-06-10  Donal K. Fellows  <dkf@users.sf.net>
+
+	* doc/chan.n: Fold in the descriptive parts of the documentation for
+	all the commands that [chan] builds on top of.
+
+2005-06-09  Vince Darley  <vincentdarley@users.sourceforge.net>
+
+	* generic/tclFCmd.c: fix to race condition in file mkdir [Bug 1217375]
+	* doc/glob.n: improve glob documentation [Bug 1190891]
+
+2005-06-09  Donal K. Fellows  <dkf@users.sf.net>
+
+	* doc/expr.n, doc/mathfunc.n: Fix minor typos [Bug 1211078] and add
+	mention of distinctly-relevant [namespace path] subcommand.
+
+2005-06-07  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclInt.h:		Reduced the Tcl_ObjTypes "index",
+	* generic/tclIndexObj.c:	"ensembleCmd", "localVarName", and
+	* generic/tclNamesp.c:		"levelReference" to file static scope.
+	* generic/tclProc.c:
+	* generic/tclVar.c:
+
+	* generic/tclObj.c:	Restored registration of the "procbody"
+	Tcl_ObjType, as required by the tclcompiler application.
+
+	* generic/tclDecls.h:		make genstubs
+	* generic/tclStubInit.c:
+
+2005-06-07  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclIO.c (Tcl_ChannelTruncateProc): Stop proliferation of
+	* generic/tcl.h:			     channel type versions
+	* doc/CrtChannel.3:			     following advice from AKu
+
+	Bump patchlevel to a4 to distinguish from a3 release.
+
+	* generic/tclInt.h (INTERP_TRACE_IN_PROGRESS): Add flag so the error
+	* generic/tclIndexObj.c (Tcl_WrongNumArgs):    messages from ensembles
+	* generic/tclIOCmd.c (Tcl_ReadObjCmd):	       can be correct.
+
+	TIP#208 IMPLEMENTATION
+
+	* library/init.tcl: Create the chan ensemble.
+	* tests/chan.test: Rudimentary test suite.
+	* doc/chan.n: General documentation.
+
+	TRUNCATION API (part of TIP#208)
+	* generic/tcl.h, generic/tcl.decls: Declaration of the API.
+	* doc/CrtChannel.3, doc/OpenFileChnl.3: Documentation of the API.
+	* generic/tclBasic.c (Tcl_CreateInterp): Create the mapping into Tcl.
+	* generic/tclIOCmd.c (TclChanTruncateObjCmd): Implementation of
+	Tcl-level truncation API.
+	* generic/tclIO.c (Tcl_TruncateChannel): Generic C-level truncation API
+	implementation.
+	* unix/tclUnixChan.c (FileTruncateProc): Basic implementation of
+	truncating driver.
+
+	* win/tclWinChan.c (FileTruncateProc): Added implementation of file
+	truncation for Windows.
+	* tests/chan.test (chan-15.2): Added real test of truncation.
+
+2005-06-06  Kevin B. Kenny  <kennykb@acm.org>
+
+	* win/tclWin32Dll.c: Corrected another buglet in the assembly code for
+	stack probing on Win32/gcc. [Bug 1213678]
+	* generic/tclObj,c: Added missing 'static' on definition of
+	UpdateStringOfBignum, and removed a 'switch' on a 'long long' operand
+	(which HP-UX native 'cc' seems unable to handle). [Bug 1215775]
+
+2005-06-04  Jeff Hobbs	<jeffh@ActiveState.com>
+
+	*** 8.5a3 TAGGED FOR RELEASE ***
+
+	* unix/Makefile.in (dist): add libtommath
+
+2005-06-03  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* library/parray.tcl (parray): Only generate the sorted list of element
+	names once. Thanks to Andreas Leitgeb for spotting this.
+
+2005-06-03  Daniel Steffen  <das@users.sourceforge.net>
+
+	* macosx/Makefile: fixed 'embedded' target.
+
+2005-06-02  Jeff Hobbs	<jeffh@ActiveState.com>
+
+	* unix/Makefile.in (html): add BUILD_HTML_FLAGS optional var
+	* tools/tcltk-man2html.tcl: add a --useversion to prevent confusion
+	when multiple Tcl source dirs exist.
+
+2005-06-01  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclBasic.c:	For compatibility with earlier Tcl releases,
+	* generic/tclResult.c:	when a command procedure simply does a
+	* generic/tclTest.c:	"return TCL_RETURN;" we must interpret that
+	* tests/result.test:	the same as
+	"return Tcl_SetReturnOptions(interp, Tcl_NewObj());"  [Bug 1209759].
+
+2005-06-01  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* generic/tclCompCmds.c (TclCompileSwitchCmd): Allow compilation of
+	-nocase -glob [switch]es (only one we know how to compile).
+
+	TIP#241 IMPLEMENTATION from Joe Mistachkin
+
+	* generic/tclCmdIL.c (Tcl_LsearchObjCmd, Tcl_LsortObjCmd):
+	* generic/tclCmdMZ.c (Tcl_SwitchObjCmd): Implementation of -nocase
+	option for [lsearch], [lsort] and [switch] commands.
+	* win/tclWinPort.h: Win uses nonstandard function names...
+	* tests/cmdIL.test, tests/lsearch.test, tests/switch.test: Tests
+	* doc/lsearch.n, doc/lsort.n, doc/switch.n: Docs
+
+	* generic/tclCompCmds.c (TclCompileLindexCmd): Compile the most common
+	case of [lindex] more efficiently.
+
+	* unix/tclUnixNotfy.c (Tcl_FinalizeNotifier): Pass the correct number
+	of arguments to Tcl_JoinThread.
+
+2005-05-31  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* unix/configure.in, unix/tcl.m4: Standardize generation of help
+	messages to always use AC_HELP_STRING and always (except for --with-tcl
+	and --with-tk, where the default is complex) say what the default is.
+
+2005-05-31  Zoran Vasiljevic  <vasiljevic@users.sourceforge.net>
+
+	* unix/tclUnixNotfy.c: the notifier thread is now created as joinable
+	thread and it is properly joined in Tcl_FinalizeNotifier. This is an
+	attempt to fix the [Bug 1082283].
+
+2005-05-30  Zoran Vasiljevic  <vasiljevic@users.sf.net>
+
+	* win/tclWinThrd.c: Fixed [Bug 1204064]
+
+2005-05-30  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	TIP #229 IMPLEMENTATION
+
+	* generic/tclNamesp.c (Tcl_FindCommand, TclResetShadowedCmdRefs)
+	(NamespacePathCmd, SetNsPath, UnlinkNsPath, TclInvalidateNsPath):
+	Implementation of the [namespace path] command and the command name
+	resolution engine.
+	* doc/info.n, doc/namespace.n: Doc updates.
+	* tests/namespace.test (namespace-51.*): Test updates.
+	* generic/tclResolve.c (BumpCmdRefEpochs, Tcl_SetNamespaceResolvers):
+	* generic/tclBasic.c (Tcl_CreateCommand, Tcl_CreateObjCommand): Ensure
+	that people don't see stale paths.
+	* generic/tclInt.h (Namespace, NamespacePathEntry): Structure defs.
+	* generic/tclCmdIL.c (InfoCommandsCmd): Updates to [info commands].
+
+2005-05-26  Daniel Steffen  <das@users.sourceforge.net>
+
+	* macosx/Makefile: moved & corrected EMBEDDED_BUILD check.
+
+	* unix/configure.in: corrected framework finalization to softlink stub
+	library to Versions/8.x subdir instead of Versions/Current.
+	* unix/configure: autoconf-2.59
+
+2005-05-25  Jeff Hobbs	<jeffh@ActiveState.com>
+
+	* generic/tclCmdMZ.c (Tcl_TimeObjCmd): add necessary cast
+
+2005-05-25  Don Porter	<dgp@users.sourceforge.net>
+
+	TIP#182 IMPLEMENTATION	[Patch 1165062]
+
+	* doc/mathfunc.n:	New built-in math function bool().
+	* generic/tclBasic.c:
+	* tests/expr.test:
+	* tests/info.test:
+
+2005-05-24  Don Porter	<dgp@users.sourceforge.net>
+
+	* library/init.tcl:	Updated [unknown] to be sure the [return]
+	* tests/init.test:	options from an auto-loaded command are seen
+	correctly by the caller.
+
+2005-05-24  Daniel Steffen  <das@users.sourceforge.net>
+
+	* tests/env.test: added DYLD_FRAMEWORK_PATH to the list of env vars
+	that need to be handled specially.
+
+	* macosx/Makefile:
+	* macosx/README:
+	* macosx/Tcl-Info.plist.in (new file):
+	* unix/Makefile.in:
+	* unix/configure.in:
+	* unix/tcl.m4:
+	* unix/tclUnixInit.c: moved all Darwin framework build support from
+	macosx/Makefile into the standard unix configure/make buildsystem, the
+	macosx/Makefile is no longer required to build Tcl.framework (but its
+	functionality is still available for backwards compatibility).
+	* unix/configure: autoconf-2.59
+
+	* generic/tclIOUtil.c (TclLoadFile):
+	* generic/tclInt.h:
+	* unix/tcl.m4:
+	* unix/tclLoadDyld.c: added support for [load]ing .bundle binaries in
+	addition to .dylib's: .bundle's can be [unload]ed (unlike .dylib's),
+	and can be [load]ed from memory, e.g. directly from VFS without needing
+	to be written out to a temporary location first. [Bug 1202209]
+	* unix/configure: autoconf-2.59
+	* unix/tclConfig.h.in: autoheader-2.59
+
+	* generic/tclCmdMZ.c (Tcl_TimeObjCmd): change [time] called with a
+	count > 1 to return a string with a float value instead of a rounded
+	off integer. [Bug 1202178]
+
+	* doc/expr.n:
+	* doc/string.n: fixed roff syntax complaints from 'make html'.
+
+2005-05-20  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclParseExpr.c:	Corrected parser to recognize all
+	boolean literals accepted by Tcl_GetBoolean, including prefixes like
+	"y" and "f", and to allow "eq" and "ne" as function names in the proper
+	context. [Bug 1201589].
+
+2005-05-19  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclBasic.c (TclEvalObjvInternal): Rewrite for greater
+	clarity; although 'goto' is Bad, the contortions you have to go through
+	to avoid it can be worse...
+
+2005-05-19  Daniel Steffen  <das@users.sourceforge.net>
+
+	* macosx/tclMacOSXNotify.c (Tcl_InitNotifier): fixed crashing CFRelease
+	of runLoopSource in Tcl_InitNotifier (reported by Zoran):
+	CFRunLoopAddSource doesn't CFRetain, so can only CFRelease the
+	runLoopSource in Tcl_FinalizeNotifier.
+
+2005-05-18  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclBasic.c (Tcl_ExprBoolean):	Rewrite as wrapper around
+	Tcl_ExprBooleanObj.
+
+	* generic/tclCmdMZ.c ([string is boolean/true/false]): Rewrite dropping
+	string-based Tcl_GetBoolean call, so that internal reps are kept for
+	subsequent quick boolean operations.
+
+	* generic/tclExecute.c:	Dropped most special handling of the "boolean"
+	Tcl_ObjType, since that type should now be rarely encountered.
+
+	* doc/BoolObj.3:	Rewrite of documentation dropping many details
+	about the internals of Tcl_Objs. Shorter documentation focuses on the
+	function and use of the routines.
+
+	* generic/tclInt.h:	Revision to the "boolean" Tcl_ObjType, so that
+	* generic/tclObj.c:	only string values like "yes" and "false" are
+	* tests/obj.test:	kept as the "boolean" Tcl_ObjType. The string
+	values "0" and "1" are kept as "int" Tcl_ObjType, which also produce
+	quick calls to Tcl_GetBooleanFromObj(). Since this internal change
+	means a Tcl_ConvertToType to a "boolean" Tcl_ObjType might not produce
+	a Tcl_Obj of type "boolean", the registration of the "boolean" type is
+	also removed.
+	***POTENTIAL INCOMPATIBILITY***
+	For callers of Tcl_GetObjType on the type name "boolean".
+
+2005-05-17  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclObj.c (TclInitObjSubsystem):	Removed the
+	* tests/listObj.test:	registration of the Tcl_ObjType's "list",
+	* tests/obj.test:	"procbody", "index", "ensembleCommand",
+	"localVarName", and "levelReference". The only reason to register a
+	Tcl_ObjType is to have it returned by Tcl_GetObjType, and the only
+	reason for that is to retrieve a (Tcl_ObjType *) to pass to
+	Tcl_ConvertToType(). None of the types above can support a
+	Tcl_ConvertToType() call; they panic. Better not to offer something
+	than to lead users into a panic.
+	***POTENTIAL INCOMPATIBILITY***
+	For callers of Tcl_GetObjType on the type names listed above.
+
+2005-05-15  Kevin Kenny  <kennykb@users.sourceforge.net>
+
+	* win/tclWin32Dll.c: conditioned definition of EXCEPTION_REGISTRATION
+	structures on HAVE_NO_SEH, to fix a bug in buildability on MSVC.
+
+2005-05-14  Daniel Steffen  <das@users.sourceforge.net>
+
+	* generic/tclInt.decls:
+	* generic/tclTest.c:
+	* generic/tclUtil.c:
+	* win/tclWin32Dll.c: fixed link error due to direct access by tclTest.c
+	to the MODULE_SCOPE tclPlatform global: renamed existing
+	TclWinGetPlatform() accessor to TclGetPlatform() and moved it to
+	generic code so that it can be used by on all platforms where
+	MODULE_SCOPE is enforced.
+
+	* macosx/tclMacOSXBundle.c:
+	* unix/tclUnixInit.c:
+	* unix/tcl.m4 (Darwin): made use of CoreFoundation API configurable and
+	added test of CoreFoundation availablility to allow building on ppc64,
+	replaced HAVE_CFBUNDLE by HAVE_COREFOUNDATION; test for availability of
+	Tiger or later OSSpinLockLock API.
+
+	* unix/tclUnixNotfy.c:
+	* unix/Makefile.in:
+	* macosx/tclMacOSXNotify.c (new file): when CoreFoundation is
+	available, use new CFRunLoop based notifier: allows easy integration
+	with other event loops on Mac OS X, in particular the TkAqua Carbon
+	event loop is now integrated via a standard tcl event source (instead
+	of TkAqua upon loading having to finalize the exsting notifier and
+	replace it with its custom version). [Patch 1202052]
+
+	* tests/unixNotfy.test: don't run unthreaded tests on Darwin since
+	notifier may be using threads even in unthreaded core.
+
+	* unix/tclUnixPort.h:
+	* unix/tcl.m4 (Darwin): test for thread-unsafe realpath during
+	configure, as Darwin 7 and later realpath is threadsafe.
+
+	* macosx/Makefile: enable configure caching.
+
+	* unix/configure.in: wrap tclConfig.h header in #ifndef _TCLCONFIG so
+	that it can be included more than once without warnings from gcc4.0 (as
+	happens e.g. when including both tclInt.h and tclPort.h)
+
+	* macosx/tclMacOSXBundle.c:
+	* unix/tclUnixChan.c:
+	* unix/tclLoadDyld.c:
+	* unix/tclUnixInit.c: fixed gcc 4.0 warnings.
+
+	* unix/configure: autoconf-2.59
+	* unix/tclConfig.h.in: autoheader-2.59
+
+	* generic/tclIntDecls.h:
+	* generic/tclIntPlatDecls.h:
+	* generic/tclStubInit.c: make genstubs
+
+2005-05-13  Kevin Kenny  <kennykb@acm.org>
+
+	* win/tclWin32Dll.c: Further rework of the SEH logic. All
+	EXCEPTION_REGISTRATION records are now in the activation record rather
+	than pushed on the stack.
+
+2005-05-13  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclBasic.c:	Dropped the TCL_NO_MATH configuration. It's
+	* generic/tclBinary.c:	believed this has not been working in a long
+	* generic/tclExecute.c: time. Tcl needs math.h. [RFE 1200680]
+	* unix/Makefile.in:
+
+2005-05-12  Kevin Kenny  <kennykb@acm.org>
+
+	* doc/mathfunc.n: Changed NAME line to match the name of the page.
+
+2005-05-11  Kevin Kenny  <kennykb@acm.org>
+
+	[kennykb-numerics-branch] Resynchronized with the HEAD; at this
+	checkpoint [-rkennykb-numerics-branch-20050511], the HEAD and
+	kennykb-numerics-branch contain identical code.
+
+2005-05-11  Kevin Kenny  <kennykb@acm.org>
+
+	* generic/tclStrToD.c (TclStrToD, RefineResult, ParseNaN): Changed the
+	code to cast 'char' to UCHAR explicitly when using ctype macros, to
+	silence complaints from the Solaris compiler.
+
+2005-05-10  Jeff Hobbs	<jeffh@ActiveState.com>
+
+	* unix/tclUnixFCmd.c: add lint attr to enum to satisfy strictly
+	compliant compilers that don't like trailing ,s.
+
+	* tests/string.test: string-10.[21-30]
+	* generic/tclCmdMZ.c (Tcl_StringObjCmd): add extra checks to prevent
+	possible UMR in unichar cmp function for string map.
+
+2005-05-10  Kevin Kenny  <kennykb@acm.org>
+
+	* generic/tclBinary.c (FormatNumber): Fixed a bug where NaN's resulted
+	in reads of uninitialized memory when using 'd', 'q', or 'Q' format.
+	* generic/tclStrToD.c (ParseNaN, TclFormatNaN): Added code to handle
+	the peculiarities of HP's PA_RISC, which uses a different 'quiet' bit
+	in NaN from everyone else.
+	* libtommath/tommath_superclass.h: Corrected C++-style comment.
+
+2005-05-10  Kevin Kenny  <kennykb@acm.org>
+
+	Merged all changes on kennykb-numerics-branch back into the HEAD.
+	TIP's 132 and 232 are now Final.
+
+2005-05-10  Kevin Kenny  <kennykb@acm.org>
+
+	[kennykb-numerics-branch] Merged changes from HEAD.
+
+2005-05-10  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclExecute.c (ExponLong, ExponWide):
+	* tests/expr.test (expr-23.34/35): fixed special case 'i**0' for i>0
+	[Bug 1198892]
+
+2005-05-09  Kevin B. Kenny  <kennykb@acm.org>
+
+	[kennykb-numerics-branch]
+	* win/tclWin32Dll.c (TclpCheckStackSpace, TclWinCPUID): Reworked
+	structured event handling to function even with -fomit-frame-pointers.
+
+2005-05-08  Kevin B. Kenny  <kennykb@acm.org>
+
+	[kennykb-numerics-branch]
+	* generic/tclStrToD.c: Made code more portable by finding a workaround
+	for MSVC's 'volatile' issue that does not require conditional
+	compilation.
+	* win/tclWin32Dll.c (TclWinCPUID): Removed structured event handling
+	from the GCC code since (a) bad code is generated by the instruction
+	scheduling with -O2, and (b) it's not needed on any reasonably modern
+	CPU.
+
+2005-05-07  Kevin B. Kenny  <kennykb@acm.org>
+
+	[kennykb-numerics-branch]
+	* generic/tclEvent.c:  Moved initialization of tclStrToD.c's
+	* generic/tclInt.h:    static constants into a procedure called
+	* generic/tclStrToD.c: from TclInitSubsystems to avoid double checked
+	locking protocol. Cleaned up an issue where MSVC ignored the
+	'volatile' specifier, causing incorrect comparison of an underflowed
+	number against zero.
+
+2005-05-06  Jeff Hobbs	<jeffh@ActiveState.com>
+
+	* unix/tcl.m4, unix/configure: correct Solaris 10 (5.10) check and add
+	support for x86_64 Solaris cc builds.
+
+2005-05-05  Kevin B. Kenny  <kennykb@acm.org>
+
+	[kennykb-numerics-branch] Merged with HEAD.
+
+2005-05-05  Kevin B. Kenny  <kennykb@acm.org>
+
+	* win/tclWinThrd.c:  Corrected a compilation error on the
+			     --enable-threads configuration.
+
+2005-05-05  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclInt.decls:	Converted TclMatchIsTrivial to a macro.
+	* generic/tclInt.h:
+	* generic/tclUtil.c:
+	* generic/tclIntDecls.h:	`make genstubs`
+	* generic/tclStubInit.c:
+	* generic/tclBasic.c:	Added callers of TclMatchIsTrivial where a
+	* generic/tclCmdIL.c:	search can be done more efficiently when it is
+	* generic/tclCompCmds.c:recognized that a pattern match is really an
+	* generic/tclDictObj.c:	exact match. [Patch 1076088]
+	* generic/tclIO.c:
+	* generic/tclNamesp.c:
+	* generic/tclVar.c:
+
+	* generic/tclCompCmds.c:	Factored common efficiency trick into a
+	macro named CompileWord.
+
+	* generic/tclCompCmds.c:	Replaced all instance of
+	* generic/tclCompile.c:		TCL_OUT_LINE_COMPILE with TCL_ERROR.
+	* generic/tclInt.h:		Now that we've eradicated the mistaken
+	* tests/appendComp.test:	notion of a "compile-time error", we
+	can use the TCL_ERROR return code to signal any failure to produce
+	bytecode.
+
+2005-05-03  Don Porter	<dgp@users.sourceforge.net>
+
+	* doc/DString.3:	Eliminated use of identifier "string" in Tcl's
+	* doc/Environment.3:	public C API to avoid conflict/confusion with
+	* doc/Eval.3:		the std::string of C++.
+	* doc/ExprLong.3, doc/ExprLongObj.3, doc/GetInt.3, doc/GetOpnFl.3:
+	* doc/ParseCmd.3, doc/RegExp.3, doc/SetResult.3, doc/StrMatch.3:
+	* doc/Utf.3, generic/tcl.decls, generic/tclBasic.c, generic/tclEnv.c:
+	* generic/tclGet.c, generic/tclParse.c, generic/tclParseExpr.c:
+	* generic/tclRegexp.c, generic/tclResult.c, generic/tclUtf.c:
+	* generic/tclUtil.c, unix/tclUnixChan.c:
+
+	* generic/tclDecls.h:	`make genstubs`
+
+2005-05-02  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tcl.decls:
+	* generic/tclBasic.c:	Simplified implementation of Tcl_ExprString.
+	* tests/expr-old.test:
+
+	* generic/tclDecls.h:	`make genstubs`
+
+2005-04-30  Daniel Steffen  <das@users.sourceforge.net>
+
+	* unix/tclUnixNotfy.c: applied dkf's tkMacOSXNotify.c cleanup changes.
+
+2005-04-29  Don Porter	<dgp@users.sourceforge.net>
+
+	TIP#176 IMPLEMENTATION	[Patch 1165695]
+
+	* generic/tclUtil.c:	Extended TclGetIntForIndex to recognize index
+	formats including end+integer and integer+/-integer.
+
+	* generic/tclCmdMZ.c:	Extended the -start switch of [regexp] and
+	[regsub] to accept all index formats known by TclGetIntForIndex.
+
+	* doc/lindex.n:		Updated docs to note new index formats.
+	* doc/linsert.n, doc/lrange.n, doc/lreplace.n, doc/lsearch.n:
+	* doc/lset.n, doc/lsort.n, doc/regexp.n, doc/regsub.n, doc/string.n:
+
+	* tests/cmdIL.test:	Updated tests.
+	* tests/compile.test, tests/lindex.test, tests/linsert.test:
+	* tests/lrange.test, tests/lreplace.test, tests/lsearch.test:
+	* tests/lset.test, tests/regexp.test, tests/regexpComp.test:
+	* tests/string.test, tests/stringComp.test, tests/util.test:
+
+2005-04-28  Don Porter	<dgp@users.sourceforge.net>
+
+	* tests/unixInit.test (7.1): Alternative fix for the 2004-11-11 commit.
+
+2005-04-27  Don Porter	<dgp@users.sourceforge.net>
+
+	* library/init.tcl:	Corrected flaw in interactive command
+	* tests/main.test:	auto-completion. [Bug 1191409].
+
+	TIP#183 IMPLEMENTATION	[Patch 577093]
+
+	* generic/tclIOUtil.c (TclGetOpenModeEx):	New routine.
+	* generic/tclInt.h:
+
+	* generic/tclIO.c (Tcl_OpenObjCmd):	Support for "b" and
+	* doc/open.n:		"BINARY" in "access" argument to [open].
+	* tests/ioCmd.test:
+
+2005-04-26  Kevin B. Kenny  <kennykb@users.sourceforge.net>
+
+	* generic/tclBinary.c (FormatNumber): Dredge the NaN out of the
+	internal representation if Tcl_GetDoubleFromObj returns TCL_ERROR on a
+	NaN.
+
+	* generic/tclObj.c (Tcl_GetDoubleFromObj): Restored silent
+	overflow/underflow behaviour that the merge of 2004-04-25 messed up.
+	Thanks to Don Porter for calling attention to this bug. Also removed an
+	uninitialised memory reference in this function that valgrind caught.
+	Also changed to return TCL_ERROR on a pure NaN.
+
+	* generic/tclStrToD.c (RefineResult): Added a test for the initial
+	approximation being HUGE_VAL; this test avoids EDOM being returned from
+	ldexp on some platforms on input values exceeding the floating point
+	range.
+
+	* tests/expr.test (expr-29.*, expr-30.*): Added further tests of
+	overflow/underflow on input conversions.
+
+2005-04-25  Kevin B. Kenny  <kennykb@users.sourceforge.net>
+
+	[kennykb-numerics-branch] Merged with HEAD.
+
+	* doc/CrtMathFunc.n:		Revised documentation for TIP 232
+
+2005-04-25  Daniel Steffen  <das@users.sourceforge.net>
+
+	* compat/string.h: fixed memchr() protoype for __APPLE__ so that we
+	build on Mac OS X 10.1 again.
+
+	* generic/tclNotify.c (TclFinalizeNotifier): fixed notifier not being
+	finalized in unthreaded core (was testing for notifier initialization
+	in current thread by checking thread id != 0 but thread id is always 0
+	in untreaded core).
+
+	* win/tclWinNotify.c (Tcl_WaitForEvent):
+	* unix/tclUnixNotfy.c (Tcl_WaitForEvent): don't call ScaleTimeProc for
+	zero wait times (as specified in TIP 233).
+
+	* unix/Makefile.in: added @PLAT_SRCS@ to SRCS and split out NOTIFY_SRCS
+	from UNIX_SRCS for parity with UNIX_OBJS & NOTIFY_OBJS.
+
+	* unix/tcl.m4 (Darwin): added configure checks for recently added
+	linker flags -single_module and -search_paths_first to allow building
+	with older tools (and on Mac OS X 10.1), use -single_module in SHLIB_LD
+	and not just T{CL,K}_SHLIB_LD_EXTRAS, added unexporting from Tk of
+	symbols from libtclstub to avoid duplicate symbol warnings, added
+	PLAT_SRCS definition for Mac OS X, defined MODULE_SCOPE to
+	__private_extern__.
+	(SC_MISSING_POSIX_HEADERS): added caching of dirent.h check.
+
+	* unix/configure: autoconf-2.59
+
+2005-04-25  Kevin B. Kenny  <kennykb@users.sourceforge.net>
+
+	* library/tzdata/America/Boise:
+	* library/tzdata/America/Chicago:
+	* library/tzdata/America/Denver
+	* library/tzdata/America/Indianapolis:
+	* library/tzdata/America/Los_Angeles:
+	* library/tzdata/America/Louisville:
+	* library/tzdata/America/Managua:
+	* library/tzdata/America/New_York:
+	* library/tzdata/America/Phoenix:
+	* library/tzdata/America/Port-au-Prince:
+	* library/tzdata/America/Indiana/Knox:
+	* library/tzdata/America/Indiana/Marengo:
+	* library/tzdata/America/Indiana/Vevay:
+	* library/tzdata/America/Kentucky/Monticello:
+	* library/tzdata/America/North_Dakota/Center:
+	* library/tzdata/Asia/Tehran:
+	Olson's tzdata2005i. Corrects exact time at which Standard Time was
+	adopted in the US (generally, noon, Standard Time, rather than noon,
+	Local Mean Time). Adopts new civil rules for Nicaragua and Iran.
+
+2005-04-25  Don Porter	<dgp@users.sourceforge.net>
+
+	* library/init.tcl:	Use "ni" and "in" operators.
+
+2005-04-25  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclExecute.c: fix for [Bug 1189274].
+
+2005-04-24  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclLiteral.c:	Silence compiler warnings.
+	* generic/tclObj.c:	[Bug 1188863].
+
+2005-04-22  Don Porter	<dgp@users.sourceforge.net>
+
+	The 2005-04-21 changes to Tcl_GetBooleanFromObj were done to bring it
+	into agreement with its docs. Further investigation reveals it was the
+	docs that were incorrect.
+
+	* doc/BoolObj.3:	Corrections to the documentation of
+	Tcl_GetBooleanFromObj to bring it into agreement with what this public
+	interface has always done, including noting the difference in function
+	between Tcl_GetBooleanFromObj and Tcl_GetBoolean.
+
+	* generic/tclGet.c:	Revised Tcl_GetBoolean to no longer be a
+	wrapper around Tcl_GetBooleanFromObj (different function!).
+
+	* generic/tclObj.c:	Removed TclGetTruthValueFromObj routine that
+	was added yesterday. Revisions so that only Tcl_GetBoolean-approved
+	values get the "boolean" Tcl_ObjType. This retains the fix for [Bug
+	1187123].
+	* tests/string.test:	Test string-23.0 for Bug 1187123.
+
+	* generic/tclInt.h:	Revert most recent change.
+	* generic/tclBasic.c:
+	* generic/tclCompCmds.c:
+	* generic/tclDictObj.c:
+	* generic/tclExecute.c:
+	* tests/obj.test:
+
+2005-04-21  Don Porter	<dgp@users.sourceforge.net>
+
+	* doc/GetInt.3:	Convert argument "string" to "str" to agree with code.
+	Also clarified a few details on int and double formats.
+	* generic/tclGet.c:	Radical code simplification. Converted
+	Tcl_GetFoo() routines into wrappers around Tcl_GetFooFromObj(). Reduces
+	code duplication, and the resulting potential for inconsistency.
+
+	* generic/tclObj.c:	Several changes:
+
+	- Re-ordered error detection code so all values with trailing garbage
+	  receive a "not an integer" message instead of an "integer too large"
+	  message.
+	- Removed inactive code meant to deal with strtoul* routines that fail
+	  to parse leading signs. All of them do, and if any are detected that
+	  do not, the correct fix is replacement with compat/strtoul*.c, not a
+	  lot of special care by the callers.
+	- Tcl_GetDoubleFromObj now avoids shimmering away a "wideInt" intrep.
+	- Fixed Tcl_GetBooleanFromObj to agree with its documentation and with
+	  Tcl_GetBoolean, accepting only "0" and "1" and not other numeric
+	  strings. [Bug 1187123]
+	- Added new private routine TclGetTruthValueFromObj to perform the more
+	  permissive conversion of numeric values to boolean that is needed by
+	  the [expr] machinery.
+
+	* generic/tclInt.h (TclGetTruthValueFromObj):	New routine.
+	* generic/tclExecute.c:	Updated callers to call new routine.
+	* generic/tclBasic.c:	Updated callers to call new routine.
+	* generic/tclCompCmds.c:	Updated callers to call new routine.
+	* generic/tclDictObj.c:	Updated callers to call new routine.
+	* tests/obj.test:	Corrected bad tests that actually expected
+	values like "47" and "0xac" to be accepted as booleans.
+
+	* generic/tclLiteral.c: Disabled the code that forces some literals
+	into the "int" Tcl_ObjType during registration. We can re-enable it if
+	this change causes trouble, but it seems more sensible to let Tcl's
+	"on-demand" shimmering rule, and not try to pre-guess things.
+
+2005-04-20  Kevin B. Kenny  <kennykb@acm.org>
+
+	[kennykb-numerics-branch]
+	* doc/expr.n:
+	* doc/mathfunc.n (new file):	Revised documentation for TIP 232
+
+2005-04-20  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclGet.c (Tcl_GetInt):	Corrected error that did not
+	* generic/tclObj.c (Tcl_GetIntFromObj): permit 0x80000000 to be
+	recognized as an integer on TCL_WIDE_INT_IS_LONG systems [Bug 1090869].
+
+2005-04-20  Kevin B. Kenny  <kennykb@acm.org>
+
+	* generic/tclFileName.c: Silenced a compiler warning about '/*' within
+	a comment.
+
+2005-04-19  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclBasic.c:	Added unsupported command
+	* generic/tclCmdAH.c:	[::tcl::unsupported::EncodingDirs] to permit
+	* generic/tclInt.h:	query/set of the encoding search path at
+	* generic/tclInterp.c:	the script level. Updated init.tcl to make
+	* library/init.tcl:	use of the new command. Also updated several
+	coding practices in init.tcl ("eq" for [string equal], etc.)
+
+2005-04-19  Kevin B. Kenny  <kennykb@acm.org>
+
+	* library/clock.tcl (Initialize): Put initialization code into a proc
+	to avoid inadvertently clobbering global variables. [Bug 1185933]
+	* tests/clock.test (clock-48.1): Added regression test for the above
+	bug.
+	Thanks to Ulrich Ring for reporting this bug.
+
+2005-04-16  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/Var.c (Tcl_ArrayObjCmd - ARRAY_NAMES): fix Tcl_Obj leak. [Bug
+	1084111]
+
+2005-04-16  Zoran Vasiljevic  <vasiljevic@users.sf.net>
+
+	* generic/tclIOUtil.c: force clenaup of the interp result in
+	TclLoadFile(). Some implementations of TclpFindSymbol() will seed the
+	interp result with error message when unable to find the requested
+	symbol (this is not considered to be an error).
+
+	Set of changes correcting huge memory waste (not a leak) when a thread
+	exits. This has been introduced in 8.4.7 within an attempt to correctly
+	cleanup after ourselves when Tcl library is being unloaded with the
+	Tcl_Finalize() call.
+
+	This fixes the [Bug 1178445]
+
+	* generic/tclInt.h: added prototypes for TclpFreeAllocCache() and
+	TclFreeAllocCache()
+
+	* generic/tclThreadAlloc.c: modified TclFinalizeThreadAlloc() to
+	explicitly call TclpFreeAllocCache with the NULL-ptr as argument
+	signalling cleanup of private tsd key used only by the threading
+	allocator.
+
+	* unix/tclUnixThrd.c: fixed TclpFreeAllocCache() to recognize when
+	being called with NULL argument. This is a signal for it to clean up
+	the tsd key associated with the threading allocator.
+
+	* win/tclWinThrd.c: renamed TclWinFreeAllocCache to TclpFreeAllocCache
+	and fixed to recognize when being called with NULL argument. This is a
+	signal for it to clean up the tsd key associated with the threading
+	allocator.
+
+2005-04-13  Don Porter	<dgp@users.sourceforge.net>
+
+	* tests/unixInit.test:	Disabled obsolete tests and removed code
+	* tests/encoding.test:	that supported them.
+	* generic/tclInterp.c:
+
+	* library/init.tcl:	Use auto-loading to bring in Tcl Module support
+	* library/tclIndex:	as needed. This reduces startup time by
+	* library/tm.tcl:	delaying this initialization to a later time.
+
+2005-04-15  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclExecute.c: missing semicolons caused failure to compile
+	with TCL_COMPILE_DEBUG.
+
+2005-04-13  David Gravereaux  <davygrvy@pobox.com>
+
+	* generic/tclIO.c (Tcl_SetChannelBufferSize): Lowest size limit
+	* tests/io.test:	changed from ten bytes to one byte. Need for
+	* tests/iogt.test:	this change was proven by Ross Cartlidge
+	<rossc@cisco.com> where [read stdin 1] was grabbing 10 bytes followed
+	by starting a child process that was intended to continue reading from
+	stdin. Even with -buffersize set to one, nine chars were getting lost
+	by the buffersize over reading for the native read() caused by [read].
+
+2005-04-13  Don Porter	<dgp@users.sourceforge.net>
+
+	* unix/tclUnixInit.c (TclpGetEncodingNameFromEnvironment): Reversed
+	order of verifying candidate [encoding system] value, checking against
+	a table in memory first before calling Tcl_GetEncoding and potentially
+	scanning through the filesystem. Also ordered the table so that a
+	binary search could be used within it. Improves startup time a bit more
+	on some systems.
+
+2005-04-13  Kevin B. Kenny  <kennykb@acm.org>
+
+	* library/clock.n: Added a missing '--' on several [switch] commands to
+	improve performance of [clock format] and related operations. [FRQ
+	1182459]
+
+2005-04-13  Donal K. Fellows  <donal.k.fellows@manchester.ac.uk>
+
+	* doc/fcopy.n: Improved documentation on copying binary files, added an
+	example and mentioned the use of [file copy].
+	* doc/fconfigure.n: Improved documentation of -encoding binary option.
+	This is all following comments from Steve Manning <steve@manning.net>
+	on comp.lang.tcl that the current documentation was not clear.
+
+2005-04-13  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclCompile.c:Commented out the functions
+	TclPrintInstruction(), TclPrintObject() and TclPrintSource() when not
+	debugging the compiler, as they are never called in that case.
+
+2005-04-12  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclInterp.c:	Corrected bad syntax of Tcl_Panic() call.
+
+	* generic/tclUtil.c (TclGetProcessGlobalValue):	More robust handling
+	of bad TclInitProcessGlobalValueProc behavior; an immediate panic
+	rather than a mysterious crash later.
+
+	* generic/tclEncoding.c:	Several changes to the way the
+	encodingFileMap cache is maintained. Previously, it was attempted to
+	keep the file map filled and up to date with changes in the encoding
+	search path. This contributed to slow startup times since it required
+	an expensive "glob" operation to fill the cache. Now the validity of
+	items in the cache are checked at the time they are used, so the cache
+	is permitted to fall out of sync with the encoding search path. Only
+	[encoding names] and Tcl_GetEncodingNames() now pay the full expense.
+	[Bug 1177363]
+
+2005-04-12  Kevin B. Kenny  <kennykb@acm.org>
+
+	* compat/strstr.c: Added default definition of NULL to accommodate
+	building on systems with badly broken headers. [Bug 1175161]
+
+2005-04-11  Donal K. Fellows  <donal.k.fellows@manchester.ac.uk>
+
+	* tools/tclZIC.tcl: Rewrote to take advantage of more features of Tcl
+	8.5 (on which it was dependent anyway). Also added a [package require]
+	line to formalize the relationship.
+
+2005-04-11  Kevin Kenny  <kennykb@users.sf.net>
+
+	[kennykb-numerics-branch] Merged with HEAD. Updated to libtommath 0.35.
+
+	* generic/tclBasic.c: Attempted to repeat changes that applied to
+	tclExecute.c in Miguel Sofer's commit of 2005-04-01, together with
+	(possibly) a few more uses of his new object creation macros. Also
+	plugged a memory leak in TclObjInvoke. [Bug 1180368]
+
+2005-04-10  Kevin Kenny  <kennykb@acm.org>
+
+	* library/tzdata/America/Montevideo:
+	* library/tzdata/Asia/Almaty:
+	* library/tzdata/Asia/Aqtau:
+	* library/tzdata/Asia/Aqtobe:
+	* library/tzdata/Asia/Baku:
+	* library/tzdata/Asia/Jerusalem:
+	* library/tzdata/Asia/Oral:
+	* library/tzdata/Asia/Qyzylorda:
+	* library/tzdata/Indian/Chagos:
+	* library/tzdata/Indian/Cocos:		Olson's tzdata2005h
+
+2005-04-10  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclBasic.c (TclObjInvoke):	Plug memory leak. [Bug 1180368]
+
+2005-04-09  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclExecute.c: fix possible leak of expansion Tcl_Objs
+
+2005-04-09  Daniel Steffen  <das@users.sourceforge.net>
+
+	* macosx/README: updated requirements for OS & developer tool versions
+	and other small fixes/cleanup.
+
+	* generic/tclListObj.c (Tcl_ListObjIndex): added missing NULL return
+	when getting index from an empty list.
+
+	* unix/tcl.m4 (Darwin): added -single_module linker flag to
+	TCL_SHLIB_LD_EXTRAS and TK_SHLIB_LD_EXTRAS.
+	* unix/configure: autoconf-2.59
+
+2005-04-08  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclInt.h (TclGetEncodingFromObj):	 New function to
+	* generic/tclEncoding.c (TclGetEncodingFromObj): retrieve a
+	Tcl_Encoding value, as well as cache it in the internal rep of a new
+	"encoding" Tcl_ObjType.
+	* generic/tclCmdAH.c (Tcl_EncodingObjCmd):	Updated to call new
+	function so that Tcl_Encoding's used by [encoding convert*] routines
+	are not freed too quickly. [Bug 1077262]
+
+2005-04-08  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclCompCmds.c (TclCompileSwitchCmd): Rewritten to be able to
+	handle the other form of [switch] and generate slightly simpler (but
+	longer) code.
+
+2005-04-06  Donal K. Fellows  <dkf@users.sf.net>
+
+	* doc/upvar.n, doc/unset.n, doc/tell.n, doc/tclvars.n, doc/subst.n:
+	* doc/seek.n, doc/scan.n, doc/regsub.n, doc/registry.n, doc/regexp.n:
+	* doc/read.n, doc/puts.n, doc/pkgMkIndex.n, doc/open.n, doc/lreplace.n:
+	* doc/lrange.n, doc/load.n, doc/llength.n, doc/linsert.n, doc/lindex.n:
+	* doc/lappend.n, doc/info.n, doc/gets.n, doc/format.n, doc/flush.n:
+	* doc/fileevent.n, doc/file.n, doc/fblocked.n, doc/close.n:
+	* doc/array.n, doc/Utf.3, doc/TraceVar.3, doc/StrMatch.3, doc/RegExp.3:
+	* doc/PrintDbl.3, doc/OpenTcp.3, doc/OpenFileChnl.3, doc/Object.3:
+	* doc/Notifier.3, doc/LinkVar.3, doc/IntObj.3, doc/Interp.3:
+	* doc/GetOpnFl.3, doc/GetIndex.3, doc/Eval.3, doc/CrtMathFnc.3:
+	* doc/CrtFileHdlr.3, doc/CrtCommand.3, doc/CrtChannel.3:
+	* doc/Backslash.3: Purge old .VS/.VE macro instances.
+
+	* tools/man2html2.tcl (IPmacro): Rewrote to understand what .IP really
+	is (.IP and .TP are really just two ways of doing the same thing).
+	Change below made this relevant.
+	* doc/re_syntax.n: Change some uses of .TP to .IP to work around bugs
+	in various *roff implementations. Also reworded the atom descriptions
+	slightly.
+
+2005-04-05  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclExecute.c (ExprSrandFunc):  Replaced incursions into the
+	* generic/tclUtil.c (TclGetIntForIndex): intreps of numeric types with
+	simpler calls of Tcl_GetIntFromObj and Tcl_GetLongFromObj, now that
+	those routines are better behaved wrt shimmering. [Patch 1177219]
+
+2005-04-05  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclInt.h:
+	* generic/tclObj.c: Change in TclDecrRefCount and TclFreeObj, to speed
+	up the freeing of simple Tcl_Obj [Patch 1174551]
+
+2005-04-04  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclExecute.c: small opts in obj handling
+
+2005-04-02  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclVar.c: converted a few function calls to macros.
+
+2005-04-01  Miguel Sofer  <msofer@users.sf.net>
+
+	* doc/ListObj.3:
+	* generic/tclBasic.c:
+	* generic/tclCmdIL.c:
+	* generic/tclConfig.c:
+	* generic/tclExecute.c:
+	* generic/tclInt.decls:
+	* generic/tclInt.h:
+	* generic/tclIntDecls.h:
+	* generic/tclListObj.c:
+	* generic/tclStubInit.c:
+	* generic/tclVar.c: Changed the internal representation of lists to
+	(a) reduce the malloc/free calls at list creation (from 2 to 1), (b)
+	reduce the cost of handling empty lists (we now never create a list
+	internal rep for them), (c) allow refcounting of the list internal rep.
+	The latter permits insuring that the pointers returned by
+	Tcl_ListObjGetElements remain valid even if the object shimmers away
+	from its original list type. This is [Patch 1158008]
+
+	* generic/tclExecute.c:
+	* generic/tclInt.h:
+	* generic/tclObj.c:
+	* generic/tclStringObj.c:
+	(1) defined new internal macros for creating and setting frequently
+	used obj types (int,long, wideInt, double, string). Changed TEBC to use
+	eg 'TclNewIntObj(objPtr, i)' to avoid the function call in 'objPtr =
+	Tcl_NewIntObj(i)'
+	(2) ExecEnv now stores two Tcl_Obj* pointing to the constants "0" and
+	"1", for use by TEBC.
+	(3) slight reduction in cost of INST_START_CMD
+
+2005-03-31  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclExecute.c (INST_JUMP_TRUE/FALSE): replaced "test and
+	branch" with "compute index into table"
+
+2005-03-30  Donal K. Fellows  <donal.k.fellows@manchester.ac.uk>
+
+	* doc/FileSystem.3: Defined loadHandle argument. [Bug 1172401]
+
+2005-03-29  Jeff Hobbs	<jeffh@ActiveState.com>
+
+	* win/tcl.m4, win/configure: do not require cygpath in macros to allow
+	msys alone as an alternative.
+
+2005-03-24  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclCompile.h:	Move the TclInterpReady() declaration from
+	* generic/tclInt.h:	tclCompile.h to tclInt.h. Should have been done
+	as part of the 1115904 bug fix on 2005-03-18.
+
+	* generic/tclThreadTest.c:	Stop providing the phony package
+	"Thread 1.0" when the [::testthread] command is defined. It's never
+	used by anything, and conflicts with loading the real "Thread" package.
+
+2005-03-18  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclCompCmds.c (TclCompileIncrCmd):	Corrected checks for
+	immediate operand usage to permit leading space and sign characters.
+	Restores more efficient bytecode for [incr x -1] that got lost in the
+	CONST string reforms of Tcl 8.4. [Bug 1165671]
+
+	* generic/tclBasic.c (Tcl_EvalEx):	Restored recursion limit
+	* generic/tclParse.c (TclSubstTokens):	testing in nested command
+	* tests/basic.test (basic-46.4):	substitutions within direct
+	* tests/parse.test (parse-19.*):	script evaluation (Tcl_EvalEx)
+	that got lost in the parser reforms of Tcl 8.1. Added tests for correct
+	behavior. [Bug 1115904]
+
+2005-03-15  Vince Darley  <vincentdarley@users.sourceforge.net>
+
+	* generic/tclFileName.c:
+	* win/tclWinFile.c:
+	* tests/winFCMd.test: fix to 'file pathtype' and 'file norm' failures
+	on reserved filenames like 'COM1:', etc.
+
+2005-03-15  Pat Thoyts	<patthoyts@users.sourceforge.net>
+
+	* unix/tcl.m4:	  Updated the OpenBSD configuration and regenerated
+	* unix/configure: the configure script.
+
+2005-03-15  Kevin B. Kenny  <kennykb@acm.org>
+
+	[kennykb-numerics-branch] Merged with HEAD.
+
+	* generic/tclBasic.c (many):
+	* generic/tclCompExpr.c (CompileMathFuncCall):
+	* generic/tclCompile.h:
+	* generic/tclExecute.c (many):
+	* generic/tclParseExpr.c (ParsePrimaryExpr):
+	* tests/compExpr-old.test:
+	* tests/compExpr.test:
+	* tests/compile.test:
+	* tests/expr-old.test:
+	* tests/expr.test:
+	* tests/for.test:
+	* tests/parseExpr.test: Initial implementation of TIP #232.
+
+	* generic/tclObj.c (Tcl_DbNewBignumObj): Fixed typo that broke
+	--enable-symbols=mem build
+	* tests/binary.test (binary-40.3, binary-40.6): Corrected tests to
+	allow NaN(7ffffffffffff).
+
+2005-03-14  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclExecute.c: fixed INST_PUSH1's debugging code (wrong obj
+	ref passed to TRACE_WITH_OBJ).
+
+2005-03-14  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclCompile.c: fixed INST_RETURN's stack effect in
+	tclInstructionTable (-1 instead of -2)
+
+2005-03-10  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclCompCmds.c: removed debugging line
+
+2005-03-10  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclTrace.c (TclCheckInterpTraces):	Corrected mistaken cast
+	of ClientData to (TraceCommandInfo *) when not warranted. Thanks to
+	Yuri Victorovich for the report. [Bug 1153871]
+	* generic/tcl.h:	Moved flag values TCL_TRACE_ENTER_EXEC and
+	* generic/tclInt.h:	TCL_TRACE_LEAVE_EXEC from public interface into
+	private. Should be used only by internal workings of execution traces.
+
+2005-03-09  Kevin B. Kenny  <kennykb@acm.org>
+
+	[kennykb-numerics-branch] Merged from HEAD.
+
+	* doc/PrintDbl.3:
+	* doc/tclVars.n: Documented new semantics for tcl_precision.
+	* generic/tclExecute.c (Tcl_ExecuteByteCode): Removed the check for
+	division-by-zero on IEEE-754 machines.
+	* generic/tclUtil.c (Tcl_PrintDouble): Corrected bug where numbers in
+	the range [1e-4 .. 1.) were printed incorrectly.
+	* tests/compExpr-old.test (compExpr-old-11.13): Revised test case for
+	division by zero.
+	* tests/expr-old.test (expr-34.11, expr-34.12): Revised test cases for
+	overflow in pow() to deal with infinities.
+	* tests/expr.test (expr-11.13, expr-29.1, expr-29.2): Revised test case
+	for division by zero and for underflow on input conversions.
+	* tests/parseExpr.test (parseExpr-16.11): Revised test case for
+	overflow on input conversion.
+	* tests/string.test (string-6.38 deleted): Removed test case for
+	underflow on input conversion, which is no longer an error.
+	* tests/util.test (util-10.*): Added test case for the bug in tclUtil.c
+
+2005-03-08  Jeff Hobbs	<jeffh@ActiveState.com>
+
+	* win/makefile.vc: clarify necessary defined vars that can come from
+	MSVC or the Platform SDK.
+
+2005-03-07  Donal K. Fellows  <dkf@users.sf.net>
+
+	* doc/string.n: Minor typo. [Bug 1158247]
+
+2005-03-07  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclExecute.c: new peephole optimisation for INST_PUSH1; fixed
+	the peephole opt in INST_POP so that it is not used when
+	TCL_COMPILE_DEBUG is defined.
+
+2005-03-04  Kevin B. Kenny  <kennykb@acm.org>
+
+	[kennykb-numerics-branch]
+
+	* generic/tclCmdMZ.c: Changed [scan] to treat out-of-range floating
+	point values as infinities and zeroes.
+	* generic/tclExecute.c: Changed [expr] to be permissive about
+	infinities, allowing them to propagate.
+	* generic/tclGet.c: Changed Tcl_GetDouble to be permissive about
+	over/underflow.
+	* generic/tclObj.c: Changed SetDoubleFromAny to be permissive about
+	over/underflow.
+	* generic/tclParseExpr.c: Made [expr] permissive about input numbers
+	out of range.
+
+2005-03-03  Kevin B. Kenny  <kennykb@acm.org>
+
+	[kennykb-numerics-branch]
+
+	* generic/tclInt.h:
+	* generic/tclStrToD.c (Tcl_DoubleDigits, TclFormatNaN):
+	* generic/tclUtil.c (Tcl_PrintDouble): Changed the signature of
+	TclDoubleDigits so that it accepts a pointer to the signum of the
+	argument, and returns the signum via that pointer. Added very hacky
+	code to handle IEEE signed zeroes in Tcl_DoubleDigits. (It can't be
+	done other than as a hack until C9x; C89 simply doesn't deal with the
+	concept of -0.0). Added output conversion of tagged NaN values.
+	* generic/tclBinary.c (FormatNumber): Changed to allow [binary format]
+	to handle NaN.
+	* tests/binary.test (binary-60.1): Added a quick-n-dirty test to make
+	sure that NaN's can be scanned and formatted.
+	* generic/tclParseExpr.c (GetLexeme, ParseMaxDoubleLength): Modified so
+	that tagged NaN (e.g., NaN(DEADBEEF)) can be recognized.
+
+2005-03-02  Kevin B. Kenny  <kennykb@acm.org>
+
+	[kennykb-numerics-branch] Merged with HEAD as of 2005-02-23.
+
+	* generic/tclExecute.c: Broadened test for NaN to work on Windows.
+	* generic/tclInt.h:
+	* generic/tclStrToD.c (Tcl_DoubleDigits):
+	* generic/tclUtil.c (Tcl_PrintDouble, TclPrecTraceProc): Added
+	Tcl_DoubleDigits to format 'double' numbers with the minimum number of
+	significant digits to yield correct rounding. Modified tcl_precision
+	to accept 0 as a precision (meaning "minimum digits"), and made 0 the
+	default. [TIP #132]
+	* generic/tclObj.c: Made NaN's throw an error in Tcl_GetDoubleFromObj.
+	* unix/Makefile.in:
+	* win/Makefile.in:
+	* win/makefile.vc: Added libtommath/bn_mp_init_set.c to the build.
+	* libtommath/tommath.h (mp_iseven): Fixed a bug that caused zero to
+	test 'odd'.
+	* generic/tommath.h: Regenerated.
+	* tests/binary.test:
+	* tests/expr-old.test:
+	* tests/expr.test:
+	* tests/scan.test: Corrected a number of tests that depended on
+	tcl_precision, and removed the {eformat} condition from tests that no
+	longer require it.
+	* tests/util.test: Corrected a number of tests that depended on
+	tcl_precision, and removed the {eformat} condition from tests that no
+	longer require it. Added a series of tests for correct rounding in
+	Tcl_PrintDouble. [TIP #132].
+
+2005-03-01  David N. Welton  <davidw@dedasys.com>
+
+	* doc/CrtSlave.3: Changed to Tcl_Object to Tcl_Obj in the man page.
+
+2005-02-24  Don Porter	<dgp@users.sourceforge.net>
+
+	* library/tcltest/tcltest.tcl:	Better use of [glob -types] to avoid
+	* tests/tcltest.test:	failed attempts to [source] a directory, and
+	similar matters. Thanks to "mpettigr". [Bug 1119798]
+
+	* library/tcltest/pkgIndex.tcl: Bump to tcltest 2.2.8
+	* unix/Makefile.in:
+	* win/Makefile.in:
+
+2005-02-23  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* doc/CrtChannel.3 (THREADACTIONPROC): Formatting fix. [Bug 1149605]
+
+2005-02-17  Jeff Hobbs	<jeffh@ActiveState.com>
+
+	* win/tclWinFCmd.c (TraverseWinTree): use wcslen on wchar, not
+	Tcl_UniCharLen.
+
+2005-02-16  Miguel Sofer  <msofer@users.sf.net>
+
+	* doc/variable.n: fix for [Bug 1124160], variables are detected by
+	[info vars] but not by [info locals].
+
+2005-02-11  Jeff Hobbs	<jeffh@ActiveState.com>
+
+	* unix/Makefile.in: remove SHLIB_LD_FLAGS (only for AIX, inlined into
+	* unix/tcl.m4:	    SHLIB_LD). Combine AIX-* and AIX-5 branches in
+	* unix/configure:   SC_CONFIG_CFLAGS. Correct gcc builds for AIX-4+
+	and HP-UX-11. autoconf-2.59 gen'd.
+
+2005-02-11  Miguel Sofer  <msofer@users.sf.net>
+
+	* tests/basic.test (basic-26.3): new test
+
+2005-02-10  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclBasic.c (Tcl_EvalObjEx):
+	* tests/basic.test (basic-26.2): preserve the arguments passed to TEOV
+	in the pure-list branch, in case the list shimmers away. Fix for [Bug
+	1119369], reported by Peter MacDonald.
+
+2005-02-10  Vince Darley  <vincentdarley@users.sourceforge.net>
+
+	* generic/tclFileName.c: fix for test failures introduced on 2005-01-17
+	[Bug 1119092]
+
+2005-02-10  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* doc/binary.n: Made the documentation of sign bit masking and [binary
+	scan] consistent. [Bug 1117017]
+
+2005-02-08  David N. Welton  <davidw@dedasys.com>
+
+	* doc/CrtChannel.3: Typo: return->returns.
+
+2005-02-06  Kevin B. Kenny  <kennykb@acm.org>
+
+	[kennykb-numerics-branch]
+
+	* generic/tclStrToD.c (TclStrToD, SafeLdExp): Added code to manage the
+	FPU precision on gcc+x86. Enabled fast conversion of floats with small
+	exponents now that precision is correct.
+	* tests/expr.test: Corrected test for the smallest representible value
+	to the right IEEE values.
+
+2005-02-06  David N. Welton  <davidw@dedasys.com>
+
+	* doc/Thread.3: One-word grammar fix.
+
+2005-02-05  David N. Welton  <davidw@dedasys.com>
+
+	* doc/Thread.3: Fixed sentence describing flags for Tcl_CreateThread.
+
+	* doc/FileSystem.3: Cleaned up typo in Tcl_FSNewNativePath
+	documentation.
+
+	* generic/tclPathObj.c: Cleaned up typo in comment.
+
+2005-02-03  Kevin B. Kenny  <kennykb@acm.org>
+
+	[kennykb-numerics-branch]
+
+	* generic/tclStrToD.c (TclStrToD, RefineResult, SafeLdExp): Added code
+	to ensure that 'ldexp' is never called with a value that will underflow
+	* tests/expr.test: Added tests for the smallest representible value,
+	and rounding between it and zero. (The tests reflect current
+	behaviour; plan is to change the specification of Tcl so that input
+	conversion of doubles underflows silently.)
+
+2005-02-02  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* generic/tclProc.c (TclInitCompiledLocals): Add check for type of the
+	framePtr->procPtr->bodyPtr passed to TclInitCompiledLocals and panic if
+	it is not the correct type. If the body of the proc is not of the
+	compiled byte code type then the code will crash. This was discovered
+	while tracking down a crash in Itcl, that crash is fixed by Itcl patch
+	1115085.
+
+2005-02-01  Kevin B. Kenny  <kennykb@acm.org>
+
+	[kennykb-numerics-branch]  Merged with HEAD as of today.
+
+	* generic/tclInt.decls: Changed numbers of new stubs to resolve a
+	conflict.
+	* generic/tclInt.h: Added new TclStrToD routine that replaces the
+	native 'strtod' throughout Tcl.
+	* generic/tclCmdMZ (Tcl_StringObjCmd):
+	* generic/tclGet.c (Tcl_GetDouble):
+	* generic/tclObj.c (SetBooleanFromAny, SetDoubleFromAny):
+	* generic/tclParseExpr.c (GetLexeme):
+	* generic/tclScan.c (Tcl_ScanObjCmd): Replaced all uses of the native
+	'strtod' with a TclStrToD routine that performs correct rounding and
+	handles denormals.
+	* generic/tclStrToD.c: (new file)
+	New scanning function for extracting 'double' from a string that rounds
+	correctly, and handles denormals and infinities.
+	* unix/Makefile.in:
+	* win/Makefile.in:
+	* win/makefile.vc:
+	Added tclStrToD.c and the tommath routines that support it.
+
+	These changes represent a partial implementation of TIP #132. Output
+	conversion of floating point numbers, and proper handling of infinities
+	within expressions, still need to be addressed.
+
+2005-02-01  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclExecute.c (TclCompEvalObj): Removed stray statement left
+	behind in prior code reorganization.
+
+2005-01-31  Don Porter	<dgp@users.sourceforge.net>
+
+	* unix/configure:	autoconf-2.57
+
+2005-01-30  Joe English  <jenglish@users.sourceforge.net>
+
+	* unix/configure.in: Restored two double-evals that were removed in the
+	DBGX purge; these are still needed on some platforms to account for
+	TCL_TRIM_DOTS. [Bug 1112654]
+
+	* unix/configure: NOT REGENERATED: only have autoconf 2.59 here, need
+	to find someone with autoconf 2.57.
+
+2005-01-28  Jeff Hobbs	<jeffh@ActiveState.com>
+
+	* unix/configure, unix/tcl.m4: add solaris 64-bit gcc build support.
+	[Bug 1021871]
+
+2005-01-28  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* tests/expr-old.test (expr-old-37.2): Added test for [Bug 1109484]
+
+2005-01-27  Jeff Hobbs	<jeffh@ActiveState.com>
+
+	* generic/tclBasic.c (Tcl_ExprBoolean, Tcl_ExprDouble)
+	(Tcl_ExprLong): Fix to recognize Tcl_WideInt type. [Bug 1109484]
+
+2005-01-26  Andreas Kupries  <andreask@activestate.com>
+
+	TIP#218 IMPLEMENTATION
+
+	* generic/tclDecls.h:	Regenerated from tcl.decls.
+	* generic/tclStubInit.c:
+
+	* doc/CrtChannel.3:	Documentation of extended API,
+	* generic/tcl.decls:	extended testsuite, and
+	* generic/tcl.h:	implementation. Removal of old
+	* generic/tclIO.c:	driver-specific TclpCut/Splice
+	* generic/tclInt.h:	functions. Replaced with generic
+	* tests/io.test:	thread-action calls through the
+	* unix/tclUnixChan.c:	new hooks. Update of all builtin
+	* unix/tclUnixPipe.c:	channel drivers to version 4.
+	* unix/tclUnixSock.c:	Windows drivers extended to
+	* win/tclWinChan.c:	manage thread state in a thread
+	* win/tclWinConsole.c:	action handler.
+	* win/tclWinPipe.c:
+	* win/tclWinSerial.c:
+	* win/tclWinSock.c:
+
+2005-01-25  Don Porter	<dgp@users.sourceforge.net>
+
+	* library/auto.tcl:	Updated [auto_reset] to clear auto-loaded
+	commands in namespaces other than :: and to clear auto-loaded commands
+	that do not happen to be procs. [Bug 1101670]
+	***POTENTIAL INCOMPATIBILITY***
+
+2005-01-25  Daniel Steffen  <das@users.sourceforge.net>
+
+	* unix/tcl.m4 (Darwin): fixed bug with static build linking to dynamic
+	library in /usr/lib etc instead of linking to static library earlier in
+	search path. [Bug 956908] Removed obsolete references to Rhapsody.
+	* unix/configure: autoconf-2.57
+
+2005-01-21  Andreas Kupries  <andreask@activestate.com>
+
+	* generic/tclStubInit.c: Regenerated the stubs support code from the
+	* generic/tclDecls.h:	 modified tcl.decls (TIP #233, see below).
+
+	* doc/GetTime.3:       Implemented TIP #233, i.e. the
+	* generic/tcl.decls:   'Virtualization of Tcl's Sense of Time'.
+	* generic/tcl.h:       Declared, implemented, and documented the
+	* generic/tclInt.h:    specified new API functions. Moved the
+	* unix/tclUnixEvent.c: native (OS) access to time information
+	* unix/tclUnixNotfy.c: into standard handler functions. Inserted
+	* unix/tclUnixTime.c:  hooks calling on the handlers where native
+	* win/tclWinNotify.c:  access was done before, and where scaling
+	* win/tclWinTime.c:    between domains (real/virtual) is required.
+
+2005-01-21  Andreas Kupries  <andreask@activestate.com>
+
+	* generic/tclThread.c: Typo police. Fixed some nits
+	* generic/tclCmdAH.c:  in header comments of functions.
+	* generic/tclBasic.c:  (Missing --).
+	* generic/tclFileName.c:
+
+2005-01-21  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* doc/FileSystem.3: Add missing ARGUMENTS section definitions for
+	arguments to Tcl_FSLink. [Bug 1106272]
+
+2005-01-21  Kevin B. Kenny  <kennykb@acm.org>
+
+	[kennykb-numerics-branch]
+
+	* unix/Makefile.in: Updated Makefile to build libtommath on Unix as
+	well as Windows. [Bug 1106865]
+
+	* generic/tclTestObj.c (TestbignumobjCmd): Silenced a compiler warning
+	about a mismatched 'const'.
+
+2005-01-20  Kevin B. Kenny  <kennykb@acm.org>
+
+	[kennykb-numerics-branch] Development checkpoint.
+
+	* compat/strtoll.c:	Reverted to HEAD.
+	* compat/strtoull.c:
+	* doc/Ensemble.3:
+	* generic/tclBasic.c:
+	* generic/tclCmdIL.c:
+	* generic/tclNamesp.c:
+	* generic/tclPathObj.c:
+	* generic/tclPort.h:
+	* unix/configure:
+	* unix/configure.in:
+	* unix/tcl.m4:
+	* win/configure:
+	* win/configure.in:
+	* win/rules.vc:
+	* win/tcl.m4:
+
+	* generic/tcl.h: Added declarations for bignum types, and for a
+	'bignumValue' in the Tcl_Obj structure.
+	* generic/tclInt.h: Added declarations of interface procedures for
+	memory allocation in libtommath.
+
+	* generic/tcl.decls: Added new interface to bignum objects.
+	* generic/tclInt.decls: Added internal stubs for bignum routines used
+	by the test code in tclTestObj.c.
+
+	* generic/tclDecls/h: Regen.
+	* generic/tclIntDecls.h:
+	* generic/tclStubInit.h:
+
+	* tools/fix_tommath_h.tcl: (New file) Script to edit
+	libtommath/tommath.h and produce generic/tommath.h so that storage
+	classes, allocation routines, and data types conform to Tcl's
+	conventions.
+	* generic/tommath.h: (New file) Generated by the above.
+
+	* generic/tclTomMath.h: (New file) Additional declarations to be
+	included in tommath.h when building Tcl.
+
+	* generic/tclTomMathInterface.c: (New file) Small 'glue' routines
+	adapting tommath's API to Tcl.
+
+	* libtommath/bn_fast_s_mp_mul_digs.c:
+	* libtommath/bn_mp_mul_d.c:
+	* libtommath/bn_mp_read_radix.c:
+	* libtommath/tommath.h: Applied suggested changes from Tom St Denis
+	that correct an off-by-one error in single-digit multiplication
+	(leading to a pointer smash if uncorrected) and change the string
+	argument to 'mp_read_radix' from 'char*' to 'const char*'.
+
+	* libtommath/bn_mp_radix_size.c: Local patch to ensure that sufficient
+	memory is requested even if the number has a single digit.
+
+	* libtommath/bn_mp_read_radix.c: Local patch to return MP_VAL if the
+	input string contains an invalid character.
+
+	* generic/tclObj.c: Added accessor functions for bignums.
+	* generic/tclTestObj.c: Added a 'testbignumobj' command to exercise the
+	accessor functions for bignums.
+
+	* win/Makefile.in: Added rules for making libtommath.
+
+2005-01-19  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	TIP#235 IMPLEMENTATION
+
+	* doc/Ensemble.3: Documentation for the new public API.
+	* generic/tclNamesp.c (Tcl_CreateEnsemble,...): Rename of
+	* generic/tcl.decls:		existing API into TIPped form.
+
+2005-01-19  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* win/tclWinChan.c (FileCloseProc): Invoke TclpCutFileChannel() to
+	remove a FileInfo from the thread local list before deallocating it.
+	This should have been done via an earlier call to Tcl_CutChannel, but I
+	was running into a crash in the next call to Tcl_CutChannel during the
+	I/O finalization stage.
+
+2005-01-18  Kevin Kenny  <kennykb@acm.org>
+
+	* library/tzdata/GMT+0:
+	* library/tzdata/GMT-0:
+	* library/tzdata/GMT0:
+	* library/tzdata/Greenwich:
+	* library/tzdata/Navajo:
+	* library/tzdata/Universal:
+	* library/tzdata/Zulu:
+	* library/tzdata/America/Asuncion:
+	* library/tzdata/America/Rosario:
+	* library/tzdata/Asia/Jerusalem:
+	* library/tzdata/Brazil/Acre:
+	Routine update per Olson's tzdata2005c. Removed links to links
+	(Greenwich in several aliases; Navajo; Acre). Updated Paraguayan DST
+	rules and "best guess" at this year's Israeli rules.
+
+2005-01-17  Vince Darley  <vincentdarley@users.sourceforge.net>
+
+	* generic/tclFileName.c: fix for glob failure on Windows shares [Bug
+	1100542].
+
+	* doc/pkgMkIndex.n: added documentation that 'pkg_mkIndex -lazy' is not
+	a good idea. [Bug 1101678]
+
+2005-01-14  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* tests/compile.test (compile-17.1): Document known issue with binding
+	time of compiled command interpretations in [expr].
+
+	* generic/tclIOUtil.c (TclFSFileAttrIndex): New helper function so that
+	we don't need to hard-code attribute indexes. [Bug 1100671]
+
+2005-01-13  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* doc/string.n: Removed the term 'set' from the documentation of the
+	[string trim] commands, as it caused confusion.
+
+2005-01-12  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* unix/tcl.m4 (SC_PATH_{TCL,TK}CONFIG): Added code to detect the case
+	when the --with-tcl/--with-tk arguments point to the config scripts
+	themselves and not their directory. If this is the case, they now
+	complain but keep working. [FRQ 951247]
+	* unix/configure:	autoconf-2.57
+
+2005-01-10  Joe English  <jenglish@users.sourceforge.net>
+
+	* unix/Makefile.in, unix/configure.in, unix/tcl.m4,
+	* unix/tclConfig.sh.in, unix/dltest/Makefile.in:
+	Remove ${DBGX}, ${TCL_DBGX} from Tcl build system [Patch 1081595].
+	* unix/configure: regenerated
+
+2005-01-10  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* unix/tclUnixFCmd.c (TclUnixCopyFile): Convert u_int to unsigned to
+	make clashes with types in standard C headers less of a problem. [Bug
+	1098829]
+
+2005-01-09  Joe English  <jenglish@users.sourceforge.net>
+
+	* unix/tclUnixThrd.c, unix/tclUnixPort.h: Remove readdir_r() and
+	related #ifdeffery (see [Bug 1095909]).
+	* unix/tcl.m4, unix/tclConfig.h.in: Don't check for HAVE_READDIR_R.
+	* unix/configure: Regenerated.
+
+2005-01-06  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* library/http/http.tcl (http::mapReply): Significant performance
+	enhancement by using [string map] instead of [regsub]/[subst], and
+	update version requirement to Tcl8.4. [Bug 1020491]
+
+2005-01-05  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* doc/lsearch.n, doc/re_syntax.n: Convert to other form of emacs mode
+	control comment to prevent problems with old versions of man. [Bug
+	1085127]
+
+2005-01-05  Pat Thoyts	<patthoyts@users.sourceforge.net>
+
+	* tests/winDde.test: Fixed broken test result.
+
+2005-01-05  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* generic/tclInt.h, generic/tclPort.h: Move the #include of tclConfig.h
+	*first* before any reference to tcl.h so that the build configuration
+	is loaded before the first reference to any system headers. Issue
+	reported by Art Haas on tcl-core.
+
+2005-01-04  Don Porter	<dgp@users.sourceforge.net>
+
+	* tests/fCmd.test (fCmd-18.10):	Added notNetworkFilesystem constraint.
+	[Bug 456665]
+
+	******************************************************************
+	*** CHANGELOG ENTRIES FOR 2004 IN "ChangeLog.2004"	       ***
+	*** CHANGELOG ENTRIES FOR 2003 IN "ChangeLog.2003"	       ***
+	*** CHANGELOG ENTRIES FOR 2002 IN "ChangeLog.2002"	       ***
+	*** CHANGELOG ENTRIES FOR 2001 IN "ChangeLog.2001"	       ***
+	*** CHANGELOG ENTRIES FOR 2000 IN "ChangeLog.2000"	       ***
+	*** CHANGELOG ENTRIES FOR 1999 AND EARLIER IN "ChangeLog.1999" ***
+	******************************************************************
diff --git a/ChangeLog.2007 b/ChangeLog.2007
new file mode 100644
index 0000000..5995956
--- /dev/null
+++ b/ChangeLog.2007
@@ -0,0 +1,5921 @@
+2007-12-31  Donal K. Fellows  <dkf@users.sf.net>
+
+	* doc/dict.n: Clarified meaning of dictionary values following
+	discussion on comp.lang.tcl.
+
+2007-12-26  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclCmdIL.c: More [lsort] data handling streamlines. The
+	function MergeSort is gone, essentially inlined into Tcl_LsortObjCmd.
+	It is not a straight inlining, two loops over all lists elements where
+	merged in the process: the linked list elements are now built and
+	merged into the temporary sublists in the same pass.
+
+2007-12-25  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclCmdIL.c: More [lsort] data handling streamlines. Extra
+	mem reqs of latest patches removed, restored to previous mem profile.
+	Improved -unique handling, now eliminating repeated elems immediately
+	instead of marking them to avoid reinsertion at the end.
+
+2007-12-23  Jeff Hobbs	<jeffh@ActiveState.com>
+
+	* generic/tclCompCmds.c (TclCompileRegexpCmd):	TCL_REG_NOSUB cannot
+	* tests/regexp.test (regexp-22.2):		be used because it
+	* tests/regexpComp.test:	[Bug 1857126]	disallows backrefs.
+
+2007-12-21  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclCmdIL.c: Speed patch for lsort. [Patch 1856994]
+
+2007-12-21  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclCmdIL.c (Tcl_LsortObjCmd, Tcl_LsearchObjCmd): Avoid
+	calling SelectObjFromSublist when there are no sublists.
+
+2007-12-21  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclCmdIL.c (Tcl_LsortObjCmd): Preallocate a listObj of
+	sufficient length for the sorted list instead of growing it. Second
+	commit replaces calls to Tcl_ListObjAppenElement with direct access to
+	the internal rep.
+
+2007-12-19  Don Porter	<dgp@users.sourceforge.net>
+
+	*** 8.5.0 TAGGED FOR RELEASE ***
+
+	* changes:		Updated for 8.5.0 release.
+
+2007-12-19  Jeff Hobbs	<jeffh@ActiveState.com>
+
+	* generic/tclCompCmds.c (TclCompileSwitchCmd):	update switch -regexp
+	* tests/switch.test-14.*:			compilation to pass
+	the cflags to INST_REGEXP (changed on 12-07). Added tests for switch
+	-regexp compilation (need more). [Bug 1854399]
+
+2007-12-18  Don Porter	<dgp@users.sourceforge.net>
+
+	* changes:		Updated for 8.5.0 release.
+
+2007-12-18  Donal K. Fellows  <donal.k.fellows@manchester.ac.uk>
+
+	* generic/regguts.h, generic/regc_color.c, generic/regc_nfa.c:
+	Fixes for problems created when processing regular expressions that
+	generate very large automata. An enormous number of thanks to Will
+	Drewry <wad_at_google.com>, Tavis Ormandy <taviso_at_google.com>,
+	and Tom Lane <tgl_at_sss.pgh.pa.us> from the Postgresql crowd for
+	their help in tracking these problems down. [Bug 1810264]
+
+2007-12-17  Don Porter	<dgp@users.sourceforge.net>
+
+	* changes:		Updated for 8.5.0 release.
+
+2007-12-17  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclAlloc.c:
+	* generic/tclExecute.c:
+	* generic/tclInt.h:
+	* generic/tclThreadAlloc.c: Fix alignment for memory returned by
+	TclStackAlloc; insure that all memory allocators align to 16-byte
+	boundaries on 64 bit platforms [Bug 1851832, 1851524]
+
+2007-12-14  Jeff Hobbs	<jeffh@ActiveState.com>
+
+	* generic/tclIOUtil.c (FsAddMountsToGlobResult): fix the tail
+	conversion of vfs mounts. [Bug 1602539]
+
+	* win/README: updated notes
+
+2007-12-14  Pat Thoyts	<patthoyts@users.sourceforge.net>
+
+	* tests/winFile.test: Fixed tests for win2k with long machine name
+
+2007-12-14  Pat Thoyts <patthoyts@users.sourceforge.net>
+
+	* win/nmakehlp.c:  Support compilation with MSVC9 for AMD64.
+	* win/makefile.vc:
+
+2007-12-13  Donal K. Fellows  <donal.k.fellows@manchester.ac.uk>
+
+	* doc/trace.n: Clarified documentation of enterstep and leavestep
+	traces, including adding example. [Bug 614282, 1701540, 1755984]
+
+2007-12-12  Don Porter	<dgp@users.sourceforge.net>
+
+	* doc/IntObj.3:	Update docs for the Tcl_GetBignumAndClearObj() ->
+	Tcl_TakeBignumFromObj() revision [TIP 298]. Added docs for the
+	Tcl_InitBignumFromDouble() routine. [Bug 1446971]
+
+	* changes:		Updated for 8.5.0 release.
+
+2007-12-10  Jeff Hobbs	<jeffh@ActiveState.com>
+
+	* generic/tclUtil.c (TclReToGlob): reduce escapes in conversion
+	when not necessary
+
+	* generic/tclInt.decls:	 move TclByteArrayMatch and TclReToGlob
+	* generic/tclIntDecls.h: to tclInt.h from stubs.
+	* generic/tclStubInit.c: Add flags var to TclByteArrayMatch for
+	* generic/tclInt.h:	 future extensibility
+	* generic/tcl.h:  define TCL_MATCH_EXACT doc for Tcl_StringCaseMatch.
+	* doc/StrMatch.3: It is compatible with existing usage.
+	* generic/tclExecute.c (INST_STR_MATCH): flag for TclByteArrayMatch
+	* generic/tclUtil.c (TclByteArrayMatch, TclStringMatchObj):
+	* generic/tclRegexp.c (Tcl_RegExpExecObj):
+	* generic/tclCmdMZ.c (StringMatchCmd): Use TclStringMatchObj
+	* tests/string.test (11.9.* 11.10.*): more tests
+
+2007-12-10  Joe English	 <jenglish@users.sourceforge.net>
+
+	* doc/string.n, doc/UniCharIsAlpha.3: Fix markup errors.
+	* doc/CrtCommand.3, doc/CrtMathFnc.3, doc/FileSystem.3,
+	* doc/GetStdChan.3, doc/OpenFileChnl.3, doc/SetChanErr.3,
+	* doc/eval.n, doc/filename.n: Consistency: Move "KEYWORDS" section
+	after "SEE ALSO".
+
+2007-12-10  Daniel Steffen  <das@users.sourceforge.net>
+
+	* tools/genStubs.tcl:		fix numerous issues handling 'macosx',
+					'aqua' or 'x11' entries interleaved
+					with 'unix' entries [Bug 1834288]; add
+					genStubs::export command
+					[Tk FR 1716117]; cleanup formatting.
+
+	* generic/tcl.decls:		use new genstubs 'export' command to
+	* generic/tclInt.decls:		mark exported symbols not in stubs
+	* generic/tclTomMath.decls:	table [Tk FR 1716117]; cleanup
+					formatting.
+
+	* generic/tclDecls.h:		regen with new genStubs.tcl.
+	* generic/tclIntDecls.h:	[Bug 1834288]
+	* generic/tclIntPlatDecls.h:
+	* generic/tclPlatDecls.h:
+	* generic/tclStubInit.c:
+
+2007-12-09  Jeff Hobbs	<jeffh@ActiveState.com>
+
+	* tests/io.test, tests/chanio.test (io-73.1): Make sure to invalidate
+	* generic/tclIO.c (SetChannelFromAny):	      internal rep only after
+	validating channel rep. [Bug 1847044]
+
+2007-12-08  Donal K. Fellows  <dkf@users.sf.net>
+
+	* doc/expr.n, doc/mathop.n: Improved the documentation of the
+	operators. [Bug 1823622]
+
+	* generic/tclBasic.c (builtInCmds): Corrected list of hidden and
+	* doc/interp.n (SAFE INTERPRETERS): exposed commands so that the
+	documentation and reality now match. [Bug 1662436]
+
+2007-12-07  Jeff Hobbs	<jeffh@ActiveState.com>
+
+	* generic/tclExecute.c (TclExecuteByteCode INST_REGEXP):
+	* generic/tclCompCmds.c (TclCompileRegexpCmd): Pass correct RE
+	compile flags at compile time, and use TCL_REG_NOSUB.
+
+	* generic/tclIOCmd.c (FinalizeIOCmdTSD, Tcl_PutsObjCmd): cache
+	stdout channel object for [puts $str] calls.
+
+2007-12-06  Don Porter	<dgp@users.sourceforge.net>
+
+	* README:	Remove mention of dead comp.lang.tcl.announce
+	newsgroup. [Bug 1846433]
+
+	* unix/README:	Mention the stub library created by `make` and warn
+	about the effect of embedded paths in the installed binaries.
+	Thanks to Larry Virden. [Bug 1794084]
+
+	* doc/AddErrInfo.3:	Documentation for the new routines in TIP 270.
+	* doc/Interp.3:
+	* doc/StringObj.3:
+
+2007-12-06  Don Porter	<dgp@users.sourceforge.net>
+
+	* doc/namespace.n:	Documentation for zero-argument form of
+	[namespace import] (TIP 261) [Bug 1596416]
+
+2007-12-06  Jeff Hobbs	<jeffh@ActiveState.com>
+
+	* generic/tclInt.h: add TclGetChannelFromObj decl
+	(TclMatchIsTrivial): simplify TclMatchIsTrivial to remove ] check.
+
+2007-12-06  Donal K. Fellows  <donal.k.fellows@manchester.ac.uk>
+
+
+	* generic/tclBasic.c (Tcl_CreateInterp): Simplify the setting up of
+	* generic/tclIOCmd.c (TclInitChanCmd):	 the [chan] ensemble. This
+	* library/init.tcl:			 gets rid of quite a bit of
+	code and makes it possible to understand the whole with less effort.
+
+	* generic/tclCompCmds.c (TclCompileEnsemble): Ensure that the right
+	number of tokens are copied. [Bug 1845320]
+
+	* generic/tclNamesp.c (TclMakeEnsemble): Added missing release of a
+	DString. [Bug 1845397]
+
+2007-12-05  Jeff Hobbs	<jeffh@ActiveState.com>
+
+	* generic/tclIO.h:    Create Tcl_Obj for Tcl channels to reduce
+	* generic/tclIO.c:    overhead in lookup by Tcl_GetChannel. New
+	* generic/tclIOCmd.c: TclGetChannelFromObj for internal use.
+	* generic/tclIO.c (WriteBytes, WriteChars): add opt check to avoid
+	EOL translation when not linebuffered or using lf. [Bug 1845092]
+
+2007-12-05  Miguel Sofer  <msofer@users.sf.net>
+
+	* tests/stack.test: made the tests for stack overflow not care
+	about which mechanism caused the error (interp's recursion limit
+	or C-stack depth detector).
+
+2007-12-05  Jeff Hobbs	<jeffh@ActiveState.com>
+
+	* win/configure, win/tcl.m4 (LIBS_GUI): mingw needs -lole32
+	-loleaut32 but not msvc for Tk's [send]. [Bug 1844749]
+
+2007-12-05  Donal K. Fellows  <donal.k.fellows@manchester.ac.uk>
+
+	* generic/tclCmdIL.c (Tcl_LsearchObjCmd): Prevent shimmering crash
+	when -exact and -integer/-real are mixed. [Bug 1844789]
+
+2007-12-03  Donal K. Fellows  <dkf@users.sf.net>
+
+	* unix/tclUnixChan.c (CreateSocketAddress): Add extra #ifdef-fery to
+	make code compile on BSD 5. [Bug 1618235, again]
+
+2007-12-03  Don Porter	<dgp@users.sourceforge.net>
+
+	* library/tcltest/tcltest.tcl:	Bump tcltest to version 2.3.0 so that
+	* library/tcltest/pkgIndex.tcl: we release a stable tcltest with a
+	* unix/Makefile.in:	stable Tcl.
+	* win/Makefile.in:
+
+2007-12-03  Jeff Hobbs	<jeffh@ActiveState.com>
+
+	* win/configure, win/tcl.m4 (LIBS_GUI): remove ole32.lib oleaut32.lib
+
+2007-12-03  Donal K. Fellows  <donal.k.fellows@manchester.ac.uk>
+
+	* generic/tclCompCmds.c (TclCompileSwitchCmd): Adjusted the [switch]
+	* generic/tclCmdMZ.c (Tcl_SwitchObjCmd):       command so that when
+	passed two arguments, no check for options are performed. This is OK
+	since in the two-arg case, detecting an option would definitely lead
+	to a syntax error. [Patch 1836519]
+
+2007-11-29  Jeff Hobbs	<jeffh@ActiveState.com>
+
+	* win/makefile.vc: add ws2_32.lib to baselibs
+	* win/configure, win/tcl.m4: add ws2_32.lib / -lws2_32 to build.
+	* win/tclWinSock.c: remove dyn loading of winsock, assume that it is
+	always available now.
+
+2007-11-29  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclWinSock.c (InitializeHostName):	Correct error in
+	buffer length tracking. After gethostname() writes into a buffer,
+	convert only the written string to internal encoding, not the whole
+	buffer.
+
+2007-11-28  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclConfig.c:	Corrected failure of the [::foo::pkgconfig]
+	command to clean up registered configuration data when the query
+	command is deleted from the interp. [Bug 983501]
+
+	* generic/tclNamesp.c (Tcl_SetEnsembleMappingDict):	Added checks
+	that the dict value passed in is in the format required to make the
+	internals of ensembles work. [Bug 1436096]
+
+	* generic/tclIO.c:	Simplify test and improve accuracy of error
+	message in latest changes.
+
+2007-11-28  Pat Thoyts	<patthoyts@users.sourceforge.net>
+
+	* generic/tclIO.c: -eofchar must support no eofchar.
+
+2007-11-27  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclBasic.c: remove unneeded call in Tcl_CreateInterp, add
+	comments.
+
+2007-11-27  Don Porter	<dgp@users.sourceforge.net>
+
+	* win/tclWinSock.c:	Add mising encoding conversion of the [info
+	hostname] value from the system encoding to Tcl's internal encoding.
+
+	* doc/chan.n:		"Fix" the limitation on channel -eofchar
+	* doc/fconfigure.n:	values to single byte characters by
+	* generic/tclIO.c:	documenting it and making it fail loudly.
+	* tests/chan.test:	Thanks to Stuart Cassoff for contributing the
+				fix. [Bug 800753]
+
+2007-11-26  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclBasic.c:
+	* generic/tclInt.h:
+	* unix/tclUnixInit.c:
+	* unix/tclUnixThrd.c: Fix stack checking via workaround for bug in
+	glibc's pthread_attr_get_np, patch from [Bug 1815573]. Many thanks to
+	Sergei Golovan (aka Teo) for detecting the bug and helping diagnose
+	and develop the fix.
+
+2007-11-24  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclCompCmds.c (TclCompileDictAppendCmd): Fix bug in [dict
+	append] compiler which caused strange stack corruption. [Bug 1837392]
+
+2007-11-23  Andreas Kupries  <andreask@activestate.com>
+
+	* generic/tclIORChan.c: Fixed a problem with reflected channels. 'chan
+	postevent' is defined to work only from within the interpreter
+	containing the handler command. Sensible, we want only handler
+	commands to use it. It identifies the channel by handle. The channel
+	moves to a different interpreter or thread. The interpreter containing
+	the handler command doesn't know the channel any longer. 'chan
+	postevent' fails, not finding the channel any longer. Uhm.
+
+	Fixed by creating a second per-interpreter channel table, just for
+	reflected channels, where each interpreter remembers for which
+	reflected channels it has the handler command. This info does not move
+	with the channel itself. The table is updated by 'chan create', and
+	used by 'chan postevent'.
+
+	* tests/ioCmd.test: Updated the testsuite.
+
+2007-11-23  Jeff Hobbs	<jeffh@ActiveState.com>
+
+	* generic/tclVar.c (Tcl_ArrayObjCmd): handle the right data for
+	* tests/var.test (var-14.2):	      [array names $var -glob $ptn]
+
+2007-11-23  Donal K. Fellows  <donal.k.fellows@manchester.ac.uk>
+
+	* generic/tclCmdMZ.c (String*Cmd, TclInitStringCmd): Rebuilt [string]
+	* generic/tclCompCmds.c (TclCompileString*Cmd): as an ensemble.
+
+2007-11-22  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclDictObj.c (Dict*Cmd,TclInitDictCmd): Rebuilt the [dict]
+	* generic/tclCompCmds.c (TclCompileDict*Cmd): command as an ensemble.
+
+2007-11-22  Donal K. Fellows  <donal.k.fellows@manchester.ac.uk>
+
+	* generic/tclCmdMZ.c (Tcl_StringObjCmd): Rewrote the [string] and
+	* generic/tclDictObj.c (Tcl_DictObjCmd): [dict] implementations to be
+	ready for conversion to ensembles.
+
+	* tests/string.test (string-12.22): Flag shimmering bug found in
+	[string range].
+
+2007-11-21  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclCompCmds.c (TclCompileEnsemble): Rewrote the ensemble
+	compiler to remove many of the limitations. Can now compile scripts
+	that use unique prefixes of subcommands, and which have mappings of a
+	command to multiple words (provided the first is a compilable command
+	of course).
+
+2007-11-21  Donal K. Fellows  <donal.k.fellows@manchester.ac.uk>
+
+	* generic/tclNamesp.c (TclMakeEnsemble): Factor out the code to set up
+	a core ensemble from a table of information about subcommands, ready
+	for reuse within the core.
+
+	* generic/various: Start to return more useful Error codes, currently
+	mainly on assorted lookup failures.
+
+2007-11-20  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclDictObj.c: Changed the underlying implementation of the
+	hash table used in dictionaries to additionally keep all entries in
+	the hash table in a linked list, which is only ever added to at the
+	end. This makes iteration over all entries in the dictionary in
+	key insertion order a trivial operation, and so cleans up a great deal
+	of complexity relating to dictionary representation and stability of
+	iteration order.
+
+	***POTENTIAL INCOMPATIBILITY***
+	For any code that depended on the (strange) old iteration order.
+
+	* generic/tclConfig.c (QueryConfigObjCmd): Correct usage of
+	Tcl_WrongNumArgs.
+
+2007-11-19  Don Porter	<dgp@users.sourceforge.net>
+
+	*** 8.5b3 TAGGED FOR RELEASE ***
+
+	* README:		Bump version number to 8.5b3.
+	* generic/tcl.h:
+	* library/init.tcl:
+	* tools/tcl.wse.in:
+	* unix/configure.in:
+	* unix/tcl.spec:
+	* win/configure.in:
+
+	* unix/configure:	autoconf (2.59)
+	* win/configure:
+
+	* changes:		Updated for 8.5b3 release.
+
+2007-11-19  Kevin Kenny	 <kennykb@users.sourceforge.net>
+
+	* library/tzdata/Africa/Cairo:
+	* library/tzdata/America/Campo_Grande:
+	* library/tzdata/America/Caracas:
+	* library/tzdata/America/Cuiaba:
+	* library/tzdata/America/Havana:
+	* library/tzdata/America/Sao_Paulo:
+	* library/tzdata/Asia/Damascus:
+	* library/tzdata/Asia/Gaza:
+	* library/tzdata/Asia/Tehran:  Olson's tzdata2007i imported.
+
+2007-11-18  Daniel Steffen  <das@users.sourceforge.net>
+
+	* generic/tclExecute.c (TclExecuteByteCode:INST_EXIST_*): Fix read
+	traces not firing on non-existent array elements. [Bug 1833522]
+
+2007-11-16  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* generic/tclCmdIL.c (TclInitInfoCmd): Rename the implementation
+	commands for [info] to be something more "expected".
+
+	* generic/tclCompCmds.c (TclCompileInfoExistsCmd): Compiler for the
+	[info exists] subcommand.
+	(TclCompileEnsemble): Cleaned up version of ensemble compiler that was
+	in TclCompileInfoCmd, but which is now much more generally applicable.
+
+	* generic/tclInt.h (ENSEMBLE_COMPILE): Added flag to allow for cleaner
+	turning on and off of ensemble bytecode compilation.
+
+	* generic/tclCompile.c (TclCompileScript): Add the cmdPtr to the list
+	of arguments passed to command compilers.
+
+2007-11-15  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/regc_nfa.c:	Fixed infinite loop in the regexp compiler.
+	[Bug 1810038]
+
+	* generic/regc_nfa.c:	Corrected looping logic in fixempties() to
+	avoid wasting time walking a list of dead states. [Bug 1832612]
+
+2007-11-15  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* generic/tclNamesp.c (NamespaceEnsembleCmd): Must pass a non-NULL
+	interp to Tcl_SetEnsemble* functions.
+
+	* doc/re_syntax.n: Try to make this easier to read. It's still a very
+	difficult manual page!
+
+	* unix/tcl.m4 (SC_CONFIG_CFLAGS): Allow people to turn off the -rpath
+	option to their linker if they so desire. This is a configuration only
+	recommended for (some) vendors. Relates to [Patch 1231022].
+
+2007-11-15  Pat Thoyts	<patthoyts@users.sourceforge.net>
+
+	* win/tclWin32Dll.c: Prefer UINT_PTR to DWORD_PTR when casting
+	pointers to integer types for greater portability. [Bug 1831253]
+
+2007-11-15  Daniel Steffen  <das@users.sourceforge.net>
+
+	* macosx/Tcl.xcodeproj/project.pbxproj: add new chanio.test.
+	* macosx/Tcl.xcode/project.pbxproj:
+
+2007-11-14  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* generic/tclCompile.c (TclCompileScript): Ensure that we get our
+	count in our INST_START_CMD calls right, even when there's a failure
+	to compile a command directly.
+
+	* generic/tclNamesp.c (Tcl_SetEnsembleSubcommandList)
+	(Tcl_SetEnsembleMappingDict):		Special code to make sure that
+	* generic/tclCmdIL.c (TclInitInfoCmd):	[info exists] is compiled
+	right while not allowing changes to the ensemble to cause havok.
+
+	* generic/tclCompCmds.c (TclCompileInfoCmd): Simple compiler for the
+	[info] command that only handles [info exists].
+
+	* generic/tclExecute.c (TclExecuteByteCode:INST_EXIST_*): New
+	instructions to allow the testing of whether a variable exists.
+
+2007-11-14  Andreas Kupries  <andreask@activestate.com>
+
+	* tests/chanio.test: New file. This is essentially a duplicate of
+	'io.test', with all channel commands converted to their 'chan xxx'
+	notation.
+	* tests/io.test: Fixed typo in test description.
+
+2007-11-14  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* generic/regc*.c: Eliminate multi-char collating element code
+	completely. Simplifies the code quite a bit. If people still want the
+	full code, it will remain on the 8.4 branch. [Bug 1831425]
+
+2007-11-13  Jeff Hobbs	<jeffh@ActiveState.com>
+
+	* generic/tclCompCmds.c (TclCompileRegexpCmd): clean up comments, only
+	free dstring on OK from TclReToGlob.
+	(TclCompileSwitchCmd): simplify TclReToGlob usage.
+
+2007-11-14  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/regc*.c: #ifdef/comment out the code that deals with
+	multi-character collating elements, which have never been supported.
+	Cuts the memory consumption of the RE compiler. [Bug 1831425]
+
+2007-11-13  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclCompCmds.c (TclCompileSwitchCmd, TclCompileRegexpCmd):
+	Extend [switch] compiler to handle regular expressions as long as
+	things are not too complex. Fix [regexp] compiler so that non-trivial
+	literal regexps get fed to INST_REGEXP.
+
+	* doc/mathop.n: Clarify definitions of some operations.
+
+2007-11-13  Miguel Sofer  <msofer@users.sf.net>
+
+	* unix/tclUnixInit.c: the TCL_NO_STACK_CHECK was being incorrectly
+	undefined here; this should be set (or not) in the compile options, it
+	is used elsewhere and needs to be consistent.
+
+2007-11-13  Pat Thoyts	<patthoyts@users.sourceforge.net>
+
+	* unix/tcl.m4:		Added autoconf goo to detect and make use of
+	* unix/configure.in:	getaddrinfo and friends.
+	* unix/configure:	(regenerated)
+
+2007-11-13  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* unix/tclUnixCompat.c (TclpGetHostByName): The six-argument form of
+	getaddressbyname_r() uses the fifth argument to indicate whether the
+	lookup succeeded or not on at least one platform. [Bug 1618235]
+
+2007-11-13  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/regcomp.c:	Convert optst() from expensive no-op to a
+	cheap no-op.
+
+2007-11-13  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* unix/tclUnixChan.c (CreateSocketAddress): Rewrote to use the
+	thread-safe version of gethostbyname() by forward-porting the code
+	used in 8.4, and added rudimentary support for getaddrinfo() (not
+	enabled by default, as no autoconf-ery written). Part of fix for [Bug
+	1618235].
+
+2007-11-12  Jeff Hobbs	<jeffh@ActiveState.com>
+
+	* generic/tclGet.c (Tcl_Get, Tcl_GetInt): revert use of TclGet* macros
+	due to compiler warning. These cases won't save time either.
+
+	* generic/tclUtil.c (TclReToGlob): add more comments, set interp
+	result if specified on error.
+
+2007-11-12  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclBasic.c:		New macro TclResetResult, new iPtr
+	* generic/tclExecute.c:		flag bit INTERP_RESULT_UNCLEAN:
+	* generic/tclInt.h:		shortcut for Tcl_ResetResult for the
+	* generic/tclProc.c:		"normal" case: TCL_OK, no return
+	* generic/tclResult.c:		options, no errorCode nor errorInfo,
+	* generic/tclStubLib.c:		return at normal level. [Patch
+	* generic/tclUtil.c:		1830184]
+
+	THIS PATCH WAS REVERTED: initial (mis)measurements overstated the
+	perfomance wins, which turn out to be tiny. Not worth the
+	complication.
+
+2007-11-11  Jeff Hobbs	<jeffh@ActiveState.com>
+
+	* generic/tclCompCmds.c, generic/tclCompile.c, generic/tclCompile.h:
+	* generic/tclExecute.c, generic/tclInt.decls, generic/tclIntDecls.h:
+	* generic/tclRegexp.c, generic/tclRegexp.h: Add INST_REGEXP and fully
+	* generic/tclStubInit.c, generic/tclUtil.c: compiled [regexp] for the
+	* tests/regexpComp.test:     [Bug 1830166]  simple cases. Also added
+	TclReToGlob function to convert RE to glob patterns and use these in
+	the possible cases.
+
+2007-11-11  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclResult.c (ResetObjResult): clarify the logic.
+
+	* generic/tclBasic.c:		Increased usage of macros to detect
+	* generic/tclBinary.c:		and take advantage of objTypes. Added
+	* generic/tclClock.c:		macros TclGet(Int|Long)FromObj,
+	* generic/tclCmdAH.c:		TclGetIntForIndexM & TclListObjLength,
+	* generic/tclCmdIL.c:		modified TclListObjGetElements.
+	* generic/tclCmdMZ.c:
+	* generic/tclCompCmds.c:	The TclGetInt* macros are only a
+	* generic/tclCompExpr.c:	shortcut on platforms where 'long' is
+	* generic/tclCompile.c:		'int'; it may be worthwhile to extend
+	* generic/tclDictObj.c:		their functionality to other cases.
+	* generic/tclExecute.c:
+	* generic/tclGet.c:		As this patch touches many files it
+	* generic/tclIO.c:		has been recorded as [Patch 1830038]
+	* generic/tclIOCmd.c:		in order to facilitate reviewing.
+	* generic/tclIOGT.c:
+	* generic/tclIndexObj.c:
+	* generic/tclInt.h:
+	* generic/tclInterp.c:
+	* generic/tclListObj.c:
+	* generic/tclLiteral.c:
+	* generic/tclNamesp.c:
+	* generic/tclObj.c:
+	* generic/tclParse.c:
+	* generic/tclProc.c:
+	* generic/tclRegexp.c:
+	* generic/tclResult.c:
+	* generic/tclScan.c:
+	* generic/tclStringObj.c:
+	* generic/tclUtil.c:
+	* generic/tclVar.c:
+
+2007-11-11  Daniel Steffen  <das@users.sourceforge.net>
+
+	* unix/tclUnixTime.c (TclpWideClicksToNanoseconds): Fix issues with
+	* generic/tclInt.h:				    int64_t overflow.
+
+	* generic/tclBasic.c:	Fix stack check failure case if stack grows up
+	* unix/tclUnixInit.c:	Simplify non-crosscompiled case.
+
+	* unix/configure:	autoconf-2.59
+	* unix/tclConfig.h.in:	autoheader-2.59
+
+2007-11-10  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclExecute.c: Fast path for INST_LIST_INDEX when the index
+	is not a list.
+
+	* generic/tclBasic.c:
+	* unix/configure.in:
+	* unix/tclUnixInit.c: Detect stack grwoth direction at compile time,
+	only fall to runtime detection when crosscompiling.
+
+	* unix/configure: autoconf 2.61
+
+	* generic/tclBasic.c:
+	* generic/tclInt.h:
+	* tests/interp.test:
+	* unix/tclUnixInit.c:
+	* win/tclWin32Dll.c: Restore simpler behaviour for stack checking, not
+	adaptive to stack size changes after a thread is launched. Consensus
+	is that "nobody does that", and so it is not worth the cost. Improved
+	failure comments (mistachkin).
+
+2007-11-10  Kevin Kenny	 <kennykb@acm.org>
+
+	* win/tclWin32Dll.c: Rewrote the Windows stack checking algorithm to
+	use information from VirtualQuery to determine the bound of the stack.
+	This change fixes a bug where the guard page of the stack was never
+	restored after an overflow. It also eliminates a nasty piece of
+	assembly code for structured exception handling on mingw. It
+	introduces an assumption that the stack is a single memory arena
+	returned from VirtualAlloc, but the code in MSVCRT makes the same
+	assumption, so it should be fairly safe.
+
+2007-11-10  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclBasic.c:
+	* generic/tclInt.h:
+	* unix/tclUnixInit.c:
+	* unix/tclUnixPort.h:
+	* win/tclWin32Dll.c: Modify the stack checking algorithm to recheck in
+	case of failure. The working assumptions are now that (a) a thread's
+	stack is never moved, and (b) a thread's stack can grow but not
+	shrink. Port to windows - could be more efficient, but is already
+	cheaper than it was.
+
+2007-11-09  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclResult.c (ResetObjResult): new shortcut.
+
+	* generic/tclAsync.c:
+	* generic/tclBasic.c:
+	* generic/tclExecute.c:
+	* generic/tclInt.h:
+	* generic/tclUnixInit.c:
+	* generic/tclUnixPort.h: New fields in interp (ekeko!) to cache TSD
+	data that is accessed at each command invocation, access macros to
+	replace Tcl_AsyncReady and TclpCheckStackSpace by much faster variants
+	[Patch 1829248]
+
+2007-11-09  Jeff Hobbs	<jeffh@ActiveState.com>
+
+	* generic/tclInt.decls, generic/tclIntDecls.h: Use unsigned char for
+	* generic/tclExecute.c, generic/tclUtil.c:     TclByteArrayMatch and
+	don't allow a nocase option. [Bug 1828296]
+	For INST_STR_MATCH, ignore pattern type for TclByteArrayMatch case.
+
+	* generic/tclBinary.c (Tcl_GetByteArrayFromObj): check type before
+	func jump (perf).
+
+2007-11-07  Jeff Hobbs	<jeffh@ActiveState.com>
+
+	* generic/tclStubInit.c:		     Added TclByteArrayMatch
+	* generic/tclInt.decls:			     for efficient glob
+	* generic/tclIntDecls.h:		     matching of ByteArray
+	* generic/tclUtil.c (TclByteArrayMatch):     Tcl_Objs, used in
+	* generic/tclExecute.c (TclExecuteByteCode): INST_STR_MATCH. [Bug
+						     1827996]
+
+	* generic/tclIO.c (TclGetsObjBinary): Add an efficient binary path for
+					      [gets].
+	(DoWriteChars): Special case for 1-byte channel write.
+
+2007-11-06  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclEncoding.c: Version of the embedded iso8859-1 encoding
+	handler that is faster (functions to do the encoding know exactly what
+	they're doing instead of pulling it from a table, though the table
+	itself has to be retained for use by shift encodings that depend on
+	iso8859-1). [Patch 1826906], committing for dkf.
+
+2007-11-05  Andreas Kupries  <andreask@activestate.com>
+
+	* generic/tclConfig.c (Tcl_RegisterConfig): Modified to not extend the
+	config database if the encoding provided by the user is not found
+	(venc == NULL). Scripts expecting the data will error out, however we
+	neither crash nor provide bogus information. See [Bug 983509] for more
+	discussion.
+
+	* unix/tclUnixChan.c (TtyGetOptionProc): Accepted [Patch 1823576]
+	provided by Stuart Cassof <stwo@users.sourceforge.net>. The patch adds
+	the necessary utf/external conversions to the handling of the
+	arguments of option -xchar which will allow the use of \0 and similar
+	characters.
+
+2007-11-03  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclTest.c (TestSetCmd2):
+	* generic/tclVar.c (TclObjLookupVarEx):
+	* tests/set.test (set-5.1): Fix error branch when array name looks
+	like array element (code not normally exercised).
+
+2007-11-01  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* tools/tcltk-man2html.tcl (output-directive): Convert .DS/.DE pairs
+	into tables since that is now all that they are used for.
+
+	* doc/RegExp.3: Clarified documentation of RE flags. [Bug 1167840]
+
+	* doc/refchan.n: Adjust internal name to be consistent with the file
+	name for reduced user confusion. After comment by Dan Steffen.
+
+	* generic/tclCmdMZ.c (Tcl_StringObjCmd, UniCharIsAscii): Remember, the
+	NUL character is in ASCII too. [Bug 1808258]
+
+	* doc/file.n: Clarified use of [file normalize]. [Bug 1185154]
+
+2007-10-30  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tcl.h:	Bump version number to 8.5b2.1 to distinguish
+	* library/init.tcl:	CVS development snapshots from the 8.5b2
+	* unix/configure.in:	release.
+	* unix/tcl.spec:
+	* win/configure.in:
+
+	* unix/configure:	autoconf (2.59)
+	* win/configure:
+
+2007-10-30  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* doc/expr.n, doc/mathfunc.n: Improve documentation to try to make
+	clearer what is going on.
+
+	* doc/interp.n: Shorten the basic descriptive text for some interp
+	subcommands so Solaris nroff doesn't truncate them. [Bug 1822268]
+
+2007-10-30  Donal K. Fellows  <dkf@users.sf.net>
+
+	* tools/tcltk-man2html.tcl (output-widget-options): Enhance the HTML
+	generator so that it can produce multi-line option descriptions.
+
+2007-10-28  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclUtil.c (Tcl_ConcatObj): optimise for some of the
+	concatenees being empty objs. [Bug 1447328]
+
+2007-10-28  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclEncoding.c (TclInitEncodingSubsystem): Hard code the
+	iso8859-1 encoding, as it's needed for more than just text (especially
+	binary encodings...) Note that other encodings rely on the encoding
+	being a table encoding (!) so we can't use more efficient encoding
+	mapping functions.
+
+2007-10-27  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/regc_lex.c (lexescape): Close off one of the problems
+	mentioned in [Bug 1810264].
+
+2007-10-27  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclNamesp.c (Tcl_FindCommand): insure that FQ command names
+	are searched from the global namespace, ie, bypassing resolvers of the
+	current namespace. [Bug 1114355]
+
+	* doc/apply.n: fixed example [Bug 1811791]
+	* doc/namespace.n: improved example [Bug 1788984]
+	* doc/AddErrInfo.3: typo [Bug 1715087]
+	* doc/CrtMathFnc.3: fixed Tcl_ListMathFuncs entry [Bug 1672219]
+
+	* generic/tclCompile.h:
+	* generic/tclInt.h: moved declaration of TclSetCmdNameObj from
+	tclCompile.h to tclInt.h, reverting linker [Bug 1821159] caused by
+	commit of 2007-10-11 (both I and gcc missed one dep).
+
+	* generic/tclVar.c: try to preserve Tcl_Objs when doing variable
+	lookups by name, partially addressing [Bug 1793601].
+
+2007-10-27  Donal K. Fellows  <dkf@users.sf.net>
+
+	* tools/tcltk-man2html.tcl (make-man-pages, htmlize-text)
+	(process-text): Make the man->HTML scraper work better.
+
+2007-10-26  Don Porter	<dgp@users.sourceforge.net>
+
+	*** 8.5b2 TAGGED FOR RELEASE ***
+
+	* changes:		Updated for 8.5b2 release.
+
+	* doc/*.1:		Revert doc changes that broke
+	* doc/*.3:		`make html` so we can get the release
+	* doc/*.n:		out the door.
+
+	* README:		Bump version number to 8.5b2.
+	* generic/tcl.h:
+	* library/init.tcl:
+	* tools/tcl.wse.in:
+	* unix/configure.in:
+	* unix/tcl.spec:
+	* win/configure.in:
+
+	* unix/configure:	autoconf (2.59)
+	* win/configure:
+
+2007-10-26  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* tools/man2help2.tcl, tools/man2tcl.c: Made some of the tooling code
+	to do man->other formats work better with current manpage set. Long
+	way still to go.
+
+2007-10-25  Zoran Vasiljevic <vasiljevic@users.sourceforge.net>
+
+	* generic/tclThread.c: Added TclpMasterLock/Unlock arround calls to
+	ForgetSyncObject in Tcl_MutexFinalize and Tcl_ConditionFinalize to
+	prevent from garbling the internal lists that track sync objects. [Bug
+	1726873]
+
+2007-10-24  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* tools/man2html2.tcl (macro): Added support for converting the new
+	macros into HTML.
+
+	* doc/man.macros (QW,PQ,QR,MT): New macros that hide the ugly mess
+	needed to get proper GOOBE quoting in the manual pages.
+	* doc/*.n, doc/*.3, doc/*.1: Lots of changes to take advantage of the
+	new macros.
+
+2007-10-20  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclCompile.c:	  Fix comments.
+	* generic/tclExecute.c:
+
+2007-10-18  David Gravereaux <davygrvy@pobox.com>
+
+	* tools/mkdepend.tcl: sort the dep list for a more humanly readable
+	output.
+
+2007-10-18  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclResult.c (TclMergeReturnOptions):	Make sure any -code
+	values get pulled out of the dictionary, even if they are integer
+	valued.
+
+	* generic/tclCompCmds.c (TclCompileReturnCmd):	Added code to more
+	optimally compile [return -level 0 $x] to "push $x". [RFE 1794073]
+
+	* compat/tmpnam.c (removed):	The routine tmpnam() is no longer
+	* unix/Makefile.in:	called by Tcl source code. Remove autogoo the
+	* unix/configure.in:	supplied a replacement version on systems
+	* win/tcl.dsp:		where the routine was not available. [RFE
+	1811848]
+
+	* unix/configure:	autoconf-2.59
+
+	* generic/tcl.h:	Remove TCL_LL_MODIFIER_SIZE. [RFE 1811837]
+
+2007-10-17  David Gravereaux <davygrvy@pobox.com>
+
+	* tools/mkdepend.tcl:	Improved defense from malformed object list
+	infile.
+
+2007-10-17  Donal K. Fellows  <donal.k.fellows@manchester.ac.uk>
+
+	* tools/man2html2.tcl: Convert .DS/.DE into HTML tables, not
+	preformatted text.
+
+2007-10-17  Kevin B. Kenny  <kennykb@acm.org>
+
+	* generic/tclCompExpr.c: Moved a misplaced declaration that blocked
+				 compilation on VC++.
+	* generic/tclExecute.c: Silenced several VC++ compiler warnings about
+				converting 'long' to 'unsigned short'.
+
+2007-10-16  David Gravereaux <davygrvy@pobox.com>
+
+	* win/makefile.vc: removed old dependency cruft that is no longer
+	needed.
+
+2007-10-15  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclIOCmd.c:	Revise [open] so that it interprets leading
+	zero strings passed as the "permissions" argument as octal numbers,
+	even if Tcl itself no longer parses integers in that way.
+
+	* unix/tclUnixFCmd.c:	Revise the "-permissions" [file attribute] so
+	that it interprets leading zero strings as octal numbers, even if Tcl
+	itself no longer parses integers in that way.
+
+	* generic/tclCompExpr.c:	Corrections to code that produces
+	* generic/tclUtil.c:		extended "bad octal" error messages.
+
+	* tests/cmdAH.test:	Test revisions so that tests pass whether or
+	* tests/cmdIL.test:	not Tcl parses leading zero strings as octal.
+	* tests/compExpr-old.test:
+	* tests/compExpr.test:
+	* tests/compile.test:
+	* tests/expr-old.test:
+	* tests/expr.test:
+	* tests/incr.test:
+	* tests/io.test:
+	* tests/lindex.test:
+	* tests/link.test:
+	* tests/mathop.test:
+	* tests/parseExpr.test:
+	* tests/set.test:
+	* tests/string.test:
+	* tests/stringComp.test:
+
+2007-10-15  David Gravereaux <davygrvy@pobox.com>
+
+	* tools/mkdepend.tcl:	Produces usable output. Include path problem
+	* win/makefile.vc:	fixed. Never fight city hall when it comes to
+	levels of quoting issues.
+
+2007-10-15  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclParse.c (Tcl_ParseBraces): fix for possible read after
+	the end of buffer. [Bug 1813528] (Joe Mistachkin)
+
+2007-10-14  David Gravereaux <davygrvy@pobox.com>
+
+	* tools/mkdepend.tcl (new):  Initial stab at generating automatic
+	* win/makefile.vc:	     dependencies.
+
+2007-10-12  Pat Thoyts	<patthoyts@users.sourceforge.net>
+
+	* win/makefile.vc:  Mine all version information from headers.
+	* win/rules.vc:	    Sync tcl and tk and bring extension versions
+	* win/nmakehlp.c:   closer together. Try and avoid using tclsh to do
+			    substitutions as we may cross compile.
+	* win/coffbase.txt: Added offsets for snack dlls.
+
+2007-10-11  David Gravereaux <davygrvy@pobox.com>
+
+	* win/makefile.vc:  Fixed my bad spelling mistakes from years back.
+	Dedependency, duh!  Rather funny.
+
+2007-10-11  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclCmdMZ.c:	Correct [string is (wide)integer] failure
+	* tests/string.test:	to report correct failindex values for
+	non-decimal integer strings. [Bug 1805887]
+
+	* compat/strtoll.c (removed):	The routines strtoll() and strtoull()
+	* compat/strtoull.c (removed):	are no longer called by the Tcl source
+	* generic/tcl.h:	code. (Their functionality has been replaced
+	* unix/Makefile.in:	by TclParseNumber().) Remove outdated comments
+	* unix/configure.in:	and mountains of configury autogoo that
+	* unix/tclUnixPort.h:	allegedly support the mythical systems where
+	* win/Makefile.in:	these routines might not have been available.
+	* win/makefile.bc:
+	* win/makefile.vc:
+	* win/tclWinPort.h:
+
+	* unix/configure:	autoconf-2.59
+
+2007-10-11  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclObj.c: remove superfluous #include of tclCompile.h
+
+2007-10-08  George Peter Staplin <georgeps@xmission.com>
+
+	* doc/Hash.3: Correct the valid usage of the flags member for the
+	Tcl_HashKeyType. It should be 0 or more of the flags mentioned.
+
+2007-10-02  Jeff Hobbs	<jeffh@ActiveState.com>
+
+	* generic/tcl.h (Tcl_DecrRefCount): Update change from 2006-05-29 to
+	make macro more warning-robust in unbraced if code.
+
+2007-10-02  Don Porter	<dgp@users.sourceforge.net>
+
+	[core-stabilizer-branch]
+
+	* README:		Bump version number to 8.5.0
+	* generic/tcl.h:
+	* library/init.tcl:
+	* tools/tcl.wse.in:
+	* unix/configure.in:
+	* unix/tcl.spec:
+	* win/configure.in:
+
+	* unix/configure:	autoconf (2.59)
+	* win/configure:
+
+2007-10-02  Andreas Kupries  <andreask@activestate.com>
+
+	* library/tclIndex: Added 'tcl::tm::path' to the tclIndex. This fixes
+	[Bug 1806422] reported by Don Porter.
+
+2007-09-25  Donal K. Fellows  <donal.k.fellows@manchester.ac.uk>
+
+	* generic/tclProc.c (Tcl_DisassembleObjCmd): Define a command,
+	::tcl::unsupported::disassemble, which can disassemble procedures,
+	lambdas and general scripts.
+	* generic/tclCompile.c (TclDisassembleByteCodeObj): Split apart the
+	code to print disassemblies of bytecode so that there is reusable code
+	that spits it out in a Tcl_Obj and then that code is used when doing
+	tracing.
+
+2007-09-20  Don Porter	<dgp@users.sourceforge.net>
+
+	*** 8.5b1 TAGGED FOR RELEASE ***
+
+	* changes: updates for 8.5b1 release.
+
+2007-09-19  Don Porter	<dgp@users.sourceforge.net>
+
+	* README:		Bump version number to 8.5b1
+	* generic/tcl.h:	Merge from core-stabilizer-branch.
+	* library/init.tcl:	Stabilizing toward 8.5b1 release now done on
+	* tools/tcl.wse.in:	the HEAD. core-stabilizer-branch is now
+	* unix/configure.in:	suspended.
+	* unix/tcl.spec:
+	* win/configure.in:
+
+2007-09-19  Pat Thoyts	<patthoyts@users.sourceforge.net>
+
+	* generic/tclStubLib.: Replaced isdigit with internal implementation.
+
+2007-09-18  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclStubLib.c:	Remove C library calls from Tcl_InitStubs() so
+	* win/makefile.vc:	that we don't need the C library linked in to
+	libtclStub.
+
+2007-09-17  Pat Thoyts	<patthoyts@users.sourceforge.net>
+
+	* win/makefile.vc: Add crt flags for tclStubLib now it uses C-library
+			   functions.
+
+2007-09-17  Joe English	 <jenglish@users.sourceforge.net>
+
+	* tcl.m4: use '${CC} -shared' instead of 'ld -Bshareable' to build
+	shared libraries on current NetBSDs. [Bug 1749251]
+	* unix/configure: regenerated (autoconf-2.59).
+
+2007-09-17  Don Porter	<dgp@users.sourceforge.net>
+
+	* unix/Makefile.in:	Update `make dist` so that tclDTrace.d is
+	included in the source code distribution.
+
+	* generic/tcl.h:	Revised Tcl_InitStubs() to restore Tcl 8.4
+	* generic/tclPkg.c:	source compatibility with callers of
+	* generic/tclStubLib.c:	Tcl_InitStubs(interp, TCL_VERSION, 1). [Bug
+	1578344]
+
+2007-09-17  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* generic/tclTrace.c (Tcl_TraceObjCmd, TraceExecutionObjCmd)
+	(TraceCommandObjCmd, TraceVariableObjCmd):   Generate literal values
+	* generic/tclNamesp.c (NamespaceCodeCmd):    more efficiently using
+	* generic/tclFCmd.c (CopyRenameOneFile):     TclNewLiteralStringObj
+	* generic/tclEvent.c (TclSetBgErrorHandler): macro.
+
+2007-09-15  Daniel Steffen  <das@users.sourceforge.net>
+
+	* unix/tcl.m4:	replace all direct references to compiler by ${CC} to
+			enable CC overriding at configure & make time; run
+			check for visibility "hidden" with all compilers;
+			quoting fixes from TEA tcl.m4.
+	(SunOS-5.1x):	replace direct use of '/usr/ccs/bin/ld' in SHLIB_LD by
+			'cc' compiler driver.
+	* unix/configure: autoconf-2.59
+
+2007-09-14  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* generic/tclBasic.c (Tcl_CreateObjCommand): Only invalidate along the
+	namespace path once; that is enough. [Bug 1519940]
+
+2007-09-14  Daniel Steffen  <das@users.sourceforge.net>
+
+	* generic/tclDTrace.d (new file): Add DTrace provider for Tcl; allows
+	* generic/tclCompile.h:		  tracing of proc and command entry &
+	* generic/tclBasic.c:		  return, bytecode execution, object
+	* generic/tclExecute.c:		  allocation and more; with
+	* generic/tclInt.h:		  essentially zero cost when tracing
+	* generic/tclObj.c:		  is inactive; enable with
+	* generic/tclProc.c:		  --enable-dtrace configure arg
+	* unix/Makefile.in:		  (disabled by default, will only
+	* unix/configure.in:		  enable if DTrace is present). [Patch
+	1793984]
+
+	* macosx/GNUmakefile:		  Enable DTrace support.
+	* macosx/Tcl-Common.xcconfig:
+	* macosx/Tcl.xcodeproj/project.pbxproj:
+
+	* generic/tclCmdIL.c:	Factor out core of InfoFrameCmd() into
+				internal TclInfoFrame() for use by DTrace
+				probes.
+
+	* unix/configure: autoconf-2.59
+	* unix/tclConfig.h.in: autoheader-2.59
+
+2007-09-12  Don Porter	<dgp@users.sourceforge.net>
+
+	* unix/Makefile.in:	Perform missing updates of the tcltest Tcl
+	* win/Makefile.in:	Module installed filename that should have
+	been part of the bump to tcltest 2.3b1. Thanks Larry Virden.
+
+2007-09-12  Pat Thoyts	<patthoyts@users.sourceforge.net>
+
+	* win/makefile.vc, win/rules.vc, win/nmakehlp.c: Use nmakehlp to
+	substitute values for tclConfig.sh (helps cross-compiling).
+
+2007-09-11  Don Porter	<dgp@users.sourceforge.net>
+
+	* library/tcltest/tcltest.tcl:	Accept underscores and colons in
+	* library/tcltest/pkgIndex.tcl: constraint names. Properly handle
+	constraint expressions that return non-numeric boolean results like
+	"false". Bump to tcltest 2.3b1. [Bug 1772989; RFE 1071322]
+	* tests/info.test:	Disable fragile tests.
+
+	* doc/package.n:	Restored the functioning of [package require
+	* generic/tclPkg.c:	-exact] to be compatible with Tcl 8.4. [Bug
+	* tests/pkg.test:	1578344]
+
+2007-09-11  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclCompCmds.c (TclCompileDictCmd-update):
+	* generic/tclCompile.c (tclInstructionTable):
+	* generic/tclExecute.c (INST_DICT_UPDATE_END): fix stack management in
+	compiled [dict update]. [Bug 1786481]
+
+	***POTENTIAL INCOMPATIBILITY***
+	Scripts that were precompiled on earlier versions of 8.5 and use [dict
+	update] will crash. Workaround: recompile.
+
+2007-09-11  Kevin B. Kenny  <kennykb@acm.org>
+
+	* generic/tclExecute.c: Corrected an off-by-one error in the setting
+	of MaxBaseWide for certain powers. [Bug 1767293 - problem reported in
+	comments when bug was reopened]
+
+2007-09-10  Jeff Hobbs	<jeffh@ActiveState.com>
+
+	* generic/tclLink.c (Tcl_UpdateLinkedVar): guard against var being
+	unlinked. [Bug 1740631] (maros)
+
+2007-09-10  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclCompile.c: fix tclInstructionTable entry for
+	dictUpdateEnd
+
+	* generic/tclExecute.c: remove unneeded setting of 'cleanup' variable
+	before jumping to checkForCatch.
+
+2007-09-10  Don Porter	<dgp@users.sourceforge.net>
+
+	* doc/package.n:	Restored the document parallel syntax of the
+	* generic/tclPkg.c:	[package present] and [package require]
+	* tests/pkg.test:	commands. [Bug 1723675]
+
+2007-09-09  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclInt.h:	Removed the "nsName" Tcl_ObjType from the
+	* generic/tclNamesp.c:	registered set. Revised the management of the
+	* generic/tclObj.c:	intrep of that Tcl_ObjType. Revised the
+	* tests/obj.test:	TclGetNamespaceFromObj() routine to return
+	TCL_ERROR and write a consistent error message when a namespace is not
+	found. [Bug 1588842. Patch 1686862]
+
+	***POTENTIAL INCOMPATIBILITY***
+	For callers of Tcl_GetObjType() on the name "nsName".
+
+	* generic/tclExecute.c: Update TclGetNamespaceFromObj() callers.
+	* generic/tclProc.c:
+
+	* tests/apply.test:		Updated tests to expect new consistent
+	* tests/namespace-old.test:	error message when a namespace is not
+	* tests/namespace.test:		found.
+	* tests/upvar.test:
+
+	* generic/tclCompCmds.c:	Use the new INST_REVERSE instruction
+	* tests/mathop.test:	to correct the compiled versions of math
+	operator commands. [Bug 1724437]
+
+	* generic/tclCompile.c: New bytecode instruction INST_REVERSE to
+	* generic/tclCompile.h: reverse the order of N items at the top of
+	* generic/tclExecute.c: stack.
+
+	* generic/tclCompCmds.c (TclCompilePowOpCmd):	Make a separate
+	routine to compile ** to account for its different associativity.
+
+2007-09-08  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclVar.c (Tcl_SetVar2, TclPtrSetVar): [Bug 1710710] fixed
+	correctly, reverted fix of 2007-05-01.
+
+2007-09-08  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclDictObj.c (DictUpdateCmd, DictWithCmd): Plug a hole that
+	* generic/tclExecute.c (TEBC,INST_DICT_UPDATE_END): allowed a careful
+	* tests/dict.test (dict-21.16,21.17,22.11): attacker to craft a dict
+	containing a recursive link to itself, violating one of Tcl's
+	fundamental datatype assumptions and causing a stack crash when the
+	dict was converted to a string. [Bug 1786481]
+
+2007-09-07  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclEvent.c ([::tcl::Bgerror]):	Corrections to Tcl's
+	* tests/event.test:	default [interp bgerror] handler so that when
+	it falls back to a hidden [bgerror] in a safe interp, it gets the
+	right error context data. [Bug 1790274]
+
+2007-09-07  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclProc.c (TclInitCompiledLocals): the refCount of resolved
+	variables was being managed without checking if they were Var or
+	VarInHash: itcl [Bug 1790184]
+
+2007-09-06  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclResult.c (Tcl_GetReturnOptions):	Take care that a
+	* tests/init.test:	non-TCL_ERROR code doesn't cause existing
+	-errorinfo, -errorcode, and -errorline entries to be omitted.
+	* generic/tclEvent.c:	With -errorInfo no longer lost, generate more
+	complete ::errorInfo when calling [bgerror] after a non-TCL_ERROR
+	background exception.
+
+2007-09-06  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclInterp.c (Tcl_Init):	Removed constraint on ability
+	to define a custom [tclInit] before calling Tcl_Init(). Until now the
+	custom command had to be a proc. Now it can be any command.
+
+	* generic/tclInt.decls: New internal routine TclBackgroundException()
+	* generic/tclEvent.c:	that for the first time permits non-TCL_ERROR
+	exceptions to trigger [interp bgerror] handling. Closes a gap in TIP
+	221. When falling back to [bgerror] (which is designed only to handle
+	TCL_ERROR), convert exceptions into errors complaining about the
+	exception.
+
+	* generic/tclInterp.c:	Convert Tcl_BackgroundError() callers to call
+	* generic/tclIO.c:	TclBackgroundException().
+	* generic/tclIOCmd.c:
+	* generic/tclTimer.c:
+
+	* generic/tclIntDecls.h:	make genstubs
+	* generic/tclStubInit.c:
+
+2007-09-06  Daniel Steffen  <das@users.sourceforge.net>
+
+	* macosx/Tcl.xcode/project.pbxproj: discontinue unmaintained support
+	* macosx/Tcl.xcode/default.pbxuser: for Xcode 1.5; replace by Xcode2
+	project for use on Tiger (with Tcl.xcodeproj to be used on Leopard).
+
+	* macosx/Tcl.xcodeproj/project.pbxproj: updates for Xcode 2.5 and 3.0.
+	* macosx/Tcl.xcodeproj/default.pbxuser:
+	* macosx/Tcl.xcode/project.pbxproj:
+	* macosx/Tcl.xcode/default.pbxuser:
+	* macosx/Tcl-Common.xcconfig:
+
+	* macosx/README: document project changes.
+
+2007-09-05  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclBasic.c:	Removed support for the unmaintained
+	* generic/tclExecute.c: -DTCL_GENERIC_ONLY configuration. [Bug
+	* unix/Makefile.in:	1264623]
+
+2007-09-04  Don Porter	<dgp@users.sourceforge.net>
+
+	* unix/Makefile.in:	It's unreliable to count on the release
+	manager to remember to `make genstubs` before `make dist`. Let the
+	Makefile remember the dependency for us.
+
+	* unix/Makefile.in:	Corrections to `make dist` dependencies to be
+	sure that macosx/configure gets generated whenever it does not exist.
+
+2007-09-03  Kevin B, Kenny  <kennykb@acm.org>
+
+	* library/tzdata/Africa/Cairo:
+	* library/tzdata/America/Grand_Turk:
+	* library/tzdata/America/Port-au-Prince:
+	* library/tzdata/America/Indiana/Petersburg:
+	* library/tzdata/America/Indiana/Tell_City:
+	* library/tzdata/America/Indiana/Vincennes:
+	* library/tzdata/Antarctica/McMurdo:
+	* library/tzdata/Australia/Adelaide:
+	* library/tzdata/Australia/Broken_Hill:
+	* library/tzdata/Australia/Currie:
+	* library/tzdata/Australia/Hobart:
+	* library/tzdata/Australia/Lord_Howe:
+	* library/tzdata/Australia/Melbourne:
+	* library/tzdata/Australia/Sydney:
+	* library/tzdata/Pacific/Auckland:
+	* library/tzdata/Pacific/Chatham: Olson's tzdata2007g.
+
+	* generic/tclListObj.c (TclLindexFlat):
+	* tests/lindex.test (lindex-17.[01]):	Added code to detect the error
+	when a script does [lindex {} end foo]; an overaggressive optimisation
+	caused this call to return an empty object rather than an error.
+
+2007-09-03  Daniel Steffen  <das@users.sourceforge.net>
+
+	* generic/tclObj.c (TclInitObjSubsystem): restore registration of the
+	"wideInt" Tcl_ObjType for compatibility with 8.4 extensions that
+	access the tclWideIntType Tcl_ObjType; add setFromAnyProc for
+	tclWideIntType.
+
+2007-09-02  Donal K. Fellows  <dkf@users.sf.net>
+
+	* doc/lsearch.n: Added note that order of results with the -all option
+	is that of the input list. It always was, but this makes it crystal.
+
+2007-08-30  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclCompile.c: Added fflush() calls following all callers of
+	* generic/tclExecute.c: TclPrintByteCodeObj() so that tcl_traceCompile
+	output is less likely to get mangled when writes to stdout interleave
+	with other code.
+
+2007-08-28  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclCompExpr.c:	Use a table lookup in ParseLexeme() to
+	determine lexemes with single-byte representations.
+
+	* generic/tclBasic.c:	Used unions to better clarify overloading of
+	* generic/tclCompExpr.c:	the fields of the OpCmdInfo and
+	* generic/tclCompile.h:		TclOpCmdClientData structs.
+
+2007-08-27  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclCompExpr.c:	Call TclCompileSyntaxError() when
+	expression syntax errors are found when compiling expressions. With
+	this in place, convert TclCompileExpr to return void, since there's no
+	longer any need to report TCL_ERROR.
+	* generic/tclCompile.c: Update callers.
+	* generic/tclExecute.c:
+
+	* generic/tclCompCmds.c:	New routine TclCompileSyntaxError()
+	* generic/tclCompile.h: to directly compile bytecodes that report a
+	* generic/tclCompile.c: syntax error, rather than (ab)use a call to
+	TclCompileReturnCmd. Also, undo the most recent commit that papered
+	over some issues with that (ab)use. New routine produces a new opcode
+	INST_SYNTAX, which is a minor variation of INST_RETURN_IMM. Also a bit
+	of constification.
+
+	* generic/tclCompile.c: Move the deallocation of local LiteralTable
+	* generic/tclCompExpr.c:	entries into TclFreeCompileEnv().
+	* generic/tclExecute.c: Update callers.
+
+	* generic/tclCompExpr.c:	Force numeric and boolean literals in
+	expressions to register with their intreps intact, even if that means
+	overwriting existing intreps in already registered literals.
+
+2007-08-25  Kevin B. Kenny  <kennykb@acm.org>
+
+	* generic/tclExecute.c (TclExecuteByteCode): Added code to handle
+	* tests/expr.test (expr-23.48-53)	     integer exponentiation
+	that results in 32- and 64-bit integer results, avoiding calls to wide
+	integer exponentiation routines in this common case. [Bug 1767293]
+
+	* library/clock.tcl (ParseClockScanFormat): Modified code to allow
+	* tests/clock.test (clock-60.*):	    case-insensitive matching
+	of time zone and month names. [Bug 1781282]
+
+2007-08-24  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclCompExpr.c:	Register literals found in expressions
+	* tests/compExpr.test:	to restore literal sharing. Preserve numeric
+	intreps when literals are created for the first time. Correct memleak
+	in ExecConstantExprTree() and add test for the leak.
+
+2007-08-24  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclCompile.c: replaced copy loop that tripped some compilers
+	with memmove. [Bug 1780870]
+
+2007-08-23  Don Porter	<dgp@users.sourceforge.net>
+
+	* library/init.tcl ([auto_load_index]): Delete stray "]" that created
+	an expr syntax error (masked by a [catch]).
+
+	* generic/tclCompCmds.c (TclCompileReturnCmd):	Added crash protection
+	to handle callers other than TclCompileScript() failing to meet the
+	initialization assumptions of the TIP 280 code in CompileWord().
+
+	* generic/tclCompExpr.c:	Suppress the attempt to convert to
+	numeric when pre-compiling a constant expresion indicates an error.
+
+2007-08-22  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclExecute.c (TEBC): disable the new shortcut to frequent
+	INSTs for debug builds. REVERTED (collision with alternative fix)
+
+2007-08-21  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclMain.c:	Corrected the logic of dropping the last
+	* tests/main.test:	newline from an interactively typed command.
+	[Bug 1775878]
+
+2007-08-21  Pat Thoyts	<patthoyts@users.sourceforge.net>
+
+	* tests/thread.test: thread-4.4: clear ::errorInfo in the thread as a
+	message is left here from init.tcl on windows due to no tcl_pkgPath.
+
+2007-08-20  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclExecute.c (INST_SUB): fix usage of the new macro for
+	overflow detection in sums, adapt to subtraction. Lengthy comment
+	added.
+
+2007-08-19  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclExecute.c (Overflowing, TclIncrObj, TclExecuteByteCode):
+	Encapsulate Miguel's last change in a more mnemonic macro.
+
+2007-08-19  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclExecute.c: changed the check for overflow in sums,
+	reducing objsize, number of branches and cache misses (according to
+	cachegrind). Non-overflow for s=a+b:
+	previous
+	  ((a >= 0 || b >= 0 || s < 0) && (s >= 0 || b < 0 || a < 0))
+	now
+	  (((a^s) >= 0) || ((a^b) < 0))
+	This expresses: "a and s have the same sign or else a and b have
+	different sign".
+
+2007-08-19  Donal K. Fellows  <dkf@users.sf.net>
+
+	* doc/interp.n (RESOURCE LIMITS): Added text to better explain why
+	time limits are described using absolute times. [Bug 1752148]
+
+2007-08-16  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclVar.c: improved localVarNameType caching to leverage
+	the new availability of Tcl_Obj in variable names, avoiding string
+	comparisons to verify that the cached value is usable.
+
+	* generic/tclExecute.c: check the two most frequent instructions
+	before the switch. Reduces both runtime and obj size a tiny bit.
+
+2007-08-16  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclCompExpr.c:	Added a "constant" field to the OpNode
+	struct (again "free" due to alignment requirements) to mark those
+	subexpressions that are completely known at compile time. Enhanced
+	CompileExprTree() and its callers to precompute these constant
+	subexpressions at compile time. This resolves the issue raised in [Bug
+	1564517].
+
+2007-08-15  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* generic/tclIOUtil.c (TclGetOpenModeEx): Only set the O_APPEND flag
+	* tests/ioUtil.test (ioUtil-4.1):	  on a channel for the 'a'
+	mode and not for 'a+'. [Bug 1773127]
+
+2007-08-14  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclExecute.c (INST_INVOKE*): peephole opt, do not get the
+	interp's result if it will be pushed/popped.
+
+2007-08-14  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclBasic.c:	Use fully qualified variable names for
+	* tests/thread.test:	::errorInfo and ::errorCode so that string
+	* tests/trace.test:	reported to variable traces are fully
+	qualified in agreement with Tcl 8.4 operations.
+
+2007-08-14  Daniel Steffen  <das@users.sourceforge.net>
+
+	* unix/tclLoadDyld.c: use dlfcn API on Mac OS X 10.4 and later; fix
+	issues with loading from memory on intel and 64bit; add debug messages
+
+	* tests/load.test: add test load-10.1 for loading from vfs.
+
+	* unix/dltest/pkga.c:		whitespace & comment cleanup, remove
+	* unix/dltest/pkgb.c:		unused pkgf.c.
+	* unix/dltest/pkgc.c:
+	* unix/dltest/pkge.c:
+	* unix/dltest/pkgf.c (removed):
+	* unix/dltest/pkgua.c:
+	* macosx/Tcl.xcodeproj/project.pbxproj:
+
+2007-08-13  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclExecute.c: Provide DECACHE/CACHE protection to the
+	* tests/trace.test:	Tcl_LogCommandInfo() call. [Bug 1773040]
+
+2007-08-12  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclCmdMZ.c (Tcl_SplitObjCmd): use TclNewStringObj macro
+	instead of calling the function.
+
+	* generic/tcl_Obj.c (TclAllocateFreeObjects): remove unneeded memset
+	to 0 of all allocated objects.
+
+2007-08-10  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclInt.h: remove redundant ops in TclNewStringObj macro.
+
+2007-08-10  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclInt.h: fix the TclSetVarNamespaceVar macro, was causing a
+	leak.
+
+2007-08-10  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclCompExpr.c:	Revise CompileExprTree() to use the
+	OpNode mark field scheme of tree traversal. This eliminates the need
+	to use magic values in the left and right fields for that purpose.
+	Also stop abusing the left field within ParseExpr() to store the
+	number of arguments in a parsed function call. CompileExprTree() now
+	determines that for itself at compile time. Then reorder code to
+	eliminate duplication.
+
+2007-08-09  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclProc.c (TclCreateProc): better comments on the required
+	varflag values when loading precompiled procs.
+
+	* generic/tclExecute.c (INST_STORE_ARRAY):
+	* tests/trace.test (trace-2.6): whole array write traces on compiled
+	local variables were not firing. [Bug 1770591]
+
+2007-08-08  Jeff Hobbs	<jeffh@ActiveState.com>
+
+	* generic/tclProc.c (InitLocalCache): reference firstLocalPtr via
+	procPtr. codePtr->procPtr == NULL exposed by tbcload.
+
+2007-08-08  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclExecute.c: Corrected failure to compile/link in the
+	-DNO_WIDE_TYPE configuration.
+
+	* generic/tclExecute.c: Corrected improper use of bignum arguments to
+	* tests/expr.test:	*SHIFT operations. [Bug 1770224]
+
+2007-08-07  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclInt.h: remove comments refering to VAR_SCALAR, as that
+	flag bit does not exist any longer.
+	* generic/tclProc.c (InitCompiledLocals): removed optimisation for
+	non-resolved case, as the function is never called in that case.
+	Renamed the function to InitResolvedLocals to calrify the point.
+
+	* generic/tclInt.decls:	  Exporting via stubs to help xotcl adapt to
+	* generic/tclInt.h:	  VarReform.
+	* generic/tclIntDecls.h:
+	* generic/tclStubInit.c:
+
+2007-08-07  Daniel Steffen  <das@users.sourceforge.net>
+
+	* generic/tclEnv.c:	improve environ handling on Mac OS X (adapted
+	* unix/tclUnixPort.h:	from Apple changes in Darwin tcl-64).
+
+	* unix/Makefile.in:	add support for compile flags specific to
+				object files linked directly into executables.
+
+	* unix/configure.in (Darwin): only use -seg1addr flag when prebinding;
+	use -mdynamic-no-pic flag for object files linked directly into exes;
+	support overriding TCL_PACKAGE_PATH/TCL_MODULE_PATH in environment.
+
+	* unix/configure: autoconf-2.59
+
+2007-08-06  Don Porter	<dgp@users.sourceforge.net>
+
+	* tests/parseExpr.test: Update source file name of expr parser code.
+
+	* generic/tclCompExpr.c:	Added a "mark" field to the OpNode
+	struct, which is used to guide tree traversal. This field costs
+	nothing since alignement requirements used the memory already.
+	Rewrote ConvertTreeToTokens() to use the new field, which permitted
+	consolidation of utility routines CopyTokens() and
+	GenerateTokensForLiteral().
+
+2007-08-06  Kevin B. Kenny  <kennykb@users.sf.net>
+
+	* generic/tclGetDate.y: Added a cast to the definition of YYFREE to
+				silence compiler warnings.
+	* generic/tclDate.c:	Regenerated
+	* win/tclWinTest.c:	Added a cast to GetSecurityDescriptorDacl call
+				to silence compiler warnings.
+
+2007-08-04  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclInt.decls:	  Exporting via stubs to help itcl adapt to
+	* generic/tclInt.h:	  VarReform. Added localCache initialization
+	* generic/tclIntDecls.h:  to TclInitCompiledLocals (which only exists
+	* generic/tclProc.c:	  for itcl).
+	* generic/tclStubInit.c:
+	* generic/tclVar.c:
+
+2007-08-01  Donal K. Fellows  <donal.k.fellows@manchester.ac.uk>
+
+	* library/word.tcl: Rewrote for greater efficiency. [Bug 1764318]
+
+2007-08-01  Pat Thoyts	<patthoyts@users.sourceforge.net>
+
+	* generic/tclInt.h:	Added a TclOffset macro ala Tk_Offset to
+	* generic/tclVar.c:	abstract out 'offsetof' which may not be
+	* generic/tclExceute.c: defined (eg: msvc6).
+
+2007-08-01  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclVar.c (TclCleanupVar): fix [Bug 1765225], thx Larry
+	Virden.
+
+2007-07-31  Miguel Sofer  <msofer@users.sf.net>
+
+	* doc/Hash.3:
+	* generic/tclHash.c:
+	* generic/tclObj.c:
+	* generic/tclThreadStorage.c: (changes part of the patch below)
+	Stop Tcl_CreateHashVar from resetting hPtr->clientData to NULL after
+	calling the allocEntryProc for a custom table.
+
+	* generic/tcl.h:
+	* generic/tclBasic.c:
+	* generic/tclCmdIL.c:
+	* generic/tclCompCmds.c:
+	* generic/tclCompile.c:
+	* generic/tclCompile.h:
+	* generic/tclExecute.c:
+	* generic/tclHash.c:
+	* generic/tclInt.decls:
+	* generic/tclInt.h:
+	* generic/tclIntDecls.h:
+	* generic/tclLiteral.c:
+	* generic/tclNamesp.c:
+	* generic/tclObj.c:
+	* generic/tclProc.c:
+	* generic/tclThreadStorage.c:
+	* generic/tclTrace.c:
+	* generic/tclVar.c: VarReform [Patch 1750051]
+
+	*** POTENTIAL INCOMPATIBILITY *** (tclInt.h and tclCompile.h)
+	Extensions that access internals defined in tclInt.h and/or
+	tclCompile.h may lose both binary and source compatibility. The
+	relevant changes are:
+	1. 'struct Var' is completely changed, all acceses to its internals
+	   (either direct or via the TclSetVar* and TclIsVar* macros) will
+	   malfunction. Var flag values and semantics changed too.
+	2. 'struct Bytecode' has an additional field that has to be
+	   initialised to NULL
+	3. 'struct Namespace' is larger, as the varTable is now one pointer
+	   larger than a Tcl_HashTable. Direct access to its fields will
+	   malfunction.
+	4. 'struct CallFrame' grew one more field (the second such growth with
+	   respect to Tcl8.4).
+	5. API change for the functions TclFindCompiledLocal, TclDeleteVars
+	   and many internal functions in tclVar.c
+
+	Additionally, direct access to variable hash tables via the standard
+	Tcl_Hash* interface is to be considered as deprecated. It still works
+	in the present version, but will be broken by further specialisation
+	of these hash tables. This concerns especially the table of array
+	elements in an array, as well as the varTable field in the Namespace
+	struct.
+
+2007-07-31  Miguel Sofer  <msofer@users.sf.net>
+
+	* unix/configure.in: allow use of 'inline' in Tcl sources. [Patch
+	* win/configure.in:  1754128]
+	* win/makefile.vc:   Regen with autoconf 2.61
+
+2007-07-31  Donal K. Fellows  <donal.k.fellows@manchester.ac.uk>
+
+	* unix/tclUnixInit.c (TclpSetVariables): Use the thread-safe getpwuid
+	replacement to fill the tcl_platform(user) field as it is not subject
+	to spoofing. [Bug 681877]
+
+	* unix/tclUnixCompat.c: Simplify the #ifdef logic.
+
+	* unix/tclUnixChan.c (FileWatchProc): Fix test failures.
+
+2007-07-30  Donal K. Fellows  <donal.k.fellows@manchester.ac.uk>
+
+	* unix/tclUnixChan.c (SET_BITS, CLEAR_BITS): Added macros to make this
+	file clearer.
+
+2007-07-24  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclBasic.c (TEOvI, GetCommandSource):
+	* generic/tclExecute.c (TEBC, TclGetSrcInfoForCmd):
+	* generic/tclInt.h:
+	* generic/tclTrace.c (TclCheck(Interp|Execution)Traces):
+	Removed the need for TEBC to inspect the command before calling TEOvI,
+	leveraging the TIP 280 infrastructure. Moved the generation of a
+	correct nul-terminated command string away from the trace code, back
+	into TEOvI/GetCommandSource.
+
+2007-07-20  Andreas Kupries  <andreask@activestate.com>
+
+	* library/platform/platform.tcl: Fixed bug in 'platform::patterns'
+	* library/platform/pkgIndex.tcl: where identifiers not matching
+	* unix/Makefile.in: the special linux and solaris forms would not
+	* win/Makefile.in: get 'tcl' as an acceptable platform added to
+	* doc/platform.n: the result. Bumped package to version 1.0.3 and
+	* doc/platform_shell.n: updated documentation and Makefiles. Also
+	fixed bad version info in the documentation of platform::shell.
+
+2007-07-19  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclParse.c:	In contexts where interp and parsePtr->interp
+	might be different, be sure to use the latter for error reporting.
+	Also pulled the interp argument back out of ParseTokens() since we
+	already had a parsePtr->interp to work with.
+
+2007-07-18  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclCompExpr.c:	Removed unused arguments and variables
+
+2007-07-17  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclCompExpr.c (ParseExpr):	While adding comments to
+	explain the operations of ParseExpr(), made significant revisions to
+	the code so it would be easier to explain, and in the process made the
+	code simpler and clearer as well.
+
+2007-07-15  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclCompExpr.c:	More commentary.
+	* tests/parseExpr.test:		Several tests of syntax error messages
+	to check that when expression substrings are truncated they leave
+	visible the context relevant to the reported error.
+
+2007-07-12  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclCompExpr.c:	Factored out, corrected, and commented
+	common code for reporting syntax errors in LEAF elements.
+
+2007-07-11  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclCompCmds.c (TclCompileWhileCmd):
+	* generic/tclCompile.c (TclCompileScript):
+	Corrected faulty avoidance of INST_START_CMD when the first opcode in
+	a script is within a loop (as produced by 'while 1'), so that the
+	corresponding command is properly counted. [Bug 1752146]
+
+2007-07-11  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclCompExpr.c:	Added a "parseOnly" flag argument to
+	ParseExpr() to indicate whether the caller is Tcl_ParseExpr(), with an
+	end goal of filling a Tcl_Parse with Tcl_Tokens representing the
+	parsed expression, or TclCompileExpr() with the goal of compiling and
+	executing the expression. In the latter case, more aggressive
+	conversion of QUOTED and BRACED lexeme to literals is done. In the
+	former case, all such conversion is avoided, since Tcl_Token
+	production would revert it anyway. This enables simplifications to the
+	GenerateTokensForLiteral() routine as well.
+
+2007-07-10  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclCompExpr.c:	Added a field for operator precedence
+	to be stored directly in the parse tree. There's no memory cost to
+	this addition, since that memory would have been lost to alignment
+	issues anyway. Also, converted precedence definitions and lookup
+	tables to use symbolic constants instead of raw number for improved
+	readability, and continued extending/improving/correcting comments.
+	Removed some unused counter variables. Renamed some variables for
+	clarity and replaced some cryptic logic with more readable macros.
+
+2007-07-09  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclCompExpr.c:	Revision so that the END lexeme never
+	gets inserted into the parse tree. Later tree traversal never reaches
+	it since its location in the tree is not variable. Starting and
+	stopping with the START lexeme (node 0) is sufficient. Also finished
+	lexeme code commentary.
+
+	* generic/tclCompExpr.c:	Added missing creation and return of
+	the Tcl_Parse fields that indicate error conditions. [Bug 1749987]
+
+2007-07-05  Don Porter	<dgp@users.sourceforge.net>
+
+	* library/init.tcl (unknown):	Corrected inconsistent error message
+	in interactive [unknown] when empty command is invoked. [Bug 1743676]
+
+2007-07-05  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclNamesp.c (SetNsNameFromAny):
+	* generic/tclObj.c (SetCmdNameFromAny): Avoid unnecessary
+	ckfree/ckalloc when the old structs can be reused.
+
+2007-07-04  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclNamesp.c: Fix case where a FQ cmd or ns was being cached
+	* generic/tclObj.c:    in a different interp, tkcon. [Bug 1747512]
+
+2007-07-03  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclCompExpr.c:	Revised #define values so that there
+	is now more expansion room to define more BINARY operators.
+
+2007-07-02  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclHash.c (CompareStringKeys): Always use the strcmp()
+	version; the operation is functionally equivalent, the speed is
+	identical (up to measurement limitations), and yet the code is
+	simpler. [FRQ 951168]
+
+2007-07-02  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tcl.h:	Removed TCL_PRESERVE_BINARY_COMPATIBILITY and
+	* generic/tclHash.c:	any code enabled when it is set to 0. We will
+	* generic/tclStubInit.c:	always want to preserve binary compat
+	of the structs that appear in the interface through the 8.* series of
+	releases, so it's pointless to drag around this never-enabled
+	alternative.
+
+	* generic/tclIO.c:	Removed dead code.
+	* unix/tclUnixChan.c:
+
+	* generic/tclCompExpr.c:	Removed dead code, old implementations
+	* generic/tclEvent.c:	of expr parsing and compiling, including the
+	* generic/tclInt.h:	routine TclFinalizeCompilation().
+
+2007-06-30  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclCmdIL.c (Tcl_LsortObjCmd): Plug a memory leak caused by a
+	missing Tcl_DecrRefCount on an error path. [Bug 1717186]
+
+2007-06-30  Zoran Vasiljevic <vasiljevic@users.sourceforge.net>
+
+	* generic/tclThread.c: Prevent RemeberSyncObj() from growing the sync
+	object lists by reusing already free'd slots, if possible. See
+	discussion on Bug 1726873 for more information.
+
+2007-06-29  Donal K. Fellows  <dkf@users.sf.net>
+
+	* doc/DictObj.3 (Tcl_DictObjDone): Improved documentation of this
+	function to make it clearer how to use it. [Bug 1710795]
+
+2007-06-29  Daniel Steffen  <das@users.sourceforge.net>
+
+	* generic/tclAlloc.c:		on Darwin, ensure memory allocated by
+	* generic/tclThreadAlloc.c:	the custom TclpAlloc()s is aligned to
+	16 byte boundaries (as is the case with the Darwin system malloc).
+
+	* generic/tclGetDate.y: use ckalloc/ckfree instead of malloc/free.
+	* generic/tclDate.c:	bison 1.875e
+
+	* generic/tclBasic.c (TclEvalEx): fix warnings.
+
+	* macosx/Tcl.xcodeproj/project.pbxproj: better support for renamed tcl
+	* macosx/Tcl.xcodeproj/default.pbxuser: source dir; add 10.5 SDK build
+	* macosx/Tcl-Common.xcconfig:		config; remove tclMathOp.c.
+
+	* macosx/README: document Tcl.xcodeproj changes.
+
+2007-06-28  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclBasic.c:		Removed dead code, including the
+	* generic/tclExecute.c:		entire file tclMathOp.c.
+	* generic/tclInt.h:
+	* generic/tclMathOp.c (removed):
+	* generic/tclTestObj.c:
+	* win/tclWinFile.c:
+
+	* unix/Makefile.in:	Updated to reflect deletion of tclMathOp.c.
+	* win/Makefile.in:
+	* win/makefile.bc:
+	* win/makefile.vc:
+
+2007-06-28  Pat Thoyts	<patthoyts@users.sourceforge.net>
+
+	* generic/tclBasic.c:	  Silence constness warnings for TclStackFree
+	* generic/tclCompCmds.c:  when building with msvc.
+	* generic/tclFCmd.c:
+	* generic/tclIOCmd.c:
+	* generic/tclTrace.c:
+
+2007-06-28  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclVar.c (UnsetVarStruct): fix possible segfault.
+
+2007-06-27  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclTrace.c:	Corrected broken trace reversal logic in
+	* generic/tclTest.c:	TclCheckInterpTraces that led to infinite loop
+	* tests/trace.test:	when multiple Tcl_CreateTrace traces were set
+	and one of them did not fire due to level restrictions. [Bug 1743931]
+
+2007-06-26  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclBasic.c (TclEvalEx):	Moved some arrays from the C
+	stack to the Tcl stack.
+
+2007-06-26  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclVar.c (UnsetVarStruct): more streamlining.
+
+2007-06-25  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclExecute.c: Safety checks to avoid crashes in the
+	TclStack* routines when called with an incompletely initialized
+	interp. [Bug 1743302]
+
+2007-06-25  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclVar.c (UnsetVarStruct): fixing incomplete change, more
+	streamlining.
+
+2007-06-24  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclVar.c (TclDeleteCompiledLocalVars): removed inlining that
+	ended up not really optimising (limited benchmarks). Now calling
+	UnsetVarStruct (streamlined old code is #ifdef'ed out, in case better
+	benchmarks do show a difference).
+
+	* generic/tclVar.c (UnsetVarStruct): fixed a leak introduced in last
+	commit.
+
+2007-06-23  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclVar.c (UnsetVarStruct, TclDeleteVars): made the logic
+	slightly clearer, eliminated some duplicated code.
+
+	*** POTENTIAL INCOMPATIBILITY *** (tclInt.h and Var struct users)
+	The core never builds VAR_LINK variable to have traces. Such a
+	"monster", should one exist, will now have its unset traces called
+	*before* it is unlinked.
+
+2007-06-23  Daniel Steffen  <das@users.sourceforge.net>
+
+	* macosx/tclMacOSXNotify.c (AtForkChild): don't call CoreFoundation
+	APIs after fork() on systems where that would lead to an abort().
+
+2007-06-22  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclExecute.c: Revised TclStackRealloc() signature to better
+	* generic/tclInt.h:	parallel (and fall back on) Tcl_Realloc.
+
+	* generic/tclNamesp.c (TclResetShadowesCmdRefs):	Replaced
+	ckrealloc based allocations with TclStackRealloc allocations.
+
+	* generic/tclCmdIL.c:	More conversions to use TclStackAlloc.
+	* generic/tclScan.c:
+
+2007-06-21  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclBasic.c:	 Move most instances of the Tcl_Parse struct
+	* generic/tclCompExpr.c: off the C stack and onto the Tcl stack. This
+	* generic/tclCompile.c:	 is a rather large struct (> 3kB).
+	* generic/tclParse.c:
+
+2007-06-21  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclBasic.c (TEOvI):		Made sure that leave traces
+	* generic/tclExecute.c (INST_INVOKE):	that were created during
+	* tests/trace.test (trace-36.2):	execution of an originally
+	untraced command do not fire [Bug 1740962], partial fix.
+
+2007-06-21  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* generic/tcl.h, generic/tclCompile.h, generic/tclCompile.c: Remove
+	references in comments to obsolete {expand} notation. [Bug 1740859]
+
+2007-06-20  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclVar.c: streamline namespace vars deletion: only compute
+	the variable's full name if the variable is traced.
+
+2007-06-20  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclInt.decls: Revised the interfaces of the routines
+	* generic/tclExecute.c: TclStackAlloc and TclStackFree to make them
+	easier for callers to use (or more precisely, harder to misuse).
+	TclStackFree now takes a (void *) argument which is the pointer
+	intended to be freed. TclStackFree will panic if that's not actually
+	the memory the call will free. TSA/TSF also now tolerate receiving
+	(interp == NULL), in which case they simply fall back to be calls to
+	Tcl_Alloc/Tcl_Free.
+
+	* generic/tclIntDecls.h:	make genstubs
+
+	* generic/tclBasic.c:	Updated callers
+	* generic/tclCmdAH.c:
+	* generic/tclCmdIL.c:
+	* generic/tclCompCmds.c:
+	* generic/tclCompExpr.c:
+	* generic/tclCompile.c:
+	* generic/tclFCmd.c:
+	* generic/tclFileName.c:
+	* generic/tclIOCmd.c:
+	* generic/tclIndexObj.c:
+	* generic/tclInterp.c:
+	* generic/tclNamesp.c:
+	* generic/tclProc.c:
+	* generic/tclTrace.c:
+	* unix/tclUnixPipe.c:
+
+2007-06-20  Jeff Hobbs	<jeffh@ActiveState.com>
+
+	* tools/tcltk-man2html.tcl: revamp of html doc output to use CSS,
+	standardized headers, subheaders, dictionary sorting of names.
+
+2007-06-18  Jeff Hobbs	<jeffh@ActiveState.com>
+
+	* tools/tcltk-man2html.tcl: clean up copyright merging and output.
+	clean up coding constructs.
+
+2007-06-18  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclCmdIL.c (InfoFrameCmd):
+	* generic/tclCmdMZ.c (Tcl_SwitchObjCmd):
+	* generic/tclCompile.c (TclInitCompileEnv):
+	* generic/tclProc.c (Tcl_ProcObjCmd, SetLambdaFromAny): Moved the
+	CmdFrame off the C stack and onto the Tcl stack.
+
+	* generic/tclExecute.c (TEBC):	Moved the CmdFrame off the C stack and
+	onto the Tcl stack, between the catch and the execution stacks
+
+2007-06-18  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclBasic.c (TclEvalEx,TclEvalObjEx):	Moved the CmdFrame off
+	the C stack and onto the Tcl stack.
+
+2007-06-17  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclProc.c (TclObjInterpProcCore): Minor fixes to make
+	* generic/tclExecute.c (TclExecuteByteCode): compilation debugging
+	builds work again. [Bug 1738542]
+
+2007-06-16  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclProc.c (TclObjInterpProcCore): Use switch instead of a
+	chain of if's for a modest performance gain and a little more clarity.
+
+2007-06-15  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclCompCmds.c:  Simplified [variable] compiler and executor.
+	* generic/tclExecute.c:	  Missed updates to "there is always a valid
+	frame".
+
+	* generic/tclCompile.c: reverted TclEvalObjvInternal and INST_INVOKE
+	* generic/tclExecute.c: to essentially what they were previous to the
+	* generic/tclBasic.c:	commit of 2007-04-03 [Patch 1693802] and the
+	subsequent optimisations, as they break the new trace tests described
+	below.
+
+	* generic/trace.test: added tests 36 to 38 for dynamic trace creation
+	and addition. These tests expose a change in dynamics due to a recent
+	round of optimisations. The "correct" behaviour is not described in
+	docs nor TIP 62.
+
+2007-06-14  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclInt.decls:	  Modif to the internals of TclObjInterpProc
+	* generic/tclInt.h:	  to reduce stack consumption and improve task
+	* generic/tclIntDecls.h:  separation. Changes the interface of
+	* generic/tclProc.c:	  TclObjInterpProcCore (patching TclOO
+	simultaneously).
+
+	* generic/tclProc.c (TclObjInterpProcCore): simplified obj management
+	in wrongNumArgs calls.
+
+2007-06-14  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclCompile.c: SetByteCodeFromAny() can no longer return any
+	* generic/tclExecute.c: code other than TCL_OK, so remove code that
+	* generic/tclProc.c:	formerly handled exceptional codes.
+
+2007-06-13  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclExecute.c (TclCompEvalObj): missed update to "there is
+	always a valid frame".
+
+	* generic/tclProc.c (TclObjInterpProcCore): call TEBC directly instead
+	of going through TclCompEvalObj - no need to check the compilation's
+	freshness, this has already been done. This improves speed and should
+	also provide some relief to [Bug 1066755].
+
+2007-06-12  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* generic/tclBasic.c (Tcl_CreateInterp): Turn the [info] command into
+	* generic/tclCmdIL.c (TclInitInfoCmd):	 an ensemble, making it easier
+	for third-party code to plug into.
+
+	* generic/tclIndexObj.c (Tcl_WrongNumArgs):
+	* generic/tclNamesp.c, generic/tclInt.h (tclEnsembleCmdType): Make
+	Tcl_WrongNumArgs do replacement correctly with ensembles and other
+	sorts of complex replacement strategies.
+
+2007-06-11  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclExecute.c:	 comments added to explain iPtr->numLevels
+	management.
+
+	* generic/tclNamesp.c:	 tweaks to Tcl_GetCommandFromObj and
+	* generic/tclObj.c:	 TclGetNamespaceFromObj; modified the usage of
+	structs ResolvedCmdName and ResolvedNsname so that the field refNsPtr
+	is NULL for fully qualified names.
+
+2007-06-10  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclBasic.c:	 Further TEOvI split, creating a new
+	* generic/tclCompile.h:	 TclEvalObjvKnownCommand() function to handle
+	* generic/tclExecute.c:	 commands that are already known and are not
+	traced. INST_INVOKE now calls into this function instead of inlining
+	parts of TEOvI. Same perf, better isolation.
+
+	***POTENTIAL INCOMPAT*** There is a subtle issue with the timing of
+	execution traces that is changed here - first change appeared in my
+	commit of 2007-04-03 [Patch 1693802], which caused some divergence
+	between compiled and non-compiled code.
+	***THIS CHANGE IS UNDER REVIEW***
+
+2007-06-10  Jeff Hobbs	<jeffh@ActiveState.com>
+
+	* README: updated links. [Bug 1715081]
+
+	* generic/tclExecute.c (TclExecuteByteCode): restore support for
+	INST_CALL_BUILTIN_FUNC1 and INST_CALL_FUNC1 bytecodes to support 8.4-
+	precompiled sources (math functions). [Bug 1720895]
+
+2007-06-10  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclInt.h:
+	* generic/tclNamesp.c:
+	* generic/tclObj.c:
+	* generic/tclvar.c: new macros TclGetCurrentNamespace() and
+	TclGetGlobalNamespace(); Tcl_GetCommandFromObj and
+	TclGetNamespaceFromObj rewritten to make the logic clearer; slightly
+	faster too.
+
+2007-06-09  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclExecute.c (INST_INVOKE): isolated two vars to the small
+	block where they are actually used.
+
+	* generic/tclObj.c (Tcl_GetCommandFromObj): rewritten to make the
+	logic clearer; slightly faster too.
+
+	* generic/tclBasic.c:	Split TEOv in two, by separating a processor
+	for non-TCL_OK returns. Also split TEOvI in a full version that
+	handles non-existing and traced commands, and a separate shorter
+	version for the regular case.
+
+	* generic/tclBasic.c:	Moved the generation of command strings for
+	* generic/tclTrace.c:	traces: previously in Tcl_EvalObjv(), now in
+	TclCheck[Interp|Execution]Traces(). Also insured that the strings are
+	properly NUL terminated at the correct length. [Bug 1693986]
+
+	***POTENTIAL INCOMPATIBILITY in internal API***
+	The functions TclCheckInterpTraces() and TclCheckExecutionTraces() (in
+	internal stubs) used to be noops if the command string was NULL, this
+	is not true anymore: if the command string is NULL, they generate an
+	appropriate string from (objc,objv) and use it to call the traces. The
+	caller might as well not call them with a NULL string if he was
+	expecting a noop.
+
+	* generic/tclBasic.c:	Extend usage of TclLimitReady() and
+	* generic/tclExecute.c: (new) TclLimitExceeded() macros.
+	* generic/tclInt.h:
+	* generic/tclInterp.c:
+
+	* generic/tclInt.h:	New TclCleanupCommandMacro for core usage.
+	* generic/tclBasic.c:
+	* generic/tclExecute.c:
+	* generic/tclObj.c:
+
+2007-06-09 Daniel Steffen  <das@users.sourceforge.net>
+
+	* macosx/Tcl.xcodeproj/project.pbxproj: add new Tclsh-Info.plist.in.
+
+2007-06-08  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclCmdMZ.c (Tcl_StringObjCmd): Changed [string first] and
+	* doc/string.n: [string last] so that they have clearer descriptions
+	for those people who know the adage about needles and haystacks. This
+	follows suggestions on comp.lang.tcl...
+
+2007-06-06  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclParse.c: fix for uninit read. [Bug 1732414]
+
+2007-06-06  Daniel Steffen  <das@users.sourceforge.net>
+
+	* macosx/Tcl.xcodeproj/project.pbxproj: add settings for Fix&Continue.
+
+	* unix/configure.in (Darwin):		add plist for tclsh; link the
+	* unix/Makefile.in  (Darwin):		Tcl and tclsh plists into
+	* macosx/Tclsh-Info.plist.in (new):	their binaries in all cases.
+	* macosx/Tcl-Common.xcconfig:
+
+	* unix/tcl.m4 (Darwin): fix CF checks in fat 32&64bit builds.
+	* unix/configure: autoconf-2.59
+
+2007-06-05  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclBasic.c:	Added interp flag value ERR_LEGACY_COPY to
+	* generic/tclInt.h:	control the timing with which the global
+	* generic/tclNamesp.c:	variables ::errorCode and ::errorInfo get
+	* generic/tclProc.c:	updated after an error. This keeps more
+	* generic/tclResult.c:	precise compatibility with Tcl 8.4.
+	* tests/result.test (result-6.2):	[Bug 1649062]
+
+2007-06-05  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclInt.h:
+	* generic/tclExecute.c: Tcl-stack reform, [Patch 1701202]
+
+2007-06-03  Daniel Steffen  <das@users.sourceforge.net>
+
+	* unix/Makefile.in: add datarootdir to silence autoconf-2.6x warning.
+
+2007-05-30  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclBasic.c:	Removed code that dealt with
+	* generic/tclCompile.c: TCL_TOKEN_EXPAND_WORD tokens representing
+	* generic/tclCompile.h: expanded literal words. These sections were
+	mostly in place to enable [info frame] to discover line information in
+	expanded literals. Since the parser now generates a token for each
+	post-expansion word referring to the right location in the original
+	script string, [info frame] gets all the data it needs.
+
+	* generic/tclInt.h:	Revised the parser so that it never produces
+	* generic/tclParse.c:	TCL_TOKEN_EXPAND_WORD tokens when parsing an
+	* tests/parse.test:	expanded literal word; that is, something like
+	{*}{x y z}. Instead, generate the series of TCL_TOKEN_SIMPLE_WORD
+	tokens to represent the words that expansion of the literal string
+	produces. [RFE 1725186]
+
+2007-05-29  Jeff Hobbs	<jeffh@ActiveState.com>
+
+	* unix/tclUnixThrd.c (Tcl_JoinThread): fix for 64-bit handling of
+	pthread_join exit return code storage. [Bug 1712723]
+
+2007-05-22  Don Porter	<dgp@users.sourceforge.net>
+
+	[core-stabilizer-branch]
+
+	* unix/configure:	autoconf-2.59 (FC6 fork)
+	* win/configure:
+
+	* README:		Bump version number to 8.5b1
+	* generic/tcl.h:
+	* library/init.tcl:
+	* tools/tcl.wse.in:
+	* unix/configure.in:
+	* unix/tcl.spec:
+	* win/configure.in:
+
+2007-05-18  Don Porter	<dgp@users.sourceforge.net>
+
+	* unix/configure:	autoconf-2.59 (FC6 fork)
+	* win/configure:
+
+	* README:		Bump version number to 8.5a7
+	* generic/tcl.h:
+	* library/init.tcl:
+	* tools/tcl.wse.in:
+	* unix/configure.in:
+	* unix/tcl.spec:
+	* win/configure.in:
+
+	* generic/tclParse.c:	Disable and remove the ALLOW_EXPAND sections
+	* tests/info.test:	that continued to support the deprecated
+	* tests/mathop.test:	{expand} syntax. Updated the few remaining
+	users of that syntax in the test suite.
+
+2007-05-17  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclExecute.c (TclLimitReady): Created a macro version of
+	Tcl_LimitReady just for TEBC, to reduce the amount of times that the
+	bytecode engine calls out to external functions on the critical path.
+	* generic/tclInterp.c (Tcl_LimitReady): Added note to remind anyone
+	doing maintenance that there is a macro version to update.
+
+2007-05-17  Daniel Steffen  <das@users.sourceforge.net>
+
+	* generic/tcl.decls: workaround 'make checkstubs' failures from
+	tclStubLib.c MODULE_SCOPE revert. [Bug 1716117]
+
+2007-05-16  Joe English	 <jenglish@users.sourceforge.net>
+
+	* generic/tclStubLib.c:	 Change Tcl_InitStubs(), tclStubsPtr, and the
+	auxilliary stubs table pointers back to public visibility.
+
+	These symbols need to be exported so that stub-enabled extensions may
+	be statically linked into an extended tclsh or Big Wish with a
+	dynamically-linked libtcl. [Bug 1716117]
+
+2007-05-15  Don Porter	<dgp@users.sourceforge.net>
+
+	* win/configure:	autoconf-2.59 (FC6 fork)
+
+	* library/reg/pkgIndex.tcl:	Bump to registry 1.2.1 to account for
+	* win/configure.in:		[Bug 1682211] fix.
+	* win/makefile.bc:
+	* win/tclWinReg.c:
+
+2007-05-11  Pat Thoyts	<patthoyts@users.sourceforge.net>
+
+	* generic/tclInt.h: Removed TclEvalObjEx and TclGetSrcInfoForPc from
+	tclInt.h now they are in the internal stubs table.
+
+2007-05-09  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclInt.h:	TclFinalizeThreadAlloc() is always defined, so
+	make sure it is also always declared (with MODULE_SCOPE).
+
+2007-05-09  Daniel Steffen  <das@users.sourceforge.net>
+
+	* generic/tclInt.h: fix warning when building threaded with -DPURIFY.
+
+	* macosx/Tcl.xcodeproj/project.pbxproj: add 'DebugUnthreaded' &
+	* macosx/Tcl.xcodeproj/default.pbxuser: 'DebugLeaks' configs and env
+	var settings needed to run the 'leaks' tool.
+
+2007-05-07  Don Porter	<dgp@users.sourceforge.net>
+
+	[Tcl Bug 1706140]
+
+	* generic/tclLink.c (LinkTraceProc):	Update Tcl_VarTraceProcs so
+	* generic/tclNamesp.c (Error*Read):	they call Tcl_InterpDeleted()
+	* generic/tclTrace.c (Trace*Proc):	for themselves, and do not
+	* generic/tclUtil.c (TclPrecTraceProc): rely on (frequently buggy)
+	setting of the TCL_INTERP_DESTROYED flag by the trace core.
+
+	* generic/tclVar.c:	Update callers of TclCallVarTraces to not pass
+	in the TCL_INTERP_DESTROYED flag. Also apply filters so that public
+	routines only pass documented flag values down to lower level routines
+
+	* generic/tclTrace.c (TclCallVarTraces):	The setting of the
+	TCL_INTERP_DESTROYED flag is now done entirely within the
+	TclCallVarTraces routine, the only place it can be done right.
+
+2007-05-06  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclInt.h (ExtraFrameInfo): Create a new mechanism for
+	* generic/tclCmdIL.c (InfoFrameCmd): conveying what information needs
+	to be added to the results of [info frame] to replace the hack that
+	was there before.
+	* generic/tclProc.c (Tcl_ApplyObjCmd): Use the new mechanism for the
+	[apply] command, the only part of Tcl itself that needs it (so far).
+
+	* generic/tclInt.decls (TclEvalObjEx, TclGetSrcInfoForPc): Expose
+	these two functions through the internal stubs table, necessary for
+	extensions that need to integrate deeply with TIP#280.
+
+2007-05-05  Donal K. Fellows  <dkf@users.sf.net>
+
+	* win/tclWinFile.c (TclpGetUserHome):	Squelch type-pun warnings in
+	* win/tclWinInit.c (TclpSetVariables):	Win-specific code not found
+	* win/tclWinReg.c (AppendSystemError):	during earlier work on Unix.
+
+2007-05-04  Kevin B. Kenny  <kennykb@acm.org>
+
+	* generic/tclIO.c (TclFinalizeIOSubsystem): Added an initializer to
+	silence a spurious gcc warning about use of an uninitialized
+	variable.
+	* tests/encoding.test: Modified so that encoding tests happen in a
+	private namespace, to avoid polluting the global one. This problem was
+	discovered when running the test suite '-singleproc 1 -skip exec.test'
+	because the 'path' variable in encoding.test conflicted with the one
+	in io.test.
+	* tests/io.test: Made more of the working variables private to the
+	namespace.
+
+2007-05-02  Kevin B. Kenny  <kennykb@acm.org>
+
+	* generic/tclTest.c (SimpleMatchInDirectory): Corrected a refcount
+	imbalance that affected the filesystem-[147]* tests in the test suite.
+	Thanks to Don Porter for the patch. [Bug 1710707]
+	* generic/tclPathObj.c (Tcl_FSJoinPath, Tcl_FSGetNormalizedPath):
+	Corrected several memory leaks that caused refcount imbalances
+	resulting in memory leaks on Windows. Thanks to Joe Mistachkin for the
+	patch.
+
+2007-05-01  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclVar.c (TclPtrSetVar): fixed leak whenever newvaluePtr had
+	refCount 0 and was used for appending (but not lappending). Thanks to
+	mistachkin and kbk. [Bug 1710710]
+
+2007-05-01  Kevin B. Kenny  <kennykb@acm.org>
+
+	* generic/tclIO.c (DeleteChannelTable): Made changes so that
+	DeleteChannelTable tries to close all open channels, not just the
+	first. [Bug 1710285]
+	* generic/tclThread.c (TclFinalizeSynchronization): Make sure that TSD
+	blocks get freed on non-threaded builds. [Bug 1710825]
+	* tests/utf.test (utf-25.1--utf-25.4): Modified tests to clean up
+	after the 'testobj' extension to avoid spurious reports of memory
+	leaks.
+
+2007-05-01  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclCmdMZ.c (STR_MAP): When [string map] has a pure dict map,
+	a missing Tcl_DictObjDone() call led to a memleak. [Bug 1710709]
+
+2007-04-30  Daniel Steffen  <das@users.sourceforge.net>
+
+	* unix/Makefile.in: add 'tclsh' dependency to install targets that
+	rely on tclsh, fixes parallel 'make install' from empty build dir.
+
+2007-04-30  Andreas Kupries <andreask@gactivestate.com>
+
+	* generic/tclIO.c (FixLevelCode): Corrected reference count
+	mismanagement of newlevel, newcode. Changed to allocate the Tcl_Obj's
+	as late as possible, and only when actually needed. [Bug 1705778, leak
+	K29]
+
+2007-04-30  Kevin B. Kenny  <kennykb@acm.org>
+
+	* generic/tclProc.c (Tcl_ProcObjCmd, SetLambdaFromAny): Corrected
+	reference count mismanagement on the name of the source file in the
+	TIP 280 code. [Bug 1705778, leak K02 among other manifestations]
+
+2007-04-25  Donal K. Fellows  <dkf@users.sf.net>
+
+	*** 8.5a6 TAGGED FOR RELEASE ***
+
+	* generic/tclProc.c (TclObjInterpProcCore): Only allocate objects for
+	error message generation when associated with argument names that are
+	really used. [Bug 1705778, leak K15]
+
+2007-04-25  Kevin B. Kenny  <kennykb@acm.org>
+
+	* generic/tclIOUtil.c (Tcl_FSChdir): Changed the memory management so
+	that the path returned from Tcl_FSGetNativePath is not duplicated
+	before being stored as the current directory, to avoid a memory leak.
+	[Bug 1705778, leak K01 among other manifestations]
+
+2007-04-25  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclCompExpr.c (ParseExpr):	Revised to be sure that an
+	error return doesn't prevent all literals getting placed on the
+	litList to be returned to the caller for freeing. Corrects some
+	memleaks. [Bug 1705778, leak K23]
+
+2007-04-25  Daniel Steffen  <das@users.sourceforge.net>
+
+	* unix/Makefile.in (dist): add macosx/*.xcconfig files to src dist;
+	copy license.terms to dist macosx dir; fix autoheader bits.
+
+2007-04-24  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclListObj.c: reverting [Patch 738900] (committed on
+	2007-04-20). Causes some Tk test breakage of unknown importance, but
+	the impact of the patch itself is likely to be so small that it does
+	not warrant investigation at this time.
+
+2007-04-24  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclDictObj.c (DictKeysCmd): Rewrote so that the lock on the
+	internal representation of a dict is only set when necessary. [Bug
+	1705778, leak K04]
+	(DictFilterCmd): Added code to drop the lock in the trivial match
+	case. [Bug 1705778, leak K05]
+
+2007-04-24  Kevin B. Kenny  <kennykb@acm.org>
+
+	* generic/tclBinary.c: Addressed several code paths where the error
+	return from the 'binary format' command leaked the result buffer.
+	* generic/tclListObj.c (TclLsetFlat): Fixed a bug where the new list
+	under construction was leaked in the error case. [Bug 1705778, leaks
+	K13 and K14]
+
+2007-04-24  Jeff Hobbs	<jeffh@ActiveState.com>
+
+	* unix/Makefile.in (dist): add platform library package to src dist
+
+2007-04-24  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclCompExpr.c (ParseExpr): Memory leak in error case; the
+	literal Tcl_Obj was not getting freed. [Bug 1705778, leak #1 (new)]
+
+	* generic/tclNamesp.c (Tcl_DeleteNamespace):	Corrected flaw in the
+	flag marking scheme to be sure that global namespaces are freed when
+	their interp is deleted. [Bug 1705778]
+
+2007-04-24  Kevin B. Kenny  <kennykb@acm.org>
+
+	* generic/tclExecute.c (TclExecuteByteCode): Plugged six memory leaks
+	in bignum arithmetic.
+	* generic/tclIOCmd.c (Tcl_ReadObjCmd): Plugged a leak of the buffer
+	object if the physical read returned an error and the bypass area had
+	no message.
+	* generic/tclIORChan.c (TclChanCreateObjCmd): Plugged a leak of the
+	return value from the "initialize" method of a channel handler.
+	(All of the above under [Bug 1705778])
+
+2007-04-23  Daniel Steffen  <das@users.sourceforge.net>
+
+	* generic/tclCkalloc.c: fix warnings from gcc build configured with
+	* generic/tclCompile.c: --enable-64bit --enable-symbols=all.
+	* generic/tclExecute.c:
+
+	* unix/tclUnixFCmd.c: add workaround for crashing bug in fts_open()
+	* unix/tclUnixInit.c: without FTS_NOSTAT on 64bit Darwin 8 or earlier.
+
+	* unix/tclLoadDyld.c (TclpLoadMemory): fix (void*) arithmetic.
+
+	* macosx/Tcl-Common.xcconfig: enable more warnings.
+
+	* macosx/Tcl.xcodeproj/project.pbxproj: add 'DebugMemCompile' build
+	configuration that calls configure with --enable-symbols=all; override
+	configure check for __attribute__((__visibility__("hidden"))) in Debug
+	configuration to restore availability of ZeroLink.
+
+	* macosx/tclMacOSXNotify.c: fix warnings.
+
+	* macosx/tclMacOSXFCmd.c: const fixes.
+
+	* macosx/Tcl-Common.xcconfig:	fix whitespace.
+	* macosx/Tcl-Debug.xcconfig:
+	* macosx/Tcl-Release.xcconfig:
+	* macosx/README:
+
+	* macosx/GNUmakefile:		fix/add copyright and license refs.
+	* macosx/tclMacOSXBundle.c:
+	* macosx/Tcl-Info.plist.in:
+	* macosx/Tcl.xcode/project.pbxproj:
+	* macosx/Tcl.xcodeproj/project.pbxproj:
+
+	* unix/configure.in: install license.terms into Tcl.framework.
+	* unix/configure: autoconf-2.59
+
+2007-04-23  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclVar.c (UnsetVarStruct):	Make sure the
+	TCL_INTERP_DESTROYED flags gets passed to unset trace routines so they
+	can respond appropriately. [Bug 1705778, leak #9]
+
+2007-04-23  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclCompile.c (TclFreeCompileEnv): Tip 280's new field
+	extCmdMapPtr was not being freed. [Bug 1705778, leak #1]
+
+2007-04-23  Kevin B. Kenny  <kennykb@acm.org>
+
+	* generic/tclCompCmds.c (TclCompileUpvarCmd): Plugged a memory leak in
+	'upvar' when compiling (a) upvar outside a proc, (b) upvar with a
+	syntax error, or (c) upvar where the frame index is not known at
+	compile time.
+	* generic/tclCompExpr.c (ParseExpr): Plugged a memory leak when
+	parsing expressions that contain syntax errors.
+	* generic/tclEnv.c (ReplaceString): Clear memory correctly when
+	growing the cache to avoid reads of uninitialised data.
+	* generic/tclIORChan.c (TclChanCreateObjCmd, FreeReflectedChannel):
+	Plugged two memory leaks.
+	* generic/tclStrToD.c (AccumulateDecimalDigit): Fixed a mistake where
+	we'd run beyond the end of the 'pow10_wide' array if a number begins
+	with a string of more than 'maxpow10_wide' zeroes.
+	* generic/tclTest.c (Testregexpobjcmd): Removed an invalid access
+	beyond the end of 'objv' in 'testregexp -about'.
+	All of these issues reported under [Bug 1705778] - detected with the
+	existing test suite, no new regression tests required.
+
+2007-04-22  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclVar.c (TclDeleteNamespaceVars): fixed access to freed
+	memory detected by valgrind: Tcl_GetCurrentNamespace was being
+	called after freeing root CallFrame (on interp deletion).
+
+2007-04-20  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclListObj.c (SetListFromAny): avoid discarding internal
+	reps of objects converted to singleton lists. [Patch 738900]
+
+2007-04-20  Kevin B. Kenny  <kennykb@acm.org>
+
+	* doc/clock.n: Corrected a silly error (transposed 'uppercase' and
+	'lowercase' in clock.n. [Bug 1656002]
+	Clarified that [clock scan] does not recognize a locale's alternative
+	calendar.
+	Deleted an entirely superfluous (and also incorrect) remark about the
+	effect of Daylight Saving Time on relative times in [clock scan]. [Bug
+	1582951]
+	* library/clock.tcl: Corrected an error in skipping over the %Ey field
+	on input.
+	* library/msgs/ja.msg:
+	* tools/loadICU.tcl: Corrected several localisation faults in the
+	Japanese locale (most notably, incorrect dates for the Emperors'
+	eras). Many thanks to SourceForge user 'nyademo' for pointing this out
+	and developing a fix. [Bug 1637471]
+	* generic/tclPathObj.c: Corrected a 'const'ness fault that caused
+	bitter complaints from MSVC.
+	* tests/clock.test (clock-40.1, clock-58.1, clock-59.1): Corrected a
+	test case that depended on ":localtime" being able to handle dates
+	prior to the Posix epoch. [Bug 1618445] Added a test case for the
+	dates of the Japanese emperors. [Bug 1637471] Added a regression test
+	for military time zone input conversion. [Bug 1586828]
+	* generic/tclGetDate.y (MilitaryTable): Fixed an ancient bug where the
+	military NZA time zones had the signs reversed. [Bug 1586828]
+	* generic/tclDate.c: Regenerated.
+	* doc/Notifier.3: Documented Tcl_SetNotifier and Tcl_ServiceModeHook.
+	Quite against my better judgment. [Bug 414933]
+	* generic/tclBasic.c, generic/tclCkalloc.c, generic/tclClock.c:
+	* generic/tclCmdIL.c, generic/tclCmdMZ.c, generic/tclFCmd.c:
+	* generic/tclFileName.c, generic/tclInterp.c, generic/tclIO.c:
+	* generic/tclIOUtil.c, generic/tclNamesp.c, generic/tclObj.c:
+	* generic/tclPathObj.c, generic/tclPipe.c, generic/tclPkg.c:
+	* generic/tclResult.c, generic/tclTest.c, generic/tclTestObj.c:
+	* generic/tclVar.c, unix/tclUnixChan.c, unix/tclUnixTest.c:
+	* win/tclWinLoad.c, win/tclWinSerial.c: Replaced commas in varargs
+	with string concatenation where possible. [Patch 1515234]
+	* library/tzdata/America/Tegucigalpa:
+	* library/tzdata/Asia/Damascus: Olson's tzdata 2007e.
+
+2007-04-19  Donal K. Fellows  <donal.k.fellows@manchester.ac.uk>
+
+	* generic/regcomp.c, generic/regc_cvec.c, generic/regc_lex.c,
+	* generic/regc_locale.c: Improve the const-correctness of the RE
+	compiler.
+
+2007-04-18  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclExecute.c (INST_LSHIFT): fixed a mistake introduced in
+	version 1.266 ('=' became '=='), which effectively turned the block
+	that handles native shifts into dead code. This explains why the
+	testsuite did not pick this mistake. Rewrote to make the intention
+	clear.
+
+	* generic/tclInt.h (TclDecrRefCount): change the order of the
+	branches, use empty 'if ; else' to handle use in unbraced outer
+	if/else conditions (as already done in tcl.h)
+
+	* generic/tclExecute.c: slight changes in Tcl_Obj management.
+
+2007-04-17  Kevin B. Kenny  <kennykb@acm.org>
+
+	* library/clock.tcl: Fixed the naming of
+	::tcl::clock::ReadZoneinfoFile because (yoicks!) it was in the global
+	namespace.
+	* doc/clock.n: Clarified the cases in which legacy time zone is
+	recognized. [Bug 1656002]
+
+2007-04-17  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclExecute.c: fixed checkInterp logic [Bug 1702212]
+
+2007-04-16  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* various (including generic/tclTest.c): Complete the purge of K&R
+	function definitions from manually-written code.
+
+2007-04-15  Kevin B. Kenny  <kennykb@acm.org>
+
+	* generic/tclCompCmds.c: added a cast to silence a compiler error on
+	VC2005.
+	* library/clock.tcl: Restored unique-prefix matching of keywords on
+	the [clock] command. [Bug 1690041]
+	* tests/clock.test: Added rudimentary test cases for unique-prefix
+	matching of keywords.
+
+2007-04-14  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclExecute.c: removed some code at INST_EXPAND_SKTOP that
+	duplicates functionality already present at checkForCatch.
+
+2007-04-12  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclExecute.c: new macros OBJ_AT_TOS, OBJ_UNDER_TOS,
+	OBJ_AT_DEPTH(n) and CURR_DEPTH that remove all direct references to
+	tosPtr from TEBC (after initialisation and the code at the label
+	cleanupV_pushObjResultPtr).
+
+2007-04-11  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclCompCmds.c: moved all exceptDepth management to the
+	macros - the decreasing half was managed by hand.
+
+2007-04-10  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* generic/tclInt.h (TclNewLiteralStringObj): New macro to make
+	allocating literal string objects (i.e. objects whose value is a
+	constant string) easier and more efficient, by allowing the omission
+	of the length argument. Based on [Patch 1529526] (afredd)
+	* generic/*.c: Make use of this (in many files).
+
+2007-04-08  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclCompile (tclInstructionTable): Fixed bugs in description
+	of dict instructions.
+
+2007-04-07  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclCompile (tclInstructionTable): Fixed bug in description
+	of INST_START_COMMAND.
+
+	* generic/tclExecute.c (TEBC): Small code reduction.
+
+2007-04-06  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclExecute.c (TEBC):
+	* generic/tclNamespace.c (NsEnsembleImplementationCmd):
+	* generic/tclProc.c (InitCompiledLocals, ObjInterpProcEx)
+	(TclObjInterpProcCore, ProcCompileProc): Code reordering to reduce
+	branching and improve branch prediction (assume that forward branches
+	are typically not taken).
+
+2007-04-03  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclExecute.c: INST_INVOKE optimisation. [Patch 1693802]
+
+2007-04-03  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclNamesp.c:	Revised ErrorCodeRead and ErrorInfoRead trace
+	routines so they guarantee the ::errorCode and ::errorInfo variable
+	always appear to exist. [Bug 1693252]
+
+2007-04-03  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclInt.decls:	 Moved TclGetNamespaceFromObj() to the
+	* generic/tclInt.h:	 internal stubs table; regen.
+	* generic/tclIntDecls.h:
+	* generic/tclStubInit.c:
+
+2007-04-02  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclBasic.c:	  Added bytecode compilers for the variable
+	* generic/tclCompCmds.c:  linking commands: 'global', 'variable',
+	* generic/tclCompile.h:	  'upvar', 'namespace upvar' [Patch 1688593]
+	* generic/tclExecute.c:
+	* generic/tclInt.h:
+	* generic/tclVar.c:
+
+2007-04-02  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclBasic.c:	Replace arrays on the C stack and ckalloc
+	* generic/tclExecute.c: calls with TclStackAlloc calls to use memory
+	* generic/tclFCmd.c:	on Tcl's evaluation stack.
+	* generic/tclFileName.c:
+	* generic/tclIOCmd.c:
+	* generic/tclIndexObj.c:
+	* generic/tclInterp.c:
+	* generic/tclNamesp.c:
+	* generic/tclTrace.c:
+	* unix/tclUnixPipe.c:
+
+2007-04-01  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclCompile.c (TclCompileScript, TclPrintInstruction):
+	* generic/tclExecute.c (TclExecuteByteCode): Changed the definition of
+	INST_START_CMD so that it knows how many commands start at the current
+	location. This makes the interpreter command counter correct without
+	requiring a large number of instructions to be issued. (See my change
+	from 2007-01-19 for what triggered this.)
+
+2007-03-30  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclCompile.c:
+	* generic/tclCompExpr.c:
+	* generic/tclCompCmds.c:	Replace arrays on the C stack and
+	ckalloc calls with TclStackAlloc calls to use memory on Tcl's
+	evaluation stack.
+
+	* generic/tclCmdMZ.c:	Revised [string to* $s $first $last]
+	implementation to reduce number of allocs/copies.
+
+	* tests/string.test:  More [string reverse] tests.
+
+2007-03-30  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclExecute.c: optimise the lookup of elements of indexed
+	arrays.
+
+2007-03-29  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclProc.c (Tcl_ApplyObjCmd):
+	* tests/apply.test (9.3): Fixed Tcl_Obj leak on error return; an
+	unneeded ref to lambdaPtr was being set and not released on an error
+	return path.
+
+2007-03-28  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclCmdMZ.c (STR_REVERSE):	Implement the actual [string
+	reverse] command in terms of the new TclStringObjReverse() routine.
+
+	* generic/tclInt.h (TclStringObjReverse):	New internal routine
+	* generic/tclStringObj.c (TclStringObjReverse): that implements the
+	[string reverse] operation, making use of knowledge/surgery of the
+	String intrep to minimize the number of allocs and copies needed to do
+	the job.
+
+2007-03-27  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclCmdMZ.c (STR_MAP): Replace ckalloc calls with
+	TclStackAlloc calls.
+
+2007-03-24  Zoran Vasiljevic <vasiljevic@users.sourceforge.net>
+
+	* win/tclWinThrd.c: Thread exit handler marks the current thread as
+	un-initialized. This allows exit handlers that are registered later to
+	re-initialize this subsystem in case they need to use some sync
+	primitives (cond variables) from this file again.
+
+2007-03-23  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclBasic.c (DeleteInterpProc): pop the root frame pointer
+	before deleting the global namespace [Bug 1658572]
+
+2007-03-23  Kevin B. Kenny  <kennykb@acm.org>
+
+	* win/Makefile.in: Added code to keep a Cygwin path name from leaking
+	into LIBRARY_DIR when doing 'make test' or 'make runtest'.
+
+2007-03-22  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclCmdAH.c (Tcl_ForeachObjCmd):	Replaced arrays on the
+	C stack and ckalloc calls with TclStackAlloc calls to use memory on
+	Tcl's evaluation stack.
+
+	* generic/tclExecute.c: Revised GrowEvaluationStack to take an
+	argument specifying the growth required by the caller, so that a
+	single reallocation / copy is the most that will ever be needed even
+	when required growth is large.
+
+2007-03-21  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclExecute.c: More ckalloc -> ckrealloc conversions.
+	* generic/tclLiteral.c:
+	* generic/tclNamesp.c:
+	* generic/tclParse.c:
+	* generic/tclPreserve.c:
+	* generic/tclStringObj.c:
+	* generic/tclUtil.c:
+
+2007-03-20  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclEnv.c:	Some more ckalloc -> ckrealloc replacements.
+	* generic/tclLink.c:
+
+2007-03-20  Kevin B. Kenny  <kennykb@acm.org>
+
+	* generic/tclDate.c: Rebuilt, despite Donal Fellows's comment when
+	committing it that no rebuild was required.
+	* generic/tclGetDate.y: According to Donal Fellows, "Introduce modern
+	formatting standards; no need for rebuild of tclDate.c."
+
+	* library/tzdata/America/Cambridge_Bay:
+	* library/tzdata/America/Havana:
+	* library/tzdata/America/Inuvik:
+	* library/tzdata/America/Iqaluit:
+	* library/tzdata/America/Pangnirtung:
+	* library/tzdata/America/Rankin_Inlet:
+	* library/tzdata/America/Resolute:
+	* library/tzdata/America/Yellowknife:
+	* library/tzdata/Asia/Choibalsan:
+	* library/tzdata/Asia/Dili:
+	* library/tzdata/Asia/Hovd:
+	* library/tzdata/Asia/Jakarta:
+	* library/tzdata/Asia/Jayapura:
+	* library/tzdata/Asia/Makassar:
+	* library/tzdata/Asia/Pontianak:
+	* library/tzdata/Asia/Ulaanbaatar:
+	* library/tzdata/Europe/Istanbul: Upgraded to Olson's tzdata2007d.
+
+	* generic/tclListObj.c (TclLsetList, TclLsetFlat):
+	* tests/lset.test: Changes to deal with shared internal representation
+	for lists passed to the [lset] command. Thanks to Don Porter for
+	fixing this issue. [Bug 1677512]
+
+2007-03-19  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclCompile.c: Revise the various expansion routines for
+	CompileEnv fields to use ckrealloc() where appropriate.
+
+	* generic/tclBinary.c (Tcl_SetByteArrayLength): Replaced ckalloc() /
+	memcpy() sequence with ckrealloc() call.
+
+	* generic/tclBasic.c (Tcl_CreateMathFunc):	Replaced some calls to
+	* generic/tclEvent.c (Tcl_CreateThread):	Tcl_Alloc() with calls
+	* generic/tclObj.c (UpdateStringOfBignum):	to ckalloc(), which
+	* unix/tclUnixTime.c (SetTZIfNecessary):	better supports memory
+	* win/tclAppInit.c (setargv):			debugging.
+
+2007-03-19  Donal K. Fellows  <donal.k.fellows@manchester.ac.uk>
+
+	* doc/regsub.n: Corrected example so that it doesn't recommend
+	potentially unsafe practice. Many thanks to Konstantin Kushnir
+	<chpock@gmail.com> for reporting this.
+
+2007-03-17  Kevin B. Kenny  <kennykb@acm.org>
+
+	* win/tclWinReg.c (GetKeyNames): Size the buffer for enumerating key
+	names correctly, so that Unicode names exceeding 127 chars can be
+	retrieved without crashing. [Bug 1682211]
+	* tests/registry.test (registry-4.9): Added test case for the above
+	bug.
+
+2007-03-15  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* generic/tclIOUtil.c (Tcl_Stat): Reimplement workaround to avoid gcc
+	warning by using local variables. When the macro argument is of type
+	long long instead of long, the incorrect warning is not generated.
+
+2007-03-15  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* win/Makefile.in: Fully qualify LIBRARY_DIR so that `make test` does
+	not depend on working dir.
+
+2007-03-15  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* tests/parse.test: Add two backslash newline parse tests.
+
+2007-03-12  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclExecute.c (INST_FOREACH_STEP4):	Make private copy of
+	* tests/foreach.test (foreach-10.1):	value list to be assigned to
+	variables so that shimmering of that list doesn't lead to invalid
+	pointers. [Bug 1671087]
+
+	* generic/tclEvent.c (HandleBgErrors):	Make efficient private copy
+	* tests/event.test (event-5.3): of the command prefix for the interp's
+	background error handling command to avoid panics due to pointers to
+	memory invalid after shimmering. [Bug 1670155]
+
+	* generic/tclNamesp.c (NsEnsembleImplementationCmd):	Make efficient
+	* tests/namespace.test (namespace-42.8):	private copy of the
+	command prefix as we invoke the command appropriate to a particular
+	subcommand of a particular ensemble to avoid panic due to shimmering
+	of the List intrep. [Bug 1670091]
+
+	* generic/tclVar.c (TclArraySet):	Make efficient private copy of
+	* tests/var.test (var-17.1):	the "list" argument to [array set] to
+	avoid crash due to shimmering invalidating pointers. [Bug 1669489]
+
+2007-03-12  Donal K. Fellows  <donal.k.fellows@manchester.ac.uk>
+
+	* generic/tclCmdIL.c (Tcl_LsortObjCmd): Fix problems with declaration
+	positioning and memory leaks. [Bug 1679072]
+
+2007-03-11  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclCmdIL.c (Tcl_LreverseObjCmd): Ensure that a list is
+	correctly reversed even if its internal representation is shared
+	without the object itself being shared. [Bug 1675044]
+
+2007-03-10  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclCmdIL (Tcl_LsortObjCmd): changed fix to [Bug 1675116] to
+	use the cheaper TclListObjCopy() instead of Tcl_DuplicateObj().
+
+2007-03-09  Andreas Kupries  <andreask@activestate.com>
+
+	* library/platform/shell.tcl: Made more robust if an older platform
+	* library/platform/pkgIndex.tcl: package is present in the inspected
+	* unix/Makefile.in: shell. Package forget it to prevent errors. Bumped
+	* win/Makefile.in: package version to 1.1.3, and updated the Makefiles
+	installing it as Tcl Module.
+
+2007-03-09  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* generic/tclCmdIL.c (Tcl_LsortObjCmd): Handle tricky case with loss
+	* tests/cmdIL.test (cmdIL-1.29):	of list rep during sorting due
+	to shimmering. [Bug 1675116]
+
+2007-03-09  Kevin B. Kenny  <kennykb@acm.org>
+
+	* library/clock.tcl (ReadZoneinfoFile): Added Y2038 compliance to the
+	code for version-2 'zoneinfo' files.
+	* tests/clock.test (clock-56.3): Added a test case for Y2038 and
+	'zoneinfo'. Modified test initialisation to use the
+	'loadTestedCommands' function of tcltest to bring in the correct path
+	for the registry library.
+
+2007-03-08  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclListObj.c (TclLsetList):	Rewrite so that the routine
+	itself does not do any direct intrep surgery. Better isolates those
+	things into the implementation of the "list" Tcl_ObjType.
+
+2007-03-08  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* generic/tclListObj.c (TclLindexList, TclLindexFlat): Moved these
+	functions to tclListObj.c from tclCmdIL.c to mirror the way that the
+	equivalent functions for [lset]'s guts are arranged.
+
+2007-03-08  Kevin B. Kenny  <kennykb@acm.org>
+
+	* library/clock.tcl: Further tweaks to the Windows time zone table
+	(restoring missing Mexican time zones). Added rudimentary handling of
+	version-2 'zoneinfo' files. Update US DST rules so that zones such as
+	'EST5EDT' get the correct transition dates.
+	* tests/clock.test: Added rudimentary test cases for 'zoneinfo'
+	parsing. Adjusted several tests that depended on obsolete US DST
+	transition rules.
+
+2007-03-07  Daniel Steffen  <das@users.sourceforge.net>
+
+	* macosx/tclMacOSXNotify.c: add spinlock debugging and sanity checks.
+
+	* macosx/Tcl.xcodeproj/project.pbxproj: ensure gcc version used by
+	* macosx/Tcl.xcodeproj/default.pbxuser: Xcode and configure/make are
+	* macosx/Tcl-Common.xcconfig:		consistent and independent of
+	gcc_select default and CC env var; fixes for Xcode 3.0.
+
+	* unix/tcl.m4 (Darwin): s/CFLAGS/CPPFLAGS/ in macosx-version-min check
+	* unix/configure: autoconf-2.59
+
+2007-03-07  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclCmdIL.c (TclLindex*):	Rewrites to make efficient
+	private copies of the list and indexlist arguments, so we can operate
+	on the list elements directly with no fear of shimmering effects.
+	Replaces defensive coding schemes that are otherwise required. End
+	result is that TclLindexList is entirely a wrapper around
+	TclLindexFlat, which is now the core engine of all [lindex]
+	operations.
+
+	* generic/tclObj.c (Tcl_AppendAllObjTypes):	Converted to simpler
+	list validity test.
+
+2007-03-07  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* generic/tclRegexp.c (TclRegAbout): Generate information about a
+	regexp as a Tcl_Obj instead of as a string, which is more efficient.
+
+2007-03-07  Kevin B. Kenny  <kennykb@acm.org>
+
+	* library/clock.tcl: Adjusted Windows time zone table to handle new US
+	DST rules by locale rather than as Posix time zone spec.
+	* tests/clock.test (clock-39.6, clock-49.2, testclock::registry):
+	Adjusted tests to simulate new US rules.
+	* library/tzdata/America/Indiana/Winamac:
+	* library/tzdata/Europe/Istanbul:
+	* library/tzdata/Pacific/Easter:
+	Olson's tzdata2007c.
+
+2007-03-05  Andreas Kupries  <andreask@activestate.com>
+
+	* library/platform/shell.tcl (::platform::shell::RUN): In the case of
+	* library/platform/pkgIndex.tcl: a failure put the captured stderr
+	* unix/Makefile.in: into the error message to aid in debugging. Bumped
+	* win/Makefile.in: package version to 1.1.2, and updated the makefiles
+	installing it as Tcl Module.
+
+2007-03-03  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclLink.c (LinkedVar): Added macro to conceal at least some
+	of the pointer hackery.
+
+2007-03-02  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclCmdIL.c (Tcl_LreverseObjCmd):	Added missing
+	TclInvalidateStringRep() call when we directly manipulate the intrep
+	of an unshared "list" Tcl_Obj. [Bug 1672585]
+
+	* generic/tclCmdIL.c (Tcl_JoinObjCmd):	Revised [join] implementation
+	to append Tcl_Obj's instead of strings. [RFE 1669420]
+
+	* generic/tclCmdIL.c (Info*Cmd):	Code simplifications and
+	optimizations.
+
+2007-03-02  Donal K. Fellows  <donal.k.fellows@manchester.ac.uk>
+
+	* generic/tclCompile.c (TclPrintInstruction): Added a scheme to allow
+	* generic/tclCompile.h (AuxDataPrintProc):    aux-data to be printed
+	* generic/tclCompCmds.c (Print*Info):	      out for debugging. For
+	this to work, immediate operands referring to aux-data must be
+	identified as such in the instruction descriptor table using
+	OPERAND_AUX4 (all are always 4 bytes).
+
+	* generic/tclExecute.c (TclExecuteByteCode): Rewrote the compiled
+	* generic/tclCompCmds.c (TclCompileDictCmd): [dict update] so that it
+	* generic/tclCompile.h (DictUpdateInfo):     stores critical
+	* tests/dict.test (dict-21.{14,15}):	     non-varying data in an
+	aux-data value instead of a (shimmerable) literal. [Bug 1671001]
+
+2007-03-01  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclCmdIL.c (Tcl_LinsertObjCmd):	Code simplifications
+	and optimizations.
+
+	* generic/tclCmdIL.c (Tcl_LreplaceObjCmd):	Code simplifications
+	and optimizations.
+
+	* generic/tclCmdIL.c (Tcl_LrangeObjCmd):	Rewrite in the same
+	spirit; avoid shimmer effects rather than react to them.
+
+	* generic/tclCmdAH.c (Tcl_ForeachObjCmd):	Stop throwing away
+	* tests/foreach.test (foreach-1.14):	useful error information when
+	loop variable sets fail.
+
+	* generic/tclCmdIL.c (Tcl_LassignObjCmd):	Rewrite to make an
+	efficient private copy of the list argument, so we can operate on the
+	list elements directly with no fear of shimmering effects. Replaces
+	defensive coding schemes that are otherwise required.
+
+	* generic/tclCmdAH.c (Tcl_ForeachObjCmd):	Rewrite to make
+	efficient private copies of the variable and value lists, so we can
+	operate on them without any special shimmer defense coding schemes.
+
+2007-03-01  Donal K. Fellows  <donal.k.fellows@manchester.ac.uk>
+
+	* generic/tclCompCmds.c (TclCompileForeachCmd): Prevent an unexpected
+	* tests/foreach.test (foreach-9.1):		infinite loop when the
+	variable list is empty and the foreach is compiled. [Bug 1671138]
+
+2007-02-26  Andreas Kupries  <andreask@activestate.com>
+
+	* generic/tclIORChan.c (FreeReflectedChannel): Added the missing
+	refcount release between NewRC and FreeRC for the channel handle
+	object, spotted by Don Porter. [Bug 1667990]
+
+2007-02-26  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclCmdAH.c (Tcl_ForeachObjCmd):	Removed surplus
+	copying of the objv array that used to be a workaround for [Bug
+	404865]. That bug is long fixed.
+
+2007-02-24  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclBasic.c:	Use new interface in Tcl_EvalObjEx so that the
+	recounting logic of the List internal rep need not be repeated there.
+	Better encapsulation of internal details.
+
+	* generic/tclInt.h:	New internal routine TclListObjCopy() used
+	* generic/tclListObj.c: to efficiently do the equivalent of [lrange
+	$list 0 end]. After some experience with this, might be a good
+	candidate for exposure as a public interface. It's useful for callers
+	of Tcl_ListObjGetElements() who want to control the ongoing validity
+	of the returned objv pointer.
+
+2007-02-22  Andreas Kupries  <andreask@activestate.com>
+
+	* tests/pkg.test: Added tests for the case of an alpha package
+	satisfying a require for the regular package, demonstrating a corner
+	case specified in TIP#280. More notes in the comments to the test.
+
+2007-02-20  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tclInt.decls: Added "const" specifiers in TclSockGetPort
+	* generic/tclIntDecls.h: regenerated
+	* generic/*.c:
+	* unix/tclUnixChan.c
+	* unix/tclUnixPipe.c
+	* win/tclWinPipe.c
+	* win/tclWinSock.c: Added many "const" specifiers in implementation.
+
+2007-02-20  Don Porter	<dgp@users.sourceforge.net>
+
+	* doc/tcltest.n:	Typo fix. [Bug 1663539]
+
+2007-02-20  Pat Thoyts	<patthoyts@users.sourceforge.net>
+
+	* generic/tclFileName.c:  Handle extended paths on Windows NT and
+	* generic/tclPathObj.c:	  above. These have a \\?\ prefix. [Bug
+	* win/tclWinFile.c:	  1479814]
+	* tests/winFCmd.test:	  Tests for extended path handling.
+
+2007-02-19  Jeff Hobbs	<jeffh@ActiveState.com>
+
+	* unix/tcl.m4: use SHLIB_SUFFIX=".so" on HP-UX ia64 arch.
+	* unix/configure: autoconf-2.59
+
+	* generic/tclIOUtil.c (Tcl_FSEvalFileEx): safe incr of objPtr ref.
+
+2007-02-18  Donal K. Fellows  <dkf@users.sf.net>
+
+	* doc/chan.n, doc/clock.n, doc/eval.n, doc/exit.n, doc/expr.n:
+	* doc/interp.n, doc/open.n, doc/platform_shell.n, doc/pwd.n:
+	* doc/refchan.n, doc/regsub.n, doc/scan.n, doc/tclvars.n, doc/tm.n:
+	* doc/unload.n: Apply [Bug 1610310] to fix typos. Thanks to Larry
+	Virden for spotting them.
+
+	* doc/interp.n: Partial fix of [Bug 1662436]; rest requires some
+	policy decisions on what should and shouldn't be safe commands from
+	the "new in 8.5" set.
+
+2007-02-13  Kevin B. Kenny  <kennykb@acm.org>
+
+	* tools/fix_tommath_h.tcl: Further tweaking for the x86-64. The change
+	is to make 'mp_digit' be an 'unsigned int' on that platform; since
+	we're using only 32 bits of it, there's no reason to make it a 64-bit
+	'unsigned long.'
+	* generic/tclTomMath.h: Regenerated.
+
+2007-02-13  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* doc/re_syntax.n: Corrected description of 'print' class [Bug
+	1614687] and enhanced description of 'graph' class.
+
+2007-02-12  Kevin B. Kenny  <kennykb@acm.org>
+
+	* tools/fix_tommath_h.tcl: Added code to patch out a check for
+	__x86_64__ that caused Tommath to use __attributes(TI)__ for the
+	mp_word type. Tetra-int's simply fail on too many gcc-glibc-OS
+	combinations to be ready for shipment today, even if they work for
+	some of us. This change allows reversion of das's change of 2006-08-18
+	that accomplised the same thing on Darwin. [Bugs 1601380, 1603737,
+	1609936, 1656265]
+	* generic/tclTomMath.h: Regenerated.
+	* library/tzdata/Africa/Asmara:
+	* library/tzdata/Africa/Asmera:
+	* library/tzdata/America/Nassau:
+	* library/tzdata/Atlantic/Faeroe:
+	* library/tzdata/Atlantic/Faroe:
+	* library/tzdata/Australia/Eucla:
+	* library/tzdata/Pacific/Easter: Rebuilt from Olson's tzdata2007b.
+
+2007-02-09  Joe Mistachkin  <joe@mistachkin.com>
+
+	* win/nmakehlp.c: Properly cleanup after nmakehlp, including the
+	* win/makefile.vc: vcX0.pch file.
+
+2007-02-08  Jeff Hobbs	<jeffh@ActiveState.com>
+
+	* unix/tclUnixInit.c (TclpCheckStackSpace): do stack size checks with
+	unsigned size_t to correctly validate stackSize in the 2^31+ range.
+	[Bug 1654104]
+
+2007-02-08  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclNamesp.c:	Corrected broken logic in Tcl_DeleteNamespace
+	* tests/namespace.test: introduced in Patch 1577278 that caused
+	[namespace delete ::] to be effective only at level #0. New test
+	namespace-7.7 should prevent similar error in the future [Bug 1655305]
+
+2007-02-06  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclNamesp.c:	Corrected broken implementation of the
+	* tests/namespace.test: TclMatchIsTrivial optimization on [namespace
+	children $namespace $pattern].
+
+2007-02-04  Daniel Steffen  <das@users.sourceforge.net>
+
+	* unix/tcl.m4: use gcc4's __attribute__((__visibility__("hidden"))) if
+	available to define MODULE_SCOPE effective on all platforms.
+	* unix/configure.in: add caching to -pipe and zoneinfo checks.
+	* unix/configure: autoconf-2.59
+	* unix/tclConfig.h.in: autoheader-2.59
+
+2007-02-03  Joe Mistachkin  <joe@mistachkin.com>
+
+	* win/rules.vc: Fix platform specific file copy macros for downlevel
+	Windows.
+
+2007-01-29  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclResult.c: Added optimization case to TclTransferResult to
+	cover common case where there's big savings over the fully general
+	path. Thanks to Peter MacDonald. [Bug 1626518]
+
+	* generic/tclLink.c:	Broken linked float logic corrected. Thanks to
+	Andy Goth. [Bug 1602538]
+
+	* doc/fcopy.n:	Typo fix. [Bug 1630627]
+
+2007-01-28  Daniel Steffen  <das@users.sourceforge.net>
+
+	* macosx/Tcl.xcodeproj/project.pbxproj:	  extract build settings that
+	* macosx/Tcl.xcodeproj/default.pbxuser:	  were common to multiple
+	* macosx/Tcl-Common.xcconfig (new file):  configurations into external
+	* macosx/Tcl-Debug.xcconfig (new file):	  xcconfig files; add extra
+	* macosx/Tcl-Release.xcconfig (new file): configurations for building
+	with SDKs and 64bit; convert legacy jam-based 'Tcl' target to native
+	target with single script phase; correct syntax of build setting
+	references to use $() throughout.
+
+	* macosx/README: document new Tcl.xcodeproj configurations; other
+	minor updates/corrections.
+
+	* generic/tcl.h: update location of version numbers in macosx files.
+
+	* macosx/Tcl.xcode/project.pbxproj: restore 'tcltest' target to
+	* macosx/Tcl.xcode/default.pbxuser: working order by replicating
+	applicable changes to Tcl.xcodeproj since 2006-07-20.
+
+2007-01-25  Daniel Steffen  <das@users.sourceforge.net>
+
+	* unix/tcl.m4: integrate CPPFLAGS into CFLAGS as late as possible and
+	move (rather than duplicate) -isysroot flags from CFLAGS to CPPFLAGS
+	to avoid errors about multiple -isysroot flags from some older gcc
+	builds.
+
+	* unix/configure: autoconf-2.59
+
+2007-01-22  Donal K. Fellows  <donal.k.fellows@manchester.ac.uk>
+
+	* compat/memcmp.c (memcmp): Reworked so that arithmetic is never
+	performed upon void pointers, since that is illegal. [Bug 1631017]
+
+2007-01-19  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* generic/tclCompile.c (TclCompileScript): Reduce the frequency with
+	which we issue INST_START_CMD, making bytecode both more compact and
+	somewhat faster. The optimized case is where we would otherwise be
+	issuing a sequence of those instructions; in those cases, it is only
+	ever the first one encountered that could possibly trigger.
+
+2007-01-19  Joe Mistachkin  <joe@mistachkin.com>
+
+	* tools/man2tcl.c: Include stdlib.h for exit() and improve comment
+	detection.
+	* win/nmakehlp.c: Update usage.
+	* win/makefile.vc: Properly build man2tcl.c for MSVC8.
+
+2007-01-19  Daniel Steffen  <das@users.sourceforge.net>
+
+	* macosx/tclMacOSXFCmd.c (TclMacOSXSetFileAttribute): on some versions
+	of Mac OS X, truncate() fails on resource forks, in that case use
+	open() with O_TRUNC instead.
+
+	* macosx/tclMacOSXNotify.c: accommodate changes to prototypes of
+	OSSpinLock(Un)Lock API.
+
+	* macosx/Tcl.xcodeproj/project.pbxproj: ensure HOME and USER env vars
+	* macosx/Tcl.xcodeproj/default.pbxuser: are defined when running
+						testsuite from Xcode.
+
+	* tests/env.test: add extra system env vars that need to be preserved
+	on some Mac OS X versions for testsuite to work.
+
+	* unix/Makefile.in:  Move libtommath defines into configure.in to
+	* unix/configure.in: avoid replicating them across multiple
+	* macosx/Tcl.xcodeproj/project.pbxproj: buildsystems.
+
+	* unix/tcl.m4: ensure CPPFLAGS env var is used when set. [Bug 1586861]
+	(Darwin): add -isysroot and -mmacosx-version-min flags to CPPFLAGS
+	when present in CFLAGS to avoid discrepancies between what headers
+	configure sees during preprocessing tests and compiling tests.
+
+	* unix/configure: autoconf-2.59
+	* unix/tclConfig.h.in: autoheader-2.59
+
+2007-01-18  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* generic/tclCompile.c (TclCompileScript): Make sure that when parsing
+	an expanded literal fails, a correct bytecode sequence is still
+	issued. [Bug 1638414]. Also make sure that the start of the expansion
+	bytecode sequence falls inside the span of bytecodes for a command.
+	* tests/compile.test (compile-16.24): Added test for [Bug 1638414]
+
+2007-01-17  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclIO.c: Added macros to make usage of ChannelBuffers
+	clearer.
+
+2007-01-11  Joe English	 <jenglish@users.sourceforge.net>
+
+	* win/tcl.m4(CFLAGS_WARNING): Remove "-Wconversion". This was removed
+	from unix/tcl.m4 2004-07-16 but not from here.
+	* win/configure: Regenerated.
+
+2007-01-11  Pat Thoyts	<patthoyts@users.sourceforge.net>
+
+	* win/makefile.vc: Fixes to work better on Win98. Read version numbers
+	* win/nmakehlp.c:  from package index file to avoid keeping numbers in
+	* win/rules.vc:	   the makefile where they may become de-synchronized.
+
+2007-01-10  Donal K. Fellows  <donal.k.fellows@manchester.ac.uk>
+
+	* generic/regcomp.c (compile, freev):	     Define a strategy for
+	* generic/regexec.c (exec):		     managing the internal
+	* generic/regguts.h (AllocVars, FreeVars):   vars of the RE engine to
+	* generic/regcustom.h (AllocVars, FreeVars): reduce C stack usage.
+	This will make Tcl as a whole much less likely to run out of stack
+	space...
+
+2007-01-09  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* generic/tclCompCmds.c (TclCompileLindexCmd):
+	* tests/lindex.test (lindex-9.2): Fix silly bug that ended up
+	sometimes compiling list arguments in the wrong order. [Bug 1631364]
+
+2007-01-03  Kevin B. Kenny  <kennykb@acm.org>
+
+	* generic/tclDate.c: Regenerated to recover a lost fix from patthoyts.
+	[Bug 1618523]
+
+2006-12-26  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* generic/tclIO.c (Tcl_GetsObj): Avoid checking for for the LF in a
+	possible CRLF sequence when EOF has already been found.
+
+2006-12-26  Mo DeJong  <mdejong@users.sourceforge.net>
+
+	* generic/tclEncoding.c (EscapeFromUtfProc): Clear the
+	TCL_ENCODING_END flag when end bytes are written. This fix keep this
+	method from writing escape bytes for an encoding like iso2022-jp
+	multiple times when the escape byte overlap with the end of the IO
+	buffer.
+	* tests/io.test: Add test for escape byte overlap issue.
+
+2006-12-19  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* unix/tclUnixThrd.c (Tcl_GetAllocMutex, TclpNewAllocMutex): Add
+	intermediate variables to shut up unwanted warnings. [Bug 1618838]
+
+2006-12-19  Daniel Steffen  <das@users.sourceforge.net>
+
+	* unix/tclUnixThrd.c (TclpInetNtoa): fix for 64 bit.
+
+	* unix/tcl.m4 (Darwin): --enable-64bit: verify linking with 64bit
+	-arch flag succeeds before enabling 64bit build.
+	* unix/configure: autoconf-2.59
+
+2006-12-17  Daniel Steffen  <das@users.sourceforge.net>
+
+	* tests/macOSXLoad.test (new file): add testing of .bundle loading and
+	* tests/load.test:		    unloading on Darwin (in addition
+	* tests/unload.test:		    to existing tests of .dylib
+	loading).
+	* macosx/Tcl.xcodeproj/project.pbxproj: add building of dltest
+	binaries so that testsuite run from Xcode can use them; fix testsuite
+	run script
+	* unix/configure.in:	   add support for building dltest binaries as
+	* unix/dltest/Makefile.in: .bundle (in addition to .dylib) on Darwin.
+	* unix/Makefile.in: add stub lib dependency to dltest target.
+	* unix/configure: autoconf-2.59
+
+	* tests/append.test: fix cleanup failure when all tests are skipped.
+
+	* tests/chan.test (chan-16.9): cleanup chan event handler to avoid
+	causing error in event.test when running testsuite with -singleproc 1.
+
+	* tests/info.test: add !singleTestInterp constraint to tests that fail
+	when running testsuite with -singleproc 1. [Bug 1605269]
+
+2006-12-14  Donal K. Fellows  <donal.k.fellows@manchester.ac.uk>
+
+	* doc/string.n: Fix example. [Bug 1615277]
+
+2006-12-12  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclCompExpr.c:	Now that the new internal structs are
+	in use to support operator commands, might as well make them the
+	default for [expr] as well and avoid passing every parsed expression
+	through the inefficient Tcl_Token array format. This addresses most
+	issues in [RFE 1517602]. Assuming no performance disasters result from
+	this, much dead code supporting the other implementation might now be
+	removed.
+
+	* generic/tclBasic.c:	Final step routing all direct evaluation forms
+	* generic/tclCompExpr.c: of the operator commands through TEBC,
+	* generic/tclCompile.h: dropping all the routines in tclMathOp.c.
+	* generic/tclMathOp.c:	Still needs Engineering Manual attention.
+
+2006-12-11  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclBasic.c:	Another step with all sorting operator
+	* generic/tclCompExpr.c: commands now routing through TEBC via
+	* generic/tclCompile.h: TclSortingOpCmd().
+
+2006-12-08  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclBasic.c:	 Another step down the path of re-using
+	* generic/tclCompExpr.c: TclExecuteByteCode to implement the TIP 174
+	* generic/tclCompile.h: commands instead of using a mass of code
+	* generic/tclMathOp.c:	duplication. Now all operator commands that
+	* tests/mathop.test:	demand exactly one operation are implemented
+	via TclSingleOpCmd and a call to TEBC.
+
+	* generic/tclCompExpr.c: Revised implementation of TclInvertOpCmd to
+	* generic/tclMathOp.c:	perform a bytecode compile / execute sequence.
+	This demonstrates a path toward avoiding mountains of code duplication
+	in tclMathOp.c and tclExecute.c.
+
+	* generic/tclCompile.h: Change TclExecuteByteCode() from static to
+	* generic/tclExecute.c: MODULE_SCOPE so all files including
+	tclCompile.h may call it.
+
+	* generic/tclMathOp.c:	More revisions to make tests pass.
+	* tests/mathop.test:
+
+2006-12-08  Donal K. Fellows  <donal.k.fellows@manchester.ac.uk>
+
+	* generic/tclNamesp.c (TclTeardownNamespace): Ensure that dying
+	namespaces unstitch themselves from their referents. [Bug 1571056]
+	(NsEnsembleImplementationCmd): Silence GCC warning.
+
+	* tests/mathop.test: Full tests for & | and ^ operators
+
+2006-12-08  Daniel Steffen  <das@users.sourceforge.net>
+
+	* library/tcltest/tcltest.tcl: use [info frame] for "-verbose line".
+
+2006-12-07  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclCompCmds.c:	Additional commits correct most
+	* generic/tclExecute.c:		failing tests illustrating bugs
+	* generic/tclMathOp.c:		uncovered in [Patch 1578137].
+
+	* generic/tclBasic.c:	Biggest source of TIP 174 failures was that
+	the commands were not [namespace export]ed from the ::tcl::mathop
+	namespace. More bits from [Patch 1578137] correct that.
+
+	* tests/mathop.test:	Commmitted several new tests from Peter Spjuth
+	found in [Patch 1578137]. Many failures now demonstrate issues to fix
+	in the TIP 174 implementation.
+
+2006-12-07  Donal K. Fellows  <donal.k.fellows@manchester.ac.uk>
+
+	* tests/mathop.test: Added tests for ! ~ eq operators.
+	* generic/tclMathOp.c (TclInvertOpCmd): Add in check for non-integral
+	numeric values.
+	* generic/tclCompCmds.c (CompileCompareOpCmd): Factor out the code
+	generation for the chained comparison operators.
+
+2006-12-07  Pat Thoyts	<patthoyts@users.sourceforge.net>
+
+	* tests/exec.test: Fixed line endings (caused win32 problems).
+
+2006-12-06  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclCompCmds.c:	Revised and consolidated into utility
+	* tests/mathop.test:		routines some of routines that compile
+	the new TIP 174 commands. This corrects some known bugs. More to come.
+
+2006-12-06  Kevin B. Kenny  <kennykb@acm.org>
+
+	* tests/expr.test (expr-47.12): Improved error reporting in hopes of
+	having more information to pursue [Bug 1609936].
+
+2006-12-05  Andreas Kupries  <andreask@activestate.com>
+
+	TIP#291 IMPLEMENTATION
+
+	* generic/tclBasic.c: Define tcl_platform element for pointerSize.
+	* doc/tclvars.n:
+
+	* win/Makefile.in: Added installation instructions for the platform
+	* win/makefile.vc: package. Added the platform package.
+	* win/makefile.bc:
+	* unix/Makefile.in:
+
+	* tests/platform.test:
+	* tests/safe.test:
+
+	* library/platform/platform.tcl:
+	* library/platform/shell.tcl:
+	* library/platform/pkgIndex.tcl:
+
+	* doc/platform.n:
+	* doc/platform_shell.n:
+
+2006-12-05  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclPkg.c:	When no requirements are supplied to a
+	* tests/pkg.test:	[package require $pkg] and [package unknown]
+	is invoked to find a satisfying package, pass the requirement argument
+	"0-" (which means all versions are acceptable). This permits a
+	registered [package unknown] command to call [package vsatisfies
+	$testVersion {*}$args] without any special handling of the empty $args
+	case. This fixes/avoids a bug in [::tcl::tm::UnknownHandler] that was
+	causing old TM versions to be provided in preference to newer TM
+	versions. Thanks to Julian Noble for discovering the issue.
+
+2006-12-04  Donal K. Fellows  <dkf@users.sf.net>
+
+	TIP#267 IMPLEMENTATION
+
+	* generic/tclIOCmd.c (Tcl_ExecObjCmd): Added -ignorestderr option,
+	* tests/exec.test, doc/exec.n:	       loosely from [Patch 1476191]
+
+2006-12-04  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclCompExpr.c:	Added implementation for the
+	CompileExprTree() routine that can produce expression bytecode
+	directly from internal structures with no need to pass through the
+	Tcl_Token array representation. Still disabled by default. #undef
+	USE_EXPR_TOKENS to try it out.
+
+2006-12-03  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclCompExpr.c:	Added expr parsing routines that
+	produce a different set of internal structures representing the parsed
+	expression, as well as routines that go on to convert those structures
+	into the traditional Tcl_Token array format. Use of these routines is
+	currently disabled. #undef PARSE_DIRECT_EXPR_TOKENS to enable them.
+	These routines will only become really useful when more routines that
+	compile directly from the new internal structures are completed.
+
+2006-12-02  Donal K. Fellows  <dkf@users.sf.net>
+
+	* doc/file.n: Clarification of [file pathtype] docs. [Bug 1606454]
+
+2006-12-01  Kevin B. Kenny	 <kennykb@acm.org>
+
+	* libtommath/bn_mp_add.c:	Corrected the effects of a
+	* libtommath/bn_mp_div.c:	bollixed 'cvs merge' operation
+	* libtommath/bncore.c:		that inadvertently committed some
+	* libtommath/tommath_class.h:	half-developed code.
+
+	TIP#299 IMPLEMENTATION
+
+	* doc/mathfunc.n:	Added isqrt() function to docs
+	* generic/tclBasic.c:	Added isqrt() math function (ExprIsqrtFunc)
+	* tests/expr.test (expr-47.*): Added tests for isqrt()
+	* tests/info.test (info-20.2): Added isqrt() to expected math funcs.
+
+2006-12-01  Don Porter	<dgp@users.sourceforge.net>
+
+	* tests/chan.test:	Correct timing sensitivity in new test. [Bug
+	1606860]
+
+	TIP#287 IMPLEMENTATION
+
+	* doc/chan.n:		New subcommand [chan pending].
+	* generic/tclBasic.c:	Thanks to Michael Cleverly for proposal
+	* generic/tclInt.h:	and implementation.
+	* generic/tclIOCmd.c:
+	* library/init.tcl:
+	* tests/chan.test:
+	* tests/ioCmd.test:
+
+	TIP#298 IMPLEMENTATION
+
+	* generic/tcl.decls: Tcl_GetBignumAndClearObj -> Tcl_TakeBignumFromObj
+	* generic/tclObj.c:
+
+	* generic/tclDecls.h:	make genstubs
+	* generic/tclStubInit.c:
+
+	* generic/tclExecute.c: Update callers.
+	* generic/tclMathOp.c:
+
+2006-11-30  Kevin B. Kenny  <kennykb@acm.org>
+
+	* library/tzdata: Olson's tzdata2006p.
+	* libtommath/bn_mp_sqrt.c: Fixed a bug where the initial approximation
+	to the square root could be on the wrong side, causing failure of
+	convergence.
+
+2006-11-29  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclBasic.c (Tcl_AppendObjToErrorInfo):  Added
+	Tcl_DecrRefCount() on the objPtr argument to plug memory leaks. This
+	makes the routine a consumer, which makes it easiest to use.
+
+2006-11-28  Andreas Kupries  <andreask@activestate.com>
+
+	* generic/tclBasic.c: TIP #280 implementation.
+	* generic/tclCmdAH.c:
+	* generic/tclCmdIL.c:
+	* generic/tclCmdMZ.c:
+	* generic/tclCompCmds.c:
+	* generic/tclCompExpr.c:
+	* generic/tclCompile.c:
+	* generic/tclCompile.h:
+	* generic/tclExecute.c:
+	* generic/tclIOUtil.c:
+	* generic/tclInt.h:
+	* generic/tclInterp.c:
+	* generic/tclNamesp.c:
+	* generic/tclObj.c:
+	* generic/tclProc.c:
+	* tests/compile.test:
+	* tests/info.test:
+	* tests/platform.test:
+	* tests/safe.test:
+
+2006-11-27  Kevin B. Kenny  <kennykb@acm.org>
+
+	* unix/tclUnixChan.c (TclUnixWaitForFile):
+	* tests/event.test (event-14.*): Corrected a bug where
+	TclUnixWaitForFile would present select() with the wrong mask on an
+	LP64 machine if a fd number exceeds 32. Thanks to Jean-Luc Fontaine
+	for reporting and diagnosing. [Bug 1602208]
+
+2006-11-27  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclExecute.c (TclIncrObj):	Correct failure to detect
+	floating-point increment values. Thanks to William Coleda [Bug
+	1602991]
+
+2006-11-26  Donal K. Fellows  <dkf@users.sf.net>
+
+	* tests/mathop.test, doc/mathop.n: More bits and pieces of the TIP#174
+	implementation. Note that the test suite is not yet complete.
+
+2006-11-26  Daniel Steffen  <das@users.sourceforge.net>
+
+	* unix/tcl.m4 (Linux): --enable-64bit support.	[Patch 1597389]
+	* unix/configure: autoconf-2.59			[Bug 1230558]
+
+2006-11-25  Donal K. Fellows  <dkf@users.sf.net>
+
+	TIP#174 IMPLEMENTATION
+
+	* generic/tclMathOp.c (new file): Completed the implementation of the
+	interpreted versions of all the tcl::mathop commands. Moved to a new
+	file to make tclCompCmds.c more focused in purpose.
+
+2006-11-23  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclCompCmds.c (Tcl*OpCmd, TclCompile*OpCmd):
+	* generic/tclBasic.c (Tcl_CreateInterp): Partial implementation of
+	TIP#174; the commands are compiled, but (mostly) not interpreted yet.
+
+2006-11-22  Donal K. Fellows  <dkf@users.sf.net>
+
+	TIP#269 IMPLEMENTATION
+
+	* generic/tclCmdMZ.c (Tcl_StringObjCmd): Implementation of the [string
+	* tests/string.test (string-25.*):	 is list] command, based on
+	* doc/string.n:				 work by Joe Mistachkin, with
+	enhancements by Donal Fellows for better failindex behaviour.
+
+2006-11-22  Don Porter	<dgp@users.sourceforge.net>
+
+	* tools/genWinImage.tcl (removed):	Removed two files used in
+	* win/README.binary (removed):	production of binary distributions
+	for Windows, a task we no longer perform. [Bug 1476980]
+	* generic/tcl.h:	Remove mention of win/README.binary in comment
+
+	* generic/tcl.h:	Moved TCL_REG_BOSONLY #define from tcl.h to
+	* generic/tclInt.h:	tclInt.h. Only know user is Expect, which
+	already #include's tclInt.h. No need to continue greater exposure.
+	[Bug 926500]
+
+2006-11-20  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclBasic.c (Tcl_CreateInterp, TclHideUnsafeCommands):
+	* library/init.tcl: Refactored the [chan] command's guts so that it
+	does not use aliases to global commands, making the code more robust.
+
+2006-11-17  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclExecute.c (INST_EXPON):	Corrected crash on
+	[expr 2**(1<<63)]. Was operating on cleared bignum Tcl_Obj.
+
+2006-11-16  Donal K. Fellows  <dkf@users.sf.net>
+
+	* doc/apply.n, doc/chan.n: Added examples.
+
+2006-11-15  Don Porter	<dgp@users.sourceforge.net>
+
+	TIP#270 IMPLEMENTATION
+
+	* generic/tcl.decls:		New public routines Tcl_ObjPrintf,
+	* generic/tclStringObj.c:	Tcl_AppendObjToErrorInfo, Tcl_Format,
+	* generic/tclInt.h:		Tcl_AppendLimitedToObj,
+	Tcl_AppendFormatToObj and Tcl_AppendPrintfToObj. Former internal
+	versions removed.
+
+	* generic/tclDecls.h:		make genstubs
+	* generic/tclStubInit.c:
+
+	* generic/tclBasic.c:		Updated callers.
+	* generic/tclCkalloc.c:
+	* generic/tclCmdAH.c:
+	* generic/tclCmdIL.c:
+	* generic/tclCmdMZ.c:
+	* generic/tclCompExpr.c:
+	* generic/tclCompile.c:
+	* generic/tclDictObj.c:
+	* generic/tclExecute.c:
+	* generic/tclIORChan.c:
+	* generic/tclIOUtil.c:
+	* generic/tclMain.c:
+	* generic/tclNamesp.c:
+	* generic/tclObj.c:
+	* generic/tclPkg.c:
+	* generic/tclProc.c:
+	* generic/tclStrToD.c:
+	* generic/tclTimer.c:
+	* generic/tclUtil.c:
+	* unix/tclUnixFCmd.c:
+
+	* tools/genStubs.tcl:	Updated script to no longer produce the
+	_ANSI_ARGS_ wrapper in generated declarations. Also revised to accept
+	variadic prototypes with more than one fixed argument. (This is
+	possible since TCL_VARARGS and its limitations are no longer in use).
+	* generic/tcl.h:	Some reordering so that macro definitions do
+	not interfere with the now _ANSI_ARGS_-less stub declarations.
+
+	* generic/tclDecls.h:		make genstubs
+	* generic/tclIntDecls.h:
+	* generic/tclIntPlatDecls.h:
+	* generic/tclPlatDecls.h:
+	* generic/tclTomMathDecls.h:
+
+2006-11-15  Donal K. Fellows  <dkf@users.sf.net>
+
+	* doc/ChnlStack.3, doc/CrtObjCmd.3, doc/GetIndex.3, doc/OpenTcp.3:
+	* doc/chan.n, doc/fconfigure.n, doc/fcopy.n, doc/foreach.n:
+	* doc/history.n, doc/http.n, doc/library.n, doc/lindex.n:
+	* doc/lrepeat.n, doc/lreverse.n, doc/pkgMkIndex.n, doc/re_syntax.n:
+	Convert \fP to \fR so that man-page scrapers have an easier time.
+
+2006-11-14  Don Porter	<dgp@users.sourceforge.net>
+
+	TIP#261 IMPLEMENTATION
+
+	* generic/tclNamesp.c:	[namespace import] with 0 arguments
+	introspects the list of imported commands.
+
+2006-11-13  Kevin B. Kenny  <kennykb@users.sourceforge.net>
+
+	* generic/tclThreadStorage.c (Tcl_InitThreadStorage):
+	(Tcl_FinalizeThreadStorage): Silence a compiler warning about
+	presenting a volatile pointer to 'memset'.
+
+2006-11-13  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclIO.c:	When [gets] on a binary channel needs to use
+	the "iso8859-1" encoding, save a copy of that encoding per-thread to
+	avoid repeated freeing and re-loading of it from the file system. This
+	replaces the cached copy of this encoding that the platform
+	initialization code used to keep in pre-8.5 releases.
+
+2006-11-13  Daniel Steffen  <das@users.sourceforge.net>
+
+	* generic/tclCompExpr.c:	Fix gcc warnings about 'cast to/from
+	* generic/tclEncoding.c:	pointer from/to integer of different
+	* generic/tclEvent.c:		size' on 64-bit platforms by casting
+	* generic/tclExecute.c:		to intermediate types
+	* generic/tclHash.c:		intptr_t/uintptr_t via new PTR2INT(),
+	* generic/tclIO.c:		INT2PTR(), PTR2UINT() and UINT2PTR()
+	* generic/tclInt.h:		macros. [Patch 1592791]
+	* generic/tclProc.c:
+	* generic/tclTest.c:
+	* generic/tclThreadStorage.c:
+	* generic/tclTimer.c:
+	* generic/tclUtil.c:
+	* unix/configure.in:
+	* unix/tclUnixChan.c:
+	* unix/tclUnixPipe.c:
+	* unix/tclUnixPort.h:
+	* unix/tclUnixTest.c:
+	* unix/tclUnixThrd.c:
+
+	* unix/configure: autoconf-2.59
+	* unix/tclConfig.h.in: autoheader-2.59
+
+2006-11-12  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclInt.h, generic/tclInt.decls: Transfer TclPtrMakeUpvar and
+	TclObjLookupVar to the internal stubs table.
+
+2006-11-10  Daniel Steffen  <das@users.sourceforge.net>
+
+	* tests/fCmd.test (fCmd-6.26): fix failure when env(HOME) path
+	contains symlinks.
+
+	* macosx/Tcl.xcodeproj/project.pbxproj: remove tclParseExpr.c; when
+	running testsuite from inside Xcdoe, skip stack-3.1 (it only fails
+	under those circumstances).
+
+	* unix/tcl.m4 (Darwin): suppress linker arch warnings when building
+	universal for both 32 & 64 bit and no 64bit CoreFoundation is
+	available; sync with tk tcl.m4 change.
+	* unix/configure.in: whitespace.
+	* unix/configure: autoconf-2.59
+
+2006-11-09  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclParseExpr.c (removed):	Moved all the code of
+	* generic/tclCompExpr.c:	tclParseExpr.c into tclCompExpr.c.
+	* unix/Makefile.in:	This sets the stage for expr compiling to work
+	* win/Makefile.in:	directly with the full parse tree structures,
+	* win/makefile.bc:	and not have to pass through the information
+	* win/makefile.vc:	lossy format of an array of Tcl_Tokens.
+	* win/tcl.dsp:
+
+2006-11-09  Donal K. Fellows  <donal.k.fellows@manchester.ac.uk>
+
+	TIP#272 IMPLEMENTATION
+
+	* generic/tclCmdMZ.c (Tcl_StringObjCmd):    Implementation of the
+	* tests/string.test, tests/stringComp.test: [string reverse] command
+	* doc/string.n:				    from TIP#272.
+
+	* generic/tclCmdIL.c (Tcl_LreverseObjCmd): Implementation of the
+	* generic/tclBasic.c, generic/tclInt.h:	   [lreverse] command from
+	* tests/cmdIL.test (cmdIL-7.*):		   TIP#272.
+	* doc/lreverse.n:
+
+2006-11-08  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclIO.c, generic/tclPkg.c: Style & clarity rewrites.
+
+2006-11-07  Andreas Kupries  <andreask@activestate.com>
+
+	* unix/tclUnixFCmd.c (CopyFile): Added code to fall back to a
+	hardwired default block size should the filesystem report a bogus
+	value. [Bug 1586470]
+
+2006-11-04  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclStringObj.c:	Changed Tcl_ObjPrintf() response to an
+	invalid format specifier string. No longer panics; now produces an
+	error message as output.
+
+	TIP#274 IMPLEMENTATION
+
+	* generic/tclParseExpr.c:	Exponentiation operator is now right
+	* tests/expr.test:		associative. [Patch 1556802]
+
+2006-11-03  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclBasic.c (TEOVI): fix por possible leak of a Command in
+	the presence of execution traces that delete it.
+
+	* generic/tclBasic.c (TEOVI):
+	* tests/trace.test (trace-21.11): fix for [Bug 1590232], execution
+	traces may cause a second command resolution in the wrong namespace.
+
+2006-11-03  Donal K. Fellows  <donal.k.fellows@manchester.ac.uk>
+
+	* tests/event.test (event-11.5):	Rewrote tests to stop Tcl from
+	* tests/io.test (multiple tests):	opening sockets that are
+	* tests/ioCmd.test (iocmd-15.1,16,17):	reachable from outside hosts
+	* tests/iogt.test (__echo_srv__.tcl):	where not necessary. This is
+	* tests/socket.test (multiple tests):	noticably annoying on some
+	* tests/unixInit.test (unixInit-1.2):	systems (e.g., Windows).
+
+2006-11-02  Daniel Steffen  <das@users.sourceforge.net>
+
+	* macosx/Tcl.xcodeproj/project.pbxproj: check autoconf/autoheader exit
+	status and stop build if they fail.
+
+2006-11-02  Jeff Hobbs	<jeffh@ActiveState.com>
+
+	* doc/ParseCmd.3, doc/Tcl.n, doc/eval.n, doc/exec.n:
+	* doc/fconfigure.n, doc/interp.n, doc/unknown.n:
+	* library/auto.tcl, library/init.tcl, library/package.tcl:
+	* library/safe.tcl, library/tm.tcl, library/msgcat/msgcat.tcl:
+	* tests/all.tcl, tests/basic.test, tests/cmdInfo.test:
+	* tests/compile.test, tests/encoding.test, tests/execute.test:
+	* tests/fCmd.test, tests/http.test, tests/init.test:
+	* tests/interp.test, tests/io.test, tests/ioUtil.test:
+	* tests/iogt.test, tests/namespace-old.test, tests/namespace.test:
+	* tests/parse.test, tests/pkg.test, tests/pkgMkIndex.test:
+	* tests/proc.test, tests/reg.test, tests/trace.test:
+	* tests/upvar.test, tests/winConsole.test, tests/winFCmd.test:
+	* tools/tclZIC.tcl:
+	* generic/tclParse.c (Tcl_ParseCommand): Replace {expand} with {*}
+	officially (TIP #293). Leave -DALLOW_EXPAND=0|1 option to keep
+	{expand} syntax for transition users. [Bug 1589629]
+
+2006-11-02  Donal K. Fellows  <donal.k.fellows@manchester.ac.uk>
+
+	* generic/tclBasic.c, generic/tclInterp.c, generic/tclProc.c: Silence
+	warnings from gcc over signed/unsigned and TclStackAlloc().
+	* generic/tclCmdMZ.c: Update to more compact and clearer coding style.
+
+2006-11-02  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclCmdAH.c:	Further revisions to produce the routines
+	* generic/tclInt.h:	TclFormat() and TclAppendFormatToObj() that
+	* generic/tclNamesp.c:	accept (objc, objv) arguments rather than
+	* generic/tclStringObj.c:	any varargs stuff.
+
+	* generic/tclBasic.c:	Further revised TclAppendPrintToObj() and
+	* generic/tclCkalloc.c: TclObjPrintf() routines to panic when unable
+	* generic/tclCmdAH.c:	to complete their formatting operations,
+	* generic/tclCmdIL.c:	rather than report an error message. This
+	* generic/tclCmdMZ.c:	means an interp argument for error message
+	* generic/tclDictObj.c: recording is no longer needed, further
+	* generic/tclExecute.c: simplifying the interface for callers.
+	* generic/tclIORChan.c:
+	* generic/tclIOUtil.c:
+	* generic/tclInt.h:
+	* generic/tclMain.c:
+	* generic/tclNamesp.c:
+	* generic/tclParseExpr.c:
+	* generic/tclPkg.c:
+	* generic/tclProc.c:
+	* generic/tclStringObj.c:
+	* generic/tclTimer.c:
+	* generic/tclUtil.c:
+	* unix/tclUnixFCmd.c:
+
+2006-11-02  Donal K. Fellows  <donal.k.fellows@manchester.ac.uk>
+
+	* tests/winPipe.test (winpipe-4.[2345]): Made robust when run in
+	directory with spaces in its name.
+
+	* generic/tclCmdAH.c: Clean up uses of cast NULLs.
+
+	* generic/tclInterp.c (AliasObjCmd): Added more explanatory comments.
+
+	* generic/tclBasic.c (TclEvalObjvInternal): Rewrote so that comments
+	are relevant and informative once more. Also made the unknown handler
+	processing use the Tcl execution stack for working space, and not the
+	general heap.
+
+2006-11-01  Daniel Steffen  <das@users.sourceforge.net>
+
+	* unix/tclUnixPort.h: ensure MODULE_SCOPE is defined before use, so
+	that tclPort.h can once again be included without tclInt.h.
+
+	* generic/tclEnv.c (Darwin): mark _environ symbol as unexported even
+	when MODULE_SCOPE != __private_extern__.
+
+2006-10-31  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclBasic.c:	Refactored and renamed the routines
+	* generic/tclCkalloc.c: TclObjPrintf, TclFormatObj, and
+	* generic/tclCmdAH.c:	TclFormatToErrorInfo to a new set of routines
+	* generic/tclCmdIL.c:	TclAppendPrintfToObj, TclAppendFormatToObj,
+	* generic/tclCmdMZ.c:	TclObjPrintf, and TclObjFormat, with the
+	* generic/tclDictObj.c: intent of making the latter list, plus
+	* generic/tclExecute.c: TclAppendLimitedToObj and
+	* generic/tclIORChan.c: TclAppendObjToErrorInfo, public via a revised
+	* generic/tclIOUtil.c:	TIP 270.
+	* generic/tclInt.h:
+	* generic/tclMain.c:
+	* generic/tclNamesp.c:
+	* generic/tclParseExpr.c:
+	* generic/tclPkg.c:
+	* generic/tclProc.c:
+	* generic/tclStringObj.c:
+	* generic/tclTimer.c:
+	* generic/tclUtil.c:
+	* unix/tclUnixFCmd.c:
+
+2006-10-31  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclBasic.c, generic/tcl.h, generic/tclInterp.c:
+	* generic/tclNamesp.c: removing the flag bit TCL_EVAL_NOREWRITE, the
+	last remnant of the callObjc/v fiasco. It is not needed, as it is now
+	always set and checked or'ed with TCL_EVAL_INVOKE.
+
+2006-10-31  Pat Thoyts	<patthoyts@users.sourceforge.net>
+
+	* win/rules.vc: Fix for [Bug 1582769] - options conflict with VC2003.
+
+2006-10-31  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclBasic.c, generic/tclNamesp.c, generic/tclProc.c:
+	* generic/tclInt.h: Removed the callObjc and callObjv fields from the
+	Interp structure. They did not function correctly and made other parts
+	of the core amazingly complex, resulting in a substantive change to
+	[info level] behaviour. [Bug 1587618]
+	* library/clock.tcl: Removed use of [info level 0] for calculating the
+	command name as used by the user and replace with a literal. What's
+	there now is sucky, but at least appears to be right to most users.
+	* tests/namespace.test (namespace-42.7,namespace-47.1): Reverted
+	changes to these tests.
+	* tests/info.test (info-9.11,info-9.12): Added knownBug constraint
+	since these tests require a different behaviour of [info level] than
+	is possible because of other dependencies.
+
+2006-10-30  Jeff Hobbs	<jeffh@ActiveState.com>
+
+	* tools/tcltk-man2html.tcl (option-toc): handle any kind of options
+	defined toc section (needed for ttk docs)
+
+2006-10-30  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclBasic.c (TEOVI): insured that the interp's callObjc/v
+	fields are restored after traces run, as they be spoiled. This was
+	causing a segfault in tcllib's profiler tests.
+
+2006-10-30  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclExecute.c (INST_MOD): Corrected improper testing of the
+	* tests/expr.test:		   sign of bignums when applying Tcl's
+	division rules. Thanks to Peter Spjuth. [Bug 1585704]
+
+2006-10-29  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclNamesp.c (EnsembleImplementationCmd):
+	* tests/namespace.test (47.7-8): reverted a wrong "optimisation" that
+	completely broke snit; added two tests.
+
+2006-10-28  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclProc.c (ObjInterpProcEx, TclObjInterpProcCore): Split the
+	core of procedures to make it easier to build procedure-like code
+	without going through horrible contortions. This is the last critical
+	component to make advanced OO systems workable as simple loadable
+	extensions. TOIPC is now in the internal stub table.
+	(MakeProcError, MakeLambdaError): Refactored ProcessProcResultCode to
+	be simpler, some of which goes to TclObjInterpProcCore, and the rest
+	of which is now in these far simpler routines which just do errorInfo
+	stack generation for different types of procedure-like entity.
+	* tests/apply.test (apply-5.1): Updated to expect the more informative
+	form of message.
+
+2006-10-27  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclVar.c (HasLocalVars): New macro to make various bits and
+	pieces cleaner.
+
+	* generic/tclNamesp.c (TclSetNsPath): Expose SetNsPath() through
+	internal stubs table with semi-external name.
+
+	* generic/tclInt.h (CallFrame): Add a field for handling context data
+	for extensions (like object systems) that should be tied to a call
+	frame (and not a command or interpreter).
+
+	* generic/tclBasic.c (TclRenameCommand): Change to take CONST args;
+	they were only ever used in a constant way anyway, so this appears to
+	be a spot that was missed during TIP#27 work.
+
+2006-10-26  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclProc.c (SetLambdaFromAny): minor change, eliminate
+	redundant call to Tcl_GetString (thanks aku).
+
+	* generic/tclInterp.c (ApplyObjCmd):
+	* generic/tclNamesp.c (EnsembleImplementationCmd): replaced ckalloc
+	(heap) with TclStackAlloc (execution stack).
+
+2006-10-24  Miguel Sofer  <msofer@users.sf.net>
+
+	* tests/info.test (info-9.11-12): tests for [Bug 1577492]
+	* tests/apply.test (apply-4.3-5): tests for [Bug 1574835]
+
+	* generic/tclProc.c (ObjInterpProcEx): disable itcl hacks for calls
+	from ApplyObjCmd (islambda==1), as they mess apply's error messages
+	[Bug 1583266]
+
+2006-10-23  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclProc.c (ApplyObjCmd): fix wrong#args for apply by using
+	the ensemble rewrite engine. [Bug 1574835]
+	* generic/tclInterp.c (AliasObjCmd): previous commit missed usage of
+	TCL_EVAL_NOREWRITE for aliases.
+
+	* generic/tclBasic.c (TclEvalObjvInternal): removed redundant check
+	for ensembles. [Bug 1577628]
+
+	* library/clock.tcl (format, scan): corrected wrong # args messages to
+	* tests/clock.test (3.1, 34.1):	    make use of the new rewrite
+	capabilities of [info level]
+
+	* generic/tcl.h:	   Lets TEOV update the iPtr->callObj[cv] new
+	* generic/tclBasic.c:	   fields, except when the flag bit
+	* generic/tclInt.h:	   TCL_EVAL_NOREWRITE is present. These values
+	* generic/tclNamesp.c:	   are used by Tcl_PushCallFrame to initialise
+	* generic/tclProc.c:	   the frame's obj[cv] fields, and allows
+	* tests/namespace.test:	   [info level] to know and use ensemble
+	rewrites. [Bug 1577492]
+
+	***POTENTIAL INCOMPATIBILITY***
+	The return value from [info level 0] on interp alias calls is changed:
+	previously returned the target command (including curried values), now
+	returns the source - what was actually called.
+
+2006-10-23  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tcl.h:	   Modified the Tcl call stack so there is
+	* generic/tclBasic.c:	   always a valid CallFrame, even at level 0
+	* generic/tclCmdIL.c:	   [Patch 1577278]. Most of the changes
+	* generic/tclInt.h:	   involve removing tests for a NULL
+	* generic/tclNamesp.c:	   iPtr->(var)framePtr. There is now a
+	* generic/tclObj.c:	   CallFrame pushed at interp creation with a
+	* generic/tclProc.c:	   pointer to it stored in iPtr->rootFramePtr.
+	* generic/tclTrace.c:	   A second unused field in Interp is
+	* generic/tclVar.c:	   hijacked to enable further functionality,
+	currently unused (but with several FRQs depending on it).
+
+	***POTENTIAL INCOMPATIBILITY***
+	Any user that includes tclInt.h and needs to determine if it is
+	running at level 0 should change (iPtr->varFramePtr == NULL) to
+	(iPtr->varFramePtr == iPtr->rootFramePtr).
+
+2006-10-23  Don Porter	<dgp@users.sourceforge.net>
+
+	* README:		Bump version number to 8.5a6
+	* generic/tcl.h:
+	* tools/tcl.wse.in:
+	* unix/configure.in:
+	* unix/tcl.spec:
+	* win/README.binary:
+	* win/configure.in:
+
+	* unix/configure:	autoconf-2.59
+	* win/configure:
+
+2006-10-21  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tcl.h, generic/tclHash.c: Tcl_FindHashEntry now calls
+	Tcl_CreateHashEntry with a newPtr set to NULL: this would have caused
+	a segfault previously and eliminates duplicated code. A macro has been
+	added to tcl.h (only used when TCL_PRESERVE_BINARY_COMPATABALITY is
+	not set - i.e., not by default).
+
+2006-10-20  Reinhard Max  <max@tclers.tk>
+
+	* unix/configure.in: Added autodetection for OS-supplied timezone
+	* unix/Makefile.in:  files and configure switches to override the
+	* unix/configure:    detected default.
+
+2006-10-20  Daniel Steffen  <das@users.sourceforge.net>
+
+	*** 8.5a5 TAGGED FOR RELEASE ***
+
+	* tools/tcltk-man2html.tcl: add support for alpha & beta versions to
+	useversion glob pattern. [Bug 1579941]
+
+2006-10-18  Don Porter	<dgp@users.sourceforge.net>
+
+	* changes:		8.5a5 release date set
+
+	* doc/Encoding.3:	Missing doc updates (mostly Table of
+	* doc/Ensemble.3:	Contents) exposed by `make checkdoc`
+	* doc/FileSystem.3:
+	* doc/GetTime.3:
+	* doc/PkgRequire.3:
+
+2006-10-17  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclInterp.c (ApplyObjCmd): fixed bad error in 2006-10-12
+	commit: interp released too early. Spotted by mistachkin.
+
+2006-10-16  Miguel Sofer  <msofer@users.sf.net>
+
+	* tclProc.c (SetLambdaFromAny):
+	* tests/apply.test (9.1-9.2): plugged intrep leak [Bug 1578454],
+	found by mjanssen.
+
+2006-10-16  Andreas Kupries  <andreask@activestate.com>
+
+	* generic/tclBasic.c: Moved TIP#219 cleanup to DeleteInterpProc.
+
+2006-10-16  Daniel Steffen  <das@users.sourceforge.net>
+
+	* changes: updates for 8.5a5 release.
+
+	* unix/tclUnixThrd.c (TclpThreadGetStackSize): Darwin: fix for main
+	thread, where pthread_get_stacksize_np() returns incorrect info.
+
+	* macosx/GNUmakefile: don't redo prebinding of non-prebound binaires.
+
+2006-10-16  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclPkg.c (ExactRequirement):	Plugged memory leak. Also
+	changed Tcl_Alloc()/Tcl_Free() calls to ckalloc()/ckfree() for easier
+	memory debugging in the future. [Bug 1568373]
+
+	* library/tcltest/tcltest.tcl:	Revise tcltest bump to 2.3a1.
+	* library/tcltest/pkgIndex.tcl: This permits more features to be
+	* unix/Makefile.in:	added to tcltest before we reach version 2.3.0
+	* win/Makefile.in:	best timed to match the release of Tcl 8.5.0.
+	* win/makefile.vc:	This also serves as a demo of TIP 268 features
+
+2006-10-13  Colin McCormack <coldstore@users.sf.net>
+
+	* win/tclWinFile.c: corrected erroneous attempt to protect against
+	NULL return from Tcl_FSGetNormalizedPath per [Bug 1548263] causing
+	[Bug 1575837].
+	* win/tclWinFile.c: alfredd supplied patch to fix [Bug 1575837]
+
+2006-10-13  Daniel Steffen  <das@users.sourceforge.net>
+
+	* unix/tclUnixThrd.c (TclpThreadGetStackSize): on Darwin, use
+	* unix/tcl.m4: pthread_get_stacksize_np() API to get thread stack size
+	* unix/configure: autoconf-2.59
+	* unix/tclConfig.h.in: autoheader-2.59
+
+2006-10-12  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclInterp.c (ApplyObjCmd):
+	* tests/interp.test (interp-14.5-10): made [interp alias] use the
+	ensemble rewrite machinery to produce better error messages [Bug
+	1576006]
+
+2006-10-12  David Gravereaux <davygrvy@pobox.com>
+
+	* win/nmakehlp.c: Replaced all wnsprintf() calls with snprintf().
+	wnsprintf was not in my shwlapi header file (VC++6)
+
+2006-10-11  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclPkg.c (Tcl_PackageRequireEx):	Corrected crash when
+	argument version=NULL passed in.
+
+2006-10-10  Don Porter	<dgp@users.sourceforge.net>
+
+	* changes:	Updates for 8.5a5 release.
+
+	* generic/tclNamespace.c (TclTeardownNamespace):  After the
+	commandPathSourceList of a namespace is cleared, set the
+	commandPathSourceList to NULL so we don't try to walk the list a
+	second time, possibly after it is freed. [Bug 1566526]
+	* tests/namespace.test (namespace-51.16):	Added test.
+
+2006-10-09  Miguel Sofer  <msofer@users.sf.net>
+
+	* doc/UpVar.3: brough the docs in accordance to the code. Ever since
+	8.0, Tcl_UpVar(2)? accepts TCL_NAMESPACE_ONLY as a flag value, and
+	var-3.4 tests for proper behaviour. The docs only allowed 0 and
+	TCL_GLOBAL_ONLY. [Bug 1574099]
+
+2006-10-09  Miguel Sofer  <msofer@users.sf.net>
+
+	* tests/*.test: updated all tests to refer explicitly to the global
+	variables ::errorInfo, ::errorCode, ::env and ::tcl_platform: many
+	were relying on the alternative lookup in the global namespace, that
+	feature is tested specifically in namespace and variable tests.
+
+	The modified testfiles are: apply.test, basic.test, case.test,
+	cmdIL.test, cmdMZ.test, compExpr-old.test, error.test, eval.test,
+	event.test, expr.test, fileSystem.test, for.test, http.test, if.test,
+	incr-old.test, incr.test, interp.test, io.test, ioCmd.test, load.test,
+	misc.test, namespace.test, parse.test, parseOld.test, pkg.test,
+	proc-old.test, set.test, switch.test, tcltest.test, thread.test,
+	var.test, while-old.test, while.test.
+
+2006-10-06  Pat Thoyts	<patthoyts@users.sourceforge.net>
+
+	* win/rules.vc: [Bug 1571954] avoid /RTCc flag with MSVC8
+
+2006-10-06  Pat Thoyts	<patthoyts@users.sourceforge.net>
+
+	* doc/binary.n:	       TIP #275: Support unsigned values in binary
+	* generic/tclBinary.c: command. Tests and documentation updated.
+	* tests/binary.test:
+
+2006-10-05  Andreas Kupries  <andreask@activestate.com>
+
+	* library/tm.tcl: Fixed bug in TIP #189 implementation, now allowing
+	'_' in module names.
+
+2006-10-05  Jeff Hobbs	<jeffh@ActiveState.com>
+
+	* library/http/http.tcl (http::geturl): only do geturl url rfc 3986
+	validity checking if $::http::strict is true (default true for 8.5).
+	[Bug 1560506]
+
+	* generic/tcl.h: note limitation on changing Tcl_UniChar size
+	* generic/tclEncoding.c (UtfToUnicodeProc, UnicodeToUtfProc):
+	* tests/encoding.test (encoding-16.1): fix alignment issues in
+	unicode <> utf conversion procs. [Bug 1122671]
+
+2006-10-05  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclVar.c (Tcl_LappendObjCmd):
+	* tests/append.test(4.21-22): fix for longstanding [Bug 1570718],
+	lappending nothing to non-list. Reported by lvirden
+
+2006-10-04  Kevin B. Kenny  <kennykb@acm.org>
+
+	* tzdata/: Olson's tzdata2006m.
+
+2006-10-01  Kevin B. Kenny  <kennykb@acm.org>
+
+	* tests/clock.test (clock-49.2): Removed a locale dependency that
+	caused a spurious failure in the German locale. [Bug 1567956]
+
+2006-10-01  Miguel Sofer  <msofer@users.sf.net>
+
+	* doc/Eval.3 (TclEvalObjv): added note on refCount management for the
+	elements of objv. [Bug 730244]
+
+2006-10-01  Pat Thoyts	<patthoyts@users.sourceforge.net>
+
+	* win/tclWinFile.c: Handle possible missing define.
+
+	* win/tclWinFile.c (TclpUtime): [Bug 1420432] file mtime fails for
+	* tests/cmdAH.test:		directories on windows
+
+	* tests/winFile.test: Handle Msys environment a little differently in
+	getuser function. [Bug 1567956]
+
+2006-09-30  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclUtil.c (Tcl_SplitList): optimisation, [Patch 1344747] by
+	dgp.
+
+	* generic/tclInt.decls:
+	* generic/tclInt.h:
+	* generic/tclIntDecls.h:
+	* generic/tclObj.c:
+	* generic/tclStubInit.c: added an internal function TclObjBeingDeleted
+	to provide info as to the reason for the loss of an internal rep. [FR
+	1512138]
+
+	* generic/tclCompile.c:
+	* generic/tclHistory.c:
+	* generic/tclInt.h:
+	* generic/tclProc.c: made Tcl_RecordAndEvalObj not call "history" if
+	it has been redefined to an empty proc, in order to reduce the noise
+	when debugging [FR 1190441]. Moved TclCompileNoOp from tclProc.c to
+	tclCompile.c
+
+2006-09-28  Andreas Kupries  <andreask@activestate.com>
+
+	* generic/tclPkg.c (CompareVersions): Bugfix. Check string lengths
+	* tests/pkg.test: before comparison. The shorter string is the smaller
+	number. Added testcases as well. Interestingly all existing test cases
+	for vcompare compared numbers of the same length with each other. [Bug
+	1563836]
+
+2006-09-28  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclIO.c (Tcl_GetsObj): added two test'n'panic guards for
+	possible NULL derefs, [Bug 1566382] and coverity #33.
+
+2006-09-27  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclExecute.c: Corrected error in INST_LSHIFT in the
+	* tests/expr.test:	calculation done to determine whether a shift
+	in the (long int) type is possible. The calculation had literal value
+	"1" where it needed a value "1L" to compute the correct result. Error
+	detected via testing with the math::bigfloat package [Bug 1567222]
+
+	* generic/tclPkg.c (CompareVersion):	Flatten strcmp() results to
+	{-1, 0, 1} to match expectations of CompareVersion() callers.
+
+2006-09-27  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/regc_color.c (singleton):
+	* generic/regc_cvec.c (addmcce):
+	* generic/regcomp.c (compile, dovec): the static function addmcce does
+	nothing when called with two NULL pointers; the only call is by
+	compile with two NULL pointers (regcomp.c #includes regc_cvec.c).
+	Large parts (all?) the code for mcce (multi character collating
+	element) that we do not use is ifdef'ed out with the macro
+	REGEXP_MCCE_ENABLE.
+	This silences coverity bugs 7, 16, 80
+
+	* generic/regc_color.c (uncolorchain):
+	* generic/regc_nfa.c (freearc): changed tests and asserts to
+	equivalent formulation, designed to avoid an explicit comparison to
+	NULL and satisfy coverity that 6 and 9 are not bugs.
+
+2006-09-27  Andreas Kupries  <andreask@activestate.com>
+
+	* tests/pkg.test: Added test for version comparison at the 32bit
+	boundary. [Bug 1563836]
+
+	* generic/tclPkg.c: Rewrote CompareVersion to perform string
+	comparison instead of numeric. This breaks through the 32bit limit on
+	version numbers. See code for details (handling of leading zeros,
+	signs, etc.). un-CONSTed some arguments of CompareVersions,
+	RequirementSatisfied, and AllRequirementsSatisfied. The new compare
+	modifies the string (temporary string terminators). All callers use
+	heap-allocated ver-intreps, so we are good with that. [Bug 1563836]
+
+2006-09-27  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclFileName.c (TclGlob): added a panic for a call with
+	TCL_GLOBMODE_TAILS and pathPrefix==NULL. This would cause a segfault,
+	as found by coverity #26.
+
+2006-09-26  Kevin B. Kenny  <kennykb@acm.org>
+
+	* doc/Encoding.3:	 Added covariant 'const' qualifier for the
+	* generic/tcl.decls:	 Tcl_EncodingType argument to
+	* generic/tclEncoding.c: Tcl_CreateEncoding. [Further TIP#27 work.]
+	* generic/tclDecls.h:	 Reran 'make genstubs'.
+
+2006-09-26  Pat Thoyts	<patthoyts@users.sourceforge.net>
+
+	* win/makefile.vc:  Additional compiler flags and amd64 support.
+	* win/nmakehlp.c:
+	* win/rules.vc:
+
+2006-09-26  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tcl.h:	As 2006-09-22 commit from Donal K. Fellows
+	demonstrates, "#define NULL 0" is just wrong, and as a quotable chat
+	figure observed, "If NULL isn't defined, we're not using a C compiler"
+	Improper fallback definition of NULL removed.
+
+2006-09-25  Pat Thoyts	<patthoyts@users.sourceforge.net>
+
+	* generic/tcl.h:	More fixing which struct stat to refer to.
+	* generic/tclGetDate.y: Some casts from time_t to int required.
+	* generic/tclTimer.c:	Tcl_Time structure members are longs.
+	* win/makefile.vc:	Support for varying compiler options
+	* win/rules.vc:		and build to platform-specific subdirs.
+
+2006-09-25  Andreas Kupries  <andreask@activestate.com>
+
+	* generic/tclIO.c (Tcl_StackChannel): Fixed [Bug 1564642], aka
+	coverity #51. Extended loop condition, added checking for NULL to
+	prevent seg.fault.
+
+2006-09-25  Andreas Kupries  <andreask@activestate.com>
+
+	* doc/package.n: Fixed nits reported by Daniel Steffen in the TIP#268
+	changes.
+
+2006-09-25  Kevin B. Kenny   <kennykb@acm.org>
+
+	* generic/tclNotify.c (Tcl_DeleteEvents): Simplified the code in hopes
+	of making the invariants clearer and proving to Coverity that the
+	event queue memory is managed correctly.
+
+2006-09-25  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclNotify.c (Tcl_DeleteEvents): Make it clear what happens
+	when the event queue is mismanaged. [Bug 1564677], coverity bug #10.
+
+2006-09-24  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclParse.c (Tcl_ParseCommand): also return an error if
+	start==NULL and numBytes<0. This is coverity's bug #20
+
+	* generic/tclStringObj.c (STRING_SIZE): fix allocation for 0-length
+	strings. This is coverity's bugs #54-5
+
+2006-09-22  Andreas Kupries  <andreask@activestate.com>
+
+	* generic/tclInt.h: Moved TIP#268's field 'packagePrefer' to the end
+	of the structure, for better backward compatibility.
+
+2006-09-22  Andreas Kupries  <andreask@activestate.com>
+
+	TIP#268 IMPLEMENTATION
+
+	* generic/tclDecls.h:	 Regenerated from tcl.decls.
+	* generic/tclStubInit.c:
+
+	* doc/PkgRequire.3: Documentation of extended API, extended testsuite.
+	* doc/package.n:
+	* tests/pkg.test:
+
+	* generic/tcl.decls: Implementation.
+	* generic/tclBasic.c:
+	* generic/tclConfig.c:
+	* generic/tclInt.h:
+	* generic/tclPkg.c:
+	* generic/tclTest.c:
+	* generic/tclTomMathInterface.c:
+	* library/init.tcl:
+	* library/package.tcl:
+	* library/tm.tcl:
+
+2006-09-22  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* generic/tclThreadTest.c (TclCreateThread): Use NULL instead of 0 as
+	end-of-strings marker to Tcl_AppendResult; the difference matters on
+	64-bit machines. [Bug 1562528]
+
+2006-09-21  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclUtil.c:	Dropped ParseInteger() routine. TclParseNumber
+	covers the task just fine.
+
+2006-09-19  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclEvent.c (Tcl_VwaitObjCmd): Rewrite so that an exceeded
+	limit trapped in a vwait cannot cause a dangerous dangling trace.
+
+2006-09-19  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclExecute.c (INST_EXPON):	Native type overflow detection
+	* tests/expr.test:	was completely broken. Falling back on use of
+	bignums for all non-trivial ** calculations until
+	native-type-constrained special cases can be done carefully and
+	correctly. [Bug 1561260]
+
+2006-09-15  Jeff Hobbs	<jeffh@ActiveState.com>
+
+	* library/http/http.tcl:      Change " " -> "+" url encoding mapping
+	* library/http/pkgIndex.tcl:  to " " -> "%20" as per RFC 3986.
+	* tests/http.test (http-5.1): bump http to 2.5.3
+	* unix/Makefile.in:
+	* win/Makefile.in:
+
+2006-09-12  Andreas Kupries  <andreask@activestate.com>
+
+	* unix/configure.in (HAVE_MTSAFE_GETHOST*): Modified to recognize
+	HP-UX 11.00 and beyond as having mt-safe implementations of the
+	gethost functions.
+	* unix/configure: Regenerated, using autoconf 2.59
+
+	* unix/tclUnixCompat.c (PadBuffer): Fixed bug in calculation of the
+	increment needed to align the pointer, and added documentation
+	explaining why the macro is implemented as it is.
+
+2006-09-11  Pat Thoyts	<patthoyts@users.sourceforge.net>
+
+	* win/rules.vc:	   Updated to install http, tcltest and msgcat as
+	* win/makefile.vc: Tcl Modules (as per Makefile.in).
+	* win/makefile.vc: Added tommath_(super)class headers.
+
+2006-09-11  Andreas Kupries  <andreask@activestate.com>
+
+	* unix/Makefile.in (install-libraries): Fixed typo tcltest 2.3.9 ->
+	2.3.0.
+
+2006-09-11  Daniel Steffen  <das@users.sourceforge.net>
+
+	* unix/tclUnixCompat.c: make compatLock static and only declare it
+	when it will actually be used; #ifdef parts of TSD that are not always
+	needed; adjust #ifdefs to cover all possible cases; fix whitespace.
+
+2006-09-11  Andreas Kupries  <andreask@activestate.com>
+
+	* tests/msgcat.test: Bumped version in auxiliary files as well.
+	* doc/msgcat.n:
+
+2006-09-11  Kevin B. Kenny  <kennykb@acm.org>
+
+	* unix/Makefile.in:	Bumped msgcat version to 1.4.2 to be
+	* win/Makefile.in:	consistent with dgp's commits of 2006-09-10.
+
+2006-09-11  Don Porter	<dgp@users.sourceforge.net>
+
+	* library/msgcat/msgcat.tcl:	Removed some unneeded [uplevel]s.
+
+2006-09-10  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclExecute.c:		Corrected INST_EXPON flaw that treated
+	* tests/expr.test:		$x**1 as $x**3. [Bug 1555371]
+
+	* doc/tcltest.n:		Bump to version tcltest 2.3.0 to
+	* library/tcltest/pkgIndex.tcl: account for new "-verbose line"
+	* library/tcltest/tcltest.tcl:	feature.
+	* unix/Makefile.in:
+	* win/Makefile.in:
+	* win/makefile.bc:
+	* win/makefile.vc:
+
+	* library/msgcat/msgcat.tcl:	Bump to version msgcat 1.4.2 to
+	* library/msgcat/pkgIndex.tcl:	account for modifications.
+
+2006-09-10  Daniel Steffen  <das@users.sourceforge.net>
+
+	* library/msgcat/msgcat.tcl (msgcat::Init): on Darwin, add fallback of
+	* tests/msgcat.test:			    default msgcat locale to
+	* unix/tclUnixInit.c (TclpSetVariables):    current CFLocale
+	identifier if available (via private ::tcl::mac::locale global, set at
+	interp init when on Mac OS X 10.3 or later with CoreFoundation).
+
+	* library/tcltest/tcltest.tcl: add 'line' verbose level: prints source
+	* doc/tcltest.n:	       file line information of failing tests.
+
+	* macosx/Tcl.xcodeproj/project.pbxproj: add new tclUnixCompat.c file;
+	revise tests target to use new tcltest 'line' verbose level.
+
+	* unix/configure.in: add descriptions to new AC_DEFINEs for MT-safe.
+	* unix/tcl.m4: add caching to new SC_TCL_* macros for MT-safe wrappers
+	* unix/configure: autoconf-2.59
+	* unix/tclConfig.h.in: autoheader-2.59
+
+2006-09-08  Zoran Vasiljevic <vasiljevic@users.sourceforge.net>
+
+	* unix/tclUnixCompat.c: Added fallback to gethostbyname() and
+	gethostbyaddr() if the implementation is known to be MT-safe
+	(currently for Darwin 6 or later only).
+
+	* unix/configure.in: Assume gethostbyname() and gethostbyaddr() are
+	MT-safe starting with Darwin 6 (Mac OSX 10.2).
+
+	* unix/configure: Regenerated with autoconf V2.59
+
+2006-09-08  Andreas Kupries  <andreask@activestate.com>
+
+	* unix/tclUnixCompat.c: Fixed conditions for CopyArray/CopyString, and
+	CopyHostent. Also fixed bad var names in TclpGetHostByName.
+
+2006-09-07  Zoran Vasiljevic <vasiljevic@users.sourceforge.net>
+
+	* unix/tclUnixCompat.c: Added fallback to MT-unsafe library calls if
+	TCL_THREADS is not defined.
+	Fixed alignment of arrays copied by CopyArray() to be on the
+	sizeof(char *) boundary.
+
+2006-09-07  Zoran Vasiljevic <vasiljevic@users.sourceforge.net>
+
+	* unix/tclUnixChan.c:	Rewritten MT-safe wrappers to return ptrs to
+	* unix/tclUnixCompat.c: TSD storage making them all look like their
+	* unix/tclUnixFCmd.c:	MT-unsafe pendants API-wise.
+	* unix/tclUnixPort.h:
+	* unix/tclUnixSock.c:
+
+2006-09-06  Zoran Vasiljevic <vasiljevic@users.sourceforge.net>
+
+	* unix/tclUnixChan.c: Added TCL_THREADS ifdef'ed usage of MT-safe
+	* unix/tclUnixFCmd.c: calls like: getpwuid, getpwnam, getgrgid,
+	* unix/tclUnixSock.c: getgrnam, gethostbyname and gethostbyaddr.
+	* unix/tclUnixPort.h: See [Bug 999544]
+	* unix/Makefile.in:
+	* unix/configure.in:
+	* unix/tcl.m4:
+	* unix/configure: Regenerated.
+
+	* unix/tclUnixCompat.c: New file containing MT-safe implementation of
+	some library calls.
+
+2006-09-04  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclCompExpr.c:	Removed much complexity that is no
+	longer needed.
+
+	* tests/main.text (Tcl_Main-4.4):	Test corrected to not be
+	timing sensitive to the Bug 1481986 fix. [Bug 1550858]
+
+2006-09-04  Jeff Hobbs	<jeffh@ActiveState.com>
+
+	* doc/package.n: correct package example
+
+2006-08-31  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclCompExpr.c:	Corrected flawed logic for disabling
+	the INST_TRY_CVT_TO_NUMERIC instruction at the end of an expression
+	when function arguments contain operators. [Bug 1541274]
+
+	* tests/expr-old.test:	The remaining failing tests reported in
+	* tests/expr.test:	[Bug 1381715] are all new in Tcl 8.5, so
+	there's really no issue of compatibility with Tcl 8.4 result to deal
+	with. Fixed by updating tests to expect 8.5 results.
+
+2006-08-29  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclParseExpr.c:	Dropped the old expr parser.
+
+2006-08-30  Jeff Hobbs	<jeffh@ActiveState.com>
+
+	* generic/tclBasic.c (Tcl_CreateInterp): init iPtr->threadId
+
+	* win/tclWinChan.c [Bug 819667] Improve logic for identifying COM
+	ports.
+
+	* generic/tclIOGT.c (ExecuteCallback):
+	* generic/tclPkg.c (Tcl_PkgRequireEx): replace Tcl_GlobalEval(Obj)
+	with more efficient Tcl_Eval(Obj)Ex
+
+	* unix/Makefile.in (valgrindshell): add valgrindshell target and
+	update default VALGRINDARGS. User can override, or add to it with
+	VALGRIND_OPTS env var.
+
+	* generic/tclFileName.c (DoGlob): match incrs with decrs.
+
+2006-08-29  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclParseExpr.c:	Use the "parent" field of orphan
+	ExprNodes to store the closure of left pointers. This lets us avoid
+	repeated re-scanning leftward for the left boundary of subexpressions,
+	which in worst case led to near O(N^2) runtime.
+
+2006-08-29  Joe Mistachkin  <joe@mistachkin.com>
+
+	* unix/tclUnixInit.c: Fixed the issue (typo) that was causing
+	* unix/tclUnixThrd.c (TclpThreadGetStackSize): stack.test to fail on
+	FreeBSD (and possibly other Unix platforms).
+
+2006-08-29  Colin McCormack  <coldstore@users.sourceforge.net>
+
+	* generic/tclIOUtil.c:	Added test for NULL return from
+	* generic/tclPathObj.c: Tcl_FSGetNormalizedPath which was causing
+	* unix/tclUnixFile.c:	segv's per [Bug 1548263]
+	* win/tclWinFCmd.c:
+	* win/tclWinFile.c:
+
+2006-08-28  Kevin B. Kenny  <kennykb@acm.org>
+
+	* library/tzdata/America/Havana:      Regenerated from Olson's
+	* library/tzdata/America/Tegucigalpa: tzdata2006k.
+	* library/tzdata/Asia/Gaza:
+
+2006-08-28  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclStringObj.c:	Revised ObjPrintfVA to take care to
+	* generic/tclParseExpr.c:	copy only whole characters when doing
+	%s formatting. This relieves callers of TclObjPrintf() and
+	TclFormatToErrorInfo() from needing to fix arguments to character
+	boundaries. Tcl_ParseExpr() simplified by taking advantage. [Bug
+	1547786]
+
+	* generic/tclStringObj.c:	Corrected TclFormatObj's failure to
+	count up the number of arguments required by examining the format
+	string. [Bug 1547681]
+
+2006-08-27  Joe Mistachkin  <joe@mistachkin.com>
+
+	* generic/tclClock.c (ClockClicksObjCmd): Fix nested macro breakage
+	with TCL_MEM_DEBUG enabled. [Bug 1547662]
+
+2006-08-26  Miguel Sofer  <msofer@users.sf.net>
+
+	* doc/namespace.n:
+	* generic/tclNamesp.c:
+	* tests/upvar.test: bugfix, docs clarification and new tests for
+	[namespace upvar] as follow up to [Bug 1546833], reported by Will
+	Duquette.
+
+2006-08-24  Kevin B. Kenny  <kennykb@acm.org>
+
+	* library/tzdata: Regenerated, including several new files, from
+	Olson's tzdata2006j.
+	* library/clock.tcl:
+	* tests/clock.test: Removed an early testing hack that allowed loading
+	'registry' from the build tree rather than an installed one. This is a
+	workaround for [Bug 15232730], which remains open because it's a
+	symptom of a deeper underlying problem.
+
+2006-08-23  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclParseExpr.c:	Minimal collection of new tests
+	* tests/parseExpr.test:		testing the error messages of the new
+	expr parser. Several bug fixes and code simplifications that appeared
+	during that effort.
+
+2006-08-21  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclIOUtil.c:	Revisions to complete the thread finalization
+	of the cwdPathPtr. [Bug 1536142]
+
+	* generic/tclParseExpr.c:	Revised mistaken call to
+	TclCheckBadOctal(), so both [expr 08] and [expr 08z] have same
+	additional info in error message.
+
+	* tests/compExpr-old.test:	Update existing tests to not fail with
+	* tests/compExpr.test:		the new expr parser.
+	* tests/compile.test:
+	* tests/expr-old.test:
+	* tests/expr.test:
+	* tests/for.test:
+	* tests/if.test:
+	* tests/parseExpr.test:
+	* tests/while.test:
+
+2006-08-21  Donal K. Fellows  <donal.k.fellows@manchester.ac.uk>
+
+	* win/Makefile.in (gdb): Make this target work so that debugging an
+	msys build is possible.
+
+2006-08-21  Daniel Steffen  <das@users.sourceforge.net>
+
+	* macosx/tclMacOSXNotify.c (Tcl_WaitForEvent): if the run loop is
+	already running (e.g. if Tcl_WaitForEvent was called recursively),
+	re-run it in a custom run loop mode containing only the source for the
+	notifier thread, otherwise wakeups from other sources added to the
+	common run loop modes might get lost.
+
+	* unix/tclUnixNotfy.c (Tcl_WaitForEvent): on 64-bit Darwin,
+	pthread_cond_timedwait() appears to have a bug that causes it to wait
+	forever when passed an absolute time which has already been exceeded
+	by the system time; as a workaround, when given a very brief timeout,
+	just do a poll on that platform. [Bug 1457797]
+
+	* generic/tclClock.c (ClockClicksObjCmd): add support for Darwin
+	* generic/tclCmdMZ.c (Tcl_TimeObjCmd):	  nanosecond resolution timer
+	* generic/tclInt.h:			  to [clock clicks] and [time]
+	* unix/configure.in (Darwin):		  when TCL_WIDE_CLICKS defined
+	* unix/tclUnixTime.c (TclpGetWideClicks, TclpWideClicksToNanoseconds):
+	* unix/configure: autoconf-2.59
+	* unix/tclConfig.h.in: autoheader-2.59
+
+	* unix/tclUnixPort.h (Darwin): override potentially faulty configure
+	detection of termios availability in all cases, since termios is known
+	to be present on all Mac OS X releases since 10.0. [Bug 497147]
+
+2006-08-18  Daniel Steffen  <das@users.sourceforge.net>
+
+	* unix/tcl.m4 (Darwin): add support for --enable-64bit on x86_64, for
+	universal builds including x86_64, for 64-bit CoreFoundation on
+	Leopard and for use of -mmacosx-version-min instead of
+	MACOSX_DEPLOYMENT_TARGET
+	* unix/configure: autoconf-2.59
+	* unix/tclConfig.h.in: autoheader-2.59
+
+	* generic/tcl.h:	  add fixes for building on Leopard and
+	* unix/tclUnixPort.h:	  support for 64-bit CoreFoundation on Leopard
+	* macosx/tclMacOSXFCmd.c:
+
+	* unix/tclUnixPort.h: on Darwin x86_64, disable use of vfork as it
+	causes execve to fail intermittently. (rdar://4685553)
+
+	* generic/tclTomMath.h: on Darwin 64-bit, for now disable use of
+	128-bit arithmetic through __attribute__ ((mode(TI))), as it leads to
+	link errors due to missing fallbacks. (rdar://4685527)
+
+	* macosx/Tcl.xcodeproj/project.pbxproj: add x86_64 to universal build,
+	switch native release targets to use DWARF with dSYM, Xcode 3.0
+	changes
+	* macosx/README: updates for x86_64 and Xcode 2.4.
+
+	* macosx/Tcl.xcodeproj/default.pbxuser: add test suite target that
+	* macosx/Tcl.xcodeproj/project.pbxproj: runs the tcl test suite at
+	build time and shows clickable test suite errors in the GUI build
+	window.
+
+	* tests/macOSXFCmd.test: fix use of deprecated resource fork paths.
+
+	* unix/tclUnixInit.c (TclpInitLibraryPath): move code that is only
+	needed when TCL_LIBRARY is defined to run only in that case.
+
+	* generic/tclLink.c (LinkTraceProc): fix 64-bit signed-with-unsigned
+	comparison warning from gcc4 -Wextra.
+
+	* unix/tclUnixChan.c (TclUnixWaitForFile): with timeout < 0, if
+	select() returns early (e.g. due to a signal), call it again instead
+	of returning a timeout result. Fixes intermittent event-13.8 failures.
+
+2006-08-17  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclCompile.c:		Revised the new set of expression
+	* generic/tclParseExpr.c:	parse error messages.
+
+2006-08-16  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclParseExpr.c:	Replace PrecedenceOf() function with
+	prec[] static array.
+
+2006-08-14  Donal K. Fellows  <donal.k.fellows@manchester.ac.uk>
+
+	* library/clock.tcl (::tcl::clock::add): Added missing braces to
+	clockval validation code. Pointed out on comp.lang.tcl.
+
+2006-08-11  Donal K. Fellows  <donal.k.fellows@manchester.ac.uk>
+
+	* generic/tclNamesp.c: Improvements in buffer management to make
+	namespace creation faster. Plus selected other minor improvements to
+	code quality. [Patch 1352382]
+
+2006-08-10  Donal K. Fellows  <donal.k.fellows@manchester.ac.uk>
+
+	Misc patches to make code more efficient. [Bug 1530474] (afredd)
+	* generic/*.c, macosx/tclMacOSXNotify.c, unix/tclUnixNotfy.c,
+	* win/tclWinThrd.c: Tidy up invokations of Tcl_Panic() to promote
+	string constant sharing and consistent style.
+	* generic/tclBasic.c (Tcl_CreateInterp): More efficient handling of
+	* generic/tclClock.c (TclClockInit):	 registration of commands not
+						 in global namespace.
+	* generic/tclVar.c (Tcl_UnsetObjCmd): Remove unreachable clause.
+
+2006-08-09  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclEncoding.c:	Replace buffer copy in for loop with
+	call to memcpy(). Thanks to afredd. [Patch 1530262]
+
+2006-08-09  Donal K. Fellows  <donal.k.fellows@manchester.ac.uk>
+
+	* generic/tclCmdIL.c (Tcl_LassignObjCmd): Make the wrong#args message
+	a bit more consistent with those used elsewhere. [Bug 1534628]
+
+	* generic/tclDictObj.c (DictForCmd): Stop crash when attempting to
+	iterate over an invalid dictionary. [Bug 1531184]
+
+	* doc/ParseCmd.3, doc/expr.n, doc/set.n, doc/subst.n, doc/switch.n:
+	* doc/tclvars.n: Ensure that uses of [expr] in documentation examples
+	are also good style (with braces) unless otherwise necessary. [Bug
+	1526581]
+
+2006-08-03  Daniel Steffen  <das@users.sourceforge.net>
+
+	* unix/tclUnixPipe.c (TclpCreateProcess): for USE_VFORK: ensure
+	standard channels are initialized before vfork() so that the child
+	doesn't potentially corrupt global state in the parent's address space
+
+	* tests/compExpr-old.test: add 'oldExprParser' constraint to all tests
+	* tests/compExpr.test:	   that depend on the exact format of the
+	* tests/compile.test:	   error messages of the pre-2006-07-05
+	* tests/expr-old.test:	   expression parser. The constraint is on by
+	* tests/expr.test:	   default (i.e those tests still fail), but
+	* tests/for.test:	   can be turned off by passing '-constraints
+	* tests/if.test:	   newExprParser' to tcltest, which will skip
+	* tests/parseExpr.test:	   the 196 failing tests in the testsuite that
+	* tests/while.test:	   are caused by the new expression parser
+	error messages.
+
+2006-07-31  Kevin B. Kenny  <kennykb@acm.org>
+
+	* generic/tclClock.c (ConvertLocalToUTCUsingC): Corrected a regression
+	that caused dates before 1969 to be one day off in the :localtime time
+	zone if TZ is not set. [Bug 1531530]
+
+2006-07-30  Kevin B. Kenny  <kennykb@acm.org>
+
+	* generic/tclClock.c (GetJulianDayFromEraYearMonthDay): Corrected
+	several errors in converting dates before the Common Era [Bug 1426279]
+	* library/clock.tcl: Corrected syntax errors in generated code for %EC
+	%Ey, and %W format groups [Bug 1505383]. Corrected a bug in cache
+	management for format strings containing [glob] metacharacters [Bug
+	1494664]. Corrected several errors in formatting/scanning of years
+	prior to the Common Era, and added the missing %EE format group to
+	indicate the era.
+	* tools/makeTestCases.tcl: Added code to make sure that %U and %V
+	format groups are included in the tests. (The code depends on %U and
+	%V formatting working correctly when 'makeTestCases.tcl' is run,
+	rather than making a completely independent check.) Added tests for
+	[glob] metacharacters in strings. Added tests for years prior to the
+	Common Era.
+	* tests/clock.test: Rebuilt with new test cases for all the above.
+
+2006-07-30  Joe English	 <jenglish@users.sourceforge.net>
+
+	* doc/AppInit.3: Fix typo [Bug 1496886]
+
+2006-07-26  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclExecute.c: Corrected flawed overflow detection in
+	* tests/expr.test:	INST_EXPON that caused [expr 2**64] to return
+	0 instead of the same value as [expr 1<<64].
+
+2006-07-24  Don Porter	<dgp@users.sourceforge.net>
+
+	* win/tclWinSock.c:	Correct un-initialized Tcl_DString. Thanks to
+	afredd. [Bug 1518166]
+
+2006-07-21  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclExecute.c:
+	* tests/execute.test (execute-9.1): dgp's fix for [Bug 1522803].
+
+2006-07-20  Daniel Steffen  <das@users.sourceforge.net>
+
+	* macosx/tclMacOSXNotify.c (Tcl_InitNotifier, Tcl_WaitForEvent):
+	create notifier thread lazily upon first call to Tcl_WaitForEvent()
+	rather than in Tcl_InitNotifier(). Allows calling exeve() in processes
+	where the event loop has not yet been run (Darwin's execve() fails in
+	processes with more than one thread), in particular allows embedders
+	to call fork() followed by execve(), previously the pthread_atfork()
+	child handler's call to Tcl_InitNotifier() would immediately recreate
+	the notifier thread in the child after a fork.
+
+	* macosx/tclMacOSXFCmd.c (TclMacOSXCopyFileAttributes):	   add support
+	* macosx/tclMacOSXNotify.c (Tcl_InitNotifier):		   for weakly
+	* unix/tclUnixInit.c (Tcl_GetEncodingNameFromEnvironment): importing
+	symbols not available on OSX 10.2 or 10.3, enables binaires built on
+	later OSX versions to run on earlier ones.
+	* macosx/Tcl.xcodeproj/project.pbxproj: enable weak-linking; turn on
+						extra warnings.
+	* macosx/README: document how to enable weak-linking; cleanup.
+	* unix/tclUnixPort.h: add support for weak-linking; conditionalize
+	AvailabilityMacros.h inclusion; only disable realpath on 10.2 or
+	earlier when threads are enabled.
+	* unix/tclLoadDyld.c (TclpLoadMemoryGetBuffer): change runtime Darwin
+	* unix/tclUnixInit.c (TclpInitPlatform):	release check to use
+							global initialized
+							once
+	* unix/tclUnixFCmd.c (DoRenameFile, TclpObjNormalizePath): add runtime
+	Darwin release check to determine if realpath is threadsafe.
+	* unix/configure.in: add check on Darwin for compiler support of weak
+	* unix/tcl.m4:	     import and for AvailabilityMacros.h header; move
+	Darwin specific checks & defines that are only relevant to the tcl
+	build out of tcl.m4; restrict framework option to Darwin; clean up
+	quoting and help messages.
+	* unix/configure: autoconf-2.59
+	* unix/tclConfig.h.in: autoheader-2.59
+
+	* generic/regc_locale.c (cclass):
+	* generic/tclExecute.c (TclExecuteByteCode):
+	* generic/tclIOCmd.c (Tcl_ExecObjCmd):
+	* generic/tclListObj.c (NewListIntRep):
+	* generic/tclObj.c (Tcl_GetLongFromObj, Tcl_GetWideIntFromObj)
+	(FreeBignum, Tcl_SetBignumObj):
+	* generic/tclParseExpr.c (Tcl_ParseExpr):
+	* generic/tclStrToD.c (TclParseNumber):
+	* generic/tclStringObj.c (TclAppendFormattedObjs):
+	* unix/tclLoadDyld.c (TclpLoadMemory):
+	* unix/tclUnixPipe.c (TclpCreateProcess): fix signed-with-unsigned
+	comparison and other warnings from gcc4 -Wextra.
+
+2006-07-13  Andreas Kupries <andreask@activestate.com>
+
+	* unix/tclUnixPort.h: Added the inclusion of <AvailabilityMacros.h>.
+	The missing header caused the upcoming #if conditions to wrongly
+	exclude realpath, causing file normalize to ignore symbolic links in
+	the path.
+
+2006-07-11  Zoran Vasiljevic <vasiljevic@users.sourceforge.net>
+
+	* generic/tclAsync.c: Made Tcl_AsyncDelete() more tolerant when called
+	after all thread TSD has been garbage-collected.
+
+2006-07-05  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclParseExpr.c:	Completely new expression parser that
+	builds a parse tree instead of operating with deep recursion. This
+	corrects reports of stack-blowing crashes parsing long expressions
+	[Bug 906201] and replaces a fundamentally O(N^2) algorithm with an
+	O(N) one [RFE 903765]. The new parser is better able to generate error
+	messages that clearly report both the nature and context of the syntax
+	error [Bugs 1029267, 1381715]. For now, the code for the old parser is
+	still present and can be activated with a "#define OLD_EXPR_PARSER
+	1". This is for the sake of a clean implementation patch, and for ease
+	of benchmarking. The new parser is non-recursive, so much lighter in
+	stack consumption, but it does use more heap, so there may be cases
+	where parsing of long expressions that succeeded with the old parser
+	will lead to out of memory panics with the new one. There are still
+	more improvements possible on that point, though significant progress
+	may require changes to the Tcl_Token specifications documented for the
+	public Tcl_Parse*() routines.
+	***POTENTIAL INCOMPATIBILITY*** for any callers that rely on the exact
+	(usually terrible) error messages generated by the old parser. This
+	includes a large number of tests in the test suite.
+
+	* generic/tclInt.h:		Replaced TclParseWhiteSpace() with
+	* generic/tclParse.c:		TclParseAllWhiteSpace() which is what
+	* generic/tclParseExpr.c:	all the callers really needed.
+	Breaking whitespace runs at newlines is useful only to the command
+	parsing function, and it can call the file scoped routine
+	ParseWhiteSpace() to do that.
+
+	* tests/expr-old.test:	Removed knownBug constraints that masked
+	* tests/expr.test:	failures due to revised error messages.
+	* tests/parseExpr.test:
+
+2006-06-20  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclIOUtil.c:	Changed default configuration to
+	* generic/tclInt.decls: #undef USE_OBSOLETE_FS_HOOKS which disables
+	* generic/tclTest.c:	access to the Tcl 8.3 internal routines for
+	hooking into filesystem operations. Everyone ought to have migrated to
+	Tcl_Filesystems by now.
+	***POTENTIAL INCOMPATIBILITY*** for any code still stuck in the
+	pre-Tcl_Filesystem era.
+
+	* generic/tclIntDecls.h:	make genstubs
+	* generic/tclStubInit.c:
+
+	* generic/tclStrToD.c:	Removed dead code that permitted disabling of
+	recognition of the new 0b and 0o numeric formats.
+
+	* generic/tclExecute.c: Removed dead code that implemented alternative
+	* generic/tclObj.c:	design where numeric values did not
+	automatically narrow to the smallest Tcl_ObjType required to hold them
+
+	* generic/tclCmdAH.c:	Removed dead code that was old implementation
+	of [format].
+
+2006-06-14  Daniel Steffen  <das@users.sourceforge.net>
+
+	* unix/tclUnixPort.h (Darwin): support MAC_OS_X_VERSION_MAX_ALLOWED
+	define from AvailabilityMacros.h: override configure detection and
+	only use API available in the indicated OS version or earlier.
+
+2006-06-14  Donal K. Fellows  <donal.k.fellows@manchester.ac.uk>
+
+	* doc/format.n, doc/scan.n: Added examples for converting between
+	characters and their numeric interpretations following user prompting.
+
+2006-06-13  Donal K. Fellows  <dkf@users.sf.net>
+
+	* unix/tclLoadDl.c (TclpDlopen): Workaround for a compiler bug in Sun
+	Forte 6. [Bug 1503729]
+
+2006-06-06  Don Porter	<dgp@users.sourceforge.net>
+
+	* doc/GetStdChan.3:	Added recommendation that each call to
+	Tcl_SetStdChannel() be accompanied by a call to Tcl_RegisterChannel().
+
+2006-06-05  Donal K. Fellows  <donal.k.fellows@manchester.ac.uk>
+
+	* doc/Alloc.3: Added documentation of promise that Tcl_Realloc(NULL,x)
+	is the same as Tcl_Alloc(x), as discussed in comp.lang.tcl. Also fixed
+	nonsense sentence to say something meaningful.
+
+2006-05-29  Jeff Hobbs	<jeffh@ActiveState.com>
+
+	* generic/tcl.h (Tcl_DecrRefCount): use if/else construct to allow
+	placement in unbraced outer if/else conditions. (jcw)
+
+2006-05-27  Daniel Steffen  <das@users.sourceforge.net>
+
+	* macosx/tclMacOSXNotify.c: implemented pthread_atfork() handler that
+	* unix/tcl.m4 (Darwin):	    recreates CoreFoundation state and
+	notifier thread in the child after a fork(). Note that pthread_atfork
+	is available starting with Tiger only. Because vfork() is used by the
+	core on Darwin, [exec]/[open] are not affected by this fix, only
+	extensions or embedders that call fork() directly (such as TclX).
+	However, this only makes fork() safe from corefoundation tcl with
+	--disable-threads; as on all platforms, forked children may deadlock
+	in threaded tcl due to the potential for stale locked mutexes in the
+	child. [Patch 923072]
+
+	* unix/configure: autoconf-2.59
+	* unix/tclConfig.h.in: autoheader-2.59
+
+2006-05-24  Donal K. Fellows  <donal.k.fellows@manchester.ac.uk>
+
+	* unix/tcl.m4 (SC_CONFIG_SYSTEM): Fixed quoting of command script to
+	awk; it was a rarely used branch, but it was wrong. [Bug 1494160]
+
+2006-05-23  Donal K. Fellows  <donal.k.fellows@manchester.ac.uk>
+
+	* doc/chan.n, doc/refchan.n: Tighten up the documentation to follow a
+	slightly more consistent style with regard to argument capitalization.
+
+2006-05-13  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclProc.c (ProcCompileProc): When a bump of the compile
+	epoch forces the re-compile of a proc body, take care not to overwrite
+	any Proc struct that may be referred to on the active call stack. Note
+	that the fix will not be effective for code that calls the private
+	routine TclProcCompileProc() directly. [Bug 1482718]
+
+2006-05-13  Daniel Steffen  <das@users.sourceforge.net>
+
+	* generic/tclEvent.c (HandleBgErrors): fix leak. [Coverity issue 86]
+
+2006-05-05  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclMain.c (Tcl_Main):		Corrected flaw that required
+	* tests/main.test: (Tcl_Main-4.5):	processing of one interactive
+	command before passing control to the loop routine registered with
+	Tcl_SetMainLoop(). [Bug 1481986]
+
+2006-05-04  Don Porter	<dgp@users.sourceforge.net>
+
+	* README:		Bump version number to 8.5a5
+	* generic/tcl.h:
+	* tools/tcl.wse.in:
+	* unix/configure.in:
+	* unix/tcl.spec:
+	* win/README.binary:
+	* win/configure.in:
+
+	* unix/configure:	autoconf-2.59
+	* win/configure:
+
+	* generic/tclBasic.c (ExprSrandFunc): Restore acceptance of wide/big
+	* doc/mathfunc.n: integer values by srand(). [Bug 1480509]
+
+2006-04-26  Don Porter	<dgp@users.sourceforge.net>
+
+	*** 8.5a4 TAGGED FOR RELEASE ***
+
+	* changes:	Updates for another RC.
+
+	* generic/tclBinary.c:	Revised the handling of the Q and q format
+	* generic/tclInt.h:	specifiers for [binary] to account for the
+	* generic/tclStrToD.c:	"middle endian" floating point format used in
+	Nokia N770.
+
+2006-04-25  Don Porter	<dgp@users.sourceforge.net>
+
+	* doc/DoubleObj.3:	More doc updates for TIP 237.
+	* doc/expr.n:
+	* doc/format.n:
+	* doc/mathfunc.n:
+	* doc/scan.n:
+	* doc/string.n:
+
+	* generic/tclScan.c:	[scan $s %u] is documented to accept only
+	* tests/scan.test:	decimal formatted integers. Fixed to match.
+
+2006-04-19  Kevin B. Kenny  <kennykb@acm.org>
+
+	* generic/tclStrToD.c: Added code to support the "middle endian"
+	floating point format used in the Nokia N770's software-based floating
+	point. Thanks to Bruce Johnson for reporting this bug, originally on
+	http://wiki.tcl.tk/15408.
+	* library/clock.tcl: Fixed a bug with Daylight Saving Time and Posix
+	time zone specifiers reported by Martin Lemburg in
+	http://groups.google.com/group/comp.lang.tcl/browse_thread/thread/9a8b15a4dfc0b7a0
+	(and not at SourceForge).
+	* tests/clock.test: Added test case for the above bug.
+
+2006-04-18  Donal K. Fellows  <dkf@users.sf.net>
+
+	* doc/IntObj.3: Minor review fixes, including better documentation of
+	the behaviour of Tcl_GetBignumAndClearObj.
+
+2006-04-17  Don Porter	<dgp@users.sourceforge.net>
+
+	* doc/IntObj.3: Documentation changes to account for TIP 237 changes.
+	* doc/Object.3: [Bug 1446971]
+
+2006-04-12  Donal K. Fellows  <donal.k.fellows@manchester.ac.uk>
+
+	* generic/regc_locale.c (cclass): Redefined the meaning of [:print:]
+	to be exactly UNICODE letters, numbers, punctuation, symbols and
+	spaces (*not* whitespace). [Bug 1376892]
+
+2006-04-11  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclTrace.c:	Stop some interference between enter traces
+	* tests/trace.test:	and enterstep traces. [Bug 1458266]
+
+2006-04-07  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclPathObj.c: Yet another revised fix for the [Bug 1379287]
+	* tests/fileSystem.test:	family of path normalization bugs.
+
+2006-04-06  Jeff Hobbs	<jeffh@ActiveState.com>
+
+	* generic/tclRegexp.c (FinalizeRegexp): full reset data to indicate
+	readiness for reinitialization.
+
+2006-04-06  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclIndexObj.c (Tcl_GetIndexFromObjStruct):	It seems there
+	* tests/indexObj.test:	are extensions that rely on the prior behavior
+	* doc/GetIndex.3:	that the empty string cannot succeed as a
+	unique prefix matcher, so I'm restoring Donal Fellows's solution.
+	Added mention of this detail to the documentation. [Bug 1464039]
+
+	* tests/compExpr-old.test:	Updated testmathfunctions constraint
+	* tests/compExpr.test:		to post-TIP-232 world.
+	* tests/expr-old.test:
+	* tests/expr.test:
+	* tests/info.test:
+
+	* tests/indexObj.test:	Corrected other test errors revealed by
+	* tests/upvar.test:	testing outside the tcltest application.
+
+	* generic/tclPathObj.c: Revised fix for the [Bug 1379287] family of
+	path normalization bugs.
+
+2006-04-06  Daniel Steffen  <das@users.sourceforge.net>
+
+	* unix/tcl.m4: removed TCL_IO_TRACK_OS_FOR_DRIVER_WITH_BAD_BLOCKING
+	define on Darwin. [Bug 1457515]
+	* unix/configure: autoconf-2.59
+	* unix/tclConfig.h.in: autoheader-2.59
+
+2006-04-05  Don Porter	<dgp@users.sourceforge.net>
+
+	* win/tclWinInit.c:	More careful calls to Tcl_DStringSetLength()
+	* win/tclWinSock.c:	to avoid creating invalid DString states. Bump
+	* win/tclWinDde.c:	to version 1.3.2. [RFE 1366195]
+	* library/dde/pkgIndex.tcl:
+
+	* library/reg/pkgIndex.tcl:	Bump to registry 1.2 because
+	* win/tclWinReg.c:	Registry_Unload() is a new public routine
+	* win/Makefile.in:	compared to the 1.1.* releases.
+
+	* win/configure.in:	Bump package version numbers.
+	* win/configure:	autoconf 2.59
+
+2006-04-05  Donal K. Fellows  <donal.k.fellows@manchester.ac.uk>
+
+	* generic/tclIndexObj.c (Tcl_GetIndexFromObjStruct): Allow empty
+	strings to be matched by the Tcl_GetIndexFromObj machinery, in the
+	same manner as any other key. [Bug 1464039]
+
+2006-04-03  Andreas Kupries <andreask@activestate.com>
+
+	* generic/tclIO.c (ReadChars): Added check, panic and commentary to a
+	piece of code which relies on BUFFER_PADDING to create enough space at
+	the beginning of each buffer for the insertion of partial multibyte
+	data at the beginning of a buffer. Commentary explains why this code
+	is OK, and the panic is as a precaution if someone twiddled the
+	BUFFER_PADDING into uselessness.
+
+	* generic/tclIO.c (ReadChars): Temporarily suppress the use of
+	TCL_ENCODING_END set when EOF was reached while the buffer we are
+	converting is not truly the last buffer in the queue. Together with
+	the Utf bug below it was possible to completely wreck the buffer data
+	structures, eventually crashing Tcl. [Bug 1462248]
+
+	* generic/tclEncoding.c (UtfToUtfProc): Stop accessing memory beyond
+	the end of the input buffer when TCL_ENCODING_END is set and the last
+	bytes of the buffer start a multi-byte sequence. This bug contributed
+	to [Bug 1462248].
+
+2006-03-30  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclExecute.c: remove unused var and silence gcc warning
+
+2006-03-29  Jeff Hobbs	<jeffh@ActiveState.com>
+
+	* win/Makefile.in: convert _NATIVE paths to use / to avoid ".\"
+	path-as-escape issue.
+
+2006-03-29  Don Porter	<dgp@users.sourceforge.net>
+
+	* changes:	Updates for another RC.
+
+	* generic/tclPathObj.c:	 More fixes for path normalization when /../
+	* tests/fileSystem.test: tries to go beyond root.[Bug 1379287]
+
+	* generic/tclExecute.c: Revised INST_MOD implementation to do
+	calculations in native types as much as possible, moving to mp_ints
+	only when necessary.
+
+2006-03-28  Jeff Hobbs	<jeffh@ActiveState.com>
+
+	* win/tclWinPipe.c (TclpCreateProcess): change panics to Tcl errors
+	and do proper refcounting of noe objPtr. [Bug 1194429]
+
+	* unix/tcl.m4, win/tcl.m4: []-quote AC_DEFUN functions.
+
+2006-03-28  Daniel Steffen  <das@users.sourceforge.net>
+
+	* macosx/Tcl.xcode/default.pbxuser:	add '-singleproc 1' cli arg to
+	* macosx/Tcl.xcodeproj/default.pbxuser: tcltest to ease test debugging
+
+	* macosx/Tcl.xcode/project.pbxproj:	removed $prefix/share from
+	* macosx/Tcl.xcodeproj/project.pbxproj: TCL_PACKAGE_PATH as per change
+	to unix/configure.in of 2006-03-13.
+
+	* unix/tclUnixFCmd.c (TclpObjNormalizePath): deal with *BSD/Darwin
+	realpath() converting relative paths into absolute paths [Bug 1064247]
+
+2006-03-28  Vince Darley  <vincentdarley@sourceforge.net>
+
+	* generic/tclIOUtil.c: fix to nativeFilesystemRecord comparisons
+	(lesser part of [Bug 1064247])
+
+2006-03-27  Pat Thoyts	<patthoyts@users.sourceforge.net>
+
+	* win/tclWinTest.c:	Fixes for [Bug 1456373] (mingw-gcc issue)
+
+2006-03-27  Andreas Kupries <andreask@activestate.com>
+
+	* doc/CrtChannel.3:    Added TCL_CHANNEL_VERSION_5, made it the
+	* generic/tcl.h:       version where the "truncateProc" is defined at,
+	* generic/tclIO.c:     and moved all channel drivers of Tcl to v5.
+	* generic/tclIOGT.c, generic/tclIORChan.c, unix/tclUnixChan.c:
+	* unix/tclUnixPipe.c, win/tclWinChan.c, win/tclWinConsole.c:
+	* win/tclWinPipe.c, win/tclWinSerial.c, win/tclWinSock.c:
+
+2006-03-27  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclExecute.c: Merge INST_MOD computation in with the
+	INST_?SHIFT instructions, which also operate only on two integral
+	values. Also corrected flaw that made INST_BITNOT of wide values
+	require mp_int calculations. Also corrected type that missed optimized
+	handling of the tclBooleanType by the TclGetBooleanFromObj macro.
+
+	* changes:	Updates for another RC.
+
+2006-03-25  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclExecute.c: Corrections to INST_EXPON detection of
+	overflow to use mp_int calculations.
+
+2006-03-24  Kevin B. Kenny  <kennykb@acm.org>
+
+	* generic/tclExecute.c (TclExecuteByteCode): Added a couple of missing
+	casts to 'int' that were affecting compilablity on VC6.
+
+2006-03-24  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclEncoding.c: Reverted latest change [Bug 506653] since it
+	reportedly killed test performance on Windows.
+
+	* generic/tclExecute.c: Revised INST_EXPON implementation to do
+	calculations in native types as much as possible, moving to mp_ints
+	only when necessary.
+
+2006-03-23  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclExecute.c: Merged INST_EXPON handling in with the other
+	binary operators that operate on all number types (INST_ADD, etc.).
+
+	* tests/env.test: With case preserved (see 2006-03-21 commit) be sure
+	to do case-insensitive filtering. [Bug 1457065]
+
+2006-03-23  Reinhard Max  <max@suse.de>
+
+	* unix/tcl.spec: Cleaned up and completed the spec file. An RPM can
+	now be built from the tcl source distribution with "rpmbuild -tb
+	<tarball>"
+
+2006-03-22  Reinhard Max  <max@suse.de>
+
+	* tests/stack.test: Run the stack tests in subshells, so that they are
+	reported as failed tests rather than bugs in the test suite if the
+	recursion causes a segfault.
+
+2006-03-21  Don Porter	<dgp@users.sourceforge.net>
+
+	* changes:	Updates for another RC.
+
+	* generic/tclStrToD.c:	One of the branches of AccumulateDecimalDigit
+	* tests/parseExpr.test: did not. [Bug 1451233]
+
+	* tests/env.test:	Preserve case of saved env vars. [Bug 1409272]
+
+2006-03-21  Daniel Steffen  <das@users.sourceforge.net>
+
+	* generic/tclInt.decls:	 implement globbing for HFS creator & type
+	* macosx/tclMacOSXFCmd.c:codes and 'hidden' flag, as documented in
+	* tests/macOSXFCmd.test: glob.n; objectified OSType handling in [glob]
+	* unix/tclUnixFile.c:	 and [file attributes]; fix globbing for
+	hidden files with pattern==NULL arg. [Bug 823329]
+	* generic/tclIntPlatDecls.h:
+	* generic/tclStubInit.c: make genstubs
+
+2006-03-20  Andreas Kupries <andreask@activestate.com>
+
+	* win/Makefile.in (install-libraries): Generate tcl8/8.4 directory
+	under Windows as well (cygwin Makefile). Related entry: 2006-03-07,
+	dgp. This moved the installation of http from 8.2 to 8.4, partially. A
+	fix of the required directory creation was done for unix on Mar 10,
+	without entry in the Changelog. This entry is for the fix of the
+	directory creation under Windows.
+
+	* unix/installManPage: There is always one even more broken "sed".
+	Moved the # comment starting character in the sed script to the
+	beginning of their respective lines. The AIX sed will not recognize
+	them as comments otherwise :( The actual text stays indented for
+	better association with the commands they belong to.
+
+2006-03-20  Donal K. Fellows  <donal.k.fellows@manchester.ac.uk>
+
+	* tests/cmdAH.test, tests/fCmd.test, tests/unixFCmd.test:
+	* tests/winFCmd.test: Cleanup of some test constraint handling, and a
+	few other minor issues.
+
+2006-03-18  Vince Darley  <vincentdarley@sourceforge.net>
+
+	* generic/tclFileName.c:
+	* doc/FileSystem.3:
+	* tests/fileName.test: Fix to [Bug 1084705] so that 'glob -nocomplain'
+	finally agrees with its documentation and doesn't swallow genuine
+	errors.
+
+	***POTENTIAL INCOMPATIBILITY*** for scripts that assumed '-nocomplain'
+	removes the need for 'catch' to deal with non-understood path names.
+
+	Small optimisation to implementation of pattern==NULL case of TclGlob,
+	and clarification to the documentation. [Tclvfs bug 1405317]
+
+2006-03-18  Vince Darley  <vincentdarley@sourceforge.net>
+
+	* tests/fCmd.test: added knownBug test case for [Bug 1394972]
+
+	* tests/winFCmd.test:
+	* tests/tcltest.test: corrected tests to better account for behaviour
+	of writable/non-writable directories on Windows 2000/XP. This, with
+	the previous patches, closes [Bug 1193497]
+
+2006-03-17  Andreas Kupries <andreask@activestate.com>
+
+	* doc/chan.n: Updated with documentation for the commands 'chan
+	create' and 'chan postevent' (TIP #219).
+
+	* doc/refchan.n: New file. Documentation of the command handler API
+	for reflected channels (TIP #219).
+
+2006-03-17  Joe Mistachkin <joe@mistachkin.com>
+
+	* unix/tclUnixPort.h: Include pthread.h prior to pthread_np.h [Bug
+	1444692]
+
+	* win/tclWinTest.c: Corrected typo of 'initializeMutex' that prevented
+	successful compilation.
+
+2006-03-16  Andreas Kupries <andreask@activestate.com>
+
+	* doc/open.n: Documented the changed behaviour of 'a'ppend mode.
+
+	* tests/io.test (io-43.1 io-44.[1234]): Rewritten to be self-contained
+	with regard to setup and cleanup. [Bug 681793]
+
+	* generic/tclIOUtil.c (TclGetOpenMode): Added the flag O_APPEND to the
+	list of POSIX modes used when opening a file for 'a'ppend. This
+	enables the proper automatic seek-to-end-on-write by the OS. See [Bug
+	680143] for longer discussion.
+
+	* tests/ioCmd.test (iocmd-13.7.*): Extended the testsuite to check the
+	new handling of 'a'.
+
+2006-03-15  Andreas Kupries <andreask@activestate.com>
+
+	* tests/socket.test: Extended the timeout in socket-11.11 from 10 to
+	40 seconds to allow for really slow machines. Also extended
+	actual/expected results with value of variable 'done' to make it
+	clearer when a test fails due to a timeout. [Bug 792159]
+
+2006-03-15  Vince Darley  <vincentdarley@sourceforge.net>
+
+	* win/fCmd.test: add proper test constraints so the new tests don't
+	run on Unix.
+
+2006-03-14  Andreas Kupries <andreask@activestate.com>
+
+	* generic/tclPipe.c (TclCreatePipeline): Modified the processing of
+	pipebars to fail if the last bar is followed only by redirections.
+	[Bug 768659]
+
+2006-03-14  Andreas Kupries <andreask@activestate.com>
+
+	* doc/fconfigure.n: Clarified that -translation is binary is reported
+	as lf when queried, because it is identical to lf, except for the
+	special additional behaviour when setting it. [Bug 666770]
+
+2006-03-14  Andreas Kupries <andreask@activestate.com>
+
+	* doc/clock.n: Removed double-quotes around section title NAME; not
+	needed.
+	* unix/installManpage: Reverted part to handle double-quotes in
+	section NAME, chokes older sed installations.
+
+2006-03-14  Andreas Kupries <andreask@activestate.com>
+
+	* library/tm.tcl (::tcl::tm::Defaults): Fixed handling of environment
+	variable TCLX.y_TM_PATH, bad variable reference. Thanks to Julian
+	Noble. [Bug 1448251]
+
+2006-03-14  Vince Darley  <vincentdarley@sourceforge.net>
+
+	* win/tclWinFile.c: updated patch to deal with 'file writable' issues
+	on Windows XP/2000.
+	* generic/tclTest.c:
+	* unix/tclUnixTest.c:
+	* win/tclWinTest.c:
+	* tests/fCmd.test: updated test suite to deal with correct permissions
+	setting and differences between XP/2000 and 95/98 3 tests still fail;
+	to be dealt with shortly
+
+2006-03-13  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclEncoding.c: Report error when an escape encoding is
+	missing one of its sub-encodings. [Bug 506653]
+
+	* unix/configure.in:	Revert change from 2005-07-26 that sometimes
+	* unix/configure:	added $prefix/share to the tcl_pkgPath. See
+	[Patch 1231015]. autoconf-2.59.
+
+2006-03-10  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclProc.c (ObjInterpProcEx):
+	* tests/apply.test (apply-5.1): Fix [apply] error messages so that
+	they quote the lambda expression. [Bug 1447355]
+
+2006-03-10  Zoran Vasiljevic  <vasiljevic@users.sourceforge.net>
+
+	-- Summary of changes fixing [Bug 1437595] --
+
+	* generic/tclEvent.c: Cosmetic touches and identation
+	* generic/tclInt.h: Added TclpFinalizeSockets() call.
+
+	* generic/tclIO.c: Calls TclpFinalizeSockets() as part of the
+	TclFinalizeIOSubsystem().
+
+	* unix/tclUnixSock.c: Added no-op TclpFinalizeSockets().
+
+	* win/tclWinPipe.c, win/tclWinSock.c: Finalization of sockets/pipes is
+	now solely done in TclpFinalizeSockets() and TclpFinalizePipes() and
+	not over the thread-exit handler, because the order of actions the Tcl
+	generic core will impose may result in cores/hangs if the thread exit
+	handler tears down corresponding subsystem(s) too early.
+
+2006-03-10  Vince Darley  <vincentdarley@sourceforge.net>
+
+	* win/tclWinFile.c: previous patch breaks tests, so removed.
+
+2006-03-09  Vince Darley  <vincentdarley@sourceforge.net>
+
+	* win/tclWinFile.c: fix to 'file writable' in certain XP directories.
+	Thanks to fvogel and jfg. [Patch 1344540] Modified patch to make use
+	of existing use of getSecurityProc.
+
+2006-03-08  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclExecute.c: Complete missing bit of TIP 215 implementation
+	* tests/incr.test:
+
+2006-03-07  Joe English	 <jenglish@users.sourceforge.net>
+
+	* unix/tcl.m4: Set SHLIB_LD_FLAGS='${LIBS}' on NetBSD, as per the
+	other *BSD variants. [Bug 1334613]
+	* unix/configure: Regenerated.
+
+2006-03-07  Don Porter	<dgp@users.sourceforge.net>
+
+	* changes:	Update in prep. for 8.5a4 release.
+
+	* unix/Makefile.in:	Package http 2.5.2 requires Tcl 8.4, so the
+	* win/Makefile.in:	*.tm installation has to be placed in an "8.4"
+	directory, not an "8.2" directory.
+
+2006-03-06  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclBasic.c:	Revised handling of TCL_EVAL_* flags to
+	* tests/parse.test:	simplify TclEvalObjvInternal and to correct
+	the auto-loading of alias targets (parse-8.12). [Bug 1444291]
+
+2006-03-03  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclPathObj.c: Revised yesterday's fix for [Bug 1379287] to
+	work on Windows.
+
+	* generic/tclObj.c:	Compatibility support for existing code that
+	calls Tcl_GetObjType("boolean").
+
+2006-03-02  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclPathObj.c:		Fix for failed normalization of paths
+	* tests/fileSystem.test:	with /../ that lead back to the root
+	of the filesystem, like /foo/.. [Bug 1379287]
+
+2006-03-01  Reinhard Max  <max@suse.de>
+
+	* unix/installManPage: Fix the script for manpages that have quotes
+	around the .SH arguments, as doctools produces them. [Bug 1292145]
+	Some minor cleanups and improvements.
+
+2006-02-28  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclBasic.c:	Corrections to be sure that TCL_EVAL_GLOBAL
+	* tests/namespace.test: evaluations act the same as [uplevel #0]
+	* tests/parse.test:	evaluations, even when execution traces or
+	* tests/trace.test:	invocations of [::unknown] are present. [Bug
+	1439836]
+
+2006-02-22  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclBasic.c:	Corrected a few bugs in how [namespace
+	* tests/namespace.test: unknown] interacts with TCL_EVAL_* flags.
+	[Patch 958222]
+
+2006-02-17  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclIORChan.c: Revised error message generation and handling
+	* tests/ioCmd.test:	of exceptional return codes in the channel
+	reflection layer. [Bug 1372348]
+
+2006-02-16  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclIndexObj.c:	Disallow the "ambiguous" error message
+	* tests/indexObj.test:		when TCL_EXACT matching is requested.
+	* tests/ioCmd.test:
+
+2006-02-15  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclIO.c:	Made several routines tolerant of
+	* generic/tclIORChan.c: interp == NULL arguments. [Bug 1380662]
+	* generic/tclIOUtil.c:
+
+2006-02-09  Don Porter	<dgp@users.sourceforge.net>
+
+	TIP#215 IMPLEMENTATION
+
+	* doc/incr.n:		Revised [incr] to auto-initialize when varName
+	* generic/tclExecute.c: argument is unset. [Patch 1413115]
+	* generic/tclVar.c:
+	* tests/compile.test:
+	* tests/incr-old.test:
+	* tests/incr.test:
+	* tests/set.test:
+
+	* tests/main.test (Tcl_Main-6.7):	Improved robustness of
+	command auto-completion test. [Bug 1422736]
+
+2006-02-08  Donal K. Fellows  <dkf@users.sf.net>
+
+	* doc/Encoding.3, doc/encoding.n: Updates due to review at request of
+	Don Porter. Mostly minor changes.
+
+2006-02-08  Don Porter	<dgp@users.sourceforge.net>
+
+	TIP#258 IMPLEMENTATION
+
+	* doc/Encoding.3:	New subcommand [encoding dirs].
+	* doc/encoding.n:	New routine Tcl_GetEncodingNameFromEnvironment
+	* generic/tcl.decls:	Made public:
+	* generic/tclBasic.c:	TclGetEncodingFromObj
+	* generic/tclCmdAH.c:		-> Tcl_GetEncodingFromObj
+	* generic/tclEncoding.c:TclGetEncodingSearchPath
+	* generic/tclInt.decls:		-> Tcl_GetEncodingSearchPath
+	* generic/tclInt.h:	TclSetEncodingSearchPath
+	* generic/tclTest.c:		-> Tcl_SetEncodingSearchPath
+	* library/init.tcl:	Removed commands:
+	* tests/cmdAH.test:		[tcl::unsupported::EncodingDirs]
+	* tests/encoding.test:		[testencoding path] (Tcltest)
+	* unix/tclUnixInit.c:	[Patch 1413934]
+	* win/tclWinInit.c:
+
+	* generic/tclDecls.h:	make genstubs
+	* generic/tclIntDecls.h:
+	* generic/tclStubInit.c:
+
+2006-02-01  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclProc.c: minor improvements to [apply]
+	* tests/apply.test: new tests; apply-5.1 currently fails to indicate
+	missing work in error reporting
+
+2006-02-01  Don Porter	<dgp@users.sourceforge.net>
+
+	TIP#194 IMPLEMENTATION
+
+	* doc/apply.n:	(New file)	New command [apply]. [Patch 944803]
+	* doc/uplevel.n:
+	* generic/tclBasic.c:
+	* generic/tclInt.h:
+	* generic/tclProc.c:
+	* tests/apply.test: (New file)
+	* tests/proc-old.test:
+	* tests/proc.test:
+
+	TIP#181 IMPLEMENTATION
+
+	* doc/Namespace.3:	New command [namespace unknown]. New public C
+	* doc/namespace.n:	routines Tcl_(Get|Set)NamespaceUnknownHandler.
+	* doc/unknown.n:	[Patch 958222]
+	* generic/tcl.decls:
+	* generic/tclBasic.c:
+	* generic/tclInt.h:
+	* generic/tclNamesp.c:
+	* tests/namespace.test:
+
+	* generic/tclDecls.h:	make genstubs
+	* generic/tclStubInit.c:
+
+	TIP#250 IMPLEMENTATION
+
+	* doc/namespace.n:	New command [namespace upvar]. [Patch 1275435]
+	* generic/tclInt.h:
+	* generic/tclNamesp.c:
+	* generic/tclVar.c:
+	* tests/namespace.test:
+	* tests/upvar.test:
+
+2006-01-26  Donal K. Fellows  <dkf@users.sf.net>
+
+	* doc/dict.n: Fixed silly bug in example. Thanks to Heiner Marxen
+	<heiner.marxen@unsel.de> for catching this! [Bug 1415725]
+
+2006-01-26  Donal K. Fellows  <donal.k.fellows@manchester.ac.uk>
+
+	* unix/tclUnixChan.c (TclpOpenFileChannel): Tidy up and comment the
+	mess to do with setting up serial channels. This (deliberately) breaks
+	a broken FreeBSD port, indicates what we're really doing, and reduces
+	the amount of conditional compilation sections for better maintenance.
+
+2006-01-25  Donal K. Fellows  <dkf@users.sf.net>
+
+	* unix/tclUnixInit.c (TclpInitPlatform): Improved conditions on when
+	to update the FP rounding mode on FreeBSD, taken from FreeBSD port.
+
+2006-01-23  Donal K. Fellows  <dkf@users.sf.net>
+
+	* tests/string.test (string-12.21): Added test for [Bug 1410553] based
+	on original bug report.
+
+2006-01-23  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclStringObj.c: fixed incorrect handling of internal rep in
+	Tcl_GetRange. Thanks to twylite and Peter Spjuth. [Bug 1410553]
+
+	* generic/tclProc.c: fixed args handling for precompiled bodies [Bug
+	1412695]; thanks to Uwe Traum.
+
+2006-01-16  Reinhard Max  <max@suse.de>
+
+	* generic/tclPipe.c (FileForRedirect): Prevent nameString from being
+	freed without having been initialized.
+	* tests/exec.test: Added a test for the above.
+
+2006-01-12  Zoran Vasiljevic  <vasiljevic@users.sourceforge.net>
+
+	* generic/tclPathObj.c (Tcl_FSGetInternalRep): backported patch from
+	core-8-4-branch. A freed pointer has been overwritten causing all
+	sorts of coredumps.
+
+2006-01-12  Vince Darley  <vincentdarley@sourceforge.net>
+
+	* win/tclWinFile.c: fix to sharing violation [Bug 1366227]
+
+2006-01-11  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclBasic.c:	Moved Tcl_LogCommandInfo from tclBasic.c to
+	* generic/tclNamesp.c:	tclNamesp.c to get access to identifier with
+	* tests/error.test (error-7.0): file scope. Added check for traces on
+	::errorInfo, and when present fall back to contruction of the stack
+	trace in the variable so that write trace notification timings are
+	compatible with earlier Tcl releases. This reduces, but does not
+	completely eliminate the ***POTENTIAL INCOMPATIBILITY*** created by
+	the 2004-10-15 commit. [Bug 1397843]
+
+2006-01-10  Daniel Steffen  <das@users.sourceforge.net>
+
+	* unix/configure:    add caching, use AC_CACHE_CHECK instead of
+	* unix/configure.in: AC_CACHE_VAL where possible, consistent message
+	* unix/tcl.m4:	     quoting, sync relevant tclconfig/tcl.m4 changes
+	and gratuitous formatting differences, fix SC_CONFIG_MANPAGES with
+	default argument, Darwin improvements to SC_LOAD_*CONFIG.
+
+2006-01-09  Don Porter	<dgp@users.sourceforge.net>
+
+	* generic/tclNamesp.c (NamespaceInscopeCmd):	[namespace inscope]
+	* tests/namespace.test: commands were not reported by [info level].
+	[Bug 1400572]
+
+2006-01-09  Donal K. Fellows  <donal.k.fellows@manchester.ac.uk>
+
+	* generic/tclTrace.c: Stop exporting the guts of the trace command;
+	nothing outside this file needs to see it. [Bug 971336]
+
+2006-01-05  Donal K. Fellows  <donal.k.fellows@manchester.ac.uk>
+
+	* unix/tcl.m4 (TCL_CONFIG_SYSTEM): Factor out the code to determine
+	the operating system version number, as it was replicated in several
+	places.
+
+2006-01-04  David Gravereaux  <davygrvy@pobox.com>
+
+	* win/tclAppInit.c: WIN32 native console signal handler removed. This
+	was found to be interfering with TWAPI extension one. IMO, special
+	services such as signal handlers should best be done with extensions
+	to the core after discussions on c.l.t. about Roy Terry's tclsh
+	children of a real windows service shell.
+
+	******************************************************************
+	*** CHANGELOG ENTRIES FOR 2005 IN "ChangeLog.2005"	       ***
+	*** CHANGELOG ENTRIES FOR 2004 IN "ChangeLog.2004"	       ***
+	*** CHANGELOG ENTRIES FOR 2003 IN "ChangeLog.2003"	       ***
+	*** CHANGELOG ENTRIES FOR 2002 IN "ChangeLog.2002"	       ***
+	*** CHANGELOG ENTRIES FOR 2001 IN "ChangeLog.2001"	       ***
+	*** CHANGELOG ENTRIES FOR 2000 IN "ChangeLog.2000"	       ***
+	*** CHANGELOG ENTRIES FOR 1999 AND EARLIER IN "ChangeLog.1999" ***
+	******************************************************************
diff --git a/ChangeLog.2008 b/ChangeLog.2008
new file mode 100644
index 0000000..9c4e951
--- /dev/null
+++ b/ChangeLog.2008
@@ -0,0 +1,3796 @@
+2008-12-31  Don Porter  <dgp@users.sourceforge.net>
+
+	* unix/Makefile.in:	Set TCLLIBPATH in SHELL_ENV so that targets
+	like `make shell` have access to builds of bundled packages.
+
+2008-12-28  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclZlib.c (Tcl_ZlibStreamPut): Plug a memory leak.
+
+2008-12-27  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclZlib.c (ZlibStreamCmd): Fix compilation consistency. [Bug
+	* generic/tcl.decls:		     2470237]
+
+	* generic/tclZlib.c (Tcl_ZlibStreamGet): Corrected the semantics of
+	this function to be useful to the PNG implementation. If the argument
+	object is empty, this gives the previous semantics.
+	(Tcl_ZlibStreamChecksum): Corrected name to be less misleading; it
+	only produced Adler-32 checksums when the stream was processing the
+	right type of compressed data format.
+	(Tcl_ZlibAdler32, Tcl_ZlibCRC32): Corrected types so that they work
+	naturally with the results of Tcl_GetByteArrayFromObj().
+	*** POTENTIAL INCOMPATIBILITY *** for all above changes, but very
+	unlikely to be difficult for anyone to deal with.
+
+2008-12-26  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tcl.decls: Tidy up the commenting style, adding markers for
+	each of the big release points under TCT stewardship and noting the
+	general purpose of each TIP that added C API. Overall effect is to
+	make this file much more informative to read without having to spend
+	effort correlating with TIPs and ChangeLogs.
+
+2008-12-23  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* win/Makefile.in:	Fix build of zlib objects with msvc
+	* win/tcl.m4:
+	* win/configure:	autoconf-2.59
+
+2008-12-23  Donal K. Fellows  <dkf@users.sf.net>
+
+	* win/Makefile.in: Handle file extensions correctly. [Bug 2459725]
+
+2008-12-22  Pat Thoyts  <patthoyts@users.sourceforge.net>
+
+	*** 8.6b1 TAGGED FOR RELEASE ***
+
+	* win/makefile.vc: Ensure pkgs directories are suitable and quote the
+			   paths. [Bug 2458395]
+
+2008-12-22  Joe Mistachkin  <joe@mistachkin.com>
+
+	* tools/man2help2.tcl: Added support for "\(mi" nroff macro. [Bug
+	2330040]
+
+2008-12-22  Pat Thoyts  <patthoyts@users.sourceforge.net>
+
+	* win/makefile.vc: Support the pkgs tree in the NMAKE builds.
+
+2008-12-21  Daniel Steffen  <das@users.sourceforge.net>
+
+	* unix/Makefile.in:	Fix broken build of bundled packages when path
+				to build dir contains spaces by switching to
+				relative paths to toplevel build dir.
+
+	* unix/configure.in:	Preserve configure environment variables for
+				sub-configures of bundled packages; reuse
+				configure cache file for sub-configures.
+
+	* unix/configure:	autoconf-2.59
+
+2008-12-21  Donal K. Fellows  <dkf@users.sf.net>
+
+	* doc/TclZlib.3: Fix minor typo. [Bug 2455165]
+
+2008-12-20  Kevin B. Kenny  <kennykb@acm.org>
+
+	* win/Makefile.in:	Renamed the static library libtcl86s.a to
+	* win/configure.in:	have a name distinct from the import library
+				libtcl86.a. This renaming dodges an ancient
+				bug in the Makefile revealed by the last
+				commit where the $(TCL_LIB_FILE) rule can
+				fire to try to build the static library in a
+				--enable-shared build (and create a static
+				library that subsequently fails to link).
+				Revised the zlib objects so that they are
+				built directly into the build dir, without
+				building an intermediate static library.
+				*** POTENTIAL INCOMPATIBILITY *** for
+				embedders who link to the static library, but
+				I couldn't figure out how to sort this out
+				any other way.
+	* win/configure:	Autoconf 2.59
+
+2008-12-20  Donal K. Fellows  <dkf@users.sf.net>
+
+	* win/Makefile.in: Minor updates to make building work better with
+	msys on Windows. (Apparently the gcc used doesn't like a / at the end
+	of a -I argument...)
+
+2008-12-20  Don Porter  <dgp@users.sourceforge.net>
+
+	* changes:	Updates for 8.6b1 release.
+
+2008-12-20  Daniel Steffen  <das@users.sourceforge.net>
+
+	* unix/Makefile.in:	Make package install directory of bundled
+	* unix/configure.in:	packages configurable via PACKAGE_DIR makefile
+				variable (set to platform-specific default).
+
+	* unix/Makefile.in (*-packages): Ensure toplevel targets fail if
+				sub-make/configure fails; fix quoting when
+				builddir path contains spaces.
+
+	* macosx/GNUmakefile:	Add install-packages to install targets.
+
+	* unix/configure:	autoconf-2.59
+
+2008-12-19  Don Porter  <dgp@users.sourceforge.net>
+
+	* doc/NRE.3:		Formatting errors found by `make html`
+	* doc/Tcl_Main.3:
+	* doc/zlib.n:
+
+	* tests/chanio.test:	Add missing [removeFile] cleanups.
+	* tests/io.test:	Add missing [close $f] to io-73.2.
+
+	* unix/Makefile.in:	Update `make dist' target to include the files
+	from the compat/zlib directory as well as all the bundled packages
+	found under the pkgs directory, according to their individual `make
+	dist' targets. Change includes breaking a `configure-packages' target
+	out of the `packages` target.
+
+	* README:		Bump version number to 8.6b1
+	* generic/tcl.h:
+	* library/init.tcl:
+	* tools/tcl.wse.in:
+	* unix/configure.in:
+	* unix/tcl.spec:
+	* win/configure.in:
+
+	* unix/configure:	autoconf-2.59
+	* win/configure:
+
+2008-12-19  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tclInt.decls: CONSTify TclGetLoadedPackages second param
+	* generic/tclLoad.c
+	* generic/tclIntDecls.h (regenerated)
+
+2008-12-19  Kevin Kenny  <kennykb@acm.org>
+
+	* generic/tclExecute.c:	Fix compile warnings when --enable-symbols=all
+
+	* win/configure.in:
+	* win/Makefile.in: Added build of packages in the 'pkgs/' directory.
+	* win/configure: Autoconf 2.59
+
+2008-12-19  Pat Thoyts  <patthoyts@users.sourceforge.net>
+
+	* win/makefile.vc: Added build of compat/zlib
+
+2008-12-18  Andreas Kupries  <andreask@activestate.com>
+
+	* generic/tclIO.c (Tcl_CloseEx, CloseWrite, CloseChannelPart)
+	(ChanCloseHalf): Rewrite the half-close to properly flush the channel,
+	like is done for a full close, going through FlushChannel, and using
+	the flag BG_FLUSH_SCHEDULED (async flush during close). New functions
+	CloseWrite, CloseChannelPart, new flag CHANNEL_CLOSEDWRITE.
+
+	* tests/chanio.test (chanio-28.[67]): Reactivated these tests.
+	Replaced tclsh -> [interpreter] to get correct executable for the pipe
+	process, and added after cancel to kill the fail timers when we are
+	done. Removed the explicits calls to [flush], now that [close] handles
+	this correctly.
+
+2008-12-18  Don Porter  <dgp@users.sourceforge.net>
+
+	* tests/chanio.test:	Replaced [chan event] handlers that returned
+	TCL_RETURN return code, with more conventional ones that return TCL_OK
+	to suppress otherwise strange writes of outdated $::errorInfo values
+	to stderr. [Bug 2444274]
+
+	* generic/tclExecute.c:	Disabled apparently faulty assertion. [Bug
+	2415422]
+
+2008-12-18  Donal K. Fellows  <dkf@users.sf.net>
+
+	* unix/configure.in, unix/Makefile.in: Autoconf wizardry.
+	* compat/zlib/*: Import of zlib 1.2.3. The license is directly
+	compatible with Tcl's. This import omits the obsolete and contributed
+	parts (i.e. selected directories) and the supplied examples.
+
+	* generic/tclZlib.c:	First implementation of the compressing and
+	* doc/zlib.n:		decompressing channel transformations.
+	* tests/zlib.test (zlib-8.*):
+
+2008-12-18  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tcl.decls:	VOID -> void
+	* generic/tclInt.decls:
+	* compat/dlfcn.h:
+	* generic/tclDecls.h:	(regenerated)
+	* generic/tclIntDecls.h:
+
+2008-12-18  Alexandre Ferrieux  <ferrieux@users.sourceforge.net>
+
+	TIP #332 IMPLEMENTATION - Half-Close for Bidirectional Channels
+
+	* doc/close.n, generic/tclIO.c, generic/tclIOCmd.c:
+	* unix/tclUnixChan.c, unix/tclUnixPipe.c, win/tclWinSock.c:
+	* generic/tcl.decls, generic/tclDecls.h, generic/tclStubInit.c:
+	* tests/chan.test, tests/chanio.test, tests/ioCmd.test:
+
+2008-12-17  Donal K. Fellows  <dkf@users.sf.net>
+
+	* doc/SetChanErr.3: General improvements in nroff rendering and some
+	corrections to language issues.
+
+2008-12-17  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tclResult.c:	   Move variable "length" inside if()
+	* generic/tclStringObj.c:  Don't use ckfree((void *)...) but
+	* generic/tclVar.c:	   ckfree((char *)...)
+	* generic/tclZlib.c
+	* generic/tclBasic.c
+
+2008-12-17  Donal K. Fellows  <dkf@users.sf.net>
+
+	* tests/namespace.test (namespace-28.1):	Make tests not
+	* tests/namespace-old.test (namespace-old-9.5): dependent on the
+	global namespace's particular imports. [Bug 2433936]
+
+2008-12-17  Don Porter  <dgp@users.sourceforge.net>
+
+	* unix/Makefile.in:	Modify the distclean-packages target so that
+	empty build directories are deleted.
+
+	* unix/Makefile.in:	Add build support for collections of TEA
+	* unix/configure.in:	packages found under the pkgs directory.
+	[Patch 1163406]. Still needs porting to Windows.
+
+	* unix/configure:	autoconf-2.59
+
+2008-12-17  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tcl.h, generic/tclZlib.c: Removed undocumented flag.
+
+2008-12-16  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tclThreadTest.c: Eliminate -Wwrite-strings warnings in
+				   --enable-threads build.
+	* generic/tclExecute.c:	   Use TclNewLiteralStringObj()
+	* unix/tclUnixFCmd.c:	   Use TclNewLiteralStringObj()
+	* win/tclWinFCmd.c:	   Use TclNewLiteralStringObj()
+
+2008-12-16  Donal K. Fellows  <dkf@users.sf.net>
+
+	TIP #329 IMPLEMENTATION
+
+	* tests/error.test: Tests for the new commands.
+	* doc/throw.n, doc/try.n: Documentation of the new commands.
+	* library/init.tcl (throw, try): Implementation of commands documented
+	in TIP. This implementation is in Tcl and is a stop-gap until
+	higher-performance ones can be written.
+
+2008-12-16  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tcl.h:	Add TIP 338 routines to stub table.
+	* generic/tcl.decls:	[Bug 2431338]
+
+	* generic/tclDecls.h:	make genstubs
+	* generic/tclStubInit.c:
+
+2008-12-15  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclExecute.c (TEBC:INST_DICT_GET): Make sure that the result
+	is empty when generating an error message. [Bug 2431847]
+
+2008-12-15  Alexandre Ferrieux  <ferrieux@users.sourceforge.net>
+
+	* generic/tclBinary.c:	Redefine non-strict decoding to ignore only
+	* doc/binary.n:		whitespace. [Bug 2380293]
+	* tests/binary.test:
+
+2008-12-15  Don Porter  <dgp@users.sourceforge.net>
+
+	* doc/AddErrInfo.3:	Documented Tcl_(Set|Get)ErrorLine (TIP 336).
+	* doc/CrtCommand.3:	Various other documentation updates to
+	* doc/CrtInterp.3:	reflect the lack of access to Tcl_Interp
+	* doc/Interp.3:		fields by default.
+	* doc/SetResult.3:
+	* doc/tcl.decls:
+
+	TIP #338 IMPLEMENTATION
+
+	* doc/AppInit.c:	Made routines Tcl_SetStartupScript and
+	* doc/Tcl_Main.3:	Tcl_GetStartupScript public. Removed all
+	* generic/tcl.h:	internal stub access to Tcl*Startup* routines,
+	* generic/tclInt.decls:	and removed their implementations. Their
+	* generic/tclMain.c:	function can now be completely performed with
+				the new public interface.
+	*** POTENTIAL INCOMPATIBILITY for callers of the internal
+	    Tcl*Startup* routines. ***
+
+	* generic/tclIntDecls.h:	make genstubs
+	* generic/tclStubInit.c:
+	* generic/tclDecls.h:
+
+2008-12-14  Donal K. Fellows  <dkf@users.sf.net>
+
+	* tests/zlib.test: Added constraint so that tests don't fail where
+	they cannot work due to zlib support being missing.
+
+	* unix/configure.in, win/configure.in: Improve the autodetection code.
+	* win/tcl.m4 (SC_CONFIG_CFLAGS): Remove the assumption of the presence
+	of zlib library on Windows.
+	* win/makefile.vc, win/makefile.bc: Add support for building tclZlib.o
+	but only in stubbed-out mode for now.
+
+2008-12-13  Donal K. Fellows  <dkf@users.sf.net>
+
+	* doc/TclZlib.3: Basic documentation of the C-level API.
+	* doc/zlib.n: Substantially improve documentation of Tcl-level API.
+	* generic/tclZlib.c (ZlibCmd): Flesh out the argument parsing for the
+	command to integrate with channels.
+
+2008-12-12  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tclZlib.c (Tcl_ZlibInflate): Change PATH_MAX to MAXPATHLEN,
+	since MSVC doesn't have PATH_MAX.
+
+	* doc/clock.n:	Document new DST fallback rules.
+	* library/clock.tcl (ProcessPosixTimeZone): Fix time change in Eastern
+	Europe (not 3:00 but 4:00 local time). [Bug 2207436]
+
+2008-12-12  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclZlib.c, unix/configure.in: Added stubs to use when the
+	version of zlib is not capable enough, and automagic to detect when
+	that is the case. [Bug 2421265]
+
+2008-12-12  Alexandre Ferrieux  <ferrieux@users.sourceforge.net>
+
+	* unix/tclUnixNotfy.c: Fix missing CLOEXEC on internal pipes [2417695]
+	* unix/tclUnixPipe.c:  Fix missing CLOEXEC on [chan pipe] fds.
+
+2008-12-12  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclZlib.c (Tcl_ZlibDeflate): Add a bit of extra space for
+	the gzip header. [Bug 2419061]
+	(Tcl_ZlibInflate): Ensure that gzip header extraction is done
+	correctly.
+
+2008-12-12  Kevin Kenny  <kennykb@acm.org>
+
+	TIP #322 IMPLEMENTATION
+
+	* doc/NRE.3 (new file): Added documentation of the published API for
+	Non-Recursive Evaluation (NRE).
+
+2008-12-11  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tclZlib.c: Eliminate warning: different 'const' qualifiers
+	with msvc compiler. A few more 'const' optimizations.
+	* win/tcl.m4: Fix Windows build (msvc) for TIP #234 implementation
+	* win/Makefile.in:
+	* win/configure:
+
+2008-12-11  Andreas Kupries  <andreask@activestate.com>
+
+	* generic/tclIO.c (SetChannelFromAny and related): Modified the
+	* tests/io.test: internal representation of the tclChannelType to
+	contain not only the ChannelState pointer, but also a reference to
+	the interpreter it was made in. Invalidate and recompute the
+	internal representation when it is used in a different interpreter,
+	like cmdName intrep's. Added testcase. [Bug 2407783]
+
+2008-12-11  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclZlib.c (ConvertError): Factor out code to turn zlib
+	errors into Tcl errors.
+
+	* doc/zlib.n: Added a start at the documentation. Still very rough.
+
+2008-12-11  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* win/Makefile.in: Fix Windows build (mingw) for TIP #234
+	implementation (additionally, first make sure that zlib is available,
+	and rename the standard zdll.lib to libz.a, but at least this works so
+	far).
+
+2008-12-11  Donal K. Fellows  <dkf@users.sf.net>
+
+	* tests/zlib.test: Start of test suite for zlib command.
+
+2008-12-11  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* library/clock.tcl (ProcessPosixTimeZone): Fallback to European time
+	zone DST rules, when the timezone is between 0 and -12. [Bug 2207436]
+	* tests/clock.test (clock-52.[23]): Test cases for [Bug 2207436]
+
+2008-12-11  Donal K. Fellows  <dkf@users.sf.net>
+
+	TIP #234 IMPLEMENTATION
+
+	* generic/tclZlib.c: A very preliminary hack at an interface to the
+	zlib library, based on code from Pascal Scheffers.
+	WARNING! The C API may be subect to change without much warning! USE
+	AT YOUR OWN RISK!
+
+2008-12-10  Kevin B. Kenny  <kennykb@acm.org>
+
+	* library/tzdata/*: Update from Olson's tzdata2008i.
+
+2008-12-10  Alexandre Ferrieux  <ferrieux@users.sourceforge.net>
+
+	TIP #343 IMPLEMENTATION - A Binary Specifier for [format/scan]
+
+	* doc/format.n
+	* doc/scan.n
+	* generic/tclInt.h
+	* generic/tclScan.c
+	* generic/tclStrToD.c
+	* generic/tclStringObj.c
+	* tests/format.test
+	* tests/scan.test
+
+2008-12-10  Donal K. Fellows  <dkf@users.sf.net>
+
+	TIP #341 IMPLEMENTATION
+
+	* generic/tclDictObj.c (DictFilterCmd): Made key and value filtering
+	* tests/dict.test, doc/dict.n:		accept arbitrary numbers of
+						glob arguments.
+
+2008-12-09  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tclInt.decls: Restore source and binary compatibility for
+				TIP #337 implementation. (When it is _that_
+				simple, there is no excuse not to do it! :-))
+	* generic/tclIntDecls.h:	make genstubs
+	* generic/tclStubInit.c:
+
+2008-12-09  Don Porter  <dgp@users.sourceforge.net>
+
+	TIP #337 IMPLEMENTATION
+
+	* doc/BackgdErr.3:	Converted internal routine
+	* doc/interp.n:		TclBackgroundException() into public routine
+	* generic/tcl.decls:	Tcl_BackgroundException().
+	* generic/tclEvent.c:
+	* generic/tclInt.decls:
+
+	* generic/tclDecls.h:	make genstubs
+	* generic/tclIntDecls.h:
+	* generic/tclStubInit.c:
+
+	* generic/tclIO.c:	Update callers.
+	* generic/tclIOCmd.c:
+	* generic/tclInterp.c:
+	* generic/tclTimer.c:
+	*** POTENTIAL INCOMPATIBILITY only for extensions using the converted
+	    internal routine ***
+
+2008-12-09  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclIO.c (ChanClose,ChanRead,...): Factored out some of the
+	code to connect to channel drivers that was common in multiple
+	locations so as to make code more readable.
+
+2008-12-06  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclCmdAH.c (FileTempfileCmd): Force temporary files to be
+	created in the native filesystem. Attempting to provide a template
+	that puts it elsewhere will result in the directory part of the
+	template being ignored. Partial address of [Bug 2388866] concerns.
+
+2008-12-05  Donal K. Fellows  <dkf@users.sf.net>
+
+	TIP #335 IMPLEMENTATION
+
+	* generic/tclBasic.c (Tcl_InterpActive): Added function for working
+	* doc/CrtInterp.3:			 out if an interp is in use.
+
+	TIP #307 IMPLEMENTATION
+
+	* generic/tclResult.c (Tcl_TransferResult): Renamed function from
+	* generic/tcl.decls:			    TclTransferResult. Added
+	* doc/SetResult.3:			    to public stubs table.
+
+2008-12-04  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclPathObj.c (Tcl_FSGetNormalizedPath):	Added another
+	flag value TCLPATH_NEEDNORM to mark those intreps which need more
+	complete normalization attention for correct results. [Bug 2385549]
+
+2008-12-03  Donal K. Fellows  <dkf@users.sf.net>
+
+	* win/tclWinPipe.c (TclpOpenTemporaryFile): Avoid an infinite loop due
+	to GetTempFileName/CreateFile interaction. [Bug 2380318]
+
+2008-12-03  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclFileName.c (DoGlob):    One of the Tcl_FSMatchInDirectory
+	calls did not have its return code checked. This caused error messages
+	returned by some Tcl_Filesystem drivers to be swallowed.
+
+2008-12-02  Don Porter  <dgp@users.sourceforge.net>
+
+	TIP #336 IMPLEMENTATION
+
+	* generic/tcl.decls:	New routines Tcl_(Get|Set)ErrorLine.
+	* generic/tcl.h:	Dropped default access to interp->errorLine.
+	* generic/tclCmdAH.c:	Restore it with -DUSE_INTERP_ERRORLINE.
+	* generic/tclCmdMZ.c:	Updated callers.
+	* generic/tclDictObj.c:
+	* generic/tclIOUtil.c:
+	* generic/tclNamesp.c:
+	* generic/tclOOBasic.c:
+	* generic/tclOODefinedCmds.c:
+	* generic/tclOOMethod.c:
+	* generic/tclProc.c:
+	* generic/tclResult.c:
+	*** POTENTIAL INCOMPATIBILITY for C code directly using the
+	    interp->errorLine field ***
+
+	* generic/tclDecls.h:	make genstubs
+	* generic/tclStubInit.c:
+
+2008-12-02  Andreas Kupries  <andreask@activestate.com>
+
+	* generic/tclIO.c (TclFinalizeIOSubsystem): Replaced Alexandre
+	Ferrieux's first patch for [Bug 2270477] with a gentler version, also
+	supplied by him.
+
+2008-12-01  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclParse.c:  Coding standards fixups.
+
+2008-12-01  Donal K. Fellows  <dkf@users.sf.net>
+
+	* tests/cmdAH.test (cmdAH-32.6): Test was not portable; depended on a
+	C API function not universally available. [Bug 2371623]
+
+2008-11-30  Kevin B. Kenny  <kennykb@acm.org>
+
+	* library/clock.tcl (format, ParseClockScanFormat): Added a [string
+	map] to get rid of namespace delimiters before caching a scan or
+	format procedure. [Bug 2362156]
+	* tests/clock.test (clock-64.[12]): Added test cases for the bug that
+	was tickled by a namespace delimiter inside a format string.
+
+2008-11-29  Donal K. Fellows  <dkf@users.sf.net>
+
+	TIP #210 IMPLEMENTATION
+
+	* generic/tclCmdAH.c (FileTempfileCmd):
+	* unix/tclUnixFCmd.c (TclpOpenTemporaryFile, DefaultTempDir):
+	* win/tclWinPipe.c (TclpOpenTemporaryFile):
+	* doc/file.n, tests/cmdAH.test: Implementation of [file tempfile]. I
+	do not claim that this is a brilliant implementation, especially on
+	Windows, but it covers the main points.
+
+	* generic/tclThreadStorage.c: General revisions to make code clearer
+	and more like the style used in the rest of the core. Includes adding
+	more comments and explanation of what is going on. Reduce the amount
+	of locking required.
+
+2008-11-27  Alexandre Ferrieux  <ferrieux@users.sourceforge.net>
+
+	* generic/tcl.h:	Alternate fix for [Bug 2251175]: missing
+	* generic/tclCompile.c:	backslash substitution on expanded literals.
+	* generic/tclParse.c:
+	* generic/tclTest.c:
+	* tests/parse.test:
+
+2008-11-26  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tclIndexObj.c:   Eliminate warning: unused variable
+	* generic/tclTest.c:	   A few more (harmless) Tcl_SetResult
+				   eliminations.
+
+2008-11-26  Kevin B. Kenny  <kennykb@acm.org>
+
+	* library/tclIndex: Removed reference to no-longer-extant procedure
+			    'tclLdAout'.
+	* doc/library.n: Corrected mention of 'auto_exec' to 'auto_execok'.
+	[Patch 2114900] thanks to Stuart Cassoff <stwo@users.sf.net>
+
+2008-11-25  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tclIndexObj.c: Eliminate 3 calls to Tcl_SetResult, as
+	* generic/tclIO.c:	 examples how it should have been done.
+	* generic/tclTestObj.c:	 purpose: contribute in the TIP #340
+				 discussion.
+
+2008-11-25  Andreas Kupries  <andreask@activestate.com>
+
+	* generic/tclIO.c (TclFinalizeIOSubsystem): Applied Alexandre
+	Ferrieux's patch for [Bug 2270477] to prevent infinite looping during
+	finalization of channels not bound to interpreters.
+
+2008-11-25  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tclTest.c: Don't assume that Tcl_SetResult sets
+	interp->result, especially not in a DString test, in preparation for
+	TIP #340
+
+2008-11-24  Donal K. Fellows  <dkf@users.sf.net>
+
+	* tools/tcltk-man2html.tcl: Improvements to tackle tricky aspects of
+	cross references and new entities to map. [Bug 2330040]
+
+2008-11-19  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tclThreadTest.c: Convert Tcl_SetResult(......, TCL_DYNAMIC)
+	to Tcl_SetResult(......, TCL_VOLATILE), in preparation for TIP #340
+
+2008-11-17  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tcl.decls:	Fix signature and implementation of
+	* generic/tclDecls.h:	Tcl_HashStats, such that it conforms to the
+	* generic/tclHash.c:	documentation. [Bug 2308236]
+	* generic/tclVar.c:
+	* doc/Hash.3:
+	* generic/tclDictObj.c: Convert Tcl_SetResult call to
+	Tcl_SetObjResult.
+
+2008-11-17  Alexandre Ferrieux  <ferrieux@users.sourceforge.net>
+
+	* tests/for.test: Check for uncompiled-for-continue [Bug 2186888]
+	fixed earlier.
+
+	* generic/tcl.h:	 Fix [Bug 2251175]: missing backslash
+	* generic/tclCompCmds.c: substitution on expanded literals.
+	* generic/tclCompile.c
+	* generic/tclParse.c
+	* generic/tclTest.c
+	* tests/compile.test
+	* tests/parse.test
+
+2008-11-16  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tclTest.c: Replace two times Tcl_SetResult with
+	Tcl_SetObjResult, a little simplification in preparation for the TIP
+	#340 patch.
+
+2008-11-13  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tclInt.h:	Rename static function FSUnloadTempFile to
+	* generic/tclIOUtil.c:	TclFSUnloadTempFile, needed in tclLoad.c
+
+	* generic/tclLoad.c:	Fixed [Bug 2269431]: Load of shared
+				objects leaves temporary files on windows.
+
+2008-11-12  Pat Thoyts  <patthoyts@users.sourceforge.net>
+
+	* tests/registry.test: Use HKCU to avoid requiring admin access for
+	registry testing on Vista/Server2008
+
+2008-11-11  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tclNamesp.c:	Eliminate warning: passing arg 4 of
+				Tcl_SplitList from incompatible pointer type.
+	* win/tcl.m4:	Reverted change from 2008-11-06 (was under the
+			impression that "-Wno-implicit-int" added an extra
+			warning)
+	* win/configure: (regenerated)
+	* unix/tcl.m4:	Use -O2 as gcc optimization compiler flag, and get rid
+			of -Wno-implicit-int for UNIX.
+	* unix/configure: (regenerated)
+
+2008-11-10  Andreas Kupries  <andreask@activestate.com>
+
+	* doc/platform_shell.n: Fixed [Bug 2255235], reported by Ulrich
+	* library/platform/pkgIndex.tcl: Ring <uring@users.sourceforge.net>.
+	* library/platform/shell.tcl: Updated the LOCATE command in the
+	* library/tm.tcl:   package 'platform::shell' to handle the new form
+	* unix/Makefile.in: of 'provide' commands generated by tm.tcl. Bumped
+	* win/Makefile.in:  package to version 1.1.4. Added cross-references
+	to the relevant parts of the code to avoid future desynchronization.
+
+2008-11-07  Pat Thoyts  <patthoyts@users.sourceforge.net>
+
+	* generic/tclInt.h:    Applied [Patch 2215022] from Duoas to clean up
+	* generic/tclBinary.c: the binary ensemble initiailization code.
+	* generic/tclNamesp.c: Extends the TclMakeEnsemble to do
+	* doc/ByteArrObj.3:    sub-ensembles from tables.
+
+2008-11-06  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* win/tcl.m4:	    Add "-Wno-implicit-int" flag for gcc, as on UNIX
+	* win/configure:    (regenerated)
+	* generic/tclIO.c:  Eliminate an 'array index out of bounds' warning
+			    on HP-UX.
+
+2008-11-04  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* generic/tclPort.h: Remove the ../win/ header dir as the build system
+	already has it, and it confuses builds when used with private headers
+	installed.
+
+2008-11-01  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclOO.h (TCLOO_VERSION): Bump version of TclOO.
+
+2008-10-31  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclOOBasic.c (TclOONRUpcatch): Reworked the code that does
+	* generic/tclOO.c (InitFoundation):	 class constructor handling so
+	that it is more robust and runs the constructor call in the context of
+	the caller of the class's constructor method. Needed because the
+	previously used code did not work at all after applying the fix below;
+	no Tcl existing command could reliably do what was needed any more.
+
+	* generic/tclOODefineCmds.c (GetClassInOuterContext): Rework and
+	factor out the code to resolve class names in definitions so that
+	classes are resolved from the perspective of the caller of the
+	[oo::define] command, rather than from the oo::define namespace! This
+	makes much code simpler by reducing how often fully-qualified names
+	are required (previously always in practice, so no back-compat issues
+	exist). [Bug 2200824]
+
+2008-10-28  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tclCompile.h: CONSTify TclDTraceInfo
+	* generic/tclBasic.c:
+	* generic/tclProc.c:
+	* generic/tclEnv.c:	Eliminate some -Wwrite-strings warnings
+	* generic/tclLink.c:
+
+2008-10-27  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclEncoding.c:	Use "iso8859-1" and not "identity" as
+	the default and original [encoding system] value. Since "iso8859-1" is
+	built in to the C source code for Tcl now, there's no availability
+	issue, and it has the good feature of "identity" that we must have
+	("bytes in" == "bytes out") without the bad feature of "identity"
+	("broken as designed") that makes us want to abandon it. [RFE 2008609]
+	*** POTENTIAL INCOMPATIBILITY for older releases of Tclkit and any
+	other code expecting a particular value for Tcl's default system
+	encoding ***
+
+2008-10-24  Pat Thoyts  <patthoyts@users.sourceforge.net>
+
+	* library/http/http.tcl: Fixed a failure to read SHOUTcast streams
+	with the new 2.7 package. Introduced a new intial state as the first
+	response may not be HTTP*.
+
+2008-10-23  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclCmdAH.c (ForNextCallback): handle TCL_CONTINUE in the for
+	body. [Bug 2186888]
+
+2008-10-22  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tcl.h:	      CONST -> const and white-spacing
+	* generic/tclCompile.h:
+	* generic/tclEncoding.c:
+	* generic/tclStubInit.c:
+	* generic/tclStubLib.c:
+	* generic/tcl.decls
+	* generic/tclInt.decls
+	* generic/tclTomMath.decls
+	* generic/tclDecls.h:	      (regenerated)
+	* generic/tclIntDecls.h:      (regenerated)
+	* generic/tclIntPlatDecls.h:  (regenerated)
+	* generic/tclOODecls.h:	      (regenerated)
+	* generic/tclOOIntDecls.h:    (regenerated)
+	* generic/tclPlatDecls.h:     (regenerated)
+	* generic/tclTomMathDecls.h:  (regenerated)
+	* generic/tclIntDecls.h:      (regenerated)
+	* tools/genStubs.tcl:	      CONST -> const and white-spacing
+
+2008-10-19  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclProc.c:	Reset -level and -code values to defaults
+	after they are used. [Bug 2152286]
+
+2008-10-19  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclBasic.c (TclInfoCoroutineCmd): Added code to make this
+	check for being invoked in a syntactically correct way.
+
+	* doc/info.n: Added documentation of [info coroutine].
+
+	* doc/prefix.n: Improved the documentation by fixing formatting,
+	adding good-practice recommendations and cross-references, etc.
+
+2008-10-17  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tclOO.decls:		CONST -> const.
+	* generic/tclOODecls.h:		(regenerated)
+	* generic/tclOOIntDecls.h:	(regenerated)
+
+2008-10-17  Andreas Kupries  <andreask@activestate.com>
+
+	* generic/tclIORTrans.c (DeleteReflectedTransformMap): Removed debug
+	output in C++ comment.
+
+2008-10-17  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclCompile.h:	Declare the internal tclInstructionTable to
+	* generic/tclExecute.c:	simply be "const", not CONST86.
+
+	* generic/tclCmdAH.c:	whitespace.
+	* generic/tclCmdIL.c:	Uninitialized variable warning.
+	* generic/tclTest.c:	const correctness warning.
+
+2008-10-17  Donal K. Fellows  <dkf@users.sf.net>
+
+	* doc/*: Many very small formatting fixes.
+	* doc/{glob,http,if}.n: More substantial reformatting for clarity.
+	* doc/split.n: Remove mention of defunct c.l.t.announce
+
+2008-10-16  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/regc_locale.c: Add "const" to many internal const tables.
+	* generic/tclClock.c:	 No functional or API change.
+	* generic/tclCmdIL.c
+	* generic/tclConfig.c
+	* generic/tclDate.c
+	* generic/tclEncoding.c
+	* generic/tclEvent.c
+	* generic/tclExecute.c
+	* generic/tclFileName.c
+	* generic/tclGetDate.y
+	* generic/tclInterp.c
+	* generic/tclIO.c
+	* generic/tclIOCmd.c
+	* generic/tclIORChan.c
+	* generic/tclIORTrans.c
+	* generic/tclLoad.c
+	* generic/tclObj.c
+	* generic/tclOOBasic.c
+	* generic/tclOOCall.c
+	* generic/tclOOInfo.c
+	* generic/tclPathObj.c
+	* generic/tclPkg.c
+	* generic/tclResult.c
+	* generic/tclStringObj.c
+	* generic/tclTest.c
+	* generic/tclTestObj.c
+	* generic/tclThreadTest.c
+	* generic/tclTimer.c
+	* generic/tclTrace.c
+	* macosx/tclMacOSXFCmd.c
+	* win/cat.c
+	* win/tclWinInit.c
+	* win/tclWinTest.c
+
+2008-10-16  Don Porter  <dgp@users.sourceforge.net>
+
+	* library/init.tcl:	Revised [unknown] so that it carefully
+	preserves the state of the ::errorInfo and ::errorCode variables at
+	the start of auto-loading and restores that state before the
+	autoloaded command is evaluated. [Bug 2140628]
+
+2008-10-15  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tclInt.h:	Add "const" to many internal const tables, so
+	* generic/tclBinary.c:	those will be put by the C-compiler in the
+	* generic/tclCompile.c:	TEXT segment in stead of the DATA segment.
+	* generic/tclDictObj.c: This makes those tables sharable in shared
+	* generic/tclHash.c:	libraries.
+	* generic/tclListObj.c:
+	* generic/tclNamesp.c:
+	* generic/tclObj.c:
+	* generic/tclProc.c:
+	* generic/tclRegexp.c:
+	* generic/tclStringObj.c:
+	* generic/tclUtil.c:
+	* generic/tclVar.c:
+
+2008-10-14  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tclCmdAH.c:	Fix minor compiler warnings when compiling
+	* generic/tclCmdMZ.c:	with -Wwrite-strings.
+	* generic/tclIndexObj.c:
+	* generic/tclProc.c:
+	* generic/tclStubLib.c:
+	* generic/tclUtil.c:
+	* win/tclWinChan.c:
+	* win/tclWinDde.c:
+	* win/tclWinInit.c:
+	* win/tclWinReg.c:
+	* win/tclWinSerial.c:
+
+2008-10-14  Donal K. Fellows  <dkf@users.sf.net>
+
+	* doc/binary.n: Formatting fix.
+
+2008-10-14  Don Porter  <dgp@users.sourceforge.net>
+
+	* README:		Bump version number to 8.6a4
+	* generic/tcl.h:
+	* library/init.tcl:
+	* tools/tcl.wse.in:
+	* unix/configure.in:
+	* unix/tcl.spec:
+	* win/configure.in:
+
+	* unix/configure:	autoconf-2.59
+	* win/configure:
+
+	* generic/tclExecute.c:	Fix compile warnings when --enable-symbols=all
+
+	* generic/tclCmdIL.c:	Fix write to unallocated memory whenever
+	[lrepeat] returns an empty list.
+
+2008-10-14  Donal K. Fellows  <dkf@users.sf.net>
+
+	* doc/chan.n, doc/fconfigure.n: Added even more emphatic text to
+	direct people to the correct manual pages for specific channel types,
+	suitable for the hard-of-reading. Following discussion on tcl-core.
+
+2008-10-13  Pat Thoyts  <patthoyts@users.sourceforge.net>
+
+	* win/tclWinThrd.c (TclpThreadCreate): We need to initialize the
+	thread id variable to 0 as on 64 bit windows this is a pointer sized
+	field while windows only fills it with a 32 bit value. The result is
+	an inability to join the threads as the ids cannot be matched.
+
+	* generic/tclTest.c (TestNRELevels): Set array to the right size.
+
+2008-10-13  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclOOInfo.c (InfoClassDestrCmd): Handle error case.
+
+	* generic/tclOOInt.h: Added macro magic to make things work with
+	Objective C. [Bug 2163447]
+
+2008-10-12  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclCompile.c: Fix bug in srcDelta encoding within ByteCodes.
+	The bug can only be triggered under conditions that cannot happen in
+	Tcl, but were met during development of L. Thanks go to Robert Netzer
+	for diagnosis and fix.
+
+2008-10-10  Don Porter  <dgp@users.sourceforge.net>
+
+	*** 8.6a3 TAGGED FOR RELEASE ***
+
+	* changes:	Updates for 8.6a3 release.
+
+2008-10-10  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclOODefineCmds.c (TclOODefineUnexportObjCmd)
+	(TclOODefineExportObjCmd): Corrected export/unexport record synthesis.
+	[Bug 2155658]
+
+2008-10-08  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* unix/tclUnixChan.c:	Fix minor compiler warning.
+	* unix/tcl.m4:		Fix for [Bug 2073255]
+	* unix/configure:	Regenerated
+
+2008-10-08  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclBasic (TclInfoCoroutineCmd):
+	* tests/unsupported.test: Arrange for [info coroutine] to return {}
+	when a coroutine is running but the resume command has been deleted.
+	[Bug 2153080]
+
+2008-10-08  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclTrace.c:	Corrected handling of errors returned by
+	variable traces so that the errorInfo value contains the original
+	error message. [Bug 2151707]
+
+	* generic/tclVar.c:	Revised implementation of TclObjVarErrMsg so
+	that error message construction does not disturb an existing
+	iPtr->errorInfo that may be in progress.
+
+2008-10-07  Donal K. Fellows  <dkf@users.sf.net>
+
+	* doc/binary.n: Added better documentation of the [binary encode] and
+	[binary decode] subcommands.
+
+2008-10-07  Miguel Sofer  <msofer@users.sf.net>
+
+	TIP #327,#328 IMPLEMENTATIONS
+
+	* generic/tclBasic.c:	   Move [tailcall], [coroutine] and
+	* generic/tclCmdIL.c:	   [yield] out of ::tcl::unsupported
+	* tclInt.h:
+	* tests/info.test:	   and into global scope: TIPs #327
+	* tests/unsupported.test:  and #328
+
+2008-10-07  Donal K. Fellows  <dkf@users.sf.net>
+
+	* doc/chan.n, doc/transchan.n: Documented the channel transformation
+	API of TIP #230.
+
+2008-10-06  Pat Thoyts  <patthoyts@users.sourceforge.net>
+
+	* tests/winFCmd.test: Fixed some erroneous tests on Vista+.
+	* generic/tclFCmd.c: Fix constness for msvc of last commit
+
+2008-10-06  Joe Mistachkin  <joe@mistachkin.com>
+
+	* tools/man2tcl.c: Added missing line from patch by Harald Oehlmann.
+	[Bug 1934200]
+
+2008-10-05  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* doc/FileSystem.3:	CONSTified Tcl_FSFileAttrStringsProc
+	* generic/tclFCmd.c:	and tclpFileAttrStrings. This allows
+	* generic/tclIOUtil.c:	FileSystems to report their attributes
+	* generic/tclTest.c:	as const strings, without worrying that
+	* unix/tclUnixFCmd.c:	Tcl modifies them (which Tcl should not
+	* win/tclWinFCmd.c:	do anyway, but the API didn't indicate that)
+	* generic/tcl.decls
+	* generic/tclDecls.h:	regenerated
+	* generic/tcl.h:	Make sure that if CONST84 is defined as empty,
+				CONST86 should be defined as empty as well
+				(unless overridden). This change complies with
+				TIP #27
+	*** POTENTIAL INCOMPATIBILITY ***
+
+2008-10-05  Kevin B, Kenny  <kennykb@acm.org>
+
+	* libtommath/bn_mp_sqrt.c (bn_mp_sqrt): Handle the case where a
+	* tests/expr.test (expr-47.13):		number's square root is
+	between n<<DIGIT_BIT and n<<DIGIT_BIT+1. [Bug 2143288]
+	Thanks to Malcolm Boffey (malcolm.boffey@virgin.net) for the patch.
+
+	TIP #331 IMPLEMENTATION
+
+	* doc/lset.n:
+	* generic/tclListObj.c (TclLsetFlat):
+	* tests/lset.test: Modified the [lset] command so that it allows for
+	an index of 'end+1', which has the effect of appending an element to
+	the list.
+
+2008-10-05  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tclInt.decls:	 CONSTified the AuxDataType argument
+	* generic/tclCompCmds.c: of TclCreateAuxData and
+	* generic/tclCompile.c:	 TclRegisterAuxDataType and the return
+	* generic/tclCompile.h:	 values of TclGetAuxDataType and
+	* generic/tclExecute.c:	 TclGetInstructionTable
+	* generic/tclIntDecls.h:		regenerated
+	This change complies with TIP #27 (even though it only involves
+	internal function, so this is not even necessary).
+
+2008-10-05  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclIndexObj.c (TclInitPrefixCmd): Make the [tcl::prefix]
+	into an exported command. [Bug 2144595]
+
+2008-10-04  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclCmdIL.c (InfoFrameCmd):	Improved hygiene of result
+	* generic/tclRegexp.c (TclRegAbout):	handling.
+
+2008-10-04  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/tclLoad.c: Make sure that any library which doesn't have an
+	unloadproc is only really unloaded when no library code is executed
+	yet. [Bug 2059262]
+
+2008-10-04  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclOOInfo.c (GetClassFromObj): Factor out the code to parse
+	a Tcl_Obj and get a class. Also make result handling hygienic.
+	* generic/tclOOBasic.c (TclOOSelfObjCmd): Better hygiene of results,
+	and stop allocating quite so much memory by sharing special "method"
+	names.
+
+2008-10-04  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* doc/ChnlStack.3:	CONSTified the typePtr argument
+	* doc/CrtChannel.3:	of Tcl_CreateChannel and Tcl_StackChannel
+	* generic/tcl.decls:	and the return value of Tcl_GetChannelType
+	* generic/tcl.h
+	* generic/tclIO.h
+	* generic/tclIO.c
+	* generic/tclDecls.h:	regenerated
+	This change complies with TIP #27.
+
+	* doc/Hash.3:		CONSTified the typePtr argument
+	* generic/tcl.decls:	of Tcl_InitCustomHashTable.
+	* generic/tcl.h
+	* generic/tclHash.c
+	* generic/tclDecls.h:	regenerated
+	This change complies with TIP #27.
+
+	* doc/RegConfig.3:	CONSTified the configuration argument
+	* generic/tcl.decls:	of Tcl_RegisterConfig.
+	* generic/tcl.h
+	* generic/tclConfig.c
+	* generic/tclPkgConfig.c
+	* generic/tclDecls.h:	regenerated
+	This change complies with TIP #27.
+
+	* doc/GetIndex.3:	CONSTified the tablePtr argument
+	* generic/tcl.decls:	of Tcl_GetIndexFromObj.
+	* generic/tclIndexObj.c
+	* generic/tclDecls.h:	regenerated
+	This change complies with TIP #27.
+
+2008-10-03  Miguel Sofer  <msofer@users.sf.net>
+
+	* tests/stack.test:
+	* unix/tclUnixTest.c: Removed test command teststacklimit and the
+	corresponding constraint: it is not needed with NRE
+
+2008-10-03  Donal K. Fellows  <dkf@users.sf.net>
+
+	TIP #195 IMPLEMENTATION
+
+	* generic/tclIndexObj.c (TclGetIndexFromObjList, PrefixMatchObjCmd)
+	* doc/prefix.n, tests/string.test: Added [tcl::prefix] command for
+	working with prefixes of strings at the Tcl level. [Patch 1040206]
+
+	TIP #265 IMPLEMENTATION
+
+	* generic/tclIndexObj.c (Tcl_ParseArgsObjv, PrintUsage):
+	* generic/tcl.h (Tcl_ArgvInfo):	Added function for simple parsing of
+	* doc/ParseArgs.3 (new file):	optional arguments to commands. Still
+	needs tests and the like. [FRQ 1446696] Note that some of the type
+	signatures are changed a bit from the proposed implementation so that
+	they better reflect codified good practice for argument order.
+
+2008-10-02  Andreas Kupries  <andreask@activestate.com>
+
+	* tests/info.test (info-23.3): Updated output of the test to handle
+	the NRE-enabled eval and the proper propagation of location
+	information through it. [Bug 2017632]
+
+	* doc/info.n: Rephrased the documentation of 'info frame' for positive
+	numbers as level argument. [Bug 2134049]
+
+	* tests/info.test (info-22.8): Made pattern for file containing
+	tcltest less specific to accept both .tcl and .tm variants of the file
+	during matching. [Bug 2129828]
+
+2008-10-02  Don Porter  <dgp@users.sourceforge.net>
+
+	TIP #330 IMPLEMENTATION
+
+	* generic/tcl.h:	Remove the "result" and "freeProc" fields
+	* generic/tclBasic.c:	from the default public declaration of the
+	* generic/tclResult.c:	Tcl_Interp struct. Code should no longer
+	* generic/tclStubLib.c:	be accessing these fields. Access can be
+	* generic/tclTest.c:	restored by defining USE_INTERP_RESULT, but
+	* generic/tclUtil.c:	that should only be a temporary migration aid.
+	*** POTENTIAL INCOMPATIBILITY ***
+
+2008-10-02  Joe Mistachkin  <joe@mistachkin.com>
+
+	* doc/info.n: Fix unmatched font change.
+	* doc/tclvars.n: Fix unmatched font change.
+	* doc/variable.n: Fix unmatched font change.
+	* tools/man2help2.tcl: Integrated patch from Harald Oehlmann.
+	[Bug 1934272]
+	* tools/man2tcl.c: Increase MAX_LINE_SIZE to fix "Too long line" error.
+	* win/buildall.vc.bat: Prefer the HtmlHelp target over the WinHelp
+	target. [Bug 2072891]
+	* win/makefile.vc: Fix the HtmlHelp and WinHelp targets to not be
+	mutually exclusive.
+
+2008-09-29  Don Porter  <dgp@users.sourceforge.net>
+
+	TIP #323 IMPLEMENTATION (partial)
+
+	* doc/glob.n:		Revise [glob] to accept zero patterns.
+	* generic/tclFileName.c:
+	* tests fileName.test:
+
+	* doc/linsert.n:	Revise [linsert] to accept zero elements.
+	* generic/tclCmdIL.c:
+	* tests/linsert.test:
+
+2008-09-29  Donal K. Fellows  <dkf@users.sf.net>
+
+	TIP #326 IMPLEMENTATION
+
+	* generic/tclCmdIL.c (Tcl_LsortObjCmd): Added -stride option to carry
+	* doc/lsort.n, tests/cmdIL.test:	out sorting of lists where the
+	elements are grouped. Adapted from [Patch 2082681]
+
+	TIP #313 IMPLEMENTATION
+
+	* generic/tclCmdIL.c (Tcl_LsearchObjCmd): Added -bisect option to
+	* doc/lsearch.n, tests/lsearch.test:	  allow the finding of the
+	place to insert an element in a sorted list when that element is
+	not already there. [Patch 1894241]
+
+	TIP #318 IMPLEMENTATION
+
+	* generic/tclCmdMZ.c (StringTrimCmd,StringTrimLCmd,StringTrimRCmd):
+	Update the default set of trimmed characters to include some from the
+	larger UNICODE space. Factor out the default trim set into a macro so
+	that it is easier to keep them in synch.
+
+2008-09-28  Donal K. Fellows  <dkf@users.sf.net>
+
+	TIP #314 IMPLEMENTATION
+
+	* generic/tclCompCmds.c (TclCompileEnsemble)
+	* generic/tclNamesp.c (NamespaceEnsembleCmd)
+	(Tcl_SetEnsembleParameterList, Tcl_GetEnsembleParameterList)
+	(NsEnsembleImplementationCmdNR):
+	* generic/tcl.decls, doc/Ensemble.3, doc/namespace.n
+	* tests/namespace.test: Allow the handling of a (fixed) number of
+	formal parameters between an ensemble's command and subcommand at
+	invokation time. [Patch 1901783]
+
+2008-09-28  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclBasic.c:	   Fix the numLevels computations on
+	* generic/tclInt.h:	   coroutine yield/resume
+	* tests/unsupported.test:
+
+2008-09-27  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclFileName.c (Tcl_GetBlock*FromStat): Made this work
+	acceptably when working with OSes that don't support reporting the
+	block size from the stat() call. [Bug 2130726]
+
+	* generic/tclCmdIL.c (Tcl_LrepeatObjCmd): Improve the handling of the
+	case where the combination of number of elements and repeat count
+	causes the resulting list to be too large. [Bug 2130992]
+
+2008-09-26  Don Porter  <dgp@users.sourceforge.net>
+
+	TIP #323 IMPLEMENTATION (partial)
+
+	* doc/lrepeat.n:	Revise [lrepeat] to accept both zero
+	* generic/tclCmdIL.c:	repetitions and zero elements to be repeated.
+	* tests/lrepeat.test:
+
+	* doc/object.n:		Revise standard oo method [my variable] to
+	* generic/tclOOBasic.c:	accept zero variable names.
+	* tests/oo.test:
+
+	* doc/tm.n:		Revise [tcl::tm::path add] and
+	* library/tm.tcl:	[tcl::tm::path remove] to accept zero paths.
+	* tests/tm.test:
+
+	* doc/namespace.n:	Revise [namespace upvar] to accept zero
+	* generic/tclNamesp.c:	variable names.
+	* tests/upvar.test:
+
+	* doc/lassign.n:	Revise [lassign] to accept zero variable names.
+	* generic/tclCmdIL.c:
+	* tests/cmdIL.test:
+
+2008-09-26  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclOO.h (TCLOO_VERSION): Bump the version.
+
+2008-09-25  Don Porter  <dgp@users.sourceforge.net>
+
+	TIP #323 IMPLEMENTATION (partial)
+
+	* doc/global.n:		Revise [global] to accept zero variable names.
+	* doc/variable.n:	Revise [variable] likewise.
+	* generic/tclVar.c:
+	* tests/proc-old.test:
+	* tests/var.test:
+
+	* doc/global.n: Correct false claim about [info locals].
+
+2008-09-25  Donal K. Fellows  <dkf@users.sf.net>
+
+	TIP #315 IMPLEMENTATION
+
+	* tests/platform.test:	Update tests to expect revised results
+	* tests/safe.test:	corresponding to the TIP 315 change.
+
+	* unix/tclUnixInit.c, win/tclWinInit.c (TclpSetVariables):
+	* doc/tclvars.n (tcl_platform): Define what character is used for
+	separating PATH-like lists. Forms part of the tcl_platform array.
+
+	* generic/tclOOCall.c (InitCallChain, IsStillValid):
+	* tests/oo.test (oo-25.2): Revise call chain cache management so that
+	it takes into account class-wide caching correctly. [Bug 2120903]
+
+2008-09-24  Don Porter  <dgp@users.sourceforge.net>
+
+	TIP #323 IMPLEMENTATION (partial)
+
+	* doc/file.n:		Revise [file delete] and [file mkdir] to
+	* generic/tclCmdAH.c:	accept zero "pathname" arguments (the
+	* generic/tclFCmd.c:	no-op case).
+	* tests/cmdAH.test:
+	* tests/fCmd.test:
+
+2008-09-24  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclOOMethod.c (DBPRINT): Remove obsolete debugging macro.
+	[Bug 2124814]
+
+	TIP #316 IMPLEMENTATION
+
+	* generic/tcl.decls, generic/tclFileName.c (Tcl_GetSizeFromStat, etc):
+	* doc/FileSystem.3: Added reader functions for Tcl_StatBuf.
+
+2008-09-23  Donal K. Fellows  <dkf@users.sf.net>
+
+	* doc/Method.3: Corrected documentation. [Patch 2082450]
+
+	* doc/lreverse.n, mathop.n, regexp.n, regsub.n: Make sure that the
+	initial line of the manpage includes nothing that chokes old versions
+	of man. [Bug 2118123]
+
+2008-09-22  Donal K. Fellows  <dkf@users.sf.net>
+
+	TIP #320 IMPLEMENTATION
+
+	* generic/tclOODefineCmds.c (TclOODefineVariablesObjCmd):
+	* generic/tclOOInfo.c (InfoObjectVariablesCmd, InfoClassVariablesCmd):
+	* generic/tclOOMethod.c (TclOOSetupVariableResolver, etc):
+	* doc/define.n, doc/ooInfo.n, benchmarks/cps.tcl:
+	* tests/oo.test (oo-26.*): Allow the declaration of the common
+	variables used in methods of a class or object. These are then mapped
+	in using a variable resolver. This makes many class declarations much
+	simpler overall, encourages good usage of variable names, and also
+	boosts speed a bit.
+
+	* generic/tclOOMethod.c (TclOOGetMethodBody): Factor out the code to
+	get the body of a procedure-like method. Reduces the amount of "poking
+	inside the abstraction" that is done by the introspection code.
+
+2008-09-22  Alexandre Ferrieux  <ferrieux@users.sourceforge.net>
+
+	* doc/chan.n: Clean up paragraph order.
+
+2008-09-18  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclExecute.c (NEXT_INST_F):
+	* generic/tclInt.h (TCL_CT_ASSERT): New compile-time assertions,
+	adapted from www.pixelbeat.org/programming/gcc/static_assert.html
+
+2008-09-17  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclInt.h: Correct the TclGetLongFromObj, TclGetIntFromObj,
+	and TclGetIntForIndexM macros so that they retrieve the longValue
+	field from the internalRep instead of casting the otherValuePtr field
+	to type long.
+
+2008-09-17  Miguel Sofer  <msofer@users.sf.net>
+
+	* library/init.tcl: Export min and max commands from the mathfunc
+	namespace. [Bug 2116053]
+
+2008-09-16  Joe Mistachkin  <joe@mistachkin.com>
+
+	* generic/tclParse.c: Move TclResetCancellation to be called on
+	returning to level 0, as opposed to it being called on starting a
+	substitution at level 0.
+
+2008-09-16  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclBasic.c: Move TclResetCancellation to be called on
+	returning to level 0, as opposed to it being called on starting a
+	command at level 0. Add a call on returning via Tcl_EvalObjEx to fix
+	[Bug 2114165].
+
+2008-09-10  Donal K. Fellows  <dkf@users.sf.net>
+
+	* doc/binary.n: Added partial documentation of [binary encode] and
+	[binary decode].
+
+	* tests/binary.test,cmdAH.test,cmdIL.test,cmdMZ.test,fileSystem.test:
+	More use of tcltest2 to simplify the tests as exposed to people.
+	* tests/compile.test (compile-18.*): Added *some* tests of the
+	disassmbler, though not of its output format.
+
+2008-09-10  Miguel Sofer  <msofer@users.sf.net>
+
+	* tests/nre.test: Add missing constraints; enable test of foreach
+	recursion.
+
+	* generic/tclBasic.c:
+	* generic/tclCompile.h:
+	* generic/tclExecute.c (INST_EVAL_STK): Wrong numLevels when evaling a
+	canonical list. [Bug 2102930]
+
+2008-09-10  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclListObj.c (Tcl_ListObjGetElements): Make this list->dict
+	transformation - encountered when using [foreach] with dicts - not as
+	expensive as it was before. Spotted by Kieran Elby and reported on
+	tcl-core.
+
+2008-09-08  Donal K. Fellows  <dkf@users.sf.net>
+
+	* tests/append.test, appendComp.test, cmdAH.test: Use the powers of
+	tcltest2 to make these files simpler.
+
+2008-09-07  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclCompile.c (TclCompileTokens):
+	* generic/tclExecute.c (CompileExprObj): Fix a perf bug (found by Alex
+	Ferrieux) where some variables in the LVT where not being accessed by
+	index. Fix missing localCache management in compiled expressions found
+	while analyzing the bug.
+
+2008-09-07  Miguel Sofer  <msofer@users.sf.net>
+
+	* doc/namespace.n: Fix [Bug 2098441]
+
+2008-09-04  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclTrace.test (TraceVarProc):
+	* generic/unsupported.test: Insure that unset traces are run even when
+	the coroutine is unwinding. [Bug 2093947]
+
+	* generic/tclExecute.c (CACHE_STACK_INFO):
+	* tests/unsupported.test: Restore execEnv's bottomPtr. [Bug 2093188]
+
+2008-09-02  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tcl.h:	Stripped "callers" of the _ANSI_ARGS_ macro
+	* compat/dirent2.h:	to support a TCL_NO_DEPRECATED build.
+	* compat/dlfcn.h:
+	* unix/tclUnixPort.h:
+
+	* generic/tcl.h:	Removed the conditional #define of
+	_ANSI_ARGS_ that would support pre-prototype C compilers. Since
+	_ANSI_ARGS_ is no longer used in tclDecls.h, it's clear no one
+	compiling against Tcl 8.5 headers is making use of a -DNO_PROTOTYPES
+	configuration.
+
+2008-09-02  Donal K. Fellows  <dkf@users.sf.net>
+
+	* tests/socket.test: Rewrote so as to use tcltest2 better.
+
+2008-09-01  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclCmdAH.c:	   NRE-enabling [eval]; eval scripts are now
+	* generic/tclOOBasic.c:	   bytecompiled. Adapted recursion limit tests
+	* tests/interp.test:	   that were relying on eval not being
+	* tests/nre.test:	   compiled. Part of the [Bug 2017632] project.
+	* tests/unsupported.test:
+
+2008-09-01  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclOOMethod.c (InvokeProcedureMethod):
+	* generic/tclOO.c (ObjectRenamedTrace): Arrange for only methods that
+	involve callbacks into the Tcl interpreter to be skipped when the
+	interpreter is being torn down. Allows the semantics of destructors in
+	a dying interpreter to be more useful when they're implemented in C.
+
+2008-08-29  Donal K. Fellows  <dkf@users.sf.net>
+
+	* unix/Makefile.in: Ensure that all TclOO headers get installed.
+	* win/Makefile.in:  [Bug 2082299]
+	* win/makefile.bc:
+	* win/makefile.vc:
+
+2008-08-28  Don Porter  <dgp@users.sourceforge.net>
+
+	* README:		Bump version number to 8.6a3
+	* generic/tcl.h:
+	* library/init.tcl:
+	* tools/tcl.wse.in:
+	* unix/configure.in:
+	* unix/tcl.spec:
+	* win/configure.in:
+
+	* unix/configure:	autoconf-2.59
+	* win/configure:
+
+2008-08-27  Donal K. Fellows  <dkf@users.sf.net>
+
+	* doc/tclvars.n, doc/library.n: Ensured that these two manual pages
+	properly cross-reference each other. Issue reported on Tcler's Chat.
+
+2008-08-26  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclBasic.c (InfoCoroutine):
+	* tests/unsupported.test: New command that returns the FQN of the
+	currently executing coroutine. Lives as infoCoroutine under
+	unsupported, but is designed to become a subcommand of [info]
+
+2008-08-23  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclBasic.c (NRInterpCoroutine): Store the caller's eePtr,
+	stop assuming the coroutine is invoked from the same execEnv where it
+	was created.
+
+2008-08-24  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclCmdAH.c (TclNRForeachCmd): Converted the [foreach]
+	command to have an NRE-aware non-compiled implementation. Part of the
+	[Bug 2017632] project. Also restructured the code so as to manage its
+	temporary memory more efficiently.
+
+2008-08-23  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclBasic.c:	  Removed unused var; fixed function pointer
+	* generic/tclOOInt.h:	  declarations (why did gcc start complaining
+	* generic/tclOOMethod.c:  all of a sudden?)
+	* generic/tclProc.c:
+
+2008-08-23  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclInt.h (EnsembleImplMap): Added extra field to make it
+	* generic/tclNamesp.c (TclMakeEnsemble): easier to build non-recursive
+	ensembles in the core.
+
+	* generic/tclDictObj.c (DictForNRCmd): Converted the [dict for]
+	command to have an NRE-aware non-compiled implementation. Part of the
+	[Bug 2017632] project.
+
+2008-08-22  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclBasic.c:
+	* generic/tclExecute.c: Set special errocodes: COROUTINE_BUSY,
+	COROUTINE_CANT_YIELD, COROUTINE_ILLEGAL_YIELD.
+
+2008-08-22  Don Porter  <dgp@users.sourceforge.net>
+
+	*** 8.6a2 TAGGED FOR RELEASE ***
+
+	* changes:	Updates for 8.6a2 release.
+
+	* generic/tcl.h:	Drop use of USE_COMPAT85_CONST. That added
+	indirection without value. Use -DCONST86="" to engage source compat
+	support for code written for 8.5 headers.
+
+	* generic/tclUtil.c (TclReToGlob):	Added missing set of the
+	*exactPtr value to really fix [Bug 2065115]. Also avoid possible
+	DString overflow.
+	* tests/regexpComp.test:	Correct duplicate test names.
+
+2008-08-21  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclBasic.c:	  Previous fix, now done right.
+	* generic/tclCmdIL.c:
+	* generic/tclInt.h:
+	* tests/unsupported.test:
+
+2008-08-21  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* tests/regexp.test, tests/regexpComp.test: Correct re2glob ***=
+	* generic/tclUtil.c (TclReToGlob):	    translation from exact
+	to anywhere-in-string match. [Bug 2065115]
+
+2008-08-21  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tcl.h:	Reduced the use of CONST86 and eliminated
+	* generic/tcl.decls:	the use of CONST86_RETURN to support source
+	code compatibility with Tcl 8.5 on those public routines passing
+	(Tcl_Filesystem *), (Tcl_Timer *), and (Tcl_Objtype *) values which
+	have been const-ified. What remains is the minimum configurability
+	needed to support code written for pre-8.6 headers via the new
+	-DUSE_COMPAT85_CONST compiler directive.
+	*** POTENTIAL INCOMPATIBILITY ***
+
+	* generic/tclDecls.h:	make genstubs
+
+2008-08-21  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclBasic.c:	Fix the cmdFrame level count in
+	* generic/tclCmdIL.c:	coroutines. Fix small bug on coroutine
+	* generic/tclInt.h:	rewind.
+
+2008-08-21  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclProc.c (Tcl_DisassembleObjCmd): Added ability to
+	disassemble TclOO methods. The code to do this is very ugly.
+
+2008-08-21  Pat Thoyts  <patthoyts@users.sourceforge.net>
+
+	* generic/tclOOMethod.c: Added casts to make MSVC happy
+	* generic/tclBasic.c:
+
+2008-08-20  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclOO.c (AllocObject): Suppress compilation of commands in
+	the namespace allocated for each object.
+	* generic/tclOOMethod.c (PushMethodCallFrame): Restore some of the
+	hackery that makes calling methods of classes fast. Fixes performance
+	problem introduced by the fix of [Bug 2037727].
+
+	* generic/tclCompile.c (TclCompileScript):    Allow the suppression of
+	* generic/tclInt.h (NS_SUPPRESS_COMPILATION): compilation of commands
+	* generic/tclNamesp.c (Tcl_CreateNamespace):  from a namespace or its
+	children.
+
+2008-08-20  Daniel Steffen  <das@users.sourceforge.net>
+
+	* generic/tclTest.c (TestconcatobjCmd):	Fix use of internal-only
+	TclInvalidateStringRep macro. [Bug 2057479]
+
+2008-08-17  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclBasic.c:	   Implementation of [coroutine] and [yield]
+	* generic/tclCmdAH.c:	   commands (in tcl::unsupported).
+	* generic/tclCompile.h:
+	* generic/tclExecute.c:
+	* generic/tclInt.h:
+	* tests/unsupported.test:
+
+	* generic/tclTest.c (TestconcatobjCmd):
+	* generic/tclUtil.c (Tcl_ConcatObj):
+	* tests/util.test (util-4.7):
+	Fix [Bug 1447328]; the original "fix" turned Tcl_ConcatObj() into a
+	hairy monster. This was exposed by [Bug 2055782]. Additionally,
+	Tcl_ConcatObj could corrupt its input under certain conditions!
+
+	*** NASTY BUG FIXED ***
+
+2008-08-16  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclExecute.c: Better cmdFrame management
+
+2008-08-14  Don Porter  <dgp@users.sourceforge.net>
+
+	* tests/fileName.test:	Revise new tests for portability to case
+	insensitive filesystems.
+
+2008-08-14  Daniel Steffen  <das@users.sourceforge.net>
+
+	* generic/tclBasic.c (TclNREvalObjv, Tcl_NRCallObjProc):
+	* generic/tclProc.c (TclNRInterpProcCore, InterpProcNR2):
+	DTrace probes for NRE. [Bug 2017160]
+
+	* generic/tclBasic.c (TclDTraceInfo):	Add two extra arguments to
+	* generic/tclCompile.h:			DTrace 'info' probes for tclOO
+	* generic/tclDTrace.d:			method & class/object info.
+
+	* generic/tclCompile.h:	Add support for debug logging of DTrace
+	* generic/tclBasic.c:	'proc', 'cmd' and 'inst' probes (does _not_
+				require a platform with DTrace).
+
+	* generic/tclCmdIL.c (TclInfoFrame):	Check fPtr->line before
+						dereferencing as line info may
+						not exists when TclInfoFrame()
+						is called from a DTrace probe.
+
+	* tests/fCmd.test (fCmd-6.23):	Made result matching robust when test
+					workdir and /tmp are not on same FS.
+
+	* unix/tclUnixThrd.c:		Remove unused TclpThreadGetStackSize()
+	* generic/tclInt.h:		and related ifdefs and autoconf tests.
+	* unix/tclUnixPort.h:		[Bug 2017264] (jenglish)
+	* unix/tcl.m4:
+
+	* unix/Makefile.in:		Ensure Makefile shell is /bin/bash for
+	* unix/configure.in (SunOS):	DTrace-enabled build on Solaris.
+					(followup to 2008-06-12) [Bug 2016584]
+
+	* unix/tcl.m4 (SC_PATH_X):	Check for libX11.dylib in addition to
+					libX11.so et al.
+
+	* unix/configure:		autoconf-2.59
+	* unix/tclConfig.h.in:		autoheader-2.59
+
+2008-08-13  Miguel Sofer  <msofer@users.sf.net>
+
+	* tests/nre.test: Added test for large {*}-expansion effects
+
+2008-08-13  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclFileName.c:	Fix for errors handling -types {}
+	* tests/fileName.test:		option to [glob]. [Bug 1750300]
+	Thanks to Matthias Kraft and George Peter Staplin.
+
+2008-08-12  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* generic/tclOOInfo.c (InfoObjectDefnCmd, InfoObjectMixinsCmd):
+	Fix # args displayed. [Bug 2048676]
+
+2008-08-08  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclOOMethod.c (PushMethodCallFrame):	Added missing check
+	for bytecode validity. [Bug 2037727]
+
+	* generic/tclProc.c (TclProcCompileProc):	On recompile of a
+	proc, clear away any entries on the CompiledLocal list from the
+	previous compile. This will prevent compile of temporary variables in
+	the proc body from growing the localCache arbitrarily large.
+
+	* README:		Bump version number to 8.6a2
+	* generic/tcl.h:
+	* library/init.tcl:
+	* tools/tcl.wse.in:
+	* unix/configure.in:
+	* unix/tcl.spec:
+	* win/configure.in:
+
+	* unix/configure:	autoconf-2.59
+	* win/configure:
+
+	* changes:	Updates for 8.6a2 release.
+
+2008-08-11  Pat Thoyts  <patthoyts@users.sourceforge.net>
+
+	* library/http/http.tcl: Remove 8.5 requirement.
+	* library/http/pkgIndex.tcl:
+	* unix/Makefile.in:
+	* win/Makefile.in:
+	* win/makefile.vc:
+
+2008-08-11  Andreas Kupries  <andreask@activestate.com>
+
+	* library/tm.tcl: Added a 'package provide' command to the generated
+	ifneeded scripts of Tcl Modules, for early detection of conflicts
+	between the version specified through the file name and a 'provide'
+	command in the module implementation, if any. Note that this change
+	also now allows Tcl Modules to not provide a 'provide' command at all,
+	and declaring their version only through their filename.
+
+	* generic/tclProc.c (Tcl_ProcObjCmd): Fixed memory leak triggered by
+	* tests/proc.test: procbody::test::proc. See [Bug 2043636]. Added a
+	test case demonstrating the leak before the fix. Fixed a few spelling
+	errors in test descriptions as well.
+
+2008-08-11  Don Porter  <dgp@users.sourceforge.net>
+
+	* library/http/http.tcl:	Bump http version to 2.7.1 to account
+	* library/http/pkgIndex.tcl:	for [Bug 2046486] bug fix. This
+	* unix/Makefile.in:		release of http now requires a
+	* win/Makefile.in:		dependency on Tcl 8.5 to be able to
+	* win/makefile.bc:		use the unsigned formats in the
+	* win/makefile.vc:		[binary scan] command.
+
+2008-08-11  Pat Thoyts  <patthoyts@users.sourceforge.net>
+
+	* library/http/http.tcl: CRC field from zlib data should be treated as
+	unsigned for 64bit support. [Bug 2046846]
+
+2008-08-10  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclProc.c: Completely removed ProcCompileProc, which was a
+	fix for [Bug 1482718]. This is not needed at least since varReform,
+	where the local variable data at runtime is read from the CallFrame
+	and/or the LocalCache.
+
+2008-08-09  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclBasic.c:	Slight cleanup
+	* generic/tclCompile.h:
+	* generic/tclExecute.c:
+
+2008-08-09  Daniel Steffen  <das@users.sourceforge.net>
+
+	* generic/tclExecute.c:	Fix warnings.
+
+	* generic/tclOOMethod.c (PushMethodCallFrame):	Fix uninitialized efi
+							name field.
+
+	* tests/lrange.test (lrange-1.17):	Add test cleanup; whitespace.
+
+2008-08-08  Don Porter  <dgp@users.sourceforge.net>
+
+	* changes:	Updates for 8.6a2 release.
+
+2008-08-08  Kevin Kenny  <kennykb@acm.org>
+
+	* library/tzdata/CET:
+	* library/tzdata/MET:
+	* library/tzdata/Africa/Casablanca:
+	* library/tzdata/America/Eirunepe:
+	* library/tzdata/America/Rio_Branco:
+	* library/tzdata/America/Santarem:
+	* library/tzdata/America/Argentina/San_Luis:
+	* library/tzdata/Asia/Karachi:
+	* library/tzdata/Europe/Belgrade:
+	* library/tzdata/Europe/Berlin:
+	* library/tzdata/Europe/Budapest:
+	* library/tzdata/Europe/Sofia:
+	* library/tzdata/Indian/Mauritius:  Olson's tzdata2008e.
+
+2008-08-07  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclBasic.c:	Fix tailcalls falling out of tebc into
+	* generic/tclExecute.c: Tcl_EvalEx. [Bug 2017946]
+	* generic/tclInt.h:
+
+2008-08-06  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclOO.c:	Revised TclOO's check for an interp being
+	deleted during handling of object command deletion. The old code was
+	relying on documented features of command delete traces that do not in
+	fact work. [Bug 2039178]
+
+	* tests/oo.test (oo-26.*):	Added tests that demonstrate failure
+	of TclOO to check for various kinds of invalid bytecode during method
+	dispatch. [Bug 2037727]
+
+2008-08-06  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclVar.c (TclLookupSimpleVar): Fix bug that the core could
+	not trigger before TclOO: the number of locals was being read from the
+	Proc, which can under some circumstance be out of sync with the
+	localCache's. Found by dgp while investigating [Bug 2037727].
+
+	* library/init.tcl (::unknown): Removed the [namespace inscope]
+	hack that was maintained for Itcl
+
+	*** POTENTIAL INCOMPATIBILITY *** for Itcl
+	Itcl users will need a new release with Itcl's [Patch 2040295], or
+	else load the tiny script in that patch by themselves (rewrite
+	::unknown). Note that it is a script-only patch.
+
+2008-08-05  Joe English  <jenglish@users.sourceforge.net>
+
+	* unix/tclUnixChan.c: Streamline async connect logic [Patch 1994512]
+
+2008-08-05  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclExecute.c: Fix for [Bug 2038069] by dgp.
+	* tests/execute.test:
+
+2008-08-04  Miguel Sofer  <msofer@users.sf.net>
+
+	* tests/nre.test: Added tests for [if], [while] and [for]. A test
+	for [foreach] has been added and marked as knownbug, awaiting for it
+	to be NR-enabled.
+
+	* generic/tclBasic.c:	   Made atProcExit commands run
+	* generic/tclCompile.h:	   unconditionally, streamlined
+	* generic/tclExecute.c:	   atProcExit/tailcall processing in TEBC.
+	* generic/tclProc.c:
+	* tests/unsupported.test:
+
+2008-08-04  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclExecute.c: Stopped faulty double-logging of errors to
+	* tests/execute.test:	stack trace when a compile epoch bump triggers
+	fallback to direct evaluation of commands in a compiled script.
+	[Bug 2037338]
+
+2008-08-03  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclBasic.c:	   New unsupported command atProcExit that
+	* generic/tclCompile.h:	   shares the implementation with tailcall.
+	* generic/tclExecute.c:	   Fixed a segfault in tailcalls. Tests added.
+	* generic/tclInt.h:
+	* generic/tclInterp.c:
+	* generic/tclNamesp.c:
+	* tests/unsupported.test:
+
+2008-08-02  Miguel Sofer  <msofer@users.sf.net>
+
+	* tests/NRE.test (removed):	Migrated tests to standard locations,
+	* tests/nre.test (new):		separating core functionality from the
+	* tests/unsupported.test (new):	experimental commands.
+
+2008-08-01  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* doc/Exit.3:			Do not call Tcl_Finalize implicitly
+	* generic/tclEvent.c:		on DLL_PROCESS_DETACH as it may lead
+	* win/tclWin32Dll.c (DllMain):	to issues and the user should be
+	explicitly calling Tcl_Finalize before unloading regardless. Clarify
+	the docs to note the explicit need in embedded use.
+
+2008-08-01  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclBasic.c:	Revised timing of the CmdFrame stack
+	* tests/info.test:	management in TclEvalEx so that the CmdFrame
+	will still be on the stack at the time Tcl_LogCommandInfo is called to
+	append another level of -errorinfo information. Sets the stage to add
+	file and line data to the stack trace. Added test to check that [info
+	frame] functioning remains unchanged by the revision.
+
+2008-07-31  Miguel Sofer  <msofer@users.sf.net>
+
+	* tests/NRE.test:  Replaced all deep-recursing tests by shallower
+	tests that actually measure the C-stack depth. This makes them
+	bearable again (even under memdebug) and avoid crashing on failure.
+
+	* generic/tclBasic.c:	NR-enabling [catch], [if] and [for] and
+	* generic/tclCmdAH.c:	[while] (the script, not the tests)
+	* generic/tclCmdIL.c:
+	* generic/tclCmdMZ.c:
+	* generic/tclInt.h:
+	* tests/NRE.test:
+
+	* generic/tclBasic.c:	Moved the few remaining defs from tclNRE.h to
+	* generic/tclDictObj.c: tclInt.h, eliminated inclusion of tclNRE.h
+	* generic/tclExecute.c: everywhere.
+	* generic/tclInt.h:
+	* generic/tclInterp.c:
+	* generic/tclNRE.h (removed):
+	* generic/tclNamesp.c:
+	* generic/tclOOBasic.c:
+	* generic/tclOOInt.h:
+	* generic/tclProc.c:
+	* generic/tclTest.c:
+	* unix/Makefile.in:
+
+2008-07-30  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclBasic.c:	 Improved tailcalls.
+	* generic/tclCompile.h:
+	* generic/tclExecute.c:
+	* generic/tclTest.c:
+	* tests/NRE.test:
+
+	* generic/tclBasic.c (TclNREvalObjEx): New comments and code reorg
+	to clarify what is happening.
+
+	* generic/tclBasic.c: Guard against the value of iPtr->evalFlags
+	changing between the times where TEOV and TEOV_exception run. Thanks
+	dgp for catching this.
+
+2008-07-29  Miguel Sofer  <msofer@users.sf.net>
+
+	* tests/NRE.test: New tests that went MIA in the NRE revamping
+
+	* generic/tclBasic.c:	Clean up
+	* generic/tclNRE.h:
+	* generic/tclExecute.c:
+
+	* generic/tclBasic.c:	Made use of the thread's alloc cache stored in
+	* generic/tclInt.h:	the ekeko at interp creation to avoid hitting
+	* generic/tclNRE.h:	the TSD each time an NRE callback is pushed or
+	* generic/tclThreadAlloc.c: pulled; the approach is suitably general
+	to extend to every other obj allocation where an interp is know; this
+	is left for some other time, requires a lot of grunt work.
+
+	* generic/tclExecute.c:	 Fix [Bug 2030670] that cause TclStackRealloc
+	to panic on rare corner cases. Thx ajpasadyn for diagnose and patch.
+
+	* generic/tcl.decls:	 Completely revamped NRE implementation, with
+	* generic/tclBasic.c:	 (almost) unchanged API.
+	* generic/tclCompile.h:
+	* generic/tclExecute.c:	 TEBC will require a bit of a facelift, but
+	* generic/tclInt.decls:	 TEOV at least looks great now. There are new
+	* generic/tclInt.h:	 tests (incomplete!) to verify that execution
+	* generic/tclInterp.c:	 is indeed in the same TEBC instance, at the
+	* generic/tclNRE.h:	 same level in all stacks involved. Tailcalls
+	* generic/tclNamesp.c:	 are still a bit leaky, still deserving to be
+	* generic/tclOOBasic.c:	 in tcl::unsupported.
+	* generic/tclOOMethod.c:
+	* generic/tclProc.c:	 Uninit'd var warnings in TEBC with -O2, no
+	* generic/tclTest.c:	 warnings otherwise.
+
+2008-07-28  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* doc/FileSystem.3:		CONSTified many functions using
+	* generic/tcl.decls:		Tcl_FileSystem which all are supposed
+	* generic/tclDecls.h:		to be a constant, but this was not
+	* generic/tclFileSystem.h:	reflected in the API: Tcl_FSData,
+	* generic/tclIOUtil.c:		Tcl_FSGetInternalRep, Tcl_FSRegister,
+	* generic/tclPathObj.c:		Tcl_FSNewNativePath, Tcl_FSUnregister,
+	* generic/tclTest.c:		Tcl_FSGetFileSystemForPath ...
+	This change complies with TIP #27.
+	***POTENTIAL INCOMPATIBILITY***
+
+2008-07-28  Andreas Kupries  <andreask@activestate.com>
+
+	* generic/tclBasic.c: Added missing ref count when creating an empty
+	string as path (TclEvalEx). In 8.4 the missing code caused panics in
+	the testsuite. It doesn't in 8.5. I am guessing that the code path
+	with the missing the incr-refcount is not invoked any longer. Because
+	the bug in itself is certainly the same.
+
+2008-07-27  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclOOMethod.c (PushMethodCallFrame): Remove hack that should
+	have gone when this code was merged into Tcl.
+
+2008-07-27  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* doc/Object.3:		CONSTified 3 functions using Tcl_ObjType
+	* doc/ObjectType.3:	which all are supposed to be a constant, but
+	* generic/tcl.decls:	this was not reflected in the API:
+	* generic/tcl.h:	Tcl_RegisterObjType, Tcl_ConvertToType,
+	* generic/tclDecls.h:	Tcl_GetObjType
+	* generic/tclObj.c:	Introduced a CONST86_RETURN, so extensions
+	* generic/tclCompCmds.c: which use Tcl_ObjType directly can be
+	* generic/tclOOMethod.c: modified to compile against both Tcl 8.5 and
+	* generic/tclTestobj.c:	Tcl 8.6. tclDecls.h regenerated
+	This change complies with TIP #27.
+	***POTENTIAL INCOMPATIBILITY***
+
+2008-07-25  Andreas Kupries  <andreask@activestate.com>
+
+	* test/info.test: More work on singleTestInterp usability. [1605269]
+
+	* tests/info.test: Tests 38.* added, exactly testing the tracking of
+	location for uplevel scripts. Resolved merge conflict on info-37.0,
+	switched !singleTestInterp constraint to glob matching instead. Ditto
+	info-22.8, removed constraint, more glob matching, and reduced the
+	depth of the stack we check. More is coming, right now I want to
+	commit the bug fixes.
+
+	* tests/oo.test: Updated oo-22.1 for expanded location tracking.
+
+	* generic/tclCompile.c (TclInitCompileEnv): Reorganized the
+	initialization of the #280 location information to match the flow in
+	TclEvalObjEx to get more absolute contexts.
+
+	* generic/tclBasic.c (TclEvalObjEx): Added missing cleanup of extended
+	location information.
+
+2008-07-25  Daniel Steffen  <das@users.sourceforge.net>
+
+	* tests/info.test (info-37.0): Add !singleTestInterp constraint;
+	(info-22.8, info-23.0): switch to glob matching to avoid sensitivity
+	to tcltest.tcl line number changes, remove knownBug constraint, fix
+	expected result. [Bug 1605269]
+
+2008-07-24  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* doc/Notifier.3:      CONSTified 4 functions in the Notifier which
+	* doc/Thread.3:	       all have a Tcl_Time* in it which is supposed
+	* generic/tcl.decls:   to be a constant, but this was not reflected
+	* generic/tcl.h:       reflected in the API:
+	* generic/tclDecls.h:	    Tcl_SetTimer, Tcl_WaitForEvent,
+	* generic/tclNotify.c:	    Tcl_ConditionWait, Tcl_SetMaxBlockTime
+	* macosx/tclMacOSXNotify.c:
+	* generic/tclThread.c: Introduced a CONST86, so extensions which have
+	* unix/tclUnixNotfy.c: have their own Notifier (are there any?) can
+	* unix/tclUnixThrd.c:  can be modified to compile against both Tcl
+	* win/tclWinNotify.c:  Tcl 8.5 and Tcl 8.6
+	* win/tclWinThrd.c:    Regenerated tclDecls.h with "make stubs".
+	This change complies with TIP #27
+	***POTENTIAL INCOMPATIBILITY***
+
+2008-07-23  Alexandre Ferrieux  <ferrieux@users.sourceforge.net>
+
+	* tests/lrange.test: Added relative speed test to check for lrange
+	in-place optimization committed 2008-06-30.
+	* tests/binary.test: Added relative speed test to check for pure byte
+	array CONCAT1 optimization committed 2008-06-30.
+
+2008-07-23  Andreas Kupries  <andreask@activestate.com>
+
+	* tests/info.test: Reordered the tests to have monotonously increasing
+	numbers.
+
+	* generic/tclBasic.c: Modified TclArgumentGet to reject pure lists
+	* generic/tclCmdIL.c: immediately, without search. Reworked setup of
+	* generic/tclCompile.c: eoFramePtr, doesn't need the line information,
+	* tests/info.test: more sensible to have everything on line 1 when
+	eval'ing a pure list. Updated the users of the line information to
+	special case this based on the frame type (i.e.
+	TCL_LOCATION_EVAL_LIST). Added a testcase demonstrating the new
+	behaviour.
+
+2008-07-23  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclBasic.c (GetCommandSource): Added comment with
+	explanation and warning for waintainers.
+
+2008-07-22  Andreas Kupries  <andreask@activestate.com>
+
+	* generic/tclCompile.c: Made the new TclEnterCmdWordIndex static, and
+	* generic/tclCompile.h: ansified.
+
+	* generic/tclBasic.c: Ansified the new functions. Added missing
+	function comments.
+
+	* generic/tclBasic.c: Reworked the handling of bytecode literals for
+	* generic/tclCompile.c: #280 to fix the abysmal performance for deep
+	* generic/tclCompile.h: recursion, replaced the linear search through
+	* generic/tclExecute.c: the whole stack with another hashtable and
+	* generic/tclInt.h: simplified the data structure used by the compiler
+	by using an array instead of a hashtable. Incidentially this also
+	fixes the memory leak reported via [Bug 2024937].
+
+2008-07-22  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclBasic.c:	 Added numLevels field to CommandFrame, let
+	* generic/tclExecute.c:	 GetCommandSource use it. This solves [Bug
+	* generic/tclInt.h:	 2017146]. Thx dgp for the analysis.
+
+2008-07-21  Andreas Kupries  <andreask@activestate.com>
+
+	* generic/tclBasic.c: Extended the existing TIP #280 system (info
+	* generic/tclCmdAH.c: frame), added the ability to track the absolute
+	* generic/tclCompCmds.c: location of literal procedure arguments, and
+	* generic/tclCompile.c: making this information available to uplevel
+	* generic/tclCompile.h: eval, and siblings. This allows proper
+	* generic/tclInterp.c: tracking of absolute location through custom
+	* generic/tclInt.h: (Tcl-coded) control structures based on uplevel,
+	* generic/tclNamesp.c: etc.
+	* generic/tclProc.c:
+	* tests/info.test:
+
+2008-07-21  Jan Nijtmans  <nijtmans@users.sf.net>
+
+	* generic/*.c: Fix [2021443] inconsistant "wrong # args" messages
+	* win/tclWinReg.c
+	* win/tclWinTest.c
+	* tests/*.test
+
+2008-07-21  Alexandre Ferrieux  <ferrieux@users.sourceforge.net>
+
+	TIP #304 IMPLEMENTATION
+
+	* generic/tcl.decls:	Public API
+	* generic/tclIOCmds.c:	Generic part
+	* unix/tclUnixPipe.c:	OS part
+	* win/tclWinPipe.c:	OS part
+	* tests/chan.test:	[chan pipe] tests
+	* tests/ioCmd.test:	Modernized checks
+	* tests/ioTrans.test:
+
+2008-07-21  Pat Thoyts  <patthoyts@users.sourceforge.net>
+
+	* generic/tclFCmd.c:  Inodes on windows are unreliable. [Bug 2015723]
+	* tests/winFCmd.test: test rename with inode collision
+
+2008-07-21  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tcl.decls:	  Changed the implementation of
+	* generic/tclBasic.c:	  [namespace import]; removed
+	* generic/tclDecls.h:	  Tcl_NRObjProc, replaced with
+	* generic/tclExecute.c:	  Tcl_NRCmdSwap (proposed public
+	* generic/tclInt.h:	  NRE API). This should fix
+	* generic/tclNRE.h:	  [Bug 582506].
+	* generic/tclNamesp.c:
+	* generic/tclStubInit.c:
+
+	* generic/tclBasic.c:	 NRE: enabled calling NR commands
+	* generic/tclExecute.c:	 from the callbacks. Completely
+	* generic/tclInt.h:	 redone tailcall implementation
+	* generic/tclNRE.h:	 using the new feature. [Bug 2021489]
+	* generic/tclProc.c:
+	* tests/NRE.test:
+
+2008-07-20  Kevin B. Kenny  <kenykb@acm.org>
+
+	* tests/fileName.test: Repaired the failing test fileName-15.7 from
+	dkf's commit earlier today.
+
+2008-07-20  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclDictObj.c (SetDictFromAny): Make the list->dict
+	transformation a bit more efficient; modern dicts are ordered and so
+	we can round-trip through lists without needing the string rep at all.
+	* generic/tclListObj.c (SetListFromAny): Make the dict->list
+	transformation not lossy of internal representations and hence more
+	efficient. [Bug 2008248] (ajpasadyn) but using a more efficient patch.
+
+	* tests/fileName.test: Revise to reduce the obscurity of tests. In
+	particular, all tests should now produce informative messages on
+	failure and the quantity of [catch]-based obscurity is now greatly
+	reduced; non-erroring is now checked for directly.
+
+2008-07-19  Donal K. Fellows  <dkf@users.sf.net>
+
+	* tests/env.test: Add LANG to the list of variables that are not
+	touched by the environment variable tests, so that subprocesses can
+	get their system encoding correct.
+
+	* tests/exec.test, tests/env.test: Rewrite so that non-ASCII
+	characters are not used in the final comparison. Part of fixing [Bug
+	1513659].
+
+2008-07-18  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclBasic.c:	 Optimization: replace calls to
+	* generic/tclDictObj.c:	 Tcl_NRAddCallback with the macro
+	* generic/tclExecute.c:	 TclNRAddCallback.
+	* generic/tclInterp.c:
+	* generic/tclNRE.h:
+	* generic/tclNamesp.c:
+	* generic/tclOO.c:
+	* generic/tclOOBasic.c:
+	* generic/tclOOCall.c:
+	* generic/tclOOInt.h:
+	* generic/tclOOMethod.c:
+	* generic/tclProc.c:
+
+2008-07-18  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclOO.c (TclNRNewObjectInstance, FinalizeAlloc):
+	* generic/tclOOBasic.c (TclOO_Class_Create, TclOO_Class_CreateNs)
+	(TclOO_Class_New, FinalizeConstruction, AddConstructionFinalizer):
+	NRE-enablement of the class construction methods.
+
+2008-07-18  Miguel Sofer  <msofer@users.sf.net>
+
+	* tests/NRE.test:  Added basic tests for deep TclOO calls
+
+	* generic/tcl.decls:	   Change the public api prefix from
+	* generic/tcl.h:	   TclNR_foo to Tcl_NRfoo
+	* generic/tclBasic.c:
+	* generic/tclDecls.h:
+	* generic/tclDictObj.c:
+	* generic/tclExecute.c:
+	* generic/tclInterp.c:
+	* generic/tclNRE.h:
+	* generic/tclNamesp.c:
+	* generic/tclOO.c:
+	* generic/tclOOBasic.c:
+	* generic/tclOOCall.c:
+	* generic/tclOOMethod.c:
+	* generic/tclProc.c:
+	* generic/tclStubInit.c:
+
+2008-07-18  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclOOBasic.c (TclOO_Object_Eval, FinalizeEval): NRE-enable
+	the oo::object.eval method.
+
+2008-07-18  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclDictObj.c (DictWithCmd, DictUpdateCmd): Fix refcounting
+	bugs that caused crashes [Bug 2017857].
+
+	* generic/tclBasic.c (TclNREvalObjEx): Streamline the management of
+	the command frame (opt).
+
+2008-07-17  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclDictObj.c (DictWithCmd, FinalizeDictWith): Split the
+	implementation of [dict with] so that it works with NRE.
+	(DictUpdateCmd, FinalizeDictUpdate): Similarly for the non-compiled
+	version of [dict update].
+
+2008-07-16  George Peter Staplin  <georgeps@users.sf.net>
+
+	* win/tclWinThrd.c: Test for TLS_OUT_OF_INDEXES to make certain that
+	thread key creation is successful.
+
+2008-07-16  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclOO.c, generic/tclOOInt.h, generic/tclOOBasic.c:
+	* generic/tclOOCall.c, generic/tclOOMethod.c: NRE-enable the TclOO
+	implementation in Tcl. No change to public APIs, except that method
+	implementations can now be NRE-aware if they choose (which normal
+	methods and forwards are). On the other hand, callers of
+	TclOOInvokeObject (which is only in the internal stub table) will need
+	to deal with the fact that it's only safe to call inside an NRE-aware
+	context.
+	***POTENTIAL INCOMPATIBILITY***
+
+2008-07-15  Miguel Sofer  <msofer@users.sf.net>
+
+	* tests/NRE.test:	Better constraint for testing the existence of
+	* tests/stack.test:	teststacklimit, to insure that the test suite
+				runs under tclsh.
+
+	* generic/tclParse.c: Fixing incomplete reversion of "fix" for [Bug
+	2017583], missing TclResetCancellation call.
+
+2008-07-15  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclBasic.c (Tcl_CancelEval): Fix blunder. [Bug 2018603]
+
+	* doc/DictObj.3: Fix error in example. [Bug 2016740]
+
+	* generic/tclNamesp.c (EnsembleUnknownCallback): Factor out some of
+	the more complex parts of the ensemble code to make it easier to
+	understand and hence to permit tighter compilation of code on the
+	critical path.
+
+2008-07-14  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclParse.c: Reverting the "fix" for [Bug 2017583], numLevel
+	* tests/parse.test:   management and TclInterpReady check seems to be
+			      necessary after all.
+
+2008-07-14  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclProc.c (TclNRApplyObjCmd, TclObjInterpProcCore):
+	* generic/tclBasic.c (TclNR_AddCallback, TclEvalObjv_NR2):
+	* generic/tclNRE.h (TEOV_callback): Change the callback storage type
+	to use an array, so guaranteeing correct inter-member spacing and
+	memory layout.
+
+2008-07-14  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclExecute.c:	 Remove unneeded TclInterpReady calls
+	* generic/tclParse.c:
+
+	* generic/tclBasic.c.:	 Embedded Tcl_Canceled() calls into
+	* generic/tclExecute.c:	 TclInterpReady().
+	* generic/tclParse.c:
+
+	* generic/tclVar.c: Fix error message
+
+	* generic/tclParse.c: Remove unnecessary numLevel management
+	* tests/parse.test:   [Bug 2017583]
+
+	* generic/tclBasic.c.:	 NRE left too many calls to
+	* generic/tclExecute.c:	 TclResetCancellation lying around: it
+	* generic/tclProc.c:	 only needs to be called prior to any
+				 iPtr->numLevels++. Thanks mistachkin.
+
+	* generic/tclBasic.c: TclResetCancellation() calls were misplaced
+	(merge mishap); stray //. Thanks patthoyts.
+
+	* generic/tclInt.h: The new macros TclSmallAlloc and TclSmallFree
+	were badly defined under mem debugging [Bug 2017240] (thx das)
+
+2008-07-13  Miguel Sofer  <msofer@users.sf.net>
+
+	NRE implementation [Patch 2017110]
+
+	* generic/tcl.decls:	 The NRE infrastructure
+	* generic/tcl.h:
+	* generic/tclBasic.c:
+	* generic/tclCmdAH.c:
+	* generic/tclCompile.h:
+	* generic/tclDecls.h:
+	* generic/tclExecute.c:
+	* generic/tclHistory.c:
+	* generic/tclInt.decls:
+	* generic/tclInt.h:
+	* generic/tclIntDecls.h:
+	* generic/tclNRE.h:
+	* generic/tclStubInit.c:
+	* unix/Makefile.in:
+
+	* generic/tclInterp.c:	 NRE-enabling: procs, lambdas, uplevel,
+	* generic/tclNamesp.c:	 same-interp aliases, ensembles, imports
+	* generic/tclProc.c:	 and namespace_eval.
+
+	* generic/tclTestProcBodyObj.c: New NRE specific tests (few, but
+	* tests/NRE.test:		note that the thing is actually
+					tested by the whole testsuite.
+
+	* tests/interp.test:	 Fixed numLevel counting.
+	* tests/parse.test:
+	* tests/stack.test:
+
+	* unix/configure:	 Removing support for the hacky nonportable
+	* unix/configure.in:	 stack check: it is not needed anymore, Tcl
+	* unix/tclConfig.h.in:	 is very thrifty on the C stack.
+	* unix/tclUnixInit.c:
+	* unix/tclUnixTest.c:
+	* win/tclWin32Dll.c:
+
+2008-07-08  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclGet.c:	Corrected out of date comments and removed
+	* generic/tclInt.decls:	internal routine TclGetLong() that's no
+	longer used. If an extension is using this from the internal stubs
+	table, it can shift to the public routine Tcl_GetLongFromObj() or
+	can request addition of a public Tcl_GetLong().
+	***POTENTIAL INCOMPATIBILITY***
+
+	* generic/tclIntDecls.h:	make genstubs
+	* generic/tclStubInit.c:
+
+2008-07-08  Donal K. Fellows  <dkf@users.sf.net>
+
+	* doc/CrtInterp.3: Tighten up the descriptions of behaviour to make
+	this page easier to read for a "Tcl 8.6" audience.
+
+2008-07-07  Andreas Kupries  <andreask@activestate.com>
+
+	* generic/tclCmdIL.c (InfoFrameCmd): Fixed unsafe idiom of setting
+	the interp result found by Don Porter.
+
+2008-07-07  Donal K. Fellows  <dkf@users.sf.net>
+
+	* doc/regexp.n, doc/regsub.n: Correct examples. [Bug 1982642]
+
+2008-07-06  Donal K. Fellows  <dkf@users.sf.net>
+
+	* doc/lindex.n: Improve examples.
+
+2008-07-03  Andreas Kupries  <andreask@activestate.com>
+
+	* generic/tclIORChan.c (InvokeTclMethod): Fixed the memory leak
+	reported in [Bug 1987821]. Thanks to Miguel for the report and Don
+	Porter for tracking the cause down.
+
+2008-07-03  Don Porter  <dgp@users.sourceforge.net>
+
+	* library/package.tcl:	Removed [file readable] testing from
+	[tclPkgUnknown] and friends. We find out soon enough whether a file is
+	readable when we try to [source] it, and not testing before allows us
+	to workaround the bugs on some common filesystems where [file
+	readable] lies to us. [Patch 1969717]
+
+2008-07-01  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/regc_nfa.c (duptraverse): Impose a maximum stack depth on
+	the single most recursive part of the RE engine. The actual maximum
+	may need tuning, but that needs a system with a small stack to carry
+	out. [Bug 1905562]
+
+	* tests/string.test: Eliminate non-ASCII characters from the actual
+	test script. [Bug 2006884]
+
+2008-06-30  Donal K. Fellows  <dkf@users.sf.net>
+
+	* doc/ObjectType.3: Clean up typedef formatting.
+
+2008-06-30  Don Porter  <dgp@users.sourceforge.net>
+
+	* doc/ObjectType.3:	Updated documentation of the Tcl_ObjType
+	struct to match expectations of Tcl 8.5. [Bug 1917650]
+
+2008-06-30  Alexandre Ferrieux  <ferrieux@users.sourceforge.net>
+
+	* generic/tclCmdIL.c: Lrange cleanup and in-place optimization. [Patch
+	1890831]
+
+	* generic/tclExecute.c: Avoid useless String conversion for CONCAT1 of
+	pure byte arrays. [Patch 1953758]
+
+2008-06-29  Donal K. Fellows  <dkf@users.sf.net>
+
+	* doc/*.1, doc/*.3, doc/*.n: Many small updates, purging out of date
+	change bars and cleaning up the formatting of typedefs. Added a few
+	missing bits of documentation in the process.
+
+2008-06-29  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclPathObj.c:	 Plug memory leak in [Bug 1999176] fix. Thanks
+	to Rolf Ade for detecting.
+
+2008-06-29  Donal K. Fellows  <dkf@users.sf.net>
+
+	* doc/interp.n: Corrected order of subcommands. [Bug 2004256]
+	Removed obsolete (i.e. 8.5) .VS/.VE pairs.
+
+	* doc/object.n (EXAMPLES): Fix incorrect usage of oo::define to be
+	done with oo::objdefine instead. [Bug 2004480]
+
+2008-06-28  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclPathObj.c:	 Plug memory leak in [Bug 1972879] fix. Thanks
+	to Rolf Ade for detecting and Dan Steffen for the fix. [Bug 2004654]
+
+2008-06-26  Andreas Kupries  <andreask@activestate.com>
+
+	* unix/Makefile.in: Followup to my change of 2008-06-25, make code
+	generated by the Makefile and put into the installed tm.tcl
+	conditional on interpreter safeness as well. Thanks to Daniel Steffen
+	for reminding me of that code.
+
+2008-06-25  Don Porter  <dgp@users.sourceforge.net>
+
+	*** 8.6a1 TAGGED FOR RELEASE ***
+
+	* changes:	Updates for 8.6a1 release.
+
+	* generic/tclOO.h:	Bump to TclOO 0.5.
+
+2008-06-25  Andreas Kupries  <andreask@activestate.com>
+
+	* library/tm.tcl:   Modified the handling of Tcl Modules and of the
+	* library/safe.tcl: Safe Base to interact nicely with each other,
+	* library/init.tcl: enabling requiring Tcl Modules in safe
+	* tests/safe.test:  interpreters. [Bug 1999119]
+
+2008-06-25  Pat Thoyts  <patthoyts@users.sourceforge.net>
+
+	* win/rules.vc: Fix versions of dde and registry dlls
+	* win/makefile.vc: Fix problem building with staticpkg option
+
+2008-06-24  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclPathObj.c: Fixed some internals management in the "path"
+	Tcl_ObjType for the empty string value. Problem led to a crash in the
+	command [glob -dir {} a]. [Bug 1999176]
+
+2008-06-24  Pat Thoyts  <patthoyts@users.sourceforge.net>
+
+	* doc/fileevent.n: Fix examples and comment on eof use. [Bug 1995063]
+
+2008-06-23  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclPathObj.c: Fixed bug in Tcl_GetTranslatedPath() when
+	operating on the "Special path" variant of the "path" Tcl_ObjType
+	intrep. A full normalization was getting done, in particular, coercing
+	relative paths to absolute, contrary to what the function of producing
+	the "translated path" is supposed to do. [Bug 1972879]
+
+2008-06-20  Don Porter  <dgp@users.sourceforge.net>
+
+	* changes:	Updates for 8.6a1 release.
+
+	* generic/tclInterp.c:	Fixed completely boneheaded mistake that
+	* tests/interp.test:	[interp bgerror $slave] and [$slave bgerror]
+	would always act like [interp bgerror {}]. [Bug 1999035]
+
+	* tests/chanio.test:	Corrected flawed tests revealed by a -debug 1
+	* tests/cmdAH.test:	-singleproc 1 test suite run.
+	* tests/event.test:
+	* tests/interp.test:
+	* tests/io.test:
+	* tests/ioTrans.test:
+	* tests/namespace.test:
+
+	* tests/encoding.test:	Make failing tests pass again. [Bug 1972867]
+
+2008-06-19  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclOO.c (Tcl_ObjectContextInvokeNext): Corrected 'next' (at
+	* tests/oo.test (oo-7.8):	end of a call chain) to make it
+	* doc/next.n:			consistent with the TIP. [Bug 1998244]
+
+	* generic/tclOOCall.c (AddSimpleClassChainToCallContext): Make sure
+	* tests/oo.test (oo-14.8): that class mixins are processed in the
+	documented order. [Bug 1998221]
+
+2008-06-19  Don Porter  <dgp@users.sourceforge.net>
+
+	* changes:	Updates for 8.6a1 release.
+
+	* README:		Bump version number to 8.6a1
+	* generic/tcl.h:
+	* library/init.tcl:
+	* tools/tcl.wse.in:
+	* unix/configure.in:
+	* unix/tcl.spec:
+	* win/configure.in:
+
+	* unix/configure:	autoconf-2.59
+	* win/configure:
+
+2008-06-17  Andreas Kupries  <andreask@activestate.com>
+
+	* generic/tclClock.c (ClockConvertlocaltoutcObjCmd): Removed left
+	over debug output.
+
+2008-06-17  Andreas Kupries  <andreask@activestate.com>
+
+	* doc/tm.n: Followup to changelog entry 2008-03-18 regarding
+	::tcl::tm::Defaults. Updated the documentation to not only mention the
+	new (underscored) form of environment variable names, but make it the
+	encouraged form as well. [Bug 1914604]
+
+2008-06-17  Kevin Kenny  <kennykb@acm.org>
+
+	* generic/tclClock.c (ConvertLocalToUTC):
+	* tests/clock.test (clock-63.1): Fixed a bug where the internal
+	ConvertLocalToUTC command segfaulted if passed a dictionary without
+	the 'localSeconds' key. To the best of my knowledge, the bug was not
+	observable in the [clock] command itself.
+
+2008-06-16  Andreas Kupries  <andreask@activestate.com>
+
+	* generic/tclCmdIL.c (TclInfoFrame): Moved the code looking up the
+	* tests/info.test: information for key 'proc' out of the
+	TCL_LOCATION_BC branch to after the switch, this is common to all
+	frame types. Updated the testsuite to match. This was exposed by the
+	2008-06-08 commit (Miguel), switching uplevel from direct eval to
+	compilation. [Bug 1987851]
+
+2008-06-16  Andreas Kupries  <andreask@activestate.com>
+
+	* tests/ioTrans.test (iortrans-11.*): Fixed same issue as for
+	iortrans.tf-11.*, cleanup of temp file, making this a followup to the
+	entry on 2008-06-10 by myself.
+
+2008-06-13  David Gravereaux  <davygrvy@pobox.com>
+
+	* win/rules.vc: SYMBOLS macro is now being set to zero when $(OPTS) is
+	not available.
+	* win/makefile.vc: The Stubs source files (tclStubLib.c and
+	tclOOStubLib.c) should not be compiled with the -GL flag.
+
+2008-06-13  Joe Mistachkin  <joe@mistachkin.com>
+
+	TIP #285 IMPLEMENTATION
+
+	* doc/Eval.3: Added documentation for the Tcl_CancelEval and
+	Tcl_Canceled functions and the TCL_CANCEL_UNWIND flag bit.
+	* doc/after.n: Corrected the spelling of 'canceled' in the
+	documentation.
+	* doc/interp.n: Added documentation for [interp cancel].
+	* generic/tcl.decls: Added the Tcl_CancelEval and Tcl_Canceled
+	functions to the stubs table.
+	* generic/tcl.h: Added the TCL_CANCEL_UNWIND flag bit.
+	* generic/tclBasic.c: The bulk of the script cancellation
+	functionality is defined here. Added code to initialize and manage the
+	script cancellation hash table in a thread-safe manner. Reset script
+	cancellation flags prior to increasing the nesting level (if the
+	nesting level is currently zero) and always cooperatively check for
+	script cancellation near the start of TclEvalObjvInternal and after
+	invoking async handlers.
+	* generic/tclDecls.h: Regenerated.
+	* generic/tclEvent.c: Call TclFinalizeEvaluation during finalization
+	to cleanup the script cancellation hash table. During [vwait], always
+	cooperatively check for script cancellation. Corrected the spelling of
+	'canceled' in comments to be consistent with the documentation.
+	* generic/tclExecute.c: Reset script cancellation flags prior to
+	increasing the nesting level (if the nesting level is currently zero)
+	and always cooperatively check for script cancellation after invoking
+	async handlers. Prevent [catch] from catching script cancellation when
+	the TCL_CANCEL_UNWIND flag is set (similar to the manner used by TIP
+	143 when a limit has been exceeded).
+	* generic/tclInt.decls: Added TclResetCancellation to the internal
+	stubs table.
+	* generic/tclInt.h: Added asyncCancel and asyncCancelMsg fields to the
+	private Interp structure. Added private interp flag value CANCELED to
+	help control script cancellation.
+	* generic/tclIntDecls.h: Regenerated.
+	* generic/tclInterp.c (Tcl_InterpObjCmd): Added [interp cancel]
+	subcommand.
+	* generic/tclNotify.c (Tcl_DeleteEventSource): Corrected the spelling
+	of 'canceled' in comments to be consistent with the documentation.
+	* generic/tclParse.c: Reset script cancellation flags prior to
+	* generic/tclProc.c: increasing the nesting level (if the nesting
+	level is currently zero) and cooperatively check for script
+	cancellation prior to evaluating commands.
+	* generic/tclStubInit.c: Regenerated.
+	* generic/tclThreadTest.c (Tcl_ThreadObjCmd): Added script
+	cancellation support ([testthread cancel]).
+	Modified [testthread id] to allow querying of the 'main' thread ID.
+	Corrected comments to reflect the actual command syntax. Made
+	[testthread wait] cooperatively check for script cancellation. Added
+	[testthread event] to allow for processing one pending event without
+	blocking.
+	* generic/tclTimer.c: Delay for a maximum of 500 milliseconds prior to
+	checking for async handlers and script cancellation.
+	* tests/cmdAH.test: Changed [interp c] to [interp create].
+	* tests/interp.test: Added and fixed tests for [interp cancel].
+	* tests/thread.test: Added tests for script cancellation via
+	[testthread cancel].
+	* tools/man2help2.tcl: Fixed problems with WinHelp target (see
+	* tools/man2tcl.c: [Bug 1934200], [Bug 1934265], and [Bug 1934272]).
+	* win/makefile.vc: Added 'pdbs' option for Windows build rules to
+	* win/rules.vc:	   allow for non-debug builds with full symbols.
+	* win/tcl.hpj.in: Corrected version for WinHelp target.
+	* win/tclWinNotify.c: Used SleepEx and WaitForSingleObjectEx on
+	* win/tclWinThrd.c: Windows because they are alertable.
+
+2008-06-12  Daniel Steffen  <das@users.sourceforge.net>
+
+	* unix/Makefile.in:		Add complete deps on tclDTrace.h.
+
+	* generic/tclOO.c:		Use TclOOStubs hooks field to retrieve
+	* generic/tclOODecls.h:		TclOOIntStubs pointer. [Bug 1980953]
+	* generic/tclOOIntDecls.h:
+	* generic/tclOOStubInit.c:
+	* generic/tclOOStubLib.c:
+
+	* generic/tclIORTrans.c:	Fix signed <-> unsigned cast warnings.
+
+	* unix/Makefile.in:		Clean generated tclDTrace.h file.
+	* unix/configure.in (SunOS):	Fix static DTrace-enabled build.
+
+	* unix/tcl.m4 (SunOS-5.11): Fix 64bit amd64 support with gcc & Sun cc.
+	* unix/configure: autoconf-2.59
+
+	* macosx/Tcl.xcodeproj/project.pbxproj:	Add tclIORTrans.c; updates and
+						cleanup for Xcode 3.1/Leopard.
+	* macosx/Tcl.xcode/project.pbxproj:	Sync Tcl.xcodeproj changes.
+	* macosx/README:			Document new build configs.
+
+2008-06-10  Joe English  <jenglish@users.sourceforge.net>
+
+	* generic/tclEncoding.c(UtfToUtfProc): Avoid unwanted sign extension
+	when converting incomplete UTF-8 sequences. See [Bug 1908443] for
+	details.
+
+2008-06-10  Andreas Kupries  <andreask@activestate.com>
+
+	* tests/ioTrans.test (iortrans.tf-6.1): Fixed the [Bug 1988552],
+	reported by Kevin. Have to close the channel before removal of the
+	file. Fixed same bug in test 'iortrans.tf-11.0', after fixing missing
+	cleanup of the file in 'iortrans.tf-11.*'. Lastly fixed the names of
+	the threaded tests 'iortrans-8.*' to the correct 'iortrans.tf-8.*'.
+
+2008-06-09  Andreas Kupries  <andreas_kupries@users.sourceforge.net>
+
+	* generic/tclIORTrans.c (ReflectInput): Fixed a bug triggered by Pat
+	Thoyts <patthoyts@users.sourceforge.net>. Reset the EOF flag after
+	draining the Tcl level into the result buffer, to make sure that the
+	result buffer will be drained as well by repeated calls to
+	ReflectInput should it contain more than one buffer-full of data.
+	Without that reset the higher I/O system will not call on ReflectInput
+	anymore due to the assumed EOF, thus losing the data which did not fit
+	in the buffer of the call which caused the eof and drain.
+
+2008-06-09  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclOOCall.c (TclOOGetSortedMethodList): Plug memory leak
+	that occurred when all methods were hidden. [Bug 1987817]
+
+2008-06-08  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclBasic.c:	   Compilation of uplevel scripts, allow
+	* generic/tclCompCmds.c:   non-body compiled scripts to access the
+	* generic/tclCompile.c:	   LVT (but not to extend it) and enable the
+	* generic/tclCompile.h:	   canonical list opt to sidestep the
+	* generic/tclExecute.c:	   compiler. [Patch 1973096]
+	* generic/tclProc.c:
+	* tests/uplevel.test:
+
+2008-06-06  Andreas Kupries  <andreask@activestate.com>
+
+	TIP #230 IMPLEMENTATION
+
+	* generic/tclIOCmd.c: Integration of transform commands into 'chan'
+			      ensemble.
+	* generic/tclInt.h: Definitions of the transform commands.
+	* generic/tclIORTrans.c: Implementation of the reflection transforms.
+	* tests/chan.test:  Tests updated for new sub-commands of 'chan'.
+	* tests/ioCmd.test: Tests updated for new sub-commands of 'chan'.
+	* tests/ioTrans.test: Whole new set of tests for the reflection
+			      transform.
+	* unix/Makefile.in: Integration of new files into build rules.
+	* win/Makefile.in:  Integration of new files into build rules.
+	* win/makefile.vc:  Integration of new files into build rules.
+
+	NOTE: The file 'tclIORTrans.c' has a lot of code in common with the
+	      file 'tclIORChan.c', as that made it much easier to develop the
+	      reference implementation as a separate module. Now that the
+	      transforms have been committed the one thing left to do is to go
+	      over both modules and see which of the common parts we can
+	      factor out and share.
+
+2008-06-04  Pat Thoyts  <patthoyts@users.sourceforge.net>
+
+	* generic/tclBinary.c: TIP #317 implementation
+	* tests/binary.test:
+
+2008-06-02  Kevin B. Kenny  <kennykb@acm.org>
+
+	* generic/tclOO.c (ReleaseClassContents): Fix the one remaining
+	valgrind complaint about oo.test, caused by failing to protect the
+	Object as well as the Class corresponding to a subclass being deleted
+	and hence getting a freed-memory read when attempting to delete the
+	class command. [Bug 1981001]
+
+2008-06-01  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclOOMethod.c (Tcl_NewMethod): Complete the fix of [Bug
+	1981001], previous fix was incomplete though helpful in telling me
+	where to look.
+
+2008-06-01  Joe Mistachkin  <joe@mistachkin.com>
+
+	* win/Makefile.in: Add tclOO genstubs to Windows makefiles and remove
+	* win/makefile.vc: -DBUILD_tcloo because it is no longer required.
+
+2008-06-01  Kevin B. Kenny  <kennykb@acm.org>
+
+	* generic/tclOODecls.h:	   Added the swizzling of DLLEXPORT and
+	* generic/tclOOIntDecls.h: DLLIMPORT needed to make EXTERN work.
+
+	* generic/tclDictObj.c:	 Added missing initializers to the ensemble
+				 map to silence a compiler warning. Thanks to
+				 George Peter Staplin for the report.
+
+	* generic/tclOOMethod.c: Fix a bug where the refcount of a method was
+				 reset if the method was redefined while there
+				 was an active invocation. [Bug 1981001]
+
+2008-06-01  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclOO.decls, unix/Makefile.in (genstubs): Make generation of
+	stub tables correct.
+	* generic/tclOO{Decls.h,IntDecls.h,StubInit.c,StubLib.c}: Fixes to
+	make the generation work correctly, removing subtle differences
+	between output of different versions of stub generator.
+
+2008-06-01  Daniel Steffen  <das@users.sourceforge.net>
+
+	* generic/tclOOStubLib.c:	Ensure use of tcl stubs; include in
+	* unix/Makefile.in:		stub lib; disable broken tclOO
+					genstubs
+
+	* generic/tclOO.c:		Make tclOO stubs tables 'static const'
+	* generic/tclOODecls.h:		and stub table pointers MODULE_SCOPE
+	* generic/tclOOIntDecls.h:	(change generated files manually
+	* generic/tclOOStubInit.c:	pending genstubs support for tclOO).
+	* generic/tclOOStubLib.c:
+
+	* generic/tclOO.c:		Fix warnings for 'int<->ptr
+	* generic/tclOOCall.c:		conversion' and 'signed vs unsigned
+	* generic/tclOOMethod.c:	comparison'.
+
+	* tests/msgcat.test:	Fix for ::tcl::mac::locale with @modifier.
+
+	* tools/tsdPerf.tcl:	Use [info sharedlibextension]
+
+	* unix/tclConfig.h.in:	autoheader-2.59
+
+	* macosx/Tcl.xcodeproj/project.pbxproj:	Add new tclOO files; add debug
+	* macosx/README:			configs with corefoundation
+						disabled and with gcov; update
+						to Xcode 3.1.
+
+2008-05-31  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclOO.c (InitFoundation): Correct reference counting for
+	strings used when creating the constructor for classes.
+	* generic/tclOOMethod.c (TclOODelMethodRef): Correct fencepost error
+	in reference counting of method implementation structures.
+	* tests/oo.test (oo-0.5): Added a test to detect a memory leak problem
+	relating to disposal of the core object system.
+
+	TIP#257 IMPLEMENTATION
+
+	* generic/tclBasic.c, generic/tclOOInt.h: Correct declarations.
+	* win/Makefile.in, win/makefile.bc, win/makefile.vc: Build support for
+	Win32, from Joe Mistachkin. [Patch 1980861]
+
+	* generic/tclOO*, doc/*, tests/oo.test: Port of implementation of
+	TclOO to sit directly inside Tcl. Note that this is incomplete (e.g.
+	no build support yet for Windows).
+
+2008-05-26  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* tests/io.test (io-53.9): Need to close chan before removing file.
+
+2008-05-26  Donal K. Fellows  <dkf@users.sf.net>
+
+	* win/makefile.bc:		    Remove deprecated winhelp target.
+	* win/Makefile.in, win/makefile.vc: It didn't work correctly anyway.
+
+2008-05-23  Andreas Kupries  <andreask@activestate.com>
+
+	* win/tclWinChan.c (FileWideSeekProc): Accepted a patch by Alexandre
+	Ferrieux <ferrieux@users.sourceforge.net> to fix the [Bug 1965787].
+	'tell' now works for locations > 2 GB as well instead of going
+	negative.
+
+	* generic/tclIO.c (Tcl_SetChannelBufferSize): Accepted a patch by
+	* tests/io.test: Alexandre Ferrieux <ferrieux@users.sourceforge.net>
+	* tests/chanio.test: to fix the [Bug 1969953]. Buffersize outside of
+	the supported range are now clipped to nearest boundary instead of
+	ignored.
+
+2008-05-22  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclNamesp.c (Tcl_LogCommandInfo):	Restored ability to
+	handle the argument value length = -1. Thanks to Chris Darroch for
+	discovering the bug and providing the fix. [Bug 1968245]
+
+2008-05-21  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclParse.c (ParseComment):	The new TclParseAllWhiteSpace
+	* tests/parse.test (parse-15.60):	routine has no mechanism to
+	return the "incomplete" status of "\\\n" so calling this routine
+	anywhere that can be reached within a Tcl_ParseCommand() call is a
+	mistake. In particular, ParseComment() must not use it. [Bug 1968882]
+
+2008-05-20  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclNamesp.c (Tcl_SetNamespaceUnknownHandler): Corrected odd
+	logic for handling installation of namespace unknown handlers which
+	could lead too very strange things happening in the error case.
+
+2008-05-16  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclCompile.c: Fix crash with tcl_traceExec. Found and fixed
+	by Alexander Pasadyn. [Bug 1964803]
+
+2008-05-15  Pat Thoyts  <patthoyts@users.sourceforge.net>
+
+	* win/makefile.vc: We should use the thread allocator for threaded
+	* win/rules.vc:	   builds. Added 'tclalloc' option to disable.
+
+2008-05-09  George Peter Staplin  <georgeps@xmission.com>
+
+	* tools/tsdPerf.c:	A loadable Tcl extension for testing TSD
+	performance.
+	* tools/tsdPerf.tcl:	A simplistic tool that uses the thread
+	extension and tsdPerf.so to get some performance metrics by,
+	simulating, simple TSD contention.
+
+2008-05-09  George Peter Staplin  <georgeps@xmission.com>
+
+	* generic/tcl.h:	Make Tcl_ThreadDataKey a void *.
+	* generic/tclInt.h:	Change around some function names and add some
+	new per-platform declarations for thread-specific data functions.
+	* generic/tclThread.c:	Make use of of the new function names that no
+	longer have a Tclp prefix.
+	* generic/tclThreadStorage.c: Replace the core thread-specific data
+	(TSD) mechanism with an array offset solution that eliminates the hash
+	tables, and only uses one slot of native TSD. Many thanks to Kevin B.
+	Kenny for his help with this.
+
+	* unix/tclUnixThrd.c:	Add platform-specific TSD functions for use by
+	* win/tclWinThrd.c:	tclThreadStorage.c.
+
+2008-05-09  Kevin B. Kenny  <kennykb@acm.org>
+
+	* tests/dict.test (dict-19.2): Corrected a bug where the test was
+	changed to use [apply] instead of a temporary proc, but the cleanup
+	script still attempted to delete the temporary proc.
+
+2008-05-07  Donal K. Fellows  <dkf@cspool38.cs.man.ac.uk>
+
+	* generic/tclCompCmds.c (TclCompileDictAppendCmd): Fix silly off-by
+	one error that caused a crash every time a compiled 'dict append' with
+	more than one argument was used. Found by Colin McCormack.
+
+2008-05-02  Pat Thoyts  <patthoyts@users.sourceforge.net>
+
+	* generic/tclBasic.c:	 Converted the [binary] command into an
+	* generic/tclBinary.c:	 ensemble.
+	* generic/tclInt.h:
+	* test/binary.test:	 Updated the error tests for ensemble errors.
+
+	* generic/tclFileName.c: Reverted accidental commit of TIP 316 APIs.
+
+2008-04-27  Donal K. Fellows  <dkf@users.sf.net>
+
+	* */*.c: A large tranche of getting rid of pre-C89-isms; if your
+	compiler doesn't support things like proper function declarations,
+	'void' and 'const', borrow a proper one when building Tcl. (The header
+	files allow building things that link against Tcl with really ancient
+	compilers still; the requirement is just when building Tcl itself.)
+
+2008-04-26  Zoran Vasiljevic  <vasiljevic@users.sourceforge.net>
+
+	* generic/tclAsync.c: Tcl_AsyncDelete(): panic if attempt to locate
+	handler token fails. Happens when some other thread attempts to delete
+	somebody else's token.
+
+	Also, panic early if we find out the wrong thread attempting to delete
+	the async handler (common trap). As, only the one that created the
+	handler is allowed to delete it.
+
+2008-04-24  Andreas Kupries  <andreask@activestate.com>
+
+	* tests/ioCmd.test: Extended testsuite for reflected channel
+	implementation. Added test cases about how it handles if the rug is
+	pulled out from under a channel (= killing threads, interpreters
+	containing the tcl command for a channel, and channel sitting in a
+	different interpreter/thread.)
+
+	* generic/tclIORChan.c: Fixed the bugs exposed by the new testcases,
+	redone most of the cleanup and exit handling.
+
+2008-04-21  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclIOUtil.c:		Removed all code delimited by
+	* generic/tclTest.c:		USE_OBSOLETE_FS_HOOKS, completing
+	* tests/ioCmd.test:		the deprecation path for these
+	* tests/ioUtil.test (removed):	obsolete interfaces. (Code was active
+	in Tcl 8.4, present but enabled only by customized compile switch in
+	Tcl 8.5, and now completely gone for Tcl 8.6). Also removed all tests
+	relevant only to the removed interfaces.
+
+2008-04-19  George Peter Staplin  <georgeps@xmission.com>
+
+	* doc/Ensemble.3: Fix a typo: s/defiend/defined/
+	Thanks to hat0 for spotting this.
+
+2008-04-16  Daniel Steffen  <das@users.sourceforge.net>
+
+	* generic/tclInt.h:		Make stubs tables 'static const' and
+	* generic/tclStubInit.c:	export only module-scope pointers to
+	* generic/tclStubLib.c:		the main stubs tables (for package
+	* tools/genStubs.tcl:		initialization). [Patch 1938497]
+	* generic/tclBasic.c (Tcl_CreateInterp):
+	* generic/tclTomMathInterface.c (TclTommath_Init):
+
+	* generic/tclInt.h:		Revise Tcl_SetNotifier() to use a
+	* generic/tclNotify.c:		module-scope hooks table instead of
+	* generic/tclStubInit.c:	runtime stubs-table modification;
+	* macosx/tclMacOSXNotify.c:	ensure all hookable notifier functions
+	* win/tclWinNotify.c:		check for hooks; remove hook checks in
+	* unix/tclUnixNotfy.c:		notifier API callers. [Patch 1938497]
+
+2008-04-15  Andreas Kupries  <andreask@activestate.com>
+
+	* generic/tclIO.c (CopyData):	Applied another patch by Alexandre
+	* io.test (io-53.8a):		Ferrieux <ferrieux@users.sf.net>,
+	* chanio.test (chan-io-53.8a):	to shift EOF handling to the async
+	part of the command if a callback is specified, should the channel be
+	at EOF already when fcopy is called. Testcase by myself.
+
+2008-04-15  Daniel Steffen  <das@users.sourceforge.net>
+
+	* unix/Makefile.in:	Adjust tclDTrace.h dependencies for removal
+				of tclStubLib.o from TCL_OBJS. [Bug 1942795]
+
+2008-04-14  Kevin B. Kenny  <kennykb@acm.org>
+
+	* unix/tclUnixTime.c (NativeGetTime): Removed obsolete use of
+	'struct timezone' in the call to 'gettimeofday'. [Bug 1942197]
+
+	* tests/clock.test (clock-33.5, clock-33.5a, clock-33.8, clock-33.8a):
+	Added comments to the test that it can fail on a heavily loaded
+	system.
+
+2008-04-10  Andreas Kupries  <andreask@activestate.com>
+
+	* generic/tclIOCmd.c (Tcl_FcopyObjCmd): Keeping check for negative
+	values, changed to not be an error, but behave like the special value
+	-1 (copy all, default).
+
+	* tests/iocmd.test (iocmd-15.{12,13}): Removed.
+
+	* tests/io.test (io-52.5{,a,b}): Reverted last change, added
+	* tests/chanio.test (chan-io-52.5{,a,b}): comment regarding the
+	meaning of -1, added two more testcases for other negative values,
+	and input wrapped to negative.
+
+2008-04-09  Donal K. Fellows  <dkf@users.sf.net>
+
+	* tests/{fCmd,unixFCmd,winFCmd,winFile}.test: Tidying up of the test
+	suite to make better use of tcltest2 and be clearer about what is
+	being tested.
+
+	* win/Makefile.in (html): Added target for doing convenient
+	documentation builds, mirroring the one from unix/Makefile.
+
+2008-04-09  Andreas Kupries  <andreask@activestate.com>
+
+	* tests/chanio.test (chan-io-52.5): Removed '-size -1' from test,
+	* tests/io.test (io-52.5): does not seem to have any bearing, and was
+	an illegal value. Test case is not affected by the value of -size,
+	test flag restoration and that evrything was properly copied.
+
+	* generic/tclIOCmd.c (Tcl_FcopyObjCmd): Added checking of -size value
+	* tests/ioCmd.test (iocmd-15.{13,14}): to reject negative values, and
+	values overflowing 32-bit signed. Basic patch by Alexandre Ferrieux
+	<ferrieux@users.sourceforge.net>, with modifications from me to
+	separate overflow from true negative value. Extended testsuite. [Bug
+	1557855]
+
+2008-04-09  Daniel Steffen  <das@users.sourceforge.net>
+
+	* tests/chanio.test (chan-io-53.8,53.9,53.10): Fix typo & quoting for
+	* tests/io.test (io-53.8,53.9,53.10):	       spaces in builddir path
+
+2008-04-08  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclExecute.c: Added comments to the alignment macros used in
+	GrowEvaluationStack() and friends.
+
+2008-04-08  Daniel Steffen  <das@users.sourceforge.net>
+
+	* tools/genStubs.tcl:	Revert erroneous 2008-04-02 change marking
+				*StubsPtr as EXTERN instead of extern.
+
+	* generic/tclDecls.h:	make genstubs
+	* generic/tclIntDecls.h:
+	* generic/tclIntPlatDecls.h:
+	* generic/tclPlatDecls.h:
+	* generic/tclTomMathDecls.h:
+
+2008-04-07  Andreas Kupries  <andreask@activestate.com>
+
+	* tests/io.test (io-53.10): Testcase for bi-directional fcopy.
+	* tests/chanio.test:
+	* generic/tclIO.c: Additional changes to data structures for fcopy and
+	* generic/tclIO.h: channels to perform proper cleanup in case of a
+	channel having two background copy operations running as is now
+	possible.
+
+	* generic/tclIO.c (BUSY_STATE, CheckChannelErrors, TclCopyChannel):
+	New macro, and the places using it. This change allows for
+	bi-directional fcopy on channels. Thanks to Alexandre Ferrieux
+	<ferrieux@users.sourceforge.net> for the patch. [Bug 1350564]
+
+2008-04-07  Reinhard Max  <max@suse.de>
+
+	* generic/tclStringObj.c (Tcl_AppendFormatToObj): Fix [format {% d}]
+	so that it behaves the same way as in 8.4 and as C's printf().
+	* tests/format.test: Add a test for '% d' and '%+d'.
+
+2008-04-05  Kevin B. Kenny  <kennykb@acm.org>
+
+	* win/tclWinFile.c: (WinSymLinkDirectory): Fixed a problem that Tcl
+	was creating an NTFS junction point (IO_REPARSE_TAG_MOUNT_POINT) but
+	filling in the union member for a Vista symbolic link. We had gotten
+	away with this error because the union member
+	(SymbolicLinkReparseBuffer) was misdefined in this file and in the
+	'winnt.h' in early versions of MinGW. MinGW 3.4.2 has the correct
+	definition of SymbolicLinkReparseBuffer, exposing the mismatch, and
+	making tests cmdAH-19.4.1, fCmd-28.*, and filename-11.* fail.
+	* tests/chanio.test (chan-io-53.9):
+	* tests/io.test (io-53.9): Made test cleanup robust against the
+	possibility of slow process shutdown on Windows.
+
+	* win/tcl.m4: Added -D_CRT_SECURE_NO_DEPRECATE and
+	-DCRT_NONSTDC_NO_DEPRECATE to the MSVC compilation flags so that the
+	compilation doesn't barf on perfectly reasonable Posix system calls.
+	* win/configure: Manually patched (don't have the right autoconf to
+	hand).
+
+2008-04-04  Andreas Kupries  <andreask@activestate.com>
+
+	* tests/io.test (io-53.9): Added testcase for [Bug 780533], based
+	* tests/chanio.test: on Alexandre's test script. Also fixed problem
+	with timer in preceding test, was not canceled properly in the ok case
+
+2008-04-04  Andreas Kupries  <andreask@activestate.com>
+
+	* generic/tclIORChan.c (ReflectOutput): Allow zero return from write
+	when input was zero-length anyway. Otherwise keept it an error, and
+	separate the message from 'written too much'.
+
+	* tests/ioCmd.test (iocmd-24.6): Testcase updated for changed message.
+
+	* generic/tclIORChan.c (ReflectClose): Added missing removal of the
+	now closed channel from the reflection map. Before we could crash the
+	system by invoking 'chan postevent' on a closed reflected channel,
+	dereferencing the dangling pointer in the map.
+
+	* tests/ioCmd.test (iocmd-31.8): Testcase for the above.
+
+2008-04-03  Andreas Kupries  <andreask@activestate.com>
+
+	* generic/tclIO.c (CopyData): Applied patch [Bug 1932639] to
+	* tests/io.test: prevent fcopy from calling -command synchronously
+	* tests/chanio.test: the first time. Thanks to Alexandre Ferrieux
+	<ferrieux@users.sourceforge.net> for report and patch.
+
+2008-04-02  Daniel Steffen  <das@users.sourceforge.net>
+
+	* generic/tcl.decls:	Remove 'export' declarations of symbols now
+				only in libtclstub and no longer in libtcl.
+
+	* generic/tclStubLib.c:	Make symbols in libtclstub.a MODULE_SCOPE to
+	* tools/genStubs.tcl:	avoid exporting them from libraries that link
+				with -ltclstub; constify tcl*StubsPtr and stub
+				table hook pointers. [Bug 1819422]
+
+	* generic/tclDecls.h:	make genstubs
+	* generic/tclIntDecls.h:
+	* generic/tclIntPlatDecls.h:
+	* generic/tclPlatDecls.h:
+	* generic/tclStubInit.c:
+	* generic/tclTomMathDecls.h:
+
+2008-04-02  Andreas Kupries  <andreask@activestate.com>
+
+	* generic/tclIO.c (CopyData): Applied patch for fcopy problem [Bug
+	780533], with many thanks to Alexandre Ferrieux
+	<ferrieux@users.sourceforge.net> for tracking it down and providing a
+	solution. Still have to convert his test script into a proper test
+	case.
+
+2008-04-01  Andreas Kupries  <andreask@activestate.com>
+
+	* generic/tclStrToD.c: Applied patch for [Bug 1839067] (fp rounding
+	* unix/tcl.m4:	       setup on solaris x86, native cc), provided by
+			       Michael Schlenker.
+
+2008-04-01  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclStubLib.c:	Removed needless #ifdef complexity.
+
+	* generic/tclStubLib.c (Tcl_InitStubs):	Added missing error message.
+	* generic/tclPkg.c (Tcl_PkgInitStubsCheck):
+
+	* README:		Bump version number to 8.6a0
+	* generic/tcl.h:
+	* library/init.tcl:
+	* macosx/Tcl-Common.xcconfig:
+	* macosx/Tcl.pbproj/default.pbxuser:
+	* macosx/Tcl.pbproj/project.pbxproj:
+	* tools/tcl.wse.in:
+	* unix/configure.in:
+	* unix/tcl.spec:
+	* win/README:
+	* win/configure.in:
+	* win/makefile.bc:
+	* win/tcl.m4:
+
+	* unix/configure:	autoconf-2.59
+	* win/configure:
+
+	* generic/tclBasic.c:	Revised stubs-generation tool and interp
+	* tools/genStubs.tcl:	creation so that "tclStubsPtr" is not present
+	* unix/Makefile.in:	in libtcl.so, but is present only in
+	* win/Makefile.in:	libtclstub.a. This tightens up the rules for
+	* win/makefile.bc:	users of the stubs interfaces. [Bug 1819422]
+	* win/makefile.vc:
+
+	* generic/tclDecls.h:	make genstubs
+	* generic/tclIntDecls.h:
+	* generic/tclIntPlatDecls.h:
+	* generic/tclPlatDecls.h:
+	* generic/tclTomMathDecls.h:
+
+2008-03-30  Kevin Kenny  <kennykb@acm.org>
+
+	* generic/tclInt.h (TclIsNaN):
+	* unix/configure.in: Added code to the configurator to check for a
+			     standard isnan() macro and use it if one is
+			     found. This change avoids bugs where the test of
+			     ((d) != (d)) is optimized away by an
+			     overaggressive compiler. [Bug 1783544]
+	* generic/tclObj.c: Added missing #include <math.h> needed to locate
+			    isnan() after the above change.
+
+	* unix/configure: autoconf-2.61
+
+	* tests/mathop.test (mathop-25.9, mathop-25.14): Modified tests to
+	deal with (slightly buggy) math libraries in which pow() returns an
+	incorrectly rounded result. [Bug 1808174]
+
+2008-03-26  Don Porter  <dgp@users.sourceforge.net>
+
+	*** 8.5.2 TAGGED FOR RELEASE ***
+
+	* generic/tcl.h:	Bump to 8.5.2 for release.
+	* library/init.tcl:
+	* tools/tcl.wse.in:
+	* unix/configure.in:
+	* unix/tcl.spec:
+	* win/configure.in:
+
+	* unix/configure:	autoconf-2.59
+	* win/configure:
+
+	* changes:		Updated for 8.5.2 release.
+
+2008-03-28  Donal K. Fellows  <dkf@users.sf.net>
+
+	* tests/fCmd.test: Substantial rewrite to use many more tcltest
+	features. Great reduction in quantity of [catch] gymnastics. Several
+	buggy tests fixed, including one where the result of the previous test
+	was being checked!
+
+2008-03-27  Kevin B. Kenny  <kennykb@acm.org>
+
+	* library/tzdata/America/Marigot:
+	* library/tztata/America/St_Barthelemy:
+	* library/tzdata/America/Argentina/San_Luis:
+	* library/tzdata/Asia/Ho_Chi_Minh:
+	* library/tzdata/Asia/Kolkata:	(new files)
+	* library/tzdata/America/Caracas:
+	* library/tzdata/America/Havana:
+	* library/tzdata/America/Santiago:
+	* library/tzdata/America/Argentina/Buenos_Aires:
+	* library/tzdata/America/Argentina/Catamarca:
+	* library/tzdata/America/Argentina/Cordoba:
+	* library/tzdata/America/Argentina/Jujuy:
+	* library/tzdata/America/Argentina/La_Rioja:
+	* library/tzdata/America/Argentina/Mendoza:
+	* library/tzdata/America/Argentina/Rio_Gallegos:
+	* library/tzdata/America/Argentina/San_Juan:
+	* library/tzdata/America/Argentina/Tucuman:
+	* library/tzdata/America/Argentina/Ushuaia:
+	* library/tzdata/Asia/Baghdad:
+	* library/tzdata/Asia/Calcutta:
+	* library/tzdata/Asia/Damascus:
+	* library/tzdata/Asia/Saigon:
+	* library/tzdata/Pacific/Easter:
+		Changes up to and including Olson's tzdata2008b.
+
+2008-03-27  Daniel Steffen  <das@users.sourceforge.net>
+
+	* unix/tcl.m4 (SunOS-5.1x): Fix 64bit support for Sun cc. [Bug
+	1921166]
+
+	* unix/configure: autoconf-2.59
+
+2008-03-26  Don Porter  <dgp@users.sourceforge.net>
+
+	* changes:		Updated for 8.5.2 release.
+
+2008-03-24  Pat Thoyts  <patthoyts@users.sourceforge.net>
+
+	* generic/tclBinary.c: [Bug 1923966] - crash in binary format
+	* tests/binary.test:   Added tests for the above crash condition.
+
+2008-03-21  Donal K. Fellows  <dkf@users.sf.net>
+
+	* doc/switch.n: Clarified documentation in respect of two-argument
+	invokation. [Bug 1899962]
+
+	* tests/switch.test: Added more tests of regexp-mode compilation of
+	the [switch] command. [Bug 1854435]
+
+2008-03-20  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tcl.h, generic/tclThreadAlloc.c: Tidied up the declarations
+	of Tcl_GetMemoryInfo so that it is always defined. Will panic when
+	called against a Tcl that was previously built without it at all,
+	which is OK because that also indicates a serious mismatch between
+	memory configuration options.
+
+2008-03-19  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tcl.h, generic/tclThreadAlloc.c (Tcl_GetMemoryInfo): Make
+	sure this function is available when direct linking. [Bug 1868171]
+
+	* tests/reg.test (reg-33.14): Marked nonPortable because some
+	environments have small default stack sizes. [Bug 1905562]
+
+2008-03-18  Andreas Kupries  <andreask@activestate.com>
+
+	* library/tm.tcl (::tcl::tm::UnknownHandler): Changed 'source' to
+	'source -encoding utf-8'. This fixes a portability problem of Tcl
+	Modules pointed out by Don Porter. By using plain 'source' we were at
+	the mercy of 'encoding system', making modules less portable than they
+	could be. The exact scenario: A writes a TM in some weird encoding
+	which is A's system encoding, distributes it, and somewhere else it
+	cannot be read/used because the system encoding is different. Forcing
+	the use of utf-8 makes the module portable.
+
+	***INCOMPATIBILITY*** for all Tcl Modules already written in non-utf-8
+	compatible encodings.
+
+2008-03-18  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclExecute.c:	Patch from Miguel Sofer to correct the
+	alignment of memory allocated by GrowEvaluationStack(). [Bug 1914503]
+
+2008-03-18  Andreas Kupries  <andreask@activestate.com>
+
+	* library/tm.tcl (::tcl::tm::Defaults): Modified handling of
+	environment variables. Solution slightly different than proposed in
+	the report. Using the underscored form TCLX_y_TM_PATH even if
+	TCLX.y_TM_PATH exists. Also using a loop to cut prevent code
+	replication. [Bug 1914604]
+
+2008-03-16  Donal K. Fellows  <dkf@users.sf.net>
+
+	* generic/tclCompCmds.c (TclCompileDictForCmd): Correct the handling
+	of stack space calculation (the jump pattern used was confusing the
+	simple-minded code doing the calculations). [Bug 1903325]
+
+	* doc/lreplace.n: Clarified documentation of what happens with
+	negative indices. [Bug 1905809] Added example, tidied up formatting.
+
+2008-03-14  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclBasic.c (OldMathFuncProc):	Same workaround protection
+	from bad TclStackAlloc() alignment. Thanks George Peter Staplin.
+
+	* generic/tclCmdIL.c (Tcl_LsortObjCmd):	Use ckalloc() to allocate
+	SortElement arrays instead of TclStackAlloc() which isn't getting
+	alignment right. Workaround for [Bug 1914503].
+
+2008-03-14  Reinhard Max  <max@suse.de>
+
+	* generic/tclTest.c:  Ignore the return value of write() when we are
+	* unix/tclUnixPipe.c: about to exit anyways.
+
+2008-03-13  Daniel Steffen  <das@users.sourceforge.net>
+
+	* unix/configure.in: Use backslash-quoting instead of double-quoting
+	* unix/tcl.m4:	     for lib paths in tclConfig.sh. [Bug 1913622]
+	* unix/configure:    autoconf-2.59
+
+2008-03-13  Don Porter  <dgp@users.sourceforge.net>
+
+	* changes:		Updated for 8.5.2 release.
+
+	* generic/tclStrToD.c:	Resolve identifier conflict over "pow10" with
+	libm in Cygwin and DJGPP. Thanks to Gordon Schumacher and Philip
+	Moore. [Patch 1800636]
+
+2008-03-12  Daniel Steffen  <das@users.sourceforge.net>
+
+	* macosx/Tcl.xcodeproj/project.pbxproj:	Add support for Xcode 3.1
+	* macosx/Tcl.xcodeproj/default.pbxuser:	CODE_SIGN_IDENTITY and
+	* macosx/Tcl-Common.xcconfig:		'xcodebuild install'.
+
+2008-03-12  Andreas Kupries  <andreask@activestate.com>
+
+	* doc/info.n: Replaced {expand} with {*}.
+
+2008-03-12  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* unix/Makefile.in (install-libraries):	Bump http to 2.7
+	* win/Makefile.in (install-libraries):	Added -myaddr option to allow
+	* library/http/http.tcl (http::geturl):	control of selected socket
+	* library/http/pkgIndex.tcl:		interface. [Bug 559898]
+	* doc/http.n, tests/http.test:		Added -keepalive and
+	-protocol 1.1 with chunked transfer encoding support. [Bug 1063703,
+	1470377, 219225] (default keepalive is 0)
+	Added ability to override Host in -headers. [Bug 928154]
+	Added -strict option to control URL validation on per-call basis.
+	[Bug 1560506]
+
+2008-03-11  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* library/http/http.tcl (http::geturl): Add -method option to support
+	* tests/http.test (http-3.1):		http PUT and DELETE requests.
+	* doc/http.n:				[Bug 1599901, 862554]
+
+	* library/http/http.tcl: Whitespace changes, code cleanup. Allow http
+	to be re-sourced without overwriting http state.
+
+2008-03-11  Daniel Steffen  <das@users.sourceforge.net>
+
+	* generic/tclEncoding.c (LoadEscapeEncoding): Avoid leaking escape
+	sub-encodings, fixes encoding-11.1 failing after iso2022-jp loaded.
+	[Bug 1893053]
+
+	* macosx/tclMacOSXNotify.c: Avoid using CoreFoundation after fork() on
+	Darwin 9 even when TclpCreateProcess() uses vfork().
+
+	* macosx/Tcl.xcodeproj/project.pbxproj:	Add support for Xcode 3.1 and
+	* macosx/Tcl.xcodeproj/default.pbxuser:	configs for building with
+	* macosx/Tcl-Common.xcconfig:		gcc-4.2 and llvm-gcc-4.2.
+
+	* unix/tclUnixPort.h:			Workaround vfork() problems in
+						llvm-gcc-4.2.1 -O4 build.
+
+	* unix/tclUnixPort.h:			Move MODULE_SCOPE compat
+						define to top. [Bug 1911102]
+
+	* macosx/GNUmakefile:			Fix quoting to allow paths
+	* macosx/Tcl-Common.xcconfig:		to ${builddir} and
+	* unix/Makefile.in:			${INSTALL_ROOT} to contain
+	* unix/configure.in:			spaces.
+	* unix/install-sh:
+	* unix/tcl.m4:
+	* tests/ioCmd.test:
+
+	* unix/configure:			autoconf-2.59
+
+	* unix/Makefile.in (install-strip):	Strip non-global symbols from
+						dynamic library.
+
+	* unix/tclUnixNotfy.c:			Fix warning.
+
+	* tests/exec.test (exec-9.7):		Reduce timing sensitivity
+	* tests/socket.test (socket-2.11):	(esp. on multi-proc machines).
+
+	* tests/fCmd.test (fCmd-9.4):		Skip on Darwin 9 (xfail).
+
+2008-03-11  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclVar.c (TclDeleteNamespaceVars):
+	* tests/var.test (var-8.2): Unset traces on vars should be called with
+	a FQ named during namespace deletion. This was causing infinite loops
+	when unset traces recreated the var, as reported by Julian Noble. [Bug
+	1911919]
+
+2008-03-10  Don Porter  <dgp@users.sourceforge.net>
+
+	* changes:		Updated for 8.5.2 release.
+
+	* doc/http.n:	Revised to indicate that [package require http 2.5.5]
+	is needed to get all the documented commands ([http::meta]).
+
+	* generic/tclEvent.c (TclDefaultBgErrorHandlerObjCmd):	Added error
+	* tests/event.test (event-5.*):	checking to protect against callers
+	passing invalid return options dictionaries. [Bug 1901113]
+
+	* generic/tclBasic.c (ExprAbsFunc):	Revised so that the abs()
+	* tests/expr.test:	function and the [::tcl::mathfunc::abs]
+	command do not return the value of -0, or equivalent values with more
+	alarming string reps like -1e-350. [Bug 1893815]
+
+2008-03-07  Andreas Kupries  <andreask@activestate.com>
+
+	* generic/tclResult.c (ReleaseKeys): Workaround for [Bug 1904907].
+	Reset the return option keys to NULL to allow full re-initialization
+	by GetKeys(). This introduces a memory leak for the key objects, but
+	gets us around a crash in the finalization of reflected channels when
+	handling returns, either at compile- or runtime. In both cases we
+	access the keys after they have been released by their thread exit
+	handler. A proper fix is entangled with the untangling of the
+	finalization ordering and attendant issues. For now we choose the
+	lesser evil.
+
+2008-03-07  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclExecute.c (Tcl_ExprObj):	Revised expression bytecode
+	compiling so that bytecodes invalid due to changing context or due to
+	the difference between expressions and scripts are not reused. [Bug
+	1899164]
+
+	* generic/tclCmdAH.c:	Revised direct evaluation implementation of
+	[expr] so that [expr $e] caches compiled bytecodes for the expression
+	as the intrep of $e.
+
+	* tests/execute.test (execute-6.*):	More tests checking that
+	script bytecode is invalidated in the right situations.
+
+2008-03-07  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* win/configure.in: Add AC_HEADER_STDC to support msys/win64.
+
+2008-03-06  Donal K. Fellows  <dkf@users.sf.net>
+
+	* doc/namespace.n: Minor tidying up. [Bug 1909019]
+
+2008-03-04  Don Porter  <dgp@users.sourceforge.net>
+
+	* tests/execute.test (6.3,4):	Added tests for [Bug 1899164].
+
+2008-03-03  Reinhard Max  <max@suse.de>
+
+	* unix/tclUnixChan.c: Fix mark and space parity on Linux, which uses
+	CMSPAR instead of PAREXT.
+
+2008-03-02  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclNamesp.c (GetNamespaceFromObj):
+	* tests/interp.test (interp-28.2): Spoil the intrep of an nsNameType
+	obj when the reference crosses interpreter boundaries.
+
+2008-02-29  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclResult.c (Tcl_SetReturnOptions):	Revised the refcount
+	management of Tcl_SetReturnOptions to become that of a conventional
+	Consumer routine. Thanks to Peter Spjuth for pointing out the
+	difficulties calling Tcl_SetReturnOptions with non-0-count value for
+	options.
+	* generic/tclExecute.c (INST_RETURN_STK): Revised the one caller
+	within Tcl itself which passes a non-0-count value to
+	Tcl_SetReturnOptions().
+
+	* generic/tclBasic.c (Tcl_AppendObjToErrorInfo):	Revised the
+	refcount management of Tcl_AppendObjToErrorInfo to become that of a
+	conventional Consumer routine. This preserves the ease of use for the
+	overwhelming common callers who pass in a 0-count value, but makes the
+	proper call with a non-0-count value less surprising.
+	* generic/tclEvent.c (TclDefaultBgErrorHandlerObjCmd):	Revised the
+	one caller within Tcl itself which passes a non-0-count value to
+	Tcl_AppendObjToErrorInfo().
+
+2008-02-28  Joe English  <jenglish@users.sourceforge.net>
+
+	* unix/tclPort.h, unix/tclCompat.h, unix/tclUnixChan.h: Reduce scope
+	of <sys/filio.h> and <sys/ioctl.h> #includes. [Patch 1903339]
+
+2008-02-28  Joe English  <jenglish@users.sourceforge.net>
+
+	* unix/tclUnixChan.c, unix/tclUnixNotfy.c, unix/tclUnixPipe.c:
+	Consolidate all code conditionalized on -DUSE_FIONBIO into one place.
+	* unix/tclUnixPort.h, unix/tclUnixCompat.c: New routine
+	TclUnixSetBlockingMode(). [Patch 1903339]
+
+2008-02-28  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclBasic.c (TclEvalObjvInternal):	Plug memory leak when
+	an enter trace deletes or changes the command, prompting a reparsing.
+	Don't let the second pass lose commandPtr value allocated during the
+	first pass.
+
+	* generic/tclCompExpr.c (ParseExpr):	Plug memory leak in error
+	message generation.
+
+	* generic/tclStringObj.c (Tcl_AppendFormatToObj): [format %llx $big]
+	leaked an mp_int.
+
+	* generic/tclCompCmds.c (TclCompileReturnCmd):	The 2007-10-18 commit
+	to optimize compiled [return -level 0 $x] [RFE 1794073] introduced a
+	memory leak of the return options dictionary. Fixing that.
+
+2008-02-27  Pat Thoyts  <patthoyts@users.sourceforge.net>
+
+	* library/http/http.tcl: [Bug 705956] - fix inverted logic when
+	cleaning up socket error in geturl.
+
+2008-02-27  Kevin B. Kenny  <kennykb@acm.org>
+
+	* doc/clock.n: Corrected minor indentation gaffe in the penultimate
+	paragraph. [Bug 1898025]
+	* generic/tclClock.c (ParseClockFormatArgs): Changed to check that the
+	clock value is in the range of a 64-bit integer. [Bug 1862555]
+	* library/clock.tcl (::tcl::clock::format, ::tcl::clock::scan,
+	(::tcl::clock::add, ::tcl::clock::LocalizeFormat): Fixed bugs in
+	caching of localized strings that caused weird results when localized
+	date/time formats were used. [Bug 1902423]
+	* tests/clock.test (clock-61.*, clock-62.1): Regression tests for [Bug
+	1862555] and [Bug 1902423].
+
+2008-02-26  Joe English  <jenglish@users.sourceforge.net>
+
+	* generic/tclIOUtil.c, unix/tclUnixPort.h, unix/tclUnixChan.c:
+	Remove dead/unused portability-related #defines and unused conditional
+	code. See [Patch 1901828] for discussion.
+
+2008-02-26  Joe English  <jenglish@users.sourceforge.net>
+
+	* generic/tclIORChan.c (enum MethodName),
+	* generic/tclCompExpr.c (enum Marks): More stray trailing ","s
+
+2008-02-26  Joe English  <jenglish@users.sourceforge.net>
+
+	* unix/configure.in(socklen_t test): Define socklen_t as "int" if
+	missing, not "unsigned". Use AC_TRY_COMPILE instead of
+	AC_EGREP_HEADER.
+	* unix/configure: regenerated.
+
+2008-02-26  Joe English  <jenglish@users.sourceforge.net>
+
+	* generic/tclCompile.h: Remove stray trailing "," from enum
+	InstOperandType definition (C99ism).
+
+2008-02-26  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* generic/tclUtil.c (TclReToGlob): Fix the handling of the last star
+	* tests/regexpComp.test:	   possibly being escaped in
+	determining right anchor. [Bug 1902436]
+
+2008-02-26  Pat Thoyts  <patthoyts@users.sourceforge.net>
+
+	* library/http/pkgIndex.tcl: Set version 2.5.5
+	* library/http/http.tcl:     It is better to do the [eof] check after
+	trying to read from the socket. No clashes found in testing. Added
+	http::meta command to access the http headers. [Bug 1868845]
+
+2008-02-22  Pat Thoyts  <patthoyts@users.sourceforge.net>
+
+	* library/http/pkgIndex.tcl: Set version 2.5.4
+	* library/http/http.tcl:     Always check that the state array exists
+	in the http::status command. [Bug 1818565]
+
+2008-02-13  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tcl.h:	Bump version number to 8.5.2b1 to distinguish
+	* library/init.tcl:	CVS development snapshots from the 8.5.1 and
+	* unix/configure.in:	8.5.2 releases.
+	* unix/tcl.spec:
+	* win/configure.in:
+	* README
+
+	* unix/configure:	autoconf (2.59)
+	* win/configure:
+
+2008-02-12  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* generic/tclCompCmds.c (TclCompileSwitchCmd): Corrected logic for
+	* tests/switch.test (switch-10.15): handling -nocase compilation; the
+	-exact -nocase option cannot be compiled currently. [Bug 1891827]
+
+	* unix/README: Documented missing configure flags. [Bug 1799011]
+
+2008-02-06  Kevin B. Kenny  <kennykb@acm.org>
+
+	* doc/clock.n (%N): Corrected an error in the explanation of the %N
+	format group.
+	* generic/tclClock.c (ClockParseformatargsObjCmd):
+	* library/clock.tcl (::tcl::clock::format):
+	* tests/clock.test (clock-1.0, clock-1.4):
+	Performance enhancements in [clock format] (moving the analysis of
+	$args into C code, holding on to Tcl_Objs with resolved command names,
+	[lassign] in place of [foreach], avoiding [namespace which] for
+	command resolution).
+
+2008-02-04  Don Porter  <dgp@users.sourceforge.net>
+
+	*** 8.5.1 TAGGED FOR RELEASE ***
+
+	* changes:		Updated for 8.5.1 release.
+
+	* generic/tcl.h:	Bump to 8.5.1 for release.
+	* library/init.tcl:
+	* tools/tcl.wse.in:
+	* unix/configure.in:
+	* unix/tcl.spec:
+	* win/configure.in:
+
+	* unix/configure:	autoconf-2.59
+	* win/configure:
+
+2008-02-04  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclExecute.c (INST_CONCAT1): Fix optimisation for in-place
+	concatenation (was going over String type)
+
+2008-02-02  Daniel Steffen  <das@users.sourceforge.net>
+
+	* unix/configure.in (Darwin):	Correct Info.plist year substitution
+					in non-framework builds.
+
+	* unix/configure:		autoconf-2.59
+
+2008-01-30  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclInterp.c (Tcl_GetAlias): Fix for [Bug 1882373], thanks go
+	to an00na.
+
+2008-01-30  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* tools/tcltk-man2html.tcl: Reworked manual page scraper to do a
+	proper job of handling references to Ttk options. [Tk Bug 1876493]
+
+2008-01-29  Donal K. Fellows  <donal.k.fellows@man.ac.uk>
+
+	* doc/man.macros (SO, SE): Adjusted macros so that it is possible for
+	Ttk to have its "standard options" on a manual page that is not called
+	"options". [Tk Bug 1876493]
+
+2008-01-25  Don Porter  <dgp@users.sourceforge.net>
+
+	* changes:		Updated for 8.5.1 release.
+
+2008-01-23  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclInt.h:		New macro TclGrowParseTokenArray() to
+	* generic/tclCompCmds.c:	simplify code that might need to grow
+	* generic/tclCompExpr.c:	an array of Tcl_Tokens in the parsePtr
+	* generic/tclParse.c:		field of a Tcl_Parse. Replaces the
+	TclExpandTokenArray() routine via replacing:
+		int needed = parsePtr->numTokens + growth;
+		while (needed > parsePtr->tokensAvailable) {
+		    TclExpandTokenArray(parsePtr);
+		}
+	with:
+		TclGrowParseTokenArray(parsePtr, growth);
+	This revision merged over from dgp-refactor branch.
+
+	* generic/tclCompile.h:	Demote TclCompEvalObj() from internal stubs to
+	* generic/tclInt.decls:	a MODULE_SCOPE routine declared in
+	tclCompile.h.
+
+	* generic/tclIntDecls.h:	make genstubs
+	* generic/tclStubInit.c:
+
+2008-01-22  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclTimer.c (AfterProc):	Replace Tcl_EvalEx() with
+	Tcl_EvalObjEx() to evaluate [after] callbacks. Part of trend to favor
+	compiled execution over direct evaluation.
+
+2008-01-22  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclCmdIl.c (Tcl_LreverseObjCmd):
+	* tests/cmdIL.test (cmdIL-7.7): Fix crash on reversing an empty list.
+	[Bug 1876793]
+
+2008-01-20  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* unix/README: Minor typo fixes [Bug 1853072]
+
+	* generic/tclIO.c (TclGetsObjBinary): Operate on topmost channel.
+	[Bug 1869405] (Ficicchia)
+
+2008-01-17  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclCompExpr.c:	Revision to preserve parsed intreps of
+	numeric and boolean literals when compiling expressions with (optimize
+	== 1).
+
+2008-01-15  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclCompExpr.c: Add an 'optimize' argument to
+	* generic/tclCompile.c:	 TclCompileExpr() to profit from better
+	* generic/tclCompile.h:	 literal management according to usage.
+	* generic/tclExecute.c:
+
+	* generic/tclCompExpr.c: Fix literal leak in exprs [Bug 1869989] (dgp)
+	* generic/tclExecute.c:
+	* tests/compExpr.test:
+
+	* doc/proc.n: Changed wording for access to non-local variables; added
+	mention to [namespace upvar]. Lame attempt at dealing with
+	documentation. [Bug 1872708]
+
+2008-01-15  Miguel Sofer  <msofer@users.sf.net>
+
+	* generic/tclBasic.c:	 Replacing 'operator' by 'op' in the def of
+	* generic/tclCompExpr.c: struct TclOpCmdClientData to accommodate C++
+	* generic/tclCompile.h:	 compilers. [Bug 1855644]
+
+2008-01-13  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* win/tclWinSerial.c (SerialCloseProc, TclWinOpenSerialChannel): Use
+	critical section for read & write side. [Bug 1353846] (newman)
+
+2008-01-11  Miguel Sofer  <msofer@users.sf.net>
+
+	* unix/tclUnixThrd.c (TclpThreadGetStackSize): Restore stack checking
+	functionality in freebsd. [Bug 1850424]
+
+	* unix/tclUnixThrd.c (TclpThreadGetStackSize): Fix for crash in
+	freebsd. [Bug 1860425]
+
+2008-01-10  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tclStringObj.c (Tcl_AppendFormatToObj):  Correct failure to
+	* tests/format.test:	account for big.used == 0 corner case in the
+	%ll(idox) format directives. [Bug 1867855]
+
+2008-01-09  George Peter Staplin  <georgeps@xmission.com>
+
+	* doc/vwait.n: Add a missing be to fix a typo.
+
+2008-01-04  Jeff Hobbs  <jeffh@ActiveState.com>
+
+	* tools/tcltk-man2html.tcl (make-man-pages): Make man page title use
+	more specific info on lhs to improve tabbed browser view titles.
+
+2008-01-02  Donal K. Fellows  <dkf@users.sf.net>
+
+	* doc/binary.n: Fixed documentation bug reported on tcl-core, and
+	reordered documentation to discourage people from using the hex
+	formatter that is hardly ever useful.
+
+2008-01-02  Don Porter  <dgp@users.sourceforge.net>
+
+	* generic/tcl.h:	Bump version number to 8.5.1b1 to distinguish
+	* library/init.tcl:	CVS development snapshots from the 8.5.0 and
+	* unix/configure.in:	8.5.1 releases.
+	* unix/tcl.spec:
+	* win/configure.in:
+	* README
+
+	* unix/configure:	autoconf (2.59)
+	* win/configure:
+
+	******************************************************************
+	*** CHANGELOG ENTRIES FOR 2006-2007 IN "ChangeLog.2007"	       ***
+	*** CHANGELOG ENTRIES FOR 2005 IN "ChangeLog.2005"	       ***
+	*** CHANGELOG ENTRIES FOR 2004 IN "ChangeLog.2004"	       ***
+	*** CHANGELOG ENTRIES FOR 2003 IN "ChangeLog.2003"	       ***
+	*** CHANGELOG ENTRIES FOR 2002 IN "ChangeLog.2002"	       ***
+	*** CHANGELOG ENTRIES FOR 2001 IN "ChangeLog.2001"	       ***
+	*** CHANGELOG ENTRIES FOR 2000 IN "ChangeLog.2000"	       ***
+	*** CHANGELOG ENTRIES FOR 1999 AND EARLIER IN "ChangeLog.1999" ***
+	******************************************************************
diff --git a/README b/README
new file mode 100644
index 0000000..401b6e6
--- /dev/null
+++ b/README
@@ -0,0 +1,185 @@
+README:  Tcl
+    This is the Tcl 8.6.6 source distribution.
+	http://sourceforge.net/projects/tcl/files/Tcl/
+    You can get any source release of Tcl from the URL above.
+
+Contents
+--------
+    1. Introduction
+    2. Documentation
+    3. Compiling and installing Tcl
+    4. Development tools
+    5. Tcl newsgroup
+    6. The Tcler's Wiki
+    7. Mailing lists
+    8. Support and Training
+    9. Tracking Development
+    10. Thank You
+
+1. Introduction
+---------------
+Tcl provides a powerful platform for creating integration applications that
+tie together diverse applications, protocols, devices, and frameworks.
+When paired with the Tk toolkit, Tcl provides the fastest and most powerful
+way to create GUI applications that run on PCs, Unix, and Mac OS X.
+Tcl can also be used for a variety of web-related tasks and for creating
+powerful command languages for applications.
+
+Tcl is maintained, enhanced, and distributed freely by the Tcl community.
+Source code development and tracking of bug reports and feature requests
+takes place at:
+
+	http://core.tcl.tk/
+
+Tcl/Tk release and mailing list services are hosted by SourceForge:
+
+	http://sourceforge.net/projects/tcl/
+
+with the Tcl Developer Xchange hosted at:
+
+	http://www.tcl.tk/
+
+Tcl is a freely available open source package.  You can do virtually
+anything you like with it, such as modifying it, redistributing it,
+and selling it either in whole or in part.  See the file
+"license.terms" for complete information.
+
+2. Documentation
+----------------
+
+Extensive documentation is available at our website.
+The home page for this release, including new features, is
+	http://www.tcl.tk/software/tcltk/8.6.html
+
+Detailed release notes can be found at the file distributions page
+by clicking on the relevant version.
+	http://sourceforge.net/projects/tcl/files/Tcl/
+
+Information about Tcl itself can be found at
+	http://www.tcl.tk/about/
+
+There have been many Tcl books on the market.  Many are mentioned in the Wiki:
+	http://wiki.tcl.tk/_/ref?N=25206
+
+To view the complete set of reference manual entries for Tcl 8.6 online,
+visit the URL:
+	http://www.tcl.tk/man/tcl8.6/
+
+2a. Unix Documentation
+----------------------
+
+The "doc" subdirectory in this release contains a complete set of
+reference manual entries for Tcl.  Files with extension ".1" are for
+programs (for example, tclsh.1); files with extension ".3" are for C
+library procedures; and files with extension ".n" describe Tcl
+commands.  The file "doc/Tcl.n" gives a quick summary of the Tcl
+language syntax.  To print any of the man pages on Unix, cd to the
+"doc" directory and invoke your favorite variant of troff using the
+normal -man macros, for example
+
+		ditroff -man Tcl.n
+
+to print Tcl.n.  If Tcl has been installed correctly and your "man" program
+supports it, you should be able to access the Tcl manual entries using the
+normal "man" mechanisms, such as
+
+		man Tcl
+
+2b. Windows Documentation
+-------------------------
+
+The "doc" subdirectory in this release contains a complete set of Windows
+help files for Tcl.  Once you install this Tcl release, a shortcut to the
+Windows help Tcl documentation will appear in the "Start" menu:
+
+	Start | Programs | Tcl | Tcl Help
+
+3. Compiling and installing Tcl
+-------------------------------
+
+There are brief notes in the unix/README, win/README, and macosx/README about
+compiling on these different platforms.  There is additional information
+about building Tcl from sources at
+
+	http://www.tcl.tk/doc/howto/compile.html
+
+4. Development tools
+---------------------------
+
+ActiveState produces a high quality set of commercial quality development
+tools that is available to accelerate your Tcl application development.
+Tcl Dev Kit builds on the earlier TclPro toolset and provides a debugger,
+static code checker, single-file wrapping utility, bytecode compiler and
+more.  More information can be found at
+
+	http://www.ActiveState.com/Tcl
+
+5. Tcl newsgroup
+----------------
+
+There is a USENET news group, "comp.lang.tcl", intended for the exchange of
+information about Tcl, Tk, and related applications.  The newsgroup is a
+great place to ask general information questions.  For bug reports, please
+see the "Support and bug fixes" section below.
+
+6. Tcl'ers Wiki
+---------------
+
+A Wiki-based open community site covering all aspects of Tcl/Tk is at:
+
+	http://wiki.tcl.tk/
+
+It is dedicated to the Tcl programming language and its extensions.  A
+wealth of useful information can be found there.  It contains code
+snippets, references to papers, books, and FAQs, as well as pointers to
+development tools, extensions, and applications.  You can also recommend
+additional URLs by editing the wiki yourself.
+
+7. Mailing lists
+----------------
+
+Several mailing lists are hosted at SourceForge to discuss development or
+use issues (like Macintosh and Windows topics).  For more information and
+to subscribe, visit:
+
+	http://sourceforge.net/projects/tcl/
+
+and go to the Mailing Lists page.
+
+8. Support and Training
+------------------------
+
+We are very interested in receiving bug reports, patches, and suggestions
+for improvements.  We prefer that you send this information to us as
+tickets entered into our tracker at:
+
+	http://core.tcl.tk/tcl/reportlist
+
+We will log and follow-up on each bug, although we cannot promise a
+specific turn-around time.  Enhancements may take longer and may not happen
+at all unless there is widespread support for them (we're trying to
+slow the rate at which Tcl/Tk turns into a kitchen sink).  It's very
+difficult to make incompatible changes to Tcl/Tk at this point, due to
+the size of the installed base.
+
+The Tcl community is too large for us to provide much individual support
+for users.  If you need help we suggest that you post questions to
+comp.lang.tcl.  We read the newsgroup and will attempt to answer esoteric
+questions for which no one else is likely to know the answer.  In addition,
+see the following Web site for links to other organizations that offer
+Tcl/Tk training:
+
+	http://wiki.tcl.tk/training
+
+9. Tracking Development
+-----------------------
+
+Tcl is developed in public.  To keep an eye on how Tcl is changing, see
+	http://core.tcl.tk/
+
+10. Thank You
+-------------
+
+We'd like to express our thanks to the Tcl community for all the
+helpful suggestions, bug reports, and patches we have received.
+Tcl/Tk has improved vastly and will continue to do so with your help.
diff --git a/changes b/changes
new file mode 100644
index 0000000..034380b
--- /dev/null
+++ b/changes
@@ -0,0 +1,8700 @@
+Recent user-visible changes to Tcl:
+
+1. No more [command1] [command2] construct for grouping multiple
+commands on a single command line.
+
+2. Semi-colon now available for grouping commands on a line.
+
+3. For a command to span multiple lines, must now use backslash-return
+at the end of each line but the last.
+
+4. "Var" command has been changed to "set".
+
+5. Double-quotes now available as an argument grouping character.
+
+6. "Return" may be used at top-level.
+
+7. More backslash sequences available now.  In particular, backslash-newline
+may be used to join lines in command files.
+
+8. New or modified built-in commands:  case, return, for, glob, info,
+print, return, set, source, string, uplevel.
+
+9. After an error, the variable "errorInfo" is filled with a stack
+trace showing what was being executed when the error occurred.
+
+10. Command abbreviations are accepted when parsing commands, but
+are not recommended except for purely-interactive commands.
+
+11. $, set, and expr all complain now if a non-existent variable is
+referenced.
+
+12. History facilities exist now.  See Tcl.man and Tcl_RecordAndEval.man.
+
+13. Changed to distinguish between empty variables and those that don't
+exist at all.  Interfaces to Tcl_GetVar and Tcl_ParseVar have changed
+(NULL return value is now possible).  *** POTENTIAL INCOMPATIBILITY ***
+
+14. Changed meaning of "level" argument to "uplevel" command (1 now means
+"go up one level", not "go to level 1"; "#1" means "go to level 1").
+*** POTENTIAL INCOMPATIBILITY ***
+
+15. 3/19/90 Added "info exists" option to see if variable exists.
+
+16. 3/19/90 Added "noAbbrev" variable to prohibit command abbreviations.
+
+17. 3/19/90 Added extra errorInfo option to "error" command.
+
+18. 3/21/90 Double-quotes now only affect space:  command, variable,
+and backslash substitutions still occur inside double-quotes.
+*** POTENTIAL INCOMPATIBILITY ***
+
+19. 3/21/90 Added support for \r.
+
+20. 3/21/90 List, concat, eval, and glob commands all expect at least
+one argument now.  *** POTENTIAL INCOMPATIBILITY ***
+
+21. 3/22/90 Added "?:" operators to expressions.
+
+22. 3/25/90 Fixed bug in Tcl_Result that caused memory to get trashed.
+
+------------------- Released version 3.1 ---------------------
+
+23. 3/29/90 Fixed bug that caused "file a.b/c ext" to return ".b/c".
+
+24. 3/29/90 Semi-colon is not treated specially when enclosed in
+double-quotes.
+
+------------------- Released version 3.2 ---------------------
+
+25. 4/16/90 Rewrote "exec" not to use select or signals anymore.
+Should be more Sys-V compatible, and no slower in the normal case.
+
+26. 4/18/90 Rewrote "glob" to eliminate GNU code (there's no GNU code
+left in Tcl, now), and added Tcl_TildeSubst procedure.  Added automatic
+tilde-substitution in many commands, including "glob".
+
+------------------- Released version 3.3 ---------------------
+
+27. 7/11/90 Added "Tcl_AppendResult" procedure.
+
+28. 7/20/90 "History" with no options now defaults to "history info"
+rather than to "history redo".  Although this is a backward incompatibility,
+it should only be used interactively and thus shouldn't present any
+compatibility problems with scripts.
+
+29. 7/20/90 Added "Tcl_GetInteger", "Tcl_GetDouble", and "Tcl_GetBoolean"
+procedures.
+
+30. 7/22/90 Removed "Tcl_WatchInterp" procedure:  doesn't seem to be
+necessary, since the same effect can be achieved with the deletion
+callbacks on individual commands.  *** POTENTIAL INCOMPATIBILITY ***
+
+31. 7/23/90 Added variable tracing:  Tcl_TraceVar, Tcl_UnTraceVar,
+and Tcl_VarTraceInfo procedures, "trace" command.
+
+32. 8/9/90 Mailed out list of all bug fixes since 3.3 release.
+
+33. 8/29/90 Fixed bugs in Tcl_Merge relating to backslashes and
+semi-colons.  Mailed out patch.
+
+34. 9/3/90 Fixed bug in tclBasic.c: quotes weren't quoting ]'s.
+Mailed out patch.
+
+35. 9/19/90 Rewrote exec to always use files both for input and
+output to the process.  The old pipe-based version didn't work if
+the exec'ed process forked a child and then exited:  Tcl waited
+around for stdout to get closed, which didn't happen until the
+grandchild exited.
+
+36. 11/5/90 ERR_IN_PROGRESS flag wasn't being cleared soon enough
+in Tcl_Eval, allowing error messages from different commands to
+pile up in $errorInfo.  Fixed by re-arranging code in Tcl_Eval that
+re-initializes result and ERR_IN_PROGRESS flag.  Didn't mail out
+patch:  changes too complicated to describe.
+
+37. 12/19/90 Added Tcl_VarEval procedure as a convenience for
+assembling and executing Tcl commands.
+
+38. 1/29/91 Fixed core leak in Tcl_AddErrorInfo.  Also changed procedure
+and Tcl_Eval so that first call to Tcl_AddErrorInfo need not come from
+Tcl_Eval.
+
+----------------- Released version 5.0 with Tk ------------------
+
+39. 4/3/91 Removed change bars from manual entries, leaving only those
+that came after version 3.3 was released.
+
+40. 5/17/91 Changed tests to conform to Mary Ann May-Pumphrey's approach.
+
+41. 5/23/91 Massive revision to Tcl parser to simplify the implementation
+of string and floating-point support in expressions.  Newlines inside
+[] are now treated as command separators rather than word separators
+(this makes newline treatment consistent throughout Tcl).
+*** POTENTIAL INCOMPATIBILITY ***
+
+42. 5/23/91 Massive rewrite of expression code to support floating-point
+values and simple string comparisons.  The C interfaces to expression
+routines have changed (Tcl_Expr is replaced by Tcl_ExprLong, Tcl_ExprDouble,
+etc.), but all old Tcl expression strings should be accepted by the new
+expression code.
+*** POTENTIAL INCOMPATIBILITY ***
+
+43. 5/23/91 Modified tclHistory.c to check for negative "keep" value.
+
+44. 5/23/91 Modified Tcl_Backslash to handle backslash-newline.  It now
+returns 0 to indicate that a backslash sequence should be replaced by
+no character at all.
+*** POTENTIAL INCOMPATIBILITY ***
+
+45. 5/29/91 Modified to use ANSI C function prototypes.  Must set
+"USE_ANSI" switch when compiling to get prototypes.
+
+46. 5/29/91 Completed test suite by providing tests for all of the
+built-in Tcl commands.
+
+47. 5/29/91 Changed Tcl_Concat to eliminate leading and trailing
+white-space in each of the things it concatenates and to ignore
+elements that are empty or have only white space in them.  This
+produces cleaner output from the "concat" command.
+*** POTENTIAL INCOMPATIBILITY ***
+
+48. 5/31/91 Changed "set" command and Tcl_SetVar procedure to return
+new value of variable.
+
+49. 6/1/91 Added "while" and "cd" commands.
+
+50. 6/1/91 Changed "exec" to delete the last character of program
+output if it is a newline.  In most cases this makes it easier to
+process program-generated output.
+*** POTENTIAL INCOMPATIBILITY ***
+
+51. 6/1/91 Made sure that pointers are never used after freeing them.
+
+52. 6/1/91 Fixed bug in TclWordEnd where it wasn't dealing with
+[] inside quotes correctly.
+
+53. 6/8/91 Fixed exec.test to accept return values of either 1 or
+255 from "false" command.
+
+54. 7/6/91 Massive overhaul of variable management.  Associative
+arrays now available, along with "unset" command (and Tcl_UnsetVar
+procedure).  Variable traces have been completely reworked:
+interfaces different both from Tcl and C, and multiple traces may
+exist on same variable.  Can no longer redefine existing local
+variable to be global.  Calling sequences have changed slightly
+for Tcl_GetVar and Tcl_SetVar ("global" is now "flags"). Tcl_SetVar
+can fail and return a NULL result.  New forms of variable-manipulation
+procedures:  Tcl_GetVar2, Tcl_SetVar2, etc.  Syntax of variable
+$-notation changed to support array indexing.
+*** POTENTIAL INCOMPATIBILITY ***
+
+55. 7/6/91 Added new list-manipulation procedures:  Tcl_ScanElement,
+Tcl_ConvertElement, Tcl_AppendElement.
+
+56. 7/12/91 Created new procedure Tcl_EvalFile, which does most of the
+work of the "source" command.
+
+57. 7/20/91 Major reworking of "exec" command to allow pipelines,
+more redirection, background.  Added new procedures Tcl_Fork,
+Tcl_WaitPids, Tcl_DetachPids, and Tcl_CreatePipeline.  The old
+"< input" notation has been replaced by "<< input" ("<" is for
+redirection from a file).  Also handles error returns and abnormal
+terminations (e.g. signals) differently.
+*** POTENTIAL INCOMPATIBILITY ***
+
+58. 7/21/91 Added "append" and "lappend" commands.
+
+59. 7/22/91 Reworked error messages and manual entries to use
+?x? as the notation for an optional argument x, instead of [x].  The
+bracket notation was often confused with the use of brackets for
+command substitution.  Also modified error messages to be more
+consistent.
+
+60. 7/23/91 Tcl_DeleteCommand now returns an indication of whether
+or not the command actually existed, and the "rename" command uses
+this information to return an error if an attempt is made to delete
+a non-existent command.
+*** POTENTIAL INCOMPATIBILITY ***
+
+61. 7/25/91 Added new "errorCode" mechanism, along with procedures
+Tcl_SetErrorCode, Tcl_UnixError, and Tcl_ResetResult.  Renamed
+Tcl_Return to Tcl_SetResult, but left a #define for Tcl_Return to
+avoid compatibility problems.
+
+62. 7/26/91 Extended "case" command with alternate syntax where all
+patterns and commands are together in a single list argument:  makes
+it easier to write multi-line case statements.
+
+63. 7/27/91 Changed "print" command to perform tilde-substitution on
+the file name.
+
+64. 7/27/91 Added "tolower", "toupper", "trim", "trimleft", and "trimright"
+options to "string" command.
+
+65. 7/29/91 Added "atime", "mtime", "size", and "stat" options to "file"
+command.
+
+66. 8/1/91 Added "split" and "join" commands.
+
+67. 8/11/91 Added commands for file I/O, including "open", "close",
+"read", "gets", "puts", "flush", "eof", "seek", and "tell".
+
+68. 8/14/91 Switched to use a hash table for command lookups.  Command
+abbreviations no longer have direct support in the Tcl interpreter, but
+it should be possible to simulate them with the auto-load features
+described below.  The "noAbbrev" variable is no longer used by Tcl.
+*** POTENTIAL INCOMPATIBILITY ***
+
+68.5 8/15/91 Added support for "unknown" command, which can be used to
+complete abbreviations, auto-load library files, auto-exec shell
+commands, etc.
+
+69. 8/15/91 Added -nocomplain switch to "glob" command.
+
+70. 8/20/91 Added "info library" option and TCL_LIBRARY #define.  Also
+added "info script" option.
+
+71. 8/20/91 Changed "file" command to take "option" argument as first
+argument (before file name), for consistency with other Tcl commands.
+*** POTENTIAL INCOMPATIBILITY ***
+
+72. 8/20/91 Changed format of information in $errorInfo variable:
+comments such as
+    ("while" body line 1)
+are now on separate lines from commands being executed.
+*** POTENTIAL INCOMPATIBILITY ***
+
+73. 8/20/91 Changed Tcl_AppendResult so that it (eventually) frees
+large buffers that it allocates.
+
+74. 8/21/91 Added "linsert", "lreplace", "lsearch", and "lsort"
+commands.
+
+75. 8/28/91 Added "incr" and "exit" commands.
+
+76. 8/30/91 Added "regexp" and "regsub" commands.
+
+77. 9/4/91 Changed "dynamic" field in interpreters to "freeProc" (procedure
+address).  This allows for alternative storage managers.
+*** POTENTIAL INCOMPATIBILITY ***
+
+78. 9/6/91 Added "index", "length", and "range" options to "string"
+command.  Added "lindex", "llength", and "lrange" commands.
+
+79. 9/8/91 Removed "index", "length", "print" and "range" commands.
+"Print" is redundant with "puts", but less general, and the other
+commands are replaced with the new commands described in change 78
+above.
+*** POTENTIAL INCOMPATIBILITY ***
+
+80. 9/8/91 Changed history revision to occur even when history command
+is nested;  needed in order to allow "history" to be invoked from
+"unknown" procedure.
+
+81. 9/13/91 Changed "panic" not to use vfprintf (it's uglier and less
+general now, but makes it easier to run Tcl on systems that don't
+have vfprintf).  Also changed "strerror" not to redeclare sys_errlist.
+
+82. 9/19/91 Lots of changes to improve portability to different UNIX
+systems, including addition of "config" script to adapt Tcl to the
+configuration of the system it's being compiled on.
+
+83. 9/22/91 Added "pwd" command.
+
+84. 9/22/91 Renamed manual pages so that their filenames are no more
+than 14 characters in length, moved to "doc" subdirectory.
+
+85. 9/24/91 Redid manual entries so they contain the supplemental
+macros that they need;  can just print with "troff -man" or "man"
+now.
+
+86. 9/26/91 Created initial version of script library, including
+a version of "unknown" that does auto-loading, auto-execution, and
+abbreviation expansion.  This library is used by tclTest
+automatically.  See the "library" manual entry for details.
+
+----------------- Released version 6.0, 9/26/91 ------------------
+
+87. 9/30/91 Made "string tolower" and "string toupper" check case
+before converting:  on some systems, "tolower" and "toupper" assume
+that character already has particular case.
+
+88. 9/30/91 Fixed bug in Tcl_SetResult:  wasn't always setting freeProc
+correctly when called with NULL value.  This tended to cause memory
+allocation errors later.
+
+89. 10/3/91 Added "upvar" command.
+
+90. 10/4/91 Changed "format" so that internally it converts %D to %ld,
+%U to %lu, %O to %lo, and %F to %f.  This eliminates some compatibility
+problems on some machines without affecting behavior.
+
+91. 10/10/91 Fixed bug in "regsub" that caused core dumps with the -all
+option when the last match wasn't at the end of the string.
+
+92. 10/17/91 Fixed problems with backslash sequences:  \r support was
+incomplete and \f and \v weren't supported at all.
+
+93. 10/24/91 Added Tcl_InitHistory procedure.
+
+94. 10/24/91 Changed "regexp" to store "-1 -1" in subMatchVars that
+don't match, rather than returning an error.
+
+95. 10/27/91 Modified "regexp" to return actual strings in matchVar
+and subMatchVars instead of indices.  Added "-indices" switch to cause
+indices to be returned.
+*** POTENTIAL INCOMPATIBILITY ***
+
+96. 10/27/91 Fixed bug in "scan" where it used hardwired constants for
+sizes of floats and doubles instead of using "sizeof".
+
+97. 10/31/91 Fixed bug in tclParse.c where parse-related error messages
+weren't being storage-managed correctly, causing spurious free's.
+
+98. 10/31/91 Form feed and vertical tab characters are now considered
+to be space characters by the parser.
+
+99. 10/31/91 Added TCL_LEAVE_ERR_MSG flag to procedures like Tcl_SetVar.
+
+100. 11/7/91 Fixed bug in "case" where "in" argument couldn't be omitted
+if all case branches were embedded in a single list.
+
+101. 11/7/91 Switched to use "pid_t" and "uid_t" and other official
+POSIC types and function prototypes.
+
+----------------- Released version 6.1, 11/7/91 ------------------
+
+102. 12/2/91 Modified Tcl_ScanElement and Tcl_ConvertElement in several
+ways.  First, allowed caller to request that only backslashes be used
+(no braces).  Second, made Tcl_ConvertElement more aggressive in using
+backslashes for braces and quotes.
+
+103. 12/5/91 Added "type", "lstat", and "readlink" options to "file"
+command, plus added new "type" element to output of "stat" and "lstat"
+options.
+
+104. 12/10/91 Manual entries had first lines that caused "man" program
+to try weird preprocessor.  Added blank comment lines to fix problem.
+
+105. 12/16/91 Fixed a few bugs in auto_mkindex proc:  wasn't handling
+errors properly, and hadn't been upgraded for new "regexp" syntax.
+
+106. 1/2/92 Fixed bug in "file" command where it didn't properly handle
+a file names containing tildes where the indicated user doesn't exist.
+
+107. 1/2/92 Fixed lots of cases in tclUnixStr.c where two different
+errno symbols (e.g. EWOULDBLOCK and EAGAIN) have the same number;  Tcl
+will only use one of them.
+
+108. 1/2/92 Lots of changes to configuration script to handle many more
+systems more gracefully.  E.g. should now detect the bogus strtoul that
+comes with AIX and substitute Tcl's own version instead.
+
+----------------- Released version 6.2, 1/10/92 ------------------
+
+109. 1/20/92 Config didn't have code to actually use "uid_t" variable
+to set TCL_UIT_T #define.
+
+110. 2/10/92 Tcl_Eval didn't properly reset "numLevels" variable when
+too-deep recursion occurred.
+
+111. 2/29/92 Added "on" and "off" to keywords accepted by Tcl_GetBoolean.
+
+112. 3/19/92 Config wasn't installing default version of strtod.c for
+systems that don't have one in libc.a.
+
+113. 3/23/92 Fixed bug in tclExpr.c where numbers with leading "."s,
+like 0.75, couldn't be properly substituted into expressions with
+variable or command substitution.
+
+114. 3/25/92 Fixed bug in tclUnixAZ.c where "gets" command wasn't
+checking to make sure that it was able to write the variable OK.
+
+115. 4/16/92 Fixed bug in tclUnixAZ.c where "read" command didn't
+compute file size right for device files.
+
+116. 4/23/92 Fixed but in tclCmdMZ.c where "trace vinfo" was overwriting
+the trace command.
+
+----------------- Released version 6.3, 5/1/92 ------------------
+
+117. 5/1/92 Added Tcl_GlobalEval.
+
+118. 6/1/92 Changed auto-load facility to source files at global level.
+
+119. 6/8/92 Tcl_ParseVar wasn't always setting termPtr after errors, which
+sometimes caused core dumps.
+
+120. 6/21/92 Fixed bug in initialization of regexp pattern cache.  This
+bug caused segmentation violations in regexp commands under some conditions.
+
+121. 6/22/92 Changed implementation of "glob" command to eliminate
+trailing slashes on directory names:  they confuse some systems.  There
+shouldn't be any user-visible changes in functionality except for names
+in error messages not having trailing slashes.
+
+122. 7/2/92 Fixed bug that caused 'string match ** ""' to return 0.
+
+123. 7/2/92 Fixed bug in Tcl_CreateCmdBuf where it wasn't initializing
+the buffer to an empty string.
+
+124. 7/6/92 Fixed bug in "case" command where it used NULL pattern string
+after errors in the "default" clause.
+
+125. 7/25/92 Speeded up auto_load procedure:  don't reread all the index
+files unless the path has changed.
+
+126. 8/3/92 Changed tclUnix.h to define MAXPATHLEN from PATH_MAX, not
+_POSIX_PATH_MAX.
+
+----------------- Released version 6.4, 8/7/92 ------------------
+
+127. 8/10/92 Changed tclBasic.c so that comment lines can be continued by
+putting a backslash before the newline.
+
+128. 8/21/92 Modified "unknown" to allow the source-ing of a file for
+an auto-load to trigger other nested auto-loads, as long as there isn't
+any recursion on the same command name.
+
+129. 8/25/92 Modified "format" command to allow " " and "+" flags, and
+allow flags in any order.
+
+130. 9/14/92 Modified Tcl_ParseVar so that it doesn't actually attempt
+to look up the variable if "noEval" mode is in effect in the interpreter
+(it just parses the name).  This avoids the errors that used to occur
+in statements like "expr {[info exists foo] && $foo}".
+
+131. 9/14/92 Fixed bug in "uplevel" command where it didn't output the
+correct error message if a level was specified but no command.
+
+132. 9/14/92 Renamed manual entries to have extensions like .3 and .n,
+and added "install" target to Makefile.
+
+133. 9/18/92 Modified "unknown" command to emulate !!, !<num>, and
+^<old>^<new> csh history substitutions.
+
+134. 9/21/92 Made the config script cleverer about figuring out which
+switches to pass to "nm".
+
+135. 9/23/92 Fixed tclVar.c to be sure to copy flags when growing variables.
+Used to forget about traces in progress and make extra recursive calls
+on trace procs.
+
+136. 9/28/92 Fixed bug in auto_reset where it was unsetting variables
+that might not exist.
+
+137. 10/7/92 Changed "parray" library procedure to print any array
+accessible to caller, local or global.
+
+138. 10/15/92 Fixed bug where propagation of new environment variable
+values among interpreters took N! time if there exist N interpreters.
+
+139. 10/16/92 Changed auto_reset procedure so that it also deletes any
+existing procedures that are in the auto_load index (the assumption is
+that they should be re-loaded to get the latest versions).
+
+140. 10/21/92 Fixed bug that caused lists to be incorrectly generated
+for elements that contained backslash-newline sequences.
+
+141. 12/9/92 Added support for TCL_LIBRARY environment variable:  use
+it as library location if it's present.
+
+142. 12/9/92 Added "info complete" command, Tcl_CommandComplete procedure.
+
+143. 12/16/92 Changed the Makefile to check to make sure "config" has been
+run (can't run config directly from the Makefile because it modifies the
+Makefile;  thus make has to be run again after running config).
+
+----------------- Released version 6.5, 12/17/92 ------------------
+
+144. 12/21/92 Changed config to look in several places for libc file.
+
+145. 12/23/92 Added "elseif" support to if.  Also, "then", "else", and
+"elseif" may no longer be abbreviated.
+*** POTENTIAL INCOMPATIBILITY ***
+
+146. 12/28/92 Changed "puts" and "read" to support initial "-nonewline"
+switch instead of additional "nonewline" argument.  The old form is
+still supported, but it is discouraged and is no longer documented.
+Also changed "puts" to make the file argument default to stdout: e.g.
+"puts foo" will print foo on standard output.
+
+147. 1/6/93 Fixed bug whereby backslash-newline wasn't working when
+typed interactively, or in "info complete".
+
+148. 1/22/93 Fixed bugs in "lreplace" and "linsert" where close
+quotes were being lost from last element before replacement or
+insertion.
+
+149. 1/29/93 Fixed bug in Tcl_AssembleCmd where it wasn't requiring
+a newline at the end of a line before considering a command to be
+complete.  The bug caused some very long lines in script files to
+be processed as multiple separate commands.
+
+150. 1/29/93 Various changes in Makefile to add more configuration
+options, simplify installation, fix bugs (e.g. don't use -f switch
+for cp), etc.
+
+151. 1/29/93 Changed "name1" and "name2" identifiers to "part1" and
+"part2" to avoid name conflicts with stupid C++ implementations that
+use "name1" and "name2" in a reserved way.
+
+152. 2/1/93 Added "putenv" procedure to replace the standard system
+version so that it will work correctly with Tcl's environment handling.
+
+----------------- Released version 6.6, 2/5/93 ------------------
+
+153. 2/10/93 Fixed bugs in config script:  missing "endif" in libc loop,
+and tried to use strncasecmp.c instead of strcasecmp.c.
+
+154. 2/10/93 Makefile improvements:  added RANLIB variable for easier
+Sys-V configuration, added SHELL variable for SGI systems.
+
+----------------- Released version 6.7, 2/11/93 ------------------
+
+153. 2/6/93 Changes in backslash processing:
+    - \Cx, \Mx, \CMx, \e sequences no longer special
+    - \<newline> also eats up any space after the newline, replacing
+      the whole sequence with a single space character
+    - Hex sequences like \x24 are now supported, along with ANSI C's \a.
+    - "format" no longer does backslash processing on its format string
+    - there is no longer any special meaning to a 0 return value from
+      Tcl_Backslash
+    - unknown backslash sequences, like (e.g. \*), are replaced with
+      the following character (e.g. *), instead of just treating the
+      backslash as an ordinary character.
+*** POTENTIAL INCOMPATIBILITY ***
+
+154. 2/6/93 Updated all copyright notices.  The meaning hasn't changed
+at all but the wording does a better job of protecting U.C. from
+liability (according to U.C. lawyers, anyway).
+
+155. 2/6/93 Changed "regsub" so that it overwrites the result variable
+in all cases, even if there is no match.
+*** POTENTIAL INCOMPATIBILITY ***
+
+156. 2/8/93 Added support for XPG3 %n$ conversion specifiers to "format"
+command.
+
+157. 2/17/93 Fixed bug in Tcl_Eval where errors due to infinite
+recursion could result in core dumps.
+
+158. 2/17/93 Improved the auto-load mechanism to deal gracefully (i.e.
+return an error) with a situation where a library file that supposedly
+defines a procedure doesn't actually define it.
+
+159. 2/17/93 Renamed Tcl_UnixError procedure to Tcl_PosixError, and
+changed errorCode variable usage to use POSIX as keyword instead of
+UNIX.
+*** POTENTIAL INCOMPATIBILITY ***
+
+160. 2/19/93 Changes to exec and process control:
+    - Added support for >>, >&, >>&, |&, <@, >@, and >&@ forms of redirection.
+    - When exec puts processes into background, it returns a list of
+      their pids as result.
+    - Added support for <file, >file, etc. (i.e. no space between
+      ">" and file name.
+    - Added -keepnewline option.
+    - Deleted Tcl_Fork and Tcl_WaitPids procedures (just use fork and
+      waitpid instead).
+    - Added waitpid compatibility procedure for systems that don't have
+      it.
+    - Added Tcl_ReapDetachedProcs procedure.
+    - Changed "exec" to return an error if there is stderr output, even
+      if the command returns a 0 exit status (it's always been documented
+      this way, but the implementation wasn't correct).
+    - If a process returns a non-zero exit status but doesn't generate
+      any diagnostic output, then Tcl generates an error message for it.
+*** POTENTIAL INCOMPATIBILITY ***
+
+161. 2/25/93 Fixed two memory-management problems having to do with
+managing the old result during variable trace callbacks.
+
+162. 3/1/93 Added dynamic string library:  Tcl_DStringInit, Tcl_DStringAppend,
+Tcl_DStringFree, Tcl_DStringResult, etc.
+
+163. 3/1/93 Modified glob command to only return the names of files that
+exist, and to only return names ending in "/" if the file is a directory.
+*** POTENTIAL INCOMPATIBILITY ***
+
+164. 3/19/93 Modified not to use system calls like "read" directly,
+but instead to use special Tcl procedures that retry automatically
+if interrupted by signals.
+
+165. 4/3/93 Eliminated "noSep" argument to Tcl_AppendElement, plus
+TCL_NO_SPACE flag for Tcl_SetVar and Tcl_SetVar2.
+*** POTENTIAL INCOMPATIBILITY ***
+
+166. 4/3/93 Eliminated "flags" and "termPtr" arguments to Tcl_Eval.
+*** POTENTIAL INCOMPATIBILITY ***
+
+167. 4/3/93 Changes to expressions:
+    - The "expr" command now accepts multiple arguments, which are
+      concatenated together with space separators.
+    - Integers aren't automatically promoted to floating-point if they
+      overflow the word size:  errors are generated instead.
+    - Tcl can now handle "NaN" and other special values if the underlying
+      library procedures handle them.
+    - When printing floating-point numbers, Tcl ensures that there is a "."
+      or "e" in the number, so it can't be treated as an integer accidentally.
+      The procedure Tcl_PrintDouble is available to provide this function
+      in other contexts.  Also, the variable "tcl_precision" can be used
+      to set the precision for printing (must be a decimal number giving
+      digits of precision).
+    - Expressions now support transcendental and other functions, e.g. sin,
+      acos, hypot, ceil, and round.  Can add new math functions with
+      Tcl_CreateMathFunc().
+    - Boolean expressions can now have any of the string values accepted
+      by Tcl_GetBoolean, such as "yes" or "no".
+*** POTENTIAL INCOMPATIBILITY ***
+
+168. 4/5/93 Changed Tcl_UnsetVar and Tcl_UnsetVar2 to return TCL_OK
+or TCL_ERROR instead of 0 or -1.
+*** POTENTIAL INCOMPATIBILITY ***
+
+169. 4/5/93 Eliminated Tcl_CmdBuf structure and associated procedures;
+can use Tcl_DStrings instead.
+*** POTENTIAL INCOMPATIBILITY ***
+
+170. 4/8/93 Changed interface to Tcl_TildeSubst to use a dynamic
+string for buffer space.  This makes the procedure re-entrant and
+thread-safe, whereas it wasn't before.
+*** POTENTIAL INCOMPATIBILITY ***
+
+171. 4/14/93 Eliminated tclHash.h, and moved everything from it to
+tcl.h
+*** POTENTIAL INCOMPATIBILITY ***
+
+172. 4/15/93 Eliminated Tcl_InitHistory, made "history" command always
+be part of interpreter.
+*** POTENTIAL INCOMPATIBILITY ***
+
+173. 4/16/93 Modified "file" command so that "readable" option always
+exists, even on machines that don't support symbolic links (always returns
+same error as if the file wasn't a symbolic link).
+
+174. 4/26/93 Fixed bugs in "regsub" where ^ patterns didn't get handled
+right (pretended not to match when it really did, and looped infinitely
+if -all was specified).
+
+175. 4/29/93 Various improvements in the handling of variables:
+    - Can create variables and array elements during a read trace.
+    - Can delete variables during traces (note: unset traces will be
+      invoked when this happens).
+    - Can upvar to array elements.
+    - Can retarget an upvar to another variable by re-issuing the
+      upvar command with a different "other" variable.
+
+176. 5/3/93 Added Tcl_GetCommandInfo, which returns info about a Tcl
+command such as whether it exists and its ClientData.  Also added
+Tcl_SetCommandInfo, which allows any of this information to be modified
+and also allows a command's delete procedure to have a different
+ClientData value than its command procedure.
+
+177. 5/5/93 Added Tcl_RegExpMatch procedure.
+
+178. 5/6/93 Fixed bug in "scan" where it didn't properly handle
+%% conversion specifiers.  Also changed "scan" to use Tcl_PrintDouble
+for printing real values.
+
+179. 5/7/93 Added "-exact", "-glob", and "-regexp" options to "lsearch"
+command to allow different kinds of pattern matching.
+
+180. 5/7/93 Added many new switches to "lsort" to control the sorting
+process: "-ascii", "-integer", "-real", "-command", "-increasing",
+and "-decreasing".
+
+181. 5/10/93 Changes to file I/O:
+    - Modified "open" command to support a list of POSIX access flags
+      like {WRONLY CREAT TRUNC} in addition to current fopen-style
+      access modes.  Also added "permissions" argument to set permissions
+      of newly-created files.
+    - Fixed Scott Bolte's bug (can close stdin etc. in application and
+      then re-open them with Tcl commands).
+    - Exported access to Tcl's file table with new procedures Tcl_EnterFile
+      and Tcl_GetOpenFile.
+
+182. 5/15/93 Added new "pid" command, which can be used to retrieve
+either the current process id or a list of the process ids in a
+pipeline opened with "open |..."
+
+183. 6/3/93 Changed to use GNU autoconfig for configuration instead of
+the home-brew "config" script.  Also made many other configuration-related
+changes, such as using <unistd.h> instead of explicitly declaring system
+calls in tclUnix.h.
+
+184. 6/4/93 Fixed bug where core-dumps could occur if a procedure
+redefined itself (the memory for the procedure's body could get
+reallocated in the middle of evaluating the body);  implemented
+simple reference count mechanism.
+
+185. 6/5/93 Changed tclIndex file format in two ways:  (a) it's now
+eval-ed instead of parsed, which makes it 3-4x faster; (b) the entries
+in auto_index are now commands to evaluate, which allows commands to
+be loaded in different ways such as dynamic-loading of C code.  The
+old tclIndex file format is still supported.
+
+186. 6/7/93 Eliminated tclTest program, added new "tclsh" program
+that is more like wish (allows script files to be invoked automatically
+using "#!/usr/local/bin/tclsh", makes arguments available to script,
+etc.).  Added support for Tcl_AppInit plus default version;  this
+allows new Tcl applications to be created without modifying the
+main program for tclsh.
+
+187. 6/7/93 Fixed bug in TclWordEnd that kept backslash-newline from
+working correctly in some cases during interactive input.
+
+188. 6/9/93 Added Tcl_LinkVar and related procedures, which automatically
+keep a Tcl variable in sync with a C variable.
+
+189. 6/16/93 Increased maximum nesting depth from 100 to 1000.
+
+190. 6/16/93 Modified "trace var" command so that error messages from
+within traces are returned properly as the result of the variable
+access, instead of the generic "access disallowed by trace command"
+message.
+
+191. 6/16/93 Added Tcl_CallWhenDeleted to provide callbacks when an
+interpreter is deleted (same functionality as Tcl_WatchInterp, which
+used to exist in versions before 6.0).
+
+193. 6/16/93 Added "-code" argument to "return" command;  it's there
+primarily for completeness, so that procedures implementing control
+constructs can reflect exceptional conditions back to their callers.
+
+194. 6/16/93 Split up Tcl.n to make separate manual entries for each
+Tcl command.  Tcl.n now contains a summary of the language syntax.
+
+195. 6/17/93 Added new "switch" command to replace "case": allows
+alternate forms of pattern matching (exact, glob, regexp), replaces
+pattern lists with single patterns (but you can use "-" bodies to
+share one body among several patterns), eliminates "in" noise word.
+"Case" command is now obsolete.
+
+196. 6/17/93 Changed the "exec", "glob", "regexp", and "regsub" commands
+to include a "--" switch.  All initial arguments starting with "-" are now
+treated as switches unless a "--" switch is present to end the list.
+*** POTENTIAL INCOMPATIBILITY ***
+
+197. 6/17/93 Changed auto-exec so that the subprocess gets stdin, stdout,
+and stderr from the parent.  This allows truly interactive sub-processes
+(e.g. vi) to be auto-exec'ed from a tcl shell command line.
+
+198. 6/18/93 Added patchlevel.h, for use in coordinating future patch
+releases, and also added "info patchlevel" command to make the patch
+level available to Tcl scripts.
+
+199. 6/19/93 Modified "glob" command so that a leading "//" in a name
+gets left as is (this is needed for systems like Apollos where "//" is
+the super-root;  Tcl used to collapse the two slashes into a single
+slash).
+
+200. 7/7/93 Added Tcl_SetRecursionLimit procedure so that the maximum
+allowable nesting depth can be controlled for an interpreter from C.
+
+----------------- Released version 7.0 Beta 1, 7/9/93 ------------------
+
+201. 7/12/93 Modified Tcl_GetInt and tclExpr.c so that full-precision
+unsigned integers can be specified without overflow errors.
+
+202. 7/12/93 Configuration changes:  eliminate leading blank line in
+configure script;  provide separate targets in Makefile for installing
+binary and non-binary information; check for size_t and a few other
+potentially missing typedefs; don't put tclAppInit.o into libtcl.a;
+better checks for matherr support.
+
+203. 7/14/93 Changed tclExpr.c to check the termination pointer before
+errno after strtod calls, to avoid problems with some versions of
+strtod that set errno in unexpected ways.
+
+204. 7/16/93 Changed "scan" command to be more ANSI-conformant:
+eliminated %F, %D, etc., added code to ignore "l", "h", and "L"
+modifiers but always convert %e, %f, and %g with implicit "l";
+also added support for %u and %i.  Also changed "format" command
+to eliminate %D, %U, %O, and add %i.
+*** POTENTIAL INCOMPATIBILITY ***
+
+205. 7/17/93 Changed "uplevel" and "upvar" so that they can be used
+from global level to global level:  this used to generate an error.
+
+206. 7/19/93 Renamed "setenv", "putenv", and "unsetenv" procedures
+to avoid conflicts with system procedures with the same names.  If
+you want Tcl's procedures to override the system procedures, do it
+in the Makefile (instructions are in the Makefile).
+*** POTENTIAL INCOMPATIBILITY ***
+
+----------------- Released version 7.0 Beta 2, 7/21/93 ------------------
+
+207. 7/21/93 Fixed bug in tclVar.c where freed memory was accidentally
+used if a procedure returned an element of a local array.
+
+208. 7/22/93 Fixed bug in "unknown" where it didn't properly handle
+errors occurring in the "auto_load" procedure, leaving its state
+inconsistent.
+
+209. 7/23/93 Changed exec's ">2" redirection operator to "2>" for
+consistency with sh.  This is incompatible with earlier beta releases
+of 7.0 but not with pre-7.0 releases, which didn't support either
+operator.
+
+210. 7/28/93 Changed backslash-newline handling so that the resulting
+space character *is* treated as a word separator unless the backslash
+sequence is in quotes or braces.  This is incompatible with 7.0b1
+and 7.0b2 but is more compatible with pre-7.0 versions that the b1
+and b2 releases were.
+
+211. 7/28/93 Eliminated Tcl_LinkedVarWritable, added TCL_LINK_READ_ONLY to
+Tcl_LinkVar to accomplish same purpose.  This change is incompatible
+with earlier beta releases, but not with releases before Tcl 7.0.
+
+212. 7/29/93 Renamed regexp C functions so they won't clash with POSIX
+regexp functions that use the same name.
+
+213. 8/3/93 Added "-errorinfo" and "-errorcode" options to "return"
+command: these allow for much better handling of the errorInfo
+and errorCode variables in some cases.
+
+214. 8/12/93 Changed "expr" so that % always returns a remainder with
+the same sign as the divisor and absolute value smaller than the
+divisor.
+
+215. 8/14/93 Turned off auto-exec in "unknown" unless the command
+was typed interactively.  This means you must use "exec" when
+invoking subprocesses, unless it's a command that's typed interactively.
+*** POTENTIAL INCOMPATIBILITY ***
+
+216. 8/14/93 Added support for tcl_prompt1 and tcl_prompt2 variables
+to tclMain.c:  makes prompts user-settable.
+
+217. 8/14/93 Added asynchronous handlers (Tcl_AsyncCreate etc.) so
+that signals can be taken cleanly by Tcl applications.
+
+218. 8/16/93 Moved information about open files from the interpreter
+structure to global variables so that a file can be opened in one
+interpreter and read or written in another.
+
+219. 8/16/93 Removed ENV_FLAGS from Makefile, so that there's no
+official support for overriding setenv, unsetenv, and putenv.
+
+220. 8/20/93 Various configuration improvements:  coerce chars
+to unsigned chars before using macros like isspace;  source ~/.tclshrc
+file during initialization if it exists and program is running
+interactively;  allow there to be directories in auto_path that don't
+exist or don't have tclIndex files (ignore them); added Tcl_Init
+procedure and changed Tcl_AppInit to call it.
+
+221. 8/21/93 Fixed bug in expr where "+", "-", and " " were all
+getting treated as integers with value 0.
+
+222. 8/26/93 Added "tcl_interactive" variable to tclsh.
+
+223. 8/27/93 Added procedure Tcl_FilePermissions to return whether a
+given file can be read or written or both.  Modified Tcl_EnterFile
+to take a permissions mask rather than separate read and write arguments.
+
+224. 8/28/93 Fixed performance bug in "glob" command (unnecessary call
+to "access" for each file caused a 5-10x slow-down for big directories).
+
+----------------- Released version 7.0 Beta 3, 8/28/93 ------------------
+
+225. 9/9/93 Renamed regexp.h to tclRegexp.h to avoid conflicts with system
+include file by same name.
+
+226. 9/9/93 Added Tcl_DontCallWhenDeleted.
+
+227. 9/16/93 Changed not to call exit C procedure directly;  instead
+always invoke "exit" Tcl command so that application can redefine the
+command to do additional cleanup.
+
+228. 9/17/93 Changed auto-exec to handle names that contain slashes
+(i.e. don't use PATH for them).
+
+229. 9/23/93 Fixed bug in "read" and "gets" commands where they didn't
+clear EOF conditions.
+
+----------------- Released version 7.0, 9/29/93 ------------------
+
+230. 10/7/93 "Scan" command wasn't properly aligning things in memory,
+so segmentation faults could arise under some circumstances.
+
+231. 10/7/93 Fixed bug in Tcl_ConvertElement where it forgot to
+backslash leading curly brace when creating lists.
+
+232. 10/7/93 Eliminated dependency of tclMain.c on tclInt.h and
+tclUnix.h, so that people can copy the file out of the Tcl source
+directory to make modified private versions.
+
+233. 10/8/93 Fixed bug in auto-loader that reversed the priority order
+of entries in auto_path for new-style index files.  Now things are
+back to the way they were before 3.0:  first in auto_path is always
+highest priority.
+
+234. 10/13/93 Fixed bug where Tcl_CommandComplete didn't recognize
+comments and treat them as such.  Thus if you typed the line
+    # {
+interactively, Tcl would think that the command wasn't complete and
+wait for more input before evaluating the script.
+
+235. 10/14/93 Fixed bug where "regsub" didn't set the output variable
+if the input string was empty.
+
+236. 10/23/93 Fixed bug where Tcl_CreatePipeline didn't close off enough
+file descriptors in child processes, causing children not to exit
+properly in some cases.
+
+237. 10/28/93 Changed "list" and "concat" commands not to generate
+errors if given zero arguments, but instead to just return an empty
+string.
+
+----------------- Released version 7.1, 11/4/93 ------------------
+
+Note: there is no 7.2 release.  It was flawed and was thus withdrawn
+shortly after it was released.
+
+238. 11/10/93 TclMain.c didn't compile on some systems because of
+R_OK in call to "access".  Changed to eliminate call to "access".
+
+----------------- Released version 7.3, 11/26/93 ------------------
+
+239. 11/6/93 Modified "lindex", "linsert", "lrange", and "lreplace"
+so that "end" can be specified as an index.
+
+240. 11/6/93 Modified "append" and "lappend" to allow only two
+words total (i.e., nothing to append) without generating an error.
+
+241. 12/2/93 Changed to use EAGAIN as the errno for non-blocking
+I/O instead of EWOULDBLOCK:  this should fix problem where non-blocking
+I/O didn't work correctly on System-V systems.
+
+242. 12/22/93 Fixed bug in expressions where cancelled evaluation
+wasn't always working correctly (e.g. "set one 1; eval {1 || 1/$one}"
+failed with a divide by zero error).
+
+243. 1/6/94 Changed TCL_VOLATILE definition from -1 to the address of
+a dummy procedure Tcl_Volatile, since -1 causes portability problems on
+some machines (e.g., Crays).
+
+244. 2/4/94 Added support for unary plus.
+
+245. 2/17/94 Changed Tcl_RecordAndEval and "history" command to
+call Tcl_GlobalEval instead of Tcl_Eval.  Otherwise, invocation of
+these facilities in nested procedures can cause unwanted results.
+
+246. 2/17/94 Fixed bug in tclExpr.c where an expression such as
+"expr {"12398712938788234-1298379" != ""}" triggers an integer
+overflow error for the number in quotes, even though it isn't really
+a proper integer anyway.
+
+247. 2/19/94 Added new procedure Tcl_DStringGetResult to move result
+from interpreter to a dynamic string.
+
+248. 2/19/94 Fixed bug in Tcl_DStringResult that caused it to overwrite
+the contents of a static result in some situations.  This can cause
+bizarre errors such as variables suddenly having empty values.
+
+249. 2/21/94 Fixed bug in Tcl_AppendElement, Tcl_DStringAppendElement,
+and the "lappend" command that caused improper omission of a separator
+space in some cases.  For example, the script
+    set x "abc{"; lappend x "def"
+used to return the result "abc{def" instead of "abc{ def".
+
+250. 3/3/94 Tcl_ConvertElement was outputting empty elements as \0 if
+TCL_DONT_USE_BRACES was set.  This depends on old pre-7.0 meaning of
+\0, which is no longer in effect, so it didn't really work.  Changed
+to output empty elements as {} always.
+
+251. 3/3/94 Renamed Tcl_DStringTrunc to Tcl_DStringSetLength and extended
+it so that it can be used to lengthen a string as well as shorten it.
+Tcl_DStringTrunc is defined as a macro for backward compatibility, but
+it is deprecated.
+
+252. 3/3/94 Added Tcl_AllowExceptions procedure.
+
+253. 3/13/94 Fixed bug in Tcl_FormatCmd that could cause "format"
+to mis-behave on 64-bit Big-Endian machines.
+
+254. 3/13/94 Changed to use vfork instead of fork on systems where
+vfork exists.
+
+255. 3/23/94 Fixed bug in expressions where ?: didn't associate
+right-to-left as they should.
+
+256. 4/3/94 Fixed "exec" to flush any files used in >@ or >&@
+redirection in exec, so that data buffered for them is written
+before any new data added by the subprocess.
+
+257. 4/3/94 Added "subst" command.
+
+258. 5/20/94 The tclsh main program is now called Tcl_Main;  tclAppInit.c
+has a "main" procedure that calls Tcl_Main.  This makes it easier to use
+Tcl with C++ programs, which need their own main programs, and it also
+allows an application to prefilter the argument list before calling
+Tcl_Main.
+*** POTENTIAL INCOMPATIBILITY ***
+
+259. 6/6/94 Fixed bug in procedure returns where the errorInfo variable
+could get truncated if an unset trace was invoked as part of returning
+from the procedure.
+
+260. 6/13/94 Added "wordstart" and "wordend" options to "string" command.
+
+261. 6/27/94 Fixed bug in expressions where they didn't properly cancel
+the evaluation of math functions in &&, ||, and ?:.
+
+262. 7/11/94 Incorrect boolean values, like "ogle", weren't being
+handled properly.
+
+263. 7/15/94 Added Tcl_RegExpCompile, Tcl_RegExpExec, and Tcl_RegExpRange,
+which provide lower-level access to regular expression pattern matching.
+
+264. 7/22/94 Fixed bug in "glob" command where "glob -nocomplain ~bad_user"
+would complain about a missing user.  Now it doesn't complain anymore.
+
+265. 8/4/94 Fixed bug with linked variables where they didn't behave
+correctly when accessed via upvars.
+
+266. 8/17/94 Fixed bug in Tcl_EvalFile where it didn't clear interp->result.
+
+267. 8/31/94 Modified "open" command so that errors in exec-ing
+subprocesses are returned by the open immediately, rather than
+being delayed until the "close" is executed.
+
+268. 9/9/94 Modified "expr" command to generate errors for integer
+overflow (includes addition, subtraction, negation, multiplication,
+division).
+
+269. 9/23/94 Modified "regsub" to return a count of the number of
+matches and replacements, rather than 0/1.
+
+279. 10/4/94 Added new features to "array" command:
+    - added "get" and "set" commands for easy conversion between arrays
+      and lists.
+    - added "exists" command to see if a variable is an array, changed
+      "names" and "size" commands to treat a non-existent array (or scalar
+      variable) just like an empty one.
+    - added pattern option to "names" command.
+
+280. 10/6/94 Modified Tcl_SetVar2 so that read traces on variables get
+called during append operations.
+
+281. 10/20/94 Fixed bug in "read" command where reading from stdin
+required two control-D's to stop the reading.
+
+282. 11/3/94 Changed "expr" command to use longs for division just like
+all other expr operators;  it previously used ints for division.
+
+283. 11/4/94 Fixed bugs in "unknown" procedure:  it wasn't properly
+handling exception returns from commands that were executed after
+being auto-loaded.
+
+----------------- Released version 7.4b1, 12/23/94 ------------------
+
+284. 12/26/94 Fixed "install" target in Makefile (couldn't always
+find install program).
+
+285. 12/26/94 Added strcncasecmp procedure to compat directory.
+
+286. 1/3/95 Fixed all procedure calls to explicitly cast arguments:
+implicit conversions from prototypes (especially integer->double)
+don't work when compiling under non-ANSI compilers.  Tcl is now clean
+under gcc -Wconversion.
+
+287. 1/4/95 Fixed problem in Tcl_ArrayCmd where same name was used for
+both a label and a variable;  caused problems on several older compilers,
+making array command misbehave and causing many errors in Tcl test suite.
+
+----------------- Released version 7.4b2, 1/12/95 ------------------
+
+288. 2/9/95 Modified Tcl_CreateCommand to return a token, and added
+Tcl_GetCommandName procedure.  Together, these procedures make it possible
+to track renames of a command.
+
+289. 2/13/95 Fixed bug in expr where "089" was interpreted as a
+floating-point number rather than a bogus octal number.
+*** POTENTIAL INCOMPATIBILITY ***
+
+290. 2/14/95 Added code to Tcl_GetInt and Tcl_GetDouble to check for
+overflows when reading in numbers.
+
+291. 2/18/95 Changed "array set" to stop after first error, rather than
+continuing after error.
+
+292. 2/20/95 Upgraded to use autoconf version 2.2.
+
+293. 2/20/95 Fixed core dump that could occur in "scan" command if a
+close bracket was omitted.
+
+294. 2/27/95 Changed Makefile to always use install-sh for installations:
+there's just too much variation among "install" system programs, which
+makes installation flakey.
+
+----------------- Released version 7.4b3, 3/24/95 ------------------
+
+3/25/95 (bug fix) Changed "install" to "./install" in Makefile so that
+"make install" will work even when "." isn't in the search path.
+
+3/29/95 (bug fix) Fixed bug where the auto-loading mechanism wasn't
+protecting the values of the errorCode and errorInfo variables.
+
+3/29/95 (new feature) Added optional pattern argument to "parray" procedure.
+
+3/29/95 (bug fix) Made the full functionality of
+    "return -code ... -errorcode ..."
+work not just inside procedures, but also in sourced files and at
+top level.
+
+4/6/95 (new feature) Added "pattern" option to "array names" command.
+
+4/18/95 (bug fix) Fixed bug in parser where it didn't allow backslash-newline
+immediately after an argument in braces or quotes.
+
+4/19/95 (new feature) Added tcl_library variable, which application can
+set to override default library directory.
+
+4/30/95 (bug fix) During trace callbacks for array elements, the variable
+name used in the original reference would be temporarily modified to
+separate the array name and element name;  if the trace callback used
+the same name string, it would get the wrong name (the array name without
+element).  Fixed to restore the variable name before making trace
+callbacks.
+
+4/30/95 (new feature) Added -nobackslashes, -nocommands, and -novariables
+switches to "subst" command.
+
+5/4/95 (new feature) Added TCL_EVAL_GLOBAL flag to Tcl_RecordAndEval.
+
+5/5/95 (bug fix)  Format command would overrun memory when printing
+integers with very large precision, as in "format %.1000d 0".
+
+5/5/95 (portability improvement) Changed to use BSDgettimeofday on
+IRIX machines, to avoid compilation problems with the gettimeofday
+declaration.
+
+5/6/95 (bug fix) Changed manual entries to use the standard .TH
+macro instead of a custom .HS macro;  the .HS macro confuses index
+generators like makewhatis.
+
+5/9/95 (bug fix) Modified configure script to check for Solaris bug
+that makes vfork unreliable (core dumps result if vforked child
+changes a signal handler);  will use fork instead of vfork if the
+bug is present.
+
+6/5/95 (bug fix) Modified "lsort" command to disallow recursive calls
+to lsort from a comparison function.  This is needed because qsort
+is not reentrant.
+
+6/5/95 (bug fix) Undid change 243 above:  changed TCL_VOLATILE and
+TCL_DYNAMIC back to integer constants rather than procedure addresses.
+This was needed because procedure addresses can have multiple values
+under some dynamic loading systems (e.g. SunOS 4.1 and Windows).
+
+6/8/95 (feature change) Modified interface to Tcl_Main to pass in the
+address of the application-specific initialization procedure.
+Tcl_AppInit is no longer hardwired into Tcl_Main.  This is needed
+in order to make Tcl a shared library.
+
+6/8/95 (feature change) Modified Makefile so that the installed versions
+of tclsh and libtcl.a have version number in them (e.g. tclsh7.4 and
+libtcl7.4.a) and the library directory name also has an embedded version
+number (e.g., /usr/local/lib/tcl7.4).  This should make it easier for
+Tcl 7.4 to coexist with earlier versions.
+
+----------------- Released version 7.4b4, 6/16/95 ------------------
+
+6/19/95 (bug fix) Fixed bugs in tclCkalloc.c that caused core dumps
+if TCL_MEM_DEBUG was enabled on word-addressed machines such as Crays.
+
+6/21/95 (feature removal) Removed overflow checks for integer arithmetic:
+they just cause too much trouble (e.g. for random  number generators).
+
+6/28/95 (new features) Added tcl_patchLevel and tcl_version variables,
+for consistency with Tk.
+
+6/29/95 (bug fix) Fixed problem in Tcl_Eval where it didn't record
+the right termination character if a script ended with a comment.  This
+caused erroneous output for the following command, among others:
+puts "[
+expr 1+1
+# duh!
+]"
+
+6/29/95 (message change) Changed the error message for ECHILD slightly
+to provide a hint about why the problem is occurring.
+
+----------------- Released version 7.4, 7/1/95 ------------------
+
+7/18/95 (bug fix) Changed "lreplace" so that nothing is deleted if
+the last index is less than the first index or if the last index
+is < 0.
+
+7/18/95 (bug fix) Fixed bugs with backslashes in comments:
+Tcl_CommandComplete (and "info complete") didn't properly handle
+strings ending in backslash-newline, and neither Tcl_CommandComplete
+nor the Tcl parser handled other backslash sequences right, such
+as two backslashes before a newline.
+
+7/19/95 (bug fix) Modified Tcl_DeleteCommand to delete the hash table
+entry for the command before invoking its callback.  This is needed in
+order to deal with reentrancy.
+
+7/22/95 (bug fix) "exec" wasn't reaping processes correctly after
+certain errors (e.g. if the name of the executable was bogus, as
+in "exec foobar").
+
+7/27/95 (bug fix) Makefile.in wasn't using the LIBS variable provided
+by the "configure" script.  This caused problems on some SCO systems.
+
+7/27/95 (bug fix) The version of strtod in fixstrtod.c didn't properly
+handle the case where endPtr == NULL.
+
+----------------- Released patch 7.4p1, 7/29/95 -----------------------
+
+8/4/95 (bug fix) C-level trace callbacks for variables were sometimes
+receiving the PART1_NOT_PARSED flag, which could cause errors in
+subsequent Tcl library calls using the flags. (JO)
+
+8/4/95 (bug fix) Calls to toupper and tolower weren't using the
+UCHAR macros, which caused trouble in non-U.S. locales. (JO)
+
+8/10/95 (new feature) Added the "load" command for dynamic loading of
+binary packages, and the Tcl_PackageInitProc prototype for package
+initialization procedures. (JO)
+
+8/23/95 (new features) Added "info sharedlibextension" and
+"info nameofexecutable" commands, plus Tcl_FindExtension procedure. (JO)
+
+8/25/95 (bug fix) If the target of an "upvar" was non-existent but
+had traces set, the traces were silently lost.  Change to generate
+an error instead. (JO)
+
+8/25/95 (bug fix) Undid change from 7/19, so that commands can stay
+around while their deletion callbacks execute.  Added lots of code to
+handle all of the reentrancy problems that this opens up. (JO)
+
+8/25/95 (bug fix) Fixed core dump that could occur in TclDeleteVars
+if there was an upvar from one entry in the table to the next entry
+in the same table. (JO)
+
+8/28/95 (bug fix) Exec wasn't handling bad user names properly, as
+in "exec ~bogus_user/foo". (JO)
+
+8/29/95 (bug fixes) Changed backslash-newline handling to correct two
+problems:
+    - Only spaces and tabs following the backslash-newline are now
+      absorbed as part of the backslash-newline.  Newlinew are no
+      longer absorbed (add another backslash if you want to absorb
+      another newline).
+    - TclWordEnd returns the character just before the backslash in
+      the sequence as the end of the sequence;  it used to not consider
+      the backslash-newline as a word separator. (JO)
+
+8/31/95 (new feature) Changed man page installation (with "mkLinks"
+script) to create additional links for manual pages corresponding to
+each of the procedure and command names described in the pages. (JO)
+
+9/10/95 Reorganized Tcl sources for Windows and Mac ports.  All sources
+are now in subdirectories:  "generic" contains sources that work on all
+platforms, "windows", "mac", and "unix" directories contain platform-
+specific sources.  Some UNIX sources are also used on other platforms. (SS)
+
+9/10/95 (feature change) Eliminated exported global variables (they
+don't work with Windows DLLs).  Replaced tcl_AsyncReady and
+tcl_FileCloseProc with procedures Tcl_AsyncReady() and
+Tcl_SetFileCloseProc().  Replaced C variable tcl_RcFileName with
+a Tcl variable tcl_rcFileName. (SS)
+*** POTENTIAL INCOMPATIBILITY ***
+
+9/11/95 (new feature) Added procedure Tcl_SetPanicProc to override
+the default implementation of "panic". (SS)
+
+9/11/95 (new feature) Added "interp" command to allow creation of
+new interpreters and execution of untrusted scripts.  Added many new
+procedures, such as Tcl_CreateSlave, Tcl_CreateAlias,and Tcl_MakeSafe,
+to provide C-level access to the interpreter facility. This mechanism
+now provides almost all of the generic functions of Borenstein's and
+Rose's Safe-Tcl (but not any Tk or email-related stuff).  (JL)
+
+9/11/95 (feature change) Changed file management so that files are
+no longer shared between interpreters:  a file cannot normally be
+referenced in one interpreter if it was opened in another.  This
+feature is needed to support safe interpreters.  Added Tcl_ShareHandle()
+procedure for allowing files to be shared, and added "interp" argument
+to Tcl_FilePermissions procedure. (JL)
+*** POTENTIAL INCOMPATIBILITY ***
+
+9/11/95 (new feature) Added "AssocData" mechanism, whereby extensions
+can associate their own data with an interpreter and get called back
+when the interpreter is deleted.  This is visible at C level via the
+procedures Tcl_SetAssocData and Tcl_GetAssocData.  (JL)
+
+9/11/95 (new feature) Added Tcl_ErrnoMsg to translate an errno value
+into a human-readable string.  This is now used instead of calling
+strerror because strerror mesages vary dramatically from platform
+to platform, which messes up Tcl tests.  Tcl_ErrnoMsg uses the standard
+POSIX messages for all the common signals, and calls strerror for
+signals it doesn't understand.
+
+----------------- Released patch 7.4p2, 9/15/95 -----------------------
+
+----------------- Released 7.5a1, 9/15/95 -----------------------
+
+9/22/95 (bug fix) Changed auto_mkindex to create tclIndex files that
+handle directories whose paths might contain spaces. (RJ)
+
+9/27/95 (bug fix) The "format" command didn't check for huge or negative
+width specifiers, which could cause core dumps. (JO)
+
+9/27/95 (bug fix) Core dumps could occur if an interactive command typed
+to tclsh returned a very long result for tclsh to print out.  The bug is
+actually in printf (in Solaris 2.3 and 2.4, at least);  switched to use
+puts instead.  (JO)
+
+9/28/95 (bug fix) Changed makefile.bc to eliminate a false dependency
+for tcl1675.dll on the Borland run time library. (SS)
+
+9/28/95 (bug fix) Fixed tcl75.dll so it looks for tcl1675.dll instead
+of tcl16.dll. (SS)
+
+9/28/95 (bug fix) Tcl was not correctly detecting the difference
+between Win32s and Windows '95. (SS)
+
+9/28/95 (bug fix) "exec" was not passing environment changes to child
+processes under Windows. (SS)
+
+9/28/95 (bug fix) Changed Tcl to ensure that open files are not passed
+to child processes under Windows. (SS)
+
+9/28/95 (bug fix) Fixed Windows '95 and NT versions of exec so it can
+handle both console and windows apps.   (SS)
+
+9/28/95 (bug fix) Fixed Windows version of exec so it no longer leaves
+temp files lying around.  Also changed it so the temp files are
+created in the appropriate system dependent temp directory. (SS)
+
+9/28/95 (bug fix) Eliminated source dependency on the Win32s Universal
+Thunk header file, since it is not bundled with VC++. (SS)
+
+9/28/95 (bug fix) Under Windows, Tcl now constructs the HOME
+environment variable from HOMEPATH and HOMEDRIVE when HOME is not
+already set. (SS)
+
+9/28/95 (bug fix) Added support for "info nameofexecutable" and "info
+sharedlibextension" to the Windows version. (SS)
+
+9/28/95 (bug fix) Changed tclsh to correctly parse command line
+arguments so that backslashes are preserved under Windows. (SS)
+
+9/29/95 (bug fix) Tcl 7.5a1 treated either return or newline as end
+of line in "gets", which caused lines ending in CRLF to be treated as
+two separate lines.  Changed to allow only character as end-of-line:
+carriage return on Macs, newline elsewhere. (JO)
+
+9/29/95 (new feature) Changed to install "configInfo" file in same
+directory as library scripts.  It didn't used to get installed. (JO)
+
+9/29/95 (bug fix) Tcl was not converting Win32 errors into POSIX
+errors under some circumstances. (SS)
+
+10/2/95 (bug fix) Safe interpreters no longer get initialized with
+a call to Tcl_Init(). (JL)
+
+10/1/95 (new feature) Added "tcl_platform" global variable to provide
+environment information such as the instruction set and operating
+system. (JO)
+
+10/1/95 (bug fix) "exec" command wasn't always generating the
+"child process exited abnormally" message when it should have.  (JO)
+
+10/2/95 (bug fix) Changed "mkLinks.tcl" so that the scripts it generates
+won't create links that overwrite original manual entries (there was
+a problem where pack-old.n was overwriting pack.n).  (JO)
+
+10/2/95 (feature change) Changed to use -ldl for dynamic loading under
+Linux if it is available, but fall back to -ldld if it isn't.  (JO)
+
+10/2/95 (bug fix) File sharing was causing refcounts to reach 0
+prematurely for stdin, stdout and stderr, under some circumstances. (JL)
+
+10/2/95 (platform support) Added support for Visual C++ compiler on
+Windows, Windows '95 and Windows NT, code donated by Gordon Chaffee. (JL)
+
+10/3/95 (bug fix) Tcl now frees any libraries that it loads before it
+exits. (SS)
+
+10/03/95 (bug fix) Fixed bug in Macintosh ls command where the -l
+and -C options would fail in anything but the HOME directory. (RJ)
+
+----------------- Released 7.5a2, 10/6/95 -----------------------
+
+10/10/95 (bug fix) "file dirnam /." was returning ":" on UNIX instead
+of "/". (JO)
+
+10/13/95 (bug fix) Eliminated dependency on MKS toolkit for generating
+the tcl.def file from Borland object files. (SS)
+
+10/17/95 (new features) Moved the event loop from Tcl to Tk, made major
+revisions along the way:
+    - New Tcl commands:  after, update, vwait (replaces "tkwait variable").
+    - "tkerror" is now replaced with "bgerror".
+    - The following procedures are similar to their old Tk counterparts:
+      Tcl_DoOneEvent, Tcl_Sleep, Tcl_DoWhenIdle, Tcl_CancelIdleCall,
+      Tcl_CreateFileHandler, Tcl_DeleteFileHandler, Tcl_CreateTimerHandler,
+      Tcl_DeleteTimerHandler, Tcl_BackgroundError.
+    - Revised notifier, add new concept of "event source" with the following
+      procedures:  Tcl_CreateEventSource, Tcl_DeleteEventSource,
+      Tcl_WatchFile, Tcl_SetMaxBlockTime, Tcl_FileReady, Tcl_QueueEvent,
+      Tcl_WaitForEvent. (JO)
+
+10/31/95 (new features) Implemented cross platform file name support to make
+it easier to write cross platform scripts.  Tcl now understands 4 file naming
+conventions: Windows (both DOS and UNC), Mac, Unix, and Network.  The network
+convention is a new naming mechanism that can be used to paths in a platform
+independent fashion.  See the "file" command manual page for more details.
+The primary interfaces changes are:
+    - All Tcl commands that expect a file name now accept both network and
+      native form.
+    - Two new "file" subcommands, "nativename" and "networkname", provide a
+      way to convert between network and native form.
+    - Renamed Tcl_TildeSubst to Tcl_TranslateFileName, and changed it so that
+      it always returns a filename in native form.  Tcl_TildeSubst is defined
+      as a macro for backward compatibility, but it is deprecated. (SS)
+
+11/5/95 (new feature) Made "tkerror" and "bgerror" synonyms, so that
+either name can be used to manipulate the command (provides temporary
+backward compatibility for existing scripts that use tkerror). (JO)
+
+11/5/95 (new feature) Added exit handlers and new C procedures
+Tcl_CreateExitHandler, Tcl_DeleteExitHandler, and Tcl_Exit. (JO)
+
+11/6/95 (new feature) Added pid command for Macintosh version of
+Tcl (it didn't previously exist on the Mac). (RJ)
+
+11/7/95 (new feature) New generic IO facility and support for IO to
+files, pipes and sockets based on a common buffering scheme. Support
+for asynchronous (non-blocking) IO and for event driver IO. Support
+for automatic (background) asynchronous flushing and asynchronous
+closing of channels. (JL)
+
+11/7/95 (new feature)  Added new commands "fconfigure" and "fblocked"
+to support new I/O features such as nonblocking I/O.  Added "socket"
+command for creating TCP client and server sockets. (JL).
+
+11/7/95 (new feature) Complete set of C APIs to the new generic IO
+facility:
+    - Opening channels: Tcl_OpenFileChannel, Tcl_OpenCommandChannel,
+      Tcl_OpenTcpClient, Tcl_OpenTcpServer.
+    - I/O procedures on channels, which roughly mirror the ANSI C stdio
+      library:  Tcl_Read, Tcl_Gets, Tcl_Write, Tcl_Flush, Tcl_Seek,
+      Tcl_Tell, Tcl_Close, Tcl_Eof, Tcl_InputBlocked, Tcl_GetChannelOption,
+      Tcl_SetChannelOption.
+    - Extension mechanism for creating new kinds of channels:
+      Tcl_CreateChannel, Tcl_GetChannelInstanceData, Tcl_GetChannelType,
+      Tcl_GetChannelName, Tcl_GetChannelFile, Tcl_RegisterChannel,
+      Tcl_UnregisterChannel, Tcl_GetChannel.
+    - Event-driven I/O on channels: Tcl_CreateChannelHandler,
+      Tcl_DeleteChannelHandler. (JL)
+
+11/7/95 (new feature) Channel driver interface specification to allow
+new types of channels to be added easily to Tcl. Currently being used
+in three drivers - for files, pipes and TCP-based sockets. (JL).
+
+11/7/95 (new feature) interp delete now takes any number of path
+names of interpreters to delete, including zero. (JL).
+
+11/8/95 (new feature) implemented 'info hostname' and Tcl_GetHostName
+command to get host name of machine on which the Tcl process is running. (JL)
+
+11/9/95 (new feature) Implemented file APIs for access to low level files
+on each system. The APIs are: Tcl_CloseFile, Tcl_OpenFile, Tcl_ReadFile,
+Tcl_WriteFile and Tcl_SeekFile. Also implemented Tcl_WaitPid which waits
+in a system dependent manner for a child process. (JL)
+
+11/9/95 (new feature) Added Tcl_UpdateLinkedVar procedure to force a
+Tcl variable to be updated after its C variable changes. (JO)
+
+11/9/95 (bug fix) The glob command has been totally reimplemented so
+that it can support different file name conventions.  It now handles
+Windows file names (both UNC and drive-relative) properly.  It also
+supports nested braces correctly now. (SS)
+
+11/13/95 (bug fix) Fixed Makefile.in so that configure can be run
+from a clean directory separate from the Tcl source tree, and compilations
+can be performed there. (JO)
+
+11/14/95 (bug fix) Fixed file sharing between interpreters and file
+transferring between interpreters to correctly manage the refcount so that
+files are closed when the last reference to them is discarded. (JL)
+
+11/14/95 (bug fix) Fixed gettimeofday implementation for the
+Macintosh.  This fixes several timing related bugs. (RJ)
+
+11/17/95 (new feature) Added missing support for info nameofexecutable
+on the Macintosh. (RJ)
+
+11/17/95 (bug fix) The Tcl variables argc argv and argv0 now return
+something reasonable on the Mac.  (RJ)
+
+11/22/95 (new feature) Implemented "auto-detect" mode for end of line
+translations. On input, standalone "\r" mean MAC mode, standalone "\n"
+mean Unix mode and "\r\n" means Windows mode. On output, the mode is
+modified to whatever the platform specific mode for that platform is. (JL)
+
+11/24/95 (feature change) Replaced "configInfo" file with tclConfig.sh,
+which is more complete and uses slightly different names.  Also
+arranged for tclConfig.sh to be installed in the platform-specific
+library directory instead of Tcl's script library directory. (JO)
+*** POTENTIAL INCOMPATIBILITY with Tcl 7.5a2, but not with Tcl 7.4 ***
+
+----------------- Released patch 7.4p3, 11/28/95 -----------------------
+
+12/5/95 (new feature) Added Tcl_File facility to support platform-
+independent file handles.  Changed all interfaces that used Unix-
+style integer fd's to use Tcl_File's instead. (SS)
+*** POTENTIAL INCOMPATIBILITY ***
+
+12/5/95 (new feature) Added a new "clock" command to Tcl.  The command
+allows you to get the current "clicks" or seconds & allows you to
+format or scan human readable time/date strings. (RJ)
+
+12/18/95 (new feature) Moved Tk_Preserve, Tk_Release, and Tk_EventuallyFree
+to Tcl, renamed to Tcl_Preserve, Tcl_Release, and Tcl_EventuallyFree. (JO)
+
+12/18/95 (new feature) Added new "package" command and associated
+procedures Tcl_PkgRequire and Tcl_PkgProvide.   Also wrote
+pkg_mkIndex library procedure to create index files from binaries
+and scripts. (JO)
+
+12/20/95 (new feature) Added Tcl_WaitForFile procedure. (JO)
+
+12/21/95 (new features) Made package name argument to "load" optional
+(Tcl will now attempt to guess the package name if necessary).  Also
+added Tcl_StaticPackage and support in "load" for statically linked
+packages.  (JO)
+
+12/22/95 (new feature) Upgraded the foreach command to accept multiple
+loop variables and multiple value lists.  This lets you iterate over
+multiple lists in parallel, and/or assign multiple loop variables from
+one value list during each iteration. The only potential compatibility
+problem is with scripts that used loop variables with a name that could be
+construed to be a list of variable names (i.e. contained spaces).  (BW)
+
+1/5/96 (new feature) Changed tclsh so it builds as a console mode
+application under Windows.  Now tclsh can be used from the command
+line with pipes or interactively.  Note that this only works under
+Windows 95 or NT. (SS)
+
+1/17/96 (new feature) Modified Makefile and configure script to allow
+Tcl to be compiled as a shared library:  use the --enable-shared option
+when configuing.  (JO)
+
+1/17/96 (removed obsolete features)  Removed the procedures Tcl_EnterFile
+and Tcl_GetOpenFile:  these no longer make sense with the new I/O system. (JL)
+*** POTENTIAL INCOMPATIBILITY ***
+
+1/19/96 (bug fixes) Prevented formation of circular aliases, through the
+Tcl 'interp alias' command and through the 'rename' command, as well as
+through the C API Tcl_CreateAlias. (JL)
+
+1/19/96 (bug fixes) Fixed several bugs in direct deletion of interpreters
+with Tcl_DeleteInterp when the interpreter is a slave; fixes based on a
+patch received from Viktor Dukhovni of ESM. (JL)
+
+1/19/96 (new feature) Implemented on-close handlers for channels; added
+the C APIs Tcl_CreateCloseHandler and Tcl_DeleteCloseHandler. (JL)
+
+1/19/96 (new feature) Implemented portable error reporting mechanism; added
+the C APIs Tcl_SetErrno and Tcl_GetErrno. (JL)
+
+1/24/96 (bug fix) Unknown command processing properly invokes external
+commands under Windows NT and Windows '95 now. (SS)
+
+1/23/96 (bug fix) Eliminated extremely long startup times under Windows '95.
+The problem was a result of the option database initialization code that
+concatenated $HOME with /.Xdefaults, resulting in a // in the middle of the
+file name.  Under Windows '95, this is incorrectly interpreted as a UNC
+path.  They delays came from the network timeouts needed to determine that
+the file name was invalid.  Tcl_TranslateFileName now suppresses duplicate
+slashes that aren't at the beginning of the file name. (SS)
+
+1/25/96 (bug fix) Changed exec and open to create children so they are
+attached to the application's console if it exists. (SS)
+
+1/31/96 (bug fix) Fixed command line parsing to handle embedded
+spaces under Windows. (SS)
+
+----------------- Released 7.5b1, 2/1/96 -----------------------
+
+2/7/96 (bug fix) Fixed off by one error in argument parsing code under
+Windows. (SS)
+
+2/7/96 (bug fix) Fixed bugs in VC++ makefile that improperly
+initialized the tcl75.dll.  Fixed bugs in Borland makefile that caused
+build failures under Windows NT. (SS)
+
+2/9/96 (bug fix) Fixed deadlock problem in AUTO end of line translation
+mode which would cause a socket server with several concurrent clients
+writing in CRLF mode to hang. (JL)
+
+2/9/96 (API change) Replaced -linemode option to fconfigure with a
+new -buffering option, added "none" setting to enable immediate write. (JL)
+*** INCOMPATIBILITY with b1 ***
+
+2/9/96 (new feature) Added C API Tcl_InputBuffered which returns the count
+of bytes currently buffered in the input buffer of a channel, and o for
+output only channels. (JL)
+
+2/9/96 (new feature) Implemented asynchronous connect for sockets. (JL)
+
+2/9/96 (new feature) Added C API Tcl_SetDefaultTranslation to set (per
+channel) the default end of line translation mode. This is the mode that
+will be installed if an output operation is done on the channel while it is
+still in AUTO mode. (JL)
+
+2/9/96 (bug fix) Changed Tcl_OpenCommandChannel interface to properly
+handle all of the combinations of stdio inheritance in background
+pipelines.  See the Tcl_OpenFileChannel(3) man page for more
+info.  This change fixes the bug where exec of a background pipeline
+was not getting passed the stdio handles properly. (SS)
+
+2/9/96 (bug fix) Removed the new Tcl_CreatePipeline interface, and
+restored the old version for Unix platforms only.  All new code should
+use Tcl_CreateCommandChannel instead. (SS)
+
+2/9/96 (bug fix) Changed Makefile.in to use -L and -ltcl7.5 for Tcl
+library so that shared libraries are more likely to be found correctly
+on more platforms. (JO)
+
+2/13/96 (new feature) Added C API Tcl_SetNotifierData and
+Tcl_GetNotifierData to allow notifier and channel driver writers to
+associate data with a Tcl_File.  The result of this change is that
+Tcl_GetFileInfo now always returns an OS file handle, and Tcl_GetFile
+can be used to construct a Tcl_File for an externally constructed OS
+handle. (SS)
+
+2/13/96 (bug fix) Changed Windows socket implementation so it doesn't
+set SO_REUSEADDR on server sockets.  Now attempts to create a server
+socket on a port that is already in use will be properly identified
+and an error will be generated. (SS)
+
+2/13/96 (bug fix) Fixed problems with DLL initialization under Visual
+C++ that left the C run time library uninitialized. (SS)
+
+2/13/96 (bug fix) Fixed Windows socket initialization so it loads
+winsock the first time it is used, rather than at the time tcl75.dll
+is loaded.  This should fix the bug where the modem immediately starts
+trying to connect to a service provider when wish or tclsh are
+started. (SS)
+
+2/13/96 (new feature) Added C APIs Tcl_MakeFileChannel and
+Tcl_MakeTcpClientChannel to wrap up existing fds and sockets into
+channels. Provided implementations on Unix and Windows. (JL)
+
+2/13/96 (bug fix) Fixed bug with seek leaving EOF and BLOCKING set. (JL)
+
+2/14/96 (bug fix) Fixed reentrancy problem in fileevent handling
+and made it more robust in the face of errors. (JL)
+
+2/14/96 (feature change) Made generic IO level emulate blocking mode if the
+channel driver is unable to provide it, e.g. if the low level device is
+always nonblocking. Thus, now blocking behavior is an advisory setting for
+channel drivers and can be ignored safely if the channel driver is unable
+to provide it. (JL)
+
+2/15/96 (new feature) Added "binary" end of line translation mode, which is
+a synonym of "lf" mode. (JL)
+
+2/15/96 (bug fix) Fixed reentrancy problem in fileevent handling vs
+deletion of channel event handlers. (JL)
+
+2/15/96 (bug fix) Fixed bug in event handling which would cause a
+nonblocking channel to not see further readable events after the first
+readable event that had insufficient input. (JL)
+
+2/17/96 (bug fix) "info complete" didn't properly handle comments
+in nested commands. (JO)
+
+2/21/96 (bug fix) "exec" under Windows NT/95 did not properly handle
+very long command lines (>200 chars). (SS)
+
+2/21/96 (bug fix) Sockets could get into an infinite loop if a read
+event arrived after all of the available data had been read. (SS)
+
+2/22/96 (bug fix) Added cast of st_size elements to (long) before
+sprintf-ing in "file size" command.  This is needed to handle systems
+like NetBSD with 64-bit file offsets.  (JO)
+
+----------------- Released 7.5b2, 2/23/96 -----------------------
+
+2/23/96 (bug fix) TCL_VARARGS macro in tcl.h wasn't defined properly
+when compiling with C++.  (JO)
+
+2/24/96 (bug fix) Removed dependencies on Makefile in the UNIX Makefile:
+this caused problems on some platforms (like Linux?). (JO)
+
+2/24/96 (bug fix) Fixed configuration bug that made Tcl not compile
+correctly on Linux machines with neither -ldl or -ldld. (JO)
+
+2/24/96 (new feature) Added a block of comments and definitions to
+Makefile.in to make it easier to have Tcl's TclSetEnv etc. replace
+the library procedures setenv etc, so that calls to setenv etc. in
+the application automatically update the Tcl "env" variable. (JO)
+
+2/27/96 (feature change) Added optional Tcl_Interp * argument (may be NULL)
+to C API Tcl_Close and simplified closing of command channels. (JL)
+*** INCOMPATIBILITY with Tcl 7.5b2, but not with Tcl 7.4 ***
+
+2/27/96 (feature change) Added optional Tcl_Interp * argument (may be NULL)
+to C type definition Tcl_DriverCloseProc; modified all channel drivers to
+implement close procedures that accept the additional argument. (JL)
+*** INCOMPATIBILITY with Tcl 7.5b2, but not with Tcl 7.4 ***
+
+2/28/96 (bug fix) Fixed memory leak that could occur if an upvar
+referred to an element of an array in the same stack frame as the
+upvar. (JO)
+
+2/29/96 (feature change) Modified both Tcl_DoOneEvent and Tcl_WaitForEvent
+so that they return immediately in cases where they would otherwise
+block forever (e.g. if there are no event handlers of any sort). (JO)
+
+2/29/96 (new feature) Added C APIs Tcl_GetChannelBufferSize and
+Tcl_SetChannelBufferSize to set and retrieve the size, in bytes, for
+buffers allocated to store input or output in a channel. (JL)
+
+2/29/96 (new feature) Added option -buffersize to Tcl fconfigure command
+to allow Tcl scripts to query and set the size of channel buffers. (JL)
+
+2/29/96 (feature removed) Removed channel driver function to specify
+the buffer size to use when allocating a buffer. Removed the C typedef
+for Tcl_DriverBufferSizeProc. Channels are now created with a default
+buffer size of 4K. (JL)
+*** INCOMPATIBILITY with Tcl 7.5b2, but not with Tcl 7.4 ***
+
+2/29/96 (feature change) The channel driver function for setting blocking
+mode on the device may now be NULL. If the generic code detects that the
+function is NULL, operations that set the blocking mode on the channel
+simply succeed. (JL)
+
+3/2/96 (bug fix) Fixed core dump that could occur if a syntax error
+(such as missing close paren) occurred in an array reference with a
+very long array name. (JO)
+
+3/4/96 (bug fix) Removed code in the "auto_load" procedure that deletes
+all existing auto-load information whenever the "auto_path" variable
+is changed.  Instead, new information adds to what was already there.
+Otherwise, changing the "auto_path" variable causes all package-
+related information to be lost.  If you really want to get rid of
+existing auto-load information, use auto_reset before setting auto_path. (JO)
+
+3/5/96 (new feature) Added version suffix to shared library names so that
+Tcl will compile under NetBSD and FreeBSD (I hope).  (JO)
+
+3/6/96 (bug fix) Cleaned up error messages in new I/O system to correspond
+more closely to old I/O system. (JO)
+
+3/6/96 (new feature) Added -myaddr and -myport options to the socket
+command, removed -tcp and -- options.  This lets clients and servers
+choose a particular interface.  Also changed the default server address
+from the hostname to INADDR_ANY.  The server accept callback now gets
+passed the client's port as well as IP address.  The C interfaces for
+Tcl_OpenTcpClient and Tcl_OpenTcpServer have changed to support the
+above changes. (BW)
+*** POTENTIAL INCOMPATIBILITY with Tcl 7.5b2, but not with Tcl 7.4 ***
+
+3/6/96 (changed feature) The library function auto_mkindex will now
+default to using the pattern "*.tcl" if no pattern is given. (RJ)
+
+3/6/96 (bug fix) The socket channel code for the Macintosh has been
+rewritten to use native MacTcp.  (RJ)
+
+3/7/96 (new feature) Added Tcl_SetStdChannel and Tcl_GetStdChannel
+interfaces to allow applications to explicitly set and get the global
+standard channels. (SS)
+
+3/7/96 (bug fix) Tcl did close not the file descriptors associated
+with "stdout", etc. when the corresponding channels were closed.  (SS)
+
+3/7/96 (bug fix) Reworked shared library and dynamic loading stuff to
+try to get it working under AIX.  Added new @SHLIB_LD_LIBS@ autoconf
+symbol as part of this.  AIX probably doesn't work yet, but it should
+be a lot closer. (JO)
+
+3/7/96 (feature change) Added Tcl_ChannelProc typedef and changed the
+signature of Tcl_CreateChannelHandler and Tcl_DeleteChannelHandler to take
+Tcl_ChannelProc arguments instead of Tcl_FileProc arguments. This change
+should not affect any code outside Tcl because the signatures of
+Tcl_ChannelProc and Tcl_FileProc are compatible. (JL)
+
+3/7/96 (API change) Modified signature of Tcl_GetChannelOption to return
+an int instead of char *, and to take a Tcl_DString * argument. Modified
+the implementation so that the option name can be NULL, to mean that the
+call should retrieve a list of alternating option names and values. (JL)
+*** INCOMPATIBILITY with Tcl 7.5b2, but not with Tcl 7.4 ***
+
+3/7/96 (API change) Added Tcl_DriverSetOptionProc, Tcl_DriverGetOptionProc
+typedefs, added two slots setOptionProc and getOptionProc to the channel
+type structure. These may be NULL to indicate that the channel type does
+not support any options. (JL)
+*** INCOMPATIBILITY with Tcl 7.5b2, but not with Tcl 7.4 ***
+
+3/7/96 (feature change) stdin, stdout and stderr can now be put into
+nonblocking mode. (JL)
+
+3/8/96 (feature change) Eliminated dependence on the registry for
+finding the Tcl library files. (SS)
+
+----------------- Released 7.5b3, 3/8/96 -----------------------
+
+3/12/96 (feature improvement) Modified startup script to look in several
+different places for the Tcl library directory.  This should allow Tcl
+to find the libraries under all but the weirdest conditions, even without
+the TCL_LIBRARY environment variable being set. (JO)
+
+3/13/96 (bug fix) Eliminated use of the "linger" option from the Windows
+socket implementation. (JL)
+
+3/13/96 (new feature) Added -peername and -sockname options for fconfigure
+for socket channels. Code contributed by John Haxby of HP. (JL)
+
+3/13/96 (bug fix) Fixed panic and core dump that would occur if the accept
+callback script on a server socket encountered an error. (JL)
+
+3/13/96 (feature change) Added -async option to the Tcl socket command.
+If the command is creating a client socket and the flag is present, the
+client is connected asynchronously. If the option is absent (the default),
+the client socket is connected synchronously, and the command returns only
+when the connection has been completed or failed. This change was suggested
+by Mark Diekhans. (JL)
+
+3/13/96 (feature change) Modified the signature of Tcl_OpenTcpClient to
+take an additional int argument, async. If nonzero, the client is connected
+to the server asynchronously. If the value is zero, the connection is made
+synchronously, and the call to Tcl_OpenTcpClient returns only when the
+connection fails or succeeds. This change was suggested by Mark Diekhans. (JL)
+*** INCOMPATIBILITY with Tcl 7.5b3, but not with Tcl 7.4 ***
+
+3/14/96 (bug fix) "tclsh bogus_file_name" didn't print an error message. (JO)
+
+3/14/96 (bug fix) Added new procedures to tclCkalloc.c so that libraries
+and applications can be compiled with TCL_MEM_DEBUG even if Tcl isn't
+(however, the converse is still not true).  Patches provided by Jan
+Nijtmans. (JO)
+
+3/15/96 (bug fix) Marked standard IO handles of a process as close-on-exec
+to fix bug in Ultrix where exec was not sharing standard IO handles with
+subprocesses. Fix suggested by Mark Diekhans. (JL)
+
+3/15/96 (bug fix) Fixed asynchronous close mechanism so that it closes the
+channel instead of leaking system resources. The manifestation was that Tcl
+would eventually run out of file descriptors if it was handling a large
+number of nonblocking sockets or pipes with high congestion. (JL)
+
+3/15/96 (bug fix) Fixed tests so that they no longer leak file descriptors.
+The manifestation was that Tcl would eventually run out of file descriptors
+if the tests were rerun many times (> a hundred times on Solaris). (JL)
+
+3/15/96 (bug fix) Fixed channel creation code so that it never creates
+unnamed channels. This would cause a panic and core dump when the channel
+was closed. (JL)
+
+3/16/96 (bug fixes) Made lots of changes in configuration stuff to get
+Tcl working under AIX (finally).  Tcl should now support the "load"
+command under AIX and should work either with or without shared
+libraries for Tcl and Tk. (JO)
+
+3/21/96 (configuration improvement) Changed configure script so it
+doesn't use version numbers (as in -ltcl7.5 and libtcl7.5.so) under
+SunOS 4.1, where they don't work anyway.  (JO)
+
+3/22/96 (new feature) Added C API Tcl_InterpDeleted that allows extension
+writers to discover when an interpreter is being deleted. (JL)
+
+3/22/96 (bug fix) The standard IO channels are now added to each
+trusted interpreter as soon as the interpreter is created. This ensures
+against the bug where a child would do IO before the master had done any,
+and then the child is destroyed - the standard IO channels would be then
+closed and the master would be unable to do any IO. (JL)
+
+3/22/96 (bug fix) Made Tcl more robust against interpreter deletion, by
+using Tcl_Preserve, Tcl_Release and Tcl_EventuallyFree to split the process
+of interpreter deletion into two distinct phases. Also went through all of
+Tcl and added calls to Tcl_Preserve and Tcl_Delete where needed. (JL)
+
+3/22/96 (bug fix) Fixed several places where C code was reading and writing
+into freed memory, especially during interpreter deletion. (JL)
+
+3/22/96 (bug fix) Fixed very deep bug in Tcl_Release that caused memory to
+be freed twice if the release callback did Tcl_Preserve and Tcl_Release on
+the same memory as the chunk currently being freed. (JL)
+
+3/22/96 (bug fix) Removed several memory leaks that would cause memory
+buildup on half-K chunks in the generic IO level. (JL)
+
+3/22/96 (bug fix) Fixed several core dumps which occurred when new
+AssocData was being created during the cleanups in interpreter deletion.
+The solution implemented now is to loop repeatedly over the AssocData until
+none is left to clean up. (JL)
+
+3/22/96 (bug fix) Fixed a bug in event handling which caused an infinite
+loop if there were no files being watched and no timer. Fix suggested by
+Jan Nijtmans. (JL)
+
+3/22/96 (bug fix) Fixed Tcl_CreateCommand, Tcl_DeleteCommand to be more
+robust if the interpreter is being deleted. Also fixed several order
+dependency bugs in Tcl_DeleteCommand which kicked in when an interpreter
+was being deleted. (JL)
+
+3/26/96 (bug fix) Upon a "short read", the generic code no longer calls
+the driver for more input. Doing this caused blocking on some platforms
+even on nonblocking channels. Bug and fix courtesy Mark Roseman. (JL)
+
+3/26/96 (new feature) Added 'package Tcltest' which is present only in
+test versions of Tcl; this allows the testing commands to be loaded into
+new interpreters besides the main one. (JL)
+
+3/26/96 (restored feature) Recreated the Tcl_GetOpenFile C API. You can
+now get a FILE * from a registered channel; Unix only. (JL)
+
+3/27/96 (bug fix) The regular expression code did not support more
+than 9 subexpressions.  It now supports up to 20. (SS)
+
+4/1/96 (bug fixes) The CHANNEL_BLOCKED bit was being left on on a short
+read, so that fileevents wouldn't fire correctly. Bug reported by Mark
+Roseman.(JL, RJ)
+
+4/1/96 (bug fix) Moved Tcl_Release to match Tcl_Preserve exactly, in
+tclInterp.c; previously interpreters were being freed only conditionally
+and sometimes not at all. (JL)
+
+4/1/96 (bug fix) Fixed error reporting in slave interpreters when the
+error message was being generated directly by C code. Fix suggested by
+Viktor Dukhovni of ESM. (JL)
+
+4/2/96 (bug fixes) Fixed a series of bugs in Windows sockets that caused
+events to variously get lost, to get sent multiple times, or to be ignored
+by the driver. The manifestation was blocking if the channel is blocking,
+and either getting EAGAIN or infinite loops if the channel is nonblocking.
+This series of bugs was found by Ian Wallis of Cisco. Now all tests (also
+those that were previously commented out) in socket.test pass.  (JL, SS)
+
+4/2/96 (feature change/bug fix) Eliminated network name support in
+favor of better native name support.  Added "file split", "file join",
+and "file pathtype" commands.  See the "file" man page for more
+details. (SS)
+*** INCOMPATIBILITY with Tcl 7.5b3, but not with Tcl 7.4 ***
+
+4/2/96 (bug fix) Changed implementation of auto_mkindex so tclIndex
+files will properly handle path names in a cross platform context. (SS)
+
+4/5/96 (bug fix) Fixed Tcl_ReadCmd to use the channel buffer size as the
+chunk size it reads, instead of a fixed 4K size. Thus, on large reads, the
+user can set the channel buffer size to a large size and the read will
+occur orders of magnitude faster. For example, on a 2MB file, reading in 4K
+chunks took 34 seconds, while reading in 1MB chunks took 1.5 seconds (on a
+SS-20). Problem identified and fix suggested by John Haxby of HP. (JL)
+
+4/5/96 (bug fix) Fixed socket creation code to invoke gethostbyname only if
+inet_addr failed (very unlikely). Before this change the order was reversed
+and this made things much slower than they needed to be (gethostbyname
+generally requires an RPC, which is slow). Problem identified and fix
+suggested by John Loverso of OSF. (JL)
+
+4/9/96 (feature change) Modified "auto" translation mode so that it
+recognizes any of "\n", "\r" and "\r\n" in input as end of line, so
+that a file can have mixed end-of-line sequences. It now outputs
+the platform specific end of line sequence on each platform for files and
+pipes, and for sockets it produces crlf in output on all platforms. (JL)
+*** INCOMPATIBILITY with Tcl 7.5b3, but not with Tcl 7.4 ***
+
+4/11/96 (new feature) Added -eofchar option to Tcl_SetChannelOption to allow
+setting of an end of file character for input and output. If an input eof
+char is set, it is recognized as EOF and further input from the channel is
+not presented to the caller. If an output eof char is set, on output, that
+byte is appended to the channel when it is closed. On Unix and Macintosh,
+all channels start with no eof char set for input or output. On Windows,
+files and pipes start with input and output eof chars set to Crlt-Z (ascii
+26), and sockets start with no input or output eof char. (JL)
+*** INCOMPATIBILITY with Tcl 7.5b3, but not with Tcl 7.4 ***
+
+4/17/96 (bug fix) Fixed series of bugs with handling of crlf sequence split
+across buffer boundaries in input, in AUTO mode. (JL, BW)
+
+4/17/96 (test suite improvement) Fixed test suite so that tests that
+depend on the availability of Unix commands such as echo, cat and others
+are not run if these commands are not present. (JL)
+
+4/17/96 (test suite improvement) The socket test now automatically starts,
+on platformst that support exec, a separate process for remote testsing. (JL)
+
+----------------- Released 7.5, 4/21/96 -----------------------
+
+5/1/96 (bug fix) "file tail ~" did not correctly return the tail
+portion of the user's home directory. (SS)
+
+5/1/96 (bug fix) Fixed bug in TclGetEnv where it didn't lookup environment
+variables correctly:  could confuse "H" and "HOME", for example.  (JO)
+
+5/1/96 (bug fix) Changed to install tclConfig.sh under "make install-binaries",
+not "make install-libraries".  (JO)
+
+5/2/96 (bug fix) Changed pkg_mkIndex not to attempt to "load" a file unless
+it has the standard shared library extension.  On SunOS, attempts to load
+Tcl scripts cause the whole application to be aborted (there's no way to
+get the error back into Tcl).  (JO)
+
+5/7/96 (bug fix) Moved initScript in tclUnixInit.c to writable memory to
+avoid potential core dumps. (JO)
+
+5/7/96 (bug fix) Auto_reset procedure was removing procedure from init.tcl,
+such as pkg_mkIndex.  (JO)
+
+5/7/96 (bug fix) Fixed cast on socket address resolution code that
+would cause a failure to connect on Dec Alphas. (JL)
+
+5/7/96 (bug fix) Added "time", "subst" and "fileevent" commands to set of
+commands available in a safe interpreter. (JL)
+
+5/13/96 (bug fix) Preventing OS level handles for stdin, stdout and stderr
+from being implicitly closed when the last reference to the standard
+channel containing that handle is discarded when an interpreter is deleted.
+Explicitly closing standard channels by using "close" still works. (JL)
+
+5/21/96 (bug fix) Do not create channels for stdin, stdout and stderr on
+Unix if the devices are closed. This prevents a duplicate channel name
+panic later on when the fd is used to open a channel and the channel is
+registered in an interpreter. (JL)
+
+5/23/96 (bug fix) Fixed bug that prevented the use of standard channels in
+interpreters created after the last interpreter was destroyed. In the sequence
+
+	interp = Tcl_CreateInterp();
+	Tcl_DeleteInterp(interp);
+	interp = Tcl_CreateInterp();
+
+channels for stdio would not be available in the second interpreter. (JL)
+
+5/23/96 (bug fix) Fixed bug that allowed Tcl_MakeFileChannel to create new
+channels with Tcl_Files in them that are already used by another channel.
+This would cause core dumps when the Tcl_Files were being freed twice. (JL)
+
+5/23/96 (bug fix) Fixed a logical timing bug that caused a standard channel
+to be removed from the standard channel table too early when the channel
+was being closed. If the channel was being flushed asynchronously, it could
+get recreated before being actually destroyed, and the recreated channel
+would contain the same Tcl_File as the one being closed, leading to
+dangling pointers and core dumps. (JL)
+
+5/27/96 (bug fix) Fixed a bug in Tcl_GetChannelOption which caused it to
+always return a list of one element, a list of the settings, for
+-translation and -eofchar options. Now correctly returns the value
+described by the documentation (Mark Diekhans found this, thanks!). (JL)
+
+5/30/96 (bug fix) Fixed a couple of syntax errors in io.test. (JL)
+
+5/30/96 (bug fix) If a fileevent scripts gets an error, delete it before
+causing a background error. This is to allow the error handler to reinstall
+the fileevent and to prevent infinite loops if the event loop is reentered
+in the error handler. (JL)
+
+5/31/96 (bug fix) Channels now will get properly flushed on exit. (JL)
+
+6/5/96 (bug fix) Changed Tcl_Ckalloc, Tcl_Ckfree, and Tcl_Ckrealloc to
+Tcl_Alloc, Tcl_Free, and Tcl_Realloc.  Added documentation for these
+routines now that they are officially supported.  Extension writers
+should use these routines instead of free() and malloc(). (SS)
+
+6/10/96 (bug fix) Changes the Tcl close command so that it no longer
+waits on nonblocking pipes for the piped processes to exit; instead it
+reaps them in the background. (JL)
+
+6/11/96 (bug fix) Increased the length of the listen queue for server
+sockets on Unix from 5 to 100. Some OSes will disregard this and reset it
+to 5, but we should try to get as long a queue as we can, for performance
+reasons. (JL)
+
+6/11/96 (bug fix) Fixed windows sockets bug that caused a cascade of events
+if the fileevent script read less than was available. Now reading less than
+is available does not cause a flood of Tcl events. (JL, SS)
+
+6/11/96 (bug fix) Fixed bug in background flushing on closed channels that
+would prevent the last buffer from getting flushed. (JL)
+
+6/13/96 (bug fix) Fixed bug in Windows sockets that caused a core dump if
+a DLL linked with tcl.dll and referred to e.g. ntohs() without opening a
+Tcl socket. The problem was that the indirection table was not being
+initialized. (JL)
+
+6/13/96 (bug fix) Fixed OS level resource leak that would occur when a
+Tcl channel was still registered in some interpreter when the process
+exits. Previously the channel was not being closed and the OS level handles
+were not being released; the output was being flushed but the device was
+not being closed. Now the device is properly closed. This was only a
+problem on Win3.1 and MacOS. (JL, SS)
+
+6/28/96 (bug fix) Fixed bug where transient errors were leaving an error
+code around, so that it would erroneously get reported later. This bug was
+exercised intermittently by closing a channel to a file on a very loaded
+NFS server, or to a socket whose other end blocked. (JL, BW)
+
+7/3/96 (bug fix) Fileevents declared in an interpreter are now deleted
+when the channel is closed in that interpreter. Before this fix, the
+fileevent would hang around until the channel is completely closed, and
+would cause errors if events happened before the channel was closed. This
+could happen in two cases: first if the channel is shared between several
+interpreters, and second if an async flush is in progress that prevents the
+channel from being closed until the flush finishes. (JL)
+
+7/10/96 (bug fix) Fixed bugs in both "lrange" and "lreplace" commands
+where too much white space was being removed. For example, the command
+		lreplace {\}\     hello} end end
+was returning "\}\", losing the significant space in the first list
+element and corrupting the list. (JO)
+
+7/20/96 (bug fix) The procedure pkg_mkIndex didn't work properly for
+extensions that depend on Tk, because it didn't load Tk into the child
+interpreter before loading the extension.  Now it loads Tk if Tk is
+present in the parent. (JO)
+
+7/23/96 (bug fix) Added compat version of strftime to fix crashes
+resulting from bad implementations under Windows. (SS)
+
+7/23/96 (bug fix) Standard implementations of gmtime() and localtime()
+under Windows did not handle dates before 1970, so they were replaced
+with a revised implementation. (SS)
+
+7/23/96 (bug fix) Tcl would crash on exit under Borland 5.0 because
+the global environ pointer was left pointing to freed memory. (SS)
+
+7/29/96 (bug fix) Fixed memory leak in Tcl_LoadCmd that could occur if
+a package's AppInit procedure called Tcl_StaticPackage to register
+static packages. (JO)
+
+8/1/96 (bug fix) Fixed a series of bugs in Windows sockets so that async
+writebehind in the presence of read event handlers now works, and so that
+async writebehind also works on sockets for which a read event handler was
+declared and whose channels were then closed before the async write
+finished. The bug was reported by John Loverso and Steven Wahl,
+independently, test case supplied by John Loverso. (JL)
+
+----------------- Released patch 7.5p1, 8/2/96 -----------------------
+
+5/8/96 (new feature) Added Tcl_GetChannelMode C API for retrieving whether
+a channel is open for reading and writing. (JL)
+
+5/8/96 (API changes) Revised C APIs for channel drivers:
+    - Removed all Tcl_Files from channel driver interface; you can now have
+      channels that are not based on Tcl_Files.
+    - Added channelReadyProc and watchChannelProc procedures to interface;
+      these are used to implement event notification for channels.
+    - Added getFileProc to channel driver, to allow the generic IO code
+      to retrieve a Tcl_File from a channel (presumably if the channel
+      uses Tcl_Files they will be stored inside its instanceData). (JL)
+*** INCOMPATIBILITY with Tcl 7.5 ***
+
+5/8/96 (API change) The Tcl_CreateChannel C API was modified to not take
+Tcl_File arguments, and instead to take a mask specifying whether the
+channel is readable and/or writable. (JL)
+*** INCOMPATIBILITY with Tcl 7.5 ***
+
+6/3/96 (bug fix) Made Tcl_SetVar2 robust against the case where the value
+of the variable is a NULL pointer instead of "". (JL)
+
+6/17/96 (bug fix) Fixed "reading uninitialized memory" error reported by
+Purify, in Tcl_Preserve/Tcl_Release. (JL)
+
+8/9/96 (bug fix) Fixed bug in init.tcl that caused incorrect error message
+if the act of autoloading a procedure caused the procedure to be invoked
+again. (JO)
+
+8/9/96 (bug fix) Configure script produced bad library names and extensions
+under SunOS and a few other platforms if the --disable-load switch was used.
+(JO)
+
+8/9/96 (bug fix) Tcl_UpdateLinkedVar generated an error if the variable
+being updated was read-only. (JO)
+
+8/14/96 (bug fix) The macintosh now supports synchronous socket
+connections.  Other minor bugs were also fixed. (RJ)
+
+8/15/96 (configuration improvement) Changed the file patchlevel.h
+to be tclPatch.h.  This avoids conflict with the Tk file and is now
+in 8.3 format on the Windows platform. (RJ)
+
+8/20/96 (bug fix) Fixed core dump in interp alias command for interpreters
+created with Tcl_CreateInterp (as opposed to with Tcl_CreateSlave). (JL)
+
+8/20/96 (bug fix) No longer masking ECONNRESET on Windows sockets so
+that the higher level of the IO mechanism sees the error instead of
+entering an infinite loop. (JL)
+
+8/20/96 (bug fix) Destroying the last interpreter no longer closes the
+standard channels. (JL)
+
+8/20/96 (bug fix) Closing one of the stdin, stdout or stderr channels and
+then opening a new channel now correctly assigns the new channel as the
+standard channel that was closed. (JL)
+
+8/20/96 (bug fix) Added code to unix/tclUnixChan.c for using ioctl with
+FIONBIO instead of fcntl with O_NONBLOCK, for those versions of Unix where
+either O_NONBLOCK is not supported or implemented incorrectly. (JL)
+
+8/21/96 (bug fix) Fixed "file extension" so it correctly returns the
+extension on files like "foo..c" as "..c" instead of ".c". (SS)
+
+8/22/96 (bug fix) If environ[] contains static strings, Tcl would core
+dump in TclSetupEnv because it was trying to write NULLs into the actual
+data in environ[]. Now we instead copy as appropriate. (JL)
+
+8/22/96 (added impl) Added missing implementation of Tcl_MakeTcpClientChannel
+for Windows platform. Code contributed by Mark Diekhans. (JL)
+
+8/22/96 (new feature) Added a new memory allocator for the Macintosh
+version of Tcl.  It's quite a bit faster than MetroWerk's version. (RJ)
+
+8/26/96 (documentation update) Removed old change bars (for all changes
+in Tcl 7.5 and earlier releases) from manual entries. (JO)
+
+8/27/96 (enhancement) The exec and open commands behave better and work in
+more situations under Windows NT and Windows 95.  Documentation describes
+what is still lacking. (CS)
+
+8/27/96 (enhancement) The Windows makefiles will now compile even if the
+compiler is not in the path and/or the compiler's environment variables
+have not been set up. (CS)
+
+8/27/96 (configuration improvement) The Windows resource files are
+automatically updated when the version/patch level changes.  The header file
+now has a comment that reminds the user which other files must be manually
+updated when the version/patch level changes. (CS)
+
+8/28/96 (new feature) Added file manipulation features (copy, rename, delete,
+mkdir) that are supported on all platforms. They are implemented as
+subcommands to the "file" command. See the documentation for the "file"
+command for more information. (JH)
+
+----------------- Released 7.6b1, 8/30/96 -----------------------
+
+9/3/96 (bug fix) Simplified code so that standard channels are created
+lazily, they are added to an interpreter lazily, and they are never added
+to a safe interpreter. (JL)
+
+9/3/96 (bug fix) Closing a channel after closing a standard channel, e.g.
+stdout, would cause the implicit recreation of that standard channel. (JL)
+
+9/3/96 (new feature) Now calling Tcl_RegisterChannel with a NULL
+interpreter increments the refcount so that code outside any interpreter
+can use channels that are also registered in interpreters, without worrying
+that the channel may turn into a dangling pointer at any time. Calling
+Tcl_UnregisterChannel with a NULL interpreter only decrements the recount
+so that code outside any interpreter can safely declare it is no longer
+interested in a channel. (JL)
+
+9/4/96 (new features) Two changes to dynamic loading:
+    - If the file name is empty in the "load" command and there is no
+      statically loaded version of the package, a dynamically loaded
+      version will be used if there is one.
+    - Tcl_StaticPackage ignores redundant calls for the same package. (JO)
+
+9/6/96 (bug fix) Platform specific procedures for manipulating files are
+no longer macros and have been prefixed with "Tclp", such as TclpRenameFile.
+Unix file code now handles symbolic links and other special files correctly.
+The semantics of file copy and file rename has been changed so that if
+a target directory exists, the source files will NOT be merged with the
+existing files. (JH)
+
+9/6/96 (bug fix) If standard channel is NULL, because Tcl cannot connect
+to the standard channel, do not increment the refcount. The channel can
+be NULL if there is for example no standard input. (JL)
+
+9/6/96 (portability improvement) Changed parsing of backslash sequences
+like \n to translate directly to absolute values like 0xa instead of
+letting the compiler do the translation.  This guarantees that the
+translation is done the same everywhere. (JO)
+
+9/9/96 (bug fix) If channel is opened and not associated with any
+interpreter, but Tcl decides to use it as one of the standard channels, it
+became impossible to close the channel with Tcl_Close -- instead you had
+to call Tcl_UnregisterChannel. Fixed now so that it's safe to call
+Tcl_Close even when Tcl is using the channel as one of the standard ones. (JL)
+
+9/11/96 (feature change) The Tcl library is now placed in the Tcl
+shared libraries resource.  You no longer need to place the Tcl files
+in your applications explicitly.  (RJ)
+
+9/11/96 (feature change) Extensions no longer automatically have the
+resource fork of the extension opened for it.  Instead you need to
+use the tclMacLibrary.c file in your extension.  (RJ)
+*** POTENTIAL INCOMPATIBILITY ***
+
+9/12/96 (bug fix) The extension loading mechanism on the Macintosh now
+looks at the 'cfrg' resource to determine where to load the code
+fragment from.  This means FAT fragments should now work. (RJ)
+
+9/18/96 (enhancement) The exec and open commands behave better and work in
+more situations under Windows 3.X.  Documentation describes what is still
+lacking.  (CS)
+
+9/19/96 (bug fix) Fixed a panic which would occur if you delete a
+non-existent alias before any aliases are created. Now instead correctly
+returns an error that the alias is not found. (JL)
+
+9/19/96 (bug fix) Slave interpreters could rename aliases and they would
+not get deleted when the alias was being redefined. This led to dangling
+pointers etc. (JL)
+
+9/19/96 (bug fix) Fixed a panic where a hash table entry was being deleted
+twice during alias management operations. (JL)
+
+9/19/96 (bug fix) Fixed bug in event loop that could cause the input focus
+in Tk to get confused during menu traversal, among other problems.  The
+problem was related to handling of the "marker" when its event was
+deleted. (JO)
+
+9/26/96 (bug fix) Windows was losing EOF on a socket if the FD_CLOSE event
+happened to precede any left over FD_READ events. Now correctly remembers
+seeing FD_CLOSE, so that trailing FD_READ events are not discarded if they
+do not contain any data. This allows Tcl to correctly get a zero read and
+notice EOF. (JL)
+
+9/26/96 (bug fix) Was not resetting READABLE state properly on sockets
+under Windows if the driver discarded an FD_READ event because no data was
+present. Now correctly resets the state. (JL)
+
+9/30/96 (bug fix) Made EOF sticky on Windows sockets, so that fileevent
+readable will fire repeatedly until the socket is closed. Previously the
+fileevent fired only once. This could lead to never-closed connections if
+the Tcl script in the fileevent wasn't closing the socket immediately. (JL)
+
+10/2/96 (new feature) Improved the package loader:
+    - Added new variable tcl_pkgPath, which holds the default
+      directories under which packages are normally installed (each
+      package goes in a separate subdirectory of a directory in
+      $tcl_pkgPath).  These directories are included in auto_path by
+      default.
+    - Changed the package auto-loader to look for pkgIndex.tcl files
+      not only in the auto_path directories but also in their immediate
+      children.  This should make it easier to install and uninstall
+      packages (don't have to change auto_path or merge pkgIndex.tcl
+      files). (JO)
+
+10/3/96 (bug fix) Changed tclsh to look for tclshrc.tcl instead of
+tclsh.rc on startup under Windows.  This is more consistent with wish and
+uses the right extension. (SS)
+*** POTENTIAL INCOMPATIBILITY ***
+
+10/8/96 (bug fix) Convertclock does not parse 24-hour times of the
+form "hhmm" correctly when hour = 00.  In the parse code, hour must be
+>= 100 for minutes to be non-zero.  Thanks to Lint LaCour for this
+bug fix. (RJ)
+
+10/11/96 (bug fix) Under Windows, the pid command returned the process
+handle instead of the process id. (SS)
+
+----------------- Released 7.6, 10/16/96 -----------------------
+
+10/29/96 (bug fix) Under Windows, sockets would consume 100% CPU time after
+the first accept(), due to a typo. (JL)
+
+10/29/96 (bug fix) Incorrect refcount management caused standard channels
+not to get deleted at process exit or DLL unload time, causing a memory
+leak of upwards of 20K each time. (JL)
+
+11/7/96 (bug fix) Auto-exec didn't work on file names that contained
+spaces. (JO)
+
+11/8/96 (bug fix) Fixed core dump that would occur if more than one call
+to Tcl_DeleteChannelHandler was made to delete a given channel handler. (JL)
+
+11/8/96 (bug fix) Fixed test for return value in Tcl_Seek and Tcl_SeekCmd
+to only treat -1 as error, instead of all negative numbers. (JL)
+
+11/12/96 (bug fix) Do not blocking waiting for processes at the end of a
+pipe during exit cleanup. (JL)
+
+11/12/96 (bug fix) If we are in exit cleanup, do not close the system level
+file descriptors 0, 1 and 2. Previously they were being closed which is
+incorrect, in the embedded case. This led to weird behavior for programs
+that want to interpose on I/O through the standard file descriptors (e.g.
+Netscape Navigator). (JL)
+
+11/15/96 (bug fix) Fixed core dump on Windows sockets due to dependency on
+deletion order at exit. Now all socket functions check to see if sockets
+are (still) initialized, before calling through function pointers. Before,
+they would call and might end up calling unloaded object code. (JL)
+
+11/15/96 (bug fix) Fixed core dump in Windows socket initialization routine
+if sockets were not installed on the system. Before, it was not properly
+checking the result of attempting to load the socket DLL, so it would call
+through uninitialized function pointers. (JL)
+
+11/15/96 (bug fix) Fixed memory leak in Windows sockets which left socket
+DLL handle open and could hold the socket DLL in memory uneccessarily,
+until a reboot. (JL)
+
+12/4/96 (bug fix) Fixed bug in Macintosh socket code that could result
+in lost data if a client was closed too soon after sending data. (RJ)
+
+12/17/96 (bug fix) Fixed deadlock bug in Windows sockets due to losing an
+event. This was happening because of an interaction between buffering and
+nonblocking mode on sockets. Now switched to sockets being blocking by
+default, so we are also no longer emulating blocking through a private
+event loop. (JL)
+
+1/21/97 (performance bug fix) Client TCP connections were slow to create
+because getservbyname was always called on the port.  Now this is only
+done if Tcl_GetInt fails. (BW)
+
+1/21/97 (configuration fix) Made it possible to override TCL_PACKAGE_PATH
+during make.  Previously it was only set during autoconf process.
+
+1/29/97 (bug fix) Fixed some problems with the clock command that
+impacted how dates were scaned after the year 2000. (RJ)
+
+----------------- Released 7.6p2, 1/31/97 -----------------------
+
+2/5/97 (bug fix) Fixed a bug where in CR-LF translation mode, \r bytes
+in the input stream were not being handled correctly. (JL)
+
+2/24/97 (bug fix) Fix bug with exec under Win32s not being able to create
+stderr file which caused all execs to fail.  Fixed temp file leak under
+Win32s.  Fixed optional parameter bug with SearchPath that only happened
+under Win32s 1.25. (CCS)
+
+----------------------------------------------------------
+Changes for Tcl 7.6 go above this line.
+Changes for Tcl 7.7 go below this line.
+----------------------------------------------------------
+
+5/8/96 (new feature) Added Tcl_Ungets C API for putting a sequence of bytes
+into a channel's input buffer. This can be used for "push" model channels
+where the input is obtained via callbacks instead of by request of the
+generic IO code. No Tcl procedure yet. (JL)
+
+11/15/96 (new feature) Implemented hidden commands. New C APIs:
+	Tcl_HideCommand		-- hides an existing exposed command.
+	Tcl_ExposeCommand	-- exposes an existing hidden command.
+New tcl APIs:
+	interp invokehidden	-- invokes a hidden command in a slave.
+	interp hide		-- hides an existing exposed command.
+	interp expose		-- exposes an existing hidden command.
+	interp hidden		-- returns a list of hidden commands.
+The implementation of Safe Tcl now uses the new hidden commands facility
+to implement the safe base, instead of deleting the commands from a safe
+interpreter. (JL)
+
+11/15/96 (new feature) Implemented the safe base, a mechanism for
+installing and requesting security policies, purely in Tcl code. Overloads
+the package command to also allow an interpreter to "require" a policy. The
+following new library commands are provided:
+	tcl_safeCreateInterp	-- creates a slave an initializes the
+				   policy mechanism.
+	tcl_safeInitInterp	-- initializes an existing slave with the
+				   policy mechanism.
+	tcl_safeDeleteInterp	-- deletes a slave and deinitializes the
+				   policy mechanism.
+Added a new file to the library, safeinit.tcl, to hold implementation. (JL)
+On 7/9/97, removed the policy loading mechanism from the Safe Base. Left
+only the Safe Base aliases dealing with auto-loading and source. (JL)
+
+12/6/96 (new feature) Implemented Tcl_Finalize, an API that should be
+called by a process when it is done using Tcl. This API runs all the exit
+handlers to allow them to clean up resources etc. (JL)
+
+12/17/96 (new feature) Add an http Tcl script package to the Tcl library.
+This package implements the client side of HTTP/1.0; the GET, HEAD,
+and POST requests. (BW)
+
+1/21/97 (new feature) Added a "marktrusted" subcommand to the "interp" and
+to the interpreter object command. It removes the "safe" mark on an
+interpreter and disables hard-wired checks for safety in the C sources. (JL)
+
+1/21/97 (removed feature) Removed "vwait" from set of commands available in
+a safe interpreter. (JL)
+
+2/11/97 (new feature, bug fix) http package.  Added -accept to http_config
+so you can set the Accept header.  Added -handler option to http_get so
+you can supply your own data handler.  Also fixed POST operation to
+set the correct MIME type on the request. (BW)
+
+----------------------------------------------------------
+Changes for Tcl 7.7 go above this line.
+Changes for Tcl 8.0 go below this line.
+----------------------------------------------------------
+
+9/17/96 (bug fix) Using "upvar" it was possible to turn an array element
+into an array itself.  Changed to disallow this; it was quirky and didn't
+really work correctly anyway. (JO)
+
+10/21/96 (new feature) The core of the Tcl interpreter has been replaced
+with an on-the-fly compiler that translates Tcl scripts to bytecoded
+instructions; a new interpreter then executes the bytecodes. The compiler
+introduces only a few minor changes at the level of Tcl scripts. The biggest
+changes are to expressions and lists.
+    - A second level of substitutions is no longer done for expressions.
+      This substantially improves their execution time. This means that
+      the expression "$x*4" produces a different result than in the past
+      if x is "$y+2". Fortunately, not much code depends on the old
+      two-level semantics. Some expressions that do, such as
+      "expr [join $list +]" can be recoded to work in Tcl8.0 by adding
+      an eval: e.g., "eval expr [join $list +]".
+    - Lists are now completely parsed on the first list operation to
+      create a faster internal representation. In the past, if you had a
+      misformed list but the erroneous part was after the point you
+      inserted or extracted an element, then you never saw an error.
+      In Tcl8.0 an error will be reported. This should only effect
+      incorrect programs that took advantage of behavior of the old
+      implementation that was not documented in the man pages.
+Other changes to Tcl scripts are discussed in the web page at
+http://www.scriptics.com/doc/compiler.html. (BL)
+*** POTENTIAL INCOMPATIBILITY ***
+
+10/21/96 (new feature) In earlier versions of Tcl, strings were used as a
+universal representation; in Tcl 8.0 strings are replaced with Tcl_Obj
+structures ("objects") that can hold both a string value and an internal
+form such as a binary integer or compiled bytecodes. The new objects make it
+possible to store information in efficient internal forms and avoid the
+constant translations to and from strings that occurred with the old
+interpreter. There are new many new C APIs for managing objects. Some of the
+new library procedures for objects (such as Tcl_EvalObj) resemble existing
+string-based procedures (such as Tcl_Eval) but take advantage of the
+internal form stored in Tcl objects for greater speed. Other new procedures
+manage objects and allow extension writers to define new kinds of objects.
+See the manual entries doc/*Obj*.3 (BL)
+
+10/24/96 (bug fix) Fixed memory leak on exit caused by some IO related
+data structures not being deallocated on exit because their refcount was
+artificially boosted. (JL)
+
+10/24/96 (bug fix) Fixed core dump in Tcl_Close if called with NULL
+Tcl_Channel. (JL)
+
+11/19/96 (new feature) Added library procedures for finding word
+breaks in strings in a platform specific manner.  See the library.n
+manual entry for more information. (SS)
+
+11/22/96 (feature improvements) Added support for different levels of
+tracing during bytecode compilation and execution. This should help in
+tracking down suspected problems with the compiler or with converting
+existing code to use Tcl8.0. Two global Tcl variables, traceCompile
+and traceExec, can be set to generate tracing information in stdout:
+    - traceCompile: 0  no tracing (default)
+                    1  trace compilations of top level commands and procs
+                    2  trace and display instructions for all compilations
+    - traceExec:    0  no tracing
+                    1  trace only calls to Tcl procs
+                    2  trace invocations of all commands including procs
+                    3  detailed trace showing the result of each instruction
+traceExec >= 2 provides a one line summary of each called command and
+its arguments. Commands that have been "compiled away" such as set are
+not shown. (BL)
+
+11/30/96 (bug fix) The command "info nameofexecutable" could sometimes
+return the name of a directory. (JO)
+
+11/30/96 (feature improvements) Changed the code in library/init.tcl
+that reads in pkgIndex.tcl so that (a) it reads the files from child
+directories before those in the parent, so that the parent gets
+precedence, and (b) it doesn't quit if there is an error in a
+pkgIndex.tcl file;  instead, it prints an error message on standard
+error and continues. (JO)
+
+10/5/96 (feature improvements) Partial implementation of binary string
+support: the ability for Tcl string values to contain embedded null bytes.
+Changed the Tcl object-based APIs to take a byte pointer and length pair
+instead of a null-terminated C string. Modified several object type managers
+to support binary strings but not, for example, the list type manager.
+Existing string-based C APIs are unchanged and will truncate binary
+strings. Compiled scripts containing nulls are also truncated. (BL)
+
+12/12/96 (feature change) Removed the commands "cp", "mkdir", "mv",
+"rm", and "rmdir" from the Macintosh version of Tcl.  They were never
+officially supported and their functionality is now available via
+the file command. (RJ)
+
+----------------- Released 8.0a1, 12/20/96 -----------------------
+
+1/7/97 (bug fix) Under Windows, "file stat c:" was returning error instead
+of stat for current dir on c: drive.
+
+1/10/97 (new feature) Added Tcl_GetIndexFromObj procedure for quick
+lookups of keyword arguments. (JO)
+
+1/12/97 (new feature) Serial IO channel drivers for Windows and Unix,
+available by using Tcl open command to open pseudo-files like "com1:" or
+"/dev/ttya".  New option to Tcl fconfigure command for serial files:
+"-mode baud,parity,data,stop" to specify baud rate, parity, data bits, and
+stop bits.  Serial IO is not yet available on Mac.
+
+1/16/97 (feature change) Restored the Tcl7.x "two level substitution
+semantics" for expressions. Expressions not enclosed in braces are
+implemented, in general, by calling the expr command procedure
+(Tcl_ExprObjCmd) at runtime after the Tcl interpreter has already done a
+first round of substitutions. This is slow (about Tcl7.x speed) because new
+code for the expression is generally compiled each time. However, if the
+expression has only variable substitutions (and not command substitutions),
+"optimistic" fast code is generated inline. This inline code will fail if a
+second round of substitutions is needed (i.e., if the value of a substituted
+variable itself requires more substitutions). The optimistic code will
+catch the error and back off to call the slower but guaranteed correct
+expr command procedure. (BL)
+
+1/16/97 (feature improvements) Added Tcl_ExprLongObj and Tcl_ExprDoubleObj
+to round out expression-related procedures. (BL)
+
+1/16/97 (feature change) Under Windows, at startup the environment variables
+"path", "comspec", and "windir" in any capitalization are converted
+automatically to upper case.  The PATH variable could be spelled as path,
+Path, PaTh, etc. and it makes programming rather annoying.  All other
+environment variables are left alone. (CS)
+
+1/20/97 (new features) Rewrote the "lsort" command:
+    - The new version is based on reentrant merge sort code provided
+      by Richard Hipp, so it eliminates the reentrancy and stability
+      problems with the old qsort-based implementation.
+    - The new version supports a -dictionary option for sorting, and
+      it also supports a -index option for sorting lists using one
+      element for comparison.
+    - The new version is an object command, so it works well with the
+      Tcl compiler, especially in conjunction with the new -index
+      option.  When the -index option is used, this version of lsort
+      is more than 100 times faster than the Tcl 7.6 lsort, which had
+      to use the -command option to get the same effect. (JO)
+
+1/20/97 (feature improvements) Added the improved debugging support for Tcl
+objects prototyped by Karl Lehenbauer <karl@hammer1.ops.NeoSoft.com>.
+If TCL_MEM_DEBUG is defined, the object creation calls use Tcl_DbCkalloc
+directly in order to record the caller's source file name and line
+number. (BL)
+
+1/21/97 (removed feature) Desupported the tcl_precision variable: if
+set, it is ignored.  Tcl now uses the full 17 digits of precision when
+converting real numbers to strings (with the new object system real
+numbers are rarely converted to strings so there is no efficiency
+disadvantage to printing all 17 digits; the new scheme improves
+accuracy and simplifies several APIs). (JO)
+*** POTENTIAL INCOMPATIBILITY ***
+
+1/21/97 (feature change) Removed the "interp" argument for the
+procedures Tcl_GetStringFromObj, Tcl_StringObjAppend, and
+Tcl_StringObjAppendObj.  Also removed the "interp" argument for
+the updateStringProc procedure in Tcl_ObjType structures.  With
+the tcl_precision changes above, these are no longer needed. (JO)
+*** POTENTIAL INCOMPATIBILITY with Tcl 8.0a1, but not with Tcl 7.6 ***
+
+1/22/97 (bug fix) Fixed http.tcl so that http_reset does not result in
+an extra call to the command callback.  In addition, if the transaction
+gets a premature eof, the state(status) is "eof", not "ok". (BW)
+
+----------------- Released 8.0a2, 1/24/97 -----------------------
+
+1/29/97 (feature change) Changed how two digit years are parsed in the
+clock command.  The old interface just added 1900 which will seem
+broken by the year 2000.  The new scheme follows the POSIX standard
+and treats dates 70-99 as 1970-1999 and dates 00-38 as 2000-2038.  All
+other two digit dates are undefined. (RJ)
+*** POTENTIAL INCOMPATIBILITY ***
+
+2/4/97 (bug fix) Fixed bug in clock code that dealt with relative
+dates.  Using the relative month code you could get an invalid date
+because it jumped into a non-existant day.  (For example, Jan 31
+to Feb 31.)  The code now will return the last valid day of the
+month in these situations.  Thanks to Hume Smith for sending in
+this bug fix.  (RJ)
+
+2/10/97 (feature change) Eliminated Tcl_StringObjAppend and
+Tcl_StringObjAppendObj procedures, replaced them with Tcl_AppendToObj
+and Tcl_AppendStringsToObj procedures.  Added new procedure
+Tcl_SetObjLength. (JO)
+*** POTENTIAL INCOMPATIBILITY with Tcl 8.0a2, but not with Tcl 7.6 ***
+
+2/10/97 (new feature) Added Tcl_WrongNumArgs procedure for generating
+error messages about incorrect number of arguments. (JO)
+
+2/11/97 (new feature, bug fix) http package.  Added -accept to http_config
+so you can set the Accept header.  Added -handler option to http_get so
+you can supply your own data handler.  Also fixed POST operation to
+set the correct MIME type on the request. (BW)
+
+2/22/97 (bug fix) Fixed bug that caused $tcl_platform(osVersion) to be
+computed incorrectly under AIX. (JO)
+
+2/25/97 (new feature, feature change) Added support for both int and long
+integer objects. Added Tcl_NewLongObj/Tcl_GetLongFromObj/Tcl_SetLongFromObj
+procedures and renamed the Tcl_Obj internalRep intValue member to
+longValue. Tcl_GetIntFromObj now checks for integer values too large to
+represent as non-long integers. Changed Tcl_GetAllObjTypes to
+Tcl_AppendAllObjTypes. (BL)
+
+3/5/97 (new feature) Added new Tcl_SetListObj procedure to round out
+collection of procedures that set the type and value of existing Tcl
+objects. (BL)
+
+3/6/97 (new feature) Added -global flag for interp invokehidden. (JL)
+
+3/6/97 (new feature, feature change) Added isNativeObjectProc field to the
+Tcl_CmdInfo structure to indicate (when 1) if the command has an
+object-based command procedure. Removed the nameLength arg from
+Tcl_CreateObjCommand since command names can't contain null characters. (BL)
+
+3/6/97 (bug fix) Fixed bug in "unknown" procedure that caused auto-
+loading to fail on commands whose names begin with digits. (JO)
+
+3/7/97 (bug fix) Auto-loading now works in Safe Base. Safe interpreters
+only accept the Version 2 and onwards tclIndex files. (JL)
+
+3/13/97 (bug fix) Fixed core dump due to interaction between aliases and
+hidden commands. Bug found by Lindsay Marshall. (JL)
+
+3/14/97 (bug fix) Fixed mac bugs relating to time.  The -gmt option
+now adjusts the time in the correct direction.  (Thanks to Ed Hume for
+reporting a fix to this problem.)  Also fixed file "mtime" etc. to
+return times from GMT rather than local time zone.  (RJ)
+
+3/18/97 (feature change) Declaration of objv in Tcl_ObjCmdProc function
+changed from "Tcl_Obj *objv[]" to "Tcl_Obj *CONST objv[]".  All Tcl object
+commands changed to use new declaration of objv.  Naive translation of
+string-based command procs to object-based command procs could very easily
+have yielded code where the contents of the objv array were changed.  This
+is not a problem with string-based command procs, but doing something as
+simple as objv[2] = objv[3] would corrupt the runtime stack and cause Tcl to
+crash.  Introduced CONST in declaration of objv so that attempted assignment
+of new pointer values to elements of the objv array will be caught by the
+compiler. (CCS)
+*** POTENTIAL INCOMPATIBILITY with Tcl 8.0a2 ***
+
+3/19/97 (bug fix) Fixed panic due to object sharing. The root cause was
+that old code was using Tcl_ResetResult instead of Tcl_ResetObjResult. (JL)
+
+3/20/97 (new feature) Added a new subcommand for the file
+command. file attributes filename can give a list of platform-specific
+options (such as file/creator type on the Mac, permissions on Unix) or
+set the values of them. Added a new subcommand for the file
+command. file nativename name gives back the platform-specific form
+for the file. This is useful when the filename is needed to pass to
+the OS, such as exec under Windows 95 or AppleScript on the Mac. For
+more info, see file.n. (SRP)
+
+3/24/97 (removed feature) Removed the tcl_safePolicyPath procedure. Now
+the policy path is computed from the auto_path by appending the directory
+'policies' to each element. Also fixed several bugs in automatic tracking
+of auto_path by computed policy path. (JL)
+*** POTENTIAL INCOMPATIBILITY with Tcl 8.0a2 but not with Tcl 7.6 ***
+
+4/8/97 (new feature) If the variable whose name is passed to lappend doesn't
+already exist, and there are no value arguments, lappend now creates the
+variable with an empty value instead of returning an error. Change suggested
+by Tom Tromey. (BL)
+
+4/9/97 (feature change) Changed the name of the TCL_PART1_NOT_PARSED flag to
+TCL_PARSE_PART1. (BL)
+*** POTENTIAL INCOMPATIBILITY with Tcl 8.0a2 but not with Tcl 7.6 ***
+
+4/10/97 (bug fixes) Fixed various compilation-related bugs:
+    - "UpdateStringOfCmdName should never be invoked" panic.
+    - Bad code generated for expressions not in {}'s inside catch commands.
+    - Segmentation fault in some command procedures when two argument
+      object pointers refer to the same object.
+    - Second level of substitutions were never done for expressions not
+      in {}'s that consist of a single variable reference: e.g.,
+      "set x 27; set bool {$x}; if $bool {puts foo}" would fail with error.
+    - Bad code generated when code storage was grown while compiling some
+      expressions: ones with compilation errors or consisting of only a
+      variable reference.
+    - Bugs involving multiple interpreters: wasn't checking that a
+      procedure's code was compiled for the same interpreter as the one
+      executing it, and didn't invalidate code on hidden-exposed command
+      transitions.
+    - "Bad stack top" panic when executing scripts that require a huge
+      amount of stack space.
+    - Incorrect sharing of code for procedure bodies, and procedure code
+      deallocated before last execution of the procedure finished.
+    - Fixed compilation of expression words in quotes. For example,
+      if "0 < 3" {puts foo}.
+    - Fixed performance bug in array set command with large assignments.
+    - Tcl_SetObjLength segmentation fault setting length of empty object.
+    - If Tcl_SetObjectResult was passed the same object as the interpreter's
+      result object, it freed the object instead of doing nothing. Bug fix
+      by Michael J. McLennan.
+    - Tcl_ListObjAppendList inserted elements from the wrong list. Bug fix
+      by Michael J. McLennan.
+    - Segmentation fault if empty variable list was specified in a foreach
+      command. Bug fix by Jan Nijtmans.
+    - NULL command name was always passed to Tcl_CreateTrace callback
+      procedure.
+    - Wrong string representation generated for the value LONG_MIN.
+      For example, expr 1<<31 printed incorrectly on a 32 bit machine.
+    - "set {a($x)} 1" stored value in wrong variable.
+    - Tcl_GetBooleanFromObj was not checking for garbage after a numeric
+      value.
+    - Garbled "bad operand type" error message when evaluating expressions
+      not surrounded by {}'s. (BL)
+
+4/16/97 (new feature) The expr command now has the "rand()" and
+"srand()" functions for getting random numbers in expr. (RJ)
+
+4/23/97 (bug fix) Fixed core dump in bgerror when the error handler command
+deletes the current interpreter. Found by Juergen Schoenwald. (JL)
+
+4/23/97 (feature change) The notifier interfaces have been redesigned
+to make embedding in applications with external event loops possible.
+A number of interfaces in the notifier and the channel drivers have
+changed.  Refer to the Notifier.3 and CrtChannel.3 manual entries for
+more details. (SS)
+*** POTENTIAL INCOMPATIBILITY ***
+
+4/23/97 (removed feature) The Tcl_File interfaces have been removed.
+The Tcl_CreateFileHandler/Tcl_DeleteFileHandler interfaces now take
+Unix fd's and are only supported on the Unix platform.
+Tcl_GetChannelFile has been replaced with Tcl_GetChannelHandle.
+Tcl_MakeFileChannel now takes a platform specific file handle. (SS)
+*** POTENTIAL INCOMPATIBILITY ***
+
+4/23/97 (removed feature) The modal timeout interface has been
+removed (Tcl_CreateModalTimeout/Tcl_DeleteModalTimeout) (SS)
+*** POTENTIAL INCOMPATIBILITY ***
+
+4/23/97 (feature change) Channel drivers are now required to correctly
+implement blocking behavior when they are in blocking mode. (SS)
+*** POTENTIAL INCOMPATIBILITY ***
+
+4/23/97 (new feature) Added the "binary" command for manipulating
+binary strings. Also, changed the "puts", "gets", and "read" commands
+to preserve embedded nulls.  (SS)
+
+4/23/97 (new feature) Added tcl_platform(byteOrder) element to the
+tcl_platform array to identify the native byte order for the current
+host. (SS)
+
+4/23/97 (bug fix) Fixed bug in date parsing around year boundaries. (SS)
+
+4/24/97 (bug fix) In the process of copying a file owned by another user,
+Tcl was changing the owner of the copy back to the owner of the original
+file, therefore causing further file operations to fail because the current
+user didn't own the copy anymore.  The owner of the copy is now left as the
+current user. (CCS)
+
+4/24/97 (feature change) Under Windows, don't automatically uppercase the
+environment variable "windir" -- it's supposed to be lower case.  (CCS)
+
+4/29/97 (new feature) Added namespace support based on a namespace
+implementation by Michael J. McLennan of Lucent Technologies. A namespace
+encapsulates a collection of commands and variables to ensure that they
+won't interfere the commands and variables of other namespaces. The global
+namespace holds all global variables and commands. Additional namespaces are
+created with the new namespace command. The new variable command lets you
+create Tcl variables inside a namespace. The names of Tcl variables and
+commands may now be qualified by the name of the namespace containing them.
+The key namespace-related commands are summarized below:
+    - namespace ?eval? name arg ?arg...?
+         Used to define the commands and variables in a namespace.
+         Optionally creates the namespace.
+    - namespace export ?-clear? ?pattern pattern...?
+         Specifies which commands are exported from a namespace. These
+         are the ones that can be imported into another namespace.
+    - namespace import ?-force? ?pattern pattern...?
+         Makes the specified commands accessible in the current namespace.
+    - namespace current
+         Returns the name of the current namespace.
+    - variable name ?value? ?name ?value?...?
+         Creates one or more namespace variables. (BTL)
+
+5/1/97 (bug fix) Under Windows, file times were reported in GMT.  Should be
+reported in local time. (CCS)
+
+5/2/97 (feature change) Changed the name of the two Tcl variables used for
+tracing bytecode compilation and execution to tcl_traceCompile and
+tcl_traceExec respectively. These variables are now documented in the
+tclvars man page. (BL)
+
+5/5/97 (new feature) Support "end" as the index for "lsort -index". (BW)
+
+5/5/97 (bug fixes) Cleaned up the way the http package resets connections (BW)
+
+5/8/97 (feature change) Newly created Tcl objects now have a reference count
+of zero instead of one. This simplifies C code that stores newly created
+objects in Tcl variables or in data structures such as list objects. That C
+code must increment the new object's reference count since the variable or
+data structure will contain a long-term reference to the object. Formerly,
+when new objects started out with reference count one, it was necessary to
+decrement the new object's reference count after the store to make sure it
+was left with the correct value; this is no longer necessary. (BL)
+
+5/9/97 (new feature) Added the Tcl_GetsObj interface that takes an
+object reference instead of a dynamic string (as in Tcl_Gets). (SS)
+
+5/12/97 (new feature) Added Tcl_CreateAliasObj and Tcl_GetAliasObj C APIs
+to allow an alias command to be created with a vector of Tcl_Obj structures
+and to get the vector back later. (JL)
+
+5/12/97 (feature change) Changed Tcl_ExposeCommand and Tcl_HideCommand to
+leave an object result instead of a string result. (JL)
+
+5/14/97 (feature change) Improved the handling of the interpreter result.
+This is still either an object or a string, but the two values are now kept
+consistent unless some C code reads or writes interp->result directly. See
+the SetResult man page for details. Removed the Tcl_ResetObjResult
+procedure. (BL)
+*** POTENTIAL INCOMPATIBILITY with Tcl 8.0a2 ***
+
+5/16/97 (new feature) Added "fcopy" command to move data between
+channels.  Refer to the manual page for more information.  Removed the
+"unsupported0" command since it is obsolete now.  (SS)
+
+5/16/97 (new feature) Added Tcl_GetStringResult procedure to allow programs
+to get an interpreter's result as a string. If the result was previously set
+to an object, this procedure will convert the object to a string. Use of
+Tcl_GetStringResult is intended to replace direct access to interp->result,
+which is not safe. (BL)
+
+5/20/97 (new features) Fixed "fcopy" to return the number of bytes
+transferred in the blocking case.  Updated the http package to use
+fcopy instead of unsupported0.  Added -timeout and -handler options to
+http_get.  http_get is now blocking by default.  It is only non-blocking
+if you supply a -command argument. (BW)
+
+5/22/97 (bug fix) Fixed several bugs in the "lsort" command having to do
+with the -dictionary option and the presence of numbers embedded in the
+strings.  (JO)
+
+----------------- Released 8.0b1, 5/27/97 -----------------------
+
+6/2/97 (bug fix) Fixed bug in startup code that caused a problem in
+finding the library files when they are installed in a directory
+containing a space in the name. (SS)
+
+6/2/97 (bug fix) Fixed bug in Unix notifier where the select mask was
+not being cleared under some circumstances. (SS)
+
+6/4/97 (bug fix) Fixed bug that prevented creation of Tk widgets in
+namespaces. Tcl_CreateObjCommand and Tcl_CreateCommand now always create
+commands in the global namespace unless the command names are qualified. Tcl
+procedures continue to be created in the current namespace by default. (BL)
+
+6/6/97 (new features) Added new namespace API procedures
+Tcl_AppendExportList and Tcl_Export to allow C code to get and set a
+namespace's export list. (BL)
+
+6/11/97 (new feature) Added Tcl_ConcatObj. This object-based routine
+parallels the string-based routine Tcl_Concat. (SRP)
+
+6/11/97 (new feature) Added Tcl_SetObjErrorCode. This object-based
+routines parallels the string-based routine Tcl_SetErrorCode. (SRP)
+
+6/12/97 (bug fix) Fix the "unknown" procedure so that wish under Windows
+will exec an external program, instead of always complaining "console1 not
+opened for writing". (CCS)
+
+6/12/97 (bug fix) Fixed core dump experienced by the following simple
+script:
+	interp create x
+	x alias exec exec
+	interp delete x
+This panic was caused by not installing the new CmdDeleteProc when exec
+got redefined by the alias creation step. Reported by Lindsay Marshal (JL)
+
+6/13/97 (new features) Tcl objects newly created by Tcl_NewObj now have a
+string representation that points to a shared heap string of length 1. (They
+used to have NULL bytes and typePtr fields. This was treated as a special
+case to indicate an empty string, but made type manager implementations
+complex and error prone.) The new procedure Tcl_InvalidateStringRep is used
+to mark an object's string representation invalid and to free any storage
+associated with the old string representation. (BL)
+*** POTENTIAL INCOMPATIBILITY with Tcl 8.0b1, but not with Tcl7.6 ***
+
+6/16/97 (bug fix) Tcl_ScanCountedElement could leave braces unmatched
+if the string ended with a backslash. (JO)
+
+6/17/97 (bug fix) Fixed channel event bug where readable events would be
+lost during recursive events loops if the input buffers contained
+data. (SS)
+
+6/17/97 (bug fix) Fixed bug in Windows socket code that didn't
+reenable read events in the case where an external entity is also
+reading from the socket. (SS)
+
+6/18/97 (bug fix) Changed initial setting of the notifier service mode
+to TCL_SERVICE_NONE to avoid unexpected event handling during
+initialization. (SS)
+
+6/19/97 (bug fix/feature change) The command callback to fcopy is now
+called in case of errors during the background copy.  This adds a second,
+optional argument to the callback that is the error string.  The callback
+in case of errors is required for proper cleanup by the user of fcopy. (BW)
+*** POTENTIAL INCOMPATIBILITY with Tcl 8.0b1, but not with Tcl 7.6 ***
+
+6/19/97 (bug fix) Fixed a panic due to the following four line script:
+	interp create x
+	x alias foo bar
+	x eval rename foo blotz
+	x alias foo {}
+The problem was that the interp code was not using the actual current name
+of the command to be deleted as a result of un-aliasing foo. (JL)
+
+6/19/97 (feature change) Pass interp down to the ChannelOption and
+driver specific calls so system errors can be differentiated from syntax
+ones. Changed Tcl_DriverGetOptionProc type. Affects Tcl_GetChannelOption,
+TcpGetOptionProc,  TtyGetOptionProc, etc. (DL)
+*** POTENTIAL INCOMPATIBILITY ***
+
+6/19/97 (new feature) Added Tcl_BadChannelOption for use by by driver
+specific option procedures (Set and Get) to return a complete and
+meaningful error message. (DL)
+
+6/19/97 (bug fixes) If a system call error occurs while doing an
+fconfigure on tcp or tty/com channel: return the appropriate error
+message (instead of the syntax error one or none). (Fixed for Unix and
+most of the Win and Mac drivers). (DL)
+
+6/20/97 (feature change) Eval is no longer assumed as the subcommand name
+in namespace commands: you must now write "namespace eval nsName {...}".
+Abbreviations of namespace subcommand names are now allowed. (BL)
+*** POTENTIAL INCOMPATIBILITY with Tcl 8.0b1, but not with Tcl7.6 ***
+
+6/20/97 (feature change) Changed the errorInfo traceback message for
+compilation errors from "invoked from within" to "while compiling". (BL)
+
+6/20/97 (bug fixes) Fixed various compilation-related bugs:
+    - "UpdateStringOfCmdName should never be called" and
+      "UpdateStringOfByteCode should never be called" panics.
+    - Segfault in TclObjInterpProc getting procedure name after evaluation
+      stack is reallocated (grown).
+    - Could not use ":" at end of variable and command names.
+    - Bad code generated for while and for commands with test expressions
+      enclosed in quotes: e.g., "set i 0; while "$i > 5" {}".
+    - Command trace procedures would crash if they did a Tcl_EvalObj that
+      reallocated the evaluation stack.
+    - Break and continue commands did not reset the interpreter result.
+    - The Tcl_ExprXXX routines, both string- or object-based, always
+      modified the interpreter result even if there was no error.
+    - The argument parsing procedure used by several compile procedures
+      always treated "]" as end of a command: e.g., "set a ]" would fail.
+    - Changed errorInfo traceback message for compilation errors from
+      "invoked from within" to "while compiling".
+    - Problem initializing Tcl object managers during interpreter creation.
+    - Added check and error message if formal parameter to a procedure is
+      an array element. (BL)
+
+6/23/97 (new feature) Added "registry" package to allow manipulation
+of the Windows system registry.  See manual entry for details. (SS)
+
+6/24/97 (feature change) Converted http to a package and added the
+http1.0 subdirectory of the Tcl script library.  This means you have
+to do a "package require http" to use this, as advertised in the man page. (BW)
+*** POTENTIAL INCOMPATIBILITY with Tcl 8.0b1, but not with Tcl 7.6 ***
+
+6/24/97 (bug fix) Ensure that Tcl_Set/GetVar C APIs, when called without
+TCL_LEAVE_ERR_MSG, don't touch the interp result. (DL)
+
+6/26/97 (feature change) Changed name of Tcl_ExprStringObj to
+Tcl_ExprObj. (BL)
+*** POTENTIAL INCOMPATIBILITY with Tcl 8.0b1, but not with Tcl 7.6 ***
+
+----------------- Released 8.0b2, 6/30/97 -----------------------
+
+7/1/97 (new feature) TCL_BUILD_SHARED flag set in tclConfig.sh
+when Tcl has been built with --enable-shared. A new tclLibObjs
+make target, echoing the list of the .o's needed to build a tcl
+library, is now provided. (DL)
+
+7/1/97 (feature change) compat/getcwd.c removed and changed the
+only place where getcwd is used so a new USEGETWD flag selects
+the use of the replacement "getwd". Adding this flag is recommended
+for SunOS 4 (because getcwd on SunOS 4 uses a pipe to pwd(1)!). (DL)
+
+7/7/97 (feature change) The split command now supports binary data (i.e.,
+null characters in strings). (BL)
+
+7/7/97 (bug fix) string first returned the wrong result if the first
+argument string was empty. (BL)
+
+7/8/97 (bug fix) Fixed core dump in fcopy that could occur when a command
+callback was supplied and an error or eof condition caused no background
+activity.  A refcount bug triggered a panic in Tcl_ListObjAppendElement. (BW)
+
+7/8/97 (bug fix) Relaxed the pattern matching on http_get so you do not
+need a trailing path component.  You can now get away with just
+http_get www.scriptics.com					(BW)
+
+7/9/97 (bug fix) Creating anonymous interpreters no longer smashes existing
+commands with names similar to the generated name. Previously creating an
+anonymous interpreter could smash an existing command, now it skips until
+it finds a command name that isn't being used. (JL)
+
+7/9/97 (feature change) Removed the policy management mechanism from the
+Safe Base; left the aliases to source and load modules, and to do a limited
+form of the "file" command. See entry of 11/15/96. (JL)
+
+7/9/97 (bug fixes) Fixed various compilation-related bugs:
+    - Line numbers in errorInfo now are the same as those in Tcl7.6 unless
+there are compilation errors. Compilation error messages now include the
+entire command in error.
+    - Trailing ::s after namespace names weren't being ignored.
+    - Could not refer to an namespace variable with an empty name using a
+name of the form "n::". (BL)
+
+7/9/97 (bug fix) Fixed bug in Tcl_Export that prevented you from exporting
+from other than the current namespace. (BL)
+
+7/9/97 (bug fix) env.test was removing env var needed for proper finding
+of libraries in child process. (DL)
+
+7/10/97 (bug fixes/new feature) Cleanup in Tcl_MakeSafe. Less information
+is leaked to safe interps. Error message fixes for interp sub commands.
+Likewise changes in safealias.tcl; tcl_safeCreateInterp can now be called
+without argument to generate the slave name (like in interp create). (DL)
+
+7/10/97 (bug fixes) Bytecode compiler now generates more detailed
+command location information: subcommands as well as commands now have
+location information. This means command trace procedures now get the
+correct source string for each command in their command parameter. (BL)
+
+7/22/97 (bug fixes) Performance improvement in Safe interpreters
+handling. Added new mask value to (tclInt.h) Interp.flags record. (DL)
+
+7/22/97 (bug fix) Fixed panic in 'interp target {} foo'. This bug
+was present since Tcl 7.6. (JL)
+
+7/22/97 (bug fix) Fixed bug in compilation of procedures in namespaces: the
+procedure's namespace must be used to look up compile procedures, not the
+current namespace. (BL)
+
+7/22/97 (bug fix) Use of the -channel option of http_get was not setting
+the end of line translations mode on the channel, so copying binary data
+with the -channel option was corrupting the result on non-unix platforms. (BW)
+
+7/22/97 (bug fixes) file commands and ~user (seg fault and other
+improper returns). (DL)
+
+7/23/97 (feature change) Reenabled "vwait" in Safe Base. (JL)
+
+7/23/97 (bug fixes) Fixed two bugs involving read traces on array variables
+in procedures: trace procedures were sometimes not called, and reading
+nonexistant array elements didn't create undefined element variables that
+could later be defined by trace procedures. (BL)
+
+7/24/97 (bug fix) Windows memory allocation performance was
+superlinear in some cases.  Made the Mac allocator generic and changed
+both the Mac and Windows platforms to use the new allocator instead of
+malloc and free. (SS)
+
+7/24/97 - 8/12/97 (bug fixes/change of features) Completely revamped safe
+sourcing/loading (see safe.n) to hide pathnames, use virtual
+paths tokens instead, improved security in several respects and made it
+more tunable. Multi level interp loading can work too now. Package auto
+loading now works in safe interps as long as the package directory is in
+the auto_path (no deep crawling allowed in safe interps). (DL)
+*** POTENTIAL INCOMPATIBILITY with previous alpha and beta releases ***
+
+7/24/97 (bug fixes) Made Tcl_SetVar* and Tcl_NewString* treat a NULL value
+as an empty string. (This fixes hairy crash case where you would crash
+because load command for other interps assumed presence of
+errorInfo...). (DL)
+
+7/28/97 (bug fix) Fixed pkg_mkIndex to understand namespaces.  It will
+use the export list of a namespace and create auto_index entries for
+all export commands.  Those names are in their fully qualified form in the
+auto_index.  Therefore, I tweaked unknown to try both $cmd and ::$cmd.
+Also fixed pkg_mkIndex so you can have "package require" commands inside
+your packages.  These commands are ignored, which is mostly ok except
+when you must load another package before loading yours because of
+linking dependencies. (BW)
+
+7/28/97 (bug fix) A variable created by the variable command now persists
+until the namespace is destroyed or the variable is unset. This is true even
+if the variable has not been initialized; these variables used to be
+destroyed if an error occurred when accessing them. In addition, the "info
+vars" command lists uninitialized namespace variables, while the "info
+exists" command returns 0 for them. (BL)
+
+7/29/97 (feature change)  Changed the http package to use the ::http
+namespace. http_get renamed to http::geturl, http_config renamed to
+http::config, http_formatQuery renamed to http::formatQuery.
+It now provides the 2.0 version of the package.
+The 1.0 version is still available with the old names.
+*** POTENTIAL INCOMPATIBILITY with Tcl 8.0b2 but not with Tcl 7.6 ***
+
+7/29/97 (bug fix, new feature) Tcl_Main now uses Tcl objects internally to
+preserve NULLs in commands and command output. Added new API procedure
+Tcl_RecordAndEvalObj that resembles Tcl_RecordAndEval but takes an object
+containing a command. (BL)
+
+7/30/97 (bug fix) Tcl freed strings in the environ array even if it
+did not allocate them. (SS)
+
+7/30/97 (bug fix) If a procedure is renamed into a different namespace, it
+now executes in the context of that namespace. (BL)
+
+7/30/97 (bug fix) Prevent renaming of commands into and from namespaces as
+part of hiding them. (JL)
+
+7/31/97 (feature change) Moved the history command from C to tcl.
+This uses the ::history namespace.  The "words" and "substitute" options
+are no longer supported.  In addition, the "keep" option without a value
+returns the current keep limit.  There is a new "clear" option.
+The unknown command now supports !! again. (BW)
+*** POTENTIAL INCOMPATIBILTY  ***
+
+7/30/97 (bug fix) Made sure that a slave can not fool the master into
+hiding the wrong command. Made sure we don't crash in hiding + namespaces
+issues. (DL)
+
+8/4/97 (bug fix) Concat, eval, uplevel, and similar commands were
+incorrectly trimming trailing space characters from their arguments
+even when the space characters were preceded by a backslash. (JO)
+
+8/4/97 (bug fix) Removed the hard link between bgerror and tkerror.
+Only bgerror is supported in tcl core. Tk will still look for a
+tkerror but using regular tcl code for that feature. (DL)
+*** POTENTIAL INCOMPATIBILTY with code relying on the hard link ***
+
+8/6/97 (bug fix) Reduced size required for compiled bytecodes by using a
+more compact encoding for the command pc-to-source map. (BL)
+
+8/6/97 (new feature) Added support for additional compilation and execution
+statistics when Tcl is compiled with the TCL_COMPILE_STATS flag. (BL)
+
+8/7/97 (bug fix) Expressions not in {}s that have a comparison operator as
+the topmost operator must be compiled out-of-line (call the expr cmd at
+runtime) to properly support expr's two-level substitution semantics. An
+example is "set a 2; set b {$a}; puts [expr $b == 2]". (BL)
+
+8/11/97 (bug fix) The catch command would sometimes crash if a variable name
+was given and the bytecode evaluation stack was grown when executing the
+argument script. (BL)
+
+8/12/97 (feature change) Reinstated the variable tcl_precision to control
+the number of digits used when floating-point values are converted to
+strings, with default of 12 digits.  However, had to make tcl_precision
+shared among all interpreters (except that safe interpreters can't
+modify it).  This makes the Tcl 8.0 behavior almost identical to 7.6
+except that the default precision is 12 instead of 6. (JO)
+*** POTENTIAL INCOMPATIBILITY ***
+
+----------------- Released 8.0, 8/18/97 -----------------------
+
+8/19/97 (bug fix) Minimal fix for glob -nocomplain bugs:
+"glob -nocomplain unreadableDir/*" was generating an anonymous
+error. More in depth fixes will come with 8.1. (DL).
+
+8/20/97 (bug fix) Removed check for FLT_MIN in binary command so
+underflow conditions are handled by the compiler automatic
+conversions. (SS)
+
+8/20/97 (bug fixes) Fixed several compilation-related bugs:
+    - Array cmd wasn't detecting arrays that, while compiled, do not yet
+      exist (e.g., are marked undefined since they haven't been assigned
+      to yet).
+    - The GetToken procedure in tclCompExpr.c wasn't recognizing properly
+      whether an integer token was invalid. For example, "0x$" is not
+      a valid integer.
+    - Performance bug in TclExecuteByteCode: the size of its stack frame
+      was reduced by over 20% by moving errorInfo code elsewhere.
+    - Uninitialized memory read error in tclCompile.c. (BL)
+
+8/21/97 (bug fix) safe::interpConfigure now behave like Tk widget's
+configure : it changes only the options you provide and you can get
+the current value of any single option. New ?-nested boolean? and
+?-statics boolean? for all safe::interp* commands but we still
+accept (upward compatibility) the previously defined non valued
+flags ?-noStatics? and ?-nestedLoadOk?. Improved the documentation. (DL).
+
+8/22/97 (bug fix) Updated PrintDbl.3 to reflect the fact that the
+tcl_precision variable is still used and that it is now shared by all
+interpreters. (BL)
+
+8/25/97 (bug fix) Fixed array access bug in IllegalExprOperandType
+procedure in tclExecute.c: it was not properly supporting the || and &&
+operators. (BL)
+
+8/27/97 (bug fix) In cases where a channel handler was created with an
+empty event mask while data was still buffered in the channel, the
+channel code would get stuck spinning on a timer that would starve
+idle handlers.  This mostly happened in Tk when reading from stdin. (SS)
+
+9/4/97 (bug fix) Slave interps now inherit the maximum recursion limit
+of their parent instead of starting back at the default. {nb: this still
+does not prevent stack overflow by multi-interps recursion or aliasing} (DL)
+
+9/11/97 (bug fix) An uninitialized variable in Tcl_WaitPid caused
+pipes to fail to report eof properly under Windows. (SS)
+
+9/12/97 (bug fix) "exec" was misidentifying some DOS executables as not
+executable. (CCS)
+
+9/14/97 (bug fix) Was using the wrong structure in sizeof operation in
+tclUnixChan.c. (JL)
+
+9/15/97 (bug fix) Fixed notifier to break out of do-one-event loop if
+Tcl_WaitForEvent returns 1, so that callers of Tcl_DoOneEvent will get
+a chance to check whether the event just handled is significant. This
+affected mainly recursive calls to Tcl_VWaitCmd; these did not get a
+chance to notice that the variable they were waiting for has been set
+and thus they didn't terminate the vwait. (JL, DL, SS)
+
+9/15/97 (bug fix) Alignment problems in "binary format" would cause a
+crash on some platforms when formatting floating point numbers. (SS)
+
+9/15/97 (bug fix) Fixed bug in Macintosh socket code.  Now passes all
+tests in socket.test that are not platform specific. (Thanks to Mark
+Roseman for the pointer on the fix.)  (RJ)
+
+9/18/97 (bug fix) Fixed bug -dictionary option of lsort that could
+cause the compare function to run off the end of an array if the
+number only contained 0's. (Thanks to Greg Couch for the report.) (RJ)
+
+9/18/97 (bug fix) TclFinalizeEnvironment was not cleaning up
+properly. (DL, JI)
+
+9/18/97 (bug fix) Fixed long-standing bug where an "array get" command
+did not trigger traces on the array or its elements. (BL)
+
+9/18/97 (bug fixes) Fixed compilation-related bugs:
+    - Fixed errorInfo traceback information for toplevel coomands that
+      contain nested commands.
+    - In the expr command, && and || now accept boolean operands as well
+      as numeric ones. (BL)
+
+9/22/97 (bug fix) Fixed bug that prevented translation modes from being
+set independently for input and output on sockets if input was "auto". (JL)
+
+9/24/97 (bug fix) Tcl_EvalFile(3) and thus source(n) now works fine on
+files containing NUL chars. (DL)
+
+9/26/97 (bug fix) Fixed use of uninitialized memory in the environ array
+that later could cause random core dumps. Applies to all platforms. (JL)
+
+9/26/97 (bug fix) Fixed use of uninitialized memory in socket address data
+structure under some circumstances. This could cause random core dumps.
+This applies only to Unix. (JL)
+
+9/26/97 (bug fix) Opening files on PC-NFS volumes would cause a hang
+until the system timed after the file was closed. (SS)
+
+10/6/97 (bug fix) The join(n) command, though objectified, was loosing
+NULs in the joinString and in list elements after the 2nd one.
+Now you can "join $list \0" for instance. (DL)
+
+10/9/97 (bug fix) Under windows, if env(TMP) or env(TEMP) referred to a
+non-existent directory, exec would fail when trying to create its temporary
+files. (CCS)
+
+10/9/97 (bug fix) Under mac and windows, "info hostname" would crash if
+sockets were installed but the hostname could not be determined anyhow.
+Tcl_GetHostName() was returning NULL when it should have been returning
+an empty string. (CCS)
+
+10/10/97 (bug fix) "file attribute /" returned error on windows. (CCS)
+
+10/10/97 (bug fix) Fixed the auto_load procedure to handle procedures
+defined in namespaces better.  Also fixed pgk_mkIndex so it sees procedures
+defined in nested namespaces.  Index entries are still only made for
+exported procedures. (BW)
+
+10/13/97 (bug fix) On unix, for files with unknown group or owner
+attributes, querying the "file attributes" would return an error rather than
+returning the group's or owner's id number, although tha command accepts
+numbers when setting the file's group or owner.  (CCS)
+
+10/22/97 (bug fix) "fcopy" did not eval the callback script at the
+global scope. (SS)
+
+10/22/97 (bug fix) Fixed the signature of the CopyDone callback used in
+the http package(s) so they can handle error cases properly. (BW)
+
+10/28/97 (bug fixes) Fixed a problem where lappend would free the Tcl object
+in a variable if a Tcl_ObjSetVar2 failed because of an error calling a trace
+on the variable. (BL)
+
+10/28/97 (bug fix) Changed binary scan to properly handle sign
+extension of integers on 64-bit or larger machines. (SS)
+
+11/3/97 (bug fixes) Fixed several bugs:
+    - expressions such as "expr ($x)" must be compiled out-of-line
+      (call the expr command procedure at runtime) to ensure the correct
+      behavior when "$x" is an expression such as "5+10".
+    - "array set a {}" now creates a new array var with an empty array
+      value if the var didn't already exist.
+    - "lreplace $foo end end" no longer returns an error (just an empty
+      list) if foo is empty.
+    - upvar will no longer create a variable in a namespace that refers
+      to a variable in a procedure.
+    - deleting a command trace within a command trace callback would
+      make the code that calls traces to reference freed memory.
+    - significantly sped up "string first" and "string last" (fix from
+      darrel@gemstone.com).
+    - seg fault in Tcl_NewStringObj() when a NULL is passed as the byte
+      pointer argument and Tcl is compiled with -DTCL_MEM_DEBUG.
+    - documentation and error msg fixes. (BL)
+
+11/3/97 (bug fix) Fixed a number of I/O bugs related to word sizes on
+64-bit machines. (SS)
+
+11/6/97 (bug fix) The exit code of the first process created by Tcl
+on Windows was not properly reported due to an initialization
+problem. (SS)
+
+----------------- Released 8.0p1, 11/7/97 -----------------------
+
+11/19/97 (bug fix) Fixed bug in linsert where it sometimes accidently
+cleared out a shared argument list object. (BL).
+
+11/19/97 (bug fix) Autoloading in namespaces was not working properly.
+auto_mkindex is still not really namespace aware but most common
+cases should now be handled properly (see init.test). (BW, DL)
+
+11/20/97 (enhancement) Made the changes required by the new Apple
+Universal Headers V.3.0, so that Tcl will compile with CW Pro 2.
+
+11/24/97 (bug fix) Fixed tests in clock test suite that needed the
+-gmt flag set.  Thanks to Jan Nijtmans for reporting the problem. (RJ)
+
+----------------- Released 8.0p2, 11/25/97 -----------------------
+
+12/3/97 (bug fix/optimization) Removed uneeded and potentially dangerous
+instances of double evaluations if "if" and "expr" statements from
+the library files. It is recommended that unless you need a double
+evaluation you always use "expr {...}" instead of "expr ..." and
+"if {...} ..." instead of "if ... ...". It will also be faster
+thanks to the byte compiler. (DL)
+
+---- Shipped as part of the plugin2.0b5 as 8.0p2Plugin1, Dec 8th 97 ----
+
+12/8/97 (bug fix) Need to protect the newly accepted channel in an
+accept callback on a socket, otherwise the callback may close it and
+cause an error, which would cause the C code to attempt to close the
+now deleted channel. Bumping the refcount assures that the channel sticks
+around to be really closed in this case. (JL)
+
+12/8/97 (bug fix) Need to protect the channel in a fileevent so that it
+is not deleted before the fileevent handler returns. (CS, JL)
+
+12/18/97 (bug fix) In the opt argument parsing package: if the description
+had only flags, the "too many arguments" case was not detected. The default
+value was not used for the special "args" ending argument. (DL)
+
+1/15/98 (improvement) Moved common part of initScript in common file.
+Moved windows specific initialization to init.tcl so you can initialize
+Tcl in windows without having to call Tcl_Init which is now only
+searching for init.tcl {back ported from 8.1}. (DL)
+
+---- Shipped as part of the plugin as 8.0p2Plugin2, Jan 15th 98 ----
+
+5/27/98 (bug fix) Windows socket driver did not notice new data arriving
+on nonblocking sockets until the event loop was entered. (SS)
+
+5/27/98 (bug fix) Windows socket driver used FIONREAD, which is not
+supported correctly by WinSock. (SS)
+
+6/9/98 (bug fix) Generic channel code failed to report readable file
+events on buffered data that was left behind by a gets or read that
+did not consume all available data. (SS)
+
+6/18/98 (bug fix) Compilation of loop expressions was too aggressive
+and incorrectly inlined non-literal expressions. (SS)
+
+6/18/98 (bug fix) "info var" and "info locals" incorrectly reported
+the existence of compiler temporary variables. (SS)
+
+6/18/98 (bug fix) Dictionary sorting used signed character
+comparisons. (SS)
+
+6/18/98 (bug fix) Compile procs corrupted the exception stack in some
+cases. (SS)
+
+6/18/98 (bug fix) Array set had erratic behavior when initializing a
+variable from an empty value list. (SS)
+
+6/18/98 (bug fix) The Windows registry package had a bad bounds check
+that could lead to a crash. (SS)
+
+6/18/98 (bug fix) The foreach compile proc did not correctly handle
+non-local variable references. (SS)
+
+6/25/98 (new features) Added name resolution hooks to support [incr Tcl].
+There are new internal Tcl_*Resolver* APIs to add, query and remove the hooks.
+With this changes it should be possible to dynamically load [incr Tcl]
+as an extension. (MM)
+
+7/1/97 (bug fix) The commands "info args, body, default, procs" did
+not correctly handle imported procedures. (RJ)
+
+7/6/98 (improvement) pkg_mkIndex now implements the "package require"
+command.  This makes it possible to create index files for packages
+that require another package and then execute code from that package in
+their file. Previously, this would throw an error because the required
+package had not been loaded.  The -nopkgrequied flag is provided to
+revert back to the old functionality. (EMS)
+
+7/6/98 (improvement) back-ported the -direct flag from 8.1 into
+pkg_mkIndex.  This results in pkgIndex.tcl files that contain direct
+source or load commands instead of tclPkgSetup commands. (EMS)
+
+7/6/98 (improvement) made changes to the AuxData items structures to support
+storage of compiled scripts on disk. Also some related minor changes in
+the compilation and execution engine. (EMS)
+
+6/4/98 (enhancement) Added new internal routines to support inserting
+and deleting from the stat, access, and open-file-channel mechanisms.
+TclAccessInsertProc, TclStatInsertProc, & TclOpenFileChannelInsertProc
+insert pointers to such routines; TclAccessDeleteProc, TclStatDeleteProc,
+& TclOpenFileChannelDeleteProc delete pointers to such routines.  See
+the file generic/tclIOUtils.c for more details. (SKS)
+
+7/1/98 (enhancement) Added a new internal C variable
+tclPreInitScript.  This is a pointer to a string that may hold an
+initialization script; If this pointer is non-NULL it is evaluated in
+Tcl_Init() prior to the built-in initialization script defined in the
+file generic/tclInitScript.h.  (SKS)
+
+7/6/98 (bug fix) Removed dead code in PlatformInitExitHandler so that
+the TCL_LIBRARY value can be safely patched in binaries. (BW)
+
+7/24/98 (enhancement) Incorporated a new version of auto_mkindex that
+can support the [incr Tcl] class structures.  This version will index
+all procedures in a source file, not just those where "proc" starts
+at the beginning of the line.  If you want the old behavior, use the
+auto_mkindex_old procedure. (MM)
+
+7/24/98 (feature change) Changed the Windows registry key to be
+HKEY_LOCAL_MACHINE\Software\Scriptics\Tcl\8.0, and to store the path
+in the default value instead of "Root".  Also, this key can be
+specified at compile time in case Tcl is being used in a different
+context where it needs an alternate library path from the standard Tcl
+installation. (SS)
+
+7/24/98 (feature change) Changed the search order for init.tcl.  The
+tcl_library variable can now be set before calling Tcl_Init to avoid
+doing any searches.  If it isn't set, then Tcl checks
+env(TCL_LIBRARY), the static value set at compile time, an install
+directory relative to the executable, a source directory relative to
+the executable, and a tcl directory relative to the source heirarchy
+containing the executable.  See the comment at the top of
+generic/tclInitScript.h for more details. (SS)
+
+7/27/98 (config change) Changed the use of the DBGX flag in configure.in
+and the makefile to be TCL_DBGX.  Users of tclConfig.sh may need to pass
+this through their configure files with AC_SUBST. (BW)
+
+729/98 (bug fix) Changed [info body] to return a copy of the body of a
+compiled procedure instead of the body itself, to avoid invalidation
+of the internal rep and loss of the byte-codes. (EMS)
+
+8/5/98 (bug fix) The platform init code could walk off the end of a
+buffer when reading the PkgPath registry value on Windows. (SS)
+
+8/5/98 (Windows makefile change) Introduced a set of macros to deal with
+exporting symbols when compiling DLLS on Windows. See win/README for
+details. (EMS)
+
+8/5/98 (addendum) Added a second Windows registry key under
+HKEY_LOCAL_MACHINE\Software\Scriptics\Tcl\8.0, named "pkgPath".
+This is a multi-string value used to initialize the tcl_pkgPath
+variable. This is required if extension DLLs are in architecture specific
+subdirectories. (SS)
+
+8/6/98 (new feature) Added tcl_findLibrary to init.tcl for use by
+extensions, including Tk.  This searches in a canonical way for
+an extensions library directory and initialization file. (BW)
+
+8/10/98 (bug fix) Imported commands used to get lost if the target
+of the import was redefined.  Tcl_CreateCommand and Tcl_CreateObjCommand
+were updated to restore import links. (Note that if you rename a command,
+the import links move to the new name, and if you delete a command then
+the import links get lost. These semantics have not changed.) (MC)
+
+-------- Released 8.0.3 to the Tcl Consortium CD-ROM project, 8/10/98 ------
+
+9/3/98 (bug fix) Tcl_Realloc was failing under Windows because the
+GlobalReAlloc API was not correctly re-allocating blocks that were
+32k+.  The fix was to use newer Win32 APIs (HeapAlloc, HeapFree, and
+HeapReAlloc.) (BS)
+
+10/5/98 (bug fix) Fixed bug in pkg_mkIndex that caused some files that do
+a "package require" of packages in the Tcl libraries to give a warning like
+	warning: "xx.tcl" provides more than one package ({xx 2.0} {yy 0.3})
+and generate a broken pkgIndex.tcl file. (EMS)
+
+10/5/98 (bug fix) Pkg_mkIndex was not doing a case-insensitive comparison
+of extensions to determine whether to load or source a file. Thus, under
+Windows, MYDLLNAME.DLL was sourced, and mydllname.dll loaded. (EMS)
+
+10/5/98 (new feature) Created a new Tcl_Obj type, "procbody". This object's
+internal representation holds a pointer to a Proc structure. Extended
+TclCreateProc to take both strings and "procbody". (EMS)
+
+10/13/98 (bug fix) The "info complete" command can now handle strings
+with NULLs embedded.  Thanks to colin@field.medicine.adelaide.edu.au
+for providing this fix. (RJ)
+
+10/13/98 (bug fix) The "lsort -dictionary" command did not properly
+handle some numbers starting with 0.  Thanks to Richard Hipp
+<drh@acm.org> for submitting the fix to Scriptics. (RJ)
+
+10/13/98 (bug fix) The function Tcl_SetListObj was creating an invalid
+Tcl_Obj if the list had zero elements (despite what the comments said
+it would do).  Thanks to Sebastian Wangnick for reporting the
+problem. (RJ)
+
+10/20/98 (new feature) Added tcl_platform(debug) element to the
+tcl_platform array on Windows platform.  The existence of the debug
+element of the tcl_platform array indicates that the particular Tcl
+shell has been compiled with debug information.  Using
+"info exists tcl_platform(debug)" a Tcl script can direct the
+interpreter to load debug versions of DLLs with the load
+command. (SKS)
+
+10/20/98 (feature change) The Makefile and configure scripts have been
+changed for IRIX to build n32 binaries instead of the old 32 abi
+format.  If you have extensions built with the o32 abi's you will need
+to update them to n32 for them to work with Tcl.  (RJ)
+*** POTENTIAL INCOMPATIBILITY ***
+
+10/23/98 (bug fix) tcl_findLibrary had a stray ] in one of the
+pathnames it searched for the initialization script.  tclInitScript.h
+was incorrectly adding the parent of tcl_library to tcl_pkgPath.  This
+logic was moved into init.tcl, and the initialization of auto_path was
+documented.  Thanks to Donald Porter and Tom Silva for related
+patches. (BW)
+
+10/29/98 (bug fix) Fixed Tcl_NotifyChannel to use Tcl_Preserve instead
+of Tcl_RegisterChannel so that 1) unregistered channels do not get
+closed after their first fileevent, and 2) errors that occur during
+close in a fileevent script are actually reflected by the close
+command. (BW)
+
+10/30/98 (bug fix) Overhaul of pkg_mkIndex to deal with transitive
+package requires and packages split among scripts and binary files.
+Also fixed ommision of global for errorInfo in tcl_findLibrary. (BW)
+
+11/08/98 (bug fix) Fixed the resource command to always detect
+the case where a file is opened a second time with the same
+permissions.  IM claims that this will always cause the same
+FileRef to be returned, but in MacOS 8.1+, this is no longer the case,
+so we have to test for this explicitly. (JI)
+
+11/10/98 (feature change) When compiling with Metrowerk's MSL, use the
+exit function from MSL rather than ExitToShell.  This allows MSL to
+clean up its temporary files. Thanks to Vince Darley for this
+improvement. (JI)
+
+----------------- Released 8.0.4, 11/19/98 -------------------------
+
+11/20/98 (bug fix) Handle possible NULL return in TclGetStdFiles. (RJ)
+
+11/20/98 (bug fix) The dltests would not build on SGI.  They reported
+that you could not mix n32 with 032 binaries.  The configure script
+has been modified to get the EXTRA_CFLAGS from the tcl configure
+script.  [Bug id: 840] (RJ)
+
+12/3/98 (bug fix) Windows NT creates sockets so they are inheritable
+by default.  Fixed socket code so it turns off this bit right after
+creation so sockets aren't kept open by exec'ed processes. [Bug: 892]
+Thanks to Kevin Kenny for this fix.  (SS)
+
+1/11/98 (bug fix)  On HP, "info sharedlibextension" was returning
+empty string on static apps.  It now always returns ".sl".  (RJ)
+
+1/28/99 (configure change) Now support -pipe option on gcc.  (RJ)
+
+2/2/99 (bug fix) Fixed initialization problem on Windows where no
+searching for init.tcl would be performed if the registry keys were
+missing.  (stanton)
+
+2/2/99 (bug fix) Added support for HKEY_PERFORMANCE_DATA and
+HKEY_DYN_DATA keys in the "registry" command. (stanton)
+
+2/2/99 (bug fix) ENOTSUP and EOPNOTSUPP clashed on some Linux
+variants. (stanton)
+
+2/2/99 (enhancement) The "open" command has been changed to use the
+object interfaces. (stanton)
+
+2/2/99 (bug fix) In some cases Tcl would crash due to an overflow of
+the exception stack resulting from a missing byte code in some
+expressions. (stanton)
+
+2/2/99 (bug fix) Changed configure so Linux and IRIX shared libraries
+are linked with the system libraries. (stanton)
+
+2/2/99 (bug fix) Added support for BSDI 4.x (BSD/OS-4*) to the
+configure script. (stanton)
+
+2/2/99 (bug fix) Fixed bug where upvar could resurrect a namespace
+variable after the namespace had been deleted. (stanton)
+
+2/2/99 (bug fix) In some cases when creating variables, the
+interpreter result was being modified even if the TCL_LEAVE_ERR_MSG
+flag was set. (stanton)
+
+2/2/99 (bug fix & new feature) Changed the socket drivers to properly
+handle failures during an async socket connection.  Added a new
+fconfigure option "-error" to retrieve the failure message.  See the
+socket.n manual entry for details. (stanton)
+
+2/2/99 (bug fix) Deleting a renamed interp alias could result in a
+panic. (stanton)
+
+2/2/99 (feature change/bug fix) Changed the behavior of "file
+extension" so that it splits at the last period.  Now the extension of
+a file like "foo..o" is ".o" instead of "..o" as in previous versions.
+*** POTENTIAL INCOMPATIBILITY ***
+
+----------------- Released 8.0.5, 3/9/99 -------------------------
+
+======== Changes for 8.0 go above this line ========
+======== Changes for 8.1 go below this line ========
+
+6/18/97 (new feature) Tcl now supports international character sets:
+    - All C APIs now accept UTF-8 strings instead of iso8859-1 strings,
+      wherever you see "char *", unless explicitly noted otherwise.
+    - All Tcl strings represented in UTF-8, which is a convenient
+      multi-byte encoding of Unicode.  Variable names, procedure names,
+      and all other values in Tcl may include arbitrary Unicode characters.
+      For example, the Tcl command "string length" returns how many
+      Unicode characters are in the argument string.
+    - For Java compatibility, embedded null bytes in C strings are
+      represented as \xC080 in UTF-8 strings, but the null byte at the end
+      of a UTF-8 string remains \0.  Thus Tcl strings once again do not
+      contain null bytes, except for termination bytes.
+    - For Java compatibility, "\uXXXX" is used in Tcl to enter a Unicode
+      character.  "\u0000" through "\uffff" are acceptable Unicode
+      characters.
+    - "\xXX" is used to enter a small Unicode character (between 0 and 255)
+      in Tcl.
+    - Tcl automatically translates between UTF-8 and the normal encoding for
+      the platform during interactions with the system.
+    - The fconfigure command now supports a -encoding option for specifying
+      the encoding of an open file or socket.  Tcl will automatically
+      translate between the specified encoding and UTF-8 during I/O.
+      See the directory library/encoding to find out what encodings are
+      supported (eventually there will be an "encoding" command that
+      makes this information more accessible).
+    - There are several new C APIs that support UTF-8 and various encodings.
+      See Utf.3 for procedures that translate between Unicode and UTF-8
+      and manipulate UTF-8 strings. See Encoding.3 for procedures that
+      create new encodings and translate between encodings.  See
+      ToUpper.3 for procedures that perform case conversions on UTF-8
+      strings.
+
+9/18/97 (enhancement) Literal objects are now shared by the ByteCode
+structures created when compiled different scripts. This saves up to 45%
+of the total memory needed for all literals. (BL)
+
+9/24/97 (bug fixes) Fixed Tcl_ParseCommand parsing of backslash-newline
+sequences at start of command words. Suppressed Tcl_EvalDirect error logging
+if non-TCL_OK result wasn't an error. (BL)
+
+10/17/97 (feature enhancement) "~username" now refers to the users' home
+directory on Windows (previously always returned failure). (CCS)
+
+10/20/97 (implementation change) The Tcl parser has been completely rewritten
+to make it more modular.  It can now be used to parse a script without actually
+executing it.  The APIs for the new parser are not correctly exported, but
+they will eventually be exported and augmented with Tcl commands so that
+Tcl scripts can parse other Tcl scripts. (JO)
+
+10/21/97 (API change) Added "flags" argument to Tcl_EvalObj, removed
+Tcl_GlobalEvalObj procedure.  Added new procedures Tcl_Eval2 and
+Tcl_EvalObjv. (JO)
+*** POTENTIAL INCOMPATIBILITY ***
+
+10/22/97 (API change) Renamed Tcl_ObjSetVar2 and Tcl_ObjGetVar2 to
+Tcl_SetObjVar2 and Tcl_GetObjVar2 (for consistency with other C APIs)
+and changed the name arguments to be strings instead of objects.  (JO)
+*** POTENTIAL INCOMPATIBILITY ***
+
+10/27/97 (enhancement) Bytecode compiler rewritten to use the new Tcl
+parser. (BL)
+
+11/3/97 (New routines) Added Tcl_AppendObjToObj, which appends the
+string rep of one Tcl_Obj to another. Added Tcl_GetIndexFromObjStruct,
+which is similar to Tcl_GetIndexFromObj, except that you can give an
+offset between strings. This allows Tcl_GetIndexFromObjStruct to be
+called with a table of records which have strings in them. (SRP)
+
+12/4/97 (enhancement) New Tcl expression parser added. Added new procedure
+Tcl_ParseExpr and new token types TCL_TOKEN_SUB_EXPR and
+TCL_TOKEN_OPERATOR. Expression compiler is reimplemented to use this
+parser. (BL)
+
+12/9/97 (bug fix) Tcl_EvalObj() increments/decrements the refcount of the
+script object to prevent the object from deleting itself while in the
+middle of being evaluated. (CCS)
+
+12/9/97 (bug fix) Memory leak in Tcl_GetsObjCmd(). (CCS)
+
+12/11/97 (bug fix) Environment array leaked memory when compiled with
+Visual C++. (SS)
+
+12/11/97 (bug fix) File events and non-blocking I/O did not work on
+pipes under Windows.  Changed to use threads to achieve non-blocking
+behavior. (SS)
+
+12/18/97 (bug fixes) Fixed segfault in "namespace import"; importing a
+procedure that causes a cycle now returns an error. Modified "info procs",
+"info args", "info body", and "info default" to return information about
+imported procedures as well as procedures defined in a namespace. (BL)
+
+12/19/97 (enhancement) Added new Tcl_GetString() procedure that can be used
+in place of Tcl_GetStringFromObj() if the string representation's length
+isn't needed. (BL)
+
+12/18/97 (bug fix) In the opt argument parsing package: if the description
+had only flags, the "too many arguments" case was not detected. The default
+value was not used for the special "args" ending argument. (DL)
+
+1/7/98 (clean up) Moved everything not absolutly necessary out of init.tcl
+procs now in auto.tcl and package.tcl can be autoloaded if needed. (DL)
+
+1/7/98 (enhancement) tcltest made at install time will search for it's
+init.tcl where it is, even when using virtual path compilation. (DL)
+
+1/8/98 (os bug workaround) when needed, using a replacement for memcmp so
+string compare "char with high bit set" "char w/o high bit set" returns
+the expected value on all platforms. (DL)
+
+1/8/98 (unix portability/configure) building from .../unix/targetName/
+subdirectories and simply using "../configure" should now work fine. (DL)
+
+1/14/98 (enhancement) Added new regular expression package that
+supports AREs, EREs, and BREs.  The new package includes new escape
+characters, meta-syntax, and character classes inside brackets.
+Regexps involving backslashes may behave differently.  (MH)
+*** POTENTIAL INCOMPATIBILITY ***
+
+1/16/98 (os workaround) Under windows, "file volume" was causing chatter
+and/or several seconds of hanging when querying empty floppy drives.
+Changed implementation to call an empirically-derived function that doesn't
+cause this. (CCS)
+
+1/16/98 (enhancement) Converted regular expressions to a Tcl_Obj type so
+their compiled form gets cached automatically.  Reduced NSUBEXP from 100
+to 20. (BW)
+
+1/16/98 (documentation) Change unclear documentation and comments for
+functions like Tcl_TranslateFileName() and Tcl_ExternalToUtfDString().  Now
+it explicitly says they take an uninitialized or free DString.  A DString
+that is "empty" or "not holding anything" could have been interpreted as one
+currently with a zero length, but with a large dynamically allocated buffer.
+(CCS)
+
+----------------- Released 8.1a1, 1/22/98 -----------------------
+
+1/28/98 (new feature) Added a "-direct" optional flag to pkg_mkIndex
+to generate direct loading package indexes (such those you need
+if you use namespaces and plan on using namespace import just after
+package require). pkg_mkIndex still has limitations regarding
+package dependencies but errors are now ignored and with -direct, correct
+package indexes can be generated even if there are dependencies as long
+as the "package provide" are done early enough in the files. (DL)
+
+1/28/98 (enhancement) Performance tuning of regexp and regsub. (CCS)
+
+1/28/98 (bug fix) regexp and regsub with "-indices" returned the byte-offsets
+of the characters in the UTF-8 representation, not the character offsets
+themselves. (CCS)
+
+1/28/98 (bug fix) "clock format 0 -format %Z -gmt 1" would return the local
+timezone string instead of "GMT" on Solaris and Windows.
+
+1/28/98 (bug fix) Restore tty settings when closing serial device on Unix.
+This is good behavior when closing real serial devices, essential when
+closing the pseudo-device /dev/tty because the user's terminal settings
+would be left useless, in raw mode, when tcl quit. (CCS)
+
+1/28/98 (bug fix) Tcl_OpenCommandChannel() was modifying the contents of the
+argv array passed to it, causing problems for any caller that wanted to
+continue to use the argv array after calling Tcl_OpenCommandChannel(). (CCS)
+
+2/1/98 (bug fix) More bugs with %Z in format string argument to strftime():
+1. Borland always returned empty string.
+2. MSVC always returned the timezone string for the current time, not the
+   timezone string for the specified time.
+3. With MSVC, "clock format 0 -format %Z -gmt 1" would return "GMT" the first
+   time it was called, but would return the current timezone string on all
+   subsequent calls. (CCS)
+
+2/1/98 (bug fix) "file stat" was broken on Windows.
+1. "file stat" of a root directory (local or network) or a relative path that
+   resolved to a root directory (c:. when in pwd was c:/) was returning error.
+2. "file stat" on a regular file (S_IFREG), the st_mode was sign extended to
+   a negative int if the platform-dependant type "mode_t" was declared as a
+   short instead of an unsigned short.
+3. "file stat" of a network directory, the st_dev was incorrectly reported
+   as the id of the last accessed local drive rather than the id of the
+   network drive. (CCS)
+
+2/1/98 (bug fix) "file attributes" of a relative path that resolved to a
+root directory was returning error. (CCS)
+
+2/1/98 (bug fix) Change error message when "file attribute" could not
+determine the attributes for a file.  Previously it would return different
+error messages on Unix vs.  Windows vs. Mac. (CCS)
+
+2/4/98 (bug fixes) Fixed several instances of bugs where the parser/compiler
+would reach outside the range of allocated memory. Improved the array
+lookup algorithm in set compilation. (DL)
+
+2/5/98 (change) The TCL_PARSE_PART1 flag for Set/Get(Obj)Var2 C APIs is now
+deprecated and ignored. The part1 is always parsed when the part2 argument
+is NULL. This is to avoid a pattern of errors for extension writers converting
+from string based Tcl_SetVar() to new Tcl_SetObjVar2() and who could easily
+forget to provide the flag and thus get code working for normal variables
+but not for array elements. The performance hit is minimal. A side effect
+of that change is that is is no longer possible to create scalar variables
+that can't be accessed by tcl scripts because of their invalid name
+(ending with parenthesis). Likewise it is also parsed and checked to
+ensure that you don't create array elements of array whose name is a valid
+array element because they would not be accessible from scripts anyway.
+Note: There is still duplicate array elements parsing code. (DL)
+*** POTENTIAL INCOMPATIBILITY ***
+
+2/11/98 (bug fix) Sharing objects between interps, such as by "interp
+eval" or "send" could cause a crash later when dereferencing an interp
+that had been deleted, given code such as:
+	set a {set x y}
+	interp create foo
+	interp eval foo $a
+	interp delete foo
+	unset a
+Interp "foo" was gone, but "a" had a internal rep consisting of bytecodes
+containing a dangling pointer to "foo".  Unsetting "a" would attempt to
+return resources back to "foo", causing a crash as random memory was
+accessed.  The lesson is that that if an object's internal rep depends on
+an interp (or any other data structure) it must preserve that data in
+some fashion. (CCS)
+
+2/11/98 (enhancement) The "interp" command was returning inconsistent error
+messages when the specified slave interp could not be found. (CCS)
+
+2/11/98 (bug fix) Result codes like TCL_BREAK and TCL_CONTINUE were not
+propagating through the master/slave interp boundaries, such as "interp
+eval" and "interp alias".  TCL_OK, TCL_ERROR, and non-standard codes like
+teh integer 57 work.  There is still a question as to whether TCL_RETURN
+can/should propagate. (CCS)
+
+2/11/98 (bug fix) TclCompileScript() was derefering memory 1 byte before
+start of the string to compile, looking for ']'. (CCS,DL)
+
+2/11/98 (bug fix) Tcl_Eval2() was derefering memory 1 byte before start
+of the string to eval, looking for ']'. (CCS,DL)
+
+2/11/98 (bug fix) Compiling "set a(b" was running off end of string. (CCS,DL)
+
+2/11/98 (bug fix) Windows initialization code was dereferencing
+uninitialized memory if TCL_LIBRARY environment didn't exist. (CCS)
+
+2/11/98 (bug fix) Windows "registry" command was dereferencing
+uninitialized memory when constructing the $errorCode for a failed
+registry call. (CCS)
+
+2/11/98 (enhancement) Eliminate the TCL_USE_TIMEZONE_VAR definition from
+configure.in, because it was the same information as the already existing
+HAVE_TM_ZONE definition.  The lack of HAVE_TM_ZONE is used to work around a
+Solaris and Windows bug where "clock format [clock sec] -format %Z -gmt 1"
+produces the local timezone string instead of "GMT". (CCS)
+
+2/11/98 (bug fix) Memleaks and dereferencing of uninitialized memory in
+regexp if an error occurred while compiling a regular expression. (CCS).
+
+2/18/98 (new feature) Added mutexes and thread local storage in order
+to make Tcl thread safe.  For testing purposes, there is a testthread
+command that creates a new thread and an interpreter inside it.  See
+thread.test for examples, but this script-level interface is not fixed.
+Each thread has its own notifier instance to manage its own events,
+and threads can post messages to each other's message queue.
+This uses pthreads on UNIX, and native thread support on other platforms.
+You enable this by configuring with --enable-threads.  Note that at
+this time *Tk* is still not thread safe. Special thanks to
+Richard Hipp: his earlier implementation inspired this work. (BW, SS, JI)
+
+2/18/98 (hidden feature change) The way the env() array is shared among
+interpreters changed.  Updates to env used to trigger write traces in
+other interpreters.  This undocumented feature is no longer implemented.
+Instead, variable tracing is used to keep the C-level environ array in sync
+with the Tcl-level env array. This required adding TCL_TRACE_ARRAY support
+to Tcl_TraceVar2 so that array names works properly. (BW)
+*** POTENTIAL INCOMPATIBILITY ***
+
+2/18/98 (enhancement) Conditional compilation for unix systems (e.g.,
+IRIX, SCO) that use f_bsize instead of st_blksize to determine disk block
+size. (CCS)
+
+2/23/98 (bug fix) Fixed the emulation of polling selects in the threaded
+version of the Unix notifier.  The bug was showing up on a multiprocessor
+as starvation of the notifier thread. (BW)
+
+----------------- Released 8.1a2, Feb 23 1998 -----------------------
+
+9/22/98 (bug fix) Changed the value of TCL_TRACE_ARRAY so it no longer
+conflicts with the deprecated TCL_PARSE_PART1 flag.  This should
+improve portability of C code. (stanton)
+
+10/6/98 (bug fix) The compile procedure for "if" incorrectly attempted
+to match against the literal string "if", resulting in a stack
+overflow when "::if" was compiled.  It also would incorrectly accept
+"if" instead of "elsif" in later clauses.  (stanton)
+
+10/15/98 (new feature) Added a "totitle" subcommand to the "string"
+command to convert strings to capitalize the first character of a string
+and lowercase all of the other characters. (stanton)
+
+10/15/98 (bug fix) Changed regexp and string commands to properly
+handle case folding according to the Unicode character
+tables. (stanton)
+
+10/21/98 (new feature) Added an "encoding" command to facilitate
+translations of strings between different character encodings.  See
+the encoding.n manual entry for more details. (stanton)
+
+11/3/98 (bug fix) The regular expression character classification
+syntax now includes Unicode characters in the supported
+classes. (stanton)
+
+11/6/98 (bug fix) Variable traces were causing crashes when upvar
+variables went out of scope. [Bug: 796] (stanton)
+
+11/9/98 (bug fix) "format" now correctly handles multibyte characters
+in %s format strings. (stanton)
+
+11/10/98 (new feature) "regexp" now accepts three new switches
+("-line", "-lineanchor", and "-linestop") that control how regular
+expressions treat line breaks. See the regexp manual entry for more
+details. (stanton)
+
+11/17/98 (bug fix) "scan" now correctly handles Unicode
+characters. (stanton)
+
+11/17/98 (new feature) "scan" now supports XPG3 position specifiers
+and the "%n" conversion character.  See the "scan" manual entry for
+more details. (stanton)
+
+11/17/98 (bug fix) The Tcl memory allocator now returns 8-byte aligned
+chunks of memory which improves performance on Windows and avoids
+crashes on other platforms. [Bug: 834] (stanton)
+
+11/23/98 (bug fix) Applied various regular expression performance bug
+fixes supplied by Henry Spencer. (stanton)
+
+11/30/98 (bug fix) Fixed various thread related race conditions. [Bug:
+880 & 607] (stanton)
+
+11/30/98 (bug fix) Fixed a number of memory overflow and leak
+bugs. [Bug: 584] (stanton)
+
+12/1/98 (new feaure) Added support for Korean encodings. (stanton)
+
+12/1/98 (feature change) Changed the Tcl_EvalObjv interface to remove
+the string and length arguments.
+*** POTENTIAL INCOMPATIBILITY with previous alpha releases ***
+
+12/2/98 (bug fix) Fixed various bugs related to line feed
+translation. [Bug: 887] (stanton)
+
+12/4/98 (new feature) Added a message catalog facility to help with
+localizing Tcl scripts.  Thanks to Mark Harrison for contributing the
+initial implementation of the "msgcat" package. (stanton)
+
+12/7/98 (bug fix) The memory allocator was failing to update the
+block list for large memory blocks that were reallocated into a
+different address. [Bug: 933] (stanton)
+
+----------------- Released 8.1b1, Dec 10 1998 -----------------------
+
+12/22/98 (performance improvement) Improved the -command option of the
+lsort command to better use the object system for improved
+performance (about 5x speed up).  Thanks to Syd Polk for suppling the
+patch. [RFE: 726] (rjohnson)
+
+2/10/99 (bug fix) Restored the Tcl_ObjSetVar2/Tcl_ObjGetVar2
+interfaces from 8.0 and renamed the Tcl_GetObjVar2/Tcl_SetObjVar2
+interfaces to Tcl_GetVar2Ex and Tcl_SetVar2Ex.  This should provide
+better compatibility with 8.0. (stanton)
+*** POTENTIAL INCOMPATIBILITY with previous alpha/beta releases ***
+
+2/10/99 (bug fix) Made the eval interfaces compatible with 8.0 by
+renaming Tcl_EvalObj to Tcl_EvalObjEx, renaming Tcl_Eval2 to
+Tcl_EvalEx and restoring Tcl_EvalObj and Tcl_GlobalEvalObj interfaces
+so they match Tcl 8.0. (stanton)
+*** POTENTIAL INCOMPATIBILITY with previous alpha/beta releases ***
+
+2/25/99 (bug fix/new feature) On Windows, the channel drivers for
+consoles and serial ports now completely support file events. (redman)
+
+3/5/99 (bug fix) Integrated patches to fix various configure problems
+that affected HP-UX-11, 64-bit IRIX, Linux, and Solaris. (stanton)
+
+3/9/99 (bug fix) Integrated various AIX related patches to improve
+support for shared libraries. (stanton)
+
+3/9/99 (new feature) Added tcl_platform(user) to provide a portable
+way to get the name of the current user. (welch)
+
+3/9/99 (new feature) Integrated the stub library mechanism contributed
+by Jan Nijtmans, Paul Duffin, and Jean-Claude Wippler.  This feature
+should make it possible to write extensions that support multiple
+versions of Tcl simultaneously.  It also makes it possible to
+dynamically load extensions into statically linked interpreters.  This
+patch includes the following changes:
+      -	Added a Tcl_InitStubs() interface
+      -	Added Tcl_PkgProvideEx, Tcl_PkgRequireEx, Tcl_PkgPresentEx,
+      	and Tcl_PkgPresent.
+      - Added va_list versions of all VARARGS functions so they can be
+	invoked from wrapper functions.
+See the manual for more information. (stanton)
+
+
+3/10/99 (feature change) Replaced Tcl_AlertNotifier with
+Tcl_ThreadAlert since the Tcl_AlertNotifier function relied on passing
+internal data structures. (stanton)
+*** POTENTIAL INCOMPATIBILITY with previous alpha/beta releases ***
+
+3/10/99 (new feature) Added a Tcl_GetVersion API to make it easier to
+check the Tcl version and patch level from C. (redman)
+
+3/14/99 (feature change) Tried to unify the TclpInitLibrary path
+routines to look in similar places from Windows to UNIX.  The new
+library search path is: TCL_LIBRARY, TCL_LIBRARY/../tcl8.1, relative
+to DLL (Windows Only) relative to installed executable, relative to
+develop executable, and relative to compiled-in in location (UNIX
+Only.)  This fix included:
+    - Defining a TclpFindExecutable
+    - Moving Tcl_FindExecutable to a common area in tclEncoding.c
+    - Modifying the TclpInitLibraryPath routines.
+(surles)
+
+3/14/99 (feature change) Added hooks for TclPro Wrapper to initialize
+the location of the encoding files and libraries.  This fix included:
+    - Adding the TclSetPerInitScript routine.
+    - Modifying the Tcl_Init routines to evaluate the non-NULL
+      pre-init script.
+    - Adding the Tcl_SetdefaultEncodingDir and Tcl_GetDefaultEncodingDir
+      routines.
+    - Modifying the TclpInitLibrary routines to append the default
+      encoding dir.
+(surles)
+
+3/14/99 (feature change) Test suite now uses "test" namespace to
+define the test procedure and other auxiliary procedures as well as
+global variables.
+    - Global array testConfige is now called ::test::testConfig.
+    - Global variable VERBOSE is now called ::test::verbose, and
+      ::test::verbose no longer works with numerical values.  We've
+      switched to a bitwise character string.  You can set
+      ::test::verbose by using the -verbose option on the Tcl command
+      line.
+    - Global variable TESTS is now called ::test::matchingTests, and
+      can be set on the Tcl command line via the -match option.
+    - There is now a ::test::skipTests variable (works similarly to
+      ::test::matchTests) that can be set on the Tcl command line via
+      the -match option.
+    - The test suite can now be run in any working directory.  When
+      you run "make test", the working directory is nolonger switched
+      to ../tests.
+(hirschl)
+*** POTENTIAL INCOMPATIBILITY ***
+
+--------------- Released 8.1b2, March 16, 1999 ----------------------
+
+3/18/99 (bug fix) Fixed missing/incorrect characters in shift-jis table
+(stanton)
+
+3/18/99 (feature change) The glob command ignores the
+FS_CASE_IS_PRESERVED bit on file systesm and always returns
+exactly what it gets from the system. (stanton)
+*** POTENTIAL INCOMPATIBILITY ***
+
+3/19/99 (new feature) Added support for --enable-64bit.  For now,
+this is only supported on Solaris 7 64bit (SunOS 5.7) using the Sun
+compiler. (redman)
+
+3/23/99 (bug fix) Fixed fileevents and gets on Windows consoles and
+serial devices so that non-blocking channels do not block on partial
+input lines.  (redman)
+
+3/23/99 (bug fix) Added a new Tcl_ServiceModeHook interface.
+This is used on Windows to avoid the various problems that people
+have been seeing where the system hangs when tclsh is running
+outside of the event loop. As part of this, renamed
+TclpAlertNotifier back to Tcl_AlertNotifier since it is public.
+(stanton)
+
+3/23/99 (feature change) Test suite now uses "tcltest" namespace to
+define the test procedure and other auxiliary procedures as well as
+global variables.  The previously chosen "test" namespace was thought
+to be too generic and likely to create conflits.
+(hirschl)
+*** POTENTIAL INCOMPATIBILITY ***
+
+3/24/99 (bug fix) Make sockets thread safe on Windows.
+(redman)
+
+3/24/99 (bug fix) Fix cases where expr would incorrect return
+a floating point value instead of an integer. (stanton)
+
+3/25/99 (bug fix) Added ASCII to big5 and gb2312 encodings.
+(stanton)
+
+3/25/99 (feature change) Changed so aliases are invoked at current
+scope in the target interpreter instead of at the global scope.  This
+was an incompatibility introduced in 8.1 that is being removed.
+(stanton)
+*** POTENTIAL INCOMPATIBILITY with previous beta releases ***
+
+3/26/99 (feature change) --enable-shared is now the default and build
+Tcl as a shared library; specify --disable-shared to build a static Tcl
+library and shell.
+*** POTENTIAL INCOMPATIBILITY ***
+
+3/29/99 (bug fix)  Removed the stub functions and changed the stub
+macros to just use the name without params. Pass &tclStubs into the
+interp (don't use tclStubsPtr because of collisions with the stubs on
+Solaris). (redman)
+
+3/30/99 (bug fix) Loadable modules are now unloaded at the last
+possible moment during Tcl_Finalize to fix various exit-time crashes.
+(welch)
+
+3/30/99 (bug fix) Tcl no longer calls setlocale().  It looks at
+env(LANG) and env(LC_TYPE) instead.  (stanton)
+
+4/1/99 (bug fix) Fixed the Ultrix multiple symbol definition problem.
+Now, even Tcl includes a copy of the Tcl stub library. (redman)
+
+4/1/99 (bug fix) Internationalized the registry package.
+
+4/1/99 (bug fix) Changed the implemenation of Tcl_ConditionWait and
+Tcl_ConditionNotify on Windows.  The new algorithm eliminates a race
+condition and was suggested by Jim Davidson. (welch)
+
+4/2/99 (new apis)  Made various Unicode utility functions public.
+Tcl_UtfToUniCharDString, Tcl_UniCharToUtfDString, Tcl_UniCharLen,
+Tcl_UniCharNcmp, Tcl_UniCharIsAlnum, Tcl_UniCharIsAlpha,
+Tcl_UniCharIsDigit, Tcl_UniCharIsLower, Tcl_UniCharIsSpace,
+Tcl_UniCharIsUpper, Tcl_UniCharIsWordChar, Tcl_WinUtfToTChar,
+Tcl_WinTCharToUtf (stanton)
+
+4/2/99 (feature change) Add new DDE package and removed the Tk
+send command from the Windows version.  Changed DDE-based send
+code into "dde eval" command.  The DDE package can be loaded
+into tclsh, not just wish.  Windows only. (redman)
+
+4/5/99 (bug fix) Changed safe-tcl so that the encoding command
+is an alias that masks out the "encoding system" subcommand.
+(redman)
+
+4/5/99 (bug fix) Configure patches to improve support for
+OS/390 and BSD/OS 4.*. (stanton)
+
+4/5/99 (bug fix) Fixed crash in the clock command that occurred
+with negative time values in timezones east of GMT. (stanton)
+
+4/6/99 (bug fix) Moved the "array set" C level code into a common
+routine (TclArraySet).  The TclSetupEnv routine now uses this API to
+create an env array w/ no elements.  This fixes the bug caused when
+every environ varaible is removed, and the Tcl env variable is
+synched.  If no environ vars existed, the Tcl env var would never be
+created. (surles)
+
+4/6/99 (bug fix) Made the Env module I18N compliant. (surles)
+
+4/6/99 (bug fix) Changed the FindVariable routine to TclpFindVariable,
+that now does a case insensitive string comparison on Windows, and not
+on UNIX. (surles)
+
+--------------- Released 8.1b3, April 6, 1999 ----------------------
+
+4/9/99 (bug fix)  Fixed notifier deadlock situation when the pipe used
+to talk back notifier thread is filled with data.  Found as a result of the
+focus.test for Tk hanging. (redman)
+
+4/13/99 (bug fix) Fixed bug where socket -async combined with
+fileevent for writing did not work under Windows NT. (redman)
+
+4/13/99 (encoding fix) Restored the double byte definition of GB2312
+and added the EUC-CN encoding.  EUC-CN is a variant of GB2312 that
+shifts the characters into bytes with the high bit set and includes
+ASCII as a subset. (stanton)
+
+4/27/99 (bug fix) Added 'extern "C" {}' block around the stub table
+pointer declaration so the stub library can be used from C++. (stanton)
+
+--------------- Released 8.1 final, April 29, 1999 ----------------------
+
+4/22/99 (bug fix) Changed Windows NT socket implementation to avoid
+creating a communication window.  This avoids the problem where the
+system hangs waiting for tclsh to respond to a system-wide synchronous
+broadcast (e.g. if you change system colors). (redman)
+
+4/22/99 (bug fix) Added call to TclWinInit from TclpInitPlatform when
+building a static library since DllMain will not be invoked.  This
+could break old code that explicitly called TclWinInit, but should be
+simpler in the long run. (stanton)
+*** POTENTIAL INCOMPATIBILITY ***
+
+4/23/99 (bug fix) Added support for the koi8-r Cyrillic
+encoding. [Bug: 1771] (stanton)
+
+4/28/99 (bug fix) Changed internal Tcl_Obj usage to avoid freeing the
+internal representation after the string representation has been
+freed.  This makes it easier to debug extensions. (stanton)
+
+4/30/99 (bug fix) Fixed a memory leak in CommandComplete. (stanton)
+
+5/3/99 (bug fix) Fixed a bug where the Tcl_ObjType was not being set
+in a duplicated Tcl_Obj. [Bug: 1975, 2047] (stanton)
+
+5/3/99 (bug fix) Changed Tcl_ParseCommand to avoid modifying eval'ed
+strings that are already null terminated.  [Bug: 1793] (stanton)
+
+5/3/99 (new feature) Applied Jeff Hobbs's string patch which includes
+the following changes:
+    - added new subcommands: equal, repeat, map, is, replace
+    - added -length option to "string compare|equal"
+    - added -nocase option to "string compare|equal|match"
+    - string and list indices can be an integer or end?-integer?.
+    - added optional first and last index args to string toupper, et al.
+See the string.n manual entry for more details about the new string
+features.  [Bug: 1845] (stanton)
+
+5/6/99 (new feature) Added Tcl_UtfNcmp and Tcl_UtfNcasecmp to make Utf
+string comparision easier. (stanton)
+
+5/7/99 (bug fix) Improved OS/390 support. [Bug: 1976, 1997] (stanton)
+
+5/12/99 (bug fix) Changed Windows initialization code to avoid using
+GetUserName system call in favor of the env(USERNAME) variable.  This
+provides a significant startup speed improvement. (stanton)
+
+5/12/99 (bug fix) Replaced the per-interpreter regexp cache with a
+per-thread cache.  Changed the Regexp object to take advantage of this
+extra cache.  Added a reference count to the TclRegexp type so regexps
+can be shared by multiple objects.  Removed the per-interp regexp cache
+from the interpreter.  Now regexps can be used with no need for an
+interpreter. This set of changes should provide significant speed
+improvements for many Tcl scripts.  [Bug: 1063] (stanton)
+
+5/14/99 (bug fix) Durining initialization on Unix, Tcl now extracts the
+encoding subfield from the LANG/LC_ALL environment variables in cases
+where the locale is not found in the built-in locale table.  It also
+attempts to initialize the locale subsystem so X11 is happy. [Bug: 1989]
+(stanton)
+
+5/14/99 (bug fix) Applied the patch to fix 100-year and 400-year
+boundaries in leap year code, from Isaac Hollander.  [Bug: 2066] (redman)
+
+5/14/99 (bug fix) Fixed a crash caused by a failure to reset the result
+before evaluating the test expression in an uncompiled for
+statement. (stanton)
+
+5/18/99 (bug fix) Modified initialization code on Windows to avoid
+inherenting closed or invalid channels.  If the standard input is
+anything other than a console, file, serial port, or pipe, then we fall
+back to the standard Tk window console. (stanton)
+
+5/19/99 (bug fix) Added an extern "C" block around the entire tcl.h
+header file to avoid C++ linkage issues. (redman)
+
+5/19/99 (new feature) Applied Jeff Hobb's patch to add
+Tcl_StringCaseMatch to support case insensitive glob style matching and
+Tcl_UniCharIs* character classification functions. (stanton)
+
+5/20/99 (bug fix) Added the directory containing the executuble and the
+../lib directory relative to that to the auto_path variable. (redman)
+
+--------------- Released 8.1.1, May 25, 1999 ----------------------
+
+5/21/99 (bug fix) Fixed launching command.com on Win95/98, no longer
+hangs. [Bug: 2105] (redman)
+
+5/28/99 (bug fix) Fixed bug where dde calls were being passed an
+invalid dde handle. [Bug: 2124] (stanton)
+
+6/1/99  (bug fix) Small configure.in patches. [Bug: 2121] (stanton)
+
+6/1/99  (bug fix) Applied latest regular expression patches to fix an
+infinite loop bug and add support for testing whether a string could
+match with additional input. [Bug: 2117] (stanton)
+
+6/2/99  (bug fix) Fixed incorrect computation of relative ordering in
+Utf case-insensitive comparison. [Bug: 2135] (stanton)
+
+6/3/99  (bug fix) Fxied bug where string equal/compare -nocase
+reported wrong result on null strings. [Bug: 2138] (stanton)
+
+6/4/99  (new feature) Windows build now uses Cygwin tools plus GNU
+make and autoconf to build static/dynamic and debug/nodebug. (stanton)
+
+6/7/99  (new feature) Optimized string index, length, range, and
+append commands. Added a new Unicode object type. (hershey)
+
+6/8/99  (bug fix) Rolled back Windows socket driver to 8.1.0
+version. (stanton)
+
+6/9/99  (new feature) Added Tcl_RegExpMatchObj and Tcl_RegExpGetInfo
+to public Tcl API, these functions are needed by Expect.  Changed
+tools/genStubs.tcl to always write output in LF mode. (stanton)
+
+6/14/99 (new feature) Merged string and Unicode object types.  Added
+new public Tcl API functions:  Tcl_NewUnicodeObj, Tcl_SetUnicodeObj,
+Tcl_GetUnicode, Tcl_GetUniChar, Tcl_GetCharLength, Tcl_GetRange,
+Tcl_AppendUnicodeToObj. (hershey)
+
+6/16/99 (new feature) Changed to conform to TEA specification, added
+tcl.m4 and aclocal.m4 macro libraries for configure.  (wart)
+
+6/17/99 (new feature) Added new regexp interfaces: -expanded, -line,
+-linestop, and -lineanchor switches.  Renamed Tcl_RegExpMatchObj to
+Tcl_RegExpExecObj and added new Tcl_RegExpMatchObj that is equivalent
+to Tcl_RegExpMatch.  Added public macros for regexp flags.  Added
+REG_BOSONLY flag to allow Expect to iterate through a string and only
+find matches that start at the current position within the
+string. (stanton)
+
+6/21/99 (bug fix) Fixed memory leak in TclpThreadCreate where thread
+attributes were not being released.  [Bug: 2254] (stanton)
+
+6/23/99 (new feature) Updated Unicode character tables to reflect
+Unicode 2.1 data. (stanton)
+
+6/25/99 (new feature) Fixed bugs in non-greedy quantifiers for regular
+expression code. (stanton)
+
+6/25/99 (new feature) Added initial implementation of new Tcl test
+harness package.  Modified test files to use new tcltest package.
+(jenn)
+
+6/26/99 (new feature) Applied patch from Peter Hardie to add poke
+command to dde and changed the dde package version number to
+1.1. (redman)
+
+6/28/99 (bug fix) Applied patch from Peter Hardie to fix problem in
+Tcl_GetIndexFromObj() when the key being passed is the empty string.
+[Bug: 1738] (redman)
+
+6/29/99 (new feature) Added options to tcltest package: -preservecore,
+-limitconstraints, -help, -file, -notfile, and flags.  (jenn)
+
+7/3/99  (new feature) Changed parsing of variable names to allow empty
+array names.  Now "$(foo)" is a variable reference.  Previously you
+had to use something line $::(foo), which is slower.  This change was
+requested by Jean-Luc Fontaine for his STOOOP package. (welch)
+
+7/3/99  (new feature) Added Tcl_SetNotifier (public API) and
+associated hook points in the notifiers to be able to replace the
+notifier calls at runtime. The Xt notifier and test program use this
+hook.  (welch)
+
+7/3/99  (new feature) Added a new variant of the "Trf core patch" from
+Andreas Kupries that adds new C APIs Tcl_StackChannel,
+Tcl_UnstackChannel, and Tcl_GetStackedChannel.  This allows the Trf
+extension to work without applying patches to the Tcl core. (welch)
+
+7/6/99  (new feature) Added -timeout option to http.tcl to handle
+timeouts that occur during connection attempts to hosts that are
+down. (welch)
+
+7/6/99  (bug fix) Applied new implementation of the Windows serial
+port driver from Rolf Schroedter that fixes reading only one byte from
+the port at a time.  Uses polling every 10ms to implement
+fileevents. [Bug: 1980 2217] (redman)
+
+7/8/99  (bug fix) Applied fix for bug in DFA state caching under
+lookahead conditions (regular expressions).  [Bug: 2318] (stanton)
+
+7/8/99  (bug fix) Fixed bug in string range bounds checking
+code. (stanton)
+
+--------------- Released 8.2b1, July 14, 1999 ----------------------
+
+7/16/99 (bug fix) Added Tcl_SetNotifier to stub table. [Bug: 2364]
+Added check for Alpha/Linux to correct the IEEE  floating point flag,
+patch from Don Porter. (redman)
+
+7/20/99 (bug fix) Merged 8.0.5 code to handle tcl_library properly,
+also fixed a bug that caused TCL_LIBRARY to be ignored. (hershey)
+
+7/21/99 (bug fix) Implemented modified socket driver for Windows that
+uses a thread to manage the socket event window.  Code works the same
+on all supported versions of Windows and was based on original 8.1.0
+code.  [Bug: 2178 2256 2259 2329 2323 2355] (redman)
+
+7/21/99 (new feature) Applied patch from Rolf Schroedter to add
+-pollinterval option to fconfigure for Windows serial ports.  Allows
+the maxblocktime to be modified to control how often serial ports are
+checked for fileevents.  Also added documentation for \\.\comX
+notation for opening serial ports on Windows.  (redman)
+
+7/21/99 (bug fix) Changed APIs in stub tables to use "unsigned long"
+instead of the platform-specific "size_t", primarily after SunOS 4
+users could no longer compile. (redman)
+
+7/22/99 (bug fix) Fixed crashing during "array set a(b) {}".
+[Bug: 2427] (redman)
+
+7/22/99 (bug fix) The install-sh script must be given execute
+permissions prior to running.  [Bug: 2413] (redman)
+
+7/22/99 (bug fix) Applied patch from Ulrich Ring to remove ANSI-style
+prototypes in the code.  [Bug: 2391] (redman)
+
+7/22/99 (bug fix) Added #if blocks around #includes of sys/*.h header
+files, to allow an extension author on Windows to use the MetroWerks
+compiler. [Bug: 2385] (redman)
+
+7/22/99 (bug fix) Fixed running the safe.test test suite, one change
+to the Windows Makefile.in to fix paths and another in safe.test to
+check for the tcl_platform(threaded) variable properly. (redman)
+
+7/22/99 (bug fix) Fixed hanging in new Win32 socket driver with
+threads enabled. (redman)
+
+7/26/99 (bug fix) Fixed terminating of helper threads by holding any
+mutexes from the primary thread while waiting for the helper thread to
+terminate.  Fixes dual-CPU WinNT hangs, only one rare sporadic hang
+that still exists with dual-CPU WinNT.  Also fixed test cases so that
+they would not depend as much on timing for dual-CPU WinNT. (redman)
+
+7/27/99 (bug fix) Some test suite cleanup. (jenn)
+
+7/29/99 (bug fix) Applied patch to fix typo in .SH NAME line in
+doc/Encoding.n [Bug: 2451].  Applied patch to avoid linking pack.n to
+pack-old.n [Bug: 2469]. Patches from Don Porter. (redman)
+
+7/29/99 (bug fix) Allow tcl to open CON and NUL, even for redirection
+of std channels.  [Bug: 2393 2392 2209 2458] (redman)
+
+7/30/99 (bug fix) Applied fixed Trf patch from Andreas Kupries.
+[Bug: 2386] (hobbs)
+
+7/30/99 (bug fix) Fixed bug in info complete. [Bug: 2383 2466] (hobbs)
+
+7/30/99 (bug fix) Applied patch to fix threading on Irix 6.5, patch
+provided by James Dennett.  [Bug: 2450] (redman)
+
+7/30/99 (bug fix) Fixed launching of 16bit applications on Win9x from
+wish.  The command line was being primed with tclpip82.dll, but it was
+ignored later.
+
+7/30/99 (bug fix) Added functions to stub table, patch provided by Jan
+Nijtmans. [Bug: 2445] (hobbs)
+
+8/1/99  (bug fix) Changed Windows socket driver to terminate threads
+by sending a message to the window rather than calling
+TerminateThread(), which seems to leak about 4k from the helper
+thread's stack space. (redman)
+
+--------------- Released 8.2b2, August 5, 1999 ----------------------
+
+8/4/99 (bug fix) Applied patches supplied by Henry Spencer to greatly
+enhance performance of certain classes of regular expressions.
+[Bug: 2440 2447] (stanton)
+
+8/5/99 (doc change) Made it clear that tcl_pkgPath was not set for
+Windows. [Bug: 2455] (hobbs)
+
+8/5/99 (bug fix) Fixed reference to bytes that might not be null
+terminated in tclLiteral.c. [Bug: 2496] (hobbs)
+
+8/5/99 (bug fix) Fixed typo in http.tcl. [Bug: 2502] (hobbs)
+
+8/9/99 (bug fix) Fixed test suite to handle larger integers
+(64bit). Patch from Don Porter. (hobbs)
+
+8/9/99 (documentation fix) Clarified Tcl_DecrRefCount docs
+[Bug: 1952]. Clarified array pattern docs [Bug: 1330]. Fixed clock docs
+[Bug: 693]. Fixed formatting errors [Bug: 2188 2189]. Fixed doc error
+in tclvars.n [Bug: 2042]. (hobbs)
+
+8/9/99 (bug fix) Fixed path handling in auto_execok [Bug: 1276] (hobbs)
+
+8/9/99 (internal api change) Removed the TclpMutexLock and TclpMutexUnlock
+APIs and added a new exported api, Tcl_GetAllocMutex. These APIs are all for
+the mutex used in the simple memory allocators.  By making this change
+we are able to substitute different implementations of the thread-related
+APIs without having to recompile the Tcl core. (welch)
+
+8/9/99 (new C API) Tcl_GetChannelNames returns a list of open channel
+names in the interpreter result.  Still no Tcl-level version of this,
+but server-like applications can use this to clean up files without
+deleting interpreters. (welch)
+
+8/9/99 (bug fix) Traces were not firing on "info exists", which used to
+happen in Tcl 7.6 and earlier. An "info exists" now fires a read trace,
+if defined.  This makes it possible to fully implement variables that
+are defined via traces. (welch)
+
+8/10/99 (bug fix) Fixed Brent's changes so that they work on
+Windows. (redman)
+
+--------------- Released 8.2b3, August 11, 1999 ----------------------
+
+8/12/99 (Mac) Rearrange projects in tclMacProjects.sea.hqx so that the
+build directory is separate from the sources. (Jim Ingham)
+
+8/12/99 (bug fix) Fixed bug in Tcl_EvalEx where the termOffset was not
+being updated in cases where the evaluation returned a non TCL_OK
+error code. [Bug: 2535] (stanton)
+
+--------------- Released 8.2.0, August 17, 1999 ----------------------
+
+9/21/99 (config fixes) fixed several AIX configuration issues.  gcc and
+threading may still cause problems on AIX. (hobbs)
+
+9/21/99 (bug fix) fixed expr double-eval problem. [Bug: 732] (hobbs)
+
+9/21/99 (bug fix) fixed static buffer overflow problem. [Bug: 2483] (hobbs)
+
+9/21/99 (bug fix) fixed end-int linsert interpretation. [Bug: 2693] (hobbs)
+
+9/21/99 (bug fix) fixed bug when setting array in non-existent
+namespace. [Bug: 2613] (hobbs)
+
+--- Released 8.2.1, October 04, 1999 --- See ChangeLog for details ---
+
+10/30/99 (feature enhancement) new regexp engine from Henry Spencer
+was patched in - should greatly reduce stack space usage. (spencer)
+
+10/30/99 (bug fix) fixed Purify reported memory leaks in findexecutable
+test command, TclpCreateProcess on Unix, in handling of C environ array,
+and in testthread code.  No more known (reported) mem leaks for Tcl
+built using gcc on Solaris 2.5.1.  Also none reported for Tcl on NT
+(using Purify 6.0). (hobbs)
+
+10/30/99 (bug fix) fixed improper bytecode handling of
+'eval {set array($unknownvar) 5}' (also for incr) (hobbs)
+
+10/30/99 (bug fix) fixed event/io threading problems by making
+triggerPipe non-blocking (nick kisserbeth)
+
+10/30/99 (bug fix) fixed Tcl_AppendStringsToObjVA and Tcl_AppendResultVA
+to only	iterates once over the va_list (avoiding non-portable memcpy).
+(joe english, hobbs)
+
+10/30/99 (bug fix) removed savedChar trick in tclCompile.c that appeared
+to be causing a segv when the literal table was released.
+[Bug: 2459, 2515] (David Whitehouse)
+
+10/30/99 (bug fix) fixed [string index] to return ByteArrayObj
+when indexing into one (test case string-5.16) [Bug: 2871] (hobbs)
+
+10/30/99 (bug fix) fixes for mac UTF filename handling (ingham)
+
+--- Released 8.2.2, November 04, 1999 --- See ChangeLog for details ---
+
+11/19/99 (feature enhancement) bug fixes for http package as well as
+patch required by TLS (SSL) extension that adds http::(un)register
+and -type to http::geturl.  Up'd http pkg version to 2.2.
+
+11/19/99 (bug fix) removed extra decr of numLevels in Tcl_EvalObjEx
+that could cause seg fault (mjansen@wendt.de)
+
+11/19/99 (bug fixes) numerous minor big fixes, including correcting the
+installation of the koi8-r encoding and tcltest1.0 on Windows.
+
+11/30/99 (bug fix) fixes scan where %[..] didn't match anything
+
+11/30/99 (bug fix) fixed setting of isNonBlocking flag in PipeBlockModeProc
+so you can now close a non-blocking channel without waiting.
+
+11/30/99 (bug work-around) prevented the unloading of DLLs for Unix in
+TclFinalizeLoad.  This stops the seg fault on exit that some users would
+see (ie with oratcl) when using DLLs that do nasty things like register
+atexit handlers.
+
+12/07/99 (bug fix) fixes for 'expr + {[incr]}' and 'expr + {[error]}'
+cases (different causes).
+
+--- Released 8.2.3, December 16, 1999 --- See ChangeLog for details ---
+
+1999-09-14 (feature enhancement) added -start switch to regexp and regsub.
+
+1999-09-15 (feature enhancement) add 'array unset' command.
+
+1999-09-15 (feature enhancement) rewrote runtime libraries to use new
+string functions
+
+1999-08-18 (feature enhancement) added 'file channels' command, along with
+Tcl_GetChannelNames(Ex) public C APIs.
+
+1999-10-19 (feature enhancement) enhanced tcltest package
+
+1999-09-16 (feature enhancement) added -milliseconds switch to 'clock clicks'
+
+1999-10-28 (feature enhancement) added support for inline 'scan'
+
+1999-10-28 (feature enhancement) added support for touch functionality by
+extendeding 'file atime' and 'file mtime' to take an optional time argument
+
+1999-11-24 (feature enhancement) added 'fconfigure $sock -lasterror'
+command to Windows to query the last error received on a serial socket.
+
+1999-11-30 (bug fix) fixed handling of %Z on NT for timezones that don't
+have DST
+
+1999-12-03 (feature enhancement) improved error message in bad octal cases
+and improper use of comments. (hobbs)
+
+1999-12-07 (bug fix) fixed Tcl_ScanCountedElement to not step
+beyond the end of the counted string
+
+1999-12-09 (feature enhancement) removed all references to 16 bit
+compatibility code for Windows (hobbs)
+
+1999-12-10 (bug fix) removed check for vfork - Tcl now uses only fork in
+exec. (hobbs)
+
+1999-12-10 (optimization) changed Tcl_ConcatObj to return a list
+object when it receives all pure list objects as input (used by 'concat'),
+added optimizations in Tcl_EvalObjEx for pure list case, and optimized
+INST_TRY_CVT_TO_NUMERIC in TclExecuteByteCode for boolean objects.
+(oakley, hobbs)
+
+1999-12-12 (feature enhancement) enhanced glob command with -type, -path,
+-directory and -join switches. (darley, hobbs)
+
+1999-12-21 (bug fix) changed CreateThread to _beginthreadex and
+ExitThread to _endthreadex to prevent 4K mem leak (gravereaux)
+
+1999-12-21 (bug fix) fixed applescript for I18N
+
+1999-12-21 (feature enhancement) added -unique option to lsort (hobbs)
+
+1999-12-21 (bug fix) changed thread ids to longs (for 64bit systems)
+
+--- Released 8.3b1, December 22, 1999 --- See ChangeLog for details ---
+
+2000-01-10 (feature enhancement) clock scan now supports the common
+ISO 8601 date/time formats.  See docs for details. (melski)
+
+2000-01-10 (bug fix) prevented \ooo substitution from accepting
+non-octal digits [Bug: 3975] (hobbs)
+
+2000-01-11 (bug fix) fixed improper handling of DST by clock when
+using relative times (like "1 month" or "tomorrow"). (melski)
+
+2000-01-12 (bug fix) improved build support for Tru64 v5, NetBSD
+and Reliant Unix (hobbs)
+
+2000-01-12 (bug fix) made imported commands also import their
+compile procedure (duffin)
+
+2000-01-12 (bug fix) fixed 'info procs ::namesp::*' behavior to return
+procs in a namespace (dejong)
+
+2000-01-12 (feature enhancement) added support for setting permissions
+symbolicly (like chmod) in [file attributes $file -permissions ...] (schoebel)
+
+2000-01-13 (bug fix) fixed lsort -dictionary problem when sorting
+characters between 'Z' and 'a' (flawed upper/lower comparison logic) (melski)
+
+--- Released 8.3b2, January 13, 2000 --- See ChangeLog for details ---
+
+2000-01-14 (feature enhancement) clock format %Q added, clock scan updated
+
+2000-01-20 (bug fix) corrected complex array elem compiling (Spjuth)
+
+2000-01-20 (bug fix) made [info body] always return a string type arg,
+to prevent possible misuse of bytecodes in the wrong context (hobbs)
+
+2000-01-20 (bug fixes) several fixes to variable handling to prevent
+possible crashes, and further definition of correct behavior (melski)
+
+2000-01-25 (bug fixes) improved QNX, Ultrix and OSF1 (Tru64) config and
+compatibility (edge, furukawa)
+
+2000-01-25 (bug fix) fixed mem leak when calling lsort with a bad -command
+argument (hobbs)
+
+2000-01-27 (feature enhancement) package mechanism overhaul: changed
+behavior of pkg_mkIndex to do -direct by default, added -lazy option.
+Fixed pkg_mkIndex to handle odd proc names and auto_mkIndex to use platform
+independent file paths.  Other fixes for odd package quirks.  Added
+::pkg namespace and ::pkg::create helper function. (melski)
+
+2000-02-01 (bug fix) fixed problem where http POST would send one extra
+newline (vasiljevic)
+
+2000-02-02 (feature enhancement) added docs for new regexp -inline and
+-all switches. (hobbs)
+
+2000-02-08 (bug fix) corrected handling of "next monthname" in clock scan
+(melski)
+
+2000-02-09 (bug fix) restored Mac source to build readiness and prevented
+mac panic from an error when closing an async socket (steffen, ingham)
+
+2000-02-10 (feature enhancement) improved error reporting for failed
+loads on Windows (dejong, hobbs)
+
+--- Released 8.3.0, February 10, 2000 --- See ChangeLog for details ---
+
+2000-03 (bug fixes, feature enhancement) overhaul of http package for
+proper handling of async callbacks (new options), version is now at 2.3
+(tamhankar, welch)
+
+2000-03 (performance enhancement) speedup in Windows filename handling (newman)
+and ==/!= empty string in exprs. (hobbs)
+
+2000-03-27 (bug fix) added uniq'ing test to namespace export list to
+prevent unnecessary mem growth (hobbs)
+
+2000-03-29 (bug fix) fixed mem leak when repeatedly sourcing the same
+bytecompiled (tbc) code repeatedly across different interpreters (hobbs)
+
+2000-03-29 (config enhancement) improved build support for gcc/mingw on
+Windows (nijtmans, hobbs) and added RPM target (melski)
+
+2000-03-31 (bug fix) corrected data encoding problem when using
+"exec << $data" construct (melski)
+
+2000-04 (feature enhancement) overhaul of threading mechanism to better
+support tcl level thread command (new APIs Tcl_ConditionFinalize,
+Tcl_MutexFinalize, Tcl_CreateThread, etc, all docs in Thread.3).
+(kupries, graveraux)
+This enables the tcl level thread extension. (welch)
+
+2000-04-10 (bug fix) fixed infinite loop case in regexp -all (melski)
+
+2000-04-13 (config enhancement) added support for --enable-64bit-vis
+Sparc target. (hobbs)
+
+2000-04-18 (bug fix) moved tclLibraryPath to thread-local storage to fix
+possible race condition on MP machines (hobbs)
+
+2000-04-18 (config enhancement) added MacOS X build target and
+tclLoadDyld.c dl type. (sanchez)
+
+2000-04-23 (bug fix) several Mac socket fixes (ingham)
+
+2000-04-24 (bug fix) fixed hang in threaded Unix case when backgrounded
+exec process was running (dejong)
+
+--- Released 8.3.1, April 26, 2000 --- See ChangeLog for details ---
+
+2000-04-26 (doc fix) updated/added documentation for many API's and
+commands (melski)
+
+2000-05-02 (feature enhancement) added support for joinable threads;
+extended API's for channels to allow channels to move between threads
+(kupries)
+
+2000-05-02 (feature enhancement) changed error return for procedures
+with incorrect args to be like the Tcl_WrongNumArgs API, with a "wrong
+# args: ..." message printed, with an args list (hobbs)
+
+2000-05-08 (feature enhancement) added [array statistics] command
+
+2000-05-08 (performance enhancement) rewrote Tcl_StringCaseMatch
+algorithm for better performance; this affects the [string match]
+command; added "eq" and "ne" operands to expr, for testing
+string equality and inequality (hobbs)
+
+2000-05-09 (feature enhancement) extended [lsearch] to support sorted
+list searches and typed list searches (melski)
+
+2000-05-10 (feature enhancement) added [namespace exists] command
+(darley)
+
+2000-05-18 (build enhancement) added support for mingw compile env and
+cross-compiling (dejong)
+
+2000-05-18 (bug fix) corrected clock grammar to properly handle the
+"ago" keyword when it follows multiple relative unit specifiers
+(melski)
+
+2000-05-22 (compile fix) type cast cleanups (dejong)
+
+2000-05-23 (performance enhancement) added byte-compiled
+implementation of [return] command and [string] command (melski)
+
+2000-05-26 (performance enhancement) extended byte-compiled [string]
+command with support for [string compare/index/match] (hobbs)
+
+2000-05-27 (feature enhancement) added ability to set [info script]
+return value ([info script ?newFileName?]) (welch)
+
+2000-05-31 (feature enhancement) added support for regexp and exact
+pattern matching for [array names] (gazetta)
+
+2000-05-31 (feature enhancement) added -nocomplain and -- flags to
+[unset] to allow for silent unset operation (hobbs)
+
+--- Released 8.4a1, June 6, 2000 --- See ChangeLog for details ---
+
+2000-05-29 (bug fix) corrected resource cleanup in http error cases.
+Improved handling of error cases in http. (tamhankar)
+
+2000-07 (feature rewrite) complete rewrite of the Tcl IO channel subsystem
+to correct problems (hangs, core dumps) with the initial stacked channel
+implementation.  The new system has many more tests for robustness and
+scalability.  There are new C APIs (see Tcl_CreateChannel), but only
+stacked channel drivers are affected (ie: TLS, Trf, iogt).  The iogt
+extension has been added to the core test code to test the system.
+(hobbs, kupries)
+	**** POTENTIAL INCOMPATABILITY ****
+
+2000-07 (build improvements) cleanup of the makefiles and configure scripts
+to correct support for building under gcc for Windows. (dejong)
+
+2000-08-07 (bug fix) corrected sizeof error in Tcl_GetIndexFromObjStruct.
+(perkins)
+
+2000-08-07 (bug fix) correct off-by-one error in HistIndex, which was
+causing [history redo] to start its search at the wrong event index. (melski)
+
+2000-08-07 (bug fix) corrected setlocale calls for XIM support and locale
+issues in startup. (takahashi)
+
+2000-08-07 (bug fix) correct code to handle locale specific return values
+from strftime, if any. (wagner)
+
+2000-08-07 (bug fix) tweaked grammar to properly handle the "ago" keyword
+when it follows multiple relative unit specifiers, as in
+"2 days 2 hours ago". (melski)
+
+2000-08-07 (doc fixes) numerous doc fixes to correct SEE ALSO and NAME
+sections. (english)
+
+2000-08-07 (bug fix) new man pages memory.n, TCL_MEM_DEBUG.3, Init.3 and
+DumpActiveMemory.3. (melski)
+
+--- Released 8.3.2, August 9, 2000 --- See ChangeLog for details ---
+
+2000-06 thru 2000-11 (build improvements) Added support for mingw (gcc on
+Windows), AIX-5 and Win64 builds (dejong, hobbs)
+
+2000-06-23 (feature enhancement) ability to use Tcl_Obj *s as hash keys (duffin)
+
+2000-06-29 (new features) added [mcmax] and [mcmset] and extended [unknown] in
+msgcat package (duperval, krone, nelson)
+=> msgcat 1.1
+
+2000-08 thru 2000-09 added tclPlatDecls.h to default install (melski, hobbs)
+
+2000-08-24 (new feature) Enhanced trace syntax to add:
+	trace {add|remove|list} {variable|command} name ops command
+(darley, melski)
+
+2000-09-06 (cross-platform feature) Set ^Z (\32) as default EOF char. (hobbs)
+
+2000-09-07 partial fix for bug 2460 to prevent exec mem leak on Windows for the
+common case (gravereaux)
+
+2000-09-14 Improved string allocation growth for large strings (hintermayer,
+melski)
+
+2000-09-14 New non-panic'ing mem allocation functions Tcl_AttemptAlloc,
+Tcl_AttemptRealloc, Tcl_AttemptSetObjLength (melski)
+
+2000-09-20 (new features) completely new, enhanced syntax in tcltest package.
+Backwards compatable with tcltest v1. (hom)
+=> tcltest 2.0
+
+2000-09-27 (bug fix) fixed a bug introduced by a partial fix in 8.3.2 that
+didn't set nonBlocking correctly when resetting the flags for the write
+side (mem leak) Correct mem leak in channels when statePtr was released
+(hobbs)
+
+2000-09-29 (bug fix) corrected reporting of space parity on Windows (Eason)
+
+2000-10-06 (bug fix) corrected [file channels] to only return channels in
+the current interpreter (hobbs)
+
+2000-10-20 (performance enhancement) call stat only when necessary in 'glob' to
+speed up command significantly in base cases (hobbs)
+
+2000-10-27 Fixed mem leak in Tcl_CreateChannel. Re-purified core via test
+suites.  (hobbs)
+
+2000-10-30 (new feature) add "ja_JP.eucJP" map to "euc-jp" encoding (takahashi)
+
+2000-11-01 (mem leak) Corrected excessive mem use of info exists on a
+non-existent array element (hobbs)
+
+2000-11-02 (bug fix) Corrected sharing of tclLibraryPath in threaded
+environment (gravereaux)
+
+2000-11-03 (new feature) Tcl_SetMainLoop enables defining an event loop for
+tclsh.  This enables Tk as a truly loadable package. (hobbs)
+
+--- Released 8.4a2, November 3, 2000 --- See ChangeLog for details ---
+
+2000-09-27 (bug fix) fixed a bug introduced by a partial fix in 8.3.2 that
+didn't set nonBlocking correctly when resetting the flags for the write
+side (mem leak) Correct mem leak in channels when statePtr was released
+(hobbs)
+
+2000-09-29 (bug fix) corrected reporting of space parity on Windows (Eason)
+
+2000-10-06 (bug fix) corrected [file channels] to only return channels in
+the current interpreter (hobbs)
+
+2000-10-20 (performance enhancement) call stat only when necessary in 'glob' to
+speed up command significantly in base cases (hobbs)
+
+2000-11-01 (mem leak) Corrected excessive mem use of info exists on a
+non-existent array element (hobbs)
+
+2000-11-02 (bug fix) Corrected sharing of tclLibraryPath in threaded
+environment (gravereaux)
+
+2000-11-23 (mem leak) fixed potential memory leak in error case of lsort
+(fellows)
+
+2000-12-09 (feature enhancement) changed %o and %x to use strtoul instead
+of strtol to correctly preserve scan<>format conversion of large integers
+(hobbs)
+Fixed handling of {!<boolean>} in expressions (hobbs, fellows)
+
+2000-12-14 (feature enhancement) improved (s)rand for 64-bit platforms
+(porter)
+
+2001-01-04 (bug fix) corrected parsing of $tcl_libPath at startup on
+Windows (porter)
+
+2001-01-30 (bug fix) Fixed possible hangs in fcopy. (porter)
+
+2001-02-15 (performance enhancement) improved efficiency of [string split]
+(fellows)
+
+2001-03-13 (bug fix) Correctly possible memory corruption in string map {}
+$str (fellows)
+
+2001-03-29 (bug fix) prevent potential race condition and security leak in
+tmp filename creation on Unix. (max)
+Fixed handling of timeout for threads (corrects excessive CPU usage issue
+for Tk on Unix in threaded Tcl environment). (ruppert)
+
+2001-03-30 (bug fix) corrected Windows memory error on exit (wu)
+Fixed race condition in readability of socket on Windows.
+
+2001-04-03 (doc fixes) numerous doc corrections and clarifications.
+Update of READMEs.
+
+2001-04-04 (build improvements) redid Mac build structure (steffen)
+Corrected IRIX-5* configure (english).  Added support for AIX-5 (hobbs).
+Added support for Win64 (hobbs).
+
+--- Released 8.3.3, April 6, 2001 --- See ChangeLog for details ---
+
+2000-11-23 (new feature)[TIP 7] higher resolution timer on Windows (kenny)
+
+2001-01-18 (new feature) Tcl_InitHashTableEx renamed to Tcl_InitCustomHashTable
+(kupries)
+
+2001-03-30 (new feature)[TIP 10] support for thread-aware/hot channels (kupries)
+
+2001-04-06 (new feature)[219280] auto-loading hidden in ::errorInfo (porter)
+
+2001-04-07 (bug fix)[406709] corrected panic when extra items left on the
+byte compiler execution stack (sofer)
+
+2001-04-09 (bug fix)[219136,232558] improved use of thread-safe functions in
+unix time commands (kenny)
+
+2001-04-24 (new feature)[TIP 27] started CONST-ification of the Tcl APIs (kenny)
+
+2001-05-03 (new feature) [auto_import] now matches patterns like
+[namespace import], not like [string match] (porter)
+        **** POTENTIAL INCOMPATABILITY ****
+
+2001-05-07 (new feature)[416643] distinct srand() seed per interp (sofer)
+
+2001-05-15 (new feature) new Tcl_GetUnicodeFromObj API (hobbs)
+
+2001-05-16 (performance enhancement) byte-compiled versions of [lappend],
+[append] simple cases (hobbs)
+
+2001-05-23 (new feature) added ISO-8859-15 and koi8-u encodings, updated other
+encoding tables based on http://www.unicode.org/Public/MAPPINGS/ (kuhn)
+
+2001-05-27 (new feature) updated to Unicode 3.1.0 data set (still using 16
+bits for Tcl_UniChar though) (hobbs)
+
+2001-05-30 (new feature)[TIP 15] Tcl_GetMathFuncInfo, Tcl_ListMathFuncs,
+Tcl_InfoObjCmd, InfoFunctionsCmd APIs (fellows)
+
+2001-06-08 (bug fix,feature enhancement)[219170,414936] all Tcl_Panic
+definitions brought into agreement (porter)
+
+2001-06-12 (bug fix)[219232] regexp returned non-matching sub-pairs to have
+index pair {-1 -1} (fellows)
+
+2001-06-27 (bug fix)[217987] corrected backslash substitution of non-ASCII
+characters.  (hobbs, riefenstahl)
+
+2001-06-28 (bug fix)[231259] failure to re-compile after cmd shadowing (sofer)
+
+2001-07-02 (bug fix)[227512] corrected [concat] treatment of UTF-8 strings
+(hobbs, barras)
+
+2001-07-12 (new feature)[TIP 36] Tcl_SubstObj API (fellows)
+
+2001-07-16 (bug fix) corrected thread-enabled pipe closing on Windows
+(hobbs, jsmith)
+
+2001-07-18 (bug fix)[427196] corrected memory overwrite error when buffer size
+of a channel is changed after channel use has already begun (kupries, porter)
+
+2001-07-31 (new feature)[TIP 17] TclFS* APIs provide new virtual file
+system.  This includes the addition of 'file normalize', 'file system',
+'file separator' and 'glob -tails' (darley)
+
+2001-08-06 (bug fix) removed use of tmpnam in TclpCreateTempFile on Unix (lim)
+
+ * improved build support for IRIX, GNU HURD, Mac OS 9 and OS X
+
+ * configure scripts revamped for better support of cygwin and gcc on
+   Windows (mdejong)
+
+ * corrected several minor errors noted by Purify (hobbs)
+
+--- Released 8.4a3, August 6, 2001 --- See ChangeLog for details ---
+
+2001-06-27 (bug fix)[217987] corrected backslash substitution of non-ASCII
+characters.  (hobbs, riefenstahl)
+
+2001-06-28 (bug fix)[231259] failure to re-compile after cmd shadowing (sofer)
+
+2001-07-02 (bug fix)[227512] corrected [concat] treatment of UTF-8 strings
+(hobbs, barras)
+
+2001-07-16 (bug fix) corrected thread-enabled pipe closing on Windows
+(hobbs, jsmith)
+
+2001-07-18 (bug fix)[427196] corrected memory overwrite error when buffer size
+of a channel is changed after channel use has already begun (kupries, porter)
+
+2001-08-06 (bug fix)[442665] corrected object reference counting in [gets]
+(jikamens)
+
+2001-08-06 (new feature) added GNU (HURD) configuration target. (brinkmann)
+
+2001-08-07 (bug fix)[406709] corrected panic when extra items left on the
+byte compiler execution stack (see test foreach-5.5) (sofer, tallneil, jstrot)
+
+2001-08-08 (new features) updated packages msgcat 1.1.1, opt 0.4.3,
+tcltest 1.0.1, dependencies checked (porter)
+
+2001-08-20 (new feature)[452217] http 2.3.2: include port number in Host: header
+to comply with HTTP/1.1 spec (RFC 2068)  (hobbs, tils)
+
+2001-08-23 (new feature) added QNX-6 build support (loverso)
+
+2001-08-23 (bug fix) corrected handling of spaces in path name passed to
+[exec] on Windows (kenpoole)
+
+2001-08-24 (bug fix) corrected [package forget] stopping on non-existent
+package (porter)
+
+2001-08-24 (bug fix) corrected construction of script library search path
+relative to executable (porter)
+
+2001-08-24 (bug fix) [auto_import] now matches patterns like
+[namespace import], not like [string match] (porter)
+        **** POTENTIAL INCOMPATABILITY ****
+
+2001-08-27 (new feature) added Tcl_SetMainLoop() to enable loading Tk as a
+true package (hobbs)
+
+2001-08-30 (bug fix) build support for Crays (andreasen)
+
+2001-09-01 (bug fix) rewrite of Tcl_Async* APIs to better manage thread
+cleanup  (gravereaux)
+
+2001-09-06 (new feature) http 2.4: honor the Content-encoding and charset
+parameters; add -binary switch for forcing the issue (hobbs, saoukhi, orwell)
+=> http 2.4
+
+2001-09-06 (performance enhancement) rewrite of file I/O flush management on
+Windows.  Approximately 100x speedup for some operations. (kupries, traum)
+
+2001-09-10 (bug fix) corrected finalization error in TclInExit (darley)
+
+2001-09-10 (bug fix) protect against alias loops (hobbs)
+
+2001-09-12 (bug fix) added missing #include in tclLoadShl.c (techentin)
+
+2001-09-12 (bug fix) script library path construction on Windows no longer
+uses registry, nor adds the current working directory to the path (porter)
+
+2001-09-12 (bug fix) correct bugs in compatibility strtod() (porter)
+
+2001-09-13 (bug fix) Tcl_UtfPrev now returns the proper location when the
+middle of a UTF-8 byte is passed in (hobbs)
+
+2001-09-19 (bug fix) [format] and [scan] corrected for 64-bit machines (rmax)
+
+2001-09-19 (new feature) --enable-64-bit support for HP-11. (hobbs)
+
+2001-09-19 (new feature) native memory allocator now default on Windows
+(hobbs)
+
+2001-09-20 (new feature) WIN64 support and extra processor definitions
+(hobbs, mstacy)
+
+2001-09-26 (bug fix) corrected potential deadlock in channels that do not
+provide a BlockModeProc (kupries, kogorman)
+
+2001-10-03  (new feature) WIN64 build support (hobbs)
+
+2001-10-03 (bug fix) correction in thread finalization (rbrunner)
+
+2001-10-04 (new feature) updated encodings with latest mappings from
+www.unicode.org (hobbs)
+
+2001-10-11 (bug fix) corrected cleanup of self-referential bytecodes at
+interpreter deletion (sofer, rbrunner)
+
+2001-10-16 (new feature) config support for MacOSX / Darwin (steffen)
+
+2001-10-16 (new feature, Mac) change in binary extension format from MachO
+bundles to standard .dylib dynamic libraries like on other unices.
+        *** POTENTIAL INCOMPATIBILITY ***
+
+2001-10-18 (bug fix) corrected off-by-one-day error in clock scan with
+relative months and years during swing hours. (lavana)
+
+--- Released 8.3.4, October 19, 2001 --- See ChangeLog for details ---
+
+2001-08-21 (bug fix)[219184] overagressive compilation of [catch] (sofer)
+
+2001-08-22 (new feature)[227482] [dde request -binary] (hobbs)
+=> dde 1.2
+
+2001-08-30 (performance enhancement)[456668] fully qualified command names use
+cached Command for all namespaces, avoiding repeated lookups (sofer)
+
+2001-08-31 (performance enhancement) bytecompiled [list] (hobbs)
+
+2001-09-02 (bug fix)[403553] Add -Zl to VC++ compile line for tclStubLib to
+avoid any specific C-runtime library dependence. (gravereaux)
+
+2001-09-05 (new feature) restored support for Borland compiler (gravereaux)
+
+2001-09-05 (new feature)[TIP 49] Tcl_OutputBuffered API (schroedter, fellows)
+
+2001-09-07 (new feature) restored VC++ 5.0 compatibility (gravereaux)
+
+2001-09-10 (performance enhancement)[TIP 53,451441] [proc foo args {}] now
+compiles to 0 bytecodes (sofer)
+
+2001-09-13 (new feature)[TIP 56] Tcl_EvalTokensStandard API (sofer)
+
+2001-09-13 (new feature) Old ChangeLog entries => ChangeLog.1999 (hobbs)
+
+2001-09-17 (new feature) compiling with TCL_COMPILE_DEBUG now required to
+enable all compile and execution tracing (sofer)
+        *** POTENTIAL INCOMPATIBILITY ***
+
+2001-09-19 (bug fix)[411825] made TclNeedSpace UTF-8 aware (fellows)
+
+2001-09-19 (bug fix)[219166] overagressive compilation of "quoted" bodies of
+[for], [foreach], [if], and [while] (sofer)
+
+2001-09-19 (performance enhancement) bytecompiled [string match] (hobbs)
+
+2001-10-15 (new feature)[TIP 35] serial channel configuration: Win (schroedter)
+
+2001-11-06 (bug fix)[478856] loss of fileevents due to short reads (kupries)
+
+2001-11-06 (new feature) revitalized makefile.vc (gravereaux)
+
+2001-11-07 (new feature) Cygwin gcc support dropped.  Use mingw (dejong)
+        *** POTENTIAL INCOMPATIBILITY ***
+
+2001-11-07 (new feature) Support --include-dir= and --libdir= options to
+configure.  Store in tclConfig.sh as TCL_INCLUDE_SPEC and TCL_LIB_SPEC.
+(dejong)
+        *** POTENTIAL INCOMPATIBILITY ***
+
+2001-11-08 (new feature) Enable --enable-threads on FreeBSD (dejong)
+
+2001-11-08 (new feature) New make target 'make gdb' (dejong)
+
+2001-11-09 (bug fix)[480176] [global] mishandled varnames matching :* (porter)
+
+2001-11-12 (new feature)[TIP 22,33,45] new command [lset],
+[lindex] extended to accept multiple indices. (kenny, hobbs)
+
+2001-11-16 (new feature) new configure option --enable-langinfo=no.
+By default, nl_langinfo() is used on Unix to determine system encoding.
+Tcl's built-in system is used only if that fails, or configured with
+--enable-langinfo=no. (hobbs, wagner)
+
+2001-11-19 (new feature)[TIP 62] A Tcl_VarTraceProc can now return Tcl_Obj *
+or a dynamic string as well as a static string to indicate an error (fellows)
+
+2001-11-19 (new feature)[TIP 73] Tcl_GetTime API (kenny)
+
+2001-11-19 (bug fix)[478847] overflows in [time] of >2**31 microseconds (kenny)
+
+2001-11-29 (performance enhancement) caching scheme added to [binary scan]
+(fellows)
+
+2001-12-05 (new feature) new algorithm for [array get] adds safety when read
+traces modify the array. (sofer)
+        *** POTENTIAL INCOMPATIBILITY ***
+
+2001-12-10 (bug fix)[490514] doc fixes (porter,english)
+
+2001-12-18 (new feature) removed unix/dltest/configure; unix/configure does
+all (dejong)
+
+2001-12-19 (new feature) New make target 'make shell' (dejong)
+
+2001-12-21 (new feature) MaxOSX / Darwin support (steffen)
+
+2001-12-28 (new feature) new command [memory onexit] replaces [checkmem] when
+compiled with TCL_MEM_DEBUG.  Added documentation. (porter)
+        *** POTENTIAL INCOMPATIBILITY ***
+
+2001-12-28 (bug fix) proper case in [auto_execok] use of $env(COMPSPEC) (hobbs)
+
+2002-01-05 (feature rewrite) Tcl_Main() rewritten and documentation improved.
+Interactive operation and event loop operation (via Tcl_SetMainLoop) now
+interleave cleanly.  Also more robust against strange happenings. (porter)
+
+2002-01-17 (bug fix)[504642] Tcl_Obj refCounts in [gets] (griffen,kupries)
+
+2002-01-21 (bug fix)[506297] infinite loop writing in iso2022-jap encoding
+(forssen,kupries)
+
+2002-01-24 (HTTP server bug workaround)[504508] leave the default port out
+of the Host: header value
+=> http 2.4.1 (hobbs)
+
+2002-01-25 (new feature)[496733] socket options -eofchar and -translation
+return read-only values (dejong)
+
+2002-01-28 (new feature) Old ChangeLog entries => ChangeLog.20900 (hobbs)
+
+2002-01-28 (performance enhancement) bytecompiled [regexp] for trivial cases
+that amount to string matching.  Also -nocase and --. (hobbs)
+
+2002-02-05 (bug fix) [http::error] called when [::error] intended
+=> http 2.4.2 (porter)
+
+2002-02-05 (bug fix)[465765] avoid zero-byte writes to STREAMs
+(talcott,kupries)
+
+2002-02-06 (performance enhancement) [regsub] special cases that map to
+[string map] detected. (hobbs)
+
+2002-02-06 (bug fix)[495213] [scan] accept 0x as prefix of base 16 value
+(hobbs)
+
+2002-02-10 (new feature)[TIP 32,79] Tcl_CreateObjTrace API (kenny)
+
+2002-02-12 (new feature) partial support for DJGPP Tcl on DOS (gravereaux)
+
+2002-02-14 (mem leak) Fixed leaking an empty Tcl_Obj when [gets $chan]
+errored out. (kupries, sofer)
+
+2002-02-15 (new feature)[TIP 72] support for 64-bit integer values on
+32-bit platforms and ability to work with >2GiB files.  Extends many
+commands.  See ChangeLog and TIP for details.
+	*** POTENTIAL INCOMPATIBILITY ***
+
+2002-02-22 (bug fix)[476537] Fix panic when loading shared library without
+proper use of stubs on platform without backlinking (porter)
+
+2002-02-22 (new feature)  64-bit support for xlc compiler on AIX-4 (hobbs)
+
+2002-02-22 (new feature)[521560] Removed limits on filename length and
+format [source]able through the Safe Base (hobbs)
+
+2002-02-22 (performance enhancement) optimized bytecodes for [if], [for],
+[while] and constant conditions (sofer)
+
+2002-02-22 (new feature)[TIP 76] [regsub] can now return result (fellows)
+
+2002-02-25 (bug fix)[495207] buffer overrun when closing ] left out of
+argument to [subst] (sofer, english)
+
+2002-02-25 (bug fix)[514392] [load] updated for Mac OS X 10.1 (steffen)
+
+2002-02-26 (bug fix) [info hostname] choked on names >31 characters (hobbs)
+
+2002-02-26 (new feature)[TIP 35] serial channel configuration: Unix
+(schroedter, hobbs)
+
+2002-02-25 (bug fix)[483575] [fconfigure ... -error] now no-op on Mac (kupries)
+
+2002-02-28 (performance enhancement)[458872] fully qualified command names use
+cached Command for all namespaces, avoiding repeated lookups (sofer)
+
+ * (new feature)[TIP 27] completed CONST-ification of TCL APIs.
+Added compiler macro USE_NON_CONST to keep using those old API prototypes
+that present irreconcilable source incompatibilities with header files
+of prior Tcl releases.  Others will need to be reconciled.
+        *** POTENTIAL INCOMPATIBILITY ***
+
+2002-03-04 (bug fix)[474358, 218099, 219314, 524674] fixed several problems
+related to the handling of iso2022 text and finalization of escape-based
+encodings. (taguchi, takahashi, hobbs)
+
+--- Released 8.4a4, March 5, 2002 --- See ChangeLog for details ---
+
+2002-03-06 (new feature)[TIP 80] expanded [lsearch] options (wilkason, fellows)
+
+2002-03-07 (new feature)[TIP 87] [interp recursionlimit] (trier)
+
+2002-03-08 (platform feature) mingw 1.1 build favored (dejong)
+
+2002-03-20 (new feature)[TIP 27] CONST-ified variable access functions (porter)
+
+2002-03-24 (bug fix)[511666,511658,523217,530960] expanded
+Tcl_FSMatchInDirectory to handle assorted [glob] bugs in VFS. (darley)
+        *** POTENTIAL INCOMPATIBILITY with prior 8.4a releases ***
+
+2002-03-25 (bug fix)[495726] stopped tcltest disabling of auto-loading (porter)
+
+2002-03-25 (bug fix)[495977] allow \n in test constraints (porter)
+
+2002-03-27 (platform support)[527941,533862] VC/winhelp/W9X (spjuth,
+gravereaux)
+
+2002-03-28 (bug fix)[219181] exception at level 0 issues (sofer)
+
+2002-03-28 (bug fix)[219362] command termination; Tcl_CreateTrace (knoll,sofer)
+
+2002-04-05 (bug fix)[536879] exceptions during variable subst (porter)
+
+2002-04-15 (bug fix)[497446,513983] tcltest syntax errors now raised (porter)
+	***POTENTIAL INCOMPATIBILITY with prior tcltest 2.0.* (8.4aX)***
+
+2002-04-17 (bug fix)[495660] [(save|restore)state] deprecated (porter)
+
+2002-04-17 (bug fix)[526524] escape-based encodings corrected (yamamoto, hobbs)
+
+2002-04-18 (bug fix)[542588] [expr] error msgs improved (ehrens, sofer)
+
+2002-04-18 (bug fix)[545325] [info level $level] now returns [namespace eval]
+as documented (suchenwirth,sofer)
+
+2002-04-19 (bug fix)[544727] export [mcload]; ns context of [mcmax] (porter)
+=> msgcat 1.2.3
+
+2002-04-22 (performance enhancement) threaded memory allocator (AOL, hobbs)
+
+2002-04-24 (new feature) TCLTK_NO_LIBRARY_TEXT_RESOURCES #define disables
+inclusion of tcl library code in resource fork on Mac.  (steffen)
+
+2002-05-21 (platform support) static libs on OSF (dejong)
+
+2002-05-24 (bug fix)[557878] set encoding on listening socket (staplin,
+kupries)
+
+2002-05-24 (new feature)[TIP 91] Tcl_Seek compatibility (fellows)
+
+2002-05-28 (bug fix)[545579] VFS [load] left temp file (darley)
+
+2002-05-28 (bug fix)[559376] plug timezone env leak on Windows (hobbs)
+
+2002-05-29 (performance enhancement) [string compare] optimized (hobbs,fellows)
+
+2002-05-31 (bug fix)[550534] plug interp leak in [pkg_mkIndex] (helmut)
+
+2002-05-31 (dead code)[474335,555635] removed all use of matherr() (english)
+        *** POTENTIAL INCOMPATIBILITY ***
+
+2002-06-04 (new feature)[TIP 85,521362] custom result match in tcltest
+(markus, porter)
+=> tcltest 2.1
+
+2002-06-06 (bug fix)[524352] encoding, threading, and environment issues on
+MacOSX (steffen)
+
+2002-06-06 (bug fix)[512214,558742,512214,461000] lazy initialization of
+tcltest constraints (porter)
+
+2002-06-07 (bug fix)[563122,564595] EOVERFLOW definitions (fellows)
+
+2002-06-11 (bug fix)[567386] [info locals] corrections (sofer)
+
+2002-06-14 (new feature)[TIP 102] [trace list] renamed [trace info] (fellows)
+
+2002-06-17 (new feature)[525522,525525] msgcat support for XPG4 locales;
+examination of LC_ALL, LC_MESSAGES environment variables (haible, porter)
+=> msgcat 1.3
+
+2002-06-17 (new feature)[565088] header files assume modern C compiler by
+default; older compilers may need configuration (english)
+        *** POTENTIAL INCOMPATIBILITY ***
+
+2002-06-17 (bug fix)[554068] [exec] argument quoting on Windows (darley)
+
+2002-06-17 (new feature)[TIP 62,462580] command execution traces (lavana)
+
+2002-06-19 (bug fix)[558324] regexp sets a linked variable (watson)
+
+ * (performance enhancment) optimizations of bytecode execution (sofer)
+
+2002-06-21 (new feature)[TIP 99,562970] new [file link] command (darley)
+
+2002-06-24 (new feature)[TIP 101] new [tcltest::configure] command (porter)
+=> tcltest 2.2
+
+2002-06-25 (new feature) --enable-man-symlinks and --enable-man-compression
+options to configure (max)
+
+2002-06-26 (bug fix)[565880] [clock format] now respects locale (max)
+        *** POTENTIAL INCOMPATIBILITY ***
+
+2002-07-03 (bug fix)[577015] [catch] catches even compile errors (sofer)
+
+--- Released 8.4b1, July 5, 2002 --- See ChangeLog for details ---
+
+2002-07-08 (bug fix) restored compatibility of [viewFile] in tcltest (porter)
+
+2002-07-11 (bug fix) [file normalize] returns long form on Win 95/98/ME (darley)
+
+2002-07-15 (performance enhancment) variable operations rewritten to store
+	and use cached Var pointers (sofer)
+
+2002-07-22 (bug fix)[218000] Inf and Nan are floating-point values (fellows)
+
+2002-07-23 (platform support)[219220] 64-bit compile on IRIX (dejong)
+
+2002-07-25 (bug fix)[219218] return codes in background errors (english)
+
+2002-07-28 (bug fix)[582522] alias fires exec traces (sofer)
+
+2002-07-29 (bug fix)[578363] regexp (fellows,pvgoran)
+
+2002-07-30 (bug fix)[584603] WriteChars infinite loop non-UTF-8 string (kupries)
+
+2002-08-04 (new feature)[584051,580433,585105,582429][TIP 27] Tcl interfaces
+	are now fully CONST-ified.  Use the symbols USE_NON_CONST or
+	USE_COMPAT_CONST to select interfaces with fewer changes.
+        *** POTENTIAL INCOMPATIBILITY ***
+
+2002-08-05 (bug fix)[589859] tcltest setup and cleanup scripts skipped when
+	test body is skipped (porter)
+	=> tcltest 2.2
+
+2002-08-07 (bug fix)[587488] mem leak with USE_THREAD_ALLOC (sofer,sass)
+
+2002-08-07 (feature enhancement)[584794,584650,472576] boolean values
+	are no longer always re-parsed from string. (sofer)
+
+Many internal bugs fixed.
+Considerable cleanup of the test suite.
+
+--- Released 8.4b2, August 9, 2002 --- See ChangeLog for details ---
+
+2002-08-20 (new feature) --enable-memdebug configure option (kupries)
+
+2002-08-23 (bug fix)[597936] mem leak with USE_THREAD_ALLOC (sofer,zoran)
+
+2002-08-26 (bug fix)[599788] segfault in compiler (sofer,wilkason)
+
+2002-08-28 (bug fix)[414910] avoid mem leaks accessing environment variables
+	on Windows (welton,gravereaux)
+
+2002-08-31 (platform support)[TIP 108] Mac OS X port (steffen,ingham)
+
+2002-09-02 (platfrom support) 64-bit compile on HP-11 (martin)
+
+--- Released 8.4.0, September 10, 2002 --- See ChangeLog for details ---
+
+2002-09-18 (platform support) Updated support for compiling with Cygwin and
+either mingw or gcc. (khan, howell, dejong)
+
+2002-09-22 (bug fix)[612786, 611922] Corrected [puts -nonewline] within
+test bodies. Also corrected reporting of body return code.  Updated tcltest
+to v2.2.1.
+
+2002-09-24 (bug fix)[613117] More robust 64-bit wide integer value
+detection (fellows)
+
+2002-09-26 (bug fix) correct overeager optimization of noop proc to handle
+the precompiled case. (sofer, hobbs)
+
+2002-09-26 (bug fix)[615115] removed extraneous spaces in koi8-u.enc that
+confused encoding reader.
+
+2002-09-29 (bug fix)[219355] Added proper exiting conditions using Win32
+console signals.  This handles the existing lack of a Ctrl+C exit to call
+exit handlers when built for thread support.  Also, properly handles exits
+from other conditions such as CTRL_CLOSE_EVENT, CTRL_LOGOFF_EVENT, and
+CTRL_SHUTDOWN_EVENT signals.  In all cases, exit handlers will be called.
+(gravereaux)
+
+2002-09-30 (bug fix) improve the checking for bad regular expressions
+during regexp compilation.  Resultant compiles were correct, but much
+slower than necessary. (hobbs)
+
+2002-10-01 (bug fix) fix precompiled locals to support 8.3 precompiled
+code. (hobbs)
+
+2002-10-09 (bug fix)[620735] Added code to set an exit handler on Windows
+that terminates the thread that calibrates the performance counter, so that
+the thread won't outlive unloading the Tcl DLL. (kenny)
+
+2002-10-09 (build support) all --enable-symbols to take the enhanced
+options yes|no|mem|compile|all. (hobbs)
+
+2002-10-10 (build support) enable USE_THREAD_ALLOC (new threaded allocator)
+by default on Windows. (hobbs, gravereaux)
+
+2002-10-14 (bug fix)[623269] correct possible mem leak in
+Tcl_PutEnv. (brouwers)
+
+2002-10-15 (bug fix)[615043] fix in execution traces with idle tasks
+firing. (lavana)
+
+2002-10-15 (platform support) Correct AIX-5 ppc and 4/5 64-bit build flags.
+Correct HP 11 64-bit gcc building. (martin, hobbs)
+
+2002-10-17 (bug fix)[624755] Fixed code that check for proper # of args to
+[array names] (porter)
+
+2002-10-18 (feature enhancement)[625453] Added support for broadcasting
+changes to the registry Environment on Windows.  Updated registry package
+to v1.1. (hobbs)
+
+2002-10-22 (platform support)[624509] On macosx, add embedded framework
+dirs to tcl_pkgPath: @executable_path/../Frameworks and
+@executable_path/../PrivateFrameworks (if they exist), as well as the dirs
+in DYLD_FRAMEWORK_PATH (if set). (steffen)
+
+--- Released 8.4.1, October 22, 2002 --- See ChangeLog for details ---
+
+2002-10-28 (bug fix)[627660] [package unknown] chaining for platform specifics
+
+2002-10-29 (bug fix)[627546] verbose [load] (dyld) error mesages on MacOSX
+
+2002-11-01 (bug fix) [package provide registry] consistent versions.
+
+2002-11-06 (bug fix)[582039] missing ar program -> configuration error
+
+2002-11-06 (feature enhancement) added new TclInThreadExit function to
+test for thread exit vs whole process exit condition. The TclInExit
+function now correctly returns 1 during Tcl_Finalize processing.
+        *** POTENTIAL INCOMPATIBILITY ***
+
+2002-11-13 (bug fix)[615043] some execution traces were not firing
+
+2002-11-18 (bug fix)[634856] multiple signs no longer accepted as valid integer
+[string is integer ++1] => 0
+        *** POTENTIAL INCOMPATIBILITY ***
+
+2002-11-26 (bug fix)[593810,597924] clean exit of channel worker threads on Win
+
+2002-11-28 (new feature) `make valgrind` target
+
+2002-12-03 (bug fix)[615304] repeated load/unload of Tcl now possible
+
+2002-12-11 (bug fix)[647307] negative return codes now propagated by procs
+
+2002-12-11 (bug fix)[648441] syntax error in [expr 0x] now detected.
+
+2003-01-07 (bug fix)[633204] [catch {return}] => 2 (not 0)
+
+2003-01-09 (bug fix)[634151] [file (a|m)time $nonASCIIpath $time] now works
+
+2003-01-16 (bug fix) dde eval with {} service name does not crash.
+=> dde 1.2.1
+
+2003-01-16 (bug fix)[635200,655645,615043,571385] many command trace fixes
+
+2003-01-31 (bug fix)[675614,678415,676978] tcltest conflicts in cleanup
+and -outfile; also failure in space-containing path; also missing [close]
+=> tcltest 2.2.2
+
+2003-02-01 (bug fix)[670042] corrected [info loaded {}] for static
+packages in multiple interps.
+
+2003-02-01 (bug fix)[675356] [clock clicks {}]; [clock clicks -] - syntax errs
+
+2003-02-01 (bug fix)[656660] MT-safety for [clock format]
+
+2003-02-03 (bug fix)[651271] command rename traces get fully-qualified names
+        *** POTENTIAL INCOMPATIBILITY ***
+
+2003-02-07 (performance improvement) [glob] on Windows is 2.5 times faster
+
+2003-02-07 (feature change) lack of Cygwin support indicated by config error
+
+2003-02-11 (bug fix)[684744] [info complete] stopped by \x00
+
+2003-02-11 (bug fix)[685445] [glob -types l] missed broken symlinks on Unix
+
+2003-02-11 (bug fix) [lsearch -regexp $a $a] doesn't crash
+
+2003-02-13 (bug fix)[685926] accept non-ASCII7 for tcl_platform(user) on Win
+
+2003-02-15 (bug fix)[673714] stop crash when Tcl_DeleteEvents deletes last
+
+2003-02-15 (bug fix)[681841] parser missed some missing ] syntax errors
+
+2003-02-17 (bug fix)[684756] memory leak during command rename plugged
+
+2003-02-18 (bug fix)[689100] reduced per-thread memory overhead
+
+2003-02-18 (platform support)[651811] use xnet library on HP 11 (64 bit).
+
+2003-02-20 (bug fix)[Patch 689341] correct jis round-trip encoding
+
+2003-02-20 (bug fix)[689835] stop MacOSX hang trying to read a write-only pipe
+
+2003-02-07 (performance improvement) [tclPkgUnknown]: fewer vfs calls
+
+2003-02-18 (platform support) cut and splice procs for file channels on Mac
+
+2003-02-21 (bug fix)[690774] [binary scan] failed on some wide ints
+
+2003-02-22 (bug fix)[571002] plugged data leak during thread exit
+
+2003-02-25 (feature change) [pkg_mkIndex -load]: case-insensitive match
+        *** POTENTIAL INCOMPATIBILITY ***
+
+2003-02-27 (bug fix)[694232] stop [lsearch -start 0 {} x] segfault
+
+--- Released 8.4.2, March 3, 2003 --- See ChangeLog for details ---
+
+2003-03-06 (bug fix)[699042] Correct case-insensitive unicode string
+comparison in Tcl_UniCharNcasecmp
+
+2003-03-11 (bug fix) Corrected loading of tclpip8x.dll on Win9x
+
+2003-03-12 (bug fix)[702383] Corrected parsing of interp create --
+
+2003-03-12 (bug fix)[685106] Correct Tcl_SubstObj handling of \x00 bytes
+
+2003-03-14 (bug fix)[702622 699060] Correct wide int issues in 'format'
+
+2003-03-14 (bug fix)[698146] Remove assumption that file times and longs
+are the same size.
+
+2003-03-18 (bug fix)[697862] Allow Tcl to differentiate between reparse
+points which are symlinks and mounted drives on Windows
+
+2003-03-19 (bug fix)[705406] Bad command count on TCL_OUT_LINE_COMPILE
+
+2003-03-20 (bug fix)[707174] Store pointers to notifier funcs in a struct
+to work around some platform linker issues
+
+2003-03-22 (bug fix)[708218] Load correct (non-)debug dll for dde or
+registry
+
+2003-03-24 (bug fix)[631741 696893] Fixing ObjMakeUpvar's lookup algorithm
+for the created local variable
+
+2003-04-07 (bug fix)[713562] Make sure that tclWideIntType is defined and
+somewhat sensible everywhere
+
+2003-04-07 (bug fix)[711371] Corrected string limits of arguments
+interpolated in error messages for 'if'
+
+2003-04-11 (bug fix)[718878] Corrected inconsistent results of
+[string is integer] observed on systems where sizeof(long) != sizeof(int)
+
+2003-04-12 (bug fix) Substantial changes to the Windows clock synch
+phase-locked loop in a quest for improved loop stability
+
+2003-04-16 [713562] Made changes so that the "wideInt" Tcl_ObjType is
+defined on all platforms, even those where TCL_WIDE_INT_IS_LONG is defined.
+Also made the Tcl_Value struct have a wideValue field on all platforms.
+Potential incompatibility for TCL_WIDE_INT_IS_LONG platforms because that
+struct changes size.
+        *** POTENTIAL INCOMPATIBILITY ***
+
+2003-04-25 (bug fix)[727271] Catch any errors returned by the Windows
+functions handling TLS ASAP instead of waiting to get some mysterious crash
+later on due to bogus pointers.
+
+2003-04-29 (bug fix) Correct 'glob -path {[tcl]} *', where leading
+special character instead lists files in '/'.  Bug only occurs on Windows
+where '\' is also a directory separator.
+
+2003-05-09 (bug fix)[731754] Fixed memory leak in threaded allocator on
+Windows caused by treating cachePtr as a TLS index
+
+2003-05-10 (bug fix)[710642] Ensure cd is thread-safe
+
+2003-05-10 (bug fix)[718002] Correct mem leak on closing a Windows serial
+port
+
+2003-05-10 (bug fix)[714106] Prevent string repeat crash when overflow
+sizes were given (throws error).
+
+2003-05-13 (feature enhancement)[736774] Use new versioned bundle resource
+API to get tcl runtime library for TCL_VERSION on Mac OS X.
+
+2003-05-13 (bug fix)[711232] Worked around the issue of realpath() not
+being thread-safe on Mac OS X by defining NO_REALPATH for threaded builds
+on Mac OS X.
+
+2003-05-14 (bug fix)[557030] Correct handling of the gb2312 encoding by
+making it an alias of the euc-cn encoding and creating a gb2312-raw
+encoding for the original.  Most uses of gb2312 really mean euc-cn.
+
+2003-05-14 (bug fix)[736421] Corrected another putenv() copy behavior
+problem when compiling on Windows and using Microsoft's runtime.
+
+--- Released 8.4.3, May 20, 2003 --- See ChangeLog for details ---
+
+2003-05-23 (bug fix)[726018] reverted internals change to the
+'cmdName' Tcl_ObjType that broke several extensions (TclBlend, e4graph...)
+in the 8.4.3 release.
+
+2003-06-10 (bug fix)[495830] stop eval of bytecode in deleted interp.
+
+2003-06-17 (bug fix) corrections to regexp when matching emtpy string.
+
+2003-06-25 (bug fix)[748957] -*ieee compiler flags for Tru64 builds.
+
+2003-07-11 (bug fix) [pkg_mkIndex] indexes provided packages, not indexed ones.
+
+2003-07-15 (feature enhancement) MacOSX build system rewrite.
+
+2003-07-15 (bug fix)[771613] corrected segfault in [if] (buffer overflow)
+
+2003-07-16 (bug fix)[756791] corrected assumption that Tcl_Free == free
+
+2003-07-16 (feature enhancement) -DTCL_UTF_MAX=6 compile option forces
+internal UCS-4 representation of Unicode (default is recommended UCS-2).
+
+2003-07-16 (bug fix)[767578] 64-bit corrections in thread notifier.
+
+2003-07-16 (bug fix)[759607] Safe Base tests normalized paths.
+
+2003-07-16 (feature enhancement)[Patch 679315] improved Cygwin path support
+
+2003-07-18 (bug fix)[706359] corrected broken -output option of [tcltest::test]
+=> tcltest 2.4.4
+
+2003-07-18 (bug fix)[753315] MT-safety of VFS records.
+
+2003-07-18 (bug fix)[759888] support for user:pass in URL by [http::geturl]
+=> http 2.4.4
+
+Improved documentation, new tests, and some code cleanup.
+[655300, 720634, 735364, 748700, 756112, 756744, 756951, 758488, 760768,
+763312, 769895, 771539, 771840, 771947, 771949, 772333]
+
+--- Released 8.4.4, July 22, 2003 --- See ChangeLog for details ---
+
+2003-07-23 (bug fix)[775976] fix registry compilation for VC7.
+
+2003-08-05 (enhancement)[781585] Use Tcl_ResetResult in bytecodes to
+prevent potential costly Tcl_Obj duplication.
+
+2003-08-06 (bug fix)[781609] prevent non-Windows platforms from trying to
+use the registry package inside msgcat.
+
+2003-08-27 (bug fix)[411825] Fix TclNeedSpace to handle non-breaking space
+(\u00A0) and backslash escapes correctly.
+
+2003-09-01 (bug fix)[788780] Fix thread-safety issues in filesystem records.
+
+2003-09-19 (bug fix)[804681] Protect ::errorInfo and ::errorCode traces
+from corrupting stack.
+
+2003-09-23 (bug fix)[218871] Fix handling of glob-sensitive chars in
+auto_load and auto_import.
+
+2003-10-03 (bug fix)[811483] Fixed refcount management for command and
+execution traces.
+
+2003-10-04 (bug fix)[789040] Fixed exec command.com error for Win9x.
+
+2003-10-06 (bug fix)[767834, 813273] Fixed volumerelative file
+normalization and 'file join' inconsistencies.
+
+2003-10-08 (bug fix)[769812] Fix Tcl_NumUtfChars string length calculation
+when negative parameter is given.
+
+2003-10-22 (bug fix)[800106] Handle VFS mountpoints inside glob'd dirs.
+
+2003-10-22 (bug fix)[599468] Watch for FD_CLOSE too on Windows when
+asked for writable events by the generic layer.
+
+2003-10-23 (bug fix)[813606] Detect OS X pipes correctly.
+
+2003-11-05 (bug fix)[832657] Allow .. in libpath initialization.
+
+2003-11-11 (bug fix) Improve AIX-64 build configuration.
+
+2003-11-17 (bug fix)[230589, 504785, 505048, 703709, 840258] fixes to
+various odd regexp "can't happen" bugs.
+
+--- Released 8.4.5, November 20, 2003 --- See ChangeLog for details ---
+
+2003-12-02 (bug fix)[851747] object sharing fix in [binary scan]
+
+2003-12-09 (platform support)[852369] update errno usage for recent glibc
+
+2003-12-12 (bug fix)[858937] fix for [file normalize ~nobody]
+
+2003-12-17 (bug fix)[839519] fixed two memory leaks (vasiljevic)
+
+2004-01-09 (bug fix)[873311] fixed infinite loop in TclFinalizeFilesystem
+
+2004-02-02 (bug fix)[405995] Tcl_Ungets buffer filling fix
+
+2004-02-04 (bug fix)[833910] tcltest command line option parsing error
+=> tcltest 2.4.5
+
+2004-02-04 (bug fix)[833637] code error in tcltest -preservecore operation
+
+2004-02-12 (feature enhancement) update HP-11 build libs setup
+
+2004-02-17 (bug fix)[849514,859251] corrected [file normailze] of $link/..
+
+2004-02-17 (bug fix)[772288] Unix std channels forced to exist at startup.
+
+2004-02-17 (new default) tcltest::configure -verbose {body error}
+
+2004-02-19 (bug fix) init.tcl search path with unusual --libdir (samson)
+
+2004-02-25 (bug fix)[554068] stopped broken [exec] quoting of { (gravereaux)
+
+2004-02-25 (bug fix)[888777] plugged memory leak with long host names (cassoff)
+
+2004-03-01 (bug fix)[462580] corrected level interpretation of Tcl_CreateTrace
+
+2004-03-01 (platform support)[218561] Allow 64-bit configure on IRIX64-6.5*
+
+--- Released 8.4.6, March 1, 2004 --- See ChangeLog for details ---
+
+Changes to 8.5a1 include all changes to the 8.4 line through 8.4.6,
+plus the following, which focuses on the high-level feature changes
+in this changeset (new minor version) rather than bug fixes:
+
+ * refactored IO code to split FS path code into generic/tclPathObj.c
+  and generic/tclFileSystem.h
+
+ * refactored trace code into generic/tclTrace.c
+
+ * configure scripts now require autoconf 2.57 for regeneration
+
+ * updated runtime library scripts to use newer Tcl code features
+   (like replacing regsub with string map)
+
+ * improve robustness of tcltest test suite across environments
+
+ * changed the bytecode evaluation-stack addressing mode, from array-style
+   to pointer-style; the catch stack and evaluation stack are now
+   contiguous in memory
+
+ * switch command is now byte-compiled
+
+ * enhanced checking in 'file' command for Windows NT file permissions
+
+ * [TIP #57] new 'lassign' command (adopted from TclX)
+
+ * [TIP #75] switch -regexp now provides submatch info
+
+ * [TIP #90] extended 'catch' and 'return' to enable creation of procs
+   that are a true replacement for 'return'
+
+ * [TIP #100] new 'unload' command (can unload DLLs loaded via 'load',
+   requires the extension writer to support it)
+
+ * [TIP #111] new 'dict' command.  Several commands have been updated
+   to handle the list form of dicts implicitly at the C level where
+   only lists were previously accepted
+
+ * [TIP #112] 'namespace ensemble' command addition allows for ensembles
+   that build on the namespace abstraction
+
+ * [TIP #118] file attributes -readonly option for unices that support
+   chflags(), support Mac Classic attribute options on OS X, add
+   -rsrclength for OS X, enhance file copy on OS X to copy finder
+   attributes and resource forks transparently
+
+ * [TIP #120] enable dde in safe interpreters
+ * [TIP #130] enable unique dde server names on Windows
+ * [TIP #135] change dde servername -exact option to -force
+=> dde 1.3
+
+ * [TIP #121] new Tcl_SetExitProc C API to control application shutdown
+
+ * [TIP #123] expr ** exponentiation operator
+
+ * [TIP #124] 'clock clicks -milliseconds' now returns a wide integer and a
+   new 'clock clicks -microseconds' returns a wide integer, representing
+   the number of microseconds, both since the Posix epoch
+
+ * [TIP #127] added 'lsearch -index' option
+
+ * [TIP #136] added 'lrepeat' command
+
+ * [TIP #137/151] Add -encoding option to 'source' command and main tclsh
+   executable.
+     *** POTENTIAL INCOMPATIBILITY ***
+   For Tcl embedders that build on Tcl_Main() and make use of Tcl_Main's
+   former ability to pass a leading "-encoding" option to interactive shell
+   operations, this will now be consumed by Tcl.
+
+ * [TIP #138] New TCL_HASH_KEY_SYSTEM_HASH option for Tcl hash tables
+
+ * [TIP #139] documented portions of Tcl's namespace C APIs
+
+ * [TIP #148] correct [list]-quoting of the '#' character
+     *** POTENTIAL INCOMPATIBILITY ***
+   For scripts that assume a particular (buggy) string rep for lists.
+
+ * [TIP #156] add "root locale" to msgcat
+=> msgcat 1.4
+
+ * [TIP #157] leading {expand} syntax on words to cause argument expansion.
+   This is a safer/cleaner alternative to the use of 'eval'.
+
+--- Released 8.5a1, March 3, 2004 --- See ChangeLog for details ---
+
+2004-03-04 (new feature) registry package is [unload]able (thoyts)
+=> registry 1.1.4
+
+2004-03-08 (bug fix)[910525] [glob -path] in root directory (darley)
+
+2004-03-12 (new feature)[TIP 163] [dict merge] (english, fellows)
+
+2004-03-18 (platform support) support for Mac Classic removed (steffen)
+
+2004-03-28 (bug fix)[925121] corrected segfault in bc compiler (sofer)
+
+2004-03-30 (bug fix)[495830,729692] bytecode execution checks
+each command/interp validity before executing. (sofer)
+
+2004-03-31 (bug fix)[811457] support translation to "" (porter)
+2004-03-31 (bug fix)[811461] ignore locales with no "language" part (porter)
+=> msgcat 1.4.1
+
+2004-04-01 (bug fix) make [glob -type d -dir . *] work across VFS boundary
+
+2004-04-06 (clean up) refactored Tcl header file #include order.  Might
+create need for changes in extensions that #include private headers.
+Changed source code files should work with older Tcl as well.  See ChangeLog.
+     *** POTENTIAL INCOMPATIBILITY ***
+
+2004-04-07 (bug fix)[920667] install into any Unicode path on Win (hobbs)
+
+2004-04-07 (platform support) properly substitute more values in Windows
+tclConfig.sh (hobbs)
+
+2004-04-23 (bug fix)[930851] reset channel EOF when eofchar changes (kupries)
+
+2004-04-28 (bug fix)[600812][TIP 184] [upvar 0 scalar array(foo)] raises error
+
+2004-05-03 (bug fix)[947070] stack overflow prevention on Win (kenny)
+
+2004-05-03 (bug fix)[868853] fix leak in [fconfigure $serial -xchar] (cassoff)
+
+2004-05 (bug fix)[928353,929892,928808,947440,948177] test fixes: OSX (abner)
+
+2004-05-05 (bug fix)[794839] socket connect error -> r/w fileevents
+(gravereaux)
+
+2004-05-07 (bug fix)[949905] corrected utf-8 encoding of \u0000 on I/O (max)
+
+2004-05-13 (new feature)[TIP 129] [binary scan tnmrRqQ] (markus, fellows)
+
+2004-05-13 (new feature)[TIP 142] [interp limit] (fellows)
+
+2004-05-14 (bug fix)[940278,922848] [clock] notices $::env(TZ) changes,
+gmt works on all platforms. (kenny, welton, glessner)
+
+2004-05-16 (feature rewrite) bytecode execution of {expand} changed
+        *** POTENTIAL INCOMPATIBILITY with prior 8.5a releases ***
+
+2004-05-18 (platform support) makefile.vc now generates tclConfig.sh (thoyts)
+
+2004-05-18 (bug fix)[500285,500389,852944] [clock %G %V] ISO8601 week numbers
+(kenny)
+
+2004-05-22 (bug fix)[735335,736729] variable name resolution error (sofer)
+
+2004-05-24 (bug fix) support for non-WIDE_INT aware math functions (hobbs)
+
+2004-05-25 (new feature) [http::config -urlencoding] (hobbs)
+=> http 2.5.0
+
+2004-05-26 (bug fix)[960926] file count doubled when -singleproc 1 (porter)
+=> tcltest 2.2.6
+
+2004-05-26 (bug fix)[874058] improved build configuration on 64-bit systems.
+Corrects Tcl_StatBuf definition issues.  (hobbs)
+
+2004-05-30 (platform support) Win: allow signed short exit codes (gravereaux)
+
+2004-06-05 (bug fix)[976722] hi-res clock fixes: Win
+(godfrey, suchenwirth, kenny)
+2004-06-10 (bug fix)[932314] bad return values from Tcl_FSChdir() (vasiljevic)
+
+2004-06-18 (platform support) regonize more unix locales (huang)
+
+2004-06-18 (bug fix) prevent stack overflow from long free() chains (fellows)
+
+2004-06-21 (platform support) exceptions w/ gcc -O3 on Win (dejong)
+
+2004-06-23 (feature rewrite)[976496] thread local storage done with hash
+tables to avoid system limits (mistachkin)
+
+2004-06-29 (bug fix)[981733] SafeBase global pollution (fellows)
+
+2004-06-30 (new feature)[TIP 188] [string is wideinteger] (kenny)
+
+2004-07-02 (new feature)[TIP 202] pipe redirection 2>@1 (hobbs)
+
+2004-07-03 (bug fix)[908375] round() wide integer support (lavana, sofer)
+
+2004-07-07 (bug fix)[458361] shimmer of single-word scripts suppressed (sofer)
+
+2004-07-15 (bug fix)[770053] crash in thread finalize of notifier (vasiljevic)
+
+2004-07-15 (bug fix)[990453] plug mutex leaks on reinit
+(mistachkin, vasiljevic)
+
+2004-07-16 (bug fix)[990500] clean exit of notifier thread
+(mistachkin, kupries)
+
+2004-07-19 (bug fix)[987967] improved self-init of mutexes on Win (vasiljevic)
+
+2004-07-20 (bug fix) pure Darwin/CFLite support (steffen)
+
+2004-07-20 (bug fix)[736426] plug leaky allocator reinit (mistachkin, kenny)
+
+2004-07-30 (bug fix)[999084] no deadlock in re-entrant Tcl_Finalize (porter)
+
+2004-08-02 (new feature)[TIP 207] [interp invokehidden -namespace] (porter)
+
+2004-08-10 (bug fix) thread IDs on 64-bit systems (ratcliff,vasiljevic)
+
+2004-08-13 (bug fix) avoid malicious code acceptance by [mclocale] (porter)
+=> msgcat 1.3.3
+
+2004-08-16 (bug fix)[1008314] Tcl_SetVar TCL_LIST_ELEMENT (sofer,porter)
+
+2004-08-18 (new feature)[TIP 173,209] complete [clock] rewrite (kenny)
+	*** POTENTIAL INCOMPATIBILITY ***
+
+2004-08-18 (new feature)[TIP 189] package loading for Tcl Modules (kupries)
+
+2004-08-19 (bug fix)[1011860] [scan %ld] fix on LP64 (fellows,porter)
+
+2004-08-23 (bug fix)[695441] extend [tcl_findLibrary] search path to include
+		$::auto_path and [pkgconfig get scriptdir,runtime] (porter)
+
+2004-08-27 (platform support) TCL_MODULE_PATH values for Mac OSX (steffen)
+
+2004-08-27 (bug fix)[1017022] recognize imported ensembles (fellows)
+
+2004-08-30 (bug fix) [string map $x $x] crash (fellows)
+
+2004-09-01 (bug fix)[1020445] WIN64 support (hobbs)
+
+2004-09-03 (bug fix)[1020538] crash in [file copy] (violi,fellows)
+
+2004-09-07 (bug fix)[1016167] [after] overwrites its imports (kenny)
+
+2004-09-08 (bug fix) fixed [clock format 0 -format %k] (kenny)
+
+2004-09-09 (bug fix)[560297] fixed broken [namespace forget] logic (porter)
+
+2004-09-09 (bug fix)[1017299] fixed [namespace import] cycle prevention
+(porter)
+
+2004-09-10 (performance) $x[set x {}] is now fast [K $x [set x {}]] (sofer)
+
+2004-09-10 (bug fix)[868489] better control over int <-> wideInt
+(fellows,kenny)
+
+2004-09-10 (bug fix)[1025359] POSIX errorCode from wide seeks (kupries,fellows)
+
+2004-09-10 (bug fix)[707104,1026493] fix [rename] of [interp alias] (porter)
+
+2004-09-18 (bug fix)[868467] fix [expr 5>>32] => 0, not 5 (hintermayer,fellows)
+
+2004-09-21 (bug fix) consistent errorinfo from [namespace eval x error foo bar]
+		and [namespace eval c {error foo bar}] (porter)
+
+2004-09-22 (feature change) syntax errors not reported at compile time;
+		deferred to runtime.  Support [return -errorline]. (porter)
+
+2004-09-23 (bug fix)[1016726] fix `make clean` in static config
+(leitgeb,dejong)
+
+2004-09-22 (feature change) report all compile errors at runtime (porter)
+
+2004-09-29 (bug fix)[1036649] syntax error in [subst] => buffer overflow
+(sofer)
+
+2004-09-30 (bug fix)[1038021] save/restore error state: var traces (porter)
+
+2004-10-01 (performance) stackframe level values in internal reps (fellows)
+
+2004-10-01 (feature change)[1037235] auto-create [dict] key paths (fellows)
+
+2004-10-04 (bug fix)[884830] eq and ne parse in expr (fellows)
+
+2004-10-05 (reform) errorInfo, errorCode management (porter)
+	*** POTENTIAL INCOMPATIBILITY for traces on those vars ***
+
+2004-10-06 (feature change)[1041072] re-bless and enhance Tcl_AppendResult
+(dkf)
+
+2004-10-06 (reform) more robust interp result appends (porter)
+=> dde 1.3.1
+=> registry 1.1.5
+
+2004-10-06 (reform) re-write of [glob] guts (fellows)
+
+2004-10-07 (reform)[925620] improved platform split of VFS code (darley)
+
+2004-10-08 (new feature)[TIP 201] "in" and "ni" expr operators (fellows)
+
+2004-10-08 (new feature)[TIP 212] [dict update]; [dict with] (fellows)
+
+2004-10-08 (bug fix)[954263] case insensitive [file exec] for Win
+(hobbs,darley)
+
+2004-10-14 (performance) [info commands/globals/procs/vars $pattern] faster
+                when $pattern is trivial (fellows)
+
+2004-10-14 (new feature)[TIP 217] [lsort -indices] (salsman,fellows)
+
+2004-10-24 (reform) replaced bit flag values with macros for Var handling
+	*** POTENTIAL INCOMPATIBILITY for accesses to Var internals ***
+
+2004-10-26 (new feature)[1054370] install msgcat, http, tcltest as TM's
+(porter)
+
+2004-10-26 (bug fix)[767676] negative PIDs with pipes (giese,gravereaux)
+
+2004-10-27 (bug fix)[731778] stop critical section leaks
+(mistachkin,gravereaux)
+
+2004-10-27 (bug fix)[926088] -load option to find tested packages (gravereaux)
+
+2004-10-28 (bug fix)[1030548] restore the --enable-symbols --enable-threads
+build on Win (mistachkin,kenny,kupries)
+
+2004-10-29 (bug fix)[1055673] fix command line syntax error message (porter)
+=> tcltest 2.2.7
+
+2004-10-30 (bug fix)[926106] fix [file mtime] DST anomaly (kenny)
+
+2004-10-31 (bug fix)[1057461] fix [info globals ::varName] (fellows)
+
+2004-11-02 (bug fix)[761471] fix [expr {NaN == NaN}] (sofer)
+
+2004-11-02 (bug fix)[1017151] misleading errorInfo after tests (seeger,porter)
+
+2004-11-03 (bug fix)[527164] preserve errorinfo from var traces (porter)
+
+2004-11-08 (bug fix){947693] Made -blocking option of channel during [close]
+consistent on Windows with Unix (gravereaux)
+	*** POTENTIAL INCOMPATIBILITY ***
+
+2004-11-11 (bug fix)[1034337] recursive file delete, MacOSX (steffen)
+
+2004-11-12 (new feature)[TIP 221] [interp bgerror] (porter)
+
+2004-11-12 (new feature)[TIP 226] Tcl_(Save|Restore|Discard)InterpState
+(porter)
+
+2004-11-12 (new feature)[TIP 227] Tcl_(Get|Set)ReturnOptions (porter)
+
+2004-11-12 (bug fix)[1004065] stop crash when TCL_UTF_MAX==6 (hobbs,porter)
+
+2004-11-15 (bug fix)[10653678] [trace variable],[trace remove] interop (porter)
+
+2004-11-16 (bug fix)[1067709] crash in [fconfigure -ttycontrol] (hobbs)
+
+2004-11-18 (new feature) configure options --enable-man-suffix (max)
+
+2004-11-22 (bug fix)[1030465] Improve HAVE_TYPE_OFF64_T check (dejong)
+
+2004-11-22 (bug fix)[1043129] Fixed the treatment of backslashes in file
+join on Windows (darley)
+
+2004-11-22 (bug fix)[976438] Move init.tcl search path construction to
+tclInit (porter)
+
+2004-11-24 (bug fix)[1072654] Fixed segfault in info vars trivial
+matching branch (new in 8.4.8) (porter)
+
+2004-11-24 (bug fix)[1001325, 1071701] Fixed readdir_r detection and usage
+(dejong, kenny, porter)
+
+2004-11-24 (bug fix)[1071807] Fixed all uses of 'select' to use standard
+macros rather than older bit-whacking style (kenny)
+
+2004-11-26 (bug fix)[1073524] Simplify the code to check for correctness of
+strstr, strtoul and strtod on unix (fellows)
+
+2004-11-26 (bug fix)[1072136] Remove file normalize on tcl_findLibrary
+search path uniqification added in 8.4.8 (porter)
+
+2004-11-30 (bug fix)[976520] Rework startup/initialization of the Tcl
+library, encoding search initialization, and Tcl_FindExecutable structure.
+[tclInit] no longer driven by the value of $::tcl_libPath (TCLLIBPATH).
+(porter)
+	*** POTENTIAL INCOMPATIBILITY : makes encoding names case sensitive
+	    on Windows, where they have been case insensitive ***
+
+2004-12-02 (bug fix)[1074671] Ensure tilde paths are not returned specially
+by 'glob' (darley)
+
+Doc improvements [759545,926590,935853,1017072,1018486,1022527,1027849,
+	1032243,1047928,1048005,1058446,1062647,1065732,1073334,etc.]
+Test suite expansion [1036649,1001997,etc.]
+
+--- Released 8.5a2, December 7, 2004 --- See ChangeLog for details ---
+
+2004-12-13 (bug fix)[1083082] encoding memory leaks (ade,porter)
+
+2004-12-13 (bug fix)[1082349] restored C++ extension support (porter)
+
+2004-12-14 (bug fix)[1081541] workaround automake-ism "$U" (porter)
+
+2004-12-15 (new feature) CallFrames on execution, not C, stack (sofer)
+
+2004-12-16 (bug fix)[1085023] [interp limit] support in [vwait], etc. (fellows)
+
+2004-12-29 (bug fix)[1090413] make [clock scan 0030] work (morian,kenny)
+
+2004-12-29 (bug fix)[1092789] make [clock scan 10000] work (porter,kenny)
+
+2004-12-29 (platform support)[1092952,1091967] MSVC7, gcc OPT compiles (hobbs)
+
+2005-01-06 (performance)[1020491] [http::mapReply] (fellows)
+=> http 2.5.1
+
+2005-01-09 (bug fix)[1095909] stopped use of readdir_r (english)
+
+2005-01-10 (enhancement)[1081595] stopped use of TCL_DBGX (english)
+
+2005-01-17 (bug fix)[1100542] [glob] of Windows shares (schar,darley)
+
+2005-01-19 (new feature)[TIP 235] C API for ensembles (fellows)
+
+2005-01-21 (new feature)[TIP 233] virtual time (kupries)
+
+2005-01-25 (bug fix)[1101670] [auto_reset] update for [namespace] (porter)
+***POTENTIAL INCOMPATIBILITY***
+May cause re-[source]-ing of files that have not anticipated that before.
+
+2005-01-27 (new feature)[TIP 218] Tcl_Channel API update for threads (kupries)
+
+2005-01-27 (bug fix)[1109484] Tcl_Expr* updates for Tcl_WideInt (hobbs)
+
+2005-01-28 (platform support)[1021871] Solaris gcc 64-bit support (hobbs)
+
+2005-02-10 (bug fix)[1119369] Tcl_EvalObjEx: avoid shimmer loss of List intrep
+(sofer,macdonald)
+
+2005-02-11 (platform support) correct gcc builds for AIX-4+, HP-UX-11 (hobbs)
+
+2005-02-24 (bug fix)[1119798] prevent [source $directory] (porter,mpettigr)
+=> tcltest 2.2.8
+
+2005-03-10 (bug fix)[1153871] bad ClientData cast (porter,victorovich)
+
+2005-03-15 (platform support) OpenBSD ports patch (thoyts)
+
+2005-03-18 (bug fix)[1115904] restore recursion limit in direct eval (porter)
+
+2005-03-24 (bug fix) stop conflict between Tcltest and Thread packages (porter)
+
+2005-03-29 (platform support) allow msys builds without cygwin (hobbs)
+
+2005-04-01 (internal change)[1158008]  internal rep of "list" Tcl_Obj's
+now uses a refcounted struct (sofer)
+***POTENTIAL INCOMPATIBILITY***
+For any code that goes poking into the internals of "list" Tcl_Obj's
+
+2005-04-05 (performance)[1174551] Tcl_DecrRefCount of Tcl_Obj "chains" (sofer)
+
+2005-04-08 (performance)[1077262] better Tcl_Encoding cache lifetimes (porter)
+
+2005-04-10 (bug fix)[1180368] [interp invokehidden] mem leak (kenny,porter)
+
+2005-04-12 (performance)[1177363] startup encoding file scan (porter)
+
+2005-04-12 (performance)[1182459] [clock format] (kenny)
+
+2005-04-13 (bug fix) min buffer size dropped from 10 to 1 byte (gravereaux)
+
+2005-04-16 (bug fix)[1178445] fix memory waste at thread exit (vasiljevic)
+
+2004-04-16 (bug fix)[1084111] [array names] memory leak (ade,sofer)
+
+2005-04-19 (bug fix)[1185933] [clock] init clobbered global vars (ring,kenny)
+
+2005-04-19 (new feature) [::tcl::unsupported::EncodingDirs] - unsupported
+command to set search path for encoding files (porter)
+
+2005-04-20 (bug fix)[1090869] Tcl_GetInt accept 0x80000000, 64-bit
+(porter,singh)
+
+2005-04-22 (bug fix)[1187123] [string is boolean] respect EIAS (porter)
+
+2005-04-25 (enhancement) update to tzdata2005i (kenny)
+
+2005-04-25 (platform support) builds on Mac OS X 10.1 (steffen)
+
+2005-04-27 (new feature)[TIP 183] [open $f {... BINARY ...}] (porter)
+
+2005-04-29 (new feature)[TIP 176] simple index arithmetic (porter)
+
+2005-05-06 (platform support) x86_64 Solarix cc and Solaris 10 builds (hobbs)
+
+2005-05-10 (bug fix)[1198892] [expr {i**0}] error (kaitschu,markus)
+
+2005-05-10 (new feature)[TIP 132] floating-point conversion to string (kenny)
+***POTENTIAL INCOMPATIBILITY***
+For scripts that rely on (tcl_precision==12) number formatting
+
+2005-05-10 (new feature)[TIP 232] math functions as commands (kenny)
+***POTENTIAL INCOMPATIBILITY***
+Tcl_GetMathFuncInfo functioning is reduced; routine is now deprecated
+
+2005-05-13 (feature removed) TCL_NO_MATH compiler directive (porter)
+
+2005-05-14 (platform support) Mac OSX: configurable CoreFoundation API
+(steffen)
+
+2005-05-14 (platform support) Mac OSX: use realpath when threadsafe (steffen)
+
+2005-05-17 (feature removed) Tcl_ObjType's "list", "procbody", "index",
+"ensembleCommand", "localVarName", "levelReference, "boolean" are no
+longer registered (porter)
+***POTENTIAL INCOMPATIBILITY***
+For any callers of Tcl_GetObjType on those strings
+
+2005-05-20 (bug fix)[1201589] boolean literal prefix in expressions (porter)
+
+2005-05-24 (platform support) Darwin build support merged into unix (steffen)
+
+2005-05-24 (new feature)[1202209] Mac OSX: support [load] of .bundle binaries
+Can support [load] from memory as well (steffen)
+
+2005-05-24 (new feature)[1202178] [time] returns non-integer result (steffen)
+
+2005-05-25 (new feature)[TIP 182] [expr {bool(...)}] (mistachkin,porter)
+
+2005-05-30 (new feature)[TIP 229] [namespace path] (fellows)
+
+2005-05-31 (bug fix)[1082283] Unix: notifier thread now joinable (vasiljevic)
+
+2005-06-01 (new feature)[TIP 241] -nocase: lsort, lsearch, switch (mistachkin)
+
+2005-06-01 (bug fix)[1209759] "return TCL_RETURN;" could cause panic (porter)
+
+Documentation improvements [1075433,1085127,1117017,1124160,1149605,etc.]
+
+--- Released 8.5a3, June 4, 2005 --- See ChangeLog for details ---
+
+2005-06-06 (bug fix)[1213678] Windows/gcc: crash in stack.test (kenny)
+
+2005-06-07 (new feature)[TIP 208] [chan] and [chan truncate] (fellows)
+
+2005-06-07 (revert) Restored registration of "procbody" Tcl_ObjType (porter)
+Reduces the ***POTENTIAL INCOMPATIBILITY*** from 2005-05-17.
+
+2005-06-13 (bug fix)[1217375,1219176] [file mkdir] race (diekhans,darley)
+
+2005-06-14 (bug fix)[1220058] [namespace delete] crash (duquette,fellows)
+
+2005-06-17 (bug fix)[1221395] Tcl_LimitSetTime able to break [vwait] (fellows)
+
+2005-06-18 (bug fix)[1154163] [format %h] on 64-bit OS's (kraft,fellows)
+
+2005-06-21 (bug fix)[1201035,1224585] execution trace crashes (porter)
+
+2005-06-21 (bug fix)[1194458] Windows: [file split] (kenny,porter)
+
+2005-06-22 (bug fix)[1225727] Windows: pipe finalization crash (kenny)
+
+2005-06-22 (bug fix)[1225571] Windows: [file pathtype] buffer overflow (thoyts)
+
+2005-06-22 (bug fix)[1225044] Windows: UMR in pipe close (kenny)
+
+2005-06-23 (bug fix)[1225957] Windows/gcc: crashes in assembler code (kenny)
+
+2005-06-24 (bug fix) make Tcl_Preserve safe in Tk exit handlers (kenny)
+
+2005-07-01 (bug fix)[1222872] notifier spurious wake-up protection (vasiljevic)
+
+2005-07-05 (bug fix)[1230597] allow idempotent [namespace import] (porter)
+
+2005-07-15 (bug fix)[1237907] localtime() => NULL => crash (kenny)
+
+2005-07-21 (dropped support) IRIX 4, RISCos, Ultrix, and ancient BSD (kenny)
+***POTENTIAL INCOMPATIBILITY***
+
+2005-07-22 (enhancement)[1237755] 8.4 features in script library (fradin,porter)
+
+2005-07-24 (new feature) configure macros SC_PROG_TCLSH, SC_BUILD_TCLSH (dejong)
+2005-07-26 (bug fix)[1047286] cmd delete traces during namespace delete (porter)
+
+2005-07-26 (new unix feature)[1231015] ${prefix}/share on ::tcl_pkgPath (dejong)
+***POTENTIAL INCOMPATIBILITY***
+
+2005-07-27 (bug fix)[1214462] [unknown] can return exceptions (porter)
+
+2005-07-27 (new feature) value of ::tcl_precision now kept per-thread (porter)
+***POTENTIAL INCOMPATIBILITY***
+
+2005-07-28 (unix bug fix)[1245953] O_APPEND for >> redirection (fellows)
+
+2005-07-29 (bug fix)[1247135] [info globals] return only existing vars (fellows)
+
+2005-07-30 (new Darwin feature) TCL_LOAD_FROM_MEMORY configuration (steffen)
+
+2005-08-05 (bug fix)[1241572] correct [expr abs($LONG_MIN)] (kenny)
+
+2005-08-05 (Solaris bug fix)[1252475] recognize cp1251 encoding (wagner,fellows)
+
+2005-08-11 (config options) eliminated USE_THREAD_STORAGE option (kenny)
+
+2005-08-23 (toolchain support) autoconf-2.59 now required (dejong)
+
+2005-08-24 (new feature)[TIP 219] reflected channels ([chan create]) (kupries)
+
+2005-08-25 (bug fix)[1267380] [lrepeat] buffer overflow prevention (fellows)
+
+2005-08-26 (bug fix) fix [namespace ensemble] crashes in Snit (fellows)
+
+2005-08-29 (bug fix)[1275043] restore round() away from zero (kenny)
+
+2005-08-29 (bug fix)[1189657] correct [tcl::tm::roots] (porter)
+
+2005-09-07 (bug fix)[1283976] invalid [format %c -1] result (porter)
+
+2005-09-08 (new feature)[1242844][TIP 254] new types for Tcl_LinkVar (fellows)
+
+2005-09-07 (toolchain support) deprecate TCL_VARARGS*; stdarg.h assumed (porter)
+***POTENTIAL INCOMPATIBILITY***
+
+2005-09-15 (RHEL bug fix)[1287638] support open >2GB files RHEL 3 (palan)
+
+2005-09-08 (new feature)[TIP 255] [expr min()] and [expr max()] (hobbs)
+
+2005-09-30 (bug fix)[1306162] $argv encoding and list formatting (porter)
+
+2005-10-04 (bug fix)[1067708] [fconfigure -ttycontrol] leak (hobbs)
+
+2005-10-04 (bug fix)[1182373] [http::mapReply] update to RFC 3986 (aho,hobbs)
+=> http 2.5.2
+
+2005-10-04 (HPUX bug fix)[1204237] shl_load() and DYNAMIC_PATH (collins,hobbs)
+
+2005-10-05 (bug fix)[979640] buffer overrun mixing putenv(), ::env (bold,hobbs)
+
+2005-10-08 (new feature)[TIP 237] unlimited range for integers (kenny,porter)
+***POTENTIAL INCOMPATIBILITY*** for any code that relies on implicit truncation
+of integer calculations to the range of a C long
+
+2005-10-14 (platform support)[1256937] MSVC++ static builds (thoyts)
+
+2005-10-19 (bug fix)[1331475] [dict append] crash (bills,sofer)
+
+2005-10-20 (bug fix)[1333036] [lset] shared sublist handling (sofer)
+
+2005-10-23 (bug fix)[1335006] memleack in [glob] (melbardis,darley)
+
+2005-10-23 (bug fix)[1325803] Win: [file stat] on links (bonilla,darley)
+
+2005-11-01 (bug fix)[1337941] Tcl_TraceCommand() -> crash (devilliers,porter)
+
+2005-11-02 (platform support)[1256937] MSVC 8 support (thoyts)
+
+2005-11-03 (new Win NT/XP feature) Unicode console support (kovalenko,thoyts)
+
+2005-11-04 (bug fix)[1337229,1338280] [namespace delete] / unset traces (sofer)
+
+2005-11-04 (enhancement) Korean timezone abbreviations (kenny)
+
+2005-11-04 (platform support)[1163896] LynxOS [load] (heidibr)
+
+2005-11-04 (bug fix)[1334947] value refcount error in var setting (sofer)
+
+2005-11-04 (Win enhancement)[1267871] extended exit codes (newman,thoyts)
+
+2005-11-07 (bug fix)[1348775] unset trace memory leak (sofer)
+
+2005-11-08 (bug fix)[1162286] [package require] checks that the script
+registered by [package ifneeded] provides the version it claims (lavana,porter)
+*** POTENTIAL INCOMPATIBILITY ***
+
+2005-11-09 (bug fix)[1350293,1350291] [after $negative $script] fixed (kenny)
+
+2005-11-12 (bug fix)[1352734,1354540,1355942,1355342] [namespace delete]
+issues with [namespace path] and command delete traces (sofer,fellows)
+
+2005-11-18 (bug fix)[1358369] URL parsing standards compliance (wu,fellows)
+=> http 2.5.2
+
+2005-11-18 (revert) Restored registration of "list" Tcl_ObjType (porter)
+Reduces the ***POTENTIAL INCOMPATIBILITY*** from 2005-05-17.
+
+2005-11-18 (bug fix)[1359094] Tclkit crash (thoyts, kupries)
+
+2005-11-20 (bug fix)[1091431] Tcl_InitStubs failure crashes wish (english)
+
+2005-11-27 (platform support) Darwin 64bit, Tiger copyfile(), and
+Max OSX universal binaries support (steffen)
+
+2005-11-28 (bug fix) [clock] DST transition error (mackerras,kenny)
+
+2005-11-29 (bug fix)[1366683] [lsearch -regexp] backrefs (cleverly,fellows)
+
+2005-11-30 (performance) recoded portions of [clock] in C (kenny)
+
+2005-11-30 (enhancement) improved bytecode compiling of [switch] (fellows)
+*** POTENTIAL INCOMPATIBILITY ***
+For loading bytecode compiled and saved by earlier 8.5alpha releases
+
+2005-12-05 (Darwin bug fix)[1034337] NFS recursive file delete (steffen)
+
+2005-12-08 (platform support) Win x64 build (hobbs)
+
+2005-12-09 (bug fix)[1374778] [lsearch -start $pastEnd] => -1 (fellows)
+
+2005-12-12 (bug fix)[1377619] configure syntax error exposed in bash-3.1 (hobbs)
+
+2005-12-13 (bug fix)[1379349] [dict for] CoW error (ring,hippler,fellows)
+
+2005-12-18 (bug fix)[1382528] [dict for {k v} {} {}] crash (kovalenko,fellows)
+
+2005-12-27 clock tzdata updated to Olson's tzdata2005r (kenny)
+
+2005-12-27 libtommath updated to release 0.37 (kenny)
+
+2006-01-09 (bug fix)[1480572] [info level $l] => "namespace inscope" (porter)
+
+2006-01-11 (compat support)[1397843] when ::errorInfo is traced, fall back to
+old pattern of stack trace construction (porter).
+Reduces the ***POTENTIAL INCOMPATIBILITY*** from 2004-10-05.
+
+2006-01-12 (bug fix)[1366227] Win: [file stat] sharing violation (darley)
+
+2006-01-23 (bug fix)[1410553] Tcl_GetRange Unicode confusion (twylite,spjuth)
+
+2006-01-23 (bug fix)[1412695] args handling in precompiled procs (traum,sofer)
+
+2006-02-01 (new feature)[1275435][TIP 250] [namespace upvar] (sofer)
+
+2006-02-01 (new feature)[958222][TIP 181] [namespace unknown] (madden)
+
+2006-02-01 (new feature)[944803][TIP 194] [apply] (mistachkin)
+
+2006-02-08 (new feature)[1413934][TIP 258] [encoding dirs], etc. (porter)
+
+2006-02-09 (new feature)[1413115][TIP 215] auto-init [incr] (leitgeb)
+
+2006-03-02 (bug fix)[1379287] norm of paths with /../ back to root (porter)
+
+2006-03-03 (compat support) Restored registration of a "boolean" Tcl_ObjType
+(porter)
+Reduces the ***POTENTIAL INCOMPATIBILITY*** from 2005-05-17.
+
+2006-03-06 (bug fix)[1439836,1444291] fix TCL_EVAL_{GLOBAL,INVOKE} handling
+when auto-loading or exec traces are present (porter)
+
+2006-03-10 (bug fix)[1437595] Win socket finalize with threads (vasiljevic)
+
+2006-03-13 (revert 2005-07-26 change) ${prefix}/share on ::tcl_pkgPath (porter)
+
+2006-03-14 (bug fix)[1448251] TCLX.y_TM_PATH handling (noble, kupries)
+
+2006-03-14 (bug fix)[768659] pipeline error when last command missing (kupries)
+
+2006-03-18 (bug fix)[1193497] Win porting of [file writable] (darley,vogel)
+
+2006-03-18 (bug fix)[1084705] [glob -nocomplain] silence empty result only,
+no other errors (darley)
+***POTENTIAL INCOMPATIBILITY***
+
+2006-03-21 (platform enhancement)[823329] HFS globbing support (steffen)
+
+2006-03-23 (platform support) updated tcl.spec file (max)
+
+2006-03-28 (bug fix)[1064247] BSD: path normalization with realpath() (steffen)
+
+2006-04-03 (bug fix)[1462248] crash reading utf-8 chars spanning multiple
+buffers at end of file (kraft,kupries)
+
+2006-04-05 (bug fix)[1464039] Tcl_GetIndexFromObj: empty key (fellows)
+
+2006-04-05 (bug fix) overdue dde, registry  patchelevel increments (porter)
+=> dde 1.3.2
+=> registry 1.2
+
+2006-04-06 (bug fix)[1457515] TCL_IO_TRACK_OS_FOR_DRIVER_WITH_BAD_BLOCKING
+removed (steffen)
+
+2006-04-11 (bug fix)[1458266] enter/enterstep trace interference (leunissen)
+
+2006-04-12 (feature change)[1376892] revised definition of [:print:] (fellows)
+
+(platform support) Use of _ANSI_ARGS_ purged.  ANSI compiler required (fellows)
+
+Documentation improvements [1211078,1190891,1292427,1277503,1104682,1359183,
+1415725,666770]
+
+--- Released 8.5a4, April 27, 2006 --- See ChangeLog for details ---
+
+2006-05-04 (bug fix)[1480509] srand() accept wide input (porter,afredd)
+
+2006-05-05 (bug fix)[1481986] interactive Tcl_Main blocks main loop (porter,lin)
+
+2006-05-13 (bug fix)[1482718] proc re-compile: preserve the previous
+bytecode while references still on the stack (porter,ryazanov)
+
+2006-05-27 (bug fix)[923072] Darwin: made unthreaded CoreFoundation notifier
+naked-fork safe on Tiger (steffen)
+
+2006-06-20 (internal change) Dropped the internal routines used to hook into
+filesystem operations back in the pre-Tcl_Filesystem days. (porter)
+***POTENTIAL INCOMPATIBILITY***
+For extensions and programs that have never migrated to the supported Tcl 8.4
+interface for virtual filesystems
+
+2006-07-05 (enhancement) Expression parser rewrite avoids stack overflow,
+reduces from O(N^2) to O(N) complexity, and greatly improves syntas error
+messages (porter)
+***POTENTIAL INCOMPATIBILITY***
+For any code relying on exact error messages.
+
+2006-07-20 (platform support) Mac OS X weak linking (steffen)
+
+2006-07-20 (bug fix) Darwin: execve() works iff event loop not yet run (steffen)
+
+2006-07-24 (bug fix)[1518166] Uninitialized Tcl_DString (afredd)
+
+2006-07-30 (bug fix)[1426279,1505383,1494664,1531530] [clock] fixes (kenny)
+
+2006-08-09 (bug fix)[1531184] [dict for {file stat} x {}] crash (fellows)
+
+2006-08-10 (bug fix)[1538262,1530474] code cleanup; optimizations (afredd)
+
+2006-08-18 (bug fix) intermittent failures in TclUnixWaitForFile() (steffen)
+
+2006-08-18 (platform support) Darwin x86_64 (steffen)
+
+2006-08-21 (bug fix)[1457797] Darwin 64-bit notifier hang (steffen)
+
+2006-08-21 (bug fix) Darwin: recursively called event loop (steffen)
+
+2006-08-21 (enhancement) Darwin: nanosec resolution clicks and [time] (steffen)
+
+2006-08-28 (bug fix)[1547681] TclFormatObj count arguments (mistachkin,porter)
+
+2006-08-28 (bug fix) stack.test failure on FreeBSD (mistachkin)
+
+2006-08-30 (bug fix)[1548263] filesystem segfaults (hobbs,mccormack)
+
+2006-08-31 (bug fix)[1541274] [expr {sqrt(-1)}] => -NaN (suchenwirth,porter)
+
+2006-09-06 (bug fix)[999544] use of MT-safe system calls (vasiljevic)
+
+2006-09-10 (platform support) Darwin: msgcat use CFLocale (steffen)
+=> msgcat 1.4.2
+
+2006-09-10 (new feature) tcltest option: -verbose line (steffen)
+=> tcltest 2.3a1
+
+2006-09-19 (bug fix)[1555271,1561260] Several ** operator bugs (porter)
+
+2006-09-22 (bug fix)[1562528] NULL terminates variadic calls (fellows,ryazanov)
+
+2006-09-22 (new feature)[1520767][TIP 268] [package] alpha/beta version;
+[package require] ranges, [package prefer] selection mode (kupries)
+
+2006-09-26 (platform support) MSVC8 AMD64 support (thoyts)
+
+2006-09-27 (bug fix)[1567222] bignum << errors (porter)
+
+2006-09-30 (enhancement)[1190441] quiet no-op [history] (sofer)
+
+2006-10-04 clock tzdata updated to Olson's tzdata2006m (kenny)
+
+2006-10-05 (bug fix)[1570718] make [lappend $nonList] complain (sofer,virden)
+
+2006-10-05 (bug fix)[1122671] alignment fixes in unicode encoding routines
+(hobbs,staplin)
+
+2006-10-05 (enhancement) Allow "_" in Tcl Module filenames (kupries)
+
+2006-10-05 (new feature) [set ::http::strict 0] (default value is 1) to disable
+URL validity checking against RFC 2986 (hobbs)
+=> http 2.5.3
+
+2006-10-06 (new feature)[1565751][TIP 275] [binary scan] unsigned (thoyts)
+
+2006-10-10 (bug fix)[1566526] crash cleaning up [namespace path] data (porter)
+
+2006-10-12 (bug fix)[1576006] better error messages from [interp alias] (sofer)
+
+2006-10-13 (platform support) get stack size on Darwin (steffen)
+
+--- Released 8.5a5, October 20, 2006 --- See ChangeLog for details ---
+
+2006-10-20 (configure change) Added autodetection for OS-supplied timezone
+files (max)
+
+2006-10-23 (enhancement)[1577278] Ensure the Tcl call stack always has a
+CallFrame, even at level 0 (sofer)
+	*** POTENTIAL INCOMPATIBILITY for users of tclInt.h ***
+
+2006-10-23 (enhancement)[1577492] Tcl_PushCallFrame and [info level]
+enhanced for ensemble rewrites (sofer)
+	*** POTENTIAL INCOMPATIBILITY for [info level 0] on interp alias ***
+
+2006-11-02 (feature change)[TIP 293] Replace {expand} with {*} (hobbs)
+	*** POTENTIAL INCOMPATIBILITY with previous 8.5 alphas only ***
+
+2006-11-04 (new feature)[TIP 274] Exponentiation operator is right
+associative (porter)
+
+2006-11-09 (new feature)[TIP 272] Added [lreverse] and [string reverse]
+commands (fellows)
+
+2006-11-14 (new feature)[TIP 261] [namespace import] returns list of
+imported commands (porter)
+
+2006-11-15 (new feature)[TIP 270] New C routines Tcl_ObjPrintf,
+Tcl_AppendObjToErrorInfo, Tcl_Format, Tcl_AppendLimitedToObj,
+Tcl_AppendFormatToObj, Tcl_AppendPrintfToObj (porter)
+
+2006-11-22 (feature change) Moved TCL_REG_BOSONLY from tcl.h to tclInt (porter)
+
+2006-11-22 (new feature)[TIP 269] Added [string is list] classification
+command (mistackin, fellows)
+
+2006-11-25 (new feature)[TIP 174] Added commands corresponding to most
+expr operators in ::tcl::mathop (fellows)
+
+2006-11-26 (platform support)[1230558] --enable-64bit on more systems (steffen)
+
+2006-11-27 (bug fix)[1602208] Fix 64-bit handling of select() on unix where
+fd was greater than 32 (fontaine, kenny)
+
+2006-11-28 (new feature)[TIP 280] Added [info frame] command for more
+Tcl-level debugging information (kupries)
+
+2006-12-01 (feature change)[TIP 298] Change Tcl_GetBignumAndClearObj to
+Tcl_TakeBignumFromObj (porter)
+
+2006-12-01 (new feature)[TIP 287] Added [chan pending] subcommand (cleverly)
+
+2006-12-01 (new feature)[TIP 299] Added isqrt() expr operator (kenny)
+
+2006-12-04 (new feature)[TIP 267] Added -ignorestderr option to exec (fellows)
+
+2006-12-05 (new feature)[TIP 291] ::tcl_platform(pointerSize) key (kupries)
+
+2007-01-11 (configure change) Remove "-Wconversion" from deflt CFLAGS (english)
+
+2007-01-25 (configure change) Ensure CPPFLAGS env var is used when set (steffen)
+
+2007-02-19 (configure change) Use SHLIB_SUFFIX=".so" on HP-UX IA64 (was
+".sl") (hobbs)
+
+2007-02-20 (bug fix)[1479814] Handle Windows NT \\?\... extended paths (thoyts)
+
+2007-03-01 (bug fix)[1671138] Fix infinite loop in compiled foreach with an
+empty list (fellows)
+
+2007-03-07 (enhancement) Improved Windows time zone tables to handle new US
+DST rules (kenny)
+
+2007-03-09 (enhancement) Improved Y2038 compliance of zoneinfo files (kenny)
+
+2007-04-02 (enhancement) Added bytecode compilation for global, variable,
+upvar and namespace upvar (sofer)
+
+2007-04-20 (bug fix) Improve clock localization for Japanese locale (kenny)
+
+2007-04-20 (enhancement) Document Tcl_SetNotifier & Tcl_ServiceModeHook (kenny)
+
+2007-04-23 (bug fix) fts_open() crash on 64bit Darwin 8 or earlier (steffen)
+
+--- Released 8.5a6, April 25, 2007 --- See ChangeLog for details ---
+
+2007-04-30 (bug fix)[1705778] many valgrind-detected leaks corrected
+
+2007-05-01 (bug fix)[1710709] leak in [string map] (porter)
+
+2007-05-02 (bug fix)[1710707] leaks in filesystem paths (mistachkin,kenny)
+
+2007-05-18 (feature change) {expand} syntax support removed. (porter)
+	*** POTENTIAL INCOMPATIBILITY with previous 8.5 alphas only ***
+
+2007-05-29 (bug fix)[1712723] Joinable thread death on 64-bit (virden,hobbs)
+
+2007-05-30 (feature change)[1725186] When expanded literals are parsed,
+(example: {*}{1 2 3}), TCL_TOKEN_EXPAND_WORD token is no longer returned.
+Tokens reflecting the expansion are returned instead. (porter)
+	*** POTENTIAL INCOMPATIBILITY with previous 8.5 alphas only ***
+
+2007-06-06 (platform support) Darwin: add plist to tclsh (steffen)
+
+2007-06-12 (enhancement) [info] is now a [namespace ensemble] (fellows)
+
+2007-06-20 (enhancement) better `make html` results (hobbs)
+
+2007-06-21 (feature change)[1740962] leave traces created during execution
+of traced command do not fire (sofer)
+	*** POTENTIAL INCOMPATIBILITY ***
+
+2007-06-23 (bug fix) Darwin: prevent post-fork() abort() (steffen)
+
+2007-06-27 (bug fix)[1743941] Infinite loop in Tcl_CreateTrace traces (porter)
+
+2007-06-29 (enhancement) Tcl_Alloc alignment on Darwin (steffen)
+
+2007-06-30 (bug fix)[1726873] crash in thread sync objects (vasiljevic,twylite)
+
+2007-06-30 (bug fix)[1717186] [lsort -command \{ $l] leak (afredd,fellows)
+
+2007-07-05 (bug fix)[1743676] no command named "" error message (porter,virden)
+
+2007-07-11 (bug fix)[1752146] [while 1 {}] & [interp limit] on commands (sofer)
+
+2007-07-31 (bug fix)[681877] tcl_platform(user) from system, not env (fellows)
+
+2007-07-31 (enhancement)[1750051] space efficiency of Tcl variables (sofer)
+	*** POTENTIAL INCOMPATIBILITY for C code that accesses internal
+	Tcl structs Var, Bytecode, Namespace, or CallFrame. ***
+
+2007-08-01 (enhancement)[1764318] word.tcl proc rewrites (petasis,fellows)
+
+2007-08-08 (bug fix)[1770224] [tcl::mathop::>> $big1 $big2] errors (porter)
+
+2007-08-14 (platform support) Darwin [load] from VFS on intel & 64bit (steffen)
+
+2007-08-15 (bug fix)[1773127] corrected open mode "a+" (rottman,fellows)
+
+2007-08-16 (bug fix)[1773040] ::errorInfo trace crash (janssen,porter)
+
+2007-08-16 (performance)[1564517] pre-compile constant expressions (porter)
+
+2007-08-21 (bug fix)[1775878] 'puts \' in interactive tclsh failed to move to
+prompt for continuation line (porter)
+
+2007-08-25 (bug fix)[1781282] [clock scan] case senstivity (kenny)
+
+2007-08-25 (performance)[1767293] ** on native integer types (kenny)
+
+2007-09-03 clock tzdata updated to Olson's tzdata2007g (kenny)
+
+2007-09-06 (platform support) Darwin: drop support for Xcode 1.5 project, add
+project for Xcode 3.0 (steffen)
+
+2007-09-08 (bug fix)[1786481] nested [dict update] crash (fellows)
+
+2007-09-08 (bug fix)[1710710] TclPtrSetVar leak (mistachkin,sofer)
+
+2005-09-09 (feature removed) Tcl_ObjType "nsName" no longer registered (porter)
+	*** POTENTIAL INCOMPATIBILITY for Tcl_GetObjType("nsName") ***
+
+2007-09-10 (bug fix)[1740631] Linked variable unlink prevention (maros,hobbs)
+
+2007-09-11 (bug fix)[1786481] [dict update] stack management (sofer)
+	*** POTENTIAL INCOMPATIBILITY with previous 8.5 alpha bytecode only ***
+
+2007-09-11 (bug fix)[1578344] [package require -exact] 8.4 compat (porter)
+	*** POTENTIAL INCOMPATIBILITY with previous 8.5 alphas only ***
+
+2007-09-11 (bug fix)[1772989,1071322] Support _, : in test constraints (porter)
+=> tcltest 2.3b1
+
+2007-09-11 (platform support) Windows AMD64 support (thoyts)
+
+2007-09-14 (enhancement)[1793984] DTrace provider for Tcl (steffen)
+
+2007-09-14 (bug fix)[1519940] surplus ns path invalidation (fellows,bauer)
+
+2007-09-15 (platform support) SunOS-5.1x link with cc, not ld (steffen)
+
+2007-09-17 (platform support)[1748251] Fix NetBSD link failures (english)
+
+(bug fix)[1066755] Several stack efficiency efforts increases recursion limit
+on Windows to be larger than the default [interp recursionlimit] value
+
+--- Released 8.5b1, September 26, 2007 --- See ChangeLog for details ---
+
+2007-10-02 (bug fix)[1806422] proper [tcl::tm::path] autoload (porter)
+
+2007-10-02 (bug fix) Improve Tcl_DecrRefCount() robustness (staplin)
+
+2007-10-11 (bug fix)[1805887] [string is int -failindex] for 0o, 0b (porter)
+
+2007-10-15 (bug fix)[1813528] Tcl_ParseBraces read past buffer (mistachkin)
+
+2007-10-25 (bug fix)[1726873] intermittent crash in threads (vasiljevic)
+
+--- Released 8.5b2, October 26, 2007 --- See ChangeLog for details ---
+
+2007-10-27 (bug fix)[1821159] fixed broken compile on x86_64 (sofer)
+
+2007-10-27 (bug fix)[1810264] stop panic in RE lexer (fellows)
+
+2007-10-28 (enhancement)[1826906] Embed iso8859-1 encoding in libtcl (fellows)
+
+2007-11-01 (bug fix)[1808258] [string is ascii \000] (fellows)
+
+2007-11-05 (bug fix)[1823576] [fconfigure $serial -xchar \000] (cassof)
+
+2007-11-07 (performance)[1827996] binary glob matching (hobbs)
+
+2007-11-07 (performance) binary [gets] (hobbs)
+
+2007-11-09 (performance)[1829248] interp state reset (sofer)
+
+2007-11-10 (performance) stack checking (sofer)
+
+2007-11-10 (performance) list indexing bytecode (sofer)
+
+2007-11-11 (performance)[1830038] macros to fetch Tcl_Obj intreps (sofer)
+
+2007-11-11 (performance)[1830166] RE bytecode for simple cases (hobbs)
+
+2007-11-13 (performance) [switch] & [regexp] use RE bytecode (hobbs, fellows)
+
+2007-11-14 (performance) bytecode for [info exists] (fellows)
+
+2007-11-15 (new feature)[1231022] configure option: --disable-rpath (fellows)
+
+2007-11-15 (bug fix)[1810038] infinite loop in RE compiler (lane,porter)
+
+Many significant documentation improvements (fellows, sofer)
+
+--- Released 8.5b3, November 19, 2007 --- See ChangeLog for details ---
+
+2007-11-20 (enhancement) string rep of dict has stable order (fellows)
+
+2007-11-21 (enhancement) compiled ensemble support (fellows)
+
+2007-11-22 (enhancement) [dict] is now an ensemble (fellows)
+
+2007-11-23 (enhancement) [string] is now an ensemble (fellows)
+
+2007-11-26 (bug fix)[1815573] Correct stack checking failure (sofer,golovan)
+
+2007-11-27 (bug fix)[800753] Document single byte char limit for
+[chan configure -eofchar] (cassoff)
+
+2007-12-03 (enhancement)[1836519] [switch $val $body] safe/fast (fellows,spjuth)
+
+2007-12-03 (release) tcltest package bump to 2.3.0 (porter)
+
+2007-12-03 (bug fix)[1618235] fix BSD compile errors (fellows)
+
+2007-12-05 (bug fix)[1844789] fix [lsearch -exact -integer] crash (fellows)
+
+2007-12-05 (performance)[1845092] Tcl_ObjType for channel names (hobbs)
+
+2007-12-14 (bug fix)[1602539] NUL pollution in [glob] result (hobbs)
+
+2007-12-17 (bug fix)[1851832,1851524] memory alignment correction (sofer)
+
+2007-12-18 (bug fix)[1810264] revised regexp engine to prevent debilitating
+over-consumption of resources (drewry,lane,ormandy,fellows)
+
+Several documentation and release notes improvements
+
+--- Released 8.5.0, December 20, 2007 --- See ChangeLog for details ---
+
+2007-12-23 (bug fix)[1857126] restore backref support to regexps (hobbs)
+
+2007-12-26 (enhancement)[1856994] [lsort] performance (sofer)
+
+2008-01-10 (bug fix)[1867855] fix [format %lli 0] crash (porter)
+
+2008-01-11 (bug fix)[1850424,1860425] stack checking on *bsd (sofer,noble)
+
+2008-01-13 (bug fix)[1353846] crash in read-only serial (hobbs,newman)
+
+2008-01-15 (bug fix)[1869989] mem leak; expr literals (porter,melbardis)
+
+2008-01-20 (bug fix)[1869405] binary [gets]; stacked channels (hobbs,ficicchia)
+
+2008-01-22 (bug fix)[1867855] fix [lreverse {}] crash (sofer,madden)
+
+2008-01-30 (bug fix)[1882373] fix Tcl_GetAlias pointer code (an00na)
+
+Several documentation and release notes improvements
+
+--- Released 8.5.1, February 5, 2008 --- See ChangeLog for details ---
+
+2008-02-06 (enhancement) [clock format] performance (kenny)
+
+2008-02-12 (bug fix)[1891827] compiled [switch -nocase] error (fellows)
+
+2008-02-22 (bug fix)[1818565] missing state array in http::status (thoyts)
+=> http 2.5.4
+
+2008-02-26 (bug fix)[1868845] corrected [eof] ordering (thoyts)
+
+2008-02-26 (new feature) [http::meta] command (thoyts)
+=> http 2.5.5
+
+2008-02-26 (bug fix)[1902436] fixed regexps ending in \* (hobbs)
+
+2008-02-27 (bug fix)[1862555,1902423] [clock] range & l10n (kenny)
+
+2008-02-28 (bug fix) [return -level 0] memory leak (porter)
+
+2008-02-28 (bug fix) [format %llx $big] memory leak (porter)
+
+2008-02-28 (bug fix) expression parser error message memory leak (porter)
+
+2008-02-28 (bug fix) memory leak when enter trace modifies command (porter)
+
+2008-02-29 (enhancement) Consumer refcounting for Tcl_SetReturnOptions()
+and Tcl_AddObjToErrorInfo() (spjuth,porter)
+	*** POTENTIAL INCOMPATIBILITY ***
+
+2008-03-07 (bug fix)[1899164] Avoid expr and script bytecode confusion (porter)
+
+2008-03-07 (bug fix)[1904907] finalize crash in Tcl_GetReturnOptions (kupries)
+
+2008-03-10 (bug fix)[1893815] expr {abs(-1e-350)} => -0.0 (porter)
+
+2008-03-10 (bug fix)[1901113] crash in [tcl::Bgerror {} {}] (madden,porter)
+
+2008-03-11 (bug fix)[1911919] unset trace inf loop in namespace delete (sofer)
+
+2008-03-12 (new feature) some HTTP 1.1 support in http (and more!) (hobbs)
+=> http 2.7
+
+2008-03-13 (enhancement) support space in INSTALL_ROOT or $builddir (steffen)
+
+2008-03-16 (bug fix)[1903325] bytecode stack space prediction crash (fellows)
+
+2008-03-18 (bug fix)[1914604] Tcl Modules: encoding fixed to utf-8; environment
+variables without "." added to customization hooks (kupries)
+	*** POTENTIAL INCOMPATIBILITY ***
+
+2008-03-18 (bug fix)[1914503] alignment of TclStackAlloc() return (sofer)\
+
+2008-03-20 (bug fix)[1868171] expose Tcl_GetMemoryInfo (for AOLserver) (fellows)
+
+2008-03-24 (bug fix)[1923966] crash in [binary format x0s] (thoyts)
+
+2008-03-27 (platform support)[1921166] Solaris 64bit build fixes (steffen)
+
+2008-03-27 clock tzdata updated to Olson's tzdata2008b (kenny)
+
+--- Released 8.5.2, March 28, 2008 --- See ChangeLog for details ---
+
+2008-03-30 (bug fix)[1783544] more robust TclIsNaN() (kenny,teterin)
+
+2008-04-01 (interface)[1819422] tclStubsPtr no longer in libtcl (porter)
+	*** POTENTIAL INCOMPATIBILITY ***
+
+2008-04-01 (bug fix)[1839067] FP round fix for Solaris/x86 (kupries,schlenker)
+
+2008-04-02 (bug fix)[780533,1932639] [fcopy] callbacks unreliable (ferrieux)
+
+2008-04-02 (interface)[1819422] libtclstub symbols MODULE_SCOPE (steffen)
+
+2008-04-04 (bug fix) [chan postevent] crash (kupries)
+
+2008-04-07 (bug fix) Fix broken [format {% d}] (max)
+
+2008-04-07 (bug fix)[1350564] Bi-directional [fcopy] now supported (ferrieux)
+
+2008-04-16 (bug fix)[1938497] Tcl_SetNotifier() fixes (steffen)
+
+2008-04-16 (interface)[1938497] make stubs tables 'static const' (steffen)
+
+2008-05-02 (new feature) [binary] is now a [namespace ensemble] (thoyts)
+
+2008-05-07 (bug fix) [dict append] crash (mccormack,fellows)
+
+2008-05-21 (bug fix)[1968882] [info complete "\\\n"] => 0 (porter)
+
+2008-05-22 (bug fix)[1968245] Tcl_LogCommandInfo() accept length=-1 (darroch)
+
+2008-05-23 (bug fix)[1965787] 32-bit overflow in [tell] result (ferrieux)
+
+2008-05-31 (new feature)[TIP 257]  [oo::*] commands from TclOO (fellows)
+
+2008-06-04 (new feature)[TIP 317] [binary encode]; [binary decode] (thoyts)
+
+2008-06-06 (new feature)[TIP 230] [chan push]; [chan pop] (kupries)
+
+2008-06-08 (enhancement)[1973096] bytecompiled [uplevel] scripts (sofer)
+
+2008-06-12 (platform support) Solaris static build with DTrace (steffen)
+
+2008-06-12 (platform support) Solaris/amd64 gcc 64bit support (steffen)
+
+2008-06-13 (new feature)[TIP 285] [interp cancel]; Tcl_CancelEval() (mistachkin)
+
+2008-06-20 (bug fix)[1999035] make [interp bgerror $i] act in $i (porter)
+
+2008-06-23 (bug fix)[1972879] bad path intrep caching (porter)
+
+2008-06-24 (bug fix)[1999176] crash in [glob -dir {} a] (porter)
+
+2008-06-25 (bug fix)[1999119] Support TM packages in Safe Base (kupries)
+
+--- Released 8.6a1, June 25, 2008 --- See ChangeLog for details ---
+
+2008-06-29 (bug fix)[2004480] plug memory leaks (ade,porter,steffen)
+
+2008-07-01 (enhancement)[1905562] embed recursion limit in RE engine (fellows)
+
+2008-07-03 (bug fix)[1969717] fix package finding on Samba shares (jos)
+
+2008-07-03 (bug fix)[1987821] mem leak in [seek] on reflected chan (kupries)
+
+2008-07-13 (enhancement)[2017110] new Non-Recursive Evaluation implementation
+enables deep Tcl evaluation stacks without deep C stacks. (sofer)
+
+2008-07-20 (enhancement)[2008248] dict->list preserve item intreps (pasadyn)
+
+2008-07-21 (bug fix)[582506] imported cmds now fire execution traces (sofer)
+
+2008-07-21 (bug fix)[2015723] [file] bad use of inodes on Windows (thoyts)
+
+2008-07-21 (new feature)[TIP 304] [chan pipe] (ferrieux)
+
+2008-07-21 (bug fix)[2021443] more consistent "wrong # args" msgs (nijtmans)
+
+2008-07-21 (enhancement) [info frame] returns file data in more cases (kupries)
+
+2008-07-29 (bug fix)[2030670] fix rare panic in TclStackFree (pasadyn,sofer)
+
+2008-08-01 Tcl_Finalize() no longer called implicitly on DLL_PROCESS_DETACH.
+
+2008-08-05 (enhancement)[1994512] async connect logic simplified (jenglish)
+
+2008-08-06 (bug fix)[2040295] stopped supplying a workaround for bugs
+in Itcl's use of [namespace code].  Itcl now supplies its own workaround.
+	*** POTENTIAL INCOMPATIBILITY for older Itcl releases ***
+
+2008-08-06 (bug fix)[2039178] repaired guard against dispatching oo methods
+in a deleted interp. (porter)
+
+2008-08-08 tzdata updated to Olson's tzdata2008e (kenny)
+
+2008-08-11 (bug fix)[2046846] 64bit support for http zlib crc (thoyts)
+=> http 2.7.1
+
+2008-08-11 (enhancement) automatic [package provide] for TMs (kupries)
+
+2008-08-17 (bug fix)[2055782] crash involving Tcl_ConcatObj (sofer)
+
+2008-08-21 (new feature) CONST-ified Tcl routines passing (Tcl_ObjType *),
+(Tcl_Filesystem *), or (Tcl_Timer *) arguments (nijtmans,porter)
+	*** POTENTIAL INCOMPATIBILITY ***
+
+2008-08-21 (bug fix)[2065115] Restored ***= regexp functioning (hobbs,porter)
+
+--- Released 8.6a2, August 25, 2008 --- See ChangeLog for details ---
+
+2008-08-29 (bug fix)[2082299] Install TclOO header files (fellows)
+
+2008-09-01 oo methods called during interp deletion no longer skipped if
+they do not need the dying interp (fellows)
+
+2008-09-02 (support) Dropped support for pre-ANSI compilers.  (porter)
+
+2008-09-04 (bug fix)[2093947] var unset trace in coroutine (fellows,sofer)
+
+2008-09-10 (enhancement) efficient list->dict conversion (elby,fellows)
+
+2008-09-10 (bug fix)[2102930] faulty numLevels count (madden,sofer)
+
+2008-09-16 (bug fix)[2114165] eval failure following cancel (sofer)
+
+2008-09-17 (bug fix)[2116053] export [min] and [max] from tcl::mathfunc (sofer)
+
+2008-09-22 (new feature)[TIP 320] oo common variable declaration (fellows)
+
+2008-09-24 (new feature)[TIP 316] portable access to Tcl_StatBuf (fellows)
+
+2008-09-24 (new feature)[TIP 323] [file delete], [file mkdir] zero pathNames (porter)
+
+2008-09-25 (new feature)[TIP 315] new var: tcl_platform(pathSeparator) (vu,fellows)
+
+2008-09-25 (new feature)[TIP 323] [global], [variable] zero varNames (porter)
+
+2008-09-26 (new feature)[TIP 323] [lassign], [namespace upvar], [my variable] zero varNames (porter)
+
+2008-09-26 (new feature)[TIP 323] [tcl::tm::path add|remove] zero pathNames (porter)
+
+2008-09-26 (new feature)[TIP 323] [lrepeat] zero elements; zero repeats (porter)
+
+2008-09-27 (bug fix)[2130992] prevent overflow crash in [lrepeat] (fellows)
+
+2008-09-28 (new feature)[TIP 314] ensemble parameters before subcommand (hellström,fellows)
+
+2008-09-29 (new feature)[TIP 318] revised defaults for [string trim] (poser)
+	*** POTENTIAL INCOMPATIBILITY ***
+
+2008-09-29 (new feature)[TIP 313] [lsearch -bisect] (spjuth)
+
+2008-09-29 (new feature)[TIP 326] [lsort -stride] (elby)
+
+2008-09-29 (new feature)[TIP 323] [linsert] zero elements (porter)
+
+2008-09-29 (new feature)[TIP 323] [glob] zero patterns (porter)
+
+2008-10-02 (new feature)[TIP 330] interp->result access disabled (kenny)
+	*** POTENTIAL INCOMPATIBILITY ***
+
+2008-10-03 (new feature)[TIP 265] Tcl_ParseArgv() (bromley)
+
+2008-10-03 (new feature)[TIP 195] [tcl::prefix] (spjuth)
+
+2008-10-04 (new feature) CONST-ified Tcl routines Tcl_GetIndexFromObj,
+Tcl_RegisterConfig, Tcl_InitCustomHashTable, and routines passing
+(Tcl_ChannelType *). (nijtmans)
+	*** POTENTIAL INCOMPATIBILITY ***
+
+2008-10-04 (bug fix)[2059262] unload only libraries marked unloadable (nijtmans)
+	*** POTENTIAL INCOMPATIBILITY ***
+
+2008-10-05 (new feature)[TIP 331] [lset listVar end+1 $value] (kenny)
+
+2008-10-05 (bug fix)[2143288] correct bad isqrt() results (boffey,kenny)
+
+2008-10-05 (new feature) CONST-ified return value of the
+Tcl_FSFileAttrStringsProc prototype. (nijtmans)
+	*** POTENTIAL INCOMPATIBILITY for Tcl_Filesystems ***
+
+2008-10-07 (new feature)[TIP 327] [tailcall] (sofer)
+
+2008-10-07 (new feature)[TIP 328] [coroutine],[yield],[info coroutine] (sofer)
+
+2008-10-08 (bug fix)[2151707] fix stack trace from variable trace (porter)
+
+2008-10-10 (bug fix)[2155658] crash in oo method export (fellows)
+
+--- Released 8.6a3, October 10, 2008 --- See ChangeLog for details ---
+
+2008-10-13 (bug fix) Fix ability to join threads on 64-bit Windows (thoyts)
+
+2008-10-23 (bug fix)[2186888] Direct-eval [for] handling of [continue] was
+broken by NRE reform (sofer,porter)
+
+2008-10-24 (bug fix) fix failure to read SHOUTcast streams (thoyts)
+=> http 2.7.2
+
+2008-10-27 (enhancement) system encoding at startup is now "iso8859-1", and
+no longer "identity".  Use of identity encoding minimized (porter)
+	*** POTENTIAL INCOMPATIBILITY ***
+
+2008-10-31 (bug fix)[2200824] revised [oo::define] to include caller
+context when resolving names. (nassau,fellows)
+
+2008-11-10 (bug fix)[2255235] [platform::shell::LOCATE] update (ring,kupries)
+=> platform::shell 1.1.4
+
+2008-11-13 (bug fix)[2269431] VFS [load] -> tempfile litter (ficicchia,nijtmans)
+
+2008-11-26 (bug fix)[2114900] updated tclIndex file (cassoff,kenny)
+
+2008-11-27 (bug fix)[2251175] [{*}{\{}] errors (hellström,ferrieux,porter)
+
+2008-11-29 (new feature)[TIP 210] [file tempfile] (techentin,fellows)
+
+2008-11-30 (bug fix)[2362156] [clock]: colon in format string (mizuno,kenny)
+
+2008-12-02 (bug fix)[2270477] hang in channel finalization (ferrieux,kupries)
+
+2008-12-02 (new feature)[TIP 336] Tcl_*ErrorLine() routines.  Direct access
+to the errorLine field of the interp struct denied by default. (porter)
+	*** POTENTIAL INCOMPATIBILITY ***
+	*** Define USE_INTERP_ERRORLINE to restore access for legacy code ***
+
+2008-12-04 (bug fix)[2385549] [file normalize] failed on some paths (porter)
+
+2008-12-05 (new feature)[TIP 307] Tcl_TransferResult() (leunissen,fellows)
+
+2008-12-05 (new feature)[TIP 335] Tcl_InterpActive() (mistachkin,fellows)
+
+2008-12-09 (new feature)[TIP 337] Tcl_BackgroundException() (porter)
+
+2008-12-10 (new feature)[TIP 341] >1 [dict filter] patterns (hellström,fellows)
+
+2008-12-10 (new feature)[TIP 343] [format %b $n] [scan $s %b] (ferrieux)
+
+2008-12-10 tzdata updated to Olson's tzdata2008i (kenny)
+
+2008-12-11 (new feature)[TIP 234] [zlib] and Tcl_Zlib*() (sheffers,fellows)
+
+2008-12-11 (bug fix)[2407783] spoil ChannelState when channel name passes
+among multiple interps (kupries)
+
+2008-12-12 (new feature)[TIP 322] Tcl_NR*() routines to enabled non-recursive
+evaluation in extensions (sofer,kenny)
+
+2008-12-09 (new feature)[TIP 338] Tcl_*StartupScript() (porter)
+	*** POTENTIAL INCOMPATIBILITY for callers of Tcl*Startup* routines ***
+
+2008-12-16 (new feature)[TIP 329] [try] [throw] (davel,fellows)
+
+2008-12-17 (new feature)[TIP 308] package tdbc 1.0b1 (kenny)
+
+2008-12-18 (new feature)[TIP 332] [close $chan read|write] (ferrieux)
+
+2008-12-18 (bug fix)[2444274] panic in long commands from {*} (goth,porter)
+
+--- Released 8.6b1, December 19, 2008 --- See ChangeLog for details ---
+
+2008-12-27 [TIP 234] Tcl_Zlib* interface revisions (fellows)
+	*** INCOMPATIBILITY with interface of 8.6b1 ***
+
+2009-01-02 (platform support)[878333] IRIX compat for mkstemp() (fellows)
+
+2009-01-03 (bug fix)[2481670] [clock add] error message (talvo)
+
+2009-01-05 (bug fix)[2412068] NR-enable [source] (fellows)
+
+2009-01-06 (bug fix)[2489836] crash unknown method dispatch (nadkarni,fellows)
+
+2009-01-06 (bug fix)[2481109] fix context of instance name check (fellows)
+
+2009-01-08 (enhancement) more -errorcode values (fellows)
+
+2009-01-19 (new feature) CONFIG_INSTALL_DIR - where tclConfig.sh goes (cassoff)
+
+2009-01-19 (platform support) better tools for BSD ports (cassoff)
+
+2009-01-21 (bug fix)[2458202] exit crash with [chan create]d channel (kupries)
+
+2009-01-26 (bug fix)[2446662] uniformly declare EOF on RST on sockets (ferrieux)
+
+2009-01-26 (bug fix)[1028264] delay WSACleanup() from under our feet (ferrieux)
+
+2009-01-29 (bug fix)[2519474] Tcl_FindCommand() bug exposed by oo (fellows)
+
+2009-01-29 (bug fix)[2537939] Fix Tcl_OOInitStubs() for no-stubs build (fellows)
+
+2009-02-04 (bug fix)[2561746] [string repeat] overflow crash (porter)
+
+2009-02-05 (enhancement) optimize string operations on bytearrays (fellows)
+
+2009-02-12 (bug fix) enable simpler [oo::define] extension (ferri,fellows)
+
+2009-02-15 (bug fix)[2603158] Tcl_AppendObjToObj: append to self crash (porter)
+
+2009-02-17 (platform support) MSVC and _WIN64 (hobbs)
+
+2009-02-20 (bug fix)[2571597] [file pathtype /a] wrong result (nadkarni,porter)
+
+2009-03-03 (bug fix)[2662434] [zlib crc32] result now unsigned (gavilan,fellows)
+
+2009-03-15 (platform support) translate SIGINFO where defined (BSD) (teterin)
+
+2009-03-15 (bug fix)[2687952] TSD struct memleak (mistachkin)
+
+2009-03-18 (bug fix)[2688184] memleak in [file normalize] (mistachkin)
+
+2009-03-20 (bug fix)[2597185] crash in Tcl_AppendStringToObj (porter)
+
+2009-03-20 (bug fix)[2561794,2669109,2494093,2553906] string overflow (porter)
+
+2009-03-22 (bug fix)[2502037] NR-enable [namespace unknown] (sofer)
+
+2009-03-27 (bug fix)[2710920] [file dirname|tail /foo/] errors (epler,porter)
+
+2009-04-08 (bug fix)[2570363] unsafe [eval]s in tcltest (bron,porter)
+=> tcltest 2.3.1
+
+2009-04-08 (platform support) more Darwin kernel patterns (steffen)
+=> platform 1.0.4
+
+2009-04-09 (bug fix)[26245326] [http::geturl] connection failures (golovan)
+=> http 2.7.3
+
+2009-04-10 (new feature) Darwin: embeddable CoreFoundation notifier (steffen)
+
+2009-04-10 (bug fix)[1961211]  Darwin [load] back-compatibility (steffen)
+
+2009-04-09 (new feature) http chunked+gzip modes (thoyts)
+=> http 2.8.0
+
+2009-04-11 (enhancement) clarified cmd name resolution in oo forwards (fellows)
+
+20009-04-19 (bug fix)[2715421] http: excess bytes after POST (thoyts)
+=> http 2.8.1
+
+2009-04-30 (bug fix)[2486550] coroutine in [interp invokehidden] (sofer)
+
+2009-05-07 (bug fix)[2785893] find command in deleted namespace (sofer)
+
+2009-05-08 (bug fix)[2414858] tailcall in oo constructor (fellows)
+
+2009-05-14 (new subcommand)[TIP 354] [info object namespace] (fellows)
+
+2009-05-29 (platform support) account for ia64_32 (kupries)
+=> platform 1.0.5
+
+2009-06-02 (bug fix)[2798543] incorrect [expr] integer ** results (porter)
+
+2009-06-10 (bug fix)[2801413] overflow in [format] (porter)
+
+2009-06-13 (bug fix)[2802881] corrected compile env context (tasada,porter)
+
+2009-06-17 (redesign) reduced ambition of [exit] finalization with aim to
+avoid otherwise very tricky multi-thread finalization bugs. (staplin,ferrieux)
+	*** POTENTIAL INCOMPATIBILITY for exit handlers ***
+
+2009-06-26 (platform support) updates for Xcode 3.1 & 3.2 (steffen)
+
+2009-06-30 (platform support) clang static analyzer macros (steffen)
+
+2009-07-01 (bug fix)[2806622] Win: bad tcl_platform(user) value (thoyts)
+
+2009-07-05 (bug fix) zlib support asynch [chan copy] on chan transform (fellows)
+
+2009-07-12 (bug fix)[1895546] TclOO support for Itcl 4 method caching (fellows)
+
+2009-07-13 (bug fix)[1605269] NR-related [info frame] fixes (kupries)
+
+2009-07-14 (bug fix)[2821401] NR-enable direct eval [switch] (kenny)
+
+2009-07-16 (bug fix)[2819200] underflow settings on MIPS systems (porter)
+
+2009-07-19 (interface)[TIP 354] new routine Tcl_GetObjectName() (fellows)
+
+2009-07-20 (performance) favor [string is] success cases over empty (fellows)
+
+2009-07-22 (interface) removed TclpPanic() routine (nijtmans)
+
+2009-07-23 (bug fix)[2820349] plug event leak in notifier (mistachkin)
+
+2009-07-24 (bug fix)[2826248] crash in Tcl_GetChannelHandle (sonnenburg,kupries)
+
+2009-07-31 (bug fix)[2830354] overflow in [format] (misch,porter)
+
+2009-08-06 (bug fix)[2827000] reflected channels can signal EGAIN (kupries)
+
+2009-08-12 (new feature)[TIP 353] Tcl_NRExprObj() (porter)
+
+2009-08-20 (bug fix)[2823276] NR-enable [if], [for], [while] (fellows)
+
+2009-08-20 (bug fix)[2806250] EIAS violation in ~foo pathnames (porter)
+
+2009-08-21 (bug fix)[2837800] [glob */foo] return ./~x/foo (porter)
+
+2009-08-24 (bug fix) nested event loop notifier w/TkAqua Cocoa (alaoui,steffen)
+
+2009-08-25 (bug fix) [info frame] account for continuation lines (kupries)
+
+2009-08-27 (bug fix)[2845535] overflows in [format] (porter)
+
+2009-09-01 (bug fix) improved error message in tcltest (porter)
+=> tcltest 2.3.2
+
+2009-09-11 (bug fix)[2849860] http handle "quoted" charset value (fellows)
+=> http 2.7.4
+
+2009-09-11 (enhancement)[2314561] [subst] now bytecompiled, NR-enabled (porter)
+
+2009-09-24 (new feature)[TIP 356] Tcl_NRSubstObj() (porter)
+
+2009-10-04 (bug fix)[2569449] Core Foundation memory bug in Tiger (steffen)
+
+2009-10-06 (bug fix) repair intrep loss in slave interp evaluations
+introduced by first versions of the NRE conversion (nadkarni,porter)
+
+2009-10-06 (bug fix)[1941434] broken tclTomMath.h includes (porter)
+
+2009-10-07 (bug fix)[2871908] leaked hash table (mistachkin,kupries)
+
+2009-10-08 (bug fix)[2874678] bignum leak in [dict incr] (fellows)
+
+2009-10-17 (bug fix)[2629338] crash in var unset traces (raney,fellows)
+
+2009-10-19 (bug fix)[2107634] extend [read] and [gets] to Tcl string limits
+(morrison,parker,porter)
+
+2009-10-21 (bug fix)[2882561] Haiku OS signal support (morrison,fellows)
+
+2009-10-22 (bug fix)[2883857] [my varname arr(index)] (boudaillier,fellows)
+
+2009-10-23 (bug fix) 0-length writes: spurious SIG_PIPE (teterin,kupries)
+
+2009-10-24 Broken DST applied EU rules to US zones (lehenbauer,kenny)
+
+2009-10-29 (bug fix)[2800740] halved bignum memory on 64-bit systems (porter)
+        *** POTENTIAL INCOMPATIBILITY ***
+
+2009-11-05 (bug fix)[2854929] TM search path support in Safe Base (kupries)
+
+2009-11-05 (enhancement) rewrite of the Safe Base commands (kupries)
+
+2009-11-11 (bug fix)[2888099] [close] loses ENOSPC error (khomoutov,ferrieux)
+
+2009-11-11 (bug fix)[2891171] RFC 3986 compliance for ? in URL (nijtmans)
+=> http 2.8.2
+
+2009-11-12 (bug fix)[2895565] [fcopy -size] miscounts when converting encodings
+(kupries)
+
+2009-11-16 (bug fix)[2891556] encoding finalization crash (mistachkin,ferrieux)
+
+2009-11-18 (bug fix)[2849797] consistent names for std chans (nijtmans,fellows)
+        *** POTENTIAL INCOMPATIBILITY ***
+
+2009-11-19 (enhancement) [load]able Tcltest extension (nijtmans)
+
+2009-11-24 (bug fix)[2893771] [file stat] on Win locked files (thoyts)
+
+2009-11-24 (bug fix)[2903011] crash call destructor from constructor (fellows)
+
+2009-12-03 (bug fix)[2906841] Safe Base [glob ../*] fixes (fellows)
+
+2009-12-09 (bug fix)[2901998] consistent I/O buffering (ferrieux,kupries)
+
+2009-12-11 (bug fix)[2806407] NR-enabled coroutines (sofer)
+
+2009-12-16 (bug fix)[2913616] msgcat: improved safe interp support (fellows)
+=> msgcat 1.4.3
+
+2009-12-22 (bug fix)[2918962] [lsort -index -stride] crash (moore,fellows)
+
+2009-12-23 (bug fix)[2913625] [info script/nameof] in safe interps (fellows)
+
+2009-12-28 (bug fix)[2891362] enable time limit in child interps (fellows)
+
+2009-12-29 (bug fix)[2922555] [binary decode hex { }] crash (thoyts)
+
+2009-12-29 (bug fix)[2895741] enable min(), max() in safe interps (fellows)
+
+2009-12-30 (bug fix)[2824981] guard [unknown] against [set] undef (sofer)
+
+2010-01-05 (bug fix)[2918610] [file rootname] corruption (magerya,porter)
+
+2010-01-18 (bug fix)[2932421] less [format %s] shimmer (ferrieux)
+
+2010-01-18 (bug fix)[2918110] [chan postevent] crash (bron,kupries)
+
+2010-01-21 (bug fix)[2910748] NR-enable epoch fallback direct eval (sofer)
+
+2010-01-30 (enhancement) [unset] now bytecompiled (fellows)
+
+2010-02-01 (bug fix)[2942697] faster match: some pathological regexp patterns
+(lane,fellows)
+
+2010-02-01 (bug fix)[2939073] [array unset] unset trace crash (ferrieux)
+
+2010-02-02 (bug fix)[2944404] crash in oo destructor (fellows)
+
+2010-02-02 (new feature) [array] is now a [namespace ensemble] (fellows)
+
+2010-02-05 (enhancement) [error] now bytecompiled (fellows)
+
+2010-02-08 (bug fix)[2947783] Tcl_Zlib*flate fail on shared values (fellows)
+
+2010-02-09 (enhancement) [try] now bytecompiled (fellows)
+
+2010-02-11 (bug fix)[2826551] line-sensitive matching in regexp (dejong)
+
+2010-02-11 (bug fix)[2949740] [open |noSuch rb] crash (kovalenko,fellows)
+
+2010-02-15 (bug fix)[2950259] harden (delete obj ns -> delete obj) (fellows)
+
+2010-02-21 (bug fix)[2954959] get sign of abs($zero) right (nijtmans)
+
+2010-02-22 (bug fix)[2762041] zlib chan transforms read EOF too early (kupries)
+
+2010-02-27 (bug fix)[801429] Tcl_SetMainLoop() thread safety (fellows)
+        *** POTENTIAL INCOMPATIBILITY ***
+
+2010-03-02 (enhancement) -fvisibility-hidden build support (nijtmans)
+
+2010-03-04 (bug fix)[2962664] [oo::class destroy] crash (fellows)
+
+2010-03-05 (interface) TclOO typedefs for function pointers (fellows)
+        *** POTENTIAL INCOMPATIBILITY ***
+
+2010-03-09 (bug fix)[2936225] stop [chan copy] to slow channel consuming all
+memory with buffer backup (ferrieux)
+
+2010-03-17 (bug fix)[2921116] crash in chan transfrom teardown (kupries)
+
+2010-03-19 (enhancement) [throw] now bytecompiled (fellows)
+
+2010-03-20 (enhancement) permit [fcopy] of > 2**31 bytes (fellows)
+
+2010-03-24 (new feature) [info object methodtype] (fellows)
+
+2010-03-24 (bug fix)[2383005] [return -errorcode] reject non-list (porter)
+
+2010-03-25 (bug fix)[2976504] broken fstatfs() call (reeuwijk,fellows)
+
+2010-03-30 (new feature)[TIP 362] [registry -32bit|-64bit] (courtney,fellows)
+=> registry 1.3
+
+2010-03-30 (bug fix)[2978773] refchan mem preservation (kupries)
+
+2010-04-02 (new feature)[TIP 357] Tcl_LoadFile, Tcl_FindSymbol, etc. (kenny)
+
+2010-04-05 (configure change)[TIP 364] default build: --enable-threads (fellows)
+        *** POTENTIAL INCOMPATIBILITY ***
+
+2010-04-02 (new feature)[TIP 348] [info errorstack], [return -errorstack]
+(ferrieux)
+
+2010-04-20 (enhancement) update bundled zlib to 1.2.5 (nijtmans)
+
+2010-04-29 (enhancement)[2992970] optimize bytearray appends (fellows)
+
+2010-05-19 (bug fix)[3004007] dict/list shimmer w/o string rep loss (fellows)
+
+2010-06-09 (bug fixes) platform: several fixes for 64 bit systems (kupries)
+=> platform 1.0.9
+
+2010-06-16 (bug fix)[3016135] [clock format] in he_IL locale (nijtmans)
+
+2010-06-18 (bug fix)[3017997] Add .cmd to file extensions for [exec] (fellows)
+
+2010-06-28 (bug fix)[3019634] support errno.h changes in MSVC++ 2010 (nijtmans)
+        *** POTENTIAL INCOMPATIBILITY ***
+
+2010-07-02 (enhancement) -errorcode for [expr] domain errors (fellows)
+
+2010-07-28 (bug fix)[3037525] crash deleting vars @ callframe pop (sofer)
+
+2010-08-04 (bug fix)[3034840] mem corrupt when refchan loses interp (kupries)
+
+2010-08-04 (enhancement) Win [load] use LOAD_WITH_ALTERED_SEARCH_PATH (hobbs)
+
+2010-08-04 (platform support) panic on detection of win9x system (hobbs)
+        *** POTENTIAL INCOMPATIBILITY ***
+
+2010-08-10 (fix) Handle non-null-terminated bytearrys in glob matching (hobbs)
+
+2010-08-11 (fix) copy-paste bug in [yield] implementation (sofer, goth)
+
+2010-08-11 (platform) Drop pre-aix 4.2 support, ldAix (hobbs)
+
+2010-08-14 (frq)[2819611] changed signatures of hash fnctions, delete-file, and get-native-path (nijtmans)
+        *** POTENTIAL INCOMPATIBILITY ***
+
+2010-08-15 (bug fix)[3045010] tweaked error message for wrong#args of lambda's (fellows)
+
+2010-08-18 (bug fix)[3004191] fixed safe [glob] (fellows)
+
+2010-08-21 (patch)[3034251] genStubs steal features of ttkGenStubs (nijtmans)
+
+2010-08-26 (bug fix)[1230554] configure, OSF-1 problems, windows manifest issues (hobbs)
+
+2010-08-30 (bug fix) [3046594,3047235,3048771] reimplemented tailcall (sofer)
+
+2010-08-31 fixed manifest handling on windows (hobbs, kupries)
+
+2010-08-31 windows makefile and stub changes (nijtmans)
+
+2010-09-01 (bug fix)[3057639] compiled lappend trace consistency (hobbs,kupries)
+        *** POTENTIAL INCOMPATIBILITY ***
+
+2010-09-01 fixed safe glob handling of -directory (kupries)
+
+2010-09-02 fixed safe glob handling of -join (kupries)
+
+2010-09-08 (bug fix)[3059922] build with mingw on amd64 (porter, mescalinum)
+
+2010-09-15 (bug fix)[3067036] stop hang in bytearray append (fellows)
+
+2010-09-22 unified set of link libraries between mingw and vc (nijtmans)
+
+2010-09-22 (bug fix)[3072640] protect writes to ::error* variables (sofer)
+
+2010-09-23 fix leak of return options [catch $err m constant] (porter, hobbs)
+
+2010-09-24 (bugfix)[3056775] fixed race condition in windows sockets (kupries)
+
+2010-09-24 (performance) string eq/cmp (hobbs)
+
+2010-09-26 (patch)[3072080] rewritten NRE core (sofer)
+
+2010-09-28 (new feature)[TIP 162] implementation of ipv6 sockets (max)
+
+2010-10-02 (bug fix)[3079830] properly invalidate string rep of dicts (fellows)
+
+2010-10-06 (bug fix)[3081065] fix writing to freed Tcl_Obj (porter)
+
+2010-10-08 fix in ipv6 code on windows (nijtmans)
+
+2010-10-09 fixed overallocation of execution stack (sofer)
+
+2010-10-11 windows unicode changes (nijtmans)
+
+2010-10-12 (bug fix)[3084338] fixed meamleak in ipv6 code (max)
+
+2010-10-13 (bug fix)[467523,983660] alt fix allows empty literal share (porter)
+
+2010-10-15 (bugfix)[3085863] updated unicode tables (nijtmans)
+        *** POTENTIAL INCOMPATIBILITY ***
+
+2010-10-16 refactored implementation of dict iteration (fellows)
+
+2010-10-17 (patch)[2995655] report inner contexts on error stack (ferrieux)
+
+2010-10-19 (bug fix)[3081008] fixed bytearray zlib interaction (fellows)
+
+2010-10-19 improved crc, appending to bytearray (fellows)
+
+2010-10-20 improved compilation of [dict for] (fellows)
+
+2010-10-26 Added private support to disable reverse dns (max)
+
+2010-10-26 Prevent crashes when querying socket options (fellows, max)
+
+2010-10-28 (bug fix)[3093120] prevent freeaddrinfo(NULL) (porter, virden)
+
+2010-10-29 (bug fix)[2905784] stop cycle waste in short [after] (ferrieux)
+
+2010-11-01 tzdata updated to Olson's tzdata2010o (kenny)
+
+2010-11-04 (bug fix)[3099086] Clarified docs of var substitution (fellows)
+
+2010-11-04 improved install targets (cassof)
+
+2010-11-04 improved testing of sockets (max)
+
+2010-11-05 (frq)[491789] setargv/unicode cmdline for MSVC (nijtmans)
+
+2010-11-09 (bug fix)[3105999] fixed memleak in OO var resolver (fellows)
+
+2010-11-15 (TIP 378)[3081184] improved TIP 280 performance (kupries)
+
+2010-11-16 (platform) VS 2005 SP1 MSVC compiler (nijtmans)
+
+2010-11-18 (bug fix)[3111059] leak in [namespace delete] w coroutines (sofer)
+
+2010-11-28 [3120139,3105247] Tcl_PrintDouble improvements (kenny)
+
+2010-11-29 (new cmd) [tcl::unsupported::inject] (ferrieux,sofer)
+
+2010-11-30 (enhancement) Restore TclFormatInt for performance (hobbs)
+
+2010-12-09 (new feature) [file] is now a [namespace ensemble] (fellows)
+
+2010-12-19 (bug fix) [fcopy -size 1 -command] asynchronous (ferrieux)
+
+2010-12-12 (platform) OpenBSD build improvements (cassoff)
+
+2010-12-17 (platform) Revisions to support rpm 4.4.2 (cassoff)
+
+2010-12-27 (bug fix) crash in [lsort] w multiple -index options (fellows)
+
+2010-12-30 (bug fix)[3142026] GrowEvaluationStack OBOE (harder,sofer)
+
+2011-01-18 (bug fix)[3001438] [info frame -1] crash (mccormack,fellows)
+
+2011-03-01 (performance)[3168398] optimize [interp cancel] (mistachkin)
+
+2011-03-05 (bug fix)[3185009] crash in OO variables (danckaert,fellows)
+
+2011-03-05 (new cmd) [tcl::unsupported::assemble] (ugurlu,kenny)
+
+2011-03-06 (bug fix)[3200987,3192636] parser buffer overruns (porter)
+
+2011-03-08 (bug fix)[3202905] failed intrep release of interp result (mccormack)
+
+2011-03-09 (bug fix)[3202171] repair [namespace inscope] optimizer (porter)
+
+2011-03-10 (new version) better tcltest reporting from child interps (fellows)
+=> tcltest 2.3.3
+
+2011-03-10 (new feature) [namespace] is now a [namespace ensemble] (fellows)
+
+2011-03-12 (interface) reduce casting by ckalloc(), ckfree() callers (fellows)
+
+2011-03-14 (bug fix) Fixes from libtommath 0.42.0 release (fellows)
+
+2011-03-21 (bug fix)[3216070] [load] extension from embed Tcl apps (nijtmans)
+	***POTENTIAL INCOMPATIBILITY***
+
+2011-03-27 (performance) NRE: LIST lset foreach benchmark (twylite)
+
+2011-04-11 (bug fix)[3282869] coroutine + eval + locals crash (ferrieux,sofer)
+
+2011-04-13 (bug fix)[2662380] crash when variable append trace unsets (sofer)
+
+2011-04-13 (bug fix)[3285375] Buffer overflow in [concat] (porter)
+
+2011-05-02 (internals change) revised TclFindElement() interface (porter)
+	*** POTENTIAL INCOMPATIBILITY ***
+
+2011-05-05 (enhancement) dict->list w/o string rep generation (porter)
+
+2011-05-10 (bug fix)[3173086] Crash parsing long lists (rogers,porter)
+
+2011-05-24 (enhancement) msgcat internal improvements (fellows)
+=> msgcat 1.4.4
+
+2011-05-25 (TIP 381) [info object|class call] [self call] [nextto] (fellows)
+
+2011-05-31 (bug fix)[3293874] let lists grow all the way to the limit (porter)
+
+2011-06-02 (bug fix)[3185407] cmd resolution epoch flaw (nadkarni,fellows)
+
+2011-06-13 (bug fix)[3315098] mem leak generating double string rep (neumann)
+
+2011-06-22 (new feature) DEB_HOST_MULTIARCH support (kupries)
+=> platform 1.0.10
+
+2011-07-15 (bug fix)[3357771] Prevent circular refs in bytecode (porter)
+
+2011-07-28 tzdata updated to Olson's tzdata2011h (porter)
+
+2011-08-01 (bug fix)[3383616] memleak exposed by XOTcl (neumann,sofer)
+
+Many more Tcl built-in command errors now set an -errorcode.
+
+--- Released 8.6b2, August 8, 2011 --- See ChangeLog for details ---
+
+2011-07-02 (bug fix)[3349507] correct double(1[string repeat 0 23]) (kenny)
+
+2011-07-19 (bug fix)[3371644] Tcl_ConvertElement() segfault (sader, ferrieux)
+
+2011-07-21 (bug fix)[3372130] hypot(.) segfault (nijtmans)
+
+2011-08-12 (bug fix)[3389764] memleaks due to reference cycles in dup'd paths
+
+2011-08-15 (bug fix)[3390272] leak of [info script] value (porter)
+
+2011-08-17 (bug fix)[3393150] bignum leaks in Tcl_Get*() routines (porter)
+
+2011-08-18 (bug fix)[3393714] [string toupper] overflow (nijtmans)
+
+2011-08-30 (bug fix)[3398794] panic in interp limit setting (gavlian,fellows)
+
+2011-09-08 (bug fix)[3401704] revised expr parser to permit function names
+like "nano()" instead of parsing as "nan o()" with missing op (duquette,porter)
+	*** POTENTIAL INCOMPATIBILITY ***
+
+2011-09-10 (bug fix)[3400658] wrong num args msg with TclOO (rsooltan,fellows)
+
+2011-09-13 (bug fix)[3390638] solaris studio cc workaround (kechel,porter)
+
+2011-09-13 (bug fix)[3405652] DTrace workaround (michelson,porter)
+
+2011-09-16 (bug fix)[3391977] -headers overrides -type (ziegenhagen,fellows)
+=> http 2.8.3
+
+2011-09-16 (TIP 388) New \Uhhhhhhhh syntax (nijtmans)
+
+2011-10-06 (enhancement) bytecode compile [dict with] (fellows)
+
+2011-10-11 (bug fix)[2935503] [file stat] returns bad mode (nadkarni,nijtmans)
+
+2011-10-20 (bug fix)[3418547] cmd lits and custom resolvers (soberning,fellows)
+
+2011-10-31 (bug fix)[3414754] EIAS violation in fs paths (porter)
+
+2011-11-22 (bug fix)[3354324] Win: [file mtime] sets wrong time (nijtmans)
+
+2011-11-30 (bug fix)[967195] Simply args passed to child processes (nijtmans)
+=> tcltest 2.3.4
+
+2011-12-07 (bug fix)[3444754] fix [string tolower \u01C5] (nijtmans)
+
+2011-12-11 (update)[3457031] Update [[:print:]] to Unicode 6.0 (nijtmans)
+
+2011-12-24 (bug fix)[3464428] fix [string is graph \u0120] (nijtmans)
+
+2012-01-08 (bug fix)[3470928] zoneinfo trouble with Windhoek data file (kenny)
+
+2012-01-13 (bug fix)[3472316] fix retrieval of socket error (fellows)
+
+2012-01-21 (bug fix)[3475667] [regexp] buffer read overflow (sebres)
+
+2012-01-22 (bug fix)[3475264] [dict exists] return 0, not error (fellows)
+
+2012-01-25 (bug fix)[3474460] [oo::copy] var resolution list (fellows)
+
+2012-01-26 (bug fix)[3475569,3479689] mem corrupt in fs path (sebres,porter)
+
+2012-01-30 (enhancement) improve bytecode compile of [catch] (fellows)
+
+2012-02-02 (bug fix)[2974459,2879351,1951574,1852572,1661378,1613456] Fix
+problems where [file *able] would return false results on Win/Samba (porter)
+
+2012-02-06 (bug fix)[3484621] bump bytecode epoch on exec traces (kuhn,sofer)
+
+2012-02-15 (bug fix)[3487626] crash compiling [dict for] (fellows)
+
+2012-02-15 (enhancement) bytecode compile [lrange],[lreplace] (fellows)
+
+2012-02-17 (bug fix)[2233954] compile problem on AIX & Android (nijtmans)
+
+2012-02-29 (bug fix)[3466099] BOM in Unicode (nijtmans)
+
+2012-03-07 (bug fix)[3498327] RFC 3986 compliance (kupries)
+
+2012-03-26 (TIP 380) New builtin class [oo::Slot] (fellows)
+	*** POTENTIAL INCOMPATIBILITY ***
+
+2012-03-27 (TIP 397) <cloned> method to extend [oo::copy] (fellows)
+	*** POTENTIAL INCOMPATIBILITY ***
+
+2012-03-27 (TIP 395) New subcommand [string is entier] (fellows)
+
+2012-04-02 (TIP 396) New command [yieldto] (fellows)
+
+2012-04-04 (bug fix)[3514761] crash combining objects and ensembles (fellows)
+
+2012-04-09 (bug fix)[2712377] [info vars] and oo variables (fellows)
+
+2012-04-09 (bug fix)[3396896] no dups in oo var lists (fellows)
+
+2012-04-11 (bug fix)[3448512] [clock scan 1958-01-01] fail on Win (nijtmans)
+
+2012-04-15 (bug fix)[3517696] fix flush of zlib chan xform (fellows)
+
+2012-04-18 tzdata updated to Olson's tzdata2012c (kenny)
+
+2012-04-28 (TIP 398) exit non-blocking chan without flush (ferrieux)
+	*** POTENTIAL INCOMPATIBILITY ***
+
+2012-05-02 (enhancement) Better use of Intel cpuid instruction (nijtmans)
+
+2012-05-03 (bug fix)[3428753] Unbreak synchronous [socket -async] (porter)
+
+2012-05-10 (bug fix)[2812981] force consistent config of Tcl+pkgs (ferrieux)
+
+2012-05-10 (bug fix)[473946] correct send of special characters (nijtmans)
+
+2012-05-17 (bug fix)[3445787] fix [file] ensemble in Safe Base (fellows)
+
+2012-05-17 (bug fix)[2964715] fix [glob] in Safe Base (fellows)
+
+2012-05-17 (bug fix)[3106532] proper [switch -indexvar] values (fellows)
+	*** POTENTIAL INCOMPATIBILITY ***
+
+2012-05-21 (TIP 106) New -binary option to [dde execute|poke] (oehlmann)
+=> dde 1.4.0
+
+2012-05-23 (bug fix)[3525907] [zlib push decompress] & [chan event]
+(fellows,ferrieux,kupries)
+
+2012-05-28 (bug fix)[3529949] Protect ~ paths in Safe Base (fellows)
+
+2012-06-21 (bug fix)[3362446] [registry keys] failure (nijtmans)
+=> registry 1.3.0
+
+2012-06-25 (bug fix)[3537605] [encoding dirs a b] error message (fellows)
+
+2012-06-25 (bug fix)[3024359] crash when multi-thread concurrent [file system]
+and Tcl_FSMountsChanged(). (porter)
+
+2012-06-29 (bug fix)[3536888] fix locale guessing (oehlmann,nijtmans)
+
+2012-07-05 (bug fix)[1189293] make "<<" redirect binary safe (porter)
+
+2012-07-08 (bug fix)[3531209] accept IPv6 URLs (max)
+=> http 2.8.4
+
+2012-07-24 (bug fix) stop mem corruption in stacked channel events (max,porter)
+
+2012-07-25 (bug fix)[3546275] [auto_execok] search match [exec] (danckaert)
+
+2012-07-27 (update)[3464401] Support Unicode 6.2 (nijtmans)
+
+2012-08-20 (bug fix)[3559678] [file normalize] EIAS failure (phao,dgp)
+
+2012-08-25 (bug fix)[3561330] Ukranian translation of "March" (teterin)
+
+2012-09-07 (TIP 404) New msgcat commands [mcflset], [mcflmset] (oehlmann)
+=> msgcat 1.5.0
+
+Many revisions to better support a Cygwin environment (nijtmans)
+
+Dropped support for OS X versions less than 10.4 (Tiger) (fellows)
+
+--- Released 8.6b3, September 18, 2012 --- See ChangeLog for details ---
+
+2012-09-20 (enhancement) full Unicode support (nijtmans)
+=> dde 1.4.0
+
+2012-09-20 (enhancement) update bundled zlib to 1.2.7 (nijtmans)
+
+2012-10-03 (bug fix) exit panic on stacked std channel (griffin,porter)
+
+2012-10-14 (bug fix) [tcl::Bgerror] crash on non-dict options (nijtmans)
+
+2012-10-16 (TIP 400) New [zlib] options to set compression dict (fellows)
+
+2012-10-16 (TIP 405) New commands [lmap] and [dict map] (fellows)
+
+2012-10-24 (enhancement) [dict unset] now bytecompiled (fellows)
+
+2012-11-05 (TIP 413) Revisions to default [string trim*] trimset (nijtmans)
+	*** POTENTIAL INCOMPATIBILITY ***
+
+2012-11-05 (enhancement) Now bytecompiled: [array exists], [array set],
+[array unset], [dict create], [dict exists], [dict merge], [format],
+[info commands], [info coroutine], [info level], [info object],
+[namespace current], [namespace code], [namespace qualifiers], [namespace tail],
+[namespace which], [regsub], [self], [string first], [string last],
+[string map], [string range], [tailcall], [yield]. (fellows)
+
+2012-11-06 (bug fix)[3581754] avoid multiple callback on keep-alive (fellows)
+=> http 2.8.5
+
+2012-11-07 tzdata updated to Olson's tzdata2012i (kenny)
+
+2012-11-13 (bug fix)[3567063] thread fp settings from master (mistachkin)
+
+2012-11-14 (bug fix)[2933003] tempfile creation in $TMPDIR (fellows)
+
+2012-11-15 (TIP 416) New [load] options -global and -lazy (nijtmans)
+
+2012-11-20 (bug fix)[3033307] base64 trail whitespace (kovalenko,goth)
+
+2012-12-03 (bug fix) [configure] query broke init from argv (porter)
+=> tcltest 2.3.5
+
+2012-12-13 (bug fix)[3595576] crash: [catch {} -> noSuchNs::var] (sofer,porter)
+
+2012-12-13 (bug fix) crash: [zlib gunzip $data -header noSuchNs::var] (porter)
+
+--- Released 8.6.0, December 20, 2012 --- See ChangeLog for details ---
+
+2012-12-22 (bug fix)[3598150] DString to Tcl_Obj memleak (afredd)
+
+2012-12-27 (bug fix)[3598580] Tcl_ListObjReplace() refcount fix (nijtmans)
+
+2013-01-04 (bug fix) memleak in [format] compiler (fellows)
+
+2013-01-08 (bug fix)[3092089,3587096] [file normalize] on junction points
+
+2013-01-09 (bug fix)[3599395] status line processing (nijtmans)
+2013-01-23 (bug fix)[2911139] repair async connection management (fellows)
+=> http 2.8.6
+
+2013-01-26 (bug fix)[3601804] Darwin segfault platformCPUID (nijtmans)
+
+2013-01-28 (enhancement) improve ensemble bytecode (fellows)
+
+2013-01-30 (enhancement) selected script code improvements (fradin)
+=> tcltest 2.3.6
+
+2013-01-30 (bug fix)[3599098] update to handle glibc banner changes (kupries)
+=> platform 1.0.11
+
+2013-01-31 (bug fix)[3598282] make install DESTDIR support (cassoff)
+
+2013-02-05 (bug fix)[3603434] [file normalize a:/] flaw in VFS (porter,griffin)
+
+2013-02-09 (bug fix)[3603695] $obj varname resolution rules (venable,fellows)
+
+2013-02-11 (bug fix)[3603553] zlib flushing errors (vampiera,fellows)
+
+2013-02-14 (bug fix)[3604576] msgcat use of Windows registry (oehlmann,nijtmans)
+=> msgcat 1.5.1
+
+2013-02-19 (bug fix)[2438181] report errors in trace handlers (yorick)
+
+2013-02-21 (bug fix)[3605447] unbreak [namespace export -clear] (porter)
+
+2013-02-23 (bug fix)[3599194] fallback IPv6 routines (afredd,max)
+
+2013-02-27 (bug fix)[3606139] stop crash in [regexp] (lane)
+
+2013-03-03 (bug fix)[3606258] major serial port update (english)
+
+2013-03-06 (bug fix)[3606683] [regexp (((((a)*)*)*)*)* {}] hangs
+(grathwohl,lane,porter)
+
+2013-03-12 (enhancement) better build support for Debian arch (shadura)
+
+2013-03-19 (bug fix)[2893771] [file stat] on locked files (thoyts,nijtmans)
+
+2013-03-21 (bug fix)[2102614] [auto_mkindex] ensemble support (griffin)
+
+2013-03-27 Tcl_Zlib*() routines tolerate NULL interps (porter
+
+2013-04-04 (bug fix) Support URLs with query but no path (max)
+=> http 2.8.7
+
+2013-04-08 (bug fix)[3610026] regexp crash on color overflow (linnakangas)
+
+2013-04-29 (enhancement) [array set] compile improvement (fellows)
+
+2013-04-30 (enhancement) broaden glibc version detection (kupries)
+=> platform 1.0.12
+
+2013-05-06 (platform support) Cygwin64 (nijtmans)
+
+2013-05-15 (enhancement) Improved [list {*}...] compile (fellows)
+
+2013-05-16 (platform support) mingw-4.0 (nijtmans)
+
+2013-05-19 (platform support) FreeBSD updates (cerutti)
+
+2013-05-20 (bug fix)[3613567] access error temp file creation (keene)
+
+2013-05-20 (bug fix)[3613569] temp file open fail can crash [load] (keene)
+
+2013-05-22 (bug fix)[3613609] [lsort -nocase] failed on non-ASCII (fellows)
+
+2013-05-28 (bug fix)[3036566] Use language packs (Vista+) locale (oehlmann)
+=> msgcat 1.5.2
+
+2013-05-29 (bug fix)[3614102] [apply {{} {list [if 1]}}] stack woes (porter)
+
+2013-06-03 Restored lost performance appending to long strings (elby,porter)
+
+2013-06-05 (bug fix)[2835313] [while 1 {foo [continue]}] crash (fellows)
+
+2013-06-17 (bug fix)[a876646] [:cntrl:] includes \x00 to \x1f (nijtmans)
+
+2013-06-27 (bug fix)[983509] missing encodings for config values (nijtmans)
+
+2013-06-27 (bug fix)[34538b] apply DST in 2099 (lang)
+
+2013-07-02 (bug fix)[32afa6] corrected dirent64 check (griffin)
+
+2013-07-06 tzdata updated to Olson's tzdata2013d (kenny)
+
+2013-07-10 (bug fix)[86fb5e] [info frame] in compiled ensembles (porter)
+
+2013-07-18 (bug fix)[1c17fb] revisd syntax errorinfo that shows error (porter)
+
+2013-07-26 (bug fix)[6585b2] regexp {(\w).*?\1} abb (lane)
+
+2013-07-29 [string is space \u202f] => 1 (nijtmans)
+
+2013-08-01 [a0bc85] Limited support for fork with threads (for Rivet) (nijtmans)
+
+2013-08-01 (bug fix)[1905562] RE recursion limit increased to support
+reported usage of large expressions (porter)
+
+2013-08-02 (bug fix)[9d6162] superclass slot empty crash (vdgoot,fellows)
+
+2013-08-03 (enhancement)[3611643] [auto_mkindex] support TclOO (fellows)
+
+2013-08-14 (bug fix)[a16752] Missing command delete callbacks (porter)
+
+2013-08-15 (bug fix)[3610404] reresolve traced forwards (porter)
+
+2013-08-15 Errors from execution traces become errors of the command (porter)
+
+2013-08-23 (bug fix)[8ff0cb9] Tcl_NR*Eval*() schedule only, as doc'd (porter)
+
+2013-08-29 (bug fix)[2486550] enable [interp invokehidden {} yield] (porter)
+
+2013-09-01 (bug fix)[b98fa55] [binary decode] fail on whitespace (reche,fellows)
+
+2013-09-07 (bug fix)[86ceb4] have tm path favor first provider (neumann,porter)
+
+2013-09-09 (bug fix)[3609693] copied object member variable confusion (fellows)
+=> TclOO 1.0.1
+
+2013-09-17 (bug fix)[2152292] [binary encode uuencode] corrected (fellows)
+
+2013-09-19 (bug fix)[3487626] segfaults in [dict] compilers (porter)
+
+2013-09-19 (bug fix)[31661d2] mem leak in [lreplace] (ade,porter)
+
+Many optmizations, improvements, and tightened stack management in bytecode.
+
+--- Released 8.6.1, September 20, 2013 --- http://core.tcl.tk/tcl/ for details
+
+2013-09-27 (enhancement) improved ::env synchronization (fellows)
+
+2013-10-20 (bug fix)[2835313] segfault from
+[apply {{} {while 1 {a {*}[return -level 0 -code continue]}}}] (fellows)
+
+2013-10-22 (bug fix)[3556215] [scan %E%G%X] support (fellows)
+
+2013-10-25 (bug fix)[3eb2ec1] upper case scheme names in url. (nijtmans)
+=> http 2.8.8
+
+2013-10-29 (bug fix)[414d103] HP-UX: restore [exec] in threaded Tcl (nijtmans)
+
+2013-11-04 (bug fix) C++ friendly stubs struct declarations (nijtmans)
+
+2013-11-05 (bug fix)[426679e] OpenBSD man page rendering (nijtmans)
+
+2013-11-12 (bug fix)[5425f2c] [fconfigure -error] breaks [socket -async]
+
+2013-11-20 (bug fix) Improved environment variable management (nijtmans)
+=> tcltest 2.3.7
+
+2013-11-21 (platforms) Support for Windows 8.1 (nijtmans)
+
+2013-12-06 (RFE) improved [foreach] bytecode (fellows)
+
+2013-12-10 (RFE) improved [lmap] bytecode (sofer)
+
+2013-12-11 (RFE) improved [catch] bytecode (sofer)
+
+2013-12-18 (bug fix)[0b874c3] SEGV [coroutine X coroutine Y info frame] (porter)
+
+2013-12-20 (RFE) reduced numeric conversion in bytecode (sofer)
+
+2014-01-07 (RFE) compilers for  [concat], [linsert], [namespace origin],
+[next], [string replace], [string tolower], [string totitle], [string toupper],
+[string trim], [string trimleft], [string trimright] (fellows)
+
+2014-01-22 (RFE) compilers for [nextto], [yieldto] (fellows)
+
+2014-02-02 (RFE) compiler for [string is] (fellows)
+
+2014-02-06 (bug fix)[a4494e2] panic in test namespace-13.2 (porter)
+
+2014-03-20 (bug fix)[2f7cbd0] FreeBSD 10.0 build failure (nijtmans)
+
+2014-03-26 (RFE)[b42b208] Cygwin: [file attr -readonly -archive -hidden -system]
+(nijtmans)
+
+2014-03-27 (bug fix) segfault iocmd-23.11 (porter)
+
+2014-04-02 (bug fix)[581937a] Win: readable event on async connect failure
+
+2014-04-04 (bug fix)[581937a,97069ea] async socket connect fail (oehlmann)
+
+2014-04-10 (bug fix)[792641f] Win: no \ in normalized path (nijtmans)
+
+2014-04-11 (bug fix)[3118489] protect NUL in filenames (nijtmans)
+
+2014-04-15 (bug fix)[88aef05] segfault iocmd-21.20 (porter)
+
+2014-04-16 (update) Win: use Winsock 2.2 (nijtmans)
+
+2014-04-16 (bug fix)[d19a30d] segfault clock-67.[23] (sebres)
+
+2014-04-21 (bug fix) segfault iocmd-21.2[12] (porter)
+
+2014-04-22 (bug fix) segfault iogt-2.4 (porter)
+
+2014-04-23 (bug fix)[3493120] memleak in thread exit
+
+2014-05-08 refactoring of core I/O functions (porter)
+
+2014-05-09 (bug fix)[3389978] Win: extended paths support (nijtmans)
+
+2014-05-09 (bug fix) segfault iocmd-32.1 (porter)
+
+2014-05-11 (bug fix)[6d2f249] nested ensemble compile failure (fellows)
+
+2014-05-17 (RFE)[47d6625] wideint support in [lsearch -integer] [lsort -integer] (nijtmans)
+	*** POTENTIAL INCOMPATIBILITY ***
+
+2014-05-20 (bug fix) Stop eof and blocked state leaking thru stacks (porter)
+        *** POTENTIAL INCOMPATIBILITY ***
+
+2014-05-20 (bug fix)[13d3af3] Win: socket -async tried only first IP address
+
+2014-05-28 (platforms) work around systems that fail when a shared library
+is deleted after it is [load]ed (kupries)
+
+2014-05-31 (bug fix) chan events on pipes must be on proper ends (porter)
+
+2014-06-04 (bug fix) socket-2.12 (porter)
+
+2014-06-05 (bug fix) io-12.6 (kupries,porter)
+
+2014-06-15 (RFE)[1b0266d] [dict replace|remove] return canonical dict (fellows)
+        *** POTENTIAL INCOMPATIBILITY ***
+
+2014-06-16 (bug fix) socket-2.13 workaround broken select() (porter)
+
+2014-06-20 (bug fix)[b47b176] iortrans.tf-11.0 (porter)
+
+2014-06-22 (RFE)[2f9df4c] -cleanup scripts before -out compare (nijtmans)
+
+2014-07-04 (update) Update Unicode data to 7.0 (nijtmans)
+        *** POTENTIAL INCOMPATIBILITY ***
+
+2014-07-08 (bug) [chan push] converts blocked writes to error (aspect,porter)
+
+2014-07-10 (bug fix)[7368d2] memleak Tcl_SetVar2(..,TCL_APPEND_VALUE) (porter)
+        *** POTENTIAL INCOMPATIBILITY ***
+
+2014-07-11 (bug) leaks in SetFsPathFromAny, [info frame] (porter)
+
+2014-07-15 (bug) compress dict leak in zlib xform channel close (porter)
+
+2014-07-17 (bug fix)[9969cf8] leak trace data in coroutine deletion (porter)
+
+2014-07-18 (RFE)[b43f2b4] fix [lappend] multi performance collapse (fellows)
+
+2014-07-19 (bug fix)[75b8433] memleak managing oo instance lists (porter)
+
+2014-07-21 (bug fix)[e6477e1] memleak in AtForkChild() (porter)
+
+2014-07-22 (bug fix)[12b0997] memleak in iocmd.tf-32.0 (porter)
+
+2014-07-28 (RFE) Optimized binary [chan copy] by moving buffers (porter)
+
+2014-07-30 (enhancement) use refcounts, not Tcl_Preserve to manage lifetime
+of Tcl_Channel  (porter)
+        *** POTENTIAL INCOMPATIBILITY ***
+
+2014-07-31 (bug fix)[a84a720] double free in oo chain deletion (porter)
+
+2014-08-01 (bug fix)[e75faba] SEGV [apply {{} {namespace upvar a b [x]}}] (porter)
+
+2014-08-01 (update) "macosx*-i386-x86_64" "macosx-universal" no longer compatible (kupries)
+=> platform 1.0.13
+
+2014-08-12 tzdata updated to Olson's tzdata2014f (kenny)
+
+2014-08-17 (bug fix)[7d52e11] [info class subclasses oo::object] should
+include ::oo::class (fellows)
+
+2014-08-25 (TIP 429) New command [string cat] (leitgeb,ferrieux)
+
+--- Released 8.6.2, August 27, 2014 --- http://core.tcl.tk/tcl/ for details
+
+2014-08-28 (bug)[b9e1a3] Correct Method Search Order (nadkarni,fellows)
+=> TclOO 1.0.3
+        *** POTENTIAL INCOMPATIBILITY ***
+
+2014-09-05 (bug)[ccc2c2] Regression [lreplace {} 1 1] (bron,fellows)
+
+2014-09-08 (bug)<oo-1.18.2> Crash regression in [oo::class destroy] (porter)
+
+2014-09-09 (bug)[84af11] Regress [regsub -all {\(.*} a(b) {}] (fellows)
+
+2014-09-10 (bug)[cee90e] [try {} on ok {} - on return {} {}] panic (porter)
+
+2014-09-20 (feature) [tcl::unsupported::getbytecode] disassember (fellows)
+
+2014-09-27 (enhancement) [string cat] bytecode optimization (leitgeb,ferrieux)
+
+2014-09-27 (bug)[82521b] segfault in mangled bytecode (ogilvie,sofer)
+
+2014-10-02 (bug)[bc5b79] Hang in some [read]s of limited size (rogers,porter)
+
+2014-10-03 (bug)[bc1a96] segfault in [array set] of traced array (tab,porter)
+
+2014-10-08 (bug)[59a2e7] MSVC14 compile support (dower,nijtmans)
+
+2014-10-10 (bug)[ed29c4] [fcopy] treats [blocked] as error (rowen,porter)
+
+2014-10-10 (bug)[bf7135] regression in Tcl_Write() interface (porter)
+
+2014-10-18 (bug)[10dc6d] fix [gets] on non-blocking channels (fassel,porter)
+
+2014-10-26 Support for Windows 10 (nijtmans)
+
+2014-10-31 (bug)[dcc034] restore [open comX: r+] (lll,nijtmans)
+
+2014-11-05 (bug)[214cc0] Restore [lappend v] return value (sayers,porter)
+
+2014-11-06 (bug)[5adc35] Stop forcing EOF to be permanent (porter)
+
+--- Released 8.6.3, November 12, 2014 --- http://core.tcl.tk/tcl/ for details
+
+2014-11-21 (bug)[743338] Win: socket error encoding (ladayaroslav,nijtmans)
+
+2014-12-01 (bug) restore tbcload/tclcompiler support (kupries)
+
+2014-12-03 (bug)[0c043a] Fix compiled [set var($) val] (porter)
+
+2014-12-04 (bug)[d2ffcc] Limit $... and bareword parsing to ASCII (ladayaroslav,porter)
+        *** POTENTIAL INCOMPATIBILITY ***
+
+2014-12-06 (bug)[c6cd4a] Win: hang in async socket connection (shults,nadkarni)
+
+2014-12-10 tzdata updated to Olson's tzdata2014j (venkat)
+
+2014-12-13 fix header files installation on OS X (houben)
+
+2014-12-17 (TIP 427) [fconfigure $h -connecting, -peername, -sockname] (oehlmann,rmax)
+
+2014-12-18 (bug)[af08c8] Crash in full finalize encoding teardown (porter)
+
+2014-12-18 (bug)[7c187a] [chan copy] crash (io-53.17) (benno,porter)
+
+2015-01-26 (bug)[df0848] Trouble with INFINITY macro (dower,nijtmans)
+
+2015-01-29 (bug) Stop crashes when extension var resolvers misbehave (porter)
+
+2015-01-29 (bug)[088727] [read] past EOF (io-73.4) (fenugrec,porter)
+
+2015-02-11 tzdata updated to Olson's tzdata2015a (venkat)
+
+2015-02-20 (bug)[32b615] Fix compiled [lreplace] (lreplace-4.[345]) (aspect)
+
+2015-03-10 (enhancement) Revise OS X notifier for better Cocoa (walzer)
+        *** POTENTIAL INCOMPATIBILITY ***
+
+--- Released 8.6.4, March 12, 2015 --- http://core.tcl.tk/tcl/ for details
+
+2015-03-19 (bug)[e66e44] Win: Ctrl-C/Ctrl-Break in console not EOF (nadkarni)
+
+2015-03-21 (bug)[d87cb1] Proper tailcall from compiled ensembles (sofer)
+
+2015-04-23 (bug)[19ea02] Win: shared read from linked dirs (bogdan,oehhar)
+
+2015-04-24 (bug)[879a07] Incomplete chars @ buffer ends (leunissen,porter)
+
+2015-04-29 (bug)[894da1] Hang flushing blocking channels (yorick)
+
+2015-05-14 (enhance)[b9d043] Default use of gzip transfer encoding (fellows)
+=> http 2.8.9
+        *** POTENTIAL INCOMPATIBILITY ***
+
+2015-05-15 (bug)[9dd1bd] destructor [self] after failed constructor (calvo,fellows)
+
+2015-05-15 (bug)[0f42ff] [tailcall] combined with [next] (aspect,fellows)
+
+2015-05-18 (bug)[c11a51] http: race condition in -accept option (fellows)
+
+2015-05-19 (enhance) More pure lists from compiled [list] (porter,fellows)
+
+2015-05-27 (enhancement) Relax memdebug constraint on extensions (kupries)
+
+2015-06-03 (bug)[268b23] crash in traced [expr] (execute-11.2)(tomkinson,porter)
+
+2015-06-11 (bug)[478c44] Memleak in zlib compresion errors (mistachkin)
+
+2015-06-16 (bug)[e770d9] Higher baud on serial channels (woods,nijtmans)
+
+2015-06-18 (update) Update Unicode data to 8.0 (nijtmans)
+        *** POTENTIAL INCOMPATIBILITY ***
+
+2015-06-18 (bug)[a4cb3f] compiled [lreplace] handling of end (bron,aspect)
+
+2015-06-23 (enhance) Use Unicode SendMessageTimeout() (nijtmans)
+=> registry 1.3.1
+
+2015-06-25 (TIP 412) msgcat dynamic locale change and package private locale (oehlmann)
+=> msgcat 1.6.0
+
+2015-07-05 (bug)[a0ece9] crash in traced [expr] (execute-11.3) (hans,porter)
+
+2015-07-10 (TIP 436) [info object isa] favors 'false' over error (fellows)
+=> TclOO 1.0.4
+
+2015-07-15 (bug)[b1534b][9bad63] writes beyond buffer bounds (hanno,porter)
+
+2015-07-18 (bug)[a3309d] Memleak in compiled [unset a($i)] (jeff,porter)
+
+2015-07-23 (bug)[57945b] lock in forking/multi-threading (neumann,mistachkin)
+
+2015-07-29 (bug)[3e7eca] Allocation overflow in expr parsing (rickyb,porter)
+
+2015-07-30 (bug)[f00009] Win: Memleak in [file] (rp,sebres)
+
+2015-07-31 (bug) Correct problems found in Coverity audit (sofer)
+
+2015-08-19 (bug)[00189c] MSVC 14: semi-static UCRT support (dower,nijtmans)
+
+2015-08-26 (bug)[0df7a1] Tolerate getcwd() failures (cato,nijtmans)
+
+2015-09-21 (bug)[1115587][a3c350][d7ea9f][0e0e15][187d7f] Many fixes and
+improvements to regexp engine from Postgres (lane,porter,fellows,seltenreich)
+
+2015-09-23 (enhance) hash lookup microoptimization (hipp)
+
+2015-09-23 (bug)[e0a7b3] Input buffer draining & file events (griffin,porter)
+
+2015-09-29 (bug)[219866] Cygwin support error (yorick,nijtmans)
+=> platform 1.0.14
+
+2015-10-06 (bug)[b42a85] Win: [file normalize ~user] wrong dir (nadkarni)
+
+2015-10-21 (bug)[1080042][8f2450] More regexp from Postgres (lane,porter)
+
+2015-10-23 (bug)[4a0c16] [clock] react to msgcat locale change (oehlmann)
+
+2015-11-10 (bug)[261a8a] Overflow segfault in I/O translation (brooks,porter)
+
+2015-11-20 (bug)[40f628] ListObjReplace callers fail to detect max (porter)
+
+2015-11-30 (enhance)[32c574] Improve list growth performance (brooks,porter)
+
+2015-12-11 (bug)[c9eb6b] tolerate unset ::env(TZ) (gahr, nijtmans)
+
+2016-01-29 (TIP 440) tcl_platform(engine) -- Tcl implementation (mistachkin)
+
+2016-02-03 (bug)[25842c] stream [zlib deflate] fails with 0 input (ade,fellows)
+
+2016-02-04 (bug)[3d96b7][593baa][cf74de] crashes in OO teardown (porter,fellows)
+
+2016-02-22 (bug)[9b4702] [info exists env(missing)] kills trace (nijtmans)
+
+--- Released 8.6.5, February 29, 2016 --- http://core.tcl.tk/tcl/ for details
+
+2016-03-01 (bug)[803042] mem leak due to reference cycle (porter)
+
+2016-03-08 (bug)[bbc304] reflected watch race condition (porter)
+
+2016-03-17 (bug)[fadc99] compile-5.3 (rodriguez,porter)
+
+2016-03-17 (enhancement)[1a25fd] compile [variable ${ns}::v] (porter)
+
+2016-03-20 (bug)[1af8de] crash in compiled [string replace] (harder,fellows)
+
+2016-03-21 (bug)[d30718] segv in notifier finalize (hirofumi,nijtmans)
+
+2016-03-23 (enhancement)[7d0db7] parallel make (yarda,nijtmans)
+
+2016-03-23 [f12535] enable test bindings customization (vogel,nijtmans)
+
+2016-04-04 (bug)[47ac84] compiled [lreplace] fixes (aspect,ferrieux,fellows)
+        *** POTENTIAL INCOMPATIBILITY ***
+
+2016-04-08 (bug)[866368] RE \w includes 'Punctuation Connector' (nijtmans)
+
+2016-04-08 (bug)[2538f3] Win crash Tcl_OpenTcpServer() (griffin)
+
+2016-04-10 [07d13d] Restore TclBlend support lost in 8.6.1 (buratti)
+
+2016-05-13 (bug)[3154ea] Mem corruption in assembler exceptions (tkob,kenny)
+
+2016-05-13 (bug) registry package support any Unicode env (nijtmans)
+=> registry 1.3.2
+
+2016-05-21 (bug)[f7d4e] [namespace delete] performance (fellows)
+
+2016-06-02 (TIP 447) execution time verbosity option (cerutti)
+=> tcltest 2.4.0
+
+2016-06-16 (bug)[16828b] crash due to [vwait] trace undo fail (dah,porter)
+
+2016-06-16 (enhancement)[4b61af] good [info frame] from more cases (beric)
+
+2016-06-21 (bug)[c383eb] crash in [glob -path a] (oehlmann,porter)
+
+2016-06-21 (update) Update Unicode data to 9.0 (nijtmans)
+        *** POTENTIAL INCOMPATIBILITY ***
+
+2016-06-22 (bug)[16896d] Tcl_DString tolerate append to self. (dah,porter)
+
+2016-06-23 (bug)[d55322] crash in [dict update] (yorick,fellows)
+
+2016-06-27 (bug)[dd260a] crash in [chan configure -dictionary] (madden,aspect)
+
+2016-07-02 (bug)[f961d7] usage message with parameters with spaces (porter)
+        *** POTENTIAL INCOMPATIBILITY ***
+
+2016-07-02 (enhancement)[09fabc] Sort order of -relateddir (lanam)
+
+2016-07-07 (bug)[5d7ca0] Win: [file executable] for .cmd and .ps1 (nadkarni)
+        *** POTENTIAL INCOMPATIBILITY ***
+
+2016-07-08 (bug)[a47641] [file normalize] & Windows junctions (nadkarni)
+
+2016-07-09 [ae61a6] [file] handling of Win hardcoded names (CON) (nadkarni)
+        *** POTENTIAL INCOMPATIBILITY ***
+
+2016-07-09 [3613671] [file owned] (more) useful on Win (nadkarni)
+
+2016-07-09 (bug)[1493a4] [namespace upvar] use of resolvers (beric,fellows)
+        *** POTENTIAL INCOMPATIBILITY ***
+
+2016-07-10 (bug)[da340d] integer division in clock math (nadkarni)
+
+2016-07-20 tzdata updated to Olson's tzdata2016f (venkat)
+
+--- Released 8.6.6, July 27, 2016 --- http://core.tcl.tk/tcl/ for details
diff --git a/compat/README b/compat/README
new file mode 100644
index 0000000..9af4285
--- /dev/null
+++ b/compat/README
@@ -0,0 +1,6 @@
+This directory contains various header and code files that are
+used make Tcl compatible with various releases of UNIX and UNIX-like
+systems.  Typically, files from this directory are used to compile
+Tcl when a system doesn't contain the corresponding files or when
+they are known to be incorrect.  When the whole world becomes POSIX-
+compliant this directory should be unnecessary.
diff --git a/compat/dirent.h b/compat/dirent.h
new file mode 100644
index 0000000..fa6222a
--- /dev/null
+++ b/compat/dirent.h
@@ -0,0 +1,21 @@
+/*
+ * dirent.h --
+ *
+ *	This file is a replacement for <dirent.h> in systems that
+ *	support the old BSD-style <sys/dir.h> with a "struct direct".
+ *
+ * Copyright (c) 1991 The Regents of the University of California.
+ * Copyright (c) 1994 Sun Microsystems, Inc.
+ *
+ * See the file "license.terms" for information on usage and redistribution
+ * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#ifndef _DIRENT
+#define _DIRENT
+
+#include <sys/dir.h>
+
+#define dirent direct
+
+#endif /* _DIRENT */
diff --git a/compat/dirent2.h b/compat/dirent2.h
new file mode 100644
index 0000000..5be08ba
--- /dev/null
+++ b/compat/dirent2.h
@@ -0,0 +1,53 @@
+/*
+ * dirent.h --
+ *
+ *	Declarations of a library of directory-reading procedures
+ *	in the POSIX style ("struct dirent").
+ *
+ * Copyright (c) 1991 The Regents of the University of California.
+ * Copyright (c) 1994 Sun Microsystems, Inc.
+ *
+ * See the file "license.terms" for information on usage and redistribution
+ * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#ifndef _DIRENT
+#define _DIRENT
+
+/*
+ * Dirent structure, which holds information about a single
+ * directory entry.
+ */
+
+#define MAXNAMLEN 255
+#define DIRBLKSIZ 512
+
+struct dirent {
+    long d_ino;			/* Inode number of entry */
+    short d_reclen;		/* Length of this record */
+    short d_namlen;		/* Length of string in d_name */
+    char d_name[MAXNAMLEN + 1];	/* Name must be no longer than this */
+};
+
+/*
+ * State that keeps track of the reading of a directory (clients
+ * should never look inside this structure;  the fields should
+ * only be accessed by the library procedures).
+ */
+
+typedef struct _dirdesc {
+    int dd_fd;
+    long dd_loc;
+    long dd_size;
+    char dd_buf[DIRBLKSIZ];
+} DIR;
+
+/*
+ * Procedures defined for reading directories:
+ */
+
+extern void		closedir (DIR *dirp);
+extern DIR *		opendir (char *name);
+extern struct dirent *	readdir (DIR *dirp);
+
+#endif /* _DIRENT */
diff --git a/compat/dlfcn.h b/compat/dlfcn.h
new file mode 100644
index 0000000..fb27ea0
--- /dev/null
+++ b/compat/dlfcn.h
@@ -0,0 +1,58 @@
+/*
+ * dlfcn.h --
+ *
+ *	This file provides a replacement for the header file "dlfcn.h"
+ *	on systems where dlfcn.h is missing.  It's primary use is for
+ *	AIX, where Tcl emulates the dl library.
+ *
+ *	This file is subject to the following copyright notice, which is
+ *	different from the notice used elsewhere in Tcl but rougly
+ *	equivalent in meaning.
+ *
+ *	Copyright (c) 1992,1993,1995,1996, Jens-Uwe Mager, Helios Software GmbH
+ *	Not derived from licensed software.
+ *
+ *	Permission is granted to freely use, copy, modify, and redistribute
+ *	this software, provided that the author is not construed to be liable
+ *	for any results of using the software, alterations are clearly marked
+ *	as such, and this notice is not modified.
+ */
+
+/*
+ * This is an unpublished work copyright (c) 1992 HELIOS Software GmbH
+ * 30159 Hannover, Germany
+ */
+
+#ifndef __dlfcn_h__
+#define __dlfcn_h__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Mode flags for the dlopen routine.
+ */
+#define RTLD_LAZY	1	/* lazy function call binding */
+#define RTLD_NOW	2	/* immediate function call binding */
+#define RTLD_GLOBAL	0x100	/* allow symbols to be global */
+
+/*
+ * To be able to intialize, a library may provide a dl_info structure
+ * that contains functions to be called to initialize and terminate.
+ */
+struct dl_info {
+	void (*init) (void);
+	void (*fini) (void);
+};
+
+void *dlopen (const char *path, int mode);
+void *dlsym (void *handle, const char *symbol);
+char *dlerror (void);
+int dlclose (void *handle);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __dlfcn_h__ */
diff --git a/compat/fake-rfc2553.c b/compat/fake-rfc2553.c
new file mode 100644
index 0000000..c8e6940
--- /dev/null
+++ b/compat/fake-rfc2553.c
@@ -0,0 +1,266 @@
+/*
+ * Copyright (C) 2000-2003 Damien Miller.  All rights reserved.
+ * Copyright (C) 1999 WIDE Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Pseudo-implementation of RFC2553 name / address resolution functions
+ *
+ * But these functions are not implemented correctly. The minimum subset
+ * is implemented for ssh use only. For example, this routine assumes
+ * that ai_family is AF_INET. Don't use it for another purpose.
+ */
+#include "tclInt.h"
+
+TCL_DECLARE_MUTEX(netdbMutex)
+
+#ifndef HAVE_GETNAMEINFO
+#ifndef HAVE_STRLCPY
+static size_t
+strlcpy(char *dst, const char *src, size_t siz)
+{
+        char *d = dst;
+        const char *s = src;
+        size_t n = siz;
+
+        /* Copy as many bytes as will fit */
+        if (n != 0 && --n != 0) {
+                do {
+                        if ((*d++ = *s++) == 0)
+                                break;
+                } while (--n != 0);
+        }
+
+        /* Not enough room in dst, add NUL and traverse rest of src */
+        if (n == 0) {
+                if (siz != 0)
+                        *d = '\0';              /* NUL-terminate dst */
+                while (*s++)
+                        ;
+        }
+
+        return(s - src - 1);    /* count does not include NUL */
+}
+#endif
+
+int fake_getnameinfo(const struct sockaddr *sa, size_t salen, char *host,
+                size_t hostlen, char *serv, size_t servlen, int flags)
+{
+	struct sockaddr_in *sin = (struct sockaddr_in *)sa;
+	struct hostent *hp;
+	char tmpserv[16];
+
+	if (sa->sa_family != AF_UNSPEC && sa->sa_family != AF_INET)
+		return (EAI_FAMILY);
+	if (serv != NULL) {
+		snprintf(tmpserv, sizeof(tmpserv), "%d", ntohs(sin->sin_port));
+		if (strlcpy(serv, tmpserv, servlen) >= servlen)
+			return (EAI_MEMORY);
+	}
+
+	if (host != NULL) {
+		if (flags & NI_NUMERICHOST) {
+			size_t len;
+			Tcl_MutexLock(&netdbMutex);
+			len = strlcpy(host, inet_ntoa(sin->sin_addr), hostlen);
+			Tcl_MutexUnlock(&netdbMutex);
+			if (len >= hostlen) {
+				return (EAI_MEMORY);
+			} else {
+				return (0);
+			}
+		} else {
+			int ret;
+			Tcl_MutexLock(&netdbMutex);
+			hp = gethostbyaddr((char *)&sin->sin_addr,
+			    sizeof(struct in_addr), AF_INET);
+			if (hp == NULL) {
+				ret = EAI_NODATA;
+			} else if (strlcpy(host, hp->h_name, hostlen)
+				   >= hostlen) {
+				ret = EAI_MEMORY;
+			} else {
+				ret = 0;
+			}
+			Tcl_MutexUnlock(&netdbMutex);
+			return ret;
+		}
+	}
+	return (0);
+}
+#endif /* !HAVE_GETNAMEINFO */
+
+#ifndef HAVE_GAI_STRERROR
+const char *
+fake_gai_strerror(int err)
+{
+	switch (err) {
+	case EAI_NODATA:
+		return ("no address associated with name");
+	case EAI_MEMORY:
+		return ("memory allocation failure.");
+	case EAI_NONAME:
+		return ("nodename nor servname provided, or not known");
+	case EAI_FAMILY:
+		return ("ai_family not supported");
+	default:
+		return ("unknown/invalid error.");
+	}
+}
+#endif /* !HAVE_GAI_STRERROR */
+
+#ifndef HAVE_FREEADDRINFO
+void
+fake_freeaddrinfo(struct addrinfo *ai)
+{
+	struct addrinfo *next;
+
+	for(; ai != NULL;) {
+		next = ai->ai_next;
+		free(ai);
+		ai = next;
+	}
+}
+#endif /* !HAVE_FREEADDRINFO */
+
+#ifndef HAVE_GETADDRINFO
+static struct
+addrinfo *malloc_ai(int port, u_long addr, const struct addrinfo *hints)
+{
+	struct addrinfo *ai;
+
+	ai = malloc(sizeof(*ai) + sizeof(struct sockaddr_in));
+	if (ai == NULL)
+		return (NULL);
+
+	memset(ai, '\0', sizeof(*ai) + sizeof(struct sockaddr_in));
+
+	ai->ai_addr = (struct sockaddr *)(ai + 1);
+	/* XXX -- ssh doesn't use sa_len */
+	ai->ai_addrlen = sizeof(struct sockaddr_in);
+	ai->ai_addr->sa_family = ai->ai_family = AF_INET;
+
+	((struct sockaddr_in *)(ai)->ai_addr)->sin_port = port;
+	((struct sockaddr_in *)(ai)->ai_addr)->sin_addr.s_addr = addr;
+
+	/* XXX: the following is not generally correct, but does what we want */
+	if (hints->ai_socktype)
+		ai->ai_socktype = hints->ai_socktype;
+	else
+		ai->ai_socktype = SOCK_STREAM;
+
+	if (hints->ai_protocol)
+		ai->ai_protocol = hints->ai_protocol;
+
+	return (ai);
+}
+
+int
+fake_getaddrinfo(const char *hostname, const char *servname,
+    const struct addrinfo *hints, struct addrinfo **res)
+{
+	struct hostent *hp;
+	struct servent *sp;
+	struct in_addr in;
+	int i;
+	long int port;
+	u_long addr;
+
+	port = 0;
+	if (hints && hints->ai_family != AF_UNSPEC &&
+	    hints->ai_family != AF_INET)
+		return (EAI_FAMILY);
+	if (servname != NULL) {
+		char *cp;
+
+		port = strtol(servname, &cp, 10);
+		if (port > 0 && port <= 65535 && *cp == '\0')
+			port = htons((unsigned short)port);
+		else if ((sp = getservbyname(servname, NULL)) != NULL)
+			port = sp->s_port;
+		else
+			port = 0;
+	}
+
+	if (hints && hints->ai_flags & AI_PASSIVE) {
+		addr = htonl(0x00000000);
+		if (hostname && inet_aton(hostname, &in) != 0)
+			addr = in.s_addr;
+		*res = malloc_ai(port, addr, hints);
+		if (*res == NULL)
+			return (EAI_MEMORY);
+		return (0);
+	}
+
+	if (!hostname) {
+		*res = malloc_ai(port, htonl(0x7f000001), hints);
+		if (*res == NULL)
+			return (EAI_MEMORY);
+		return (0);
+	}
+
+	if (inet_aton(hostname, &in)) {
+		*res = malloc_ai(port, in.s_addr, hints);
+		if (*res == NULL)
+			return (EAI_MEMORY);
+		return (0);
+	}
+
+	/* Don't try DNS if AI_NUMERICHOST is set */
+	if (hints && hints->ai_flags & AI_NUMERICHOST)
+		return (EAI_NONAME);
+
+	Tcl_MutexLock(&netdbMutex);
+	hp = gethostbyname(hostname);
+	if (hp && hp->h_name && hp->h_name[0] && hp->h_addr_list[0]) {
+		struct addrinfo *cur, *prev;
+
+		cur = prev = *res = NULL;
+		for (i = 0; hp->h_addr_list[i]; i++) {
+			struct in_addr *in = (struct in_addr *)hp->h_addr_list[i];
+
+			cur = malloc_ai(port, in->s_addr, hints);
+			if (cur == NULL) {
+				if (*res != NULL)
+					freeaddrinfo(*res);
+				Tcl_MutexUnlock(&netdbMutex);
+				return (EAI_MEMORY);
+			}
+			if (prev)
+				prev->ai_next = cur;
+			else
+				*res = cur;
+
+			prev = cur;
+		}
+		Tcl_MutexUnlock(&netdbMutex);
+		return (0);
+	}
+	Tcl_MutexUnlock(&netdbMutex);
+	return (EAI_NODATA);
+}
+#endif /* !HAVE_GETADDRINFO */
diff --git a/compat/fake-rfc2553.h b/compat/fake-rfc2553.h
new file mode 100644
index 0000000..6413170
--- /dev/null
+++ b/compat/fake-rfc2553.h
@@ -0,0 +1,170 @@
+/*
+ * Copyright (C) 2000-2003 Damien Miller.  All rights reserved.
+ * Copyright (C) 1999 WIDE Project.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Pseudo-implementation of RFC2553 name / address resolution functions
+ *
+ * But these functions are not implemented correctly. The minimum subset
+ * is implemented for ssh use only. For example, this routine assumes
+ * that ai_family is AF_INET. Don't use it for another purpose.
+ */
+
+#ifndef _FAKE_RFC2553_H
+#define _FAKE_RFC2553_H
+
+/*
+ * First, socket and INET6 related definitions
+ */
+#ifndef HAVE_STRUCT_SOCKADDR_STORAGE
+# define	_SS_MAXSIZE	128	/* Implementation specific max size */
+# define       _SS_PADSIZE     (_SS_MAXSIZE - sizeof (struct sockaddr))
+struct sockaddr_storage {
+	struct sockaddr	ss_sa;
+	char		__ss_pad2[_SS_PADSIZE];
+};
+# define ss_family ss_sa.sa_family
+#endif /* !HAVE_STRUCT_SOCKADDR_STORAGE */
+
+#ifndef IN6_IS_ADDR_LOOPBACK
+# define IN6_IS_ADDR_LOOPBACK(a) \
+	(((uint32_t *)(a))[0] == 0 && ((uint32_t *)(a))[1] == 0 && \
+	 ((uint32_t *)(a))[2] == 0 && ((uint32_t *)(a))[3] == htonl(1))
+#endif /* !IN6_IS_ADDR_LOOPBACK */
+
+#ifndef HAVE_STRUCT_IN6_ADDR
+struct in6_addr {
+	uint8_t	s6_addr[16];
+};
+#endif /* !HAVE_STRUCT_IN6_ADDR */
+
+#ifndef HAVE_STRUCT_SOCKADDR_IN6
+struct sockaddr_in6 {
+	unsigned short	sin6_family;
+	uint16_t	sin6_port;
+	uint32_t	sin6_flowinfo;
+	struct in6_addr	sin6_addr;
+	uint32_t	sin6_scope_id;
+};
+#endif /* !HAVE_STRUCT_SOCKADDR_IN6 */
+
+#ifndef AF_INET6
+/* Define it to something that should never appear */
+#define AF_INET6 AF_MAX
+#endif
+
+/*
+ * Next, RFC2553 name / address resolution API
+ */
+
+#ifndef NI_NUMERICHOST
+# define NI_NUMERICHOST    (1)
+#endif
+#ifndef NI_NAMEREQD
+# define NI_NAMEREQD       (1<<1)
+#endif
+#ifndef NI_NUMERICSERV
+# define NI_NUMERICSERV    (1<<2)
+#endif
+
+#ifndef AI_PASSIVE
+# define AI_PASSIVE		(1)
+#endif
+#ifndef AI_CANONNAME
+# define AI_CANONNAME		(1<<1)
+#endif
+#ifndef AI_NUMERICHOST
+# define AI_NUMERICHOST		(1<<2)
+#endif
+
+#ifndef NI_MAXSERV
+# define NI_MAXSERV 32
+#endif /* !NI_MAXSERV */
+#ifndef NI_MAXHOST
+# define NI_MAXHOST 1025
+#endif /* !NI_MAXHOST */
+
+#ifndef EAI_NODATA
+# define EAI_NODATA	(INT_MAX - 1)
+#endif
+#ifndef EAI_MEMORY
+# define EAI_MEMORY	(INT_MAX - 2)
+#endif
+#ifndef EAI_NONAME
+# define EAI_NONAME	(INT_MAX - 3)
+#endif
+#ifndef EAI_SYSTEM
+# define EAI_SYSTEM	(INT_MAX - 4)
+#endif
+#ifndef EAI_FAMILY
+# define EAI_FAMILY	(INT_MAX - 5)
+#endif
+#ifndef EAI_SERVICE
+# define EAI_SERVICE      -8    /* SERVICE not supported for `ai_socktype'.  */
+#endif
+
+#ifndef HAVE_STRUCT_ADDRINFO
+struct addrinfo {
+	int	ai_flags;	/* AI_PASSIVE, AI_CANONNAME */
+	int	ai_family;	/* PF_xxx */
+	int	ai_socktype;	/* SOCK_xxx */
+	int	ai_protocol;	/* 0 or IPPROTO_xxx for IPv4 and IPv6 */
+	size_t	ai_addrlen;	/* length of ai_addr */
+	char	*ai_canonname;	/* canonical name for hostname */
+	struct sockaddr *ai_addr;	/* binary address */
+	struct addrinfo *ai_next;	/* next structure in linked list */
+};
+#endif /* !HAVE_STRUCT_ADDRINFO */
+
+#ifndef HAVE_GETADDRINFO
+#ifdef getaddrinfo
+# undef getaddrinfo
+#endif
+#define getaddrinfo(a,b,c,d)    (fake_getaddrinfo(a,b,c,d))
+int getaddrinfo(const char *, const char *,
+    const struct addrinfo *, struct addrinfo **);
+#endif /* !HAVE_GETADDRINFO */
+
+#ifndef HAVE_GAI_STRERROR
+#define gai_strerror(a)         (fake_gai_strerror(a))
+const char *gai_strerror(int);
+#endif /* !HAVE_GAI_STRERROR */
+
+#ifndef HAVE_FREEADDRINFO
+#define freeaddrinfo(a)         (fake_freeaddrinfo(a))
+void freeaddrinfo(struct addrinfo *);
+#endif /* !HAVE_FREEADDRINFO */
+
+#ifndef HAVE_GETNAMEINFO
+#define getnameinfo(a,b,c,d,e,f,g) (fake_getnameinfo(a,b,c,d,e,f,g))
+int getnameinfo(const struct sockaddr *, size_t, char *, size_t,
+    char *, size_t, int);
+#endif /* !HAVE_GETNAMEINFO */
+
+
+#endif /* !_FAKE_RFC2553_H */
diff --git a/compat/fixstrtod.c b/compat/fixstrtod.c
new file mode 100644
index 0000000..63fb8ef
--- /dev/null
+++ b/compat/fixstrtod.c
@@ -0,0 +1,36 @@
+/*
+ * fixstrtod.c --
+ *
+ *	Source code for the "fixstrtod" procedure.  This procedure is
+ *	used in place of strtod under Solaris 2.4, in order to fix
+ *	a bug where the "end" pointer gets set incorrectly.
+ *
+ * Copyright (c) 1995 Sun Microsystems, Inc.
+ *
+ * See the file "license.terms" for information on usage and redistribution
+ * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#include <stdio.h>
+
+#undef strtod
+
+/*
+ * Declare strtod explicitly rather than including stdlib.h, since in
+ * somes systems (e.g. SunOS 4.1.4) stdlib.h doesn't declare strtod.
+ */
+
+extern double strtod(char *, char **);
+
+double
+fixstrtod(
+    char *string,
+    char **endPtr)
+{
+    double d;
+    d = strtod(string, endPtr);
+    if ((endPtr != NULL) && (*endPtr != string) && ((*endPtr)[-1] == 0)) {
+	*endPtr -= 1;
+    }
+    return d;
+}
diff --git a/compat/float.h b/compat/float.h
new file mode 100644
index 0000000..411edbf
--- /dev/null
+++ b/compat/float.h
@@ -0,0 +1,14 @@
+/*
+ * float.h --
+ *
+ *	This is a dummy header file to #include in Tcl when there
+ *	is no float.h in /usr/include.  Right now this file is empty:
+ *	Tcl contains #ifdefs to deal with the lack of definitions;
+ *	all it needs is for the #include statement to work.
+ *
+ * Copyright (c) 1993 The Regents of the University of California.
+ * Copyright (c) 1994 Sun Microsystems, Inc.
+ *
+ * See the file "license.terms" for information on usage and redistribution
+ * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
diff --git a/compat/gettod.c b/compat/gettod.c
new file mode 100644
index 0000000..ca20cf8
--- /dev/null
+++ b/compat/gettod.c
@@ -0,0 +1,30 @@
+/*
+ * gettod.c --
+ *
+ *	This file provides the gettimeofday function on systems
+ *	that only have the System V ftime function.
+ *
+ * Copyright (c) 1995 Sun Microsystems, Inc.
+ *
+ * See the file "license.terms" for information on usage and redistribution
+ * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#include "tclPort.h"
+#include <sys/timeb.h>
+
+#undef timezone
+
+int
+gettimeofday(
+    struct timeval *tp,
+    struct timezone *tz)
+{
+    struct timeb t;
+
+    ftime(&t);
+    tp->tv_sec = t.time;
+    tp->tv_usec = t. millitm * 1000;
+    return 0;
+}
+
diff --git a/compat/memcmp.c b/compat/memcmp.c
new file mode 100644
index 0000000..c4e25a8
--- /dev/null
+++ b/compat/memcmp.c
@@ -0,0 +1,64 @@
+/*
+ * memcmp.c --
+ *
+ *	Source code for the "memcmp" library routine.
+ *
+ * Copyright (c) 1998 Sun Microsystems, Inc.
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#include "tclPort.h"
+
+/*
+ * Here is the prototype just in case it is not included in tclPort.h.
+ */
+
+int		memcmp(const void *s1, const void *s2, size_t n);
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * memcmp --
+ *
+ *	Compares two bytes sequences.
+ *
+ * Results:
+ *	Compares its arguments, looking at the first n bytes (each interpreted
+ *	as an unsigned char), and returns an integer less than, equal to, or
+ *	greater than 0, according as s1 is less than, equal to, or greater
+ *	than s2 when taken to be unsigned 8 bit numbers.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+memcmp(
+    const void *s1,		/* First string. */
+    const void *s2,		/* Second string. */
+    size_t n)			/* Length to compare. */
+{
+    const unsigned char *ptr1 = (const unsigned char *) s1;
+    const unsigned char *ptr2 = (const unsigned char *) s2;
+
+    for ( ; n-- ; ptr1++, ptr2++) {
+	unsigned char u1 = *ptr1, u2 = *ptr2;
+
+	if (u1 != u2) {
+	    return (u1-u2);
+	}
+    }
+    return 0;
+}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/compat/mkstemp.c b/compat/mkstemp.c
new file mode 100644
index 0000000..1a44dfa
--- /dev/null
+++ b/compat/mkstemp.c
@@ -0,0 +1,78 @@
+/*
+ * mkstemp.c --
+ *
+ *	Source code for the "mkstemp" library routine.
+ *
+ * Copyright (c) 2009 Donal K. Fellows
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * mkstemp --
+ *
+ *	Create an open temporary file from a template.
+ *
+ * Results:
+ *	A file descriptor, or -1 (with errno set) in the case of an error.
+ *
+ * Side effects:
+ *	The template is updated to contain the real filename.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+mkstemp(
+    char *template)		/* Template for filename. */
+{
+    static const char alphanumerics[] =
+	"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
+    register char *a, *b;
+    int fd, count, alphanumericsLen = strlen(alphanumerics); /* == 62 */
+
+    a = template + strlen(template);
+    while (a > template && *(a-1) == 'X') {
+	a--;
+    }
+
+    if (a == template) {
+	errno = ENOENT;
+	return -1;
+    }
+
+    /*
+     * We'll only try up to 10 times; after that, we're suffering from enemy
+     * action and should let the caller know.
+     */
+
+    count = 10;
+    do {
+	/*
+	 * Replace the X's in the original template with random alphanumeric
+	 * digits.
+	 */
+
+	for (b=a ; *b ; b++) {
+	    float r = rand() / ((float) RAND_MAX);
+
+	    *b = alphanumerics[(int)(r * alphanumericsLen)];
+	}
+
+	/*
+	 * Template is now realized; try to open (with correct options).
+	 */
+
+	fd = open(template, O_RDWR|O_CREAT|O_EXCL, 0600);
+    } while (fd == -1 && errno == EEXIST && --count > 0);
+
+    return fd;
+}
diff --git a/compat/opendir.c b/compat/opendir.c
new file mode 100644
index 0000000..22e8a3a
--- /dev/null
+++ b/compat/opendir.c
@@ -0,0 +1,110 @@
+/*
+ * opendir.c --
+ *
+ *	This file provides dirent-style directory-reading procedures for V7
+ *	Unix systems that don't have such procedures. The origin of this code
+ *	is unclear, but it seems to have come originally from Larry Wall.
+ */
+
+#include "tclInt.h"
+
+#undef DIRSIZ
+#define DIRSIZ(dp) \
+    ((sizeof(struct dirent) - (MAXNAMLEN+1)) + (((dp)->d_namlen+1 + 3) &~ 3))
+
+/*
+ * open a directory.
+ */
+
+DIR *
+opendir(
+    char *name)
+{
+    register DIR *dirp;
+    register int fd;
+    char *myname;
+
+    myname = ((*name == '\0') ? "." : name);
+    if ((fd = open(myname, 0, 0)) == -1) {
+	return NULL;
+    }
+    dirp = (DIR *) ckalloc(sizeof(DIR));
+    if (dirp == NULL) {
+	/* unreachable? */
+	close(fd);
+	return NULL;
+    }
+    dirp->dd_fd = fd;
+    dirp->dd_loc = 0;
+    return dirp;
+}
+
+/*
+ * read an old style directory entry and present it as a new one
+ */
+#ifndef pyr
+#define	ODIRSIZ	14
+
+struct olddirect {
+    ino_t od_ino;
+    char od_name[ODIRSIZ];
+};
+#else	/* a Pyramid in the ATT universe */
+#define	ODIRSIZ	248
+
+struct olddirect {
+    long od_ino;
+    short od_fill1, od_fill2;
+    char od_name[ODIRSIZ];
+};
+#endif
+
+/*
+ * get next entry in a directory.
+ */
+
+struct dirent *
+readdir(
+    register DIR *dirp)
+{
+    register struct olddirect *dp;
+    static struct dirent dir;
+
+    for (;;) {
+	if (dirp->dd_loc == 0) {
+	    dirp->dd_size = read(dirp->dd_fd, dirp->dd_buf, DIRBLKSIZ);
+	    if (dirp->dd_size <= 0) {
+		return NULL;
+	    }
+	}
+	if (dirp->dd_loc >= dirp->dd_size) {
+	    dirp->dd_loc = 0;
+	    continue;
+	}
+	dp = (struct olddirect *)(dirp->dd_buf + dirp->dd_loc);
+	dirp->dd_loc += sizeof(struct olddirect);
+	if (dp->od_ino == 0) {
+	    continue;
+	}
+	dir.d_ino = dp->od_ino;
+	strncpy(dir.d_name, dp->od_name, ODIRSIZ);
+	dir.d_name[ODIRSIZ] = '\0'; /* insure null termination */
+	dir.d_namlen = strlen(dir.d_name);
+	dir.d_reclen = DIRSIZ(&dir);
+	return &dir;
+    }
+}
+
+/*
+ * close a directory.
+ */
+
+void
+closedir(
+    register DIR *dirp)
+{
+    close(dirp->dd_fd);
+    dirp->dd_fd = -1;
+    dirp->dd_loc = 0;
+    ckfree((char *) dirp);
+}
diff --git a/compat/stdlib.h b/compat/stdlib.h
new file mode 100644
index 0000000..0ad4c1d
--- /dev/null
+++ b/compat/stdlib.h
@@ -0,0 +1,36 @@
+/*
+ * stdlib.h --
+ *
+ *	Declares facilities exported by the "stdlib" portion of the C library.
+ *	This file isn't complete in the ANSI-C sense; it only declares things
+ *	that are needed by Tcl. This file is needed even on many systems with
+ *	their own stdlib.h (e.g. SunOS) because not all stdlib.h files declare
+ *	all the procedures needed here (such as strtod).
+ *
+ * Copyright (c) 1991 The Regents of the University of California.
+ * Copyright (c) 1994-1998 Sun Microsystems, Inc.
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#ifndef _STDLIB
+#define _STDLIB
+
+extern void		abort(void);
+extern double		atof(const char *string);
+extern int		atoi(const char *string);
+extern long		atol(const char *string);
+extern char *		calloc(unsigned int numElements, unsigned int size);
+extern void		exit(int status);
+extern int		free(char *blockPtr);
+extern char *		getenv(const char *name);
+extern char *		malloc(unsigned int numBytes);
+extern void		qsort(void *base, int n, int size, int (*compar)(
+			    const void *element1, const void *element2));
+extern char *		realloc(char *ptr, unsigned int numBytes);
+extern double		strtod(const char *string, char **endPtr);
+extern long		strtol(const char *string, char **endPtr, int base);
+extern unsigned long	strtoul(const char *string, char **endPtr, int base);
+
+#endif /* _STDLIB */
diff --git a/compat/string.h b/compat/string.h
new file mode 100644
index 0000000..42be10c
--- /dev/null
+++ b/compat/string.h
@@ -0,0 +1,57 @@
+/*
+ * string.h --
+ *
+ *	Declarations of ANSI C library procedures for string handling.
+ *
+ * Copyright (c) 1991-1993 The Regents of the University of California.
+ * Copyright (c) 1994-1996 Sun Microsystems, Inc.
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#ifndef _STRING
+#define _STRING
+
+/*
+ * The following #include is needed to define size_t. (This used to include
+ * sys/stdtypes.h but that doesn't exist on older versions of SunOS, e.g.
+ * 4.0.2, so I'm trying sys/types.h now.... hopefully it exists everywhere)
+ */
+
+#include <sys/types.h>
+
+#ifdef __APPLE__
+extern void *		memchr(const void *s, int c, size_t n);
+#else
+extern char *		memchr(const void *s, int c, size_t n);
+#endif
+extern int		memcmp(const void *s1, const void *s2, size_t n);
+extern char *		memcpy(void *t, const void *f, size_t n);
+#ifdef NO_MEMMOVE
+#define memmove(d,s,n)	(bcopy((s), (d), (n)))
+#else
+extern char *		memmove(void *t, const void *f, size_t n);
+#endif
+extern char *		memset(void *s, int c, size_t n);
+
+extern int		strcasecmp(const char *s1, const char *s2);
+extern char *		strcat(char *dst, const char *src);
+extern char *		strchr(const char *string, int c);
+extern int		strcmp(const char *s1, const char *s2);
+extern char *		strcpy(char *dst, const char *src);
+extern size_t		strcspn(const char *string, const char *chars);
+extern char *		strdup(const char *string);
+extern char *		strerror(int error);
+extern size_t		strlen(const char *string);
+extern int		strncasecmp(const char *s1, const char *s2, size_t n);
+extern char *		strncat(char *dst, const char *src, size_t numChars);
+extern int		strncmp(const char *s1, const char *s2, size_t nChars);
+extern char *		strncpy(char *dst, const char *src, size_t numChars);
+extern char *		strpbrk(const char *string, const char *chars);
+extern char *		strrchr(const char *string, int c);
+extern size_t		strspn(const char *string, const char *chars);
+extern char *		strstr(const char *string, const char *substring);
+extern char *		strtok(char *s, const char *delim);
+
+#endif /* _STRING */
diff --git a/compat/strncasecmp.c b/compat/strncasecmp.c
new file mode 100644
index 0000000..0a69f35
--- /dev/null
+++ b/compat/strncasecmp.c
@@ -0,0 +1,136 @@
+/*
+ * strncasecmp.c --
+ *
+ *	Source code for the "strncasecmp" library routine.
+ *
+ * Copyright (c) 1988-1993 The Regents of the University of California.
+ * Copyright (c) 1995-1996 Sun Microsystems, Inc.
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#include "tclPort.h"
+
+/*
+ * This array is designed for mapping upper and lower case letter together for
+ * a case independent comparison. The mappings are based upon ASCII character
+ * sequences.
+ */
+
+static const unsigned char charmap[] = {
+    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+    0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+    0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+    0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
+    0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
+    0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
+    0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+    0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
+    0x40, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
+    0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
+    0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
+    0x78, 0x79, 0x7a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
+    0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
+    0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
+    0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
+    0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
+    0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
+    0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
+    0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
+    0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
+    0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
+    0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
+    0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
+    0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
+    0xc0, 0xe1, 0xe2, 0xe3, 0xe4, 0xc5, 0xe6, 0xe7,
+    0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
+    0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
+    0xf8, 0xf9, 0xfa, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
+    0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
+    0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
+    0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
+    0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
+};
+
+/*
+ * Here are the prototypes just in case they are not included in tclPort.h.
+ */
+
+int		strncasecmp(const char *s1, const char *s2, size_t n);
+int		strcasecmp(const char *s1, const char *s2);
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * strcasecmp --
+ *
+ *	Compares two strings, ignoring case differences.
+ *
+ * Results:
+ *	Compares two null-terminated strings s1 and s2, returning -1, 0, or 1
+ *	if s1 is lexicographically less than, equal to, or greater than s2.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+strcasecmp(
+    const char *s1,		/* First string. */
+    const char *s2)		/* Second string. */
+{
+    unsigned char u1, u2;
+
+    for ( ; ; s1++, s2++) {
+	u1 = (unsigned char) *s1;
+	u2 = (unsigned char) *s2;
+	if ((u1 == '\0') || (charmap[u1] != charmap[u2])) {
+	    break;
+	}
+    }
+    return charmap[u1] - charmap[u2];
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * strncasecmp --
+ *
+ *	Compares two strings, ignoring case differences.
+ *
+ * Results:
+ *	Compares up to length chars of s1 and s2, returning -1, 0, or 1 if s1
+ *	is lexicographically less than, equal to, or greater than s2 over
+ *	those characters.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+strncasecmp(
+    const char *s1,		/* First string. */
+    const char *s2,		/* Second string. */
+    size_t length)		/* Maximum number of characters to compare
+				 * (stop earlier if the end of either string
+				 * is reached). */
+{
+    unsigned char u1, u2;
+
+    for (; length != 0; length--, s1++, s2++) {
+	u1 = (unsigned char) *s1;
+	u2 = (unsigned char) *s2;
+	if (charmap[u1] != charmap[u2]) {
+	    return charmap[u1] - charmap[u2];
+	}
+	if (u1 == '\0') {
+	    return 0;
+	}
+    }
+    return 0;
+}
diff --git a/compat/strstr.c b/compat/strstr.c
new file mode 100644
index 0000000..e3b9b8d
--- /dev/null
+++ b/compat/strstr.c
@@ -0,0 +1,70 @@
+/*
+ * strstr.c --
+ *
+ *	Source code for the "strstr" library routine.
+ *
+ * Copyright (c) 1988-1993 The Regents of the University of California.
+ * Copyright (c) 1994 Sun Microsystems, Inc.
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#include "tcl.h"
+#ifndef NULL
+#define NULL 0
+#endif
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * strstr --
+ *
+ *	Locate the first instance of a substring in a string.
+ *
+ * Results:
+ *	If string contains substring, the return value is the location of the
+ *	first matching instance of substring in string. If string doesn't
+ *	contain substring, the return value is 0. Matching is done on an exact
+ *	character-for-character basis with no wildcards or special characters.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+char *
+strstr(
+    register char *string,	/* String to search. */
+    char *substring)		/* Substring to try to find in string. */
+{
+    register char *a, *b;
+
+    /*
+     * First scan quickly through the two strings looking for a
+     * single-character match. When it's found, then compare the rest of the
+     * substring.
+     */
+
+    b = substring;
+    if (*b == 0) {
+	return string;
+    }
+    for ( ; *string != 0; string += 1) {
+	if (*string != *b) {
+	    continue;
+	}
+	a = string;
+	while (1) {
+	    if (*b == 0) {
+		return string;
+	    }
+	    if (*a++ != *b++) {
+		break;
+	    }
+	}
+	b = substring;
+    }
+    return NULL;
+}
diff --git a/compat/strtod.c b/compat/strtod.c
new file mode 100644
index 0000000..9643c09
--- /dev/null
+++ b/compat/strtod.c
@@ -0,0 +1,252 @@
+/*
+ * strtod.c --
+ *
+ *	Source code for the "strtod" library procedure.
+ *
+ * Copyright (c) 1988-1993 The Regents of the University of California.
+ * Copyright (c) 1994 Sun Microsystems, Inc.
+ *
+ * See the file "license.terms" for information on usage and redistribution
+ * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#include "tclInt.h"
+
+#ifndef TRUE
+#define TRUE 1
+#define FALSE 0
+#endif
+#ifndef NULL
+#define NULL 0
+#endif
+
+static const int maxExponent = 511;	/* Largest possible base 10 exponent.  Any
+				 * exponent larger than this will already
+				 * produce underflow or overflow, so there's
+				 * no need to worry about additional digits.
+				 */
+static const double powersOf10[] = {	/* Table giving binary powers of 10.  Entry */
+    10.,			/* is 10^2^i.  Used to convert decimal */
+    100.,			/* exponents into floating-point numbers. */
+    1.0e4,
+    1.0e8,
+    1.0e16,
+    1.0e32,
+    1.0e64,
+    1.0e128,
+    1.0e256
+};
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * strtod --
+ *
+ *	This procedure converts a floating-point number from an ASCII
+ *	decimal representation to internal double-precision format.
+ *
+ * Results:
+ *	The return value is the double-precision floating-point
+ *	representation of the characters in string.  If endPtr isn't
+ *	NULL, then *endPtr is filled in with the address of the
+ *	next character after the last one that was part of the
+ *	floating-point number.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+double
+strtod(
+    const char *string,		/* A decimal ASCII floating-point number,
+				 * optionally preceded by white space. Must
+				 * have form "-I.FE-X", where I is the integer
+				 * part of the mantissa, F is the fractional
+				 * part of the mantissa, and X is the
+				 * exponent. Either of the signs may be "+",
+				 * "-", or omitted. Either I or F may be
+				 * omitted, or both. The decimal point isn't
+				 * necessary unless F is present. The "E" may
+				 * actually be an "e". E and X may both be
+				 * omitted (but not just one). */
+    char **endPtr)		/* If non-NULL, store terminating character's
+				 * address here. */
+{
+    int sign, expSign = FALSE;
+    double fraction, dblExp;
+    const double *d;
+    register const char *p;
+    register int c;
+    int exp = 0;		/* Exponent read from "EX" field. */
+    int fracExp = 0;		/* Exponent that derives from the fractional
+				 * part. Under normal circumstatnces, it is
+				 * the negative of the number of digits in F.
+				 * However, if I is very long, the last digits
+				 * of I get dropped (otherwise a long I with a
+				 * large negative exponent could cause an
+				 * unnecessary overflow on I alone). In this
+				 * case, fracExp is incremented one for each
+				 * dropped digit. */
+    int mantSize;		/* Number of digits in mantissa. */
+    int decPt;			/* Number of mantissa digits BEFORE decimal
+				 * point. */
+    const char *pExp;		/* Temporarily holds location of exponent in
+				 * string. */
+
+    /*
+     * Strip off leading blanks and check for a sign.
+     */
+
+    p = string;
+    while (isspace(UCHAR(*p))) {
+	p += 1;
+    }
+    if (*p == '-') {
+	sign = TRUE;
+	p += 1;
+    } else {
+	if (*p == '+') {
+	    p += 1;
+	}
+	sign = FALSE;
+    }
+
+    /*
+     * Count the number of digits in the mantissa (including the decimal
+     * point), and also locate the decimal point.
+     */
+
+    decPt = -1;
+    for (mantSize = 0; ; mantSize += 1)
+    {
+	c = *p;
+	if (!isdigit(c)) {
+	    if ((c != '.') || (decPt >= 0)) {
+		break;
+	    }
+	    decPt = mantSize;
+	}
+	p += 1;
+    }
+
+    /*
+     * Now suck up the digits in the mantissa. Use two integers to collect 9
+     * digits each (this is faster than using floating-point). If the mantissa
+     * has more than 18 digits, ignore the extras, since they can't affect the
+     * value anyway.
+     */
+
+    pExp  = p;
+    p -= mantSize;
+    if (decPt < 0) {
+	decPt = mantSize;
+    } else {
+	mantSize -= 1;		/* One of the digits was the point. */
+    }
+    if (mantSize > 18) {
+	fracExp = decPt - 18;
+	mantSize = 18;
+    } else {
+	fracExp = decPt - mantSize;
+    }
+    if (mantSize == 0) {
+	fraction = 0.0;
+	p = string;
+	goto done;
+    } else {
+	int frac1, frac2;
+
+	frac1 = 0;
+	for ( ; mantSize > 9; mantSize -= 1) {
+	    c = *p;
+	    p += 1;
+	    if (c == '.') {
+		c = *p;
+		p += 1;
+	    }
+	    frac1 = 10*frac1 + (c - '0');
+	}
+	frac2 = 0;
+	for (; mantSize > 0; mantSize -= 1) {
+	    c = *p;
+	    p += 1;
+	    if (c == '.') {
+		c = *p;
+		p += 1;
+	    }
+	    frac2 = 10*frac2 + (c - '0');
+	}
+	fraction = (1.0e9 * frac1) + frac2;
+    }
+
+    /*
+     * Skim off the exponent.
+     */
+
+    p = pExp;
+    if ((*p == 'E') || (*p == 'e')) {
+	p += 1;
+	if (*p == '-') {
+	    expSign = TRUE;
+	    p += 1;
+	} else {
+	    if (*p == '+') {
+		p += 1;
+	    }
+	    expSign = FALSE;
+	}
+	if (!isdigit(UCHAR(*p))) {
+	    p = pExp;
+	    goto done;
+	}
+	while (isdigit(UCHAR(*p))) {
+	    exp = exp * 10 + (*p - '0');
+	    p += 1;
+	}
+    }
+    if (expSign) {
+	exp = fracExp - exp;
+    } else {
+	exp = fracExp + exp;
+    }
+
+    /*
+     * Generate a floating-point number that represents the exponent. Do this
+     * by processing the exponent one bit at a time to combine many powers of
+     * 2 of 10. Then combine the exponent with the fraction.
+     */
+
+    if (exp < 0) {
+	expSign = TRUE;
+	exp = -exp;
+    } else {
+	expSign = FALSE;
+    }
+    if (exp > maxExponent) {
+	exp = maxExponent;
+	errno = ERANGE;
+    }
+    dblExp = 1.0;
+    for (d = powersOf10; exp != 0; exp >>= 1, ++d) {
+	if (exp & 01) {
+	    dblExp *= *d;
+	}
+    }
+    if (expSign) {
+	fraction /= dblExp;
+    } else {
+	fraction *= dblExp;
+    }
+
+  done:
+    if (endPtr != NULL) {
+	*endPtr = (char *) p;
+    }
+
+    if (sign) {
+	return -fraction;
+    }
+    return fraction;
+}
diff --git a/compat/strtol.c b/compat/strtol.c
new file mode 100644
index 0000000..811006a
--- /dev/null
+++ b/compat/strtol.c
@@ -0,0 +1,77 @@
+/*
+ * strtol.c --
+ *
+ *	Source code for the "strtol" library procedure.
+ *
+ * Copyright (c) 1988 The Regents of the University of California.
+ * Copyright (c) 1994 Sun Microsystems, Inc.
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#include "tclInt.h"
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * strtol --
+ *
+ *	Convert an ASCII string into an integer.
+ *
+ * Results:
+ *	The return value is the integer equivalent of string. If endPtr is
+ *	non-NULL, then *endPtr is filled in with the character after the last
+ *	one that was part of the integer. If string doesn't contain a valid
+ *	integer value, then zero is returned and *endPtr is set to string.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+long int
+strtol(
+    const char *string,		/* String of ASCII digits, possibly preceded
+				 * by white space. For bases greater than 10,
+				 * either lower- or upper-case digits may be
+				 * used. */
+    char **endPtr,		/* Where to store address of terminating
+				 * character, or NULL. */
+    int base)			/* Base for conversion. Must be less than 37.
+				 * If 0, then the base is chosen from the
+				 * leading characters of string: "0x" means
+				 * hex, "0" means octal, anything else means
+				 * decimal. */
+{
+    register const char *p;
+    long result;
+
+    /*
+     * Skip any leading blanks.
+     */
+
+    p = string;
+    while (isspace(UCHAR(*p))) {
+	p += 1;
+    }
+
+    /*
+     * Check for a sign.
+     */
+
+    if (*p == '-') {
+	p += 1;
+	result = -(strtoul(p, endPtr, base));
+    } else {
+	if (*p == '+') {
+	    p += 1;
+	}
+	result = strtoul(p, endPtr, base);
+    }
+    if ((result == 0) && (endPtr != 0) && (*endPtr == p)) {
+	*endPtr = (char *) string;
+    }
+    return result;
+}
diff --git a/compat/strtoul.c b/compat/strtoul.c
new file mode 100644
index 0000000..15587f1
--- /dev/null
+++ b/compat/strtoul.c
@@ -0,0 +1,214 @@
+/*
+ * strtoul.c --
+ *
+ *	Source code for the "strtoul" library procedure.
+ *
+ * Copyright (c) 1988 The Regents of the University of California.
+ * Copyright (c) 1994 Sun Microsystems, Inc.
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#include "tclInt.h"
+
+/*
+ * The table below is used to convert from ASCII digits to a numerical
+ * equivalent. It maps from '0' through 'z' to integers (100 for non-digit
+ * characters).
+ */
+
+static const char cvtIn[] = {
+    0, 1, 2, 3, 4, 5, 6, 7, 8, 9,		/* '0' - '9' */
+    100, 100, 100, 100, 100, 100, 100,		/* punctuation */
+    10, 11, 12, 13, 14, 15, 16, 17, 18, 19,	/* 'A' - 'Z' */
+    20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
+    30, 31, 32, 33, 34, 35,
+    100, 100, 100, 100, 100, 100,		/* punctuation */
+    10, 11, 12, 13, 14, 15, 16, 17, 18, 19,	/* 'a' - 'z' */
+    20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
+    30, 31, 32, 33, 34, 35};
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * strtoul --
+ *
+ *	Convert an ASCII string into an integer.
+ *
+ * Results:
+ *	The return value is the integer equivalent of string. If endPtr is
+ *	non-NULL, then *endPtr is filled in with the character after the last
+ *	one that was part of the integer. If string doesn't contain a valid
+ *	integer value, then zero is returned and *endPtr is set to string.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+unsigned long int
+strtoul(
+    const char *string,		/* String of ASCII digits, possibly preceded
+				 * by white space. For bases greater than 10,
+				 * either lower- or upper-case digits may be
+				 * used. */
+    char **endPtr,		/* Where to store address of terminating
+				 * character, or NULL. */
+    int base)			/* Base for conversion.  Must be less than 37.
+				 * If 0, then the base is chosen from the
+				 * leading characters of string: "0x" means
+				 * hex, "0" means octal, anything else means
+				 * decimal. */
+{
+    register const char *p;
+    register unsigned long int result = 0;
+    register unsigned digit;
+    int anyDigits = 0;
+    int negative=0;
+    int overflow=0;
+
+    /*
+     * Skip any leading blanks.
+     */
+
+    p = string;
+    while (isspace(UCHAR(*p))) {
+	p += 1;
+    }
+    if (*p == '-') {
+        negative = 1;
+        p += 1;
+    } else {
+        if (*p == '+') {
+            p += 1;
+        }
+    }
+
+    /*
+     * If no base was provided, pick one from the leading characters of the
+     * string.
+     */
+
+    if (base == 0) {
+	if (*p == '0') {
+	    p += 1;
+	    if ((*p == 'x') || (*p == 'X')) {
+		p += 1;
+		base = 16;
+	    } else {
+		/*
+		 * Must set anyDigits here, otherwise "0" produces a "no
+		 * digits" error.
+		 */
+
+		anyDigits = 1;
+		base = 8;
+	    }
+	} else {
+	    base = 10;
+	}
+    } else if (base == 16) {
+	/*
+	 * Skip a leading "0x" from hex numbers.
+	 */
+
+	if ((p[0] == '0') && ((p[1] == 'x') || (p[1] == 'X'))) {
+	    p += 2;
+	}
+    }
+
+    /*
+     * Sorry this code is so messy, but speed seems important. Do different
+     * things for base 8, 10, 16, and other.
+     */
+
+    if (base == 8) {
+	unsigned long maxres = ULONG_MAX >> 3;
+
+	for ( ; ; p += 1) {
+	    digit = *p - '0';
+	    if (digit > 7) {
+		break;
+	    }
+	    if (result > maxres) { overflow = 1; }
+	    result = (result << 3);
+	    if (digit > (ULONG_MAX - result)) { overflow = 1; }
+	    result += digit;
+	    anyDigits = 1;
+	}
+    } else if (base == 10) {
+	unsigned long maxres = ULONG_MAX / 10;
+
+	for ( ; ; p += 1) {
+	    digit = *p - '0';
+	    if (digit > 9) {
+		break;
+	    }
+	    if (result > maxres) { overflow = 1; }
+	    result *= 10;
+	    if (digit > (ULONG_MAX - result)) { overflow = 1; }
+	    result += digit;
+	    anyDigits = 1;
+	}
+    } else if (base == 16) {
+	unsigned long maxres = ULONG_MAX >> 4;
+
+	for ( ; ; p += 1) {
+	    digit = *p - '0';
+	    if (digit > ('z' - '0')) {
+		break;
+	    }
+	    digit = cvtIn[digit];
+	    if (digit > 15) {
+		break;
+	    }
+	    if (result > maxres) { overflow = 1; }
+	    result = (result << 4);
+	    if (digit > (ULONG_MAX - result)) { overflow = 1; }
+	    result += digit;
+	    anyDigits = 1;
+	}
+    } else if (base >= 2 && base <= 36) {
+	unsigned long maxres = ULONG_MAX / base;
+
+	for ( ; ; p += 1) {
+	    digit = *p - '0';
+	    if (digit > ('z' - '0')) {
+		break;
+	    }
+	    digit = cvtIn[digit];
+	    if (digit >= ( (unsigned) base )) {
+		break;
+	    }
+	    if (result > maxres) { overflow = 1; }
+	    result *= base;
+	    if (digit > (ULONG_MAX - result)) { overflow = 1; }
+	    result += digit;
+	    anyDigits = 1;
+	}
+    }
+
+    /*
+     * See if there were any digits at all.
+     */
+
+    if (!anyDigits) {
+	p = string;
+    }
+
+    if (endPtr != 0) {
+	/* unsafe, but required by the strtoul prototype */
+	*endPtr = (char *) p;
+    }
+
+    if (overflow) {
+	errno = ERANGE;
+	return ULONG_MAX;
+    }
+    if (negative) {
+	return -result;
+    }
+    return result;
+}
diff --git a/compat/unistd.h b/compat/unistd.h
new file mode 100644
index 0000000..a8f14f2
--- /dev/null
+++ b/compat/unistd.h
@@ -0,0 +1,76 @@
+/*
+ * unistd.h --
+ *
+ *      Macros, constants and prototypes for Posix conformance.
+ *
+ * Copyright 1989 Regents of the University of California Permission to use,
+ * copy, modify, and distribute this software and its documentation for any
+ * purpose and without fee is hereby granted, provided that the above
+ * copyright notice appear in all copies. The University of California makes
+ * no representations about the suitability of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+ */
+
+#ifndef _UNISTD
+#define _UNISTD
+
+#include <sys/types.h>
+
+#ifndef NULL
+#define NULL    0
+#endif
+
+/*
+ * Strict POSIX stuff goes here. Extensions go down below, in the ifndef
+ * _POSIX_SOURCE section.
+ */
+
+extern void		_exit(int status);
+extern int		access(const char *path, int mode);
+extern int		chdir(const char *path);
+extern int		chown(const char *path, uid_t owner, gid_t group);
+extern int		close(int fd);
+extern int		dup(int oldfd);
+extern int		dup2(int oldfd, int newfd);
+extern int		execl(const char *path, ...);
+extern int		execle(const char *path, ...);
+extern int		execlp(const char *file, ...);
+extern int		execv(const char *path, char **argv);
+extern int		execve(const char *path, char **argv, char **envp);
+extern int		execvpw(const char *file, char **argv);
+extern pid_t		fork(void);
+extern char *		getcwd(char *buf, size_t size);
+extern gid_t		getegid(void);
+extern uid_t		geteuid(void);
+extern gid_t		getgid(void);
+extern int		getgroups(int bufSize, int *buffer);
+extern pid_t		getpid(void);
+extern uid_t		getuid(void);
+extern int		isatty(int fd);
+extern long		lseek(int fd, long offset, int whence);
+extern int		pipe(int *fildes);
+extern int		read(int fd, char *buf, size_t size);
+extern int		setgid(gid_t group);
+extern int		setuid(uid_t user);
+extern unsigned		sleep(unsigned seconds);
+extern char *		ttyname(int fd);
+extern int		unlink(const char *path);
+extern int		write(int fd, const char *buf, size_t size);
+
+#ifndef	_POSIX_SOURCE
+extern char *		crypt(const char *, const char *);
+extern int		fchown(int fd, uid_t owner, gid_t group);
+extern int		flock(int fd, int operation);
+extern int		ftruncate(int fd, unsigned long length);
+extern int		ioctl(int fd, int request, ...);
+extern int		readlink(const char *path, char *buf, int bufsize);
+extern int		setegid(gid_t group);
+extern int		seteuidw(uid_t user);
+extern int		setreuid(int ruid, int euid);
+extern int		symlink(const char *, const char *);
+extern int		ttyslot(void);
+extern int		truncate(const char *path, unsigned long length);
+extern int		vfork(void);
+#endif /* _POSIX_SOURCE */
+
+#endif /* _UNISTD */
diff --git a/compat/waitpid.c b/compat/waitpid.c
new file mode 100644
index 0000000..e03275a
--- /dev/null
+++ b/compat/waitpid.c
@@ -0,0 +1,168 @@
+/*
+ * waitpid.c --
+ *
+ *	This procedure emulates the POSIX waitpid kernel call on BSD systems
+ *	that don't have waitpid but do have wait3. This code is based on a
+ *	prototype version written by Mark Diekhans and Karl Lehenbauer.
+ *
+ * Copyright (c) 1993 The Regents of the University of California.
+ * Copyright (c) 1994 Sun Microsystems, Inc.
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#include "tclPort.h"
+
+#ifndef pid_t
+#define pid_t int
+#endif
+
+/*
+ * A linked list of the following structures is used to keep track of
+ * processes for which we received notification from the kernel, but the
+ * application hasn't waited for them yet (this can happen because wait may
+ * not return the process we really want). We save the information here until
+ * the application finally does wait for the process.
+ */
+
+typedef struct WaitInfo {
+    pid_t pid;			/* Pid of process that exited. */
+    WAIT_STATUS_TYPE status;	/* Status returned when child exited or
+				 * suspended. */
+    struct WaitInfo *nextPtr;	/* Next in list of exited processes. */
+} WaitInfo;
+
+static WaitInfo *deadList = NULL;
+				/* First in list of all dead processes. */
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * waitpid --
+ *
+ *	This procedure emulates the functionality of the POSIX waitpid kernel
+ *	call, using the BSD wait3 kernel call. Note: it doesn't emulate
+ *	absolutely all of the waitpid functionality, in that it doesn't
+ *	support pid's of 0 or < -1.
+ *
+ * Results:
+ *	-1 is returned if there is an error in the wait kernel call. Otherwise
+ *	the pid of an exited or suspended process is returned and *statusPtr
+ *	is set to the status value of the process.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+#ifdef waitpid
+#   undef waitpid
+#endif
+
+pid_t
+waitpid(
+    pid_t pid,			/* The pid to wait on. Must be -1 or greater
+				 * than zero. */
+    int *statusPtr,		/* Where to store wait status for the
+				 * process. */
+    int options)		/* OR'ed combination of WNOHANG and
+				 * WUNTRACED. */
+{
+    register WaitInfo *waitPtr, *prevPtr;
+    pid_t result;
+    WAIT_STATUS_TYPE status;
+
+    if ((pid < -1) || (pid == 0)) {
+	errno = EINVAL;
+	return -1;
+    }
+
+    /*
+     * See if there's a suitable process that has already stopped or exited.
+     * If so, remove it from the list of exited processes and return its
+     * information.
+     */
+
+    for (waitPtr = deadList, prevPtr = NULL; waitPtr != NULL;
+	    prevPtr = waitPtr, waitPtr = waitPtr->nextPtr) {
+	if ((pid != waitPtr->pid) && (pid != -1)) {
+	    continue;
+	}
+	if (!(options & WUNTRACED) && (WIFSTOPPED(waitPtr->status))) {
+	    continue;
+	}
+	result = waitPtr->pid;
+	*statusPtr = *((int *) &waitPtr->status);
+	if (prevPtr == NULL) {
+	    deadList = waitPtr->nextPtr;
+	} else {
+	    prevPtr->nextPtr = waitPtr->nextPtr;
+	}
+	ckfree((char *) waitPtr);
+	return result;
+    }
+
+    /*
+     * Wait for any process to stop or exit. If it's an acceptable one then
+     * return it to the caller; otherwise store information about it in the
+     * list of exited processes and try again. On systems that have only wait
+     * but not wait3, there are several situations we can't handle, but we do
+     * the best we can (e.g. can still handle some combinations of options by
+     * invoking wait instead of wait3).
+     */
+
+    while (1) {
+#if NO_WAIT3
+	if (options & WNOHANG) {
+	    return 0;
+	}
+	if (options != 0) {
+	    errno = EINVAL;
+	    return -1;
+	}
+	result = wait(&status);
+#else
+	result = wait3(&status, options, 0);
+#endif
+	if ((result == -1) && (errno == EINTR)) {
+	    continue;
+	}
+	if (result <= 0) {
+	    return result;
+	}
+
+	if ((pid != result) && (pid != -1)) {
+	    goto saveInfo;
+	}
+	if (!(options & WUNTRACED) && (WIFSTOPPED(status))) {
+	    goto saveInfo;
+	}
+	*statusPtr = *((int *) &status);
+	return result;
+
+	/*
+	 * Can't return this info to caller. Save it in the list of stopped or
+	 * exited processes. Tricky point: first check for an existing entry
+	 * for the process and overwrite it if it exists (e.g. a previously
+	 * stopped process might now be dead).
+	 */
+
+    saveInfo:
+	for (waitPtr = deadList; waitPtr != NULL; waitPtr = waitPtr->nextPtr) {
+	    if (waitPtr->pid == result) {
+		waitPtr->status = status;
+		goto waitAgain;
+	    }
+	}
+	waitPtr = (WaitInfo *) ckalloc(sizeof(WaitInfo));
+	waitPtr->pid = result;
+	waitPtr->status = status;
+	waitPtr->nextPtr = deadList;
+	deadList = waitPtr;
+
+    waitAgain:
+	continue;
+    }
+}
diff --git a/compat/zlib/CMakeLists.txt b/compat/zlib/CMakeLists.txt
new file mode 100644
index 0000000..0c0247c
--- /dev/null
+++ b/compat/zlib/CMakeLists.txt
@@ -0,0 +1,249 @@
+cmake_minimum_required(VERSION 2.4.4)
+set(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS ON)
+
+project(zlib C)
+
+set(VERSION "1.2.8")
+
+option(ASM686 "Enable building i686 assembly implementation")
+option(AMD64 "Enable building amd64 assembly implementation")
+
+set(INSTALL_BIN_DIR "${CMAKE_INSTALL_PREFIX}/bin" CACHE PATH "Installation directory for executables")
+set(INSTALL_LIB_DIR "${CMAKE_INSTALL_PREFIX}/lib" CACHE PATH "Installation directory for libraries")
+set(INSTALL_INC_DIR "${CMAKE_INSTALL_PREFIX}/include" CACHE PATH "Installation directory for headers")
+set(INSTALL_MAN_DIR "${CMAKE_INSTALL_PREFIX}/share/man" CACHE PATH "Installation directory for manual pages")
+set(INSTALL_PKGCONFIG_DIR "${CMAKE_INSTALL_PREFIX}/share/pkgconfig" CACHE PATH "Installation directory for pkgconfig (.pc) files")
+
+include(CheckTypeSize)
+include(CheckFunctionExists)
+include(CheckIncludeFile)
+include(CheckCSourceCompiles)
+enable_testing()
+
+check_include_file(sys/types.h HAVE_SYS_TYPES_H)
+check_include_file(stdint.h    HAVE_STDINT_H)
+check_include_file(stddef.h    HAVE_STDDEF_H)
+
+#
+# Check to see if we have large file support
+#
+set(CMAKE_REQUIRED_DEFINITIONS -D_LARGEFILE64_SOURCE=1)
+# We add these other definitions here because CheckTypeSize.cmake
+# in CMake 2.4.x does not automatically do so and we want
+# compatibility with CMake 2.4.x.
+if(HAVE_SYS_TYPES_H)
+    list(APPEND CMAKE_REQUIRED_DEFINITIONS -DHAVE_SYS_TYPES_H)
+endif()
+if(HAVE_STDINT_H)
+    list(APPEND CMAKE_REQUIRED_DEFINITIONS -DHAVE_STDINT_H)
+endif()
+if(HAVE_STDDEF_H)
+    list(APPEND CMAKE_REQUIRED_DEFINITIONS -DHAVE_STDDEF_H)
+endif()
+check_type_size(off64_t OFF64_T)
+if(HAVE_OFF64_T)
+   add_definitions(-D_LARGEFILE64_SOURCE=1)
+endif()
+set(CMAKE_REQUIRED_DEFINITIONS) # clear variable
+
+#
+# Check for fseeko
+#
+check_function_exists(fseeko HAVE_FSEEKO)
+if(NOT HAVE_FSEEKO)
+    add_definitions(-DNO_FSEEKO)
+endif()
+
+#
+# Check for unistd.h
+#
+check_include_file(unistd.h Z_HAVE_UNISTD_H)
+
+if(MSVC)
+    set(CMAKE_DEBUG_POSTFIX "d")
+    add_definitions(-D_CRT_SECURE_NO_DEPRECATE)
+    add_definitions(-D_CRT_NONSTDC_NO_DEPRECATE)
+    include_directories(${CMAKE_CURRENT_SOURCE_DIR})
+endif()
+
+if(NOT CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_CURRENT_BINARY_DIR)
+    # If we're doing an out of source build and the user has a zconf.h
+    # in their source tree...
+    if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/zconf.h)
+        message(STATUS "Renaming")
+        message(STATUS "    ${CMAKE_CURRENT_SOURCE_DIR}/zconf.h")
+        message(STATUS "to 'zconf.h.included' because this file is included with zlib")
+        message(STATUS "but CMake generates it automatically in the build directory.")
+        file(RENAME ${CMAKE_CURRENT_SOURCE_DIR}/zconf.h ${CMAKE_CURRENT_SOURCE_DIR}/zconf.h.included)
+  endif()
+endif()
+
+set(ZLIB_PC ${CMAKE_CURRENT_BINARY_DIR}/zlib.pc)
+configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/zlib.pc.cmakein
+		${ZLIB_PC} @ONLY)
+configure_file(	${CMAKE_CURRENT_SOURCE_DIR}/zconf.h.cmakein
+		${CMAKE_CURRENT_BINARY_DIR}/zconf.h @ONLY)
+include_directories(${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_SOURCE_DIR})
+
+
+#============================================================================
+# zlib
+#============================================================================
+
+set(ZLIB_PUBLIC_HDRS
+    ${CMAKE_CURRENT_BINARY_DIR}/zconf.h
+    zlib.h
+)
+set(ZLIB_PRIVATE_HDRS
+    crc32.h
+    deflate.h
+    gzguts.h
+    inffast.h
+    inffixed.h
+    inflate.h
+    inftrees.h
+    trees.h
+    zutil.h
+)
+set(ZLIB_SRCS
+    adler32.c
+    compress.c
+    crc32.c
+    deflate.c
+    gzclose.c
+    gzlib.c
+    gzread.c
+    gzwrite.c
+    inflate.c
+    infback.c
+    inftrees.c
+    inffast.c
+    trees.c
+    uncompr.c
+    zutil.c
+)
+
+if(NOT MINGW)
+    set(ZLIB_DLL_SRCS
+        win32/zlib1.rc # If present will override custom build rule below.
+    )
+endif()
+
+if(CMAKE_COMPILER_IS_GNUCC)
+    if(ASM686)
+        set(ZLIB_ASMS contrib/asm686/match.S)
+    elseif (AMD64)
+        set(ZLIB_ASMS contrib/amd64/amd64-match.S)
+    endif ()
+
+	if(ZLIB_ASMS)
+		add_definitions(-DASMV)
+		set_source_files_properties(${ZLIB_ASMS} PROPERTIES LANGUAGE C COMPILE_FLAGS -DNO_UNDERLINE)
+	endif()
+endif()
+
+if(MSVC)
+    if(ASM686)
+		ENABLE_LANGUAGE(ASM_MASM)
+        set(ZLIB_ASMS
+			contrib/masmx86/inffas32.asm
+			contrib/masmx86/match686.asm
+		)
+    elseif (AMD64)
+		ENABLE_LANGUAGE(ASM_MASM)
+        set(ZLIB_ASMS
+			contrib/masmx64/gvmat64.asm
+			contrib/masmx64/inffasx64.asm
+		)
+    endif()
+
+	if(ZLIB_ASMS)
+		add_definitions(-DASMV -DASMINF)
+	endif()
+endif()
+
+# parse the full version number from zlib.h and include in ZLIB_FULL_VERSION
+file(READ ${CMAKE_CURRENT_SOURCE_DIR}/zlib.h _zlib_h_contents)
+string(REGEX REPLACE ".*#define[ \t]+ZLIB_VERSION[ \t]+\"([-0-9A-Za-z.]+)\".*"
+    "\\1" ZLIB_FULL_VERSION ${_zlib_h_contents})
+
+if(MINGW)
+    # This gets us DLL resource information when compiling on MinGW.
+    if(NOT CMAKE_RC_COMPILER)
+        set(CMAKE_RC_COMPILER windres.exe)
+    endif()
+
+    add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/zlib1rc.obj
+                       COMMAND ${CMAKE_RC_COMPILER}
+                            -D GCC_WINDRES
+                            -I ${CMAKE_CURRENT_SOURCE_DIR}
+                            -I ${CMAKE_CURRENT_BINARY_DIR}
+                            -o ${CMAKE_CURRENT_BINARY_DIR}/zlib1rc.obj
+                            -i ${CMAKE_CURRENT_SOURCE_DIR}/win32/zlib1.rc)
+    set(ZLIB_DLL_SRCS ${CMAKE_CURRENT_BINARY_DIR}/zlib1rc.obj)
+endif(MINGW)
+
+add_library(zlib SHARED ${ZLIB_SRCS} ${ZLIB_ASMS} ${ZLIB_DLL_SRCS} ${ZLIB_PUBLIC_HDRS} ${ZLIB_PRIVATE_HDRS})
+add_library(zlibstatic STATIC ${ZLIB_SRCS} ${ZLIB_ASMS} ${ZLIB_PUBLIC_HDRS} ${ZLIB_PRIVATE_HDRS})
+set_target_properties(zlib PROPERTIES DEFINE_SYMBOL ZLIB_DLL)
+set_target_properties(zlib PROPERTIES SOVERSION 1)
+
+if(NOT CYGWIN)
+    # This property causes shared libraries on Linux to have the full version
+    # encoded into their final filename.  We disable this on Cygwin because
+    # it causes cygz-${ZLIB_FULL_VERSION}.dll to be created when cygz.dll
+    # seems to be the default.
+    #
+    # This has no effect with MSVC, on that platform the version info for
+    # the DLL comes from the resource file win32/zlib1.rc
+    set_target_properties(zlib PROPERTIES VERSION ${ZLIB_FULL_VERSION})
+endif()
+
+if(UNIX)
+    # On unix-like platforms the library is almost always called libz
+   set_target_properties(zlib zlibstatic PROPERTIES OUTPUT_NAME z)
+   if(NOT APPLE)
+     set_target_properties(zlib PROPERTIES LINK_FLAGS "-Wl,--version-script,\"${CMAKE_CURRENT_SOURCE_DIR}/zlib.map\"")
+   endif()
+elseif(BUILD_SHARED_LIBS AND WIN32)
+    # Creates zlib1.dll when building shared library version
+    set_target_properties(zlib PROPERTIES SUFFIX "1.dll")
+endif()
+
+if(NOT SKIP_INSTALL_LIBRARIES AND NOT SKIP_INSTALL_ALL )
+    install(TARGETS zlib zlibstatic
+        RUNTIME DESTINATION "${INSTALL_BIN_DIR}"
+        ARCHIVE DESTINATION "${INSTALL_LIB_DIR}"
+        LIBRARY DESTINATION "${INSTALL_LIB_DIR}" )
+endif()
+if(NOT SKIP_INSTALL_HEADERS AND NOT SKIP_INSTALL_ALL )
+    install(FILES ${ZLIB_PUBLIC_HDRS} DESTINATION "${INSTALL_INC_DIR}")
+endif()
+if(NOT SKIP_INSTALL_FILES AND NOT SKIP_INSTALL_ALL )
+    install(FILES zlib.3 DESTINATION "${INSTALL_MAN_DIR}/man3")
+endif()
+if(NOT SKIP_INSTALL_FILES AND NOT SKIP_INSTALL_ALL )
+    install(FILES ${ZLIB_PC} DESTINATION "${INSTALL_PKGCONFIG_DIR}")
+endif()
+
+#============================================================================
+# Example binaries
+#============================================================================
+
+add_executable(example test/example.c)
+target_link_libraries(example zlib)
+add_test(example example)
+
+add_executable(minigzip test/minigzip.c)
+target_link_libraries(minigzip zlib)
+
+if(HAVE_OFF64_T)
+    add_executable(example64 test/example.c)
+    target_link_libraries(example64 zlib)
+    set_target_properties(example64 PROPERTIES COMPILE_FLAGS "-D_FILE_OFFSET_BITS=64")
+    add_test(example64 example64)
+
+    add_executable(minigzip64 test/minigzip.c)
+    target_link_libraries(minigzip64 zlib)
+    set_target_properties(minigzip64 PROPERTIES COMPILE_FLAGS "-D_FILE_OFFSET_BITS=64")
+endif()
diff --git a/compat/zlib/ChangeLog b/compat/zlib/ChangeLog
new file mode 100644
index 0000000..f22aaba
--- /dev/null
+++ b/compat/zlib/ChangeLog
@@ -0,0 +1,1472 @@
+
+                ChangeLog file for zlib
+
+Changes in 1.2.8 (28 Apr 2013)
+- Update contrib/minizip/iowin32.c for Windows RT [Vollant]
+- Do not force Z_CONST for C++
+- Clean up contrib/vstudio [Ro�]
+- Correct spelling error in zlib.h
+- Fix mixed line endings in contrib/vstudio
+
+Changes in 1.2.7.3 (13 Apr 2013)
+- Fix version numbers and DLL names in contrib/vstudio/*/zlib.rc
+
+Changes in 1.2.7.2 (13 Apr 2013)
+- Change check for a four-byte type back to hexadecimal
+- Fix typo in win32/Makefile.msc
+- Add casts in gzwrite.c for pointer differences
+
+Changes in 1.2.7.1 (24 Mar 2013)
+- Replace use of unsafe string functions with snprintf if available
+- Avoid including stddef.h on Windows for Z_SOLO compile [Niessink]
+- Fix gzgetc undefine when Z_PREFIX set [Turk]
+- Eliminate use of mktemp in Makefile (not always available)
+- Fix bug in 'F' mode for gzopen()
+- Add inflateGetDictionary() function
+- Correct comment in deflate.h
+- Use _snprintf for snprintf in Microsoft C
+- On Darwin, only use /usr/bin/libtool if libtool is not Apple
+- Delete "--version" file if created by "ar --version" [Richard G.]
+- Fix configure check for veracity of compiler error return codes
+- Fix CMake compilation of static lib for MSVC2010 x64
+- Remove unused variable in infback9.c
+- Fix argument checks in gzlog_compress() and gzlog_write()
+- Clean up the usage of z_const and respect const usage within zlib
+- Clean up examples/gzlog.[ch] comparisons of different types
+- Avoid shift equal to bits in type (caused endless loop)
+- Fix unintialized value bug in gzputc() introduced by const patches
+- Fix memory allocation error in examples/zran.c [Nor]
+- Fix bug where gzopen(), gzclose() would write an empty file
+- Fix bug in gzclose() when gzwrite() runs out of memory
+- Check for input buffer malloc failure in examples/gzappend.c
+- Add note to contrib/blast to use binary mode in stdio
+- Fix comparisons of differently signed integers in contrib/blast
+- Check for invalid code length codes in contrib/puff
+- Fix serious but very rare decompression bug in inftrees.c
+- Update inflateBack() comments, since inflate() can be faster
+- Use underscored I/O function names for WINAPI_FAMILY
+- Add _tr_flush_bits to the external symbols prefixed by --zprefix
+- Add contrib/vstudio/vc10 pre-build step for static only
+- Quote --version-script argument in CMakeLists.txt
+- Don't specify --version-script on Apple platforms in CMakeLists.txt
+- Fix casting error in contrib/testzlib/testzlib.c
+- Fix types in contrib/minizip to match result of get_crc_table()
+- Simplify contrib/vstudio/vc10 with 'd' suffix
+- Add TOP support to win32/Makefile.msc
+- Suport i686 and amd64 assembler builds in CMakeLists.txt
+- Fix typos in the use of _LARGEFILE64_SOURCE in zconf.h
+- Add vc11 and vc12 build files to contrib/vstudio
+- Add gzvprintf() as an undocumented function in zlib
+- Fix configure for Sun shell
+- Remove runtime check in configure for four-byte integer type
+- Add casts and consts to ease user conversion to C++
+- Add man pages for minizip and miniunzip
+- In Makefile uninstall, don't rm if preceding cd fails
+- Do not return Z_BUF_ERROR if deflateParam() has nothing to write
+
+Changes in 1.2.7 (2 May 2012)
+- Replace use of memmove() with a simple copy for portability
+- Test for existence of strerror
+- Restore gzgetc_ for backward compatibility with 1.2.6
+- Fix build with non-GNU make on Solaris
+- Require gcc 4.0 or later on Mac OS X to use the hidden attribute
+- Include unistd.h for Watcom C
+- Use __WATCOMC__ instead of __WATCOM__
+- Do not use the visibility attribute if NO_VIZ defined
+- Improve the detection of no hidden visibility attribute
+- Avoid using __int64 for gcc or solo compilation
+- Cast to char * in gzprintf to avoid warnings [Zinser]
+- Fix make_vms.com for VAX [Zinser]
+- Don't use library or built-in byte swaps
+- Simplify test and use of gcc hidden attribute
+- Fix bug in gzclose_w() when gzwrite() fails to allocate memory
+- Add "x" (O_EXCL) and "e" (O_CLOEXEC) modes support to gzopen()
+- Fix bug in test/minigzip.c for configure --solo
+- Fix contrib/vstudio project link errors [Mohanathas]
+- Add ability to choose the builder in make_vms.com [Schweda]
+- Add DESTDIR support to mingw32 win32/Makefile.gcc
+- Fix comments in win32/Makefile.gcc for proper usage
+- Allow overriding the default install locations for cmake
+- Generate and install the pkg-config file with cmake
+- Build both a static and a shared version of zlib with cmake
+- Include version symbols for cmake builds
+- If using cmake with MSVC, add the source directory to the includes
+- Remove unneeded EXTRA_CFLAGS from win32/Makefile.gcc [Truta]
+- Move obsolete emx makefile to old [Truta]
+- Allow the use of -Wundef when compiling or using zlib
+- Avoid the use of the -u option with mktemp
+- Improve inflate() documentation on the use of Z_FINISH
+- Recognize clang as gcc
+- Add gzopen_w() in Windows for wide character path names
+- Rename zconf.h in CMakeLists.txt to move it out of the way
+- Add source directory in CMakeLists.txt for building examples
+- Look in build directory for zlib.pc in CMakeLists.txt
+- Remove gzflags from zlibvc.def in vc9 and vc10
+- Fix contrib/minizip compilation in the MinGW environment
+- Update ./configure for Solaris, support --64 [Mooney]
+- Remove -R. from Solaris shared build (possible security issue)
+- Avoid race condition for parallel make (-j) running example
+- Fix type mismatch between get_crc_table() and crc_table
+- Fix parsing of version with "-" in CMakeLists.txt [Snider, Ziegler]
+- Fix the path to zlib.map in CMakeLists.txt
+- Force the native libtool in Mac OS X to avoid GNU libtool [Beebe]
+- Add instructions to win32/Makefile.gcc for shared install [Torri]
+
+Changes in 1.2.6.1 (12 Feb 2012)
+- Avoid the use of the Objective-C reserved name "id"
+- Include io.h in gzguts.h for Microsoft compilers
+- Fix problem with ./configure --prefix and gzgetc macro
+- Include gz_header definition when compiling zlib solo
+- Put gzflags() functionality back in zutil.c
+- Avoid library header include in crc32.c for Z_SOLO
+- Use name in GCC_CLASSIC as C compiler for coverage testing, if set
+- Minor cleanup in contrib/minizip/zip.c [Vollant]
+- Update make_vms.com [Zinser]
+- Remove unnecessary gzgetc_ function
+- Use optimized byte swap operations for Microsoft and GNU [Snyder]
+- Fix minor typo in zlib.h comments [Rzesniowiecki]
+
+Changes in 1.2.6 (29 Jan 2012)
+- Update the Pascal interface in contrib/pascal
+- Fix function numbers for gzgetc_ in zlibvc.def files
+- Fix configure.ac for contrib/minizip [Schiffer]
+- Fix large-entry detection in minizip on 64-bit systems [Schiffer]
+- Have ./configure use the compiler return code for error indication
+- Fix CMakeLists.txt for cross compilation [McClure]
+- Fix contrib/minizip/zip.c for 64-bit architectures [Dalsnes]
+- Fix compilation of contrib/minizip on FreeBSD [Marquez]
+- Correct suggested usages in win32/Makefile.msc [Shachar, Horvath]
+- Include io.h for Turbo C / Borland C on all platforms [Truta]
+- Make version explicit in contrib/minizip/configure.ac [Bosmans]
+- Avoid warning for no encryption in contrib/minizip/zip.c [Vollant]
+- Minor cleanup up contrib/minizip/unzip.c [Vollant]
+- Fix bug when compiling minizip with C++ [Vollant]
+- Protect for long name and extra fields in contrib/minizip [Vollant]
+- Avoid some warnings in contrib/minizip [Vollant]
+- Add -I../.. -L../.. to CFLAGS for minizip and miniunzip
+- Add missing libs to minizip linker command
+- Add support for VPATH builds in contrib/minizip
+- Add an --enable-demos option to contrib/minizip/configure
+- Add the generation of configure.log by ./configure
+- Exit when required parameters not provided to win32/Makefile.gcc
+- Have gzputc return the character written instead of the argument
+- Use the -m option on ldconfig for BSD systems [Tobias]
+- Correct in zlib.map when deflateResetKeep was added
+
+Changes in 1.2.5.3 (15 Jan 2012)
+- Restore gzgetc function for binary compatibility
+- Do not use _lseeki64 under Borland C++ [Truta]
+- Update win32/Makefile.msc to build test/*.c [Truta]
+- Remove old/visualc6 given CMakefile and other alternatives
+- Update AS400 build files and documentation [Monnerat]
+- Update win32/Makefile.gcc to build test/*.c [Truta]
+- Permit stronger flushes after Z_BLOCK flushes
+- Avoid extraneous empty blocks when doing empty flushes
+- Permit Z_NULL arguments to deflatePending
+- Allow deflatePrime() to insert bits in the middle of a stream
+- Remove second empty static block for Z_PARTIAL_FLUSH
+- Write out all of the available bits when using Z_BLOCK
+- Insert the first two strings in the hash table after a flush
+
+Changes in 1.2.5.2 (17 Dec 2011)
+- fix ld error: unable to find version dependency 'ZLIB_1.2.5'
+- use relative symlinks for shared libs
+- Avoid searching past window for Z_RLE strategy
+- Assure that high-water mark initialization is always applied in deflate
+- Add assertions to fill_window() in deflate.c to match comments
+- Update python link in README
+- Correct spelling error in gzread.c
+- Fix bug in gzgets() for a concatenated empty gzip stream
+- Correct error in comment for gz_make()
+- Change gzread() and related to ignore junk after gzip streams
+- Allow gzread() and related to continue after gzclearerr()
+- Allow gzrewind() and gzseek() after a premature end-of-file
+- Simplify gzseek() now that raw after gzip is ignored
+- Change gzgetc() to a macro for speed (~40% speedup in testing)
+- Fix gzclose() to return the actual error last encountered
+- Always add large file support for windows
+- Include zconf.h for windows large file support
+- Include zconf.h.cmakein for windows large file support
+- Update zconf.h.cmakein on make distclean
+- Merge vestigial vsnprintf determination from zutil.h to gzguts.h
+- Clarify how gzopen() appends in zlib.h comments
+- Correct documentation of gzdirect() since junk at end now ignored
+- Add a transparent write mode to gzopen() when 'T' is in the mode
+- Update python link in zlib man page
+- Get inffixed.h and MAKEFIXED result to match
+- Add a ./config --solo option to make zlib subset with no libary use
+- Add undocumented inflateResetKeep() function for CAB file decoding
+- Add --cover option to ./configure for gcc coverage testing
+- Add #define ZLIB_CONST option to use const in the z_stream interface
+- Add comment to gzdopen() in zlib.h to use dup() when using fileno()
+- Note behavior of uncompress() to provide as much data as it can
+- Add files in contrib/minizip to aid in building libminizip
+- Split off AR options in Makefile.in and configure
+- Change ON macro to Z_ARG to avoid application conflicts
+- Facilitate compilation with Borland C++ for pragmas and vsnprintf
+- Include io.h for Turbo C / Borland C++
+- Move example.c and minigzip.c to test/
+- Simplify incomplete code table filling in inflate_table()
+- Remove code from inflate.c and infback.c that is impossible to execute
+- Test the inflate code with full coverage
+- Allow deflateSetDictionary, inflateSetDictionary at any time (in raw)
+- Add deflateResetKeep and fix inflateResetKeep to retain dictionary
+- Fix gzwrite.c to accommodate reduced memory zlib compilation
+- Have inflate() with Z_FINISH avoid the allocation of a window
+- Do not set strm->adler when doing raw inflate
+- Fix gzeof() to behave just like feof() when read is not past end of file
+- Fix bug in gzread.c when end-of-file is reached
+- Avoid use of Z_BUF_ERROR in gz* functions except for premature EOF
+- Document gzread() capability to read concurrently written files
+- Remove hard-coding of resource compiler in CMakeLists.txt [Blammo]
+
+Changes in 1.2.5.1 (10 Sep 2011)
+- Update FAQ entry on shared builds (#13)
+- Avoid symbolic argument to chmod in Makefile.in
+- Fix bug and add consts in contrib/puff [Oberhumer]
+- Update contrib/puff/zeros.raw test file to have all block types
+- Add full coverage test for puff in contrib/puff/Makefile
+- Fix static-only-build install in Makefile.in
+- Fix bug in unzGetCurrentFileInfo() in contrib/minizip [Kuno]
+- Add libz.a dependency to shared in Makefile.in for parallel builds
+- Spell out "number" (instead of "nb") in zlib.h for total_in, total_out
+- Replace $(...) with `...` in configure for non-bash sh [Bowler]
+- Add darwin* to Darwin* and solaris* to SunOS\ 5* in configure [Groffen]
+- Add solaris* to Linux* in configure to allow gcc use [Groffen]
+- Add *bsd* to Linux* case in configure [Bar-Lev]
+- Add inffast.obj to dependencies in win32/Makefile.msc
+- Correct spelling error in deflate.h [Kohler]
+- Change libzdll.a again to libz.dll.a (!) in win32/Makefile.gcc
+- Add test to configure for GNU C looking for gcc in output of $cc -v
+- Add zlib.pc generation to win32/Makefile.gcc [Weigelt]
+- Fix bug in zlib.h for _FILE_OFFSET_BITS set and _LARGEFILE64_SOURCE not
+- Add comment in zlib.h that adler32_combine with len2 < 0 makes no sense
+- Make NO_DIVIDE option in adler32.c much faster (thanks to John Reiser)
+- Make stronger test in zconf.h to include unistd.h for LFS
+- Apply Darwin patches for 64-bit file offsets to contrib/minizip [Slack]
+- Fix zlib.h LFS support when Z_PREFIX used
+- Add updated as400 support (removed from old) [Monnerat]
+- Avoid deflate sensitivity to volatile input data
+- Avoid division in adler32_combine for NO_DIVIDE
+- Clarify the use of Z_FINISH with deflateBound() amount of space
+- Set binary for output file in puff.c
+- Use u4 type for crc_table to avoid conversion warnings
+- Apply casts in zlib.h to avoid conversion warnings
+- Add OF to prototypes for adler32_combine_ and crc32_combine_ [Miller]
+- Improve inflateSync() documentation to note indeterminancy
+- Add deflatePending() function to return the amount of pending output
+- Correct the spelling of "specification" in FAQ [Randers-Pehrson]
+- Add a check in configure for stdarg.h, use for gzprintf()
+- Check that pointers fit in ints when gzprint() compiled old style
+- Add dummy name before $(SHAREDLIBV) in Makefile [Bar-Lev, Bowler]
+- Delete line in configure that adds -L. libz.a to LDFLAGS [Weigelt]
+- Add debug records in assmebler code [Londer]
+- Update RFC references to use http://tools.ietf.org/html/... [Li]
+- Add --archs option, use of libtool to configure for Mac OS X [Borstel]
+
+Changes in 1.2.5 (19 Apr 2010)
+- Disable visibility attribute in win32/Makefile.gcc [Bar-Lev]
+- Default to libdir as sharedlibdir in configure [Nieder]
+- Update copyright dates on modified source files
+- Update trees.c to be able to generate modified trees.h
+- Exit configure for MinGW, suggesting win32/Makefile.gcc
+- Check for NULL path in gz_open [Homurlu]
+
+Changes in 1.2.4.5 (18 Apr 2010)
+- Set sharedlibdir in configure [Torok]
+- Set LDFLAGS in Makefile.in [Bar-Lev]
+- Avoid mkdir objs race condition in Makefile.in [Bowler]
+- Add ZLIB_INTERNAL in front of internal inter-module functions and arrays
+- Define ZLIB_INTERNAL to hide internal functions and arrays for GNU C
+- Don't use hidden attribute when it is a warning generator (e.g. Solaris)
+
+Changes in 1.2.4.4 (18 Apr 2010)
+- Fix CROSS_PREFIX executable testing, CHOST extract, mingw* [Torok]
+- Undefine _LARGEFILE64_SOURCE in zconf.h if it is zero, but not if empty
+- Try to use bash or ksh regardless of functionality of /bin/sh
+- Fix configure incompatibility with NetBSD sh
+- Remove attempt to run under bash or ksh since have better NetBSD fix
+- Fix win32/Makefile.gcc for MinGW [Bar-Lev]
+- Add diagnostic messages when using CROSS_PREFIX in configure
+- Added --sharedlibdir option to configure [Weigelt]
+- Use hidden visibility attribute when available [Frysinger]
+
+Changes in 1.2.4.3 (10 Apr 2010)
+- Only use CROSS_PREFIX in configure for ar and ranlib if they exist
+- Use CROSS_PREFIX for nm [Bar-Lev]
+- Assume _LARGEFILE64_SOURCE defined is equivalent to true
+- Avoid use of undefined symbols in #if with && and ||
+- Make *64 prototypes in gzguts.h consistent with functions
+- Add -shared load option for MinGW in configure [Bowler]
+- Move z_off64_t to public interface, use instead of off64_t
+- Remove ! from shell test in configure (not portable to Solaris)
+- Change +0 macro tests to -0 for possibly increased portability
+
+Changes in 1.2.4.2 (9 Apr 2010)
+- Add consistent carriage returns to readme.txt's in masmx86 and masmx64
+- Really provide prototypes for *64 functions when building without LFS
+- Only define unlink() in minigzip.c if unistd.h not included
+- Update README to point to contrib/vstudio project files
+- Move projects/vc6 to old/ and remove projects/
+- Include stdlib.h in minigzip.c for setmode() definition under WinCE
+- Clean up assembler builds in win32/Makefile.msc [Rowe]
+- Include sys/types.h for Microsoft for off_t definition
+- Fix memory leak on error in gz_open()
+- Symbolize nm as $NM in configure [Weigelt]
+- Use TEST_LDSHARED instead of LDSHARED to link test programs [Weigelt]
+- Add +0 to _FILE_OFFSET_BITS and _LFS64_LARGEFILE in case not defined
+- Fix bug in gzeof() to take into account unused input data
+- Avoid initialization of structures with variables in puff.c
+- Updated win32/README-WIN32.txt [Rowe]
+
+Changes in 1.2.4.1 (28 Mar 2010)
+- Remove the use of [a-z] constructs for sed in configure [gentoo 310225]
+- Remove $(SHAREDLIB) from LIBS in Makefile.in [Creech]
+- Restore "for debugging" comment on sprintf() in gzlib.c
+- Remove fdopen for MVS from gzguts.h
+- Put new README-WIN32.txt in win32 [Rowe]
+- Add check for shell to configure and invoke another shell if needed
+- Fix big fat stinking bug in gzseek() on uncompressed files
+- Remove vestigial F_OPEN64 define in zutil.h
+- Set and check the value of _LARGEFILE_SOURCE and _LARGEFILE64_SOURCE
+- Avoid errors on non-LFS systems when applications define LFS macros
+- Set EXE to ".exe" in configure for MINGW [Kahle]
+- Match crc32() in crc32.c exactly to the prototype in zlib.h [Sherrill]
+- Add prefix for cross-compilation in win32/makefile.gcc [Bar-Lev]
+- Add DLL install in win32/makefile.gcc [Bar-Lev]
+- Allow Linux* or linux* from uname in configure [Bar-Lev]
+- Allow ldconfig to be redefined in configure and Makefile.in [Bar-Lev]
+- Add cross-compilation prefixes to configure [Bar-Lev]
+- Match type exactly in gz_load() invocation in gzread.c
+- Match type exactly of zcalloc() in zutil.c to zlib.h alloc_func
+- Provide prototypes for *64 functions when building zlib without LFS
+- Don't use -lc when linking shared library on MinGW
+- Remove errno.h check in configure and vestigial errno code in zutil.h
+
+Changes in 1.2.4 (14 Mar 2010)
+- Fix VER3 extraction in configure for no fourth subversion
+- Update zlib.3, add docs to Makefile.in to make .pdf out of it
+- Add zlib.3.pdf to distribution
+- Don't set error code in gzerror() if passed pointer is NULL
+- Apply destination directory fixes to CMakeLists.txt [Lowman]
+- Move #cmakedefine's to a new zconf.in.cmakein
+- Restore zconf.h for builds that don't use configure or cmake
+- Add distclean to dummy Makefile for convenience
+- Update and improve INDEX, README, and FAQ
+- Update CMakeLists.txt for the return of zconf.h [Lowman]
+- Update contrib/vstudio/vc9 and vc10 [Vollant]
+- Change libz.dll.a back to libzdll.a in win32/Makefile.gcc
+- Apply license and readme changes to contrib/asm686 [Raiter]
+- Check file name lengths and add -c option in minigzip.c [Li]
+- Update contrib/amd64 and contrib/masmx86/ [Vollant]
+- Avoid use of "eof" parameter in trees.c to not shadow library variable
+- Update make_vms.com for removal of zlibdefs.h [Zinser]
+- Update assembler code and vstudio projects in contrib [Vollant]
+- Remove outdated assembler code contrib/masm686 and contrib/asm586
+- Remove old vc7 and vc8 from contrib/vstudio
+- Update win32/Makefile.msc, add ZLIB_VER_SUBREVISION [Rowe]
+- Fix memory leaks in gzclose_r() and gzclose_w(), file leak in gz_open()
+- Add contrib/gcc_gvmat64 for longest_match and inflate_fast [Vollant]
+- Remove *64 functions from win32/zlib.def (they're not 64-bit yet)
+- Fix bug in void-returning vsprintf() case in gzwrite.c
+- Fix name change from inflate.h in contrib/inflate86/inffas86.c
+- Check if temporary file exists before removing in make_vms.com [Zinser]
+- Fix make install and uninstall for --static option
+- Fix usage of _MSC_VER in gzguts.h and zutil.h [Truta]
+- Update readme.txt in contrib/masmx64 and masmx86 to assemble
+
+Changes in 1.2.3.9 (21 Feb 2010)
+- Expunge gzio.c
+- Move as400 build information to old
+- Fix updates in contrib/minizip and contrib/vstudio
+- Add const to vsnprintf test in configure to avoid warnings [Weigelt]
+- Delete zconf.h (made by configure) [Weigelt]
+- Change zconf.in.h to zconf.h.in per convention [Weigelt]
+- Check for NULL buf in gzgets()
+- Return empty string for gzgets() with len == 1 (like fgets())
+- Fix description of gzgets() in zlib.h for end-of-file, NULL return
+- Update minizip to 1.1 [Vollant]
+- Avoid MSVC loss of data warnings in gzread.c, gzwrite.c
+- Note in zlib.h that gzerror() should be used to distinguish from EOF
+- Remove use of snprintf() from gzlib.c
+- Fix bug in gzseek()
+- Update contrib/vstudio, adding vc9 and vc10 [Kuno, Vollant]
+- Fix zconf.h generation in CMakeLists.txt [Lowman]
+- Improve comments in zconf.h where modified by configure
+
+Changes in 1.2.3.8 (13 Feb 2010)
+- Clean up text files (tabs, trailing whitespace, etc.) [Oberhumer]
+- Use z_off64_t in gz_zero() and gz_skip() to match state->skip
+- Avoid comparison problem when sizeof(int) == sizeof(z_off64_t)
+- Revert to Makefile.in from 1.2.3.6 (live with the clutter)
+- Fix missing error return in gzflush(), add zlib.h note
+- Add *64 functions to zlib.map [Levin]
+- Fix signed/unsigned comparison in gz_comp()
+- Use SFLAGS when testing shared linking in configure
+- Add --64 option to ./configure to use -m64 with gcc
+- Fix ./configure --help to correctly name options
+- Have make fail if a test fails [Levin]
+- Avoid buffer overrun in contrib/masmx64/gvmat64.asm [Simpson]
+- Remove assembler object files from contrib
+
+Changes in 1.2.3.7 (24 Jan 2010)
+- Always gzopen() with O_LARGEFILE if available
+- Fix gzdirect() to work immediately after gzopen() or gzdopen()
+- Make gzdirect() more precise when the state changes while reading
+- Improve zlib.h documentation in many places
+- Catch memory allocation failure in gz_open()
+- Complete close operation if seek forward in gzclose_w() fails
+- Return Z_ERRNO from gzclose_r() if close() fails
+- Return Z_STREAM_ERROR instead of EOF for gzclose() being passed NULL
+- Return zero for gzwrite() errors to match zlib.h description
+- Return -1 on gzputs() error to match zlib.h description
+- Add zconf.in.h to allow recovery from configure modification [Weigelt]
+- Fix static library permissions in Makefile.in [Weigelt]
+- Avoid warnings in configure tests that hide functionality [Weigelt]
+- Add *BSD and DragonFly to Linux case in configure [gentoo 123571]
+- Change libzdll.a to libz.dll.a in win32/Makefile.gcc [gentoo 288212]
+- Avoid access of uninitialized data for first inflateReset2 call [Gomes]
+- Keep object files in subdirectories to reduce the clutter somewhat
+- Remove default Makefile and zlibdefs.h, add dummy Makefile
+- Add new external functions to Z_PREFIX, remove duplicates, z_z_ -> z_
+- Remove zlibdefs.h completely -- modify zconf.h instead
+
+Changes in 1.2.3.6 (17 Jan 2010)
+- Avoid void * arithmetic in gzread.c and gzwrite.c
+- Make compilers happier with const char * for gz_error message
+- Avoid unused parameter warning in inflate.c
+- Avoid signed-unsigned comparison warning in inflate.c
+- Indent #pragma's for traditional C
+- Fix usage of strwinerror() in glib.c, change to gz_strwinerror()
+- Correct email address in configure for system options
+- Update make_vms.com and add make_vms.com to contrib/minizip [Zinser]
+- Update zlib.map [Brown]
+- Fix Makefile.in for Solaris 10 make of example64 and minizip64 [Torok]
+- Apply various fixes to CMakeLists.txt [Lowman]
+- Add checks on len in gzread() and gzwrite()
+- Add error message for no more room for gzungetc()
+- Remove zlib version check in gzwrite()
+- Defer compression of gzprintf() result until need to
+- Use snprintf() in gzdopen() if available
+- Remove USE_MMAP configuration determination (only used by minigzip)
+- Remove examples/pigz.c (available separately)
+- Update examples/gun.c to 1.6
+
+Changes in 1.2.3.5 (8 Jan 2010)
+- Add space after #if in zutil.h for some compilers
+- Fix relatively harmless bug in deflate_fast() [Exarevsky]
+- Fix same problem in deflate_slow()
+- Add $(SHAREDLIBV) to LIBS in Makefile.in [Brown]
+- Add deflate_rle() for faster Z_RLE strategy run-length encoding
+- Add deflate_huff() for faster Z_HUFFMAN_ONLY encoding
+- Change name of "write" variable in inffast.c to avoid library collisions
+- Fix premature EOF from gzread() in gzio.c [Brown]
+- Use zlib header window size if windowBits is 0 in inflateInit2()
+- Remove compressBound() call in deflate.c to avoid linking compress.o
+- Replace use of errno in gz* with functions, support WinCE [Alves]
+- Provide alternative to perror() in minigzip.c for WinCE [Alves]
+- Don't use _vsnprintf on later versions of MSVC [Lowman]
+- Add CMake build script and input file [Lowman]
+- Update contrib/minizip to 1.1 [Svensson, Vollant]
+- Moved nintendods directory from contrib to .
+- Replace gzio.c with a new set of routines with the same functionality
+- Add gzbuffer(), gzoffset(), gzclose_r(), gzclose_w() as part of above
+- Update contrib/minizip to 1.1b
+- Change gzeof() to return 0 on error instead of -1 to agree with zlib.h
+
+Changes in 1.2.3.4 (21 Dec 2009)
+- Use old school .SUFFIXES in Makefile.in for FreeBSD compatibility
+- Update comments in configure and Makefile.in for default --shared
+- Fix test -z's in configure [Marquess]
+- Build examplesh and minigzipsh when not testing
+- Change NULL's to Z_NULL's in deflate.c and in comments in zlib.h
+- Import LDFLAGS from the environment in configure
+- Fix configure to populate SFLAGS with discovered CFLAGS options
+- Adapt make_vms.com to the new Makefile.in [Zinser]
+- Add zlib2ansi script for C++ compilation [Marquess]
+- Add _FILE_OFFSET_BITS=64 test to make test (when applicable)
+- Add AMD64 assembler code for longest match to contrib [Teterin]
+- Include options from $SFLAGS when doing $LDSHARED
+- Simplify 64-bit file support by introducing z_off64_t type
+- Make shared object files in objs directory to work around old Sun cc
+- Use only three-part version number for Darwin shared compiles
+- Add rc option to ar in Makefile.in for when ./configure not run
+- Add -WI,-rpath,. to LDFLAGS for OSF 1 V4*
+- Set LD_LIBRARYN32_PATH for SGI IRIX shared compile
+- Protect against _FILE_OFFSET_BITS being defined when compiling zlib
+- Rename Makefile.in targets allstatic to static and allshared to shared
+- Fix static and shared Makefile.in targets to be independent
+- Correct error return bug in gz_open() by setting state [Brown]
+- Put spaces before ;;'s in configure for better sh compatibility
+- Add pigz.c (parallel implementation of gzip) to examples/
+- Correct constant in crc32.c to UL [Leventhal]
+- Reject negative lengths in crc32_combine()
+- Add inflateReset2() function to work like inflateEnd()/inflateInit2()
+- Include sys/types.h for _LARGEFILE64_SOURCE [Brown]
+- Correct typo in doc/algorithm.txt [Janik]
+- Fix bug in adler32_combine() [Zhu]
+- Catch missing-end-of-block-code error in all inflates and in puff
+    Assures that random input to inflate eventually results in an error
+- Added enough.c (calculation of ENOUGH for inftrees.h) to examples/
+- Update ENOUGH and its usage to reflect discovered bounds
+- Fix gzerror() error report on empty input file [Brown]
+- Add ush casts in trees.c to avoid pedantic runtime errors
+- Fix typo in zlib.h uncompress() description [Reiss]
+- Correct inflate() comments with regard to automatic header detection
+- Remove deprecation comment on Z_PARTIAL_FLUSH (it stays)
+- Put new version of gzlog (2.0) in examples with interruption recovery
+- Add puff compile option to permit invalid distance-too-far streams
+- Add puff TEST command options, ability to read piped input
+- Prototype the *64 functions in zlib.h when _FILE_OFFSET_BITS == 64, but
+  _LARGEFILE64_SOURCE not defined
+- Fix Z_FULL_FLUSH to truly erase the past by resetting s->strstart
+- Fix deflateSetDictionary() to use all 32K for output consistency
+- Remove extraneous #define MIN_LOOKAHEAD in deflate.c (in deflate.h)
+- Clear bytes after deflate lookahead to avoid use of uninitialized data
+- Change a limit in inftrees.c to be more transparent to Coverity Prevent
+- Update win32/zlib.def with exported symbols from zlib.h
+- Correct spelling errors in zlib.h [Willem, Sobrado]
+- Allow Z_BLOCK for deflate() to force a new block
+- Allow negative bits in inflatePrime() to delete existing bit buffer
+- Add Z_TREES flush option to inflate() to return at end of trees
+- Add inflateMark() to return current state information for random access
+- Add Makefile for NintendoDS to contrib [Costa]
+- Add -w in configure compile tests to avoid spurious warnings [Beucler]
+- Fix typos in zlib.h comments for deflateSetDictionary()
+- Fix EOF detection in transparent gzread() [Maier]
+
+Changes in 1.2.3.3 (2 October 2006)
+- Make --shared the default for configure, add a --static option
+- Add compile option to permit invalid distance-too-far streams
+- Add inflateUndermine() function which is required to enable above
+- Remove use of "this" variable name for C++ compatibility [Marquess]
+- Add testing of shared library in make test, if shared library built
+- Use ftello() and fseeko() if available instead of ftell() and fseek()
+- Provide two versions of all functions that use the z_off_t type for
+  binary compatibility -- a normal version and a 64-bit offset version,
+  per the Large File Support Extension when _LARGEFILE64_SOURCE is
+  defined; use the 64-bit versions by default when _FILE_OFFSET_BITS
+  is defined to be 64
+- Add a --uname= option to configure to perhaps help with cross-compiling
+
+Changes in 1.2.3.2 (3 September 2006)
+- Turn off silly Borland warnings [Hay]
+- Use off64_t and define _LARGEFILE64_SOURCE when present
+- Fix missing dependency on inffixed.h in Makefile.in
+- Rig configure --shared to build both shared and static [Teredesai, Truta]
+- Remove zconf.in.h and instead create a new zlibdefs.h file
+- Fix contrib/minizip/unzip.c non-encrypted after encrypted [Vollant]
+- Add treebuild.xml (see http://treebuild.metux.de/) [Weigelt]
+
+Changes in 1.2.3.1 (16 August 2006)
+- Add watcom directory with OpenWatcom make files [Daniel]
+- Remove #undef of FAR in zconf.in.h for MVS [Fedtke]
+- Update make_vms.com [Zinser]
+- Use -fPIC for shared build in configure [Teredesai, Nicholson]
+- Use only major version number for libz.so on IRIX and OSF1 [Reinholdtsen]
+- Use fdopen() (not _fdopen()) for Interix in zutil.h [B�ck]
+- Add some FAQ entries about the contrib directory
+- Update the MVS question in the FAQ
+- Avoid extraneous reads after EOF in gzio.c [Brown]
+- Correct spelling of "successfully" in gzio.c [Randers-Pehrson]
+- Add comments to zlib.h about gzerror() usage [Brown]
+- Set extra flags in gzip header in gzopen() like deflate() does
+- Make configure options more compatible with double-dash conventions
+  [Weigelt]
+- Clean up compilation under Solaris SunStudio cc [Rowe, Reinholdtsen]
+- Fix uninstall target in Makefile.in [Truta]
+- Add pkgconfig support [Weigelt]
+- Use $(DESTDIR) macro in Makefile.in [Reinholdtsen, Weigelt]
+- Replace set_data_type() with a more accurate detect_data_type() in
+  trees.c, according to the txtvsbin.txt document [Truta]
+- Swap the order of #include <stdio.h> and #include "zlib.h" in
+  gzio.c, example.c and minigzip.c [Truta]
+- Shut up annoying VS2005 warnings about standard C deprecation [Rowe,
+  Truta] (where?)
+- Fix target "clean" from win32/Makefile.bor [Truta]
+- Create .pdb and .manifest files in win32/makefile.msc [Ziegler, Rowe]
+- Update zlib www home address in win32/DLL_FAQ.txt [Truta]
+- Update contrib/masmx86/inffas32.asm for VS2005 [Vollant, Van Wassenhove]
+- Enable browse info in the "Debug" and "ASM Debug" configurations in
+  the Visual C++ 6 project, and set (non-ASM) "Debug" as default [Truta]
+- Add pkgconfig support [Weigelt]
+- Add ZLIB_VER_MAJOR, ZLIB_VER_MINOR and ZLIB_VER_REVISION in zlib.h,
+  for use in win32/zlib1.rc [Polushin, Rowe, Truta]
+- Add a document that explains the new text detection scheme to
+  doc/txtvsbin.txt [Truta]
+- Add rfc1950.txt, rfc1951.txt and rfc1952.txt to doc/ [Truta]
+- Move algorithm.txt into doc/ [Truta]
+- Synchronize FAQ with website
+- Fix compressBound(), was low for some pathological cases [Fearnley]
+- Take into account wrapper variations in deflateBound()
+- Set examples/zpipe.c input and output to binary mode for Windows
+- Update examples/zlib_how.html with new zpipe.c (also web site)
+- Fix some warnings in examples/gzlog.c and examples/zran.c (it seems
+  that gcc became pickier in 4.0)
+- Add zlib.map for Linux: "All symbols from zlib-1.1.4 remain
+  un-versioned, the patch adds versioning only for symbols introduced in
+  zlib-1.2.0 or later.  It also declares as local those symbols which are
+  not designed to be exported." [Levin]
+- Update Z_PREFIX list in zconf.in.h, add --zprefix option to configure
+- Do not initialize global static by default in trees.c, add a response
+  NO_INIT_GLOBAL_POINTERS to initialize them if needed [Marquess]
+- Don't use strerror() in gzio.c under WinCE [Yakimov]
+- Don't use errno.h in zutil.h under WinCE [Yakimov]
+- Move arguments for AR to its usage to allow replacing ar [Marot]
+- Add HAVE_VISIBILITY_PRAGMA in zconf.in.h for Mozilla [Randers-Pehrson]
+- Improve inflateInit() and inflateInit2() documentation
+- Fix structure size comment in inflate.h
+- Change configure help option from --h* to --help [Santos]
+
+Changes in 1.2.3 (18 July 2005)
+- Apply security vulnerability fixes to contrib/infback9 as well
+- Clean up some text files (carriage returns, trailing space)
+- Update testzlib, vstudio, masmx64, and masmx86 in contrib [Vollant]
+
+Changes in 1.2.2.4 (11 July 2005)
+- Add inflatePrime() function for starting inflation at bit boundary
+- Avoid some Visual C warnings in deflate.c
+- Avoid more silly Visual C warnings in inflate.c and inftrees.c for 64-bit
+  compile
+- Fix some spelling errors in comments [Betts]
+- Correct inflateInit2() error return documentation in zlib.h
+- Add zran.c example of compressed data random access to examples
+  directory, shows use of inflatePrime()
+- Fix cast for assignments to strm->state in inflate.c and infback.c
+- Fix zlibCompileFlags() in zutil.c to use 1L for long shifts [Oberhumer]
+- Move declarations of gf2 functions to right place in crc32.c [Oberhumer]
+- Add cast in trees.c t avoid a warning [Oberhumer]
+- Avoid some warnings in fitblk.c, gun.c, gzjoin.c in examples [Oberhumer]
+- Update make_vms.com [Zinser]
+- Initialize state->write in inflateReset() since copied in inflate_fast()
+- Be more strict on incomplete code sets in inflate_table() and increase
+  ENOUGH and MAXD -- this repairs a possible security vulnerability for
+  invalid inflate input.  Thanks to Tavis Ormandy and Markus Oberhumer for
+  discovering the vulnerability and providing test cases.
+- Add ia64 support to configure for HP-UX [Smith]
+- Add error return to gzread() for format or i/o error [Levin]
+- Use malloc.h for OS/2 [Necasek]
+
+Changes in 1.2.2.3 (27 May 2005)
+- Replace 1U constants in inflate.c and inftrees.c for 64-bit compile
+- Typecast fread() return values in gzio.c [Vollant]
+- Remove trailing space in minigzip.c outmode (VC++ can't deal with it)
+- Fix crc check bug in gzread() after gzungetc() [Heiner]
+- Add the deflateTune() function to adjust internal compression parameters
+- Add a fast gzip decompressor, gun.c, to examples (use of inflateBack)
+- Remove an incorrect assertion in examples/zpipe.c
+- Add C++ wrapper in infback9.h [Donais]
+- Fix bug in inflateCopy() when decoding fixed codes
+- Note in zlib.h how much deflateSetDictionary() actually uses
+- Remove USE_DICT_HEAD in deflate.c (would mess up inflate if used)
+- Add _WIN32_WCE to define WIN32 in zconf.in.h [Spencer]
+- Don't include stderr.h or errno.h for _WIN32_WCE in zutil.h [Spencer]
+- Add gzdirect() function to indicate transparent reads
+- Update contrib/minizip [Vollant]
+- Fix compilation of deflate.c when both ASMV and FASTEST [Oberhumer]
+- Add casts in crc32.c to avoid warnings [Oberhumer]
+- Add contrib/masmx64 [Vollant]
+- Update contrib/asm586, asm686, masmx86, testzlib, vstudio [Vollant]
+
+Changes in 1.2.2.2 (30 December 2004)
+- Replace structure assignments in deflate.c and inflate.c with zmemcpy to
+  avoid implicit memcpy calls (portability for no-library compilation)
+- Increase sprintf() buffer size in gzdopen() to allow for large numbers
+- Add INFLATE_STRICT to check distances against zlib header
+- Improve WinCE errno handling and comments [Chang]
+- Remove comment about no gzip header processing in FAQ
+- Add Z_FIXED strategy option to deflateInit2() to force fixed trees
+- Add updated make_vms.com [Coghlan], update README
+- Create a new "examples" directory, move gzappend.c there, add zpipe.c,
+  fitblk.c, gzlog.[ch], gzjoin.c, and zlib_how.html.
+- Add FAQ entry and comments in deflate.c on uninitialized memory access
+- Add Solaris 9 make options in configure [Gilbert]
+- Allow strerror() usage in gzio.c for STDC
+- Fix DecompressBuf in contrib/delphi/ZLib.pas [ManChesTer]
+- Update contrib/masmx86/inffas32.asm and gvmat32.asm [Vollant]
+- Use z_off_t for adler32_combine() and crc32_combine() lengths
+- Make adler32() much faster for small len
+- Use OS_CODE in deflate() default gzip header
+
+Changes in 1.2.2.1 (31 October 2004)
+- Allow inflateSetDictionary() call for raw inflate
+- Fix inflate header crc check bug for file names and comments
+- Add deflateSetHeader() and gz_header structure for custom gzip headers
+- Add inflateGetheader() to retrieve gzip headers
+- Add crc32_combine() and adler32_combine() functions
+- Add alloc_func, free_func, in_func, out_func to Z_PREFIX list
+- Use zstreamp consistently in zlib.h (inflate_back functions)
+- Remove GUNZIP condition from definition of inflate_mode in inflate.h
+  and in contrib/inflate86/inffast.S [Truta, Anderson]
+- Add support for AMD64 in contrib/inflate86/inffas86.c [Anderson]
+- Update projects/README.projects and projects/visualc6 [Truta]
+- Update win32/DLL_FAQ.txt [Truta]
+- Avoid warning under NO_GZCOMPRESS in gzio.c; fix typo [Truta]
+- Deprecate Z_ASCII; use Z_TEXT instead [Truta]
+- Use a new algorithm for setting strm->data_type in trees.c [Truta]
+- Do not define an exit() prototype in zutil.c unless DEBUG defined
+- Remove prototype of exit() from zutil.c, example.c, minigzip.c [Truta]
+- Add comment in zlib.h for Z_NO_FLUSH parameter to deflate()
+- Fix Darwin build version identification [Peterson]
+
+Changes in 1.2.2 (3 October 2004)
+- Update zlib.h comments on gzip in-memory processing
+- Set adler to 1 in inflateReset() to support Java test suite [Walles]
+- Add contrib/dotzlib [Ravn]
+- Update win32/DLL_FAQ.txt [Truta]
+- Update contrib/minizip [Vollant]
+- Move contrib/visual-basic.txt to old/ [Truta]
+- Fix assembler builds in projects/visualc6/ [Truta]
+
+Changes in 1.2.1.2 (9 September 2004)
+- Update INDEX file
+- Fix trees.c to update strm->data_type (no one ever noticed!)
+- Fix bug in error case in inflate.c, infback.c, and infback9.c [Brown]
+- Add "volatile" to crc table flag declaration (for DYNAMIC_CRC_TABLE)
+- Add limited multitasking protection to DYNAMIC_CRC_TABLE
+- Add NO_vsnprintf for VMS in zutil.h [Mozilla]
+- Don't declare strerror() under VMS [Mozilla]
+- Add comment to DYNAMIC_CRC_TABLE to use get_crc_table() to initialize
+- Update contrib/ada [Anisimkov]
+- Update contrib/minizip [Vollant]
+- Fix configure to not hardcode directories for Darwin [Peterson]
+- Fix gzio.c to not return error on empty files [Brown]
+- Fix indentation; update version in contrib/delphi/ZLib.pas and
+  contrib/pascal/zlibpas.pas [Truta]
+- Update mkasm.bat in contrib/masmx86 [Truta]
+- Update contrib/untgz [Truta]
+- Add projects/README.projects [Truta]
+- Add project for MS Visual C++ 6.0 in projects/visualc6 [Cadieux, Truta]
+- Update win32/DLL_FAQ.txt [Truta]
+- Update list of Z_PREFIX symbols in zconf.h [Randers-Pehrson, Truta]
+- Remove an unnecessary assignment to curr in inftrees.c [Truta]
+- Add OS/2 to exe builds in configure [Poltorak]
+- Remove err dummy parameter in zlib.h [Kientzle]
+
+Changes in 1.2.1.1 (9 January 2004)
+- Update email address in README
+- Several FAQ updates
+- Fix a big fat bug in inftrees.c that prevented decoding valid
+  dynamic blocks with only literals and no distance codes --
+  Thanks to "Hot Emu" for the bug report and sample file
+- Add a note to puff.c on no distance codes case.
+
+Changes in 1.2.1 (17 November 2003)
+- Remove a tab in contrib/gzappend/gzappend.c
+- Update some interfaces in contrib for new zlib functions
+- Update zlib version number in some contrib entries
+- Add Windows CE definition for ptrdiff_t in zutil.h [Mai, Truta]
+- Support shared libraries on Hurd and KFreeBSD [Brown]
+- Fix error in NO_DIVIDE option of adler32.c
+
+Changes in 1.2.0.8 (4 November 2003)
+- Update version in contrib/delphi/ZLib.pas and contrib/pascal/zlibpas.pas
+- Add experimental NO_DIVIDE #define in adler32.c
+    - Possibly faster on some processors (let me know if it is)
+- Correct Z_BLOCK to not return on first inflate call if no wrap
+- Fix strm->data_type on inflate() return to correctly indicate EOB
+- Add deflatePrime() function for appending in the middle of a byte
+- Add contrib/gzappend for an example of appending to a stream
+- Update win32/DLL_FAQ.txt [Truta]
+- Delete Turbo C comment in README [Truta]
+- Improve some indentation in zconf.h [Truta]
+- Fix infinite loop on bad input in configure script [Church]
+- Fix gzeof() for concatenated gzip files [Johnson]
+- Add example to contrib/visual-basic.txt [Michael B.]
+- Add -p to mkdir's in Makefile.in [vda]
+- Fix configure to properly detect presence or lack of printf functions
+- Add AS400 support [Monnerat]
+- Add a little Cygwin support [Wilson]
+
+Changes in 1.2.0.7 (21 September 2003)
+- Correct some debug formats in contrib/infback9
+- Cast a type in a debug statement in trees.c
+- Change search and replace delimiter in configure from % to # [Beebe]
+- Update contrib/untgz to 0.2 with various fixes [Truta]
+- Add build support for Amiga [Nikl]
+- Remove some directories in old that have been updated to 1.2
+- Add dylib building for Mac OS X in configure and Makefile.in
+- Remove old distribution stuff from Makefile
+- Update README to point to DLL_FAQ.txt, and add comment on Mac OS X
+- Update links in README
+
+Changes in 1.2.0.6 (13 September 2003)
+- Minor FAQ updates
+- Update contrib/minizip to 1.00 [Vollant]
+- Remove test of gz functions in example.c when GZ_COMPRESS defined [Truta]
+- Update POSTINC comment for 68060 [Nikl]
+- Add contrib/infback9 with deflate64 decoding (unsupported)
+- For MVS define NO_vsnprintf and undefine FAR [van Burik]
+- Add pragma for fdopen on MVS [van Burik]
+
+Changes in 1.2.0.5 (8 September 2003)
+- Add OF to inflateBackEnd() declaration in zlib.h
+- Remember start when using gzdopen in the middle of a file
+- Use internal off_t counters in gz* functions to properly handle seeks
+- Perform more rigorous check for distance-too-far in inffast.c
+- Add Z_BLOCK flush option to return from inflate at block boundary
+- Set strm->data_type on return from inflate
+    - Indicate bits unused, if at block boundary, and if in last block
+- Replace size_t with ptrdiff_t in crc32.c, and check for correct size
+- Add condition so old NO_DEFLATE define still works for compatibility
+- FAQ update regarding the Windows DLL [Truta]
+- INDEX update: add qnx entry, remove aix entry [Truta]
+- Install zlib.3 into mandir [Wilson]
+- Move contrib/zlib_dll_FAQ.txt to win32/DLL_FAQ.txt; update [Truta]
+- Adapt the zlib interface to the new DLL convention guidelines [Truta]
+- Introduce ZLIB_WINAPI macro to allow the export of functions using
+  the WINAPI calling convention, for Visual Basic [Vollant, Truta]
+- Update msdos and win32 scripts and makefiles [Truta]
+- Export symbols by name, not by ordinal, in win32/zlib.def [Truta]
+- Add contrib/ada [Anisimkov]
+- Move asm files from contrib/vstudio/vc70_32 to contrib/asm386 [Truta]
+- Rename contrib/asm386 to contrib/masmx86 [Truta, Vollant]
+- Add contrib/masm686 [Truta]
+- Fix offsets in contrib/inflate86 and contrib/masmx86/inffas32.asm
+  [Truta, Vollant]
+- Update contrib/delphi; rename to contrib/pascal; add example [Truta]
+- Remove contrib/delphi2; add a new contrib/delphi [Truta]
+- Avoid inclusion of the nonstandard <memory.h> in contrib/iostream,
+  and fix some method prototypes [Truta]
+- Fix the ZCR_SEED2 constant to avoid warnings in contrib/minizip
+  [Truta]
+- Avoid the use of backslash (\) in contrib/minizip [Vollant]
+- Fix file time handling in contrib/untgz; update makefiles [Truta]
+- Update contrib/vstudio/vc70_32 to comply with the new DLL guidelines
+  [Vollant]
+- Remove contrib/vstudio/vc15_16 [Vollant]
+- Rename contrib/vstudio/vc70_32 to contrib/vstudio/vc7 [Truta]
+- Update README.contrib [Truta]
+- Invert the assignment order of match_head and s->prev[...] in
+  INSERT_STRING [Truta]
+- Compare TOO_FAR with 32767 instead of 32768, to avoid 16-bit warnings
+  [Truta]
+- Compare function pointers with 0, not with NULL or Z_NULL [Truta]
+- Fix prototype of syncsearch in inflate.c [Truta]
+- Introduce ASMINF macro to be enabled when using an ASM implementation
+  of inflate_fast [Truta]
+- Change NO_DEFLATE to NO_GZCOMPRESS [Truta]
+- Modify test_gzio in example.c to take a single file name as a
+  parameter [Truta]
+- Exit the example.c program if gzopen fails [Truta]
+- Add type casts around strlen in example.c [Truta]
+- Remove casting to sizeof in minigzip.c; give a proper type
+  to the variable compared with SUFFIX_LEN [Truta]
+- Update definitions of STDC and STDC99 in zconf.h [Truta]
+- Synchronize zconf.h with the new Windows DLL interface [Truta]
+- Use SYS16BIT instead of __32BIT__ to distinguish between
+  16- and 32-bit platforms [Truta]
+- Use far memory allocators in small 16-bit memory models for
+  Turbo C [Truta]
+- Add info about the use of ASMV, ASMINF and ZLIB_WINAPI in
+  zlibCompileFlags [Truta]
+- Cygwin has vsnprintf [Wilson]
+- In Windows16, OS_CODE is 0, as in MSDOS [Truta]
+- In Cygwin, OS_CODE is 3 (Unix), not 11 (Windows32) [Wilson]
+
+Changes in 1.2.0.4 (10 August 2003)
+- Minor FAQ updates
+- Be more strict when checking inflateInit2's windowBits parameter
+- Change NO_GUNZIP compile option to NO_GZIP to cover deflate as well
+- Add gzip wrapper option to deflateInit2 using windowBits
+- Add updated QNX rule in configure and qnx directory [Bonnefoy]
+- Make inflate distance-too-far checks more rigorous
+- Clean up FAR usage in inflate
+- Add casting to sizeof() in gzio.c and minigzip.c
+
+Changes in 1.2.0.3 (19 July 2003)
+- Fix silly error in gzungetc() implementation [Vollant]
+- Update contrib/minizip and contrib/vstudio [Vollant]
+- Fix printf format in example.c
+- Correct cdecl support in zconf.in.h [Anisimkov]
+- Minor FAQ updates
+
+Changes in 1.2.0.2 (13 July 2003)
+- Add ZLIB_VERNUM in zlib.h for numerical preprocessor comparisons
+- Attempt to avoid warnings in crc32.c for pointer-int conversion
+- Add AIX to configure, remove aix directory [Bakker]
+- Add some casts to minigzip.c
+- Improve checking after insecure sprintf() or vsprintf() calls
+- Remove #elif's from crc32.c
+- Change leave label to inf_leave in inflate.c and infback.c to avoid
+  library conflicts
+- Remove inflate gzip decoding by default--only enable gzip decoding by
+  special request for stricter backward compatibility
+- Add zlibCompileFlags() function to return compilation information
+- More typecasting in deflate.c to avoid warnings
+- Remove leading underscore from _Capital #defines [Truta]
+- Fix configure to link shared library when testing
+- Add some Windows CE target adjustments [Mai]
+- Remove #define ZLIB_DLL in zconf.h [Vollant]
+- Add zlib.3 [Rodgers]
+- Update RFC URL in deflate.c and algorithm.txt [Mai]
+- Add zlib_dll_FAQ.txt to contrib [Truta]
+- Add UL to some constants [Truta]
+- Update minizip and vstudio [Vollant]
+- Remove vestigial NEED_DUMMY_RETURN from zconf.in.h
+- Expand use of NO_DUMMY_DECL to avoid all dummy structures
+- Added iostream3 to contrib [Schwardt]
+- Replace rewind() with fseek() for WinCE [Truta]
+- Improve setting of zlib format compression level flags
+    - Report 0 for huffman and rle strategies and for level == 0 or 1
+    - Report 2 only for level == 6
+- Only deal with 64K limit when necessary at compile time [Truta]
+- Allow TOO_FAR check to be turned off at compile time [Truta]
+- Add gzclearerr() function [Souza]
+- Add gzungetc() function
+
+Changes in 1.2.0.1 (17 March 2003)
+- Add Z_RLE strategy for run-length encoding [Truta]
+    - When Z_RLE requested, restrict matches to distance one
+    - Update zlib.h, minigzip.c, gzopen(), gzdopen() for Z_RLE
+- Correct FASTEST compilation to allow level == 0
+- Clean up what gets compiled for FASTEST
+- Incorporate changes to zconf.in.h [Vollant]
+    - Refine detection of Turbo C need for dummy returns
+    - Refine ZLIB_DLL compilation
+    - Include additional header file on VMS for off_t typedef
+- Try to use _vsnprintf where it supplants vsprintf [Vollant]
+- Add some casts in inffast.c
+- Enchance comments in zlib.h on what happens if gzprintf() tries to
+  write more than 4095 bytes before compression
+- Remove unused state from inflateBackEnd()
+- Remove exit(0) from minigzip.c, example.c
+- Get rid of all those darn tabs
+- Add "check" target to Makefile.in that does the same thing as "test"
+- Add "mostlyclean" and "maintainer-clean" targets to Makefile.in
+- Update contrib/inflate86 [Anderson]
+- Update contrib/testzlib, contrib/vstudio, contrib/minizip [Vollant]
+- Add msdos and win32 directories with makefiles [Truta]
+- More additions and improvements to the FAQ
+
+Changes in 1.2.0 (9 March 2003)
+- New and improved inflate code
+    - About 20% faster
+    - Does not allocate 32K window unless and until needed
+    - Automatically detects and decompresses gzip streams
+    - Raw inflate no longer needs an extra dummy byte at end
+    - Added inflateBack functions using a callback interface--even faster
+      than inflate, useful for file utilities (gzip, zip)
+    - Added inflateCopy() function to record state for random access on
+      externally generated deflate streams (e.g. in gzip files)
+    - More readable code (I hope)
+- New and improved crc32()
+    - About 50% faster, thanks to suggestions from Rodney Brown
+- Add deflateBound() and compressBound() functions
+- Fix memory leak in deflateInit2()
+- Permit setting dictionary for raw deflate (for parallel deflate)
+- Fix const declaration for gzwrite()
+- Check for some malloc() failures in gzio.c
+- Fix bug in gzopen() on single-byte file 0x1f
+- Fix bug in gzread() on concatenated file with 0x1f at end of buffer
+  and next buffer doesn't start with 0x8b
+- Fix uncompress() to return Z_DATA_ERROR on truncated input
+- Free memory at end of example.c
+- Remove MAX #define in trees.c (conflicted with some libraries)
+- Fix static const's in deflate.c, gzio.c, and zutil.[ch]
+- Declare malloc() and free() in gzio.c if STDC not defined
+- Use malloc() instead of calloc() in zutil.c if int big enough
+- Define STDC for AIX
+- Add aix/ with approach for compiling shared library on AIX
+- Add HP-UX support for shared libraries in configure
+- Add OpenUNIX support for shared libraries in configure
+- Use $cc instead of gcc to build shared library
+- Make prefix directory if needed when installing
+- Correct Macintosh avoidance of typedef Byte in zconf.h
+- Correct Turbo C memory allocation when under Linux
+- Use libz.a instead of -lz in Makefile (assure use of compiled library)
+- Update configure to check for snprintf or vsnprintf functions and their
+  return value, warn during make if using an insecure function
+- Fix configure problem with compile-time knowledge of HAVE_UNISTD_H that
+  is lost when library is used--resolution is to build new zconf.h
+- Documentation improvements (in zlib.h):
+    - Document raw deflate and inflate
+    - Update RFCs URL
+    - Point out that zlib and gzip formats are different
+    - Note that Z_BUF_ERROR is not fatal
+    - Document string limit for gzprintf() and possible buffer overflow
+    - Note requirement on avail_out when flushing
+    - Note permitted values of flush parameter of inflate()
+- Add some FAQs (and even answers) to the FAQ
+- Add contrib/inflate86/ for x86 faster inflate
+- Add contrib/blast/ for PKWare Data Compression Library decompression
+- Add contrib/puff/ simple inflate for deflate format description
+
+Changes in 1.1.4 (11 March 2002)
+- ZFREE was repeated on same allocation on some error conditions.
+  This creates a security problem described in
+  http://www.zlib.org/advisory-2002-03-11.txt
+- Returned incorrect error (Z_MEM_ERROR) on some invalid data
+- Avoid accesses before window for invalid distances with inflate window
+  less than 32K.
+- force windowBits > 8 to avoid a bug in the encoder for a window size
+  of 256 bytes. (A complete fix will be available in 1.1.5).
+
+Changes in 1.1.3 (9 July 1998)
+- fix "an inflate input buffer bug that shows up on rare but persistent
+  occasions" (Mark)
+- fix gzread and gztell for concatenated .gz files (Didier Le Botlan)
+- fix gzseek(..., SEEK_SET) in write mode
+- fix crc check after a gzeek (Frank Faubert)
+- fix miniunzip when the last entry in a zip file is itself a zip file
+  (J Lillge)
+- add contrib/asm586 and contrib/asm686 (Brian Raiter)
+  See http://www.muppetlabs.com/~breadbox/software/assembly.html
+- add support for Delphi 3 in contrib/delphi (Bob Dellaca)
+- add support for C++Builder 3 and Delphi 3 in contrib/delphi2 (Davide Moretti)
+- do not exit prematurely in untgz if 0 at start of block (Magnus Holmgren)
+- use macro EXTERN instead of extern to support DLL for BeOS (Sander Stoks)
+- added a FAQ file
+
+- Support gzdopen on Mac with Metrowerks (Jason Linhart)
+- Do not redefine Byte on Mac (Brad Pettit & Jason Linhart)
+- define SEEK_END too if SEEK_SET is not defined (Albert Chin-A-Young)
+- avoid some warnings with Borland C (Tom Tanner)
+- fix a problem in contrib/minizip/zip.c for 16-bit MSDOS (Gilles Vollant)
+- emulate utime() for WIN32 in contrib/untgz  (Gilles Vollant)
+- allow several arguments to configure (Tim Mooney, Frodo Looijaard)
+- use libdir and includedir in Makefile.in (Tim Mooney)
+- support shared libraries on OSF1 V4 (Tim Mooney)
+- remove so_locations in "make clean"  (Tim Mooney)
+- fix maketree.c compilation error (Glenn, Mark)
+- Python interface to zlib now in Python 1.5 (Jeremy Hylton)
+- new Makefile.riscos (Rich Walker)
+- initialize static descriptors in trees.c for embedded targets (Nick Smith)
+- use "foo-gz" in example.c for RISCOS and VMS (Nick Smith)
+- add the OS/2 files in Makefile.in too (Andrew Zabolotny)
+- fix fdopen and halloc macros for Microsoft C 6.0 (Tom Lane)
+- fix maketree.c to allow clean compilation of inffixed.h (Mark)
+- fix parameter check in deflateCopy (Gunther Nikl)
+- cleanup trees.c, use compressed_len only in debug mode (Christian Spieler)
+- Many portability patches by Christian Spieler:
+  . zutil.c, zutil.h: added "const" for zmem*
+  . Make_vms.com: fixed some typos
+  . Make_vms.com: msdos/Makefile.*: removed zutil.h from some dependency lists
+  . msdos/Makefile.msc: remove "default rtl link library" info from obj files
+  . msdos/Makefile.*: use model-dependent name for the built zlib library
+  . msdos/Makefile.emx, nt/Makefile.emx, nt/Makefile.gcc:
+     new makefiles, for emx (DOS/OS2), emx&rsxnt and mingw32 (Windows 9x / NT)
+- use define instead of typedef for Bytef also for MSC small/medium (Tom Lane)
+- replace __far with _far for better portability (Christian Spieler, Tom Lane)
+- fix test for errno.h in configure (Tim Newsham)
+
+Changes in 1.1.2 (19 March 98)
+- added contrib/minzip, mini zip and unzip based on zlib (Gilles Vollant)
+  See http://www.winimage.com/zLibDll/unzip.html
+- preinitialize the inflate tables for fixed codes, to make the code
+  completely thread safe (Mark)
+- some simplifications and slight speed-up to the inflate code (Mark)
+- fix gzeof on non-compressed files (Allan Schrum)
+- add -std1 option in configure for OSF1 to fix gzprintf (Martin Mokrejs)
+- use default value of 4K for Z_BUFSIZE for 16-bit MSDOS (Tim Wegner + Glenn)
+- added os2/Makefile.def and os2/zlib.def (Andrew Zabolotny)
+- add shared lib support for UNIX_SV4.2MP (MATSUURA Takanori)
+- do not wrap extern "C" around system includes (Tom Lane)
+- mention zlib binding for TCL in README (Andreas Kupries)
+- added amiga/Makefile.pup for Amiga powerUP SAS/C PPC (Andreas Kleinert)
+- allow "make install prefix=..." even after configure (Glenn Randers-Pehrson)
+- allow "configure --prefix $HOME" (Tim Mooney)
+- remove warnings in example.c and gzio.c (Glenn Randers-Pehrson)
+- move Makefile.sas to amiga/Makefile.sas
+
+Changes in 1.1.1 (27 Feb 98)
+- fix macros _tr_tally_* in deflate.h for debug mode  (Glenn Randers-Pehrson)
+- remove block truncation heuristic which had very marginal effect for zlib
+  (smaller lit_bufsize than in gzip 1.2.4) and degraded a little the
+  compression ratio on some files. This also allows inlining _tr_tally for
+  matches in deflate_slow.
+- added msdos/Makefile.w32 for WIN32 Microsoft Visual C++ (Bob Frazier)
+
+Changes in 1.1.0 (24 Feb 98)
+- do not return STREAM_END prematurely in inflate (John Bowler)
+- revert to the zlib 1.0.8 inflate to avoid the gcc 2.8.0 bug (Jeremy Buhler)
+- compile with -DFASTEST to get compression code optimized for speed only
+- in minigzip, try mmap'ing the input file first (Miguel Albrecht)
+- increase size of I/O buffers in minigzip.c and gzio.c (not a big gain
+  on Sun but significant on HP)
+
+- add a pointer to experimental unzip library in README (Gilles Vollant)
+- initialize variable gcc in configure (Chris Herborth)
+
+Changes in 1.0.9 (17 Feb 1998)
+- added gzputs and gzgets functions
+- do not clear eof flag in gzseek (Mark Diekhans)
+- fix gzseek for files in transparent mode (Mark Diekhans)
+- do not assume that vsprintf returns the number of bytes written (Jens Krinke)
+- replace EXPORT with ZEXPORT to avoid conflict with other programs
+- added compress2 in zconf.h, zlib.def, zlib.dnt
+- new asm code from Gilles Vollant in contrib/asm386
+- simplify the inflate code (Mark):
+ . Replace ZALLOC's in huft_build() with single ZALLOC in inflate_blocks_new()
+ . ZALLOC the length list in inflate_trees_fixed() instead of using stack
+ . ZALLOC the value area for huft_build() instead of using stack
+ . Simplify Z_FINISH check in inflate()
+
+- Avoid gcc 2.8.0 comparison bug a little differently than zlib 1.0.8
+- in inftrees.c, avoid cc -O bug on HP (Farshid Elahi)
+- in zconf.h move the ZLIB_DLL stuff earlier to avoid problems with
+  the declaration of FAR (Gilles VOllant)
+- install libz.so* with mode 755 (executable) instead of 644 (Marc Lehmann)
+- read_buf buf parameter of type Bytef* instead of charf*
+- zmemcpy parameters are of type Bytef*, not charf* (Joseph Strout)
+- do not redeclare unlink in minigzip.c for WIN32 (John Bowler)
+- fix check for presence of directories in "make install" (Ian Willis)
+
+Changes in 1.0.8 (27 Jan 1998)
+- fixed offsets in contrib/asm386/gvmat32.asm (Gilles Vollant)
+- fix gzgetc and gzputc for big endian systems (Markus Oberhumer)
+- added compress2() to allow setting the compression level
+- include sys/types.h to get off_t on some systems (Marc Lehmann & QingLong)
+- use constant arrays for the static trees in trees.c instead of computing
+  them at run time (thanks to Ken Raeburn for this suggestion). To create
+  trees.h, compile with GEN_TREES_H and run "make test".
+- check return code of example in "make test" and display result
+- pass minigzip command line options to file_compress
+- simplifying code of inflateSync to avoid gcc 2.8 bug
+
+- support CC="gcc -Wall" in configure -s (QingLong)
+- avoid a flush caused by ftell in gzopen for write mode (Ken Raeburn)
+- fix test for shared library support to avoid compiler warnings
+- zlib.lib -> zlib.dll in msdos/zlib.rc (Gilles Vollant)
+- check for TARGET_OS_MAC in addition to MACOS (Brad Pettit)
+- do not use fdopen for Metrowerks on Mac (Brad Pettit))
+- add checks for gzputc and gzputc in example.c
+- avoid warnings in gzio.c and deflate.c (Andreas Kleinert)
+- use const for the CRC table (Ken Raeburn)
+- fixed "make uninstall" for shared libraries
+- use Tracev instead of Trace in infblock.c
+- in example.c use correct compressed length for test_sync
+- suppress +vnocompatwarnings in configure for HPUX (not always supported)
+
+Changes in 1.0.7 (20 Jan 1998)
+- fix gzseek which was broken in write mode
+- return error for gzseek to negative absolute position
+- fix configure for Linux (Chun-Chung Chen)
+- increase stack space for MSC (Tim Wegner)
+- get_crc_table and inflateSyncPoint are EXPORTed (Gilles Vollant)
+- define EXPORTVA for gzprintf (Gilles Vollant)
+- added man page zlib.3 (Rick Rodgers)
+- for contrib/untgz, fix makedir() and improve Makefile
+
+- check gzseek in write mode in example.c
+- allocate extra buffer for seeks only if gzseek is actually called
+- avoid signed/unsigned comparisons (Tim Wegner, Gilles Vollant)
+- add inflateSyncPoint in zconf.h
+- fix list of exported functions in nt/zlib.dnt and mdsos/zlib.def
+
+Changes in 1.0.6 (19 Jan 1998)
+- add functions gzprintf, gzputc, gzgetc, gztell, gzeof, gzseek, gzrewind and
+  gzsetparams (thanks to Roland Giersig and Kevin Ruland for some of this code)
+- Fix a deflate bug occurring only with compression level 0 (thanks to
+  Andy Buckler for finding this one).
+- In minigzip, pass transparently also the first byte for .Z files.
+- return Z_BUF_ERROR instead of Z_OK if output buffer full in uncompress()
+- check Z_FINISH in inflate (thanks to Marc Schluper)
+- Implement deflateCopy (thanks to Adam Costello)
+- make static libraries by default in configure, add --shared option.
+- move MSDOS or Windows specific files to directory msdos
+- suppress the notion of partial flush to simplify the interface
+  (but the symbol Z_PARTIAL_FLUSH is kept for compatibility with 1.0.4)
+- suppress history buffer provided by application to simplify the interface
+  (this feature was not implemented anyway in 1.0.4)
+- next_in and avail_in must be initialized before calling inflateInit or
+  inflateInit2
+- add EXPORT in all exported functions (for Windows DLL)
+- added Makefile.nt (thanks to Stephen Williams)
+- added the unsupported "contrib" directory:
+   contrib/asm386/ by Gilles Vollant <info@winimage.com>
+        386 asm code replacing longest_match().
+   contrib/iostream/ by Kevin Ruland <kevin@rodin.wustl.edu>
+        A C++ I/O streams interface to the zlib gz* functions
+   contrib/iostream2/  by Tyge L�vset <Tyge.Lovset@cmr.no>
+        Another C++ I/O streams interface
+   contrib/untgz/  by "Pedro A. Aranda Guti\irrez" <paag@tid.es>
+        A very simple tar.gz file extractor using zlib
+   contrib/visual-basic.txt by Carlos Rios <c_rios@sonda.cl>
+        How to use compress(), uncompress() and the gz* functions from VB.
+- pass params -f (filtered data), -h (huffman only), -1 to -9 (compression
+  level) in minigzip (thanks to Tom Lane)
+
+- use const for rommable constants in deflate
+- added test for gzseek and gztell in example.c
+- add undocumented function inflateSyncPoint() (hack for Paul Mackerras)
+- add undocumented function zError to convert error code to string
+  (for Tim Smithers)
+- Allow compilation of gzio with -DNO_DEFLATE to avoid the compression code.
+- Use default memcpy for Symantec MSDOS compiler.
+- Add EXPORT keyword for check_func (needed for Windows DLL)
+- add current directory to LD_LIBRARY_PATH for "make test"
+- create also a link for libz.so.1
+- added support for FUJITSU UXP/DS (thanks to Toshiaki Nomura)
+- use $(SHAREDLIB) instead of libz.so in Makefile.in (for HPUX)
+- added -soname for Linux in configure (Chun-Chung Chen,
+- assign numbers to the exported functions in zlib.def (for Windows DLL)
+- add advice in zlib.h for best usage of deflateSetDictionary
+- work around compiler bug on Atari (cast Z_NULL in call of s->checkfn)
+- allow compilation with ANSI keywords only enabled for TurboC in large model
+- avoid "versionString"[0] (Borland bug)
+- add NEED_DUMMY_RETURN for Borland
+- use variable z_verbose for tracing in debug mode (L. Peter Deutsch).
+- allow compilation with CC
+- defined STDC for OS/2 (David Charlap)
+- limit external names to 8 chars for MVS (Thomas Lund)
+- in minigzip.c, use static buffers only for 16-bit systems
+- fix suffix check for "minigzip -d foo.gz"
+- do not return an error for the 2nd of two consecutive gzflush() (Felix Lee)
+- use _fdopen instead of fdopen for MSC >= 6.0 (Thomas Fanslau)
+- added makelcc.bat for lcc-win32 (Tom St Denis)
+- in Makefile.dj2, use copy and del instead of install and rm (Frank Donahoe)
+- Avoid expanded $Id$. Use "rcs -kb" or "cvs admin -kb" to avoid Id expansion.
+- check for unistd.h in configure (for off_t)
+- remove useless check parameter in inflate_blocks_free
+- avoid useless assignment of s->check to itself in inflate_blocks_new
+- do not flush twice in gzclose (thanks to Ken Raeburn)
+- rename FOPEN as F_OPEN to avoid clash with /usr/include/sys/file.h
+- use NO_ERRNO_H instead of enumeration of operating systems with errno.h
+- work around buggy fclose on pipes for HP/UX
+- support zlib DLL with BORLAND C++ 5.0 (thanks to Glenn Randers-Pehrson)
+- fix configure if CC is already equal to gcc
+
+Changes in 1.0.5 (3 Jan 98)
+- Fix inflate to terminate gracefully when fed corrupted or invalid data
+- Use const for rommable constants in inflate
+- Eliminate memory leaks on error conditions in inflate
+- Removed some vestigial code in inflate
+- Update web address in README
+
+Changes in 1.0.4 (24 Jul 96)
+- In very rare conditions, deflate(s, Z_FINISH) could fail to produce an EOF
+  bit, so the decompressor could decompress all the correct data but went
+  on to attempt decompressing extra garbage data. This affected minigzip too.
+- zlibVersion and gzerror return const char* (needed for DLL)
+- port to RISCOS (no fdopen, no multiple dots, no unlink, no fileno)
+- use z_error only for DEBUG (avoid problem with DLLs)
+
+Changes in 1.0.3 (2 Jul 96)
+- use z_streamp instead of z_stream *, which is now a far pointer in MSDOS
+  small and medium models; this makes the library incompatible with previous
+  versions for these models. (No effect in large model or on other systems.)
+- return OK instead of BUF_ERROR if previous deflate call returned with
+  avail_out as zero but there is nothing to do
+- added memcmp for non STDC compilers
+- define NO_DUMMY_DECL for more Mac compilers (.h files merged incorrectly)
+- define __32BIT__ if __386__ or i386 is defined (pb. with Watcom and SCO)
+- better check for 16-bit mode MSC (avoids problem with Symantec)
+
+Changes in 1.0.2 (23 May 96)
+- added Windows DLL support
+- added a function zlibVersion (for the DLL support)
+- fixed declarations using Bytef in infutil.c (pb with MSDOS medium model)
+- Bytef is define's instead of typedef'd only for Borland C
+- avoid reading uninitialized memory in example.c
+- mention in README that the zlib format is now RFC1950
+- updated Makefile.dj2
+- added algorithm.doc
+
+Changes in 1.0.1 (20 May 96) [1.0 skipped to avoid confusion]
+- fix array overlay in deflate.c which sometimes caused bad compressed data
+- fix inflate bug with empty stored block
+- fix MSDOS medium model which was broken in 0.99
+- fix deflateParams() which could generated bad compressed data.
+- Bytef is define'd instead of typedef'ed (work around Borland bug)
+- added an INDEX file
+- new makefiles for DJGPP (Makefile.dj2), 32-bit Borland (Makefile.b32),
+  Watcom (Makefile.wat), Amiga SAS/C (Makefile.sas)
+- speed up adler32 for modern machines without auto-increment
+- added -ansi for IRIX in configure
+- static_init_done in trees.c is an int
+- define unlink as delete for VMS
+- fix configure for QNX
+- add configure branch for SCO and HPUX
+- avoid many warnings (unused variables, dead assignments, etc...)
+- no fdopen for BeOS
+- fix the Watcom fix for 32 bit mode (define FAR as empty)
+- removed redefinition of Byte for MKWERKS
+- work around an MWKERKS bug (incorrect merge of all .h files)
+
+Changes in 0.99 (27 Jan 96)
+- allow preset dictionary shared between compressor and decompressor
+- allow compression level 0 (no compression)
+- add deflateParams in zlib.h: allow dynamic change of compression level
+  and compression strategy.
+- test large buffers and deflateParams in example.c
+- add optional "configure" to build zlib as a shared library
+- suppress Makefile.qnx, use configure instead
+- fixed deflate for 64-bit systems (detected on Cray)
+- fixed inflate_blocks for 64-bit systems (detected on Alpha)
+- declare Z_DEFLATED in zlib.h (possible parameter for deflateInit2)
+- always return Z_BUF_ERROR when deflate() has nothing to do
+- deflateInit and inflateInit are now macros to allow version checking
+- prefix all global functions and types with z_ with -DZ_PREFIX
+- make falloc completely reentrant (inftrees.c)
+- fixed very unlikely race condition in ct_static_init
+- free in reverse order of allocation to help memory manager
+- use zlib-1.0/* instead of zlib/* inside the tar.gz
+- make zlib warning-free with "gcc -O3 -Wall -Wwrite-strings -Wpointer-arith
+  -Wconversion -Wstrict-prototypes -Wmissing-prototypes"
+- allow gzread on concatenated .gz files
+- deflateEnd now returns Z_DATA_ERROR if it was premature
+- deflate is finally (?) fully deterministic (no matches beyond end of input)
+- Document Z_SYNC_FLUSH
+- add uninstall in Makefile
+- Check for __cpluplus in zlib.h
+- Better test in ct_align for partial flush
+- avoid harmless warnings for Borland C++
+- initialize hash_head in deflate.c
+- avoid warning on fdopen (gzio.c) for HP cc -Aa
+- include stdlib.h for STDC compilers
+- include errno.h for Cray
+- ignore error if ranlib doesn't exist
+- call ranlib twice for NeXTSTEP
+- use exec_prefix instead of prefix for libz.a
+- renamed ct_* as _tr_* to avoid conflict with applications
+- clear z->msg in inflateInit2 before any error return
+- initialize opaque in example.c, gzio.c, deflate.c and inflate.c
+- fixed typo in zconf.h (_GNUC__ => __GNUC__)
+- check for WIN32 in zconf.h and zutil.c (avoid farmalloc in 32-bit mode)
+- fix typo in Make_vms.com (f$trnlnm -> f$getsyi)
+- in fcalloc, normalize pointer if size > 65520 bytes
+- don't use special fcalloc for 32 bit Borland C++
+- use STDC instead of __GO32__ to avoid redeclaring exit, calloc, etc...
+- use Z_BINARY instead of BINARY
+- document that gzclose after gzdopen will close the file
+- allow "a" as mode in gzopen.
+- fix error checking in gzread
+- allow skipping .gz extra-field on pipes
+- added reference to Perl interface in README
+- put the crc table in FAR data (I dislike more and more the medium model :)
+- added get_crc_table
+- added a dimension to all arrays (Borland C can't count).
+- workaround Borland C bug in declaration of inflate_codes_new & inflate_fast
+- guard against multiple inclusion of *.h (for precompiled header on Mac)
+- Watcom C pretends to be Microsoft C small model even in 32 bit mode.
+- don't use unsized arrays to avoid silly warnings by Visual C++:
+     warning C4746: 'inflate_mask' : unsized array treated as  '__far'
+     (what's wrong with far data in far model?).
+- define enum out of inflate_blocks_state to allow compilation with C++
+
+Changes in 0.95 (16 Aug 95)
+- fix MSDOS small and medium model (now easier to adapt to any compiler)
+- inlined send_bits
+- fix the final (:-) bug for deflate with flush (output was correct but
+  not completely flushed in rare occasions).
+- default window size is same for compression and decompression
+  (it's now sufficient to set MAX_WBITS in zconf.h).
+- voidp -> voidpf and voidnp -> voidp (for consistency with other
+  typedefs and because voidnp was not near in large model).
+
+Changes in 0.94 (13 Aug 95)
+- support MSDOS medium model
+- fix deflate with flush (could sometimes generate bad output)
+- fix deflateReset (zlib header was incorrectly suppressed)
+- added support for VMS
+- allow a compression level in gzopen()
+- gzflush now calls fflush
+- For deflate with flush, flush even if no more input is provided.
+- rename libgz.a as libz.a
+- avoid complex expression in infcodes.c triggering Turbo C bug
+- work around a problem with gcc on Alpha (in INSERT_STRING)
+- don't use inline functions (problem with some gcc versions)
+- allow renaming of Byte, uInt, etc... with #define.
+- avoid warning about (unused) pointer before start of array in deflate.c
+- avoid various warnings in gzio.c, example.c, infblock.c, adler32.c, zutil.c
+- avoid reserved word 'new' in trees.c
+
+Changes in 0.93 (25 June 95)
+- temporarily disable inline functions
+- make deflate deterministic
+- give enough lookahead for PARTIAL_FLUSH
+- Set binary mode for stdin/stdout in minigzip.c for OS/2
+- don't even use signed char in inflate (not portable enough)
+- fix inflate memory leak for segmented architectures
+
+Changes in 0.92 (3 May 95)
+- don't assume that char is signed (problem on SGI)
+- Clear bit buffer when starting a stored block
+- no memcpy on Pyramid
+- suppressed inftest.c
+- optimized fill_window, put longest_match inline for gcc
+- optimized inflate on stored blocks.
+- untabify all sources to simplify patches
+
+Changes in 0.91 (2 May 95)
+- Default MEM_LEVEL is 8 (not 9 for Unix) as documented in zlib.h
+- Document the memory requirements in zconf.h
+- added "make install"
+- fix sync search logic in inflateSync
+- deflate(Z_FULL_FLUSH) now works even if output buffer too short
+- after inflateSync, don't scare people with just "lo world"
+- added support for DJGPP
+
+Changes in 0.9 (1 May 95)
+- don't assume that zalloc clears the allocated memory (the TurboC bug
+  was Mark's bug after all :)
+- let again gzread copy uncompressed data unchanged (was working in 0.71)
+- deflate(Z_FULL_FLUSH), inflateReset and inflateSync are now fully implemented
+- added a test of inflateSync in example.c
+- moved MAX_WBITS to zconf.h because users might want to change that.
+- document explicitly that zalloc(64K) on MSDOS must return a normalized
+  pointer (zero offset)
+- added Makefiles for Microsoft C, Turbo C, Borland C++
+- faster crc32()
+
+Changes in 0.8 (29 April 95)
+- added fast inflate (inffast.c)
+- deflate(Z_FINISH) now returns Z_STREAM_END when done. Warning: this
+  is incompatible with previous versions of zlib which returned Z_OK.
+- work around a TurboC compiler bug (bad code for b << 0, see infutil.h)
+  (actually that was not a compiler bug, see 0.81 above)
+- gzread no longer reads one extra byte in certain cases
+- In gzio destroy(), don't reference a freed structure
+- avoid many warnings for MSDOS
+- avoid the ERROR symbol which is used by MS Windows
+
+Changes in 0.71 (14 April 95)
+- Fixed more MSDOS compilation problems :( There is still a bug with
+  TurboC large model.
+
+Changes in 0.7 (14 April 95)
+- Added full inflate support.
+- Simplified the crc32() interface. The pre- and post-conditioning
+  (one's complement) is now done inside crc32(). WARNING: this is
+  incompatible with previous versions; see zlib.h for the new usage.
+
+Changes in 0.61 (12 April 95)
+- workaround for a bug in TurboC. example and minigzip now work on MSDOS.
+
+Changes in 0.6 (11 April 95)
+- added minigzip.c
+- added gzdopen to reopen a file descriptor as gzFile
+- added transparent reading of non-gziped files in gzread.
+- fixed bug in gzread (don't read crc as data)
+- fixed bug in destroy (gzio.c) (don't return Z_STREAM_END for gzclose).
+- don't allocate big arrays in the stack (for MSDOS)
+- fix some MSDOS compilation problems
+
+Changes in 0.5:
+- do real compression in deflate.c. Z_PARTIAL_FLUSH is supported but
+  not yet Z_FULL_FLUSH.
+- support decompression but only in a single step (forced Z_FINISH)
+- added opaque object for zalloc and zfree.
+- added deflateReset and inflateReset
+- added a variable zlib_version for consistency checking.
+- renamed the 'filter' parameter of deflateInit2 as 'strategy'.
+  Added Z_FILTERED and Z_HUFFMAN_ONLY constants.
+
+Changes in 0.4:
+- avoid "zip" everywhere, use zlib instead of ziplib.
+- suppress Z_BLOCK_FLUSH, interpret Z_PARTIAL_FLUSH as block flush
+  if compression method == 8.
+- added adler32 and crc32
+- renamed deflateOptions as deflateInit2, call one or the other but not both
+- added the method parameter for deflateInit2.
+- added inflateInit2
+- simplied considerably deflateInit and inflateInit by not supporting
+  user-provided history buffer. This is supported only in deflateInit2
+  and inflateInit2.
+
+Changes in 0.3:
+- prefix all macro names with Z_
+- use Z_FINISH instead of deflateEnd to finish compression.
+- added Z_HUFFMAN_ONLY
+- added gzerror()
diff --git a/compat/zlib/FAQ b/compat/zlib/FAQ
new file mode 100644
index 0000000..99b7cf9
--- /dev/null
+++ b/compat/zlib/FAQ
@@ -0,0 +1,368 @@
+
+                Frequently Asked Questions about zlib
+
+
+If your question is not there, please check the zlib home page
+http://zlib.net/ which may have more recent information.
+The lastest zlib FAQ is at http://zlib.net/zlib_faq.html
+
+
+ 1. Is zlib Y2K-compliant?
+
+    Yes. zlib doesn't handle dates.
+
+ 2. Where can I get a Windows DLL version?
+
+    The zlib sources can be compiled without change to produce a DLL.  See the
+    file win32/DLL_FAQ.txt in the zlib distribution.  Pointers to the
+    precompiled DLL are found in the zlib web site at http://zlib.net/ .
+
+ 3. Where can I get a Visual Basic interface to zlib?
+
+    See
+        * http://marknelson.us/1997/01/01/zlib-engine/
+        * win32/DLL_FAQ.txt in the zlib distribution
+
+ 4. compress() returns Z_BUF_ERROR.
+
+    Make sure that before the call of compress(), the length of the compressed
+    buffer is equal to the available size of the compressed buffer and not
+    zero.  For Visual Basic, check that this parameter is passed by reference
+    ("as any"), not by value ("as long").
+
+ 5. deflate() or inflate() returns Z_BUF_ERROR.
+
+    Before making the call, make sure that avail_in and avail_out are not zero.
+    When setting the parameter flush equal to Z_FINISH, also make sure that
+    avail_out is big enough to allow processing all pending input.  Note that a
+    Z_BUF_ERROR is not fatal--another call to deflate() or inflate() can be
+    made with more input or output space.  A Z_BUF_ERROR may in fact be
+    unavoidable depending on how the functions are used, since it is not
+    possible to tell whether or not there is more output pending when
+    strm.avail_out returns with zero.  See http://zlib.net/zlib_how.html for a
+    heavily annotated example.
+
+ 6. Where's the zlib documentation (man pages, etc.)?
+
+    It's in zlib.h .  Examples of zlib usage are in the files test/example.c
+    and test/minigzip.c, with more in examples/ .
+
+ 7. Why don't you use GNU autoconf or libtool or ...?
+
+    Because we would like to keep zlib as a very small and simple package.
+    zlib is rather portable and doesn't need much configuration.
+
+ 8. I found a bug in zlib.
+
+    Most of the time, such problems are due to an incorrect usage of zlib.
+    Please try to reproduce the problem with a small program and send the
+    corresponding source to us at zlib@gzip.org .  Do not send multi-megabyte
+    data files without prior agreement.
+
+ 9. Why do I get "undefined reference to gzputc"?
+
+    If "make test" produces something like
+
+       example.o(.text+0x154): undefined reference to `gzputc'
+
+    check that you don't have old files libz.* in /usr/lib, /usr/local/lib or
+    /usr/X11R6/lib. Remove any old versions, then do "make install".
+
+10. I need a Delphi interface to zlib.
+
+    See the contrib/delphi directory in the zlib distribution.
+
+11. Can zlib handle .zip archives?
+
+    Not by itself, no.  See the directory contrib/minizip in the zlib
+    distribution.
+
+12. Can zlib handle .Z files?
+
+    No, sorry.  You have to spawn an uncompress or gunzip subprocess, or adapt
+    the code of uncompress on your own.
+
+13. How can I make a Unix shared library?
+
+    By default a shared (and a static) library is built for Unix.  So:
+
+    make distclean
+    ./configure
+    make
+
+14. How do I install a shared zlib library on Unix?
+
+    After the above, then:
+
+    make install
+
+    However, many flavors of Unix come with a shared zlib already installed.
+    Before going to the trouble of compiling a shared version of zlib and
+    trying to install it, you may want to check if it's already there!  If you
+    can #include <zlib.h>, it's there.  The -lz option will probably link to
+    it.  You can check the version at the top of zlib.h or with the
+    ZLIB_VERSION symbol defined in zlib.h .
+
+15. I have a question about OttoPDF.
+
+    We are not the authors of OttoPDF. The real author is on the OttoPDF web
+    site: Joel Hainley, jhainley@myndkryme.com.
+
+16. Can zlib decode Flate data in an Adobe PDF file?
+
+    Yes. See http://www.pdflib.com/ . To modify PDF forms, see
+    http://sourceforge.net/projects/acroformtool/ .
+
+17. Why am I getting this "register_frame_info not found" error on Solaris?
+
+    After installing zlib 1.1.4 on Solaris 2.6, running applications using zlib
+    generates an error such as:
+
+        ld.so.1: rpm: fatal: relocation error: file /usr/local/lib/libz.so:
+        symbol __register_frame_info: referenced symbol not found
+
+    The symbol __register_frame_info is not part of zlib, it is generated by
+    the C compiler (cc or gcc).  You must recompile applications using zlib
+    which have this problem.  This problem is specific to Solaris.  See
+    http://www.sunfreeware.com for Solaris versions of zlib and applications
+    using zlib.
+
+18. Why does gzip give an error on a file I make with compress/deflate?
+
+    The compress and deflate functions produce data in the zlib format, which
+    is different and incompatible with the gzip format.  The gz* functions in
+    zlib on the other hand use the gzip format.  Both the zlib and gzip formats
+    use the same compressed data format internally, but have different headers
+    and trailers around the compressed data.
+
+19. Ok, so why are there two different formats?
+
+    The gzip format was designed to retain the directory information about a
+    single file, such as the name and last modification date.  The zlib format
+    on the other hand was designed for in-memory and communication channel
+    applications, and has a much more compact header and trailer and uses a
+    faster integrity check than gzip.
+
+20. Well that's nice, but how do I make a gzip file in memory?
+
+    You can request that deflate write the gzip format instead of the zlib
+    format using deflateInit2().  You can also request that inflate decode the
+    gzip format using inflateInit2().  Read zlib.h for more details.
+
+21. Is zlib thread-safe?
+
+    Yes.  However any library routines that zlib uses and any application-
+    provided memory allocation routines must also be thread-safe.  zlib's gz*
+    functions use stdio library routines, and most of zlib's functions use the
+    library memory allocation routines by default.  zlib's *Init* functions
+    allow for the application to provide custom memory allocation routines.
+
+    Of course, you should only operate on any given zlib or gzip stream from a
+    single thread at a time.
+
+22. Can I use zlib in my commercial application?
+
+    Yes.  Please read the license in zlib.h.
+
+23. Is zlib under the GNU license?
+
+    No.  Please read the license in zlib.h.
+
+24. The license says that altered source versions must be "plainly marked". So
+    what exactly do I need to do to meet that requirement?
+
+    You need to change the ZLIB_VERSION and ZLIB_VERNUM #defines in zlib.h.  In
+    particular, the final version number needs to be changed to "f", and an
+    identification string should be appended to ZLIB_VERSION.  Version numbers
+    x.x.x.f are reserved for modifications to zlib by others than the zlib
+    maintainers.  For example, if the version of the base zlib you are altering
+    is "1.2.3.4", then in zlib.h you should change ZLIB_VERNUM to 0x123f, and
+    ZLIB_VERSION to something like "1.2.3.f-zachary-mods-v3".  You can also
+    update the version strings in deflate.c and inftrees.c.
+
+    For altered source distributions, you should also note the origin and
+    nature of the changes in zlib.h, as well as in ChangeLog and README, along
+    with the dates of the alterations.  The origin should include at least your
+    name (or your company's name), and an email address to contact for help or
+    issues with the library.
+
+    Note that distributing a compiled zlib library along with zlib.h and
+    zconf.h is also a source distribution, and so you should change
+    ZLIB_VERSION and ZLIB_VERNUM and note the origin and nature of the changes
+    in zlib.h as you would for a full source distribution.
+
+25. Will zlib work on a big-endian or little-endian architecture, and can I
+    exchange compressed data between them?
+
+    Yes and yes.
+
+26. Will zlib work on a 64-bit machine?
+
+    Yes.  It has been tested on 64-bit machines, and has no dependence on any
+    data types being limited to 32-bits in length.  If you have any
+    difficulties, please provide a complete problem report to zlib@gzip.org
+
+27. Will zlib decompress data from the PKWare Data Compression Library?
+
+    No.  The PKWare DCL uses a completely different compressed data format than
+    does PKZIP and zlib.  However, you can look in zlib's contrib/blast
+    directory for a possible solution to your problem.
+
+28. Can I access data randomly in a compressed stream?
+
+    No, not without some preparation.  If when compressing you periodically use
+    Z_FULL_FLUSH, carefully write all the pending data at those points, and
+    keep an index of those locations, then you can start decompression at those
+    points.  You have to be careful to not use Z_FULL_FLUSH too often, since it
+    can significantly degrade compression.  Alternatively, you can scan a
+    deflate stream once to generate an index, and then use that index for
+    random access.  See examples/zran.c .
+
+29. Does zlib work on MVS, OS/390, CICS, etc.?
+
+    It has in the past, but we have not heard of any recent evidence.  There
+    were working ports of zlib 1.1.4 to MVS, but those links no longer work.
+    If you know of recent, successful applications of zlib on these operating
+    systems, please let us know.  Thanks.
+
+30. Is there some simpler, easier to read version of inflate I can look at to
+    understand the deflate format?
+
+    First off, you should read RFC 1951.  Second, yes.  Look in zlib's
+    contrib/puff directory.
+
+31. Does zlib infringe on any patents?
+
+    As far as we know, no.  In fact, that was originally the whole point behind
+    zlib.  Look here for some more information:
+
+    http://www.gzip.org/#faq11
+
+32. Can zlib work with greater than 4 GB of data?
+
+    Yes.  inflate() and deflate() will process any amount of data correctly.
+    Each call of inflate() or deflate() is limited to input and output chunks
+    of the maximum value that can be stored in the compiler's "unsigned int"
+    type, but there is no limit to the number of chunks.  Note however that the
+    strm.total_in and strm_total_out counters may be limited to 4 GB.  These
+    counters are provided as a convenience and are not used internally by
+    inflate() or deflate().  The application can easily set up its own counters
+    updated after each call of inflate() or deflate() to count beyond 4 GB.
+    compress() and uncompress() may be limited to 4 GB, since they operate in a
+    single call.  gzseek() and gztell() may be limited to 4 GB depending on how
+    zlib is compiled.  See the zlibCompileFlags() function in zlib.h.
+
+    The word "may" appears several times above since there is a 4 GB limit only
+    if the compiler's "long" type is 32 bits.  If the compiler's "long" type is
+    64 bits, then the limit is 16 exabytes.
+
+33. Does zlib have any security vulnerabilities?
+
+    The only one that we are aware of is potentially in gzprintf().  If zlib is
+    compiled to use sprintf() or vsprintf(), then there is no protection
+    against a buffer overflow of an 8K string space (or other value as set by
+    gzbuffer()), other than the caller of gzprintf() assuring that the output
+    will not exceed 8K.  On the other hand, if zlib is compiled to use
+    snprintf() or vsnprintf(), which should normally be the case, then there is
+    no vulnerability.  The ./configure script will display warnings if an
+    insecure variation of sprintf() will be used by gzprintf().  Also the
+    zlibCompileFlags() function will return information on what variant of
+    sprintf() is used by gzprintf().
+
+    If you don't have snprintf() or vsnprintf() and would like one, you can
+    find a portable implementation here:
+
+        http://www.ijs.si/software/snprintf/
+
+    Note that you should be using the most recent version of zlib.  Versions
+    1.1.3 and before were subject to a double-free vulnerability, and versions
+    1.2.1 and 1.2.2 were subject to an access exception when decompressing
+    invalid compressed data.
+
+34. Is there a Java version of zlib?
+
+    Probably what you want is to use zlib in Java. zlib is already included
+    as part of the Java SDK in the java.util.zip package. If you really want
+    a version of zlib written in the Java language, look on the zlib home
+    page for links: http://zlib.net/ .
+
+35. I get this or that compiler or source-code scanner warning when I crank it
+    up to maximally-pedantic. Can't you guys write proper code?
+
+    Many years ago, we gave up attempting to avoid warnings on every compiler
+    in the universe.  It just got to be a waste of time, and some compilers
+    were downright silly as well as contradicted each other.  So now, we simply
+    make sure that the code always works.
+
+36. Valgrind (or some similar memory access checker) says that deflate is
+    performing a conditional jump that depends on an uninitialized value.
+    Isn't that a bug?
+
+    No.  That is intentional for performance reasons, and the output of deflate
+    is not affected.  This only started showing up recently since zlib 1.2.x
+    uses malloc() by default for allocations, whereas earlier versions used
+    calloc(), which zeros out the allocated memory.  Even though the code was
+    correct, versions 1.2.4 and later was changed to not stimulate these
+    checkers.
+
+37. Will zlib read the (insert any ancient or arcane format here) compressed
+    data format?
+
+    Probably not. Look in the comp.compression FAQ for pointers to various
+    formats and associated software.
+
+38. How can I encrypt/decrypt zip files with zlib?
+
+    zlib doesn't support encryption.  The original PKZIP encryption is very
+    weak and can be broken with freely available programs.  To get strong
+    encryption, use GnuPG, http://www.gnupg.org/ , which already includes zlib
+    compression.  For PKZIP compatible "encryption", look at
+    http://www.info-zip.org/
+
+39. What's the difference between the "gzip" and "deflate" HTTP 1.1 encodings?
+
+    "gzip" is the gzip format, and "deflate" is the zlib format.  They should
+    probably have called the second one "zlib" instead to avoid confusion with
+    the raw deflate compressed data format.  While the HTTP 1.1 RFC 2616
+    correctly points to the zlib specification in RFC 1950 for the "deflate"
+    transfer encoding, there have been reports of servers and browsers that
+    incorrectly produce or expect raw deflate data per the deflate
+    specification in RFC 1951, most notably Microsoft.  So even though the
+    "deflate" transfer encoding using the zlib format would be the more
+    efficient approach (and in fact exactly what the zlib format was designed
+    for), using the "gzip" transfer encoding is probably more reliable due to
+    an unfortunate choice of name on the part of the HTTP 1.1 authors.
+
+    Bottom line: use the gzip format for HTTP 1.1 encoding.
+
+40. Does zlib support the new "Deflate64" format introduced by PKWare?
+
+    No.  PKWare has apparently decided to keep that format proprietary, since
+    they have not documented it as they have previous compression formats.  In
+    any case, the compression improvements are so modest compared to other more
+    modern approaches, that it's not worth the effort to implement.
+
+41. I'm having a problem with the zip functions in zlib, can you help?
+
+    There are no zip functions in zlib.  You are probably using minizip by
+    Giles Vollant, which is found in the contrib directory of zlib.  It is not
+    part of zlib.  In fact none of the stuff in contrib is part of zlib.  The
+    files in there are not supported by the zlib authors.  You need to contact
+    the authors of the respective contribution for help.
+
+42. The match.asm code in contrib is under the GNU General Public License.
+    Since it's part of zlib, doesn't that mean that all of zlib falls under the
+    GNU GPL?
+
+    No.  The files in contrib are not part of zlib.  They were contributed by
+    other authors and are provided as a convenience to the user within the zlib
+    distribution.  Each item in contrib has its own license.
+
+43. Is zlib subject to export controls?  What is its ECCN?
+
+    zlib is not subject to export controls, and so is classified as EAR99.
+
+44. Can you please sign these lengthy legal documents and fax them back to us
+    so that we can use your software in our product?
+
+    No. Go away. Shoo.
diff --git a/compat/zlib/INDEX b/compat/zlib/INDEX
new file mode 100644
index 0000000..2ba0641
--- /dev/null
+++ b/compat/zlib/INDEX
@@ -0,0 +1,68 @@
+CMakeLists.txt  cmake build file
+ChangeLog       history of changes
+FAQ             Frequently Asked Questions about zlib
+INDEX           this file
+Makefile        dummy Makefile that tells you to ./configure
+Makefile.in     template for Unix Makefile
+README          guess what
+configure       configure script for Unix
+make_vms.com    makefile for VMS
+test/example.c  zlib usages examples for build testing
+test/minigzip.c minimal gzip-like functionality for build testing
+test/infcover.c inf*.c code coverage for build coverage testing
+treebuild.xml   XML description of source file dependencies
+zconf.h.cmakein zconf.h template for cmake
+zconf.h.in      zconf.h template for configure
+zlib.3          Man page for zlib
+zlib.3.pdf      Man page in PDF format
+zlib.map        Linux symbol information
+zlib.pc.in      Template for pkg-config descriptor
+zlib.pc.cmakein zlib.pc template for cmake
+zlib2ansi       perl script to convert source files for C++ compilation
+
+amiga/          makefiles for Amiga SAS C
+as400/          makefiles for AS/400
+doc/            documentation for formats and algorithms
+msdos/          makefiles for MSDOS
+nintendods/     makefile for Nintendo DS
+old/            makefiles for various architectures and zlib documentation
+                files that have not yet been updated for zlib 1.2.x
+qnx/            makefiles for QNX
+watcom/         makefiles for OpenWatcom
+win32/          makefiles for Windows
+
+                zlib public header files (required for library use):
+zconf.h
+zlib.h
+
+                private source files used to build the zlib library:
+adler32.c
+compress.c
+crc32.c
+crc32.h
+deflate.c
+deflate.h
+gzclose.c
+gzguts.h
+gzlib.c
+gzread.c
+gzwrite.c
+infback.c
+inffast.c
+inffast.h
+inffixed.h
+inflate.c
+inflate.h
+inftrees.c
+inftrees.h
+trees.c
+trees.h
+uncompr.c
+zutil.c
+zutil.h
+
+                source files for sample programs
+See examples/README.examples
+
+                unsupported contributions by third parties
+See contrib/README.contrib
diff --git a/compat/zlib/Makefile b/compat/zlib/Makefile
new file mode 100644
index 0000000..6bba86c
--- /dev/null
+++ b/compat/zlib/Makefile
@@ -0,0 +1,5 @@
+all:
+	-@echo "Please use ./configure first.  Thank you."
+
+distclean:
+	make -f Makefile.in distclean
diff --git a/compat/zlib/Makefile.in b/compat/zlib/Makefile.in
new file mode 100644
index 0000000..c61aa30
--- /dev/null
+++ b/compat/zlib/Makefile.in
@@ -0,0 +1,288 @@
+# Makefile for zlib
+# Copyright (C) 1995-2013 Jean-loup Gailly, Mark Adler
+# For conditions of distribution and use, see copyright notice in zlib.h
+
+# To compile and test, type:
+#    ./configure; make test
+# Normally configure builds both a static and a shared library.
+# If you want to build just a static library, use: ./configure --static
+
+# To use the asm code, type:
+#    cp contrib/asm?86/match.S ./match.S
+#    make LOC=-DASMV OBJA=match.o
+
+# To install /usr/local/lib/libz.* and /usr/local/include/zlib.h, type:
+#    make install
+# To install in $HOME instead of /usr/local, use:
+#    make install prefix=$HOME
+
+CC=cc
+
+CFLAGS=-O
+#CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7
+#CFLAGS=-g -DDEBUG
+#CFLAGS=-O3 -Wall -Wwrite-strings -Wpointer-arith -Wconversion \
+#           -Wstrict-prototypes -Wmissing-prototypes
+
+SFLAGS=-O
+LDFLAGS=
+TEST_LDFLAGS=-L. libz.a
+LDSHARED=$(CC)
+CPP=$(CC) -E
+
+STATICLIB=libz.a
+SHAREDLIB=libz.so
+SHAREDLIBV=libz.so.1.2.8
+SHAREDLIBM=libz.so.1
+LIBS=$(STATICLIB) $(SHAREDLIBV)
+
+AR=ar
+ARFLAGS=rc
+RANLIB=ranlib
+LDCONFIG=ldconfig
+LDSHAREDLIBC=-lc
+TAR=tar
+SHELL=/bin/sh
+EXE=
+
+prefix = /usr/local
+exec_prefix = ${prefix}
+libdir = ${exec_prefix}/lib
+sharedlibdir = ${libdir}
+includedir = ${prefix}/include
+mandir = ${prefix}/share/man
+man3dir = ${mandir}/man3
+pkgconfigdir = ${libdir}/pkgconfig
+
+OBJZ = adler32.o crc32.o deflate.o infback.o inffast.o inflate.o inftrees.o trees.o zutil.o
+OBJG = compress.o uncompr.o gzclose.o gzlib.o gzread.o gzwrite.o
+OBJC = $(OBJZ) $(OBJG)
+
+PIC_OBJZ = adler32.lo crc32.lo deflate.lo infback.lo inffast.lo inflate.lo inftrees.lo trees.lo zutil.lo
+PIC_OBJG = compress.lo uncompr.lo gzclose.lo gzlib.lo gzread.lo gzwrite.lo
+PIC_OBJC = $(PIC_OBJZ) $(PIC_OBJG)
+
+# to use the asm code: make OBJA=match.o, PIC_OBJA=match.lo
+OBJA =
+PIC_OBJA =
+
+OBJS = $(OBJC) $(OBJA)
+
+PIC_OBJS = $(PIC_OBJC) $(PIC_OBJA)
+
+all: static shared
+
+static: example$(EXE) minigzip$(EXE)
+
+shared: examplesh$(EXE) minigzipsh$(EXE)
+
+all64: example64$(EXE) minigzip64$(EXE)
+
+check: test
+
+test: all teststatic testshared
+
+teststatic: static
+	@TMPST=tmpst_$$; \
+	if echo hello world | ./minigzip | ./minigzip -d && ./example $$TMPST ; then \
+	  echo '		*** zlib test OK ***'; \
+	else \
+	  echo '		*** zlib test FAILED ***'; false; \
+	fi; \
+	rm -f $$TMPST
+
+testshared: shared
+	@LD_LIBRARY_PATH=`pwd`:$(LD_LIBRARY_PATH) ; export LD_LIBRARY_PATH; \
+	LD_LIBRARYN32_PATH=`pwd`:$(LD_LIBRARYN32_PATH) ; export LD_LIBRARYN32_PATH; \
+	DYLD_LIBRARY_PATH=`pwd`:$(DYLD_LIBRARY_PATH) ; export DYLD_LIBRARY_PATH; \
+	SHLIB_PATH=`pwd`:$(SHLIB_PATH) ; export SHLIB_PATH; \
+	TMPSH=tmpsh_$$; \
+	if echo hello world | ./minigzipsh | ./minigzipsh -d && ./examplesh $$TMPSH; then \
+	  echo '		*** zlib shared test OK ***'; \
+	else \
+	  echo '		*** zlib shared test FAILED ***'; false; \
+	fi; \
+	rm -f $$TMPSH
+
+test64: all64
+	@TMP64=tmp64_$$; \
+	if echo hello world | ./minigzip64 | ./minigzip64 -d && ./example64 $$TMP64; then \
+	  echo '		*** zlib 64-bit test OK ***'; \
+	else \
+	  echo '		*** zlib 64-bit test FAILED ***'; false; \
+	fi; \
+	rm -f $$TMP64
+
+infcover.o: test/infcover.c zlib.h zconf.h
+	$(CC) $(CFLAGS) -I. -c -o $@ test/infcover.c
+
+infcover: infcover.o libz.a
+	$(CC) $(CFLAGS) -o $@ infcover.o libz.a
+
+cover: infcover
+	rm -f *.gcda
+	./infcover
+	gcov inf*.c
+
+libz.a: $(OBJS)
+	$(AR) $(ARFLAGS) $@ $(OBJS)
+	-@ ($(RANLIB) $@ || true) >/dev/null 2>&1
+
+match.o: match.S
+	$(CPP) match.S > _match.s
+	$(CC) -c _match.s
+	mv _match.o match.o
+	rm -f _match.s
+
+match.lo: match.S
+	$(CPP) match.S > _match.s
+	$(CC) -c -fPIC _match.s
+	mv _match.o match.lo
+	rm -f _match.s
+
+example.o: test/example.c zlib.h zconf.h
+	$(CC) $(CFLAGS) -I. -c -o $@ test/example.c
+
+minigzip.o: test/minigzip.c zlib.h zconf.h
+	$(CC) $(CFLAGS) -I. -c -o $@ test/minigzip.c
+
+example64.o: test/example.c zlib.h zconf.h
+	$(CC) $(CFLAGS) -I. -D_FILE_OFFSET_BITS=64 -c -o $@ test/example.c
+
+minigzip64.o: test/minigzip.c zlib.h zconf.h
+	$(CC) $(CFLAGS) -I. -D_FILE_OFFSET_BITS=64 -c -o $@ test/minigzip.c
+
+.SUFFIXES: .lo
+
+.c.lo:
+	-@mkdir objs 2>/dev/null || test -d objs
+	$(CC) $(SFLAGS) -DPIC -c -o objs/$*.o $<
+	-@mv objs/$*.o $@
+
+placebo $(SHAREDLIBV): $(PIC_OBJS) libz.a
+	$(LDSHARED) $(SFLAGS) -o $@ $(PIC_OBJS) $(LDSHAREDLIBC) $(LDFLAGS)
+	rm -f $(SHAREDLIB) $(SHAREDLIBM)
+	ln -s $@ $(SHAREDLIB)
+	ln -s $@ $(SHAREDLIBM)
+	-@rmdir objs
+
+example$(EXE): example.o $(STATICLIB)
+	$(CC) $(CFLAGS) -o $@ example.o $(TEST_LDFLAGS)
+
+minigzip$(EXE): minigzip.o $(STATICLIB)
+	$(CC) $(CFLAGS) -o $@ minigzip.o $(TEST_LDFLAGS)
+
+examplesh$(EXE): example.o $(SHAREDLIBV)
+	$(CC) $(CFLAGS) -o $@ example.o -L. $(SHAREDLIBV)
+
+minigzipsh$(EXE): minigzip.o $(SHAREDLIBV)
+	$(CC) $(CFLAGS) -o $@ minigzip.o -L. $(SHAREDLIBV)
+
+example64$(EXE): example64.o $(STATICLIB)
+	$(CC) $(CFLAGS) -o $@ example64.o $(TEST_LDFLAGS)
+
+minigzip64$(EXE): minigzip64.o $(STATICLIB)
+	$(CC) $(CFLAGS) -o $@ minigzip64.o $(TEST_LDFLAGS)
+
+install-libs: $(LIBS)
+	-@if [ ! -d $(DESTDIR)$(exec_prefix)  ]; then mkdir -p $(DESTDIR)$(exec_prefix); fi
+	-@if [ ! -d $(DESTDIR)$(libdir)       ]; then mkdir -p $(DESTDIR)$(libdir); fi
+	-@if [ ! -d $(DESTDIR)$(sharedlibdir) ]; then mkdir -p $(DESTDIR)$(sharedlibdir); fi
+	-@if [ ! -d $(DESTDIR)$(man3dir)      ]; then mkdir -p $(DESTDIR)$(man3dir); fi
+	-@if [ ! -d $(DESTDIR)$(pkgconfigdir) ]; then mkdir -p $(DESTDIR)$(pkgconfigdir); fi
+	cp $(STATICLIB) $(DESTDIR)$(libdir)
+	chmod 644 $(DESTDIR)$(libdir)/$(STATICLIB)
+	-@($(RANLIB) $(DESTDIR)$(libdir)/libz.a || true) >/dev/null 2>&1
+	-@if test -n "$(SHAREDLIBV)"; then \
+	  cp $(SHAREDLIBV) $(DESTDIR)$(sharedlibdir); \
+	  echo "cp $(SHAREDLIBV) $(DESTDIR)$(sharedlibdir)"; \
+	  chmod 755 $(DESTDIR)$(sharedlibdir)/$(SHAREDLIBV); \
+	  echo "chmod 755 $(DESTDIR)$(sharedlibdir)/$(SHAREDLIBV)"; \
+	  rm -f $(DESTDIR)$(sharedlibdir)/$(SHAREDLIB) $(DESTDIR)$(sharedlibdir)/$(SHAREDLIBM); \
+	  ln -s $(SHAREDLIBV) $(DESTDIR)$(sharedlibdir)/$(SHAREDLIB); \
+	  ln -s $(SHAREDLIBV) $(DESTDIR)$(sharedlibdir)/$(SHAREDLIBM); \
+	  ($(LDCONFIG) || true)  >/dev/null 2>&1; \
+	fi
+	cp zlib.3 $(DESTDIR)$(man3dir)
+	chmod 644 $(DESTDIR)$(man3dir)/zlib.3
+	cp zlib.pc $(DESTDIR)$(pkgconfigdir)
+	chmod 644 $(DESTDIR)$(pkgconfigdir)/zlib.pc
+# The ranlib in install is needed on NeXTSTEP which checks file times
+# ldconfig is for Linux
+
+install: install-libs
+	-@if [ ! -d $(DESTDIR)$(includedir)   ]; then mkdir -p $(DESTDIR)$(includedir); fi
+	cp zlib.h zconf.h $(DESTDIR)$(includedir)
+	chmod 644 $(DESTDIR)$(includedir)/zlib.h $(DESTDIR)$(includedir)/zconf.h
+
+uninstall:
+	cd $(DESTDIR)$(includedir) && rm -f zlib.h zconf.h
+	cd $(DESTDIR)$(libdir) && rm -f libz.a; \
+	if test -n "$(SHAREDLIBV)" -a -f $(SHAREDLIBV); then \
+	  rm -f $(SHAREDLIBV) $(SHAREDLIB) $(SHAREDLIBM); \
+	fi
+	cd $(DESTDIR)$(man3dir) && rm -f zlib.3
+	cd $(DESTDIR)$(pkgconfigdir) && rm -f zlib.pc
+
+docs: zlib.3.pdf
+
+zlib.3.pdf: zlib.3
+	groff -mandoc -f H -T ps zlib.3 | ps2pdf - zlib.3.pdf
+
+zconf.h.cmakein: zconf.h.in
+	-@ TEMPFILE=zconfh_$$; \
+	echo "/#define ZCONF_H/ a\\\\\n#cmakedefine Z_PREFIX\\\\\n#cmakedefine Z_HAVE_UNISTD_H\n" >> $$TEMPFILE &&\
+	sed -f $$TEMPFILE zconf.h.in > zconf.h.cmakein &&\
+	touch -r zconf.h.in zconf.h.cmakein &&\
+	rm $$TEMPFILE
+
+zconf: zconf.h.in
+	cp -p zconf.h.in zconf.h
+
+mostlyclean: clean
+clean:
+	rm -f *.o *.lo *~ \
+	   example$(EXE) minigzip$(EXE) examplesh$(EXE) minigzipsh$(EXE) \
+	   example64$(EXE) minigzip64$(EXE) \
+	   infcover \
+	   libz.* foo.gz so_locations \
+	   _match.s maketree contrib/infback9/*.o
+	rm -rf objs
+	rm -f *.gcda *.gcno *.gcov
+	rm -f contrib/infback9/*.gcda contrib/infback9/*.gcno contrib/infback9/*.gcov
+
+maintainer-clean: distclean
+distclean: clean zconf zconf.h.cmakein docs
+	rm -f Makefile zlib.pc configure.log
+	-@rm -f .DS_Store
+	-@printf 'all:\n\t-@echo "Please use ./configure first.  Thank you."\n' > Makefile
+	-@printf '\ndistclean:\n\tmake -f Makefile.in distclean\n' >> Makefile
+	-@touch -r Makefile.in Makefile
+
+tags:
+	etags *.[ch]
+
+depend:
+	makedepend -- $(CFLAGS) -- *.[ch]
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+adler32.o zutil.o: zutil.h zlib.h zconf.h
+gzclose.o gzlib.o gzread.o gzwrite.o: zlib.h zconf.h gzguts.h
+compress.o example.o minigzip.o uncompr.o: zlib.h zconf.h
+crc32.o: zutil.h zlib.h zconf.h crc32.h
+deflate.o: deflate.h zutil.h zlib.h zconf.h
+infback.o inflate.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h inffixed.h
+inffast.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h
+inftrees.o: zutil.h zlib.h zconf.h inftrees.h
+trees.o: deflate.h zutil.h zlib.h zconf.h trees.h
+
+adler32.lo zutil.lo: zutil.h zlib.h zconf.h
+gzclose.lo gzlib.lo gzread.lo gzwrite.lo: zlib.h zconf.h gzguts.h
+compress.lo example.lo minigzip.lo uncompr.lo: zlib.h zconf.h
+crc32.lo: zutil.h zlib.h zconf.h crc32.h
+deflate.lo: deflate.h zutil.h zlib.h zconf.h
+infback.lo inflate.lo: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h inffixed.h
+inffast.lo: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h
+inftrees.lo: zutil.h zlib.h zconf.h inftrees.h
+trees.lo: deflate.h zutil.h zlib.h zconf.h trees.h
diff --git a/compat/zlib/README b/compat/zlib/README
new file mode 100644
index 0000000..5ca9d12
--- /dev/null
+++ b/compat/zlib/README
@@ -0,0 +1,115 @@
+ZLIB DATA COMPRESSION LIBRARY
+
+zlib 1.2.8 is a general purpose data compression library.  All the code is
+thread safe.  The data format used by the zlib library is described by RFCs
+(Request for Comments) 1950 to 1952 in the files
+http://tools.ietf.org/html/rfc1950 (zlib format), rfc1951 (deflate format) and
+rfc1952 (gzip format).
+
+All functions of the compression library are documented in the file zlib.h
+(volunteer to write man pages welcome, contact zlib@gzip.org).  A usage example
+of the library is given in the file test/example.c which also tests that
+the library is working correctly.  Another example is given in the file
+test/minigzip.c.  The compression library itself is composed of all source
+files in the root directory.
+
+To compile all files and run the test program, follow the instructions given at
+the top of Makefile.in.  In short "./configure; make test", and if that goes
+well, "make install" should work for most flavors of Unix.  For Windows, use
+one of the special makefiles in win32/ or contrib/vstudio/ .  For VMS, use
+make_vms.com.
+
+Questions about zlib should be sent to <zlib@gzip.org>, or to Gilles Vollant
+<info@winimage.com> for the Windows DLL version.  The zlib home page is
+http://zlib.net/ .  Before reporting a problem, please check this site to
+verify that you have the latest version of zlib; otherwise get the latest
+version and check whether the problem still exists or not.
+
+PLEASE read the zlib FAQ http://zlib.net/zlib_faq.html before asking for help.
+
+Mark Nelson <markn@ieee.org> wrote an article about zlib for the Jan.  1997
+issue of Dr.  Dobb's Journal; a copy of the article is available at
+http://marknelson.us/1997/01/01/zlib-engine/ .
+
+The changes made in version 1.2.8 are documented in the file ChangeLog.
+
+Unsupported third party contributions are provided in directory contrib/ .
+
+zlib is available in Java using the java.util.zip package, documented at
+http://java.sun.com/developer/technicalArticles/Programming/compression/ .
+
+A Perl interface to zlib written by Paul Marquess <pmqs@cpan.org> is available
+at CPAN (Comprehensive Perl Archive Network) sites, including
+http://search.cpan.org/~pmqs/IO-Compress-Zlib/ .
+
+A Python interface to zlib written by A.M. Kuchling <amk@amk.ca> is
+available in Python 1.5 and later versions, see
+http://docs.python.org/library/zlib.html .
+
+zlib is built into tcl: http://wiki.tcl.tk/4610 .
+
+An experimental package to read and write files in .zip format, written on top
+of zlib by Gilles Vollant <info@winimage.com>, is available in the
+contrib/minizip directory of zlib.
+
+
+Notes for some targets:
+
+- For Windows DLL versions, please see win32/DLL_FAQ.txt
+
+- For 64-bit Irix, deflate.c must be compiled without any optimization. With
+  -O, one libpng test fails. The test works in 32 bit mode (with the -n32
+  compiler flag). The compiler bug has been reported to SGI.
+
+- zlib doesn't work with gcc 2.6.3 on a DEC 3000/300LX under OSF/1 2.1 it works
+  when compiled with cc.
+
+- On Digital Unix 4.0D (formely OSF/1) on AlphaServer, the cc option -std1 is
+  necessary to get gzprintf working correctly. This is done by configure.
+
+- zlib doesn't work on HP-UX 9.05 with some versions of /bin/cc. It works with
+  other compilers. Use "make test" to check your compiler.
+
+- gzdopen is not supported on RISCOS or BEOS.
+
+- For PalmOs, see http://palmzlib.sourceforge.net/
+
+
+Acknowledgments:
+
+  The deflate format used by zlib was defined by Phil Katz.  The deflate and
+  zlib specifications were written by L.  Peter Deutsch.  Thanks to all the
+  people who reported problems and suggested various improvements in zlib; they
+  are too numerous to cite here.
+
+Copyright notice:
+
+ (C) 1995-2013 Jean-loup Gailly and Mark Adler
+
+  This software is provided 'as-is', without any express or implied
+  warranty.  In no event will the authors be held liable for any damages
+  arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any purpose,
+  including commercial applications, and to alter it and redistribute it
+  freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+
+  Jean-loup Gailly        Mark Adler
+  jloup@gzip.org          madler@alumni.caltech.edu
+
+If you use the zlib library in a product, we would appreciate *not* receiving
+lengthy legal documents to sign.  The sources are provided for free but without
+warranty of any kind.  The library has been entirely written by Jean-loup
+Gailly and Mark Adler; it does not include third-party code.
+
+If you redistribute modified sources, we would appreciate that you include in
+the file ChangeLog history information documenting your changes.  Please read
+the FAQ for more information on the distribution of modified source versions.
diff --git a/compat/zlib/adler32.c b/compat/zlib/adler32.c
new file mode 100644
index 0000000..a868f07
--- /dev/null
+++ b/compat/zlib/adler32.c
@@ -0,0 +1,179 @@
+/* adler32.c -- compute the Adler-32 checksum of a data stream
+ * Copyright (C) 1995-2011 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id$ */
+
+#include "zutil.h"
+
+#define local static
+
+local uLong adler32_combine_ OF((uLong adler1, uLong adler2, z_off64_t len2));
+
+#define BASE 65521      /* largest prime smaller than 65536 */
+#define NMAX 5552
+/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
+
+#define DO1(buf,i)  {adler += (buf)[i]; sum2 += adler;}
+#define DO2(buf,i)  DO1(buf,i); DO1(buf,i+1);
+#define DO4(buf,i)  DO2(buf,i); DO2(buf,i+2);
+#define DO8(buf,i)  DO4(buf,i); DO4(buf,i+4);
+#define DO16(buf)   DO8(buf,0); DO8(buf,8);
+
+/* use NO_DIVIDE if your processor does not do division in hardware --
+   try it both ways to see which is faster */
+#ifdef NO_DIVIDE
+/* note that this assumes BASE is 65521, where 65536 % 65521 == 15
+   (thank you to John Reiser for pointing this out) */
+#  define CHOP(a) \
+    do { \
+        unsigned long tmp = a >> 16; \
+        a &= 0xffffUL; \
+        a += (tmp << 4) - tmp; \
+    } while (0)
+#  define MOD28(a) \
+    do { \
+        CHOP(a); \
+        if (a >= BASE) a -= BASE; \
+    } while (0)
+#  define MOD(a) \
+    do { \
+        CHOP(a); \
+        MOD28(a); \
+    } while (0)
+#  define MOD63(a) \
+    do { /* this assumes a is not negative */ \
+        z_off64_t tmp = a >> 32; \
+        a &= 0xffffffffL; \
+        a += (tmp << 8) - (tmp << 5) + tmp; \
+        tmp = a >> 16; \
+        a &= 0xffffL; \
+        a += (tmp << 4) - tmp; \
+        tmp = a >> 16; \
+        a &= 0xffffL; \
+        a += (tmp << 4) - tmp; \
+        if (a >= BASE) a -= BASE; \
+    } while (0)
+#else
+#  define MOD(a) a %= BASE
+#  define MOD28(a) a %= BASE
+#  define MOD63(a) a %= BASE
+#endif
+
+/* ========================================================================= */
+uLong ZEXPORT adler32(adler, buf, len)
+    uLong adler;
+    const Bytef *buf;
+    uInt len;
+{
+    unsigned long sum2;
+    unsigned n;
+
+    /* split Adler-32 into component sums */
+    sum2 = (adler >> 16) & 0xffff;
+    adler &= 0xffff;
+
+    /* in case user likes doing a byte at a time, keep it fast */
+    if (len == 1) {
+        adler += buf[0];
+        if (adler >= BASE)
+            adler -= BASE;
+        sum2 += adler;
+        if (sum2 >= BASE)
+            sum2 -= BASE;
+        return adler | (sum2 << 16);
+    }
+
+    /* initial Adler-32 value (deferred check for len == 1 speed) */
+    if (buf == Z_NULL)
+        return 1L;
+
+    /* in case short lengths are provided, keep it somewhat fast */
+    if (len < 16) {
+        while (len--) {
+            adler += *buf++;
+            sum2 += adler;
+        }
+        if (adler >= BASE)
+            adler -= BASE;
+        MOD28(sum2);            /* only added so many BASE's */
+        return adler | (sum2 << 16);
+    }
+
+    /* do length NMAX blocks -- requires just one modulo operation */
+    while (len >= NMAX) {
+        len -= NMAX;
+        n = NMAX / 16;          /* NMAX is divisible by 16 */
+        do {
+            DO16(buf);          /* 16 sums unrolled */
+            buf += 16;
+        } while (--n);
+        MOD(adler);
+        MOD(sum2);
+    }
+
+    /* do remaining bytes (less than NMAX, still just one modulo) */
+    if (len) {                  /* avoid modulos if none remaining */
+        while (len >= 16) {
+            len -= 16;
+            DO16(buf);
+            buf += 16;
+        }
+        while (len--) {
+            adler += *buf++;
+            sum2 += adler;
+        }
+        MOD(adler);
+        MOD(sum2);
+    }
+
+    /* return recombined sums */
+    return adler | (sum2 << 16);
+}
+
+/* ========================================================================= */
+local uLong adler32_combine_(adler1, adler2, len2)
+    uLong adler1;
+    uLong adler2;
+    z_off64_t len2;
+{
+    unsigned long sum1;
+    unsigned long sum2;
+    unsigned rem;
+
+    /* for negative len, return invalid adler32 as a clue for debugging */
+    if (len2 < 0)
+        return 0xffffffffUL;
+
+    /* the derivation of this formula is left as an exercise for the reader */
+    MOD63(len2);                /* assumes len2 >= 0 */
+    rem = (unsigned)len2;
+    sum1 = adler1 & 0xffff;
+    sum2 = rem * sum1;
+    MOD(sum2);
+    sum1 += (adler2 & 0xffff) + BASE - 1;
+    sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem;
+    if (sum1 >= BASE) sum1 -= BASE;
+    if (sum1 >= BASE) sum1 -= BASE;
+    if (sum2 >= (BASE << 1)) sum2 -= (BASE << 1);
+    if (sum2 >= BASE) sum2 -= BASE;
+    return sum1 | (sum2 << 16);
+}
+
+/* ========================================================================= */
+uLong ZEXPORT adler32_combine(adler1, adler2, len2)
+    uLong adler1;
+    uLong adler2;
+    z_off_t len2;
+{
+    return adler32_combine_(adler1, adler2, len2);
+}
+
+uLong ZEXPORT adler32_combine64(adler1, adler2, len2)
+    uLong adler1;
+    uLong adler2;
+    z_off64_t len2;
+{
+    return adler32_combine_(adler1, adler2, len2);
+}
diff --git a/compat/zlib/amiga/Makefile.pup b/compat/zlib/amiga/Makefile.pup
new file mode 100644
index 0000000..8940c12
--- /dev/null
+++ b/compat/zlib/amiga/Makefile.pup
@@ -0,0 +1,69 @@
+# Amiga powerUP (TM) Makefile
+# makefile for libpng and SAS C V6.58/7.00 PPC compiler
+# Copyright (C) 1998 by Andreas R. Kleinert
+
+LIBNAME	= libzip.a
+
+CC	= scppc
+CFLAGS	= NOSTKCHK NOSINT OPTIMIZE OPTGO OPTPEEP OPTINLOCAL OPTINL \
+	  OPTLOOP OPTRDEP=8 OPTDEP=8 OPTCOMP=8 NOVER
+AR	= ppc-amigaos-ar cr
+RANLIB	= ppc-amigaos-ranlib
+LD	= ppc-amigaos-ld -r
+LDFLAGS	= -o
+LDLIBS	= LIB:scppc.a LIB:end.o
+RM	= delete quiet
+
+OBJS = adler32.o compress.o crc32.o gzclose.o gzlib.o gzread.o gzwrite.o \
+       uncompr.o deflate.o trees.o zutil.o inflate.o infback.o inftrees.o inffast.o
+
+TEST_OBJS = example.o minigzip.o
+
+all: example minigzip
+
+check: test
+test: all
+	example
+	echo hello world | minigzip | minigzip -d
+
+$(LIBNAME): $(OBJS)
+	$(AR) $@ $(OBJS)
+	-$(RANLIB) $@
+
+example: example.o $(LIBNAME)
+	$(LD) $(LDFLAGS) $@ LIB:c_ppc.o $@.o $(LIBNAME) $(LDLIBS)
+
+minigzip: minigzip.o $(LIBNAME)
+	$(LD) $(LDFLAGS) $@ LIB:c_ppc.o $@.o $(LIBNAME) $(LDLIBS)
+
+mostlyclean: clean
+clean:
+	$(RM) *.o example minigzip $(LIBNAME) foo.gz
+
+zip:
+	zip -ul9 zlib README ChangeLog Makefile Make????.??? Makefile.?? \
+	  descrip.mms *.[ch]
+
+tgz:
+	cd ..; tar cfz zlib/zlib.tgz zlib/README zlib/ChangeLog zlib/Makefile \
+	  zlib/Make????.??? zlib/Makefile.?? zlib/descrip.mms zlib/*.[ch]
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+adler32.o: zlib.h zconf.h
+compress.o: zlib.h zconf.h
+crc32.o: crc32.h zlib.h zconf.h
+deflate.o: deflate.h zutil.h zlib.h zconf.h
+example.o: zlib.h zconf.h
+gzclose.o: zlib.h zconf.h gzguts.h
+gzlib.o: zlib.h zconf.h gzguts.h
+gzread.o: zlib.h zconf.h gzguts.h
+gzwrite.o: zlib.h zconf.h gzguts.h
+inffast.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h
+inflate.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h
+infback.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h
+inftrees.o: zutil.h zlib.h zconf.h inftrees.h
+minigzip.o: zlib.h zconf.h
+trees.o: deflate.h zutil.h zlib.h zconf.h trees.h
+uncompr.o: zlib.h zconf.h
+zutil.o: zutil.h zlib.h zconf.h
diff --git a/compat/zlib/amiga/Makefile.sas b/compat/zlib/amiga/Makefile.sas
new file mode 100644
index 0000000..749e291
--- /dev/null
+++ b/compat/zlib/amiga/Makefile.sas
@@ -0,0 +1,68 @@
+# SMakefile for zlib
+# Modified from the standard UNIX Makefile Copyright Jean-loup Gailly
+# Osma Ahvenlampi <Osma.Ahvenlampi@hut.fi>
+# Amiga, SAS/C 6.56 & Smake
+
+CC=sc
+CFLAGS=OPT
+#CFLAGS=OPT CPU=68030
+#CFLAGS=DEBUG=LINE
+LDFLAGS=LIB z.lib
+
+SCOPTIONS=OPTSCHED OPTINLINE OPTALIAS OPTTIME OPTINLOCAL STRMERGE \
+       NOICONS PARMS=BOTH NOSTACKCHECK UTILLIB NOVERSION ERRORREXX \
+       DEF=POSTINC
+
+OBJS = adler32.o compress.o crc32.o gzclose.o gzlib.o gzread.o gzwrite.o \
+       uncompr.o deflate.o trees.o zutil.o inflate.o infback.o inftrees.o inffast.o
+
+TEST_OBJS = example.o minigzip.o
+
+all: SCOPTIONS example minigzip
+
+check: test
+test: all
+	example
+	echo hello world | minigzip | minigzip -d
+
+install: z.lib
+	copy clone zlib.h zconf.h INCLUDE:
+	copy clone z.lib LIB:
+
+z.lib: $(OBJS)
+	oml z.lib r $(OBJS)
+
+example: example.o z.lib
+	$(CC) $(CFLAGS) LINK TO $@ example.o $(LDFLAGS)
+
+minigzip: minigzip.o z.lib
+	$(CC) $(CFLAGS) LINK TO $@ minigzip.o $(LDFLAGS)
+
+mostlyclean: clean
+clean:
+	-delete force quiet example minigzip *.o z.lib foo.gz *.lnk SCOPTIONS
+
+SCOPTIONS: Makefile.sas
+	copy to $@ <from <
+$(SCOPTIONS)
+<
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+adler32.o: zlib.h zconf.h
+compress.o: zlib.h zconf.h
+crc32.o: crc32.h zlib.h zconf.h
+deflate.o: deflate.h zutil.h zlib.h zconf.h
+example.o: zlib.h zconf.h
+gzclose.o: zlib.h zconf.h gzguts.h
+gzlib.o: zlib.h zconf.h gzguts.h
+gzread.o: zlib.h zconf.h gzguts.h
+gzwrite.o: zlib.h zconf.h gzguts.h
+inffast.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h
+inflate.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h
+infback.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h
+inftrees.o: zutil.h zlib.h zconf.h inftrees.h
+minigzip.o: zlib.h zconf.h
+trees.o: deflate.h zutil.h zlib.h zconf.h trees.h
+uncompr.o: zlib.h zconf.h
+zutil.o: zutil.h zlib.h zconf.h
diff --git a/compat/zlib/as400/bndsrc b/compat/zlib/as400/bndsrc
new file mode 100644
index 0000000..98814fd
--- /dev/null
+++ b/compat/zlib/as400/bndsrc
@@ -0,0 +1,215 @@
+STRPGMEXP PGMLVL(*CURRENT) SIGNATURE('ZLIB')
+
+/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
+/*   Version 1.1.3 entry points.                                    */
+/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
+
+/********************************************************************/
+/*   *MODULE      ADLER32      ZLIB         01/02/01  00:15:09      */
+/********************************************************************/
+
+  EXPORT SYMBOL("adler32")
+
+/********************************************************************/
+/*   *MODULE      COMPRESS     ZLIB         01/02/01  00:15:09      */
+/********************************************************************/
+
+  EXPORT SYMBOL("compress")
+  EXPORT SYMBOL("compress2")
+
+/********************************************************************/
+/*   *MODULE      CRC32        ZLIB         01/02/01  00:15:09      */
+/********************************************************************/
+
+  EXPORT SYMBOL("crc32")
+  EXPORT SYMBOL("get_crc_table")
+
+/********************************************************************/
+/*   *MODULE      DEFLATE      ZLIB         01/02/01  00:15:09      */
+/********************************************************************/
+
+  EXPORT SYMBOL("deflate")
+  EXPORT SYMBOL("deflateEnd")
+  EXPORT SYMBOL("deflateSetDictionary")
+  EXPORT SYMBOL("deflateCopy")
+  EXPORT SYMBOL("deflateReset")
+  EXPORT SYMBOL("deflateParams")
+  EXPORT SYMBOL("deflatePrime")
+  EXPORT SYMBOL("deflateInit_")
+  EXPORT SYMBOL("deflateInit2_")
+
+/********************************************************************/
+/*   *MODULE      GZIO         ZLIB         01/02/01  00:15:09      */
+/********************************************************************/
+
+  EXPORT SYMBOL("gzopen")
+  EXPORT SYMBOL("gzdopen")
+  EXPORT SYMBOL("gzsetparams")
+  EXPORT SYMBOL("gzread")
+  EXPORT SYMBOL("gzwrite")
+  EXPORT SYMBOL("gzprintf")
+  EXPORT SYMBOL("gzputs")
+  EXPORT SYMBOL("gzgets")
+  EXPORT SYMBOL("gzputc")
+  EXPORT SYMBOL("gzgetc")
+  EXPORT SYMBOL("gzflush")
+  EXPORT SYMBOL("gzseek")
+  EXPORT SYMBOL("gzrewind")
+  EXPORT SYMBOL("gztell")
+  EXPORT SYMBOL("gzeof")
+  EXPORT SYMBOL("gzclose")
+  EXPORT SYMBOL("gzerror")
+
+/********************************************************************/
+/*   *MODULE      INFLATE      ZLIB         01/02/01  00:15:09      */
+/********************************************************************/
+
+  EXPORT SYMBOL("inflate")
+  EXPORT SYMBOL("inflateEnd")
+  EXPORT SYMBOL("inflateSetDictionary")
+  EXPORT SYMBOL("inflateSync")
+  EXPORT SYMBOL("inflateReset")
+  EXPORT SYMBOL("inflateInit_")
+  EXPORT SYMBOL("inflateInit2_")
+  EXPORT SYMBOL("inflateSyncPoint")
+
+/********************************************************************/
+/*   *MODULE      UNCOMPR      ZLIB         01/02/01  00:15:09      */
+/********************************************************************/
+
+  EXPORT SYMBOL("uncompress")
+
+/********************************************************************/
+/*   *MODULE      ZUTIL        ZLIB         01/02/01  00:15:09      */
+/********************************************************************/
+
+  EXPORT SYMBOL("zlibVersion")
+  EXPORT SYMBOL("zError")
+
+/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
+/*   Version 1.2.1 additional entry points.                         */
+/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
+
+/********************************************************************/
+/*   *MODULE      COMPRESS     ZLIB         01/02/01  00:15:09      */
+/********************************************************************/
+
+  EXPORT SYMBOL("compressBound")
+
+/********************************************************************/
+/*   *MODULE      DEFLATE      ZLIB         01/02/01  00:15:09      */
+/********************************************************************/
+
+  EXPORT SYMBOL("deflateBound")
+
+/********************************************************************/
+/*   *MODULE      GZIO         ZLIB         01/02/01  00:15:09      */
+/********************************************************************/
+
+  EXPORT SYMBOL("gzungetc")
+  EXPORT SYMBOL("gzclearerr")
+
+/********************************************************************/
+/*   *MODULE      INFBACK      ZLIB         01/02/01  00:15:09      */
+/********************************************************************/
+
+  EXPORT SYMBOL("inflateBack")
+  EXPORT SYMBOL("inflateBackEnd")
+  EXPORT SYMBOL("inflateBackInit_")
+
+/********************************************************************/
+/*   *MODULE      INFLATE      ZLIB         01/02/01  00:15:09      */
+/********************************************************************/
+
+  EXPORT SYMBOL("inflateCopy")
+
+/********************************************************************/
+/*   *MODULE      ZUTIL        ZLIB         01/02/01  00:15:09      */
+/********************************************************************/
+
+  EXPORT SYMBOL("zlibCompileFlags")
+
+/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
+/*   Version 1.2.5 additional entry points.                         */
+/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
+
+/********************************************************************/
+/*   *MODULE      ADLER32      ZLIB         01/02/01  00:15:09      */
+/********************************************************************/
+
+  EXPORT SYMBOL("adler32_combine")
+  EXPORT SYMBOL("adler32_combine64")
+
+/********************************************************************/
+/*   *MODULE      CRC32        ZLIB         01/02/01  00:15:09      */
+/********************************************************************/
+
+  EXPORT SYMBOL("crc32_combine")
+  EXPORT SYMBOL("crc32_combine64")
+
+/********************************************************************/
+/*   *MODULE      GZLIB        ZLIB         01/02/01  00:15:09      */
+/********************************************************************/
+
+  EXPORT SYMBOL("gzbuffer")
+  EXPORT SYMBOL("gzoffset")
+  EXPORT SYMBOL("gzoffset64")
+  EXPORT SYMBOL("gzopen64")
+  EXPORT SYMBOL("gzseek64")
+  EXPORT SYMBOL("gztell64")
+
+/********************************************************************/
+/*   *MODULE      GZREAD       ZLIB         01/02/01  00:15:09      */
+/********************************************************************/
+
+  EXPORT SYMBOL("gzclose_r")
+
+/********************************************************************/
+/*   *MODULE      GZWRITE      ZLIB         01/02/01  00:15:09      */
+/********************************************************************/
+
+  EXPORT SYMBOL("gzclose_w")
+
+/********************************************************************/
+/*   *MODULE      INFLATE      ZLIB         01/02/01  00:15:09      */
+/********************************************************************/
+
+  EXPORT SYMBOL("inflateMark")
+  EXPORT SYMBOL("inflatePrime")
+  EXPORT SYMBOL("inflateReset2")
+  EXPORT SYMBOL("inflateUndermine")
+
+/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
+/*   Version 1.2.6 additional entry points.                         */
+/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
+
+/********************************************************************/
+/*   *MODULE      DEFLATE      ZLIB         01/02/01  00:15:09      */
+/********************************************************************/
+
+  EXPORT SYMBOL("deflateResetKeep")
+  EXPORT SYMBOL("deflatePending")
+
+/********************************************************************/
+/*   *MODULE      GZWRITE      ZLIB         01/02/01  00:15:09      */
+/********************************************************************/
+
+  EXPORT SYMBOL("gzgetc_")
+
+/********************************************************************/
+/*   *MODULE      INFLATE      ZLIB         01/02/01  00:15:09      */
+/********************************************************************/
+
+  EXPORT SYMBOL("inflateResetKeep")
+
+/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
+/*   Version 1.2.8 additional entry points.                         */
+/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
+
+/********************************************************************/
+/*   *MODULE      INFLATE      ZLIB         01/02/01  00:15:09      */
+/********************************************************************/
+
+  EXPORT SYMBOL("inflateGetDictionary")
+
+ENDPGMEXP
diff --git a/compat/zlib/as400/compile.clp b/compat/zlib/as400/compile.clp
new file mode 100644
index 0000000..e3f47c6
--- /dev/null
+++ b/compat/zlib/as400/compile.clp
@@ -0,0 +1,110 @@
+/******************************************************************************/
+/*                                                                            */
+/*  ZLIB                                                                      */
+/*                                                                            */
+/*    Compile sources into modules and link them into a service program.      */
+/*                                                                            */
+/******************************************************************************/
+
+             PGM
+
+/*      Configuration adjustable parameters.                                  */
+
+             DCL        VAR(&SRCLIB) TYPE(*CHAR) LEN(10) +
+                          VALUE('ZLIB')                         /* Source library. */
+             DCL        VAR(&SRCFILE) TYPE(*CHAR) LEN(10) +
+                          VALUE('SOURCES')                      /* Source member file. */
+             DCL        VAR(&CTLFILE) TYPE(*CHAR) LEN(10) +
+                          VALUE('TOOLS')                        /* Control member file. */
+
+             DCL        VAR(&MODLIB) TYPE(*CHAR) LEN(10) +
+                          VALUE('ZLIB')                         /* Module library. */
+
+             DCL        VAR(&SRVLIB) TYPE(*CHAR) LEN(10) +
+                          VALUE('LGPL')                         /* Service program library. */
+
+             DCL        VAR(&CFLAGS) TYPE(*CHAR) +
+                          VALUE('OPTIMIZE(40)')                 /* Compile options. */
+
+             DCL        VAR(&TGTRLS) TYPE(*CHAR) +
+                          VALUE('V5R3M0')                       /* Target release. */
+
+
+/*      Working storage.                                                      */
+
+             DCL        VAR(&CMDLEN) TYPE(*DEC) LEN(15 5) VALUE(300)    /* Command length. */
+             DCL        VAR(&CMD) TYPE(*CHAR) LEN(512)
+             DCL        VAR(&FIXDCMD) TYPE(*CHAR) LEN(512)
+
+
+/*      Compile sources into modules.                                         */
+
+             CHGVAR     VAR(&FIXDCMD) VALUE('CRTCMOD' *BCAT &CFLAGS *BCAT      +
+                        'SYSIFCOPT(*IFS64IO)' *BCAT                            +
+                        'DEFINE(''_LARGEFILE64_SOURCE''' *BCAT                 +
+                        '''_LFS64_LARGEFILE=1'') TGTRLS(' *TCAT &TGTRLS *TCAT  +
+                        ') SRCFILE(' *TCAT &SRCLIB *TCAT '/' *TCAT             +
+                        &SRCFILE *TCAT ') MODULE(' *TCAT &MODLIB *TCAT '/')
+
+
+             CHGVAR     VAR(&CMD) VALUE(&FIXDCMD *TCAT 'ADLER32)')
+             CALL       PGM(QCMDEXC) PARM(&CMD &CMDLEN)
+
+             CHGVAR     VAR(&CMD) VALUE(&FIXDCMD *TCAT 'COMPRESS)')
+             CALL       PGM(QCMDEXC) PARM(&CMD &CMDLEN)
+
+             CHGVAR     VAR(&CMD) VALUE(&FIXDCMD *TCAT 'CRC32)')
+             CALL       PGM(QCMDEXC) PARM(&CMD &CMDLEN)
+
+             CHGVAR     VAR(&CMD) VALUE(&FIXDCMD *TCAT 'DEFLATE)')
+             CALL       PGM(QCMDEXC) PARM(&CMD &CMDLEN)
+
+             CHGVAR     VAR(&CMD) VALUE(&FIXDCMD *TCAT 'GZCLOSE)')
+             CALL       PGM(QCMDEXC) PARM(&CMD &CMDLEN)
+
+             CHGVAR     VAR(&CMD) VALUE(&FIXDCMD *TCAT 'GZLIB)')
+             CALL       PGM(QCMDEXC) PARM(&CMD &CMDLEN)
+
+             CHGVAR     VAR(&CMD) VALUE(&FIXDCMD *TCAT 'GZREAD)')
+             CALL       PGM(QCMDEXC) PARM(&CMD &CMDLEN)
+
+             CHGVAR     VAR(&CMD) VALUE(&FIXDCMD *TCAT 'GZWRITE)')
+             CALL       PGM(QCMDEXC) PARM(&CMD &CMDLEN)
+
+             CHGVAR     VAR(&CMD) VALUE(&FIXDCMD *TCAT 'INFBACK)')
+             CALL       PGM(QCMDEXC) PARM(&CMD &CMDLEN)
+
+             CHGVAR     VAR(&CMD) VALUE(&FIXDCMD *TCAT 'INFFAST)')
+             CALL       PGM(QCMDEXC) PARM(&CMD &CMDLEN)
+
+             CHGVAR     VAR(&CMD) VALUE(&FIXDCMD *TCAT 'INFLATE)')
+             CALL       PGM(QCMDEXC) PARM(&CMD &CMDLEN)
+
+             CHGVAR     VAR(&CMD) VALUE(&FIXDCMD *TCAT 'INFTREES)')
+             CALL       PGM(QCMDEXC) PARM(&CMD &CMDLEN)
+
+             CHGVAR     VAR(&CMD) VALUE(&FIXDCMD *TCAT 'TREES)')
+             CALL       PGM(QCMDEXC) PARM(&CMD &CMDLEN)
+
+             CHGVAR     VAR(&CMD) VALUE(&FIXDCMD *TCAT 'UNCOMPR)')
+             CALL       PGM(QCMDEXC) PARM(&CMD &CMDLEN)
+
+             CHGVAR     VAR(&CMD) VALUE(&FIXDCMD *TCAT 'ZUTIL)')
+             CALL       PGM(QCMDEXC) PARM(&CMD &CMDLEN)
+
+
+/*      Link modules into a service program.                                  */
+
+             CRTSRVPGM  SRVPGM(&SRVLIB/ZLIB) +
+                          MODULE(&MODLIB/ADLER32     &MODLIB/COMPRESS    +
+                                 &MODLIB/CRC32       &MODLIB/DEFLATE     +
+                                 &MODLIB/GZCLOSE     &MODLIB/GZLIB       +
+                                 &MODLIB/GZREAD      &MODLIB/GZWRITE     +
+                                 &MODLIB/INFBACK     &MODLIB/INFFAST     +
+                                 &MODLIB/INFLATE     &MODLIB/INFTREES    +
+                                 &MODLIB/TREES       &MODLIB/UNCOMPR     +
+                                 &MODLIB/ZUTIL)                          +
+                          SRCFILE(&SRCLIB/&CTLFILE) SRCMBR(BNDSRC)       +
+                          TEXT('ZLIB 1.2.8') TGTRLS(&TGTRLS)
+
+             ENDPGM
diff --git a/compat/zlib/as400/readme.txt b/compat/zlib/as400/readme.txt
new file mode 100644
index 0000000..7b5d93b
--- /dev/null
+++ b/compat/zlib/as400/readme.txt
@@ -0,0 +1,115 @@
+        ZLIB version 1.2.8 for AS400 installation instructions
+
+I) From an AS400 *SAVF file:
+
+1)      Unpacking archive to an AS400 save file
+
+On the AS400:
+
+_       Create the ZLIB AS400 library:
+
+        CRTLIB LIB(ZLIB) TYPE(*PROD) TEXT('ZLIB compression API library')
+
+_       Create a work save file, for example:
+
+                CRTSAVF FILE(ZLIB/ZLIBSAVF)
+
+On a PC connected to the target AS400:
+
+_       Unpack the save file image to a PC file "ZLIBSAVF"
+_       Upload this file into the save file on the AS400, for example
+                using ftp in BINARY mode.
+
+
+2)      Populating the ZLIB AS400 source library
+
+On the AS400:
+
+_       Extract the saved objects into the ZLIB AS400 library using:
+
+RSTOBJ OBJ(*ALL) SAVLIB(ZLIB) DEV(*SAVF) SAVF(ZLIB/ZLIBSAVF) RSTLIB(ZLIB)
+
+
+3)      Customize installation:
+
+_       Edit CL member ZLIB/TOOLS(COMPILE) and change parameters if needed,
+                according to the comments.
+
+_       Compile this member with:
+
+        CRTCLPGM PGM(ZLIB/COMPILE) SRCFILE(ZLIB/TOOLS) SRCMBR(COMPILE)
+
+
+4)      Compile and generate the service program:
+
+_       This can now be done by executing:
+
+        CALL PGM(ZLIB/COMPILE)
+
+
+
+II) From the original source distribution:
+
+1)      On the AS400, create the source library:
+
+        CRTLIB LIB(ZLIB) TYPE(*PROD) TEXT('ZLIB compression API library')
+
+2)      Create the source files:
+
+        CRTSRCPF FILE(ZLIB/SOURCES) RCDLEN(112) TEXT('ZLIB library modules')
+        CRTSRCPF FILE(ZLIB/H)       RCDLEN(112) TEXT('ZLIB library includes')
+        CRTSRCPF FILE(ZLIB/TOOLS)   RCDLEN(112) TEXT('ZLIB library control utilities')
+
+3)      From the machine hosting the distribution files, upload them (with
+                FTP in text mode, for example) according to the following table:
+
+    Original    AS400   AS400    AS400 AS400
+    file        file    member   type  description
+                SOURCES                Original ZLIB C subprogram sources
+    adler32.c           ADLER32  C     ZLIB - Compute the Adler-32 checksum of a dta strm
+    compress.c          COMPRESS C     ZLIB - Compress a memory buffer
+    crc32.c             CRC32    C     ZLIB - Compute the CRC-32 of a data stream
+    deflate.c           DEFLATE  C     ZLIB - Compress data using the deflation algorithm
+    gzclose.c           GZCLOSE  C     ZLIB - Close .gz files
+    gzlib.c             GZLIB    C     ZLIB - Miscellaneous .gz files IO support
+    gzread.c            GZREAD   C     ZLIB - Read .gz files
+    gzwrite.c           GZWRITE  C     ZLIB - Write .gz files
+    infback.c           INFBACK  C     ZLIB - Inflate using a callback interface
+    inffast.c           INFFAST  C     ZLIB - Fast proc. literals & length/distance pairs
+    inflate.c           INFLATE  C     ZLIB - Interface to inflate modules
+    inftrees.c          INFTREES C     ZLIB - Generate Huffman trees for efficient decode
+    trees.c             TREES    C     ZLIB - Output deflated data using Huffman coding
+    uncompr.c           UNCOMPR  C     ZLIB - Decompress a memory buffer
+    zutil.c             ZUTIL    C     ZLIB - Target dependent utility functions
+                H                      Original ZLIB C and ILE/RPG include files
+    crc32.h             CRC32    C     ZLIB - CRC32 tables
+    deflate.h           DEFLATE  C     ZLIB - Internal compression state
+    gzguts.h            GZGUTS   C     ZLIB - Definitions for the gzclose module
+    inffast.h           INFFAST  C     ZLIB - Header to use inffast.c
+    inffixed.h          INFFIXED C     ZLIB - Table for decoding fixed codes
+    inflate.h           INFLATE  C     ZLIB - Internal inflate state definitions
+    inftrees.h          INFTREES C     ZLIB - Header to use inftrees.c
+    trees.h             TREES    C     ZLIB - Created automatically with -DGEN_TREES_H
+    zconf.h             ZCONF    C     ZLIB - Compression library configuration
+    zlib.h              ZLIB     C     ZLIB - Compression library C user interface
+    as400/zlib.inc      ZLIB.INC RPGLE ZLIB - Compression library ILE RPG user interface
+    zutil.h             ZUTIL    C     ZLIB - Internal interface and configuration
+                TOOLS                  Building source software & AS/400 README
+    as400/bndsrc        BNDSRC         Entry point exportation list
+    as400/compile.clp   COMPILE  CLP   Compile sources & generate service program
+    as400/readme.txt    README   TXT   Installation instructions
+
+4)      Continue as in I)3).
+
+
+
+
+Notes:  For AS400 ILE RPG programmers, a /copy member defining the ZLIB
+                API prototypes for ILE RPG can be found in ZLIB/H(ZLIB.INC).
+                Please read comments in this member for more information.
+
+        Remember that most foreign textual data are ASCII coded: this
+                implementation does not handle conversion from/to ASCII, so
+                text data code conversions must be done explicitely.
+
+        Mainly for the reason above, always open zipped files in binary mode.
diff --git a/compat/zlib/as400/zlib.inc b/compat/zlib/as400/zlib.inc
new file mode 100644
index 0000000..7341a6d
--- /dev/null
+++ b/compat/zlib/as400/zlib.inc
@@ -0,0 +1,451 @@
+      *  ZLIB.INC - Interface to the general purpose compression library
+      *
+      *  ILE RPG400 version by Patrick Monnerat, DATASPHERE.
+      *  Version 1.2.8
+      *
+      *
+      *  WARNING:
+      *     Procedures inflateInit(), inflateInit2(), deflateInit(),
+      *         deflateInit2() and inflateBackInit() need to be called with
+      *         two additional arguments:
+      *         the package version string and the stream control structure.
+      *         size. This is needed because RPG lacks some macro feature.
+      *         Call these procedures as:
+      *             inflateInit(...: ZLIB_VERSION: %size(z_stream))
+      *
+      /if not defined(ZLIB_H_)
+      /define ZLIB_H_
+      *
+      **************************************************************************
+      *                               Constants
+      **************************************************************************
+      *
+      *  Versioning information.
+      *
+     D ZLIB_VERSION    C                   '1.2.8'
+     D ZLIB_VERNUM     C                   X'1280'
+     D ZLIB_VER_MAJOR  C                   1
+     D ZLIB_VER_MINOR  C                   2
+     D ZLIB_VER_REVISION...
+     D                 C                   8
+     D ZLIB_VER_SUBREVISION...
+     D                 C                   0
+      *
+      *  Other equates.
+      *
+     D Z_NO_FLUSH      C                   0
+     D Z_PARTIAL_FLUSH...
+     D                 C                   1
+     D Z_SYNC_FLUSH    C                   2
+     D Z_FULL_FLUSH    C                   3
+     D Z_FINISH        C                   4
+     D Z_BLOCK         C                   5
+     D Z_TREES         C                   6
+      *
+     D Z_OK            C                   0
+     D Z_STREAM_END    C                   1
+     D Z_NEED_DICT     C                   2
+     D Z_ERRNO         C                   -1
+     D Z_STREAM_ERROR  C                   -2
+     D Z_DATA_ERROR    C                   -3
+     D Z_MEM_ERROR     C                   -4
+     D Z_BUF_ERROR     C                   -5
+     DZ_VERSION_ERROR  C                   -6
+      *
+     D Z_NO_COMPRESSION...
+     D                 C                   0
+     D Z_BEST_SPEED    C                   1
+     D Z_BEST_COMPRESSION...
+     D                 C                   9
+     D Z_DEFAULT_COMPRESSION...
+     D                 C                   -1
+      *
+     D Z_FILTERED      C                   1
+     D Z_HUFFMAN_ONLY  C                   2
+     D Z_RLE           C                   3
+     D Z_DEFAULT_STRATEGY...
+     D                 C                   0
+      *
+     D Z_BINARY        C                   0
+     D Z_ASCII         C                   1
+     D Z_UNKNOWN       C                   2
+      *
+     D Z_DEFLATED      C                   8
+      *
+     D Z_NULL          C                   0
+      *
+      **************************************************************************
+      *                                 Types
+      **************************************************************************
+      *
+     D z_streamp       S               *                                        Stream struct ptr
+     D gzFile          S               *                                        File pointer
+     D z_off_t         S             10i 0                                      Stream offsets
+     D z_off64_t       S             20i 0                                      Stream offsets
+      *
+      **************************************************************************
+      *                               Structures
+      **************************************************************************
+      *
+      *  The GZIP encode/decode stream support structure.
+      *
+     D z_stream        DS                  align based(z_streamp)
+     D  zs_next_in                     *                                        Next input byte
+     D  zs_avail_in                  10U 0                                      Byte cnt at next_in
+     D  zs_total_in                  10U 0                                      Total bytes read
+     D  zs_next_out                    *                                        Output buffer ptr
+     D  zs_avail_out                 10U 0                                      Room left @ next_out
+     D  zs_total_out                 10U 0                                      Total bytes written
+     D  zs_msg                         *                                        Last errmsg or null
+     D  zs_state                       *                                        Internal state
+     D  zs_zalloc                      *   procptr                              Int. state allocator
+     D  zs_free                        *   procptr                              Int. state dealloc.
+     D  zs_opaque                      *                                        Private alloc. data
+     D  zs_data_type                 10i 0                                      ASC/BIN best guess
+     D  zs_adler                     10u 0                                      Uncompr. adler32 val
+     D                               10U 0                                      Reserved
+     D                               10U 0                                      Ptr. alignment
+      *
+      **************************************************************************
+      *                     Utility function prototypes
+      **************************************************************************
+      *
+     D compress        PR            10I 0 extproc('compress')
+     D  dest                      65535    options(*varsize)                    Destination buffer
+     D  destLen                      10U 0                                      Destination length
+     D  source                    65535    const options(*varsize)              Source buffer
+     D  sourceLen                    10u 0 value                                Source length
+      *
+     D compress2       PR            10I 0 extproc('compress2')
+     D  dest                      65535    options(*varsize)                    Destination buffer
+     D  destLen                      10U 0                                      Destination length
+     D  source                    65535    const options(*varsize)              Source buffer
+     D  sourceLen                    10U 0 value                                Source length
+     D  level                        10I 0 value                                Compression level
+      *
+     D compressBound   PR            10U 0 extproc('compressBound')
+     D  sourceLen                    10U 0 value
+      *
+     D uncompress      PR            10I 0 extproc('uncompress')
+     D  dest                      65535    options(*varsize)                    Destination buffer
+     D  destLen                      10U 0                                      Destination length
+     D  source                    65535    const options(*varsize)              Source buffer
+     D  sourceLen                    10U 0 value                                Source length
+      *
+      /if not defined(LARGE_FILES)
+     D gzopen          PR                  extproc('gzopen')
+     D                                     like(gzFile)
+     D  path                           *   value options(*string)               File pathname
+     D  mode                           *   value options(*string)               Open mode
+      /else
+     D gzopen          PR                  extproc('gzopen64')
+     D                                     like(gzFile)
+     D  path                           *   value options(*string)               File pathname
+     D  mode                           *   value options(*string)               Open mode
+      *
+     D gzopen64        PR                  extproc('gzopen64')
+     D                                     like(gzFile)
+     D  path                           *   value options(*string)               File pathname
+     D  mode                           *   value options(*string)               Open mode
+      /endif
+      *
+     D gzdopen         PR                  extproc('gzdopen')
+     D                                     like(gzFile)
+     D  fd                           10I 0 value                                File descriptor
+     D  mode                           *   value options(*string)               Open mode
+      *
+     D gzbuffer        PR            10I 0 extproc('gzbuffer')
+     D  file                               value like(gzFile)                   File pointer
+     D  size                         10U 0 value
+      *
+     D gzsetparams     PR            10I 0 extproc('gzsetparams')
+     D  file                               value like(gzFile)                   File pointer
+     D  level                        10I 0 value
+     D  strategy                     10I 0 value
+      *
+     D gzread          PR            10I 0 extproc('gzread')
+     D  file                               value like(gzFile)                   File pointer
+     D  buf                       65535    options(*varsize)                    Buffer
+     D  len                          10u 0 value                                Buffer length
+      *
+     D gzwrite         PR            10I 0 extproc('gzwrite')
+     D  file                               value like(gzFile)                   File pointer
+     D  buf                       65535    const options(*varsize)              Buffer
+     D  len                          10u 0 value                                Buffer length
+      *
+     D gzputs          PR            10I 0 extproc('gzputs')
+     D  file                               value like(gzFile)                   File pointer
+     D  s                              *   value options(*string)               String to output
+      *
+     D gzgets          PR              *   extproc('gzgets')
+     D  file                               value like(gzFile)                   File pointer
+     D  buf                       65535    options(*varsize)                    Read buffer
+     D  len                          10i 0 value                                Buffer length
+      *
+     D gzputc          PR            10i 0 extproc('gzputc')
+     D  file                               value like(gzFile)                   File pointer
+     D  c                            10I 0 value                                Character to write
+      *
+     D gzgetc          PR            10i 0 extproc('gzgetc')
+     D  file                               value like(gzFile)                   File pointer
+      *
+     D gzgetc_         PR            10i 0 extproc('gzgetc_')
+     D  file                               value like(gzFile)                   File pointer
+      *
+     D gzungetc        PR            10i 0 extproc('gzungetc')
+     D  c                            10I 0 value                                Character to push
+     D  file                               value like(gzFile)                   File pointer
+      *
+     D gzflush         PR            10i 0 extproc('gzflush')
+     D  file                               value like(gzFile)                   File pointer
+     D  flush                        10I 0 value                                Type of flush
+      *
+      /if not defined(LARGE_FILES)
+     D gzseek          PR                  extproc('gzseek')
+     D                                     like(z_off_t)
+     D  file                               value like(gzFile)                   File pointer
+     D  offset                             value like(z_off_t)                  Offset
+     D  whence                       10i 0 value                                Origin
+      /else
+     D gzseek          PR                  extproc('gzseek64')
+     D                                     like(z_off_t)
+     D  file                               value like(gzFile)                   File pointer
+     D  offset                             value like(z_off_t)                  Offset
+     D  whence                       10i 0 value                                Origin
+      *
+     D gzseek64        PR                  extproc('gzseek64')
+     D                                     like(z_off64_t)
+     D  file                               value like(gzFile)                   File pointer
+     D  offset                             value like(z_off64_t)                Offset
+     D  whence                       10i 0 value                                Origin
+      /endif
+      *
+     D gzrewind        PR            10i 0 extproc('gzrewind')
+     D  file                               value like(gzFile)                   File pointer
+      *
+      /if not defined(LARGE_FILES)
+     D gztell          PR                  extproc('gztell')
+     D                                     like(z_off_t)
+     D  file                               value like(gzFile)                   File pointer
+      /else
+     D gztell          PR                  extproc('gztell64')
+     D                                     like(z_off_t)
+     D  file                               value like(gzFile)                   File pointer
+      *
+     D gztell64        PR                  extproc('gztell64')
+     D                                     like(z_off64_t)
+     D  file                               value like(gzFile)                   File pointer
+      /endif
+      *
+      /if not defined(LARGE_FILES)
+     D gzoffset        PR                  extproc('gzoffset')
+     D                                     like(z_off_t)
+     D  file                               value like(gzFile)                   File pointer
+      /else
+     D gzoffset        PR                  extproc('gzoffset64')
+     D                                     like(z_off_t)
+     D  file                               value like(gzFile)                   File pointer
+      *
+     D gzoffset64      PR                  extproc('gzoffset64')
+     D                                     like(z_off64_t)
+     D  file                               value like(gzFile)                   File pointer
+      /endif
+      *
+     D gzeof           PR            10i 0 extproc('gzeof')
+     D  file                               value like(gzFile)                   File pointer
+      *
+     D gzclose_r       PR            10i 0 extproc('gzclose_r')
+     D  file                               value like(gzFile)                   File pointer
+      *
+     D gzclose_w       PR            10i 0 extproc('gzclose_w')
+     D  file                               value like(gzFile)                   File pointer
+      *
+     D gzclose         PR            10i 0 extproc('gzclose')
+     D  file                               value like(gzFile)                   File pointer
+      *
+     D gzerror         PR              *   extproc('gzerror')                   Error string
+     D  file                               value like(gzFile)                   File pointer
+     D  errnum                       10I 0                                      Error code
+      *
+     D gzclearerr      PR                  extproc('gzclearerr')
+     D  file                               value like(gzFile)                   File pointer
+      *
+      **************************************************************************
+      *                        Basic function prototypes
+      **************************************************************************
+      *
+     D zlibVersion     PR              *   extproc('zlibVersion')               Version string
+      *
+     D deflateInit     PR            10I 0 extproc('deflateInit_')              Init. compression
+     D  strm                               like(z_stream)                       Compression stream
+     D  level                        10I 0 value                                Compression level
+     D  version                        *   value options(*string)               Version string
+     D  stream_size                  10i 0 value                                Stream struct. size
+      *
+     D deflate         PR            10I 0 extproc('deflate')                   Compress data
+     D  strm                               like(z_stream)                       Compression stream
+     D  flush                        10I 0 value                                Flush type required
+      *
+     D deflateEnd      PR            10I 0 extproc('deflateEnd')                Termin. compression
+     D  strm                               like(z_stream)                       Compression stream
+      *
+     D inflateInit     PR            10I 0 extproc('inflateInit_')              Init. expansion
+     D  strm                               like(z_stream)                       Expansion stream
+     D  version                        *   value options(*string)               Version string
+     D  stream_size                  10i 0 value                                Stream struct. size
+      *
+     D inflate         PR            10I 0 extproc('inflate')                   Expand data
+     D  strm                               like(z_stream)                       Expansion stream
+     D  flush                        10I 0 value                                Flush type required
+      *
+     D inflateEnd      PR            10I 0 extproc('inflateEnd')                Termin. expansion
+     D  strm                               like(z_stream)                       Expansion stream
+      *
+      **************************************************************************
+      *                        Advanced function prototypes
+      **************************************************************************
+      *
+     D deflateInit2    PR            10I 0 extproc('deflateInit2_')             Init. compression
+     D  strm                               like(z_stream)                       Compression stream
+     D  level                        10I 0 value                                Compression level
+     D  method                       10I 0 value                                Compression method
+     D  windowBits                   10I 0 value                                log2(window size)
+     D  memLevel                     10I 0 value                                Mem/cmpress tradeoff
+     D  strategy                     10I 0 value                                Compression stategy
+     D  version                        *   value options(*string)               Version string
+     D  stream_size                  10i 0 value                                Stream struct. size
+      *
+     D deflateSetDictionary...
+     D                 PR            10I 0 extproc('deflateSetDictionary')      Init. dictionary
+     D  strm                               like(z_stream)                       Compression stream
+     D  dictionary                65535    const options(*varsize)              Dictionary bytes
+     D  dictLength                   10U 0 value                                Dictionary length
+      *
+     D deflateCopy     PR            10I 0 extproc('deflateCopy')               Compress strm 2 strm
+     D  dest                               like(z_stream)                       Destination stream
+     D  source                             like(z_stream)                       Source stream
+      *
+     D deflateReset    PR            10I 0 extproc('deflateReset')              End and init. stream
+     D  strm                               like(z_stream)                       Compression stream
+      *
+     D deflateParams   PR            10I 0 extproc('deflateParams')             Change level & strat
+     D  strm                               like(z_stream)                       Compression stream
+     D  level                        10I 0 value                                Compression level
+     D  strategy                     10I 0 value                                Compression stategy
+      *
+     D deflateBound    PR            10U 0 extproc('deflateBound')              Change level & strat
+     D  strm                               like(z_stream)                       Compression stream
+     D  sourcelen                    10U 0 value                                Compression level
+      *
+     D deflatePending  PR            10I 0 extproc('deflatePending')            Change level & strat
+     D  strm                               like(z_stream)                       Compression stream
+     D  pending                      10U 0                                      Pending bytes
+     D  bits                         10I 0                                      Pending bits
+      *
+     D deflatePrime    PR            10I 0 extproc('deflatePrime')              Change level & strat
+     D  strm                               like(z_stream)                       Compression stream
+     D  bits                         10I 0 value                                # of bits to insert
+     D  value                        10I 0 value                                Bits to insert
+      *
+     D inflateInit2    PR            10I 0 extproc('inflateInit2_')             Init. expansion
+     D  strm                               like(z_stream)                       Expansion stream
+     D  windowBits                   10I 0 value                                log2(window size)
+     D  version                        *   value options(*string)               Version string
+     D  stream_size                  10i 0 value                                Stream struct. size
+      *
+     D inflateSetDictionary...
+     D                 PR            10I 0 extproc('inflateSetDictionary')      Init. dictionary
+     D  strm                               like(z_stream)                       Expansion stream
+     D  dictionary                65535    const options(*varsize)              Dictionary bytes
+     D  dictLength                   10U 0 value                                Dictionary length
+      *
+     D inflateGetDictionary...
+     D                 PR            10I 0 extproc('inflateGetDictionary')      Get dictionary
+     D  strm                               like(z_stream)                       Expansion stream
+     D  dictionary                65535    options(*varsize)                    Dictionary bytes
+     D  dictLength                   10U 0                                      Dictionary length
+      *
+     D inflateSync     PR            10I 0 extproc('inflateSync')               Sync. expansion
+     D  strm                               like(z_stream)                       Expansion stream
+      *
+     D inflateCopy     PR            10I 0 extproc('inflateCopy')
+     D  dest                               like(z_stream)                       Destination stream
+     D  source                             like(z_stream)                       Source stream
+      *
+     D inflateReset    PR            10I 0 extproc('inflateReset')              End and init. stream
+     D  strm                               like(z_stream)                       Expansion stream
+      *
+     D inflateReset2   PR            10I 0 extproc('inflateReset2')             End and init. stream
+     D  strm                               like(z_stream)                       Expansion stream
+     D  windowBits                   10I 0 value                                Log2(buffer size)
+      *
+     D inflatePrime    PR            10I 0 extproc('inflatePrime')              Insert bits
+     D  strm                               like(z_stream)                       Expansion stream
+     D  bits                         10I 0 value                                Bit count
+     D  value                        10I 0 value                                Bits to insert
+      *
+     D inflateMark     PR            10I 0 extproc('inflateMark')               Get inflate info
+     D  strm                               like(z_stream)                       Expansion stream
+      *
+     D inflateBackInit...
+     D                 PR            10I 0 extproc('inflateBackInit_')
+     D  strm                               like(z_stream)                       Expansion stream
+     D  windowBits                   10I 0 value                                Log2(buffer size)
+     D  window                    65535    options(*varsize)                    Buffer
+     D  version                        *   value options(*string)               Version string
+     D  stream_size                  10i 0 value                                Stream struct. size
+      *
+     D inflateBack     PR            10I 0 extproc('inflateBack')
+     D  strm                               like(z_stream)                       Expansion stream
+     D  in                             *   value procptr                        Input function
+     D  in_desc                        *   value                                Input descriptor
+     D  out                            *   value procptr                        Output function
+     D  out_desc                       *   value                                Output descriptor
+      *
+     D inflateBackEnd  PR            10I 0 extproc('inflateBackEnd')
+     D  strm                               like(z_stream)                       Expansion stream
+      *
+     D zlibCompileFlags...
+     D                 PR            10U 0 extproc('zlibCompileFlags')
+      *
+      **************************************************************************
+      *                        Checksum function prototypes
+      **************************************************************************
+      *
+     D adler32         PR            10U 0 extproc('adler32')                   New checksum
+     D  adler                        10U 0 value                                Old checksum
+     D  buf                       65535    const options(*varsize)              Bytes to accumulate
+     D  len                          10U 0 value                                Buffer length
+      *
+     D crc32           PR            10U 0 extproc('crc32')                     New checksum
+     D  crc                          10U 0 value                                Old checksum
+     D  buf                       65535    const options(*varsize)              Bytes to accumulate
+     D  len                          10U 0 value                                Buffer length
+      *
+      **************************************************************************
+      *                     Miscellaneous function prototypes
+      **************************************************************************
+      *
+     D zError          PR              *   extproc('zError')                    Error string
+     D  err                          10I 0 value                                Error code
+      *
+     D inflateSyncPoint...
+     D                 PR            10I 0 extproc('inflateSyncPoint')
+     D  strm                               like(z_stream)                       Expansion stream
+      *
+     D get_crc_table   PR              *   extproc('get_crc_table')             Ptr to ulongs
+      *
+     D inflateUndermine...
+     D                 PR            10I 0 extproc('inflateUndermine')
+     D  strm                               like(z_stream)                       Expansion stream
+     D  arg                          10I 0 value                                Error code
+      *
+     D inflateResetKeep...
+     D                 PR            10I 0 extproc('inflateResetKeep')          End and init. stream
+     D  strm                               like(z_stream)                       Expansion stream
+      *
+     D deflateResetKeep...
+     D                 PR            10I 0 extproc('deflateResetKeep')          End and init. stream
+     D  strm                               like(z_stream)                       Expansion stream
+      *
+      /endif
diff --git a/compat/zlib/compress.c b/compat/zlib/compress.c
new file mode 100644
index 0000000..6e97626
--- /dev/null
+++ b/compat/zlib/compress.c
@@ -0,0 +1,80 @@
+/* compress.c -- compress a memory buffer
+ * Copyright (C) 1995-2005 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id$ */
+
+#define ZLIB_INTERNAL
+#include "zlib.h"
+
+/* ===========================================================================
+     Compresses the source buffer into the destination buffer. The level
+   parameter has the same meaning as in deflateInit.  sourceLen is the byte
+   length of the source buffer. Upon entry, destLen is the total size of the
+   destination buffer, which must be at least 0.1% larger than sourceLen plus
+   12 bytes. Upon exit, destLen is the actual size of the compressed buffer.
+
+     compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
+   memory, Z_BUF_ERROR if there was not enough room in the output buffer,
+   Z_STREAM_ERROR if the level parameter is invalid.
+*/
+int ZEXPORT compress2 (dest, destLen, source, sourceLen, level)
+    Bytef *dest;
+    uLongf *destLen;
+    const Bytef *source;
+    uLong sourceLen;
+    int level;
+{
+    z_stream stream;
+    int err;
+
+    stream.next_in = (z_const Bytef *)source;
+    stream.avail_in = (uInt)sourceLen;
+#ifdef MAXSEG_64K
+    /* Check for source > 64K on 16-bit machine: */
+    if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR;
+#endif
+    stream.next_out = dest;
+    stream.avail_out = (uInt)*destLen;
+    if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR;
+
+    stream.zalloc = (alloc_func)0;
+    stream.zfree = (free_func)0;
+    stream.opaque = (voidpf)0;
+
+    err = deflateInit(&stream, level);
+    if (err != Z_OK) return err;
+
+    err = deflate(&stream, Z_FINISH);
+    if (err != Z_STREAM_END) {
+        deflateEnd(&stream);
+        return err == Z_OK ? Z_BUF_ERROR : err;
+    }
+    *destLen = stream.total_out;
+
+    err = deflateEnd(&stream);
+    return err;
+}
+
+/* ===========================================================================
+ */
+int ZEXPORT compress (dest, destLen, source, sourceLen)
+    Bytef *dest;
+    uLongf *destLen;
+    const Bytef *source;
+    uLong sourceLen;
+{
+    return compress2(dest, destLen, source, sourceLen, Z_DEFAULT_COMPRESSION);
+}
+
+/* ===========================================================================
+     If the default memLevel or windowBits for deflateInit() is changed, then
+   this function needs to be updated.
+ */
+uLong ZEXPORT compressBound (sourceLen)
+    uLong sourceLen;
+{
+    return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) +
+           (sourceLen >> 25) + 13;
+}
diff --git a/compat/zlib/configure b/compat/zlib/configure
new file mode 100755
index 0000000..b77a8a8
--- /dev/null
+++ b/compat/zlib/configure
@@ -0,0 +1,831 @@
+#!/bin/sh
+# configure script for zlib.
+#
+# Normally configure builds both a static and a shared library.
+# If you want to build just a static library, use: ./configure --static
+#
+# To impose specific compiler or flags or install directory, use for example:
+#    prefix=$HOME CC=cc CFLAGS="-O4" ./configure
+# or for csh/tcsh users:
+#    (setenv prefix $HOME; setenv CC cc; setenv CFLAGS "-O4"; ./configure)
+
+# Incorrect settings of CC or CFLAGS may prevent creating a shared library.
+# If you have problems, try without defining CC and CFLAGS before reporting
+# an error.
+
+# start off configure.log
+echo -------------------- >> configure.log
+echo $0 $* >> configure.log
+date >> configure.log
+
+# set command prefix for cross-compilation
+if [ -n "${CHOST}" ]; then
+    uname="`echo "${CHOST}" | sed -e 's/^[^-]*-\([^-]*\)$/\1/' -e 's/^[^-]*-[^-]*-\([^-]*\)$/\1/' -e 's/^[^-]*-[^-]*-\([^-]*\)-.*$/\1/'`"
+    CROSS_PREFIX="${CHOST}-"
+fi
+
+# destination name for static library
+STATICLIB=libz.a
+
+# extract zlib version numbers from zlib.h
+VER=`sed -n -e '/VERSION "/s/.*"\(.*\)".*/\1/p' < zlib.h`
+VER3=`sed -n -e '/VERSION "/s/.*"\([0-9]*\\.[0-9]*\\.[0-9]*\).*/\1/p' < zlib.h`
+VER2=`sed -n -e '/VERSION "/s/.*"\([0-9]*\\.[0-9]*\)\\..*/\1/p' < zlib.h`
+VER1=`sed -n -e '/VERSION "/s/.*"\([0-9]*\)\\..*/\1/p' < zlib.h`
+
+# establish commands for library building
+if "${CROSS_PREFIX}ar" --version >/dev/null 2>/dev/null || test $? -lt 126; then
+    AR=${AR-"${CROSS_PREFIX}ar"}
+    test -n "${CROSS_PREFIX}" && echo Using ${AR} | tee -a configure.log
+else
+    AR=${AR-"ar"}
+    test -n "${CROSS_PREFIX}" && echo Using ${AR} | tee -a configure.log
+fi
+ARFLAGS=${ARFLAGS-"rc"}
+if "${CROSS_PREFIX}ranlib" --version >/dev/null 2>/dev/null || test $? -lt 126; then
+    RANLIB=${RANLIB-"${CROSS_PREFIX}ranlib"}
+    test -n "${CROSS_PREFIX}" && echo Using ${RANLIB} | tee -a configure.log
+else
+    RANLIB=${RANLIB-"ranlib"}
+fi
+if "${CROSS_PREFIX}nm" --version >/dev/null 2>/dev/null || test $? -lt 126; then
+    NM=${NM-"${CROSS_PREFIX}nm"}
+    test -n "${CROSS_PREFIX}" && echo Using ${NM} | tee -a configure.log
+else
+    NM=${NM-"nm"}
+fi
+
+# set defaults before processing command line options
+LDCONFIG=${LDCONFIG-"ldconfig"}
+LDSHAREDLIBC="${LDSHAREDLIBC--lc}"
+ARCHS=
+prefix=${prefix-/usr/local}
+exec_prefix=${exec_prefix-'${prefix}'}
+libdir=${libdir-'${exec_prefix}/lib'}
+sharedlibdir=${sharedlibdir-'${libdir}'}
+includedir=${includedir-'${prefix}/include'}
+mandir=${mandir-'${prefix}/share/man'}
+shared_ext='.so'
+shared=1
+solo=0
+cover=0
+zprefix=0
+zconst=0
+build64=0
+gcc=0
+old_cc="$CC"
+old_cflags="$CFLAGS"
+OBJC='$(OBJZ) $(OBJG)'
+PIC_OBJC='$(PIC_OBJZ) $(PIC_OBJG)'
+
+# leave this script, optionally in a bad way
+leave()
+{
+  if test "$*" != "0"; then
+    echo "** $0 aborting." | tee -a configure.log
+  fi
+  rm -f $test.[co] $test $test$shared_ext $test.gcno ./--version
+  echo -------------------- >> configure.log
+  echo >> configure.log
+  echo >> configure.log
+  exit $1
+}
+
+# process command line options
+while test $# -ge 1
+do
+case "$1" in
+    -h* | --help)
+      echo 'usage:' | tee -a configure.log
+      echo '  configure [--const] [--zprefix] [--prefix=PREFIX]  [--eprefix=EXPREFIX]' | tee -a configure.log
+      echo '    [--static] [--64] [--libdir=LIBDIR] [--sharedlibdir=LIBDIR]' | tee -a configure.log
+      echo '    [--includedir=INCLUDEDIR] [--archs="-arch i386 -arch x86_64"]' | tee -a configure.log
+        exit 0 ;;
+    -p*=* | --prefix=*) prefix=`echo $1 | sed 's/.*=//'`; shift ;;
+    -e*=* | --eprefix=*) exec_prefix=`echo $1 | sed 's/.*=//'`; shift ;;
+    -l*=* | --libdir=*) libdir=`echo $1 | sed 's/.*=//'`; shift ;;
+    --sharedlibdir=*) sharedlibdir=`echo $1 | sed 's/.*=//'`; shift ;;
+    -i*=* | --includedir=*) includedir=`echo $1 | sed 's/.*=//'`;shift ;;
+    -u*=* | --uname=*) uname=`echo $1 | sed 's/.*=//'`;shift ;;
+    -p* | --prefix) prefix="$2"; shift; shift ;;
+    -e* | --eprefix) exec_prefix="$2"; shift; shift ;;
+    -l* | --libdir) libdir="$2"; shift; shift ;;
+    -i* | --includedir) includedir="$2"; shift; shift ;;
+    -s* | --shared | --enable-shared) shared=1; shift ;;
+    -t | --static) shared=0; shift ;;
+    --solo) solo=1; shift ;;
+    --cover) cover=1; shift ;;
+    -z* | --zprefix) zprefix=1; shift ;;
+    -6* | --64) build64=1; shift ;;
+    -a*=* | --archs=*) ARCHS=`echo $1 | sed 's/.*=//'`; shift ;;
+    --sysconfdir=*) echo "ignored option: --sysconfdir" | tee -a configure.log; shift ;;
+    --localstatedir=*) echo "ignored option: --localstatedir" | tee -a configure.log; shift ;;
+    -c* | --const) zconst=1; shift ;;
+    *)
+      echo "unknown option: $1" | tee -a configure.log
+      echo "$0 --help for help" | tee -a configure.log
+      leave 1;;
+    esac
+done
+
+# temporary file name
+test=ztest$$
+
+# put arguments in log, also put test file in log if used in arguments
+show()
+{
+  case "$*" in
+    *$test.c*)
+      echo === $test.c === >> configure.log
+      cat $test.c >> configure.log
+      echo === >> configure.log;;
+  esac
+  echo $* >> configure.log
+}
+
+# check for gcc vs. cc and set compile and link flags based on the system identified by uname
+cat > $test.c <<EOF
+extern int getchar();
+int hello() {return getchar();}
+EOF
+
+test -z "$CC" && echo Checking for ${CROSS_PREFIX}gcc... | tee -a configure.log
+cc=${CC-${CROSS_PREFIX}gcc}
+cflags=${CFLAGS-"-O3"}
+# to force the asm version use: CFLAGS="-O3 -DASMV" ./configure
+case "$cc" in
+  *gcc*) gcc=1 ;;
+  *clang*) gcc=1 ;;
+esac
+case `$cc -v 2>&1` in
+  *gcc*) gcc=1 ;;
+esac
+
+show $cc -c $test.c
+if test "$gcc" -eq 1 && ($cc -c $test.c) >> configure.log 2>&1; then
+  echo ... using gcc >> configure.log
+  CC="$cc"
+  CFLAGS="${CFLAGS--O3} ${ARCHS}"
+  SFLAGS="${CFLAGS--O3} -fPIC"
+  LDFLAGS="${LDFLAGS} ${ARCHS}"
+  if test $build64 -eq 1; then
+    CFLAGS="${CFLAGS} -m64"
+    SFLAGS="${SFLAGS} -m64"
+  fi
+  if test "${ZLIBGCCWARN}" = "YES"; then
+    if test "$zconst" -eq 1; then
+      CFLAGS="${CFLAGS} -Wall -Wextra -Wcast-qual -pedantic -DZLIB_CONST"
+    else
+      CFLAGS="${CFLAGS} -Wall -Wextra -pedantic"
+    fi
+  fi
+  if test -z "$uname"; then
+    uname=`(uname -s || echo unknown) 2>/dev/null`
+  fi
+  case "$uname" in
+  Linux* | linux* | GNU | GNU/* | solaris*)
+        LDSHARED=${LDSHARED-"$cc -shared -Wl,-soname,libz.so.1,--version-script,zlib.map"} ;;
+  *BSD | *bsd* | DragonFly)
+        LDSHARED=${LDSHARED-"$cc -shared -Wl,-soname,libz.so.1,--version-script,zlib.map"}
+        LDCONFIG="ldconfig -m" ;;
+  CYGWIN* | Cygwin* | cygwin* | OS/2*)
+        EXE='.exe' ;;
+  MINGW* | mingw*)
+# temporary bypass
+        rm -f $test.[co] $test $test$shared_ext
+        echo "Please use win32/Makefile.gcc instead." | tee -a configure.log
+        leave 1
+        LDSHARED=${LDSHARED-"$cc -shared"}
+        LDSHAREDLIBC=""
+        EXE='.exe' ;;
+  QNX*)  # This is for QNX6. I suppose that the QNX rule below is for QNX2,QNX4
+         # (alain.bonnefoy@icbt.com)
+                 LDSHARED=${LDSHARED-"$cc -shared -Wl,-hlibz.so.1"} ;;
+  HP-UX*)
+         LDSHARED=${LDSHARED-"$cc -shared $SFLAGS"}
+         case `(uname -m || echo unknown) 2>/dev/null` in
+         ia64)
+                 shared_ext='.so'
+                 SHAREDLIB='libz.so' ;;
+         *)
+                 shared_ext='.sl'
+                 SHAREDLIB='libz.sl' ;;
+         esac ;;
+  Darwin* | darwin*)
+             shared_ext='.dylib'
+             SHAREDLIB=libz$shared_ext
+             SHAREDLIBV=libz.$VER$shared_ext
+             SHAREDLIBM=libz.$VER1$shared_ext
+             LDSHARED=${LDSHARED-"$cc -dynamiclib -install_name $libdir/$SHAREDLIBM -compatibility_version $VER1 -current_version $VER3"}
+             if libtool -V 2>&1 | grep Apple > /dev/null; then
+                 AR="libtool"
+             else
+                 AR="/usr/bin/libtool"
+             fi
+             ARFLAGS="-o" ;;
+  *)             LDSHARED=${LDSHARED-"$cc -shared"} ;;
+  esac
+else
+  # find system name and corresponding cc options
+  CC=${CC-cc}
+  gcc=0
+  echo ... using $CC >> configure.log
+  if test -z "$uname"; then
+    uname=`(uname -sr || echo unknown) 2>/dev/null`
+  fi
+  case "$uname" in
+  HP-UX*)    SFLAGS=${CFLAGS-"-O +z"}
+             CFLAGS=${CFLAGS-"-O"}
+#            LDSHARED=${LDSHARED-"ld -b +vnocompatwarnings"}
+             LDSHARED=${LDSHARED-"ld -b"}
+         case `(uname -m || echo unknown) 2>/dev/null` in
+         ia64)
+             shared_ext='.so'
+             SHAREDLIB='libz.so' ;;
+         *)
+             shared_ext='.sl'
+             SHAREDLIB='libz.sl' ;;
+         esac ;;
+  IRIX*)     SFLAGS=${CFLAGS-"-ansi -O2 -rpath ."}
+             CFLAGS=${CFLAGS-"-ansi -O2"}
+             LDSHARED=${LDSHARED-"cc -shared -Wl,-soname,libz.so.1"} ;;
+  OSF1\ V4*) SFLAGS=${CFLAGS-"-O -std1"}
+             CFLAGS=${CFLAGS-"-O -std1"}
+             LDFLAGS="${LDFLAGS} -Wl,-rpath,."
+             LDSHARED=${LDSHARED-"cc -shared  -Wl,-soname,libz.so -Wl,-msym -Wl,-rpath,$(libdir) -Wl,-set_version,${VER}:1.0"} ;;
+  OSF1*)     SFLAGS=${CFLAGS-"-O -std1"}
+             CFLAGS=${CFLAGS-"-O -std1"}
+             LDSHARED=${LDSHARED-"cc -shared -Wl,-soname,libz.so.1"} ;;
+  QNX*)      SFLAGS=${CFLAGS-"-4 -O"}
+             CFLAGS=${CFLAGS-"-4 -O"}
+             LDSHARED=${LDSHARED-"cc"}
+             RANLIB=${RANLIB-"true"}
+             AR="cc"
+             ARFLAGS="-A" ;;
+  SCO_SV\ 3.2*) SFLAGS=${CFLAGS-"-O3 -dy -KPIC "}
+             CFLAGS=${CFLAGS-"-O3"}
+             LDSHARED=${LDSHARED-"cc -dy -KPIC -G"} ;;
+  SunOS\ 5* | solaris*)
+         LDSHARED=${LDSHARED-"cc -G -h libz$shared_ext.$VER1"}
+         SFLAGS=${CFLAGS-"-fast -KPIC"}
+         CFLAGS=${CFLAGS-"-fast"}
+         if test $build64 -eq 1; then
+             # old versions of SunPRO/Workshop/Studio don't support -m64,
+             # but newer ones do.  Check for it.
+             flag64=`$CC -flags | egrep -- '^-m64'`
+             if test x"$flag64" != x"" ; then
+                 CFLAGS="${CFLAGS} -m64"
+                 SFLAGS="${SFLAGS} -m64"
+             else
+                 case `(uname -m || echo unknown) 2>/dev/null` in
+                   i86*)
+                     SFLAGS="$SFLAGS -xarch=amd64"
+                     CFLAGS="$CFLAGS -xarch=amd64" ;;
+                   *)
+                     SFLAGS="$SFLAGS -xarch=v9"
+                     CFLAGS="$CFLAGS -xarch=v9" ;;
+                 esac
+             fi
+         fi
+         ;;
+  SunOS\ 4*) SFLAGS=${CFLAGS-"-O2 -PIC"}
+             CFLAGS=${CFLAGS-"-O2"}
+             LDSHARED=${LDSHARED-"ld"} ;;
+  SunStudio\ 9*) SFLAGS=${CFLAGS-"-fast -xcode=pic32 -xtarget=ultra3 -xarch=v9b"}
+             CFLAGS=${CFLAGS-"-fast -xtarget=ultra3 -xarch=v9b"}
+             LDSHARED=${LDSHARED-"cc -xarch=v9b"} ;;
+  UNIX_System_V\ 4.2.0)
+             SFLAGS=${CFLAGS-"-KPIC -O"}
+             CFLAGS=${CFLAGS-"-O"}
+             LDSHARED=${LDSHARED-"cc -G"} ;;
+  UNIX_SV\ 4.2MP)
+             SFLAGS=${CFLAGS-"-Kconform_pic -O"}
+             CFLAGS=${CFLAGS-"-O"}
+             LDSHARED=${LDSHARED-"cc -G"} ;;
+  OpenUNIX\ 5)
+             SFLAGS=${CFLAGS-"-KPIC -O"}
+             CFLAGS=${CFLAGS-"-O"}
+             LDSHARED=${LDSHARED-"cc -G"} ;;
+  AIX*)  # Courtesy of dbakker@arrayasolutions.com
+             SFLAGS=${CFLAGS-"-O -qmaxmem=8192"}
+             CFLAGS=${CFLAGS-"-O -qmaxmem=8192"}
+             LDSHARED=${LDSHARED-"xlc -G"} ;;
+  # send working options for other systems to zlib@gzip.org
+  *)         SFLAGS=${CFLAGS-"-O"}
+             CFLAGS=${CFLAGS-"-O"}
+             LDSHARED=${LDSHARED-"cc -shared"} ;;
+  esac
+fi
+
+# destination names for shared library if not defined above
+SHAREDLIB=${SHAREDLIB-"libz$shared_ext"}
+SHAREDLIBV=${SHAREDLIBV-"libz$shared_ext.$VER"}
+SHAREDLIBM=${SHAREDLIBM-"libz$shared_ext.$VER1"}
+
+echo >> configure.log
+
+# define functions for testing compiler and library characteristics and logging the results
+
+cat > $test.c <<EOF
+#error error
+EOF
+if ($CC -c $CFLAGS $test.c) 2>/dev/null; then
+  try()
+  {
+    show $*
+    test "`( $* ) 2>&1 | tee -a configure.log`" = ""
+  }
+  echo - using any output from compiler to indicate an error >> configure.log
+else
+try()
+{
+  show $*
+  ( $* ) >> configure.log 2>&1
+  ret=$?
+  if test $ret -ne 0; then
+    echo "(exit code "$ret")" >> configure.log
+  fi
+  return $ret
+}
+fi
+
+tryboth()
+{
+  show $*
+  got=`( $* ) 2>&1`
+  ret=$?
+  printf %s "$got" >> configure.log
+  if test $ret -ne 0; then
+    return $ret
+  fi
+  test "$got" = ""
+}
+
+cat > $test.c << EOF
+int foo() { return 0; }
+EOF
+echo "Checking for obsessive-compulsive compiler options..." >> configure.log
+if try $CC -c $CFLAGS $test.c; then
+  :
+else
+  echo "Compiler error reporting is too harsh for $0 (perhaps remove -Werror)." | tee -a configure.log
+  leave 1
+fi
+
+echo >> configure.log
+
+# see if shared library build supported
+cat > $test.c <<EOF
+extern int getchar();
+int hello() {return getchar();}
+EOF
+if test $shared -eq 1; then
+  echo Checking for shared library support... | tee -a configure.log
+  # we must test in two steps (cc then ld), required at least on SunOS 4.x
+  if try $CC -w -c $SFLAGS $test.c &&
+     try $LDSHARED $SFLAGS -o $test$shared_ext $test.o; then
+    echo Building shared library $SHAREDLIBV with $CC. | tee -a configure.log
+  elif test -z "$old_cc" -a -z "$old_cflags"; then
+    echo No shared library support. | tee -a configure.log
+    shared=0;
+  else
+    echo 'No shared library support; try without defining CC and CFLAGS' | tee -a configure.log
+    shared=0;
+  fi
+fi
+if test $shared -eq 0; then
+  LDSHARED="$CC"
+  ALL="static"
+  TEST="all teststatic"
+  SHAREDLIB=""
+  SHAREDLIBV=""
+  SHAREDLIBM=""
+  echo Building static library $STATICLIB version $VER with $CC. | tee -a configure.log
+else
+  ALL="static shared"
+  TEST="all teststatic testshared"
+fi
+
+# check for underscores in external names for use by assembler code
+CPP=${CPP-"$CC -E"}
+case $CFLAGS in
+  *ASMV*)
+    echo >> configure.log
+    show "$NM $test.o | grep _hello"
+    if test "`$NM $test.o | grep _hello | tee -a configure.log`" = ""; then
+      CPP="$CPP -DNO_UNDERLINE"
+      echo Checking for underline in external names... No. | tee -a configure.log
+    else
+      echo Checking for underline in external names... Yes. | tee -a configure.log
+    fi ;;
+esac
+
+echo >> configure.log
+
+# check for large file support, and if none, check for fseeko()
+cat > $test.c <<EOF
+#include <sys/types.h>
+off64_t dummy = 0;
+EOF
+if try $CC -c $CFLAGS -D_LARGEFILE64_SOURCE=1 $test.c; then
+  CFLAGS="${CFLAGS} -D_LARGEFILE64_SOURCE=1"
+  SFLAGS="${SFLAGS} -D_LARGEFILE64_SOURCE=1"
+  ALL="${ALL} all64"
+  TEST="${TEST} test64"
+  echo "Checking for off64_t... Yes." | tee -a configure.log
+  echo "Checking for fseeko... Yes." | tee -a configure.log
+else
+  echo "Checking for off64_t... No." | tee -a configure.log
+  echo >> configure.log
+  cat > $test.c <<EOF
+#include <stdio.h>
+int main(void) {
+  fseeko(NULL, 0, 0);
+  return 0;
+}
+EOF
+  if try $CC $CFLAGS -o $test $test.c; then
+    echo "Checking for fseeko... Yes." | tee -a configure.log
+  else
+    CFLAGS="${CFLAGS} -DNO_FSEEKO"
+    SFLAGS="${SFLAGS} -DNO_FSEEKO"
+    echo "Checking for fseeko... No." | tee -a configure.log
+  fi
+fi
+
+echo >> configure.log
+
+# check for strerror() for use by gz* functions
+cat > $test.c <<EOF
+#include <string.h>
+#include <errno.h>
+int main() { return strlen(strerror(errno)); }
+EOF
+if try $CC $CFLAGS -o $test $test.c; then
+  echo "Checking for strerror... Yes." | tee -a configure.log
+else
+  CFLAGS="${CFLAGS} -DNO_STRERROR"
+  SFLAGS="${SFLAGS} -DNO_STRERROR"
+  echo "Checking for strerror... No." | tee -a configure.log
+fi
+
+# copy clean zconf.h for subsequent edits
+cp -p zconf.h.in zconf.h
+
+echo >> configure.log
+
+# check for unistd.h and save result in zconf.h
+cat > $test.c <<EOF
+#include <unistd.h>
+int main() { return 0; }
+EOF
+if try $CC -c $CFLAGS $test.c; then
+  sed < zconf.h "/^#ifdef HAVE_UNISTD_H.* may be/s/def HAVE_UNISTD_H\(.*\) may be/ 1\1 was/" > zconf.temp.h
+  mv zconf.temp.h zconf.h
+  echo "Checking for unistd.h... Yes." | tee -a configure.log
+else
+  echo "Checking for unistd.h... No." | tee -a configure.log
+fi
+
+echo >> configure.log
+
+# check for stdarg.h and save result in zconf.h
+cat > $test.c <<EOF
+#include <stdarg.h>
+int main() { return 0; }
+EOF
+if try $CC -c $CFLAGS $test.c; then
+  sed < zconf.h "/^#ifdef HAVE_STDARG_H.* may be/s/def HAVE_STDARG_H\(.*\) may be/ 1\1 was/" > zconf.temp.h
+  mv zconf.temp.h zconf.h
+  echo "Checking for stdarg.h... Yes." | tee -a configure.log
+else
+  echo "Checking for stdarg.h... No." | tee -a configure.log
+fi
+
+# if the z_ prefix was requested, save that in zconf.h
+if test $zprefix -eq 1; then
+  sed < zconf.h "/#ifdef Z_PREFIX.* may be/s/def Z_PREFIX\(.*\) may be/ 1\1 was/" > zconf.temp.h
+  mv zconf.temp.h zconf.h
+  echo >> configure.log
+  echo "Using z_ prefix on all symbols." | tee -a configure.log
+fi
+
+# if --solo compilation was requested, save that in zconf.h and remove gz stuff from object lists
+if test $solo -eq 1; then
+  sed '/#define ZCONF_H/a\
+#define Z_SOLO
+
+' < zconf.h > zconf.temp.h
+  mv zconf.temp.h zconf.h
+OBJC='$(OBJZ)'
+PIC_OBJC='$(PIC_OBJZ)'
+fi
+
+# if code coverage testing was requested, use older gcc if defined, e.g. "gcc-4.2" on Mac OS X
+if test $cover -eq 1; then
+  CFLAGS="${CFLAGS} -fprofile-arcs -ftest-coverage"
+  if test -n "$GCC_CLASSIC"; then
+    CC=$GCC_CLASSIC
+  fi
+fi
+
+echo >> configure.log
+
+# conduct a series of tests to resolve eight possible cases of using "vs" or "s" printf functions
+# (using stdarg or not), with or without "n" (proving size of buffer), and with or without a
+# return value.  The most secure result is vsnprintf() with a return value.  snprintf() with a
+# return value is secure as well, but then gzprintf() will be limited to 20 arguments.
+cat > $test.c <<EOF
+#include <stdio.h>
+#include <stdarg.h>
+#include "zconf.h"
+int main()
+{
+#ifndef STDC
+  choke me
+#endif
+  return 0;
+}
+EOF
+if try $CC -c $CFLAGS $test.c; then
+  echo "Checking whether to use vs[n]printf() or s[n]printf()... using vs[n]printf()." | tee -a configure.log
+
+  echo >> configure.log
+  cat > $test.c <<EOF
+#include <stdio.h>
+#include <stdarg.h>
+int mytest(const char *fmt, ...)
+{
+  char buf[20];
+  va_list ap;
+  va_start(ap, fmt);
+  vsnprintf(buf, sizeof(buf), fmt, ap);
+  va_end(ap);
+  return 0;
+}
+int main()
+{
+  return (mytest("Hello%d\n", 1));
+}
+EOF
+  if try $CC $CFLAGS -o $test $test.c; then
+    echo "Checking for vsnprintf() in stdio.h... Yes." | tee -a configure.log
+
+    echo >> configure.log
+    cat >$test.c <<EOF
+#include <stdio.h>
+#include <stdarg.h>
+int mytest(const char *fmt, ...)
+{
+  int n;
+  char buf[20];
+  va_list ap;
+  va_start(ap, fmt);
+  n = vsnprintf(buf, sizeof(buf), fmt, ap);
+  va_end(ap);
+  return n;
+}
+int main()
+{
+  return (mytest("Hello%d\n", 1));
+}
+EOF
+
+    if try $CC -c $CFLAGS $test.c; then
+      echo "Checking for return value of vsnprintf()... Yes." | tee -a configure.log
+    else
+      CFLAGS="$CFLAGS -DHAS_vsnprintf_void"
+      SFLAGS="$SFLAGS -DHAS_vsnprintf_void"
+      echo "Checking for return value of vsnprintf()... No." | tee -a configure.log
+      echo "  WARNING: apparently vsnprintf() does not return a value. zlib" | tee -a configure.log
+      echo "  can build but will be open to possible string-format security" | tee -a configure.log
+      echo "  vulnerabilities." | tee -a configure.log
+    fi
+  else
+    CFLAGS="$CFLAGS -DNO_vsnprintf"
+    SFLAGS="$SFLAGS -DNO_vsnprintf"
+    echo "Checking for vsnprintf() in stdio.h... No." | tee -a configure.log
+    echo "  WARNING: vsnprintf() not found, falling back to vsprintf(). zlib" | tee -a configure.log
+    echo "  can build but will be open to possible buffer-overflow security" | tee -a configure.log
+    echo "  vulnerabilities." | tee -a configure.log
+
+    echo >> configure.log
+    cat >$test.c <<EOF
+#include <stdio.h>
+#include <stdarg.h>
+int mytest(const char *fmt, ...)
+{
+  int n;
+  char buf[20];
+  va_list ap;
+  va_start(ap, fmt);
+  n = vsprintf(buf, fmt, ap);
+  va_end(ap);
+  return n;
+}
+int main()
+{
+  return (mytest("Hello%d\n", 1));
+}
+EOF
+
+    if try $CC -c $CFLAGS $test.c; then
+      echo "Checking for return value of vsprintf()... Yes." | tee -a configure.log
+    else
+      CFLAGS="$CFLAGS -DHAS_vsprintf_void"
+      SFLAGS="$SFLAGS -DHAS_vsprintf_void"
+      echo "Checking for return value of vsprintf()... No." | tee -a configure.log
+      echo "  WARNING: apparently vsprintf() does not return a value. zlib" | tee -a configure.log
+      echo "  can build but will be open to possible string-format security" | tee -a configure.log
+      echo "  vulnerabilities." | tee -a configure.log
+    fi
+  fi
+else
+  echo "Checking whether to use vs[n]printf() or s[n]printf()... using s[n]printf()." | tee -a configure.log
+
+  echo >> configure.log
+  cat >$test.c <<EOF
+#include <stdio.h>
+int mytest()
+{
+  char buf[20];
+  snprintf(buf, sizeof(buf), "%s", "foo");
+  return 0;
+}
+int main()
+{
+  return (mytest());
+}
+EOF
+
+  if try $CC $CFLAGS -o $test $test.c; then
+    echo "Checking for snprintf() in stdio.h... Yes." | tee -a configure.log
+
+    echo >> configure.log
+    cat >$test.c <<EOF
+#include <stdio.h>
+int mytest()
+{
+  char buf[20];
+  return snprintf(buf, sizeof(buf), "%s", "foo");
+}
+int main()
+{
+  return (mytest());
+}
+EOF
+
+    if try $CC -c $CFLAGS $test.c; then
+      echo "Checking for return value of snprintf()... Yes." | tee -a configure.log
+    else
+      CFLAGS="$CFLAGS -DHAS_snprintf_void"
+      SFLAGS="$SFLAGS -DHAS_snprintf_void"
+      echo "Checking for return value of snprintf()... No." | tee -a configure.log
+      echo "  WARNING: apparently snprintf() does not return a value. zlib" | tee -a configure.log
+      echo "  can build but will be open to possible string-format security" | tee -a configure.log
+      echo "  vulnerabilities." | tee -a configure.log
+    fi
+  else
+    CFLAGS="$CFLAGS -DNO_snprintf"
+    SFLAGS="$SFLAGS -DNO_snprintf"
+    echo "Checking for snprintf() in stdio.h... No." | tee -a configure.log
+    echo "  WARNING: snprintf() not found, falling back to sprintf(). zlib" | tee -a configure.log
+    echo "  can build but will be open to possible buffer-overflow security" | tee -a configure.log
+    echo "  vulnerabilities." | tee -a configure.log
+
+    echo >> configure.log
+    cat >$test.c <<EOF
+#include <stdio.h>
+int mytest()
+{
+  char buf[20];
+  return sprintf(buf, "%s", "foo");
+}
+int main()
+{
+  return (mytest());
+}
+EOF
+
+    if try $CC -c $CFLAGS $test.c; then
+      echo "Checking for return value of sprintf()... Yes." | tee -a configure.log
+    else
+      CFLAGS="$CFLAGS -DHAS_sprintf_void"
+      SFLAGS="$SFLAGS -DHAS_sprintf_void"
+      echo "Checking for return value of sprintf()... No." | tee -a configure.log
+      echo "  WARNING: apparently sprintf() does not return a value. zlib" | tee -a configure.log
+      echo "  can build but will be open to possible string-format security" | tee -a configure.log
+      echo "  vulnerabilities." | tee -a configure.log
+    fi
+  fi
+fi
+
+# see if we can hide zlib internal symbols that are linked between separate source files
+if test "$gcc" -eq 1; then
+  echo >> configure.log
+  cat > $test.c <<EOF
+#define ZLIB_INTERNAL __attribute__((visibility ("hidden")))
+int ZLIB_INTERNAL foo;
+int main()
+{
+  return 0;
+}
+EOF
+  if tryboth $CC -c $CFLAGS $test.c; then
+    CFLAGS="$CFLAGS -DHAVE_HIDDEN"
+    SFLAGS="$SFLAGS -DHAVE_HIDDEN"
+    echo "Checking for attribute(visibility) support... Yes." | tee -a configure.log
+  else
+    echo "Checking for attribute(visibility) support... No." | tee -a configure.log
+  fi
+fi
+
+# show the results in the log
+echo >> configure.log
+echo ALL = $ALL >> configure.log
+echo AR = $AR >> configure.log
+echo ARFLAGS = $ARFLAGS >> configure.log
+echo CC = $CC >> configure.log
+echo CFLAGS = $CFLAGS >> configure.log
+echo CPP = $CPP >> configure.log
+echo EXE = $EXE >> configure.log
+echo LDCONFIG = $LDCONFIG >> configure.log
+echo LDFLAGS = $LDFLAGS >> configure.log
+echo LDSHARED = $LDSHARED >> configure.log
+echo LDSHAREDLIBC = $LDSHAREDLIBC >> configure.log
+echo OBJC = $OBJC >> configure.log
+echo PIC_OBJC = $PIC_OBJC >> configure.log
+echo RANLIB = $RANLIB >> configure.log
+echo SFLAGS = $SFLAGS >> configure.log
+echo SHAREDLIB = $SHAREDLIB >> configure.log
+echo SHAREDLIBM = $SHAREDLIBM >> configure.log
+echo SHAREDLIBV = $SHAREDLIBV >> configure.log
+echo STATICLIB = $STATICLIB >> configure.log
+echo TEST = $TEST >> configure.log
+echo VER = $VER >> configure.log
+echo Z_U4 = $Z_U4 >> configure.log
+echo exec_prefix = $exec_prefix >> configure.log
+echo includedir = $includedir >> configure.log
+echo libdir = $libdir >> configure.log
+echo mandir = $mandir >> configure.log
+echo prefix = $prefix >> configure.log
+echo sharedlibdir = $sharedlibdir >> configure.log
+echo uname = $uname >> configure.log
+
+# udpate Makefile with the configure results
+sed < Makefile.in "
+/^CC *=/s#=.*#=$CC#
+/^CFLAGS *=/s#=.*#=$CFLAGS#
+/^SFLAGS *=/s#=.*#=$SFLAGS#
+/^LDFLAGS *=/s#=.*#=$LDFLAGS#
+/^LDSHARED *=/s#=.*#=$LDSHARED#
+/^CPP *=/s#=.*#=$CPP#
+/^STATICLIB *=/s#=.*#=$STATICLIB#
+/^SHAREDLIB *=/s#=.*#=$SHAREDLIB#
+/^SHAREDLIBV *=/s#=.*#=$SHAREDLIBV#
+/^SHAREDLIBM *=/s#=.*#=$SHAREDLIBM#
+/^AR *=/s#=.*#=$AR#
+/^ARFLAGS *=/s#=.*#=$ARFLAGS#
+/^RANLIB *=/s#=.*#=$RANLIB#
+/^LDCONFIG *=/s#=.*#=$LDCONFIG#
+/^LDSHAREDLIBC *=/s#=.*#=$LDSHAREDLIBC#
+/^EXE *=/s#=.*#=$EXE#
+/^prefix *=/s#=.*#=$prefix#
+/^exec_prefix *=/s#=.*#=$exec_prefix#
+/^libdir *=/s#=.*#=$libdir#
+/^sharedlibdir *=/s#=.*#=$sharedlibdir#
+/^includedir *=/s#=.*#=$includedir#
+/^mandir *=/s#=.*#=$mandir#
+/^OBJC *=/s#=.*#= $OBJC#
+/^PIC_OBJC *=/s#=.*#= $PIC_OBJC#
+/^all: */s#:.*#: $ALL#
+/^test: */s#:.*#: $TEST#
+" > Makefile
+
+# create zlib.pc with the configure results
+sed < zlib.pc.in "
+/^CC *=/s#=.*#=$CC#
+/^CFLAGS *=/s#=.*#=$CFLAGS#
+/^CPP *=/s#=.*#=$CPP#
+/^LDSHARED *=/s#=.*#=$LDSHARED#
+/^STATICLIB *=/s#=.*#=$STATICLIB#
+/^SHAREDLIB *=/s#=.*#=$SHAREDLIB#
+/^SHAREDLIBV *=/s#=.*#=$SHAREDLIBV#
+/^SHAREDLIBM *=/s#=.*#=$SHAREDLIBM#
+/^AR *=/s#=.*#=$AR#
+/^ARFLAGS *=/s#=.*#=$ARFLAGS#
+/^RANLIB *=/s#=.*#=$RANLIB#
+/^EXE *=/s#=.*#=$EXE#
+/^prefix *=/s#=.*#=$prefix#
+/^exec_prefix *=/s#=.*#=$exec_prefix#
+/^libdir *=/s#=.*#=$libdir#
+/^sharedlibdir *=/s#=.*#=$sharedlibdir#
+/^includedir *=/s#=.*#=$includedir#
+/^mandir *=/s#=.*#=$mandir#
+/^LDFLAGS *=/s#=.*#=$LDFLAGS#
+" | sed -e "
+s/\@VERSION\@/$VER/g;
+" > zlib.pc
+
+# done
+leave 0
diff --git a/compat/zlib/contrib/README.contrib b/compat/zlib/contrib/README.contrib
new file mode 100644
index 0000000..c66349b
--- /dev/null
+++ b/compat/zlib/contrib/README.contrib
@@ -0,0 +1,78 @@
+All files under this contrib directory are UNSUPPORTED. There were
+provided by users of zlib and were not tested by the authors of zlib.
+Use at your own risk. Please contact the authors of the contributions
+for help about these, not the zlib authors. Thanks.
+
+
+ada/        by Dmitriy Anisimkov <anisimkov@yahoo.com>
+        Support for Ada
+        See http://zlib-ada.sourceforge.net/
+
+amd64/      by Mikhail Teterin <mi@ALDAN.algebra.com>
+        asm code for AMD64
+        See patch at http://www.freebsd.org/cgi/query-pr.cgi?pr=bin/96393
+
+asm686/     by Brian Raiter <breadbox@muppetlabs.com>
+        asm code for Pentium and PPro/PII, using the AT&T (GNU as) syntax
+        See http://www.muppetlabs.com/~breadbox/software/assembly.html
+
+blast/      by Mark Adler <madler@alumni.caltech.edu>
+        Decompressor for output of PKWare Data Compression Library (DCL)
+
+delphi/     by Cosmin Truta <cosmint@cs.ubbcluj.ro>
+        Support for Delphi and C++ Builder
+
+dotzlib/    by Henrik Ravn <henrik@ravn.com>
+        Support for Microsoft .Net and Visual C++ .Net
+
+gcc_gvmat64/by Gilles Vollant <info@winimage.com>
+        GCC Version of x86 64-bit (AMD64 and Intel EM64t) code for x64
+        assembler to replace longest_match() and inflate_fast()
+
+infback9/   by Mark Adler <madler@alumni.caltech.edu>
+        Unsupported diffs to infback to decode the deflate64 format
+
+inflate86/  by Chris Anderson <christop@charm.net>
+        Tuned x86 gcc asm code to replace inflate_fast()
+
+iostream/   by Kevin Ruland <kevin@rodin.wustl.edu>
+        A C++ I/O streams interface to the zlib gz* functions
+
+iostream2/  by Tyge L�vset <Tyge.Lovset@cmr.no>
+        Another C++ I/O streams interface
+
+iostream3/  by Ludwig Schwardt <schwardt@sun.ac.za>
+            and Kevin Ruland <kevin@rodin.wustl.edu>
+        Yet another C++ I/O streams interface
+
+masmx64/    by Gilles Vollant <info@winimage.com>
+        x86 64-bit (AMD64 and Intel EM64t) code for x64 assembler to
+        replace longest_match() and inflate_fast(),  also masm x86
+        64-bits translation of Chris Anderson inflate_fast()
+
+masmx86/    by Gilles Vollant <info@winimage.com>
+        x86 asm code to replace longest_match() and inflate_fast(),
+        for Visual C++ and MASM (32 bits).
+        Based on Brian Raiter (asm686) and Chris Anderson (inflate86)
+
+minizip/    by Gilles Vollant <info@winimage.com>
+        Mini zip and unzip based on zlib
+        Includes Zip64 support by Mathias Svensson <mathias@result42.com>
+        See http://www.winimage.com/zLibDll/unzip.html
+
+pascal/     by Bob Dellaca <bobdl@xtra.co.nz> et al.
+        Support for Pascal
+
+puff/       by Mark Adler <madler@alumni.caltech.edu>
+        Small, low memory usage inflate.  Also serves to provide an
+        unambiguous description of the deflate format.
+
+testzlib/   by Gilles Vollant <info@winimage.com>
+        Example of the use of zlib
+
+untgz/      by Pedro A. Aranda Gutierrez <paag@tid.es>
+        A very simple tar.gz file extractor using zlib
+
+vstudio/    by Gilles Vollant <info@winimage.com>
+        Building a minizip-enhanced zlib with Microsoft Visual Studio
+        Includes vc11 from kreuzerkrieg and vc12 from davispuh
diff --git a/compat/zlib/contrib/ada/buffer_demo.adb b/compat/zlib/contrib/ada/buffer_demo.adb
new file mode 100644
index 0000000..46b8638
--- /dev/null
+++ b/compat/zlib/contrib/ada/buffer_demo.adb
@@ -0,0 +1,106 @@
+----------------------------------------------------------------
+--  ZLib for Ada thick binding.                               --
+--                                                            --
+--  Copyright (C) 2002-2004 Dmitriy Anisimkov                 --
+--                                                            --
+--  Open source license information is in the zlib.ads file.  --
+----------------------------------------------------------------
+--
+--  $Id: buffer_demo.adb,v 1.3 2004/09/06 06:55:35 vagul Exp $
+
+--  This demo program provided by Dr Steve Sangwine <sjs@essex.ac.uk>
+--
+--  Demonstration of a problem with Zlib-Ada (already fixed) when a buffer
+--  of exactly the correct size is used for decompressed data, and the last
+--  few bytes passed in to Zlib are checksum bytes.
+
+--  This program compresses a string of text, and then decompresses the
+--  compressed text into a buffer of the same size as the original text.
+
+with Ada.Streams; use Ada.Streams;
+with Ada.Text_IO;
+
+with ZLib; use ZLib;
+
+procedure Buffer_Demo is
+   EOL  : Character renames ASCII.LF;
+   Text : constant String
+     := "Four score and seven years ago our fathers brought forth," & EOL &
+        "upon this continent, a new nation, conceived in liberty," & EOL &
+        "and dedicated to the proposition that `all men are created equal'.";
+
+   Source : Stream_Element_Array (1 .. Text'Length);
+   for Source'Address use Text'Address;
+
+begin
+   Ada.Text_IO.Put (Text);
+   Ada.Text_IO.New_Line;
+   Ada.Text_IO.Put_Line
+     ("Uncompressed size : " & Positive'Image (Text'Length) & " bytes");
+
+   declare
+      Compressed_Data : Stream_Element_Array (1 .. Text'Length);
+      L               : Stream_Element_Offset;
+   begin
+      Compress : declare
+         Compressor : Filter_Type;
+         I : Stream_Element_Offset;
+      begin
+         Deflate_Init (Compressor);
+
+         --  Compress the whole of T at once.
+
+         Translate (Compressor, Source, I, Compressed_Data, L, Finish);
+         pragma Assert (I = Source'Last);
+
+         Close (Compressor);
+
+         Ada.Text_IO.Put_Line
+           ("Compressed size :   "
+            & Stream_Element_Offset'Image (L) & " bytes");
+      end Compress;
+
+      --  Now we decompress the data, passing short blocks of data to Zlib
+      --  (because this demonstrates the problem - the last block passed will
+      --  contain checksum information and there will be no output, only a
+      --  check inside Zlib that the checksum is correct).
+
+      Decompress : declare
+         Decompressor : Filter_Type;
+
+         Uncompressed_Data : Stream_Element_Array (1 .. Text'Length);
+
+         Block_Size : constant := 4;
+         --  This makes sure that the last block contains
+         --  only Adler checksum data.
+
+         P : Stream_Element_Offset := Compressed_Data'First - 1;
+         O : Stream_Element_Offset;
+      begin
+         Inflate_Init (Decompressor);
+
+         loop
+            Translate
+              (Decompressor,
+               Compressed_Data
+                 (P + 1 .. Stream_Element_Offset'Min (P + Block_Size, L)),
+               P,
+               Uncompressed_Data
+                 (Total_Out (Decompressor) + 1 .. Uncompressed_Data'Last),
+               O,
+               No_Flush);
+
+               Ada.Text_IO.Put_Line
+                 ("Total in : " & Count'Image (Total_In (Decompressor)) &
+                  ", out : " & Count'Image (Total_Out (Decompressor)));
+
+               exit when P = L;
+         end loop;
+
+         Ada.Text_IO.New_Line;
+         Ada.Text_IO.Put_Line
+           ("Decompressed text matches original text : "
+             & Boolean'Image (Uncompressed_Data = Source));
+      end Decompress;
+   end;
+end Buffer_Demo;
diff --git a/compat/zlib/contrib/ada/mtest.adb b/compat/zlib/contrib/ada/mtest.adb
new file mode 100644
index 0000000..c4dfd08
--- /dev/null
+++ b/compat/zlib/contrib/ada/mtest.adb
@@ -0,0 +1,156 @@
+----------------------------------------------------------------
+--  ZLib for Ada thick binding.                               --
+--                                                            --
+--  Copyright (C) 2002-2003 Dmitriy Anisimkov                 --
+--                                                            --
+--  Open source license information is in the zlib.ads file.  --
+----------------------------------------------------------------
+--  Continuous test for ZLib multithreading. If the test would fail
+--  we should provide thread safe allocation routines for the Z_Stream.
+--
+--  $Id: mtest.adb,v 1.4 2004/07/23 07:49:54 vagul Exp $
+
+with ZLib;
+with Ada.Streams;
+with Ada.Numerics.Discrete_Random;
+with Ada.Text_IO;
+with Ada.Exceptions;
+with Ada.Task_Identification;
+
+procedure MTest is
+   use Ada.Streams;
+   use ZLib;
+
+   Stop : Boolean := False;
+
+   pragma Atomic (Stop);
+
+   subtype Visible_Symbols is Stream_Element range 16#20# .. 16#7E#;
+
+   package Random_Elements is
+      new Ada.Numerics.Discrete_Random (Visible_Symbols);
+
+   task type Test_Task;
+
+   task body Test_Task is
+      Buffer : Stream_Element_Array (1 .. 100_000);
+      Gen : Random_Elements.Generator;
+
+      Buffer_First  : Stream_Element_Offset;
+      Compare_First : Stream_Element_Offset;
+
+      Deflate : Filter_Type;
+      Inflate : Filter_Type;
+
+      procedure Further (Item : in Stream_Element_Array);
+
+      procedure Read_Buffer
+        (Item : out Ada.Streams.Stream_Element_Array;
+         Last : out Ada.Streams.Stream_Element_Offset);
+
+      -------------
+      -- Further --
+      -------------
+
+      procedure Further (Item : in Stream_Element_Array) is
+
+         procedure Compare (Item : in Stream_Element_Array);
+
+         -------------
+         -- Compare --
+         -------------
+
+         procedure Compare (Item : in Stream_Element_Array) is
+            Next_First : Stream_Element_Offset := Compare_First + Item'Length;
+         begin
+            if Buffer (Compare_First .. Next_First - 1) /= Item then
+               raise Program_Error;
+            end if;
+
+            Compare_First := Next_First;
+         end Compare;
+
+         procedure Compare_Write is new ZLib.Write (Write => Compare);
+      begin
+         Compare_Write (Inflate, Item, No_Flush);
+      end Further;
+
+      -----------------
+      -- Read_Buffer --
+      -----------------
+
+      procedure Read_Buffer
+        (Item : out Ada.Streams.Stream_Element_Array;
+         Last : out Ada.Streams.Stream_Element_Offset)
+      is
+         Buff_Diff   : Stream_Element_Offset := Buffer'Last - Buffer_First;
+         Next_First : Stream_Element_Offset;
+      begin
+         if Item'Length <= Buff_Diff then
+            Last := Item'Last;
+
+            Next_First := Buffer_First + Item'Length;
+
+            Item := Buffer (Buffer_First .. Next_First - 1);
+
+            Buffer_First := Next_First;
+         else
+            Last := Item'First + Buff_Diff;
+            Item (Item'First .. Last) := Buffer (Buffer_First .. Buffer'Last);
+            Buffer_First := Buffer'Last + 1;
+         end if;
+      end Read_Buffer;
+
+      procedure Translate is new Generic_Translate
+                                   (Data_In  => Read_Buffer,
+                                    Data_Out => Further);
+
+   begin
+      Random_Elements.Reset (Gen);
+
+      Buffer := (others => 20);
+
+      Main : loop
+         for J in Buffer'Range loop
+            Buffer (J) := Random_Elements.Random (Gen);
+
+            Deflate_Init (Deflate);
+            Inflate_Init (Inflate);
+
+            Buffer_First  := Buffer'First;
+            Compare_First := Buffer'First;
+
+            Translate (Deflate);
+
+            if Compare_First /= Buffer'Last + 1 then
+               raise Program_Error;
+            end if;
+
+            Ada.Text_IO.Put_Line
+              (Ada.Task_Identification.Image
+                 (Ada.Task_Identification.Current_Task)
+               & Stream_Element_Offset'Image (J)
+               & ZLib.Count'Image (Total_Out (Deflate)));
+
+            Close (Deflate);
+            Close (Inflate);
+
+            exit Main when Stop;
+         end loop;
+      end loop Main;
+   exception
+      when E : others =>
+         Ada.Text_IO.Put_Line (Ada.Exceptions.Exception_Information (E));
+         Stop := True;
+   end Test_Task;
+
+   Test : array (1 .. 4) of Test_Task;
+
+   pragma Unreferenced (Test);
+
+   Dummy : Character;
+
+begin
+   Ada.Text_IO.Get_Immediate (Dummy);
+   Stop := True;
+end MTest;
diff --git a/compat/zlib/contrib/ada/read.adb b/compat/zlib/contrib/ada/read.adb
new file mode 100644
index 0000000..1f2efbf
--- /dev/null
+++ b/compat/zlib/contrib/ada/read.adb
@@ -0,0 +1,156 @@
+----------------------------------------------------------------
+--  ZLib for Ada thick binding.                               --
+--                                                            --
+--  Copyright (C) 2002-2003 Dmitriy Anisimkov                 --
+--                                                            --
+--  Open source license information is in the zlib.ads file.  --
+----------------------------------------------------------------
+
+--  $Id: read.adb,v 1.8 2004/05/31 10:53:40 vagul Exp $
+
+--  Test/demo program for the generic read interface.
+
+with Ada.Numerics.Discrete_Random;
+with Ada.Streams;
+with Ada.Text_IO;
+
+with ZLib;
+
+procedure Read is
+
+   use Ada.Streams;
+
+   ------------------------------------
+   --  Test configuration parameters --
+   ------------------------------------
+
+   File_Size   : Stream_Element_Offset := 100_000;
+
+   Continuous  : constant Boolean          := False;
+   --  If this constant is True, the test would be repeated again and again,
+   --  with increment File_Size for every iteration.
+
+   Header      : constant ZLib.Header_Type := ZLib.Default;
+   --  Do not use Header other than Default in ZLib versions 1.1.4 and older.
+
+   Init_Random : constant := 8;
+   --  We are using the same random sequence, in case of we catch bug,
+   --  so we would be able to reproduce it.
+
+   -- End --
+
+   Pack_Size : Stream_Element_Offset;
+   Offset    : Stream_Element_Offset;
+
+   Filter     : ZLib.Filter_Type;
+
+   subtype Visible_Symbols
+      is Stream_Element range 16#20# .. 16#7E#;
+
+   package Random_Elements is new
+      Ada.Numerics.Discrete_Random (Visible_Symbols);
+
+   Gen : Random_Elements.Generator;
+   Period  : constant Stream_Element_Offset := 200;
+   --  Period constant variable for random generator not to be very random.
+   --  Bigger period, harder random.
+
+   Read_Buffer : Stream_Element_Array (1 .. 2048);
+   Read_First  : Stream_Element_Offset;
+   Read_Last   : Stream_Element_Offset;
+
+   procedure Reset;
+
+   procedure Read
+     (Item : out Stream_Element_Array;
+      Last : out Stream_Element_Offset);
+   --  this procedure is for generic instantiation of
+   --  ZLib.Read
+   --  reading data from the File_In.
+
+   procedure Read is new ZLib.Read
+                           (Read,
+                            Read_Buffer,
+                            Rest_First => Read_First,
+                            Rest_Last  => Read_Last);
+
+   ----------
+   -- Read --
+   ----------
+
+   procedure Read
+     (Item : out Stream_Element_Array;
+      Last : out Stream_Element_Offset) is
+   begin
+      Last := Stream_Element_Offset'Min
+               (Item'Last,
+                Item'First + File_Size - Offset);
+
+      for J in Item'First .. Last loop
+         if J < Item'First + Period then
+            Item (J) := Random_Elements.Random (Gen);
+         else
+            Item (J) := Item (J - Period);
+         end if;
+
+         Offset   := Offset + 1;
+      end loop;
+   end Read;
+
+   -----------
+   -- Reset --
+   -----------
+
+   procedure Reset is
+   begin
+      Random_Elements.Reset (Gen, Init_Random);
+      Pack_Size := 0;
+      Offset := 1;
+      Read_First := Read_Buffer'Last + 1;
+      Read_Last  := Read_Buffer'Last;
+   end Reset;
+
+begin
+   Ada.Text_IO.Put_Line ("ZLib " & ZLib.Version);
+
+   loop
+      for Level in ZLib.Compression_Level'Range loop
+
+         Ada.Text_IO.Put ("Level ="
+            & ZLib.Compression_Level'Image (Level));
+
+         --  Deflate using generic instantiation.
+
+         ZLib.Deflate_Init
+               (Filter,
+                Level,
+                Header => Header);
+
+         Reset;
+
+         Ada.Text_IO.Put
+           (Stream_Element_Offset'Image (File_Size) & " ->");
+
+         loop
+            declare
+               Buffer : Stream_Element_Array (1 .. 1024);
+               Last   : Stream_Element_Offset;
+            begin
+               Read (Filter, Buffer, Last);
+
+               Pack_Size := Pack_Size + Last - Buffer'First + 1;
+
+               exit when Last < Buffer'Last;
+            end;
+         end loop;
+
+         Ada.Text_IO.Put_Line (Stream_Element_Offset'Image (Pack_Size));
+
+         ZLib.Close (Filter);
+      end loop;
+
+      exit when not Continuous;
+
+      File_Size := File_Size + 1;
+   end loop;
+end Read;
diff --git a/compat/zlib/contrib/ada/readme.txt b/compat/zlib/contrib/ada/readme.txt
new file mode 100644
index 0000000..ce4d2ca
--- /dev/null
+++ b/compat/zlib/contrib/ada/readme.txt
@@ -0,0 +1,65 @@
+                        ZLib for Ada thick binding (ZLib.Ada)
+                        Release 1.3
+
+ZLib.Ada is a thick binding interface to the popular ZLib data
+compression library, available at http://www.gzip.org/zlib/.
+It provides Ada-style access to the ZLib C library.
+
+
+        Here are the main changes since ZLib.Ada 1.2:
+
+- Attension: ZLib.Read generic routine have a initialization requirement
+  for Read_Last parameter now. It is a bit incompartible with previous version,
+  but extends functionality, we could use new parameters Allow_Read_Some and
+  Flush now.
+
+- Added Is_Open routines to ZLib and ZLib.Streams packages.
+
+- Add pragma Assert to check Stream_Element is 8 bit.
+
+- Fix extraction to buffer with exact known decompressed size. Error reported by
+  Steve Sangwine.
+
+- Fix definition of ULong (changed to unsigned_long), fix regression on 64 bits
+  computers. Patch provided by Pascal Obry.
+
+- Add Status_Error exception definition.
+
+- Add pragma Assertion that Ada.Streams.Stream_Element size is 8 bit.
+
+
+        How to build ZLib.Ada under GNAT
+
+You should have the ZLib library already build on your computer, before
+building ZLib.Ada. Make the directory of ZLib.Ada sources current and
+issue the command:
+
+  gnatmake test -largs -L<directory where libz.a is> -lz
+
+Or use the GNAT project file build for GNAT 3.15 or later:
+
+  gnatmake -Pzlib.gpr -L<directory where libz.a is>
+
+
+        How to build ZLib.Ada under Aonix ObjectAda for Win32 7.2.2
+
+1. Make a project with all *.ads and *.adb files from the distribution.
+2. Build the libz.a library from the ZLib C sources.
+3. Rename libz.a to z.lib.
+4. Add the library z.lib to the project.
+5. Add the libc.lib library from the ObjectAda distribution to the project.
+6. Build the executable using test.adb as a main procedure.
+
+
+        How to use ZLib.Ada
+
+The source files test.adb and read.adb are small demo programs that show
+the main functionality of ZLib.Ada.
+
+The routines from the package specifications are commented.
+
+
+Homepage: http://zlib-ada.sourceforge.net/
+Author: Dmitriy Anisimkov <anisimkov@yahoo.com>
+
+Contributors: Pascal Obry <pascal@obry.org>, Steve Sangwine <sjs@essex.ac.uk>
diff --git a/compat/zlib/contrib/ada/test.adb b/compat/zlib/contrib/ada/test.adb
new file mode 100644
index 0000000..90773ac
--- /dev/null
+++ b/compat/zlib/contrib/ada/test.adb
@@ -0,0 +1,463 @@
+----------------------------------------------------------------
+--  ZLib for Ada thick binding.                               --
+--                                                            --
+--  Copyright (C) 2002-2003 Dmitriy Anisimkov                 --
+--                                                            --
+--  Open source license information is in the zlib.ads file.  --
+----------------------------------------------------------------
+
+--  $Id: test.adb,v 1.17 2003/08/12 12:13:30 vagul Exp $
+
+--  The program has a few aims.
+--  1. Test ZLib.Ada95 thick binding functionality.
+--  2. Show the example of use main functionality of the ZLib.Ada95 binding.
+--  3. Build this program automatically compile all ZLib.Ada95 packages under
+--     GNAT Ada95 compiler.
+
+with ZLib.Streams;
+with Ada.Streams.Stream_IO;
+with Ada.Numerics.Discrete_Random;
+
+with Ada.Text_IO;
+
+with Ada.Calendar;
+
+procedure Test is
+
+   use Ada.Streams;
+   use Stream_IO;
+
+   ------------------------------------
+   --  Test configuration parameters --
+   ------------------------------------
+
+   File_Size   : Count   := 100_000;
+   Continuous  : constant Boolean := False;
+
+   Header      : constant ZLib.Header_Type := ZLib.Default;
+                                              --  ZLib.None;
+                                              --  ZLib.Auto;
+                                              --  ZLib.GZip;
+   --  Do not use Header other then Default in ZLib versions 1.1.4
+   --  and older.
+
+   Strategy    : constant ZLib.Strategy_Type := ZLib.Default_Strategy;
+   Init_Random : constant := 10;
+
+   -- End --
+
+   In_File_Name  : constant String := "testzlib.in";
+   --  Name of the input file
+
+   Z_File_Name   : constant String := "testzlib.zlb";
+   --  Name of the compressed file.
+
+   Out_File_Name : constant String := "testzlib.out";
+   --  Name of the decompressed file.
+
+   File_In   : File_Type;
+   File_Out  : File_Type;
+   File_Back : File_Type;
+   File_Z    : ZLib.Streams.Stream_Type;
+
+   Filter : ZLib.Filter_Type;
+
+   Time_Stamp : Ada.Calendar.Time;
+
+   procedure Generate_File;
+   --  Generate file of spetsified size with some random data.
+   --  The random data is repeatable, for the good compression.
+
+   procedure Compare_Streams
+     (Left, Right : in out Root_Stream_Type'Class);
+   --  The procedure compearing data in 2 streams.
+   --  It is for compare data before and after compression/decompression.
+
+   procedure Compare_Files (Left, Right : String);
+   --  Compare files. Based on the Compare_Streams.
+
+   procedure Copy_Streams
+     (Source, Target : in out Root_Stream_Type'Class;
+      Buffer_Size    : in     Stream_Element_Offset := 1024);
+   --  Copying data from one stream to another. It is for test stream
+   --  interface of the library.
+
+   procedure Data_In
+     (Item : out Stream_Element_Array;
+      Last : out Stream_Element_Offset);
+   --  this procedure is for generic instantiation of
+   --  ZLib.Generic_Translate.
+   --  reading data from the File_In.
+
+   procedure Data_Out (Item : in Stream_Element_Array);
+   --  this procedure is for generic instantiation of
+   --  ZLib.Generic_Translate.
+   --  writing data to the File_Out.
+
+   procedure Stamp;
+   --  Store the timestamp to the local variable.
+
+   procedure Print_Statistic (Msg : String; Data_Size : ZLib.Count);
+   --  Print the time statistic with the message.
+
+   procedure Translate is new ZLib.Generic_Translate
+                                (Data_In  => Data_In,
+                                 Data_Out => Data_Out);
+   --  This procedure is moving data from File_In to File_Out
+   --  with compression or decompression, depend on initialization of
+   --  Filter parameter.
+
+   -------------------
+   -- Compare_Files --
+   -------------------
+
+   procedure Compare_Files (Left, Right : String) is
+      Left_File, Right_File : File_Type;
+   begin
+      Open (Left_File, In_File, Left);
+      Open (Right_File, In_File, Right);
+      Compare_Streams (Stream (Left_File).all, Stream (Right_File).all);
+      Close (Left_File);
+      Close (Right_File);
+   end Compare_Files;
+
+   ---------------------
+   -- Compare_Streams --
+   ---------------------
+
+   procedure Compare_Streams
+     (Left, Right : in out Ada.Streams.Root_Stream_Type'Class)
+   is
+      Left_Buffer, Right_Buffer : Stream_Element_Array (0 .. 16#FFF#);
+      Left_Last, Right_Last : Stream_Element_Offset;
+   begin
+      loop
+         Read (Left, Left_Buffer, Left_Last);
+         Read (Right, Right_Buffer, Right_Last);
+
+         if Left_Last /= Right_Last then
+            Ada.Text_IO.Put_Line ("Compare error :"
+              & Stream_Element_Offset'Image (Left_Last)
+              & " /= "
+              & Stream_Element_Offset'Image (Right_Last));
+
+            raise Constraint_Error;
+
+         elsif Left_Buffer (0 .. Left_Last)
+               /= Right_Buffer (0 .. Right_Last)
+         then
+            Ada.Text_IO.Put_Line ("ERROR: IN and OUT files is not equal.");
+            raise Constraint_Error;
+
+         end if;
+
+         exit when Left_Last < Left_Buffer'Last;
+      end loop;
+   end Compare_Streams;
+
+   ------------------
+   -- Copy_Streams --
+   ------------------
+
+   procedure Copy_Streams
+     (Source, Target : in out Ada.Streams.Root_Stream_Type'Class;
+      Buffer_Size    : in     Stream_Element_Offset := 1024)
+   is
+      Buffer : Stream_Element_Array (1 .. Buffer_Size);
+      Last   : Stream_Element_Offset;
+   begin
+      loop
+         Read  (Source, Buffer, Last);
+         Write (Target, Buffer (1 .. Last));
+
+         exit when Last < Buffer'Last;
+      end loop;
+   end Copy_Streams;
+
+   -------------
+   -- Data_In --
+   -------------
+
+   procedure Data_In
+     (Item : out Stream_Element_Array;
+      Last : out Stream_Element_Offset) is
+   begin
+      Read (File_In, Item, Last);
+   end Data_In;
+
+   --------------
+   -- Data_Out --
+   --------------
+
+   procedure Data_Out (Item : in Stream_Element_Array) is
+   begin
+      Write (File_Out, Item);
+   end Data_Out;
+
+   -------------------
+   -- Generate_File --
+   -------------------
+
+   procedure Generate_File is
+      subtype Visible_Symbols is Stream_Element range 16#20# .. 16#7E#;
+
+      package Random_Elements is
+         new Ada.Numerics.Discrete_Random (Visible_Symbols);
+
+      Gen    : Random_Elements.Generator;
+      Buffer : Stream_Element_Array := (1 .. 77 => 16#20#) & 10;
+
+      Buffer_Count : constant Count := File_Size / Buffer'Length;
+      --  Number of same buffers in the packet.
+
+      Density : constant Count := 30; --  from 0 to Buffer'Length - 2;
+
+      procedure Fill_Buffer (J, D : in Count);
+      --  Change the part of the buffer.
+
+      -----------------
+      -- Fill_Buffer --
+      -----------------
+
+      procedure Fill_Buffer (J, D : in Count) is
+      begin
+         for K in 0 .. D loop
+            Buffer
+              (Stream_Element_Offset ((J + K) mod (Buffer'Length - 1) + 1))
+             := Random_Elements.Random (Gen);
+
+         end loop;
+      end Fill_Buffer;
+
+   begin
+      Random_Elements.Reset (Gen, Init_Random);
+
+      Create (File_In, Out_File, In_File_Name);
+
+      Fill_Buffer (1, Buffer'Length - 2);
+
+      for J in 1 .. Buffer_Count loop
+         Write (File_In, Buffer);
+
+         Fill_Buffer (J, Density);
+      end loop;
+
+      --  fill remain size.
+
+      Write
+        (File_In,
+         Buffer
+           (1 .. Stream_Element_Offset
+                   (File_Size - Buffer'Length * Buffer_Count)));
+
+      Flush (File_In);
+      Close (File_In);
+   end Generate_File;
+
+   ---------------------
+   -- Print_Statistic --
+   ---------------------
+
+   procedure Print_Statistic (Msg : String; Data_Size : ZLib.Count) is
+      use Ada.Calendar;
+      use Ada.Text_IO;
+
+      package Count_IO is new Integer_IO (ZLib.Count);
+
+      Curr_Dur : Duration := Clock - Time_Stamp;
+   begin
+      Put (Msg);
+
+      Set_Col (20);
+      Ada.Text_IO.Put ("size =");
+
+      Count_IO.Put
+        (Data_Size,
+         Width => Stream_IO.Count'Image (File_Size)'Length);
+
+      Put_Line (" duration =" & Duration'Image (Curr_Dur));
+   end Print_Statistic;
+
+   -----------
+   -- Stamp --
+   -----------
+
+   procedure Stamp is
+   begin
+      Time_Stamp := Ada.Calendar.Clock;
+   end Stamp;
+
+begin
+   Ada.Text_IO.Put_Line ("ZLib " & ZLib.Version);
+
+   loop
+      Generate_File;
+
+      for Level in ZLib.Compression_Level'Range loop
+
+         Ada.Text_IO.Put_Line ("Level ="
+            & ZLib.Compression_Level'Image (Level));
+
+         --  Test generic interface.
+         Open   (File_In, In_File, In_File_Name);
+         Create (File_Out, Out_File, Z_File_Name);
+
+         Stamp;
+
+         --  Deflate using generic instantiation.
+
+         ZLib.Deflate_Init
+               (Filter   => Filter,
+                Level    => Level,
+                Strategy => Strategy,
+                Header   => Header);
+
+         Translate (Filter);
+         Print_Statistic ("Generic compress", ZLib.Total_Out (Filter));
+         ZLib.Close (Filter);
+
+         Close (File_In);
+         Close (File_Out);
+
+         Open   (File_In, In_File, Z_File_Name);
+         Create (File_Out, Out_File, Out_File_Name);
+
+         Stamp;
+
+         --  Inflate using generic instantiation.
+
+         ZLib.Inflate_Init (Filter, Header => Header);
+
+         Translate (Filter);
+         Print_Statistic ("Generic decompress", ZLib.Total_Out (Filter));
+
+         ZLib.Close (Filter);
+
+         Close (File_In);
+         Close (File_Out);
+
+         Compare_Files (In_File_Name, Out_File_Name);
+
+         --  Test stream interface.
+
+         --  Compress to the back stream.
+
+         Open   (File_In, In_File, In_File_Name);
+         Create (File_Back, Out_File, Z_File_Name);
+
+         Stamp;
+
+         ZLib.Streams.Create
+           (Stream          => File_Z,
+            Mode            => ZLib.Streams.Out_Stream,
+            Back            => ZLib.Streams.Stream_Access
+                                 (Stream (File_Back)),
+            Back_Compressed => True,
+            Level           => Level,
+            Strategy        => Strategy,
+            Header          => Header);
+
+         Copy_Streams
+           (Source => Stream (File_In).all,
+            Target => File_Z);
+
+         --  Flushing internal buffers to the back stream.
+
+         ZLib.Streams.Flush (File_Z, ZLib.Finish);
+
+         Print_Statistic ("Write compress",
+                          ZLib.Streams.Write_Total_Out (File_Z));
+
+         ZLib.Streams.Close (File_Z);
+
+         Close (File_In);
+         Close (File_Back);
+
+         --  Compare reading from original file and from
+         --  decompression stream.
+
+         Open (File_In,   In_File, In_File_Name);
+         Open (File_Back, In_File, Z_File_Name);
+
+         ZLib.Streams.Create
+           (Stream          => File_Z,
+            Mode            => ZLib.Streams.In_Stream,
+            Back            => ZLib.Streams.Stream_Access
+                                 (Stream (File_Back)),
+            Back_Compressed => True,
+            Header          => Header);
+
+         Stamp;
+         Compare_Streams (Stream (File_In).all, File_Z);
+
+         Print_Statistic ("Read decompress",
+                          ZLib.Streams.Read_Total_Out (File_Z));
+
+         ZLib.Streams.Close (File_Z);
+         Close (File_In);
+         Close (File_Back);
+
+         --  Compress by reading from compression stream.
+
+         Open (File_Back, In_File, In_File_Name);
+         Create (File_Out, Out_File, Z_File_Name);
+
+         ZLib.Streams.Create
+           (Stream          => File_Z,
+            Mode            => ZLib.Streams.In_Stream,
+            Back            => ZLib.Streams.Stream_Access
+                                 (Stream (File_Back)),
+            Back_Compressed => False,
+            Level           => Level,
+            Strategy        => Strategy,
+            Header          => Header);
+
+         Stamp;
+         Copy_Streams
+           (Source => File_Z,
+            Target => Stream (File_Out).all);
+
+         Print_Statistic ("Read compress",
+                          ZLib.Streams.Read_Total_Out (File_Z));
+
+         ZLib.Streams.Close (File_Z);
+
+         Close (File_Out);
+         Close (File_Back);
+
+         --  Decompress to decompression stream.
+
+         Open   (File_In,   In_File, Z_File_Name);
+         Create (File_Back, Out_File, Out_File_Name);
+
+         ZLib.Streams.Create
+           (Stream          => File_Z,
+            Mode            => ZLib.Streams.Out_Stream,
+            Back            => ZLib.Streams.Stream_Access
+                                 (Stream (File_Back)),
+            Back_Compressed => False,
+            Header          => Header);
+
+         Stamp;
+
+         Copy_Streams
+           (Source => Stream (File_In).all,
+            Target => File_Z);
+
+         Print_Statistic ("Write decompress",
+                          ZLib.Streams.Write_Total_Out (File_Z));
+
+         ZLib.Streams.Close (File_Z);
+         Close (File_In);
+         Close (File_Back);
+
+         Compare_Files (In_File_Name, Out_File_Name);
+      end loop;
+
+      Ada.Text_IO.Put_Line (Count'Image (File_Size) & " Ok.");
+
+      exit when not Continuous;
+
+      File_Size := File_Size + 1;
+   end loop;
+end Test;
diff --git a/compat/zlib/contrib/ada/zlib-streams.adb b/compat/zlib/contrib/ada/zlib-streams.adb
new file mode 100644
index 0000000..b6497ba
--- /dev/null
+++ b/compat/zlib/contrib/ada/zlib-streams.adb
@@ -0,0 +1,225 @@
+----------------------------------------------------------------
+--  ZLib for Ada thick binding.                               --
+--                                                            --
+--  Copyright (C) 2002-2003 Dmitriy Anisimkov                 --
+--                                                            --
+--  Open source license information is in the zlib.ads file.  --
+----------------------------------------------------------------
+
+--  $Id: zlib-streams.adb,v 1.10 2004/05/31 10:53:40 vagul Exp $
+
+with Ada.Unchecked_Deallocation;
+
+package body ZLib.Streams is
+
+   -----------
+   -- Close --
+   -----------
+
+   procedure Close (Stream : in out Stream_Type) is
+      procedure Free is new Ada.Unchecked_Deallocation
+         (Stream_Element_Array, Buffer_Access);
+   begin
+      if Stream.Mode = Out_Stream or Stream.Mode = Duplex then
+         --  We should flush the data written by the writer.
+
+         Flush (Stream, Finish);
+
+         Close (Stream.Writer);
+      end if;
+
+      if Stream.Mode = In_Stream or Stream.Mode = Duplex then
+         Close (Stream.Reader);
+         Free (Stream.Buffer);
+      end if;
+   end Close;
+
+   ------------
+   -- Create --
+   ------------
+
+   procedure Create
+     (Stream            :    out Stream_Type;
+      Mode              : in     Stream_Mode;
+      Back              : in     Stream_Access;
+      Back_Compressed   : in     Boolean;
+      Level             : in     Compression_Level := Default_Compression;
+      Strategy          : in     Strategy_Type     := Default_Strategy;
+      Header            : in     Header_Type       := Default;
+      Read_Buffer_Size  : in     Ada.Streams.Stream_Element_Offset
+                                    := Default_Buffer_Size;
+      Write_Buffer_Size : in     Ada.Streams.Stream_Element_Offset
+                                    := Default_Buffer_Size)
+   is
+
+      subtype Buffer_Subtype is Stream_Element_Array (1 .. Read_Buffer_Size);
+
+      procedure Init_Filter
+         (Filter   : in out Filter_Type;
+          Compress : in     Boolean);
+
+      -----------------
+      -- Init_Filter --
+      -----------------
+
+      procedure Init_Filter
+         (Filter   : in out Filter_Type;
+          Compress : in     Boolean) is
+      begin
+         if Compress then
+            Deflate_Init
+              (Filter, Level, Strategy, Header => Header);
+         else
+            Inflate_Init (Filter, Header => Header);
+         end if;
+      end Init_Filter;
+
+   begin
+      Stream.Back := Back;
+      Stream.Mode := Mode;
+
+      if Mode = Out_Stream or Mode = Duplex then
+         Init_Filter (Stream.Writer, Back_Compressed);
+         Stream.Buffer_Size := Write_Buffer_Size;
+      else
+         Stream.Buffer_Size := 0;
+      end if;
+
+      if Mode = In_Stream or Mode = Duplex then
+         Init_Filter (Stream.Reader, not Back_Compressed);
+
+         Stream.Buffer     := new Buffer_Subtype;
+         Stream.Rest_First := Stream.Buffer'Last + 1;
+         Stream.Rest_Last  := Stream.Buffer'Last;
+      end if;
+   end Create;
+
+   -----------
+   -- Flush --
+   -----------
+
+   procedure Flush
+     (Stream : in out Stream_Type;
+      Mode   : in     Flush_Mode := Sync_Flush)
+   is
+      Buffer : Stream_Element_Array (1 .. Stream.Buffer_Size);
+      Last   : Stream_Element_Offset;
+   begin
+      loop
+         Flush (Stream.Writer, Buffer, Last, Mode);
+
+         Ada.Streams.Write (Stream.Back.all, Buffer (1 .. Last));
+
+         exit when Last < Buffer'Last;
+      end loop;
+   end Flush;
+
+   -------------
+   -- Is_Open --
+   -------------
+
+   function Is_Open (Stream : Stream_Type) return Boolean is
+   begin
+      return Is_Open (Stream.Reader) or else Is_Open (Stream.Writer);
+   end Is_Open;
+
+   ----------
+   -- Read --
+   ----------
+
+   procedure Read
+     (Stream : in out Stream_Type;
+      Item   :    out Stream_Element_Array;
+      Last   :    out Stream_Element_Offset)
+   is
+
+      procedure Read
+        (Item : out Stream_Element_Array;
+         Last : out Stream_Element_Offset);
+
+      ----------
+      -- Read --
+      ----------
+
+      procedure Read
+        (Item : out Stream_Element_Array;
+         Last : out Stream_Element_Offset) is
+      begin
+         Ada.Streams.Read (Stream.Back.all, Item, Last);
+      end Read;
+
+      procedure Read is new ZLib.Read
+         (Read       => Read,
+          Buffer     => Stream.Buffer.all,
+          Rest_First => Stream.Rest_First,
+          Rest_Last  => Stream.Rest_Last);
+
+   begin
+      Read (Stream.Reader, Item, Last);
+   end Read;
+
+   -------------------
+   -- Read_Total_In --
+   -------------------
+
+   function Read_Total_In (Stream : in Stream_Type) return Count is
+   begin
+      return Total_In (Stream.Reader);
+   end Read_Total_In;
+
+   --------------------
+   -- Read_Total_Out --
+   --------------------
+
+   function Read_Total_Out (Stream : in Stream_Type) return Count is
+   begin
+      return Total_Out (Stream.Reader);
+   end Read_Total_Out;
+
+   -----------
+   -- Write --
+   -----------
+
+   procedure Write
+     (Stream : in out Stream_Type;
+      Item   : in     Stream_Element_Array)
+   is
+
+      procedure Write (Item : in Stream_Element_Array);
+
+      -----------
+      -- Write --
+      -----------
+
+      procedure Write (Item : in Stream_Element_Array) is
+      begin
+         Ada.Streams.Write (Stream.Back.all, Item);
+      end Write;
+
+      procedure Write is new ZLib.Write
+         (Write       => Write,
+          Buffer_Size => Stream.Buffer_Size);
+
+   begin
+      Write (Stream.Writer, Item, No_Flush);
+   end Write;
+
+   --------------------
+   -- Write_Total_In --
+   --------------------
+
+   function Write_Total_In (Stream : in Stream_Type) return Count is
+   begin
+      return Total_In (Stream.Writer);
+   end Write_Total_In;
+
+   ---------------------
+   -- Write_Total_Out --
+   ---------------------
+
+   function Write_Total_Out (Stream : in Stream_Type) return Count is
+   begin
+      return Total_Out (Stream.Writer);
+   end Write_Total_Out;
+
+end ZLib.Streams;
diff --git a/compat/zlib/contrib/ada/zlib-streams.ads b/compat/zlib/contrib/ada/zlib-streams.ads
new file mode 100644
index 0000000..f0193c6
--- /dev/null
+++ b/compat/zlib/contrib/ada/zlib-streams.ads
@@ -0,0 +1,114 @@
+----------------------------------------------------------------
+--  ZLib for Ada thick binding.                               --
+--                                                            --
+--  Copyright (C) 2002-2003 Dmitriy Anisimkov                 --
+--                                                            --
+--  Open source license information is in the zlib.ads file.  --
+----------------------------------------------------------------
+
+--  $Id: zlib-streams.ads,v 1.12 2004/05/31 10:53:40 vagul Exp $
+
+package ZLib.Streams is
+
+   type Stream_Mode is (In_Stream, Out_Stream, Duplex);
+
+   type Stream_Access is access all Ada.Streams.Root_Stream_Type'Class;
+
+   type Stream_Type is
+      new Ada.Streams.Root_Stream_Type with private;
+
+   procedure Read
+     (Stream : in out Stream_Type;
+      Item   :    out Ada.Streams.Stream_Element_Array;
+      Last   :    out Ada.Streams.Stream_Element_Offset);
+
+   procedure Write
+     (Stream : in out Stream_Type;
+      Item   : in     Ada.Streams.Stream_Element_Array);
+
+   procedure Flush
+     (Stream : in out Stream_Type;
+      Mode   : in     Flush_Mode := Sync_Flush);
+   --  Flush the written data to the back stream,
+   --  all data placed to the compressor is flushing to the Back stream.
+   --  Should not be used untill necessary, becouse it is decreasing
+   --  compression.
+
+   function Read_Total_In (Stream : in Stream_Type) return Count;
+   pragma Inline (Read_Total_In);
+   --  Return total number of bytes read from back stream so far.
+
+   function Read_Total_Out (Stream : in Stream_Type) return Count;
+   pragma Inline (Read_Total_Out);
+   --  Return total number of bytes read so far.
+
+   function Write_Total_In (Stream : in Stream_Type) return Count;
+   pragma Inline (Write_Total_In);
+   --  Return total number of bytes written so far.
+
+   function Write_Total_Out (Stream : in Stream_Type) return Count;
+   pragma Inline (Write_Total_Out);
+   --  Return total number of bytes written to the back stream.
+
+   procedure Create
+     (Stream            :    out Stream_Type;
+      Mode              : in     Stream_Mode;
+      Back              : in     Stream_Access;
+      Back_Compressed   : in     Boolean;
+      Level             : in     Compression_Level := Default_Compression;
+      Strategy          : in     Strategy_Type     := Default_Strategy;
+      Header            : in     Header_Type       := Default;
+      Read_Buffer_Size  : in     Ada.Streams.Stream_Element_Offset
+                                    := Default_Buffer_Size;
+      Write_Buffer_Size : in     Ada.Streams.Stream_Element_Offset
+                                    := Default_Buffer_Size);
+   --  Create the Comression/Decompression stream.
+   --  If mode is In_Stream then Write operation is disabled.
+   --  If mode is Out_Stream then Read operation is disabled.
+
+   --  If Back_Compressed is true then
+   --  Data written to the Stream is compressing to the Back stream
+   --  and data read from the Stream is decompressed data from the Back stream.
+
+   --  If Back_Compressed is false then
+   --  Data written to the Stream is decompressing to the Back stream
+   --  and data read from the Stream is compressed data from the Back stream.
+
+   --  !!! When the Need_Header is False ZLib-Ada is using undocumented
+   --  ZLib 1.1.4 functionality to do not create/wait for ZLib headers.
+
+   function Is_Open (Stream : Stream_Type) return Boolean;
+
+   procedure Close (Stream : in out Stream_Type);
+
+private
+
+   use Ada.Streams;
+
+   type Buffer_Access is access all Stream_Element_Array;
+
+   type Stream_Type
+     is new Root_Stream_Type with
+   record
+      Mode       : Stream_Mode;
+
+      Buffer     : Buffer_Access;
+      Rest_First : Stream_Element_Offset;
+      Rest_Last  : Stream_Element_Offset;
+      --  Buffer for Read operation.
+      --  We need to have this buffer in the record
+      --  becouse not all read data from back stream
+      --  could be processed during the read operation.
+
+      Buffer_Size : Stream_Element_Offset;
+      --  Buffer size for write operation.
+      --  We do not need to have this buffer
+      --  in the record becouse all data could be
+      --  processed in the write operation.
+
+      Back       : Stream_Access;
+      Reader     : Filter_Type;
+      Writer     : Filter_Type;
+   end record;
+
+end ZLib.Streams;
diff --git a/compat/zlib/contrib/ada/zlib-thin.adb b/compat/zlib/contrib/ada/zlib-thin.adb
new file mode 100644
index 0000000..0ca4a71
--- /dev/null
+++ b/compat/zlib/contrib/ada/zlib-thin.adb
@@ -0,0 +1,141 @@
+----------------------------------------------------------------
+--  ZLib for Ada thick binding.                               --
+--                                                            --
+--  Copyright (C) 2002-2003 Dmitriy Anisimkov                 --
+--                                                            --
+--  Open source license information is in the zlib.ads file.  --
+----------------------------------------------------------------
+
+--  $Id: zlib-thin.adb,v 1.8 2003/12/14 18:27:31 vagul Exp $
+
+package body ZLib.Thin is
+
+   ZLIB_VERSION  : constant Chars_Ptr := zlibVersion;
+
+   Z_Stream_Size : constant Int := Z_Stream'Size / System.Storage_Unit;
+
+   --------------
+   -- Avail_In --
+   --------------
+
+   function Avail_In (Strm : in Z_Stream) return UInt is
+   begin
+      return Strm.Avail_In;
+   end Avail_In;
+
+   ---------------
+   -- Avail_Out --
+   ---------------
+
+   function Avail_Out (Strm : in Z_Stream) return UInt is
+   begin
+      return Strm.Avail_Out;
+   end Avail_Out;
+
+   ------------------
+   -- Deflate_Init --
+   ------------------
+
+   function Deflate_Init
+     (strm       : Z_Streamp;
+      level      : Int;
+      method     : Int;
+      windowBits : Int;
+      memLevel   : Int;
+      strategy   : Int)
+      return       Int is
+   begin
+      return deflateInit2
+               (strm,
+                level,
+                method,
+                windowBits,
+                memLevel,
+                strategy,
+                ZLIB_VERSION,
+                Z_Stream_Size);
+   end Deflate_Init;
+
+   ------------------
+   -- Inflate_Init --
+   ------------------
+
+   function Inflate_Init (strm : Z_Streamp; windowBits : Int) return Int is
+   begin
+      return inflateInit2 (strm, windowBits, ZLIB_VERSION, Z_Stream_Size);
+   end Inflate_Init;
+
+   ------------------------
+   -- Last_Error_Message --
+   ------------------------
+
+   function Last_Error_Message (Strm : in Z_Stream) return String is
+      use Interfaces.C.Strings;
+   begin
+      if Strm.msg = Null_Ptr then
+         return "";
+      else
+         return Value (Strm.msg);
+      end if;
+   end Last_Error_Message;
+
+   ------------
+   -- Set_In --
+   ------------
+
+   procedure Set_In
+     (Strm   : in out Z_Stream;
+      Buffer : in     Voidp;
+      Size   : in     UInt) is
+   begin
+      Strm.Next_In  := Buffer;
+      Strm.Avail_In := Size;
+   end Set_In;
+
+   ------------------
+   -- Set_Mem_Func --
+   ------------------
+
+   procedure Set_Mem_Func
+     (Strm   : in out Z_Stream;
+      Opaque : in     Voidp;
+      Alloc  : in     alloc_func;
+      Free   : in     free_func) is
+   begin
+      Strm.opaque := Opaque;
+      Strm.zalloc := Alloc;
+      Strm.zfree  := Free;
+   end Set_Mem_Func;
+
+   -------------
+   -- Set_Out --
+   -------------
+
+   procedure Set_Out
+     (Strm   : in out Z_Stream;
+      Buffer : in     Voidp;
+      Size   : in     UInt) is
+   begin
+      Strm.Next_Out  := Buffer;
+      Strm.Avail_Out := Size;
+   end Set_Out;
+
+   --------------
+   -- Total_In --
+   --------------
+
+   function Total_In (Strm : in Z_Stream) return ULong is
+   begin
+      return Strm.Total_In;
+   end Total_In;
+
+   ---------------
+   -- Total_Out --
+   ---------------
+
+   function Total_Out (Strm : in Z_Stream) return ULong is
+   begin
+      return Strm.Total_Out;
+   end Total_Out;
+
+end ZLib.Thin;
diff --git a/compat/zlib/contrib/ada/zlib-thin.ads b/compat/zlib/contrib/ada/zlib-thin.ads
new file mode 100644
index 0000000..d4407eb
--- /dev/null
+++ b/compat/zlib/contrib/ada/zlib-thin.ads
@@ -0,0 +1,450 @@
+----------------------------------------------------------------
+--  ZLib for Ada thick binding.                               --
+--                                                            --
+--  Copyright (C) 2002-2003 Dmitriy Anisimkov                 --
+--                                                            --
+--  Open source license information is in the zlib.ads file.  --
+----------------------------------------------------------------
+
+--  $Id: zlib-thin.ads,v 1.11 2004/07/23 06:33:11 vagul Exp $
+
+with Interfaces.C.Strings;
+
+with System;
+
+private package ZLib.Thin is
+
+   --  From zconf.h
+
+   MAX_MEM_LEVEL : constant := 9;         --  zconf.h:105
+                                          --  zconf.h:105
+   MAX_WBITS : constant := 15;      --  zconf.h:115
+                                    --  32K LZ77 window
+                                    --  zconf.h:115
+   SEEK_SET : constant := 8#0000#;  --  zconf.h:244
+                                    --  Seek from beginning of file.
+                                    --  zconf.h:244
+   SEEK_CUR : constant := 1;        --  zconf.h:245
+                                    --  Seek from current position.
+                                    --  zconf.h:245
+   SEEK_END : constant := 2;        --  zconf.h:246
+                                    --  Set file pointer to EOF plus "offset"
+                                    --  zconf.h:246
+
+   type Byte is new Interfaces.C.unsigned_char; --  8 bits
+                                                --  zconf.h:214
+   type UInt is new Interfaces.C.unsigned;      --  16 bits or more
+                                                --  zconf.h:216
+   type Int is new Interfaces.C.int;
+
+   type ULong is new Interfaces.C.unsigned_long;     --  32 bits or more
+                                                     --  zconf.h:217
+   subtype Chars_Ptr is Interfaces.C.Strings.chars_ptr;
+
+   type ULong_Access is access ULong;
+   type Int_Access is access Int;
+
+   subtype Voidp is System.Address;            --  zconf.h:232
+
+   subtype Byte_Access is Voidp;
+
+   Nul : constant Voidp := System.Null_Address;
+   --  end from zconf
+
+   Z_NO_FLUSH : constant := 8#0000#;   --  zlib.h:125
+                                       --  zlib.h:125
+   Z_PARTIAL_FLUSH : constant := 1;       --  zlib.h:126
+                                          --  will be removed, use
+                                          --  Z_SYNC_FLUSH instead
+                                          --  zlib.h:126
+   Z_SYNC_FLUSH : constant := 2;       --  zlib.h:127
+                                       --  zlib.h:127
+   Z_FULL_FLUSH : constant := 3;       --  zlib.h:128
+                                       --  zlib.h:128
+   Z_FINISH : constant := 4;        --  zlib.h:129
+                                    --  zlib.h:129
+   Z_OK : constant := 8#0000#;   --  zlib.h:132
+                                 --  zlib.h:132
+   Z_STREAM_END : constant := 1;       --  zlib.h:133
+                                       --  zlib.h:133
+   Z_NEED_DICT : constant := 2;        --  zlib.h:134
+                                       --  zlib.h:134
+   Z_ERRNO : constant := -1;        --  zlib.h:135
+                                    --  zlib.h:135
+   Z_STREAM_ERROR : constant := -2;       --  zlib.h:136
+                                          --  zlib.h:136
+   Z_DATA_ERROR : constant := -3;      --  zlib.h:137
+                                       --  zlib.h:137
+   Z_MEM_ERROR : constant := -4;       --  zlib.h:138
+                                       --  zlib.h:138
+   Z_BUF_ERROR : constant := -5;       --  zlib.h:139
+                                       --  zlib.h:139
+   Z_VERSION_ERROR : constant := -6;      --  zlib.h:140
+                                          --  zlib.h:140
+   Z_NO_COMPRESSION : constant := 8#0000#;   --  zlib.h:145
+                                             --  zlib.h:145
+   Z_BEST_SPEED : constant := 1;       --  zlib.h:146
+                                       --  zlib.h:146
+   Z_BEST_COMPRESSION : constant := 9;       --  zlib.h:147
+                                             --  zlib.h:147
+   Z_DEFAULT_COMPRESSION : constant := -1;      --  zlib.h:148
+                                                --  zlib.h:148
+   Z_FILTERED : constant := 1;      --  zlib.h:151
+                                    --  zlib.h:151
+   Z_HUFFMAN_ONLY : constant := 2;        --  zlib.h:152
+                                          --  zlib.h:152
+   Z_DEFAULT_STRATEGY : constant := 8#0000#; --  zlib.h:153
+                                             --  zlib.h:153
+   Z_BINARY : constant := 8#0000#;  --  zlib.h:156
+                                    --  zlib.h:156
+   Z_ASCII : constant := 1;      --  zlib.h:157
+                                 --  zlib.h:157
+   Z_UNKNOWN : constant := 2;       --  zlib.h:158
+                                    --  zlib.h:158
+   Z_DEFLATED : constant := 8;      --  zlib.h:161
+                                    --  zlib.h:161
+   Z_NULL : constant := 8#0000#; --  zlib.h:164
+                                 --  for initializing zalloc, zfree, opaque
+                                 --  zlib.h:164
+   type gzFile is new Voidp;                  --  zlib.h:646
+
+   type Z_Stream is private;
+
+   type Z_Streamp is access all Z_Stream;     --  zlib.h:89
+
+   type alloc_func is access function
+     (Opaque : Voidp;
+      Items  : UInt;
+      Size   : UInt)
+      return Voidp; --  zlib.h:63
+
+   type free_func is access procedure (opaque : Voidp; address : Voidp);
+
+   function zlibVersion return Chars_Ptr;
+
+   function Deflate (strm : Z_Streamp; flush : Int) return Int;
+
+   function DeflateEnd (strm : Z_Streamp) return Int;
+
+   function Inflate (strm : Z_Streamp; flush : Int) return Int;
+
+   function InflateEnd (strm : Z_Streamp) return Int;
+
+   function deflateSetDictionary
+     (strm       : Z_Streamp;
+      dictionary : Byte_Access;
+      dictLength : UInt)
+      return       Int;
+
+   function deflateCopy (dest : Z_Streamp; source : Z_Streamp) return Int;
+   --  zlib.h:478
+
+   function deflateReset (strm : Z_Streamp) return Int; -- zlib.h:495
+
+   function deflateParams
+     (strm     : Z_Streamp;
+      level    : Int;
+      strategy : Int)
+      return     Int;       -- zlib.h:506
+
+   function inflateSetDictionary
+     (strm       : Z_Streamp;
+      dictionary : Byte_Access;
+      dictLength : UInt)
+      return       Int; --  zlib.h:548
+
+   function inflateSync (strm : Z_Streamp) return Int;  --  zlib.h:565
+
+   function inflateReset (strm : Z_Streamp) return Int; --  zlib.h:580
+
+   function compress
+     (dest      : Byte_Access;
+      destLen   : ULong_Access;
+      source    : Byte_Access;
+      sourceLen : ULong)
+      return      Int;           -- zlib.h:601
+
+   function compress2
+     (dest      : Byte_Access;
+      destLen   : ULong_Access;
+      source    : Byte_Access;
+      sourceLen : ULong;
+      level     : Int)
+      return      Int;          -- zlib.h:615
+
+   function uncompress
+     (dest      : Byte_Access;
+      destLen   : ULong_Access;
+      source    : Byte_Access;
+      sourceLen : ULong)
+      return      Int;
+
+   function gzopen (path : Chars_Ptr; mode : Chars_Ptr) return gzFile;
+
+   function gzdopen (fd : Int; mode : Chars_Ptr) return gzFile;
+
+   function gzsetparams
+     (file     : gzFile;
+      level    : Int;
+      strategy : Int)
+      return     Int;
+
+   function gzread
+     (file : gzFile;
+      buf  : Voidp;
+      len  : UInt)
+      return Int;
+
+   function gzwrite
+     (file : in gzFile;
+      buf  : in Voidp;
+      len  : in UInt)
+      return Int;
+
+   function gzprintf (file : in gzFile; format : in Chars_Ptr) return Int;
+
+   function gzputs (file : in gzFile; s : in Chars_Ptr) return Int;
+
+   function gzgets
+     (file : gzFile;
+      buf  : Chars_Ptr;
+      len  : Int)
+      return Chars_Ptr;
+
+   function gzputc (file : gzFile; char : Int) return Int;
+
+   function gzgetc (file : gzFile) return Int;
+
+   function gzflush (file : gzFile; flush : Int) return Int;
+
+   function gzseek
+     (file   : gzFile;
+      offset : Int;
+      whence : Int)
+      return   Int;
+
+   function gzrewind (file : gzFile) return Int;
+
+   function gztell (file : gzFile) return Int;
+
+   function gzeof (file : gzFile) return Int;
+
+   function gzclose (file : gzFile) return Int;
+
+   function gzerror (file : gzFile; errnum : Int_Access) return Chars_Ptr;
+
+   function adler32
+     (adler : ULong;
+      buf   : Byte_Access;
+      len   : UInt)
+      return  ULong;
+
+   function crc32
+     (crc  : ULong;
+      buf  : Byte_Access;
+      len  : UInt)
+      return ULong;
+
+   function deflateInit
+     (strm        : Z_Streamp;
+      level       : Int;
+      version     : Chars_Ptr;
+      stream_size : Int)
+      return        Int;
+
+   function deflateInit2
+     (strm        : Z_Streamp;
+      level       : Int;
+      method      : Int;
+      windowBits  : Int;
+      memLevel    : Int;
+      strategy    : Int;
+      version     : Chars_Ptr;
+      stream_size : Int)
+      return        Int;
+
+   function Deflate_Init
+     (strm       : Z_Streamp;
+      level      : Int;
+      method     : Int;
+      windowBits : Int;
+      memLevel   : Int;
+      strategy   : Int)
+      return       Int;
+   pragma Inline (Deflate_Init);
+
+   function inflateInit
+     (strm        : Z_Streamp;
+      version     : Chars_Ptr;
+      stream_size : Int)
+      return        Int;
+
+   function inflateInit2
+     (strm        : in Z_Streamp;
+      windowBits  : in Int;
+      version     : in Chars_Ptr;
+      stream_size : in Int)
+      return      Int;
+
+   function inflateBackInit
+     (strm        : in Z_Streamp;
+      windowBits  : in Int;
+      window      : in Byte_Access;
+      version     : in Chars_Ptr;
+      stream_size : in Int)
+      return      Int;
+   --  Size of window have to be 2**windowBits.
+
+   function Inflate_Init (strm : Z_Streamp; windowBits : Int) return Int;
+   pragma Inline (Inflate_Init);
+
+   function zError (err : Int) return Chars_Ptr;
+
+   function inflateSyncPoint (z : Z_Streamp) return Int;
+
+   function get_crc_table return ULong_Access;
+
+   --  Interface to the available fields of the z_stream structure.
+   --  The application must update next_in and avail_in when avail_in has
+   --  dropped to zero. It must update next_out and avail_out when avail_out
+   --  has dropped to zero. The application must initialize zalloc, zfree and
+   --  opaque before calling the init function.
+
+   procedure Set_In
+     (Strm   : in out Z_Stream;
+      Buffer : in Voidp;
+      Size   : in UInt);
+   pragma Inline (Set_In);
+
+   procedure Set_Out
+     (Strm   : in out Z_Stream;
+      Buffer : in Voidp;
+      Size   : in UInt);
+   pragma Inline (Set_Out);
+
+   procedure Set_Mem_Func
+     (Strm   : in out Z_Stream;
+      Opaque : in Voidp;
+      Alloc  : in alloc_func;
+      Free   : in free_func);
+   pragma Inline (Set_Mem_Func);
+
+   function Last_Error_Message (Strm : in Z_Stream) return String;
+   pragma Inline (Last_Error_Message);
+
+   function Avail_Out (Strm : in Z_Stream) return UInt;
+   pragma Inline (Avail_Out);
+
+   function Avail_In (Strm : in Z_Stream) return UInt;
+   pragma Inline (Avail_In);
+
+   function Total_In (Strm : in Z_Stream) return ULong;
+   pragma Inline (Total_In);
+
+   function Total_Out (Strm : in Z_Stream) return ULong;
+   pragma Inline (Total_Out);
+
+   function inflateCopy
+     (dest   : in Z_Streamp;
+      Source : in Z_Streamp)
+      return Int;
+
+   function compressBound (Source_Len : in ULong) return ULong;
+
+   function deflateBound
+     (Strm       : in Z_Streamp;
+      Source_Len : in ULong)
+      return     ULong;
+
+   function gzungetc (C : in Int; File : in  gzFile) return Int;
+
+   function zlibCompileFlags return ULong;
+
+private
+
+   type Z_Stream is record            -- zlib.h:68
+      Next_In   : Voidp      := Nul;  -- next input byte
+      Avail_In  : UInt       := 0;    -- number of bytes available at next_in
+      Total_In  : ULong      := 0;    -- total nb of input bytes read so far
+      Next_Out  : Voidp      := Nul;  -- next output byte should be put there
+      Avail_Out : UInt       := 0;    -- remaining free space at next_out
+      Total_Out : ULong      := 0;    -- total nb of bytes output so far
+      msg       : Chars_Ptr;          -- last error message, NULL if no error
+      state     : Voidp;              -- not visible by applications
+      zalloc    : alloc_func := null; -- used to allocate the internal state
+      zfree     : free_func  := null; -- used to free the internal state
+      opaque    : Voidp;              -- private data object passed to
+                                      --  zalloc and zfree
+      data_type : Int;                -- best guess about the data type:
+                                      --  ascii or binary
+      adler     : ULong;              -- adler32 value of the uncompressed
+                                      --  data
+      reserved  : ULong;              -- reserved for future use
+   end record;
+
+   pragma Convention (C, Z_Stream);
+
+   pragma Import (C, zlibVersion, "zlibVersion");
+   pragma Import (C, Deflate, "deflate");
+   pragma Import (C, DeflateEnd, "deflateEnd");
+   pragma Import (C, Inflate, "inflate");
+   pragma Import (C, InflateEnd, "inflateEnd");
+   pragma Import (C, deflateSetDictionary, "deflateSetDictionary");
+   pragma Import (C, deflateCopy, "deflateCopy");
+   pragma Import (C, deflateReset, "deflateReset");
+   pragma Import (C, deflateParams, "deflateParams");
+   pragma Import (C, inflateSetDictionary, "inflateSetDictionary");
+   pragma Import (C, inflateSync, "inflateSync");
+   pragma Import (C, inflateReset, "inflateReset");
+   pragma Import (C, compress, "compress");
+   pragma Import (C, compress2, "compress2");
+   pragma Import (C, uncompress, "uncompress");
+   pragma Import (C, gzopen, "gzopen");
+   pragma Import (C, gzdopen, "gzdopen");
+   pragma Import (C, gzsetparams, "gzsetparams");
+   pragma Import (C, gzread, "gzread");
+   pragma Import (C, gzwrite, "gzwrite");
+   pragma Import (C, gzprintf, "gzprintf");
+   pragma Import (C, gzputs, "gzputs");
+   pragma Import (C, gzgets, "gzgets");
+   pragma Import (C, gzputc, "gzputc");
+   pragma Import (C, gzgetc, "gzgetc");
+   pragma Import (C, gzflush, "gzflush");
+   pragma Import (C, gzseek, "gzseek");
+   pragma Import (C, gzrewind, "gzrewind");
+   pragma Import (C, gztell, "gztell");
+   pragma Import (C, gzeof, "gzeof");
+   pragma Import (C, gzclose, "gzclose");
+   pragma Import (C, gzerror, "gzerror");
+   pragma Import (C, adler32, "adler32");
+   pragma Import (C, crc32, "crc32");
+   pragma Import (C, deflateInit, "deflateInit_");
+   pragma Import (C, inflateInit, "inflateInit_");
+   pragma Import (C, deflateInit2, "deflateInit2_");
+   pragma Import (C, inflateInit2, "inflateInit2_");
+   pragma Import (C, zError, "zError");
+   pragma Import (C, inflateSyncPoint, "inflateSyncPoint");
+   pragma Import (C, get_crc_table, "get_crc_table");
+
+   --  since zlib 1.2.0:
+
+   pragma Import (C, inflateCopy, "inflateCopy");
+   pragma Import (C, compressBound, "compressBound");
+   pragma Import (C, deflateBound, "deflateBound");
+   pragma Import (C, gzungetc, "gzungetc");
+   pragma Import (C, zlibCompileFlags, "zlibCompileFlags");
+
+   pragma Import (C, inflateBackInit, "inflateBackInit_");
+
+   --  I stopped binding the inflateBack routines, becouse realize that
+   --  it does not support zlib and gzip headers for now, and have no
+   --  symmetric deflateBack routines.
+   --  ZLib-Ada is symmetric regarding deflate/inflate data transformation
+   --  and has a similar generic callback interface for the
+   --  deflate/inflate transformation based on the regular Deflate/Inflate
+   --  routines.
+
+   --  pragma Import (C, inflateBack, "inflateBack");
+   --  pragma Import (C, inflateBackEnd, "inflateBackEnd");
+
+end ZLib.Thin;
diff --git a/compat/zlib/contrib/ada/zlib.adb b/compat/zlib/contrib/ada/zlib.adb
new file mode 100644
index 0000000..8b6fd68
--- /dev/null
+++ b/compat/zlib/contrib/ada/zlib.adb
@@ -0,0 +1,701 @@
+----------------------------------------------------------------
+--  ZLib for Ada thick binding.                               --
+--                                                            --
+--  Copyright (C) 2002-2004 Dmitriy Anisimkov                 --
+--                                                            --
+--  Open source license information is in the zlib.ads file.  --
+----------------------------------------------------------------
+
+--  $Id: zlib.adb,v 1.31 2004/09/06 06:53:19 vagul Exp $
+
+with Ada.Exceptions;
+with Ada.Unchecked_Conversion;
+with Ada.Unchecked_Deallocation;
+
+with Interfaces.C.Strings;
+
+with ZLib.Thin;
+
+package body ZLib is
+
+   use type Thin.Int;
+
+   type Z_Stream is new Thin.Z_Stream;
+
+   type Return_Code_Enum is
+      (OK,
+       STREAM_END,
+       NEED_DICT,
+       ERRNO,
+       STREAM_ERROR,
+       DATA_ERROR,
+       MEM_ERROR,
+       BUF_ERROR,
+       VERSION_ERROR);
+
+   type Flate_Step_Function is access
+     function (Strm : in Thin.Z_Streamp; Flush : in Thin.Int) return Thin.Int;
+   pragma Convention (C, Flate_Step_Function);
+
+   type Flate_End_Function is access
+      function (Ctrm : in Thin.Z_Streamp) return Thin.Int;
+   pragma Convention (C, Flate_End_Function);
+
+   type Flate_Type is record
+      Step : Flate_Step_Function;
+      Done : Flate_End_Function;
+   end record;
+
+   subtype Footer_Array is Stream_Element_Array (1 .. 8);
+
+   Simple_GZip_Header : constant Stream_Element_Array (1 .. 10)
+     := (16#1f#, 16#8b#,                 --  Magic header
+         16#08#,                         --  Z_DEFLATED
+         16#00#,                         --  Flags
+         16#00#, 16#00#, 16#00#, 16#00#, --  Time
+         16#00#,                         --  XFlags
+         16#03#                          --  OS code
+        );
+   --  The simplest gzip header is not for informational, but just for
+   --  gzip format compatibility.
+   --  Note that some code below is using assumption
+   --  Simple_GZip_Header'Last > Footer_Array'Last, so do not make
+   --  Simple_GZip_Header'Last <= Footer_Array'Last.
+
+   Return_Code : constant array (Thin.Int range <>) of Return_Code_Enum
+     := (0 => OK,
+         1 => STREAM_END,
+         2 => NEED_DICT,
+        -1 => ERRNO,
+        -2 => STREAM_ERROR,
+        -3 => DATA_ERROR,
+        -4 => MEM_ERROR,
+        -5 => BUF_ERROR,
+        -6 => VERSION_ERROR);
+
+   Flate : constant array (Boolean) of Flate_Type
+     := (True  => (Step => Thin.Deflate'Access,
+                   Done => Thin.DeflateEnd'Access),
+         False => (Step => Thin.Inflate'Access,
+                   Done => Thin.InflateEnd'Access));
+
+   Flush_Finish : constant array (Boolean) of Flush_Mode
+     := (True => Finish, False => No_Flush);
+
+   procedure Raise_Error (Stream : in Z_Stream);
+   pragma Inline (Raise_Error);
+
+   procedure Raise_Error (Message : in String);
+   pragma Inline (Raise_Error);
+
+   procedure Check_Error (Stream : in Z_Stream; Code : in Thin.Int);
+
+   procedure Free is new Ada.Unchecked_Deallocation
+      (Z_Stream, Z_Stream_Access);
+
+   function To_Thin_Access is new Ada.Unchecked_Conversion
+     (Z_Stream_Access, Thin.Z_Streamp);
+
+   procedure Translate_GZip
+     (Filter    : in out Filter_Type;
+      In_Data   : in     Ada.Streams.Stream_Element_Array;
+      In_Last   :    out Ada.Streams.Stream_Element_Offset;
+      Out_Data  :    out Ada.Streams.Stream_Element_Array;
+      Out_Last  :    out Ada.Streams.Stream_Element_Offset;
+      Flush     : in     Flush_Mode);
+   --  Separate translate routine for make gzip header.
+
+   procedure Translate_Auto
+     (Filter    : in out Filter_Type;
+      In_Data   : in     Ada.Streams.Stream_Element_Array;
+      In_Last   :    out Ada.Streams.Stream_Element_Offset;
+      Out_Data  :    out Ada.Streams.Stream_Element_Array;
+      Out_Last  :    out Ada.Streams.Stream_Element_Offset;
+      Flush     : in     Flush_Mode);
+   --  translate routine without additional headers.
+
+   -----------------
+   -- Check_Error --
+   -----------------
+
+   procedure Check_Error (Stream : in Z_Stream; Code : in Thin.Int) is
+      use type Thin.Int;
+   begin
+      if Code /= Thin.Z_OK then
+         Raise_Error
+            (Return_Code_Enum'Image (Return_Code (Code))
+              & ": " & Last_Error_Message (Stream));
+      end if;
+   end Check_Error;
+
+   -----------
+   -- Close --
+   -----------
+
+   procedure Close
+     (Filter       : in out Filter_Type;
+      Ignore_Error : in     Boolean := False)
+   is
+      Code : Thin.Int;
+   begin
+      if not Ignore_Error and then not Is_Open (Filter) then
+         raise Status_Error;
+      end if;
+
+      Code := Flate (Filter.Compression).Done (To_Thin_Access (Filter.Strm));
+
+      if Ignore_Error or else Code = Thin.Z_OK then
+         Free (Filter.Strm);
+      else
+         declare
+            Error_Message : constant String
+              := Last_Error_Message (Filter.Strm.all);
+         begin
+            Free (Filter.Strm);
+            Ada.Exceptions.Raise_Exception
+               (ZLib_Error'Identity,
+                Return_Code_Enum'Image (Return_Code (Code))
+                  & ": " & Error_Message);
+         end;
+      end if;
+   end Close;
+
+   -----------
+   -- CRC32 --
+   -----------
+
+   function CRC32
+     (CRC  : in Unsigned_32;
+      Data : in Ada.Streams.Stream_Element_Array)
+      return Unsigned_32
+   is
+      use Thin;
+   begin
+      return Unsigned_32 (crc32 (ULong (CRC),
+                                 Data'Address,
+                                 Data'Length));
+   end CRC32;
+
+   procedure CRC32
+     (CRC  : in out Unsigned_32;
+      Data : in     Ada.Streams.Stream_Element_Array) is
+   begin
+      CRC := CRC32 (CRC, Data);
+   end CRC32;
+
+   ------------------
+   -- Deflate_Init --
+   ------------------
+
+   procedure Deflate_Init
+     (Filter       : in out Filter_Type;
+      Level        : in     Compression_Level  := Default_Compression;
+      Strategy     : in     Strategy_Type      := Default_Strategy;
+      Method       : in     Compression_Method := Deflated;
+      Window_Bits  : in     Window_Bits_Type   := Default_Window_Bits;
+      Memory_Level : in     Memory_Level_Type  := Default_Memory_Level;
+      Header       : in     Header_Type        := Default)
+   is
+      use type Thin.Int;
+      Win_Bits : Thin.Int := Thin.Int (Window_Bits);
+   begin
+      if Is_Open (Filter) then
+         raise Status_Error;
+      end if;
+
+      --  We allow ZLib to make header only in case of default header type.
+      --  Otherwise we would either do header by ourselfs, or do not do
+      --  header at all.
+
+      if Header = None or else Header = GZip then
+         Win_Bits := -Win_Bits;
+      end if;
+
+      --  For the GZip CRC calculation and make headers.
+
+      if Header = GZip then
+         Filter.CRC    := 0;
+         Filter.Offset := Simple_GZip_Header'First;
+      else
+         Filter.Offset := Simple_GZip_Header'Last + 1;
+      end if;
+
+      Filter.Strm        := new Z_Stream;
+      Filter.Compression := True;
+      Filter.Stream_End  := False;
+      Filter.Header      := Header;
+
+      if Thin.Deflate_Init
+           (To_Thin_Access (Filter.Strm),
+            Level      => Thin.Int (Level),
+            method     => Thin.Int (Method),
+            windowBits => Win_Bits,
+            memLevel   => Thin.Int (Memory_Level),
+            strategy   => Thin.Int (Strategy)) /= Thin.Z_OK
+      then
+         Raise_Error (Filter.Strm.all);
+      end if;
+   end Deflate_Init;
+
+   -----------
+   -- Flush --
+   -----------
+
+   procedure Flush
+     (Filter    : in out Filter_Type;
+      Out_Data  :    out Ada.Streams.Stream_Element_Array;
+      Out_Last  :    out Ada.Streams.Stream_Element_Offset;
+      Flush     : in     Flush_Mode)
+   is
+      No_Data : Stream_Element_Array := (1 .. 0 => 0);
+      Last    : Stream_Element_Offset;
+   begin
+      Translate (Filter, No_Data, Last, Out_Data, Out_Last, Flush);
+   end Flush;
+
+   -----------------------
+   -- Generic_Translate --
+   -----------------------
+
+   procedure Generic_Translate
+     (Filter          : in out ZLib.Filter_Type;
+      In_Buffer_Size  : in     Integer := Default_Buffer_Size;
+      Out_Buffer_Size : in     Integer := Default_Buffer_Size)
+   is
+      In_Buffer  : Stream_Element_Array
+                     (1 .. Stream_Element_Offset (In_Buffer_Size));
+      Out_Buffer : Stream_Element_Array
+                     (1 .. Stream_Element_Offset (Out_Buffer_Size));
+      Last       : Stream_Element_Offset;
+      In_Last    : Stream_Element_Offset;
+      In_First   : Stream_Element_Offset;
+      Out_Last   : Stream_Element_Offset;
+   begin
+      Main : loop
+         Data_In (In_Buffer, Last);
+
+         In_First := In_Buffer'First;
+
+         loop
+            Translate
+              (Filter   => Filter,
+               In_Data  => In_Buffer (In_First .. Last),
+               In_Last  => In_Last,
+               Out_Data => Out_Buffer,
+               Out_Last => Out_Last,
+               Flush    => Flush_Finish (Last < In_Buffer'First));
+
+            if Out_Buffer'First <= Out_Last then
+               Data_Out (Out_Buffer (Out_Buffer'First .. Out_Last));
+            end if;
+
+            exit Main when Stream_End (Filter);
+
+            --  The end of in buffer.
+
+            exit when In_Last = Last;
+
+            In_First := In_Last + 1;
+         end loop;
+      end loop Main;
+
+   end Generic_Translate;
+
+   ------------------
+   -- Inflate_Init --
+   ------------------
+
+   procedure Inflate_Init
+     (Filter      : in out Filter_Type;
+      Window_Bits : in     Window_Bits_Type := Default_Window_Bits;
+      Header      : in     Header_Type      := Default)
+   is
+      use type Thin.Int;
+      Win_Bits : Thin.Int := Thin.Int (Window_Bits);
+
+      procedure Check_Version;
+      --  Check the latest header types compatibility.
+
+      procedure Check_Version is
+      begin
+         if Version <= "1.1.4" then
+            Raise_Error
+              ("Inflate header type " & Header_Type'Image (Header)
+               & " incompatible with ZLib version " & Version);
+         end if;
+      end Check_Version;
+
+   begin
+      if Is_Open (Filter) then
+         raise Status_Error;
+      end if;
+
+      case Header is
+         when None =>
+            Check_Version;
+
+            --  Inflate data without headers determined
+            --  by negative Win_Bits.
+
+            Win_Bits := -Win_Bits;
+         when GZip =>
+            Check_Version;
+
+            --  Inflate gzip data defined by flag 16.
+
+            Win_Bits := Win_Bits + 16;
+         when Auto =>
+            Check_Version;
+
+            --  Inflate with automatic detection
+            --  of gzip or native header defined by flag 32.
+
+            Win_Bits := Win_Bits + 32;
+         when Default => null;
+      end case;
+
+      Filter.Strm        := new Z_Stream;
+      Filter.Compression := False;
+      Filter.Stream_End  := False;
+      Filter.Header      := Header;
+
+      if Thin.Inflate_Init
+         (To_Thin_Access (Filter.Strm), Win_Bits) /= Thin.Z_OK
+      then
+         Raise_Error (Filter.Strm.all);
+      end if;
+   end Inflate_Init;
+
+   -------------
+   -- Is_Open --
+   -------------
+
+   function Is_Open (Filter : in Filter_Type) return Boolean is
+   begin
+      return Filter.Strm /= null;
+   end Is_Open;
+
+   -----------------
+   -- Raise_Error --
+   -----------------
+
+   procedure Raise_Error (Message : in String) is
+   begin
+      Ada.Exceptions.Raise_Exception (ZLib_Error'Identity, Message);
+   end Raise_Error;
+
+   procedure Raise_Error (Stream : in Z_Stream) is
+   begin
+      Raise_Error (Last_Error_Message (Stream));
+   end Raise_Error;
+
+   ----------
+   -- Read --
+   ----------
+
+   procedure Read
+     (Filter : in out Filter_Type;
+      Item   :    out Ada.Streams.Stream_Element_Array;
+      Last   :    out Ada.Streams.Stream_Element_Offset;
+      Flush  : in     Flush_Mode := No_Flush)
+   is
+      In_Last    : Stream_Element_Offset;
+      Item_First : Ada.Streams.Stream_Element_Offset := Item'First;
+      V_Flush    : Flush_Mode := Flush;
+
+   begin
+      pragma Assert (Rest_First in Buffer'First .. Buffer'Last + 1);
+      pragma Assert (Rest_Last in Buffer'First - 1 .. Buffer'Last);
+
+      loop
+         if Rest_Last = Buffer'First - 1 then
+            V_Flush := Finish;
+
+         elsif Rest_First > Rest_Last then
+            Read (Buffer, Rest_Last);
+            Rest_First := Buffer'First;
+
+            if Rest_Last < Buffer'First then
+               V_Flush := Finish;
+            end if;
+         end if;
+
+         Translate
+           (Filter   => Filter,
+            In_Data  => Buffer (Rest_First .. Rest_Last),
+            In_Last  => In_Last,
+            Out_Data => Item (Item_First .. Item'Last),
+            Out_Last => Last,
+            Flush    => V_Flush);
+
+         Rest_First := In_Last + 1;
+
+         exit when Stream_End (Filter)
+           or else Last = Item'Last
+           or else (Last >= Item'First and then Allow_Read_Some);
+
+         Item_First := Last + 1;
+      end loop;
+   end Read;
+
+   ----------------
+   -- Stream_End --
+   ----------------
+
+   function Stream_End (Filter : in Filter_Type) return Boolean is
+   begin
+      if Filter.Header = GZip and Filter.Compression then
+         return Filter.Stream_End
+            and then Filter.Offset = Footer_Array'Last + 1;
+      else
+         return Filter.Stream_End;
+      end if;
+   end Stream_End;
+
+   --------------
+   -- Total_In --
+   --------------
+
+   function Total_In (Filter : in Filter_Type) return Count is
+   begin
+      return Count (Thin.Total_In (To_Thin_Access (Filter.Strm).all));
+   end Total_In;
+
+   ---------------
+   -- Total_Out --
+   ---------------
+
+   function Total_Out (Filter : in Filter_Type) return Count is
+   begin
+      return Count (Thin.Total_Out (To_Thin_Access (Filter.Strm).all));
+   end Total_Out;
+
+   ---------------
+   -- Translate --
+   ---------------
+
+   procedure Translate
+     (Filter    : in out Filter_Type;
+      In_Data   : in     Ada.Streams.Stream_Element_Array;
+      In_Last   :    out Ada.Streams.Stream_Element_Offset;
+      Out_Data  :    out Ada.Streams.Stream_Element_Array;
+      Out_Last  :    out Ada.Streams.Stream_Element_Offset;
+      Flush     : in     Flush_Mode) is
+   begin
+      if Filter.Header = GZip and then Filter.Compression then
+         Translate_GZip
+           (Filter   => Filter,
+            In_Data  => In_Data,
+            In_Last  => In_Last,
+            Out_Data => Out_Data,
+            Out_Last => Out_Last,
+            Flush    => Flush);
+      else
+         Translate_Auto
+           (Filter   => Filter,
+            In_Data  => In_Data,
+            In_Last  => In_Last,
+            Out_Data => Out_Data,
+            Out_Last => Out_Last,
+            Flush    => Flush);
+      end if;
+   end Translate;
+
+   --------------------
+   -- Translate_Auto --
+   --------------------
+
+   procedure Translate_Auto
+     (Filter    : in out Filter_Type;
+      In_Data   : in     Ada.Streams.Stream_Element_Array;
+      In_Last   :    out Ada.Streams.Stream_Element_Offset;
+      Out_Data  :    out Ada.Streams.Stream_Element_Array;
+      Out_Last  :    out Ada.Streams.Stream_Element_Offset;
+      Flush     : in     Flush_Mode)
+   is
+      use type Thin.Int;
+      Code : Thin.Int;
+
+   begin
+      if not Is_Open (Filter) then
+         raise Status_Error;
+      end if;
+
+      if Out_Data'Length = 0 and then In_Data'Length = 0 then
+         raise Constraint_Error;
+      end if;
+
+      Set_Out (Filter.Strm.all, Out_Data'Address, Out_Data'Length);
+      Set_In  (Filter.Strm.all, In_Data'Address, In_Data'Length);
+
+      Code := Flate (Filter.Compression).Step
+        (To_Thin_Access (Filter.Strm),
+         Thin.Int (Flush));
+
+      if Code = Thin.Z_STREAM_END then
+         Filter.Stream_End := True;
+      else
+         Check_Error (Filter.Strm.all, Code);
+      end if;
+
+      In_Last  := In_Data'Last
+         - Stream_Element_Offset (Avail_In (Filter.Strm.all));
+      Out_Last := Out_Data'Last
+         - Stream_Element_Offset (Avail_Out (Filter.Strm.all));
+   end Translate_Auto;
+
+   --------------------
+   -- Translate_GZip --
+   --------------------
+
+   procedure Translate_GZip
+     (Filter    : in out Filter_Type;
+      In_Data   : in     Ada.Streams.Stream_Element_Array;
+      In_Last   :    out Ada.Streams.Stream_Element_Offset;
+      Out_Data  :    out Ada.Streams.Stream_Element_Array;
+      Out_Last  :    out Ada.Streams.Stream_Element_Offset;
+      Flush     : in     Flush_Mode)
+   is
+      Out_First : Stream_Element_Offset;
+
+      procedure Add_Data (Data : in Stream_Element_Array);
+      --  Add data to stream from the Filter.Offset till necessary,
+      --  used for add gzip headr/footer.
+
+      procedure Put_32
+        (Item : in out Stream_Element_Array;
+         Data : in     Unsigned_32);
+      pragma Inline (Put_32);
+
+      --------------
+      -- Add_Data --
+      --------------
+
+      procedure Add_Data (Data : in Stream_Element_Array) is
+         Data_First : Stream_Element_Offset renames Filter.Offset;
+         Data_Last  : Stream_Element_Offset;
+         Data_Len   : Stream_Element_Offset; --  -1
+         Out_Len    : Stream_Element_Offset; --  -1
+      begin
+         Out_First := Out_Last + 1;
+
+         if Data_First > Data'Last then
+            return;
+         end if;
+
+         Data_Len  := Data'Last     - Data_First;
+         Out_Len   := Out_Data'Last - Out_First;
+
+         if Data_Len <= Out_Len then
+            Out_Last  := Out_First  + Data_Len;
+            Data_Last := Data'Last;
+         else
+            Out_Last  := Out_Data'Last;
+            Data_Last := Data_First + Out_Len;
+         end if;
+
+         Out_Data (Out_First .. Out_Last) := Data (Data_First .. Data_Last);
+
+         Data_First := Data_Last + 1;
+         Out_First  := Out_Last + 1;
+      end Add_Data;
+
+      ------------
+      -- Put_32 --
+      ------------
+
+      procedure Put_32
+        (Item : in out Stream_Element_Array;
+         Data : in     Unsigned_32)
+      is
+         D : Unsigned_32 := Data;
+      begin
+         for J in Item'First .. Item'First + 3 loop
+            Item (J) := Stream_Element (D and 16#FF#);
+            D := Shift_Right (D, 8);
+         end loop;
+      end Put_32;
+
+   begin
+      Out_Last := Out_Data'First - 1;
+
+      if not Filter.Stream_End then
+         Add_Data (Simple_GZip_Header);
+
+         Translate_Auto
+           (Filter   => Filter,
+            In_Data  => In_Data,
+            In_Last  => In_Last,
+            Out_Data => Out_Data (Out_First .. Out_Data'Last),
+            Out_Last => Out_Last,
+            Flush    => Flush);
+
+         CRC32 (Filter.CRC, In_Data (In_Data'First .. In_Last));
+      end if;
+
+      if Filter.Stream_End and then Out_Last <= Out_Data'Last then
+         --  This detection method would work only when
+         --  Simple_GZip_Header'Last > Footer_Array'Last
+
+         if Filter.Offset = Simple_GZip_Header'Last + 1 then
+            Filter.Offset := Footer_Array'First;
+         end if;
+
+         declare
+            Footer : Footer_Array;
+         begin
+            Put_32 (Footer, Filter.CRC);
+            Put_32 (Footer (Footer'First + 4 .. Footer'Last),
+                    Unsigned_32 (Total_In (Filter)));
+            Add_Data (Footer);
+         end;
+      end if;
+   end Translate_GZip;
+
+   -------------
+   -- Version --
+   -------------
+
+   function Version return String is
+   begin
+      return Interfaces.C.Strings.Value (Thin.zlibVersion);
+   end Version;
+
+   -----------
+   -- Write --
+   -----------
+
+   procedure Write
+     (Filter : in out Filter_Type;
+      Item   : in     Ada.Streams.Stream_Element_Array;
+      Flush  : in     Flush_Mode := No_Flush)
+   is
+      Buffer   : Stream_Element_Array (1 .. Buffer_Size);
+      In_Last  : Stream_Element_Offset;
+      Out_Last : Stream_Element_Offset;
+      In_First : Stream_Element_Offset := Item'First;
+   begin
+      if Item'Length = 0 and Flush = No_Flush then
+         return;
+      end if;
+
+      loop
+         Translate
+           (Filter   => Filter,
+            In_Data  => Item (In_First .. Item'Last),
+            In_Last  => In_Last,
+            Out_Data => Buffer,
+            Out_Last => Out_Last,
+            Flush    => Flush);
+
+         if Out_Last >= Buffer'First then
+            Write (Buffer (1 .. Out_Last));
+         end if;
+
+         exit when In_Last = Item'Last or Stream_End (Filter);
+
+         In_First := In_Last + 1;
+      end loop;
+   end Write;
+
+end ZLib;
diff --git a/compat/zlib/contrib/ada/zlib.ads b/compat/zlib/contrib/ada/zlib.ads
new file mode 100644
index 0000000..79ffc40
--- /dev/null
+++ b/compat/zlib/contrib/ada/zlib.ads
@@ -0,0 +1,328 @@
+------------------------------------------------------------------------------
+--                      ZLib for Ada thick binding.                         --
+--                                                                          --
+--              Copyright (C) 2002-2004 Dmitriy Anisimkov                   --
+--                                                                          --
+--  This library is free software; you can redistribute it and/or modify    --
+--  it under the terms of the GNU General Public License as published by    --
+--  the Free Software Foundation; either version 2 of the License, or (at   --
+--  your option) any later version.                                         --
+--                                                                          --
+--  This library is distributed in the hope that it will be useful, but     --
+--  WITHOUT ANY WARRANTY; without even the implied warranty of              --
+--  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU       --
+--  General Public License for more details.                                --
+--                                                                          --
+--  You should have received a copy of the GNU General Public License       --
+--  along with this library; if not, write to the Free Software Foundation, --
+--  Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.          --
+--                                                                          --
+--  As a special exception, if other files instantiate generics from this   --
+--  unit, or you link this unit with other files to produce an executable,  --
+--  this  unit  does not  by itself cause  the resulting executable to be   --
+--  covered by the GNU General Public License. This exception does not      --
+--  however invalidate any other reasons why the executable file  might be  --
+--  covered by the  GNU Public License.                                     --
+------------------------------------------------------------------------------
+
+--  $Id: zlib.ads,v 1.26 2004/09/06 06:53:19 vagul Exp $
+
+with Ada.Streams;
+
+with Interfaces;
+
+package ZLib is
+
+   ZLib_Error   : exception;
+   Status_Error : exception;
+
+   type Compression_Level is new Integer range -1 .. 9;
+
+   type Flush_Mode is private;
+
+   type Compression_Method is private;
+
+   type Window_Bits_Type is new Integer range 8 .. 15;
+
+   type Memory_Level_Type is new Integer range 1 .. 9;
+
+   type Unsigned_32 is new Interfaces.Unsigned_32;
+
+   type Strategy_Type is private;
+
+   type Header_Type is (None, Auto, Default, GZip);
+   --  Header type usage have a some limitation for inflate.
+   --  See comment for Inflate_Init.
+
+   subtype Count is Ada.Streams.Stream_Element_Count;
+
+   Default_Memory_Level : constant Memory_Level_Type := 8;
+   Default_Window_Bits  : constant Window_Bits_Type  := 15;
+
+   ----------------------------------
+   -- Compression method constants --
+   ----------------------------------
+
+   Deflated : constant Compression_Method;
+   --  Only one method allowed in this ZLib version
+
+   ---------------------------------
+   -- Compression level constants --
+   ---------------------------------
+
+   No_Compression      : constant Compression_Level := 0;
+   Best_Speed          : constant Compression_Level := 1;
+   Best_Compression    : constant Compression_Level := 9;
+   Default_Compression : constant Compression_Level := -1;
+
+   --------------------------
+   -- Flush mode constants --
+   --------------------------
+
+   No_Flush      : constant Flush_Mode;
+   --  Regular way for compression, no flush
+
+   Partial_Flush : constant Flush_Mode;
+   --  Will be removed, use Z_SYNC_FLUSH instead
+
+   Sync_Flush    : constant Flush_Mode;
+   --  All pending output is flushed to the output buffer and the output
+   --  is aligned on a byte boundary, so that the decompressor can get all
+   --  input data available so far. (In particular avail_in is zero after the
+   --  call if enough output space has been provided  before the call.)
+   --  Flushing may degrade compression for some compression algorithms and so
+   --  it should be used only when necessary.
+
+   Block_Flush   : constant Flush_Mode;
+   --  Z_BLOCK requests that inflate() stop
+   --  if and when it get to the next deflate block boundary. When decoding the
+   --  zlib or gzip format, this will cause inflate() to return immediately
+   --  after the header and before the first block. When doing a raw inflate,
+   --  inflate() will go ahead and process the first block, and will return
+   --  when it gets to the end of that block, or when it runs out of data.
+
+   Full_Flush    : constant Flush_Mode;
+   --  All output is flushed as with SYNC_FLUSH, and the compression state
+   --  is reset so that decompression can restart from this point if previous
+   --  compressed data has been damaged or if random access is desired. Using
+   --  Full_Flush too often can seriously degrade the compression.
+
+   Finish        : constant Flush_Mode;
+   --  Just for tell the compressor that input data is complete.
+
+   ------------------------------------
+   -- Compression strategy constants --
+   ------------------------------------
+
+   --  RLE stategy could be used only in version 1.2.0 and later.
+
+   Filtered         : constant Strategy_Type;
+   Huffman_Only     : constant Strategy_Type;
+   RLE              : constant Strategy_Type;
+   Default_Strategy : constant Strategy_Type;
+
+   Default_Buffer_Size : constant := 4096;
+
+   type Filter_Type is tagged limited private;
+   --  The filter is for compression and for decompression.
+   --  The usage of the type is depend of its initialization.
+
+   function Version return String;
+   pragma Inline (Version);
+   --  Return string representation of the ZLib version.
+
+   procedure Deflate_Init
+     (Filter       : in out Filter_Type;
+      Level        : in     Compression_Level  := Default_Compression;
+      Strategy     : in     Strategy_Type      := Default_Strategy;
+      Method       : in     Compression_Method := Deflated;
+      Window_Bits  : in     Window_Bits_Type   := Default_Window_Bits;
+      Memory_Level : in     Memory_Level_Type  := Default_Memory_Level;
+      Header       : in     Header_Type        := Default);
+   --  Compressor initialization.
+   --  When Header parameter is Auto or Default, then default zlib header
+   --  would be provided for compressed data.
+   --  When Header is GZip, then gzip header would be set instead of
+   --  default header.
+   --  When Header is None, no header would be set for compressed data.
+
+   procedure Inflate_Init
+     (Filter      : in out Filter_Type;
+      Window_Bits : in     Window_Bits_Type := Default_Window_Bits;
+      Header      : in     Header_Type      := Default);
+   --  Decompressor initialization.
+   --  Default header type mean that ZLib default header is expecting in the
+   --  input compressed stream.
+   --  Header type None mean that no header is expecting in the input stream.
+   --  GZip header type mean that GZip header is expecting in the
+   --  input compressed stream.
+   --  Auto header type mean that header type (GZip or Native) would be
+   --  detected automatically in the input stream.
+   --  Note that header types parameter values None, GZip and Auto are
+   --  supported for inflate routine only in ZLib versions 1.2.0.2 and later.
+   --  Deflate_Init is supporting all header types.
+
+   function Is_Open (Filter : in Filter_Type) return Boolean;
+   pragma Inline (Is_Open);
+   --  Is the filter opened for compression or decompression.
+
+   procedure Close
+     (Filter       : in out Filter_Type;
+      Ignore_Error : in     Boolean := False);
+   --  Closing the compression or decompressor.
+   --  If stream is closing before the complete and Ignore_Error is False,
+   --  The exception would be raised.
+
+   generic
+      with procedure Data_In
+        (Item : out Ada.Streams.Stream_Element_Array;
+         Last : out Ada.Streams.Stream_Element_Offset);
+      with procedure Data_Out
+        (Item : in Ada.Streams.Stream_Element_Array);
+   procedure Generic_Translate
+     (Filter          : in out Filter_Type;
+      In_Buffer_Size  : in     Integer := Default_Buffer_Size;
+      Out_Buffer_Size : in     Integer := Default_Buffer_Size);
+   --  Compress/decompress data fetch from Data_In routine and pass the result
+   --  to the Data_Out routine. User should provide Data_In and Data_Out
+   --  for compression/decompression data flow.
+   --  Compression or decompression depend on Filter initialization.
+
+   function Total_In (Filter : in Filter_Type) return Count;
+   pragma Inline (Total_In);
+   --  Returns total number of input bytes read so far
+
+   function Total_Out (Filter : in Filter_Type) return Count;
+   pragma Inline (Total_Out);
+   --  Returns total number of bytes output so far
+
+   function CRC32
+     (CRC    : in Unsigned_32;
+      Data   : in Ada.Streams.Stream_Element_Array)
+      return Unsigned_32;
+   pragma Inline (CRC32);
+   --  Compute CRC32, it could be necessary for make gzip format
+
+   procedure CRC32
+     (CRC  : in out Unsigned_32;
+      Data : in     Ada.Streams.Stream_Element_Array);
+   pragma Inline (CRC32);
+   --  Compute CRC32, it could be necessary for make gzip format
+
+   -------------------------------------------------
+   --  Below is more complex low level routines.  --
+   -------------------------------------------------
+
+   procedure Translate
+     (Filter    : in out Filter_Type;
+      In_Data   : in     Ada.Streams.Stream_Element_Array;
+      In_Last   :    out Ada.Streams.Stream_Element_Offset;
+      Out_Data  :    out Ada.Streams.Stream_Element_Array;
+      Out_Last  :    out Ada.Streams.Stream_Element_Offset;
+      Flush     : in     Flush_Mode);
+   --  Compress/decompress the In_Data buffer and place the result into
+   --  Out_Data. In_Last is the index of last element from In_Data accepted by
+   --  the Filter. Out_Last is the last element of the received data from
+   --  Filter. To tell the filter that incoming data are complete put the
+   --  Flush parameter to Finish.
+
+   function Stream_End (Filter : in Filter_Type) return Boolean;
+   pragma Inline (Stream_End);
+   --  Return the true when the stream is complete.
+
+   procedure Flush
+     (Filter    : in out Filter_Type;
+      Out_Data  :    out Ada.Streams.Stream_Element_Array;
+      Out_Last  :    out Ada.Streams.Stream_Element_Offset;
+      Flush     : in     Flush_Mode);
+   pragma Inline (Flush);
+   --  Flushing the data from the compressor.
+
+   generic
+      with procedure Write
+        (Item : in Ada.Streams.Stream_Element_Array);
+      --  User should provide this routine for accept
+      --  compressed/decompressed data.
+
+      Buffer_Size : in Ada.Streams.Stream_Element_Offset
+         := Default_Buffer_Size;
+      --  Buffer size for Write user routine.
+
+   procedure Write
+     (Filter  : in out Filter_Type;
+      Item    : in     Ada.Streams.Stream_Element_Array;
+      Flush   : in     Flush_Mode := No_Flush);
+   --  Compress/Decompress data from Item to the generic parameter procedure
+   --  Write. Output buffer size could be set in Buffer_Size generic parameter.
+
+   generic
+      with procedure Read
+        (Item : out Ada.Streams.Stream_Element_Array;
+         Last : out Ada.Streams.Stream_Element_Offset);
+      --  User should provide data for compression/decompression
+      --  thru this routine.
+
+      Buffer : in out Ada.Streams.Stream_Element_Array;
+      --  Buffer for keep remaining data from the previous
+      --  back read.
+
+      Rest_First, Rest_Last : in out Ada.Streams.Stream_Element_Offset;
+      --  Rest_First have to be initialized to Buffer'Last + 1
+      --  Rest_Last have to be initialized to Buffer'Last
+      --  before usage.
+
+      Allow_Read_Some : in Boolean := False;
+      --  Is it allowed to return Last < Item'Last before end of data.
+
+   procedure Read
+     (Filter : in out Filter_Type;
+      Item   :    out Ada.Streams.Stream_Element_Array;
+      Last   :    out Ada.Streams.Stream_Element_Offset;
+      Flush  : in     Flush_Mode := No_Flush);
+   --  Compress/Decompress data from generic parameter procedure Read to the
+   --  Item. User should provide Buffer and initialized Rest_First, Rest_Last
+   --  indicators. If Allow_Read_Some is True, Read routines could return
+   --  Last < Item'Last only at end of stream.
+
+private
+
+   use Ada.Streams;
+
+   pragma Assert (Ada.Streams.Stream_Element'Size    =    8);
+   pragma Assert (Ada.Streams.Stream_Element'Modulus = 2**8);
+
+   type Flush_Mode is new Integer range 0 .. 5;
+
+   type Compression_Method is new Integer range 8 .. 8;
+
+   type Strategy_Type is new Integer range 0 .. 3;
+
+   No_Flush      : constant Flush_Mode := 0;
+   Partial_Flush : constant Flush_Mode := 1;
+   Sync_Flush    : constant Flush_Mode := 2;
+   Full_Flush    : constant Flush_Mode := 3;
+   Finish        : constant Flush_Mode := 4;
+   Block_Flush   : constant Flush_Mode := 5;
+
+   Filtered         : constant Strategy_Type := 1;
+   Huffman_Only     : constant Strategy_Type := 2;
+   RLE              : constant Strategy_Type := 3;
+   Default_Strategy : constant Strategy_Type := 0;
+
+   Deflated : constant Compression_Method := 8;
+
+   type Z_Stream;
+
+   type Z_Stream_Access is access all Z_Stream;
+
+   type Filter_Type is tagged limited record
+      Strm        : Z_Stream_Access;
+      Compression : Boolean;
+      Stream_End  : Boolean;
+      Header      : Header_Type;
+      CRC         : Unsigned_32;
+      Offset      : Stream_Element_Offset;
+      --  Offset for gzip header/footer output.
+   end record;
+
+end ZLib;
diff --git a/compat/zlib/contrib/ada/zlib.gpr b/compat/zlib/contrib/ada/zlib.gpr
new file mode 100644
index 0000000..296b22a
--- /dev/null
+++ b/compat/zlib/contrib/ada/zlib.gpr
@@ -0,0 +1,20 @@
+project Zlib is
+
+   for Languages use ("Ada");
+   for Source_Dirs use (".");
+   for Object_Dir use ".";
+   for Main use ("test.adb", "mtest.adb", "read.adb", "buffer_demo");
+
+   package Compiler is
+      for Default_Switches ("ada") use ("-gnatwcfilopru", "-gnatVcdfimorst", "-gnatyabcefhiklmnoprst");
+   end Compiler;
+
+   package Linker is
+      for Default_Switches ("ada") use ("-lz");
+   end Linker;
+
+   package Builder is
+      for Default_Switches ("ada") use ("-s", "-gnatQ");
+   end Builder;
+
+end Zlib;
diff --git a/compat/zlib/contrib/amd64/amd64-match.S b/compat/zlib/contrib/amd64/amd64-match.S
new file mode 100644
index 0000000..81d4a1c
--- /dev/null
+++ b/compat/zlib/contrib/amd64/amd64-match.S
@@ -0,0 +1,452 @@
+/*
+ * match.S -- optimized version of longest_match()
+ * based on the similar work by Gilles Vollant, and Brian Raiter, written 1998
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the BSD License. Use by owners of Che Guevarra
+ * parafernalia is prohibited, where possible, and highly discouraged
+ * elsewhere.
+ */
+
+#ifndef NO_UNDERLINE
+#	define	match_init	_match_init
+#	define	longest_match	_longest_match
+#endif
+
+#define	scanend		ebx
+#define	scanendw	bx
+#define	chainlenwmask	edx /* high word: current chain len low word: s->wmask */
+#define	curmatch	rsi
+#define	curmatchd	esi
+#define	windowbestlen	r8
+#define	scanalign	r9
+#define	scanalignd	r9d
+#define	window		r10
+#define	bestlen		r11
+#define	bestlend	r11d
+#define	scanstart	r12d
+#define	scanstartw	r12w
+#define scan		r13
+#define nicematch	r14d
+#define	limit		r15
+#define	limitd		r15d
+#define prev		rcx
+
+/*
+ * The 258 is a "magic number, not a parameter -- changing it
+ * breaks the hell loose
+ */
+#define	MAX_MATCH	(258)
+#define	MIN_MATCH	(3)
+#define	MIN_LOOKAHEAD	(MAX_MATCH + MIN_MATCH + 1)
+#define	MAX_MATCH_8	((MAX_MATCH + 7) & ~7)
+
+/* stack frame offsets */
+#define	LocalVarsSize	(112)
+#define _chainlenwmask	( 8-LocalVarsSize)(%rsp)
+#define _windowbestlen	(16-LocalVarsSize)(%rsp)
+#define save_r14        (24-LocalVarsSize)(%rsp)
+#define save_rsi        (32-LocalVarsSize)(%rsp)
+#define save_rbx        (40-LocalVarsSize)(%rsp)
+#define save_r12        (56-LocalVarsSize)(%rsp)
+#define save_r13        (64-LocalVarsSize)(%rsp)
+#define save_r15        (80-LocalVarsSize)(%rsp)
+
+
+.globl	match_init, longest_match
+
+/*
+ * On AMD64 the first argument of a function (in our case -- the pointer to
+ * deflate_state structure) is passed in %rdi, hence our offsets below are
+ * all off of that.
+ */
+
+/* you can check the structure offset by running
+
+#include <stdlib.h>
+#include <stdio.h>
+#include "deflate.h"
+
+void print_depl()
+{
+deflate_state ds;
+deflate_state *s=&ds;
+printf("size pointer=%u\n",(int)sizeof(void*));
+
+printf("#define dsWSize         (%3u)(%%rdi)\n",(int)(((char*)&(s->w_size))-((char*)s)));
+printf("#define dsWMask         (%3u)(%%rdi)\n",(int)(((char*)&(s->w_mask))-((char*)s)));
+printf("#define dsWindow        (%3u)(%%rdi)\n",(int)(((char*)&(s->window))-((char*)s)));
+printf("#define dsPrev          (%3u)(%%rdi)\n",(int)(((char*)&(s->prev))-((char*)s)));
+printf("#define dsMatchLen      (%3u)(%%rdi)\n",(int)(((char*)&(s->match_length))-((char*)s)));
+printf("#define dsPrevMatch     (%3u)(%%rdi)\n",(int)(((char*)&(s->prev_match))-((char*)s)));
+printf("#define dsStrStart      (%3u)(%%rdi)\n",(int)(((char*)&(s->strstart))-((char*)s)));
+printf("#define dsMatchStart    (%3u)(%%rdi)\n",(int)(((char*)&(s->match_start))-((char*)s)));
+printf("#define dsLookahead     (%3u)(%%rdi)\n",(int)(((char*)&(s->lookahead))-((char*)s)));
+printf("#define dsPrevLen       (%3u)(%%rdi)\n",(int)(((char*)&(s->prev_length))-((char*)s)));
+printf("#define dsMaxChainLen   (%3u)(%%rdi)\n",(int)(((char*)&(s->max_chain_length))-((char*)s)));
+printf("#define dsGoodMatch     (%3u)(%%rdi)\n",(int)(((char*)&(s->good_match))-((char*)s)));
+printf("#define dsNiceMatch     (%3u)(%%rdi)\n",(int)(((char*)&(s->nice_match))-((char*)s)));
+}
+
+*/
+
+
+/*
+  to compile for XCode 3.2 on MacOSX x86_64
+  - run "gcc -g -c -DXCODE_MAC_X64_STRUCTURE amd64-match.S"
+ */
+
+
+#ifndef CURRENT_LINX_XCODE_MAC_X64_STRUCTURE
+#define dsWSize		( 68)(%rdi)
+#define dsWMask		( 76)(%rdi)
+#define dsWindow	( 80)(%rdi)
+#define dsPrev		( 96)(%rdi)
+#define dsMatchLen	(144)(%rdi)
+#define dsPrevMatch	(148)(%rdi)
+#define dsStrStart	(156)(%rdi)
+#define dsMatchStart	(160)(%rdi)
+#define dsLookahead	(164)(%rdi)
+#define dsPrevLen	(168)(%rdi)
+#define dsMaxChainLen	(172)(%rdi)
+#define dsGoodMatch	(188)(%rdi)
+#define dsNiceMatch	(192)(%rdi)
+
+#else 
+
+#ifndef STRUCT_OFFSET
+#	define STRUCT_OFFSET	(0)
+#endif
+
+
+#define dsWSize		( 56 + STRUCT_OFFSET)(%rdi)
+#define dsWMask		( 64 + STRUCT_OFFSET)(%rdi)
+#define dsWindow	( 72 + STRUCT_OFFSET)(%rdi)
+#define dsPrev		( 88 + STRUCT_OFFSET)(%rdi)
+#define dsMatchLen	(136 + STRUCT_OFFSET)(%rdi)
+#define dsPrevMatch	(140 + STRUCT_OFFSET)(%rdi)
+#define dsStrStart	(148 + STRUCT_OFFSET)(%rdi)
+#define dsMatchStart	(152 + STRUCT_OFFSET)(%rdi)
+#define dsLookahead	(156 + STRUCT_OFFSET)(%rdi)
+#define dsPrevLen	(160 + STRUCT_OFFSET)(%rdi)
+#define dsMaxChainLen	(164 + STRUCT_OFFSET)(%rdi)
+#define dsGoodMatch	(180 + STRUCT_OFFSET)(%rdi)
+#define dsNiceMatch	(184 + STRUCT_OFFSET)(%rdi)
+
+#endif
+
+
+
+
+.text
+
+/* uInt longest_match(deflate_state *deflatestate, IPos curmatch) */
+
+longest_match:
+/*
+ * Retrieve the function arguments. %curmatch will hold cur_match
+ * throughout the entire function (passed via rsi on amd64).
+ * rdi will hold the pointer to the deflate_state (first arg on amd64)
+ */
+		mov     %rsi, save_rsi
+		mov     %rbx, save_rbx
+		mov	%r12, save_r12
+		mov     %r13, save_r13
+		mov     %r14, save_r14
+		mov     %r15, save_r15
+
+/* uInt wmask = s->w_mask;						*/
+/* unsigned chain_length = s->max_chain_length;				*/
+/* if (s->prev_length >= s->good_match) {				*/
+/*     chain_length >>= 2;						*/
+/* }									*/
+
+		movl	dsPrevLen, %eax
+		movl	dsGoodMatch, %ebx
+		cmpl	%ebx, %eax
+		movl	dsWMask, %eax
+		movl	dsMaxChainLen, %chainlenwmask
+		jl	LastMatchGood
+		shrl	$2, %chainlenwmask
+LastMatchGood:
+
+/* chainlen is decremented once beforehand so that the function can	*/
+/* use the sign flag instead of the zero flag for the exit test.	*/
+/* It is then shifted into the high word, to make room for the wmask	*/
+/* value, which it will always accompany.				*/
+
+		decl	%chainlenwmask
+		shll	$16, %chainlenwmask
+		orl	%eax, %chainlenwmask
+
+/* if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;	*/
+
+		movl	dsNiceMatch, %eax
+		movl	dsLookahead, %ebx
+		cmpl	%eax, %ebx
+		jl	LookaheadLess
+		movl	%eax, %ebx
+LookaheadLess:	movl	%ebx, %nicematch
+
+/* register Bytef *scan = s->window + s->strstart;			*/
+
+		mov	dsWindow, %window
+		movl	dsStrStart, %limitd
+		lea	(%limit, %window), %scan
+
+/* Determine how many bytes the scan ptr is off from being		*/
+/* dword-aligned.							*/
+
+		mov	%scan, %scanalign
+		negl	%scanalignd
+		andl	$3, %scanalignd
+
+/* IPos limit = s->strstart > (IPos)MAX_DIST(s) ?			*/
+/*     s->strstart - (IPos)MAX_DIST(s) : NIL;				*/
+
+		movl	dsWSize, %eax
+		subl	$MIN_LOOKAHEAD, %eax
+		xorl	%ecx, %ecx
+		subl	%eax, %limitd
+		cmovng	%ecx, %limitd
+
+/* int best_len = s->prev_length;					*/
+
+		movl	dsPrevLen, %bestlend
+
+/* Store the sum of s->window + best_len in %windowbestlen locally, and in memory.	*/
+
+		lea	(%window, %bestlen), %windowbestlen
+		mov	%windowbestlen, _windowbestlen
+
+/* register ush scan_start = *(ushf*)scan;				*/
+/* register ush scan_end   = *(ushf*)(scan+best_len-1);			*/
+/* Posf *prev = s->prev;						*/
+
+		movzwl	(%scan), %scanstart
+		movzwl	-1(%scan, %bestlen), %scanend
+		mov	dsPrev, %prev
+
+/* Jump into the main loop.						*/
+
+		movl	%chainlenwmask, _chainlenwmask
+		jmp	LoopEntry
+
+.balign 16
+
+/* do {
+ *     match = s->window + cur_match;
+ *     if (*(ushf*)(match+best_len-1) != scan_end ||
+ *         *(ushf*)match != scan_start) continue;
+ *     [...]
+ * } while ((cur_match = prev[cur_match & wmask]) > limit
+ *          && --chain_length != 0);
+ *
+ * Here is the inner loop of the function. The function will spend the
+ * majority of its time in this loop, and majority of that time will
+ * be spent in the first ten instructions.
+ */
+LookupLoop:
+		andl	%chainlenwmask, %curmatchd
+		movzwl	(%prev, %curmatch, 2), %curmatchd
+		cmpl	%limitd, %curmatchd
+		jbe	LeaveNow
+		subl	$0x00010000, %chainlenwmask
+		js	LeaveNow
+LoopEntry:	cmpw	-1(%windowbestlen, %curmatch), %scanendw
+		jne	LookupLoop
+		cmpw	%scanstartw, (%window, %curmatch)
+		jne	LookupLoop
+
+/* Store the current value of chainlen.					*/
+		movl	%chainlenwmask, _chainlenwmask
+
+/* %scan is the string under scrutiny, and %prev to the string we	*/
+/* are hoping to match it up with. In actuality, %esi and %edi are	*/
+/* both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and %edx is	*/
+/* initialized to -(MAX_MATCH_8 - scanalign).				*/
+
+		mov	$(-MAX_MATCH_8), %rdx
+		lea	(%curmatch, %window), %windowbestlen
+		lea	MAX_MATCH_8(%windowbestlen, %scanalign), %windowbestlen
+		lea	MAX_MATCH_8(%scan, %scanalign), %prev
+
+/* the prefetching below makes very little difference... */
+		prefetcht1	(%windowbestlen, %rdx)
+		prefetcht1	(%prev, %rdx)
+
+/*
+ * Test the strings for equality, 8 bytes at a time. At the end,
+ * adjust %rdx so that it is offset to the exact byte that mismatched.
+ *
+ * It should be confessed that this loop usually does not represent
+ * much of the total running time. Replacing it with a more
+ * straightforward "rep cmpsb" would not drastically degrade
+ * performance -- unrolling it, for example, makes no difference.
+ */
+
+#undef USE_SSE	/* works, but is 6-7% slower, than non-SSE... */
+
+LoopCmps:
+#ifdef USE_SSE
+		/* Preload the SSE registers */
+		movdqu	  (%windowbestlen, %rdx), %xmm1
+		movdqu	  (%prev, %rdx), %xmm2
+		pcmpeqb	%xmm2, %xmm1
+		movdqu	16(%windowbestlen, %rdx), %xmm3
+		movdqu	16(%prev, %rdx), %xmm4
+		pcmpeqb	%xmm4, %xmm3
+		movdqu	32(%windowbestlen, %rdx), %xmm5
+		movdqu	32(%prev, %rdx), %xmm6
+		pcmpeqb	%xmm6, %xmm5
+		movdqu	48(%windowbestlen, %rdx), %xmm7
+		movdqu	48(%prev, %rdx), %xmm8
+		pcmpeqb	%xmm8, %xmm7
+
+		/* Check the comparisions' results */
+		pmovmskb %xmm1, %rax
+		notw	%ax
+		bsfw	%ax, %ax
+		jnz	LeaveLoopCmps
+		
+		/* this is the only iteration of the loop with a possibility of having
+		   incremented rdx by 0x108 (each loop iteration add 16*4 = 0x40 
+		   and (0x40*4)+8=0x108 */
+		add	$8, %rdx
+		jz LenMaximum
+		add	$8, %rdx
+
+		
+		pmovmskb %xmm3, %rax
+		notw	%ax
+		bsfw	%ax, %ax
+		jnz	LeaveLoopCmps
+		
+		
+		add	$16, %rdx
+
+
+		pmovmskb %xmm5, %rax
+		notw	%ax
+		bsfw	%ax, %ax
+		jnz	LeaveLoopCmps
+		
+		add	$16, %rdx
+
+
+		pmovmskb %xmm7, %rax
+		notw	%ax
+		bsfw	%ax, %ax
+		jnz	LeaveLoopCmps
+		
+		add	$16, %rdx
+		
+		jmp	LoopCmps
+LeaveLoopCmps:	add	%rax, %rdx
+#else
+		mov	(%windowbestlen, %rdx), %rax
+		xor	(%prev, %rdx), %rax
+		jnz	LeaveLoopCmps
+		
+		mov	8(%windowbestlen, %rdx), %rax
+		xor	8(%prev, %rdx), %rax
+		jnz	LeaveLoopCmps8
+
+		mov	16(%windowbestlen, %rdx), %rax
+		xor	16(%prev, %rdx), %rax
+		jnz	LeaveLoopCmps16
+				
+		add	$24, %rdx
+		jnz	LoopCmps
+		jmp	LenMaximum
+#	if 0
+/*
+ * This three-liner is tantalizingly simple, but bsf is a slow instruction,
+ * and the complicated alternative down below is quite a bit faster. Sad...
+ */
+
+LeaveLoopCmps:	bsf	%rax, %rax /* find the first non-zero bit */
+		shrl	$3, %eax /* divide by 8 to get the byte */
+		add	%rax, %rdx
+#	else
+LeaveLoopCmps16:
+		add	$8, %rdx
+LeaveLoopCmps8:
+		add	$8, %rdx
+LeaveLoopCmps:	testl   $0xFFFFFFFF, %eax /* Check the first 4 bytes */
+		jnz     Check16
+		add     $4, %rdx
+		shr     $32, %rax
+Check16:        testw   $0xFFFF, %ax
+		jnz     LenLower
+		add	$2, %rdx
+		shrl	$16, %eax
+LenLower:	subb	$1, %al
+		adc	$0, %rdx
+#	endif
+#endif
+
+/* Calculate the length of the match. If it is longer than MAX_MATCH,	*/
+/* then automatically accept it as the best possible match and leave.	*/
+
+		lea	(%prev, %rdx), %rax
+		sub	%scan, %rax
+		cmpl	$MAX_MATCH, %eax
+		jge	LenMaximum
+
+/* If the length of the match is not longer than the best match we	*/
+/* have so far, then forget it and return to the lookup loop.		*/
+
+		cmpl	%bestlend, %eax
+		jg	LongerMatch
+		mov	_windowbestlen, %windowbestlen
+		mov	dsPrev, %prev
+		movl	_chainlenwmask, %edx
+		jmp	LookupLoop
+
+/*         s->match_start = cur_match;					*/
+/*         best_len = len;						*/
+/*         if (len >= nice_match) break;				*/
+/*         scan_end = *(ushf*)(scan+best_len-1);			*/
+
+LongerMatch:
+		movl	%eax, %bestlend
+		movl	%curmatchd, dsMatchStart
+		cmpl	%nicematch, %eax
+		jge	LeaveNow
+
+		lea	(%window, %bestlen), %windowbestlen
+		mov	%windowbestlen, _windowbestlen
+
+		movzwl	-1(%scan, %rax), %scanend
+		mov	dsPrev, %prev
+		movl	_chainlenwmask, %chainlenwmask
+		jmp	LookupLoop
+
+/* Accept the current string, with the maximum possible length.		*/
+
+LenMaximum:
+		movl	$MAX_MATCH, %bestlend
+		movl	%curmatchd, dsMatchStart
+
+/* if ((uInt)best_len <= s->lookahead) return (uInt)best_len;		*/
+/* return s->lookahead;							*/
+
+LeaveNow:
+		movl	dsLookahead, %eax
+		cmpl	%eax, %bestlend
+		cmovngl	%bestlend, %eax
+LookaheadRet:
+
+/* Restore the registers and return from whence we came.			*/
+
+	mov	save_rsi, %rsi
+	mov	save_rbx, %rbx
+	mov	save_r12, %r12
+	mov	save_r13, %r13
+	mov	save_r14, %r14
+	mov	save_r15, %r15
+
+	ret
+
+match_init:	ret
diff --git a/compat/zlib/contrib/asm686/README.686 b/compat/zlib/contrib/asm686/README.686
new file mode 100644
index 0000000..a0bf3be
--- /dev/null
+++ b/compat/zlib/contrib/asm686/README.686
@@ -0,0 +1,51 @@
+This is a patched version of zlib, modified to use
+Pentium-Pro-optimized assembly code in the deflation algorithm. The
+files changed/added by this patch are:
+
+README.686
+match.S
+
+The speedup that this patch provides varies, depending on whether the
+compiler used to build the original version of zlib falls afoul of the
+PPro's speed traps. My own tests show a speedup of around 10-20% at
+the default compression level, and 20-30% using -9, against a version
+compiled using gcc 2.7.2.3. Your mileage may vary.
+
+Note that this code has been tailored for the PPro/PII in particular,
+and will not perform particuarly well on a Pentium.
+
+If you are using an assembler other than GNU as, you will have to
+translate match.S to use your assembler's syntax. (Have fun.)
+
+Brian Raiter
+breadbox@muppetlabs.com
+April, 1998
+
+
+Added for zlib 1.1.3:
+
+The patches come from
+http://www.muppetlabs.com/~breadbox/software/assembly.html
+
+To compile zlib with this asm file, copy match.S to the zlib directory
+then do:
+
+CFLAGS="-O3 -DASMV" ./configure
+make OBJA=match.o
+
+
+Update:
+
+I've been ignoring these assembly routines for years, believing that
+gcc's generated code had caught up with it sometime around gcc 2.95
+and the major rearchitecting of the Pentium 4. However, I recently
+learned that, despite what I believed, this code still has some life
+in it. On the Pentium 4 and AMD64 chips, it continues to run about 8%
+faster than the code produced by gcc 4.1.
+
+In acknowledgement of its continuing usefulness, I've altered the
+license to match that of the rest of zlib. Share and Enjoy!
+
+Brian Raiter
+breadbox@muppetlabs.com
+April, 2007
diff --git a/compat/zlib/contrib/asm686/match.S b/compat/zlib/contrib/asm686/match.S
new file mode 100644
index 0000000..fa42109
--- /dev/null
+++ b/compat/zlib/contrib/asm686/match.S
@@ -0,0 +1,357 @@
+/* match.S -- x86 assembly version of the zlib longest_match() function.
+ * Optimized for the Intel 686 chips (PPro and later).
+ *
+ * Copyright (C) 1998, 2007 Brian Raiter <breadbox@muppetlabs.com>
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty.  In no event will the author be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ *    claim that you wrote the original software. If you use this software
+ *    in a product, an acknowledgment in the product documentation would be
+ *    appreciated but is not required.
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ *    misrepresented as being the original software.
+ * 3. This notice may not be removed or altered from any source distribution.
+ */
+
+#ifndef NO_UNDERLINE
+#define	match_init	_match_init
+#define	longest_match	_longest_match
+#endif
+
+#define	MAX_MATCH	(258)
+#define	MIN_MATCH	(3)
+#define	MIN_LOOKAHEAD	(MAX_MATCH + MIN_MATCH + 1)
+#define	MAX_MATCH_8	((MAX_MATCH + 7) & ~7)
+
+/* stack frame offsets */
+
+#define	chainlenwmask		0	/* high word: current chain len	*/
+					/* low word: s->wmask		*/
+#define	window			4	/* local copy of s->window	*/
+#define	windowbestlen		8	/* s->window + bestlen		*/
+#define	scanstart		16	/* first two bytes of string	*/
+#define	scanend			12	/* last two bytes of string	*/
+#define	scanalign		20	/* dword-misalignment of string	*/
+#define	nicematch		24	/* a good enough match size	*/
+#define	bestlen			28	/* size of best match so far	*/
+#define	scan			32	/* ptr to string wanting match	*/
+
+#define	LocalVarsSize		(36)
+/*	saved ebx		36 */
+/*	saved edi		40 */
+/*	saved esi		44 */
+/*	saved ebp		48 */
+/*	return address		52 */
+#define	deflatestate		56	/* the function arguments	*/
+#define	curmatch		60
+
+/* All the +zlib1222add offsets are due to the addition of fields
+ *  in zlib in the deflate_state structure since the asm code was first written
+ * (if you compile with zlib 1.0.4 or older, use "zlib1222add equ (-4)").
+ * (if you compile with zlib between 1.0.5 and 1.2.2.1, use "zlib1222add equ 0").
+ * if you compile with zlib 1.2.2.2 or later , use "zlib1222add equ 8").
+ */
+
+#define zlib1222add		(8)
+
+#define	dsWSize			(36+zlib1222add)
+#define	dsWMask			(44+zlib1222add)
+#define	dsWindow		(48+zlib1222add)
+#define	dsPrev			(56+zlib1222add)
+#define	dsMatchLen		(88+zlib1222add)
+#define	dsPrevMatch		(92+zlib1222add)
+#define	dsStrStart		(100+zlib1222add)
+#define	dsMatchStart		(104+zlib1222add)
+#define	dsLookahead		(108+zlib1222add)
+#define	dsPrevLen		(112+zlib1222add)
+#define	dsMaxChainLen		(116+zlib1222add)
+#define	dsGoodMatch		(132+zlib1222add)
+#define	dsNiceMatch		(136+zlib1222add)
+
+
+.file "match.S"
+
+.globl	match_init, longest_match
+
+.text
+
+/* uInt longest_match(deflate_state *deflatestate, IPos curmatch) */
+.cfi_sections	.debug_frame
+
+longest_match:
+
+.cfi_startproc
+/* Save registers that the compiler may be using, and adjust %esp to	*/
+/* make room for our stack frame.					*/
+
+		pushl	%ebp
+		.cfi_def_cfa_offset 8
+		.cfi_offset ebp, -8
+		pushl	%edi
+		.cfi_def_cfa_offset 12
+		pushl	%esi
+		.cfi_def_cfa_offset 16
+		pushl	%ebx
+		.cfi_def_cfa_offset 20
+		subl	$LocalVarsSize, %esp
+		.cfi_def_cfa_offset LocalVarsSize+20
+
+/* Retrieve the function arguments. %ecx will hold cur_match		*/
+/* throughout the entire function. %edx will hold the pointer to the	*/
+/* deflate_state structure during the function's setup (before		*/
+/* entering the main loop).						*/
+
+		movl	deflatestate(%esp), %edx
+		movl	curmatch(%esp), %ecx
+
+/* uInt wmask = s->w_mask;						*/
+/* unsigned chain_length = s->max_chain_length;				*/
+/* if (s->prev_length >= s->good_match) {				*/
+/*     chain_length >>= 2;						*/
+/* }									*/
+ 
+		movl	dsPrevLen(%edx), %eax
+		movl	dsGoodMatch(%edx), %ebx
+		cmpl	%ebx, %eax
+		movl	dsWMask(%edx), %eax
+		movl	dsMaxChainLen(%edx), %ebx
+		jl	LastMatchGood
+		shrl	$2, %ebx
+LastMatchGood:
+
+/* chainlen is decremented once beforehand so that the function can	*/
+/* use the sign flag instead of the zero flag for the exit test.	*/
+/* It is then shifted into the high word, to make room for the wmask	*/
+/* value, which it will always accompany.				*/
+
+		decl	%ebx
+		shll	$16, %ebx
+		orl	%eax, %ebx
+		movl	%ebx, chainlenwmask(%esp)
+
+/* if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;	*/
+
+		movl	dsNiceMatch(%edx), %eax
+		movl	dsLookahead(%edx), %ebx
+		cmpl	%eax, %ebx
+		jl	LookaheadLess
+		movl	%eax, %ebx
+LookaheadLess:	movl	%ebx, nicematch(%esp)
+
+/* register Bytef *scan = s->window + s->strstart;			*/
+
+		movl	dsWindow(%edx), %esi
+		movl	%esi, window(%esp)
+		movl	dsStrStart(%edx), %ebp
+		lea	(%esi,%ebp), %edi
+		movl	%edi, scan(%esp)
+
+/* Determine how many bytes the scan ptr is off from being		*/
+/* dword-aligned.							*/
+
+		movl	%edi, %eax
+		negl	%eax
+		andl	$3, %eax
+		movl	%eax, scanalign(%esp)
+
+/* IPos limit = s->strstart > (IPos)MAX_DIST(s) ?			*/
+/*     s->strstart - (IPos)MAX_DIST(s) : NIL;				*/
+
+		movl	dsWSize(%edx), %eax
+		subl	$MIN_LOOKAHEAD, %eax
+		subl	%eax, %ebp
+		jg	LimitPositive
+		xorl	%ebp, %ebp
+LimitPositive:
+
+/* int best_len = s->prev_length;					*/
+
+		movl	dsPrevLen(%edx), %eax
+		movl	%eax, bestlen(%esp)
+
+/* Store the sum of s->window + best_len in %esi locally, and in %esi.	*/
+
+		addl	%eax, %esi
+		movl	%esi, windowbestlen(%esp)
+
+/* register ush scan_start = *(ushf*)scan;				*/
+/* register ush scan_end   = *(ushf*)(scan+best_len-1);			*/
+/* Posf *prev = s->prev;						*/
+
+		movzwl	(%edi), %ebx
+		movl	%ebx, scanstart(%esp)
+		movzwl	-1(%edi,%eax), %ebx
+		movl	%ebx, scanend(%esp)
+		movl	dsPrev(%edx), %edi
+
+/* Jump into the main loop.						*/
+
+		movl	chainlenwmask(%esp), %edx
+		jmp	LoopEntry
+
+.balign 16
+
+/* do {
+ *     match = s->window + cur_match;
+ *     if (*(ushf*)(match+best_len-1) != scan_end ||
+ *         *(ushf*)match != scan_start) continue;
+ *     [...]
+ * } while ((cur_match = prev[cur_match & wmask]) > limit
+ *          && --chain_length != 0);
+ *
+ * Here is the inner loop of the function. The function will spend the
+ * majority of its time in this loop, and majority of that time will
+ * be spent in the first ten instructions.
+ *
+ * Within this loop:
+ * %ebx = scanend
+ * %ecx = curmatch
+ * %edx = chainlenwmask - i.e., ((chainlen << 16) | wmask)
+ * %esi = windowbestlen - i.e., (window + bestlen)
+ * %edi = prev
+ * %ebp = limit
+ */
+LookupLoop:
+		andl	%edx, %ecx
+		movzwl	(%edi,%ecx,2), %ecx
+		cmpl	%ebp, %ecx
+		jbe	LeaveNow
+		subl	$0x00010000, %edx
+		js	LeaveNow
+LoopEntry:	movzwl	-1(%esi,%ecx), %eax
+		cmpl	%ebx, %eax
+		jnz	LookupLoop
+		movl	window(%esp), %eax
+		movzwl	(%eax,%ecx), %eax
+		cmpl	scanstart(%esp), %eax
+		jnz	LookupLoop
+
+/* Store the current value of chainlen.					*/
+
+		movl	%edx, chainlenwmask(%esp)
+
+/* Point %edi to the string under scrutiny, and %esi to the string we	*/
+/* are hoping to match it up with. In actuality, %esi and %edi are	*/
+/* both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and %edx is	*/
+/* initialized to -(MAX_MATCH_8 - scanalign).				*/
+
+		movl	window(%esp), %esi
+		movl	scan(%esp), %edi
+		addl	%ecx, %esi
+		movl	scanalign(%esp), %eax
+		movl	$(-MAX_MATCH_8), %edx
+		lea	MAX_MATCH_8(%edi,%eax), %edi
+		lea	MAX_MATCH_8(%esi,%eax), %esi
+
+/* Test the strings for equality, 8 bytes at a time. At the end,
+ * adjust %edx so that it is offset to the exact byte that mismatched.
+ *
+ * We already know at this point that the first three bytes of the
+ * strings match each other, and they can be safely passed over before
+ * starting the compare loop. So what this code does is skip over 0-3
+ * bytes, as much as necessary in order to dword-align the %edi
+ * pointer. (%esi will still be misaligned three times out of four.)
+ *
+ * It should be confessed that this loop usually does not represent
+ * much of the total running time. Replacing it with a more
+ * straightforward "rep cmpsb" would not drastically degrade
+ * performance.
+ */
+LoopCmps:
+		movl	(%esi,%edx), %eax
+		xorl	(%edi,%edx), %eax
+		jnz	LeaveLoopCmps
+		movl	4(%esi,%edx), %eax
+		xorl	4(%edi,%edx), %eax
+		jnz	LeaveLoopCmps4
+		addl	$8, %edx
+		jnz	LoopCmps
+		jmp	LenMaximum
+LeaveLoopCmps4:	addl	$4, %edx
+LeaveLoopCmps:	testl	$0x0000FFFF, %eax
+		jnz	LenLower
+		addl	$2, %edx
+		shrl	$16, %eax
+LenLower:	subb	$1, %al
+		adcl	$0, %edx
+
+/* Calculate the length of the match. If it is longer than MAX_MATCH,	*/
+/* then automatically accept it as the best possible match and leave.	*/
+
+		lea	(%edi,%edx), %eax
+		movl	scan(%esp), %edi
+		subl	%edi, %eax
+		cmpl	$MAX_MATCH, %eax
+		jge	LenMaximum
+
+/* If the length of the match is not longer than the best match we	*/
+/* have so far, then forget it and return to the lookup loop.		*/
+
+		movl	deflatestate(%esp), %edx
+		movl	bestlen(%esp), %ebx
+		cmpl	%ebx, %eax
+		jg	LongerMatch
+		movl	windowbestlen(%esp), %esi
+		movl	dsPrev(%edx), %edi
+		movl	scanend(%esp), %ebx
+		movl	chainlenwmask(%esp), %edx
+		jmp	LookupLoop
+
+/*         s->match_start = cur_match;					*/
+/*         best_len = len;						*/
+/*         if (len >= nice_match) break;				*/
+/*         scan_end = *(ushf*)(scan+best_len-1);			*/
+
+LongerMatch:	movl	nicematch(%esp), %ebx
+		movl	%eax, bestlen(%esp)
+		movl	%ecx, dsMatchStart(%edx)
+		cmpl	%ebx, %eax
+		jge	LeaveNow
+		movl	window(%esp), %esi
+		addl	%eax, %esi
+		movl	%esi, windowbestlen(%esp)
+		movzwl	-1(%edi,%eax), %ebx
+		movl	dsPrev(%edx), %edi
+		movl	%ebx, scanend(%esp)
+		movl	chainlenwmask(%esp), %edx
+		jmp	LookupLoop
+
+/* Accept the current string, with the maximum possible length.		*/
+
+LenMaximum:	movl	deflatestate(%esp), %edx
+		movl	$MAX_MATCH, bestlen(%esp)
+		movl	%ecx, dsMatchStart(%edx)
+
+/* if ((uInt)best_len <= s->lookahead) return (uInt)best_len;		*/
+/* return s->lookahead;							*/
+
+LeaveNow:
+		movl	deflatestate(%esp), %edx
+		movl	bestlen(%esp), %ebx
+		movl	dsLookahead(%edx), %eax
+		cmpl	%eax, %ebx
+		jg	LookaheadRet
+		movl	%ebx, %eax
+LookaheadRet:
+
+/* Restore the stack and return from whence we came.			*/
+
+		addl	$LocalVarsSize, %esp
+		.cfi_def_cfa_offset 20
+		popl	%ebx
+		.cfi_def_cfa_offset 16
+		popl	%esi
+		.cfi_def_cfa_offset 12
+		popl	%edi
+		.cfi_def_cfa_offset 8
+		popl	%ebp
+		.cfi_def_cfa_offset 4
+.cfi_endproc
+match_init:	ret
diff --git a/compat/zlib/contrib/blast/Makefile b/compat/zlib/contrib/blast/Makefile
new file mode 100644
index 0000000..9be80ba
--- /dev/null
+++ b/compat/zlib/contrib/blast/Makefile
@@ -0,0 +1,8 @@
+blast: blast.c blast.h
+	cc -DTEST -o blast blast.c
+
+test: blast
+	blast < test.pk | cmp - test.txt
+
+clean:
+	rm -f blast blast.o
diff --git a/compat/zlib/contrib/blast/README b/compat/zlib/contrib/blast/README
new file mode 100644
index 0000000..e3a60b3
--- /dev/null
+++ b/compat/zlib/contrib/blast/README
@@ -0,0 +1,4 @@
+Read blast.h for purpose and usage.
+
+Mark Adler
+madler@alumni.caltech.edu
diff --git a/compat/zlib/contrib/blast/blast.c b/compat/zlib/contrib/blast/blast.c
new file mode 100644
index 0000000..69ef0fe
--- /dev/null
+++ b/compat/zlib/contrib/blast/blast.c
@@ -0,0 +1,446 @@
+/* blast.c
+ * Copyright (C) 2003, 2012 Mark Adler
+ * For conditions of distribution and use, see copyright notice in blast.h
+ * version 1.2, 24 Oct 2012
+ *
+ * blast.c decompresses data compressed by the PKWare Compression Library.
+ * This function provides functionality similar to the explode() function of
+ * the PKWare library, hence the name "blast".
+ *
+ * This decompressor is based on the excellent format description provided by
+ * Ben Rudiak-Gould in comp.compression on August 13, 2001.  Interestingly, the
+ * example Ben provided in the post is incorrect.  The distance 110001 should
+ * instead be 111000.  When corrected, the example byte stream becomes:
+ *
+ *    00 04 82 24 25 8f 80 7f
+ *
+ * which decompresses to "AIAIAIAIAIAIA" (without the quotes).
+ */
+
+/*
+ * Change history:
+ *
+ * 1.0  12 Feb 2003     - First version
+ * 1.1  16 Feb 2003     - Fixed distance check for > 4 GB uncompressed data
+ * 1.2  24 Oct 2012     - Add note about using binary mode in stdio
+ *                      - Fix comparisons of differently signed integers
+ */
+
+#include <setjmp.h>             /* for setjmp(), longjmp(), and jmp_buf */
+#include "blast.h"              /* prototype for blast() */
+
+#define local static            /* for local function definitions */
+#define MAXBITS 13              /* maximum code length */
+#define MAXWIN 4096             /* maximum window size */
+
+/* input and output state */
+struct state {
+    /* input state */
+    blast_in infun;             /* input function provided by user */
+    void *inhow;                /* opaque information passed to infun() */
+    unsigned char *in;          /* next input location */
+    unsigned left;              /* available input at in */
+    int bitbuf;                 /* bit buffer */
+    int bitcnt;                 /* number of bits in bit buffer */
+
+    /* input limit error return state for bits() and decode() */
+    jmp_buf env;
+
+    /* output state */
+    blast_out outfun;           /* output function provided by user */
+    void *outhow;               /* opaque information passed to outfun() */
+    unsigned next;              /* index of next write location in out[] */
+    int first;                  /* true to check distances (for first 4K) */
+    unsigned char out[MAXWIN];  /* output buffer and sliding window */
+};
+
+/*
+ * Return need bits from the input stream.  This always leaves less than
+ * eight bits in the buffer.  bits() works properly for need == 0.
+ *
+ * Format notes:
+ *
+ * - Bits are stored in bytes from the least significant bit to the most
+ *   significant bit.  Therefore bits are dropped from the bottom of the bit
+ *   buffer, using shift right, and new bytes are appended to the top of the
+ *   bit buffer, using shift left.
+ */
+local int bits(struct state *s, int need)
+{
+    int val;            /* bit accumulator */
+
+    /* load at least need bits into val */
+    val = s->bitbuf;
+    while (s->bitcnt < need) {
+        if (s->left == 0) {
+            s->left = s->infun(s->inhow, &(s->in));
+            if (s->left == 0) longjmp(s->env, 1);       /* out of input */
+        }
+        val |= (int)(*(s->in)++) << s->bitcnt;          /* load eight bits */
+        s->left--;
+        s->bitcnt += 8;
+    }
+
+    /* drop need bits and update buffer, always zero to seven bits left */
+    s->bitbuf = val >> need;
+    s->bitcnt -= need;
+
+    /* return need bits, zeroing the bits above that */
+    return val & ((1 << need) - 1);
+}
+
+/*
+ * Huffman code decoding tables.  count[1..MAXBITS] is the number of symbols of
+ * each length, which for a canonical code are stepped through in order.
+ * symbol[] are the symbol values in canonical order, where the number of
+ * entries is the sum of the counts in count[].  The decoding process can be
+ * seen in the function decode() below.
+ */
+struct huffman {
+    short *count;       /* number of symbols of each length */
+    short *symbol;      /* canonically ordered symbols */
+};
+
+/*
+ * Decode a code from the stream s using huffman table h.  Return the symbol or
+ * a negative value if there is an error.  If all of the lengths are zero, i.e.
+ * an empty code, or if the code is incomplete and an invalid code is received,
+ * then -9 is returned after reading MAXBITS bits.
+ *
+ * Format notes:
+ *
+ * - The codes as stored in the compressed data are bit-reversed relative to
+ *   a simple integer ordering of codes of the same lengths.  Hence below the
+ *   bits are pulled from the compressed data one at a time and used to
+ *   build the code value reversed from what is in the stream in order to
+ *   permit simple integer comparisons for decoding.
+ *
+ * - The first code for the shortest length is all ones.  Subsequent codes of
+ *   the same length are simply integer decrements of the previous code.  When
+ *   moving up a length, a one bit is appended to the code.  For a complete
+ *   code, the last code of the longest length will be all zeros.  To support
+ *   this ordering, the bits pulled during decoding are inverted to apply the
+ *   more "natural" ordering starting with all zeros and incrementing.
+ */
+local int decode(struct state *s, struct huffman *h)
+{
+    int len;            /* current number of bits in code */
+    int code;           /* len bits being decoded */
+    int first;          /* first code of length len */
+    int count;          /* number of codes of length len */
+    int index;          /* index of first code of length len in symbol table */
+    int bitbuf;         /* bits from stream */
+    int left;           /* bits left in next or left to process */
+    short *next;        /* next number of codes */
+
+    bitbuf = s->bitbuf;
+    left = s->bitcnt;
+    code = first = index = 0;
+    len = 1;
+    next = h->count + 1;
+    while (1) {
+        while (left--) {
+            code |= (bitbuf & 1) ^ 1;   /* invert code */
+            bitbuf >>= 1;
+            count = *next++;
+            if (code < first + count) { /* if length len, return symbol */
+                s->bitbuf = bitbuf;
+                s->bitcnt = (s->bitcnt - len) & 7;
+                return h->symbol[index + (code - first)];
+            }
+            index += count;             /* else update for next length */
+            first += count;
+            first <<= 1;
+            code <<= 1;
+            len++;
+        }
+        left = (MAXBITS+1) - len;
+        if (left == 0) break;
+        if (s->left == 0) {
+            s->left = s->infun(s->inhow, &(s->in));
+            if (s->left == 0) longjmp(s->env, 1);       /* out of input */
+        }
+        bitbuf = *(s->in)++;
+        s->left--;
+        if (left > 8) left = 8;
+    }
+    return -9;                          /* ran out of codes */
+}
+
+/*
+ * Given a list of repeated code lengths rep[0..n-1], where each byte is a
+ * count (high four bits + 1) and a code length (low four bits), generate the
+ * list of code lengths.  This compaction reduces the size of the object code.
+ * Then given the list of code lengths length[0..n-1] representing a canonical
+ * Huffman code for n symbols, construct the tables required to decode those
+ * codes.  Those tables are the number of codes of each length, and the symbols
+ * sorted by length, retaining their original order within each length.  The
+ * return value is zero for a complete code set, negative for an over-
+ * subscribed code set, and positive for an incomplete code set.  The tables
+ * can be used if the return value is zero or positive, but they cannot be used
+ * if the return value is negative.  If the return value is zero, it is not
+ * possible for decode() using that table to return an error--any stream of
+ * enough bits will resolve to a symbol.  If the return value is positive, then
+ * it is possible for decode() using that table to return an error for received
+ * codes past the end of the incomplete lengths.
+ */
+local int construct(struct huffman *h, const unsigned char *rep, int n)
+{
+    int symbol;         /* current symbol when stepping through length[] */
+    int len;            /* current length when stepping through h->count[] */
+    int left;           /* number of possible codes left of current length */
+    short offs[MAXBITS+1];      /* offsets in symbol table for each length */
+    short length[256];  /* code lengths */
+
+    /* convert compact repeat counts into symbol bit length list */
+    symbol = 0;
+    do {
+        len = *rep++;
+        left = (len >> 4) + 1;
+        len &= 15;
+        do {
+            length[symbol++] = len;
+        } while (--left);
+    } while (--n);
+    n = symbol;
+
+    /* count number of codes of each length */
+    for (len = 0; len <= MAXBITS; len++)
+        h->count[len] = 0;
+    for (symbol = 0; symbol < n; symbol++)
+        (h->count[length[symbol]])++;   /* assumes lengths are within bounds */
+    if (h->count[0] == n)               /* no codes! */
+        return 0;                       /* complete, but decode() will fail */
+
+    /* check for an over-subscribed or incomplete set of lengths */
+    left = 1;                           /* one possible code of zero length */
+    for (len = 1; len <= MAXBITS; len++) {
+        left <<= 1;                     /* one more bit, double codes left */
+        left -= h->count[len];          /* deduct count from possible codes */
+        if (left < 0) return left;      /* over-subscribed--return negative */
+    }                                   /* left > 0 means incomplete */
+
+    /* generate offsets into symbol table for each length for sorting */
+    offs[1] = 0;
+    for (len = 1; len < MAXBITS; len++)
+        offs[len + 1] = offs[len] + h->count[len];
+
+    /*
+     * put symbols in table sorted by length, by symbol order within each
+     * length
+     */
+    for (symbol = 0; symbol < n; symbol++)
+        if (length[symbol] != 0)
+            h->symbol[offs[length[symbol]]++] = symbol;
+
+    /* return zero for complete set, positive for incomplete set */
+    return left;
+}
+
+/*
+ * Decode PKWare Compression Library stream.
+ *
+ * Format notes:
+ *
+ * - First byte is 0 if literals are uncoded or 1 if they are coded.  Second
+ *   byte is 4, 5, or 6 for the number of extra bits in the distance code.
+ *   This is the base-2 logarithm of the dictionary size minus six.
+ *
+ * - Compressed data is a combination of literals and length/distance pairs
+ *   terminated by an end code.  Literals are either Huffman coded or
+ *   uncoded bytes.  A length/distance pair is a coded length followed by a
+ *   coded distance to represent a string that occurs earlier in the
+ *   uncompressed data that occurs again at the current location.
+ *
+ * - A bit preceding a literal or length/distance pair indicates which comes
+ *   next, 0 for literals, 1 for length/distance.
+ *
+ * - If literals are uncoded, then the next eight bits are the literal, in the
+ *   normal bit order in th stream, i.e. no bit-reversal is needed. Similarly,
+ *   no bit reversal is needed for either the length extra bits or the distance
+ *   extra bits.
+ *
+ * - Literal bytes are simply written to the output.  A length/distance pair is
+ *   an instruction to copy previously uncompressed bytes to the output.  The
+ *   copy is from distance bytes back in the output stream, copying for length
+ *   bytes.
+ *
+ * - Distances pointing before the beginning of the output data are not
+ *   permitted.
+ *
+ * - Overlapped copies, where the length is greater than the distance, are
+ *   allowed and common.  For example, a distance of one and a length of 518
+ *   simply copies the last byte 518 times.  A distance of four and a length of
+ *   twelve copies the last four bytes three times.  A simple forward copy
+ *   ignoring whether the length is greater than the distance or not implements
+ *   this correctly.
+ */
+local int decomp(struct state *s)
+{
+    int lit;            /* true if literals are coded */
+    int dict;           /* log2(dictionary size) - 6 */
+    int symbol;         /* decoded symbol, extra bits for distance */
+    int len;            /* length for copy */
+    unsigned dist;      /* distance for copy */
+    int copy;           /* copy counter */
+    unsigned char *from, *to;   /* copy pointers */
+    static int virgin = 1;                              /* build tables once */
+    static short litcnt[MAXBITS+1], litsym[256];        /* litcode memory */
+    static short lencnt[MAXBITS+1], lensym[16];         /* lencode memory */
+    static short distcnt[MAXBITS+1], distsym[64];       /* distcode memory */
+    static struct huffman litcode = {litcnt, litsym};   /* length code */
+    static struct huffman lencode = {lencnt, lensym};   /* length code */
+    static struct huffman distcode = {distcnt, distsym};/* distance code */
+        /* bit lengths of literal codes */
+    static const unsigned char litlen[] = {
+        11, 124, 8, 7, 28, 7, 188, 13, 76, 4, 10, 8, 12, 10, 12, 10, 8, 23, 8,
+        9, 7, 6, 7, 8, 7, 6, 55, 8, 23, 24, 12, 11, 7, 9, 11, 12, 6, 7, 22, 5,
+        7, 24, 6, 11, 9, 6, 7, 22, 7, 11, 38, 7, 9, 8, 25, 11, 8, 11, 9, 12,
+        8, 12, 5, 38, 5, 38, 5, 11, 7, 5, 6, 21, 6, 10, 53, 8, 7, 24, 10, 27,
+        44, 253, 253, 253, 252, 252, 252, 13, 12, 45, 12, 45, 12, 61, 12, 45,
+        44, 173};
+        /* bit lengths of length codes 0..15 */
+    static const unsigned char lenlen[] = {2, 35, 36, 53, 38, 23};
+        /* bit lengths of distance codes 0..63 */
+    static const unsigned char distlen[] = {2, 20, 53, 230, 247, 151, 248};
+    static const short base[16] = {     /* base for length codes */
+        3, 2, 4, 5, 6, 7, 8, 9, 10, 12, 16, 24, 40, 72, 136, 264};
+    static const char extra[16] = {     /* extra bits for length codes */
+        0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8};
+
+    /* set up decoding tables (once--might not be thread-safe) */
+    if (virgin) {
+        construct(&litcode, litlen, sizeof(litlen));
+        construct(&lencode, lenlen, sizeof(lenlen));
+        construct(&distcode, distlen, sizeof(distlen));
+        virgin = 0;
+    }
+
+    /* read header */
+    lit = bits(s, 8);
+    if (lit > 1) return -1;
+    dict = bits(s, 8);
+    if (dict < 4 || dict > 6) return -2;
+
+    /* decode literals and length/distance pairs */
+    do {
+        if (bits(s, 1)) {
+            /* get length */
+            symbol = decode(s, &lencode);
+            len = base[symbol] + bits(s, extra[symbol]);
+            if (len == 519) break;              /* end code */
+
+            /* get distance */
+            symbol = len == 2 ? 2 : dict;
+            dist = decode(s, &distcode) << symbol;
+            dist += bits(s, symbol);
+            dist++;
+            if (s->first && dist > s->next)
+                return -3;              /* distance too far back */
+
+            /* copy length bytes from distance bytes back */
+            do {
+                to = s->out + s->next;
+                from = to - dist;
+                copy = MAXWIN;
+                if (s->next < dist) {
+                    from += copy;
+                    copy = dist;
+                }
+                copy -= s->next;
+                if (copy > len) copy = len;
+                len -= copy;
+                s->next += copy;
+                do {
+                    *to++ = *from++;
+                } while (--copy);
+                if (s->next == MAXWIN) {
+                    if (s->outfun(s->outhow, s->out, s->next)) return 1;
+                    s->next = 0;
+                    s->first = 0;
+                }
+            } while (len != 0);
+        }
+        else {
+            /* get literal and write it */
+            symbol = lit ? decode(s, &litcode) : bits(s, 8);
+            s->out[s->next++] = symbol;
+            if (s->next == MAXWIN) {
+                if (s->outfun(s->outhow, s->out, s->next)) return 1;
+                s->next = 0;
+                s->first = 0;
+            }
+        }
+    } while (1);
+    return 0;
+}
+
+/* See comments in blast.h */
+int blast(blast_in infun, void *inhow, blast_out outfun, void *outhow)
+{
+    struct state s;             /* input/output state */
+    int err;                    /* return value */
+
+    /* initialize input state */
+    s.infun = infun;
+    s.inhow = inhow;
+    s.left = 0;
+    s.bitbuf = 0;
+    s.bitcnt = 0;
+
+    /* initialize output state */
+    s.outfun = outfun;
+    s.outhow = outhow;
+    s.next = 0;
+    s.first = 1;
+
+    /* return if bits() or decode() tries to read past available input */
+    if (setjmp(s.env) != 0)             /* if came back here via longjmp(), */
+        err = 2;                        /*  then skip decomp(), return error */
+    else
+        err = decomp(&s);               /* decompress */
+
+    /* write any leftover output and update the error code if needed */
+    if (err != 1 && s.next && s.outfun(s.outhow, s.out, s.next) && err == 0)
+        err = 1;
+    return err;
+}
+
+#ifdef TEST
+/* Example of how to use blast() */
+#include <stdio.h>
+#include <stdlib.h>
+
+#define CHUNK 16384
+
+local unsigned inf(void *how, unsigned char **buf)
+{
+    static unsigned char hold[CHUNK];
+
+    *buf = hold;
+    return fread(hold, 1, CHUNK, (FILE *)how);
+}
+
+local int outf(void *how, unsigned char *buf, unsigned len)
+{
+    return fwrite(buf, 1, len, (FILE *)how) != len;
+}
+
+/* Decompress a PKWare Compression Library stream from stdin to stdout */
+int main(void)
+{
+    int ret, n;
+
+    /* decompress to stdout */
+    ret = blast(inf, stdin, outf, stdout);
+    if (ret != 0) fprintf(stderr, "blast error: %d\n", ret);
+
+    /* see if there are any leftover bytes */
+    n = 0;
+    while (getchar() != EOF) n++;
+    if (n) fprintf(stderr, "blast warning: %d unused bytes of input\n", n);
+
+    /* return blast() error code */
+    return ret;
+}
+#endif
diff --git a/compat/zlib/contrib/blast/blast.h b/compat/zlib/contrib/blast/blast.h
new file mode 100644
index 0000000..658cfd3
--- /dev/null
+++ b/compat/zlib/contrib/blast/blast.h
@@ -0,0 +1,75 @@
+/* blast.h -- interface for blast.c
+  Copyright (C) 2003, 2012 Mark Adler
+  version 1.2, 24 Oct 2012
+
+  This software is provided 'as-is', without any express or implied
+  warranty.  In no event will the author be held liable for any damages
+  arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any purpose,
+  including commercial applications, and to alter it and redistribute it
+  freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+
+  Mark Adler    madler@alumni.caltech.edu
+ */
+
+
+/*
+ * blast() decompresses the PKWare Data Compression Library (DCL) compressed
+ * format.  It provides the same functionality as the explode() function in
+ * that library.  (Note: PKWare overused the "implode" verb, and the format
+ * used by their library implode() function is completely different and
+ * incompatible with the implode compression method supported by PKZIP.)
+ *
+ * The binary mode for stdio functions should be used to assure that the
+ * compressed data is not corrupted when read or written.  For example:
+ * fopen(..., "rb") and fopen(..., "wb").
+ */
+
+
+typedef unsigned (*blast_in)(void *how, unsigned char **buf);
+typedef int (*blast_out)(void *how, unsigned char *buf, unsigned len);
+/* Definitions for input/output functions passed to blast().  See below for
+ * what the provided functions need to do.
+ */
+
+
+int blast(blast_in infun, void *inhow, blast_out outfun, void *outhow);
+/* Decompress input to output using the provided infun() and outfun() calls.
+ * On success, the return value of blast() is zero.  If there is an error in
+ * the source data, i.e. it is not in the proper format, then a negative value
+ * is returned.  If there is not enough input available or there is not enough
+ * output space, then a positive error is returned.
+ *
+ * The input function is invoked: len = infun(how, &buf), where buf is set by
+ * infun() to point to the input buffer, and infun() returns the number of
+ * available bytes there.  If infun() returns zero, then blast() returns with
+ * an input error.  (blast() only asks for input if it needs it.)  inhow is for
+ * use by the application to pass an input descriptor to infun(), if desired.
+ *
+ * The output function is invoked: err = outfun(how, buf, len), where the bytes
+ * to be written are buf[0..len-1].  If err is not zero, then blast() returns
+ * with an output error.  outfun() is always called with len <= 4096.  outhow
+ * is for use by the application to pass an output descriptor to outfun(), if
+ * desired.
+ *
+ * The return codes are:
+ *
+ *   2:  ran out of input before completing decompression
+ *   1:  output error before completing decompression
+ *   0:  successful decompression
+ *  -1:  literal flag not zero or one
+ *  -2:  dictionary size not in 4..6
+ *  -3:  distance is too far back
+ *
+ * At the bottom of blast.c is an example program that uses blast() that can be
+ * compiled to produce a command-line decompression filter by defining TEST.
+ */
diff --git a/compat/zlib/contrib/blast/test.pk b/compat/zlib/contrib/blast/test.pk
new file mode 100644
index 0000000..be10b2b
Binary files /dev/null and b/compat/zlib/contrib/blast/test.pk differ
diff --git a/compat/zlib/contrib/blast/test.txt b/compat/zlib/contrib/blast/test.txt
new file mode 100644
index 0000000..bfdf1c5
--- /dev/null
+++ b/compat/zlib/contrib/blast/test.txt
@@ -0,0 +1 @@
+AIAIAIAIAIAIA
\ No newline at end of file
diff --git a/compat/zlib/contrib/delphi/ZLib.pas b/compat/zlib/contrib/delphi/ZLib.pas
new file mode 100644
index 0000000..a579974
--- /dev/null
+++ b/compat/zlib/contrib/delphi/ZLib.pas
@@ -0,0 +1,557 @@
+{*******************************************************}
+{                                                       }
+{       Borland Delphi Supplemental Components          }
+{       ZLIB Data Compression Interface Unit            }
+{                                                       }
+{       Copyright (c) 1997,99 Borland Corporation       }
+{                                                       }
+{*******************************************************}
+
+{ Updated for zlib 1.2.x by Cosmin Truta <cosmint@cs.ubbcluj.ro> }
+
+unit ZLib;
+
+interface
+
+uses SysUtils, Classes;
+
+type
+  TAlloc = function (AppData: Pointer; Items, Size: Integer): Pointer; cdecl;
+  TFree = procedure (AppData, Block: Pointer); cdecl;
+
+  // Internal structure.  Ignore.
+  TZStreamRec = packed record
+    next_in: PChar;       // next input byte
+    avail_in: Integer;    // number of bytes available at next_in
+    total_in: Longint;    // total nb of input bytes read so far
+
+    next_out: PChar;      // next output byte should be put here
+    avail_out: Integer;   // remaining free space at next_out
+    total_out: Longint;   // total nb of bytes output so far
+
+    msg: PChar;           // last error message, NULL if no error
+    internal: Pointer;    // not visible by applications
+
+    zalloc: TAlloc;       // used to allocate the internal state
+    zfree: TFree;         // used to free the internal state
+    AppData: Pointer;     // private data object passed to zalloc and zfree
+
+    data_type: Integer;   // best guess about the data type: ascii or binary
+    adler: Longint;       // adler32 value of the uncompressed data
+    reserved: Longint;    // reserved for future use
+  end;
+
+  // Abstract ancestor class
+  TCustomZlibStream = class(TStream)
+  private
+    FStrm: TStream;
+    FStrmPos: Integer;
+    FOnProgress: TNotifyEvent;
+    FZRec: TZStreamRec;
+    FBuffer: array [Word] of Char;
+  protected
+    procedure Progress(Sender: TObject); dynamic;
+    property OnProgress: TNotifyEvent read FOnProgress write FOnProgress;
+    constructor Create(Strm: TStream);
+  end;
+
+{ TCompressionStream compresses data on the fly as data is written to it, and
+  stores the compressed data to another stream.
+
+  TCompressionStream is write-only and strictly sequential. Reading from the
+  stream will raise an exception. Using Seek to move the stream pointer
+  will raise an exception.
+
+  Output data is cached internally, written to the output stream only when
+  the internal output buffer is full.  All pending output data is flushed
+  when the stream is destroyed.
+
+  The Position property returns the number of uncompressed bytes of
+  data that have been written to the stream so far.
+
+  CompressionRate returns the on-the-fly percentage by which the original
+  data has been compressed:  (1 - (CompressedBytes / UncompressedBytes)) * 100
+  If raw data size = 100 and compressed data size = 25, the CompressionRate
+  is 75%
+
+  The OnProgress event is called each time the output buffer is filled and
+  written to the output stream.  This is useful for updating a progress
+  indicator when you are writing a large chunk of data to the compression
+  stream in a single call.}
+
+
+  TCompressionLevel = (clNone, clFastest, clDefault, clMax);
+
+  TCompressionStream = class(TCustomZlibStream)
+  private
+    function GetCompressionRate: Single;
+  public
+    constructor Create(CompressionLevel: TCompressionLevel; Dest: TStream);
+    destructor Destroy; override;
+    function Read(var Buffer; Count: Longint): Longint; override;
+    function Write(const Buffer; Count: Longint): Longint; override;
+    function Seek(Offset: Longint; Origin: Word): Longint; override;
+    property CompressionRate: Single read GetCompressionRate;
+    property OnProgress;
+  end;
+
+{ TDecompressionStream decompresses data on the fly as data is read from it.
+
+  Compressed data comes from a separate source stream.  TDecompressionStream
+  is read-only and unidirectional; you can seek forward in the stream, but not
+  backwards.  The special case of setting the stream position to zero is
+  allowed.  Seeking forward decompresses data until the requested position in
+  the uncompressed data has been reached.  Seeking backwards, seeking relative
+  to the end of the stream, requesting the size of the stream, and writing to
+  the stream will raise an exception.
+
+  The Position property returns the number of bytes of uncompressed data that
+  have been read from the stream so far.
+
+  The OnProgress event is called each time the internal input buffer of
+  compressed data is exhausted and the next block is read from the input stream.
+  This is useful for updating a progress indicator when you are reading a
+  large chunk of data from the decompression stream in a single call.}
+
+  TDecompressionStream = class(TCustomZlibStream)
+  public
+    constructor Create(Source: TStream);
+    destructor Destroy; override;
+    function Read(var Buffer; Count: Longint): Longint; override;
+    function Write(const Buffer; Count: Longint): Longint; override;
+    function Seek(Offset: Longint; Origin: Word): Longint; override;
+    property OnProgress;
+  end;
+
+
+
+{ CompressBuf compresses data, buffer to buffer, in one call.
+   In: InBuf = ptr to compressed data
+       InBytes = number of bytes in InBuf
+  Out: OutBuf = ptr to newly allocated buffer containing decompressed data
+       OutBytes = number of bytes in OutBuf   }
+procedure CompressBuf(const InBuf: Pointer; InBytes: Integer;
+                      out OutBuf: Pointer; out OutBytes: Integer);
+
+
+{ DecompressBuf decompresses data, buffer to buffer, in one call.
+   In: InBuf = ptr to compressed data
+       InBytes = number of bytes in InBuf
+       OutEstimate = zero, or est. size of the decompressed data
+  Out: OutBuf = ptr to newly allocated buffer containing decompressed data
+       OutBytes = number of bytes in OutBuf   }
+procedure DecompressBuf(const InBuf: Pointer; InBytes: Integer;
+ OutEstimate: Integer; out OutBuf: Pointer; out OutBytes: Integer);
+
+{ DecompressToUserBuf decompresses data, buffer to buffer, in one call.
+   In: InBuf = ptr to compressed data
+       InBytes = number of bytes in InBuf
+  Out: OutBuf = ptr to user-allocated buffer to contain decompressed data
+       BufSize = number of bytes in OutBuf   }
+procedure DecompressToUserBuf(const InBuf: Pointer; InBytes: Integer;
+  const OutBuf: Pointer; BufSize: Integer);
+
+const
+  zlib_version = '1.2.8';
+
+type
+  EZlibError = class(Exception);
+  ECompressionError = class(EZlibError);
+  EDecompressionError = class(EZlibError);
+
+implementation
+
+uses ZLibConst;
+
+const
+  Z_NO_FLUSH      = 0;
+  Z_PARTIAL_FLUSH = 1;
+  Z_SYNC_FLUSH    = 2;
+  Z_FULL_FLUSH    = 3;
+  Z_FINISH        = 4;
+
+  Z_OK            = 0;
+  Z_STREAM_END    = 1;
+  Z_NEED_DICT     = 2;
+  Z_ERRNO         = (-1);
+  Z_STREAM_ERROR  = (-2);
+  Z_DATA_ERROR    = (-3);
+  Z_MEM_ERROR     = (-4);
+  Z_BUF_ERROR     = (-5);
+  Z_VERSION_ERROR = (-6);
+
+  Z_NO_COMPRESSION       =   0;
+  Z_BEST_SPEED           =   1;
+  Z_BEST_COMPRESSION     =   9;
+  Z_DEFAULT_COMPRESSION  = (-1);
+
+  Z_FILTERED            = 1;
+  Z_HUFFMAN_ONLY        = 2;
+  Z_RLE                 = 3;
+  Z_DEFAULT_STRATEGY    = 0;
+
+  Z_BINARY   = 0;
+  Z_ASCII    = 1;
+  Z_UNKNOWN  = 2;
+
+  Z_DEFLATED = 8;
+
+
+{$L adler32.obj}
+{$L compress.obj}
+{$L crc32.obj}
+{$L deflate.obj}
+{$L infback.obj}
+{$L inffast.obj}
+{$L inflate.obj}
+{$L inftrees.obj}
+{$L trees.obj}
+{$L uncompr.obj}
+{$L zutil.obj}
+
+procedure adler32; external;
+procedure compressBound; external;
+procedure crc32; external;
+procedure deflateInit2_; external;
+procedure deflateParams; external;
+
+function _malloc(Size: Integer): Pointer; cdecl;
+begin
+  Result := AllocMem(Size);
+end;
+
+procedure _free(Block: Pointer); cdecl;
+begin
+  FreeMem(Block);
+end;
+
+procedure _memset(P: Pointer; B: Byte; count: Integer); cdecl;
+begin
+  FillChar(P^, count, B);
+end;
+
+procedure _memcpy(dest, source: Pointer; count: Integer); cdecl;
+begin
+  Move(source^, dest^, count);
+end;
+
+
+
+// deflate compresses data
+function deflateInit_(var strm: TZStreamRec; level: Integer; version: PChar;
+  recsize: Integer): Integer; external;
+function deflate(var strm: TZStreamRec; flush: Integer): Integer; external;
+function deflateEnd(var strm: TZStreamRec): Integer; external;
+
+// inflate decompresses data
+function inflateInit_(var strm: TZStreamRec; version: PChar;
+  recsize: Integer): Integer; external;
+function inflate(var strm: TZStreamRec; flush: Integer): Integer; external;
+function inflateEnd(var strm: TZStreamRec): Integer; external;
+function inflateReset(var strm: TZStreamRec): Integer; external;
+
+
+function zlibAllocMem(AppData: Pointer; Items, Size: Integer): Pointer; cdecl;
+begin
+//  GetMem(Result, Items*Size);
+  Result := AllocMem(Items * Size);
+end;
+
+procedure zlibFreeMem(AppData, Block: Pointer); cdecl;
+begin
+  FreeMem(Block);
+end;
+
+{function zlibCheck(code: Integer): Integer;
+begin
+  Result := code;
+  if code < 0 then
+    raise EZlibError.Create('error');    //!!
+end;}
+
+function CCheck(code: Integer): Integer;
+begin
+  Result := code;
+  if code < 0 then
+    raise ECompressionError.Create('error'); //!!
+end;
+
+function DCheck(code: Integer): Integer;
+begin
+  Result := code;
+  if code < 0 then
+    raise EDecompressionError.Create('error');  //!!
+end;
+
+procedure CompressBuf(const InBuf: Pointer; InBytes: Integer;
+                      out OutBuf: Pointer; out OutBytes: Integer);
+var
+  strm: TZStreamRec;
+  P: Pointer;
+begin
+  FillChar(strm, sizeof(strm), 0);
+  strm.zalloc := zlibAllocMem;
+  strm.zfree := zlibFreeMem;
+  OutBytes := ((InBytes + (InBytes div 10) + 12) + 255) and not 255;
+  GetMem(OutBuf, OutBytes);
+  try
+    strm.next_in := InBuf;
+    strm.avail_in := InBytes;
+    strm.next_out := OutBuf;
+    strm.avail_out := OutBytes;
+    CCheck(deflateInit_(strm, Z_BEST_COMPRESSION, zlib_version, sizeof(strm)));
+    try
+      while CCheck(deflate(strm, Z_FINISH)) <> Z_STREAM_END do
+      begin
+        P := OutBuf;
+        Inc(OutBytes, 256);
+        ReallocMem(OutBuf, OutBytes);
+        strm.next_out := PChar(Integer(OutBuf) + (Integer(strm.next_out) - Integer(P)));
+        strm.avail_out := 256;
+      end;
+    finally
+      CCheck(deflateEnd(strm));
+    end;
+    ReallocMem(OutBuf, strm.total_out);
+    OutBytes := strm.total_out;
+  except
+    FreeMem(OutBuf);
+    raise
+  end;
+end;
+
+
+procedure DecompressBuf(const InBuf: Pointer; InBytes: Integer;
+  OutEstimate: Integer; out OutBuf: Pointer; out OutBytes: Integer);
+var
+  strm: TZStreamRec;
+  P: Pointer;
+  BufInc: Integer;
+begin
+  FillChar(strm, sizeof(strm), 0);
+  strm.zalloc := zlibAllocMem;
+  strm.zfree := zlibFreeMem;
+  BufInc := (InBytes + 255) and not 255;
+  if OutEstimate = 0 then
+    OutBytes := BufInc
+  else
+    OutBytes := OutEstimate;
+  GetMem(OutBuf, OutBytes);
+  try
+    strm.next_in := InBuf;
+    strm.avail_in := InBytes;
+    strm.next_out := OutBuf;
+    strm.avail_out := OutBytes;
+    DCheck(inflateInit_(strm, zlib_version, sizeof(strm)));
+    try
+      while DCheck(inflate(strm, Z_NO_FLUSH)) <> Z_STREAM_END do
+      begin
+        P := OutBuf;
+        Inc(OutBytes, BufInc);
+        ReallocMem(OutBuf, OutBytes);
+        strm.next_out := PChar(Integer(OutBuf) + (Integer(strm.next_out) - Integer(P)));
+        strm.avail_out := BufInc;
+      end;
+    finally
+      DCheck(inflateEnd(strm));
+    end;
+    ReallocMem(OutBuf, strm.total_out);
+    OutBytes := strm.total_out;
+  except
+    FreeMem(OutBuf);
+    raise
+  end;
+end;
+
+procedure DecompressToUserBuf(const InBuf: Pointer; InBytes: Integer;
+  const OutBuf: Pointer; BufSize: Integer);
+var
+  strm: TZStreamRec;
+begin
+  FillChar(strm, sizeof(strm), 0);
+  strm.zalloc := zlibAllocMem;
+  strm.zfree := zlibFreeMem;
+  strm.next_in := InBuf;
+  strm.avail_in := InBytes;
+  strm.next_out := OutBuf;
+  strm.avail_out := BufSize;
+  DCheck(inflateInit_(strm, zlib_version, sizeof(strm)));
+  try
+    if DCheck(inflate(strm, Z_FINISH)) <> Z_STREAM_END then
+      raise EZlibError.CreateRes(@sTargetBufferTooSmall);
+  finally
+    DCheck(inflateEnd(strm));
+  end;
+end;
+
+// TCustomZlibStream
+
+constructor TCustomZLibStream.Create(Strm: TStream);
+begin
+  inherited Create;
+  FStrm := Strm;
+  FStrmPos := Strm.Position;
+  FZRec.zalloc := zlibAllocMem;
+  FZRec.zfree := zlibFreeMem;
+end;
+
+procedure TCustomZLibStream.Progress(Sender: TObject);
+begin
+  if Assigned(FOnProgress) then FOnProgress(Sender);
+end;
+
+
+// TCompressionStream
+
+constructor TCompressionStream.Create(CompressionLevel: TCompressionLevel;
+  Dest: TStream);
+const
+  Levels: array [TCompressionLevel] of ShortInt =
+    (Z_NO_COMPRESSION, Z_BEST_SPEED, Z_DEFAULT_COMPRESSION, Z_BEST_COMPRESSION);
+begin
+  inherited Create(Dest);
+  FZRec.next_out := FBuffer;
+  FZRec.avail_out := sizeof(FBuffer);
+  CCheck(deflateInit_(FZRec, Levels[CompressionLevel], zlib_version, sizeof(FZRec)));
+end;
+
+destructor TCompressionStream.Destroy;
+begin
+  FZRec.next_in := nil;
+  FZRec.avail_in := 0;
+  try
+    if FStrm.Position <> FStrmPos then FStrm.Position := FStrmPos;
+    while (CCheck(deflate(FZRec, Z_FINISH)) <> Z_STREAM_END)
+      and (FZRec.avail_out = 0) do
+    begin
+      FStrm.WriteBuffer(FBuffer, sizeof(FBuffer));
+      FZRec.next_out := FBuffer;
+      FZRec.avail_out := sizeof(FBuffer);
+    end;
+    if FZRec.avail_out < sizeof(FBuffer) then
+      FStrm.WriteBuffer(FBuffer, sizeof(FBuffer) - FZRec.avail_out);
+  finally
+    deflateEnd(FZRec);
+  end;
+  inherited Destroy;
+end;
+
+function TCompressionStream.Read(var Buffer; Count: Longint): Longint;
+begin
+  raise ECompressionError.CreateRes(@sInvalidStreamOp);
+end;
+
+function TCompressionStream.Write(const Buffer; Count: Longint): Longint;
+begin
+  FZRec.next_in := @Buffer;
+  FZRec.avail_in := Count;
+  if FStrm.Position <> FStrmPos then FStrm.Position := FStrmPos;
+  while (FZRec.avail_in > 0) do
+  begin
+    CCheck(deflate(FZRec, 0));
+    if FZRec.avail_out = 0 then
+    begin
+      FStrm.WriteBuffer(FBuffer, sizeof(FBuffer));
+      FZRec.next_out := FBuffer;
+      FZRec.avail_out := sizeof(FBuffer);
+      FStrmPos := FStrm.Position;
+      Progress(Self);
+    end;
+  end;
+  Result := Count;
+end;
+
+function TCompressionStream.Seek(Offset: Longint; Origin: Word): Longint;
+begin
+  if (Offset = 0) and (Origin = soFromCurrent) then
+    Result := FZRec.total_in
+  else
+    raise ECompressionError.CreateRes(@sInvalidStreamOp);
+end;
+
+function TCompressionStream.GetCompressionRate: Single;
+begin
+  if FZRec.total_in = 0 then
+    Result := 0
+  else
+    Result := (1.0 - (FZRec.total_out / FZRec.total_in)) * 100.0;
+end;
+
+
+// TDecompressionStream
+
+constructor TDecompressionStream.Create(Source: TStream);
+begin
+  inherited Create(Source);
+  FZRec.next_in := FBuffer;
+  FZRec.avail_in := 0;
+  DCheck(inflateInit_(FZRec, zlib_version, sizeof(FZRec)));
+end;
+
+destructor TDecompressionStream.Destroy;
+begin
+  FStrm.Seek(-FZRec.avail_in, 1);
+  inflateEnd(FZRec);
+  inherited Destroy;
+end;
+
+function TDecompressionStream.Read(var Buffer; Count: Longint): Longint;
+begin
+  FZRec.next_out := @Buffer;
+  FZRec.avail_out := Count;
+  if FStrm.Position <> FStrmPos then FStrm.Position := FStrmPos;
+  while (FZRec.avail_out > 0) do
+  begin
+    if FZRec.avail_in = 0 then
+    begin
+      FZRec.avail_in := FStrm.Read(FBuffer, sizeof(FBuffer));
+      if FZRec.avail_in = 0 then
+      begin
+        Result := Count - FZRec.avail_out;
+        Exit;
+      end;
+      FZRec.next_in := FBuffer;
+      FStrmPos := FStrm.Position;
+      Progress(Self);
+    end;
+    CCheck(inflate(FZRec, 0));
+  end;
+  Result := Count;
+end;
+
+function TDecompressionStream.Write(const Buffer; Count: Longint): Longint;
+begin
+  raise EDecompressionError.CreateRes(@sInvalidStreamOp);
+end;
+
+function TDecompressionStream.Seek(Offset: Longint; Origin: Word): Longint;
+var
+  I: Integer;
+  Buf: array [0..4095] of Char;
+begin
+  if (Offset = 0) and (Origin = soFromBeginning) then
+  begin
+    DCheck(inflateReset(FZRec));
+    FZRec.next_in := FBuffer;
+    FZRec.avail_in := 0;
+    FStrm.Position := 0;
+    FStrmPos := 0;
+  end
+  else if ( (Offset >= 0) and (Origin = soFromCurrent)) or
+          ( ((Offset - FZRec.total_out) > 0) and (Origin = soFromBeginning)) then
+  begin
+    if Origin = soFromBeginning then Dec(Offset, FZRec.total_out);
+    if Offset > 0 then
+    begin
+      for I := 1 to Offset div sizeof(Buf) do
+        ReadBuffer(Buf, sizeof(Buf));
+      ReadBuffer(Buf, Offset mod sizeof(Buf));
+    end;
+  end
+  else
+    raise EDecompressionError.CreateRes(@sInvalidStreamOp);
+  Result := FZRec.total_out;
+end;
+
+
+end.
diff --git a/compat/zlib/contrib/delphi/ZLibConst.pas b/compat/zlib/contrib/delphi/ZLibConst.pas
new file mode 100644
index 0000000..cdfe136
--- /dev/null
+++ b/compat/zlib/contrib/delphi/ZLibConst.pas
@@ -0,0 +1,11 @@
+unit ZLibConst;
+
+interface
+
+resourcestring
+  sTargetBufferTooSmall = 'ZLib error: target buffer may be too small';
+  sInvalidStreamOp = 'Invalid stream operation';
+
+implementation
+
+end.
diff --git a/compat/zlib/contrib/delphi/readme.txt b/compat/zlib/contrib/delphi/readme.txt
new file mode 100644
index 0000000..2dc9a8b
--- /dev/null
+++ b/compat/zlib/contrib/delphi/readme.txt
@@ -0,0 +1,76 @@
+
+Overview
+========
+
+This directory contains an update to the ZLib interface unit,
+distributed by Borland as a Delphi supplemental component.
+
+The original ZLib unit is Copyright (c) 1997,99 Borland Corp.,
+and is based on zlib version 1.0.4.  There are a series of bugs
+and security problems associated with that old zlib version, and
+we recommend the users to update their ZLib unit.
+
+
+Summary of modifications
+========================
+
+- Improved makefile, adapted to zlib version 1.2.1.
+
+- Some field types from TZStreamRec are changed from Integer to
+  Longint, for consistency with the zlib.h header, and for 64-bit
+  readiness.
+
+- The zlib_version constant is updated.
+
+- The new Z_RLE strategy has its corresponding symbolic constant.
+
+- The allocation and deallocation functions and function types
+  (TAlloc, TFree, zlibAllocMem and zlibFreeMem) are now cdecl,
+  and _malloc and _free are added as C RTL stubs.  As a result,
+  the original C sources of zlib can be compiled out of the box,
+  and linked to the ZLib unit.
+
+
+Suggestions for improvements
+============================
+
+Currently, the ZLib unit provides only a limited wrapper around
+the zlib library, and much of the original zlib functionality is
+missing.  Handling compressed file formats like ZIP/GZIP or PNG
+cannot be implemented without having this functionality.
+Applications that handle these formats are either using their own,
+duplicated code, or not using the ZLib unit at all.
+
+Here are a few suggestions:
+
+- Checksum class wrappers around adler32() and crc32(), similar
+  to the Java classes that implement the java.util.zip.Checksum
+  interface.
+
+- The ability to read and write raw deflate streams, without the
+  zlib stream header and trailer.  Raw deflate streams are used
+  in the ZIP file format.
+
+- The ability to read and write gzip streams, used in the GZIP
+  file format, and normally produced by the gzip program.
+
+- The ability to select a different compression strategy, useful
+  to PNG and MNG image compression, and to multimedia compression
+  in general.  Besides the compression level
+
+    TCompressionLevel = (clNone, clFastest, clDefault, clMax);
+
+  which, in fact, could have used the 'z' prefix and avoided
+  TColor-like symbols
+
+    TCompressionLevel = (zcNone, zcFastest, zcDefault, zcMax);
+
+  there could be a compression strategy
+
+    TCompressionStrategy = (zsDefault, zsFiltered, zsHuffmanOnly, zsRle);
+
+- ZIP and GZIP stream handling via TStreams.
+
+
+--
+Cosmin Truta <cosmint@cs.ubbcluj.ro>
diff --git a/compat/zlib/contrib/delphi/zlibd32.mak b/compat/zlib/contrib/delphi/zlibd32.mak
new file mode 100644
index 0000000..9bb00b7
--- /dev/null
+++ b/compat/zlib/contrib/delphi/zlibd32.mak
@@ -0,0 +1,99 @@
+# Makefile for zlib
+# For use with Delphi and C++ Builder under Win32
+# Updated for zlib 1.2.x by Cosmin Truta
+
+# ------------ Borland C++ ------------
+
+# This project uses the Delphi (fastcall/register) calling convention:
+LOC = -DZEXPORT=__fastcall -DZEXPORTVA=__cdecl
+
+CC = bcc32
+LD = bcc32
+AR = tlib
+# do not use "-pr" in CFLAGS
+CFLAGS = -a -d -k- -O2 $(LOC)
+LDFLAGS =
+
+
+# variables
+ZLIB_LIB = zlib.lib
+
+OBJ1 = adler32.obj compress.obj crc32.obj deflate.obj gzclose.obj gzlib.obj gzread.obj
+OBJ2 = gzwrite.obj infback.obj inffast.obj inflate.obj inftrees.obj trees.obj uncompr.obj zutil.obj
+OBJP1 = +adler32.obj+compress.obj+crc32.obj+deflate.obj+gzclose.obj+gzlib.obj+gzread.obj
+OBJP2 = +gzwrite.obj+infback.obj+inffast.obj+inflate.obj+inftrees.obj+trees.obj+uncompr.obj+zutil.obj
+
+
+# targets
+all: $(ZLIB_LIB) example.exe minigzip.exe
+
+.c.obj:
+	$(CC) -c $(CFLAGS) $*.c
+
+adler32.obj: adler32.c zlib.h zconf.h
+
+compress.obj: compress.c zlib.h zconf.h
+
+crc32.obj: crc32.c zlib.h zconf.h crc32.h
+
+deflate.obj: deflate.c deflate.h zutil.h zlib.h zconf.h
+
+gzclose.obj: gzclose.c zlib.h zconf.h gzguts.h
+
+gzlib.obj: gzlib.c zlib.h zconf.h gzguts.h
+
+gzread.obj: gzread.c zlib.h zconf.h gzguts.h
+
+gzwrite.obj: gzwrite.c zlib.h zconf.h gzguts.h
+
+infback.obj: infback.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
+ inffast.h inffixed.h
+
+inffast.obj: inffast.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
+ inffast.h
+
+inflate.obj: inflate.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
+ inffast.h inffixed.h
+
+inftrees.obj: inftrees.c zutil.h zlib.h zconf.h inftrees.h
+
+trees.obj: trees.c zutil.h zlib.h zconf.h deflate.h trees.h
+
+uncompr.obj: uncompr.c zlib.h zconf.h
+
+zutil.obj: zutil.c zutil.h zlib.h zconf.h
+
+example.obj: test/example.c zlib.h zconf.h
+
+minigzip.obj: test/minigzip.c zlib.h zconf.h
+
+
+# For the sake of the old Borland make,
+# the command line is cut to fit in the MS-DOS 128 byte limit:
+$(ZLIB_LIB): $(OBJ1) $(OBJ2)
+	-del $(ZLIB_LIB)
+	$(AR) $(ZLIB_LIB) $(OBJP1)
+	$(AR) $(ZLIB_LIB) $(OBJP2)
+
+
+# testing
+test: example.exe minigzip.exe
+	example
+	echo hello world | minigzip | minigzip -d
+
+example.exe: example.obj $(ZLIB_LIB)
+	$(LD) $(LDFLAGS) example.obj $(ZLIB_LIB)
+
+minigzip.exe: minigzip.obj $(ZLIB_LIB)
+	$(LD) $(LDFLAGS) minigzip.obj $(ZLIB_LIB)
+
+
+# cleanup
+clean:
+	-del *.obj
+	-del *.exe
+	-del *.lib
+	-del *.tds
+	-del zlib.bak
+	-del foo.gz
+
diff --git a/compat/zlib/contrib/dotzlib/DotZLib.build b/compat/zlib/contrib/dotzlib/DotZLib.build
new file mode 100644
index 0000000..7f90d6b
--- /dev/null
+++ b/compat/zlib/contrib/dotzlib/DotZLib.build
@@ -0,0 +1,33 @@
+﻿<?xml version="1.0" encoding="utf-8" ?>
+<project name="DotZLib" default="build" basedir="./DotZLib">
+	<description>A .Net wrapper library around ZLib1.dll</description>
+
+	<property name="nunit.location" value="c:/program files/NUnit V2.1/bin" />
+	<property name="build.root" value="bin" />
+
+	<property name="debug" value="true" />
+	<property name="nunit" value="true" />
+
+	<property name="build.folder" value="${build.root}/debug/" if="${debug}" />
+	<property name="build.folder" value="${build.root}/release/" unless="${debug}" />
+
+	<target name="clean" description="Remove all generated files">
+		<delete dir="${build.root}" failonerror="false" />
+	</target>
+
+	<target name="build" description="compiles the source code">
+
+		<mkdir dir="${build.folder}" />
+		<csc target="library" output="${build.folder}DotZLib.dll" debug="${debug}">
+			<references basedir="${nunit.location}">
+				<includes if="${nunit}" name="nunit.framework.dll" />
+			</references>
+			<sources>
+				<includes name="*.cs" />
+				<excludes name="UnitTests.cs" unless="${nunit}" />
+			</sources>
+			<arg value="/d:nunit" if="${nunit}" />
+		</csc>
+	</target>
+
+</project>
\ No newline at end of file
diff --git a/compat/zlib/contrib/dotzlib/DotZLib.chm b/compat/zlib/contrib/dotzlib/DotZLib.chm
new file mode 100644
index 0000000..f214a44
Binary files /dev/null and b/compat/zlib/contrib/dotzlib/DotZLib.chm differ
diff --git a/compat/zlib/contrib/dotzlib/DotZLib.sln b/compat/zlib/contrib/dotzlib/DotZLib.sln
new file mode 100644
index 0000000..ac45ca0
--- /dev/null
+++ b/compat/zlib/contrib/dotzlib/DotZLib.sln
@@ -0,0 +1,21 @@
+Microsoft Visual Studio Solution File, Format Version 8.00
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DotZLib", "DotZLib\DotZLib.csproj", "{BB1EE0B1-1808-46CB-B786-949D91117FC5}"
+	ProjectSection(ProjectDependencies) = postProject
+	EndProjectSection
+EndProject
+Global
+	GlobalSection(SolutionConfiguration) = preSolution
+		Debug = Debug
+		Release = Release
+	EndGlobalSection
+	GlobalSection(ProjectConfiguration) = postSolution
+		{BB1EE0B1-1808-46CB-B786-949D91117FC5}.Debug.ActiveCfg = Debug|.NET
+		{BB1EE0B1-1808-46CB-B786-949D91117FC5}.Debug.Build.0 = Debug|.NET
+		{BB1EE0B1-1808-46CB-B786-949D91117FC5}.Release.ActiveCfg = Release|.NET
+		{BB1EE0B1-1808-46CB-B786-949D91117FC5}.Release.Build.0 = Release|.NET
+	EndGlobalSection
+	GlobalSection(ExtensibilityGlobals) = postSolution
+	EndGlobalSection
+	GlobalSection(ExtensibilityAddIns) = postSolution
+	EndGlobalSection
+EndGlobal
diff --git a/compat/zlib/contrib/dotzlib/DotZLib/AssemblyInfo.cs b/compat/zlib/contrib/dotzlib/DotZLib/AssemblyInfo.cs
new file mode 100644
index 0000000..0491bfc
--- /dev/null
+++ b/compat/zlib/contrib/dotzlib/DotZLib/AssemblyInfo.cs
@@ -0,0 +1,58 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+
+//
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+//
+[assembly: AssemblyTitle("DotZLib")]
+[assembly: AssemblyDescription(".Net bindings for ZLib compression dll 1.2.x")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Henrik Ravn")]
+[assembly: AssemblyProduct("")]
+[assembly: AssemblyCopyright("(c) 2004 by Henrik Ravn")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+//
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version
+//      Build Number
+//      Revision
+//
+// You can specify all the values or you can default the Revision and Build Numbers
+// by using the '*' as shown below:
+
+[assembly: AssemblyVersion("1.0.*")]
+
+//
+// In order to sign your assembly you must specify a key to use. Refer to the
+// Microsoft .NET Framework documentation for more information on assembly signing.
+//
+// Use the attributes below to control which key is used for signing.
+//
+// Notes:
+//   (*) If no key is specified, the assembly is not signed.
+//   (*) KeyName refers to a key that has been installed in the Crypto Service
+//       Provider (CSP) on your machine. KeyFile refers to a file which contains
+//       a key.
+//   (*) If the KeyFile and the KeyName values are both specified, the
+//       following processing occurs:
+//       (1) If the KeyName can be found in the CSP, that key is used.
+//       (2) If the KeyName does not exist and the KeyFile does exist, the key
+//           in the KeyFile is installed into the CSP and used.
+//   (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility.
+//       When specifying the KeyFile, the location of the KeyFile should be
+//       relative to the project output directory which is
+//       %Project Directory%\obj\<configuration>. For example, if your KeyFile is
+//       located in the project directory, you would specify the AssemblyKeyFile
+//       attribute as [assembly: AssemblyKeyFile("..\\..\\mykey.snk")]
+//   (*) Delay Signing is an advanced option - see the Microsoft .NET Framework
+//       documentation for more information on this.
+//
+[assembly: AssemblyDelaySign(false)]
+[assembly: AssemblyKeyFile("")]
+[assembly: AssemblyKeyName("")]
diff --git a/compat/zlib/contrib/dotzlib/DotZLib/ChecksumImpl.cs b/compat/zlib/contrib/dotzlib/DotZLib/ChecksumImpl.cs
new file mode 100644
index 0000000..788b2fc
--- /dev/null
+++ b/compat/zlib/contrib/dotzlib/DotZLib/ChecksumImpl.cs
@@ -0,0 +1,202 @@
+//
+// � Copyright Henrik Ravn 2004
+//
+// Use, modification and distribution are subject to the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+using System;
+using System.Runtime.InteropServices;
+using System.Text;
+
+
+namespace DotZLib
+{
+    #region ChecksumGeneratorBase
+    /// <summary>
+    /// Implements the common functionality needed for all <see cref="ChecksumGenerator"/>s
+    /// </summary>
+    /// <example></example>
+    public abstract class ChecksumGeneratorBase : ChecksumGenerator
+    {
+        /// <summary>
+        /// The value of the current checksum
+        /// </summary>
+        protected uint _current;
+
+        /// <summary>
+        /// Initializes a new instance of the checksum generator base - the current checksum is
+        /// set to zero
+        /// </summary>
+        public ChecksumGeneratorBase()
+        {
+            _current = 0;
+        }
+
+        /// <summary>
+        /// Initializes a new instance of the checksum generator basewith a specified value
+        /// </summary>
+        /// <param name="initialValue">The value to set the current checksum to</param>
+        public ChecksumGeneratorBase(uint initialValue)
+        {
+            _current = initialValue;
+        }
+
+        /// <summary>
+        /// Resets the current checksum to zero
+        /// </summary>
+        public void Reset() { _current = 0; }
+
+        /// <summary>
+        /// Gets the current checksum value
+        /// </summary>
+        public uint Value { get { return _current; } }
+
+        /// <summary>
+        /// Updates the current checksum with part of an array of bytes
+        /// </summary>
+        /// <param name="data">The data to update the checksum with</param>
+        /// <param name="offset">Where in <c>data</c> to start updating</param>
+        /// <param name="count">The number of bytes from <c>data</c> to use</param>
+        /// <exception cref="ArgumentException">The sum of offset and count is larger than the length of <c>data</c></exception>
+        /// <exception cref="NullReferenceException"><c>data</c> is a null reference</exception>
+        /// <exception cref="ArgumentOutOfRangeException">Offset or count is negative.</exception>
+        /// <remarks>All the other <c>Update</c> methods are implmeneted in terms of this one.
+        /// This is therefore the only method a derived class has to implement</remarks>
+        public abstract void Update(byte[] data, int offset, int count);
+
+        /// <summary>
+        /// Updates the current checksum with an array of bytes.
+        /// </summary>
+        /// <param name="data">The data to update the checksum with</param>
+        public void Update(byte[] data)
+        {
+            Update(data, 0, data.Length);
+        }
+
+        /// <summary>
+        /// Updates the current checksum with the data from a string
+        /// </summary>
+        /// <param name="data">The string to update the checksum with</param>
+        /// <remarks>The characters in the string are converted by the UTF-8 encoding</remarks>
+        public void Update(string data)
+        {
+			Update(Encoding.UTF8.GetBytes(data));
+        }
+
+        /// <summary>
+        /// Updates the current checksum with the data from a string, using a specific encoding
+        /// </summary>
+        /// <param name="data">The string to update the checksum with</param>
+        /// <param name="encoding">The encoding to use</param>
+        public void Update(string data, Encoding encoding)
+        {
+            Update(encoding.GetBytes(data));
+        }
+
+    }
+    #endregion
+
+    #region CRC32
+    /// <summary>
+    /// Implements a CRC32 checksum generator
+    /// </summary>
+    public sealed class CRC32Checksum : ChecksumGeneratorBase
+    {
+        #region DLL imports
+
+        [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]
+        private static extern uint crc32(uint crc, int data, uint length);
+
+        #endregion
+
+        /// <summary>
+        /// Initializes a new instance of the CRC32 checksum generator
+        /// </summary>
+        public CRC32Checksum() : base() {}
+
+        /// <summary>
+        /// Initializes a new instance of the CRC32 checksum generator with a specified value
+        /// </summary>
+        /// <param name="initialValue">The value to set the current checksum to</param>
+        public CRC32Checksum(uint initialValue) : base(initialValue) {}
+
+        /// <summary>
+        /// Updates the current checksum with part of an array of bytes
+        /// </summary>
+        /// <param name="data">The data to update the checksum with</param>
+        /// <param name="offset">Where in <c>data</c> to start updating</param>
+        /// <param name="count">The number of bytes from <c>data</c> to use</param>
+        /// <exception cref="ArgumentException">The sum of offset and count is larger than the length of <c>data</c></exception>
+        /// <exception cref="NullReferenceException"><c>data</c> is a null reference</exception>
+        /// <exception cref="ArgumentOutOfRangeException">Offset or count is negative.</exception>
+        public override void Update(byte[] data, int offset, int count)
+        {
+            if (offset < 0 || count < 0) throw new ArgumentOutOfRangeException();
+            if ((offset+count) > data.Length) throw new ArgumentException();
+            GCHandle hData = GCHandle.Alloc(data, GCHandleType.Pinned);
+            try
+            {
+                _current = crc32(_current, hData.AddrOfPinnedObject().ToInt32()+offset, (uint)count);
+            }
+            finally
+            {
+                hData.Free();
+            }
+        }
+
+    }
+    #endregion
+
+    #region Adler
+    /// <summary>
+    /// Implements a checksum generator that computes the Adler checksum on data
+    /// </summary>
+    public sealed class AdlerChecksum : ChecksumGeneratorBase
+    {
+        #region DLL imports
+
+        [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]
+        private static extern uint adler32(uint adler, int data, uint length);
+
+        #endregion
+
+        /// <summary>
+        /// Initializes a new instance of the Adler checksum generator
+        /// </summary>
+        public AdlerChecksum() : base() {}
+
+        /// <summary>
+        /// Initializes a new instance of the Adler checksum generator with a specified value
+        /// </summary>
+        /// <param name="initialValue">The value to set the current checksum to</param>
+        public AdlerChecksum(uint initialValue) : base(initialValue) {}
+
+        /// <summary>
+        /// Updates the current checksum with part of an array of bytes
+        /// </summary>
+        /// <param name="data">The data to update the checksum with</param>
+        /// <param name="offset">Where in <c>data</c> to start updating</param>
+        /// <param name="count">The number of bytes from <c>data</c> to use</param>
+        /// <exception cref="ArgumentException">The sum of offset and count is larger than the length of <c>data</c></exception>
+        /// <exception cref="NullReferenceException"><c>data</c> is a null reference</exception>
+        /// <exception cref="ArgumentOutOfRangeException">Offset or count is negative.</exception>
+        public override void Update(byte[] data, int offset, int count)
+        {
+            if (offset < 0 || count < 0) throw new ArgumentOutOfRangeException();
+            if ((offset+count) > data.Length) throw new ArgumentException();
+            GCHandle hData = GCHandle.Alloc(data, GCHandleType.Pinned);
+            try
+            {
+                _current = adler32(_current, hData.AddrOfPinnedObject().ToInt32()+offset, (uint)count);
+            }
+            finally
+            {
+                hData.Free();
+            }
+        }
+
+    }
+    #endregion
+
+}
\ No newline at end of file
diff --git a/compat/zlib/contrib/dotzlib/DotZLib/CircularBuffer.cs b/compat/zlib/contrib/dotzlib/DotZLib/CircularBuffer.cs
new file mode 100644
index 0000000..c1cab3a
--- /dev/null
+++ b/compat/zlib/contrib/dotzlib/DotZLib/CircularBuffer.cs
@@ -0,0 +1,83 @@
+//
+// � Copyright Henrik Ravn 2004
+//
+// Use, modification and distribution are subject to the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+using System;
+using System.Diagnostics;
+
+namespace DotZLib
+{
+
+	/// <summary>
+	/// This class implements a circular buffer
+	/// </summary>
+	internal class CircularBuffer
+	{
+        #region Private data
+        private int _capacity;
+        private int _head;
+        private int _tail;
+        private int _size;
+        private byte[] _buffer;
+        #endregion
+
+        public CircularBuffer(int capacity)
+        {
+            Debug.Assert( capacity > 0 );
+            _buffer = new byte[capacity];
+            _capacity = capacity;
+            _head = 0;
+            _tail = 0;
+            _size = 0;
+        }
+
+        public int Size { get { return _size; } }
+
+        public int Put(byte[] source, int offset, int count)
+        {
+            Debug.Assert( count > 0 );
+            int trueCount = Math.Min(count, _capacity - Size);
+            for (int i = 0; i < trueCount; ++i)
+                _buffer[(_tail+i) % _capacity] = source[offset+i];
+            _tail += trueCount;
+            _tail %= _capacity;
+            _size += trueCount;
+            return trueCount;
+        }
+
+        public bool Put(byte b)
+        {
+            if (Size == _capacity) // no room
+                return false;
+            _buffer[_tail++] = b;
+            _tail %= _capacity;
+            ++_size;
+            return true;
+        }
+
+        public int Get(byte[] destination, int offset, int count)
+        {
+            int trueCount = Math.Min(count,Size);
+            for (int i = 0; i < trueCount; ++i)
+                destination[offset + i] = _buffer[(_head+i) % _capacity];
+            _head += trueCount;
+            _head %= _capacity;
+            _size -= trueCount;
+            return trueCount;
+        }
+
+        public int Get()
+        {
+            if (Size == 0)
+                return -1;
+
+            int result = (int)_buffer[_head++ % _capacity];
+            --_size;
+            return result;
+        }
+
+    }
+}
diff --git a/compat/zlib/contrib/dotzlib/DotZLib/CodecBase.cs b/compat/zlib/contrib/dotzlib/DotZLib/CodecBase.cs
new file mode 100644
index 0000000..42e6da3
--- /dev/null
+++ b/compat/zlib/contrib/dotzlib/DotZLib/CodecBase.cs
@@ -0,0 +1,198 @@
+//
+// � Copyright Henrik Ravn 2004
+//
+// Use, modification and distribution are subject to the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+using System;
+using System.Runtime.InteropServices;
+
+namespace DotZLib
+{
+	/// <summary>
+	/// Implements the common functionality needed for all <see cref="Codec"/>s
+	/// </summary>
+	public abstract class CodecBase : Codec, IDisposable
+	{
+
+        #region Data members
+
+        /// <summary>
+        /// Instance of the internal zlib buffer structure that is
+        /// passed to all functions in the zlib dll
+        /// </summary>
+        internal ZStream _ztream = new ZStream();
+
+        /// <summary>
+        /// True if the object instance has been disposed, false otherwise
+        /// </summary>
+        protected bool _isDisposed = false;
+
+        /// <summary>
+        /// The size of the internal buffers
+        /// </summary>
+        protected const int kBufferSize = 16384;
+
+        private byte[] _outBuffer = new byte[kBufferSize];
+        private byte[] _inBuffer = new byte[kBufferSize];
+
+        private GCHandle _hInput;
+        private GCHandle _hOutput;
+
+        private uint _checksum = 0;
+
+        #endregion
+
+        /// <summary>
+        /// Initializes a new instance of the <c>CodeBase</c> class.
+        /// </summary>
+		public CodecBase()
+		{
+            try
+            {
+                _hInput = GCHandle.Alloc(_inBuffer, GCHandleType.Pinned);
+                _hOutput = GCHandle.Alloc(_outBuffer, GCHandleType.Pinned);
+            }
+            catch (Exception)
+            {
+                CleanUp(false);
+                throw;
+            }
+        }
+
+
+        #region Codec Members
+
+        /// <summary>
+        /// Occurs when more processed data are available.
+        /// </summary>
+        public event DataAvailableHandler DataAvailable;
+
+        /// <summary>
+        /// Fires the <see cref="DataAvailable"/> event
+        /// </summary>
+        protected void OnDataAvailable()
+        {
+            if (_ztream.total_out > 0)
+            {
+                if (DataAvailable != null)
+                    DataAvailable( _outBuffer, 0, (int)_ztream.total_out);
+                resetOutput();
+            }
+        }
+
+        /// <summary>
+        /// Adds more data to the codec to be processed.
+        /// </summary>
+        /// <param name="data">Byte array containing the data to be added to the codec</param>
+        /// <remarks>Adding data may, or may not, raise the <c>DataAvailable</c> event</remarks>
+        public void Add(byte[] data)
+        {
+            Add(data,0,data.Length);
+        }
+
+        /// <summary>
+        /// Adds more data to the codec to be processed.
+        /// </summary>
+        /// <param name="data">Byte array containing the data to be added to the codec</param>
+        /// <param name="offset">The index of the first byte to add from <c>data</c></param>
+        /// <param name="count">The number of bytes to add</param>
+        /// <remarks>Adding data may, or may not, raise the <c>DataAvailable</c> event</remarks>
+        /// <remarks>This must be implemented by a derived class</remarks>
+        public abstract void Add(byte[] data, int offset, int count);
+
+        /// <summary>
+        /// Finishes up any pending data that needs to be processed and handled.
+        /// </summary>
+        /// <remarks>This must be implemented by a derived class</remarks>
+        public abstract void Finish();
+
+        /// <summary>
+        /// Gets the checksum of the data that has been added so far
+        /// </summary>
+        public uint Checksum { get { return _checksum; } }
+
+        #endregion
+
+        #region Destructor & IDisposable stuff
+
+        /// <summary>
+        /// Destroys this instance
+        /// </summary>
+        ~CodecBase()
+        {
+            CleanUp(false);
+        }
+
+        /// <summary>
+        /// Releases any unmanaged resources and calls the <see cref="CleanUp()"/> method of the derived class
+        /// </summary>
+        public void Dispose()
+        {
+            CleanUp(true);
+        }
+
+        /// <summary>
+        /// Performs any codec specific cleanup
+        /// </summary>
+        /// <remarks>This must be implemented by a derived class</remarks>
+        protected abstract void CleanUp();
+
+        // performs the release of the handles and calls the dereived CleanUp()
+        private void CleanUp(bool isDisposing)
+        {
+            if (!_isDisposed)
+            {
+                CleanUp();
+                if (_hInput.IsAllocated)
+                    _hInput.Free();
+                if (_hOutput.IsAllocated)
+                    _hOutput.Free();
+
+                _isDisposed = true;
+            }
+        }
+
+
+        #endregion
+
+        #region Helper methods
+
+        /// <summary>
+        /// Copies a number of bytes to the internal codec buffer - ready for proccesing
+        /// </summary>
+        /// <param name="data">The byte array that contains the data to copy</param>
+        /// <param name="startIndex">The index of the first byte to copy</param>
+        /// <param name="count">The number of bytes to copy from <c>data</c></param>
+        protected void copyInput(byte[] data, int startIndex, int count)
+        {
+            Array.Copy(data, startIndex, _inBuffer,0, count);
+            _ztream.next_in = _hInput.AddrOfPinnedObject();
+            _ztream.total_in = 0;
+            _ztream.avail_in = (uint)count;
+
+        }
+
+        /// <summary>
+        /// Resets the internal output buffers to a known state - ready for processing
+        /// </summary>
+        protected void resetOutput()
+        {
+            _ztream.total_out = 0;
+            _ztream.avail_out = kBufferSize;
+            _ztream.next_out = _hOutput.AddrOfPinnedObject();
+        }
+
+        /// <summary>
+        /// Updates the running checksum property
+        /// </summary>
+        /// <param name="newSum">The new checksum value</param>
+        protected void setChecksum(uint newSum)
+        {
+            _checksum = newSum;
+        }
+        #endregion
+
+    }
+}
diff --git a/compat/zlib/contrib/dotzlib/DotZLib/Deflater.cs b/compat/zlib/contrib/dotzlib/DotZLib/Deflater.cs
new file mode 100644
index 0000000..c247792
--- /dev/null
+++ b/compat/zlib/contrib/dotzlib/DotZLib/Deflater.cs
@@ -0,0 +1,106 @@
+//
+// � Copyright Henrik Ravn 2004
+//
+// Use, modification and distribution are subject to the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+using System;
+using System.Diagnostics;
+using System.Runtime.InteropServices;
+
+namespace DotZLib
+{
+
+    /// <summary>
+    /// Implements a data compressor, using the deflate algorithm in the ZLib dll
+    /// </summary>
+	public sealed class Deflater : CodecBase
+	{
+        #region Dll imports
+        [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl, CharSet=CharSet.Ansi)]
+        private static extern int deflateInit_(ref ZStream sz, int level, string vs, int size);
+
+        [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]
+        private static extern int deflate(ref ZStream sz, int flush);
+
+        [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]
+        private static extern int deflateReset(ref ZStream sz);
+
+        [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]
+        private static extern int deflateEnd(ref ZStream sz);
+        #endregion
+
+        /// <summary>
+        /// Constructs an new instance of the <c>Deflater</c>
+        /// </summary>
+        /// <param name="level">The compression level to use for this <c>Deflater</c></param>
+		public Deflater(CompressLevel level) : base()
+		{
+            int retval = deflateInit_(ref _ztream, (int)level, Info.Version, Marshal.SizeOf(_ztream));
+            if (retval != 0)
+                throw new ZLibException(retval, "Could not initialize deflater");
+
+            resetOutput();
+		}
+
+        /// <summary>
+        /// Adds more data to the codec to be processed.
+        /// </summary>
+        /// <param name="data">Byte array containing the data to be added to the codec</param>
+        /// <param name="offset">The index of the first byte to add from <c>data</c></param>
+        /// <param name="count">The number of bytes to add</param>
+        /// <remarks>Adding data may, or may not, raise the <c>DataAvailable</c> event</remarks>
+        public override void Add(byte[] data, int offset, int count)
+        {
+            if (data == null) throw new ArgumentNullException();
+            if (offset < 0 || count < 0) throw new ArgumentOutOfRangeException();
+            if ((offset+count) > data.Length) throw new ArgumentException();
+
+            int total = count;
+            int inputIndex = offset;
+            int err = 0;
+
+            while (err >= 0 && inputIndex < total)
+            {
+                copyInput(data, inputIndex, Math.Min(total - inputIndex, kBufferSize));
+                while (err >= 0 && _ztream.avail_in > 0)
+                {
+                    err = deflate(ref _ztream, (int)FlushTypes.None);
+                    if (err == 0)
+                        while (_ztream.avail_out == 0)
+                        {
+                            OnDataAvailable();
+                            err = deflate(ref _ztream, (int)FlushTypes.None);
+                        }
+                    inputIndex += (int)_ztream.total_in;
+                }
+            }
+            setChecksum( _ztream.adler );
+        }
+
+
+        /// <summary>
+        /// Finishes up any pending data that needs to be processed and handled.
+        /// </summary>
+        public override void Finish()
+        {
+            int err;
+            do
+            {
+                err = deflate(ref _ztream, (int)FlushTypes.Finish);
+                OnDataAvailable();
+            }
+            while (err == 0);
+            setChecksum( _ztream.adler );
+            deflateReset(ref _ztream);
+            resetOutput();
+        }
+
+        /// <summary>
+        /// Closes the internal zlib deflate stream
+        /// </summary>
+        protected override void CleanUp() { deflateEnd(ref _ztream); }
+
+    }
+}
diff --git a/compat/zlib/contrib/dotzlib/DotZLib/DotZLib.cs b/compat/zlib/contrib/dotzlib/DotZLib/DotZLib.cs
new file mode 100644
index 0000000..be184b4
--- /dev/null
+++ b/compat/zlib/contrib/dotzlib/DotZLib/DotZLib.cs
@@ -0,0 +1,288 @@
+//
+// � Copyright Henrik Ravn 2004
+//
+// Use, modification and distribution are subject to the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+using System;
+using System.IO;
+using System.Runtime.InteropServices;
+using System.Text;
+
+
+namespace DotZLib
+{
+
+    #region Internal types
+
+    /// <summary>
+    /// Defines constants for the various flush types used with zlib
+    /// </summary>
+    internal enum FlushTypes
+    {
+        None,  Partial,  Sync,  Full,  Finish,  Block
+    }
+
+    #region ZStream structure
+    // internal mapping of the zlib zstream structure for marshalling
+    [StructLayoutAttribute(LayoutKind.Sequential, Pack=4, Size=0, CharSet=CharSet.Ansi)]
+    internal struct ZStream
+    {
+        public IntPtr next_in;
+        public uint avail_in;
+        public uint total_in;
+
+        public IntPtr next_out;
+        public uint avail_out;
+        public uint total_out;
+
+        [MarshalAs(UnmanagedType.LPStr)]
+        string msg;
+        uint state;
+
+        uint zalloc;
+        uint zfree;
+        uint opaque;
+
+        int data_type;
+        public uint adler;
+        uint reserved;
+    }
+
+    #endregion
+
+    #endregion
+
+    #region Public enums
+    /// <summary>
+    /// Defines constants for the available compression levels in zlib
+    /// </summary>
+    public enum CompressLevel : int
+    {
+        /// <summary>
+        /// The default compression level with a reasonable compromise between compression and speed
+        /// </summary>
+        Default = -1,
+        /// <summary>
+        /// No compression at all. The data are passed straight through.
+        /// </summary>
+        None = 0,
+        /// <summary>
+        /// The maximum compression rate available.
+        /// </summary>
+        Best = 9,
+        /// <summary>
+        /// The fastest available compression level.
+        /// </summary>
+        Fastest = 1
+    }
+    #endregion
+
+    #region Exception classes
+    /// <summary>
+    /// The exception that is thrown when an error occurs on the zlib dll
+    /// </summary>
+    public class ZLibException : ApplicationException
+    {
+        /// <summary>
+        /// Initializes a new instance of the <see cref="ZLibException"/> class with a specified
+        /// error message and error code
+        /// </summary>
+        /// <param name="errorCode">The zlib error code that caused the exception</param>
+        /// <param name="msg">A message that (hopefully) describes the error</param>
+        public ZLibException(int errorCode, string msg) : base(String.Format("ZLib error {0} {1}", errorCode, msg))
+        {
+        }
+
+        /// <summary>
+        /// Initializes a new instance of the <see cref="ZLibException"/> class with a specified
+        /// error code
+        /// </summary>
+        /// <param name="errorCode">The zlib error code that caused the exception</param>
+        public ZLibException(int errorCode) : base(String.Format("ZLib error {0}", errorCode))
+        {
+        }
+    }
+    #endregion
+
+    #region Interfaces
+
+    /// <summary>
+    /// Declares methods and properties that enables a running checksum to be calculated
+    /// </summary>
+    public interface ChecksumGenerator
+    {
+        /// <summary>
+        /// Gets the current value of the checksum
+        /// </summary>
+        uint Value { get; }
+
+        /// <summary>
+        /// Clears the current checksum to 0
+        /// </summary>
+        void Reset();
+
+        /// <summary>
+        /// Updates the current checksum with an array of bytes
+        /// </summary>
+        /// <param name="data">The data to update the checksum with</param>
+        void Update(byte[] data);
+
+        /// <summary>
+        /// Updates the current checksum with part of an array of bytes
+        /// </summary>
+        /// <param name="data">The data to update the checksum with</param>
+        /// <param name="offset">Where in <c>data</c> to start updating</param>
+        /// <param name="count">The number of bytes from <c>data</c> to use</param>
+        /// <exception cref="ArgumentException">The sum of offset and count is larger than the length of <c>data</c></exception>
+        /// <exception cref="ArgumentNullException"><c>data</c> is a null reference</exception>
+        /// <exception cref="ArgumentOutOfRangeException">Offset or count is negative.</exception>
+        void Update(byte[] data, int offset, int count);
+
+        /// <summary>
+        /// Updates the current checksum with the data from a string
+        /// </summary>
+        /// <param name="data">The string to update the checksum with</param>
+        /// <remarks>The characters in the string are converted by the UTF-8 encoding</remarks>
+        void Update(string data);
+
+        /// <summary>
+        /// Updates the current checksum with the data from a string, using a specific encoding
+        /// </summary>
+        /// <param name="data">The string to update the checksum with</param>
+        /// <param name="encoding">The encoding to use</param>
+        void Update(string data, Encoding encoding);
+    }
+
+
+    /// <summary>
+    /// Represents the method that will be called from a codec when new data
+    /// are available.
+    /// </summary>
+    /// <paramref name="data">The byte array containing the processed data</paramref>
+    /// <paramref name="startIndex">The index of the first processed byte in <c>data</c></paramref>
+    /// <paramref name="count">The number of processed bytes available</paramref>
+    /// <remarks>On return from this method, the data may be overwritten, so grab it while you can.
+    /// You cannot assume that startIndex will be zero.
+    /// </remarks>
+    public delegate void DataAvailableHandler(byte[] data, int startIndex, int count);
+
+    /// <summary>
+    /// Declares methods and events for implementing compressors/decompressors
+    /// </summary>
+    public interface Codec
+    {
+        /// <summary>
+        /// Occurs when more processed data are available.
+        /// </summary>
+        event DataAvailableHandler DataAvailable;
+
+        /// <summary>
+        /// Adds more data to the codec to be processed.
+        /// </summary>
+        /// <param name="data">Byte array containing the data to be added to the codec</param>
+        /// <remarks>Adding data may, or may not, raise the <c>DataAvailable</c> event</remarks>
+        void Add(byte[] data);
+
+        /// <summary>
+        /// Adds more data to the codec to be processed.
+        /// </summary>
+        /// <param name="data">Byte array containing the data to be added to the codec</param>
+        /// <param name="offset">The index of the first byte to add from <c>data</c></param>
+        /// <param name="count">The number of bytes to add</param>
+        /// <remarks>Adding data may, or may not, raise the <c>DataAvailable</c> event</remarks>
+        void Add(byte[] data, int offset, int count);
+
+        /// <summary>
+        /// Finishes up any pending data that needs to be processed and handled.
+        /// </summary>
+        void Finish();
+
+        /// <summary>
+        /// Gets the checksum of the data that has been added so far
+        /// </summary>
+        uint Checksum { get; }
+
+
+    }
+
+    #endregion
+
+    #region Classes
+    /// <summary>
+    /// Encapsulates general information about the ZLib library
+    /// </summary>
+    public class Info
+    {
+        #region DLL imports
+        [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]
+        private static extern uint zlibCompileFlags();
+
+        [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]
+        private static extern string zlibVersion();
+        #endregion
+
+        #region Private stuff
+        private uint _flags;
+
+        // helper function that unpacks a bitsize mask
+        private static int bitSize(uint bits)
+        {
+            switch (bits)
+            {
+                case 0: return 16;
+                case 1: return 32;
+                case 2: return 64;
+            }
+            return -1;
+        }
+        #endregion
+
+        /// <summary>
+        /// Constructs an instance of the <c>Info</c> class.
+        /// </summary>
+        public Info()
+        {
+            _flags = zlibCompileFlags();
+        }
+
+        /// <summary>
+        /// True if the library is compiled with debug info
+        /// </summary>
+        public bool HasDebugInfo { get { return 0 != (_flags & 0x100); } }
+
+        /// <summary>
+        /// True if the library is compiled with assembly optimizations
+        /// </summary>
+        public bool UsesAssemblyCode { get { return 0 != (_flags & 0x200); } }
+
+        /// <summary>
+        /// Gets the size of the unsigned int that was compiled into Zlib
+        /// </summary>
+        public int SizeOfUInt { get { return bitSize(_flags & 3); } }
+
+        /// <summary>
+        /// Gets the size of the unsigned long that was compiled into Zlib
+        /// </summary>
+        public int SizeOfULong { get { return bitSize((_flags >> 2) & 3); } }
+
+        /// <summary>
+        /// Gets the size of the pointers that were compiled into Zlib
+        /// </summary>
+        public int SizeOfPointer { get { return bitSize((_flags >> 4) & 3); } }
+
+        /// <summary>
+        /// Gets the size of the z_off_t type that was compiled into Zlib
+        /// </summary>
+        public int SizeOfOffset { get { return bitSize((_flags >> 6) & 3); } }
+
+        /// <summary>
+        /// Gets the version of ZLib as a string, e.g. "1.2.1"
+        /// </summary>
+        public static string Version { get { return zlibVersion(); } }
+    }
+
+    #endregion
+
+}
diff --git a/compat/zlib/contrib/dotzlib/DotZLib/DotZLib.csproj b/compat/zlib/contrib/dotzlib/DotZLib/DotZLib.csproj
new file mode 100644
index 0000000..71eeb85
--- /dev/null
+++ b/compat/zlib/contrib/dotzlib/DotZLib/DotZLib.csproj
@@ -0,0 +1,141 @@
+<VisualStudioProject>
+    <CSHARP
+        ProjectType = "Local"
+        ProductVersion = "7.10.3077"
+        SchemaVersion = "2.0"
+        ProjectGuid = "{BB1EE0B1-1808-46CB-B786-949D91117FC5}"
+    >
+        <Build>
+            <Settings
+                ApplicationIcon = ""
+                AssemblyKeyContainerName = ""
+                AssemblyName = "DotZLib"
+                AssemblyOriginatorKeyFile = ""
+                DefaultClientScript = "JScript"
+                DefaultHTMLPageLayout = "Grid"
+                DefaultTargetSchema = "IE50"
+                DelaySign = "false"
+                OutputType = "Library"
+                PreBuildEvent = ""
+                PostBuildEvent = ""
+                RootNamespace = "DotZLib"
+                RunPostBuildEvent = "OnBuildSuccess"
+                StartupObject = ""
+            >
+                <Config
+                    Name = "Debug"
+                    AllowUnsafeBlocks = "false"
+                    BaseAddress = "285212672"
+                    CheckForOverflowUnderflow = "false"
+                    ConfigurationOverrideFile = ""
+                    DefineConstants = "DEBUG;TRACE"
+                    DocumentationFile = "docs\DotZLib.xml"
+                    DebugSymbols = "true"
+                    FileAlignment = "4096"
+                    IncrementalBuild = "false"
+                    NoStdLib = "false"
+                    NoWarn = "1591"
+                    Optimize = "false"
+                    OutputPath = "bin\Debug\"
+                    RegisterForComInterop = "false"
+                    RemoveIntegerChecks = "false"
+                    TreatWarningsAsErrors = "false"
+                    WarningLevel = "4"
+                />
+                <Config
+                    Name = "Release"
+                    AllowUnsafeBlocks = "false"
+                    BaseAddress = "285212672"
+                    CheckForOverflowUnderflow = "false"
+                    ConfigurationOverrideFile = ""
+                    DefineConstants = "TRACE"
+                    DocumentationFile = "docs\DotZLib.xml"
+                    DebugSymbols = "false"
+                    FileAlignment = "4096"
+                    IncrementalBuild = "false"
+                    NoStdLib = "false"
+                    NoWarn = ""
+                    Optimize = "true"
+                    OutputPath = "bin\Release\"
+                    RegisterForComInterop = "false"
+                    RemoveIntegerChecks = "false"
+                    TreatWarningsAsErrors = "false"
+                    WarningLevel = "4"
+                />
+            </Settings>
+            <References>
+                <Reference
+                    Name = "System"
+                    AssemblyName = "System"
+                    HintPath = "C:\WINNT\Microsoft.NET\Framework\v1.1.4322\System.dll"
+                />
+                <Reference
+                    Name = "System.Data"
+                    AssemblyName = "System.Data"
+                    HintPath = "C:\WINNT\Microsoft.NET\Framework\v1.1.4322\System.Data.dll"
+                />
+                <Reference
+                    Name = "System.XML"
+                    AssemblyName = "System.Xml"
+                    HintPath = "C:\WINNT\Microsoft.NET\Framework\v1.1.4322\System.XML.dll"
+                />
+                <Reference
+                    Name = "nunit.framework"
+                    AssemblyName = "nunit.framework"
+                    HintPath = "E:\apps\NUnit V2.1\\bin\nunit.framework.dll"
+                    AssemblyFolderKey = "hklm\dn\nunit.framework"
+                />
+            </References>
+        </Build>
+        <Files>
+            <Include>
+                <File
+                    RelPath = "AssemblyInfo.cs"
+                    SubType = "Code"
+                    BuildAction = "Compile"
+                />
+                <File
+                    RelPath = "ChecksumImpl.cs"
+                    SubType = "Code"
+                    BuildAction = "Compile"
+                />
+                <File
+                    RelPath = "CircularBuffer.cs"
+                    SubType = "Code"
+                    BuildAction = "Compile"
+                />
+                <File
+                    RelPath = "CodecBase.cs"
+                    SubType = "Code"
+                    BuildAction = "Compile"
+                />
+                <File
+                    RelPath = "Deflater.cs"
+                    SubType = "Code"
+                    BuildAction = "Compile"
+                />
+                <File
+                    RelPath = "DotZLib.cs"
+                    SubType = "Code"
+                    BuildAction = "Compile"
+                />
+                <File
+                    RelPath = "GZipStream.cs"
+                    SubType = "Code"
+                    BuildAction = "Compile"
+                />
+                <File
+                    RelPath = "Inflater.cs"
+                    SubType = "Code"
+                    BuildAction = "Compile"
+                />
+                <File
+                    RelPath = "UnitTests.cs"
+                    SubType = "Code"
+                    BuildAction = "Compile"
+                />
+            </Include>
+        </Files>
+    </CSHARP>
+</VisualStudioProject>
+
diff --git a/compat/zlib/contrib/dotzlib/DotZLib/GZipStream.cs b/compat/zlib/contrib/dotzlib/DotZLib/GZipStream.cs
new file mode 100644
index 0000000..b161300
--- /dev/null
+++ b/compat/zlib/contrib/dotzlib/DotZLib/GZipStream.cs
@@ -0,0 +1,301 @@
+//
+// � Copyright Henrik Ravn 2004
+//
+// Use, modification and distribution are subject to the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+using System;
+using System.IO;
+using System.Runtime.InteropServices;
+
+namespace DotZLib
+{
+	/// <summary>
+	/// Implements a compressed <see cref="Stream"/>, in GZip (.gz) format.
+	/// </summary>
+	public class GZipStream : Stream, IDisposable
+	{
+        #region Dll Imports
+        [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl, CharSet=CharSet.Ansi)]
+        private static extern IntPtr gzopen(string name, string mode);
+
+        [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]
+        private static extern int gzclose(IntPtr gzFile);
+
+        [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]
+        private static extern int gzwrite(IntPtr gzFile, int data, int length);
+
+        [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]
+        private static extern int gzread(IntPtr gzFile, int data, int length);
+
+        [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]
+        private static extern int gzgetc(IntPtr gzFile);
+
+        [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]
+        private static extern int gzputc(IntPtr gzFile, int c);
+
+        #endregion
+
+        #region Private data
+        private IntPtr _gzFile;
+        private bool _isDisposed = false;
+        private bool _isWriting;
+        #endregion
+
+        #region Constructors
+        /// <summary>
+        /// Creates a new file as a writeable GZipStream
+        /// </summary>
+        /// <param name="fileName">The name of the compressed file to create</param>
+        /// <param name="level">The compression level to use when adding data</param>
+        /// <exception cref="ZLibException">If an error occurred in the internal zlib function</exception>
+		public GZipStream(string fileName, CompressLevel level)
+		{
+            _isWriting = true;
+            _gzFile = gzopen(fileName, String.Format("wb{0}", (int)level));
+            if (_gzFile == IntPtr.Zero)
+                throw new ZLibException(-1, "Could not open " + fileName);
+		}
+
+        /// <summary>
+        /// Opens an existing file as a readable GZipStream
+        /// </summary>
+        /// <param name="fileName">The name of the file to open</param>
+        /// <exception cref="ZLibException">If an error occurred in the internal zlib function</exception>
+        public GZipStream(string fileName)
+        {
+            _isWriting = false;
+            _gzFile = gzopen(fileName, "rb");
+            if (_gzFile == IntPtr.Zero)
+                throw new ZLibException(-1, "Could not open " + fileName);
+
+        }
+        #endregion
+
+        #region Access properties
+        /// <summary>
+        /// Returns true of this stream can be read from, false otherwise
+        /// </summary>
+        public override bool CanRead
+        {
+            get
+            {
+                return !_isWriting;
+            }
+        }
+
+
+        /// <summary>
+        /// Returns false.
+        /// </summary>
+        public override bool CanSeek
+        {
+            get
+            {
+                return false;
+            }
+        }
+
+        /// <summary>
+        /// Returns true if this tsream is writeable, false otherwise
+        /// </summary>
+        public override bool CanWrite
+        {
+            get
+            {
+                return _isWriting;
+            }
+        }
+        #endregion
+
+        #region Destructor & IDispose stuff
+
+        /// <summary>
+        /// Destroys this instance
+        /// </summary>
+        ~GZipStream()
+        {
+            cleanUp(false);
+        }
+
+        /// <summary>
+        /// Closes the external file handle
+        /// </summary>
+        public void Dispose()
+        {
+            cleanUp(true);
+        }
+
+        // Does the actual closing of the file handle.
+        private void cleanUp(bool isDisposing)
+        {
+            if (!_isDisposed)
+            {
+                gzclose(_gzFile);
+                _isDisposed = true;
+            }
+        }
+        #endregion
+
+        #region Basic reading and writing
+        /// <summary>
+        /// Attempts to read a number of bytes from the stream.
+        /// </summary>
+        /// <param name="buffer">The destination data buffer</param>
+        /// <param name="offset">The index of the first destination byte in <c>buffer</c></param>
+        /// <param name="count">The number of bytes requested</param>
+        /// <returns>The number of bytes read</returns>
+        /// <exception cref="ArgumentNullException">If <c>buffer</c> is null</exception>
+        /// <exception cref="ArgumentOutOfRangeException">If <c>count</c> or <c>offset</c> are negative</exception>
+        /// <exception cref="ArgumentException">If <c>offset</c>  + <c>count</c> is &gt; buffer.Length</exception>
+        /// <exception cref="NotSupportedException">If this stream is not readable.</exception>
+        /// <exception cref="ObjectDisposedException">If this stream has been disposed.</exception>
+        public override int Read(byte[] buffer, int offset, int count)
+        {
+            if (!CanRead) throw new NotSupportedException();
+            if (buffer == null) throw new ArgumentNullException();
+            if (offset < 0 || count < 0) throw new ArgumentOutOfRangeException();
+            if ((offset+count) > buffer.Length) throw new ArgumentException();
+            if (_isDisposed) throw new ObjectDisposedException("GZipStream");
+
+            GCHandle h = GCHandle.Alloc(buffer, GCHandleType.Pinned);
+            int result;
+            try
+            {
+                result = gzread(_gzFile, h.AddrOfPinnedObject().ToInt32() + offset, count);
+                if (result < 0)
+                    throw new IOException();
+            }
+            finally
+            {
+                h.Free();
+            }
+            return result;
+        }
+
+        /// <summary>
+        /// Attempts to read a single byte from the stream.
+        /// </summary>
+        /// <returns>The byte that was read, or -1 in case of error or End-Of-File</returns>
+        public override int ReadByte()
+        {
+            if (!CanRead) throw new NotSupportedException();
+            if (_isDisposed) throw new ObjectDisposedException("GZipStream");
+            return gzgetc(_gzFile);
+        }
+
+        /// <summary>
+        /// Writes a number of bytes to the stream
+        /// </summary>
+        /// <param name="buffer"></param>
+        /// <param name="offset"></param>
+        /// <param name="count"></param>
+        /// <exception cref="ArgumentNullException">If <c>buffer</c> is null</exception>
+        /// <exception cref="ArgumentOutOfRangeException">If <c>count</c> or <c>offset</c> are negative</exception>
+        /// <exception cref="ArgumentException">If <c>offset</c>  + <c>count</c> is &gt; buffer.Length</exception>
+        /// <exception cref="NotSupportedException">If this stream is not writeable.</exception>
+        /// <exception cref="ObjectDisposedException">If this stream has been disposed.</exception>
+        public override void Write(byte[] buffer, int offset, int count)
+        {
+            if (!CanWrite) throw new NotSupportedException();
+            if (buffer == null) throw new ArgumentNullException();
+            if (offset < 0 || count < 0) throw new ArgumentOutOfRangeException();
+            if ((offset+count) > buffer.Length) throw new ArgumentException();
+            if (_isDisposed) throw new ObjectDisposedException("GZipStream");
+
+            GCHandle h = GCHandle.Alloc(buffer, GCHandleType.Pinned);
+            try
+            {
+                int result = gzwrite(_gzFile, h.AddrOfPinnedObject().ToInt32() + offset, count);
+                if (result < 0)
+                    throw new IOException();
+            }
+            finally
+            {
+                h.Free();
+            }
+        }
+
+        /// <summary>
+        /// Writes a single byte to the stream
+        /// </summary>
+        /// <param name="value">The byte to add to the stream.</param>
+        /// <exception cref="NotSupportedException">If this stream is not writeable.</exception>
+        /// <exception cref="ObjectDisposedException">If this stream has been disposed.</exception>
+        public override void WriteByte(byte value)
+        {
+            if (!CanWrite) throw new NotSupportedException();
+            if (_isDisposed) throw new ObjectDisposedException("GZipStream");
+
+            int result = gzputc(_gzFile, (int)value);
+            if (result < 0)
+                throw new IOException();
+        }
+        #endregion
+
+        #region Position & length stuff
+        /// <summary>
+        /// Not supported.
+        /// </summary>
+        /// <param name="value"></param>
+        /// <exception cref="NotSupportedException">Always thrown</exception>
+        public override void SetLength(long value)
+        {
+            throw new NotSupportedException();
+        }
+
+        /// <summary>
+        ///  Not suppported.
+        /// </summary>
+        /// <param name="offset"></param>
+        /// <param name="origin"></param>
+        /// <returns></returns>
+        /// <exception cref="NotSupportedException">Always thrown</exception>
+        public override long Seek(long offset, SeekOrigin origin)
+        {
+            throw new NotSupportedException();
+        }
+
+        /// <summary>
+        /// Flushes the <c>GZipStream</c>.
+        /// </summary>
+        /// <remarks>In this implementation, this method does nothing. This is because excessive
+        /// flushing may degrade the achievable compression rates.</remarks>
+        public override void Flush()
+        {
+            // left empty on purpose
+        }
+
+        /// <summary>
+        /// Gets/sets the current position in the <c>GZipStream</c>. Not suppported.
+        /// </summary>
+        /// <remarks>In this implementation this property is not supported</remarks>
+        /// <exception cref="NotSupportedException">Always thrown</exception>
+        public override long Position
+        {
+            get
+            {
+                throw new NotSupportedException();
+            }
+            set
+            {
+                throw new NotSupportedException();
+            }
+        }
+
+        /// <summary>
+        /// Gets the size of the stream. Not suppported.
+        /// </summary>
+        /// <remarks>In this implementation this property is not supported</remarks>
+        /// <exception cref="NotSupportedException">Always thrown</exception>
+        public override long Length
+        {
+            get
+            {
+                throw new NotSupportedException();
+            }
+        }
+        #endregion
+    }
+}
diff --git a/compat/zlib/contrib/dotzlib/DotZLib/Inflater.cs b/compat/zlib/contrib/dotzlib/DotZLib/Inflater.cs
new file mode 100644
index 0000000..8ed5451
--- /dev/null
+++ b/compat/zlib/contrib/dotzlib/DotZLib/Inflater.cs
@@ -0,0 +1,105 @@
+//
+// � Copyright Henrik Ravn 2004
+//
+// Use, modification and distribution are subject to the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+using System;
+using System.Diagnostics;
+using System.Runtime.InteropServices;
+
+namespace DotZLib
+{
+
+    /// <summary>
+    /// Implements a data decompressor, using the inflate algorithm in the ZLib dll
+    /// </summary>
+    public class Inflater : CodecBase
+	{
+        #region Dll imports
+        [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl, CharSet=CharSet.Ansi)]
+        private static extern int inflateInit_(ref ZStream sz, string vs, int size);
+
+        [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]
+        private static extern int inflate(ref ZStream sz, int flush);
+
+        [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]
+        private static extern int inflateReset(ref ZStream sz);
+
+        [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]
+        private static extern int inflateEnd(ref ZStream sz);
+        #endregion
+
+        /// <summary>
+        /// Constructs an new instance of the <c>Inflater</c>
+        /// </summary>
+        public Inflater() : base()
+		{
+            int retval = inflateInit_(ref _ztream, Info.Version, Marshal.SizeOf(_ztream));
+            if (retval != 0)
+                throw new ZLibException(retval, "Could not initialize inflater");
+
+            resetOutput();
+        }
+
+
+        /// <summary>
+        /// Adds more data to the codec to be processed.
+        /// </summary>
+        /// <param name="data">Byte array containing the data to be added to the codec</param>
+        /// <param name="offset">The index of the first byte to add from <c>data</c></param>
+        /// <param name="count">The number of bytes to add</param>
+        /// <remarks>Adding data may, or may not, raise the <c>DataAvailable</c> event</remarks>
+        public override void Add(byte[] data, int offset, int count)
+        {
+            if (data == null) throw new ArgumentNullException();
+            if (offset < 0 || count < 0) throw new ArgumentOutOfRangeException();
+            if ((offset+count) > data.Length) throw new ArgumentException();
+
+            int total = count;
+            int inputIndex = offset;
+            int err = 0;
+
+            while (err >= 0 && inputIndex < total)
+            {
+                copyInput(data, inputIndex, Math.Min(total - inputIndex, kBufferSize));
+                err = inflate(ref _ztream, (int)FlushTypes.None);
+                if (err == 0)
+                    while (_ztream.avail_out == 0)
+                    {
+                        OnDataAvailable();
+                        err = inflate(ref _ztream, (int)FlushTypes.None);
+                    }
+
+                inputIndex += (int)_ztream.total_in;
+            }
+            setChecksum( _ztream.adler );
+        }
+
+
+        /// <summary>
+        /// Finishes up any pending data that needs to be processed and handled.
+        /// </summary>
+        public override void Finish()
+        {
+            int err;
+            do
+            {
+                err = inflate(ref _ztream, (int)FlushTypes.Finish);
+                OnDataAvailable();
+            }
+            while (err == 0);
+            setChecksum( _ztream.adler );
+            inflateReset(ref _ztream);
+            resetOutput();
+        }
+
+        /// <summary>
+        /// Closes the internal zlib inflate stream
+        /// </summary>
+        protected override void CleanUp() { inflateEnd(ref _ztream); }
+
+
+	}
+}
diff --git a/compat/zlib/contrib/dotzlib/DotZLib/UnitTests.cs b/compat/zlib/contrib/dotzlib/DotZLib/UnitTests.cs
new file mode 100644
index 0000000..b273d54
--- /dev/null
+++ b/compat/zlib/contrib/dotzlib/DotZLib/UnitTests.cs
@@ -0,0 +1,274 @@
+//
+// © Copyright Henrik Ravn 2004
+//
+// Use, modification and distribution are subject to the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+//
+
+using System;
+using System.Collections;
+using System.IO;
+
+// uncomment the define below to include unit tests
+//#define nunit
+#if nunit
+using NUnit.Framework;
+
+// Unit tests for the DotZLib class library
+// ----------------------------------------
+//
+// Use this with NUnit 2 from http://www.nunit.org
+//
+
+namespace DotZLibTests
+{
+    using DotZLib;
+
+    // helper methods
+    internal class Utils
+    {
+        public static bool byteArrEqual( byte[] lhs, byte[] rhs )
+        {
+            if (lhs.Length != rhs.Length)
+                return false;
+            for (int i = lhs.Length-1; i >= 0; --i)
+                if (lhs[i] != rhs[i])
+                    return false;
+            return true;
+        }
+
+    }
+
+
+    [TestFixture]
+    public class CircBufferTests
+    {
+        #region Circular buffer tests
+        [Test]
+        public void SinglePutGet()
+        {
+            CircularBuffer buf = new CircularBuffer(10);
+            Assert.AreEqual( 0, buf.Size );
+            Assert.AreEqual( -1, buf.Get() );
+
+            Assert.IsTrue(buf.Put( 1 ));
+            Assert.AreEqual( 1, buf.Size );
+            Assert.AreEqual( 1, buf.Get() );
+            Assert.AreEqual( 0, buf.Size );
+            Assert.AreEqual( -1, buf.Get() );
+        }
+
+        [Test]
+        public void BlockPutGet()
+        {
+            CircularBuffer buf = new CircularBuffer(10);
+            byte[] arr = {1,2,3,4,5,6,7,8,9,10};
+            Assert.AreEqual( 10, buf.Put(arr,0,10) );
+            Assert.AreEqual( 10, buf.Size );
+            Assert.IsFalse( buf.Put(11) );
+            Assert.AreEqual( 1, buf.Get() );
+            Assert.IsTrue( buf.Put(11) );
+
+            byte[] arr2 = (byte[])arr.Clone();
+            Assert.AreEqual( 9, buf.Get(arr2,1,9) );
+            Assert.IsTrue( Utils.byteArrEqual(arr,arr2) );
+        }
+
+        #endregion
+    }
+
+    [TestFixture]
+    public class ChecksumTests
+    {
+        #region CRC32 Tests
+        [Test]
+        public void CRC32_Null()
+        {
+            CRC32Checksum crc32 = new CRC32Checksum();
+            Assert.AreEqual( 0, crc32.Value );
+
+            crc32 = new CRC32Checksum(1);
+            Assert.AreEqual( 1, crc32.Value );
+
+            crc32 = new CRC32Checksum(556);
+            Assert.AreEqual( 556, crc32.Value );
+        }
+
+        [Test]
+        public void CRC32_Data()
+        {
+            CRC32Checksum crc32 = new CRC32Checksum();
+            byte[] data = { 1,2,3,4,5,6,7 };
+            crc32.Update(data);
+            Assert.AreEqual( 0x70e46888, crc32.Value  );
+
+            crc32 = new CRC32Checksum();
+            crc32.Update("penguin");
+            Assert.AreEqual( 0x0e5c1a120, crc32.Value );
+
+            crc32 = new CRC32Checksum(1);
+            crc32.Update("penguin");
+            Assert.AreEqual(0x43b6aa94, crc32.Value);
+
+        }
+        #endregion
+
+        #region Adler tests
+
+        [Test]
+        public void Adler_Null()
+        {
+            AdlerChecksum adler = new AdlerChecksum();
+            Assert.AreEqual(0, adler.Value);
+
+            adler = new AdlerChecksum(1);
+            Assert.AreEqual( 1, adler.Value );
+
+            adler = new AdlerChecksum(556);
+            Assert.AreEqual( 556, adler.Value );
+        }
+
+        [Test]
+        public void Adler_Data()
+        {
+            AdlerChecksum adler = new AdlerChecksum(1);
+            byte[] data = { 1,2,3,4,5,6,7 };
+            adler.Update(data);
+            Assert.AreEqual( 0x5b001d, adler.Value  );
+
+            adler = new AdlerChecksum();
+            adler.Update("penguin");
+            Assert.AreEqual(0x0bcf02f6, adler.Value );
+
+            adler = new AdlerChecksum(1);
+            adler.Update("penguin");
+            Assert.AreEqual(0x0bd602f7, adler.Value);
+
+        }
+        #endregion
+    }
+
+    [TestFixture]
+    public class InfoTests
+    {
+        #region Info tests
+        [Test]
+        public void Info_Version()
+        {
+            Info info = new Info();
+            Assert.AreEqual("1.2.8", Info.Version);
+            Assert.AreEqual(32, info.SizeOfUInt);
+            Assert.AreEqual(32, info.SizeOfULong);
+            Assert.AreEqual(32, info.SizeOfPointer);
+            Assert.AreEqual(32, info.SizeOfOffset);
+        }
+        #endregion
+    }
+
+    [TestFixture]
+    public class DeflateInflateTests
+    {
+        #region Deflate tests
+        [Test]
+        public void Deflate_Init()
+        {
+            using (Deflater def = new Deflater(CompressLevel.Default))
+            {
+            }
+        }
+
+        private ArrayList compressedData = new ArrayList();
+        private uint adler1;
+
+        private ArrayList uncompressedData = new ArrayList();
+        private uint adler2;
+
+        public void CDataAvail(byte[] data, int startIndex, int count)
+        {
+            for (int i = 0; i < count; ++i)
+                compressedData.Add(data[i+startIndex]);
+        }
+
+        [Test]
+        public void Deflate_Compress()
+        {
+            compressedData.Clear();
+
+            byte[] testData = new byte[35000];
+            for (int i = 0; i < testData.Length; ++i)
+                testData[i] = 5;
+
+            using (Deflater def = new Deflater((CompressLevel)5))
+            {
+                def.DataAvailable += new DataAvailableHandler(CDataAvail);
+                def.Add(testData);
+                def.Finish();
+                adler1 = def.Checksum;
+            }
+        }
+        #endregion
+
+        #region Inflate tests
+        [Test]
+        public void Inflate_Init()
+        {
+            using (Inflater inf = new Inflater())
+            {
+            }
+        }
+
+        private void DDataAvail(byte[] data, int startIndex, int count)
+        {
+            for (int i = 0; i < count; ++i)
+                uncompressedData.Add(data[i+startIndex]);
+        }
+
+        [Test]
+        public void Inflate_Expand()
+        {
+            uncompressedData.Clear();
+
+            using (Inflater inf = new Inflater())
+            {
+                inf.DataAvailable += new DataAvailableHandler(DDataAvail);
+                inf.Add((byte[])compressedData.ToArray(typeof(byte)));
+                inf.Finish();
+                adler2 = inf.Checksum;
+            }
+            Assert.AreEqual( adler1, adler2 );
+        }
+        #endregion
+    }
+
+    [TestFixture]
+    public class GZipStreamTests
+    {
+        #region GZipStream test
+        [Test]
+        public void GZipStream_WriteRead()
+        {
+            using (GZipStream gzOut = new GZipStream("gzstream.gz", CompressLevel.Best))
+            {
+                BinaryWriter writer = new BinaryWriter(gzOut);
+                writer.Write("hi there");
+                writer.Write(Math.PI);
+                writer.Write(42);
+            }
+
+            using (GZipStream gzIn = new GZipStream("gzstream.gz"))
+            {
+                BinaryReader reader = new BinaryReader(gzIn);
+                string s = reader.ReadString();
+                Assert.AreEqual("hi there",s);
+                double d = reader.ReadDouble();
+                Assert.AreEqual(Math.PI, d);
+                int i = reader.ReadInt32();
+                Assert.AreEqual(42,i);
+            }
+
+        }
+        #endregion
+	}
+}
+
+#endif
diff --git a/compat/zlib/contrib/dotzlib/LICENSE_1_0.txt b/compat/zlib/contrib/dotzlib/LICENSE_1_0.txt
new file mode 100644
index 0000000..30aac2c
--- /dev/null
+++ b/compat/zlib/contrib/dotzlib/LICENSE_1_0.txt
@@ -0,0 +1,23 @@
+Boost Software License - Version 1.0 - August 17th, 2003
+
+Permission is hereby granted, free of charge, to any person or organization
+obtaining a copy of the software and accompanying documentation covered by
+this license (the "Software") to use, reproduce, display, distribute,
+execute, and transmit the Software, and to prepare derivative works of the
+Software, and to permit third-parties to whom the Software is furnished to
+do so, all subject to the following:
+
+The copyright notices in the Software and this entire statement, including
+the above license grant, this restriction and the following disclaimer,
+must be included in all copies of the Software, in whole or in part, and
+all derivative works of the Software, unless such copies or derivative
+works are solely in the form of machine-executable object code generated by
+a source language processor.
+
+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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
\ No newline at end of file
diff --git a/compat/zlib/contrib/dotzlib/readme.txt b/compat/zlib/contrib/dotzlib/readme.txt
new file mode 100644
index 0000000..b239572
--- /dev/null
+++ b/compat/zlib/contrib/dotzlib/readme.txt
@@ -0,0 +1,58 @@
+This directory contains a .Net wrapper class library for the ZLib1.dll
+
+The wrapper includes support for inflating/deflating memory buffers,
+.Net streaming wrappers for the gz streams part of zlib, and wrappers
+for the checksum parts of zlib. See DotZLib/UnitTests.cs for examples.
+
+Directory structure:
+--------------------
+
+LICENSE_1_0.txt       - License file.
+readme.txt            - This file.
+DotZLib.chm           - Class library documentation
+DotZLib.build         - NAnt build file
+DotZLib.sln           - Microsoft Visual Studio 2003 solution file
+
+DotZLib\*.cs          - Source files for the class library
+
+Unit tests:
+-----------
+The file DotZLib/UnitTests.cs contains unit tests for use with NUnit 2.1 or higher.
+To include unit tests in the build, define nunit before building.
+
+
+Build instructions:
+-------------------
+
+1. Using Visual Studio.Net 2003:
+   Open DotZLib.sln in VS.Net and build from there. Output file (DotZLib.dll)
+   will be found ./DotZLib/bin/release or ./DotZLib/bin/debug, depending on
+   you are building the release or debug version of the library. Check
+   DotZLib/UnitTests.cs for instructions on how to include unit tests in the
+   build.
+
+2. Using NAnt:
+   Open a command prompt with access to the build environment and run nant
+   in the same directory as the DotZLib.build file.
+   You can define 2 properties on the nant command-line to control the build:
+   debug={true|false} to toggle between release/debug builds (default=true).
+   nunit={true|false} to include or esclude unit tests (default=true).
+   Also the target clean will remove binaries.
+   Output file (DotZLib.dll) will be found in either ./DotZLib/bin/release
+   or ./DotZLib/bin/debug, depending on whether you are building the release
+   or debug version of the library.
+
+   Examples:
+     nant -D:debug=false -D:nunit=false
+       will build a release mode version of the library without unit tests.
+     nant
+       will build a debug version of the library with unit tests
+     nant clean
+       will remove all previously built files.
+
+
+---------------------------------
+Copyright (c) Henrik Ravn 2004
+
+Use, modification and distribution are subject to the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
diff --git a/compat/zlib/contrib/gcc_gvmat64/gvmat64.S b/compat/zlib/contrib/gcc_gvmat64/gvmat64.S
new file mode 100644
index 0000000..dd858dd
--- /dev/null
+++ b/compat/zlib/contrib/gcc_gvmat64/gvmat64.S
@@ -0,0 +1,574 @@
+/*
+;uInt longest_match_x64(
+;    deflate_state *s,
+;    IPos cur_match);                             // current match 
+
+; gvmat64.S -- Asm portion of the optimized longest_match for 32 bits x86_64
+;  (AMD64 on Athlon 64, Opteron, Phenom
+;     and Intel EM64T on Pentium 4 with EM64T, Pentium D, Core 2 Duo, Core I5/I7)
+; this file is translation from gvmat64.asm to GCC 4.x (for Linux, Mac XCode)
+; Copyright (C) 1995-2010 Jean-loup Gailly, Brian Raiter and Gilles Vollant.
+;
+; File written by Gilles Vollant, by converting to assembly the longest_match
+;  from Jean-loup Gailly in deflate.c of zLib and infoZip zip.
+;  and by taking inspiration on asm686 with masm, optimised assembly code
+;        from Brian Raiter, written 1998
+;
+;  This software is provided 'as-is', without any express or implied
+;  warranty.  In no event will the authors be held liable for any damages
+;  arising from the use of this software.
+;
+;  Permission is granted to anyone to use this software for any purpose,
+;  including commercial applications, and to alter it and redistribute it
+;  freely, subject to the following restrictions:
+;
+;  1. The origin of this software must not be misrepresented; you must not
+;     claim that you wrote the original software. If you use this software
+;     in a product, an acknowledgment in the product documentation would be
+;     appreciated but is not required.
+;  2. Altered source versions must be plainly marked as such, and must not be
+;     misrepresented as being the original software
+;  3. This notice may not be removed or altered from any source distribution.
+;
+;         http://www.zlib.net
+;         http://www.winimage.com/zLibDll
+;         http://www.muppetlabs.com/~breadbox/software/assembly.html
+;
+; to compile this file for zLib, I use option:
+;   gcc -c -arch x86_64 gvmat64.S
+
+
+;uInt longest_match(s, cur_match)
+;    deflate_state *s;
+;    IPos cur_match;                             // current match /
+;
+; with XCode for Mac, I had strange error with some jump on intel syntax
+; this is why BEFORE_JMP and AFTER_JMP are used
+ */
+
+
+#define BEFORE_JMP .att_syntax
+#define AFTER_JMP .intel_syntax noprefix
+
+#ifndef NO_UNDERLINE
+#	define	match_init	_match_init
+#	define	longest_match	_longest_match
+#endif
+
+.intel_syntax noprefix
+
+.globl	match_init, longest_match
+.text
+longest_match:
+
+
+
+#define LocalVarsSize 96
+/*
+; register used : rax,rbx,rcx,rdx,rsi,rdi,r8,r9,r10,r11,r12
+; free register :  r14,r15
+; register can be saved : rsp
+*/
+
+#define chainlenwmask     (rsp + 8 - LocalVarsSize)
+#define nicematch         (rsp + 16 - LocalVarsSize)
+
+#define save_rdi        (rsp + 24 - LocalVarsSize)
+#define save_rsi        (rsp + 32 - LocalVarsSize)
+#define save_rbx        (rsp + 40 - LocalVarsSize)
+#define save_rbp        (rsp + 48 - LocalVarsSize)
+#define save_r12        (rsp + 56 - LocalVarsSize)
+#define save_r13        (rsp + 64 - LocalVarsSize)
+#define save_r14        (rsp + 72 - LocalVarsSize)
+#define save_r15        (rsp + 80 - LocalVarsSize)
+
+
+/*
+;  all the +4 offsets are due to the addition of pending_buf_size (in zlib
+;  in the deflate_state structure since the asm code was first written
+;  (if you compile with zlib 1.0.4 or older, remove the +4).
+;  Note : these value are good with a 8 bytes boundary pack structure
+*/
+
+#define    MAX_MATCH              258
+#define    MIN_MATCH              3
+#define    MIN_LOOKAHEAD          (MAX_MATCH+MIN_MATCH+1)
+
+/*
+;;; Offsets for fields in the deflate_state structure. These numbers
+;;; are calculated from the definition of deflate_state, with the
+;;; assumption that the compiler will dword-align the fields. (Thus,
+;;; changing the definition of deflate_state could easily cause this
+;;; program to crash horribly, without so much as a warning at
+;;; compile time. Sigh.)
+
+;  all the +zlib1222add offsets are due to the addition of fields
+;  in zlib in the deflate_state structure since the asm code was first written
+;  (if you compile with zlib 1.0.4 or older, use "zlib1222add equ (-4)").
+;  (if you compile with zlib between 1.0.5 and 1.2.2.1, use "zlib1222add equ 0").
+;  if you compile with zlib 1.2.2.2 or later , use "zlib1222add equ 8").
+*/
+
+
+
+/* you can check the structure offset by running
+
+#include <stdlib.h>
+#include <stdio.h>
+#include "deflate.h"
+
+void print_depl()
+{
+deflate_state ds;
+deflate_state *s=&ds;
+printf("size pointer=%u\n",(int)sizeof(void*));
+
+printf("#define dsWSize         %u\n",(int)(((char*)&(s->w_size))-((char*)s)));
+printf("#define dsWMask         %u\n",(int)(((char*)&(s->w_mask))-((char*)s)));
+printf("#define dsWindow        %u\n",(int)(((char*)&(s->window))-((char*)s)));
+printf("#define dsPrev          %u\n",(int)(((char*)&(s->prev))-((char*)s)));
+printf("#define dsMatchLen      %u\n",(int)(((char*)&(s->match_length))-((char*)s)));
+printf("#define dsPrevMatch     %u\n",(int)(((char*)&(s->prev_match))-((char*)s)));
+printf("#define dsStrStart      %u\n",(int)(((char*)&(s->strstart))-((char*)s)));
+printf("#define dsMatchStart    %u\n",(int)(((char*)&(s->match_start))-((char*)s)));
+printf("#define dsLookahead     %u\n",(int)(((char*)&(s->lookahead))-((char*)s)));
+printf("#define dsPrevLen       %u\n",(int)(((char*)&(s->prev_length))-((char*)s)));
+printf("#define dsMaxChainLen   %u\n",(int)(((char*)&(s->max_chain_length))-((char*)s)));
+printf("#define dsGoodMatch     %u\n",(int)(((char*)&(s->good_match))-((char*)s)));
+printf("#define dsNiceMatch     %u\n",(int)(((char*)&(s->nice_match))-((char*)s)));
+}
+*/
+
+#define dsWSize          68
+#define dsWMask          76
+#define dsWindow         80
+#define dsPrev           96
+#define dsMatchLen       144
+#define dsPrevMatch      148
+#define dsStrStart       156
+#define dsMatchStart     160
+#define dsLookahead      164
+#define dsPrevLen        168
+#define dsMaxChainLen    172
+#define dsGoodMatch      188
+#define dsNiceMatch      192
+
+#define window_size      [ rcx + dsWSize]
+#define WMask            [ rcx + dsWMask]
+#define window_ad        [ rcx + dsWindow]
+#define prev_ad          [ rcx + dsPrev]
+#define strstart         [ rcx + dsStrStart]
+#define match_start      [ rcx + dsMatchStart]
+#define Lookahead        [ rcx + dsLookahead] //; 0ffffffffh on infozip
+#define prev_length      [ rcx + dsPrevLen]
+#define max_chain_length [ rcx + dsMaxChainLen]
+#define good_match       [ rcx + dsGoodMatch]
+#define nice_match       [ rcx + dsNiceMatch]
+
+/*
+; windows:
+; parameter 1 in rcx(deflate state s), param 2 in rdx (cur match)
+
+; see http://weblogs.asp.net/oldnewthing/archive/2004/01/14/58579.aspx and
+; http://msdn.microsoft.com/library/en-us/kmarch/hh/kmarch/64bitAMD_8e951dd2-ee77-4728-8702-55ce4b5dd24a.xml.asp
+;
+; All registers must be preserved across the call, except for
+;   rax, rcx, rdx, r8, r9, r10, and r11, which are scratch.
+
+;
+; gcc on macosx-linux:
+; see http://www.x86-64.org/documentation/abi-0.99.pdf
+; param 1 in rdi, param 2 in rsi
+; rbx, rsp, rbp, r12 to r15 must be preserved
+
+;;; Save registers that the compiler may be using, and adjust esp to
+;;; make room for our stack frame.
+
+
+;;; Retrieve the function arguments. r8d will hold cur_match
+;;; throughout the entire function. edx will hold the pointer to the
+;;; deflate_state structure during the function's setup (before
+;;; entering the main loop.
+
+; ms: parameter 1 in rcx (deflate_state* s), param 2 in edx -> r8 (cur match)
+; mac: param 1 in rdi, param 2 rsi
+; this clear high 32 bits of r8, which can be garbage in both r8 and rdx
+*/
+        mov [save_rbx],rbx
+        mov [save_rbp],rbp
+
+
+        mov rcx,rdi
+
+        mov r8d,esi
+
+
+        mov [save_r12],r12
+        mov [save_r13],r13
+        mov [save_r14],r14
+        mov [save_r15],r15
+
+
+//;;; uInt wmask = s->w_mask;
+//;;; unsigned chain_length = s->max_chain_length;
+//;;; if (s->prev_length >= s->good_match) {
+//;;;     chain_length >>= 2;
+//;;; }
+
+
+        mov edi, prev_length
+        mov esi, good_match
+        mov eax, WMask
+        mov ebx, max_chain_length
+        cmp edi, esi
+        jl  LastMatchGood
+        shr ebx, 2
+LastMatchGood:
+
+//;;; chainlen is decremented once beforehand so that the function can
+//;;; use the sign flag instead of the zero flag for the exit test.
+//;;; It is then shifted into the high word, to make room for the wmask
+//;;; value, which it will always accompany.
+
+        dec ebx
+        shl ebx, 16
+        or  ebx, eax
+
+//;;; on zlib only
+//;;; if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;
+
+
+
+        mov eax, nice_match
+        mov [chainlenwmask], ebx
+        mov r10d, Lookahead
+        cmp r10d, eax
+        cmovnl r10d, eax
+        mov [nicematch],r10d
+
+
+
+//;;; register Bytef *scan = s->window + s->strstart;
+        mov r10, window_ad
+        mov ebp, strstart
+        lea r13, [r10 + rbp]
+
+//;;; Determine how many bytes the scan ptr is off from being
+//;;; dword-aligned.
+
+         mov r9,r13
+         neg r13
+         and r13,3
+
+//;;; IPos limit = s->strstart > (IPos)MAX_DIST(s) ?
+//;;;     s->strstart - (IPos)MAX_DIST(s) : NIL;
+
+
+        mov eax, window_size
+        sub eax, MIN_LOOKAHEAD
+
+
+        xor edi,edi
+        sub ebp, eax
+
+        mov r11d, prev_length
+
+        cmovng ebp,edi
+
+//;;; int best_len = s->prev_length;
+
+
+//;;; Store the sum of s->window + best_len in esi locally, and in esi.
+
+       lea  rsi,[r10+r11]
+
+//;;; register ush scan_start = *(ushf*)scan;
+//;;; register ush scan_end   = *(ushf*)(scan+best_len-1);
+//;;; Posf *prev = s->prev;
+
+        movzx r12d,word ptr [r9]
+        movzx ebx, word ptr [r9 + r11 - 1]
+
+        mov rdi, prev_ad
+
+//;;; Jump into the main loop.
+
+        mov edx, [chainlenwmask]
+
+        cmp bx,word ptr [rsi + r8 - 1]
+        jz  LookupLoopIsZero
+				
+						
+						
+LookupLoop1:
+        and r8d, edx
+
+        movzx   r8d, word ptr [rdi + r8*2]
+        cmp r8d, ebp
+        jbe LeaveNow
+		
+		
+		
+        sub edx, 0x00010000
+		BEFORE_JMP
+        js  LeaveNow
+		AFTER_JMP
+
+LoopEntry1:
+        cmp bx,word ptr [rsi + r8 - 1]
+		BEFORE_JMP
+        jz  LookupLoopIsZero
+		AFTER_JMP
+
+LookupLoop2:
+        and r8d, edx
+
+        movzx   r8d, word ptr [rdi + r8*2]
+        cmp r8d, ebp
+		BEFORE_JMP
+        jbe LeaveNow
+		AFTER_JMP
+        sub edx, 0x00010000
+		BEFORE_JMP
+        js  LeaveNow
+		AFTER_JMP
+
+LoopEntry2:
+        cmp bx,word ptr [rsi + r8 - 1]
+		BEFORE_JMP
+        jz  LookupLoopIsZero
+		AFTER_JMP
+
+LookupLoop4:
+        and r8d, edx
+
+        movzx   r8d, word ptr [rdi + r8*2]
+        cmp r8d, ebp
+		BEFORE_JMP
+        jbe LeaveNow
+		AFTER_JMP
+        sub edx, 0x00010000
+		BEFORE_JMP
+        js  LeaveNow
+		AFTER_JMP
+
+LoopEntry4:
+
+        cmp bx,word ptr [rsi + r8 - 1]
+		BEFORE_JMP
+        jnz LookupLoop1
+        jmp LookupLoopIsZero
+		AFTER_JMP
+/*
+;;; do {
+;;;     match = s->window + cur_match;
+;;;     if (*(ushf*)(match+best_len-1) != scan_end ||
+;;;         *(ushf*)match != scan_start) continue;
+;;;     [...]
+;;; } while ((cur_match = prev[cur_match & wmask]) > limit
+;;;          && --chain_length != 0);
+;;;
+;;; Here is the inner loop of the function. The function will spend the
+;;; majority of its time in this loop, and majority of that time will
+;;; be spent in the first ten instructions.
+;;;
+;;; Within this loop:
+;;; ebx = scanend
+;;; r8d = curmatch
+;;; edx = chainlenwmask - i.e., ((chainlen << 16) | wmask)
+;;; esi = windowbestlen - i.e., (window + bestlen)
+;;; edi = prev
+;;; ebp = limit
+*/
+.balign 16
+LookupLoop:
+        and r8d, edx
+
+        movzx   r8d, word ptr [rdi + r8*2]
+        cmp r8d, ebp
+		BEFORE_JMP
+        jbe LeaveNow
+		AFTER_JMP
+        sub edx, 0x00010000
+		BEFORE_JMP
+        js  LeaveNow
+		AFTER_JMP
+
+LoopEntry:
+
+        cmp bx,word ptr [rsi + r8 - 1]
+		BEFORE_JMP
+        jnz LookupLoop1
+		AFTER_JMP
+LookupLoopIsZero:
+        cmp     r12w, word ptr [r10 + r8]
+		BEFORE_JMP
+        jnz LookupLoop1
+		AFTER_JMP
+
+
+//;;; Store the current value of chainlen.
+        mov [chainlenwmask], edx
+/*
+;;; Point edi to the string under scrutiny, and esi to the string we
+;;; are hoping to match it up with. In actuality, esi and edi are
+;;; both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and edx is
+;;; initialized to -(MAX_MATCH_8 - scanalign).
+*/
+        lea rsi,[r8+r10]
+        mov rdx, 0xfffffffffffffef8 //; -(MAX_MATCH_8)
+        lea rsi, [rsi + r13 + 0x0108] //;MAX_MATCH_8]
+        lea rdi, [r9 + r13 + 0x0108] //;MAX_MATCH_8]
+
+        prefetcht1 [rsi+rdx]
+        prefetcht1 [rdi+rdx]
+
+/*
+;;; Test the strings for equality, 8 bytes at a time. At the end,
+;;; adjust rdx so that it is offset to the exact byte that mismatched.
+;;;
+;;; We already know at this point that the first three bytes of the
+;;; strings match each other, and they can be safely passed over before
+;;; starting the compare loop. So what this code does is skip over 0-3
+;;; bytes, as much as necessary in order to dword-align the edi
+;;; pointer. (rsi will still be misaligned three times out of four.)
+;;;
+;;; It should be confessed that this loop usually does not represent
+;;; much of the total running time. Replacing it with a more
+;;; straightforward "rep cmpsb" would not drastically degrade
+;;; performance.
+*/
+
+LoopCmps:
+        mov rax, [rsi + rdx]
+        xor rax, [rdi + rdx]
+        jnz LeaveLoopCmps
+
+        mov rax, [rsi + rdx + 8]
+        xor rax, [rdi + rdx + 8]
+        jnz LeaveLoopCmps8
+
+
+        mov rax, [rsi + rdx + 8+8]
+        xor rax, [rdi + rdx + 8+8]
+        jnz LeaveLoopCmps16
+
+        add rdx,8+8+8
+
+		BEFORE_JMP
+        jnz  LoopCmps
+        jmp  LenMaximum
+		AFTER_JMP
+		
+LeaveLoopCmps16: add rdx,8
+LeaveLoopCmps8: add rdx,8
+LeaveLoopCmps:
+
+        test    eax, 0x0000FFFF
+        jnz LenLower
+
+        test eax,0xffffffff
+
+        jnz LenLower32
+
+        add rdx,4
+        shr rax,32
+        or ax,ax
+		BEFORE_JMP
+        jnz LenLower
+		AFTER_JMP
+
+LenLower32:
+        shr eax,16
+        add rdx,2
+		
+LenLower:		
+        sub al, 1
+        adc rdx, 0
+//;;; Calculate the length of the match. If it is longer than MAX_MATCH,
+//;;; then automatically accept it as the best possible match and leave.
+
+        lea rax, [rdi + rdx]
+        sub rax, r9
+        cmp eax, MAX_MATCH
+		BEFORE_JMP
+        jge LenMaximum
+		AFTER_JMP
+/*
+;;; If the length of the match is not longer than the best match we
+;;; have so far, then forget it and return to the lookup loop.
+;///////////////////////////////////
+*/
+        cmp eax, r11d
+        jg  LongerMatch
+
+        lea rsi,[r10+r11]
+
+        mov rdi, prev_ad
+        mov edx, [chainlenwmask]
+		BEFORE_JMP
+        jmp LookupLoop
+		AFTER_JMP
+/*
+;;;         s->match_start = cur_match;
+;;;         best_len = len;
+;;;         if (len >= nice_match) break;
+;;;         scan_end = *(ushf*)(scan+best_len-1);
+*/
+LongerMatch:
+        mov r11d, eax
+        mov match_start, r8d
+        cmp eax, [nicematch]
+		BEFORE_JMP
+        jge LeaveNow
+		AFTER_JMP
+
+        lea rsi,[r10+rax]
+
+        movzx   ebx, word ptr [r9 + rax - 1]
+        mov rdi, prev_ad
+        mov edx, [chainlenwmask]
+		BEFORE_JMP
+        jmp LookupLoop
+		AFTER_JMP
+
+//;;; Accept the current string, with the maximum possible length.
+
+LenMaximum:
+        mov r11d,MAX_MATCH
+        mov match_start, r8d
+
+//;;; if ((uInt)best_len <= s->lookahead) return (uInt)best_len;
+//;;; return s->lookahead;
+
+LeaveNow:
+        mov eax, Lookahead
+        cmp r11d, eax
+        cmovng eax, r11d
+
+
+
+//;;; Restore the stack and return from whence we came.
+
+
+//        mov rsi,[save_rsi]
+//        mov rdi,[save_rdi]
+        mov rbx,[save_rbx]
+        mov rbp,[save_rbp]
+        mov r12,[save_r12]
+        mov r13,[save_r13]
+        mov r14,[save_r14]
+        mov r15,[save_r15]
+
+
+        ret 0
+//; please don't remove this string !
+//; Your can freely use gvmat64 in any free or commercial app
+//; but it is far better don't remove the string in the binary!
+ //   db     0dh,0ah,"asm686 with masm, optimised assembly code from Brian Raiter, written 1998, converted to amd 64 by Gilles Vollant 2005",0dh,0ah,0
+
+
+match_init:
+  ret 0
+
+
diff --git a/compat/zlib/contrib/infback9/README b/compat/zlib/contrib/infback9/README
new file mode 100644
index 0000000..e75ed13
--- /dev/null
+++ b/compat/zlib/contrib/infback9/README
@@ -0,0 +1 @@
+See infback9.h for what this is and how to use it.
diff --git a/compat/zlib/contrib/infback9/infback9.c b/compat/zlib/contrib/infback9/infback9.c
new file mode 100644
index 0000000..05fb3e3
--- /dev/null
+++ b/compat/zlib/contrib/infback9/infback9.c
@@ -0,0 +1,615 @@
+/* infback9.c -- inflate deflate64 data using a call-back interface
+ * Copyright (C) 1995-2008 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+#include "zutil.h"
+#include "infback9.h"
+#include "inftree9.h"
+#include "inflate9.h"
+
+#define WSIZE 65536UL
+
+/*
+   strm provides memory allocation functions in zalloc and zfree, or
+   Z_NULL to use the library memory allocation functions.
+
+   window is a user-supplied window and output buffer that is 64K bytes.
+ */
+int ZEXPORT inflateBack9Init_(strm, window, version, stream_size)
+z_stream FAR *strm;
+unsigned char FAR *window;
+const char *version;
+int stream_size;
+{
+    struct inflate_state FAR *state;
+
+    if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
+        stream_size != (int)(sizeof(z_stream)))
+        return Z_VERSION_ERROR;
+    if (strm == Z_NULL || window == Z_NULL)
+        return Z_STREAM_ERROR;
+    strm->msg = Z_NULL;                 /* in case we return an error */
+    if (strm->zalloc == (alloc_func)0) {
+        strm->zalloc = zcalloc;
+        strm->opaque = (voidpf)0;
+    }
+    if (strm->zfree == (free_func)0) strm->zfree = zcfree;
+    state = (struct inflate_state FAR *)ZALLOC(strm, 1,
+                                               sizeof(struct inflate_state));
+    if (state == Z_NULL) return Z_MEM_ERROR;
+    Tracev((stderr, "inflate: allocated\n"));
+    strm->state = (voidpf)state;
+    state->window = window;
+    return Z_OK;
+}
+
+/*
+   Build and output length and distance decoding tables for fixed code
+   decoding.
+ */
+#ifdef MAKEFIXED
+#include <stdio.h>
+
+void makefixed9(void)
+{
+    unsigned sym, bits, low, size;
+    code *next, *lenfix, *distfix;
+    struct inflate_state state;
+    code fixed[544];
+
+    /* literal/length table */
+    sym = 0;
+    while (sym < 144) state.lens[sym++] = 8;
+    while (sym < 256) state.lens[sym++] = 9;
+    while (sym < 280) state.lens[sym++] = 7;
+    while (sym < 288) state.lens[sym++] = 8;
+    next = fixed;
+    lenfix = next;
+    bits = 9;
+    inflate_table9(LENS, state.lens, 288, &(next), &(bits), state.work);
+
+    /* distance table */
+    sym = 0;
+    while (sym < 32) state.lens[sym++] = 5;
+    distfix = next;
+    bits = 5;
+    inflate_table9(DISTS, state.lens, 32, &(next), &(bits), state.work);
+
+    /* write tables */
+    puts("    /* inffix9.h -- table for decoding deflate64 fixed codes");
+    puts("     * Generated automatically by makefixed9().");
+    puts("     */");
+    puts("");
+    puts("    /* WARNING: this file should *not* be used by applications.");
+    puts("       It is part of the implementation of this library and is");
+    puts("       subject to change. Applications should only use zlib.h.");
+    puts("     */");
+    puts("");
+    size = 1U << 9;
+    printf("    static const code lenfix[%u] = {", size);
+    low = 0;
+    for (;;) {
+        if ((low % 6) == 0) printf("\n        ");
+        printf("{%u,%u,%d}", lenfix[low].op, lenfix[low].bits,
+               lenfix[low].val);
+        if (++low == size) break;
+        putchar(',');
+    }
+    puts("\n    };");
+    size = 1U << 5;
+    printf("\n    static const code distfix[%u] = {", size);
+    low = 0;
+    for (;;) {
+        if ((low % 5) == 0) printf("\n        ");
+        printf("{%u,%u,%d}", distfix[low].op, distfix[low].bits,
+               distfix[low].val);
+        if (++low == size) break;
+        putchar(',');
+    }
+    puts("\n    };");
+}
+#endif /* MAKEFIXED */
+
+/* Macros for inflateBack(): */
+
+/* Clear the input bit accumulator */
+#define INITBITS() \
+    do { \
+        hold = 0; \
+        bits = 0; \
+    } while (0)
+
+/* Assure that some input is available.  If input is requested, but denied,
+   then return a Z_BUF_ERROR from inflateBack(). */
+#define PULL() \
+    do { \
+        if (have == 0) { \
+            have = in(in_desc, &next); \
+            if (have == 0) { \
+                next = Z_NULL; \
+                ret = Z_BUF_ERROR; \
+                goto inf_leave; \
+            } \
+        } \
+    } while (0)
+
+/* Get a byte of input into the bit accumulator, or return from inflateBack()
+   with an error if there is no input available. */
+#define PULLBYTE() \
+    do { \
+        PULL(); \
+        have--; \
+        hold += (unsigned long)(*next++) << bits; \
+        bits += 8; \
+    } while (0)
+
+/* Assure that there are at least n bits in the bit accumulator.  If there is
+   not enough available input to do that, then return from inflateBack() with
+   an error. */
+#define NEEDBITS(n) \
+    do { \
+        while (bits < (unsigned)(n)) \
+            PULLBYTE(); \
+    } while (0)
+
+/* Return the low n bits of the bit accumulator (n <= 16) */
+#define BITS(n) \
+    ((unsigned)hold & ((1U << (n)) - 1))
+
+/* Remove n bits from the bit accumulator */
+#define DROPBITS(n) \
+    do { \
+        hold >>= (n); \
+        bits -= (unsigned)(n); \
+    } while (0)
+
+/* Remove zero to seven bits as needed to go to a byte boundary */
+#define BYTEBITS() \
+    do { \
+        hold >>= bits & 7; \
+        bits -= bits & 7; \
+    } while (0)
+
+/* Assure that some output space is available, by writing out the window
+   if it's full.  If the write fails, return from inflateBack() with a
+   Z_BUF_ERROR. */
+#define ROOM() \
+    do { \
+        if (left == 0) { \
+            put = window; \
+            left = WSIZE; \
+            wrap = 1; \
+            if (out(out_desc, put, (unsigned)left)) { \
+                ret = Z_BUF_ERROR; \
+                goto inf_leave; \
+            } \
+        } \
+    } while (0)
+
+/*
+   strm provides the memory allocation functions and window buffer on input,
+   and provides information on the unused input on return.  For Z_DATA_ERROR
+   returns, strm will also provide an error message.
+
+   in() and out() are the call-back input and output functions.  When
+   inflateBack() needs more input, it calls in().  When inflateBack() has
+   filled the window with output, or when it completes with data in the
+   window, it calls out() to write out the data.  The application must not
+   change the provided input until in() is called again or inflateBack()
+   returns.  The application must not change the window/output buffer until
+   inflateBack() returns.
+
+   in() and out() are called with a descriptor parameter provided in the
+   inflateBack() call.  This parameter can be a structure that provides the
+   information required to do the read or write, as well as accumulated
+   information on the input and output such as totals and check values.
+
+   in() should return zero on failure.  out() should return non-zero on
+   failure.  If either in() or out() fails, than inflateBack() returns a
+   Z_BUF_ERROR.  strm->next_in can be checked for Z_NULL to see whether it
+   was in() or out() that caused in the error.  Otherwise,  inflateBack()
+   returns Z_STREAM_END on success, Z_DATA_ERROR for an deflate format
+   error, or Z_MEM_ERROR if it could not allocate memory for the state.
+   inflateBack() can also return Z_STREAM_ERROR if the input parameters
+   are not correct, i.e. strm is Z_NULL or the state was not initialized.
+ */
+int ZEXPORT inflateBack9(strm, in, in_desc, out, out_desc)
+z_stream FAR *strm;
+in_func in;
+void FAR *in_desc;
+out_func out;
+void FAR *out_desc;
+{
+    struct inflate_state FAR *state;
+    z_const unsigned char FAR *next;    /* next input */
+    unsigned char FAR *put;     /* next output */
+    unsigned have;              /* available input */
+    unsigned long left;         /* available output */
+    inflate_mode mode;          /* current inflate mode */
+    int lastblock;              /* true if processing last block */
+    int wrap;                   /* true if the window has wrapped */
+    unsigned char FAR *window;  /* allocated sliding window, if needed */
+    unsigned long hold;         /* bit buffer */
+    unsigned bits;              /* bits in bit buffer */
+    unsigned extra;             /* extra bits needed */
+    unsigned long length;       /* literal or length of data to copy */
+    unsigned long offset;       /* distance back to copy string from */
+    unsigned long copy;         /* number of stored or match bytes to copy */
+    unsigned char FAR *from;    /* where to copy match bytes from */
+    code const FAR *lencode;    /* starting table for length/literal codes */
+    code const FAR *distcode;   /* starting table for distance codes */
+    unsigned lenbits;           /* index bits for lencode */
+    unsigned distbits;          /* index bits for distcode */
+    code here;                  /* current decoding table entry */
+    code last;                  /* parent table entry */
+    unsigned len;               /* length to copy for repeats, bits to drop */
+    int ret;                    /* return code */
+    static const unsigned short order[19] = /* permutation of code lengths */
+        {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
+#include "inffix9.h"
+
+    /* Check that the strm exists and that the state was initialized */
+    if (strm == Z_NULL || strm->state == Z_NULL)
+        return Z_STREAM_ERROR;
+    state = (struct inflate_state FAR *)strm->state;
+
+    /* Reset the state */
+    strm->msg = Z_NULL;
+    mode = TYPE;
+    lastblock = 0;
+    wrap = 0;
+    window = state->window;
+    next = strm->next_in;
+    have = next != Z_NULL ? strm->avail_in : 0;
+    hold = 0;
+    bits = 0;
+    put = window;
+    left = WSIZE;
+    lencode = Z_NULL;
+    distcode = Z_NULL;
+
+    /* Inflate until end of block marked as last */
+    for (;;)
+        switch (mode) {
+        case TYPE:
+            /* determine and dispatch block type */
+            if (lastblock) {
+                BYTEBITS();
+                mode = DONE;
+                break;
+            }
+            NEEDBITS(3);
+            lastblock = BITS(1);
+            DROPBITS(1);
+            switch (BITS(2)) {
+            case 0:                             /* stored block */
+                Tracev((stderr, "inflate:     stored block%s\n",
+                        lastblock ? " (last)" : ""));
+                mode = STORED;
+                break;
+            case 1:                             /* fixed block */
+                lencode = lenfix;
+                lenbits = 9;
+                distcode = distfix;
+                distbits = 5;
+                Tracev((stderr, "inflate:     fixed codes block%s\n",
+                        lastblock ? " (last)" : ""));
+                mode = LEN;                     /* decode codes */
+                break;
+            case 2:                             /* dynamic block */
+                Tracev((stderr, "inflate:     dynamic codes block%s\n",
+                        lastblock ? " (last)" : ""));
+                mode = TABLE;
+                break;
+            case 3:
+                strm->msg = (char *)"invalid block type";
+                mode = BAD;
+            }
+            DROPBITS(2);
+            break;
+
+        case STORED:
+            /* get and verify stored block length */
+            BYTEBITS();                         /* go to byte boundary */
+            NEEDBITS(32);
+            if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) {
+                strm->msg = (char *)"invalid stored block lengths";
+                mode = BAD;
+                break;
+            }
+            length = (unsigned)hold & 0xffff;
+            Tracev((stderr, "inflate:       stored length %lu\n",
+                    length));
+            INITBITS();
+
+            /* copy stored block from input to output */
+            while (length != 0) {
+                copy = length;
+                PULL();
+                ROOM();
+                if (copy > have) copy = have;
+                if (copy > left) copy = left;
+                zmemcpy(put, next, copy);
+                have -= copy;
+                next += copy;
+                left -= copy;
+                put += copy;
+                length -= copy;
+            }
+            Tracev((stderr, "inflate:       stored end\n"));
+            mode = TYPE;
+            break;
+
+        case TABLE:
+            /* get dynamic table entries descriptor */
+            NEEDBITS(14);
+            state->nlen = BITS(5) + 257;
+            DROPBITS(5);
+            state->ndist = BITS(5) + 1;
+            DROPBITS(5);
+            state->ncode = BITS(4) + 4;
+            DROPBITS(4);
+            if (state->nlen > 286) {
+                strm->msg = (char *)"too many length symbols";
+                mode = BAD;
+                break;
+            }
+            Tracev((stderr, "inflate:       table sizes ok\n"));
+
+            /* get code length code lengths (not a typo) */
+            state->have = 0;
+            while (state->have < state->ncode) {
+                NEEDBITS(3);
+                state->lens[order[state->have++]] = (unsigned short)BITS(3);
+                DROPBITS(3);
+            }
+            while (state->have < 19)
+                state->lens[order[state->have++]] = 0;
+            state->next = state->codes;
+            lencode = (code const FAR *)(state->next);
+            lenbits = 7;
+            ret = inflate_table9(CODES, state->lens, 19, &(state->next),
+                                &(lenbits), state->work);
+            if (ret) {
+                strm->msg = (char *)"invalid code lengths set";
+                mode = BAD;
+                break;
+            }
+            Tracev((stderr, "inflate:       code lengths ok\n"));
+
+            /* get length and distance code code lengths */
+            state->have = 0;
+            while (state->have < state->nlen + state->ndist) {
+                for (;;) {
+                    here = lencode[BITS(lenbits)];
+                    if ((unsigned)(here.bits) <= bits) break;
+                    PULLBYTE();
+                }
+                if (here.val < 16) {
+                    NEEDBITS(here.bits);
+                    DROPBITS(here.bits);
+                    state->lens[state->have++] = here.val;
+                }
+                else {
+                    if (here.val == 16) {
+                        NEEDBITS(here.bits + 2);
+                        DROPBITS(here.bits);
+                        if (state->have == 0) {
+                            strm->msg = (char *)"invalid bit length repeat";
+                            mode = BAD;
+                            break;
+                        }
+                        len = (unsigned)(state->lens[state->have - 1]);
+                        copy = 3 + BITS(2);
+                        DROPBITS(2);
+                    }
+                    else if (here.val == 17) {
+                        NEEDBITS(here.bits + 3);
+                        DROPBITS(here.bits);
+                        len = 0;
+                        copy = 3 + BITS(3);
+                        DROPBITS(3);
+                    }
+                    else {
+                        NEEDBITS(here.bits + 7);
+                        DROPBITS(here.bits);
+                        len = 0;
+                        copy = 11 + BITS(7);
+                        DROPBITS(7);
+                    }
+                    if (state->have + copy > state->nlen + state->ndist) {
+                        strm->msg = (char *)"invalid bit length repeat";
+                        mode = BAD;
+                        break;
+                    }
+                    while (copy--)
+                        state->lens[state->have++] = (unsigned short)len;
+                }
+            }
+
+            /* handle error breaks in while */
+            if (mode == BAD) break;
+
+            /* check for end-of-block code (better have one) */
+            if (state->lens[256] == 0) {
+                strm->msg = (char *)"invalid code -- missing end-of-block";
+                mode = BAD;
+                break;
+            }
+
+            /* build code tables -- note: do not change the lenbits or distbits
+               values here (9 and 6) without reading the comments in inftree9.h
+               concerning the ENOUGH constants, which depend on those values */
+            state->next = state->codes;
+            lencode = (code const FAR *)(state->next);
+            lenbits = 9;
+            ret = inflate_table9(LENS, state->lens, state->nlen,
+                            &(state->next), &(lenbits), state->work);
+            if (ret) {
+                strm->msg = (char *)"invalid literal/lengths set";
+                mode = BAD;
+                break;
+            }
+            distcode = (code const FAR *)(state->next);
+            distbits = 6;
+            ret = inflate_table9(DISTS, state->lens + state->nlen,
+                            state->ndist, &(state->next), &(distbits),
+                            state->work);
+            if (ret) {
+                strm->msg = (char *)"invalid distances set";
+                mode = BAD;
+                break;
+            }
+            Tracev((stderr, "inflate:       codes ok\n"));
+            mode = LEN;
+
+        case LEN:
+            /* get a literal, length, or end-of-block code */
+            for (;;) {
+                here = lencode[BITS(lenbits)];
+                if ((unsigned)(here.bits) <= bits) break;
+                PULLBYTE();
+            }
+            if (here.op && (here.op & 0xf0) == 0) {
+                last = here;
+                for (;;) {
+                    here = lencode[last.val +
+                            (BITS(last.bits + last.op) >> last.bits)];
+                    if ((unsigned)(last.bits + here.bits) <= bits) break;
+                    PULLBYTE();
+                }
+                DROPBITS(last.bits);
+            }
+            DROPBITS(here.bits);
+            length = (unsigned)here.val;
+
+            /* process literal */
+            if (here.op == 0) {
+                Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?
+                        "inflate:         literal '%c'\n" :
+                        "inflate:         literal 0x%02x\n", here.val));
+                ROOM();
+                *put++ = (unsigned char)(length);
+                left--;
+                mode = LEN;
+                break;
+            }
+
+            /* process end of block */
+            if (here.op & 32) {
+                Tracevv((stderr, "inflate:         end of block\n"));
+                mode = TYPE;
+                break;
+            }
+
+            /* invalid code */
+            if (here.op & 64) {
+                strm->msg = (char *)"invalid literal/length code";
+                mode = BAD;
+                break;
+            }
+
+            /* length code -- get extra bits, if any */
+            extra = (unsigned)(here.op) & 31;
+            if (extra != 0) {
+                NEEDBITS(extra);
+                length += BITS(extra);
+                DROPBITS(extra);
+            }
+            Tracevv((stderr, "inflate:         length %lu\n", length));
+
+            /* get distance code */
+            for (;;) {
+                here = distcode[BITS(distbits)];
+                if ((unsigned)(here.bits) <= bits) break;
+                PULLBYTE();
+            }
+            if ((here.op & 0xf0) == 0) {
+                last = here;
+                for (;;) {
+                    here = distcode[last.val +
+                            (BITS(last.bits + last.op) >> last.bits)];
+                    if ((unsigned)(last.bits + here.bits) <= bits) break;
+                    PULLBYTE();
+                }
+                DROPBITS(last.bits);
+            }
+            DROPBITS(here.bits);
+            if (here.op & 64) {
+                strm->msg = (char *)"invalid distance code";
+                mode = BAD;
+                break;
+            }
+            offset = (unsigned)here.val;
+
+            /* get distance extra bits, if any */
+            extra = (unsigned)(here.op) & 15;
+            if (extra != 0) {
+                NEEDBITS(extra);
+                offset += BITS(extra);
+                DROPBITS(extra);
+            }
+            if (offset > WSIZE - (wrap ? 0: left)) {
+                strm->msg = (char *)"invalid distance too far back";
+                mode = BAD;
+                break;
+            }
+            Tracevv((stderr, "inflate:         distance %lu\n", offset));
+
+            /* copy match from window to output */
+            do {
+                ROOM();
+                copy = WSIZE - offset;
+                if (copy < left) {
+                    from = put + copy;
+                    copy = left - copy;
+                }
+                else {
+                    from = put - offset;
+                    copy = left;
+                }
+                if (copy > length) copy = length;
+                length -= copy;
+                left -= copy;
+                do {
+                    *put++ = *from++;
+                } while (--copy);
+            } while (length != 0);
+            break;
+
+        case DONE:
+            /* inflate stream terminated properly -- write leftover output */
+            ret = Z_STREAM_END;
+            if (left < WSIZE) {
+                if (out(out_desc, window, (unsigned)(WSIZE - left)))
+                    ret = Z_BUF_ERROR;
+            }
+            goto inf_leave;
+
+        case BAD:
+            ret = Z_DATA_ERROR;
+            goto inf_leave;
+
+        default:                /* can't happen, but makes compilers happy */
+            ret = Z_STREAM_ERROR;
+            goto inf_leave;
+        }
+
+    /* Return unused input */
+  inf_leave:
+    strm->next_in = next;
+    strm->avail_in = have;
+    return ret;
+}
+
+int ZEXPORT inflateBack9End(strm)
+z_stream FAR *strm;
+{
+    if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0)
+        return Z_STREAM_ERROR;
+    ZFREE(strm, strm->state);
+    strm->state = Z_NULL;
+    Tracev((stderr, "inflate: end\n"));
+    return Z_OK;
+}
diff --git a/compat/zlib/contrib/infback9/infback9.h b/compat/zlib/contrib/infback9/infback9.h
new file mode 100644
index 0000000..1073c0a
--- /dev/null
+++ b/compat/zlib/contrib/infback9/infback9.h
@@ -0,0 +1,37 @@
+/* infback9.h -- header for using inflateBack9 functions
+ * Copyright (C) 2003 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/*
+ * This header file and associated patches provide a decoder for PKWare's
+ * undocumented deflate64 compression method (method 9).  Use with infback9.c,
+ * inftree9.h, inftree9.c, and inffix9.h.  These patches are not supported.
+ * This should be compiled with zlib, since it uses zutil.h and zutil.o.
+ * This code has not yet been tested on 16-bit architectures.  See the
+ * comments in zlib.h for inflateBack() usage.  These functions are used
+ * identically, except that there is no windowBits parameter, and a 64K
+ * window must be provided.  Also if int's are 16 bits, then a zero for
+ * the third parameter of the "out" function actually means 65536UL.
+ * zlib.h must be included before this header file.
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ZEXTERN int ZEXPORT inflateBack9 OF((z_stream FAR *strm,
+                                    in_func in, void FAR *in_desc,
+                                    out_func out, void FAR *out_desc));
+ZEXTERN int ZEXPORT inflateBack9End OF((z_stream FAR *strm));
+ZEXTERN int ZEXPORT inflateBack9Init_ OF((z_stream FAR *strm,
+                                         unsigned char FAR *window,
+                                         const char *version,
+                                         int stream_size));
+#define inflateBack9Init(strm, window) \
+        inflateBack9Init_((strm), (window), \
+        ZLIB_VERSION, sizeof(z_stream))
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/compat/zlib/contrib/infback9/inffix9.h b/compat/zlib/contrib/infback9/inffix9.h
new file mode 100644
index 0000000..ee5671d
--- /dev/null
+++ b/compat/zlib/contrib/infback9/inffix9.h
@@ -0,0 +1,107 @@
+    /* inffix9.h -- table for decoding deflate64 fixed codes
+     * Generated automatically by makefixed9().
+     */
+
+    /* WARNING: this file should *not* be used by applications.
+       It is part of the implementation of this library and is
+       subject to change. Applications should only use zlib.h.
+     */
+
+    static const code lenfix[512] = {
+        {96,7,0},{0,8,80},{0,8,16},{132,8,115},{130,7,31},{0,8,112},
+        {0,8,48},{0,9,192},{128,7,10},{0,8,96},{0,8,32},{0,9,160},
+        {0,8,0},{0,8,128},{0,8,64},{0,9,224},{128,7,6},{0,8,88},
+        {0,8,24},{0,9,144},{131,7,59},{0,8,120},{0,8,56},{0,9,208},
+        {129,7,17},{0,8,104},{0,8,40},{0,9,176},{0,8,8},{0,8,136},
+        {0,8,72},{0,9,240},{128,7,4},{0,8,84},{0,8,20},{133,8,227},
+        {131,7,43},{0,8,116},{0,8,52},{0,9,200},{129,7,13},{0,8,100},
+        {0,8,36},{0,9,168},{0,8,4},{0,8,132},{0,8,68},{0,9,232},
+        {128,7,8},{0,8,92},{0,8,28},{0,9,152},{132,7,83},{0,8,124},
+        {0,8,60},{0,9,216},{130,7,23},{0,8,108},{0,8,44},{0,9,184},
+        {0,8,12},{0,8,140},{0,8,76},{0,9,248},{128,7,3},{0,8,82},
+        {0,8,18},{133,8,163},{131,7,35},{0,8,114},{0,8,50},{0,9,196},
+        {129,7,11},{0,8,98},{0,8,34},{0,9,164},{0,8,2},{0,8,130},
+        {0,8,66},{0,9,228},{128,7,7},{0,8,90},{0,8,26},{0,9,148},
+        {132,7,67},{0,8,122},{0,8,58},{0,9,212},{130,7,19},{0,8,106},
+        {0,8,42},{0,9,180},{0,8,10},{0,8,138},{0,8,74},{0,9,244},
+        {128,7,5},{0,8,86},{0,8,22},{65,8,0},{131,7,51},{0,8,118},
+        {0,8,54},{0,9,204},{129,7,15},{0,8,102},{0,8,38},{0,9,172},
+        {0,8,6},{0,8,134},{0,8,70},{0,9,236},{128,7,9},{0,8,94},
+        {0,8,30},{0,9,156},{132,7,99},{0,8,126},{0,8,62},{0,9,220},
+        {130,7,27},{0,8,110},{0,8,46},{0,9,188},{0,8,14},{0,8,142},
+        {0,8,78},{0,9,252},{96,7,0},{0,8,81},{0,8,17},{133,8,131},
+        {130,7,31},{0,8,113},{0,8,49},{0,9,194},{128,7,10},{0,8,97},
+        {0,8,33},{0,9,162},{0,8,1},{0,8,129},{0,8,65},{0,9,226},
+        {128,7,6},{0,8,89},{0,8,25},{0,9,146},{131,7,59},{0,8,121},
+        {0,8,57},{0,9,210},{129,7,17},{0,8,105},{0,8,41},{0,9,178},
+        {0,8,9},{0,8,137},{0,8,73},{0,9,242},{128,7,4},{0,8,85},
+        {0,8,21},{144,8,3},{131,7,43},{0,8,117},{0,8,53},{0,9,202},
+        {129,7,13},{0,8,101},{0,8,37},{0,9,170},{0,8,5},{0,8,133},
+        {0,8,69},{0,9,234},{128,7,8},{0,8,93},{0,8,29},{0,9,154},
+        {132,7,83},{0,8,125},{0,8,61},{0,9,218},{130,7,23},{0,8,109},
+        {0,8,45},{0,9,186},{0,8,13},{0,8,141},{0,8,77},{0,9,250},
+        {128,7,3},{0,8,83},{0,8,19},{133,8,195},{131,7,35},{0,8,115},
+        {0,8,51},{0,9,198},{129,7,11},{0,8,99},{0,8,35},{0,9,166},
+        {0,8,3},{0,8,131},{0,8,67},{0,9,230},{128,7,7},{0,8,91},
+        {0,8,27},{0,9,150},{132,7,67},{0,8,123},{0,8,59},{0,9,214},
+        {130,7,19},{0,8,107},{0,8,43},{0,9,182},{0,8,11},{0,8,139},
+        {0,8,75},{0,9,246},{128,7,5},{0,8,87},{0,8,23},{77,8,0},
+        {131,7,51},{0,8,119},{0,8,55},{0,9,206},{129,7,15},{0,8,103},
+        {0,8,39},{0,9,174},{0,8,7},{0,8,135},{0,8,71},{0,9,238},
+        {128,7,9},{0,8,95},{0,8,31},{0,9,158},{132,7,99},{0,8,127},
+        {0,8,63},{0,9,222},{130,7,27},{0,8,111},{0,8,47},{0,9,190},
+        {0,8,15},{0,8,143},{0,8,79},{0,9,254},{96,7,0},{0,8,80},
+        {0,8,16},{132,8,115},{130,7,31},{0,8,112},{0,8,48},{0,9,193},
+        {128,7,10},{0,8,96},{0,8,32},{0,9,161},{0,8,0},{0,8,128},
+        {0,8,64},{0,9,225},{128,7,6},{0,8,88},{0,8,24},{0,9,145},
+        {131,7,59},{0,8,120},{0,8,56},{0,9,209},{129,7,17},{0,8,104},
+        {0,8,40},{0,9,177},{0,8,8},{0,8,136},{0,8,72},{0,9,241},
+        {128,7,4},{0,8,84},{0,8,20},{133,8,227},{131,7,43},{0,8,116},
+        {0,8,52},{0,9,201},{129,7,13},{0,8,100},{0,8,36},{0,9,169},
+        {0,8,4},{0,8,132},{0,8,68},{0,9,233},{128,7,8},{0,8,92},
+        {0,8,28},{0,9,153},{132,7,83},{0,8,124},{0,8,60},{0,9,217},
+        {130,7,23},{0,8,108},{0,8,44},{0,9,185},{0,8,12},{0,8,140},
+        {0,8,76},{0,9,249},{128,7,3},{0,8,82},{0,8,18},{133,8,163},
+        {131,7,35},{0,8,114},{0,8,50},{0,9,197},{129,7,11},{0,8,98},
+        {0,8,34},{0,9,165},{0,8,2},{0,8,130},{0,8,66},{0,9,229},
+        {128,7,7},{0,8,90},{0,8,26},{0,9,149},{132,7,67},{0,8,122},
+        {0,8,58},{0,9,213},{130,7,19},{0,8,106},{0,8,42},{0,9,181},
+        {0,8,10},{0,8,138},{0,8,74},{0,9,245},{128,7,5},{0,8,86},
+        {0,8,22},{65,8,0},{131,7,51},{0,8,118},{0,8,54},{0,9,205},
+        {129,7,15},{0,8,102},{0,8,38},{0,9,173},{0,8,6},{0,8,134},
+        {0,8,70},{0,9,237},{128,7,9},{0,8,94},{0,8,30},{0,9,157},
+        {132,7,99},{0,8,126},{0,8,62},{0,9,221},{130,7,27},{0,8,110},
+        {0,8,46},{0,9,189},{0,8,14},{0,8,142},{0,8,78},{0,9,253},
+        {96,7,0},{0,8,81},{0,8,17},{133,8,131},{130,7,31},{0,8,113},
+        {0,8,49},{0,9,195},{128,7,10},{0,8,97},{0,8,33},{0,9,163},
+        {0,8,1},{0,8,129},{0,8,65},{0,9,227},{128,7,6},{0,8,89},
+        {0,8,25},{0,9,147},{131,7,59},{0,8,121},{0,8,57},{0,9,211},
+        {129,7,17},{0,8,105},{0,8,41},{0,9,179},{0,8,9},{0,8,137},
+        {0,8,73},{0,9,243},{128,7,4},{0,8,85},{0,8,21},{144,8,3},
+        {131,7,43},{0,8,117},{0,8,53},{0,9,203},{129,7,13},{0,8,101},
+        {0,8,37},{0,9,171},{0,8,5},{0,8,133},{0,8,69},{0,9,235},
+        {128,7,8},{0,8,93},{0,8,29},{0,9,155},{132,7,83},{0,8,125},
+        {0,8,61},{0,9,219},{130,7,23},{0,8,109},{0,8,45},{0,9,187},
+        {0,8,13},{0,8,141},{0,8,77},{0,9,251},{128,7,3},{0,8,83},
+        {0,8,19},{133,8,195},{131,7,35},{0,8,115},{0,8,51},{0,9,199},
+        {129,7,11},{0,8,99},{0,8,35},{0,9,167},{0,8,3},{0,8,131},
+        {0,8,67},{0,9,231},{128,7,7},{0,8,91},{0,8,27},{0,9,151},
+        {132,7,67},{0,8,123},{0,8,59},{0,9,215},{130,7,19},{0,8,107},
+        {0,8,43},{0,9,183},{0,8,11},{0,8,139},{0,8,75},{0,9,247},
+        {128,7,5},{0,8,87},{0,8,23},{77,8,0},{131,7,51},{0,8,119},
+        {0,8,55},{0,9,207},{129,7,15},{0,8,103},{0,8,39},{0,9,175},
+        {0,8,7},{0,8,135},{0,8,71},{0,9,239},{128,7,9},{0,8,95},
+        {0,8,31},{0,9,159},{132,7,99},{0,8,127},{0,8,63},{0,9,223},
+        {130,7,27},{0,8,111},{0,8,47},{0,9,191},{0,8,15},{0,8,143},
+        {0,8,79},{0,9,255}
+    };
+
+    static const code distfix[32] = {
+        {128,5,1},{135,5,257},{131,5,17},{139,5,4097},{129,5,5},
+        {137,5,1025},{133,5,65},{141,5,16385},{128,5,3},{136,5,513},
+        {132,5,33},{140,5,8193},{130,5,9},{138,5,2049},{134,5,129},
+        {142,5,32769},{128,5,2},{135,5,385},{131,5,25},{139,5,6145},
+        {129,5,7},{137,5,1537},{133,5,97},{141,5,24577},{128,5,4},
+        {136,5,769},{132,5,49},{140,5,12289},{130,5,13},{138,5,3073},
+        {134,5,193},{142,5,49153}
+    };
diff --git a/compat/zlib/contrib/infback9/inflate9.h b/compat/zlib/contrib/infback9/inflate9.h
new file mode 100644
index 0000000..ee9a793
--- /dev/null
+++ b/compat/zlib/contrib/infback9/inflate9.h
@@ -0,0 +1,47 @@
+/* inflate9.h -- internal inflate state definition
+ * Copyright (C) 1995-2003 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+   part of the implementation of the compression library and is
+   subject to change. Applications should only use zlib.h.
+ */
+
+/* Possible inflate modes between inflate() calls */
+typedef enum {
+        TYPE,       /* i: waiting for type bits, including last-flag bit */
+        STORED,     /* i: waiting for stored size (length and complement) */
+        TABLE,      /* i: waiting for dynamic block table lengths */
+            LEN,        /* i: waiting for length/lit code */
+    DONE,       /* finished check, done -- remain here until reset */
+    BAD         /* got a data error -- remain here until reset */
+} inflate_mode;
+
+/*
+    State transitions between above modes -
+
+    (most modes can go to the BAD mode -- not shown for clarity)
+
+    Read deflate blocks:
+            TYPE -> STORED or TABLE or LEN or DONE
+            STORED -> TYPE
+            TABLE -> LENLENS -> CODELENS -> LEN
+    Read deflate codes:
+                LEN -> LEN or TYPE
+ */
+
+/* state maintained between inflate() calls.  Approximately 7K bytes. */
+struct inflate_state {
+        /* sliding window */
+    unsigned char FAR *window;  /* allocated sliding window, if needed */
+        /* dynamic table building */
+    unsigned ncode;             /* number of code length code lengths */
+    unsigned nlen;              /* number of length code lengths */
+    unsigned ndist;             /* number of distance code lengths */
+    unsigned have;              /* number of code lengths in lens[] */
+    code FAR *next;             /* next available space in codes[] */
+    unsigned short lens[320];   /* temporary storage for code lengths */
+    unsigned short work[288];   /* work area for code table building */
+    code codes[ENOUGH];         /* space for code tables */
+};
diff --git a/compat/zlib/contrib/infback9/inftree9.c b/compat/zlib/contrib/infback9/inftree9.c
new file mode 100644
index 0000000..4a73ad2
--- /dev/null
+++ b/compat/zlib/contrib/infback9/inftree9.c
@@ -0,0 +1,324 @@
+/* inftree9.c -- generate Huffman trees for efficient decoding
+ * Copyright (C) 1995-2013 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+#include "zutil.h"
+#include "inftree9.h"
+
+#define MAXBITS 15
+
+const char inflate9_copyright[] =
+   " inflate9 1.2.8 Copyright 1995-2013 Mark Adler ";
+/*
+  If you use the zlib library in a product, an acknowledgment is welcome
+  in the documentation of your product. If for some reason you cannot
+  include such an acknowledgment, I would appreciate that you keep this
+  copyright string in the executable of your product.
+ */
+
+/*
+   Build a set of tables to decode the provided canonical Huffman code.
+   The code lengths are lens[0..codes-1].  The result starts at *table,
+   whose indices are 0..2^bits-1.  work is a writable array of at least
+   lens shorts, which is used as a work area.  type is the type of code
+   to be generated, CODES, LENS, or DISTS.  On return, zero is success,
+   -1 is an invalid code, and +1 means that ENOUGH isn't enough.  table
+   on return points to the next available entry's address.  bits is the
+   requested root table index bits, and on return it is the actual root
+   table index bits.  It will differ if the request is greater than the
+   longest code or if it is less than the shortest code.
+ */
+int inflate_table9(type, lens, codes, table, bits, work)
+codetype type;
+unsigned short FAR *lens;
+unsigned codes;
+code FAR * FAR *table;
+unsigned FAR *bits;
+unsigned short FAR *work;
+{
+    unsigned len;               /* a code's length in bits */
+    unsigned sym;               /* index of code symbols */
+    unsigned min, max;          /* minimum and maximum code lengths */
+    unsigned root;              /* number of index bits for root table */
+    unsigned curr;              /* number of index bits for current table */
+    unsigned drop;              /* code bits to drop for sub-table */
+    int left;                   /* number of prefix codes available */
+    unsigned used;              /* code entries in table used */
+    unsigned huff;              /* Huffman code */
+    unsigned incr;              /* for incrementing code, index */
+    unsigned fill;              /* index for replicating entries */
+    unsigned low;               /* low bits for current root entry */
+    unsigned mask;              /* mask for low root bits */
+    code this;                  /* table entry for duplication */
+    code FAR *next;             /* next available space in table */
+    const unsigned short FAR *base;     /* base value table to use */
+    const unsigned short FAR *extra;    /* extra bits table to use */
+    int end;                    /* use base and extra for symbol > end */
+    unsigned short count[MAXBITS+1];    /* number of codes of each length */
+    unsigned short offs[MAXBITS+1];     /* offsets in table for each length */
+    static const unsigned short lbase[31] = { /* Length codes 257..285 base */
+        3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17,
+        19, 23, 27, 31, 35, 43, 51, 59, 67, 83, 99, 115,
+        131, 163, 195, 227, 3, 0, 0};
+    static const unsigned short lext[31] = { /* Length codes 257..285 extra */
+        128, 128, 128, 128, 128, 128, 128, 128, 129, 129, 129, 129,
+        130, 130, 130, 130, 131, 131, 131, 131, 132, 132, 132, 132,
+        133, 133, 133, 133, 144, 72, 78};
+    static const unsigned short dbase[32] = { /* Distance codes 0..31 base */
+        1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49,
+        65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073,
+        4097, 6145, 8193, 12289, 16385, 24577, 32769, 49153};
+    static const unsigned short dext[32] = { /* Distance codes 0..31 extra */
+        128, 128, 128, 128, 129, 129, 130, 130, 131, 131, 132, 132,
+        133, 133, 134, 134, 135, 135, 136, 136, 137, 137, 138, 138,
+        139, 139, 140, 140, 141, 141, 142, 142};
+
+    /*
+       Process a set of code lengths to create a canonical Huffman code.  The
+       code lengths are lens[0..codes-1].  Each length corresponds to the
+       symbols 0..codes-1.  The Huffman code is generated by first sorting the
+       symbols by length from short to long, and retaining the symbol order
+       for codes with equal lengths.  Then the code starts with all zero bits
+       for the first code of the shortest length, and the codes are integer
+       increments for the same length, and zeros are appended as the length
+       increases.  For the deflate format, these bits are stored backwards
+       from their more natural integer increment ordering, and so when the
+       decoding tables are built in the large loop below, the integer codes
+       are incremented backwards.
+
+       This routine assumes, but does not check, that all of the entries in
+       lens[] are in the range 0..MAXBITS.  The caller must assure this.
+       1..MAXBITS is interpreted as that code length.  zero means that that
+       symbol does not occur in this code.
+
+       The codes are sorted by computing a count of codes for each length,
+       creating from that a table of starting indices for each length in the
+       sorted table, and then entering the symbols in order in the sorted
+       table.  The sorted table is work[], with that space being provided by
+       the caller.
+
+       The length counts are used for other purposes as well, i.e. finding
+       the minimum and maximum length codes, determining if there are any
+       codes at all, checking for a valid set of lengths, and looking ahead
+       at length counts to determine sub-table sizes when building the
+       decoding tables.
+     */
+
+    /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */
+    for (len = 0; len <= MAXBITS; len++)
+        count[len] = 0;
+    for (sym = 0; sym < codes; sym++)
+        count[lens[sym]]++;
+
+    /* bound code lengths, force root to be within code lengths */
+    root = *bits;
+    for (max = MAXBITS; max >= 1; max--)
+        if (count[max] != 0) break;
+    if (root > max) root = max;
+    if (max == 0) return -1;            /* no codes! */
+    for (min = 1; min <= MAXBITS; min++)
+        if (count[min] != 0) break;
+    if (root < min) root = min;
+
+    /* check for an over-subscribed or incomplete set of lengths */
+    left = 1;
+    for (len = 1; len <= MAXBITS; len++) {
+        left <<= 1;
+        left -= count[len];
+        if (left < 0) return -1;        /* over-subscribed */
+    }
+    if (left > 0 && (type == CODES || max != 1))
+        return -1;                      /* incomplete set */
+
+    /* generate offsets into symbol table for each length for sorting */
+    offs[1] = 0;
+    for (len = 1; len < MAXBITS; len++)
+        offs[len + 1] = offs[len] + count[len];
+
+    /* sort symbols by length, by symbol order within each length */
+    for (sym = 0; sym < codes; sym++)
+        if (lens[sym] != 0) work[offs[lens[sym]]++] = (unsigned short)sym;
+
+    /*
+       Create and fill in decoding tables.  In this loop, the table being
+       filled is at next and has curr index bits.  The code being used is huff
+       with length len.  That code is converted to an index by dropping drop
+       bits off of the bottom.  For codes where len is less than drop + curr,
+       those top drop + curr - len bits are incremented through all values to
+       fill the table with replicated entries.
+
+       root is the number of index bits for the root table.  When len exceeds
+       root, sub-tables are created pointed to by the root entry with an index
+       of the low root bits of huff.  This is saved in low to check for when a
+       new sub-table should be started.  drop is zero when the root table is
+       being filled, and drop is root when sub-tables are being filled.
+
+       When a new sub-table is needed, it is necessary to look ahead in the
+       code lengths to determine what size sub-table is needed.  The length
+       counts are used for this, and so count[] is decremented as codes are
+       entered in the tables.
+
+       used keeps track of how many table entries have been allocated from the
+       provided *table space.  It is checked for LENS and DIST tables against
+       the constants ENOUGH_LENS and ENOUGH_DISTS to guard against changes in
+       the initial root table size constants.  See the comments in inftree9.h
+       for more information.
+
+       sym increments through all symbols, and the loop terminates when
+       all codes of length max, i.e. all codes, have been processed.  This
+       routine permits incomplete codes, so another loop after this one fills
+       in the rest of the decoding tables with invalid code markers.
+     */
+
+    /* set up for code type */
+    switch (type) {
+    case CODES:
+        base = extra = work;    /* dummy value--not used */
+        end = 19;
+        break;
+    case LENS:
+        base = lbase;
+        base -= 257;
+        extra = lext;
+        extra -= 257;
+        end = 256;
+        break;
+    default:            /* DISTS */
+        base = dbase;
+        extra = dext;
+        end = -1;
+    }
+
+    /* initialize state for loop */
+    huff = 0;                   /* starting code */
+    sym = 0;                    /* starting code symbol */
+    len = min;                  /* starting code length */
+    next = *table;              /* current table to fill in */
+    curr = root;                /* current table index bits */
+    drop = 0;                   /* current bits to drop from code for index */
+    low = (unsigned)(-1);       /* trigger new sub-table when len > root */
+    used = 1U << root;          /* use root table entries */
+    mask = used - 1;            /* mask for comparing low */
+
+    /* check available table space */
+    if ((type == LENS && used >= ENOUGH_LENS) ||
+        (type == DISTS && used >= ENOUGH_DISTS))
+        return 1;
+
+    /* process all codes and make table entries */
+    for (;;) {
+        /* create table entry */
+        this.bits = (unsigned char)(len - drop);
+        if ((int)(work[sym]) < end) {
+            this.op = (unsigned char)0;
+            this.val = work[sym];
+        }
+        else if ((int)(work[sym]) > end) {
+            this.op = (unsigned char)(extra[work[sym]]);
+            this.val = base[work[sym]];
+        }
+        else {
+            this.op = (unsigned char)(32 + 64);         /* end of block */
+            this.val = 0;
+        }
+
+        /* replicate for those indices with low len bits equal to huff */
+        incr = 1U << (len - drop);
+        fill = 1U << curr;
+        do {
+            fill -= incr;
+            next[(huff >> drop) + fill] = this;
+        } while (fill != 0);
+
+        /* backwards increment the len-bit code huff */
+        incr = 1U << (len - 1);
+        while (huff & incr)
+            incr >>= 1;
+        if (incr != 0) {
+            huff &= incr - 1;
+            huff += incr;
+        }
+        else
+            huff = 0;
+
+        /* go to next symbol, update count, len */
+        sym++;
+        if (--(count[len]) == 0) {
+            if (len == max) break;
+            len = lens[work[sym]];
+        }
+
+        /* create new sub-table if needed */
+        if (len > root && (huff & mask) != low) {
+            /* if first time, transition to sub-tables */
+            if (drop == 0)
+                drop = root;
+
+            /* increment past last table */
+            next += 1U << curr;
+
+            /* determine length of next table */
+            curr = len - drop;
+            left = (int)(1 << curr);
+            while (curr + drop < max) {
+                left -= count[curr + drop];
+                if (left <= 0) break;
+                curr++;
+                left <<= 1;
+            }
+
+            /* check for enough space */
+            used += 1U << curr;
+            if ((type == LENS && used >= ENOUGH_LENS) ||
+                (type == DISTS && used >= ENOUGH_DISTS))
+                return 1;
+
+            /* point entry in root table to sub-table */
+            low = huff & mask;
+            (*table)[low].op = (unsigned char)curr;
+            (*table)[low].bits = (unsigned char)root;
+            (*table)[low].val = (unsigned short)(next - *table);
+        }
+    }
+
+    /*
+       Fill in rest of table for incomplete codes.  This loop is similar to the
+       loop above in incrementing huff for table indices.  It is assumed that
+       len is equal to curr + drop, so there is no loop needed to increment
+       through high index bits.  When the current sub-table is filled, the loop
+       drops back to the root table to fill in any remaining entries there.
+     */
+    this.op = (unsigned char)64;                /* invalid code marker */
+    this.bits = (unsigned char)(len - drop);
+    this.val = (unsigned short)0;
+    while (huff != 0) {
+        /* when done with sub-table, drop back to root table */
+        if (drop != 0 && (huff & mask) != low) {
+            drop = 0;
+            len = root;
+            next = *table;
+            curr = root;
+            this.bits = (unsigned char)len;
+        }
+
+        /* put invalid code marker in table */
+        next[huff >> drop] = this;
+
+        /* backwards increment the len-bit code huff */
+        incr = 1U << (len - 1);
+        while (huff & incr)
+            incr >>= 1;
+        if (incr != 0) {
+            huff &= incr - 1;
+            huff += incr;
+        }
+        else
+            huff = 0;
+    }
+
+    /* set return parameters */
+    *table += used;
+    *bits = root;
+    return 0;
+}
diff --git a/compat/zlib/contrib/infback9/inftree9.h b/compat/zlib/contrib/infback9/inftree9.h
new file mode 100644
index 0000000..5ab21f0
--- /dev/null
+++ b/compat/zlib/contrib/infback9/inftree9.h
@@ -0,0 +1,61 @@
+/* inftree9.h -- header to use inftree9.c
+ * Copyright (C) 1995-2008 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+   part of the implementation of the compression library and is
+   subject to change. Applications should only use zlib.h.
+ */
+
+/* Structure for decoding tables.  Each entry provides either the
+   information needed to do the operation requested by the code that
+   indexed that table entry, or it provides a pointer to another
+   table that indexes more bits of the code.  op indicates whether
+   the entry is a pointer to another table, a literal, a length or
+   distance, an end-of-block, or an invalid code.  For a table
+   pointer, the low four bits of op is the number of index bits of
+   that table.  For a length or distance, the low four bits of op
+   is the number of extra bits to get after the code.  bits is
+   the number of bits in this code or part of the code to drop off
+   of the bit buffer.  val is the actual byte to output in the case
+   of a literal, the base length or distance, or the offset from
+   the current table to the next table.  Each entry is four bytes. */
+typedef struct {
+    unsigned char op;           /* operation, extra bits, table bits */
+    unsigned char bits;         /* bits in this part of the code */
+    unsigned short val;         /* offset in table or code value */
+} code;
+
+/* op values as set by inflate_table():
+    00000000 - literal
+    0000tttt - table link, tttt != 0 is the number of table index bits
+    100eeeee - length or distance, eeee is the number of extra bits
+    01100000 - end of block
+    01000000 - invalid code
+ */
+
+/* Maximum size of the dynamic table.  The maximum number of code structures is
+   1446, which is the sum of 852 for literal/length codes and 594 for distance
+   codes.  These values were found by exhaustive searches using the program
+   examples/enough.c found in the zlib distribtution.  The arguments to that
+   program are the number of symbols, the initial root table size, and the
+   maximum bit length of a code.  "enough 286 9 15" for literal/length codes
+   returns returns 852, and "enough 32 6 15" for distance codes returns 594.
+   The initial root table size (9 or 6) is found in the fifth argument of the
+   inflate_table() calls in infback9.c.  If the root table size is changed,
+   then these maximum sizes would be need to be recalculated and updated. */
+#define ENOUGH_LENS 852
+#define ENOUGH_DISTS 594
+#define ENOUGH (ENOUGH_LENS+ENOUGH_DISTS)
+
+/* Type of code to build for inflate_table9() */
+typedef enum {
+    CODES,
+    LENS,
+    DISTS
+} codetype;
+
+extern int inflate_table9 OF((codetype type, unsigned short FAR *lens,
+                             unsigned codes, code FAR * FAR *table,
+                             unsigned FAR *bits, unsigned short FAR *work));
diff --git a/compat/zlib/contrib/inflate86/inffas86.c b/compat/zlib/contrib/inflate86/inffas86.c
new file mode 100644
index 0000000..7292f67
--- /dev/null
+++ b/compat/zlib/contrib/inflate86/inffas86.c
@@ -0,0 +1,1157 @@
+/* inffas86.c is a hand tuned assembler version of
+ *
+ * inffast.c -- fast decoding
+ * Copyright (C) 1995-2003 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ *
+ * Copyright (C) 2003 Chris Anderson <christop@charm.net>
+ * Please use the copyright conditions above.
+ *
+ * Dec-29-2003 -- I added AMD64 inflate asm support.  This version is also
+ * slightly quicker on x86 systems because, instead of using rep movsb to copy
+ * data, it uses rep movsw, which moves data in 2-byte chunks instead of single
+ * bytes.  I've tested the AMD64 code on a Fedora Core 1 + the x86_64 updates
+ * from http://fedora.linux.duke.edu/fc1_x86_64
+ * which is running on an Athlon 64 3000+ / Gigabyte GA-K8VT800M system with
+ * 1GB ram.  The 64-bit version is about 4% faster than the 32-bit version,
+ * when decompressing mozilla-source-1.3.tar.gz.
+ *
+ * Mar-13-2003 -- Most of this is derived from inffast.S which is derived from
+ * the gcc -S output of zlib-1.2.0/inffast.c.  Zlib-1.2.0 is in beta release at
+ * the moment.  I have successfully compiled and tested this code with gcc2.96,
+ * gcc3.2, icc5.0, msvc6.0.  It is very close to the speed of inffast.S
+ * compiled with gcc -DNO_MMX, but inffast.S is still faster on the P3 with MMX
+ * enabled.  I will attempt to merge the MMX code into this version.  Newer
+ * versions of this and inffast.S can be found at
+ * http://www.eetbeetee.com/zlib/ and http://www.charm.net/~christop/zlib/
+ */
+
+#include "zutil.h"
+#include "inftrees.h"
+#include "inflate.h"
+#include "inffast.h"
+
+/* Mark Adler's comments from inffast.c: */
+
+/*
+   Decode literal, length, and distance codes and write out the resulting
+   literal and match bytes until either not enough input or output is
+   available, an end-of-block is encountered, or a data error is encountered.
+   When large enough input and output buffers are supplied to inflate(), for
+   example, a 16K input buffer and a 64K output buffer, more than 95% of the
+   inflate execution time is spent in this routine.
+
+   Entry assumptions:
+
+        state->mode == LEN
+        strm->avail_in >= 6
+        strm->avail_out >= 258
+        start >= strm->avail_out
+        state->bits < 8
+
+   On return, state->mode is one of:
+
+        LEN -- ran out of enough output space or enough available input
+        TYPE -- reached end of block code, inflate() to interpret next block
+        BAD -- error in block data
+
+   Notes:
+
+    - The maximum input bits used by a length/distance pair is 15 bits for the
+      length code, 5 bits for the length extra, 15 bits for the distance code,
+      and 13 bits for the distance extra.  This totals 48 bits, or six bytes.
+      Therefore if strm->avail_in >= 6, then there is enough input to avoid
+      checking for available input while decoding.
+
+    - The maximum bytes that a single length/distance pair can output is 258
+      bytes, which is the maximum length that can be coded.  inflate_fast()
+      requires strm->avail_out >= 258 for each loop to avoid checking for
+      output space.
+ */
+void inflate_fast(strm, start)
+z_streamp strm;
+unsigned start;         /* inflate()'s starting value for strm->avail_out */
+{
+    struct inflate_state FAR *state;
+    struct inffast_ar {
+/* 64   32                               x86  x86_64 */
+/* ar offset                              register */
+/*  0    0 */ void *esp;                /* esp save */
+/*  8    4 */ void *ebp;                /* ebp save */
+/* 16    8 */ unsigned char FAR *in;    /* esi rsi  local strm->next_in */
+/* 24   12 */ unsigned char FAR *last;  /*     r9   while in < last */
+/* 32   16 */ unsigned char FAR *out;   /* edi rdi  local strm->next_out */
+/* 40   20 */ unsigned char FAR *beg;   /*          inflate()'s init next_out */
+/* 48   24 */ unsigned char FAR *end;   /*     r10  while out < end */
+/* 56   28 */ unsigned char FAR *window;/*          size of window, wsize!=0 */
+/* 64   32 */ code const FAR *lcode;    /* ebp rbp  local strm->lencode */
+/* 72   36 */ code const FAR *dcode;    /*     r11  local strm->distcode */
+/* 80   40 */ unsigned long hold;       /* edx rdx  local strm->hold */
+/* 88   44 */ unsigned bits;            /* ebx rbx  local strm->bits */
+/* 92   48 */ unsigned wsize;           /*          window size */
+/* 96   52 */ unsigned write;           /*          window write index */
+/*100   56 */ unsigned lmask;           /*     r12  mask for lcode */
+/*104   60 */ unsigned dmask;           /*     r13  mask for dcode */
+/*108   64 */ unsigned len;             /*     r14  match length */
+/*112   68 */ unsigned dist;            /*     r15  match distance */
+/*116   72 */ unsigned status;          /*          set when state chng*/
+    } ar;
+
+#if defined( __GNUC__ ) && defined( __amd64__ ) && ! defined( __i386 )
+#define PAD_AVAIL_IN 6
+#define PAD_AVAIL_OUT 258
+#else
+#define PAD_AVAIL_IN 5
+#define PAD_AVAIL_OUT 257
+#endif
+
+    /* copy state to local variables */
+    state = (struct inflate_state FAR *)strm->state;
+    ar.in = strm->next_in;
+    ar.last = ar.in + (strm->avail_in - PAD_AVAIL_IN);
+    ar.out = strm->next_out;
+    ar.beg = ar.out - (start - strm->avail_out);
+    ar.end = ar.out + (strm->avail_out - PAD_AVAIL_OUT);
+    ar.wsize = state->wsize;
+    ar.write = state->wnext;
+    ar.window = state->window;
+    ar.hold = state->hold;
+    ar.bits = state->bits;
+    ar.lcode = state->lencode;
+    ar.dcode = state->distcode;
+    ar.lmask = (1U << state->lenbits) - 1;
+    ar.dmask = (1U << state->distbits) - 1;
+
+    /* decode literals and length/distances until end-of-block or not enough
+       input data or output space */
+
+    /* align in on 1/2 hold size boundary */
+    while (((unsigned long)(void *)ar.in & (sizeof(ar.hold) / 2 - 1)) != 0) {
+        ar.hold += (unsigned long)*ar.in++ << ar.bits;
+        ar.bits += 8;
+    }
+
+#if defined( __GNUC__ ) && defined( __amd64__ ) && ! defined( __i386 )
+    __asm__ __volatile__ (
+"        leaq    %0, %%rax\n"
+"        movq    %%rbp, 8(%%rax)\n"       /* save regs rbp and rsp */
+"        movq    %%rsp, (%%rax)\n"
+"        movq    %%rax, %%rsp\n"          /* make rsp point to &ar */
+"        movq    16(%%rsp), %%rsi\n"      /* rsi  = in */
+"        movq    32(%%rsp), %%rdi\n"      /* rdi  = out */
+"        movq    24(%%rsp), %%r9\n"       /* r9   = last */
+"        movq    48(%%rsp), %%r10\n"      /* r10  = end */
+"        movq    64(%%rsp), %%rbp\n"      /* rbp  = lcode */
+"        movq    72(%%rsp), %%r11\n"      /* r11  = dcode */
+"        movq    80(%%rsp), %%rdx\n"      /* rdx  = hold */
+"        movl    88(%%rsp), %%ebx\n"      /* ebx  = bits */
+"        movl    100(%%rsp), %%r12d\n"    /* r12d = lmask */
+"        movl    104(%%rsp), %%r13d\n"    /* r13d = dmask */
+                                          /* r14d = len */
+                                          /* r15d = dist */
+"        cld\n"
+"        cmpq    %%rdi, %%r10\n"
+"        je      .L_one_time\n"           /* if only one decode left */
+"        cmpq    %%rsi, %%r9\n"
+"        je      .L_one_time\n"
+"        jmp     .L_do_loop\n"
+
+".L_one_time:\n"
+"        movq    %%r12, %%r8\n"           /* r8 = lmask */
+"        cmpb    $32, %%bl\n"
+"        ja      .L_get_length_code_one_time\n"
+
+"        lodsl\n"                         /* eax = *(uint *)in++ */
+"        movb    %%bl, %%cl\n"            /* cl = bits, needs it for shifting */
+"        addb    $32, %%bl\n"             /* bits += 32 */
+"        shlq    %%cl, %%rax\n"
+"        orq     %%rax, %%rdx\n"          /* hold |= *((uint *)in)++ << bits */
+"        jmp     .L_get_length_code_one_time\n"
+
+".align 32,0x90\n"
+".L_while_test:\n"
+"        cmpq    %%rdi, %%r10\n"
+"        jbe     .L_break_loop\n"
+"        cmpq    %%rsi, %%r9\n"
+"        jbe     .L_break_loop\n"
+
+".L_do_loop:\n"
+"        movq    %%r12, %%r8\n"           /* r8 = lmask */
+"        cmpb    $32, %%bl\n"
+"        ja      .L_get_length_code\n"    /* if (32 < bits) */
+
+"        lodsl\n"                         /* eax = *(uint *)in++ */
+"        movb    %%bl, %%cl\n"            /* cl = bits, needs it for shifting */
+"        addb    $32, %%bl\n"             /* bits += 32 */
+"        shlq    %%cl, %%rax\n"
+"        orq     %%rax, %%rdx\n"          /* hold |= *((uint *)in)++ << bits */
+
+".L_get_length_code:\n"
+"        andq    %%rdx, %%r8\n"            /* r8 &= hold */
+"        movl    (%%rbp,%%r8,4), %%eax\n"  /* eax = lcode[hold & lmask] */
+
+"        movb    %%ah, %%cl\n"            /* cl = this.bits */
+"        subb    %%ah, %%bl\n"            /* bits -= this.bits */
+"        shrq    %%cl, %%rdx\n"           /* hold >>= this.bits */
+
+"        testb   %%al, %%al\n"
+"        jnz     .L_test_for_length_base\n" /* if (op != 0) 45.7% */
+
+"        movq    %%r12, %%r8\n"            /* r8 = lmask */
+"        shrl    $16, %%eax\n"            /* output this.val char */
+"        stosb\n"
+
+".L_get_length_code_one_time:\n"
+"        andq    %%rdx, %%r8\n"            /* r8 &= hold */
+"        movl    (%%rbp,%%r8,4), %%eax\n" /* eax = lcode[hold & lmask] */
+
+".L_dolen:\n"
+"        movb    %%ah, %%cl\n"            /* cl = this.bits */
+"        subb    %%ah, %%bl\n"            /* bits -= this.bits */
+"        shrq    %%cl, %%rdx\n"           /* hold >>= this.bits */
+
+"        testb   %%al, %%al\n"
+"        jnz     .L_test_for_length_base\n" /* if (op != 0) 45.7% */
+
+"        shrl    $16, %%eax\n"            /* output this.val char */
+"        stosb\n"
+"        jmp     .L_while_test\n"
+
+".align 32,0x90\n"
+".L_test_for_length_base:\n"
+"        movl    %%eax, %%r14d\n"         /* len = this */
+"        shrl    $16, %%r14d\n"           /* len = this.val */
+"        movb    %%al, %%cl\n"
+
+"        testb   $16, %%al\n"
+"        jz      .L_test_for_second_level_length\n" /* if ((op & 16) == 0) 8% */
+"        andb    $15, %%cl\n"             /* op &= 15 */
+"        jz      .L_decode_distance\n"    /* if (!op) */
+
+".L_add_bits_to_len:\n"
+"        subb    %%cl, %%bl\n"
+"        xorl    %%eax, %%eax\n"
+"        incl    %%eax\n"
+"        shll    %%cl, %%eax\n"
+"        decl    %%eax\n"
+"        andl    %%edx, %%eax\n"          /* eax &= hold */
+"        shrq    %%cl, %%rdx\n"
+"        addl    %%eax, %%r14d\n"         /* len += hold & mask[op] */
+
+".L_decode_distance:\n"
+"        movq    %%r13, %%r8\n"           /* r8 = dmask */
+"        cmpb    $32, %%bl\n"
+"        ja      .L_get_distance_code\n"  /* if (32 < bits) */
+
+"        lodsl\n"                         /* eax = *(uint *)in++ */
+"        movb    %%bl, %%cl\n"            /* cl = bits, needs it for shifting */
+"        addb    $32, %%bl\n"             /* bits += 32 */
+"        shlq    %%cl, %%rax\n"
+"        orq     %%rax, %%rdx\n"          /* hold |= *((uint *)in)++ << bits */
+
+".L_get_distance_code:\n"
+"        andq    %%rdx, %%r8\n"           /* r8 &= hold */
+"        movl    (%%r11,%%r8,4), %%eax\n" /* eax = dcode[hold & dmask] */
+
+".L_dodist:\n"
+"        movl    %%eax, %%r15d\n"         /* dist = this */
+"        shrl    $16, %%r15d\n"           /* dist = this.val */
+"        movb    %%ah, %%cl\n"
+"        subb    %%ah, %%bl\n"            /* bits -= this.bits */
+"        shrq    %%cl, %%rdx\n"           /* hold >>= this.bits */
+"        movb    %%al, %%cl\n"            /* cl = this.op */
+
+"        testb   $16, %%al\n"             /* if ((op & 16) == 0) */
+"        jz      .L_test_for_second_level_dist\n"
+"        andb    $15, %%cl\n"             /* op &= 15 */
+"        jz      .L_check_dist_one\n"
+
+".L_add_bits_to_dist:\n"
+"        subb    %%cl, %%bl\n"
+"        xorl    %%eax, %%eax\n"
+"        incl    %%eax\n"
+"        shll    %%cl, %%eax\n"
+"        decl    %%eax\n"                 /* (1 << op) - 1 */
+"        andl    %%edx, %%eax\n"          /* eax &= hold */
+"        shrq    %%cl, %%rdx\n"
+"        addl    %%eax, %%r15d\n"         /* dist += hold & ((1 << op) - 1) */
+
+".L_check_window:\n"
+"        movq    %%rsi, %%r8\n"           /* save in so from can use it's reg */
+"        movq    %%rdi, %%rax\n"
+"        subq    40(%%rsp), %%rax\n"      /* nbytes = out - beg */
+
+"        cmpl    %%r15d, %%eax\n"
+"        jb      .L_clip_window\n"        /* if (dist > nbytes) 4.2% */
+
+"        movl    %%r14d, %%ecx\n"         /* ecx = len */
+"        movq    %%rdi, %%rsi\n"
+"        subq    %%r15, %%rsi\n"          /* from = out - dist */
+
+"        sarl    %%ecx\n"
+"        jnc     .L_copy_two\n"           /* if len % 2 == 0 */
+
+"        rep     movsw\n"
+"        movb    (%%rsi), %%al\n"
+"        movb    %%al, (%%rdi)\n"
+"        incq    %%rdi\n"
+
+"        movq    %%r8, %%rsi\n"           /* move in back to %rsi, toss from */
+"        jmp     .L_while_test\n"
+
+".L_copy_two:\n"
+"        rep     movsw\n"
+"        movq    %%r8, %%rsi\n"           /* move in back to %rsi, toss from */
+"        jmp     .L_while_test\n"
+
+".align 32,0x90\n"
+".L_check_dist_one:\n"
+"        cmpl    $1, %%r15d\n"            /* if dist 1, is a memset */
+"        jne     .L_check_window\n"
+"        cmpq    %%rdi, 40(%%rsp)\n"      /* if out == beg, outside window */
+"        je      .L_check_window\n"
+
+"        movl    %%r14d, %%ecx\n"         /* ecx = len */
+"        movb    -1(%%rdi), %%al\n"
+"        movb    %%al, %%ah\n"
+
+"        sarl    %%ecx\n"
+"        jnc     .L_set_two\n"
+"        movb    %%al, (%%rdi)\n"
+"        incq    %%rdi\n"
+
+".L_set_two:\n"
+"        rep     stosw\n"
+"        jmp     .L_while_test\n"
+
+".align 32,0x90\n"
+".L_test_for_second_level_length:\n"
+"        testb   $64, %%al\n"
+"        jnz     .L_test_for_end_of_block\n" /* if ((op & 64) != 0) */
+
+"        xorl    %%eax, %%eax\n"
+"        incl    %%eax\n"
+"        shll    %%cl, %%eax\n"
+"        decl    %%eax\n"
+"        andl    %%edx, %%eax\n"         /* eax &= hold */
+"        addl    %%r14d, %%eax\n"        /* eax += len */
+"        movl    (%%rbp,%%rax,4), %%eax\n" /* eax = lcode[val+(hold&mask[op])]*/
+"        jmp     .L_dolen\n"
+
+".align 32,0x90\n"
+".L_test_for_second_level_dist:\n"
+"        testb   $64, %%al\n"
+"        jnz     .L_invalid_distance_code\n" /* if ((op & 64) != 0) */
+
+"        xorl    %%eax, %%eax\n"
+"        incl    %%eax\n"
+"        shll    %%cl, %%eax\n"
+"        decl    %%eax\n"
+"        andl    %%edx, %%eax\n"         /* eax &= hold */
+"        addl    %%r15d, %%eax\n"        /* eax += dist */
+"        movl    (%%r11,%%rax,4), %%eax\n" /* eax = dcode[val+(hold&mask[op])]*/
+"        jmp     .L_dodist\n"
+
+".align 32,0x90\n"
+".L_clip_window:\n"
+"        movl    %%eax, %%ecx\n"         /* ecx = nbytes */
+"        movl    92(%%rsp), %%eax\n"     /* eax = wsize, prepare for dist cmp */
+"        negl    %%ecx\n"                /* nbytes = -nbytes */
+
+"        cmpl    %%r15d, %%eax\n"
+"        jb      .L_invalid_distance_too_far\n" /* if (dist > wsize) */
+
+"        addl    %%r15d, %%ecx\n"         /* nbytes = dist - nbytes */
+"        cmpl    $0, 96(%%rsp)\n"
+"        jne     .L_wrap_around_window\n" /* if (write != 0) */
+
+"        movq    56(%%rsp), %%rsi\n"     /* from  = window */
+"        subl    %%ecx, %%eax\n"         /* eax  -= nbytes */
+"        addq    %%rax, %%rsi\n"         /* from += wsize - nbytes */
+
+"        movl    %%r14d, %%eax\n"        /* eax = len */
+"        cmpl    %%ecx, %%r14d\n"
+"        jbe     .L_do_copy\n"           /* if (nbytes >= len) */
+
+"        subl    %%ecx, %%eax\n"         /* eax -= nbytes */
+"        rep     movsb\n"
+"        movq    %%rdi, %%rsi\n"
+"        subq    %%r15, %%rsi\n"         /* from = &out[ -dist ] */
+"        jmp     .L_do_copy\n"
+
+".align 32,0x90\n"
+".L_wrap_around_window:\n"
+"        movl    96(%%rsp), %%eax\n"     /* eax = write */
+"        cmpl    %%eax, %%ecx\n"
+"        jbe     .L_contiguous_in_window\n" /* if (write >= nbytes) */
+
+"        movl    92(%%rsp), %%esi\n"     /* from  = wsize */
+"        addq    56(%%rsp), %%rsi\n"     /* from += window */
+"        addq    %%rax, %%rsi\n"         /* from += write */
+"        subq    %%rcx, %%rsi\n"         /* from -= nbytes */
+"        subl    %%eax, %%ecx\n"         /* nbytes -= write */
+
+"        movl    %%r14d, %%eax\n"        /* eax = len */
+"        cmpl    %%ecx, %%eax\n"
+"        jbe     .L_do_copy\n"           /* if (nbytes >= len) */
+
+"        subl    %%ecx, %%eax\n"         /* len -= nbytes */
+"        rep     movsb\n"
+"        movq    56(%%rsp), %%rsi\n"     /* from = window */
+"        movl    96(%%rsp), %%ecx\n"     /* nbytes = write */
+"        cmpl    %%ecx, %%eax\n"
+"        jbe     .L_do_copy\n"           /* if (nbytes >= len) */
+
+"        subl    %%ecx, %%eax\n"         /* len -= nbytes */
+"        rep     movsb\n"
+"        movq    %%rdi, %%rsi\n"
+"        subq    %%r15, %%rsi\n"         /* from = out - dist */
+"        jmp     .L_do_copy\n"
+
+".align 32,0x90\n"
+".L_contiguous_in_window:\n"
+"        movq    56(%%rsp), %%rsi\n"     /* rsi = window */
+"        addq    %%rax, %%rsi\n"
+"        subq    %%rcx, %%rsi\n"         /* from += write - nbytes */
+
+"        movl    %%r14d, %%eax\n"        /* eax = len */
+"        cmpl    %%ecx, %%eax\n"
+"        jbe     .L_do_copy\n"           /* if (nbytes >= len) */
+
+"        subl    %%ecx, %%eax\n"         /* len -= nbytes */
+"        rep     movsb\n"
+"        movq    %%rdi, %%rsi\n"
+"        subq    %%r15, %%rsi\n"         /* from = out - dist */
+"        jmp     .L_do_copy\n"           /* if (nbytes >= len) */
+
+".align 32,0x90\n"
+".L_do_copy:\n"
+"        movl    %%eax, %%ecx\n"         /* ecx = len */
+"        rep     movsb\n"
+
+"        movq    %%r8, %%rsi\n"          /* move in back to %esi, toss from */
+"        jmp     .L_while_test\n"
+
+".L_test_for_end_of_block:\n"
+"        testb   $32, %%al\n"
+"        jz      .L_invalid_literal_length_code\n"
+"        movl    $1, 116(%%rsp)\n"
+"        jmp     .L_break_loop_with_status\n"
+
+".L_invalid_literal_length_code:\n"
+"        movl    $2, 116(%%rsp)\n"
+"        jmp     .L_break_loop_with_status\n"
+
+".L_invalid_distance_code:\n"
+"        movl    $3, 116(%%rsp)\n"
+"        jmp     .L_break_loop_with_status\n"
+
+".L_invalid_distance_too_far:\n"
+"        movl    $4, 116(%%rsp)\n"
+"        jmp     .L_break_loop_with_status\n"
+
+".L_break_loop:\n"
+"        movl    $0, 116(%%rsp)\n"
+
+".L_break_loop_with_status:\n"
+/* put in, out, bits, and hold back into ar and pop esp */
+"        movq    %%rsi, 16(%%rsp)\n"     /* in */
+"        movq    %%rdi, 32(%%rsp)\n"     /* out */
+"        movl    %%ebx, 88(%%rsp)\n"     /* bits */
+"        movq    %%rdx, 80(%%rsp)\n"     /* hold */
+"        movq    (%%rsp), %%rax\n"       /* restore rbp and rsp */
+"        movq    8(%%rsp), %%rbp\n"
+"        movq    %%rax, %%rsp\n"
+          :
+          : "m" (ar)
+          : "memory", "%rax", "%rbx", "%rcx", "%rdx", "%rsi", "%rdi",
+            "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15"
+    );
+#elif ( defined( __GNUC__ ) || defined( __ICC ) ) && defined( __i386 )
+    __asm__ __volatile__ (
+"        leal    %0, %%eax\n"
+"        movl    %%esp, (%%eax)\n"        /* save esp, ebp */
+"        movl    %%ebp, 4(%%eax)\n"
+"        movl    %%eax, %%esp\n"
+"        movl    8(%%esp), %%esi\n"       /* esi = in */
+"        movl    16(%%esp), %%edi\n"      /* edi = out */
+"        movl    40(%%esp), %%edx\n"      /* edx = hold */
+"        movl    44(%%esp), %%ebx\n"      /* ebx = bits */
+"        movl    32(%%esp), %%ebp\n"      /* ebp = lcode */
+
+"        cld\n"
+"        jmp     .L_do_loop\n"
+
+".align 32,0x90\n"
+".L_while_test:\n"
+"        cmpl    %%edi, 24(%%esp)\n"      /* out < end */
+"        jbe     .L_break_loop\n"
+"        cmpl    %%esi, 12(%%esp)\n"      /* in < last */
+"        jbe     .L_break_loop\n"
+
+".L_do_loop:\n"
+"        cmpb    $15, %%bl\n"
+"        ja      .L_get_length_code\n"    /* if (15 < bits) */
+
+"        xorl    %%eax, %%eax\n"
+"        lodsw\n"                         /* al = *(ushort *)in++ */
+"        movb    %%bl, %%cl\n"            /* cl = bits, needs it for shifting */
+"        addb    $16, %%bl\n"             /* bits += 16 */
+"        shll    %%cl, %%eax\n"
+"        orl     %%eax, %%edx\n"        /* hold |= *((ushort *)in)++ << bits */
+
+".L_get_length_code:\n"
+"        movl    56(%%esp), %%eax\n"      /* eax = lmask */
+"        andl    %%edx, %%eax\n"          /* eax &= hold */
+"        movl    (%%ebp,%%eax,4), %%eax\n" /* eax = lcode[hold & lmask] */
+
+".L_dolen:\n"
+"        movb    %%ah, %%cl\n"            /* cl = this.bits */
+"        subb    %%ah, %%bl\n"            /* bits -= this.bits */
+"        shrl    %%cl, %%edx\n"           /* hold >>= this.bits */
+
+"        testb   %%al, %%al\n"
+"        jnz     .L_test_for_length_base\n" /* if (op != 0) 45.7% */
+
+"        shrl    $16, %%eax\n"            /* output this.val char */
+"        stosb\n"
+"        jmp     .L_while_test\n"
+
+".align 32,0x90\n"
+".L_test_for_length_base:\n"
+"        movl    %%eax, %%ecx\n"          /* len = this */
+"        shrl    $16, %%ecx\n"            /* len = this.val */
+"        movl    %%ecx, 64(%%esp)\n"      /* save len */
+"        movb    %%al, %%cl\n"
+
+"        testb   $16, %%al\n"
+"        jz      .L_test_for_second_level_length\n" /* if ((op & 16) == 0) 8% */
+"        andb    $15, %%cl\n"             /* op &= 15 */
+"        jz      .L_decode_distance\n"    /* if (!op) */
+"        cmpb    %%cl, %%bl\n"
+"        jae     .L_add_bits_to_len\n"    /* if (op <= bits) */
+
+"        movb    %%cl, %%ch\n"            /* stash op in ch, freeing cl */
+"        xorl    %%eax, %%eax\n"
+"        lodsw\n"                         /* al = *(ushort *)in++ */
+"        movb    %%bl, %%cl\n"            /* cl = bits, needs it for shifting */
+"        addb    $16, %%bl\n"             /* bits += 16 */
+"        shll    %%cl, %%eax\n"
+"        orl     %%eax, %%edx\n"         /* hold |= *((ushort *)in)++ << bits */
+"        movb    %%ch, %%cl\n"            /* move op back to ecx */
+
+".L_add_bits_to_len:\n"
+"        subb    %%cl, %%bl\n"
+"        xorl    %%eax, %%eax\n"
+"        incl    %%eax\n"
+"        shll    %%cl, %%eax\n"
+"        decl    %%eax\n"
+"        andl    %%edx, %%eax\n"          /* eax &= hold */
+"        shrl    %%cl, %%edx\n"
+"        addl    %%eax, 64(%%esp)\n"      /* len += hold & mask[op] */
+
+".L_decode_distance:\n"
+"        cmpb    $15, %%bl\n"
+"        ja      .L_get_distance_code\n"  /* if (15 < bits) */
+
+"        xorl    %%eax, %%eax\n"
+"        lodsw\n"                         /* al = *(ushort *)in++ */
+"        movb    %%bl, %%cl\n"            /* cl = bits, needs it for shifting */
+"        addb    $16, %%bl\n"             /* bits += 16 */
+"        shll    %%cl, %%eax\n"
+"        orl     %%eax, %%edx\n"         /* hold |= *((ushort *)in)++ << bits */
+
+".L_get_distance_code:\n"
+"        movl    60(%%esp), %%eax\n"      /* eax = dmask */
+"        movl    36(%%esp), %%ecx\n"      /* ecx = dcode */
+"        andl    %%edx, %%eax\n"          /* eax &= hold */
+"        movl    (%%ecx,%%eax,4), %%eax\n"/* eax = dcode[hold & dmask] */
+
+".L_dodist:\n"
+"        movl    %%eax, %%ebp\n"          /* dist = this */
+"        shrl    $16, %%ebp\n"            /* dist = this.val */
+"        movb    %%ah, %%cl\n"
+"        subb    %%ah, %%bl\n"            /* bits -= this.bits */
+"        shrl    %%cl, %%edx\n"           /* hold >>= this.bits */
+"        movb    %%al, %%cl\n"            /* cl = this.op */
+
+"        testb   $16, %%al\n"             /* if ((op & 16) == 0) */
+"        jz      .L_test_for_second_level_dist\n"
+"        andb    $15, %%cl\n"             /* op &= 15 */
+"        jz      .L_check_dist_one\n"
+"        cmpb    %%cl, %%bl\n"
+"        jae     .L_add_bits_to_dist\n"   /* if (op <= bits) 97.6% */
+
+"        movb    %%cl, %%ch\n"            /* stash op in ch, freeing cl */
+"        xorl    %%eax, %%eax\n"
+"        lodsw\n"                         /* al = *(ushort *)in++ */
+"        movb    %%bl, %%cl\n"            /* cl = bits, needs it for shifting */
+"        addb    $16, %%bl\n"             /* bits += 16 */
+"        shll    %%cl, %%eax\n"
+"        orl     %%eax, %%edx\n"        /* hold |= *((ushort *)in)++ << bits */
+"        movb    %%ch, %%cl\n"            /* move op back to ecx */
+
+".L_add_bits_to_dist:\n"
+"        subb    %%cl, %%bl\n"
+"        xorl    %%eax, %%eax\n"
+"        incl    %%eax\n"
+"        shll    %%cl, %%eax\n"
+"        decl    %%eax\n"                 /* (1 << op) - 1 */
+"        andl    %%edx, %%eax\n"          /* eax &= hold */
+"        shrl    %%cl, %%edx\n"
+"        addl    %%eax, %%ebp\n"          /* dist += hold & ((1 << op) - 1) */
+
+".L_check_window:\n"
+"        movl    %%esi, 8(%%esp)\n"       /* save in so from can use it's reg */
+"        movl    %%edi, %%eax\n"
+"        subl    20(%%esp), %%eax\n"      /* nbytes = out - beg */
+
+"        cmpl    %%ebp, %%eax\n"
+"        jb      .L_clip_window\n"        /* if (dist > nbytes) 4.2% */
+
+"        movl    64(%%esp), %%ecx\n"      /* ecx = len */
+"        movl    %%edi, %%esi\n"
+"        subl    %%ebp, %%esi\n"          /* from = out - dist */
+
+"        sarl    %%ecx\n"
+"        jnc     .L_copy_two\n"           /* if len % 2 == 0 */
+
+"        rep     movsw\n"
+"        movb    (%%esi), %%al\n"
+"        movb    %%al, (%%edi)\n"
+"        incl    %%edi\n"
+
+"        movl    8(%%esp), %%esi\n"       /* move in back to %esi, toss from */
+"        movl    32(%%esp), %%ebp\n"      /* ebp = lcode */
+"        jmp     .L_while_test\n"
+
+".L_copy_two:\n"
+"        rep     movsw\n"
+"        movl    8(%%esp), %%esi\n"       /* move in back to %esi, toss from */
+"        movl    32(%%esp), %%ebp\n"      /* ebp = lcode */
+"        jmp     .L_while_test\n"
+
+".align 32,0x90\n"
+".L_check_dist_one:\n"
+"        cmpl    $1, %%ebp\n"            /* if dist 1, is a memset */
+"        jne     .L_check_window\n"
+"        cmpl    %%edi, 20(%%esp)\n"
+"        je      .L_check_window\n"      /* out == beg, if outside window */
+
+"        movl    64(%%esp), %%ecx\n"      /* ecx = len */
+"        movb    -1(%%edi), %%al\n"
+"        movb    %%al, %%ah\n"
+
+"        sarl    %%ecx\n"
+"        jnc     .L_set_two\n"
+"        movb    %%al, (%%edi)\n"
+"        incl    %%edi\n"
+
+".L_set_two:\n"
+"        rep     stosw\n"
+"        movl    32(%%esp), %%ebp\n"      /* ebp = lcode */
+"        jmp     .L_while_test\n"
+
+".align 32,0x90\n"
+".L_test_for_second_level_length:\n"
+"        testb   $64, %%al\n"
+"        jnz     .L_test_for_end_of_block\n" /* if ((op & 64) != 0) */
+
+"        xorl    %%eax, %%eax\n"
+"        incl    %%eax\n"
+"        shll    %%cl, %%eax\n"
+"        decl    %%eax\n"
+"        andl    %%edx, %%eax\n"         /* eax &= hold */
+"        addl    64(%%esp), %%eax\n"     /* eax += len */
+"        movl    (%%ebp,%%eax,4), %%eax\n" /* eax = lcode[val+(hold&mask[op])]*/
+"        jmp     .L_dolen\n"
+
+".align 32,0x90\n"
+".L_test_for_second_level_dist:\n"
+"        testb   $64, %%al\n"
+"        jnz     .L_invalid_distance_code\n" /* if ((op & 64) != 0) */
+
+"        xorl    %%eax, %%eax\n"
+"        incl    %%eax\n"
+"        shll    %%cl, %%eax\n"
+"        decl    %%eax\n"
+"        andl    %%edx, %%eax\n"         /* eax &= hold */
+"        addl    %%ebp, %%eax\n"         /* eax += dist */
+"        movl    36(%%esp), %%ecx\n"     /* ecx = dcode */
+"        movl    (%%ecx,%%eax,4), %%eax\n" /* eax = dcode[val+(hold&mask[op])]*/
+"        jmp     .L_dodist\n"
+
+".align 32,0x90\n"
+".L_clip_window:\n"
+"        movl    %%eax, %%ecx\n"
+"        movl    48(%%esp), %%eax\n"     /* eax = wsize */
+"        negl    %%ecx\n"                /* nbytes = -nbytes */
+"        movl    28(%%esp), %%esi\n"     /* from = window */
+
+"        cmpl    %%ebp, %%eax\n"
+"        jb      .L_invalid_distance_too_far\n" /* if (dist > wsize) */
+
+"        addl    %%ebp, %%ecx\n"         /* nbytes = dist - nbytes */
+"        cmpl    $0, 52(%%esp)\n"
+"        jne     .L_wrap_around_window\n" /* if (write != 0) */
+
+"        subl    %%ecx, %%eax\n"
+"        addl    %%eax, %%esi\n"         /* from += wsize - nbytes */
+
+"        movl    64(%%esp), %%eax\n"     /* eax = len */
+"        cmpl    %%ecx, %%eax\n"
+"        jbe     .L_do_copy\n"           /* if (nbytes >= len) */
+
+"        subl    %%ecx, %%eax\n"         /* len -= nbytes */
+"        rep     movsb\n"
+"        movl    %%edi, %%esi\n"
+"        subl    %%ebp, %%esi\n"         /* from = out - dist */
+"        jmp     .L_do_copy\n"
+
+".align 32,0x90\n"
+".L_wrap_around_window:\n"
+"        movl    52(%%esp), %%eax\n"     /* eax = write */
+"        cmpl    %%eax, %%ecx\n"
+"        jbe     .L_contiguous_in_window\n" /* if (write >= nbytes) */
+
+"        addl    48(%%esp), %%esi\n"     /* from += wsize */
+"        addl    %%eax, %%esi\n"         /* from += write */
+"        subl    %%ecx, %%esi\n"         /* from -= nbytes */
+"        subl    %%eax, %%ecx\n"         /* nbytes -= write */
+
+"        movl    64(%%esp), %%eax\n"     /* eax = len */
+"        cmpl    %%ecx, %%eax\n"
+"        jbe     .L_do_copy\n"           /* if (nbytes >= len) */
+
+"        subl    %%ecx, %%eax\n"         /* len -= nbytes */
+"        rep     movsb\n"
+"        movl    28(%%esp), %%esi\n"     /* from = window */
+"        movl    52(%%esp), %%ecx\n"     /* nbytes = write */
+"        cmpl    %%ecx, %%eax\n"
+"        jbe     .L_do_copy\n"           /* if (nbytes >= len) */
+
+"        subl    %%ecx, %%eax\n"         /* len -= nbytes */
+"        rep     movsb\n"
+"        movl    %%edi, %%esi\n"
+"        subl    %%ebp, %%esi\n"         /* from = out - dist */
+"        jmp     .L_do_copy\n"
+
+".align 32,0x90\n"
+".L_contiguous_in_window:\n"
+"        addl    %%eax, %%esi\n"
+"        subl    %%ecx, %%esi\n"         /* from += write - nbytes */
+
+"        movl    64(%%esp), %%eax\n"     /* eax = len */
+"        cmpl    %%ecx, %%eax\n"
+"        jbe     .L_do_copy\n"           /* if (nbytes >= len) */
+
+"        subl    %%ecx, %%eax\n"         /* len -= nbytes */
+"        rep     movsb\n"
+"        movl    %%edi, %%esi\n"
+"        subl    %%ebp, %%esi\n"         /* from = out - dist */
+"        jmp     .L_do_copy\n"           /* if (nbytes >= len) */
+
+".align 32,0x90\n"
+".L_do_copy:\n"
+"        movl    %%eax, %%ecx\n"
+"        rep     movsb\n"
+
+"        movl    8(%%esp), %%esi\n"      /* move in back to %esi, toss from */
+"        movl    32(%%esp), %%ebp\n"     /* ebp = lcode */
+"        jmp     .L_while_test\n"
+
+".L_test_for_end_of_block:\n"
+"        testb   $32, %%al\n"
+"        jz      .L_invalid_literal_length_code\n"
+"        movl    $1, 72(%%esp)\n"
+"        jmp     .L_break_loop_with_status\n"
+
+".L_invalid_literal_length_code:\n"
+"        movl    $2, 72(%%esp)\n"
+"        jmp     .L_break_loop_with_status\n"
+
+".L_invalid_distance_code:\n"
+"        movl    $3, 72(%%esp)\n"
+"        jmp     .L_break_loop_with_status\n"
+
+".L_invalid_distance_too_far:\n"
+"        movl    8(%%esp), %%esi\n"
+"        movl    $4, 72(%%esp)\n"
+"        jmp     .L_break_loop_with_status\n"
+
+".L_break_loop:\n"
+"        movl    $0, 72(%%esp)\n"
+
+".L_break_loop_with_status:\n"
+/* put in, out, bits, and hold back into ar and pop esp */
+"        movl    %%esi, 8(%%esp)\n"      /* save in */
+"        movl    %%edi, 16(%%esp)\n"     /* save out */
+"        movl    %%ebx, 44(%%esp)\n"     /* save bits */
+"        movl    %%edx, 40(%%esp)\n"     /* save hold */
+"        movl    4(%%esp), %%ebp\n"      /* restore esp, ebp */
+"        movl    (%%esp), %%esp\n"
+          :
+          : "m" (ar)
+          : "memory", "%eax", "%ebx", "%ecx", "%edx", "%esi", "%edi"
+    );
+#elif defined( _MSC_VER ) && ! defined( _M_AMD64 )
+    __asm {
+	lea	eax, ar
+	mov	[eax], esp         /* save esp, ebp */
+	mov	[eax+4], ebp
+	mov	esp, eax
+	mov	esi, [esp+8]       /* esi = in */
+	mov	edi, [esp+16]      /* edi = out */
+	mov	edx, [esp+40]      /* edx = hold */
+	mov	ebx, [esp+44]      /* ebx = bits */
+	mov	ebp, [esp+32]      /* ebp = lcode */
+
+	cld
+	jmp	L_do_loop
+
+ALIGN 4
+L_while_test:
+	cmp	[esp+24], edi
+	jbe	L_break_loop
+	cmp	[esp+12], esi
+	jbe	L_break_loop
+
+L_do_loop:
+	cmp	bl, 15
+	ja	L_get_length_code    /* if (15 < bits) */
+
+	xor	eax, eax
+	lodsw                         /* al = *(ushort *)in++ */
+	mov	cl, bl            /* cl = bits, needs it for shifting */
+	add	bl, 16             /* bits += 16 */
+	shl	eax, cl
+	or	edx, eax        /* hold |= *((ushort *)in)++ << bits */
+
+L_get_length_code:
+	mov	eax, [esp+56]      /* eax = lmask */
+	and	eax, edx          /* eax &= hold */
+	mov	eax, [ebp+eax*4] /* eax = lcode[hold & lmask] */
+
+L_dolen:
+	mov	cl, ah            /* cl = this.bits */
+	sub	bl, ah            /* bits -= this.bits */
+	shr	edx, cl           /* hold >>= this.bits */
+
+	test	al, al
+	jnz	L_test_for_length_base /* if (op != 0) 45.7% */
+
+	shr	eax, 16            /* output this.val char */
+	stosb
+	jmp	L_while_test
+
+ALIGN 4
+L_test_for_length_base:
+	mov	ecx, eax          /* len = this */
+	shr	ecx, 16            /* len = this.val */
+	mov	[esp+64], ecx      /* save len */
+	mov	cl, al
+
+	test	al, 16
+	jz	L_test_for_second_level_length /* if ((op & 16) == 0) 8% */
+	and	cl, 15             /* op &= 15 */
+	jz	L_decode_distance    /* if (!op) */
+	cmp	bl, cl
+	jae	L_add_bits_to_len    /* if (op <= bits) */
+
+	mov	ch, cl            /* stash op in ch, freeing cl */
+	xor	eax, eax
+	lodsw                         /* al = *(ushort *)in++ */
+	mov	cl, bl            /* cl = bits, needs it for shifting */
+	add	bl, 16             /* bits += 16 */
+	shl	eax, cl
+	or	edx, eax         /* hold |= *((ushort *)in)++ << bits */
+	mov	cl, ch            /* move op back to ecx */
+
+L_add_bits_to_len:
+	sub	bl, cl
+	xor	eax, eax
+	inc	eax
+	shl	eax, cl
+	dec	eax
+	and	eax, edx          /* eax &= hold */
+	shr	edx, cl
+	add	[esp+64], eax      /* len += hold & mask[op] */
+
+L_decode_distance:
+	cmp	bl, 15
+	ja	L_get_distance_code  /* if (15 < bits) */
+
+	xor	eax, eax
+	lodsw                         /* al = *(ushort *)in++ */
+	mov	cl, bl            /* cl = bits, needs it for shifting */
+	add	bl, 16             /* bits += 16 */
+	shl	eax, cl
+	or	edx, eax         /* hold |= *((ushort *)in)++ << bits */
+
+L_get_distance_code:
+	mov	eax, [esp+60]      /* eax = dmask */
+	mov	ecx, [esp+36]      /* ecx = dcode */
+	and	eax, edx          /* eax &= hold */
+	mov	eax, [ecx+eax*4]/* eax = dcode[hold & dmask] */
+
+L_dodist:
+	mov	ebp, eax          /* dist = this */
+	shr	ebp, 16            /* dist = this.val */
+	mov	cl, ah
+	sub	bl, ah            /* bits -= this.bits */
+	shr	edx, cl           /* hold >>= this.bits */
+	mov	cl, al            /* cl = this.op */
+
+	test	al, 16             /* if ((op & 16) == 0) */
+	jz	L_test_for_second_level_dist
+	and	cl, 15             /* op &= 15 */
+	jz	L_check_dist_one
+	cmp	bl, cl
+	jae	L_add_bits_to_dist   /* if (op <= bits) 97.6% */
+
+	mov	ch, cl            /* stash op in ch, freeing cl */
+	xor	eax, eax
+	lodsw                         /* al = *(ushort *)in++ */
+	mov	cl, bl            /* cl = bits, needs it for shifting */
+	add	bl, 16             /* bits += 16 */
+	shl	eax, cl
+	or	edx, eax        /* hold |= *((ushort *)in)++ << bits */
+	mov	cl, ch            /* move op back to ecx */
+
+L_add_bits_to_dist:
+	sub	bl, cl
+	xor	eax, eax
+	inc	eax
+	shl	eax, cl
+	dec	eax                 /* (1 << op) - 1 */
+	and	eax, edx          /* eax &= hold */
+	shr	edx, cl
+	add	ebp, eax          /* dist += hold & ((1 << op) - 1) */
+
+L_check_window:
+	mov	[esp+8], esi       /* save in so from can use it's reg */
+	mov	eax, edi
+	sub	eax, [esp+20]      /* nbytes = out - beg */
+
+	cmp	eax, ebp
+	jb	L_clip_window        /* if (dist > nbytes) 4.2% */
+
+	mov	ecx, [esp+64]      /* ecx = len */
+	mov	esi, edi
+	sub	esi, ebp          /* from = out - dist */
+
+	sar	ecx, 1
+	jnc	L_copy_two
+
+	rep     movsw
+	mov	al, [esi]
+	mov	[edi], al
+	inc	edi
+
+	mov	esi, [esp+8]      /* move in back to %esi, toss from */
+	mov	ebp, [esp+32]     /* ebp = lcode */
+	jmp	L_while_test
+
+L_copy_two:
+	rep     movsw
+	mov	esi, [esp+8]      /* move in back to %esi, toss from */
+	mov	ebp, [esp+32]     /* ebp = lcode */
+	jmp	L_while_test
+
+ALIGN 4
+L_check_dist_one:
+	cmp	ebp, 1            /* if dist 1, is a memset */
+	jne	L_check_window
+	cmp	[esp+20], edi
+	je	L_check_window    /* out == beg, if outside window */
+
+	mov	ecx, [esp+64]     /* ecx = len */
+	mov	al, [edi-1]
+	mov	ah, al
+
+	sar	ecx, 1
+	jnc	L_set_two
+	mov	[edi], al         /* memset out with from[-1] */
+	inc	edi
+
+L_set_two:
+	rep     stosw
+	mov	ebp, [esp+32]     /* ebp = lcode */
+	jmp	L_while_test
+
+ALIGN 4
+L_test_for_second_level_length:
+	test	al, 64
+	jnz	L_test_for_end_of_block /* if ((op & 64) != 0) */
+
+	xor	eax, eax
+	inc	eax
+	shl	eax, cl
+	dec	eax
+	and	eax, edx         /* eax &= hold */
+	add	eax, [esp+64]     /* eax += len */
+	mov	eax, [ebp+eax*4] /* eax = lcode[val+(hold&mask[op])]*/
+	jmp	L_dolen
+
+ALIGN 4
+L_test_for_second_level_dist:
+	test	al, 64
+	jnz	L_invalid_distance_code /* if ((op & 64) != 0) */
+
+	xor	eax, eax
+	inc	eax
+	shl	eax, cl
+	dec	eax
+	and	eax, edx         /* eax &= hold */
+	add	eax, ebp         /* eax += dist */
+	mov	ecx, [esp+36]     /* ecx = dcode */
+	mov	eax, [ecx+eax*4] /* eax = dcode[val+(hold&mask[op])]*/
+	jmp	L_dodist
+
+ALIGN 4
+L_clip_window:
+	mov	ecx, eax
+	mov	eax, [esp+48]     /* eax = wsize */
+	neg	ecx                /* nbytes = -nbytes */
+	mov	esi, [esp+28]     /* from = window */
+
+	cmp	eax, ebp
+	jb	L_invalid_distance_too_far /* if (dist > wsize) */
+
+	add	ecx, ebp         /* nbytes = dist - nbytes */
+	cmp	dword ptr [esp+52], 0
+	jne	L_wrap_around_window /* if (write != 0) */
+
+	sub	eax, ecx
+	add	esi, eax         /* from += wsize - nbytes */
+
+	mov	eax, [esp+64]    /* eax = len */
+	cmp	eax, ecx
+	jbe	L_do_copy          /* if (nbytes >= len) */
+
+	sub	eax, ecx         /* len -= nbytes */
+	rep     movsb
+	mov	esi, edi
+	sub	esi, ebp         /* from = out - dist */
+	jmp	L_do_copy
+
+ALIGN 4
+L_wrap_around_window:
+	mov	eax, [esp+52]    /* eax = write */
+	cmp	ecx, eax
+	jbe	L_contiguous_in_window /* if (write >= nbytes) */
+
+	add	esi, [esp+48]    /* from += wsize */
+	add	esi, eax         /* from += write */
+	sub	esi, ecx         /* from -= nbytes */
+	sub	ecx, eax         /* nbytes -= write */
+
+	mov	eax, [esp+64]    /* eax = len */
+	cmp	eax, ecx
+	jbe	L_do_copy          /* if (nbytes >= len) */
+
+	sub	eax, ecx         /* len -= nbytes */
+	rep     movsb
+	mov	esi, [esp+28]     /* from = window */
+	mov	ecx, [esp+52]     /* nbytes = write */
+	cmp	eax, ecx
+	jbe	L_do_copy          /* if (nbytes >= len) */
+
+	sub	eax, ecx         /* len -= nbytes */
+	rep     movsb
+	mov	esi, edi
+	sub	esi, ebp         /* from = out - dist */
+	jmp	L_do_copy
+
+ALIGN 4
+L_contiguous_in_window:
+	add	esi, eax
+	sub	esi, ecx         /* from += write - nbytes */
+
+	mov	eax, [esp+64]    /* eax = len */
+	cmp	eax, ecx
+	jbe	L_do_copy          /* if (nbytes >= len) */
+
+	sub	eax, ecx         /* len -= nbytes */
+	rep     movsb
+	mov	esi, edi
+	sub	esi, ebp         /* from = out - dist */
+	jmp	L_do_copy
+
+ALIGN 4
+L_do_copy:
+	mov	ecx, eax
+	rep     movsb
+
+	mov	esi, [esp+8]      /* move in back to %esi, toss from */
+	mov	ebp, [esp+32]     /* ebp = lcode */
+	jmp	L_while_test
+
+L_test_for_end_of_block:
+	test	al, 32
+	jz	L_invalid_literal_length_code
+	mov	dword ptr [esp+72], 1
+	jmp	L_break_loop_with_status
+
+L_invalid_literal_length_code:
+	mov	dword ptr [esp+72], 2
+	jmp	L_break_loop_with_status
+
+L_invalid_distance_code:
+	mov	dword ptr [esp+72], 3
+	jmp	L_break_loop_with_status
+
+L_invalid_distance_too_far:
+	mov	esi, [esp+4]
+	mov	dword ptr [esp+72], 4
+	jmp	L_break_loop_with_status
+
+L_break_loop:
+	mov	dword ptr [esp+72], 0
+
+L_break_loop_with_status:
+/* put in, out, bits, and hold back into ar and pop esp */
+	mov	[esp+8], esi     /* save in */
+	mov	[esp+16], edi    /* save out */
+	mov	[esp+44], ebx    /* save bits */
+	mov	[esp+40], edx    /* save hold */
+	mov	ebp, [esp+4]     /* restore esp, ebp */
+	mov	esp, [esp]
+    }
+#else
+#error "x86 architecture not defined"
+#endif
+
+    if (ar.status > 1) {
+        if (ar.status == 2)
+            strm->msg = "invalid literal/length code";
+        else if (ar.status == 3)
+            strm->msg = "invalid distance code";
+        else
+            strm->msg = "invalid distance too far back";
+        state->mode = BAD;
+    }
+    else if ( ar.status == 1 ) {
+        state->mode = TYPE;
+    }
+
+    /* return unused bytes (on entry, bits < 8, so in won't go too far back) */
+    ar.len = ar.bits >> 3;
+    ar.in -= ar.len;
+    ar.bits -= ar.len << 3;
+    ar.hold &= (1U << ar.bits) - 1;
+
+    /* update state and return */
+    strm->next_in = ar.in;
+    strm->next_out = ar.out;
+    strm->avail_in = (unsigned)(ar.in < ar.last ?
+                                PAD_AVAIL_IN + (ar.last - ar.in) :
+                                PAD_AVAIL_IN - (ar.in - ar.last));
+    strm->avail_out = (unsigned)(ar.out < ar.end ?
+                                 PAD_AVAIL_OUT + (ar.end - ar.out) :
+                                 PAD_AVAIL_OUT - (ar.out - ar.end));
+    state->hold = ar.hold;
+    state->bits = ar.bits;
+    return;
+}
+
diff --git a/compat/zlib/contrib/inflate86/inffast.S b/compat/zlib/contrib/inflate86/inffast.S
new file mode 100644
index 0000000..2245a29
--- /dev/null
+++ b/compat/zlib/contrib/inflate86/inffast.S
@@ -0,0 +1,1368 @@
+/*
+ * inffast.S is a hand tuned assembler version of:
+ *
+ * inffast.c -- fast decoding
+ * Copyright (C) 1995-2003 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ *
+ * Copyright (C) 2003 Chris Anderson <christop@charm.net>
+ * Please use the copyright conditions above.
+ *
+ * This version (Jan-23-2003) of inflate_fast was coded and tested under
+ * GNU/Linux on a pentium 3, using the gcc-3.2 compiler distribution.  On that
+ * machine, I found that gzip style archives decompressed about 20% faster than
+ * the gcc-3.2 -O3 -fomit-frame-pointer compiled version.  Your results will
+ * depend on how large of a buffer is used for z_stream.next_in & next_out
+ * (8K-32K worked best for my 256K cpu cache) and how much overhead there is in
+ * stream processing I/O and crc32/addler32.  In my case, this routine used
+ * 70% of the cpu time and crc32 used 20%.
+ *
+ * I am confident that this version will work in the general case, but I have
+ * not tested a wide variety of datasets or a wide variety of platforms.
+ *
+ * Jan-24-2003 -- Added -DUSE_MMX define for slightly faster inflating.
+ * It should be a runtime flag instead of compile time flag...
+ *
+ * Jan-26-2003 -- Added runtime check for MMX support with cpuid instruction.
+ * With -DUSE_MMX, only MMX code is compiled.  With -DNO_MMX, only non-MMX code
+ * is compiled.  Without either option, runtime detection is enabled.  Runtime
+ * detection should work on all modern cpus and the recomended algorithm (flip
+ * ID bit on eflags and then use the cpuid instruction) is used in many
+ * multimedia applications.  Tested under win2k with gcc-2.95 and gas-2.12
+ * distributed with cygwin3.  Compiling with gcc-2.95 -c inffast.S -o
+ * inffast.obj generates a COFF object which can then be linked with MSVC++
+ * compiled code.  Tested under FreeBSD 4.7 with gcc-2.95.
+ *
+ * Jan-28-2003 -- Tested Athlon XP... MMX mode is slower than no MMX (and
+ * slower than compiler generated code).  Adjusted cpuid check to use the MMX
+ * code only for Pentiums < P4 until I have more data on the P4.  Speed
+ * improvment is only about 15% on the Athlon when compared with code generated
+ * with MSVC++.  Not sure yet, but I think the P4 will also be slower using the
+ * MMX mode because many of it's x86 ALU instructions execute in .5 cycles and
+ * have less latency than MMX ops.  Added code to buffer the last 11 bytes of
+ * the input stream since the MMX code grabs bits in chunks of 32, which
+ * differs from the inffast.c algorithm.  I don't think there would have been
+ * read overruns where a page boundary was crossed (a segfault), but there
+ * could have been overruns when next_in ends on unaligned memory (unintialized
+ * memory read).
+ *
+ * Mar-13-2003 -- P4 MMX is slightly slower than P4 NO_MMX.  I created a C
+ * version of the non-MMX code so that it doesn't depend on zstrm and zstate
+ * structure offsets which are hard coded in this file.  This was last tested
+ * with zlib-1.2.0 which is currently in beta testing, newer versions of this
+ * and inffas86.c can be found at http://www.eetbeetee.com/zlib/ and
+ * http://www.charm.net/~christop/zlib/
+ */
+
+
+/*
+ * if you have underscore linking problems (_inflate_fast undefined), try
+ * using -DGAS_COFF
+ */
+#if ! defined( GAS_COFF ) && ! defined( GAS_ELF )
+
+#if defined( WIN32 ) || defined( __CYGWIN__ )
+#define GAS_COFF /* windows object format */
+#else
+#define GAS_ELF
+#endif
+
+#endif /* ! GAS_COFF && ! GAS_ELF */
+
+
+#if defined( GAS_COFF )
+
+/* coff externals have underscores */
+#define inflate_fast _inflate_fast
+#define inflate_fast_use_mmx _inflate_fast_use_mmx
+
+#endif /* GAS_COFF */
+
+
+.file "inffast.S"
+
+.globl inflate_fast
+
+.text
+.align 4,0
+.L_invalid_literal_length_code_msg:
+.string "invalid literal/length code"
+
+.align 4,0
+.L_invalid_distance_code_msg:
+.string "invalid distance code"
+
+.align 4,0
+.L_invalid_distance_too_far_msg:
+.string "invalid distance too far back"
+
+#if ! defined( NO_MMX )
+.align 4,0
+.L_mask: /* mask[N] = ( 1 << N ) - 1 */
+.long 0
+.long 1
+.long 3
+.long 7
+.long 15
+.long 31
+.long 63
+.long 127
+.long 255
+.long 511
+.long 1023
+.long 2047
+.long 4095
+.long 8191
+.long 16383
+.long 32767
+.long 65535
+.long 131071
+.long 262143
+.long 524287
+.long 1048575
+.long 2097151
+.long 4194303
+.long 8388607
+.long 16777215
+.long 33554431
+.long 67108863
+.long 134217727
+.long 268435455
+.long 536870911
+.long 1073741823
+.long 2147483647
+.long 4294967295
+#endif /* NO_MMX */
+
+.text
+
+/*
+ * struct z_stream offsets, in zlib.h
+ */
+#define next_in_strm   0   /* strm->next_in */
+#define avail_in_strm  4   /* strm->avail_in */
+#define next_out_strm  12  /* strm->next_out */
+#define avail_out_strm 16  /* strm->avail_out */
+#define msg_strm       24  /* strm->msg */
+#define state_strm     28  /* strm->state */
+
+/*
+ * struct inflate_state offsets, in inflate.h
+ */
+#define mode_state     0   /* state->mode */
+#define wsize_state    32  /* state->wsize */
+#define write_state    40  /* state->write */
+#define window_state   44  /* state->window */
+#define hold_state     48  /* state->hold */
+#define bits_state     52  /* state->bits */
+#define lencode_state  68  /* state->lencode */
+#define distcode_state 72  /* state->distcode */
+#define lenbits_state  76  /* state->lenbits */
+#define distbits_state 80  /* state->distbits */
+
+/*
+ * inflate_fast's activation record
+ */
+#define local_var_size 64 /* how much local space for vars */
+#define strm_sp        88 /* first arg: z_stream * (local_var_size + 24) */
+#define start_sp       92 /* second arg: unsigned int (local_var_size + 28) */
+
+/*
+ * offsets for local vars on stack
+ */
+#define out            60  /* unsigned char* */
+#define window         56  /* unsigned char* */
+#define wsize          52  /* unsigned int */
+#define write          48  /* unsigned int */
+#define in             44  /* unsigned char* */
+#define beg            40  /* unsigned char* */
+#define buf            28  /* char[ 12 ] */
+#define len            24  /* unsigned int */
+#define last           20  /* unsigned char* */
+#define end            16  /* unsigned char* */
+#define dcode          12  /* code* */
+#define lcode           8  /* code* */
+#define dmask           4  /* unsigned int */
+#define lmask           0  /* unsigned int */
+
+/*
+ * typedef enum inflate_mode consts, in inflate.h
+ */
+#define INFLATE_MODE_TYPE 11  /* state->mode flags enum-ed in inflate.h */
+#define INFLATE_MODE_BAD  26
+
+
+#if ! defined( USE_MMX ) && ! defined( NO_MMX )
+
+#define RUN_TIME_MMX
+
+#define CHECK_MMX    1
+#define DO_USE_MMX   2
+#define DONT_USE_MMX 3
+
+.globl inflate_fast_use_mmx
+
+.data
+
+.align 4,0
+inflate_fast_use_mmx: /* integer flag for run time control 1=check,2=mmx,3=no */
+.long CHECK_MMX
+
+#if defined( GAS_ELF )
+/* elf info */
+.type   inflate_fast_use_mmx,@object
+.size   inflate_fast_use_mmx,4
+#endif
+
+#endif /* RUN_TIME_MMX */
+
+#if defined( GAS_COFF )
+/* coff info: scl 2 = extern, type 32 = function */
+.def inflate_fast; .scl 2; .type 32; .endef
+#endif
+
+.text
+
+.align 32,0x90
+inflate_fast:
+        pushl   %edi
+        pushl   %esi
+        pushl   %ebp
+        pushl   %ebx
+        pushf   /* save eflags (strm_sp, state_sp assumes this is 32 bits) */
+        subl    $local_var_size, %esp
+        cld
+
+#define strm_r  %esi
+#define state_r %edi
+
+        movl    strm_sp(%esp), strm_r
+        movl    state_strm(strm_r), state_r
+
+        /* in = strm->next_in;
+         * out = strm->next_out;
+         * last = in + strm->avail_in - 11;
+         * beg = out - (start - strm->avail_out);
+         * end = out + (strm->avail_out - 257);
+         */
+        movl    avail_in_strm(strm_r), %edx
+        movl    next_in_strm(strm_r), %eax
+
+        addl    %eax, %edx      /* avail_in += next_in */
+        subl    $11, %edx       /* avail_in -= 11 */
+
+        movl    %eax, in(%esp)
+        movl    %edx, last(%esp)
+
+        movl    start_sp(%esp), %ebp
+        movl    avail_out_strm(strm_r), %ecx
+        movl    next_out_strm(strm_r), %ebx
+
+        subl    %ecx, %ebp      /* start -= avail_out */
+        negl    %ebp            /* start = -start */
+        addl    %ebx, %ebp      /* start += next_out */
+
+        subl    $257, %ecx      /* avail_out -= 257 */
+        addl    %ebx, %ecx      /* avail_out += out */
+
+        movl    %ebx, out(%esp)
+        movl    %ebp, beg(%esp)
+        movl    %ecx, end(%esp)
+
+        /* wsize = state->wsize;
+         * write = state->write;
+         * window = state->window;
+         * hold = state->hold;
+         * bits = state->bits;
+         * lcode = state->lencode;
+         * dcode = state->distcode;
+         * lmask = ( 1 << state->lenbits ) - 1;
+         * dmask = ( 1 << state->distbits ) - 1;
+         */
+
+        movl    lencode_state(state_r), %eax
+        movl    distcode_state(state_r), %ecx
+
+        movl    %eax, lcode(%esp)
+        movl    %ecx, dcode(%esp)
+
+        movl    $1, %eax
+        movl    lenbits_state(state_r), %ecx
+        shll    %cl, %eax
+        decl    %eax
+        movl    %eax, lmask(%esp)
+
+        movl    $1, %eax
+        movl    distbits_state(state_r), %ecx
+        shll    %cl, %eax
+        decl    %eax
+        movl    %eax, dmask(%esp)
+
+        movl    wsize_state(state_r), %eax
+        movl    write_state(state_r), %ecx
+        movl    window_state(state_r), %edx
+
+        movl    %eax, wsize(%esp)
+        movl    %ecx, write(%esp)
+        movl    %edx, window(%esp)
+
+        movl    hold_state(state_r), %ebp
+        movl    bits_state(state_r), %ebx
+
+#undef strm_r
+#undef state_r
+
+#define in_r       %esi
+#define from_r     %esi
+#define out_r      %edi
+
+        movl    in(%esp), in_r
+        movl    last(%esp), %ecx
+        cmpl    in_r, %ecx
+        ja      .L_align_long           /* if in < last */
+
+        addl    $11, %ecx               /* ecx = &in[ avail_in ] */
+        subl    in_r, %ecx              /* ecx = avail_in */
+        movl    $12, %eax
+        subl    %ecx, %eax              /* eax = 12 - avail_in */
+        leal    buf(%esp), %edi
+        rep     movsb                   /* memcpy( buf, in, avail_in ) */
+        movl    %eax, %ecx
+        xorl    %eax, %eax
+        rep     stosb         /* memset( &buf[ avail_in ], 0, 12 - avail_in ) */
+        leal    buf(%esp), in_r         /* in = buf */
+        movl    in_r, last(%esp)        /* last = in, do just one iteration */
+        jmp     .L_is_aligned
+
+        /* align in_r on long boundary */
+.L_align_long:
+        testl   $3, in_r
+        jz      .L_is_aligned
+        xorl    %eax, %eax
+        movb    (in_r), %al
+        incl    in_r
+        movl    %ebx, %ecx
+        addl    $8, %ebx
+        shll    %cl, %eax
+        orl     %eax, %ebp
+        jmp     .L_align_long
+
+.L_is_aligned:
+        movl    out(%esp), out_r
+
+#if defined( NO_MMX )
+        jmp     .L_do_loop
+#endif
+
+#if defined( USE_MMX )
+        jmp     .L_init_mmx
+#endif
+
+/*** Runtime MMX check ***/
+
+#if defined( RUN_TIME_MMX )
+.L_check_mmx:
+        cmpl    $DO_USE_MMX, inflate_fast_use_mmx
+        je      .L_init_mmx
+        ja      .L_do_loop /* > 2 */
+
+        pushl   %eax
+        pushl   %ebx
+        pushl   %ecx
+        pushl   %edx
+        pushf
+        movl    (%esp), %eax      /* copy eflags to eax */
+        xorl    $0x200000, (%esp) /* try toggling ID bit of eflags (bit 21)
+                                   * to see if cpu supports cpuid...
+                                   * ID bit method not supported by NexGen but
+                                   * bios may load a cpuid instruction and
+                                   * cpuid may be disabled on Cyrix 5-6x86 */
+        popf
+        pushf
+        popl    %edx              /* copy new eflags to edx */
+        xorl    %eax, %edx        /* test if ID bit is flipped */
+        jz      .L_dont_use_mmx   /* not flipped if zero */
+        xorl    %eax, %eax
+        cpuid
+        cmpl    $0x756e6547, %ebx /* check for GenuineIntel in ebx,ecx,edx */
+        jne     .L_dont_use_mmx
+        cmpl    $0x6c65746e, %ecx
+        jne     .L_dont_use_mmx
+        cmpl    $0x49656e69, %edx
+        jne     .L_dont_use_mmx
+        movl    $1, %eax
+        cpuid                     /* get cpu features */
+        shrl    $8, %eax
+        andl    $15, %eax
+        cmpl    $6, %eax          /* check for Pentium family, is 0xf for P4 */
+        jne     .L_dont_use_mmx
+        testl   $0x800000, %edx   /* test if MMX feature is set (bit 23) */
+        jnz     .L_use_mmx
+        jmp     .L_dont_use_mmx
+.L_use_mmx:
+        movl    $DO_USE_MMX, inflate_fast_use_mmx
+        jmp     .L_check_mmx_pop
+.L_dont_use_mmx:
+        movl    $DONT_USE_MMX, inflate_fast_use_mmx
+.L_check_mmx_pop:
+        popl    %edx
+        popl    %ecx
+        popl    %ebx
+        popl    %eax
+        jmp     .L_check_mmx
+#endif
+
+
+/*** Non-MMX code ***/
+
+#if defined ( NO_MMX ) || defined( RUN_TIME_MMX )
+
+#define hold_r     %ebp
+#define bits_r     %bl
+#define bitslong_r %ebx
+
+.align 32,0x90
+.L_while_test:
+        /* while (in < last && out < end)
+         */
+        cmpl    out_r, end(%esp)
+        jbe     .L_break_loop           /* if (out >= end) */
+
+        cmpl    in_r, last(%esp)
+        jbe     .L_break_loop
+
+.L_do_loop:
+        /* regs: %esi = in, %ebp = hold, %bl = bits, %edi = out
+         *
+         * do {
+         *   if (bits < 15) {
+         *     hold |= *((unsigned short *)in)++ << bits;
+         *     bits += 16
+         *   }
+         *   this = lcode[hold & lmask]
+         */
+        cmpb    $15, bits_r
+        ja      .L_get_length_code      /* if (15 < bits) */
+
+        xorl    %eax, %eax
+        lodsw                           /* al = *(ushort *)in++ */
+        movb    bits_r, %cl             /* cl = bits, needs it for shifting */
+        addb    $16, bits_r             /* bits += 16 */
+        shll    %cl, %eax
+        orl     %eax, hold_r            /* hold |= *((ushort *)in)++ << bits */
+
+.L_get_length_code:
+        movl    lmask(%esp), %edx       /* edx = lmask */
+        movl    lcode(%esp), %ecx       /* ecx = lcode */
+        andl    hold_r, %edx            /* edx &= hold */
+        movl    (%ecx,%edx,4), %eax     /* eax = lcode[hold & lmask] */
+
+.L_dolen:
+        /* regs: %esi = in, %ebp = hold, %bl = bits, %edi = out
+         *
+         * dolen:
+         *    bits -= this.bits;
+         *    hold >>= this.bits
+         */
+        movb    %ah, %cl                /* cl = this.bits */
+        subb    %ah, bits_r             /* bits -= this.bits */
+        shrl    %cl, hold_r             /* hold >>= this.bits */
+
+        /* check if op is a literal
+         * if (op == 0) {
+         *    PUP(out) = this.val;
+         *  }
+         */
+        testb   %al, %al
+        jnz     .L_test_for_length_base /* if (op != 0) 45.7% */
+
+        shrl    $16, %eax               /* output this.val char */
+        stosb
+        jmp     .L_while_test
+
+.L_test_for_length_base:
+        /* regs: %esi = in, %ebp = hold, %bl = bits, %edi = out, %edx = len
+         *
+         * else if (op & 16) {
+         *   len = this.val
+         *   op &= 15
+         *   if (op) {
+         *     if (op > bits) {
+         *       hold |= *((unsigned short *)in)++ << bits;
+         *       bits += 16
+         *     }
+         *     len += hold & mask[op];
+         *     bits -= op;
+         *     hold >>= op;
+         *   }
+         */
+#define len_r %edx
+        movl    %eax, len_r             /* len = this */
+        shrl    $16, len_r              /* len = this.val */
+        movb    %al, %cl
+
+        testb   $16, %al
+        jz      .L_test_for_second_level_length /* if ((op & 16) == 0) 8% */
+        andb    $15, %cl                /* op &= 15 */
+        jz      .L_save_len             /* if (!op) */
+        cmpb    %cl, bits_r
+        jae     .L_add_bits_to_len      /* if (op <= bits) */
+
+        movb    %cl, %ch                /* stash op in ch, freeing cl */
+        xorl    %eax, %eax
+        lodsw                           /* al = *(ushort *)in++ */
+        movb    bits_r, %cl             /* cl = bits, needs it for shifting */
+        addb    $16, bits_r             /* bits += 16 */
+        shll    %cl, %eax
+        orl     %eax, hold_r            /* hold |= *((ushort *)in)++ << bits */
+        movb    %ch, %cl                /* move op back to ecx */
+
+.L_add_bits_to_len:
+        movl    $1, %eax
+        shll    %cl, %eax
+        decl    %eax
+        subb    %cl, bits_r
+        andl    hold_r, %eax            /* eax &= hold */
+        shrl    %cl, hold_r
+        addl    %eax, len_r             /* len += hold & mask[op] */
+
+.L_save_len:
+        movl    len_r, len(%esp)        /* save len */
+#undef  len_r
+
+.L_decode_distance:
+        /* regs: %esi = in, %ebp = hold, %bl = bits, %edi = out, %edx = dist
+         *
+         *   if (bits < 15) {
+         *     hold |= *((unsigned short *)in)++ << bits;
+         *     bits += 16
+         *   }
+         *   this = dcode[hold & dmask];
+         * dodist:
+         *   bits -= this.bits;
+         *   hold >>= this.bits;
+         *   op = this.op;
+         */
+
+        cmpb    $15, bits_r
+        ja      .L_get_distance_code    /* if (15 < bits) */
+
+        xorl    %eax, %eax
+        lodsw                           /* al = *(ushort *)in++ */
+        movb    bits_r, %cl             /* cl = bits, needs it for shifting */
+        addb    $16, bits_r             /* bits += 16 */
+        shll    %cl, %eax
+        orl     %eax, hold_r            /* hold |= *((ushort *)in)++ << bits */
+
+.L_get_distance_code:
+        movl    dmask(%esp), %edx       /* edx = dmask */
+        movl    dcode(%esp), %ecx       /* ecx = dcode */
+        andl    hold_r, %edx            /* edx &= hold */
+        movl    (%ecx,%edx,4), %eax     /* eax = dcode[hold & dmask] */
+
+#define dist_r %edx
+.L_dodist:
+        movl    %eax, dist_r            /* dist = this */
+        shrl    $16, dist_r             /* dist = this.val */
+        movb    %ah, %cl
+        subb    %ah, bits_r             /* bits -= this.bits */
+        shrl    %cl, hold_r             /* hold >>= this.bits */
+
+        /* if (op & 16) {
+         *   dist = this.val
+         *   op &= 15
+         *   if (op > bits) {
+         *     hold |= *((unsigned short *)in)++ << bits;
+         *     bits += 16
+         *   }
+         *   dist += hold & mask[op];
+         *   bits -= op;
+         *   hold >>= op;
+         */
+        movb    %al, %cl                /* cl = this.op */
+
+        testb   $16, %al                /* if ((op & 16) == 0) */
+        jz      .L_test_for_second_level_dist
+        andb    $15, %cl                /* op &= 15 */
+        jz      .L_check_dist_one
+        cmpb    %cl, bits_r
+        jae     .L_add_bits_to_dist     /* if (op <= bits) 97.6% */
+
+        movb    %cl, %ch                /* stash op in ch, freeing cl */
+        xorl    %eax, %eax
+        lodsw                           /* al = *(ushort *)in++ */
+        movb    bits_r, %cl             /* cl = bits, needs it for shifting */
+        addb    $16, bits_r             /* bits += 16 */
+        shll    %cl, %eax
+        orl     %eax, hold_r            /* hold |= *((ushort *)in)++ << bits */
+        movb    %ch, %cl                /* move op back to ecx */
+
+.L_add_bits_to_dist:
+        movl    $1, %eax
+        shll    %cl, %eax
+        decl    %eax                    /* (1 << op) - 1 */
+        subb    %cl, bits_r
+        andl    hold_r, %eax            /* eax &= hold */
+        shrl    %cl, hold_r
+        addl    %eax, dist_r            /* dist += hold & ((1 << op) - 1) */
+        jmp     .L_check_window
+
+.L_check_window:
+        /* regs: %esi = from, %ebp = hold, %bl = bits, %edi = out, %edx = dist
+         *       %ecx = nbytes
+         *
+         * nbytes = out - beg;
+         * if (dist <= nbytes) {
+         *   from = out - dist;
+         *   do {
+         *     PUP(out) = PUP(from);
+         *   } while (--len > 0) {
+         * }
+         */
+
+        movl    in_r, in(%esp)          /* save in so from can use it's reg */
+        movl    out_r, %eax
+        subl    beg(%esp), %eax         /* nbytes = out - beg */
+
+        cmpl    dist_r, %eax
+        jb      .L_clip_window          /* if (dist > nbytes) 4.2% */
+
+        movl    len(%esp), %ecx
+        movl    out_r, from_r
+        subl    dist_r, from_r          /* from = out - dist */
+
+        subl    $3, %ecx
+        movb    (from_r), %al
+        movb    %al, (out_r)
+        movb    1(from_r), %al
+        movb    2(from_r), %dl
+        addl    $3, from_r
+        movb    %al, 1(out_r)
+        movb    %dl, 2(out_r)
+        addl    $3, out_r
+        rep     movsb
+
+        movl    in(%esp), in_r          /* move in back to %esi, toss from */
+        jmp     .L_while_test
+
+.align 16,0x90
+.L_check_dist_one:
+        cmpl    $1, dist_r
+        jne     .L_check_window
+        cmpl    out_r, beg(%esp)
+        je      .L_check_window
+
+        decl    out_r
+        movl    len(%esp), %ecx
+        movb    (out_r), %al
+        subl    $3, %ecx
+
+        movb    %al, 1(out_r)
+        movb    %al, 2(out_r)
+        movb    %al, 3(out_r)
+        addl    $4, out_r
+        rep     stosb
+
+        jmp     .L_while_test
+
+.align 16,0x90
+.L_test_for_second_level_length:
+        /* else if ((op & 64) == 0) {
+         *   this = lcode[this.val + (hold & mask[op])];
+         * }
+         */
+        testb   $64, %al
+        jnz     .L_test_for_end_of_block  /* if ((op & 64) != 0) */
+
+        movl    $1, %eax
+        shll    %cl, %eax
+        decl    %eax
+        andl    hold_r, %eax            /* eax &= hold */
+        addl    %edx, %eax              /* eax += this.val */
+        movl    lcode(%esp), %edx       /* edx = lcode */
+        movl    (%edx,%eax,4), %eax     /* eax = lcode[val + (hold&mask[op])] */
+        jmp     .L_dolen
+
+.align 16,0x90
+.L_test_for_second_level_dist:
+        /* else if ((op & 64) == 0) {
+         *   this = dcode[this.val + (hold & mask[op])];
+         * }
+         */
+        testb   $64, %al
+        jnz     .L_invalid_distance_code  /* if ((op & 64) != 0) */
+
+        movl    $1, %eax
+        shll    %cl, %eax
+        decl    %eax
+        andl    hold_r, %eax            /* eax &= hold */
+        addl    %edx, %eax              /* eax += this.val */
+        movl    dcode(%esp), %edx       /* edx = dcode */
+        movl    (%edx,%eax,4), %eax     /* eax = dcode[val + (hold&mask[op])] */
+        jmp     .L_dodist
+
+.align 16,0x90
+.L_clip_window:
+        /* regs: %esi = from, %ebp = hold, %bl = bits, %edi = out, %edx = dist
+         *       %ecx = nbytes
+         *
+         * else {
+         *   if (dist > wsize) {
+         *     invalid distance
+         *   }
+         *   from = window;
+         *   nbytes = dist - nbytes;
+         *   if (write == 0) {
+         *     from += wsize - nbytes;
+         */
+#define nbytes_r %ecx
+        movl    %eax, nbytes_r
+        movl    wsize(%esp), %eax       /* prepare for dist compare */
+        negl    nbytes_r                /* nbytes = -nbytes */
+        movl    window(%esp), from_r    /* from = window */
+
+        cmpl    dist_r, %eax
+        jb      .L_invalid_distance_too_far /* if (dist > wsize) */
+
+        addl    dist_r, nbytes_r        /* nbytes = dist - nbytes */
+        cmpl    $0, write(%esp)
+        jne     .L_wrap_around_window   /* if (write != 0) */
+
+        subl    nbytes_r, %eax
+        addl    %eax, from_r            /* from += wsize - nbytes */
+
+        /* regs: %esi = from, %ebp = hold, %bl = bits, %edi = out, %edx = dist
+         *       %ecx = nbytes, %eax = len
+         *
+         *     if (nbytes < len) {
+         *       len -= nbytes;
+         *       do {
+         *         PUP(out) = PUP(from);
+         *       } while (--nbytes);
+         *       from = out - dist;
+         *     }
+         *   }
+         */
+#define len_r %eax
+        movl    len(%esp), len_r
+        cmpl    nbytes_r, len_r
+        jbe     .L_do_copy1             /* if (nbytes >= len) */
+
+        subl    nbytes_r, len_r         /* len -= nbytes */
+        rep     movsb
+        movl    out_r, from_r
+        subl    dist_r, from_r          /* from = out - dist */
+        jmp     .L_do_copy1
+
+        cmpl    nbytes_r, len_r
+        jbe     .L_do_copy1             /* if (nbytes >= len) */
+
+        subl    nbytes_r, len_r         /* len -= nbytes */
+        rep     movsb
+        movl    out_r, from_r
+        subl    dist_r, from_r          /* from = out - dist */
+        jmp     .L_do_copy1
+
+.L_wrap_around_window:
+        /* regs: %esi = from, %ebp = hold, %bl = bits, %edi = out, %edx = dist
+         *       %ecx = nbytes, %eax = write, %eax = len
+         *
+         *   else if (write < nbytes) {
+         *     from += wsize + write - nbytes;
+         *     nbytes -= write;
+         *     if (nbytes < len) {
+         *       len -= nbytes;
+         *       do {
+         *         PUP(out) = PUP(from);
+         *       } while (--nbytes);
+         *       from = window;
+         *       nbytes = write;
+         *       if (nbytes < len) {
+         *         len -= nbytes;
+         *         do {
+         *           PUP(out) = PUP(from);
+         *         } while(--nbytes);
+         *         from = out - dist;
+         *       }
+         *     }
+         *   }
+         */
+#define write_r %eax
+        movl    write(%esp), write_r
+        cmpl    write_r, nbytes_r
+        jbe     .L_contiguous_in_window /* if (write >= nbytes) */
+
+        addl    wsize(%esp), from_r
+        addl    write_r, from_r
+        subl    nbytes_r, from_r        /* from += wsize + write - nbytes */
+        subl    write_r, nbytes_r       /* nbytes -= write */
+#undef write_r
+
+        movl    len(%esp), len_r
+        cmpl    nbytes_r, len_r
+        jbe     .L_do_copy1             /* if (nbytes >= len) */
+
+        subl    nbytes_r, len_r         /* len -= nbytes */
+        rep     movsb
+        movl    window(%esp), from_r    /* from = window */
+        movl    write(%esp), nbytes_r   /* nbytes = write */
+        cmpl    nbytes_r, len_r
+        jbe     .L_do_copy1             /* if (nbytes >= len) */
+
+        subl    nbytes_r, len_r         /* len -= nbytes */
+        rep     movsb
+        movl    out_r, from_r
+        subl    dist_r, from_r          /* from = out - dist */
+        jmp     .L_do_copy1
+
+.L_contiguous_in_window:
+        /* regs: %esi = from, %ebp = hold, %bl = bits, %edi = out, %edx = dist
+         *       %ecx = nbytes, %eax = write, %eax = len
+         *
+         *   else {
+         *     from += write - nbytes;
+         *     if (nbytes < len) {
+         *       len -= nbytes;
+         *       do {
+         *         PUP(out) = PUP(from);
+         *       } while (--nbytes);
+         *       from = out - dist;
+         *     }
+         *   }
+         */
+#define write_r %eax
+        addl    write_r, from_r
+        subl    nbytes_r, from_r        /* from += write - nbytes */
+#undef write_r
+
+        movl    len(%esp), len_r
+        cmpl    nbytes_r, len_r
+        jbe     .L_do_copy1             /* if (nbytes >= len) */
+
+        subl    nbytes_r, len_r         /* len -= nbytes */
+        rep     movsb
+        movl    out_r, from_r
+        subl    dist_r, from_r          /* from = out - dist */
+
+.L_do_copy1:
+        /* regs: %esi = from, %esi = in, %ebp = hold, %bl = bits, %edi = out
+         *       %eax = len
+         *
+         *     while (len > 0) {
+         *       PUP(out) = PUP(from);
+         *       len--;
+         *     }
+         *   }
+         * } while (in < last && out < end);
+         */
+#undef nbytes_r
+#define in_r %esi
+        movl    len_r, %ecx
+        rep     movsb
+
+        movl    in(%esp), in_r          /* move in back to %esi, toss from */
+        jmp     .L_while_test
+
+#undef len_r
+#undef dist_r
+
+#endif /* NO_MMX || RUN_TIME_MMX */
+
+
+/*** MMX code ***/
+
+#if defined( USE_MMX ) || defined( RUN_TIME_MMX )
+
+.align 32,0x90
+.L_init_mmx:
+        emms
+
+#undef  bits_r
+#undef  bitslong_r
+#define bitslong_r %ebp
+#define hold_mm    %mm0
+        movd    %ebp, hold_mm
+        movl    %ebx, bitslong_r
+
+#define used_mm   %mm1
+#define dmask2_mm %mm2
+#define lmask2_mm %mm3
+#define lmask_mm  %mm4
+#define dmask_mm  %mm5
+#define tmp_mm    %mm6
+
+        movd    lmask(%esp), lmask_mm
+        movq    lmask_mm, lmask2_mm
+        movd    dmask(%esp), dmask_mm
+        movq    dmask_mm, dmask2_mm
+        pxor    used_mm, used_mm
+        movl    lcode(%esp), %ebx       /* ebx = lcode */
+        jmp     .L_do_loop_mmx
+
+.align 32,0x90
+.L_while_test_mmx:
+        /* while (in < last && out < end)
+         */
+        cmpl    out_r, end(%esp)
+        jbe     .L_break_loop           /* if (out >= end) */
+
+        cmpl    in_r, last(%esp)
+        jbe     .L_break_loop
+
+.L_do_loop_mmx:
+        psrlq   used_mm, hold_mm        /* hold_mm >>= last bit length */
+
+        cmpl    $32, bitslong_r
+        ja      .L_get_length_code_mmx  /* if (32 < bits) */
+
+        movd    bitslong_r, tmp_mm
+        movd    (in_r), %mm7
+        addl    $4, in_r
+        psllq   tmp_mm, %mm7
+        addl    $32, bitslong_r
+        por     %mm7, hold_mm           /* hold_mm |= *((uint *)in)++ << bits */
+
+.L_get_length_code_mmx:
+        pand    hold_mm, lmask_mm
+        movd    lmask_mm, %eax
+        movq    lmask2_mm, lmask_mm
+        movl    (%ebx,%eax,4), %eax     /* eax = lcode[hold & lmask] */
+
+.L_dolen_mmx:
+        movzbl  %ah, %ecx               /* ecx = this.bits */
+        movd    %ecx, used_mm
+        subl    %ecx, bitslong_r        /* bits -= this.bits */
+
+        testb   %al, %al
+        jnz     .L_test_for_length_base_mmx /* if (op != 0) 45.7% */
+
+        shrl    $16, %eax               /* output this.val char */
+        stosb
+        jmp     .L_while_test_mmx
+
+.L_test_for_length_base_mmx:
+#define len_r  %edx
+        movl    %eax, len_r             /* len = this */
+        shrl    $16, len_r              /* len = this.val */
+
+        testb   $16, %al
+        jz      .L_test_for_second_level_length_mmx /* if ((op & 16) == 0) 8% */
+        andl    $15, %eax               /* op &= 15 */
+        jz      .L_decode_distance_mmx  /* if (!op) */
+
+        psrlq   used_mm, hold_mm        /* hold_mm >>= last bit length */
+        movd    %eax, used_mm
+        movd    hold_mm, %ecx
+        subl    %eax, bitslong_r
+        andl    .L_mask(,%eax,4), %ecx
+        addl    %ecx, len_r             /* len += hold & mask[op] */
+
+.L_decode_distance_mmx:
+        psrlq   used_mm, hold_mm        /* hold_mm >>= last bit length */
+
+        cmpl    $32, bitslong_r
+        ja      .L_get_dist_code_mmx    /* if (32 < bits) */
+
+        movd    bitslong_r, tmp_mm
+        movd    (in_r), %mm7
+        addl    $4, in_r
+        psllq   tmp_mm, %mm7
+        addl    $32, bitslong_r
+        por     %mm7, hold_mm           /* hold_mm |= *((uint *)in)++ << bits */
+
+.L_get_dist_code_mmx:
+        movl    dcode(%esp), %ebx       /* ebx = dcode */
+        pand    hold_mm, dmask_mm
+        movd    dmask_mm, %eax
+        movq    dmask2_mm, dmask_mm
+        movl    (%ebx,%eax,4), %eax     /* eax = dcode[hold & lmask] */
+
+.L_dodist_mmx:
+#define dist_r %ebx
+        movzbl  %ah, %ecx               /* ecx = this.bits */
+        movl    %eax, dist_r
+        shrl    $16, dist_r             /* dist  = this.val */
+        subl    %ecx, bitslong_r        /* bits -= this.bits */
+        movd    %ecx, used_mm
+
+        testb   $16, %al                /* if ((op & 16) == 0) */
+        jz      .L_test_for_second_level_dist_mmx
+        andl    $15, %eax               /* op &= 15 */
+        jz      .L_check_dist_one_mmx
+
+.L_add_bits_to_dist_mmx:
+        psrlq   used_mm, hold_mm        /* hold_mm >>= last bit length */
+        movd    %eax, used_mm           /* save bit length of current op */
+        movd    hold_mm, %ecx           /* get the next bits on input stream */
+        subl    %eax, bitslong_r        /* bits -= op bits */
+        andl    .L_mask(,%eax,4), %ecx  /* ecx   = hold & mask[op] */
+        addl    %ecx, dist_r            /* dist += hold & mask[op] */
+
+.L_check_window_mmx:
+        movl    in_r, in(%esp)          /* save in so from can use it's reg */
+        movl    out_r, %eax
+        subl    beg(%esp), %eax         /* nbytes = out - beg */
+
+        cmpl    dist_r, %eax
+        jb      .L_clip_window_mmx      /* if (dist > nbytes) 4.2% */
+
+        movl    len_r, %ecx
+        movl    out_r, from_r
+        subl    dist_r, from_r          /* from = out - dist */
+
+        subl    $3, %ecx
+        movb    (from_r), %al
+        movb    %al, (out_r)
+        movb    1(from_r), %al
+        movb    2(from_r), %dl
+        addl    $3, from_r
+        movb    %al, 1(out_r)
+        movb    %dl, 2(out_r)
+        addl    $3, out_r
+        rep     movsb
+
+        movl    in(%esp), in_r          /* move in back to %esi, toss from */
+        movl    lcode(%esp), %ebx       /* move lcode back to %ebx, toss dist */
+        jmp     .L_while_test_mmx
+
+.align 16,0x90
+.L_check_dist_one_mmx:
+        cmpl    $1, dist_r
+        jne     .L_check_window_mmx
+        cmpl    out_r, beg(%esp)
+        je      .L_check_window_mmx
+
+        decl    out_r
+        movl    len_r, %ecx
+        movb    (out_r), %al
+        subl    $3, %ecx
+
+        movb    %al, 1(out_r)
+        movb    %al, 2(out_r)
+        movb    %al, 3(out_r)
+        addl    $4, out_r
+        rep     stosb
+
+        movl    lcode(%esp), %ebx       /* move lcode back to %ebx, toss dist */
+        jmp     .L_while_test_mmx
+
+.align 16,0x90
+.L_test_for_second_level_length_mmx:
+        testb   $64, %al
+        jnz     .L_test_for_end_of_block  /* if ((op & 64) != 0) */
+
+        andl    $15, %eax
+        psrlq   used_mm, hold_mm        /* hold_mm >>= last bit length */
+        movd    hold_mm, %ecx
+        andl    .L_mask(,%eax,4), %ecx
+        addl    len_r, %ecx
+        movl    (%ebx,%ecx,4), %eax     /* eax = lcode[hold & lmask] */
+        jmp     .L_dolen_mmx
+
+.align 16,0x90
+.L_test_for_second_level_dist_mmx:
+        testb   $64, %al
+        jnz     .L_invalid_distance_code  /* if ((op & 64) != 0) */
+
+        andl    $15, %eax
+        psrlq   used_mm, hold_mm        /* hold_mm >>= last bit length */
+        movd    hold_mm, %ecx
+        andl    .L_mask(,%eax,4), %ecx
+        movl    dcode(%esp), %eax       /* ecx = dcode */
+        addl    dist_r, %ecx
+        movl    (%eax,%ecx,4), %eax     /* eax = lcode[hold & lmask] */
+        jmp     .L_dodist_mmx
+
+.align 16,0x90
+.L_clip_window_mmx:
+#define nbytes_r %ecx
+        movl    %eax, nbytes_r
+        movl    wsize(%esp), %eax       /* prepare for dist compare */
+        negl    nbytes_r                /* nbytes = -nbytes */
+        movl    window(%esp), from_r    /* from = window */
+
+        cmpl    dist_r, %eax
+        jb      .L_invalid_distance_too_far /* if (dist > wsize) */
+
+        addl    dist_r, nbytes_r        /* nbytes = dist - nbytes */
+        cmpl    $0, write(%esp)
+        jne     .L_wrap_around_window_mmx /* if (write != 0) */
+
+        subl    nbytes_r, %eax
+        addl    %eax, from_r            /* from += wsize - nbytes */
+
+        cmpl    nbytes_r, len_r
+        jbe     .L_do_copy1_mmx         /* if (nbytes >= len) */
+
+        subl    nbytes_r, len_r         /* len -= nbytes */
+        rep     movsb
+        movl    out_r, from_r
+        subl    dist_r, from_r          /* from = out - dist */
+        jmp     .L_do_copy1_mmx
+
+        cmpl    nbytes_r, len_r
+        jbe     .L_do_copy1_mmx         /* if (nbytes >= len) */
+
+        subl    nbytes_r, len_r         /* len -= nbytes */
+        rep     movsb
+        movl    out_r, from_r
+        subl    dist_r, from_r          /* from = out - dist */
+        jmp     .L_do_copy1_mmx
+
+.L_wrap_around_window_mmx:
+#define write_r %eax
+        movl    write(%esp), write_r
+        cmpl    write_r, nbytes_r
+        jbe     .L_contiguous_in_window_mmx /* if (write >= nbytes) */
+
+        addl    wsize(%esp), from_r
+        addl    write_r, from_r
+        subl    nbytes_r, from_r        /* from += wsize + write - nbytes */
+        subl    write_r, nbytes_r       /* nbytes -= write */
+#undef write_r
+
+        cmpl    nbytes_r, len_r
+        jbe     .L_do_copy1_mmx         /* if (nbytes >= len) */
+
+        subl    nbytes_r, len_r         /* len -= nbytes */
+        rep     movsb
+        movl    window(%esp), from_r    /* from = window */
+        movl    write(%esp), nbytes_r   /* nbytes = write */
+        cmpl    nbytes_r, len_r
+        jbe     .L_do_copy1_mmx         /* if (nbytes >= len) */
+
+        subl    nbytes_r, len_r         /* len -= nbytes */
+        rep     movsb
+        movl    out_r, from_r
+        subl    dist_r, from_r          /* from = out - dist */
+        jmp     .L_do_copy1_mmx
+
+.L_contiguous_in_window_mmx:
+#define write_r %eax
+        addl    write_r, from_r
+        subl    nbytes_r, from_r        /* from += write - nbytes */
+#undef write_r
+
+        cmpl    nbytes_r, len_r
+        jbe     .L_do_copy1_mmx         /* if (nbytes >= len) */
+
+        subl    nbytes_r, len_r         /* len -= nbytes */
+        rep     movsb
+        movl    out_r, from_r
+        subl    dist_r, from_r          /* from = out - dist */
+
+.L_do_copy1_mmx:
+#undef nbytes_r
+#define in_r %esi
+        movl    len_r, %ecx
+        rep     movsb
+
+        movl    in(%esp), in_r          /* move in back to %esi, toss from */
+        movl    lcode(%esp), %ebx       /* move lcode back to %ebx, toss dist */
+        jmp     .L_while_test_mmx
+
+#undef hold_r
+#undef bitslong_r
+
+#endif /* USE_MMX || RUN_TIME_MMX */
+
+
+/*** USE_MMX, NO_MMX, and RUNTIME_MMX from here on ***/
+
+.L_invalid_distance_code:
+        /* else {
+         *   strm->msg = "invalid distance code";
+         *   state->mode = BAD;
+         * }
+         */
+        movl    $.L_invalid_distance_code_msg, %ecx
+        movl    $INFLATE_MODE_BAD, %edx
+        jmp     .L_update_stream_state
+
+.L_test_for_end_of_block:
+        /* else if (op & 32) {
+         *   state->mode = TYPE;
+         *   break;
+         * }
+         */
+        testb   $32, %al
+        jz      .L_invalid_literal_length_code  /* if ((op & 32) == 0) */
+
+        movl    $0, %ecx
+        movl    $INFLATE_MODE_TYPE, %edx
+        jmp     .L_update_stream_state
+
+.L_invalid_literal_length_code:
+        /* else {
+         *   strm->msg = "invalid literal/length code";
+         *   state->mode = BAD;
+         * }
+         */
+        movl    $.L_invalid_literal_length_code_msg, %ecx
+        movl    $INFLATE_MODE_BAD, %edx
+        jmp     .L_update_stream_state
+
+.L_invalid_distance_too_far:
+        /* strm->msg = "invalid distance too far back";
+         * state->mode = BAD;
+         */
+        movl    in(%esp), in_r          /* from_r has in's reg, put in back */
+        movl    $.L_invalid_distance_too_far_msg, %ecx
+        movl    $INFLATE_MODE_BAD, %edx
+        jmp     .L_update_stream_state
+
+.L_update_stream_state:
+        /* set strm->msg = %ecx, strm->state->mode = %edx */
+        movl    strm_sp(%esp), %eax
+        testl   %ecx, %ecx              /* if (msg != NULL) */
+        jz      .L_skip_msg
+        movl    %ecx, msg_strm(%eax)    /* strm->msg = msg */
+.L_skip_msg:
+        movl    state_strm(%eax), %eax  /* state = strm->state */
+        movl    %edx, mode_state(%eax)  /* state->mode = edx (BAD | TYPE) */
+        jmp     .L_break_loop
+
+.align 32,0x90
+.L_break_loop:
+
+/*
+ * Regs:
+ *
+ * bits = %ebp when mmx, and in %ebx when non-mmx
+ * hold = %hold_mm when mmx, and in %ebp when non-mmx
+ * in   = %esi
+ * out  = %edi
+ */
+
+#if defined( USE_MMX ) || defined( RUN_TIME_MMX )
+
+#if defined( RUN_TIME_MMX )
+
+        cmpl    $DO_USE_MMX, inflate_fast_use_mmx
+        jne     .L_update_next_in
+
+#endif /* RUN_TIME_MMX */
+
+        movl    %ebp, %ebx
+
+.L_update_next_in:
+
+#endif
+
+#define strm_r  %eax
+#define state_r %edx
+
+        /* len = bits >> 3;
+         * in -= len;
+         * bits -= len << 3;
+         * hold &= (1U << bits) - 1;
+         * state->hold = hold;
+         * state->bits = bits;
+         * strm->next_in = in;
+         * strm->next_out = out;
+         */
+        movl    strm_sp(%esp), strm_r
+        movl    %ebx, %ecx
+        movl    state_strm(strm_r), state_r
+        shrl    $3, %ecx
+        subl    %ecx, in_r
+        shll    $3, %ecx
+        subl    %ecx, %ebx
+        movl    out_r, next_out_strm(strm_r)
+        movl    %ebx, bits_state(state_r)
+        movl    %ebx, %ecx
+
+        leal    buf(%esp), %ebx
+        cmpl    %ebx, last(%esp)
+        jne     .L_buf_not_used         /* if buf != last */
+
+        subl    %ebx, in_r              /* in -= buf */
+        movl    next_in_strm(strm_r), %ebx
+        movl    %ebx, last(%esp)        /* last = strm->next_in */
+        addl    %ebx, in_r              /* in += strm->next_in */
+        movl    avail_in_strm(strm_r), %ebx
+        subl    $11, %ebx
+        addl    %ebx, last(%esp)    /* last = &strm->next_in[ avail_in - 11 ] */
+
+.L_buf_not_used:
+        movl    in_r, next_in_strm(strm_r)
+
+        movl    $1, %ebx
+        shll    %cl, %ebx
+        decl    %ebx
+
+#if defined( USE_MMX ) || defined( RUN_TIME_MMX )
+
+#if defined( RUN_TIME_MMX )
+
+        cmpl    $DO_USE_MMX, inflate_fast_use_mmx
+        jne     .L_update_hold
+
+#endif /* RUN_TIME_MMX */
+
+        psrlq   used_mm, hold_mm        /* hold_mm >>= last bit length */
+        movd    hold_mm, %ebp
+
+        emms
+
+.L_update_hold:
+
+#endif /* USE_MMX || RUN_TIME_MMX */
+
+        andl    %ebx, %ebp
+        movl    %ebp, hold_state(state_r)
+
+#define last_r %ebx
+
+        /* strm->avail_in = in < last ? 11 + (last - in) : 11 - (in - last) */
+        movl    last(%esp), last_r
+        cmpl    in_r, last_r
+        jbe     .L_last_is_smaller     /* if (in >= last) */
+
+        subl    in_r, last_r           /* last -= in */
+        addl    $11, last_r            /* last += 11 */
+        movl    last_r, avail_in_strm(strm_r)
+        jmp     .L_fixup_out
+.L_last_is_smaller:
+        subl    last_r, in_r           /* in -= last */
+        negl    in_r                   /* in = -in */
+        addl    $11, in_r              /* in += 11 */
+        movl    in_r, avail_in_strm(strm_r)
+
+#undef last_r
+#define end_r %ebx
+
+.L_fixup_out:
+        /* strm->avail_out = out < end ? 257 + (end - out) : 257 - (out - end)*/
+        movl    end(%esp), end_r
+        cmpl    out_r, end_r
+        jbe     .L_end_is_smaller      /* if (out >= end) */
+
+        subl    out_r, end_r           /* end -= out */
+        addl    $257, end_r            /* end += 257 */
+        movl    end_r, avail_out_strm(strm_r)
+        jmp     .L_done
+.L_end_is_smaller:
+        subl    end_r, out_r           /* out -= end */
+        negl    out_r                  /* out = -out */
+        addl    $257, out_r            /* out += 257 */
+        movl    out_r, avail_out_strm(strm_r)
+
+#undef end_r
+#undef strm_r
+#undef state_r
+
+.L_done:
+        addl    $local_var_size, %esp
+        popf
+        popl    %ebx
+        popl    %ebp
+        popl    %esi
+        popl    %edi
+        ret
+
+#if defined( GAS_ELF )
+/* elf info */
+.type inflate_fast,@function
+.size inflate_fast,.-inflate_fast
+#endif
diff --git a/compat/zlib/contrib/iostream/test.cpp b/compat/zlib/contrib/iostream/test.cpp
new file mode 100644
index 0000000..7d265b3
--- /dev/null
+++ b/compat/zlib/contrib/iostream/test.cpp
@@ -0,0 +1,24 @@
+
+#include "zfstream.h"
+
+int main() {
+
+  // Construct a stream object with this filebuffer.  Anything sent
+  // to this stream will go to standard out.
+  gzofstream os( 1, ios::out );
+
+  // This text is getting compressed and sent to stdout.
+  // To prove this, run 'test | zcat'.
+  os << "Hello, Mommy" << endl;
+
+  os << setcompressionlevel( Z_NO_COMPRESSION );
+  os << "hello, hello, hi, ho!" << endl;
+
+  setcompressionlevel( os, Z_DEFAULT_COMPRESSION )
+    << "I'm compressing again" << endl;
+
+  os.close();
+
+  return 0;
+
+}
diff --git a/compat/zlib/contrib/iostream/zfstream.cpp b/compat/zlib/contrib/iostream/zfstream.cpp
new file mode 100644
index 0000000..d0cd85f
--- /dev/null
+++ b/compat/zlib/contrib/iostream/zfstream.cpp
@@ -0,0 +1,329 @@
+
+#include "zfstream.h"
+
+gzfilebuf::gzfilebuf() :
+  file(NULL),
+  mode(0),
+  own_file_descriptor(0)
+{ }
+
+gzfilebuf::~gzfilebuf() {
+
+  sync();
+  if ( own_file_descriptor )
+    close();
+
+}
+
+gzfilebuf *gzfilebuf::open( const char *name,
+                            int io_mode ) {
+
+  if ( is_open() )
+    return NULL;
+
+  char char_mode[10];
+  char *p = char_mode;
+
+  if ( io_mode & ios::in ) {
+    mode = ios::in;
+    *p++ = 'r';
+  } else if ( io_mode & ios::app ) {
+    mode = ios::app;
+    *p++ = 'a';
+  } else {
+    mode = ios::out;
+    *p++ = 'w';
+  }
+
+  if ( io_mode & ios::binary ) {
+    mode |= ios::binary;
+    *p++ = 'b';
+  }
+
+  // Hard code the compression level
+  if ( io_mode & (ios::out|ios::app )) {
+    *p++ = '9';
+  }
+
+  // Put the end-of-string indicator
+  *p = '\0';
+
+  if ( (file = gzopen(name, char_mode)) == NULL )
+    return NULL;
+
+  own_file_descriptor = 1;
+
+  return this;
+
+}
+
+gzfilebuf *gzfilebuf::attach( int file_descriptor,
+                              int io_mode ) {
+
+  if ( is_open() )
+    return NULL;
+
+  char char_mode[10];
+  char *p = char_mode;
+
+  if ( io_mode & ios::in ) {
+    mode = ios::in;
+    *p++ = 'r';
+  } else if ( io_mode & ios::app ) {
+    mode = ios::app;
+    *p++ = 'a';
+  } else {
+    mode = ios::out;
+    *p++ = 'w';
+  }
+
+  if ( io_mode & ios::binary ) {
+    mode |= ios::binary;
+    *p++ = 'b';
+  }
+
+  // Hard code the compression level
+  if ( io_mode & (ios::out|ios::app )) {
+    *p++ = '9';
+  }
+
+  // Put the end-of-string indicator
+  *p = '\0';
+
+  if ( (file = gzdopen(file_descriptor, char_mode)) == NULL )
+    return NULL;
+
+  own_file_descriptor = 0;
+
+  return this;
+
+}
+
+gzfilebuf *gzfilebuf::close() {
+
+  if ( is_open() ) {
+
+    sync();
+    gzclose( file );
+    file = NULL;
+
+  }
+
+  return this;
+
+}
+
+int gzfilebuf::setcompressionlevel( int comp_level ) {
+
+  return gzsetparams(file, comp_level, -2);
+
+}
+
+int gzfilebuf::setcompressionstrategy( int comp_strategy ) {
+
+  return gzsetparams(file, -2, comp_strategy);
+
+}
+
+
+streampos gzfilebuf::seekoff( streamoff off, ios::seek_dir dir, int which ) {
+
+  return streampos(EOF);
+
+}
+
+int gzfilebuf::underflow() {
+
+  // If the file hasn't been opened for reading, error.
+  if ( !is_open() || !(mode & ios::in) )
+    return EOF;
+
+  // if a buffer doesn't exists, allocate one.
+  if ( !base() ) {
+
+    if ( (allocate()) == EOF )
+      return EOF;
+    setp(0,0);
+
+  } else {
+
+    if ( in_avail() )
+      return (unsigned char) *gptr();
+
+    if ( out_waiting() ) {
+      if ( flushbuf() == EOF )
+        return EOF;
+    }
+
+  }
+
+  // Attempt to fill the buffer.
+
+  int result = fillbuf();
+  if ( result == EOF ) {
+    // disable get area
+    setg(0,0,0);
+    return EOF;
+  }
+
+  return (unsigned char) *gptr();
+
+}
+
+int gzfilebuf::overflow( int c ) {
+
+  if ( !is_open() || !(mode & ios::out) )
+    return EOF;
+
+  if ( !base() ) {
+    if ( allocate() == EOF )
+      return EOF;
+    setg(0,0,0);
+  } else {
+    if (in_avail()) {
+        return EOF;
+    }
+    if (out_waiting()) {
+      if (flushbuf() == EOF)
+        return EOF;
+    }
+  }
+
+  int bl = blen();
+  setp( base(), base() + bl);
+
+  if ( c != EOF ) {
+
+    *pptr() = c;
+    pbump(1);
+
+  }
+
+  return 0;
+
+}
+
+int gzfilebuf::sync() {
+
+  if ( !is_open() )
+    return EOF;
+
+  if ( out_waiting() )
+    return flushbuf();
+
+  return 0;
+
+}
+
+int gzfilebuf::flushbuf() {
+
+  int n;
+  char *q;
+
+  q = pbase();
+  n = pptr() - q;
+
+  if ( gzwrite( file, q, n) < n )
+    return EOF;
+
+  setp(0,0);
+
+  return 0;
+
+}
+
+int gzfilebuf::fillbuf() {
+
+  int required;
+  char *p;
+
+  p = base();
+
+  required = blen();
+
+  int t = gzread( file, p, required );
+
+  if ( t <= 0) return EOF;
+
+  setg( base(), base(), base()+t);
+
+  return t;
+
+}
+
+gzfilestream_common::gzfilestream_common() :
+  ios( gzfilestream_common::rdbuf() )
+{ }
+
+gzfilestream_common::~gzfilestream_common()
+{ }
+
+void gzfilestream_common::attach( int fd, int io_mode ) {
+
+  if ( !buffer.attach( fd, io_mode) )
+    clear( ios::failbit | ios::badbit );
+  else
+    clear();
+
+}
+
+void gzfilestream_common::open( const char *name, int io_mode ) {
+
+  if ( !buffer.open( name, io_mode ) )
+    clear( ios::failbit | ios::badbit );
+  else
+    clear();
+
+}
+
+void gzfilestream_common::close() {
+
+  if ( !buffer.close() )
+    clear( ios::failbit | ios::badbit );
+
+}
+
+gzfilebuf *gzfilestream_common::rdbuf()
+{
+  return &buffer;
+}
+
+gzifstream::gzifstream() :
+  ios( gzfilestream_common::rdbuf() )
+{
+  clear( ios::badbit );
+}
+
+gzifstream::gzifstream( const char *name, int io_mode ) :
+  ios( gzfilestream_common::rdbuf() )
+{
+  gzfilestream_common::open( name, io_mode );
+}
+
+gzifstream::gzifstream( int fd, int io_mode ) :
+  ios( gzfilestream_common::rdbuf() )
+{
+  gzfilestream_common::attach( fd, io_mode );
+}
+
+gzifstream::~gzifstream() { }
+
+gzofstream::gzofstream() :
+  ios( gzfilestream_common::rdbuf() )
+{
+  clear( ios::badbit );
+}
+
+gzofstream::gzofstream( const char *name, int io_mode ) :
+  ios( gzfilestream_common::rdbuf() )
+{
+  gzfilestream_common::open( name, io_mode );
+}
+
+gzofstream::gzofstream( int fd, int io_mode ) :
+  ios( gzfilestream_common::rdbuf() )
+{
+  gzfilestream_common::attach( fd, io_mode );
+}
+
+gzofstream::~gzofstream() { }
diff --git a/compat/zlib/contrib/iostream/zfstream.h b/compat/zlib/contrib/iostream/zfstream.h
new file mode 100644
index 0000000..ed79098
--- /dev/null
+++ b/compat/zlib/contrib/iostream/zfstream.h
@@ -0,0 +1,128 @@
+
+#ifndef zfstream_h
+#define zfstream_h
+
+#include <fstream.h>
+#include "zlib.h"
+
+class gzfilebuf : public streambuf {
+
+public:
+
+  gzfilebuf( );
+  virtual ~gzfilebuf();
+
+  gzfilebuf *open( const char *name, int io_mode );
+  gzfilebuf *attach( int file_descriptor, int io_mode );
+  gzfilebuf *close();
+
+  int setcompressionlevel( int comp_level );
+  int setcompressionstrategy( int comp_strategy );
+
+  inline int is_open() const { return (file !=NULL); }
+
+  virtual streampos seekoff( streamoff, ios::seek_dir, int );
+
+  virtual int sync();
+
+protected:
+
+  virtual int underflow();
+  virtual int overflow( int = EOF );
+
+private:
+
+  gzFile file;
+  short mode;
+  short own_file_descriptor;
+
+  int flushbuf();
+  int fillbuf();
+
+};
+
+class gzfilestream_common : virtual public ios {
+
+  friend class gzifstream;
+  friend class gzofstream;
+  friend gzofstream &setcompressionlevel( gzofstream &, int );
+  friend gzofstream &setcompressionstrategy( gzofstream &, int );
+
+public:
+  virtual ~gzfilestream_common();
+
+  void attach( int fd, int io_mode );
+  void open( const char *name, int io_mode );
+  void close();
+
+protected:
+  gzfilestream_common();
+
+private:
+  gzfilebuf *rdbuf();
+
+  gzfilebuf buffer;
+
+};
+
+class gzifstream : public gzfilestream_common, public istream {
+
+public:
+
+  gzifstream();
+  gzifstream( const char *name, int io_mode = ios::in );
+  gzifstream( int fd, int io_mode = ios::in );
+
+  virtual ~gzifstream();
+
+};
+
+class gzofstream : public gzfilestream_common, public ostream {
+
+public:
+
+  gzofstream();
+  gzofstream( const char *name, int io_mode = ios::out );
+  gzofstream( int fd, int io_mode = ios::out );
+
+  virtual ~gzofstream();
+
+};
+
+template<class T> class gzomanip {
+  friend gzofstream &operator<<(gzofstream &, const gzomanip<T> &);
+public:
+  gzomanip(gzofstream &(*f)(gzofstream &, T), T v) : func(f), val(v) { }
+private:
+  gzofstream &(*func)(gzofstream &, T);
+  T val;
+};
+
+template<class T> gzofstream &operator<<(gzofstream &s, const gzomanip<T> &m)
+{
+  return (*m.func)(s, m.val);
+}
+
+inline gzofstream &setcompressionlevel( gzofstream &s, int l )
+{
+  (s.rdbuf())->setcompressionlevel(l);
+  return s;
+}
+
+inline gzofstream &setcompressionstrategy( gzofstream &s, int l )
+{
+  (s.rdbuf())->setcompressionstrategy(l);
+  return s;
+}
+
+inline gzomanip<int> setcompressionlevel(int l)
+{
+  return gzomanip<int>(&setcompressionlevel,l);
+}
+
+inline gzomanip<int> setcompressionstrategy(int l)
+{
+  return gzomanip<int>(&setcompressionstrategy,l);
+}
+
+#endif
diff --git a/compat/zlib/contrib/iostream2/zstream.h b/compat/zlib/contrib/iostream2/zstream.h
new file mode 100644
index 0000000..43d2332
--- /dev/null
+++ b/compat/zlib/contrib/iostream2/zstream.h
@@ -0,0 +1,307 @@
+/*
+ *
+ * Copyright (c) 1997
+ * Christian Michelsen Research AS
+ * Advanced Computing
+ * Fantoftvegen 38, 5036 BERGEN, Norway
+ * http://www.cmr.no
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear
+ * in supporting documentation.  Christian Michelsen Research AS makes no
+ * representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ *
+ */
+
+#ifndef ZSTREAM__H
+#define ZSTREAM__H
+
+/*
+ * zstream.h - C++ interface to the 'zlib' general purpose compression library
+ * $Id: zstream.h 1.1 1997-06-25 12:00:56+02 tyge Exp tyge $
+ */
+
+#include <strstream.h>
+#include <string.h>
+#include <stdio.h>
+#include "zlib.h"
+
+#if defined(_WIN32)
+#   include <fcntl.h>
+#   include <io.h>
+#   define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY)
+#else
+#   define SET_BINARY_MODE(file)
+#endif
+
+class zstringlen {
+public:
+    zstringlen(class izstream&);
+    zstringlen(class ozstream&, const char*);
+    size_t value() const { return val.word; }
+private:
+    struct Val { unsigned char byte; size_t word; } val;
+};
+
+//  ----------------------------- izstream -----------------------------
+
+class izstream
+{
+    public:
+        izstream() : m_fp(0) {}
+        izstream(FILE* fp) : m_fp(0) { open(fp); }
+        izstream(const char* name) : m_fp(0) { open(name); }
+        ~izstream() { close(); }
+
+        /* Opens a gzip (.gz) file for reading.
+         * open() can be used to read a file which is not in gzip format;
+         * in this case read() will directly read from the file without
+         * decompression. errno can be checked to distinguish two error
+         * cases (if errno is zero, the zlib error is Z_MEM_ERROR).
+         */
+        void open(const char* name) {
+            if (m_fp) close();
+            m_fp = ::gzopen(name, "rb");
+        }
+
+        void open(FILE* fp) {
+            SET_BINARY_MODE(fp);
+            if (m_fp) close();
+            m_fp = ::gzdopen(fileno(fp), "rb");
+        }
+
+        /* Flushes all pending input if necessary, closes the compressed file
+         * and deallocates all the (de)compression state. The return value is
+         * the zlib error number (see function error() below).
+         */
+        int close() {
+            int r = ::gzclose(m_fp);
+            m_fp = 0; return r;
+        }
+
+        /* Binary read the given number of bytes from the compressed file.
+         */
+        int read(void* buf, size_t len) {
+            return ::gzread(m_fp, buf, len);
+        }
+
+        /* Returns the error message for the last error which occurred on the
+         * given compressed file. errnum is set to zlib error number. If an
+         * error occurred in the file system and not in the compression library,
+         * errnum is set to Z_ERRNO and the application may consult errno
+         * to get the exact error code.
+         */
+        const char* error(int* errnum) {
+            return ::gzerror(m_fp, errnum);
+        }
+
+        gzFile fp() { return m_fp; }
+
+    private:
+        gzFile m_fp;
+};
+
+/*
+ * Binary read the given (array of) object(s) from the compressed file.
+ * If the input file was not in gzip format, read() copies the objects number
+ * of bytes into the buffer.
+ * returns the number of uncompressed bytes actually read
+ * (0 for end of file, -1 for error).
+ */
+template <class T, class Items>
+inline int read(izstream& zs, T* x, Items items) {
+    return ::gzread(zs.fp(), x, items*sizeof(T));
+}
+
+/*
+ * Binary input with the '>' operator.
+ */
+template <class T>
+inline izstream& operator>(izstream& zs, T& x) {
+    ::gzread(zs.fp(), &x, sizeof(T));
+    return zs;
+}
+
+
+inline zstringlen::zstringlen(izstream& zs) {
+    zs > val.byte;
+    if (val.byte == 255) zs > val.word;
+    else val.word = val.byte;
+}
+
+/*
+ * Read length of string + the string with the '>' operator.
+ */
+inline izstream& operator>(izstream& zs, char* x) {
+    zstringlen len(zs);
+    ::gzread(zs.fp(), x, len.value());
+    x[len.value()] = '\0';
+    return zs;
+}
+
+inline char* read_string(izstream& zs) {
+    zstringlen len(zs);
+    char* x = new char[len.value()+1];
+    ::gzread(zs.fp(), x, len.value());
+    x[len.value()] = '\0';
+    return x;
+}
+
+// ----------------------------- ozstream -----------------------------
+
+class ozstream
+{
+    public:
+        ozstream() : m_fp(0), m_os(0) {
+        }
+        ozstream(FILE* fp, int level = Z_DEFAULT_COMPRESSION)
+            : m_fp(0), m_os(0) {
+            open(fp, level);
+        }
+        ozstream(const char* name, int level = Z_DEFAULT_COMPRESSION)
+            : m_fp(0), m_os(0) {
+            open(name, level);
+        }
+        ~ozstream() {
+            close();
+        }
+
+        /* Opens a gzip (.gz) file for writing.
+         * The compression level parameter should be in 0..9
+         * errno can be checked to distinguish two error cases
+         * (if errno is zero, the zlib error is Z_MEM_ERROR).
+         */
+        void open(const char* name, int level = Z_DEFAULT_COMPRESSION) {
+            char mode[4] = "wb\0";
+            if (level != Z_DEFAULT_COMPRESSION) mode[2] = '0'+level;
+            if (m_fp) close();
+            m_fp = ::gzopen(name, mode);
+        }
+
+        /* open from a FILE pointer.
+         */
+        void open(FILE* fp, int level = Z_DEFAULT_COMPRESSION) {
+            SET_BINARY_MODE(fp);
+            char mode[4] = "wb\0";
+            if (level != Z_DEFAULT_COMPRESSION) mode[2] = '0'+level;
+            if (m_fp) close();
+            m_fp = ::gzdopen(fileno(fp), mode);
+        }
+
+        /* Flushes all pending output if necessary, closes the compressed file
+         * and deallocates all the (de)compression state. The return value is
+         * the zlib error number (see function error() below).
+         */
+        int close() {
+            if (m_os) {
+                ::gzwrite(m_fp, m_os->str(), m_os->pcount());
+                delete[] m_os->str(); delete m_os; m_os = 0;
+            }
+            int r = ::gzclose(m_fp); m_fp = 0; return r;
+        }
+
+        /* Binary write the given number of bytes into the compressed file.
+         */
+        int write(const void* buf, size_t len) {
+            return ::gzwrite(m_fp, (voidp) buf, len);
+        }
+
+        /* Flushes all pending output into the compressed file. The parameter
+         * _flush is as in the deflate() function. The return value is the zlib
+         * error number (see function gzerror below). flush() returns Z_OK if
+         * the flush_ parameter is Z_FINISH and all output could be flushed.
+         * flush() should be called only when strictly necessary because it can
+         * degrade compression.
+         */
+        int flush(int _flush) {
+            os_flush();
+            return ::gzflush(m_fp, _flush);
+        }
+
+        /* Returns the error message for the last error which occurred on the
+         * given compressed file. errnum is set to zlib error number. If an
+         * error occurred in the file system and not in the compression library,
+         * errnum is set to Z_ERRNO and the application may consult errno
+         * to get the exact error code.
+         */
+        const char* error(int* errnum) {
+            return ::gzerror(m_fp, errnum);
+        }
+
+        gzFile fp() { return m_fp; }
+
+        ostream& os() {
+            if (m_os == 0) m_os = new ostrstream;
+            return *m_os;
+        }
+
+        void os_flush() {
+            if (m_os && m_os->pcount()>0) {
+                ostrstream* oss = new ostrstream;
+                oss->fill(m_os->fill());
+                oss->flags(m_os->flags());
+                oss->precision(m_os->precision());
+                oss->width(m_os->width());
+                ::gzwrite(m_fp, m_os->str(), m_os->pcount());
+                delete[] m_os->str(); delete m_os; m_os = oss;
+            }
+        }
+
+    private:
+        gzFile m_fp;
+        ostrstream* m_os;
+};
+
+/*
+ * Binary write the given (array of) object(s) into the compressed file.
+ * returns the number of uncompressed bytes actually written
+ * (0 in case of error).
+ */
+template <class T, class Items>
+inline int write(ozstream& zs, const T* x, Items items) {
+    return ::gzwrite(zs.fp(), (voidp) x, items*sizeof(T));
+}
+
+/*
+ * Binary output with the '<' operator.
+ */
+template <class T>
+inline ozstream& operator<(ozstream& zs, const T& x) {
+    ::gzwrite(zs.fp(), (voidp) &x, sizeof(T));
+    return zs;
+}
+
+inline zstringlen::zstringlen(ozstream& zs, const char* x) {
+    val.byte = 255;  val.word = ::strlen(x);
+    if (val.word < 255) zs < (val.byte = val.word);
+    else zs < val;
+}
+
+/*
+ * Write length of string + the string with the '<' operator.
+ */
+inline ozstream& operator<(ozstream& zs, const char* x) {
+    zstringlen len(zs, x);
+    ::gzwrite(zs.fp(), (voidp) x, len.value());
+    return zs;
+}
+
+#ifdef _MSC_VER
+inline ozstream& operator<(ozstream& zs, char* const& x) {
+    return zs < (const char*) x;
+}
+#endif
+
+/*
+ * Ascii write with the << operator;
+ */
+template <class T>
+inline ostream& operator<<(ozstream& zs, const T& x) {
+    zs.os_flush();
+    return zs.os() << x;
+}
+
+#endif
diff --git a/compat/zlib/contrib/iostream2/zstream_test.cpp b/compat/zlib/contrib/iostream2/zstream_test.cpp
new file mode 100644
index 0000000..6273f62
--- /dev/null
+++ b/compat/zlib/contrib/iostream2/zstream_test.cpp
@@ -0,0 +1,25 @@
+#include "zstream.h"
+#include <math.h>
+#include <stdlib.h>
+#include <iomanip.h>
+
+void main() {
+    char h[256] = "Hello";
+    char* g = "Goodbye";
+    ozstream out("temp.gz");
+    out < "This works well" < h < g;
+    out.close();
+
+    izstream in("temp.gz"); // read it back
+    char *x = read_string(in), *y = new char[256], z[256];
+    in > y > z;
+    in.close();
+    cout << x << endl << y << endl << z << endl;
+
+    out.open("temp.gz"); // try ascii output; zcat temp.gz to see the results
+    out << setw(50) << setfill('#') << setprecision(20) << x << endl << y << endl << z << endl;
+    out << z << endl << y << endl << x << endl;
+    out << 1.1234567890123456789 << endl;
+
+    delete[] x; delete[] y;
+}
diff --git a/compat/zlib/contrib/iostream3/README b/compat/zlib/contrib/iostream3/README
new file mode 100644
index 0000000..f7b319a
--- /dev/null
+++ b/compat/zlib/contrib/iostream3/README
@@ -0,0 +1,35 @@
+These classes provide a C++ stream interface to the zlib library. It allows you
+to do things like:
+
+  gzofstream outf("blah.gz");
+  outf << "These go into the gzip file " << 123 << endl;
+
+It does this by deriving a specialized stream buffer for gzipped files, which is
+the way Stroustrup would have done it. :->
+
+The gzifstream and gzofstream classes were originally written by Kevin Ruland
+and made available in the zlib contrib/iostream directory. The older version still
+compiles under gcc 2.xx, but not under gcc 3.xx, which sparked the development of
+this version.
+
+The new classes are as standard-compliant as possible, closely following the
+approach of the standard library's fstream classes. It compiles under gcc versions
+3.2 and 3.3, but not under gcc 2.xx. This is mainly due to changes in the standard
+library naming scheme. The new version of gzifstream/gzofstream/gzfilebuf differs
+from the previous one in the following respects:
+- added showmanyc
+- added setbuf, with support for unbuffered output via setbuf(0,0)
+- a few bug fixes of stream behavior
+- gzipped output file opened with default compression level instead of maximum level
+- setcompressionlevel()/strategy() members replaced by single setcompression()
+
+The code is provided "as is", with the permission to use, copy, modify, distribute
+and sell it for any purpose without fee.
+
+Ludwig Schwardt
+<schwardt@sun.ac.za>
+
+DSP Lab
+Electrical & Electronic Engineering Department
+University of Stellenbosch
+South Africa
diff --git a/compat/zlib/contrib/iostream3/TODO b/compat/zlib/contrib/iostream3/TODO
new file mode 100644
index 0000000..7032f97
--- /dev/null
+++ b/compat/zlib/contrib/iostream3/TODO
@@ -0,0 +1,17 @@
+Possible upgrades to gzfilebuf:
+
+- The ability to do putback (e.g. putbackfail)
+
+- The ability to seek (zlib supports this, but could be slow/tricky)
+
+- Simultaneous read/write access (does it make sense?)
+
+- Support for ios_base::ate open mode
+
+- Locale support?
+
+- Check public interface to see which calls give problems
+  (due to dependence on library internals)
+
+- Override operator<<(ostream&, gzfilebuf*) to allow direct copying
+  of stream buffer to stream ( i.e. os << is.rdbuf(); )
diff --git a/compat/zlib/contrib/iostream3/test.cc b/compat/zlib/contrib/iostream3/test.cc
new file mode 100644
index 0000000..9423533
--- /dev/null
+++ b/compat/zlib/contrib/iostream3/test.cc
@@ -0,0 +1,50 @@
+/*
+ * Test program for gzifstream and gzofstream
+ *
+ * by Ludwig Schwardt <schwardt@sun.ac.za>
+ * original version by Kevin Ruland <kevin@rodin.wustl.edu>
+ */
+
+#include "zfstream.h"
+#include <iostream>      // for cout
+
+int main() {
+
+  gzofstream outf;
+  gzifstream inf;
+  char buf[80];
+
+  outf.open("test1.txt.gz");
+  outf << "The quick brown fox sidestepped the lazy canine\n"
+       << 1.3 << "\nPlan " << 9 << std::endl;
+  outf.close();
+  std::cout << "Wrote the following message to 'test1.txt.gz' (check with zcat or zless):\n"
+            << "The quick brown fox sidestepped the lazy canine\n"
+            << 1.3 << "\nPlan " << 9 << std::endl;
+
+  std::cout << "\nReading 'test1.txt.gz' (buffered) produces:\n";
+  inf.open("test1.txt.gz");
+  while (inf.getline(buf,80,'\n')) {
+    std::cout << buf << "\t(" << inf.rdbuf()->in_avail() << " chars left in buffer)\n";
+  }
+  inf.close();
+
+  outf.rdbuf()->pubsetbuf(0,0);
+  outf.open("test2.txt.gz");
+  outf << setcompression(Z_NO_COMPRESSION)
+       << "The quick brown fox sidestepped the lazy canine\n"
+       << 1.3 << "\nPlan " << 9 << std::endl;
+  outf.close();
+  std::cout << "\nWrote the same message to 'test2.txt.gz' in uncompressed form";
+
+  std::cout << "\nReading 'test2.txt.gz' (unbuffered) produces:\n";
+  inf.rdbuf()->pubsetbuf(0,0);
+  inf.open("test2.txt.gz");
+  while (inf.getline(buf,80,'\n')) {
+    std::cout << buf << "\t(" << inf.rdbuf()->in_avail() << " chars left in buffer)\n";
+  }
+  inf.close();
+
+  return 0;
+
+}
diff --git a/compat/zlib/contrib/iostream3/zfstream.cc b/compat/zlib/contrib/iostream3/zfstream.cc
new file mode 100644
index 0000000..94eb933
--- /dev/null
+++ b/compat/zlib/contrib/iostream3/zfstream.cc
@@ -0,0 +1,479 @@
+/*
+ * A C++ I/O streams interface to the zlib gz* functions
+ *
+ * by Ludwig Schwardt <schwardt@sun.ac.za>
+ * original version by Kevin Ruland <kevin@rodin.wustl.edu>
+ *
+ * This version is standard-compliant and compatible with gcc 3.x.
+ */
+
+#include "zfstream.h"
+#include <cstring>          // for strcpy, strcat, strlen (mode strings)
+#include <cstdio>           // for BUFSIZ
+
+// Internal buffer sizes (default and "unbuffered" versions)
+#define BIGBUFSIZE BUFSIZ
+#define SMALLBUFSIZE 1
+
+/*****************************************************************************/
+
+// Default constructor
+gzfilebuf::gzfilebuf()
+: file(NULL), io_mode(std::ios_base::openmode(0)), own_fd(false),
+  buffer(NULL), buffer_size(BIGBUFSIZE), own_buffer(true)
+{
+  // No buffers to start with
+  this->disable_buffer();
+}
+
+// Destructor
+gzfilebuf::~gzfilebuf()
+{
+  // Sync output buffer and close only if responsible for file
+  // (i.e. attached streams should be left open at this stage)
+  this->sync();
+  if (own_fd)
+    this->close();
+  // Make sure internal buffer is deallocated
+  this->disable_buffer();
+}
+
+// Set compression level and strategy
+int
+gzfilebuf::setcompression(int comp_level,
+                          int comp_strategy)
+{
+  return gzsetparams(file, comp_level, comp_strategy);
+}
+
+// Open gzipped file
+gzfilebuf*
+gzfilebuf::open(const char *name,
+                std::ios_base::openmode mode)
+{
+  // Fail if file already open
+  if (this->is_open())
+    return NULL;
+  // Don't support simultaneous read/write access (yet)
+  if ((mode & std::ios_base::in) && (mode & std::ios_base::out))
+    return NULL;
+
+  // Build mode string for gzopen and check it [27.8.1.3.2]
+  char char_mode[6] = "\0\0\0\0\0";
+  if (!this->open_mode(mode, char_mode))
+    return NULL;
+
+  // Attempt to open file
+  if ((file = gzopen(name, char_mode)) == NULL)
+    return NULL;
+
+  // On success, allocate internal buffer and set flags
+  this->enable_buffer();
+  io_mode = mode;
+  own_fd = true;
+  return this;
+}
+
+// Attach to gzipped file
+gzfilebuf*
+gzfilebuf::attach(int fd,
+                  std::ios_base::openmode mode)
+{
+  // Fail if file already open
+  if (this->is_open())
+    return NULL;
+  // Don't support simultaneous read/write access (yet)
+  if ((mode & std::ios_base::in) && (mode & std::ios_base::out))
+    return NULL;
+
+  // Build mode string for gzdopen and check it [27.8.1.3.2]
+  char char_mode[6] = "\0\0\0\0\0";
+  if (!this->open_mode(mode, char_mode))
+    return NULL;
+
+  // Attempt to attach to file
+  if ((file = gzdopen(fd, char_mode)) == NULL)
+    return NULL;
+
+  // On success, allocate internal buffer and set flags
+  this->enable_buffer();
+  io_mode = mode;
+  own_fd = false;
+  return this;
+}
+
+// Close gzipped file
+gzfilebuf*
+gzfilebuf::close()
+{
+  // Fail immediately if no file is open
+  if (!this->is_open())
+    return NULL;
+  // Assume success
+  gzfilebuf* retval = this;
+  // Attempt to sync and close gzipped file
+  if (this->sync() == -1)
+    retval = NULL;
+  if (gzclose(file) < 0)
+    retval = NULL;
+  // File is now gone anyway (postcondition [27.8.1.3.8])
+  file = NULL;
+  own_fd = false;
+  // Destroy internal buffer if it exists
+  this->disable_buffer();
+  return retval;
+}
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+// Convert int open mode to mode string
+bool
+gzfilebuf::open_mode(std::ios_base::openmode mode,
+                     char* c_mode) const
+{
+  bool testb = mode & std::ios_base::binary;
+  bool testi = mode & std::ios_base::in;
+  bool testo = mode & std::ios_base::out;
+  bool testt = mode & std::ios_base::trunc;
+  bool testa = mode & std::ios_base::app;
+
+  // Check for valid flag combinations - see [27.8.1.3.2] (Table 92)
+  // Original zfstream hardcoded the compression level to maximum here...
+  // Double the time for less than 1% size improvement seems
+  // excessive though - keeping it at the default level
+  // To change back, just append "9" to the next three mode strings
+  if (!testi && testo && !testt && !testa)
+    strcpy(c_mode, "w");
+  if (!testi && testo && !testt && testa)
+    strcpy(c_mode, "a");
+  if (!testi && testo && testt && !testa)
+    strcpy(c_mode, "w");
+  if (testi && !testo && !testt && !testa)
+    strcpy(c_mode, "r");
+  // No read/write mode yet
+//  if (testi && testo && !testt && !testa)
+//    strcpy(c_mode, "r+");
+//  if (testi && testo && testt && !testa)
+//    strcpy(c_mode, "w+");
+
+  // Mode string should be empty for invalid combination of flags
+  if (strlen(c_mode) == 0)
+    return false;
+  if (testb)
+    strcat(c_mode, "b");
+  return true;
+}
+
+// Determine number of characters in internal get buffer
+std::streamsize
+gzfilebuf::showmanyc()
+{
+  // Calls to underflow will fail if file not opened for reading
+  if (!this->is_open() || !(io_mode & std::ios_base::in))
+    return -1;
+  // Make sure get area is in use
+  if (this->gptr() && (this->gptr() < this->egptr()))
+    return std::streamsize(this->egptr() - this->gptr());
+  else
+    return 0;
+}
+
+// Fill get area from gzipped file
+gzfilebuf::int_type
+gzfilebuf::underflow()
+{
+  // If something is left in the get area by chance, return it
+  // (this shouldn't normally happen, as underflow is only supposed
+  // to be called when gptr >= egptr, but it serves as error check)
+  if (this->gptr() && (this->gptr() < this->egptr()))
+    return traits_type::to_int_type(*(this->gptr()));
+
+  // If the file hasn't been opened for reading, produce error
+  if (!this->is_open() || !(io_mode & std::ios_base::in))
+    return traits_type::eof();
+
+  // Attempt to fill internal buffer from gzipped file
+  // (buffer must be guaranteed to exist...)
+  int bytes_read = gzread(file, buffer, buffer_size);
+  // Indicates error or EOF
+  if (bytes_read <= 0)
+  {
+    // Reset get area
+    this->setg(buffer, buffer, buffer);
+    return traits_type::eof();
+  }
+  // Make all bytes read from file available as get area
+  this->setg(buffer, buffer, buffer + bytes_read);
+
+  // Return next character in get area
+  return traits_type::to_int_type(*(this->gptr()));
+}
+
+// Write put area to gzipped file
+gzfilebuf::int_type
+gzfilebuf::overflow(int_type c)
+{
+  // Determine whether put area is in use
+  if (this->pbase())
+  {
+    // Double-check pointer range
+    if (this->pptr() > this->epptr() || this->pptr() < this->pbase())
+      return traits_type::eof();
+    // Add extra character to buffer if not EOF
+    if (!traits_type::eq_int_type(c, traits_type::eof()))
+    {
+      *(this->pptr()) = traits_type::to_char_type(c);
+      this->pbump(1);
+    }
+    // Number of characters to write to file
+    int bytes_to_write = this->pptr() - this->pbase();
+    // Overflow doesn't fail if nothing is to be written
+    if (bytes_to_write > 0)
+    {
+      // If the file hasn't been opened for writing, produce error
+      if (!this->is_open() || !(io_mode & std::ios_base::out))
+        return traits_type::eof();
+      // If gzipped file won't accept all bytes written to it, fail
+      if (gzwrite(file, this->pbase(), bytes_to_write) != bytes_to_write)
+        return traits_type::eof();
+      // Reset next pointer to point to pbase on success
+      this->pbump(-bytes_to_write);
+    }
+  }
+  // Write extra character to file if not EOF
+  else if (!traits_type::eq_int_type(c, traits_type::eof()))
+  {
+    // If the file hasn't been opened for writing, produce error
+    if (!this->is_open() || !(io_mode & std::ios_base::out))
+      return traits_type::eof();
+    // Impromptu char buffer (allows "unbuffered" output)
+    char_type last_char = traits_type::to_char_type(c);
+    // If gzipped file won't accept this character, fail
+    if (gzwrite(file, &last_char, 1) != 1)
+      return traits_type::eof();
+  }
+
+  // If you got here, you have succeeded (even if c was EOF)
+  // The return value should therefore be non-EOF
+  if (traits_type::eq_int_type(c, traits_type::eof()))
+    return traits_type::not_eof(c);
+  else
+    return c;
+}
+
+// Assign new buffer
+std::streambuf*
+gzfilebuf::setbuf(char_type* p,
+                  std::streamsize n)
+{
+  // First make sure stuff is sync'ed, for safety
+  if (this->sync() == -1)
+    return NULL;
+  // If buffering is turned off on purpose via setbuf(0,0), still allocate one...
+  // "Unbuffered" only really refers to put [27.8.1.4.10], while get needs at
+  // least a buffer of size 1 (very inefficient though, therefore make it bigger?)
+  // This follows from [27.5.2.4.3]/12 (gptr needs to point at something, it seems)
+  if (!p || !n)
+  {
+    // Replace existing buffer (if any) with small internal buffer
+    this->disable_buffer();
+    buffer = NULL;
+    buffer_size = 0;
+    own_buffer = true;
+    this->enable_buffer();
+  }
+  else
+  {
+    // Replace existing buffer (if any) with external buffer
+    this->disable_buffer();
+    buffer = p;
+    buffer_size = n;
+    own_buffer = false;
+    this->enable_buffer();
+  }
+  return this;
+}
+
+// Write put area to gzipped file (i.e. ensures that put area is empty)
+int
+gzfilebuf::sync()
+{
+  return traits_type::eq_int_type(this->overflow(), traits_type::eof()) ? -1 : 0;
+}
+
+/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+
+// Allocate internal buffer
+void
+gzfilebuf::enable_buffer()
+{
+  // If internal buffer required, allocate one
+  if (own_buffer && !buffer)
+  {
+    // Check for buffered vs. "unbuffered"
+    if (buffer_size > 0)
+    {
+      // Allocate internal buffer
+      buffer = new char_type[buffer_size];
+      // Get area starts empty and will be expanded by underflow as need arises
+      this->setg(buffer, buffer, buffer);
+      // Setup entire internal buffer as put area.
+      // The one-past-end pointer actually points to the last element of the buffer,
+      // so that overflow(c) can safely add the extra character c to the sequence.
+      // These pointers remain in place for the duration of the buffer
+      this->setp(buffer, buffer + buffer_size - 1);
+    }
+    else
+    {
+      // Even in "unbuffered" case, (small?) get buffer is still required
+      buffer_size = SMALLBUFSIZE;
+      buffer = new char_type[buffer_size];
+      this->setg(buffer, buffer, buffer);
+      // "Unbuffered" means no put buffer
+      this->setp(0, 0);
+    }
+  }
+  else
+  {
+    // If buffer already allocated, reset buffer pointers just to make sure no
+    // stale chars are lying around
+    this->setg(buffer, buffer, buffer);
+    this->setp(buffer, buffer + buffer_size - 1);
+  }
+}
+
+// Destroy internal buffer
+void
+gzfilebuf::disable_buffer()
+{
+  // If internal buffer exists, deallocate it
+  if (own_buffer && buffer)
+  {
+    // Preserve unbuffered status by zeroing size
+    if (!this->pbase())
+      buffer_size = 0;
+    delete[] buffer;
+    buffer = NULL;
+    this->setg(0, 0, 0);
+    this->setp(0, 0);
+  }
+  else
+  {
+    // Reset buffer pointers to initial state if external buffer exists
+    this->setg(buffer, buffer, buffer);
+    if (buffer)
+      this->setp(buffer, buffer + buffer_size - 1);
+    else
+      this->setp(0, 0);
+  }
+}
+
+/*****************************************************************************/
+
+// Default constructor initializes stream buffer
+gzifstream::gzifstream()
+: std::istream(NULL), sb()
+{ this->init(&sb); }
+
+// Initialize stream buffer and open file
+gzifstream::gzifstream(const char* name,
+                       std::ios_base::openmode mode)
+: std::istream(NULL), sb()
+{
+  this->init(&sb);
+  this->open(name, mode);
+}
+
+// Initialize stream buffer and attach to file
+gzifstream::gzifstream(int fd,
+                       std::ios_base::openmode mode)
+: std::istream(NULL), sb()
+{
+  this->init(&sb);
+  this->attach(fd, mode);
+}
+
+// Open file and go into fail() state if unsuccessful
+void
+gzifstream::open(const char* name,
+                 std::ios_base::openmode mode)
+{
+  if (!sb.open(name, mode | std::ios_base::in))
+    this->setstate(std::ios_base::failbit);
+  else
+    this->clear();
+}
+
+// Attach to file and go into fail() state if unsuccessful
+void
+gzifstream::attach(int fd,
+                   std::ios_base::openmode mode)
+{
+  if (!sb.attach(fd, mode | std::ios_base::in))
+    this->setstate(std::ios_base::failbit);
+  else
+    this->clear();
+}
+
+// Close file
+void
+gzifstream::close()
+{
+  if (!sb.close())
+    this->setstate(std::ios_base::failbit);
+}
+
+/*****************************************************************************/
+
+// Default constructor initializes stream buffer
+gzofstream::gzofstream()
+: std::ostream(NULL), sb()
+{ this->init(&sb); }
+
+// Initialize stream buffer and open file
+gzofstream::gzofstream(const char* name,
+                       std::ios_base::openmode mode)
+: std::ostream(NULL), sb()
+{
+  this->init(&sb);
+  this->open(name, mode);
+}
+
+// Initialize stream buffer and attach to file
+gzofstream::gzofstream(int fd,
+                       std::ios_base::openmode mode)
+: std::ostream(NULL), sb()
+{
+  this->init(&sb);
+  this->attach(fd, mode);
+}
+
+// Open file and go into fail() state if unsuccessful
+void
+gzofstream::open(const char* name,
+                 std::ios_base::openmode mode)
+{
+  if (!sb.open(name, mode | std::ios_base::out))
+    this->setstate(std::ios_base::failbit);
+  else
+    this->clear();
+}
+
+// Attach to file and go into fail() state if unsuccessful
+void
+gzofstream::attach(int fd,
+                   std::ios_base::openmode mode)
+{
+  if (!sb.attach(fd, mode | std::ios_base::out))
+    this->setstate(std::ios_base::failbit);
+  else
+    this->clear();
+}
+
+// Close file
+void
+gzofstream::close()
+{
+  if (!sb.close())
+    this->setstate(std::ios_base::failbit);
+}
diff --git a/compat/zlib/contrib/iostream3/zfstream.h b/compat/zlib/contrib/iostream3/zfstream.h
new file mode 100644
index 0000000..8574479
--- /dev/null
+++ b/compat/zlib/contrib/iostream3/zfstream.h
@@ -0,0 +1,466 @@
+/*
+ * A C++ I/O streams interface to the zlib gz* functions
+ *
+ * by Ludwig Schwardt <schwardt@sun.ac.za>
+ * original version by Kevin Ruland <kevin@rodin.wustl.edu>
+ *
+ * This version is standard-compliant and compatible with gcc 3.x.
+ */
+
+#ifndef ZFSTREAM_H
+#define ZFSTREAM_H
+
+#include <istream>  // not iostream, since we don't need cin/cout
+#include <ostream>
+#include "zlib.h"
+
+/*****************************************************************************/
+
+/**
+ *  @brief  Gzipped file stream buffer class.
+ *
+ *  This class implements basic_filebuf for gzipped files. It doesn't yet support
+ *  seeking (allowed by zlib but slow/limited), putback and read/write access
+ *  (tricky). Otherwise, it attempts to be a drop-in replacement for the standard
+ *  file streambuf.
+*/
+class gzfilebuf : public std::streambuf
+{
+public:
+  //  Default constructor.
+  gzfilebuf();
+
+  //  Destructor.
+  virtual
+  ~gzfilebuf();
+
+  /**
+   *  @brief  Set compression level and strategy on the fly.
+   *  @param  comp_level  Compression level (see zlib.h for allowed values)
+   *  @param  comp_strategy  Compression strategy (see zlib.h for allowed values)
+   *  @return  Z_OK on success, Z_STREAM_ERROR otherwise.
+   *
+   *  Unfortunately, these parameters cannot be modified separately, as the
+   *  previous zfstream version assumed. Since the strategy is seldom changed,
+   *  it can default and setcompression(level) then becomes like the old
+   *  setcompressionlevel(level).
+  */
+  int
+  setcompression(int comp_level,
+                 int comp_strategy = Z_DEFAULT_STRATEGY);
+
+  /**
+   *  @brief  Check if file is open.
+   *  @return  True if file is open.
+  */
+  bool
+  is_open() const { return (file != NULL); }
+
+  /**
+   *  @brief  Open gzipped file.
+   *  @param  name  File name.
+   *  @param  mode  Open mode flags.
+   *  @return  @c this on success, NULL on failure.
+  */
+  gzfilebuf*
+  open(const char* name,
+       std::ios_base::openmode mode);
+
+  /**
+   *  @brief  Attach to already open gzipped file.
+   *  @param  fd  File descriptor.
+   *  @param  mode  Open mode flags.
+   *  @return  @c this on success, NULL on failure.
+  */
+  gzfilebuf*
+  attach(int fd,
+         std::ios_base::openmode mode);
+
+  /**
+   *  @brief  Close gzipped file.
+   *  @return  @c this on success, NULL on failure.
+  */
+  gzfilebuf*
+  close();
+
+protected:
+  /**
+   *  @brief  Convert ios open mode int to mode string used by zlib.
+   *  @return  True if valid mode flag combination.
+  */
+  bool
+  open_mode(std::ios_base::openmode mode,
+            char* c_mode) const;
+
+  /**
+   *  @brief  Number of characters available in stream buffer.
+   *  @return  Number of characters.
+   *
+   *  This indicates number of characters in get area of stream buffer.
+   *  These characters can be read without accessing the gzipped file.
+  */
+  virtual std::streamsize
+  showmanyc();
+
+  /**
+   *  @brief  Fill get area from gzipped file.
+   *  @return  First character in get area on success, EOF on error.
+   *
+   *  This actually reads characters from gzipped file to stream
+   *  buffer. Always buffered.
+  */
+  virtual int_type
+  underflow();
+
+  /**
+   *  @brief  Write put area to gzipped file.
+   *  @param  c  Extra character to add to buffer contents.
+   *  @return  Non-EOF on success, EOF on error.
+   *
+   *  This actually writes characters in stream buffer to
+   *  gzipped file. With unbuffered output this is done one
+   *  character at a time.
+  */
+  virtual int_type
+  overflow(int_type c = traits_type::eof());
+
+  /**
+   *  @brief  Installs external stream buffer.
+   *  @param  p  Pointer to char buffer.
+   *  @param  n  Size of external buffer.
+   *  @return  @c this on success, NULL on failure.
+   *
+   *  Call setbuf(0,0) to enable unbuffered output.
+  */
+  virtual std::streambuf*
+  setbuf(char_type* p,
+         std::streamsize n);
+
+  /**
+   *  @brief  Flush stream buffer to file.
+   *  @return  0 on success, -1 on error.
+   *
+   *  This calls underflow(EOF) to do the job.
+  */
+  virtual int
+  sync();
+
+//
+// Some future enhancements
+//
+//  virtual int_type uflow();
+//  virtual int_type pbackfail(int_type c = traits_type::eof());
+//  virtual pos_type
+//  seekoff(off_type off,
+//          std::ios_base::seekdir way,
+//          std::ios_base::openmode mode = std::ios_base::in|std::ios_base::out);
+//  virtual pos_type
+//  seekpos(pos_type sp,
+//          std::ios_base::openmode mode = std::ios_base::in|std::ios_base::out);
+
+private:
+  /**
+   *  @brief  Allocate internal buffer.
+   *
+   *  This function is safe to call multiple times. It will ensure
+   *  that a proper internal buffer exists if it is required. If the
+   *  buffer already exists or is external, the buffer pointers will be
+   *  reset to their original state.
+  */
+  void
+  enable_buffer();
+
+  /**
+   *  @brief  Destroy internal buffer.
+   *
+   *  This function is safe to call multiple times. It will ensure
+   *  that the internal buffer is deallocated if it exists. In any
+   *  case, it will also reset the buffer pointers.
+  */
+  void
+  disable_buffer();
+
+  /**
+   *  Underlying file pointer.
+  */
+  gzFile file;
+
+  /**
+   *  Mode in which file was opened.
+  */
+  std::ios_base::openmode io_mode;
+
+  /**
+   *  @brief  True if this object owns file descriptor.
+   *
+   *  This makes the class responsible for closing the file
+   *  upon destruction.
+  */
+  bool own_fd;
+
+  /**
+   *  @brief  Stream buffer.
+   *
+   *  For simplicity this remains allocated on the free store for the
+   *  entire life span of the gzfilebuf object, unless replaced by setbuf.
+  */
+  char_type* buffer;
+
+  /**
+   *  @brief  Stream buffer size.
+   *
+   *  Defaults to system default buffer size (typically 8192 bytes).
+   *  Modified by setbuf.
+  */
+  std::streamsize buffer_size;
+
+  /**
+   *  @brief  True if this object owns stream buffer.
+   *
+   *  This makes the class responsible for deleting the buffer
+   *  upon destruction.
+  */
+  bool own_buffer;
+};
+
+/*****************************************************************************/
+
+/**
+ *  @brief  Gzipped file input stream class.
+ *
+ *  This class implements ifstream for gzipped files. Seeking and putback
+ *  is not supported yet.
+*/
+class gzifstream : public std::istream
+{
+public:
+  //  Default constructor
+  gzifstream();
+
+  /**
+   *  @brief  Construct stream on gzipped file to be opened.
+   *  @param  name  File name.
+   *  @param  mode  Open mode flags (forced to contain ios::in).
+  */
+  explicit
+  gzifstream(const char* name,
+             std::ios_base::openmode mode = std::ios_base::in);
+
+  /**
+   *  @brief  Construct stream on already open gzipped file.
+   *  @param  fd    File descriptor.
+   *  @param  mode  Open mode flags (forced to contain ios::in).
+  */
+  explicit
+  gzifstream(int fd,
+             std::ios_base::openmode mode = std::ios_base::in);
+
+  /**
+   *  Obtain underlying stream buffer.
+  */
+  gzfilebuf*
+  rdbuf() const
+  { return const_cast<gzfilebuf*>(&sb); }
+
+  /**
+   *  @brief  Check if file is open.
+   *  @return  True if file is open.
+  */
+  bool
+  is_open() { return sb.is_open(); }
+
+  /**
+   *  @brief  Open gzipped file.
+   *  @param  name  File name.
+   *  @param  mode  Open mode flags (forced to contain ios::in).
+   *
+   *  Stream will be in state good() if file opens successfully;
+   *  otherwise in state fail(). This differs from the behavior of
+   *  ifstream, which never sets the state to good() and therefore
+   *  won't allow you to reuse the stream for a second file unless
+   *  you manually clear() the state. The choice is a matter of
+   *  convenience.
+  */
+  void
+  open(const char* name,
+       std::ios_base::openmode mode = std::ios_base::in);
+
+  /**
+   *  @brief  Attach to already open gzipped file.
+   *  @param  fd  File descriptor.
+   *  @param  mode  Open mode flags (forced to contain ios::in).
+   *
+   *  Stream will be in state good() if attach succeeded; otherwise
+   *  in state fail().
+  */
+  void
+  attach(int fd,
+         std::ios_base::openmode mode = std::ios_base::in);
+
+  /**
+   *  @brief  Close gzipped file.
+   *
+   *  Stream will be in state fail() if close failed.
+  */
+  void
+  close();
+
+private:
+  /**
+   *  Underlying stream buffer.
+  */
+  gzfilebuf sb;
+};
+
+/*****************************************************************************/
+
+/**
+ *  @brief  Gzipped file output stream class.
+ *
+ *  This class implements ofstream for gzipped files. Seeking and putback
+ *  is not supported yet.
+*/
+class gzofstream : public std::ostream
+{
+public:
+  //  Default constructor
+  gzofstream();
+
+  /**
+   *  @brief  Construct stream on gzipped file to be opened.
+   *  @param  name  File name.
+   *  @param  mode  Open mode flags (forced to contain ios::out).
+  */
+  explicit
+  gzofstream(const char* name,
+             std::ios_base::openmode mode = std::ios_base::out);
+
+  /**
+   *  @brief  Construct stream on already open gzipped file.
+   *  @param  fd    File descriptor.
+   *  @param  mode  Open mode flags (forced to contain ios::out).
+  */
+  explicit
+  gzofstream(int fd,
+             std::ios_base::openmode mode = std::ios_base::out);
+
+  /**
+   *  Obtain underlying stream buffer.
+  */
+  gzfilebuf*
+  rdbuf() const
+  { return const_cast<gzfilebuf*>(&sb); }
+
+  /**
+   *  @brief  Check if file is open.
+   *  @return  True if file is open.
+  */
+  bool
+  is_open() { return sb.is_open(); }
+
+  /**
+   *  @brief  Open gzipped file.
+   *  @param  name  File name.
+   *  @param  mode  Open mode flags (forced to contain ios::out).
+   *
+   *  Stream will be in state good() if file opens successfully;
+   *  otherwise in state fail(). This differs from the behavior of
+   *  ofstream, which never sets the state to good() and therefore
+   *  won't allow you to reuse the stream for a second file unless
+   *  you manually clear() the state. The choice is a matter of
+   *  convenience.
+  */
+  void
+  open(const char* name,
+       std::ios_base::openmode mode = std::ios_base::out);
+
+  /**
+   *  @brief  Attach to already open gzipped file.
+   *  @param  fd  File descriptor.
+   *  @param  mode  Open mode flags (forced to contain ios::out).
+   *
+   *  Stream will be in state good() if attach succeeded; otherwise
+   *  in state fail().
+  */
+  void
+  attach(int fd,
+         std::ios_base::openmode mode = std::ios_base::out);
+
+  /**
+   *  @brief  Close gzipped file.
+   *
+   *  Stream will be in state fail() if close failed.
+  */
+  void
+  close();
+
+private:
+  /**
+   *  Underlying stream buffer.
+  */
+  gzfilebuf sb;
+};
+
+/*****************************************************************************/
+
+/**
+ *  @brief  Gzipped file output stream manipulator class.
+ *
+ *  This class defines a two-argument manipulator for gzofstream. It is used
+ *  as base for the setcompression(int,int) manipulator.
+*/
+template<typename T1, typename T2>
+  class gzomanip2
+  {
+  public:
+    // Allows insertor to peek at internals
+    template <typename Ta, typename Tb>
+      friend gzofstream&
+      operator<<(gzofstream&,
+                 const gzomanip2<Ta,Tb>&);
+
+    // Constructor
+    gzomanip2(gzofstream& (*f)(gzofstream&, T1, T2),
+              T1 v1,
+              T2 v2);
+  private:
+    // Underlying manipulator function
+    gzofstream&
+    (*func)(gzofstream&, T1, T2);
+
+    // Arguments for manipulator function
+    T1 val1;
+    T2 val2;
+  };
+
+/*****************************************************************************/
+
+// Manipulator function thunks through to stream buffer
+inline gzofstream&
+setcompression(gzofstream &gzs, int l, int s = Z_DEFAULT_STRATEGY)
+{
+  (gzs.rdbuf())->setcompression(l, s);
+  return gzs;
+}
+
+// Manipulator constructor stores arguments
+template<typename T1, typename T2>
+  inline
+  gzomanip2<T1,T2>::gzomanip2(gzofstream &(*f)(gzofstream &, T1, T2),
+                              T1 v1,
+                              T2 v2)
+  : func(f), val1(v1), val2(v2)
+  { }
+
+// Insertor applies underlying manipulator function to stream
+template<typename T1, typename T2>
+  inline gzofstream&
+  operator<<(gzofstream& s, const gzomanip2<T1,T2>& m)
+  { return (*m.func)(s, m.val1, m.val2); }
+
+// Insert this onto stream to simplify setting of compression level
+inline gzomanip2<int,int>
+setcompression(int l, int s = Z_DEFAULT_STRATEGY)
+{ return gzomanip2<int,int>(&setcompression, l, s); }
+
+#endif // ZFSTREAM_H
diff --git a/compat/zlib/contrib/masmx64/bld_ml64.bat b/compat/zlib/contrib/masmx64/bld_ml64.bat
new file mode 100644
index 0000000..8f9343d
--- /dev/null
+++ b/compat/zlib/contrib/masmx64/bld_ml64.bat
@@ -0,0 +1,2 @@
+ml64.exe /Flinffasx64 /c /Zi inffasx64.asm
+ml64.exe /Flgvmat64   /c /Zi gvmat64.asm
diff --git a/compat/zlib/contrib/masmx64/gvmat64.asm b/compat/zlib/contrib/masmx64/gvmat64.asm
new file mode 100644
index 0000000..9879c28
--- /dev/null
+++ b/compat/zlib/contrib/masmx64/gvmat64.asm
@@ -0,0 +1,553 @@
+;uInt longest_match_x64(
+;    deflate_state *s,
+;    IPos cur_match);                             /* current match */
+
+; gvmat64.asm -- Asm portion of the optimized longest_match for 32 bits x86_64
+;  (AMD64 on Athlon 64, Opteron, Phenom
+;     and Intel EM64T on Pentium 4 with EM64T, Pentium D, Core 2 Duo, Core I5/I7)
+; Copyright (C) 1995-2010 Jean-loup Gailly, Brian Raiter and Gilles Vollant.
+;
+; File written by Gilles Vollant, by converting to assembly the longest_match
+;  from Jean-loup Gailly in deflate.c of zLib and infoZip zip.
+;
+;  and by taking inspiration on asm686 with masm, optimised assembly code
+;        from Brian Raiter, written 1998
+;
+;  This software is provided 'as-is', without any express or implied
+;  warranty.  In no event will the authors be held liable for any damages
+;  arising from the use of this software.
+;
+;  Permission is granted to anyone to use this software for any purpose,
+;  including commercial applications, and to alter it and redistribute it
+;  freely, subject to the following restrictions:
+;
+;  1. The origin of this software must not be misrepresented; you must not
+;     claim that you wrote the original software. If you use this software
+;     in a product, an acknowledgment in the product documentation would be
+;     appreciated but is not required.
+;  2. Altered source versions must be plainly marked as such, and must not be
+;     misrepresented as being the original software
+;  3. This notice may not be removed or altered from any source distribution.
+;
+;
+;
+;         http://www.zlib.net
+;         http://www.winimage.com/zLibDll
+;         http://www.muppetlabs.com/~breadbox/software/assembly.html
+;
+; to compile this file for infozip Zip, I use option:
+;   ml64.exe /Flgvmat64 /c /Zi /DINFOZIP gvmat64.asm
+;
+; to compile this file for zLib, I use option:
+;   ml64.exe /Flgvmat64 /c /Zi gvmat64.asm
+; Be carrefull to adapt zlib1222add below to your version of zLib
+;   (if you use a version of zLib before 1.0.4 or after 1.2.2.2, change
+;    value of zlib1222add later)
+;
+; This file compile with Microsoft Macro Assembler (x64) for AMD64
+;
+;   ml64.exe is given with Visual Studio 2005/2008/2010 and Windows WDK
+;
+;   (you can get Windows WDK with ml64 for AMD64 from
+;      http://www.microsoft.com/whdc/Devtools/wdk/default.mspx for low price)
+;
+
+
+;uInt longest_match(s, cur_match)
+;    deflate_state *s;
+;    IPos cur_match;                             /* current match */
+.code
+longest_match PROC
+
+
+;LocalVarsSize   equ 88
+ LocalVarsSize   equ 72
+
+; register used : rax,rbx,rcx,rdx,rsi,rdi,r8,r9,r10,r11,r12
+; free register :  r14,r15
+; register can be saved : rsp
+
+ chainlenwmask   equ  rsp + 8 - LocalVarsSize    ; high word: current chain len
+                                                 ; low word: s->wmask
+;window          equ  rsp + xx - LocalVarsSize   ; local copy of s->window ; stored in r10
+;windowbestlen   equ  rsp + xx - LocalVarsSize   ; s->window + bestlen , use r10+r11
+;scanstart       equ  rsp + xx - LocalVarsSize   ; first two bytes of string ; stored in r12w
+;scanend         equ  rsp + xx - LocalVarsSize   ; last two bytes of string use ebx
+;scanalign       equ  rsp + xx - LocalVarsSize   ; dword-misalignment of string r13
+;bestlen         equ  rsp + xx - LocalVarsSize   ; size of best match so far -> r11d
+;scan            equ  rsp + xx - LocalVarsSize   ; ptr to string wanting match -> r9
+IFDEF INFOZIP
+ELSE
+ nicematch       equ  (rsp + 16 - LocalVarsSize) ; a good enough match size
+ENDIF
+
+save_rdi        equ  rsp + 24 - LocalVarsSize
+save_rsi        equ  rsp + 32 - LocalVarsSize
+save_rbx        equ  rsp + 40 - LocalVarsSize
+save_rbp        equ  rsp + 48 - LocalVarsSize
+save_r12        equ  rsp + 56 - LocalVarsSize
+save_r13        equ  rsp + 64 - LocalVarsSize
+;save_r14        equ  rsp + 72 - LocalVarsSize
+;save_r15        equ  rsp + 80 - LocalVarsSize
+
+
+; summary of register usage
+; scanend     ebx
+; scanendw    bx
+; chainlenwmask   edx
+; curmatch    rsi
+; curmatchd   esi
+; windowbestlen   r8
+; scanalign   r9
+; scanalignd  r9d
+; window      r10
+; bestlen     r11
+; bestlend    r11d
+; scanstart   r12d
+; scanstartw  r12w
+; scan        r13
+; nicematch   r14d
+; limit       r15
+; limitd      r15d
+; prev        rcx
+
+;  all the +4 offsets are due to the addition of pending_buf_size (in zlib
+;  in the deflate_state structure since the asm code was first written
+;  (if you compile with zlib 1.0.4 or older, remove the +4).
+;  Note : these value are good with a 8 bytes boundary pack structure
+
+
+    MAX_MATCH           equ     258
+    MIN_MATCH           equ     3
+    MIN_LOOKAHEAD       equ     (MAX_MATCH+MIN_MATCH+1)
+
+
+;;; Offsets for fields in the deflate_state structure. These numbers
+;;; are calculated from the definition of deflate_state, with the
+;;; assumption that the compiler will dword-align the fields. (Thus,
+;;; changing the definition of deflate_state could easily cause this
+;;; program to crash horribly, without so much as a warning at
+;;; compile time. Sigh.)
+
+;  all the +zlib1222add offsets are due to the addition of fields
+;  in zlib in the deflate_state structure since the asm code was first written
+;  (if you compile with zlib 1.0.4 or older, use "zlib1222add equ (-4)").
+;  (if you compile with zlib between 1.0.5 and 1.2.2.1, use "zlib1222add equ 0").
+;  if you compile with zlib 1.2.2.2 or later , use "zlib1222add equ 8").
+
+
+IFDEF INFOZIP
+
+_DATA   SEGMENT
+COMM    window_size:DWORD
+; WMask ; 7fff
+COMM    window:BYTE:010040H
+COMM    prev:WORD:08000H
+; MatchLen : unused
+; PrevMatch : unused
+COMM    strstart:DWORD
+COMM    match_start:DWORD
+; Lookahead : ignore
+COMM    prev_length:DWORD ; PrevLen
+COMM    max_chain_length:DWORD
+COMM    good_match:DWORD
+COMM    nice_match:DWORD
+prev_ad equ OFFSET prev
+window_ad equ OFFSET window
+nicematch equ nice_match
+_DATA ENDS
+WMask equ 07fffh
+
+ELSE
+
+  IFNDEF zlib1222add
+    zlib1222add equ 8
+  ENDIF
+dsWSize         equ 56+zlib1222add+(zlib1222add/2)
+dsWMask         equ 64+zlib1222add+(zlib1222add/2)
+dsWindow        equ 72+zlib1222add
+dsPrev          equ 88+zlib1222add
+dsMatchLen      equ 128+zlib1222add
+dsPrevMatch     equ 132+zlib1222add
+dsStrStart      equ 140+zlib1222add
+dsMatchStart    equ 144+zlib1222add
+dsLookahead     equ 148+zlib1222add
+dsPrevLen       equ 152+zlib1222add
+dsMaxChainLen   equ 156+zlib1222add
+dsGoodMatch     equ 172+zlib1222add
+dsNiceMatch     equ 176+zlib1222add
+
+window_size     equ [ rcx + dsWSize]
+WMask           equ [ rcx + dsWMask]
+window_ad       equ [ rcx + dsWindow]
+prev_ad         equ [ rcx + dsPrev]
+strstart        equ [ rcx + dsStrStart]
+match_start     equ [ rcx + dsMatchStart]
+Lookahead       equ [ rcx + dsLookahead] ; 0ffffffffh on infozip
+prev_length     equ [ rcx + dsPrevLen]
+max_chain_length equ [ rcx + dsMaxChainLen]
+good_match      equ [ rcx + dsGoodMatch]
+nice_match      equ [ rcx + dsNiceMatch]
+ENDIF
+
+; parameter 1 in r8(deflate state s), param 2 in rdx (cur match)
+
+; see http://weblogs.asp.net/oldnewthing/archive/2004/01/14/58579.aspx and
+; http://msdn.microsoft.com/library/en-us/kmarch/hh/kmarch/64bitAMD_8e951dd2-ee77-4728-8702-55ce4b5dd24a.xml.asp
+;
+; All registers must be preserved across the call, except for
+;   rax, rcx, rdx, r8, r9, r10, and r11, which are scratch.
+
+
+
+;;; Save registers that the compiler may be using, and adjust esp to
+;;; make room for our stack frame.
+
+
+;;; Retrieve the function arguments. r8d will hold cur_match
+;;; throughout the entire function. edx will hold the pointer to the
+;;; deflate_state structure during the function's setup (before
+;;; entering the main loop.
+
+; parameter 1 in rcx (deflate_state* s), param 2 in edx -> r8 (cur match)
+
+; this clear high 32 bits of r8, which can be garbage in both r8 and rdx
+
+        mov [save_rdi],rdi
+        mov [save_rsi],rsi
+        mov [save_rbx],rbx
+        mov [save_rbp],rbp
+IFDEF INFOZIP
+        mov r8d,ecx
+ELSE
+        mov r8d,edx
+ENDIF
+        mov [save_r12],r12
+        mov [save_r13],r13
+;        mov [save_r14],r14
+;        mov [save_r15],r15
+
+
+;;; uInt wmask = s->w_mask;
+;;; unsigned chain_length = s->max_chain_length;
+;;; if (s->prev_length >= s->good_match) {
+;;;     chain_length >>= 2;
+;;; }
+
+        mov edi, prev_length
+        mov esi, good_match
+        mov eax, WMask
+        mov ebx, max_chain_length
+        cmp edi, esi
+        jl  LastMatchGood
+        shr ebx, 2
+LastMatchGood:
+
+;;; chainlen is decremented once beforehand so that the function can
+;;; use the sign flag instead of the zero flag for the exit test.
+;;; It is then shifted into the high word, to make room for the wmask
+;;; value, which it will always accompany.
+
+        dec ebx
+        shl ebx, 16
+        or  ebx, eax
+
+;;; on zlib only
+;;; if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;
+
+IFDEF INFOZIP
+        mov [chainlenwmask], ebx
+; on infozip nice_match = [nice_match]
+ELSE
+        mov eax, nice_match
+        mov [chainlenwmask], ebx
+        mov r10d, Lookahead
+        cmp r10d, eax
+        cmovnl r10d, eax
+        mov [nicematch],r10d
+ENDIF
+
+;;; register Bytef *scan = s->window + s->strstart;
+        mov r10, window_ad
+        mov ebp, strstart
+        lea r13, [r10 + rbp]
+
+;;; Determine how many bytes the scan ptr is off from being
+;;; dword-aligned.
+
+         mov r9,r13
+         neg r13
+         and r13,3
+
+;;; IPos limit = s->strstart > (IPos)MAX_DIST(s) ?
+;;;     s->strstart - (IPos)MAX_DIST(s) : NIL;
+IFDEF INFOZIP
+        mov eax,07efah ; MAX_DIST = (WSIZE-MIN_LOOKAHEAD) (0x8000-(3+8+1))
+ELSE
+        mov eax, window_size
+        sub eax, MIN_LOOKAHEAD
+ENDIF
+        xor edi,edi
+        sub ebp, eax
+
+        mov r11d, prev_length
+
+        cmovng ebp,edi
+
+;;; int best_len = s->prev_length;
+
+
+;;; Store the sum of s->window + best_len in esi locally, and in esi.
+
+       lea  rsi,[r10+r11]
+
+;;; register ush scan_start = *(ushf*)scan;
+;;; register ush scan_end   = *(ushf*)(scan+best_len-1);
+;;; Posf *prev = s->prev;
+
+        movzx r12d,word ptr [r9]
+        movzx ebx, word ptr [r9 + r11 - 1]
+
+        mov rdi, prev_ad
+
+;;; Jump into the main loop.
+
+        mov edx, [chainlenwmask]
+
+        cmp bx,word ptr [rsi + r8 - 1]
+        jz  LookupLoopIsZero
+
+LookupLoop1:
+        and r8d, edx
+
+        movzx   r8d, word ptr [rdi + r8*2]
+        cmp r8d, ebp
+        jbe LeaveNow
+        sub edx, 00010000h
+        js  LeaveNow
+
+LoopEntry1:
+        cmp bx,word ptr [rsi + r8 - 1]
+        jz  LookupLoopIsZero
+
+LookupLoop2:
+        and r8d, edx
+
+        movzx   r8d, word ptr [rdi + r8*2]
+        cmp r8d, ebp
+        jbe LeaveNow
+        sub edx, 00010000h
+        js  LeaveNow
+
+LoopEntry2:
+        cmp bx,word ptr [rsi + r8 - 1]
+        jz  LookupLoopIsZero
+
+LookupLoop4:
+        and r8d, edx
+
+        movzx   r8d, word ptr [rdi + r8*2]
+        cmp r8d, ebp
+        jbe LeaveNow
+        sub edx, 00010000h
+        js  LeaveNow
+
+LoopEntry4:
+
+        cmp bx,word ptr [rsi + r8 - 1]
+        jnz LookupLoop1
+        jmp LookupLoopIsZero
+
+
+;;; do {
+;;;     match = s->window + cur_match;
+;;;     if (*(ushf*)(match+best_len-1) != scan_end ||
+;;;         *(ushf*)match != scan_start) continue;
+;;;     [...]
+;;; } while ((cur_match = prev[cur_match & wmask]) > limit
+;;;          && --chain_length != 0);
+;;;
+;;; Here is the inner loop of the function. The function will spend the
+;;; majority of its time in this loop, and majority of that time will
+;;; be spent in the first ten instructions.
+;;;
+;;; Within this loop:
+;;; ebx = scanend
+;;; r8d = curmatch
+;;; edx = chainlenwmask - i.e., ((chainlen << 16) | wmask)
+;;; esi = windowbestlen - i.e., (window + bestlen)
+;;; edi = prev
+;;; ebp = limit
+
+LookupLoop:
+        and r8d, edx
+
+        movzx   r8d, word ptr [rdi + r8*2]
+        cmp r8d, ebp
+        jbe LeaveNow
+        sub edx, 00010000h
+        js  LeaveNow
+
+LoopEntry:
+
+        cmp bx,word ptr [rsi + r8 - 1]
+        jnz LookupLoop1
+LookupLoopIsZero:
+        cmp     r12w, word ptr [r10 + r8]
+        jnz LookupLoop1
+
+
+;;; Store the current value of chainlen.
+        mov [chainlenwmask], edx
+
+;;; Point edi to the string under scrutiny, and esi to the string we
+;;; are hoping to match it up with. In actuality, esi and edi are
+;;; both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and edx is
+;;; initialized to -(MAX_MATCH_8 - scanalign).
+
+        lea rsi,[r8+r10]
+        mov rdx, 0fffffffffffffef8h; -(MAX_MATCH_8)
+        lea rsi, [rsi + r13 + 0108h] ;MAX_MATCH_8]
+        lea rdi, [r9 + r13 + 0108h] ;MAX_MATCH_8]
+
+        prefetcht1 [rsi+rdx]
+        prefetcht1 [rdi+rdx]
+
+
+;;; Test the strings for equality, 8 bytes at a time. At the end,
+;;; adjust rdx so that it is offset to the exact byte that mismatched.
+;;;
+;;; We already know at this point that the first three bytes of the
+;;; strings match each other, and they can be safely passed over before
+;;; starting the compare loop. So what this code does is skip over 0-3
+;;; bytes, as much as necessary in order to dword-align the edi
+;;; pointer. (rsi will still be misaligned three times out of four.)
+;;;
+;;; It should be confessed that this loop usually does not represent
+;;; much of the total running time. Replacing it with a more
+;;; straightforward "rep cmpsb" would not drastically degrade
+;;; performance.
+
+
+LoopCmps:
+        mov rax, [rsi + rdx]
+        xor rax, [rdi + rdx]
+        jnz LeaveLoopCmps
+
+        mov rax, [rsi + rdx + 8]
+        xor rax, [rdi + rdx + 8]
+        jnz LeaveLoopCmps8
+
+
+        mov rax, [rsi + rdx + 8+8]
+        xor rax, [rdi + rdx + 8+8]
+        jnz LeaveLoopCmps16
+
+        add rdx,8+8+8
+
+        jnz short LoopCmps
+        jmp short LenMaximum
+LeaveLoopCmps16: add rdx,8
+LeaveLoopCmps8: add rdx,8
+LeaveLoopCmps:
+
+        test    eax, 0000FFFFh
+        jnz LenLower
+
+        test eax,0ffffffffh
+
+        jnz LenLower32
+
+        add rdx,4
+        shr rax,32
+        or ax,ax
+        jnz LenLower
+
+LenLower32:
+        shr eax,16
+        add rdx,2
+LenLower:   sub al, 1
+        adc rdx, 0
+;;; Calculate the length of the match. If it is longer than MAX_MATCH,
+;;; then automatically accept it as the best possible match and leave.
+
+        lea rax, [rdi + rdx]
+        sub rax, r9
+        cmp eax, MAX_MATCH
+        jge LenMaximum
+
+;;; If the length of the match is not longer than the best match we
+;;; have so far, then forget it and return to the lookup loop.
+;///////////////////////////////////
+
+        cmp eax, r11d
+        jg  LongerMatch
+
+        lea rsi,[r10+r11]
+
+        mov rdi, prev_ad
+        mov edx, [chainlenwmask]
+        jmp LookupLoop
+
+;;;         s->match_start = cur_match;
+;;;         best_len = len;
+;;;         if (len >= nice_match) break;
+;;;         scan_end = *(ushf*)(scan+best_len-1);
+
+LongerMatch:
+        mov r11d, eax
+        mov match_start, r8d
+        cmp eax, [nicematch]
+        jge LeaveNow
+
+        lea rsi,[r10+rax]
+
+        movzx   ebx, word ptr [r9 + rax - 1]
+        mov rdi, prev_ad
+        mov edx, [chainlenwmask]
+        jmp LookupLoop
+
+;;; Accept the current string, with the maximum possible length.
+
+LenMaximum:
+        mov r11d,MAX_MATCH
+        mov match_start, r8d
+
+;;; if ((uInt)best_len <= s->lookahead) return (uInt)best_len;
+;;; return s->lookahead;
+
+LeaveNow:
+IFDEF INFOZIP
+        mov eax,r11d
+ELSE
+        mov eax, Lookahead
+        cmp r11d, eax
+        cmovng eax, r11d
+ENDIF
+
+;;; Restore the stack and return from whence we came.
+
+
+        mov rsi,[save_rsi]
+        mov rdi,[save_rdi]
+        mov rbx,[save_rbx]
+        mov rbp,[save_rbp]
+        mov r12,[save_r12]
+        mov r13,[save_r13]
+;        mov r14,[save_r14]
+;        mov r15,[save_r15]
+
+
+        ret 0
+; please don't remove this string !
+; Your can freely use gvmat64 in any free or commercial app
+; but it is far better don't remove the string in the binary!
+    db     0dh,0ah,"asm686 with masm, optimised assembly code from Brian Raiter, written 1998, converted to amd 64 by Gilles Vollant 2005",0dh,0ah,0
+longest_match   ENDP
+
+match_init PROC
+  ret 0
+match_init ENDP
+
+
+END
diff --git a/compat/zlib/contrib/masmx64/inffas8664.c b/compat/zlib/contrib/masmx64/inffas8664.c
new file mode 100644
index 0000000..e8af06f
--- /dev/null
+++ b/compat/zlib/contrib/masmx64/inffas8664.c
@@ -0,0 +1,186 @@
+/* inffas8664.c is a hand tuned assembler version of inffast.c - fast decoding
+ * version for AMD64 on Windows using Microsoft C compiler
+ *
+ * Copyright (C) 1995-2003 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ *
+ * Copyright (C) 2003 Chris Anderson <christop@charm.net>
+ * Please use the copyright conditions above.
+ *
+ * 2005 - Adaptation to Microsoft C Compiler for AMD64 by Gilles Vollant
+ *
+ * inffas8664.c call function inffas8664fnc in inffasx64.asm
+ *  inffasx64.asm is automatically convert from AMD64 portion of inffas86.c
+ *
+ * Dec-29-2003 -- I added AMD64 inflate asm support.  This version is also
+ * slightly quicker on x86 systems because, instead of using rep movsb to copy
+ * data, it uses rep movsw, which moves data in 2-byte chunks instead of single
+ * bytes.  I've tested the AMD64 code on a Fedora Core 1 + the x86_64 updates
+ * from http://fedora.linux.duke.edu/fc1_x86_64
+ * which is running on an Athlon 64 3000+ / Gigabyte GA-K8VT800M system with
+ * 1GB ram.  The 64-bit version is about 4% faster than the 32-bit version,
+ * when decompressing mozilla-source-1.3.tar.gz.
+ *
+ * Mar-13-2003 -- Most of this is derived from inffast.S which is derived from
+ * the gcc -S output of zlib-1.2.0/inffast.c.  Zlib-1.2.0 is in beta release at
+ * the moment.  I have successfully compiled and tested this code with gcc2.96,
+ * gcc3.2, icc5.0, msvc6.0.  It is very close to the speed of inffast.S
+ * compiled with gcc -DNO_MMX, but inffast.S is still faster on the P3 with MMX
+ * enabled.  I will attempt to merge the MMX code into this version.  Newer
+ * versions of this and inffast.S can be found at
+ * http://www.eetbeetee.com/zlib/ and http://www.charm.net/~christop/zlib/
+ *
+ */
+
+#include <stdio.h>
+#include "zutil.h"
+#include "inftrees.h"
+#include "inflate.h"
+#include "inffast.h"
+
+/* Mark Adler's comments from inffast.c: */
+
+/*
+   Decode literal, length, and distance codes and write out the resulting
+   literal and match bytes until either not enough input or output is
+   available, an end-of-block is encountered, or a data error is encountered.
+   When large enough input and output buffers are supplied to inflate(), for
+   example, a 16K input buffer and a 64K output buffer, more than 95% of the
+   inflate execution time is spent in this routine.
+
+   Entry assumptions:
+
+        state->mode == LEN
+        strm->avail_in >= 6
+        strm->avail_out >= 258
+        start >= strm->avail_out
+        state->bits < 8
+
+   On return, state->mode is one of:
+
+        LEN -- ran out of enough output space or enough available input
+        TYPE -- reached end of block code, inflate() to interpret next block
+        BAD -- error in block data
+
+   Notes:
+
+    - The maximum input bits used by a length/distance pair is 15 bits for the
+      length code, 5 bits for the length extra, 15 bits for the distance code,
+      and 13 bits for the distance extra.  This totals 48 bits, or six bytes.
+      Therefore if strm->avail_in >= 6, then there is enough input to avoid
+      checking for available input while decoding.
+
+    - The maximum bytes that a single length/distance pair can output is 258
+      bytes, which is the maximum length that can be coded.  inflate_fast()
+      requires strm->avail_out >= 258 for each loop to avoid checking for
+      output space.
+ */
+
+
+
+    typedef struct inffast_ar {
+/* 64   32                               x86  x86_64 */
+/* ar offset                              register */
+/*  0    0 */ void *esp;                /* esp save */
+/*  8    4 */ void *ebp;                /* ebp save */
+/* 16    8 */ unsigned char FAR *in;    /* esi rsi  local strm->next_in */
+/* 24   12 */ unsigned char FAR *last;  /*     r9   while in < last */
+/* 32   16 */ unsigned char FAR *out;   /* edi rdi  local strm->next_out */
+/* 40   20 */ unsigned char FAR *beg;   /*          inflate()'s init next_out */
+/* 48   24 */ unsigned char FAR *end;   /*     r10  while out < end */
+/* 56   28 */ unsigned char FAR *window;/*          size of window, wsize!=0 */
+/* 64   32 */ code const FAR *lcode;    /* ebp rbp  local strm->lencode */
+/* 72   36 */ code const FAR *dcode;    /*     r11  local strm->distcode */
+/* 80   40 */ size_t /*unsigned long */hold;       /* edx rdx  local strm->hold */
+/* 88   44 */ unsigned bits;            /* ebx rbx  local strm->bits */
+/* 92   48 */ unsigned wsize;           /*          window size */
+/* 96   52 */ unsigned write;           /*          window write index */
+/*100   56 */ unsigned lmask;           /*     r12  mask for lcode */
+/*104   60 */ unsigned dmask;           /*     r13  mask for dcode */
+/*108   64 */ unsigned len;             /*     r14  match length */
+/*112   68 */ unsigned dist;            /*     r15  match distance */
+/*116   72 */ unsigned status;          /*          set when state chng*/
+    } type_ar;
+#ifdef ASMINF
+
+void inflate_fast(strm, start)
+z_streamp strm;
+unsigned start;         /* inflate()'s starting value for strm->avail_out */
+{
+    struct inflate_state FAR *state;
+    type_ar ar;
+    void inffas8664fnc(struct inffast_ar * par);
+
+
+
+#if (defined( __GNUC__ ) && defined( __amd64__ ) && ! defined( __i386 )) || (defined(_MSC_VER) && defined(_M_AMD64))
+#define PAD_AVAIL_IN 6
+#define PAD_AVAIL_OUT 258
+#else
+#define PAD_AVAIL_IN 5
+#define PAD_AVAIL_OUT 257
+#endif
+
+    /* copy state to local variables */
+    state = (struct inflate_state FAR *)strm->state;
+
+    ar.in = strm->next_in;
+    ar.last = ar.in + (strm->avail_in - PAD_AVAIL_IN);
+    ar.out = strm->next_out;
+    ar.beg = ar.out - (start - strm->avail_out);
+    ar.end = ar.out + (strm->avail_out - PAD_AVAIL_OUT);
+    ar.wsize = state->wsize;
+    ar.write = state->wnext;
+    ar.window = state->window;
+    ar.hold = state->hold;
+    ar.bits = state->bits;
+    ar.lcode = state->lencode;
+    ar.dcode = state->distcode;
+    ar.lmask = (1U << state->lenbits) - 1;
+    ar.dmask = (1U << state->distbits) - 1;
+
+    /* decode literals and length/distances until end-of-block or not enough
+       input data or output space */
+
+    /* align in on 1/2 hold size boundary */
+    while (((size_t)(void *)ar.in & (sizeof(ar.hold) / 2 - 1)) != 0) {
+        ar.hold += (unsigned long)*ar.in++ << ar.bits;
+        ar.bits += 8;
+    }
+
+    inffas8664fnc(&ar);
+
+    if (ar.status > 1) {
+        if (ar.status == 2)
+            strm->msg = "invalid literal/length code";
+        else if (ar.status == 3)
+            strm->msg = "invalid distance code";
+        else
+            strm->msg = "invalid distance too far back";
+        state->mode = BAD;
+    }
+    else if ( ar.status == 1 ) {
+        state->mode = TYPE;
+    }
+
+    /* return unused bytes (on entry, bits < 8, so in won't go too far back) */
+    ar.len = ar.bits >> 3;
+    ar.in -= ar.len;
+    ar.bits -= ar.len << 3;
+    ar.hold &= (1U << ar.bits) - 1;
+
+    /* update state and return */
+    strm->next_in = ar.in;
+    strm->next_out = ar.out;
+    strm->avail_in = (unsigned)(ar.in < ar.last ?
+                                PAD_AVAIL_IN + (ar.last - ar.in) :
+                                PAD_AVAIL_IN - (ar.in - ar.last));
+    strm->avail_out = (unsigned)(ar.out < ar.end ?
+                                 PAD_AVAIL_OUT + (ar.end - ar.out) :
+                                 PAD_AVAIL_OUT - (ar.out - ar.end));
+    state->hold = (unsigned long)ar.hold;
+    state->bits = ar.bits;
+    return;
+}
+
+#endif
diff --git a/compat/zlib/contrib/masmx64/inffasx64.asm b/compat/zlib/contrib/masmx64/inffasx64.asm
new file mode 100644
index 0000000..60a8d89
--- /dev/null
+++ b/compat/zlib/contrib/masmx64/inffasx64.asm
@@ -0,0 +1,396 @@
+; inffasx64.asm is a hand tuned assembler version of inffast.c - fast decoding
+; version for AMD64 on Windows using Microsoft C compiler
+;
+; inffasx64.asm is automatically convert from AMD64 portion of inffas86.c
+; inffasx64.asm is called by inffas8664.c, which contain more info.
+
+
+; to compile this file, I use option
+;   ml64.exe /Flinffasx64 /c /Zi inffasx64.asm
+;   with Microsoft Macro Assembler (x64) for AMD64
+;
+
+; This file compile with Microsoft Macro Assembler (x64) for AMD64
+;
+;   ml64.exe is given with Visual Studio 2005/2008/2010 and Windows WDK
+;
+;   (you can get Windows WDK with ml64 for AMD64 from
+;      http://www.microsoft.com/whdc/Devtools/wdk/default.mspx for low price)
+;
+
+
+.code
+inffas8664fnc PROC
+
+; see http://weblogs.asp.net/oldnewthing/archive/2004/01/14/58579.aspx and
+; http://msdn.microsoft.com/library/en-us/kmarch/hh/kmarch/64bitAMD_8e951dd2-ee77-4728-8702-55ce4b5dd24a.xml.asp
+;
+; All registers must be preserved across the call, except for
+;   rax, rcx, rdx, r8, r-9, r10, and r11, which are scratch.
+
+
+	mov [rsp-8],rsi
+	mov [rsp-16],rdi
+	mov [rsp-24],r12
+	mov [rsp-32],r13
+	mov [rsp-40],r14
+	mov [rsp-48],r15
+	mov [rsp-56],rbx
+
+	mov rax,rcx
+
+	mov	[rax+8], rbp       ; /* save regs rbp and rsp */
+	mov	[rax], rsp
+
+	mov	rsp, rax          ; /* make rsp point to &ar */
+
+	mov	rsi, [rsp+16]      ; /* rsi  = in */
+	mov	rdi, [rsp+32]      ; /* rdi  = out */
+	mov	r9, [rsp+24]       ; /* r9   = last */
+	mov	r10, [rsp+48]      ; /* r10  = end */
+	mov	rbp, [rsp+64]      ; /* rbp  = lcode */
+	mov	r11, [rsp+72]      ; /* r11  = dcode */
+	mov	rdx, [rsp+80]      ; /* rdx  = hold */
+	mov	ebx, [rsp+88]      ; /* ebx  = bits */
+	mov	r12d, [rsp+100]    ; /* r12d = lmask */
+	mov	r13d, [rsp+104]    ; /* r13d = dmask */
+                                          ; /* r14d = len */
+                                          ; /* r15d = dist */
+
+
+	cld
+	cmp	r10, rdi
+	je	L_one_time           ; /* if only one decode left */
+	cmp	r9, rsi
+
+    jne L_do_loop
+
+
+L_one_time:
+	mov	r8, r12           ; /* r8 = lmask */
+	cmp	bl, 32
+	ja	L_get_length_code_one_time
+
+	lodsd                         ; /* eax = *(uint *)in++ */
+	mov	cl, bl            ; /* cl = bits, needs it for shifting */
+	add	bl, 32             ; /* bits += 32 */
+	shl	rax, cl
+	or	rdx, rax          ; /* hold |= *((uint *)in)++ << bits */
+	jmp	L_get_length_code_one_time
+
+ALIGN 4
+L_while_test:
+	cmp	r10, rdi
+	jbe	L_break_loop
+	cmp	r9, rsi
+	jbe	L_break_loop
+
+L_do_loop:
+	mov	r8, r12           ; /* r8 = lmask */
+	cmp	bl, 32
+	ja	L_get_length_code    ; /* if (32 < bits) */
+
+	lodsd                         ; /* eax = *(uint *)in++ */
+	mov	cl, bl            ; /* cl = bits, needs it for shifting */
+	add	bl, 32             ; /* bits += 32 */
+	shl	rax, cl
+	or	rdx, rax          ; /* hold |= *((uint *)in)++ << bits */
+
+L_get_length_code:
+	and	r8, rdx            ; /* r8 &= hold */
+	mov	eax, [rbp+r8*4]  ; /* eax = lcode[hold & lmask] */
+
+	mov	cl, ah            ; /* cl = this.bits */
+	sub	bl, ah            ; /* bits -= this.bits */
+	shr	rdx, cl           ; /* hold >>= this.bits */
+
+	test	al, al
+	jnz	L_test_for_length_base ; /* if (op != 0) 45.7% */
+
+	mov	r8, r12            ; /* r8 = lmask */
+	shr	eax, 16            ; /* output this.val char */
+	stosb
+
+L_get_length_code_one_time:
+	and	r8, rdx            ; /* r8 &= hold */
+	mov	eax, [rbp+r8*4] ; /* eax = lcode[hold & lmask] */
+
+L_dolen:
+	mov	cl, ah            ; /* cl = this.bits */
+	sub	bl, ah            ; /* bits -= this.bits */
+	shr	rdx, cl           ; /* hold >>= this.bits */
+
+	test	al, al
+	jnz	L_test_for_length_base ; /* if (op != 0) 45.7% */
+
+	shr	eax, 16            ; /* output this.val char */
+	stosb
+	jmp	L_while_test
+
+ALIGN 4
+L_test_for_length_base:
+	mov	r14d, eax         ; /* len = this */
+	shr	r14d, 16           ; /* len = this.val */
+	mov	cl, al
+
+	test	al, 16
+	jz	L_test_for_second_level_length ; /* if ((op & 16) == 0) 8% */
+	and	cl, 15             ; /* op &= 15 */
+	jz	L_decode_distance    ; /* if (!op) */
+
+L_add_bits_to_len:
+	sub	bl, cl
+	xor	eax, eax
+	inc	eax
+	shl	eax, cl
+	dec	eax
+	and	eax, edx          ; /* eax &= hold */
+	shr	rdx, cl
+	add	r14d, eax         ; /* len += hold & mask[op] */
+
+L_decode_distance:
+	mov	r8, r13           ; /* r8 = dmask */
+	cmp	bl, 32
+	ja	L_get_distance_code  ; /* if (32 < bits) */
+
+	lodsd                         ; /* eax = *(uint *)in++ */
+	mov	cl, bl            ; /* cl = bits, needs it for shifting */
+	add	bl, 32             ; /* bits += 32 */
+	shl	rax, cl
+	or	rdx, rax          ; /* hold |= *((uint *)in)++ << bits */
+
+L_get_distance_code:
+	and	r8, rdx           ; /* r8 &= hold */
+	mov	eax, [r11+r8*4] ; /* eax = dcode[hold & dmask] */
+
+L_dodist:
+	mov	r15d, eax         ; /* dist = this */
+	shr	r15d, 16           ; /* dist = this.val */
+	mov	cl, ah
+	sub	bl, ah            ; /* bits -= this.bits */
+	shr	rdx, cl           ; /* hold >>= this.bits */
+	mov	cl, al            ; /* cl = this.op */
+
+	test	al, 16             ; /* if ((op & 16) == 0) */
+	jz	L_test_for_second_level_dist
+	and	cl, 15             ; /* op &= 15 */
+	jz	L_check_dist_one
+
+L_add_bits_to_dist:
+	sub	bl, cl
+	xor	eax, eax
+	inc	eax
+	shl	eax, cl
+	dec	eax                 ; /* (1 << op) - 1 */
+	and	eax, edx          ; /* eax &= hold */
+	shr	rdx, cl
+	add	r15d, eax         ; /* dist += hold & ((1 << op) - 1) */
+
+L_check_window:
+	mov	r8, rsi           ; /* save in so from can use it's reg */
+	mov	rax, rdi
+	sub	rax, [rsp+40]      ; /* nbytes = out - beg */
+
+	cmp	eax, r15d
+	jb	L_clip_window        ; /* if (dist > nbytes) 4.2% */
+
+	mov	ecx, r14d         ; /* ecx = len */
+	mov	rsi, rdi
+	sub	rsi, r15          ; /* from = out - dist */
+
+	sar	ecx, 1
+	jnc	L_copy_two           ; /* if len % 2 == 0 */
+
+	rep     movsw
+	mov	al, [rsi]
+	mov	[rdi], al
+	inc	rdi
+
+	mov	rsi, r8           ; /* move in back to %rsi, toss from */
+	jmp	L_while_test
+
+L_copy_two:
+	rep     movsw
+	mov	rsi, r8           ; /* move in back to %rsi, toss from */
+	jmp	L_while_test
+
+ALIGN 4
+L_check_dist_one:
+	cmp	r15d, 1            ; /* if dist 1, is a memset */
+	jne	L_check_window
+	cmp	[rsp+40], rdi      ; /* if out == beg, outside window */
+	je	L_check_window
+
+	mov	ecx, r14d         ; /* ecx = len */
+	mov	al, [rdi-1]
+	mov	ah, al
+
+	sar	ecx, 1
+	jnc	L_set_two
+	mov	[rdi], al
+	inc	rdi
+
+L_set_two:
+	rep     stosw
+	jmp	L_while_test
+
+ALIGN 4
+L_test_for_second_level_length:
+	test	al, 64
+	jnz	L_test_for_end_of_block ; /* if ((op & 64) != 0) */
+
+	xor	eax, eax
+	inc	eax
+	shl	eax, cl
+	dec	eax
+	and	eax, edx         ; /* eax &= hold */
+	add	eax, r14d        ; /* eax += len */
+	mov	eax, [rbp+rax*4] ; /* eax = lcode[val+(hold&mask[op])]*/
+	jmp	L_dolen
+
+ALIGN 4
+L_test_for_second_level_dist:
+	test	al, 64
+	jnz	L_invalid_distance_code ; /* if ((op & 64) != 0) */
+
+	xor	eax, eax
+	inc	eax
+	shl	eax, cl
+	dec	eax
+	and	eax, edx         ; /* eax &= hold */
+	add	eax, r15d        ; /* eax += dist */
+	mov	eax, [r11+rax*4] ; /* eax = dcode[val+(hold&mask[op])]*/
+	jmp	L_dodist
+
+ALIGN 4
+L_clip_window:
+	mov	ecx, eax         ; /* ecx = nbytes */
+	mov	eax, [rsp+92]     ; /* eax = wsize, prepare for dist cmp */
+	neg	ecx                ; /* nbytes = -nbytes */
+
+	cmp	eax, r15d
+	jb	L_invalid_distance_too_far ; /* if (dist > wsize) */
+
+	add	ecx, r15d         ; /* nbytes = dist - nbytes */
+	cmp	dword ptr [rsp+96], 0
+	jne	L_wrap_around_window ; /* if (write != 0) */
+
+	mov	rsi, [rsp+56]     ; /* from  = window */
+	sub	eax, ecx         ; /* eax  -= nbytes */
+	add	rsi, rax         ; /* from += wsize - nbytes */
+
+	mov	eax, r14d        ; /* eax = len */
+	cmp	r14d, ecx
+	jbe	L_do_copy           ; /* if (nbytes >= len) */
+
+	sub	eax, ecx         ; /* eax -= nbytes */
+	rep     movsb
+	mov	rsi, rdi
+	sub	rsi, r15         ; /* from = &out[ -dist ] */
+	jmp	L_do_copy
+
+ALIGN 4
+L_wrap_around_window:
+	mov	eax, [rsp+96]     ; /* eax = write */
+	cmp	ecx, eax
+	jbe	L_contiguous_in_window ; /* if (write >= nbytes) */
+
+	mov	esi, [rsp+92]     ; /* from  = wsize */
+	add	rsi, [rsp+56]     ; /* from += window */
+	add	rsi, rax         ; /* from += write */
+	sub	rsi, rcx         ; /* from -= nbytes */
+	sub	ecx, eax         ; /* nbytes -= write */
+
+	mov	eax, r14d        ; /* eax = len */
+	cmp	eax, ecx
+	jbe	L_do_copy           ; /* if (nbytes >= len) */
+
+	sub	eax, ecx         ; /* len -= nbytes */
+	rep     movsb
+	mov	rsi, [rsp+56]     ; /* from = window */
+	mov	ecx, [rsp+96]     ; /* nbytes = write */
+	cmp	eax, ecx
+	jbe	L_do_copy           ; /* if (nbytes >= len) */
+
+	sub	eax, ecx         ; /* len -= nbytes */
+	rep     movsb
+	mov	rsi, rdi
+	sub	rsi, r15         ; /* from = out - dist */
+	jmp	L_do_copy
+
+ALIGN 4
+L_contiguous_in_window:
+	mov	rsi, [rsp+56]     ; /* rsi = window */
+	add	rsi, rax
+	sub	rsi, rcx         ; /* from += write - nbytes */
+
+	mov	eax, r14d        ; /* eax = len */
+	cmp	eax, ecx
+	jbe	L_do_copy           ; /* if (nbytes >= len) */
+
+	sub	eax, ecx         ; /* len -= nbytes */
+	rep     movsb
+	mov	rsi, rdi
+	sub	rsi, r15         ; /* from = out - dist */
+	jmp	L_do_copy           ; /* if (nbytes >= len) */
+
+ALIGN 4
+L_do_copy:
+	mov	ecx, eax         ; /* ecx = len */
+	rep     movsb
+
+	mov	rsi, r8          ; /* move in back to %esi, toss from */
+	jmp	L_while_test
+
+L_test_for_end_of_block:
+	test	al, 32
+	jz	L_invalid_literal_length_code
+	mov	dword ptr [rsp+116], 1
+	jmp	L_break_loop_with_status
+
+L_invalid_literal_length_code:
+	mov	dword ptr [rsp+116], 2
+	jmp	L_break_loop_with_status
+
+L_invalid_distance_code:
+	mov	dword ptr [rsp+116], 3
+	jmp	L_break_loop_with_status
+
+L_invalid_distance_too_far:
+	mov	dword ptr [rsp+116], 4
+	jmp	L_break_loop_with_status
+
+L_break_loop:
+	mov	dword ptr [rsp+116], 0
+
+L_break_loop_with_status:
+; /* put in, out, bits, and hold back into ar and pop esp */
+	mov	[rsp+16], rsi     ; /* in */
+	mov	[rsp+32], rdi     ; /* out */
+	mov	[rsp+88], ebx     ; /* bits */
+	mov	[rsp+80], rdx     ; /* hold */
+
+	mov	rax, [rsp]       ; /* restore rbp and rsp */
+	mov	rbp, [rsp+8]
+	mov	rsp, rax
+
+
+
+	mov rsi,[rsp-8]
+	mov rdi,[rsp-16]
+	mov r12,[rsp-24]
+	mov r13,[rsp-32]
+	mov r14,[rsp-40]
+	mov r15,[rsp-48]
+	mov rbx,[rsp-56]
+
+    ret 0
+;          :
+;          : "m" (ar)
+;          : "memory", "%rax", "%rbx", "%rcx", "%rdx", "%rsi", "%rdi",
+;            "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15"
+;    );
+
+inffas8664fnc 	ENDP
+;_TEXT	ENDS
+END
diff --git a/compat/zlib/contrib/masmx64/readme.txt b/compat/zlib/contrib/masmx64/readme.txt
new file mode 100644
index 0000000..2da6733
--- /dev/null
+++ b/compat/zlib/contrib/masmx64/readme.txt
@@ -0,0 +1,31 @@
+Summary
+-------
+This directory contains ASM implementations of the functions
+longest_match() and inflate_fast(), for 64 bits x86 (both AMD64 and Intel EM64t),
+for use with Microsoft Macro Assembler (x64) for AMD64 and Microsoft C++ 64 bits.
+
+gvmat64.asm is written by Gilles Vollant (2005), by using Brian Raiter 686/32 bits
+   assembly optimized version from Jean-loup Gailly original longest_match function
+
+inffasx64.asm and inffas8664.c were written by Chris Anderson, by optimizing
+   original function from Mark Adler
+
+Use instructions
+----------------
+Assemble the .asm files using MASM and put the object files into the zlib source
+directory.  You can also get object files here:
+
+     http://www.winimage.com/zLibDll/zlib124_masm_obj.zip
+
+define ASMV and ASMINF in your project. Include inffas8664.c in your source tree,
+and inffasx64.obj and gvmat64.obj as object to link.
+
+
+Build instructions
+------------------
+run bld_64.bat with Microsoft Macro Assembler (x64) for AMD64 (ml64.exe)
+
+ml64.exe is given with Visual Studio 2005, Windows 2003 server DDK
+
+You can get Windows 2003 server DDK with ml64 and cl for AMD64 from
+  http://www.microsoft.com/whdc/devtools/ddk/default.mspx for low price)
diff --git a/compat/zlib/contrib/masmx86/bld_ml32.bat b/compat/zlib/contrib/masmx86/bld_ml32.bat
new file mode 100644
index 0000000..e1b86bf
--- /dev/null
+++ b/compat/zlib/contrib/masmx86/bld_ml32.bat
@@ -0,0 +1,2 @@
+ml /coff /Zi /c /Flmatch686.lst match686.asm
+ml /coff /Zi /c /Flinffas32.lst inffas32.asm
diff --git a/compat/zlib/contrib/masmx86/inffas32.asm b/compat/zlib/contrib/masmx86/inffas32.asm
new file mode 100644
index 0000000..03d20f8
--- /dev/null
+++ b/compat/zlib/contrib/masmx86/inffas32.asm
@@ -0,0 +1,1080 @@
+;/* inffas32.asm is a hand tuned assembler version of inffast.c -- fast decoding
+; *
+; * inffas32.asm is derivated from inffas86.c, with translation of assembly code
+; *
+; * Copyright (C) 1995-2003 Mark Adler
+; * For conditions of distribution and use, see copyright notice in zlib.h
+; *
+; * Copyright (C) 2003 Chris Anderson <christop@charm.net>
+; * Please use the copyright conditions above.
+; *
+; * Mar-13-2003 -- Most of this is derived from inffast.S which is derived from
+; * the gcc -S output of zlib-1.2.0/inffast.c.  Zlib-1.2.0 is in beta release at
+; * the moment.  I have successfully compiled and tested this code with gcc2.96,
+; * gcc3.2, icc5.0, msvc6.0.  It is very close to the speed of inffast.S
+; * compiled with gcc -DNO_MMX, but inffast.S is still faster on the P3 with MMX
+; * enabled.  I will attempt to merge the MMX code into this version.  Newer
+; * versions of this and inffast.S can be found at
+; * http://www.eetbeetee.com/zlib/ and http://www.charm.net/~christop/zlib/
+; *
+; * 2005 : modification by Gilles Vollant
+; */
+; For Visual C++ 4.x and higher and ML 6.x and higher
+;   ml.exe is in directory \MASM611C of Win95 DDK
+;   ml.exe is also distributed in http://www.masm32.com/masmdl.htm
+;    and in VC++2003 toolkit at http://msdn.microsoft.com/visualc/vctoolkit2003/
+;
+;
+;   compile with command line option
+;   ml  /coff /Zi /c /Flinffas32.lst inffas32.asm
+
+;   if you define NO_GZIP (see inflate.h), compile with
+;   ml  /coff /Zi /c /Flinffas32.lst /DNO_GUNZIP inffas32.asm
+
+
+; zlib122sup is 0 fort zlib 1.2.2.1 and lower
+; zlib122sup is 8 fort zlib 1.2.2.2 and more (with addition of dmax and head
+;        in inflate_state in inflate.h)
+zlib1222sup      equ    8
+
+
+IFDEF GUNZIP
+  INFLATE_MODE_TYPE    equ 11
+  INFLATE_MODE_BAD     equ 26
+ELSE
+  IFNDEF NO_GUNZIP
+    INFLATE_MODE_TYPE    equ 11
+    INFLATE_MODE_BAD     equ 26
+  ELSE
+    INFLATE_MODE_TYPE    equ 3
+    INFLATE_MODE_BAD     equ 17
+  ENDIF
+ENDIF
+
+
+; 75 "inffast.S"
+;FILE "inffast.S"
+
+;;;GLOBAL _inflate_fast
+
+;;;SECTION .text
+
+
+
+	.586p
+	.mmx
+
+	name	inflate_fast_x86
+	.MODEL	FLAT
+
+_DATA			segment
+inflate_fast_use_mmx:
+	dd	1
+
+
+_TEXT			segment
+
+
+
+ALIGN 4
+	db	'Fast decoding Code from Chris Anderson'
+	db	0
+
+ALIGN 4
+invalid_literal_length_code_msg:
+	db	'invalid literal/length code'
+	db	0
+
+ALIGN 4
+invalid_distance_code_msg:
+	db	'invalid distance code'
+	db	0
+
+ALIGN 4
+invalid_distance_too_far_msg:
+	db	'invalid distance too far back'
+	db	0
+
+
+ALIGN 4
+inflate_fast_mask:
+dd	0
+dd	1
+dd	3
+dd	7
+dd	15
+dd	31
+dd	63
+dd	127
+dd	255
+dd	511
+dd	1023
+dd	2047
+dd	4095
+dd	8191
+dd	16383
+dd	32767
+dd	65535
+dd	131071
+dd	262143
+dd	524287
+dd	1048575
+dd	2097151
+dd	4194303
+dd	8388607
+dd	16777215
+dd	33554431
+dd	67108863
+dd	134217727
+dd	268435455
+dd	536870911
+dd	1073741823
+dd	2147483647
+dd	4294967295
+
+
+mode_state	 equ	0	;/* state->mode	*/
+wsize_state	 equ	(32+zlib1222sup)	;/* state->wsize */
+write_state	 equ	(36+4+zlib1222sup)	;/* state->write */
+window_state	 equ	(40+4+zlib1222sup)	;/* state->window */
+hold_state	 equ	(44+4+zlib1222sup)	;/* state->hold	*/
+bits_state	 equ	(48+4+zlib1222sup)	;/* state->bits	*/
+lencode_state	 equ	(64+4+zlib1222sup)	;/* state->lencode */
+distcode_state	 equ	(68+4+zlib1222sup)	;/* state->distcode */
+lenbits_state	 equ	(72+4+zlib1222sup)	;/* state->lenbits */
+distbits_state	 equ	(76+4+zlib1222sup)	;/* state->distbits */
+
+
+;;SECTION .text
+; 205 "inffast.S"
+;GLOBAL	inflate_fast_use_mmx
+
+;SECTION .data
+
+
+; GLOBAL inflate_fast_use_mmx:object
+;.size inflate_fast_use_mmx, 4
+; 226 "inffast.S"
+;SECTION .text
+
+ALIGN 4
+_inflate_fast proc near
+.FPO (16, 4, 0, 0, 1, 0)
+	push  edi
+	push  esi
+	push  ebp
+	push  ebx
+	pushfd
+	sub  esp,64
+	cld
+
+
+
+
+	mov  esi, [esp+88]
+	mov  edi, [esi+28]
+
+
+
+
+
+
+
+	mov  edx, [esi+4]
+	mov  eax, [esi+0]
+
+	add  edx,eax
+	sub  edx,11
+
+	mov  [esp+44],eax
+	mov  [esp+20],edx
+
+	mov  ebp, [esp+92]
+	mov  ecx, [esi+16]
+	mov  ebx, [esi+12]
+
+	sub  ebp,ecx
+	neg  ebp
+	add  ebp,ebx
+
+	sub  ecx,257
+	add  ecx,ebx
+
+	mov  [esp+60],ebx
+	mov  [esp+40],ebp
+	mov  [esp+16],ecx
+; 285 "inffast.S"
+	mov  eax, [edi+lencode_state]
+	mov  ecx, [edi+distcode_state]
+
+	mov  [esp+8],eax
+	mov  [esp+12],ecx
+
+	mov  eax,1
+	mov  ecx, [edi+lenbits_state]
+	shl  eax,cl
+	dec  eax
+	mov  [esp+0],eax
+
+	mov  eax,1
+	mov  ecx, [edi+distbits_state]
+	shl  eax,cl
+	dec  eax
+	mov  [esp+4],eax
+
+	mov  eax, [edi+wsize_state]
+	mov  ecx, [edi+write_state]
+	mov  edx, [edi+window_state]
+
+	mov  [esp+52],eax
+	mov  [esp+48],ecx
+	mov  [esp+56],edx
+
+	mov  ebp, [edi+hold_state]
+	mov  ebx, [edi+bits_state]
+; 321 "inffast.S"
+	mov  esi, [esp+44]
+	mov  ecx, [esp+20]
+	cmp  ecx,esi
+	ja   L_align_long
+
+	add  ecx,11
+	sub  ecx,esi
+	mov  eax,12
+	sub  eax,ecx
+	lea  edi, [esp+28]
+	rep movsb
+	mov  ecx,eax
+	xor  eax,eax
+	rep stosb
+	lea  esi, [esp+28]
+	mov  [esp+20],esi
+	jmp  L_is_aligned
+
+
+L_align_long:
+	test  esi,3
+	jz   L_is_aligned
+	xor  eax,eax
+	mov  al, [esi]
+	inc  esi
+	mov  ecx,ebx
+	add  ebx,8
+	shl  eax,cl
+	or  ebp,eax
+	jmp L_align_long
+
+L_is_aligned:
+	mov  edi, [esp+60]
+; 366 "inffast.S"
+L_check_mmx:
+	cmp  dword ptr [inflate_fast_use_mmx],2
+	je   L_init_mmx
+	ja   L_do_loop
+
+	push  eax
+	push  ebx
+	push  ecx
+	push  edx
+	pushfd
+	mov  eax, [esp]
+	xor  dword ptr [esp],0200000h
+
+
+
+
+	popfd
+	pushfd
+	pop  edx
+	xor  edx,eax
+	jz   L_dont_use_mmx
+	xor  eax,eax
+	cpuid
+	cmp  ebx,0756e6547h
+	jne  L_dont_use_mmx
+	cmp  ecx,06c65746eh
+	jne  L_dont_use_mmx
+	cmp  edx,049656e69h
+	jne  L_dont_use_mmx
+	mov  eax,1
+	cpuid
+	shr  eax,8
+	and  eax,15
+	cmp  eax,6
+	jne  L_dont_use_mmx
+	test  edx,0800000h
+	jnz  L_use_mmx
+	jmp  L_dont_use_mmx
+L_use_mmx:
+	mov  dword ptr [inflate_fast_use_mmx],2
+	jmp  L_check_mmx_pop
+L_dont_use_mmx:
+	mov  dword ptr [inflate_fast_use_mmx],3
+L_check_mmx_pop:
+	pop  edx
+	pop  ecx
+	pop  ebx
+	pop  eax
+	jmp  L_check_mmx
+; 426 "inffast.S"
+ALIGN 4
+L_do_loop:
+; 437 "inffast.S"
+	cmp  bl,15
+	ja   L_get_length_code
+
+	xor  eax,eax
+	lodsw
+	mov  cl,bl
+	add  bl,16
+	shl  eax,cl
+	or  ebp,eax
+
+L_get_length_code:
+	mov  edx, [esp+0]
+	mov  ecx, [esp+8]
+	and  edx,ebp
+	mov  eax, [ecx+edx*4]
+
+L_dolen:
+
+
+
+
+
+
+	mov  cl,ah
+	sub  bl,ah
+	shr  ebp,cl
+
+
+
+
+
+
+	test  al,al
+	jnz   L_test_for_length_base
+
+	shr  eax,16
+	stosb
+
+L_while_test:
+
+
+	cmp  [esp+16],edi
+	jbe  L_break_loop
+
+	cmp  [esp+20],esi
+	ja   L_do_loop
+	jmp  L_break_loop
+
+L_test_for_length_base:
+; 502 "inffast.S"
+	mov  edx,eax
+	shr  edx,16
+	mov  cl,al
+
+	test  al,16
+	jz   L_test_for_second_level_length
+	and  cl,15
+	jz   L_save_len
+	cmp  bl,cl
+	jae  L_add_bits_to_len
+
+	mov  ch,cl
+	xor  eax,eax
+	lodsw
+	mov  cl,bl
+	add  bl,16
+	shl  eax,cl
+	or  ebp,eax
+	mov  cl,ch
+
+L_add_bits_to_len:
+	mov  eax,1
+	shl  eax,cl
+	dec  eax
+	sub  bl,cl
+	and  eax,ebp
+	shr  ebp,cl
+	add  edx,eax
+
+L_save_len:
+	mov  [esp+24],edx
+
+
+L_decode_distance:
+; 549 "inffast.S"
+	cmp  bl,15
+	ja   L_get_distance_code
+
+	xor  eax,eax
+	lodsw
+	mov  cl,bl
+	add  bl,16
+	shl  eax,cl
+	or  ebp,eax
+
+L_get_distance_code:
+	mov  edx, [esp+4]
+	mov  ecx, [esp+12]
+	and  edx,ebp
+	mov  eax, [ecx+edx*4]
+
+
+L_dodist:
+	mov  edx,eax
+	shr  edx,16
+	mov  cl,ah
+	sub  bl,ah
+	shr  ebp,cl
+; 584 "inffast.S"
+	mov  cl,al
+
+	test  al,16
+	jz  L_test_for_second_level_dist
+	and  cl,15
+	jz  L_check_dist_one
+	cmp  bl,cl
+	jae  L_add_bits_to_dist
+
+	mov  ch,cl
+	xor  eax,eax
+	lodsw
+	mov  cl,bl
+	add  bl,16
+	shl  eax,cl
+	or  ebp,eax
+	mov  cl,ch
+
+L_add_bits_to_dist:
+	mov  eax,1
+	shl  eax,cl
+	dec  eax
+	sub  bl,cl
+	and  eax,ebp
+	shr  ebp,cl
+	add  edx,eax
+	jmp  L_check_window
+
+L_check_window:
+; 625 "inffast.S"
+	mov  [esp+44],esi
+	mov  eax,edi
+	sub  eax, [esp+40]
+
+	cmp  eax,edx
+	jb   L_clip_window
+
+	mov  ecx, [esp+24]
+	mov  esi,edi
+	sub  esi,edx
+
+	sub  ecx,3
+	mov  al, [esi]
+	mov  [edi],al
+	mov  al, [esi+1]
+	mov  dl, [esi+2]
+	add  esi,3
+	mov  [edi+1],al
+	mov  [edi+2],dl
+	add  edi,3
+	rep movsb
+
+	mov  esi, [esp+44]
+	jmp  L_while_test
+
+ALIGN 4
+L_check_dist_one:
+	cmp  edx,1
+	jne  L_check_window
+	cmp  [esp+40],edi
+	je  L_check_window
+
+	dec  edi
+	mov  ecx, [esp+24]
+	mov  al, [edi]
+	sub  ecx,3
+
+	mov  [edi+1],al
+	mov  [edi+2],al
+	mov  [edi+3],al
+	add  edi,4
+	rep stosb
+
+	jmp  L_while_test
+
+ALIGN 4
+L_test_for_second_level_length:
+
+
+
+
+	test  al,64
+	jnz   L_test_for_end_of_block
+
+	mov  eax,1
+	shl  eax,cl
+	dec  eax
+	and  eax,ebp
+	add  eax,edx
+	mov  edx, [esp+8]
+	mov  eax, [edx+eax*4]
+	jmp  L_dolen
+
+ALIGN 4
+L_test_for_second_level_dist:
+
+
+
+
+	test  al,64
+	jnz   L_invalid_distance_code
+
+	mov  eax,1
+	shl  eax,cl
+	dec  eax
+	and  eax,ebp
+	add  eax,edx
+	mov  edx, [esp+12]
+	mov  eax, [edx+eax*4]
+	jmp  L_dodist
+
+ALIGN 4
+L_clip_window:
+; 721 "inffast.S"
+	mov  ecx,eax
+	mov  eax, [esp+52]
+	neg  ecx
+	mov  esi, [esp+56]
+
+	cmp  eax,edx
+	jb   L_invalid_distance_too_far
+
+	add  ecx,edx
+	cmp  dword ptr [esp+48],0
+	jne  L_wrap_around_window
+
+	sub  eax,ecx
+	add  esi,eax
+; 749 "inffast.S"
+	mov  eax, [esp+24]
+	cmp  eax,ecx
+	jbe  L_do_copy1
+
+	sub  eax,ecx
+	rep movsb
+	mov  esi,edi
+	sub  esi,edx
+	jmp  L_do_copy1
+
+	cmp  eax,ecx
+	jbe  L_do_copy1
+
+	sub  eax,ecx
+	rep movsb
+	mov  esi,edi
+	sub  esi,edx
+	jmp  L_do_copy1
+
+L_wrap_around_window:
+; 793 "inffast.S"
+	mov  eax, [esp+48]
+	cmp  ecx,eax
+	jbe  L_contiguous_in_window
+
+	add  esi, [esp+52]
+	add  esi,eax
+	sub  esi,ecx
+	sub  ecx,eax
+
+
+	mov  eax, [esp+24]
+	cmp  eax,ecx
+	jbe  L_do_copy1
+
+	sub  eax,ecx
+	rep movsb
+	mov  esi, [esp+56]
+	mov  ecx, [esp+48]
+	cmp  eax,ecx
+	jbe  L_do_copy1
+
+	sub  eax,ecx
+	rep movsb
+	mov  esi,edi
+	sub  esi,edx
+	jmp  L_do_copy1
+
+L_contiguous_in_window:
+; 836 "inffast.S"
+	add  esi,eax
+	sub  esi,ecx
+
+
+	mov  eax, [esp+24]
+	cmp  eax,ecx
+	jbe  L_do_copy1
+
+	sub  eax,ecx
+	rep movsb
+	mov  esi,edi
+	sub  esi,edx
+
+L_do_copy1:
+; 862 "inffast.S"
+	mov  ecx,eax
+	rep movsb
+
+	mov  esi, [esp+44]
+	jmp  L_while_test
+; 878 "inffast.S"
+ALIGN 4
+L_init_mmx:
+	emms
+
+
+
+
+
+	movd mm0,ebp
+	mov  ebp,ebx
+; 896 "inffast.S"
+	movd mm4,dword ptr [esp+0]
+	movq mm3,mm4
+	movd mm5,dword ptr [esp+4]
+	movq mm2,mm5
+	pxor mm1,mm1
+	mov  ebx, [esp+8]
+	jmp  L_do_loop_mmx
+
+ALIGN 4
+L_do_loop_mmx:
+	psrlq mm0,mm1
+
+	cmp  ebp,32
+	ja  L_get_length_code_mmx
+
+	movd mm6,ebp
+	movd mm7,dword ptr [esi]
+	add  esi,4
+	psllq mm7,mm6
+	add  ebp,32
+	por mm0,mm7
+
+L_get_length_code_mmx:
+	pand mm4,mm0
+	movd eax,mm4
+	movq mm4,mm3
+	mov  eax, [ebx+eax*4]
+
+L_dolen_mmx:
+	movzx  ecx,ah
+	movd mm1,ecx
+	sub  ebp,ecx
+
+	test  al,al
+	jnz L_test_for_length_base_mmx
+
+	shr  eax,16
+	stosb
+
+L_while_test_mmx:
+
+
+	cmp  [esp+16],edi
+	jbe L_break_loop
+
+	cmp  [esp+20],esi
+	ja L_do_loop_mmx
+	jmp L_break_loop
+
+L_test_for_length_base_mmx:
+
+	mov  edx,eax
+	shr  edx,16
+
+	test  al,16
+	jz  L_test_for_second_level_length_mmx
+	and  eax,15
+	jz L_decode_distance_mmx
+
+	psrlq mm0,mm1
+	movd mm1,eax
+	movd ecx,mm0
+	sub  ebp,eax
+	and  ecx, [inflate_fast_mask+eax*4]
+	add  edx,ecx
+
+L_decode_distance_mmx:
+	psrlq mm0,mm1
+
+	cmp  ebp,32
+	ja L_get_dist_code_mmx
+
+	movd mm6,ebp
+	movd mm7,dword ptr [esi]
+	add  esi,4
+	psllq mm7,mm6
+	add  ebp,32
+	por mm0,mm7
+
+L_get_dist_code_mmx:
+	mov  ebx, [esp+12]
+	pand mm5,mm0
+	movd eax,mm5
+	movq mm5,mm2
+	mov  eax, [ebx+eax*4]
+
+L_dodist_mmx:
+
+	movzx  ecx,ah
+	mov  ebx,eax
+	shr  ebx,16
+	sub  ebp,ecx
+	movd mm1,ecx
+
+	test  al,16
+	jz L_test_for_second_level_dist_mmx
+	and  eax,15
+	jz L_check_dist_one_mmx
+
+L_add_bits_to_dist_mmx:
+	psrlq mm0,mm1
+	movd mm1,eax
+	movd ecx,mm0
+	sub  ebp,eax
+	and  ecx, [inflate_fast_mask+eax*4]
+	add  ebx,ecx
+
+L_check_window_mmx:
+	mov  [esp+44],esi
+	mov  eax,edi
+	sub  eax, [esp+40]
+
+	cmp  eax,ebx
+	jb L_clip_window_mmx
+
+	mov  ecx,edx
+	mov  esi,edi
+	sub  esi,ebx
+
+	sub  ecx,3
+	mov  al, [esi]
+	mov  [edi],al
+	mov  al, [esi+1]
+	mov  dl, [esi+2]
+	add  esi,3
+	mov  [edi+1],al
+	mov  [edi+2],dl
+	add  edi,3
+	rep movsb
+
+	mov  esi, [esp+44]
+	mov  ebx, [esp+8]
+	jmp  L_while_test_mmx
+
+ALIGN 4
+L_check_dist_one_mmx:
+	cmp  ebx,1
+	jne  L_check_window_mmx
+	cmp  [esp+40],edi
+	je   L_check_window_mmx
+
+	dec  edi
+	mov  ecx,edx
+	mov  al, [edi]
+	sub  ecx,3
+
+	mov  [edi+1],al
+	mov  [edi+2],al
+	mov  [edi+3],al
+	add  edi,4
+	rep stosb
+
+	mov  ebx, [esp+8]
+	jmp  L_while_test_mmx
+
+ALIGN 4
+L_test_for_second_level_length_mmx:
+	test  al,64
+	jnz L_test_for_end_of_block
+
+	and  eax,15
+	psrlq mm0,mm1
+	movd ecx,mm0
+	and  ecx, [inflate_fast_mask+eax*4]
+	add  ecx,edx
+	mov  eax, [ebx+ecx*4]
+	jmp L_dolen_mmx
+
+ALIGN 4
+L_test_for_second_level_dist_mmx:
+	test  al,64
+	jnz L_invalid_distance_code
+
+	and  eax,15
+	psrlq mm0,mm1
+	movd ecx,mm0
+	and  ecx, [inflate_fast_mask+eax*4]
+	mov  eax, [esp+12]
+	add  ecx,ebx
+	mov  eax, [eax+ecx*4]
+	jmp  L_dodist_mmx
+
+ALIGN 4
+L_clip_window_mmx:
+
+	mov  ecx,eax
+	mov  eax, [esp+52]
+	neg  ecx
+	mov  esi, [esp+56]
+
+	cmp  eax,ebx
+	jb  L_invalid_distance_too_far
+
+	add  ecx,ebx
+	cmp  dword ptr [esp+48],0
+	jne  L_wrap_around_window_mmx
+
+	sub  eax,ecx
+	add  esi,eax
+
+	cmp  edx,ecx
+	jbe  L_do_copy1_mmx
+
+	sub  edx,ecx
+	rep movsb
+	mov  esi,edi
+	sub  esi,ebx
+	jmp  L_do_copy1_mmx
+
+	cmp  edx,ecx
+	jbe  L_do_copy1_mmx
+
+	sub  edx,ecx
+	rep movsb
+	mov  esi,edi
+	sub  esi,ebx
+	jmp  L_do_copy1_mmx
+
+L_wrap_around_window_mmx:
+
+	mov  eax, [esp+48]
+	cmp  ecx,eax
+	jbe  L_contiguous_in_window_mmx
+
+	add  esi, [esp+52]
+	add  esi,eax
+	sub  esi,ecx
+	sub  ecx,eax
+
+
+	cmp  edx,ecx
+	jbe  L_do_copy1_mmx
+
+	sub  edx,ecx
+	rep movsb
+	mov  esi, [esp+56]
+	mov  ecx, [esp+48]
+	cmp  edx,ecx
+	jbe  L_do_copy1_mmx
+
+	sub  edx,ecx
+	rep movsb
+	mov  esi,edi
+	sub  esi,ebx
+	jmp  L_do_copy1_mmx
+
+L_contiguous_in_window_mmx:
+
+	add  esi,eax
+	sub  esi,ecx
+
+
+	cmp  edx,ecx
+	jbe  L_do_copy1_mmx
+
+	sub  edx,ecx
+	rep movsb
+	mov  esi,edi
+	sub  esi,ebx
+
+L_do_copy1_mmx:
+
+
+	mov  ecx,edx
+	rep movsb
+
+	mov  esi, [esp+44]
+	mov  ebx, [esp+8]
+	jmp  L_while_test_mmx
+; 1174 "inffast.S"
+L_invalid_distance_code:
+
+
+
+
+
+	mov  ecx, invalid_distance_code_msg
+	mov  edx,INFLATE_MODE_BAD
+	jmp  L_update_stream_state
+
+L_test_for_end_of_block:
+
+
+
+
+
+	test  al,32
+	jz  L_invalid_literal_length_code
+
+	mov  ecx,0
+	mov  edx,INFLATE_MODE_TYPE
+	jmp  L_update_stream_state
+
+L_invalid_literal_length_code:
+
+
+
+
+
+	mov  ecx, invalid_literal_length_code_msg
+	mov  edx,INFLATE_MODE_BAD
+	jmp  L_update_stream_state
+
+L_invalid_distance_too_far:
+
+
+
+	mov  esi, [esp+44]
+	mov  ecx, invalid_distance_too_far_msg
+	mov  edx,INFLATE_MODE_BAD
+	jmp  L_update_stream_state
+
+L_update_stream_state:
+
+	mov  eax, [esp+88]
+	test  ecx,ecx
+	jz  L_skip_msg
+	mov  [eax+24],ecx
+L_skip_msg:
+	mov  eax, [eax+28]
+	mov  [eax+mode_state],edx
+	jmp  L_break_loop
+
+ALIGN 4
+L_break_loop:
+; 1243 "inffast.S"
+	cmp  dword ptr [inflate_fast_use_mmx],2
+	jne  L_update_next_in
+
+
+
+	mov  ebx,ebp
+
+L_update_next_in:
+; 1266 "inffast.S"
+	mov  eax, [esp+88]
+	mov  ecx,ebx
+	mov  edx, [eax+28]
+	shr  ecx,3
+	sub  esi,ecx
+	shl  ecx,3
+	sub  ebx,ecx
+	mov  [eax+12],edi
+	mov  [edx+bits_state],ebx
+	mov  ecx,ebx
+
+	lea  ebx, [esp+28]
+	cmp  [esp+20],ebx
+	jne  L_buf_not_used
+
+	sub  esi,ebx
+	mov  ebx, [eax+0]
+	mov  [esp+20],ebx
+	add  esi,ebx
+	mov  ebx, [eax+4]
+	sub  ebx,11
+	add  [esp+20],ebx
+
+L_buf_not_used:
+	mov  [eax+0],esi
+
+	mov  ebx,1
+	shl  ebx,cl
+	dec  ebx
+
+
+
+
+
+	cmp  dword ptr [inflate_fast_use_mmx],2
+	jne  L_update_hold
+
+
+
+	psrlq mm0,mm1
+	movd ebp,mm0
+
+	emms
+
+L_update_hold:
+
+
+
+	and  ebp,ebx
+	mov  [edx+hold_state],ebp
+
+
+
+
+	mov  ebx, [esp+20]
+	cmp  ebx,esi
+	jbe  L_last_is_smaller
+
+	sub  ebx,esi
+	add  ebx,11
+	mov  [eax+4],ebx
+	jmp  L_fixup_out
+L_last_is_smaller:
+	sub  esi,ebx
+	neg  esi
+	add  esi,11
+	mov  [eax+4],esi
+
+
+
+
+L_fixup_out:
+
+	mov  ebx, [esp+16]
+	cmp  ebx,edi
+	jbe  L_end_is_smaller
+
+	sub  ebx,edi
+	add  ebx,257
+	mov  [eax+16],ebx
+	jmp  L_done
+L_end_is_smaller:
+	sub  edi,ebx
+	neg  edi
+	add  edi,257
+	mov  [eax+16],edi
+
+
+
+
+
+L_done:
+	add  esp,64
+	popfd
+	pop  ebx
+	pop  ebp
+	pop  esi
+	pop  edi
+	ret
+_inflate_fast endp
+
+_TEXT	ends
+end
diff --git a/compat/zlib/contrib/masmx86/match686.asm b/compat/zlib/contrib/masmx86/match686.asm
new file mode 100644
index 0000000..3b09212
--- /dev/null
+++ b/compat/zlib/contrib/masmx86/match686.asm
@@ -0,0 +1,479 @@
+; match686.asm -- Asm portion of the optimized longest_match for 32 bits x86
+; Copyright (C) 1995-1996 Jean-loup Gailly, Brian Raiter and Gilles Vollant.
+; File written by Gilles Vollant, by converting match686.S from Brian Raiter
+; for MASM. This is as assembly version of longest_match
+;  from Jean-loup Gailly in deflate.c
+;
+;         http://www.zlib.net
+;         http://www.winimage.com/zLibDll
+;         http://www.muppetlabs.com/~breadbox/software/assembly.html
+;
+; For Visual C++ 4.x and higher and ML 6.x and higher
+;   ml.exe is distributed in
+;  http://www.microsoft.com/downloads/details.aspx?FamilyID=7a1c9da0-0510-44a2-b042-7ef370530c64
+;
+; this file contain two implementation of longest_match
+;
+;  this longest_match was written by Brian raiter (1998), optimized for Pentium Pro
+;   (and the faster known version of match_init on modern Core 2 Duo and AMD Phenom)
+;
+;  for using an assembly version of longest_match, you need define ASMV in project
+;
+;    compile the asm file running
+;           ml /coff /Zi /c /Flmatch686.lst match686.asm
+;    and do not include match686.obj in your project
+;
+; note: contrib of zLib 1.2.3 and earlier contained both a deprecated version for
+;  Pentium (prior Pentium Pro) and this version for Pentium Pro and modern processor
+;  with autoselect (with cpu detection code)
+;  if you want support the old pentium optimization, you can still use these version
+;
+; this file is not optimized for old pentium, but it compatible with all x86 32 bits
+; processor (starting 80386)
+;
+;
+; see below : zlib1222add must be adjuster if you use a zlib version < 1.2.2.2
+
+;uInt longest_match(s, cur_match)
+;    deflate_state *s;
+;    IPos cur_match;                             /* current match */
+
+    NbStack         equ     76
+    cur_match       equ     dword ptr[esp+NbStack-0]
+    str_s           equ     dword ptr[esp+NbStack-4]
+; 5 dword on top (ret,ebp,esi,edi,ebx)
+    adrret          equ     dword ptr[esp+NbStack-8]
+    pushebp         equ     dword ptr[esp+NbStack-12]
+    pushedi         equ     dword ptr[esp+NbStack-16]
+    pushesi         equ     dword ptr[esp+NbStack-20]
+    pushebx         equ     dword ptr[esp+NbStack-24]
+
+    chain_length    equ     dword ptr [esp+NbStack-28]
+    limit           equ     dword ptr [esp+NbStack-32]
+    best_len        equ     dword ptr [esp+NbStack-36]
+    window          equ     dword ptr [esp+NbStack-40]
+    prev            equ     dword ptr [esp+NbStack-44]
+    scan_start      equ      word ptr [esp+NbStack-48]
+    wmask           equ     dword ptr [esp+NbStack-52]
+    match_start_ptr equ     dword ptr [esp+NbStack-56]
+    nice_match      equ     dword ptr [esp+NbStack-60]
+    scan            equ     dword ptr [esp+NbStack-64]
+
+    windowlen       equ     dword ptr [esp+NbStack-68]
+    match_start     equ     dword ptr [esp+NbStack-72]
+    strend          equ     dword ptr [esp+NbStack-76]
+    NbStackAdd      equ     (NbStack-24)
+
+    .386p
+
+    name    gvmatch
+    .MODEL  FLAT
+
+
+
+;  all the +zlib1222add offsets are due to the addition of fields
+;  in zlib in the deflate_state structure since the asm code was first written
+;  (if you compile with zlib 1.0.4 or older, use "zlib1222add equ (-4)").
+;  (if you compile with zlib between 1.0.5 and 1.2.2.1, use "zlib1222add equ 0").
+;  if you compile with zlib 1.2.2.2 or later , use "zlib1222add equ 8").
+
+    zlib1222add         equ     8
+
+;  Note : these value are good with a 8 bytes boundary pack structure
+    dep_chain_length    equ     74h+zlib1222add
+    dep_window          equ     30h+zlib1222add
+    dep_strstart        equ     64h+zlib1222add
+    dep_prev_length     equ     70h+zlib1222add
+    dep_nice_match      equ     88h+zlib1222add
+    dep_w_size          equ     24h+zlib1222add
+    dep_prev            equ     38h+zlib1222add
+    dep_w_mask          equ     2ch+zlib1222add
+    dep_good_match      equ     84h+zlib1222add
+    dep_match_start     equ     68h+zlib1222add
+    dep_lookahead       equ     6ch+zlib1222add
+
+
+_TEXT                   segment
+
+IFDEF NOUNDERLINE
+            public  longest_match
+            public  match_init
+ELSE
+            public  _longest_match
+            public  _match_init
+ENDIF
+
+    MAX_MATCH           equ     258
+    MIN_MATCH           equ     3
+    MIN_LOOKAHEAD       equ     (MAX_MATCH+MIN_MATCH+1)
+
+
+
+MAX_MATCH       equ     258
+MIN_MATCH       equ     3
+MIN_LOOKAHEAD   equ     (MAX_MATCH + MIN_MATCH + 1)
+MAX_MATCH_8_     equ     ((MAX_MATCH + 7) AND 0FFF0h)
+
+
+;;; stack frame offsets
+
+chainlenwmask   equ  esp + 0    ; high word: current chain len
+                    ; low word: s->wmask
+window      equ  esp + 4    ; local copy of s->window
+windowbestlen   equ  esp + 8    ; s->window + bestlen
+scanstart   equ  esp + 16   ; first two bytes of string
+scanend     equ  esp + 12   ; last two bytes of string
+scanalign   equ  esp + 20   ; dword-misalignment of string
+nicematch   equ  esp + 24   ; a good enough match size
+bestlen     equ  esp + 28   ; size of best match so far
+scan        equ  esp + 32   ; ptr to string wanting match
+
+LocalVarsSize   equ 36
+;   saved ebx   byte esp + 36
+;   saved edi   byte esp + 40
+;   saved esi   byte esp + 44
+;   saved ebp   byte esp + 48
+;   return address  byte esp + 52
+deflatestate    equ  esp + 56   ; the function arguments
+curmatch    equ  esp + 60
+
+;;; Offsets for fields in the deflate_state structure. These numbers
+;;; are calculated from the definition of deflate_state, with the
+;;; assumption that the compiler will dword-align the fields. (Thus,
+;;; changing the definition of deflate_state could easily cause this
+;;; program to crash horribly, without so much as a warning at
+;;; compile time. Sigh.)
+
+dsWSize     equ 36+zlib1222add
+dsWMask     equ 44+zlib1222add
+dsWindow    equ 48+zlib1222add
+dsPrev      equ 56+zlib1222add
+dsMatchLen  equ 88+zlib1222add
+dsPrevMatch equ 92+zlib1222add
+dsStrStart  equ 100+zlib1222add
+dsMatchStart    equ 104+zlib1222add
+dsLookahead equ 108+zlib1222add
+dsPrevLen   equ 112+zlib1222add
+dsMaxChainLen   equ 116+zlib1222add
+dsGoodMatch equ 132+zlib1222add
+dsNiceMatch equ 136+zlib1222add
+
+
+;;; match686.asm -- Pentium-Pro-optimized version of longest_match()
+;;; Written for zlib 1.1.2
+;;; Copyright (C) 1998 Brian Raiter <breadbox@muppetlabs.com>
+;;; You can look at http://www.muppetlabs.com/~breadbox/software/assembly.html
+;;;
+;;
+;;  This software is provided 'as-is', without any express or implied
+;;  warranty.  In no event will the authors be held liable for any damages
+;;  arising from the use of this software.
+;;
+;;  Permission is granted to anyone to use this software for any purpose,
+;;  including commercial applications, and to alter it and redistribute it
+;;  freely, subject to the following restrictions:
+;;
+;;  1. The origin of this software must not be misrepresented; you must not
+;;     claim that you wrote the original software. If you use this software
+;;     in a product, an acknowledgment in the product documentation would be
+;;     appreciated but is not required.
+;;  2. Altered source versions must be plainly marked as such, and must not be
+;;     misrepresented as being the original software
+;;  3. This notice may not be removed or altered from any source distribution.
+;;
+
+;GLOBAL _longest_match, _match_init
+
+
+;SECTION    .text
+
+;;; uInt longest_match(deflate_state *deflatestate, IPos curmatch)
+
+;_longest_match:
+    IFDEF NOUNDERLINE
+    longest_match       proc near
+    ELSE
+    _longest_match      proc near
+    ENDIF
+.FPO (9, 4, 0, 0, 1, 0)
+
+;;; Save registers that the compiler may be using, and adjust esp to
+;;; make room for our stack frame.
+
+        push    ebp
+        push    edi
+        push    esi
+        push    ebx
+        sub esp, LocalVarsSize
+
+;;; Retrieve the function arguments. ecx will hold cur_match
+;;; throughout the entire function. edx will hold the pointer to the
+;;; deflate_state structure during the function's setup (before
+;;; entering the main loop.
+
+        mov edx, [deflatestate]
+        mov ecx, [curmatch]
+
+;;; uInt wmask = s->w_mask;
+;;; unsigned chain_length = s->max_chain_length;
+;;; if (s->prev_length >= s->good_match) {
+;;;     chain_length >>= 2;
+;;; }
+
+        mov eax, [edx + dsPrevLen]
+        mov ebx, [edx + dsGoodMatch]
+        cmp eax, ebx
+        mov eax, [edx + dsWMask]
+        mov ebx, [edx + dsMaxChainLen]
+        jl  LastMatchGood
+        shr ebx, 2
+LastMatchGood:
+
+;;; chainlen is decremented once beforehand so that the function can
+;;; use the sign flag instead of the zero flag for the exit test.
+;;; It is then shifted into the high word, to make room for the wmask
+;;; value, which it will always accompany.
+
+        dec ebx
+        shl ebx, 16
+        or  ebx, eax
+        mov [chainlenwmask], ebx
+
+;;; if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;
+
+        mov eax, [edx + dsNiceMatch]
+        mov ebx, [edx + dsLookahead]
+        cmp ebx, eax
+        jl  LookaheadLess
+        mov ebx, eax
+LookaheadLess:  mov [nicematch], ebx
+
+;;; register Bytef *scan = s->window + s->strstart;
+
+        mov esi, [edx + dsWindow]
+        mov [window], esi
+        mov ebp, [edx + dsStrStart]
+        lea edi, [esi + ebp]
+        mov [scan], edi
+
+;;; Determine how many bytes the scan ptr is off from being
+;;; dword-aligned.
+
+        mov eax, edi
+        neg eax
+        and eax, 3
+        mov [scanalign], eax
+
+;;; IPos limit = s->strstart > (IPos)MAX_DIST(s) ?
+;;;     s->strstart - (IPos)MAX_DIST(s) : NIL;
+
+        mov eax, [edx + dsWSize]
+        sub eax, MIN_LOOKAHEAD
+        sub ebp, eax
+        jg  LimitPositive
+        xor ebp, ebp
+LimitPositive:
+
+;;; int best_len = s->prev_length;
+
+        mov eax, [edx + dsPrevLen]
+        mov [bestlen], eax
+
+;;; Store the sum of s->window + best_len in esi locally, and in esi.
+
+        add esi, eax
+        mov [windowbestlen], esi
+
+;;; register ush scan_start = *(ushf*)scan;
+;;; register ush scan_end   = *(ushf*)(scan+best_len-1);
+;;; Posf *prev = s->prev;
+
+        movzx   ebx, word ptr [edi]
+        mov [scanstart], ebx
+        movzx   ebx, word ptr [edi + eax - 1]
+        mov [scanend], ebx
+        mov edi, [edx + dsPrev]
+
+;;; Jump into the main loop.
+
+        mov edx, [chainlenwmask]
+        jmp short LoopEntry
+
+align 4
+
+;;; do {
+;;;     match = s->window + cur_match;
+;;;     if (*(ushf*)(match+best_len-1) != scan_end ||
+;;;         *(ushf*)match != scan_start) continue;
+;;;     [...]
+;;; } while ((cur_match = prev[cur_match & wmask]) > limit
+;;;          && --chain_length != 0);
+;;;
+;;; Here is the inner loop of the function. The function will spend the
+;;; majority of its time in this loop, and majority of that time will
+;;; be spent in the first ten instructions.
+;;;
+;;; Within this loop:
+;;; ebx = scanend
+;;; ecx = curmatch
+;;; edx = chainlenwmask - i.e., ((chainlen << 16) | wmask)
+;;; esi = windowbestlen - i.e., (window + bestlen)
+;;; edi = prev
+;;; ebp = limit
+
+LookupLoop:
+        and ecx, edx
+        movzx   ecx, word ptr [edi + ecx*2]
+        cmp ecx, ebp
+        jbe LeaveNow
+        sub edx, 00010000h
+        js  LeaveNow
+LoopEntry:  movzx   eax, word ptr [esi + ecx - 1]
+        cmp eax, ebx
+        jnz LookupLoop
+        mov eax, [window]
+        movzx   eax, word ptr [eax + ecx]
+        cmp eax, [scanstart]
+        jnz LookupLoop
+
+;;; Store the current value of chainlen.
+
+        mov [chainlenwmask], edx
+
+;;; Point edi to the string under scrutiny, and esi to the string we
+;;; are hoping to match it up with. In actuality, esi and edi are
+;;; both pointed (MAX_MATCH_8 - scanalign) bytes ahead, and edx is
+;;; initialized to -(MAX_MATCH_8 - scanalign).
+
+        mov esi, [window]
+        mov edi, [scan]
+        add esi, ecx
+        mov eax, [scanalign]
+        mov edx, 0fffffef8h; -(MAX_MATCH_8)
+        lea edi, [edi + eax + 0108h] ;MAX_MATCH_8]
+        lea esi, [esi + eax + 0108h] ;MAX_MATCH_8]
+
+;;; Test the strings for equality, 8 bytes at a time. At the end,
+;;; adjust edx so that it is offset to the exact byte that mismatched.
+;;;
+;;; We already know at this point that the first three bytes of the
+;;; strings match each other, and they can be safely passed over before
+;;; starting the compare loop. So what this code does is skip over 0-3
+;;; bytes, as much as necessary in order to dword-align the edi
+;;; pointer. (esi will still be misaligned three times out of four.)
+;;;
+;;; It should be confessed that this loop usually does not represent
+;;; much of the total running time. Replacing it with a more
+;;; straightforward "rep cmpsb" would not drastically degrade
+;;; performance.
+
+LoopCmps:
+        mov eax, [esi + edx]
+        xor eax, [edi + edx]
+        jnz LeaveLoopCmps
+        mov eax, [esi + edx + 4]
+        xor eax, [edi + edx + 4]
+        jnz LeaveLoopCmps4
+        add edx, 8
+        jnz LoopCmps
+        jmp short LenMaximum
+LeaveLoopCmps4: add edx, 4
+LeaveLoopCmps:  test    eax, 0000FFFFh
+        jnz LenLower
+        add edx,  2
+        shr eax, 16
+LenLower:   sub al, 1
+        adc edx, 0
+
+;;; Calculate the length of the match. If it is longer than MAX_MATCH,
+;;; then automatically accept it as the best possible match and leave.
+
+        lea eax, [edi + edx]
+        mov edi, [scan]
+        sub eax, edi
+        cmp eax, MAX_MATCH
+        jge LenMaximum
+
+;;; If the length of the match is not longer than the best match we
+;;; have so far, then forget it and return to the lookup loop.
+
+        mov edx, [deflatestate]
+        mov ebx, [bestlen]
+        cmp eax, ebx
+        jg  LongerMatch
+        mov esi, [windowbestlen]
+        mov edi, [edx + dsPrev]
+        mov ebx, [scanend]
+        mov edx, [chainlenwmask]
+        jmp LookupLoop
+
+;;;         s->match_start = cur_match;
+;;;         best_len = len;
+;;;         if (len >= nice_match) break;
+;;;         scan_end = *(ushf*)(scan+best_len-1);
+
+LongerMatch:    mov ebx, [nicematch]
+        mov [bestlen], eax
+        mov [edx + dsMatchStart], ecx
+        cmp eax, ebx
+        jge LeaveNow
+        mov esi, [window]
+        add esi, eax
+        mov [windowbestlen], esi
+        movzx   ebx, word ptr [edi + eax - 1]
+        mov edi, [edx + dsPrev]
+        mov [scanend], ebx
+        mov edx, [chainlenwmask]
+        jmp LookupLoop
+
+;;; Accept the current string, with the maximum possible length.
+
+LenMaximum: mov edx, [deflatestate]
+        mov dword ptr [bestlen], MAX_MATCH
+        mov [edx + dsMatchStart], ecx
+
+;;; if ((uInt)best_len <= s->lookahead) return (uInt)best_len;
+;;; return s->lookahead;
+
+LeaveNow:
+        mov edx, [deflatestate]
+        mov ebx, [bestlen]
+        mov eax, [edx + dsLookahead]
+        cmp ebx, eax
+        jg  LookaheadRet
+        mov eax, ebx
+LookaheadRet:
+
+;;; Restore the stack and return from whence we came.
+
+        add esp, LocalVarsSize
+        pop ebx
+        pop esi
+        pop edi
+        pop ebp
+
+        ret
+; please don't remove this string !
+; Your can freely use match686 in any free or commercial app if you don't remove the string in the binary!
+    db     0dh,0ah,"asm686 with masm, optimised assembly code from Brian Raiter, written 1998",0dh,0ah
+
+
+    IFDEF NOUNDERLINE
+    longest_match       endp
+    ELSE
+    _longest_match      endp
+    ENDIF
+
+    IFDEF NOUNDERLINE
+    match_init      proc near
+                    ret
+    match_init      endp
+    ELSE
+    _match_init     proc near
+                    ret
+    _match_init     endp
+    ENDIF
+
+
+_TEXT   ends
+end
diff --git a/compat/zlib/contrib/masmx86/readme.txt b/compat/zlib/contrib/masmx86/readme.txt
new file mode 100644
index 0000000..3271f72
--- /dev/null
+++ b/compat/zlib/contrib/masmx86/readme.txt
@@ -0,0 +1,27 @@
+
+Summary
+-------
+This directory contains ASM implementations of the functions
+longest_match() and inflate_fast().
+
+
+Use instructions
+----------------
+Assemble using MASM, and copy the object files into the zlib source
+directory, then run the appropriate makefile, as suggested below.  You can
+donwload MASM from here:
+
+    http://www.microsoft.com/downloads/details.aspx?displaylang=en&FamilyID=7a1c9da0-0510-44a2-b042-7ef370530c64
+
+You can also get objects files here:
+
+    http://www.winimage.com/zLibDll/zlib124_masm_obj.zip
+
+Build instructions
+------------------
+* With Microsoft C and MASM:
+nmake -f win32/Makefile.msc LOC="-DASMV -DASMINF" OBJA="match686.obj inffas32.obj"
+
+* With Borland C and TASM:
+make -f win32/Makefile.bor LOCAL_ZLIB="-DASMV -DASMINF" OBJA="match686.obj inffas32.obj" OBJPA="+match686c.obj+match686.obj+inffas32.obj"
+
diff --git a/compat/zlib/contrib/minizip/Makefile b/compat/zlib/contrib/minizip/Makefile
new file mode 100644
index 0000000..84eaad2
--- /dev/null
+++ b/compat/zlib/contrib/minizip/Makefile
@@ -0,0 +1,25 @@
+CC=cc
+CFLAGS=-O -I../..
+
+UNZ_OBJS = miniunz.o unzip.o ioapi.o ../../libz.a
+ZIP_OBJS = minizip.o zip.o   ioapi.o ../../libz.a
+
+.c.o:
+	$(CC) -c $(CFLAGS) $*.c
+
+all: miniunz minizip
+
+miniunz:  $(UNZ_OBJS)
+	$(CC) $(CFLAGS) -o $@ $(UNZ_OBJS)
+
+minizip:  $(ZIP_OBJS)
+	$(CC) $(CFLAGS) -o $@ $(ZIP_OBJS)
+
+test:	miniunz minizip
+	./minizip test readme.txt
+	./miniunz -l test.zip
+	mv readme.txt readme.old
+	./miniunz test.zip
+
+clean:
+	/bin/rm -f *.o *~ minizip miniunz
diff --git a/compat/zlib/contrib/minizip/Makefile.am b/compat/zlib/contrib/minizip/Makefile.am
new file mode 100644
index 0000000..d343011
--- /dev/null
+++ b/compat/zlib/contrib/minizip/Makefile.am
@@ -0,0 +1,45 @@
+lib_LTLIBRARIES = libminizip.la
+
+if COND_DEMOS
+bin_PROGRAMS = miniunzip minizip
+endif
+
+zlib_top_srcdir = $(top_srcdir)/../..
+zlib_top_builddir = $(top_builddir)/../..
+
+AM_CPPFLAGS = -I$(zlib_top_srcdir)
+AM_LDFLAGS = -L$(zlib_top_builddir)
+
+if WIN32
+iowin32_src = iowin32.c
+iowin32_h = iowin32.h
+endif
+
+libminizip_la_SOURCES = \
+	ioapi.c \
+	mztools.c \
+	unzip.c \
+	zip.c \
+	${iowin32_src}
+
+libminizip_la_LDFLAGS = $(AM_LDFLAGS) -version-info 1:0:0 -lz
+
+minizip_includedir = $(includedir)/minizip
+minizip_include_HEADERS = \
+	crypt.h \
+	ioapi.h \
+	mztools.h \
+	unzip.h \
+	zip.h \
+	${iowin32_h}
+
+pkgconfigdir = $(libdir)/pkgconfig
+pkgconfig_DATA = minizip.pc
+
+EXTRA_PROGRAMS = miniunzip minizip
+
+miniunzip_SOURCES = miniunz.c
+miniunzip_LDADD = libminizip.la
+
+minizip_SOURCES = minizip.c
+minizip_LDADD = libminizip.la -lz
diff --git a/compat/zlib/contrib/minizip/MiniZip64_Changes.txt b/compat/zlib/contrib/minizip/MiniZip64_Changes.txt
new file mode 100644
index 0000000..13a1bd9
--- /dev/null
+++ b/compat/zlib/contrib/minizip/MiniZip64_Changes.txt
@@ -0,0 +1,6 @@
+
+MiniZip 1.1 was derrived from MiniZip at version 1.01f
+
+Change in 1.0 (Okt 2009)
+ - **TODO - Add history**
+
diff --git a/compat/zlib/contrib/minizip/MiniZip64_info.txt b/compat/zlib/contrib/minizip/MiniZip64_info.txt
new file mode 100644
index 0000000..57d7152
--- /dev/null
+++ b/compat/zlib/contrib/minizip/MiniZip64_info.txt
@@ -0,0 +1,74 @@
+MiniZip - Copyright (c) 1998-2010 - by Gilles Vollant - version 1.1 64 bits from Mathias Svensson
+
+Introduction
+---------------------
+MiniZip 1.1 is built from MiniZip 1.0 by Gilles Vollant ( http://www.winimage.com/zLibDll/minizip.html )
+
+When adding ZIP64 support into minizip it would result into risk of breaking compatibility with minizip 1.0.
+All possible work was done for compatibility.
+
+
+Background
+---------------------
+When adding ZIP64 support Mathias Svensson found that Even Rouault have added ZIP64 
+support for unzip.c into minizip for a open source project called gdal ( http://www.gdal.org/ )
+
+That was used as a starting point. And after that ZIP64 support was added to zip.c
+some refactoring and code cleanup was also done.
+
+
+Changed from MiniZip 1.0 to MiniZip 1.1
+---------------------------------------
+* Added ZIP64 support for unzip ( by Even Rouault )
+* Added ZIP64 support for zip ( by Mathias Svensson )
+* Reverted some changed that Even Rouault did.
+* Bunch of patches received from Gulles Vollant that he received for MiniZip from various users.
+* Added unzip patch for BZIP Compression method (patch create by Daniel Borca)
+* Added BZIP Compress method for zip
+* Did some refactoring and code cleanup
+
+
+Credits
+
+ Gilles Vollant    - Original MiniZip author
+ Even Rouault      - ZIP64 unzip Support
+ Daniel Borca      - BZip Compression method support in unzip
+ Mathias Svensson  - ZIP64 zip support
+ Mathias Svensson  - BZip Compression method support in zip
+
+ Resources
+
+ ZipLayout   http://result42.com/projects/ZipFileLayout
+             Command line tool for Windows that shows the layout and information of the headers in a zip archive.
+             Used when debugging and validating the creation of zip files using MiniZip64
+
+
+ ZIP App Note  http://www.pkware.com/documents/casestudies/APPNOTE.TXT
+               Zip File specification
+
+
+Notes.
+ * To be able to use BZip compression method in zip64.c or unzip64.c the BZIP2 lib is needed and HAVE_BZIP2 need to be defined.
+
+License
+----------------------------------------------------------
+   Condition of use and distribution are the same than zlib :
+
+  This software is provided 'as-is', without any express or implied
+  warranty.  In no event will the authors be held liable for any damages
+  arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any purpose,
+  including commercial applications, and to alter it and redistribute it
+  freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+
+----------------------------------------------------------
+
diff --git a/compat/zlib/contrib/minizip/configure.ac b/compat/zlib/contrib/minizip/configure.ac
new file mode 100644
index 0000000..827a4e0
--- /dev/null
+++ b/compat/zlib/contrib/minizip/configure.ac
@@ -0,0 +1,32 @@
+#                                               -*- Autoconf -*-
+# Process this file with autoconf to produce a configure script.
+
+AC_INIT([minizip], [1.2.8], [bugzilla.redhat.com])
+AC_CONFIG_SRCDIR([minizip.c])
+AM_INIT_AUTOMAKE([foreign])
+LT_INIT
+
+AC_MSG_CHECKING([whether to build example programs])
+AC_ARG_ENABLE([demos], AC_HELP_STRING([--enable-demos], [build example programs]))
+AM_CONDITIONAL([COND_DEMOS], [test "$enable_demos" = yes])
+if test "$enable_demos" = yes
+then
+	AC_MSG_RESULT([yes])
+else
+	AC_MSG_RESULT([no])
+fi
+
+case "${host}" in
+	*-mingw* | mingw*)
+		WIN32="yes"
+		;;
+	*)
+		;;
+esac
+AM_CONDITIONAL([WIN32], [test "${WIN32}" = "yes"])
+
+
+AC_SUBST([HAVE_UNISTD_H], [0])
+AC_CHECK_HEADER([unistd.h], [HAVE_UNISTD_H=1], [])
+AC_CONFIG_FILES([Makefile minizip.pc])
+AC_OUTPUT
diff --git a/compat/zlib/contrib/minizip/crypt.h b/compat/zlib/contrib/minizip/crypt.h
new file mode 100644
index 0000000..1e9e820
--- /dev/null
+++ b/compat/zlib/contrib/minizip/crypt.h
@@ -0,0 +1,131 @@
+/* crypt.h -- base code for crypt/uncrypt ZIPfile
+
+
+   Version 1.01e, February 12th, 2005
+
+   Copyright (C) 1998-2005 Gilles Vollant
+
+   This code is a modified version of crypting code in Infozip distribution
+
+   The encryption/decryption parts of this source code (as opposed to the
+   non-echoing password parts) were originally written in Europe.  The
+   whole source package can be freely distributed, including from the USA.
+   (Prior to January 2000, re-export from the US was a violation of US law.)
+
+   This encryption code is a direct transcription of the algorithm from
+   Roger Schlafly, described by Phil Katz in the file appnote.txt.  This
+   file (appnote.txt) is distributed with the PKZIP program (even in the
+   version without encryption capabilities).
+
+   If you don't need crypting in your application, just define symbols
+   NOCRYPT and NOUNCRYPT.
+
+   This code support the "Traditional PKWARE Encryption".
+
+   The new AES encryption added on Zip format by Winzip (see the page
+   http://www.winzip.com/aes_info.htm ) and PKWare PKZip 5.x Strong
+   Encryption is not supported.
+*/
+
+#define CRC32(c, b) ((*(pcrc_32_tab+(((int)(c) ^ (b)) & 0xff))) ^ ((c) >> 8))
+
+/***********************************************************************
+ * Return the next byte in the pseudo-random sequence
+ */
+static int decrypt_byte(unsigned long* pkeys, const z_crc_t* pcrc_32_tab)
+{
+    unsigned temp;  /* POTENTIAL BUG:  temp*(temp^1) may overflow in an
+                     * unpredictable manner on 16-bit systems; not a problem
+                     * with any known compiler so far, though */
+
+    temp = ((unsigned)(*(pkeys+2)) & 0xffff) | 2;
+    return (int)(((temp * (temp ^ 1)) >> 8) & 0xff);
+}
+
+/***********************************************************************
+ * Update the encryption keys with the next byte of plain text
+ */
+static int update_keys(unsigned long* pkeys,const z_crc_t* pcrc_32_tab,int c)
+{
+    (*(pkeys+0)) = CRC32((*(pkeys+0)), c);
+    (*(pkeys+1)) += (*(pkeys+0)) & 0xff;
+    (*(pkeys+1)) = (*(pkeys+1)) * 134775813L + 1;
+    {
+      register int keyshift = (int)((*(pkeys+1)) >> 24);
+      (*(pkeys+2)) = CRC32((*(pkeys+2)), keyshift);
+    }
+    return c;
+}
+
+
+/***********************************************************************
+ * Initialize the encryption keys and the random header according to
+ * the given password.
+ */
+static void init_keys(const char* passwd,unsigned long* pkeys,const z_crc_t* pcrc_32_tab)
+{
+    *(pkeys+0) = 305419896L;
+    *(pkeys+1) = 591751049L;
+    *(pkeys+2) = 878082192L;
+    while (*passwd != '\0') {
+        update_keys(pkeys,pcrc_32_tab,(int)*passwd);
+        passwd++;
+    }
+}
+
+#define zdecode(pkeys,pcrc_32_tab,c) \
+    (update_keys(pkeys,pcrc_32_tab,c ^= decrypt_byte(pkeys,pcrc_32_tab)))
+
+#define zencode(pkeys,pcrc_32_tab,c,t) \
+    (t=decrypt_byte(pkeys,pcrc_32_tab), update_keys(pkeys,pcrc_32_tab,c), t^(c))
+
+#ifdef INCLUDECRYPTINGCODE_IFCRYPTALLOWED
+
+#define RAND_HEAD_LEN  12
+   /* "last resort" source for second part of crypt seed pattern */
+#  ifndef ZCR_SEED2
+#    define ZCR_SEED2 3141592654UL     /* use PI as default pattern */
+#  endif
+
+static int crypthead(const char* passwd,      /* password string */
+                     unsigned char* buf,      /* where to write header */
+                     int bufSize,
+                     unsigned long* pkeys,
+                     const z_crc_t* pcrc_32_tab,
+                     unsigned long crcForCrypting)
+{
+    int n;                       /* index in random header */
+    int t;                       /* temporary */
+    int c;                       /* random byte */
+    unsigned char header[RAND_HEAD_LEN-2]; /* random header */
+    static unsigned calls = 0;   /* ensure different random header each time */
+
+    if (bufSize<RAND_HEAD_LEN)
+      return 0;
+
+    /* First generate RAND_HEAD_LEN-2 random bytes. We encrypt the
+     * output of rand() to get less predictability, since rand() is
+     * often poorly implemented.
+     */
+    if (++calls == 1)
+    {
+        srand((unsigned)(time(NULL) ^ ZCR_SEED2));
+    }
+    init_keys(passwd, pkeys, pcrc_32_tab);
+    for (n = 0; n < RAND_HEAD_LEN-2; n++)
+    {
+        c = (rand() >> 7) & 0xff;
+        header[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, c, t);
+    }
+    /* Encrypt random header (last two bytes is high word of crc) */
+    init_keys(passwd, pkeys, pcrc_32_tab);
+    for (n = 0; n < RAND_HEAD_LEN-2; n++)
+    {
+        buf[n] = (unsigned char)zencode(pkeys, pcrc_32_tab, header[n], t);
+    }
+    buf[n++] = (unsigned char)zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 16) & 0xff, t);
+    buf[n++] = (unsigned char)zencode(pkeys, pcrc_32_tab, (int)(crcForCrypting >> 24) & 0xff, t);
+    return n;
+}
+
+#endif
diff --git a/compat/zlib/contrib/minizip/ioapi.c b/compat/zlib/contrib/minizip/ioapi.c
new file mode 100644
index 0000000..7f5c191
--- /dev/null
+++ b/compat/zlib/contrib/minizip/ioapi.c
@@ -0,0 +1,247 @@
+/* ioapi.h -- IO base function header for compress/uncompress .zip
+   part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
+
+         Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
+
+         Modifications for Zip64 support
+         Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
+
+         For more info read MiniZip_info.txt
+
+*/
+
+#if defined(_WIN32) && (!(defined(_CRT_SECURE_NO_WARNINGS)))
+        #define _CRT_SECURE_NO_WARNINGS
+#endif
+
+#if defined(__APPLE__) || defined(IOAPI_NO_64)
+// In darwin and perhaps other BSD variants off_t is a 64 bit value, hence no need for specific 64 bit functions
+#define FOPEN_FUNC(filename, mode) fopen(filename, mode)
+#define FTELLO_FUNC(stream) ftello(stream)
+#define FSEEKO_FUNC(stream, offset, origin) fseeko(stream, offset, origin)
+#else
+#define FOPEN_FUNC(filename, mode) fopen64(filename, mode)
+#define FTELLO_FUNC(stream) ftello64(stream)
+#define FSEEKO_FUNC(stream, offset, origin) fseeko64(stream, offset, origin)
+#endif
+
+
+#include "ioapi.h"
+
+voidpf call_zopen64 (const zlib_filefunc64_32_def* pfilefunc,const void*filename,int mode)
+{
+    if (pfilefunc->zfile_func64.zopen64_file != NULL)
+        return (*(pfilefunc->zfile_func64.zopen64_file)) (pfilefunc->zfile_func64.opaque,filename,mode);
+    else
+    {
+        return (*(pfilefunc->zopen32_file))(pfilefunc->zfile_func64.opaque,(const char*)filename,mode);
+    }
+}
+
+long call_zseek64 (const zlib_filefunc64_32_def* pfilefunc,voidpf filestream, ZPOS64_T offset, int origin)
+{
+    if (pfilefunc->zfile_func64.zseek64_file != NULL)
+        return (*(pfilefunc->zfile_func64.zseek64_file)) (pfilefunc->zfile_func64.opaque,filestream,offset,origin);
+    else
+    {
+        uLong offsetTruncated = (uLong)offset;
+        if (offsetTruncated != offset)
+            return -1;
+        else
+            return (*(pfilefunc->zseek32_file))(pfilefunc->zfile_func64.opaque,filestream,offsetTruncated,origin);
+    }
+}
+
+ZPOS64_T call_ztell64 (const zlib_filefunc64_32_def* pfilefunc,voidpf filestream)
+{
+    if (pfilefunc->zfile_func64.zseek64_file != NULL)
+        return (*(pfilefunc->zfile_func64.ztell64_file)) (pfilefunc->zfile_func64.opaque,filestream);
+    else
+    {
+        uLong tell_uLong = (*(pfilefunc->ztell32_file))(pfilefunc->zfile_func64.opaque,filestream);
+        if ((tell_uLong) == MAXU32)
+            return (ZPOS64_T)-1;
+        else
+            return tell_uLong;
+    }
+}
+
+void fill_zlib_filefunc64_32_def_from_filefunc32(zlib_filefunc64_32_def* p_filefunc64_32,const zlib_filefunc_def* p_filefunc32)
+{
+    p_filefunc64_32->zfile_func64.zopen64_file = NULL;
+    p_filefunc64_32->zopen32_file = p_filefunc32->zopen_file;
+    p_filefunc64_32->zfile_func64.zerror_file = p_filefunc32->zerror_file;
+    p_filefunc64_32->zfile_func64.zread_file = p_filefunc32->zread_file;
+    p_filefunc64_32->zfile_func64.zwrite_file = p_filefunc32->zwrite_file;
+    p_filefunc64_32->zfile_func64.ztell64_file = NULL;
+    p_filefunc64_32->zfile_func64.zseek64_file = NULL;
+    p_filefunc64_32->zfile_func64.zclose_file = p_filefunc32->zclose_file;
+    p_filefunc64_32->zfile_func64.zerror_file = p_filefunc32->zerror_file;
+    p_filefunc64_32->zfile_func64.opaque = p_filefunc32->opaque;
+    p_filefunc64_32->zseek32_file = p_filefunc32->zseek_file;
+    p_filefunc64_32->ztell32_file = p_filefunc32->ztell_file;
+}
+
+
+
+static voidpf  ZCALLBACK fopen_file_func OF((voidpf opaque, const char* filename, int mode));
+static uLong   ZCALLBACK fread_file_func OF((voidpf opaque, voidpf stream, void* buf, uLong size));
+static uLong   ZCALLBACK fwrite_file_func OF((voidpf opaque, voidpf stream, const void* buf,uLong size));
+static ZPOS64_T ZCALLBACK ftell64_file_func OF((voidpf opaque, voidpf stream));
+static long    ZCALLBACK fseek64_file_func OF((voidpf opaque, voidpf stream, ZPOS64_T offset, int origin));
+static int     ZCALLBACK fclose_file_func OF((voidpf opaque, voidpf stream));
+static int     ZCALLBACK ferror_file_func OF((voidpf opaque, voidpf stream));
+
+static voidpf ZCALLBACK fopen_file_func (voidpf opaque, const char* filename, int mode)
+{
+    FILE* file = NULL;
+    const char* mode_fopen = NULL;
+    if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ)
+        mode_fopen = "rb";
+    else
+    if (mode & ZLIB_FILEFUNC_MODE_EXISTING)
+        mode_fopen = "r+b";
+    else
+    if (mode & ZLIB_FILEFUNC_MODE_CREATE)
+        mode_fopen = "wb";
+
+    if ((filename!=NULL) && (mode_fopen != NULL))
+        file = fopen(filename, mode_fopen);
+    return file;
+}
+
+static voidpf ZCALLBACK fopen64_file_func (voidpf opaque, const void* filename, int mode)
+{
+    FILE* file = NULL;
+    const char* mode_fopen = NULL;
+    if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ)
+        mode_fopen = "rb";
+    else
+    if (mode & ZLIB_FILEFUNC_MODE_EXISTING)
+        mode_fopen = "r+b";
+    else
+    if (mode & ZLIB_FILEFUNC_MODE_CREATE)
+        mode_fopen = "wb";
+
+    if ((filename!=NULL) && (mode_fopen != NULL))
+        file = FOPEN_FUNC((const char*)filename, mode_fopen);
+    return file;
+}
+
+
+static uLong ZCALLBACK fread_file_func (voidpf opaque, voidpf stream, void* buf, uLong size)
+{
+    uLong ret;
+    ret = (uLong)fread(buf, 1, (size_t)size, (FILE *)stream);
+    return ret;
+}
+
+static uLong ZCALLBACK fwrite_file_func (voidpf opaque, voidpf stream, const void* buf, uLong size)
+{
+    uLong ret;
+    ret = (uLong)fwrite(buf, 1, (size_t)size, (FILE *)stream);
+    return ret;
+}
+
+static long ZCALLBACK ftell_file_func (voidpf opaque, voidpf stream)
+{
+    long ret;
+    ret = ftell((FILE *)stream);
+    return ret;
+}
+
+
+static ZPOS64_T ZCALLBACK ftell64_file_func (voidpf opaque, voidpf stream)
+{
+    ZPOS64_T ret;
+    ret = FTELLO_FUNC((FILE *)stream);
+    return ret;
+}
+
+static long ZCALLBACK fseek_file_func (voidpf  opaque, voidpf stream, uLong offset, int origin)
+{
+    int fseek_origin=0;
+    long ret;
+    switch (origin)
+    {
+    case ZLIB_FILEFUNC_SEEK_CUR :
+        fseek_origin = SEEK_CUR;
+        break;
+    case ZLIB_FILEFUNC_SEEK_END :
+        fseek_origin = SEEK_END;
+        break;
+    case ZLIB_FILEFUNC_SEEK_SET :
+        fseek_origin = SEEK_SET;
+        break;
+    default: return -1;
+    }
+    ret = 0;
+    if (fseek((FILE *)stream, offset, fseek_origin) != 0)
+        ret = -1;
+    return ret;
+}
+
+static long ZCALLBACK fseek64_file_func (voidpf  opaque, voidpf stream, ZPOS64_T offset, int origin)
+{
+    int fseek_origin=0;
+    long ret;
+    switch (origin)
+    {
+    case ZLIB_FILEFUNC_SEEK_CUR :
+        fseek_origin = SEEK_CUR;
+        break;
+    case ZLIB_FILEFUNC_SEEK_END :
+        fseek_origin = SEEK_END;
+        break;
+    case ZLIB_FILEFUNC_SEEK_SET :
+        fseek_origin = SEEK_SET;
+        break;
+    default: return -1;
+    }
+    ret = 0;
+
+    if(FSEEKO_FUNC((FILE *)stream, offset, fseek_origin) != 0)
+                        ret = -1;
+
+    return ret;
+}
+
+
+static int ZCALLBACK fclose_file_func (voidpf opaque, voidpf stream)
+{
+    int ret;
+    ret = fclose((FILE *)stream);
+    return ret;
+}
+
+static int ZCALLBACK ferror_file_func (voidpf opaque, voidpf stream)
+{
+    int ret;
+    ret = ferror((FILE *)stream);
+    return ret;
+}
+
+void fill_fopen_filefunc (pzlib_filefunc_def)
+  zlib_filefunc_def* pzlib_filefunc_def;
+{
+    pzlib_filefunc_def->zopen_file = fopen_file_func;
+    pzlib_filefunc_def->zread_file = fread_file_func;
+    pzlib_filefunc_def->zwrite_file = fwrite_file_func;
+    pzlib_filefunc_def->ztell_file = ftell_file_func;
+    pzlib_filefunc_def->zseek_file = fseek_file_func;
+    pzlib_filefunc_def->zclose_file = fclose_file_func;
+    pzlib_filefunc_def->zerror_file = ferror_file_func;
+    pzlib_filefunc_def->opaque = NULL;
+}
+
+void fill_fopen64_filefunc (zlib_filefunc64_def*  pzlib_filefunc_def)
+{
+    pzlib_filefunc_def->zopen64_file = fopen64_file_func;
+    pzlib_filefunc_def->zread_file = fread_file_func;
+    pzlib_filefunc_def->zwrite_file = fwrite_file_func;
+    pzlib_filefunc_def->ztell64_file = ftell64_file_func;
+    pzlib_filefunc_def->zseek64_file = fseek64_file_func;
+    pzlib_filefunc_def->zclose_file = fclose_file_func;
+    pzlib_filefunc_def->zerror_file = ferror_file_func;
+    pzlib_filefunc_def->opaque = NULL;
+}
diff --git a/compat/zlib/contrib/minizip/ioapi.h b/compat/zlib/contrib/minizip/ioapi.h
new file mode 100644
index 0000000..8dcbdb0
--- /dev/null
+++ b/compat/zlib/contrib/minizip/ioapi.h
@@ -0,0 +1,208 @@
+/* ioapi.h -- IO base function header for compress/uncompress .zip
+   part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
+
+         Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
+
+         Modifications for Zip64 support
+         Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
+
+         For more info read MiniZip_info.txt
+
+         Changes
+
+    Oct-2009 - Defined ZPOS64_T to fpos_t on windows and u_int64_t on linux. (might need to find a better why for this)
+    Oct-2009 - Change to fseeko64, ftello64 and fopen64 so large files would work on linux.
+               More if/def section may be needed to support other platforms
+    Oct-2009 - Defined fxxxx64 calls to normal fopen/ftell/fseek so they would compile on windows.
+                          (but you should use iowin32.c for windows instead)
+
+*/
+
+#ifndef _ZLIBIOAPI64_H
+#define _ZLIBIOAPI64_H
+
+#if (!defined(_WIN32)) && (!defined(WIN32)) && (!defined(__APPLE__))
+
+  // Linux needs this to support file operation on files larger then 4+GB
+  // But might need better if/def to select just the platforms that needs them.
+
+        #ifndef __USE_FILE_OFFSET64
+                #define __USE_FILE_OFFSET64
+        #endif
+        #ifndef __USE_LARGEFILE64
+                #define __USE_LARGEFILE64
+        #endif
+        #ifndef _LARGEFILE64_SOURCE
+                #define _LARGEFILE64_SOURCE
+        #endif
+        #ifndef _FILE_OFFSET_BIT
+                #define _FILE_OFFSET_BIT 64
+        #endif
+
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "zlib.h"
+
+#if defined(USE_FILE32API)
+#define fopen64 fopen
+#define ftello64 ftell
+#define fseeko64 fseek
+#else
+#ifdef __FreeBSD__
+#define fopen64 fopen
+#define ftello64 ftello
+#define fseeko64 fseeko
+#endif
+#ifdef _MSC_VER
+ #define fopen64 fopen
+ #if (_MSC_VER >= 1400) && (!(defined(NO_MSCVER_FILE64_FUNC)))
+  #define ftello64 _ftelli64
+  #define fseeko64 _fseeki64
+ #else // old MSC
+  #define ftello64 ftell
+  #define fseeko64 fseek
+ #endif
+#endif
+#endif
+
+/*
+#ifndef ZPOS64_T
+  #ifdef _WIN32
+                #define ZPOS64_T fpos_t
+  #else
+    #include <stdint.h>
+    #define ZPOS64_T uint64_t
+  #endif
+#endif
+*/
+
+#ifdef HAVE_MINIZIP64_CONF_H
+#include "mz64conf.h"
+#endif
+
+/* a type choosen by DEFINE */
+#ifdef HAVE_64BIT_INT_CUSTOM
+typedef  64BIT_INT_CUSTOM_TYPE ZPOS64_T;
+#else
+#ifdef HAS_STDINT_H
+#include "stdint.h"
+typedef uint64_t ZPOS64_T;
+#else
+
+/* Maximum unsigned 32-bit value used as placeholder for zip64 */
+#define MAXU32 0xffffffff
+
+#if defined(_MSC_VER) || defined(__BORLANDC__)
+typedef unsigned __int64 ZPOS64_T;
+#else
+typedef unsigned long long int ZPOS64_T;
+#endif
+#endif
+#endif
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#define ZLIB_FILEFUNC_SEEK_CUR (1)
+#define ZLIB_FILEFUNC_SEEK_END (2)
+#define ZLIB_FILEFUNC_SEEK_SET (0)
+
+#define ZLIB_FILEFUNC_MODE_READ      (1)
+#define ZLIB_FILEFUNC_MODE_WRITE     (2)
+#define ZLIB_FILEFUNC_MODE_READWRITEFILTER (3)
+
+#define ZLIB_FILEFUNC_MODE_EXISTING (4)
+#define ZLIB_FILEFUNC_MODE_CREATE   (8)
+
+
+#ifndef ZCALLBACK
+ #if (defined(WIN32) || defined(_WIN32) || defined (WINDOWS) || defined (_WINDOWS)) && defined(CALLBACK) && defined (USEWINDOWS_CALLBACK)
+   #define ZCALLBACK CALLBACK
+ #else
+   #define ZCALLBACK
+ #endif
+#endif
+
+
+
+
+typedef voidpf   (ZCALLBACK *open_file_func)      OF((voidpf opaque, const char* filename, int mode));
+typedef uLong    (ZCALLBACK *read_file_func)      OF((voidpf opaque, voidpf stream, void* buf, uLong size));
+typedef uLong    (ZCALLBACK *write_file_func)     OF((voidpf opaque, voidpf stream, const void* buf, uLong size));
+typedef int      (ZCALLBACK *close_file_func)     OF((voidpf opaque, voidpf stream));
+typedef int      (ZCALLBACK *testerror_file_func) OF((voidpf opaque, voidpf stream));
+
+typedef long     (ZCALLBACK *tell_file_func)      OF((voidpf opaque, voidpf stream));
+typedef long     (ZCALLBACK *seek_file_func)      OF((voidpf opaque, voidpf stream, uLong offset, int origin));
+
+
+/* here is the "old" 32 bits structure structure */
+typedef struct zlib_filefunc_def_s
+{
+    open_file_func      zopen_file;
+    read_file_func      zread_file;
+    write_file_func     zwrite_file;
+    tell_file_func      ztell_file;
+    seek_file_func      zseek_file;
+    close_file_func     zclose_file;
+    testerror_file_func zerror_file;
+    voidpf              opaque;
+} zlib_filefunc_def;
+
+typedef ZPOS64_T (ZCALLBACK *tell64_file_func)    OF((voidpf opaque, voidpf stream));
+typedef long     (ZCALLBACK *seek64_file_func)    OF((voidpf opaque, voidpf stream, ZPOS64_T offset, int origin));
+typedef voidpf   (ZCALLBACK *open64_file_func)    OF((voidpf opaque, const void* filename, int mode));
+
+typedef struct zlib_filefunc64_def_s
+{
+    open64_file_func    zopen64_file;
+    read_file_func      zread_file;
+    write_file_func     zwrite_file;
+    tell64_file_func    ztell64_file;
+    seek64_file_func    zseek64_file;
+    close_file_func     zclose_file;
+    testerror_file_func zerror_file;
+    voidpf              opaque;
+} zlib_filefunc64_def;
+
+void fill_fopen64_filefunc OF((zlib_filefunc64_def* pzlib_filefunc_def));
+void fill_fopen_filefunc OF((zlib_filefunc_def* pzlib_filefunc_def));
+
+/* now internal definition, only for zip.c and unzip.h */
+typedef struct zlib_filefunc64_32_def_s
+{
+    zlib_filefunc64_def zfile_func64;
+    open_file_func      zopen32_file;
+    tell_file_func      ztell32_file;
+    seek_file_func      zseek32_file;
+} zlib_filefunc64_32_def;
+
+
+#define ZREAD64(filefunc,filestream,buf,size)     ((*((filefunc).zfile_func64.zread_file))   ((filefunc).zfile_func64.opaque,filestream,buf,size))
+#define ZWRITE64(filefunc,filestream,buf,size)    ((*((filefunc).zfile_func64.zwrite_file))  ((filefunc).zfile_func64.opaque,filestream,buf,size))
+//#define ZTELL64(filefunc,filestream)            ((*((filefunc).ztell64_file)) ((filefunc).opaque,filestream))
+//#define ZSEEK64(filefunc,filestream,pos,mode)   ((*((filefunc).zseek64_file)) ((filefunc).opaque,filestream,pos,mode))
+#define ZCLOSE64(filefunc,filestream)             ((*((filefunc).zfile_func64.zclose_file))  ((filefunc).zfile_func64.opaque,filestream))
+#define ZERROR64(filefunc,filestream)             ((*((filefunc).zfile_func64.zerror_file))  ((filefunc).zfile_func64.opaque,filestream))
+
+voidpf call_zopen64 OF((const zlib_filefunc64_32_def* pfilefunc,const void*filename,int mode));
+long    call_zseek64 OF((const zlib_filefunc64_32_def* pfilefunc,voidpf filestream, ZPOS64_T offset, int origin));
+ZPOS64_T call_ztell64 OF((const zlib_filefunc64_32_def* pfilefunc,voidpf filestream));
+
+void    fill_zlib_filefunc64_32_def_from_filefunc32(zlib_filefunc64_32_def* p_filefunc64_32,const zlib_filefunc_def* p_filefunc32);
+
+#define ZOPEN64(filefunc,filename,mode)         (call_zopen64((&(filefunc)),(filename),(mode)))
+#define ZTELL64(filefunc,filestream)            (call_ztell64((&(filefunc)),(filestream)))
+#define ZSEEK64(filefunc,filestream,pos,mode)   (call_zseek64((&(filefunc)),(filestream),(pos),(mode)))
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/compat/zlib/contrib/minizip/iowin32.c b/compat/zlib/contrib/minizip/iowin32.c
new file mode 100644
index 0000000..a46d96c
--- /dev/null
+++ b/compat/zlib/contrib/minizip/iowin32.c
@@ -0,0 +1,461 @@
+/* iowin32.c -- IO base function header for compress/uncompress .zip
+     Version 1.1, February 14h, 2010
+     part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
+
+         Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
+
+         Modifications for Zip64 support
+         Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
+
+     For more info read MiniZip_info.txt
+
+*/
+
+#include <stdlib.h>
+
+#include "zlib.h"
+#include "ioapi.h"
+#include "iowin32.h"
+
+#ifndef INVALID_HANDLE_VALUE
+#define INVALID_HANDLE_VALUE (0xFFFFFFFF)
+#endif
+
+#ifndef INVALID_SET_FILE_POINTER
+#define INVALID_SET_FILE_POINTER ((DWORD)-1)
+#endif
+
+
+#if defined(WINAPI_FAMILY_PARTITION) && (!(defined(IOWIN32_USING_WINRT_API)))
+#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP)
+#define IOWIN32_USING_WINRT_API 1
+#endif
+#endif
+
+voidpf  ZCALLBACK win32_open_file_func  OF((voidpf opaque, const char* filename, int mode));
+uLong   ZCALLBACK win32_read_file_func  OF((voidpf opaque, voidpf stream, void* buf, uLong size));
+uLong   ZCALLBACK win32_write_file_func OF((voidpf opaque, voidpf stream, const void* buf, uLong size));
+ZPOS64_T ZCALLBACK win32_tell64_file_func  OF((voidpf opaque, voidpf stream));
+long    ZCALLBACK win32_seek64_file_func  OF((voidpf opaque, voidpf stream, ZPOS64_T offset, int origin));
+int     ZCALLBACK win32_close_file_func OF((voidpf opaque, voidpf stream));
+int     ZCALLBACK win32_error_file_func OF((voidpf opaque, voidpf stream));
+
+typedef struct
+{
+    HANDLE hf;
+    int error;
+} WIN32FILE_IOWIN;
+
+
+static void win32_translate_open_mode(int mode,
+                                      DWORD* lpdwDesiredAccess,
+                                      DWORD* lpdwCreationDisposition,
+                                      DWORD* lpdwShareMode,
+                                      DWORD* lpdwFlagsAndAttributes)
+{
+    *lpdwDesiredAccess = *lpdwShareMode = *lpdwFlagsAndAttributes = *lpdwCreationDisposition = 0;
+
+    if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ)
+    {
+        *lpdwDesiredAccess = GENERIC_READ;
+        *lpdwCreationDisposition = OPEN_EXISTING;
+        *lpdwShareMode = FILE_SHARE_READ;
+    }
+    else if (mode & ZLIB_FILEFUNC_MODE_EXISTING)
+    {
+        *lpdwDesiredAccess = GENERIC_WRITE | GENERIC_READ;
+        *lpdwCreationDisposition = OPEN_EXISTING;
+    }
+    else if (mode & ZLIB_FILEFUNC_MODE_CREATE)
+    {
+        *lpdwDesiredAccess = GENERIC_WRITE | GENERIC_READ;
+        *lpdwCreationDisposition = CREATE_ALWAYS;
+    }
+}
+
+static voidpf win32_build_iowin(HANDLE hFile)
+{
+    voidpf ret=NULL;
+
+    if ((hFile != NULL) && (hFile != INVALID_HANDLE_VALUE))
+    {
+        WIN32FILE_IOWIN w32fiow;
+        w32fiow.hf = hFile;
+        w32fiow.error = 0;
+        ret = malloc(sizeof(WIN32FILE_IOWIN));
+
+        if (ret==NULL)
+            CloseHandle(hFile);
+        else
+            *((WIN32FILE_IOWIN*)ret) = w32fiow;
+    }
+    return ret;
+}
+
+voidpf ZCALLBACK win32_open64_file_func (voidpf opaque,const void* filename,int mode)
+{
+    const char* mode_fopen = NULL;
+    DWORD dwDesiredAccess,dwCreationDisposition,dwShareMode,dwFlagsAndAttributes ;
+    HANDLE hFile = NULL;
+
+    win32_translate_open_mode(mode,&dwDesiredAccess,&dwCreationDisposition,&dwShareMode,&dwFlagsAndAttributes);
+
+#ifdef IOWIN32_USING_WINRT_API
+#ifdef UNICODE
+    if ((filename!=NULL) && (dwDesiredAccess != 0))
+        hFile = CreateFile2((LPCTSTR)filename, dwDesiredAccess, dwShareMode, dwCreationDisposition, NULL);
+#else
+    if ((filename!=NULL) && (dwDesiredAccess != 0))
+    {
+        WCHAR filenameW[FILENAME_MAX + 0x200 + 1];
+        MultiByteToWideChar(CP_ACP,0,(const char*)filename,-1,filenameW,FILENAME_MAX + 0x200);
+        hFile = CreateFile2(filenameW, dwDesiredAccess, dwShareMode, dwCreationDisposition, NULL);
+    }
+#endif
+#else
+    if ((filename!=NULL) && (dwDesiredAccess != 0))
+        hFile = CreateFile((LPCTSTR)filename, dwDesiredAccess, dwShareMode, NULL, dwCreationDisposition, dwFlagsAndAttributes, NULL);
+#endif
+
+    return win32_build_iowin(hFile);
+}
+
+
+voidpf ZCALLBACK win32_open64_file_funcA (voidpf opaque,const void* filename,int mode)
+{
+    const char* mode_fopen = NULL;
+    DWORD dwDesiredAccess,dwCreationDisposition,dwShareMode,dwFlagsAndAttributes ;
+    HANDLE hFile = NULL;
+
+    win32_translate_open_mode(mode,&dwDesiredAccess,&dwCreationDisposition,&dwShareMode,&dwFlagsAndAttributes);
+
+#ifdef IOWIN32_USING_WINRT_API
+    if ((filename!=NULL) && (dwDesiredAccess != 0))
+    {
+        WCHAR filenameW[FILENAME_MAX + 0x200 + 1];
+        MultiByteToWideChar(CP_ACP,0,(const char*)filename,-1,filenameW,FILENAME_MAX + 0x200);
+        hFile = CreateFile2(filenameW, dwDesiredAccess, dwShareMode, dwCreationDisposition, NULL);
+    }
+#else
+    if ((filename!=NULL) && (dwDesiredAccess != 0))
+        hFile = CreateFileA((LPCSTR)filename, dwDesiredAccess, dwShareMode, NULL, dwCreationDisposition, dwFlagsAndAttributes, NULL);
+#endif
+
+    return win32_build_iowin(hFile);
+}
+
+
+voidpf ZCALLBACK win32_open64_file_funcW (voidpf opaque,const void* filename,int mode)
+{
+    const char* mode_fopen = NULL;
+    DWORD dwDesiredAccess,dwCreationDisposition,dwShareMode,dwFlagsAndAttributes ;
+    HANDLE hFile = NULL;
+
+    win32_translate_open_mode(mode,&dwDesiredAccess,&dwCreationDisposition,&dwShareMode,&dwFlagsAndAttributes);
+
+#ifdef IOWIN32_USING_WINRT_API
+    if ((filename!=NULL) && (dwDesiredAccess != 0))
+        hFile = CreateFile2((LPCWSTR)filename, dwDesiredAccess, dwShareMode, dwCreationDisposition,NULL);
+#else
+    if ((filename!=NULL) && (dwDesiredAccess != 0))
+        hFile = CreateFileW((LPCWSTR)filename, dwDesiredAccess, dwShareMode, NULL, dwCreationDisposition, dwFlagsAndAttributes, NULL);
+#endif
+
+    return win32_build_iowin(hFile);
+}
+
+
+voidpf ZCALLBACK win32_open_file_func (voidpf opaque,const char* filename,int mode)
+{
+    const char* mode_fopen = NULL;
+    DWORD dwDesiredAccess,dwCreationDisposition,dwShareMode,dwFlagsAndAttributes ;
+    HANDLE hFile = NULL;
+
+    win32_translate_open_mode(mode,&dwDesiredAccess,&dwCreationDisposition,&dwShareMode,&dwFlagsAndAttributes);
+
+#ifdef IOWIN32_USING_WINRT_API
+#ifdef UNICODE
+    if ((filename!=NULL) && (dwDesiredAccess != 0))
+        hFile = CreateFile2((LPCTSTR)filename, dwDesiredAccess, dwShareMode, dwCreationDisposition, NULL);
+#else
+    if ((filename!=NULL) && (dwDesiredAccess != 0))
+    {
+        WCHAR filenameW[FILENAME_MAX + 0x200 + 1];
+        MultiByteToWideChar(CP_ACP,0,(const char*)filename,-1,filenameW,FILENAME_MAX + 0x200);
+        hFile = CreateFile2(filenameW, dwDesiredAccess, dwShareMode, dwCreationDisposition, NULL);
+    }
+#endif
+#else
+    if ((filename!=NULL) && (dwDesiredAccess != 0))
+        hFile = CreateFile((LPCTSTR)filename, dwDesiredAccess, dwShareMode, NULL, dwCreationDisposition, dwFlagsAndAttributes, NULL);
+#endif
+
+    return win32_build_iowin(hFile);
+}
+
+
+uLong ZCALLBACK win32_read_file_func (voidpf opaque, voidpf stream, void* buf,uLong size)
+{
+    uLong ret=0;
+    HANDLE hFile = NULL;
+    if (stream!=NULL)
+        hFile = ((WIN32FILE_IOWIN*)stream) -> hf;
+
+    if (hFile != NULL)
+    {
+        if (!ReadFile(hFile, buf, size, &ret, NULL))
+        {
+            DWORD dwErr = GetLastError();
+            if (dwErr == ERROR_HANDLE_EOF)
+                dwErr = 0;
+            ((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr;
+        }
+    }
+
+    return ret;
+}
+
+
+uLong ZCALLBACK win32_write_file_func (voidpf opaque,voidpf stream,const void* buf,uLong size)
+{
+    uLong ret=0;
+    HANDLE hFile = NULL;
+    if (stream!=NULL)
+        hFile = ((WIN32FILE_IOWIN*)stream) -> hf;
+
+    if (hFile != NULL)
+    {
+        if (!WriteFile(hFile, buf, size, &ret, NULL))
+        {
+            DWORD dwErr = GetLastError();
+            if (dwErr == ERROR_HANDLE_EOF)
+                dwErr = 0;
+            ((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr;
+        }
+    }
+
+    return ret;
+}
+
+static BOOL MySetFilePointerEx(HANDLE hFile, LARGE_INTEGER pos, LARGE_INTEGER *newPos,  DWORD dwMoveMethod)
+{
+#ifdef IOWIN32_USING_WINRT_API
+    return SetFilePointerEx(hFile, pos, newPos, dwMoveMethod);
+#else
+    LONG lHigh = pos.HighPart;
+    DWORD dwNewPos = SetFilePointer(hFile, pos.LowPart, &lHigh, FILE_CURRENT);
+    BOOL fOk = TRUE;
+    if (dwNewPos == 0xFFFFFFFF)
+        if (GetLastError() != NO_ERROR)
+            fOk = FALSE;
+    if ((newPos != NULL) && (fOk))
+    {
+        newPos->LowPart = dwNewPos;
+        newPos->HighPart = lHigh;
+    }
+    return fOk;
+#endif
+}
+
+long ZCALLBACK win32_tell_file_func (voidpf opaque,voidpf stream)
+{
+    long ret=-1;
+    HANDLE hFile = NULL;
+    if (stream!=NULL)
+        hFile = ((WIN32FILE_IOWIN*)stream) -> hf;
+    if (hFile != NULL)
+    {
+        LARGE_INTEGER pos;
+        pos.QuadPart = 0;
+
+        if (!MySetFilePointerEx(hFile, pos, &pos, FILE_CURRENT))
+        {
+            DWORD dwErr = GetLastError();
+            ((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr;
+            ret = -1;
+        }
+        else
+            ret=(long)pos.LowPart;
+    }
+    return ret;
+}
+
+ZPOS64_T ZCALLBACK win32_tell64_file_func (voidpf opaque, voidpf stream)
+{
+    ZPOS64_T ret= (ZPOS64_T)-1;
+    HANDLE hFile = NULL;
+    if (stream!=NULL)
+        hFile = ((WIN32FILE_IOWIN*)stream)->hf;
+
+    if (hFile)
+    {
+        LARGE_INTEGER pos;
+        pos.QuadPart = 0;
+
+        if (!MySetFilePointerEx(hFile, pos, &pos, FILE_CURRENT))
+        {
+            DWORD dwErr = GetLastError();
+            ((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr;
+            ret = (ZPOS64_T)-1;
+        }
+        else
+            ret=pos.QuadPart;
+    }
+    return ret;
+}
+
+
+long ZCALLBACK win32_seek_file_func (voidpf opaque,voidpf stream,uLong offset,int origin)
+{
+    DWORD dwMoveMethod=0xFFFFFFFF;
+    HANDLE hFile = NULL;
+
+    long ret=-1;
+    if (stream!=NULL)
+        hFile = ((WIN32FILE_IOWIN*)stream) -> hf;
+    switch (origin)
+    {
+    case ZLIB_FILEFUNC_SEEK_CUR :
+        dwMoveMethod = FILE_CURRENT;
+        break;
+    case ZLIB_FILEFUNC_SEEK_END :
+        dwMoveMethod = FILE_END;
+        break;
+    case ZLIB_FILEFUNC_SEEK_SET :
+        dwMoveMethod = FILE_BEGIN;
+        break;
+    default: return -1;
+    }
+
+    if (hFile != NULL)
+    {
+        LARGE_INTEGER pos;
+        pos.QuadPart = offset;
+        if (!MySetFilePointerEx(hFile, pos, NULL, dwMoveMethod))
+        {
+            DWORD dwErr = GetLastError();
+            ((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr;
+            ret = -1;
+        }
+        else
+            ret=0;
+    }
+    return ret;
+}
+
+long ZCALLBACK win32_seek64_file_func (voidpf opaque, voidpf stream,ZPOS64_T offset,int origin)
+{
+    DWORD dwMoveMethod=0xFFFFFFFF;
+    HANDLE hFile = NULL;
+    long ret=-1;
+
+    if (stream!=NULL)
+        hFile = ((WIN32FILE_IOWIN*)stream)->hf;
+
+    switch (origin)
+    {
+        case ZLIB_FILEFUNC_SEEK_CUR :
+            dwMoveMethod = FILE_CURRENT;
+            break;
+        case ZLIB_FILEFUNC_SEEK_END :
+            dwMoveMethod = FILE_END;
+            break;
+        case ZLIB_FILEFUNC_SEEK_SET :
+            dwMoveMethod = FILE_BEGIN;
+            break;
+        default: return -1;
+    }
+
+    if (hFile)
+    {
+        LARGE_INTEGER pos;
+        pos.QuadPart = offset;
+        if (!MySetFilePointerEx(hFile, pos, NULL, FILE_CURRENT))
+        {
+            DWORD dwErr = GetLastError();
+            ((WIN32FILE_IOWIN*)stream) -> error=(int)dwErr;
+            ret = -1;
+        }
+        else
+            ret=0;
+    }
+    return ret;
+}
+
+int ZCALLBACK win32_close_file_func (voidpf opaque, voidpf stream)
+{
+    int ret=-1;
+
+    if (stream!=NULL)
+    {
+        HANDLE hFile;
+        hFile = ((WIN32FILE_IOWIN*)stream) -> hf;
+        if (hFile != NULL)
+        {
+            CloseHandle(hFile);
+            ret=0;
+        }
+        free(stream);
+    }
+    return ret;
+}
+
+int ZCALLBACK win32_error_file_func (voidpf opaque,voidpf stream)
+{
+    int ret=-1;
+    if (stream!=NULL)
+    {
+        ret = ((WIN32FILE_IOWIN*)stream) -> error;
+    }
+    return ret;
+}
+
+void fill_win32_filefunc (zlib_filefunc_def* pzlib_filefunc_def)
+{
+    pzlib_filefunc_def->zopen_file = win32_open_file_func;
+    pzlib_filefunc_def->zread_file = win32_read_file_func;
+    pzlib_filefunc_def->zwrite_file = win32_write_file_func;
+    pzlib_filefunc_def->ztell_file = win32_tell_file_func;
+    pzlib_filefunc_def->zseek_file = win32_seek_file_func;
+    pzlib_filefunc_def->zclose_file = win32_close_file_func;
+    pzlib_filefunc_def->zerror_file = win32_error_file_func;
+    pzlib_filefunc_def->opaque = NULL;
+}
+
+void fill_win32_filefunc64(zlib_filefunc64_def* pzlib_filefunc_def)
+{
+    pzlib_filefunc_def->zopen64_file = win32_open64_file_func;
+    pzlib_filefunc_def->zread_file = win32_read_file_func;
+    pzlib_filefunc_def->zwrite_file = win32_write_file_func;
+    pzlib_filefunc_def->ztell64_file = win32_tell64_file_func;
+    pzlib_filefunc_def->zseek64_file = win32_seek64_file_func;
+    pzlib_filefunc_def->zclose_file = win32_close_file_func;
+    pzlib_filefunc_def->zerror_file = win32_error_file_func;
+    pzlib_filefunc_def->opaque = NULL;
+}
+
+
+void fill_win32_filefunc64A(zlib_filefunc64_def* pzlib_filefunc_def)
+{
+    pzlib_filefunc_def->zopen64_file = win32_open64_file_funcA;
+    pzlib_filefunc_def->zread_file = win32_read_file_func;
+    pzlib_filefunc_def->zwrite_file = win32_write_file_func;
+    pzlib_filefunc_def->ztell64_file = win32_tell64_file_func;
+    pzlib_filefunc_def->zseek64_file = win32_seek64_file_func;
+    pzlib_filefunc_def->zclose_file = win32_close_file_func;
+    pzlib_filefunc_def->zerror_file = win32_error_file_func;
+    pzlib_filefunc_def->opaque = NULL;
+}
+
+
+void fill_win32_filefunc64W(zlib_filefunc64_def* pzlib_filefunc_def)
+{
+    pzlib_filefunc_def->zopen64_file = win32_open64_file_funcW;
+    pzlib_filefunc_def->zread_file = win32_read_file_func;
+    pzlib_filefunc_def->zwrite_file = win32_write_file_func;
+    pzlib_filefunc_def->ztell64_file = win32_tell64_file_func;
+    pzlib_filefunc_def->zseek64_file = win32_seek64_file_func;
+    pzlib_filefunc_def->zclose_file = win32_close_file_func;
+    pzlib_filefunc_def->zerror_file = win32_error_file_func;
+    pzlib_filefunc_def->opaque = NULL;
+}
diff --git a/compat/zlib/contrib/minizip/iowin32.h b/compat/zlib/contrib/minizip/iowin32.h
new file mode 100644
index 0000000..0ca0969
--- /dev/null
+++ b/compat/zlib/contrib/minizip/iowin32.h
@@ -0,0 +1,28 @@
+/* iowin32.h -- IO base function header for compress/uncompress .zip
+     Version 1.1, February 14h, 2010
+     part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
+
+         Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
+
+         Modifications for Zip64 support
+         Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
+
+         For more info read MiniZip_info.txt
+
+*/
+
+#include <windows.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void fill_win32_filefunc OF((zlib_filefunc_def* pzlib_filefunc_def));
+void fill_win32_filefunc64 OF((zlib_filefunc64_def* pzlib_filefunc_def));
+void fill_win32_filefunc64A OF((zlib_filefunc64_def* pzlib_filefunc_def));
+void fill_win32_filefunc64W OF((zlib_filefunc64_def* pzlib_filefunc_def));
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/compat/zlib/contrib/minizip/make_vms.com b/compat/zlib/contrib/minizip/make_vms.com
new file mode 100644
index 0000000..9ac13a9
--- /dev/null
+++ b/compat/zlib/contrib/minizip/make_vms.com
@@ -0,0 +1,25 @@
+$ if f$search("ioapi.h_orig") .eqs. "" then copy ioapi.h ioapi.h_orig
+$ open/write zdef vmsdefs.h
+$ copy sys$input: zdef
+$ deck
+#define unix
+#define fill_zlib_filefunc64_32_def_from_filefunc32 fillzffunc64from
+#define Write_Zip64EndOfCentralDirectoryLocator Write_Zip64EoDLocator
+#define Write_Zip64EndOfCentralDirectoryRecord Write_Zip64EoDRecord
+#define Write_EndOfCentralDirectoryRecord Write_EoDRecord
+$ eod
+$ close zdef
+$ copy vmsdefs.h,ioapi.h_orig ioapi.h
+$ cc/include=[--]/prefix=all ioapi.c
+$ cc/include=[--]/prefix=all miniunz.c
+$ cc/include=[--]/prefix=all unzip.c
+$ cc/include=[--]/prefix=all minizip.c
+$ cc/include=[--]/prefix=all zip.c
+$ link miniunz,unzip,ioapi,[--]libz.olb/lib
+$ link minizip,zip,ioapi,[--]libz.olb/lib
+$ mcr []minizip test minizip_info.txt
+$ mcr []miniunz -l test.zip
+$ rename minizip_info.txt; minizip_info.txt_old
+$ mcr []miniunz test.zip
+$ delete test.zip;*
+$exit
diff --git a/compat/zlib/contrib/minizip/miniunz.c b/compat/zlib/contrib/minizip/miniunz.c
new file mode 100644
index 0000000..3d65401
--- /dev/null
+++ b/compat/zlib/contrib/minizip/miniunz.c
@@ -0,0 +1,660 @@
+/*
+   miniunz.c
+   Version 1.1, February 14h, 2010
+   sample part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
+
+         Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
+
+         Modifications of Unzip for Zip64
+         Copyright (C) 2007-2008 Even Rouault
+
+         Modifications for Zip64 support on both zip and unzip
+         Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
+*/
+
+#if (!defined(_WIN32)) && (!defined(WIN32)) && (!defined(__APPLE__))
+        #ifndef __USE_FILE_OFFSET64
+                #define __USE_FILE_OFFSET64
+        #endif
+        #ifndef __USE_LARGEFILE64
+                #define __USE_LARGEFILE64
+        #endif
+        #ifndef _LARGEFILE64_SOURCE
+                #define _LARGEFILE64_SOURCE
+        #endif
+        #ifndef _FILE_OFFSET_BIT
+                #define _FILE_OFFSET_BIT 64
+        #endif
+#endif
+
+#ifdef __APPLE__
+// In darwin and perhaps other BSD variants off_t is a 64 bit value, hence no need for specific 64 bit functions
+#define FOPEN_FUNC(filename, mode) fopen(filename, mode)
+#define FTELLO_FUNC(stream) ftello(stream)
+#define FSEEKO_FUNC(stream, offset, origin) fseeko(stream, offset, origin)
+#else
+#define FOPEN_FUNC(filename, mode) fopen64(filename, mode)
+#define FTELLO_FUNC(stream) ftello64(stream)
+#define FSEEKO_FUNC(stream, offset, origin) fseeko64(stream, offset, origin)
+#endif
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <errno.h>
+#include <fcntl.h>
+
+#ifdef _WIN32
+# include <direct.h>
+# include <io.h>
+#else
+# include <unistd.h>
+# include <utime.h>
+#endif
+
+
+#include "unzip.h"
+
+#define CASESENSITIVITY (0)
+#define WRITEBUFFERSIZE (8192)
+#define MAXFILENAME (256)
+
+#ifdef _WIN32
+#define USEWIN32IOAPI
+#include "iowin32.h"
+#endif
+/*
+  mini unzip, demo of unzip package
+
+  usage :
+  Usage : miniunz [-exvlo] file.zip [file_to_extract] [-d extractdir]
+
+  list the file in the zipfile, and print the content of FILE_ID.ZIP or README.TXT
+    if it exists
+*/
+
+
+/* change_file_date : change the date/time of a file
+    filename : the filename of the file where date/time must be modified
+    dosdate : the new date at the MSDos format (4 bytes)
+    tmu_date : the SAME new date at the tm_unz format */
+void change_file_date(filename,dosdate,tmu_date)
+    const char *filename;
+    uLong dosdate;
+    tm_unz tmu_date;
+{
+#ifdef _WIN32
+  HANDLE hFile;
+  FILETIME ftm,ftLocal,ftCreate,ftLastAcc,ftLastWrite;
+
+  hFile = CreateFileA(filename,GENERIC_READ | GENERIC_WRITE,
+                      0,NULL,OPEN_EXISTING,0,NULL);
+  GetFileTime(hFile,&ftCreate,&ftLastAcc,&ftLastWrite);
+  DosDateTimeToFileTime((WORD)(dosdate>>16),(WORD)dosdate,&ftLocal);
+  LocalFileTimeToFileTime(&ftLocal,&ftm);
+  SetFileTime(hFile,&ftm,&ftLastAcc,&ftm);
+  CloseHandle(hFile);
+#else
+#ifdef unix || __APPLE__
+  struct utimbuf ut;
+  struct tm newdate;
+  newdate.tm_sec = tmu_date.tm_sec;
+  newdate.tm_min=tmu_date.tm_min;
+  newdate.tm_hour=tmu_date.tm_hour;
+  newdate.tm_mday=tmu_date.tm_mday;
+  newdate.tm_mon=tmu_date.tm_mon;
+  if (tmu_date.tm_year > 1900)
+      newdate.tm_year=tmu_date.tm_year - 1900;
+  else
+      newdate.tm_year=tmu_date.tm_year ;
+  newdate.tm_isdst=-1;
+
+  ut.actime=ut.modtime=mktime(&newdate);
+  utime(filename,&ut);
+#endif
+#endif
+}
+
+
+/* mymkdir and change_file_date are not 100 % portable
+   As I don't know well Unix, I wait feedback for the unix portion */
+
+int mymkdir(dirname)
+    const char* dirname;
+{
+    int ret=0;
+#ifdef _WIN32
+    ret = _mkdir(dirname);
+#elif unix
+    ret = mkdir (dirname,0775);
+#elif __APPLE__
+    ret = mkdir (dirname,0775);
+#endif
+    return ret;
+}
+
+int makedir (newdir)
+    char *newdir;
+{
+  char *buffer ;
+  char *p;
+  int  len = (int)strlen(newdir);
+
+  if (len <= 0)
+    return 0;
+
+  buffer = (char*)malloc(len+1);
+        if (buffer==NULL)
+        {
+                printf("Error allocating memory\n");
+                return UNZ_INTERNALERROR;
+        }
+  strcpy(buffer,newdir);
+
+  if (buffer[len-1] == '/') {
+    buffer[len-1] = '\0';
+  }
+  if (mymkdir(buffer) == 0)
+    {
+      free(buffer);
+      return 1;
+    }
+
+  p = buffer+1;
+  while (1)
+    {
+      char hold;
+
+      while(*p && *p != '\\' && *p != '/')
+        p++;
+      hold = *p;
+      *p = 0;
+      if ((mymkdir(buffer) == -1) && (errno == ENOENT))
+        {
+          printf("couldn't create directory %s\n",buffer);
+          free(buffer);
+          return 0;
+        }
+      if (hold == 0)
+        break;
+      *p++ = hold;
+    }
+  free(buffer);
+  return 1;
+}
+
+void do_banner()
+{
+    printf("MiniUnz 1.01b, demo of zLib + Unz package written by Gilles Vollant\n");
+    printf("more info at http://www.winimage.com/zLibDll/unzip.html\n\n");
+}
+
+void do_help()
+{
+    printf("Usage : miniunz [-e] [-x] [-v] [-l] [-o] [-p password] file.zip [file_to_extr.] [-d extractdir]\n\n" \
+           "  -e  Extract without pathname (junk paths)\n" \
+           "  -x  Extract with pathname\n" \
+           "  -v  list files\n" \
+           "  -l  list files\n" \
+           "  -d  directory to extract into\n" \
+           "  -o  overwrite files without prompting\n" \
+           "  -p  extract crypted file using password\n\n");
+}
+
+void Display64BitsSize(ZPOS64_T n, int size_char)
+{
+  /* to avoid compatibility problem , we do here the conversion */
+  char number[21];
+  int offset=19;
+  int pos_string = 19;
+  number[20]=0;
+  for (;;) {
+      number[offset]=(char)((n%10)+'0');
+      if (number[offset] != '0')
+          pos_string=offset;
+      n/=10;
+      if (offset==0)
+          break;
+      offset--;
+  }
+  {
+      int size_display_string = 19-pos_string;
+      while (size_char > size_display_string)
+      {
+          size_char--;
+          printf(" ");
+      }
+  }
+
+  printf("%s",&number[pos_string]);
+}
+
+int do_list(uf)
+    unzFile uf;
+{
+    uLong i;
+    unz_global_info64 gi;
+    int err;
+
+    err = unzGetGlobalInfo64(uf,&gi);
+    if (err!=UNZ_OK)
+        printf("error %d with zipfile in unzGetGlobalInfo \n",err);
+    printf("  Length  Method     Size Ratio   Date    Time   CRC-32     Name\n");
+    printf("  ------  ------     ---- -----   ----    ----   ------     ----\n");
+    for (i=0;i<gi.number_entry;i++)
+    {
+        char filename_inzip[256];
+        unz_file_info64 file_info;
+        uLong ratio=0;
+        const char *string_method;
+        char charCrypt=' ';
+        err = unzGetCurrentFileInfo64(uf,&file_info,filename_inzip,sizeof(filename_inzip),NULL,0,NULL,0);
+        if (err!=UNZ_OK)
+        {
+            printf("error %d with zipfile in unzGetCurrentFileInfo\n",err);
+            break;
+        }
+        if (file_info.uncompressed_size>0)
+            ratio = (uLong)((file_info.compressed_size*100)/file_info.uncompressed_size);
+
+        /* display a '*' if the file is crypted */
+        if ((file_info.flag & 1) != 0)
+            charCrypt='*';
+
+        if (file_info.compression_method==0)
+            string_method="Stored";
+        else
+        if (file_info.compression_method==Z_DEFLATED)
+        {
+            uInt iLevel=(uInt)((file_info.flag & 0x6)/2);
+            if (iLevel==0)
+              string_method="Defl:N";
+            else if (iLevel==1)
+              string_method="Defl:X";
+            else if ((iLevel==2) || (iLevel==3))
+              string_method="Defl:F"; /* 2:fast , 3 : extra fast*/
+        }
+        else
+        if (file_info.compression_method==Z_BZIP2ED)
+        {
+              string_method="BZip2 ";
+        }
+        else
+            string_method="Unkn. ";
+
+        Display64BitsSize(file_info.uncompressed_size,7);
+        printf("  %6s%c",string_method,charCrypt);
+        Display64BitsSize(file_info.compressed_size,7);
+        printf(" %3lu%%  %2.2lu-%2.2lu-%2.2lu  %2.2lu:%2.2lu  %8.8lx   %s\n",
+                ratio,
+                (uLong)file_info.tmu_date.tm_mon + 1,
+                (uLong)file_info.tmu_date.tm_mday,
+                (uLong)file_info.tmu_date.tm_year % 100,
+                (uLong)file_info.tmu_date.tm_hour,(uLong)file_info.tmu_date.tm_min,
+                (uLong)file_info.crc,filename_inzip);
+        if ((i+1)<gi.number_entry)
+        {
+            err = unzGoToNextFile(uf);
+            if (err!=UNZ_OK)
+            {
+                printf("error %d with zipfile in unzGoToNextFile\n",err);
+                break;
+            }
+        }
+    }
+
+    return 0;
+}
+
+
+int do_extract_currentfile(uf,popt_extract_without_path,popt_overwrite,password)
+    unzFile uf;
+    const int* popt_extract_without_path;
+    int* popt_overwrite;
+    const char* password;
+{
+    char filename_inzip[256];
+    char* filename_withoutpath;
+    char* p;
+    int err=UNZ_OK;
+    FILE *fout=NULL;
+    void* buf;
+    uInt size_buf;
+
+    unz_file_info64 file_info;
+    uLong ratio=0;
+    err = unzGetCurrentFileInfo64(uf,&file_info,filename_inzip,sizeof(filename_inzip),NULL,0,NULL,0);
+
+    if (err!=UNZ_OK)
+    {
+        printf("error %d with zipfile in unzGetCurrentFileInfo\n",err);
+        return err;
+    }
+
+    size_buf = WRITEBUFFERSIZE;
+    buf = (void*)malloc(size_buf);
+    if (buf==NULL)
+    {
+        printf("Error allocating memory\n");
+        return UNZ_INTERNALERROR;
+    }
+
+    p = filename_withoutpath = filename_inzip;
+    while ((*p) != '\0')
+    {
+        if (((*p)=='/') || ((*p)=='\\'))
+            filename_withoutpath = p+1;
+        p++;
+    }
+
+    if ((*filename_withoutpath)=='\0')
+    {
+        if ((*popt_extract_without_path)==0)
+        {
+            printf("creating directory: %s\n",filename_inzip);
+            mymkdir(filename_inzip);
+        }
+    }
+    else
+    {
+        const char* write_filename;
+        int skip=0;
+
+        if ((*popt_extract_without_path)==0)
+            write_filename = filename_inzip;
+        else
+            write_filename = filename_withoutpath;
+
+        err = unzOpenCurrentFilePassword(uf,password);
+        if (err!=UNZ_OK)
+        {
+            printf("error %d with zipfile in unzOpenCurrentFilePassword\n",err);
+        }
+
+        if (((*popt_overwrite)==0) && (err==UNZ_OK))
+        {
+            char rep=0;
+            FILE* ftestexist;
+            ftestexist = FOPEN_FUNC(write_filename,"rb");
+            if (ftestexist!=NULL)
+            {
+                fclose(ftestexist);
+                do
+                {
+                    char answer[128];
+                    int ret;
+
+                    printf("The file %s exists. Overwrite ? [y]es, [n]o, [A]ll: ",write_filename);
+                    ret = scanf("%1s",answer);
+                    if (ret != 1)
+                    {
+                       exit(EXIT_FAILURE);
+                    }
+                    rep = answer[0] ;
+                    if ((rep>='a') && (rep<='z'))
+                        rep -= 0x20;
+                }
+                while ((rep!='Y') && (rep!='N') && (rep!='A'));
+            }
+
+            if (rep == 'N')
+                skip = 1;
+
+            if (rep == 'A')
+                *popt_overwrite=1;
+        }
+
+        if ((skip==0) && (err==UNZ_OK))
+        {
+            fout=FOPEN_FUNC(write_filename,"wb");
+            /* some zipfile don't contain directory alone before file */
+            if ((fout==NULL) && ((*popt_extract_without_path)==0) &&
+                                (filename_withoutpath!=(char*)filename_inzip))
+            {
+                char c=*(filename_withoutpath-1);
+                *(filename_withoutpath-1)='\0';
+                makedir(write_filename);
+                *(filename_withoutpath-1)=c;
+                fout=FOPEN_FUNC(write_filename,"wb");
+            }
+
+            if (fout==NULL)
+            {
+                printf("error opening %s\n",write_filename);
+            }
+        }
+
+        if (fout!=NULL)
+        {
+            printf(" extracting: %s\n",write_filename);
+
+            do
+            {
+                err = unzReadCurrentFile(uf,buf,size_buf);
+                if (err<0)
+                {
+                    printf("error %d with zipfile in unzReadCurrentFile\n",err);
+                    break;
+                }
+                if (err>0)
+                    if (fwrite(buf,err,1,fout)!=1)
+                    {
+                        printf("error in writing extracted file\n");
+                        err=UNZ_ERRNO;
+                        break;
+                    }
+            }
+            while (err>0);
+            if (fout)
+                    fclose(fout);
+
+            if (err==0)
+                change_file_date(write_filename,file_info.dosDate,
+                                 file_info.tmu_date);
+        }
+
+        if (err==UNZ_OK)
+        {
+            err = unzCloseCurrentFile (uf);
+            if (err!=UNZ_OK)
+            {
+                printf("error %d with zipfile in unzCloseCurrentFile\n",err);
+            }
+        }
+        else
+            unzCloseCurrentFile(uf); /* don't lose the error */
+    }
+
+    free(buf);
+    return err;
+}
+
+
+int do_extract(uf,opt_extract_without_path,opt_overwrite,password)
+    unzFile uf;
+    int opt_extract_without_path;
+    int opt_overwrite;
+    const char* password;
+{
+    uLong i;
+    unz_global_info64 gi;
+    int err;
+    FILE* fout=NULL;
+
+    err = unzGetGlobalInfo64(uf,&gi);
+    if (err!=UNZ_OK)
+        printf("error %d with zipfile in unzGetGlobalInfo \n",err);
+
+    for (i=0;i<gi.number_entry;i++)
+    {
+        if (do_extract_currentfile(uf,&opt_extract_without_path,
+                                      &opt_overwrite,
+                                      password) != UNZ_OK)
+            break;
+
+        if ((i+1)<gi.number_entry)
+        {
+            err = unzGoToNextFile(uf);
+            if (err!=UNZ_OK)
+            {
+                printf("error %d with zipfile in unzGoToNextFile\n",err);
+                break;
+            }
+        }
+    }
+
+    return 0;
+}
+
+int do_extract_onefile(uf,filename,opt_extract_without_path,opt_overwrite,password)
+    unzFile uf;
+    const char* filename;
+    int opt_extract_without_path;
+    int opt_overwrite;
+    const char* password;
+{
+    int err = UNZ_OK;
+    if (unzLocateFile(uf,filename,CASESENSITIVITY)!=UNZ_OK)
+    {
+        printf("file %s not found in the zipfile\n",filename);
+        return 2;
+    }
+
+    if (do_extract_currentfile(uf,&opt_extract_without_path,
+                                      &opt_overwrite,
+                                      password) == UNZ_OK)
+        return 0;
+    else
+        return 1;
+}
+
+
+int main(argc,argv)
+    int argc;
+    char *argv[];
+{
+    const char *zipfilename=NULL;
+    const char *filename_to_extract=NULL;
+    const char *password=NULL;
+    char filename_try[MAXFILENAME+16] = "";
+    int i;
+    int ret_value=0;
+    int opt_do_list=0;
+    int opt_do_extract=1;
+    int opt_do_extract_withoutpath=0;
+    int opt_overwrite=0;
+    int opt_extractdir=0;
+    const char *dirname=NULL;
+    unzFile uf=NULL;
+
+    do_banner();
+    if (argc==1)
+    {
+        do_help();
+        return 0;
+    }
+    else
+    {
+        for (i=1;i<argc;i++)
+        {
+            if ((*argv[i])=='-')
+            {
+                const char *p=argv[i]+1;
+
+                while ((*p)!='\0')
+                {
+                    char c=*(p++);;
+                    if ((c=='l') || (c=='L'))
+                        opt_do_list = 1;
+                    if ((c=='v') || (c=='V'))
+                        opt_do_list = 1;
+                    if ((c=='x') || (c=='X'))
+                        opt_do_extract = 1;
+                    if ((c=='e') || (c=='E'))
+                        opt_do_extract = opt_do_extract_withoutpath = 1;
+                    if ((c=='o') || (c=='O'))
+                        opt_overwrite=1;
+                    if ((c=='d') || (c=='D'))
+                    {
+                        opt_extractdir=1;
+                        dirname=argv[i+1];
+                    }
+
+                    if (((c=='p') || (c=='P')) && (i+1<argc))
+                    {
+                        password=argv[i+1];
+                        i++;
+                    }
+                }
+            }
+            else
+            {
+                if (zipfilename == NULL)
+                    zipfilename = argv[i];
+                else if ((filename_to_extract==NULL) && (!opt_extractdir))
+                        filename_to_extract = argv[i] ;
+            }
+        }
+    }
+
+    if (zipfilename!=NULL)
+    {
+
+#        ifdef USEWIN32IOAPI
+        zlib_filefunc64_def ffunc;
+#        endif
+
+        strncpy(filename_try, zipfilename,MAXFILENAME-1);
+        /* strncpy doesnt append the trailing NULL, of the string is too long. */
+        filename_try[ MAXFILENAME ] = '\0';
+
+#        ifdef USEWIN32IOAPI
+        fill_win32_filefunc64A(&ffunc);
+        uf = unzOpen2_64(zipfilename,&ffunc);
+#        else
+        uf = unzOpen64(zipfilename);
+#        endif
+        if (uf==NULL)
+        {
+            strcat(filename_try,".zip");
+#            ifdef USEWIN32IOAPI
+            uf = unzOpen2_64(filename_try,&ffunc);
+#            else
+            uf = unzOpen64(filename_try);
+#            endif
+        }
+    }
+
+    if (uf==NULL)
+    {
+        printf("Cannot open %s or %s.zip\n",zipfilename,zipfilename);
+        return 1;
+    }
+    printf("%s opened\n",filename_try);
+
+    if (opt_do_list==1)
+        ret_value = do_list(uf);
+    else if (opt_do_extract==1)
+    {
+#ifdef _WIN32
+        if (opt_extractdir && _chdir(dirname))
+#else
+        if (opt_extractdir && chdir(dirname))
+#endif
+        {
+          printf("Error changing into %s, aborting\n", dirname);
+          exit(-1);
+        }
+
+        if (filename_to_extract == NULL)
+            ret_value = do_extract(uf, opt_do_extract_withoutpath, opt_overwrite, password);
+        else
+            ret_value = do_extract_onefile(uf, filename_to_extract, opt_do_extract_withoutpath, opt_overwrite, password);
+    }
+
+    unzClose(uf);
+
+    return ret_value;
+}
diff --git a/compat/zlib/contrib/minizip/miniunzip.1 b/compat/zlib/contrib/minizip/miniunzip.1
new file mode 100644
index 0000000..111ac69
--- /dev/null
+++ b/compat/zlib/contrib/minizip/miniunzip.1
@@ -0,0 +1,63 @@
+.\"                                      Hey, EMACS: -*- nroff -*-
+.TH miniunzip 1 "Nov 7, 2001"
+.\" Please adjust this date whenever revising the manpage.
+.\"
+.\" Some roff macros, for reference:
+.\" .nh        disable hyphenation
+.\" .hy        enable hyphenation
+.\" .ad l      left justify
+.\" .ad b      justify to both left and right margins
+.\" .nf        disable filling
+.\" .fi        enable filling
+.\" .br        insert line break
+.\" .sp <n>    insert n+1 empty lines
+.\" for manpage-specific macros, see man(7)
+.SH NAME
+miniunzip - uncompress and examine ZIP archives
+.SH SYNOPSIS
+.B miniunzip
+.RI [ -exvlo ]
+zipfile [ files_to_extract ] [-d tempdir]
+.SH DESCRIPTION
+.B minizip
+is a simple tool which allows the extraction of compressed file
+archives in the ZIP format used by the MS-DOS utility PKZIP.  It was
+written as a demonstration of the
+.IR zlib (3)
+library and therefore lack many of the features of the
+.IR unzip (1)
+program.
+.SH OPTIONS
+A number of options are supported.  With the exception of
+.BI \-d\  tempdir
+these must be supplied before any
+other arguments and are:
+.TP
+.BI \-l\ ,\ \-\-v
+List the files in the archive without extracting them.
+.TP
+.B \-o
+Overwrite files without prompting for confirmation.
+.TP
+.B \-x
+Extract files (default).
+.PP
+The
+.I zipfile
+argument is the name of the archive to process. The next argument can be used
+to specify a single file to extract from the archive.
+
+Lastly, the following option can be specified at the end of the command-line:
+.TP
+.BI \-d\  tempdir
+Extract the archive in the directory
+.I tempdir
+rather than the current directory.
+.SH SEE ALSO
+.BR minizip (1),
+.BR zlib (3),
+.BR unzip (1).
+.SH AUTHOR
+This program was written by Gilles Vollant.  This manual page was
+written by Mark Brown <broonie@sirena.org.uk>. The -d tempdir option
+was added by Dirk Eddelbuettel <edd@debian.org>.
diff --git a/compat/zlib/contrib/minizip/minizip.1 b/compat/zlib/contrib/minizip/minizip.1
new file mode 100644
index 0000000..1154484
--- /dev/null
+++ b/compat/zlib/contrib/minizip/minizip.1
@@ -0,0 +1,46 @@
+.\"                                      Hey, EMACS: -*- nroff -*-
+.TH minizip 1 "May 2, 2001"
+.\" Please adjust this date whenever revising the manpage.
+.\"
+.\" Some roff macros, for reference:
+.\" .nh        disable hyphenation
+.\" .hy        enable hyphenation
+.\" .ad l      left justify
+.\" .ad b      justify to both left and right margins
+.\" .nf        disable filling
+.\" .fi        enable filling
+.\" .br        insert line break
+.\" .sp <n>    insert n+1 empty lines
+.\" for manpage-specific macros, see man(7)
+.SH NAME
+minizip - create ZIP archives
+.SH SYNOPSIS
+.B minizip
+.RI [ -o ]
+zipfile [ " files" ... ]
+.SH DESCRIPTION
+.B minizip
+is a simple tool which allows the creation of compressed file archives
+in the ZIP format used by the MS-DOS utility PKZIP.  It was written as
+a demonstration of the
+.IR zlib (3)
+library and therefore lack many of the features of the
+.IR zip (1)
+program.
+.SH OPTIONS
+The first argument supplied is the name of the ZIP archive to create or
+.RI -o
+in which case it is ignored and the second argument treated as the
+name of the ZIP file.  If the ZIP file already exists it will be
+overwritten.
+.PP
+Subsequent arguments specify a list of files to place in the ZIP
+archive.  If none are specified then an empty archive will be created.
+.SH SEE ALSO
+.BR miniunzip (1),
+.BR zlib (3),
+.BR zip (1).
+.SH AUTHOR
+This program was written by Gilles Vollant.  This manual page was
+written by Mark Brown <broonie@sirena.org.uk>.
+
diff --git a/compat/zlib/contrib/minizip/minizip.c b/compat/zlib/contrib/minizip/minizip.c
new file mode 100644
index 0000000..4288962
--- /dev/null
+++ b/compat/zlib/contrib/minizip/minizip.c
@@ -0,0 +1,520 @@
+/*
+   minizip.c
+   Version 1.1, February 14h, 2010
+   sample part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
+
+         Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
+
+         Modifications of Unzip for Zip64
+         Copyright (C) 2007-2008 Even Rouault
+
+         Modifications for Zip64 support on both zip and unzip
+         Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
+*/
+
+
+#if (!defined(_WIN32)) && (!defined(WIN32)) && (!defined(__APPLE__))
+        #ifndef __USE_FILE_OFFSET64
+                #define __USE_FILE_OFFSET64
+        #endif
+        #ifndef __USE_LARGEFILE64
+                #define __USE_LARGEFILE64
+        #endif
+        #ifndef _LARGEFILE64_SOURCE
+                #define _LARGEFILE64_SOURCE
+        #endif
+        #ifndef _FILE_OFFSET_BIT
+                #define _FILE_OFFSET_BIT 64
+        #endif
+#endif
+
+#ifdef __APPLE__
+// In darwin and perhaps other BSD variants off_t is a 64 bit value, hence no need for specific 64 bit functions
+#define FOPEN_FUNC(filename, mode) fopen(filename, mode)
+#define FTELLO_FUNC(stream) ftello(stream)
+#define FSEEKO_FUNC(stream, offset, origin) fseeko(stream, offset, origin)
+#else
+#define FOPEN_FUNC(filename, mode) fopen64(filename, mode)
+#define FTELLO_FUNC(stream) ftello64(stream)
+#define FSEEKO_FUNC(stream, offset, origin) fseeko64(stream, offset, origin)
+#endif
+
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <errno.h>
+#include <fcntl.h>
+
+#ifdef _WIN32
+# include <direct.h>
+# include <io.h>
+#else
+# include <unistd.h>
+# include <utime.h>
+# include <sys/types.h>
+# include <sys/stat.h>
+#endif
+
+#include "zip.h"
+
+#ifdef _WIN32
+        #define USEWIN32IOAPI
+        #include "iowin32.h"
+#endif
+
+
+
+#define WRITEBUFFERSIZE (16384)
+#define MAXFILENAME (256)
+
+#ifdef _WIN32
+uLong filetime(f, tmzip, dt)
+    char *f;                /* name of file to get info on */
+    tm_zip *tmzip;             /* return value: access, modific. and creation times */
+    uLong *dt;             /* dostime */
+{
+  int ret = 0;
+  {
+      FILETIME ftLocal;
+      HANDLE hFind;
+      WIN32_FIND_DATAA ff32;
+
+      hFind = FindFirstFileA(f,&ff32);
+      if (hFind != INVALID_HANDLE_VALUE)
+      {
+        FileTimeToLocalFileTime(&(ff32.ftLastWriteTime),&ftLocal);
+        FileTimeToDosDateTime(&ftLocal,((LPWORD)dt)+1,((LPWORD)dt)+0);
+        FindClose(hFind);
+        ret = 1;
+      }
+  }
+  return ret;
+}
+#else
+#ifdef unix || __APPLE__
+uLong filetime(f, tmzip, dt)
+    char *f;               /* name of file to get info on */
+    tm_zip *tmzip;         /* return value: access, modific. and creation times */
+    uLong *dt;             /* dostime */
+{
+  int ret=0;
+  struct stat s;        /* results of stat() */
+  struct tm* filedate;
+  time_t tm_t=0;
+
+  if (strcmp(f,"-")!=0)
+  {
+    char name[MAXFILENAME+1];
+    int len = strlen(f);
+    if (len > MAXFILENAME)
+      len = MAXFILENAME;
+
+    strncpy(name, f,MAXFILENAME-1);
+    /* strncpy doesnt append the trailing NULL, of the string is too long. */
+    name[ MAXFILENAME ] = '\0';
+
+    if (name[len - 1] == '/')
+      name[len - 1] = '\0';
+    /* not all systems allow stat'ing a file with / appended */
+    if (stat(name,&s)==0)
+    {
+      tm_t = s.st_mtime;
+      ret = 1;
+    }
+  }
+  filedate = localtime(&tm_t);
+
+  tmzip->tm_sec  = filedate->tm_sec;
+  tmzip->tm_min  = filedate->tm_min;
+  tmzip->tm_hour = filedate->tm_hour;
+  tmzip->tm_mday = filedate->tm_mday;
+  tmzip->tm_mon  = filedate->tm_mon ;
+  tmzip->tm_year = filedate->tm_year;
+
+  return ret;
+}
+#else
+uLong filetime(f, tmzip, dt)
+    char *f;                /* name of file to get info on */
+    tm_zip *tmzip;             /* return value: access, modific. and creation times */
+    uLong *dt;             /* dostime */
+{
+    return 0;
+}
+#endif
+#endif
+
+
+
+
+int check_exist_file(filename)
+    const char* filename;
+{
+    FILE* ftestexist;
+    int ret = 1;
+    ftestexist = FOPEN_FUNC(filename,"rb");
+    if (ftestexist==NULL)
+        ret = 0;
+    else
+        fclose(ftestexist);
+    return ret;
+}
+
+void do_banner()
+{
+    printf("MiniZip 1.1, demo of zLib + MiniZip64 package, written by Gilles Vollant\n");
+    printf("more info on MiniZip at http://www.winimage.com/zLibDll/minizip.html\n\n");
+}
+
+void do_help()
+{
+    printf("Usage : minizip [-o] [-a] [-0 to -9] [-p password] [-j] file.zip [files_to_add]\n\n" \
+           "  -o  Overwrite existing file.zip\n" \
+           "  -a  Append to existing file.zip\n" \
+           "  -0  Store only\n" \
+           "  -1  Compress faster\n" \
+           "  -9  Compress better\n\n" \
+           "  -j  exclude path. store only the file name.\n\n");
+}
+
+/* calculate the CRC32 of a file,
+   because to encrypt a file, we need known the CRC32 of the file before */
+int getFileCrc(const char* filenameinzip,void*buf,unsigned long size_buf,unsigned long* result_crc)
+{
+   unsigned long calculate_crc=0;
+   int err=ZIP_OK;
+   FILE * fin = FOPEN_FUNC(filenameinzip,"rb");
+
+   unsigned long size_read = 0;
+   unsigned long total_read = 0;
+   if (fin==NULL)
+   {
+       err = ZIP_ERRNO;
+   }
+
+    if (err == ZIP_OK)
+        do
+        {
+            err = ZIP_OK;
+            size_read = (int)fread(buf,1,size_buf,fin);
+            if (size_read < size_buf)
+                if (feof(fin)==0)
+            {
+                printf("error in reading %s\n",filenameinzip);
+                err = ZIP_ERRNO;
+            }
+
+            if (size_read>0)
+                calculate_crc = crc32(calculate_crc,buf,size_read);
+            total_read += size_read;
+
+        } while ((err == ZIP_OK) && (size_read>0));
+
+    if (fin)
+        fclose(fin);
+
+    *result_crc=calculate_crc;
+    printf("file %s crc %lx\n", filenameinzip, calculate_crc);
+    return err;
+}
+
+int isLargeFile(const char* filename)
+{
+  int largeFile = 0;
+  ZPOS64_T pos = 0;
+  FILE* pFile = FOPEN_FUNC(filename, "rb");
+
+  if(pFile != NULL)
+  {
+    int n = FSEEKO_FUNC(pFile, 0, SEEK_END);
+    pos = FTELLO_FUNC(pFile);
+
+                printf("File : %s is %lld bytes\n", filename, pos);
+
+    if(pos >= 0xffffffff)
+     largeFile = 1;
+
+                fclose(pFile);
+  }
+
+ return largeFile;
+}
+
+int main(argc,argv)
+    int argc;
+    char *argv[];
+{
+    int i;
+    int opt_overwrite=0;
+    int opt_compress_level=Z_DEFAULT_COMPRESSION;
+    int opt_exclude_path=0;
+    int zipfilenamearg = 0;
+    char filename_try[MAXFILENAME+16];
+    int zipok;
+    int err=0;
+    int size_buf=0;
+    void* buf=NULL;
+    const char* password=NULL;
+
+
+    do_banner();
+    if (argc==1)
+    {
+        do_help();
+        return 0;
+    }
+    else
+    {
+        for (i=1;i<argc;i++)
+        {
+            if ((*argv[i])=='-')
+            {
+                const char *p=argv[i]+1;
+
+                while ((*p)!='\0')
+                {
+                    char c=*(p++);;
+                    if ((c=='o') || (c=='O'))
+                        opt_overwrite = 1;
+                    if ((c=='a') || (c=='A'))
+                        opt_overwrite = 2;
+                    if ((c>='0') && (c<='9'))
+                        opt_compress_level = c-'0';
+                    if ((c=='j') || (c=='J'))
+                        opt_exclude_path = 1;
+
+                    if (((c=='p') || (c=='P')) && (i+1<argc))
+                    {
+                        password=argv[i+1];
+                        i++;
+                    }
+                }
+            }
+            else
+            {
+                if (zipfilenamearg == 0)
+                {
+                    zipfilenamearg = i ;
+                }
+            }
+        }
+    }
+
+    size_buf = WRITEBUFFERSIZE;
+    buf = (void*)malloc(size_buf);
+    if (buf==NULL)
+    {
+        printf("Error allocating memory\n");
+        return ZIP_INTERNALERROR;
+    }
+
+    if (zipfilenamearg==0)
+    {
+        zipok=0;
+    }
+    else
+    {
+        int i,len;
+        int dot_found=0;
+
+        zipok = 1 ;
+        strncpy(filename_try, argv[zipfilenamearg],MAXFILENAME-1);
+        /* strncpy doesnt append the trailing NULL, of the string is too long. */
+        filename_try[ MAXFILENAME ] = '\0';
+
+        len=(int)strlen(filename_try);
+        for (i=0;i<len;i++)
+            if (filename_try[i]=='.')
+                dot_found=1;
+
+        if (dot_found==0)
+            strcat(filename_try,".zip");
+
+        if (opt_overwrite==2)
+        {
+            /* if the file don't exist, we not append file */
+            if (check_exist_file(filename_try)==0)
+                opt_overwrite=1;
+        }
+        else
+        if (opt_overwrite==0)
+            if (check_exist_file(filename_try)!=0)
+            {
+                char rep=0;
+                do
+                {
+                    char answer[128];
+                    int ret;
+                    printf("The file %s exists. Overwrite ? [y]es, [n]o, [a]ppend : ",filename_try);
+                    ret = scanf("%1s",answer);
+                    if (ret != 1)
+                    {
+                       exit(EXIT_FAILURE);
+                    }
+                    rep = answer[0] ;
+                    if ((rep>='a') && (rep<='z'))
+                        rep -= 0x20;
+                }
+                while ((rep!='Y') && (rep!='N') && (rep!='A'));
+                if (rep=='N')
+                    zipok = 0;
+                if (rep=='A')
+                    opt_overwrite = 2;
+            }
+    }
+
+    if (zipok==1)
+    {
+        zipFile zf;
+        int errclose;
+#        ifdef USEWIN32IOAPI
+        zlib_filefunc64_def ffunc;
+        fill_win32_filefunc64A(&ffunc);
+        zf = zipOpen2_64(filename_try,(opt_overwrite==2) ? 2 : 0,NULL,&ffunc);
+#        else
+        zf = zipOpen64(filename_try,(opt_overwrite==2) ? 2 : 0);
+#        endif
+
+        if (zf == NULL)
+        {
+            printf("error opening %s\n",filename_try);
+            err= ZIP_ERRNO;
+        }
+        else
+            printf("creating %s\n",filename_try);
+
+        for (i=zipfilenamearg+1;(i<argc) && (err==ZIP_OK);i++)
+        {
+            if (!((((*(argv[i]))=='-') || ((*(argv[i]))=='/')) &&
+                  ((argv[i][1]=='o') || (argv[i][1]=='O') ||
+                   (argv[i][1]=='a') || (argv[i][1]=='A') ||
+                   (argv[i][1]=='p') || (argv[i][1]=='P') ||
+                   ((argv[i][1]>='0') || (argv[i][1]<='9'))) &&
+                  (strlen(argv[i]) == 2)))
+            {
+                FILE * fin;
+                int size_read;
+                const char* filenameinzip = argv[i];
+                const char *savefilenameinzip;
+                zip_fileinfo zi;
+                unsigned long crcFile=0;
+                int zip64 = 0;
+
+                zi.tmz_date.tm_sec = zi.tmz_date.tm_min = zi.tmz_date.tm_hour =
+                zi.tmz_date.tm_mday = zi.tmz_date.tm_mon = zi.tmz_date.tm_year = 0;
+                zi.dosDate = 0;
+                zi.internal_fa = 0;
+                zi.external_fa = 0;
+                filetime(filenameinzip,&zi.tmz_date,&zi.dosDate);
+
+/*
+                err = zipOpenNewFileInZip(zf,filenameinzip,&zi,
+                                 NULL,0,NULL,0,NULL / * comment * /,
+                                 (opt_compress_level != 0) ? Z_DEFLATED : 0,
+                                 opt_compress_level);
+*/
+                if ((password != NULL) && (err==ZIP_OK))
+                    err = getFileCrc(filenameinzip,buf,size_buf,&crcFile);
+
+                zip64 = isLargeFile(filenameinzip);
+
+                                                         /* The path name saved, should not include a leading slash. */
+               /*if it did, windows/xp and dynazip couldn't read the zip file. */
+                 savefilenameinzip = filenameinzip;
+                 while( savefilenameinzip[0] == '\\' || savefilenameinzip[0] == '/' )
+                 {
+                     savefilenameinzip++;
+                 }
+
+                 /*should the zip file contain any path at all?*/
+                 if( opt_exclude_path )
+                 {
+                     const char *tmpptr;
+                     const char *lastslash = 0;
+                     for( tmpptr = savefilenameinzip; *tmpptr; tmpptr++)
+                     {
+                         if( *tmpptr == '\\' || *tmpptr == '/')
+                         {
+                             lastslash = tmpptr;
+                         }
+                     }
+                     if( lastslash != NULL )
+                     {
+                         savefilenameinzip = lastslash+1; // base filename follows last slash.
+                     }
+                 }
+
+                 /**/
+                err = zipOpenNewFileInZip3_64(zf,savefilenameinzip,&zi,
+                                 NULL,0,NULL,0,NULL /* comment*/,
+                                 (opt_compress_level != 0) ? Z_DEFLATED : 0,
+                                 opt_compress_level,0,
+                                 /* -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, */
+                                 -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
+                                 password,crcFile, zip64);
+
+                if (err != ZIP_OK)
+                    printf("error in opening %s in zipfile\n",filenameinzip);
+                else
+                {
+                    fin = FOPEN_FUNC(filenameinzip,"rb");
+                    if (fin==NULL)
+                    {
+                        err=ZIP_ERRNO;
+                        printf("error in opening %s for reading\n",filenameinzip);
+                    }
+                }
+
+                if (err == ZIP_OK)
+                    do
+                    {
+                        err = ZIP_OK;
+                        size_read = (int)fread(buf,1,size_buf,fin);
+                        if (size_read < size_buf)
+                            if (feof(fin)==0)
+                        {
+                            printf("error in reading %s\n",filenameinzip);
+                            err = ZIP_ERRNO;
+                        }
+
+                        if (size_read>0)
+                        {
+                            err = zipWriteInFileInZip (zf,buf,size_read);
+                            if (err<0)
+                            {
+                                printf("error in writing %s in the zipfile\n",
+                                                 filenameinzip);
+                            }
+
+                        }
+                    } while ((err == ZIP_OK) && (size_read>0));
+
+                if (fin)
+                    fclose(fin);
+
+                if (err<0)
+                    err=ZIP_ERRNO;
+                else
+                {
+                    err = zipCloseFileInZip(zf);
+                    if (err!=ZIP_OK)
+                        printf("error in closing %s in the zipfile\n",
+                                    filenameinzip);
+                }
+            }
+        }
+        errclose = zipClose(zf,NULL);
+        if (errclose != ZIP_OK)
+            printf("error in closing %s\n",filename_try);
+    }
+    else
+    {
+       do_help();
+    }
+
+    free(buf);
+    return 0;
+}
diff --git a/compat/zlib/contrib/minizip/minizip.pc.in b/compat/zlib/contrib/minizip/minizip.pc.in
new file mode 100644
index 0000000..69b5b7f
--- /dev/null
+++ b/compat/zlib/contrib/minizip/minizip.pc.in
@@ -0,0 +1,12 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@/minizip
+
+Name: minizip
+Description: Minizip zip file manipulation library
+Requires:
+Version: @PACKAGE_VERSION@
+Libs: -L${libdir} -lminizip
+Libs.private: -lz
+Cflags: -I${includedir}
diff --git a/compat/zlib/contrib/minizip/mztools.c b/compat/zlib/contrib/minizip/mztools.c
new file mode 100644
index 0000000..96891c2
--- /dev/null
+++ b/compat/zlib/contrib/minizip/mztools.c
@@ -0,0 +1,291 @@
+/*
+  Additional tools for Minizip
+  Code: Xavier Roche '2004
+  License: Same as ZLIB (www.gzip.org)
+*/
+
+/* Code */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "zlib.h"
+#include "unzip.h"
+
+#define READ_8(adr)  ((unsigned char)*(adr))
+#define READ_16(adr) ( READ_8(adr) | (READ_8(adr+1) << 8) )
+#define READ_32(adr) ( READ_16(adr) | (READ_16((adr)+2) << 16) )
+
+#define WRITE_8(buff, n) do { \
+  *((unsigned char*)(buff)) = (unsigned char) ((n) & 0xff); \
+} while(0)
+#define WRITE_16(buff, n) do { \
+  WRITE_8((unsigned char*)(buff), n); \
+  WRITE_8(((unsigned char*)(buff)) + 1, (n) >> 8); \
+} while(0)
+#define WRITE_32(buff, n) do { \
+  WRITE_16((unsigned char*)(buff), (n) & 0xffff); \
+  WRITE_16((unsigned char*)(buff) + 2, (n) >> 16); \
+} while(0)
+
+extern int ZEXPORT unzRepair(file, fileOut, fileOutTmp, nRecovered, bytesRecovered)
+const char* file;
+const char* fileOut;
+const char* fileOutTmp;
+uLong* nRecovered;
+uLong* bytesRecovered;
+{
+  int err = Z_OK;
+  FILE* fpZip = fopen(file, "rb");
+  FILE* fpOut = fopen(fileOut, "wb");
+  FILE* fpOutCD = fopen(fileOutTmp, "wb");
+  if (fpZip != NULL &&  fpOut != NULL) {
+    int entries = 0;
+    uLong totalBytes = 0;
+    char header[30];
+    char filename[1024];
+    char extra[1024];
+    int offset = 0;
+    int offsetCD = 0;
+    while ( fread(header, 1, 30, fpZip) == 30 ) {
+      int currentOffset = offset;
+
+      /* File entry */
+      if (READ_32(header) == 0x04034b50) {
+        unsigned int version = READ_16(header + 4);
+        unsigned int gpflag = READ_16(header + 6);
+        unsigned int method = READ_16(header + 8);
+        unsigned int filetime = READ_16(header + 10);
+        unsigned int filedate = READ_16(header + 12);
+        unsigned int crc = READ_32(header + 14); /* crc */
+        unsigned int cpsize = READ_32(header + 18); /* compressed size */
+        unsigned int uncpsize = READ_32(header + 22); /* uncompressed sz */
+        unsigned int fnsize = READ_16(header + 26); /* file name length */
+        unsigned int extsize = READ_16(header + 28); /* extra field length */
+        filename[0] = extra[0] = '\0';
+
+        /* Header */
+        if (fwrite(header, 1, 30, fpOut) == 30) {
+          offset += 30;
+        } else {
+          err = Z_ERRNO;
+          break;
+        }
+
+        /* Filename */
+        if (fnsize > 0) {
+          if (fnsize < sizeof(filename)) {
+            if (fread(filename, 1, fnsize, fpZip) == fnsize) {
+                if (fwrite(filename, 1, fnsize, fpOut) == fnsize) {
+                offset += fnsize;
+              } else {
+                err = Z_ERRNO;
+                break;
+              }
+            } else {
+              err = Z_ERRNO;
+              break;
+            }
+          } else {
+            err = Z_ERRNO;
+            break;
+          }
+        } else {
+          err = Z_STREAM_ERROR;
+          break;
+        }
+
+        /* Extra field */
+        if (extsize > 0) {
+          if (extsize < sizeof(extra)) {
+            if (fread(extra, 1, extsize, fpZip) == extsize) {
+              if (fwrite(extra, 1, extsize, fpOut) == extsize) {
+                offset += extsize;
+                } else {
+                err = Z_ERRNO;
+                break;
+              }
+            } else {
+              err = Z_ERRNO;
+              break;
+            }
+          } else {
+            err = Z_ERRNO;
+            break;
+          }
+        }
+
+        /* Data */
+        {
+          int dataSize = cpsize;
+          if (dataSize == 0) {
+            dataSize = uncpsize;
+          }
+          if (dataSize > 0) {
+            char* data = malloc(dataSize);
+            if (data != NULL) {
+              if ((int)fread(data, 1, dataSize, fpZip) == dataSize) {
+                if ((int)fwrite(data, 1, dataSize, fpOut) == dataSize) {
+                  offset += dataSize;
+                  totalBytes += dataSize;
+                } else {
+                  err = Z_ERRNO;
+                }
+              } else {
+                err = Z_ERRNO;
+              }
+              free(data);
+              if (err != Z_OK) {
+                break;
+              }
+            } else {
+              err = Z_MEM_ERROR;
+              break;
+            }
+          }
+        }
+
+        /* Central directory entry */
+        {
+          char header[46];
+          char* comment = "";
+          int comsize = (int) strlen(comment);
+          WRITE_32(header, 0x02014b50);
+          WRITE_16(header + 4, version);
+          WRITE_16(header + 6, version);
+          WRITE_16(header + 8, gpflag);
+          WRITE_16(header + 10, method);
+          WRITE_16(header + 12, filetime);
+          WRITE_16(header + 14, filedate);
+          WRITE_32(header + 16, crc);
+          WRITE_32(header + 20, cpsize);
+          WRITE_32(header + 24, uncpsize);
+          WRITE_16(header + 28, fnsize);
+          WRITE_16(header + 30, extsize);
+          WRITE_16(header + 32, comsize);
+          WRITE_16(header + 34, 0);     /* disk # */
+          WRITE_16(header + 36, 0);     /* int attrb */
+          WRITE_32(header + 38, 0);     /* ext attrb */
+          WRITE_32(header + 42, currentOffset);
+          /* Header */
+          if (fwrite(header, 1, 46, fpOutCD) == 46) {
+            offsetCD += 46;
+
+            /* Filename */
+            if (fnsize > 0) {
+              if (fwrite(filename, 1, fnsize, fpOutCD) == fnsize) {
+                offsetCD += fnsize;
+              } else {
+                err = Z_ERRNO;
+                break;
+              }
+            } else {
+              err = Z_STREAM_ERROR;
+              break;
+            }
+
+            /* Extra field */
+            if (extsize > 0) {
+              if (fwrite(extra, 1, extsize, fpOutCD) == extsize) {
+                offsetCD += extsize;
+              } else {
+                err = Z_ERRNO;
+                break;
+              }
+            }
+
+            /* Comment field */
+            if (comsize > 0) {
+              if ((int)fwrite(comment, 1, comsize, fpOutCD) == comsize) {
+                offsetCD += comsize;
+              } else {
+                err = Z_ERRNO;
+                break;
+              }
+            }
+
+
+          } else {
+            err = Z_ERRNO;
+            break;
+          }
+        }
+
+        /* Success */
+        entries++;
+
+      } else {
+        break;
+      }
+    }
+
+    /* Final central directory  */
+    {
+      int entriesZip = entries;
+      char header[22];
+      char* comment = ""; // "ZIP File recovered by zlib/minizip/mztools";
+      int comsize = (int) strlen(comment);
+      if (entriesZip > 0xffff) {
+        entriesZip = 0xffff;
+      }
+      WRITE_32(header, 0x06054b50);
+      WRITE_16(header + 4, 0);    /* disk # */
+      WRITE_16(header + 6, 0);    /* disk # */
+      WRITE_16(header + 8, entriesZip);   /* hack */
+      WRITE_16(header + 10, entriesZip);  /* hack */
+      WRITE_32(header + 12, offsetCD);    /* size of CD */
+      WRITE_32(header + 16, offset);      /* offset to CD */
+      WRITE_16(header + 20, comsize);     /* comment */
+
+      /* Header */
+      if (fwrite(header, 1, 22, fpOutCD) == 22) {
+
+        /* Comment field */
+        if (comsize > 0) {
+          if ((int)fwrite(comment, 1, comsize, fpOutCD) != comsize) {
+            err = Z_ERRNO;
+          }
+        }
+
+      } else {
+        err = Z_ERRNO;
+      }
+    }
+
+    /* Final merge (file + central directory) */
+    fclose(fpOutCD);
+    if (err == Z_OK) {
+      fpOutCD = fopen(fileOutTmp, "rb");
+      if (fpOutCD != NULL) {
+        int nRead;
+        char buffer[8192];
+        while ( (nRead = (int)fread(buffer, 1, sizeof(buffer), fpOutCD)) > 0) {
+          if ((int)fwrite(buffer, 1, nRead, fpOut) != nRead) {
+            err = Z_ERRNO;
+            break;
+          }
+        }
+        fclose(fpOutCD);
+      }
+    }
+
+    /* Close */
+    fclose(fpZip);
+    fclose(fpOut);
+
+    /* Wipe temporary file */
+    (void)remove(fileOutTmp);
+
+    /* Number of recovered entries */
+    if (err == Z_OK) {
+      if (nRecovered != NULL) {
+        *nRecovered = entries;
+      }
+      if (bytesRecovered != NULL) {
+        *bytesRecovered = totalBytes;
+      }
+    }
+  } else {
+    err = Z_STREAM_ERROR;
+  }
+  return err;
+}
diff --git a/compat/zlib/contrib/minizip/mztools.h b/compat/zlib/contrib/minizip/mztools.h
new file mode 100644
index 0000000..a49a426
--- /dev/null
+++ b/compat/zlib/contrib/minizip/mztools.h
@@ -0,0 +1,37 @@
+/*
+  Additional tools for Minizip
+  Code: Xavier Roche '2004
+  License: Same as ZLIB (www.gzip.org)
+*/
+
+#ifndef _zip_tools_H
+#define _zip_tools_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _ZLIB_H
+#include "zlib.h"
+#endif
+
+#include "unzip.h"
+
+/* Repair a ZIP file (missing central directory)
+   file: file to recover
+   fileOut: output file after recovery
+   fileOutTmp: temporary file name used for recovery
+*/
+extern int ZEXPORT unzRepair(const char* file,
+                             const char* fileOut,
+                             const char* fileOutTmp,
+                             uLong* nRecovered,
+                             uLong* bytesRecovered);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif
diff --git a/compat/zlib/contrib/minizip/unzip.c b/compat/zlib/contrib/minizip/unzip.c
new file mode 100644
index 0000000..9093504
--- /dev/null
+++ b/compat/zlib/contrib/minizip/unzip.c
@@ -0,0 +1,2125 @@
+/* unzip.c -- IO for uncompress .zip files using zlib
+   Version 1.1, February 14h, 2010
+   part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
+
+         Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
+
+         Modifications of Unzip for Zip64
+         Copyright (C) 2007-2008 Even Rouault
+
+         Modifications for Zip64 support on both zip and unzip
+         Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
+
+         For more info read MiniZip_info.txt
+
+
+  ------------------------------------------------------------------------------------
+  Decryption code comes from crypt.c by Info-ZIP but has been greatly reduced in terms of
+  compatibility with older software. The following is from the original crypt.c.
+  Code woven in by Terry Thorsen 1/2003.
+
+  Copyright (c) 1990-2000 Info-ZIP.  All rights reserved.
+
+  See the accompanying file LICENSE, version 2000-Apr-09 or later
+  (the contents of which are also included in zip.h) for terms of use.
+  If, for some reason, all these files are missing, the Info-ZIP license
+  also may be found at:  ftp://ftp.info-zip.org/pub/infozip/license.html
+
+        crypt.c (full version) by Info-ZIP.      Last revised:  [see crypt.h]
+
+  The encryption/decryption parts of this source code (as opposed to the
+  non-echoing password parts) were originally written in Europe.  The
+  whole source package can be freely distributed, including from the USA.
+  (Prior to January 2000, re-export from the US was a violation of US law.)
+
+        This encryption code is a direct transcription of the algorithm from
+  Roger Schlafly, described by Phil Katz in the file appnote.txt.  This
+  file (appnote.txt) is distributed with the PKZIP program (even in the
+  version without encryption capabilities).
+
+        ------------------------------------------------------------------------------------
+
+        Changes in unzip.c
+
+        2007-2008 - Even Rouault - Addition of cpl_unzGetCurrentFileZStreamPos
+  2007-2008 - Even Rouault - Decoration of symbol names unz* -> cpl_unz*
+  2007-2008 - Even Rouault - Remove old C style function prototypes
+  2007-2008 - Even Rouault - Add unzip support for ZIP64
+
+        Copyright (C) 2007-2008 Even Rouault
+
+
+        Oct-2009 - Mathias Svensson - Removed cpl_* from symbol names (Even Rouault added them but since this is now moved to a new project (minizip64) I renamed them again).
+  Oct-2009 - Mathias Svensson - Fixed problem if uncompressed size was > 4G and compressed size was <4G
+                                should only read the compressed/uncompressed size from the Zip64 format if
+                                the size from normal header was 0xFFFFFFFF
+  Oct-2009 - Mathias Svensson - Applied some bug fixes from paches recived from Gilles Vollant
+        Oct-2009 - Mathias Svensson - Applied support to unzip files with compression mathod BZIP2 (bzip2 lib is required)
+                                Patch created by Daniel Borca
+
+  Jan-2010 - back to unzip and minizip 1.0 name scheme, with compatibility layer
+
+  Copyright (C) 1998 - 2010 Gilles Vollant, Even Rouault, Mathias Svensson
+
+*/
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifndef NOUNCRYPT
+        #define NOUNCRYPT
+#endif
+
+#include "zlib.h"
+#include "unzip.h"
+
+#ifdef STDC
+#  include <stddef.h>
+#  include <string.h>
+#  include <stdlib.h>
+#endif
+#ifdef NO_ERRNO_H
+    extern int errno;
+#else
+#   include <errno.h>
+#endif
+
+
+#ifndef local
+#  define local static
+#endif
+/* compile with -Dlocal if your debugger can't find static symbols */
+
+
+#ifndef CASESENSITIVITYDEFAULT_NO
+#  if !defined(unix) && !defined(CASESENSITIVITYDEFAULT_YES)
+#    define CASESENSITIVITYDEFAULT_NO
+#  endif
+#endif
+
+
+#ifndef UNZ_BUFSIZE
+#define UNZ_BUFSIZE (16384)
+#endif
+
+#ifndef UNZ_MAXFILENAMEINZIP
+#define UNZ_MAXFILENAMEINZIP (256)
+#endif
+
+#ifndef ALLOC
+# define ALLOC(size) (malloc(size))
+#endif
+#ifndef TRYFREE
+# define TRYFREE(p) {if (p) free(p);}
+#endif
+
+#define SIZECENTRALDIRITEM (0x2e)
+#define SIZEZIPLOCALHEADER (0x1e)
+
+
+const char unz_copyright[] =
+   " unzip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll";
+
+/* unz_file_info_interntal contain internal info about a file in zipfile*/
+typedef struct unz_file_info64_internal_s
+{
+    ZPOS64_T offset_curfile;/* relative offset of local header 8 bytes */
+} unz_file_info64_internal;
+
+
+/* file_in_zip_read_info_s contain internal information about a file in zipfile,
+    when reading and decompress it */
+typedef struct
+{
+    char  *read_buffer;         /* internal buffer for compressed data */
+    z_stream stream;            /* zLib stream structure for inflate */
+
+#ifdef HAVE_BZIP2
+    bz_stream bstream;          /* bzLib stream structure for bziped */
+#endif
+
+    ZPOS64_T pos_in_zipfile;       /* position in byte on the zipfile, for fseek*/
+    uLong stream_initialised;   /* flag set if stream structure is initialised*/
+
+    ZPOS64_T offset_local_extrafield;/* offset of the local extra field */
+    uInt  size_local_extrafield;/* size of the local extra field */
+    ZPOS64_T pos_local_extrafield;   /* position in the local extra field in read*/
+    ZPOS64_T total_out_64;
+
+    uLong crc32;                /* crc32 of all data uncompressed */
+    uLong crc32_wait;           /* crc32 we must obtain after decompress all */
+    ZPOS64_T rest_read_compressed; /* number of byte to be decompressed */
+    ZPOS64_T rest_read_uncompressed;/*number of byte to be obtained after decomp*/
+    zlib_filefunc64_32_def z_filefunc;
+    voidpf filestream;        /* io structore of the zipfile */
+    uLong compression_method;   /* compression method (0==store) */
+    ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
+    int   raw;
+} file_in_zip64_read_info_s;
+
+
+/* unz64_s contain internal information about the zipfile
+*/
+typedef struct
+{
+    zlib_filefunc64_32_def z_filefunc;
+    int is64bitOpenFunction;
+    voidpf filestream;        /* io structore of the zipfile */
+    unz_global_info64 gi;       /* public global information */
+    ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
+    ZPOS64_T num_file;             /* number of the current file in the zipfile*/
+    ZPOS64_T pos_in_central_dir;   /* pos of the current file in the central dir*/
+    ZPOS64_T current_file_ok;      /* flag about the usability of the current file*/
+    ZPOS64_T central_pos;          /* position of the beginning of the central dir*/
+
+    ZPOS64_T size_central_dir;     /* size of the central directory  */
+    ZPOS64_T offset_central_dir;   /* offset of start of central directory with
+                                   respect to the starting disk number */
+
+    unz_file_info64 cur_file_info; /* public info about the current file in zip*/
+    unz_file_info64_internal cur_file_info_internal; /* private info about it*/
+    file_in_zip64_read_info_s* pfile_in_zip_read; /* structure about the current
+                                        file if we are decompressing it */
+    int encrypted;
+
+    int isZip64;
+
+#    ifndef NOUNCRYPT
+    unsigned long keys[3];     /* keys defining the pseudo-random sequence */
+    const z_crc_t* pcrc_32_tab;
+#    endif
+} unz64_s;
+
+
+#ifndef NOUNCRYPT
+#include "crypt.h"
+#endif
+
+/* ===========================================================================
+     Read a byte from a gz_stream; update next_in and avail_in. Return EOF
+   for end of file.
+   IN assertion: the stream s has been sucessfully opened for reading.
+*/
+
+
+local int unz64local_getByte OF((
+    const zlib_filefunc64_32_def* pzlib_filefunc_def,
+    voidpf filestream,
+    int *pi));
+
+local int unz64local_getByte(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, int *pi)
+{
+    unsigned char c;
+    int err = (int)ZREAD64(*pzlib_filefunc_def,filestream,&c,1);
+    if (err==1)
+    {
+        *pi = (int)c;
+        return UNZ_OK;
+    }
+    else
+    {
+        if (ZERROR64(*pzlib_filefunc_def,filestream))
+            return UNZ_ERRNO;
+        else
+            return UNZ_EOF;
+    }
+}
+
+
+/* ===========================================================================
+   Reads a long in LSB order from the given gz_stream. Sets
+*/
+local int unz64local_getShort OF((
+    const zlib_filefunc64_32_def* pzlib_filefunc_def,
+    voidpf filestream,
+    uLong *pX));
+
+local int unz64local_getShort (const zlib_filefunc64_32_def* pzlib_filefunc_def,
+                             voidpf filestream,
+                             uLong *pX)
+{
+    uLong x ;
+    int i = 0;
+    int err;
+
+    err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
+    x = (uLong)i;
+
+    if (err==UNZ_OK)
+        err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
+    x |= ((uLong)i)<<8;
+
+    if (err==UNZ_OK)
+        *pX = x;
+    else
+        *pX = 0;
+    return err;
+}
+
+local int unz64local_getLong OF((
+    const zlib_filefunc64_32_def* pzlib_filefunc_def,
+    voidpf filestream,
+    uLong *pX));
+
+local int unz64local_getLong (const zlib_filefunc64_32_def* pzlib_filefunc_def,
+                            voidpf filestream,
+                            uLong *pX)
+{
+    uLong x ;
+    int i = 0;
+    int err;
+
+    err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
+    x = (uLong)i;
+
+    if (err==UNZ_OK)
+        err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
+    x |= ((uLong)i)<<8;
+
+    if (err==UNZ_OK)
+        err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
+    x |= ((uLong)i)<<16;
+
+    if (err==UNZ_OK)
+        err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
+    x += ((uLong)i)<<24;
+
+    if (err==UNZ_OK)
+        *pX = x;
+    else
+        *pX = 0;
+    return err;
+}
+
+local int unz64local_getLong64 OF((
+    const zlib_filefunc64_32_def* pzlib_filefunc_def,
+    voidpf filestream,
+    ZPOS64_T *pX));
+
+
+local int unz64local_getLong64 (const zlib_filefunc64_32_def* pzlib_filefunc_def,
+                            voidpf filestream,
+                            ZPOS64_T *pX)
+{
+    ZPOS64_T x ;
+    int i = 0;
+    int err;
+
+    err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
+    x = (ZPOS64_T)i;
+
+    if (err==UNZ_OK)
+        err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
+    x |= ((ZPOS64_T)i)<<8;
+
+    if (err==UNZ_OK)
+        err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
+    x |= ((ZPOS64_T)i)<<16;
+
+    if (err==UNZ_OK)
+        err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
+    x |= ((ZPOS64_T)i)<<24;
+
+    if (err==UNZ_OK)
+        err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
+    x |= ((ZPOS64_T)i)<<32;
+
+    if (err==UNZ_OK)
+        err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
+    x |= ((ZPOS64_T)i)<<40;
+
+    if (err==UNZ_OK)
+        err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
+    x |= ((ZPOS64_T)i)<<48;
+
+    if (err==UNZ_OK)
+        err = unz64local_getByte(pzlib_filefunc_def,filestream,&i);
+    x |= ((ZPOS64_T)i)<<56;
+
+    if (err==UNZ_OK)
+        *pX = x;
+    else
+        *pX = 0;
+    return err;
+}
+
+/* My own strcmpi / strcasecmp */
+local int strcmpcasenosensitive_internal (const char* fileName1, const char* fileName2)
+{
+    for (;;)
+    {
+        char c1=*(fileName1++);
+        char c2=*(fileName2++);
+        if ((c1>='a') && (c1<='z'))
+            c1 -= 0x20;
+        if ((c2>='a') && (c2<='z'))
+            c2 -= 0x20;
+        if (c1=='\0')
+            return ((c2=='\0') ? 0 : -1);
+        if (c2=='\0')
+            return 1;
+        if (c1<c2)
+            return -1;
+        if (c1>c2)
+            return 1;
+    }
+}
+
+
+#ifdef  CASESENSITIVITYDEFAULT_NO
+#define CASESENSITIVITYDEFAULTVALUE 2
+#else
+#define CASESENSITIVITYDEFAULTVALUE 1
+#endif
+
+#ifndef STRCMPCASENOSENTIVEFUNCTION
+#define STRCMPCASENOSENTIVEFUNCTION strcmpcasenosensitive_internal
+#endif
+
+/*
+   Compare two filename (fileName1,fileName2).
+   If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
+   If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi
+                                                                or strcasecmp)
+   If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
+        (like 1 on Unix, 2 on Windows)
+
+*/
+extern int ZEXPORT unzStringFileNameCompare (const char*  fileName1,
+                                                 const char*  fileName2,
+                                                 int iCaseSensitivity)
+
+{
+    if (iCaseSensitivity==0)
+        iCaseSensitivity=CASESENSITIVITYDEFAULTVALUE;
+
+    if (iCaseSensitivity==1)
+        return strcmp(fileName1,fileName2);
+
+    return STRCMPCASENOSENTIVEFUNCTION(fileName1,fileName2);
+}
+
+#ifndef BUFREADCOMMENT
+#define BUFREADCOMMENT (0x400)
+#endif
+
+/*
+  Locate the Central directory of a zipfile (at the end, just before
+    the global comment)
+*/
+local ZPOS64_T unz64local_SearchCentralDir OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream));
+local ZPOS64_T unz64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream)
+{
+    unsigned char* buf;
+    ZPOS64_T uSizeFile;
+    ZPOS64_T uBackRead;
+    ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */
+    ZPOS64_T uPosFound=0;
+
+    if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
+        return 0;
+
+
+    uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream);
+
+    if (uMaxBack>uSizeFile)
+        uMaxBack = uSizeFile;
+
+    buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
+    if (buf==NULL)
+        return 0;
+
+    uBackRead = 4;
+    while (uBackRead<uMaxBack)
+    {
+        uLong uReadSize;
+        ZPOS64_T uReadPos ;
+        int i;
+        if (uBackRead+BUFREADCOMMENT>uMaxBack)
+            uBackRead = uMaxBack;
+        else
+            uBackRead+=BUFREADCOMMENT;
+        uReadPos = uSizeFile-uBackRead ;
+
+        uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
+                     (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos);
+        if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)
+            break;
+
+        if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
+            break;
+
+        for (i=(int)uReadSize-3; (i--)>0;)
+            if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&
+                ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06))
+            {
+                uPosFound = uReadPos+i;
+                break;
+            }
+
+        if (uPosFound!=0)
+            break;
+    }
+    TRYFREE(buf);
+    return uPosFound;
+}
+
+
+/*
+  Locate the Central directory 64 of a zipfile (at the end, just before
+    the global comment)
+*/
+local ZPOS64_T unz64local_SearchCentralDir64 OF((
+    const zlib_filefunc64_32_def* pzlib_filefunc_def,
+    voidpf filestream));
+
+local ZPOS64_T unz64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib_filefunc_def,
+                                      voidpf filestream)
+{
+    unsigned char* buf;
+    ZPOS64_T uSizeFile;
+    ZPOS64_T uBackRead;
+    ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */
+    ZPOS64_T uPosFound=0;
+    uLong uL;
+                ZPOS64_T relativeOffset;
+
+    if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
+        return 0;
+
+
+    uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream);
+
+    if (uMaxBack>uSizeFile)
+        uMaxBack = uSizeFile;
+
+    buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
+    if (buf==NULL)
+        return 0;
+
+    uBackRead = 4;
+    while (uBackRead<uMaxBack)
+    {
+        uLong uReadSize;
+        ZPOS64_T uReadPos;
+        int i;
+        if (uBackRead+BUFREADCOMMENT>uMaxBack)
+            uBackRead = uMaxBack;
+        else
+            uBackRead+=BUFREADCOMMENT;
+        uReadPos = uSizeFile-uBackRead ;
+
+        uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
+                     (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos);
+        if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)
+            break;
+
+        if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
+            break;
+
+        for (i=(int)uReadSize-3; (i--)>0;)
+            if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&
+                ((*(buf+i+2))==0x06) && ((*(buf+i+3))==0x07))
+            {
+                uPosFound = uReadPos+i;
+                break;
+            }
+
+        if (uPosFound!=0)
+            break;
+    }
+    TRYFREE(buf);
+    if (uPosFound == 0)
+        return 0;
+
+    /* Zip64 end of central directory locator */
+    if (ZSEEK64(*pzlib_filefunc_def,filestream, uPosFound,ZLIB_FILEFUNC_SEEK_SET)!=0)
+        return 0;
+
+    /* the signature, already checked */
+    if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK)
+        return 0;
+
+    /* number of the disk with the start of the zip64 end of  central directory */
+    if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK)
+        return 0;
+    if (uL != 0)
+        return 0;
+
+    /* relative offset of the zip64 end of central directory record */
+    if (unz64local_getLong64(pzlib_filefunc_def,filestream,&relativeOffset)!=UNZ_OK)
+        return 0;
+
+    /* total number of disks */
+    if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK)
+        return 0;
+    if (uL != 1)
+        return 0;
+
+    /* Goto end of central directory record */
+    if (ZSEEK64(*pzlib_filefunc_def,filestream, relativeOffset,ZLIB_FILEFUNC_SEEK_SET)!=0)
+        return 0;
+
+     /* the signature */
+    if (unz64local_getLong(pzlib_filefunc_def,filestream,&uL)!=UNZ_OK)
+        return 0;
+
+    if (uL != 0x06064b50)
+        return 0;
+
+    return relativeOffset;
+}
+
+/*
+  Open a Zip file. path contain the full pathname (by example,
+     on a Windows NT computer "c:\\test\\zlib114.zip" or on an Unix computer
+     "zlib/zlib114.zip".
+     If the zipfile cannot be opened (file doesn't exist or in not valid), the
+       return value is NULL.
+     Else, the return value is a unzFile Handle, usable with other function
+       of this unzip package.
+*/
+local unzFile unzOpenInternal (const void *path,
+                               zlib_filefunc64_32_def* pzlib_filefunc64_32_def,
+                               int is64bitOpenFunction)
+{
+    unz64_s us;
+    unz64_s *s;
+    ZPOS64_T central_pos;
+    uLong   uL;
+
+    uLong number_disk;          /* number of the current dist, used for
+                                   spaning ZIP, unsupported, always 0*/
+    uLong number_disk_with_CD;  /* number the the disk with central dir, used
+                                   for spaning ZIP, unsupported, always 0*/
+    ZPOS64_T number_entry_CD;      /* total number of entries in
+                                   the central dir
+                                   (same than number_entry on nospan) */
+
+    int err=UNZ_OK;
+
+    if (unz_copyright[0]!=' ')
+        return NULL;
+
+    us.z_filefunc.zseek32_file = NULL;
+    us.z_filefunc.ztell32_file = NULL;
+    if (pzlib_filefunc64_32_def==NULL)
+        fill_fopen64_filefunc(&us.z_filefunc.zfile_func64);
+    else
+        us.z_filefunc = *pzlib_filefunc64_32_def;
+    us.is64bitOpenFunction = is64bitOpenFunction;
+
+
+
+    us.filestream = ZOPEN64(us.z_filefunc,
+                                                 path,
+                                                 ZLIB_FILEFUNC_MODE_READ |
+                                                 ZLIB_FILEFUNC_MODE_EXISTING);
+    if (us.filestream==NULL)
+        return NULL;
+
+    central_pos = unz64local_SearchCentralDir64(&us.z_filefunc,us.filestream);
+    if (central_pos)
+    {
+        uLong uS;
+        ZPOS64_T uL64;
+
+        us.isZip64 = 1;
+
+        if (ZSEEK64(us.z_filefunc, us.filestream,
+                                      central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0)
+        err=UNZ_ERRNO;
+
+        /* the signature, already checked */
+        if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
+            err=UNZ_ERRNO;
+
+        /* size of zip64 end of central directory record */
+        if (unz64local_getLong64(&us.z_filefunc, us.filestream,&uL64)!=UNZ_OK)
+            err=UNZ_ERRNO;
+
+        /* version made by */
+        if (unz64local_getShort(&us.z_filefunc, us.filestream,&uS)!=UNZ_OK)
+            err=UNZ_ERRNO;
+
+        /* version needed to extract */
+        if (unz64local_getShort(&us.z_filefunc, us.filestream,&uS)!=UNZ_OK)
+            err=UNZ_ERRNO;
+
+        /* number of this disk */
+        if (unz64local_getLong(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK)
+            err=UNZ_ERRNO;
+
+        /* number of the disk with the start of the central directory */
+        if (unz64local_getLong(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=UNZ_OK)
+            err=UNZ_ERRNO;
+
+        /* total number of entries in the central directory on this disk */
+        if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.gi.number_entry)!=UNZ_OK)
+            err=UNZ_ERRNO;
+
+        /* total number of entries in the central directory */
+        if (unz64local_getLong64(&us.z_filefunc, us.filestream,&number_entry_CD)!=UNZ_OK)
+            err=UNZ_ERRNO;
+
+        if ((number_entry_CD!=us.gi.number_entry) ||
+            (number_disk_with_CD!=0) ||
+            (number_disk!=0))
+            err=UNZ_BADZIPFILE;
+
+        /* size of the central directory */
+        if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.size_central_dir)!=UNZ_OK)
+            err=UNZ_ERRNO;
+
+        /* offset of start of central directory with respect to the
+          starting disk number */
+        if (unz64local_getLong64(&us.z_filefunc, us.filestream,&us.offset_central_dir)!=UNZ_OK)
+            err=UNZ_ERRNO;
+
+        us.gi.size_comment = 0;
+    }
+    else
+    {
+        central_pos = unz64local_SearchCentralDir(&us.z_filefunc,us.filestream);
+        if (central_pos==0)
+            err=UNZ_ERRNO;
+
+        us.isZip64 = 0;
+
+        if (ZSEEK64(us.z_filefunc, us.filestream,
+                                        central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0)
+            err=UNZ_ERRNO;
+
+        /* the signature, already checked */
+        if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
+            err=UNZ_ERRNO;
+
+        /* number of this disk */
+        if (unz64local_getShort(&us.z_filefunc, us.filestream,&number_disk)!=UNZ_OK)
+            err=UNZ_ERRNO;
+
+        /* number of the disk with the start of the central directory */
+        if (unz64local_getShort(&us.z_filefunc, us.filestream,&number_disk_with_CD)!=UNZ_OK)
+            err=UNZ_ERRNO;
+
+        /* total number of entries in the central dir on this disk */
+        if (unz64local_getShort(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
+            err=UNZ_ERRNO;
+        us.gi.number_entry = uL;
+
+        /* total number of entries in the central dir */
+        if (unz64local_getShort(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
+            err=UNZ_ERRNO;
+        number_entry_CD = uL;
+
+        if ((number_entry_CD!=us.gi.number_entry) ||
+            (number_disk_with_CD!=0) ||
+            (number_disk!=0))
+            err=UNZ_BADZIPFILE;
+
+        /* size of the central directory */
+        if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
+            err=UNZ_ERRNO;
+        us.size_central_dir = uL;
+
+        /* offset of start of central directory with respect to the
+            starting disk number */
+        if (unz64local_getLong(&us.z_filefunc, us.filestream,&uL)!=UNZ_OK)
+            err=UNZ_ERRNO;
+        us.offset_central_dir = uL;
+
+        /* zipfile comment length */
+        if (unz64local_getShort(&us.z_filefunc, us.filestream,&us.gi.size_comment)!=UNZ_OK)
+            err=UNZ_ERRNO;
+    }
+
+    if ((central_pos<us.offset_central_dir+us.size_central_dir) &&
+        (err==UNZ_OK))
+        err=UNZ_BADZIPFILE;
+
+    if (err!=UNZ_OK)
+    {
+        ZCLOSE64(us.z_filefunc, us.filestream);
+        return NULL;
+    }
+
+    us.byte_before_the_zipfile = central_pos -
+                            (us.offset_central_dir+us.size_central_dir);
+    us.central_pos = central_pos;
+    us.pfile_in_zip_read = NULL;
+    us.encrypted = 0;
+
+
+    s=(unz64_s*)ALLOC(sizeof(unz64_s));
+    if( s != NULL)
+    {
+        *s=us;
+        unzGoToFirstFile((unzFile)s);
+    }
+    return (unzFile)s;
+}
+
+
+extern unzFile ZEXPORT unzOpen2 (const char *path,
+                                        zlib_filefunc_def* pzlib_filefunc32_def)
+{
+    if (pzlib_filefunc32_def != NULL)
+    {
+        zlib_filefunc64_32_def zlib_filefunc64_32_def_fill;
+        fill_zlib_filefunc64_32_def_from_filefunc32(&zlib_filefunc64_32_def_fill,pzlib_filefunc32_def);
+        return unzOpenInternal(path, &zlib_filefunc64_32_def_fill, 0);
+    }
+    else
+        return unzOpenInternal(path, NULL, 0);
+}
+
+extern unzFile ZEXPORT unzOpen2_64 (const void *path,
+                                     zlib_filefunc64_def* pzlib_filefunc_def)
+{
+    if (pzlib_filefunc_def != NULL)
+    {
+        zlib_filefunc64_32_def zlib_filefunc64_32_def_fill;
+        zlib_filefunc64_32_def_fill.zfile_func64 = *pzlib_filefunc_def;
+        zlib_filefunc64_32_def_fill.ztell32_file = NULL;
+        zlib_filefunc64_32_def_fill.zseek32_file = NULL;
+        return unzOpenInternal(path, &zlib_filefunc64_32_def_fill, 1);
+    }
+    else
+        return unzOpenInternal(path, NULL, 1);
+}
+
+extern unzFile ZEXPORT unzOpen (const char *path)
+{
+    return unzOpenInternal(path, NULL, 0);
+}
+
+extern unzFile ZEXPORT unzOpen64 (const void *path)
+{
+    return unzOpenInternal(path, NULL, 1);
+}
+
+/*
+  Close a ZipFile opened with unzOpen.
+  If there is files inside the .Zip opened with unzOpenCurrentFile (see later),
+    these files MUST be closed with unzCloseCurrentFile before call unzClose.
+  return UNZ_OK if there is no problem. */
+extern int ZEXPORT unzClose (unzFile file)
+{
+    unz64_s* s;
+    if (file==NULL)
+        return UNZ_PARAMERROR;
+    s=(unz64_s*)file;
+
+    if (s->pfile_in_zip_read!=NULL)
+        unzCloseCurrentFile(file);
+
+    ZCLOSE64(s->z_filefunc, s->filestream);
+    TRYFREE(s);
+    return UNZ_OK;
+}
+
+
+/*
+  Write info about the ZipFile in the *pglobal_info structure.
+  No preparation of the structure is needed
+  return UNZ_OK if there is no problem. */
+extern int ZEXPORT unzGetGlobalInfo64 (unzFile file, unz_global_info64* pglobal_info)
+{
+    unz64_s* s;
+    if (file==NULL)
+        return UNZ_PARAMERROR;
+    s=(unz64_s*)file;
+    *pglobal_info=s->gi;
+    return UNZ_OK;
+}
+
+extern int ZEXPORT unzGetGlobalInfo (unzFile file, unz_global_info* pglobal_info32)
+{
+    unz64_s* s;
+    if (file==NULL)
+        return UNZ_PARAMERROR;
+    s=(unz64_s*)file;
+    /* to do : check if number_entry is not truncated */
+    pglobal_info32->number_entry = (uLong)s->gi.number_entry;
+    pglobal_info32->size_comment = s->gi.size_comment;
+    return UNZ_OK;
+}
+/*
+   Translate date/time from Dos format to tm_unz (readable more easilty)
+*/
+local void unz64local_DosDateToTmuDate (ZPOS64_T ulDosDate, tm_unz* ptm)
+{
+    ZPOS64_T uDate;
+    uDate = (ZPOS64_T)(ulDosDate>>16);
+    ptm->tm_mday = (uInt)(uDate&0x1f) ;
+    ptm->tm_mon =  (uInt)((((uDate)&0x1E0)/0x20)-1) ;
+    ptm->tm_year = (uInt)(((uDate&0x0FE00)/0x0200)+1980) ;
+
+    ptm->tm_hour = (uInt) ((ulDosDate &0xF800)/0x800);
+    ptm->tm_min =  (uInt) ((ulDosDate&0x7E0)/0x20) ;
+    ptm->tm_sec =  (uInt) (2*(ulDosDate&0x1f)) ;
+}
+
+/*
+  Get Info about the current file in the zipfile, with internal only info
+*/
+local int unz64local_GetCurrentFileInfoInternal OF((unzFile file,
+                                                  unz_file_info64 *pfile_info,
+                                                  unz_file_info64_internal
+                                                  *pfile_info_internal,
+                                                  char *szFileName,
+                                                  uLong fileNameBufferSize,
+                                                  void *extraField,
+                                                  uLong extraFieldBufferSize,
+                                                  char *szComment,
+                                                  uLong commentBufferSize));
+
+local int unz64local_GetCurrentFileInfoInternal (unzFile file,
+                                                  unz_file_info64 *pfile_info,
+                                                  unz_file_info64_internal
+                                                  *pfile_info_internal,
+                                                  char *szFileName,
+                                                  uLong fileNameBufferSize,
+                                                  void *extraField,
+                                                  uLong extraFieldBufferSize,
+                                                  char *szComment,
+                                                  uLong commentBufferSize)
+{
+    unz64_s* s;
+    unz_file_info64 file_info;
+    unz_file_info64_internal file_info_internal;
+    int err=UNZ_OK;
+    uLong uMagic;
+    long lSeek=0;
+    uLong uL;
+
+    if (file==NULL)
+        return UNZ_PARAMERROR;
+    s=(unz64_s*)file;
+    if (ZSEEK64(s->z_filefunc, s->filestream,
+              s->pos_in_central_dir+s->byte_before_the_zipfile,
+              ZLIB_FILEFUNC_SEEK_SET)!=0)
+        err=UNZ_ERRNO;
+
+
+    /* we check the magic */
+    if (err==UNZ_OK)
+    {
+        if (unz64local_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK)
+            err=UNZ_ERRNO;
+        else if (uMagic!=0x02014b50)
+            err=UNZ_BADZIPFILE;
+    }
+
+    if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.version) != UNZ_OK)
+        err=UNZ_ERRNO;
+
+    if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.version_needed) != UNZ_OK)
+        err=UNZ_ERRNO;
+
+    if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.flag) != UNZ_OK)
+        err=UNZ_ERRNO;
+
+    if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.compression_method) != UNZ_OK)
+        err=UNZ_ERRNO;
+
+    if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.dosDate) != UNZ_OK)
+        err=UNZ_ERRNO;
+
+    unz64local_DosDateToTmuDate(file_info.dosDate,&file_info.tmu_date);
+
+    if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.crc) != UNZ_OK)
+        err=UNZ_ERRNO;
+
+    if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK)
+        err=UNZ_ERRNO;
+    file_info.compressed_size = uL;
+
+    if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK)
+        err=UNZ_ERRNO;
+    file_info.uncompressed_size = uL;
+
+    if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_filename) != UNZ_OK)
+        err=UNZ_ERRNO;
+
+    if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_extra) != UNZ_OK)
+        err=UNZ_ERRNO;
+
+    if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.size_file_comment) != UNZ_OK)
+        err=UNZ_ERRNO;
+
+    if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.disk_num_start) != UNZ_OK)
+        err=UNZ_ERRNO;
+
+    if (unz64local_getShort(&s->z_filefunc, s->filestream,&file_info.internal_fa) != UNZ_OK)
+        err=UNZ_ERRNO;
+
+    if (unz64local_getLong(&s->z_filefunc, s->filestream,&file_info.external_fa) != UNZ_OK)
+        err=UNZ_ERRNO;
+
+                // relative offset of local header
+    if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK)
+        err=UNZ_ERRNO;
+    file_info_internal.offset_curfile = uL;
+
+    lSeek+=file_info.size_filename;
+    if ((err==UNZ_OK) && (szFileName!=NULL))
+    {
+        uLong uSizeRead ;
+        if (file_info.size_filename<fileNameBufferSize)
+        {
+            *(szFileName+file_info.size_filename)='\0';
+            uSizeRead = file_info.size_filename;
+        }
+        else
+            uSizeRead = fileNameBufferSize;
+
+        if ((file_info.size_filename>0) && (fileNameBufferSize>0))
+            if (ZREAD64(s->z_filefunc, s->filestream,szFileName,uSizeRead)!=uSizeRead)
+                err=UNZ_ERRNO;
+        lSeek -= uSizeRead;
+    }
+
+    // Read extrafield
+    if ((err==UNZ_OK) && (extraField!=NULL))
+    {
+        ZPOS64_T uSizeRead ;
+        if (file_info.size_file_extra<extraFieldBufferSize)
+            uSizeRead = file_info.size_file_extra;
+        else
+            uSizeRead = extraFieldBufferSize;
+
+        if (lSeek!=0)
+        {
+            if (ZSEEK64(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
+                lSeek=0;
+            else
+                err=UNZ_ERRNO;
+        }
+
+        if ((file_info.size_file_extra>0) && (extraFieldBufferSize>0))
+            if (ZREAD64(s->z_filefunc, s->filestream,extraField,(uLong)uSizeRead)!=uSizeRead)
+                err=UNZ_ERRNO;
+
+        lSeek += file_info.size_file_extra - (uLong)uSizeRead;
+    }
+    else
+        lSeek += file_info.size_file_extra;
+
+
+    if ((err==UNZ_OK) && (file_info.size_file_extra != 0))
+    {
+                                uLong acc = 0;
+
+        // since lSeek now points to after the extra field we need to move back
+        lSeek -= file_info.size_file_extra;
+
+        if (lSeek!=0)
+        {
+            if (ZSEEK64(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
+                lSeek=0;
+            else
+                err=UNZ_ERRNO;
+        }
+
+        while(acc < file_info.size_file_extra)
+        {
+            uLong headerId;
+                                                uLong dataSize;
+
+            if (unz64local_getShort(&s->z_filefunc, s->filestream,&headerId) != UNZ_OK)
+                err=UNZ_ERRNO;
+
+            if (unz64local_getShort(&s->z_filefunc, s->filestream,&dataSize) != UNZ_OK)
+                err=UNZ_ERRNO;
+
+            /* ZIP64 extra fields */
+            if (headerId == 0x0001)
+            {
+                                                        uLong uL;
+
+                                                                if(file_info.uncompressed_size == MAXU32)
+                                                                {
+                                                                        if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info.uncompressed_size) != UNZ_OK)
+                                                                                        err=UNZ_ERRNO;
+                                                                }
+
+                                                                if(file_info.compressed_size == MAXU32)
+                                                                {
+                                                                        if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info.compressed_size) != UNZ_OK)
+                                                                                  err=UNZ_ERRNO;
+                                                                }
+
+                                                                if(file_info_internal.offset_curfile == MAXU32)
+                                                                {
+                                                                        /* Relative Header offset */
+                                                                        if (unz64local_getLong64(&s->z_filefunc, s->filestream,&file_info_internal.offset_curfile) != UNZ_OK)
+                                                                                err=UNZ_ERRNO;
+                                                                }
+
+                                                                if(file_info.disk_num_start == MAXU32)
+                                                                {
+                                                                        /* Disk Start Number */
+                                                                        if (unz64local_getLong(&s->z_filefunc, s->filestream,&uL) != UNZ_OK)
+                                                                                err=UNZ_ERRNO;
+                                                                }
+
+            }
+            else
+            {
+                if (ZSEEK64(s->z_filefunc, s->filestream,dataSize,ZLIB_FILEFUNC_SEEK_CUR)!=0)
+                    err=UNZ_ERRNO;
+            }
+
+            acc += 2 + 2 + dataSize;
+        }
+    }
+
+    if ((err==UNZ_OK) && (szComment!=NULL))
+    {
+        uLong uSizeRead ;
+        if (file_info.size_file_comment<commentBufferSize)
+        {
+            *(szComment+file_info.size_file_comment)='\0';
+            uSizeRead = file_info.size_file_comment;
+        }
+        else
+            uSizeRead = commentBufferSize;
+
+        if (lSeek!=0)
+        {
+            if (ZSEEK64(s->z_filefunc, s->filestream,lSeek,ZLIB_FILEFUNC_SEEK_CUR)==0)
+                lSeek=0;
+            else
+                err=UNZ_ERRNO;
+        }
+
+        if ((file_info.size_file_comment>0) && (commentBufferSize>0))
+            if (ZREAD64(s->z_filefunc, s->filestream,szComment,uSizeRead)!=uSizeRead)
+                err=UNZ_ERRNO;
+        lSeek+=file_info.size_file_comment - uSizeRead;
+    }
+    else
+        lSeek+=file_info.size_file_comment;
+
+
+    if ((err==UNZ_OK) && (pfile_info!=NULL))
+        *pfile_info=file_info;
+
+    if ((err==UNZ_OK) && (pfile_info_internal!=NULL))
+        *pfile_info_internal=file_info_internal;
+
+    return err;
+}
+
+
+
+/*
+  Write info about the ZipFile in the *pglobal_info structure.
+  No preparation of the structure is needed
+  return UNZ_OK if there is no problem.
+*/
+extern int ZEXPORT unzGetCurrentFileInfo64 (unzFile file,
+                                          unz_file_info64 * pfile_info,
+                                          char * szFileName, uLong fileNameBufferSize,
+                                          void *extraField, uLong extraFieldBufferSize,
+                                          char* szComment,  uLong commentBufferSize)
+{
+    return unz64local_GetCurrentFileInfoInternal(file,pfile_info,NULL,
+                                                szFileName,fileNameBufferSize,
+                                                extraField,extraFieldBufferSize,
+                                                szComment,commentBufferSize);
+}
+
+extern int ZEXPORT unzGetCurrentFileInfo (unzFile file,
+                                          unz_file_info * pfile_info,
+                                          char * szFileName, uLong fileNameBufferSize,
+                                          void *extraField, uLong extraFieldBufferSize,
+                                          char* szComment,  uLong commentBufferSize)
+{
+    int err;
+    unz_file_info64 file_info64;
+    err = unz64local_GetCurrentFileInfoInternal(file,&file_info64,NULL,
+                                                szFileName,fileNameBufferSize,
+                                                extraField,extraFieldBufferSize,
+                                                szComment,commentBufferSize);
+    if ((err==UNZ_OK) && (pfile_info != NULL))
+    {
+        pfile_info->version = file_info64.version;
+        pfile_info->version_needed = file_info64.version_needed;
+        pfile_info->flag = file_info64.flag;
+        pfile_info->compression_method = file_info64.compression_method;
+        pfile_info->dosDate = file_info64.dosDate;
+        pfile_info->crc = file_info64.crc;
+
+        pfile_info->size_filename = file_info64.size_filename;
+        pfile_info->size_file_extra = file_info64.size_file_extra;
+        pfile_info->size_file_comment = file_info64.size_file_comment;
+
+        pfile_info->disk_num_start = file_info64.disk_num_start;
+        pfile_info->internal_fa = file_info64.internal_fa;
+        pfile_info->external_fa = file_info64.external_fa;
+
+        pfile_info->tmu_date = file_info64.tmu_date,
+
+
+        pfile_info->compressed_size = (uLong)file_info64.compressed_size;
+        pfile_info->uncompressed_size = (uLong)file_info64.uncompressed_size;
+
+    }
+    return err;
+}
+/*
+  Set the current file of the zipfile to the first file.
+  return UNZ_OK if there is no problem
+*/
+extern int ZEXPORT unzGoToFirstFile (unzFile file)
+{
+    int err=UNZ_OK;
+    unz64_s* s;
+    if (file==NULL)
+        return UNZ_PARAMERROR;
+    s=(unz64_s*)file;
+    s->pos_in_central_dir=s->offset_central_dir;
+    s->num_file=0;
+    err=unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info,
+                                             &s->cur_file_info_internal,
+                                             NULL,0,NULL,0,NULL,0);
+    s->current_file_ok = (err == UNZ_OK);
+    return err;
+}
+
+/*
+  Set the current file of the zipfile to the next file.
+  return UNZ_OK if there is no problem
+  return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
+*/
+extern int ZEXPORT unzGoToNextFile (unzFile  file)
+{
+    unz64_s* s;
+    int err;
+
+    if (file==NULL)
+        return UNZ_PARAMERROR;
+    s=(unz64_s*)file;
+    if (!s->current_file_ok)
+        return UNZ_END_OF_LIST_OF_FILE;
+    if (s->gi.number_entry != 0xffff)    /* 2^16 files overflow hack */
+      if (s->num_file+1==s->gi.number_entry)
+        return UNZ_END_OF_LIST_OF_FILE;
+
+    s->pos_in_central_dir += SIZECENTRALDIRITEM + s->cur_file_info.size_filename +
+            s->cur_file_info.size_file_extra + s->cur_file_info.size_file_comment ;
+    s->num_file++;
+    err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info,
+                                               &s->cur_file_info_internal,
+                                               NULL,0,NULL,0,NULL,0);
+    s->current_file_ok = (err == UNZ_OK);
+    return err;
+}
+
+
+/*
+  Try locate the file szFileName in the zipfile.
+  For the iCaseSensitivity signification, see unzStringFileNameCompare
+
+  return value :
+  UNZ_OK if the file is found. It becomes the current file.
+  UNZ_END_OF_LIST_OF_FILE if the file is not found
+*/
+extern int ZEXPORT unzLocateFile (unzFile file, const char *szFileName, int iCaseSensitivity)
+{
+    unz64_s* s;
+    int err;
+
+    /* We remember the 'current' position in the file so that we can jump
+     * back there if we fail.
+     */
+    unz_file_info64 cur_file_infoSaved;
+    unz_file_info64_internal cur_file_info_internalSaved;
+    ZPOS64_T num_fileSaved;
+    ZPOS64_T pos_in_central_dirSaved;
+
+
+    if (file==NULL)
+        return UNZ_PARAMERROR;
+
+    if (strlen(szFileName)>=UNZ_MAXFILENAMEINZIP)
+        return UNZ_PARAMERROR;
+
+    s=(unz64_s*)file;
+    if (!s->current_file_ok)
+        return UNZ_END_OF_LIST_OF_FILE;
+
+    /* Save the current state */
+    num_fileSaved = s->num_file;
+    pos_in_central_dirSaved = s->pos_in_central_dir;
+    cur_file_infoSaved = s->cur_file_info;
+    cur_file_info_internalSaved = s->cur_file_info_internal;
+
+    err = unzGoToFirstFile(file);
+
+    while (err == UNZ_OK)
+    {
+        char szCurrentFileName[UNZ_MAXFILENAMEINZIP+1];
+        err = unzGetCurrentFileInfo64(file,NULL,
+                                    szCurrentFileName,sizeof(szCurrentFileName)-1,
+                                    NULL,0,NULL,0);
+        if (err == UNZ_OK)
+        {
+            if (unzStringFileNameCompare(szCurrentFileName,
+                                            szFileName,iCaseSensitivity)==0)
+                return UNZ_OK;
+            err = unzGoToNextFile(file);
+        }
+    }
+
+    /* We failed, so restore the state of the 'current file' to where we
+     * were.
+     */
+    s->num_file = num_fileSaved ;
+    s->pos_in_central_dir = pos_in_central_dirSaved ;
+    s->cur_file_info = cur_file_infoSaved;
+    s->cur_file_info_internal = cur_file_info_internalSaved;
+    return err;
+}
+
+
+/*
+///////////////////////////////////////////
+// Contributed by Ryan Haksi (mailto://cryogen@infoserve.net)
+// I need random access
+//
+// Further optimization could be realized by adding an ability
+// to cache the directory in memory. The goal being a single
+// comprehensive file read to put the file I need in a memory.
+*/
+
+/*
+typedef struct unz_file_pos_s
+{
+    ZPOS64_T pos_in_zip_directory;   // offset in file
+    ZPOS64_T num_of_file;            // # of file
+} unz_file_pos;
+*/
+
+extern int ZEXPORT unzGetFilePos64(unzFile file, unz64_file_pos*  file_pos)
+{
+    unz64_s* s;
+
+    if (file==NULL || file_pos==NULL)
+        return UNZ_PARAMERROR;
+    s=(unz64_s*)file;
+    if (!s->current_file_ok)
+        return UNZ_END_OF_LIST_OF_FILE;
+
+    file_pos->pos_in_zip_directory  = s->pos_in_central_dir;
+    file_pos->num_of_file           = s->num_file;
+
+    return UNZ_OK;
+}
+
+extern int ZEXPORT unzGetFilePos(
+    unzFile file,
+    unz_file_pos* file_pos)
+{
+    unz64_file_pos file_pos64;
+    int err = unzGetFilePos64(file,&file_pos64);
+    if (err==UNZ_OK)
+    {
+        file_pos->pos_in_zip_directory = (uLong)file_pos64.pos_in_zip_directory;
+        file_pos->num_of_file = (uLong)file_pos64.num_of_file;
+    }
+    return err;
+}
+
+extern int ZEXPORT unzGoToFilePos64(unzFile file, const unz64_file_pos* file_pos)
+{
+    unz64_s* s;
+    int err;
+
+    if (file==NULL || file_pos==NULL)
+        return UNZ_PARAMERROR;
+    s=(unz64_s*)file;
+
+    /* jump to the right spot */
+    s->pos_in_central_dir = file_pos->pos_in_zip_directory;
+    s->num_file           = file_pos->num_of_file;
+
+    /* set the current file */
+    err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info,
+                                               &s->cur_file_info_internal,
+                                               NULL,0,NULL,0,NULL,0);
+    /* return results */
+    s->current_file_ok = (err == UNZ_OK);
+    return err;
+}
+
+extern int ZEXPORT unzGoToFilePos(
+    unzFile file,
+    unz_file_pos* file_pos)
+{
+    unz64_file_pos file_pos64;
+    if (file_pos == NULL)
+        return UNZ_PARAMERROR;
+
+    file_pos64.pos_in_zip_directory = file_pos->pos_in_zip_directory;
+    file_pos64.num_of_file = file_pos->num_of_file;
+    return unzGoToFilePos64(file,&file_pos64);
+}
+
+/*
+// Unzip Helper Functions - should be here?
+///////////////////////////////////////////
+*/
+
+/*
+  Read the local header of the current zipfile
+  Check the coherency of the local header and info in the end of central
+        directory about this file
+  store in *piSizeVar the size of extra info in local header
+        (filename and size of extra field data)
+*/
+local int unz64local_CheckCurrentFileCoherencyHeader (unz64_s* s, uInt* piSizeVar,
+                                                    ZPOS64_T * poffset_local_extrafield,
+                                                    uInt  * psize_local_extrafield)
+{
+    uLong uMagic,uData,uFlags;
+    uLong size_filename;
+    uLong size_extra_field;
+    int err=UNZ_OK;
+
+    *piSizeVar = 0;
+    *poffset_local_extrafield = 0;
+    *psize_local_extrafield = 0;
+
+    if (ZSEEK64(s->z_filefunc, s->filestream,s->cur_file_info_internal.offset_curfile +
+                                s->byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET)!=0)
+        return UNZ_ERRNO;
+
+
+    if (err==UNZ_OK)
+    {
+        if (unz64local_getLong(&s->z_filefunc, s->filestream,&uMagic) != UNZ_OK)
+            err=UNZ_ERRNO;
+        else if (uMagic!=0x04034b50)
+            err=UNZ_BADZIPFILE;
+    }
+
+    if (unz64local_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK)
+        err=UNZ_ERRNO;
+/*
+    else if ((err==UNZ_OK) && (uData!=s->cur_file_info.wVersion))
+        err=UNZ_BADZIPFILE;
+*/
+    if (unz64local_getShort(&s->z_filefunc, s->filestream,&uFlags) != UNZ_OK)
+        err=UNZ_ERRNO;
+
+    if (unz64local_getShort(&s->z_filefunc, s->filestream,&uData) != UNZ_OK)
+        err=UNZ_ERRNO;
+    else if ((err==UNZ_OK) && (uData!=s->cur_file_info.compression_method))
+        err=UNZ_BADZIPFILE;
+
+    if ((err==UNZ_OK) && (s->cur_file_info.compression_method!=0) &&
+/* #ifdef HAVE_BZIP2 */
+                         (s->cur_file_info.compression_method!=Z_BZIP2ED) &&
+/* #endif */
+                         (s->cur_file_info.compression_method!=Z_DEFLATED))
+        err=UNZ_BADZIPFILE;
+
+    if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* date/time */
+        err=UNZ_ERRNO;
+
+    if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* crc */
+        err=UNZ_ERRNO;
+    else if ((err==UNZ_OK) && (uData!=s->cur_file_info.crc) && ((uFlags & 8)==0))
+        err=UNZ_BADZIPFILE;
+
+    if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size compr */
+        err=UNZ_ERRNO;
+    else if (uData != 0xFFFFFFFF && (err==UNZ_OK) && (uData!=s->cur_file_info.compressed_size) && ((uFlags & 8)==0))
+        err=UNZ_BADZIPFILE;
+
+    if (unz64local_getLong(&s->z_filefunc, s->filestream,&uData) != UNZ_OK) /* size uncompr */
+        err=UNZ_ERRNO;
+    else if (uData != 0xFFFFFFFF && (err==UNZ_OK) && (uData!=s->cur_file_info.uncompressed_size) && ((uFlags & 8)==0))
+        err=UNZ_BADZIPFILE;
+
+    if (unz64local_getShort(&s->z_filefunc, s->filestream,&size_filename) != UNZ_OK)
+        err=UNZ_ERRNO;
+    else if ((err==UNZ_OK) && (size_filename!=s->cur_file_info.size_filename))
+        err=UNZ_BADZIPFILE;
+
+    *piSizeVar += (uInt)size_filename;
+
+    if (unz64local_getShort(&s->z_filefunc, s->filestream,&size_extra_field) != UNZ_OK)
+        err=UNZ_ERRNO;
+    *poffset_local_extrafield= s->cur_file_info_internal.offset_curfile +
+                                    SIZEZIPLOCALHEADER + size_filename;
+    *psize_local_extrafield = (uInt)size_extra_field;
+
+    *piSizeVar += (uInt)size_extra_field;
+
+    return err;
+}
+
+/*
+  Open for reading data the current file in the zipfile.
+  If there is no error and the file is opened, the return value is UNZ_OK.
+*/
+extern int ZEXPORT unzOpenCurrentFile3 (unzFile file, int* method,
+                                            int* level, int raw, const char* password)
+{
+    int err=UNZ_OK;
+    uInt iSizeVar;
+    unz64_s* s;
+    file_in_zip64_read_info_s* pfile_in_zip_read_info;
+    ZPOS64_T offset_local_extrafield;  /* offset of the local extra field */
+    uInt  size_local_extrafield;    /* size of the local extra field */
+#    ifndef NOUNCRYPT
+    char source[12];
+#    else
+    if (password != NULL)
+        return UNZ_PARAMERROR;
+#    endif
+
+    if (file==NULL)
+        return UNZ_PARAMERROR;
+    s=(unz64_s*)file;
+    if (!s->current_file_ok)
+        return UNZ_PARAMERROR;
+
+    if (s->pfile_in_zip_read != NULL)
+        unzCloseCurrentFile(file);
+
+    if (unz64local_CheckCurrentFileCoherencyHeader(s,&iSizeVar, &offset_local_extrafield,&size_local_extrafield)!=UNZ_OK)
+        return UNZ_BADZIPFILE;
+
+    pfile_in_zip_read_info = (file_in_zip64_read_info_s*)ALLOC(sizeof(file_in_zip64_read_info_s));
+    if (pfile_in_zip_read_info==NULL)
+        return UNZ_INTERNALERROR;
+
+    pfile_in_zip_read_info->read_buffer=(char*)ALLOC(UNZ_BUFSIZE);
+    pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield;
+    pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield;
+    pfile_in_zip_read_info->pos_local_extrafield=0;
+    pfile_in_zip_read_info->raw=raw;
+
+    if (pfile_in_zip_read_info->read_buffer==NULL)
+    {
+        TRYFREE(pfile_in_zip_read_info);
+        return UNZ_INTERNALERROR;
+    }
+
+    pfile_in_zip_read_info->stream_initialised=0;
+
+    if (method!=NULL)
+        *method = (int)s->cur_file_info.compression_method;
+
+    if (level!=NULL)
+    {
+        *level = 6;
+        switch (s->cur_file_info.flag & 0x06)
+        {
+          case 6 : *level = 1; break;
+          case 4 : *level = 2; break;
+          case 2 : *level = 9; break;
+        }
+    }
+
+    if ((s->cur_file_info.compression_method!=0) &&
+/* #ifdef HAVE_BZIP2 */
+        (s->cur_file_info.compression_method!=Z_BZIP2ED) &&
+/* #endif */
+        (s->cur_file_info.compression_method!=Z_DEFLATED))
+
+        err=UNZ_BADZIPFILE;
+
+    pfile_in_zip_read_info->crc32_wait=s->cur_file_info.crc;
+    pfile_in_zip_read_info->crc32=0;
+    pfile_in_zip_read_info->total_out_64=0;
+    pfile_in_zip_read_info->compression_method = s->cur_file_info.compression_method;
+    pfile_in_zip_read_info->filestream=s->filestream;
+    pfile_in_zip_read_info->z_filefunc=s->z_filefunc;
+    pfile_in_zip_read_info->byte_before_the_zipfile=s->byte_before_the_zipfile;
+
+    pfile_in_zip_read_info->stream.total_out = 0;
+
+    if ((s->cur_file_info.compression_method==Z_BZIP2ED) && (!raw))
+    {
+#ifdef HAVE_BZIP2
+      pfile_in_zip_read_info->bstream.bzalloc = (void *(*) (void *, int, int))0;
+      pfile_in_zip_read_info->bstream.bzfree = (free_func)0;
+      pfile_in_zip_read_info->bstream.opaque = (voidpf)0;
+      pfile_in_zip_read_info->bstream.state = (voidpf)0;
+
+      pfile_in_zip_read_info->stream.zalloc = (alloc_func)0;
+      pfile_in_zip_read_info->stream.zfree = (free_func)0;
+      pfile_in_zip_read_info->stream.opaque = (voidpf)0;
+      pfile_in_zip_read_info->stream.next_in = (voidpf)0;
+      pfile_in_zip_read_info->stream.avail_in = 0;
+
+      err=BZ2_bzDecompressInit(&pfile_in_zip_read_info->bstream, 0, 0);
+      if (err == Z_OK)
+        pfile_in_zip_read_info->stream_initialised=Z_BZIP2ED;
+      else
+      {
+        TRYFREE(pfile_in_zip_read_info);
+        return err;
+      }
+#else
+      pfile_in_zip_read_info->raw=1;
+#endif
+    }
+    else if ((s->cur_file_info.compression_method==Z_DEFLATED) && (!raw))
+    {
+      pfile_in_zip_read_info->stream.zalloc = (alloc_func)0;
+      pfile_in_zip_read_info->stream.zfree = (free_func)0;
+      pfile_in_zip_read_info->stream.opaque = (voidpf)0;
+      pfile_in_zip_read_info->stream.next_in = 0;
+      pfile_in_zip_read_info->stream.avail_in = 0;
+
+      err=inflateInit2(&pfile_in_zip_read_info->stream, -MAX_WBITS);
+      if (err == Z_OK)
+        pfile_in_zip_read_info->stream_initialised=Z_DEFLATED;
+      else
+      {
+        TRYFREE(pfile_in_zip_read_info);
+        return err;
+      }
+        /* windowBits is passed < 0 to tell that there is no zlib header.
+         * Note that in this case inflate *requires* an extra "dummy" byte
+         * after the compressed stream in order to complete decompression and
+         * return Z_STREAM_END.
+         * In unzip, i don't wait absolutely Z_STREAM_END because I known the
+         * size of both compressed and uncompressed data
+         */
+    }
+    pfile_in_zip_read_info->rest_read_compressed =
+            s->cur_file_info.compressed_size ;
+    pfile_in_zip_read_info->rest_read_uncompressed =
+            s->cur_file_info.uncompressed_size ;
+
+
+    pfile_in_zip_read_info->pos_in_zipfile =
+            s->cur_file_info_internal.offset_curfile + SIZEZIPLOCALHEADER +
+              iSizeVar;
+
+    pfile_in_zip_read_info->stream.avail_in = (uInt)0;
+
+    s->pfile_in_zip_read = pfile_in_zip_read_info;
+                s->encrypted = 0;
+
+#    ifndef NOUNCRYPT
+    if (password != NULL)
+    {
+        int i;
+        s->pcrc_32_tab = get_crc_table();
+        init_keys(password,s->keys,s->pcrc_32_tab);
+        if (ZSEEK64(s->z_filefunc, s->filestream,
+                  s->pfile_in_zip_read->pos_in_zipfile +
+                     s->pfile_in_zip_read->byte_before_the_zipfile,
+                  SEEK_SET)!=0)
+            return UNZ_INTERNALERROR;
+        if(ZREAD64(s->z_filefunc, s->filestream,source, 12)<12)
+            return UNZ_INTERNALERROR;
+
+        for (i = 0; i<12; i++)
+            zdecode(s->keys,s->pcrc_32_tab,source[i]);
+
+        s->pfile_in_zip_read->pos_in_zipfile+=12;
+        s->encrypted=1;
+    }
+#    endif
+
+
+    return UNZ_OK;
+}
+
+extern int ZEXPORT unzOpenCurrentFile (unzFile file)
+{
+    return unzOpenCurrentFile3(file, NULL, NULL, 0, NULL);
+}
+
+extern int ZEXPORT unzOpenCurrentFilePassword (unzFile file, const char*  password)
+{
+    return unzOpenCurrentFile3(file, NULL, NULL, 0, password);
+}
+
+extern int ZEXPORT unzOpenCurrentFile2 (unzFile file, int* method, int* level, int raw)
+{
+    return unzOpenCurrentFile3(file, method, level, raw, NULL);
+}
+
+/** Addition for GDAL : START */
+
+extern ZPOS64_T ZEXPORT unzGetCurrentFileZStreamPos64( unzFile file)
+{
+    unz64_s* s;
+    file_in_zip64_read_info_s* pfile_in_zip_read_info;
+    s=(unz64_s*)file;
+    if (file==NULL)
+        return 0; //UNZ_PARAMERROR;
+    pfile_in_zip_read_info=s->pfile_in_zip_read;
+    if (pfile_in_zip_read_info==NULL)
+        return 0; //UNZ_PARAMERROR;
+    return pfile_in_zip_read_info->pos_in_zipfile +
+                         pfile_in_zip_read_info->byte_before_the_zipfile;
+}
+
+/** Addition for GDAL : END */
+
+/*
+  Read bytes from the current file.
+  buf contain buffer where data must be copied
+  len the size of buf.
+
+  return the number of byte copied if somes bytes are copied
+  return 0 if the end of file was reached
+  return <0 with error code if there is an error
+    (UNZ_ERRNO for IO error, or zLib error for uncompress error)
+*/
+extern int ZEXPORT unzReadCurrentFile  (unzFile file, voidp buf, unsigned len)
+{
+    int err=UNZ_OK;
+    uInt iRead = 0;
+    unz64_s* s;
+    file_in_zip64_read_info_s* pfile_in_zip_read_info;
+    if (file==NULL)
+        return UNZ_PARAMERROR;
+    s=(unz64_s*)file;
+    pfile_in_zip_read_info=s->pfile_in_zip_read;
+
+    if (pfile_in_zip_read_info==NULL)
+        return UNZ_PARAMERROR;
+
+
+    if (pfile_in_zip_read_info->read_buffer == NULL)
+        return UNZ_END_OF_LIST_OF_FILE;
+    if (len==0)
+        return 0;
+
+    pfile_in_zip_read_info->stream.next_out = (Bytef*)buf;
+
+    pfile_in_zip_read_info->stream.avail_out = (uInt)len;
+
+    if ((len>pfile_in_zip_read_info->rest_read_uncompressed) &&
+        (!(pfile_in_zip_read_info->raw)))
+        pfile_in_zip_read_info->stream.avail_out =
+            (uInt)pfile_in_zip_read_info->rest_read_uncompressed;
+
+    if ((len>pfile_in_zip_read_info->rest_read_compressed+
+           pfile_in_zip_read_info->stream.avail_in) &&
+         (pfile_in_zip_read_info->raw))
+        pfile_in_zip_read_info->stream.avail_out =
+            (uInt)pfile_in_zip_read_info->rest_read_compressed+
+            pfile_in_zip_read_info->stream.avail_in;
+
+    while (pfile_in_zip_read_info->stream.avail_out>0)
+    {
+        if ((pfile_in_zip_read_info->stream.avail_in==0) &&
+            (pfile_in_zip_read_info->rest_read_compressed>0))
+        {
+            uInt uReadThis = UNZ_BUFSIZE;
+            if (pfile_in_zip_read_info->rest_read_compressed<uReadThis)
+                uReadThis = (uInt)pfile_in_zip_read_info->rest_read_compressed;
+            if (uReadThis == 0)
+                return UNZ_EOF;
+            if (ZSEEK64(pfile_in_zip_read_info->z_filefunc,
+                      pfile_in_zip_read_info->filestream,
+                      pfile_in_zip_read_info->pos_in_zipfile +
+                         pfile_in_zip_read_info->byte_before_the_zipfile,
+                         ZLIB_FILEFUNC_SEEK_SET)!=0)
+                return UNZ_ERRNO;
+            if (ZREAD64(pfile_in_zip_read_info->z_filefunc,
+                      pfile_in_zip_read_info->filestream,
+                      pfile_in_zip_read_info->read_buffer,
+                      uReadThis)!=uReadThis)
+                return UNZ_ERRNO;
+
+
+#            ifndef NOUNCRYPT
+            if(s->encrypted)
+            {
+                uInt i;
+                for(i=0;i<uReadThis;i++)
+                  pfile_in_zip_read_info->read_buffer[i] =
+                      zdecode(s->keys,s->pcrc_32_tab,
+                              pfile_in_zip_read_info->read_buffer[i]);
+            }
+#            endif
+
+
+            pfile_in_zip_read_info->pos_in_zipfile += uReadThis;
+
+            pfile_in_zip_read_info->rest_read_compressed-=uReadThis;
+
+            pfile_in_zip_read_info->stream.next_in =
+                (Bytef*)pfile_in_zip_read_info->read_buffer;
+            pfile_in_zip_read_info->stream.avail_in = (uInt)uReadThis;
+        }
+
+        if ((pfile_in_zip_read_info->compression_method==0) || (pfile_in_zip_read_info->raw))
+        {
+            uInt uDoCopy,i ;
+
+            if ((pfile_in_zip_read_info->stream.avail_in == 0) &&
+                (pfile_in_zip_read_info->rest_read_compressed == 0))
+                return (iRead==0) ? UNZ_EOF : iRead;
+
+            if (pfile_in_zip_read_info->stream.avail_out <
+                            pfile_in_zip_read_info->stream.avail_in)
+                uDoCopy = pfile_in_zip_read_info->stream.avail_out ;
+            else
+                uDoCopy = pfile_in_zip_read_info->stream.avail_in ;
+
+            for (i=0;i<uDoCopy;i++)
+                *(pfile_in_zip_read_info->stream.next_out+i) =
+                        *(pfile_in_zip_read_info->stream.next_in+i);
+
+            pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uDoCopy;
+
+            pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,
+                                pfile_in_zip_read_info->stream.next_out,
+                                uDoCopy);
+            pfile_in_zip_read_info->rest_read_uncompressed-=uDoCopy;
+            pfile_in_zip_read_info->stream.avail_in -= uDoCopy;
+            pfile_in_zip_read_info->stream.avail_out -= uDoCopy;
+            pfile_in_zip_read_info->stream.next_out += uDoCopy;
+            pfile_in_zip_read_info->stream.next_in += uDoCopy;
+            pfile_in_zip_read_info->stream.total_out += uDoCopy;
+            iRead += uDoCopy;
+        }
+        else if (pfile_in_zip_read_info->compression_method==Z_BZIP2ED)
+        {
+#ifdef HAVE_BZIP2
+            uLong uTotalOutBefore,uTotalOutAfter;
+            const Bytef *bufBefore;
+            uLong uOutThis;
+
+            pfile_in_zip_read_info->bstream.next_in        = (char*)pfile_in_zip_read_info->stream.next_in;
+            pfile_in_zip_read_info->bstream.avail_in       = pfile_in_zip_read_info->stream.avail_in;
+            pfile_in_zip_read_info->bstream.total_in_lo32  = pfile_in_zip_read_info->stream.total_in;
+            pfile_in_zip_read_info->bstream.total_in_hi32  = 0;
+            pfile_in_zip_read_info->bstream.next_out       = (char*)pfile_in_zip_read_info->stream.next_out;
+            pfile_in_zip_read_info->bstream.avail_out      = pfile_in_zip_read_info->stream.avail_out;
+            pfile_in_zip_read_info->bstream.total_out_lo32 = pfile_in_zip_read_info->stream.total_out;
+            pfile_in_zip_read_info->bstream.total_out_hi32 = 0;
+
+            uTotalOutBefore = pfile_in_zip_read_info->bstream.total_out_lo32;
+            bufBefore = (const Bytef *)pfile_in_zip_read_info->bstream.next_out;
+
+            err=BZ2_bzDecompress(&pfile_in_zip_read_info->bstream);
+
+            uTotalOutAfter = pfile_in_zip_read_info->bstream.total_out_lo32;
+            uOutThis = uTotalOutAfter-uTotalOutBefore;
+
+            pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uOutThis;
+
+            pfile_in_zip_read_info->crc32 = crc32(pfile_in_zip_read_info->crc32,bufBefore, (uInt)(uOutThis));
+            pfile_in_zip_read_info->rest_read_uncompressed -= uOutThis;
+            iRead += (uInt)(uTotalOutAfter - uTotalOutBefore);
+
+            pfile_in_zip_read_info->stream.next_in   = (Bytef*)pfile_in_zip_read_info->bstream.next_in;
+            pfile_in_zip_read_info->stream.avail_in  = pfile_in_zip_read_info->bstream.avail_in;
+            pfile_in_zip_read_info->stream.total_in  = pfile_in_zip_read_info->bstream.total_in_lo32;
+            pfile_in_zip_read_info->stream.next_out  = (Bytef*)pfile_in_zip_read_info->bstream.next_out;
+            pfile_in_zip_read_info->stream.avail_out = pfile_in_zip_read_info->bstream.avail_out;
+            pfile_in_zip_read_info->stream.total_out = pfile_in_zip_read_info->bstream.total_out_lo32;
+
+            if (err==BZ_STREAM_END)
+              return (iRead==0) ? UNZ_EOF : iRead;
+            if (err!=BZ_OK)
+              break;
+#endif
+        } // end Z_BZIP2ED
+        else
+        {
+            ZPOS64_T uTotalOutBefore,uTotalOutAfter;
+            const Bytef *bufBefore;
+            ZPOS64_T uOutThis;
+            int flush=Z_SYNC_FLUSH;
+
+            uTotalOutBefore = pfile_in_zip_read_info->stream.total_out;
+            bufBefore = pfile_in_zip_read_info->stream.next_out;
+
+            /*
+            if ((pfile_in_zip_read_info->rest_read_uncompressed ==
+                     pfile_in_zip_read_info->stream.avail_out) &&
+                (pfile_in_zip_read_info->rest_read_compressed == 0))
+                flush = Z_FINISH;
+            */
+            err=inflate(&pfile_in_zip_read_info->stream,flush);
+
+            if ((err>=0) && (pfile_in_zip_read_info->stream.msg!=NULL))
+              err = Z_DATA_ERROR;
+
+            uTotalOutAfter = pfile_in_zip_read_info->stream.total_out;
+            uOutThis = uTotalOutAfter-uTotalOutBefore;
+
+            pfile_in_zip_read_info->total_out_64 = pfile_in_zip_read_info->total_out_64 + uOutThis;
+
+            pfile_in_zip_read_info->crc32 =
+                crc32(pfile_in_zip_read_info->crc32,bufBefore,
+                        (uInt)(uOutThis));
+
+            pfile_in_zip_read_info->rest_read_uncompressed -=
+                uOutThis;
+
+            iRead += (uInt)(uTotalOutAfter - uTotalOutBefore);
+
+            if (err==Z_STREAM_END)
+                return (iRead==0) ? UNZ_EOF : iRead;
+            if (err!=Z_OK)
+                break;
+        }
+    }
+
+    if (err==Z_OK)
+        return iRead;
+    return err;
+}
+
+
+/*
+  Give the current position in uncompressed data
+*/
+extern z_off_t ZEXPORT unztell (unzFile file)
+{
+    unz64_s* s;
+    file_in_zip64_read_info_s* pfile_in_zip_read_info;
+    if (file==NULL)
+        return UNZ_PARAMERROR;
+    s=(unz64_s*)file;
+    pfile_in_zip_read_info=s->pfile_in_zip_read;
+
+    if (pfile_in_zip_read_info==NULL)
+        return UNZ_PARAMERROR;
+
+    return (z_off_t)pfile_in_zip_read_info->stream.total_out;
+}
+
+extern ZPOS64_T ZEXPORT unztell64 (unzFile file)
+{
+
+    unz64_s* s;
+    file_in_zip64_read_info_s* pfile_in_zip_read_info;
+    if (file==NULL)
+        return (ZPOS64_T)-1;
+    s=(unz64_s*)file;
+    pfile_in_zip_read_info=s->pfile_in_zip_read;
+
+    if (pfile_in_zip_read_info==NULL)
+        return (ZPOS64_T)-1;
+
+    return pfile_in_zip_read_info->total_out_64;
+}
+
+
+/*
+  return 1 if the end of file was reached, 0 elsewhere
+*/
+extern int ZEXPORT unzeof (unzFile file)
+{
+    unz64_s* s;
+    file_in_zip64_read_info_s* pfile_in_zip_read_info;
+    if (file==NULL)
+        return UNZ_PARAMERROR;
+    s=(unz64_s*)file;
+    pfile_in_zip_read_info=s->pfile_in_zip_read;
+
+    if (pfile_in_zip_read_info==NULL)
+        return UNZ_PARAMERROR;
+
+    if (pfile_in_zip_read_info->rest_read_uncompressed == 0)
+        return 1;
+    else
+        return 0;
+}
+
+
+
+/*
+Read extra field from the current file (opened by unzOpenCurrentFile)
+This is the local-header version of the extra field (sometimes, there is
+more info in the local-header version than in the central-header)
+
+  if buf==NULL, it return the size of the local extra field that can be read
+
+  if buf!=NULL, len is the size of the buffer, the extra header is copied in
+    buf.
+  the return value is the number of bytes copied in buf, or (if <0)
+    the error code
+*/
+extern int ZEXPORT unzGetLocalExtrafield (unzFile file, voidp buf, unsigned len)
+{
+    unz64_s* s;
+    file_in_zip64_read_info_s* pfile_in_zip_read_info;
+    uInt read_now;
+    ZPOS64_T size_to_read;
+
+    if (file==NULL)
+        return UNZ_PARAMERROR;
+    s=(unz64_s*)file;
+    pfile_in_zip_read_info=s->pfile_in_zip_read;
+
+    if (pfile_in_zip_read_info==NULL)
+        return UNZ_PARAMERROR;
+
+    size_to_read = (pfile_in_zip_read_info->size_local_extrafield -
+                pfile_in_zip_read_info->pos_local_extrafield);
+
+    if (buf==NULL)
+        return (int)size_to_read;
+
+    if (len>size_to_read)
+        read_now = (uInt)size_to_read;
+    else
+        read_now = (uInt)len ;
+
+    if (read_now==0)
+        return 0;
+
+    if (ZSEEK64(pfile_in_zip_read_info->z_filefunc,
+              pfile_in_zip_read_info->filestream,
+              pfile_in_zip_read_info->offset_local_extrafield +
+              pfile_in_zip_read_info->pos_local_extrafield,
+              ZLIB_FILEFUNC_SEEK_SET)!=0)
+        return UNZ_ERRNO;
+
+    if (ZREAD64(pfile_in_zip_read_info->z_filefunc,
+              pfile_in_zip_read_info->filestream,
+              buf,read_now)!=read_now)
+        return UNZ_ERRNO;
+
+    return (int)read_now;
+}
+
+/*
+  Close the file in zip opened with unzOpenCurrentFile
+  Return UNZ_CRCERROR if all the file was read but the CRC is not good
+*/
+extern int ZEXPORT unzCloseCurrentFile (unzFile file)
+{
+    int err=UNZ_OK;
+
+    unz64_s* s;
+    file_in_zip64_read_info_s* pfile_in_zip_read_info;
+    if (file==NULL)
+        return UNZ_PARAMERROR;
+    s=(unz64_s*)file;
+    pfile_in_zip_read_info=s->pfile_in_zip_read;
+
+    if (pfile_in_zip_read_info==NULL)
+        return UNZ_PARAMERROR;
+
+
+    if ((pfile_in_zip_read_info->rest_read_uncompressed == 0) &&
+        (!pfile_in_zip_read_info->raw))
+    {
+        if (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait)
+            err=UNZ_CRCERROR;
+    }
+
+
+    TRYFREE(pfile_in_zip_read_info->read_buffer);
+    pfile_in_zip_read_info->read_buffer = NULL;
+    if (pfile_in_zip_read_info->stream_initialised == Z_DEFLATED)
+        inflateEnd(&pfile_in_zip_read_info->stream);
+#ifdef HAVE_BZIP2
+    else if (pfile_in_zip_read_info->stream_initialised == Z_BZIP2ED)
+        BZ2_bzDecompressEnd(&pfile_in_zip_read_info->bstream);
+#endif
+
+
+    pfile_in_zip_read_info->stream_initialised = 0;
+    TRYFREE(pfile_in_zip_read_info);
+
+    s->pfile_in_zip_read=NULL;
+
+    return err;
+}
+
+
+/*
+  Get the global comment string of the ZipFile, in the szComment buffer.
+  uSizeBuf is the size of the szComment buffer.
+  return the number of byte copied or an error code <0
+*/
+extern int ZEXPORT unzGetGlobalComment (unzFile file, char * szComment, uLong uSizeBuf)
+{
+    unz64_s* s;
+    uLong uReadThis ;
+    if (file==NULL)
+        return (int)UNZ_PARAMERROR;
+    s=(unz64_s*)file;
+
+    uReadThis = uSizeBuf;
+    if (uReadThis>s->gi.size_comment)
+        uReadThis = s->gi.size_comment;
+
+    if (ZSEEK64(s->z_filefunc,s->filestream,s->central_pos+22,ZLIB_FILEFUNC_SEEK_SET)!=0)
+        return UNZ_ERRNO;
+
+    if (uReadThis>0)
+    {
+      *szComment='\0';
+      if (ZREAD64(s->z_filefunc,s->filestream,szComment,uReadThis)!=uReadThis)
+        return UNZ_ERRNO;
+    }
+
+    if ((szComment != NULL) && (uSizeBuf > s->gi.size_comment))
+        *(szComment+s->gi.size_comment)='\0';
+    return (int)uReadThis;
+}
+
+/* Additions by RX '2004 */
+extern ZPOS64_T ZEXPORT unzGetOffset64(unzFile file)
+{
+    unz64_s* s;
+
+    if (file==NULL)
+          return 0; //UNZ_PARAMERROR;
+    s=(unz64_s*)file;
+    if (!s->current_file_ok)
+      return 0;
+    if (s->gi.number_entry != 0 && s->gi.number_entry != 0xffff)
+      if (s->num_file==s->gi.number_entry)
+         return 0;
+    return s->pos_in_central_dir;
+}
+
+extern uLong ZEXPORT unzGetOffset (unzFile file)
+{
+    ZPOS64_T offset64;
+
+    if (file==NULL)
+          return 0; //UNZ_PARAMERROR;
+    offset64 = unzGetOffset64(file);
+    return (uLong)offset64;
+}
+
+extern int ZEXPORT unzSetOffset64(unzFile file, ZPOS64_T pos)
+{
+    unz64_s* s;
+    int err;
+
+    if (file==NULL)
+        return UNZ_PARAMERROR;
+    s=(unz64_s*)file;
+
+    s->pos_in_central_dir = pos;
+    s->num_file = s->gi.number_entry;      /* hack */
+    err = unz64local_GetCurrentFileInfoInternal(file,&s->cur_file_info,
+                                              &s->cur_file_info_internal,
+                                              NULL,0,NULL,0,NULL,0);
+    s->current_file_ok = (err == UNZ_OK);
+    return err;
+}
+
+extern int ZEXPORT unzSetOffset (unzFile file, uLong pos)
+{
+    return unzSetOffset64(file,pos);
+}
diff --git a/compat/zlib/contrib/minizip/unzip.h b/compat/zlib/contrib/minizip/unzip.h
new file mode 100644
index 0000000..2104e39
--- /dev/null
+++ b/compat/zlib/contrib/minizip/unzip.h
@@ -0,0 +1,437 @@
+/* unzip.h -- IO for uncompress .zip files using zlib
+   Version 1.1, February 14h, 2010
+   part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
+
+         Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
+
+         Modifications of Unzip for Zip64
+         Copyright (C) 2007-2008 Even Rouault
+
+         Modifications for Zip64 support on both zip and unzip
+         Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
+
+         For more info read MiniZip_info.txt
+
+         ---------------------------------------------------------------------------------
+
+        Condition of use and distribution are the same than zlib :
+
+  This software is provided 'as-is', without any express or implied
+  warranty.  In no event will the authors be held liable for any damages
+  arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any purpose,
+  including commercial applications, and to alter it and redistribute it
+  freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+
+  ---------------------------------------------------------------------------------
+
+        Changes
+
+        See header of unzip64.c
+
+*/
+
+#ifndef _unz64_H
+#define _unz64_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _ZLIB_H
+#include "zlib.h"
+#endif
+
+#ifndef  _ZLIBIOAPI_H
+#include "ioapi.h"
+#endif
+
+#ifdef HAVE_BZIP2
+#include "bzlib.h"
+#endif
+
+#define Z_BZIP2ED 12
+
+#if defined(STRICTUNZIP) || defined(STRICTZIPUNZIP)
+/* like the STRICT of WIN32, we define a pointer that cannot be converted
+    from (void*) without cast */
+typedef struct TagunzFile__ { int unused; } unzFile__;
+typedef unzFile__ *unzFile;
+#else
+typedef voidp unzFile;
+#endif
+
+
+#define UNZ_OK                          (0)
+#define UNZ_END_OF_LIST_OF_FILE         (-100)
+#define UNZ_ERRNO                       (Z_ERRNO)
+#define UNZ_EOF                         (0)
+#define UNZ_PARAMERROR                  (-102)
+#define UNZ_BADZIPFILE                  (-103)
+#define UNZ_INTERNALERROR               (-104)
+#define UNZ_CRCERROR                    (-105)
+
+/* tm_unz contain date/time info */
+typedef struct tm_unz_s
+{
+    uInt tm_sec;            /* seconds after the minute - [0,59] */
+    uInt tm_min;            /* minutes after the hour - [0,59] */
+    uInt tm_hour;           /* hours since midnight - [0,23] */
+    uInt tm_mday;           /* day of the month - [1,31] */
+    uInt tm_mon;            /* months since January - [0,11] */
+    uInt tm_year;           /* years - [1980..2044] */
+} tm_unz;
+
+/* unz_global_info structure contain global data about the ZIPfile
+   These data comes from the end of central dir */
+typedef struct unz_global_info64_s
+{
+    ZPOS64_T number_entry;         /* total number of entries in
+                                     the central dir on this disk */
+    uLong size_comment;         /* size of the global comment of the zipfile */
+} unz_global_info64;
+
+typedef struct unz_global_info_s
+{
+    uLong number_entry;         /* total number of entries in
+                                     the central dir on this disk */
+    uLong size_comment;         /* size of the global comment of the zipfile */
+} unz_global_info;
+
+/* unz_file_info contain information about a file in the zipfile */
+typedef struct unz_file_info64_s
+{
+    uLong version;              /* version made by                 2 bytes */
+    uLong version_needed;       /* version needed to extract       2 bytes */
+    uLong flag;                 /* general purpose bit flag        2 bytes */
+    uLong compression_method;   /* compression method              2 bytes */
+    uLong dosDate;              /* last mod file date in Dos fmt   4 bytes */
+    uLong crc;                  /* crc-32                          4 bytes */
+    ZPOS64_T compressed_size;   /* compressed size                 8 bytes */
+    ZPOS64_T uncompressed_size; /* uncompressed size               8 bytes */
+    uLong size_filename;        /* filename length                 2 bytes */
+    uLong size_file_extra;      /* extra field length              2 bytes */
+    uLong size_file_comment;    /* file comment length             2 bytes */
+
+    uLong disk_num_start;       /* disk number start               2 bytes */
+    uLong internal_fa;          /* internal file attributes        2 bytes */
+    uLong external_fa;          /* external file attributes        4 bytes */
+
+    tm_unz tmu_date;
+} unz_file_info64;
+
+typedef struct unz_file_info_s
+{
+    uLong version;              /* version made by                 2 bytes */
+    uLong version_needed;       /* version needed to extract       2 bytes */
+    uLong flag;                 /* general purpose bit flag        2 bytes */
+    uLong compression_method;   /* compression method              2 bytes */
+    uLong dosDate;              /* last mod file date in Dos fmt   4 bytes */
+    uLong crc;                  /* crc-32                          4 bytes */
+    uLong compressed_size;      /* compressed size                 4 bytes */
+    uLong uncompressed_size;    /* uncompressed size               4 bytes */
+    uLong size_filename;        /* filename length                 2 bytes */
+    uLong size_file_extra;      /* extra field length              2 bytes */
+    uLong size_file_comment;    /* file comment length             2 bytes */
+
+    uLong disk_num_start;       /* disk number start               2 bytes */
+    uLong internal_fa;          /* internal file attributes        2 bytes */
+    uLong external_fa;          /* external file attributes        4 bytes */
+
+    tm_unz tmu_date;
+} unz_file_info;
+
+extern int ZEXPORT unzStringFileNameCompare OF ((const char* fileName1,
+                                                 const char* fileName2,
+                                                 int iCaseSensitivity));
+/*
+   Compare two filename (fileName1,fileName2).
+   If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
+   If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi
+                                or strcasecmp)
+   If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
+    (like 1 on Unix, 2 on Windows)
+*/
+
+
+extern unzFile ZEXPORT unzOpen OF((const char *path));
+extern unzFile ZEXPORT unzOpen64 OF((const void *path));
+/*
+  Open a Zip file. path contain the full pathname (by example,
+     on a Windows XP computer "c:\\zlib\\zlib113.zip" or on an Unix computer
+     "zlib/zlib113.zip".
+     If the zipfile cannot be opened (file don't exist or in not valid), the
+       return value is NULL.
+     Else, the return value is a unzFile Handle, usable with other function
+       of this unzip package.
+     the "64" function take a const void* pointer, because the path is just the
+       value passed to the open64_file_func callback.
+     Under Windows, if UNICODE is defined, using fill_fopen64_filefunc, the path
+       is a pointer to a wide unicode string (LPCTSTR is LPCWSTR), so const char*
+       does not describe the reality
+*/
+
+
+extern unzFile ZEXPORT unzOpen2 OF((const char *path,
+                                    zlib_filefunc_def* pzlib_filefunc_def));
+/*
+   Open a Zip file, like unzOpen, but provide a set of file low level API
+      for read/write the zip file (see ioapi.h)
+*/
+
+extern unzFile ZEXPORT unzOpen2_64 OF((const void *path,
+                                    zlib_filefunc64_def* pzlib_filefunc_def));
+/*
+   Open a Zip file, like unz64Open, but provide a set of file low level API
+      for read/write the zip file (see ioapi.h)
+*/
+
+extern int ZEXPORT unzClose OF((unzFile file));
+/*
+  Close a ZipFile opened with unzOpen.
+  If there is files inside the .Zip opened with unzOpenCurrentFile (see later),
+    these files MUST be closed with unzCloseCurrentFile before call unzClose.
+  return UNZ_OK if there is no problem. */
+
+extern int ZEXPORT unzGetGlobalInfo OF((unzFile file,
+                                        unz_global_info *pglobal_info));
+
+extern int ZEXPORT unzGetGlobalInfo64 OF((unzFile file,
+                                        unz_global_info64 *pglobal_info));
+/*
+  Write info about the ZipFile in the *pglobal_info structure.
+  No preparation of the structure is needed
+  return UNZ_OK if there is no problem. */
+
+
+extern int ZEXPORT unzGetGlobalComment OF((unzFile file,
+                                           char *szComment,
+                                           uLong uSizeBuf));
+/*
+  Get the global comment string of the ZipFile, in the szComment buffer.
+  uSizeBuf is the size of the szComment buffer.
+  return the number of byte copied or an error code <0
+*/
+
+
+/***************************************************************************/
+/* Unzip package allow you browse the directory of the zipfile */
+
+extern int ZEXPORT unzGoToFirstFile OF((unzFile file));
+/*
+  Set the current file of the zipfile to the first file.
+  return UNZ_OK if there is no problem
+*/
+
+extern int ZEXPORT unzGoToNextFile OF((unzFile file));
+/*
+  Set the current file of the zipfile to the next file.
+  return UNZ_OK if there is no problem
+  return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
+*/
+
+extern int ZEXPORT unzLocateFile OF((unzFile file,
+                     const char *szFileName,
+                     int iCaseSensitivity));
+/*
+  Try locate the file szFileName in the zipfile.
+  For the iCaseSensitivity signification, see unzStringFileNameCompare
+
+  return value :
+  UNZ_OK if the file is found. It becomes the current file.
+  UNZ_END_OF_LIST_OF_FILE if the file is not found
+*/
+
+
+/* ****************************************** */
+/* Ryan supplied functions */
+/* unz_file_info contain information about a file in the zipfile */
+typedef struct unz_file_pos_s
+{
+    uLong pos_in_zip_directory;   /* offset in zip file directory */
+    uLong num_of_file;            /* # of file */
+} unz_file_pos;
+
+extern int ZEXPORT unzGetFilePos(
+    unzFile file,
+    unz_file_pos* file_pos);
+
+extern int ZEXPORT unzGoToFilePos(
+    unzFile file,
+    unz_file_pos* file_pos);
+
+typedef struct unz64_file_pos_s
+{
+    ZPOS64_T pos_in_zip_directory;   /* offset in zip file directory */
+    ZPOS64_T num_of_file;            /* # of file */
+} unz64_file_pos;
+
+extern int ZEXPORT unzGetFilePos64(
+    unzFile file,
+    unz64_file_pos* file_pos);
+
+extern int ZEXPORT unzGoToFilePos64(
+    unzFile file,
+    const unz64_file_pos* file_pos);
+
+/* ****************************************** */
+
+extern int ZEXPORT unzGetCurrentFileInfo64 OF((unzFile file,
+                         unz_file_info64 *pfile_info,
+                         char *szFileName,
+                         uLong fileNameBufferSize,
+                         void *extraField,
+                         uLong extraFieldBufferSize,
+                         char *szComment,
+                         uLong commentBufferSize));
+
+extern int ZEXPORT unzGetCurrentFileInfo OF((unzFile file,
+                         unz_file_info *pfile_info,
+                         char *szFileName,
+                         uLong fileNameBufferSize,
+                         void *extraField,
+                         uLong extraFieldBufferSize,
+                         char *szComment,
+                         uLong commentBufferSize));
+/*
+  Get Info about the current file
+  if pfile_info!=NULL, the *pfile_info structure will contain somes info about
+        the current file
+  if szFileName!=NULL, the filemane string will be copied in szFileName
+            (fileNameBufferSize is the size of the buffer)
+  if extraField!=NULL, the extra field information will be copied in extraField
+            (extraFieldBufferSize is the size of the buffer).
+            This is the Central-header version of the extra field
+  if szComment!=NULL, the comment string of the file will be copied in szComment
+            (commentBufferSize is the size of the buffer)
+*/
+
+
+/** Addition for GDAL : START */
+
+extern ZPOS64_T ZEXPORT unzGetCurrentFileZStreamPos64 OF((unzFile file));
+
+/** Addition for GDAL : END */
+
+
+/***************************************************************************/
+/* for reading the content of the current zipfile, you can open it, read data
+   from it, and close it (you can close it before reading all the file)
+   */
+
+extern int ZEXPORT unzOpenCurrentFile OF((unzFile file));
+/*
+  Open for reading data the current file in the zipfile.
+  If there is no error, the return value is UNZ_OK.
+*/
+
+extern int ZEXPORT unzOpenCurrentFilePassword OF((unzFile file,
+                                                  const char* password));
+/*
+  Open for reading data the current file in the zipfile.
+  password is a crypting password
+  If there is no error, the return value is UNZ_OK.
+*/
+
+extern int ZEXPORT unzOpenCurrentFile2 OF((unzFile file,
+                                           int* method,
+                                           int* level,
+                                           int raw));
+/*
+  Same than unzOpenCurrentFile, but open for read raw the file (not uncompress)
+    if raw==1
+  *method will receive method of compression, *level will receive level of
+     compression
+  note : you can set level parameter as NULL (if you did not want known level,
+         but you CANNOT set method parameter as NULL
+*/
+
+extern int ZEXPORT unzOpenCurrentFile3 OF((unzFile file,
+                                           int* method,
+                                           int* level,
+                                           int raw,
+                                           const char* password));
+/*
+  Same than unzOpenCurrentFile, but open for read raw the file (not uncompress)
+    if raw==1
+  *method will receive method of compression, *level will receive level of
+     compression
+  note : you can set level parameter as NULL (if you did not want known level,
+         but you CANNOT set method parameter as NULL
+*/
+
+
+extern int ZEXPORT unzCloseCurrentFile OF((unzFile file));
+/*
+  Close the file in zip opened with unzOpenCurrentFile
+  Return UNZ_CRCERROR if all the file was read but the CRC is not good
+*/
+
+extern int ZEXPORT unzReadCurrentFile OF((unzFile file,
+                      voidp buf,
+                      unsigned len));
+/*
+  Read bytes from the current file (opened by unzOpenCurrentFile)
+  buf contain buffer where data must be copied
+  len the size of buf.
+
+  return the number of byte copied if somes bytes are copied
+  return 0 if the end of file was reached
+  return <0 with error code if there is an error
+    (UNZ_ERRNO for IO error, or zLib error for uncompress error)
+*/
+
+extern z_off_t ZEXPORT unztell OF((unzFile file));
+
+extern ZPOS64_T ZEXPORT unztell64 OF((unzFile file));
+/*
+  Give the current position in uncompressed data
+*/
+
+extern int ZEXPORT unzeof OF((unzFile file));
+/*
+  return 1 if the end of file was reached, 0 elsewhere
+*/
+
+extern int ZEXPORT unzGetLocalExtrafield OF((unzFile file,
+                                             voidp buf,
+                                             unsigned len));
+/*
+  Read extra field from the current file (opened by unzOpenCurrentFile)
+  This is the local-header version of the extra field (sometimes, there is
+    more info in the local-header version than in the central-header)
+
+  if buf==NULL, it return the size of the local extra field
+
+  if buf!=NULL, len is the size of the buffer, the extra header is copied in
+    buf.
+  the return value is the number of bytes copied in buf, or (if <0)
+    the error code
+*/
+
+/***************************************************************************/
+
+/* Get the current file offset */
+extern ZPOS64_T ZEXPORT unzGetOffset64 (unzFile file);
+extern uLong ZEXPORT unzGetOffset (unzFile file);
+
+/* Set the current file offset */
+extern int ZEXPORT unzSetOffset64 (unzFile file, ZPOS64_T pos);
+extern int ZEXPORT unzSetOffset (unzFile file, uLong pos);
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _unz64_H */
diff --git a/compat/zlib/contrib/minizip/zip.c b/compat/zlib/contrib/minizip/zip.c
new file mode 100644
index 0000000..ea54853
--- /dev/null
+++ b/compat/zlib/contrib/minizip/zip.c
@@ -0,0 +1,2007 @@
+/* zip.c -- IO on .zip files using zlib
+   Version 1.1, February 14h, 2010
+   part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
+
+         Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
+
+         Modifications for Zip64 support
+         Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
+
+         For more info read MiniZip_info.txt
+
+         Changes
+   Oct-2009 - Mathias Svensson - Remove old C style function prototypes
+   Oct-2009 - Mathias Svensson - Added Zip64 Support when creating new file archives
+   Oct-2009 - Mathias Svensson - Did some code cleanup and refactoring to get better overview of some functions.
+   Oct-2009 - Mathias Svensson - Added zipRemoveExtraInfoBlock to strip extra field data from its ZIP64 data
+                                 It is used when recreting zip archive with RAW when deleting items from a zip.
+                                 ZIP64 data is automaticly added to items that needs it, and existing ZIP64 data need to be removed.
+   Oct-2009 - Mathias Svensson - Added support for BZIP2 as compression mode (bzip2 lib is required)
+   Jan-2010 - back to unzip and minizip 1.0 name scheme, with compatibility layer
+
+*/
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include "zlib.h"
+#include "zip.h"
+
+#ifdef STDC
+#  include <stddef.h>
+#  include <string.h>
+#  include <stdlib.h>
+#endif
+#ifdef NO_ERRNO_H
+    extern int errno;
+#else
+#   include <errno.h>
+#endif
+
+
+#ifndef local
+#  define local static
+#endif
+/* compile with -Dlocal if your debugger can't find static symbols */
+
+#ifndef VERSIONMADEBY
+# define VERSIONMADEBY   (0x0) /* platform depedent */
+#endif
+
+#ifndef Z_BUFSIZE
+#define Z_BUFSIZE (64*1024) //(16384)
+#endif
+
+#ifndef Z_MAXFILENAMEINZIP
+#define Z_MAXFILENAMEINZIP (256)
+#endif
+
+#ifndef ALLOC
+# define ALLOC(size) (malloc(size))
+#endif
+#ifndef TRYFREE
+# define TRYFREE(p) {if (p) free(p);}
+#endif
+
+/*
+#define SIZECENTRALDIRITEM (0x2e)
+#define SIZEZIPLOCALHEADER (0x1e)
+*/
+
+/* I've found an old Unix (a SunOS 4.1.3_U1) without all SEEK_* defined.... */
+
+
+// NOT sure that this work on ALL platform
+#define MAKEULONG64(a, b) ((ZPOS64_T)(((unsigned long)(a)) | ((ZPOS64_T)((unsigned long)(b))) << 32))
+
+#ifndef SEEK_CUR
+#define SEEK_CUR    1
+#endif
+
+#ifndef SEEK_END
+#define SEEK_END    2
+#endif
+
+#ifndef SEEK_SET
+#define SEEK_SET    0
+#endif
+
+#ifndef DEF_MEM_LEVEL
+#if MAX_MEM_LEVEL >= 8
+#  define DEF_MEM_LEVEL 8
+#else
+#  define DEF_MEM_LEVEL  MAX_MEM_LEVEL
+#endif
+#endif
+const char zip_copyright[] =" zip 1.01 Copyright 1998-2004 Gilles Vollant - http://www.winimage.com/zLibDll";
+
+
+#define SIZEDATA_INDATABLOCK (4096-(4*4))
+
+#define LOCALHEADERMAGIC    (0x04034b50)
+#define CENTRALHEADERMAGIC  (0x02014b50)
+#define ENDHEADERMAGIC      (0x06054b50)
+#define ZIP64ENDHEADERMAGIC      (0x6064b50)
+#define ZIP64ENDLOCHEADERMAGIC   (0x7064b50)
+
+#define FLAG_LOCALHEADER_OFFSET (0x06)
+#define CRC_LOCALHEADER_OFFSET  (0x0e)
+
+#define SIZECENTRALHEADER (0x2e) /* 46 */
+
+typedef struct linkedlist_datablock_internal_s
+{
+  struct linkedlist_datablock_internal_s* next_datablock;
+  uLong  avail_in_this_block;
+  uLong  filled_in_this_block;
+  uLong  unused; /* for future use and alignement */
+  unsigned char data[SIZEDATA_INDATABLOCK];
+} linkedlist_datablock_internal;
+
+typedef struct linkedlist_data_s
+{
+    linkedlist_datablock_internal* first_block;
+    linkedlist_datablock_internal* last_block;
+} linkedlist_data;
+
+
+typedef struct
+{
+    z_stream stream;            /* zLib stream structure for inflate */
+#ifdef HAVE_BZIP2
+    bz_stream bstream;          /* bzLib stream structure for bziped */
+#endif
+
+    int  stream_initialised;    /* 1 is stream is initialised */
+    uInt pos_in_buffered_data;  /* last written byte in buffered_data */
+
+    ZPOS64_T pos_local_header;     /* offset of the local header of the file
+                                     currenty writing */
+    char* central_header;       /* central header data for the current file */
+    uLong size_centralExtra;
+    uLong size_centralheader;   /* size of the central header for cur file */
+    uLong size_centralExtraFree; /* Extra bytes allocated to the centralheader but that are not used */
+    uLong flag;                 /* flag of the file currently writing */
+
+    int  method;                /* compression method of file currenty wr.*/
+    int  raw;                   /* 1 for directly writing raw data */
+    Byte buffered_data[Z_BUFSIZE];/* buffer contain compressed data to be writ*/
+    uLong dosDate;
+    uLong crc32;
+    int  encrypt;
+    int  zip64;               /* Add ZIP64 extened information in the extra field */
+    ZPOS64_T pos_zip64extrainfo;
+    ZPOS64_T totalCompressedData;
+    ZPOS64_T totalUncompressedData;
+#ifndef NOCRYPT
+    unsigned long keys[3];     /* keys defining the pseudo-random sequence */
+    const z_crc_t* pcrc_32_tab;
+    int crypt_header_size;
+#endif
+} curfile64_info;
+
+typedef struct
+{
+    zlib_filefunc64_32_def z_filefunc;
+    voidpf filestream;        /* io structore of the zipfile */
+    linkedlist_data central_dir;/* datablock with central dir in construction*/
+    int  in_opened_file_inzip;  /* 1 if a file in the zip is currently writ.*/
+    curfile64_info ci;            /* info on the file curretly writing */
+
+    ZPOS64_T begin_pos;            /* position of the beginning of the zipfile */
+    ZPOS64_T add_position_when_writting_offset;
+    ZPOS64_T number_entry;
+
+#ifndef NO_ADDFILEINEXISTINGZIP
+    char *globalcomment;
+#endif
+
+} zip64_internal;
+
+
+#ifndef NOCRYPT
+#define INCLUDECRYPTINGCODE_IFCRYPTALLOWED
+#include "crypt.h"
+#endif
+
+local linkedlist_datablock_internal* allocate_new_datablock()
+{
+    linkedlist_datablock_internal* ldi;
+    ldi = (linkedlist_datablock_internal*)
+                 ALLOC(sizeof(linkedlist_datablock_internal));
+    if (ldi!=NULL)
+    {
+        ldi->next_datablock = NULL ;
+        ldi->filled_in_this_block = 0 ;
+        ldi->avail_in_this_block = SIZEDATA_INDATABLOCK ;
+    }
+    return ldi;
+}
+
+local void free_datablock(linkedlist_datablock_internal* ldi)
+{
+    while (ldi!=NULL)
+    {
+        linkedlist_datablock_internal* ldinext = ldi->next_datablock;
+        TRYFREE(ldi);
+        ldi = ldinext;
+    }
+}
+
+local void init_linkedlist(linkedlist_data* ll)
+{
+    ll->first_block = ll->last_block = NULL;
+}
+
+local void free_linkedlist(linkedlist_data* ll)
+{
+    free_datablock(ll->first_block);
+    ll->first_block = ll->last_block = NULL;
+}
+
+
+local int add_data_in_datablock(linkedlist_data* ll, const void* buf, uLong len)
+{
+    linkedlist_datablock_internal* ldi;
+    const unsigned char* from_copy;
+
+    if (ll==NULL)
+        return ZIP_INTERNALERROR;
+
+    if (ll->last_block == NULL)
+    {
+        ll->first_block = ll->last_block = allocate_new_datablock();
+        if (ll->first_block == NULL)
+            return ZIP_INTERNALERROR;
+    }
+
+    ldi = ll->last_block;
+    from_copy = (unsigned char*)buf;
+
+    while (len>0)
+    {
+        uInt copy_this;
+        uInt i;
+        unsigned char* to_copy;
+
+        if (ldi->avail_in_this_block==0)
+        {
+            ldi->next_datablock = allocate_new_datablock();
+            if (ldi->next_datablock == NULL)
+                return ZIP_INTERNALERROR;
+            ldi = ldi->next_datablock ;
+            ll->last_block = ldi;
+        }
+
+        if (ldi->avail_in_this_block < len)
+            copy_this = (uInt)ldi->avail_in_this_block;
+        else
+            copy_this = (uInt)len;
+
+        to_copy = &(ldi->data[ldi->filled_in_this_block]);
+
+        for (i=0;i<copy_this;i++)
+            *(to_copy+i)=*(from_copy+i);
+
+        ldi->filled_in_this_block += copy_this;
+        ldi->avail_in_this_block -= copy_this;
+        from_copy += copy_this ;
+        len -= copy_this;
+    }
+    return ZIP_OK;
+}
+
+
+
+/****************************************************************************/
+
+#ifndef NO_ADDFILEINEXISTINGZIP
+/* ===========================================================================
+   Inputs a long in LSB order to the given file
+   nbByte == 1, 2 ,4 or 8 (byte, short or long, ZPOS64_T)
+*/
+
+local int zip64local_putValue OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T x, int nbByte));
+local int zip64local_putValue (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T x, int nbByte)
+{
+    unsigned char buf[8];
+    int n;
+    for (n = 0; n < nbByte; n++)
+    {
+        buf[n] = (unsigned char)(x & 0xff);
+        x >>= 8;
+    }
+    if (x != 0)
+      {     /* data overflow - hack for ZIP64 (X Roche) */
+      for (n = 0; n < nbByte; n++)
+        {
+          buf[n] = 0xff;
+        }
+      }
+
+    if (ZWRITE64(*pzlib_filefunc_def,filestream,buf,nbByte)!=(uLong)nbByte)
+        return ZIP_ERRNO;
+    else
+        return ZIP_OK;
+}
+
+local void zip64local_putValue_inmemory OF((void* dest, ZPOS64_T x, int nbByte));
+local void zip64local_putValue_inmemory (void* dest, ZPOS64_T x, int nbByte)
+{
+    unsigned char* buf=(unsigned char*)dest;
+    int n;
+    for (n = 0; n < nbByte; n++) {
+        buf[n] = (unsigned char)(x & 0xff);
+        x >>= 8;
+    }
+
+    if (x != 0)
+    {     /* data overflow - hack for ZIP64 */
+       for (n = 0; n < nbByte; n++)
+       {
+          buf[n] = 0xff;
+       }
+    }
+}
+
+/****************************************************************************/
+
+
+local uLong zip64local_TmzDateToDosDate(const tm_zip* ptm)
+{
+    uLong year = (uLong)ptm->tm_year;
+    if (year>=1980)
+        year-=1980;
+    else if (year>=80)
+        year-=80;
+    return
+      (uLong) (((ptm->tm_mday) + (32 * (ptm->tm_mon+1)) + (512 * year)) << 16) |
+        ((ptm->tm_sec/2) + (32* ptm->tm_min) + (2048 * (uLong)ptm->tm_hour));
+}
+
+
+/****************************************************************************/
+
+local int zip64local_getByte OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, int *pi));
+
+local int zip64local_getByte(const zlib_filefunc64_32_def* pzlib_filefunc_def,voidpf filestream,int* pi)
+{
+    unsigned char c;
+    int err = (int)ZREAD64(*pzlib_filefunc_def,filestream,&c,1);
+    if (err==1)
+    {
+        *pi = (int)c;
+        return ZIP_OK;
+    }
+    else
+    {
+        if (ZERROR64(*pzlib_filefunc_def,filestream))
+            return ZIP_ERRNO;
+        else
+            return ZIP_EOF;
+    }
+}
+
+
+/* ===========================================================================
+   Reads a long in LSB order from the given gz_stream. Sets
+*/
+local int zip64local_getShort OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong *pX));
+
+local int zip64local_getShort (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong* pX)
+{
+    uLong x ;
+    int i = 0;
+    int err;
+
+    err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
+    x = (uLong)i;
+
+    if (err==ZIP_OK)
+        err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
+    x += ((uLong)i)<<8;
+
+    if (err==ZIP_OK)
+        *pX = x;
+    else
+        *pX = 0;
+    return err;
+}
+
+local int zip64local_getLong OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong *pX));
+
+local int zip64local_getLong (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, uLong* pX)
+{
+    uLong x ;
+    int i = 0;
+    int err;
+
+    err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
+    x = (uLong)i;
+
+    if (err==ZIP_OK)
+        err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
+    x += ((uLong)i)<<8;
+
+    if (err==ZIP_OK)
+        err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
+    x += ((uLong)i)<<16;
+
+    if (err==ZIP_OK)
+        err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
+    x += ((uLong)i)<<24;
+
+    if (err==ZIP_OK)
+        *pX = x;
+    else
+        *pX = 0;
+    return err;
+}
+
+local int zip64local_getLong64 OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T *pX));
+
+
+local int zip64local_getLong64 (const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream, ZPOS64_T *pX)
+{
+  ZPOS64_T x;
+  int i = 0;
+  int err;
+
+  err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
+  x = (ZPOS64_T)i;
+
+  if (err==ZIP_OK)
+    err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
+  x += ((ZPOS64_T)i)<<8;
+
+  if (err==ZIP_OK)
+    err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
+  x += ((ZPOS64_T)i)<<16;
+
+  if (err==ZIP_OK)
+    err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
+  x += ((ZPOS64_T)i)<<24;
+
+  if (err==ZIP_OK)
+    err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
+  x += ((ZPOS64_T)i)<<32;
+
+  if (err==ZIP_OK)
+    err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
+  x += ((ZPOS64_T)i)<<40;
+
+  if (err==ZIP_OK)
+    err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
+  x += ((ZPOS64_T)i)<<48;
+
+  if (err==ZIP_OK)
+    err = zip64local_getByte(pzlib_filefunc_def,filestream,&i);
+  x += ((ZPOS64_T)i)<<56;
+
+  if (err==ZIP_OK)
+    *pX = x;
+  else
+    *pX = 0;
+
+  return err;
+}
+
+#ifndef BUFREADCOMMENT
+#define BUFREADCOMMENT (0x400)
+#endif
+/*
+  Locate the Central directory of a zipfile (at the end, just before
+    the global comment)
+*/
+local ZPOS64_T zip64local_SearchCentralDir OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream));
+
+local ZPOS64_T zip64local_SearchCentralDir(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream)
+{
+  unsigned char* buf;
+  ZPOS64_T uSizeFile;
+  ZPOS64_T uBackRead;
+  ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */
+  ZPOS64_T uPosFound=0;
+
+  if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
+    return 0;
+
+
+  uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream);
+
+  if (uMaxBack>uSizeFile)
+    uMaxBack = uSizeFile;
+
+  buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
+  if (buf==NULL)
+    return 0;
+
+  uBackRead = 4;
+  while (uBackRead<uMaxBack)
+  {
+    uLong uReadSize;
+    ZPOS64_T uReadPos ;
+    int i;
+    if (uBackRead+BUFREADCOMMENT>uMaxBack)
+      uBackRead = uMaxBack;
+    else
+      uBackRead+=BUFREADCOMMENT;
+    uReadPos = uSizeFile-uBackRead ;
+
+    uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
+      (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos);
+    if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)
+      break;
+
+    if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
+      break;
+
+    for (i=(int)uReadSize-3; (i--)>0;)
+      if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) &&
+        ((*(buf+i+2))==0x05) && ((*(buf+i+3))==0x06))
+      {
+        uPosFound = uReadPos+i;
+        break;
+      }
+
+      if (uPosFound!=0)
+        break;
+  }
+  TRYFREE(buf);
+  return uPosFound;
+}
+
+/*
+Locate the End of Zip64 Central directory locator and from there find the CD of a zipfile (at the end, just before
+the global comment)
+*/
+local ZPOS64_T zip64local_SearchCentralDir64 OF((const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream));
+
+local ZPOS64_T zip64local_SearchCentralDir64(const zlib_filefunc64_32_def* pzlib_filefunc_def, voidpf filestream)
+{
+  unsigned char* buf;
+  ZPOS64_T uSizeFile;
+  ZPOS64_T uBackRead;
+  ZPOS64_T uMaxBack=0xffff; /* maximum size of global comment */
+  ZPOS64_T uPosFound=0;
+  uLong uL;
+  ZPOS64_T relativeOffset;
+
+  if (ZSEEK64(*pzlib_filefunc_def,filestream,0,ZLIB_FILEFUNC_SEEK_END) != 0)
+    return 0;
+
+  uSizeFile = ZTELL64(*pzlib_filefunc_def,filestream);
+
+  if (uMaxBack>uSizeFile)
+    uMaxBack = uSizeFile;
+
+  buf = (unsigned char*)ALLOC(BUFREADCOMMENT+4);
+  if (buf==NULL)
+    return 0;
+
+  uBackRead = 4;
+  while (uBackRead<uMaxBack)
+  {
+    uLong uReadSize;
+    ZPOS64_T uReadPos;
+    int i;
+    if (uBackRead+BUFREADCOMMENT>uMaxBack)
+      uBackRead = uMaxBack;
+    else
+      uBackRead+=BUFREADCOMMENT;
+    uReadPos = uSizeFile-uBackRead ;
+
+    uReadSize = ((BUFREADCOMMENT+4) < (uSizeFile-uReadPos)) ?
+      (BUFREADCOMMENT+4) : (uLong)(uSizeFile-uReadPos);
+    if (ZSEEK64(*pzlib_filefunc_def,filestream,uReadPos,ZLIB_FILEFUNC_SEEK_SET)!=0)
+      break;
+
+    if (ZREAD64(*pzlib_filefunc_def,filestream,buf,uReadSize)!=uReadSize)
+      break;
+
+    for (i=(int)uReadSize-3; (i--)>0;)
+    {
+      // Signature "0x07064b50" Zip64 end of central directory locater
+      if (((*(buf+i))==0x50) && ((*(buf+i+1))==0x4b) && ((*(buf+i+2))==0x06) && ((*(buf+i+3))==0x07))
+      {
+        uPosFound = uReadPos+i;
+        break;
+      }
+    }
+
+      if (uPosFound!=0)
+        break;
+  }
+
+  TRYFREE(buf);
+  if (uPosFound == 0)
+    return 0;
+
+  /* Zip64 end of central directory locator */
+  if (ZSEEK64(*pzlib_filefunc_def,filestream, uPosFound,ZLIB_FILEFUNC_SEEK_SET)!=0)
+    return 0;
+
+  /* the signature, already checked */
+  if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK)
+    return 0;
+
+  /* number of the disk with the start of the zip64 end of  central directory */
+  if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK)
+    return 0;
+  if (uL != 0)
+    return 0;
+
+  /* relative offset of the zip64 end of central directory record */
+  if (zip64local_getLong64(pzlib_filefunc_def,filestream,&relativeOffset)!=ZIP_OK)
+    return 0;
+
+  /* total number of disks */
+  if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK)
+    return 0;
+  if (uL != 1)
+    return 0;
+
+  /* Goto Zip64 end of central directory record */
+  if (ZSEEK64(*pzlib_filefunc_def,filestream, relativeOffset,ZLIB_FILEFUNC_SEEK_SET)!=0)
+    return 0;
+
+  /* the signature */
+  if (zip64local_getLong(pzlib_filefunc_def,filestream,&uL)!=ZIP_OK)
+    return 0;
+
+  if (uL != 0x06064b50) // signature of 'Zip64 end of central directory'
+    return 0;
+
+  return relativeOffset;
+}
+
+int LoadCentralDirectoryRecord(zip64_internal* pziinit)
+{
+  int err=ZIP_OK;
+  ZPOS64_T byte_before_the_zipfile;/* byte before the zipfile, (>0 for sfx)*/
+
+  ZPOS64_T size_central_dir;     /* size of the central directory  */
+  ZPOS64_T offset_central_dir;   /* offset of start of central directory */
+  ZPOS64_T central_pos;
+  uLong uL;
+
+  uLong number_disk;          /* number of the current dist, used for
+                              spaning ZIP, unsupported, always 0*/
+  uLong number_disk_with_CD;  /* number the the disk with central dir, used
+                              for spaning ZIP, unsupported, always 0*/
+  ZPOS64_T number_entry;
+  ZPOS64_T number_entry_CD;      /* total number of entries in
+                                the central dir
+                                (same than number_entry on nospan) */
+  uLong VersionMadeBy;
+  uLong VersionNeeded;
+  uLong size_comment;
+
+  int hasZIP64Record = 0;
+
+  // check first if we find a ZIP64 record
+  central_pos = zip64local_SearchCentralDir64(&pziinit->z_filefunc,pziinit->filestream);
+  if(central_pos > 0)
+  {
+    hasZIP64Record = 1;
+  }
+  else if(central_pos == 0)
+  {
+    central_pos = zip64local_SearchCentralDir(&pziinit->z_filefunc,pziinit->filestream);
+  }
+
+/* disable to allow appending to empty ZIP archive
+        if (central_pos==0)
+            err=ZIP_ERRNO;
+*/
+
+  if(hasZIP64Record)
+  {
+    ZPOS64_T sizeEndOfCentralDirectory;
+    if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, central_pos, ZLIB_FILEFUNC_SEEK_SET) != 0)
+      err=ZIP_ERRNO;
+
+    /* the signature, already checked */
+    if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&uL)!=ZIP_OK)
+      err=ZIP_ERRNO;
+
+    /* size of zip64 end of central directory record */
+    if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream, &sizeEndOfCentralDirectory)!=ZIP_OK)
+      err=ZIP_ERRNO;
+
+    /* version made by */
+    if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &VersionMadeBy)!=ZIP_OK)
+      err=ZIP_ERRNO;
+
+    /* version needed to extract */
+    if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &VersionNeeded)!=ZIP_OK)
+      err=ZIP_ERRNO;
+
+    /* number of this disk */
+    if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&number_disk)!=ZIP_OK)
+      err=ZIP_ERRNO;
+
+    /* number of the disk with the start of the central directory */
+    if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&number_disk_with_CD)!=ZIP_OK)
+      err=ZIP_ERRNO;
+
+    /* total number of entries in the central directory on this disk */
+    if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream, &number_entry)!=ZIP_OK)
+      err=ZIP_ERRNO;
+
+    /* total number of entries in the central directory */
+    if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream,&number_entry_CD)!=ZIP_OK)
+      err=ZIP_ERRNO;
+
+    if ((number_entry_CD!=number_entry) || (number_disk_with_CD!=0) || (number_disk!=0))
+      err=ZIP_BADZIPFILE;
+
+    /* size of the central directory */
+    if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream,&size_central_dir)!=ZIP_OK)
+      err=ZIP_ERRNO;
+
+    /* offset of start of central directory with respect to the
+    starting disk number */
+    if (zip64local_getLong64(&pziinit->z_filefunc, pziinit->filestream,&offset_central_dir)!=ZIP_OK)
+      err=ZIP_ERRNO;
+
+    // TODO..
+    // read the comment from the standard central header.
+    size_comment = 0;
+  }
+  else
+  {
+    // Read End of central Directory info
+    if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, central_pos,ZLIB_FILEFUNC_SEEK_SET)!=0)
+      err=ZIP_ERRNO;
+
+    /* the signature, already checked */
+    if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream,&uL)!=ZIP_OK)
+      err=ZIP_ERRNO;
+
+    /* number of this disk */
+    if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream,&number_disk)!=ZIP_OK)
+      err=ZIP_ERRNO;
+
+    /* number of the disk with the start of the central directory */
+    if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream,&number_disk_with_CD)!=ZIP_OK)
+      err=ZIP_ERRNO;
+
+    /* total number of entries in the central dir on this disk */
+    number_entry = 0;
+    if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK)
+      err=ZIP_ERRNO;
+    else
+      number_entry = uL;
+
+    /* total number of entries in the central dir */
+    number_entry_CD = 0;
+    if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK)
+      err=ZIP_ERRNO;
+    else
+      number_entry_CD = uL;
+
+    if ((number_entry_CD!=number_entry) || (number_disk_with_CD!=0) || (number_disk!=0))
+      err=ZIP_BADZIPFILE;
+
+    /* size of the central directory */
+    size_central_dir = 0;
+    if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK)
+      err=ZIP_ERRNO;
+    else
+      size_central_dir = uL;
+
+    /* offset of start of central directory with respect to the starting disk number */
+    offset_central_dir = 0;
+    if (zip64local_getLong(&pziinit->z_filefunc, pziinit->filestream, &uL)!=ZIP_OK)
+      err=ZIP_ERRNO;
+    else
+      offset_central_dir = uL;
+
+
+    /* zipfile global comment length */
+    if (zip64local_getShort(&pziinit->z_filefunc, pziinit->filestream, &size_comment)!=ZIP_OK)
+      err=ZIP_ERRNO;
+  }
+
+  if ((central_pos<offset_central_dir+size_central_dir) &&
+    (err==ZIP_OK))
+    err=ZIP_BADZIPFILE;
+
+  if (err!=ZIP_OK)
+  {
+    ZCLOSE64(pziinit->z_filefunc, pziinit->filestream);
+    return ZIP_ERRNO;
+  }
+
+  if (size_comment>0)
+  {
+    pziinit->globalcomment = (char*)ALLOC(size_comment+1);
+    if (pziinit->globalcomment)
+    {
+      size_comment = ZREAD64(pziinit->z_filefunc, pziinit->filestream, pziinit->globalcomment,size_comment);
+      pziinit->globalcomment[size_comment]=0;
+    }
+  }
+
+  byte_before_the_zipfile = central_pos - (offset_central_dir+size_central_dir);
+  pziinit->add_position_when_writting_offset = byte_before_the_zipfile;
+
+  {
+    ZPOS64_T size_central_dir_to_read = size_central_dir;
+    size_t buf_size = SIZEDATA_INDATABLOCK;
+    void* buf_read = (void*)ALLOC(buf_size);
+    if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, offset_central_dir + byte_before_the_zipfile, ZLIB_FILEFUNC_SEEK_SET) != 0)
+      err=ZIP_ERRNO;
+
+    while ((size_central_dir_to_read>0) && (err==ZIP_OK))
+    {
+      ZPOS64_T read_this = SIZEDATA_INDATABLOCK;
+      if (read_this > size_central_dir_to_read)
+        read_this = size_central_dir_to_read;
+
+      if (ZREAD64(pziinit->z_filefunc, pziinit->filestream,buf_read,(uLong)read_this) != read_this)
+        err=ZIP_ERRNO;
+
+      if (err==ZIP_OK)
+        err = add_data_in_datablock(&pziinit->central_dir,buf_read, (uLong)read_this);
+
+      size_central_dir_to_read-=read_this;
+    }
+    TRYFREE(buf_read);
+  }
+  pziinit->begin_pos = byte_before_the_zipfile;
+  pziinit->number_entry = number_entry_CD;
+
+  if (ZSEEK64(pziinit->z_filefunc, pziinit->filestream, offset_central_dir+byte_before_the_zipfile,ZLIB_FILEFUNC_SEEK_SET) != 0)
+    err=ZIP_ERRNO;
+
+  return err;
+}
+
+
+#endif /* !NO_ADDFILEINEXISTINGZIP*/
+
+
+/************************************************************/
+extern zipFile ZEXPORT zipOpen3 (const void *pathname, int append, zipcharpc* globalcomment, zlib_filefunc64_32_def* pzlib_filefunc64_32_def)
+{
+    zip64_internal ziinit;
+    zip64_internal* zi;
+    int err=ZIP_OK;
+
+    ziinit.z_filefunc.zseek32_file = NULL;
+    ziinit.z_filefunc.ztell32_file = NULL;
+    if (pzlib_filefunc64_32_def==NULL)
+        fill_fopen64_filefunc(&ziinit.z_filefunc.zfile_func64);
+    else
+        ziinit.z_filefunc = *pzlib_filefunc64_32_def;
+
+    ziinit.filestream = ZOPEN64(ziinit.z_filefunc,
+                  pathname,
+                  (append == APPEND_STATUS_CREATE) ?
+                  (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_CREATE) :
+                    (ZLIB_FILEFUNC_MODE_READ | ZLIB_FILEFUNC_MODE_WRITE | ZLIB_FILEFUNC_MODE_EXISTING));
+
+    if (ziinit.filestream == NULL)
+        return NULL;
+
+    if (append == APPEND_STATUS_CREATEAFTER)
+        ZSEEK64(ziinit.z_filefunc,ziinit.filestream,0,SEEK_END);
+
+    ziinit.begin_pos = ZTELL64(ziinit.z_filefunc,ziinit.filestream);
+    ziinit.in_opened_file_inzip = 0;
+    ziinit.ci.stream_initialised = 0;
+    ziinit.number_entry = 0;
+    ziinit.add_position_when_writting_offset = 0;
+    init_linkedlist(&(ziinit.central_dir));
+
+
+
+    zi = (zip64_internal*)ALLOC(sizeof(zip64_internal));
+    if (zi==NULL)
+    {
+        ZCLOSE64(ziinit.z_filefunc,ziinit.filestream);
+        return NULL;
+    }
+
+    /* now we add file in a zipfile */
+#    ifndef NO_ADDFILEINEXISTINGZIP
+    ziinit.globalcomment = NULL;
+    if (append == APPEND_STATUS_ADDINZIP)
+    {
+      // Read and Cache Central Directory Records
+      err = LoadCentralDirectoryRecord(&ziinit);
+    }
+
+    if (globalcomment)
+    {
+      *globalcomment = ziinit.globalcomment;
+    }
+#    endif /* !NO_ADDFILEINEXISTINGZIP*/
+
+    if (err != ZIP_OK)
+    {
+#    ifndef NO_ADDFILEINEXISTINGZIP
+        TRYFREE(ziinit.globalcomment);
+#    endif /* !NO_ADDFILEINEXISTINGZIP*/
+        TRYFREE(zi);
+        return NULL;
+    }
+    else
+    {
+        *zi = ziinit;
+        return (zipFile)zi;
+    }
+}
+
+extern zipFile ZEXPORT zipOpen2 (const char *pathname, int append, zipcharpc* globalcomment, zlib_filefunc_def* pzlib_filefunc32_def)
+{
+    if (pzlib_filefunc32_def != NULL)
+    {
+        zlib_filefunc64_32_def zlib_filefunc64_32_def_fill;
+        fill_zlib_filefunc64_32_def_from_filefunc32(&zlib_filefunc64_32_def_fill,pzlib_filefunc32_def);
+        return zipOpen3(pathname, append, globalcomment, &zlib_filefunc64_32_def_fill);
+    }
+    else
+        return zipOpen3(pathname, append, globalcomment, NULL);
+}
+
+extern zipFile ZEXPORT zipOpen2_64 (const void *pathname, int append, zipcharpc* globalcomment, zlib_filefunc64_def* pzlib_filefunc_def)
+{
+    if (pzlib_filefunc_def != NULL)
+    {
+        zlib_filefunc64_32_def zlib_filefunc64_32_def_fill;
+        zlib_filefunc64_32_def_fill.zfile_func64 = *pzlib_filefunc_def;
+        zlib_filefunc64_32_def_fill.ztell32_file = NULL;
+        zlib_filefunc64_32_def_fill.zseek32_file = NULL;
+        return zipOpen3(pathname, append, globalcomment, &zlib_filefunc64_32_def_fill);
+    }
+    else
+        return zipOpen3(pathname, append, globalcomment, NULL);
+}
+
+
+
+extern zipFile ZEXPORT zipOpen (const char* pathname, int append)
+{
+    return zipOpen3((const void*)pathname,append,NULL,NULL);
+}
+
+extern zipFile ZEXPORT zipOpen64 (const void* pathname, int append)
+{
+    return zipOpen3(pathname,append,NULL,NULL);
+}
+
+int Write_LocalFileHeader(zip64_internal* zi, const char* filename, uInt size_extrafield_local, const void* extrafield_local)
+{
+  /* write the local header */
+  int err;
+  uInt size_filename = (uInt)strlen(filename);
+  uInt size_extrafield = size_extrafield_local;
+
+  err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)LOCALHEADERMAGIC, 4);
+
+  if (err==ZIP_OK)
+  {
+    if(zi->ci.zip64)
+      err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)45,2);/* version needed to extract */
+    else
+      err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)20,2);/* version needed to extract */
+  }
+
+  if (err==ZIP_OK)
+    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.flag,2);
+
+  if (err==ZIP_OK)
+    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.method,2);
+
+  if (err==ZIP_OK)
+    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->ci.dosDate,4);
+
+  // CRC / Compressed size / Uncompressed size will be filled in later and rewritten later
+  if (err==ZIP_OK)
+    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* crc 32, unknown */
+  if (err==ZIP_OK)
+  {
+    if(zi->ci.zip64)
+      err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xFFFFFFFF,4); /* compressed size, unknown */
+    else
+      err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* compressed size, unknown */
+  }
+  if (err==ZIP_OK)
+  {
+    if(zi->ci.zip64)
+      err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xFFFFFFFF,4); /* uncompressed size, unknown */
+    else
+      err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4); /* uncompressed size, unknown */
+  }
+
+  if (err==ZIP_OK)
+    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_filename,2);
+
+  if(zi->ci.zip64)
+  {
+    size_extrafield += 20;
+  }
+
+  if (err==ZIP_OK)
+    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_extrafield,2);
+
+  if ((err==ZIP_OK) && (size_filename > 0))
+  {
+    if (ZWRITE64(zi->z_filefunc,zi->filestream,filename,size_filename)!=size_filename)
+      err = ZIP_ERRNO;
+  }
+
+  if ((err==ZIP_OK) && (size_extrafield_local > 0))
+  {
+    if (ZWRITE64(zi->z_filefunc, zi->filestream, extrafield_local, size_extrafield_local) != size_extrafield_local)
+      err = ZIP_ERRNO;
+  }
+
+
+  if ((err==ZIP_OK) && (zi->ci.zip64))
+  {
+      // write the Zip64 extended info
+      short HeaderID = 1;
+      short DataSize = 16;
+      ZPOS64_T CompressedSize = 0;
+      ZPOS64_T UncompressedSize = 0;
+
+      // Remember position of Zip64 extended info for the local file header. (needed when we update size after done with file)
+      zi->ci.pos_zip64extrainfo = ZTELL64(zi->z_filefunc,zi->filestream);
+
+      err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (short)HeaderID,2);
+      err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (short)DataSize,2);
+
+      err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (ZPOS64_T)UncompressedSize,8);
+      err = zip64local_putValue(&zi->z_filefunc, zi->filestream, (ZPOS64_T)CompressedSize,8);
+  }
+
+  return err;
+}
+
+/*
+ NOTE.
+ When writing RAW the ZIP64 extended information in extrafield_local and extrafield_global needs to be stripped
+ before calling this function it can be done with zipRemoveExtraInfoBlock
+
+ It is not done here because then we need to realloc a new buffer since parameters are 'const' and I want to minimize
+ unnecessary allocations.
+ */
+extern int ZEXPORT zipOpenNewFileInZip4_64 (zipFile file, const char* filename, const zip_fileinfo* zipfi,
+                                         const void* extrafield_local, uInt size_extrafield_local,
+                                         const void* extrafield_global, uInt size_extrafield_global,
+                                         const char* comment, int method, int level, int raw,
+                                         int windowBits,int memLevel, int strategy,
+                                         const char* password, uLong crcForCrypting,
+                                         uLong versionMadeBy, uLong flagBase, int zip64)
+{
+    zip64_internal* zi;
+    uInt size_filename;
+    uInt size_comment;
+    uInt i;
+    int err = ZIP_OK;
+
+#    ifdef NOCRYPT
+    (crcForCrypting);
+    if (password != NULL)
+        return ZIP_PARAMERROR;
+#    endif
+
+    if (file == NULL)
+        return ZIP_PARAMERROR;
+
+#ifdef HAVE_BZIP2
+    if ((method!=0) && (method!=Z_DEFLATED) && (method!=Z_BZIP2ED))
+      return ZIP_PARAMERROR;
+#else
+    if ((method!=0) && (method!=Z_DEFLATED))
+      return ZIP_PARAMERROR;
+#endif
+
+    zi = (zip64_internal*)file;
+
+    if (zi->in_opened_file_inzip == 1)
+    {
+        err = zipCloseFileInZip (file);
+        if (err != ZIP_OK)
+            return err;
+    }
+
+    if (filename==NULL)
+        filename="-";
+
+    if (comment==NULL)
+        size_comment = 0;
+    else
+        size_comment = (uInt)strlen(comment);
+
+    size_filename = (uInt)strlen(filename);
+
+    if (zipfi == NULL)
+        zi->ci.dosDate = 0;
+    else
+    {
+        if (zipfi->dosDate != 0)
+            zi->ci.dosDate = zipfi->dosDate;
+        else
+          zi->ci.dosDate = zip64local_TmzDateToDosDate(&zipfi->tmz_date);
+    }
+
+    zi->ci.flag = flagBase;
+    if ((level==8) || (level==9))
+      zi->ci.flag |= 2;
+    if (level==2)
+      zi->ci.flag |= 4;
+    if (level==1)
+      zi->ci.flag |= 6;
+    if (password != NULL)
+      zi->ci.flag |= 1;
+
+    zi->ci.crc32 = 0;
+    zi->ci.method = method;
+    zi->ci.encrypt = 0;
+    zi->ci.stream_initialised = 0;
+    zi->ci.pos_in_buffered_data = 0;
+    zi->ci.raw = raw;
+    zi->ci.pos_local_header = ZTELL64(zi->z_filefunc,zi->filestream);
+
+    zi->ci.size_centralheader = SIZECENTRALHEADER + size_filename + size_extrafield_global + size_comment;
+    zi->ci.size_centralExtraFree = 32; // Extra space we have reserved in case we need to add ZIP64 extra info data
+
+    zi->ci.central_header = (char*)ALLOC((uInt)zi->ci.size_centralheader + zi->ci.size_centralExtraFree);
+
+    zi->ci.size_centralExtra = size_extrafield_global;
+    zip64local_putValue_inmemory(zi->ci.central_header,(uLong)CENTRALHEADERMAGIC,4);
+    /* version info */
+    zip64local_putValue_inmemory(zi->ci.central_header+4,(uLong)versionMadeBy,2);
+    zip64local_putValue_inmemory(zi->ci.central_header+6,(uLong)20,2);
+    zip64local_putValue_inmemory(zi->ci.central_header+8,(uLong)zi->ci.flag,2);
+    zip64local_putValue_inmemory(zi->ci.central_header+10,(uLong)zi->ci.method,2);
+    zip64local_putValue_inmemory(zi->ci.central_header+12,(uLong)zi->ci.dosDate,4);
+    zip64local_putValue_inmemory(zi->ci.central_header+16,(uLong)0,4); /*crc*/
+    zip64local_putValue_inmemory(zi->ci.central_header+20,(uLong)0,4); /*compr size*/
+    zip64local_putValue_inmemory(zi->ci.central_header+24,(uLong)0,4); /*uncompr size*/
+    zip64local_putValue_inmemory(zi->ci.central_header+28,(uLong)size_filename,2);
+    zip64local_putValue_inmemory(zi->ci.central_header+30,(uLong)size_extrafield_global,2);
+    zip64local_putValue_inmemory(zi->ci.central_header+32,(uLong)size_comment,2);
+    zip64local_putValue_inmemory(zi->ci.central_header+34,(uLong)0,2); /*disk nm start*/
+
+    if (zipfi==NULL)
+        zip64local_putValue_inmemory(zi->ci.central_header+36,(uLong)0,2);
+    else
+        zip64local_putValue_inmemory(zi->ci.central_header+36,(uLong)zipfi->internal_fa,2);
+
+    if (zipfi==NULL)
+        zip64local_putValue_inmemory(zi->ci.central_header+38,(uLong)0,4);
+    else
+        zip64local_putValue_inmemory(zi->ci.central_header+38,(uLong)zipfi->external_fa,4);
+
+    if(zi->ci.pos_local_header >= 0xffffffff)
+      zip64local_putValue_inmemory(zi->ci.central_header+42,(uLong)0xffffffff,4);
+    else
+      zip64local_putValue_inmemory(zi->ci.central_header+42,(uLong)zi->ci.pos_local_header - zi->add_position_when_writting_offset,4);
+
+    for (i=0;i<size_filename;i++)
+        *(zi->ci.central_header+SIZECENTRALHEADER+i) = *(filename+i);
+
+    for (i=0;i<size_extrafield_global;i++)
+        *(zi->ci.central_header+SIZECENTRALHEADER+size_filename+i) =
+              *(((const char*)extrafield_global)+i);
+
+    for (i=0;i<size_comment;i++)
+        *(zi->ci.central_header+SIZECENTRALHEADER+size_filename+
+              size_extrafield_global+i) = *(comment+i);
+    if (zi->ci.central_header == NULL)
+        return ZIP_INTERNALERROR;
+
+    zi->ci.zip64 = zip64;
+    zi->ci.totalCompressedData = 0;
+    zi->ci.totalUncompressedData = 0;
+    zi->ci.pos_zip64extrainfo = 0;
+
+    err = Write_LocalFileHeader(zi, filename, size_extrafield_local, extrafield_local);
+
+#ifdef HAVE_BZIP2
+    zi->ci.bstream.avail_in = (uInt)0;
+    zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE;
+    zi->ci.bstream.next_out = (char*)zi->ci.buffered_data;
+    zi->ci.bstream.total_in_hi32 = 0;
+    zi->ci.bstream.total_in_lo32 = 0;
+    zi->ci.bstream.total_out_hi32 = 0;
+    zi->ci.bstream.total_out_lo32 = 0;
+#endif
+
+    zi->ci.stream.avail_in = (uInt)0;
+    zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
+    zi->ci.stream.next_out = zi->ci.buffered_data;
+    zi->ci.stream.total_in = 0;
+    zi->ci.stream.total_out = 0;
+    zi->ci.stream.data_type = Z_BINARY;
+
+#ifdef HAVE_BZIP2
+    if ((err==ZIP_OK) && (zi->ci.method == Z_DEFLATED || zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw))
+#else
+    if ((err==ZIP_OK) && (zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
+#endif
+    {
+        if(zi->ci.method == Z_DEFLATED)
+        {
+          zi->ci.stream.zalloc = (alloc_func)0;
+          zi->ci.stream.zfree = (free_func)0;
+          zi->ci.stream.opaque = (voidpf)0;
+
+          if (windowBits>0)
+              windowBits = -windowBits;
+
+          err = deflateInit2(&zi->ci.stream, level, Z_DEFLATED, windowBits, memLevel, strategy);
+
+          if (err==Z_OK)
+              zi->ci.stream_initialised = Z_DEFLATED;
+        }
+        else if(zi->ci.method == Z_BZIP2ED)
+        {
+#ifdef HAVE_BZIP2
+            // Init BZip stuff here
+          zi->ci.bstream.bzalloc = 0;
+          zi->ci.bstream.bzfree = 0;
+          zi->ci.bstream.opaque = (voidpf)0;
+
+          err = BZ2_bzCompressInit(&zi->ci.bstream, level, 0,35);
+          if(err == BZ_OK)
+            zi->ci.stream_initialised = Z_BZIP2ED;
+#endif
+        }
+
+    }
+
+#    ifndef NOCRYPT
+    zi->ci.crypt_header_size = 0;
+    if ((err==Z_OK) && (password != NULL))
+    {
+        unsigned char bufHead[RAND_HEAD_LEN];
+        unsigned int sizeHead;
+        zi->ci.encrypt = 1;
+        zi->ci.pcrc_32_tab = get_crc_table();
+        /*init_keys(password,zi->ci.keys,zi->ci.pcrc_32_tab);*/
+
+        sizeHead=crypthead(password,bufHead,RAND_HEAD_LEN,zi->ci.keys,zi->ci.pcrc_32_tab,crcForCrypting);
+        zi->ci.crypt_header_size = sizeHead;
+
+        if (ZWRITE64(zi->z_filefunc,zi->filestream,bufHead,sizeHead) != sizeHead)
+                err = ZIP_ERRNO;
+    }
+#    endif
+
+    if (err==Z_OK)
+        zi->in_opened_file_inzip = 1;
+    return err;
+}
+
+extern int ZEXPORT zipOpenNewFileInZip4 (zipFile file, const char* filename, const zip_fileinfo* zipfi,
+                                         const void* extrafield_local, uInt size_extrafield_local,
+                                         const void* extrafield_global, uInt size_extrafield_global,
+                                         const char* comment, int method, int level, int raw,
+                                         int windowBits,int memLevel, int strategy,
+                                         const char* password, uLong crcForCrypting,
+                                         uLong versionMadeBy, uLong flagBase)
+{
+    return zipOpenNewFileInZip4_64 (file, filename, zipfi,
+                                 extrafield_local, size_extrafield_local,
+                                 extrafield_global, size_extrafield_global,
+                                 comment, method, level, raw,
+                                 windowBits, memLevel, strategy,
+                                 password, crcForCrypting, versionMadeBy, flagBase, 0);
+}
+
+extern int ZEXPORT zipOpenNewFileInZip3 (zipFile file, const char* filename, const zip_fileinfo* zipfi,
+                                         const void* extrafield_local, uInt size_extrafield_local,
+                                         const void* extrafield_global, uInt size_extrafield_global,
+                                         const char* comment, int method, int level, int raw,
+                                         int windowBits,int memLevel, int strategy,
+                                         const char* password, uLong crcForCrypting)
+{
+    return zipOpenNewFileInZip4_64 (file, filename, zipfi,
+                                 extrafield_local, size_extrafield_local,
+                                 extrafield_global, size_extrafield_global,
+                                 comment, method, level, raw,
+                                 windowBits, memLevel, strategy,
+                                 password, crcForCrypting, VERSIONMADEBY, 0, 0);
+}
+
+extern int ZEXPORT zipOpenNewFileInZip3_64(zipFile file, const char* filename, const zip_fileinfo* zipfi,
+                                         const void* extrafield_local, uInt size_extrafield_local,
+                                         const void* extrafield_global, uInt size_extrafield_global,
+                                         const char* comment, int method, int level, int raw,
+                                         int windowBits,int memLevel, int strategy,
+                                         const char* password, uLong crcForCrypting, int zip64)
+{
+    return zipOpenNewFileInZip4_64 (file, filename, zipfi,
+                                 extrafield_local, size_extrafield_local,
+                                 extrafield_global, size_extrafield_global,
+                                 comment, method, level, raw,
+                                 windowBits, memLevel, strategy,
+                                 password, crcForCrypting, VERSIONMADEBY, 0, zip64);
+}
+
+extern int ZEXPORT zipOpenNewFileInZip2(zipFile file, const char* filename, const zip_fileinfo* zipfi,
+                                        const void* extrafield_local, uInt size_extrafield_local,
+                                        const void* extrafield_global, uInt size_extrafield_global,
+                                        const char* comment, int method, int level, int raw)
+{
+    return zipOpenNewFileInZip4_64 (file, filename, zipfi,
+                                 extrafield_local, size_extrafield_local,
+                                 extrafield_global, size_extrafield_global,
+                                 comment, method, level, raw,
+                                 -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
+                                 NULL, 0, VERSIONMADEBY, 0, 0);
+}
+
+extern int ZEXPORT zipOpenNewFileInZip2_64(zipFile file, const char* filename, const zip_fileinfo* zipfi,
+                                        const void* extrafield_local, uInt size_extrafield_local,
+                                        const void* extrafield_global, uInt size_extrafield_global,
+                                        const char* comment, int method, int level, int raw, int zip64)
+{
+    return zipOpenNewFileInZip4_64 (file, filename, zipfi,
+                                 extrafield_local, size_extrafield_local,
+                                 extrafield_global, size_extrafield_global,
+                                 comment, method, level, raw,
+                                 -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
+                                 NULL, 0, VERSIONMADEBY, 0, zip64);
+}
+
+extern int ZEXPORT zipOpenNewFileInZip64 (zipFile file, const char* filename, const zip_fileinfo* zipfi,
+                                        const void* extrafield_local, uInt size_extrafield_local,
+                                        const void*extrafield_global, uInt size_extrafield_global,
+                                        const char* comment, int method, int level, int zip64)
+{
+    return zipOpenNewFileInZip4_64 (file, filename, zipfi,
+                                 extrafield_local, size_extrafield_local,
+                                 extrafield_global, size_extrafield_global,
+                                 comment, method, level, 0,
+                                 -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
+                                 NULL, 0, VERSIONMADEBY, 0, zip64);
+}
+
+extern int ZEXPORT zipOpenNewFileInZip (zipFile file, const char* filename, const zip_fileinfo* zipfi,
+                                        const void* extrafield_local, uInt size_extrafield_local,
+                                        const void*extrafield_global, uInt size_extrafield_global,
+                                        const char* comment, int method, int level)
+{
+    return zipOpenNewFileInZip4_64 (file, filename, zipfi,
+                                 extrafield_local, size_extrafield_local,
+                                 extrafield_global, size_extrafield_global,
+                                 comment, method, level, 0,
+                                 -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
+                                 NULL, 0, VERSIONMADEBY, 0, 0);
+}
+
+local int zip64FlushWriteBuffer(zip64_internal* zi)
+{
+    int err=ZIP_OK;
+
+    if (zi->ci.encrypt != 0)
+    {
+#ifndef NOCRYPT
+        uInt i;
+        int t;
+        for (i=0;i<zi->ci.pos_in_buffered_data;i++)
+            zi->ci.buffered_data[i] = zencode(zi->ci.keys, zi->ci.pcrc_32_tab, zi->ci.buffered_data[i],t);
+#endif
+    }
+
+    if (ZWRITE64(zi->z_filefunc,zi->filestream,zi->ci.buffered_data,zi->ci.pos_in_buffered_data) != zi->ci.pos_in_buffered_data)
+      err = ZIP_ERRNO;
+
+    zi->ci.totalCompressedData += zi->ci.pos_in_buffered_data;
+
+#ifdef HAVE_BZIP2
+    if(zi->ci.method == Z_BZIP2ED)
+    {
+      zi->ci.totalUncompressedData += zi->ci.bstream.total_in_lo32;
+      zi->ci.bstream.total_in_lo32 = 0;
+      zi->ci.bstream.total_in_hi32 = 0;
+    }
+    else
+#endif
+    {
+      zi->ci.totalUncompressedData += zi->ci.stream.total_in;
+      zi->ci.stream.total_in = 0;
+    }
+
+
+    zi->ci.pos_in_buffered_data = 0;
+
+    return err;
+}
+
+extern int ZEXPORT zipWriteInFileInZip (zipFile file,const void* buf,unsigned int len)
+{
+    zip64_internal* zi;
+    int err=ZIP_OK;
+
+    if (file == NULL)
+        return ZIP_PARAMERROR;
+    zi = (zip64_internal*)file;
+
+    if (zi->in_opened_file_inzip == 0)
+        return ZIP_PARAMERROR;
+
+    zi->ci.crc32 = crc32(zi->ci.crc32,buf,(uInt)len);
+
+#ifdef HAVE_BZIP2
+    if(zi->ci.method == Z_BZIP2ED && (!zi->ci.raw))
+    {
+      zi->ci.bstream.next_in = (void*)buf;
+      zi->ci.bstream.avail_in = len;
+      err = BZ_RUN_OK;
+
+      while ((err==BZ_RUN_OK) && (zi->ci.bstream.avail_in>0))
+      {
+        if (zi->ci.bstream.avail_out == 0)
+        {
+          if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO)
+            err = ZIP_ERRNO;
+          zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE;
+          zi->ci.bstream.next_out = (char*)zi->ci.buffered_data;
+        }
+
+
+        if(err != BZ_RUN_OK)
+          break;
+
+        if ((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw))
+        {
+          uLong uTotalOutBefore_lo = zi->ci.bstream.total_out_lo32;
+//          uLong uTotalOutBefore_hi = zi->ci.bstream.total_out_hi32;
+          err=BZ2_bzCompress(&zi->ci.bstream,  BZ_RUN);
+
+          zi->ci.pos_in_buffered_data += (uInt)(zi->ci.bstream.total_out_lo32 - uTotalOutBefore_lo) ;
+        }
+      }
+
+      if(err == BZ_RUN_OK)
+        err = ZIP_OK;
+    }
+    else
+#endif
+    {
+      zi->ci.stream.next_in = (Bytef*)buf;
+      zi->ci.stream.avail_in = len;
+
+      while ((err==ZIP_OK) && (zi->ci.stream.avail_in>0))
+      {
+          if (zi->ci.stream.avail_out == 0)
+          {
+              if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO)
+                  err = ZIP_ERRNO;
+              zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
+              zi->ci.stream.next_out = zi->ci.buffered_data;
+          }
+
+
+          if(err != ZIP_OK)
+              break;
+
+          if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
+          {
+              uLong uTotalOutBefore = zi->ci.stream.total_out;
+              err=deflate(&zi->ci.stream,  Z_NO_FLUSH);
+              if(uTotalOutBefore > zi->ci.stream.total_out)
+              {
+                int bBreak = 0;
+                bBreak++;
+              }
+
+              zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ;
+          }
+          else
+          {
+              uInt copy_this,i;
+              if (zi->ci.stream.avail_in < zi->ci.stream.avail_out)
+                  copy_this = zi->ci.stream.avail_in;
+              else
+                  copy_this = zi->ci.stream.avail_out;
+
+              for (i = 0; i < copy_this; i++)
+                  *(((char*)zi->ci.stream.next_out)+i) =
+                      *(((const char*)zi->ci.stream.next_in)+i);
+              {
+                  zi->ci.stream.avail_in -= copy_this;
+                  zi->ci.stream.avail_out-= copy_this;
+                  zi->ci.stream.next_in+= copy_this;
+                  zi->ci.stream.next_out+= copy_this;
+                  zi->ci.stream.total_in+= copy_this;
+                  zi->ci.stream.total_out+= copy_this;
+                  zi->ci.pos_in_buffered_data += copy_this;
+              }
+          }
+      }// while(...)
+    }
+
+    return err;
+}
+
+extern int ZEXPORT zipCloseFileInZipRaw (zipFile file, uLong uncompressed_size, uLong crc32)
+{
+    return zipCloseFileInZipRaw64 (file, uncompressed_size, crc32);
+}
+
+extern int ZEXPORT zipCloseFileInZipRaw64 (zipFile file, ZPOS64_T uncompressed_size, uLong crc32)
+{
+    zip64_internal* zi;
+    ZPOS64_T compressed_size;
+    uLong invalidValue = 0xffffffff;
+    short datasize = 0;
+    int err=ZIP_OK;
+
+    if (file == NULL)
+        return ZIP_PARAMERROR;
+    zi = (zip64_internal*)file;
+
+    if (zi->in_opened_file_inzip == 0)
+        return ZIP_PARAMERROR;
+    zi->ci.stream.avail_in = 0;
+
+    if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
+                {
+                        while (err==ZIP_OK)
+                        {
+                                uLong uTotalOutBefore;
+                                if (zi->ci.stream.avail_out == 0)
+                                {
+                                        if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO)
+                                                err = ZIP_ERRNO;
+                                        zi->ci.stream.avail_out = (uInt)Z_BUFSIZE;
+                                        zi->ci.stream.next_out = zi->ci.buffered_data;
+                                }
+                                uTotalOutBefore = zi->ci.stream.total_out;
+                                err=deflate(&zi->ci.stream,  Z_FINISH);
+                                zi->ci.pos_in_buffered_data += (uInt)(zi->ci.stream.total_out - uTotalOutBefore) ;
+                        }
+                }
+    else if ((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw))
+    {
+#ifdef HAVE_BZIP2
+      err = BZ_FINISH_OK;
+      while (err==BZ_FINISH_OK)
+      {
+        uLong uTotalOutBefore;
+        if (zi->ci.bstream.avail_out == 0)
+        {
+          if (zip64FlushWriteBuffer(zi) == ZIP_ERRNO)
+            err = ZIP_ERRNO;
+          zi->ci.bstream.avail_out = (uInt)Z_BUFSIZE;
+          zi->ci.bstream.next_out = (char*)zi->ci.buffered_data;
+        }
+        uTotalOutBefore = zi->ci.bstream.total_out_lo32;
+        err=BZ2_bzCompress(&zi->ci.bstream,  BZ_FINISH);
+        if(err == BZ_STREAM_END)
+          err = Z_STREAM_END;
+
+        zi->ci.pos_in_buffered_data += (uInt)(zi->ci.bstream.total_out_lo32 - uTotalOutBefore);
+      }
+
+      if(err == BZ_FINISH_OK)
+        err = ZIP_OK;
+#endif
+    }
+
+    if (err==Z_STREAM_END)
+        err=ZIP_OK; /* this is normal */
+
+    if ((zi->ci.pos_in_buffered_data>0) && (err==ZIP_OK))
+                {
+        if (zip64FlushWriteBuffer(zi)==ZIP_ERRNO)
+            err = ZIP_ERRNO;
+                }
+
+    if ((zi->ci.method == Z_DEFLATED) && (!zi->ci.raw))
+    {
+        int tmp_err = deflateEnd(&zi->ci.stream);
+        if (err == ZIP_OK)
+            err = tmp_err;
+        zi->ci.stream_initialised = 0;
+    }
+#ifdef HAVE_BZIP2
+    else if((zi->ci.method == Z_BZIP2ED) && (!zi->ci.raw))
+    {
+      int tmperr = BZ2_bzCompressEnd(&zi->ci.bstream);
+                        if (err==ZIP_OK)
+                                err = tmperr;
+                        zi->ci.stream_initialised = 0;
+    }
+#endif
+
+    if (!zi->ci.raw)
+    {
+        crc32 = (uLong)zi->ci.crc32;
+        uncompressed_size = zi->ci.totalUncompressedData;
+    }
+    compressed_size = zi->ci.totalCompressedData;
+
+#    ifndef NOCRYPT
+    compressed_size += zi->ci.crypt_header_size;
+#    endif
+
+    // update Current Item crc and sizes,
+    if(compressed_size >= 0xffffffff || uncompressed_size >= 0xffffffff || zi->ci.pos_local_header >= 0xffffffff)
+    {
+      /*version Made by*/
+      zip64local_putValue_inmemory(zi->ci.central_header+4,(uLong)45,2);
+      /*version needed*/
+      zip64local_putValue_inmemory(zi->ci.central_header+6,(uLong)45,2);
+
+    }
+
+    zip64local_putValue_inmemory(zi->ci.central_header+16,crc32,4); /*crc*/
+
+
+    if(compressed_size >= 0xffffffff)
+      zip64local_putValue_inmemory(zi->ci.central_header+20, invalidValue,4); /*compr size*/
+    else
+      zip64local_putValue_inmemory(zi->ci.central_header+20, compressed_size,4); /*compr size*/
+
+    /// set internal file attributes field
+    if (zi->ci.stream.data_type == Z_ASCII)
+        zip64local_putValue_inmemory(zi->ci.central_header+36,(uLong)Z_ASCII,2);
+
+    if(uncompressed_size >= 0xffffffff)
+      zip64local_putValue_inmemory(zi->ci.central_header+24, invalidValue,4); /*uncompr size*/
+    else
+      zip64local_putValue_inmemory(zi->ci.central_header+24, uncompressed_size,4); /*uncompr size*/
+
+    // Add ZIP64 extra info field for uncompressed size
+    if(uncompressed_size >= 0xffffffff)
+      datasize += 8;
+
+    // Add ZIP64 extra info field for compressed size
+    if(compressed_size >= 0xffffffff)
+      datasize += 8;
+
+    // Add ZIP64 extra info field for relative offset to local file header of current file
+    if(zi->ci.pos_local_header >= 0xffffffff)
+      datasize += 8;
+
+    if(datasize > 0)
+    {
+      char* p = NULL;
+
+      if((uLong)(datasize + 4) > zi->ci.size_centralExtraFree)
+      {
+        // we can not write more data to the buffer that we have room for.
+        return ZIP_BADZIPFILE;
+      }
+
+      p = zi->ci.central_header + zi->ci.size_centralheader;
+
+      // Add Extra Information Header for 'ZIP64 information'
+      zip64local_putValue_inmemory(p, 0x0001, 2); // HeaderID
+      p += 2;
+      zip64local_putValue_inmemory(p, datasize, 2); // DataSize
+      p += 2;
+
+      if(uncompressed_size >= 0xffffffff)
+      {
+        zip64local_putValue_inmemory(p, uncompressed_size, 8);
+        p += 8;
+      }
+
+      if(compressed_size >= 0xffffffff)
+      {
+        zip64local_putValue_inmemory(p, compressed_size, 8);
+        p += 8;
+      }
+
+      if(zi->ci.pos_local_header >= 0xffffffff)
+      {
+        zip64local_putValue_inmemory(p, zi->ci.pos_local_header, 8);
+        p += 8;
+      }
+
+      // Update how much extra free space we got in the memory buffer
+      // and increase the centralheader size so the new ZIP64 fields are included
+      // ( 4 below is the size of HeaderID and DataSize field )
+      zi->ci.size_centralExtraFree -= datasize + 4;
+      zi->ci.size_centralheader += datasize + 4;
+
+      // Update the extra info size field
+      zi->ci.size_centralExtra += datasize + 4;
+      zip64local_putValue_inmemory(zi->ci.central_header+30,(uLong)zi->ci.size_centralExtra,2);
+    }
+
+    if (err==ZIP_OK)
+        err = add_data_in_datablock(&zi->central_dir, zi->ci.central_header, (uLong)zi->ci.size_centralheader);
+
+    free(zi->ci.central_header);
+
+    if (err==ZIP_OK)
+    {
+        // Update the LocalFileHeader with the new values.
+
+        ZPOS64_T cur_pos_inzip = ZTELL64(zi->z_filefunc,zi->filestream);
+
+        if (ZSEEK64(zi->z_filefunc,zi->filestream, zi->ci.pos_local_header + 14,ZLIB_FILEFUNC_SEEK_SET)!=0)
+            err = ZIP_ERRNO;
+
+        if (err==ZIP_OK)
+            err = zip64local_putValue(&zi->z_filefunc,zi->filestream,crc32,4); /* crc 32, unknown */
+
+        if(uncompressed_size >= 0xffffffff || compressed_size >= 0xffffffff )
+        {
+          if(zi->ci.pos_zip64extrainfo > 0)
+          {
+            // Update the size in the ZIP64 extended field.
+            if (ZSEEK64(zi->z_filefunc,zi->filestream, zi->ci.pos_zip64extrainfo + 4,ZLIB_FILEFUNC_SEEK_SET)!=0)
+              err = ZIP_ERRNO;
+
+            if (err==ZIP_OK) /* compressed size, unknown */
+              err = zip64local_putValue(&zi->z_filefunc, zi->filestream, uncompressed_size, 8);
+
+            if (err==ZIP_OK) /* uncompressed size, unknown */
+              err = zip64local_putValue(&zi->z_filefunc, zi->filestream, compressed_size, 8);
+          }
+          else
+              err = ZIP_BADZIPFILE; // Caller passed zip64 = 0, so no room for zip64 info -> fatal
+        }
+        else
+        {
+          if (err==ZIP_OK) /* compressed size, unknown */
+              err = zip64local_putValue(&zi->z_filefunc,zi->filestream,compressed_size,4);
+
+          if (err==ZIP_OK) /* uncompressed size, unknown */
+              err = zip64local_putValue(&zi->z_filefunc,zi->filestream,uncompressed_size,4);
+        }
+
+        if (ZSEEK64(zi->z_filefunc,zi->filestream, cur_pos_inzip,ZLIB_FILEFUNC_SEEK_SET)!=0)
+            err = ZIP_ERRNO;
+    }
+
+    zi->number_entry ++;
+    zi->in_opened_file_inzip = 0;
+
+    return err;
+}
+
+extern int ZEXPORT zipCloseFileInZip (zipFile file)
+{
+    return zipCloseFileInZipRaw (file,0,0);
+}
+
+int Write_Zip64EndOfCentralDirectoryLocator(zip64_internal* zi, ZPOS64_T zip64eocd_pos_inzip)
+{
+  int err = ZIP_OK;
+  ZPOS64_T pos = zip64eocd_pos_inzip - zi->add_position_when_writting_offset;
+
+  err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ZIP64ENDLOCHEADERMAGIC,4);
+
+  /*num disks*/
+    if (err==ZIP_OK) /* number of the disk with the start of the central directory */
+      err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4);
+
+  /*relative offset*/
+    if (err==ZIP_OK) /* Relative offset to the Zip64EndOfCentralDirectory */
+      err = zip64local_putValue(&zi->z_filefunc,zi->filestream, pos,8);
+
+  /*total disks*/ /* Do not support spawning of disk so always say 1 here*/
+    if (err==ZIP_OK) /* number of the disk with the start of the central directory */
+      err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)1,4);
+
+    return err;
+}
+
+int Write_Zip64EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centraldir, ZPOS64_T centraldir_pos_inzip)
+{
+  int err = ZIP_OK;
+
+  uLong Zip64DataSize = 44;
+
+  err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ZIP64ENDHEADERMAGIC,4);
+
+  if (err==ZIP_OK) /* size of this 'zip64 end of central directory' */
+    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(ZPOS64_T)Zip64DataSize,8); // why ZPOS64_T of this ?
+
+  if (err==ZIP_OK) /* version made by */
+    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)45,2);
+
+  if (err==ZIP_OK) /* version needed */
+    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)45,2);
+
+  if (err==ZIP_OK) /* number of this disk */
+    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4);
+
+  if (err==ZIP_OK) /* number of the disk with the start of the central directory */
+    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,4);
+
+  if (err==ZIP_OK) /* total number of entries in the central dir on this disk */
+    err = zip64local_putValue(&zi->z_filefunc, zi->filestream, zi->number_entry, 8);
+
+  if (err==ZIP_OK) /* total number of entries in the central dir */
+    err = zip64local_putValue(&zi->z_filefunc, zi->filestream, zi->number_entry, 8);
+
+  if (err==ZIP_OK) /* size of the central directory */
+    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(ZPOS64_T)size_centraldir,8);
+
+  if (err==ZIP_OK) /* offset of start of central directory with respect to the starting disk number */
+  {
+    ZPOS64_T pos = centraldir_pos_inzip - zi->add_position_when_writting_offset;
+    err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (ZPOS64_T)pos,8);
+  }
+  return err;
+}
+int Write_EndOfCentralDirectoryRecord(zip64_internal* zi, uLong size_centraldir, ZPOS64_T centraldir_pos_inzip)
+{
+  int err = ZIP_OK;
+
+  /*signature*/
+  err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)ENDHEADERMAGIC,4);
+
+  if (err==ZIP_OK) /* number of this disk */
+    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2);
+
+  if (err==ZIP_OK) /* number of the disk with the start of the central directory */
+    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0,2);
+
+  if (err==ZIP_OK) /* total number of entries in the central dir on this disk */
+  {
+    {
+      if(zi->number_entry >= 0xFFFF)
+        err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xffff,2); // use value in ZIP64 record
+      else
+        err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2);
+    }
+  }
+
+  if (err==ZIP_OK) /* total number of entries in the central dir */
+  {
+    if(zi->number_entry >= 0xFFFF)
+      err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)0xffff,2); // use value in ZIP64 record
+    else
+      err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)zi->number_entry,2);
+  }
+
+  if (err==ZIP_OK) /* size of the central directory */
+    err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_centraldir,4);
+
+  if (err==ZIP_OK) /* offset of start of central directory with respect to the starting disk number */
+  {
+    ZPOS64_T pos = centraldir_pos_inzip - zi->add_position_when_writting_offset;
+    if(pos >= 0xffffffff)
+    {
+      err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (uLong)0xffffffff,4);
+    }
+    else
+      err = zip64local_putValue(&zi->z_filefunc,zi->filestream, (uLong)(centraldir_pos_inzip - zi->add_position_when_writting_offset),4);
+  }
+
+   return err;
+}
+
+int Write_GlobalComment(zip64_internal* zi, const char* global_comment)
+{
+  int err = ZIP_OK;
+  uInt size_global_comment = 0;
+
+  if(global_comment != NULL)
+    size_global_comment = (uInt)strlen(global_comment);
+
+  err = zip64local_putValue(&zi->z_filefunc,zi->filestream,(uLong)size_global_comment,2);
+
+  if (err == ZIP_OK && size_global_comment > 0)
+  {
+    if (ZWRITE64(zi->z_filefunc,zi->filestream, global_comment, size_global_comment) != size_global_comment)
+      err = ZIP_ERRNO;
+  }
+  return err;
+}
+
+extern int ZEXPORT zipClose (zipFile file, const char* global_comment)
+{
+    zip64_internal* zi;
+    int err = 0;
+    uLong size_centraldir = 0;
+    ZPOS64_T centraldir_pos_inzip;
+    ZPOS64_T pos;
+
+    if (file == NULL)
+        return ZIP_PARAMERROR;
+
+    zi = (zip64_internal*)file;
+
+    if (zi->in_opened_file_inzip == 1)
+    {
+        err = zipCloseFileInZip (file);
+    }
+
+#ifndef NO_ADDFILEINEXISTINGZIP
+    if (global_comment==NULL)
+        global_comment = zi->globalcomment;
+#endif
+
+    centraldir_pos_inzip = ZTELL64(zi->z_filefunc,zi->filestream);
+
+    if (err==ZIP_OK)
+    {
+        linkedlist_datablock_internal* ldi = zi->central_dir.first_block;
+        while (ldi!=NULL)
+        {
+            if ((err==ZIP_OK) && (ldi->filled_in_this_block>0))
+            {
+                if (ZWRITE64(zi->z_filefunc,zi->filestream, ldi->data, ldi->filled_in_this_block) != ldi->filled_in_this_block)
+                    err = ZIP_ERRNO;
+            }
+
+            size_centraldir += ldi->filled_in_this_block;
+            ldi = ldi->next_datablock;
+        }
+    }
+    free_linkedlist(&(zi->central_dir));
+
+    pos = centraldir_pos_inzip - zi->add_position_when_writting_offset;
+    if(pos >= 0xffffffff || zi->number_entry > 0xFFFF)
+    {
+      ZPOS64_T Zip64EOCDpos = ZTELL64(zi->z_filefunc,zi->filestream);
+      Write_Zip64EndOfCentralDirectoryRecord(zi, size_centraldir, centraldir_pos_inzip);
+
+      Write_Zip64EndOfCentralDirectoryLocator(zi, Zip64EOCDpos);
+    }
+
+    if (err==ZIP_OK)
+      err = Write_EndOfCentralDirectoryRecord(zi, size_centraldir, centraldir_pos_inzip);
+
+    if(err == ZIP_OK)
+      err = Write_GlobalComment(zi, global_comment);
+
+    if (ZCLOSE64(zi->z_filefunc,zi->filestream) != 0)
+        if (err == ZIP_OK)
+            err = ZIP_ERRNO;
+
+#ifndef NO_ADDFILEINEXISTINGZIP
+    TRYFREE(zi->globalcomment);
+#endif
+    TRYFREE(zi);
+
+    return err;
+}
+
+extern int ZEXPORT zipRemoveExtraInfoBlock (char* pData, int* dataLen, short sHeader)
+{
+  char* p = pData;
+  int size = 0;
+  char* pNewHeader;
+  char* pTmp;
+  short header;
+  short dataSize;
+
+  int retVal = ZIP_OK;
+
+  if(pData == NULL || *dataLen < 4)
+    return ZIP_PARAMERROR;
+
+  pNewHeader = (char*)ALLOC(*dataLen);
+  pTmp = pNewHeader;
+
+  while(p < (pData + *dataLen))
+  {
+    header = *(short*)p;
+    dataSize = *(((short*)p)+1);
+
+    if( header == sHeader ) // Header found.
+    {
+      p += dataSize + 4; // skip it. do not copy to temp buffer
+    }
+    else
+    {
+      // Extra Info block should not be removed, So copy it to the temp buffer.
+      memcpy(pTmp, p, dataSize + 4);
+      p += dataSize + 4;
+      size += dataSize + 4;
+    }
+
+  }
+
+  if(size < *dataLen)
+  {
+    // clean old extra info block.
+    memset(pData,0, *dataLen);
+
+    // copy the new extra info block over the old
+    if(size > 0)
+      memcpy(pData, pNewHeader, size);
+
+    // set the new extra info size
+    *dataLen = size;
+
+    retVal = ZIP_OK;
+  }
+  else
+    retVal = ZIP_ERRNO;
+
+  TRYFREE(pNewHeader);
+
+  return retVal;
+}
diff --git a/compat/zlib/contrib/minizip/zip.h b/compat/zlib/contrib/minizip/zip.h
new file mode 100644
index 0000000..8aaebb6
--- /dev/null
+++ b/compat/zlib/contrib/minizip/zip.h
@@ -0,0 +1,362 @@
+/* zip.h -- IO on .zip files using zlib
+   Version 1.1, February 14h, 2010
+   part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
+
+         Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
+
+         Modifications for Zip64 support
+         Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
+
+         For more info read MiniZip_info.txt
+
+         ---------------------------------------------------------------------------
+
+   Condition of use and distribution are the same than zlib :
+
+  This software is provided 'as-is', without any express or implied
+  warranty.  In no event will the authors be held liable for any damages
+  arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any purpose,
+  including commercial applications, and to alter it and redistribute it
+  freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+
+        ---------------------------------------------------------------------------
+
+        Changes
+
+        See header of zip.h
+
+*/
+
+#ifndef _zip12_H
+#define _zip12_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+//#define HAVE_BZIP2
+
+#ifndef _ZLIB_H
+#include "zlib.h"
+#endif
+
+#ifndef _ZLIBIOAPI_H
+#include "ioapi.h"
+#endif
+
+#ifdef HAVE_BZIP2
+#include "bzlib.h"
+#endif
+
+#define Z_BZIP2ED 12
+
+#if defined(STRICTZIP) || defined(STRICTZIPUNZIP)
+/* like the STRICT of WIN32, we define a pointer that cannot be converted
+    from (void*) without cast */
+typedef struct TagzipFile__ { int unused; } zipFile__;
+typedef zipFile__ *zipFile;
+#else
+typedef voidp zipFile;
+#endif
+
+#define ZIP_OK                          (0)
+#define ZIP_EOF                         (0)
+#define ZIP_ERRNO                       (Z_ERRNO)
+#define ZIP_PARAMERROR                  (-102)
+#define ZIP_BADZIPFILE                  (-103)
+#define ZIP_INTERNALERROR               (-104)
+
+#ifndef DEF_MEM_LEVEL
+#  if MAX_MEM_LEVEL >= 8
+#    define DEF_MEM_LEVEL 8
+#  else
+#    define DEF_MEM_LEVEL  MAX_MEM_LEVEL
+#  endif
+#endif
+/* default memLevel */
+
+/* tm_zip contain date/time info */
+typedef struct tm_zip_s
+{
+    uInt tm_sec;            /* seconds after the minute - [0,59] */
+    uInt tm_min;            /* minutes after the hour - [0,59] */
+    uInt tm_hour;           /* hours since midnight - [0,23] */
+    uInt tm_mday;           /* day of the month - [1,31] */
+    uInt tm_mon;            /* months since January - [0,11] */
+    uInt tm_year;           /* years - [1980..2044] */
+} tm_zip;
+
+typedef struct
+{
+    tm_zip      tmz_date;       /* date in understandable format           */
+    uLong       dosDate;       /* if dos_date == 0, tmu_date is used      */
+/*    uLong       flag;        */   /* general purpose bit flag        2 bytes */
+
+    uLong       internal_fa;    /* internal file attributes        2 bytes */
+    uLong       external_fa;    /* external file attributes        4 bytes */
+} zip_fileinfo;
+
+typedef const char* zipcharpc;
+
+
+#define APPEND_STATUS_CREATE        (0)
+#define APPEND_STATUS_CREATEAFTER   (1)
+#define APPEND_STATUS_ADDINZIP      (2)
+
+extern zipFile ZEXPORT zipOpen OF((const char *pathname, int append));
+extern zipFile ZEXPORT zipOpen64 OF((const void *pathname, int append));
+/*
+  Create a zipfile.
+     pathname contain on Windows XP a filename like "c:\\zlib\\zlib113.zip" or on
+       an Unix computer "zlib/zlib113.zip".
+     if the file pathname exist and append==APPEND_STATUS_CREATEAFTER, the zip
+       will be created at the end of the file.
+         (useful if the file contain a self extractor code)
+     if the file pathname exist and append==APPEND_STATUS_ADDINZIP, we will
+       add files in existing zip (be sure you don't add file that doesn't exist)
+     If the zipfile cannot be opened, the return value is NULL.
+     Else, the return value is a zipFile Handle, usable with other function
+       of this zip package.
+*/
+
+/* Note : there is no delete function into a zipfile.
+   If you want delete file into a zipfile, you must open a zipfile, and create another
+   Of couse, you can use RAW reading and writing to copy the file you did not want delte
+*/
+
+extern zipFile ZEXPORT zipOpen2 OF((const char *pathname,
+                                   int append,
+                                   zipcharpc* globalcomment,
+                                   zlib_filefunc_def* pzlib_filefunc_def));
+
+extern zipFile ZEXPORT zipOpen2_64 OF((const void *pathname,
+                                   int append,
+                                   zipcharpc* globalcomment,
+                                   zlib_filefunc64_def* pzlib_filefunc_def));
+
+extern int ZEXPORT zipOpenNewFileInZip OF((zipFile file,
+                       const char* filename,
+                       const zip_fileinfo* zipfi,
+                       const void* extrafield_local,
+                       uInt size_extrafield_local,
+                       const void* extrafield_global,
+                       uInt size_extrafield_global,
+                       const char* comment,
+                       int method,
+                       int level));
+
+extern int ZEXPORT zipOpenNewFileInZip64 OF((zipFile file,
+                       const char* filename,
+                       const zip_fileinfo* zipfi,
+                       const void* extrafield_local,
+                       uInt size_extrafield_local,
+                       const void* extrafield_global,
+                       uInt size_extrafield_global,
+                       const char* comment,
+                       int method,
+                       int level,
+                       int zip64));
+
+/*
+  Open a file in the ZIP for writing.
+  filename : the filename in zip (if NULL, '-' without quote will be used
+  *zipfi contain supplemental information
+  if extrafield_local!=NULL and size_extrafield_local>0, extrafield_local
+    contains the extrafield data the the local header
+  if extrafield_global!=NULL and size_extrafield_global>0, extrafield_global
+    contains the extrafield data the the local header
+  if comment != NULL, comment contain the comment string
+  method contain the compression method (0 for store, Z_DEFLATED for deflate)
+  level contain the level of compression (can be Z_DEFAULT_COMPRESSION)
+  zip64 is set to 1 if a zip64 extended information block should be added to the local file header.
+                    this MUST be '1' if the uncompressed size is >= 0xffffffff.
+
+*/
+
+
+extern int ZEXPORT zipOpenNewFileInZip2 OF((zipFile file,
+                                            const char* filename,
+                                            const zip_fileinfo* zipfi,
+                                            const void* extrafield_local,
+                                            uInt size_extrafield_local,
+                                            const void* extrafield_global,
+                                            uInt size_extrafield_global,
+                                            const char* comment,
+                                            int method,
+                                            int level,
+                                            int raw));
+
+
+extern int ZEXPORT zipOpenNewFileInZip2_64 OF((zipFile file,
+                                            const char* filename,
+                                            const zip_fileinfo* zipfi,
+                                            const void* extrafield_local,
+                                            uInt size_extrafield_local,
+                                            const void* extrafield_global,
+                                            uInt size_extrafield_global,
+                                            const char* comment,
+                                            int method,
+                                            int level,
+                                            int raw,
+                                            int zip64));
+/*
+  Same than zipOpenNewFileInZip, except if raw=1, we write raw file
+ */
+
+extern int ZEXPORT zipOpenNewFileInZip3 OF((zipFile file,
+                                            const char* filename,
+                                            const zip_fileinfo* zipfi,
+                                            const void* extrafield_local,
+                                            uInt size_extrafield_local,
+                                            const void* extrafield_global,
+                                            uInt size_extrafield_global,
+                                            const char* comment,
+                                            int method,
+                                            int level,
+                                            int raw,
+                                            int windowBits,
+                                            int memLevel,
+                                            int strategy,
+                                            const char* password,
+                                            uLong crcForCrypting));
+
+extern int ZEXPORT zipOpenNewFileInZip3_64 OF((zipFile file,
+                                            const char* filename,
+                                            const zip_fileinfo* zipfi,
+                                            const void* extrafield_local,
+                                            uInt size_extrafield_local,
+                                            const void* extrafield_global,
+                                            uInt size_extrafield_global,
+                                            const char* comment,
+                                            int method,
+                                            int level,
+                                            int raw,
+                                            int windowBits,
+                                            int memLevel,
+                                            int strategy,
+                                            const char* password,
+                                            uLong crcForCrypting,
+                                            int zip64
+                                            ));
+
+/*
+  Same than zipOpenNewFileInZip2, except
+    windowBits,memLevel,,strategy : see parameter strategy in deflateInit2
+    password : crypting password (NULL for no crypting)
+    crcForCrypting : crc of file to compress (needed for crypting)
+ */
+
+extern int ZEXPORT zipOpenNewFileInZip4 OF((zipFile file,
+                                            const char* filename,
+                                            const zip_fileinfo* zipfi,
+                                            const void* extrafield_local,
+                                            uInt size_extrafield_local,
+                                            const void* extrafield_global,
+                                            uInt size_extrafield_global,
+                                            const char* comment,
+                                            int method,
+                                            int level,
+                                            int raw,
+                                            int windowBits,
+                                            int memLevel,
+                                            int strategy,
+                                            const char* password,
+                                            uLong crcForCrypting,
+                                            uLong versionMadeBy,
+                                            uLong flagBase
+                                            ));
+
+
+extern int ZEXPORT zipOpenNewFileInZip4_64 OF((zipFile file,
+                                            const char* filename,
+                                            const zip_fileinfo* zipfi,
+                                            const void* extrafield_local,
+                                            uInt size_extrafield_local,
+                                            const void* extrafield_global,
+                                            uInt size_extrafield_global,
+                                            const char* comment,
+                                            int method,
+                                            int level,
+                                            int raw,
+                                            int windowBits,
+                                            int memLevel,
+                                            int strategy,
+                                            const char* password,
+                                            uLong crcForCrypting,
+                                            uLong versionMadeBy,
+                                            uLong flagBase,
+                                            int zip64
+                                            ));
+/*
+  Same than zipOpenNewFileInZip4, except
+    versionMadeBy : value for Version made by field
+    flag : value for flag field (compression level info will be added)
+ */
+
+
+extern int ZEXPORT zipWriteInFileInZip OF((zipFile file,
+                       const void* buf,
+                       unsigned len));
+/*
+  Write data in the zipfile
+*/
+
+extern int ZEXPORT zipCloseFileInZip OF((zipFile file));
+/*
+  Close the current file in the zipfile
+*/
+
+extern int ZEXPORT zipCloseFileInZipRaw OF((zipFile file,
+                                            uLong uncompressed_size,
+                                            uLong crc32));
+
+extern int ZEXPORT zipCloseFileInZipRaw64 OF((zipFile file,
+                                            ZPOS64_T uncompressed_size,
+                                            uLong crc32));
+
+/*
+  Close the current file in the zipfile, for file opened with
+    parameter raw=1 in zipOpenNewFileInZip2
+  uncompressed_size and crc32 are value for the uncompressed size
+*/
+
+extern int ZEXPORT zipClose OF((zipFile file,
+                const char* global_comment));
+/*
+  Close the zipfile
+*/
+
+
+extern int ZEXPORT zipRemoveExtraInfoBlock OF((char* pData, int* dataLen, short sHeader));
+/*
+  zipRemoveExtraInfoBlock -  Added by Mathias Svensson
+
+  Remove extra information block from a extra information data for the local file header or central directory header
+
+  It is needed to remove ZIP64 extra information blocks when before data is written if using RAW mode.
+
+  0x0001 is the signature header for the ZIP64 extra information blocks
+
+  usage.
+                        Remove ZIP64 Extra information from a central director extra field data
+              zipRemoveExtraInfoBlock(pCenDirExtraFieldData, &nCenDirExtraFieldDataLen, 0x0001);
+
+                        Remove ZIP64 Extra information from a Local File Header extra field data
+        zipRemoveExtraInfoBlock(pLocalHeaderExtraFieldData, &nLocalHeaderExtraFieldDataLen, 0x0001);
+*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _zip64_H */
diff --git a/compat/zlib/contrib/pascal/example.pas b/compat/zlib/contrib/pascal/example.pas
new file mode 100644
index 0000000..5518b36
--- /dev/null
+++ b/compat/zlib/contrib/pascal/example.pas
@@ -0,0 +1,599 @@
+(* example.c -- usage example of the zlib compression library
+ * Copyright (C) 1995-2003 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ *
+ * Pascal translation
+ * Copyright (C) 1998 by Jacques Nomssi Nzali.
+ * For conditions of distribution and use, see copyright notice in readme.txt
+ *
+ * Adaptation to the zlibpas interface
+ * Copyright (C) 2003 by Cosmin Truta.
+ * For conditions of distribution and use, see copyright notice in readme.txt
+ *)
+
+program example;
+
+{$DEFINE TEST_COMPRESS}
+{DO NOT $DEFINE TEST_GZIO}
+{$DEFINE TEST_DEFLATE}
+{$DEFINE TEST_INFLATE}
+{$DEFINE TEST_FLUSH}
+{$DEFINE TEST_SYNC}
+{$DEFINE TEST_DICT}
+
+uses SysUtils, zlibpas;
+
+const TESTFILE = 'foo.gz';
+
+(* "hello world" would be more standard, but the repeated "hello"
+ * stresses the compression code better, sorry...
+ *)
+const hello: PChar = 'hello, hello!';
+
+const dictionary: PChar = 'hello';
+
+var dictId: LongInt; (* Adler32 value of the dictionary *)
+
+procedure CHECK_ERR(err: Integer; msg: String);
+begin
+  if err <> Z_OK then
+  begin
+    WriteLn(msg, ' error: ', err);
+    Halt(1);
+  end;
+end;
+
+procedure EXIT_ERR(const msg: String);
+begin
+  WriteLn('Error: ', msg);
+  Halt(1);
+end;
+
+(* ===========================================================================
+ * Test compress and uncompress
+ *)
+{$IFDEF TEST_COMPRESS}
+procedure test_compress(compr: Pointer; comprLen: LongInt;
+                        uncompr: Pointer; uncomprLen: LongInt);
+var err: Integer;
+    len: LongInt;
+begin
+  len := StrLen(hello)+1;
+
+  err := compress(compr, comprLen, hello, len);
+  CHECK_ERR(err, 'compress');
+
+  StrCopy(PChar(uncompr), 'garbage');
+
+  err := uncompress(uncompr, uncomprLen, compr, comprLen);
+  CHECK_ERR(err, 'uncompress');
+
+  if StrComp(PChar(uncompr), hello) <> 0 then
+    EXIT_ERR('bad uncompress')
+  else
+    WriteLn('uncompress(): ', PChar(uncompr));
+end;
+{$ENDIF}
+
+(* ===========================================================================
+ * Test read/write of .gz files
+ *)
+{$IFDEF TEST_GZIO}
+procedure test_gzio(const fname: PChar; (* compressed file name *)
+                    uncompr: Pointer;
+                    uncomprLen: LongInt);
+var err: Integer;
+    len: Integer;
+    zfile: gzFile;
+    pos: LongInt;
+begin
+  len := StrLen(hello)+1;
+
+  zfile := gzopen(fname, 'wb');
+  if zfile = NIL then
+  begin
+    WriteLn('gzopen error');
+    Halt(1);
+  end;
+  gzputc(zfile, 'h');
+  if gzputs(zfile, 'ello') <> 4 then
+  begin
+    WriteLn('gzputs err: ', gzerror(zfile, err));
+    Halt(1);
+  end;
+  {$IFDEF GZ_FORMAT_STRING}
+  if gzprintf(zfile, ', %s!', 'hello') <> 8 then
+  begin
+    WriteLn('gzprintf err: ', gzerror(zfile, err));
+    Halt(1);
+  end;
+  {$ELSE}
+  if gzputs(zfile, ', hello!') <> 8 then
+  begin
+    WriteLn('gzputs err: ', gzerror(zfile, err));
+    Halt(1);
+  end;
+  {$ENDIF}
+  gzseek(zfile, 1, SEEK_CUR); (* add one zero byte *)
+  gzclose(zfile);
+
+  zfile := gzopen(fname, 'rb');
+  if zfile = NIL then
+  begin
+    WriteLn('gzopen error');
+    Halt(1);
+  end;
+
+  StrCopy(PChar(uncompr), 'garbage');
+
+  if gzread(zfile, uncompr, uncomprLen) <> len then
+  begin
+    WriteLn('gzread err: ', gzerror(zfile, err));
+    Halt(1);
+  end;
+  if StrComp(PChar(uncompr), hello) <> 0 then
+  begin
+    WriteLn('bad gzread: ', PChar(uncompr));
+    Halt(1);
+  end
+  else
+    WriteLn('gzread(): ', PChar(uncompr));
+
+  pos := gzseek(zfile, -8, SEEK_CUR);
+  if (pos <> 6) or (gztell(zfile) <> pos) then
+  begin
+    WriteLn('gzseek error, pos=', pos, ', gztell=', gztell(zfile));
+    Halt(1);
+  end;
+
+  if gzgetc(zfile) <> ' ' then
+  begin
+    WriteLn('gzgetc error');
+    Halt(1);
+  end;
+
+  if gzungetc(' ', zfile) <> ' ' then
+  begin
+    WriteLn('gzungetc error');
+    Halt(1);
+  end;
+
+  gzgets(zfile, PChar(uncompr), uncomprLen);
+  uncomprLen := StrLen(PChar(uncompr));
+  if uncomprLen <> 7 then (* " hello!" *)
+  begin
+    WriteLn('gzgets err after gzseek: ', gzerror(zfile, err));
+    Halt(1);
+  end;
+  if StrComp(PChar(uncompr), hello + 6) <> 0 then
+  begin
+    WriteLn('bad gzgets after gzseek');
+    Halt(1);
+  end
+  else
+    WriteLn('gzgets() after gzseek: ', PChar(uncompr));
+
+  gzclose(zfile);
+end;
+{$ENDIF}
+
+(* ===========================================================================
+ * Test deflate with small buffers
+ *)
+{$IFDEF TEST_DEFLATE}
+procedure test_deflate(compr: Pointer; comprLen: LongInt);
+var c_stream: z_stream; (* compression stream *)
+    err: Integer;
+    len: LongInt;
+begin
+  len := StrLen(hello)+1;
+
+  c_stream.zalloc := NIL;
+  c_stream.zfree := NIL;
+  c_stream.opaque := NIL;
+
+  err := deflateInit(c_stream, Z_DEFAULT_COMPRESSION);
+  CHECK_ERR(err, 'deflateInit');
+
+  c_stream.next_in := hello;
+  c_stream.next_out := compr;
+
+  while (c_stream.total_in <> len) and
+        (c_stream.total_out < comprLen) do
+  begin
+    c_stream.avail_out := 1; { force small buffers }
+    c_stream.avail_in := 1;
+    err := deflate(c_stream, Z_NO_FLUSH);
+    CHECK_ERR(err, 'deflate');
+  end;
+
+  (* Finish the stream, still forcing small buffers: *)
+  while TRUE do
+  begin
+    c_stream.avail_out := 1;
+    err := deflate(c_stream, Z_FINISH);
+    if err = Z_STREAM_END then
+      break;
+    CHECK_ERR(err, 'deflate');
+  end;
+
+  err := deflateEnd(c_stream);
+  CHECK_ERR(err, 'deflateEnd');
+end;
+{$ENDIF}
+
+(* ===========================================================================
+ * Test inflate with small buffers
+ *)
+{$IFDEF TEST_INFLATE}
+procedure test_inflate(compr: Pointer; comprLen : LongInt;
+                       uncompr: Pointer; uncomprLen : LongInt);
+var err: Integer;
+    d_stream: z_stream; (* decompression stream *)
+begin
+  StrCopy(PChar(uncompr), 'garbage');
+
+  d_stream.zalloc := NIL;
+  d_stream.zfree := NIL;
+  d_stream.opaque := NIL;
+
+  d_stream.next_in := compr;
+  d_stream.avail_in := 0;
+  d_stream.next_out := uncompr;
+
+  err := inflateInit(d_stream);
+  CHECK_ERR(err, 'inflateInit');
+
+  while (d_stream.total_out < uncomprLen) and
+        (d_stream.total_in < comprLen) do
+  begin
+    d_stream.avail_out := 1; (* force small buffers *)
+    d_stream.avail_in := 1;
+    err := inflate(d_stream, Z_NO_FLUSH);
+    if err = Z_STREAM_END then
+      break;
+    CHECK_ERR(err, 'inflate');
+  end;
+
+  err := inflateEnd(d_stream);
+  CHECK_ERR(err, 'inflateEnd');
+
+  if StrComp(PChar(uncompr), hello) <> 0 then
+    EXIT_ERR('bad inflate')
+  else
+    WriteLn('inflate(): ', PChar(uncompr));
+end;
+{$ENDIF}
+
+(* ===========================================================================
+ * Test deflate with large buffers and dynamic change of compression level
+ *)
+{$IFDEF TEST_DEFLATE}
+procedure test_large_deflate(compr: Pointer; comprLen: LongInt;
+                             uncompr: Pointer; uncomprLen: LongInt);
+var c_stream: z_stream; (* compression stream *)
+    err: Integer;
+begin
+  c_stream.zalloc := NIL;
+  c_stream.zfree := NIL;
+  c_stream.opaque := NIL;
+
+  err := deflateInit(c_stream, Z_BEST_SPEED);
+  CHECK_ERR(err, 'deflateInit');
+
+  c_stream.next_out := compr;
+  c_stream.avail_out := Integer(comprLen);
+
+  (* At this point, uncompr is still mostly zeroes, so it should compress
+   * very well:
+   *)
+  c_stream.next_in := uncompr;
+  c_stream.avail_in := Integer(uncomprLen);
+  err := deflate(c_stream, Z_NO_FLUSH);
+  CHECK_ERR(err, 'deflate');
+  if c_stream.avail_in <> 0 then
+    EXIT_ERR('deflate not greedy');
+
+  (* Feed in already compressed data and switch to no compression: *)
+  deflateParams(c_stream, Z_NO_COMPRESSION, Z_DEFAULT_STRATEGY);
+  c_stream.next_in := compr;
+  c_stream.avail_in := Integer(comprLen div 2);
+  err := deflate(c_stream, Z_NO_FLUSH);
+  CHECK_ERR(err, 'deflate');
+
+  (* Switch back to compressing mode: *)
+  deflateParams(c_stream, Z_BEST_COMPRESSION, Z_FILTERED);
+  c_stream.next_in := uncompr;
+  c_stream.avail_in := Integer(uncomprLen);
+  err := deflate(c_stream, Z_NO_FLUSH);
+  CHECK_ERR(err, 'deflate');
+
+  err := deflate(c_stream, Z_FINISH);
+  if err <> Z_STREAM_END then
+    EXIT_ERR('deflate should report Z_STREAM_END');
+
+  err := deflateEnd(c_stream);
+  CHECK_ERR(err, 'deflateEnd');
+end;
+{$ENDIF}
+
+(* ===========================================================================
+ * Test inflate with large buffers
+ *)
+{$IFDEF TEST_INFLATE}
+procedure test_large_inflate(compr: Pointer; comprLen: LongInt;
+                             uncompr: Pointer; uncomprLen: LongInt);
+var err: Integer;
+    d_stream: z_stream; (* decompression stream *)
+begin
+  StrCopy(PChar(uncompr), 'garbage');
+
+  d_stream.zalloc := NIL;
+  d_stream.zfree := NIL;
+  d_stream.opaque := NIL;
+
+  d_stream.next_in := compr;
+  d_stream.avail_in := Integer(comprLen);
+
+  err := inflateInit(d_stream);
+  CHECK_ERR(err, 'inflateInit');
+
+  while TRUE do
+  begin
+    d_stream.next_out := uncompr;            (* discard the output *)
+    d_stream.avail_out := Integer(uncomprLen);
+    err := inflate(d_stream, Z_NO_FLUSH);
+    if err = Z_STREAM_END then
+      break;
+    CHECK_ERR(err, 'large inflate');
+  end;
+
+  err := inflateEnd(d_stream);
+  CHECK_ERR(err, 'inflateEnd');
+
+  if d_stream.total_out <> 2 * uncomprLen + comprLen div 2 then
+  begin
+    WriteLn('bad large inflate: ', d_stream.total_out);
+    Halt(1);
+  end
+  else
+    WriteLn('large_inflate(): OK');
+end;
+{$ENDIF}
+
+(* ===========================================================================
+ * Test deflate with full flush
+ *)
+{$IFDEF TEST_FLUSH}
+procedure test_flush(compr: Pointer; var comprLen : LongInt);
+var c_stream: z_stream; (* compression stream *)
+    err: Integer;
+    len: Integer;
+begin
+  len := StrLen(hello)+1;
+
+  c_stream.zalloc := NIL;
+  c_stream.zfree := NIL;
+  c_stream.opaque := NIL;
+
+  err := deflateInit(c_stream, Z_DEFAULT_COMPRESSION);
+  CHECK_ERR(err, 'deflateInit');
+
+  c_stream.next_in := hello;
+  c_stream.next_out := compr;
+  c_stream.avail_in := 3;
+  c_stream.avail_out := Integer(comprLen);
+  err := deflate(c_stream, Z_FULL_FLUSH);
+  CHECK_ERR(err, 'deflate');
+
+  Inc(PByteArray(compr)^[3]); (* force an error in first compressed block *)
+  c_stream.avail_in := len - 3;
+
+  err := deflate(c_stream, Z_FINISH);
+  if err <> Z_STREAM_END then
+    CHECK_ERR(err, 'deflate');
+
+  err := deflateEnd(c_stream);
+  CHECK_ERR(err, 'deflateEnd');
+
+  comprLen := c_stream.total_out;
+end;
+{$ENDIF}
+
+(* ===========================================================================
+ * Test inflateSync()
+ *)
+{$IFDEF TEST_SYNC}
+procedure test_sync(compr: Pointer; comprLen: LongInt;
+                    uncompr: Pointer; uncomprLen : LongInt);
+var err: Integer;
+    d_stream: z_stream; (* decompression stream *)
+begin
+  StrCopy(PChar(uncompr), 'garbage');
+
+  d_stream.zalloc := NIL;
+  d_stream.zfree := NIL;
+  d_stream.opaque := NIL;
+
+  d_stream.next_in := compr;
+  d_stream.avail_in := 2; (* just read the zlib header *)
+
+  err := inflateInit(d_stream);
+  CHECK_ERR(err, 'inflateInit');
+
+  d_stream.next_out := uncompr;
+  d_stream.avail_out := Integer(uncomprLen);
+
+  inflate(d_stream, Z_NO_FLUSH);
+  CHECK_ERR(err, 'inflate');
+
+  d_stream.avail_in := Integer(comprLen-2);   (* read all compressed data *)
+  err := inflateSync(d_stream);               (* but skip the damaged part *)
+  CHECK_ERR(err, 'inflateSync');
+
+  err := inflate(d_stream, Z_FINISH);
+  if err <> Z_DATA_ERROR then
+    EXIT_ERR('inflate should report DATA_ERROR');
+    (* Because of incorrect adler32 *)
+
+  err := inflateEnd(d_stream);
+  CHECK_ERR(err, 'inflateEnd');
+
+  WriteLn('after inflateSync(): hel', PChar(uncompr));
+end;
+{$ENDIF}
+
+(* ===========================================================================
+ * Test deflate with preset dictionary
+ *)
+{$IFDEF TEST_DICT}
+procedure test_dict_deflate(compr: Pointer; comprLen: LongInt);
+var c_stream: z_stream; (* compression stream *)
+    err: Integer;
+begin
+  c_stream.zalloc := NIL;
+  c_stream.zfree := NIL;
+  c_stream.opaque := NIL;
+
+  err := deflateInit(c_stream, Z_BEST_COMPRESSION);
+  CHECK_ERR(err, 'deflateInit');
+
+  err := deflateSetDictionary(c_stream, dictionary, StrLen(dictionary));
+  CHECK_ERR(err, 'deflateSetDictionary');
+
+  dictId := c_stream.adler;
+  c_stream.next_out := compr;
+  c_stream.avail_out := Integer(comprLen);
+
+  c_stream.next_in := hello;
+  c_stream.avail_in := StrLen(hello)+1;
+
+  err := deflate(c_stream, Z_FINISH);
+  if err <> Z_STREAM_END then
+    EXIT_ERR('deflate should report Z_STREAM_END');
+
+  err := deflateEnd(c_stream);
+  CHECK_ERR(err, 'deflateEnd');
+end;
+{$ENDIF}
+
+(* ===========================================================================
+ * Test inflate with a preset dictionary
+ *)
+{$IFDEF TEST_DICT}
+procedure test_dict_inflate(compr: Pointer; comprLen: LongInt;
+                            uncompr: Pointer; uncomprLen: LongInt);
+var err: Integer;
+    d_stream: z_stream; (* decompression stream *)
+begin
+  StrCopy(PChar(uncompr), 'garbage');
+
+  d_stream.zalloc := NIL;
+  d_stream.zfree := NIL;
+  d_stream.opaque := NIL;
+
+  d_stream.next_in := compr;
+  d_stream.avail_in := Integer(comprLen);
+
+  err := inflateInit(d_stream);
+  CHECK_ERR(err, 'inflateInit');
+
+  d_stream.next_out := uncompr;
+  d_stream.avail_out := Integer(uncomprLen);
+
+  while TRUE do
+  begin
+    err := inflate(d_stream, Z_NO_FLUSH);
+    if err = Z_STREAM_END then
+      break;
+    if err = Z_NEED_DICT then
+    begin
+      if d_stream.adler <> dictId then
+        EXIT_ERR('unexpected dictionary');
+      err := inflateSetDictionary(d_stream, dictionary, StrLen(dictionary));
+    end;
+    CHECK_ERR(err, 'inflate with dict');
+  end;
+
+  err := inflateEnd(d_stream);
+  CHECK_ERR(err, 'inflateEnd');
+
+  if StrComp(PChar(uncompr), hello) <> 0 then
+    EXIT_ERR('bad inflate with dict')
+  else
+    WriteLn('inflate with dictionary: ', PChar(uncompr));
+end;
+{$ENDIF}
+
+var compr, uncompr: Pointer;
+    comprLen, uncomprLen: LongInt;
+
+begin
+  if zlibVersion^ <> ZLIB_VERSION[1] then
+    EXIT_ERR('Incompatible zlib version');
+
+  WriteLn('zlib version: ', zlibVersion);
+  WriteLn('zlib compile flags: ', Format('0x%x', [zlibCompileFlags]));
+
+  comprLen := 10000 * SizeOf(Integer); (* don't overflow on MSDOS *)
+  uncomprLen := comprLen;
+  GetMem(compr, comprLen);
+  GetMem(uncompr, uncomprLen);
+  if (compr = NIL) or (uncompr = NIL) then
+    EXIT_ERR('Out of memory');
+  (* compr and uncompr are cleared to avoid reading uninitialized
+   * data and to ensure that uncompr compresses well.
+   *)
+  FillChar(compr^, comprLen, 0);
+  FillChar(uncompr^, uncomprLen, 0);
+
+  {$IFDEF TEST_COMPRESS}
+  WriteLn('** Testing compress');
+  test_compress(compr, comprLen, uncompr, uncomprLen);
+  {$ENDIF}
+
+  {$IFDEF TEST_GZIO}
+  WriteLn('** Testing gzio');
+  if ParamCount >= 1 then
+    test_gzio(ParamStr(1), uncompr, uncomprLen)
+  else
+    test_gzio(TESTFILE, uncompr, uncomprLen);
+  {$ENDIF}
+
+  {$IFDEF TEST_DEFLATE}
+  WriteLn('** Testing deflate with small buffers');
+  test_deflate(compr, comprLen);
+  {$ENDIF}
+  {$IFDEF TEST_INFLATE}
+  WriteLn('** Testing inflate with small buffers');
+  test_inflate(compr, comprLen, uncompr, uncomprLen);
+  {$ENDIF}
+
+  {$IFDEF TEST_DEFLATE}
+  WriteLn('** Testing deflate with large buffers');
+  test_large_deflate(compr, comprLen, uncompr, uncomprLen);
+  {$ENDIF}
+  {$IFDEF TEST_INFLATE}
+  WriteLn('** Testing inflate with large buffers');
+  test_large_inflate(compr, comprLen, uncompr, uncomprLen);
+  {$ENDIF}
+
+  {$IFDEF TEST_FLUSH}
+  WriteLn('** Testing deflate with full flush');
+  test_flush(compr, comprLen);
+  {$ENDIF}
+  {$IFDEF TEST_SYNC}
+  WriteLn('** Testing inflateSync');
+  test_sync(compr, comprLen, uncompr, uncomprLen);
+  {$ENDIF}
+  comprLen := uncomprLen;
+
+  {$IFDEF TEST_DICT}
+  WriteLn('** Testing deflate and inflate with preset dictionary');
+  test_dict_deflate(compr, comprLen);
+  test_dict_inflate(compr, comprLen, uncompr, uncomprLen);
+  {$ENDIF}
+
+  FreeMem(compr, comprLen);
+  FreeMem(uncompr, uncomprLen);
+end.
diff --git a/compat/zlib/contrib/pascal/readme.txt b/compat/zlib/contrib/pascal/readme.txt
new file mode 100644
index 0000000..60e87c8
--- /dev/null
+++ b/compat/zlib/contrib/pascal/readme.txt
@@ -0,0 +1,76 @@
+
+This directory contains a Pascal (Delphi, Kylix) interface to the
+zlib data compression library.
+
+
+Directory listing
+=================
+
+zlibd32.mak     makefile for Borland C++
+example.pas     usage example of zlib
+zlibpas.pas     the Pascal interface to zlib
+readme.txt      this file
+
+
+Compatibility notes
+===================
+
+- Although the name "zlib" would have been more normal for the
+  zlibpas unit, this name is already taken by Borland's ZLib unit.
+  This is somehow unfortunate, because that unit is not a genuine
+  interface to the full-fledged zlib functionality, but a suite of
+  class wrappers around zlib streams.  Other essential features,
+  such as checksums, are missing.
+  It would have been more appropriate for that unit to have a name
+  like "ZStreams", or something similar.
+
+- The C and zlib-supplied types int, uInt, long, uLong, etc. are
+  translated directly into Pascal types of similar sizes (Integer,
+  LongInt, etc.), to avoid namespace pollution.  In particular,
+  there is no conversion of unsigned int into a Pascal unsigned
+  integer.  The Word type is non-portable and has the same size
+  (16 bits) both in a 16-bit and in a 32-bit environment, unlike
+  Integer.  Even if there is a 32-bit Cardinal type, there is no
+  real need for unsigned int in zlib under a 32-bit environment.
+
+- Except for the callbacks, the zlib function interfaces are
+  assuming the calling convention normally used in Pascal
+  (__pascal for DOS and Windows16, __fastcall for Windows32).
+  Since the cdecl keyword is used, the old Turbo Pascal does
+  not work with this interface.
+
+- The gz* function interfaces are not translated, to avoid
+  interfacing problems with the C runtime library.  Besides,
+    gzprintf(gzFile file, const char *format, ...)
+  cannot be translated into Pascal.
+
+
+Legal issues
+============
+
+The zlibpas interface is:
+  Copyright (C) 1995-2003 Jean-loup Gailly and Mark Adler.
+  Copyright (C) 1998 by Bob Dellaca.
+  Copyright (C) 2003 by Cosmin Truta.
+
+The example program is:
+  Copyright (C) 1995-2003 by Jean-loup Gailly.
+  Copyright (C) 1998,1999,2000 by Jacques Nomssi Nzali.
+  Copyright (C) 2003 by Cosmin Truta.
+
+  This software is provided 'as-is', without any express or implied
+  warranty.  In no event will the author be held liable for any damages
+  arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any purpose,
+  including commercial applications, and to alter it and redistribute it
+  freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+
diff --git a/compat/zlib/contrib/pascal/zlibd32.mak b/compat/zlib/contrib/pascal/zlibd32.mak
new file mode 100644
index 0000000..9bb00b7
--- /dev/null
+++ b/compat/zlib/contrib/pascal/zlibd32.mak
@@ -0,0 +1,99 @@
+# Makefile for zlib
+# For use with Delphi and C++ Builder under Win32
+# Updated for zlib 1.2.x by Cosmin Truta
+
+# ------------ Borland C++ ------------
+
+# This project uses the Delphi (fastcall/register) calling convention:
+LOC = -DZEXPORT=__fastcall -DZEXPORTVA=__cdecl
+
+CC = bcc32
+LD = bcc32
+AR = tlib
+# do not use "-pr" in CFLAGS
+CFLAGS = -a -d -k- -O2 $(LOC)
+LDFLAGS =
+
+
+# variables
+ZLIB_LIB = zlib.lib
+
+OBJ1 = adler32.obj compress.obj crc32.obj deflate.obj gzclose.obj gzlib.obj gzread.obj
+OBJ2 = gzwrite.obj infback.obj inffast.obj inflate.obj inftrees.obj trees.obj uncompr.obj zutil.obj
+OBJP1 = +adler32.obj+compress.obj+crc32.obj+deflate.obj+gzclose.obj+gzlib.obj+gzread.obj
+OBJP2 = +gzwrite.obj+infback.obj+inffast.obj+inflate.obj+inftrees.obj+trees.obj+uncompr.obj+zutil.obj
+
+
+# targets
+all: $(ZLIB_LIB) example.exe minigzip.exe
+
+.c.obj:
+	$(CC) -c $(CFLAGS) $*.c
+
+adler32.obj: adler32.c zlib.h zconf.h
+
+compress.obj: compress.c zlib.h zconf.h
+
+crc32.obj: crc32.c zlib.h zconf.h crc32.h
+
+deflate.obj: deflate.c deflate.h zutil.h zlib.h zconf.h
+
+gzclose.obj: gzclose.c zlib.h zconf.h gzguts.h
+
+gzlib.obj: gzlib.c zlib.h zconf.h gzguts.h
+
+gzread.obj: gzread.c zlib.h zconf.h gzguts.h
+
+gzwrite.obj: gzwrite.c zlib.h zconf.h gzguts.h
+
+infback.obj: infback.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
+ inffast.h inffixed.h
+
+inffast.obj: inffast.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
+ inffast.h
+
+inflate.obj: inflate.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
+ inffast.h inffixed.h
+
+inftrees.obj: inftrees.c zutil.h zlib.h zconf.h inftrees.h
+
+trees.obj: trees.c zutil.h zlib.h zconf.h deflate.h trees.h
+
+uncompr.obj: uncompr.c zlib.h zconf.h
+
+zutil.obj: zutil.c zutil.h zlib.h zconf.h
+
+example.obj: test/example.c zlib.h zconf.h
+
+minigzip.obj: test/minigzip.c zlib.h zconf.h
+
+
+# For the sake of the old Borland make,
+# the command line is cut to fit in the MS-DOS 128 byte limit:
+$(ZLIB_LIB): $(OBJ1) $(OBJ2)
+	-del $(ZLIB_LIB)
+	$(AR) $(ZLIB_LIB) $(OBJP1)
+	$(AR) $(ZLIB_LIB) $(OBJP2)
+
+
+# testing
+test: example.exe minigzip.exe
+	example
+	echo hello world | minigzip | minigzip -d
+
+example.exe: example.obj $(ZLIB_LIB)
+	$(LD) $(LDFLAGS) example.obj $(ZLIB_LIB)
+
+minigzip.exe: minigzip.obj $(ZLIB_LIB)
+	$(LD) $(LDFLAGS) minigzip.obj $(ZLIB_LIB)
+
+
+# cleanup
+clean:
+	-del *.obj
+	-del *.exe
+	-del *.lib
+	-del *.tds
+	-del zlib.bak
+	-del foo.gz
+
diff --git a/compat/zlib/contrib/pascal/zlibpas.pas b/compat/zlib/contrib/pascal/zlibpas.pas
new file mode 100644
index 0000000..e6a0782
--- /dev/null
+++ b/compat/zlib/contrib/pascal/zlibpas.pas
@@ -0,0 +1,276 @@
+(* zlibpas -- Pascal interface to the zlib data compression library
+ *
+ * Copyright (C) 2003 Cosmin Truta.
+ * Derived from original sources by Bob Dellaca.
+ * For conditions of distribution and use, see copyright notice in readme.txt
+ *)
+
+unit zlibpas;
+
+interface
+
+const
+  ZLIB_VERSION = '1.2.8';
+  ZLIB_VERNUM  = $1280;
+
+type
+  alloc_func = function(opaque: Pointer; items, size: Integer): Pointer;
+                 cdecl;
+  free_func  = procedure(opaque, address: Pointer);
+                 cdecl;
+
+  in_func    = function(opaque: Pointer; var buf: PByte): Integer;
+                 cdecl;
+  out_func   = function(opaque: Pointer; buf: PByte; size: Integer): Integer;
+                 cdecl;
+
+  z_streamp = ^z_stream;
+  z_stream = packed record
+    next_in: PChar;       (* next input byte *)
+    avail_in: Integer;    (* number of bytes available at next_in *)
+    total_in: LongInt;    (* total nb of input bytes read so far *)
+
+    next_out: PChar;      (* next output byte should be put there *)
+    avail_out: Integer;   (* remaining free space at next_out *)
+    total_out: LongInt;   (* total nb of bytes output so far *)
+
+    msg: PChar;           (* last error message, NULL if no error *)
+    state: Pointer;       (* not visible by applications *)
+
+    zalloc: alloc_func;   (* used to allocate the internal state *)
+    zfree: free_func;     (* used to free the internal state *)
+    opaque: Pointer;      (* private data object passed to zalloc and zfree *)
+
+    data_type: Integer;   (* best guess about the data type: ascii or binary *)
+    adler: LongInt;       (* adler32 value of the uncompressed data *)
+    reserved: LongInt;    (* reserved for future use *)
+  end;
+
+  gz_headerp = ^gz_header;
+  gz_header = packed record
+    text: Integer;        (* true if compressed data believed to be text *)
+    time: LongInt;        (* modification time *)
+    xflags: Integer;      (* extra flags (not used when writing a gzip file) *)
+    os: Integer;          (* operating system *)
+    extra: PChar;         (* pointer to extra field or Z_NULL if none *)
+    extra_len: Integer;   (* extra field length (valid if extra != Z_NULL) *)
+    extra_max: Integer;   (* space at extra (only when reading header) *)
+    name: PChar;          (* pointer to zero-terminated file name or Z_NULL *)
+    name_max: Integer;    (* space at name (only when reading header) *)
+    comment: PChar;       (* pointer to zero-terminated comment or Z_NULL *)
+    comm_max: Integer;    (* space at comment (only when reading header) *)
+    hcrc: Integer;        (* true if there was or will be a header crc *)
+    done: Integer;        (* true when done reading gzip header *)
+  end;
+
+(* constants *)
+const
+  Z_NO_FLUSH      = 0;
+  Z_PARTIAL_FLUSH = 1;
+  Z_SYNC_FLUSH    = 2;
+  Z_FULL_FLUSH    = 3;
+  Z_FINISH        = 4;
+  Z_BLOCK         = 5;
+  Z_TREES         = 6;
+
+  Z_OK            =  0;
+  Z_STREAM_END    =  1;
+  Z_NEED_DICT     =  2;
+  Z_ERRNO         = -1;
+  Z_STREAM_ERROR  = -2;
+  Z_DATA_ERROR    = -3;
+  Z_MEM_ERROR     = -4;
+  Z_BUF_ERROR     = -5;
+  Z_VERSION_ERROR = -6;
+
+  Z_NO_COMPRESSION       =  0;
+  Z_BEST_SPEED           =  1;
+  Z_BEST_COMPRESSION     =  9;
+  Z_DEFAULT_COMPRESSION  = -1;
+
+  Z_FILTERED            = 1;
+  Z_HUFFMAN_ONLY        = 2;
+  Z_RLE                 = 3;
+  Z_FIXED               = 4;
+  Z_DEFAULT_STRATEGY    = 0;
+
+  Z_BINARY   = 0;
+  Z_TEXT     = 1;
+  Z_ASCII    = 1;
+  Z_UNKNOWN  = 2;
+
+  Z_DEFLATED = 8;
+
+(* basic functions *)
+function zlibVersion: PChar;
+function deflateInit(var strm: z_stream; level: Integer): Integer;
+function deflate(var strm: z_stream; flush: Integer): Integer;
+function deflateEnd(var strm: z_stream): Integer;
+function inflateInit(var strm: z_stream): Integer;
+function inflate(var strm: z_stream; flush: Integer): Integer;
+function inflateEnd(var strm: z_stream): Integer;
+
+(* advanced functions *)
+function deflateInit2(var strm: z_stream; level, method, windowBits,
+                      memLevel, strategy: Integer): Integer;
+function deflateSetDictionary(var strm: z_stream; const dictionary: PChar;
+                              dictLength: Integer): Integer;
+function deflateCopy(var dest, source: z_stream): Integer;
+function deflateReset(var strm: z_stream): Integer;
+function deflateParams(var strm: z_stream; level, strategy: Integer): Integer;
+function deflateTune(var strm: z_stream; good_length, max_lazy, nice_length, max_chain: Integer): Integer;
+function deflateBound(var strm: z_stream; sourceLen: LongInt): LongInt;
+function deflatePending(var strm: z_stream; var pending: Integer; var bits: Integer): Integer;
+function deflatePrime(var strm: z_stream; bits, value: Integer): Integer;
+function deflateSetHeader(var strm: z_stream; head: gz_header): Integer;
+function inflateInit2(var strm: z_stream; windowBits: Integer): Integer;
+function inflateSetDictionary(var strm: z_stream; const dictionary: PChar;
+                              dictLength: Integer): Integer;
+function inflateSync(var strm: z_stream): Integer;
+function inflateCopy(var dest, source: z_stream): Integer;
+function inflateReset(var strm: z_stream): Integer;
+function inflateReset2(var strm: z_stream; windowBits: Integer): Integer;
+function inflatePrime(var strm: z_stream; bits, value: Integer): Integer;
+function inflateMark(var strm: z_stream): LongInt;
+function inflateGetHeader(var strm: z_stream; var head: gz_header): Integer;
+function inflateBackInit(var strm: z_stream;
+                         windowBits: Integer; window: PChar): Integer;
+function inflateBack(var strm: z_stream; in_fn: in_func; in_desc: Pointer;
+                     out_fn: out_func; out_desc: Pointer): Integer;
+function inflateBackEnd(var strm: z_stream): Integer;
+function zlibCompileFlags: LongInt;
+
+(* utility functions *)
+function compress(dest: PChar; var destLen: LongInt;
+                  const source: PChar; sourceLen: LongInt): Integer;
+function compress2(dest: PChar; var destLen: LongInt;
+                  const source: PChar; sourceLen: LongInt;
+                  level: Integer): Integer;
+function compressBound(sourceLen: LongInt): LongInt;
+function uncompress(dest: PChar; var destLen: LongInt;
+                    const source: PChar; sourceLen: LongInt): Integer;
+
+(* checksum functions *)
+function adler32(adler: LongInt; const buf: PChar; len: Integer): LongInt;
+function adler32_combine(adler1, adler2, len2: LongInt): LongInt;
+function crc32(crc: LongInt; const buf: PChar; len: Integer): LongInt;
+function crc32_combine(crc1, crc2, len2: LongInt): LongInt;
+
+(* various hacks, don't look :) *)
+function deflateInit_(var strm: z_stream; level: Integer;
+                      const version: PChar; stream_size: Integer): Integer;
+function inflateInit_(var strm: z_stream; const version: PChar;
+                      stream_size: Integer): Integer;
+function deflateInit2_(var strm: z_stream;
+                       level, method, windowBits, memLevel, strategy: Integer;
+                       const version: PChar; stream_size: Integer): Integer;
+function inflateInit2_(var strm: z_stream; windowBits: Integer;
+                       const version: PChar; stream_size: Integer): Integer;
+function inflateBackInit_(var strm: z_stream;
+                          windowBits: Integer; window: PChar;
+                          const version: PChar; stream_size: Integer): Integer;
+
+
+implementation
+
+{$L adler32.obj}
+{$L compress.obj}
+{$L crc32.obj}
+{$L deflate.obj}
+{$L infback.obj}
+{$L inffast.obj}
+{$L inflate.obj}
+{$L inftrees.obj}
+{$L trees.obj}
+{$L uncompr.obj}
+{$L zutil.obj}
+
+function adler32; external;
+function adler32_combine; external;
+function compress; external;
+function compress2; external;
+function compressBound; external;
+function crc32; external;
+function crc32_combine; external;
+function deflate; external;
+function deflateBound; external;
+function deflateCopy; external;
+function deflateEnd; external;
+function deflateInit_; external;
+function deflateInit2_; external;
+function deflateParams; external;
+function deflatePending; external;
+function deflatePrime; external;
+function deflateReset; external;
+function deflateSetDictionary; external;
+function deflateSetHeader; external;
+function deflateTune; external;
+function inflate; external;
+function inflateBack; external;
+function inflateBackEnd; external;
+function inflateBackInit_; external;
+function inflateCopy; external;
+function inflateEnd; external;
+function inflateGetHeader; external;
+function inflateInit_; external;
+function inflateInit2_; external;
+function inflateMark; external;
+function inflatePrime; external;
+function inflateReset; external;
+function inflateReset2; external;
+function inflateSetDictionary; external;
+function inflateSync; external;
+function uncompress; external;
+function zlibCompileFlags; external;
+function zlibVersion; external;
+
+function deflateInit(var strm: z_stream; level: Integer): Integer;
+begin
+  Result := deflateInit_(strm, level, ZLIB_VERSION, sizeof(z_stream));
+end;
+
+function deflateInit2(var strm: z_stream; level, method, windowBits, memLevel,
+                      strategy: Integer): Integer;
+begin
+  Result := deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
+                          ZLIB_VERSION, sizeof(z_stream));
+end;
+
+function inflateInit(var strm: z_stream): Integer;
+begin
+  Result := inflateInit_(strm, ZLIB_VERSION, sizeof(z_stream));
+end;
+
+function inflateInit2(var strm: z_stream; windowBits: Integer): Integer;
+begin
+  Result := inflateInit2_(strm, windowBits, ZLIB_VERSION, sizeof(z_stream));
+end;
+
+function inflateBackInit(var strm: z_stream;
+                         windowBits: Integer; window: PChar): Integer;
+begin
+  Result := inflateBackInit_(strm, windowBits, window,
+                             ZLIB_VERSION, sizeof(z_stream));
+end;
+
+function _malloc(Size: Integer): Pointer; cdecl;
+begin
+  GetMem(Result, Size);
+end;
+
+procedure _free(Block: Pointer); cdecl;
+begin
+  FreeMem(Block);
+end;
+
+procedure _memset(P: Pointer; B: Byte; count: Integer); cdecl;
+begin
+  FillChar(P^, count, B);
+end;
+
+procedure _memcpy(dest, source: Pointer; count: Integer); cdecl;
+begin
+  Move(source^, dest^, count);
+end;
+
+end.
diff --git a/compat/zlib/contrib/puff/Makefile b/compat/zlib/contrib/puff/Makefile
new file mode 100644
index 0000000..0e2594c
--- /dev/null
+++ b/compat/zlib/contrib/puff/Makefile
@@ -0,0 +1,42 @@
+CFLAGS=-O
+
+puff: puff.o pufftest.o
+
+puff.o: puff.h
+
+pufftest.o: puff.h
+
+test: puff
+	puff zeros.raw
+
+puft: puff.c puff.h pufftest.o
+	cc -fprofile-arcs -ftest-coverage -o puft puff.c pufftest.o
+
+# puff full coverage test (should say 100%)
+cov: puft
+	@rm -f *.gcov *.gcda
+	@puft -w zeros.raw 2>&1 | cat > /dev/null
+	@echo '04' | xxd -r -p | puft 2> /dev/null || test $$? -eq 2
+	@echo '00' | xxd -r -p | puft 2> /dev/null || test $$? -eq 2
+	@echo '00 00 00 00 00' | xxd -r -p | puft 2> /dev/null || test $$? -eq 254
+	@echo '00 01 00 fe ff' | xxd -r -p | puft 2> /dev/null || test $$? -eq 2
+	@echo '01 01 00 fe ff 0a' | xxd -r -p | puft -f 2>&1 | cat > /dev/null
+	@echo '02 7e ff ff' | xxd -r -p | puft 2> /dev/null || test $$? -eq 246
+	@echo '02' | xxd -r -p | puft 2> /dev/null || test $$? -eq 2
+	@echo '04 80 49 92 24 49 92 24 0f b4 ff ff c3 04' | xxd -r -p | puft 2> /dev/null || test $$? -eq 2
+	@echo '04 80 49 92 24 49 92 24 71 ff ff 93 11 00' | xxd -r -p | puft 2> /dev/null || test $$? -eq 249
+	@echo '04 c0 81 08 00 00 00 00 20 7f eb 0b 00 00' | xxd -r -p | puft 2> /dev/null || test $$? -eq 246
+	@echo '0b 00 00' | xxd -r -p | puft -f 2>&1 | cat > /dev/null
+	@echo '1a 07' | xxd -r -p | puft 2> /dev/null || test $$? -eq 246
+	@echo '0c c0 81 00 00 00 00 00 90 ff 6b 04' | xxd -r -p | puft 2> /dev/null || test $$? -eq 245
+	@puft -f zeros.raw 2>&1 | cat > /dev/null
+	@echo 'fc 00 00' | xxd -r -p | puft 2> /dev/null || test $$? -eq 253
+	@echo '04 00 fe ff' | xxd -r -p | puft 2> /dev/null || test $$? -eq 252
+	@echo '04 00 24 49' | xxd -r -p | puft 2> /dev/null || test $$? -eq 251
+	@echo '04 80 49 92 24 49 92 24 0f b4 ff ff c3 84' | xxd -r -p | puft 2> /dev/null || test $$? -eq 248
+	@echo '04 00 24 e9 ff ff' | xxd -r -p | puft 2> /dev/null || test $$? -eq 250
+	@echo '04 00 24 e9 ff 6d' | xxd -r -p | puft 2> /dev/null || test $$? -eq 247
+	@gcov -n puff.c
+
+clean:
+	rm -f puff puft *.o *.gc*
diff --git a/compat/zlib/contrib/puff/README b/compat/zlib/contrib/puff/README
new file mode 100644
index 0000000..bbc4cb5
--- /dev/null
+++ b/compat/zlib/contrib/puff/README
@@ -0,0 +1,63 @@
+Puff -- A Simple Inflate
+3 Mar 2003
+Mark Adler
+madler@alumni.caltech.edu
+
+What this is --
+
+puff.c provides the routine puff() to decompress the deflate data format.  It
+does so more slowly than zlib, but the code is about one-fifth the size of the
+inflate code in zlib, and written to be very easy to read.
+
+Why I wrote this --
+
+puff.c was written to document the deflate format unambiguously, by virtue of
+being working C code.  It is meant to supplement RFC 1951, which formally
+describes the deflate format.  I have received many questions on details of the
+deflate format, and I hope that reading this code will answer those questions.
+puff.c is heavily commented with details of the deflate format, especially
+those little nooks and cranies of the format that might not be obvious from a
+specification.
+
+puff.c may also be useful in applications where code size or memory usage is a
+very limited resource, and speed is not as important.
+
+How to use it --
+
+Well, most likely you should just be reading puff.c and using zlib for actual
+applications, but if you must ...
+
+Include puff.h in your code, which provides this prototype:
+
+int puff(unsigned char *dest,           /* pointer to destination pointer */
+         unsigned long *destlen,        /* amount of output space */
+         unsigned char *source,         /* pointer to source data pointer */
+         unsigned long *sourcelen);     /* amount of input available */
+
+Then you can call puff() to decompress a deflate stream that is in memory in
+its entirety at source, to a sufficiently sized block of memory for the
+decompressed data at dest.  puff() is the only external symbol in puff.c  The
+only C library functions that puff.c needs are setjmp() and longjmp(), which
+are used to simplify error checking in the code to improve readabilty.  puff.c
+does no memory allocation, and uses less than 2K bytes off of the stack.
+
+If destlen is not enough space for the uncompressed data, then inflate will
+return an error without writing more than destlen bytes.  Note that this means
+that in order to decompress the deflate data successfully, you need to know
+the size of the uncompressed data ahead of time.
+
+If needed, puff() can determine the size of the uncompressed data with no
+output space.  This is done by passing dest equal to (unsigned char *)0.  Then
+the initial value of *destlen is ignored and *destlen is set to the length of
+the uncompressed data.  So if the size of the uncompressed data is not known,
+then two passes of puff() can be used--first to determine the size, and second
+to do the actual inflation after allocating the appropriate memory.  Not
+pretty, but it works.  (This is one of the reasons you should be using zlib.)
+
+The deflate format is self-terminating.  If the deflate stream does not end
+in *sourcelen bytes, puff() will return an error without reading at or past
+endsource.
+
+On return, *sourcelen is updated to the amount of input data consumed, and
+*destlen is updated to the size of the uncompressed data.  See the comments
+in puff.c for the possible return codes for puff().
diff --git a/compat/zlib/contrib/puff/puff.c b/compat/zlib/contrib/puff/puff.c
new file mode 100644
index 0000000..ba58483
--- /dev/null
+++ b/compat/zlib/contrib/puff/puff.c
@@ -0,0 +1,840 @@
+/*
+ * puff.c
+ * Copyright (C) 2002-2013 Mark Adler
+ * For conditions of distribution and use, see copyright notice in puff.h
+ * version 2.3, 21 Jan 2013
+ *
+ * puff.c is a simple inflate written to be an unambiguous way to specify the
+ * deflate format.  It is not written for speed but rather simplicity.  As a
+ * side benefit, this code might actually be useful when small code is more
+ * important than speed, such as bootstrap applications.  For typical deflate
+ * data, zlib's inflate() is about four times as fast as puff().  zlib's
+ * inflate compiles to around 20K on my machine, whereas puff.c compiles to
+ * around 4K on my machine (a PowerPC using GNU cc).  If the faster decode()
+ * function here is used, then puff() is only twice as slow as zlib's
+ * inflate().
+ *
+ * All dynamically allocated memory comes from the stack.  The stack required
+ * is less than 2K bytes.  This code is compatible with 16-bit int's and
+ * assumes that long's are at least 32 bits.  puff.c uses the short data type,
+ * assumed to be 16 bits, for arrays in order to to conserve memory.  The code
+ * works whether integers are stored big endian or little endian.
+ *
+ * In the comments below are "Format notes" that describe the inflate process
+ * and document some of the less obvious aspects of the format.  This source
+ * code is meant to supplement RFC 1951, which formally describes the deflate
+ * format:
+ *
+ *    http://www.zlib.org/rfc-deflate.html
+ */
+
+/*
+ * Change history:
+ *
+ * 1.0  10 Feb 2002     - First version
+ * 1.1  17 Feb 2002     - Clarifications of some comments and notes
+ *                      - Update puff() dest and source pointers on negative
+ *                        errors to facilitate debugging deflators
+ *                      - Remove longest from struct huffman -- not needed
+ *                      - Simplify offs[] index in construct()
+ *                      - Add input size and checking, using longjmp() to
+ *                        maintain easy readability
+ *                      - Use short data type for large arrays
+ *                      - Use pointers instead of long to specify source and
+ *                        destination sizes to avoid arbitrary 4 GB limits
+ * 1.2  17 Mar 2002     - Add faster version of decode(), doubles speed (!),
+ *                        but leave simple version for readabilty
+ *                      - Make sure invalid distances detected if pointers
+ *                        are 16 bits
+ *                      - Fix fixed codes table error
+ *                      - Provide a scanning mode for determining size of
+ *                        uncompressed data
+ * 1.3  20 Mar 2002     - Go back to lengths for puff() parameters [Gailly]
+ *                      - Add a puff.h file for the interface
+ *                      - Add braces in puff() for else do [Gailly]
+ *                      - Use indexes instead of pointers for readability
+ * 1.4  31 Mar 2002     - Simplify construct() code set check
+ *                      - Fix some comments
+ *                      - Add FIXLCODES #define
+ * 1.5   6 Apr 2002     - Minor comment fixes
+ * 1.6   7 Aug 2002     - Minor format changes
+ * 1.7   3 Mar 2003     - Added test code for distribution
+ *                      - Added zlib-like license
+ * 1.8   9 Jan 2004     - Added some comments on no distance codes case
+ * 1.9  21 Feb 2008     - Fix bug on 16-bit integer architectures [Pohland]
+ *                      - Catch missing end-of-block symbol error
+ * 2.0  25 Jul 2008     - Add #define to permit distance too far back
+ *                      - Add option in TEST code for puff to write the data
+ *                      - Add option in TEST code to skip input bytes
+ *                      - Allow TEST code to read from piped stdin
+ * 2.1   4 Apr 2010     - Avoid variable initialization for happier compilers
+ *                      - Avoid unsigned comparisons for even happier compilers
+ * 2.2  25 Apr 2010     - Fix bug in variable initializations [Oberhumer]
+ *                      - Add const where appropriate [Oberhumer]
+ *                      - Split if's and ?'s for coverage testing
+ *                      - Break out test code to separate file
+ *                      - Move NIL to puff.h
+ *                      - Allow incomplete code only if single code length is 1
+ *                      - Add full code coverage test to Makefile
+ * 2.3  21 Jan 2013     - Check for invalid code length codes in dynamic blocks
+ */
+
+#include <setjmp.h>             /* for setjmp(), longjmp(), and jmp_buf */
+#include "puff.h"               /* prototype for puff() */
+
+#define local static            /* for local function definitions */
+
+/*
+ * Maximums for allocations and loops.  It is not useful to change these --
+ * they are fixed by the deflate format.
+ */
+#define MAXBITS 15              /* maximum bits in a code */
+#define MAXLCODES 286           /* maximum number of literal/length codes */
+#define MAXDCODES 30            /* maximum number of distance codes */
+#define MAXCODES (MAXLCODES+MAXDCODES)  /* maximum codes lengths to read */
+#define FIXLCODES 288           /* number of fixed literal/length codes */
+
+/* input and output state */
+struct state {
+    /* output state */
+    unsigned char *out;         /* output buffer */
+    unsigned long outlen;       /* available space at out */
+    unsigned long outcnt;       /* bytes written to out so far */
+
+    /* input state */
+    const unsigned char *in;    /* input buffer */
+    unsigned long inlen;        /* available input at in */
+    unsigned long incnt;        /* bytes read so far */
+    int bitbuf;                 /* bit buffer */
+    int bitcnt;                 /* number of bits in bit buffer */
+
+    /* input limit error return state for bits() and decode() */
+    jmp_buf env;
+};
+
+/*
+ * Return need bits from the input stream.  This always leaves less than
+ * eight bits in the buffer.  bits() works properly for need == 0.
+ *
+ * Format notes:
+ *
+ * - Bits are stored in bytes from the least significant bit to the most
+ *   significant bit.  Therefore bits are dropped from the bottom of the bit
+ *   buffer, using shift right, and new bytes are appended to the top of the
+ *   bit buffer, using shift left.
+ */
+local int bits(struct state *s, int need)
+{
+    long val;           /* bit accumulator (can use up to 20 bits) */
+
+    /* load at least need bits into val */
+    val = s->bitbuf;
+    while (s->bitcnt < need) {
+        if (s->incnt == s->inlen)
+            longjmp(s->env, 1);         /* out of input */
+        val |= (long)(s->in[s->incnt++]) << s->bitcnt;  /* load eight bits */
+        s->bitcnt += 8;
+    }
+
+    /* drop need bits and update buffer, always zero to seven bits left */
+    s->bitbuf = (int)(val >> need);
+    s->bitcnt -= need;
+
+    /* return need bits, zeroing the bits above that */
+    return (int)(val & ((1L << need) - 1));
+}
+
+/*
+ * Process a stored block.
+ *
+ * Format notes:
+ *
+ * - After the two-bit stored block type (00), the stored block length and
+ *   stored bytes are byte-aligned for fast copying.  Therefore any leftover
+ *   bits in the byte that has the last bit of the type, as many as seven, are
+ *   discarded.  The value of the discarded bits are not defined and should not
+ *   be checked against any expectation.
+ *
+ * - The second inverted copy of the stored block length does not have to be
+ *   checked, but it's probably a good idea to do so anyway.
+ *
+ * - A stored block can have zero length.  This is sometimes used to byte-align
+ *   subsets of the compressed data for random access or partial recovery.
+ */
+local int stored(struct state *s)
+{
+    unsigned len;       /* length of stored block */
+
+    /* discard leftover bits from current byte (assumes s->bitcnt < 8) */
+    s->bitbuf = 0;
+    s->bitcnt = 0;
+
+    /* get length and check against its one's complement */
+    if (s->incnt + 4 > s->inlen)
+        return 2;                               /* not enough input */
+    len = s->in[s->incnt++];
+    len |= s->in[s->incnt++] << 8;
+    if (s->in[s->incnt++] != (~len & 0xff) ||
+        s->in[s->incnt++] != ((~len >> 8) & 0xff))
+        return -2;                              /* didn't match complement! */
+
+    /* copy len bytes from in to out */
+    if (s->incnt + len > s->inlen)
+        return 2;                               /* not enough input */
+    if (s->out != NIL) {
+        if (s->outcnt + len > s->outlen)
+            return 1;                           /* not enough output space */
+        while (len--)
+            s->out[s->outcnt++] = s->in[s->incnt++];
+    }
+    else {                                      /* just scanning */
+        s->outcnt += len;
+        s->incnt += len;
+    }
+
+    /* done with a valid stored block */
+    return 0;
+}
+
+/*
+ * Huffman code decoding tables.  count[1..MAXBITS] is the number of symbols of
+ * each length, which for a canonical code are stepped through in order.
+ * symbol[] are the symbol values in canonical order, where the number of
+ * entries is the sum of the counts in count[].  The decoding process can be
+ * seen in the function decode() below.
+ */
+struct huffman {
+    short *count;       /* number of symbols of each length */
+    short *symbol;      /* canonically ordered symbols */
+};
+
+/*
+ * Decode a code from the stream s using huffman table h.  Return the symbol or
+ * a negative value if there is an error.  If all of the lengths are zero, i.e.
+ * an empty code, or if the code is incomplete and an invalid code is received,
+ * then -10 is returned after reading MAXBITS bits.
+ *
+ * Format notes:
+ *
+ * - The codes as stored in the compressed data are bit-reversed relative to
+ *   a simple integer ordering of codes of the same lengths.  Hence below the
+ *   bits are pulled from the compressed data one at a time and used to
+ *   build the code value reversed from what is in the stream in order to
+ *   permit simple integer comparisons for decoding.  A table-based decoding
+ *   scheme (as used in zlib) does not need to do this reversal.
+ *
+ * - The first code for the shortest length is all zeros.  Subsequent codes of
+ *   the same length are simply integer increments of the previous code.  When
+ *   moving up a length, a zero bit is appended to the code.  For a complete
+ *   code, the last code of the longest length will be all ones.
+ *
+ * - Incomplete codes are handled by this decoder, since they are permitted
+ *   in the deflate format.  See the format notes for fixed() and dynamic().
+ */
+#ifdef SLOW
+local int decode(struct state *s, const struct huffman *h)
+{
+    int len;            /* current number of bits in code */
+    int code;           /* len bits being decoded */
+    int first;          /* first code of length len */
+    int count;          /* number of codes of length len */
+    int index;          /* index of first code of length len in symbol table */
+
+    code = first = index = 0;
+    for (len = 1; len <= MAXBITS; len++) {
+        code |= bits(s, 1);             /* get next bit */
+        count = h->count[len];
+        if (code - count < first)       /* if length len, return symbol */
+            return h->symbol[index + (code - first)];
+        index += count;                 /* else update for next length */
+        first += count;
+        first <<= 1;
+        code <<= 1;
+    }
+    return -10;                         /* ran out of codes */
+}
+
+/*
+ * A faster version of decode() for real applications of this code.   It's not
+ * as readable, but it makes puff() twice as fast.  And it only makes the code
+ * a few percent larger.
+ */
+#else /* !SLOW */
+local int decode(struct state *s, const struct huffman *h)
+{
+    int len;            /* current number of bits in code */
+    int code;           /* len bits being decoded */
+    int first;          /* first code of length len */
+    int count;          /* number of codes of length len */
+    int index;          /* index of first code of length len in symbol table */
+    int bitbuf;         /* bits from stream */
+    int left;           /* bits left in next or left to process */
+    short *next;        /* next number of codes */
+
+    bitbuf = s->bitbuf;
+    left = s->bitcnt;
+    code = first = index = 0;
+    len = 1;
+    next = h->count + 1;
+    while (1) {
+        while (left--) {
+            code |= bitbuf & 1;
+            bitbuf >>= 1;
+            count = *next++;
+            if (code - count < first) { /* if length len, return symbol */
+                s->bitbuf = bitbuf;
+                s->bitcnt = (s->bitcnt - len) & 7;
+                return h->symbol[index + (code - first)];
+            }
+            index += count;             /* else update for next length */
+            first += count;
+            first <<= 1;
+            code <<= 1;
+            len++;
+        }
+        left = (MAXBITS+1) - len;
+        if (left == 0)
+            break;
+        if (s->incnt == s->inlen)
+            longjmp(s->env, 1);         /* out of input */
+        bitbuf = s->in[s->incnt++];
+        if (left > 8)
+            left = 8;
+    }
+    return -10;                         /* ran out of codes */
+}
+#endif /* SLOW */
+
+/*
+ * Given the list of code lengths length[0..n-1] representing a canonical
+ * Huffman code for n symbols, construct the tables required to decode those
+ * codes.  Those tables are the number of codes of each length, and the symbols
+ * sorted by length, retaining their original order within each length.  The
+ * return value is zero for a complete code set, negative for an over-
+ * subscribed code set, and positive for an incomplete code set.  The tables
+ * can be used if the return value is zero or positive, but they cannot be used
+ * if the return value is negative.  If the return value is zero, it is not
+ * possible for decode() using that table to return an error--any stream of
+ * enough bits will resolve to a symbol.  If the return value is positive, then
+ * it is possible for decode() using that table to return an error for received
+ * codes past the end of the incomplete lengths.
+ *
+ * Not used by decode(), but used for error checking, h->count[0] is the number
+ * of the n symbols not in the code.  So n - h->count[0] is the number of
+ * codes.  This is useful for checking for incomplete codes that have more than
+ * one symbol, which is an error in a dynamic block.
+ *
+ * Assumption: for all i in 0..n-1, 0 <= length[i] <= MAXBITS
+ * This is assured by the construction of the length arrays in dynamic() and
+ * fixed() and is not verified by construct().
+ *
+ * Format notes:
+ *
+ * - Permitted and expected examples of incomplete codes are one of the fixed
+ *   codes and any code with a single symbol which in deflate is coded as one
+ *   bit instead of zero bits.  See the format notes for fixed() and dynamic().
+ *
+ * - Within a given code length, the symbols are kept in ascending order for
+ *   the code bits definition.
+ */
+local int construct(struct huffman *h, const short *length, int n)
+{
+    int symbol;         /* current symbol when stepping through length[] */
+    int len;            /* current length when stepping through h->count[] */
+    int left;           /* number of possible codes left of current length */
+    short offs[MAXBITS+1];      /* offsets in symbol table for each length */
+
+    /* count number of codes of each length */
+    for (len = 0; len <= MAXBITS; len++)
+        h->count[len] = 0;
+    for (symbol = 0; symbol < n; symbol++)
+        (h->count[length[symbol]])++;   /* assumes lengths are within bounds */
+    if (h->count[0] == n)               /* no codes! */
+        return 0;                       /* complete, but decode() will fail */
+
+    /* check for an over-subscribed or incomplete set of lengths */
+    left = 1;                           /* one possible code of zero length */
+    for (len = 1; len <= MAXBITS; len++) {
+        left <<= 1;                     /* one more bit, double codes left */
+        left -= h->count[len];          /* deduct count from possible codes */
+        if (left < 0)
+            return left;                /* over-subscribed--return negative */
+    }                                   /* left > 0 means incomplete */
+
+    /* generate offsets into symbol table for each length for sorting */
+    offs[1] = 0;
+    for (len = 1; len < MAXBITS; len++)
+        offs[len + 1] = offs[len] + h->count[len];
+
+    /*
+     * put symbols in table sorted by length, by symbol order within each
+     * length
+     */
+    for (symbol = 0; symbol < n; symbol++)
+        if (length[symbol] != 0)
+            h->symbol[offs[length[symbol]]++] = symbol;
+
+    /* return zero for complete set, positive for incomplete set */
+    return left;
+}
+
+/*
+ * Decode literal/length and distance codes until an end-of-block code.
+ *
+ * Format notes:
+ *
+ * - Compressed data that is after the block type if fixed or after the code
+ *   description if dynamic is a combination of literals and length/distance
+ *   pairs terminated by and end-of-block code.  Literals are simply Huffman
+ *   coded bytes.  A length/distance pair is a coded length followed by a
+ *   coded distance to represent a string that occurs earlier in the
+ *   uncompressed data that occurs again at the current location.
+ *
+ * - Literals, lengths, and the end-of-block code are combined into a single
+ *   code of up to 286 symbols.  They are 256 literals (0..255), 29 length
+ *   symbols (257..285), and the end-of-block symbol (256).
+ *
+ * - There are 256 possible lengths (3..258), and so 29 symbols are not enough
+ *   to represent all of those.  Lengths 3..10 and 258 are in fact represented
+ *   by just a length symbol.  Lengths 11..257 are represented as a symbol and
+ *   some number of extra bits that are added as an integer to the base length
+ *   of the length symbol.  The number of extra bits is determined by the base
+ *   length symbol.  These are in the static arrays below, lens[] for the base
+ *   lengths and lext[] for the corresponding number of extra bits.
+ *
+ * - The reason that 258 gets its own symbol is that the longest length is used
+ *   often in highly redundant files.  Note that 258 can also be coded as the
+ *   base value 227 plus the maximum extra value of 31.  While a good deflate
+ *   should never do this, it is not an error, and should be decoded properly.
+ *
+ * - If a length is decoded, including its extra bits if any, then it is
+ *   followed a distance code.  There are up to 30 distance symbols.  Again
+ *   there are many more possible distances (1..32768), so extra bits are added
+ *   to a base value represented by the symbol.  The distances 1..4 get their
+ *   own symbol, but the rest require extra bits.  The base distances and
+ *   corresponding number of extra bits are below in the static arrays dist[]
+ *   and dext[].
+ *
+ * - Literal bytes are simply written to the output.  A length/distance pair is
+ *   an instruction to copy previously uncompressed bytes to the output.  The
+ *   copy is from distance bytes back in the output stream, copying for length
+ *   bytes.
+ *
+ * - Distances pointing before the beginning of the output data are not
+ *   permitted.
+ *
+ * - Overlapped copies, where the length is greater than the distance, are
+ *   allowed and common.  For example, a distance of one and a length of 258
+ *   simply copies the last byte 258 times.  A distance of four and a length of
+ *   twelve copies the last four bytes three times.  A simple forward copy
+ *   ignoring whether the length is greater than the distance or not implements
+ *   this correctly.  You should not use memcpy() since its behavior is not
+ *   defined for overlapped arrays.  You should not use memmove() or bcopy()
+ *   since though their behavior -is- defined for overlapping arrays, it is
+ *   defined to do the wrong thing in this case.
+ */
+local int codes(struct state *s,
+                const struct huffman *lencode,
+                const struct huffman *distcode)
+{
+    int symbol;         /* decoded symbol */
+    int len;            /* length for copy */
+    unsigned dist;      /* distance for copy */
+    static const short lens[29] = { /* Size base for length codes 257..285 */
+        3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
+        35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258};
+    static const short lext[29] = { /* Extra bits for length codes 257..285 */
+        0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2,
+        3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0};
+    static const short dists[30] = { /* Offset base for distance codes 0..29 */
+        1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
+        257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
+        8193, 12289, 16385, 24577};
+    static const short dext[30] = { /* Extra bits for distance codes 0..29 */
+        0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6,
+        7, 7, 8, 8, 9, 9, 10, 10, 11, 11,
+        12, 12, 13, 13};
+
+    /* decode literals and length/distance pairs */
+    do {
+        symbol = decode(s, lencode);
+        if (symbol < 0)
+            return symbol;              /* invalid symbol */
+        if (symbol < 256) {             /* literal: symbol is the byte */
+            /* write out the literal */
+            if (s->out != NIL) {
+                if (s->outcnt == s->outlen)
+                    return 1;
+                s->out[s->outcnt] = symbol;
+            }
+            s->outcnt++;
+        }
+        else if (symbol > 256) {        /* length */
+            /* get and compute length */
+            symbol -= 257;
+            if (symbol >= 29)
+                return -10;             /* invalid fixed code */
+            len = lens[symbol] + bits(s, lext[symbol]);
+
+            /* get and check distance */
+            symbol = decode(s, distcode);
+            if (symbol < 0)
+                return symbol;          /* invalid symbol */
+            dist = dists[symbol] + bits(s, dext[symbol]);
+#ifndef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
+            if (dist > s->outcnt)
+                return -11;     /* distance too far back */
+#endif
+
+            /* copy length bytes from distance bytes back */
+            if (s->out != NIL) {
+                if (s->outcnt + len > s->outlen)
+                    return 1;
+                while (len--) {
+                    s->out[s->outcnt] =
+#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
+                        dist > s->outcnt ?
+                            0 :
+#endif
+                            s->out[s->outcnt - dist];
+                    s->outcnt++;
+                }
+            }
+            else
+                s->outcnt += len;
+        }
+    } while (symbol != 256);            /* end of block symbol */
+
+    /* done with a valid fixed or dynamic block */
+    return 0;
+}
+
+/*
+ * Process a fixed codes block.
+ *
+ * Format notes:
+ *
+ * - This block type can be useful for compressing small amounts of data for
+ *   which the size of the code descriptions in a dynamic block exceeds the
+ *   benefit of custom codes for that block.  For fixed codes, no bits are
+ *   spent on code descriptions.  Instead the code lengths for literal/length
+ *   codes and distance codes are fixed.  The specific lengths for each symbol
+ *   can be seen in the "for" loops below.
+ *
+ * - The literal/length code is complete, but has two symbols that are invalid
+ *   and should result in an error if received.  This cannot be implemented
+ *   simply as an incomplete code since those two symbols are in the "middle"
+ *   of the code.  They are eight bits long and the longest literal/length\
+ *   code is nine bits.  Therefore the code must be constructed with those
+ *   symbols, and the invalid symbols must be detected after decoding.
+ *
+ * - The fixed distance codes also have two invalid symbols that should result
+ *   in an error if received.  Since all of the distance codes are the same
+ *   length, this can be implemented as an incomplete code.  Then the invalid
+ *   codes are detected while decoding.
+ */
+local int fixed(struct state *s)
+{
+    static int virgin = 1;
+    static short lencnt[MAXBITS+1], lensym[FIXLCODES];
+    static short distcnt[MAXBITS+1], distsym[MAXDCODES];
+    static struct huffman lencode, distcode;
+
+    /* build fixed huffman tables if first call (may not be thread safe) */
+    if (virgin) {
+        int symbol;
+        short lengths[FIXLCODES];
+
+        /* construct lencode and distcode */
+        lencode.count = lencnt;
+        lencode.symbol = lensym;
+        distcode.count = distcnt;
+        distcode.symbol = distsym;
+
+        /* literal/length table */
+        for (symbol = 0; symbol < 144; symbol++)
+            lengths[symbol] = 8;
+        for (; symbol < 256; symbol++)
+            lengths[symbol] = 9;
+        for (; symbol < 280; symbol++)
+            lengths[symbol] = 7;
+        for (; symbol < FIXLCODES; symbol++)
+            lengths[symbol] = 8;
+        construct(&lencode, lengths, FIXLCODES);
+
+        /* distance table */
+        for (symbol = 0; symbol < MAXDCODES; symbol++)
+            lengths[symbol] = 5;
+        construct(&distcode, lengths, MAXDCODES);
+
+        /* do this just once */
+        virgin = 0;
+    }
+
+    /* decode data until end-of-block code */
+    return codes(s, &lencode, &distcode);
+}
+
+/*
+ * Process a dynamic codes block.
+ *
+ * Format notes:
+ *
+ * - A dynamic block starts with a description of the literal/length and
+ *   distance codes for that block.  New dynamic blocks allow the compressor to
+ *   rapidly adapt to changing data with new codes optimized for that data.
+ *
+ * - The codes used by the deflate format are "canonical", which means that
+ *   the actual bits of the codes are generated in an unambiguous way simply
+ *   from the number of bits in each code.  Therefore the code descriptions
+ *   are simply a list of code lengths for each symbol.
+ *
+ * - The code lengths are stored in order for the symbols, so lengths are
+ *   provided for each of the literal/length symbols, and for each of the
+ *   distance symbols.
+ *
+ * - If a symbol is not used in the block, this is represented by a zero as
+ *   as the code length.  This does not mean a zero-length code, but rather
+ *   that no code should be created for this symbol.  There is no way in the
+ *   deflate format to represent a zero-length code.
+ *
+ * - The maximum number of bits in a code is 15, so the possible lengths for
+ *   any code are 1..15.
+ *
+ * - The fact that a length of zero is not permitted for a code has an
+ *   interesting consequence.  Normally if only one symbol is used for a given
+ *   code, then in fact that code could be represented with zero bits.  However
+ *   in deflate, that code has to be at least one bit.  So for example, if
+ *   only a single distance base symbol appears in a block, then it will be
+ *   represented by a single code of length one, in particular one 0 bit.  This
+ *   is an incomplete code, since if a 1 bit is received, it has no meaning,
+ *   and should result in an error.  So incomplete distance codes of one symbol
+ *   should be permitted, and the receipt of invalid codes should be handled.
+ *
+ * - It is also possible to have a single literal/length code, but that code
+ *   must be the end-of-block code, since every dynamic block has one.  This
+ *   is not the most efficient way to create an empty block (an empty fixed
+ *   block is fewer bits), but it is allowed by the format.  So incomplete
+ *   literal/length codes of one symbol should also be permitted.
+ *
+ * - If there are only literal codes and no lengths, then there are no distance
+ *   codes.  This is represented by one distance code with zero bits.
+ *
+ * - The list of up to 286 length/literal lengths and up to 30 distance lengths
+ *   are themselves compressed using Huffman codes and run-length encoding.  In
+ *   the list of code lengths, a 0 symbol means no code, a 1..15 symbol means
+ *   that length, and the symbols 16, 17, and 18 are run-length instructions.
+ *   Each of 16, 17, and 18 are follwed by extra bits to define the length of
+ *   the run.  16 copies the last length 3 to 6 times.  17 represents 3 to 10
+ *   zero lengths, and 18 represents 11 to 138 zero lengths.  Unused symbols
+ *   are common, hence the special coding for zero lengths.
+ *
+ * - The symbols for 0..18 are Huffman coded, and so that code must be
+ *   described first.  This is simply a sequence of up to 19 three-bit values
+ *   representing no code (0) or the code length for that symbol (1..7).
+ *
+ * - A dynamic block starts with three fixed-size counts from which is computed
+ *   the number of literal/length code lengths, the number of distance code
+ *   lengths, and the number of code length code lengths (ok, you come up with
+ *   a better name!) in the code descriptions.  For the literal/length and
+ *   distance codes, lengths after those provided are considered zero, i.e. no
+ *   code.  The code length code lengths are received in a permuted order (see
+ *   the order[] array below) to make a short code length code length list more
+ *   likely.  As it turns out, very short and very long codes are less likely
+ *   to be seen in a dynamic code description, hence what may appear initially
+ *   to be a peculiar ordering.
+ *
+ * - Given the number of literal/length code lengths (nlen) and distance code
+ *   lengths (ndist), then they are treated as one long list of nlen + ndist
+ *   code lengths.  Therefore run-length coding can and often does cross the
+ *   boundary between the two sets of lengths.
+ *
+ * - So to summarize, the code description at the start of a dynamic block is
+ *   three counts for the number of code lengths for the literal/length codes,
+ *   the distance codes, and the code length codes.  This is followed by the
+ *   code length code lengths, three bits each.  This is used to construct the
+ *   code length code which is used to read the remainder of the lengths.  Then
+ *   the literal/length code lengths and distance lengths are read as a single
+ *   set of lengths using the code length codes.  Codes are constructed from
+ *   the resulting two sets of lengths, and then finally you can start
+ *   decoding actual compressed data in the block.
+ *
+ * - For reference, a "typical" size for the code description in a dynamic
+ *   block is around 80 bytes.
+ */
+local int dynamic(struct state *s)
+{
+    int nlen, ndist, ncode;             /* number of lengths in descriptor */
+    int index;                          /* index of lengths[] */
+    int err;                            /* construct() return value */
+    short lengths[MAXCODES];            /* descriptor code lengths */
+    short lencnt[MAXBITS+1], lensym[MAXLCODES];         /* lencode memory */
+    short distcnt[MAXBITS+1], distsym[MAXDCODES];       /* distcode memory */
+    struct huffman lencode, distcode;   /* length and distance codes */
+    static const short order[19] =      /* permutation of code length codes */
+        {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
+
+    /* construct lencode and distcode */
+    lencode.count = lencnt;
+    lencode.symbol = lensym;
+    distcode.count = distcnt;
+    distcode.symbol = distsym;
+
+    /* get number of lengths in each table, check lengths */
+    nlen = bits(s, 5) + 257;
+    ndist = bits(s, 5) + 1;
+    ncode = bits(s, 4) + 4;
+    if (nlen > MAXLCODES || ndist > MAXDCODES)
+        return -3;                      /* bad counts */
+
+    /* read code length code lengths (really), missing lengths are zero */
+    for (index = 0; index < ncode; index++)
+        lengths[order[index]] = bits(s, 3);
+    for (; index < 19; index++)
+        lengths[order[index]] = 0;
+
+    /* build huffman table for code lengths codes (use lencode temporarily) */
+    err = construct(&lencode, lengths, 19);
+    if (err != 0)               /* require complete code set here */
+        return -4;
+
+    /* read length/literal and distance code length tables */
+    index = 0;
+    while (index < nlen + ndist) {
+        int symbol;             /* decoded value */
+        int len;                /* last length to repeat */
+
+        symbol = decode(s, &lencode);
+        if (symbol < 0)
+            return symbol;          /* invalid symbol */
+        if (symbol < 16)                /* length in 0..15 */
+            lengths[index++] = symbol;
+        else {                          /* repeat instruction */
+            len = 0;                    /* assume repeating zeros */
+            if (symbol == 16) {         /* repeat last length 3..6 times */
+                if (index == 0)
+                    return -5;          /* no last length! */
+                len = lengths[index - 1];       /* last length */
+                symbol = 3 + bits(s, 2);
+            }
+            else if (symbol == 17)      /* repeat zero 3..10 times */
+                symbol = 3 + bits(s, 3);
+            else                        /* == 18, repeat zero 11..138 times */
+                symbol = 11 + bits(s, 7);
+            if (index + symbol > nlen + ndist)
+                return -6;              /* too many lengths! */
+            while (symbol--)            /* repeat last or zero symbol times */
+                lengths[index++] = len;
+        }
+    }
+
+    /* check for end-of-block code -- there better be one! */
+    if (lengths[256] == 0)
+        return -9;
+
+    /* build huffman table for literal/length codes */
+    err = construct(&lencode, lengths, nlen);
+    if (err && (err < 0 || nlen != lencode.count[0] + lencode.count[1]))
+        return -7;      /* incomplete code ok only for single length 1 code */
+
+    /* build huffman table for distance codes */
+    err = construct(&distcode, lengths + nlen, ndist);
+    if (err && (err < 0 || ndist != distcode.count[0] + distcode.count[1]))
+        return -8;      /* incomplete code ok only for single length 1 code */
+
+    /* decode data until end-of-block code */
+    return codes(s, &lencode, &distcode);
+}
+
+/*
+ * Inflate source to dest.  On return, destlen and sourcelen are updated to the
+ * size of the uncompressed data and the size of the deflate data respectively.
+ * On success, the return value of puff() is zero.  If there is an error in the
+ * source data, i.e. it is not in the deflate format, then a negative value is
+ * returned.  If there is not enough input available or there is not enough
+ * output space, then a positive error is returned.  In that case, destlen and
+ * sourcelen are not updated to facilitate retrying from the beginning with the
+ * provision of more input data or more output space.  In the case of invalid
+ * inflate data (a negative error), the dest and source pointers are updated to
+ * facilitate the debugging of deflators.
+ *
+ * puff() also has a mode to determine the size of the uncompressed output with
+ * no output written.  For this dest must be (unsigned char *)0.  In this case,
+ * the input value of *destlen is ignored, and on return *destlen is set to the
+ * size of the uncompressed output.
+ *
+ * The return codes are:
+ *
+ *   2:  available inflate data did not terminate
+ *   1:  output space exhausted before completing inflate
+ *   0:  successful inflate
+ *  -1:  invalid block type (type == 3)
+ *  -2:  stored block length did not match one's complement
+ *  -3:  dynamic block code description: too many length or distance codes
+ *  -4:  dynamic block code description: code lengths codes incomplete
+ *  -5:  dynamic block code description: repeat lengths with no first length
+ *  -6:  dynamic block code description: repeat more than specified lengths
+ *  -7:  dynamic block code description: invalid literal/length code lengths
+ *  -8:  dynamic block code description: invalid distance code lengths
+ *  -9:  dynamic block code description: missing end-of-block code
+ * -10:  invalid literal/length or distance code in fixed or dynamic block
+ * -11:  distance is too far back in fixed or dynamic block
+ *
+ * Format notes:
+ *
+ * - Three bits are read for each block to determine the kind of block and
+ *   whether or not it is the last block.  Then the block is decoded and the
+ *   process repeated if it was not the last block.
+ *
+ * - The leftover bits in the last byte of the deflate data after the last
+ *   block (if it was a fixed or dynamic block) are undefined and have no
+ *   expected values to check.
+ */
+int puff(unsigned char *dest,           /* pointer to destination pointer */
+         unsigned long *destlen,        /* amount of output space */
+         const unsigned char *source,   /* pointer to source data pointer */
+         unsigned long *sourcelen)      /* amount of input available */
+{
+    struct state s;             /* input/output state */
+    int last, type;             /* block information */
+    int err;                    /* return value */
+
+    /* initialize output state */
+    s.out = dest;
+    s.outlen = *destlen;                /* ignored if dest is NIL */
+    s.outcnt = 0;
+
+    /* initialize input state */
+    s.in = source;
+    s.inlen = *sourcelen;
+    s.incnt = 0;
+    s.bitbuf = 0;
+    s.bitcnt = 0;
+
+    /* return if bits() or decode() tries to read past available input */
+    if (setjmp(s.env) != 0)             /* if came back here via longjmp() */
+        err = 2;                        /* then skip do-loop, return error */
+    else {
+        /* process blocks until last block or error */
+        do {
+            last = bits(&s, 1);         /* one if last block */
+            type = bits(&s, 2);         /* block type 0..3 */
+            err = type == 0 ?
+                    stored(&s) :
+                    (type == 1 ?
+                        fixed(&s) :
+                        (type == 2 ?
+                            dynamic(&s) :
+                            -1));       /* type == 3, invalid */
+            if (err != 0)
+                break;                  /* return with error */
+        } while (!last);
+    }
+
+    /* update the lengths and return */
+    if (err <= 0) {
+        *destlen = s.outcnt;
+        *sourcelen = s.incnt;
+    }
+    return err;
+}
diff --git a/compat/zlib/contrib/puff/puff.h b/compat/zlib/contrib/puff/puff.h
new file mode 100644
index 0000000..e23a245
--- /dev/null
+++ b/compat/zlib/contrib/puff/puff.h
@@ -0,0 +1,35 @@
+/* puff.h
+  Copyright (C) 2002-2013 Mark Adler, all rights reserved
+  version 2.3, 21 Jan 2013
+
+  This software is provided 'as-is', without any express or implied
+  warranty.  In no event will the author be held liable for any damages
+  arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any purpose,
+  including commercial applications, and to alter it and redistribute it
+  freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+
+  Mark Adler    madler@alumni.caltech.edu
+ */
+
+
+/*
+ * See puff.c for purpose and usage.
+ */
+#ifndef NIL
+#  define NIL ((unsigned char *)0)      /* for no output option */
+#endif
+
+int puff(unsigned char *dest,           /* pointer to destination pointer */
+         unsigned long *destlen,        /* amount of output space */
+         const unsigned char *source,   /* pointer to source data pointer */
+         unsigned long *sourcelen);     /* amount of input available */
diff --git a/compat/zlib/contrib/puff/pufftest.c b/compat/zlib/contrib/puff/pufftest.c
new file mode 100644
index 0000000..7764814
--- /dev/null
+++ b/compat/zlib/contrib/puff/pufftest.c
@@ -0,0 +1,165 @@
+/*
+ * pufftest.c
+ * Copyright (C) 2002-2013 Mark Adler
+ * For conditions of distribution and use, see copyright notice in puff.h
+ * version 2.3, 21 Jan 2013
+ */
+
+/* Example of how to use puff().
+
+   Usage: puff [-w] [-f] [-nnn] file
+          ... | puff [-w] [-f] [-nnn]
+
+   where file is the input file with deflate data, nnn is the number of bytes
+   of input to skip before inflating (e.g. to skip a zlib or gzip header), and
+   -w is used to write the decompressed data to stdout.  -f is for coverage
+   testing, and causes pufftest to fail with not enough output space (-f does
+   a write like -w, so -w is not required). */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "puff.h"
+
+#if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(__CYGWIN__)
+#  include <fcntl.h>
+#  include <io.h>
+#  define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY)
+#else
+#  define SET_BINARY_MODE(file)
+#endif
+
+#define local static
+
+/* Return size times approximately the cube root of 2, keeping the result as 1,
+   3, or 5 times a power of 2 -- the result is always > size, until the result
+   is the maximum value of an unsigned long, where it remains.  This is useful
+   to keep reallocations less than ~33% over the actual data. */
+local size_t bythirds(size_t size)
+{
+    int n;
+    size_t m;
+
+    m = size;
+    for (n = 0; m; n++)
+        m >>= 1;
+    if (n < 3)
+        return size + 1;
+    n -= 3;
+    m = size >> n;
+    m += m == 6 ? 2 : 1;
+    m <<= n;
+    return m > size ? m : (size_t)(-1);
+}
+
+/* Read the input file *name, or stdin if name is NULL, into allocated memory.
+   Reallocate to larger buffers until the entire file is read in.  Return a
+   pointer to the allocated data, or NULL if there was a memory allocation
+   failure.  *len is the number of bytes of data read from the input file (even
+   if load() returns NULL).  If the input file was empty or could not be opened
+   or read, *len is zero. */
+local void *load(const char *name, size_t *len)
+{
+    size_t size;
+    void *buf, *swap;
+    FILE *in;
+
+    *len = 0;
+    buf = malloc(size = 4096);
+    if (buf == NULL)
+        return NULL;
+    in = name == NULL ? stdin : fopen(name, "rb");
+    if (in != NULL) {
+        for (;;) {
+            *len += fread((char *)buf + *len, 1, size - *len, in);
+            if (*len < size) break;
+            size = bythirds(size);
+            if (size == *len || (swap = realloc(buf, size)) == NULL) {
+                free(buf);
+                buf = NULL;
+                break;
+            }
+            buf = swap;
+        }
+        fclose(in);
+    }
+    return buf;
+}
+
+int main(int argc, char **argv)
+{
+    int ret, put = 0, fail = 0;
+    unsigned skip = 0;
+    char *arg, *name = NULL;
+    unsigned char *source = NULL, *dest;
+    size_t len = 0;
+    unsigned long sourcelen, destlen;
+
+    /* process arguments */
+    while (arg = *++argv, --argc)
+        if (arg[0] == '-') {
+            if (arg[1] == 'w' && arg[2] == 0)
+                put = 1;
+            else if (arg[1] == 'f' && arg[2] == 0)
+                fail = 1, put = 1;
+            else if (arg[1] >= '0' && arg[1] <= '9')
+                skip = (unsigned)atoi(arg + 1);
+            else {
+                fprintf(stderr, "invalid option %s\n", arg);
+                return 3;
+            }
+        }
+        else if (name != NULL) {
+            fprintf(stderr, "only one file name allowed\n");
+            return 3;
+        }
+        else
+            name = arg;
+    source = load(name, &len);
+    if (source == NULL) {
+        fprintf(stderr, "memory allocation failure\n");
+        return 4;
+    }
+    if (len == 0) {
+        fprintf(stderr, "could not read %s, or it was empty\n",
+                name == NULL ? "<stdin>" : name);
+        free(source);
+        return 3;
+    }
+    if (skip >= len) {
+        fprintf(stderr, "skip request of %d leaves no input\n", skip);
+        free(source);
+        return 3;
+    }
+
+    /* test inflate data with offset skip */
+    len -= skip;
+    sourcelen = (unsigned long)len;
+    ret = puff(NIL, &destlen, source + skip, &sourcelen);
+    if (ret)
+        fprintf(stderr, "puff() failed with return code %d\n", ret);
+    else {
+        fprintf(stderr, "puff() succeeded uncompressing %lu bytes\n", destlen);
+        if (sourcelen < len) fprintf(stderr, "%lu compressed bytes unused\n",
+                                     len - sourcelen);
+    }
+
+    /* if requested, inflate again and write decompressd data to stdout */
+    if (put && ret == 0) {
+        if (fail)
+            destlen >>= 1;
+        dest = malloc(destlen);
+        if (dest == NULL) {
+            fprintf(stderr, "memory allocation failure\n");
+            free(source);
+            return 4;
+        }
+        puff(dest, &destlen, source + skip, &sourcelen);
+        SET_BINARY_MODE(stdout);
+        fwrite(dest, 1, destlen, stdout);
+        free(dest);
+    }
+
+    /* clean up */
+    free(source);
+    return ret;
+}
diff --git a/compat/zlib/contrib/puff/zeros.raw b/compat/zlib/contrib/puff/zeros.raw
new file mode 100644
index 0000000..0a90e76
Binary files /dev/null and b/compat/zlib/contrib/puff/zeros.raw differ
diff --git a/compat/zlib/contrib/testzlib/testzlib.c b/compat/zlib/contrib/testzlib/testzlib.c
new file mode 100644
index 0000000..5f659de
--- /dev/null
+++ b/compat/zlib/contrib/testzlib/testzlib.c
@@ -0,0 +1,275 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <windows.h>
+
+#include "zlib.h"
+
+
+void MyDoMinus64(LARGE_INTEGER *R,LARGE_INTEGER A,LARGE_INTEGER B)
+{
+    R->HighPart = A.HighPart - B.HighPart;
+    if (A.LowPart >= B.LowPart)
+        R->LowPart = A.LowPart - B.LowPart;
+    else
+    {
+        R->LowPart = A.LowPart - B.LowPart;
+        R->HighPart --;
+    }
+}
+
+#ifdef _M_X64
+// see http://msdn2.microsoft.com/library/twchhe95(en-us,vs.80).aspx for __rdtsc
+unsigned __int64 __rdtsc(void);
+void BeginCountRdtsc(LARGE_INTEGER * pbeginTime64)
+{
+ //   printf("rdtsc = %I64x\n",__rdtsc());
+   pbeginTime64->QuadPart=__rdtsc();
+}
+
+LARGE_INTEGER GetResRdtsc(LARGE_INTEGER beginTime64,BOOL fComputeTimeQueryPerf)
+{
+    LARGE_INTEGER LIres;
+    unsigned _int64 res=__rdtsc()-((unsigned _int64)(beginTime64.QuadPart));
+    LIres.QuadPart=res;
+   // printf("rdtsc = %I64x\n",__rdtsc());
+    return LIres;
+}
+#else
+#ifdef _M_IX86
+void myGetRDTSC32(LARGE_INTEGER * pbeginTime64)
+{
+    DWORD dwEdx,dwEax;
+    _asm
+    {
+        rdtsc
+        mov dwEax,eax
+        mov dwEdx,edx
+    }
+    pbeginTime64->LowPart=dwEax;
+    pbeginTime64->HighPart=dwEdx;
+}
+
+void BeginCountRdtsc(LARGE_INTEGER * pbeginTime64)
+{
+    myGetRDTSC32(pbeginTime64);
+}
+
+LARGE_INTEGER GetResRdtsc(LARGE_INTEGER beginTime64,BOOL fComputeTimeQueryPerf)
+{
+    LARGE_INTEGER LIres,endTime64;
+    myGetRDTSC32(&endTime64);
+
+    LIres.LowPart=LIres.HighPart=0;
+    MyDoMinus64(&LIres,endTime64,beginTime64);
+    return LIres;
+}
+#else
+void myGetRDTSC32(LARGE_INTEGER * pbeginTime64)
+{
+}
+
+void BeginCountRdtsc(LARGE_INTEGER * pbeginTime64)
+{
+}
+
+LARGE_INTEGER GetResRdtsc(LARGE_INTEGER beginTime64,BOOL fComputeTimeQueryPerf)
+{
+    LARGE_INTEGER lr;
+    lr.QuadPart=0;
+    return lr;
+}
+#endif
+#endif
+
+void BeginCountPerfCounter(LARGE_INTEGER * pbeginTime64,BOOL fComputeTimeQueryPerf)
+{
+    if ((!fComputeTimeQueryPerf) || (!QueryPerformanceCounter(pbeginTime64)))
+    {
+        pbeginTime64->LowPart = GetTickCount();
+        pbeginTime64->HighPart = 0;
+    }
+}
+
+DWORD GetMsecSincePerfCounter(LARGE_INTEGER beginTime64,BOOL fComputeTimeQueryPerf)
+{
+    LARGE_INTEGER endTime64,ticksPerSecond,ticks;
+    DWORDLONG ticksShifted,tickSecShifted;
+    DWORD dwLog=16+0;
+    DWORD dwRet;
+    if ((!fComputeTimeQueryPerf) || (!QueryPerformanceCounter(&endTime64)))
+        dwRet = (GetTickCount() - beginTime64.LowPart)*1;
+    else
+    {
+        MyDoMinus64(&ticks,endTime64,beginTime64);
+        QueryPerformanceFrequency(&ticksPerSecond);
+
+
+        {
+            ticksShifted = Int64ShrlMod32(*(DWORDLONG*)&ticks,dwLog);
+            tickSecShifted = Int64ShrlMod32(*(DWORDLONG*)&ticksPerSecond,dwLog);
+
+        }
+
+        dwRet = (DWORD)((((DWORD)ticksShifted)*1000)/(DWORD)(tickSecShifted));
+        dwRet *=1;
+    }
+    return dwRet;
+}
+
+int ReadFileMemory(const char* filename,long* plFileSize,unsigned char** pFilePtr)
+{
+    FILE* stream;
+    unsigned char* ptr;
+    int retVal=1;
+    stream=fopen(filename, "rb");
+    if (stream==NULL)
+        return 0;
+
+    fseek(stream,0,SEEK_END);
+
+    *plFileSize=ftell(stream);
+    fseek(stream,0,SEEK_SET);
+    ptr=malloc((*plFileSize)+1);
+    if (ptr==NULL)
+        retVal=0;
+    else
+    {
+        if (fread(ptr, 1, *plFileSize,stream) != (*plFileSize))
+            retVal=0;
+    }
+    fclose(stream);
+    *pFilePtr=ptr;
+    return retVal;
+}
+
+int main(int argc, char *argv[])
+{
+    int BlockSizeCompress=0x8000;
+    int BlockSizeUncompress=0x8000;
+    int cprLevel=Z_DEFAULT_COMPRESSION ;
+    long lFileSize;
+    unsigned char* FilePtr;
+    long lBufferSizeCpr;
+    long lBufferSizeUncpr;
+    long lCompressedSize=0;
+    unsigned char* CprPtr;
+    unsigned char* UncprPtr;
+    long lSizeCpr,lSizeUncpr;
+    DWORD dwGetTick,dwMsecQP;
+    LARGE_INTEGER li_qp,li_rdtsc,dwResRdtsc;
+
+    if (argc<=1)
+    {
+        printf("run TestZlib <File> [BlockSizeCompress] [BlockSizeUncompress] [compres. level]\n");
+        return 0;
+    }
+
+    if (ReadFileMemory(argv[1],&lFileSize,&FilePtr)==0)
+    {
+        printf("error reading %s\n",argv[1]);
+        return 1;
+    }
+    else printf("file %s read, %u bytes\n",argv[1],lFileSize);
+
+    if (argc>=3)
+        BlockSizeCompress=atol(argv[2]);
+
+    if (argc>=4)
+        BlockSizeUncompress=atol(argv[3]);
+
+    if (argc>=5)
+        cprLevel=(int)atol(argv[4]);
+
+    lBufferSizeCpr = lFileSize + (lFileSize/0x10) + 0x200;
+    lBufferSizeUncpr = lBufferSizeCpr;
+
+    CprPtr=(unsigned char*)malloc(lBufferSizeCpr + BlockSizeCompress);
+
+    BeginCountPerfCounter(&li_qp,TRUE);
+    dwGetTick=GetTickCount();
+    BeginCountRdtsc(&li_rdtsc);
+    {
+        z_stream zcpr;
+        int ret=Z_OK;
+        long lOrigToDo = lFileSize;
+        long lOrigDone = 0;
+        int step=0;
+        memset(&zcpr,0,sizeof(z_stream));
+        deflateInit(&zcpr,cprLevel);
+
+        zcpr.next_in = FilePtr;
+        zcpr.next_out = CprPtr;
+
+
+        do
+        {
+            long all_read_before = zcpr.total_in;
+            zcpr.avail_in = min(lOrigToDo,BlockSizeCompress);
+            zcpr.avail_out = BlockSizeCompress;
+            ret=deflate(&zcpr,(zcpr.avail_in==lOrigToDo) ? Z_FINISH : Z_SYNC_FLUSH);
+            lOrigDone += (zcpr.total_in-all_read_before);
+            lOrigToDo -= (zcpr.total_in-all_read_before);
+            step++;
+        } while (ret==Z_OK);
+
+        lSizeCpr=zcpr.total_out;
+        deflateEnd(&zcpr);
+        dwGetTick=GetTickCount()-dwGetTick;
+        dwMsecQP=GetMsecSincePerfCounter(li_qp,TRUE);
+        dwResRdtsc=GetResRdtsc(li_rdtsc,TRUE);
+        printf("total compress size = %u, in %u step\n",lSizeCpr,step);
+        printf("time = %u msec = %f sec\n",dwGetTick,dwGetTick/(double)1000.);
+        printf("defcpr time QP = %u msec = %f sec\n",dwMsecQP,dwMsecQP/(double)1000.);
+        printf("defcpr result rdtsc = %I64x\n\n",dwResRdtsc.QuadPart);
+    }
+
+    CprPtr=(unsigned char*)realloc(CprPtr,lSizeCpr);
+    UncprPtr=(unsigned char*)malloc(lBufferSizeUncpr + BlockSizeUncompress);
+
+    BeginCountPerfCounter(&li_qp,TRUE);
+    dwGetTick=GetTickCount();
+    BeginCountRdtsc(&li_rdtsc);
+    {
+        z_stream zcpr;
+        int ret=Z_OK;
+        long lOrigToDo = lSizeCpr;
+        long lOrigDone = 0;
+        int step=0;
+        memset(&zcpr,0,sizeof(z_stream));
+        inflateInit(&zcpr);
+
+        zcpr.next_in = CprPtr;
+        zcpr.next_out = UncprPtr;
+
+
+        do
+        {
+            long all_read_before = zcpr.total_in;
+            zcpr.avail_in = min(lOrigToDo,BlockSizeUncompress);
+            zcpr.avail_out = BlockSizeUncompress;
+            ret=inflate(&zcpr,Z_SYNC_FLUSH);
+            lOrigDone += (zcpr.total_in-all_read_before);
+            lOrigToDo -= (zcpr.total_in-all_read_before);
+            step++;
+        } while (ret==Z_OK);
+
+        lSizeUncpr=zcpr.total_out;
+        inflateEnd(&zcpr);
+        dwGetTick=GetTickCount()-dwGetTick;
+        dwMsecQP=GetMsecSincePerfCounter(li_qp,TRUE);
+        dwResRdtsc=GetResRdtsc(li_rdtsc,TRUE);
+        printf("total uncompress size = %u, in %u step\n",lSizeUncpr,step);
+        printf("time = %u msec = %f sec\n",dwGetTick,dwGetTick/(double)1000.);
+        printf("uncpr  time QP = %u msec = %f sec\n",dwMsecQP,dwMsecQP/(double)1000.);
+        printf("uncpr  result rdtsc = %I64x\n\n",dwResRdtsc.QuadPart);
+    }
+
+    if (lSizeUncpr==lFileSize)
+    {
+        if (memcmp(FilePtr,UncprPtr,lFileSize)==0)
+            printf("compare ok\n");
+
+    }
+
+    return 0;
+}
diff --git a/compat/zlib/contrib/testzlib/testzlib.txt b/compat/zlib/contrib/testzlib/testzlib.txt
new file mode 100644
index 0000000..62258f1
--- /dev/null
+++ b/compat/zlib/contrib/testzlib/testzlib.txt
@@ -0,0 +1,10 @@
+To build testzLib with Visual Studio 2005:
+
+copy to a directory file from :
+- root of zLib tree
+- contrib/testzlib
+- contrib/masmx86
+- contrib/masmx64
+- contrib/vstudio/vc7
+
+and open testzlib8.sln
\ No newline at end of file
diff --git a/compat/zlib/contrib/untgz/Makefile b/compat/zlib/contrib/untgz/Makefile
new file mode 100644
index 0000000..b54266f
--- /dev/null
+++ b/compat/zlib/contrib/untgz/Makefile
@@ -0,0 +1,14 @@
+CC=cc
+CFLAGS=-g
+
+untgz: untgz.o ../../libz.a
+	$(CC) $(CFLAGS) -o untgz untgz.o -L../.. -lz
+
+untgz.o: untgz.c ../../zlib.h
+	$(CC) $(CFLAGS) -c -I../.. untgz.c
+
+../../libz.a:
+	cd ../..; ./configure; make
+
+clean:
+	rm -f untgz untgz.o *~
diff --git a/compat/zlib/contrib/untgz/Makefile.msc b/compat/zlib/contrib/untgz/Makefile.msc
new file mode 100644
index 0000000..77b8602
--- /dev/null
+++ b/compat/zlib/contrib/untgz/Makefile.msc
@@ -0,0 +1,17 @@
+CC=cl
+CFLAGS=-MD
+
+untgz.exe: untgz.obj ..\..\zlib.lib
+	$(CC) $(CFLAGS) untgz.obj ..\..\zlib.lib
+
+untgz.obj: untgz.c ..\..\zlib.h
+	$(CC) $(CFLAGS) -c -I..\.. untgz.c
+
+..\..\zlib.lib:
+	cd ..\..
+	$(MAKE) -f win32\makefile.msc
+	cd contrib\untgz
+
+clean:
+	-del untgz.obj
+	-del untgz.exe
diff --git a/compat/zlib/contrib/untgz/untgz.c b/compat/zlib/contrib/untgz/untgz.c
new file mode 100644
index 0000000..2c391e5
--- /dev/null
+++ b/compat/zlib/contrib/untgz/untgz.c
@@ -0,0 +1,674 @@
+/*
+ * untgz.c -- Display contents and extract files from a gzip'd TAR file
+ *
+ * written by Pedro A. Aranda Gutierrez <paag@tid.es>
+ * adaptation to Unix by Jean-loup Gailly <jloup@gzip.org>
+ * various fixes by Cosmin Truta <cosmint@cs.ubbcluj.ro>
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <errno.h>
+
+#include "zlib.h"
+
+#ifdef unix
+#  include <unistd.h>
+#else
+#  include <direct.h>
+#  include <io.h>
+#endif
+
+#ifdef WIN32
+#include <windows.h>
+#  ifndef F_OK
+#    define F_OK  0
+#  endif
+#  define mkdir(dirname,mode)   _mkdir(dirname)
+#  ifdef _MSC_VER
+#    define access(path,mode)   _access(path,mode)
+#    define chmod(path,mode)    _chmod(path,mode)
+#    define strdup(str)         _strdup(str)
+#  endif
+#else
+#  include <utime.h>
+#endif
+
+
+/* values used in typeflag field */
+
+#define REGTYPE  '0'            /* regular file */
+#define AREGTYPE '\0'           /* regular file */
+#define LNKTYPE  '1'            /* link */
+#define SYMTYPE  '2'            /* reserved */
+#define CHRTYPE  '3'            /* character special */
+#define BLKTYPE  '4'            /* block special */
+#define DIRTYPE  '5'            /* directory */
+#define FIFOTYPE '6'            /* FIFO special */
+#define CONTTYPE '7'            /* reserved */
+
+/* GNU tar extensions */
+
+#define GNUTYPE_DUMPDIR  'D'    /* file names from dumped directory */
+#define GNUTYPE_LONGLINK 'K'    /* long link name */
+#define GNUTYPE_LONGNAME 'L'    /* long file name */
+#define GNUTYPE_MULTIVOL 'M'    /* continuation of file from another volume */
+#define GNUTYPE_NAMES    'N'    /* file name that does not fit into main hdr */
+#define GNUTYPE_SPARSE   'S'    /* sparse file */
+#define GNUTYPE_VOLHDR   'V'    /* tape/volume header */
+
+
+/* tar header */
+
+#define BLOCKSIZE     512
+#define SHORTNAMESIZE 100
+
+struct tar_header
+{                               /* byte offset */
+  char name[100];               /*   0 */
+  char mode[8];                 /* 100 */
+  char uid[8];                  /* 108 */
+  char gid[8];                  /* 116 */
+  char size[12];                /* 124 */
+  char mtime[12];               /* 136 */
+  char chksum[8];               /* 148 */
+  char typeflag;                /* 156 */
+  char linkname[100];           /* 157 */
+  char magic[6];                /* 257 */
+  char version[2];              /* 263 */
+  char uname[32];               /* 265 */
+  char gname[32];               /* 297 */
+  char devmajor[8];             /* 329 */
+  char devminor[8];             /* 337 */
+  char prefix[155];             /* 345 */
+                                /* 500 */
+};
+
+union tar_buffer
+{
+  char               buffer[BLOCKSIZE];
+  struct tar_header  header;
+};
+
+struct attr_item
+{
+  struct attr_item  *next;
+  char              *fname;
+  int                mode;
+  time_t             time;
+};
+
+enum { TGZ_EXTRACT, TGZ_LIST, TGZ_INVALID };
+
+char *TGZfname          OF((const char *));
+void TGZnotfound        OF((const char *));
+
+int getoct              OF((char *, int));
+char *strtime           OF((time_t *));
+int setfiletime         OF((char *, time_t));
+void push_attr          OF((struct attr_item **, char *, int, time_t));
+void restore_attr       OF((struct attr_item **));
+
+int ExprMatch           OF((char *, char *));
+
+int makedir             OF((char *));
+int matchname           OF((int, int, char **, char *));
+
+void error              OF((const char *));
+int tar                 OF((gzFile, int, int, int, char **));
+
+void help               OF((int));
+int main                OF((int, char **));
+
+char *prog;
+
+const char *TGZsuffix[] = { "\0", ".tar", ".tar.gz", ".taz", ".tgz", NULL };
+
+/* return the file name of the TGZ archive */
+/* or NULL if it does not exist */
+
+char *TGZfname (const char *arcname)
+{
+  static char buffer[1024];
+  int origlen,i;
+
+  strcpy(buffer,arcname);
+  origlen = strlen(buffer);
+
+  for (i=0; TGZsuffix[i]; i++)
+    {
+       strcpy(buffer+origlen,TGZsuffix[i]);
+       if (access(buffer,F_OK) == 0)
+         return buffer;
+    }
+  return NULL;
+}
+
+
+/* error message for the filename */
+
+void TGZnotfound (const char *arcname)
+{
+  int i;
+
+  fprintf(stderr,"%s: Couldn't find ",prog);
+  for (i=0;TGZsuffix[i];i++)
+    fprintf(stderr,(TGZsuffix[i+1]) ? "%s%s, " : "or %s%s\n",
+            arcname,
+            TGZsuffix[i]);
+  exit(1);
+}
+
+
+/* convert octal digits to int */
+/* on error return -1 */
+
+int getoct (char *p,int width)
+{
+  int result = 0;
+  char c;
+
+  while (width--)
+    {
+      c = *p++;
+      if (c == 0)
+        break;
+      if (c == ' ')
+        continue;
+      if (c < '0' || c > '7')
+        return -1;
+      result = result * 8 + (c - '0');
+    }
+  return result;
+}
+
+
+/* convert time_t to string */
+/* use the "YYYY/MM/DD hh:mm:ss" format */
+
+char *strtime (time_t *t)
+{
+  struct tm   *local;
+  static char result[32];
+
+  local = localtime(t);
+  sprintf(result,"%4d/%02d/%02d %02d:%02d:%02d",
+          local->tm_year+1900, local->tm_mon+1, local->tm_mday,
+          local->tm_hour, local->tm_min, local->tm_sec);
+  return result;
+}
+
+
+/* set file time */
+
+int setfiletime (char *fname,time_t ftime)
+{
+#ifdef WIN32
+  static int isWinNT = -1;
+  SYSTEMTIME st;
+  FILETIME locft, modft;
+  struct tm *loctm;
+  HANDLE hFile;
+  int result;
+
+  loctm = localtime(&ftime);
+  if (loctm == NULL)
+    return -1;
+
+  st.wYear         = (WORD)loctm->tm_year + 1900;
+  st.wMonth        = (WORD)loctm->tm_mon + 1;
+  st.wDayOfWeek    = (WORD)loctm->tm_wday;
+  st.wDay          = (WORD)loctm->tm_mday;
+  st.wHour         = (WORD)loctm->tm_hour;
+  st.wMinute       = (WORD)loctm->tm_min;
+  st.wSecond       = (WORD)loctm->tm_sec;
+  st.wMilliseconds = 0;
+  if (!SystemTimeToFileTime(&st, &locft) ||
+      !LocalFileTimeToFileTime(&locft, &modft))
+    return -1;
+
+  if (isWinNT < 0)
+    isWinNT = (GetVersion() < 0x80000000) ? 1 : 0;
+  hFile = CreateFile(fname, GENERIC_WRITE, 0, NULL, OPEN_EXISTING,
+                     (isWinNT ? FILE_FLAG_BACKUP_SEMANTICS : 0),
+                     NULL);
+  if (hFile == INVALID_HANDLE_VALUE)
+    return -1;
+  result = SetFileTime(hFile, NULL, NULL, &modft) ? 0 : -1;
+  CloseHandle(hFile);
+  return result;
+#else
+  struct utimbuf settime;
+
+  settime.actime = settime.modtime = ftime;
+  return utime(fname,&settime);
+#endif
+}
+
+
+/* push file attributes */
+
+void push_attr(struct attr_item **list,char *fname,int mode,time_t time)
+{
+  struct attr_item *item;
+
+  item = (struct attr_item *)malloc(sizeof(struct attr_item));
+  if (item == NULL)
+    error("Out of memory");
+  item->fname = strdup(fname);
+  item->mode  = mode;
+  item->time  = time;
+  item->next  = *list;
+  *list       = item;
+}
+
+
+/* restore file attributes */
+
+void restore_attr(struct attr_item **list)
+{
+  struct attr_item *item, *prev;
+
+  for (item = *list; item != NULL; )
+    {
+      setfiletime(item->fname,item->time);
+      chmod(item->fname,item->mode);
+      prev = item;
+      item = item->next;
+      free(prev);
+    }
+  *list = NULL;
+}
+
+
+/* match regular expression */
+
+#define ISSPECIAL(c) (((c) == '*') || ((c) == '/'))
+
+int ExprMatch (char *string,char *expr)
+{
+  while (1)
+    {
+      if (ISSPECIAL(*expr))
+        {
+          if (*expr == '/')
+            {
+              if (*string != '\\' && *string != '/')
+                return 0;
+              string ++; expr++;
+            }
+          else if (*expr == '*')
+            {
+              if (*expr ++ == 0)
+                return 1;
+              while (*++string != *expr)
+                if (*string == 0)
+                  return 0;
+            }
+        }
+      else
+        {
+          if (*string != *expr)
+            return 0;
+          if (*expr++ == 0)
+            return 1;
+          string++;
+        }
+    }
+}
+
+
+/* recursive mkdir */
+/* abort on ENOENT; ignore other errors like "directory already exists" */
+/* return 1 if OK */
+/*        0 on error */
+
+int makedir (char *newdir)
+{
+  char *buffer = strdup(newdir);
+  char *p;
+  int  len = strlen(buffer);
+
+  if (len <= 0) {
+    free(buffer);
+    return 0;
+  }
+  if (buffer[len-1] == '/') {
+    buffer[len-1] = '\0';
+  }
+  if (mkdir(buffer, 0755) == 0)
+    {
+      free(buffer);
+      return 1;
+    }
+
+  p = buffer+1;
+  while (1)
+    {
+      char hold;
+
+      while(*p && *p != '\\' && *p != '/')
+        p++;
+      hold = *p;
+      *p = 0;
+      if ((mkdir(buffer, 0755) == -1) && (errno == ENOENT))
+        {
+          fprintf(stderr,"%s: Couldn't create directory %s\n",prog,buffer);
+          free(buffer);
+          return 0;
+        }
+      if (hold == 0)
+        break;
+      *p++ = hold;
+    }
+  free(buffer);
+  return 1;
+}
+
+
+int matchname (int arg,int argc,char **argv,char *fname)
+{
+  if (arg == argc)      /* no arguments given (untgz tgzarchive) */
+    return 1;
+
+  while (arg < argc)
+    if (ExprMatch(fname,argv[arg++]))
+      return 1;
+
+  return 0; /* ignore this for the moment being */
+}
+
+
+/* tar file list or extract */
+
+int tar (gzFile in,int action,int arg,int argc,char **argv)
+{
+  union  tar_buffer buffer;
+  int    len;
+  int    err;
+  int    getheader = 1;
+  int    remaining = 0;
+  FILE   *outfile = NULL;
+  char   fname[BLOCKSIZE];
+  int    tarmode;
+  time_t tartime;
+  struct attr_item *attributes = NULL;
+
+  if (action == TGZ_LIST)
+    printf("    date      time     size                       file\n"
+           " ---------- -------- --------- -------------------------------------\n");
+  while (1)
+    {
+      len = gzread(in, &buffer, BLOCKSIZE);
+      if (len < 0)
+        error(gzerror(in, &err));
+      /*
+       * Always expect complete blocks to process
+       * the tar information.
+       */
+      if (len != BLOCKSIZE)
+        {
+          action = TGZ_INVALID; /* force error exit */
+          remaining = 0;        /* force I/O cleanup */
+        }
+
+      /*
+       * If we have to get a tar header
+       */
+      if (getheader >= 1)
+        {
+          /*
+           * if we met the end of the tar
+           * or the end-of-tar block,
+           * we are done
+           */
+          if (len == 0 || buffer.header.name[0] == 0)
+            break;
+
+          tarmode = getoct(buffer.header.mode,8);
+          tartime = (time_t)getoct(buffer.header.mtime,12);
+          if (tarmode == -1 || tartime == (time_t)-1)
+            {
+              buffer.header.name[0] = 0;
+              action = TGZ_INVALID;
+            }
+
+          if (getheader == 1)
+            {
+              strncpy(fname,buffer.header.name,SHORTNAMESIZE);
+              if (fname[SHORTNAMESIZE-1] != 0)
+                  fname[SHORTNAMESIZE] = 0;
+            }
+          else
+            {
+              /*
+               * The file name is longer than SHORTNAMESIZE
+               */
+              if (strncmp(fname,buffer.header.name,SHORTNAMESIZE-1) != 0)
+                  error("bad long name");
+              getheader = 1;
+            }
+
+          /*
+           * Act according to the type flag
+           */
+          switch (buffer.header.typeflag)
+            {
+            case DIRTYPE:
+              if (action == TGZ_LIST)
+                printf(" %s     <dir> %s\n",strtime(&tartime),fname);
+              if (action == TGZ_EXTRACT)
+                {
+                  makedir(fname);
+                  push_attr(&attributes,fname,tarmode,tartime);
+                }
+              break;
+            case REGTYPE:
+            case AREGTYPE:
+              remaining = getoct(buffer.header.size,12);
+              if (remaining == -1)
+                {
+                  action = TGZ_INVALID;
+                  break;
+                }
+              if (action == TGZ_LIST)
+                printf(" %s %9d %s\n",strtime(&tartime),remaining,fname);
+              else if (action == TGZ_EXTRACT)
+                {
+                  if (matchname(arg,argc,argv,fname))
+                    {
+                      outfile = fopen(fname,"wb");
+                      if (outfile == NULL) {
+                        /* try creating directory */
+                        char *p = strrchr(fname, '/');
+                        if (p != NULL) {
+                          *p = '\0';
+                          makedir(fname);
+                          *p = '/';
+                          outfile = fopen(fname,"wb");
+                        }
+                      }
+                      if (outfile != NULL)
+                        printf("Extracting %s\n",fname);
+                      else
+                        fprintf(stderr, "%s: Couldn't create %s",prog,fname);
+                    }
+                  else
+                    outfile = NULL;
+                }
+              getheader = 0;
+              break;
+            case GNUTYPE_LONGLINK:
+            case GNUTYPE_LONGNAME:
+              remaining = getoct(buffer.header.size,12);
+              if (remaining < 0 || remaining >= BLOCKSIZE)
+                {
+                  action = TGZ_INVALID;
+                  break;
+                }
+              len = gzread(in, fname, BLOCKSIZE);
+              if (len < 0)
+                error(gzerror(in, &err));
+              if (fname[BLOCKSIZE-1] != 0 || (int)strlen(fname) > remaining)
+                {
+                  action = TGZ_INVALID;
+                  break;
+                }
+              getheader = 2;
+              break;
+            default:
+              if (action == TGZ_LIST)
+                printf(" %s     <---> %s\n",strtime(&tartime),fname);
+              break;
+            }
+        }
+      else
+        {
+          unsigned int bytes = (remaining > BLOCKSIZE) ? BLOCKSIZE : remaining;
+
+          if (outfile != NULL)
+            {
+              if (fwrite(&buffer,sizeof(char),bytes,outfile) != bytes)
+                {
+                  fprintf(stderr,
+                    "%s: Error writing %s -- skipping\n",prog,fname);
+                  fclose(outfile);
+                  outfile = NULL;
+                  remove(fname);
+                }
+            }
+          remaining -= bytes;
+        }
+
+      if (remaining == 0)
+        {
+          getheader = 1;
+          if (outfile != NULL)
+            {
+              fclose(outfile);
+              outfile = NULL;
+              if (action != TGZ_INVALID)
+                push_attr(&attributes,fname,tarmode,tartime);
+            }
+        }
+
+      /*
+       * Abandon if errors are found
+       */
+      if (action == TGZ_INVALID)
+        {
+          error("broken archive");
+          break;
+        }
+    }
+
+  /*
+   * Restore file modes and time stamps
+   */
+  restore_attr(&attributes);
+
+  if (gzclose(in) != Z_OK)
+    error("failed gzclose");
+
+  return 0;
+}
+
+
+/* ============================================================ */
+
+void help(int exitval)
+{
+  printf("untgz version 0.2.1\n"
+         "  using zlib version %s\n\n",
+         zlibVersion());
+  printf("Usage: untgz file.tgz            extract all files\n"
+         "       untgz file.tgz fname ...  extract selected files\n"
+         "       untgz -l file.tgz         list archive contents\n"
+         "       untgz -h                  display this help\n");
+  exit(exitval);
+}
+
+void error(const char *msg)
+{
+  fprintf(stderr, "%s: %s\n", prog, msg);
+  exit(1);
+}
+
+
+/* ============================================================ */
+
+#if defined(WIN32) && defined(__GNUC__)
+int _CRT_glob = 0;      /* disable argument globbing in MinGW */
+#endif
+
+int main(int argc,char **argv)
+{
+    int         action = TGZ_EXTRACT;
+    int         arg = 1;
+    char        *TGZfile;
+    gzFile      *f;
+
+    prog = strrchr(argv[0],'\\');
+    if (prog == NULL)
+      {
+        prog = strrchr(argv[0],'/');
+        if (prog == NULL)
+          {
+            prog = strrchr(argv[0],':');
+            if (prog == NULL)
+              prog = argv[0];
+            else
+              prog++;
+          }
+        else
+          prog++;
+      }
+    else
+      prog++;
+
+    if (argc == 1)
+      help(0);
+
+    if (strcmp(argv[arg],"-l") == 0)
+      {
+        action = TGZ_LIST;
+        if (argc == ++arg)
+          help(0);
+      }
+    else if (strcmp(argv[arg],"-h") == 0)
+      {
+        help(0);
+      }
+
+    if ((TGZfile = TGZfname(argv[arg])) == NULL)
+      TGZnotfound(argv[arg]);
+
+    ++arg;
+    if ((action == TGZ_LIST) && (arg != argc))
+      help(1);
+
+/*
+ *  Process the TGZ file
+ */
+    switch(action)
+      {
+      case TGZ_LIST:
+      case TGZ_EXTRACT:
+        f = gzopen(TGZfile,"rb");
+        if (f == NULL)
+          {
+            fprintf(stderr,"%s: Couldn't gzopen %s\n",prog,TGZfile);
+            return 1;
+          }
+        exit(tar(f, action, arg, argc, argv));
+      break;
+
+      default:
+        error("Unknown option");
+        exit(1);
+      }
+
+    return 0;
+}
diff --git a/compat/zlib/contrib/vstudio/readme.txt b/compat/zlib/contrib/vstudio/readme.txt
new file mode 100644
index 0000000..bfdcd9d
--- /dev/null
+++ b/compat/zlib/contrib/vstudio/readme.txt
@@ -0,0 +1,65 @@
+Building instructions for the DLL versions of Zlib 1.2.8
+========================================================
+
+This directory contains projects that build zlib and minizip using
+Microsoft Visual C++ 9.0/10.0.
+
+You don't need to build these projects yourself. You can download the
+binaries from:
+  http://www.winimage.com/zLibDll
+
+More information can be found at this site.
+
+
+
+
+
+Build instructions for Visual Studio 2008 (32 bits or 64 bits)
+--------------------------------------------------------------
+- Uncompress current zlib, including all contrib/* files
+- Compile assembly code (with Visual Studio Command Prompt) by running:
+   bld_ml64.bat (in contrib\masmx64)
+   bld_ml32.bat (in contrib\masmx86)
+- Open contrib\vstudio\vc9\zlibvc.sln with Microsoft Visual C++ 2008
+- Or run: vcbuild /rebuild contrib\vstudio\vc9\zlibvc.sln "Release|Win32"
+
+Build instructions for Visual Studio 2010 (32 bits or 64 bits)
+--------------------------------------------------------------
+- Uncompress current zlib, including all contrib/* files
+- Open contrib\vstudio\vc10\zlibvc.sln with Microsoft Visual C++ 2010
+
+Build instructions for Visual Studio 2012 (32 bits or 64 bits)
+--------------------------------------------------------------
+- Uncompress current zlib, including all contrib/* files
+- Open contrib\vstudio\vc11\zlibvc.sln with Microsoft Visual C++ 2012
+
+
+Important
+---------
+- To use zlibwapi.dll in your application, you must define the
+  macro ZLIB_WINAPI when compiling your application's source files.
+
+
+Additional notes
+----------------
+- This DLL, named zlibwapi.dll, is compatible to the old zlib.dll built
+  by Gilles Vollant from the zlib 1.1.x sources, and distributed at
+    http://www.winimage.com/zLibDll
+  It uses the WINAPI calling convention for the exported functions, and
+  includes the minizip functionality. If your application needs that
+  particular build of zlib.dll, you can rename zlibwapi.dll to zlib.dll.
+
+- The new DLL was renamed because there exist several incompatible
+  versions of zlib.dll on the Internet.
+
+- There is also an official DLL build of zlib, named zlib1.dll. This one
+  is exporting the functions using the CDECL convention. See the file
+  win32\DLL_FAQ.txt found in this zlib distribution.
+
+- There used to be a ZLIB_DLL macro in zlib 1.1.x, but now this symbol
+  has a slightly different effect. To avoid compatibility problems, do
+  not define it here.
+
+
+Gilles Vollant
+info@winimage.com
diff --git a/compat/zlib/contrib/vstudio/vc10/miniunz.vcxproj b/compat/zlib/contrib/vstudio/vc10/miniunz.vcxproj
new file mode 100644
index 0000000..74e15c9
--- /dev/null
+++ b/compat/zlib/contrib/vstudio/vc10/miniunz.vcxproj
@@ -0,0 +1,310 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Itanium">
+      <Configuration>Debug</Configuration>
+      <Platform>Itanium</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Itanium">
+      <Configuration>Release</Configuration>
+      <Platform>Itanium</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{C52F9E7B-498A-42BE-8DB4-85A15694382A}</ProjectGuid>
+    <Keyword>Win32Proj</Keyword>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>MultiByte</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>MultiByte</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>MultiByte</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>MultiByte</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>MultiByte</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>MultiByte</CharacterSet>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup>
+    <_ProjectFileVersion>10.0.30128.1</_ProjectFileVersion>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">x86\MiniUnzip$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">x86\MiniUnzip$(Configuration)\Tmp\</IntDir>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
+    <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</GenerateManifest>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">x86\MiniUnzip$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">x86\MiniUnzip$(Configuration)\Tmp\</IntDir>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
+    <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</GenerateManifest>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">x64\MiniUnzip$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">x64\MiniUnzip$(Configuration)\Tmp\</IntDir>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>
+    <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</GenerateManifest>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">ia64\MiniUnzip$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">ia64\MiniUnzip$(Configuration)\Tmp\</IntDir>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">true</LinkIncremental>
+    <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">false</GenerateManifest>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">x64\MiniUnzip$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">x64\MiniUnzip$(Configuration)\Tmp\</IntDir>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
+    <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</GenerateManifest>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">ia64\MiniUnzip$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">ia64\MiniUnzip$(Configuration)\Tmp\</IntDir>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">false</LinkIncremental>
+    <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">false</GenerateManifest>
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">AllRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" />
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" />
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">AllRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" />
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" />
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <MinimalRebuild>true</MinimalRebuild>
+      <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>x86\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <OutputFile>$(OutDir)miniunz.exe</OutputFile>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <ProgramDatabaseFile>$(OutDir)miniunz.pdb</ProgramDatabaseFile>
+      <SubSystem>Console</SubSystem>
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>
+      <DataExecutionPrevention>
+      </DataExecutionPrevention>
+      <TargetMachine>MachineX86</TargetMachine>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <Optimization>MaxSpeed</Optimization>
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+      <OmitFramePointers>true</OmitFramePointers>
+      <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <StringPooling>true</StringPooling>
+      <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>x86\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <OutputFile>$(OutDir)miniunz.exe</OutputFile>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <OptimizeReferences>true</OptimizeReferences>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>
+      <DataExecutionPrevention>
+      </DataExecutionPrevention>
+      <TargetMachine>MachineX86</TargetMachine>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <Midl>
+      <TargetEnvironment>X64</TargetEnvironment>
+    </Midl>
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <MinimalRebuild>true</MinimalRebuild>
+      <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>x64\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <OutputFile>$(OutDir)miniunz.exe</OutputFile>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <ProgramDatabaseFile>$(OutDir)miniunz.pdb</ProgramDatabaseFile>
+      <SubSystem>Console</SubSystem>
+      <TargetMachine>MachineX64</TargetMachine>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">
+    <Midl>
+      <TargetEnvironment>Itanium</TargetEnvironment>
+    </Midl>
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <MinimalRebuild>true</MinimalRebuild>
+      <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>ia64\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <OutputFile>$(OutDir)miniunz.exe</OutputFile>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <ProgramDatabaseFile>$(OutDir)miniunz.pdb</ProgramDatabaseFile>
+      <SubSystem>Console</SubSystem>
+      <TargetMachine>MachineIA64</TargetMachine>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <Midl>
+      <TargetEnvironment>X64</TargetEnvironment>
+    </Midl>
+    <ClCompile>
+      <Optimization>MaxSpeed</Optimization>
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+      <OmitFramePointers>true</OmitFramePointers>
+      <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <StringPooling>true</StringPooling>
+      <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>x64\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <OutputFile>$(OutDir)miniunz.exe</OutputFile>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <OptimizeReferences>true</OptimizeReferences>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <TargetMachine>MachineX64</TargetMachine>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">
+    <Midl>
+      <TargetEnvironment>Itanium</TargetEnvironment>
+    </Midl>
+    <ClCompile>
+      <Optimization>MaxSpeed</Optimization>
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+      <OmitFramePointers>true</OmitFramePointers>
+      <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <StringPooling>true</StringPooling>
+      <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>ia64\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <OutputFile>$(OutDir)miniunz.exe</OutputFile>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <OptimizeReferences>true</OptimizeReferences>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <TargetMachine>MachineIA64</TargetMachine>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <ClCompile Include="..\..\minizip\miniunz.c" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="zlibvc.vcxproj">
+      <Project>{8fd826f8-3739-44e6-8cc8-997122e53b8d}</Project>
+    </ProjectReference>
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
\ No newline at end of file
diff --git a/compat/zlib/contrib/vstudio/vc10/miniunz.vcxproj.filters b/compat/zlib/contrib/vstudio/vc10/miniunz.vcxproj.filters
new file mode 100644
index 0000000..0b2a3de
--- /dev/null
+++ b/compat/zlib/contrib/vstudio/vc10/miniunz.vcxproj.filters
@@ -0,0 +1,22 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <Filter Include="Source Files">
+      <UniqueIdentifier>{048af943-022b-4db6-beeb-a54c34774ee2}</UniqueIdentifier>
+      <Extensions>cpp;c;cxx;def;odl;idl;hpj;bat;asm</Extensions>
+    </Filter>
+    <Filter Include="Header Files">
+      <UniqueIdentifier>{c1d600d2-888f-4aea-b73e-8b0dd9befa0c}</UniqueIdentifier>
+      <Extensions>h;hpp;hxx;hm;inl;inc</Extensions>
+    </Filter>
+    <Filter Include="Resource Files">
+      <UniqueIdentifier>{0844199a-966b-4f19-81db-1e0125e141b9}</UniqueIdentifier>
+      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe</Extensions>
+    </Filter>
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="..\..\minizip\miniunz.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+  </ItemGroup>
+</Project>
\ No newline at end of file
diff --git a/compat/zlib/contrib/vstudio/vc10/minizip.vcxproj b/compat/zlib/contrib/vstudio/vc10/minizip.vcxproj
new file mode 100644
index 0000000..917e156
--- /dev/null
+++ b/compat/zlib/contrib/vstudio/vc10/minizip.vcxproj
@@ -0,0 +1,307 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Itanium">
+      <Configuration>Debug</Configuration>
+      <Platform>Itanium</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Itanium">
+      <Configuration>Release</Configuration>
+      <Platform>Itanium</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}</ProjectGuid>
+    <Keyword>Win32Proj</Keyword>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>MultiByte</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>MultiByte</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>MultiByte</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>MultiByte</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>MultiByte</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>MultiByte</CharacterSet>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup>
+    <_ProjectFileVersion>10.0.30128.1</_ProjectFileVersion>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">x86\MiniZip$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">x86\MiniZip$(Configuration)\Tmp\</IntDir>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
+    <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</GenerateManifest>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">x86\MiniZip$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">x86\MiniZip$(Configuration)\Tmp\</IntDir>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">x64\$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">x64\$(Configuration)\</IntDir>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>
+    <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</GenerateManifest>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">ia64\$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">ia64\$(Configuration)\</IntDir>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">true</LinkIncremental>
+    <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">false</GenerateManifest>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">x64\$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">x64\$(Configuration)\</IntDir>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">ia64\$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">ia64\$(Configuration)\</IntDir>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">false</LinkIncremental>
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">AllRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" />
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" />
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">AllRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" />
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" />
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <MinimalRebuild>true</MinimalRebuild>
+      <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>x86\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <OutputFile>$(OutDir)minizip.exe</OutputFile>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <ProgramDatabaseFile>$(OutDir)minizip.pdb</ProgramDatabaseFile>
+      <SubSystem>Console</SubSystem>
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>
+      <DataExecutionPrevention>
+      </DataExecutionPrevention>
+      <TargetMachine>MachineX86</TargetMachine>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <Optimization>MaxSpeed</Optimization>
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+      <OmitFramePointers>true</OmitFramePointers>
+      <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <StringPooling>true</StringPooling>
+      <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>x86\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <OutputFile>$(OutDir)minizip.exe</OutputFile>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <OptimizeReferences>true</OptimizeReferences>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>
+      <DataExecutionPrevention>
+      </DataExecutionPrevention>
+      <TargetMachine>MachineX86</TargetMachine>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <Midl>
+      <TargetEnvironment>X64</TargetEnvironment>
+    </Midl>
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <MinimalRebuild>true</MinimalRebuild>
+      <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>x64\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <OutputFile>$(OutDir)minizip.exe</OutputFile>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <ProgramDatabaseFile>$(OutDir)minizip.pdb</ProgramDatabaseFile>
+      <SubSystem>Console</SubSystem>
+      <TargetMachine>MachineX64</TargetMachine>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">
+    <Midl>
+      <TargetEnvironment>Itanium</TargetEnvironment>
+    </Midl>
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <MinimalRebuild>true</MinimalRebuild>
+      <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>ia64\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <OutputFile>$(OutDir)minizip.exe</OutputFile>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <ProgramDatabaseFile>$(OutDir)minizip.pdb</ProgramDatabaseFile>
+      <SubSystem>Console</SubSystem>
+      <TargetMachine>MachineIA64</TargetMachine>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <Midl>
+      <TargetEnvironment>X64</TargetEnvironment>
+    </Midl>
+    <ClCompile>
+      <Optimization>MaxSpeed</Optimization>
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+      <OmitFramePointers>true</OmitFramePointers>
+      <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <StringPooling>true</StringPooling>
+      <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>x64\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <OutputFile>$(OutDir)minizip.exe</OutputFile>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <OptimizeReferences>true</OptimizeReferences>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <TargetMachine>MachineX64</TargetMachine>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">
+    <Midl>
+      <TargetEnvironment>Itanium</TargetEnvironment>
+    </Midl>
+    <ClCompile>
+      <Optimization>MaxSpeed</Optimization>
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+      <OmitFramePointers>true</OmitFramePointers>
+      <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <StringPooling>true</StringPooling>
+      <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>ia64\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <OutputFile>$(OutDir)minizip.exe</OutputFile>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <OptimizeReferences>true</OptimizeReferences>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <TargetMachine>MachineIA64</TargetMachine>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <ClCompile Include="..\..\minizip\minizip.c" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="zlibvc.vcxproj">
+      <Project>{8fd826f8-3739-44e6-8cc8-997122e53b8d}</Project>
+    </ProjectReference>
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
\ No newline at end of file
diff --git a/compat/zlib/contrib/vstudio/vc10/minizip.vcxproj.filters b/compat/zlib/contrib/vstudio/vc10/minizip.vcxproj.filters
new file mode 100644
index 0000000..dd73cd3
--- /dev/null
+++ b/compat/zlib/contrib/vstudio/vc10/minizip.vcxproj.filters
@@ -0,0 +1,22 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <Filter Include="Source Files">
+      <UniqueIdentifier>{c0419b40-bf50-40da-b153-ff74215b79de}</UniqueIdentifier>
+      <Extensions>cpp;c;cxx;def;odl;idl;hpj;bat;asm</Extensions>
+    </Filter>
+    <Filter Include="Header Files">
+      <UniqueIdentifier>{bb87b070-735b-478e-92ce-7383abb2f36c}</UniqueIdentifier>
+      <Extensions>h;hpp;hxx;hm;inl;inc</Extensions>
+    </Filter>
+    <Filter Include="Resource Files">
+      <UniqueIdentifier>{f46ab6a6-548f-43cb-ae96-681abb5bd5db}</UniqueIdentifier>
+      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe</Extensions>
+    </Filter>
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="..\..\minizip\minizip.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+  </ItemGroup>
+</Project>
\ No newline at end of file
diff --git a/compat/zlib/contrib/vstudio/vc10/testzlib.vcxproj b/compat/zlib/contrib/vstudio/vc10/testzlib.vcxproj
new file mode 100644
index 0000000..9088d17
--- /dev/null
+++ b/compat/zlib/contrib/vstudio/vc10/testzlib.vcxproj
@@ -0,0 +1,420 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Itanium">
+      <Configuration>Debug</Configuration>
+      <Platform>Itanium</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="ReleaseWithoutAsm|Itanium">
+      <Configuration>ReleaseWithoutAsm</Configuration>
+      <Platform>Itanium</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="ReleaseWithoutAsm|Win32">
+      <Configuration>ReleaseWithoutAsm</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="ReleaseWithoutAsm|x64">
+      <Configuration>ReleaseWithoutAsm</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Itanium">
+      <Configuration>Release</Configuration>
+      <Platform>Itanium</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}</ProjectGuid>
+    <RootNamespace>testzlib</RootNamespace>
+    <Keyword>Win32Proj</Keyword>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>MultiByte</CharacterSet>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>MultiByte</CharacterSet>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>MultiByte</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>MultiByte</CharacterSet>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>MultiByte</CharacterSet>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>MultiByte</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup>
+    <_ProjectFileVersion>10.0.30128.1</_ProjectFileVersion>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">x86\TestZlib$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">x86\TestZlib$(Configuration)\Tmp\</IntDir>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
+    <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</GenerateManifest>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">x86\TestZlib$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">x86\TestZlib$(Configuration)\Tmp\</IntDir>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">false</LinkIncremental>
+    <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">false</GenerateManifest>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">x86\TestZlib$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">x86\TestZlib$(Configuration)\Tmp\</IntDir>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
+    <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</GenerateManifest>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">x64\TestZlib$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">x64\TestZlib$(Configuration)\Tmp\</IntDir>
+    <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</GenerateManifest>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">ia64\TestZlib$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">ia64\TestZlib$(Configuration)\Tmp\</IntDir>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">true</LinkIncremental>
+    <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">false</GenerateManifest>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">x64\TestZlib$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">x64\TestZlib$(Configuration)\Tmp\</IntDir>
+    <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">false</GenerateManifest>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">ia64\TestZlib$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">ia64\TestZlib$(Configuration)\Tmp\</IntDir>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">false</LinkIncremental>
+    <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">false</GenerateManifest>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">x64\TestZlib$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">x64\TestZlib$(Configuration)\Tmp\</IntDir>
+    <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</GenerateManifest>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">ia64\TestZlib$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">ia64\TestZlib$(Configuration)\Tmp\</IntDir>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">false</LinkIncremental>
+    <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">false</GenerateManifest>
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">AllRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" />
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" />
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">AllRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'" />
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'" />
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'" />
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'" />
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'" />
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'" />
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">AllRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" />
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" />
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>..\..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>ASMV;ASMINF;WIN32;ZLIB_WINAPI;_DEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <MinimalRebuild>true</MinimalRebuild>
+      <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <AssemblerOutput>AssemblyAndSourceCode</AssemblerOutput>
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>..\..\masmx86\match686.obj;..\..\masmx86\inffas32.obj;%(AdditionalDependencies)</AdditionalDependencies>
+      <OutputFile>$(OutDir)testzlib.exe</OutputFile>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <ProgramDatabaseFile>$(OutDir)testzlib.pdb</ProgramDatabaseFile>
+      <SubSystem>Console</SubSystem>
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>
+      <DataExecutionPrevention>
+      </DataExecutionPrevention>
+      <TargetMachine>MachineX86</TargetMachine>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">
+    <ClCompile>
+      <Optimization>MaxSpeed</Optimization>
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+      <OmitFramePointers>true</OmitFramePointers>
+      <AdditionalIncludeDirectories>..\..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <StringPooling>true</StringPooling>
+      <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <OutputFile>$(OutDir)testzlib.exe</OutputFile>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <OptimizeReferences>true</OptimizeReferences>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>
+      <DataExecutionPrevention>
+      </DataExecutionPrevention>
+      <TargetMachine>MachineX86</TargetMachine>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <Optimization>MaxSpeed</Optimization>
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+      <OmitFramePointers>true</OmitFramePointers>
+      <AdditionalIncludeDirectories>..\..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>ASMV;ASMINF;WIN32;ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <StringPooling>true</StringPooling>
+      <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>..\..\masmx86\match686.obj;..\..\masmx86\inffas32.obj;%(AdditionalDependencies)</AdditionalDependencies>
+      <OutputFile>$(OutDir)testzlib.exe</OutputFile>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <OptimizeReferences>true</OptimizeReferences>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>
+      <DataExecutionPrevention>
+      </DataExecutionPrevention>
+      <TargetMachine>MachineX86</TargetMachine>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <AdditionalIncludeDirectories>..\..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>ASMV;ASMINF;WIN32;ZLIB_WINAPI;_DEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>..\..\masmx64\gvmat64.obj;..\..\masmx64\inffasx64.obj;%(AdditionalDependencies)</AdditionalDependencies>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">
+    <Midl>
+      <TargetEnvironment>Itanium</TargetEnvironment>
+    </Midl>
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>..\..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>ZLIB_WINAPI;_DEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <MinimalRebuild>true</MinimalRebuild>
+      <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <AssemblerOutput>AssemblyAndSourceCode</AssemblerOutput>
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <OutputFile>$(OutDir)testzlib.exe</OutputFile>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <ProgramDatabaseFile>$(OutDir)testzlib.pdb</ProgramDatabaseFile>
+      <SubSystem>Console</SubSystem>
+      <TargetMachine>MachineIA64</TargetMachine>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">
+    <ClCompile>
+      <AdditionalIncludeDirectories>..\..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">
+    <Midl>
+      <TargetEnvironment>Itanium</TargetEnvironment>
+    </Midl>
+    <ClCompile>
+      <Optimization>MaxSpeed</Optimization>
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+      <OmitFramePointers>true</OmitFramePointers>
+      <AdditionalIncludeDirectories>..\..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <StringPooling>true</StringPooling>
+      <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <OutputFile>$(OutDir)testzlib.exe</OutputFile>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <OptimizeReferences>true</OptimizeReferences>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <TargetMachine>MachineIA64</TargetMachine>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <AdditionalIncludeDirectories>..\..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>ASMV;ASMINF;WIN32;ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>..\..\masmx64\gvmat64.obj;..\..\masmx64\inffasx64.obj;%(AdditionalDependencies)</AdditionalDependencies>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">
+    <Midl>
+      <TargetEnvironment>Itanium</TargetEnvironment>
+    </Midl>
+    <ClCompile>
+      <Optimization>MaxSpeed</Optimization>
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+      <OmitFramePointers>true</OmitFramePointers>
+      <AdditionalIncludeDirectories>..\..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <StringPooling>true</StringPooling>
+      <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <OutputFile>$(OutDir)testzlib.exe</OutputFile>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <OptimizeReferences>true</OptimizeReferences>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <TargetMachine>MachineIA64</TargetMachine>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <ClCompile Include="..\..\..\adler32.c" />
+    <ClCompile Include="..\..\..\compress.c" />
+    <ClCompile Include="..\..\..\crc32.c" />
+    <ClCompile Include="..\..\..\deflate.c" />
+    <ClCompile Include="..\..\..\infback.c" />
+    <ClCompile Include="..\..\masmx64\inffas8664.c">
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
+    </ClCompile>
+    <ClCompile Include="..\..\..\inffast.c" />
+    <ClCompile Include="..\..\..\inflate.c" />
+    <ClCompile Include="..\..\..\inftrees.c" />
+    <ClCompile Include="..\..\testzlib\testzlib.c" />
+    <ClCompile Include="..\..\..\trees.c" />
+    <ClCompile Include="..\..\..\uncompr.c" />
+    <ClCompile Include="..\..\..\zutil.c" />
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
\ No newline at end of file
diff --git a/compat/zlib/contrib/vstudio/vc10/testzlib.vcxproj.filters b/compat/zlib/contrib/vstudio/vc10/testzlib.vcxproj.filters
new file mode 100644
index 0000000..249daa8
--- /dev/null
+++ b/compat/zlib/contrib/vstudio/vc10/testzlib.vcxproj.filters
@@ -0,0 +1,58 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <Filter Include="Source Files">
+      <UniqueIdentifier>{c1f6a2e3-5da5-4955-8653-310d3efe05a9}</UniqueIdentifier>
+      <Extensions>cpp;c;cxx;def;odl;idl;hpj;bat;asm</Extensions>
+    </Filter>
+    <Filter Include="Header Files">
+      <UniqueIdentifier>{c2aaffdc-2c95-4d6f-8466-4bec5890af2c}</UniqueIdentifier>
+      <Extensions>h;hpp;hxx;hm;inl;inc</Extensions>
+    </Filter>
+    <Filter Include="Resource Files">
+      <UniqueIdentifier>{c274fe07-05f2-461c-964b-f6341e4e7eb5}</UniqueIdentifier>
+      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe</Extensions>
+    </Filter>
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="..\..\..\adler32.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\compress.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\crc32.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\deflate.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\infback.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\masmx64\inffas8664.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\inffast.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\inflate.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\inftrees.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\testzlib\testzlib.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\trees.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\uncompr.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\zutil.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+  </ItemGroup>
+</Project>
\ No newline at end of file
diff --git a/compat/zlib/contrib/vstudio/vc10/testzlibdll.vcxproj b/compat/zlib/contrib/vstudio/vc10/testzlibdll.vcxproj
new file mode 100644
index 0000000..bcb08ff
--- /dev/null
+++ b/compat/zlib/contrib/vstudio/vc10/testzlibdll.vcxproj
@@ -0,0 +1,310 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Itanium">
+      <Configuration>Debug</Configuration>
+      <Platform>Itanium</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Itanium">
+      <Configuration>Release</Configuration>
+      <Platform>Itanium</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{C52F9E7B-498A-42BE-8DB4-85A15694366A}</ProjectGuid>
+    <Keyword>Win32Proj</Keyword>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>MultiByte</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>MultiByte</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>MultiByte</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>MultiByte</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>MultiByte</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>MultiByte</CharacterSet>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup>
+    <_ProjectFileVersion>10.0.30128.1</_ProjectFileVersion>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">x86\TestZlibDll$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">x86\TestZlibDll$(Configuration)\Tmp\</IntDir>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
+    <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</GenerateManifest>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">x86\TestZlibDll$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">x86\TestZlibDll$(Configuration)\Tmp\</IntDir>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
+    <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</GenerateManifest>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">x64\TestZlibDll$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">x64\TestZlibDll$(Configuration)\Tmp\</IntDir>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>
+    <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</GenerateManifest>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">ia64\TestZlibDll$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">ia64\TestZlibDll$(Configuration)\Tmp\</IntDir>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">true</LinkIncremental>
+    <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">false</GenerateManifest>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">x64\TestZlibDll$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">x64\TestZlibDll$(Configuration)\Tmp\</IntDir>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
+    <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</GenerateManifest>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">ia64\TestZlibDll$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">ia64\TestZlibDll$(Configuration)\Tmp\</IntDir>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">false</LinkIncremental>
+    <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">false</GenerateManifest>
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">AllRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" />
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" />
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">AllRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" />
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" />
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <MinimalRebuild>true</MinimalRebuild>
+      <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>x86\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <OutputFile>$(OutDir)testzlibdll.exe</OutputFile>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <ProgramDatabaseFile>$(OutDir)testzlib.pdb</ProgramDatabaseFile>
+      <SubSystem>Console</SubSystem>
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>
+      <DataExecutionPrevention>
+      </DataExecutionPrevention>
+      <TargetMachine>MachineX86</TargetMachine>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <Optimization>MaxSpeed</Optimization>
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+      <OmitFramePointers>true</OmitFramePointers>
+      <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <StringPooling>true</StringPooling>
+      <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>x86\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <OutputFile>$(OutDir)testzlibdll.exe</OutputFile>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <OptimizeReferences>true</OptimizeReferences>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>
+      <DataExecutionPrevention>
+      </DataExecutionPrevention>
+      <TargetMachine>MachineX86</TargetMachine>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <Midl>
+      <TargetEnvironment>X64</TargetEnvironment>
+    </Midl>
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <MinimalRebuild>true</MinimalRebuild>
+      <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>x64\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <OutputFile>$(OutDir)testzlibdll.exe</OutputFile>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <ProgramDatabaseFile>$(OutDir)testzlib.pdb</ProgramDatabaseFile>
+      <SubSystem>Console</SubSystem>
+      <TargetMachine>MachineX64</TargetMachine>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">
+    <Midl>
+      <TargetEnvironment>Itanium</TargetEnvironment>
+    </Midl>
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <MinimalRebuild>true</MinimalRebuild>
+      <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>ia64\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <OutputFile>$(OutDir)testzlibdll.exe</OutputFile>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <ProgramDatabaseFile>$(OutDir)testzlib.pdb</ProgramDatabaseFile>
+      <SubSystem>Console</SubSystem>
+      <TargetMachine>MachineIA64</TargetMachine>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <Midl>
+      <TargetEnvironment>X64</TargetEnvironment>
+    </Midl>
+    <ClCompile>
+      <Optimization>MaxSpeed</Optimization>
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+      <OmitFramePointers>true</OmitFramePointers>
+      <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <StringPooling>true</StringPooling>
+      <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>x64\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <OutputFile>$(OutDir)testzlibdll.exe</OutputFile>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <OptimizeReferences>true</OptimizeReferences>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <TargetMachine>MachineX64</TargetMachine>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">
+    <Midl>
+      <TargetEnvironment>Itanium</TargetEnvironment>
+    </Midl>
+    <ClCompile>
+      <Optimization>MaxSpeed</Optimization>
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+      <OmitFramePointers>true</OmitFramePointers>
+      <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <StringPooling>true</StringPooling>
+      <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>ia64\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <OutputFile>$(OutDir)testzlibdll.exe</OutputFile>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <OptimizeReferences>true</OptimizeReferences>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <TargetMachine>MachineIA64</TargetMachine>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <ClCompile Include="..\..\testzlib\testzlib.c" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="zlibvc.vcxproj">
+      <Project>{8fd826f8-3739-44e6-8cc8-997122e53b8d}</Project>
+    </ProjectReference>
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
\ No newline at end of file
diff --git a/compat/zlib/contrib/vstudio/vc10/testzlibdll.vcxproj.filters b/compat/zlib/contrib/vstudio/vc10/testzlibdll.vcxproj.filters
new file mode 100644
index 0000000..53a8693
--- /dev/null
+++ b/compat/zlib/contrib/vstudio/vc10/testzlibdll.vcxproj.filters
@@ -0,0 +1,22 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <Filter Include="Source Files">
+      <UniqueIdentifier>{fa61a89f-93fc-4c89-b29e-36224b7592f4}</UniqueIdentifier>
+      <Extensions>cpp;c;cxx;def;odl;idl;hpj;bat;asm</Extensions>
+    </Filter>
+    <Filter Include="Header Files">
+      <UniqueIdentifier>{d4b85da0-2ba2-4934-b57f-e2584e3848ee}</UniqueIdentifier>
+      <Extensions>h;hpp;hxx;hm;inl;inc</Extensions>
+    </Filter>
+    <Filter Include="Resource Files">
+      <UniqueIdentifier>{e573e075-00bd-4a7d-bd67-a8cc9bfc5aca}</UniqueIdentifier>
+      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe</Extensions>
+    </Filter>
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="..\..\testzlib\testzlib.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+  </ItemGroup>
+</Project>
\ No newline at end of file
diff --git a/compat/zlib/contrib/vstudio/vc10/zlib.rc b/compat/zlib/contrib/vstudio/vc10/zlib.rc
new file mode 100644
index 0000000..73f6476
--- /dev/null
+++ b/compat/zlib/contrib/vstudio/vc10/zlib.rc
@@ -0,0 +1,32 @@
+#include <windows.h>
+
+#define IDR_VERSION1  1
+IDR_VERSION1	VERSIONINFO	MOVEABLE IMPURE LOADONCALL DISCARDABLE
+  FILEVERSION	 1,2,8,0
+  PRODUCTVERSION 1,2,8,0
+  FILEFLAGSMASK	VS_FFI_FILEFLAGSMASK
+  FILEFLAGS	0
+  FILEOS	VOS_DOS_WINDOWS32
+  FILETYPE	VFT_DLL
+  FILESUBTYPE	0	// not used
+BEGIN
+  BLOCK "StringFileInfo"
+  BEGIN
+    BLOCK "040904E4"
+    //language ID = U.S. English, char set = Windows, Multilingual
+
+    BEGIN
+      VALUE "FileDescription", "zlib data compression and ZIP file I/O library\0"
+      VALUE "FileVersion",	"1.2.8\0"
+      VALUE "InternalName",	"zlib\0"
+      VALUE "OriginalFilename",	"zlibwapi.dll\0"
+      VALUE "ProductName",	"ZLib.DLL\0"
+      VALUE "Comments","DLL support by Alessandro Iacopetti & Gilles Vollant\0"
+      VALUE "LegalCopyright", "(C) 1995-2013 Jean-loup Gailly & Mark Adler\0"
+    END
+  END
+  BLOCK "VarFileInfo"
+  BEGIN
+    VALUE "Translation", 0x0409, 1252
+  END
+END
diff --git a/compat/zlib/contrib/vstudio/vc10/zlibstat.vcxproj b/compat/zlib/contrib/vstudio/vc10/zlibstat.vcxproj
new file mode 100644
index 0000000..b9f2bbe
--- /dev/null
+++ b/compat/zlib/contrib/vstudio/vc10/zlibstat.vcxproj
@@ -0,0 +1,473 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Itanium">
+      <Configuration>Debug</Configuration>
+      <Platform>Itanium</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="ReleaseWithoutAsm|Itanium">
+      <Configuration>ReleaseWithoutAsm</Configuration>
+      <Platform>Itanium</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="ReleaseWithoutAsm|Win32">
+      <Configuration>ReleaseWithoutAsm</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="ReleaseWithoutAsm|x64">
+      <Configuration>ReleaseWithoutAsm</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Itanium">
+      <Configuration>Release</Configuration>
+      <Platform>Itanium</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}</ProjectGuid>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <UseOfMfc>false</UseOfMfc>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <UseOfMfc>false</UseOfMfc>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <UseOfMfc>false</UseOfMfc>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <UseOfMfc>false</UseOfMfc>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <UseOfMfc>false</UseOfMfc>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <UseOfMfc>false</UseOfMfc>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <UseOfMfc>false</UseOfMfc>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <UseOfMfc>false</UseOfMfc>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <UseOfMfc>false</UseOfMfc>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup>
+    <_ProjectFileVersion>10.0.30128.1</_ProjectFileVersion>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">x86\ZlibStat$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">x86\ZlibStat$(Configuration)\Tmp\</IntDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">x86\ZlibStat$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">x86\ZlibStat$(Configuration)\Tmp\</IntDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">x86\ZlibStat$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">x86\ZlibStat$(Configuration)\Tmp\</IntDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">x64\ZlibStat$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">x64\ZlibStat$(Configuration)\Tmp\</IntDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">ia64\ZlibStat$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">ia64\ZlibStat$(Configuration)\Tmp\</IntDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">x64\ZlibStat$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">x64\ZlibStat$(Configuration)\Tmp\</IntDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">ia64\ZlibStat$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">ia64\ZlibStat$(Configuration)\Tmp\</IntDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">x64\ZlibStat$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">x64\ZlibStat$(Configuration)\Tmp\</IntDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">ia64\ZlibStat$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">ia64\ZlibStat$(Configuration)\Tmp\</IntDir>
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">AllRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" />
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" />
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">AllRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'" />
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'" />
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'" />
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'" />
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'" />
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'" />
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">AllRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" />
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" />
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <ExceptionHandling>
+      </ExceptionHandling>
+      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+      <PrecompiledHeaderOutputFile>$(IntDir)zlibstat.pch</PrecompiledHeaderOutputFile>
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+      <ObjectFileName>$(IntDir)</ObjectFileName>
+      <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+      <WarningLevel>Level3</WarningLevel>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <DebugInformationFormat>OldStyle</DebugInformationFormat>
+    </ClCompile>
+    <ResourceCompile>
+      <Culture>0x040c</Culture>
+    </ResourceCompile>
+    <Lib>
+      <AdditionalOptions>/MACHINE:X86 /NODEFAULTLIB %(AdditionalOptions)</AdditionalOptions>
+      <OutputFile>$(OutDir)zlibstat.lib</OutputFile>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+    </Lib>
+    <PreBuildEvent>
+      <Command>cd ..\..\masmx86
+bld_ml32.bat</Command>
+    </PreBuildEvent>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+      <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ASMV;ASMINF;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <StringPooling>true</StringPooling>
+      <ExceptionHandling>
+      </ExceptionHandling>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <PrecompiledHeaderOutputFile>$(IntDir)zlibstat.pch</PrecompiledHeaderOutputFile>
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+      <ObjectFileName>$(IntDir)</ObjectFileName>
+      <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+      <WarningLevel>Level3</WarningLevel>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+    </ClCompile>
+    <ResourceCompile>
+      <Culture>0x040c</Culture>
+    </ResourceCompile>
+    <Lib>
+      <AdditionalOptions>/MACHINE:X86 /NODEFAULTLIB %(AdditionalOptions)</AdditionalOptions>
+      <AdditionalDependencies>..\..\masmx86\match686.obj;..\..\masmx86\inffas32.obj;%(AdditionalDependencies)</AdditionalDependencies>
+      <OutputFile>$(OutDir)zlibstat.lib</OutputFile>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+    </Lib>
+    <PreBuildEvent>
+      <Command>cd ..\..\masmx86
+bld_ml32.bat</Command>
+    </PreBuildEvent>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">
+    <ClCompile>
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+      <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <StringPooling>true</StringPooling>
+      <ExceptionHandling>
+      </ExceptionHandling>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <PrecompiledHeaderOutputFile>$(IntDir)zlibstat.pch</PrecompiledHeaderOutputFile>
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+      <ObjectFileName>$(IntDir)</ObjectFileName>
+      <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+      <WarningLevel>Level3</WarningLevel>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+    </ClCompile>
+    <ResourceCompile>
+      <Culture>0x040c</Culture>
+    </ResourceCompile>
+    <Lib>
+      <AdditionalOptions>/MACHINE:X86 /NODEFAULTLIB %(AdditionalOptions)</AdditionalOptions>
+      <OutputFile>$(OutDir)zlibstat.lib</OutputFile>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+    </Lib>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <Midl>
+      <TargetEnvironment>X64</TargetEnvironment>
+    </Midl>
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <ExceptionHandling>
+      </ExceptionHandling>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+      <PrecompiledHeaderOutputFile>$(IntDir)zlibstat.pch</PrecompiledHeaderOutputFile>
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+      <ObjectFileName>$(IntDir)</ObjectFileName>
+      <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+      <WarningLevel>Level3</WarningLevel>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <DebugInformationFormat>OldStyle</DebugInformationFormat>
+    </ClCompile>
+    <ResourceCompile>
+      <Culture>0x040c</Culture>
+    </ResourceCompile>
+    <Lib>
+      <AdditionalOptions>/MACHINE:AMD64 /NODEFAULTLIB %(AdditionalOptions)</AdditionalOptions>
+      <OutputFile>$(OutDir)zlibstat.lib</OutputFile>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+    </Lib>
+    <PreBuildEvent>
+      <Command>cd ..\..\masmx64
+bld_ml64.bat</Command>
+    </PreBuildEvent>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">
+    <Midl>
+      <TargetEnvironment>Itanium</TargetEnvironment>
+    </Midl>
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <ExceptionHandling>
+      </ExceptionHandling>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+      <PrecompiledHeaderOutputFile>$(IntDir)zlibstat.pch</PrecompiledHeaderOutputFile>
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+      <ObjectFileName>$(IntDir)</ObjectFileName>
+      <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+      <WarningLevel>Level3</WarningLevel>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <DebugInformationFormat>OldStyle</DebugInformationFormat>
+    </ClCompile>
+    <ResourceCompile>
+      <Culture>0x040c</Culture>
+    </ResourceCompile>
+    <Lib>
+      <AdditionalOptions>/MACHINE:IA64 /NODEFAULTLIB %(AdditionalOptions)</AdditionalOptions>
+      <OutputFile>$(OutDir)zlibstat.lib</OutputFile>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+    </Lib>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <Midl>
+      <TargetEnvironment>X64</TargetEnvironment>
+    </Midl>
+    <ClCompile>
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+      <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ASMV;ASMINF;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <StringPooling>true</StringPooling>
+      <ExceptionHandling>
+      </ExceptionHandling>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <PrecompiledHeaderOutputFile>$(IntDir)zlibstat.pch</PrecompiledHeaderOutputFile>
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+      <ObjectFileName>$(IntDir)</ObjectFileName>
+      <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+      <WarningLevel>Level3</WarningLevel>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+    </ClCompile>
+    <ResourceCompile>
+      <Culture>0x040c</Culture>
+    </ResourceCompile>
+    <Lib>
+      <AdditionalOptions>/MACHINE:AMD64 /NODEFAULTLIB %(AdditionalOptions)</AdditionalOptions>
+      <AdditionalDependencies>..\..\masmx64\gvmat64.obj;..\..\masmx64\inffasx64.obj;%(AdditionalDependencies)</AdditionalDependencies>
+      <OutputFile>$(OutDir)zlibstat.lib</OutputFile>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+    </Lib>
+    <PreBuildEvent>
+      <Command>cd ..\..\masmx64
+bld_ml64.bat</Command>
+    </PreBuildEvent>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">
+    <Midl>
+      <TargetEnvironment>Itanium</TargetEnvironment>
+    </Midl>
+    <ClCompile>
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+      <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <StringPooling>true</StringPooling>
+      <ExceptionHandling>
+      </ExceptionHandling>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <PrecompiledHeaderOutputFile>$(IntDir)zlibstat.pch</PrecompiledHeaderOutputFile>
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+      <ObjectFileName>$(IntDir)</ObjectFileName>
+      <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+      <WarningLevel>Level3</WarningLevel>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+    </ClCompile>
+    <ResourceCompile>
+      <Culture>0x040c</Culture>
+    </ResourceCompile>
+    <Lib>
+      <AdditionalOptions>/MACHINE:IA64 /NODEFAULTLIB %(AdditionalOptions)</AdditionalOptions>
+      <OutputFile>$(OutDir)zlibstat.lib</OutputFile>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+    </Lib>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">
+    <Midl>
+      <TargetEnvironment>X64</TargetEnvironment>
+    </Midl>
+    <ClCompile>
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+      <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <StringPooling>true</StringPooling>
+      <ExceptionHandling>
+      </ExceptionHandling>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <PrecompiledHeaderOutputFile>$(IntDir)zlibstat.pch</PrecompiledHeaderOutputFile>
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+      <ObjectFileName>$(IntDir)</ObjectFileName>
+      <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+      <WarningLevel>Level3</WarningLevel>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+    </ClCompile>
+    <ResourceCompile>
+      <Culture>0x040c</Culture>
+    </ResourceCompile>
+    <Lib>
+      <AdditionalOptions>/MACHINE:AMD64 /NODEFAULTLIB %(AdditionalOptions)</AdditionalOptions>
+      <OutputFile>$(OutDir)zlibstat.lib</OutputFile>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+    </Lib>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">
+    <Midl>
+      <TargetEnvironment>Itanium</TargetEnvironment>
+    </Midl>
+    <ClCompile>
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+      <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <StringPooling>true</StringPooling>
+      <ExceptionHandling>
+      </ExceptionHandling>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <PrecompiledHeaderOutputFile>$(IntDir)zlibstat.pch</PrecompiledHeaderOutputFile>
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+      <ObjectFileName>$(IntDir)</ObjectFileName>
+      <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+      <WarningLevel>Level3</WarningLevel>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+    </ClCompile>
+    <ResourceCompile>
+      <Culture>0x040c</Culture>
+    </ResourceCompile>
+    <Lib>
+      <AdditionalOptions>/MACHINE:IA64 /NODEFAULTLIB %(AdditionalOptions)</AdditionalOptions>
+      <OutputFile>$(OutDir)zlibstat.lib</OutputFile>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+    </Lib>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <ClCompile Include="..\..\..\adler32.c" />
+    <ClCompile Include="..\..\..\compress.c" />
+    <ClCompile Include="..\..\..\crc32.c" />
+    <ClCompile Include="..\..\..\deflate.c" />
+    <ClCompile Include="..\..\..\gzclose.c" />
+    <ClCompile Include="..\..\..\gzlib.c" />
+    <ClCompile Include="..\..\..\gzread.c" />
+    <ClCompile Include="..\..\..\gzwrite.c" />
+    <ClCompile Include="..\..\..\infback.c" />
+    <ClCompile Include="..\..\masmx64\inffas8664.c">
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
+    </ClCompile>
+    <ClCompile Include="..\..\..\inffast.c" />
+    <ClCompile Include="..\..\..\inflate.c" />
+    <ClCompile Include="..\..\..\inftrees.c" />
+    <ClCompile Include="..\..\minizip\ioapi.c" />
+    <ClCompile Include="..\..\..\trees.c" />
+    <ClCompile Include="..\..\..\uncompr.c" />
+    <ClCompile Include="..\..\minizip\unzip.c" />
+    <ClCompile Include="..\..\minizip\zip.c" />
+    <ClCompile Include="..\..\..\zutil.c" />
+  </ItemGroup>
+  <ItemGroup>
+    <ResourceCompile Include="zlib.rc" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="zlibvc.def" />
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
\ No newline at end of file
diff --git a/compat/zlib/contrib/vstudio/vc10/zlibstat.vcxproj.filters b/compat/zlib/contrib/vstudio/vc10/zlibstat.vcxproj.filters
new file mode 100644
index 0000000..c8c7f7e
--- /dev/null
+++ b/compat/zlib/contrib/vstudio/vc10/zlibstat.vcxproj.filters
@@ -0,0 +1,77 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <Filter Include="Source Files">
+      <UniqueIdentifier>{174213f6-7f66-4ae8-a3a8-a1e0a1e6ffdd}</UniqueIdentifier>
+    </Filter>
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="..\..\..\adler32.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\compress.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\crc32.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\deflate.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\gzclose.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\gzlib.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\gzread.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\gzwrite.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\infback.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\masmx64\inffas8664.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\inffast.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\inflate.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\inftrees.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\minizip\ioapi.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\trees.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\uncompr.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\minizip\unzip.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\minizip\zip.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\zutil.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ResourceCompile Include="zlib.rc">
+      <Filter>Source Files</Filter>
+    </ResourceCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="zlibvc.def">
+      <Filter>Source Files</Filter>
+    </None>
+  </ItemGroup>
+</Project>
\ No newline at end of file
diff --git a/compat/zlib/contrib/vstudio/vc10/zlibvc.def b/compat/zlib/contrib/vstudio/vc10/zlibvc.def
new file mode 100644
index 0000000..6367046
--- /dev/null
+++ b/compat/zlib/contrib/vstudio/vc10/zlibvc.def
@@ -0,0 +1,143 @@
+LIBRARY
+; zlib data compression and ZIP file I/O library
+
+VERSION		1.2.8
+
+EXPORTS
+        adler32                                  @1
+        compress                                 @2
+        crc32                                    @3
+        deflate                                  @4
+        deflateCopy                              @5
+        deflateEnd                               @6
+        deflateInit2_                            @7
+        deflateInit_                             @8
+        deflateParams                            @9
+        deflateReset                             @10
+        deflateSetDictionary                     @11
+        gzclose                                  @12
+        gzdopen                                  @13
+        gzerror                                  @14
+        gzflush                                  @15
+        gzopen                                   @16
+        gzread                                   @17
+        gzwrite                                  @18
+        inflate                                  @19
+        inflateEnd                               @20
+        inflateInit2_                            @21
+        inflateInit_                             @22
+        inflateReset                             @23
+        inflateSetDictionary                     @24
+        inflateSync                              @25
+        uncompress                               @26
+        zlibVersion                              @27
+        gzprintf                                 @28
+        gzputc                                   @29
+        gzgetc                                   @30
+        gzseek                                   @31
+        gzrewind                                 @32
+        gztell                                   @33
+        gzeof                                    @34
+        gzsetparams                              @35
+        zError                                   @36
+        inflateSyncPoint                         @37
+        get_crc_table                            @38
+        compress2                                @39
+        gzputs                                   @40
+        gzgets                                   @41
+        inflateCopy                              @42
+        inflateBackInit_                         @43
+        inflateBack                              @44
+        inflateBackEnd                           @45
+        compressBound                            @46
+        deflateBound                             @47
+        gzclearerr                               @48
+        gzungetc                                 @49
+        zlibCompileFlags                         @50
+        deflatePrime                             @51
+        deflatePending                           @52
+
+        unzOpen                                  @61
+        unzClose                                 @62
+        unzGetGlobalInfo                         @63
+        unzGetCurrentFileInfo                    @64
+        unzGoToFirstFile                         @65
+        unzGoToNextFile                          @66
+        unzOpenCurrentFile                       @67
+        unzReadCurrentFile                       @68
+        unzOpenCurrentFile3                      @69
+        unztell                                  @70
+        unzeof                                   @71
+        unzCloseCurrentFile                      @72
+        unzGetGlobalComment                      @73
+        unzStringFileNameCompare                 @74
+        unzLocateFile                            @75
+        unzGetLocalExtrafield                    @76
+        unzOpen2                                 @77
+        unzOpenCurrentFile2                      @78
+        unzOpenCurrentFilePassword               @79
+
+        zipOpen                                  @80
+        zipOpenNewFileInZip                      @81
+        zipWriteInFileInZip                      @82
+        zipCloseFileInZip                        @83
+        zipClose                                 @84
+        zipOpenNewFileInZip2                     @86
+        zipCloseFileInZipRaw                     @87
+        zipOpen2                                 @88
+        zipOpenNewFileInZip3                     @89
+
+        unzGetFilePos                            @100
+        unzGoToFilePos                           @101
+
+        fill_win32_filefunc                      @110
+
+; zlibwapi v1.2.4 added:
+        fill_win32_filefunc64                   @111
+        fill_win32_filefunc64A                  @112
+        fill_win32_filefunc64W                  @113
+
+        unzOpen64                               @120
+        unzOpen2_64                             @121
+        unzGetGlobalInfo64                      @122
+        unzGetCurrentFileInfo64                 @124
+        unzGetCurrentFileZStreamPos64           @125
+        unztell64                               @126
+        unzGetFilePos64                         @127
+        unzGoToFilePos64                        @128
+
+        zipOpen64                               @130
+        zipOpen2_64                             @131
+        zipOpenNewFileInZip64                   @132
+        zipOpenNewFileInZip2_64                 @133
+        zipOpenNewFileInZip3_64                 @134
+        zipOpenNewFileInZip4_64                 @135
+        zipCloseFileInZipRaw64                  @136
+
+; zlib1 v1.2.4 added:
+        adler32_combine                         @140
+        crc32_combine                           @142
+        deflateSetHeader                        @144
+        deflateTune                             @145
+        gzbuffer                                @146
+        gzclose_r                               @147
+        gzclose_w                               @148
+        gzdirect                                @149
+        gzoffset                                @150
+        inflateGetHeader                        @156
+        inflateMark                             @157
+        inflatePrime                            @158
+        inflateReset2                           @159
+        inflateUndermine                        @160
+
+; zlib1 v1.2.6 added:
+        gzgetc_                                 @161
+        inflateResetKeep                        @163
+        deflateResetKeep                        @164
+
+; zlib1 v1.2.7 added:
+        gzopen_w                                @165
+
+; zlib1 v1.2.8 added:
+        inflateGetDictionary                    @166
+        gzvprintf                               @167
diff --git a/compat/zlib/contrib/vstudio/vc10/zlibvc.sln b/compat/zlib/contrib/vstudio/vc10/zlibvc.sln
new file mode 100644
index 0000000..6f6ffd5
--- /dev/null
+++ b/compat/zlib/contrib/vstudio/vc10/zlibvc.sln
@@ -0,0 +1,135 @@
+﻿
+Microsoft Visual Studio Solution File, Format Version 11.00
+# Visual Studio 2010
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlibvc", "zlibvc.vcxproj", "{8FD826F8-3739-44E6-8CC8-997122E53B8D}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlibstat", "zlibstat.vcxproj", "{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testzlib", "testzlib.vcxproj", "{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testzlibdll", "testzlibdll.vcxproj", "{C52F9E7B-498A-42BE-8DB4-85A15694366A}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "minizip", "minizip.vcxproj", "{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "miniunz", "miniunz.vcxproj", "{C52F9E7B-498A-42BE-8DB4-85A15694382A}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Itanium = Debug|Itanium
+		Debug|Win32 = Debug|Win32
+		Debug|x64 = Debug|x64
+		Release|Itanium = Release|Itanium
+		Release|Win32 = Release|Win32
+		Release|x64 = Release|x64
+		ReleaseWithoutAsm|Itanium = ReleaseWithoutAsm|Itanium
+		ReleaseWithoutAsm|Win32 = ReleaseWithoutAsm|Win32
+		ReleaseWithoutAsm|x64 = ReleaseWithoutAsm|x64
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|Itanium.ActiveCfg = Debug|Itanium
+		{8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|Itanium.Build.0 = Debug|Itanium
+		{8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|Win32.ActiveCfg = Debug|Win32
+		{8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|Win32.Build.0 = Debug|Win32
+		{8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|x64.ActiveCfg = Debug|x64
+		{8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|x64.Build.0 = Debug|x64
+		{8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|Itanium.ActiveCfg = Release|Itanium
+		{8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|Itanium.Build.0 = Release|Itanium
+		{8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|Win32.ActiveCfg = Release|Win32
+		{8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|Win32.Build.0 = Release|Win32
+		{8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|x64.ActiveCfg = Release|x64
+		{8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|x64.Build.0 = Release|x64
+		{8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|Itanium.ActiveCfg = ReleaseWithoutAsm|Itanium
+		{8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|Itanium.Build.0 = ReleaseWithoutAsm|Itanium
+		{8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|Win32.ActiveCfg = ReleaseWithoutAsm|Win32
+		{8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|Win32.Build.0 = ReleaseWithoutAsm|Win32
+		{8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|x64.ActiveCfg = ReleaseWithoutAsm|x64
+		{8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|x64.Build.0 = ReleaseWithoutAsm|x64
+		{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|Itanium.ActiveCfg = Debug|Itanium
+		{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|Itanium.Build.0 = Debug|Itanium
+		{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|Win32.ActiveCfg = Debug|Win32
+		{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|Win32.Build.0 = Debug|Win32
+		{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|x64.ActiveCfg = Debug|x64
+		{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|x64.Build.0 = Debug|x64
+		{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|Itanium.ActiveCfg = Release|Itanium
+		{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|Itanium.Build.0 = Release|Itanium
+		{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|Win32.ActiveCfg = Release|Win32
+		{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|Win32.Build.0 = Release|Win32
+		{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|x64.ActiveCfg = Release|x64
+		{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|x64.Build.0 = Release|x64
+		{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|Itanium.ActiveCfg = ReleaseWithoutAsm|Itanium
+		{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|Itanium.Build.0 = ReleaseWithoutAsm|Itanium
+		{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|Win32.ActiveCfg = ReleaseWithoutAsm|Win32
+		{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|Win32.Build.0 = ReleaseWithoutAsm|Win32
+		{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|x64.ActiveCfg = ReleaseWithoutAsm|x64
+		{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|x64.Build.0 = ReleaseWithoutAsm|x64
+		{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|Itanium.ActiveCfg = Debug|Itanium
+		{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|Itanium.Build.0 = Debug|Itanium
+		{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|Win32.ActiveCfg = Debug|Win32
+		{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|Win32.Build.0 = Debug|Win32
+		{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|x64.ActiveCfg = Debug|x64
+		{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|x64.Build.0 = Debug|x64
+		{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|Itanium.ActiveCfg = Release|Itanium
+		{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|Itanium.Build.0 = Release|Itanium
+		{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|Win32.ActiveCfg = Release|Win32
+		{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|Win32.Build.0 = Release|Win32
+		{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|x64.ActiveCfg = Release|x64
+		{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|x64.Build.0 = Release|x64
+		{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Itanium.ActiveCfg = ReleaseWithoutAsm|Itanium
+		{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Itanium.Build.0 = ReleaseWithoutAsm|Itanium
+		{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Win32.ActiveCfg = ReleaseWithoutAsm|Win32
+		{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Win32.Build.0 = ReleaseWithoutAsm|Win32
+		{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|x64.ActiveCfg = ReleaseWithoutAsm|x64
+		{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|x64.Build.0 = ReleaseWithoutAsm|x64
+		{C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|Itanium.ActiveCfg = Debug|Itanium
+		{C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|Itanium.Build.0 = Debug|Itanium
+		{C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|Win32.ActiveCfg = Debug|Win32
+		{C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|Win32.Build.0 = Debug|Win32
+		{C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|x64.ActiveCfg = Debug|x64
+		{C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|x64.Build.0 = Debug|x64
+		{C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|Itanium.ActiveCfg = Release|Itanium
+		{C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|Itanium.Build.0 = Release|Itanium
+		{C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|Win32.ActiveCfg = Release|Win32
+		{C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|Win32.Build.0 = Release|Win32
+		{C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|x64.ActiveCfg = Release|x64
+		{C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|x64.Build.0 = Release|x64
+		{C52F9E7B-498A-42BE-8DB4-85A15694366A}.ReleaseWithoutAsm|Itanium.ActiveCfg = Release|Itanium
+		{C52F9E7B-498A-42BE-8DB4-85A15694366A}.ReleaseWithoutAsm|Itanium.Build.0 = Release|Itanium
+		{C52F9E7B-498A-42BE-8DB4-85A15694366A}.ReleaseWithoutAsm|Win32.ActiveCfg = Release|Win32
+		{C52F9E7B-498A-42BE-8DB4-85A15694366A}.ReleaseWithoutAsm|x64.ActiveCfg = Release|x64
+		{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|Itanium.ActiveCfg = Debug|Itanium
+		{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|Itanium.Build.0 = Debug|Itanium
+		{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|Win32.ActiveCfg = Debug|Win32
+		{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|Win32.Build.0 = Debug|Win32
+		{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|x64.ActiveCfg = Debug|x64
+		{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|x64.Build.0 = Debug|x64
+		{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|Itanium.ActiveCfg = Release|Itanium
+		{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|Itanium.Build.0 = Release|Itanium
+		{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|Win32.ActiveCfg = Release|Win32
+		{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|Win32.Build.0 = Release|Win32
+		{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|x64.ActiveCfg = Release|x64
+		{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|x64.Build.0 = Release|x64
+		{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Itanium.ActiveCfg = Release|Itanium
+		{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Itanium.Build.0 = Release|Itanium
+		{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Win32.ActiveCfg = Release|Win32
+		{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|x64.ActiveCfg = Release|x64
+		{C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|Itanium.ActiveCfg = Debug|Itanium
+		{C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|Itanium.Build.0 = Debug|Itanium
+		{C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|Win32.ActiveCfg = Debug|Win32
+		{C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|Win32.Build.0 = Debug|Win32
+		{C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|x64.ActiveCfg = Debug|x64
+		{C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|x64.Build.0 = Debug|x64
+		{C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|Itanium.ActiveCfg = Release|Itanium
+		{C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|Itanium.Build.0 = Release|Itanium
+		{C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|Win32.ActiveCfg = Release|Win32
+		{C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|Win32.Build.0 = Release|Win32
+		{C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|x64.ActiveCfg = Release|x64
+		{C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|x64.Build.0 = Release|x64
+		{C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseWithoutAsm|Itanium.ActiveCfg = Release|Itanium
+		{C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseWithoutAsm|Itanium.Build.0 = Release|Itanium
+		{C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseWithoutAsm|Win32.ActiveCfg = Release|Win32
+		{C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseWithoutAsm|x64.ActiveCfg = Release|x64
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal
diff --git a/compat/zlib/contrib/vstudio/vc10/zlibvc.vcxproj b/compat/zlib/contrib/vstudio/vc10/zlibvc.vcxproj
new file mode 100644
index 0000000..6ff9ddb
--- /dev/null
+++ b/compat/zlib/contrib/vstudio/vc10/zlibvc.vcxproj
@@ -0,0 +1,657 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Itanium">
+      <Configuration>Debug</Configuration>
+      <Platform>Itanium</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="ReleaseWithoutAsm|Itanium">
+      <Configuration>ReleaseWithoutAsm</Configuration>
+      <Platform>Itanium</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="ReleaseWithoutAsm|Win32">
+      <Configuration>ReleaseWithoutAsm</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="ReleaseWithoutAsm|x64">
+      <Configuration>ReleaseWithoutAsm</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Itanium">
+      <Configuration>Release</Configuration>
+      <Platform>Itanium</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{8FD826F8-3739-44E6-8CC8-997122E53B8D}</ProjectGuid>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <UseOfMfc>false</UseOfMfc>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <UseOfMfc>false</UseOfMfc>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <UseOfMfc>false</UseOfMfc>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <UseOfMfc>false</UseOfMfc>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <UseOfMfc>false</UseOfMfc>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <UseOfMfc>false</UseOfMfc>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <UseOfMfc>false</UseOfMfc>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <UseOfMfc>false</UseOfMfc>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <UseOfMfc>false</UseOfMfc>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup>
+    <_ProjectFileVersion>10.0.30128.1</_ProjectFileVersion>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">x86\ZlibDll$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">x86\ZlibDll$(Configuration)\Tmp\</IntDir>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
+    <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</GenerateManifest>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">x86\ZlibDll$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">x86\ZlibDll$(Configuration)\Tmp\</IntDir>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">false</LinkIncremental>
+    <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">false</GenerateManifest>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">x86\ZlibDll$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">x86\ZlibDll$(Configuration)\Tmp\</IntDir>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
+    <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</GenerateManifest>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">x64\ZlibDll$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">x64\ZlibDll$(Configuration)\Tmp\</IntDir>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>
+    <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</GenerateManifest>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">ia64\ZlibDll$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">ia64\ZlibDll$(Configuration)\Tmp\</IntDir>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">true</LinkIncremental>
+    <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">false</GenerateManifest>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">x64\ZlibDll$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">x64\ZlibDll$(Configuration)\Tmp\</IntDir>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">false</LinkIncremental>
+    <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">false</GenerateManifest>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">ia64\ZlibDll$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">ia64\ZlibDll$(Configuration)\Tmp\</IntDir>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">false</LinkIncremental>
+    <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">false</GenerateManifest>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">x64\ZlibDll$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">x64\ZlibDll$(Configuration)\Tmp\</IntDir>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
+    <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</GenerateManifest>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">ia64\ZlibDll$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">ia64\ZlibDll$(Configuration)\Tmp\</IntDir>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">false</LinkIncremental>
+    <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">false</GenerateManifest>
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">AllRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" />
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" />
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">AllRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'" />
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'" />
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'" />
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'" />
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'" />
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'" />
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">AllRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" />
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" />
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
+    <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">zlibwapid</TargetName>
+    <TargetName Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">zlibwapi</TargetName>
+    <TargetName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">zlibwapi</TargetName>
+    <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">zlibwapid</TargetName>
+    <TargetName Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">zlibwapi</TargetName>
+    <TargetName Condition="'$(Configuration)|$(Platform)'=='Release|x64'">zlibwapi</TargetName>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <Midl>
+      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <MkTypLibCompatible>true</MkTypLibCompatible>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <TargetEnvironment>Win32</TargetEnvironment>
+      <TypeLibraryName>$(OutDir)zlibvc.tlb</TypeLibraryName>
+    </Midl>
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;ASMV;ASMINF;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <ExceptionHandling>
+      </ExceptionHandling>
+      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+      <PrecompiledHeaderOutputFile>$(IntDir)zlibvc.pch</PrecompiledHeaderOutputFile>
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+      <ObjectFileName>$(IntDir)</ObjectFileName>
+      <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+      <BrowseInformation>
+      </BrowseInformation>
+      <WarningLevel>Level3</WarningLevel>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
+    </ClCompile>
+    <ResourceCompile>
+      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <Culture>0x040c</Culture>
+    </ResourceCompile>
+    <Link>
+      <AdditionalOptions>/MACHINE:I386 %(AdditionalOptions)</AdditionalOptions>
+      <AdditionalDependencies>..\..\masmx86\match686.obj;..\..\masmx86\inffas32.obj;%(AdditionalDependencies)</AdditionalDependencies>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <ModuleDefinitionFile>.\zlibvc.def</ModuleDefinitionFile>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <GenerateMapFile>true</GenerateMapFile>
+      <SubSystem>Windows</SubSystem>
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>
+      <DataExecutionPrevention>
+      </DataExecutionPrevention>
+    </Link>
+    <PreBuildEvent>
+      <Command>cd ..\..\masmx86
+bld_ml32.bat</Command>
+    </PreBuildEvent>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">
+    <Midl>
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <MkTypLibCompatible>true</MkTypLibCompatible>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <TargetEnvironment>Win32</TargetEnvironment>
+      <TypeLibraryName>$(OutDir)zlibvc.tlb</TypeLibraryName>
+    </Midl>
+    <ClCompile>
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+      <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <StringPooling>true</StringPooling>
+      <ExceptionHandling>
+      </ExceptionHandling>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <PrecompiledHeaderOutputFile>$(IntDir)zlibvc.pch</PrecompiledHeaderOutputFile>
+      <AssemblerOutput>All</AssemblerOutput>
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+      <ObjectFileName>$(IntDir)</ObjectFileName>
+      <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+      <BrowseInformation>
+      </BrowseInformation>
+      <WarningLevel>Level3</WarningLevel>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+    </ClCompile>
+    <ResourceCompile>
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <Culture>0x040c</Culture>
+    </ResourceCompile>
+    <Link>
+      <AdditionalOptions>/MACHINE:I386 %(AdditionalOptions)</AdditionalOptions>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+      <ModuleDefinitionFile>.\zlibvc.def</ModuleDefinitionFile>
+      <GenerateMapFile>true</GenerateMapFile>
+      <SubSystem>Windows</SubSystem>
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>
+      <DataExecutionPrevention>
+      </DataExecutionPrevention>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <Midl>
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <MkTypLibCompatible>true</MkTypLibCompatible>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <TargetEnvironment>Win32</TargetEnvironment>
+      <TypeLibraryName>$(OutDir)zlibvc.tlb</TypeLibraryName>
+    </Midl>
+    <ClCompile>
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+      <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;ASMV;ASMINF;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <StringPooling>true</StringPooling>
+      <ExceptionHandling>
+      </ExceptionHandling>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <PrecompiledHeaderOutputFile>$(IntDir)zlibvc.pch</PrecompiledHeaderOutputFile>
+      <AssemblerOutput>All</AssemblerOutput>
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+      <ObjectFileName>$(IntDir)</ObjectFileName>
+      <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+      <BrowseInformation>
+      </BrowseInformation>
+      <WarningLevel>Level3</WarningLevel>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+    </ClCompile>
+    <ResourceCompile>
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <Culture>0x040c</Culture>
+    </ResourceCompile>
+    <Link>
+      <AdditionalOptions>/MACHINE:I386 %(AdditionalOptions)</AdditionalOptions>
+      <AdditionalDependencies>..\..\masmx86\match686.obj;..\..\masmx86\inffas32.obj;%(AdditionalDependencies)</AdditionalDependencies>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+      <ModuleDefinitionFile>.\zlibvc.def</ModuleDefinitionFile>
+      <GenerateMapFile>true</GenerateMapFile>
+      <SubSystem>Windows</SubSystem>
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>
+      <DataExecutionPrevention>
+      </DataExecutionPrevention>
+    </Link>
+    <PreBuildEvent>
+      <Command>cd ..\..\masmx86
+bld_ml32.bat</Command>
+    </PreBuildEvent>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <Midl>
+      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <MkTypLibCompatible>true</MkTypLibCompatible>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <TargetEnvironment>X64</TargetEnvironment>
+      <TypeLibraryName>$(OutDir)zlibvc.tlb</TypeLibraryName>
+    </Midl>
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;ASMV;ASMINF;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <ExceptionHandling>
+      </ExceptionHandling>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+      <PrecompiledHeaderOutputFile>$(IntDir)zlibvc.pch</PrecompiledHeaderOutputFile>
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+      <ObjectFileName>$(IntDir)</ObjectFileName>
+      <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+      <BrowseInformation>
+      </BrowseInformation>
+      <WarningLevel>Level3</WarningLevel>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <ResourceCompile>
+      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <Culture>0x040c</Culture>
+    </ResourceCompile>
+    <Link>
+      <AdditionalDependencies>..\..\masmx64\gvmat64.obj;..\..\masmx64\inffasx64.obj;%(AdditionalDependencies)</AdditionalDependencies>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <ModuleDefinitionFile>.\zlibvc.def</ModuleDefinitionFile>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <GenerateMapFile>true</GenerateMapFile>
+      <SubSystem>Windows</SubSystem>
+      <TargetMachine>MachineX64</TargetMachine>
+    </Link>
+    <PreBuildEvent>
+      <Command>cd ..\..\masmx64
+bld_ml64.bat</Command>
+    </PreBuildEvent>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">
+    <Midl>
+      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <MkTypLibCompatible>true</MkTypLibCompatible>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <TargetEnvironment>Itanium</TargetEnvironment>
+      <TypeLibraryName>$(OutDir)zlibvc.tlb</TypeLibraryName>
+    </Midl>
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <ExceptionHandling>
+      </ExceptionHandling>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+      <PrecompiledHeaderOutputFile>$(IntDir)zlibvc.pch</PrecompiledHeaderOutputFile>
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+      <ObjectFileName>$(IntDir)</ObjectFileName>
+      <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+      <BrowseInformation>
+      </BrowseInformation>
+      <WarningLevel>Level3</WarningLevel>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <ResourceCompile>
+      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <Culture>0x040c</Culture>
+    </ResourceCompile>
+    <Link>
+      <OutputFile>$(OutDir)zlibwapi.dll</OutputFile>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <ModuleDefinitionFile>.\zlibvc.def</ModuleDefinitionFile>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <ProgramDatabaseFile>$(OutDir)zlibwapi.pdb</ProgramDatabaseFile>
+      <GenerateMapFile>true</GenerateMapFile>
+      <MapFileName>$(OutDir)zlibwapi.map</MapFileName>
+      <SubSystem>Windows</SubSystem>
+      <ImportLibrary>$(OutDir)zlibwapi.lib</ImportLibrary>
+      <TargetMachine>MachineIA64</TargetMachine>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">
+    <Midl>
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <MkTypLibCompatible>true</MkTypLibCompatible>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <TargetEnvironment>X64</TargetEnvironment>
+      <TypeLibraryName>$(OutDir)zlibvc.tlb</TypeLibraryName>
+    </Midl>
+    <ClCompile>
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+      <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <StringPooling>true</StringPooling>
+      <ExceptionHandling>
+      </ExceptionHandling>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <PrecompiledHeaderOutputFile>$(IntDir)zlibvc.pch</PrecompiledHeaderOutputFile>
+      <AssemblerOutput>All</AssemblerOutput>
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+      <ObjectFileName>$(IntDir)</ObjectFileName>
+      <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+      <BrowseInformation>
+      </BrowseInformation>
+      <WarningLevel>Level3</WarningLevel>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+    </ClCompile>
+    <ResourceCompile>
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <Culture>0x040c</Culture>
+    </ResourceCompile>
+    <Link>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+      <ModuleDefinitionFile>.\zlibvc.def</ModuleDefinitionFile>
+      <GenerateMapFile>true</GenerateMapFile>
+      <SubSystem>Windows</SubSystem>
+      <TargetMachine>MachineX64</TargetMachine>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">
+    <Midl>
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <MkTypLibCompatible>true</MkTypLibCompatible>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <TargetEnvironment>Itanium</TargetEnvironment>
+      <TypeLibraryName>$(OutDir)zlibvc.tlb</TypeLibraryName>
+    </Midl>
+    <ClCompile>
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+      <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <StringPooling>true</StringPooling>
+      <ExceptionHandling>
+      </ExceptionHandling>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <PrecompiledHeaderOutputFile>$(IntDir)zlibvc.pch</PrecompiledHeaderOutputFile>
+      <AssemblerOutput>All</AssemblerOutput>
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+      <ObjectFileName>$(IntDir)</ObjectFileName>
+      <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+      <BrowseInformation>
+      </BrowseInformation>
+      <WarningLevel>Level3</WarningLevel>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+    </ClCompile>
+    <ResourceCompile>
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <Culture>0x040c</Culture>
+    </ResourceCompile>
+    <Link>
+      <OutputFile>$(OutDir)zlibwapi.dll</OutputFile>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+      <ModuleDefinitionFile>.\zlibvc.def</ModuleDefinitionFile>
+      <ProgramDatabaseFile>$(OutDir)zlibwapi.pdb</ProgramDatabaseFile>
+      <GenerateMapFile>true</GenerateMapFile>
+      <MapFileName>$(OutDir)zlibwapi.map</MapFileName>
+      <SubSystem>Windows</SubSystem>
+      <ImportLibrary>$(OutDir)zlibwapi.lib</ImportLibrary>
+      <TargetMachine>MachineIA64</TargetMachine>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <Midl>
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <MkTypLibCompatible>true</MkTypLibCompatible>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <TargetEnvironment>X64</TargetEnvironment>
+      <TypeLibraryName>$(OutDir)zlibvc.tlb</TypeLibraryName>
+    </Midl>
+    <ClCompile>
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+      <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;ASMV;ASMINF;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <StringPooling>true</StringPooling>
+      <ExceptionHandling>
+      </ExceptionHandling>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <PrecompiledHeaderOutputFile>$(IntDir)zlibvc.pch</PrecompiledHeaderOutputFile>
+      <AssemblerOutput>All</AssemblerOutput>
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+      <ObjectFileName>$(IntDir)</ObjectFileName>
+      <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+      <BrowseInformation>
+      </BrowseInformation>
+      <WarningLevel>Level3</WarningLevel>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+    </ClCompile>
+    <ResourceCompile>
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <Culture>0x040c</Culture>
+    </ResourceCompile>
+    <Link>
+      <AdditionalDependencies>..\..\masmx64\gvmat64.obj;..\..\masmx64\inffasx64.obj;%(AdditionalDependencies)</AdditionalDependencies>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+      <ModuleDefinitionFile>.\zlibvc.def</ModuleDefinitionFile>
+      <GenerateMapFile>true</GenerateMapFile>
+      <SubSystem>Windows</SubSystem>
+      <TargetMachine>MachineX64</TargetMachine>
+    </Link>
+    <PreBuildEvent>
+      <Command>cd ..\..\masmx64
+bld_ml64.bat</Command>
+    </PreBuildEvent>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">
+    <Midl>
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <MkTypLibCompatible>true</MkTypLibCompatible>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <TargetEnvironment>Itanium</TargetEnvironment>
+      <TypeLibraryName>$(OutDir)zlibvc.tlb</TypeLibraryName>
+    </Midl>
+    <ClCompile>
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+      <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <StringPooling>true</StringPooling>
+      <ExceptionHandling>
+      </ExceptionHandling>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <PrecompiledHeaderOutputFile>$(IntDir)zlibvc.pch</PrecompiledHeaderOutputFile>
+      <AssemblerOutput>All</AssemblerOutput>
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+      <ObjectFileName>$(IntDir)</ObjectFileName>
+      <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+      <BrowseInformation>
+      </BrowseInformation>
+      <WarningLevel>Level3</WarningLevel>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+    </ClCompile>
+    <ResourceCompile>
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <Culture>0x040c</Culture>
+    </ResourceCompile>
+    <Link>
+      <OutputFile>$(OutDir)zlibwapi.dll</OutputFile>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+      <ModuleDefinitionFile>.\zlibvc.def</ModuleDefinitionFile>
+      <ProgramDatabaseFile>$(OutDir)zlibwapi.pdb</ProgramDatabaseFile>
+      <GenerateMapFile>true</GenerateMapFile>
+      <MapFileName>$(OutDir)zlibwapi.map</MapFileName>
+      <SubSystem>Windows</SubSystem>
+      <ImportLibrary>$(OutDir)zlibwapi.lib</ImportLibrary>
+      <TargetMachine>MachineIA64</TargetMachine>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <ClCompile Include="..\..\..\adler32.c" />
+    <ClCompile Include="..\..\..\compress.c" />
+    <ClCompile Include="..\..\..\crc32.c" />
+    <ClCompile Include="..\..\..\deflate.c" />
+    <ClCompile Include="..\..\..\gzclose.c" />
+    <ClCompile Include="..\..\..\gzlib.c" />
+    <ClCompile Include="..\..\..\gzread.c" />
+    <ClCompile Include="..\..\..\gzwrite.c" />
+    <ClCompile Include="..\..\..\infback.c" />
+    <ClCompile Include="..\..\masmx64\inffas8664.c">
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
+    </ClCompile>
+    <ClCompile Include="..\..\..\inffast.c" />
+    <ClCompile Include="..\..\..\inflate.c" />
+    <ClCompile Include="..\..\..\inftrees.c" />
+    <ClCompile Include="..\..\minizip\ioapi.c" />
+    <ClCompile Include="..\..\minizip\iowin32.c" />
+    <ClCompile Include="..\..\..\trees.c" />
+    <ClCompile Include="..\..\..\uncompr.c" />
+    <ClCompile Include="..\..\minizip\unzip.c">
+      <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">ZLIB_INTERNAL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">ZLIB_INTERNAL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">ZLIB_INTERNAL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ClCompile>
+    <ClCompile Include="..\..\minizip\zip.c">
+      <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">ZLIB_INTERNAL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">ZLIB_INTERNAL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">ZLIB_INTERNAL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ClCompile>
+    <ClCompile Include="..\..\..\zutil.c" />
+  </ItemGroup>
+  <ItemGroup>
+    <ResourceCompile Include="zlib.rc" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="zlibvc.def" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="..\..\..\deflate.h" />
+    <ClInclude Include="..\..\..\infblock.h" />
+    <ClInclude Include="..\..\..\infcodes.h" />
+    <ClInclude Include="..\..\..\inffast.h" />
+    <ClInclude Include="..\..\..\inftrees.h" />
+    <ClInclude Include="..\..\..\infutil.h" />
+    <ClInclude Include="..\..\..\zconf.h" />
+    <ClInclude Include="..\..\..\zlib.h" />
+    <ClInclude Include="..\..\..\zutil.h" />
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
\ No newline at end of file
diff --git a/compat/zlib/contrib/vstudio/vc10/zlibvc.vcxproj.filters b/compat/zlib/contrib/vstudio/vc10/zlibvc.vcxproj.filters
new file mode 100644
index 0000000..180b71c
--- /dev/null
+++ b/compat/zlib/contrib/vstudio/vc10/zlibvc.vcxproj.filters
@@ -0,0 +1,118 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <Filter Include="Source Files">
+      <UniqueIdentifier>{07934a85-8b61-443d-a0ee-b2eedb74f3cd}</UniqueIdentifier>
+      <Extensions>cpp;c;cxx;rc;def;r;odl;hpj;bat;for;f90</Extensions>
+    </Filter>
+    <Filter Include="Header Files">
+      <UniqueIdentifier>{1d99675b-433d-4a21-9e50-ed4ab8b19762}</UniqueIdentifier>
+      <Extensions>h;hpp;hxx;hm;inl;fi;fd</Extensions>
+    </Filter>
+    <Filter Include="Resource Files">
+      <UniqueIdentifier>{431c0958-fa71-44d0-9084-2d19d100c0cc}</UniqueIdentifier>
+      <Extensions>ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe</Extensions>
+    </Filter>
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="..\..\..\adler32.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\compress.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\crc32.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\deflate.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\gzclose.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\gzlib.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\gzread.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\gzwrite.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\infback.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\masmx64\inffas8664.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\inffast.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\inflate.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\inftrees.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\minizip\ioapi.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\minizip\iowin32.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\trees.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\uncompr.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\minizip\unzip.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\minizip\zip.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\..\zutil.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ResourceCompile Include="zlib.rc">
+      <Filter>Source Files</Filter>
+    </ResourceCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="zlibvc.def">
+      <Filter>Source Files</Filter>
+    </None>
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="..\..\..\deflate.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\infblock.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\infcodes.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\inffast.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\inftrees.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\infutil.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\zconf.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\zlib.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\..\zutil.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
+  </ItemGroup>
+</Project>
\ No newline at end of file
diff --git a/compat/zlib/contrib/vstudio/vc11/miniunz.vcxproj b/compat/zlib/contrib/vstudio/vc11/miniunz.vcxproj
new file mode 100644
index 0000000..8f9f20b
--- /dev/null
+++ b/compat/zlib/contrib/vstudio/vc11/miniunz.vcxproj
@@ -0,0 +1,314 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Itanium">
+      <Configuration>Debug</Configuration>
+      <Platform>Itanium</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Itanium">
+      <Configuration>Release</Configuration>
+      <Platform>Itanium</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{C52F9E7B-498A-42BE-8DB4-85A15694382A}</ProjectGuid>
+    <Keyword>Win32Proj</Keyword>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>MultiByte</CharacterSet>
+    <PlatformToolset>v110</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+    <PlatformToolset>v110</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>MultiByte</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>MultiByte</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>MultiByte</CharacterSet>
+    <PlatformToolset>v110</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>MultiByte</CharacterSet>
+    <PlatformToolset>v110</PlatformToolset>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup>
+    <_ProjectFileVersion>10.0.30128.1</_ProjectFileVersion>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">x86\MiniUnzip$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">x86\MiniUnzip$(Configuration)\Tmp\</IntDir>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
+    <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</GenerateManifest>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">x86\MiniUnzip$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">x86\MiniUnzip$(Configuration)\Tmp\</IntDir>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
+    <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</GenerateManifest>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">x64\MiniUnzip$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">x64\MiniUnzip$(Configuration)\Tmp\</IntDir>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>
+    <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</GenerateManifest>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">ia64\MiniUnzip$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">ia64\MiniUnzip$(Configuration)\Tmp\</IntDir>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">true</LinkIncremental>
+    <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">false</GenerateManifest>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">x64\MiniUnzip$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">x64\MiniUnzip$(Configuration)\Tmp\</IntDir>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
+    <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</GenerateManifest>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">ia64\MiniUnzip$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">ia64\MiniUnzip$(Configuration)\Tmp\</IntDir>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">false</LinkIncremental>
+    <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">false</GenerateManifest>
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">AllRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" />
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" />
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">AllRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" />
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" />
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <MinimalRebuild>true</MinimalRebuild>
+      <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>x86\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <OutputFile>$(OutDir)miniunz.exe</OutputFile>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <ProgramDatabaseFile>$(OutDir)miniunz.pdb</ProgramDatabaseFile>
+      <SubSystem>Console</SubSystem>
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>
+      <DataExecutionPrevention>
+      </DataExecutionPrevention>
+      <TargetMachine>MachineX86</TargetMachine>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <Optimization>MaxSpeed</Optimization>
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+      <OmitFramePointers>true</OmitFramePointers>
+      <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <StringPooling>true</StringPooling>
+      <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>x86\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <OutputFile>$(OutDir)miniunz.exe</OutputFile>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <OptimizeReferences>true</OptimizeReferences>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>
+      <DataExecutionPrevention>
+      </DataExecutionPrevention>
+      <TargetMachine>MachineX86</TargetMachine>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <Midl>
+      <TargetEnvironment>X64</TargetEnvironment>
+    </Midl>
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <MinimalRebuild>true</MinimalRebuild>
+      <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>x64\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <OutputFile>$(OutDir)miniunz.exe</OutputFile>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <ProgramDatabaseFile>$(OutDir)miniunz.pdb</ProgramDatabaseFile>
+      <SubSystem>Console</SubSystem>
+      <TargetMachine>MachineX64</TargetMachine>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">
+    <Midl>
+      <TargetEnvironment>Itanium</TargetEnvironment>
+    </Midl>
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <MinimalRebuild>true</MinimalRebuild>
+      <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>ia64\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <OutputFile>$(OutDir)miniunz.exe</OutputFile>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <ProgramDatabaseFile>$(OutDir)miniunz.pdb</ProgramDatabaseFile>
+      <SubSystem>Console</SubSystem>
+      <TargetMachine>MachineIA64</TargetMachine>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <Midl>
+      <TargetEnvironment>X64</TargetEnvironment>
+    </Midl>
+    <ClCompile>
+      <Optimization>MaxSpeed</Optimization>
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+      <OmitFramePointers>true</OmitFramePointers>
+      <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <StringPooling>true</StringPooling>
+      <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>x64\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <OutputFile>$(OutDir)miniunz.exe</OutputFile>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <OptimizeReferences>true</OptimizeReferences>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <TargetMachine>MachineX64</TargetMachine>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">
+    <Midl>
+      <TargetEnvironment>Itanium</TargetEnvironment>
+    </Midl>
+    <ClCompile>
+      <Optimization>MaxSpeed</Optimization>
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+      <OmitFramePointers>true</OmitFramePointers>
+      <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <StringPooling>true</StringPooling>
+      <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>ia64\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <OutputFile>$(OutDir)miniunz.exe</OutputFile>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <OptimizeReferences>true</OptimizeReferences>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <TargetMachine>MachineIA64</TargetMachine>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <ClCompile Include="..\..\minizip\miniunz.c" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="zlibvc.vcxproj">
+      <Project>{8fd826f8-3739-44e6-8cc8-997122e53b8d}</Project>
+    </ProjectReference>
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
\ No newline at end of file
diff --git a/compat/zlib/contrib/vstudio/vc11/minizip.vcxproj b/compat/zlib/contrib/vstudio/vc11/minizip.vcxproj
new file mode 100644
index 0000000..c93d9e6
--- /dev/null
+++ b/compat/zlib/contrib/vstudio/vc11/minizip.vcxproj
@@ -0,0 +1,311 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Itanium">
+      <Configuration>Debug</Configuration>
+      <Platform>Itanium</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Itanium">
+      <Configuration>Release</Configuration>
+      <Platform>Itanium</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}</ProjectGuid>
+    <Keyword>Win32Proj</Keyword>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>MultiByte</CharacterSet>
+    <PlatformToolset>v110</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+    <PlatformToolset>v110</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>MultiByte</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>MultiByte</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>MultiByte</CharacterSet>
+    <PlatformToolset>v110</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>MultiByte</CharacterSet>
+    <PlatformToolset>v110</PlatformToolset>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup>
+    <_ProjectFileVersion>10.0.30128.1</_ProjectFileVersion>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">x86\MiniZip$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">x86\MiniZip$(Configuration)\Tmp\</IntDir>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
+    <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</GenerateManifest>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">x86\MiniZip$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">x86\MiniZip$(Configuration)\Tmp\</IntDir>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">x64\$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">x64\$(Configuration)\</IntDir>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>
+    <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</GenerateManifest>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">ia64\$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">ia64\$(Configuration)\</IntDir>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">true</LinkIncremental>
+    <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">false</GenerateManifest>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">x64\$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">x64\$(Configuration)\</IntDir>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">ia64\$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">ia64\$(Configuration)\</IntDir>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">false</LinkIncremental>
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">AllRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" />
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" />
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">AllRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" />
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" />
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <MinimalRebuild>true</MinimalRebuild>
+      <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>x86\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <OutputFile>$(OutDir)minizip.exe</OutputFile>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <ProgramDatabaseFile>$(OutDir)minizip.pdb</ProgramDatabaseFile>
+      <SubSystem>Console</SubSystem>
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>
+      <DataExecutionPrevention>
+      </DataExecutionPrevention>
+      <TargetMachine>MachineX86</TargetMachine>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <Optimization>MaxSpeed</Optimization>
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+      <OmitFramePointers>true</OmitFramePointers>
+      <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <StringPooling>true</StringPooling>
+      <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>x86\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <OutputFile>$(OutDir)minizip.exe</OutputFile>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <OptimizeReferences>true</OptimizeReferences>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>
+      <DataExecutionPrevention>
+      </DataExecutionPrevention>
+      <TargetMachine>MachineX86</TargetMachine>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <Midl>
+      <TargetEnvironment>X64</TargetEnvironment>
+    </Midl>
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <MinimalRebuild>true</MinimalRebuild>
+      <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>x64\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <OutputFile>$(OutDir)minizip.exe</OutputFile>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <ProgramDatabaseFile>$(OutDir)minizip.pdb</ProgramDatabaseFile>
+      <SubSystem>Console</SubSystem>
+      <TargetMachine>MachineX64</TargetMachine>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">
+    <Midl>
+      <TargetEnvironment>Itanium</TargetEnvironment>
+    </Midl>
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <MinimalRebuild>true</MinimalRebuild>
+      <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>ia64\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <OutputFile>$(OutDir)minizip.exe</OutputFile>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <ProgramDatabaseFile>$(OutDir)minizip.pdb</ProgramDatabaseFile>
+      <SubSystem>Console</SubSystem>
+      <TargetMachine>MachineIA64</TargetMachine>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <Midl>
+      <TargetEnvironment>X64</TargetEnvironment>
+    </Midl>
+    <ClCompile>
+      <Optimization>MaxSpeed</Optimization>
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+      <OmitFramePointers>true</OmitFramePointers>
+      <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <StringPooling>true</StringPooling>
+      <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>x64\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <OutputFile>$(OutDir)minizip.exe</OutputFile>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <OptimizeReferences>true</OptimizeReferences>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <TargetMachine>MachineX64</TargetMachine>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">
+    <Midl>
+      <TargetEnvironment>Itanium</TargetEnvironment>
+    </Midl>
+    <ClCompile>
+      <Optimization>MaxSpeed</Optimization>
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+      <OmitFramePointers>true</OmitFramePointers>
+      <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <StringPooling>true</StringPooling>
+      <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>ia64\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <OutputFile>$(OutDir)minizip.exe</OutputFile>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <OptimizeReferences>true</OptimizeReferences>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <TargetMachine>MachineIA64</TargetMachine>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <ClCompile Include="..\..\minizip\minizip.c" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="zlibvc.vcxproj">
+      <Project>{8fd826f8-3739-44e6-8cc8-997122e53b8d}</Project>
+    </ProjectReference>
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
\ No newline at end of file
diff --git a/compat/zlib/contrib/vstudio/vc11/testzlib.vcxproj b/compat/zlib/contrib/vstudio/vc11/testzlib.vcxproj
new file mode 100644
index 0000000..6d55954
--- /dev/null
+++ b/compat/zlib/contrib/vstudio/vc11/testzlib.vcxproj
@@ -0,0 +1,426 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Itanium">
+      <Configuration>Debug</Configuration>
+      <Platform>Itanium</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="ReleaseWithoutAsm|Itanium">
+      <Configuration>ReleaseWithoutAsm</Configuration>
+      <Platform>Itanium</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="ReleaseWithoutAsm|Win32">
+      <Configuration>ReleaseWithoutAsm</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="ReleaseWithoutAsm|x64">
+      <Configuration>ReleaseWithoutAsm</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Itanium">
+      <Configuration>Release</Configuration>
+      <Platform>Itanium</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}</ProjectGuid>
+    <RootNamespace>testzlib</RootNamespace>
+    <Keyword>Win32Proj</Keyword>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>MultiByte</CharacterSet>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <PlatformToolset>v110</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>MultiByte</CharacterSet>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <PlatformToolset>v110</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+    <PlatformToolset>v110</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>MultiByte</CharacterSet>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>MultiByte</CharacterSet>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>MultiByte</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <PlatformToolset>v110</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <PlatformToolset>v110</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <PlatformToolset>v110</PlatformToolset>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup>
+    <_ProjectFileVersion>10.0.30128.1</_ProjectFileVersion>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">x86\TestZlib$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">x86\TestZlib$(Configuration)\Tmp\</IntDir>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
+    <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</GenerateManifest>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">x86\TestZlib$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">x86\TestZlib$(Configuration)\Tmp\</IntDir>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">false</LinkIncremental>
+    <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">false</GenerateManifest>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">x86\TestZlib$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">x86\TestZlib$(Configuration)\Tmp\</IntDir>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
+    <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</GenerateManifest>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">x64\TestZlib$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">x64\TestZlib$(Configuration)\Tmp\</IntDir>
+    <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</GenerateManifest>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">ia64\TestZlib$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">ia64\TestZlib$(Configuration)\Tmp\</IntDir>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">true</LinkIncremental>
+    <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">false</GenerateManifest>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">x64\TestZlib$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">x64\TestZlib$(Configuration)\Tmp\</IntDir>
+    <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">false</GenerateManifest>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">ia64\TestZlib$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">ia64\TestZlib$(Configuration)\Tmp\</IntDir>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">false</LinkIncremental>
+    <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">false</GenerateManifest>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">x64\TestZlib$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">x64\TestZlib$(Configuration)\Tmp\</IntDir>
+    <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</GenerateManifest>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">ia64\TestZlib$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">ia64\TestZlib$(Configuration)\Tmp\</IntDir>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">false</LinkIncremental>
+    <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">false</GenerateManifest>
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">AllRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" />
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" />
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">AllRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'" />
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'" />
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'" />
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'" />
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'" />
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'" />
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">AllRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" />
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" />
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>..\..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>ASMV;ASMINF;WIN32;ZLIB_WINAPI;_DEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <MinimalRebuild>true</MinimalRebuild>
+      <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <AssemblerOutput>AssemblyAndSourceCode</AssemblerOutput>
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>..\..\masmx86\match686.obj;..\..\masmx86\inffas32.obj;%(AdditionalDependencies)</AdditionalDependencies>
+      <OutputFile>$(OutDir)testzlib.exe</OutputFile>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <ProgramDatabaseFile>$(OutDir)testzlib.pdb</ProgramDatabaseFile>
+      <SubSystem>Console</SubSystem>
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>
+      <DataExecutionPrevention>
+      </DataExecutionPrevention>
+      <TargetMachine>MachineX86</TargetMachine>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">
+    <ClCompile>
+      <Optimization>MaxSpeed</Optimization>
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+      <OmitFramePointers>true</OmitFramePointers>
+      <AdditionalIncludeDirectories>..\..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <StringPooling>true</StringPooling>
+      <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <OutputFile>$(OutDir)testzlib.exe</OutputFile>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <OptimizeReferences>true</OptimizeReferences>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>
+      <DataExecutionPrevention>
+      </DataExecutionPrevention>
+      <TargetMachine>MachineX86</TargetMachine>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <Optimization>MaxSpeed</Optimization>
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+      <OmitFramePointers>true</OmitFramePointers>
+      <AdditionalIncludeDirectories>..\..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>ASMV;ASMINF;WIN32;ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <StringPooling>true</StringPooling>
+      <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>..\..\masmx86\match686.obj;..\..\masmx86\inffas32.obj;%(AdditionalDependencies)</AdditionalDependencies>
+      <OutputFile>$(OutDir)testzlib.exe</OutputFile>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <OptimizeReferences>true</OptimizeReferences>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>
+      <DataExecutionPrevention>
+      </DataExecutionPrevention>
+      <TargetMachine>MachineX86</TargetMachine>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <AdditionalIncludeDirectories>..\..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>ASMV;ASMINF;WIN32;ZLIB_WINAPI;_DEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>..\..\masmx64\gvmat64.obj;..\..\masmx64\inffasx64.obj;%(AdditionalDependencies)</AdditionalDependencies>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">
+    <Midl>
+      <TargetEnvironment>Itanium</TargetEnvironment>
+    </Midl>
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>..\..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>ZLIB_WINAPI;_DEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <MinimalRebuild>true</MinimalRebuild>
+      <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <AssemblerOutput>AssemblyAndSourceCode</AssemblerOutput>
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <OutputFile>$(OutDir)testzlib.exe</OutputFile>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <ProgramDatabaseFile>$(OutDir)testzlib.pdb</ProgramDatabaseFile>
+      <SubSystem>Console</SubSystem>
+      <TargetMachine>MachineIA64</TargetMachine>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">
+    <ClCompile>
+      <AdditionalIncludeDirectories>..\..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">
+    <Midl>
+      <TargetEnvironment>Itanium</TargetEnvironment>
+    </Midl>
+    <ClCompile>
+      <Optimization>MaxSpeed</Optimization>
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+      <OmitFramePointers>true</OmitFramePointers>
+      <AdditionalIncludeDirectories>..\..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <StringPooling>true</StringPooling>
+      <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <OutputFile>$(OutDir)testzlib.exe</OutputFile>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <OptimizeReferences>true</OptimizeReferences>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <TargetMachine>MachineIA64</TargetMachine>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <AdditionalIncludeDirectories>..\..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>ASMV;ASMINF;WIN32;ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>..\..\masmx64\gvmat64.obj;..\..\masmx64\inffasx64.obj;%(AdditionalDependencies)</AdditionalDependencies>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">
+    <Midl>
+      <TargetEnvironment>Itanium</TargetEnvironment>
+    </Midl>
+    <ClCompile>
+      <Optimization>MaxSpeed</Optimization>
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+      <OmitFramePointers>true</OmitFramePointers>
+      <AdditionalIncludeDirectories>..\..\..;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <StringPooling>true</StringPooling>
+      <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <OutputFile>$(OutDir)testzlib.exe</OutputFile>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <OptimizeReferences>true</OptimizeReferences>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <TargetMachine>MachineIA64</TargetMachine>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <ClCompile Include="..\..\..\adler32.c" />
+    <ClCompile Include="..\..\..\compress.c" />
+    <ClCompile Include="..\..\..\crc32.c" />
+    <ClCompile Include="..\..\..\deflate.c" />
+    <ClCompile Include="..\..\..\infback.c" />
+    <ClCompile Include="..\..\masmx64\inffas8664.c">
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
+    </ClCompile>
+    <ClCompile Include="..\..\..\inffast.c" />
+    <ClCompile Include="..\..\..\inflate.c" />
+    <ClCompile Include="..\..\..\inftrees.c" />
+    <ClCompile Include="..\..\testzlib\testzlib.c" />
+    <ClCompile Include="..\..\..\trees.c" />
+    <ClCompile Include="..\..\..\uncompr.c" />
+    <ClCompile Include="..\..\..\zutil.c" />
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
\ No newline at end of file
diff --git a/compat/zlib/contrib/vstudio/vc11/testzlibdll.vcxproj b/compat/zlib/contrib/vstudio/vc11/testzlibdll.vcxproj
new file mode 100644
index 0000000..9f20c78
--- /dev/null
+++ b/compat/zlib/contrib/vstudio/vc11/testzlibdll.vcxproj
@@ -0,0 +1,314 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Itanium">
+      <Configuration>Debug</Configuration>
+      <Platform>Itanium</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Itanium">
+      <Configuration>Release</Configuration>
+      <Platform>Itanium</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{C52F9E7B-498A-42BE-8DB4-85A15694366A}</ProjectGuid>
+    <Keyword>Win32Proj</Keyword>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>MultiByte</CharacterSet>
+    <PlatformToolset>v110</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>Unicode</CharacterSet>
+    <PlatformToolset>v110</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>MultiByte</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>MultiByte</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>MultiByte</CharacterSet>
+    <PlatformToolset>v110</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <CharacterSet>MultiByte</CharacterSet>
+    <PlatformToolset>v110</PlatformToolset>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup>
+    <_ProjectFileVersion>10.0.30128.1</_ProjectFileVersion>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">x86\TestZlibDll$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">x86\TestZlibDll$(Configuration)\Tmp\</IntDir>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
+    <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</GenerateManifest>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">x86\TestZlibDll$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">x86\TestZlibDll$(Configuration)\Tmp\</IntDir>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
+    <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</GenerateManifest>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">x64\TestZlibDll$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">x64\TestZlibDll$(Configuration)\Tmp\</IntDir>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>
+    <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</GenerateManifest>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">ia64\TestZlibDll$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">ia64\TestZlibDll$(Configuration)\Tmp\</IntDir>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">true</LinkIncremental>
+    <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">false</GenerateManifest>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">x64\TestZlibDll$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">x64\TestZlibDll$(Configuration)\Tmp\</IntDir>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
+    <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</GenerateManifest>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">ia64\TestZlibDll$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">ia64\TestZlibDll$(Configuration)\Tmp\</IntDir>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">false</LinkIncremental>
+    <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">false</GenerateManifest>
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">AllRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" />
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" />
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">AllRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" />
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" />
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <MinimalRebuild>true</MinimalRebuild>
+      <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>x86\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <OutputFile>$(OutDir)testzlibdll.exe</OutputFile>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <ProgramDatabaseFile>$(OutDir)testzlib.pdb</ProgramDatabaseFile>
+      <SubSystem>Console</SubSystem>
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>
+      <DataExecutionPrevention>
+      </DataExecutionPrevention>
+      <TargetMachine>MachineX86</TargetMachine>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <Optimization>MaxSpeed</Optimization>
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+      <OmitFramePointers>true</OmitFramePointers>
+      <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <StringPooling>true</StringPooling>
+      <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>x86\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <OutputFile>$(OutDir)testzlibdll.exe</OutputFile>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <OptimizeReferences>true</OptimizeReferences>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>
+      <DataExecutionPrevention>
+      </DataExecutionPrevention>
+      <TargetMachine>MachineX86</TargetMachine>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <Midl>
+      <TargetEnvironment>X64</TargetEnvironment>
+    </Midl>
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <MinimalRebuild>true</MinimalRebuild>
+      <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>x64\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <OutputFile>$(OutDir)testzlibdll.exe</OutputFile>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <ProgramDatabaseFile>$(OutDir)testzlib.pdb</ProgramDatabaseFile>
+      <SubSystem>Console</SubSystem>
+      <TargetMachine>MachineX64</TargetMachine>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">
+    <Midl>
+      <TargetEnvironment>Itanium</TargetEnvironment>
+    </Midl>
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <MinimalRebuild>true</MinimalRebuild>
+      <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>ia64\ZlibDllDebug\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <OutputFile>$(OutDir)testzlibdll.exe</OutputFile>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <ProgramDatabaseFile>$(OutDir)testzlib.pdb</ProgramDatabaseFile>
+      <SubSystem>Console</SubSystem>
+      <TargetMachine>MachineIA64</TargetMachine>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <Midl>
+      <TargetEnvironment>X64</TargetEnvironment>
+    </Midl>
+    <ClCompile>
+      <Optimization>MaxSpeed</Optimization>
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+      <OmitFramePointers>true</OmitFramePointers>
+      <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <StringPooling>true</StringPooling>
+      <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>x64\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <OutputFile>$(OutDir)testzlibdll.exe</OutputFile>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <OptimizeReferences>true</OptimizeReferences>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <TargetMachine>MachineX64</TargetMachine>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">
+    <Midl>
+      <TargetEnvironment>Itanium</TargetEnvironment>
+    </Midl>
+    <ClCompile>
+      <Optimization>MaxSpeed</Optimization>
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+      <OmitFramePointers>true</OmitFramePointers>
+      <AdditionalIncludeDirectories>..\..\..;..\..\minizip;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <StringPooling>true</StringPooling>
+      <BasicRuntimeChecks>Default</BasicRuntimeChecks>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <PrecompiledHeader>
+      </PrecompiledHeader>
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+      <WarningLevel>Level3</WarningLevel>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <Link>
+      <AdditionalDependencies>ia64\ZlibDllRelease\zlibwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
+      <OutputFile>$(OutDir)testzlibdll.exe</OutputFile>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <SubSystem>Console</SubSystem>
+      <OptimizeReferences>true</OptimizeReferences>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <TargetMachine>MachineIA64</TargetMachine>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <ClCompile Include="..\..\testzlib\testzlib.c" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="zlibvc.vcxproj">
+      <Project>{8fd826f8-3739-44e6-8cc8-997122e53b8d}</Project>
+    </ProjectReference>
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
\ No newline at end of file
diff --git a/compat/zlib/contrib/vstudio/vc11/zlib.rc b/compat/zlib/contrib/vstudio/vc11/zlib.rc
new file mode 100644
index 0000000..73f6476
--- /dev/null
+++ b/compat/zlib/contrib/vstudio/vc11/zlib.rc
@@ -0,0 +1,32 @@
+#include <windows.h>
+
+#define IDR_VERSION1  1
+IDR_VERSION1	VERSIONINFO	MOVEABLE IMPURE LOADONCALL DISCARDABLE
+  FILEVERSION	 1,2,8,0
+  PRODUCTVERSION 1,2,8,0
+  FILEFLAGSMASK	VS_FFI_FILEFLAGSMASK
+  FILEFLAGS	0
+  FILEOS	VOS_DOS_WINDOWS32
+  FILETYPE	VFT_DLL
+  FILESUBTYPE	0	// not used
+BEGIN
+  BLOCK "StringFileInfo"
+  BEGIN
+    BLOCK "040904E4"
+    //language ID = U.S. English, char set = Windows, Multilingual
+
+    BEGIN
+      VALUE "FileDescription", "zlib data compression and ZIP file I/O library\0"
+      VALUE "FileVersion",	"1.2.8\0"
+      VALUE "InternalName",	"zlib\0"
+      VALUE "OriginalFilename",	"zlibwapi.dll\0"
+      VALUE "ProductName",	"ZLib.DLL\0"
+      VALUE "Comments","DLL support by Alessandro Iacopetti & Gilles Vollant\0"
+      VALUE "LegalCopyright", "(C) 1995-2013 Jean-loup Gailly & Mark Adler\0"
+    END
+  END
+  BLOCK "VarFileInfo"
+  BEGIN
+    VALUE "Translation", 0x0409, 1252
+  END
+END
diff --git a/compat/zlib/contrib/vstudio/vc11/zlibstat.vcxproj b/compat/zlib/contrib/vstudio/vc11/zlibstat.vcxproj
new file mode 100644
index 0000000..806b76a
--- /dev/null
+++ b/compat/zlib/contrib/vstudio/vc11/zlibstat.vcxproj
@@ -0,0 +1,464 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Itanium">
+      <Configuration>Debug</Configuration>
+      <Platform>Itanium</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="ReleaseWithoutAsm|Itanium">
+      <Configuration>ReleaseWithoutAsm</Configuration>
+      <Platform>Itanium</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="ReleaseWithoutAsm|Win32">
+      <Configuration>ReleaseWithoutAsm</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="ReleaseWithoutAsm|x64">
+      <Configuration>ReleaseWithoutAsm</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Itanium">
+      <Configuration>Release</Configuration>
+      <Platform>Itanium</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}</ProjectGuid>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <UseOfMfc>false</UseOfMfc>
+    <PlatformToolset>v110</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <UseOfMfc>false</UseOfMfc>
+    <PlatformToolset>v110</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <UseOfMfc>false</UseOfMfc>
+    <PlatformToolset>v110</PlatformToolset>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <UseOfMfc>false</UseOfMfc>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <UseOfMfc>false</UseOfMfc>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <UseOfMfc>false</UseOfMfc>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <UseOfMfc>false</UseOfMfc>
+    <PlatformToolset>v110</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <UseOfMfc>false</UseOfMfc>
+    <PlatformToolset>v110</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>StaticLibrary</ConfigurationType>
+    <UseOfMfc>false</UseOfMfc>
+    <PlatformToolset>v110</PlatformToolset>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup>
+    <_ProjectFileVersion>10.0.30128.1</_ProjectFileVersion>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">x86\ZlibStat$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">x86\ZlibStat$(Configuration)\Tmp\</IntDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">x86\ZlibStat$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">x86\ZlibStat$(Configuration)\Tmp\</IntDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">x86\ZlibStat$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">x86\ZlibStat$(Configuration)\Tmp\</IntDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">x64\ZlibStat$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">x64\ZlibStat$(Configuration)\Tmp\</IntDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">ia64\ZlibStat$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">ia64\ZlibStat$(Configuration)\Tmp\</IntDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">x64\ZlibStat$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">x64\ZlibStat$(Configuration)\Tmp\</IntDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">ia64\ZlibStat$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">ia64\ZlibStat$(Configuration)\Tmp\</IntDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">x64\ZlibStat$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">x64\ZlibStat$(Configuration)\Tmp\</IntDir>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">ia64\ZlibStat$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">ia64\ZlibStat$(Configuration)\Tmp\</IntDir>
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">AllRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" />
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" />
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">AllRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'" />
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'" />
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'" />
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'" />
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'" />
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'" />
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">AllRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" />
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" />
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <ExceptionHandling>
+      </ExceptionHandling>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+      <PrecompiledHeaderOutputFile>$(IntDir)zlibstat.pch</PrecompiledHeaderOutputFile>
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+      <ObjectFileName>$(IntDir)</ObjectFileName>
+      <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+      <WarningLevel>Level3</WarningLevel>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <DebugInformationFormat>OldStyle</DebugInformationFormat>
+    </ClCompile>
+    <ResourceCompile>
+      <Culture>0x040c</Culture>
+    </ResourceCompile>
+    <Lib>
+      <AdditionalOptions>/MACHINE:X86 /NODEFAULTLIB %(AdditionalOptions)</AdditionalOptions>
+      <OutputFile>$(OutDir)zlibstat.lib</OutputFile>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+    </Lib>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+      <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ASMV;ASMINF;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <StringPooling>true</StringPooling>
+      <ExceptionHandling>
+      </ExceptionHandling>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <PrecompiledHeaderOutputFile>$(IntDir)zlibstat.pch</PrecompiledHeaderOutputFile>
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+      <ObjectFileName>$(IntDir)</ObjectFileName>
+      <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+      <WarningLevel>Level3</WarningLevel>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+    </ClCompile>
+    <ResourceCompile>
+      <Culture>0x040c</Culture>
+    </ResourceCompile>
+    <Lib>
+      <AdditionalOptions>/MACHINE:X86 /NODEFAULTLIB %(AdditionalOptions)</AdditionalOptions>
+      <AdditionalDependencies>..\..\masmx86\match686.obj;..\..\masmx86\inffas32.obj;%(AdditionalDependencies)</AdditionalDependencies>
+      <OutputFile>$(OutDir)zlibstat.lib</OutputFile>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+    </Lib>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">
+    <ClCompile>
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+      <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <StringPooling>true</StringPooling>
+      <ExceptionHandling>
+      </ExceptionHandling>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <PrecompiledHeaderOutputFile>$(IntDir)zlibstat.pch</PrecompiledHeaderOutputFile>
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+      <ObjectFileName>$(IntDir)</ObjectFileName>
+      <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+      <WarningLevel>Level3</WarningLevel>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+    </ClCompile>
+    <ResourceCompile>
+      <Culture>0x040c</Culture>
+    </ResourceCompile>
+    <Lib>
+      <AdditionalOptions>/MACHINE:X86 /NODEFAULTLIB %(AdditionalOptions)</AdditionalOptions>
+      <OutputFile>$(OutDir)zlibstat.lib</OutputFile>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+    </Lib>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <Midl>
+      <TargetEnvironment>X64</TargetEnvironment>
+    </Midl>
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <ExceptionHandling>
+      </ExceptionHandling>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+      <PrecompiledHeaderOutputFile>$(IntDir)zlibstat.pch</PrecompiledHeaderOutputFile>
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+      <ObjectFileName>$(IntDir)</ObjectFileName>
+      <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+      <WarningLevel>Level3</WarningLevel>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <DebugInformationFormat>OldStyle</DebugInformationFormat>
+    </ClCompile>
+    <ResourceCompile>
+      <Culture>0x040c</Culture>
+    </ResourceCompile>
+    <Lib>
+      <AdditionalOptions>/MACHINE:AMD64 /NODEFAULTLIB %(AdditionalOptions)</AdditionalOptions>
+      <OutputFile>$(OutDir)zlibstat.lib</OutputFile>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+    </Lib>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">
+    <Midl>
+      <TargetEnvironment>Itanium</TargetEnvironment>
+    </Midl>
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <ExceptionHandling>
+      </ExceptionHandling>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+      <PrecompiledHeaderOutputFile>$(IntDir)zlibstat.pch</PrecompiledHeaderOutputFile>
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+      <ObjectFileName>$(IntDir)</ObjectFileName>
+      <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+      <WarningLevel>Level3</WarningLevel>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <DebugInformationFormat>OldStyle</DebugInformationFormat>
+    </ClCompile>
+    <ResourceCompile>
+      <Culture>0x040c</Culture>
+    </ResourceCompile>
+    <Lib>
+      <AdditionalOptions>/MACHINE:IA64 /NODEFAULTLIB %(AdditionalOptions)</AdditionalOptions>
+      <OutputFile>$(OutDir)zlibstat.lib</OutputFile>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+    </Lib>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <Midl>
+      <TargetEnvironment>X64</TargetEnvironment>
+    </Midl>
+    <ClCompile>
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+      <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ASMV;ASMINF;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <StringPooling>true</StringPooling>
+      <ExceptionHandling>
+      </ExceptionHandling>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <PrecompiledHeaderOutputFile>$(IntDir)zlibstat.pch</PrecompiledHeaderOutputFile>
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+      <ObjectFileName>$(IntDir)</ObjectFileName>
+      <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+      <WarningLevel>Level3</WarningLevel>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+    </ClCompile>
+    <ResourceCompile>
+      <Culture>0x040c</Culture>
+    </ResourceCompile>
+    <Lib>
+      <AdditionalOptions>/MACHINE:AMD64 /NODEFAULTLIB %(AdditionalOptions)</AdditionalOptions>
+      <AdditionalDependencies>..\..\masmx64\gvmat64.obj;..\..\masmx64\inffasx64.obj;%(AdditionalDependencies)</AdditionalDependencies>
+      <OutputFile>$(OutDir)zlibstat.lib</OutputFile>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+    </Lib>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">
+    <Midl>
+      <TargetEnvironment>Itanium</TargetEnvironment>
+    </Midl>
+    <ClCompile>
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+      <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <StringPooling>true</StringPooling>
+      <ExceptionHandling>
+      </ExceptionHandling>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <PrecompiledHeaderOutputFile>$(IntDir)zlibstat.pch</PrecompiledHeaderOutputFile>
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+      <ObjectFileName>$(IntDir)</ObjectFileName>
+      <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+      <WarningLevel>Level3</WarningLevel>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+    </ClCompile>
+    <ResourceCompile>
+      <Culture>0x040c</Culture>
+    </ResourceCompile>
+    <Lib>
+      <AdditionalOptions>/MACHINE:IA64 /NODEFAULTLIB %(AdditionalOptions)</AdditionalOptions>
+      <OutputFile>$(OutDir)zlibstat.lib</OutputFile>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+    </Lib>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">
+    <Midl>
+      <TargetEnvironment>X64</TargetEnvironment>
+    </Midl>
+    <ClCompile>
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+      <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <StringPooling>true</StringPooling>
+      <ExceptionHandling>
+      </ExceptionHandling>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <PrecompiledHeaderOutputFile>$(IntDir)zlibstat.pch</PrecompiledHeaderOutputFile>
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+      <ObjectFileName>$(IntDir)</ObjectFileName>
+      <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+      <WarningLevel>Level3</WarningLevel>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+    </ClCompile>
+    <ResourceCompile>
+      <Culture>0x040c</Culture>
+    </ResourceCompile>
+    <Lib>
+      <AdditionalOptions>/MACHINE:AMD64 /NODEFAULTLIB %(AdditionalOptions)</AdditionalOptions>
+      <OutputFile>$(OutDir)zlibstat.lib</OutputFile>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+    </Lib>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">
+    <Midl>
+      <TargetEnvironment>Itanium</TargetEnvironment>
+    </Midl>
+    <ClCompile>
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+      <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <StringPooling>true</StringPooling>
+      <ExceptionHandling>
+      </ExceptionHandling>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <PrecompiledHeaderOutputFile>$(IntDir)zlibstat.pch</PrecompiledHeaderOutputFile>
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+      <ObjectFileName>$(IntDir)</ObjectFileName>
+      <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+      <WarningLevel>Level3</WarningLevel>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+    </ClCompile>
+    <ResourceCompile>
+      <Culture>0x040c</Culture>
+    </ResourceCompile>
+    <Lib>
+      <AdditionalOptions>/MACHINE:IA64 /NODEFAULTLIB %(AdditionalOptions)</AdditionalOptions>
+      <OutputFile>$(OutDir)zlibstat.lib</OutputFile>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+    </Lib>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <ClCompile Include="..\..\..\adler32.c" />
+    <ClCompile Include="..\..\..\compress.c" />
+    <ClCompile Include="..\..\..\crc32.c" />
+    <ClCompile Include="..\..\..\deflate.c" />
+    <ClCompile Include="..\..\..\gzclose.c" />
+    <ClCompile Include="..\..\..\gzlib.c" />
+    <ClCompile Include="..\..\..\gzread.c" />
+    <ClCompile Include="..\..\..\gzwrite.c" />
+    <ClCompile Include="..\..\..\infback.c" />
+    <ClCompile Include="..\..\masmx64\inffas8664.c">
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
+    </ClCompile>
+    <ClCompile Include="..\..\..\inffast.c" />
+    <ClCompile Include="..\..\..\inflate.c" />
+    <ClCompile Include="..\..\..\inftrees.c" />
+    <ClCompile Include="..\..\minizip\ioapi.c" />
+    <ClCompile Include="..\..\..\trees.c" />
+    <ClCompile Include="..\..\..\uncompr.c" />
+    <ClCompile Include="..\..\minizip\unzip.c" />
+    <ClCompile Include="..\..\minizip\zip.c" />
+    <ClCompile Include="..\..\..\zutil.c" />
+  </ItemGroup>
+  <ItemGroup>
+    <ResourceCompile Include="zlib.rc" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="zlibvc.def" />
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
\ No newline at end of file
diff --git a/compat/zlib/contrib/vstudio/vc11/zlibvc.def b/compat/zlib/contrib/vstudio/vc11/zlibvc.def
new file mode 100644
index 0000000..6367046
--- /dev/null
+++ b/compat/zlib/contrib/vstudio/vc11/zlibvc.def
@@ -0,0 +1,143 @@
+LIBRARY
+; zlib data compression and ZIP file I/O library
+
+VERSION		1.2.8
+
+EXPORTS
+        adler32                                  @1
+        compress                                 @2
+        crc32                                    @3
+        deflate                                  @4
+        deflateCopy                              @5
+        deflateEnd                               @6
+        deflateInit2_                            @7
+        deflateInit_                             @8
+        deflateParams                            @9
+        deflateReset                             @10
+        deflateSetDictionary                     @11
+        gzclose                                  @12
+        gzdopen                                  @13
+        gzerror                                  @14
+        gzflush                                  @15
+        gzopen                                   @16
+        gzread                                   @17
+        gzwrite                                  @18
+        inflate                                  @19
+        inflateEnd                               @20
+        inflateInit2_                            @21
+        inflateInit_                             @22
+        inflateReset                             @23
+        inflateSetDictionary                     @24
+        inflateSync                              @25
+        uncompress                               @26
+        zlibVersion                              @27
+        gzprintf                                 @28
+        gzputc                                   @29
+        gzgetc                                   @30
+        gzseek                                   @31
+        gzrewind                                 @32
+        gztell                                   @33
+        gzeof                                    @34
+        gzsetparams                              @35
+        zError                                   @36
+        inflateSyncPoint                         @37
+        get_crc_table                            @38
+        compress2                                @39
+        gzputs                                   @40
+        gzgets                                   @41
+        inflateCopy                              @42
+        inflateBackInit_                         @43
+        inflateBack                              @44
+        inflateBackEnd                           @45
+        compressBound                            @46
+        deflateBound                             @47
+        gzclearerr                               @48
+        gzungetc                                 @49
+        zlibCompileFlags                         @50
+        deflatePrime                             @51
+        deflatePending                           @52
+
+        unzOpen                                  @61
+        unzClose                                 @62
+        unzGetGlobalInfo                         @63
+        unzGetCurrentFileInfo                    @64
+        unzGoToFirstFile                         @65
+        unzGoToNextFile                          @66
+        unzOpenCurrentFile                       @67
+        unzReadCurrentFile                       @68
+        unzOpenCurrentFile3                      @69
+        unztell                                  @70
+        unzeof                                   @71
+        unzCloseCurrentFile                      @72
+        unzGetGlobalComment                      @73
+        unzStringFileNameCompare                 @74
+        unzLocateFile                            @75
+        unzGetLocalExtrafield                    @76
+        unzOpen2                                 @77
+        unzOpenCurrentFile2                      @78
+        unzOpenCurrentFilePassword               @79
+
+        zipOpen                                  @80
+        zipOpenNewFileInZip                      @81
+        zipWriteInFileInZip                      @82
+        zipCloseFileInZip                        @83
+        zipClose                                 @84
+        zipOpenNewFileInZip2                     @86
+        zipCloseFileInZipRaw                     @87
+        zipOpen2                                 @88
+        zipOpenNewFileInZip3                     @89
+
+        unzGetFilePos                            @100
+        unzGoToFilePos                           @101
+
+        fill_win32_filefunc                      @110
+
+; zlibwapi v1.2.4 added:
+        fill_win32_filefunc64                   @111
+        fill_win32_filefunc64A                  @112
+        fill_win32_filefunc64W                  @113
+
+        unzOpen64                               @120
+        unzOpen2_64                             @121
+        unzGetGlobalInfo64                      @122
+        unzGetCurrentFileInfo64                 @124
+        unzGetCurrentFileZStreamPos64           @125
+        unztell64                               @126
+        unzGetFilePos64                         @127
+        unzGoToFilePos64                        @128
+
+        zipOpen64                               @130
+        zipOpen2_64                             @131
+        zipOpenNewFileInZip64                   @132
+        zipOpenNewFileInZip2_64                 @133
+        zipOpenNewFileInZip3_64                 @134
+        zipOpenNewFileInZip4_64                 @135
+        zipCloseFileInZipRaw64                  @136
+
+; zlib1 v1.2.4 added:
+        adler32_combine                         @140
+        crc32_combine                           @142
+        deflateSetHeader                        @144
+        deflateTune                             @145
+        gzbuffer                                @146
+        gzclose_r                               @147
+        gzclose_w                               @148
+        gzdirect                                @149
+        gzoffset                                @150
+        inflateGetHeader                        @156
+        inflateMark                             @157
+        inflatePrime                            @158
+        inflateReset2                           @159
+        inflateUndermine                        @160
+
+; zlib1 v1.2.6 added:
+        gzgetc_                                 @161
+        inflateResetKeep                        @163
+        deflateResetKeep                        @164
+
+; zlib1 v1.2.7 added:
+        gzopen_w                                @165
+
+; zlib1 v1.2.8 added:
+        inflateGetDictionary                    @166
+        gzvprintf                               @167
diff --git a/compat/zlib/contrib/vstudio/vc11/zlibvc.sln b/compat/zlib/contrib/vstudio/vc11/zlibvc.sln
new file mode 100644
index 0000000..9fcbafd
--- /dev/null
+++ b/compat/zlib/contrib/vstudio/vc11/zlibvc.sln
@@ -0,0 +1,117 @@
+﻿
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 2012
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlibvc", "zlibvc.vcxproj", "{8FD826F8-3739-44E6-8CC8-997122E53B8D}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlibstat", "zlibstat.vcxproj", "{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testzlib", "testzlib.vcxproj", "{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testzlibdll", "testzlibdll.vcxproj", "{C52F9E7B-498A-42BE-8DB4-85A15694366A}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "minizip", "minizip.vcxproj", "{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "miniunz", "miniunz.vcxproj", "{C52F9E7B-498A-42BE-8DB4-85A15694382A}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Itanium = Debug|Itanium
+		Debug|Win32 = Debug|Win32
+		Debug|x64 = Debug|x64
+		Release|Itanium = Release|Itanium
+		Release|Win32 = Release|Win32
+		Release|x64 = Release|x64
+		ReleaseWithoutAsm|Itanium = ReleaseWithoutAsm|Itanium
+		ReleaseWithoutAsm|Win32 = ReleaseWithoutAsm|Win32
+		ReleaseWithoutAsm|x64 = ReleaseWithoutAsm|x64
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|Itanium.ActiveCfg = Debug|Win32
+		{8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|Win32.ActiveCfg = Debug|Win32
+		{8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|Win32.Build.0 = Debug|Win32
+		{8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|x64.ActiveCfg = Debug|x64
+		{8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|x64.Build.0 = Debug|x64
+		{8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|Itanium.ActiveCfg = Release|Win32
+		{8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|Win32.ActiveCfg = Release|Win32
+		{8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|Win32.Build.0 = Release|Win32
+		{8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|x64.ActiveCfg = Release|x64
+		{8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|x64.Build.0 = Release|x64
+		{8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|Itanium.ActiveCfg = ReleaseWithoutAsm|Win32
+		{8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|Win32.ActiveCfg = ReleaseWithoutAsm|Win32
+		{8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|Win32.Build.0 = ReleaseWithoutAsm|Win32
+		{8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|x64.ActiveCfg = ReleaseWithoutAsm|x64
+		{8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|x64.Build.0 = ReleaseWithoutAsm|x64
+		{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|Itanium.ActiveCfg = Debug|Win32
+		{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|Win32.ActiveCfg = Debug|Win32
+		{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|Win32.Build.0 = Debug|Win32
+		{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|x64.ActiveCfg = Debug|x64
+		{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|x64.Build.0 = Debug|x64
+		{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|Itanium.ActiveCfg = Release|Win32
+		{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|Win32.ActiveCfg = Release|Win32
+		{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|Win32.Build.0 = Release|Win32
+		{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|x64.ActiveCfg = Release|x64
+		{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|x64.Build.0 = Release|x64
+		{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|Itanium.ActiveCfg = ReleaseWithoutAsm|Win32
+		{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|Win32.ActiveCfg = ReleaseWithoutAsm|Win32
+		{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|Win32.Build.0 = ReleaseWithoutAsm|Win32
+		{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|x64.ActiveCfg = ReleaseWithoutAsm|x64
+		{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|x64.Build.0 = ReleaseWithoutAsm|x64
+		{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|Itanium.ActiveCfg = Debug|Win32
+		{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|Win32.ActiveCfg = Debug|Win32
+		{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|Win32.Build.0 = Debug|Win32
+		{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|x64.ActiveCfg = Debug|x64
+		{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|x64.Build.0 = Debug|x64
+		{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|Itanium.ActiveCfg = Release|Win32
+		{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|Win32.ActiveCfg = Release|Win32
+		{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|Win32.Build.0 = Release|Win32
+		{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|x64.ActiveCfg = Release|x64
+		{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|x64.Build.0 = Release|x64
+		{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Itanium.ActiveCfg = ReleaseWithoutAsm|Win32
+		{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Win32.ActiveCfg = ReleaseWithoutAsm|Win32
+		{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Win32.Build.0 = ReleaseWithoutAsm|Win32
+		{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|x64.ActiveCfg = ReleaseWithoutAsm|x64
+		{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|x64.Build.0 = ReleaseWithoutAsm|x64
+		{C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|Itanium.ActiveCfg = Debug|Win32
+		{C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|Win32.ActiveCfg = Debug|Win32
+		{C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|Win32.Build.0 = Debug|Win32
+		{C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|x64.ActiveCfg = Debug|x64
+		{C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|x64.Build.0 = Debug|x64
+		{C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|Itanium.ActiveCfg = Release|Win32
+		{C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|Win32.ActiveCfg = Release|Win32
+		{C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|Win32.Build.0 = Release|Win32
+		{C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|x64.ActiveCfg = Release|x64
+		{C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|x64.Build.0 = Release|x64
+		{C52F9E7B-498A-42BE-8DB4-85A15694366A}.ReleaseWithoutAsm|Itanium.ActiveCfg = Release|Win32
+		{C52F9E7B-498A-42BE-8DB4-85A15694366A}.ReleaseWithoutAsm|Win32.ActiveCfg = Release|Win32
+		{C52F9E7B-498A-42BE-8DB4-85A15694366A}.ReleaseWithoutAsm|x64.ActiveCfg = Release|x64
+		{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|Itanium.ActiveCfg = Debug|Win32
+		{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|Win32.ActiveCfg = Debug|Win32
+		{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|Win32.Build.0 = Debug|Win32
+		{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|x64.ActiveCfg = Debug|x64
+		{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|x64.Build.0 = Debug|x64
+		{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|Itanium.ActiveCfg = Release|Win32
+		{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|Win32.ActiveCfg = Release|Win32
+		{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|Win32.Build.0 = Release|Win32
+		{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|x64.ActiveCfg = Release|x64
+		{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|x64.Build.0 = Release|x64
+		{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Itanium.ActiveCfg = Release|Win32
+		{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Win32.ActiveCfg = Release|Win32
+		{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|x64.ActiveCfg = Release|x64
+		{C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|Itanium.ActiveCfg = Debug|Win32
+		{C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|Win32.ActiveCfg = Debug|Win32
+		{C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|Win32.Build.0 = Debug|Win32
+		{C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|x64.ActiveCfg = Debug|x64
+		{C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|x64.Build.0 = Debug|x64
+		{C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|Itanium.ActiveCfg = Release|Win32
+		{C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|Win32.ActiveCfg = Release|Win32
+		{C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|Win32.Build.0 = Release|Win32
+		{C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|x64.ActiveCfg = Release|x64
+		{C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|x64.Build.0 = Release|x64
+		{C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseWithoutAsm|Itanium.ActiveCfg = Release|Win32
+		{C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseWithoutAsm|Win32.ActiveCfg = Release|Win32
+		{C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseWithoutAsm|x64.ActiveCfg = Release|x64
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal
diff --git a/compat/zlib/contrib/vstudio/vc11/zlibvc.vcxproj b/compat/zlib/contrib/vstudio/vc11/zlibvc.vcxproj
new file mode 100644
index 0000000..c65b95f
--- /dev/null
+++ b/compat/zlib/contrib/vstudio/vc11/zlibvc.vcxproj
@@ -0,0 +1,688 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Itanium">
+      <Configuration>Debug</Configuration>
+      <Platform>Itanium</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="ReleaseWithoutAsm|Itanium">
+      <Configuration>ReleaseWithoutAsm</Configuration>
+      <Platform>Itanium</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="ReleaseWithoutAsm|Win32">
+      <Configuration>ReleaseWithoutAsm</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="ReleaseWithoutAsm|x64">
+      <Configuration>ReleaseWithoutAsm</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Itanium">
+      <Configuration>Release</Configuration>
+      <Platform>Itanium</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <ProjectGuid>{8FD826F8-3739-44E6-8CC8-997122E53B8D}</ProjectGuid>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <UseOfMfc>false</UseOfMfc>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <PlatformToolset>v110</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <UseOfMfc>false</UseOfMfc>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <PlatformToolset>v110</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <UseOfMfc>false</UseOfMfc>
+    <PlatformToolset>v110</PlatformToolset>
+    <CharacterSet>Unicode</CharacterSet>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <UseOfMfc>false</UseOfMfc>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <UseOfMfc>false</UseOfMfc>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <UseOfMfc>false</UseOfMfc>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <UseOfMfc>false</UseOfMfc>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <PlatformToolset>v110</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <UseOfMfc>false</UseOfMfc>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <PlatformToolset>v110</PlatformToolset>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>DynamicLibrary</ConfigurationType>
+    <UseOfMfc>false</UseOfMfc>
+    <PlatformToolset>v110</PlatformToolset>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup>
+    <_ProjectFileVersion>10.0.30128.1</_ProjectFileVersion>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">x86\ZlibDll$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">x86\ZlibDll$(Configuration)\Tmp\</IntDir>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
+    <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</GenerateManifest>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">x86\ZlibDll$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">x86\ZlibDll$(Configuration)\Tmp\</IntDir>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">false</LinkIncremental>
+    <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">false</GenerateManifest>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">x86\ZlibDll$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">x86\ZlibDll$(Configuration)\Tmp\</IntDir>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
+    <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</GenerateManifest>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">x64\ZlibDll$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">x64\ZlibDll$(Configuration)\Tmp\</IntDir>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</LinkIncremental>
+    <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</GenerateManifest>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">ia64\ZlibDll$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">ia64\ZlibDll$(Configuration)\Tmp\</IntDir>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">true</LinkIncremental>
+    <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">false</GenerateManifest>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">x64\ZlibDll$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">x64\ZlibDll$(Configuration)\Tmp\</IntDir>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">false</LinkIncremental>
+    <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">false</GenerateManifest>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">ia64\ZlibDll$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">ia64\ZlibDll$(Configuration)\Tmp\</IntDir>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">false</LinkIncremental>
+    <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">false</GenerateManifest>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">x64\ZlibDll$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">x64\ZlibDll$(Configuration)\Tmp\</IntDir>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>
+    <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</GenerateManifest>
+    <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">ia64\ZlibDll$(Configuration)\</OutDir>
+    <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">ia64\ZlibDll$(Configuration)\Tmp\</IntDir>
+    <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">false</LinkIncremental>
+    <GenerateManifest Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">false</GenerateManifest>
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">AllRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" />
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'" />
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">AllRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'" />
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'" />
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'" />
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'" />
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'" />
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'" />
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">AllRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" />
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'" />
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />
+    <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|x64'">AllRules.ruleset</CodeAnalysisRuleSet>
+    <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
+    <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />
+    <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">zlibwapi</TargetName>
+    <TargetName Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">zlibwapi</TargetName>
+    <TargetName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">zlibwapi</TargetName>
+    <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">zlibwapi</TargetName>
+    <TargetName Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">zlibwapi</TargetName>
+    <TargetName Condition="'$(Configuration)|$(Platform)'=='Release|x64'">zlibwapi</TargetName>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <Midl>
+      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <MkTypLibCompatible>true</MkTypLibCompatible>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <TargetEnvironment>Win32</TargetEnvironment>
+      <TypeLibraryName>$(OutDir)zlibvc.tlb</TypeLibraryName>
+    </Midl>
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;ASMV;ASMINF;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <ExceptionHandling>
+      </ExceptionHandling>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+      <PrecompiledHeaderOutputFile>$(IntDir)zlibvc.pch</PrecompiledHeaderOutputFile>
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+      <ObjectFileName>$(IntDir)</ObjectFileName>
+      <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+      <BrowseInformation>
+      </BrowseInformation>
+      <WarningLevel>Level3</WarningLevel>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <ResourceCompile>
+      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <Culture>0x040c</Culture>
+    </ResourceCompile>
+    <Link>
+      <AdditionalOptions>/MACHINE:I386 %(AdditionalOptions)</AdditionalOptions>
+      <AdditionalDependencies>..\..\masmx86\match686.obj;..\..\masmx86\inffas32.obj;%(AdditionalDependencies)</AdditionalDependencies>
+      <OutputFile>$(OutDir)zlibwapi.dll</OutputFile>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <ModuleDefinitionFile>.\zlibvc.def</ModuleDefinitionFile>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <ProgramDatabaseFile>$(OutDir)zlibwapi.pdb</ProgramDatabaseFile>
+      <GenerateMapFile>true</GenerateMapFile>
+      <MapFileName>$(OutDir)zlibwapi.map</MapFileName>
+      <SubSystem>Windows</SubSystem>
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>
+      <DataExecutionPrevention>
+      </DataExecutionPrevention>
+      <ImportLibrary>$(OutDir)zlibwapi.lib</ImportLibrary>
+    </Link>
+    <PreBuildEvent>
+      <Command>cd ..\..\masmx86
+bld_ml32.bat</Command>
+    </PreBuildEvent>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">
+    <Midl>
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <MkTypLibCompatible>true</MkTypLibCompatible>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <TargetEnvironment>Win32</TargetEnvironment>
+      <TypeLibraryName>$(OutDir)zlibvc.tlb</TypeLibraryName>
+    </Midl>
+    <ClCompile>
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+      <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <StringPooling>true</StringPooling>
+      <ExceptionHandling>
+      </ExceptionHandling>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <PrecompiledHeaderOutputFile>$(IntDir)zlibvc.pch</PrecompiledHeaderOutputFile>
+      <AssemblerOutput>All</AssemblerOutput>
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+      <ObjectFileName>$(IntDir)</ObjectFileName>
+      <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+      <BrowseInformation>
+      </BrowseInformation>
+      <WarningLevel>Level3</WarningLevel>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+    </ClCompile>
+    <ResourceCompile>
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <Culture>0x040c</Culture>
+    </ResourceCompile>
+    <Link>
+      <AdditionalOptions>/MACHINE:I386 %(AdditionalOptions)</AdditionalOptions>
+      <OutputFile>$(OutDir)zlibwapi.dll</OutputFile>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+      <ModuleDefinitionFile>.\zlibvc.def</ModuleDefinitionFile>
+      <ProgramDatabaseFile>$(OutDir)zlibwapi.pdb</ProgramDatabaseFile>
+      <GenerateMapFile>true</GenerateMapFile>
+      <MapFileName>$(OutDir)zlibwapi.map</MapFileName>
+      <SubSystem>Windows</SubSystem>
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>
+      <DataExecutionPrevention>
+      </DataExecutionPrevention>
+      <ImportLibrary>$(OutDir)zlibwapi.lib</ImportLibrary>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <Midl>
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <MkTypLibCompatible>true</MkTypLibCompatible>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <TargetEnvironment>Win32</TargetEnvironment>
+      <TypeLibraryName>$(OutDir)zlibvc.tlb</TypeLibraryName>
+    </Midl>
+    <ClCompile>
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+      <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;ASMV;ASMINF;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <StringPooling>true</StringPooling>
+      <ExceptionHandling>
+      </ExceptionHandling>
+      <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <PrecompiledHeaderOutputFile>$(IntDir)zlibvc.pch</PrecompiledHeaderOutputFile>
+      <AssemblerOutput>All</AssemblerOutput>
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+      <ObjectFileName>$(IntDir)</ObjectFileName>
+      <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+      <BrowseInformation>
+      </BrowseInformation>
+      <WarningLevel>Level3</WarningLevel>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+    </ClCompile>
+    <ResourceCompile>
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <Culture>0x040c</Culture>
+    </ResourceCompile>
+    <Link>
+      <AdditionalOptions>/MACHINE:I386 %(AdditionalOptions)</AdditionalOptions>
+      <AdditionalDependencies>..\..\masmx86\match686.obj;..\..\masmx86\inffas32.obj;%(AdditionalDependencies)</AdditionalDependencies>
+      <OutputFile>$(OutDir)zlibwapi.dll</OutputFile>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+      <ModuleDefinitionFile>.\zlibvc.def</ModuleDefinitionFile>
+      <ProgramDatabaseFile>$(OutDir)zlibwapi.pdb</ProgramDatabaseFile>
+      <GenerateMapFile>true</GenerateMapFile>
+      <MapFileName>$(OutDir)zlibwapi.map</MapFileName>
+      <SubSystem>Windows</SubSystem>
+      <RandomizedBaseAddress>false</RandomizedBaseAddress>
+      <DataExecutionPrevention>
+      </DataExecutionPrevention>
+      <ImportLibrary>$(OutDir)zlibwapi.lib</ImportLibrary>
+    </Link>
+    <PreBuildEvent>
+      <Command>cd ..\..\masmx86
+bld_ml32.bat</Command>
+    </PreBuildEvent>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <Midl>
+      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <MkTypLibCompatible>true</MkTypLibCompatible>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <TargetEnvironment>X64</TargetEnvironment>
+      <TypeLibraryName>$(OutDir)zlibvc.tlb</TypeLibraryName>
+    </Midl>
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;ASMV;ASMINF;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <ExceptionHandling>
+      </ExceptionHandling>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+      <PrecompiledHeaderOutputFile>$(IntDir)zlibvc.pch</PrecompiledHeaderOutputFile>
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+      <ObjectFileName>$(IntDir)</ObjectFileName>
+      <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+      <BrowseInformation>
+      </BrowseInformation>
+      <WarningLevel>Level3</WarningLevel>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <ResourceCompile>
+      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <Culture>0x040c</Culture>
+    </ResourceCompile>
+    <Link>
+      <AdditionalDependencies>..\..\masmx64\gvmat64.obj;..\..\masmx64\inffasx64.obj;%(AdditionalDependencies)</AdditionalDependencies>
+      <OutputFile>$(OutDir)zlibwapi.dll</OutputFile>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <ModuleDefinitionFile>.\zlibvc.def</ModuleDefinitionFile>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <ProgramDatabaseFile>$(OutDir)zlibwapi.pdb</ProgramDatabaseFile>
+      <GenerateMapFile>true</GenerateMapFile>
+      <MapFileName>$(OutDir)zlibwapi.map</MapFileName>
+      <SubSystem>Windows</SubSystem>
+      <ImportLibrary>$(OutDir)zlibwapi.lib</ImportLibrary>
+      <TargetMachine>MachineX64</TargetMachine>
+    </Link>
+    <PreBuildEvent>
+      <Command>cd ..\..\contrib\masmx64
+bld_ml64.bat</Command>
+    </PreBuildEvent>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">
+    <Midl>
+      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <MkTypLibCompatible>true</MkTypLibCompatible>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <TargetEnvironment>Itanium</TargetEnvironment>
+      <TypeLibraryName>$(OutDir)zlibvc.tlb</TypeLibraryName>
+    </Midl>
+    <ClCompile>
+      <Optimization>Disabled</Optimization>
+      <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <ExceptionHandling>
+      </ExceptionHandling>
+      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+      <PrecompiledHeaderOutputFile>$(IntDir)zlibvc.pch</PrecompiledHeaderOutputFile>
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+      <ObjectFileName>$(IntDir)</ObjectFileName>
+      <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+      <BrowseInformation>
+      </BrowseInformation>
+      <WarningLevel>Level3</WarningLevel>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
+    </ClCompile>
+    <ResourceCompile>
+      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <Culture>0x040c</Culture>
+    </ResourceCompile>
+    <Link>
+      <OutputFile>$(OutDir)zlibwapi.dll</OutputFile>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <ModuleDefinitionFile>.\zlibvc.def</ModuleDefinitionFile>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+      <ProgramDatabaseFile>$(OutDir)zlibwapi.pdb</ProgramDatabaseFile>
+      <GenerateMapFile>true</GenerateMapFile>
+      <MapFileName>$(OutDir)zlibwapi.map</MapFileName>
+      <SubSystem>Windows</SubSystem>
+      <ImportLibrary>$(OutDir)zlibwapi.lib</ImportLibrary>
+      <TargetMachine>MachineIA64</TargetMachine>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|x64'">
+    <Midl>
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <MkTypLibCompatible>true</MkTypLibCompatible>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <TargetEnvironment>X64</TargetEnvironment>
+      <TypeLibraryName>$(OutDir)zlibvc.tlb</TypeLibraryName>
+    </Midl>
+    <ClCompile>
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+      <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <StringPooling>true</StringPooling>
+      <ExceptionHandling>
+      </ExceptionHandling>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <PrecompiledHeaderOutputFile>$(IntDir)zlibvc.pch</PrecompiledHeaderOutputFile>
+      <AssemblerOutput>All</AssemblerOutput>
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+      <ObjectFileName>$(IntDir)</ObjectFileName>
+      <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+      <BrowseInformation>
+      </BrowseInformation>
+      <WarningLevel>Level3</WarningLevel>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+    </ClCompile>
+    <ResourceCompile>
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <Culture>0x040c</Culture>
+    </ResourceCompile>
+    <Link>
+      <OutputFile>$(OutDir)zlibwapi.dll</OutputFile>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+      <ModuleDefinitionFile>.\zlibvc.def</ModuleDefinitionFile>
+      <ProgramDatabaseFile>$(OutDir)zlibwapi.pdb</ProgramDatabaseFile>
+      <GenerateMapFile>true</GenerateMapFile>
+      <MapFileName>$(OutDir)zlibwapi.map</MapFileName>
+      <SubSystem>Windows</SubSystem>
+      <ImportLibrary>$(OutDir)zlibwapi.lib</ImportLibrary>
+      <TargetMachine>MachineX64</TargetMachine>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">
+    <Midl>
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <MkTypLibCompatible>true</MkTypLibCompatible>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <TargetEnvironment>Itanium</TargetEnvironment>
+      <TypeLibraryName>$(OutDir)zlibvc.tlb</TypeLibraryName>
+    </Midl>
+    <ClCompile>
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+      <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <StringPooling>true</StringPooling>
+      <ExceptionHandling>
+      </ExceptionHandling>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <PrecompiledHeaderOutputFile>$(IntDir)zlibvc.pch</PrecompiledHeaderOutputFile>
+      <AssemblerOutput>All</AssemblerOutput>
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+      <ObjectFileName>$(IntDir)</ObjectFileName>
+      <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+      <BrowseInformation>
+      </BrowseInformation>
+      <WarningLevel>Level3</WarningLevel>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+    </ClCompile>
+    <ResourceCompile>
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <Culture>0x040c</Culture>
+    </ResourceCompile>
+    <Link>
+      <OutputFile>$(OutDir)zlibwapi.dll</OutputFile>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+      <ModuleDefinitionFile>.\zlibvc.def</ModuleDefinitionFile>
+      <ProgramDatabaseFile>$(OutDir)zlibwapi.pdb</ProgramDatabaseFile>
+      <GenerateMapFile>true</GenerateMapFile>
+      <MapFileName>$(OutDir)zlibwapi.map</MapFileName>
+      <SubSystem>Windows</SubSystem>
+      <ImportLibrary>$(OutDir)zlibwapi.lib</ImportLibrary>
+      <TargetMachine>MachineIA64</TargetMachine>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <Midl>
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <MkTypLibCompatible>true</MkTypLibCompatible>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <TargetEnvironment>X64</TargetEnvironment>
+      <TypeLibraryName>$(OutDir)zlibvc.tlb</TypeLibraryName>
+    </Midl>
+    <ClCompile>
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+      <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;ASMV;ASMINF;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <StringPooling>true</StringPooling>
+      <ExceptionHandling>
+      </ExceptionHandling>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <PrecompiledHeaderOutputFile>$(IntDir)zlibvc.pch</PrecompiledHeaderOutputFile>
+      <AssemblerOutput>All</AssemblerOutput>
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+      <ObjectFileName>$(IntDir)</ObjectFileName>
+      <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+      <BrowseInformation>
+      </BrowseInformation>
+      <WarningLevel>Level3</WarningLevel>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+    </ClCompile>
+    <ResourceCompile>
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <Culture>0x040c</Culture>
+    </ResourceCompile>
+    <Link>
+      <AdditionalDependencies>..\..\masmx64\gvmat64.obj;..\..\masmx64\inffasx64.obj;%(AdditionalDependencies)</AdditionalDependencies>
+      <OutputFile>$(OutDir)zlibwapi.dll</OutputFile>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+      <ModuleDefinitionFile>.\zlibvc.def</ModuleDefinitionFile>
+      <ProgramDatabaseFile>$(OutDir)zlibwapi.pdb</ProgramDatabaseFile>
+      <GenerateMapFile>true</GenerateMapFile>
+      <MapFileName>$(OutDir)zlibwapi.map</MapFileName>
+      <SubSystem>Windows</SubSystem>
+      <ImportLibrary>$(OutDir)zlibwapi.lib</ImportLibrary>
+      <TargetMachine>MachineX64</TargetMachine>
+    </Link>
+    <PreBuildEvent>
+      <Command>cd ..\..\masmx64
+bld_ml64.bat</Command>
+    </PreBuildEvent>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">
+    <Midl>
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <MkTypLibCompatible>true</MkTypLibCompatible>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <TargetEnvironment>Itanium</TargetEnvironment>
+      <TypeLibraryName>$(OutDir)zlibvc.tlb</TypeLibraryName>
+    </Midl>
+    <ClCompile>
+      <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
+      <AdditionalIncludeDirectories>..\..\..;..\..\masmx86;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions>_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;WIN64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <StringPooling>true</StringPooling>
+      <ExceptionHandling>
+      </ExceptionHandling>
+      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
+      <BufferSecurityCheck>false</BufferSecurityCheck>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <PrecompiledHeaderOutputFile>$(IntDir)zlibvc.pch</PrecompiledHeaderOutputFile>
+      <AssemblerOutput>All</AssemblerOutput>
+      <AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
+      <ObjectFileName>$(IntDir)</ObjectFileName>
+      <ProgramDataBaseFileName>$(OutDir)</ProgramDataBaseFileName>
+      <BrowseInformation>
+      </BrowseInformation>
+      <WarningLevel>Level3</WarningLevel>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+    </ClCompile>
+    <ResourceCompile>
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <Culture>0x040c</Culture>
+    </ResourceCompile>
+    <Link>
+      <OutputFile>$(OutDir)zlibwapi.dll</OutputFile>
+      <SuppressStartupBanner>true</SuppressStartupBanner>
+      <IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
+      <ModuleDefinitionFile>.\zlibvc.def</ModuleDefinitionFile>
+      <ProgramDatabaseFile>$(OutDir)zlibwapi.pdb</ProgramDatabaseFile>
+      <GenerateMapFile>true</GenerateMapFile>
+      <MapFileName>$(OutDir)zlibwapi.map</MapFileName>
+      <SubSystem>Windows</SubSystem>
+      <ImportLibrary>$(OutDir)zlibwapi.lib</ImportLibrary>
+      <TargetMachine>MachineIA64</TargetMachine>
+    </Link>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <ClCompile Include="..\..\..\adler32.c" />
+    <ClCompile Include="..\..\..\compress.c" />
+    <ClCompile Include="..\..\..\crc32.c" />
+    <ClCompile Include="..\..\..\deflate.c" />
+    <ClCompile Include="..\..\..\gzclose.c" />
+    <ClCompile Include="..\..\..\gzlib.c" />
+    <ClCompile Include="..\..\..\gzread.c" />
+    <ClCompile Include="..\..\..\gzwrite.c" />
+    <ClCompile Include="..\..\..\infback.c" />
+    <ClCompile Include="..\..\masmx64\inffas8664.c">
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Itanium'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Itanium'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='ReleaseWithoutAsm|Win32'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">true</ExcludedFromBuild>
+      <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
+    </ClCompile>
+    <ClCompile Include="..\..\..\inffast.c" />
+    <ClCompile Include="..\..\..\inflate.c" />
+    <ClCompile Include="..\..\..\inftrees.c" />
+    <ClCompile Include="..\..\minizip\ioapi.c" />
+    <ClCompile Include="..\..\minizip\iowin32.c" />
+    <ClCompile Include="..\..\..\trees.c" />
+    <ClCompile Include="..\..\..\uncompr.c" />
+    <ClCompile Include="..\..\minizip\unzip.c">
+      <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">ZLIB_INTERNAL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">ZLIB_INTERNAL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">ZLIB_INTERNAL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ClCompile>
+    <ClCompile Include="..\..\minizip\zip.c">
+      <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Itanium'">ZLIB_INTERNAL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">ZLIB_INTERNAL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+      <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">ZLIB_INTERNAL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ClCompile>
+    <ClCompile Include="..\..\..\zutil.c" />
+  </ItemGroup>
+  <ItemGroup>
+    <ResourceCompile Include="zlib.rc" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="zlibvc.def" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="..\..\..\deflate.h" />
+    <ClInclude Include="..\..\..\infblock.h" />
+    <ClInclude Include="..\..\..\infcodes.h" />
+    <ClInclude Include="..\..\..\inffast.h" />
+    <ClInclude Include="..\..\..\inftrees.h" />
+    <ClInclude Include="..\..\..\infutil.h" />
+    <ClInclude Include="..\..\..\zconf.h" />
+    <ClInclude Include="..\..\..\zlib.h" />
+    <ClInclude Include="..\..\..\zutil.h" />
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
\ No newline at end of file
diff --git a/compat/zlib/contrib/vstudio/vc9/miniunz.vcproj b/compat/zlib/contrib/vstudio/vc9/miniunz.vcproj
new file mode 100644
index 0000000..7da32b9
--- /dev/null
+++ b/compat/zlib/contrib/vstudio/vc9/miniunz.vcproj
@@ -0,0 +1,565 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="9.00"
+	Name="miniunz"
+	ProjectGUID="{C52F9E7B-498A-42BE-8DB4-85A15694382A}"
+	Keyword="Win32Proj"
+	TargetFrameworkVersion="131072"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+		<Platform
+			Name="x64"
+		/>
+		<Platform
+			Name="Itanium"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="x86\MiniUnzip$(ConfigurationName)"
+			IntermediateDirectory="x86\MiniUnzip$(ConfigurationName)\Tmp"
+			ConfigurationType="1"
+			InheritedPropertySheets="UpgradeFromVC70.vsprops"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="..\..\..;..\..\minizip"
+				PreprocessorDefinitions="WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE"
+				MinimalRebuild="true"
+				BasicRuntimeChecks="0"
+				RuntimeLibrary="1"
+				BufferSecurityCheck="false"
+				UsePrecompiledHeader="0"
+				AssemblerListingLocation="$(IntDir)\"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="true"
+				DebugInformationFormat="4"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="x86\ZlibDllDebug\zlibwapi.lib"
+				OutputFile="$(OutDir)/miniunz.exe"
+				LinkIncremental="2"
+				GenerateManifest="false"
+				GenerateDebugInformation="true"
+				ProgramDatabaseFile="$(OutDir)/miniunz.pdb"
+				SubSystem="1"
+				RandomizedBaseAddress="1"
+				DataExecutionPrevention="0"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="x86\MiniUnzip$(ConfigurationName)"
+			IntermediateDirectory="x86\MiniUnzip$(ConfigurationName)\Tmp"
+			ConfigurationType="1"
+			InheritedPropertySheets="UpgradeFromVC70.vsprops"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="2"
+				InlineFunctionExpansion="1"
+				OmitFramePointers="true"
+				AdditionalIncludeDirectories="..\..\..;..\..\minizip"
+				PreprocessorDefinitions="WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE"
+				StringPooling="true"
+				BasicRuntimeChecks="0"
+				RuntimeLibrary="0"
+				BufferSecurityCheck="false"
+				EnableFunctionLevelLinking="true"
+				UsePrecompiledHeader="0"
+				AssemblerListingLocation="$(IntDir)\"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="true"
+				DebugInformationFormat="3"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="x86\ZlibDllRelease\zlibwapi.lib"
+				OutputFile="$(OutDir)/miniunz.exe"
+				LinkIncremental="1"
+				GenerateManifest="false"
+				GenerateDebugInformation="true"
+				SubSystem="1"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
+				OptimizeForWindows98="1"
+				RandomizedBaseAddress="1"
+				DataExecutionPrevention="0"
+				TargetMachine="1"
+			/>
+			<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\MiniUnzip$(ConfigurationName)"
+			IntermediateDirectory="x64\MiniUnzip$(ConfigurationName)\Tmp"
+			ConfigurationType="1"
+			InheritedPropertySheets="UpgradeFromVC70.vsprops"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="..\..\..;..\..\minizip"
+				PreprocessorDefinitions="_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64"
+				MinimalRebuild="true"
+				BasicRuntimeChecks="0"
+				RuntimeLibrary="3"
+				BufferSecurityCheck="false"
+				UsePrecompiledHeader="0"
+				AssemblerListingLocation="$(IntDir)\"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="true"
+				DebugInformationFormat="3"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="x64\ZlibDllDebug\zlibwapi.lib"
+				OutputFile="$(OutDir)/miniunz.exe"
+				LinkIncremental="2"
+				GenerateManifest="false"
+				GenerateDebugInformation="true"
+				ProgramDatabaseFile="$(OutDir)/miniunz.pdb"
+				SubSystem="1"
+				TargetMachine="17"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Debug|Itanium"
+			OutputDirectory="ia64\MiniUnzip$(ConfigurationName)"
+			IntermediateDirectory="ia64\MiniUnzip$(ConfigurationName)\Tmp"
+			ConfigurationType="1"
+			InheritedPropertySheets="UpgradeFromVC70.vsprops"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="2"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="..\..\..;..\..\minizip"
+				PreprocessorDefinitions="_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64"
+				MinimalRebuild="true"
+				BasicRuntimeChecks="0"
+				RuntimeLibrary="3"
+				BufferSecurityCheck="false"
+				UsePrecompiledHeader="0"
+				AssemblerListingLocation="$(IntDir)\"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="true"
+				DebugInformationFormat="3"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="ia64\ZlibDllDebug\zlibwapi.lib"
+				OutputFile="$(OutDir)/miniunz.exe"
+				LinkIncremental="2"
+				GenerateManifest="false"
+				GenerateDebugInformation="true"
+				ProgramDatabaseFile="$(OutDir)/miniunz.pdb"
+				SubSystem="1"
+				TargetMachine="5"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|x64"
+			OutputDirectory="x64\MiniUnzip$(ConfigurationName)"
+			IntermediateDirectory="x64\MiniUnzip$(ConfigurationName)\Tmp"
+			ConfigurationType="1"
+			InheritedPropertySheets="UpgradeFromVC70.vsprops"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="2"
+				InlineFunctionExpansion="1"
+				OmitFramePointers="true"
+				AdditionalIncludeDirectories="..\..\..;..\..\minizip"
+				PreprocessorDefinitions="_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64"
+				StringPooling="true"
+				BasicRuntimeChecks="0"
+				RuntimeLibrary="2"
+				BufferSecurityCheck="false"
+				EnableFunctionLevelLinking="true"
+				UsePrecompiledHeader="0"
+				AssemblerListingLocation="$(IntDir)\"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="true"
+				DebugInformationFormat="3"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="x64\ZlibDllRelease\zlibwapi.lib"
+				OutputFile="$(OutDir)/miniunz.exe"
+				LinkIncremental="1"
+				GenerateManifest="false"
+				GenerateDebugInformation="true"
+				SubSystem="1"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
+				OptimizeForWindows98="1"
+				TargetMachine="17"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Itanium"
+			OutputDirectory="ia64\MiniUnzip$(ConfigurationName)"
+			IntermediateDirectory="ia64\MiniUnzip$(ConfigurationName)\Tmp"
+			ConfigurationType="1"
+			InheritedPropertySheets="UpgradeFromVC70.vsprops"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="2"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="2"
+				InlineFunctionExpansion="1"
+				OmitFramePointers="true"
+				AdditionalIncludeDirectories="..\..\..;..\..\minizip"
+				PreprocessorDefinitions="_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64"
+				StringPooling="true"
+				BasicRuntimeChecks="0"
+				RuntimeLibrary="2"
+				BufferSecurityCheck="false"
+				EnableFunctionLevelLinking="true"
+				UsePrecompiledHeader="0"
+				AssemblerListingLocation="$(IntDir)\"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="true"
+				DebugInformationFormat="3"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="ia64\ZlibDllRelease\zlibwapi.lib"
+				OutputFile="$(OutDir)/miniunz.exe"
+				LinkIncremental="1"
+				GenerateManifest="false"
+				GenerateDebugInformation="true"
+				SubSystem="1"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
+				OptimizeForWindows98="1"
+				TargetMachine="5"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Source Files"
+			Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm"
+			>
+			<File
+				RelativePath="..\..\minizip\miniunz.c"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="Header Files"
+			Filter="h;hpp;hxx;hm;inl;inc"
+			>
+		</Filter>
+		<Filter
+			Name="Resource Files"
+			Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+			>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
diff --git a/compat/zlib/contrib/vstudio/vc9/minizip.vcproj b/compat/zlib/contrib/vstudio/vc9/minizip.vcproj
new file mode 100644
index 0000000..e57e07d
--- /dev/null
+++ b/compat/zlib/contrib/vstudio/vc9/minizip.vcproj
@@ -0,0 +1,562 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="9.00"
+	Name="minizip"
+	ProjectGUID="{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}"
+	Keyword="Win32Proj"
+	TargetFrameworkVersion="131072"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+		<Platform
+			Name="x64"
+		/>
+		<Platform
+			Name="Itanium"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="x86\MiniZip$(ConfigurationName)"
+			IntermediateDirectory="x86\MiniZip$(ConfigurationName)\Tmp"
+			ConfigurationType="1"
+			InheritedPropertySheets="UpgradeFromVC70.vsprops"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="..\..\..;..\..\minizip"
+				PreprocessorDefinitions="WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE"
+				MinimalRebuild="true"
+				BasicRuntimeChecks="0"
+				RuntimeLibrary="1"
+				BufferSecurityCheck="false"
+				UsePrecompiledHeader="0"
+				AssemblerListingLocation="$(IntDir)\"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="true"
+				DebugInformationFormat="4"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="x86\ZlibDllDebug\zlibwapi.lib"
+				OutputFile="$(OutDir)/minizip.exe"
+				LinkIncremental="2"
+				GenerateManifest="false"
+				GenerateDebugInformation="true"
+				ProgramDatabaseFile="$(OutDir)/minizip.pdb"
+				SubSystem="1"
+				RandomizedBaseAddress="1"
+				DataExecutionPrevention="0"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="x86\MiniZip$(ConfigurationName)"
+			IntermediateDirectory="x86\MiniZip$(ConfigurationName)\Tmp"
+			ConfigurationType="1"
+			InheritedPropertySheets="UpgradeFromVC70.vsprops"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="2"
+				InlineFunctionExpansion="1"
+				OmitFramePointers="true"
+				AdditionalIncludeDirectories="..\..\..;..\..\minizip"
+				PreprocessorDefinitions="WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE"
+				StringPooling="true"
+				BasicRuntimeChecks="0"
+				RuntimeLibrary="0"
+				BufferSecurityCheck="false"
+				EnableFunctionLevelLinking="true"
+				UsePrecompiledHeader="0"
+				AssemblerListingLocation="$(IntDir)\"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="true"
+				DebugInformationFormat="3"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="x86\ZlibDllRelease\zlibwapi.lib"
+				OutputFile="$(OutDir)/minizip.exe"
+				LinkIncremental="1"
+				GenerateDebugInformation="true"
+				SubSystem="1"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
+				OptimizeForWindows98="1"
+				RandomizedBaseAddress="1"
+				DataExecutionPrevention="0"
+				TargetMachine="1"
+			/>
+			<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\$(ConfigurationName)"
+			IntermediateDirectory="x64\$(ConfigurationName)"
+			ConfigurationType="1"
+			InheritedPropertySheets="UpgradeFromVC70.vsprops"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="..\..\..;..\..\minizip"
+				PreprocessorDefinitions="_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64"
+				MinimalRebuild="true"
+				BasicRuntimeChecks="0"
+				RuntimeLibrary="3"
+				BufferSecurityCheck="false"
+				UsePrecompiledHeader="0"
+				AssemblerListingLocation="$(IntDir)\"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="true"
+				DebugInformationFormat="3"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="x64\ZlibDllDebug\zlibwapi.lib"
+				OutputFile="$(OutDir)/minizip.exe"
+				LinkIncremental="2"
+				GenerateManifest="false"
+				GenerateDebugInformation="true"
+				ProgramDatabaseFile="$(OutDir)/minizip.pdb"
+				SubSystem="1"
+				TargetMachine="17"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Debug|Itanium"
+			OutputDirectory="ia64\$(ConfigurationName)"
+			IntermediateDirectory="ia64\$(ConfigurationName)"
+			ConfigurationType="1"
+			InheritedPropertySheets="UpgradeFromVC70.vsprops"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="2"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="..\..\..;..\..\minizip"
+				PreprocessorDefinitions="_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64"
+				MinimalRebuild="true"
+				BasicRuntimeChecks="0"
+				RuntimeLibrary="3"
+				BufferSecurityCheck="false"
+				UsePrecompiledHeader="0"
+				AssemblerListingLocation="$(IntDir)\"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="true"
+				DebugInformationFormat="3"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="ia64\ZlibDllDebug\zlibwapi.lib"
+				OutputFile="$(OutDir)/minizip.exe"
+				LinkIncremental="2"
+				GenerateManifest="false"
+				GenerateDebugInformation="true"
+				ProgramDatabaseFile="$(OutDir)/minizip.pdb"
+				SubSystem="1"
+				TargetMachine="5"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|x64"
+			OutputDirectory="x64\$(ConfigurationName)"
+			IntermediateDirectory="x64\$(ConfigurationName)"
+			ConfigurationType="1"
+			InheritedPropertySheets="UpgradeFromVC70.vsprops"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="2"
+				InlineFunctionExpansion="1"
+				OmitFramePointers="true"
+				AdditionalIncludeDirectories="..\..\..;..\..\minizip"
+				PreprocessorDefinitions="_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64"
+				StringPooling="true"
+				BasicRuntimeChecks="0"
+				RuntimeLibrary="2"
+				BufferSecurityCheck="false"
+				EnableFunctionLevelLinking="true"
+				UsePrecompiledHeader="0"
+				AssemblerListingLocation="$(IntDir)\"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="true"
+				DebugInformationFormat="3"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="x64\ZlibDllRelease\zlibwapi.lib"
+				OutputFile="$(OutDir)/minizip.exe"
+				LinkIncremental="1"
+				GenerateDebugInformation="true"
+				SubSystem="1"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
+				OptimizeForWindows98="1"
+				TargetMachine="17"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Itanium"
+			OutputDirectory="ia64\$(ConfigurationName)"
+			IntermediateDirectory="ia64\$(ConfigurationName)"
+			ConfigurationType="1"
+			InheritedPropertySheets="UpgradeFromVC70.vsprops"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="2"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="2"
+				InlineFunctionExpansion="1"
+				OmitFramePointers="true"
+				AdditionalIncludeDirectories="..\..\..;..\..\minizip"
+				PreprocessorDefinitions="_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64"
+				StringPooling="true"
+				BasicRuntimeChecks="0"
+				RuntimeLibrary="2"
+				BufferSecurityCheck="false"
+				EnableFunctionLevelLinking="true"
+				UsePrecompiledHeader="0"
+				AssemblerListingLocation="$(IntDir)\"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="true"
+				DebugInformationFormat="3"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="ia64\ZlibDllRelease\zlibwapi.lib"
+				OutputFile="$(OutDir)/minizip.exe"
+				LinkIncremental="1"
+				GenerateDebugInformation="true"
+				SubSystem="1"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
+				OptimizeForWindows98="1"
+				TargetMachine="5"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Source Files"
+			Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm"
+			>
+			<File
+				RelativePath="..\..\minizip\minizip.c"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="Header Files"
+			Filter="h;hpp;hxx;hm;inl;inc"
+			>
+		</Filter>
+		<Filter
+			Name="Resource Files"
+			Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+			>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
diff --git a/compat/zlib/contrib/vstudio/vc9/testzlib.vcproj b/compat/zlib/contrib/vstudio/vc9/testzlib.vcproj
new file mode 100644
index 0000000..9cb0bf8
--- /dev/null
+++ b/compat/zlib/contrib/vstudio/vc9/testzlib.vcproj
@@ -0,0 +1,852 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="9,00"
+	Name="testzlib"
+	ProjectGUID="{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}"
+	RootNamespace="testzlib"
+	Keyword="Win32Proj"
+	TargetFrameworkVersion="131072"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+		<Platform
+			Name="x64"
+		/>
+		<Platform
+			Name="Itanium"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="x86\TestZlib$(ConfigurationName)"
+			IntermediateDirectory="x86\TestZlib$(ConfigurationName)\Tmp"
+			ConfigurationType="1"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="..\..\.."
+				PreprocessorDefinitions="ASMV;ASMINF;WIN32;ZLIB_WINAPI;_DEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS"
+				MinimalRebuild="true"
+				BasicRuntimeChecks="0"
+				RuntimeLibrary="1"
+				BufferSecurityCheck="false"
+				UsePrecompiledHeader="0"
+				AssemblerOutput="4"
+				AssemblerListingLocation="$(IntDir)\"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="true"
+				DebugInformationFormat="4"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="..\..\masmx86\match686.obj ..\..\masmx86\inffas32.obj"
+				OutputFile="$(OutDir)/testzlib.exe"
+				LinkIncremental="2"
+				GenerateManifest="false"
+				GenerateDebugInformation="true"
+				ProgramDatabaseFile="$(OutDir)/testzlib.pdb"
+				SubSystem="1"
+				RandomizedBaseAddress="1"
+				DataExecutionPrevention="0"
+				TargetMachine="1"
+			/>
+			<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\TestZlib$(ConfigurationName)"
+			IntermediateDirectory="x64\TestZlib$(ConfigurationName)\Tmp"
+			ConfigurationType="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="..\..\.."
+				PreprocessorDefinitions="ASMV;ASMINF;WIN32;ZLIB_WINAPI;_DEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS"
+				BasicRuntimeChecks="0"
+				RuntimeLibrary="3"
+				BufferSecurityCheck="false"
+				AssemblerListingLocation="$(IntDir)\"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="..\..\masmx64\gvmat64.obj ..\..\masmx64\inffasx64.obj"
+				GenerateManifest="false"
+			/>
+			<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|Itanium"
+			OutputDirectory="ia64\TestZlib$(ConfigurationName)"
+			IntermediateDirectory="ia64\TestZlib$(ConfigurationName)\Tmp"
+			ConfigurationType="1"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="2"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="..\..\.."
+				PreprocessorDefinitions="ZLIB_WINAPI;_DEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64"
+				MinimalRebuild="true"
+				BasicRuntimeChecks="0"
+				RuntimeLibrary="3"
+				BufferSecurityCheck="false"
+				UsePrecompiledHeader="0"
+				AssemblerOutput="4"
+				AssemblerListingLocation="$(IntDir)\"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="true"
+				DebugInformationFormat="3"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				OutputFile="$(OutDir)/testzlib.exe"
+				LinkIncremental="2"
+				GenerateManifest="false"
+				GenerateDebugInformation="true"
+				ProgramDatabaseFile="$(OutDir)/testzlib.pdb"
+				SubSystem="1"
+				TargetMachine="5"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="ReleaseWithoutAsm|Win32"
+			OutputDirectory="x86\TestZlib$(ConfigurationName)"
+			IntermediateDirectory="x86\TestZlib$(ConfigurationName)\Tmp"
+			ConfigurationType="1"
+			CharacterSet="2"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="2"
+				InlineFunctionExpansion="1"
+				OmitFramePointers="true"
+				AdditionalIncludeDirectories="..\..\.."
+				PreprocessorDefinitions="WIN32;ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS"
+				StringPooling="true"
+				BasicRuntimeChecks="0"
+				RuntimeLibrary="0"
+				BufferSecurityCheck="false"
+				EnableFunctionLevelLinking="true"
+				UsePrecompiledHeader="0"
+				AssemblerListingLocation="$(IntDir)\"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="true"
+				DebugInformationFormat="3"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				OutputFile="$(OutDir)/testzlib.exe"
+				LinkIncremental="1"
+				GenerateManifest="false"
+				GenerateDebugInformation="true"
+				SubSystem="1"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
+				OptimizeForWindows98="1"
+				RandomizedBaseAddress="1"
+				DataExecutionPrevention="0"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="ReleaseWithoutAsm|x64"
+			OutputDirectory="x64\TestZlib$(ConfigurationName)"
+			IntermediateDirectory="x64\TestZlib$(ConfigurationName)\Tmp"
+			ConfigurationType="1"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="..\..\.."
+				PreprocessorDefinitions="WIN32;ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS"
+				BasicRuntimeChecks="0"
+				RuntimeLibrary="2"
+				BufferSecurityCheck="false"
+				AssemblerListingLocation="$(IntDir)\"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies=""
+				GenerateManifest="false"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="ReleaseWithoutAsm|Itanium"
+			OutputDirectory="ia64\TestZlib$(ConfigurationName)"
+			IntermediateDirectory="ia64\TestZlib$(ConfigurationName)\Tmp"
+			ConfigurationType="1"
+			CharacterSet="2"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="2"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="2"
+				InlineFunctionExpansion="1"
+				OmitFramePointers="true"
+				AdditionalIncludeDirectories="..\..\.."
+				PreprocessorDefinitions="ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64"
+				StringPooling="true"
+				BasicRuntimeChecks="0"
+				RuntimeLibrary="2"
+				BufferSecurityCheck="false"
+				EnableFunctionLevelLinking="true"
+				UsePrecompiledHeader="0"
+				AssemblerListingLocation="$(IntDir)\"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="true"
+				DebugInformationFormat="3"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				OutputFile="$(OutDir)/testzlib.exe"
+				LinkIncremental="1"
+				GenerateManifest="false"
+				GenerateDebugInformation="true"
+				SubSystem="1"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
+				OptimizeForWindows98="1"
+				TargetMachine="5"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="x86\TestZlib$(ConfigurationName)"
+			IntermediateDirectory="x86\TestZlib$(ConfigurationName)\Tmp"
+			ConfigurationType="1"
+			CharacterSet="2"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="2"
+				InlineFunctionExpansion="1"
+				OmitFramePointers="true"
+				AdditionalIncludeDirectories="..\..\.."
+				PreprocessorDefinitions="ASMV;ASMINF;WIN32;ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS"
+				StringPooling="true"
+				BasicRuntimeChecks="0"
+				RuntimeLibrary="0"
+				BufferSecurityCheck="false"
+				EnableFunctionLevelLinking="true"
+				UsePrecompiledHeader="0"
+				AssemblerListingLocation="$(IntDir)\"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="true"
+				DebugInformationFormat="3"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="..\..\masmx86\match686.obj ..\..\masmx86\inffas32.obj"
+				OutputFile="$(OutDir)/testzlib.exe"
+				LinkIncremental="1"
+				GenerateManifest="false"
+				GenerateDebugInformation="true"
+				SubSystem="1"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
+				OptimizeForWindows98="1"
+				RandomizedBaseAddress="1"
+				DataExecutionPrevention="0"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|x64"
+			OutputDirectory="x64\TestZlib$(ConfigurationName)"
+			IntermediateDirectory="x64\TestZlib$(ConfigurationName)\Tmp"
+			ConfigurationType="1"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="..\..\.."
+				PreprocessorDefinitions="ASMV;ASMINF;WIN32;ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS"
+				BasicRuntimeChecks="0"
+				RuntimeLibrary="0"
+				BufferSecurityCheck="false"
+				AssemblerListingLocation="$(IntDir)\"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="..\..\masmx64\gvmat64.obj ..\..\masmx64\inffasx64.obj"
+				GenerateManifest="false"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Itanium"
+			OutputDirectory="ia64\TestZlib$(ConfigurationName)"
+			IntermediateDirectory="ia64\TestZlib$(ConfigurationName)\Tmp"
+			ConfigurationType="1"
+			CharacterSet="2"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="2"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="2"
+				InlineFunctionExpansion="1"
+				OmitFramePointers="true"
+				AdditionalIncludeDirectories="..\..\.."
+				PreprocessorDefinitions="ZLIB_WINAPI;NDEBUG;_CONSOLE;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64"
+				StringPooling="true"
+				BasicRuntimeChecks="0"
+				RuntimeLibrary="2"
+				BufferSecurityCheck="false"
+				EnableFunctionLevelLinking="true"
+				UsePrecompiledHeader="0"
+				AssemblerListingLocation="$(IntDir)\"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="true"
+				DebugInformationFormat="3"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				OutputFile="$(OutDir)/testzlib.exe"
+				LinkIncremental="1"
+				GenerateManifest="false"
+				GenerateDebugInformation="true"
+				SubSystem="1"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
+				OptimizeForWindows98="1"
+				TargetMachine="5"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Source Files"
+			Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm"
+			>
+			<File
+				RelativePath="..\..\..\adler32.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\compress.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\crc32.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\deflate.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\infback.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\masmx64\inffas8664.c"
+				>
+				<FileConfiguration
+					Name="Debug|Win32"
+					ExcludedFromBuild="true"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|Itanium"
+					ExcludedFromBuild="true"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="ReleaseWithoutAsm|Win32"
+					ExcludedFromBuild="true"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="ReleaseWithoutAsm|Itanium"
+					ExcludedFromBuild="true"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|Win32"
+					ExcludedFromBuild="true"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|Itanium"
+					ExcludedFromBuild="true"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath="..\..\..\inffast.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\inflate.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\inftrees.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\testzlib\testzlib.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\trees.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\uncompr.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\zutil.c"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="Header Files"
+			Filter="h;hpp;hxx;hm;inl;inc"
+			>
+		</Filter>
+		<Filter
+			Name="Resource Files"
+			Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+			>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
diff --git a/compat/zlib/contrib/vstudio/vc9/testzlibdll.vcproj b/compat/zlib/contrib/vstudio/vc9/testzlibdll.vcproj
new file mode 100644
index 0000000..b1ddde0
--- /dev/null
+++ b/compat/zlib/contrib/vstudio/vc9/testzlibdll.vcproj
@@ -0,0 +1,565 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="9.00"
+	Name="TestZlibDll"
+	ProjectGUID="{C52F9E7B-498A-42BE-8DB4-85A15694366A}"
+	Keyword="Win32Proj"
+	TargetFrameworkVersion="131072"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+		<Platform
+			Name="x64"
+		/>
+		<Platform
+			Name="Itanium"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="x86\TestZlibDll$(ConfigurationName)"
+			IntermediateDirectory="x86\TestZlibDll$(ConfigurationName)\Tmp"
+			ConfigurationType="1"
+			InheritedPropertySheets="UpgradeFromVC70.vsprops"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="..\..\..;..\..\minizip"
+				PreprocessorDefinitions="WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE"
+				MinimalRebuild="true"
+				BasicRuntimeChecks="0"
+				RuntimeLibrary="1"
+				BufferSecurityCheck="false"
+				UsePrecompiledHeader="0"
+				AssemblerListingLocation="$(IntDir)\"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="true"
+				DebugInformationFormat="4"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="x86\ZlibDllDebug\zlibwapi.lib"
+				OutputFile="$(OutDir)/testzlib.exe"
+				LinkIncremental="2"
+				GenerateManifest="false"
+				GenerateDebugInformation="true"
+				ProgramDatabaseFile="$(OutDir)/testzlib.pdb"
+				SubSystem="1"
+				RandomizedBaseAddress="1"
+				DataExecutionPrevention="0"
+				TargetMachine="1"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="x86\TestZlibDll$(ConfigurationName)"
+			IntermediateDirectory="x86\TestZlibDll$(ConfigurationName)\Tmp"
+			ConfigurationType="1"
+			InheritedPropertySheets="UpgradeFromVC70.vsprops"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="2"
+				InlineFunctionExpansion="1"
+				OmitFramePointers="true"
+				AdditionalIncludeDirectories="..\..\..;..\..\minizip"
+				PreprocessorDefinitions="WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE"
+				StringPooling="true"
+				BasicRuntimeChecks="0"
+				RuntimeLibrary="0"
+				BufferSecurityCheck="false"
+				EnableFunctionLevelLinking="true"
+				UsePrecompiledHeader="0"
+				AssemblerListingLocation="$(IntDir)\"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="true"
+				DebugInformationFormat="3"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="x86\ZlibDllRelease\zlibwapi.lib"
+				OutputFile="$(OutDir)/testzlib.exe"
+				LinkIncremental="1"
+				GenerateManifest="false"
+				GenerateDebugInformation="true"
+				SubSystem="1"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
+				OptimizeForWindows98="1"
+				RandomizedBaseAddress="1"
+				DataExecutionPrevention="0"
+				TargetMachine="1"
+			/>
+			<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\TestZlibDll$(ConfigurationName)"
+			IntermediateDirectory="x64\TestZlibDll$(ConfigurationName)\Tmp"
+			ConfigurationType="1"
+			InheritedPropertySheets="UpgradeFromVC70.vsprops"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="..\..\..;..\..\minizip"
+				PreprocessorDefinitions="_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64"
+				MinimalRebuild="true"
+				BasicRuntimeChecks="0"
+				RuntimeLibrary="3"
+				BufferSecurityCheck="false"
+				UsePrecompiledHeader="0"
+				AssemblerListingLocation="$(IntDir)\"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="true"
+				DebugInformationFormat="3"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="x64\ZlibDllDebug\zlibwapi.lib"
+				OutputFile="$(OutDir)/testzlib.exe"
+				LinkIncremental="2"
+				GenerateManifest="false"
+				GenerateDebugInformation="true"
+				ProgramDatabaseFile="$(OutDir)/testzlib.pdb"
+				SubSystem="1"
+				TargetMachine="17"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Debug|Itanium"
+			OutputDirectory="ia64\TestZlibDll$(ConfigurationName)"
+			IntermediateDirectory="ia64\TestZlibDll$(ConfigurationName)\Tmp"
+			ConfigurationType="1"
+			InheritedPropertySheets="UpgradeFromVC70.vsprops"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="2"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="..\..\..;..\..\minizip"
+				PreprocessorDefinitions="_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;_DEBUG;_CONSOLE;WIN64"
+				MinimalRebuild="true"
+				BasicRuntimeChecks="0"
+				RuntimeLibrary="3"
+				BufferSecurityCheck="false"
+				UsePrecompiledHeader="0"
+				AssemblerListingLocation="$(IntDir)\"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="true"
+				DebugInformationFormat="3"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="ia64\ZlibDllDebug\zlibwapi.lib"
+				OutputFile="$(OutDir)/testzlib.exe"
+				LinkIncremental="2"
+				GenerateManifest="false"
+				GenerateDebugInformation="true"
+				ProgramDatabaseFile="$(OutDir)/testzlib.pdb"
+				SubSystem="1"
+				TargetMachine="5"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|x64"
+			OutputDirectory="x64\TestZlibDll$(ConfigurationName)"
+			IntermediateDirectory="x64\TestZlibDll$(ConfigurationName)\Tmp"
+			ConfigurationType="1"
+			InheritedPropertySheets="UpgradeFromVC70.vsprops"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="2"
+				InlineFunctionExpansion="1"
+				OmitFramePointers="true"
+				AdditionalIncludeDirectories="..\..\..;..\..\minizip"
+				PreprocessorDefinitions="_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64"
+				StringPooling="true"
+				BasicRuntimeChecks="0"
+				RuntimeLibrary="2"
+				BufferSecurityCheck="false"
+				EnableFunctionLevelLinking="true"
+				UsePrecompiledHeader="0"
+				AssemblerListingLocation="$(IntDir)\"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="true"
+				DebugInformationFormat="3"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="x64\ZlibDllRelease\zlibwapi.lib"
+				OutputFile="$(OutDir)/testzlib.exe"
+				LinkIncremental="1"
+				GenerateManifest="false"
+				GenerateDebugInformation="true"
+				SubSystem="1"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
+				OptimizeForWindows98="1"
+				TargetMachine="17"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Itanium"
+			OutputDirectory="ia64\TestZlibDll$(ConfigurationName)"
+			IntermediateDirectory="ia64\TestZlibDll$(ConfigurationName)\Tmp"
+			ConfigurationType="1"
+			InheritedPropertySheets="UpgradeFromVC70.vsprops"
+			CharacterSet="2"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="2"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="2"
+				InlineFunctionExpansion="1"
+				OmitFramePointers="true"
+				AdditionalIncludeDirectories="..\..\..;..\..\minizip"
+				PreprocessorDefinitions="_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;ZLIB_WINAPI;NDEBUG;_CONSOLE;WIN64"
+				StringPooling="true"
+				BasicRuntimeChecks="0"
+				RuntimeLibrary="2"
+				BufferSecurityCheck="false"
+				EnableFunctionLevelLinking="true"
+				UsePrecompiledHeader="0"
+				AssemblerListingLocation="$(IntDir)\"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="true"
+				DebugInformationFormat="3"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="ia64\ZlibDllRelease\zlibwapi.lib"
+				OutputFile="$(OutDir)/testzlib.exe"
+				LinkIncremental="1"
+				GenerateManifest="false"
+				GenerateDebugInformation="true"
+				SubSystem="1"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
+				OptimizeForWindows98="1"
+				TargetMachine="5"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCWebDeploymentTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Source Files"
+			Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm"
+			>
+			<File
+				RelativePath="..\..\testzlib\testzlib.c"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="Header Files"
+			Filter="h;hpp;hxx;hm;inl;inc"
+			>
+		</Filter>
+		<Filter
+			Name="Resource Files"
+			Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
+			>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
diff --git a/compat/zlib/contrib/vstudio/vc9/zlib.rc b/compat/zlib/contrib/vstudio/vc9/zlib.rc
new file mode 100644
index 0000000..73f6476
--- /dev/null
+++ b/compat/zlib/contrib/vstudio/vc9/zlib.rc
@@ -0,0 +1,32 @@
+#include <windows.h>
+
+#define IDR_VERSION1  1
+IDR_VERSION1	VERSIONINFO	MOVEABLE IMPURE LOADONCALL DISCARDABLE
+  FILEVERSION	 1,2,8,0
+  PRODUCTVERSION 1,2,8,0
+  FILEFLAGSMASK	VS_FFI_FILEFLAGSMASK
+  FILEFLAGS	0
+  FILEOS	VOS_DOS_WINDOWS32
+  FILETYPE	VFT_DLL
+  FILESUBTYPE	0	// not used
+BEGIN
+  BLOCK "StringFileInfo"
+  BEGIN
+    BLOCK "040904E4"
+    //language ID = U.S. English, char set = Windows, Multilingual
+
+    BEGIN
+      VALUE "FileDescription", "zlib data compression and ZIP file I/O library\0"
+      VALUE "FileVersion",	"1.2.8\0"
+      VALUE "InternalName",	"zlib\0"
+      VALUE "OriginalFilename",	"zlibwapi.dll\0"
+      VALUE "ProductName",	"ZLib.DLL\0"
+      VALUE "Comments","DLL support by Alessandro Iacopetti & Gilles Vollant\0"
+      VALUE "LegalCopyright", "(C) 1995-2013 Jean-loup Gailly & Mark Adler\0"
+    END
+  END
+  BLOCK "VarFileInfo"
+  BEGIN
+    VALUE "Translation", 0x0409, 1252
+  END
+END
diff --git a/compat/zlib/contrib/vstudio/vc9/zlibstat.vcproj b/compat/zlib/contrib/vstudio/vc9/zlibstat.vcproj
new file mode 100644
index 0000000..61c76c7
--- /dev/null
+++ b/compat/zlib/contrib/vstudio/vc9/zlibstat.vcproj
@@ -0,0 +1,835 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="9,00"
+	Name="zlibstat"
+	ProjectGUID="{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}"
+	TargetFrameworkVersion="131072"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+		<Platform
+			Name="x64"
+		/>
+		<Platform
+			Name="Itanium"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="x86\ZlibStat$(ConfigurationName)"
+			IntermediateDirectory="x86\ZlibStat$(ConfigurationName)\Tmp"
+			ConfigurationType="4"
+			InheritedPropertySheets="UpgradeFromVC70.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="..\..\..;..\..\masmx86"
+				PreprocessorDefinitions="WIN32;ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS"
+				ExceptionHandling="0"
+				RuntimeLibrary="1"
+				BufferSecurityCheck="false"
+				PrecompiledHeaderFile="$(IntDir)/zlibstat.pch"
+				AssemblerListingLocation="$(IntDir)\"
+				ObjectFile="$(IntDir)\"
+				ProgramDataBaseFileName="$(OutDir)\"
+				WarningLevel="3"
+				SuppressStartupBanner="true"
+				Detect64BitPortabilityProblems="true"
+				DebugInformationFormat="1"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+				Culture="1036"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+				AdditionalOptions="/MACHINE:X86 /NODEFAULTLIB"
+				OutputFile="$(OutDir)\zlibstat.lib"
+				SuppressStartupBanner="true"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Debug|x64"
+			OutputDirectory="x64\ZlibStat$(ConfigurationName)"
+			IntermediateDirectory="x64\ZlibStat$(ConfigurationName)\Tmp"
+			ConfigurationType="4"
+			InheritedPropertySheets="UpgradeFromVC70.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="..\..\..;..\..\masmx86"
+				PreprocessorDefinitions="ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64"
+				ExceptionHandling="0"
+				RuntimeLibrary="3"
+				BufferSecurityCheck="false"
+				PrecompiledHeaderFile="$(IntDir)/zlibstat.pch"
+				AssemblerListingLocation="$(IntDir)\"
+				ObjectFile="$(IntDir)\"
+				ProgramDataBaseFileName="$(OutDir)\"
+				WarningLevel="3"
+				SuppressStartupBanner="true"
+				Detect64BitPortabilityProblems="true"
+				DebugInformationFormat="1"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+				Culture="1036"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+				AdditionalOptions="/MACHINE:AMD64 /NODEFAULTLIB"
+				OutputFile="$(OutDir)\zlibstat.lib"
+				SuppressStartupBanner="true"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Debug|Itanium"
+			OutputDirectory="ia64\ZlibStat$(ConfigurationName)"
+			IntermediateDirectory="ia64\ZlibStat$(ConfigurationName)\Tmp"
+			ConfigurationType="4"
+			InheritedPropertySheets="UpgradeFromVC70.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="2"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="..\..\..;..\..\masmx86"
+				PreprocessorDefinitions="ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64"
+				ExceptionHandling="0"
+				RuntimeLibrary="3"
+				BufferSecurityCheck="false"
+				PrecompiledHeaderFile="$(IntDir)/zlibstat.pch"
+				AssemblerListingLocation="$(IntDir)\"
+				ObjectFile="$(IntDir)\"
+				ProgramDataBaseFileName="$(OutDir)\"
+				WarningLevel="3"
+				SuppressStartupBanner="true"
+				Detect64BitPortabilityProblems="true"
+				DebugInformationFormat="1"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+				Culture="1036"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+				AdditionalOptions="/MACHINE:IA64 /NODEFAULTLIB"
+				OutputFile="$(OutDir)\zlibstat.lib"
+				SuppressStartupBanner="true"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="x86\ZlibStat$(ConfigurationName)"
+			IntermediateDirectory="x86\ZlibStat$(ConfigurationName)\Tmp"
+			ConfigurationType="4"
+			InheritedPropertySheets="UpgradeFromVC70.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				InlineFunctionExpansion="1"
+				AdditionalIncludeDirectories="..\..\..;..\..\masmx86"
+				PreprocessorDefinitions="WIN32;ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ASMV;ASMINF"
+				StringPooling="true"
+				ExceptionHandling="0"
+				RuntimeLibrary="0"
+				BufferSecurityCheck="false"
+				EnableFunctionLevelLinking="true"
+				PrecompiledHeaderFile="$(IntDir)/zlibstat.pch"
+				AssemblerListingLocation="$(IntDir)\"
+				ObjectFile="$(IntDir)\"
+				ProgramDataBaseFileName="$(OutDir)\"
+				WarningLevel="3"
+				SuppressStartupBanner="true"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+				Culture="1036"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+				AdditionalOptions="/MACHINE:X86 /NODEFAULTLIB"
+				AdditionalDependencies="..\..\masmx86\match686.obj ..\..\masmx86\inffas32.obj "
+				OutputFile="$(OutDir)\zlibstat.lib"
+				SuppressStartupBanner="true"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|x64"
+			OutputDirectory="x64\ZlibStat$(ConfigurationName)"
+			IntermediateDirectory="x64\ZlibStat$(ConfigurationName)\Tmp"
+			ConfigurationType="4"
+			InheritedPropertySheets="UpgradeFromVC70.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				InlineFunctionExpansion="1"
+				AdditionalIncludeDirectories="..\..\..;..\..\masmx86"
+				PreprocessorDefinitions="ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ASMV;ASMINF;WIN64"
+				StringPooling="true"
+				ExceptionHandling="0"
+				RuntimeLibrary="2"
+				BufferSecurityCheck="false"
+				EnableFunctionLevelLinking="true"
+				PrecompiledHeaderFile="$(IntDir)/zlibstat.pch"
+				AssemblerListingLocation="$(IntDir)\"
+				ObjectFile="$(IntDir)\"
+				ProgramDataBaseFileName="$(OutDir)\"
+				WarningLevel="3"
+				SuppressStartupBanner="true"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+				Culture="1036"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+				AdditionalOptions="/MACHINE:AMD64 /NODEFAULTLIB"
+				AdditionalDependencies="..\..\masmx64\gvmat64.obj ..\..\masmx64\inffasx64.obj "
+				OutputFile="$(OutDir)\zlibstat.lib"
+				SuppressStartupBanner="true"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Itanium"
+			OutputDirectory="ia64\ZlibStat$(ConfigurationName)"
+			IntermediateDirectory="ia64\ZlibStat$(ConfigurationName)\Tmp"
+			ConfigurationType="4"
+			InheritedPropertySheets="UpgradeFromVC70.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="2"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				InlineFunctionExpansion="1"
+				AdditionalIncludeDirectories="..\..\..;..\..\masmx86"
+				PreprocessorDefinitions="ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64"
+				StringPooling="true"
+				ExceptionHandling="0"
+				RuntimeLibrary="2"
+				BufferSecurityCheck="false"
+				EnableFunctionLevelLinking="true"
+				PrecompiledHeaderFile="$(IntDir)/zlibstat.pch"
+				AssemblerListingLocation="$(IntDir)\"
+				ObjectFile="$(IntDir)\"
+				ProgramDataBaseFileName="$(OutDir)\"
+				WarningLevel="3"
+				SuppressStartupBanner="true"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+				Culture="1036"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+				AdditionalOptions="/MACHINE:IA64 /NODEFAULTLIB"
+				OutputFile="$(OutDir)\zlibstat.lib"
+				SuppressStartupBanner="true"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="ReleaseWithoutAsm|Win32"
+			OutputDirectory="x86\ZlibStat$(ConfigurationName)"
+			IntermediateDirectory="x86\ZlibStat$(ConfigurationName)\Tmp"
+			ConfigurationType="4"
+			InheritedPropertySheets="UpgradeFromVC70.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				InlineFunctionExpansion="1"
+				AdditionalIncludeDirectories="..\..\..;..\..\masmx86"
+				PreprocessorDefinitions="WIN32;ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS"
+				StringPooling="true"
+				ExceptionHandling="0"
+				RuntimeLibrary="0"
+				BufferSecurityCheck="false"
+				EnableFunctionLevelLinking="true"
+				PrecompiledHeaderFile="$(IntDir)/zlibstat.pch"
+				AssemblerListingLocation="$(IntDir)\"
+				ObjectFile="$(IntDir)\"
+				ProgramDataBaseFileName="$(OutDir)\"
+				WarningLevel="3"
+				SuppressStartupBanner="true"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+				Culture="1036"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+				AdditionalOptions="/MACHINE:X86 /NODEFAULTLIB"
+				OutputFile="$(OutDir)\zlibstat.lib"
+				SuppressStartupBanner="true"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="ReleaseWithoutAsm|x64"
+			OutputDirectory="x64\ZlibStat$(ConfigurationName)"
+			IntermediateDirectory="x64\ZlibStat$(ConfigurationName)\Tmp"
+			ConfigurationType="4"
+			InheritedPropertySheets="UpgradeFromVC70.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="3"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				InlineFunctionExpansion="1"
+				AdditionalIncludeDirectories="..\..\..;..\..\masmx86"
+				PreprocessorDefinitions="ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64"
+				StringPooling="true"
+				ExceptionHandling="0"
+				RuntimeLibrary="2"
+				BufferSecurityCheck="false"
+				EnableFunctionLevelLinking="true"
+				PrecompiledHeaderFile="$(IntDir)/zlibstat.pch"
+				AssemblerListingLocation="$(IntDir)\"
+				ObjectFile="$(IntDir)\"
+				ProgramDataBaseFileName="$(OutDir)\"
+				WarningLevel="3"
+				SuppressStartupBanner="true"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+				Culture="1036"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+				AdditionalOptions="/MACHINE:AMD64 /NODEFAULTLIB"
+				OutputFile="$(OutDir)\zlibstat.lib"
+				SuppressStartupBanner="true"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="ReleaseWithoutAsm|Itanium"
+			OutputDirectory="ia64\ZlibStat$(ConfigurationName)"
+			IntermediateDirectory="ia64\ZlibStat$(ConfigurationName)\Tmp"
+			ConfigurationType="4"
+			InheritedPropertySheets="UpgradeFromVC70.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				TargetEnvironment="2"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				InlineFunctionExpansion="1"
+				AdditionalIncludeDirectories="..\..\..;..\..\masmx86"
+				PreprocessorDefinitions="ZLIB_WINAPI;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;WIN64"
+				StringPooling="true"
+				ExceptionHandling="0"
+				RuntimeLibrary="2"
+				BufferSecurityCheck="false"
+				EnableFunctionLevelLinking="true"
+				PrecompiledHeaderFile="$(IntDir)/zlibstat.pch"
+				AssemblerListingLocation="$(IntDir)\"
+				ObjectFile="$(IntDir)\"
+				ProgramDataBaseFileName="$(OutDir)\"
+				WarningLevel="3"
+				SuppressStartupBanner="true"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+				Culture="1036"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLibrarianTool"
+				AdditionalOptions="/MACHINE:IA64 /NODEFAULTLIB"
+				OutputFile="$(OutDir)\zlibstat.lib"
+				SuppressStartupBanner="true"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Source Files"
+			>
+			<File
+				RelativePath="..\..\..\adler32.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\compress.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\crc32.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\deflate.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\gzclose.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\gzguts.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\gzlib.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\gzread.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\gzwrite.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\infback.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\masmx64\inffas8664.c"
+				>
+				<FileConfiguration
+					Name="Debug|Win32"
+					ExcludedFromBuild="true"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|Itanium"
+					ExcludedFromBuild="true"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|Win32"
+					ExcludedFromBuild="true"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|Itanium"
+					ExcludedFromBuild="true"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="ReleaseWithoutAsm|Win32"
+					ExcludedFromBuild="true"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="ReleaseWithoutAsm|Itanium"
+					ExcludedFromBuild="true"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath="..\..\..\inffast.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\inflate.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\inftrees.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\minizip\ioapi.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\trees.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\uncompr.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\minizip\unzip.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\minizip\zip.c"
+				>
+			</File>
+			<File
+				RelativePath=".\zlib.rc"
+				>
+			</File>
+			<File
+				RelativePath=".\zlibvc.def"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\zutil.c"
+				>
+			</File>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
diff --git a/compat/zlib/contrib/vstudio/vc9/zlibvc.def b/compat/zlib/contrib/vstudio/vc9/zlibvc.def
new file mode 100644
index 0000000..6367046
--- /dev/null
+++ b/compat/zlib/contrib/vstudio/vc9/zlibvc.def
@@ -0,0 +1,143 @@
+LIBRARY
+; zlib data compression and ZIP file I/O library
+
+VERSION		1.2.8
+
+EXPORTS
+        adler32                                  @1
+        compress                                 @2
+        crc32                                    @3
+        deflate                                  @4
+        deflateCopy                              @5
+        deflateEnd                               @6
+        deflateInit2_                            @7
+        deflateInit_                             @8
+        deflateParams                            @9
+        deflateReset                             @10
+        deflateSetDictionary                     @11
+        gzclose                                  @12
+        gzdopen                                  @13
+        gzerror                                  @14
+        gzflush                                  @15
+        gzopen                                   @16
+        gzread                                   @17
+        gzwrite                                  @18
+        inflate                                  @19
+        inflateEnd                               @20
+        inflateInit2_                            @21
+        inflateInit_                             @22
+        inflateReset                             @23
+        inflateSetDictionary                     @24
+        inflateSync                              @25
+        uncompress                               @26
+        zlibVersion                              @27
+        gzprintf                                 @28
+        gzputc                                   @29
+        gzgetc                                   @30
+        gzseek                                   @31
+        gzrewind                                 @32
+        gztell                                   @33
+        gzeof                                    @34
+        gzsetparams                              @35
+        zError                                   @36
+        inflateSyncPoint                         @37
+        get_crc_table                            @38
+        compress2                                @39
+        gzputs                                   @40
+        gzgets                                   @41
+        inflateCopy                              @42
+        inflateBackInit_                         @43
+        inflateBack                              @44
+        inflateBackEnd                           @45
+        compressBound                            @46
+        deflateBound                             @47
+        gzclearerr                               @48
+        gzungetc                                 @49
+        zlibCompileFlags                         @50
+        deflatePrime                             @51
+        deflatePending                           @52
+
+        unzOpen                                  @61
+        unzClose                                 @62
+        unzGetGlobalInfo                         @63
+        unzGetCurrentFileInfo                    @64
+        unzGoToFirstFile                         @65
+        unzGoToNextFile                          @66
+        unzOpenCurrentFile                       @67
+        unzReadCurrentFile                       @68
+        unzOpenCurrentFile3                      @69
+        unztell                                  @70
+        unzeof                                   @71
+        unzCloseCurrentFile                      @72
+        unzGetGlobalComment                      @73
+        unzStringFileNameCompare                 @74
+        unzLocateFile                            @75
+        unzGetLocalExtrafield                    @76
+        unzOpen2                                 @77
+        unzOpenCurrentFile2                      @78
+        unzOpenCurrentFilePassword               @79
+
+        zipOpen                                  @80
+        zipOpenNewFileInZip                      @81
+        zipWriteInFileInZip                      @82
+        zipCloseFileInZip                        @83
+        zipClose                                 @84
+        zipOpenNewFileInZip2                     @86
+        zipCloseFileInZipRaw                     @87
+        zipOpen2                                 @88
+        zipOpenNewFileInZip3                     @89
+
+        unzGetFilePos                            @100
+        unzGoToFilePos                           @101
+
+        fill_win32_filefunc                      @110
+
+; zlibwapi v1.2.4 added:
+        fill_win32_filefunc64                   @111
+        fill_win32_filefunc64A                  @112
+        fill_win32_filefunc64W                  @113
+
+        unzOpen64                               @120
+        unzOpen2_64                             @121
+        unzGetGlobalInfo64                      @122
+        unzGetCurrentFileInfo64                 @124
+        unzGetCurrentFileZStreamPos64           @125
+        unztell64                               @126
+        unzGetFilePos64                         @127
+        unzGoToFilePos64                        @128
+
+        zipOpen64                               @130
+        zipOpen2_64                             @131
+        zipOpenNewFileInZip64                   @132
+        zipOpenNewFileInZip2_64                 @133
+        zipOpenNewFileInZip3_64                 @134
+        zipOpenNewFileInZip4_64                 @135
+        zipCloseFileInZipRaw64                  @136
+
+; zlib1 v1.2.4 added:
+        adler32_combine                         @140
+        crc32_combine                           @142
+        deflateSetHeader                        @144
+        deflateTune                             @145
+        gzbuffer                                @146
+        gzclose_r                               @147
+        gzclose_w                               @148
+        gzdirect                                @149
+        gzoffset                                @150
+        inflateGetHeader                        @156
+        inflateMark                             @157
+        inflatePrime                            @158
+        inflateReset2                           @159
+        inflateUndermine                        @160
+
+; zlib1 v1.2.6 added:
+        gzgetc_                                 @161
+        inflateResetKeep                        @163
+        deflateResetKeep                        @164
+
+; zlib1 v1.2.7 added:
+        gzopen_w                                @165
+
+; zlib1 v1.2.8 added:
+        inflateGetDictionary                    @166
+        gzvprintf                               @167
diff --git a/compat/zlib/contrib/vstudio/vc9/zlibvc.sln b/compat/zlib/contrib/vstudio/vc9/zlibvc.sln
new file mode 100644
index 0000000..b482967
--- /dev/null
+++ b/compat/zlib/contrib/vstudio/vc9/zlibvc.sln
@@ -0,0 +1,144 @@
+﻿
+Microsoft Visual Studio Solution File, Format Version 10.00
+# Visual Studio 2008
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlibvc", "zlibvc.vcproj", "{8FD826F8-3739-44E6-8CC8-997122E53B8D}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlibstat", "zlibstat.vcproj", "{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "testzlib", "testzlib.vcproj", "{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TestZlibDll", "testzlibdll.vcproj", "{C52F9E7B-498A-42BE-8DB4-85A15694366A}"
+	ProjectSection(ProjectDependencies) = postProject
+		{8FD826F8-3739-44E6-8CC8-997122E53B8D} = {8FD826F8-3739-44E6-8CC8-997122E53B8D}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "minizip", "minizip.vcproj", "{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}"
+	ProjectSection(ProjectDependencies) = postProject
+		{8FD826F8-3739-44E6-8CC8-997122E53B8D} = {8FD826F8-3739-44E6-8CC8-997122E53B8D}
+	EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "miniunz", "miniunz.vcproj", "{C52F9E7B-498A-42BE-8DB4-85A15694382A}"
+	ProjectSection(ProjectDependencies) = postProject
+		{8FD826F8-3739-44E6-8CC8-997122E53B8D} = {8FD826F8-3739-44E6-8CC8-997122E53B8D}
+	EndProjectSection
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Itanium = Debug|Itanium
+		Debug|Win32 = Debug|Win32
+		Debug|x64 = Debug|x64
+		Release|Itanium = Release|Itanium
+		Release|Win32 = Release|Win32
+		Release|x64 = Release|x64
+		ReleaseWithoutAsm|Itanium = ReleaseWithoutAsm|Itanium
+		ReleaseWithoutAsm|Win32 = ReleaseWithoutAsm|Win32
+		ReleaseWithoutAsm|x64 = ReleaseWithoutAsm|x64
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|Itanium.ActiveCfg = Debug|Itanium
+		{8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|Itanium.Build.0 = Debug|Itanium
+		{8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|Win32.ActiveCfg = Debug|Win32
+		{8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|Win32.Build.0 = Debug|Win32
+		{8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|x64.ActiveCfg = Debug|x64
+		{8FD826F8-3739-44E6-8CC8-997122E53B8D}.Debug|x64.Build.0 = Debug|x64
+		{8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|Itanium.ActiveCfg = Release|Itanium
+		{8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|Itanium.Build.0 = Release|Itanium
+		{8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|Win32.ActiveCfg = Release|Win32
+		{8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|Win32.Build.0 = Release|Win32
+		{8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|x64.ActiveCfg = Release|x64
+		{8FD826F8-3739-44E6-8CC8-997122E53B8D}.Release|x64.Build.0 = Release|x64
+		{8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|Itanium.ActiveCfg = ReleaseWithoutAsm|Itanium
+		{8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|Itanium.Build.0 = ReleaseWithoutAsm|Itanium
+		{8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|Win32.ActiveCfg = ReleaseWithoutAsm|Win32
+		{8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|Win32.Build.0 = ReleaseWithoutAsm|Win32
+		{8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|x64.ActiveCfg = ReleaseWithoutAsm|x64
+		{8FD826F8-3739-44E6-8CC8-997122E53B8D}.ReleaseWithoutAsm|x64.Build.0 = ReleaseWithoutAsm|x64
+		{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|Itanium.ActiveCfg = Debug|Itanium
+		{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|Itanium.Build.0 = Debug|Itanium
+		{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|Win32.ActiveCfg = Debug|Win32
+		{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|Win32.Build.0 = Debug|Win32
+		{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|x64.ActiveCfg = Debug|x64
+		{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Debug|x64.Build.0 = Debug|x64
+		{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|Itanium.ActiveCfg = Release|Itanium
+		{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|Itanium.Build.0 = Release|Itanium
+		{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|Win32.ActiveCfg = Release|Win32
+		{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|Win32.Build.0 = Release|Win32
+		{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|x64.ActiveCfg = Release|x64
+		{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.Release|x64.Build.0 = Release|x64
+		{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|Itanium.ActiveCfg = ReleaseWithoutAsm|Itanium
+		{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|Itanium.Build.0 = ReleaseWithoutAsm|Itanium
+		{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|Win32.ActiveCfg = ReleaseWithoutAsm|Win32
+		{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|Win32.Build.0 = ReleaseWithoutAsm|Win32
+		{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|x64.ActiveCfg = ReleaseWithoutAsm|x64
+		{745DEC58-EBB3-47A9-A9B8-4C6627C01BF8}.ReleaseWithoutAsm|x64.Build.0 = ReleaseWithoutAsm|x64
+		{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|Itanium.ActiveCfg = Debug|Itanium
+		{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|Itanium.Build.0 = Debug|Itanium
+		{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|Win32.ActiveCfg = Debug|Win32
+		{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|Win32.Build.0 = Debug|Win32
+		{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|x64.ActiveCfg = Debug|x64
+		{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Debug|x64.Build.0 = Debug|x64
+		{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|Itanium.ActiveCfg = Release|Itanium
+		{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|Itanium.Build.0 = Release|Itanium
+		{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|Win32.ActiveCfg = Release|Win32
+		{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|Win32.Build.0 = Release|Win32
+		{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|x64.ActiveCfg = Release|x64
+		{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.Release|x64.Build.0 = Release|x64
+		{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Itanium.ActiveCfg = ReleaseWithoutAsm|Itanium
+		{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Itanium.Build.0 = ReleaseWithoutAsm|Itanium
+		{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Win32.ActiveCfg = ReleaseWithoutAsm|Win32
+		{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Win32.Build.0 = ReleaseWithoutAsm|Win32
+		{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|x64.ActiveCfg = ReleaseWithoutAsm|x64
+		{AA6666AA-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|x64.Build.0 = ReleaseWithoutAsm|x64
+		{C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|Itanium.ActiveCfg = Debug|Itanium
+		{C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|Itanium.Build.0 = Debug|Itanium
+		{C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|Win32.ActiveCfg = Debug|Win32
+		{C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|Win32.Build.0 = Debug|Win32
+		{C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|x64.ActiveCfg = Debug|x64
+		{C52F9E7B-498A-42BE-8DB4-85A15694366A}.Debug|x64.Build.0 = Debug|x64
+		{C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|Itanium.ActiveCfg = Release|Itanium
+		{C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|Itanium.Build.0 = Release|Itanium
+		{C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|Win32.ActiveCfg = Release|Win32
+		{C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|Win32.Build.0 = Release|Win32
+		{C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|x64.ActiveCfg = Release|x64
+		{C52F9E7B-498A-42BE-8DB4-85A15694366A}.Release|x64.Build.0 = Release|x64
+		{C52F9E7B-498A-42BE-8DB4-85A15694366A}.ReleaseWithoutAsm|Itanium.ActiveCfg = Release|Itanium
+		{C52F9E7B-498A-42BE-8DB4-85A15694366A}.ReleaseWithoutAsm|Itanium.Build.0 = Release|Itanium
+		{C52F9E7B-498A-42BE-8DB4-85A15694366A}.ReleaseWithoutAsm|Win32.ActiveCfg = Release|Win32
+		{C52F9E7B-498A-42BE-8DB4-85A15694366A}.ReleaseWithoutAsm|x64.ActiveCfg = Release|x64
+		{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|Itanium.ActiveCfg = Debug|Itanium
+		{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|Itanium.Build.0 = Debug|Itanium
+		{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|Win32.ActiveCfg = Debug|Win32
+		{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|Win32.Build.0 = Debug|Win32
+		{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|x64.ActiveCfg = Debug|x64
+		{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Debug|x64.Build.0 = Debug|x64
+		{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|Itanium.ActiveCfg = Release|Itanium
+		{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|Itanium.Build.0 = Release|Itanium
+		{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|Win32.ActiveCfg = Release|Win32
+		{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|Win32.Build.0 = Release|Win32
+		{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|x64.ActiveCfg = Release|x64
+		{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.Release|x64.Build.0 = Release|x64
+		{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Itanium.ActiveCfg = Release|Itanium
+		{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Itanium.Build.0 = Release|Itanium
+		{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|Win32.ActiveCfg = Release|Win32
+		{48CDD9DC-E09F-4135-9C0C-4FE50C3C654B}.ReleaseWithoutAsm|x64.ActiveCfg = Release|x64
+		{C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|Itanium.ActiveCfg = Debug|Itanium
+		{C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|Itanium.Build.0 = Debug|Itanium
+		{C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|Win32.ActiveCfg = Debug|Win32
+		{C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|Win32.Build.0 = Debug|Win32
+		{C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|x64.ActiveCfg = Debug|x64
+		{C52F9E7B-498A-42BE-8DB4-85A15694382A}.Debug|x64.Build.0 = Debug|x64
+		{C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|Itanium.ActiveCfg = Release|Itanium
+		{C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|Itanium.Build.0 = Release|Itanium
+		{C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|Win32.ActiveCfg = Release|Win32
+		{C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|Win32.Build.0 = Release|Win32
+		{C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|x64.ActiveCfg = Release|x64
+		{C52F9E7B-498A-42BE-8DB4-85A15694382A}.Release|x64.Build.0 = Release|x64
+		{C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseWithoutAsm|Itanium.ActiveCfg = Release|Itanium
+		{C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseWithoutAsm|Itanium.Build.0 = Release|Itanium
+		{C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseWithoutAsm|Win32.ActiveCfg = Release|Win32
+		{C52F9E7B-498A-42BE-8DB4-85A15694382A}.ReleaseWithoutAsm|x64.ActiveCfg = Release|x64
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal
diff --git a/compat/zlib/contrib/vstudio/vc9/zlibvc.vcproj b/compat/zlib/contrib/vstudio/vc9/zlibvc.vcproj
new file mode 100644
index 0000000..c9a8947
--- /dev/null
+++ b/compat/zlib/contrib/vstudio/vc9/zlibvc.vcproj
@@ -0,0 +1,1156 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="9,00"
+	Name="zlibvc"
+	ProjectGUID="{8FD826F8-3739-44E6-8CC8-997122E53B8D}"
+	RootNamespace="zlibvc"
+	TargetFrameworkVersion="131072"
+	>
+	<Platforms>
+		<Platform
+			Name="Win32"
+		/>
+		<Platform
+			Name="x64"
+		/>
+		<Platform
+			Name="Itanium"
+		/>
+	</Platforms>
+	<ToolFiles>
+	</ToolFiles>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="x86\ZlibDll$(ConfigurationName)"
+			IntermediateDirectory="x86\ZlibDll$(ConfigurationName)\Tmp"
+			ConfigurationType="2"
+			InheritedPropertySheets="UpgradeFromVC70.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				PreprocessorDefinitions="_DEBUG"
+				MkTypLibCompatible="true"
+				SuppressStartupBanner="true"
+				TargetEnvironment="1"
+				TypeLibraryName="$(OutDir)/zlibvc.tlb"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="..\..\..;..\..\masmx86"
+				PreprocessorDefinitions="WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;ASMV;ASMINF"
+				ExceptionHandling="0"
+				RuntimeLibrary="1"
+				BufferSecurityCheck="false"
+				PrecompiledHeaderFile="$(IntDir)/zlibvc.pch"
+				AssemblerListingLocation="$(IntDir)\"
+				ObjectFile="$(IntDir)\"
+				ProgramDataBaseFileName="$(OutDir)\"
+				BrowseInformation="0"
+				WarningLevel="3"
+				SuppressStartupBanner="true"
+				DebugInformationFormat="4"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+				PreprocessorDefinitions="_DEBUG"
+				Culture="1036"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalOptions="/MACHINE:I386"
+				AdditionalDependencies="..\..\masmx86\match686.obj ..\..\masmx86\inffas32.obj"
+				OutputFile="$(OutDir)\zlibwapi.dll"
+				LinkIncremental="2"
+				SuppressStartupBanner="true"
+				GenerateManifest="false"
+				ModuleDefinitionFile=".\zlibvc.def"
+				GenerateDebugInformation="true"
+				ProgramDatabaseFile="$(OutDir)/zlibwapi.pdb"
+				GenerateMapFile="true"
+				MapFileName="$(OutDir)/zlibwapi.map"
+				SubSystem="2"
+				RandomizedBaseAddress="1"
+				DataExecutionPrevention="0"
+				ImportLibrary="$(OutDir)/zlibwapi.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|x64"
+			OutputDirectory="x64\ZlibDll$(ConfigurationName)"
+			IntermediateDirectory="x64\ZlibDll$(ConfigurationName)\Tmp"
+			ConfigurationType="2"
+			InheritedPropertySheets="UpgradeFromVC70.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				PreprocessorDefinitions="_DEBUG"
+				MkTypLibCompatible="true"
+				SuppressStartupBanner="true"
+				TargetEnvironment="3"
+				TypeLibraryName="$(OutDir)/zlibvc.tlb"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="..\..\..;..\..\masmx86"
+				PreprocessorDefinitions="WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;ASMV;ASMINF;WIN64"
+				ExceptionHandling="0"
+				RuntimeLibrary="3"
+				BufferSecurityCheck="false"
+				PrecompiledHeaderFile="$(IntDir)/zlibvc.pch"
+				AssemblerListingLocation="$(IntDir)\"
+				ObjectFile="$(IntDir)\"
+				ProgramDataBaseFileName="$(OutDir)\"
+				BrowseInformation="0"
+				WarningLevel="3"
+				SuppressStartupBanner="true"
+				DebugInformationFormat="3"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+				PreprocessorDefinitions="_DEBUG"
+				Culture="1036"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="..\..\masmx64\gvmat64.obj ..\..\masmx64\inffasx64.obj "
+				OutputFile="$(OutDir)\zlibwapi.dll"
+				LinkIncremental="2"
+				SuppressStartupBanner="true"
+				GenerateManifest="false"
+				ModuleDefinitionFile=".\zlibvc.def"
+				GenerateDebugInformation="true"
+				ProgramDatabaseFile="$(OutDir)/zlibwapi.pdb"
+				GenerateMapFile="true"
+				MapFileName="$(OutDir)/zlibwapi.map"
+				SubSystem="2"
+				ImportLibrary="$(OutDir)/zlibwapi.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|Itanium"
+			OutputDirectory="ia64\ZlibDll$(ConfigurationName)"
+			IntermediateDirectory="ia64\ZlibDll$(ConfigurationName)\Tmp"
+			ConfigurationType="2"
+			InheritedPropertySheets="UpgradeFromVC70.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				PreprocessorDefinitions="_DEBUG"
+				MkTypLibCompatible="true"
+				SuppressStartupBanner="true"
+				TargetEnvironment="2"
+				TypeLibraryName="$(OutDir)/zlibvc.tlb"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="..\..\..;..\..\masmx86"
+				PreprocessorDefinitions="WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;WIN64"
+				ExceptionHandling="0"
+				RuntimeLibrary="3"
+				BufferSecurityCheck="false"
+				PrecompiledHeaderFile="$(IntDir)/zlibvc.pch"
+				AssemblerListingLocation="$(IntDir)\"
+				ObjectFile="$(IntDir)\"
+				ProgramDataBaseFileName="$(OutDir)\"
+				BrowseInformation="0"
+				WarningLevel="3"
+				SuppressStartupBanner="true"
+				DebugInformationFormat="3"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+				PreprocessorDefinitions="_DEBUG"
+				Culture="1036"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				OutputFile="$(OutDir)\zlibwapi.dll"
+				LinkIncremental="2"
+				SuppressStartupBanner="true"
+				GenerateManifest="false"
+				ModuleDefinitionFile=".\zlibvc.def"
+				GenerateDebugInformation="true"
+				ProgramDatabaseFile="$(OutDir)/zlibwapi.pdb"
+				GenerateMapFile="true"
+				MapFileName="$(OutDir)/zlibwapi.map"
+				SubSystem="2"
+				ImportLibrary="$(OutDir)/zlibwapi.lib"
+				TargetMachine="5"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="ReleaseWithoutAsm|Win32"
+			OutputDirectory="x86\ZlibDll$(ConfigurationName)"
+			IntermediateDirectory="x86\ZlibDll$(ConfigurationName)\Tmp"
+			ConfigurationType="2"
+			InheritedPropertySheets="UpgradeFromVC70.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				PreprocessorDefinitions="NDEBUG"
+				MkTypLibCompatible="true"
+				SuppressStartupBanner="true"
+				TargetEnvironment="1"
+				TypeLibraryName="$(OutDir)/zlibvc.tlb"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				InlineFunctionExpansion="1"
+				AdditionalIncludeDirectories="..\..\..;..\..\masmx86"
+				PreprocessorDefinitions="WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI"
+				StringPooling="true"
+				ExceptionHandling="0"
+				RuntimeLibrary="2"
+				BufferSecurityCheck="false"
+				EnableFunctionLevelLinking="true"
+				PrecompiledHeaderFile="$(IntDir)/zlibvc.pch"
+				AssemblerOutput="2"
+				AssemblerListingLocation="$(IntDir)\"
+				ObjectFile="$(IntDir)\"
+				ProgramDataBaseFileName="$(OutDir)\"
+				BrowseInformation="0"
+				WarningLevel="3"
+				SuppressStartupBanner="true"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+				PreprocessorDefinitions="NDEBUG"
+				Culture="1036"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalOptions="/MACHINE:I386"
+				OutputFile="$(OutDir)\zlibwapi.dll"
+				LinkIncremental="1"
+				SuppressStartupBanner="true"
+				GenerateManifest="false"
+				IgnoreAllDefaultLibraries="false"
+				ModuleDefinitionFile=".\zlibvc.def"
+				ProgramDatabaseFile="$(OutDir)/zlibwapi.pdb"
+				GenerateMapFile="true"
+				MapFileName="$(OutDir)/zlibwapi.map"
+				SubSystem="2"
+				OptimizeForWindows98="1"
+				RandomizedBaseAddress="1"
+				DataExecutionPrevention="0"
+				ImportLibrary="$(OutDir)/zlibwapi.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="ReleaseWithoutAsm|x64"
+			OutputDirectory="x64\ZlibDll$(ConfigurationName)"
+			IntermediateDirectory="x64\ZlibDll$(ConfigurationName)\Tmp"
+			ConfigurationType="2"
+			InheritedPropertySheets="UpgradeFromVC70.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				PreprocessorDefinitions="NDEBUG"
+				MkTypLibCompatible="true"
+				SuppressStartupBanner="true"
+				TargetEnvironment="3"
+				TypeLibraryName="$(OutDir)/zlibvc.tlb"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				InlineFunctionExpansion="1"
+				AdditionalIncludeDirectories="..\..\..;..\..\masmx86"
+				PreprocessorDefinitions="WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;WIN64"
+				StringPooling="true"
+				ExceptionHandling="0"
+				RuntimeLibrary="2"
+				BufferSecurityCheck="false"
+				EnableFunctionLevelLinking="true"
+				PrecompiledHeaderFile="$(IntDir)/zlibvc.pch"
+				AssemblerOutput="2"
+				AssemblerListingLocation="$(IntDir)\"
+				ObjectFile="$(IntDir)\"
+				ProgramDataBaseFileName="$(OutDir)\"
+				BrowseInformation="0"
+				WarningLevel="3"
+				SuppressStartupBanner="true"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+				PreprocessorDefinitions="NDEBUG"
+				Culture="1036"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				OutputFile="$(OutDir)\zlibwapi.dll"
+				LinkIncremental="1"
+				SuppressStartupBanner="true"
+				GenerateManifest="false"
+				IgnoreAllDefaultLibraries="false"
+				ModuleDefinitionFile=".\zlibvc.def"
+				ProgramDatabaseFile="$(OutDir)/zlibwapi.pdb"
+				GenerateMapFile="true"
+				MapFileName="$(OutDir)/zlibwapi.map"
+				SubSystem="2"
+				OptimizeForWindows98="1"
+				ImportLibrary="$(OutDir)/zlibwapi.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="ReleaseWithoutAsm|Itanium"
+			OutputDirectory="ia64\ZlibDll$(ConfigurationName)"
+			IntermediateDirectory="ia64\ZlibDll$(ConfigurationName)\Tmp"
+			ConfigurationType="2"
+			InheritedPropertySheets="UpgradeFromVC70.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				PreprocessorDefinitions="NDEBUG"
+				MkTypLibCompatible="true"
+				SuppressStartupBanner="true"
+				TargetEnvironment="2"
+				TypeLibraryName="$(OutDir)/zlibvc.tlb"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				InlineFunctionExpansion="1"
+				AdditionalIncludeDirectories="..\..\..;..\..\masmx86"
+				PreprocessorDefinitions="WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;WIN64"
+				StringPooling="true"
+				ExceptionHandling="0"
+				RuntimeLibrary="2"
+				BufferSecurityCheck="false"
+				EnableFunctionLevelLinking="true"
+				PrecompiledHeaderFile="$(IntDir)/zlibvc.pch"
+				AssemblerOutput="2"
+				AssemblerListingLocation="$(IntDir)\"
+				ObjectFile="$(IntDir)\"
+				ProgramDataBaseFileName="$(OutDir)\"
+				BrowseInformation="0"
+				WarningLevel="3"
+				SuppressStartupBanner="true"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+				PreprocessorDefinitions="NDEBUG"
+				Culture="1036"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				OutputFile="$(OutDir)\zlibwapi.dll"
+				LinkIncremental="1"
+				SuppressStartupBanner="true"
+				GenerateManifest="false"
+				IgnoreAllDefaultLibraries="false"
+				ModuleDefinitionFile=".\zlibvc.def"
+				ProgramDatabaseFile="$(OutDir)/zlibwapi.pdb"
+				GenerateMapFile="true"
+				MapFileName="$(OutDir)/zlibwapi.map"
+				SubSystem="2"
+				OptimizeForWindows98="1"
+				ImportLibrary="$(OutDir)/zlibwapi.lib"
+				TargetMachine="5"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="x86\ZlibDll$(ConfigurationName)"
+			IntermediateDirectory="x86\ZlibDll$(ConfigurationName)\Tmp"
+			ConfigurationType="2"
+			InheritedPropertySheets="UpgradeFromVC70.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				PreprocessorDefinitions="NDEBUG"
+				MkTypLibCompatible="true"
+				SuppressStartupBanner="true"
+				TargetEnvironment="1"
+				TypeLibraryName="$(OutDir)/zlibvc.tlb"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				InlineFunctionExpansion="1"
+				AdditionalIncludeDirectories="..\..\..;..\..\masmx86"
+				PreprocessorDefinitions="WIN32;_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;ASMV;ASMINF"
+				StringPooling="true"
+				ExceptionHandling="0"
+				RuntimeLibrary="0"
+				BufferSecurityCheck="false"
+				EnableFunctionLevelLinking="true"
+				PrecompiledHeaderFile="$(IntDir)/zlibvc.pch"
+				AssemblerOutput="2"
+				AssemblerListingLocation="$(IntDir)\"
+				ObjectFile="$(IntDir)\"
+				ProgramDataBaseFileName="$(OutDir)\"
+				BrowseInformation="0"
+				WarningLevel="3"
+				SuppressStartupBanner="true"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+				PreprocessorDefinitions="NDEBUG"
+				Culture="1036"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalOptions="/MACHINE:I386"
+				AdditionalDependencies="..\..\masmx86\match686.obj ..\..\masmx86\inffas32.obj "
+				OutputFile="$(OutDir)\zlibwapi.dll"
+				LinkIncremental="1"
+				SuppressStartupBanner="true"
+				GenerateManifest="false"
+				IgnoreAllDefaultLibraries="false"
+				ModuleDefinitionFile=".\zlibvc.def"
+				ProgramDatabaseFile="$(OutDir)/zlibwapi.pdb"
+				GenerateMapFile="true"
+				MapFileName="$(OutDir)/zlibwapi.map"
+				SubSystem="2"
+				OptimizeForWindows98="1"
+				RandomizedBaseAddress="1"
+				DataExecutionPrevention="0"
+				ImportLibrary="$(OutDir)/zlibwapi.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="Release|x64"
+			OutputDirectory="x64\ZlibDll$(ConfigurationName)"
+			IntermediateDirectory="x64\ZlibDll$(ConfigurationName)\Tmp"
+			ConfigurationType="2"
+			InheritedPropertySheets="UpgradeFromVC70.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				PreprocessorDefinitions="NDEBUG"
+				MkTypLibCompatible="true"
+				SuppressStartupBanner="true"
+				TargetEnvironment="3"
+				TypeLibraryName="$(OutDir)/zlibvc.tlb"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				InlineFunctionExpansion="1"
+				AdditionalIncludeDirectories="..\..\..;..\..\masmx86"
+				PreprocessorDefinitions="_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;ASMV;ASMINF;WIN64"
+				StringPooling="true"
+				ExceptionHandling="0"
+				RuntimeLibrary="2"
+				BufferSecurityCheck="false"
+				EnableFunctionLevelLinking="true"
+				PrecompiledHeaderFile="$(IntDir)/zlibvc.pch"
+				AssemblerOutput="2"
+				AssemblerListingLocation="$(IntDir)\"
+				ObjectFile="$(IntDir)\"
+				ProgramDataBaseFileName="$(OutDir)\"
+				BrowseInformation="0"
+				WarningLevel="3"
+				SuppressStartupBanner="true"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+				PreprocessorDefinitions="NDEBUG"
+				Culture="1036"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="..\..\masmx64\gvmat64.obj ..\..\masmx64\inffasx64.obj "
+				OutputFile="$(OutDir)\zlibwapi.dll"
+				LinkIncremental="1"
+				SuppressStartupBanner="true"
+				GenerateManifest="false"
+				IgnoreAllDefaultLibraries="false"
+				ModuleDefinitionFile=".\zlibvc.def"
+				ProgramDatabaseFile="$(OutDir)/zlibwapi.pdb"
+				GenerateMapFile="true"
+				MapFileName="$(OutDir)/zlibwapi.map"
+				SubSystem="2"
+				OptimizeForWindows98="1"
+				ImportLibrary="$(OutDir)/zlibwapi.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="Release|Itanium"
+			OutputDirectory="ia64\ZlibDll$(ConfigurationName)"
+			IntermediateDirectory="ia64\ZlibDll$(ConfigurationName)\Tmp"
+			ConfigurationType="2"
+			InheritedPropertySheets="UpgradeFromVC70.vsprops"
+			UseOfMFC="0"
+			ATLMinimizesCRunTimeLibraryUsage="false"
+			WholeProgramOptimization="1"
+			>
+			<Tool
+				Name="VCPreBuildEventTool"
+			/>
+			<Tool
+				Name="VCCustomBuildTool"
+			/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"
+			/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"
+			/>
+			<Tool
+				Name="VCMIDLTool"
+				PreprocessorDefinitions="NDEBUG"
+				MkTypLibCompatible="true"
+				SuppressStartupBanner="true"
+				TargetEnvironment="2"
+				TypeLibraryName="$(OutDir)/zlibvc.tlb"
+			/>
+			<Tool
+				Name="VCCLCompilerTool"
+				InlineFunctionExpansion="1"
+				AdditionalIncludeDirectories="..\..\..;..\..\masmx86"
+				PreprocessorDefinitions="_CRT_NONSTDC_NO_DEPRECATE;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ZLIB_WINAPI;WIN64"
+				StringPooling="true"
+				ExceptionHandling="0"
+				RuntimeLibrary="2"
+				BufferSecurityCheck="false"
+				EnableFunctionLevelLinking="true"
+				PrecompiledHeaderFile="$(IntDir)/zlibvc.pch"
+				AssemblerOutput="2"
+				AssemblerListingLocation="$(IntDir)\"
+				ObjectFile="$(IntDir)\"
+				ProgramDataBaseFileName="$(OutDir)\"
+				BrowseInformation="0"
+				WarningLevel="3"
+				SuppressStartupBanner="true"
+			/>
+			<Tool
+				Name="VCManagedResourceCompilerTool"
+			/>
+			<Tool
+				Name="VCResourceCompilerTool"
+				PreprocessorDefinitions="NDEBUG"
+				Culture="1036"
+			/>
+			<Tool
+				Name="VCPreLinkEventTool"
+			/>
+			<Tool
+				Name="VCLinkerTool"
+				OutputFile="$(OutDir)\zlibwapi.dll"
+				LinkIncremental="1"
+				SuppressStartupBanner="true"
+				GenerateManifest="false"
+				IgnoreAllDefaultLibraries="false"
+				ModuleDefinitionFile=".\zlibvc.def"
+				ProgramDatabaseFile="$(OutDir)/zlibwapi.pdb"
+				GenerateMapFile="true"
+				MapFileName="$(OutDir)/zlibwapi.map"
+				SubSystem="2"
+				OptimizeForWindows98="1"
+				ImportLibrary="$(OutDir)/zlibwapi.lib"
+				TargetMachine="5"
+			/>
+			<Tool
+				Name="VCALinkTool"
+			/>
+			<Tool
+				Name="VCManifestTool"
+			/>
+			<Tool
+				Name="VCXDCMakeTool"
+			/>
+			<Tool
+				Name="VCBscMakeTool"
+			/>
+			<Tool
+				Name="VCFxCopTool"
+			/>
+			<Tool
+				Name="VCAppVerifierTool"
+			/>
+			<Tool
+				Name="VCPostBuildEventTool"
+			/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Source Files"
+			Filter="cpp;c;cxx;rc;def;r;odl;hpj;bat;for;f90"
+			>
+			<File
+				RelativePath="..\..\..\adler32.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\compress.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\crc32.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\deflate.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\gzclose.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\gzguts.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\gzlib.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\gzread.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\gzwrite.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\infback.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\masmx64\inffas8664.c"
+				>
+				<FileConfiguration
+					Name="Debug|Win32"
+					ExcludedFromBuild="true"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Debug|Itanium"
+					ExcludedFromBuild="true"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="ReleaseWithoutAsm|Win32"
+					ExcludedFromBuild="true"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="ReleaseWithoutAsm|Itanium"
+					ExcludedFromBuild="true"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|Win32"
+					ExcludedFromBuild="true"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|Itanium"
+					ExcludedFromBuild="true"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath="..\..\..\inffast.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\inflate.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\inftrees.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\minizip\ioapi.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\minizip\iowin32.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\trees.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\uncompr.c"
+				>
+			</File>
+			<File
+				RelativePath="..\..\minizip\unzip.c"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions="ZLIB_INTERNAL"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions="ZLIB_INTERNAL"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|Itanium"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions="ZLIB_INTERNAL"
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath="..\..\minizip\zip.c"
+				>
+				<FileConfiguration
+					Name="Release|Win32"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions="ZLIB_INTERNAL"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|x64"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions="ZLIB_INTERNAL"
+					/>
+				</FileConfiguration>
+				<FileConfiguration
+					Name="Release|Itanium"
+					>
+					<Tool
+						Name="VCCLCompilerTool"
+						AdditionalIncludeDirectories=""
+						PreprocessorDefinitions="ZLIB_INTERNAL"
+					/>
+				</FileConfiguration>
+			</File>
+			<File
+				RelativePath=".\zlib.rc"
+				>
+			</File>
+			<File
+				RelativePath=".\zlibvc.def"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\zutil.c"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="Header Files"
+			Filter="h;hpp;hxx;hm;inl;fi;fd"
+			>
+			<File
+				RelativePath="..\..\..\deflate.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\infblock.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\infcodes.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\inffast.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\inftrees.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\infutil.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\zconf.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\zlib.h"
+				>
+			</File>
+			<File
+				RelativePath="..\..\..\zutil.h"
+				>
+			</File>
+		</Filter>
+		<Filter
+			Name="Resource Files"
+			Filter="ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe"
+			>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
diff --git a/compat/zlib/crc32.c b/compat/zlib/crc32.c
new file mode 100644
index 0000000..979a719
--- /dev/null
+++ b/compat/zlib/crc32.c
@@ -0,0 +1,425 @@
+/* crc32.c -- compute the CRC-32 of a data stream
+ * Copyright (C) 1995-2006, 2010, 2011, 2012 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ *
+ * Thanks to Rodney Brown <rbrown64@csc.com.au> for his contribution of faster
+ * CRC methods: exclusive-oring 32 bits of data at a time, and pre-computing
+ * tables for updating the shift register in one step with three exclusive-ors
+ * instead of four steps with four exclusive-ors.  This results in about a
+ * factor of two increase in speed on a Power PC G4 (PPC7455) using gcc -O3.
+ */
+
+/* @(#) $Id$ */
+
+/*
+  Note on the use of DYNAMIC_CRC_TABLE: there is no mutex or semaphore
+  protection on the static variables used to control the first-use generation
+  of the crc tables.  Therefore, if you #define DYNAMIC_CRC_TABLE, you should
+  first call get_crc_table() to initialize the tables before allowing more than
+  one thread to use crc32().
+
+  DYNAMIC_CRC_TABLE and MAKECRCH can be #defined to write out crc32.h.
+ */
+
+#ifdef MAKECRCH
+#  include <stdio.h>
+#  ifndef DYNAMIC_CRC_TABLE
+#    define DYNAMIC_CRC_TABLE
+#  endif /* !DYNAMIC_CRC_TABLE */
+#endif /* MAKECRCH */
+
+#include "zutil.h"      /* for STDC and FAR definitions */
+
+#define local static
+
+/* Definitions for doing the crc four data bytes at a time. */
+#if !defined(NOBYFOUR) && defined(Z_U4)
+#  define BYFOUR
+#endif
+#ifdef BYFOUR
+   local unsigned long crc32_little OF((unsigned long,
+                        const unsigned char FAR *, unsigned));
+   local unsigned long crc32_big OF((unsigned long,
+                        const unsigned char FAR *, unsigned));
+#  define TBLS 8
+#else
+#  define TBLS 1
+#endif /* BYFOUR */
+
+/* Local functions for crc concatenation */
+local unsigned long gf2_matrix_times OF((unsigned long *mat,
+                                         unsigned long vec));
+local void gf2_matrix_square OF((unsigned long *square, unsigned long *mat));
+local uLong crc32_combine_ OF((uLong crc1, uLong crc2, z_off64_t len2));
+
+
+#ifdef DYNAMIC_CRC_TABLE
+
+local volatile int crc_table_empty = 1;
+local z_crc_t FAR crc_table[TBLS][256];
+local void make_crc_table OF((void));
+#ifdef MAKECRCH
+   local void write_table OF((FILE *, const z_crc_t FAR *));
+#endif /* MAKECRCH */
+/*
+  Generate tables for a byte-wise 32-bit CRC calculation on the polynomial:
+  x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1.
+
+  Polynomials over GF(2) are represented in binary, one bit per coefficient,
+  with the lowest powers in the most significant bit.  Then adding polynomials
+  is just exclusive-or, and multiplying a polynomial by x is a right shift by
+  one.  If we call the above polynomial p, and represent a byte as the
+  polynomial q, also with the lowest power in the most significant bit (so the
+  byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p,
+  where a mod b means the remainder after dividing a by b.
+
+  This calculation is done using the shift-register method of multiplying and
+  taking the remainder.  The register is initialized to zero, and for each
+  incoming bit, x^32 is added mod p to the register if the bit is a one (where
+  x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by
+  x (which is shifting right by one and adding x^32 mod p if the bit shifted
+  out is a one).  We start with the highest power (least significant bit) of
+  q and repeat for all eight bits of q.
+
+  The first table is simply the CRC of all possible eight bit values.  This is
+  all the information needed to generate CRCs on data a byte at a time for all
+  combinations of CRC register values and incoming bytes.  The remaining tables
+  allow for word-at-a-time CRC calculation for both big-endian and little-
+  endian machines, where a word is four bytes.
+*/
+local void make_crc_table()
+{
+    z_crc_t c;
+    int n, k;
+    z_crc_t poly;                       /* polynomial exclusive-or pattern */
+    /* terms of polynomial defining this crc (except x^32): */
+    static volatile int first = 1;      /* flag to limit concurrent making */
+    static const unsigned char p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26};
+
+    /* See if another task is already doing this (not thread-safe, but better
+       than nothing -- significantly reduces duration of vulnerability in
+       case the advice about DYNAMIC_CRC_TABLE is ignored) */
+    if (first) {
+        first = 0;
+
+        /* make exclusive-or pattern from polynomial (0xedb88320UL) */
+        poly = 0;
+        for (n = 0; n < (int)(sizeof(p)/sizeof(unsigned char)); n++)
+            poly |= (z_crc_t)1 << (31 - p[n]);
+
+        /* generate a crc for every 8-bit value */
+        for (n = 0; n < 256; n++) {
+            c = (z_crc_t)n;
+            for (k = 0; k < 8; k++)
+                c = c & 1 ? poly ^ (c >> 1) : c >> 1;
+            crc_table[0][n] = c;
+        }
+
+#ifdef BYFOUR
+        /* generate crc for each value followed by one, two, and three zeros,
+           and then the byte reversal of those as well as the first table */
+        for (n = 0; n < 256; n++) {
+            c = crc_table[0][n];
+            crc_table[4][n] = ZSWAP32(c);
+            for (k = 1; k < 4; k++) {
+                c = crc_table[0][c & 0xff] ^ (c >> 8);
+                crc_table[k][n] = c;
+                crc_table[k + 4][n] = ZSWAP32(c);
+            }
+        }
+#endif /* BYFOUR */
+
+        crc_table_empty = 0;
+    }
+    else {      /* not first */
+        /* wait for the other guy to finish (not efficient, but rare) */
+        while (crc_table_empty)
+            ;
+    }
+
+#ifdef MAKECRCH
+    /* write out CRC tables to crc32.h */
+    {
+        FILE *out;
+
+        out = fopen("crc32.h", "w");
+        if (out == NULL) return;
+        fprintf(out, "/* crc32.h -- tables for rapid CRC calculation\n");
+        fprintf(out, " * Generated automatically by crc32.c\n */\n\n");
+        fprintf(out, "local const z_crc_t FAR ");
+        fprintf(out, "crc_table[TBLS][256] =\n{\n  {\n");
+        write_table(out, crc_table[0]);
+#  ifdef BYFOUR
+        fprintf(out, "#ifdef BYFOUR\n");
+        for (k = 1; k < 8; k++) {
+            fprintf(out, "  },\n  {\n");
+            write_table(out, crc_table[k]);
+        }
+        fprintf(out, "#endif\n");
+#  endif /* BYFOUR */
+        fprintf(out, "  }\n};\n");
+        fclose(out);
+    }
+#endif /* MAKECRCH */
+}
+
+#ifdef MAKECRCH
+local void write_table(out, table)
+    FILE *out;
+    const z_crc_t FAR *table;
+{
+    int n;
+
+    for (n = 0; n < 256; n++)
+        fprintf(out, "%s0x%08lxUL%s", n % 5 ? "" : "    ",
+                (unsigned long)(table[n]),
+                n == 255 ? "\n" : (n % 5 == 4 ? ",\n" : ", "));
+}
+#endif /* MAKECRCH */
+
+#else /* !DYNAMIC_CRC_TABLE */
+/* ========================================================================
+ * Tables of CRC-32s of all single-byte values, made by make_crc_table().
+ */
+#include "crc32.h"
+#endif /* DYNAMIC_CRC_TABLE */
+
+/* =========================================================================
+ * This function can be used by asm versions of crc32()
+ */
+const z_crc_t FAR * ZEXPORT get_crc_table()
+{
+#ifdef DYNAMIC_CRC_TABLE
+    if (crc_table_empty)
+        make_crc_table();
+#endif /* DYNAMIC_CRC_TABLE */
+    return (const z_crc_t FAR *)crc_table;
+}
+
+/* ========================================================================= */
+#define DO1 crc = crc_table[0][((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8)
+#define DO8 DO1; DO1; DO1; DO1; DO1; DO1; DO1; DO1
+
+/* ========================================================================= */
+unsigned long ZEXPORT crc32(crc, buf, len)
+    unsigned long crc;
+    const unsigned char FAR *buf;
+    uInt len;
+{
+    if (buf == Z_NULL) return 0UL;
+
+#ifdef DYNAMIC_CRC_TABLE
+    if (crc_table_empty)
+        make_crc_table();
+#endif /* DYNAMIC_CRC_TABLE */
+
+#ifdef BYFOUR
+    if (sizeof(void *) == sizeof(ptrdiff_t)) {
+        z_crc_t endian;
+
+        endian = 1;
+        if (*((unsigned char *)(&endian)))
+            return crc32_little(crc, buf, len);
+        else
+            return crc32_big(crc, buf, len);
+    }
+#endif /* BYFOUR */
+    crc = crc ^ 0xffffffffUL;
+    while (len >= 8) {
+        DO8;
+        len -= 8;
+    }
+    if (len) do {
+        DO1;
+    } while (--len);
+    return crc ^ 0xffffffffUL;
+}
+
+#ifdef BYFOUR
+
+/* ========================================================================= */
+#define DOLIT4 c ^= *buf4++; \
+        c = crc_table[3][c & 0xff] ^ crc_table[2][(c >> 8) & 0xff] ^ \
+            crc_table[1][(c >> 16) & 0xff] ^ crc_table[0][c >> 24]
+#define DOLIT32 DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4
+
+/* ========================================================================= */
+local unsigned long crc32_little(crc, buf, len)
+    unsigned long crc;
+    const unsigned char FAR *buf;
+    unsigned len;
+{
+    register z_crc_t c;
+    register const z_crc_t FAR *buf4;
+
+    c = (z_crc_t)crc;
+    c = ~c;
+    while (len && ((ptrdiff_t)buf & 3)) {
+        c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8);
+        len--;
+    }
+
+    buf4 = (const z_crc_t FAR *)(const void FAR *)buf;
+    while (len >= 32) {
+        DOLIT32;
+        len -= 32;
+    }
+    while (len >= 4) {
+        DOLIT4;
+        len -= 4;
+    }
+    buf = (const unsigned char FAR *)buf4;
+
+    if (len) do {
+        c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8);
+    } while (--len);
+    c = ~c;
+    return (unsigned long)c;
+}
+
+/* ========================================================================= */
+#define DOBIG4 c ^= *++buf4; \
+        c = crc_table[4][c & 0xff] ^ crc_table[5][(c >> 8) & 0xff] ^ \
+            crc_table[6][(c >> 16) & 0xff] ^ crc_table[7][c >> 24]
+#define DOBIG32 DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4
+
+/* ========================================================================= */
+local unsigned long crc32_big(crc, buf, len)
+    unsigned long crc;
+    const unsigned char FAR *buf;
+    unsigned len;
+{
+    register z_crc_t c;
+    register const z_crc_t FAR *buf4;
+
+    c = ZSWAP32((z_crc_t)crc);
+    c = ~c;
+    while (len && ((ptrdiff_t)buf & 3)) {
+        c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
+        len--;
+    }
+
+    buf4 = (const z_crc_t FAR *)(const void FAR *)buf;
+    buf4--;
+    while (len >= 32) {
+        DOBIG32;
+        len -= 32;
+    }
+    while (len >= 4) {
+        DOBIG4;
+        len -= 4;
+    }
+    buf4++;
+    buf = (const unsigned char FAR *)buf4;
+
+    if (len) do {
+        c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
+    } while (--len);
+    c = ~c;
+    return (unsigned long)(ZSWAP32(c));
+}
+
+#endif /* BYFOUR */
+
+#define GF2_DIM 32      /* dimension of GF(2) vectors (length of CRC) */
+
+/* ========================================================================= */
+local unsigned long gf2_matrix_times(mat, vec)
+    unsigned long *mat;
+    unsigned long vec;
+{
+    unsigned long sum;
+
+    sum = 0;
+    while (vec) {
+        if (vec & 1)
+            sum ^= *mat;
+        vec >>= 1;
+        mat++;
+    }
+    return sum;
+}
+
+/* ========================================================================= */
+local void gf2_matrix_square(square, mat)
+    unsigned long *square;
+    unsigned long *mat;
+{
+    int n;
+
+    for (n = 0; n < GF2_DIM; n++)
+        square[n] = gf2_matrix_times(mat, mat[n]);
+}
+
+/* ========================================================================= */
+local uLong crc32_combine_(crc1, crc2, len2)
+    uLong crc1;
+    uLong crc2;
+    z_off64_t len2;
+{
+    int n;
+    unsigned long row;
+    unsigned long even[GF2_DIM];    /* even-power-of-two zeros operator */
+    unsigned long odd[GF2_DIM];     /* odd-power-of-two zeros operator */
+
+    /* degenerate case (also disallow negative lengths) */
+    if (len2 <= 0)
+        return crc1;
+
+    /* put operator for one zero bit in odd */
+    odd[0] = 0xedb88320UL;          /* CRC-32 polynomial */
+    row = 1;
+    for (n = 1; n < GF2_DIM; n++) {
+        odd[n] = row;
+        row <<= 1;
+    }
+
+    /* put operator for two zero bits in even */
+    gf2_matrix_square(even, odd);
+
+    /* put operator for four zero bits in odd */
+    gf2_matrix_square(odd, even);
+
+    /* apply len2 zeros to crc1 (first square will put the operator for one
+       zero byte, eight zero bits, in even) */
+    do {
+        /* apply zeros operator for this bit of len2 */
+        gf2_matrix_square(even, odd);
+        if (len2 & 1)
+            crc1 = gf2_matrix_times(even, crc1);
+        len2 >>= 1;
+
+        /* if no more bits set, then done */
+        if (len2 == 0)
+            break;
+
+        /* another iteration of the loop with odd and even swapped */
+        gf2_matrix_square(odd, even);
+        if (len2 & 1)
+            crc1 = gf2_matrix_times(odd, crc1);
+        len2 >>= 1;
+
+        /* if no more bits set, then done */
+    } while (len2 != 0);
+
+    /* return combined crc */
+    crc1 ^= crc2;
+    return crc1;
+}
+
+/* ========================================================================= */
+uLong ZEXPORT crc32_combine(crc1, crc2, len2)
+    uLong crc1;
+    uLong crc2;
+    z_off_t len2;
+{
+    return crc32_combine_(crc1, crc2, len2);
+}
+
+uLong ZEXPORT crc32_combine64(crc1, crc2, len2)
+    uLong crc1;
+    uLong crc2;
+    z_off64_t len2;
+{
+    return crc32_combine_(crc1, crc2, len2);
+}
diff --git a/compat/zlib/crc32.h b/compat/zlib/crc32.h
new file mode 100644
index 0000000..9e0c778
--- /dev/null
+++ b/compat/zlib/crc32.h
@@ -0,0 +1,441 @@
+/* crc32.h -- tables for rapid CRC calculation
+ * Generated automatically by crc32.c
+ */
+
+local const z_crc_t FAR crc_table[TBLS][256] =
+{
+  {
+    0x00000000UL, 0x77073096UL, 0xee0e612cUL, 0x990951baUL, 0x076dc419UL,
+    0x706af48fUL, 0xe963a535UL, 0x9e6495a3UL, 0x0edb8832UL, 0x79dcb8a4UL,
+    0xe0d5e91eUL, 0x97d2d988UL, 0x09b64c2bUL, 0x7eb17cbdUL, 0xe7b82d07UL,
+    0x90bf1d91UL, 0x1db71064UL, 0x6ab020f2UL, 0xf3b97148UL, 0x84be41deUL,
+    0x1adad47dUL, 0x6ddde4ebUL, 0xf4d4b551UL, 0x83d385c7UL, 0x136c9856UL,
+    0x646ba8c0UL, 0xfd62f97aUL, 0x8a65c9ecUL, 0x14015c4fUL, 0x63066cd9UL,
+    0xfa0f3d63UL, 0x8d080df5UL, 0x3b6e20c8UL, 0x4c69105eUL, 0xd56041e4UL,
+    0xa2677172UL, 0x3c03e4d1UL, 0x4b04d447UL, 0xd20d85fdUL, 0xa50ab56bUL,
+    0x35b5a8faUL, 0x42b2986cUL, 0xdbbbc9d6UL, 0xacbcf940UL, 0x32d86ce3UL,
+    0x45df5c75UL, 0xdcd60dcfUL, 0xabd13d59UL, 0x26d930acUL, 0x51de003aUL,
+    0xc8d75180UL, 0xbfd06116UL, 0x21b4f4b5UL, 0x56b3c423UL, 0xcfba9599UL,
+    0xb8bda50fUL, 0x2802b89eUL, 0x5f058808UL, 0xc60cd9b2UL, 0xb10be924UL,
+    0x2f6f7c87UL, 0x58684c11UL, 0xc1611dabUL, 0xb6662d3dUL, 0x76dc4190UL,
+    0x01db7106UL, 0x98d220bcUL, 0xefd5102aUL, 0x71b18589UL, 0x06b6b51fUL,
+    0x9fbfe4a5UL, 0xe8b8d433UL, 0x7807c9a2UL, 0x0f00f934UL, 0x9609a88eUL,
+    0xe10e9818UL, 0x7f6a0dbbUL, 0x086d3d2dUL, 0x91646c97UL, 0xe6635c01UL,
+    0x6b6b51f4UL, 0x1c6c6162UL, 0x856530d8UL, 0xf262004eUL, 0x6c0695edUL,
+    0x1b01a57bUL, 0x8208f4c1UL, 0xf50fc457UL, 0x65b0d9c6UL, 0x12b7e950UL,
+    0x8bbeb8eaUL, 0xfcb9887cUL, 0x62dd1ddfUL, 0x15da2d49UL, 0x8cd37cf3UL,
+    0xfbd44c65UL, 0x4db26158UL, 0x3ab551ceUL, 0xa3bc0074UL, 0xd4bb30e2UL,
+    0x4adfa541UL, 0x3dd895d7UL, 0xa4d1c46dUL, 0xd3d6f4fbUL, 0x4369e96aUL,
+    0x346ed9fcUL, 0xad678846UL, 0xda60b8d0UL, 0x44042d73UL, 0x33031de5UL,
+    0xaa0a4c5fUL, 0xdd0d7cc9UL, 0x5005713cUL, 0x270241aaUL, 0xbe0b1010UL,
+    0xc90c2086UL, 0x5768b525UL, 0x206f85b3UL, 0xb966d409UL, 0xce61e49fUL,
+    0x5edef90eUL, 0x29d9c998UL, 0xb0d09822UL, 0xc7d7a8b4UL, 0x59b33d17UL,
+    0x2eb40d81UL, 0xb7bd5c3bUL, 0xc0ba6cadUL, 0xedb88320UL, 0x9abfb3b6UL,
+    0x03b6e20cUL, 0x74b1d29aUL, 0xead54739UL, 0x9dd277afUL, 0x04db2615UL,
+    0x73dc1683UL, 0xe3630b12UL, 0x94643b84UL, 0x0d6d6a3eUL, 0x7a6a5aa8UL,
+    0xe40ecf0bUL, 0x9309ff9dUL, 0x0a00ae27UL, 0x7d079eb1UL, 0xf00f9344UL,
+    0x8708a3d2UL, 0x1e01f268UL, 0x6906c2feUL, 0xf762575dUL, 0x806567cbUL,
+    0x196c3671UL, 0x6e6b06e7UL, 0xfed41b76UL, 0x89d32be0UL, 0x10da7a5aUL,
+    0x67dd4accUL, 0xf9b9df6fUL, 0x8ebeeff9UL, 0x17b7be43UL, 0x60b08ed5UL,
+    0xd6d6a3e8UL, 0xa1d1937eUL, 0x38d8c2c4UL, 0x4fdff252UL, 0xd1bb67f1UL,
+    0xa6bc5767UL, 0x3fb506ddUL, 0x48b2364bUL, 0xd80d2bdaUL, 0xaf0a1b4cUL,
+    0x36034af6UL, 0x41047a60UL, 0xdf60efc3UL, 0xa867df55UL, 0x316e8eefUL,
+    0x4669be79UL, 0xcb61b38cUL, 0xbc66831aUL, 0x256fd2a0UL, 0x5268e236UL,
+    0xcc0c7795UL, 0xbb0b4703UL, 0x220216b9UL, 0x5505262fUL, 0xc5ba3bbeUL,
+    0xb2bd0b28UL, 0x2bb45a92UL, 0x5cb36a04UL, 0xc2d7ffa7UL, 0xb5d0cf31UL,
+    0x2cd99e8bUL, 0x5bdeae1dUL, 0x9b64c2b0UL, 0xec63f226UL, 0x756aa39cUL,
+    0x026d930aUL, 0x9c0906a9UL, 0xeb0e363fUL, 0x72076785UL, 0x05005713UL,
+    0x95bf4a82UL, 0xe2b87a14UL, 0x7bb12baeUL, 0x0cb61b38UL, 0x92d28e9bUL,
+    0xe5d5be0dUL, 0x7cdcefb7UL, 0x0bdbdf21UL, 0x86d3d2d4UL, 0xf1d4e242UL,
+    0x68ddb3f8UL, 0x1fda836eUL, 0x81be16cdUL, 0xf6b9265bUL, 0x6fb077e1UL,
+    0x18b74777UL, 0x88085ae6UL, 0xff0f6a70UL, 0x66063bcaUL, 0x11010b5cUL,
+    0x8f659effUL, 0xf862ae69UL, 0x616bffd3UL, 0x166ccf45UL, 0xa00ae278UL,
+    0xd70dd2eeUL, 0x4e048354UL, 0x3903b3c2UL, 0xa7672661UL, 0xd06016f7UL,
+    0x4969474dUL, 0x3e6e77dbUL, 0xaed16a4aUL, 0xd9d65adcUL, 0x40df0b66UL,
+    0x37d83bf0UL, 0xa9bcae53UL, 0xdebb9ec5UL, 0x47b2cf7fUL, 0x30b5ffe9UL,
+    0xbdbdf21cUL, 0xcabac28aUL, 0x53b39330UL, 0x24b4a3a6UL, 0xbad03605UL,
+    0xcdd70693UL, 0x54de5729UL, 0x23d967bfUL, 0xb3667a2eUL, 0xc4614ab8UL,
+    0x5d681b02UL, 0x2a6f2b94UL, 0xb40bbe37UL, 0xc30c8ea1UL, 0x5a05df1bUL,
+    0x2d02ef8dUL
+#ifdef BYFOUR
+  },
+  {
+    0x00000000UL, 0x191b3141UL, 0x32366282UL, 0x2b2d53c3UL, 0x646cc504UL,
+    0x7d77f445UL, 0x565aa786UL, 0x4f4196c7UL, 0xc8d98a08UL, 0xd1c2bb49UL,
+    0xfaefe88aUL, 0xe3f4d9cbUL, 0xacb54f0cUL, 0xb5ae7e4dUL, 0x9e832d8eUL,
+    0x87981ccfUL, 0x4ac21251UL, 0x53d92310UL, 0x78f470d3UL, 0x61ef4192UL,
+    0x2eaed755UL, 0x37b5e614UL, 0x1c98b5d7UL, 0x05838496UL, 0x821b9859UL,
+    0x9b00a918UL, 0xb02dfadbUL, 0xa936cb9aUL, 0xe6775d5dUL, 0xff6c6c1cUL,
+    0xd4413fdfUL, 0xcd5a0e9eUL, 0x958424a2UL, 0x8c9f15e3UL, 0xa7b24620UL,
+    0xbea97761UL, 0xf1e8e1a6UL, 0xe8f3d0e7UL, 0xc3de8324UL, 0xdac5b265UL,
+    0x5d5daeaaUL, 0x44469febUL, 0x6f6bcc28UL, 0x7670fd69UL, 0x39316baeUL,
+    0x202a5aefUL, 0x0b07092cUL, 0x121c386dUL, 0xdf4636f3UL, 0xc65d07b2UL,
+    0xed705471UL, 0xf46b6530UL, 0xbb2af3f7UL, 0xa231c2b6UL, 0x891c9175UL,
+    0x9007a034UL, 0x179fbcfbUL, 0x0e848dbaUL, 0x25a9de79UL, 0x3cb2ef38UL,
+    0x73f379ffUL, 0x6ae848beUL, 0x41c51b7dUL, 0x58de2a3cUL, 0xf0794f05UL,
+    0xe9627e44UL, 0xc24f2d87UL, 0xdb541cc6UL, 0x94158a01UL, 0x8d0ebb40UL,
+    0xa623e883UL, 0xbf38d9c2UL, 0x38a0c50dUL, 0x21bbf44cUL, 0x0a96a78fUL,
+    0x138d96ceUL, 0x5ccc0009UL, 0x45d73148UL, 0x6efa628bUL, 0x77e153caUL,
+    0xbabb5d54UL, 0xa3a06c15UL, 0x888d3fd6UL, 0x91960e97UL, 0xded79850UL,
+    0xc7cca911UL, 0xece1fad2UL, 0xf5facb93UL, 0x7262d75cUL, 0x6b79e61dUL,
+    0x4054b5deUL, 0x594f849fUL, 0x160e1258UL, 0x0f152319UL, 0x243870daUL,
+    0x3d23419bUL, 0x65fd6ba7UL, 0x7ce65ae6UL, 0x57cb0925UL, 0x4ed03864UL,
+    0x0191aea3UL, 0x188a9fe2UL, 0x33a7cc21UL, 0x2abcfd60UL, 0xad24e1afUL,
+    0xb43fd0eeUL, 0x9f12832dUL, 0x8609b26cUL, 0xc94824abUL, 0xd05315eaUL,
+    0xfb7e4629UL, 0xe2657768UL, 0x2f3f79f6UL, 0x362448b7UL, 0x1d091b74UL,
+    0x04122a35UL, 0x4b53bcf2UL, 0x52488db3UL, 0x7965de70UL, 0x607eef31UL,
+    0xe7e6f3feUL, 0xfefdc2bfUL, 0xd5d0917cUL, 0xcccba03dUL, 0x838a36faUL,
+    0x9a9107bbUL, 0xb1bc5478UL, 0xa8a76539UL, 0x3b83984bUL, 0x2298a90aUL,
+    0x09b5fac9UL, 0x10aecb88UL, 0x5fef5d4fUL, 0x46f46c0eUL, 0x6dd93fcdUL,
+    0x74c20e8cUL, 0xf35a1243UL, 0xea412302UL, 0xc16c70c1UL, 0xd8774180UL,
+    0x9736d747UL, 0x8e2de606UL, 0xa500b5c5UL, 0xbc1b8484UL, 0x71418a1aUL,
+    0x685abb5bUL, 0x4377e898UL, 0x5a6cd9d9UL, 0x152d4f1eUL, 0x0c367e5fUL,
+    0x271b2d9cUL, 0x3e001cddUL, 0xb9980012UL, 0xa0833153UL, 0x8bae6290UL,
+    0x92b553d1UL, 0xddf4c516UL, 0xc4eff457UL, 0xefc2a794UL, 0xf6d996d5UL,
+    0xae07bce9UL, 0xb71c8da8UL, 0x9c31de6bUL, 0x852aef2aUL, 0xca6b79edUL,
+    0xd37048acUL, 0xf85d1b6fUL, 0xe1462a2eUL, 0x66de36e1UL, 0x7fc507a0UL,
+    0x54e85463UL, 0x4df36522UL, 0x02b2f3e5UL, 0x1ba9c2a4UL, 0x30849167UL,
+    0x299fa026UL, 0xe4c5aeb8UL, 0xfdde9ff9UL, 0xd6f3cc3aUL, 0xcfe8fd7bUL,
+    0x80a96bbcUL, 0x99b25afdUL, 0xb29f093eUL, 0xab84387fUL, 0x2c1c24b0UL,
+    0x350715f1UL, 0x1e2a4632UL, 0x07317773UL, 0x4870e1b4UL, 0x516bd0f5UL,
+    0x7a468336UL, 0x635db277UL, 0xcbfad74eUL, 0xd2e1e60fUL, 0xf9ccb5ccUL,
+    0xe0d7848dUL, 0xaf96124aUL, 0xb68d230bUL, 0x9da070c8UL, 0x84bb4189UL,
+    0x03235d46UL, 0x1a386c07UL, 0x31153fc4UL, 0x280e0e85UL, 0x674f9842UL,
+    0x7e54a903UL, 0x5579fac0UL, 0x4c62cb81UL, 0x8138c51fUL, 0x9823f45eUL,
+    0xb30ea79dUL, 0xaa1596dcUL, 0xe554001bUL, 0xfc4f315aUL, 0xd7626299UL,
+    0xce7953d8UL, 0x49e14f17UL, 0x50fa7e56UL, 0x7bd72d95UL, 0x62cc1cd4UL,
+    0x2d8d8a13UL, 0x3496bb52UL, 0x1fbbe891UL, 0x06a0d9d0UL, 0x5e7ef3ecUL,
+    0x4765c2adUL, 0x6c48916eUL, 0x7553a02fUL, 0x3a1236e8UL, 0x230907a9UL,
+    0x0824546aUL, 0x113f652bUL, 0x96a779e4UL, 0x8fbc48a5UL, 0xa4911b66UL,
+    0xbd8a2a27UL, 0xf2cbbce0UL, 0xebd08da1UL, 0xc0fdde62UL, 0xd9e6ef23UL,
+    0x14bce1bdUL, 0x0da7d0fcUL, 0x268a833fUL, 0x3f91b27eUL, 0x70d024b9UL,
+    0x69cb15f8UL, 0x42e6463bUL, 0x5bfd777aUL, 0xdc656bb5UL, 0xc57e5af4UL,
+    0xee530937UL, 0xf7483876UL, 0xb809aeb1UL, 0xa1129ff0UL, 0x8a3fcc33UL,
+    0x9324fd72UL
+  },
+  {
+    0x00000000UL, 0x01c26a37UL, 0x0384d46eUL, 0x0246be59UL, 0x0709a8dcUL,
+    0x06cbc2ebUL, 0x048d7cb2UL, 0x054f1685UL, 0x0e1351b8UL, 0x0fd13b8fUL,
+    0x0d9785d6UL, 0x0c55efe1UL, 0x091af964UL, 0x08d89353UL, 0x0a9e2d0aUL,
+    0x0b5c473dUL, 0x1c26a370UL, 0x1de4c947UL, 0x1fa2771eUL, 0x1e601d29UL,
+    0x1b2f0bacUL, 0x1aed619bUL, 0x18abdfc2UL, 0x1969b5f5UL, 0x1235f2c8UL,
+    0x13f798ffUL, 0x11b126a6UL, 0x10734c91UL, 0x153c5a14UL, 0x14fe3023UL,
+    0x16b88e7aUL, 0x177ae44dUL, 0x384d46e0UL, 0x398f2cd7UL, 0x3bc9928eUL,
+    0x3a0bf8b9UL, 0x3f44ee3cUL, 0x3e86840bUL, 0x3cc03a52UL, 0x3d025065UL,
+    0x365e1758UL, 0x379c7d6fUL, 0x35dac336UL, 0x3418a901UL, 0x3157bf84UL,
+    0x3095d5b3UL, 0x32d36beaUL, 0x331101ddUL, 0x246be590UL, 0x25a98fa7UL,
+    0x27ef31feUL, 0x262d5bc9UL, 0x23624d4cUL, 0x22a0277bUL, 0x20e69922UL,
+    0x2124f315UL, 0x2a78b428UL, 0x2bbade1fUL, 0x29fc6046UL, 0x283e0a71UL,
+    0x2d711cf4UL, 0x2cb376c3UL, 0x2ef5c89aUL, 0x2f37a2adUL, 0x709a8dc0UL,
+    0x7158e7f7UL, 0x731e59aeUL, 0x72dc3399UL, 0x7793251cUL, 0x76514f2bUL,
+    0x7417f172UL, 0x75d59b45UL, 0x7e89dc78UL, 0x7f4bb64fUL, 0x7d0d0816UL,
+    0x7ccf6221UL, 0x798074a4UL, 0x78421e93UL, 0x7a04a0caUL, 0x7bc6cafdUL,
+    0x6cbc2eb0UL, 0x6d7e4487UL, 0x6f38fadeUL, 0x6efa90e9UL, 0x6bb5866cUL,
+    0x6a77ec5bUL, 0x68315202UL, 0x69f33835UL, 0x62af7f08UL, 0x636d153fUL,
+    0x612bab66UL, 0x60e9c151UL, 0x65a6d7d4UL, 0x6464bde3UL, 0x662203baUL,
+    0x67e0698dUL, 0x48d7cb20UL, 0x4915a117UL, 0x4b531f4eUL, 0x4a917579UL,
+    0x4fde63fcUL, 0x4e1c09cbUL, 0x4c5ab792UL, 0x4d98dda5UL, 0x46c49a98UL,
+    0x4706f0afUL, 0x45404ef6UL, 0x448224c1UL, 0x41cd3244UL, 0x400f5873UL,
+    0x4249e62aUL, 0x438b8c1dUL, 0x54f16850UL, 0x55330267UL, 0x5775bc3eUL,
+    0x56b7d609UL, 0x53f8c08cUL, 0x523aaabbUL, 0x507c14e2UL, 0x51be7ed5UL,
+    0x5ae239e8UL, 0x5b2053dfUL, 0x5966ed86UL, 0x58a487b1UL, 0x5deb9134UL,
+    0x5c29fb03UL, 0x5e6f455aUL, 0x5fad2f6dUL, 0xe1351b80UL, 0xe0f771b7UL,
+    0xe2b1cfeeUL, 0xe373a5d9UL, 0xe63cb35cUL, 0xe7fed96bUL, 0xe5b86732UL,
+    0xe47a0d05UL, 0xef264a38UL, 0xeee4200fUL, 0xeca29e56UL, 0xed60f461UL,
+    0xe82fe2e4UL, 0xe9ed88d3UL, 0xebab368aUL, 0xea695cbdUL, 0xfd13b8f0UL,
+    0xfcd1d2c7UL, 0xfe976c9eUL, 0xff5506a9UL, 0xfa1a102cUL, 0xfbd87a1bUL,
+    0xf99ec442UL, 0xf85cae75UL, 0xf300e948UL, 0xf2c2837fUL, 0xf0843d26UL,
+    0xf1465711UL, 0xf4094194UL, 0xf5cb2ba3UL, 0xf78d95faUL, 0xf64fffcdUL,
+    0xd9785d60UL, 0xd8ba3757UL, 0xdafc890eUL, 0xdb3ee339UL, 0xde71f5bcUL,
+    0xdfb39f8bUL, 0xddf521d2UL, 0xdc374be5UL, 0xd76b0cd8UL, 0xd6a966efUL,
+    0xd4efd8b6UL, 0xd52db281UL, 0xd062a404UL, 0xd1a0ce33UL, 0xd3e6706aUL,
+    0xd2241a5dUL, 0xc55efe10UL, 0xc49c9427UL, 0xc6da2a7eUL, 0xc7184049UL,
+    0xc25756ccUL, 0xc3953cfbUL, 0xc1d382a2UL, 0xc011e895UL, 0xcb4dafa8UL,
+    0xca8fc59fUL, 0xc8c97bc6UL, 0xc90b11f1UL, 0xcc440774UL, 0xcd866d43UL,
+    0xcfc0d31aUL, 0xce02b92dUL, 0x91af9640UL, 0x906dfc77UL, 0x922b422eUL,
+    0x93e92819UL, 0x96a63e9cUL, 0x976454abUL, 0x9522eaf2UL, 0x94e080c5UL,
+    0x9fbcc7f8UL, 0x9e7eadcfUL, 0x9c381396UL, 0x9dfa79a1UL, 0x98b56f24UL,
+    0x99770513UL, 0x9b31bb4aUL, 0x9af3d17dUL, 0x8d893530UL, 0x8c4b5f07UL,
+    0x8e0de15eUL, 0x8fcf8b69UL, 0x8a809decUL, 0x8b42f7dbUL, 0x89044982UL,
+    0x88c623b5UL, 0x839a6488UL, 0x82580ebfUL, 0x801eb0e6UL, 0x81dcdad1UL,
+    0x8493cc54UL, 0x8551a663UL, 0x8717183aUL, 0x86d5720dUL, 0xa9e2d0a0UL,
+    0xa820ba97UL, 0xaa6604ceUL, 0xaba46ef9UL, 0xaeeb787cUL, 0xaf29124bUL,
+    0xad6fac12UL, 0xacadc625UL, 0xa7f18118UL, 0xa633eb2fUL, 0xa4755576UL,
+    0xa5b73f41UL, 0xa0f829c4UL, 0xa13a43f3UL, 0xa37cfdaaUL, 0xa2be979dUL,
+    0xb5c473d0UL, 0xb40619e7UL, 0xb640a7beUL, 0xb782cd89UL, 0xb2cddb0cUL,
+    0xb30fb13bUL, 0xb1490f62UL, 0xb08b6555UL, 0xbbd72268UL, 0xba15485fUL,
+    0xb853f606UL, 0xb9919c31UL, 0xbcde8ab4UL, 0xbd1ce083UL, 0xbf5a5edaUL,
+    0xbe9834edUL
+  },
+  {
+    0x00000000UL, 0xb8bc6765UL, 0xaa09c88bUL, 0x12b5afeeUL, 0x8f629757UL,
+    0x37def032UL, 0x256b5fdcUL, 0x9dd738b9UL, 0xc5b428efUL, 0x7d084f8aUL,
+    0x6fbde064UL, 0xd7018701UL, 0x4ad6bfb8UL, 0xf26ad8ddUL, 0xe0df7733UL,
+    0x58631056UL, 0x5019579fUL, 0xe8a530faUL, 0xfa109f14UL, 0x42acf871UL,
+    0xdf7bc0c8UL, 0x67c7a7adUL, 0x75720843UL, 0xcdce6f26UL, 0x95ad7f70UL,
+    0x2d111815UL, 0x3fa4b7fbUL, 0x8718d09eUL, 0x1acfe827UL, 0xa2738f42UL,
+    0xb0c620acUL, 0x087a47c9UL, 0xa032af3eUL, 0x188ec85bUL, 0x0a3b67b5UL,
+    0xb28700d0UL, 0x2f503869UL, 0x97ec5f0cUL, 0x8559f0e2UL, 0x3de59787UL,
+    0x658687d1UL, 0xdd3ae0b4UL, 0xcf8f4f5aUL, 0x7733283fUL, 0xeae41086UL,
+    0x525877e3UL, 0x40edd80dUL, 0xf851bf68UL, 0xf02bf8a1UL, 0x48979fc4UL,
+    0x5a22302aUL, 0xe29e574fUL, 0x7f496ff6UL, 0xc7f50893UL, 0xd540a77dUL,
+    0x6dfcc018UL, 0x359fd04eUL, 0x8d23b72bUL, 0x9f9618c5UL, 0x272a7fa0UL,
+    0xbafd4719UL, 0x0241207cUL, 0x10f48f92UL, 0xa848e8f7UL, 0x9b14583dUL,
+    0x23a83f58UL, 0x311d90b6UL, 0x89a1f7d3UL, 0x1476cf6aUL, 0xaccaa80fUL,
+    0xbe7f07e1UL, 0x06c36084UL, 0x5ea070d2UL, 0xe61c17b7UL, 0xf4a9b859UL,
+    0x4c15df3cUL, 0xd1c2e785UL, 0x697e80e0UL, 0x7bcb2f0eUL, 0xc377486bUL,
+    0xcb0d0fa2UL, 0x73b168c7UL, 0x6104c729UL, 0xd9b8a04cUL, 0x446f98f5UL,
+    0xfcd3ff90UL, 0xee66507eUL, 0x56da371bUL, 0x0eb9274dUL, 0xb6054028UL,
+    0xa4b0efc6UL, 0x1c0c88a3UL, 0x81dbb01aUL, 0x3967d77fUL, 0x2bd27891UL,
+    0x936e1ff4UL, 0x3b26f703UL, 0x839a9066UL, 0x912f3f88UL, 0x299358edUL,
+    0xb4446054UL, 0x0cf80731UL, 0x1e4da8dfUL, 0xa6f1cfbaUL, 0xfe92dfecUL,
+    0x462eb889UL, 0x549b1767UL, 0xec277002UL, 0x71f048bbUL, 0xc94c2fdeUL,
+    0xdbf98030UL, 0x6345e755UL, 0x6b3fa09cUL, 0xd383c7f9UL, 0xc1366817UL,
+    0x798a0f72UL, 0xe45d37cbUL, 0x5ce150aeUL, 0x4e54ff40UL, 0xf6e89825UL,
+    0xae8b8873UL, 0x1637ef16UL, 0x048240f8UL, 0xbc3e279dUL, 0x21e91f24UL,
+    0x99557841UL, 0x8be0d7afUL, 0x335cb0caUL, 0xed59b63bUL, 0x55e5d15eUL,
+    0x47507eb0UL, 0xffec19d5UL, 0x623b216cUL, 0xda874609UL, 0xc832e9e7UL,
+    0x708e8e82UL, 0x28ed9ed4UL, 0x9051f9b1UL, 0x82e4565fUL, 0x3a58313aUL,
+    0xa78f0983UL, 0x1f336ee6UL, 0x0d86c108UL, 0xb53aa66dUL, 0xbd40e1a4UL,
+    0x05fc86c1UL, 0x1749292fUL, 0xaff54e4aUL, 0x322276f3UL, 0x8a9e1196UL,
+    0x982bbe78UL, 0x2097d91dUL, 0x78f4c94bUL, 0xc048ae2eUL, 0xd2fd01c0UL,
+    0x6a4166a5UL, 0xf7965e1cUL, 0x4f2a3979UL, 0x5d9f9697UL, 0xe523f1f2UL,
+    0x4d6b1905UL, 0xf5d77e60UL, 0xe762d18eUL, 0x5fdeb6ebUL, 0xc2098e52UL,
+    0x7ab5e937UL, 0x680046d9UL, 0xd0bc21bcUL, 0x88df31eaUL, 0x3063568fUL,
+    0x22d6f961UL, 0x9a6a9e04UL, 0x07bda6bdUL, 0xbf01c1d8UL, 0xadb46e36UL,
+    0x15080953UL, 0x1d724e9aUL, 0xa5ce29ffUL, 0xb77b8611UL, 0x0fc7e174UL,
+    0x9210d9cdUL, 0x2aacbea8UL, 0x38191146UL, 0x80a57623UL, 0xd8c66675UL,
+    0x607a0110UL, 0x72cfaefeUL, 0xca73c99bUL, 0x57a4f122UL, 0xef189647UL,
+    0xfdad39a9UL, 0x45115eccUL, 0x764dee06UL, 0xcef18963UL, 0xdc44268dUL,
+    0x64f841e8UL, 0xf92f7951UL, 0x41931e34UL, 0x5326b1daUL, 0xeb9ad6bfUL,
+    0xb3f9c6e9UL, 0x0b45a18cUL, 0x19f00e62UL, 0xa14c6907UL, 0x3c9b51beUL,
+    0x842736dbUL, 0x96929935UL, 0x2e2efe50UL, 0x2654b999UL, 0x9ee8defcUL,
+    0x8c5d7112UL, 0x34e11677UL, 0xa9362eceUL, 0x118a49abUL, 0x033fe645UL,
+    0xbb838120UL, 0xe3e09176UL, 0x5b5cf613UL, 0x49e959fdUL, 0xf1553e98UL,
+    0x6c820621UL, 0xd43e6144UL, 0xc68bceaaUL, 0x7e37a9cfUL, 0xd67f4138UL,
+    0x6ec3265dUL, 0x7c7689b3UL, 0xc4caeed6UL, 0x591dd66fUL, 0xe1a1b10aUL,
+    0xf3141ee4UL, 0x4ba87981UL, 0x13cb69d7UL, 0xab770eb2UL, 0xb9c2a15cUL,
+    0x017ec639UL, 0x9ca9fe80UL, 0x241599e5UL, 0x36a0360bUL, 0x8e1c516eUL,
+    0x866616a7UL, 0x3eda71c2UL, 0x2c6fde2cUL, 0x94d3b949UL, 0x090481f0UL,
+    0xb1b8e695UL, 0xa30d497bUL, 0x1bb12e1eUL, 0x43d23e48UL, 0xfb6e592dUL,
+    0xe9dbf6c3UL, 0x516791a6UL, 0xccb0a91fUL, 0x740cce7aUL, 0x66b96194UL,
+    0xde0506f1UL
+  },
+  {
+    0x00000000UL, 0x96300777UL, 0x2c610eeeUL, 0xba510999UL, 0x19c46d07UL,
+    0x8ff46a70UL, 0x35a563e9UL, 0xa395649eUL, 0x3288db0eUL, 0xa4b8dc79UL,
+    0x1ee9d5e0UL, 0x88d9d297UL, 0x2b4cb609UL, 0xbd7cb17eUL, 0x072db8e7UL,
+    0x911dbf90UL, 0x6410b71dUL, 0xf220b06aUL, 0x4871b9f3UL, 0xde41be84UL,
+    0x7dd4da1aUL, 0xebe4dd6dUL, 0x51b5d4f4UL, 0xc785d383UL, 0x56986c13UL,
+    0xc0a86b64UL, 0x7af962fdUL, 0xecc9658aUL, 0x4f5c0114UL, 0xd96c0663UL,
+    0x633d0ffaUL, 0xf50d088dUL, 0xc8206e3bUL, 0x5e10694cUL, 0xe44160d5UL,
+    0x727167a2UL, 0xd1e4033cUL, 0x47d4044bUL, 0xfd850dd2UL, 0x6bb50aa5UL,
+    0xfaa8b535UL, 0x6c98b242UL, 0xd6c9bbdbUL, 0x40f9bcacUL, 0xe36cd832UL,
+    0x755cdf45UL, 0xcf0dd6dcUL, 0x593dd1abUL, 0xac30d926UL, 0x3a00de51UL,
+    0x8051d7c8UL, 0x1661d0bfUL, 0xb5f4b421UL, 0x23c4b356UL, 0x9995bacfUL,
+    0x0fa5bdb8UL, 0x9eb80228UL, 0x0888055fUL, 0xb2d90cc6UL, 0x24e90bb1UL,
+    0x877c6f2fUL, 0x114c6858UL, 0xab1d61c1UL, 0x3d2d66b6UL, 0x9041dc76UL,
+    0x0671db01UL, 0xbc20d298UL, 0x2a10d5efUL, 0x8985b171UL, 0x1fb5b606UL,
+    0xa5e4bf9fUL, 0x33d4b8e8UL, 0xa2c90778UL, 0x34f9000fUL, 0x8ea80996UL,
+    0x18980ee1UL, 0xbb0d6a7fUL, 0x2d3d6d08UL, 0x976c6491UL, 0x015c63e6UL,
+    0xf4516b6bUL, 0x62616c1cUL, 0xd8306585UL, 0x4e0062f2UL, 0xed95066cUL,
+    0x7ba5011bUL, 0xc1f40882UL, 0x57c40ff5UL, 0xc6d9b065UL, 0x50e9b712UL,
+    0xeab8be8bUL, 0x7c88b9fcUL, 0xdf1ddd62UL, 0x492dda15UL, 0xf37cd38cUL,
+    0x654cd4fbUL, 0x5861b24dUL, 0xce51b53aUL, 0x7400bca3UL, 0xe230bbd4UL,
+    0x41a5df4aUL, 0xd795d83dUL, 0x6dc4d1a4UL, 0xfbf4d6d3UL, 0x6ae96943UL,
+    0xfcd96e34UL, 0x468867adUL, 0xd0b860daUL, 0x732d0444UL, 0xe51d0333UL,
+    0x5f4c0aaaUL, 0xc97c0dddUL, 0x3c710550UL, 0xaa410227UL, 0x10100bbeUL,
+    0x86200cc9UL, 0x25b56857UL, 0xb3856f20UL, 0x09d466b9UL, 0x9fe461ceUL,
+    0x0ef9de5eUL, 0x98c9d929UL, 0x2298d0b0UL, 0xb4a8d7c7UL, 0x173db359UL,
+    0x810db42eUL, 0x3b5cbdb7UL, 0xad6cbac0UL, 0x2083b8edUL, 0xb6b3bf9aUL,
+    0x0ce2b603UL, 0x9ad2b174UL, 0x3947d5eaUL, 0xaf77d29dUL, 0x1526db04UL,
+    0x8316dc73UL, 0x120b63e3UL, 0x843b6494UL, 0x3e6a6d0dUL, 0xa85a6a7aUL,
+    0x0bcf0ee4UL, 0x9dff0993UL, 0x27ae000aUL, 0xb19e077dUL, 0x44930ff0UL,
+    0xd2a30887UL, 0x68f2011eUL, 0xfec20669UL, 0x5d5762f7UL, 0xcb676580UL,
+    0x71366c19UL, 0xe7066b6eUL, 0x761bd4feUL, 0xe02bd389UL, 0x5a7ada10UL,
+    0xcc4add67UL, 0x6fdfb9f9UL, 0xf9efbe8eUL, 0x43beb717UL, 0xd58eb060UL,
+    0xe8a3d6d6UL, 0x7e93d1a1UL, 0xc4c2d838UL, 0x52f2df4fUL, 0xf167bbd1UL,
+    0x6757bca6UL, 0xdd06b53fUL, 0x4b36b248UL, 0xda2b0dd8UL, 0x4c1b0aafUL,
+    0xf64a0336UL, 0x607a0441UL, 0xc3ef60dfUL, 0x55df67a8UL, 0xef8e6e31UL,
+    0x79be6946UL, 0x8cb361cbUL, 0x1a8366bcUL, 0xa0d26f25UL, 0x36e26852UL,
+    0x95770cccUL, 0x03470bbbUL, 0xb9160222UL, 0x2f260555UL, 0xbe3bbac5UL,
+    0x280bbdb2UL, 0x925ab42bUL, 0x046ab35cUL, 0xa7ffd7c2UL, 0x31cfd0b5UL,
+    0x8b9ed92cUL, 0x1daede5bUL, 0xb0c2649bUL, 0x26f263ecUL, 0x9ca36a75UL,
+    0x0a936d02UL, 0xa906099cUL, 0x3f360eebUL, 0x85670772UL, 0x13570005UL,
+    0x824abf95UL, 0x147ab8e2UL, 0xae2bb17bUL, 0x381bb60cUL, 0x9b8ed292UL,
+    0x0dbed5e5UL, 0xb7efdc7cUL, 0x21dfdb0bUL, 0xd4d2d386UL, 0x42e2d4f1UL,
+    0xf8b3dd68UL, 0x6e83da1fUL, 0xcd16be81UL, 0x5b26b9f6UL, 0xe177b06fUL,
+    0x7747b718UL, 0xe65a0888UL, 0x706a0fffUL, 0xca3b0666UL, 0x5c0b0111UL,
+    0xff9e658fUL, 0x69ae62f8UL, 0xd3ff6b61UL, 0x45cf6c16UL, 0x78e20aa0UL,
+    0xeed20dd7UL, 0x5483044eUL, 0xc2b30339UL, 0x612667a7UL, 0xf71660d0UL,
+    0x4d476949UL, 0xdb776e3eUL, 0x4a6ad1aeUL, 0xdc5ad6d9UL, 0x660bdf40UL,
+    0xf03bd837UL, 0x53aebca9UL, 0xc59ebbdeUL, 0x7fcfb247UL, 0xe9ffb530UL,
+    0x1cf2bdbdUL, 0x8ac2bacaUL, 0x3093b353UL, 0xa6a3b424UL, 0x0536d0baUL,
+    0x9306d7cdUL, 0x2957de54UL, 0xbf67d923UL, 0x2e7a66b3UL, 0xb84a61c4UL,
+    0x021b685dUL, 0x942b6f2aUL, 0x37be0bb4UL, 0xa18e0cc3UL, 0x1bdf055aUL,
+    0x8def022dUL
+  },
+  {
+    0x00000000UL, 0x41311b19UL, 0x82623632UL, 0xc3532d2bUL, 0x04c56c64UL,
+    0x45f4777dUL, 0x86a75a56UL, 0xc796414fUL, 0x088ad9c8UL, 0x49bbc2d1UL,
+    0x8ae8effaUL, 0xcbd9f4e3UL, 0x0c4fb5acUL, 0x4d7eaeb5UL, 0x8e2d839eUL,
+    0xcf1c9887UL, 0x5112c24aUL, 0x1023d953UL, 0xd370f478UL, 0x9241ef61UL,
+    0x55d7ae2eUL, 0x14e6b537UL, 0xd7b5981cUL, 0x96848305UL, 0x59981b82UL,
+    0x18a9009bUL, 0xdbfa2db0UL, 0x9acb36a9UL, 0x5d5d77e6UL, 0x1c6c6cffUL,
+    0xdf3f41d4UL, 0x9e0e5acdUL, 0xa2248495UL, 0xe3159f8cUL, 0x2046b2a7UL,
+    0x6177a9beUL, 0xa6e1e8f1UL, 0xe7d0f3e8UL, 0x2483dec3UL, 0x65b2c5daUL,
+    0xaaae5d5dUL, 0xeb9f4644UL, 0x28cc6b6fUL, 0x69fd7076UL, 0xae6b3139UL,
+    0xef5a2a20UL, 0x2c09070bUL, 0x6d381c12UL, 0xf33646dfUL, 0xb2075dc6UL,
+    0x715470edUL, 0x30656bf4UL, 0xf7f32abbUL, 0xb6c231a2UL, 0x75911c89UL,
+    0x34a00790UL, 0xfbbc9f17UL, 0xba8d840eUL, 0x79dea925UL, 0x38efb23cUL,
+    0xff79f373UL, 0xbe48e86aUL, 0x7d1bc541UL, 0x3c2ade58UL, 0x054f79f0UL,
+    0x447e62e9UL, 0x872d4fc2UL, 0xc61c54dbUL, 0x018a1594UL, 0x40bb0e8dUL,
+    0x83e823a6UL, 0xc2d938bfUL, 0x0dc5a038UL, 0x4cf4bb21UL, 0x8fa7960aUL,
+    0xce968d13UL, 0x0900cc5cUL, 0x4831d745UL, 0x8b62fa6eUL, 0xca53e177UL,
+    0x545dbbbaUL, 0x156ca0a3UL, 0xd63f8d88UL, 0x970e9691UL, 0x5098d7deUL,
+    0x11a9ccc7UL, 0xd2fae1ecUL, 0x93cbfaf5UL, 0x5cd76272UL, 0x1de6796bUL,
+    0xdeb55440UL, 0x9f844f59UL, 0x58120e16UL, 0x1923150fUL, 0xda703824UL,
+    0x9b41233dUL, 0xa76bfd65UL, 0xe65ae67cUL, 0x2509cb57UL, 0x6438d04eUL,
+    0xa3ae9101UL, 0xe29f8a18UL, 0x21cca733UL, 0x60fdbc2aUL, 0xafe124adUL,
+    0xeed03fb4UL, 0x2d83129fUL, 0x6cb20986UL, 0xab2448c9UL, 0xea1553d0UL,
+    0x29467efbUL, 0x687765e2UL, 0xf6793f2fUL, 0xb7482436UL, 0x741b091dUL,
+    0x352a1204UL, 0xf2bc534bUL, 0xb38d4852UL, 0x70de6579UL, 0x31ef7e60UL,
+    0xfef3e6e7UL, 0xbfc2fdfeUL, 0x7c91d0d5UL, 0x3da0cbccUL, 0xfa368a83UL,
+    0xbb07919aUL, 0x7854bcb1UL, 0x3965a7a8UL, 0x4b98833bUL, 0x0aa99822UL,
+    0xc9fab509UL, 0x88cbae10UL, 0x4f5def5fUL, 0x0e6cf446UL, 0xcd3fd96dUL,
+    0x8c0ec274UL, 0x43125af3UL, 0x022341eaUL, 0xc1706cc1UL, 0x804177d8UL,
+    0x47d73697UL, 0x06e62d8eUL, 0xc5b500a5UL, 0x84841bbcUL, 0x1a8a4171UL,
+    0x5bbb5a68UL, 0x98e87743UL, 0xd9d96c5aUL, 0x1e4f2d15UL, 0x5f7e360cUL,
+    0x9c2d1b27UL, 0xdd1c003eUL, 0x120098b9UL, 0x533183a0UL, 0x9062ae8bUL,
+    0xd153b592UL, 0x16c5f4ddUL, 0x57f4efc4UL, 0x94a7c2efUL, 0xd596d9f6UL,
+    0xe9bc07aeUL, 0xa88d1cb7UL, 0x6bde319cUL, 0x2aef2a85UL, 0xed796bcaUL,
+    0xac4870d3UL, 0x6f1b5df8UL, 0x2e2a46e1UL, 0xe136de66UL, 0xa007c57fUL,
+    0x6354e854UL, 0x2265f34dUL, 0xe5f3b202UL, 0xa4c2a91bUL, 0x67918430UL,
+    0x26a09f29UL, 0xb8aec5e4UL, 0xf99fdefdUL, 0x3accf3d6UL, 0x7bfde8cfUL,
+    0xbc6ba980UL, 0xfd5ab299UL, 0x3e099fb2UL, 0x7f3884abUL, 0xb0241c2cUL,
+    0xf1150735UL, 0x32462a1eUL, 0x73773107UL, 0xb4e17048UL, 0xf5d06b51UL,
+    0x3683467aUL, 0x77b25d63UL, 0x4ed7facbUL, 0x0fe6e1d2UL, 0xccb5ccf9UL,
+    0x8d84d7e0UL, 0x4a1296afUL, 0x0b238db6UL, 0xc870a09dUL, 0x8941bb84UL,
+    0x465d2303UL, 0x076c381aUL, 0xc43f1531UL, 0x850e0e28UL, 0x42984f67UL,
+    0x03a9547eUL, 0xc0fa7955UL, 0x81cb624cUL, 0x1fc53881UL, 0x5ef42398UL,
+    0x9da70eb3UL, 0xdc9615aaUL, 0x1b0054e5UL, 0x5a314ffcUL, 0x996262d7UL,
+    0xd85379ceUL, 0x174fe149UL, 0x567efa50UL, 0x952dd77bUL, 0xd41ccc62UL,
+    0x138a8d2dUL, 0x52bb9634UL, 0x91e8bb1fUL, 0xd0d9a006UL, 0xecf37e5eUL,
+    0xadc26547UL, 0x6e91486cUL, 0x2fa05375UL, 0xe836123aUL, 0xa9070923UL,
+    0x6a542408UL, 0x2b653f11UL, 0xe479a796UL, 0xa548bc8fUL, 0x661b91a4UL,
+    0x272a8abdUL, 0xe0bccbf2UL, 0xa18dd0ebUL, 0x62defdc0UL, 0x23efe6d9UL,
+    0xbde1bc14UL, 0xfcd0a70dUL, 0x3f838a26UL, 0x7eb2913fUL, 0xb924d070UL,
+    0xf815cb69UL, 0x3b46e642UL, 0x7a77fd5bUL, 0xb56b65dcUL, 0xf45a7ec5UL,
+    0x370953eeUL, 0x763848f7UL, 0xb1ae09b8UL, 0xf09f12a1UL, 0x33cc3f8aUL,
+    0x72fd2493UL
+  },
+  {
+    0x00000000UL, 0x376ac201UL, 0x6ed48403UL, 0x59be4602UL, 0xdca80907UL,
+    0xebc2cb06UL, 0xb27c8d04UL, 0x85164f05UL, 0xb851130eUL, 0x8f3bd10fUL,
+    0xd685970dUL, 0xe1ef550cUL, 0x64f91a09UL, 0x5393d808UL, 0x0a2d9e0aUL,
+    0x3d475c0bUL, 0x70a3261cUL, 0x47c9e41dUL, 0x1e77a21fUL, 0x291d601eUL,
+    0xac0b2f1bUL, 0x9b61ed1aUL, 0xc2dfab18UL, 0xf5b56919UL, 0xc8f23512UL,
+    0xff98f713UL, 0xa626b111UL, 0x914c7310UL, 0x145a3c15UL, 0x2330fe14UL,
+    0x7a8eb816UL, 0x4de47a17UL, 0xe0464d38UL, 0xd72c8f39UL, 0x8e92c93bUL,
+    0xb9f80b3aUL, 0x3cee443fUL, 0x0b84863eUL, 0x523ac03cUL, 0x6550023dUL,
+    0x58175e36UL, 0x6f7d9c37UL, 0x36c3da35UL, 0x01a91834UL, 0x84bf5731UL,
+    0xb3d59530UL, 0xea6bd332UL, 0xdd011133UL, 0x90e56b24UL, 0xa78fa925UL,
+    0xfe31ef27UL, 0xc95b2d26UL, 0x4c4d6223UL, 0x7b27a022UL, 0x2299e620UL,
+    0x15f32421UL, 0x28b4782aUL, 0x1fdeba2bUL, 0x4660fc29UL, 0x710a3e28UL,
+    0xf41c712dUL, 0xc376b32cUL, 0x9ac8f52eUL, 0xada2372fUL, 0xc08d9a70UL,
+    0xf7e75871UL, 0xae591e73UL, 0x9933dc72UL, 0x1c259377UL, 0x2b4f5176UL,
+    0x72f11774UL, 0x459bd575UL, 0x78dc897eUL, 0x4fb64b7fUL, 0x16080d7dUL,
+    0x2162cf7cUL, 0xa4748079UL, 0x931e4278UL, 0xcaa0047aUL, 0xfdcac67bUL,
+    0xb02ebc6cUL, 0x87447e6dUL, 0xdefa386fUL, 0xe990fa6eUL, 0x6c86b56bUL,
+    0x5bec776aUL, 0x02523168UL, 0x3538f369UL, 0x087faf62UL, 0x3f156d63UL,
+    0x66ab2b61UL, 0x51c1e960UL, 0xd4d7a665UL, 0xe3bd6464UL, 0xba032266UL,
+    0x8d69e067UL, 0x20cbd748UL, 0x17a11549UL, 0x4e1f534bUL, 0x7975914aUL,
+    0xfc63de4fUL, 0xcb091c4eUL, 0x92b75a4cUL, 0xa5dd984dUL, 0x989ac446UL,
+    0xaff00647UL, 0xf64e4045UL, 0xc1248244UL, 0x4432cd41UL, 0x73580f40UL,
+    0x2ae64942UL, 0x1d8c8b43UL, 0x5068f154UL, 0x67023355UL, 0x3ebc7557UL,
+    0x09d6b756UL, 0x8cc0f853UL, 0xbbaa3a52UL, 0xe2147c50UL, 0xd57ebe51UL,
+    0xe839e25aUL, 0xdf53205bUL, 0x86ed6659UL, 0xb187a458UL, 0x3491eb5dUL,
+    0x03fb295cUL, 0x5a456f5eUL, 0x6d2fad5fUL, 0x801b35e1UL, 0xb771f7e0UL,
+    0xeecfb1e2UL, 0xd9a573e3UL, 0x5cb33ce6UL, 0x6bd9fee7UL, 0x3267b8e5UL,
+    0x050d7ae4UL, 0x384a26efUL, 0x0f20e4eeUL, 0x569ea2ecUL, 0x61f460edUL,
+    0xe4e22fe8UL, 0xd388ede9UL, 0x8a36abebUL, 0xbd5c69eaUL, 0xf0b813fdUL,
+    0xc7d2d1fcUL, 0x9e6c97feUL, 0xa90655ffUL, 0x2c101afaUL, 0x1b7ad8fbUL,
+    0x42c49ef9UL, 0x75ae5cf8UL, 0x48e900f3UL, 0x7f83c2f2UL, 0x263d84f0UL,
+    0x115746f1UL, 0x944109f4UL, 0xa32bcbf5UL, 0xfa958df7UL, 0xcdff4ff6UL,
+    0x605d78d9UL, 0x5737bad8UL, 0x0e89fcdaUL, 0x39e33edbUL, 0xbcf571deUL,
+    0x8b9fb3dfUL, 0xd221f5ddUL, 0xe54b37dcUL, 0xd80c6bd7UL, 0xef66a9d6UL,
+    0xb6d8efd4UL, 0x81b22dd5UL, 0x04a462d0UL, 0x33cea0d1UL, 0x6a70e6d3UL,
+    0x5d1a24d2UL, 0x10fe5ec5UL, 0x27949cc4UL, 0x7e2adac6UL, 0x494018c7UL,
+    0xcc5657c2UL, 0xfb3c95c3UL, 0xa282d3c1UL, 0x95e811c0UL, 0xa8af4dcbUL,
+    0x9fc58fcaUL, 0xc67bc9c8UL, 0xf1110bc9UL, 0x740744ccUL, 0x436d86cdUL,
+    0x1ad3c0cfUL, 0x2db902ceUL, 0x4096af91UL, 0x77fc6d90UL, 0x2e422b92UL,
+    0x1928e993UL, 0x9c3ea696UL, 0xab546497UL, 0xf2ea2295UL, 0xc580e094UL,
+    0xf8c7bc9fUL, 0xcfad7e9eUL, 0x9613389cUL, 0xa179fa9dUL, 0x246fb598UL,
+    0x13057799UL, 0x4abb319bUL, 0x7dd1f39aUL, 0x3035898dUL, 0x075f4b8cUL,
+    0x5ee10d8eUL, 0x698bcf8fUL, 0xec9d808aUL, 0xdbf7428bUL, 0x82490489UL,
+    0xb523c688UL, 0x88649a83UL, 0xbf0e5882UL, 0xe6b01e80UL, 0xd1dadc81UL,
+    0x54cc9384UL, 0x63a65185UL, 0x3a181787UL, 0x0d72d586UL, 0xa0d0e2a9UL,
+    0x97ba20a8UL, 0xce0466aaUL, 0xf96ea4abUL, 0x7c78ebaeUL, 0x4b1229afUL,
+    0x12ac6fadUL, 0x25c6adacUL, 0x1881f1a7UL, 0x2feb33a6UL, 0x765575a4UL,
+    0x413fb7a5UL, 0xc429f8a0UL, 0xf3433aa1UL, 0xaafd7ca3UL, 0x9d97bea2UL,
+    0xd073c4b5UL, 0xe71906b4UL, 0xbea740b6UL, 0x89cd82b7UL, 0x0cdbcdb2UL,
+    0x3bb10fb3UL, 0x620f49b1UL, 0x55658bb0UL, 0x6822d7bbUL, 0x5f4815baUL,
+    0x06f653b8UL, 0x319c91b9UL, 0xb48adebcUL, 0x83e01cbdUL, 0xda5e5abfUL,
+    0xed3498beUL
+  },
+  {
+    0x00000000UL, 0x6567bcb8UL, 0x8bc809aaUL, 0xeeafb512UL, 0x5797628fUL,
+    0x32f0de37UL, 0xdc5f6b25UL, 0xb938d79dUL, 0xef28b4c5UL, 0x8a4f087dUL,
+    0x64e0bd6fUL, 0x018701d7UL, 0xb8bfd64aUL, 0xddd86af2UL, 0x3377dfe0UL,
+    0x56106358UL, 0x9f571950UL, 0xfa30a5e8UL, 0x149f10faUL, 0x71f8ac42UL,
+    0xc8c07bdfUL, 0xada7c767UL, 0x43087275UL, 0x266fcecdUL, 0x707fad95UL,
+    0x1518112dUL, 0xfbb7a43fUL, 0x9ed01887UL, 0x27e8cf1aUL, 0x428f73a2UL,
+    0xac20c6b0UL, 0xc9477a08UL, 0x3eaf32a0UL, 0x5bc88e18UL, 0xb5673b0aUL,
+    0xd00087b2UL, 0x6938502fUL, 0x0c5fec97UL, 0xe2f05985UL, 0x8797e53dUL,
+    0xd1878665UL, 0xb4e03addUL, 0x5a4f8fcfUL, 0x3f283377UL, 0x8610e4eaUL,
+    0xe3775852UL, 0x0dd8ed40UL, 0x68bf51f8UL, 0xa1f82bf0UL, 0xc49f9748UL,
+    0x2a30225aUL, 0x4f579ee2UL, 0xf66f497fUL, 0x9308f5c7UL, 0x7da740d5UL,
+    0x18c0fc6dUL, 0x4ed09f35UL, 0x2bb7238dUL, 0xc518969fUL, 0xa07f2a27UL,
+    0x1947fdbaUL, 0x7c204102UL, 0x928ff410UL, 0xf7e848a8UL, 0x3d58149bUL,
+    0x583fa823UL, 0xb6901d31UL, 0xd3f7a189UL, 0x6acf7614UL, 0x0fa8caacUL,
+    0xe1077fbeUL, 0x8460c306UL, 0xd270a05eUL, 0xb7171ce6UL, 0x59b8a9f4UL,
+    0x3cdf154cUL, 0x85e7c2d1UL, 0xe0807e69UL, 0x0e2fcb7bUL, 0x6b4877c3UL,
+    0xa20f0dcbUL, 0xc768b173UL, 0x29c70461UL, 0x4ca0b8d9UL, 0xf5986f44UL,
+    0x90ffd3fcUL, 0x7e5066eeUL, 0x1b37da56UL, 0x4d27b90eUL, 0x284005b6UL,
+    0xc6efb0a4UL, 0xa3880c1cUL, 0x1ab0db81UL, 0x7fd76739UL, 0x9178d22bUL,
+    0xf41f6e93UL, 0x03f7263bUL, 0x66909a83UL, 0x883f2f91UL, 0xed589329UL,
+    0x546044b4UL, 0x3107f80cUL, 0xdfa84d1eUL, 0xbacff1a6UL, 0xecdf92feUL,
+    0x89b82e46UL, 0x67179b54UL, 0x027027ecUL, 0xbb48f071UL, 0xde2f4cc9UL,
+    0x3080f9dbUL, 0x55e74563UL, 0x9ca03f6bUL, 0xf9c783d3UL, 0x176836c1UL,
+    0x720f8a79UL, 0xcb375de4UL, 0xae50e15cUL, 0x40ff544eUL, 0x2598e8f6UL,
+    0x73888baeUL, 0x16ef3716UL, 0xf8408204UL, 0x9d273ebcUL, 0x241fe921UL,
+    0x41785599UL, 0xafd7e08bUL, 0xcab05c33UL, 0x3bb659edUL, 0x5ed1e555UL,
+    0xb07e5047UL, 0xd519ecffUL, 0x6c213b62UL, 0x094687daUL, 0xe7e932c8UL,
+    0x828e8e70UL, 0xd49eed28UL, 0xb1f95190UL, 0x5f56e482UL, 0x3a31583aUL,
+    0x83098fa7UL, 0xe66e331fUL, 0x08c1860dUL, 0x6da63ab5UL, 0xa4e140bdUL,
+    0xc186fc05UL, 0x2f294917UL, 0x4a4ef5afUL, 0xf3762232UL, 0x96119e8aUL,
+    0x78be2b98UL, 0x1dd99720UL, 0x4bc9f478UL, 0x2eae48c0UL, 0xc001fdd2UL,
+    0xa566416aUL, 0x1c5e96f7UL, 0x79392a4fUL, 0x97969f5dUL, 0xf2f123e5UL,
+    0x05196b4dUL, 0x607ed7f5UL, 0x8ed162e7UL, 0xebb6de5fUL, 0x528e09c2UL,
+    0x37e9b57aUL, 0xd9460068UL, 0xbc21bcd0UL, 0xea31df88UL, 0x8f566330UL,
+    0x61f9d622UL, 0x049e6a9aUL, 0xbda6bd07UL, 0xd8c101bfUL, 0x366eb4adUL,
+    0x53090815UL, 0x9a4e721dUL, 0xff29cea5UL, 0x11867bb7UL, 0x74e1c70fUL,
+    0xcdd91092UL, 0xa8beac2aUL, 0x46111938UL, 0x2376a580UL, 0x7566c6d8UL,
+    0x10017a60UL, 0xfeaecf72UL, 0x9bc973caUL, 0x22f1a457UL, 0x479618efUL,
+    0xa939adfdUL, 0xcc5e1145UL, 0x06ee4d76UL, 0x6389f1ceUL, 0x8d2644dcUL,
+    0xe841f864UL, 0x51792ff9UL, 0x341e9341UL, 0xdab12653UL, 0xbfd69aebUL,
+    0xe9c6f9b3UL, 0x8ca1450bUL, 0x620ef019UL, 0x07694ca1UL, 0xbe519b3cUL,
+    0xdb362784UL, 0x35999296UL, 0x50fe2e2eUL, 0x99b95426UL, 0xfcdee89eUL,
+    0x12715d8cUL, 0x7716e134UL, 0xce2e36a9UL, 0xab498a11UL, 0x45e63f03UL,
+    0x208183bbUL, 0x7691e0e3UL, 0x13f65c5bUL, 0xfd59e949UL, 0x983e55f1UL,
+    0x2106826cUL, 0x44613ed4UL, 0xaace8bc6UL, 0xcfa9377eUL, 0x38417fd6UL,
+    0x5d26c36eUL, 0xb389767cUL, 0xd6eecac4UL, 0x6fd61d59UL, 0x0ab1a1e1UL,
+    0xe41e14f3UL, 0x8179a84bUL, 0xd769cb13UL, 0xb20e77abUL, 0x5ca1c2b9UL,
+    0x39c67e01UL, 0x80fea99cUL, 0xe5991524UL, 0x0b36a036UL, 0x6e511c8eUL,
+    0xa7166686UL, 0xc271da3eUL, 0x2cde6f2cUL, 0x49b9d394UL, 0xf0810409UL,
+    0x95e6b8b1UL, 0x7b490da3UL, 0x1e2eb11bUL, 0x483ed243UL, 0x2d596efbUL,
+    0xc3f6dbe9UL, 0xa6916751UL, 0x1fa9b0ccUL, 0x7ace0c74UL, 0x9461b966UL,
+    0xf10605deUL
+#endif
+  }
+};
diff --git a/compat/zlib/deflate.c b/compat/zlib/deflate.c
new file mode 100644
index 0000000..6969577
--- /dev/null
+++ b/compat/zlib/deflate.c
@@ -0,0 +1,1967 @@
+/* deflate.c -- compress data using the deflation algorithm
+ * Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/*
+ *  ALGORITHM
+ *
+ *      The "deflation" process depends on being able to identify portions
+ *      of the input text which are identical to earlier input (within a
+ *      sliding window trailing behind the input currently being processed).
+ *
+ *      The most straightforward technique turns out to be the fastest for
+ *      most input files: try all possible matches and select the longest.
+ *      The key feature of this algorithm is that insertions into the string
+ *      dictionary are very simple and thus fast, and deletions are avoided
+ *      completely. Insertions are performed at each input character, whereas
+ *      string matches are performed only when the previous match ends. So it
+ *      is preferable to spend more time in matches to allow very fast string
+ *      insertions and avoid deletions. The matching algorithm for small
+ *      strings is inspired from that of Rabin & Karp. A brute force approach
+ *      is used to find longer strings when a small match has been found.
+ *      A similar algorithm is used in comic (by Jan-Mark Wams) and freeze
+ *      (by Leonid Broukhis).
+ *         A previous version of this file used a more sophisticated algorithm
+ *      (by Fiala and Greene) which is guaranteed to run in linear amortized
+ *      time, but has a larger average cost, uses more memory and is patented.
+ *      However the F&G algorithm may be faster for some highly redundant
+ *      files if the parameter max_chain_length (described below) is too large.
+ *
+ *  ACKNOWLEDGEMENTS
+ *
+ *      The idea of lazy evaluation of matches is due to Jan-Mark Wams, and
+ *      I found it in 'freeze' written by Leonid Broukhis.
+ *      Thanks to many people for bug reports and testing.
+ *
+ *  REFERENCES
+ *
+ *      Deutsch, L.P.,"DEFLATE Compressed Data Format Specification".
+ *      Available in http://tools.ietf.org/html/rfc1951
+ *
+ *      A description of the Rabin and Karp algorithm is given in the book
+ *         "Algorithms" by R. Sedgewick, Addison-Wesley, p252.
+ *
+ *      Fiala,E.R., and Greene,D.H.
+ *         Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595
+ *
+ */
+
+/* @(#) $Id$ */
+
+#include "deflate.h"
+
+const char deflate_copyright[] =
+   " deflate 1.2.8 Copyright 1995-2013 Jean-loup Gailly and Mark Adler ";
+/*
+  If you use the zlib library in a product, an acknowledgment is welcome
+  in the documentation of your product. If for some reason you cannot
+  include such an acknowledgment, I would appreciate that you keep this
+  copyright string in the executable of your product.
+ */
+
+/* ===========================================================================
+ *  Function prototypes.
+ */
+typedef enum {
+    need_more,      /* block not completed, need more input or more output */
+    block_done,     /* block flush performed */
+    finish_started, /* finish started, need only more output at next deflate */
+    finish_done     /* finish done, accept no more input or output */
+} block_state;
+
+typedef block_state (*compress_func) OF((deflate_state *s, int flush));
+/* Compression function. Returns the block state after the call. */
+
+local void fill_window    OF((deflate_state *s));
+local block_state deflate_stored OF((deflate_state *s, int flush));
+local block_state deflate_fast   OF((deflate_state *s, int flush));
+#ifndef FASTEST
+local block_state deflate_slow   OF((deflate_state *s, int flush));
+#endif
+local block_state deflate_rle    OF((deflate_state *s, int flush));
+local block_state deflate_huff   OF((deflate_state *s, int flush));
+local void lm_init        OF((deflate_state *s));
+local void putShortMSB    OF((deflate_state *s, uInt b));
+local void flush_pending  OF((z_streamp strm));
+local int read_buf        OF((z_streamp strm, Bytef *buf, unsigned size));
+#ifdef ASMV
+      void match_init OF((void)); /* asm code initialization */
+      uInt longest_match  OF((deflate_state *s, IPos cur_match));
+#else
+local uInt longest_match  OF((deflate_state *s, IPos cur_match));
+#endif
+
+#ifdef DEBUG
+local  void check_match OF((deflate_state *s, IPos start, IPos match,
+                            int length));
+#endif
+
+/* ===========================================================================
+ * Local data
+ */
+
+#define NIL 0
+/* Tail of hash chains */
+
+#ifndef TOO_FAR
+#  define TOO_FAR 4096
+#endif
+/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */
+
+/* Values for max_lazy_match, good_match and max_chain_length, depending on
+ * the desired pack level (0..9). The values given below have been tuned to
+ * exclude worst case performance for pathological files. Better values may be
+ * found for specific files.
+ */
+typedef struct config_s {
+   ush good_length; /* reduce lazy search above this match length */
+   ush max_lazy;    /* do not perform lazy search above this match length */
+   ush nice_length; /* quit search above this match length */
+   ush max_chain;
+   compress_func func;
+} config;
+
+#ifdef FASTEST
+local const config configuration_table[2] = {
+/*      good lazy nice chain */
+/* 0 */ {0,    0,  0,    0, deflate_stored},  /* store only */
+/* 1 */ {4,    4,  8,    4, deflate_fast}}; /* max speed, no lazy matches */
+#else
+local const config configuration_table[10] = {
+/*      good lazy nice chain */
+/* 0 */ {0,    0,  0,    0, deflate_stored},  /* store only */
+/* 1 */ {4,    4,  8,    4, deflate_fast}, /* max speed, no lazy matches */
+/* 2 */ {4,    5, 16,    8, deflate_fast},
+/* 3 */ {4,    6, 32,   32, deflate_fast},
+
+/* 4 */ {4,    4, 16,   16, deflate_slow},  /* lazy matches */
+/* 5 */ {8,   16, 32,   32, deflate_slow},
+/* 6 */ {8,   16, 128, 128, deflate_slow},
+/* 7 */ {8,   32, 128, 256, deflate_slow},
+/* 8 */ {32, 128, 258, 1024, deflate_slow},
+/* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* max compression */
+#endif
+
+/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4
+ * For deflate_fast() (levels <= 3) good is ignored and lazy has a different
+ * meaning.
+ */
+
+#define EQUAL 0
+/* result of memcmp for equal strings */
+
+#ifndef NO_DUMMY_DECL
+struct static_tree_desc_s {int dummy;}; /* for buggy compilers */
+#endif
+
+/* rank Z_BLOCK between Z_NO_FLUSH and Z_PARTIAL_FLUSH */
+#define RANK(f) (((f) << 1) - ((f) > 4 ? 9 : 0))
+
+/* ===========================================================================
+ * Update a hash value with the given input byte
+ * IN  assertion: all calls to to UPDATE_HASH are made with consecutive
+ *    input characters, so that a running hash key can be computed from the
+ *    previous key instead of complete recalculation each time.
+ */
+#define UPDATE_HASH(s,h,c) (h = (((h)<<s->hash_shift) ^ (c)) & s->hash_mask)
+
+
+/* ===========================================================================
+ * Insert string str in the dictionary and set match_head to the previous head
+ * of the hash chain (the most recent string with same hash key). Return
+ * the previous length of the hash chain.
+ * If this file is compiled with -DFASTEST, the compression level is forced
+ * to 1, and no hash chains are maintained.
+ * IN  assertion: all calls to to INSERT_STRING are made with consecutive
+ *    input characters and the first MIN_MATCH bytes of str are valid
+ *    (except for the last MIN_MATCH-1 bytes of the input file).
+ */
+#ifdef FASTEST
+#define INSERT_STRING(s, str, match_head) \
+   (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
+    match_head = s->head[s->ins_h], \
+    s->head[s->ins_h] = (Pos)(str))
+#else
+#define INSERT_STRING(s, str, match_head) \
+   (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
+    match_head = s->prev[(str) & s->w_mask] = s->head[s->ins_h], \
+    s->head[s->ins_h] = (Pos)(str))
+#endif
+
+/* ===========================================================================
+ * Initialize the hash table (avoiding 64K overflow for 16 bit systems).
+ * prev[] will be initialized on the fly.
+ */
+#define CLEAR_HASH(s) \
+    s->head[s->hash_size-1] = NIL; \
+    zmemzero((Bytef *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head));
+
+/* ========================================================================= */
+int ZEXPORT deflateInit_(strm, level, version, stream_size)
+    z_streamp strm;
+    int level;
+    const char *version;
+    int stream_size;
+{
+    return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL,
+                         Z_DEFAULT_STRATEGY, version, stream_size);
+    /* To do: ignore strm->next_in if we use it as window */
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
+                  version, stream_size)
+    z_streamp strm;
+    int  level;
+    int  method;
+    int  windowBits;
+    int  memLevel;
+    int  strategy;
+    const char *version;
+    int stream_size;
+{
+    deflate_state *s;
+    int wrap = 1;
+    static const char my_version[] = ZLIB_VERSION;
+
+    ushf *overlay;
+    /* We overlay pending_buf and d_buf+l_buf. This works since the average
+     * output size for (length,distance) codes is <= 24 bits.
+     */
+
+    if (version == Z_NULL || version[0] != my_version[0] ||
+        stream_size != sizeof(z_stream)) {
+        return Z_VERSION_ERROR;
+    }
+    if (strm == Z_NULL) return Z_STREAM_ERROR;
+
+    strm->msg = Z_NULL;
+    if (strm->zalloc == (alloc_func)0) {
+#ifdef Z_SOLO
+        return Z_STREAM_ERROR;
+#else
+        strm->zalloc = zcalloc;
+        strm->opaque = (voidpf)0;
+#endif
+    }
+    if (strm->zfree == (free_func)0)
+#ifdef Z_SOLO
+        return Z_STREAM_ERROR;
+#else
+        strm->zfree = zcfree;
+#endif
+
+#ifdef FASTEST
+    if (level != 0) level = 1;
+#else
+    if (level == Z_DEFAULT_COMPRESSION) level = 6;
+#endif
+
+    if (windowBits < 0) { /* suppress zlib wrapper */
+        wrap = 0;
+        windowBits = -windowBits;
+    }
+#ifdef GZIP
+    else if (windowBits > 15) {
+        wrap = 2;       /* write gzip wrapper instead */
+        windowBits -= 16;
+    }
+#endif
+    if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED ||
+        windowBits < 8 || windowBits > 15 || level < 0 || level > 9 ||
+        strategy < 0 || strategy > Z_FIXED) {
+        return Z_STREAM_ERROR;
+    }
+    if (windowBits == 8) windowBits = 9;  /* until 256-byte window bug fixed */
+    s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state));
+    if (s == Z_NULL) return Z_MEM_ERROR;
+    strm->state = (struct internal_state FAR *)s;
+    s->strm = strm;
+
+    s->wrap = wrap;
+    s->gzhead = Z_NULL;
+    s->w_bits = windowBits;
+    s->w_size = 1 << s->w_bits;
+    s->w_mask = s->w_size - 1;
+
+    s->hash_bits = memLevel + 7;
+    s->hash_size = 1 << s->hash_bits;
+    s->hash_mask = s->hash_size - 1;
+    s->hash_shift =  ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH);
+
+    s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte));
+    s->prev   = (Posf *)  ZALLOC(strm, s->w_size, sizeof(Pos));
+    s->head   = (Posf *)  ZALLOC(strm, s->hash_size, sizeof(Pos));
+
+    s->high_water = 0;      /* nothing written to s->window yet */
+
+    s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */
+
+    overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2);
+    s->pending_buf = (uchf *) overlay;
+    s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L);
+
+    if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL ||
+        s->pending_buf == Z_NULL) {
+        s->status = FINISH_STATE;
+        strm->msg = ERR_MSG(Z_MEM_ERROR);
+        deflateEnd (strm);
+        return Z_MEM_ERROR;
+    }
+    s->d_buf = overlay + s->lit_bufsize/sizeof(ush);
+    s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize;
+
+    s->level = level;
+    s->strategy = strategy;
+    s->method = (Byte)method;
+
+    return deflateReset(strm);
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength)
+    z_streamp strm;
+    const Bytef *dictionary;
+    uInt  dictLength;
+{
+    deflate_state *s;
+    uInt str, n;
+    int wrap;
+    unsigned avail;
+    z_const unsigned char *next;
+
+    if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL)
+        return Z_STREAM_ERROR;
+    s = strm->state;
+    wrap = s->wrap;
+    if (wrap == 2 || (wrap == 1 && s->status != INIT_STATE) || s->lookahead)
+        return Z_STREAM_ERROR;
+
+    /* when using zlib wrappers, compute Adler-32 for provided dictionary */
+    if (wrap == 1)
+        strm->adler = adler32(strm->adler, dictionary, dictLength);
+    s->wrap = 0;                    /* avoid computing Adler-32 in read_buf */
+
+    /* if dictionary would fill window, just replace the history */
+    if (dictLength >= s->w_size) {
+        if (wrap == 0) {            /* already empty otherwise */
+            CLEAR_HASH(s);
+            s->strstart = 0;
+            s->block_start = 0L;
+            s->insert = 0;
+        }
+        dictionary += dictLength - s->w_size;  /* use the tail */
+        dictLength = s->w_size;
+    }
+
+    /* insert dictionary into window and hash */
+    avail = strm->avail_in;
+    next = strm->next_in;
+    strm->avail_in = dictLength;
+    strm->next_in = (z_const Bytef *)dictionary;
+    fill_window(s);
+    while (s->lookahead >= MIN_MATCH) {
+        str = s->strstart;
+        n = s->lookahead - (MIN_MATCH-1);
+        do {
+            UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]);
+#ifndef FASTEST
+            s->prev[str & s->w_mask] = s->head[s->ins_h];
+#endif
+            s->head[s->ins_h] = (Pos)str;
+            str++;
+        } while (--n);
+        s->strstart = str;
+        s->lookahead = MIN_MATCH-1;
+        fill_window(s);
+    }
+    s->strstart += s->lookahead;
+    s->block_start = (long)s->strstart;
+    s->insert = s->lookahead;
+    s->lookahead = 0;
+    s->match_length = s->prev_length = MIN_MATCH-1;
+    s->match_available = 0;
+    strm->next_in = next;
+    strm->avail_in = avail;
+    s->wrap = wrap;
+    return Z_OK;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateResetKeep (strm)
+    z_streamp strm;
+{
+    deflate_state *s;
+
+    if (strm == Z_NULL || strm->state == Z_NULL ||
+        strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0) {
+        return Z_STREAM_ERROR;
+    }
+
+    strm->total_in = strm->total_out = 0;
+    strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */
+    strm->data_type = Z_UNKNOWN;
+
+    s = (deflate_state *)strm->state;
+    s->pending = 0;
+    s->pending_out = s->pending_buf;
+
+    if (s->wrap < 0) {
+        s->wrap = -s->wrap; /* was made negative by deflate(..., Z_FINISH); */
+    }
+    s->status = s->wrap ? INIT_STATE : BUSY_STATE;
+    strm->adler =
+#ifdef GZIP
+        s->wrap == 2 ? crc32(0L, Z_NULL, 0) :
+#endif
+        adler32(0L, Z_NULL, 0);
+    s->last_flush = Z_NO_FLUSH;
+
+    _tr_init(s);
+
+    return Z_OK;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateReset (strm)
+    z_streamp strm;
+{
+    int ret;
+
+    ret = deflateResetKeep(strm);
+    if (ret == Z_OK)
+        lm_init(strm->state);
+    return ret;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateSetHeader (strm, head)
+    z_streamp strm;
+    gz_headerp head;
+{
+    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+    if (strm->state->wrap != 2) return Z_STREAM_ERROR;
+    strm->state->gzhead = head;
+    return Z_OK;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflatePending (strm, pending, bits)
+    unsigned *pending;
+    int *bits;
+    z_streamp strm;
+{
+    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+    if (pending != Z_NULL)
+        *pending = strm->state->pending;
+    if (bits != Z_NULL)
+        *bits = strm->state->bi_valid;
+    return Z_OK;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflatePrime (strm, bits, value)
+    z_streamp strm;
+    int bits;
+    int value;
+{
+    deflate_state *s;
+    int put;
+
+    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+    s = strm->state;
+    if ((Bytef *)(s->d_buf) < s->pending_out + ((Buf_size + 7) >> 3))
+        return Z_BUF_ERROR;
+    do {
+        put = Buf_size - s->bi_valid;
+        if (put > bits)
+            put = bits;
+        s->bi_buf |= (ush)((value & ((1 << put) - 1)) << s->bi_valid);
+        s->bi_valid += put;
+        _tr_flush_bits(s);
+        value >>= put;
+        bits -= put;
+    } while (bits);
+    return Z_OK;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateParams(strm, level, strategy)
+    z_streamp strm;
+    int level;
+    int strategy;
+{
+    deflate_state *s;
+    compress_func func;
+    int err = Z_OK;
+
+    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+    s = strm->state;
+
+#ifdef FASTEST
+    if (level != 0) level = 1;
+#else
+    if (level == Z_DEFAULT_COMPRESSION) level = 6;
+#endif
+    if (level < 0 || level > 9 || strategy < 0 || strategy > Z_FIXED) {
+        return Z_STREAM_ERROR;
+    }
+    func = configuration_table[s->level].func;
+
+    if ((strategy != s->strategy || func != configuration_table[level].func) &&
+        strm->total_in != 0) {
+        /* Flush the last buffer: */
+        err = deflate(strm, Z_BLOCK);
+        if (err == Z_BUF_ERROR && s->pending == 0)
+            err = Z_OK;
+    }
+    if (s->level != level) {
+        s->level = level;
+        s->max_lazy_match   = configuration_table[level].max_lazy;
+        s->good_match       = configuration_table[level].good_length;
+        s->nice_match       = configuration_table[level].nice_length;
+        s->max_chain_length = configuration_table[level].max_chain;
+    }
+    s->strategy = strategy;
+    return err;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateTune(strm, good_length, max_lazy, nice_length, max_chain)
+    z_streamp strm;
+    int good_length;
+    int max_lazy;
+    int nice_length;
+    int max_chain;
+{
+    deflate_state *s;
+
+    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+    s = strm->state;
+    s->good_match = good_length;
+    s->max_lazy_match = max_lazy;
+    s->nice_match = nice_length;
+    s->max_chain_length = max_chain;
+    return Z_OK;
+}
+
+/* =========================================================================
+ * For the default windowBits of 15 and memLevel of 8, this function returns
+ * a close to exact, as well as small, upper bound on the compressed size.
+ * They are coded as constants here for a reason--if the #define's are
+ * changed, then this function needs to be changed as well.  The return
+ * value for 15 and 8 only works for those exact settings.
+ *
+ * For any setting other than those defaults for windowBits and memLevel,
+ * the value returned is a conservative worst case for the maximum expansion
+ * resulting from using fixed blocks instead of stored blocks, which deflate
+ * can emit on compressed data for some combinations of the parameters.
+ *
+ * This function could be more sophisticated to provide closer upper bounds for
+ * every combination of windowBits and memLevel.  But even the conservative
+ * upper bound of about 14% expansion does not seem onerous for output buffer
+ * allocation.
+ */
+uLong ZEXPORT deflateBound(strm, sourceLen)
+    z_streamp strm;
+    uLong sourceLen;
+{
+    deflate_state *s;
+    uLong complen, wraplen;
+    Bytef *str;
+
+    /* conservative upper bound for compressed data */
+    complen = sourceLen +
+              ((sourceLen + 7) >> 3) + ((sourceLen + 63) >> 6) + 5;
+
+    /* if can't get parameters, return conservative bound plus zlib wrapper */
+    if (strm == Z_NULL || strm->state == Z_NULL)
+        return complen + 6;
+
+    /* compute wrapper length */
+    s = strm->state;
+    switch (s->wrap) {
+    case 0:                                 /* raw deflate */
+        wraplen = 0;
+        break;
+    case 1:                                 /* zlib wrapper */
+        wraplen = 6 + (s->strstart ? 4 : 0);
+        break;
+    case 2:                                 /* gzip wrapper */
+        wraplen = 18;
+        if (s->gzhead != Z_NULL) {          /* user-supplied gzip header */
+            if (s->gzhead->extra != Z_NULL)
+                wraplen += 2 + s->gzhead->extra_len;
+            str = s->gzhead->name;
+            if (str != Z_NULL)
+                do {
+                    wraplen++;
+                } while (*str++);
+            str = s->gzhead->comment;
+            if (str != Z_NULL)
+                do {
+                    wraplen++;
+                } while (*str++);
+            if (s->gzhead->hcrc)
+                wraplen += 2;
+        }
+        break;
+    default:                                /* for compiler happiness */
+        wraplen = 6;
+    }
+
+    /* if not default parameters, return conservative bound */
+    if (s->w_bits != 15 || s->hash_bits != 8 + 7)
+        return complen + wraplen;
+
+    /* default settings: return tight bound for that case */
+    return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) +
+           (sourceLen >> 25) + 13 - 6 + wraplen;
+}
+
+/* =========================================================================
+ * Put a short in the pending buffer. The 16-bit value is put in MSB order.
+ * IN assertion: the stream state is correct and there is enough room in
+ * pending_buf.
+ */
+local void putShortMSB (s, b)
+    deflate_state *s;
+    uInt b;
+{
+    put_byte(s, (Byte)(b >> 8));
+    put_byte(s, (Byte)(b & 0xff));
+}
+
+/* =========================================================================
+ * Flush as much pending output as possible. All deflate() output goes
+ * through this function so some applications may wish to modify it
+ * to avoid allocating a large strm->next_out buffer and copying into it.
+ * (See also read_buf()).
+ */
+local void flush_pending(strm)
+    z_streamp strm;
+{
+    unsigned len;
+    deflate_state *s = strm->state;
+
+    _tr_flush_bits(s);
+    len = s->pending;
+    if (len > strm->avail_out) len = strm->avail_out;
+    if (len == 0) return;
+
+    zmemcpy(strm->next_out, s->pending_out, len);
+    strm->next_out  += len;
+    s->pending_out  += len;
+    strm->total_out += len;
+    strm->avail_out  -= len;
+    s->pending -= len;
+    if (s->pending == 0) {
+        s->pending_out = s->pending_buf;
+    }
+}
+
+/* ========================================================================= */
+int ZEXPORT deflate (strm, flush)
+    z_streamp strm;
+    int flush;
+{
+    int old_flush; /* value of flush param for previous deflate call */
+    deflate_state *s;
+
+    if (strm == Z_NULL || strm->state == Z_NULL ||
+        flush > Z_BLOCK || flush < 0) {
+        return Z_STREAM_ERROR;
+    }
+    s = strm->state;
+
+    if (strm->next_out == Z_NULL ||
+        (strm->next_in == Z_NULL && strm->avail_in != 0) ||
+        (s->status == FINISH_STATE && flush != Z_FINISH)) {
+        ERR_RETURN(strm, Z_STREAM_ERROR);
+    }
+    if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR);
+
+    s->strm = strm; /* just in case */
+    old_flush = s->last_flush;
+    s->last_flush = flush;
+
+    /* Write the header */
+    if (s->status == INIT_STATE) {
+#ifdef GZIP
+        if (s->wrap == 2) {
+            strm->adler = crc32(0L, Z_NULL, 0);
+            put_byte(s, 31);
+            put_byte(s, 139);
+            put_byte(s, 8);
+            if (s->gzhead == Z_NULL) {
+                put_byte(s, 0);
+                put_byte(s, 0);
+                put_byte(s, 0);
+                put_byte(s, 0);
+                put_byte(s, 0);
+                put_byte(s, s->level == 9 ? 2 :
+                            (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ?
+                             4 : 0));
+                put_byte(s, OS_CODE);
+                s->status = BUSY_STATE;
+            }
+            else {
+                put_byte(s, (s->gzhead->text ? 1 : 0) +
+                            (s->gzhead->hcrc ? 2 : 0) +
+                            (s->gzhead->extra == Z_NULL ? 0 : 4) +
+                            (s->gzhead->name == Z_NULL ? 0 : 8) +
+                            (s->gzhead->comment == Z_NULL ? 0 : 16)
+                        );
+                put_byte(s, (Byte)(s->gzhead->time & 0xff));
+                put_byte(s, (Byte)((s->gzhead->time >> 8) & 0xff));
+                put_byte(s, (Byte)((s->gzhead->time >> 16) & 0xff));
+                put_byte(s, (Byte)((s->gzhead->time >> 24) & 0xff));
+                put_byte(s, s->level == 9 ? 2 :
+                            (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ?
+                             4 : 0));
+                put_byte(s, s->gzhead->os & 0xff);
+                if (s->gzhead->extra != Z_NULL) {
+                    put_byte(s, s->gzhead->extra_len & 0xff);
+                    put_byte(s, (s->gzhead->extra_len >> 8) & 0xff);
+                }
+                if (s->gzhead->hcrc)
+                    strm->adler = crc32(strm->adler, s->pending_buf,
+                                        s->pending);
+                s->gzindex = 0;
+                s->status = EXTRA_STATE;
+            }
+        }
+        else
+#endif
+        {
+            uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8;
+            uInt level_flags;
+
+            if (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2)
+                level_flags = 0;
+            else if (s->level < 6)
+                level_flags = 1;
+            else if (s->level == 6)
+                level_flags = 2;
+            else
+                level_flags = 3;
+            header |= (level_flags << 6);
+            if (s->strstart != 0) header |= PRESET_DICT;
+            header += 31 - (header % 31);
+
+            s->status = BUSY_STATE;
+            putShortMSB(s, header);
+
+            /* Save the adler32 of the preset dictionary: */
+            if (s->strstart != 0) {
+                putShortMSB(s, (uInt)(strm->adler >> 16));
+                putShortMSB(s, (uInt)(strm->adler & 0xffff));
+            }
+            strm->adler = adler32(0L, Z_NULL, 0);
+        }
+    }
+#ifdef GZIP
+    if (s->status == EXTRA_STATE) {
+        if (s->gzhead->extra != Z_NULL) {
+            uInt beg = s->pending;  /* start of bytes to update crc */
+
+            while (s->gzindex < (s->gzhead->extra_len & 0xffff)) {
+                if (s->pending == s->pending_buf_size) {
+                    if (s->gzhead->hcrc && s->pending > beg)
+                        strm->adler = crc32(strm->adler, s->pending_buf + beg,
+                                            s->pending - beg);
+                    flush_pending(strm);
+                    beg = s->pending;
+                    if (s->pending == s->pending_buf_size)
+                        break;
+                }
+                put_byte(s, s->gzhead->extra[s->gzindex]);
+                s->gzindex++;
+            }
+            if (s->gzhead->hcrc && s->pending > beg)
+                strm->adler = crc32(strm->adler, s->pending_buf + beg,
+                                    s->pending - beg);
+            if (s->gzindex == s->gzhead->extra_len) {
+                s->gzindex = 0;
+                s->status = NAME_STATE;
+            }
+        }
+        else
+            s->status = NAME_STATE;
+    }
+    if (s->status == NAME_STATE) {
+        if (s->gzhead->name != Z_NULL) {
+            uInt beg = s->pending;  /* start of bytes to update crc */
+            int val;
+
+            do {
+                if (s->pending == s->pending_buf_size) {
+                    if (s->gzhead->hcrc && s->pending > beg)
+                        strm->adler = crc32(strm->adler, s->pending_buf + beg,
+                                            s->pending - beg);
+                    flush_pending(strm);
+                    beg = s->pending;
+                    if (s->pending == s->pending_buf_size) {
+                        val = 1;
+                        break;
+                    }
+                }
+                val = s->gzhead->name[s->gzindex++];
+                put_byte(s, val);
+            } while (val != 0);
+            if (s->gzhead->hcrc && s->pending > beg)
+                strm->adler = crc32(strm->adler, s->pending_buf + beg,
+                                    s->pending - beg);
+            if (val == 0) {
+                s->gzindex = 0;
+                s->status = COMMENT_STATE;
+            }
+        }
+        else
+            s->status = COMMENT_STATE;
+    }
+    if (s->status == COMMENT_STATE) {
+        if (s->gzhead->comment != Z_NULL) {
+            uInt beg = s->pending;  /* start of bytes to update crc */
+            int val;
+
+            do {
+                if (s->pending == s->pending_buf_size) {
+                    if (s->gzhead->hcrc && s->pending > beg)
+                        strm->adler = crc32(strm->adler, s->pending_buf + beg,
+                                            s->pending - beg);
+                    flush_pending(strm);
+                    beg = s->pending;
+                    if (s->pending == s->pending_buf_size) {
+                        val = 1;
+                        break;
+                    }
+                }
+                val = s->gzhead->comment[s->gzindex++];
+                put_byte(s, val);
+            } while (val != 0);
+            if (s->gzhead->hcrc && s->pending > beg)
+                strm->adler = crc32(strm->adler, s->pending_buf + beg,
+                                    s->pending - beg);
+            if (val == 0)
+                s->status = HCRC_STATE;
+        }
+        else
+            s->status = HCRC_STATE;
+    }
+    if (s->status == HCRC_STATE) {
+        if (s->gzhead->hcrc) {
+            if (s->pending + 2 > s->pending_buf_size)
+                flush_pending(strm);
+            if (s->pending + 2 <= s->pending_buf_size) {
+                put_byte(s, (Byte)(strm->adler & 0xff));
+                put_byte(s, (Byte)((strm->adler >> 8) & 0xff));
+                strm->adler = crc32(0L, Z_NULL, 0);
+                s->status = BUSY_STATE;
+            }
+        }
+        else
+            s->status = BUSY_STATE;
+    }
+#endif
+
+    /* Flush as much pending output as possible */
+    if (s->pending != 0) {
+        flush_pending(strm);
+        if (strm->avail_out == 0) {
+            /* Since avail_out is 0, deflate will be called again with
+             * more output space, but possibly with both pending and
+             * avail_in equal to zero. There won't be anything to do,
+             * but this is not an error situation so make sure we
+             * return OK instead of BUF_ERROR at next call of deflate:
+             */
+            s->last_flush = -1;
+            return Z_OK;
+        }
+
+    /* Make sure there is something to do and avoid duplicate consecutive
+     * flushes. For repeated and useless calls with Z_FINISH, we keep
+     * returning Z_STREAM_END instead of Z_BUF_ERROR.
+     */
+    } else if (strm->avail_in == 0 && RANK(flush) <= RANK(old_flush) &&
+               flush != Z_FINISH) {
+        ERR_RETURN(strm, Z_BUF_ERROR);
+    }
+
+    /* User must not provide more input after the first FINISH: */
+    if (s->status == FINISH_STATE && strm->avail_in != 0) {
+        ERR_RETURN(strm, Z_BUF_ERROR);
+    }
+
+    /* Start a new block or continue the current one.
+     */
+    if (strm->avail_in != 0 || s->lookahead != 0 ||
+        (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) {
+        block_state bstate;
+
+        bstate = s->strategy == Z_HUFFMAN_ONLY ? deflate_huff(s, flush) :
+                    (s->strategy == Z_RLE ? deflate_rle(s, flush) :
+                        (*(configuration_table[s->level].func))(s, flush));
+
+        if (bstate == finish_started || bstate == finish_done) {
+            s->status = FINISH_STATE;
+        }
+        if (bstate == need_more || bstate == finish_started) {
+            if (strm->avail_out == 0) {
+                s->last_flush = -1; /* avoid BUF_ERROR next call, see above */
+            }
+            return Z_OK;
+            /* If flush != Z_NO_FLUSH && avail_out == 0, the next call
+             * of deflate should use the same flush parameter to make sure
+             * that the flush is complete. So we don't have to output an
+             * empty block here, this will be done at next call. This also
+             * ensures that for a very small output buffer, we emit at most
+             * one empty block.
+             */
+        }
+        if (bstate == block_done) {
+            if (flush == Z_PARTIAL_FLUSH) {
+                _tr_align(s);
+            } else if (flush != Z_BLOCK) { /* FULL_FLUSH or SYNC_FLUSH */
+                _tr_stored_block(s, (char*)0, 0L, 0);
+                /* For a full flush, this empty block will be recognized
+                 * as a special marker by inflate_sync().
+                 */
+                if (flush == Z_FULL_FLUSH) {
+                    CLEAR_HASH(s);             /* forget history */
+                    if (s->lookahead == 0) {
+                        s->strstart = 0;
+                        s->block_start = 0L;
+                        s->insert = 0;
+                    }
+                }
+            }
+            flush_pending(strm);
+            if (strm->avail_out == 0) {
+              s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */
+              return Z_OK;
+            }
+        }
+    }
+    Assert(strm->avail_out > 0, "bug2");
+
+    if (flush != Z_FINISH) return Z_OK;
+    if (s->wrap <= 0) return Z_STREAM_END;
+
+    /* Write the trailer */
+#ifdef GZIP
+    if (s->wrap == 2) {
+        put_byte(s, (Byte)(strm->adler & 0xff));
+        put_byte(s, (Byte)((strm->adler >> 8) & 0xff));
+        put_byte(s, (Byte)((strm->adler >> 16) & 0xff));
+        put_byte(s, (Byte)((strm->adler >> 24) & 0xff));
+        put_byte(s, (Byte)(strm->total_in & 0xff));
+        put_byte(s, (Byte)((strm->total_in >> 8) & 0xff));
+        put_byte(s, (Byte)((strm->total_in >> 16) & 0xff));
+        put_byte(s, (Byte)((strm->total_in >> 24) & 0xff));
+    }
+    else
+#endif
+    {
+        putShortMSB(s, (uInt)(strm->adler >> 16));
+        putShortMSB(s, (uInt)(strm->adler & 0xffff));
+    }
+    flush_pending(strm);
+    /* If avail_out is zero, the application will call deflate again
+     * to flush the rest.
+     */
+    if (s->wrap > 0) s->wrap = -s->wrap; /* write the trailer only once! */
+    return s->pending != 0 ? Z_OK : Z_STREAM_END;
+}
+
+/* ========================================================================= */
+int ZEXPORT deflateEnd (strm)
+    z_streamp strm;
+{
+    int status;
+
+    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+
+    status = strm->state->status;
+    if (status != INIT_STATE &&
+        status != EXTRA_STATE &&
+        status != NAME_STATE &&
+        status != COMMENT_STATE &&
+        status != HCRC_STATE &&
+        status != BUSY_STATE &&
+        status != FINISH_STATE) {
+      return Z_STREAM_ERROR;
+    }
+
+    /* Deallocate in reverse order of allocations: */
+    TRY_FREE(strm, strm->state->pending_buf);
+    TRY_FREE(strm, strm->state->head);
+    TRY_FREE(strm, strm->state->prev);
+    TRY_FREE(strm, strm->state->window);
+
+    ZFREE(strm, strm->state);
+    strm->state = Z_NULL;
+
+    return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK;
+}
+
+/* =========================================================================
+ * Copy the source state to the destination state.
+ * To simplify the source, this is not supported for 16-bit MSDOS (which
+ * doesn't have enough memory anyway to duplicate compression states).
+ */
+int ZEXPORT deflateCopy (dest, source)
+    z_streamp dest;
+    z_streamp source;
+{
+#ifdef MAXSEG_64K
+    return Z_STREAM_ERROR;
+#else
+    deflate_state *ds;
+    deflate_state *ss;
+    ushf *overlay;
+
+
+    if (source == Z_NULL || dest == Z_NULL || source->state == Z_NULL) {
+        return Z_STREAM_ERROR;
+    }
+
+    ss = source->state;
+
+    zmemcpy((voidpf)dest, (voidpf)source, sizeof(z_stream));
+
+    ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state));
+    if (ds == Z_NULL) return Z_MEM_ERROR;
+    dest->state = (struct internal_state FAR *) ds;
+    zmemcpy((voidpf)ds, (voidpf)ss, sizeof(deflate_state));
+    ds->strm = dest;
+
+    ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte));
+    ds->prev   = (Posf *)  ZALLOC(dest, ds->w_size, sizeof(Pos));
+    ds->head   = (Posf *)  ZALLOC(dest, ds->hash_size, sizeof(Pos));
+    overlay = (ushf *) ZALLOC(dest, ds->lit_bufsize, sizeof(ush)+2);
+    ds->pending_buf = (uchf *) overlay;
+
+    if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL ||
+        ds->pending_buf == Z_NULL) {
+        deflateEnd (dest);
+        return Z_MEM_ERROR;
+    }
+    /* following zmemcpy do not work for 16-bit MSDOS */
+    zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte));
+    zmemcpy((voidpf)ds->prev, (voidpf)ss->prev, ds->w_size * sizeof(Pos));
+    zmemcpy((voidpf)ds->head, (voidpf)ss->head, ds->hash_size * sizeof(Pos));
+    zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size);
+
+    ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf);
+    ds->d_buf = overlay + ds->lit_bufsize/sizeof(ush);
+    ds->l_buf = ds->pending_buf + (1+sizeof(ush))*ds->lit_bufsize;
+
+    ds->l_desc.dyn_tree = ds->dyn_ltree;
+    ds->d_desc.dyn_tree = ds->dyn_dtree;
+    ds->bl_desc.dyn_tree = ds->bl_tree;
+
+    return Z_OK;
+#endif /* MAXSEG_64K */
+}
+
+/* ===========================================================================
+ * Read a new buffer from the current input stream, update the adler32
+ * and total number of bytes read.  All deflate() input goes through
+ * this function so some applications may wish to modify it to avoid
+ * allocating a large strm->next_in buffer and copying from it.
+ * (See also flush_pending()).
+ */
+local int read_buf(strm, buf, size)
+    z_streamp strm;
+    Bytef *buf;
+    unsigned size;
+{
+    unsigned len = strm->avail_in;
+
+    if (len > size) len = size;
+    if (len == 0) return 0;
+
+    strm->avail_in  -= len;
+
+    zmemcpy(buf, strm->next_in, len);
+    if (strm->state->wrap == 1) {
+        strm->adler = adler32(strm->adler, buf, len);
+    }
+#ifdef GZIP
+    else if (strm->state->wrap == 2) {
+        strm->adler = crc32(strm->adler, buf, len);
+    }
+#endif
+    strm->next_in  += len;
+    strm->total_in += len;
+
+    return (int)len;
+}
+
+/* ===========================================================================
+ * Initialize the "longest match" routines for a new zlib stream
+ */
+local void lm_init (s)
+    deflate_state *s;
+{
+    s->window_size = (ulg)2L*s->w_size;
+
+    CLEAR_HASH(s);
+
+    /* Set the default configuration parameters:
+     */
+    s->max_lazy_match   = configuration_table[s->level].max_lazy;
+    s->good_match       = configuration_table[s->level].good_length;
+    s->nice_match       = configuration_table[s->level].nice_length;
+    s->max_chain_length = configuration_table[s->level].max_chain;
+
+    s->strstart = 0;
+    s->block_start = 0L;
+    s->lookahead = 0;
+    s->insert = 0;
+    s->match_length = s->prev_length = MIN_MATCH-1;
+    s->match_available = 0;
+    s->ins_h = 0;
+#ifndef FASTEST
+#ifdef ASMV
+    match_init(); /* initialize the asm code */
+#endif
+#endif
+}
+
+#ifndef FASTEST
+/* ===========================================================================
+ * Set match_start to the longest match starting at the given string and
+ * return its length. Matches shorter or equal to prev_length are discarded,
+ * in which case the result is equal to prev_length and match_start is
+ * garbage.
+ * IN assertions: cur_match is the head of the hash chain for the current
+ *   string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1
+ * OUT assertion: the match length is not greater than s->lookahead.
+ */
+#ifndef ASMV
+/* For 80x86 and 680x0, an optimized version will be provided in match.asm or
+ * match.S. The code will be functionally equivalent.
+ */
+local uInt longest_match(s, cur_match)
+    deflate_state *s;
+    IPos cur_match;                             /* current match */
+{
+    unsigned chain_length = s->max_chain_length;/* max hash chain length */
+    register Bytef *scan = s->window + s->strstart; /* current string */
+    register Bytef *match;                       /* matched string */
+    register int len;                           /* length of current match */
+    int best_len = s->prev_length;              /* best match length so far */
+    int nice_match = s->nice_match;             /* stop if match long enough */
+    IPos limit = s->strstart > (IPos)MAX_DIST(s) ?
+        s->strstart - (IPos)MAX_DIST(s) : NIL;
+    /* Stop when cur_match becomes <= limit. To simplify the code,
+     * we prevent matches with the string of window index 0.
+     */
+    Posf *prev = s->prev;
+    uInt wmask = s->w_mask;
+
+#ifdef UNALIGNED_OK
+    /* Compare two bytes at a time. Note: this is not always beneficial.
+     * Try with and without -DUNALIGNED_OK to check.
+     */
+    register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1;
+    register ush scan_start = *(ushf*)scan;
+    register ush scan_end   = *(ushf*)(scan+best_len-1);
+#else
+    register Bytef *strend = s->window + s->strstart + MAX_MATCH;
+    register Byte scan_end1  = scan[best_len-1];
+    register Byte scan_end   = scan[best_len];
+#endif
+
+    /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
+     * It is easy to get rid of this optimization if necessary.
+     */
+    Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
+
+    /* Do not waste too much time if we already have a good match: */
+    if (s->prev_length >= s->good_match) {
+        chain_length >>= 2;
+    }
+    /* Do not look for matches beyond the end of the input. This is necessary
+     * to make deflate deterministic.
+     */
+    if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;
+
+    Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
+
+    do {
+        Assert(cur_match < s->strstart, "no future");
+        match = s->window + cur_match;
+
+        /* Skip to next match if the match length cannot increase
+         * or if the match length is less than 2.  Note that the checks below
+         * for insufficient lookahead only occur occasionally for performance
+         * reasons.  Therefore uninitialized memory will be accessed, and
+         * conditional jumps will be made that depend on those values.
+         * However the length of the match is limited to the lookahead, so
+         * the output of deflate is not affected by the uninitialized values.
+         */
+#if (defined(UNALIGNED_OK) && MAX_MATCH == 258)
+        /* This code assumes sizeof(unsigned short) == 2. Do not use
+         * UNALIGNED_OK if your compiler uses a different size.
+         */
+        if (*(ushf*)(match+best_len-1) != scan_end ||
+            *(ushf*)match != scan_start) continue;
+
+        /* It is not necessary to compare scan[2] and match[2] since they are
+         * always equal when the other bytes match, given that the hash keys
+         * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at
+         * strstart+3, +5, ... up to strstart+257. We check for insufficient
+         * lookahead only every 4th comparison; the 128th check will be made
+         * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is
+         * necessary to put more guard bytes at the end of the window, or
+         * to check more often for insufficient lookahead.
+         */
+        Assert(scan[2] == match[2], "scan[2]?");
+        scan++, match++;
+        do {
+        } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
+                 *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
+                 *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
+                 *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
+                 scan < strend);
+        /* The funny "do {}" generates better code on most compilers */
+
+        /* Here, scan <= window+strstart+257 */
+        Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
+        if (*scan == *match) scan++;
+
+        len = (MAX_MATCH - 1) - (int)(strend-scan);
+        scan = strend - (MAX_MATCH-1);
+
+#else /* UNALIGNED_OK */
+
+        if (match[best_len]   != scan_end  ||
+            match[best_len-1] != scan_end1 ||
+            *match            != *scan     ||
+            *++match          != scan[1])      continue;
+
+        /* The check at best_len-1 can be removed because it will be made
+         * again later. (This heuristic is not always a win.)
+         * It is not necessary to compare scan[2] and match[2] since they
+         * are always equal when the other bytes match, given that
+         * the hash keys are equal and that HASH_BITS >= 8.
+         */
+        scan += 2, match++;
+        Assert(*scan == *match, "match[2]?");
+
+        /* We check for insufficient lookahead only every 8th comparison;
+         * the 256th check will be made at strstart+258.
+         */
+        do {
+        } while (*++scan == *++match && *++scan == *++match &&
+                 *++scan == *++match && *++scan == *++match &&
+                 *++scan == *++match && *++scan == *++match &&
+                 *++scan == *++match && *++scan == *++match &&
+                 scan < strend);
+
+        Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
+
+        len = MAX_MATCH - (int)(strend - scan);
+        scan = strend - MAX_MATCH;
+
+#endif /* UNALIGNED_OK */
+
+        if (len > best_len) {
+            s->match_start = cur_match;
+            best_len = len;
+            if (len >= nice_match) break;
+#ifdef UNALIGNED_OK
+            scan_end = *(ushf*)(scan+best_len-1);
+#else
+            scan_end1  = scan[best_len-1];
+            scan_end   = scan[best_len];
+#endif
+        }
+    } while ((cur_match = prev[cur_match & wmask]) > limit
+             && --chain_length != 0);
+
+    if ((uInt)best_len <= s->lookahead) return (uInt)best_len;
+    return s->lookahead;
+}
+#endif /* ASMV */
+
+#else /* FASTEST */
+
+/* ---------------------------------------------------------------------------
+ * Optimized version for FASTEST only
+ */
+local uInt longest_match(s, cur_match)
+    deflate_state *s;
+    IPos cur_match;                             /* current match */
+{
+    register Bytef *scan = s->window + s->strstart; /* current string */
+    register Bytef *match;                       /* matched string */
+    register int len;                           /* length of current match */
+    register Bytef *strend = s->window + s->strstart + MAX_MATCH;
+
+    /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
+     * It is easy to get rid of this optimization if necessary.
+     */
+    Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
+
+    Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
+
+    Assert(cur_match < s->strstart, "no future");
+
+    match = s->window + cur_match;
+
+    /* Return failure if the match length is less than 2:
+     */
+    if (match[0] != scan[0] || match[1] != scan[1]) return MIN_MATCH-1;
+
+    /* The check at best_len-1 can be removed because it will be made
+     * again later. (This heuristic is not always a win.)
+     * It is not necessary to compare scan[2] and match[2] since they
+     * are always equal when the other bytes match, given that
+     * the hash keys are equal and that HASH_BITS >= 8.
+     */
+    scan += 2, match += 2;
+    Assert(*scan == *match, "match[2]?");
+
+    /* We check for insufficient lookahead only every 8th comparison;
+     * the 256th check will be made at strstart+258.
+     */
+    do {
+    } while (*++scan == *++match && *++scan == *++match &&
+             *++scan == *++match && *++scan == *++match &&
+             *++scan == *++match && *++scan == *++match &&
+             *++scan == *++match && *++scan == *++match &&
+             scan < strend);
+
+    Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
+
+    len = MAX_MATCH - (int)(strend - scan);
+
+    if (len < MIN_MATCH) return MIN_MATCH - 1;
+
+    s->match_start = cur_match;
+    return (uInt)len <= s->lookahead ? (uInt)len : s->lookahead;
+}
+
+#endif /* FASTEST */
+
+#ifdef DEBUG
+/* ===========================================================================
+ * Check that the match at match_start is indeed a match.
+ */
+local void check_match(s, start, match, length)
+    deflate_state *s;
+    IPos start, match;
+    int length;
+{
+    /* check that the match is indeed a match */
+    if (zmemcmp(s->window + match,
+                s->window + start, length) != EQUAL) {
+        fprintf(stderr, " start %u, match %u, length %d\n",
+                start, match, length);
+        do {
+            fprintf(stderr, "%c%c", s->window[match++], s->window[start++]);
+        } while (--length != 0);
+        z_error("invalid match");
+    }
+    if (z_verbose > 1) {
+        fprintf(stderr,"\\[%d,%d]", start-match, length);
+        do { putc(s->window[start++], stderr); } while (--length != 0);
+    }
+}
+#else
+#  define check_match(s, start, match, length)
+#endif /* DEBUG */
+
+/* ===========================================================================
+ * Fill the window when the lookahead becomes insufficient.
+ * Updates strstart and lookahead.
+ *
+ * IN assertion: lookahead < MIN_LOOKAHEAD
+ * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD
+ *    At least one byte has been read, or avail_in == 0; reads are
+ *    performed for at least two bytes (required for the zip translate_eol
+ *    option -- not supported here).
+ */
+local void fill_window(s)
+    deflate_state *s;
+{
+    register unsigned n, m;
+    register Posf *p;
+    unsigned more;    /* Amount of free space at the end of the window. */
+    uInt wsize = s->w_size;
+
+    Assert(s->lookahead < MIN_LOOKAHEAD, "already enough lookahead");
+
+    do {
+        more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart);
+
+        /* Deal with !@#$% 64K limit: */
+        if (sizeof(int) <= 2) {
+            if (more == 0 && s->strstart == 0 && s->lookahead == 0) {
+                more = wsize;
+
+            } else if (more == (unsigned)(-1)) {
+                /* Very unlikely, but possible on 16 bit machine if
+                 * strstart == 0 && lookahead == 1 (input done a byte at time)
+                 */
+                more--;
+            }
+        }
+
+        /* If the window is almost full and there is insufficient lookahead,
+         * move the upper half to the lower one to make room in the upper half.
+         */
+        if (s->strstart >= wsize+MAX_DIST(s)) {
+
+            zmemcpy(s->window, s->window+wsize, (unsigned)wsize);
+            s->match_start -= wsize;
+            s->strstart    -= wsize; /* we now have strstart >= MAX_DIST */
+            s->block_start -= (long) wsize;
+
+            /* Slide the hash table (could be avoided with 32 bit values
+               at the expense of memory usage). We slide even when level == 0
+               to keep the hash table consistent if we switch back to level > 0
+               later. (Using level 0 permanently is not an optimal usage of
+               zlib, so we don't care about this pathological case.)
+             */
+            n = s->hash_size;
+            p = &s->head[n];
+            do {
+                m = *--p;
+                *p = (Pos)(m >= wsize ? m-wsize : NIL);
+            } while (--n);
+
+            n = wsize;
+#ifndef FASTEST
+            p = &s->prev[n];
+            do {
+                m = *--p;
+                *p = (Pos)(m >= wsize ? m-wsize : NIL);
+                /* If n is not on any hash chain, prev[n] is garbage but
+                 * its value will never be used.
+                 */
+            } while (--n);
+#endif
+            more += wsize;
+        }
+        if (s->strm->avail_in == 0) break;
+
+        /* If there was no sliding:
+         *    strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 &&
+         *    more == window_size - lookahead - strstart
+         * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1)
+         * => more >= window_size - 2*WSIZE + 2
+         * In the BIG_MEM or MMAP case (not yet supported),
+         *   window_size == input_size + MIN_LOOKAHEAD  &&
+         *   strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD.
+         * Otherwise, window_size == 2*WSIZE so more >= 2.
+         * If there was sliding, more >= WSIZE. So in all cases, more >= 2.
+         */
+        Assert(more >= 2, "more < 2");
+
+        n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more);
+        s->lookahead += n;
+
+        /* Initialize the hash value now that we have some input: */
+        if (s->lookahead + s->insert >= MIN_MATCH) {
+            uInt str = s->strstart - s->insert;
+            s->ins_h = s->window[str];
+            UPDATE_HASH(s, s->ins_h, s->window[str + 1]);
+#if MIN_MATCH != 3
+            Call UPDATE_HASH() MIN_MATCH-3 more times
+#endif
+            while (s->insert) {
+                UPDATE_HASH(s, s->ins_h, s->window[str + MIN_MATCH-1]);
+#ifndef FASTEST
+                s->prev[str & s->w_mask] = s->head[s->ins_h];
+#endif
+                s->head[s->ins_h] = (Pos)str;
+                str++;
+                s->insert--;
+                if (s->lookahead + s->insert < MIN_MATCH)
+                    break;
+            }
+        }
+        /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage,
+         * but this is not important since only literal bytes will be emitted.
+         */
+
+    } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0);
+
+    /* If the WIN_INIT bytes after the end of the current data have never been
+     * written, then zero those bytes in order to avoid memory check reports of
+     * the use of uninitialized (or uninitialised as Julian writes) bytes by
+     * the longest match routines.  Update the high water mark for the next
+     * time through here.  WIN_INIT is set to MAX_MATCH since the longest match
+     * routines allow scanning to strstart + MAX_MATCH, ignoring lookahead.
+     */
+    if (s->high_water < s->window_size) {
+        ulg curr = s->strstart + (ulg)(s->lookahead);
+        ulg init;
+
+        if (s->high_water < curr) {
+            /* Previous high water mark below current data -- zero WIN_INIT
+             * bytes or up to end of window, whichever is less.
+             */
+            init = s->window_size - curr;
+            if (init > WIN_INIT)
+                init = WIN_INIT;
+            zmemzero(s->window + curr, (unsigned)init);
+            s->high_water = curr + init;
+        }
+        else if (s->high_water < (ulg)curr + WIN_INIT) {
+            /* High water mark at or above current data, but below current data
+             * plus WIN_INIT -- zero out to current data plus WIN_INIT, or up
+             * to end of window, whichever is less.
+             */
+            init = (ulg)curr + WIN_INIT - s->high_water;
+            if (init > s->window_size - s->high_water)
+                init = s->window_size - s->high_water;
+            zmemzero(s->window + s->high_water, (unsigned)init);
+            s->high_water += init;
+        }
+    }
+
+    Assert((ulg)s->strstart <= s->window_size - MIN_LOOKAHEAD,
+           "not enough room for search");
+}
+
+/* ===========================================================================
+ * Flush the current block, with given end-of-file flag.
+ * IN assertion: strstart is set to the end of the current match.
+ */
+#define FLUSH_BLOCK_ONLY(s, last) { \
+   _tr_flush_block(s, (s->block_start >= 0L ? \
+                   (charf *)&s->window[(unsigned)s->block_start] : \
+                   (charf *)Z_NULL), \
+                (ulg)((long)s->strstart - s->block_start), \
+                (last)); \
+   s->block_start = s->strstart; \
+   flush_pending(s->strm); \
+   Tracev((stderr,"[FLUSH]")); \
+}
+
+/* Same but force premature exit if necessary. */
+#define FLUSH_BLOCK(s, last) { \
+   FLUSH_BLOCK_ONLY(s, last); \
+   if (s->strm->avail_out == 0) return (last) ? finish_started : need_more; \
+}
+
+/* ===========================================================================
+ * Copy without compression as much as possible from the input stream, return
+ * the current block state.
+ * This function does not insert new strings in the dictionary since
+ * uncompressible data is probably not useful. This function is used
+ * only for the level=0 compression option.
+ * NOTE: this function should be optimized to avoid extra copying from
+ * window to pending_buf.
+ */
+local block_state deflate_stored(s, flush)
+    deflate_state *s;
+    int flush;
+{
+    /* Stored blocks are limited to 0xffff bytes, pending_buf is limited
+     * to pending_buf_size, and each stored block has a 5 byte header:
+     */
+    ulg max_block_size = 0xffff;
+    ulg max_start;
+
+    if (max_block_size > s->pending_buf_size - 5) {
+        max_block_size = s->pending_buf_size - 5;
+    }
+
+    /* Copy as much as possible from input to output: */
+    for (;;) {
+        /* Fill the window as much as possible: */
+        if (s->lookahead <= 1) {
+
+            Assert(s->strstart < s->w_size+MAX_DIST(s) ||
+                   s->block_start >= (long)s->w_size, "slide too late");
+
+            fill_window(s);
+            if (s->lookahead == 0 && flush == Z_NO_FLUSH) return need_more;
+
+            if (s->lookahead == 0) break; /* flush the current block */
+        }
+        Assert(s->block_start >= 0L, "block gone");
+
+        s->strstart += s->lookahead;
+        s->lookahead = 0;
+
+        /* Emit a stored block if pending_buf will be full: */
+        max_start = s->block_start + max_block_size;
+        if (s->strstart == 0 || (ulg)s->strstart >= max_start) {
+            /* strstart == 0 is possible when wraparound on 16-bit machine */
+            s->lookahead = (uInt)(s->strstart - max_start);
+            s->strstart = (uInt)max_start;
+            FLUSH_BLOCK(s, 0);
+        }
+        /* Flush if we may have to slide, otherwise block_start may become
+         * negative and the data will be gone:
+         */
+        if (s->strstart - (uInt)s->block_start >= MAX_DIST(s)) {
+            FLUSH_BLOCK(s, 0);
+        }
+    }
+    s->insert = 0;
+    if (flush == Z_FINISH) {
+        FLUSH_BLOCK(s, 1);
+        return finish_done;
+    }
+    if ((long)s->strstart > s->block_start)
+        FLUSH_BLOCK(s, 0);
+    return block_done;
+}
+
+/* ===========================================================================
+ * Compress as much as possible from the input stream, return the current
+ * block state.
+ * This function does not perform lazy evaluation of matches and inserts
+ * new strings in the dictionary only for unmatched strings or for short
+ * matches. It is used only for the fast compression options.
+ */
+local block_state deflate_fast(s, flush)
+    deflate_state *s;
+    int flush;
+{
+    IPos hash_head;       /* head of the hash chain */
+    int bflush;           /* set if current block must be flushed */
+
+    for (;;) {
+        /* Make sure that we always have enough lookahead, except
+         * at the end of the input file. We need MAX_MATCH bytes
+         * for the next match, plus MIN_MATCH bytes to insert the
+         * string following the next match.
+         */
+        if (s->lookahead < MIN_LOOKAHEAD) {
+            fill_window(s);
+            if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
+                return need_more;
+            }
+            if (s->lookahead == 0) break; /* flush the current block */
+        }
+
+        /* Insert the string window[strstart .. strstart+2] in the
+         * dictionary, and set hash_head to the head of the hash chain:
+         */
+        hash_head = NIL;
+        if (s->lookahead >= MIN_MATCH) {
+            INSERT_STRING(s, s->strstart, hash_head);
+        }
+
+        /* Find the longest match, discarding those <= prev_length.
+         * At this point we have always match_length < MIN_MATCH
+         */
+        if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) {
+            /* To simplify the code, we prevent matches with the string
+             * of window index 0 (in particular we have to avoid a match
+             * of the string with itself at the start of the input file).
+             */
+            s->match_length = longest_match (s, hash_head);
+            /* longest_match() sets match_start */
+        }
+        if (s->match_length >= MIN_MATCH) {
+            check_match(s, s->strstart, s->match_start, s->match_length);
+
+            _tr_tally_dist(s, s->strstart - s->match_start,
+                           s->match_length - MIN_MATCH, bflush);
+
+            s->lookahead -= s->match_length;
+
+            /* Insert new strings in the hash table only if the match length
+             * is not too large. This saves time but degrades compression.
+             */
+#ifndef FASTEST
+            if (s->match_length <= s->max_insert_length &&
+                s->lookahead >= MIN_MATCH) {
+                s->match_length--; /* string at strstart already in table */
+                do {
+                    s->strstart++;
+                    INSERT_STRING(s, s->strstart, hash_head);
+                    /* strstart never exceeds WSIZE-MAX_MATCH, so there are
+                     * always MIN_MATCH bytes ahead.
+                     */
+                } while (--s->match_length != 0);
+                s->strstart++;
+            } else
+#endif
+            {
+                s->strstart += s->match_length;
+                s->match_length = 0;
+                s->ins_h = s->window[s->strstart];
+                UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]);
+#if MIN_MATCH != 3
+                Call UPDATE_HASH() MIN_MATCH-3 more times
+#endif
+                /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not
+                 * matter since it will be recomputed at next deflate call.
+                 */
+            }
+        } else {
+            /* No match, output a literal byte */
+            Tracevv((stderr,"%c", s->window[s->strstart]));
+            _tr_tally_lit (s, s->window[s->strstart], bflush);
+            s->lookahead--;
+            s->strstart++;
+        }
+        if (bflush) FLUSH_BLOCK(s, 0);
+    }
+    s->insert = s->strstart < MIN_MATCH-1 ? s->strstart : MIN_MATCH-1;
+    if (flush == Z_FINISH) {
+        FLUSH_BLOCK(s, 1);
+        return finish_done;
+    }
+    if (s->last_lit)
+        FLUSH_BLOCK(s, 0);
+    return block_done;
+}
+
+#ifndef FASTEST
+/* ===========================================================================
+ * Same as above, but achieves better compression. We use a lazy
+ * evaluation for matches: a match is finally adopted only if there is
+ * no better match at the next window position.
+ */
+local block_state deflate_slow(s, flush)
+    deflate_state *s;
+    int flush;
+{
+    IPos hash_head;          /* head of hash chain */
+    int bflush;              /* set if current block must be flushed */
+
+    /* Process the input block. */
+    for (;;) {
+        /* Make sure that we always have enough lookahead, except
+         * at the end of the input file. We need MAX_MATCH bytes
+         * for the next match, plus MIN_MATCH bytes to insert the
+         * string following the next match.
+         */
+        if (s->lookahead < MIN_LOOKAHEAD) {
+            fill_window(s);
+            if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
+                return need_more;
+            }
+            if (s->lookahead == 0) break; /* flush the current block */
+        }
+
+        /* Insert the string window[strstart .. strstart+2] in the
+         * dictionary, and set hash_head to the head of the hash chain:
+         */
+        hash_head = NIL;
+        if (s->lookahead >= MIN_MATCH) {
+            INSERT_STRING(s, s->strstart, hash_head);
+        }
+
+        /* Find the longest match, discarding those <= prev_length.
+         */
+        s->prev_length = s->match_length, s->prev_match = s->match_start;
+        s->match_length = MIN_MATCH-1;
+
+        if (hash_head != NIL && s->prev_length < s->max_lazy_match &&
+            s->strstart - hash_head <= MAX_DIST(s)) {
+            /* To simplify the code, we prevent matches with the string
+             * of window index 0 (in particular we have to avoid a match
+             * of the string with itself at the start of the input file).
+             */
+            s->match_length = longest_match (s, hash_head);
+            /* longest_match() sets match_start */
+
+            if (s->match_length <= 5 && (s->strategy == Z_FILTERED
+#if TOO_FAR <= 32767
+                || (s->match_length == MIN_MATCH &&
+                    s->strstart - s->match_start > TOO_FAR)
+#endif
+                )) {
+
+                /* If prev_match is also MIN_MATCH, match_start is garbage
+                 * but we will ignore the current match anyway.
+                 */
+                s->match_length = MIN_MATCH-1;
+            }
+        }
+        /* If there was a match at the previous step and the current
+         * match is not better, output the previous match:
+         */
+        if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) {
+            uInt max_insert = s->strstart + s->lookahead - MIN_MATCH;
+            /* Do not insert strings in hash table beyond this. */
+
+            check_match(s, s->strstart-1, s->prev_match, s->prev_length);
+
+            _tr_tally_dist(s, s->strstart -1 - s->prev_match,
+                           s->prev_length - MIN_MATCH, bflush);
+
+            /* Insert in hash table all strings up to the end of the match.
+             * strstart-1 and strstart are already inserted. If there is not
+             * enough lookahead, the last two strings are not inserted in
+             * the hash table.
+             */
+            s->lookahead -= s->prev_length-1;
+            s->prev_length -= 2;
+            do {
+                if (++s->strstart <= max_insert) {
+                    INSERT_STRING(s, s->strstart, hash_head);
+                }
+            } while (--s->prev_length != 0);
+            s->match_available = 0;
+            s->match_length = MIN_MATCH-1;
+            s->strstart++;
+
+            if (bflush) FLUSH_BLOCK(s, 0);
+
+        } else if (s->match_available) {
+            /* If there was no match at the previous position, output a
+             * single literal. If there was a match but the current match
+             * is longer, truncate the previous match to a single literal.
+             */
+            Tracevv((stderr,"%c", s->window[s->strstart-1]));
+            _tr_tally_lit(s, s->window[s->strstart-1], bflush);
+            if (bflush) {
+                FLUSH_BLOCK_ONLY(s, 0);
+            }
+            s->strstart++;
+            s->lookahead--;
+            if (s->strm->avail_out == 0) return need_more;
+        } else {
+            /* There is no previous match to compare with, wait for
+             * the next step to decide.
+             */
+            s->match_available = 1;
+            s->strstart++;
+            s->lookahead--;
+        }
+    }
+    Assert (flush != Z_NO_FLUSH, "no flush?");
+    if (s->match_available) {
+        Tracevv((stderr,"%c", s->window[s->strstart-1]));
+        _tr_tally_lit(s, s->window[s->strstart-1], bflush);
+        s->match_available = 0;
+    }
+    s->insert = s->strstart < MIN_MATCH-1 ? s->strstart : MIN_MATCH-1;
+    if (flush == Z_FINISH) {
+        FLUSH_BLOCK(s, 1);
+        return finish_done;
+    }
+    if (s->last_lit)
+        FLUSH_BLOCK(s, 0);
+    return block_done;
+}
+#endif /* FASTEST */
+
+/* ===========================================================================
+ * For Z_RLE, simply look for runs of bytes, generate matches only of distance
+ * one.  Do not maintain a hash table.  (It will be regenerated if this run of
+ * deflate switches away from Z_RLE.)
+ */
+local block_state deflate_rle(s, flush)
+    deflate_state *s;
+    int flush;
+{
+    int bflush;             /* set if current block must be flushed */
+    uInt prev;              /* byte at distance one to match */
+    Bytef *scan, *strend;   /* scan goes up to strend for length of run */
+
+    for (;;) {
+        /* Make sure that we always have enough lookahead, except
+         * at the end of the input file. We need MAX_MATCH bytes
+         * for the longest run, plus one for the unrolled loop.
+         */
+        if (s->lookahead <= MAX_MATCH) {
+            fill_window(s);
+            if (s->lookahead <= MAX_MATCH && flush == Z_NO_FLUSH) {
+                return need_more;
+            }
+            if (s->lookahead == 0) break; /* flush the current block */
+        }
+
+        /* See how many times the previous byte repeats */
+        s->match_length = 0;
+        if (s->lookahead >= MIN_MATCH && s->strstart > 0) {
+            scan = s->window + s->strstart - 1;
+            prev = *scan;
+            if (prev == *++scan && prev == *++scan && prev == *++scan) {
+                strend = s->window + s->strstart + MAX_MATCH;
+                do {
+                } while (prev == *++scan && prev == *++scan &&
+                         prev == *++scan && prev == *++scan &&
+                         prev == *++scan && prev == *++scan &&
+                         prev == *++scan && prev == *++scan &&
+                         scan < strend);
+                s->match_length = MAX_MATCH - (int)(strend - scan);
+                if (s->match_length > s->lookahead)
+                    s->match_length = s->lookahead;
+            }
+            Assert(scan <= s->window+(uInt)(s->window_size-1), "wild scan");
+        }
+
+        /* Emit match if have run of MIN_MATCH or longer, else emit literal */
+        if (s->match_length >= MIN_MATCH) {
+            check_match(s, s->strstart, s->strstart - 1, s->match_length);
+
+            _tr_tally_dist(s, 1, s->match_length - MIN_MATCH, bflush);
+
+            s->lookahead -= s->match_length;
+            s->strstart += s->match_length;
+            s->match_length = 0;
+        } else {
+            /* No match, output a literal byte */
+            Tracevv((stderr,"%c", s->window[s->strstart]));
+            _tr_tally_lit (s, s->window[s->strstart], bflush);
+            s->lookahead--;
+            s->strstart++;
+        }
+        if (bflush) FLUSH_BLOCK(s, 0);
+    }
+    s->insert = 0;
+    if (flush == Z_FINISH) {
+        FLUSH_BLOCK(s, 1);
+        return finish_done;
+    }
+    if (s->last_lit)
+        FLUSH_BLOCK(s, 0);
+    return block_done;
+}
+
+/* ===========================================================================
+ * For Z_HUFFMAN_ONLY, do not look for matches.  Do not maintain a hash table.
+ * (It will be regenerated if this run of deflate switches away from Huffman.)
+ */
+local block_state deflate_huff(s, flush)
+    deflate_state *s;
+    int flush;
+{
+    int bflush;             /* set if current block must be flushed */
+
+    for (;;) {
+        /* Make sure that we have a literal to write. */
+        if (s->lookahead == 0) {
+            fill_window(s);
+            if (s->lookahead == 0) {
+                if (flush == Z_NO_FLUSH)
+                    return need_more;
+                break;      /* flush the current block */
+            }
+        }
+
+        /* Output a literal byte */
+        s->match_length = 0;
+        Tracevv((stderr,"%c", s->window[s->strstart]));
+        _tr_tally_lit (s, s->window[s->strstart], bflush);
+        s->lookahead--;
+        s->strstart++;
+        if (bflush) FLUSH_BLOCK(s, 0);
+    }
+    s->insert = 0;
+    if (flush == Z_FINISH) {
+        FLUSH_BLOCK(s, 1);
+        return finish_done;
+    }
+    if (s->last_lit)
+        FLUSH_BLOCK(s, 0);
+    return block_done;
+}
diff --git a/compat/zlib/deflate.h b/compat/zlib/deflate.h
new file mode 100644
index 0000000..ce0299e
--- /dev/null
+++ b/compat/zlib/deflate.h
@@ -0,0 +1,346 @@
+/* deflate.h -- internal compression state
+ * Copyright (C) 1995-2012 Jean-loup Gailly
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+   part of the implementation of the compression library and is
+   subject to change. Applications should only use zlib.h.
+ */
+
+/* @(#) $Id$ */
+
+#ifndef DEFLATE_H
+#define DEFLATE_H
+
+#include "zutil.h"
+
+/* define NO_GZIP when compiling if you want to disable gzip header and
+   trailer creation by deflate().  NO_GZIP would be used to avoid linking in
+   the crc code when it is not needed.  For shared libraries, gzip encoding
+   should be left enabled. */
+#ifndef NO_GZIP
+#  define GZIP
+#endif
+
+/* ===========================================================================
+ * Internal compression state.
+ */
+
+#define LENGTH_CODES 29
+/* number of length codes, not counting the special END_BLOCK code */
+
+#define LITERALS  256
+/* number of literal bytes 0..255 */
+
+#define L_CODES (LITERALS+1+LENGTH_CODES)
+/* number of Literal or Length codes, including the END_BLOCK code */
+
+#define D_CODES   30
+/* number of distance codes */
+
+#define BL_CODES  19
+/* number of codes used to transfer the bit lengths */
+
+#define HEAP_SIZE (2*L_CODES+1)
+/* maximum heap size */
+
+#define MAX_BITS 15
+/* All codes must not exceed MAX_BITS bits */
+
+#define Buf_size 16
+/* size of bit buffer in bi_buf */
+
+#define INIT_STATE    42
+#define EXTRA_STATE   69
+#define NAME_STATE    73
+#define COMMENT_STATE 91
+#define HCRC_STATE   103
+#define BUSY_STATE   113
+#define FINISH_STATE 666
+/* Stream status */
+
+
+/* Data structure describing a single value and its code string. */
+typedef struct ct_data_s {
+    union {
+        ush  freq;       /* frequency count */
+        ush  code;       /* bit string */
+    } fc;
+    union {
+        ush  dad;        /* father node in Huffman tree */
+        ush  len;        /* length of bit string */
+    } dl;
+} FAR ct_data;
+
+#define Freq fc.freq
+#define Code fc.code
+#define Dad  dl.dad
+#define Len  dl.len
+
+typedef struct static_tree_desc_s  static_tree_desc;
+
+typedef struct tree_desc_s {
+    ct_data *dyn_tree;           /* the dynamic tree */
+    int     max_code;            /* largest code with non zero frequency */
+    static_tree_desc *stat_desc; /* the corresponding static tree */
+} FAR tree_desc;
+
+typedef ush Pos;
+typedef Pos FAR Posf;
+typedef unsigned IPos;
+
+/* A Pos is an index in the character window. We use short instead of int to
+ * save space in the various tables. IPos is used only for parameter passing.
+ */
+
+typedef struct internal_state {
+    z_streamp strm;      /* pointer back to this zlib stream */
+    int   status;        /* as the name implies */
+    Bytef *pending_buf;  /* output still pending */
+    ulg   pending_buf_size; /* size of pending_buf */
+    Bytef *pending_out;  /* next pending byte to output to the stream */
+    uInt   pending;      /* nb of bytes in the pending buffer */
+    int   wrap;          /* bit 0 true for zlib, bit 1 true for gzip */
+    gz_headerp  gzhead;  /* gzip header information to write */
+    uInt   gzindex;      /* where in extra, name, or comment */
+    Byte  method;        /* can only be DEFLATED */
+    int   last_flush;    /* value of flush param for previous deflate call */
+
+                /* used by deflate.c: */
+
+    uInt  w_size;        /* LZ77 window size (32K by default) */
+    uInt  w_bits;        /* log2(w_size)  (8..16) */
+    uInt  w_mask;        /* w_size - 1 */
+
+    Bytef *window;
+    /* Sliding window. Input bytes are read into the second half of the window,
+     * and move to the first half later to keep a dictionary of at least wSize
+     * bytes. With this organization, matches are limited to a distance of
+     * wSize-MAX_MATCH bytes, but this ensures that IO is always
+     * performed with a length multiple of the block size. Also, it limits
+     * the window size to 64K, which is quite useful on MSDOS.
+     * To do: use the user input buffer as sliding window.
+     */
+
+    ulg window_size;
+    /* Actual size of window: 2*wSize, except when the user input buffer
+     * is directly used as sliding window.
+     */
+
+    Posf *prev;
+    /* Link to older string with same hash index. To limit the size of this
+     * array to 64K, this link is maintained only for the last 32K strings.
+     * An index in this array is thus a window index modulo 32K.
+     */
+
+    Posf *head; /* Heads of the hash chains or NIL. */
+
+    uInt  ins_h;          /* hash index of string to be inserted */
+    uInt  hash_size;      /* number of elements in hash table */
+    uInt  hash_bits;      /* log2(hash_size) */
+    uInt  hash_mask;      /* hash_size-1 */
+
+    uInt  hash_shift;
+    /* Number of bits by which ins_h must be shifted at each input
+     * step. It must be such that after MIN_MATCH steps, the oldest
+     * byte no longer takes part in the hash key, that is:
+     *   hash_shift * MIN_MATCH >= hash_bits
+     */
+
+    long block_start;
+    /* Window position at the beginning of the current output block. Gets
+     * negative when the window is moved backwards.
+     */
+
+    uInt match_length;           /* length of best match */
+    IPos prev_match;             /* previous match */
+    int match_available;         /* set if previous match exists */
+    uInt strstart;               /* start of string to insert */
+    uInt match_start;            /* start of matching string */
+    uInt lookahead;              /* number of valid bytes ahead in window */
+
+    uInt prev_length;
+    /* Length of the best match at previous step. Matches not greater than this
+     * are discarded. This is used in the lazy match evaluation.
+     */
+
+    uInt max_chain_length;
+    /* To speed up deflation, hash chains are never searched beyond this
+     * length.  A higher limit improves compression ratio but degrades the
+     * speed.
+     */
+
+    uInt max_lazy_match;
+    /* Attempt to find a better match only when the current match is strictly
+     * smaller than this value. This mechanism is used only for compression
+     * levels >= 4.
+     */
+#   define max_insert_length  max_lazy_match
+    /* Insert new strings in the hash table only if the match length is not
+     * greater than this length. This saves time but degrades compression.
+     * max_insert_length is used only for compression levels <= 3.
+     */
+
+    int level;    /* compression level (1..9) */
+    int strategy; /* favor or force Huffman coding*/
+
+    uInt good_match;
+    /* Use a faster search when the previous match is longer than this */
+
+    int nice_match; /* Stop searching when current match exceeds this */
+
+                /* used by trees.c: */
+    /* Didn't use ct_data typedef below to suppress compiler warning */
+    struct ct_data_s dyn_ltree[HEAP_SIZE];   /* literal and length tree */
+    struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */
+    struct ct_data_s bl_tree[2*BL_CODES+1];  /* Huffman tree for bit lengths */
+
+    struct tree_desc_s l_desc;               /* desc. for literal tree */
+    struct tree_desc_s d_desc;               /* desc. for distance tree */
+    struct tree_desc_s bl_desc;              /* desc. for bit length tree */
+
+    ush bl_count[MAX_BITS+1];
+    /* number of codes at each bit length for an optimal tree */
+
+    int heap[2*L_CODES+1];      /* heap used to build the Huffman trees */
+    int heap_len;               /* number of elements in the heap */
+    int heap_max;               /* element of largest frequency */
+    /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used.
+     * The same heap array is used to build all trees.
+     */
+
+    uch depth[2*L_CODES+1];
+    /* Depth of each subtree used as tie breaker for trees of equal frequency
+     */
+
+    uchf *l_buf;          /* buffer for literals or lengths */
+
+    uInt  lit_bufsize;
+    /* Size of match buffer for literals/lengths.  There are 4 reasons for
+     * limiting lit_bufsize to 64K:
+     *   - frequencies can be kept in 16 bit counters
+     *   - if compression is not successful for the first block, all input
+     *     data is still in the window so we can still emit a stored block even
+     *     when input comes from standard input.  (This can also be done for
+     *     all blocks if lit_bufsize is not greater than 32K.)
+     *   - if compression is not successful for a file smaller than 64K, we can
+     *     even emit a stored file instead of a stored block (saving 5 bytes).
+     *     This is applicable only for zip (not gzip or zlib).
+     *   - creating new Huffman trees less frequently may not provide fast
+     *     adaptation to changes in the input data statistics. (Take for
+     *     example a binary file with poorly compressible code followed by
+     *     a highly compressible string table.) Smaller buffer sizes give
+     *     fast adaptation but have of course the overhead of transmitting
+     *     trees more frequently.
+     *   - I can't count above 4
+     */
+
+    uInt last_lit;      /* running index in l_buf */
+
+    ushf *d_buf;
+    /* Buffer for distances. To simplify the code, d_buf and l_buf have
+     * the same number of elements. To use different lengths, an extra flag
+     * array would be necessary.
+     */
+
+    ulg opt_len;        /* bit length of current block with optimal trees */
+    ulg static_len;     /* bit length of current block with static trees */
+    uInt matches;       /* number of string matches in current block */
+    uInt insert;        /* bytes at end of window left to insert */
+
+#ifdef DEBUG
+    ulg compressed_len; /* total bit length of compressed file mod 2^32 */
+    ulg bits_sent;      /* bit length of compressed data sent mod 2^32 */
+#endif
+
+    ush bi_buf;
+    /* Output buffer. bits are inserted starting at the bottom (least
+     * significant bits).
+     */
+    int bi_valid;
+    /* Number of valid bits in bi_buf.  All bits above the last valid bit
+     * are always zero.
+     */
+
+    ulg high_water;
+    /* High water mark offset in window for initialized bytes -- bytes above
+     * this are set to zero in order to avoid memory check warnings when
+     * longest match routines access bytes past the input.  This is then
+     * updated to the new high water mark.
+     */
+
+} FAR deflate_state;
+
+/* Output a byte on the stream.
+ * IN assertion: there is enough room in pending_buf.
+ */
+#define put_byte(s, c) {s->pending_buf[s->pending++] = (c);}
+
+
+#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
+/* Minimum amount of lookahead, except at the end of the input file.
+ * See deflate.c for comments about the MIN_MATCH+1.
+ */
+
+#define MAX_DIST(s)  ((s)->w_size-MIN_LOOKAHEAD)
+/* In order to simplify the code, particularly on 16 bit machines, match
+ * distances are limited to MAX_DIST instead of WSIZE.
+ */
+
+#define WIN_INIT MAX_MATCH
+/* Number of bytes after end of data in window to initialize in order to avoid
+   memory checker errors from longest match routines */
+
+        /* in trees.c */
+void ZLIB_INTERNAL _tr_init OF((deflate_state *s));
+int ZLIB_INTERNAL _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc));
+void ZLIB_INTERNAL _tr_flush_block OF((deflate_state *s, charf *buf,
+                        ulg stored_len, int last));
+void ZLIB_INTERNAL _tr_flush_bits OF((deflate_state *s));
+void ZLIB_INTERNAL _tr_align OF((deflate_state *s));
+void ZLIB_INTERNAL _tr_stored_block OF((deflate_state *s, charf *buf,
+                        ulg stored_len, int last));
+
+#define d_code(dist) \
+   ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)])
+/* Mapping from a distance to a distance code. dist is the distance - 1 and
+ * must not have side effects. _dist_code[256] and _dist_code[257] are never
+ * used.
+ */
+
+#ifndef DEBUG
+/* Inline versions of _tr_tally for speed: */
+
+#if defined(GEN_TREES_H) || !defined(STDC)
+  extern uch ZLIB_INTERNAL _length_code[];
+  extern uch ZLIB_INTERNAL _dist_code[];
+#else
+  extern const uch ZLIB_INTERNAL _length_code[];
+  extern const uch ZLIB_INTERNAL _dist_code[];
+#endif
+
+# define _tr_tally_lit(s, c, flush) \
+  { uch cc = (c); \
+    s->d_buf[s->last_lit] = 0; \
+    s->l_buf[s->last_lit++] = cc; \
+    s->dyn_ltree[cc].Freq++; \
+    flush = (s->last_lit == s->lit_bufsize-1); \
+   }
+# define _tr_tally_dist(s, distance, length, flush) \
+  { uch len = (length); \
+    ush dist = (distance); \
+    s->d_buf[s->last_lit] = dist; \
+    s->l_buf[s->last_lit++] = len; \
+    dist--; \
+    s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \
+    s->dyn_dtree[d_code(dist)].Freq++; \
+    flush = (s->last_lit == s->lit_bufsize-1); \
+  }
+#else
+# define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c)
+# define _tr_tally_dist(s, distance, length, flush) \
+              flush = _tr_tally(s, distance, length)
+#endif
+
+#endif /* DEFLATE_H */
diff --git a/compat/zlib/doc/algorithm.txt b/compat/zlib/doc/algorithm.txt
new file mode 100644
index 0000000..c97f495
--- /dev/null
+++ b/compat/zlib/doc/algorithm.txt
@@ -0,0 +1,209 @@
+1. Compression algorithm (deflate)
+
+The deflation algorithm used by gzip (also zip and zlib) is a variation of
+LZ77 (Lempel-Ziv 1977, see reference below). It finds duplicated strings in
+the input data.  The second occurrence of a string is replaced by a
+pointer to the previous string, in the form of a pair (distance,
+length).  Distances are limited to 32K bytes, and lengths are limited
+to 258 bytes. When a string does not occur anywhere in the previous
+32K bytes, it is emitted as a sequence of literal bytes.  (In this
+description, `string' must be taken as an arbitrary sequence of bytes,
+and is not restricted to printable characters.)
+
+Literals or match lengths are compressed with one Huffman tree, and
+match distances are compressed with another tree. The trees are stored
+in a compact form at the start of each block. The blocks can have any
+size (except that the compressed data for one block must fit in
+available memory). A block is terminated when deflate() determines that
+it would be useful to start another block with fresh trees. (This is
+somewhat similar to the behavior of LZW-based _compress_.)
+
+Duplicated strings are found using a hash table. All input strings of
+length 3 are inserted in the hash table. A hash index is computed for
+the next 3 bytes. If the hash chain for this index is not empty, all
+strings in the chain are compared with the current input string, and
+the longest match is selected.
+
+The hash chains are searched starting with the most recent strings, to
+favor small distances and thus take advantage of the Huffman encoding.
+The hash chains are singly linked. There are no deletions from the
+hash chains, the algorithm simply discards matches that are too old.
+
+To avoid a worst-case situation, very long hash chains are arbitrarily
+truncated at a certain length, determined by a runtime option (level
+parameter of deflateInit). So deflate() does not always find the longest
+possible match but generally finds a match which is long enough.
+
+deflate() also defers the selection of matches with a lazy evaluation
+mechanism. After a match of length N has been found, deflate() searches for
+a longer match at the next input byte. If a longer match is found, the
+previous match is truncated to a length of one (thus producing a single
+literal byte) and the process of lazy evaluation begins again. Otherwise,
+the original match is kept, and the next match search is attempted only N
+steps later.
+
+The lazy match evaluation is also subject to a runtime parameter. If
+the current match is long enough, deflate() reduces the search for a longer
+match, thus speeding up the whole process. If compression ratio is more
+important than speed, deflate() attempts a complete second search even if
+the first match is already long enough.
+
+The lazy match evaluation is not performed for the fastest compression
+modes (level parameter 1 to 3). For these fast modes, new strings
+are inserted in the hash table only when no match was found, or
+when the match is not too long. This degrades the compression ratio
+but saves time since there are both fewer insertions and fewer searches.
+
+
+2. Decompression algorithm (inflate)
+
+2.1 Introduction
+
+The key question is how to represent a Huffman code (or any prefix code) so
+that you can decode fast.  The most important characteristic is that shorter
+codes are much more common than longer codes, so pay attention to decoding the
+short codes fast, and let the long codes take longer to decode.
+
+inflate() sets up a first level table that covers some number of bits of
+input less than the length of longest code.  It gets that many bits from the
+stream, and looks it up in the table.  The table will tell if the next
+code is that many bits or less and how many, and if it is, it will tell
+the value, else it will point to the next level table for which inflate()
+grabs more bits and tries to decode a longer code.
+
+How many bits to make the first lookup is a tradeoff between the time it
+takes to decode and the time it takes to build the table.  If building the
+table took no time (and if you had infinite memory), then there would only
+be a first level table to cover all the way to the longest code.  However,
+building the table ends up taking a lot longer for more bits since short
+codes are replicated many times in such a table.  What inflate() does is
+simply to make the number of bits in the first table a variable, and  then
+to set that variable for the maximum speed.
+
+For inflate, which has 286 possible codes for the literal/length tree, the size
+of the first table is nine bits.  Also the distance trees have 30 possible
+values, and the size of the first table is six bits.  Note that for each of
+those cases, the table ended up one bit longer than the ``average'' code
+length, i.e. the code length of an approximately flat code which would be a
+little more than eight bits for 286 symbols and a little less than five bits
+for 30 symbols.
+
+
+2.2 More details on the inflate table lookup
+
+Ok, you want to know what this cleverly obfuscated inflate tree actually
+looks like.  You are correct that it's not a Huffman tree.  It is simply a
+lookup table for the first, let's say, nine bits of a Huffman symbol.  The
+symbol could be as short as one bit or as long as 15 bits.  If a particular
+symbol is shorter than nine bits, then that symbol's translation is duplicated
+in all those entries that start with that symbol's bits.  For example, if the
+symbol is four bits, then it's duplicated 32 times in a nine-bit table.  If a
+symbol is nine bits long, it appears in the table once.
+
+If the symbol is longer than nine bits, then that entry in the table points
+to another similar table for the remaining bits.  Again, there are duplicated
+entries as needed.  The idea is that most of the time the symbol will be short
+and there will only be one table look up.  (That's whole idea behind data
+compression in the first place.)  For the less frequent long symbols, there
+will be two lookups.  If you had a compression method with really long
+symbols, you could have as many levels of lookups as is efficient.  For
+inflate, two is enough.
+
+So a table entry either points to another table (in which case nine bits in
+the above example are gobbled), or it contains the translation for the symbol
+and the number of bits to gobble.  Then you start again with the next
+ungobbled bit.
+
+You may wonder: why not just have one lookup table for how ever many bits the
+longest symbol is?  The reason is that if you do that, you end up spending
+more time filling in duplicate symbol entries than you do actually decoding.
+At least for deflate's output that generates new trees every several 10's of
+kbytes.  You can imagine that filling in a 2^15 entry table for a 15-bit code
+would take too long if you're only decoding several thousand symbols.  At the
+other extreme, you could make a new table for every bit in the code.  In fact,
+that's essentially a Huffman tree.  But then you spend too much time
+traversing the tree while decoding, even for short symbols.
+
+So the number of bits for the first lookup table is a trade of the time to
+fill out the table vs. the time spent looking at the second level and above of
+the table.
+
+Here is an example, scaled down:
+
+The code being decoded, with 10 symbols, from 1 to 6 bits long:
+
+A: 0
+B: 10
+C: 1100
+D: 11010
+E: 11011
+F: 11100
+G: 11101
+H: 11110
+I: 111110
+J: 111111
+
+Let's make the first table three bits long (eight entries):
+
+000: A,1
+001: A,1
+010: A,1
+011: A,1
+100: B,2
+101: B,2
+110: -> table X (gobble 3 bits)
+111: -> table Y (gobble 3 bits)
+
+Each entry is what the bits decode as and how many bits that is, i.e. how
+many bits to gobble.  Or the entry points to another table, with the number of
+bits to gobble implicit in the size of the table.
+
+Table X is two bits long since the longest code starting with 110 is five bits
+long:
+
+00: C,1
+01: C,1
+10: D,2
+11: E,2
+
+Table Y is three bits long since the longest code starting with 111 is six
+bits long:
+
+000: F,2
+001: F,2
+010: G,2
+011: G,2
+100: H,2
+101: H,2
+110: I,3
+111: J,3
+
+So what we have here are three tables with a total of 20 entries that had to
+be constructed.  That's compared to 64 entries for a single table.  Or
+compared to 16 entries for a Huffman tree (six two entry tables and one four
+entry table).  Assuming that the code ideally represents the probability of
+the symbols, it takes on the average 1.25 lookups per symbol.  That's compared
+to one lookup for the single table, or 1.66 lookups per symbol for the
+Huffman tree.
+
+There, I think that gives you a picture of what's going on.  For inflate, the
+meaning of a particular symbol is often more than just a letter.  It can be a
+byte (a "literal"), or it can be either a length or a distance which
+indicates a base value and a number of bits to fetch after the code that is
+added to the base value.  Or it might be the special end-of-block code.  The
+data structures created in inftrees.c try to encode all that information
+compactly in the tables.
+
+
+Jean-loup Gailly        Mark Adler
+jloup@gzip.org          madler@alumni.caltech.edu
+
+
+References:
+
+[LZ77] Ziv J., Lempel A., ``A Universal Algorithm for Sequential Data
+Compression,'' IEEE Transactions on Information Theory, Vol. 23, No. 3,
+pp. 337-343.
+
+``DEFLATE Compressed Data Format Specification'' available in
+http://tools.ietf.org/html/rfc1951
diff --git a/compat/zlib/doc/rfc1950.txt b/compat/zlib/doc/rfc1950.txt
new file mode 100644
index 0000000..ce6428a
--- /dev/null
+++ b/compat/zlib/doc/rfc1950.txt
@@ -0,0 +1,619 @@
+
+
+
+
+
+
+Network Working Group                                         P. Deutsch
+Request for Comments: 1950                           Aladdin Enterprises
+Category: Informational                                      J-L. Gailly
+                                                                Info-ZIP
+                                                                May 1996
+
+
+         ZLIB Compressed Data Format Specification version 3.3
+
+Status of This Memo
+
+   This memo provides information for the Internet community.  This memo
+   does not specify an Internet standard of any kind.  Distribution of
+   this memo is unlimited.
+
+IESG Note:
+
+   The IESG takes no position on the validity of any Intellectual
+   Property Rights statements contained in this document.
+
+Notices
+
+   Copyright (c) 1996 L. Peter Deutsch and Jean-Loup Gailly
+
+   Permission is granted to copy and distribute this document for any
+   purpose and without charge, including translations into other
+   languages and incorporation into compilations, provided that the
+   copyright notice and this notice are preserved, and that any
+   substantive changes or deletions from the original are clearly
+   marked.
+
+   A pointer to the latest version of this and related documentation in
+   HTML format can be found at the URL
+   <ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html>.
+
+Abstract
+
+   This specification defines a lossless compressed data format.  The
+   data can be produced or consumed, even for an arbitrarily long
+   sequentially presented input data stream, using only an a priori
+   bounded amount of intermediate storage.  The format presently uses
+   the DEFLATE compression method but can be easily extended to use
+   other compression methods.  It can be implemented readily in a manner
+   not covered by patents.  This specification also defines the ADLER-32
+   checksum (an extension and improvement of the Fletcher checksum),
+   used for detection of data corruption, and provides an algorithm for
+   computing it.
+
+
+
+
+Deutsch & Gailly             Informational                      [Page 1]
+
+RFC 1950       ZLIB Compressed Data Format Specification        May 1996
+
+
+Table of Contents
+
+   1. Introduction ................................................... 2
+      1.1. Purpose ................................................... 2
+      1.2. Intended audience ......................................... 3
+      1.3. Scope ..................................................... 3
+      1.4. Compliance ................................................ 3
+      1.5.  Definitions of terms and conventions used ................ 3
+      1.6. Changes from previous versions ............................ 3
+   2. Detailed specification ......................................... 3
+      2.1. Overall conventions ....................................... 3
+      2.2. Data format ............................................... 4
+      2.3. Compliance ................................................ 7
+   3. References ..................................................... 7
+   4. Source code .................................................... 8
+   5. Security Considerations ........................................ 8
+   6. Acknowledgements ............................................... 8
+   7. Authors' Addresses ............................................. 8
+   8. Appendix: Rationale ............................................ 9
+   9. Appendix: Sample code ..........................................10
+
+1. Introduction
+
+   1.1. Purpose
+
+      The purpose of this specification is to define a lossless
+      compressed data format that:
+
+          * Is independent of CPU type, operating system, file system,
+            and character set, and hence can be used for interchange;
+
+          * Can be produced or consumed, even for an arbitrarily long
+            sequentially presented input data stream, using only an a
+            priori bounded amount of intermediate storage, and hence can
+            be used in data communications or similar structures such as
+            Unix filters;
+
+          * Can use a number of different compression methods;
+
+          * Can be implemented readily in a manner not covered by
+            patents, and hence can be practiced freely.
+
+      The data format defined by this specification does not attempt to
+      allow random access to compressed data.
+
+
+
+
+
+
+
+Deutsch & Gailly             Informational                      [Page 2]
+
+RFC 1950       ZLIB Compressed Data Format Specification        May 1996
+
+
+   1.2. Intended audience
+
+      This specification is intended for use by implementors of software
+      to compress data into zlib format and/or decompress data from zlib
+      format.
+
+      The text of the specification assumes a basic background in
+      programming at the level of bits and other primitive data
+      representations.
+
+   1.3. Scope
+
+      The specification specifies a compressed data format that can be
+      used for in-memory compression of a sequence of arbitrary bytes.
+
+   1.4. Compliance
+
+      Unless otherwise indicated below, a compliant decompressor must be
+      able to accept and decompress any data set that conforms to all
+      the specifications presented here; a compliant compressor must
+      produce data sets that conform to all the specifications presented
+      here.
+
+   1.5.  Definitions of terms and conventions used
+
+      byte: 8 bits stored or transmitted as a unit (same as an octet).
+      (For this specification, a byte is exactly 8 bits, even on
+      machines which store a character on a number of bits different
+      from 8.) See below, for the numbering of bits within a byte.
+
+   1.6. Changes from previous versions
+
+      Version 3.1 was the first public release of this specification.
+      In version 3.2, some terminology was changed and the Adler-32
+      sample code was rewritten for clarity.  In version 3.3, the
+      support for a preset dictionary was introduced, and the
+      specification was converted to RFC style.
+
+2. Detailed specification
+
+   2.1. Overall conventions
+
+      In the diagrams below, a box like this:
+
+         +---+
+         |   | <-- the vertical bars might be missing
+         +---+
+
+
+
+
+Deutsch & Gailly             Informational                      [Page 3]
+
+RFC 1950       ZLIB Compressed Data Format Specification        May 1996
+
+
+      represents one byte; a box like this:
+
+         +==============+
+         |              |
+         +==============+
+
+      represents a variable number of bytes.
+
+      Bytes stored within a computer do not have a "bit order", since
+      they are always treated as a unit.  However, a byte considered as
+      an integer between 0 and 255 does have a most- and least-
+      significant bit, and since we write numbers with the most-
+      significant digit on the left, we also write bytes with the most-
+      significant bit on the left.  In the diagrams below, we number the
+      bits of a byte so that bit 0 is the least-significant bit, i.e.,
+      the bits are numbered:
+
+         +--------+
+         |76543210|
+         +--------+
+
+      Within a computer, a number may occupy multiple bytes.  All
+      multi-byte numbers in the format described here are stored with
+      the MOST-significant byte first (at the lower memory address).
+      For example, the decimal number 520 is stored as:
+
+             0     1
+         +--------+--------+
+         |00000010|00001000|
+         +--------+--------+
+          ^        ^
+          |        |
+          |        + less significant byte = 8
+          + more significant byte = 2 x 256
+
+   2.2. Data format
+
+      A zlib stream has the following structure:
+
+           0   1
+         +---+---+
+         |CMF|FLG|   (more-->)
+         +---+---+
+
+
+
+
+
+
+
+
+Deutsch & Gailly             Informational                      [Page 4]
+
+RFC 1950       ZLIB Compressed Data Format Specification        May 1996
+
+
+      (if FLG.FDICT set)
+
+           0   1   2   3
+         +---+---+---+---+
+         |     DICTID    |   (more-->)
+         +---+---+---+---+
+
+         +=====================+---+---+---+---+
+         |...compressed data...|    ADLER32    |
+         +=====================+---+---+---+---+
+
+      Any data which may appear after ADLER32 are not part of the zlib
+      stream.
+
+      CMF (Compression Method and flags)
+         This byte is divided into a 4-bit compression method and a 4-
+         bit information field depending on the compression method.
+
+            bits 0 to 3  CM     Compression method
+            bits 4 to 7  CINFO  Compression info
+
+      CM (Compression method)
+         This identifies the compression method used in the file. CM = 8
+         denotes the "deflate" compression method with a window size up
+         to 32K.  This is the method used by gzip and PNG (see
+         references [1] and [2] in Chapter 3, below, for the reference
+         documents).  CM = 15 is reserved.  It might be used in a future
+         version of this specification to indicate the presence of an
+         extra field before the compressed data.
+
+      CINFO (Compression info)
+         For CM = 8, CINFO is the base-2 logarithm of the LZ77 window
+         size, minus eight (CINFO=7 indicates a 32K window size). Values
+         of CINFO above 7 are not allowed in this version of the
+         specification.  CINFO is not defined in this specification for
+         CM not equal to 8.
+
+      FLG (FLaGs)
+         This flag byte is divided as follows:
+
+            bits 0 to 4  FCHECK  (check bits for CMF and FLG)
+            bit  5       FDICT   (preset dictionary)
+            bits 6 to 7  FLEVEL  (compression level)
+
+         The FCHECK value must be such that CMF and FLG, when viewed as
+         a 16-bit unsigned integer stored in MSB order (CMF*256 + FLG),
+         is a multiple of 31.
+
+
+
+
+Deutsch & Gailly             Informational                      [Page 5]
+
+RFC 1950       ZLIB Compressed Data Format Specification        May 1996
+
+
+      FDICT (Preset dictionary)
+         If FDICT is set, a DICT dictionary identifier is present
+         immediately after the FLG byte. The dictionary is a sequence of
+         bytes which are initially fed to the compressor without
+         producing any compressed output. DICT is the Adler-32 checksum
+         of this sequence of bytes (see the definition of ADLER32
+         below).  The decompressor can use this identifier to determine
+         which dictionary has been used by the compressor.
+
+      FLEVEL (Compression level)
+         These flags are available for use by specific compression
+         methods.  The "deflate" method (CM = 8) sets these flags as
+         follows:
+
+            0 - compressor used fastest algorithm
+            1 - compressor used fast algorithm
+            2 - compressor used default algorithm
+            3 - compressor used maximum compression, slowest algorithm
+
+         The information in FLEVEL is not needed for decompression; it
+         is there to indicate if recompression might be worthwhile.
+
+      compressed data
+         For compression method 8, the compressed data is stored in the
+         deflate compressed data format as described in the document
+         "DEFLATE Compressed Data Format Specification" by L. Peter
+         Deutsch. (See reference [3] in Chapter 3, below)
+
+         Other compressed data formats are not specified in this version
+         of the zlib specification.
+
+      ADLER32 (Adler-32 checksum)
+         This contains a checksum value of the uncompressed data
+         (excluding any dictionary data) computed according to Adler-32
+         algorithm. This algorithm is a 32-bit extension and improvement
+         of the Fletcher algorithm, used in the ITU-T X.224 / ISO 8073
+         standard. See references [4] and [5] in Chapter 3, below)
+
+         Adler-32 is composed of two sums accumulated per byte: s1 is
+         the sum of all bytes, s2 is the sum of all s1 values. Both sums
+         are done modulo 65521. s1 is initialized to 1, s2 to zero.  The
+         Adler-32 checksum is stored as s2*65536 + s1 in most-
+         significant-byte first (network) order.
+
+
+
+
+
+
+
+
+Deutsch & Gailly             Informational                      [Page 6]
+
+RFC 1950       ZLIB Compressed Data Format Specification        May 1996
+
+
+   2.3. Compliance
+
+      A compliant compressor must produce streams with correct CMF, FLG
+      and ADLER32, but need not support preset dictionaries.  When the
+      zlib data format is used as part of another standard data format,
+      the compressor may use only preset dictionaries that are specified
+      by this other data format.  If this other format does not use the
+      preset dictionary feature, the compressor must not set the FDICT
+      flag.
+
+      A compliant decompressor must check CMF, FLG, and ADLER32, and
+      provide an error indication if any of these have incorrect values.
+      A compliant decompressor must give an error indication if CM is
+      not one of the values defined in this specification (only the
+      value 8 is permitted in this version), since another value could
+      indicate the presence of new features that would cause subsequent
+      data to be interpreted incorrectly.  A compliant decompressor must
+      give an error indication if FDICT is set and DICTID is not the
+      identifier of a known preset dictionary.  A decompressor may
+      ignore FLEVEL and still be compliant.  When the zlib data format
+      is being used as a part of another standard format, a compliant
+      decompressor must support all the preset dictionaries specified by
+      the other format. When the other format does not use the preset
+      dictionary feature, a compliant decompressor must reject any
+      stream in which the FDICT flag is set.
+
+3. References
+
+   [1] Deutsch, L.P.,"GZIP Compressed Data Format Specification",
+       available in ftp://ftp.uu.net/pub/archiving/zip/doc/
+
+   [2] Thomas Boutell, "PNG (Portable Network Graphics) specification",
+       available in ftp://ftp.uu.net/graphics/png/documents/
+
+   [3] Deutsch, L.P.,"DEFLATE Compressed Data Format Specification",
+       available in ftp://ftp.uu.net/pub/archiving/zip/doc/
+
+   [4] Fletcher, J. G., "An Arithmetic Checksum for Serial
+       Transmissions," IEEE Transactions on Communications, Vol. COM-30,
+       No. 1, January 1982, pp. 247-252.
+
+   [5] ITU-T Recommendation X.224, Annex D, "Checksum Algorithms,"
+       November, 1993, pp. 144, 145. (Available from
+       gopher://info.itu.ch). ITU-T X.244 is also the same as ISO 8073.
+
+
+
+
+
+
+
+Deutsch & Gailly             Informational                      [Page 7]
+
+RFC 1950       ZLIB Compressed Data Format Specification        May 1996
+
+
+4. Source code
+
+   Source code for a C language implementation of a "zlib" compliant
+   library is available at ftp://ftp.uu.net/pub/archiving/zip/zlib/.
+
+5. Security Considerations
+
+   A decoder that fails to check the ADLER32 checksum value may be
+   subject to undetected data corruption.
+
+6. Acknowledgements
+
+   Trademarks cited in this document are the property of their
+   respective owners.
+
+   Jean-Loup Gailly and Mark Adler designed the zlib format and wrote
+   the related software described in this specification.  Glenn
+   Randers-Pehrson converted this document to RFC and HTML format.
+
+7. Authors' Addresses
+
+   L. Peter Deutsch
+   Aladdin Enterprises
+   203 Santa Margarita Ave.
+   Menlo Park, CA 94025
+
+   Phone: (415) 322-0103 (AM only)
+   FAX:   (415) 322-1734
+   EMail: <ghost@aladdin.com>
+
+
+   Jean-Loup Gailly
+
+   EMail: <gzip@prep.ai.mit.edu>
+
+   Questions about the technical content of this specification can be
+   sent by email to
+
+   Jean-Loup Gailly <gzip@prep.ai.mit.edu> and
+   Mark Adler <madler@alumni.caltech.edu>
+
+   Editorial comments on this specification can be sent by email to
+
+   L. Peter Deutsch <ghost@aladdin.com> and
+   Glenn Randers-Pehrson <randeg@alumni.rpi.edu>
+
+
+
+
+
+
+Deutsch & Gailly             Informational                      [Page 8]
+
+RFC 1950       ZLIB Compressed Data Format Specification        May 1996
+
+
+8. Appendix: Rationale
+
+   8.1. Preset dictionaries
+
+      A preset dictionary is specially useful to compress short input
+      sequences. The compressor can take advantage of the dictionary
+      context to encode the input in a more compact manner. The
+      decompressor can be initialized with the appropriate context by
+      virtually decompressing a compressed version of the dictionary
+      without producing any output. However for certain compression
+      algorithms such as the deflate algorithm this operation can be
+      achieved without actually performing any decompression.
+
+      The compressor and the decompressor must use exactly the same
+      dictionary. The dictionary may be fixed or may be chosen among a
+      certain number of predefined dictionaries, according to the kind
+      of input data. The decompressor can determine which dictionary has
+      been chosen by the compressor by checking the dictionary
+      identifier. This document does not specify the contents of
+      predefined dictionaries, since the optimal dictionaries are
+      application specific. Standard data formats using this feature of
+      the zlib specification must precisely define the allowed
+      dictionaries.
+
+   8.2. The Adler-32 algorithm
+
+      The Adler-32 algorithm is much faster than the CRC32 algorithm yet
+      still provides an extremely low probability of undetected errors.
+
+      The modulo on unsigned long accumulators can be delayed for 5552
+      bytes, so the modulo operation time is negligible.  If the bytes
+      are a, b, c, the second sum is 3a + 2b + c + 3, and so is position
+      and order sensitive, unlike the first sum, which is just a
+      checksum.  That 65521 is prime is important to avoid a possible
+      large class of two-byte errors that leave the check unchanged.
+      (The Fletcher checksum uses 255, which is not prime and which also
+      makes the Fletcher check insensitive to single byte changes 0 <->
+      255.)
+
+      The sum s1 is initialized to 1 instead of zero to make the length
+      of the sequence part of s2, so that the length does not have to be
+      checked separately. (Any sequence of zeroes has a Fletcher
+      checksum of zero.)
+
+
+
+
+
+
+
+
+Deutsch & Gailly             Informational                      [Page 9]
+
+RFC 1950       ZLIB Compressed Data Format Specification        May 1996
+
+
+9. Appendix: Sample code
+
+   The following C code computes the Adler-32 checksum of a data buffer.
+   It is written for clarity, not for speed.  The sample code is in the
+   ANSI C programming language. Non C users may find it easier to read
+   with these hints:
+
+      &      Bitwise AND operator.
+      >>     Bitwise right shift operator. When applied to an
+             unsigned quantity, as here, right shift inserts zero bit(s)
+             at the left.
+      <<     Bitwise left shift operator. Left shift inserts zero
+             bit(s) at the right.
+      ++     "n++" increments the variable n.
+      %      modulo operator: a % b is the remainder of a divided by b.
+
+      #define BASE 65521 /* largest prime smaller than 65536 */
+
+      /*
+         Update a running Adler-32 checksum with the bytes buf[0..len-1]
+       and return the updated checksum. The Adler-32 checksum should be
+       initialized to 1.
+
+       Usage example:
+
+         unsigned long adler = 1L;
+
+         while (read_buffer(buffer, length) != EOF) {
+           adler = update_adler32(adler, buffer, length);
+         }
+         if (adler != original_adler) error();
+      */
+      unsigned long update_adler32(unsigned long adler,
+         unsigned char *buf, int len)
+      {
+        unsigned long s1 = adler & 0xffff;
+        unsigned long s2 = (adler >> 16) & 0xffff;
+        int n;
+
+        for (n = 0; n < len; n++) {
+          s1 = (s1 + buf[n]) % BASE;
+          s2 = (s2 + s1)     % BASE;
+        }
+        return (s2 << 16) + s1;
+      }
+
+      /* Return the adler32 of the bytes buf[0..len-1] */
+
+
+
+
+Deutsch & Gailly             Informational                     [Page 10]
+
+RFC 1950       ZLIB Compressed Data Format Specification        May 1996
+
+
+      unsigned long adler32(unsigned char *buf, int len)
+      {
+        return update_adler32(1L, buf, len);
+      }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Deutsch & Gailly             Informational                     [Page 11]
+
diff --git a/compat/zlib/doc/rfc1951.txt b/compat/zlib/doc/rfc1951.txt
new file mode 100644
index 0000000..403c8c7
--- /dev/null
+++ b/compat/zlib/doc/rfc1951.txt
@@ -0,0 +1,955 @@
+
+
+
+
+
+
+Network Working Group                                         P. Deutsch
+Request for Comments: 1951                           Aladdin Enterprises
+Category: Informational                                         May 1996
+
+
+        DEFLATE Compressed Data Format Specification version 1.3
+
+Status of This Memo
+
+   This memo provides information for the Internet community.  This memo
+   does not specify an Internet standard of any kind.  Distribution of
+   this memo is unlimited.
+
+IESG Note:
+
+   The IESG takes no position on the validity of any Intellectual
+   Property Rights statements contained in this document.
+
+Notices
+
+   Copyright (c) 1996 L. Peter Deutsch
+
+   Permission is granted to copy and distribute this document for any
+   purpose and without charge, including translations into other
+   languages and incorporation into compilations, provided that the
+   copyright notice and this notice are preserved, and that any
+   substantive changes or deletions from the original are clearly
+   marked.
+
+   A pointer to the latest version of this and related documentation in
+   HTML format can be found at the URL
+   <ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html>.
+
+Abstract
+
+   This specification defines a lossless compressed data format that
+   compresses data using a combination of the LZ77 algorithm and Huffman
+   coding, with efficiency comparable to the best currently available
+   general-purpose compression methods.  The data can be produced or
+   consumed, even for an arbitrarily long sequentially presented input
+   data stream, using only an a priori bounded amount of intermediate
+   storage.  The format can be implemented readily in a manner not
+   covered by patents.
+
+
+
+
+
+
+
+
+Deutsch                      Informational                      [Page 1]
+
+RFC 1951      DEFLATE Compressed Data Format Specification      May 1996
+
+
+Table of Contents
+
+   1. Introduction ................................................... 2
+      1.1. Purpose ................................................... 2
+      1.2. Intended audience ......................................... 3
+      1.3. Scope ..................................................... 3
+      1.4. Compliance ................................................ 3
+      1.5.  Definitions of terms and conventions used ................ 3
+      1.6. Changes from previous versions ............................ 4
+   2. Compressed representation overview ............................. 4
+   3. Detailed specification ......................................... 5
+      3.1. Overall conventions ....................................... 5
+          3.1.1. Packing into bytes .................................. 5
+      3.2. Compressed block format ................................... 6
+          3.2.1. Synopsis of prefix and Huffman coding ............... 6
+          3.2.2. Use of Huffman coding in the "deflate" format ....... 7
+          3.2.3. Details of block format ............................. 9
+          3.2.4. Non-compressed blocks (BTYPE=00) ................... 11
+          3.2.5. Compressed blocks (length and distance codes) ...... 11
+          3.2.6. Compression with fixed Huffman codes (BTYPE=01) .... 12
+          3.2.7. Compression with dynamic Huffman codes (BTYPE=10) .. 13
+      3.3. Compliance ............................................... 14
+   4. Compression algorithm details ................................. 14
+   5. References .................................................... 16
+   6. Security Considerations ....................................... 16
+   7. Source code ................................................... 16
+   8. Acknowledgements .............................................. 16
+   9. Author's Address .............................................. 17
+
+1. Introduction
+
+   1.1. Purpose
+
+      The purpose of this specification is to define a lossless
+      compressed data format that:
+          * Is independent of CPU type, operating system, file system,
+            and character set, and hence can be used for interchange;
+          * Can be produced or consumed, even for an arbitrarily long
+            sequentially presented input data stream, using only an a
+            priori bounded amount of intermediate storage, and hence
+            can be used in data communications or similar structures
+            such as Unix filters;
+          * Compresses data with efficiency comparable to the best
+            currently available general-purpose compression methods,
+            and in particular considerably better than the "compress"
+            program;
+          * Can be implemented readily in a manner not covered by
+            patents, and hence can be practiced freely;
+
+
+
+Deutsch                      Informational                      [Page 2]
+
+RFC 1951      DEFLATE Compressed Data Format Specification      May 1996
+
+
+          * Is compatible with the file format produced by the current
+            widely used gzip utility, in that conforming decompressors
+            will be able to read data produced by the existing gzip
+            compressor.
+
+      The data format defined by this specification does not attempt to:
+
+          * Allow random access to compressed data;
+          * Compress specialized data (e.g., raster graphics) as well
+            as the best currently available specialized algorithms.
+
+      A simple counting argument shows that no lossless compression
+      algorithm can compress every possible input data set.  For the
+      format defined here, the worst case expansion is 5 bytes per 32K-
+      byte block, i.e., a size increase of 0.015% for large data sets.
+      English text usually compresses by a factor of 2.5 to 3;
+      executable files usually compress somewhat less; graphical data
+      such as raster images may compress much more.
+
+   1.2. Intended audience
+
+      This specification is intended for use by implementors of software
+      to compress data into "deflate" format and/or decompress data from
+      "deflate" format.
+
+      The text of the specification assumes a basic background in
+      programming at the level of bits and other primitive data
+      representations.  Familiarity with the technique of Huffman coding
+      is helpful but not required.
+
+   1.3. Scope
+
+      The specification specifies a method for representing a sequence
+      of bytes as a (usually shorter) sequence of bits, and a method for
+      packing the latter bit sequence into bytes.
+
+   1.4. Compliance
+
+      Unless otherwise indicated below, a compliant decompressor must be
+      able to accept and decompress any data set that conforms to all
+      the specifications presented here; a compliant compressor must
+      produce data sets that conform to all the specifications presented
+      here.
+
+   1.5.  Definitions of terms and conventions used
+
+      Byte: 8 bits stored or transmitted as a unit (same as an octet).
+      For this specification, a byte is exactly 8 bits, even on machines
+
+
+
+Deutsch                      Informational                      [Page 3]
+
+RFC 1951      DEFLATE Compressed Data Format Specification      May 1996
+
+
+      which store a character on a number of bits different from eight.
+      See below, for the numbering of bits within a byte.
+
+      String: a sequence of arbitrary bytes.
+
+   1.6. Changes from previous versions
+
+      There have been no technical changes to the deflate format since
+      version 1.1 of this specification.  In version 1.2, some
+      terminology was changed.  Version 1.3 is a conversion of the
+      specification to RFC style.
+
+2. Compressed representation overview
+
+   A compressed data set consists of a series of blocks, corresponding
+   to successive blocks of input data.  The block sizes are arbitrary,
+   except that non-compressible blocks are limited to 65,535 bytes.
+
+   Each block is compressed using a combination of the LZ77 algorithm
+   and Huffman coding. The Huffman trees for each block are independent
+   of those for previous or subsequent blocks; the LZ77 algorithm may
+   use a reference to a duplicated string occurring in a previous block,
+   up to 32K input bytes before.
+
+   Each block consists of two parts: a pair of Huffman code trees that
+   describe the representation of the compressed data part, and a
+   compressed data part.  (The Huffman trees themselves are compressed
+   using Huffman encoding.)  The compressed data consists of a series of
+   elements of two types: literal bytes (of strings that have not been
+   detected as duplicated within the previous 32K input bytes), and
+   pointers to duplicated strings, where a pointer is represented as a
+   pair <length, backward distance>.  The representation used in the
+   "deflate" format limits distances to 32K bytes and lengths to 258
+   bytes, but does not limit the size of a block, except for
+   uncompressible blocks, which are limited as noted above.
+
+   Each type of value (literals, distances, and lengths) in the
+   compressed data is represented using a Huffman code, using one code
+   tree for literals and lengths and a separate code tree for distances.
+   The code trees for each block appear in a compact form just before
+   the compressed data for that block.
+
+
+
+
+
+
+
+
+
+
+Deutsch                      Informational                      [Page 4]
+
+RFC 1951      DEFLATE Compressed Data Format Specification      May 1996
+
+
+3. Detailed specification
+
+   3.1. Overall conventions In the diagrams below, a box like this:
+
+         +---+
+         |   | <-- the vertical bars might be missing
+         +---+
+
+      represents one byte; a box like this:
+
+         +==============+
+         |              |
+         +==============+
+
+      represents a variable number of bytes.
+
+      Bytes stored within a computer do not have a "bit order", since
+      they are always treated as a unit.  However, a byte considered as
+      an integer between 0 and 255 does have a most- and least-
+      significant bit, and since we write numbers with the most-
+      significant digit on the left, we also write bytes with the most-
+      significant bit on the left.  In the diagrams below, we number the
+      bits of a byte so that bit 0 is the least-significant bit, i.e.,
+      the bits are numbered:
+
+         +--------+
+         |76543210|
+         +--------+
+
+      Within a computer, a number may occupy multiple bytes.  All
+      multi-byte numbers in the format described here are stored with
+      the least-significant byte first (at the lower memory address).
+      For example, the decimal number 520 is stored as:
+
+             0        1
+         +--------+--------+
+         |00001000|00000010|
+         +--------+--------+
+          ^        ^
+          |        |
+          |        + more significant byte = 2 x 256
+          + less significant byte = 8
+
+      3.1.1. Packing into bytes
+
+         This document does not address the issue of the order in which
+         bits of a byte are transmitted on a bit-sequential medium,
+         since the final data format described here is byte- rather than
+
+
+
+Deutsch                      Informational                      [Page 5]
+
+RFC 1951      DEFLATE Compressed Data Format Specification      May 1996
+
+
+         bit-oriented.  However, we describe the compressed block format
+         in below, as a sequence of data elements of various bit
+         lengths, not a sequence of bytes.  We must therefore specify
+         how to pack these data elements into bytes to form the final
+         compressed byte sequence:
+
+             * Data elements are packed into bytes in order of
+               increasing bit number within the byte, i.e., starting
+               with the least-significant bit of the byte.
+             * Data elements other than Huffman codes are packed
+               starting with the least-significant bit of the data
+               element.
+             * Huffman codes are packed starting with the most-
+               significant bit of the code.
+
+         In other words, if one were to print out the compressed data as
+         a sequence of bytes, starting with the first byte at the
+         *right* margin and proceeding to the *left*, with the most-
+         significant bit of each byte on the left as usual, one would be
+         able to parse the result from right to left, with fixed-width
+         elements in the correct MSB-to-LSB order and Huffman codes in
+         bit-reversed order (i.e., with the first bit of the code in the
+         relative LSB position).
+
+   3.2. Compressed block format
+
+      3.2.1. Synopsis of prefix and Huffman coding
+
+         Prefix coding represents symbols from an a priori known
+         alphabet by bit sequences (codes), one code for each symbol, in
+         a manner such that different symbols may be represented by bit
+         sequences of different lengths, but a parser can always parse
+         an encoded string unambiguously symbol-by-symbol.
+
+         We define a prefix code in terms of a binary tree in which the
+         two edges descending from each non-leaf node are labeled 0 and
+         1 and in which the leaf nodes correspond one-for-one with (are
+         labeled with) the symbols of the alphabet; then the code for a
+         symbol is the sequence of 0's and 1's on the edges leading from
+         the root to the leaf labeled with that symbol.  For example:
+
+
+
+
+
+
+
+
+
+
+
+Deutsch                      Informational                      [Page 6]
+
+RFC 1951      DEFLATE Compressed Data Format Specification      May 1996
+
+
+                          /\              Symbol    Code
+                         0  1             ------    ----
+                        /    \                A      00
+                       /\     B               B       1
+                      0  1                    C     011
+                     /    \                   D     010
+                    A     /\
+                         0  1
+                        /    \
+                       D      C
+
+         A parser can decode the next symbol from an encoded input
+         stream by walking down the tree from the root, at each step
+         choosing the edge corresponding to the next input bit.
+
+         Given an alphabet with known symbol frequencies, the Huffman
+         algorithm allows the construction of an optimal prefix code
+         (one which represents strings with those symbol frequencies
+         using the fewest bits of any possible prefix codes for that
+         alphabet).  Such a code is called a Huffman code.  (See
+         reference [1] in Chapter 5, references for additional
+         information on Huffman codes.)
+
+         Note that in the "deflate" format, the Huffman codes for the
+         various alphabets must not exceed certain maximum code lengths.
+         This constraint complicates the algorithm for computing code
+         lengths from symbol frequencies.  Again, see Chapter 5,
+         references for details.
+
+      3.2.2. Use of Huffman coding in the "deflate" format
+
+         The Huffman codes used for each alphabet in the "deflate"
+         format have two additional rules:
+
+             * All codes of a given bit length have lexicographically
+               consecutive values, in the same order as the symbols
+               they represent;
+
+             * Shorter codes lexicographically precede longer codes.
+
+
+
+
+
+
+
+
+
+
+
+
+Deutsch                      Informational                      [Page 7]
+
+RFC 1951      DEFLATE Compressed Data Format Specification      May 1996
+
+
+         We could recode the example above to follow this rule as
+         follows, assuming that the order of the alphabet is ABCD:
+
+            Symbol  Code
+            ------  ----
+            A       10
+            B       0
+            C       110
+            D       111
+
+         I.e., 0 precedes 10 which precedes 11x, and 110 and 111 are
+         lexicographically consecutive.
+
+         Given this rule, we can define the Huffman code for an alphabet
+         just by giving the bit lengths of the codes for each symbol of
+         the alphabet in order; this is sufficient to determine the
+         actual codes.  In our example, the code is completely defined
+         by the sequence of bit lengths (2, 1, 3, 3).  The following
+         algorithm generates the codes as integers, intended to be read
+         from most- to least-significant bit.  The code lengths are
+         initially in tree[I].Len; the codes are produced in
+         tree[I].Code.
+
+         1)  Count the number of codes for each code length.  Let
+             bl_count[N] be the number of codes of length N, N >= 1.
+
+         2)  Find the numerical value of the smallest code for each
+             code length:
+
+                code = 0;
+                bl_count[0] = 0;
+                for (bits = 1; bits <= MAX_BITS; bits++) {
+                    code = (code + bl_count[bits-1]) << 1;
+                    next_code[bits] = code;
+                }
+
+         3)  Assign numerical values to all codes, using consecutive
+             values for all codes of the same length with the base
+             values determined at step 2. Codes that are never used
+             (which have a bit length of zero) must not be assigned a
+             value.
+
+                for (n = 0;  n <= max_code; n++) {
+                    len = tree[n].Len;
+                    if (len != 0) {
+                        tree[n].Code = next_code[len];
+                        next_code[len]++;
+                    }
+
+
+
+Deutsch                      Informational                      [Page 8]
+
+RFC 1951      DEFLATE Compressed Data Format Specification      May 1996
+
+
+                }
+
+         Example:
+
+         Consider the alphabet ABCDEFGH, with bit lengths (3, 3, 3, 3,
+         3, 2, 4, 4).  After step 1, we have:
+
+            N      bl_count[N]
+            -      -----------
+            2      1
+            3      5
+            4      2
+
+         Step 2 computes the following next_code values:
+
+            N      next_code[N]
+            -      ------------
+            1      0
+            2      0
+            3      2
+            4      14
+
+         Step 3 produces the following code values:
+
+            Symbol Length   Code
+            ------ ------   ----
+            A       3        010
+            B       3        011
+            C       3        100
+            D       3        101
+            E       3        110
+            F       2         00
+            G       4       1110
+            H       4       1111
+
+      3.2.3. Details of block format
+
+         Each block of compressed data begins with 3 header bits
+         containing the following data:
+
+            first bit       BFINAL
+            next 2 bits     BTYPE
+
+         Note that the header bits do not necessarily begin on a byte
+         boundary, since a block does not necessarily occupy an integral
+         number of bytes.
+
+
+
+
+
+Deutsch                      Informational                      [Page 9]
+
+RFC 1951      DEFLATE Compressed Data Format Specification      May 1996
+
+
+         BFINAL is set if and only if this is the last block of the data
+         set.
+
+         BTYPE specifies how the data are compressed, as follows:
+
+            00 - no compression
+            01 - compressed with fixed Huffman codes
+            10 - compressed with dynamic Huffman codes
+            11 - reserved (error)
+
+         The only difference between the two compressed cases is how the
+         Huffman codes for the literal/length and distance alphabets are
+         defined.
+
+         In all cases, the decoding algorithm for the actual data is as
+         follows:
+
+            do
+               read block header from input stream.
+               if stored with no compression
+                  skip any remaining bits in current partially
+                     processed byte
+                  read LEN and NLEN (see next section)
+                  copy LEN bytes of data to output
+               otherwise
+                  if compressed with dynamic Huffman codes
+                     read representation of code trees (see
+                        subsection below)
+                  loop (until end of block code recognized)
+                     decode literal/length value from input stream
+                     if value < 256
+                        copy value (literal byte) to output stream
+                     otherwise
+                        if value = end of block (256)
+                           break from loop
+                        otherwise (value = 257..285)
+                           decode distance from input stream
+
+                           move backwards distance bytes in the output
+                           stream, and copy length bytes from this
+                           position to the output stream.
+                  end loop
+            while not last block
+
+         Note that a duplicated string reference may refer to a string
+         in a previous block; i.e., the backward distance may cross one
+         or more block boundaries.  However a distance cannot refer past
+         the beginning of the output stream.  (An application using a
+
+
+
+Deutsch                      Informational                     [Page 10]
+
+RFC 1951      DEFLATE Compressed Data Format Specification      May 1996
+
+
+         preset dictionary might discard part of the output stream; a
+         distance can refer to that part of the output stream anyway)
+         Note also that the referenced string may overlap the current
+         position; for example, if the last 2 bytes decoded have values
+         X and Y, a string reference with <length = 5, distance = 2>
+         adds X,Y,X,Y,X to the output stream.
+
+         We now specify each compression method in turn.
+
+      3.2.4. Non-compressed blocks (BTYPE=00)
+
+         Any bits of input up to the next byte boundary are ignored.
+         The rest of the block consists of the following information:
+
+              0   1   2   3   4...
+            +---+---+---+---+================================+
+            |  LEN  | NLEN  |... LEN bytes of literal data...|
+            +---+---+---+---+================================+
+
+         LEN is the number of data bytes in the block.  NLEN is the
+         one's complement of LEN.
+
+      3.2.5. Compressed blocks (length and distance codes)
+
+         As noted above, encoded data blocks in the "deflate" format
+         consist of sequences of symbols drawn from three conceptually
+         distinct alphabets: either literal bytes, from the alphabet of
+         byte values (0..255), or <length, backward distance> pairs,
+         where the length is drawn from (3..258) and the distance is
+         drawn from (1..32,768).  In fact, the literal and length
+         alphabets are merged into a single alphabet (0..285), where
+         values 0..255 represent literal bytes, the value 256 indicates
+         end-of-block, and values 257..285 represent length codes
+         (possibly in conjunction with extra bits following the symbol
+         code) as follows:
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Deutsch                      Informational                     [Page 11]
+
+RFC 1951      DEFLATE Compressed Data Format Specification      May 1996
+
+
+                 Extra               Extra               Extra
+            Code Bits Length(s) Code Bits Lengths   Code Bits Length(s)
+            ---- ---- ------     ---- ---- -------   ---- ---- -------
+             257   0     3       267   1   15,16     277   4   67-82
+             258   0     4       268   1   17,18     278   4   83-98
+             259   0     5       269   2   19-22     279   4   99-114
+             260   0     6       270   2   23-26     280   4  115-130
+             261   0     7       271   2   27-30     281   5  131-162
+             262   0     8       272   2   31-34     282   5  163-194
+             263   0     9       273   3   35-42     283   5  195-226
+             264   0    10       274   3   43-50     284   5  227-257
+             265   1  11,12      275   3   51-58     285   0    258
+             266   1  13,14      276   3   59-66
+
+         The extra bits should be interpreted as a machine integer
+         stored with the most-significant bit first, e.g., bits 1110
+         represent the value 14.
+
+                  Extra           Extra               Extra
+             Code Bits Dist  Code Bits   Dist     Code Bits Distance
+             ---- ---- ----  ---- ----  ------    ---- ---- --------
+               0   0    1     10   4     33-48    20    9   1025-1536
+               1   0    2     11   4     49-64    21    9   1537-2048
+               2   0    3     12   5     65-96    22   10   2049-3072
+               3   0    4     13   5     97-128   23   10   3073-4096
+               4   1   5,6    14   6    129-192   24   11   4097-6144
+               5   1   7,8    15   6    193-256   25   11   6145-8192
+               6   2   9-12   16   7    257-384   26   12  8193-12288
+               7   2  13-16   17   7    385-512   27   12 12289-16384
+               8   3  17-24   18   8    513-768   28   13 16385-24576
+               9   3  25-32   19   8   769-1024   29   13 24577-32768
+
+      3.2.6. Compression with fixed Huffman codes (BTYPE=01)
+
+         The Huffman codes for the two alphabets are fixed, and are not
+         represented explicitly in the data.  The Huffman code lengths
+         for the literal/length alphabet are:
+
+                   Lit Value    Bits        Codes
+                   ---------    ----        -----
+                     0 - 143     8          00110000 through
+                                            10111111
+                   144 - 255     9          110010000 through
+                                            111111111
+                   256 - 279     7          0000000 through
+                                            0010111
+                   280 - 287     8          11000000 through
+                                            11000111
+
+
+
+Deutsch                      Informational                     [Page 12]
+
+RFC 1951      DEFLATE Compressed Data Format Specification      May 1996
+
+
+         The code lengths are sufficient to generate the actual codes,
+         as described above; we show the codes in the table for added
+         clarity.  Literal/length values 286-287 will never actually
+         occur in the compressed data, but participate in the code
+         construction.
+
+         Distance codes 0-31 are represented by (fixed-length) 5-bit
+         codes, with possible additional bits as shown in the table
+         shown in Paragraph 3.2.5, above.  Note that distance codes 30-
+         31 will never actually occur in the compressed data.
+
+      3.2.7. Compression with dynamic Huffman codes (BTYPE=10)
+
+         The Huffman codes for the two alphabets appear in the block
+         immediately after the header bits and before the actual
+         compressed data, first the literal/length code and then the
+         distance code.  Each code is defined by a sequence of code
+         lengths, as discussed in Paragraph 3.2.2, above.  For even
+         greater compactness, the code length sequences themselves are
+         compressed using a Huffman code.  The alphabet for code lengths
+         is as follows:
+
+               0 - 15: Represent code lengths of 0 - 15
+                   16: Copy the previous code length 3 - 6 times.
+                       The next 2 bits indicate repeat length
+                             (0 = 3, ... , 3 = 6)
+                          Example:  Codes 8, 16 (+2 bits 11),
+                                    16 (+2 bits 10) will expand to
+                                    12 code lengths of 8 (1 + 6 + 5)
+                   17: Repeat a code length of 0 for 3 - 10 times.
+                       (3 bits of length)
+                   18: Repeat a code length of 0 for 11 - 138 times
+                       (7 bits of length)
+
+         A code length of 0 indicates that the corresponding symbol in
+         the literal/length or distance alphabet will not occur in the
+         block, and should not participate in the Huffman code
+         construction algorithm given earlier.  If only one distance
+         code is used, it is encoded using one bit, not zero bits; in
+         this case there is a single code length of one, with one unused
+         code.  One distance code of zero bits means that there are no
+         distance codes used at all (the data is all literals).
+
+         We can now define the format of the block:
+
+               5 Bits: HLIT, # of Literal/Length codes - 257 (257 - 286)
+               5 Bits: HDIST, # of Distance codes - 1        (1 - 32)
+               4 Bits: HCLEN, # of Code Length codes - 4     (4 - 19)
+
+
+
+Deutsch                      Informational                     [Page 13]
+
+RFC 1951      DEFLATE Compressed Data Format Specification      May 1996
+
+
+               (HCLEN + 4) x 3 bits: code lengths for the code length
+                  alphabet given just above, in the order: 16, 17, 18,
+                  0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15
+
+                  These code lengths are interpreted as 3-bit integers
+                  (0-7); as above, a code length of 0 means the
+                  corresponding symbol (literal/length or distance code
+                  length) is not used.
+
+               HLIT + 257 code lengths for the literal/length alphabet,
+                  encoded using the code length Huffman code
+
+               HDIST + 1 code lengths for the distance alphabet,
+                  encoded using the code length Huffman code
+
+               The actual compressed data of the block,
+                  encoded using the literal/length and distance Huffman
+                  codes
+
+               The literal/length symbol 256 (end of data),
+                  encoded using the literal/length Huffman code
+
+         The code length repeat codes can cross from HLIT + 257 to the
+         HDIST + 1 code lengths.  In other words, all code lengths form
+         a single sequence of HLIT + HDIST + 258 values.
+
+   3.3. Compliance
+
+      A compressor may limit further the ranges of values specified in
+      the previous section and still be compliant; for example, it may
+      limit the range of backward pointers to some value smaller than
+      32K.  Similarly, a compressor may limit the size of blocks so that
+      a compressible block fits in memory.
+
+      A compliant decompressor must accept the full range of possible
+      values defined in the previous section, and must accept blocks of
+      arbitrary size.
+
+4. Compression algorithm details
+
+   While it is the intent of this document to define the "deflate"
+   compressed data format without reference to any particular
+   compression algorithm, the format is related to the compressed
+   formats produced by LZ77 (Lempel-Ziv 1977, see reference [2] below);
+   since many variations of LZ77 are patented, it is strongly
+   recommended that the implementor of a compressor follow the general
+   algorithm presented here, which is known not to be patented per se.
+   The material in this section is not part of the definition of the
+
+
+
+Deutsch                      Informational                     [Page 14]
+
+RFC 1951      DEFLATE Compressed Data Format Specification      May 1996
+
+
+   specification per se, and a compressor need not follow it in order to
+   be compliant.
+
+   The compressor terminates a block when it determines that starting a
+   new block with fresh trees would be useful, or when the block size
+   fills up the compressor's block buffer.
+
+   The compressor uses a chained hash table to find duplicated strings,
+   using a hash function that operates on 3-byte sequences.  At any
+   given point during compression, let XYZ be the next 3 input bytes to
+   be examined (not necessarily all different, of course).  First, the
+   compressor examines the hash chain for XYZ.  If the chain is empty,
+   the compressor simply writes out X as a literal byte and advances one
+   byte in the input.  If the hash chain is not empty, indicating that
+   the sequence XYZ (or, if we are unlucky, some other 3 bytes with the
+   same hash function value) has occurred recently, the compressor
+   compares all strings on the XYZ hash chain with the actual input data
+   sequence starting at the current point, and selects the longest
+   match.
+
+   The compressor searches the hash chains starting with the most recent
+   strings, to favor small distances and thus take advantage of the
+   Huffman encoding.  The hash chains are singly linked. There are no
+   deletions from the hash chains; the algorithm simply discards matches
+   that are too old.  To avoid a worst-case situation, very long hash
+   chains are arbitrarily truncated at a certain length, determined by a
+   run-time parameter.
+
+   To improve overall compression, the compressor optionally defers the
+   selection of matches ("lazy matching"): after a match of length N has
+   been found, the compressor searches for a longer match starting at
+   the next input byte.  If it finds a longer match, it truncates the
+   previous match to a length of one (thus producing a single literal
+   byte) and then emits the longer match.  Otherwise, it emits the
+   original match, and, as described above, advances N bytes before
+   continuing.
+
+   Run-time parameters also control this "lazy match" procedure.  If
+   compression ratio is most important, the compressor attempts a
+   complete second search regardless of the length of the first match.
+   In the normal case, if the current match is "long enough", the
+   compressor reduces the search for a longer match, thus speeding up
+   the process.  If speed is most important, the compressor inserts new
+   strings in the hash table only when no match was found, or when the
+   match is not "too long".  This degrades the compression ratio but
+   saves time since there are both fewer insertions and fewer searches.
+
+
+
+
+
+Deutsch                      Informational                     [Page 15]
+
+RFC 1951      DEFLATE Compressed Data Format Specification      May 1996
+
+
+5. References
+
+   [1] Huffman, D. A., "A Method for the Construction of Minimum
+       Redundancy Codes", Proceedings of the Institute of Radio
+       Engineers, September 1952, Volume 40, Number 9, pp. 1098-1101.
+
+   [2] Ziv J., Lempel A., "A Universal Algorithm for Sequential Data
+       Compression", IEEE Transactions on Information Theory, Vol. 23,
+       No. 3, pp. 337-343.
+
+   [3] Gailly, J.-L., and Adler, M., ZLIB documentation and sources,
+       available in ftp://ftp.uu.net/pub/archiving/zip/doc/
+
+   [4] Gailly, J.-L., and Adler, M., GZIP documentation and sources,
+       available as gzip-*.tar in ftp://prep.ai.mit.edu/pub/gnu/
+
+   [5] Schwartz, E. S., and Kallick, B. "Generating a canonical prefix
+       encoding." Comm. ACM, 7,3 (Mar. 1964), pp. 166-169.
+
+   [6] Hirschberg and Lelewer, "Efficient decoding of prefix codes,"
+       Comm. ACM, 33,4, April 1990, pp. 449-459.
+
+6. Security Considerations
+
+   Any data compression method involves the reduction of redundancy in
+   the data.  Consequently, any corruption of the data is likely to have
+   severe effects and be difficult to correct.  Uncompressed text, on
+   the other hand, will probably still be readable despite the presence
+   of some corrupted bytes.
+
+   It is recommended that systems using this data format provide some
+   means of validating the integrity of the compressed data.  See
+   reference [3], for example.
+
+7. Source code
+
+   Source code for a C language implementation of a "deflate" compliant
+   compressor and decompressor is available within the zlib package at
+   ftp://ftp.uu.net/pub/archiving/zip/zlib/.
+
+8. Acknowledgements
+
+   Trademarks cited in this document are the property of their
+   respective owners.
+
+   Phil Katz designed the deflate format.  Jean-Loup Gailly and Mark
+   Adler wrote the related software described in this specification.
+   Glenn Randers-Pehrson converted this document to RFC and HTML format.
+
+
+
+Deutsch                      Informational                     [Page 16]
+
+RFC 1951      DEFLATE Compressed Data Format Specification      May 1996
+
+
+9. Author's Address
+
+   L. Peter Deutsch
+   Aladdin Enterprises
+   203 Santa Margarita Ave.
+   Menlo Park, CA 94025
+
+   Phone: (415) 322-0103 (AM only)
+   FAX:   (415) 322-1734
+   EMail: <ghost@aladdin.com>
+
+   Questions about the technical content of this specification can be
+   sent by email to:
+
+   Jean-Loup Gailly <gzip@prep.ai.mit.edu> and
+   Mark Adler <madler@alumni.caltech.edu>
+
+   Editorial comments on this specification can be sent by email to:
+
+   L. Peter Deutsch <ghost@aladdin.com> and
+   Glenn Randers-Pehrson <randeg@alumni.rpi.edu>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Deutsch                      Informational                     [Page 17]
+
diff --git a/compat/zlib/doc/rfc1952.txt b/compat/zlib/doc/rfc1952.txt
new file mode 100644
index 0000000..a8e51b4
--- /dev/null
+++ b/compat/zlib/doc/rfc1952.txt
@@ -0,0 +1,675 @@
+
+
+
+
+
+
+Network Working Group                                         P. Deutsch
+Request for Comments: 1952                           Aladdin Enterprises
+Category: Informational                                         May 1996
+
+
+               GZIP file format specification version 4.3
+
+Status of This Memo
+
+   This memo provides information for the Internet community.  This memo
+   does not specify an Internet standard of any kind.  Distribution of
+   this memo is unlimited.
+
+IESG Note:
+
+   The IESG takes no position on the validity of any Intellectual
+   Property Rights statements contained in this document.
+
+Notices
+
+   Copyright (c) 1996 L. Peter Deutsch
+
+   Permission is granted to copy and distribute this document for any
+   purpose and without charge, including translations into other
+   languages and incorporation into compilations, provided that the
+   copyright notice and this notice are preserved, and that any
+   substantive changes or deletions from the original are clearly
+   marked.
+
+   A pointer to the latest version of this and related documentation in
+   HTML format can be found at the URL
+   <ftp://ftp.uu.net/graphics/png/documents/zlib/zdoc-index.html>.
+
+Abstract
+
+   This specification defines a lossless compressed data format that is
+   compatible with the widely used GZIP utility.  The format includes a
+   cyclic redundancy check value for detecting data corruption.  The
+   format presently uses the DEFLATE method of compression but can be
+   easily extended to use other compression methods.  The format can be
+   implemented readily in a manner not covered by patents.
+
+
+
+
+
+
+
+
+
+
+Deutsch                      Informational                      [Page 1]
+
+RFC 1952             GZIP File Format Specification             May 1996
+
+
+Table of Contents
+
+   1. Introduction ................................................... 2
+      1.1. Purpose ................................................... 2
+      1.2. Intended audience ......................................... 3
+      1.3. Scope ..................................................... 3
+      1.4. Compliance ................................................ 3
+      1.5. Definitions of terms and conventions used ................. 3
+      1.6. Changes from previous versions ............................ 3
+   2. Detailed specification ......................................... 4
+      2.1. Overall conventions ....................................... 4
+      2.2. File format ............................................... 5
+      2.3. Member format ............................................. 5
+          2.3.1. Member header and trailer ........................... 6
+              2.3.1.1. Extra field ................................... 8
+              2.3.1.2. Compliance .................................... 9
+      3. References .................................................. 9
+      4. Security Considerations .................................... 10
+      5. Acknowledgements ........................................... 10
+      6. Author's Address ........................................... 10
+      7. Appendix: Jean-Loup Gailly's gzip utility .................. 11
+      8. Appendix: Sample CRC Code .................................. 11
+
+1. Introduction
+
+   1.1. Purpose
+
+      The purpose of this specification is to define a lossless
+      compressed data format that:
+
+          * Is independent of CPU type, operating system, file system,
+            and character set, and hence can be used for interchange;
+          * Can compress or decompress a data stream (as opposed to a
+            randomly accessible file) to produce another data stream,
+            using only an a priori bounded amount of intermediate
+            storage, and hence can be used in data communications or
+            similar structures such as Unix filters;
+          * Compresses data with efficiency comparable to the best
+            currently available general-purpose compression methods,
+            and in particular considerably better than the "compress"
+            program;
+          * Can be implemented readily in a manner not covered by
+            patents, and hence can be practiced freely;
+          * Is compatible with the file format produced by the current
+            widely used gzip utility, in that conforming decompressors
+            will be able to read data produced by the existing gzip
+            compressor.
+
+
+
+
+Deutsch                      Informational                      [Page 2]
+
+RFC 1952             GZIP File Format Specification             May 1996
+
+
+      The data format defined by this specification does not attempt to:
+
+          * Provide random access to compressed data;
+          * Compress specialized data (e.g., raster graphics) as well as
+            the best currently available specialized algorithms.
+
+   1.2. Intended audience
+
+      This specification is intended for use by implementors of software
+      to compress data into gzip format and/or decompress data from gzip
+      format.
+
+      The text of the specification assumes a basic background in
+      programming at the level of bits and other primitive data
+      representations.
+
+   1.3. Scope
+
+      The specification specifies a compression method and a file format
+      (the latter assuming only that a file can store a sequence of
+      arbitrary bytes).  It does not specify any particular interface to
+      a file system or anything about character sets or encodings
+      (except for file names and comments, which are optional).
+
+   1.4. Compliance
+
+      Unless otherwise indicated below, a compliant decompressor must be
+      able to accept and decompress any file that conforms to all the
+      specifications presented here; a compliant compressor must produce
+      files that conform to all the specifications presented here.  The
+      material in the appendices is not part of the specification per se
+      and is not relevant to compliance.
+
+   1.5. Definitions of terms and conventions used
+
+      byte: 8 bits stored or transmitted as a unit (same as an octet).
+      (For this specification, a byte is exactly 8 bits, even on
+      machines which store a character on a number of bits different
+      from 8.)  See below for the numbering of bits within a byte.
+
+   1.6. Changes from previous versions
+
+      There have been no technical changes to the gzip format since
+      version 4.1 of this specification.  In version 4.2, some
+      terminology was changed, and the sample CRC code was rewritten for
+      clarity and to eliminate the requirement for the caller to do pre-
+      and post-conditioning.  Version 4.3 is a conversion of the
+      specification to RFC style.
+
+
+
+Deutsch                      Informational                      [Page 3]
+
+RFC 1952             GZIP File Format Specification             May 1996
+
+
+2. Detailed specification
+
+   2.1. Overall conventions
+
+      In the diagrams below, a box like this:
+
+         +---+
+         |   | <-- the vertical bars might be missing
+         +---+
+
+      represents one byte; a box like this:
+
+         +==============+
+         |              |
+         +==============+
+
+      represents a variable number of bytes.
+
+      Bytes stored within a computer do not have a "bit order", since
+      they are always treated as a unit.  However, a byte considered as
+      an integer between 0 and 255 does have a most- and least-
+      significant bit, and since we write numbers with the most-
+      significant digit on the left, we also write bytes with the most-
+      significant bit on the left.  In the diagrams below, we number the
+      bits of a byte so that bit 0 is the least-significant bit, i.e.,
+      the bits are numbered:
+
+         +--------+
+         |76543210|
+         +--------+
+
+      This document does not address the issue of the order in which
+      bits of a byte are transmitted on a bit-sequential medium, since
+      the data format described here is byte- rather than bit-oriented.
+
+      Within a computer, a number may occupy multiple bytes.  All
+      multi-byte numbers in the format described here are stored with
+      the least-significant byte first (at the lower memory address).
+      For example, the decimal number 520 is stored as:
+
+             0        1
+         +--------+--------+
+         |00001000|00000010|
+         +--------+--------+
+          ^        ^
+          |        |
+          |        + more significant byte = 2 x 256
+          + less significant byte = 8
+
+
+
+Deutsch                      Informational                      [Page 4]
+
+RFC 1952             GZIP File Format Specification             May 1996
+
+
+   2.2. File format
+
+      A gzip file consists of a series of "members" (compressed data
+      sets).  The format of each member is specified in the following
+      section.  The members simply appear one after another in the file,
+      with no additional information before, between, or after them.
+
+   2.3. Member format
+
+      Each member has the following structure:
+
+         +---+---+---+---+---+---+---+---+---+---+
+         |ID1|ID2|CM |FLG|     MTIME     |XFL|OS | (more-->)
+         +---+---+---+---+---+---+---+---+---+---+
+
+      (if FLG.FEXTRA set)
+
+         +---+---+=================================+
+         | XLEN  |...XLEN bytes of "extra field"...| (more-->)
+         +---+---+=================================+
+
+      (if FLG.FNAME set)
+
+         +=========================================+
+         |...original file name, zero-terminated...| (more-->)
+         +=========================================+
+
+      (if FLG.FCOMMENT set)
+
+         +===================================+
+         |...file comment, zero-terminated...| (more-->)
+         +===================================+
+
+      (if FLG.FHCRC set)
+
+         +---+---+
+         | CRC16 |
+         +---+---+
+
+         +=======================+
+         |...compressed blocks...| (more-->)
+         +=======================+
+
+           0   1   2   3   4   5   6   7
+         +---+---+---+---+---+---+---+---+
+         |     CRC32     |     ISIZE     |
+         +---+---+---+---+---+---+---+---+
+
+
+
+
+Deutsch                      Informational                      [Page 5]
+
+RFC 1952             GZIP File Format Specification             May 1996
+
+
+      2.3.1. Member header and trailer
+
+         ID1 (IDentification 1)
+         ID2 (IDentification 2)
+            These have the fixed values ID1 = 31 (0x1f, \037), ID2 = 139
+            (0x8b, \213), to identify the file as being in gzip format.
+
+         CM (Compression Method)
+            This identifies the compression method used in the file.  CM
+            = 0-7 are reserved.  CM = 8 denotes the "deflate"
+            compression method, which is the one customarily used by
+            gzip and which is documented elsewhere.
+
+         FLG (FLaGs)
+            This flag byte is divided into individual bits as follows:
+
+               bit 0   FTEXT
+               bit 1   FHCRC
+               bit 2   FEXTRA
+               bit 3   FNAME
+               bit 4   FCOMMENT
+               bit 5   reserved
+               bit 6   reserved
+               bit 7   reserved
+
+            If FTEXT is set, the file is probably ASCII text.  This is
+            an optional indication, which the compressor may set by
+            checking a small amount of the input data to see whether any
+            non-ASCII characters are present.  In case of doubt, FTEXT
+            is cleared, indicating binary data. For systems which have
+            different file formats for ascii text and binary data, the
+            decompressor can use FTEXT to choose the appropriate format.
+            We deliberately do not specify the algorithm used to set
+            this bit, since a compressor always has the option of
+            leaving it cleared and a decompressor always has the option
+            of ignoring it and letting some other program handle issues
+            of data conversion.
+
+            If FHCRC is set, a CRC16 for the gzip header is present,
+            immediately before the compressed data. The CRC16 consists
+            of the two least significant bytes of the CRC32 for all
+            bytes of the gzip header up to and not including the CRC16.
+            [The FHCRC bit was never set by versions of gzip up to
+            1.2.4, even though it was documented with a different
+            meaning in gzip 1.2.4.]
+
+            If FEXTRA is set, optional extra fields are present, as
+            described in a following section.
+
+
+
+Deutsch                      Informational                      [Page 6]
+
+RFC 1952             GZIP File Format Specification             May 1996
+
+
+            If FNAME is set, an original file name is present,
+            terminated by a zero byte.  The name must consist of ISO
+            8859-1 (LATIN-1) characters; on operating systems using
+            EBCDIC or any other character set for file names, the name
+            must be translated to the ISO LATIN-1 character set.  This
+            is the original name of the file being compressed, with any
+            directory components removed, and, if the file being
+            compressed is on a file system with case insensitive names,
+            forced to lower case. There is no original file name if the
+            data was compressed from a source other than a named file;
+            for example, if the source was stdin on a Unix system, there
+            is no file name.
+
+            If FCOMMENT is set, a zero-terminated file comment is
+            present.  This comment is not interpreted; it is only
+            intended for human consumption.  The comment must consist of
+            ISO 8859-1 (LATIN-1) characters.  Line breaks should be
+            denoted by a single line feed character (10 decimal).
+
+            Reserved FLG bits must be zero.
+
+         MTIME (Modification TIME)
+            This gives the most recent modification time of the original
+            file being compressed.  The time is in Unix format, i.e.,
+            seconds since 00:00:00 GMT, Jan.  1, 1970.  (Note that this
+            may cause problems for MS-DOS and other systems that use
+            local rather than Universal time.)  If the compressed data
+            did not come from a file, MTIME is set to the time at which
+            compression started.  MTIME = 0 means no time stamp is
+            available.
+
+         XFL (eXtra FLags)
+            These flags are available for use by specific compression
+            methods.  The "deflate" method (CM = 8) sets these flags as
+            follows:
+
+               XFL = 2 - compressor used maximum compression,
+                         slowest algorithm
+               XFL = 4 - compressor used fastest algorithm
+
+         OS (Operating System)
+            This identifies the type of file system on which compression
+            took place.  This may be useful in determining end-of-line
+            convention for text files.  The currently defined values are
+            as follows:
+
+
+
+
+
+
+Deutsch                      Informational                      [Page 7]
+
+RFC 1952             GZIP File Format Specification             May 1996
+
+
+                 0 - FAT filesystem (MS-DOS, OS/2, NT/Win32)
+                 1 - Amiga
+                 2 - VMS (or OpenVMS)
+                 3 - Unix
+                 4 - VM/CMS
+                 5 - Atari TOS
+                 6 - HPFS filesystem (OS/2, NT)
+                 7 - Macintosh
+                 8 - Z-System
+                 9 - CP/M
+                10 - TOPS-20
+                11 - NTFS filesystem (NT)
+                12 - QDOS
+                13 - Acorn RISCOS
+               255 - unknown
+
+         XLEN (eXtra LENgth)
+            If FLG.FEXTRA is set, this gives the length of the optional
+            extra field.  See below for details.
+
+         CRC32 (CRC-32)
+            This contains a Cyclic Redundancy Check value of the
+            uncompressed data computed according to CRC-32 algorithm
+            used in the ISO 3309 standard and in section 8.1.1.6.2 of
+            ITU-T recommendation V.42.  (See http://www.iso.ch for
+            ordering ISO documents. See gopher://info.itu.ch for an
+            online version of ITU-T V.42.)
+
+         ISIZE (Input SIZE)
+            This contains the size of the original (uncompressed) input
+            data modulo 2^32.
+
+      2.3.1.1. Extra field
+
+         If the FLG.FEXTRA bit is set, an "extra field" is present in
+         the header, with total length XLEN bytes.  It consists of a
+         series of subfields, each of the form:
+
+            +---+---+---+---+==================================+
+            |SI1|SI2|  LEN  |... LEN bytes of subfield data ...|
+            +---+---+---+---+==================================+
+
+         SI1 and SI2 provide a subfield ID, typically two ASCII letters
+         with some mnemonic value.  Jean-Loup Gailly
+         <gzip@prep.ai.mit.edu> is maintaining a registry of subfield
+         IDs; please send him any subfield ID you wish to use.  Subfield
+         IDs with SI2 = 0 are reserved for future use.  The following
+         IDs are currently defined:
+
+
+
+Deutsch                      Informational                      [Page 8]
+
+RFC 1952             GZIP File Format Specification             May 1996
+
+
+            SI1         SI2         Data
+            ----------  ----------  ----
+            0x41 ('A')  0x70 ('P')  Apollo file type information
+
+         LEN gives the length of the subfield data, excluding the 4
+         initial bytes.
+
+      2.3.1.2. Compliance
+
+         A compliant compressor must produce files with correct ID1,
+         ID2, CM, CRC32, and ISIZE, but may set all the other fields in
+         the fixed-length part of the header to default values (255 for
+         OS, 0 for all others).  The compressor must set all reserved
+         bits to zero.
+
+         A compliant decompressor must check ID1, ID2, and CM, and
+         provide an error indication if any of these have incorrect
+         values.  It must examine FEXTRA/XLEN, FNAME, FCOMMENT and FHCRC
+         at least so it can skip over the optional fields if they are
+         present.  It need not examine any other part of the header or
+         trailer; in particular, a decompressor may ignore FTEXT and OS
+         and always produce binary output, and still be compliant.  A
+         compliant decompressor must give an error indication if any
+         reserved bit is non-zero, since such a bit could indicate the
+         presence of a new field that would cause subsequent data to be
+         interpreted incorrectly.
+
+3. References
+
+   [1] "Information Processing - 8-bit single-byte coded graphic
+       character sets - Part 1: Latin alphabet No.1" (ISO 8859-1:1987).
+       The ISO 8859-1 (Latin-1) character set is a superset of 7-bit
+       ASCII. Files defining this character set are available as
+       iso_8859-1.* in ftp://ftp.uu.net/graphics/png/documents/
+
+   [2] ISO 3309
+
+   [3] ITU-T recommendation V.42
+
+   [4] Deutsch, L.P.,"DEFLATE Compressed Data Format Specification",
+       available in ftp://ftp.uu.net/pub/archiving/zip/doc/
+
+   [5] Gailly, J.-L., GZIP documentation, available as gzip-*.tar in
+       ftp://prep.ai.mit.edu/pub/gnu/
+
+   [6] Sarwate, D.V., "Computation of Cyclic Redundancy Checks via Table
+       Look-Up", Communications of the ACM, 31(8), pp.1008-1013.
+
+
+
+
+Deutsch                      Informational                      [Page 9]
+
+RFC 1952             GZIP File Format Specification             May 1996
+
+
+   [7] Schwaderer, W.D., "CRC Calculation", April 85 PC Tech Journal,
+       pp.118-133.
+
+   [8] ftp://ftp.adelaide.edu.au/pub/rocksoft/papers/crc_v3.txt,
+       describing the CRC concept.
+
+4. Security Considerations
+
+   Any data compression method involves the reduction of redundancy in
+   the data.  Consequently, any corruption of the data is likely to have
+   severe effects and be difficult to correct.  Uncompressed text, on
+   the other hand, will probably still be readable despite the presence
+   of some corrupted bytes.
+
+   It is recommended that systems using this data format provide some
+   means of validating the integrity of the compressed data, such as by
+   setting and checking the CRC-32 check value.
+
+5. Acknowledgements
+
+   Trademarks cited in this document are the property of their
+   respective owners.
+
+   Jean-Loup Gailly designed the gzip format and wrote, with Mark Adler,
+   the related software described in this specification.  Glenn
+   Randers-Pehrson converted this document to RFC and HTML format.
+
+6. Author's Address
+
+   L. Peter Deutsch
+   Aladdin Enterprises
+   203 Santa Margarita Ave.
+   Menlo Park, CA 94025
+
+   Phone: (415) 322-0103 (AM only)
+   FAX:   (415) 322-1734
+   EMail: <ghost@aladdin.com>
+
+   Questions about the technical content of this specification can be
+   sent by email to:
+
+   Jean-Loup Gailly <gzip@prep.ai.mit.edu> and
+   Mark Adler <madler@alumni.caltech.edu>
+
+   Editorial comments on this specification can be sent by email to:
+
+   L. Peter Deutsch <ghost@aladdin.com> and
+   Glenn Randers-Pehrson <randeg@alumni.rpi.edu>
+
+
+
+Deutsch                      Informational                     [Page 10]
+
+RFC 1952             GZIP File Format Specification             May 1996
+
+
+7. Appendix: Jean-Loup Gailly's gzip utility
+
+   The most widely used implementation of gzip compression, and the
+   original documentation on which this specification is based, were
+   created by Jean-Loup Gailly <gzip@prep.ai.mit.edu>.  Since this
+   implementation is a de facto standard, we mention some more of its
+   features here.  Again, the material in this section is not part of
+   the specification per se, and implementations need not follow it to
+   be compliant.
+
+   When compressing or decompressing a file, gzip preserves the
+   protection, ownership, and modification time attributes on the local
+   file system, since there is no provision for representing protection
+   attributes in the gzip file format itself.  Since the file format
+   includes a modification time, the gzip decompressor provides a
+   command line switch that assigns the modification time from the file,
+   rather than the local modification time of the compressed input, to
+   the decompressed output.
+
+8. Appendix: Sample CRC Code
+
+   The following sample code represents a practical implementation of
+   the CRC (Cyclic Redundancy Check). (See also ISO 3309 and ITU-T V.42
+   for a formal specification.)
+
+   The sample code is in the ANSI C programming language. Non C users
+   may find it easier to read with these hints:
+
+      &      Bitwise AND operator.
+      ^      Bitwise exclusive-OR operator.
+      >>     Bitwise right shift operator. When applied to an
+             unsigned quantity, as here, right shift inserts zero
+             bit(s) at the left.
+      !      Logical NOT operator.
+      ++     "n++" increments the variable n.
+      0xNNN  0x introduces a hexadecimal (base 16) constant.
+             Suffix L indicates a long value (at least 32 bits).
+
+      /* Table of CRCs of all 8-bit messages. */
+      unsigned long crc_table[256];
+
+      /* Flag: has the table been computed? Initially false. */
+      int crc_table_computed = 0;
+
+      /* Make the table for a fast CRC. */
+      void make_crc_table(void)
+      {
+        unsigned long c;
+
+
+
+Deutsch                      Informational                     [Page 11]
+
+RFC 1952             GZIP File Format Specification             May 1996
+
+
+        int n, k;
+        for (n = 0; n < 256; n++) {
+          c = (unsigned long) n;
+          for (k = 0; k < 8; k++) {
+            if (c & 1) {
+              c = 0xedb88320L ^ (c >> 1);
+            } else {
+              c = c >> 1;
+            }
+          }
+          crc_table[n] = c;
+        }
+        crc_table_computed = 1;
+      }
+
+      /*
+         Update a running crc with the bytes buf[0..len-1] and return
+       the updated crc. The crc should be initialized to zero. Pre- and
+       post-conditioning (one's complement) is performed within this
+       function so it shouldn't be done by the caller. Usage example:
+
+         unsigned long crc = 0L;
+
+         while (read_buffer(buffer, length) != EOF) {
+           crc = update_crc(crc, buffer, length);
+         }
+         if (crc != original_crc) error();
+      */
+      unsigned long update_crc(unsigned long crc,
+                      unsigned char *buf, int len)
+      {
+        unsigned long c = crc ^ 0xffffffffL;
+        int n;
+
+        if (!crc_table_computed)
+          make_crc_table();
+        for (n = 0; n < len; n++) {
+          c = crc_table[(c ^ buf[n]) & 0xff] ^ (c >> 8);
+        }
+        return c ^ 0xffffffffL;
+      }
+
+      /* Return the CRC of the bytes buf[0..len-1]. */
+      unsigned long crc(unsigned char *buf, int len)
+      {
+        return update_crc(0L, buf, len);
+      }
+
+
+
+
+Deutsch                      Informational                     [Page 12]
+
diff --git a/compat/zlib/doc/txtvsbin.txt b/compat/zlib/doc/txtvsbin.txt
new file mode 100644
index 0000000..3d0f063
--- /dev/null
+++ b/compat/zlib/doc/txtvsbin.txt
@@ -0,0 +1,107 @@
+A Fast Method for Identifying Plain Text Files
+==============================================
+
+
+Introduction
+------------
+
+Given a file coming from an unknown source, it is sometimes desirable
+to find out whether the format of that file is plain text.  Although
+this may appear like a simple task, a fully accurate detection of the
+file type requires heavy-duty semantic analysis on the file contents.
+It is, however, possible to obtain satisfactory results by employing
+various heuristics.
+
+Previous versions of PKZip and other zip-compatible compression tools
+were using a crude detection scheme: if more than 80% (4/5) of the bytes
+found in a certain buffer are within the range [7..127], the file is
+labeled as plain text, otherwise it is labeled as binary.  A prominent
+limitation of this scheme is the restriction to Latin-based alphabets.
+Other alphabets, like Greek, Cyrillic or Asian, make extensive use of
+the bytes within the range [128..255], and texts using these alphabets
+are most often misidentified by this scheme; in other words, the rate
+of false negatives is sometimes too high, which means that the recall
+is low.  Another weakness of this scheme is a reduced precision, due to
+the false positives that may occur when binary files containing large
+amounts of textual characters are misidentified as plain text.
+
+In this article we propose a new, simple detection scheme that features
+a much increased precision and a near-100% recall.  This scheme is
+designed to work on ASCII, Unicode and other ASCII-derived alphabets,
+and it handles single-byte encodings (ISO-8859, MacRoman, KOI8, etc.)
+and variable-sized encodings (ISO-2022, UTF-8, etc.).  Wider encodings
+(UCS-2/UTF-16 and UCS-4/UTF-32) are not handled, however.
+
+
+The Algorithm
+-------------
+
+The algorithm works by dividing the set of bytecodes [0..255] into three
+categories:
+- The white list of textual bytecodes:
+  9 (TAB), 10 (LF), 13 (CR), 32 (SPACE) to 255.
+- The gray list of tolerated bytecodes:
+  7 (BEL), 8 (BS), 11 (VT), 12 (FF), 26 (SUB), 27 (ESC).
+- The black list of undesired, non-textual bytecodes:
+  0 (NUL) to 6, 14 to 31.
+
+If a file contains at least one byte that belongs to the white list and
+no byte that belongs to the black list, then the file is categorized as
+plain text; otherwise, it is categorized as binary.  (The boundary case,
+when the file is empty, automatically falls into the latter category.)
+
+
+Rationale
+---------
+
+The idea behind this algorithm relies on two observations.
+
+The first observation is that, although the full range of 7-bit codes
+[0..127] is properly specified by the ASCII standard, most control
+characters in the range [0..31] are not used in practice.  The only
+widely-used, almost universally-portable control codes are 9 (TAB),
+10 (LF) and 13 (CR).  There are a few more control codes that are
+recognized on a reduced range of platforms and text viewers/editors:
+7 (BEL), 8 (BS), 11 (VT), 12 (FF), 26 (SUB) and 27 (ESC); but these
+codes are rarely (if ever) used alone, without being accompanied by
+some printable text.  Even the newer, portable text formats such as
+XML avoid using control characters outside the list mentioned here.
+
+The second observation is that most of the binary files tend to contain
+control characters, especially 0 (NUL).  Even though the older text
+detection schemes observe the presence of non-ASCII codes from the range
+[128..255], the precision rarely has to suffer if this upper range is
+labeled as textual, because the files that are genuinely binary tend to
+contain both control characters and codes from the upper range.  On the
+other hand, the upper range needs to be labeled as textual, because it
+is used by virtually all ASCII extensions.  In particular, this range is
+used for encoding non-Latin scripts.
+
+Since there is no counting involved, other than simply observing the
+presence or the absence of some byte values, the algorithm produces
+consistent results, regardless what alphabet encoding is being used.
+(If counting were involved, it could be possible to obtain different
+results on a text encoded, say, using ISO-8859-16 versus UTF-8.)
+
+There is an extra category of plain text files that are "polluted" with
+one or more black-listed codes, either by mistake or by peculiar design
+considerations.  In such cases, a scheme that tolerates a small fraction
+of black-listed codes would provide an increased recall (i.e. more true
+positives).  This, however, incurs a reduced precision overall, since
+false positives are more likely to appear in binary files that contain
+large chunks of textual data.  Furthermore, "polluted" plain text should
+be regarded as binary by general-purpose text detection schemes, because
+general-purpose text processing algorithms might not be applicable.
+Under this premise, it is safe to say that our detection method provides
+a near-100% recall.
+
+Experiments have been run on many files coming from various platforms
+and applications.  We tried plain text files, system logs, source code,
+formatted office documents, compiled object code, etc.  The results
+confirm the optimistic assumptions about the capabilities of this
+algorithm.
+
+
+--
+Cosmin Truta
+Last updated: 2006-May-28
diff --git a/compat/zlib/examples/README.examples b/compat/zlib/examples/README.examples
new file mode 100644
index 0000000..56a3171
--- /dev/null
+++ b/compat/zlib/examples/README.examples
@@ -0,0 +1,49 @@
+This directory contains examples of the use of zlib and other relevant
+programs and documentation.
+
+enough.c
+    calculation and justification of ENOUGH parameter in inftrees.h
+    - calculates the maximum table space used in inflate tree
+      construction over all possible Huffman codes
+
+fitblk.c
+    compress just enough input to nearly fill a requested output size
+    - zlib isn't designed to do this, but fitblk does it anyway
+
+gun.c
+    uncompress a gzip file
+    - illustrates the use of inflateBack() for high speed file-to-file
+      decompression using call-back functions
+    - is approximately twice as fast as gzip -d
+    - also provides Unix uncompress functionality, again twice as fast
+
+gzappend.c
+    append to a gzip file
+    - illustrates the use of the Z_BLOCK flush parameter for inflate()
+    - illustrates the use of deflatePrime() to start at any bit
+
+gzjoin.c
+    join gzip files without recalculating the crc or recompressing
+    - illustrates the use of the Z_BLOCK flush parameter for inflate()
+    - illustrates the use of crc32_combine()
+
+gzlog.c
+gzlog.h
+    efficiently and robustly maintain a message log file in gzip format
+    - illustrates use of raw deflate, Z_PARTIAL_FLUSH, deflatePrime(),
+      and deflateSetDictionary()
+    - illustrates use of a gzip header extra field
+
+zlib_how.html
+    painfully comprehensive description of zpipe.c (see below)
+    - describes in excruciating detail the use of deflate() and inflate()
+
+zpipe.c
+    reads and writes zlib streams from stdin to stdout
+    - illustrates the proper use of deflate() and inflate()
+    - deeply commented in zlib_how.html (see above)
+
+zran.c
+    index a zlib or gzip stream and randomly access it
+    - illustrates the use of Z_BLOCK, inflatePrime(), and
+      inflateSetDictionary() to provide random access
diff --git a/compat/zlib/examples/enough.c b/compat/zlib/examples/enough.c
new file mode 100644
index 0000000..b991144
--- /dev/null
+++ b/compat/zlib/examples/enough.c
@@ -0,0 +1,572 @@
+/* enough.c -- determine the maximum size of inflate's Huffman code tables over
+ * all possible valid and complete Huffman codes, subject to a length limit.
+ * Copyright (C) 2007, 2008, 2012 Mark Adler
+ * Version 1.4  18 August 2012  Mark Adler
+ */
+
+/* Version history:
+   1.0   3 Jan 2007  First version (derived from codecount.c version 1.4)
+   1.1   4 Jan 2007  Use faster incremental table usage computation
+                     Prune examine() search on previously visited states
+   1.2   5 Jan 2007  Comments clean up
+                     As inflate does, decrease root for short codes
+                     Refuse cases where inflate would increase root
+   1.3  17 Feb 2008  Add argument for initial root table size
+                     Fix bug for initial root table size == max - 1
+                     Use a macro to compute the history index
+   1.4  18 Aug 2012  Avoid shifts more than bits in type (caused endless loop!)
+                     Clean up comparisons of different types
+                     Clean up code indentation
+ */
+
+/*
+   Examine all possible Huffman codes for a given number of symbols and a
+   maximum code length in bits to determine the maximum table size for zilb's
+   inflate.  Only complete Huffman codes are counted.
+
+   Two codes are considered distinct if the vectors of the number of codes per
+   length are not identical.  So permutations of the symbol assignments result
+   in the same code for the counting, as do permutations of the assignments of
+   the bit values to the codes (i.e. only canonical codes are counted).
+
+   We build a code from shorter to longer lengths, determining how many symbols
+   are coded at each length.  At each step, we have how many symbols remain to
+   be coded, what the last code length used was, and how many bit patterns of
+   that length remain unused. Then we add one to the code length and double the
+   number of unused patterns to graduate to the next code length.  We then
+   assign all portions of the remaining symbols to that code length that
+   preserve the properties of a correct and eventually complete code.  Those
+   properties are: we cannot use more bit patterns than are available; and when
+   all the symbols are used, there are exactly zero possible bit patterns
+   remaining.
+
+   The inflate Huffman decoding algorithm uses two-level lookup tables for
+   speed.  There is a single first-level table to decode codes up to root bits
+   in length (root == 9 in the current inflate implementation).  The table
+   has 1 << root entries and is indexed by the next root bits of input.  Codes
+   shorter than root bits have replicated table entries, so that the correct
+   entry is pointed to regardless of the bits that follow the short code.  If
+   the code is longer than root bits, then the table entry points to a second-
+   level table.  The size of that table is determined by the longest code with
+   that root-bit prefix.  If that longest code has length len, then the table
+   has size 1 << (len - root), to index the remaining bits in that set of
+   codes.  Each subsequent root-bit prefix then has its own sub-table.  The
+   total number of table entries required by the code is calculated
+   incrementally as the number of codes at each bit length is populated.  When
+   all of the codes are shorter than root bits, then root is reduced to the
+   longest code length, resulting in a single, smaller, one-level table.
+
+   The inflate algorithm also provides for small values of root (relative to
+   the log2 of the number of symbols), where the shortest code has more bits
+   than root.  In that case, root is increased to the length of the shortest
+   code.  This program, by design, does not handle that case, so it is verified
+   that the number of symbols is less than 2^(root + 1).
+
+   In order to speed up the examination (by about ten orders of magnitude for
+   the default arguments), the intermediate states in the build-up of a code
+   are remembered and previously visited branches are pruned.  The memory
+   required for this will increase rapidly with the total number of symbols and
+   the maximum code length in bits.  However this is a very small price to pay
+   for the vast speedup.
+
+   First, all of the possible Huffman codes are counted, and reachable
+   intermediate states are noted by a non-zero count in a saved-results array.
+   Second, the intermediate states that lead to (root + 1) bit or longer codes
+   are used to look at all sub-codes from those junctures for their inflate
+   memory usage.  (The amount of memory used is not affected by the number of
+   codes of root bits or less in length.)  Third, the visited states in the
+   construction of those sub-codes and the associated calculation of the table
+   size is recalled in order to avoid recalculating from the same juncture.
+   Beginning the code examination at (root + 1) bit codes, which is enabled by
+   identifying the reachable nodes, accounts for about six of the orders of
+   magnitude of improvement for the default arguments.  About another four
+   orders of magnitude come from not revisiting previous states.  Out of
+   approximately 2x10^16 possible Huffman codes, only about 2x10^6 sub-codes
+   need to be examined to cover all of the possible table memory usage cases
+   for the default arguments of 286 symbols limited to 15-bit codes.
+
+   Note that an unsigned long long type is used for counting.  It is quite easy
+   to exceed the capacity of an eight-byte integer with a large number of
+   symbols and a large maximum code length, so multiple-precision arithmetic
+   would need to replace the unsigned long long arithmetic in that case.  This
+   program will abort if an overflow occurs.  The big_t type identifies where
+   the counting takes place.
+
+   An unsigned long long type is also used for calculating the number of
+   possible codes remaining at the maximum length.  This limits the maximum
+   code length to the number of bits in a long long minus the number of bits
+   needed to represent the symbols in a flat code.  The code_t type identifies
+   where the bit pattern counting takes place.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#define local static
+
+/* special data types */
+typedef unsigned long long big_t;   /* type for code counting */
+typedef unsigned long long code_t;  /* type for bit pattern counting */
+struct tab {                        /* type for been here check */
+    size_t len;         /* length of bit vector in char's */
+    char *vec;          /* allocated bit vector */
+};
+
+/* The array for saving results, num[], is indexed with this triplet:
+
+      syms: number of symbols remaining to code
+      left: number of available bit patterns at length len
+      len: number of bits in the codes currently being assigned
+
+   Those indices are constrained thusly when saving results:
+
+      syms: 3..totsym (totsym == total symbols to code)
+      left: 2..syms - 1, but only the evens (so syms == 8 -> 2, 4, 6)
+      len: 1..max - 1 (max == maximum code length in bits)
+
+   syms == 2 is not saved since that immediately leads to a single code.  left
+   must be even, since it represents the number of available bit patterns at
+   the current length, which is double the number at the previous length.
+   left ends at syms-1 since left == syms immediately results in a single code.
+   (left > sym is not allowed since that would result in an incomplete code.)
+   len is less than max, since the code completes immediately when len == max.
+
+   The offset into the array is calculated for the three indices with the
+   first one (syms) being outermost, and the last one (len) being innermost.
+   We build the array with length max-1 lists for the len index, with syms-3
+   of those for each symbol.  There are totsym-2 of those, with each one
+   varying in length as a function of sym.  See the calculation of index in
+   count() for the index, and the calculation of size in main() for the size
+   of the array.
+
+   For the deflate example of 286 symbols limited to 15-bit codes, the array
+   has 284,284 entries, taking up 2.17 MB for an 8-byte big_t.  More than
+   half of the space allocated for saved results is actually used -- not all
+   possible triplets are reached in the generation of valid Huffman codes.
+ */
+
+/* The array for tracking visited states, done[], is itself indexed identically
+   to the num[] array as described above for the (syms, left, len) triplet.
+   Each element in the array is further indexed by the (mem, rem) doublet,
+   where mem is the amount of inflate table space used so far, and rem is the
+   remaining unused entries in the current inflate sub-table.  Each indexed
+   element is simply one bit indicating whether the state has been visited or
+   not.  Since the ranges for mem and rem are not known a priori, each bit
+   vector is of a variable size, and grows as needed to accommodate the visited
+   states.  mem and rem are used to calculate a single index in a triangular
+   array.  Since the range of mem is expected in the default case to be about
+   ten times larger than the range of rem, the array is skewed to reduce the
+   memory usage, with eight times the range for mem than for rem.  See the
+   calculations for offset and bit in beenhere() for the details.
+
+   For the deflate example of 286 symbols limited to 15-bit codes, the bit
+   vectors grow to total approximately 21 MB, in addition to the 4.3 MB done[]
+   array itself.
+ */
+
+/* Globals to avoid propagating constants or constant pointers recursively */
+local int max;          /* maximum allowed bit length for the codes */
+local int root;         /* size of base code table in bits */
+local int large;        /* largest code table so far */
+local size_t size;      /* number of elements in num and done */
+local int *code;        /* number of symbols assigned to each bit length */
+local big_t *num;       /* saved results array for code counting */
+local struct tab *done; /* states already evaluated array */
+
+/* Index function for num[] and done[] */
+#define INDEX(i,j,k) (((size_t)((i-1)>>1)*((i-2)>>1)+(j>>1)-1)*(max-1)+k-1)
+
+/* Free allocated space.  Uses globals code, num, and done. */
+local void cleanup(void)
+{
+    size_t n;
+
+    if (done != NULL) {
+        for (n = 0; n < size; n++)
+            if (done[n].len)
+                free(done[n].vec);
+        free(done);
+    }
+    if (num != NULL)
+        free(num);
+    if (code != NULL)
+        free(code);
+}
+
+/* Return the number of possible Huffman codes using bit patterns of lengths
+   len through max inclusive, coding syms symbols, with left bit patterns of
+   length len unused -- return -1 if there is an overflow in the counting.
+   Keep a record of previous results in num to prevent repeating the same
+   calculation.  Uses the globals max and num. */
+local big_t count(int syms, int len, int left)
+{
+    big_t sum;          /* number of possible codes from this juncture */
+    big_t got;          /* value returned from count() */
+    int least;          /* least number of syms to use at this juncture */
+    int most;           /* most number of syms to use at this juncture */
+    int use;            /* number of bit patterns to use in next call */
+    size_t index;       /* index of this case in *num */
+
+    /* see if only one possible code */
+    if (syms == left)
+        return 1;
+
+    /* note and verify the expected state */
+    assert(syms > left && left > 0 && len < max);
+
+    /* see if we've done this one already */
+    index = INDEX(syms, left, len);
+    got = num[index];
+    if (got)
+        return got;         /* we have -- return the saved result */
+
+    /* we need to use at least this many bit patterns so that the code won't be
+       incomplete at the next length (more bit patterns than symbols) */
+    least = (left << 1) - syms;
+    if (least < 0)
+        least = 0;
+
+    /* we can use at most this many bit patterns, lest there not be enough
+       available for the remaining symbols at the maximum length (if there were
+       no limit to the code length, this would become: most = left - 1) */
+    most = (((code_t)left << (max - len)) - syms) /
+            (((code_t)1 << (max - len)) - 1);
+
+    /* count all possible codes from this juncture and add them up */
+    sum = 0;
+    for (use = least; use <= most; use++) {
+        got = count(syms - use, len + 1, (left - use) << 1);
+        sum += got;
+        if (got == (big_t)0 - 1 || sum < got)   /* overflow */
+            return (big_t)0 - 1;
+    }
+
+    /* verify that all recursive calls are productive */
+    assert(sum != 0);
+
+    /* save the result and return it */
+    num[index] = sum;
+    return sum;
+}
+
+/* Return true if we've been here before, set to true if not.  Set a bit in a
+   bit vector to indicate visiting this state.  Each (syms,len,left) state
+   has a variable size bit vector indexed by (mem,rem).  The bit vector is
+   lengthened if needed to allow setting the (mem,rem) bit. */
+local int beenhere(int syms, int len, int left, int mem, int rem)
+{
+    size_t index;       /* index for this state's bit vector */
+    size_t offset;      /* offset in this state's bit vector */
+    int bit;            /* mask for this state's bit */
+    size_t length;      /* length of the bit vector in bytes */
+    char *vector;       /* new or enlarged bit vector */
+
+    /* point to vector for (syms,left,len), bit in vector for (mem,rem) */
+    index = INDEX(syms, left, len);
+    mem -= 1 << root;
+    offset = (mem >> 3) + rem;
+    offset = ((offset * (offset + 1)) >> 1) + rem;
+    bit = 1 << (mem & 7);
+
+    /* see if we've been here */
+    length = done[index].len;
+    if (offset < length && (done[index].vec[offset] & bit) != 0)
+        return 1;       /* done this! */
+
+    /* we haven't been here before -- set the bit to show we have now */
+
+    /* see if we need to lengthen the vector in order to set the bit */
+    if (length <= offset) {
+        /* if we have one already, enlarge it, zero out the appended space */
+        if (length) {
+            do {
+                length <<= 1;
+            } while (length <= offset);
+            vector = realloc(done[index].vec, length);
+            if (vector != NULL)
+                memset(vector + done[index].len, 0, length - done[index].len);
+        }
+
+        /* otherwise we need to make a new vector and zero it out */
+        else {
+            length = 1 << (len - root);
+            while (length <= offset)
+                length <<= 1;
+            vector = calloc(length, sizeof(char));
+        }
+
+        /* in either case, bail if we can't get the memory */
+        if (vector == NULL) {
+            fputs("abort: unable to allocate enough memory\n", stderr);
+            cleanup();
+            exit(1);
+        }
+
+        /* install the new vector */
+        done[index].len = length;
+        done[index].vec = vector;
+    }
+
+    /* set the bit */
+    done[index].vec[offset] |= bit;
+    return 0;
+}
+
+/* Examine all possible codes from the given node (syms, len, left).  Compute
+   the amount of memory required to build inflate's decoding tables, where the
+   number of code structures used so far is mem, and the number remaining in
+   the current sub-table is rem.  Uses the globals max, code, root, large, and
+   done. */
+local void examine(int syms, int len, int left, int mem, int rem)
+{
+    int least;          /* least number of syms to use at this juncture */
+    int most;           /* most number of syms to use at this juncture */
+    int use;            /* number of bit patterns to use in next call */
+
+    /* see if we have a complete code */
+    if (syms == left) {
+        /* set the last code entry */
+        code[len] = left;
+
+        /* complete computation of memory used by this code */
+        while (rem < left) {
+            left -= rem;
+            rem = 1 << (len - root);
+            mem += rem;
+        }
+        assert(rem == left);
+
+        /* if this is a new maximum, show the entries used and the sub-code */
+        if (mem > large) {
+            large = mem;
+            printf("max %d: ", mem);
+            for (use = root + 1; use <= max; use++)
+                if (code[use])
+                    printf("%d[%d] ", code[use], use);
+            putchar('\n');
+            fflush(stdout);
+        }
+
+        /* remove entries as we drop back down in the recursion */
+        code[len] = 0;
+        return;
+    }
+
+    /* prune the tree if we can */
+    if (beenhere(syms, len, left, mem, rem))
+        return;
+
+    /* we need to use at least this many bit patterns so that the code won't be
+       incomplete at the next length (more bit patterns than symbols) */
+    least = (left << 1) - syms;
+    if (least < 0)
+        least = 0;
+
+    /* we can use at most this many bit patterns, lest there not be enough
+       available for the remaining symbols at the maximum length (if there were
+       no limit to the code length, this would become: most = left - 1) */
+    most = (((code_t)left << (max - len)) - syms) /
+            (((code_t)1 << (max - len)) - 1);
+
+    /* occupy least table spaces, creating new sub-tables as needed */
+    use = least;
+    while (rem < use) {
+        use -= rem;
+        rem = 1 << (len - root);
+        mem += rem;
+    }
+    rem -= use;
+
+    /* examine codes from here, updating table space as we go */
+    for (use = least; use <= most; use++) {
+        code[len] = use;
+        examine(syms - use, len + 1, (left - use) << 1,
+                mem + (rem ? 1 << (len - root) : 0), rem << 1);
+        if (rem == 0) {
+            rem = 1 << (len - root);
+            mem += rem;
+        }
+        rem--;
+    }
+
+    /* remove entries as we drop back down in the recursion */
+    code[len] = 0;
+}
+
+/* Look at all sub-codes starting with root + 1 bits.  Look at only the valid
+   intermediate code states (syms, left, len).  For each completed code,
+   calculate the amount of memory required by inflate to build the decoding
+   tables. Find the maximum amount of memory required and show the code that
+   requires that maximum.  Uses the globals max, root, and num. */
+local void enough(int syms)
+{
+    int n;              /* number of remaing symbols for this node */
+    int left;           /* number of unused bit patterns at this length */
+    size_t index;       /* index of this case in *num */
+
+    /* clear code */
+    for (n = 0; n <= max; n++)
+        code[n] = 0;
+
+    /* look at all (root + 1) bit and longer codes */
+    large = 1 << root;              /* base table */
+    if (root < max)                 /* otherwise, there's only a base table */
+        for (n = 3; n <= syms; n++)
+            for (left = 2; left < n; left += 2)
+            {
+                /* look at all reachable (root + 1) bit nodes, and the
+                   resulting codes (complete at root + 2 or more) */
+                index = INDEX(n, left, root + 1);
+                if (root + 1 < max && num[index])       /* reachable node */
+                    examine(n, root + 1, left, 1 << root, 0);
+
+                /* also look at root bit codes with completions at root + 1
+                   bits (not saved in num, since complete), just in case */
+                if (num[index - 1] && n <= left << 1)
+                    examine((n - left) << 1, root + 1, (n - left) << 1,
+                            1 << root, 0);
+            }
+
+    /* done */
+    printf("done: maximum of %d table entries\n", large);
+}
+
+/*
+   Examine and show the total number of possible Huffman codes for a given
+   maximum number of symbols, initial root table size, and maximum code length
+   in bits -- those are the command arguments in that order.  The default
+   values are 286, 9, and 15 respectively, for the deflate literal/length code.
+   The possible codes are counted for each number of coded symbols from two to
+   the maximum.  The counts for each of those and the total number of codes are
+   shown.  The maximum number of inflate table entires is then calculated
+   across all possible codes.  Each new maximum number of table entries and the
+   associated sub-code (starting at root + 1 == 10 bits) is shown.
+
+   To count and examine Huffman codes that are not length-limited, provide a
+   maximum length equal to the number of symbols minus one.
+
+   For the deflate literal/length code, use "enough".  For the deflate distance
+   code, use "enough 30 6".
+
+   This uses the %llu printf format to print big_t numbers, which assumes that
+   big_t is an unsigned long long.  If the big_t type is changed (for example
+   to a multiple precision type), the method of printing will also need to be
+   updated.
+ */
+int main(int argc, char **argv)
+{
+    int syms;           /* total number of symbols to code */
+    int n;              /* number of symbols to code for this run */
+    big_t got;          /* return value of count() */
+    big_t sum;          /* accumulated number of codes over n */
+    code_t word;        /* for counting bits in code_t */
+
+    /* set up globals for cleanup() */
+    code = NULL;
+    num = NULL;
+    done = NULL;
+
+    /* get arguments -- default to the deflate literal/length code */
+    syms = 286;
+    root = 9;
+    max = 15;
+    if (argc > 1) {
+        syms = atoi(argv[1]);
+        if (argc > 2) {
+            root = atoi(argv[2]);
+            if (argc > 3)
+                max = atoi(argv[3]);
+        }
+    }
+    if (argc > 4 || syms < 2 || root < 1 || max < 1) {
+        fputs("invalid arguments, need: [sym >= 2 [root >= 1 [max >= 1]]]\n",
+              stderr);
+        return 1;
+    }
+
+    /* if not restricting the code length, the longest is syms - 1 */
+    if (max > syms - 1)
+        max = syms - 1;
+
+    /* determine the number of bits in a code_t */
+    for (n = 0, word = 1; word; n++, word <<= 1)
+        ;
+
+    /* make sure that the calculation of most will not overflow */
+    if (max > n || (code_t)(syms - 2) >= (((code_t)0 - 1) >> (max - 1))) {
+        fputs("abort: code length too long for internal types\n", stderr);
+        return 1;
+    }
+
+    /* reject impossible code requests */
+    if ((code_t)(syms - 1) > ((code_t)1 << max) - 1) {
+        fprintf(stderr, "%d symbols cannot be coded in %d bits\n",
+                syms, max);
+        return 1;
+    }
+
+    /* allocate code vector */
+    code = calloc(max + 1, sizeof(int));
+    if (code == NULL) {
+        fputs("abort: unable to allocate enough memory\n", stderr);
+        return 1;
+    }
+
+    /* determine size of saved results array, checking for overflows,
+       allocate and clear the array (set all to zero with calloc()) */
+    if (syms == 2)              /* iff max == 1 */
+        num = NULL;             /* won't be saving any results */
+    else {
+        size = syms >> 1;
+        if (size > ((size_t)0 - 1) / (n = (syms - 1) >> 1) ||
+                (size *= n, size > ((size_t)0 - 1) / (n = max - 1)) ||
+                (size *= n, size > ((size_t)0 - 1) / sizeof(big_t)) ||
+                (num = calloc(size, sizeof(big_t))) == NULL) {
+            fputs("abort: unable to allocate enough memory\n", stderr);
+            cleanup();
+            return 1;
+        }
+    }
+
+    /* count possible codes for all numbers of symbols, add up counts */
+    sum = 0;
+    for (n = 2; n <= syms; n++) {
+        got = count(n, 1, 2);
+        sum += got;
+        if (got == (big_t)0 - 1 || sum < got) {     /* overflow */
+            fputs("abort: can't count that high!\n", stderr);
+            cleanup();
+            return 1;
+        }
+        printf("%llu %d-codes\n", got, n);
+    }
+    printf("%llu total codes for 2 to %d symbols", sum, syms);
+    if (max < syms - 1)
+        printf(" (%d-bit length limit)\n", max);
+    else
+        puts(" (no length limit)");
+
+    /* allocate and clear done array for beenhere() */
+    if (syms == 2)
+        done = NULL;
+    else if (size > ((size_t)0 - 1) / sizeof(struct tab) ||
+             (done = calloc(size, sizeof(struct tab))) == NULL) {
+        fputs("abort: unable to allocate enough memory\n", stderr);
+        cleanup();
+        return 1;
+    }
+
+    /* find and show maximum inflate table usage */
+    if (root > max)                 /* reduce root to max length */
+        root = max;
+    if ((code_t)syms < ((code_t)1 << (root + 1)))
+        enough(syms);
+    else
+        puts("cannot handle minimum code lengths > root");
+
+    /* done */
+    cleanup();
+    return 0;
+}
diff --git a/compat/zlib/examples/fitblk.c b/compat/zlib/examples/fitblk.c
new file mode 100644
index 0000000..c61de5c
--- /dev/null
+++ b/compat/zlib/examples/fitblk.c
@@ -0,0 +1,233 @@
+/* fitblk.c: example of fitting compressed output to a specified size
+   Not copyrighted -- provided to the public domain
+   Version 1.1  25 November 2004  Mark Adler */
+
+/* Version history:
+   1.0  24 Nov 2004  First version
+   1.1  25 Nov 2004  Change deflateInit2() to deflateInit()
+                     Use fixed-size, stack-allocated raw buffers
+                     Simplify code moving compression to subroutines
+                     Use assert() for internal errors
+                     Add detailed description of approach
+ */
+
+/* Approach to just fitting a requested compressed size:
+
+   fitblk performs three compression passes on a portion of the input
+   data in order to determine how much of that input will compress to
+   nearly the requested output block size.  The first pass generates
+   enough deflate blocks to produce output to fill the requested
+   output size plus a specfied excess amount (see the EXCESS define
+   below).  The last deflate block may go quite a bit past that, but
+   is discarded.  The second pass decompresses and recompresses just
+   the compressed data that fit in the requested plus excess sized
+   buffer.  The deflate process is terminated after that amount of
+   input, which is less than the amount consumed on the first pass.
+   The last deflate block of the result will be of a comparable size
+   to the final product, so that the header for that deflate block and
+   the compression ratio for that block will be about the same as in
+   the final product.  The third compression pass decompresses the
+   result of the second step, but only the compressed data up to the
+   requested size minus an amount to allow the compressed stream to
+   complete (see the MARGIN define below).  That will result in a
+   final compressed stream whose length is less than or equal to the
+   requested size.  Assuming sufficient input and a requested size
+   greater than a few hundred bytes, the shortfall will typically be
+   less than ten bytes.
+
+   If the input is short enough that the first compression completes
+   before filling the requested output size, then that compressed
+   stream is return with no recompression.
+
+   EXCESS is chosen to be just greater than the shortfall seen in a
+   two pass approach similar to the above.  That shortfall is due to
+   the last deflate block compressing more efficiently with a smaller
+   header on the second pass.  EXCESS is set to be large enough so
+   that there is enough uncompressed data for the second pass to fill
+   out the requested size, and small enough so that the final deflate
+   block of the second pass will be close in size to the final deflate
+   block of the third and final pass.  MARGIN is chosen to be just
+   large enough to assure that the final compression has enough room
+   to complete in all cases.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include "zlib.h"
+
+#define local static
+
+/* print nastygram and leave */
+local void quit(char *why)
+{
+    fprintf(stderr, "fitblk abort: %s\n", why);
+    exit(1);
+}
+
+#define RAWLEN 4096    /* intermediate uncompressed buffer size */
+
+/* compress from file to def until provided buffer is full or end of
+   input reached; return last deflate() return value, or Z_ERRNO if
+   there was read error on the file */
+local int partcompress(FILE *in, z_streamp def)
+{
+    int ret, flush;
+    unsigned char raw[RAWLEN];
+
+    flush = Z_NO_FLUSH;
+    do {
+        def->avail_in = fread(raw, 1, RAWLEN, in);
+        if (ferror(in))
+            return Z_ERRNO;
+        def->next_in = raw;
+        if (feof(in))
+            flush = Z_FINISH;
+        ret = deflate(def, flush);
+        assert(ret != Z_STREAM_ERROR);
+    } while (def->avail_out != 0 && flush == Z_NO_FLUSH);
+    return ret;
+}
+
+/* recompress from inf's input to def's output; the input for inf and
+   the output for def are set in those structures before calling;
+   return last deflate() return value, or Z_MEM_ERROR if inflate()
+   was not able to allocate enough memory when it needed to */
+local int recompress(z_streamp inf, z_streamp def)
+{
+    int ret, flush;
+    unsigned char raw[RAWLEN];
+
+    flush = Z_NO_FLUSH;
+    do {
+        /* decompress */
+        inf->avail_out = RAWLEN;
+        inf->next_out = raw;
+        ret = inflate(inf, Z_NO_FLUSH);
+        assert(ret != Z_STREAM_ERROR && ret != Z_DATA_ERROR &&
+               ret != Z_NEED_DICT);
+        if (ret == Z_MEM_ERROR)
+            return ret;
+
+        /* compress what was decompresed until done or no room */
+        def->avail_in = RAWLEN - inf->avail_out;
+        def->next_in = raw;
+        if (inf->avail_out != 0)
+            flush = Z_FINISH;
+        ret = deflate(def, flush);
+        assert(ret != Z_STREAM_ERROR);
+    } while (ret != Z_STREAM_END && def->avail_out != 0);
+    return ret;
+}
+
+#define EXCESS 256      /* empirically determined stream overage */
+#define MARGIN 8        /* amount to back off for completion */
+
+/* compress from stdin to fixed-size block on stdout */
+int main(int argc, char **argv)
+{
+    int ret;                /* return code */
+    unsigned size;          /* requested fixed output block size */
+    unsigned have;          /* bytes written by deflate() call */
+    unsigned char *blk;     /* intermediate and final stream */
+    unsigned char *tmp;     /* close to desired size stream */
+    z_stream def, inf;      /* zlib deflate and inflate states */
+
+    /* get requested output size */
+    if (argc != 2)
+        quit("need one argument: size of output block");
+    ret = strtol(argv[1], argv + 1, 10);
+    if (argv[1][0] != 0)
+        quit("argument must be a number");
+    if (ret < 8)            /* 8 is minimum zlib stream size */
+        quit("need positive size of 8 or greater");
+    size = (unsigned)ret;
+
+    /* allocate memory for buffers and compression engine */
+    blk = malloc(size + EXCESS);
+    def.zalloc = Z_NULL;
+    def.zfree = Z_NULL;
+    def.opaque = Z_NULL;
+    ret = deflateInit(&def, Z_DEFAULT_COMPRESSION);
+    if (ret != Z_OK || blk == NULL)
+        quit("out of memory");
+
+    /* compress from stdin until output full, or no more input */
+    def.avail_out = size + EXCESS;
+    def.next_out = blk;
+    ret = partcompress(stdin, &def);
+    if (ret == Z_ERRNO)
+        quit("error reading input");
+
+    /* if it all fit, then size was undersubscribed -- done! */
+    if (ret == Z_STREAM_END && def.avail_out >= EXCESS) {
+        /* write block to stdout */
+        have = size + EXCESS - def.avail_out;
+        if (fwrite(blk, 1, have, stdout) != have || ferror(stdout))
+            quit("error writing output");
+
+        /* clean up and print results to stderr */
+        ret = deflateEnd(&def);
+        assert(ret != Z_STREAM_ERROR);
+        free(blk);
+        fprintf(stderr,
+                "%u bytes unused out of %u requested (all input)\n",
+                size - have, size);
+        return 0;
+    }
+
+    /* it didn't all fit -- set up for recompression */
+    inf.zalloc = Z_NULL;
+    inf.zfree = Z_NULL;
+    inf.opaque = Z_NULL;
+    inf.avail_in = 0;
+    inf.next_in = Z_NULL;
+    ret = inflateInit(&inf);
+    tmp = malloc(size + EXCESS);
+    if (ret != Z_OK || tmp == NULL)
+        quit("out of memory");
+    ret = deflateReset(&def);
+    assert(ret != Z_STREAM_ERROR);
+
+    /* do first recompression close to the right amount */
+    inf.avail_in = size + EXCESS;
+    inf.next_in = blk;
+    def.avail_out = size + EXCESS;
+    def.next_out = tmp;
+    ret = recompress(&inf, &def);
+    if (ret == Z_MEM_ERROR)
+        quit("out of memory");
+
+    /* set up for next reocmpression */
+    ret = inflateReset(&inf);
+    assert(ret != Z_STREAM_ERROR);
+    ret = deflateReset(&def);
+    assert(ret != Z_STREAM_ERROR);
+
+    /* do second and final recompression (third compression) */
+    inf.avail_in = size - MARGIN;   /* assure stream will complete */
+    inf.next_in = tmp;
+    def.avail_out = size;
+    def.next_out = blk;
+    ret = recompress(&inf, &def);
+    if (ret == Z_MEM_ERROR)
+        quit("out of memory");
+    assert(ret == Z_STREAM_END);    /* otherwise MARGIN too small */
+
+    /* done -- write block to stdout */
+    have = size - def.avail_out;
+    if (fwrite(blk, 1, have, stdout) != have || ferror(stdout))
+        quit("error writing output");
+
+    /* clean up and print results to stderr */
+    free(tmp);
+    ret = inflateEnd(&inf);
+    assert(ret != Z_STREAM_ERROR);
+    ret = deflateEnd(&def);
+    assert(ret != Z_STREAM_ERROR);
+    free(blk);
+    fprintf(stderr,
+            "%u bytes unused out of %u requested (%lu input)\n",
+            size - have, size, def.total_in);
+    return 0;
+}
diff --git a/compat/zlib/examples/gun.c b/compat/zlib/examples/gun.c
new file mode 100644
index 0000000..89e484f
--- /dev/null
+++ b/compat/zlib/examples/gun.c
@@ -0,0 +1,702 @@
+/* gun.c -- simple gunzip to give an example of the use of inflateBack()
+ * Copyright (C) 2003, 2005, 2008, 2010, 2012 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+   Version 1.7  12 August 2012  Mark Adler */
+
+/* Version history:
+   1.0  16 Feb 2003  First version for testing of inflateBack()
+   1.1  21 Feb 2005  Decompress concatenated gzip streams
+                     Remove use of "this" variable (C++ keyword)
+                     Fix return value for in()
+                     Improve allocation failure checking
+                     Add typecasting for void * structures
+                     Add -h option for command version and usage
+                     Add a bunch of comments
+   1.2  20 Mar 2005  Add Unix compress (LZW) decompression
+                     Copy file attributes from input file to output file
+   1.3  12 Jun 2005  Add casts for error messages [Oberhumer]
+   1.4   8 Dec 2006  LZW decompression speed improvements
+   1.5   9 Feb 2008  Avoid warning in latest version of gcc
+   1.6  17 Jan 2010  Avoid signed/unsigned comparison warnings
+   1.7  12 Aug 2012  Update for z_const usage in zlib 1.2.8
+ */
+
+/*
+   gun [ -t ] [ name ... ]
+
+   decompresses the data in the named gzip files.  If no arguments are given,
+   gun will decompress from stdin to stdout.  The names must end in .gz, -gz,
+   .z, -z, _z, or .Z.  The uncompressed data will be written to a file name
+   with the suffix stripped.  On success, the original file is deleted.  On
+   failure, the output file is deleted.  For most failures, the command will
+   continue to process the remaining names on the command line.  A memory
+   allocation failure will abort the command.  If -t is specified, then the
+   listed files or stdin will be tested as gzip files for integrity (without
+   checking for a proper suffix), no output will be written, and no files
+   will be deleted.
+
+   Like gzip, gun allows concatenated gzip streams and will decompress them,
+   writing all of the uncompressed data to the output.  Unlike gzip, gun allows
+   an empty file on input, and will produce no error writing an empty output
+   file.
+
+   gun will also decompress files made by Unix compress, which uses LZW
+   compression.  These files are automatically detected by virtue of their
+   magic header bytes.  Since the end of Unix compress stream is marked by the
+   end-of-file, they cannot be concantenated.  If a Unix compress stream is
+   encountered in an input file, it is the last stream in that file.
+
+   Like gunzip and uncompress, the file attributes of the orignal compressed
+   file are maintained in the final uncompressed file, to the extent that the
+   user permissions allow it.
+
+   On my Mac OS X PowerPC G4, gun is almost twice as fast as gunzip (version
+   1.2.4) is on the same file, when gun is linked with zlib 1.2.2.  Also the
+   LZW decompression provided by gun is about twice as fast as the standard
+   Unix uncompress command.
+ */
+
+/* external functions and related types and constants */
+#include <stdio.h>          /* fprintf() */
+#include <stdlib.h>         /* malloc(), free() */
+#include <string.h>         /* strerror(), strcmp(), strlen(), memcpy() */
+#include <errno.h>          /* errno */
+#include <fcntl.h>          /* open() */
+#include <unistd.h>         /* read(), write(), close(), chown(), unlink() */
+#include <sys/types.h>
+#include <sys/stat.h>       /* stat(), chmod() */
+#include <utime.h>          /* utime() */
+#include "zlib.h"           /* inflateBackInit(), inflateBack(), */
+                            /* inflateBackEnd(), crc32() */
+
+/* function declaration */
+#define local static
+
+/* buffer constants */
+#define SIZE 32768U         /* input and output buffer sizes */
+#define PIECE 16384         /* limits i/o chunks for 16-bit int case */
+
+/* structure for infback() to pass to input function in() -- it maintains the
+   input file and a buffer of size SIZE */
+struct ind {
+    int infile;
+    unsigned char *inbuf;
+};
+
+/* Load input buffer, assumed to be empty, and return bytes loaded and a
+   pointer to them.  read() is called until the buffer is full, or until it
+   returns end-of-file or error.  Return 0 on error. */
+local unsigned in(void *in_desc, z_const unsigned char **buf)
+{
+    int ret;
+    unsigned len;
+    unsigned char *next;
+    struct ind *me = (struct ind *)in_desc;
+
+    next = me->inbuf;
+    *buf = next;
+    len = 0;
+    do {
+        ret = PIECE;
+        if ((unsigned)ret > SIZE - len)
+            ret = (int)(SIZE - len);
+        ret = (int)read(me->infile, next, ret);
+        if (ret == -1) {
+            len = 0;
+            break;
+        }
+        next += ret;
+        len += ret;
+    } while (ret != 0 && len < SIZE);
+    return len;
+}
+
+/* structure for infback() to pass to output function out() -- it maintains the
+   output file, a running CRC-32 check on the output and the total number of
+   bytes output, both for checking against the gzip trailer.  (The length in
+   the gzip trailer is stored modulo 2^32, so it's ok if a long is 32 bits and
+   the output is greater than 4 GB.) */
+struct outd {
+    int outfile;
+    int check;                  /* true if checking crc and total */
+    unsigned long crc;
+    unsigned long total;
+};
+
+/* Write output buffer and update the CRC-32 and total bytes written.  write()
+   is called until all of the output is written or an error is encountered.
+   On success out() returns 0.  For a write failure, out() returns 1.  If the
+   output file descriptor is -1, then nothing is written.
+ */
+local int out(void *out_desc, unsigned char *buf, unsigned len)
+{
+    int ret;
+    struct outd *me = (struct outd *)out_desc;
+
+    if (me->check) {
+        me->crc = crc32(me->crc, buf, len);
+        me->total += len;
+    }
+    if (me->outfile != -1)
+        do {
+            ret = PIECE;
+            if ((unsigned)ret > len)
+                ret = (int)len;
+            ret = (int)write(me->outfile, buf, ret);
+            if (ret == -1)
+                return 1;
+            buf += ret;
+            len -= ret;
+        } while (len != 0);
+    return 0;
+}
+
+/* next input byte macro for use inside lunpipe() and gunpipe() */
+#define NEXT() (have ? 0 : (have = in(indp, &next)), \
+                last = have ? (have--, (int)(*next++)) : -1)
+
+/* memory for gunpipe() and lunpipe() --
+   the first 256 entries of prefix[] and suffix[] are never used, could
+   have offset the index, but it's faster to waste the memory */
+unsigned char inbuf[SIZE];              /* input buffer */
+unsigned char outbuf[SIZE];             /* output buffer */
+unsigned short prefix[65536];           /* index to LZW prefix string */
+unsigned char suffix[65536];            /* one-character LZW suffix */
+unsigned char match[65280 + 2];         /* buffer for reversed match or gzip
+                                           32K sliding window */
+
+/* throw out what's left in the current bits byte buffer (this is a vestigial
+   aspect of the compressed data format derived from an implementation that
+   made use of a special VAX machine instruction!) */
+#define FLUSHCODE() \
+    do { \
+        left = 0; \
+        rem = 0; \
+        if (chunk > have) { \
+            chunk -= have; \
+            have = 0; \
+            if (NEXT() == -1) \
+                break; \
+            chunk--; \
+            if (chunk > have) { \
+                chunk = have = 0; \
+                break; \
+            } \
+        } \
+        have -= chunk; \
+        next += chunk; \
+        chunk = 0; \
+    } while (0)
+
+/* Decompress a compress (LZW) file from indp to outfile.  The compress magic
+   header (two bytes) has already been read and verified.  There are have bytes
+   of buffered input at next.  strm is used for passing error information back
+   to gunpipe().
+
+   lunpipe() will return Z_OK on success, Z_BUF_ERROR for an unexpected end of
+   file, read error, or write error (a write error indicated by strm->next_in
+   not equal to Z_NULL), or Z_DATA_ERROR for invalid input.
+ */
+local int lunpipe(unsigned have, z_const unsigned char *next, struct ind *indp,
+                  int outfile, z_stream *strm)
+{
+    int last;                   /* last byte read by NEXT(), or -1 if EOF */
+    unsigned chunk;             /* bytes left in current chunk */
+    int left;                   /* bits left in rem */
+    unsigned rem;               /* unused bits from input */
+    int bits;                   /* current bits per code */
+    unsigned code;              /* code, table traversal index */
+    unsigned mask;              /* mask for current bits codes */
+    int max;                    /* maximum bits per code for this stream */
+    unsigned flags;             /* compress flags, then block compress flag */
+    unsigned end;               /* last valid entry in prefix/suffix tables */
+    unsigned temp;              /* current code */
+    unsigned prev;              /* previous code */
+    unsigned final;             /* last character written for previous code */
+    unsigned stack;             /* next position for reversed string */
+    unsigned outcnt;            /* bytes in output buffer */
+    struct outd outd;           /* output structure */
+    unsigned char *p;
+
+    /* set up output */
+    outd.outfile = outfile;
+    outd.check = 0;
+
+    /* process remainder of compress header -- a flags byte */
+    flags = NEXT();
+    if (last == -1)
+        return Z_BUF_ERROR;
+    if (flags & 0x60) {
+        strm->msg = (char *)"unknown lzw flags set";
+        return Z_DATA_ERROR;
+    }
+    max = flags & 0x1f;
+    if (max < 9 || max > 16) {
+        strm->msg = (char *)"lzw bits out of range";
+        return Z_DATA_ERROR;
+    }
+    if (max == 9)                           /* 9 doesn't really mean 9 */
+        max = 10;
+    flags &= 0x80;                          /* true if block compress */
+
+    /* clear table */
+    bits = 9;
+    mask = 0x1ff;
+    end = flags ? 256 : 255;
+
+    /* set up: get first 9-bit code, which is the first decompressed byte, but
+       don't create a table entry until the next code */
+    if (NEXT() == -1)                       /* no compressed data is ok */
+        return Z_OK;
+    final = prev = (unsigned)last;          /* low 8 bits of code */
+    if (NEXT() == -1)                       /* missing a bit */
+        return Z_BUF_ERROR;
+    if (last & 1) {                         /* code must be < 256 */
+        strm->msg = (char *)"invalid lzw code";
+        return Z_DATA_ERROR;
+    }
+    rem = (unsigned)last >> 1;              /* remaining 7 bits */
+    left = 7;
+    chunk = bits - 2;                       /* 7 bytes left in this chunk */
+    outbuf[0] = (unsigned char)final;       /* write first decompressed byte */
+    outcnt = 1;
+
+    /* decode codes */
+    stack = 0;
+    for (;;) {
+        /* if the table will be full after this, increment the code size */
+        if (end >= mask && bits < max) {
+            FLUSHCODE();
+            bits++;
+            mask <<= 1;
+            mask++;
+        }
+
+        /* get a code of length bits */
+        if (chunk == 0)                     /* decrement chunk modulo bits */
+            chunk = bits;
+        code = rem;                         /* low bits of code */
+        if (NEXT() == -1) {                 /* EOF is end of compressed data */
+            /* write remaining buffered output */
+            if (outcnt && out(&outd, outbuf, outcnt)) {
+                strm->next_in = outbuf;     /* signal write error */
+                return Z_BUF_ERROR;
+            }
+            return Z_OK;
+        }
+        code += (unsigned)last << left;     /* middle (or high) bits of code */
+        left += 8;
+        chunk--;
+        if (bits > left) {                  /* need more bits */
+            if (NEXT() == -1)               /* can't end in middle of code */
+                return Z_BUF_ERROR;
+            code += (unsigned)last << left; /* high bits of code */
+            left += 8;
+            chunk--;
+        }
+        code &= mask;                       /* mask to current code length */
+        left -= bits;                       /* number of unused bits */
+        rem = (unsigned)last >> (8 - left); /* unused bits from last byte */
+
+        /* process clear code (256) */
+        if (code == 256 && flags) {
+            FLUSHCODE();
+            bits = 9;                       /* initialize bits and mask */
+            mask = 0x1ff;
+            end = 255;                      /* empty table */
+            continue;                       /* get next code */
+        }
+
+        /* special code to reuse last match */
+        temp = code;                        /* save the current code */
+        if (code > end) {
+            /* Be picky on the allowed code here, and make sure that the code
+               we drop through (prev) will be a valid index so that random
+               input does not cause an exception.  The code != end + 1 check is
+               empirically derived, and not checked in the original uncompress
+               code.  If this ever causes a problem, that check could be safely
+               removed.  Leaving this check in greatly improves gun's ability
+               to detect random or corrupted input after a compress header.
+               In any case, the prev > end check must be retained. */
+            if (code != end + 1 || prev > end) {
+                strm->msg = (char *)"invalid lzw code";
+                return Z_DATA_ERROR;
+            }
+            match[stack++] = (unsigned char)final;
+            code = prev;
+        }
+
+        /* walk through linked list to generate output in reverse order */
+        p = match + stack;
+        while (code >= 256) {
+            *p++ = suffix[code];
+            code = prefix[code];
+        }
+        stack = p - match;
+        match[stack++] = (unsigned char)code;
+        final = code;
+
+        /* link new table entry */
+        if (end < mask) {
+            end++;
+            prefix[end] = (unsigned short)prev;
+            suffix[end] = (unsigned char)final;
+        }
+
+        /* set previous code for next iteration */
+        prev = temp;
+
+        /* write output in forward order */
+        while (stack > SIZE - outcnt) {
+            while (outcnt < SIZE)
+                outbuf[outcnt++] = match[--stack];
+            if (out(&outd, outbuf, outcnt)) {
+                strm->next_in = outbuf; /* signal write error */
+                return Z_BUF_ERROR;
+            }
+            outcnt = 0;
+        }
+        p = match + stack;
+        do {
+            outbuf[outcnt++] = *--p;
+        } while (p > match);
+        stack = 0;
+
+        /* loop for next code with final and prev as the last match, rem and
+           left provide the first 0..7 bits of the next code, end is the last
+           valid table entry */
+    }
+}
+
+/* Decompress a gzip file from infile to outfile.  strm is assumed to have been
+   successfully initialized with inflateBackInit().  The input file may consist
+   of a series of gzip streams, in which case all of them will be decompressed
+   to the output file.  If outfile is -1, then the gzip stream(s) integrity is
+   checked and nothing is written.
+
+   The return value is a zlib error code: Z_MEM_ERROR if out of memory,
+   Z_DATA_ERROR if the header or the compressed data is invalid, or if the
+   trailer CRC-32 check or length doesn't match, Z_BUF_ERROR if the input ends
+   prematurely or a write error occurs, or Z_ERRNO if junk (not a another gzip
+   stream) follows a valid gzip stream.
+ */
+local int gunpipe(z_stream *strm, int infile, int outfile)
+{
+    int ret, first, last;
+    unsigned have, flags, len;
+    z_const unsigned char *next = NULL;
+    struct ind ind, *indp;
+    struct outd outd;
+
+    /* setup input buffer */
+    ind.infile = infile;
+    ind.inbuf = inbuf;
+    indp = &ind;
+
+    /* decompress concatenated gzip streams */
+    have = 0;                               /* no input data read in yet */
+    first = 1;                              /* looking for first gzip header */
+    strm->next_in = Z_NULL;                 /* so Z_BUF_ERROR means EOF */
+    for (;;) {
+        /* look for the two magic header bytes for a gzip stream */
+        if (NEXT() == -1) {
+            ret = Z_OK;
+            break;                          /* empty gzip stream is ok */
+        }
+        if (last != 31 || (NEXT() != 139 && last != 157)) {
+            strm->msg = (char *)"incorrect header check";
+            ret = first ? Z_DATA_ERROR : Z_ERRNO;
+            break;                          /* not a gzip or compress header */
+        }
+        first = 0;                          /* next non-header is junk */
+
+        /* process a compress (LZW) file -- can't be concatenated after this */
+        if (last == 157) {
+            ret = lunpipe(have, next, indp, outfile, strm);
+            break;
+        }
+
+        /* process remainder of gzip header */
+        ret = Z_BUF_ERROR;
+        if (NEXT() != 8) {                  /* only deflate method allowed */
+            if (last == -1) break;
+            strm->msg = (char *)"unknown compression method";
+            ret = Z_DATA_ERROR;
+            break;
+        }
+        flags = NEXT();                     /* header flags */
+        NEXT();                             /* discard mod time, xflgs, os */
+        NEXT();
+        NEXT();
+        NEXT();
+        NEXT();
+        NEXT();
+        if (last == -1) break;
+        if (flags & 0xe0) {
+            strm->msg = (char *)"unknown header flags set";
+            ret = Z_DATA_ERROR;
+            break;
+        }
+        if (flags & 4) {                    /* extra field */
+            len = NEXT();
+            len += (unsigned)(NEXT()) << 8;
+            if (last == -1) break;
+            while (len > have) {
+                len -= have;
+                have = 0;
+                if (NEXT() == -1) break;
+                len--;
+            }
+            if (last == -1) break;
+            have -= len;
+            next += len;
+        }
+        if (flags & 8)                      /* file name */
+            while (NEXT() != 0 && last != -1)
+                ;
+        if (flags & 16)                     /* comment */
+            while (NEXT() != 0 && last != -1)
+                ;
+        if (flags & 2) {                    /* header crc */
+            NEXT();
+            NEXT();
+        }
+        if (last == -1) break;
+
+        /* set up output */
+        outd.outfile = outfile;
+        outd.check = 1;
+        outd.crc = crc32(0L, Z_NULL, 0);
+        outd.total = 0;
+
+        /* decompress data to output */
+        strm->next_in = next;
+        strm->avail_in = have;
+        ret = inflateBack(strm, in, indp, out, &outd);
+        if (ret != Z_STREAM_END) break;
+        next = strm->next_in;
+        have = strm->avail_in;
+        strm->next_in = Z_NULL;             /* so Z_BUF_ERROR means EOF */
+
+        /* check trailer */
+        ret = Z_BUF_ERROR;
+        if (NEXT() != (int)(outd.crc & 0xff) ||
+            NEXT() != (int)((outd.crc >> 8) & 0xff) ||
+            NEXT() != (int)((outd.crc >> 16) & 0xff) ||
+            NEXT() != (int)((outd.crc >> 24) & 0xff)) {
+            /* crc error */
+            if (last != -1) {
+                strm->msg = (char *)"incorrect data check";
+                ret = Z_DATA_ERROR;
+            }
+            break;
+        }
+        if (NEXT() != (int)(outd.total & 0xff) ||
+            NEXT() != (int)((outd.total >> 8) & 0xff) ||
+            NEXT() != (int)((outd.total >> 16) & 0xff) ||
+            NEXT() != (int)((outd.total >> 24) & 0xff)) {
+            /* length error */
+            if (last != -1) {
+                strm->msg = (char *)"incorrect length check";
+                ret = Z_DATA_ERROR;
+            }
+            break;
+        }
+
+        /* go back and look for another gzip stream */
+    }
+
+    /* clean up and return */
+    return ret;
+}
+
+/* Copy file attributes, from -> to, as best we can.  This is best effort, so
+   no errors are reported.  The mode bits, including suid, sgid, and the sticky
+   bit are copied (if allowed), the owner's user id and group id are copied
+   (again if allowed), and the access and modify times are copied. */
+local void copymeta(char *from, char *to)
+{
+    struct stat was;
+    struct utimbuf when;
+
+    /* get all of from's Unix meta data, return if not a regular file */
+    if (stat(from, &was) != 0 || (was.st_mode & S_IFMT) != S_IFREG)
+        return;
+
+    /* set to's mode bits, ignore errors */
+    (void)chmod(to, was.st_mode & 07777);
+
+    /* copy owner's user and group, ignore errors */
+    (void)chown(to, was.st_uid, was.st_gid);
+
+    /* copy access and modify times, ignore errors */
+    when.actime = was.st_atime;
+    when.modtime = was.st_mtime;
+    (void)utime(to, &when);
+}
+
+/* Decompress the file inname to the file outnname, of if test is true, just
+   decompress without writing and check the gzip trailer for integrity.  If
+   inname is NULL or an empty string, read from stdin.  If outname is NULL or
+   an empty string, write to stdout.  strm is a pre-initialized inflateBack
+   structure.  When appropriate, copy the file attributes from inname to
+   outname.
+
+   gunzip() returns 1 if there is an out-of-memory error or an unexpected
+   return code from gunpipe().  Otherwise it returns 0.
+ */
+local int gunzip(z_stream *strm, char *inname, char *outname, int test)
+{
+    int ret;
+    int infile, outfile;
+
+    /* open files */
+    if (inname == NULL || *inname == 0) {
+        inname = "-";
+        infile = 0;     /* stdin */
+    }
+    else {
+        infile = open(inname, O_RDONLY, 0);
+        if (infile == -1) {
+            fprintf(stderr, "gun cannot open %s\n", inname);
+            return 0;
+        }
+    }
+    if (test)
+        outfile = -1;
+    else if (outname == NULL || *outname == 0) {
+        outname = "-";
+        outfile = 1;    /* stdout */
+    }
+    else {
+        outfile = open(outname, O_CREAT | O_TRUNC | O_WRONLY, 0666);
+        if (outfile == -1) {
+            close(infile);
+            fprintf(stderr, "gun cannot create %s\n", outname);
+            return 0;
+        }
+    }
+    errno = 0;
+
+    /* decompress */
+    ret = gunpipe(strm, infile, outfile);
+    if (outfile > 2) close(outfile);
+    if (infile > 2) close(infile);
+
+    /* interpret result */
+    switch (ret) {
+    case Z_OK:
+    case Z_ERRNO:
+        if (infile > 2 && outfile > 2) {
+            copymeta(inname, outname);          /* copy attributes */
+            unlink(inname);
+        }
+        if (ret == Z_ERRNO)
+            fprintf(stderr, "gun warning: trailing garbage ignored in %s\n",
+                    inname);
+        break;
+    case Z_DATA_ERROR:
+        if (outfile > 2) unlink(outname);
+        fprintf(stderr, "gun data error on %s: %s\n", inname, strm->msg);
+        break;
+    case Z_MEM_ERROR:
+        if (outfile > 2) unlink(outname);
+        fprintf(stderr, "gun out of memory error--aborting\n");
+        return 1;
+    case Z_BUF_ERROR:
+        if (outfile > 2) unlink(outname);
+        if (strm->next_in != Z_NULL) {
+            fprintf(stderr, "gun write error on %s: %s\n",
+                    outname, strerror(errno));
+        }
+        else if (errno) {
+            fprintf(stderr, "gun read error on %s: %s\n",
+                    inname, strerror(errno));
+        }
+        else {
+            fprintf(stderr, "gun unexpected end of file on %s\n",
+                    inname);
+        }
+        break;
+    default:
+        if (outfile > 2) unlink(outname);
+        fprintf(stderr, "gun internal error--aborting\n");
+        return 1;
+    }
+    return 0;
+}
+
+/* Process the gun command line arguments.  See the command syntax near the
+   beginning of this source file. */
+int main(int argc, char **argv)
+{
+    int ret, len, test;
+    char *outname;
+    unsigned char *window;
+    z_stream strm;
+
+    /* initialize inflateBack state for repeated use */
+    window = match;                         /* reuse LZW match buffer */
+    strm.zalloc = Z_NULL;
+    strm.zfree = Z_NULL;
+    strm.opaque = Z_NULL;
+    ret = inflateBackInit(&strm, 15, window);
+    if (ret != Z_OK) {
+        fprintf(stderr, "gun out of memory error--aborting\n");
+        return 1;
+    }
+
+    /* decompress each file to the same name with the suffix removed */
+    argc--;
+    argv++;
+    test = 0;
+    if (argc && strcmp(*argv, "-h") == 0) {
+        fprintf(stderr, "gun 1.6 (17 Jan 2010)\n");
+        fprintf(stderr, "Copyright (C) 2003-2010 Mark Adler\n");
+        fprintf(stderr, "usage: gun [-t] [file1.gz [file2.Z ...]]\n");
+        return 0;
+    }
+    if (argc && strcmp(*argv, "-t") == 0) {
+        test = 1;
+        argc--;
+        argv++;
+    }
+    if (argc)
+        do {
+            if (test)
+                outname = NULL;
+            else {
+                len = (int)strlen(*argv);
+                if (strcmp(*argv + len - 3, ".gz") == 0 ||
+                    strcmp(*argv + len - 3, "-gz") == 0)
+                    len -= 3;
+                else if (strcmp(*argv + len - 2, ".z") == 0 ||
+                    strcmp(*argv + len - 2, "-z") == 0 ||
+                    strcmp(*argv + len - 2, "_z") == 0 ||
+                    strcmp(*argv + len - 2, ".Z") == 0)
+                    len -= 2;
+                else {
+                    fprintf(stderr, "gun error: no gz type on %s--skipping\n",
+                            *argv);
+                    continue;
+                }
+                outname = malloc(len + 1);
+                if (outname == NULL) {
+                    fprintf(stderr, "gun out of memory error--aborting\n");
+                    ret = 1;
+                    break;
+                }
+                memcpy(outname, *argv, len);
+                outname[len] = 0;
+            }
+            ret = gunzip(&strm, *argv, outname, test);
+            if (outname != NULL) free(outname);
+            if (ret) break;
+        } while (argv++, --argc);
+    else
+        ret = gunzip(&strm, NULL, NULL, test);
+
+    /* clean up */
+    inflateBackEnd(&strm);
+    return ret;
+}
diff --git a/compat/zlib/examples/gzappend.c b/compat/zlib/examples/gzappend.c
new file mode 100644
index 0000000..662dec3
--- /dev/null
+++ b/compat/zlib/examples/gzappend.c
@@ -0,0 +1,504 @@
+/* gzappend -- command to append to a gzip file
+
+  Copyright (C) 2003, 2012 Mark Adler, all rights reserved
+  version 1.2, 11 Oct 2012
+
+  This software is provided 'as-is', without any express or implied
+  warranty.  In no event will the author be held liable for any damages
+  arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any purpose,
+  including commercial applications, and to alter it and redistribute it
+  freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+
+  Mark Adler    madler@alumni.caltech.edu
+ */
+
+/*
+ * Change history:
+ *
+ * 1.0  19 Oct 2003     - First version
+ * 1.1   4 Nov 2003     - Expand and clarify some comments and notes
+ *                      - Add version and copyright to help
+ *                      - Send help to stdout instead of stderr
+ *                      - Add some preemptive typecasts
+ *                      - Add L to constants in lseek() calls
+ *                      - Remove some debugging information in error messages
+ *                      - Use new data_type definition for zlib 1.2.1
+ *                      - Simplfy and unify file operations
+ *                      - Finish off gzip file in gztack()
+ *                      - Use deflatePrime() instead of adding empty blocks
+ *                      - Keep gzip file clean on appended file read errors
+ *                      - Use in-place rotate instead of auxiliary buffer
+ *                        (Why you ask?  Because it was fun to write!)
+ * 1.2  11 Oct 2012     - Fix for proper z_const usage
+ *                      - Check for input buffer malloc failure
+ */
+
+/*
+   gzappend takes a gzip file and appends to it, compressing files from the
+   command line or data from stdin.  The gzip file is written to directly, to
+   avoid copying that file, in case it's large.  Note that this results in the
+   unfriendly behavior that if gzappend fails, the gzip file is corrupted.
+
+   This program was written to illustrate the use of the new Z_BLOCK option of
+   zlib 1.2.x's inflate() function.  This option returns from inflate() at each
+   block boundary to facilitate locating and modifying the last block bit at
+   the start of the final deflate block.  Also whether using Z_BLOCK or not,
+   another required feature of zlib 1.2.x is that inflate() now provides the
+   number of unusued bits in the last input byte used.  gzappend will not work
+   with versions of zlib earlier than 1.2.1.
+
+   gzappend first decompresses the gzip file internally, discarding all but
+   the last 32K of uncompressed data, and noting the location of the last block
+   bit and the number of unused bits in the last byte of the compressed data.
+   The gzip trailer containing the CRC-32 and length of the uncompressed data
+   is verified.  This trailer will be later overwritten.
+
+   Then the last block bit is cleared by seeking back in the file and rewriting
+   the byte that contains it.  Seeking forward, the last byte of the compressed
+   data is saved along with the number of unused bits to initialize deflate.
+
+   A deflate process is initialized, using the last 32K of the uncompressed
+   data from the gzip file to initialize the dictionary.  If the total
+   uncompressed data was less than 32K, then all of it is used to initialize
+   the dictionary.  The deflate output bit buffer is also initialized with the
+   last bits from the original deflate stream.  From here on, the data to
+   append is simply compressed using deflate, and written to the gzip file.
+   When that is complete, the new CRC-32 and uncompressed length are written
+   as the trailer of the gzip file.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include "zlib.h"
+
+#define local static
+#define LGCHUNK 14
+#define CHUNK (1U << LGCHUNK)
+#define DSIZE 32768U
+
+/* print an error message and terminate with extreme prejudice */
+local void bye(char *msg1, char *msg2)
+{
+    fprintf(stderr, "gzappend error: %s%s\n", msg1, msg2);
+    exit(1);
+}
+
+/* return the greatest common divisor of a and b using Euclid's algorithm,
+   modified to be fast when one argument much greater than the other, and
+   coded to avoid unnecessary swapping */
+local unsigned gcd(unsigned a, unsigned b)
+{
+    unsigned c;
+
+    while (a && b)
+        if (a > b) {
+            c = b;
+            while (a - c >= c)
+                c <<= 1;
+            a -= c;
+        }
+        else {
+            c = a;
+            while (b - c >= c)
+                c <<= 1;
+            b -= c;
+        }
+    return a + b;
+}
+
+/* rotate list[0..len-1] left by rot positions, in place */
+local void rotate(unsigned char *list, unsigned len, unsigned rot)
+{
+    unsigned char tmp;
+    unsigned cycles;
+    unsigned char *start, *last, *to, *from;
+
+    /* normalize rot and handle degenerate cases */
+    if (len < 2) return;
+    if (rot >= len) rot %= len;
+    if (rot == 0) return;
+
+    /* pointer to last entry in list */
+    last = list + (len - 1);
+
+    /* do simple left shift by one */
+    if (rot == 1) {
+        tmp = *list;
+        memcpy(list, list + 1, len - 1);
+        *last = tmp;
+        return;
+    }
+
+    /* do simple right shift by one */
+    if (rot == len - 1) {
+        tmp = *last;
+        memmove(list + 1, list, len - 1);
+        *list = tmp;
+        return;
+    }
+
+    /* otherwise do rotate as a set of cycles in place */
+    cycles = gcd(len, rot);             /* number of cycles */
+    do {
+        start = from = list + cycles;   /* start index is arbitrary */
+        tmp = *from;                    /* save entry to be overwritten */
+        for (;;) {
+            to = from;                  /* next step in cycle */
+            from += rot;                /* go right rot positions */
+            if (from > last) from -= len;   /* (pointer better not wrap) */
+            if (from == start) break;   /* all but one shifted */
+            *to = *from;                /* shift left */
+        }
+        *to = tmp;                      /* complete the circle */
+    } while (--cycles);
+}
+
+/* structure for gzip file read operations */
+typedef struct {
+    int fd;                     /* file descriptor */
+    int size;                   /* 1 << size is bytes in buf */
+    unsigned left;              /* bytes available at next */
+    unsigned char *buf;         /* buffer */
+    z_const unsigned char *next;    /* next byte in buffer */
+    char *name;                 /* file name for error messages */
+} file;
+
+/* reload buffer */
+local int readin(file *in)
+{
+    int len;
+
+    len = read(in->fd, in->buf, 1 << in->size);
+    if (len == -1) bye("error reading ", in->name);
+    in->left = (unsigned)len;
+    in->next = in->buf;
+    return len;
+}
+
+/* read from file in, exit if end-of-file */
+local int readmore(file *in)
+{
+    if (readin(in) == 0) bye("unexpected end of ", in->name);
+    return 0;
+}
+
+#define read1(in) (in->left == 0 ? readmore(in) : 0, \
+                   in->left--, *(in->next)++)
+
+/* skip over n bytes of in */
+local void skip(file *in, unsigned n)
+{
+    unsigned bypass;
+
+    if (n > in->left) {
+        n -= in->left;
+        bypass = n & ~((1U << in->size) - 1);
+        if (bypass) {
+            if (lseek(in->fd, (off_t)bypass, SEEK_CUR) == -1)
+                bye("seeking ", in->name);
+            n -= bypass;
+        }
+        readmore(in);
+        if (n > in->left)
+            bye("unexpected end of ", in->name);
+    }
+    in->left -= n;
+    in->next += n;
+}
+
+/* read a four-byte unsigned integer, little-endian, from in */
+unsigned long read4(file *in)
+{
+    unsigned long val;
+
+    val = read1(in);
+    val += (unsigned)read1(in) << 8;
+    val += (unsigned long)read1(in) << 16;
+    val += (unsigned long)read1(in) << 24;
+    return val;
+}
+
+/* skip over gzip header */
+local void gzheader(file *in)
+{
+    int flags;
+    unsigned n;
+
+    if (read1(in) != 31 || read1(in) != 139) bye(in->name, " not a gzip file");
+    if (read1(in) != 8) bye("unknown compression method in", in->name);
+    flags = read1(in);
+    if (flags & 0xe0) bye("unknown header flags set in", in->name);
+    skip(in, 6);
+    if (flags & 4) {
+        n = read1(in);
+        n += (unsigned)(read1(in)) << 8;
+        skip(in, n);
+    }
+    if (flags & 8) while (read1(in) != 0) ;
+    if (flags & 16) while (read1(in) != 0) ;
+    if (flags & 2) skip(in, 2);
+}
+
+/* decompress gzip file "name", return strm with a deflate stream ready to
+   continue compression of the data in the gzip file, and return a file
+   descriptor pointing to where to write the compressed data -- the deflate
+   stream is initialized to compress using level "level" */
+local int gzscan(char *name, z_stream *strm, int level)
+{
+    int ret, lastbit, left, full;
+    unsigned have;
+    unsigned long crc, tot;
+    unsigned char *window;
+    off_t lastoff, end;
+    file gz;
+
+    /* open gzip file */
+    gz.name = name;
+    gz.fd = open(name, O_RDWR, 0);
+    if (gz.fd == -1) bye("cannot open ", name);
+    gz.buf = malloc(CHUNK);
+    if (gz.buf == NULL) bye("out of memory", "");
+    gz.size = LGCHUNK;
+    gz.left = 0;
+
+    /* skip gzip header */
+    gzheader(&gz);
+
+    /* prepare to decompress */
+    window = malloc(DSIZE);
+    if (window == NULL) bye("out of memory", "");
+    strm->zalloc = Z_NULL;
+    strm->zfree = Z_NULL;
+    strm->opaque = Z_NULL;
+    ret = inflateInit2(strm, -15);
+    if (ret != Z_OK) bye("out of memory", " or library mismatch");
+
+    /* decompress the deflate stream, saving append information */
+    lastbit = 0;
+    lastoff = lseek(gz.fd, 0L, SEEK_CUR) - gz.left;
+    left = 0;
+    strm->avail_in = gz.left;
+    strm->next_in = gz.next;
+    crc = crc32(0L, Z_NULL, 0);
+    have = full = 0;
+    do {
+        /* if needed, get more input */
+        if (strm->avail_in == 0) {
+            readmore(&gz);
+            strm->avail_in = gz.left;
+            strm->next_in = gz.next;
+        }
+
+        /* set up output to next available section of sliding window */
+        strm->avail_out = DSIZE - have;
+        strm->next_out = window + have;
+
+        /* inflate and check for errors */
+        ret = inflate(strm, Z_BLOCK);
+        if (ret == Z_STREAM_ERROR) bye("internal stream error!", "");
+        if (ret == Z_MEM_ERROR) bye("out of memory", "");
+        if (ret == Z_DATA_ERROR)
+            bye("invalid compressed data--format violated in", name);
+
+        /* update crc and sliding window pointer */
+        crc = crc32(crc, window + have, DSIZE - have - strm->avail_out);
+        if (strm->avail_out)
+            have = DSIZE - strm->avail_out;
+        else {
+            have = 0;
+            full = 1;
+        }
+
+        /* process end of block */
+        if (strm->data_type & 128) {
+            if (strm->data_type & 64)
+                left = strm->data_type & 0x1f;
+            else {
+                lastbit = strm->data_type & 0x1f;
+                lastoff = lseek(gz.fd, 0L, SEEK_CUR) - strm->avail_in;
+            }
+        }
+    } while (ret != Z_STREAM_END);
+    inflateEnd(strm);
+    gz.left = strm->avail_in;
+    gz.next = strm->next_in;
+
+    /* save the location of the end of the compressed data */
+    end = lseek(gz.fd, 0L, SEEK_CUR) - gz.left;
+
+    /* check gzip trailer and save total for deflate */
+    if (crc != read4(&gz))
+        bye("invalid compressed data--crc mismatch in ", name);
+    tot = strm->total_out;
+    if ((tot & 0xffffffffUL) != read4(&gz))
+        bye("invalid compressed data--length mismatch in", name);
+
+    /* if not at end of file, warn */
+    if (gz.left || readin(&gz))
+        fprintf(stderr,
+            "gzappend warning: junk at end of gzip file overwritten\n");
+
+    /* clear last block bit */
+    lseek(gz.fd, lastoff - (lastbit != 0), SEEK_SET);
+    if (read(gz.fd, gz.buf, 1) != 1) bye("reading after seek on ", name);
+    *gz.buf = (unsigned char)(*gz.buf ^ (1 << ((8 - lastbit) & 7)));
+    lseek(gz.fd, -1L, SEEK_CUR);
+    if (write(gz.fd, gz.buf, 1) != 1) bye("writing after seek to ", name);
+
+    /* if window wrapped, build dictionary from window by rotating */
+    if (full) {
+        rotate(window, DSIZE, have);
+        have = DSIZE;
+    }
+
+    /* set up deflate stream with window, crc, total_in, and leftover bits */
+    ret = deflateInit2(strm, level, Z_DEFLATED, -15, 8, Z_DEFAULT_STRATEGY);
+    if (ret != Z_OK) bye("out of memory", "");
+    deflateSetDictionary(strm, window, have);
+    strm->adler = crc;
+    strm->total_in = tot;
+    if (left) {
+        lseek(gz.fd, --end, SEEK_SET);
+        if (read(gz.fd, gz.buf, 1) != 1) bye("reading after seek on ", name);
+        deflatePrime(strm, 8 - left, *gz.buf);
+    }
+    lseek(gz.fd, end, SEEK_SET);
+
+    /* clean up and return */
+    free(window);
+    free(gz.buf);
+    return gz.fd;
+}
+
+/* append file "name" to gzip file gd using deflate stream strm -- if last
+   is true, then finish off the deflate stream at the end */
+local void gztack(char *name, int gd, z_stream *strm, int last)
+{
+    int fd, len, ret;
+    unsigned left;
+    unsigned char *in, *out;
+
+    /* open file to compress and append */
+    fd = 0;
+    if (name != NULL) {
+        fd = open(name, O_RDONLY, 0);
+        if (fd == -1)
+            fprintf(stderr, "gzappend warning: %s not found, skipping ...\n",
+                    name);
+    }
+
+    /* allocate buffers */
+    in = malloc(CHUNK);
+    out = malloc(CHUNK);
+    if (in == NULL || out == NULL) bye("out of memory", "");
+
+    /* compress input file and append to gzip file */
+    do {
+        /* get more input */
+        len = read(fd, in, CHUNK);
+        if (len == -1) {
+            fprintf(stderr,
+                    "gzappend warning: error reading %s, skipping rest ...\n",
+                    name);
+            len = 0;
+        }
+        strm->avail_in = (unsigned)len;
+        strm->next_in = in;
+        if (len) strm->adler = crc32(strm->adler, in, (unsigned)len);
+
+        /* compress and write all available output */
+        do {
+            strm->avail_out = CHUNK;
+            strm->next_out = out;
+            ret = deflate(strm, last && len == 0 ? Z_FINISH : Z_NO_FLUSH);
+            left = CHUNK - strm->avail_out;
+            while (left) {
+                len = write(gd, out + CHUNK - strm->avail_out - left, left);
+                if (len == -1) bye("writing gzip file", "");
+                left -= (unsigned)len;
+            }
+        } while (strm->avail_out == 0 && ret != Z_STREAM_END);
+    } while (len != 0);
+
+    /* write trailer after last entry */
+    if (last) {
+        deflateEnd(strm);
+        out[0] = (unsigned char)(strm->adler);
+        out[1] = (unsigned char)(strm->adler >> 8);
+        out[2] = (unsigned char)(strm->adler >> 16);
+        out[3] = (unsigned char)(strm->adler >> 24);
+        out[4] = (unsigned char)(strm->total_in);
+        out[5] = (unsigned char)(strm->total_in >> 8);
+        out[6] = (unsigned char)(strm->total_in >> 16);
+        out[7] = (unsigned char)(strm->total_in >> 24);
+        len = 8;
+        do {
+            ret = write(gd, out + 8 - len, len);
+            if (ret == -1) bye("writing gzip file", "");
+            len -= ret;
+        } while (len);
+        close(gd);
+    }
+
+    /* clean up and return */
+    free(out);
+    free(in);
+    if (fd > 0) close(fd);
+}
+
+/* process the compression level option if present, scan the gzip file, and
+   append the specified files, or append the data from stdin if no other file
+   names are provided on the command line -- the gzip file must be writable
+   and seekable */
+int main(int argc, char **argv)
+{
+    int gd, level;
+    z_stream strm;
+
+    /* ignore command name */
+    argc--; argv++;
+
+    /* provide usage if no arguments */
+    if (*argv == NULL) {
+        printf(
+            "gzappend 1.2 (11 Oct 2012) Copyright (C) 2003, 2012 Mark Adler\n"
+               );
+        printf(
+            "usage: gzappend [-level] file.gz [ addthis [ andthis ... ]]\n");
+        return 0;
+    }
+
+    /* set compression level */
+    level = Z_DEFAULT_COMPRESSION;
+    if (argv[0][0] == '-') {
+        if (argv[0][1] < '0' || argv[0][1] > '9' || argv[0][2] != 0)
+            bye("invalid compression level", "");
+        level = argv[0][1] - '0';
+        if (*++argv == NULL) bye("no gzip file name after options", "");
+    }
+
+    /* prepare to append to gzip file */
+    gd = gzscan(*argv++, &strm, level);
+
+    /* append files on command line, or from stdin if none */
+    if (*argv == NULL)
+        gztack(NULL, gd, &strm, 1);
+    else
+        do {
+            gztack(*argv, gd, &strm, argv[1] == NULL);
+        } while (*++argv != NULL);
+    return 0;
+}
diff --git a/compat/zlib/examples/gzjoin.c b/compat/zlib/examples/gzjoin.c
new file mode 100644
index 0000000..89e8098
--- /dev/null
+++ b/compat/zlib/examples/gzjoin.c
@@ -0,0 +1,449 @@
+/* gzjoin -- command to join gzip files into one gzip file
+
+  Copyright (C) 2004, 2005, 2012 Mark Adler, all rights reserved
+  version 1.2, 14 Aug 2012
+
+  This software is provided 'as-is', without any express or implied
+  warranty.  In no event will the author be held liable for any damages
+  arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any purpose,
+  including commercial applications, and to alter it and redistribute it
+  freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+
+  Mark Adler    madler@alumni.caltech.edu
+ */
+
+/*
+ * Change history:
+ *
+ * 1.0  11 Dec 2004     - First version
+ * 1.1  12 Jun 2005     - Changed ssize_t to long for portability
+ * 1.2  14 Aug 2012     - Clean up for z_const usage
+ */
+
+/*
+   gzjoin takes one or more gzip files on the command line and writes out a
+   single gzip file that will uncompress to the concatenation of the
+   uncompressed data from the individual gzip files.  gzjoin does this without
+   having to recompress any of the data and without having to calculate a new
+   crc32 for the concatenated uncompressed data.  gzjoin does however have to
+   decompress all of the input data in order to find the bits in the compressed
+   data that need to be modified to concatenate the streams.
+
+   gzjoin does not do an integrity check on the input gzip files other than
+   checking the gzip header and decompressing the compressed data.  They are
+   otherwise assumed to be complete and correct.
+
+   Each joint between gzip files removes at least 18 bytes of previous trailer
+   and subsequent header, and inserts an average of about three bytes to the
+   compressed data in order to connect the streams.  The output gzip file
+   has a minimal ten-byte gzip header with no file name or modification time.
+
+   This program was written to illustrate the use of the Z_BLOCK option of
+   inflate() and the crc32_combine() function.  gzjoin will not compile with
+   versions of zlib earlier than 1.2.3.
+ */
+
+#include <stdio.h>      /* fputs(), fprintf(), fwrite(), putc() */
+#include <stdlib.h>     /* exit(), malloc(), free() */
+#include <fcntl.h>      /* open() */
+#include <unistd.h>     /* close(), read(), lseek() */
+#include "zlib.h"
+    /* crc32(), crc32_combine(), inflateInit2(), inflate(), inflateEnd() */
+
+#define local static
+
+/* exit with an error (return a value to allow use in an expression) */
+local int bail(char *why1, char *why2)
+{
+    fprintf(stderr, "gzjoin error: %s%s, output incomplete\n", why1, why2);
+    exit(1);
+    return 0;
+}
+
+/* -- simple buffered file input with access to the buffer -- */
+
+#define CHUNK 32768         /* must be a power of two and fit in unsigned */
+
+/* bin buffered input file type */
+typedef struct {
+    char *name;             /* name of file for error messages */
+    int fd;                 /* file descriptor */
+    unsigned left;          /* bytes remaining at next */
+    unsigned char *next;    /* next byte to read */
+    unsigned char *buf;     /* allocated buffer of length CHUNK */
+} bin;
+
+/* close a buffered file and free allocated memory */
+local void bclose(bin *in)
+{
+    if (in != NULL) {
+        if (in->fd != -1)
+            close(in->fd);
+        if (in->buf != NULL)
+            free(in->buf);
+        free(in);
+    }
+}
+
+/* open a buffered file for input, return a pointer to type bin, or NULL on
+   failure */
+local bin *bopen(char *name)
+{
+    bin *in;
+
+    in = malloc(sizeof(bin));
+    if (in == NULL)
+        return NULL;
+    in->buf = malloc(CHUNK);
+    in->fd = open(name, O_RDONLY, 0);
+    if (in->buf == NULL || in->fd == -1) {
+        bclose(in);
+        return NULL;
+    }
+    in->left = 0;
+    in->next = in->buf;
+    in->name = name;
+    return in;
+}
+
+/* load buffer from file, return -1 on read error, 0 or 1 on success, with
+   1 indicating that end-of-file was reached */
+local int bload(bin *in)
+{
+    long len;
+
+    if (in == NULL)
+        return -1;
+    if (in->left != 0)
+        return 0;
+    in->next = in->buf;
+    do {
+        len = (long)read(in->fd, in->buf + in->left, CHUNK - in->left);
+        if (len < 0)
+            return -1;
+        in->left += (unsigned)len;
+    } while (len != 0 && in->left < CHUNK);
+    return len == 0 ? 1 : 0;
+}
+
+/* get a byte from the file, bail if end of file */
+#define bget(in) (in->left ? 0 : bload(in), \
+                  in->left ? (in->left--, *(in->next)++) : \
+                    bail("unexpected end of file on ", in->name))
+
+/* get a four-byte little-endian unsigned integer from file */
+local unsigned long bget4(bin *in)
+{
+    unsigned long val;
+
+    val = bget(in);
+    val += (unsigned long)(bget(in)) << 8;
+    val += (unsigned long)(bget(in)) << 16;
+    val += (unsigned long)(bget(in)) << 24;
+    return val;
+}
+
+/* skip bytes in file */
+local void bskip(bin *in, unsigned skip)
+{
+    /* check pointer */
+    if (in == NULL)
+        return;
+
+    /* easy case -- skip bytes in buffer */
+    if (skip <= in->left) {
+        in->left -= skip;
+        in->next += skip;
+        return;
+    }
+
+    /* skip what's in buffer, discard buffer contents */
+    skip -= in->left;
+    in->left = 0;
+
+    /* seek past multiples of CHUNK bytes */
+    if (skip > CHUNK) {
+        unsigned left;
+
+        left = skip & (CHUNK - 1);
+        if (left == 0) {
+            /* exact number of chunks: seek all the way minus one byte to check
+               for end-of-file with a read */
+            lseek(in->fd, skip - 1, SEEK_CUR);
+            if (read(in->fd, in->buf, 1) != 1)
+                bail("unexpected end of file on ", in->name);
+            return;
+        }
+
+        /* skip the integral chunks, update skip with remainder */
+        lseek(in->fd, skip - left, SEEK_CUR);
+        skip = left;
+    }
+
+    /* read more input and skip remainder */
+    bload(in);
+    if (skip > in->left)
+        bail("unexpected end of file on ", in->name);
+    in->left -= skip;
+    in->next += skip;
+}
+
+/* -- end of buffered input functions -- */
+
+/* skip the gzip header from file in */
+local void gzhead(bin *in)
+{
+    int flags;
+
+    /* verify gzip magic header and compression method */
+    if (bget(in) != 0x1f || bget(in) != 0x8b || bget(in) != 8)
+        bail(in->name, " is not a valid gzip file");
+
+    /* get and verify flags */
+    flags = bget(in);
+    if ((flags & 0xe0) != 0)
+        bail("unknown reserved bits set in ", in->name);
+
+    /* skip modification time, extra flags, and os */
+    bskip(in, 6);
+
+    /* skip extra field if present */
+    if (flags & 4) {
+        unsigned len;
+
+        len = bget(in);
+        len += (unsigned)(bget(in)) << 8;
+        bskip(in, len);
+    }
+
+    /* skip file name if present */
+    if (flags & 8)
+        while (bget(in) != 0)
+            ;
+
+    /* skip comment if present */
+    if (flags & 16)
+        while (bget(in) != 0)
+            ;
+
+    /* skip header crc if present */
+    if (flags & 2)
+        bskip(in, 2);
+}
+
+/* write a four-byte little-endian unsigned integer to out */
+local void put4(unsigned long val, FILE *out)
+{
+    putc(val & 0xff, out);
+    putc((val >> 8) & 0xff, out);
+    putc((val >> 16) & 0xff, out);
+    putc((val >> 24) & 0xff, out);
+}
+
+/* Load up zlib stream from buffered input, bail if end of file */
+local void zpull(z_streamp strm, bin *in)
+{
+    if (in->left == 0)
+        bload(in);
+    if (in->left == 0)
+        bail("unexpected end of file on ", in->name);
+    strm->avail_in = in->left;
+    strm->next_in = in->next;
+}
+
+/* Write header for gzip file to out and initialize trailer. */
+local void gzinit(unsigned long *crc, unsigned long *tot, FILE *out)
+{
+    fwrite("\x1f\x8b\x08\0\0\0\0\0\0\xff", 1, 10, out);
+    *crc = crc32(0L, Z_NULL, 0);
+    *tot = 0;
+}
+
+/* Copy the compressed data from name, zeroing the last block bit of the last
+   block if clr is true, and adding empty blocks as needed to get to a byte
+   boundary.  If clr is false, then the last block becomes the last block of
+   the output, and the gzip trailer is written.  crc and tot maintains the
+   crc and length (modulo 2^32) of the output for the trailer.  The resulting
+   gzip file is written to out.  gzinit() must be called before the first call
+   of gzcopy() to write the gzip header and to initialize crc and tot. */
+local void gzcopy(char *name, int clr, unsigned long *crc, unsigned long *tot,
+                  FILE *out)
+{
+    int ret;                /* return value from zlib functions */
+    int pos;                /* where the "last block" bit is in byte */
+    int last;               /* true if processing the last block */
+    bin *in;                /* buffered input file */
+    unsigned char *start;   /* start of compressed data in buffer */
+    unsigned char *junk;    /* buffer for uncompressed data -- discarded */
+    z_off_t len;            /* length of uncompressed data (support > 4 GB) */
+    z_stream strm;          /* zlib inflate stream */
+
+    /* open gzip file and skip header */
+    in = bopen(name);
+    if (in == NULL)
+        bail("could not open ", name);
+    gzhead(in);
+
+    /* allocate buffer for uncompressed data and initialize raw inflate
+       stream */
+    junk = malloc(CHUNK);
+    strm.zalloc = Z_NULL;
+    strm.zfree = Z_NULL;
+    strm.opaque = Z_NULL;
+    strm.avail_in = 0;
+    strm.next_in = Z_NULL;
+    ret = inflateInit2(&strm, -15);
+    if (junk == NULL || ret != Z_OK)
+        bail("out of memory", "");
+
+    /* inflate and copy compressed data, clear last-block bit if requested */
+    len = 0;
+    zpull(&strm, in);
+    start = in->next;
+    last = start[0] & 1;
+    if (last && clr)
+        start[0] &= ~1;
+    strm.avail_out = 0;
+    for (;;) {
+        /* if input used and output done, write used input and get more */
+        if (strm.avail_in == 0 && strm.avail_out != 0) {
+            fwrite(start, 1, strm.next_in - start, out);
+            start = in->buf;
+            in->left = 0;
+            zpull(&strm, in);
+        }
+
+        /* decompress -- return early when end-of-block reached */
+        strm.avail_out = CHUNK;
+        strm.next_out = junk;
+        ret = inflate(&strm, Z_BLOCK);
+        switch (ret) {
+        case Z_MEM_ERROR:
+            bail("out of memory", "");
+        case Z_DATA_ERROR:
+            bail("invalid compressed data in ", in->name);
+        }
+
+        /* update length of uncompressed data */
+        len += CHUNK - strm.avail_out;
+
+        /* check for block boundary (only get this when block copied out) */
+        if (strm.data_type & 128) {
+            /* if that was the last block, then done */
+            if (last)
+                break;
+
+            /* number of unused bits in last byte */
+            pos = strm.data_type & 7;
+
+            /* find the next last-block bit */
+            if (pos != 0) {
+                /* next last-block bit is in last used byte */
+                pos = 0x100 >> pos;
+                last = strm.next_in[-1] & pos;
+                if (last && clr)
+                    in->buf[strm.next_in - in->buf - 1] &= ~pos;
+            }
+            else {
+                /* next last-block bit is in next unused byte */
+                if (strm.avail_in == 0) {
+                    /* don't have that byte yet -- get it */
+                    fwrite(start, 1, strm.next_in - start, out);
+                    start = in->buf;
+                    in->left = 0;
+                    zpull(&strm, in);
+                }
+                last = strm.next_in[0] & 1;
+                if (last && clr)
+                    in->buf[strm.next_in - in->buf] &= ~1;
+            }
+        }
+    }
+
+    /* update buffer with unused input */
+    in->left = strm.avail_in;
+    in->next = in->buf + (strm.next_in - in->buf);
+
+    /* copy used input, write empty blocks to get to byte boundary */
+    pos = strm.data_type & 7;
+    fwrite(start, 1, in->next - start - 1, out);
+    last = in->next[-1];
+    if (pos == 0 || !clr)
+        /* already at byte boundary, or last file: write last byte */
+        putc(last, out);
+    else {
+        /* append empty blocks to last byte */
+        last &= ((0x100 >> pos) - 1);       /* assure unused bits are zero */
+        if (pos & 1) {
+            /* odd -- append an empty stored block */
+            putc(last, out);
+            if (pos == 1)
+                putc(0, out);               /* two more bits in block header */
+            fwrite("\0\0\xff\xff", 1, 4, out);
+        }
+        else {
+            /* even -- append 1, 2, or 3 empty fixed blocks */
+            switch (pos) {
+            case 6:
+                putc(last | 8, out);
+                last = 0;
+            case 4:
+                putc(last | 0x20, out);
+                last = 0;
+            case 2:
+                putc(last | 0x80, out);
+                putc(0, out);
+            }
+        }
+    }
+
+    /* update crc and tot */
+    *crc = crc32_combine(*crc, bget4(in), len);
+    *tot += (unsigned long)len;
+
+    /* clean up */
+    inflateEnd(&strm);
+    free(junk);
+    bclose(in);
+
+    /* write trailer if this is the last gzip file */
+    if (!clr) {
+        put4(*crc, out);
+        put4(*tot, out);
+    }
+}
+
+/* join the gzip files on the command line, write result to stdout */
+int main(int argc, char **argv)
+{
+    unsigned long crc, tot;     /* running crc and total uncompressed length */
+
+    /* skip command name */
+    argc--;
+    argv++;
+
+    /* show usage if no arguments */
+    if (argc == 0) {
+        fputs("gzjoin usage: gzjoin f1.gz [f2.gz [f3.gz ...]] > fjoin.gz\n",
+              stderr);
+        return 0;
+    }
+
+    /* join gzip files on command line and write to stdout */
+    gzinit(&crc, &tot, stdout);
+    while (argc--)
+        gzcopy(*argv++, argc, &crc, &tot, stdout);
+
+    /* done */
+    return 0;
+}
diff --git a/compat/zlib/examples/gzlog.c b/compat/zlib/examples/gzlog.c
new file mode 100644
index 0000000..922f878
--- /dev/null
+++ b/compat/zlib/examples/gzlog.c
@@ -0,0 +1,1059 @@
+/*
+ * gzlog.c
+ * Copyright (C) 2004, 2008, 2012 Mark Adler, all rights reserved
+ * For conditions of distribution and use, see copyright notice in gzlog.h
+ * version 2.2, 14 Aug 2012
+ */
+
+/*
+   gzlog provides a mechanism for frequently appending short strings to a gzip
+   file that is efficient both in execution time and compression ratio.  The
+   strategy is to write the short strings in an uncompressed form to the end of
+   the gzip file, only compressing when the amount of uncompressed data has
+   reached a given threshold.
+
+   gzlog also provides protection against interruptions in the process due to
+   system crashes.  The status of the operation is recorded in an extra field
+   in the gzip file, and is only updated once the gzip file is brought to a
+   valid state.  The last data to be appended or compressed is saved in an
+   auxiliary file, so that if the operation is interrupted, it can be completed
+   the next time an append operation is attempted.
+
+   gzlog maintains another auxiliary file with the last 32K of data from the
+   compressed portion, which is preloaded for the compression of the subsequent
+   data.  This minimizes the impact to the compression ratio of appending.
+ */
+
+/*
+   Operations Concept:
+
+   Files (log name "foo"):
+   foo.gz -- gzip file with the complete log
+   foo.add -- last message to append or last data to compress
+   foo.dict -- dictionary of the last 32K of data for next compression
+   foo.temp -- temporary dictionary file for compression after this one
+   foo.lock -- lock file for reading and writing the other files
+   foo.repairs -- log file for log file recovery operations (not compressed)
+
+   gzip file structure:
+   - fixed-length (no file name) header with extra field (see below)
+   - compressed data ending initially with empty stored block
+   - uncompressed data filling out originally empty stored block and
+     subsequent stored blocks as needed (16K max each)
+   - gzip trailer
+   - no junk at end (no other gzip streams)
+
+   When appending data, the information in the first three items above plus the
+   foo.add file are sufficient to recover an interrupted append operation.  The
+   extra field has the necessary information to restore the start of the last
+   stored block and determine where to append the data in the foo.add file, as
+   well as the crc and length of the gzip data before the append operation.
+
+   The foo.add file is created before the gzip file is marked for append, and
+   deleted after the gzip file is marked as complete.  So if the append
+   operation is interrupted, the data to add will still be there.  If due to
+   some external force, the foo.add file gets deleted between when the append
+   operation was interrupted and when recovery is attempted, the gzip file will
+   still be restored, but without the appended data.
+
+   When compressing data, the information in the first two items above plus the
+   foo.add file are sufficient to recover an interrupted compress operation.
+   The extra field has the necessary information to find the end of the
+   compressed data, and contains both the crc and length of just the compressed
+   data and of the complete set of data including the contents of the foo.add
+   file.
+
+   Again, the foo.add file is maintained during the compress operation in case
+   of an interruption.  If in the unlikely event the foo.add file with the data
+   to be compressed is missing due to some external force, a gzip file with
+   just the previous compressed data will be reconstructed.  In this case, all
+   of the data that was to be compressed is lost (approximately one megabyte).
+   This will not occur if all that happened was an interruption of the compress
+   operation.
+
+   The third state that is marked is the replacement of the old dictionary with
+   the new dictionary after a compress operation.  Once compression is
+   complete, the gzip file is marked as being in the replace state.  This
+   completes the gzip file, so an interrupt after being so marked does not
+   result in recompression.  Then the dictionary file is replaced, and the gzip
+   file is marked as completed.  This state prevents the possibility of
+   restarting compression with the wrong dictionary file.
+
+   All three operations are wrapped by a lock/unlock procedure.  In order to
+   gain exclusive access to the log files, first a foo.lock file must be
+   exclusively created.  When all operations are complete, the lock is
+   released by deleting the foo.lock file.  If when attempting to create the
+   lock file, it already exists and the modify time of the lock file is more
+   than five minutes old (set by the PATIENCE define below), then the old
+   lock file is considered stale and deleted, and the exclusive creation of
+   the lock file is retried.  To assure that there are no false assessments
+   of the staleness of the lock file, the operations periodically touch the
+   lock file to update the modified date.
+
+   Following is the definition of the extra field with all of the information
+   required to enable the above append and compress operations and their
+   recovery if interrupted.  Multi-byte values are stored little endian
+   (consistent with the gzip format).  File pointers are eight bytes long.
+   The crc's and lengths for the gzip trailer are four bytes long.  (Note that
+   the length at the end of a gzip file is used for error checking only, and
+   for large files is actually the length modulo 2^32.)  The stored block
+   length is two bytes long.  The gzip extra field two-byte identification is
+   "ap" for append.  It is assumed that writing the extra field to the file is
+   an "atomic" operation.  That is, either all of the extra field is written
+   to the file, or none of it is, if the operation is interrupted right at the
+   point of updating the extra field.  This is a reasonable assumption, since
+   the extra field is within the first 52 bytes of the file, which is smaller
+   than any expected block size for a mass storage device (usually 512 bytes or
+   larger).
+
+   Extra field (35 bytes):
+   - Pointer to first stored block length -- this points to the two-byte length
+     of the first stored block, which is followed by the two-byte, one's
+     complement of that length.  The stored block length is preceded by the
+     three-bit header of the stored block, which is the actual start of the
+     stored block in the deflate format.  See the bit offset field below.
+   - Pointer to the last stored block length.  This is the same as above, but
+     for the last stored block of the uncompressed data in the gzip file.
+     Initially this is the same as the first stored block length pointer.
+     When the stored block gets to 16K (see the MAX_STORE define), then a new
+     stored block as added, at which point the last stored block length pointer
+     is different from the first stored block length pointer.  When they are
+     different, the first bit of the last stored block header is eight bits, or
+     one byte back from the block length.
+   - Compressed data crc and length.  This is the crc and length of the data
+     that is in the compressed portion of the deflate stream.  These are used
+     only in the event that the foo.add file containing the data to compress is
+     lost after a compress operation is interrupted.
+   - Total data crc and length.  This is the crc and length of all of the data
+     stored in the gzip file, compressed and uncompressed.  It is used to
+     reconstruct the gzip trailer when compressing, as well as when recovering
+     interrupted operations.
+   - Final stored block length.  This is used to quickly find where to append,
+     and allows the restoration of the original final stored block state when
+     an append operation is interrupted.
+   - First stored block start as the number of bits back from the final stored
+     block first length byte.  This value is in the range of 3..10, and is
+     stored as the low three bits of the final byte of the extra field after
+     subtracting three (0..7).  This allows the last-block bit of the stored
+     block header to be updated when a new stored block is added, for the case
+     when the first stored block and the last stored block are the same.  (When
+     they are different, the numbers of bits back is known to be eight.)  This
+     also allows for new compressed data to be appended to the old compressed
+     data in the compress operation, overwriting the previous first stored
+     block, or for the compressed data to be terminated and a valid gzip file
+     reconstructed on the off chance that a compression operation was
+     interrupted and the data to compress in the foo.add file was deleted.
+   - The operation in process.  This is the next two bits in the last byte (the
+     bits under the mask 0x18).  The are interpreted as 0: nothing in process,
+     1: append in process, 2: compress in process, 3: replace in process.
+   - The top three bits of the last byte in the extra field are reserved and
+     are currently set to zero.
+
+   Main procedure:
+   - Exclusively create the foo.lock file using the O_CREAT and O_EXCL modes of
+     the system open() call.  If the modify time of an existing lock file is
+     more than PATIENCE seconds old, then the lock file is deleted and the
+     exclusive create is retried.
+   - Load the extra field from the foo.gz file, and see if an operation was in
+     progress but not completed.  If so, apply the recovery procedure below.
+   - Perform the append procedure with the provided data.
+   - If the uncompressed data in the foo.gz file is 1MB or more, apply the
+     compress procedure.
+   - Delete the foo.lock file.
+
+   Append procedure:
+   - Put what to append in the foo.add file so that the operation can be
+     restarted if this procedure is interrupted.
+   - Mark the foo.gz extra field with the append operation in progress.
+   + Restore the original last-block bit and stored block length of the last
+     stored block from the information in the extra field, in case a previous
+     append operation was interrupted.
+   - Append the provided data to the last stored block, creating new stored
+     blocks as needed and updating the stored blocks last-block bits and
+     lengths.
+   - Update the crc and length with the new data, and write the gzip trailer.
+   - Write over the extra field (with a single write operation) with the new
+     pointers, lengths, and crc's, and mark the gzip file as not in process.
+     Though there is still a foo.add file, it will be ignored since nothing
+     is in process.  If a foo.add file is leftover from a previously
+     completed operation, it is truncated when writing new data to it.
+   - Delete the foo.add file.
+
+   Compress and replace procedures:
+   - Read all of the uncompressed data in the stored blocks in foo.gz and write
+     it to foo.add.  Also write foo.temp with the last 32K of that data to
+     provide a dictionary for the next invocation of this procedure.
+   - Rewrite the extra field marking foo.gz with a compression in process.
+   * If there is no data provided to compress (due to a missing foo.add file
+     when recovering), reconstruct and truncate the foo.gz file to contain
+     only the previous compressed data and proceed to the step after the next
+     one.  Otherwise ...
+   - Compress the data with the dictionary in foo.dict, and write to the
+     foo.gz file starting at the bit immediately following the last previously
+     compressed block.  If there is no foo.dict, proceed anyway with the
+     compression at slightly reduced efficiency.  (For the foo.dict file to be
+     missing requires some external failure beyond simply the interruption of
+     a compress operation.)  During this process, the foo.lock file is
+     periodically touched to assure that that file is not considered stale by
+     another process before we're done.  The deflation is terminated with a
+     non-last empty static block (10 bits long), that is then located and
+     written over by a last-bit-set empty stored block.
+   - Append the crc and length of the data in the gzip file (previously
+     calculated during the append operations).
+   - Write over the extra field with the updated stored block offsets, bits
+     back, crc's, and lengths, and mark foo.gz as in process for a replacement
+     of the dictionary.
+   @ Delete the foo.add file.
+   - Replace foo.dict with foo.temp.
+   - Write over the extra field, marking foo.gz as complete.
+
+   Recovery procedure:
+   - If not a replace recovery, read in the foo.add file, and provide that data
+     to the appropriate recovery below.  If there is no foo.add file, provide
+     a zero data length to the recovery.  In that case, the append recovery
+     restores the foo.gz to the previous compressed + uncompressed data state.
+     For the the compress recovery, a missing foo.add file results in foo.gz
+     being restored to the previous compressed-only data state.
+   - Append recovery:
+     - Pick up append at + step above
+   - Compress recovery:
+     - Pick up compress at * step above
+   - Replace recovery:
+     - Pick up compress at @ step above
+   - Log the repair with a date stamp in foo.repairs
+ */
+
+#include <sys/types.h>
+#include <stdio.h>      /* rename, fopen, fprintf, fclose */
+#include <stdlib.h>     /* malloc, free */
+#include <string.h>     /* strlen, strrchr, strcpy, strncpy, strcmp */
+#include <fcntl.h>      /* open */
+#include <unistd.h>     /* lseek, read, write, close, unlink, sleep, */
+                        /* ftruncate, fsync */
+#include <errno.h>      /* errno */
+#include <time.h>       /* time, ctime */
+#include <sys/stat.h>   /* stat */
+#include <sys/time.h>   /* utimes */
+#include "zlib.h"       /* crc32 */
+
+#include "gzlog.h"      /* header for external access */
+
+#define local static
+typedef unsigned int uint;
+typedef unsigned long ulong;
+
+/* Macro for debugging to deterministically force recovery operations */
+#ifdef DEBUG
+    #include <setjmp.h>         /* longjmp */
+    jmp_buf gzlog_jump;         /* where to go back to */
+    int gzlog_bail = 0;         /* which point to bail at (1..8) */
+    int gzlog_count = -1;       /* number of times through to wait */
+#   define BAIL(n) do { if (n == gzlog_bail && gzlog_count-- == 0) \
+                            longjmp(gzlog_jump, gzlog_bail); } while (0)
+#else
+#   define BAIL(n)
+#endif
+
+/* how old the lock file can be in seconds before considering it stale */
+#define PATIENCE 300
+
+/* maximum stored block size in Kbytes -- must be in 1..63 */
+#define MAX_STORE 16
+
+/* number of stored Kbytes to trigger compression (must be >= 32 to allow
+   dictionary construction, and <= 204 * MAX_STORE, in order for >> 10 to
+   discard the stored block headers contribution of five bytes each) */
+#define TRIGGER 1024
+
+/* size of a deflate dictionary (this cannot be changed) */
+#define DICT 32768U
+
+/* values for the operation (2 bits) */
+#define NO_OP 0
+#define APPEND_OP 1
+#define COMPRESS_OP 2
+#define REPLACE_OP 3
+
+/* macros to extract little-endian integers from an unsigned byte buffer */
+#define PULL2(p) ((p)[0]+((uint)((p)[1])<<8))
+#define PULL4(p) (PULL2(p)+((ulong)PULL2(p+2)<<16))
+#define PULL8(p) (PULL4(p)+((off_t)PULL4(p+4)<<32))
+
+/* macros to store integers into a byte buffer in little-endian order */
+#define PUT2(p,a) do {(p)[0]=a;(p)[1]=(a)>>8;} while(0)
+#define PUT4(p,a) do {PUT2(p,a);PUT2(p+2,a>>16);} while(0)
+#define PUT8(p,a) do {PUT4(p,a);PUT4(p+4,a>>32);} while(0)
+
+/* internal structure for log information */
+#define LOGID "\106\035\172"    /* should be three non-zero characters */
+struct log {
+    char id[4];     /* contains LOGID to detect inadvertent overwrites */
+    int fd;         /* file descriptor for .gz file, opened read/write */
+    char *path;     /* allocated path, e.g. "/var/log/foo" or "foo" */
+    char *end;      /* end of path, for appending suffices such as ".gz" */
+    off_t first;    /* offset of first stored block first length byte */
+    int back;       /* location of first block id in bits back from first */
+    uint stored;    /* bytes currently in last stored block */
+    off_t last;     /* offset of last stored block first length byte */
+    ulong ccrc;     /* crc of compressed data */
+    ulong clen;     /* length (modulo 2^32) of compressed data */
+    ulong tcrc;     /* crc of total data */
+    ulong tlen;     /* length (modulo 2^32) of total data */
+    time_t lock;    /* last modify time of our lock file */
+};
+
+/* gzip header for gzlog */
+local unsigned char log_gzhead[] = {
+    0x1f, 0x8b,                 /* magic gzip id */
+    8,                          /* compression method is deflate */
+    4,                          /* there is an extra field (no file name) */
+    0, 0, 0, 0,                 /* no modification time provided */
+    0, 0xff,                    /* no extra flags, no OS specified */
+    39, 0, 'a', 'p', 35, 0      /* extra field with "ap" subfield */
+                                /* 35 is EXTRA, 39 is EXTRA + 4 */
+};
+
+#define HEAD sizeof(log_gzhead)     /* should be 16 */
+
+/* initial gzip extra field content (52 == HEAD + EXTRA + 1) */
+local unsigned char log_gzext[] = {
+    52, 0, 0, 0, 0, 0, 0, 0,    /* offset of first stored block length */
+    52, 0, 0, 0, 0, 0, 0, 0,    /* offset of last stored block length */
+    0, 0, 0, 0, 0, 0, 0, 0,     /* compressed data crc and length */
+    0, 0, 0, 0, 0, 0, 0, 0,     /* total data crc and length */
+    0, 0,                       /* final stored block data length */
+    5                           /* op is NO_OP, last bit 8 bits back */
+};
+
+#define EXTRA sizeof(log_gzext)     /* should be 35 */
+
+/* initial gzip data and trailer */
+local unsigned char log_gzbody[] = {
+    1, 0, 0, 0xff, 0xff,        /* empty stored block (last) */
+    0, 0, 0, 0,                 /* crc */
+    0, 0, 0, 0                  /* uncompressed length */
+};
+
+#define BODY sizeof(log_gzbody)
+
+/* Exclusively create foo.lock in order to negotiate exclusive access to the
+   foo.* files.  If the modify time of an existing lock file is greater than
+   PATIENCE seconds in the past, then consider the lock file to have been
+   abandoned, delete it, and try the exclusive create again.  Save the lock
+   file modify time for verification of ownership.  Return 0 on success, or -1
+   on failure, usually due to an access restriction or invalid path.  Note that
+   if stat() or unlink() fails, it may be due to another process noticing the
+   abandoned lock file a smidge sooner and deleting it, so those are not
+   flagged as an error. */
+local int log_lock(struct log *log)
+{
+    int fd;
+    struct stat st;
+
+    strcpy(log->end, ".lock");
+    while ((fd = open(log->path, O_CREAT | O_EXCL, 0644)) < 0) {
+        if (errno != EEXIST)
+            return -1;
+        if (stat(log->path, &st) == 0 && time(NULL) - st.st_mtime > PATIENCE) {
+            unlink(log->path);
+            continue;
+        }
+        sleep(2);       /* relinquish the CPU for two seconds while waiting */
+    }
+    close(fd);
+    if (stat(log->path, &st) == 0)
+        log->lock = st.st_mtime;
+    return 0;
+}
+
+/* Update the modify time of the lock file to now, in order to prevent another
+   task from thinking that the lock is stale.  Save the lock file modify time
+   for verification of ownership. */
+local void log_touch(struct log *log)
+{
+    struct stat st;
+
+    strcpy(log->end, ".lock");
+    utimes(log->path, NULL);
+    if (stat(log->path, &st) == 0)
+        log->lock = st.st_mtime;
+}
+
+/* Check the log file modify time against what is expected.  Return true if
+   this is not our lock.  If it is our lock, touch it to keep it. */
+local int log_check(struct log *log)
+{
+    struct stat st;
+
+    strcpy(log->end, ".lock");
+    if (stat(log->path, &st) || st.st_mtime != log->lock)
+        return 1;
+    log_touch(log);
+    return 0;
+}
+
+/* Unlock a previously acquired lock, but only if it's ours. */
+local void log_unlock(struct log *log)
+{
+    if (log_check(log))
+        return;
+    strcpy(log->end, ".lock");
+    unlink(log->path);
+    log->lock = 0;
+}
+
+/* Check the gzip header and read in the extra field, filling in the values in
+   the log structure.  Return op on success or -1 if the gzip header was not as
+   expected.  op is the current operation in progress last written to the extra
+   field.  This assumes that the gzip file has already been opened, with the
+   file descriptor log->fd. */
+local int log_head(struct log *log)
+{
+    int op;
+    unsigned char buf[HEAD + EXTRA];
+
+    if (lseek(log->fd, 0, SEEK_SET) < 0 ||
+        read(log->fd, buf, HEAD + EXTRA) != HEAD + EXTRA ||
+        memcmp(buf, log_gzhead, HEAD)) {
+        return -1;
+    }
+    log->first = PULL8(buf + HEAD);
+    log->last = PULL8(buf + HEAD + 8);
+    log->ccrc = PULL4(buf + HEAD + 16);
+    log->clen = PULL4(buf + HEAD + 20);
+    log->tcrc = PULL4(buf + HEAD + 24);
+    log->tlen = PULL4(buf + HEAD + 28);
+    log->stored = PULL2(buf + HEAD + 32);
+    log->back = 3 + (buf[HEAD + 34] & 7);
+    op = (buf[HEAD + 34] >> 3) & 3;
+    return op;
+}
+
+/* Write over the extra field contents, marking the operation as op.  Use fsync
+   to assure that the device is written to, and in the requested order.  This
+   operation, and only this operation, is assumed to be atomic in order to
+   assure that the log is recoverable in the event of an interruption at any
+   point in the process.  Return -1 if the write to foo.gz failed. */
+local int log_mark(struct log *log, int op)
+{
+    int ret;
+    unsigned char ext[EXTRA];
+
+    PUT8(ext, log->first);
+    PUT8(ext + 8, log->last);
+    PUT4(ext + 16, log->ccrc);
+    PUT4(ext + 20, log->clen);
+    PUT4(ext + 24, log->tcrc);
+    PUT4(ext + 28, log->tlen);
+    PUT2(ext + 32, log->stored);
+    ext[34] = log->back - 3 + (op << 3);
+    fsync(log->fd);
+    ret = lseek(log->fd, HEAD, SEEK_SET) < 0 ||
+          write(log->fd, ext, EXTRA) != EXTRA ? -1 : 0;
+    fsync(log->fd);
+    return ret;
+}
+
+/* Rewrite the last block header bits and subsequent zero bits to get to a byte
+   boundary, setting the last block bit if last is true, and then write the
+   remainder of the stored block header (length and one's complement).  Leave
+   the file pointer after the end of the last stored block data.  Return -1 if
+   there is a read or write failure on the foo.gz file */
+local int log_last(struct log *log, int last)
+{
+    int back, len, mask;
+    unsigned char buf[6];
+
+    /* determine the locations of the bytes and bits to modify */
+    back = log->last == log->first ? log->back : 8;
+    len = back > 8 ? 2 : 1;                 /* bytes back from log->last */
+    mask = 0x80 >> ((back - 1) & 7);        /* mask for block last-bit */
+
+    /* get the byte to modify (one or two back) into buf[0] -- don't need to
+       read the byte if the last-bit is eight bits back, since in that case
+       the entire byte will be modified */
+    buf[0] = 0;
+    if (back != 8 && (lseek(log->fd, log->last - len, SEEK_SET) < 0 ||
+                      read(log->fd, buf, 1) != 1))
+        return -1;
+
+    /* change the last-bit of the last stored block as requested -- note
+       that all bits above the last-bit are set to zero, per the type bits
+       of a stored block being 00 and per the convention that the bits to
+       bring the stream to a byte boundary are also zeros */
+    buf[1] = 0;
+    buf[2 - len] = (*buf & (mask - 1)) + (last ? mask : 0);
+
+    /* write the modified stored block header and lengths, move the file
+       pointer to after the last stored block data */
+    PUT2(buf + 2, log->stored);
+    PUT2(buf + 4, log->stored ^ 0xffff);
+    return lseek(log->fd, log->last - len, SEEK_SET) < 0 ||
+           write(log->fd, buf + 2 - len, len + 4) != len + 4 ||
+           lseek(log->fd, log->stored, SEEK_CUR) < 0 ? -1 : 0;
+}
+
+/* Append len bytes from data to the locked and open log file.  len may be zero
+   if recovering and no .add file was found.  In that case, the previous state
+   of the foo.gz file is restored.  The data is appended uncompressed in
+   deflate stored blocks.  Return -1 if there was an error reading or writing
+   the foo.gz file. */
+local int log_append(struct log *log, unsigned char *data, size_t len)
+{
+    uint put;
+    off_t end;
+    unsigned char buf[8];
+
+    /* set the last block last-bit and length, in case recovering an
+       interrupted append, then position the file pointer to append to the
+       block */
+    if (log_last(log, 1))
+        return -1;
+
+    /* append, adding stored blocks and updating the offset of the last stored
+       block as needed, and update the total crc and length */
+    while (len) {
+        /* append as much as we can to the last block */
+        put = (MAX_STORE << 10) - log->stored;
+        if (put > len)
+            put = (uint)len;
+        if (put) {
+            if (write(log->fd, data, put) != put)
+                return -1;
+            BAIL(1);
+            log->tcrc = crc32(log->tcrc, data, put);
+            log->tlen += put;
+            log->stored += put;
+            data += put;
+            len -= put;
+        }
+
+        /* if we need to, add a new empty stored block */
+        if (len) {
+            /* mark current block as not last */
+            if (log_last(log, 0))
+                return -1;
+
+            /* point to new, empty stored block */
+            log->last += 4 + log->stored + 1;
+            log->stored = 0;
+        }
+
+        /* mark last block as last, update its length */
+        if (log_last(log, 1))
+            return -1;
+        BAIL(2);
+    }
+
+    /* write the new crc and length trailer, and truncate just in case (could
+       be recovering from partial append with a missing foo.add file) */
+    PUT4(buf, log->tcrc);
+    PUT4(buf + 4, log->tlen);
+    if (write(log->fd, buf, 8) != 8 ||
+        (end = lseek(log->fd, 0, SEEK_CUR)) < 0 || ftruncate(log->fd, end))
+        return -1;
+
+    /* write the extra field, marking the log file as done, delete .add file */
+    if (log_mark(log, NO_OP))
+        return -1;
+    strcpy(log->end, ".add");
+    unlink(log->path);          /* ignore error, since may not exist */
+    return 0;
+}
+
+/* Replace the foo.dict file with the foo.temp file.  Also delete the foo.add
+   file, since the compress operation may have been interrupted before that was
+   done.  Returns 1 if memory could not be allocated, or -1 if reading or
+   writing foo.gz fails, or if the rename fails for some reason other than
+   foo.temp not existing.  foo.temp not existing is a permitted error, since
+   the replace operation may have been interrupted after the rename is done,
+   but before foo.gz is marked as complete. */
+local int log_replace(struct log *log)
+{
+    int ret;
+    char *dest;
+
+    /* delete foo.add file */
+    strcpy(log->end, ".add");
+    unlink(log->path);         /* ignore error, since may not exist */
+    BAIL(3);
+
+    /* rename foo.name to foo.dict, replacing foo.dict if it exists */
+    strcpy(log->end, ".dict");
+    dest = malloc(strlen(log->path) + 1);
+    if (dest == NULL)
+        return -2;
+    strcpy(dest, log->path);
+    strcpy(log->end, ".temp");
+    ret = rename(log->path, dest);
+    free(dest);
+    if (ret && errno != ENOENT)
+        return -1;
+    BAIL(4);
+
+    /* mark the foo.gz file as done */
+    return log_mark(log, NO_OP);
+}
+
+/* Compress the len bytes at data and append the compressed data to the
+   foo.gz deflate data immediately after the previous compressed data.  This
+   overwrites the previous uncompressed data, which was stored in foo.add
+   and is the data provided in data[0..len-1].  If this operation is
+   interrupted, it picks up at the start of this routine, with the foo.add
+   file read in again.  If there is no data to compress (len == 0), then we
+   simply terminate the foo.gz file after the previously compressed data,
+   appending a final empty stored block and the gzip trailer.  Return -1 if
+   reading or writing the log.gz file failed, or -2 if there was a memory
+   allocation failure. */
+local int log_compress(struct log *log, unsigned char *data, size_t len)
+{
+    int fd;
+    uint got, max;
+    ssize_t dict;
+    off_t end;
+    z_stream strm;
+    unsigned char buf[DICT];
+
+    /* compress and append compressed data */
+    if (len) {
+        /* set up for deflate, allocating memory */
+        strm.zalloc = Z_NULL;
+        strm.zfree = Z_NULL;
+        strm.opaque = Z_NULL;
+        if (deflateInit2(&strm, Z_DEFAULT_COMPRESSION, Z_DEFLATED, -15, 8,
+                         Z_DEFAULT_STRATEGY) != Z_OK)
+            return -2;
+
+        /* read in dictionary (last 32K of data that was compressed) */
+        strcpy(log->end, ".dict");
+        fd = open(log->path, O_RDONLY, 0);
+        if (fd >= 0) {
+            dict = read(fd, buf, DICT);
+            close(fd);
+            if (dict < 0) {
+                deflateEnd(&strm);
+                return -1;
+            }
+            if (dict)
+                deflateSetDictionary(&strm, buf, (uint)dict);
+        }
+        log_touch(log);
+
+        /* prime deflate with last bits of previous block, position write
+           pointer to write those bits and overwrite what follows */
+        if (lseek(log->fd, log->first - (log->back > 8 ? 2 : 1),
+                SEEK_SET) < 0 ||
+            read(log->fd, buf, 1) != 1 || lseek(log->fd, -1, SEEK_CUR) < 0) {
+            deflateEnd(&strm);
+            return -1;
+        }
+        deflatePrime(&strm, (8 - log->back) & 7, *buf);
+
+        /* compress, finishing with a partial non-last empty static block */
+        strm.next_in = data;
+        max = (((uint)0 - 1) >> 1) + 1; /* in case int smaller than size_t */
+        do {
+            strm.avail_in = len > max ? max : (uint)len;
+            len -= strm.avail_in;
+            do {
+                strm.avail_out = DICT;
+                strm.next_out = buf;
+                deflate(&strm, len ? Z_NO_FLUSH : Z_PARTIAL_FLUSH);
+                got = DICT - strm.avail_out;
+                if (got && write(log->fd, buf, got) != got) {
+                    deflateEnd(&strm);
+                    return -1;
+                }
+                log_touch(log);
+            } while (strm.avail_out == 0);
+        } while (len);
+        deflateEnd(&strm);
+        BAIL(5);
+
+        /* find start of empty static block -- scanning backwards the first one
+           bit is the second bit of the block, if the last byte is zero, then
+           we know the byte before that has a one in the top bit, since an
+           empty static block is ten bits long */
+        if ((log->first = lseek(log->fd, -1, SEEK_CUR)) < 0 ||
+            read(log->fd, buf, 1) != 1)
+            return -1;
+        log->first++;
+        if (*buf) {
+            log->back = 1;
+            while ((*buf & ((uint)1 << (8 - log->back++))) == 0)
+                ;       /* guaranteed to terminate, since *buf != 0 */
+        }
+        else
+            log->back = 10;
+
+        /* update compressed crc and length */
+        log->ccrc = log->tcrc;
+        log->clen = log->tlen;
+    }
+    else {
+        /* no data to compress -- fix up existing gzip stream */
+        log->tcrc = log->ccrc;
+        log->tlen = log->clen;
+    }
+
+    /* complete and truncate gzip stream */
+    log->last = log->first;
+    log->stored = 0;
+    PUT4(buf, log->tcrc);
+    PUT4(buf + 4, log->tlen);
+    if (log_last(log, 1) || write(log->fd, buf, 8) != 8 ||
+        (end = lseek(log->fd, 0, SEEK_CUR)) < 0 || ftruncate(log->fd, end))
+        return -1;
+    BAIL(6);
+
+    /* mark as being in the replace operation */
+    if (log_mark(log, REPLACE_OP))
+        return -1;
+
+    /* execute the replace operation and mark the file as done */
+    return log_replace(log);
+}
+
+/* log a repair record to the .repairs file */
+local void log_log(struct log *log, int op, char *record)
+{
+    time_t now;
+    FILE *rec;
+
+    now = time(NULL);
+    strcpy(log->end, ".repairs");
+    rec = fopen(log->path, "a");
+    if (rec == NULL)
+        return;
+    fprintf(rec, "%.24s %s recovery: %s\n", ctime(&now), op == APPEND_OP ?
+            "append" : (op == COMPRESS_OP ? "compress" : "replace"), record);
+    fclose(rec);
+    return;
+}
+
+/* Recover the interrupted operation op.  First read foo.add for recovering an
+   append or compress operation.  Return -1 if there was an error reading or
+   writing foo.gz or reading an existing foo.add, or -2 if there was a memory
+   allocation failure. */
+local int log_recover(struct log *log, int op)
+{
+    int fd, ret = 0;
+    unsigned char *data = NULL;
+    size_t len = 0;
+    struct stat st;
+
+    /* log recovery */
+    log_log(log, op, "start");
+
+    /* load foo.add file if expected and present */
+    if (op == APPEND_OP || op == COMPRESS_OP) {
+        strcpy(log->end, ".add");
+        if (stat(log->path, &st) == 0 && st.st_size) {
+            len = (size_t)(st.st_size);
+            if ((off_t)len != st.st_size ||
+                    (data = malloc(st.st_size)) == NULL) {
+                log_log(log, op, "allocation failure");
+                return -2;
+            }
+            if ((fd = open(log->path, O_RDONLY, 0)) < 0) {
+                log_log(log, op, ".add file read failure");
+                return -1;
+            }
+            ret = (size_t)read(fd, data, len) != len;
+            close(fd);
+            if (ret) {
+                log_log(log, op, ".add file read failure");
+                return -1;
+            }
+            log_log(log, op, "loaded .add file");
+        }
+        else
+            log_log(log, op, "missing .add file!");
+    }
+
+    /* recover the interrupted operation */
+    switch (op) {
+    case APPEND_OP:
+        ret = log_append(log, data, len);
+        break;
+    case COMPRESS_OP:
+        ret = log_compress(log, data, len);
+        break;
+    case REPLACE_OP:
+        ret = log_replace(log);
+    }
+
+    /* log status */
+    log_log(log, op, ret ? "failure" : "complete");
+
+    /* clean up */
+    if (data != NULL)
+        free(data);
+    return ret;
+}
+
+/* Close the foo.gz file (if open) and release the lock. */
+local void log_close(struct log *log)
+{
+    if (log->fd >= 0)
+        close(log->fd);
+    log->fd = -1;
+    log_unlock(log);
+}
+
+/* Open foo.gz, verify the header, and load the extra field contents, after
+   first creating the foo.lock file to gain exclusive access to the foo.*
+   files.  If foo.gz does not exist or is empty, then write the initial header,
+   extra, and body content of an empty foo.gz log file.  If there is an error
+   creating the lock file due to access restrictions, or an error reading or
+   writing the foo.gz file, or if the foo.gz file is not a proper log file for
+   this object (e.g. not a gzip file or does not contain the expected extra
+   field), then return true.  If there is an error, the lock is released.
+   Otherwise, the lock is left in place. */
+local int log_open(struct log *log)
+{
+    int op;
+
+    /* release open file resource if left over -- can occur if lock lost
+       between gzlog_open() and gzlog_write() */
+    if (log->fd >= 0)
+        close(log->fd);
+    log->fd = -1;
+
+    /* negotiate exclusive access */
+    if (log_lock(log) < 0)
+        return -1;
+
+    /* open the log file, foo.gz */
+    strcpy(log->end, ".gz");
+    log->fd = open(log->path, O_RDWR | O_CREAT, 0644);
+    if (log->fd < 0) {
+        log_close(log);
+        return -1;
+    }
+
+    /* if new, initialize foo.gz with an empty log, delete old dictionary */
+    if (lseek(log->fd, 0, SEEK_END) == 0) {
+        if (write(log->fd, log_gzhead, HEAD) != HEAD ||
+            write(log->fd, log_gzext, EXTRA) != EXTRA ||
+            write(log->fd, log_gzbody, BODY) != BODY) {
+            log_close(log);
+            return -1;
+        }
+        strcpy(log->end, ".dict");
+        unlink(log->path);
+    }
+
+    /* verify log file and load extra field information */
+    if ((op = log_head(log)) < 0) {
+        log_close(log);
+        return -1;
+    }
+
+    /* check for interrupted process and if so, recover */
+    if (op != NO_OP && log_recover(log, op)) {
+        log_close(log);
+        return -1;
+    }
+
+    /* touch the lock file to prevent another process from grabbing it */
+    log_touch(log);
+    return 0;
+}
+
+/* See gzlog.h for the description of the external methods below */
+gzlog *gzlog_open(char *path)
+{
+    size_t n;
+    struct log *log;
+
+    /* check arguments */
+    if (path == NULL || *path == 0)
+        return NULL;
+
+    /* allocate and initialize log structure */
+    log = malloc(sizeof(struct log));
+    if (log == NULL)
+        return NULL;
+    strcpy(log->id, LOGID);
+    log->fd = -1;
+
+    /* save path and end of path for name construction */
+    n = strlen(path);
+    log->path = malloc(n + 9);              /* allow for ".repairs" */
+    if (log->path == NULL) {
+        free(log);
+        return NULL;
+    }
+    strcpy(log->path, path);
+    log->end = log->path + n;
+
+    /* gain exclusive access and verify log file -- may perform a
+       recovery operation if needed */
+    if (log_open(log)) {
+        free(log->path);
+        free(log);
+        return NULL;
+    }
+
+    /* return pointer to log structure */
+    return log;
+}
+
+/* gzlog_compress() return values:
+    0: all good
+   -1: file i/o error (usually access issue)
+   -2: memory allocation failure
+   -3: invalid log pointer argument */
+int gzlog_compress(gzlog *logd)
+{
+    int fd, ret;
+    uint block;
+    size_t len, next;
+    unsigned char *data, buf[5];
+    struct log *log = logd;
+
+    /* check arguments */
+    if (log == NULL || strcmp(log->id, LOGID))
+        return -3;
+
+    /* see if we lost the lock -- if so get it again and reload the extra
+       field information (it probably changed), recover last operation if
+       necessary */
+    if (log_check(log) && log_open(log))
+        return -1;
+
+    /* create space for uncompressed data */
+    len = ((size_t)(log->last - log->first) & ~(((size_t)1 << 10) - 1)) +
+          log->stored;
+    if ((data = malloc(len)) == NULL)
+        return -2;
+
+    /* do statement here is just a cheap trick for error handling */
+    do {
+        /* read in the uncompressed data */
+        if (lseek(log->fd, log->first - 1, SEEK_SET) < 0)
+            break;
+        next = 0;
+        while (next < len) {
+            if (read(log->fd, buf, 5) != 5)
+                break;
+            block = PULL2(buf + 1);
+            if (next + block > len ||
+                read(log->fd, (char *)data + next, block) != block)
+                break;
+            next += block;
+        }
+        if (lseek(log->fd, 0, SEEK_CUR) != log->last + 4 + log->stored)
+            break;
+        log_touch(log);
+
+        /* write the uncompressed data to the .add file */
+        strcpy(log->end, ".add");
+        fd = open(log->path, O_WRONLY | O_CREAT | O_TRUNC, 0644);
+        if (fd < 0)
+            break;
+        ret = (size_t)write(fd, data, len) != len;
+        if (ret | close(fd))
+            break;
+        log_touch(log);
+
+        /* write the dictionary for the next compress to the .temp file */
+        strcpy(log->end, ".temp");
+        fd = open(log->path, O_WRONLY | O_CREAT | O_TRUNC, 0644);
+        if (fd < 0)
+            break;
+        next = DICT > len ? len : DICT;
+        ret = (size_t)write(fd, (char *)data + len - next, next) != next;
+        if (ret | close(fd))
+            break;
+        log_touch(log);
+
+        /* roll back to compressed data, mark the compress in progress */
+        log->last = log->first;
+        log->stored = 0;
+        if (log_mark(log, COMPRESS_OP))
+            break;
+        BAIL(7);
+
+        /* compress and append the data (clears mark) */
+        ret = log_compress(log, data, len);
+        free(data);
+        return ret;
+    } while (0);
+
+    /* broke out of do above on i/o error */
+    free(data);
+    return -1;
+}
+
+/* gzlog_write() return values:
+    0: all good
+   -1: file i/o error (usually access issue)
+   -2: memory allocation failure
+   -3: invalid log pointer argument */
+int gzlog_write(gzlog *logd, void *data, size_t len)
+{
+    int fd, ret;
+    struct log *log = logd;
+
+    /* check arguments */
+    if (log == NULL || strcmp(log->id, LOGID))
+        return -3;
+    if (data == NULL || len <= 0)
+        return 0;
+
+    /* see if we lost the lock -- if so get it again and reload the extra
+       field information (it probably changed), recover last operation if
+       necessary */
+    if (log_check(log) && log_open(log))
+        return -1;
+
+    /* create and write .add file */
+    strcpy(log->end, ".add");
+    fd = open(log->path, O_WRONLY | O_CREAT | O_TRUNC, 0644);
+    if (fd < 0)
+        return -1;
+    ret = (size_t)write(fd, data, len) != len;
+    if (ret | close(fd))
+        return -1;
+    log_touch(log);
+
+    /* mark log file with append in progress */
+    if (log_mark(log, APPEND_OP))
+        return -1;
+    BAIL(8);
+
+    /* append data (clears mark) */
+    if (log_append(log, data, len))
+        return -1;
+
+    /* check to see if it's time to compress -- if not, then done */
+    if (((log->last - log->first) >> 10) + (log->stored >> 10) < TRIGGER)
+        return 0;
+
+    /* time to compress */
+    return gzlog_compress(log);
+}
+
+/* gzlog_close() return values:
+    0: ok
+   -3: invalid log pointer argument */
+int gzlog_close(gzlog *logd)
+{
+    struct log *log = logd;
+
+    /* check arguments */
+    if (log == NULL || strcmp(log->id, LOGID))
+        return -3;
+
+    /* close the log file and release the lock */
+    log_close(log);
+
+    /* free structure and return */
+    if (log->path != NULL)
+        free(log->path);
+    strcpy(log->id, "bad");
+    free(log);
+    return 0;
+}
diff --git a/compat/zlib/examples/gzlog.h b/compat/zlib/examples/gzlog.h
new file mode 100644
index 0000000..86f0cec
--- /dev/null
+++ b/compat/zlib/examples/gzlog.h
@@ -0,0 +1,91 @@
+/* gzlog.h
+  Copyright (C) 2004, 2008, 2012 Mark Adler, all rights reserved
+  version 2.2, 14 Aug 2012
+
+  This software is provided 'as-is', without any express or implied
+  warranty.  In no event will the author be held liable for any damages
+  arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any purpose,
+  including commercial applications, and to alter it and redistribute it
+  freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+
+  Mark Adler    madler@alumni.caltech.edu
+ */
+
+/* Version History:
+   1.0  26 Nov 2004  First version
+   2.0  25 Apr 2008  Complete redesign for recovery of interrupted operations
+                     Interface changed slightly in that now path is a prefix
+                     Compression now occurs as needed during gzlog_write()
+                     gzlog_write() now always leaves the log file as valid gzip
+   2.1   8 Jul 2012  Fix argument checks in gzlog_compress() and gzlog_write()
+   2.2  14 Aug 2012  Clean up signed comparisons
+ */
+
+/*
+   The gzlog object allows writing short messages to a gzipped log file,
+   opening the log file locked for small bursts, and then closing it.  The log
+   object works by appending stored (uncompressed) data to the gzip file until
+   1 MB has been accumulated.  At that time, the stored data is compressed, and
+   replaces the uncompressed data in the file.  The log file is truncated to
+   its new size at that time.  After each write operation, the log file is a
+   valid gzip file that can decompressed to recover what was written.
+
+   The gzlog operations can be interupted at any point due to an application or
+   system crash, and the log file will be recovered the next time the log is
+   opened with gzlog_open().
+ */
+
+#ifndef GZLOG_H
+#define GZLOG_H
+
+/* gzlog object type */
+typedef void gzlog;
+
+/* Open a gzlog object, creating the log file if it does not exist.  Return
+   NULL on error.  Note that gzlog_open() could take a while to complete if it
+   has to wait to verify that a lock is stale (possibly for five minutes), or
+   if there is significant contention with other instantiations of this object
+   when locking the resource.  path is the prefix of the file names created by
+   this object.  If path is "foo", then the log file will be "foo.gz", and
+   other auxiliary files will be created and destroyed during the process:
+   "foo.dict" for a compression dictionary, "foo.temp" for a temporary (next)
+   dictionary, "foo.add" for data being added or compressed, "foo.lock" for the
+   lock file, and "foo.repairs" to log recovery operations performed due to
+   interrupted gzlog operations.  A gzlog_open() followed by a gzlog_close()
+   will recover a previously interrupted operation, if any. */
+gzlog *gzlog_open(char *path);
+
+/* Write to a gzlog object.  Return zero on success, -1 if there is a file i/o
+   error on any of the gzlog files (this should not happen if gzlog_open()
+   succeeded, unless the device has run out of space or leftover auxiliary
+   files have permissions or ownership that prevent their use), -2 if there is
+   a memory allocation failure, or -3 if the log argument is invalid (e.g. if
+   it was not created by gzlog_open()).  This function will write data to the
+   file uncompressed, until 1 MB has been accumulated, at which time that data
+   will be compressed.  The log file will be a valid gzip file upon successful
+   return. */
+int gzlog_write(gzlog *log, void *data, size_t len);
+
+/* Force compression of any uncompressed data in the log.  This should be used
+   sparingly, if at all.  The main application would be when a log file will
+   not be appended to again.  If this is used to compress frequently while
+   appending, it will both significantly increase the execution time and
+   reduce the compression ratio.  The return codes are the same as for
+   gzlog_write(). */
+int gzlog_compress(gzlog *log);
+
+/* Close a gzlog object.  Return zero on success, -3 if the log argument is
+   invalid.  The log object is freed, and so cannot be referenced again. */
+int gzlog_close(gzlog *log);
+
+#endif
diff --git a/compat/zlib/examples/zlib_how.html b/compat/zlib/examples/zlib_how.html
new file mode 100644
index 0000000..444ff1c
--- /dev/null
+++ b/compat/zlib/examples/zlib_how.html
@@ -0,0 +1,545 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"
+  "http://www.w3.org/TR/REC-html40/loose.dtd">
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+<title>zlib Usage Example</title>
+<!--  Copyright (c) 2004, 2005 Mark Adler.  -->
+</head>
+<body bgcolor="#FFFFFF" text="#000000" link="#0000FF" vlink="#00A000">
+<h2 align="center"> zlib Usage Example </h2>
+We often get questions about how the <tt>deflate()</tt> and <tt>inflate()</tt> functions should be used.
+Users wonder when they should provide more input, when they should use more output,
+what to do with a <tt>Z_BUF_ERROR</tt>, how to make sure the process terminates properly, and
+so on.  So for those who have read <tt>zlib.h</tt> (a few times), and
+would like further edification, below is an annotated example in C of simple routines to compress and decompress
+from an input file to an output file using <tt>deflate()</tt> and <tt>inflate()</tt> respectively.  The
+annotations are interspersed between lines of the code.  So please read between the lines.
+We hope this helps explain some of the intricacies of <em>zlib</em>.
+<p>
+Without further adieu, here is the program <a href="zpipe.c"><tt>zpipe.c</tt></a>:
+<pre><b>
+/* zpipe.c: example of proper use of zlib's inflate() and deflate()
+   Not copyrighted -- provided to the public domain
+   Version 1.4  11 December 2005  Mark Adler */
+
+/* Version history:
+   1.0  30 Oct 2004  First version
+   1.1   8 Nov 2004  Add void casting for unused return values
+                     Use switch statement for inflate() return values
+   1.2   9 Nov 2004  Add assertions to document zlib guarantees
+   1.3   6 Apr 2005  Remove incorrect assertion in inf()
+   1.4  11 Dec 2005  Add hack to avoid MSDOS end-of-line conversions
+                     Avoid some compiler warnings for input and output buffers
+ */
+</b></pre><!-- -->
+We now include the header files for the required definitions.  From
+<tt>stdio.h</tt> we use <tt>fopen()</tt>, <tt>fread()</tt>, <tt>fwrite()</tt>,
+<tt>feof()</tt>, <tt>ferror()</tt>, and <tt>fclose()</tt> for file i/o, and
+<tt>fputs()</tt> for error messages.  From <tt>string.h</tt> we use
+<tt>strcmp()</tt> for command line argument processing.
+From <tt>assert.h</tt> we use the <tt>assert()</tt> macro.
+From <tt>zlib.h</tt>
+we use the basic compression functions <tt>deflateInit()</tt>,
+<tt>deflate()</tt>, and <tt>deflateEnd()</tt>, and the basic decompression
+functions <tt>inflateInit()</tt>, <tt>inflate()</tt>, and
+<tt>inflateEnd()</tt>.
+<pre><b>
+#include &lt;stdio.h&gt;
+#include &lt;string.h&gt;
+#include &lt;assert.h&gt;
+#include "zlib.h"
+</b></pre><!-- -->
+This is an ugly hack required to avoid corruption of the input and output data on
+Windows/MS-DOS systems.  Without this, those systems would assume that the input and output
+files are text, and try to convert the end-of-line characters from one standard to
+another.  That would corrupt binary data, and in particular would render the compressed data unusable.
+This sets the input and output to binary which suppresses the end-of-line conversions.
+<tt>SET_BINARY_MODE()</tt> will be used later on <tt>stdin</tt> and <tt>stdout</tt>, at the beginning of <tt>main()</tt>.
+<pre><b>
+#if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(__CYGWIN__)
+#  include &lt;fcntl.h&gt;
+#  include &lt;io.h&gt;
+#  define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY)
+#else
+#  define SET_BINARY_MODE(file)
+#endif
+</b></pre><!-- -->
+<tt>CHUNK</tt> is simply the buffer size for feeding data to and pulling data
+from the <em>zlib</em> routines.  Larger buffer sizes would be more efficient,
+especially for <tt>inflate()</tt>.  If the memory is available, buffers sizes
+on the order of 128K or 256K bytes should be used.
+<pre><b>
+#define CHUNK 16384
+</b></pre><!-- -->
+The <tt>def()</tt> routine compresses data from an input file to an output file.  The output data
+will be in the <em>zlib</em> format, which is different from the <em>gzip</em> or <em>zip</em>
+formats.  The <em>zlib</em> format has a very small header of only two bytes to identify it as
+a <em>zlib</em> stream and to provide decoding information, and a four-byte trailer with a fast
+check value to verify the integrity of the uncompressed data after decoding.
+<pre><b>
+/* Compress from file source to file dest until EOF on source.
+   def() returns Z_OK on success, Z_MEM_ERROR if memory could not be
+   allocated for processing, Z_STREAM_ERROR if an invalid compression
+   level is supplied, Z_VERSION_ERROR if the version of zlib.h and the
+   version of the library linked do not match, or Z_ERRNO if there is
+   an error reading or writing the files. */
+int def(FILE *source, FILE *dest, int level)
+{
+</b></pre>
+Here are the local variables for <tt>def()</tt>.  <tt>ret</tt> will be used for <em>zlib</em>
+return codes.  <tt>flush</tt> will keep track of the current flushing state for <tt>deflate()</tt>,
+which is either no flushing, or flush to completion after the end of the input file is reached.
+<tt>have</tt> is the amount of data returned from <tt>deflate()</tt>.  The <tt>strm</tt> structure
+is used to pass information to and from the <em>zlib</em> routines, and to maintain the
+<tt>deflate()</tt> state.  <tt>in</tt> and <tt>out</tt> are the input and output buffers for
+<tt>deflate()</tt>.
+<pre><b>
+    int ret, flush;
+    unsigned have;
+    z_stream strm;
+    unsigned char in[CHUNK];
+    unsigned char out[CHUNK];
+</b></pre><!-- -->
+The first thing we do is to initialize the <em>zlib</em> state for compression using
+<tt>deflateInit()</tt>.  This must be done before the first use of <tt>deflate()</tt>.
+The <tt>zalloc</tt>, <tt>zfree</tt>, and <tt>opaque</tt> fields in the <tt>strm</tt>
+structure must be initialized before calling <tt>deflateInit()</tt>.  Here they are
+set to the <em>zlib</em> constant <tt>Z_NULL</tt> to request that <em>zlib</em> use
+the default memory allocation routines.  An application may also choose to provide
+custom memory allocation routines here.  <tt>deflateInit()</tt> will allocate on the
+order of 256K bytes for the internal state.
+(See <a href="zlib_tech.html"><em>zlib Technical Details</em></a>.)
+<p>
+<tt>deflateInit()</tt> is called with a pointer to the structure to be initialized and
+the compression level, which is an integer in the range of -1 to 9.  Lower compression
+levels result in faster execution, but less compression.  Higher levels result in
+greater compression, but slower execution.  The <em>zlib</em> constant Z_DEFAULT_COMPRESSION,
+equal to -1,
+provides a good compromise between compression and speed and is equivalent to level 6.
+Level 0 actually does no compression at all, and in fact expands the data slightly to produce
+the <em>zlib</em> format (it is not a byte-for-byte copy of the input).
+More advanced applications of <em>zlib</em>
+may use <tt>deflateInit2()</tt> here instead.  Such an application may want to reduce how
+much memory will be used, at some price in compression.  Or it may need to request a
+<em>gzip</em> header and trailer instead of a <em>zlib</em> header and trailer, or raw
+encoding with no header or trailer at all.
+<p>
+We must check the return value of <tt>deflateInit()</tt> against the <em>zlib</em> constant
+<tt>Z_OK</tt> to make sure that it was able to
+allocate memory for the internal state, and that the provided arguments were valid.
+<tt>deflateInit()</tt> will also check that the version of <em>zlib</em> that the <tt>zlib.h</tt>
+file came from matches the version of <em>zlib</em> actually linked with the program.  This
+is especially important for environments in which <em>zlib</em> is a shared library.
+<p>
+Note that an application can initialize multiple, independent <em>zlib</em> streams, which can
+operate in parallel.  The state information maintained in the structure allows the <em>zlib</em>
+routines to be reentrant.
+<pre><b>
+    /* allocate deflate state */
+    strm.zalloc = Z_NULL;
+    strm.zfree = Z_NULL;
+    strm.opaque = Z_NULL;
+    ret = deflateInit(&amp;strm, level);
+    if (ret != Z_OK)
+        return ret;
+</b></pre><!-- -->
+With the pleasantries out of the way, now we can get down to business.  The outer <tt>do</tt>-loop
+reads all of the input file and exits at the bottom of the loop once end-of-file is reached.
+This loop contains the only call of <tt>deflate()</tt>.  So we must make sure that all of the
+input data has been processed and that all of the output data has been generated and consumed
+before we fall out of the loop at the bottom.
+<pre><b>
+    /* compress until end of file */
+    do {
+</b></pre>
+We start off by reading data from the input file.  The number of bytes read is put directly
+into <tt>avail_in</tt>, and a pointer to those bytes is put into <tt>next_in</tt>.  We also
+check to see if end-of-file on the input has been reached.  If we are at the end of file, then <tt>flush</tt> is set to the
+<em>zlib</em> constant <tt>Z_FINISH</tt>, which is later passed to <tt>deflate()</tt> to
+indicate that this is the last chunk of input data to compress.  We need to use <tt>feof()</tt>
+to check for end-of-file as opposed to seeing if fewer than <tt>CHUNK</tt> bytes have been read.  The
+reason is that if the input file length is an exact multiple of <tt>CHUNK</tt>, we will miss
+the fact that we got to the end-of-file, and not know to tell <tt>deflate()</tt> to finish
+up the compressed stream.  If we are not yet at the end of the input, then the <em>zlib</em>
+constant <tt>Z_NO_FLUSH</tt> will be passed to <tt>deflate</tt> to indicate that we are still
+in the middle of the uncompressed data.
+<p>
+If there is an error in reading from the input file, the process is aborted with
+<tt>deflateEnd()</tt> being called to free the allocated <em>zlib</em> state before returning
+the error.  We wouldn't want a memory leak, now would we?  <tt>deflateEnd()</tt> can be called
+at any time after the state has been initialized.  Once that's done, <tt>deflateInit()</tt> (or
+<tt>deflateInit2()</tt>) would have to be called to start a new compression process.  There is
+no point here in checking the <tt>deflateEnd()</tt> return code.  The deallocation can't fail.
+<pre><b>
+        strm.avail_in = fread(in, 1, CHUNK, source);
+        if (ferror(source)) {
+            (void)deflateEnd(&amp;strm);
+            return Z_ERRNO;
+        }
+        flush = feof(source) ? Z_FINISH : Z_NO_FLUSH;
+        strm.next_in = in;
+</b></pre><!-- -->
+The inner <tt>do</tt>-loop passes our chunk of input data to <tt>deflate()</tt>, and then
+keeps calling <tt>deflate()</tt> until it is done producing output.  Once there is no more
+new output, <tt>deflate()</tt> is guaranteed to have consumed all of the input, i.e.,
+<tt>avail_in</tt> will be zero.
+<pre><b>
+        /* run deflate() on input until output buffer not full, finish
+           compression if all of source has been read in */
+        do {
+</b></pre>
+Output space is provided to <tt>deflate()</tt> by setting <tt>avail_out</tt> to the number
+of available output bytes and <tt>next_out</tt> to a pointer to that space.
+<pre><b>
+            strm.avail_out = CHUNK;
+            strm.next_out = out;
+</b></pre>
+Now we call the compression engine itself, <tt>deflate()</tt>.  It takes as many of the
+<tt>avail_in</tt> bytes at <tt>next_in</tt> as it can process, and writes as many as
+<tt>avail_out</tt> bytes to <tt>next_out</tt>.  Those counters and pointers are then
+updated past the input data consumed and the output data written.  It is the amount of
+output space available that may limit how much input is consumed.
+Hence the inner loop to make sure that
+all of the input is consumed by providing more output space each time.  Since <tt>avail_in</tt>
+and <tt>next_in</tt> are updated by <tt>deflate()</tt>, we don't have to mess with those
+between <tt>deflate()</tt> calls until it's all used up.
+<p>
+The parameters to <tt>deflate()</tt> are a pointer to the <tt>strm</tt> structure containing
+the input and output information and the internal compression engine state, and a parameter
+indicating whether and how to flush data to the output.  Normally <tt>deflate</tt> will consume
+several K bytes of input data before producing any output (except for the header), in order
+to accumulate statistics on the data for optimum compression.  It will then put out a burst of
+compressed data, and proceed to consume more input before the next burst.  Eventually,
+<tt>deflate()</tt>
+must be told to terminate the stream, complete the compression with provided input data, and
+write out the trailer check value.  <tt>deflate()</tt> will continue to compress normally as long
+as the flush parameter is <tt>Z_NO_FLUSH</tt>.  Once the <tt>Z_FINISH</tt> parameter is provided,
+<tt>deflate()</tt> will begin to complete the compressed output stream.  However depending on how
+much output space is provided, <tt>deflate()</tt> may have to be called several times until it
+has provided the complete compressed stream, even after it has consumed all of the input.  The flush
+parameter must continue to be <tt>Z_FINISH</tt> for those subsequent calls.
+<p>
+There are other values of the flush parameter that are used in more advanced applications.  You can
+force <tt>deflate()</tt> to produce a burst of output that encodes all of the input data provided
+so far, even if it wouldn't have otherwise, for example to control data latency on a link with
+compressed data.  You can also ask that <tt>deflate()</tt> do that as well as erase any history up to
+that point so that what follows can be decompressed independently, for example for random access
+applications.  Both requests will degrade compression by an amount depending on how often such
+requests are made.
+<p>
+<tt>deflate()</tt> has a return value that can indicate errors, yet we do not check it here.  Why
+not?  Well, it turns out that <tt>deflate()</tt> can do no wrong here.  Let's go through
+<tt>deflate()</tt>'s return values and dispense with them one by one.  The possible values are
+<tt>Z_OK</tt>, <tt>Z_STREAM_END</tt>, <tt>Z_STREAM_ERROR</tt>, or <tt>Z_BUF_ERROR</tt>.  <tt>Z_OK</tt>
+is, well, ok.  <tt>Z_STREAM_END</tt> is also ok and will be returned for the last call of
+<tt>deflate()</tt>.  This is already guaranteed by calling <tt>deflate()</tt> with <tt>Z_FINISH</tt>
+until it has no more output.  <tt>Z_STREAM_ERROR</tt> is only possible if the stream is not
+initialized properly, but we did initialize it properly.  There is no harm in checking for
+<tt>Z_STREAM_ERROR</tt> here, for example to check for the possibility that some
+other part of the application inadvertently clobbered the memory containing the <em>zlib</em> state.
+<tt>Z_BUF_ERROR</tt> will be explained further below, but
+suffice it to say that this is simply an indication that <tt>deflate()</tt> could not consume
+more input or produce more output.  <tt>deflate()</tt> can be called again with more output space
+or more available input, which it will be in this code.
+<pre><b>
+            ret = deflate(&amp;strm, flush);    /* no bad return value */
+            assert(ret != Z_STREAM_ERROR);  /* state not clobbered */
+</b></pre>
+Now we compute how much output <tt>deflate()</tt> provided on the last call, which is the
+difference between how much space was provided before the call, and how much output space
+is still available after the call.  Then that data, if any, is written to the output file.
+We can then reuse the output buffer for the next call of <tt>deflate()</tt>.  Again if there
+is a file i/o error, we call <tt>deflateEnd()</tt> before returning to avoid a memory leak.
+<pre><b>
+            have = CHUNK - strm.avail_out;
+            if (fwrite(out, 1, have, dest) != have || ferror(dest)) {
+                (void)deflateEnd(&amp;strm);
+                return Z_ERRNO;
+            }
+</b></pre>
+The inner <tt>do</tt>-loop is repeated until the last <tt>deflate()</tt> call fails to fill the
+provided output buffer.  Then we know that <tt>deflate()</tt> has done as much as it can with
+the provided input, and that all of that input has been consumed.  We can then fall out of this
+loop and reuse the input buffer.
+<p>
+The way we tell that <tt>deflate()</tt> has no more output is by seeing that it did not fill
+the output buffer, leaving <tt>avail_out</tt> greater than zero.  However suppose that
+<tt>deflate()</tt> has no more output, but just so happened to exactly fill the output buffer!
+<tt>avail_out</tt> is zero, and we can't tell that <tt>deflate()</tt> has done all it can.
+As far as we know, <tt>deflate()</tt>
+has more output for us.  So we call it again.  But now <tt>deflate()</tt> produces no output
+at all, and <tt>avail_out</tt> remains unchanged as <tt>CHUNK</tt>.  That <tt>deflate()</tt> call
+wasn't able to do anything, either consume input or produce output, and so it returns
+<tt>Z_BUF_ERROR</tt>.  (See, I told you I'd cover this later.)  However this is not a problem at
+all.  Now we finally have the desired indication that <tt>deflate()</tt> is really done,
+and so we drop out of the inner loop to provide more input to <tt>deflate()</tt>.
+<p>
+With <tt>flush</tt> set to <tt>Z_FINISH</tt>, this final set of <tt>deflate()</tt> calls will
+complete the output stream.  Once that is done, subsequent calls of <tt>deflate()</tt> would return
+<tt>Z_STREAM_ERROR</tt> if the flush parameter is not <tt>Z_FINISH</tt>, and do no more processing
+until the state is reinitialized.
+<p>
+Some applications of <em>zlib</em> have two loops that call <tt>deflate()</tt>
+instead of the single inner loop we have here.  The first loop would call
+without flushing and feed all of the data to <tt>deflate()</tt>.  The second loop would call
+<tt>deflate()</tt> with no more
+data and the <tt>Z_FINISH</tt> parameter to complete the process.  As you can see from this
+example, that can be avoided by simply keeping track of the current flush state.
+<pre><b>
+        } while (strm.avail_out == 0);
+        assert(strm.avail_in == 0);     /* all input will be used */
+</b></pre><!-- -->
+Now we check to see if we have already processed all of the input file.  That information was
+saved in the <tt>flush</tt> variable, so we see if that was set to <tt>Z_FINISH</tt>.  If so,
+then we're done and we fall out of the outer loop.  We're guaranteed to get <tt>Z_STREAM_END</tt>
+from the last <tt>deflate()</tt> call, since we ran it until the last chunk of input was
+consumed and all of the output was generated.
+<pre><b>
+        /* done when last data in file processed */
+    } while (flush != Z_FINISH);
+    assert(ret == Z_STREAM_END);        /* stream will be complete */
+</b></pre><!-- -->
+The process is complete, but we still need to deallocate the state to avoid a memory leak
+(or rather more like a memory hemorrhage if you didn't do this).  Then
+finally we can return with a happy return value.
+<pre><b>
+    /* clean up and return */
+    (void)deflateEnd(&amp;strm);
+    return Z_OK;
+}
+</b></pre><!-- -->
+Now we do the same thing for decompression in the <tt>inf()</tt> routine. <tt>inf()</tt>
+decompresses what is hopefully a valid <em>zlib</em> stream from the input file and writes the
+uncompressed data to the output file.  Much of the discussion above for <tt>def()</tt>
+applies to <tt>inf()</tt> as well, so the discussion here will focus on the differences between
+the two.
+<pre><b>
+/* Decompress from file source to file dest until stream ends or EOF.
+   inf() returns Z_OK on success, Z_MEM_ERROR if memory could not be
+   allocated for processing, Z_DATA_ERROR if the deflate data is
+   invalid or incomplete, Z_VERSION_ERROR if the version of zlib.h and
+   the version of the library linked do not match, or Z_ERRNO if there
+   is an error reading or writing the files. */
+int inf(FILE *source, FILE *dest)
+{
+</b></pre>
+The local variables have the same functionality as they do for <tt>def()</tt>.  The
+only difference is that there is no <tt>flush</tt> variable, since <tt>inflate()</tt>
+can tell from the <em>zlib</em> stream itself when the stream is complete.
+<pre><b>
+    int ret;
+    unsigned have;
+    z_stream strm;
+    unsigned char in[CHUNK];
+    unsigned char out[CHUNK];
+</b></pre><!-- -->
+The initialization of the state is the same, except that there is no compression level,
+of course, and two more elements of the structure are initialized.  <tt>avail_in</tt>
+and <tt>next_in</tt> must be initialized before calling <tt>inflateInit()</tt>.  This
+is because the application has the option to provide the start of the zlib stream in
+order for <tt>inflateInit()</tt> to have access to information about the compression
+method to aid in memory allocation.  In the current implementation of <em>zlib</em>
+(up through versions 1.2.x), the method-dependent memory allocations are deferred to the first call of
+<tt>inflate()</tt> anyway.  However those fields must be initialized since later versions
+of <em>zlib</em> that provide more compression methods may take advantage of this interface.
+In any case, no decompression is performed by <tt>inflateInit()</tt>, so the
+<tt>avail_out</tt> and <tt>next_out</tt> fields do not need to be initialized before calling.
+<p>
+Here <tt>avail_in</tt> is set to zero and <tt>next_in</tt> is set to <tt>Z_NULL</tt> to
+indicate that no input data is being provided.
+<pre><b>
+    /* allocate inflate state */
+    strm.zalloc = Z_NULL;
+    strm.zfree = Z_NULL;
+    strm.opaque = Z_NULL;
+    strm.avail_in = 0;
+    strm.next_in = Z_NULL;
+    ret = inflateInit(&amp;strm);
+    if (ret != Z_OK)
+        return ret;
+</b></pre><!-- -->
+The outer <tt>do</tt>-loop decompresses input until <tt>inflate()</tt> indicates
+that it has reached the end of the compressed data and has produced all of the uncompressed
+output.  This is in contrast to <tt>def()</tt> which processes all of the input file.
+If end-of-file is reached before the compressed data self-terminates, then the compressed
+data is incomplete and an error is returned.
+<pre><b>
+    /* decompress until deflate stream ends or end of file */
+    do {
+</b></pre>
+We read input data and set the <tt>strm</tt> structure accordingly.  If we've reached the
+end of the input file, then we leave the outer loop and report an error, since the
+compressed data is incomplete.  Note that we may read more data than is eventually consumed
+by <tt>inflate()</tt>, if the input file continues past the <em>zlib</em> stream.
+For applications where <em>zlib</em> streams are embedded in other data, this routine would
+need to be modified to return the unused data, or at least indicate how much of the input
+data was not used, so the application would know where to pick up after the <em>zlib</em> stream.
+<pre><b>
+        strm.avail_in = fread(in, 1, CHUNK, source);
+        if (ferror(source)) {
+            (void)inflateEnd(&amp;strm);
+            return Z_ERRNO;
+        }
+        if (strm.avail_in == 0)
+            break;
+        strm.next_in = in;
+</b></pre><!-- -->
+The inner <tt>do</tt>-loop has the same function it did in <tt>def()</tt>, which is to
+keep calling <tt>inflate()</tt> until has generated all of the output it can with the
+provided input.
+<pre><b>
+        /* run inflate() on input until output buffer not full */
+        do {
+</b></pre>
+Just like in <tt>def()</tt>, the same output space is provided for each call of <tt>inflate()</tt>.
+<pre><b>
+            strm.avail_out = CHUNK;
+            strm.next_out = out;
+</b></pre>
+Now we run the decompression engine itself.  There is no need to adjust the flush parameter, since
+the <em>zlib</em> format is self-terminating. The main difference here is that there are
+return values that we need to pay attention to.  <tt>Z_DATA_ERROR</tt>
+indicates that <tt>inflate()</tt> detected an error in the <em>zlib</em> compressed data format,
+which means that either the data is not a <em>zlib</em> stream to begin with, or that the data was
+corrupted somewhere along the way since it was compressed.  The other error to be processed is
+<tt>Z_MEM_ERROR</tt>, which can occur since memory allocation is deferred until <tt>inflate()</tt>
+needs it, unlike <tt>deflate()</tt>, whose memory is allocated at the start by <tt>deflateInit()</tt>.
+<p>
+Advanced applications may use
+<tt>deflateSetDictionary()</tt> to prime <tt>deflate()</tt> with a set of likely data to improve the
+first 32K or so of compression.  This is noted in the <em>zlib</em> header, so <tt>inflate()</tt>
+requests that that dictionary be provided before it can start to decompress.  Without the dictionary,
+correct decompression is not possible.  For this routine, we have no idea what the dictionary is,
+so the <tt>Z_NEED_DICT</tt> indication is converted to a <tt>Z_DATA_ERROR</tt>.
+<p>
+<tt>inflate()</tt> can also return <tt>Z_STREAM_ERROR</tt>, which should not be possible here,
+but could be checked for as noted above for <tt>def()</tt>.  <tt>Z_BUF_ERROR</tt> does not need to be
+checked for here, for the same reasons noted for <tt>def()</tt>.  <tt>Z_STREAM_END</tt> will be
+checked for later.
+<pre><b>
+            ret = inflate(&amp;strm, Z_NO_FLUSH);
+            assert(ret != Z_STREAM_ERROR);  /* state not clobbered */
+            switch (ret) {
+            case Z_NEED_DICT:
+                ret = Z_DATA_ERROR;     /* and fall through */
+            case Z_DATA_ERROR:
+            case Z_MEM_ERROR:
+                (void)inflateEnd(&amp;strm);
+                return ret;
+            }
+</b></pre>
+The output of <tt>inflate()</tt> is handled identically to that of <tt>deflate()</tt>.
+<pre><b>
+            have = CHUNK - strm.avail_out;
+            if (fwrite(out, 1, have, dest) != have || ferror(dest)) {
+                (void)inflateEnd(&amp;strm);
+                return Z_ERRNO;
+            }
+</b></pre>
+The inner <tt>do</tt>-loop ends when <tt>inflate()</tt> has no more output as indicated
+by not filling the output buffer, just as for <tt>deflate()</tt>.  In this case, we cannot
+assert that <tt>strm.avail_in</tt> will be zero, since the deflate stream may end before the file
+does.
+<pre><b>
+        } while (strm.avail_out == 0);
+</b></pre><!-- -->
+The outer <tt>do</tt>-loop ends when <tt>inflate()</tt> reports that it has reached the
+end of the input <em>zlib</em> stream, has completed the decompression and integrity
+check, and has provided all of the output.  This is indicated by the <tt>inflate()</tt>
+return value <tt>Z_STREAM_END</tt>.  The inner loop is guaranteed to leave <tt>ret</tt>
+equal to <tt>Z_STREAM_END</tt> if the last chunk of the input file read contained the end
+of the <em>zlib</em> stream.  So if the return value is not <tt>Z_STREAM_END</tt>, the
+loop continues to read more input.
+<pre><b>
+        /* done when inflate() says it's done */
+    } while (ret != Z_STREAM_END);
+</b></pre><!-- -->
+At this point, decompression successfully completed, or we broke out of the loop due to no
+more data being available from the input file.  If the last <tt>inflate()</tt> return value
+is not <tt>Z_STREAM_END</tt>, then the <em>zlib</em> stream was incomplete and a data error
+is returned.  Otherwise, we return with a happy return value.  Of course, <tt>inflateEnd()</tt>
+is called first to avoid a memory leak.
+<pre><b>
+    /* clean up and return */
+    (void)inflateEnd(&amp;strm);
+    return ret == Z_STREAM_END ? Z_OK : Z_DATA_ERROR;
+}
+</b></pre><!-- -->
+That ends the routines that directly use <em>zlib</em>.  The following routines make this
+a command-line program by running data through the above routines from <tt>stdin</tt> to
+<tt>stdout</tt>, and handling any errors reported by <tt>def()</tt> or <tt>inf()</tt>.
+<p>
+<tt>zerr()</tt> is used to interpret the possible error codes from <tt>def()</tt>
+and <tt>inf()</tt>, as detailed in their comments above, and print out an error message.
+Note that these are only a subset of the possible return values from <tt>deflate()</tt>
+and <tt>inflate()</tt>.
+<pre><b>
+/* report a zlib or i/o error */
+void zerr(int ret)
+{
+    fputs("zpipe: ", stderr);
+    switch (ret) {
+    case Z_ERRNO:
+        if (ferror(stdin))
+            fputs("error reading stdin\n", stderr);
+        if (ferror(stdout))
+            fputs("error writing stdout\n", stderr);
+        break;
+    case Z_STREAM_ERROR:
+        fputs("invalid compression level\n", stderr);
+        break;
+    case Z_DATA_ERROR:
+        fputs("invalid or incomplete deflate data\n", stderr);
+        break;
+    case Z_MEM_ERROR:
+        fputs("out of memory\n", stderr);
+        break;
+    case Z_VERSION_ERROR:
+        fputs("zlib version mismatch!\n", stderr);
+    }
+}
+</b></pre><!-- -->
+Here is the <tt>main()</tt> routine used to test <tt>def()</tt> and <tt>inf()</tt>.  The
+<tt>zpipe</tt> command is simply a compression pipe from <tt>stdin</tt> to <tt>stdout</tt>, if
+no arguments are given, or it is a decompression pipe if <tt>zpipe -d</tt> is used.  If any other
+arguments are provided, no compression or decompression is performed.  Instead a usage
+message is displayed.  Examples are <tt>zpipe < foo.txt > foo.txt.z</tt> to compress, and
+<tt>zpipe -d < foo.txt.z > foo.txt</tt> to decompress.
+<pre><b>
+/* compress or decompress from stdin to stdout */
+int main(int argc, char **argv)
+{
+    int ret;
+
+    /* avoid end-of-line conversions */
+    SET_BINARY_MODE(stdin);
+    SET_BINARY_MODE(stdout);
+
+    /* do compression if no arguments */
+    if (argc == 1) {
+        ret = def(stdin, stdout, Z_DEFAULT_COMPRESSION);
+        if (ret != Z_OK)
+            zerr(ret);
+        return ret;
+    }
+
+    /* do decompression if -d specified */
+    else if (argc == 2 &amp;&amp; strcmp(argv[1], "-d") == 0) {
+        ret = inf(stdin, stdout);
+        if (ret != Z_OK)
+            zerr(ret);
+        return ret;
+    }
+
+    /* otherwise, report usage */
+    else {
+        fputs("zpipe usage: zpipe [-d] &lt; source &gt; dest\n", stderr);
+        return 1;
+    }
+}
+</b></pre>
+<hr>
+<i>Copyright (c) 2004, 2005 by Mark Adler<br>Last modified 11 December 2005</i>
+</body>
+</html>
diff --git a/compat/zlib/examples/zpipe.c b/compat/zlib/examples/zpipe.c
new file mode 100644
index 0000000..83535d1
--- /dev/null
+++ b/compat/zlib/examples/zpipe.c
@@ -0,0 +1,205 @@
+/* zpipe.c: example of proper use of zlib's inflate() and deflate()
+   Not copyrighted -- provided to the public domain
+   Version 1.4  11 December 2005  Mark Adler */
+
+/* Version history:
+   1.0  30 Oct 2004  First version
+   1.1   8 Nov 2004  Add void casting for unused return values
+                     Use switch statement for inflate() return values
+   1.2   9 Nov 2004  Add assertions to document zlib guarantees
+   1.3   6 Apr 2005  Remove incorrect assertion in inf()
+   1.4  11 Dec 2005  Add hack to avoid MSDOS end-of-line conversions
+                     Avoid some compiler warnings for input and output buffers
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+#include "zlib.h"
+
+#if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(__CYGWIN__)
+#  include <fcntl.h>
+#  include <io.h>
+#  define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY)
+#else
+#  define SET_BINARY_MODE(file)
+#endif
+
+#define CHUNK 16384
+
+/* Compress from file source to file dest until EOF on source.
+   def() returns Z_OK on success, Z_MEM_ERROR if memory could not be
+   allocated for processing, Z_STREAM_ERROR if an invalid compression
+   level is supplied, Z_VERSION_ERROR if the version of zlib.h and the
+   version of the library linked do not match, or Z_ERRNO if there is
+   an error reading or writing the files. */
+int def(FILE *source, FILE *dest, int level)
+{
+    int ret, flush;
+    unsigned have;
+    z_stream strm;
+    unsigned char in[CHUNK];
+    unsigned char out[CHUNK];
+
+    /* allocate deflate state */
+    strm.zalloc = Z_NULL;
+    strm.zfree = Z_NULL;
+    strm.opaque = Z_NULL;
+    ret = deflateInit(&strm, level);
+    if (ret != Z_OK)
+        return ret;
+
+    /* compress until end of file */
+    do {
+        strm.avail_in = fread(in, 1, CHUNK, source);
+        if (ferror(source)) {
+            (void)deflateEnd(&strm);
+            return Z_ERRNO;
+        }
+        flush = feof(source) ? Z_FINISH : Z_NO_FLUSH;
+        strm.next_in = in;
+
+        /* run deflate() on input until output buffer not full, finish
+           compression if all of source has been read in */
+        do {
+            strm.avail_out = CHUNK;
+            strm.next_out = out;
+            ret = deflate(&strm, flush);    /* no bad return value */
+            assert(ret != Z_STREAM_ERROR);  /* state not clobbered */
+            have = CHUNK - strm.avail_out;
+            if (fwrite(out, 1, have, dest) != have || ferror(dest)) {
+                (void)deflateEnd(&strm);
+                return Z_ERRNO;
+            }
+        } while (strm.avail_out == 0);
+        assert(strm.avail_in == 0);     /* all input will be used */
+
+        /* done when last data in file processed */
+    } while (flush != Z_FINISH);
+    assert(ret == Z_STREAM_END);        /* stream will be complete */
+
+    /* clean up and return */
+    (void)deflateEnd(&strm);
+    return Z_OK;
+}
+
+/* Decompress from file source to file dest until stream ends or EOF.
+   inf() returns Z_OK on success, Z_MEM_ERROR if memory could not be
+   allocated for processing, Z_DATA_ERROR if the deflate data is
+   invalid or incomplete, Z_VERSION_ERROR if the version of zlib.h and
+   the version of the library linked do not match, or Z_ERRNO if there
+   is an error reading or writing the files. */
+int inf(FILE *source, FILE *dest)
+{
+    int ret;
+    unsigned have;
+    z_stream strm;
+    unsigned char in[CHUNK];
+    unsigned char out[CHUNK];
+
+    /* allocate inflate state */
+    strm.zalloc = Z_NULL;
+    strm.zfree = Z_NULL;
+    strm.opaque = Z_NULL;
+    strm.avail_in = 0;
+    strm.next_in = Z_NULL;
+    ret = inflateInit(&strm);
+    if (ret != Z_OK)
+        return ret;
+
+    /* decompress until deflate stream ends or end of file */
+    do {
+        strm.avail_in = fread(in, 1, CHUNK, source);
+        if (ferror(source)) {
+            (void)inflateEnd(&strm);
+            return Z_ERRNO;
+        }
+        if (strm.avail_in == 0)
+            break;
+        strm.next_in = in;
+
+        /* run inflate() on input until output buffer not full */
+        do {
+            strm.avail_out = CHUNK;
+            strm.next_out = out;
+            ret = inflate(&strm, Z_NO_FLUSH);
+            assert(ret != Z_STREAM_ERROR);  /* state not clobbered */
+            switch (ret) {
+            case Z_NEED_DICT:
+                ret = Z_DATA_ERROR;     /* and fall through */
+            case Z_DATA_ERROR:
+            case Z_MEM_ERROR:
+                (void)inflateEnd(&strm);
+                return ret;
+            }
+            have = CHUNK - strm.avail_out;
+            if (fwrite(out, 1, have, dest) != have || ferror(dest)) {
+                (void)inflateEnd(&strm);
+                return Z_ERRNO;
+            }
+        } while (strm.avail_out == 0);
+
+        /* done when inflate() says it's done */
+    } while (ret != Z_STREAM_END);
+
+    /* clean up and return */
+    (void)inflateEnd(&strm);
+    return ret == Z_STREAM_END ? Z_OK : Z_DATA_ERROR;
+}
+
+/* report a zlib or i/o error */
+void zerr(int ret)
+{
+    fputs("zpipe: ", stderr);
+    switch (ret) {
+    case Z_ERRNO:
+        if (ferror(stdin))
+            fputs("error reading stdin\n", stderr);
+        if (ferror(stdout))
+            fputs("error writing stdout\n", stderr);
+        break;
+    case Z_STREAM_ERROR:
+        fputs("invalid compression level\n", stderr);
+        break;
+    case Z_DATA_ERROR:
+        fputs("invalid or incomplete deflate data\n", stderr);
+        break;
+    case Z_MEM_ERROR:
+        fputs("out of memory\n", stderr);
+        break;
+    case Z_VERSION_ERROR:
+        fputs("zlib version mismatch!\n", stderr);
+    }
+}
+
+/* compress or decompress from stdin to stdout */
+int main(int argc, char **argv)
+{
+    int ret;
+
+    /* avoid end-of-line conversions */
+    SET_BINARY_MODE(stdin);
+    SET_BINARY_MODE(stdout);
+
+    /* do compression if no arguments */
+    if (argc == 1) {
+        ret = def(stdin, stdout, Z_DEFAULT_COMPRESSION);
+        if (ret != Z_OK)
+            zerr(ret);
+        return ret;
+    }
+
+    /* do decompression if -d specified */
+    else if (argc == 2 && strcmp(argv[1], "-d") == 0) {
+        ret = inf(stdin, stdout);
+        if (ret != Z_OK)
+            zerr(ret);
+        return ret;
+    }
+
+    /* otherwise, report usage */
+    else {
+        fputs("zpipe usage: zpipe [-d] < source > dest\n", stderr);
+        return 1;
+    }
+}
diff --git a/compat/zlib/examples/zran.c b/compat/zlib/examples/zran.c
new file mode 100644
index 0000000..278f9ad
--- /dev/null
+++ b/compat/zlib/examples/zran.c
@@ -0,0 +1,409 @@
+/* zran.c -- example of zlib/gzip stream indexing and random access
+ * Copyright (C) 2005, 2012 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+   Version 1.1  29 Sep 2012  Mark Adler */
+
+/* Version History:
+ 1.0  29 May 2005  First version
+ 1.1  29 Sep 2012  Fix memory reallocation error
+ */
+
+/* Illustrate the use of Z_BLOCK, inflatePrime(), and inflateSetDictionary()
+   for random access of a compressed file.  A file containing a zlib or gzip
+   stream is provided on the command line.  The compressed stream is decoded in
+   its entirety, and an index built with access points about every SPAN bytes
+   in the uncompressed output.  The compressed file is left open, and can then
+   be read randomly, having to decompress on the average SPAN/2 uncompressed
+   bytes before getting to the desired block of data.
+
+   An access point can be created at the start of any deflate block, by saving
+   the starting file offset and bit of that block, and the 32K bytes of
+   uncompressed data that precede that block.  Also the uncompressed offset of
+   that block is saved to provide a referece for locating a desired starting
+   point in the uncompressed stream.  build_index() works by decompressing the
+   input zlib or gzip stream a block at a time, and at the end of each block
+   deciding if enough uncompressed data has gone by to justify the creation of
+   a new access point.  If so, that point is saved in a data structure that
+   grows as needed to accommodate the points.
+
+   To use the index, an offset in the uncompressed data is provided, for which
+   the latest accees point at or preceding that offset is located in the index.
+   The input file is positioned to the specified location in the index, and if
+   necessary the first few bits of the compressed data is read from the file.
+   inflate is initialized with those bits and the 32K of uncompressed data, and
+   the decompression then proceeds until the desired offset in the file is
+   reached.  Then the decompression continues to read the desired uncompressed
+   data from the file.
+
+   Another approach would be to generate the index on demand.  In that case,
+   requests for random access reads from the compressed data would try to use
+   the index, but if a read far enough past the end of the index is required,
+   then further index entries would be generated and added.
+
+   There is some fair bit of overhead to starting inflation for the random
+   access, mainly copying the 32K byte dictionary.  So if small pieces of the
+   file are being accessed, it would make sense to implement a cache to hold
+   some lookahead and avoid many calls to extract() for small lengths.
+
+   Another way to build an index would be to use inflateCopy().  That would
+   not be constrained to have access points at block boundaries, but requires
+   more memory per access point, and also cannot be saved to file due to the
+   use of pointers in the state.  The approach here allows for storage of the
+   index in a file.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "zlib.h"
+
+#define local static
+
+#define SPAN 1048576L       /* desired distance between access points */
+#define WINSIZE 32768U      /* sliding window size */
+#define CHUNK 16384         /* file input buffer size */
+
+/* access point entry */
+struct point {
+    off_t out;          /* corresponding offset in uncompressed data */
+    off_t in;           /* offset in input file of first full byte */
+    int bits;           /* number of bits (1-7) from byte at in - 1, or 0 */
+    unsigned char window[WINSIZE];  /* preceding 32K of uncompressed data */
+};
+
+/* access point list */
+struct access {
+    int have;           /* number of list entries filled in */
+    int size;           /* number of list entries allocated */
+    struct point *list; /* allocated list */
+};
+
+/* Deallocate an index built by build_index() */
+local void free_index(struct access *index)
+{
+    if (index != NULL) {
+        free(index->list);
+        free(index);
+    }
+}
+
+/* Add an entry to the access point list.  If out of memory, deallocate the
+   existing list and return NULL. */
+local struct access *addpoint(struct access *index, int bits,
+    off_t in, off_t out, unsigned left, unsigned char *window)
+{
+    struct point *next;
+
+    /* if list is empty, create it (start with eight points) */
+    if (index == NULL) {
+        index = malloc(sizeof(struct access));
+        if (index == NULL) return NULL;
+        index->list = malloc(sizeof(struct point) << 3);
+        if (index->list == NULL) {
+            free(index);
+            return NULL;
+        }
+        index->size = 8;
+        index->have = 0;
+    }
+
+    /* if list is full, make it bigger */
+    else if (index->have == index->size) {
+        index->size <<= 1;
+        next = realloc(index->list, sizeof(struct point) * index->size);
+        if (next == NULL) {
+            free_index(index);
+            return NULL;
+        }
+        index->list = next;
+    }
+
+    /* fill in entry and increment how many we have */
+    next = index->list + index->have;
+    next->bits = bits;
+    next->in = in;
+    next->out = out;
+    if (left)
+        memcpy(next->window, window + WINSIZE - left, left);
+    if (left < WINSIZE)
+        memcpy(next->window + left, window, WINSIZE - left);
+    index->have++;
+
+    /* return list, possibly reallocated */
+    return index;
+}
+
+/* Make one entire pass through the compressed stream and build an index, with
+   access points about every span bytes of uncompressed output -- span is
+   chosen to balance the speed of random access against the memory requirements
+   of the list, about 32K bytes per access point.  Note that data after the end
+   of the first zlib or gzip stream in the file is ignored.  build_index()
+   returns the number of access points on success (>= 1), Z_MEM_ERROR for out
+   of memory, Z_DATA_ERROR for an error in the input file, or Z_ERRNO for a
+   file read error.  On success, *built points to the resulting index. */
+local int build_index(FILE *in, off_t span, struct access **built)
+{
+    int ret;
+    off_t totin, totout;        /* our own total counters to avoid 4GB limit */
+    off_t last;                 /* totout value of last access point */
+    struct access *index;       /* access points being generated */
+    z_stream strm;
+    unsigned char input[CHUNK];
+    unsigned char window[WINSIZE];
+
+    /* initialize inflate */
+    strm.zalloc = Z_NULL;
+    strm.zfree = Z_NULL;
+    strm.opaque = Z_NULL;
+    strm.avail_in = 0;
+    strm.next_in = Z_NULL;
+    ret = inflateInit2(&strm, 47);      /* automatic zlib or gzip decoding */
+    if (ret != Z_OK)
+        return ret;
+
+    /* inflate the input, maintain a sliding window, and build an index -- this
+       also validates the integrity of the compressed data using the check
+       information at the end of the gzip or zlib stream */
+    totin = totout = last = 0;
+    index = NULL;               /* will be allocated by first addpoint() */
+    strm.avail_out = 0;
+    do {
+        /* get some compressed data from input file */
+        strm.avail_in = fread(input, 1, CHUNK, in);
+        if (ferror(in)) {
+            ret = Z_ERRNO;
+            goto build_index_error;
+        }
+        if (strm.avail_in == 0) {
+            ret = Z_DATA_ERROR;
+            goto build_index_error;
+        }
+        strm.next_in = input;
+
+        /* process all of that, or until end of stream */
+        do {
+            /* reset sliding window if necessary */
+            if (strm.avail_out == 0) {
+                strm.avail_out = WINSIZE;
+                strm.next_out = window;
+            }
+
+            /* inflate until out of input, output, or at end of block --
+               update the total input and output counters */
+            totin += strm.avail_in;
+            totout += strm.avail_out;
+            ret = inflate(&strm, Z_BLOCK);      /* return at end of block */
+            totin -= strm.avail_in;
+            totout -= strm.avail_out;
+            if (ret == Z_NEED_DICT)
+                ret = Z_DATA_ERROR;
+            if (ret == Z_MEM_ERROR || ret == Z_DATA_ERROR)
+                goto build_index_error;
+            if (ret == Z_STREAM_END)
+                break;
+
+            /* if at end of block, consider adding an index entry (note that if
+               data_type indicates an end-of-block, then all of the
+               uncompressed data from that block has been delivered, and none
+               of the compressed data after that block has been consumed,
+               except for up to seven bits) -- the totout == 0 provides an
+               entry point after the zlib or gzip header, and assures that the
+               index always has at least one access point; we avoid creating an
+               access point after the last block by checking bit 6 of data_type
+             */
+            if ((strm.data_type & 128) && !(strm.data_type & 64) &&
+                (totout == 0 || totout - last > span)) {
+                index = addpoint(index, strm.data_type & 7, totin,
+                                 totout, strm.avail_out, window);
+                if (index == NULL) {
+                    ret = Z_MEM_ERROR;
+                    goto build_index_error;
+                }
+                last = totout;
+            }
+        } while (strm.avail_in != 0);
+    } while (ret != Z_STREAM_END);
+
+    /* clean up and return index (release unused entries in list) */
+    (void)inflateEnd(&strm);
+    index->list = realloc(index->list, sizeof(struct point) * index->have);
+    index->size = index->have;
+    *built = index;
+    return index->size;
+
+    /* return error */
+  build_index_error:
+    (void)inflateEnd(&strm);
+    if (index != NULL)
+        free_index(index);
+    return ret;
+}
+
+/* Use the index to read len bytes from offset into buf, return bytes read or
+   negative for error (Z_DATA_ERROR or Z_MEM_ERROR).  If data is requested past
+   the end of the uncompressed data, then extract() will return a value less
+   than len, indicating how much as actually read into buf.  This function
+   should not return a data error unless the file was modified since the index
+   was generated.  extract() may also return Z_ERRNO if there is an error on
+   reading or seeking the input file. */
+local int extract(FILE *in, struct access *index, off_t offset,
+                  unsigned char *buf, int len)
+{
+    int ret, skip;
+    z_stream strm;
+    struct point *here;
+    unsigned char input[CHUNK];
+    unsigned char discard[WINSIZE];
+
+    /* proceed only if something reasonable to do */
+    if (len < 0)
+        return 0;
+
+    /* find where in stream to start */
+    here = index->list;
+    ret = index->have;
+    while (--ret && here[1].out <= offset)
+        here++;
+
+    /* initialize file and inflate state to start there */
+    strm.zalloc = Z_NULL;
+    strm.zfree = Z_NULL;
+    strm.opaque = Z_NULL;
+    strm.avail_in = 0;
+    strm.next_in = Z_NULL;
+    ret = inflateInit2(&strm, -15);         /* raw inflate */
+    if (ret != Z_OK)
+        return ret;
+    ret = fseeko(in, here->in - (here->bits ? 1 : 0), SEEK_SET);
+    if (ret == -1)
+        goto extract_ret;
+    if (here->bits) {
+        ret = getc(in);
+        if (ret == -1) {
+            ret = ferror(in) ? Z_ERRNO : Z_DATA_ERROR;
+            goto extract_ret;
+        }
+        (void)inflatePrime(&strm, here->bits, ret >> (8 - here->bits));
+    }
+    (void)inflateSetDictionary(&strm, here->window, WINSIZE);
+
+    /* skip uncompressed bytes until offset reached, then satisfy request */
+    offset -= here->out;
+    strm.avail_in = 0;
+    skip = 1;                               /* while skipping to offset */
+    do {
+        /* define where to put uncompressed data, and how much */
+        if (offset == 0 && skip) {          /* at offset now */
+            strm.avail_out = len;
+            strm.next_out = buf;
+            skip = 0;                       /* only do this once */
+        }
+        if (offset > WINSIZE) {             /* skip WINSIZE bytes */
+            strm.avail_out = WINSIZE;
+            strm.next_out = discard;
+            offset -= WINSIZE;
+        }
+        else if (offset != 0) {             /* last skip */
+            strm.avail_out = (unsigned)offset;
+            strm.next_out = discard;
+            offset = 0;
+        }
+
+        /* uncompress until avail_out filled, or end of stream */
+        do {
+            if (strm.avail_in == 0) {
+                strm.avail_in = fread(input, 1, CHUNK, in);
+                if (ferror(in)) {
+                    ret = Z_ERRNO;
+                    goto extract_ret;
+                }
+                if (strm.avail_in == 0) {
+                    ret = Z_DATA_ERROR;
+                    goto extract_ret;
+                }
+                strm.next_in = input;
+            }
+            ret = inflate(&strm, Z_NO_FLUSH);       /* normal inflate */
+            if (ret == Z_NEED_DICT)
+                ret = Z_DATA_ERROR;
+            if (ret == Z_MEM_ERROR || ret == Z_DATA_ERROR)
+                goto extract_ret;
+            if (ret == Z_STREAM_END)
+                break;
+        } while (strm.avail_out != 0);
+
+        /* if reach end of stream, then don't keep trying to get more */
+        if (ret == Z_STREAM_END)
+            break;
+
+        /* do until offset reached and requested data read, or stream ends */
+    } while (skip);
+
+    /* compute number of uncompressed bytes read after offset */
+    ret = skip ? 0 : len - strm.avail_out;
+
+    /* clean up and return bytes read or error */
+  extract_ret:
+    (void)inflateEnd(&strm);
+    return ret;
+}
+
+/* Demonstrate the use of build_index() and extract() by processing the file
+   provided on the command line, and the extracting 16K from about 2/3rds of
+   the way through the uncompressed output, and writing that to stdout. */
+int main(int argc, char **argv)
+{
+    int len;
+    off_t offset;
+    FILE *in;
+    struct access *index = NULL;
+    unsigned char buf[CHUNK];
+
+    /* open input file */
+    if (argc != 2) {
+        fprintf(stderr, "usage: zran file.gz\n");
+        return 1;
+    }
+    in = fopen(argv[1], "rb");
+    if (in == NULL) {
+        fprintf(stderr, "zran: could not open %s for reading\n", argv[1]);
+        return 1;
+    }
+
+    /* build index */
+    len = build_index(in, SPAN, &index);
+    if (len < 0) {
+        fclose(in);
+        switch (len) {
+        case Z_MEM_ERROR:
+            fprintf(stderr, "zran: out of memory\n");
+            break;
+        case Z_DATA_ERROR:
+            fprintf(stderr, "zran: compressed data error in %s\n", argv[1]);
+            break;
+        case Z_ERRNO:
+            fprintf(stderr, "zran: read error on %s\n", argv[1]);
+            break;
+        default:
+            fprintf(stderr, "zran: error %d while building index\n", len);
+        }
+        return 1;
+    }
+    fprintf(stderr, "zran: built index with %d access points\n", len);
+
+    /* use index by reading some bytes from an arbitrary offset */
+    offset = (index->list[index->have - 1].out << 1) / 3;
+    len = extract(in, index, offset, buf, CHUNK);
+    if (len < 0)
+        fprintf(stderr, "zran: extraction failed: %s error\n",
+                len == Z_MEM_ERROR ? "out of memory" : "input corrupted");
+    else {
+        fwrite(buf, 1, len, stdout);
+        fprintf(stderr, "zran: extracted %d bytes at %llu\n", len, offset);
+    }
+
+    /* clean up and exit */
+    free_index(index);
+    fclose(in);
+    return 0;
+}
diff --git a/compat/zlib/gzclose.c b/compat/zlib/gzclose.c
new file mode 100644
index 0000000..caeb99a
--- /dev/null
+++ b/compat/zlib/gzclose.c
@@ -0,0 +1,25 @@
+/* gzclose.c -- zlib gzclose() function
+ * Copyright (C) 2004, 2010 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+#include "gzguts.h"
+
+/* gzclose() is in a separate file so that it is linked in only if it is used.
+   That way the other gzclose functions can be used instead to avoid linking in
+   unneeded compression or decompression routines. */
+int ZEXPORT gzclose(file)
+    gzFile file;
+{
+#ifndef NO_GZCOMPRESS
+    gz_statep state;
+
+    if (file == NULL)
+        return Z_STREAM_ERROR;
+    state = (gz_statep)file;
+
+    return state->mode == GZ_READ ? gzclose_r(file) : gzclose_w(file);
+#else
+    return gzclose_r(file);
+#endif
+}
diff --git a/compat/zlib/gzguts.h b/compat/zlib/gzguts.h
new file mode 100644
index 0000000..d87659d
--- /dev/null
+++ b/compat/zlib/gzguts.h
@@ -0,0 +1,209 @@
+/* gzguts.h -- zlib internal header definitions for gz* operations
+ * Copyright (C) 2004, 2005, 2010, 2011, 2012, 2013 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+#ifdef _LARGEFILE64_SOURCE
+#  ifndef _LARGEFILE_SOURCE
+#    define _LARGEFILE_SOURCE 1
+#  endif
+#  ifdef _FILE_OFFSET_BITS
+#    undef _FILE_OFFSET_BITS
+#  endif
+#endif
+
+#ifdef HAVE_HIDDEN
+#  define ZLIB_INTERNAL __attribute__((visibility ("hidden")))
+#else
+#  define ZLIB_INTERNAL
+#endif
+
+#include <stdio.h>
+#include "zlib.h"
+#ifdef STDC
+#  include <string.h>
+#  include <stdlib.h>
+#  include <limits.h>
+#endif
+#include <fcntl.h>
+
+#ifdef _WIN32
+#  include <stddef.h>
+#endif
+
+#if defined(__TURBOC__) || defined(_MSC_VER) || defined(_WIN32)
+#  include <io.h>
+#endif
+
+#ifdef WINAPI_FAMILY
+#  define open _open
+#  define read _read
+#  define write _write
+#  define close _close
+#endif
+
+#ifdef NO_DEFLATE       /* for compatibility with old definition */
+#  define NO_GZCOMPRESS
+#endif
+
+#if defined(STDC99) || (defined(__TURBOC__) && __TURBOC__ >= 0x550)
+#  ifndef HAVE_VSNPRINTF
+#    define HAVE_VSNPRINTF
+#  endif
+#endif
+
+#if defined(__CYGWIN__)
+#  ifndef HAVE_VSNPRINTF
+#    define HAVE_VSNPRINTF
+#  endif
+#endif
+
+#if defined(MSDOS) && defined(__BORLANDC__) && (BORLANDC > 0x410)
+#  ifndef HAVE_VSNPRINTF
+#    define HAVE_VSNPRINTF
+#  endif
+#endif
+
+#ifndef HAVE_VSNPRINTF
+#  ifdef MSDOS
+/* vsnprintf may exist on some MS-DOS compilers (DJGPP?),
+   but for now we just assume it doesn't. */
+#    define NO_vsnprintf
+#  endif
+#  ifdef __TURBOC__
+#    define NO_vsnprintf
+#  endif
+#  ifdef WIN32
+/* In Win32, vsnprintf is available as the "non-ANSI" _vsnprintf. */
+#    if !defined(vsnprintf) && !defined(NO_vsnprintf)
+#      if !defined(_MSC_VER) || ( defined(_MSC_VER) && _MSC_VER < 1500 )
+#         define vsnprintf _vsnprintf
+#      endif
+#    endif
+#  endif
+#  ifdef __SASC
+#    define NO_vsnprintf
+#  endif
+#  ifdef VMS
+#    define NO_vsnprintf
+#  endif
+#  ifdef __OS400__
+#    define NO_vsnprintf
+#  endif
+#  ifdef __MVS__
+#    define NO_vsnprintf
+#  endif
+#endif
+
+/* unlike snprintf (which is required in C99, yet still not supported by
+   Microsoft more than a decade later!), _snprintf does not guarantee null
+   termination of the result -- however this is only used in gzlib.c where
+   the result is assured to fit in the space provided */
+#ifdef _MSC_VER
+#  define snprintf _snprintf
+#endif
+
+#ifndef local
+#  define local static
+#endif
+/* compile with -Dlocal if your debugger can't find static symbols */
+
+/* gz* functions always use library allocation functions */
+#ifndef STDC
+  extern voidp  malloc OF((uInt size));
+  extern void   free   OF((voidpf ptr));
+#endif
+
+/* get errno and strerror definition */
+#if defined UNDER_CE
+#  include <windows.h>
+#  define zstrerror() gz_strwinerror((DWORD)GetLastError())
+#else
+#  ifndef NO_STRERROR
+#    include <errno.h>
+#    define zstrerror() strerror(errno)
+#  else
+#    define zstrerror() "stdio error (consult errno)"
+#  endif
+#endif
+
+/* provide prototypes for these when building zlib without LFS */
+#if !defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0
+    ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *));
+    ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int));
+    ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile));
+    ZEXTERN z_off64_t ZEXPORT gzoffset64 OF((gzFile));
+#endif
+
+/* default memLevel */
+#if MAX_MEM_LEVEL >= 8
+#  define DEF_MEM_LEVEL 8
+#else
+#  define DEF_MEM_LEVEL  MAX_MEM_LEVEL
+#endif
+
+/* default i/o buffer size -- double this for output when reading (this and
+   twice this must be able to fit in an unsigned type) */
+#define GZBUFSIZE 8192
+
+/* gzip modes, also provide a little integrity check on the passed structure */
+#define GZ_NONE 0
+#define GZ_READ 7247
+#define GZ_WRITE 31153
+#define GZ_APPEND 1     /* mode set to GZ_WRITE after the file is opened */
+
+/* values for gz_state how */
+#define LOOK 0      /* look for a gzip header */
+#define COPY 1      /* copy input directly */
+#define GZIP 2      /* decompress a gzip stream */
+
+/* internal gzip file state data structure */
+typedef struct {
+        /* exposed contents for gzgetc() macro */
+    struct gzFile_s x;      /* "x" for exposed */
+                            /* x.have: number of bytes available at x.next */
+                            /* x.next: next output data to deliver or write */
+                            /* x.pos: current position in uncompressed data */
+        /* used for both reading and writing */
+    int mode;               /* see gzip modes above */
+    int fd;                 /* file descriptor */
+    char *path;             /* path or fd for error messages */
+    unsigned size;          /* buffer size, zero if not allocated yet */
+    unsigned want;          /* requested buffer size, default is GZBUFSIZE */
+    unsigned char *in;      /* input buffer */
+    unsigned char *out;     /* output buffer (double-sized when reading) */
+    int direct;             /* 0 if processing gzip, 1 if transparent */
+        /* just for reading */
+    int how;                /* 0: get header, 1: copy, 2: decompress */
+    z_off64_t start;        /* where the gzip data started, for rewinding */
+    int eof;                /* true if end of input file reached */
+    int past;               /* true if read requested past end */
+        /* just for writing */
+    int level;              /* compression level */
+    int strategy;           /* compression strategy */
+        /* seek request */
+    z_off64_t skip;         /* amount to skip (already rewound if backwards) */
+    int seek;               /* true if seek request pending */
+        /* error information */
+    int err;                /* error code */
+    char *msg;              /* error message */
+        /* zlib inflate or deflate stream */
+    z_stream strm;          /* stream structure in-place (not a pointer) */
+} gz_state;
+typedef gz_state FAR *gz_statep;
+
+/* shared functions */
+void ZLIB_INTERNAL gz_error OF((gz_statep, int, const char *));
+#if defined UNDER_CE
+char ZLIB_INTERNAL *gz_strwinerror OF((DWORD error));
+#endif
+
+/* GT_OFF(x), where x is an unsigned value, is true if x > maximum z_off64_t
+   value -- needed when comparing unsigned to z_off64_t, which is signed
+   (possible z_off64_t types off_t, off64_t, and long are all signed) */
+#ifdef INT_MAX
+#  define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > INT_MAX)
+#else
+unsigned ZLIB_INTERNAL gz_intmax OF((void));
+#  define GT_OFF(x) (sizeof(int) == sizeof(z_off64_t) && (x) > gz_intmax())
+#endif
diff --git a/compat/zlib/gzlib.c b/compat/zlib/gzlib.c
new file mode 100644
index 0000000..fae202e
--- /dev/null
+++ b/compat/zlib/gzlib.c
@@ -0,0 +1,634 @@
+/* gzlib.c -- zlib functions common to reading and writing gzip files
+ * Copyright (C) 2004, 2010, 2011, 2012, 2013 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+#include "gzguts.h"
+
+#if defined(_WIN32) && !defined(__BORLANDC__)
+#  define LSEEK _lseeki64
+#else
+#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0
+#  define LSEEK lseek64
+#else
+#  define LSEEK lseek
+#endif
+#endif
+
+/* Local functions */
+local void gz_reset OF((gz_statep));
+local gzFile gz_open OF((const void *, int, const char *));
+
+#if defined UNDER_CE
+
+/* Map the Windows error number in ERROR to a locale-dependent error message
+   string and return a pointer to it.  Typically, the values for ERROR come
+   from GetLastError.
+
+   The string pointed to shall not be modified by the application, but may be
+   overwritten by a subsequent call to gz_strwinerror
+
+   The gz_strwinerror function does not change the current setting of
+   GetLastError. */
+char ZLIB_INTERNAL *gz_strwinerror (error)
+     DWORD error;
+{
+    static char buf[1024];
+
+    wchar_t *msgbuf;
+    DWORD lasterr = GetLastError();
+    DWORD chars = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM
+        | FORMAT_MESSAGE_ALLOCATE_BUFFER,
+        NULL,
+        error,
+        0, /* Default language */
+        (LPVOID)&msgbuf,
+        0,
+        NULL);
+    if (chars != 0) {
+        /* If there is an \r\n appended, zap it.  */
+        if (chars >= 2
+            && msgbuf[chars - 2] == '\r' && msgbuf[chars - 1] == '\n') {
+            chars -= 2;
+            msgbuf[chars] = 0;
+        }
+
+        if (chars > sizeof (buf) - 1) {
+            chars = sizeof (buf) - 1;
+            msgbuf[chars] = 0;
+        }
+
+        wcstombs(buf, msgbuf, chars + 1);
+        LocalFree(msgbuf);
+    }
+    else {
+        sprintf(buf, "unknown win32 error (%ld)", error);
+    }
+
+    SetLastError(lasterr);
+    return buf;
+}
+
+#endif /* UNDER_CE */
+
+/* Reset gzip file state */
+local void gz_reset(state)
+    gz_statep state;
+{
+    state->x.have = 0;              /* no output data available */
+    if (state->mode == GZ_READ) {   /* for reading ... */
+        state->eof = 0;             /* not at end of file */
+        state->past = 0;            /* have not read past end yet */
+        state->how = LOOK;          /* look for gzip header */
+    }
+    state->seek = 0;                /* no seek request pending */
+    gz_error(state, Z_OK, NULL);    /* clear error */
+    state->x.pos = 0;               /* no uncompressed data yet */
+    state->strm.avail_in = 0;       /* no input data yet */
+}
+
+/* Open a gzip file either by name or file descriptor. */
+local gzFile gz_open(path, fd, mode)
+    const void *path;
+    int fd;
+    const char *mode;
+{
+    gz_statep state;
+    size_t len;
+    int oflag;
+#ifdef O_CLOEXEC
+    int cloexec = 0;
+#endif
+#ifdef O_EXCL
+    int exclusive = 0;
+#endif
+
+    /* check input */
+    if (path == NULL)
+        return NULL;
+
+    /* allocate gzFile structure to return */
+    state = (gz_statep)malloc(sizeof(gz_state));
+    if (state == NULL)
+        return NULL;
+    state->size = 0;            /* no buffers allocated yet */
+    state->want = GZBUFSIZE;    /* requested buffer size */
+    state->msg = NULL;          /* no error message yet */
+
+    /* interpret mode */
+    state->mode = GZ_NONE;
+    state->level = Z_DEFAULT_COMPRESSION;
+    state->strategy = Z_DEFAULT_STRATEGY;
+    state->direct = 0;
+    while (*mode) {
+        if (*mode >= '0' && *mode <= '9')
+            state->level = *mode - '0';
+        else
+            switch (*mode) {
+            case 'r':
+                state->mode = GZ_READ;
+                break;
+#ifndef NO_GZCOMPRESS
+            case 'w':
+                state->mode = GZ_WRITE;
+                break;
+            case 'a':
+                state->mode = GZ_APPEND;
+                break;
+#endif
+            case '+':       /* can't read and write at the same time */
+                free(state);
+                return NULL;
+            case 'b':       /* ignore -- will request binary anyway */
+                break;
+#ifdef O_CLOEXEC
+            case 'e':
+                cloexec = 1;
+                break;
+#endif
+#ifdef O_EXCL
+            case 'x':
+                exclusive = 1;
+                break;
+#endif
+            case 'f':
+                state->strategy = Z_FILTERED;
+                break;
+            case 'h':
+                state->strategy = Z_HUFFMAN_ONLY;
+                break;
+            case 'R':
+                state->strategy = Z_RLE;
+                break;
+            case 'F':
+                state->strategy = Z_FIXED;
+                break;
+            case 'T':
+                state->direct = 1;
+                break;
+            default:        /* could consider as an error, but just ignore */
+                ;
+            }
+        mode++;
+    }
+
+    /* must provide an "r", "w", or "a" */
+    if (state->mode == GZ_NONE) {
+        free(state);
+        return NULL;
+    }
+
+    /* can't force transparent read */
+    if (state->mode == GZ_READ) {
+        if (state->direct) {
+            free(state);
+            return NULL;
+        }
+        state->direct = 1;      /* for empty file */
+    }
+
+    /* save the path name for error messages */
+#ifdef _WIN32
+    if (fd == -2) {
+        len = wcstombs(NULL, path, 0);
+        if (len == (size_t)-1)
+            len = 0;
+    }
+    else
+#endif
+        len = strlen((const char *)path);
+    state->path = (char *)malloc(len + 1);
+    if (state->path == NULL) {
+        free(state);
+        return NULL;
+    }
+#ifdef _WIN32
+    if (fd == -2)
+        if (len)
+            wcstombs(state->path, path, len + 1);
+        else
+            *(state->path) = 0;
+    else
+#endif
+#if !defined(NO_snprintf) && !defined(NO_vsnprintf)
+        snprintf(state->path, len + 1, "%s", (const char *)path);
+#else
+        strcpy(state->path, path);
+#endif
+
+    /* compute the flags for open() */
+    oflag =
+#ifdef O_LARGEFILE
+        O_LARGEFILE |
+#endif
+#ifdef O_BINARY
+        O_BINARY |
+#endif
+#ifdef O_CLOEXEC
+        (cloexec ? O_CLOEXEC : 0) |
+#endif
+        (state->mode == GZ_READ ?
+         O_RDONLY :
+         (O_WRONLY | O_CREAT |
+#ifdef O_EXCL
+          (exclusive ? O_EXCL : 0) |
+#endif
+          (state->mode == GZ_WRITE ?
+           O_TRUNC :
+           O_APPEND)));
+
+    /* open the file with the appropriate flags (or just use fd) */
+    state->fd = fd > -1 ? fd : (
+#ifdef _WIN32
+        fd == -2 ? _wopen(path, oflag, 0666) :
+#endif
+        open((const char *)path, oflag, 0666));
+    if (state->fd == -1) {
+        free(state->path);
+        free(state);
+        return NULL;
+    }
+    if (state->mode == GZ_APPEND)
+        state->mode = GZ_WRITE;         /* simplify later checks */
+
+    /* save the current position for rewinding (only if reading) */
+    if (state->mode == GZ_READ) {
+        state->start = LSEEK(state->fd, 0, SEEK_CUR);
+        if (state->start == -1) state->start = 0;
+    }
+
+    /* initialize stream */
+    gz_reset(state);
+
+    /* return stream */
+    return (gzFile)state;
+}
+
+/* -- see zlib.h -- */
+gzFile ZEXPORT gzopen(path, mode)
+    const char *path;
+    const char *mode;
+{
+    return gz_open(path, -1, mode);
+}
+
+/* -- see zlib.h -- */
+gzFile ZEXPORT gzopen64(path, mode)
+    const char *path;
+    const char *mode;
+{
+    return gz_open(path, -1, mode);
+}
+
+/* -- see zlib.h -- */
+gzFile ZEXPORT gzdopen(fd, mode)
+    int fd;
+    const char *mode;
+{
+    char *path;         /* identifier for error messages */
+    gzFile gz;
+
+    if (fd == -1 || (path = (char *)malloc(7 + 3 * sizeof(int))) == NULL)
+        return NULL;
+#if !defined(NO_snprintf) && !defined(NO_vsnprintf)
+    snprintf(path, 7 + 3 * sizeof(int), "<fd:%d>", fd); /* for debugging */
+#else
+    sprintf(path, "<fd:%d>", fd);   /* for debugging */
+#endif
+    gz = gz_open(path, fd, mode);
+    free(path);
+    return gz;
+}
+
+/* -- see zlib.h -- */
+#ifdef _WIN32
+gzFile ZEXPORT gzopen_w(path, mode)
+    const wchar_t *path;
+    const char *mode;
+{
+    return gz_open(path, -2, mode);
+}
+#endif
+
+/* -- see zlib.h -- */
+int ZEXPORT gzbuffer(file, size)
+    gzFile file;
+    unsigned size;
+{
+    gz_statep state;
+
+    /* get internal structure and check integrity */
+    if (file == NULL)
+        return -1;
+    state = (gz_statep)file;
+    if (state->mode != GZ_READ && state->mode != GZ_WRITE)
+        return -1;
+
+    /* make sure we haven't already allocated memory */
+    if (state->size != 0)
+        return -1;
+
+    /* check and set requested size */
+    if (size < 2)
+        size = 2;               /* need two bytes to check magic header */
+    state->want = size;
+    return 0;
+}
+
+/* -- see zlib.h -- */
+int ZEXPORT gzrewind(file)
+    gzFile file;
+{
+    gz_statep state;
+
+    /* get internal structure */
+    if (file == NULL)
+        return -1;
+    state = (gz_statep)file;
+
+    /* check that we're reading and that there's no error */
+    if (state->mode != GZ_READ ||
+            (state->err != Z_OK && state->err != Z_BUF_ERROR))
+        return -1;
+
+    /* back up and start over */
+    if (LSEEK(state->fd, state->start, SEEK_SET) == -1)
+        return -1;
+    gz_reset(state);
+    return 0;
+}
+
+/* -- see zlib.h -- */
+z_off64_t ZEXPORT gzseek64(file, offset, whence)
+    gzFile file;
+    z_off64_t offset;
+    int whence;
+{
+    unsigned n;
+    z_off64_t ret;
+    gz_statep state;
+
+    /* get internal structure and check integrity */
+    if (file == NULL)
+        return -1;
+    state = (gz_statep)file;
+    if (state->mode != GZ_READ && state->mode != GZ_WRITE)
+        return -1;
+
+    /* check that there's no error */
+    if (state->err != Z_OK && state->err != Z_BUF_ERROR)
+        return -1;
+
+    /* can only seek from start or relative to current position */
+    if (whence != SEEK_SET && whence != SEEK_CUR)
+        return -1;
+
+    /* normalize offset to a SEEK_CUR specification */
+    if (whence == SEEK_SET)
+        offset -= state->x.pos;
+    else if (state->seek)
+        offset += state->skip;
+    state->seek = 0;
+
+    /* if within raw area while reading, just go there */
+    if (state->mode == GZ_READ && state->how == COPY &&
+            state->x.pos + offset >= 0) {
+        ret = LSEEK(state->fd, offset - state->x.have, SEEK_CUR);
+        if (ret == -1)
+            return -1;
+        state->x.have = 0;
+        state->eof = 0;
+        state->past = 0;
+        state->seek = 0;
+        gz_error(state, Z_OK, NULL);
+        state->strm.avail_in = 0;
+        state->x.pos += offset;
+        return state->x.pos;
+    }
+
+    /* calculate skip amount, rewinding if needed for back seek when reading */
+    if (offset < 0) {
+        if (state->mode != GZ_READ)         /* writing -- can't go backwards */
+            return -1;
+        offset += state->x.pos;
+        if (offset < 0)                     /* before start of file! */
+            return -1;
+        if (gzrewind(file) == -1)           /* rewind, then skip to offset */
+            return -1;
+    }
+
+    /* if reading, skip what's in output buffer (one less gzgetc() check) */
+    if (state->mode == GZ_READ) {
+        n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > offset ?
+            (unsigned)offset : state->x.have;
+        state->x.have -= n;
+        state->x.next += n;
+        state->x.pos += n;
+        offset -= n;
+    }
+
+    /* request skip (if not zero) */
+    if (offset) {
+        state->seek = 1;
+        state->skip = offset;
+    }
+    return state->x.pos + offset;
+}
+
+/* -- see zlib.h -- */
+z_off_t ZEXPORT gzseek(file, offset, whence)
+    gzFile file;
+    z_off_t offset;
+    int whence;
+{
+    z_off64_t ret;
+
+    ret = gzseek64(file, (z_off64_t)offset, whence);
+    return ret == (z_off_t)ret ? (z_off_t)ret : -1;
+}
+
+/* -- see zlib.h -- */
+z_off64_t ZEXPORT gztell64(file)
+    gzFile file;
+{
+    gz_statep state;
+
+    /* get internal structure and check integrity */
+    if (file == NULL)
+        return -1;
+    state = (gz_statep)file;
+    if (state->mode != GZ_READ && state->mode != GZ_WRITE)
+        return -1;
+
+    /* return position */
+    return state->x.pos + (state->seek ? state->skip : 0);
+}
+
+/* -- see zlib.h -- */
+z_off_t ZEXPORT gztell(file)
+    gzFile file;
+{
+    z_off64_t ret;
+
+    ret = gztell64(file);
+    return ret == (z_off_t)ret ? (z_off_t)ret : -1;
+}
+
+/* -- see zlib.h -- */
+z_off64_t ZEXPORT gzoffset64(file)
+    gzFile file;
+{
+    z_off64_t offset;
+    gz_statep state;
+
+    /* get internal structure and check integrity */
+    if (file == NULL)
+        return -1;
+    state = (gz_statep)file;
+    if (state->mode != GZ_READ && state->mode != GZ_WRITE)
+        return -1;
+
+    /* compute and return effective offset in file */
+    offset = LSEEK(state->fd, 0, SEEK_CUR);
+    if (offset == -1)
+        return -1;
+    if (state->mode == GZ_READ)             /* reading */
+        offset -= state->strm.avail_in;     /* don't count buffered input */
+    return offset;
+}
+
+/* -- see zlib.h -- */
+z_off_t ZEXPORT gzoffset(file)
+    gzFile file;
+{
+    z_off64_t ret;
+
+    ret = gzoffset64(file);
+    return ret == (z_off_t)ret ? (z_off_t)ret : -1;
+}
+
+/* -- see zlib.h -- */
+int ZEXPORT gzeof(file)
+    gzFile file;
+{
+    gz_statep state;
+
+    /* get internal structure and check integrity */
+    if (file == NULL)
+        return 0;
+    state = (gz_statep)file;
+    if (state->mode != GZ_READ && state->mode != GZ_WRITE)
+        return 0;
+
+    /* return end-of-file state */
+    return state->mode == GZ_READ ? state->past : 0;
+}
+
+/* -- see zlib.h -- */
+const char * ZEXPORT gzerror(file, errnum)
+    gzFile file;
+    int *errnum;
+{
+    gz_statep state;
+
+    /* get internal structure and check integrity */
+    if (file == NULL)
+        return NULL;
+    state = (gz_statep)file;
+    if (state->mode != GZ_READ && state->mode != GZ_WRITE)
+        return NULL;
+
+    /* return error information */
+    if (errnum != NULL)
+        *errnum = state->err;
+    return state->err == Z_MEM_ERROR ? "out of memory" :
+                                       (state->msg == NULL ? "" : state->msg);
+}
+
+/* -- see zlib.h -- */
+void ZEXPORT gzclearerr(file)
+    gzFile file;
+{
+    gz_statep state;
+
+    /* get internal structure and check integrity */
+    if (file == NULL)
+        return;
+    state = (gz_statep)file;
+    if (state->mode != GZ_READ && state->mode != GZ_WRITE)
+        return;
+
+    /* clear error and end-of-file */
+    if (state->mode == GZ_READ) {
+        state->eof = 0;
+        state->past = 0;
+    }
+    gz_error(state, Z_OK, NULL);
+}
+
+/* Create an error message in allocated memory and set state->err and
+   state->msg accordingly.  Free any previous error message already there.  Do
+   not try to free or allocate space if the error is Z_MEM_ERROR (out of
+   memory).  Simply save the error message as a static string.  If there is an
+   allocation failure constructing the error message, then convert the error to
+   out of memory. */
+void ZLIB_INTERNAL gz_error(state, err, msg)
+    gz_statep state;
+    int err;
+    const char *msg;
+{
+    /* free previously allocated message and clear */
+    if (state->msg != NULL) {
+        if (state->err != Z_MEM_ERROR)
+            free(state->msg);
+        state->msg = NULL;
+    }
+
+    /* if fatal, set state->x.have to 0 so that the gzgetc() macro fails */
+    if (err != Z_OK && err != Z_BUF_ERROR)
+        state->x.have = 0;
+
+    /* set error code, and if no message, then done */
+    state->err = err;
+    if (msg == NULL)
+        return;
+
+    /* for an out of memory error, return literal string when requested */
+    if (err == Z_MEM_ERROR)
+        return;
+
+    /* construct error message with path */
+    if ((state->msg = (char *)malloc(strlen(state->path) + strlen(msg) + 3)) ==
+            NULL) {
+        state->err = Z_MEM_ERROR;
+        return;
+    }
+#if !defined(NO_snprintf) && !defined(NO_vsnprintf)
+    snprintf(state->msg, strlen(state->path) + strlen(msg) + 3,
+             "%s%s%s", state->path, ": ", msg);
+#else
+    strcpy(state->msg, state->path);
+    strcat(state->msg, ": ");
+    strcat(state->msg, msg);
+#endif
+    return;
+}
+
+#ifndef INT_MAX
+/* portably return maximum value for an int (when limits.h presumed not
+   available) -- we need to do this to cover cases where 2's complement not
+   used, since C standard permits 1's complement and sign-bit representations,
+   otherwise we could just use ((unsigned)-1) >> 1 */
+unsigned ZLIB_INTERNAL gz_intmax()
+{
+    unsigned p, q;
+
+    p = 1;
+    do {
+        q = p;
+        p <<= 1;
+        p++;
+    } while (p > q);
+    return q >> 1;
+}
+#endif
diff --git a/compat/zlib/gzread.c b/compat/zlib/gzread.c
new file mode 100644
index 0000000..bf4538e
--- /dev/null
+++ b/compat/zlib/gzread.c
@@ -0,0 +1,594 @@
+/* gzread.c -- zlib functions for reading gzip files
+ * Copyright (C) 2004, 2005, 2010, 2011, 2012, 2013 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+#include "gzguts.h"
+
+/* Local functions */
+local int gz_load OF((gz_statep, unsigned char *, unsigned, unsigned *));
+local int gz_avail OF((gz_statep));
+local int gz_look OF((gz_statep));
+local int gz_decomp OF((gz_statep));
+local int gz_fetch OF((gz_statep));
+local int gz_skip OF((gz_statep, z_off64_t));
+
+/* Use read() to load a buffer -- return -1 on error, otherwise 0.  Read from
+   state->fd, and update state->eof, state->err, and state->msg as appropriate.
+   This function needs to loop on read(), since read() is not guaranteed to
+   read the number of bytes requested, depending on the type of descriptor. */
+local int gz_load(state, buf, len, have)
+    gz_statep state;
+    unsigned char *buf;
+    unsigned len;
+    unsigned *have;
+{
+    int ret;
+
+    *have = 0;
+    do {
+        ret = read(state->fd, buf + *have, len - *have);
+        if (ret <= 0)
+            break;
+        *have += ret;
+    } while (*have < len);
+    if (ret < 0) {
+        gz_error(state, Z_ERRNO, zstrerror());
+        return -1;
+    }
+    if (ret == 0)
+        state->eof = 1;
+    return 0;
+}
+
+/* Load up input buffer and set eof flag if last data loaded -- return -1 on
+   error, 0 otherwise.  Note that the eof flag is set when the end of the input
+   file is reached, even though there may be unused data in the buffer.  Once
+   that data has been used, no more attempts will be made to read the file.
+   If strm->avail_in != 0, then the current data is moved to the beginning of
+   the input buffer, and then the remainder of the buffer is loaded with the
+   available data from the input file. */
+local int gz_avail(state)
+    gz_statep state;
+{
+    unsigned got;
+    z_streamp strm = &(state->strm);
+
+    if (state->err != Z_OK && state->err != Z_BUF_ERROR)
+        return -1;
+    if (state->eof == 0) {
+        if (strm->avail_in) {       /* copy what's there to the start */
+            unsigned char *p = state->in;
+            unsigned const char *q = strm->next_in;
+            unsigned n = strm->avail_in;
+            do {
+                *p++ = *q++;
+            } while (--n);
+        }
+        if (gz_load(state, state->in + strm->avail_in,
+                    state->size - strm->avail_in, &got) == -1)
+            return -1;
+        strm->avail_in += got;
+        strm->next_in = state->in;
+    }
+    return 0;
+}
+
+/* Look for gzip header, set up for inflate or copy.  state->x.have must be 0.
+   If this is the first time in, allocate required memory.  state->how will be
+   left unchanged if there is no more input data available, will be set to COPY
+   if there is no gzip header and direct copying will be performed, or it will
+   be set to GZIP for decompression.  If direct copying, then leftover input
+   data from the input buffer will be copied to the output buffer.  In that
+   case, all further file reads will be directly to either the output buffer or
+   a user buffer.  If decompressing, the inflate state will be initialized.
+   gz_look() will return 0 on success or -1 on failure. */
+local int gz_look(state)
+    gz_statep state;
+{
+    z_streamp strm = &(state->strm);
+
+    /* allocate read buffers and inflate memory */
+    if (state->size == 0) {
+        /* allocate buffers */
+        state->in = (unsigned char *)malloc(state->want);
+        state->out = (unsigned char *)malloc(state->want << 1);
+        if (state->in == NULL || state->out == NULL) {
+            if (state->out != NULL)
+                free(state->out);
+            if (state->in != NULL)
+                free(state->in);
+            gz_error(state, Z_MEM_ERROR, "out of memory");
+            return -1;
+        }
+        state->size = state->want;
+
+        /* allocate inflate memory */
+        state->strm.zalloc = Z_NULL;
+        state->strm.zfree = Z_NULL;
+        state->strm.opaque = Z_NULL;
+        state->strm.avail_in = 0;
+        state->strm.next_in = Z_NULL;
+        if (inflateInit2(&(state->strm), 15 + 16) != Z_OK) {    /* gunzip */
+            free(state->out);
+            free(state->in);
+            state->size = 0;
+            gz_error(state, Z_MEM_ERROR, "out of memory");
+            return -1;
+        }
+    }
+
+    /* get at least the magic bytes in the input buffer */
+    if (strm->avail_in < 2) {
+        if (gz_avail(state) == -1)
+            return -1;
+        if (strm->avail_in == 0)
+            return 0;
+    }
+
+    /* look for gzip magic bytes -- if there, do gzip decoding (note: there is
+       a logical dilemma here when considering the case of a partially written
+       gzip file, to wit, if a single 31 byte is written, then we cannot tell
+       whether this is a single-byte file, or just a partially written gzip
+       file -- for here we assume that if a gzip file is being written, then
+       the header will be written in a single operation, so that reading a
+       single byte is sufficient indication that it is not a gzip file) */
+    if (strm->avail_in > 1 &&
+            strm->next_in[0] == 31 && strm->next_in[1] == 139) {
+        inflateReset(strm);
+        state->how = GZIP;
+        state->direct = 0;
+        return 0;
+    }
+
+    /* no gzip header -- if we were decoding gzip before, then this is trailing
+       garbage.  Ignore the trailing garbage and finish. */
+    if (state->direct == 0) {
+        strm->avail_in = 0;
+        state->eof = 1;
+        state->x.have = 0;
+        return 0;
+    }
+
+    /* doing raw i/o, copy any leftover input to output -- this assumes that
+       the output buffer is larger than the input buffer, which also assures
+       space for gzungetc() */
+    state->x.next = state->out;
+    if (strm->avail_in) {
+        memcpy(state->x.next, strm->next_in, strm->avail_in);
+        state->x.have = strm->avail_in;
+        strm->avail_in = 0;
+    }
+    state->how = COPY;
+    state->direct = 1;
+    return 0;
+}
+
+/* Decompress from input to the provided next_out and avail_out in the state.
+   On return, state->x.have and state->x.next point to the just decompressed
+   data.  If the gzip stream completes, state->how is reset to LOOK to look for
+   the next gzip stream or raw data, once state->x.have is depleted.  Returns 0
+   on success, -1 on failure. */
+local int gz_decomp(state)
+    gz_statep state;
+{
+    int ret = Z_OK;
+    unsigned had;
+    z_streamp strm = &(state->strm);
+
+    /* fill output buffer up to end of deflate stream */
+    had = strm->avail_out;
+    do {
+        /* get more input for inflate() */
+        if (strm->avail_in == 0 && gz_avail(state) == -1)
+            return -1;
+        if (strm->avail_in == 0) {
+            gz_error(state, Z_BUF_ERROR, "unexpected end of file");
+            break;
+        }
+
+        /* decompress and handle errors */
+        ret = inflate(strm, Z_NO_FLUSH);
+        if (ret == Z_STREAM_ERROR || ret == Z_NEED_DICT) {
+            gz_error(state, Z_STREAM_ERROR,
+                     "internal error: inflate stream corrupt");
+            return -1;
+        }
+        if (ret == Z_MEM_ERROR) {
+            gz_error(state, Z_MEM_ERROR, "out of memory");
+            return -1;
+        }
+        if (ret == Z_DATA_ERROR) {              /* deflate stream invalid */
+            gz_error(state, Z_DATA_ERROR,
+                     strm->msg == NULL ? "compressed data error" : strm->msg);
+            return -1;
+        }
+    } while (strm->avail_out && ret != Z_STREAM_END);
+
+    /* update available output */
+    state->x.have = had - strm->avail_out;
+    state->x.next = strm->next_out - state->x.have;
+
+    /* if the gzip stream completed successfully, look for another */
+    if (ret == Z_STREAM_END)
+        state->how = LOOK;
+
+    /* good decompression */
+    return 0;
+}
+
+/* Fetch data and put it in the output buffer.  Assumes state->x.have is 0.
+   Data is either copied from the input file or decompressed from the input
+   file depending on state->how.  If state->how is LOOK, then a gzip header is
+   looked for to determine whether to copy or decompress.  Returns -1 on error,
+   otherwise 0.  gz_fetch() will leave state->how as COPY or GZIP unless the
+   end of the input file has been reached and all data has been processed.  */
+local int gz_fetch(state)
+    gz_statep state;
+{
+    z_streamp strm = &(state->strm);
+
+    do {
+        switch(state->how) {
+        case LOOK:      /* -> LOOK, COPY (only if never GZIP), or GZIP */
+            if (gz_look(state) == -1)
+                return -1;
+            if (state->how == LOOK)
+                return 0;
+            break;
+        case COPY:      /* -> COPY */
+            if (gz_load(state, state->out, state->size << 1, &(state->x.have))
+                    == -1)
+                return -1;
+            state->x.next = state->out;
+            return 0;
+        case GZIP:      /* -> GZIP or LOOK (if end of gzip stream) */
+            strm->avail_out = state->size << 1;
+            strm->next_out = state->out;
+            if (gz_decomp(state) == -1)
+                return -1;
+        }
+    } while (state->x.have == 0 && (!state->eof || strm->avail_in));
+    return 0;
+}
+
+/* Skip len uncompressed bytes of output.  Return -1 on error, 0 on success. */
+local int gz_skip(state, len)
+    gz_statep state;
+    z_off64_t len;
+{
+    unsigned n;
+
+    /* skip over len bytes or reach end-of-file, whichever comes first */
+    while (len)
+        /* skip over whatever is in output buffer */
+        if (state->x.have) {
+            n = GT_OFF(state->x.have) || (z_off64_t)state->x.have > len ?
+                (unsigned)len : state->x.have;
+            state->x.have -= n;
+            state->x.next += n;
+            state->x.pos += n;
+            len -= n;
+        }
+
+        /* output buffer empty -- return if we're at the end of the input */
+        else if (state->eof && state->strm.avail_in == 0)
+            break;
+
+        /* need more data to skip -- load up output buffer */
+        else {
+            /* get more output, looking for header if required */
+            if (gz_fetch(state) == -1)
+                return -1;
+        }
+    return 0;
+}
+
+/* -- see zlib.h -- */
+int ZEXPORT gzread(file, buf, len)
+    gzFile file;
+    voidp buf;
+    unsigned len;
+{
+    unsigned got, n;
+    gz_statep state;
+    z_streamp strm;
+
+    /* get internal structure */
+    if (file == NULL)
+        return -1;
+    state = (gz_statep)file;
+    strm = &(state->strm);
+
+    /* check that we're reading and that there's no (serious) error */
+    if (state->mode != GZ_READ ||
+            (state->err != Z_OK && state->err != Z_BUF_ERROR))
+        return -1;
+
+    /* since an int is returned, make sure len fits in one, otherwise return
+       with an error (this avoids the flaw in the interface) */
+    if ((int)len < 0) {
+        gz_error(state, Z_DATA_ERROR, "requested length does not fit in int");
+        return -1;
+    }
+
+    /* if len is zero, avoid unnecessary operations */
+    if (len == 0)
+        return 0;
+
+    /* process a skip request */
+    if (state->seek) {
+        state->seek = 0;
+        if (gz_skip(state, state->skip) == -1)
+            return -1;
+    }
+
+    /* get len bytes to buf, or less than len if at the end */
+    got = 0;
+    do {
+        /* first just try copying data from the output buffer */
+        if (state->x.have) {
+            n = state->x.have > len ? len : state->x.have;
+            memcpy(buf, state->x.next, n);
+            state->x.next += n;
+            state->x.have -= n;
+        }
+
+        /* output buffer empty -- return if we're at the end of the input */
+        else if (state->eof && strm->avail_in == 0) {
+            state->past = 1;        /* tried to read past end */
+            break;
+        }
+
+        /* need output data -- for small len or new stream load up our output
+           buffer */
+        else if (state->how == LOOK || len < (state->size << 1)) {
+            /* get more output, looking for header if required */
+            if (gz_fetch(state) == -1)
+                return -1;
+            continue;       /* no progress yet -- go back to copy above */
+            /* the copy above assures that we will leave with space in the
+               output buffer, allowing at least one gzungetc() to succeed */
+        }
+
+        /* large len -- read directly into user buffer */
+        else if (state->how == COPY) {      /* read directly */
+            if (gz_load(state, (unsigned char *)buf, len, &n) == -1)
+                return -1;
+        }
+
+        /* large len -- decompress directly into user buffer */
+        else {  /* state->how == GZIP */
+            strm->avail_out = len;
+            strm->next_out = (unsigned char *)buf;
+            if (gz_decomp(state) == -1)
+                return -1;
+            n = state->x.have;
+            state->x.have = 0;
+        }
+
+        /* update progress */
+        len -= n;
+        buf = (char *)buf + n;
+        got += n;
+        state->x.pos += n;
+    } while (len);
+
+    /* return number of bytes read into user buffer (will fit in int) */
+    return (int)got;
+}
+
+/* -- see zlib.h -- */
+#ifdef Z_PREFIX_SET
+#  undef z_gzgetc
+#else
+#  undef gzgetc
+#endif
+int ZEXPORT gzgetc(file)
+    gzFile file;
+{
+    int ret;
+    unsigned char buf[1];
+    gz_statep state;
+
+    /* get internal structure */
+    if (file == NULL)
+        return -1;
+    state = (gz_statep)file;
+
+    /* check that we're reading and that there's no (serious) error */
+    if (state->mode != GZ_READ ||
+        (state->err != Z_OK && state->err != Z_BUF_ERROR))
+        return -1;
+
+    /* try output buffer (no need to check for skip request) */
+    if (state->x.have) {
+        state->x.have--;
+        state->x.pos++;
+        return *(state->x.next)++;
+    }
+
+    /* nothing there -- try gzread() */
+    ret = gzread(file, buf, 1);
+    return ret < 1 ? -1 : buf[0];
+}
+
+int ZEXPORT gzgetc_(file)
+gzFile file;
+{
+    return gzgetc(file);
+}
+
+/* -- see zlib.h -- */
+int ZEXPORT gzungetc(c, file)
+    int c;
+    gzFile file;
+{
+    gz_statep state;
+
+    /* get internal structure */
+    if (file == NULL)
+        return -1;
+    state = (gz_statep)file;
+
+    /* check that we're reading and that there's no (serious) error */
+    if (state->mode != GZ_READ ||
+        (state->err != Z_OK && state->err != Z_BUF_ERROR))
+        return -1;
+
+    /* process a skip request */
+    if (state->seek) {
+        state->seek = 0;
+        if (gz_skip(state, state->skip) == -1)
+            return -1;
+    }
+
+    /* can't push EOF */
+    if (c < 0)
+        return -1;
+
+    /* if output buffer empty, put byte at end (allows more pushing) */
+    if (state->x.have == 0) {
+        state->x.have = 1;
+        state->x.next = state->out + (state->size << 1) - 1;
+        state->x.next[0] = c;
+        state->x.pos--;
+        state->past = 0;
+        return c;
+    }
+
+    /* if no room, give up (must have already done a gzungetc()) */
+    if (state->x.have == (state->size << 1)) {
+        gz_error(state, Z_DATA_ERROR, "out of room to push characters");
+        return -1;
+    }
+
+    /* slide output data if needed and insert byte before existing data */
+    if (state->x.next == state->out) {
+        unsigned char *src = state->out + state->x.have;
+        unsigned char *dest = state->out + (state->size << 1);
+        while (src > state->out)
+            *--dest = *--src;
+        state->x.next = dest;
+    }
+    state->x.have++;
+    state->x.next--;
+    state->x.next[0] = c;
+    state->x.pos--;
+    state->past = 0;
+    return c;
+}
+
+/* -- see zlib.h -- */
+char * ZEXPORT gzgets(file, buf, len)
+    gzFile file;
+    char *buf;
+    int len;
+{
+    unsigned left, n;
+    char *str;
+    unsigned char *eol;
+    gz_statep state;
+
+    /* check parameters and get internal structure */
+    if (file == NULL || buf == NULL || len < 1)
+        return NULL;
+    state = (gz_statep)file;
+
+    /* check that we're reading and that there's no (serious) error */
+    if (state->mode != GZ_READ ||
+        (state->err != Z_OK && state->err != Z_BUF_ERROR))
+        return NULL;
+
+    /* process a skip request */
+    if (state->seek) {
+        state->seek = 0;
+        if (gz_skip(state, state->skip) == -1)
+            return NULL;
+    }
+
+    /* copy output bytes up to new line or len - 1, whichever comes first --
+       append a terminating zero to the string (we don't check for a zero in
+       the contents, let the user worry about that) */
+    str = buf;
+    left = (unsigned)len - 1;
+    if (left) do {
+        /* assure that something is in the output buffer */
+        if (state->x.have == 0 && gz_fetch(state) == -1)
+            return NULL;                /* error */
+        if (state->x.have == 0) {       /* end of file */
+            state->past = 1;            /* read past end */
+            break;                      /* return what we have */
+        }
+
+        /* look for end-of-line in current output buffer */
+        n = state->x.have > left ? left : state->x.have;
+        eol = (unsigned char *)memchr(state->x.next, '\n', n);
+        if (eol != NULL)
+            n = (unsigned)(eol - state->x.next) + 1;
+
+        /* copy through end-of-line, or remainder if not found */
+        memcpy(buf, state->x.next, n);
+        state->x.have -= n;
+        state->x.next += n;
+        state->x.pos += n;
+        left -= n;
+        buf += n;
+    } while (left && eol == NULL);
+
+    /* return terminated string, or if nothing, end of file */
+    if (buf == str)
+        return NULL;
+    buf[0] = 0;
+    return str;
+}
+
+/* -- see zlib.h -- */
+int ZEXPORT gzdirect(file)
+    gzFile file;
+{
+    gz_statep state;
+
+    /* get internal structure */
+    if (file == NULL)
+        return 0;
+    state = (gz_statep)file;
+
+    /* if the state is not known, but we can find out, then do so (this is
+       mainly for right after a gzopen() or gzdopen()) */
+    if (state->mode == GZ_READ && state->how == LOOK && state->x.have == 0)
+        (void)gz_look(state);
+
+    /* return 1 if transparent, 0 if processing a gzip stream */
+    return state->direct;
+}
+
+/* -- see zlib.h -- */
+int ZEXPORT gzclose_r(file)
+    gzFile file;
+{
+    int ret, err;
+    gz_statep state;
+
+    /* get internal structure */
+    if (file == NULL)
+        return Z_STREAM_ERROR;
+    state = (gz_statep)file;
+
+    /* check that we're reading */
+    if (state->mode != GZ_READ)
+        return Z_STREAM_ERROR;
+
+    /* free memory and close file */
+    if (state->size) {
+        inflateEnd(&(state->strm));
+        free(state->out);
+        free(state->in);
+    }
+    err = state->err == Z_BUF_ERROR ? Z_BUF_ERROR : Z_OK;
+    gz_error(state, Z_OK, NULL);
+    free(state->path);
+    ret = close(state->fd);
+    free(state);
+    return ret ? Z_ERRNO : err;
+}
diff --git a/compat/zlib/gzwrite.c b/compat/zlib/gzwrite.c
new file mode 100644
index 0000000..aa767fb
--- /dev/null
+++ b/compat/zlib/gzwrite.c
@@ -0,0 +1,577 @@
+/* gzwrite.c -- zlib functions for writing gzip files
+ * Copyright (C) 2004, 2005, 2010, 2011, 2012, 2013 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+#include "gzguts.h"
+
+/* Local functions */
+local int gz_init OF((gz_statep));
+local int gz_comp OF((gz_statep, int));
+local int gz_zero OF((gz_statep, z_off64_t));
+
+/* Initialize state for writing a gzip file.  Mark initialization by setting
+   state->size to non-zero.  Return -1 on failure or 0 on success. */
+local int gz_init(state)
+    gz_statep state;
+{
+    int ret;
+    z_streamp strm = &(state->strm);
+
+    /* allocate input buffer */
+    state->in = (unsigned char *)malloc(state->want);
+    if (state->in == NULL) {
+        gz_error(state, Z_MEM_ERROR, "out of memory");
+        return -1;
+    }
+
+    /* only need output buffer and deflate state if compressing */
+    if (!state->direct) {
+        /* allocate output buffer */
+        state->out = (unsigned char *)malloc(state->want);
+        if (state->out == NULL) {
+            free(state->in);
+            gz_error(state, Z_MEM_ERROR, "out of memory");
+            return -1;
+        }
+
+        /* allocate deflate memory, set up for gzip compression */
+        strm->zalloc = Z_NULL;
+        strm->zfree = Z_NULL;
+        strm->opaque = Z_NULL;
+        ret = deflateInit2(strm, state->level, Z_DEFLATED,
+                           MAX_WBITS + 16, DEF_MEM_LEVEL, state->strategy);
+        if (ret != Z_OK) {
+            free(state->out);
+            free(state->in);
+            gz_error(state, Z_MEM_ERROR, "out of memory");
+            return -1;
+        }
+    }
+
+    /* mark state as initialized */
+    state->size = state->want;
+
+    /* initialize write buffer if compressing */
+    if (!state->direct) {
+        strm->avail_out = state->size;
+        strm->next_out = state->out;
+        state->x.next = strm->next_out;
+    }
+    return 0;
+}
+
+/* Compress whatever is at avail_in and next_in and write to the output file.
+   Return -1 if there is an error writing to the output file, otherwise 0.
+   flush is assumed to be a valid deflate() flush value.  If flush is Z_FINISH,
+   then the deflate() state is reset to start a new gzip stream.  If gz->direct
+   is true, then simply write to the output file without compressing, and
+   ignore flush. */
+local int gz_comp(state, flush)
+    gz_statep state;
+    int flush;
+{
+    int ret, got;
+    unsigned have;
+    z_streamp strm = &(state->strm);
+
+    /* allocate memory if this is the first time through */
+    if (state->size == 0 && gz_init(state) == -1)
+        return -1;
+
+    /* write directly if requested */
+    if (state->direct) {
+        got = write(state->fd, strm->next_in, strm->avail_in);
+        if (got < 0 || (unsigned)got != strm->avail_in) {
+            gz_error(state, Z_ERRNO, zstrerror());
+            return -1;
+        }
+        strm->avail_in = 0;
+        return 0;
+    }
+
+    /* run deflate() on provided input until it produces no more output */
+    ret = Z_OK;
+    do {
+        /* write out current buffer contents if full, or if flushing, but if
+           doing Z_FINISH then don't write until we get to Z_STREAM_END */
+        if (strm->avail_out == 0 || (flush != Z_NO_FLUSH &&
+            (flush != Z_FINISH || ret == Z_STREAM_END))) {
+            have = (unsigned)(strm->next_out - state->x.next);
+            if (have && ((got = write(state->fd, state->x.next, have)) < 0 ||
+                         (unsigned)got != have)) {
+                gz_error(state, Z_ERRNO, zstrerror());
+                return -1;
+            }
+            if (strm->avail_out == 0) {
+                strm->avail_out = state->size;
+                strm->next_out = state->out;
+            }
+            state->x.next = strm->next_out;
+        }
+
+        /* compress */
+        have = strm->avail_out;
+        ret = deflate(strm, flush);
+        if (ret == Z_STREAM_ERROR) {
+            gz_error(state, Z_STREAM_ERROR,
+                      "internal error: deflate stream corrupt");
+            return -1;
+        }
+        have -= strm->avail_out;
+    } while (have);
+
+    /* if that completed a deflate stream, allow another to start */
+    if (flush == Z_FINISH)
+        deflateReset(strm);
+
+    /* all done, no errors */
+    return 0;
+}
+
+/* Compress len zeros to output.  Return -1 on error, 0 on success. */
+local int gz_zero(state, len)
+    gz_statep state;
+    z_off64_t len;
+{
+    int first;
+    unsigned n;
+    z_streamp strm = &(state->strm);
+
+    /* consume whatever's left in the input buffer */
+    if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1)
+        return -1;
+
+    /* compress len zeros (len guaranteed > 0) */
+    first = 1;
+    while (len) {
+        n = GT_OFF(state->size) || (z_off64_t)state->size > len ?
+            (unsigned)len : state->size;
+        if (first) {
+            memset(state->in, 0, n);
+            first = 0;
+        }
+        strm->avail_in = n;
+        strm->next_in = state->in;
+        state->x.pos += n;
+        if (gz_comp(state, Z_NO_FLUSH) == -1)
+            return -1;
+        len -= n;
+    }
+    return 0;
+}
+
+/* -- see zlib.h -- */
+int ZEXPORT gzwrite(file, buf, len)
+    gzFile file;
+    voidpc buf;
+    unsigned len;
+{
+    unsigned put = len;
+    gz_statep state;
+    z_streamp strm;
+
+    /* get internal structure */
+    if (file == NULL)
+        return 0;
+    state = (gz_statep)file;
+    strm = &(state->strm);
+
+    /* check that we're writing and that there's no error */
+    if (state->mode != GZ_WRITE || state->err != Z_OK)
+        return 0;
+
+    /* since an int is returned, make sure len fits in one, otherwise return
+       with an error (this avoids the flaw in the interface) */
+    if ((int)len < 0) {
+        gz_error(state, Z_DATA_ERROR, "requested length does not fit in int");
+        return 0;
+    }
+
+    /* if len is zero, avoid unnecessary operations */
+    if (len == 0)
+        return 0;
+
+    /* allocate memory if this is the first time through */
+    if (state->size == 0 && gz_init(state) == -1)
+        return 0;
+
+    /* check for seek request */
+    if (state->seek) {
+        state->seek = 0;
+        if (gz_zero(state, state->skip) == -1)
+            return 0;
+    }
+
+    /* for small len, copy to input buffer, otherwise compress directly */
+    if (len < state->size) {
+        /* copy to input buffer, compress when full */
+        do {
+            unsigned have, copy;
+
+            if (strm->avail_in == 0)
+                strm->next_in = state->in;
+            have = (unsigned)((strm->next_in + strm->avail_in) - state->in);
+            copy = state->size - have;
+            if (copy > len)
+                copy = len;
+            memcpy(state->in + have, buf, copy);
+            strm->avail_in += copy;
+            state->x.pos += copy;
+            buf = (const char *)buf + copy;
+            len -= copy;
+            if (len && gz_comp(state, Z_NO_FLUSH) == -1)
+                return 0;
+        } while (len);
+    }
+    else {
+        /* consume whatever's left in the input buffer */
+        if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1)
+            return 0;
+
+        /* directly compress user buffer to file */
+        strm->avail_in = len;
+        strm->next_in = (z_const Bytef *)buf;
+        state->x.pos += len;
+        if (gz_comp(state, Z_NO_FLUSH) == -1)
+            return 0;
+    }
+
+    /* input was all buffered or compressed (put will fit in int) */
+    return (int)put;
+}
+
+/* -- see zlib.h -- */
+int ZEXPORT gzputc(file, c)
+    gzFile file;
+    int c;
+{
+    unsigned have;
+    unsigned char buf[1];
+    gz_statep state;
+    z_streamp strm;
+
+    /* get internal structure */
+    if (file == NULL)
+        return -1;
+    state = (gz_statep)file;
+    strm = &(state->strm);
+
+    /* check that we're writing and that there's no error */
+    if (state->mode != GZ_WRITE || state->err != Z_OK)
+        return -1;
+
+    /* check for seek request */
+    if (state->seek) {
+        state->seek = 0;
+        if (gz_zero(state, state->skip) == -1)
+            return -1;
+    }
+
+    /* try writing to input buffer for speed (state->size == 0 if buffer not
+       initialized) */
+    if (state->size) {
+        if (strm->avail_in == 0)
+            strm->next_in = state->in;
+        have = (unsigned)((strm->next_in + strm->avail_in) - state->in);
+        if (have < state->size) {
+            state->in[have] = c;
+            strm->avail_in++;
+            state->x.pos++;
+            return c & 0xff;
+        }
+    }
+
+    /* no room in buffer or not initialized, use gz_write() */
+    buf[0] = c;
+    if (gzwrite(file, buf, 1) != 1)
+        return -1;
+    return c & 0xff;
+}
+
+/* -- see zlib.h -- */
+int ZEXPORT gzputs(file, str)
+    gzFile file;
+    const char *str;
+{
+    int ret;
+    unsigned len;
+
+    /* write string */
+    len = (unsigned)strlen(str);
+    ret = gzwrite(file, str, len);
+    return ret == 0 && len != 0 ? -1 : ret;
+}
+
+#if defined(STDC) || defined(Z_HAVE_STDARG_H)
+#include <stdarg.h>
+
+/* -- see zlib.h -- */
+int ZEXPORTVA gzvprintf(gzFile file, const char *format, va_list va)
+{
+    int size, len;
+    gz_statep state;
+    z_streamp strm;
+
+    /* get internal structure */
+    if (file == NULL)
+        return -1;
+    state = (gz_statep)file;
+    strm = &(state->strm);
+
+    /* check that we're writing and that there's no error */
+    if (state->mode != GZ_WRITE || state->err != Z_OK)
+        return 0;
+
+    /* make sure we have some buffer space */
+    if (state->size == 0 && gz_init(state) == -1)
+        return 0;
+
+    /* check for seek request */
+    if (state->seek) {
+        state->seek = 0;
+        if (gz_zero(state, state->skip) == -1)
+            return 0;
+    }
+
+    /* consume whatever's left in the input buffer */
+    if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1)
+        return 0;
+
+    /* do the printf() into the input buffer, put length in len */
+    size = (int)(state->size);
+    state->in[size - 1] = 0;
+#ifdef NO_vsnprintf
+#  ifdef HAS_vsprintf_void
+    (void)vsprintf((char *)(state->in), format, va);
+    for (len = 0; len < size; len++)
+        if (state->in[len] == 0) break;
+#  else
+    len = vsprintf((char *)(state->in), format, va);
+#  endif
+#else
+#  ifdef HAS_vsnprintf_void
+    (void)vsnprintf((char *)(state->in), size, format, va);
+    len = strlen((char *)(state->in));
+#  else
+    len = vsnprintf((char *)(state->in), size, format, va);
+#  endif
+#endif
+
+    /* check that printf() results fit in buffer */
+    if (len <= 0 || len >= (int)size || state->in[size - 1] != 0)
+        return 0;
+
+    /* update buffer and position, defer compression until needed */
+    strm->avail_in = (unsigned)len;
+    strm->next_in = state->in;
+    state->x.pos += len;
+    return len;
+}
+
+int ZEXPORTVA gzprintf(gzFile file, const char *format, ...)
+{
+    va_list va;
+    int ret;
+
+    va_start(va, format);
+    ret = gzvprintf(file, format, va);
+    va_end(va);
+    return ret;
+}
+
+#else /* !STDC && !Z_HAVE_STDARG_H */
+
+/* -- see zlib.h -- */
+int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
+                       a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
+    gzFile file;
+    const char *format;
+    int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
+        a11, a12, a13, a14, a15, a16, a17, a18, a19, a20;
+{
+    int size, len;
+    gz_statep state;
+    z_streamp strm;
+
+    /* get internal structure */
+    if (file == NULL)
+        return -1;
+    state = (gz_statep)file;
+    strm = &(state->strm);
+
+    /* check that can really pass pointer in ints */
+    if (sizeof(int) != sizeof(void *))
+        return 0;
+
+    /* check that we're writing and that there's no error */
+    if (state->mode != GZ_WRITE || state->err != Z_OK)
+        return 0;
+
+    /* make sure we have some buffer space */
+    if (state->size == 0 && gz_init(state) == -1)
+        return 0;
+
+    /* check for seek request */
+    if (state->seek) {
+        state->seek = 0;
+        if (gz_zero(state, state->skip) == -1)
+            return 0;
+    }
+
+    /* consume whatever's left in the input buffer */
+    if (strm->avail_in && gz_comp(state, Z_NO_FLUSH) == -1)
+        return 0;
+
+    /* do the printf() into the input buffer, put length in len */
+    size = (int)(state->size);
+    state->in[size - 1] = 0;
+#ifdef NO_snprintf
+#  ifdef HAS_sprintf_void
+    sprintf((char *)(state->in), format, a1, a2, a3, a4, a5, a6, a7, a8,
+            a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
+    for (len = 0; len < size; len++)
+        if (state->in[len] == 0) break;
+#  else
+    len = sprintf((char *)(state->in), format, a1, a2, a3, a4, a5, a6, a7, a8,
+                  a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
+#  endif
+#else
+#  ifdef HAS_snprintf_void
+    snprintf((char *)(state->in), size, format, a1, a2, a3, a4, a5, a6, a7, a8,
+             a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
+    len = strlen((char *)(state->in));
+#  else
+    len = snprintf((char *)(state->in), size, format, a1, a2, a3, a4, a5, a6,
+                   a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18,
+                   a19, a20);
+#  endif
+#endif
+
+    /* check that printf() results fit in buffer */
+    if (len <= 0 || len >= (int)size || state->in[size - 1] != 0)
+        return 0;
+
+    /* update buffer and position, defer compression until needed */
+    strm->avail_in = (unsigned)len;
+    strm->next_in = state->in;
+    state->x.pos += len;
+    return len;
+}
+
+#endif
+
+/* -- see zlib.h -- */
+int ZEXPORT gzflush(file, flush)
+    gzFile file;
+    int flush;
+{
+    gz_statep state;
+
+    /* get internal structure */
+    if (file == NULL)
+        return -1;
+    state = (gz_statep)file;
+
+    /* check that we're writing and that there's no error */
+    if (state->mode != GZ_WRITE || state->err != Z_OK)
+        return Z_STREAM_ERROR;
+
+    /* check flush parameter */
+    if (flush < 0 || flush > Z_FINISH)
+        return Z_STREAM_ERROR;
+
+    /* check for seek request */
+    if (state->seek) {
+        state->seek = 0;
+        if (gz_zero(state, state->skip) == -1)
+            return -1;
+    }
+
+    /* compress remaining data with requested flush */
+    gz_comp(state, flush);
+    return state->err;
+}
+
+/* -- see zlib.h -- */
+int ZEXPORT gzsetparams(file, level, strategy)
+    gzFile file;
+    int level;
+    int strategy;
+{
+    gz_statep state;
+    z_streamp strm;
+
+    /* get internal structure */
+    if (file == NULL)
+        return Z_STREAM_ERROR;
+    state = (gz_statep)file;
+    strm = &(state->strm);
+
+    /* check that we're writing and that there's no error */
+    if (state->mode != GZ_WRITE || state->err != Z_OK)
+        return Z_STREAM_ERROR;
+
+    /* if no change is requested, then do nothing */
+    if (level == state->level && strategy == state->strategy)
+        return Z_OK;
+
+    /* check for seek request */
+    if (state->seek) {
+        state->seek = 0;
+        if (gz_zero(state, state->skip) == -1)
+            return -1;
+    }
+
+    /* change compression parameters for subsequent input */
+    if (state->size) {
+        /* flush previous input with previous parameters before changing */
+        if (strm->avail_in && gz_comp(state, Z_PARTIAL_FLUSH) == -1)
+            return state->err;
+        deflateParams(strm, level, strategy);
+    }
+    state->level = level;
+    state->strategy = strategy;
+    return Z_OK;
+}
+
+/* -- see zlib.h -- */
+int ZEXPORT gzclose_w(file)
+    gzFile file;
+{
+    int ret = Z_OK;
+    gz_statep state;
+
+    /* get internal structure */
+    if (file == NULL)
+        return Z_STREAM_ERROR;
+    state = (gz_statep)file;
+
+    /* check that we're writing */
+    if (state->mode != GZ_WRITE)
+        return Z_STREAM_ERROR;
+
+    /* check for seek request */
+    if (state->seek) {
+        state->seek = 0;
+        if (gz_zero(state, state->skip) == -1)
+            ret = state->err;
+    }
+
+    /* flush, free memory, and close file */
+    if (gz_comp(state, Z_FINISH) == -1)
+        ret = state->err;
+    if (state->size) {
+        if (!state->direct) {
+            (void)deflateEnd(&(state->strm));
+            free(state->out);
+        }
+        free(state->in);
+    }
+    gz_error(state, Z_OK, NULL);
+    free(state->path);
+    if (close(state->fd) == -1)
+        ret = Z_ERRNO;
+    free(state);
+    return ret;
+}
diff --git a/compat/zlib/infback.c b/compat/zlib/infback.c
new file mode 100644
index 0000000..f3833c2
--- /dev/null
+++ b/compat/zlib/infback.c
@@ -0,0 +1,640 @@
+/* infback.c -- inflate using a call-back interface
+ * Copyright (C) 1995-2011 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/*
+   This code is largely copied from inflate.c.  Normally either infback.o or
+   inflate.o would be linked into an application--not both.  The interface
+   with inffast.c is retained so that optimized assembler-coded versions of
+   inflate_fast() can be used with either inflate.c or infback.c.
+ */
+
+#include "zutil.h"
+#include "inftrees.h"
+#include "inflate.h"
+#include "inffast.h"
+
+/* function prototypes */
+local void fixedtables OF((struct inflate_state FAR *state));
+
+/*
+   strm provides memory allocation functions in zalloc and zfree, or
+   Z_NULL to use the library memory allocation functions.
+
+   windowBits is in the range 8..15, and window is a user-supplied
+   window and output buffer that is 2**windowBits bytes.
+ */
+int ZEXPORT inflateBackInit_(strm, windowBits, window, version, stream_size)
+z_streamp strm;
+int windowBits;
+unsigned char FAR *window;
+const char *version;
+int stream_size;
+{
+    struct inflate_state FAR *state;
+
+    if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
+        stream_size != (int)(sizeof(z_stream)))
+        return Z_VERSION_ERROR;
+    if (strm == Z_NULL || window == Z_NULL ||
+        windowBits < 8 || windowBits > 15)
+        return Z_STREAM_ERROR;
+    strm->msg = Z_NULL;                 /* in case we return an error */
+    if (strm->zalloc == (alloc_func)0) {
+#ifdef Z_SOLO
+        return Z_STREAM_ERROR;
+#else
+        strm->zalloc = zcalloc;
+        strm->opaque = (voidpf)0;
+#endif
+    }
+    if (strm->zfree == (free_func)0)
+#ifdef Z_SOLO
+        return Z_STREAM_ERROR;
+#else
+    strm->zfree = zcfree;
+#endif
+    state = (struct inflate_state FAR *)ZALLOC(strm, 1,
+                                               sizeof(struct inflate_state));
+    if (state == Z_NULL) return Z_MEM_ERROR;
+    Tracev((stderr, "inflate: allocated\n"));
+    strm->state = (struct internal_state FAR *)state;
+    state->dmax = 32768U;
+    state->wbits = windowBits;
+    state->wsize = 1U << windowBits;
+    state->window = window;
+    state->wnext = 0;
+    state->whave = 0;
+    return Z_OK;
+}
+
+/*
+   Return state with length and distance decoding tables and index sizes set to
+   fixed code decoding.  Normally this returns fixed tables from inffixed.h.
+   If BUILDFIXED is defined, then instead this routine builds the tables the
+   first time it's called, and returns those tables the first time and
+   thereafter.  This reduces the size of the code by about 2K bytes, in
+   exchange for a little execution time.  However, BUILDFIXED should not be
+   used for threaded applications, since the rewriting of the tables and virgin
+   may not be thread-safe.
+ */
+local void fixedtables(state)
+struct inflate_state FAR *state;
+{
+#ifdef BUILDFIXED
+    static int virgin = 1;
+    static code *lenfix, *distfix;
+    static code fixed[544];
+
+    /* build fixed huffman tables if first call (may not be thread safe) */
+    if (virgin) {
+        unsigned sym, bits;
+        static code *next;
+
+        /* literal/length table */
+        sym = 0;
+        while (sym < 144) state->lens[sym++] = 8;
+        while (sym < 256) state->lens[sym++] = 9;
+        while (sym < 280) state->lens[sym++] = 7;
+        while (sym < 288) state->lens[sym++] = 8;
+        next = fixed;
+        lenfix = next;
+        bits = 9;
+        inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work);
+
+        /* distance table */
+        sym = 0;
+        while (sym < 32) state->lens[sym++] = 5;
+        distfix = next;
+        bits = 5;
+        inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work);
+
+        /* do this just once */
+        virgin = 0;
+    }
+#else /* !BUILDFIXED */
+#   include "inffixed.h"
+#endif /* BUILDFIXED */
+    state->lencode = lenfix;
+    state->lenbits = 9;
+    state->distcode = distfix;
+    state->distbits = 5;
+}
+
+/* Macros for inflateBack(): */
+
+/* Load returned state from inflate_fast() */
+#define LOAD() \
+    do { \
+        put = strm->next_out; \
+        left = strm->avail_out; \
+        next = strm->next_in; \
+        have = strm->avail_in; \
+        hold = state->hold; \
+        bits = state->bits; \
+    } while (0)
+
+/* Set state from registers for inflate_fast() */
+#define RESTORE() \
+    do { \
+        strm->next_out = put; \
+        strm->avail_out = left; \
+        strm->next_in = next; \
+        strm->avail_in = have; \
+        state->hold = hold; \
+        state->bits = bits; \
+    } while (0)
+
+/* Clear the input bit accumulator */
+#define INITBITS() \
+    do { \
+        hold = 0; \
+        bits = 0; \
+    } while (0)
+
+/* Assure that some input is available.  If input is requested, but denied,
+   then return a Z_BUF_ERROR from inflateBack(). */
+#define PULL() \
+    do { \
+        if (have == 0) { \
+            have = in(in_desc, &next); \
+            if (have == 0) { \
+                next = Z_NULL; \
+                ret = Z_BUF_ERROR; \
+                goto inf_leave; \
+            } \
+        } \
+    } while (0)
+
+/* Get a byte of input into the bit accumulator, or return from inflateBack()
+   with an error if there is no input available. */
+#define PULLBYTE() \
+    do { \
+        PULL(); \
+        have--; \
+        hold += (unsigned long)(*next++) << bits; \
+        bits += 8; \
+    } while (0)
+
+/* Assure that there are at least n bits in the bit accumulator.  If there is
+   not enough available input to do that, then return from inflateBack() with
+   an error. */
+#define NEEDBITS(n) \
+    do { \
+        while (bits < (unsigned)(n)) \
+            PULLBYTE(); \
+    } while (0)
+
+/* Return the low n bits of the bit accumulator (n < 16) */
+#define BITS(n) \
+    ((unsigned)hold & ((1U << (n)) - 1))
+
+/* Remove n bits from the bit accumulator */
+#define DROPBITS(n) \
+    do { \
+        hold >>= (n); \
+        bits -= (unsigned)(n); \
+    } while (0)
+
+/* Remove zero to seven bits as needed to go to a byte boundary */
+#define BYTEBITS() \
+    do { \
+        hold >>= bits & 7; \
+        bits -= bits & 7; \
+    } while (0)
+
+/* Assure that some output space is available, by writing out the window
+   if it's full.  If the write fails, return from inflateBack() with a
+   Z_BUF_ERROR. */
+#define ROOM() \
+    do { \
+        if (left == 0) { \
+            put = state->window; \
+            left = state->wsize; \
+            state->whave = left; \
+            if (out(out_desc, put, left)) { \
+                ret = Z_BUF_ERROR; \
+                goto inf_leave; \
+            } \
+        } \
+    } while (0)
+
+/*
+   strm provides the memory allocation functions and window buffer on input,
+   and provides information on the unused input on return.  For Z_DATA_ERROR
+   returns, strm will also provide an error message.
+
+   in() and out() are the call-back input and output functions.  When
+   inflateBack() needs more input, it calls in().  When inflateBack() has
+   filled the window with output, or when it completes with data in the
+   window, it calls out() to write out the data.  The application must not
+   change the provided input until in() is called again or inflateBack()
+   returns.  The application must not change the window/output buffer until
+   inflateBack() returns.
+
+   in() and out() are called with a descriptor parameter provided in the
+   inflateBack() call.  This parameter can be a structure that provides the
+   information required to do the read or write, as well as accumulated
+   information on the input and output such as totals and check values.
+
+   in() should return zero on failure.  out() should return non-zero on
+   failure.  If either in() or out() fails, than inflateBack() returns a
+   Z_BUF_ERROR.  strm->next_in can be checked for Z_NULL to see whether it
+   was in() or out() that caused in the error.  Otherwise,  inflateBack()
+   returns Z_STREAM_END on success, Z_DATA_ERROR for an deflate format
+   error, or Z_MEM_ERROR if it could not allocate memory for the state.
+   inflateBack() can also return Z_STREAM_ERROR if the input parameters
+   are not correct, i.e. strm is Z_NULL or the state was not initialized.
+ */
+int ZEXPORT inflateBack(strm, in, in_desc, out, out_desc)
+z_streamp strm;
+in_func in;
+void FAR *in_desc;
+out_func out;
+void FAR *out_desc;
+{
+    struct inflate_state FAR *state;
+    z_const unsigned char FAR *next;    /* next input */
+    unsigned char FAR *put;     /* next output */
+    unsigned have, left;        /* available input and output */
+    unsigned long hold;         /* bit buffer */
+    unsigned bits;              /* bits in bit buffer */
+    unsigned copy;              /* number of stored or match bytes to copy */
+    unsigned char FAR *from;    /* where to copy match bytes from */
+    code here;                  /* current decoding table entry */
+    code last;                  /* parent table entry */
+    unsigned len;               /* length to copy for repeats, bits to drop */
+    int ret;                    /* return code */
+    static const unsigned short order[19] = /* permutation of code lengths */
+        {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
+
+    /* Check that the strm exists and that the state was initialized */
+    if (strm == Z_NULL || strm->state == Z_NULL)
+        return Z_STREAM_ERROR;
+    state = (struct inflate_state FAR *)strm->state;
+
+    /* Reset the state */
+    strm->msg = Z_NULL;
+    state->mode = TYPE;
+    state->last = 0;
+    state->whave = 0;
+    next = strm->next_in;
+    have = next != Z_NULL ? strm->avail_in : 0;
+    hold = 0;
+    bits = 0;
+    put = state->window;
+    left = state->wsize;
+
+    /* Inflate until end of block marked as last */
+    for (;;)
+        switch (state->mode) {
+        case TYPE:
+            /* determine and dispatch block type */
+            if (state->last) {
+                BYTEBITS();
+                state->mode = DONE;
+                break;
+            }
+            NEEDBITS(3);
+            state->last = BITS(1);
+            DROPBITS(1);
+            switch (BITS(2)) {
+            case 0:                             /* stored block */
+                Tracev((stderr, "inflate:     stored block%s\n",
+                        state->last ? " (last)" : ""));
+                state->mode = STORED;
+                break;
+            case 1:                             /* fixed block */
+                fixedtables(state);
+                Tracev((stderr, "inflate:     fixed codes block%s\n",
+                        state->last ? " (last)" : ""));
+                state->mode = LEN;              /* decode codes */
+                break;
+            case 2:                             /* dynamic block */
+                Tracev((stderr, "inflate:     dynamic codes block%s\n",
+                        state->last ? " (last)" : ""));
+                state->mode = TABLE;
+                break;
+            case 3:
+                strm->msg = (char *)"invalid block type";
+                state->mode = BAD;
+            }
+            DROPBITS(2);
+            break;
+
+        case STORED:
+            /* get and verify stored block length */
+            BYTEBITS();                         /* go to byte boundary */
+            NEEDBITS(32);
+            if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) {
+                strm->msg = (char *)"invalid stored block lengths";
+                state->mode = BAD;
+                break;
+            }
+            state->length = (unsigned)hold & 0xffff;
+            Tracev((stderr, "inflate:       stored length %u\n",
+                    state->length));
+            INITBITS();
+
+            /* copy stored block from input to output */
+            while (state->length != 0) {
+                copy = state->length;
+                PULL();
+                ROOM();
+                if (copy > have) copy = have;
+                if (copy > left) copy = left;
+                zmemcpy(put, next, copy);
+                have -= copy;
+                next += copy;
+                left -= copy;
+                put += copy;
+                state->length -= copy;
+            }
+            Tracev((stderr, "inflate:       stored end\n"));
+            state->mode = TYPE;
+            break;
+
+        case TABLE:
+            /* get dynamic table entries descriptor */
+            NEEDBITS(14);
+            state->nlen = BITS(5) + 257;
+            DROPBITS(5);
+            state->ndist = BITS(5) + 1;
+            DROPBITS(5);
+            state->ncode = BITS(4) + 4;
+            DROPBITS(4);
+#ifndef PKZIP_BUG_WORKAROUND
+            if (state->nlen > 286 || state->ndist > 30) {
+                strm->msg = (char *)"too many length or distance symbols";
+                state->mode = BAD;
+                break;
+            }
+#endif
+            Tracev((stderr, "inflate:       table sizes ok\n"));
+
+            /* get code length code lengths (not a typo) */
+            state->have = 0;
+            while (state->have < state->ncode) {
+                NEEDBITS(3);
+                state->lens[order[state->have++]] = (unsigned short)BITS(3);
+                DROPBITS(3);
+            }
+            while (state->have < 19)
+                state->lens[order[state->have++]] = 0;
+            state->next = state->codes;
+            state->lencode = (code const FAR *)(state->next);
+            state->lenbits = 7;
+            ret = inflate_table(CODES, state->lens, 19, &(state->next),
+                                &(state->lenbits), state->work);
+            if (ret) {
+                strm->msg = (char *)"invalid code lengths set";
+                state->mode = BAD;
+                break;
+            }
+            Tracev((stderr, "inflate:       code lengths ok\n"));
+
+            /* get length and distance code code lengths */
+            state->have = 0;
+            while (state->have < state->nlen + state->ndist) {
+                for (;;) {
+                    here = state->lencode[BITS(state->lenbits)];
+                    if ((unsigned)(here.bits) <= bits) break;
+                    PULLBYTE();
+                }
+                if (here.val < 16) {
+                    DROPBITS(here.bits);
+                    state->lens[state->have++] = here.val;
+                }
+                else {
+                    if (here.val == 16) {
+                        NEEDBITS(here.bits + 2);
+                        DROPBITS(here.bits);
+                        if (state->have == 0) {
+                            strm->msg = (char *)"invalid bit length repeat";
+                            state->mode = BAD;
+                            break;
+                        }
+                        len = (unsigned)(state->lens[state->have - 1]);
+                        copy = 3 + BITS(2);
+                        DROPBITS(2);
+                    }
+                    else if (here.val == 17) {
+                        NEEDBITS(here.bits + 3);
+                        DROPBITS(here.bits);
+                        len = 0;
+                        copy = 3 + BITS(3);
+                        DROPBITS(3);
+                    }
+                    else {
+                        NEEDBITS(here.bits + 7);
+                        DROPBITS(here.bits);
+                        len = 0;
+                        copy = 11 + BITS(7);
+                        DROPBITS(7);
+                    }
+                    if (state->have + copy > state->nlen + state->ndist) {
+                        strm->msg = (char *)"invalid bit length repeat";
+                        state->mode = BAD;
+                        break;
+                    }
+                    while (copy--)
+                        state->lens[state->have++] = (unsigned short)len;
+                }
+            }
+
+            /* handle error breaks in while */
+            if (state->mode == BAD) break;
+
+            /* check for end-of-block code (better have one) */
+            if (state->lens[256] == 0) {
+                strm->msg = (char *)"invalid code -- missing end-of-block";
+                state->mode = BAD;
+                break;
+            }
+
+            /* build code tables -- note: do not change the lenbits or distbits
+               values here (9 and 6) without reading the comments in inftrees.h
+               concerning the ENOUGH constants, which depend on those values */
+            state->next = state->codes;
+            state->lencode = (code const FAR *)(state->next);
+            state->lenbits = 9;
+            ret = inflate_table(LENS, state->lens, state->nlen, &(state->next),
+                                &(state->lenbits), state->work);
+            if (ret) {
+                strm->msg = (char *)"invalid literal/lengths set";
+                state->mode = BAD;
+                break;
+            }
+            state->distcode = (code const FAR *)(state->next);
+            state->distbits = 6;
+            ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist,
+                            &(state->next), &(state->distbits), state->work);
+            if (ret) {
+                strm->msg = (char *)"invalid distances set";
+                state->mode = BAD;
+                break;
+            }
+            Tracev((stderr, "inflate:       codes ok\n"));
+            state->mode = LEN;
+
+        case LEN:
+            /* use inflate_fast() if we have enough input and output */
+            if (have >= 6 && left >= 258) {
+                RESTORE();
+                if (state->whave < state->wsize)
+                    state->whave = state->wsize - left;
+                inflate_fast(strm, state->wsize);
+                LOAD();
+                break;
+            }
+
+            /* get a literal, length, or end-of-block code */
+            for (;;) {
+                here = state->lencode[BITS(state->lenbits)];
+                if ((unsigned)(here.bits) <= bits) break;
+                PULLBYTE();
+            }
+            if (here.op && (here.op & 0xf0) == 0) {
+                last = here;
+                for (;;) {
+                    here = state->lencode[last.val +
+                            (BITS(last.bits + last.op) >> last.bits)];
+                    if ((unsigned)(last.bits + here.bits) <= bits) break;
+                    PULLBYTE();
+                }
+                DROPBITS(last.bits);
+            }
+            DROPBITS(here.bits);
+            state->length = (unsigned)here.val;
+
+            /* process literal */
+            if (here.op == 0) {
+                Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?
+                        "inflate:         literal '%c'\n" :
+                        "inflate:         literal 0x%02x\n", here.val));
+                ROOM();
+                *put++ = (unsigned char)(state->length);
+                left--;
+                state->mode = LEN;
+                break;
+            }
+
+            /* process end of block */
+            if (here.op & 32) {
+                Tracevv((stderr, "inflate:         end of block\n"));
+                state->mode = TYPE;
+                break;
+            }
+
+            /* invalid code */
+            if (here.op & 64) {
+                strm->msg = (char *)"invalid literal/length code";
+                state->mode = BAD;
+                break;
+            }
+
+            /* length code -- get extra bits, if any */
+            state->extra = (unsigned)(here.op) & 15;
+            if (state->extra != 0) {
+                NEEDBITS(state->extra);
+                state->length += BITS(state->extra);
+                DROPBITS(state->extra);
+            }
+            Tracevv((stderr, "inflate:         length %u\n", state->length));
+
+            /* get distance code */
+            for (;;) {
+                here = state->distcode[BITS(state->distbits)];
+                if ((unsigned)(here.bits) <= bits) break;
+                PULLBYTE();
+            }
+            if ((here.op & 0xf0) == 0) {
+                last = here;
+                for (;;) {
+                    here = state->distcode[last.val +
+                            (BITS(last.bits + last.op) >> last.bits)];
+                    if ((unsigned)(last.bits + here.bits) <= bits) break;
+                    PULLBYTE();
+                }
+                DROPBITS(last.bits);
+            }
+            DROPBITS(here.bits);
+            if (here.op & 64) {
+                strm->msg = (char *)"invalid distance code";
+                state->mode = BAD;
+                break;
+            }
+            state->offset = (unsigned)here.val;
+
+            /* get distance extra bits, if any */
+            state->extra = (unsigned)(here.op) & 15;
+            if (state->extra != 0) {
+                NEEDBITS(state->extra);
+                state->offset += BITS(state->extra);
+                DROPBITS(state->extra);
+            }
+            if (state->offset > state->wsize - (state->whave < state->wsize ?
+                                                left : 0)) {
+                strm->msg = (char *)"invalid distance too far back";
+                state->mode = BAD;
+                break;
+            }
+            Tracevv((stderr, "inflate:         distance %u\n", state->offset));
+
+            /* copy match from window to output */
+            do {
+                ROOM();
+                copy = state->wsize - state->offset;
+                if (copy < left) {
+                    from = put + copy;
+                    copy = left - copy;
+                }
+                else {
+                    from = put - state->offset;
+                    copy = left;
+                }
+                if (copy > state->length) copy = state->length;
+                state->length -= copy;
+                left -= copy;
+                do {
+                    *put++ = *from++;
+                } while (--copy);
+            } while (state->length != 0);
+            break;
+
+        case DONE:
+            /* inflate stream terminated properly -- write leftover output */
+            ret = Z_STREAM_END;
+            if (left < state->wsize) {
+                if (out(out_desc, state->window, state->wsize - left))
+                    ret = Z_BUF_ERROR;
+            }
+            goto inf_leave;
+
+        case BAD:
+            ret = Z_DATA_ERROR;
+            goto inf_leave;
+
+        default:                /* can't happen, but makes compilers happy */
+            ret = Z_STREAM_ERROR;
+            goto inf_leave;
+        }
+
+    /* Return unused input */
+  inf_leave:
+    strm->next_in = next;
+    strm->avail_in = have;
+    return ret;
+}
+
+int ZEXPORT inflateBackEnd(strm)
+z_streamp strm;
+{
+    if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0)
+        return Z_STREAM_ERROR;
+    ZFREE(strm, strm->state);
+    strm->state = Z_NULL;
+    Tracev((stderr, "inflate: end\n"));
+    return Z_OK;
+}
diff --git a/compat/zlib/inffast.c b/compat/zlib/inffast.c
new file mode 100644
index 0000000..bda59ce
--- /dev/null
+++ b/compat/zlib/inffast.c
@@ -0,0 +1,340 @@
+/* inffast.c -- fast decoding
+ * Copyright (C) 1995-2008, 2010, 2013 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+#include "zutil.h"
+#include "inftrees.h"
+#include "inflate.h"
+#include "inffast.h"
+
+#ifndef ASMINF
+
+/* Allow machine dependent optimization for post-increment or pre-increment.
+   Based on testing to date,
+   Pre-increment preferred for:
+   - PowerPC G3 (Adler)
+   - MIPS R5000 (Randers-Pehrson)
+   Post-increment preferred for:
+   - none
+   No measurable difference:
+   - Pentium III (Anderson)
+   - M68060 (Nikl)
+ */
+#ifdef POSTINC
+#  define OFF 0
+#  define PUP(a) *(a)++
+#else
+#  define OFF 1
+#  define PUP(a) *++(a)
+#endif
+
+/*
+   Decode literal, length, and distance codes and write out the resulting
+   literal and match bytes until either not enough input or output is
+   available, an end-of-block is encountered, or a data error is encountered.
+   When large enough input and output buffers are supplied to inflate(), for
+   example, a 16K input buffer and a 64K output buffer, more than 95% of the
+   inflate execution time is spent in this routine.
+
+   Entry assumptions:
+
+        state->mode == LEN
+        strm->avail_in >= 6
+        strm->avail_out >= 258
+        start >= strm->avail_out
+        state->bits < 8
+
+   On return, state->mode is one of:
+
+        LEN -- ran out of enough output space or enough available input
+        TYPE -- reached end of block code, inflate() to interpret next block
+        BAD -- error in block data
+
+   Notes:
+
+    - The maximum input bits used by a length/distance pair is 15 bits for the
+      length code, 5 bits for the length extra, 15 bits for the distance code,
+      and 13 bits for the distance extra.  This totals 48 bits, or six bytes.
+      Therefore if strm->avail_in >= 6, then there is enough input to avoid
+      checking for available input while decoding.
+
+    - The maximum bytes that a single length/distance pair can output is 258
+      bytes, which is the maximum length that can be coded.  inflate_fast()
+      requires strm->avail_out >= 258 for each loop to avoid checking for
+      output space.
+ */
+void ZLIB_INTERNAL inflate_fast(strm, start)
+z_streamp strm;
+unsigned start;         /* inflate()'s starting value for strm->avail_out */
+{
+    struct inflate_state FAR *state;
+    z_const unsigned char FAR *in;      /* local strm->next_in */
+    z_const unsigned char FAR *last;    /* have enough input while in < last */
+    unsigned char FAR *out;     /* local strm->next_out */
+    unsigned char FAR *beg;     /* inflate()'s initial strm->next_out */
+    unsigned char FAR *end;     /* while out < end, enough space available */
+#ifdef INFLATE_STRICT
+    unsigned dmax;              /* maximum distance from zlib header */
+#endif
+    unsigned wsize;             /* window size or zero if not using window */
+    unsigned whave;             /* valid bytes in the window */
+    unsigned wnext;             /* window write index */
+    unsigned char FAR *window;  /* allocated sliding window, if wsize != 0 */
+    unsigned long hold;         /* local strm->hold */
+    unsigned bits;              /* local strm->bits */
+    code const FAR *lcode;      /* local strm->lencode */
+    code const FAR *dcode;      /* local strm->distcode */
+    unsigned lmask;             /* mask for first level of length codes */
+    unsigned dmask;             /* mask for first level of distance codes */
+    code here;                  /* retrieved table entry */
+    unsigned op;                /* code bits, operation, extra bits, or */
+                                /*  window position, window bytes to copy */
+    unsigned len;               /* match length, unused bytes */
+    unsigned dist;              /* match distance */
+    unsigned char FAR *from;    /* where to copy match from */
+
+    /* copy state to local variables */
+    state = (struct inflate_state FAR *)strm->state;
+    in = strm->next_in - OFF;
+    last = in + (strm->avail_in - 5);
+    out = strm->next_out - OFF;
+    beg = out - (start - strm->avail_out);
+    end = out + (strm->avail_out - 257);
+#ifdef INFLATE_STRICT
+    dmax = state->dmax;
+#endif
+    wsize = state->wsize;
+    whave = state->whave;
+    wnext = state->wnext;
+    window = state->window;
+    hold = state->hold;
+    bits = state->bits;
+    lcode = state->lencode;
+    dcode = state->distcode;
+    lmask = (1U << state->lenbits) - 1;
+    dmask = (1U << state->distbits) - 1;
+
+    /* decode literals and length/distances until end-of-block or not enough
+       input data or output space */
+    do {
+        if (bits < 15) {
+            hold += (unsigned long)(PUP(in)) << bits;
+            bits += 8;
+            hold += (unsigned long)(PUP(in)) << bits;
+            bits += 8;
+        }
+        here = lcode[hold & lmask];
+      dolen:
+        op = (unsigned)(here.bits);
+        hold >>= op;
+        bits -= op;
+        op = (unsigned)(here.op);
+        if (op == 0) {                          /* literal */
+            Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?
+                    "inflate:         literal '%c'\n" :
+                    "inflate:         literal 0x%02x\n", here.val));
+            PUP(out) = (unsigned char)(here.val);
+        }
+        else if (op & 16) {                     /* length base */
+            len = (unsigned)(here.val);
+            op &= 15;                           /* number of extra bits */
+            if (op) {
+                if (bits < op) {
+                    hold += (unsigned long)(PUP(in)) << bits;
+                    bits += 8;
+                }
+                len += (unsigned)hold & ((1U << op) - 1);
+                hold >>= op;
+                bits -= op;
+            }
+            Tracevv((stderr, "inflate:         length %u\n", len));
+            if (bits < 15) {
+                hold += (unsigned long)(PUP(in)) << bits;
+                bits += 8;
+                hold += (unsigned long)(PUP(in)) << bits;
+                bits += 8;
+            }
+            here = dcode[hold & dmask];
+          dodist:
+            op = (unsigned)(here.bits);
+            hold >>= op;
+            bits -= op;
+            op = (unsigned)(here.op);
+            if (op & 16) {                      /* distance base */
+                dist = (unsigned)(here.val);
+                op &= 15;                       /* number of extra bits */
+                if (bits < op) {
+                    hold += (unsigned long)(PUP(in)) << bits;
+                    bits += 8;
+                    if (bits < op) {
+                        hold += (unsigned long)(PUP(in)) << bits;
+                        bits += 8;
+                    }
+                }
+                dist += (unsigned)hold & ((1U << op) - 1);
+#ifdef INFLATE_STRICT
+                if (dist > dmax) {
+                    strm->msg = (char *)"invalid distance too far back";
+                    state->mode = BAD;
+                    break;
+                }
+#endif
+                hold >>= op;
+                bits -= op;
+                Tracevv((stderr, "inflate:         distance %u\n", dist));
+                op = (unsigned)(out - beg);     /* max distance in output */
+                if (dist > op) {                /* see if copy from window */
+                    op = dist - op;             /* distance back in window */
+                    if (op > whave) {
+                        if (state->sane) {
+                            strm->msg =
+                                (char *)"invalid distance too far back";
+                            state->mode = BAD;
+                            break;
+                        }
+#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
+                        if (len <= op - whave) {
+                            do {
+                                PUP(out) = 0;
+                            } while (--len);
+                            continue;
+                        }
+                        len -= op - whave;
+                        do {
+                            PUP(out) = 0;
+                        } while (--op > whave);
+                        if (op == 0) {
+                            from = out - dist;
+                            do {
+                                PUP(out) = PUP(from);
+                            } while (--len);
+                            continue;
+                        }
+#endif
+                    }
+                    from = window - OFF;
+                    if (wnext == 0) {           /* very common case */
+                        from += wsize - op;
+                        if (op < len) {         /* some from window */
+                            len -= op;
+                            do {
+                                PUP(out) = PUP(from);
+                            } while (--op);
+                            from = out - dist;  /* rest from output */
+                        }
+                    }
+                    else if (wnext < op) {      /* wrap around window */
+                        from += wsize + wnext - op;
+                        op -= wnext;
+                        if (op < len) {         /* some from end of window */
+                            len -= op;
+                            do {
+                                PUP(out) = PUP(from);
+                            } while (--op);
+                            from = window - OFF;
+                            if (wnext < len) {  /* some from start of window */
+                                op = wnext;
+                                len -= op;
+                                do {
+                                    PUP(out) = PUP(from);
+                                } while (--op);
+                                from = out - dist;      /* rest from output */
+                            }
+                        }
+                    }
+                    else {                      /* contiguous in window */
+                        from += wnext - op;
+                        if (op < len) {         /* some from window */
+                            len -= op;
+                            do {
+                                PUP(out) = PUP(from);
+                            } while (--op);
+                            from = out - dist;  /* rest from output */
+                        }
+                    }
+                    while (len > 2) {
+                        PUP(out) = PUP(from);
+                        PUP(out) = PUP(from);
+                        PUP(out) = PUP(from);
+                        len -= 3;
+                    }
+                    if (len) {
+                        PUP(out) = PUP(from);
+                        if (len > 1)
+                            PUP(out) = PUP(from);
+                    }
+                }
+                else {
+                    from = out - dist;          /* copy direct from output */
+                    do {                        /* minimum length is three */
+                        PUP(out) = PUP(from);
+                        PUP(out) = PUP(from);
+                        PUP(out) = PUP(from);
+                        len -= 3;
+                    } while (len > 2);
+                    if (len) {
+                        PUP(out) = PUP(from);
+                        if (len > 1)
+                            PUP(out) = PUP(from);
+                    }
+                }
+            }
+            else if ((op & 64) == 0) {          /* 2nd level distance code */
+                here = dcode[here.val + (hold & ((1U << op) - 1))];
+                goto dodist;
+            }
+            else {
+                strm->msg = (char *)"invalid distance code";
+                state->mode = BAD;
+                break;
+            }
+        }
+        else if ((op & 64) == 0) {              /* 2nd level length code */
+            here = lcode[here.val + (hold & ((1U << op) - 1))];
+            goto dolen;
+        }
+        else if (op & 32) {                     /* end-of-block */
+            Tracevv((stderr, "inflate:         end of block\n"));
+            state->mode = TYPE;
+            break;
+        }
+        else {
+            strm->msg = (char *)"invalid literal/length code";
+            state->mode = BAD;
+            break;
+        }
+    } while (in < last && out < end);
+
+    /* return unused bytes (on entry, bits < 8, so in won't go too far back) */
+    len = bits >> 3;
+    in -= len;
+    bits -= len << 3;
+    hold &= (1U << bits) - 1;
+
+    /* update state and return */
+    strm->next_in = in + OFF;
+    strm->next_out = out + OFF;
+    strm->avail_in = (unsigned)(in < last ? 5 + (last - in) : 5 - (in - last));
+    strm->avail_out = (unsigned)(out < end ?
+                                 257 + (end - out) : 257 - (out - end));
+    state->hold = hold;
+    state->bits = bits;
+    return;
+}
+
+/*
+   inflate_fast() speedups that turned out slower (on a PowerPC G3 750CXe):
+   - Using bit fields for code structure
+   - Different op definition to avoid & for extra bits (do & for table bits)
+   - Three separate decoding do-loops for direct, window, and wnext == 0
+   - Special case for distance > 1 copies to do overlapped load and store copy
+   - Explicit branch predictions (based on measured branch probabilities)
+   - Deferring match copy and interspersed it with decoding subsequent codes
+   - Swapping literal/length else
+   - Swapping window/direct else
+   - Larger unrolled copy loops (three is about right)
+   - Moving len -= 3 statement into middle of loop
+ */
+
+#endif /* !ASMINF */
diff --git a/compat/zlib/inffast.h b/compat/zlib/inffast.h
new file mode 100644
index 0000000..e5c1aa4
--- /dev/null
+++ b/compat/zlib/inffast.h
@@ -0,0 +1,11 @@
+/* inffast.h -- header to use inffast.c
+ * Copyright (C) 1995-2003, 2010 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+   part of the implementation of the compression library and is
+   subject to change. Applications should only use zlib.h.
+ */
+
+void ZLIB_INTERNAL inflate_fast OF((z_streamp strm, unsigned start));
diff --git a/compat/zlib/inffixed.h b/compat/zlib/inffixed.h
new file mode 100644
index 0000000..d628327
--- /dev/null
+++ b/compat/zlib/inffixed.h
@@ -0,0 +1,94 @@
+    /* inffixed.h -- table for decoding fixed codes
+     * Generated automatically by makefixed().
+     */
+
+    /* WARNING: this file should *not* be used by applications.
+       It is part of the implementation of this library and is
+       subject to change. Applications should only use zlib.h.
+     */
+
+    static const code lenfix[512] = {
+        {96,7,0},{0,8,80},{0,8,16},{20,8,115},{18,7,31},{0,8,112},{0,8,48},
+        {0,9,192},{16,7,10},{0,8,96},{0,8,32},{0,9,160},{0,8,0},{0,8,128},
+        {0,8,64},{0,9,224},{16,7,6},{0,8,88},{0,8,24},{0,9,144},{19,7,59},
+        {0,8,120},{0,8,56},{0,9,208},{17,7,17},{0,8,104},{0,8,40},{0,9,176},
+        {0,8,8},{0,8,136},{0,8,72},{0,9,240},{16,7,4},{0,8,84},{0,8,20},
+        {21,8,227},{19,7,43},{0,8,116},{0,8,52},{0,9,200},{17,7,13},{0,8,100},
+        {0,8,36},{0,9,168},{0,8,4},{0,8,132},{0,8,68},{0,9,232},{16,7,8},
+        {0,8,92},{0,8,28},{0,9,152},{20,7,83},{0,8,124},{0,8,60},{0,9,216},
+        {18,7,23},{0,8,108},{0,8,44},{0,9,184},{0,8,12},{0,8,140},{0,8,76},
+        {0,9,248},{16,7,3},{0,8,82},{0,8,18},{21,8,163},{19,7,35},{0,8,114},
+        {0,8,50},{0,9,196},{17,7,11},{0,8,98},{0,8,34},{0,9,164},{0,8,2},
+        {0,8,130},{0,8,66},{0,9,228},{16,7,7},{0,8,90},{0,8,26},{0,9,148},
+        {20,7,67},{0,8,122},{0,8,58},{0,9,212},{18,7,19},{0,8,106},{0,8,42},
+        {0,9,180},{0,8,10},{0,8,138},{0,8,74},{0,9,244},{16,7,5},{0,8,86},
+        {0,8,22},{64,8,0},{19,7,51},{0,8,118},{0,8,54},{0,9,204},{17,7,15},
+        {0,8,102},{0,8,38},{0,9,172},{0,8,6},{0,8,134},{0,8,70},{0,9,236},
+        {16,7,9},{0,8,94},{0,8,30},{0,9,156},{20,7,99},{0,8,126},{0,8,62},
+        {0,9,220},{18,7,27},{0,8,110},{0,8,46},{0,9,188},{0,8,14},{0,8,142},
+        {0,8,78},{0,9,252},{96,7,0},{0,8,81},{0,8,17},{21,8,131},{18,7,31},
+        {0,8,113},{0,8,49},{0,9,194},{16,7,10},{0,8,97},{0,8,33},{0,9,162},
+        {0,8,1},{0,8,129},{0,8,65},{0,9,226},{16,7,6},{0,8,89},{0,8,25},
+        {0,9,146},{19,7,59},{0,8,121},{0,8,57},{0,9,210},{17,7,17},{0,8,105},
+        {0,8,41},{0,9,178},{0,8,9},{0,8,137},{0,8,73},{0,9,242},{16,7,4},
+        {0,8,85},{0,8,21},{16,8,258},{19,7,43},{0,8,117},{0,8,53},{0,9,202},
+        {17,7,13},{0,8,101},{0,8,37},{0,9,170},{0,8,5},{0,8,133},{0,8,69},
+        {0,9,234},{16,7,8},{0,8,93},{0,8,29},{0,9,154},{20,7,83},{0,8,125},
+        {0,8,61},{0,9,218},{18,7,23},{0,8,109},{0,8,45},{0,9,186},{0,8,13},
+        {0,8,141},{0,8,77},{0,9,250},{16,7,3},{0,8,83},{0,8,19},{21,8,195},
+        {19,7,35},{0,8,115},{0,8,51},{0,9,198},{17,7,11},{0,8,99},{0,8,35},
+        {0,9,166},{0,8,3},{0,8,131},{0,8,67},{0,9,230},{16,7,7},{0,8,91},
+        {0,8,27},{0,9,150},{20,7,67},{0,8,123},{0,8,59},{0,9,214},{18,7,19},
+        {0,8,107},{0,8,43},{0,9,182},{0,8,11},{0,8,139},{0,8,75},{0,9,246},
+        {16,7,5},{0,8,87},{0,8,23},{64,8,0},{19,7,51},{0,8,119},{0,8,55},
+        {0,9,206},{17,7,15},{0,8,103},{0,8,39},{0,9,174},{0,8,7},{0,8,135},
+        {0,8,71},{0,9,238},{16,7,9},{0,8,95},{0,8,31},{0,9,158},{20,7,99},
+        {0,8,127},{0,8,63},{0,9,222},{18,7,27},{0,8,111},{0,8,47},{0,9,190},
+        {0,8,15},{0,8,143},{0,8,79},{0,9,254},{96,7,0},{0,8,80},{0,8,16},
+        {20,8,115},{18,7,31},{0,8,112},{0,8,48},{0,9,193},{16,7,10},{0,8,96},
+        {0,8,32},{0,9,161},{0,8,0},{0,8,128},{0,8,64},{0,9,225},{16,7,6},
+        {0,8,88},{0,8,24},{0,9,145},{19,7,59},{0,8,120},{0,8,56},{0,9,209},
+        {17,7,17},{0,8,104},{0,8,40},{0,9,177},{0,8,8},{0,8,136},{0,8,72},
+        {0,9,241},{16,7,4},{0,8,84},{0,8,20},{21,8,227},{19,7,43},{0,8,116},
+        {0,8,52},{0,9,201},{17,7,13},{0,8,100},{0,8,36},{0,9,169},{0,8,4},
+        {0,8,132},{0,8,68},{0,9,233},{16,7,8},{0,8,92},{0,8,28},{0,9,153},
+        {20,7,83},{0,8,124},{0,8,60},{0,9,217},{18,7,23},{0,8,108},{0,8,44},
+        {0,9,185},{0,8,12},{0,8,140},{0,8,76},{0,9,249},{16,7,3},{0,8,82},
+        {0,8,18},{21,8,163},{19,7,35},{0,8,114},{0,8,50},{0,9,197},{17,7,11},
+        {0,8,98},{0,8,34},{0,9,165},{0,8,2},{0,8,130},{0,8,66},{0,9,229},
+        {16,7,7},{0,8,90},{0,8,26},{0,9,149},{20,7,67},{0,8,122},{0,8,58},
+        {0,9,213},{18,7,19},{0,8,106},{0,8,42},{0,9,181},{0,8,10},{0,8,138},
+        {0,8,74},{0,9,245},{16,7,5},{0,8,86},{0,8,22},{64,8,0},{19,7,51},
+        {0,8,118},{0,8,54},{0,9,205},{17,7,15},{0,8,102},{0,8,38},{0,9,173},
+        {0,8,6},{0,8,134},{0,8,70},{0,9,237},{16,7,9},{0,8,94},{0,8,30},
+        {0,9,157},{20,7,99},{0,8,126},{0,8,62},{0,9,221},{18,7,27},{0,8,110},
+        {0,8,46},{0,9,189},{0,8,14},{0,8,142},{0,8,78},{0,9,253},{96,7,0},
+        {0,8,81},{0,8,17},{21,8,131},{18,7,31},{0,8,113},{0,8,49},{0,9,195},
+        {16,7,10},{0,8,97},{0,8,33},{0,9,163},{0,8,1},{0,8,129},{0,8,65},
+        {0,9,227},{16,7,6},{0,8,89},{0,8,25},{0,9,147},{19,7,59},{0,8,121},
+        {0,8,57},{0,9,211},{17,7,17},{0,8,105},{0,8,41},{0,9,179},{0,8,9},
+        {0,8,137},{0,8,73},{0,9,243},{16,7,4},{0,8,85},{0,8,21},{16,8,258},
+        {19,7,43},{0,8,117},{0,8,53},{0,9,203},{17,7,13},{0,8,101},{0,8,37},
+        {0,9,171},{0,8,5},{0,8,133},{0,8,69},{0,9,235},{16,7,8},{0,8,93},
+        {0,8,29},{0,9,155},{20,7,83},{0,8,125},{0,8,61},{0,9,219},{18,7,23},
+        {0,8,109},{0,8,45},{0,9,187},{0,8,13},{0,8,141},{0,8,77},{0,9,251},
+        {16,7,3},{0,8,83},{0,8,19},{21,8,195},{19,7,35},{0,8,115},{0,8,51},
+        {0,9,199},{17,7,11},{0,8,99},{0,8,35},{0,9,167},{0,8,3},{0,8,131},
+        {0,8,67},{0,9,231},{16,7,7},{0,8,91},{0,8,27},{0,9,151},{20,7,67},
+        {0,8,123},{0,8,59},{0,9,215},{18,7,19},{0,8,107},{0,8,43},{0,9,183},
+        {0,8,11},{0,8,139},{0,8,75},{0,9,247},{16,7,5},{0,8,87},{0,8,23},
+        {64,8,0},{19,7,51},{0,8,119},{0,8,55},{0,9,207},{17,7,15},{0,8,103},
+        {0,8,39},{0,9,175},{0,8,7},{0,8,135},{0,8,71},{0,9,239},{16,7,9},
+        {0,8,95},{0,8,31},{0,9,159},{20,7,99},{0,8,127},{0,8,63},{0,9,223},
+        {18,7,27},{0,8,111},{0,8,47},{0,9,191},{0,8,15},{0,8,143},{0,8,79},
+        {0,9,255}
+    };
+
+    static const code distfix[32] = {
+        {16,5,1},{23,5,257},{19,5,17},{27,5,4097},{17,5,5},{25,5,1025},
+        {21,5,65},{29,5,16385},{16,5,3},{24,5,513},{20,5,33},{28,5,8193},
+        {18,5,9},{26,5,2049},{22,5,129},{64,5,0},{16,5,2},{23,5,385},
+        {19,5,25},{27,5,6145},{17,5,7},{25,5,1537},{21,5,97},{29,5,24577},
+        {16,5,4},{24,5,769},{20,5,49},{28,5,12289},{18,5,13},{26,5,3073},
+        {22,5,193},{64,5,0}
+    };
diff --git a/compat/zlib/inflate.c b/compat/zlib/inflate.c
new file mode 100644
index 0000000..870f89b
--- /dev/null
+++ b/compat/zlib/inflate.c
@@ -0,0 +1,1512 @@
+/* inflate.c -- zlib decompression
+ * Copyright (C) 1995-2012 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/*
+ * Change history:
+ *
+ * 1.2.beta0    24 Nov 2002
+ * - First version -- complete rewrite of inflate to simplify code, avoid
+ *   creation of window when not needed, minimize use of window when it is
+ *   needed, make inffast.c even faster, implement gzip decoding, and to
+ *   improve code readability and style over the previous zlib inflate code
+ *
+ * 1.2.beta1    25 Nov 2002
+ * - Use pointers for available input and output checking in inffast.c
+ * - Remove input and output counters in inffast.c
+ * - Change inffast.c entry and loop from avail_in >= 7 to >= 6
+ * - Remove unnecessary second byte pull from length extra in inffast.c
+ * - Unroll direct copy to three copies per loop in inffast.c
+ *
+ * 1.2.beta2    4 Dec 2002
+ * - Change external routine names to reduce potential conflicts
+ * - Correct filename to inffixed.h for fixed tables in inflate.c
+ * - Make hbuf[] unsigned char to match parameter type in inflate.c
+ * - Change strm->next_out[-state->offset] to *(strm->next_out - state->offset)
+ *   to avoid negation problem on Alphas (64 bit) in inflate.c
+ *
+ * 1.2.beta3    22 Dec 2002
+ * - Add comments on state->bits assertion in inffast.c
+ * - Add comments on op field in inftrees.h
+ * - Fix bug in reuse of allocated window after inflateReset()
+ * - Remove bit fields--back to byte structure for speed
+ * - Remove distance extra == 0 check in inflate_fast()--only helps for lengths
+ * - Change post-increments to pre-increments in inflate_fast(), PPC biased?
+ * - Add compile time option, POSTINC, to use post-increments instead (Intel?)
+ * - Make MATCH copy in inflate() much faster for when inflate_fast() not used
+ * - Use local copies of stream next and avail values, as well as local bit
+ *   buffer and bit count in inflate()--for speed when inflate_fast() not used
+ *
+ * 1.2.beta4    1 Jan 2003
+ * - Split ptr - 257 statements in inflate_table() to avoid compiler warnings
+ * - Move a comment on output buffer sizes from inffast.c to inflate.c
+ * - Add comments in inffast.c to introduce the inflate_fast() routine
+ * - Rearrange window copies in inflate_fast() for speed and simplification
+ * - Unroll last copy for window match in inflate_fast()
+ * - Use local copies of window variables in inflate_fast() for speed
+ * - Pull out common wnext == 0 case for speed in inflate_fast()
+ * - Make op and len in inflate_fast() unsigned for consistency
+ * - Add FAR to lcode and dcode declarations in inflate_fast()
+ * - Simplified bad distance check in inflate_fast()
+ * - Added inflateBackInit(), inflateBack(), and inflateBackEnd() in new
+ *   source file infback.c to provide a call-back interface to inflate for
+ *   programs like gzip and unzip -- uses window as output buffer to avoid
+ *   window copying
+ *
+ * 1.2.beta5    1 Jan 2003
+ * - Improved inflateBack() interface to allow the caller to provide initial
+ *   input in strm.
+ * - Fixed stored blocks bug in inflateBack()
+ *
+ * 1.2.beta6    4 Jan 2003
+ * - Added comments in inffast.c on effectiveness of POSTINC
+ * - Typecasting all around to reduce compiler warnings
+ * - Changed loops from while (1) or do {} while (1) to for (;;), again to
+ *   make compilers happy
+ * - Changed type of window in inflateBackInit() to unsigned char *
+ *
+ * 1.2.beta7    27 Jan 2003
+ * - Changed many types to unsigned or unsigned short to avoid warnings
+ * - Added inflateCopy() function
+ *
+ * 1.2.0        9 Mar 2003
+ * - Changed inflateBack() interface to provide separate opaque descriptors
+ *   for the in() and out() functions
+ * - Changed inflateBack() argument and in_func typedef to swap the length
+ *   and buffer address return values for the input function
+ * - Check next_in and next_out for Z_NULL on entry to inflate()
+ *
+ * The history for versions after 1.2.0 are in ChangeLog in zlib distribution.
+ */
+
+#include "zutil.h"
+#include "inftrees.h"
+#include "inflate.h"
+#include "inffast.h"
+
+#ifdef MAKEFIXED
+#  ifndef BUILDFIXED
+#    define BUILDFIXED
+#  endif
+#endif
+
+/* function prototypes */
+local void fixedtables OF((struct inflate_state FAR *state));
+local int updatewindow OF((z_streamp strm, const unsigned char FAR *end,
+                           unsigned copy));
+#ifdef BUILDFIXED
+   void makefixed OF((void));
+#endif
+local unsigned syncsearch OF((unsigned FAR *have, const unsigned char FAR *buf,
+                              unsigned len));
+
+int ZEXPORT inflateResetKeep(strm)
+z_streamp strm;
+{
+    struct inflate_state FAR *state;
+
+    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+    state = (struct inflate_state FAR *)strm->state;
+    strm->total_in = strm->total_out = state->total = 0;
+    strm->msg = Z_NULL;
+    if (state->wrap)        /* to support ill-conceived Java test suite */
+        strm->adler = state->wrap & 1;
+    state->mode = HEAD;
+    state->last = 0;
+    state->havedict = 0;
+    state->dmax = 32768U;
+    state->head = Z_NULL;
+    state->hold = 0;
+    state->bits = 0;
+    state->lencode = state->distcode = state->next = state->codes;
+    state->sane = 1;
+    state->back = -1;
+    Tracev((stderr, "inflate: reset\n"));
+    return Z_OK;
+}
+
+int ZEXPORT inflateReset(strm)
+z_streamp strm;
+{
+    struct inflate_state FAR *state;
+
+    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+    state = (struct inflate_state FAR *)strm->state;
+    state->wsize = 0;
+    state->whave = 0;
+    state->wnext = 0;
+    return inflateResetKeep(strm);
+}
+
+int ZEXPORT inflateReset2(strm, windowBits)
+z_streamp strm;
+int windowBits;
+{
+    int wrap;
+    struct inflate_state FAR *state;
+
+    /* get the state */
+    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+    state = (struct inflate_state FAR *)strm->state;
+
+    /* extract wrap request from windowBits parameter */
+    if (windowBits < 0) {
+        wrap = 0;
+        windowBits = -windowBits;
+    }
+    else {
+        wrap = (windowBits >> 4) + 1;
+#ifdef GUNZIP
+        if (windowBits < 48)
+            windowBits &= 15;
+#endif
+    }
+
+    /* set number of window bits, free window if different */
+    if (windowBits && (windowBits < 8 || windowBits > 15))
+        return Z_STREAM_ERROR;
+    if (state->window != Z_NULL && state->wbits != (unsigned)windowBits) {
+        ZFREE(strm, state->window);
+        state->window = Z_NULL;
+    }
+
+    /* update state and reset the rest of it */
+    state->wrap = wrap;
+    state->wbits = (unsigned)windowBits;
+    return inflateReset(strm);
+}
+
+int ZEXPORT inflateInit2_(strm, windowBits, version, stream_size)
+z_streamp strm;
+int windowBits;
+const char *version;
+int stream_size;
+{
+    int ret;
+    struct inflate_state FAR *state;
+
+    if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
+        stream_size != (int)(sizeof(z_stream)))
+        return Z_VERSION_ERROR;
+    if (strm == Z_NULL) return Z_STREAM_ERROR;
+    strm->msg = Z_NULL;                 /* in case we return an error */
+    if (strm->zalloc == (alloc_func)0) {
+#ifdef Z_SOLO
+        return Z_STREAM_ERROR;
+#else
+        strm->zalloc = zcalloc;
+        strm->opaque = (voidpf)0;
+#endif
+    }
+    if (strm->zfree == (free_func)0)
+#ifdef Z_SOLO
+        return Z_STREAM_ERROR;
+#else
+        strm->zfree = zcfree;
+#endif
+    state = (struct inflate_state FAR *)
+            ZALLOC(strm, 1, sizeof(struct inflate_state));
+    if (state == Z_NULL) return Z_MEM_ERROR;
+    Tracev((stderr, "inflate: allocated\n"));
+    strm->state = (struct internal_state FAR *)state;
+    state->window = Z_NULL;
+    ret = inflateReset2(strm, windowBits);
+    if (ret != Z_OK) {
+        ZFREE(strm, state);
+        strm->state = Z_NULL;
+    }
+    return ret;
+}
+
+int ZEXPORT inflateInit_(strm, version, stream_size)
+z_streamp strm;
+const char *version;
+int stream_size;
+{
+    return inflateInit2_(strm, DEF_WBITS, version, stream_size);
+}
+
+int ZEXPORT inflatePrime(strm, bits, value)
+z_streamp strm;
+int bits;
+int value;
+{
+    struct inflate_state FAR *state;
+
+    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+    state = (struct inflate_state FAR *)strm->state;
+    if (bits < 0) {
+        state->hold = 0;
+        state->bits = 0;
+        return Z_OK;
+    }
+    if (bits > 16 || state->bits + bits > 32) return Z_STREAM_ERROR;
+    value &= (1L << bits) - 1;
+    state->hold += value << state->bits;
+    state->bits += bits;
+    return Z_OK;
+}
+
+/*
+   Return state with length and distance decoding tables and index sizes set to
+   fixed code decoding.  Normally this returns fixed tables from inffixed.h.
+   If BUILDFIXED is defined, then instead this routine builds the tables the
+   first time it's called, and returns those tables the first time and
+   thereafter.  This reduces the size of the code by about 2K bytes, in
+   exchange for a little execution time.  However, BUILDFIXED should not be
+   used for threaded applications, since the rewriting of the tables and virgin
+   may not be thread-safe.
+ */
+local void fixedtables(state)
+struct inflate_state FAR *state;
+{
+#ifdef BUILDFIXED
+    static int virgin = 1;
+    static code *lenfix, *distfix;
+    static code fixed[544];
+
+    /* build fixed huffman tables if first call (may not be thread safe) */
+    if (virgin) {
+        unsigned sym, bits;
+        static code *next;
+
+        /* literal/length table */
+        sym = 0;
+        while (sym < 144) state->lens[sym++] = 8;
+        while (sym < 256) state->lens[sym++] = 9;
+        while (sym < 280) state->lens[sym++] = 7;
+        while (sym < 288) state->lens[sym++] = 8;
+        next = fixed;
+        lenfix = next;
+        bits = 9;
+        inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work);
+
+        /* distance table */
+        sym = 0;
+        while (sym < 32) state->lens[sym++] = 5;
+        distfix = next;
+        bits = 5;
+        inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work);
+
+        /* do this just once */
+        virgin = 0;
+    }
+#else /* !BUILDFIXED */
+#   include "inffixed.h"
+#endif /* BUILDFIXED */
+    state->lencode = lenfix;
+    state->lenbits = 9;
+    state->distcode = distfix;
+    state->distbits = 5;
+}
+
+#ifdef MAKEFIXED
+#include <stdio.h>
+
+/*
+   Write out the inffixed.h that is #include'd above.  Defining MAKEFIXED also
+   defines BUILDFIXED, so the tables are built on the fly.  makefixed() writes
+   those tables to stdout, which would be piped to inffixed.h.  A small program
+   can simply call makefixed to do this:
+
+    void makefixed(void);
+
+    int main(void)
+    {
+        makefixed();
+        return 0;
+    }
+
+   Then that can be linked with zlib built with MAKEFIXED defined and run:
+
+    a.out > inffixed.h
+ */
+void makefixed()
+{
+    unsigned low, size;
+    struct inflate_state state;
+
+    fixedtables(&state);
+    puts("    /* inffixed.h -- table for decoding fixed codes");
+    puts("     * Generated automatically by makefixed().");
+    puts("     */");
+    puts("");
+    puts("    /* WARNING: this file should *not* be used by applications.");
+    puts("       It is part of the implementation of this library and is");
+    puts("       subject to change. Applications should only use zlib.h.");
+    puts("     */");
+    puts("");
+    size = 1U << 9;
+    printf("    static const code lenfix[%u] = {", size);
+    low = 0;
+    for (;;) {
+        if ((low % 7) == 0) printf("\n        ");
+        printf("{%u,%u,%d}", (low & 127) == 99 ? 64 : state.lencode[low].op,
+               state.lencode[low].bits, state.lencode[low].val);
+        if (++low == size) break;
+        putchar(',');
+    }
+    puts("\n    };");
+    size = 1U << 5;
+    printf("\n    static const code distfix[%u] = {", size);
+    low = 0;
+    for (;;) {
+        if ((low % 6) == 0) printf("\n        ");
+        printf("{%u,%u,%d}", state.distcode[low].op, state.distcode[low].bits,
+               state.distcode[low].val);
+        if (++low == size) break;
+        putchar(',');
+    }
+    puts("\n    };");
+}
+#endif /* MAKEFIXED */
+
+/*
+   Update the window with the last wsize (normally 32K) bytes written before
+   returning.  If window does not exist yet, create it.  This is only called
+   when a window is already in use, or when output has been written during this
+   inflate call, but the end of the deflate stream has not been reached yet.
+   It is also called to create a window for dictionary data when a dictionary
+   is loaded.
+
+   Providing output buffers larger than 32K to inflate() should provide a speed
+   advantage, since only the last 32K of output is copied to the sliding window
+   upon return from inflate(), and since all distances after the first 32K of
+   output will fall in the output data, making match copies simpler and faster.
+   The advantage may be dependent on the size of the processor's data caches.
+ */
+local int updatewindow(strm, end, copy)
+z_streamp strm;
+const Bytef *end;
+unsigned copy;
+{
+    struct inflate_state FAR *state;
+    unsigned dist;
+
+    state = (struct inflate_state FAR *)strm->state;
+
+    /* if it hasn't been done already, allocate space for the window */
+    if (state->window == Z_NULL) {
+        state->window = (unsigned char FAR *)
+                        ZALLOC(strm, 1U << state->wbits,
+                               sizeof(unsigned char));
+        if (state->window == Z_NULL) return 1;
+    }
+
+    /* if window not in use yet, initialize */
+    if (state->wsize == 0) {
+        state->wsize = 1U << state->wbits;
+        state->wnext = 0;
+        state->whave = 0;
+    }
+
+    /* copy state->wsize or less output bytes into the circular window */
+    if (copy >= state->wsize) {
+        zmemcpy(state->window, end - state->wsize, state->wsize);
+        state->wnext = 0;
+        state->whave = state->wsize;
+    }
+    else {
+        dist = state->wsize - state->wnext;
+        if (dist > copy) dist = copy;
+        zmemcpy(state->window + state->wnext, end - copy, dist);
+        copy -= dist;
+        if (copy) {
+            zmemcpy(state->window, end - copy, copy);
+            state->wnext = copy;
+            state->whave = state->wsize;
+        }
+        else {
+            state->wnext += dist;
+            if (state->wnext == state->wsize) state->wnext = 0;
+            if (state->whave < state->wsize) state->whave += dist;
+        }
+    }
+    return 0;
+}
+
+/* Macros for inflate(): */
+
+/* check function to use adler32() for zlib or crc32() for gzip */
+#ifdef GUNZIP
+#  define UPDATE(check, buf, len) \
+    (state->flags ? crc32(check, buf, len) : adler32(check, buf, len))
+#else
+#  define UPDATE(check, buf, len) adler32(check, buf, len)
+#endif
+
+/* check macros for header crc */
+#ifdef GUNZIP
+#  define CRC2(check, word) \
+    do { \
+        hbuf[0] = (unsigned char)(word); \
+        hbuf[1] = (unsigned char)((word) >> 8); \
+        check = crc32(check, hbuf, 2); \
+    } while (0)
+
+#  define CRC4(check, word) \
+    do { \
+        hbuf[0] = (unsigned char)(word); \
+        hbuf[1] = (unsigned char)((word) >> 8); \
+        hbuf[2] = (unsigned char)((word) >> 16); \
+        hbuf[3] = (unsigned char)((word) >> 24); \
+        check = crc32(check, hbuf, 4); \
+    } while (0)
+#endif
+
+/* Load registers with state in inflate() for speed */
+#define LOAD() \
+    do { \
+        put = strm->next_out; \
+        left = strm->avail_out; \
+        next = strm->next_in; \
+        have = strm->avail_in; \
+        hold = state->hold; \
+        bits = state->bits; \
+    } while (0)
+
+/* Restore state from registers in inflate() */
+#define RESTORE() \
+    do { \
+        strm->next_out = put; \
+        strm->avail_out = left; \
+        strm->next_in = next; \
+        strm->avail_in = have; \
+        state->hold = hold; \
+        state->bits = bits; \
+    } while (0)
+
+/* Clear the input bit accumulator */
+#define INITBITS() \
+    do { \
+        hold = 0; \
+        bits = 0; \
+    } while (0)
+
+/* Get a byte of input into the bit accumulator, or return from inflate()
+   if there is no input available. */
+#define PULLBYTE() \
+    do { \
+        if (have == 0) goto inf_leave; \
+        have--; \
+        hold += (unsigned long)(*next++) << bits; \
+        bits += 8; \
+    } while (0)
+
+/* Assure that there are at least n bits in the bit accumulator.  If there is
+   not enough available input to do that, then return from inflate(). */
+#define NEEDBITS(n) \
+    do { \
+        while (bits < (unsigned)(n)) \
+            PULLBYTE(); \
+    } while (0)
+
+/* Return the low n bits of the bit accumulator (n < 16) */
+#define BITS(n) \
+    ((unsigned)hold & ((1U << (n)) - 1))
+
+/* Remove n bits from the bit accumulator */
+#define DROPBITS(n) \
+    do { \
+        hold >>= (n); \
+        bits -= (unsigned)(n); \
+    } while (0)
+
+/* Remove zero to seven bits as needed to go to a byte boundary */
+#define BYTEBITS() \
+    do { \
+        hold >>= bits & 7; \
+        bits -= bits & 7; \
+    } while (0)
+
+/*
+   inflate() uses a state machine to process as much input data and generate as
+   much output data as possible before returning.  The state machine is
+   structured roughly as follows:
+
+    for (;;) switch (state) {
+    ...
+    case STATEn:
+        if (not enough input data or output space to make progress)
+            return;
+        ... make progress ...
+        state = STATEm;
+        break;
+    ...
+    }
+
+   so when inflate() is called again, the same case is attempted again, and
+   if the appropriate resources are provided, the machine proceeds to the
+   next state.  The NEEDBITS() macro is usually the way the state evaluates
+   whether it can proceed or should return.  NEEDBITS() does the return if
+   the requested bits are not available.  The typical use of the BITS macros
+   is:
+
+        NEEDBITS(n);
+        ... do something with BITS(n) ...
+        DROPBITS(n);
+
+   where NEEDBITS(n) either returns from inflate() if there isn't enough
+   input left to load n bits into the accumulator, or it continues.  BITS(n)
+   gives the low n bits in the accumulator.  When done, DROPBITS(n) drops
+   the low n bits off the accumulator.  INITBITS() clears the accumulator
+   and sets the number of available bits to zero.  BYTEBITS() discards just
+   enough bits to put the accumulator on a byte boundary.  After BYTEBITS()
+   and a NEEDBITS(8), then BITS(8) would return the next byte in the stream.
+
+   NEEDBITS(n) uses PULLBYTE() to get an available byte of input, or to return
+   if there is no input available.  The decoding of variable length codes uses
+   PULLBYTE() directly in order to pull just enough bytes to decode the next
+   code, and no more.
+
+   Some states loop until they get enough input, making sure that enough
+   state information is maintained to continue the loop where it left off
+   if NEEDBITS() returns in the loop.  For example, want, need, and keep
+   would all have to actually be part of the saved state in case NEEDBITS()
+   returns:
+
+    case STATEw:
+        while (want < need) {
+            NEEDBITS(n);
+            keep[want++] = BITS(n);
+            DROPBITS(n);
+        }
+        state = STATEx;
+    case STATEx:
+
+   As shown above, if the next state is also the next case, then the break
+   is omitted.
+
+   A state may also return if there is not enough output space available to
+   complete that state.  Those states are copying stored data, writing a
+   literal byte, and copying a matching string.
+
+   When returning, a "goto inf_leave" is used to update the total counters,
+   update the check value, and determine whether any progress has been made
+   during that inflate() call in order to return the proper return code.
+   Progress is defined as a change in either strm->avail_in or strm->avail_out.
+   When there is a window, goto inf_leave will update the window with the last
+   output written.  If a goto inf_leave occurs in the middle of decompression
+   and there is no window currently, goto inf_leave will create one and copy
+   output to the window for the next call of inflate().
+
+   In this implementation, the flush parameter of inflate() only affects the
+   return code (per zlib.h).  inflate() always writes as much as possible to
+   strm->next_out, given the space available and the provided input--the effect
+   documented in zlib.h of Z_SYNC_FLUSH.  Furthermore, inflate() always defers
+   the allocation of and copying into a sliding window until necessary, which
+   provides the effect documented in zlib.h for Z_FINISH when the entire input
+   stream available.  So the only thing the flush parameter actually does is:
+   when flush is set to Z_FINISH, inflate() cannot return Z_OK.  Instead it
+   will return Z_BUF_ERROR if it has not reached the end of the stream.
+ */
+
+int ZEXPORT inflate(strm, flush)
+z_streamp strm;
+int flush;
+{
+    struct inflate_state FAR *state;
+    z_const unsigned char FAR *next;    /* next input */
+    unsigned char FAR *put;     /* next output */
+    unsigned have, left;        /* available input and output */
+    unsigned long hold;         /* bit buffer */
+    unsigned bits;              /* bits in bit buffer */
+    unsigned in, out;           /* save starting available input and output */
+    unsigned copy;              /* number of stored or match bytes to copy */
+    unsigned char FAR *from;    /* where to copy match bytes from */
+    code here;                  /* current decoding table entry */
+    code last;                  /* parent table entry */
+    unsigned len;               /* length to copy for repeats, bits to drop */
+    int ret;                    /* return code */
+#ifdef GUNZIP
+    unsigned char hbuf[4];      /* buffer for gzip header crc calculation */
+#endif
+    static const unsigned short order[19] = /* permutation of code lengths */
+        {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
+
+    if (strm == Z_NULL || strm->state == Z_NULL || strm->next_out == Z_NULL ||
+        (strm->next_in == Z_NULL && strm->avail_in != 0))
+        return Z_STREAM_ERROR;
+
+    state = (struct inflate_state FAR *)strm->state;
+    if (state->mode == TYPE) state->mode = TYPEDO;      /* skip check */
+    LOAD();
+    in = have;
+    out = left;
+    ret = Z_OK;
+    for (;;)
+        switch (state->mode) {
+        case HEAD:
+            if (state->wrap == 0) {
+                state->mode = TYPEDO;
+                break;
+            }
+            NEEDBITS(16);
+#ifdef GUNZIP
+            if ((state->wrap & 2) && hold == 0x8b1f) {  /* gzip header */
+                state->check = crc32(0L, Z_NULL, 0);
+                CRC2(state->check, hold);
+                INITBITS();
+                state->mode = FLAGS;
+                break;
+            }
+            state->flags = 0;           /* expect zlib header */
+            if (state->head != Z_NULL)
+                state->head->done = -1;
+            if (!(state->wrap & 1) ||   /* check if zlib header allowed */
+#else
+            if (
+#endif
+                ((BITS(8) << 8) + (hold >> 8)) % 31) {
+                strm->msg = (char *)"incorrect header check";
+                state->mode = BAD;
+                break;
+            }
+            if (BITS(4) != Z_DEFLATED) {
+                strm->msg = (char *)"unknown compression method";
+                state->mode = BAD;
+                break;
+            }
+            DROPBITS(4);
+            len = BITS(4) + 8;
+            if (state->wbits == 0)
+                state->wbits = len;
+            else if (len > state->wbits) {
+                strm->msg = (char *)"invalid window size";
+                state->mode = BAD;
+                break;
+            }
+            state->dmax = 1U << len;
+            Tracev((stderr, "inflate:   zlib header ok\n"));
+            strm->adler = state->check = adler32(0L, Z_NULL, 0);
+            state->mode = hold & 0x200 ? DICTID : TYPE;
+            INITBITS();
+            break;
+#ifdef GUNZIP
+        case FLAGS:
+            NEEDBITS(16);
+            state->flags = (int)(hold);
+            if ((state->flags & 0xff) != Z_DEFLATED) {
+                strm->msg = (char *)"unknown compression method";
+                state->mode = BAD;
+                break;
+            }
+            if (state->flags & 0xe000) {
+                strm->msg = (char *)"unknown header flags set";
+                state->mode = BAD;
+                break;
+            }
+            if (state->head != Z_NULL)
+                state->head->text = (int)((hold >> 8) & 1);
+            if (state->flags & 0x0200) CRC2(state->check, hold);
+            INITBITS();
+            state->mode = TIME;
+        case TIME:
+            NEEDBITS(32);
+            if (state->head != Z_NULL)
+                state->head->time = hold;
+            if (state->flags & 0x0200) CRC4(state->check, hold);
+            INITBITS();
+            state->mode = OS;
+        case OS:
+            NEEDBITS(16);
+            if (state->head != Z_NULL) {
+                state->head->xflags = (int)(hold & 0xff);
+                state->head->os = (int)(hold >> 8);
+            }
+            if (state->flags & 0x0200) CRC2(state->check, hold);
+            INITBITS();
+            state->mode = EXLEN;
+        case EXLEN:
+            if (state->flags & 0x0400) {
+                NEEDBITS(16);
+                state->length = (unsigned)(hold);
+                if (state->head != Z_NULL)
+                    state->head->extra_len = (unsigned)hold;
+                if (state->flags & 0x0200) CRC2(state->check, hold);
+                INITBITS();
+            }
+            else if (state->head != Z_NULL)
+                state->head->extra = Z_NULL;
+            state->mode = EXTRA;
+        case EXTRA:
+            if (state->flags & 0x0400) {
+                copy = state->length;
+                if (copy > have) copy = have;
+                if (copy) {
+                    if (state->head != Z_NULL &&
+                        state->head->extra != Z_NULL) {
+                        len = state->head->extra_len - state->length;
+                        zmemcpy(state->head->extra + len, next,
+                                len + copy > state->head->extra_max ?
+                                state->head->extra_max - len : copy);
+                    }
+                    if (state->flags & 0x0200)
+                        state->check = crc32(state->check, next, copy);
+                    have -= copy;
+                    next += copy;
+                    state->length -= copy;
+                }
+                if (state->length) goto inf_leave;
+            }
+            state->length = 0;
+            state->mode = NAME;
+        case NAME:
+            if (state->flags & 0x0800) {
+                if (have == 0) goto inf_leave;
+                copy = 0;
+                do {
+                    len = (unsigned)(next[copy++]);
+                    if (state->head != Z_NULL &&
+                            state->head->name != Z_NULL &&
+                            state->length < state->head->name_max)
+                        state->head->name[state->length++] = len;
+                } while (len && copy < have);
+                if (state->flags & 0x0200)
+                    state->check = crc32(state->check, next, copy);
+                have -= copy;
+                next += copy;
+                if (len) goto inf_leave;
+            }
+            else if (state->head != Z_NULL)
+                state->head->name = Z_NULL;
+            state->length = 0;
+            state->mode = COMMENT;
+        case COMMENT:
+            if (state->flags & 0x1000) {
+                if (have == 0) goto inf_leave;
+                copy = 0;
+                do {
+                    len = (unsigned)(next[copy++]);
+                    if (state->head != Z_NULL &&
+                            state->head->comment != Z_NULL &&
+                            state->length < state->head->comm_max)
+                        state->head->comment[state->length++] = len;
+                } while (len && copy < have);
+                if (state->flags & 0x0200)
+                    state->check = crc32(state->check, next, copy);
+                have -= copy;
+                next += copy;
+                if (len) goto inf_leave;
+            }
+            else if (state->head != Z_NULL)
+                state->head->comment = Z_NULL;
+            state->mode = HCRC;
+        case HCRC:
+            if (state->flags & 0x0200) {
+                NEEDBITS(16);
+                if (hold != (state->check & 0xffff)) {
+                    strm->msg = (char *)"header crc mismatch";
+                    state->mode = BAD;
+                    break;
+                }
+                INITBITS();
+            }
+            if (state->head != Z_NULL) {
+                state->head->hcrc = (int)((state->flags >> 9) & 1);
+                state->head->done = 1;
+            }
+            strm->adler = state->check = crc32(0L, Z_NULL, 0);
+            state->mode = TYPE;
+            break;
+#endif
+        case DICTID:
+            NEEDBITS(32);
+            strm->adler = state->check = ZSWAP32(hold);
+            INITBITS();
+            state->mode = DICT;
+        case DICT:
+            if (state->havedict == 0) {
+                RESTORE();
+                return Z_NEED_DICT;
+            }
+            strm->adler = state->check = adler32(0L, Z_NULL, 0);
+            state->mode = TYPE;
+        case TYPE:
+            if (flush == Z_BLOCK || flush == Z_TREES) goto inf_leave;
+        case TYPEDO:
+            if (state->last) {
+                BYTEBITS();
+                state->mode = CHECK;
+                break;
+            }
+            NEEDBITS(3);
+            state->last = BITS(1);
+            DROPBITS(1);
+            switch (BITS(2)) {
+            case 0:                             /* stored block */
+                Tracev((stderr, "inflate:     stored block%s\n",
+                        state->last ? " (last)" : ""));
+                state->mode = STORED;
+                break;
+            case 1:                             /* fixed block */
+                fixedtables(state);
+                Tracev((stderr, "inflate:     fixed codes block%s\n",
+                        state->last ? " (last)" : ""));
+                state->mode = LEN_;             /* decode codes */
+                if (flush == Z_TREES) {
+                    DROPBITS(2);
+                    goto inf_leave;
+                }
+                break;
+            case 2:                             /* dynamic block */
+                Tracev((stderr, "inflate:     dynamic codes block%s\n",
+                        state->last ? " (last)" : ""));
+                state->mode = TABLE;
+                break;
+            case 3:
+                strm->msg = (char *)"invalid block type";
+                state->mode = BAD;
+            }
+            DROPBITS(2);
+            break;
+        case STORED:
+            BYTEBITS();                         /* go to byte boundary */
+            NEEDBITS(32);
+            if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) {
+                strm->msg = (char *)"invalid stored block lengths";
+                state->mode = BAD;
+                break;
+            }
+            state->length = (unsigned)hold & 0xffff;
+            Tracev((stderr, "inflate:       stored length %u\n",
+                    state->length));
+            INITBITS();
+            state->mode = COPY_;
+            if (flush == Z_TREES) goto inf_leave;
+        case COPY_:
+            state->mode = COPY;
+        case COPY:
+            copy = state->length;
+            if (copy) {
+                if (copy > have) copy = have;
+                if (copy > left) copy = left;
+                if (copy == 0) goto inf_leave;
+                zmemcpy(put, next, copy);
+                have -= copy;
+                next += copy;
+                left -= copy;
+                put += copy;
+                state->length -= copy;
+                break;
+            }
+            Tracev((stderr, "inflate:       stored end\n"));
+            state->mode = TYPE;
+            break;
+        case TABLE:
+            NEEDBITS(14);
+            state->nlen = BITS(5) + 257;
+            DROPBITS(5);
+            state->ndist = BITS(5) + 1;
+            DROPBITS(5);
+            state->ncode = BITS(4) + 4;
+            DROPBITS(4);
+#ifndef PKZIP_BUG_WORKAROUND
+            if (state->nlen > 286 || state->ndist > 30) {
+                strm->msg = (char *)"too many length or distance symbols";
+                state->mode = BAD;
+                break;
+            }
+#endif
+            Tracev((stderr, "inflate:       table sizes ok\n"));
+            state->have = 0;
+            state->mode = LENLENS;
+        case LENLENS:
+            while (state->have < state->ncode) {
+                NEEDBITS(3);
+                state->lens[order[state->have++]] = (unsigned short)BITS(3);
+                DROPBITS(3);
+            }
+            while (state->have < 19)
+                state->lens[order[state->have++]] = 0;
+            state->next = state->codes;
+            state->lencode = (const code FAR *)(state->next);
+            state->lenbits = 7;
+            ret = inflate_table(CODES, state->lens, 19, &(state->next),
+                                &(state->lenbits), state->work);
+            if (ret) {
+                strm->msg = (char *)"invalid code lengths set";
+                state->mode = BAD;
+                break;
+            }
+            Tracev((stderr, "inflate:       code lengths ok\n"));
+            state->have = 0;
+            state->mode = CODELENS;
+        case CODELENS:
+            while (state->have < state->nlen + state->ndist) {
+                for (;;) {
+                    here = state->lencode[BITS(state->lenbits)];
+                    if ((unsigned)(here.bits) <= bits) break;
+                    PULLBYTE();
+                }
+                if (here.val < 16) {
+                    DROPBITS(here.bits);
+                    state->lens[state->have++] = here.val;
+                }
+                else {
+                    if (here.val == 16) {
+                        NEEDBITS(here.bits + 2);
+                        DROPBITS(here.bits);
+                        if (state->have == 0) {
+                            strm->msg = (char *)"invalid bit length repeat";
+                            state->mode = BAD;
+                            break;
+                        }
+                        len = state->lens[state->have - 1];
+                        copy = 3 + BITS(2);
+                        DROPBITS(2);
+                    }
+                    else if (here.val == 17) {
+                        NEEDBITS(here.bits + 3);
+                        DROPBITS(here.bits);
+                        len = 0;
+                        copy = 3 + BITS(3);
+                        DROPBITS(3);
+                    }
+                    else {
+                        NEEDBITS(here.bits + 7);
+                        DROPBITS(here.bits);
+                        len = 0;
+                        copy = 11 + BITS(7);
+                        DROPBITS(7);
+                    }
+                    if (state->have + copy > state->nlen + state->ndist) {
+                        strm->msg = (char *)"invalid bit length repeat";
+                        state->mode = BAD;
+                        break;
+                    }
+                    while (copy--)
+                        state->lens[state->have++] = (unsigned short)len;
+                }
+            }
+
+            /* handle error breaks in while */
+            if (state->mode == BAD) break;
+
+            /* check for end-of-block code (better have one) */
+            if (state->lens[256] == 0) {
+                strm->msg = (char *)"invalid code -- missing end-of-block";
+                state->mode = BAD;
+                break;
+            }
+
+            /* build code tables -- note: do not change the lenbits or distbits
+               values here (9 and 6) without reading the comments in inftrees.h
+               concerning the ENOUGH constants, which depend on those values */
+            state->next = state->codes;
+            state->lencode = (const code FAR *)(state->next);
+            state->lenbits = 9;
+            ret = inflate_table(LENS, state->lens, state->nlen, &(state->next),
+                                &(state->lenbits), state->work);
+            if (ret) {
+                strm->msg = (char *)"invalid literal/lengths set";
+                state->mode = BAD;
+                break;
+            }
+            state->distcode = (const code FAR *)(state->next);
+            state->distbits = 6;
+            ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist,
+                            &(state->next), &(state->distbits), state->work);
+            if (ret) {
+                strm->msg = (char *)"invalid distances set";
+                state->mode = BAD;
+                break;
+            }
+            Tracev((stderr, "inflate:       codes ok\n"));
+            state->mode = LEN_;
+            if (flush == Z_TREES) goto inf_leave;
+        case LEN_:
+            state->mode = LEN;
+        case LEN:
+            if (have >= 6 && left >= 258) {
+                RESTORE();
+                inflate_fast(strm, out);
+                LOAD();
+                if (state->mode == TYPE)
+                    state->back = -1;
+                break;
+            }
+            state->back = 0;
+            for (;;) {
+                here = state->lencode[BITS(state->lenbits)];
+                if ((unsigned)(here.bits) <= bits) break;
+                PULLBYTE();
+            }
+            if (here.op && (here.op & 0xf0) == 0) {
+                last = here;
+                for (;;) {
+                    here = state->lencode[last.val +
+                            (BITS(last.bits + last.op) >> last.bits)];
+                    if ((unsigned)(last.bits + here.bits) <= bits) break;
+                    PULLBYTE();
+                }
+                DROPBITS(last.bits);
+                state->back += last.bits;
+            }
+            DROPBITS(here.bits);
+            state->back += here.bits;
+            state->length = (unsigned)here.val;
+            if ((int)(here.op) == 0) {
+                Tracevv((stderr, here.val >= 0x20 && here.val < 0x7f ?
+                        "inflate:         literal '%c'\n" :
+                        "inflate:         literal 0x%02x\n", here.val));
+                state->mode = LIT;
+                break;
+            }
+            if (here.op & 32) {
+                Tracevv((stderr, "inflate:         end of block\n"));
+                state->back = -1;
+                state->mode = TYPE;
+                break;
+            }
+            if (here.op & 64) {
+                strm->msg = (char *)"invalid literal/length code";
+                state->mode = BAD;
+                break;
+            }
+            state->extra = (unsigned)(here.op) & 15;
+            state->mode = LENEXT;
+        case LENEXT:
+            if (state->extra) {
+                NEEDBITS(state->extra);
+                state->length += BITS(state->extra);
+                DROPBITS(state->extra);
+                state->back += state->extra;
+            }
+            Tracevv((stderr, "inflate:         length %u\n", state->length));
+            state->was = state->length;
+            state->mode = DIST;
+        case DIST:
+            for (;;) {
+                here = state->distcode[BITS(state->distbits)];
+                if ((unsigned)(here.bits) <= bits) break;
+                PULLBYTE();
+            }
+            if ((here.op & 0xf0) == 0) {
+                last = here;
+                for (;;) {
+                    here = state->distcode[last.val +
+                            (BITS(last.bits + last.op) >> last.bits)];
+                    if ((unsigned)(last.bits + here.bits) <= bits) break;
+                    PULLBYTE();
+                }
+                DROPBITS(last.bits);
+                state->back += last.bits;
+            }
+            DROPBITS(here.bits);
+            state->back += here.bits;
+            if (here.op & 64) {
+                strm->msg = (char *)"invalid distance code";
+                state->mode = BAD;
+                break;
+            }
+            state->offset = (unsigned)here.val;
+            state->extra = (unsigned)(here.op) & 15;
+            state->mode = DISTEXT;
+        case DISTEXT:
+            if (state->extra) {
+                NEEDBITS(state->extra);
+                state->offset += BITS(state->extra);
+                DROPBITS(state->extra);
+                state->back += state->extra;
+            }
+#ifdef INFLATE_STRICT
+            if (state->offset > state->dmax) {
+                strm->msg = (char *)"invalid distance too far back";
+                state->mode = BAD;
+                break;
+            }
+#endif
+            Tracevv((stderr, "inflate:         distance %u\n", state->offset));
+            state->mode = MATCH;
+        case MATCH:
+            if (left == 0) goto inf_leave;
+            copy = out - left;
+            if (state->offset > copy) {         /* copy from window */
+                copy = state->offset - copy;
+                if (copy > state->whave) {
+                    if (state->sane) {
+                        strm->msg = (char *)"invalid distance too far back";
+                        state->mode = BAD;
+                        break;
+                    }
+#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
+                    Trace((stderr, "inflate.c too far\n"));
+                    copy -= state->whave;
+                    if (copy > state->length) copy = state->length;
+                    if (copy > left) copy = left;
+                    left -= copy;
+                    state->length -= copy;
+                    do {
+                        *put++ = 0;
+                    } while (--copy);
+                    if (state->length == 0) state->mode = LEN;
+                    break;
+#endif
+                }
+                if (copy > state->wnext) {
+                    copy -= state->wnext;
+                    from = state->window + (state->wsize - copy);
+                }
+                else
+                    from = state->window + (state->wnext - copy);
+                if (copy > state->length) copy = state->length;
+            }
+            else {                              /* copy from output */
+                from = put - state->offset;
+                copy = state->length;
+            }
+            if (copy > left) copy = left;
+            left -= copy;
+            state->length -= copy;
+            do {
+                *put++ = *from++;
+            } while (--copy);
+            if (state->length == 0) state->mode = LEN;
+            break;
+        case LIT:
+            if (left == 0) goto inf_leave;
+            *put++ = (unsigned char)(state->length);
+            left--;
+            state->mode = LEN;
+            break;
+        case CHECK:
+            if (state->wrap) {
+                NEEDBITS(32);
+                out -= left;
+                strm->total_out += out;
+                state->total += out;
+                if (out)
+                    strm->adler = state->check =
+                        UPDATE(state->check, put - out, out);
+                out = left;
+                if ((
+#ifdef GUNZIP
+                     state->flags ? hold :
+#endif
+                     ZSWAP32(hold)) != state->check) {
+                    strm->msg = (char *)"incorrect data check";
+                    state->mode = BAD;
+                    break;
+                }
+                INITBITS();
+                Tracev((stderr, "inflate:   check matches trailer\n"));
+            }
+#ifdef GUNZIP
+            state->mode = LENGTH;
+        case LENGTH:
+            if (state->wrap && state->flags) {
+                NEEDBITS(32);
+                if (hold != (state->total & 0xffffffffUL)) {
+                    strm->msg = (char *)"incorrect length check";
+                    state->mode = BAD;
+                    break;
+                }
+                INITBITS();
+                Tracev((stderr, "inflate:   length matches trailer\n"));
+            }
+#endif
+            state->mode = DONE;
+        case DONE:
+            ret = Z_STREAM_END;
+            goto inf_leave;
+        case BAD:
+            ret = Z_DATA_ERROR;
+            goto inf_leave;
+        case MEM:
+            return Z_MEM_ERROR;
+        case SYNC:
+        default:
+            return Z_STREAM_ERROR;
+        }
+
+    /*
+       Return from inflate(), updating the total counts and the check value.
+       If there was no progress during the inflate() call, return a buffer
+       error.  Call updatewindow() to create and/or update the window state.
+       Note: a memory error from inflate() is non-recoverable.
+     */
+  inf_leave:
+    RESTORE();
+    if (state->wsize || (out != strm->avail_out && state->mode < BAD &&
+            (state->mode < CHECK || flush != Z_FINISH)))
+        if (updatewindow(strm, strm->next_out, out - strm->avail_out)) {
+            state->mode = MEM;
+            return Z_MEM_ERROR;
+        }
+    in -= strm->avail_in;
+    out -= strm->avail_out;
+    strm->total_in += in;
+    strm->total_out += out;
+    state->total += out;
+    if (state->wrap && out)
+        strm->adler = state->check =
+            UPDATE(state->check, strm->next_out - out, out);
+    strm->data_type = state->bits + (state->last ? 64 : 0) +
+                      (state->mode == TYPE ? 128 : 0) +
+                      (state->mode == LEN_ || state->mode == COPY_ ? 256 : 0);
+    if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK)
+        ret = Z_BUF_ERROR;
+    return ret;
+}
+
+int ZEXPORT inflateEnd(strm)
+z_streamp strm;
+{
+    struct inflate_state FAR *state;
+    if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0)
+        return Z_STREAM_ERROR;
+    state = (struct inflate_state FAR *)strm->state;
+    if (state->window != Z_NULL) ZFREE(strm, state->window);
+    ZFREE(strm, strm->state);
+    strm->state = Z_NULL;
+    Tracev((stderr, "inflate: end\n"));
+    return Z_OK;
+}
+
+int ZEXPORT inflateGetDictionary(strm, dictionary, dictLength)
+z_streamp strm;
+Bytef *dictionary;
+uInt *dictLength;
+{
+    struct inflate_state FAR *state;
+
+    /* check state */
+    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+    state = (struct inflate_state FAR *)strm->state;
+
+    /* copy dictionary */
+    if (state->whave && dictionary != Z_NULL) {
+        zmemcpy(dictionary, state->window + state->wnext,
+                state->whave - state->wnext);
+        zmemcpy(dictionary + state->whave - state->wnext,
+                state->window, state->wnext);
+    }
+    if (dictLength != Z_NULL)
+        *dictLength = state->whave;
+    return Z_OK;
+}
+
+int ZEXPORT inflateSetDictionary(strm, dictionary, dictLength)
+z_streamp strm;
+const Bytef *dictionary;
+uInt dictLength;
+{
+    struct inflate_state FAR *state;
+    unsigned long dictid;
+    int ret;
+
+    /* check state */
+    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+    state = (struct inflate_state FAR *)strm->state;
+    if (state->wrap != 0 && state->mode != DICT)
+        return Z_STREAM_ERROR;
+
+    /* check for correct dictionary identifier */
+    if (state->mode == DICT) {
+        dictid = adler32(0L, Z_NULL, 0);
+        dictid = adler32(dictid, dictionary, dictLength);
+        if (dictid != state->check)
+            return Z_DATA_ERROR;
+    }
+
+    /* copy dictionary to window using updatewindow(), which will amend the
+       existing dictionary if appropriate */
+    ret = updatewindow(strm, dictionary + dictLength, dictLength);
+    if (ret) {
+        state->mode = MEM;
+        return Z_MEM_ERROR;
+    }
+    state->havedict = 1;
+    Tracev((stderr, "inflate:   dictionary set\n"));
+    return Z_OK;
+}
+
+int ZEXPORT inflateGetHeader(strm, head)
+z_streamp strm;
+gz_headerp head;
+{
+    struct inflate_state FAR *state;
+
+    /* check state */
+    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+    state = (struct inflate_state FAR *)strm->state;
+    if ((state->wrap & 2) == 0) return Z_STREAM_ERROR;
+
+    /* save header structure */
+    state->head = head;
+    head->done = 0;
+    return Z_OK;
+}
+
+/*
+   Search buf[0..len-1] for the pattern: 0, 0, 0xff, 0xff.  Return when found
+   or when out of input.  When called, *have is the number of pattern bytes
+   found in order so far, in 0..3.  On return *have is updated to the new
+   state.  If on return *have equals four, then the pattern was found and the
+   return value is how many bytes were read including the last byte of the
+   pattern.  If *have is less than four, then the pattern has not been found
+   yet and the return value is len.  In the latter case, syncsearch() can be
+   called again with more data and the *have state.  *have is initialized to
+   zero for the first call.
+ */
+local unsigned syncsearch(have, buf, len)
+unsigned FAR *have;
+const unsigned char FAR *buf;
+unsigned len;
+{
+    unsigned got;
+    unsigned next;
+
+    got = *have;
+    next = 0;
+    while (next < len && got < 4) {
+        if ((int)(buf[next]) == (got < 2 ? 0 : 0xff))
+            got++;
+        else if (buf[next])
+            got = 0;
+        else
+            got = 4 - got;
+        next++;
+    }
+    *have = got;
+    return next;
+}
+
+int ZEXPORT inflateSync(strm)
+z_streamp strm;
+{
+    unsigned len;               /* number of bytes to look at or looked at */
+    unsigned long in, out;      /* temporary to save total_in and total_out */
+    unsigned char buf[4];       /* to restore bit buffer to byte string */
+    struct inflate_state FAR *state;
+
+    /* check parameters */
+    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+    state = (struct inflate_state FAR *)strm->state;
+    if (strm->avail_in == 0 && state->bits < 8) return Z_BUF_ERROR;
+
+    /* if first time, start search in bit buffer */
+    if (state->mode != SYNC) {
+        state->mode = SYNC;
+        state->hold <<= state->bits & 7;
+        state->bits -= state->bits & 7;
+        len = 0;
+        while (state->bits >= 8) {
+            buf[len++] = (unsigned char)(state->hold);
+            state->hold >>= 8;
+            state->bits -= 8;
+        }
+        state->have = 0;
+        syncsearch(&(state->have), buf, len);
+    }
+
+    /* search available input */
+    len = syncsearch(&(state->have), strm->next_in, strm->avail_in);
+    strm->avail_in -= len;
+    strm->next_in += len;
+    strm->total_in += len;
+
+    /* return no joy or set up to restart inflate() on a new block */
+    if (state->have != 4) return Z_DATA_ERROR;
+    in = strm->total_in;  out = strm->total_out;
+    inflateReset(strm);
+    strm->total_in = in;  strm->total_out = out;
+    state->mode = TYPE;
+    return Z_OK;
+}
+
+/*
+   Returns true if inflate is currently at the end of a block generated by
+   Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP
+   implementation to provide an additional safety check. PPP uses
+   Z_SYNC_FLUSH but removes the length bytes of the resulting empty stored
+   block. When decompressing, PPP checks that at the end of input packet,
+   inflate is waiting for these length bytes.
+ */
+int ZEXPORT inflateSyncPoint(strm)
+z_streamp strm;
+{
+    struct inflate_state FAR *state;
+
+    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+    state = (struct inflate_state FAR *)strm->state;
+    return state->mode == STORED && state->bits == 0;
+}
+
+int ZEXPORT inflateCopy(dest, source)
+z_streamp dest;
+z_streamp source;
+{
+    struct inflate_state FAR *state;
+    struct inflate_state FAR *copy;
+    unsigned char FAR *window;
+    unsigned wsize;
+
+    /* check input */
+    if (dest == Z_NULL || source == Z_NULL || source->state == Z_NULL ||
+        source->zalloc == (alloc_func)0 || source->zfree == (free_func)0)
+        return Z_STREAM_ERROR;
+    state = (struct inflate_state FAR *)source->state;
+
+    /* allocate space */
+    copy = (struct inflate_state FAR *)
+           ZALLOC(source, 1, sizeof(struct inflate_state));
+    if (copy == Z_NULL) return Z_MEM_ERROR;
+    window = Z_NULL;
+    if (state->window != Z_NULL) {
+        window = (unsigned char FAR *)
+                 ZALLOC(source, 1U << state->wbits, sizeof(unsigned char));
+        if (window == Z_NULL) {
+            ZFREE(source, copy);
+            return Z_MEM_ERROR;
+        }
+    }
+
+    /* copy state */
+    zmemcpy((voidpf)dest, (voidpf)source, sizeof(z_stream));
+    zmemcpy((voidpf)copy, (voidpf)state, sizeof(struct inflate_state));
+    if (state->lencode >= state->codes &&
+        state->lencode <= state->codes + ENOUGH - 1) {
+        copy->lencode = copy->codes + (state->lencode - state->codes);
+        copy->distcode = copy->codes + (state->distcode - state->codes);
+    }
+    copy->next = copy->codes + (state->next - state->codes);
+    if (window != Z_NULL) {
+        wsize = 1U << state->wbits;
+        zmemcpy(window, state->window, wsize);
+    }
+    copy->window = window;
+    dest->state = (struct internal_state FAR *)copy;
+    return Z_OK;
+}
+
+int ZEXPORT inflateUndermine(strm, subvert)
+z_streamp strm;
+int subvert;
+{
+    struct inflate_state FAR *state;
+
+    if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
+    state = (struct inflate_state FAR *)strm->state;
+    state->sane = !subvert;
+#ifdef INFLATE_ALLOW_INVALID_DISTANCE_TOOFAR_ARRR
+    return Z_OK;
+#else
+    state->sane = 1;
+    return Z_DATA_ERROR;
+#endif
+}
+
+long ZEXPORT inflateMark(strm)
+z_streamp strm;
+{
+    struct inflate_state FAR *state;
+
+    if (strm == Z_NULL || strm->state == Z_NULL) return -1L << 16;
+    state = (struct inflate_state FAR *)strm->state;
+    return ((long)(state->back) << 16) +
+        (state->mode == COPY ? state->length :
+            (state->mode == MATCH ? state->was - state->length : 0));
+}
diff --git a/compat/zlib/inflate.h b/compat/zlib/inflate.h
new file mode 100644
index 0000000..95f4986
--- /dev/null
+++ b/compat/zlib/inflate.h
@@ -0,0 +1,122 @@
+/* inflate.h -- internal inflate state definition
+ * Copyright (C) 1995-2009 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+   part of the implementation of the compression library and is
+   subject to change. Applications should only use zlib.h.
+ */
+
+/* define NO_GZIP when compiling if you want to disable gzip header and
+   trailer decoding by inflate().  NO_GZIP would be used to avoid linking in
+   the crc code when it is not needed.  For shared libraries, gzip decoding
+   should be left enabled. */
+#ifndef NO_GZIP
+#  define GUNZIP
+#endif
+
+/* Possible inflate modes between inflate() calls */
+typedef enum {
+    HEAD,       /* i: waiting for magic header */
+    FLAGS,      /* i: waiting for method and flags (gzip) */
+    TIME,       /* i: waiting for modification time (gzip) */
+    OS,         /* i: waiting for extra flags and operating system (gzip) */
+    EXLEN,      /* i: waiting for extra length (gzip) */
+    EXTRA,      /* i: waiting for extra bytes (gzip) */
+    NAME,       /* i: waiting for end of file name (gzip) */
+    COMMENT,    /* i: waiting for end of comment (gzip) */
+    HCRC,       /* i: waiting for header crc (gzip) */
+    DICTID,     /* i: waiting for dictionary check value */
+    DICT,       /* waiting for inflateSetDictionary() call */
+        TYPE,       /* i: waiting for type bits, including last-flag bit */
+        TYPEDO,     /* i: same, but skip check to exit inflate on new block */
+        STORED,     /* i: waiting for stored size (length and complement) */
+        COPY_,      /* i/o: same as COPY below, but only first time in */
+        COPY,       /* i/o: waiting for input or output to copy stored block */
+        TABLE,      /* i: waiting for dynamic block table lengths */
+        LENLENS,    /* i: waiting for code length code lengths */
+        CODELENS,   /* i: waiting for length/lit and distance code lengths */
+            LEN_,       /* i: same as LEN below, but only first time in */
+            LEN,        /* i: waiting for length/lit/eob code */
+            LENEXT,     /* i: waiting for length extra bits */
+            DIST,       /* i: waiting for distance code */
+            DISTEXT,    /* i: waiting for distance extra bits */
+            MATCH,      /* o: waiting for output space to copy string */
+            LIT,        /* o: waiting for output space to write literal */
+    CHECK,      /* i: waiting for 32-bit check value */
+    LENGTH,     /* i: waiting for 32-bit length (gzip) */
+    DONE,       /* finished check, done -- remain here until reset */
+    BAD,        /* got a data error -- remain here until reset */
+    MEM,        /* got an inflate() memory error -- remain here until reset */
+    SYNC        /* looking for synchronization bytes to restart inflate() */
+} inflate_mode;
+
+/*
+    State transitions between above modes -
+
+    (most modes can go to BAD or MEM on error -- not shown for clarity)
+
+    Process header:
+        HEAD -> (gzip) or (zlib) or (raw)
+        (gzip) -> FLAGS -> TIME -> OS -> EXLEN -> EXTRA -> NAME -> COMMENT ->
+                  HCRC -> TYPE
+        (zlib) -> DICTID or TYPE
+        DICTID -> DICT -> TYPE
+        (raw) -> TYPEDO
+    Read deflate blocks:
+            TYPE -> TYPEDO -> STORED or TABLE or LEN_ or CHECK
+            STORED -> COPY_ -> COPY -> TYPE
+            TABLE -> LENLENS -> CODELENS -> LEN_
+            LEN_ -> LEN
+    Read deflate codes in fixed or dynamic block:
+                LEN -> LENEXT or LIT or TYPE
+                LENEXT -> DIST -> DISTEXT -> MATCH -> LEN
+                LIT -> LEN
+    Process trailer:
+        CHECK -> LENGTH -> DONE
+ */
+
+/* state maintained between inflate() calls.  Approximately 10K bytes. */
+struct inflate_state {
+    inflate_mode mode;          /* current inflate mode */
+    int last;                   /* true if processing last block */
+    int wrap;                   /* bit 0 true for zlib, bit 1 true for gzip */
+    int havedict;               /* true if dictionary provided */
+    int flags;                  /* gzip header method and flags (0 if zlib) */
+    unsigned dmax;              /* zlib header max distance (INFLATE_STRICT) */
+    unsigned long check;        /* protected copy of check value */
+    unsigned long total;        /* protected copy of output count */
+    gz_headerp head;            /* where to save gzip header information */
+        /* sliding window */
+    unsigned wbits;             /* log base 2 of requested window size */
+    unsigned wsize;             /* window size or zero if not using window */
+    unsigned whave;             /* valid bytes in the window */
+    unsigned wnext;             /* window write index */
+    unsigned char FAR *window;  /* allocated sliding window, if needed */
+        /* bit accumulator */
+    unsigned long hold;         /* input bit accumulator */
+    unsigned bits;              /* number of bits in "in" */
+        /* for string and stored block copying */
+    unsigned length;            /* literal or length of data to copy */
+    unsigned offset;            /* distance back to copy string from */
+        /* for table and code decoding */
+    unsigned extra;             /* extra bits needed */
+        /* fixed and dynamic code tables */
+    code const FAR *lencode;    /* starting table for length/literal codes */
+    code const FAR *distcode;   /* starting table for distance codes */
+    unsigned lenbits;           /* index bits for lencode */
+    unsigned distbits;          /* index bits for distcode */
+        /* dynamic table building */
+    unsigned ncode;             /* number of code length code lengths */
+    unsigned nlen;              /* number of length code lengths */
+    unsigned ndist;             /* number of distance code lengths */
+    unsigned have;              /* number of code lengths in lens[] */
+    code FAR *next;             /* next available space in codes[] */
+    unsigned short lens[320];   /* temporary storage for code lengths */
+    unsigned short work[288];   /* work area for code table building */
+    code codes[ENOUGH];         /* space for code tables */
+    int sane;                   /* if false, allow invalid distance too far */
+    int back;                   /* bits back of last unprocessed length/lit */
+    unsigned was;               /* initial length of match */
+};
diff --git a/compat/zlib/inftrees.c b/compat/zlib/inftrees.c
new file mode 100644
index 0000000..44d89cf
--- /dev/null
+++ b/compat/zlib/inftrees.c
@@ -0,0 +1,306 @@
+/* inftrees.c -- generate Huffman trees for efficient decoding
+ * Copyright (C) 1995-2013 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+#include "zutil.h"
+#include "inftrees.h"
+
+#define MAXBITS 15
+
+const char inflate_copyright[] =
+   " inflate 1.2.8 Copyright 1995-2013 Mark Adler ";
+/*
+  If you use the zlib library in a product, an acknowledgment is welcome
+  in the documentation of your product. If for some reason you cannot
+  include such an acknowledgment, I would appreciate that you keep this
+  copyright string in the executable of your product.
+ */
+
+/*
+   Build a set of tables to decode the provided canonical Huffman code.
+   The code lengths are lens[0..codes-1].  The result starts at *table,
+   whose indices are 0..2^bits-1.  work is a writable array of at least
+   lens shorts, which is used as a work area.  type is the type of code
+   to be generated, CODES, LENS, or DISTS.  On return, zero is success,
+   -1 is an invalid code, and +1 means that ENOUGH isn't enough.  table
+   on return points to the next available entry's address.  bits is the
+   requested root table index bits, and on return it is the actual root
+   table index bits.  It will differ if the request is greater than the
+   longest code or if it is less than the shortest code.
+ */
+int ZLIB_INTERNAL inflate_table(type, lens, codes, table, bits, work)
+codetype type;
+unsigned short FAR *lens;
+unsigned codes;
+code FAR * FAR *table;
+unsigned FAR *bits;
+unsigned short FAR *work;
+{
+    unsigned len;               /* a code's length in bits */
+    unsigned sym;               /* index of code symbols */
+    unsigned min, max;          /* minimum and maximum code lengths */
+    unsigned root;              /* number of index bits for root table */
+    unsigned curr;              /* number of index bits for current table */
+    unsigned drop;              /* code bits to drop for sub-table */
+    int left;                   /* number of prefix codes available */
+    unsigned used;              /* code entries in table used */
+    unsigned huff;              /* Huffman code */
+    unsigned incr;              /* for incrementing code, index */
+    unsigned fill;              /* index for replicating entries */
+    unsigned low;               /* low bits for current root entry */
+    unsigned mask;              /* mask for low root bits */
+    code here;                  /* table entry for duplication */
+    code FAR *next;             /* next available space in table */
+    const unsigned short FAR *base;     /* base value table to use */
+    const unsigned short FAR *extra;    /* extra bits table to use */
+    int end;                    /* use base and extra for symbol > end */
+    unsigned short count[MAXBITS+1];    /* number of codes of each length */
+    unsigned short offs[MAXBITS+1];     /* offsets in table for each length */
+    static const unsigned short lbase[31] = { /* Length codes 257..285 base */
+        3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
+        35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
+    static const unsigned short lext[31] = { /* Length codes 257..285 extra */
+        16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18,
+        19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 72, 78};
+    static const unsigned short dbase[32] = { /* Distance codes 0..29 base */
+        1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
+        257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
+        8193, 12289, 16385, 24577, 0, 0};
+    static const unsigned short dext[32] = { /* Distance codes 0..29 extra */
+        16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22,
+        23, 23, 24, 24, 25, 25, 26, 26, 27, 27,
+        28, 28, 29, 29, 64, 64};
+
+    /*
+       Process a set of code lengths to create a canonical Huffman code.  The
+       code lengths are lens[0..codes-1].  Each length corresponds to the
+       symbols 0..codes-1.  The Huffman code is generated by first sorting the
+       symbols by length from short to long, and retaining the symbol order
+       for codes with equal lengths.  Then the code starts with all zero bits
+       for the first code of the shortest length, and the codes are integer
+       increments for the same length, and zeros are appended as the length
+       increases.  For the deflate format, these bits are stored backwards
+       from their more natural integer increment ordering, and so when the
+       decoding tables are built in the large loop below, the integer codes
+       are incremented backwards.
+
+       This routine assumes, but does not check, that all of the entries in
+       lens[] are in the range 0..MAXBITS.  The caller must assure this.
+       1..MAXBITS is interpreted as that code length.  zero means that that
+       symbol does not occur in this code.
+
+       The codes are sorted by computing a count of codes for each length,
+       creating from that a table of starting indices for each length in the
+       sorted table, and then entering the symbols in order in the sorted
+       table.  The sorted table is work[], with that space being provided by
+       the caller.
+
+       The length counts are used for other purposes as well, i.e. finding
+       the minimum and maximum length codes, determining if there are any
+       codes at all, checking for a valid set of lengths, and looking ahead
+       at length counts to determine sub-table sizes when building the
+       decoding tables.
+     */
+
+    /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */
+    for (len = 0; len <= MAXBITS; len++)
+        count[len] = 0;
+    for (sym = 0; sym < codes; sym++)
+        count[lens[sym]]++;
+
+    /* bound code lengths, force root to be within code lengths */
+    root = *bits;
+    for (max = MAXBITS; max >= 1; max--)
+        if (count[max] != 0) break;
+    if (root > max) root = max;
+    if (max == 0) {                     /* no symbols to code at all */
+        here.op = (unsigned char)64;    /* invalid code marker */
+        here.bits = (unsigned char)1;
+        here.val = (unsigned short)0;
+        *(*table)++ = here;             /* make a table to force an error */
+        *(*table)++ = here;
+        *bits = 1;
+        return 0;     /* no symbols, but wait for decoding to report error */
+    }
+    for (min = 1; min < max; min++)
+        if (count[min] != 0) break;
+    if (root < min) root = min;
+
+    /* check for an over-subscribed or incomplete set of lengths */
+    left = 1;
+    for (len = 1; len <= MAXBITS; len++) {
+        left <<= 1;
+        left -= count[len];
+        if (left < 0) return -1;        /* over-subscribed */
+    }
+    if (left > 0 && (type == CODES || max != 1))
+        return -1;                      /* incomplete set */
+
+    /* generate offsets into symbol table for each length for sorting */
+    offs[1] = 0;
+    for (len = 1; len < MAXBITS; len++)
+        offs[len + 1] = offs[len] + count[len];
+
+    /* sort symbols by length, by symbol order within each length */
+    for (sym = 0; sym < codes; sym++)
+        if (lens[sym] != 0) work[offs[lens[sym]]++] = (unsigned short)sym;
+
+    /*
+       Create and fill in decoding tables.  In this loop, the table being
+       filled is at next and has curr index bits.  The code being used is huff
+       with length len.  That code is converted to an index by dropping drop
+       bits off of the bottom.  For codes where len is less than drop + curr,
+       those top drop + curr - len bits are incremented through all values to
+       fill the table with replicated entries.
+
+       root is the number of index bits for the root table.  When len exceeds
+       root, sub-tables are created pointed to by the root entry with an index
+       of the low root bits of huff.  This is saved in low to check for when a
+       new sub-table should be started.  drop is zero when the root table is
+       being filled, and drop is root when sub-tables are being filled.
+
+       When a new sub-table is needed, it is necessary to look ahead in the
+       code lengths to determine what size sub-table is needed.  The length
+       counts are used for this, and so count[] is decremented as codes are
+       entered in the tables.
+
+       used keeps track of how many table entries have been allocated from the
+       provided *table space.  It is checked for LENS and DIST tables against
+       the constants ENOUGH_LENS and ENOUGH_DISTS to guard against changes in
+       the initial root table size constants.  See the comments in inftrees.h
+       for more information.
+
+       sym increments through all symbols, and the loop terminates when
+       all codes of length max, i.e. all codes, have been processed.  This
+       routine permits incomplete codes, so another loop after this one fills
+       in the rest of the decoding tables with invalid code markers.
+     */
+
+    /* set up for code type */
+    switch (type) {
+    case CODES:
+        base = extra = work;    /* dummy value--not used */
+        end = 19;
+        break;
+    case LENS:
+        base = lbase;
+        base -= 257;
+        extra = lext;
+        extra -= 257;
+        end = 256;
+        break;
+    default:            /* DISTS */
+        base = dbase;
+        extra = dext;
+        end = -1;
+    }
+
+    /* initialize state for loop */
+    huff = 0;                   /* starting code */
+    sym = 0;                    /* starting code symbol */
+    len = min;                  /* starting code length */
+    next = *table;              /* current table to fill in */
+    curr = root;                /* current table index bits */
+    drop = 0;                   /* current bits to drop from code for index */
+    low = (unsigned)(-1);       /* trigger new sub-table when len > root */
+    used = 1U << root;          /* use root table entries */
+    mask = used - 1;            /* mask for comparing low */
+
+    /* check available table space */
+    if ((type == LENS && used > ENOUGH_LENS) ||
+        (type == DISTS && used > ENOUGH_DISTS))
+        return 1;
+
+    /* process all codes and make table entries */
+    for (;;) {
+        /* create table entry */
+        here.bits = (unsigned char)(len - drop);
+        if ((int)(work[sym]) < end) {
+            here.op = (unsigned char)0;
+            here.val = work[sym];
+        }
+        else if ((int)(work[sym]) > end) {
+            here.op = (unsigned char)(extra[work[sym]]);
+            here.val = base[work[sym]];
+        }
+        else {
+            here.op = (unsigned char)(32 + 64);         /* end of block */
+            here.val = 0;
+        }
+
+        /* replicate for those indices with low len bits equal to huff */
+        incr = 1U << (len - drop);
+        fill = 1U << curr;
+        min = fill;                 /* save offset to next table */
+        do {
+            fill -= incr;
+            next[(huff >> drop) + fill] = here;
+        } while (fill != 0);
+
+        /* backwards increment the len-bit code huff */
+        incr = 1U << (len - 1);
+        while (huff & incr)
+            incr >>= 1;
+        if (incr != 0) {
+            huff &= incr - 1;
+            huff += incr;
+        }
+        else
+            huff = 0;
+
+        /* go to next symbol, update count, len */
+        sym++;
+        if (--(count[len]) == 0) {
+            if (len == max) break;
+            len = lens[work[sym]];
+        }
+
+        /* create new sub-table if needed */
+        if (len > root && (huff & mask) != low) {
+            /* if first time, transition to sub-tables */
+            if (drop == 0)
+                drop = root;
+
+            /* increment past last table */
+            next += min;            /* here min is 1 << curr */
+
+            /* determine length of next table */
+            curr = len - drop;
+            left = (int)(1 << curr);
+            while (curr + drop < max) {
+                left -= count[curr + drop];
+                if (left <= 0) break;
+                curr++;
+                left <<= 1;
+            }
+
+            /* check for enough space */
+            used += 1U << curr;
+            if ((type == LENS && used > ENOUGH_LENS) ||
+                (type == DISTS && used > ENOUGH_DISTS))
+                return 1;
+
+            /* point entry in root table to sub-table */
+            low = huff & mask;
+            (*table)[low].op = (unsigned char)curr;
+            (*table)[low].bits = (unsigned char)root;
+            (*table)[low].val = (unsigned short)(next - *table);
+        }
+    }
+
+    /* fill in remaining table entry if code is incomplete (guaranteed to have
+       at most one remaining entry, since if the code is incomplete, the
+       maximum code length that was allowed to get this far is one bit) */
+    if (huff != 0) {
+        here.op = (unsigned char)64;            /* invalid code marker */
+        here.bits = (unsigned char)(len - drop);
+        here.val = (unsigned short)0;
+        next[huff] = here;
+    }
+
+    /* set return parameters */
+    *table += used;
+    *bits = root;
+    return 0;
+}
diff --git a/compat/zlib/inftrees.h b/compat/zlib/inftrees.h
new file mode 100644
index 0000000..baa53a0
--- /dev/null
+++ b/compat/zlib/inftrees.h
@@ -0,0 +1,62 @@
+/* inftrees.h -- header to use inftrees.c
+ * Copyright (C) 1995-2005, 2010 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+   part of the implementation of the compression library and is
+   subject to change. Applications should only use zlib.h.
+ */
+
+/* Structure for decoding tables.  Each entry provides either the
+   information needed to do the operation requested by the code that
+   indexed that table entry, or it provides a pointer to another
+   table that indexes more bits of the code.  op indicates whether
+   the entry is a pointer to another table, a literal, a length or
+   distance, an end-of-block, or an invalid code.  For a table
+   pointer, the low four bits of op is the number of index bits of
+   that table.  For a length or distance, the low four bits of op
+   is the number of extra bits to get after the code.  bits is
+   the number of bits in this code or part of the code to drop off
+   of the bit buffer.  val is the actual byte to output in the case
+   of a literal, the base length or distance, or the offset from
+   the current table to the next table.  Each entry is four bytes. */
+typedef struct {
+    unsigned char op;           /* operation, extra bits, table bits */
+    unsigned char bits;         /* bits in this part of the code */
+    unsigned short val;         /* offset in table or code value */
+} code;
+
+/* op values as set by inflate_table():
+    00000000 - literal
+    0000tttt - table link, tttt != 0 is the number of table index bits
+    0001eeee - length or distance, eeee is the number of extra bits
+    01100000 - end of block
+    01000000 - invalid code
+ */
+
+/* Maximum size of the dynamic table.  The maximum number of code structures is
+   1444, which is the sum of 852 for literal/length codes and 592 for distance
+   codes.  These values were found by exhaustive searches using the program
+   examples/enough.c found in the zlib distribtution.  The arguments to that
+   program are the number of symbols, the initial root table size, and the
+   maximum bit length of a code.  "enough 286 9 15" for literal/length codes
+   returns returns 852, and "enough 30 6 15" for distance codes returns 592.
+   The initial root table size (9 or 6) is found in the fifth argument of the
+   inflate_table() calls in inflate.c and infback.c.  If the root table size is
+   changed, then these maximum sizes would be need to be recalculated and
+   updated. */
+#define ENOUGH_LENS 852
+#define ENOUGH_DISTS 592
+#define ENOUGH (ENOUGH_LENS+ENOUGH_DISTS)
+
+/* Type of code to build for inflate_table() */
+typedef enum {
+    CODES,
+    LENS,
+    DISTS
+} codetype;
+
+int ZLIB_INTERNAL inflate_table OF((codetype type, unsigned short FAR *lens,
+                             unsigned codes, code FAR * FAR *table,
+                             unsigned FAR *bits, unsigned short FAR *work));
diff --git a/compat/zlib/make_vms.com b/compat/zlib/make_vms.com
new file mode 100644
index 0000000..65e9d0c
--- /dev/null
+++ b/compat/zlib/make_vms.com
@@ -0,0 +1,867 @@
+$! make libz under VMS written by
+$! Martin P.J. Zinser
+$!
+$! In case of problems with the install you might contact me at
+$! zinser@zinser.no-ip.info(preferred) or
+$! martin.zinser@eurexchange.com (work)
+$!
+$! Make procedure history for Zlib
+$!
+$!------------------------------------------------------------------------------
+$! Version history
+$! 0.01 20060120 First version to receive a number
+$! 0.02 20061008 Adapt to new Makefile.in
+$! 0.03 20091224 Add support for large file check
+$! 0.04 20100110 Add new gzclose, gzlib, gzread, gzwrite
+$! 0.05 20100221 Exchange zlibdefs.h by zconf.h.in
+$! 0.06 20120111 Fix missing amiss_err, update zconf_h.in, fix new exmples
+$!               subdir path, update module search in makefile.in
+$! 0.07 20120115 Triggered by work done by Alexey Chupahin completly redesigned
+$!               shared image creation
+$! 0.08 20120219 Make it work on VAX again, pre-load missing symbols to shared
+$!               image
+$! 0.09 20120305 SMS.  P1 sets builder ("MMK", "MMS", " " (built-in)).
+$!               "" -> automatic, preference: MMK, MMS, built-in.
+$!
+$ on error then goto err_exit
+$!
+$ true  = 1
+$ false = 0
+$ tmpnam = "temp_" + f$getjpi("","pid")
+$ tt = tmpnam + ".txt"
+$ tc = tmpnam + ".c"
+$ th = tmpnam + ".h"
+$ define/nolog tconfig 'th'
+$ its_decc = false
+$ its_vaxc = false
+$ its_gnuc = false
+$ s_case   = False
+$!
+$! Setup variables holding "config" information
+$!
+$ Make    = "''p1'"
+$ name     = "Zlib"
+$ version  = "?.?.?"
+$ v_string = "ZLIB_VERSION"
+$ v_file   = "zlib.h"
+$ ccopt   = "/include = []"
+$ lopts   = ""
+$ dnsrl   = ""
+$ aconf_in_file = "zconf.h.in#zconf.h_in#zconf_h.in"
+$ conf_check_string = ""
+$ linkonly = false
+$ optfile  = name + ".opt"
+$ mapfile  = name + ".map"
+$ libdefs  = ""
+$ vax      = f$getsyi("HW_MODEL").lt.1024
+$ axp      = f$getsyi("HW_MODEL").ge.1024 .and. f$getsyi("HW_MODEL").lt.4096
+$ ia64     = f$getsyi("HW_MODEL").ge.4096
+$!
+$! 2012-03-05 SMS.
+$! Why is this needed?  And if it is needed, why not simply ".not. vax"?
+$!
+$!!! if axp .or. ia64 then  set proc/parse=extended
+$!
+$ whoami = f$parse(f$environment("Procedure"),,,,"NO_CONCEAL")
+$ mydef  = F$parse(whoami,,,"DEVICE")
+$ mydir  = f$parse(whoami,,,"DIRECTORY") - "]["
+$ myproc = f$parse(whoami,,,"Name") + f$parse(whoami,,,"type")
+$!
+$! Check for MMK/MMS
+$!
+$ if (Make .eqs. "")
+$ then
+$   If F$Search ("Sys$System:MMS.EXE") .nes. "" Then Make = "MMS"
+$   If F$Type (MMK) .eqs. "STRING" Then Make = "MMK"
+$ else
+$   Make = f$edit( Make, "trim")
+$ endif
+$!
+$ gosub find_version
+$!
+$  open/write topt tmp.opt
+$  open/write optf 'optfile'
+$!
+$ gosub check_opts
+$!
+$! Look for the compiler used
+$!
+$ gosub check_compiler
+$ close topt
+$ close optf
+$!
+$ if its_decc
+$ then
+$   ccopt = "/prefix=all" + ccopt
+$   if f$trnlnm("SYS") .eqs. ""
+$   then
+$     if axp
+$     then
+$       define sys sys$library:
+$     else
+$       ccopt = "/decc" + ccopt
+$       define sys decc$library_include:
+$     endif
+$   endif
+$!
+$! 2012-03-05 SMS.
+$! Why /NAMES = AS_IS?  Why not simply ".not. vax"?  And why not on VAX?
+$!
+$   if axp .or. ia64
+$   then
+$       ccopt = ccopt + "/name=as_is/opt=(inline=speed)"
+$       s_case = true
+$   endif
+$ endif
+$ if its_vaxc .or. its_gnuc
+$ then
+$    if f$trnlnm("SYS").eqs."" then define sys sys$library:
+$ endif
+$!
+$! Build a fake configure input header
+$!
+$ open/write conf_hin config.hin
+$ write conf_hin "#undef _LARGEFILE64_SOURCE"
+$ close conf_hin
+$!
+$!
+$ i = 0
+$FIND_ACONF:
+$ fname = f$element(i,"#",aconf_in_file)
+$ if fname .eqs. "#" then goto AMISS_ERR
+$ if f$search(fname) .eqs. ""
+$ then
+$   i = i + 1
+$   goto find_aconf
+$ endif
+$ open/read/err=aconf_err aconf_in 'fname'
+$ open/write aconf zconf.h
+$ACONF_LOOP:
+$ read/end_of_file=aconf_exit aconf_in line
+$ work = f$edit(line, "compress,trim")
+$ if f$extract(0,6,work) .nes. "#undef"
+$ then
+$   if f$extract(0,12,work) .nes. "#cmakedefine"
+$   then
+$       write aconf line
+$   endif
+$ else
+$   cdef = f$element(1," ",work)
+$   gosub check_config
+$ endif
+$ goto aconf_loop
+$ACONF_EXIT:
+$ write aconf ""
+$ write aconf "/* VMS specifics added by make_vms.com: */"
+$ write aconf "#define VMS 1"
+$ write aconf "#include <unistd.h>"
+$ write aconf "#include <unixio.h>"
+$ write aconf "#ifdef _LARGEFILE"
+$ write aconf "# define off64_t __off64_t"
+$ write aconf "# define fopen64 fopen"
+$ write aconf "# define fseeko64 fseeko"
+$ write aconf "# define lseek64 lseek"
+$ write aconf "# define ftello64 ftell"
+$ write aconf "#endif"
+$ write aconf "#if !defined( __VAX) && (__CRTL_VER >= 70312000)"
+$ write aconf "# define HAVE_VSNPRINTF"
+$ write aconf "#endif"
+$ close aconf_in
+$ close aconf
+$ if f$search("''th'") .nes. "" then delete 'th';*
+$! Build the thing plain or with mms
+$!
+$ write sys$output "Compiling Zlib sources ..."
+$ if make.eqs.""
+$ then
+$   if (f$search( "example.obj;*") .nes. "") then delete example.obj;*
+$   if (f$search( "minigzip.obj;*") .nes. "") then delete minigzip.obj;*
+$   CALL MAKE adler32.OBJ "CC ''CCOPT' adler32" -
+                adler32.c zlib.h zconf.h
+$   CALL MAKE compress.OBJ "CC ''CCOPT' compress" -
+                compress.c zlib.h zconf.h
+$   CALL MAKE crc32.OBJ "CC ''CCOPT' crc32" -
+                crc32.c zlib.h zconf.h
+$   CALL MAKE deflate.OBJ "CC ''CCOPT' deflate" -
+                deflate.c deflate.h zutil.h zlib.h zconf.h
+$   CALL MAKE gzclose.OBJ "CC ''CCOPT' gzclose" -
+                gzclose.c zutil.h zlib.h zconf.h
+$   CALL MAKE gzlib.OBJ "CC ''CCOPT' gzlib" -
+                gzlib.c zutil.h zlib.h zconf.h
+$   CALL MAKE gzread.OBJ "CC ''CCOPT' gzread" -
+                gzread.c zutil.h zlib.h zconf.h
+$   CALL MAKE gzwrite.OBJ "CC ''CCOPT' gzwrite" -
+                gzwrite.c zutil.h zlib.h zconf.h
+$   CALL MAKE infback.OBJ "CC ''CCOPT' infback" -
+                infback.c zutil.h inftrees.h inflate.h inffast.h inffixed.h
+$   CALL MAKE inffast.OBJ "CC ''CCOPT' inffast" -
+                inffast.c zutil.h zlib.h zconf.h inffast.h
+$   CALL MAKE inflate.OBJ "CC ''CCOPT' inflate" -
+                inflate.c zutil.h zlib.h zconf.h infblock.h
+$   CALL MAKE inftrees.OBJ "CC ''CCOPT' inftrees" -
+                inftrees.c zutil.h zlib.h zconf.h inftrees.h
+$   CALL MAKE trees.OBJ "CC ''CCOPT' trees" -
+                trees.c deflate.h zutil.h zlib.h zconf.h
+$   CALL MAKE uncompr.OBJ "CC ''CCOPT' uncompr" -
+                uncompr.c zlib.h zconf.h
+$   CALL MAKE zutil.OBJ "CC ''CCOPT' zutil" -
+                zutil.c zutil.h zlib.h zconf.h
+$   write sys$output "Building Zlib ..."
+$   CALL MAKE libz.OLB "lib/crea libz.olb *.obj" *.OBJ
+$   write sys$output "Building example..."
+$   CALL MAKE example.OBJ "CC ''CCOPT' [.test]example" -
+                [.test]example.c zlib.h zconf.h
+$   call make example.exe "LINK example,libz.olb/lib" example.obj libz.olb
+$   write sys$output "Building minigzip..."
+$   CALL MAKE minigzip.OBJ "CC ''CCOPT' [.test]minigzip" -
+              [.test]minigzip.c zlib.h zconf.h
+$   call make minigzip.exe -
+              "LINK minigzip,libz.olb/lib" -
+              minigzip.obj libz.olb
+$ else
+$   gosub crea_mms
+$   write sys$output "Make ''name' ''version' with ''Make' "
+$   'make'
+$ endif
+$!
+$! Create shareable image
+$!
+$ gosub crea_olist
+$ write sys$output "Creating libzshr.exe"
+$ call map_2_shopt 'mapfile' 'optfile'
+$ LINK_'lopts'/SHARE=libzshr.exe modules.opt/opt,'optfile'/opt
+$ write sys$output "Zlib build completed"
+$ delete/nolog tmp.opt;*
+$ exit
+$AMISS_ERR:
+$ write sys$output "No source for config.hin found."
+$ write sys$output "Tried any of ''aconf_in_file'"
+$ goto err_exit
+$CC_ERR:
+$ write sys$output "C compiler required to build ''name'"
+$ goto err_exit
+$ERR_EXIT:
+$ set message/facil/ident/sever/text
+$ close/nolog optf
+$ close/nolog topt
+$ close/nolog aconf_in
+$ close/nolog aconf
+$ close/nolog out
+$ close/nolog min
+$ close/nolog mod
+$ close/nolog h_in
+$ write sys$output "Exiting..."
+$ exit 2
+$!
+$!
+$MAKE: SUBROUTINE   !SUBROUTINE TO CHECK DEPENDENCIES
+$ V = 'F$Verify(0)
+$! P1 = What we are trying to make
+$! P2 = Command to make it
+$! P3 - P8  What it depends on
+$
+$ If F$Search(P1) .Eqs. "" Then Goto Makeit
+$ Time = F$CvTime(F$File(P1,"RDT"))
+$arg=3
+$Loop:
+$       Argument = P'arg
+$       If Argument .Eqs. "" Then Goto Exit
+$       El=0
+$Loop2:
+$       File = F$Element(El," ",Argument)
+$       If File .Eqs. " " Then Goto Endl
+$       AFile = ""
+$Loop3:
+$       OFile = AFile
+$       AFile = F$Search(File)
+$       If AFile .Eqs. "" .Or. AFile .Eqs. OFile Then Goto NextEl
+$       If F$CvTime(F$File(AFile,"RDT")) .Ges. Time Then Goto Makeit
+$       Goto Loop3
+$NextEL:
+$       El = El + 1
+$       Goto Loop2
+$EndL:
+$ arg=arg+1
+$ If arg .Le. 8 Then Goto Loop
+$ Goto Exit
+$
+$Makeit:
+$ VV=F$VERIFY(0)
+$ write sys$output P2
+$ 'P2
+$ VV='F$Verify(VV)
+$Exit:
+$ If V Then Set Verify
+$ENDSUBROUTINE
+$!------------------------------------------------------------------------------
+$!
+$! Check command line options and set symbols accordingly
+$!
+$!------------------------------------------------------------------------------
+$! Version history
+$! 0.01 20041206 First version to receive a number
+$! 0.02 20060126 Add new "HELP" target
+$ CHECK_OPTS:
+$ i = 1
+$ OPT_LOOP:
+$ if i .lt. 9
+$ then
+$   cparm = f$edit(p'i',"upcase")
+$!
+$! Check if parameter actually contains something
+$!
+$   if f$edit(cparm,"trim") .nes. ""
+$   then
+$     if cparm .eqs. "DEBUG"
+$     then
+$       ccopt = ccopt + "/noopt/deb"
+$       lopts = lopts + "/deb"
+$     endif
+$     if f$locate("CCOPT=",cparm) .lt. f$length(cparm)
+$     then
+$       start = f$locate("=",cparm) + 1
+$       len   = f$length(cparm) - start
+$       ccopt = ccopt + f$extract(start,len,cparm)
+$       if f$locate("AS_IS",f$edit(ccopt,"UPCASE")) .lt. f$length(ccopt) -
+          then s_case = true
+$     endif
+$     if cparm .eqs. "LINK" then linkonly = true
+$     if f$locate("LOPTS=",cparm) .lt. f$length(cparm)
+$     then
+$       start = f$locate("=",cparm) + 1
+$       len   = f$length(cparm) - start
+$       lopts = lopts + f$extract(start,len,cparm)
+$     endif
+$     if f$locate("CC=",cparm) .lt. f$length(cparm)
+$     then
+$       start  = f$locate("=",cparm) + 1
+$       len    = f$length(cparm) - start
+$       cc_com = f$extract(start,len,cparm)
+        if (cc_com .nes. "DECC") .and. -
+           (cc_com .nes. "VAXC") .and. -
+           (cc_com .nes. "GNUC")
+$       then
+$         write sys$output "Unsupported compiler choice ''cc_com' ignored"
+$         write sys$output "Use DECC, VAXC, or GNUC instead"
+$       else
+$         if cc_com .eqs. "DECC" then its_decc = true
+$         if cc_com .eqs. "VAXC" then its_vaxc = true
+$         if cc_com .eqs. "GNUC" then its_gnuc = true
+$       endif
+$     endif
+$     if f$locate("MAKE=",cparm) .lt. f$length(cparm)
+$     then
+$       start  = f$locate("=",cparm) + 1
+$       len    = f$length(cparm) - start
+$       mmks = f$extract(start,len,cparm)
+$       if (mmks .eqs. "MMK") .or. (mmks .eqs. "MMS")
+$       then
+$         make = mmks
+$       else
+$         write sys$output "Unsupported make choice ''mmks' ignored"
+$         write sys$output "Use MMK or MMS instead"
+$       endif
+$     endif
+$     if cparm .eqs. "HELP" then gosub bhelp
+$   endif
+$   i = i + 1
+$   goto opt_loop
+$ endif
+$ return
+$!------------------------------------------------------------------------------
+$!
+$! Look for the compiler used
+$!
+$! Version history
+$! 0.01 20040223 First version to receive a number
+$! 0.02 20040229 Save/set value of decc$no_rooted_search_lists
+$! 0.03 20060202 Extend handling of GNU C
+$! 0.04 20090402 Compaq -> hp
+$CHECK_COMPILER:
+$ if (.not. (its_decc .or. its_vaxc .or. its_gnuc))
+$ then
+$   its_decc = (f$search("SYS$SYSTEM:DECC$COMPILER.EXE") .nes. "")
+$   its_vaxc = .not. its_decc .and. (F$Search("SYS$System:VAXC.Exe") .nes. "")
+$   its_gnuc = .not. (its_decc .or. its_vaxc) .and. (f$trnlnm("gnu_cc") .nes. "")
+$ endif
+$!
+$! Exit if no compiler available
+$!
+$ if (.not. (its_decc .or. its_vaxc .or. its_gnuc))
+$ then goto CC_ERR
+$ else
+$   if its_decc
+$   then
+$     write sys$output "CC compiler check ... hp C"
+$     if f$trnlnm("decc$no_rooted_search_lists") .nes. ""
+$     then
+$       dnrsl = f$trnlnm("decc$no_rooted_search_lists")
+$     endif
+$     define/nolog decc$no_rooted_search_lists 1
+$   else
+$     if its_vaxc then write sys$output "CC compiler check ... VAX C"
+$     if its_gnuc
+$     then
+$         write sys$output "CC compiler check ... GNU C"
+$         if f$trnlnm(topt) then write topt "gnu_cc:[000000]gcclib.olb/lib"
+$         if f$trnlnm(optf) then write optf "gnu_cc:[000000]gcclib.olb/lib"
+$         cc = "gcc"
+$     endif
+$     if f$trnlnm(topt) then write topt "sys$share:vaxcrtl.exe/share"
+$     if f$trnlnm(optf) then write optf "sys$share:vaxcrtl.exe/share"
+$   endif
+$ endif
+$ return
+$!------------------------------------------------------------------------------
+$!
+$! If MMS/MMK are available dump out the descrip.mms if required
+$!
+$CREA_MMS:
+$ write sys$output "Creating descrip.mms..."
+$ create descrip.mms
+$ open/append out descrip.mms
+$ copy sys$input: out
+$ deck
+# descrip.mms: MMS description file for building zlib on VMS
+# written by Martin P.J. Zinser
+# <zinser@zinser.no-ip.info or martin.zinser@eurexchange.com>
+
+OBJS = adler32.obj, compress.obj, crc32.obj, gzclose.obj, gzlib.obj\
+       gzread.obj, gzwrite.obj, uncompr.obj, infback.obj\
+       deflate.obj, trees.obj, zutil.obj, inflate.obj, \
+       inftrees.obj, inffast.obj
+
+$ eod
+$ write out "CFLAGS=", ccopt
+$ write out "LOPTS=", lopts
+$ write out "all : example.exe minigzip.exe libz.olb"
+$ copy sys$input: out
+$ deck
+        @ write sys$output " Example applications available"
+
+libz.olb : libz.olb($(OBJS))
+	@ write sys$output " libz available"
+
+example.exe : example.obj libz.olb
+              link $(LOPTS) example,libz.olb/lib
+
+minigzip.exe : minigzip.obj libz.olb
+              link $(LOPTS) minigzip,libz.olb/lib
+
+clean :
+	delete *.obj;*,libz.olb;*,*.opt;*,*.exe;*
+
+
+# Other dependencies.
+adler32.obj  : adler32.c zutil.h zlib.h zconf.h
+compress.obj : compress.c zlib.h zconf.h
+crc32.obj    : crc32.c zutil.h zlib.h zconf.h
+deflate.obj  : deflate.c deflate.h zutil.h zlib.h zconf.h
+example.obj  : [.test]example.c zlib.h zconf.h
+gzclose.obj  : gzclose.c zutil.h zlib.h zconf.h
+gzlib.obj    : gzlib.c zutil.h zlib.h zconf.h
+gzread.obj   : gzread.c zutil.h zlib.h zconf.h
+gzwrite.obj  : gzwrite.c zutil.h zlib.h zconf.h
+inffast.obj  : inffast.c zutil.h zlib.h zconf.h inftrees.h inffast.h
+inflate.obj  : inflate.c zutil.h zlib.h zconf.h
+inftrees.obj : inftrees.c zutil.h zlib.h zconf.h inftrees.h
+minigzip.obj : [.test]minigzip.c zlib.h zconf.h
+trees.obj    : trees.c deflate.h zutil.h zlib.h zconf.h
+uncompr.obj  : uncompr.c zlib.h zconf.h
+zutil.obj    : zutil.c zutil.h zlib.h zconf.h
+infback.obj  : infback.c zutil.h inftrees.h inflate.h inffast.h inffixed.h
+$ eod
+$ close out
+$ return
+$!------------------------------------------------------------------------------
+$!
+$! Read list of core library sources from makefile.in and create options
+$! needed to build shareable image
+$!
+$CREA_OLIST:
+$ open/read min makefile.in
+$ open/write mod modules.opt
+$ src_check_list = "OBJZ =#OBJG ="
+$MRLOOP:
+$ read/end=mrdone min rec
+$ i = 0
+$SRC_CHECK_LOOP:
+$ src_check = f$element(i, "#", src_check_list)
+$ i = i+1
+$ if src_check .eqs. "#" then goto mrloop
+$ if (f$extract(0,6,rec) .nes. src_check) then goto src_check_loop
+$ rec = rec - src_check
+$ gosub extra_filnam
+$ if (f$element(1,"\",rec) .eqs. "\") then goto mrloop
+$MRSLOOP:
+$ read/end=mrdone min rec
+$ gosub extra_filnam
+$ if (f$element(1,"\",rec) .nes. "\") then goto mrsloop
+$MRDONE:
+$ close min
+$ close mod
+$ return
+$!------------------------------------------------------------------------------
+$!
+$! Take record extracted in crea_olist and split it into single filenames
+$!
+$EXTRA_FILNAM:
+$ myrec = f$edit(rec - "\", "trim,compress")
+$ i = 0
+$FELOOP:
+$ srcfil = f$element(i," ", myrec)
+$ if (srcfil .nes. " ")
+$ then
+$   write mod f$parse(srcfil,,,"NAME"), ".obj"
+$   i = i + 1
+$   goto feloop
+$ endif
+$ return
+$!------------------------------------------------------------------------------
+$!
+$! Find current Zlib version number
+$!
+$FIND_VERSION:
+$ open/read h_in 'v_file'
+$hloop:
+$ read/end=hdone h_in rec
+$ rec = f$edit(rec,"TRIM")
+$ if (f$extract(0,1,rec) .nes. "#") then goto hloop
+$ rec = f$edit(rec - "#", "TRIM")
+$ if f$element(0," ",rec) .nes. "define" then goto hloop
+$ if f$element(1," ",rec) .eqs. v_string
+$ then
+$   version = 'f$element(2," ",rec)'
+$   goto hdone
+$ endif
+$ goto hloop
+$hdone:
+$ close h_in
+$ return
+$!------------------------------------------------------------------------------
+$!
+$CHECK_CONFIG:
+$!
+$ in_ldef = f$locate(cdef,libdefs)
+$ if (in_ldef .lt. f$length(libdefs))
+$ then
+$   write aconf "#define ''cdef' 1"
+$   libdefs = f$extract(0,in_ldef,libdefs) + -
+              f$extract(in_ldef + f$length(cdef) + 1, -
+                        f$length(libdefs) - in_ldef - f$length(cdef) - 1, -
+                        libdefs)
+$ else
+$   if (f$type('cdef') .eqs. "INTEGER")
+$   then
+$     write aconf "#define ''cdef' ", 'cdef'
+$   else
+$     if (f$type('cdef') .eqs. "STRING")
+$     then
+$       write aconf "#define ''cdef' ", """", '''cdef'', """"
+$     else
+$       gosub check_cc_def
+$     endif
+$   endif
+$ endif
+$ return
+$!------------------------------------------------------------------------------
+$!
+$! Check if this is a define relating to the properties of the C/C++
+$! compiler
+$!
+$ CHECK_CC_DEF:
+$ if (cdef .eqs. "_LARGEFILE64_SOURCE")
+$ then
+$   copy sys$input: 'tc'
+$   deck
+#include "tconfig"
+#define _LARGEFILE
+#include <stdio.h>
+
+int main(){
+FILE *fp;
+  fp = fopen("temp.txt","r");
+  fseeko(fp,1,SEEK_SET);
+  fclose(fp);
+}
+
+$   eod
+$   test_inv = false
+$   comm_h = false
+$   gosub cc_prop_check
+$   return
+$ endif
+$ write aconf "/* ", line, " */"
+$ return
+$!------------------------------------------------------------------------------
+$!
+$! Check for properties of C/C++ compiler
+$!
+$! Version history
+$! 0.01 20031020 First version to receive a number
+$! 0.02 20031022 Added logic for defines with value
+$! 0.03 20040309 Make sure local config file gets not deleted
+$! 0.04 20041230 Also write include for configure run
+$! 0.05 20050103 Add processing of "comment defines"
+$CC_PROP_CHECK:
+$ cc_prop = true
+$ is_need = false
+$ is_need = (f$extract(0,4,cdef) .eqs. "NEED") .or. (test_inv .eq. true)
+$ if f$search(th) .eqs. "" then create 'th'
+$ set message/nofac/noident/nosever/notext
+$ on error then continue
+$ cc 'tmpnam'
+$ if .not. ($status)  then cc_prop = false
+$ on error then continue
+$! The headers might lie about the capabilities of the RTL
+$ link 'tmpnam',tmp.opt/opt
+$ if .not. ($status)  then cc_prop = false
+$ set message/fac/ident/sever/text
+$ on error then goto err_exit
+$ delete/nolog 'tmpnam'.*;*/exclude='th'
+$ if (cc_prop .and. .not. is_need) .or. -
+     (.not. cc_prop .and. is_need)
+$ then
+$   write sys$output "Checking for ''cdef'... yes"
+$   if f$type('cdef_val'_yes) .nes. ""
+$   then
+$     if f$type('cdef_val'_yes) .eqs. "INTEGER" -
+         then call write_config f$fao("#define !AS !UL",cdef,'cdef_val'_yes)
+$     if f$type('cdef_val'_yes) .eqs. "STRING" -
+         then call write_config f$fao("#define !AS !AS",cdef,'cdef_val'_yes)
+$   else
+$     call write_config f$fao("#define !AS 1",cdef)
+$   endif
+$   if (cdef .eqs. "HAVE_FSEEKO") .or. (cdef .eqs. "_LARGE_FILES") .or. -
+       (cdef .eqs. "_LARGEFILE64_SOURCE") then -
+      call write_config f$string("#define _LARGEFILE 1")
+$ else
+$   write sys$output "Checking for ''cdef'... no"
+$   if (comm_h)
+$   then
+      call write_config f$fao("/* !AS */",line)
+$   else
+$     if f$type('cdef_val'_no) .nes. ""
+$     then
+$       if f$type('cdef_val'_no) .eqs. "INTEGER" -
+           then call write_config f$fao("#define !AS !UL",cdef,'cdef_val'_no)
+$       if f$type('cdef_val'_no) .eqs. "STRING" -
+           then call write_config f$fao("#define !AS !AS",cdef,'cdef_val'_no)
+$     else
+$       call write_config f$fao("#undef !AS",cdef)
+$     endif
+$   endif
+$ endif
+$ return
+$!------------------------------------------------------------------------------
+$!
+$! Check for properties of C/C++ compiler with multiple result values
+$!
+$! Version history
+$! 0.01 20040127 First version
+$! 0.02 20050103 Reconcile changes from cc_prop up to version 0.05
+$CC_MPROP_CHECK:
+$ cc_prop = true
+$ i    = 1
+$ idel = 1
+$ MT_LOOP:
+$ if f$type(result_'i') .eqs. "STRING"
+$ then
+$   set message/nofac/noident/nosever/notext
+$   on error then continue
+$   cc 'tmpnam'_'i'
+$   if .not. ($status)  then cc_prop = false
+$   on error then continue
+$! The headers might lie about the capabilities of the RTL
+$   link 'tmpnam'_'i',tmp.opt/opt
+$   if .not. ($status)  then cc_prop = false
+$   set message/fac/ident/sever/text
+$   on error then goto err_exit
+$   delete/nolog 'tmpnam'_'i'.*;*
+$   if (cc_prop)
+$   then
+$     write sys$output "Checking for ''cdef'... ", mdef_'i'
+$     if f$type(mdef_'i') .eqs. "INTEGER" -
+         then call write_config f$fao("#define !AS !UL",cdef,mdef_'i')
+$     if f$type('cdef_val'_yes) .eqs. "STRING" -
+         then call write_config f$fao("#define !AS !AS",cdef,mdef_'i')
+$     goto msym_clean
+$   else
+$     i = i + 1
+$     goto mt_loop
+$   endif
+$ endif
+$ write sys$output "Checking for ''cdef'... no"
+$ call write_config f$fao("#undef !AS",cdef)
+$ MSYM_CLEAN:
+$ if (idel .le. msym_max)
+$ then
+$   delete/sym mdef_'idel'
+$   idel = idel + 1
+$   goto msym_clean
+$ endif
+$ return
+$!------------------------------------------------------------------------------
+$!
+$! Write configuration to both permanent and temporary config file
+$!
+$! Version history
+$! 0.01 20031029 First version to receive a number
+$!
+$WRITE_CONFIG: SUBROUTINE
+$  write aconf 'p1'
+$  open/append confh 'th'
+$  write confh 'p1'
+$  close confh
+$ENDSUBROUTINE
+$!------------------------------------------------------------------------------
+$!
+$! Analyze the project map file and create the symbol vector for a shareable
+$! image from it
+$!
+$! Version history
+$! 0.01 20120128 First version
+$! 0.02 20120226 Add pre-load logic
+$!
+$ MAP_2_SHOPT: Subroutine
+$!
+$ SAY := "WRITE_ SYS$OUTPUT"
+$!
+$ IF F$SEARCH("''P1'") .EQS. ""
+$ THEN
+$    SAY "MAP_2_SHOPT-E-NOSUCHFILE:  Error, inputfile ''p1' not available"
+$    goto exit_m2s
+$ ENDIF
+$ IF "''P2'" .EQS. ""
+$ THEN
+$    SAY "MAP_2_SHOPT:  Error, no output file provided"
+$    goto exit_m2s
+$ ENDIF
+$!
+$ module1 = "deflate#deflateEnd#deflateInit_#deflateParams#deflateSetDictionary"
+$ module2 = "gzclose#gzerror#gzgetc#gzgets#gzopen#gzprintf#gzputc#gzputs#gzread"
+$ module3 = "gzseek#gztell#inflate#inflateEnd#inflateInit_#inflateSetDictionary"
+$ module4 = "inflateSync#uncompress#zlibVersion#compress"
+$ open/read map 'p1
+$ if axp .or. ia64
+$ then
+$     open/write aopt a.opt
+$     open/write bopt b.opt
+$     write aopt " CASE_SENSITIVE=YES"
+$     write bopt "SYMBOL_VECTOR= (-"
+$     mod_sym_num = 1
+$ MOD_SYM_LOOP:
+$     if f$type(module'mod_sym_num') .nes. ""
+$     then
+$         mod_in = 0
+$ MOD_SYM_IN:
+$         shared_proc = f$element(mod_in, "#", module'mod_sym_num')
+$         if shared_proc .nes. "#"
+$         then
+$             write aopt f$fao(" symbol_vector=(!AS/!AS=PROCEDURE)",-
+        		       f$edit(shared_proc,"upcase"),shared_proc)
+$             write bopt f$fao("!AS=PROCEDURE,-",shared_proc)
+$             mod_in = mod_in + 1
+$             goto mod_sym_in
+$         endif
+$         mod_sym_num = mod_sym_num + 1
+$         goto mod_sym_loop
+$     endif
+$MAP_LOOP:
+$     read/end=map_end map line
+$     if (f$locate("{",line).lt. f$length(line)) .or. -
+         (f$locate("global:", line) .lt. f$length(line))
+$     then
+$         proc = true
+$         goto map_loop
+$     endif
+$     if f$locate("}",line).lt. f$length(line) then proc = false
+$     if f$locate("local:", line) .lt. f$length(line) then proc = false
+$     if proc
+$     then
+$         shared_proc = f$edit(line,"collapse")
+$         chop_semi = f$locate(";", shared_proc)
+$         if chop_semi .lt. f$length(shared_proc) then -
+              shared_proc = f$extract(0, chop_semi, shared_proc)
+$         write aopt f$fao(" symbol_vector=(!AS/!AS=PROCEDURE)",-
+        			 f$edit(shared_proc,"upcase"),shared_proc)
+$         write bopt f$fao("!AS=PROCEDURE,-",shared_proc)
+$     endif
+$     goto map_loop
+$MAP_END:
+$     close/nolog aopt
+$     close/nolog bopt
+$     open/append libopt 'p2'
+$     open/read aopt a.opt
+$     open/read bopt b.opt
+$ALOOP:
+$     read/end=aloop_end aopt line
+$     write libopt line
+$     goto aloop
+$ALOOP_END:
+$     close/nolog aopt
+$     sv = ""
+$BLOOP:
+$     read/end=bloop_end bopt svn
+$     if (svn.nes."")
+$     then
+$        if (sv.nes."") then write libopt sv
+$        sv = svn
+$     endif
+$     goto bloop
+$BLOOP_END:
+$     write libopt f$extract(0,f$length(sv)-2,sv), "-"
+$     write libopt ")"
+$     close/nolog bopt
+$     delete/nolog/noconf a.opt;*,b.opt;*
+$ else
+$     if vax
+$     then
+$     open/append libopt 'p2'
+$     mod_sym_num = 1
+$ VMOD_SYM_LOOP:
+$     if f$type(module'mod_sym_num') .nes. ""
+$     then
+$         mod_in = 0
+$ VMOD_SYM_IN:
+$         shared_proc = f$element(mod_in, "#", module'mod_sym_num')
+$         if shared_proc .nes. "#"
+$         then
+$     	      write libopt f$fao("UNIVERSAL=!AS",-
+      	  			     f$edit(shared_proc,"upcase"))
+$             mod_in = mod_in + 1
+$             goto vmod_sym_in
+$         endif
+$         mod_sym_num = mod_sym_num + 1
+$         goto vmod_sym_loop
+$     endif
+$VMAP_LOOP:
+$     	  read/end=vmap_end map line
+$     	  if (f$locate("{",line).lt. f$length(line)) .or. -
+   	      (f$locate("global:", line) .lt. f$length(line))
+$     	  then
+$     	      proc = true
+$     	      goto vmap_loop
+$     	  endif
+$     	  if f$locate("}",line).lt. f$length(line) then proc = false
+$     	  if f$locate("local:", line) .lt. f$length(line) then proc = false
+$     	  if proc
+$     	  then
+$     	      shared_proc = f$edit(line,"collapse")
+$     	      chop_semi = f$locate(";", shared_proc)
+$     	      if chop_semi .lt. f$length(shared_proc) then -
+      	  	  shared_proc = f$extract(0, chop_semi, shared_proc)
+$     	      write libopt f$fao("UNIVERSAL=!AS",-
+      	  			     f$edit(shared_proc,"upcase"))
+$     	  endif
+$     	  goto vmap_loop
+$VMAP_END:
+$     else
+$         write sys$output "Unknown Architecture (Not VAX, AXP, or IA64)"
+$         write sys$output "No options file created"
+$     endif
+$ endif
+$ EXIT_M2S:
+$ close/nolog map
+$ close/nolog libopt
+$ endsubroutine
diff --git a/compat/zlib/msdos/Makefile.bor b/compat/zlib/msdos/Makefile.bor
new file mode 100644
index 0000000..3d12a2c
--- /dev/null
+++ b/compat/zlib/msdos/Makefile.bor
@@ -0,0 +1,115 @@
+# Makefile for zlib
+# Borland C++
+# Last updated: 15-Mar-2003
+
+# To use, do "make -fmakefile.bor"
+# To compile in small model, set below: MODEL=s
+
+# WARNING: the small model is supported but only for small values of
+# MAX_WBITS and MAX_MEM_LEVEL. For example:
+#    -DMAX_WBITS=11 -DDEF_WBITS=11 -DMAX_MEM_LEVEL=3
+# If you wish to reduce the memory requirements (default 256K for big
+# objects plus a few K), you can add to the LOC macro below:
+#   -DMAX_MEM_LEVEL=7 -DMAX_WBITS=14
+# See zconf.h for details about the memory requirements.
+
+# ------------ Turbo C++, Borland C++ ------------
+
+#    Optional nonstandard preprocessor flags (e.g. -DMAX_MEM_LEVEL=7)
+#    should be added to the environment via "set LOCAL_ZLIB=-DFOO" or added
+#    to the declaration of LOC here:
+LOC = $(LOCAL_ZLIB)
+
+# type for CPU required: 0: 8086, 1: 80186, 2: 80286, 3: 80386, etc.
+CPU_TYP = 0
+
+# memory model: one of s, m, c, l (small, medium, compact, large)
+MODEL=l
+
+# replace bcc with tcc for Turbo C++ 1.0, with bcc32 for the 32 bit version
+CC=bcc
+LD=bcc
+AR=tlib
+
+# compiler flags
+# replace "-O2" by "-O -G -a -d" for Turbo C++ 1.0
+CFLAGS=-O2 -Z -m$(MODEL) $(LOC)
+
+LDFLAGS=-m$(MODEL) -f-
+
+
+# variables
+ZLIB_LIB = zlib_$(MODEL).lib
+
+OBJ1 = adler32.obj compress.obj crc32.obj deflate.obj gzclose.obj gzlib.obj gzread.obj
+OBJ2 = gzwrite.obj infback.obj inffast.obj inflate.obj inftrees.obj trees.obj uncompr.obj zutil.obj
+OBJP1 = +adler32.obj+compress.obj+crc32.obj+deflate.obj+gzclose.obj+gzlib.obj+gzread.obj
+OBJP2 = +gzwrite.obj+infback.obj+inffast.obj+inflate.obj+inftrees.obj+trees.obj+uncompr.obj+zutil.obj
+
+
+# targets
+all: $(ZLIB_LIB) example.exe minigzip.exe
+
+.c.obj:
+	$(CC) -c $(CFLAGS) $*.c
+
+adler32.obj: adler32.c zlib.h zconf.h
+
+compress.obj: compress.c zlib.h zconf.h
+
+crc32.obj: crc32.c zlib.h zconf.h crc32.h
+
+deflate.obj: deflate.c deflate.h zutil.h zlib.h zconf.h
+
+gzclose.obj: gzclose.c zlib.h zconf.h gzguts.h
+
+gzlib.obj: gzlib.c zlib.h zconf.h gzguts.h
+
+gzread.obj: gzread.c zlib.h zconf.h gzguts.h
+
+gzwrite.obj: gzwrite.c zlib.h zconf.h gzguts.h
+
+infback.obj: infback.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
+ inffast.h inffixed.h
+
+inffast.obj: inffast.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
+ inffast.h
+
+inflate.obj: inflate.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
+ inffast.h inffixed.h
+
+inftrees.obj: inftrees.c zutil.h zlib.h zconf.h inftrees.h
+
+trees.obj: trees.c zutil.h zlib.h zconf.h deflate.h trees.h
+
+uncompr.obj: uncompr.c zlib.h zconf.h
+
+zutil.obj: zutil.c zutil.h zlib.h zconf.h
+
+example.obj: test/example.c zlib.h zconf.h
+
+minigzip.obj: test/minigzip.c zlib.h zconf.h
+
+
+# the command line is cut to fit in the MS-DOS 128 byte limit:
+$(ZLIB_LIB): $(OBJ1) $(OBJ2)
+	-del $(ZLIB_LIB)
+	$(AR) $(ZLIB_LIB) $(OBJP1)
+	$(AR) $(ZLIB_LIB) $(OBJP2)
+
+example.exe: example.obj $(ZLIB_LIB)
+	$(LD) $(LDFLAGS) example.obj $(ZLIB_LIB)
+
+minigzip.exe: minigzip.obj $(ZLIB_LIB)
+	$(LD) $(LDFLAGS) minigzip.obj $(ZLIB_LIB)
+
+test: example.exe minigzip.exe
+	example
+	echo hello world | minigzip | minigzip -d
+
+clean:
+	-del *.obj
+	-del *.lib
+	-del *.exe
+	-del zlib_*.bak
+	-del foo.gz
diff --git a/compat/zlib/msdos/Makefile.dj2 b/compat/zlib/msdos/Makefile.dj2
new file mode 100644
index 0000000..29b0395
--- /dev/null
+++ b/compat/zlib/msdos/Makefile.dj2
@@ -0,0 +1,104 @@
+# Makefile for zlib.  Modified for djgpp v2.0 by F. J. Donahoe, 3/15/96.
+# Copyright (C) 1995-1998 Jean-loup Gailly.
+# For conditions of distribution and use, see copyright notice in zlib.h
+
+# To compile, or to compile and test, type:
+#
+#   make -fmakefile.dj2;  make test -fmakefile.dj2
+#
+# To install libz.a, zconf.h and zlib.h in the djgpp directories, type:
+#
+#    make install -fmakefile.dj2
+#
+# after first defining LIBRARY_PATH and INCLUDE_PATH in djgpp.env as
+# in the sample below if the pattern of the DJGPP distribution is to
+# be followed.  Remember that, while <sp>'es around <=> are ignored in
+# makefiles, they are *not* in batch files or in djgpp.env.
+# - - - - -
+# [make]
+# INCLUDE_PATH=%\>;INCLUDE_PATH%%\DJDIR%\include
+# LIBRARY_PATH=%\>;LIBRARY_PATH%%\DJDIR%\lib
+# BUTT=-m486
+# - - - - -
+# Alternately, these variables may be defined below, overriding the values
+# in djgpp.env, as
+# INCLUDE_PATH=c:\usr\include
+# LIBRARY_PATH=c:\usr\lib
+
+CC=gcc
+
+#CFLAGS=-MMD -O
+#CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7
+#CFLAGS=-MMD -g -DDEBUG
+CFLAGS=-MMD -O3 $(BUTT) -Wall -Wwrite-strings -Wpointer-arith -Wconversion \
+             -Wstrict-prototypes -Wmissing-prototypes
+
+# If cp.exe is available, replace "copy /Y" with "cp -fp" .
+CP=copy /Y
+# If gnu install.exe is available, replace $(CP) with ginstall.
+INSTALL=$(CP)
+# The default value of RM is "rm -f."  If "rm.exe" is found, comment out:
+RM=del
+LDLIBS=-L. -lz
+LD=$(CC) -s -o
+LDSHARED=$(CC)
+
+INCL=zlib.h zconf.h
+LIBS=libz.a
+
+AR=ar rcs
+
+prefix=/usr/local
+exec_prefix = $(prefix)
+
+OBJS = adler32.o compress.o crc32.o gzclose.o gzlib.o gzread.o gzwrite.o \
+       uncompr.o deflate.o trees.o zutil.o inflate.o infback.o inftrees.o inffast.o
+
+OBJA =
+# to use the asm code: make OBJA=match.o
+
+TEST_OBJS = example.o minigzip.o
+
+all: example.exe minigzip.exe
+
+check: test
+test: all
+	./example
+	echo hello world | .\minigzip | .\minigzip -d
+
+%.o : %.c
+	$(CC) $(CFLAGS) -c $< -o $@
+
+libz.a: $(OBJS) $(OBJA)
+	$(AR) $@ $(OBJS) $(OBJA)
+
+%.exe : %.o $(LIBS)
+	$(LD) $@ $< $(LDLIBS)
+
+# INCLUDE_PATH and LIBRARY_PATH were set for [make] in djgpp.env .
+
+.PHONY : uninstall clean
+
+install: $(INCL) $(LIBS)
+	-@if not exist $(INCLUDE_PATH)\nul mkdir $(INCLUDE_PATH)
+	-@if not exist $(LIBRARY_PATH)\nul mkdir $(LIBRARY_PATH)
+	$(INSTALL) zlib.h $(INCLUDE_PATH)
+	$(INSTALL) zconf.h $(INCLUDE_PATH)
+	$(INSTALL) libz.a $(LIBRARY_PATH)
+
+uninstall:
+	$(RM) $(INCLUDE_PATH)\zlib.h
+	$(RM) $(INCLUDE_PATH)\zconf.h
+	$(RM) $(LIBRARY_PATH)\libz.a
+
+clean:
+	$(RM) *.d
+	$(RM) *.o
+	$(RM) *.exe
+	$(RM) libz.a
+	$(RM) foo.gz
+
+DEPS := $(wildcard *.d)
+ifneq ($(DEPS),)
+include $(DEPS)
+endif
diff --git a/compat/zlib/msdos/Makefile.emx b/compat/zlib/msdos/Makefile.emx
new file mode 100644
index 0000000..9c1b57a
--- /dev/null
+++ b/compat/zlib/msdos/Makefile.emx
@@ -0,0 +1,69 @@
+# Makefile for zlib.  Modified for emx 0.9c by Chr. Spieler, 6/17/98.
+# Copyright (C) 1995-1998 Jean-loup Gailly.
+# For conditions of distribution and use, see copyright notice in zlib.h
+
+# To compile, or to compile and test, type:
+#
+#   make -fmakefile.emx;  make test -fmakefile.emx
+#
+
+CC=gcc
+
+#CFLAGS=-MMD -O
+#CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7
+#CFLAGS=-MMD -g -DDEBUG
+CFLAGS=-MMD -O3 $(BUTT) -Wall -Wwrite-strings -Wpointer-arith -Wconversion \
+             -Wstrict-prototypes -Wmissing-prototypes
+
+# If cp.exe is available, replace "copy /Y" with "cp -fp" .
+CP=copy /Y
+# If gnu install.exe is available, replace $(CP) with ginstall.
+INSTALL=$(CP)
+# The default value of RM is "rm -f."  If "rm.exe" is found, comment out:
+RM=del
+LDLIBS=-L. -lzlib
+LD=$(CC) -s -o
+LDSHARED=$(CC)
+
+INCL=zlib.h zconf.h
+LIBS=zlib.a
+
+AR=ar rcs
+
+prefix=/usr/local
+exec_prefix = $(prefix)
+
+OBJS = adler32.o compress.o crc32.o gzclose.o gzlib.o gzread.o gzwrite.o \
+       uncompr.o deflate.o trees.o zutil.o inflate.o infback.o inftrees.o inffast.o
+
+TEST_OBJS = example.o minigzip.o
+
+all: example.exe minigzip.exe
+
+test: all
+	./example
+	echo hello world | .\minigzip | .\minigzip -d
+
+%.o : %.c
+	$(CC) $(CFLAGS) -c $< -o $@
+
+zlib.a: $(OBJS)
+	$(AR) $@ $(OBJS)
+
+%.exe : %.o $(LIBS)
+	$(LD) $@ $< $(LDLIBS)
+
+
+.PHONY : clean
+
+clean:
+	$(RM) *.d
+	$(RM) *.o
+	$(RM) *.exe
+	$(RM) zlib.a
+	$(RM) foo.gz
+
+DEPS := $(wildcard *.d)
+ifneq ($(DEPS),)
+include $(DEPS)
+endif
diff --git a/compat/zlib/msdos/Makefile.msc b/compat/zlib/msdos/Makefile.msc
new file mode 100644
index 0000000..ae83786
--- /dev/null
+++ b/compat/zlib/msdos/Makefile.msc
@@ -0,0 +1,112 @@
+# Makefile for zlib
+# Microsoft C 5.1 or later
+# Last updated: 19-Mar-2003
+
+# To use, do "make makefile.msc"
+# To compile in small model, set below: MODEL=S
+
+# If you wish to reduce the memory requirements (default 256K for big
+# objects plus a few K), you can add to the LOC macro below:
+#   -DMAX_MEM_LEVEL=7 -DMAX_WBITS=14
+# See zconf.h for details about the memory requirements.
+
+# ------------- Microsoft C 5.1 and later -------------
+
+#    Optional nonstandard preprocessor flags (e.g. -DMAX_MEM_LEVEL=7)
+#    should be added to the environment via "set LOCAL_ZLIB=-DFOO" or added
+#    to the declaration of LOC here:
+LOC = $(LOCAL_ZLIB)
+
+# Type for CPU required: 0: 8086, 1: 80186, 2: 80286, 3: 80386, etc.
+CPU_TYP = 0
+
+# Memory model: one of S, M, C, L (small, medium, compact, large)
+MODEL=L
+
+CC=cl
+CFLAGS=-nologo -A$(MODEL) -G$(CPU_TYP) -W3 -Oait -Gs $(LOC)
+#-Ox generates bad code with MSC 5.1
+LIB_CFLAGS=-Zl $(CFLAGS)
+
+LD=link
+LDFLAGS=/noi/e/st:0x1500/noe/farcall/packcode
+# "/farcall/packcode" are only useful for `large code' memory models
+# but should be a "no-op" for small code models.
+
+
+# variables
+ZLIB_LIB = zlib_$(MODEL).lib
+
+OBJ1 = adler32.obj compress.obj crc32.obj deflate.obj gzclose.obj gzlib.obj gzread.obj
+OBJ2 = gzwrite.obj infback.obj inffast.obj inflate.obj inftrees.obj trees.obj uncompr.obj zutil.obj
+
+
+# targets
+all:  $(ZLIB_LIB) example.exe minigzip.exe
+
+.c.obj:
+	$(CC) -c $(LIB_CFLAGS) $*.c
+
+adler32.obj: adler32.c zlib.h zconf.h
+
+compress.obj: compress.c zlib.h zconf.h
+
+crc32.obj: crc32.c zlib.h zconf.h crc32.h
+
+deflate.obj: deflate.c deflate.h zutil.h zlib.h zconf.h
+
+gzclose.obj: gzclose.c zlib.h zconf.h gzguts.h
+
+gzlib.obj: gzlib.c zlib.h zconf.h gzguts.h
+
+gzread.obj: gzread.c zlib.h zconf.h gzguts.h
+
+gzwrite.obj: gzwrite.c zlib.h zconf.h gzguts.h
+
+infback.obj: infback.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
+ inffast.h inffixed.h
+
+inffast.obj: inffast.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
+ inffast.h
+
+inflate.obj: inflate.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
+ inffast.h inffixed.h
+
+inftrees.obj: inftrees.c zutil.h zlib.h zconf.h inftrees.h
+
+trees.obj: trees.c zutil.h zlib.h zconf.h deflate.h trees.h
+
+uncompr.obj: uncompr.c zlib.h zconf.h
+
+zutil.obj: zutil.c zutil.h zlib.h zconf.h
+
+example.obj: test/example.c zlib.h zconf.h
+	$(CC) -c $(CFLAGS) $*.c
+
+minigzip.obj: test/minigzip.c zlib.h zconf.h
+	$(CC) -c $(CFLAGS) $*.c
+
+
+# the command line is cut to fit in the MS-DOS 128 byte limit:
+$(ZLIB_LIB): $(OBJ1) $(OBJ2)
+	if exist $(ZLIB_LIB) del $(ZLIB_LIB)
+	lib $(ZLIB_LIB) $(OBJ1);
+	lib $(ZLIB_LIB) $(OBJ2);
+
+example.exe: example.obj $(ZLIB_LIB)
+	$(LD) $(LDFLAGS) example.obj,,,$(ZLIB_LIB);
+
+minigzip.exe: minigzip.obj $(ZLIB_LIB)
+	$(LD) $(LDFLAGS) minigzip.obj,,,$(ZLIB_LIB);
+
+test: example.exe minigzip.exe
+	example
+	echo hello world | minigzip | minigzip -d
+
+clean:
+	-del *.obj
+	-del *.lib
+	-del *.exe
+	-del *.map
+	-del zlib_*.bak
+	-del foo.gz
diff --git a/compat/zlib/msdos/Makefile.tc b/compat/zlib/msdos/Makefile.tc
new file mode 100644
index 0000000..5aec82a
--- /dev/null
+++ b/compat/zlib/msdos/Makefile.tc
@@ -0,0 +1,100 @@
+# Makefile for zlib
+# Turbo C 2.01, Turbo C++ 1.01
+# Last updated: 15-Mar-2003
+
+# To use, do "make -fmakefile.tc"
+# To compile in small model, set below: MODEL=s
+
+# WARNING: the small model is supported but only for small values of
+# MAX_WBITS and MAX_MEM_LEVEL. For example:
+#    -DMAX_WBITS=11 -DMAX_MEM_LEVEL=3
+# If you wish to reduce the memory requirements (default 256K for big
+# objects plus a few K), you can add to CFLAGS below:
+#   -DMAX_MEM_LEVEL=7 -DMAX_WBITS=14
+# See zconf.h for details about the memory requirements.
+
+# ------------ Turbo C 2.01, Turbo C++ 1.01 ------------
+MODEL=l
+CC=tcc
+LD=tcc
+AR=tlib
+# CFLAGS=-O2 -G -Z -m$(MODEL) -DMAX_WBITS=11 -DMAX_MEM_LEVEL=3
+CFLAGS=-O2 -G -Z -m$(MODEL)
+LDFLAGS=-m$(MODEL) -f-
+
+
+# variables
+ZLIB_LIB = zlib_$(MODEL).lib
+
+OBJ1 = adler32.obj compress.obj crc32.obj deflate.obj gzclose.obj gzlib.obj gzread.obj
+OBJ2 = gzwrite.obj infback.obj inffast.obj inflate.obj inftrees.obj trees.obj uncompr.obj zutil.obj
+OBJP1 = +adler32.obj+compress.obj+crc32.obj+deflate.obj+gzclose.obj+gzlib.obj+gzread.obj
+OBJP2 = +gzwrite.obj+infback.obj+inffast.obj+inflate.obj+inftrees.obj+trees.obj+uncompr.obj+zutil.obj
+
+
+# targets
+all: $(ZLIB_LIB) example.exe minigzip.exe
+
+.c.obj:
+	$(CC) -c $(CFLAGS) $*.c
+
+adler32.obj: adler32.c zlib.h zconf.h
+
+compress.obj: compress.c zlib.h zconf.h
+
+crc32.obj: crc32.c zlib.h zconf.h crc32.h
+
+deflate.obj: deflate.c deflate.h zutil.h zlib.h zconf.h
+
+gzclose.obj: gzclose.c zlib.h zconf.h gzguts.h
+
+gzlib.obj: gzlib.c zlib.h zconf.h gzguts.h
+
+gzread.obj: gzread.c zlib.h zconf.h gzguts.h
+
+gzwrite.obj: gzwrite.c zlib.h zconf.h gzguts.h
+
+infback.obj: infback.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
+ inffast.h inffixed.h
+
+inffast.obj: inffast.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
+ inffast.h
+
+inflate.obj: inflate.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
+ inffast.h inffixed.h
+
+inftrees.obj: inftrees.c zutil.h zlib.h zconf.h inftrees.h
+
+trees.obj: trees.c zutil.h zlib.h zconf.h deflate.h trees.h
+
+uncompr.obj: uncompr.c zlib.h zconf.h
+
+zutil.obj: zutil.c zutil.h zlib.h zconf.h
+
+example.obj: test/example.c zlib.h zconf.h
+
+minigzip.obj: test/minigzip.c zlib.h zconf.h
+
+
+# the command line is cut to fit in the MS-DOS 128 byte limit:
+$(ZLIB_LIB): $(OBJ1) $(OBJ2)
+	-del $(ZLIB_LIB)
+	$(AR) $(ZLIB_LIB) $(OBJP1)
+	$(AR) $(ZLIB_LIB) $(OBJP2)
+
+example.exe: example.obj $(ZLIB_LIB)
+	$(LD) $(LDFLAGS) example.obj $(ZLIB_LIB)
+
+minigzip.exe: minigzip.obj $(ZLIB_LIB)
+	$(LD) $(LDFLAGS) minigzip.obj $(ZLIB_LIB)
+
+test: example.exe minigzip.exe
+	example
+	echo hello world | minigzip | minigzip -d
+
+clean:
+	-del *.obj
+	-del *.lib
+	-del *.exe
+	-del zlib_*.bak
+	-del foo.gz
diff --git a/compat/zlib/nintendods/Makefile b/compat/zlib/nintendods/Makefile
new file mode 100644
index 0000000..21337d0
--- /dev/null
+++ b/compat/zlib/nintendods/Makefile
@@ -0,0 +1,126 @@
+#---------------------------------------------------------------------------------
+.SUFFIXES:
+#---------------------------------------------------------------------------------
+
+ifeq ($(strip $(DEVKITARM)),)
+$(error "Please set DEVKITARM in your environment. export DEVKITARM=<path to>devkitARM")
+endif
+
+include $(DEVKITARM)/ds_rules
+
+#---------------------------------------------------------------------------------
+# TARGET is the name of the output
+# BUILD is the directory where object files & intermediate files will be placed
+# SOURCES is a list of directories containing source code
+# DATA is a list of directories containing data files
+# INCLUDES is a list of directories containing header files
+#---------------------------------------------------------------------------------
+TARGET		:=	$(shell basename $(CURDIR))
+BUILD		:=	build
+SOURCES		:=	../../
+DATA		:=	data
+INCLUDES	:=	include
+
+#---------------------------------------------------------------------------------
+# options for code generation
+#---------------------------------------------------------------------------------
+ARCH	:=	-mthumb -mthumb-interwork
+
+CFLAGS	:=	-Wall -O2\
+		-march=armv5te -mtune=arm946e-s \
+		-fomit-frame-pointer -ffast-math \
+		$(ARCH)
+
+CFLAGS	+=	$(INCLUDE) -DARM9
+CXXFLAGS	:= $(CFLAGS) -fno-rtti -fno-exceptions
+
+ASFLAGS	:=	$(ARCH) -march=armv5te -mtune=arm946e-s
+LDFLAGS	=	-specs=ds_arm9.specs -g $(ARCH) -Wl,-Map,$(notdir $*.map)
+
+#---------------------------------------------------------------------------------
+# list of directories containing libraries, this must be the top level containing
+# include and lib
+#---------------------------------------------------------------------------------
+LIBDIRS	:=	$(LIBNDS)
+
+#---------------------------------------------------------------------------------
+# no real need to edit anything past this point unless you need to add additional
+# rules for different file extensions
+#---------------------------------------------------------------------------------
+ifneq ($(BUILD),$(notdir $(CURDIR)))
+#---------------------------------------------------------------------------------
+
+export OUTPUT	:=	$(CURDIR)/lib/libz.a
+
+export VPATH	:=	$(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
+			$(foreach dir,$(DATA),$(CURDIR)/$(dir))
+
+export DEPSDIR	:=	$(CURDIR)/$(BUILD)
+
+CFILES		:=	$(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
+CPPFILES	:=	$(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp)))
+SFILES		:=	$(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
+BINFILES	:=	$(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*)))
+
+#---------------------------------------------------------------------------------
+# use CXX for linking C++ projects, CC for standard C
+#---------------------------------------------------------------------------------
+ifeq ($(strip $(CPPFILES)),)
+#---------------------------------------------------------------------------------
+	export LD	:=	$(CC)
+#---------------------------------------------------------------------------------
+else
+#---------------------------------------------------------------------------------
+	export LD	:=	$(CXX)
+#---------------------------------------------------------------------------------
+endif
+#---------------------------------------------------------------------------------
+
+export OFILES	:=	$(addsuffix .o,$(BINFILES)) \
+			$(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o)
+
+export INCLUDE	:=	$(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \
+			$(foreach dir,$(LIBDIRS),-I$(dir)/include) \
+			-I$(CURDIR)/$(BUILD)
+
+.PHONY: $(BUILD) clean all
+
+#---------------------------------------------------------------------------------
+all: $(BUILD)
+	@[ -d $@ ] || mkdir -p include
+	@cp ../../*.h include
+
+lib:
+	@[ -d $@ ] || mkdir -p $@
+	
+$(BUILD): lib
+	@[ -d $@ ] || mkdir -p $@
+	@$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
+
+#---------------------------------------------------------------------------------
+clean:
+	@echo clean ...
+	@rm -fr $(BUILD) lib
+
+#---------------------------------------------------------------------------------
+else
+
+DEPENDS	:=	$(OFILES:.o=.d)
+
+#---------------------------------------------------------------------------------
+# main targets
+#---------------------------------------------------------------------------------
+$(OUTPUT)	:	$(OFILES)
+
+#---------------------------------------------------------------------------------
+%.bin.o	:	%.bin
+#---------------------------------------------------------------------------------
+	@echo $(notdir $<)
+	@$(bin2o)
+
+
+-include $(DEPENDS)
+
+#---------------------------------------------------------------------------------------
+endif
+#---------------------------------------------------------------------------------------
diff --git a/compat/zlib/nintendods/README b/compat/zlib/nintendods/README
new file mode 100644
index 0000000..ba7a37d
--- /dev/null
+++ b/compat/zlib/nintendods/README
@@ -0,0 +1,5 @@
+This Makefile requires devkitARM (http://www.devkitpro.org/category/devkitarm/) and works inside "contrib/nds". It is based on a devkitARM template.
+
+Eduardo Costa <eduardo.m.costa@gmail.com>
+January 3, 2009
+
diff --git a/compat/zlib/old/Makefile.emx b/compat/zlib/old/Makefile.emx
new file mode 100644
index 0000000..4d6ab0e
--- /dev/null
+++ b/compat/zlib/old/Makefile.emx
@@ -0,0 +1,69 @@
+# Makefile for zlib.  Modified for emx/rsxnt by Chr. Spieler, 6/16/98.
+# Copyright (C) 1995-1998 Jean-loup Gailly.
+# For conditions of distribution and use, see copyright notice in zlib.h
+
+# To compile, or to compile and test, type:
+#
+#   make -fmakefile.emx;  make test -fmakefile.emx
+#
+
+CC=gcc -Zwin32
+
+#CFLAGS=-MMD -O
+#CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7
+#CFLAGS=-MMD -g -DDEBUG
+CFLAGS=-MMD -O3 $(BUTT) -Wall -Wwrite-strings -Wpointer-arith -Wconversion \
+             -Wstrict-prototypes -Wmissing-prototypes
+
+# If cp.exe is available, replace "copy /Y" with "cp -fp" .
+CP=copy /Y
+# If gnu install.exe is available, replace $(CP) with ginstall.
+INSTALL=$(CP)
+# The default value of RM is "rm -f."  If "rm.exe" is found, comment out:
+RM=del
+LDLIBS=-L. -lzlib
+LD=$(CC) -s -o
+LDSHARED=$(CC)
+
+INCL=zlib.h zconf.h
+LIBS=zlib.a
+
+AR=ar rcs
+
+prefix=/usr/local
+exec_prefix = $(prefix)
+
+OBJS = adler32.o compress.o crc32.o deflate.o gzclose.o gzlib.o gzread.o \
+       gzwrite.o infback.o inffast.o inflate.o inftrees.o trees.o uncompr.o zutil.o
+
+TEST_OBJS = example.o minigzip.o
+
+all: example.exe minigzip.exe
+
+test: all
+	./example
+	echo hello world | .\minigzip | .\minigzip -d
+
+%.o : %.c
+	$(CC) $(CFLAGS) -c $< -o $@
+
+zlib.a: $(OBJS)
+	$(AR) $@ $(OBJS)
+
+%.exe : %.o $(LIBS)
+	$(LD) $@ $< $(LDLIBS)
+
+
+.PHONY : clean
+
+clean:
+	$(RM) *.d
+	$(RM) *.o
+	$(RM) *.exe
+	$(RM) zlib.a
+	$(RM) foo.gz
+
+DEPS := $(wildcard *.d)
+ifneq ($(DEPS),)
+include $(DEPS)
+endif
diff --git a/compat/zlib/old/Makefile.riscos b/compat/zlib/old/Makefile.riscos
new file mode 100644
index 0000000..57e29d3
--- /dev/null
+++ b/compat/zlib/old/Makefile.riscos
@@ -0,0 +1,151 @@
+# Project:   zlib_1_03
+# Patched for zlib 1.1.2 rw@shadow.org.uk 19980430
+# test works out-of-the-box, installs `somewhere' on demand
+
+# Toolflags:
+CCflags = -c -depend !Depend -IC: -g -throwback  -DRISCOS  -fah
+C++flags = -c -depend !Depend -IC: -throwback
+Linkflags = -aif -c++ -o $@
+ObjAsmflags = -throwback -NoCache -depend !Depend
+CMHGflags =
+LibFileflags = -c -l -o $@
+Squeezeflags = -o $@
+
+# change the line below to where _you_ want the library installed.
+libdest = lib:zlib
+
+# Final targets:
+@.lib:   @.o.adler32 @.o.compress @.o.crc32 @.o.deflate @.o.gzio \
+        @.o.infblock @.o.infcodes @.o.inffast @.o.inflate @.o.inftrees @.o.infutil @.o.trees \
+        @.o.uncompr @.o.zutil
+        LibFile $(LibFileflags) @.o.adler32 @.o.compress @.o.crc32 @.o.deflate \
+        @.o.gzio @.o.infblock @.o.infcodes @.o.inffast @.o.inflate @.o.inftrees @.o.infutil \
+        @.o.trees @.o.uncompr @.o.zutil
+test:   @.minigzip @.example @.lib
+	@copy @.lib @.libc  A~C~DF~L~N~P~Q~RS~TV
+	@echo running tests: hang on.
+	@/@.minigzip -f -9 libc
+	@/@.minigzip -d libc-gz
+	@/@.minigzip -f -1 libc
+	@/@.minigzip -d libc-gz
+	@/@.minigzip -h -9 libc
+	@/@.minigzip -d libc-gz
+	@/@.minigzip -h -1 libc
+	@/@.minigzip -d libc-gz
+	@/@.minigzip -9 libc
+	@/@.minigzip -d libc-gz
+	@/@.minigzip -1 libc
+	@/@.minigzip -d libc-gz
+	@diff @.lib @.libc
+	@echo that should have reported '@.lib and @.libc identical' if you have diff.
+	@/@.example @.fred @.fred
+	@echo that will have given lots of hello!'s.
+
+@.minigzip:   @.o.minigzip @.lib C:o.Stubs
+        Link $(Linkflags) @.o.minigzip @.lib C:o.Stubs
+@.example:   @.o.example @.lib C:o.Stubs
+        Link $(Linkflags) @.o.example @.lib C:o.Stubs
+
+install: @.lib
+	cdir $(libdest)
+	cdir $(libdest).h
+	@copy @.h.zlib $(libdest).h.zlib A~C~DF~L~N~P~Q~RS~TV
+	@copy @.h.zconf $(libdest).h.zconf A~C~DF~L~N~P~Q~RS~TV
+	@copy @.lib $(libdest).lib  A~C~DF~L~N~P~Q~RS~TV
+	@echo okay, installed zlib in $(libdest)
+
+clean:; remove @.minigzip
+	remove @.example
+	remove @.libc
+	-wipe @.o.* F~r~cV
+	remove @.fred
+
+# User-editable dependencies:
+.c.o:
+        cc $(ccflags) -o $@ $<
+
+# Static dependencies:
+
+# Dynamic dependencies:
+o.example:	c.example
+o.example:	h.zlib
+o.example:	h.zconf
+o.minigzip:	c.minigzip
+o.minigzip:	h.zlib
+o.minigzip:	h.zconf
+o.adler32:	c.adler32
+o.adler32:	h.zlib
+o.adler32:	h.zconf
+o.compress:	c.compress
+o.compress:	h.zlib
+o.compress:	h.zconf
+o.crc32:	c.crc32
+o.crc32:	h.zlib
+o.crc32:	h.zconf
+o.deflate:	c.deflate
+o.deflate:	h.deflate
+o.deflate:	h.zutil
+o.deflate:	h.zlib
+o.deflate:	h.zconf
+o.gzio:	c.gzio
+o.gzio:	h.zutil
+o.gzio:	h.zlib
+o.gzio:	h.zconf
+o.infblock:	c.infblock
+o.infblock:	h.zutil
+o.infblock:	h.zlib
+o.infblock:	h.zconf
+o.infblock:	h.infblock
+o.infblock:	h.inftrees
+o.infblock:	h.infcodes
+o.infblock:	h.infutil
+o.infcodes:	c.infcodes
+o.infcodes:	h.zutil
+o.infcodes:	h.zlib
+o.infcodes:	h.zconf
+o.infcodes:	h.inftrees
+o.infcodes:	h.infblock
+o.infcodes:	h.infcodes
+o.infcodes:	h.infutil
+o.infcodes:	h.inffast
+o.inffast:	c.inffast
+o.inffast:	h.zutil
+o.inffast:	h.zlib
+o.inffast:	h.zconf
+o.inffast:	h.inftrees
+o.inffast:	h.infblock
+o.inffast:	h.infcodes
+o.inffast:	h.infutil
+o.inffast:	h.inffast
+o.inflate:	c.inflate
+o.inflate:	h.zutil
+o.inflate:	h.zlib
+o.inflate:	h.zconf
+o.inflate:	h.infblock
+o.inftrees:	c.inftrees
+o.inftrees:	h.zutil
+o.inftrees:	h.zlib
+o.inftrees:	h.zconf
+o.inftrees:	h.inftrees
+o.inftrees:	h.inffixed
+o.infutil:	c.infutil
+o.infutil:	h.zutil
+o.infutil:	h.zlib
+o.infutil:	h.zconf
+o.infutil:	h.infblock
+o.infutil:	h.inftrees
+o.infutil:	h.infcodes
+o.infutil:	h.infutil
+o.trees:	c.trees
+o.trees:	h.deflate
+o.trees:	h.zutil
+o.trees:	h.zlib
+o.trees:	h.zconf
+o.trees:	h.trees
+o.uncompr:	c.uncompr
+o.uncompr:	h.zlib
+o.uncompr:	h.zconf
+o.zutil:	c.zutil
+o.zutil:	h.zutil
+o.zutil:	h.zlib
+o.zutil:	h.zconf
diff --git a/compat/zlib/old/README b/compat/zlib/old/README
new file mode 100644
index 0000000..800bf07
--- /dev/null
+++ b/compat/zlib/old/README
@@ -0,0 +1,3 @@
+This directory contains files that have not been updated for zlib 1.2.x
+
+(Volunteers are encouraged to help clean this up.  Thanks.)
diff --git a/compat/zlib/old/descrip.mms b/compat/zlib/old/descrip.mms
new file mode 100644
index 0000000..7066da5
--- /dev/null
+++ b/compat/zlib/old/descrip.mms
@@ -0,0 +1,48 @@
+# descrip.mms: MMS description file for building zlib on VMS
+# written by Martin P.J. Zinser <m.zinser@gsi.de>
+
+cc_defs =
+c_deb =
+
+.ifdef __DECC__
+pref = /prefix=all
+.endif
+
+OBJS = adler32.obj, compress.obj, crc32.obj, gzio.obj, uncompr.obj,\
+       deflate.obj, trees.obj, zutil.obj, inflate.obj, infblock.obj,\
+       inftrees.obj, infcodes.obj, infutil.obj, inffast.obj
+
+CFLAGS= $(C_DEB) $(CC_DEFS) $(PREF)
+
+all : example.exe minigzip.exe
+        @ write sys$output " Example applications available"
+libz.olb : libz.olb($(OBJS))
+	@ write sys$output " libz available"
+
+example.exe : example.obj libz.olb
+              link example,libz.olb/lib
+
+minigzip.exe : minigzip.obj libz.olb
+              link minigzip,libz.olb/lib,x11vms:xvmsutils.olb/lib
+
+clean :
+	delete *.obj;*,libz.olb;*
+
+
+# Other dependencies.
+adler32.obj : zutil.h zlib.h zconf.h
+compress.obj : zlib.h zconf.h
+crc32.obj : zutil.h zlib.h zconf.h
+deflate.obj : deflate.h zutil.h zlib.h zconf.h
+example.obj : zlib.h zconf.h
+gzio.obj : zutil.h zlib.h zconf.h
+infblock.obj : zutil.h zlib.h zconf.h infblock.h inftrees.h infcodes.h infutil.h
+infcodes.obj : zutil.h zlib.h zconf.h inftrees.h infutil.h infcodes.h inffast.h
+inffast.obj : zutil.h zlib.h zconf.h inftrees.h infutil.h inffast.h
+inflate.obj : zutil.h zlib.h zconf.h infblock.h
+inftrees.obj : zutil.h zlib.h zconf.h inftrees.h
+infutil.obj : zutil.h zlib.h zconf.h inftrees.h infutil.h
+minigzip.obj : zlib.h zconf.h
+trees.obj : deflate.h zutil.h zlib.h zconf.h
+uncompr.obj : zlib.h zconf.h
+zutil.obj : zutil.h zlib.h zconf.h
diff --git a/compat/zlib/old/os2/Makefile.os2 b/compat/zlib/old/os2/Makefile.os2
new file mode 100644
index 0000000..a105aaa
--- /dev/null
+++ b/compat/zlib/old/os2/Makefile.os2
@@ -0,0 +1,136 @@
+# Makefile for zlib under OS/2 using GCC (PGCC)
+# For conditions of distribution and use, see copyright notice in zlib.h
+
+# To compile and test, type:
+#   cp Makefile.os2 ..
+#   cd ..
+#   make -f Makefile.os2 test
+
+# This makefile will build a static library z.lib, a shared library
+# z.dll and a import library zdll.lib. You can use either z.lib or
+# zdll.lib by specifying either -lz or -lzdll on gcc's command line
+
+CC=gcc -Zomf -s
+
+CFLAGS=-O6 -Wall
+#CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7
+#CFLAGS=-g -DDEBUG
+#CFLAGS=-O3 -Wall -Wwrite-strings -Wpointer-arith -Wconversion \
+#           -Wstrict-prototypes -Wmissing-prototypes
+
+#################### BUG WARNING: #####################
+## infcodes.c hits a bug in pgcc-1.0, so you have to use either
+## -O# where # <= 4 or one of (-fno-ommit-frame-pointer or -fno-force-mem)
+## This bug is reportedly fixed in pgcc >1.0, but this was not tested
+CFLAGS+=-fno-force-mem
+
+LDFLAGS=-s -L. -lzdll -Zcrtdll
+LDSHARED=$(CC) -s -Zomf -Zdll -Zcrtdll
+
+VER=1.1.0
+ZLIB=z.lib
+SHAREDLIB=z.dll
+SHAREDLIBIMP=zdll.lib
+LIBS=$(ZLIB) $(SHAREDLIB) $(SHAREDLIBIMP)
+
+AR=emxomfar cr
+IMPLIB=emximp
+RANLIB=echo
+TAR=tar
+SHELL=bash
+
+prefix=/usr/local
+exec_prefix = $(prefix)
+
+OBJS = adler32.o compress.o crc32.o gzio.o uncompr.o deflate.o trees.o \
+       zutil.o inflate.o infblock.o inftrees.o infcodes.o infutil.o inffast.o
+
+TEST_OBJS = example.o minigzip.o
+
+DISTFILES = README INDEX ChangeLog configure Make*[a-z0-9] *.[ch] descrip.mms \
+  algorithm.txt zlib.3 msdos/Make*[a-z0-9] msdos/zlib.def msdos/zlib.rc \
+  nt/Makefile.nt nt/zlib.dnt  contrib/README.contrib contrib/*.txt \
+  contrib/asm386/*.asm contrib/asm386/*.c \
+  contrib/asm386/*.bat contrib/asm386/zlibvc.d?? contrib/iostream/*.cpp \
+  contrib/iostream/*.h  contrib/iostream2/*.h contrib/iostream2/*.cpp \
+  contrib/untgz/Makefile contrib/untgz/*.c contrib/untgz/*.w32
+
+all: example.exe minigzip.exe
+
+test: all
+	@LD_LIBRARY_PATH=.:$(LD_LIBRARY_PATH) ; export LD_LIBRARY_PATH; \
+	echo hello world | ./minigzip | ./minigzip -d || \
+	  echo '		*** minigzip test FAILED ***' ; \
+	if ./example; then \
+	  echo '		*** zlib test OK ***'; \
+	else \
+	  echo '		*** zlib test FAILED ***'; \
+	fi
+
+$(ZLIB): $(OBJS)
+	$(AR) $@ $(OBJS)
+	-@ ($(RANLIB) $@ || true) >/dev/null 2>&1
+
+$(SHAREDLIB): $(OBJS) os2/z.def
+	$(LDSHARED) -o $@ $^
+
+$(SHAREDLIBIMP): os2/z.def
+	$(IMPLIB) -o $@ $^
+
+example.exe: example.o $(LIBS)
+	$(CC) $(CFLAGS) -o $@ example.o $(LDFLAGS)
+
+minigzip.exe: minigzip.o $(LIBS)
+	$(CC) $(CFLAGS) -o $@ minigzip.o $(LDFLAGS)
+
+clean:
+	rm -f *.o *~ example minigzip libz.a libz.so* foo.gz
+
+distclean:	clean
+
+zip:
+	mv Makefile Makefile~; cp -p Makefile.in Makefile
+	rm -f test.c ztest*.c
+	v=`sed -n -e 's/\.//g' -e '/VERSION "/s/.*"\(.*\)".*/\1/p' < zlib.h`;\
+	zip -ul9 zlib$$v $(DISTFILES)
+	mv Makefile~ Makefile
+
+dist:
+	mv Makefile Makefile~; cp -p Makefile.in Makefile
+	rm -f test.c ztest*.c
+	d=zlib-`sed -n '/VERSION "/s/.*"\(.*\)".*/\1/p' < zlib.h`;\
+	rm -f $$d.tar.gz; \
+	if test ! -d ../$$d; then rm -f ../$$d; ln -s `pwd` ../$$d; fi; \
+	files=""; \
+	for f in $(DISTFILES); do files="$$files $$d/$$f"; done; \
+	cd ..; \
+	GZIP=-9 $(TAR) chofz $$d/$$d.tar.gz $$files; \
+	if test ! -d $$d; then rm -f $$d; fi
+	mv Makefile~ Makefile
+
+tags:
+	etags *.[ch]
+
+depend:
+	makedepend -- $(CFLAGS) -- *.[ch]
+
+# DO NOT DELETE THIS LINE -- make depend depends on it.
+
+adler32.o: zlib.h zconf.h
+compress.o: zlib.h zconf.h
+crc32.o: zlib.h zconf.h
+deflate.o: deflate.h zutil.h zlib.h zconf.h
+example.o: zlib.h zconf.h
+gzio.o: zutil.h zlib.h zconf.h
+infblock.o: infblock.h inftrees.h infcodes.h infutil.h zutil.h zlib.h zconf.h
+infcodes.o: zutil.h zlib.h zconf.h
+infcodes.o: inftrees.h infblock.h infcodes.h infutil.h inffast.h
+inffast.o: zutil.h zlib.h zconf.h inftrees.h
+inffast.o: infblock.h infcodes.h infutil.h inffast.h
+inflate.o: zutil.h zlib.h zconf.h infblock.h
+inftrees.o: zutil.h zlib.h zconf.h inftrees.h
+infutil.o: zutil.h zlib.h zconf.h infblock.h inftrees.h infcodes.h infutil.h
+minigzip.o: zlib.h zconf.h
+trees.o: deflate.h zutil.h zlib.h zconf.h trees.h
+uncompr.o: zlib.h zconf.h
+zutil.o: zutil.h zlib.h zconf.h
diff --git a/compat/zlib/old/os2/zlib.def b/compat/zlib/old/os2/zlib.def
new file mode 100644
index 0000000..4c753f1
--- /dev/null
+++ b/compat/zlib/old/os2/zlib.def
@@ -0,0 +1,51 @@
+;
+; Slightly modified version of ../nt/zlib.dnt :-)
+;
+
+LIBRARY		Z
+DESCRIPTION	"Zlib compression library for OS/2"
+CODE		PRELOAD MOVEABLE DISCARDABLE
+DATA		PRELOAD MOVEABLE MULTIPLE
+
+EXPORTS
+    adler32
+    compress
+    crc32
+    deflate
+    deflateCopy
+    deflateEnd
+    deflateInit2_
+    deflateInit_
+    deflateParams
+    deflateReset
+    deflateSetDictionary
+    gzclose
+    gzdopen
+    gzerror
+    gzflush
+    gzopen
+    gzread
+    gzwrite
+    inflate
+    inflateEnd
+    inflateInit2_
+    inflateInit_
+    inflateReset
+    inflateSetDictionary
+    inflateSync
+    uncompress
+    zlibVersion
+    gzprintf
+    gzputc
+    gzgetc
+    gzseek
+    gzrewind
+    gztell
+    gzeof
+    gzsetparams
+    zError
+    inflateSyncPoint
+    get_crc_table
+    compress2
+    gzputs
+    gzgets
diff --git a/compat/zlib/old/visual-basic.txt b/compat/zlib/old/visual-basic.txt
new file mode 100644
index 0000000..57efe58
--- /dev/null
+++ b/compat/zlib/old/visual-basic.txt
@@ -0,0 +1,160 @@
+See below some functions declarations for Visual Basic.
+
+Frequently Asked Question:
+
+Q: Each time I use the compress function I get the -5 error (not enough
+   room in the output buffer).
+
+A: Make sure that the length of the compressed buffer is passed by
+   reference ("as any"), not by value ("as long"). Also check that
+   before the call of compress this length is equal to the total size of
+   the compressed buffer and not zero.
+
+
+From: "Jon Caruana" <jon-net@usa.net>
+Subject: Re: How to port zlib declares to vb?
+Date: Mon, 28 Oct 1996 18:33:03 -0600
+
+Got the answer! (I haven't had time to check this but it's what I got, and
+looks correct):
+
+He has the following routines working:
+        compress
+        uncompress
+        gzopen
+        gzwrite
+        gzread
+        gzclose
+
+Declares follow: (Quoted from Carlos Rios <c_rios@sonda.cl>, in Vb4 form)
+
+#If Win16 Then   'Use Win16 calls.
+Declare Function compress Lib "ZLIB.DLL" (ByVal compr As
+        String, comprLen As Any, ByVal buf As String, ByVal buflen
+        As Long) As Integer
+Declare Function uncompress Lib "ZLIB.DLL" (ByVal uncompr
+        As String, uncomprLen As Any, ByVal compr As String, ByVal
+        lcompr As Long) As Integer
+Declare Function gzopen Lib "ZLIB.DLL" (ByVal filePath As
+        String, ByVal mode As String) As Long
+Declare Function gzread Lib "ZLIB.DLL" (ByVal file As
+        Long, ByVal uncompr As String, ByVal uncomprLen As Integer)
+        As Integer
+Declare Function gzwrite Lib "ZLIB.DLL" (ByVal file As
+        Long, ByVal uncompr As String, ByVal uncomprLen As Integer)
+        As Integer
+Declare Function gzclose Lib "ZLIB.DLL" (ByVal file As
+        Long) As Integer
+#Else
+Declare Function compress Lib "ZLIB32.DLL"
+        (ByVal compr As String, comprLen As Any, ByVal buf As
+        String, ByVal buflen As Long) As Integer
+Declare Function uncompress Lib "ZLIB32.DLL"
+        (ByVal uncompr As String, uncomprLen As Any, ByVal compr As
+        String, ByVal lcompr As Long) As Long
+Declare Function gzopen Lib "ZLIB32.DLL"
+        (ByVal file As String, ByVal mode As String) As Long
+Declare Function gzread Lib "ZLIB32.DLL"
+        (ByVal file As Long, ByVal uncompr As String, ByVal
+        uncomprLen As Long) As Long
+Declare Function gzwrite Lib "ZLIB32.DLL"
+        (ByVal file As Long, ByVal uncompr As String, ByVal
+        uncomprLen As Long) As Long
+Declare Function gzclose Lib "ZLIB32.DLL"
+        (ByVal file As Long) As Long
+#End If
+
+-Jon Caruana
+jon-net@usa.net
+Microsoft Sitebuilder Network Level 1 Member - HTML Writer's Guild Member
+
+
+Here is another example from Michael <michael_borgsys@hotmail.com> that he
+says conforms to the VB guidelines, and that solves the problem of not
+knowing the uncompressed size by storing it at the end of the file:
+
+'Calling the functions:
+'bracket meaning: <parameter> [optional] {Range of possible values}
+'Call subCompressFile(<path with filename to compress> [, <path with
+filename to write to>, [level of compression {1..9}]])
+'Call subUncompressFile(<path with filename to compress>)
+
+Option Explicit
+Private lngpvtPcnSml As Long 'Stores value for 'lngPercentSmaller'
+Private Const SUCCESS As Long = 0
+Private Const strFilExt As String = ".cpr"
+Private Declare Function lngfncCpr Lib "zlib.dll" Alias "compress2" (ByRef
+dest As Any, ByRef destLen As Any, ByRef src As Any, ByVal srcLen As Long,
+ByVal level As Integer) As Long
+Private Declare Function lngfncUcp Lib "zlib.dll" Alias "uncompress" (ByRef
+dest As Any, ByRef destLen As Any, ByRef src As Any, ByVal srcLen As Long)
+As Long
+
+Public Sub subCompressFile(ByVal strargOriFilPth As String, Optional ByVal
+strargCprFilPth As String, Optional ByVal intLvl As Integer = 9)
+    Dim strCprPth As String
+    Dim lngOriSiz As Long
+    Dim lngCprSiz As Long
+    Dim bytaryOri() As Byte
+    Dim bytaryCpr() As Byte
+    lngOriSiz = FileLen(strargOriFilPth)
+    ReDim bytaryOri(lngOriSiz - 1)
+    Open strargOriFilPth For Binary Access Read As #1
+        Get #1, , bytaryOri()
+    Close #1
+    strCprPth = IIf(strargCprFilPth = "", strargOriFilPth, strargCprFilPth)
+'Select file path and name
+    strCprPth = strCprPth & IIf(Right(strCprPth, Len(strFilExt)) =
+strFilExt, "", strFilExt) 'Add file extension if not exists
+    lngCprSiz = (lngOriSiz * 1.01) + 12 'Compression needs temporary a bit
+more space then original file size
+    ReDim bytaryCpr(lngCprSiz - 1)
+    If lngfncCpr(bytaryCpr(0), lngCprSiz, bytaryOri(0), lngOriSiz, intLvl) =
+SUCCESS Then
+        lngpvtPcnSml = (1# - (lngCprSiz / lngOriSiz)) * 100
+        ReDim Preserve bytaryCpr(lngCprSiz - 1)
+        Open strCprPth For Binary Access Write As #1
+            Put #1, , bytaryCpr()
+            Put #1, , lngOriSiz 'Add the the original size value to the end
+(last 4 bytes)
+        Close #1
+    Else
+        MsgBox "Compression error"
+    End If
+    Erase bytaryCpr
+    Erase bytaryOri
+End Sub
+
+Public Sub subUncompressFile(ByVal strargFilPth As String)
+    Dim bytaryCpr() As Byte
+    Dim bytaryOri() As Byte
+    Dim lngOriSiz As Long
+    Dim lngCprSiz As Long
+    Dim strOriPth As String
+    lngCprSiz = FileLen(strargFilPth)
+    ReDim bytaryCpr(lngCprSiz - 1)
+    Open strargFilPth For Binary Access Read As #1
+        Get #1, , bytaryCpr()
+    Close #1
+    'Read the original file size value:
+    lngOriSiz = bytaryCpr(lngCprSiz - 1) * (2 ^ 24) _
+              + bytaryCpr(lngCprSiz - 2) * (2 ^ 16) _
+              + bytaryCpr(lngCprSiz - 3) * (2 ^ 8) _
+              + bytaryCpr(lngCprSiz - 4)
+    ReDim Preserve bytaryCpr(lngCprSiz - 5) 'Cut of the original size value
+    ReDim bytaryOri(lngOriSiz - 1)
+    If lngfncUcp(bytaryOri(0), lngOriSiz, bytaryCpr(0), lngCprSiz) = SUCCESS
+Then
+        strOriPth = Left(strargFilPth, Len(strargFilPth) - Len(strFilExt))
+        Open strOriPth For Binary Access Write As #1
+            Put #1, , bytaryOri()
+        Close #1
+    Else
+        MsgBox "Uncompression error"
+    End If
+    Erase bytaryCpr
+    Erase bytaryOri
+End Sub
+Public Property Get lngPercentSmaller() As Long
+    lngPercentSmaller = lngpvtPcnSml
+End Property
diff --git a/compat/zlib/qnx/package.qpg b/compat/zlib/qnx/package.qpg
new file mode 100644
index 0000000..aebf6e3
--- /dev/null
+++ b/compat/zlib/qnx/package.qpg
@@ -0,0 +1,141 @@
+<QPG:Generation>
+   <QPG:Options>
+      <QPG:User unattended="no" verbosity="2" listfiles="yes"/>
+      <QPG:Defaults type="qnx_package"/>
+      <QPG:Source></QPG:Source>
+      <QPG:Release number="+"/>
+      <QPG:Build></QPG:Build>
+      <QPG:FileSorting strip="yes"/>
+      <QPG:Package targets="combine"/>
+      <QPG:Repository generate="yes"/>
+      <QPG:FinalDir></QPG:FinalDir>
+      <QPG:Cleanup></QPG:Cleanup>
+   </QPG:Options>
+
+   <QPG:Responsible>
+      <QPG:Company></QPG:Company>
+      <QPG:Department></QPG:Department>
+      <QPG:Group></QPG:Group>
+      <QPG:Team></QPG:Team>
+      <QPG:Employee></QPG:Employee>
+      <QPG:EmailAddress></QPG:EmailAddress>
+   </QPG:Responsible>
+
+   <QPG:Values>
+      <QPG:Files>
+         <QPG:Add file="../zconf.h" install="/opt/include/" user="root:sys" permission="644"/>
+         <QPG:Add file="../zlib.h" install="/opt/include/" user="root:sys" permission="644"/>
+         <QPG:Add file="../libz.so.1.2.8" install="/opt/lib/" user="root:bin" permission="644"/>
+         <QPG:Add file="libz.so" install="/opt/lib/" component="dev" filetype="symlink" linkto="libz.so.1.2.8"/>
+         <QPG:Add file="libz.so.1" install="/opt/lib/" filetype="symlink" linkto="libz.so.1.2.8"/>
+         <QPG:Add file="../libz.so.1.2.8" install="/opt/lib/" component="slib"/>
+      </QPG:Files>
+
+      <QPG:PackageFilter>
+         <QPM:PackageManifest>
+            <QPM:PackageDescription>
+               <QPM:PackageType>Library</QPM:PackageType>
+               <QPM:PackageReleaseNotes></QPM:PackageReleaseNotes>
+               <QPM:PackageReleaseUrgency>Medium</QPM:PackageReleaseUrgency>
+               <QPM:PackageRepository></QPM:PackageRepository>
+               <QPM:FileVersion>2.0</QPM:FileVersion>
+            </QPM:PackageDescription>
+
+            <QPM:ProductDescription>
+               <QPM:ProductName>zlib</QPM:ProductName>
+               <QPM:ProductIdentifier>zlib</QPM:ProductIdentifier>
+               <QPM:ProductEmail>alain.bonnefoy@icbt.com</QPM:ProductEmail>
+               <QPM:VendorName>Public</QPM:VendorName>
+               <QPM:VendorInstallName>public</QPM:VendorInstallName>
+               <QPM:VendorURL>www.gzip.org/zlib</QPM:VendorURL>
+               <QPM:VendorEmbedURL></QPM:VendorEmbedURL>
+               <QPM:VendorEmail></QPM:VendorEmail>
+               <QPM:AuthorName>Jean-Loup Gailly,Mark Adler</QPM:AuthorName>
+               <QPM:AuthorURL>www.gzip.org/zlib</QPM:AuthorURL>
+               <QPM:AuthorEmbedURL></QPM:AuthorEmbedURL>
+               <QPM:AuthorEmail>zlib@gzip.org</QPM:AuthorEmail>
+               <QPM:ProductIconSmall></QPM:ProductIconSmall>
+               <QPM:ProductIconLarge></QPM:ProductIconLarge>
+               <QPM:ProductDescriptionShort>A massively spiffy yet delicately unobtrusive compression library.</QPM:ProductDescriptionShort>
+               <QPM:ProductDescriptionLong>zlib is designed to be a free, general-purpose, legally unencumbered, lossless data compression library for use on virtually any computer hardware and operating system.</QPM:ProductDescriptionLong>
+               <QPM:ProductDescriptionURL>http://www.gzip.org/zlib</QPM:ProductDescriptionURL>
+               <QPM:ProductDescriptionEmbedURL></QPM:ProductDescriptionEmbedURL>
+            </QPM:ProductDescription>
+
+            <QPM:ReleaseDescription>
+               <QPM:ReleaseVersion>1.2.8</QPM:ReleaseVersion>
+               <QPM:ReleaseUrgency>Medium</QPM:ReleaseUrgency>
+               <QPM:ReleaseStability>Stable</QPM:ReleaseStability>
+               <QPM:ReleaseNoteMinor></QPM:ReleaseNoteMinor>
+               <QPM:ReleaseNoteMajor></QPM:ReleaseNoteMajor>
+               <QPM:ExcludeCountries>
+                  <QPM:Country></QPM:Country>
+               </QPM:ExcludeCountries>
+
+               <QPM:ReleaseCopyright>No License</QPM:ReleaseCopyright>
+            </QPM:ReleaseDescription>
+
+            <QPM:ContentDescription>
+               <QPM:ContentTopic xmlmultiple="true">Software Development/Libraries and Extensions/C Libraries</QPM:ContentTopic>
+               <QPM:ContentKeyword>zlib,compression</QPM:ContentKeyword>
+               <QPM:TargetOS>qnx6</QPM:TargetOS>
+               <QPM:HostOS>qnx6</QPM:HostOS>
+               <QPM:DisplayEnvironment xmlmultiple="true">None</QPM:DisplayEnvironment>
+               <QPM:TargetAudience xmlmultiple="true">Developer</QPM:TargetAudience>
+            </QPM:ContentDescription>
+         </QPM:PackageManifest>
+      </QPG:PackageFilter>
+
+      <QPG:PackageFilter proc="none" target="none">
+         <QPM:PackageManifest>
+            <QPM:ProductInstallationDependencies>
+               <QPM:ProductRequirements></QPM:ProductRequirements>
+            </QPM:ProductInstallationDependencies>
+
+            <QPM:ProductInstallationProcedure>
+               <QPM:Script xmlmultiple="true">
+                  <QPM:ScriptName></QPM:ScriptName>
+                  <QPM:ScriptType>Install</QPM:ScriptType>
+                  <QPM:ScriptTiming>Post</QPM:ScriptTiming>
+                  <QPM:ScriptBlocking>No</QPM:ScriptBlocking>
+                  <QPM:ScriptResult>Ignore</QPM:ScriptResult>
+                  <QPM:ShortDescription></QPM:ShortDescription>
+                  <QPM:UseBinaries>No</QPM:UseBinaries>
+                  <QPM:Priority>Optional</QPM:Priority>
+               </QPM:Script>
+            </QPM:ProductInstallationProcedure>
+         </QPM:PackageManifest>
+
+         <QPM:Launch>
+         </QPM:Launch>
+      </QPG:PackageFilter>
+
+      <QPG:PackageFilter type="core" component="none">
+         <QPM:PackageManifest>
+            <QPM:ProductInstallationProcedure>
+	       <QPM:OrderDependency xmlmultiple="true">
+	          <QPM:Order>InstallOver</QPM:Order>
+	          <QPM:Product>zlib</QPM:Product>
+	       </QPM:OrderDependency>
+            </QPM:ProductInstallationProcedure>
+         </QPM:PackageManifest>
+
+         <QPM:Launch>
+         </QPM:Launch>
+      </QPG:PackageFilter>
+
+      <QPG:PackageFilter type="core" component="dev">
+         <QPM:PackageManifest>
+            <QPM:ProductInstallationProcedure>
+	       <QPM:OrderDependency xmlmultiple="true">
+	          <QPM:Order>InstallOver</QPM:Order>
+	          <QPM:Product>zlib-dev</QPM:Product>
+	       </QPM:OrderDependency>
+            </QPM:ProductInstallationProcedure>
+         </QPM:PackageManifest>
+
+         <QPM:Launch>
+         </QPM:Launch>
+      </QPG:PackageFilter>
+   </QPG:Values>
+</QPG:Generation>
diff --git a/compat/zlib/test/example.c b/compat/zlib/test/example.c
new file mode 100644
index 0000000..138a699
--- /dev/null
+++ b/compat/zlib/test/example.c
@@ -0,0 +1,601 @@
+/* example.c -- usage example of the zlib compression library
+ * Copyright (C) 1995-2006, 2011 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id$ */
+
+#include "zlib.h"
+#include <stdio.h>
+
+#ifdef STDC
+#  include <string.h>
+#  include <stdlib.h>
+#endif
+
+#if defined(VMS) || defined(RISCOS)
+#  define TESTFILE "foo-gz"
+#else
+#  define TESTFILE "foo.gz"
+#endif
+
+#define CHECK_ERR(err, msg) { \
+    if (err != Z_OK) { \
+        fprintf(stderr, "%s error: %d\n", msg, err); \
+        exit(1); \
+    } \
+}
+
+z_const char hello[] = "hello, hello!";
+/* "hello world" would be more standard, but the repeated "hello"
+ * stresses the compression code better, sorry...
+ */
+
+const char dictionary[] = "hello";
+uLong dictId; /* Adler32 value of the dictionary */
+
+void test_deflate       OF((Byte *compr, uLong comprLen));
+void test_inflate       OF((Byte *compr, uLong comprLen,
+                            Byte *uncompr, uLong uncomprLen));
+void test_large_deflate OF((Byte *compr, uLong comprLen,
+                            Byte *uncompr, uLong uncomprLen));
+void test_large_inflate OF((Byte *compr, uLong comprLen,
+                            Byte *uncompr, uLong uncomprLen));
+void test_flush         OF((Byte *compr, uLong *comprLen));
+void test_sync          OF((Byte *compr, uLong comprLen,
+                            Byte *uncompr, uLong uncomprLen));
+void test_dict_deflate  OF((Byte *compr, uLong comprLen));
+void test_dict_inflate  OF((Byte *compr, uLong comprLen,
+                            Byte *uncompr, uLong uncomprLen));
+int  main               OF((int argc, char *argv[]));
+
+
+#ifdef Z_SOLO
+
+void *myalloc OF((void *, unsigned, unsigned));
+void myfree OF((void *, void *));
+
+void *myalloc(q, n, m)
+    void *q;
+    unsigned n, m;
+{
+    q = Z_NULL;
+    return calloc(n, m);
+}
+
+void myfree(void *q, void *p)
+{
+    q = Z_NULL;
+    free(p);
+}
+
+static alloc_func zalloc = myalloc;
+static free_func zfree = myfree;
+
+#else /* !Z_SOLO */
+
+static alloc_func zalloc = (alloc_func)0;
+static free_func zfree = (free_func)0;
+
+void test_compress      OF((Byte *compr, uLong comprLen,
+                            Byte *uncompr, uLong uncomprLen));
+void test_gzio          OF((const char *fname,
+                            Byte *uncompr, uLong uncomprLen));
+
+/* ===========================================================================
+ * Test compress() and uncompress()
+ */
+void test_compress(compr, comprLen, uncompr, uncomprLen)
+    Byte *compr, *uncompr;
+    uLong comprLen, uncomprLen;
+{
+    int err;
+    uLong len = (uLong)strlen(hello)+1;
+
+    err = compress(compr, &comprLen, (const Bytef*)hello, len);
+    CHECK_ERR(err, "compress");
+
+    strcpy((char*)uncompr, "garbage");
+
+    err = uncompress(uncompr, &uncomprLen, compr, comprLen);
+    CHECK_ERR(err, "uncompress");
+
+    if (strcmp((char*)uncompr, hello)) {
+        fprintf(stderr, "bad uncompress\n");
+        exit(1);
+    } else {
+        printf("uncompress(): %s\n", (char *)uncompr);
+    }
+}
+
+/* ===========================================================================
+ * Test read/write of .gz files
+ */
+void test_gzio(fname, uncompr, uncomprLen)
+    const char *fname; /* compressed file name */
+    Byte *uncompr;
+    uLong uncomprLen;
+{
+#ifdef NO_GZCOMPRESS
+    fprintf(stderr, "NO_GZCOMPRESS -- gz* functions cannot compress\n");
+#else
+    int err;
+    int len = (int)strlen(hello)+1;
+    gzFile file;
+    z_off_t pos;
+
+    file = gzopen(fname, "wb");
+    if (file == NULL) {
+        fprintf(stderr, "gzopen error\n");
+        exit(1);
+    }
+    gzputc(file, 'h');
+    if (gzputs(file, "ello") != 4) {
+        fprintf(stderr, "gzputs err: %s\n", gzerror(file, &err));
+        exit(1);
+    }
+    if (gzprintf(file, ", %s!", "hello") != 8) {
+        fprintf(stderr, "gzprintf err: %s\n", gzerror(file, &err));
+        exit(1);
+    }
+    gzseek(file, 1L, SEEK_CUR); /* add one zero byte */
+    gzclose(file);
+
+    file = gzopen(fname, "rb");
+    if (file == NULL) {
+        fprintf(stderr, "gzopen error\n");
+        exit(1);
+    }
+    strcpy((char*)uncompr, "garbage");
+
+    if (gzread(file, uncompr, (unsigned)uncomprLen) != len) {
+        fprintf(stderr, "gzread err: %s\n", gzerror(file, &err));
+        exit(1);
+    }
+    if (strcmp((char*)uncompr, hello)) {
+        fprintf(stderr, "bad gzread: %s\n", (char*)uncompr);
+        exit(1);
+    } else {
+        printf("gzread(): %s\n", (char*)uncompr);
+    }
+
+    pos = gzseek(file, -8L, SEEK_CUR);
+    if (pos != 6 || gztell(file) != pos) {
+        fprintf(stderr, "gzseek error, pos=%ld, gztell=%ld\n",
+                (long)pos, (long)gztell(file));
+        exit(1);
+    }
+
+    if (gzgetc(file) != ' ') {
+        fprintf(stderr, "gzgetc error\n");
+        exit(1);
+    }
+
+    if (gzungetc(' ', file) != ' ') {
+        fprintf(stderr, "gzungetc error\n");
+        exit(1);
+    }
+
+    gzgets(file, (char*)uncompr, (int)uncomprLen);
+    if (strlen((char*)uncompr) != 7) { /* " hello!" */
+        fprintf(stderr, "gzgets err after gzseek: %s\n", gzerror(file, &err));
+        exit(1);
+    }
+    if (strcmp((char*)uncompr, hello + 6)) {
+        fprintf(stderr, "bad gzgets after gzseek\n");
+        exit(1);
+    } else {
+        printf("gzgets() after gzseek: %s\n", (char*)uncompr);
+    }
+
+    gzclose(file);
+#endif
+}
+
+#endif /* Z_SOLO */
+
+/* ===========================================================================
+ * Test deflate() with small buffers
+ */
+void test_deflate(compr, comprLen)
+    Byte *compr;
+    uLong comprLen;
+{
+    z_stream c_stream; /* compression stream */
+    int err;
+    uLong len = (uLong)strlen(hello)+1;
+
+    c_stream.zalloc = zalloc;
+    c_stream.zfree = zfree;
+    c_stream.opaque = (voidpf)0;
+
+    err = deflateInit(&c_stream, Z_DEFAULT_COMPRESSION);
+    CHECK_ERR(err, "deflateInit");
+
+    c_stream.next_in  = (z_const unsigned char *)hello;
+    c_stream.next_out = compr;
+
+    while (c_stream.total_in != len && c_stream.total_out < comprLen) {
+        c_stream.avail_in = c_stream.avail_out = 1; /* force small buffers */
+        err = deflate(&c_stream, Z_NO_FLUSH);
+        CHECK_ERR(err, "deflate");
+    }
+    /* Finish the stream, still forcing small buffers: */
+    for (;;) {
+        c_stream.avail_out = 1;
+        err = deflate(&c_stream, Z_FINISH);
+        if (err == Z_STREAM_END) break;
+        CHECK_ERR(err, "deflate");
+    }
+
+    err = deflateEnd(&c_stream);
+    CHECK_ERR(err, "deflateEnd");
+}
+
+/* ===========================================================================
+ * Test inflate() with small buffers
+ */
+void test_inflate(compr, comprLen, uncompr, uncomprLen)
+    Byte *compr, *uncompr;
+    uLong comprLen, uncomprLen;
+{
+    int err;
+    z_stream d_stream; /* decompression stream */
+
+    strcpy((char*)uncompr, "garbage");
+
+    d_stream.zalloc = zalloc;
+    d_stream.zfree = zfree;
+    d_stream.opaque = (voidpf)0;
+
+    d_stream.next_in  = compr;
+    d_stream.avail_in = 0;
+    d_stream.next_out = uncompr;
+
+    err = inflateInit(&d_stream);
+    CHECK_ERR(err, "inflateInit");
+
+    while (d_stream.total_out < uncomprLen && d_stream.total_in < comprLen) {
+        d_stream.avail_in = d_stream.avail_out = 1; /* force small buffers */
+        err = inflate(&d_stream, Z_NO_FLUSH);
+        if (err == Z_STREAM_END) break;
+        CHECK_ERR(err, "inflate");
+    }
+
+    err = inflateEnd(&d_stream);
+    CHECK_ERR(err, "inflateEnd");
+
+    if (strcmp((char*)uncompr, hello)) {
+        fprintf(stderr, "bad inflate\n");
+        exit(1);
+    } else {
+        printf("inflate(): %s\n", (char *)uncompr);
+    }
+}
+
+/* ===========================================================================
+ * Test deflate() with large buffers and dynamic change of compression level
+ */
+void test_large_deflate(compr, comprLen, uncompr, uncomprLen)
+    Byte *compr, *uncompr;
+    uLong comprLen, uncomprLen;
+{
+    z_stream c_stream; /* compression stream */
+    int err;
+
+    c_stream.zalloc = zalloc;
+    c_stream.zfree = zfree;
+    c_stream.opaque = (voidpf)0;
+
+    err = deflateInit(&c_stream, Z_BEST_SPEED);
+    CHECK_ERR(err, "deflateInit");
+
+    c_stream.next_out = compr;
+    c_stream.avail_out = (uInt)comprLen;
+
+    /* At this point, uncompr is still mostly zeroes, so it should compress
+     * very well:
+     */
+    c_stream.next_in = uncompr;
+    c_stream.avail_in = (uInt)uncomprLen;
+    err = deflate(&c_stream, Z_NO_FLUSH);
+    CHECK_ERR(err, "deflate");
+    if (c_stream.avail_in != 0) {
+        fprintf(stderr, "deflate not greedy\n");
+        exit(1);
+    }
+
+    /* Feed in already compressed data and switch to no compression: */
+    deflateParams(&c_stream, Z_NO_COMPRESSION, Z_DEFAULT_STRATEGY);
+    c_stream.next_in = compr;
+    c_stream.avail_in = (uInt)comprLen/2;
+    err = deflate(&c_stream, Z_NO_FLUSH);
+    CHECK_ERR(err, "deflate");
+
+    /* Switch back to compressing mode: */
+    deflateParams(&c_stream, Z_BEST_COMPRESSION, Z_FILTERED);
+    c_stream.next_in = uncompr;
+    c_stream.avail_in = (uInt)uncomprLen;
+    err = deflate(&c_stream, Z_NO_FLUSH);
+    CHECK_ERR(err, "deflate");
+
+    err = deflate(&c_stream, Z_FINISH);
+    if (err != Z_STREAM_END) {
+        fprintf(stderr, "deflate should report Z_STREAM_END\n");
+        exit(1);
+    }
+    err = deflateEnd(&c_stream);
+    CHECK_ERR(err, "deflateEnd");
+}
+
+/* ===========================================================================
+ * Test inflate() with large buffers
+ */
+void test_large_inflate(compr, comprLen, uncompr, uncomprLen)
+    Byte *compr, *uncompr;
+    uLong comprLen, uncomprLen;
+{
+    int err;
+    z_stream d_stream; /* decompression stream */
+
+    strcpy((char*)uncompr, "garbage");
+
+    d_stream.zalloc = zalloc;
+    d_stream.zfree = zfree;
+    d_stream.opaque = (voidpf)0;
+
+    d_stream.next_in  = compr;
+    d_stream.avail_in = (uInt)comprLen;
+
+    err = inflateInit(&d_stream);
+    CHECK_ERR(err, "inflateInit");
+
+    for (;;) {
+        d_stream.next_out = uncompr;            /* discard the output */
+        d_stream.avail_out = (uInt)uncomprLen;
+        err = inflate(&d_stream, Z_NO_FLUSH);
+        if (err == Z_STREAM_END) break;
+        CHECK_ERR(err, "large inflate");
+    }
+
+    err = inflateEnd(&d_stream);
+    CHECK_ERR(err, "inflateEnd");
+
+    if (d_stream.total_out != 2*uncomprLen + comprLen/2) {
+        fprintf(stderr, "bad large inflate: %ld\n", d_stream.total_out);
+        exit(1);
+    } else {
+        printf("large_inflate(): OK\n");
+    }
+}
+
+/* ===========================================================================
+ * Test deflate() with full flush
+ */
+void test_flush(compr, comprLen)
+    Byte *compr;
+    uLong *comprLen;
+{
+    z_stream c_stream; /* compression stream */
+    int err;
+    uInt len = (uInt)strlen(hello)+1;
+
+    c_stream.zalloc = zalloc;
+    c_stream.zfree = zfree;
+    c_stream.opaque = (voidpf)0;
+
+    err = deflateInit(&c_stream, Z_DEFAULT_COMPRESSION);
+    CHECK_ERR(err, "deflateInit");
+
+    c_stream.next_in  = (z_const unsigned char *)hello;
+    c_stream.next_out = compr;
+    c_stream.avail_in = 3;
+    c_stream.avail_out = (uInt)*comprLen;
+    err = deflate(&c_stream, Z_FULL_FLUSH);
+    CHECK_ERR(err, "deflate");
+
+    compr[3]++; /* force an error in first compressed block */
+    c_stream.avail_in = len - 3;
+
+    err = deflate(&c_stream, Z_FINISH);
+    if (err != Z_STREAM_END) {
+        CHECK_ERR(err, "deflate");
+    }
+    err = deflateEnd(&c_stream);
+    CHECK_ERR(err, "deflateEnd");
+
+    *comprLen = c_stream.total_out;
+}
+
+/* ===========================================================================
+ * Test inflateSync()
+ */
+void test_sync(compr, comprLen, uncompr, uncomprLen)
+    Byte *compr, *uncompr;
+    uLong comprLen, uncomprLen;
+{
+    int err;
+    z_stream d_stream; /* decompression stream */
+
+    strcpy((char*)uncompr, "garbage");
+
+    d_stream.zalloc = zalloc;
+    d_stream.zfree = zfree;
+    d_stream.opaque = (voidpf)0;
+
+    d_stream.next_in  = compr;
+    d_stream.avail_in = 2; /* just read the zlib header */
+
+    err = inflateInit(&d_stream);
+    CHECK_ERR(err, "inflateInit");
+
+    d_stream.next_out = uncompr;
+    d_stream.avail_out = (uInt)uncomprLen;
+
+    inflate(&d_stream, Z_NO_FLUSH);
+    CHECK_ERR(err, "inflate");
+
+    d_stream.avail_in = (uInt)comprLen-2;   /* read all compressed data */
+    err = inflateSync(&d_stream);           /* but skip the damaged part */
+    CHECK_ERR(err, "inflateSync");
+
+    err = inflate(&d_stream, Z_FINISH);
+    if (err != Z_DATA_ERROR) {
+        fprintf(stderr, "inflate should report DATA_ERROR\n");
+        /* Because of incorrect adler32 */
+        exit(1);
+    }
+    err = inflateEnd(&d_stream);
+    CHECK_ERR(err, "inflateEnd");
+
+    printf("after inflateSync(): hel%s\n", (char *)uncompr);
+}
+
+/* ===========================================================================
+ * Test deflate() with preset dictionary
+ */
+void test_dict_deflate(compr, comprLen)
+    Byte *compr;
+    uLong comprLen;
+{
+    z_stream c_stream; /* compression stream */
+    int err;
+
+    c_stream.zalloc = zalloc;
+    c_stream.zfree = zfree;
+    c_stream.opaque = (voidpf)0;
+
+    err = deflateInit(&c_stream, Z_BEST_COMPRESSION);
+    CHECK_ERR(err, "deflateInit");
+
+    err = deflateSetDictionary(&c_stream,
+                (const Bytef*)dictionary, (int)sizeof(dictionary));
+    CHECK_ERR(err, "deflateSetDictionary");
+
+    dictId = c_stream.adler;
+    c_stream.next_out = compr;
+    c_stream.avail_out = (uInt)comprLen;
+
+    c_stream.next_in = (z_const unsigned char *)hello;
+    c_stream.avail_in = (uInt)strlen(hello)+1;
+
+    err = deflate(&c_stream, Z_FINISH);
+    if (err != Z_STREAM_END) {
+        fprintf(stderr, "deflate should report Z_STREAM_END\n");
+        exit(1);
+    }
+    err = deflateEnd(&c_stream);
+    CHECK_ERR(err, "deflateEnd");
+}
+
+/* ===========================================================================
+ * Test inflate() with a preset dictionary
+ */
+void test_dict_inflate(compr, comprLen, uncompr, uncomprLen)
+    Byte *compr, *uncompr;
+    uLong comprLen, uncomprLen;
+{
+    int err;
+    z_stream d_stream; /* decompression stream */
+
+    strcpy((char*)uncompr, "garbage");
+
+    d_stream.zalloc = zalloc;
+    d_stream.zfree = zfree;
+    d_stream.opaque = (voidpf)0;
+
+    d_stream.next_in  = compr;
+    d_stream.avail_in = (uInt)comprLen;
+
+    err = inflateInit(&d_stream);
+    CHECK_ERR(err, "inflateInit");
+
+    d_stream.next_out = uncompr;
+    d_stream.avail_out = (uInt)uncomprLen;
+
+    for (;;) {
+        err = inflate(&d_stream, Z_NO_FLUSH);
+        if (err == Z_STREAM_END) break;
+        if (err == Z_NEED_DICT) {
+            if (d_stream.adler != dictId) {
+                fprintf(stderr, "unexpected dictionary");
+                exit(1);
+            }
+            err = inflateSetDictionary(&d_stream, (const Bytef*)dictionary,
+                                       (int)sizeof(dictionary));
+        }
+        CHECK_ERR(err, "inflate with dict");
+    }
+
+    err = inflateEnd(&d_stream);
+    CHECK_ERR(err, "inflateEnd");
+
+    if (strcmp((char*)uncompr, hello)) {
+        fprintf(stderr, "bad inflate with dict\n");
+        exit(1);
+    } else {
+        printf("inflate with dictionary: %s\n", (char *)uncompr);
+    }
+}
+
+/* ===========================================================================
+ * Usage:  example [output.gz  [input.gz]]
+ */
+
+int main(argc, argv)
+    int argc;
+    char *argv[];
+{
+    Byte *compr, *uncompr;
+    uLong comprLen = 10000*sizeof(int); /* don't overflow on MSDOS */
+    uLong uncomprLen = comprLen;
+    static const char* myVersion = ZLIB_VERSION;
+
+    if (zlibVersion()[0] != myVersion[0]) {
+        fprintf(stderr, "incompatible zlib version\n");
+        exit(1);
+
+    } else if (strcmp(zlibVersion(), ZLIB_VERSION) != 0) {
+        fprintf(stderr, "warning: different zlib version\n");
+    }
+
+    printf("zlib version %s = 0x%04x, compile flags = 0x%lx\n",
+            ZLIB_VERSION, ZLIB_VERNUM, zlibCompileFlags());
+
+    compr    = (Byte*)calloc((uInt)comprLen, 1);
+    uncompr  = (Byte*)calloc((uInt)uncomprLen, 1);
+    /* compr and uncompr are cleared to avoid reading uninitialized
+     * data and to ensure that uncompr compresses well.
+     */
+    if (compr == Z_NULL || uncompr == Z_NULL) {
+        printf("out of memory\n");
+        exit(1);
+    }
+
+#ifdef Z_SOLO
+    argc = strlen(argv[0]);
+#else
+    test_compress(compr, comprLen, uncompr, uncomprLen);
+
+    test_gzio((argc > 1 ? argv[1] : TESTFILE),
+              uncompr, uncomprLen);
+#endif
+
+    test_deflate(compr, comprLen);
+    test_inflate(compr, comprLen, uncompr, uncomprLen);
+
+    test_large_deflate(compr, comprLen, uncompr, uncomprLen);
+    test_large_inflate(compr, comprLen, uncompr, uncomprLen);
+
+    test_flush(compr, &comprLen);
+    test_sync(compr, comprLen, uncompr, uncomprLen);
+    comprLen = uncomprLen;
+
+    test_dict_deflate(compr, comprLen);
+    test_dict_inflate(compr, comprLen, uncompr, uncomprLen);
+
+    free(compr);
+    free(uncompr);
+
+    return 0;
+}
diff --git a/compat/zlib/test/infcover.c b/compat/zlib/test/infcover.c
new file mode 100644
index 0000000..fe3d920
--- /dev/null
+++ b/compat/zlib/test/infcover.c
@@ -0,0 +1,671 @@
+/* infcover.c -- test zlib's inflate routines with full code coverage
+ * Copyright (C) 2011 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* to use, do: ./configure --cover && make cover */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include "zlib.h"
+
+/* get definition of internal structure so we can mess with it (see pull()),
+   and so we can call inflate_trees() (see cover5()) */
+#define ZLIB_INTERNAL
+#include "inftrees.h"
+#include "inflate.h"
+
+#define local static
+
+/* -- memory tracking routines -- */
+
+/*
+   These memory tracking routines are provided to zlib and track all of zlib's
+   allocations and deallocations, check for LIFO operations, keep a current
+   and high water mark of total bytes requested, optionally set a limit on the
+   total memory that can be allocated, and when done check for memory leaks.
+
+   They are used as follows:
+
+   z_stream strm;
+   mem_setup(&strm)         initializes the memory tracking and sets the
+                            zalloc, zfree, and opaque members of strm to use
+                            memory tracking for all zlib operations on strm
+   mem_limit(&strm, limit)  sets a limit on the total bytes requested -- a
+                            request that exceeds this limit will result in an
+                            allocation failure (returns NULL) -- setting the
+                            limit to zero means no limit, which is the default
+                            after mem_setup()
+   mem_used(&strm, "msg")   prints to stderr "msg" and the total bytes used
+   mem_high(&strm, "msg")   prints to stderr "msg" and the high water mark
+   mem_done(&strm, "msg")   ends memory tracking, releases all allocations
+                            for the tracking as well as leaked zlib blocks, if
+                            any.  If there was anything unusual, such as leaked
+                            blocks, non-FIFO frees, or frees of addresses not
+                            allocated, then "msg" and information about the
+                            problem is printed to stderr.  If everything is
+                            normal, nothing is printed. mem_done resets the
+                            strm members to Z_NULL to use the default memory
+                            allocation routines on the next zlib initialization
+                            using strm.
+ */
+
+/* these items are strung together in a linked list, one for each allocation */
+struct mem_item {
+    void *ptr;                  /* pointer to allocated memory */
+    size_t size;                /* requested size of allocation */
+    struct mem_item *next;      /* pointer to next item in list, or NULL */
+};
+
+/* this structure is at the root of the linked list, and tracks statistics */
+struct mem_zone {
+    struct mem_item *first;     /* pointer to first item in list, or NULL */
+    size_t total, highwater;    /* total allocations, and largest total */
+    size_t limit;               /* memory allocation limit, or 0 if no limit */
+    int notlifo, rogue;         /* counts of non-LIFO frees and rogue frees */
+};
+
+/* memory allocation routine to pass to zlib */
+local void *mem_alloc(void *mem, unsigned count, unsigned size)
+{
+    void *ptr;
+    struct mem_item *item;
+    struct mem_zone *zone = mem;
+    size_t len = count * (size_t)size;
+
+    /* induced allocation failure */
+    if (zone == NULL || (zone->limit && zone->total + len > zone->limit))
+        return NULL;
+
+    /* perform allocation using the standard library, fill memory with a
+       non-zero value to make sure that the code isn't depending on zeros */
+    ptr = malloc(len);
+    if (ptr == NULL)
+        return NULL;
+    memset(ptr, 0xa5, len);
+
+    /* create a new item for the list */
+    item = malloc(sizeof(struct mem_item));
+    if (item == NULL) {
+        free(ptr);
+        return NULL;
+    }
+    item->ptr = ptr;
+    item->size = len;
+
+    /* insert item at the beginning of the list */
+    item->next = zone->first;
+    zone->first = item;
+
+    /* update the statistics */
+    zone->total += item->size;
+    if (zone->total > zone->highwater)
+        zone->highwater = zone->total;
+
+    /* return the allocated memory */
+    return ptr;
+}
+
+/* memory free routine to pass to zlib */
+local void mem_free(void *mem, void *ptr)
+{
+    struct mem_item *item, *next;
+    struct mem_zone *zone = mem;
+
+    /* if no zone, just do a free */
+    if (zone == NULL) {
+        free(ptr);
+        return;
+    }
+
+    /* point next to the item that matches ptr, or NULL if not found -- remove
+       the item from the linked list if found */
+    next = zone->first;
+    if (next) {
+        if (next->ptr == ptr)
+            zone->first = next->next;   /* first one is it, remove from list */
+        else {
+            do {                        /* search the linked list */
+                item = next;
+                next = item->next;
+            } while (next != NULL && next->ptr != ptr);
+            if (next) {                 /* if found, remove from linked list */
+                item->next = next->next;
+                zone->notlifo++;        /* not a LIFO free */
+            }
+
+        }
+    }
+
+    /* if found, update the statistics and free the item */
+    if (next) {
+        zone->total -= next->size;
+        free(next);
+    }
+
+    /* if not found, update the rogue count */
+    else
+        zone->rogue++;
+
+    /* in any case, do the requested free with the standard library function */
+    free(ptr);
+}
+
+/* set up a controlled memory allocation space for monitoring, set the stream
+   parameters to the controlled routines, with opaque pointing to the space */
+local void mem_setup(z_stream *strm)
+{
+    struct mem_zone *zone;
+
+    zone = malloc(sizeof(struct mem_zone));
+    assert(zone != NULL);
+    zone->first = NULL;
+    zone->total = 0;
+    zone->highwater = 0;
+    zone->limit = 0;
+    zone->notlifo = 0;
+    zone->rogue = 0;
+    strm->opaque = zone;
+    strm->zalloc = mem_alloc;
+    strm->zfree = mem_free;
+}
+
+/* set a limit on the total memory allocation, or 0 to remove the limit */
+local void mem_limit(z_stream *strm, size_t limit)
+{
+    struct mem_zone *zone = strm->opaque;
+
+    zone->limit = limit;
+}
+
+/* show the current total requested allocations in bytes */
+local void mem_used(z_stream *strm, char *prefix)
+{
+    struct mem_zone *zone = strm->opaque;
+
+    fprintf(stderr, "%s: %lu allocated\n", prefix, zone->total);
+}
+
+/* show the high water allocation in bytes */
+local void mem_high(z_stream *strm, char *prefix)
+{
+    struct mem_zone *zone = strm->opaque;
+
+    fprintf(stderr, "%s: %lu high water mark\n", prefix, zone->highwater);
+}
+
+/* release the memory allocation zone -- if there are any surprises, notify */
+local void mem_done(z_stream *strm, char *prefix)
+{
+    int count = 0;
+    struct mem_item *item, *next;
+    struct mem_zone *zone = strm->opaque;
+
+    /* show high water mark */
+    mem_high(strm, prefix);
+
+    /* free leftover allocations and item structures, if any */
+    item = zone->first;
+    while (item != NULL) {
+        free(item->ptr);
+        next = item->next;
+        free(item);
+        item = next;
+        count++;
+    }
+
+    /* issue alerts about anything unexpected */
+    if (count || zone->total)
+        fprintf(stderr, "** %s: %lu bytes in %d blocks not freed\n",
+                prefix, zone->total, count);
+    if (zone->notlifo)
+        fprintf(stderr, "** %s: %d frees not LIFO\n", prefix, zone->notlifo);
+    if (zone->rogue)
+        fprintf(stderr, "** %s: %d frees not recognized\n",
+                prefix, zone->rogue);
+
+    /* free the zone and delete from the stream */
+    free(zone);
+    strm->opaque = Z_NULL;
+    strm->zalloc = Z_NULL;
+    strm->zfree = Z_NULL;
+}
+
+/* -- inflate test routines -- */
+
+/* Decode a hexadecimal string, set *len to length, in[] to the bytes.  This
+   decodes liberally, in that hex digits can be adjacent, in which case two in
+   a row writes a byte.  Or they can delimited by any non-hex character, where
+   the delimiters are ignored except when a single hex digit is followed by a
+   delimiter in which case that single digit writes a byte.  The returned
+   data is allocated and must eventually be freed.  NULL is returned if out of
+   memory.  If the length is not needed, then len can be NULL. */
+local unsigned char *h2b(const char *hex, unsigned *len)
+{
+    unsigned char *in;
+    unsigned next, val;
+
+    in = malloc((strlen(hex) + 1) >> 1);
+    if (in == NULL)
+        return NULL;
+    next = 0;
+    val = 1;
+    do {
+        if (*hex >= '0' && *hex <= '9')
+            val = (val << 4) + *hex - '0';
+        else if (*hex >= 'A' && *hex <= 'F')
+            val = (val << 4) + *hex - 'A' + 10;
+        else if (*hex >= 'a' && *hex <= 'f')
+            val = (val << 4) + *hex - 'a' + 10;
+        else if (val != 1 && val < 32)  /* one digit followed by delimiter */
+            val += 240;                 /* make it look like two digits */
+        if (val > 255) {                /* have two digits */
+            in[next++] = val & 0xff;    /* save the decoded byte */
+            val = 1;                    /* start over */
+        }
+    } while (*hex++);       /* go through the loop with the terminating null */
+    if (len != NULL)
+        *len = next;
+    in = reallocf(in, next);
+    return in;
+}
+
+/* generic inflate() run, where hex is the hexadecimal input data, what is the
+   text to include in an error message, step is how much input data to feed
+   inflate() on each call, or zero to feed it all, win is the window bits
+   parameter to inflateInit2(), len is the size of the output buffer, and err
+   is the error code expected from the first inflate() call (the second
+   inflate() call is expected to return Z_STREAM_END).  If win is 47, then
+   header information is collected with inflateGetHeader().  If a zlib stream
+   is looking for a dictionary, then an empty dictionary is provided.
+   inflate() is run until all of the input data is consumed. */
+local void inf(char *hex, char *what, unsigned step, int win, unsigned len,
+               int err)
+{
+    int ret;
+    unsigned have;
+    unsigned char *in, *out;
+    z_stream strm, copy;
+    gz_header head;
+
+    mem_setup(&strm);
+    strm.avail_in = 0;
+    strm.next_in = Z_NULL;
+    ret = inflateInit2(&strm, win);
+    if (ret != Z_OK) {
+        mem_done(&strm, what);
+        return;
+    }
+    out = malloc(len);                          assert(out != NULL);
+    if (win == 47) {
+        head.extra = out;
+        head.extra_max = len;
+        head.name = out;
+        head.name_max = len;
+        head.comment = out;
+        head.comm_max = len;
+        ret = inflateGetHeader(&strm, &head);   assert(ret == Z_OK);
+    }
+    in = h2b(hex, &have);                       assert(in != NULL);
+    if (step == 0 || step > have)
+        step = have;
+    strm.avail_in = step;
+    have -= step;
+    strm.next_in = in;
+    do {
+        strm.avail_out = len;
+        strm.next_out = out;
+        ret = inflate(&strm, Z_NO_FLUSH);       assert(err == 9 || ret == err);
+        if (ret != Z_OK && ret != Z_BUF_ERROR && ret != Z_NEED_DICT)
+            break;
+        if (ret == Z_NEED_DICT) {
+            ret = inflateSetDictionary(&strm, in, 1);
+                                                assert(ret == Z_DATA_ERROR);
+            mem_limit(&strm, 1);
+            ret = inflateSetDictionary(&strm, out, 0);
+                                                assert(ret == Z_MEM_ERROR);
+            mem_limit(&strm, 0);
+            ((struct inflate_state *)strm.state)->mode = DICT;
+            ret = inflateSetDictionary(&strm, out, 0);
+                                                assert(ret == Z_OK);
+            ret = inflate(&strm, Z_NO_FLUSH);   assert(ret == Z_BUF_ERROR);
+        }
+        ret = inflateCopy(&copy, &strm);        assert(ret == Z_OK);
+        ret = inflateEnd(&copy);                assert(ret == Z_OK);
+        err = 9;                        /* don't care next time around */
+        have += strm.avail_in;
+        strm.avail_in = step > have ? have : step;
+        have -= strm.avail_in;
+    } while (strm.avail_in);
+    free(in);
+    free(out);
+    ret = inflateReset2(&strm, -8);             assert(ret == Z_OK);
+    ret = inflateEnd(&strm);                    assert(ret == Z_OK);
+    mem_done(&strm, what);
+}
+
+/* cover all of the lines in inflate.c up to inflate() */
+local void cover_support(void)
+{
+    int ret;
+    z_stream strm;
+
+    mem_setup(&strm);
+    strm.avail_in = 0;
+    strm.next_in = Z_NULL;
+    ret = inflateInit(&strm);                   assert(ret == Z_OK);
+    mem_used(&strm, "inflate init");
+    ret = inflatePrime(&strm, 5, 31);           assert(ret == Z_OK);
+    ret = inflatePrime(&strm, -1, 0);           assert(ret == Z_OK);
+    ret = inflateSetDictionary(&strm, Z_NULL, 0);
+                                                assert(ret == Z_STREAM_ERROR);
+    ret = inflateEnd(&strm);                    assert(ret == Z_OK);
+    mem_done(&strm, "prime");
+
+    inf("63 0", "force window allocation", 0, -15, 1, Z_OK);
+    inf("63 18 5", "force window replacement", 0, -8, 259, Z_OK);
+    inf("63 18 68 30 d0 0 0", "force split window update", 4, -8, 259, Z_OK);
+    inf("3 0", "use fixed blocks", 0, -15, 1, Z_STREAM_END);
+    inf("", "bad window size", 0, 1, 0, Z_STREAM_ERROR);
+
+    mem_setup(&strm);
+    strm.avail_in = 0;
+    strm.next_in = Z_NULL;
+    ret = inflateInit_(&strm, ZLIB_VERSION - 1, (int)sizeof(z_stream));
+                                                assert(ret == Z_VERSION_ERROR);
+    mem_done(&strm, "wrong version");
+
+    strm.avail_in = 0;
+    strm.next_in = Z_NULL;
+    ret = inflateInit(&strm);                   assert(ret == Z_OK);
+    ret = inflateEnd(&strm);                    assert(ret == Z_OK);
+    fputs("inflate built-in memory routines\n", stderr);
+}
+
+/* cover all inflate() header and trailer cases and code after inflate() */
+local void cover_wrap(void)
+{
+    int ret;
+    z_stream strm, copy;
+    unsigned char dict[257];
+
+    ret = inflate(Z_NULL, 0);                   assert(ret == Z_STREAM_ERROR);
+    ret = inflateEnd(Z_NULL);                   assert(ret == Z_STREAM_ERROR);
+    ret = inflateCopy(Z_NULL, Z_NULL);          assert(ret == Z_STREAM_ERROR);
+    fputs("inflate bad parameters\n", stderr);
+
+    inf("1f 8b 0 0", "bad gzip method", 0, 31, 0, Z_DATA_ERROR);
+    inf("1f 8b 8 80", "bad gzip flags", 0, 31, 0, Z_DATA_ERROR);
+    inf("77 85", "bad zlib method", 0, 15, 0, Z_DATA_ERROR);
+    inf("8 99", "set window size from header", 0, 0, 0, Z_OK);
+    inf("78 9c", "bad zlib window size", 0, 8, 0, Z_DATA_ERROR);
+    inf("78 9c 63 0 0 0 1 0 1", "check adler32", 0, 15, 1, Z_STREAM_END);
+    inf("1f 8b 8 1e 0 0 0 0 0 0 1 0 0 0 0 0 0", "bad header crc", 0, 47, 1,
+        Z_DATA_ERROR);
+    inf("1f 8b 8 2 0 0 0 0 0 0 1d 26 3 0 0 0 0 0 0 0 0 0", "check gzip length",
+        0, 47, 0, Z_STREAM_END);
+    inf("78 90", "bad zlib header check", 0, 47, 0, Z_DATA_ERROR);
+    inf("8 b8 0 0 0 1", "need dictionary", 0, 8, 0, Z_NEED_DICT);
+    inf("78 9c 63 0", "compute adler32", 0, 15, 1, Z_OK);
+
+    mem_setup(&strm);
+    strm.avail_in = 0;
+    strm.next_in = Z_NULL;
+    ret = inflateInit2(&strm, -8);
+    strm.avail_in = 2;
+    strm.next_in = (void *)"\x63";
+    strm.avail_out = 1;
+    strm.next_out = (void *)&ret;
+    mem_limit(&strm, 1);
+    ret = inflate(&strm, Z_NO_FLUSH);           assert(ret == Z_MEM_ERROR);
+    ret = inflate(&strm, Z_NO_FLUSH);           assert(ret == Z_MEM_ERROR);
+    mem_limit(&strm, 0);
+    memset(dict, 0, 257);
+    ret = inflateSetDictionary(&strm, dict, 257);
+                                                assert(ret == Z_OK);
+    mem_limit(&strm, (sizeof(struct inflate_state) << 1) + 256);
+    ret = inflatePrime(&strm, 16, 0);           assert(ret == Z_OK);
+    strm.avail_in = 2;
+    strm.next_in = (void *)"\x80";
+    ret = inflateSync(&strm);                   assert(ret == Z_DATA_ERROR);
+    ret = inflate(&strm, Z_NO_FLUSH);           assert(ret == Z_STREAM_ERROR);
+    strm.avail_in = 4;
+    strm.next_in = (void *)"\0\0\xff\xff";
+    ret = inflateSync(&strm);                   assert(ret == Z_OK);
+    (void)inflateSyncPoint(&strm);
+    ret = inflateCopy(&copy, &strm);            assert(ret == Z_MEM_ERROR);
+    mem_limit(&strm, 0);
+    ret = inflateUndermine(&strm, 1);           assert(ret == Z_DATA_ERROR);
+    (void)inflateMark(&strm);
+    ret = inflateEnd(&strm);                    assert(ret == Z_OK);
+    mem_done(&strm, "miscellaneous, force memory errors");
+}
+
+/* input and output functions for inflateBack() */
+local unsigned pull(void *desc, unsigned char **buf)
+{
+    static unsigned int next = 0;
+    static unsigned char dat[] = {0x63, 0, 2, 0};
+    struct inflate_state *state;
+
+    if (desc == Z_NULL) {
+        next = 0;
+        return 0;   /* no input (already provided at next_in) */
+    }
+    state = (void *)((z_stream *)desc)->state;
+    if (state != Z_NULL)
+        state->mode = SYNC;     /* force an otherwise impossible situation */
+    return next < sizeof(dat) ? (*buf = dat + next++, 1) : 0;
+}
+
+local int push(void *desc, unsigned char *buf, unsigned len)
+{
+    buf += len;
+    return desc != Z_NULL;      /* force error if desc not null */
+}
+
+/* cover inflateBack() up to common deflate data cases and after those */
+local void cover_back(void)
+{
+    int ret;
+    z_stream strm;
+    unsigned char win[32768];
+
+    ret = inflateBackInit_(Z_NULL, 0, win, 0, 0);
+                                                assert(ret == Z_VERSION_ERROR);
+    ret = inflateBackInit(Z_NULL, 0, win);      assert(ret == Z_STREAM_ERROR);
+    ret = inflateBack(Z_NULL, Z_NULL, Z_NULL, Z_NULL, Z_NULL);
+                                                assert(ret == Z_STREAM_ERROR);
+    ret = inflateBackEnd(Z_NULL);               assert(ret == Z_STREAM_ERROR);
+    fputs("inflateBack bad parameters\n", stderr);
+
+    mem_setup(&strm);
+    ret = inflateBackInit(&strm, 15, win);      assert(ret == Z_OK);
+    strm.avail_in = 2;
+    strm.next_in = (void *)"\x03";
+    ret = inflateBack(&strm, pull, Z_NULL, push, Z_NULL);
+                                                assert(ret == Z_STREAM_END);
+        /* force output error */
+    strm.avail_in = 3;
+    strm.next_in = (void *)"\x63\x00";
+    ret = inflateBack(&strm, pull, Z_NULL, push, &strm);
+                                                assert(ret == Z_BUF_ERROR);
+        /* force mode error by mucking with state */
+    ret = inflateBack(&strm, pull, &strm, push, Z_NULL);
+                                                assert(ret == Z_STREAM_ERROR);
+    ret = inflateBackEnd(&strm);                assert(ret == Z_OK);
+    mem_done(&strm, "inflateBack bad state");
+
+    ret = inflateBackInit(&strm, 15, win);      assert(ret == Z_OK);
+    ret = inflateBackEnd(&strm);                assert(ret == Z_OK);
+    fputs("inflateBack built-in memory routines\n", stderr);
+}
+
+/* do a raw inflate of data in hexadecimal with both inflate and inflateBack */
+local int try(char *hex, char *id, int err)
+{
+    int ret;
+    unsigned len, size;
+    unsigned char *in, *out, *win;
+    char *prefix;
+    z_stream strm;
+
+    /* convert to hex */
+    in = h2b(hex, &len);
+    assert(in != NULL);
+
+    /* allocate work areas */
+    size = len << 3;
+    out = malloc(size);
+    assert(out != NULL);
+    win = malloc(32768);
+    assert(win != NULL);
+    prefix = malloc(strlen(id) + 6);
+    assert(prefix != NULL);
+
+    /* first with inflate */
+    strcpy(prefix, id);
+    strcat(prefix, "-late");
+    mem_setup(&strm);
+    strm.avail_in = 0;
+    strm.next_in = Z_NULL;
+    ret = inflateInit2(&strm, err < 0 ? 47 : -15);
+    assert(ret == Z_OK);
+    strm.avail_in = len;
+    strm.next_in = in;
+    do {
+        strm.avail_out = size;
+        strm.next_out = out;
+        ret = inflate(&strm, Z_TREES);
+        assert(ret != Z_STREAM_ERROR && ret != Z_MEM_ERROR);
+        if (ret == Z_DATA_ERROR || ret == Z_NEED_DICT)
+            break;
+    } while (strm.avail_in || strm.avail_out == 0);
+    if (err) {
+        assert(ret == Z_DATA_ERROR);
+        assert(strcmp(id, strm.msg) == 0);
+    }
+    inflateEnd(&strm);
+    mem_done(&strm, prefix);
+
+    /* then with inflateBack */
+    if (err >= 0) {
+        strcpy(prefix, id);
+        strcat(prefix, "-back");
+        mem_setup(&strm);
+        ret = inflateBackInit(&strm, 15, win);
+        assert(ret == Z_OK);
+        strm.avail_in = len;
+        strm.next_in = in;
+        ret = inflateBack(&strm, pull, Z_NULL, push, Z_NULL);
+        assert(ret != Z_STREAM_ERROR);
+        if (err) {
+            assert(ret == Z_DATA_ERROR);
+            assert(strcmp(id, strm.msg) == 0);
+        }
+        inflateBackEnd(&strm);
+        mem_done(&strm, prefix);
+    }
+
+    /* clean up */
+    free(prefix);
+    free(win);
+    free(out);
+    free(in);
+    return ret;
+}
+
+/* cover deflate data cases in both inflate() and inflateBack() */
+local void cover_inflate(void)
+{
+    try("0 0 0 0 0", "invalid stored block lengths", 1);
+    try("3 0", "fixed", 0);
+    try("6", "invalid block type", 1);
+    try("1 1 0 fe ff 0", "stored", 0);
+    try("fc 0 0", "too many length or distance symbols", 1);
+    try("4 0 fe ff", "invalid code lengths set", 1);
+    try("4 0 24 49 0", "invalid bit length repeat", 1);
+    try("4 0 24 e9 ff ff", "invalid bit length repeat", 1);
+    try("4 0 24 e9 ff 6d", "invalid code -- missing end-of-block", 1);
+    try("4 80 49 92 24 49 92 24 71 ff ff 93 11 0",
+        "invalid literal/lengths set", 1);
+    try("4 80 49 92 24 49 92 24 f b4 ff ff c3 84", "invalid distances set", 1);
+    try("4 c0 81 8 0 0 0 0 20 7f eb b 0 0", "invalid literal/length code", 1);
+    try("2 7e ff ff", "invalid distance code", 1);
+    try("c c0 81 0 0 0 0 0 90 ff 6b 4 0", "invalid distance too far back", 1);
+
+    /* also trailer mismatch just in inflate() */
+    try("1f 8b 8 0 0 0 0 0 0 0 3 0 0 0 0 1", "incorrect data check", -1);
+    try("1f 8b 8 0 0 0 0 0 0 0 3 0 0 0 0 0 0 0 0 1",
+        "incorrect length check", -1);
+    try("5 c0 21 d 0 0 0 80 b0 fe 6d 2f 91 6c", "pull 17", 0);
+    try("5 e0 81 91 24 cb b2 2c 49 e2 f 2e 8b 9a 47 56 9f fb fe ec d2 ff 1f",
+        "long code", 0);
+    try("ed c0 1 1 0 0 0 40 20 ff 57 1b 42 2c 4f", "length extra", 0);
+    try("ed cf c1 b1 2c 47 10 c4 30 fa 6f 35 1d 1 82 59 3d fb be 2e 2a fc f c",
+        "long distance and extra", 0);
+    try("ed c0 81 0 0 0 0 80 a0 fd a9 17 a9 0 0 0 0 0 0 0 0 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", "window end", 0);
+    inf("2 8 20 80 0 3 0", "inflate_fast TYPE return", 0, -15, 258,
+        Z_STREAM_END);
+    inf("63 18 5 40 c 0", "window wrap", 3, -8, 300, Z_OK);
+}
+
+/* cover remaining lines in inftrees.c */
+local void cover_trees(void)
+{
+    int ret;
+    unsigned bits;
+    unsigned short lens[16], work[16];
+    code *next, table[ENOUGH_DISTS];
+
+    /* we need to call inflate_table() directly in order to manifest not-
+       enough errors, since zlib insures that enough is always enough */
+    for (bits = 0; bits < 15; bits++)
+        lens[bits] = (unsigned short)(bits + 1);
+    lens[15] = 15;
+    next = table;
+    bits = 15;
+    ret = inflate_table(DISTS, lens, 16, &next, &bits, work);
+                                                assert(ret == 1);
+    next = table;
+    bits = 1;
+    ret = inflate_table(DISTS, lens, 16, &next, &bits, work);
+                                                assert(ret == 1);
+    fputs("inflate_table not enough errors\n", stderr);
+}
+
+/* cover remaining inffast.c decoding and window copying */
+local void cover_fast(void)
+{
+    inf("e5 e0 81 ad 6d cb b2 2c c9 01 1e 59 63 ae 7d ee fb 4d fd b5 35 41 68"
+        " ff 7f 0f 0 0 0", "fast length extra bits", 0, -8, 258, Z_DATA_ERROR);
+    inf("25 fd 81 b5 6d 59 b6 6a 49 ea af 35 6 34 eb 8c b9 f6 b9 1e ef 67 49"
+        " 50 fe ff ff 3f 0 0", "fast distance extra bits", 0, -8, 258,
+        Z_DATA_ERROR);
+    inf("3 7e 0 0 0 0 0", "fast invalid distance code", 0, -8, 258,
+        Z_DATA_ERROR);
+    inf("1b 7 0 0 0 0 0", "fast invalid literal/length code", 0, -8, 258,
+        Z_DATA_ERROR);
+    inf("d c7 1 ae eb 38 c 4 41 a0 87 72 de df fb 1f b8 36 b1 38 5d ff ff 0",
+        "fast 2nd level codes and too far back", 0, -8, 258, Z_DATA_ERROR);
+    inf("63 18 5 8c 10 8 0 0 0 0", "very common case", 0, -8, 259, Z_OK);
+    inf("63 60 60 18 c9 0 8 18 18 18 26 c0 28 0 29 0 0 0",
+        "contiguous and wrap around window", 6, -8, 259, Z_OK);
+    inf("63 0 3 0 0 0 0 0", "copy direct from output", 0, -8, 259,
+        Z_STREAM_END);
+}
+
+int main(void)
+{
+    fprintf(stderr, "%s\n", zlibVersion());
+    cover_support();
+    cover_wrap();
+    cover_back();
+    cover_inflate();
+    cover_trees();
+    cover_fast();
+    return 0;
+}
diff --git a/compat/zlib/test/minigzip.c b/compat/zlib/test/minigzip.c
new file mode 100644
index 0000000..b3025a4
--- /dev/null
+++ b/compat/zlib/test/minigzip.c
@@ -0,0 +1,651 @@
+/* minigzip.c -- simulate gzip using the zlib compression library
+ * Copyright (C) 1995-2006, 2010, 2011 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/*
+ * minigzip is a minimal implementation of the gzip utility. This is
+ * only an example of using zlib and isn't meant to replace the
+ * full-featured gzip. No attempt is made to deal with file systems
+ * limiting names to 14 or 8+3 characters, etc... Error checking is
+ * very limited. So use minigzip only for testing; use gzip for the
+ * real thing. On MSDOS, use only on file names without extension
+ * or in pipe mode.
+ */
+
+/* @(#) $Id$ */
+
+#include "zlib.h"
+#include <stdio.h>
+
+#ifdef STDC
+#  include <string.h>
+#  include <stdlib.h>
+#endif
+
+#ifdef USE_MMAP
+#  include <sys/types.h>
+#  include <sys/mman.h>
+#  include <sys/stat.h>
+#endif
+
+#if defined(MSDOS) || defined(OS2) || defined(WIN32) || defined(__CYGWIN__)
+#  include <fcntl.h>
+#  include <io.h>
+#  ifdef UNDER_CE
+#    include <stdlib.h>
+#  endif
+#  define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY)
+#else
+#  define SET_BINARY_MODE(file)
+#endif
+
+#ifdef _MSC_VER
+#  define snprintf _snprintf
+#endif
+
+#ifdef VMS
+#  define unlink delete
+#  define GZ_SUFFIX "-gz"
+#endif
+#ifdef RISCOS
+#  define unlink remove
+#  define GZ_SUFFIX "-gz"
+#  define fileno(file) file->__file
+#endif
+#if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os
+#  include <unix.h> /* for fileno */
+#endif
+
+#if !defined(Z_HAVE_UNISTD_H) && !defined(_LARGEFILE64_SOURCE)
+#ifndef WIN32 /* unlink already in stdio.h for WIN32 */
+  extern int unlink OF((const char *));
+#endif
+#endif
+
+#if defined(UNDER_CE)
+#  include <windows.h>
+#  define perror(s) pwinerror(s)
+
+/* Map the Windows error number in ERROR to a locale-dependent error
+   message string and return a pointer to it.  Typically, the values
+   for ERROR come from GetLastError.
+
+   The string pointed to shall not be modified by the application,
+   but may be overwritten by a subsequent call to strwinerror
+
+   The strwinerror function does not change the current setting
+   of GetLastError.  */
+
+static char *strwinerror (error)
+     DWORD error;
+{
+    static char buf[1024];
+
+    wchar_t *msgbuf;
+    DWORD lasterr = GetLastError();
+    DWORD chars = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM
+        | FORMAT_MESSAGE_ALLOCATE_BUFFER,
+        NULL,
+        error,
+        0, /* Default language */
+        (LPVOID)&msgbuf,
+        0,
+        NULL);
+    if (chars != 0) {
+        /* If there is an \r\n appended, zap it.  */
+        if (chars >= 2
+            && msgbuf[chars - 2] == '\r' && msgbuf[chars - 1] == '\n') {
+            chars -= 2;
+            msgbuf[chars] = 0;
+        }
+
+        if (chars > sizeof (buf) - 1) {
+            chars = sizeof (buf) - 1;
+            msgbuf[chars] = 0;
+        }
+
+        wcstombs(buf, msgbuf, chars + 1);
+        LocalFree(msgbuf);
+    }
+    else {
+        sprintf(buf, "unknown win32 error (%ld)", error);
+    }
+
+    SetLastError(lasterr);
+    return buf;
+}
+
+static void pwinerror (s)
+    const char *s;
+{
+    if (s && *s)
+        fprintf(stderr, "%s: %s\n", s, strwinerror(GetLastError ()));
+    else
+        fprintf(stderr, "%s\n", strwinerror(GetLastError ()));
+}
+
+#endif /* UNDER_CE */
+
+#ifndef GZ_SUFFIX
+#  define GZ_SUFFIX ".gz"
+#endif
+#define SUFFIX_LEN (sizeof(GZ_SUFFIX)-1)
+
+#define BUFLEN      16384
+#define MAX_NAME_LEN 1024
+
+#ifdef MAXSEG_64K
+#  define local static
+   /* Needed for systems with limitation on stack size. */
+#else
+#  define local
+#endif
+
+#ifdef Z_SOLO
+/* for Z_SOLO, create simplified gz* functions using deflate and inflate */
+
+#if defined(Z_HAVE_UNISTD_H) || defined(Z_LARGE)
+#  include <unistd.h>       /* for unlink() */
+#endif
+
+void *myalloc OF((void *, unsigned, unsigned));
+void myfree OF((void *, void *));
+
+void *myalloc(q, n, m)
+    void *q;
+    unsigned n, m;
+{
+    q = Z_NULL;
+    return calloc(n, m);
+}
+
+void myfree(q, p)
+    void *q, *p;
+{
+    q = Z_NULL;
+    free(p);
+}
+
+typedef struct gzFile_s {
+    FILE *file;
+    int write;
+    int err;
+    char *msg;
+    z_stream strm;
+} *gzFile;
+
+gzFile gzopen OF((const char *, const char *));
+gzFile gzdopen OF((int, const char *));
+gzFile gz_open OF((const char *, int, const char *));
+
+gzFile gzopen(path, mode)
+const char *path;
+const char *mode;
+{
+    return gz_open(path, -1, mode);
+}
+
+gzFile gzdopen(fd, mode)
+int fd;
+const char *mode;
+{
+    return gz_open(NULL, fd, mode);
+}
+
+gzFile gz_open(path, fd, mode)
+    const char *path;
+    int fd;
+    const char *mode;
+{
+    gzFile gz;
+    int ret;
+
+    gz = malloc(sizeof(struct gzFile_s));
+    if (gz == NULL)
+        return NULL;
+    gz->write = strchr(mode, 'w') != NULL;
+    gz->strm.zalloc = myalloc;
+    gz->strm.zfree = myfree;
+    gz->strm.opaque = Z_NULL;
+    if (gz->write)
+        ret = deflateInit2(&(gz->strm), -1, 8, 15 + 16, 8, 0);
+    else {
+        gz->strm.next_in = 0;
+        gz->strm.avail_in = Z_NULL;
+        ret = inflateInit2(&(gz->strm), 15 + 16);
+    }
+    if (ret != Z_OK) {
+        free(gz);
+        return NULL;
+    }
+    gz->file = path == NULL ? fdopen(fd, gz->write ? "wb" : "rb") :
+                              fopen(path, gz->write ? "wb" : "rb");
+    if (gz->file == NULL) {
+        gz->write ? deflateEnd(&(gz->strm)) : inflateEnd(&(gz->strm));
+        free(gz);
+        return NULL;
+    }
+    gz->err = 0;
+    gz->msg = "";
+    return gz;
+}
+
+int gzwrite OF((gzFile, const void *, unsigned));
+
+int gzwrite(gz, buf, len)
+    gzFile gz;
+    const void *buf;
+    unsigned len;
+{
+    z_stream *strm;
+    unsigned char out[BUFLEN];
+
+    if (gz == NULL || !gz->write)
+        return 0;
+    strm = &(gz->strm);
+    strm->next_in = (void *)buf;
+    strm->avail_in = len;
+    do {
+        strm->next_out = out;
+        strm->avail_out = BUFLEN;
+        (void)deflate(strm, Z_NO_FLUSH);
+        fwrite(out, 1, BUFLEN - strm->avail_out, gz->file);
+    } while (strm->avail_out == 0);
+    return len;
+}
+
+int gzread OF((gzFile, void *, unsigned));
+
+int gzread(gz, buf, len)
+    gzFile gz;
+    void *buf;
+    unsigned len;
+{
+    int ret;
+    unsigned got;
+    unsigned char in[1];
+    z_stream *strm;
+
+    if (gz == NULL || gz->write)
+        return 0;
+    if (gz->err)
+        return 0;
+    strm = &(gz->strm);
+    strm->next_out = (void *)buf;
+    strm->avail_out = len;
+    do {
+        got = fread(in, 1, 1, gz->file);
+        if (got == 0)
+            break;
+        strm->next_in = in;
+        strm->avail_in = 1;
+        ret = inflate(strm, Z_NO_FLUSH);
+        if (ret == Z_DATA_ERROR) {
+            gz->err = Z_DATA_ERROR;
+            gz->msg = strm->msg;
+            return 0;
+        }
+        if (ret == Z_STREAM_END)
+            inflateReset(strm);
+    } while (strm->avail_out);
+    return len - strm->avail_out;
+}
+
+int gzclose OF((gzFile));
+
+int gzclose(gz)
+    gzFile gz;
+{
+    z_stream *strm;
+    unsigned char out[BUFLEN];
+
+    if (gz == NULL)
+        return Z_STREAM_ERROR;
+    strm = &(gz->strm);
+    if (gz->write) {
+        strm->next_in = Z_NULL;
+        strm->avail_in = 0;
+        do {
+            strm->next_out = out;
+            strm->avail_out = BUFLEN;
+            (void)deflate(strm, Z_FINISH);
+            fwrite(out, 1, BUFLEN - strm->avail_out, gz->file);
+        } while (strm->avail_out == 0);
+        deflateEnd(strm);
+    }
+    else
+        inflateEnd(strm);
+    fclose(gz->file);
+    free(gz);
+    return Z_OK;
+}
+
+const char *gzerror OF((gzFile, int *));
+
+const char *gzerror(gz, err)
+    gzFile gz;
+    int *err;
+{
+    *err = gz->err;
+    return gz->msg;
+}
+
+#endif
+
+char *prog;
+
+void error            OF((const char *msg));
+void gz_compress      OF((FILE   *in, gzFile out));
+#ifdef USE_MMAP
+int  gz_compress_mmap OF((FILE   *in, gzFile out));
+#endif
+void gz_uncompress    OF((gzFile in, FILE   *out));
+void file_compress    OF((char  *file, char *mode));
+void file_uncompress  OF((char  *file));
+int  main             OF((int argc, char *argv[]));
+
+/* ===========================================================================
+ * Display error message and exit
+ */
+void error(msg)
+    const char *msg;
+{
+    fprintf(stderr, "%s: %s\n", prog, msg);
+    exit(1);
+}
+
+/* ===========================================================================
+ * Compress input to output then close both files.
+ */
+
+void gz_compress(in, out)
+    FILE   *in;
+    gzFile out;
+{
+    local char buf[BUFLEN];
+    int len;
+    int err;
+
+#ifdef USE_MMAP
+    /* Try first compressing with mmap. If mmap fails (minigzip used in a
+     * pipe), use the normal fread loop.
+     */
+    if (gz_compress_mmap(in, out) == Z_OK) return;
+#endif
+    for (;;) {
+        len = (int)fread(buf, 1, sizeof(buf), in);
+        if (ferror(in)) {
+            perror("fread");
+            exit(1);
+        }
+        if (len == 0) break;
+
+        if (gzwrite(out, buf, (unsigned)len) != len) error(gzerror(out, &err));
+    }
+    fclose(in);
+    if (gzclose(out) != Z_OK) error("failed gzclose");
+}
+
+#ifdef USE_MMAP /* MMAP version, Miguel Albrecht <malbrech@eso.org> */
+
+/* Try compressing the input file at once using mmap. Return Z_OK if
+ * if success, Z_ERRNO otherwise.
+ */
+int gz_compress_mmap(in, out)
+    FILE   *in;
+    gzFile out;
+{
+    int len;
+    int err;
+    int ifd = fileno(in);
+    caddr_t buf;    /* mmap'ed buffer for the entire input file */
+    off_t buf_len;  /* length of the input file */
+    struct stat sb;
+
+    /* Determine the size of the file, needed for mmap: */
+    if (fstat(ifd, &sb) < 0) return Z_ERRNO;
+    buf_len = sb.st_size;
+    if (buf_len <= 0) return Z_ERRNO;
+
+    /* Now do the actual mmap: */
+    buf = mmap((caddr_t) 0, buf_len, PROT_READ, MAP_SHARED, ifd, (off_t)0);
+    if (buf == (caddr_t)(-1)) return Z_ERRNO;
+
+    /* Compress the whole file at once: */
+    len = gzwrite(out, (char *)buf, (unsigned)buf_len);
+
+    if (len != (int)buf_len) error(gzerror(out, &err));
+
+    munmap(buf, buf_len);
+    fclose(in);
+    if (gzclose(out) != Z_OK) error("failed gzclose");
+    return Z_OK;
+}
+#endif /* USE_MMAP */
+
+/* ===========================================================================
+ * Uncompress input to output then close both files.
+ */
+void gz_uncompress(in, out)
+    gzFile in;
+    FILE   *out;
+{
+    local char buf[BUFLEN];
+    int len;
+    int err;
+
+    for (;;) {
+        len = gzread(in, buf, sizeof(buf));
+        if (len < 0) error (gzerror(in, &err));
+        if (len == 0) break;
+
+        if ((int)fwrite(buf, 1, (unsigned)len, out) != len) {
+            error("failed fwrite");
+        }
+    }
+    if (fclose(out)) error("failed fclose");
+
+    if (gzclose(in) != Z_OK) error("failed gzclose");
+}
+
+
+/* ===========================================================================
+ * Compress the given file: create a corresponding .gz file and remove the
+ * original.
+ */
+void file_compress(file, mode)
+    char  *file;
+    char  *mode;
+{
+    local char outfile[MAX_NAME_LEN];
+    FILE  *in;
+    gzFile out;
+
+    if (strlen(file) + strlen(GZ_SUFFIX) >= sizeof(outfile)) {
+        fprintf(stderr, "%s: filename too long\n", prog);
+        exit(1);
+    }
+
+#if !defined(NO_snprintf) && !defined(NO_vsnprintf)
+    snprintf(outfile, sizeof(outfile), "%s%s", file, GZ_SUFFIX);
+#else
+    strcpy(outfile, file);
+    strcat(outfile, GZ_SUFFIX);
+#endif
+
+    in = fopen(file, "rb");
+    if (in == NULL) {
+        perror(file);
+        exit(1);
+    }
+    out = gzopen(outfile, mode);
+    if (out == NULL) {
+        fprintf(stderr, "%s: can't gzopen %s\n", prog, outfile);
+        exit(1);
+    }
+    gz_compress(in, out);
+
+    unlink(file);
+}
+
+
+/* ===========================================================================
+ * Uncompress the given file and remove the original.
+ */
+void file_uncompress(file)
+    char  *file;
+{
+    local char buf[MAX_NAME_LEN];
+    char *infile, *outfile;
+    FILE  *out;
+    gzFile in;
+    size_t len = strlen(file);
+
+    if (len + strlen(GZ_SUFFIX) >= sizeof(buf)) {
+        fprintf(stderr, "%s: filename too long\n", prog);
+        exit(1);
+    }
+
+#if !defined(NO_snprintf) && !defined(NO_vsnprintf)
+    snprintf(buf, sizeof(buf), "%s", file);
+#else
+    strcpy(buf, file);
+#endif
+
+    if (len > SUFFIX_LEN && strcmp(file+len-SUFFIX_LEN, GZ_SUFFIX) == 0) {
+        infile = file;
+        outfile = buf;
+        outfile[len-3] = '\0';
+    } else {
+        outfile = file;
+        infile = buf;
+#if !defined(NO_snprintf) && !defined(NO_vsnprintf)
+        snprintf(buf + len, sizeof(buf) - len, "%s", GZ_SUFFIX);
+#else
+        strcat(infile, GZ_SUFFIX);
+#endif
+    }
+    in = gzopen(infile, "rb");
+    if (in == NULL) {
+        fprintf(stderr, "%s: can't gzopen %s\n", prog, infile);
+        exit(1);
+    }
+    out = fopen(outfile, "wb");
+    if (out == NULL) {
+        perror(file);
+        exit(1);
+    }
+
+    gz_uncompress(in, out);
+
+    unlink(infile);
+}
+
+
+/* ===========================================================================
+ * Usage:  minigzip [-c] [-d] [-f] [-h] [-r] [-1 to -9] [files...]
+ *   -c : write to standard output
+ *   -d : decompress
+ *   -f : compress with Z_FILTERED
+ *   -h : compress with Z_HUFFMAN_ONLY
+ *   -r : compress with Z_RLE
+ *   -1 to -9 : compression level
+ */
+
+int main(argc, argv)
+    int argc;
+    char *argv[];
+{
+    int copyout = 0;
+    int uncompr = 0;
+    gzFile file;
+    char *bname, outmode[20];
+
+#if !defined(NO_snprintf) && !defined(NO_vsnprintf)
+    snprintf(outmode, sizeof(outmode), "%s", "wb6 ");
+#else
+    strcpy(outmode, "wb6 ");
+#endif
+
+    prog = argv[0];
+    bname = strrchr(argv[0], '/');
+    if (bname)
+      bname++;
+    else
+      bname = argv[0];
+    argc--, argv++;
+
+    if (!strcmp(bname, "gunzip"))
+      uncompr = 1;
+    else if (!strcmp(bname, "zcat"))
+      copyout = uncompr = 1;
+
+    while (argc > 0) {
+      if (strcmp(*argv, "-c") == 0)
+        copyout = 1;
+      else if (strcmp(*argv, "-d") == 0)
+        uncompr = 1;
+      else if (strcmp(*argv, "-f") == 0)
+        outmode[3] = 'f';
+      else if (strcmp(*argv, "-h") == 0)
+        outmode[3] = 'h';
+      else if (strcmp(*argv, "-r") == 0)
+        outmode[3] = 'R';
+      else if ((*argv)[0] == '-' && (*argv)[1] >= '1' && (*argv)[1] <= '9' &&
+               (*argv)[2] == 0)
+        outmode[2] = (*argv)[1];
+      else
+        break;
+      argc--, argv++;
+    }
+    if (outmode[3] == ' ')
+        outmode[3] = 0;
+    if (argc == 0) {
+        SET_BINARY_MODE(stdin);
+        SET_BINARY_MODE(stdout);
+        if (uncompr) {
+            file = gzdopen(fileno(stdin), "rb");
+            if (file == NULL) error("can't gzdopen stdin");
+            gz_uncompress(file, stdout);
+        } else {
+            file = gzdopen(fileno(stdout), outmode);
+            if (file == NULL) error("can't gzdopen stdout");
+            gz_compress(stdin, file);
+        }
+    } else {
+        if (copyout) {
+            SET_BINARY_MODE(stdout);
+        }
+        do {
+            if (uncompr) {
+                if (copyout) {
+                    file = gzopen(*argv, "rb");
+                    if (file == NULL)
+                        fprintf(stderr, "%s: can't gzopen %s\n", prog, *argv);
+                    else
+                        gz_uncompress(file, stdout);
+                } else {
+                    file_uncompress(*argv);
+                }
+            } else {
+                if (copyout) {
+                    FILE * in = fopen(*argv, "rb");
+
+                    if (in == NULL) {
+                        perror(*argv);
+                    } else {
+                        file = gzdopen(fileno(stdout), outmode);
+                        if (file == NULL) error("can't gzdopen stdout");
+
+                        gz_compress(in, file);
+                    }
+
+                } else {
+                    file_compress(*argv, outmode);
+                }
+            }
+        } while (argv++, --argc);
+    }
+    return 0;
+}
diff --git a/compat/zlib/treebuild.xml b/compat/zlib/treebuild.xml
new file mode 100644
index 0000000..38d29d7
--- /dev/null
+++ b/compat/zlib/treebuild.xml
@@ -0,0 +1,116 @@
+<?xml version="1.0" ?>
+<package name="zlib" version="1.2.8">
+    <library name="zlib" dlversion="1.2.8" dlname="z">
+	<property name="description"> zip compression library </property>
+	<property name="include-target-dir" value="$(@PACKAGE/install-includedir)" />
+
+	<!-- fixme: not implemented yet -->
+	<property name="compiler/c/inline" value="yes" />
+
+	<include-file name="zlib.h" scope="public" mode="644" />
+	<include-file name="zconf.h" scope="public" mode="644" />
+
+	<source name="adler32.c">
+	    <depend name="zlib.h" />
+	    <depend name="zconf.h" />
+	</source>
+	<source name="compress.c">
+	    <depend name="zlib.h" />
+	    <depend name="zconf.h" />
+	</source>
+	<source name="crc32.c">
+	    <depend name="zlib.h" />
+	    <depend name="zconf.h" />
+	    <depend name="crc32.h" />
+	</source>
+	<source name="gzclose.c">
+	    <depend name="zlib.h" />
+	    <depend name="zconf.h" />
+	    <depend name="gzguts.h" />
+	</source>
+	<source name="gzlib.c">
+	    <depend name="zlib.h" />
+	    <depend name="zconf.h" />
+	    <depend name="gzguts.h" />
+	</source>
+	<source name="gzread.c">
+	    <depend name="zlib.h" />
+	    <depend name="zconf.h" />
+	    <depend name="gzguts.h" />
+	</source>
+	<source name="gzwrite.c">
+	    <depend name="zlib.h" />
+	    <depend name="zconf.h" />
+	    <depend name="gzguts.h" />
+	</source>
+	<source name="uncompr.c">
+	    <depend name="zlib.h" />
+	    <depend name="zconf.h" />
+	</source>
+	<source name="deflate.c">
+	    <depend name="zlib.h" />
+	    <depend name="zconf.h" />
+	    <depend name="zutil.h" />
+	    <depend name="deflate.h" />
+	</source>
+	<source name="trees.c">
+	    <depend name="zlib.h" />
+	    <depend name="zconf.h" />
+	    <depend name="zutil.h" />
+	    <depend name="deflate.h" />
+	    <depend name="trees.h" />
+	</source>
+	<source name="zutil.c">
+	    <depend name="zlib.h" />
+	    <depend name="zconf.h" />
+	    <depend name="zutil.h" />
+	</source>
+	<source name="inflate.c">
+	    <depend name="zlib.h" />
+	    <depend name="zconf.h" />
+	    <depend name="zutil.h" />
+	    <depend name="inftrees.h" />
+	    <depend name="inflate.h" />
+	    <depend name="inffast.h" />
+	</source>
+	<source name="infback.c">
+	    <depend name="zlib.h" />
+	    <depend name="zconf.h" />
+	    <depend name="zutil.h" />
+	    <depend name="inftrees.h" />
+	    <depend name="inflate.h" />
+	    <depend name="inffast.h" />
+	</source>
+	<source name="inftrees.c">
+	    <depend name="zlib.h" />
+	    <depend name="zconf.h" />
+	    <depend name="zutil.h" />
+	    <depend name="inftrees.h" />
+	</source>
+	<source name="inffast.c">
+	    <depend name="zlib.h" />
+	    <depend name="zconf.h" />
+	    <depend name="zutil.h" />
+	    <depend name="inftrees.h" />
+	    <depend name="inflate.h" />
+	    <depend name="inffast.h" />
+	</source>
+    </library>
+</package>
+
+<!--
+CFLAGS=-O
+#CFLAGS=-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7
+#CFLAGS=-g -DDEBUG
+#CFLAGS=-O3 -Wall -Wwrite-strings -Wpointer-arith -Wconversion \
+#           -Wstrict-prototypes -Wmissing-prototypes
+
+# OBJA =
+# to use the asm code: make OBJA=match.o
+#
+match.o: match.S
+	$(CPP) match.S > _match.s
+	$(CC) -c _match.s
+	mv _match.o match.o
+	rm -f _match.s
+-->
diff --git a/compat/zlib/trees.c b/compat/zlib/trees.c
new file mode 100644
index 0000000..1fd7759
--- /dev/null
+++ b/compat/zlib/trees.c
@@ -0,0 +1,1226 @@
+/* trees.c -- output deflated data using Huffman coding
+ * Copyright (C) 1995-2012 Jean-loup Gailly
+ * detect_data_type() function provided freely by Cosmin Truta, 2006
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/*
+ *  ALGORITHM
+ *
+ *      The "deflation" process uses several Huffman trees. The more
+ *      common source values are represented by shorter bit sequences.
+ *
+ *      Each code tree is stored in a compressed form which is itself
+ * a Huffman encoding of the lengths of all the code strings (in
+ * ascending order by source values).  The actual code strings are
+ * reconstructed from the lengths in the inflate process, as described
+ * in the deflate specification.
+ *
+ *  REFERENCES
+ *
+ *      Deutsch, L.P.,"'Deflate' Compressed Data Format Specification".
+ *      Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc
+ *
+ *      Storer, James A.
+ *          Data Compression:  Methods and Theory, pp. 49-50.
+ *          Computer Science Press, 1988.  ISBN 0-7167-8156-5.
+ *
+ *      Sedgewick, R.
+ *          Algorithms, p290.
+ *          Addison-Wesley, 1983. ISBN 0-201-06672-6.
+ */
+
+/* @(#) $Id$ */
+
+/* #define GEN_TREES_H */
+
+#include "deflate.h"
+
+#ifdef DEBUG
+#  include <ctype.h>
+#endif
+
+/* ===========================================================================
+ * Constants
+ */
+
+#define MAX_BL_BITS 7
+/* Bit length codes must not exceed MAX_BL_BITS bits */
+
+#define END_BLOCK 256
+/* end of block literal code */
+
+#define REP_3_6      16
+/* repeat previous bit length 3-6 times (2 bits of repeat count) */
+
+#define REPZ_3_10    17
+/* repeat a zero length 3-10 times  (3 bits of repeat count) */
+
+#define REPZ_11_138  18
+/* repeat a zero length 11-138 times  (7 bits of repeat count) */
+
+local const int extra_lbits[LENGTH_CODES] /* extra bits for each length code */
+   = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0};
+
+local const int extra_dbits[D_CODES] /* extra bits for each distance code */
+   = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13};
+
+local const int extra_blbits[BL_CODES]/* extra bits for each bit length code */
+   = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7};
+
+local const uch bl_order[BL_CODES]
+   = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15};
+/* The lengths of the bit length codes are sent in order of decreasing
+ * probability, to avoid transmitting the lengths for unused bit length codes.
+ */
+
+/* ===========================================================================
+ * Local data. These are initialized only once.
+ */
+
+#define DIST_CODE_LEN  512 /* see definition of array dist_code below */
+
+#if defined(GEN_TREES_H) || !defined(STDC)
+/* non ANSI compilers may not accept trees.h */
+
+local ct_data static_ltree[L_CODES+2];
+/* The static literal tree. Since the bit lengths are imposed, there is no
+ * need for the L_CODES extra codes used during heap construction. However
+ * The codes 286 and 287 are needed to build a canonical tree (see _tr_init
+ * below).
+ */
+
+local ct_data static_dtree[D_CODES];
+/* The static distance tree. (Actually a trivial tree since all codes use
+ * 5 bits.)
+ */
+
+uch _dist_code[DIST_CODE_LEN];
+/* Distance codes. The first 256 values correspond to the distances
+ * 3 .. 258, the last 256 values correspond to the top 8 bits of
+ * the 15 bit distances.
+ */
+
+uch _length_code[MAX_MATCH-MIN_MATCH+1];
+/* length code for each normalized match length (0 == MIN_MATCH) */
+
+local int base_length[LENGTH_CODES];
+/* First normalized length for each code (0 = MIN_MATCH) */
+
+local int base_dist[D_CODES];
+/* First normalized distance for each code (0 = distance of 1) */
+
+#else
+#  include "trees.h"
+#endif /* GEN_TREES_H */
+
+struct static_tree_desc_s {
+    const ct_data *static_tree;  /* static tree or NULL */
+    const intf *extra_bits;      /* extra bits for each code or NULL */
+    int     extra_base;          /* base index for extra_bits */
+    int     elems;               /* max number of elements in the tree */
+    int     max_length;          /* max bit length for the codes */
+};
+
+local static_tree_desc  static_l_desc =
+{static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS};
+
+local static_tree_desc  static_d_desc =
+{static_dtree, extra_dbits, 0,          D_CODES, MAX_BITS};
+
+local static_tree_desc  static_bl_desc =
+{(const ct_data *)0, extra_blbits, 0,   BL_CODES, MAX_BL_BITS};
+
+/* ===========================================================================
+ * Local (static) routines in this file.
+ */
+
+local void tr_static_init OF((void));
+local void init_block     OF((deflate_state *s));
+local void pqdownheap     OF((deflate_state *s, ct_data *tree, int k));
+local void gen_bitlen     OF((deflate_state *s, tree_desc *desc));
+local void gen_codes      OF((ct_data *tree, int max_code, ushf *bl_count));
+local void build_tree     OF((deflate_state *s, tree_desc *desc));
+local void scan_tree      OF((deflate_state *s, ct_data *tree, int max_code));
+local void send_tree      OF((deflate_state *s, ct_data *tree, int max_code));
+local int  build_bl_tree  OF((deflate_state *s));
+local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes,
+                              int blcodes));
+local void compress_block OF((deflate_state *s, const ct_data *ltree,
+                              const ct_data *dtree));
+local int  detect_data_type OF((deflate_state *s));
+local unsigned bi_reverse OF((unsigned value, int length));
+local void bi_windup      OF((deflate_state *s));
+local void bi_flush       OF((deflate_state *s));
+local void copy_block     OF((deflate_state *s, charf *buf, unsigned len,
+                              int header));
+
+#ifdef GEN_TREES_H
+local void gen_trees_header OF((void));
+#endif
+
+#ifndef DEBUG
+#  define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len)
+   /* Send a code of the given tree. c and tree must not have side effects */
+
+#else /* DEBUG */
+#  define send_code(s, c, tree) \
+     { if (z_verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \
+       send_bits(s, tree[c].Code, tree[c].Len); }
+#endif
+
+/* ===========================================================================
+ * Output a short LSB first on the stream.
+ * IN assertion: there is enough room in pendingBuf.
+ */
+#define put_short(s, w) { \
+    put_byte(s, (uch)((w) & 0xff)); \
+    put_byte(s, (uch)((ush)(w) >> 8)); \
+}
+
+/* ===========================================================================
+ * Send a value on a given number of bits.
+ * IN assertion: length <= 16 and value fits in length bits.
+ */
+#ifdef DEBUG
+local void send_bits      OF((deflate_state *s, int value, int length));
+
+local void send_bits(s, value, length)
+    deflate_state *s;
+    int value;  /* value to send */
+    int length; /* number of bits */
+{
+    Tracevv((stderr," l %2d v %4x ", length, value));
+    Assert(length > 0 && length <= 15, "invalid length");
+    s->bits_sent += (ulg)length;
+
+    /* If not enough room in bi_buf, use (valid) bits from bi_buf and
+     * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid))
+     * unused bits in value.
+     */
+    if (s->bi_valid > (int)Buf_size - length) {
+        s->bi_buf |= (ush)value << s->bi_valid;
+        put_short(s, s->bi_buf);
+        s->bi_buf = (ush)value >> (Buf_size - s->bi_valid);
+        s->bi_valid += length - Buf_size;
+    } else {
+        s->bi_buf |= (ush)value << s->bi_valid;
+        s->bi_valid += length;
+    }
+}
+#else /* !DEBUG */
+
+#define send_bits(s, value, length) \
+{ int len = length;\
+  if (s->bi_valid > (int)Buf_size - len) {\
+    int val = value;\
+    s->bi_buf |= (ush)val << s->bi_valid;\
+    put_short(s, s->bi_buf);\
+    s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\
+    s->bi_valid += len - Buf_size;\
+  } else {\
+    s->bi_buf |= (ush)(value) << s->bi_valid;\
+    s->bi_valid += len;\
+  }\
+}
+#endif /* DEBUG */
+
+
+/* the arguments must not have side effects */
+
+/* ===========================================================================
+ * Initialize the various 'constant' tables.
+ */
+local void tr_static_init()
+{
+#if defined(GEN_TREES_H) || !defined(STDC)
+    static int static_init_done = 0;
+    int n;        /* iterates over tree elements */
+    int bits;     /* bit counter */
+    int length;   /* length value */
+    int code;     /* code value */
+    int dist;     /* distance index */
+    ush bl_count[MAX_BITS+1];
+    /* number of codes at each bit length for an optimal tree */
+
+    if (static_init_done) return;
+
+    /* For some embedded targets, global variables are not initialized: */
+#ifdef NO_INIT_GLOBAL_POINTERS
+    static_l_desc.static_tree = static_ltree;
+    static_l_desc.extra_bits = extra_lbits;
+    static_d_desc.static_tree = static_dtree;
+    static_d_desc.extra_bits = extra_dbits;
+    static_bl_desc.extra_bits = extra_blbits;
+#endif
+
+    /* Initialize the mapping length (0..255) -> length code (0..28) */
+    length = 0;
+    for (code = 0; code < LENGTH_CODES-1; code++) {
+        base_length[code] = length;
+        for (n = 0; n < (1<<extra_lbits[code]); n++) {
+            _length_code[length++] = (uch)code;
+        }
+    }
+    Assert (length == 256, "tr_static_init: length != 256");
+    /* Note that the length 255 (match length 258) can be represented
+     * in two different ways: code 284 + 5 bits or code 285, so we
+     * overwrite length_code[255] to use the best encoding:
+     */
+    _length_code[length-1] = (uch)code;
+
+    /* Initialize the mapping dist (0..32K) -> dist code (0..29) */
+    dist = 0;
+    for (code = 0 ; code < 16; code++) {
+        base_dist[code] = dist;
+        for (n = 0; n < (1<<extra_dbits[code]); n++) {
+            _dist_code[dist++] = (uch)code;
+        }
+    }
+    Assert (dist == 256, "tr_static_init: dist != 256");
+    dist >>= 7; /* from now on, all distances are divided by 128 */
+    for ( ; code < D_CODES; code++) {
+        base_dist[code] = dist << 7;
+        for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) {
+            _dist_code[256 + dist++] = (uch)code;
+        }
+    }
+    Assert (dist == 256, "tr_static_init: 256+dist != 512");
+
+    /* Construct the codes of the static literal tree */
+    for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0;
+    n = 0;
+    while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++;
+    while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++;
+    while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++;
+    while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++;
+    /* Codes 286 and 287 do not exist, but we must include them in the
+     * tree construction to get a canonical Huffman tree (longest code
+     * all ones)
+     */
+    gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count);
+
+    /* The static distance tree is trivial: */
+    for (n = 0; n < D_CODES; n++) {
+        static_dtree[n].Len = 5;
+        static_dtree[n].Code = bi_reverse((unsigned)n, 5);
+    }
+    static_init_done = 1;
+
+#  ifdef GEN_TREES_H
+    gen_trees_header();
+#  endif
+#endif /* defined(GEN_TREES_H) || !defined(STDC) */
+}
+
+/* ===========================================================================
+ * Genererate the file trees.h describing the static trees.
+ */
+#ifdef GEN_TREES_H
+#  ifndef DEBUG
+#    include <stdio.h>
+#  endif
+
+#  define SEPARATOR(i, last, width) \
+      ((i) == (last)? "\n};\n\n" :    \
+       ((i) % (width) == (width)-1 ? ",\n" : ", "))
+
+void gen_trees_header()
+{
+    FILE *header = fopen("trees.h", "w");
+    int i;
+
+    Assert (header != NULL, "Can't open trees.h");
+    fprintf(header,
+            "/* header created automatically with -DGEN_TREES_H */\n\n");
+
+    fprintf(header, "local const ct_data static_ltree[L_CODES+2] = {\n");
+    for (i = 0; i < L_CODES+2; i++) {
+        fprintf(header, "{{%3u},{%3u}}%s", static_ltree[i].Code,
+                static_ltree[i].Len, SEPARATOR(i, L_CODES+1, 5));
+    }
+
+    fprintf(header, "local const ct_data static_dtree[D_CODES] = {\n");
+    for (i = 0; i < D_CODES; i++) {
+        fprintf(header, "{{%2u},{%2u}}%s", static_dtree[i].Code,
+                static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5));
+    }
+
+    fprintf(header, "const uch ZLIB_INTERNAL _dist_code[DIST_CODE_LEN] = {\n");
+    for (i = 0; i < DIST_CODE_LEN; i++) {
+        fprintf(header, "%2u%s", _dist_code[i],
+                SEPARATOR(i, DIST_CODE_LEN-1, 20));
+    }
+
+    fprintf(header,
+        "const uch ZLIB_INTERNAL _length_code[MAX_MATCH-MIN_MATCH+1]= {\n");
+    for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) {
+        fprintf(header, "%2u%s", _length_code[i],
+                SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20));
+    }
+
+    fprintf(header, "local const int base_length[LENGTH_CODES] = {\n");
+    for (i = 0; i < LENGTH_CODES; i++) {
+        fprintf(header, "%1u%s", base_length[i],
+                SEPARATOR(i, LENGTH_CODES-1, 20));
+    }
+
+    fprintf(header, "local const int base_dist[D_CODES] = {\n");
+    for (i = 0; i < D_CODES; i++) {
+        fprintf(header, "%5u%s", base_dist[i],
+                SEPARATOR(i, D_CODES-1, 10));
+    }
+
+    fclose(header);
+}
+#endif /* GEN_TREES_H */
+
+/* ===========================================================================
+ * Initialize the tree data structures for a new zlib stream.
+ */
+void ZLIB_INTERNAL _tr_init(s)
+    deflate_state *s;
+{
+    tr_static_init();
+
+    s->l_desc.dyn_tree = s->dyn_ltree;
+    s->l_desc.stat_desc = &static_l_desc;
+
+    s->d_desc.dyn_tree = s->dyn_dtree;
+    s->d_desc.stat_desc = &static_d_desc;
+
+    s->bl_desc.dyn_tree = s->bl_tree;
+    s->bl_desc.stat_desc = &static_bl_desc;
+
+    s->bi_buf = 0;
+    s->bi_valid = 0;
+#ifdef DEBUG
+    s->compressed_len = 0L;
+    s->bits_sent = 0L;
+#endif
+
+    /* Initialize the first block of the first file: */
+    init_block(s);
+}
+
+/* ===========================================================================
+ * Initialize a new block.
+ */
+local void init_block(s)
+    deflate_state *s;
+{
+    int n; /* iterates over tree elements */
+
+    /* Initialize the trees. */
+    for (n = 0; n < L_CODES;  n++) s->dyn_ltree[n].Freq = 0;
+    for (n = 0; n < D_CODES;  n++) s->dyn_dtree[n].Freq = 0;
+    for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0;
+
+    s->dyn_ltree[END_BLOCK].Freq = 1;
+    s->opt_len = s->static_len = 0L;
+    s->last_lit = s->matches = 0;
+}
+
+#define SMALLEST 1
+/* Index within the heap array of least frequent node in the Huffman tree */
+
+
+/* ===========================================================================
+ * Remove the smallest element from the heap and recreate the heap with
+ * one less element. Updates heap and heap_len.
+ */
+#define pqremove(s, tree, top) \
+{\
+    top = s->heap[SMALLEST]; \
+    s->heap[SMALLEST] = s->heap[s->heap_len--]; \
+    pqdownheap(s, tree, SMALLEST); \
+}
+
+/* ===========================================================================
+ * Compares to subtrees, using the tree depth as tie breaker when
+ * the subtrees have equal frequency. This minimizes the worst case length.
+ */
+#define smaller(tree, n, m, depth) \
+   (tree[n].Freq < tree[m].Freq || \
+   (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m]))
+
+/* ===========================================================================
+ * Restore the heap property by moving down the tree starting at node k,
+ * exchanging a node with the smallest of its two sons if necessary, stopping
+ * when the heap property is re-established (each father smaller than its
+ * two sons).
+ */
+local void pqdownheap(s, tree, k)
+    deflate_state *s;
+    ct_data *tree;  /* the tree to restore */
+    int k;               /* node to move down */
+{
+    int v = s->heap[k];
+    int j = k << 1;  /* left son of k */
+    while (j <= s->heap_len) {
+        /* Set j to the smallest of the two sons: */
+        if (j < s->heap_len &&
+            smaller(tree, s->heap[j+1], s->heap[j], s->depth)) {
+            j++;
+        }
+        /* Exit if v is smaller than both sons */
+        if (smaller(tree, v, s->heap[j], s->depth)) break;
+
+        /* Exchange v with the smallest son */
+        s->heap[k] = s->heap[j];  k = j;
+
+        /* And continue down the tree, setting j to the left son of k */
+        j <<= 1;
+    }
+    s->heap[k] = v;
+}
+
+/* ===========================================================================
+ * Compute the optimal bit lengths for a tree and update the total bit length
+ * for the current block.
+ * IN assertion: the fields freq and dad are set, heap[heap_max] and
+ *    above are the tree nodes sorted by increasing frequency.
+ * OUT assertions: the field len is set to the optimal bit length, the
+ *     array bl_count contains the frequencies for each bit length.
+ *     The length opt_len is updated; static_len is also updated if stree is
+ *     not null.
+ */
+local void gen_bitlen(s, desc)
+    deflate_state *s;
+    tree_desc *desc;    /* the tree descriptor */
+{
+    ct_data *tree        = desc->dyn_tree;
+    int max_code         = desc->max_code;
+    const ct_data *stree = desc->stat_desc->static_tree;
+    const intf *extra    = desc->stat_desc->extra_bits;
+    int base             = desc->stat_desc->extra_base;
+    int max_length       = desc->stat_desc->max_length;
+    int h;              /* heap index */
+    int n, m;           /* iterate over the tree elements */
+    int bits;           /* bit length */
+    int xbits;          /* extra bits */
+    ush f;              /* frequency */
+    int overflow = 0;   /* number of elements with bit length too large */
+
+    for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0;
+
+    /* In a first pass, compute the optimal bit lengths (which may
+     * overflow in the case of the bit length tree).
+     */
+    tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */
+
+    for (h = s->heap_max+1; h < HEAP_SIZE; h++) {
+        n = s->heap[h];
+        bits = tree[tree[n].Dad].Len + 1;
+        if (bits > max_length) bits = max_length, overflow++;
+        tree[n].Len = (ush)bits;
+        /* We overwrite tree[n].Dad which is no longer needed */
+
+        if (n > max_code) continue; /* not a leaf node */
+
+        s->bl_count[bits]++;
+        xbits = 0;
+        if (n >= base) xbits = extra[n-base];
+        f = tree[n].Freq;
+        s->opt_len += (ulg)f * (bits + xbits);
+        if (stree) s->static_len += (ulg)f * (stree[n].Len + xbits);
+    }
+    if (overflow == 0) return;
+
+    Trace((stderr,"\nbit length overflow\n"));
+    /* This happens for example on obj2 and pic of the Calgary corpus */
+
+    /* Find the first bit length which could increase: */
+    do {
+        bits = max_length-1;
+        while (s->bl_count[bits] == 0) bits--;
+        s->bl_count[bits]--;      /* move one leaf down the tree */
+        s->bl_count[bits+1] += 2; /* move one overflow item as its brother */
+        s->bl_count[max_length]--;
+        /* The brother of the overflow item also moves one step up,
+         * but this does not affect bl_count[max_length]
+         */
+        overflow -= 2;
+    } while (overflow > 0);
+
+    /* Now recompute all bit lengths, scanning in increasing frequency.
+     * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all
+     * lengths instead of fixing only the wrong ones. This idea is taken
+     * from 'ar' written by Haruhiko Okumura.)
+     */
+    for (bits = max_length; bits != 0; bits--) {
+        n = s->bl_count[bits];
+        while (n != 0) {
+            m = s->heap[--h];
+            if (m > max_code) continue;
+            if ((unsigned) tree[m].Len != (unsigned) bits) {
+                Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits));
+                s->opt_len += ((long)bits - (long)tree[m].Len)
+                              *(long)tree[m].Freq;
+                tree[m].Len = (ush)bits;
+            }
+            n--;
+        }
+    }
+}
+
+/* ===========================================================================
+ * Generate the codes for a given tree and bit counts (which need not be
+ * optimal).
+ * IN assertion: the array bl_count contains the bit length statistics for
+ * the given tree and the field len is set for all tree elements.
+ * OUT assertion: the field code is set for all tree elements of non
+ *     zero code length.
+ */
+local void gen_codes (tree, max_code, bl_count)
+    ct_data *tree;             /* the tree to decorate */
+    int max_code;              /* largest code with non zero frequency */
+    ushf *bl_count;            /* number of codes at each bit length */
+{
+    ush next_code[MAX_BITS+1]; /* next code value for each bit length */
+    ush code = 0;              /* running code value */
+    int bits;                  /* bit index */
+    int n;                     /* code index */
+
+    /* The distribution counts are first used to generate the code values
+     * without bit reversal.
+     */
+    for (bits = 1; bits <= MAX_BITS; bits++) {
+        next_code[bits] = code = (code + bl_count[bits-1]) << 1;
+    }
+    /* Check that the bit counts in bl_count are consistent. The last code
+     * must be all ones.
+     */
+    Assert (code + bl_count[MAX_BITS]-1 == (1<<MAX_BITS)-1,
+            "inconsistent bit counts");
+    Tracev((stderr,"\ngen_codes: max_code %d ", max_code));
+
+    for (n = 0;  n <= max_code; n++) {
+        int len = tree[n].Len;
+        if (len == 0) continue;
+        /* Now reverse the bits */
+        tree[n].Code = bi_reverse(next_code[len]++, len);
+
+        Tracecv(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ",
+             n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len]-1));
+    }
+}
+
+/* ===========================================================================
+ * Construct one Huffman tree and assigns the code bit strings and lengths.
+ * Update the total bit length for the current block.
+ * IN assertion: the field freq is set for all tree elements.
+ * OUT assertions: the fields len and code are set to the optimal bit length
+ *     and corresponding code. The length opt_len is updated; static_len is
+ *     also updated if stree is not null. The field max_code is set.
+ */
+local void build_tree(s, desc)
+    deflate_state *s;
+    tree_desc *desc; /* the tree descriptor */
+{
+    ct_data *tree         = desc->dyn_tree;
+    const ct_data *stree  = desc->stat_desc->static_tree;
+    int elems             = desc->stat_desc->elems;
+    int n, m;          /* iterate over heap elements */
+    int max_code = -1; /* largest code with non zero frequency */
+    int node;          /* new node being created */
+
+    /* Construct the initial heap, with least frequent element in
+     * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1].
+     * heap[0] is not used.
+     */
+    s->heap_len = 0, s->heap_max = HEAP_SIZE;
+
+    for (n = 0; n < elems; n++) {
+        if (tree[n].Freq != 0) {
+            s->heap[++(s->heap_len)] = max_code = n;
+            s->depth[n] = 0;
+        } else {
+            tree[n].Len = 0;
+        }
+    }
+
+    /* The pkzip format requires that at least one distance code exists,
+     * and that at least one bit should be sent even if there is only one
+     * possible code. So to avoid special checks later on we force at least
+     * two codes of non zero frequency.
+     */
+    while (s->heap_len < 2) {
+        node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0);
+        tree[node].Freq = 1;
+        s->depth[node] = 0;
+        s->opt_len--; if (stree) s->static_len -= stree[node].Len;
+        /* node is 0 or 1 so it does not have extra bits */
+    }
+    desc->max_code = max_code;
+
+    /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree,
+     * establish sub-heaps of increasing lengths:
+     */
+    for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n);
+
+    /* Construct the Huffman tree by repeatedly combining the least two
+     * frequent nodes.
+     */
+    node = elems;              /* next internal node of the tree */
+    do {
+        pqremove(s, tree, n);  /* n = node of least frequency */
+        m = s->heap[SMALLEST]; /* m = node of next least frequency */
+
+        s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */
+        s->heap[--(s->heap_max)] = m;
+
+        /* Create a new node father of n and m */
+        tree[node].Freq = tree[n].Freq + tree[m].Freq;
+        s->depth[node] = (uch)((s->depth[n] >= s->depth[m] ?
+                                s->depth[n] : s->depth[m]) + 1);
+        tree[n].Dad = tree[m].Dad = (ush)node;
+#ifdef DUMP_BL_TREE
+        if (tree == s->bl_tree) {
+            fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)",
+                    node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq);
+        }
+#endif
+        /* and insert the new node in the heap */
+        s->heap[SMALLEST] = node++;
+        pqdownheap(s, tree, SMALLEST);
+
+    } while (s->heap_len >= 2);
+
+    s->heap[--(s->heap_max)] = s->heap[SMALLEST];
+
+    /* At this point, the fields freq and dad are set. We can now
+     * generate the bit lengths.
+     */
+    gen_bitlen(s, (tree_desc *)desc);
+
+    /* The field len is now set, we can generate the bit codes */
+    gen_codes ((ct_data *)tree, max_code, s->bl_count);
+}
+
+/* ===========================================================================
+ * Scan a literal or distance tree to determine the frequencies of the codes
+ * in the bit length tree.
+ */
+local void scan_tree (s, tree, max_code)
+    deflate_state *s;
+    ct_data *tree;   /* the tree to be scanned */
+    int max_code;    /* and its largest code of non zero frequency */
+{
+    int n;                     /* iterates over all tree elements */
+    int prevlen = -1;          /* last emitted length */
+    int curlen;                /* length of current code */
+    int nextlen = tree[0].Len; /* length of next code */
+    int count = 0;             /* repeat count of the current code */
+    int max_count = 7;         /* max repeat count */
+    int min_count = 4;         /* min repeat count */
+
+    if (nextlen == 0) max_count = 138, min_count = 3;
+    tree[max_code+1].Len = (ush)0xffff; /* guard */
+
+    for (n = 0; n <= max_code; n++) {
+        curlen = nextlen; nextlen = tree[n+1].Len;
+        if (++count < max_count && curlen == nextlen) {
+            continue;
+        } else if (count < min_count) {
+            s->bl_tree[curlen].Freq += count;
+        } else if (curlen != 0) {
+            if (curlen != prevlen) s->bl_tree[curlen].Freq++;
+            s->bl_tree[REP_3_6].Freq++;
+        } else if (count <= 10) {
+            s->bl_tree[REPZ_3_10].Freq++;
+        } else {
+            s->bl_tree[REPZ_11_138].Freq++;
+        }
+        count = 0; prevlen = curlen;
+        if (nextlen == 0) {
+            max_count = 138, min_count = 3;
+        } else if (curlen == nextlen) {
+            max_count = 6, min_count = 3;
+        } else {
+            max_count = 7, min_count = 4;
+        }
+    }
+}
+
+/* ===========================================================================
+ * Send a literal or distance tree in compressed form, using the codes in
+ * bl_tree.
+ */
+local void send_tree (s, tree, max_code)
+    deflate_state *s;
+    ct_data *tree; /* the tree to be scanned */
+    int max_code;       /* and its largest code of non zero frequency */
+{
+    int n;                     /* iterates over all tree elements */
+    int prevlen = -1;          /* last emitted length */
+    int curlen;                /* length of current code */
+    int nextlen = tree[0].Len; /* length of next code */
+    int count = 0;             /* repeat count of the current code */
+    int max_count = 7;         /* max repeat count */
+    int min_count = 4;         /* min repeat count */
+
+    /* tree[max_code+1].Len = -1; */  /* guard already set */
+    if (nextlen == 0) max_count = 138, min_count = 3;
+
+    for (n = 0; n <= max_code; n++) {
+        curlen = nextlen; nextlen = tree[n+1].Len;
+        if (++count < max_count && curlen == nextlen) {
+            continue;
+        } else if (count < min_count) {
+            do { send_code(s, curlen, s->bl_tree); } while (--count != 0);
+
+        } else if (curlen != 0) {
+            if (curlen != prevlen) {
+                send_code(s, curlen, s->bl_tree); count--;
+            }
+            Assert(count >= 3 && count <= 6, " 3_6?");
+            send_code(s, REP_3_6, s->bl_tree); send_bits(s, count-3, 2);
+
+        } else if (count <= 10) {
+            send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count-3, 3);
+
+        } else {
+            send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count-11, 7);
+        }
+        count = 0; prevlen = curlen;
+        if (nextlen == 0) {
+            max_count = 138, min_count = 3;
+        } else if (curlen == nextlen) {
+            max_count = 6, min_count = 3;
+        } else {
+            max_count = 7, min_count = 4;
+        }
+    }
+}
+
+/* ===========================================================================
+ * Construct the Huffman tree for the bit lengths and return the index in
+ * bl_order of the last bit length code to send.
+ */
+local int build_bl_tree(s)
+    deflate_state *s;
+{
+    int max_blindex;  /* index of last bit length code of non zero freq */
+
+    /* Determine the bit length frequencies for literal and distance trees */
+    scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code);
+    scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code);
+
+    /* Build the bit length tree: */
+    build_tree(s, (tree_desc *)(&(s->bl_desc)));
+    /* opt_len now includes the length of the tree representations, except
+     * the lengths of the bit lengths codes and the 5+5+4 bits for the counts.
+     */
+
+    /* Determine the number of bit length codes to send. The pkzip format
+     * requires that at least 4 bit length codes be sent. (appnote.txt says
+     * 3 but the actual value used is 4.)
+     */
+    for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) {
+        if (s->bl_tree[bl_order[max_blindex]].Len != 0) break;
+    }
+    /* Update opt_len to include the bit length tree and counts */
+    s->opt_len += 3*(max_blindex+1) + 5+5+4;
+    Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld",
+            s->opt_len, s->static_len));
+
+    return max_blindex;
+}
+
+/* ===========================================================================
+ * Send the header for a block using dynamic Huffman trees: the counts, the
+ * lengths of the bit length codes, the literal tree and the distance tree.
+ * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4.
+ */
+local void send_all_trees(s, lcodes, dcodes, blcodes)
+    deflate_state *s;
+    int lcodes, dcodes, blcodes; /* number of codes for each tree */
+{
+    int rank;                    /* index in bl_order */
+
+    Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes");
+    Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES,
+            "too many codes");
+    Tracev((stderr, "\nbl counts: "));
+    send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */
+    send_bits(s, dcodes-1,   5);
+    send_bits(s, blcodes-4,  4); /* not -3 as stated in appnote.txt */
+    for (rank = 0; rank < blcodes; rank++) {
+        Tracev((stderr, "\nbl code %2d ", bl_order[rank]));
+        send_bits(s, s->bl_tree[bl_order[rank]].Len, 3);
+    }
+    Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent));
+
+    send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */
+    Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent));
+
+    send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */
+    Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent));
+}
+
+/* ===========================================================================
+ * Send a stored block
+ */
+void ZLIB_INTERNAL _tr_stored_block(s, buf, stored_len, last)
+    deflate_state *s;
+    charf *buf;       /* input block */
+    ulg stored_len;   /* length of input block */
+    int last;         /* one if this is the last block for a file */
+{
+    send_bits(s, (STORED_BLOCK<<1)+last, 3);    /* send block type */
+#ifdef DEBUG
+    s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L;
+    s->compressed_len += (stored_len + 4) << 3;
+#endif
+    copy_block(s, buf, (unsigned)stored_len, 1); /* with header */
+}
+
+/* ===========================================================================
+ * Flush the bits in the bit buffer to pending output (leaves at most 7 bits)
+ */
+void ZLIB_INTERNAL _tr_flush_bits(s)
+    deflate_state *s;
+{
+    bi_flush(s);
+}
+
+/* ===========================================================================
+ * Send one empty static block to give enough lookahead for inflate.
+ * This takes 10 bits, of which 7 may remain in the bit buffer.
+ */
+void ZLIB_INTERNAL _tr_align(s)
+    deflate_state *s;
+{
+    send_bits(s, STATIC_TREES<<1, 3);
+    send_code(s, END_BLOCK, static_ltree);
+#ifdef DEBUG
+    s->compressed_len += 10L; /* 3 for block type, 7 for EOB */
+#endif
+    bi_flush(s);
+}
+
+/* ===========================================================================
+ * Determine the best encoding for the current block: dynamic trees, static
+ * trees or store, and output the encoded block to the zip file.
+ */
+void ZLIB_INTERNAL _tr_flush_block(s, buf, stored_len, last)
+    deflate_state *s;
+    charf *buf;       /* input block, or NULL if too old */
+    ulg stored_len;   /* length of input block */
+    int last;         /* one if this is the last block for a file */
+{
+    ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */
+    int max_blindex = 0;  /* index of last bit length code of non zero freq */
+
+    /* Build the Huffman trees unless a stored block is forced */
+    if (s->level > 0) {
+
+        /* Check if the file is binary or text */
+        if (s->strm->data_type == Z_UNKNOWN)
+            s->strm->data_type = detect_data_type(s);
+
+        /* Construct the literal and distance trees */
+        build_tree(s, (tree_desc *)(&(s->l_desc)));
+        Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len,
+                s->static_len));
+
+        build_tree(s, (tree_desc *)(&(s->d_desc)));
+        Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len,
+                s->static_len));
+        /* At this point, opt_len and static_len are the total bit lengths of
+         * the compressed block data, excluding the tree representations.
+         */
+
+        /* Build the bit length tree for the above two trees, and get the index
+         * in bl_order of the last bit length code to send.
+         */
+        max_blindex = build_bl_tree(s);
+
+        /* Determine the best encoding. Compute the block lengths in bytes. */
+        opt_lenb = (s->opt_len+3+7)>>3;
+        static_lenb = (s->static_len+3+7)>>3;
+
+        Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ",
+                opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len,
+                s->last_lit));
+
+        if (static_lenb <= opt_lenb) opt_lenb = static_lenb;
+
+    } else {
+        Assert(buf != (char*)0, "lost buf");
+        opt_lenb = static_lenb = stored_len + 5; /* force a stored block */
+    }
+
+#ifdef FORCE_STORED
+    if (buf != (char*)0) { /* force stored block */
+#else
+    if (stored_len+4 <= opt_lenb && buf != (char*)0) {
+                       /* 4: two words for the lengths */
+#endif
+        /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE.
+         * Otherwise we can't have processed more than WSIZE input bytes since
+         * the last block flush, because compression would have been
+         * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to
+         * transform a block into a stored block.
+         */
+        _tr_stored_block(s, buf, stored_len, last);
+
+#ifdef FORCE_STATIC
+    } else if (static_lenb >= 0) { /* force static trees */
+#else
+    } else if (s->strategy == Z_FIXED || static_lenb == opt_lenb) {
+#endif
+        send_bits(s, (STATIC_TREES<<1)+last, 3);
+        compress_block(s, (const ct_data *)static_ltree,
+                       (const ct_data *)static_dtree);
+#ifdef DEBUG
+        s->compressed_len += 3 + s->static_len;
+#endif
+    } else {
+        send_bits(s, (DYN_TREES<<1)+last, 3);
+        send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1,
+                       max_blindex+1);
+        compress_block(s, (const ct_data *)s->dyn_ltree,
+                       (const ct_data *)s->dyn_dtree);
+#ifdef DEBUG
+        s->compressed_len += 3 + s->opt_len;
+#endif
+    }
+    Assert (s->compressed_len == s->bits_sent, "bad compressed size");
+    /* The above check is made mod 2^32, for files larger than 512 MB
+     * and uLong implemented on 32 bits.
+     */
+    init_block(s);
+
+    if (last) {
+        bi_windup(s);
+#ifdef DEBUG
+        s->compressed_len += 7;  /* align on byte boundary */
+#endif
+    }
+    Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3,
+           s->compressed_len-7*last));
+}
+
+/* ===========================================================================
+ * Save the match info and tally the frequency counts. Return true if
+ * the current block must be flushed.
+ */
+int ZLIB_INTERNAL _tr_tally (s, dist, lc)
+    deflate_state *s;
+    unsigned dist;  /* distance of matched string */
+    unsigned lc;    /* match length-MIN_MATCH or unmatched char (if dist==0) */
+{
+    s->d_buf[s->last_lit] = (ush)dist;
+    s->l_buf[s->last_lit++] = (uch)lc;
+    if (dist == 0) {
+        /* lc is the unmatched char */
+        s->dyn_ltree[lc].Freq++;
+    } else {
+        s->matches++;
+        /* Here, lc is the match length - MIN_MATCH */
+        dist--;             /* dist = match distance - 1 */
+        Assert((ush)dist < (ush)MAX_DIST(s) &&
+               (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) &&
+               (ush)d_code(dist) < (ush)D_CODES,  "_tr_tally: bad match");
+
+        s->dyn_ltree[_length_code[lc]+LITERALS+1].Freq++;
+        s->dyn_dtree[d_code(dist)].Freq++;
+    }
+
+#ifdef TRUNCATE_BLOCK
+    /* Try to guess if it is profitable to stop the current block here */
+    if ((s->last_lit & 0x1fff) == 0 && s->level > 2) {
+        /* Compute an upper bound for the compressed length */
+        ulg out_length = (ulg)s->last_lit*8L;
+        ulg in_length = (ulg)((long)s->strstart - s->block_start);
+        int dcode;
+        for (dcode = 0; dcode < D_CODES; dcode++) {
+            out_length += (ulg)s->dyn_dtree[dcode].Freq *
+                (5L+extra_dbits[dcode]);
+        }
+        out_length >>= 3;
+        Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ",
+               s->last_lit, in_length, out_length,
+               100L - out_length*100L/in_length));
+        if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1;
+    }
+#endif
+    return (s->last_lit == s->lit_bufsize-1);
+    /* We avoid equality with lit_bufsize because of wraparound at 64K
+     * on 16 bit machines and because stored blocks are restricted to
+     * 64K-1 bytes.
+     */
+}
+
+/* ===========================================================================
+ * Send the block data compressed using the given Huffman trees
+ */
+local void compress_block(s, ltree, dtree)
+    deflate_state *s;
+    const ct_data *ltree; /* literal tree */
+    const ct_data *dtree; /* distance tree */
+{
+    unsigned dist;      /* distance of matched string */
+    int lc;             /* match length or unmatched char (if dist == 0) */
+    unsigned lx = 0;    /* running index in l_buf */
+    unsigned code;      /* the code to send */
+    int extra;          /* number of extra bits to send */
+
+    if (s->last_lit != 0) do {
+        dist = s->d_buf[lx];
+        lc = s->l_buf[lx++];
+        if (dist == 0) {
+            send_code(s, lc, ltree); /* send a literal byte */
+            Tracecv(isgraph(lc), (stderr," '%c' ", lc));
+        } else {
+            /* Here, lc is the match length - MIN_MATCH */
+            code = _length_code[lc];
+            send_code(s, code+LITERALS+1, ltree); /* send the length code */
+            extra = extra_lbits[code];
+            if (extra != 0) {
+                lc -= base_length[code];
+                send_bits(s, lc, extra);       /* send the extra length bits */
+            }
+            dist--; /* dist is now the match distance - 1 */
+            code = d_code(dist);
+            Assert (code < D_CODES, "bad d_code");
+
+            send_code(s, code, dtree);       /* send the distance code */
+            extra = extra_dbits[code];
+            if (extra != 0) {
+                dist -= base_dist[code];
+                send_bits(s, dist, extra);   /* send the extra distance bits */
+            }
+        } /* literal or match pair ? */
+
+        /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */
+        Assert((uInt)(s->pending) < s->lit_bufsize + 2*lx,
+               "pendingBuf overflow");
+
+    } while (lx < s->last_lit);
+
+    send_code(s, END_BLOCK, ltree);
+}
+
+/* ===========================================================================
+ * Check if the data type is TEXT or BINARY, using the following algorithm:
+ * - TEXT if the two conditions below are satisfied:
+ *    a) There are no non-portable control characters belonging to the
+ *       "black list" (0..6, 14..25, 28..31).
+ *    b) There is at least one printable character belonging to the
+ *       "white list" (9 {TAB}, 10 {LF}, 13 {CR}, 32..255).
+ * - BINARY otherwise.
+ * - The following partially-portable control characters form a
+ *   "gray list" that is ignored in this detection algorithm:
+ *   (7 {BEL}, 8 {BS}, 11 {VT}, 12 {FF}, 26 {SUB}, 27 {ESC}).
+ * IN assertion: the fields Freq of dyn_ltree are set.
+ */
+local int detect_data_type(s)
+    deflate_state *s;
+{
+    /* black_mask is the bit mask of black-listed bytes
+     * set bits 0..6, 14..25, and 28..31
+     * 0xf3ffc07f = binary 11110011111111111100000001111111
+     */
+    unsigned long black_mask = 0xf3ffc07fUL;
+    int n;
+
+    /* Check for non-textual ("black-listed") bytes. */
+    for (n = 0; n <= 31; n++, black_mask >>= 1)
+        if ((black_mask & 1) && (s->dyn_ltree[n].Freq != 0))
+            return Z_BINARY;
+
+    /* Check for textual ("white-listed") bytes. */
+    if (s->dyn_ltree[9].Freq != 0 || s->dyn_ltree[10].Freq != 0
+            || s->dyn_ltree[13].Freq != 0)
+        return Z_TEXT;
+    for (n = 32; n < LITERALS; n++)
+        if (s->dyn_ltree[n].Freq != 0)
+            return Z_TEXT;
+
+    /* There are no "black-listed" or "white-listed" bytes:
+     * this stream either is empty or has tolerated ("gray-listed") bytes only.
+     */
+    return Z_BINARY;
+}
+
+/* ===========================================================================
+ * Reverse the first len bits of a code, using straightforward code (a faster
+ * method would use a table)
+ * IN assertion: 1 <= len <= 15
+ */
+local unsigned bi_reverse(code, len)
+    unsigned code; /* the value to invert */
+    int len;       /* its bit length */
+{
+    register unsigned res = 0;
+    do {
+        res |= code & 1;
+        code >>= 1, res <<= 1;
+    } while (--len > 0);
+    return res >> 1;
+}
+
+/* ===========================================================================
+ * Flush the bit buffer, keeping at most 7 bits in it.
+ */
+local void bi_flush(s)
+    deflate_state *s;
+{
+    if (s->bi_valid == 16) {
+        put_short(s, s->bi_buf);
+        s->bi_buf = 0;
+        s->bi_valid = 0;
+    } else if (s->bi_valid >= 8) {
+        put_byte(s, (Byte)s->bi_buf);
+        s->bi_buf >>= 8;
+        s->bi_valid -= 8;
+    }
+}
+
+/* ===========================================================================
+ * Flush the bit buffer and align the output on a byte boundary
+ */
+local void bi_windup(s)
+    deflate_state *s;
+{
+    if (s->bi_valid > 8) {
+        put_short(s, s->bi_buf);
+    } else if (s->bi_valid > 0) {
+        put_byte(s, (Byte)s->bi_buf);
+    }
+    s->bi_buf = 0;
+    s->bi_valid = 0;
+#ifdef DEBUG
+    s->bits_sent = (s->bits_sent+7) & ~7;
+#endif
+}
+
+/* ===========================================================================
+ * Copy a stored block, storing first the length and its
+ * one's complement if requested.
+ */
+local void copy_block(s, buf, len, header)
+    deflate_state *s;
+    charf    *buf;    /* the input data */
+    unsigned len;     /* its length */
+    int      header;  /* true if block header must be written */
+{
+    bi_windup(s);        /* align on byte boundary */
+
+    if (header) {
+        put_short(s, (ush)len);
+        put_short(s, (ush)~len);
+#ifdef DEBUG
+        s->bits_sent += 2*16;
+#endif
+    }
+#ifdef DEBUG
+    s->bits_sent += (ulg)len<<3;
+#endif
+    while (len--) {
+        put_byte(s, *buf++);
+    }
+}
diff --git a/compat/zlib/trees.h b/compat/zlib/trees.h
new file mode 100644
index 0000000..d35639d
--- /dev/null
+++ b/compat/zlib/trees.h
@@ -0,0 +1,128 @@
+/* header created automatically with -DGEN_TREES_H */
+
+local const ct_data static_ltree[L_CODES+2] = {
+{{ 12},{  8}}, {{140},{  8}}, {{ 76},{  8}}, {{204},{  8}}, {{ 44},{  8}},
+{{172},{  8}}, {{108},{  8}}, {{236},{  8}}, {{ 28},{  8}}, {{156},{  8}},
+{{ 92},{  8}}, {{220},{  8}}, {{ 60},{  8}}, {{188},{  8}}, {{124},{  8}},
+{{252},{  8}}, {{  2},{  8}}, {{130},{  8}}, {{ 66},{  8}}, {{194},{  8}},
+{{ 34},{  8}}, {{162},{  8}}, {{ 98},{  8}}, {{226},{  8}}, {{ 18},{  8}},
+{{146},{  8}}, {{ 82},{  8}}, {{210},{  8}}, {{ 50},{  8}}, {{178},{  8}},
+{{114},{  8}}, {{242},{  8}}, {{ 10},{  8}}, {{138},{  8}}, {{ 74},{  8}},
+{{202},{  8}}, {{ 42},{  8}}, {{170},{  8}}, {{106},{  8}}, {{234},{  8}},
+{{ 26},{  8}}, {{154},{  8}}, {{ 90},{  8}}, {{218},{  8}}, {{ 58},{  8}},
+{{186},{  8}}, {{122},{  8}}, {{250},{  8}}, {{  6},{  8}}, {{134},{  8}},
+{{ 70},{  8}}, {{198},{  8}}, {{ 38},{  8}}, {{166},{  8}}, {{102},{  8}},
+{{230},{  8}}, {{ 22},{  8}}, {{150},{  8}}, {{ 86},{  8}}, {{214},{  8}},
+{{ 54},{  8}}, {{182},{  8}}, {{118},{  8}}, {{246},{  8}}, {{ 14},{  8}},
+{{142},{  8}}, {{ 78},{  8}}, {{206},{  8}}, {{ 46},{  8}}, {{174},{  8}},
+{{110},{  8}}, {{238},{  8}}, {{ 30},{  8}}, {{158},{  8}}, {{ 94},{  8}},
+{{222},{  8}}, {{ 62},{  8}}, {{190},{  8}}, {{126},{  8}}, {{254},{  8}},
+{{  1},{  8}}, {{129},{  8}}, {{ 65},{  8}}, {{193},{  8}}, {{ 33},{  8}},
+{{161},{  8}}, {{ 97},{  8}}, {{225},{  8}}, {{ 17},{  8}}, {{145},{  8}},
+{{ 81},{  8}}, {{209},{  8}}, {{ 49},{  8}}, {{177},{  8}}, {{113},{  8}},
+{{241},{  8}}, {{  9},{  8}}, {{137},{  8}}, {{ 73},{  8}}, {{201},{  8}},
+{{ 41},{  8}}, {{169},{  8}}, {{105},{  8}}, {{233},{  8}}, {{ 25},{  8}},
+{{153},{  8}}, {{ 89},{  8}}, {{217},{  8}}, {{ 57},{  8}}, {{185},{  8}},
+{{121},{  8}}, {{249},{  8}}, {{  5},{  8}}, {{133},{  8}}, {{ 69},{  8}},
+{{197},{  8}}, {{ 37},{  8}}, {{165},{  8}}, {{101},{  8}}, {{229},{  8}},
+{{ 21},{  8}}, {{149},{  8}}, {{ 85},{  8}}, {{213},{  8}}, {{ 53},{  8}},
+{{181},{  8}}, {{117},{  8}}, {{245},{  8}}, {{ 13},{  8}}, {{141},{  8}},
+{{ 77},{  8}}, {{205},{  8}}, {{ 45},{  8}}, {{173},{  8}}, {{109},{  8}},
+{{237},{  8}}, {{ 29},{  8}}, {{157},{  8}}, {{ 93},{  8}}, {{221},{  8}},
+{{ 61},{  8}}, {{189},{  8}}, {{125},{  8}}, {{253},{  8}}, {{ 19},{  9}},
+{{275},{  9}}, {{147},{  9}}, {{403},{  9}}, {{ 83},{  9}}, {{339},{  9}},
+{{211},{  9}}, {{467},{  9}}, {{ 51},{  9}}, {{307},{  9}}, {{179},{  9}},
+{{435},{  9}}, {{115},{  9}}, {{371},{  9}}, {{243},{  9}}, {{499},{  9}},
+{{ 11},{  9}}, {{267},{  9}}, {{139},{  9}}, {{395},{  9}}, {{ 75},{  9}},
+{{331},{  9}}, {{203},{  9}}, {{459},{  9}}, {{ 43},{  9}}, {{299},{  9}},
+{{171},{  9}}, {{427},{  9}}, {{107},{  9}}, {{363},{  9}}, {{235},{  9}},
+{{491},{  9}}, {{ 27},{  9}}, {{283},{  9}}, {{155},{  9}}, {{411},{  9}},
+{{ 91},{  9}}, {{347},{  9}}, {{219},{  9}}, {{475},{  9}}, {{ 59},{  9}},
+{{315},{  9}}, {{187},{  9}}, {{443},{  9}}, {{123},{  9}}, {{379},{  9}},
+{{251},{  9}}, {{507},{  9}}, {{  7},{  9}}, {{263},{  9}}, {{135},{  9}},
+{{391},{  9}}, {{ 71},{  9}}, {{327},{  9}}, {{199},{  9}}, {{455},{  9}},
+{{ 39},{  9}}, {{295},{  9}}, {{167},{  9}}, {{423},{  9}}, {{103},{  9}},
+{{359},{  9}}, {{231},{  9}}, {{487},{  9}}, {{ 23},{  9}}, {{279},{  9}},
+{{151},{  9}}, {{407},{  9}}, {{ 87},{  9}}, {{343},{  9}}, {{215},{  9}},
+{{471},{  9}}, {{ 55},{  9}}, {{311},{  9}}, {{183},{  9}}, {{439},{  9}},
+{{119},{  9}}, {{375},{  9}}, {{247},{  9}}, {{503},{  9}}, {{ 15},{  9}},
+{{271},{  9}}, {{143},{  9}}, {{399},{  9}}, {{ 79},{  9}}, {{335},{  9}},
+{{207},{  9}}, {{463},{  9}}, {{ 47},{  9}}, {{303},{  9}}, {{175},{  9}},
+{{431},{  9}}, {{111},{  9}}, {{367},{  9}}, {{239},{  9}}, {{495},{  9}},
+{{ 31},{  9}}, {{287},{  9}}, {{159},{  9}}, {{415},{  9}}, {{ 95},{  9}},
+{{351},{  9}}, {{223},{  9}}, {{479},{  9}}, {{ 63},{  9}}, {{319},{  9}},
+{{191},{  9}}, {{447},{  9}}, {{127},{  9}}, {{383},{  9}}, {{255},{  9}},
+{{511},{  9}}, {{  0},{  7}}, {{ 64},{  7}}, {{ 32},{  7}}, {{ 96},{  7}},
+{{ 16},{  7}}, {{ 80},{  7}}, {{ 48},{  7}}, {{112},{  7}}, {{  8},{  7}},
+{{ 72},{  7}}, {{ 40},{  7}}, {{104},{  7}}, {{ 24},{  7}}, {{ 88},{  7}},
+{{ 56},{  7}}, {{120},{  7}}, {{  4},{  7}}, {{ 68},{  7}}, {{ 36},{  7}},
+{{100},{  7}}, {{ 20},{  7}}, {{ 84},{  7}}, {{ 52},{  7}}, {{116},{  7}},
+{{  3},{  8}}, {{131},{  8}}, {{ 67},{  8}}, {{195},{  8}}, {{ 35},{  8}},
+{{163},{  8}}, {{ 99},{  8}}, {{227},{  8}}
+};
+
+local const ct_data static_dtree[D_CODES] = {
+{{ 0},{ 5}}, {{16},{ 5}}, {{ 8},{ 5}}, {{24},{ 5}}, {{ 4},{ 5}},
+{{20},{ 5}}, {{12},{ 5}}, {{28},{ 5}}, {{ 2},{ 5}}, {{18},{ 5}},
+{{10},{ 5}}, {{26},{ 5}}, {{ 6},{ 5}}, {{22},{ 5}}, {{14},{ 5}},
+{{30},{ 5}}, {{ 1},{ 5}}, {{17},{ 5}}, {{ 9},{ 5}}, {{25},{ 5}},
+{{ 5},{ 5}}, {{21},{ 5}}, {{13},{ 5}}, {{29},{ 5}}, {{ 3},{ 5}},
+{{19},{ 5}}, {{11},{ 5}}, {{27},{ 5}}, {{ 7},{ 5}}, {{23},{ 5}}
+};
+
+const uch ZLIB_INTERNAL _dist_code[DIST_CODE_LEN] = {
+ 0,  1,  2,  3,  4,  4,  5,  5,  6,  6,  6,  6,  7,  7,  7,  7,  8,  8,  8,  8,
+ 8,  8,  8,  8,  9,  9,  9,  9,  9,  9,  9,  9, 10, 10, 10, 10, 10, 10, 10, 10,
+10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
+12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13,
+13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15,
+15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,  0,  0, 16, 17,
+18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22,
+23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
+26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27,
+27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
+27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
+28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
+28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
+28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
+29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
+29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
+29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29
+};
+
+const uch ZLIB_INTERNAL _length_code[MAX_MATCH-MIN_MATCH+1]= {
+ 0,  1,  2,  3,  4,  5,  6,  7,  8,  8,  9,  9, 10, 10, 11, 11, 12, 12, 12, 12,
+13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16,
+17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19,
+19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
+21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22,
+22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23,
+23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
+25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26,
+26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
+26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
+27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28
+};
+
+local const int base_length[LENGTH_CODES] = {
+0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56,
+64, 80, 96, 112, 128, 160, 192, 224, 0
+};
+
+local const int base_dist[D_CODES] = {
+    0,     1,     2,     3,     4,     6,     8,    12,    16,    24,
+   32,    48,    64,    96,   128,   192,   256,   384,   512,   768,
+ 1024,  1536,  2048,  3072,  4096,  6144,  8192, 12288, 16384, 24576
+};
+
diff --git a/compat/zlib/uncompr.c b/compat/zlib/uncompr.c
new file mode 100644
index 0000000..242e949
--- /dev/null
+++ b/compat/zlib/uncompr.c
@@ -0,0 +1,59 @@
+/* uncompr.c -- decompress a memory buffer
+ * Copyright (C) 1995-2003, 2010 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id$ */
+
+#define ZLIB_INTERNAL
+#include "zlib.h"
+
+/* ===========================================================================
+     Decompresses the source buffer into the destination buffer.  sourceLen is
+   the byte length of the source buffer. Upon entry, destLen is the total
+   size of the destination buffer, which must be large enough to hold the
+   entire uncompressed data. (The size of the uncompressed data must have
+   been saved previously by the compressor and transmitted to the decompressor
+   by some mechanism outside the scope of this compression library.)
+   Upon exit, destLen is the actual size of the compressed buffer.
+
+     uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
+   enough memory, Z_BUF_ERROR if there was not enough room in the output
+   buffer, or Z_DATA_ERROR if the input data was corrupted.
+*/
+int ZEXPORT uncompress (dest, destLen, source, sourceLen)
+    Bytef *dest;
+    uLongf *destLen;
+    const Bytef *source;
+    uLong sourceLen;
+{
+    z_stream stream;
+    int err;
+
+    stream.next_in = (z_const Bytef *)source;
+    stream.avail_in = (uInt)sourceLen;
+    /* Check for source > 64K on 16-bit machine: */
+    if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR;
+
+    stream.next_out = dest;
+    stream.avail_out = (uInt)*destLen;
+    if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR;
+
+    stream.zalloc = (alloc_func)0;
+    stream.zfree = (free_func)0;
+
+    err = inflateInit(&stream);
+    if (err != Z_OK) return err;
+
+    err = inflate(&stream, Z_FINISH);
+    if (err != Z_STREAM_END) {
+        inflateEnd(&stream);
+        if (err == Z_NEED_DICT || (err == Z_BUF_ERROR && stream.avail_in == 0))
+            return Z_DATA_ERROR;
+        return err;
+    }
+    *destLen = stream.total_out;
+
+    err = inflateEnd(&stream);
+    return err;
+}
diff --git a/compat/zlib/watcom/watcom_f.mak b/compat/zlib/watcom/watcom_f.mak
new file mode 100644
index 0000000..37f4d74
--- /dev/null
+++ b/compat/zlib/watcom/watcom_f.mak
@@ -0,0 +1,43 @@
+# Makefile for zlib
+# OpenWatcom flat model
+# Last updated: 28-Dec-2005
+
+# To use, do "wmake -f watcom_f.mak"
+
+C_SOURCE =  adler32.c  compress.c crc32.c   deflate.c    &
+	    gzclose.c  gzlib.c    gzread.c  gzwrite.c    &
+            infback.c  inffast.c  inflate.c inftrees.c   &
+            trees.c    uncompr.c  zutil.c
+
+OBJS =      adler32.obj  compress.obj crc32.obj   deflate.obj    &
+	    gzclose.obj  gzlib.obj    gzread.obj  gzwrite.obj    &
+            infback.obj  inffast.obj  inflate.obj inftrees.obj   &
+            trees.obj    uncompr.obj  zutil.obj
+
+CC       = wcc386
+LINKER   = wcl386
+CFLAGS   = -zq -mf -3r -fp3 -s -bt=dos -oilrtfm -fr=nul -wx
+ZLIB_LIB = zlib_f.lib
+
+.C.OBJ:
+        $(CC) $(CFLAGS) $[@
+
+all: $(ZLIB_LIB) example.exe minigzip.exe
+
+$(ZLIB_LIB): $(OBJS)
+	wlib -b -c $(ZLIB_LIB) -+adler32.obj  -+compress.obj -+crc32.obj
+	wlib -b -c $(ZLIB_LIB) -+gzclose.obj  -+gzlib.obj    -+gzread.obj   -+gzwrite.obj
+        wlib -b -c $(ZLIB_LIB) -+deflate.obj  -+infback.obj
+        wlib -b -c $(ZLIB_LIB) -+inffast.obj  -+inflate.obj  -+inftrees.obj
+        wlib -b -c $(ZLIB_LIB) -+trees.obj    -+uncompr.obj  -+zutil.obj
+
+example.exe: $(ZLIB_LIB) example.obj
+	$(LINKER) -ldos32a -fe=example.exe example.obj $(ZLIB_LIB)
+
+minigzip.exe: $(ZLIB_LIB) minigzip.obj
+	$(LINKER) -ldos32a -fe=minigzip.exe minigzip.obj $(ZLIB_LIB)
+
+clean: .SYMBOLIC
+          del *.obj
+          del $(ZLIB_LIB)
+          @echo Cleaning done
diff --git a/compat/zlib/watcom/watcom_l.mak b/compat/zlib/watcom/watcom_l.mak
new file mode 100644
index 0000000..193eed7
--- /dev/null
+++ b/compat/zlib/watcom/watcom_l.mak
@@ -0,0 +1,43 @@
+# Makefile for zlib
+# OpenWatcom large model
+# Last updated: 28-Dec-2005
+
+# To use, do "wmake -f watcom_l.mak"
+
+C_SOURCE =  adler32.c  compress.c crc32.c   deflate.c    &
+	    gzclose.c  gzlib.c    gzread.c  gzwrite.c    &
+            infback.c  inffast.c  inflate.c inftrees.c   &
+            trees.c    uncompr.c  zutil.c
+
+OBJS =      adler32.obj  compress.obj crc32.obj   deflate.obj    &
+	    gzclose.obj  gzlib.obj    gzread.obj  gzwrite.obj    &
+            infback.obj  inffast.obj  inflate.obj inftrees.obj   &
+            trees.obj    uncompr.obj  zutil.obj
+
+CC       = wcc
+LINKER   = wcl
+CFLAGS   = -zq -ml -s -bt=dos -oilrtfm -fr=nul -wx
+ZLIB_LIB = zlib_l.lib
+
+.C.OBJ:
+        $(CC) $(CFLAGS) $[@
+
+all: $(ZLIB_LIB) example.exe minigzip.exe
+
+$(ZLIB_LIB): $(OBJS)
+	wlib -b -c $(ZLIB_LIB) -+adler32.obj  -+compress.obj -+crc32.obj
+	wlib -b -c $(ZLIB_LIB) -+gzclose.obj  -+gzlib.obj    -+gzread.obj   -+gzwrite.obj
+        wlib -b -c $(ZLIB_LIB) -+deflate.obj  -+infback.obj
+        wlib -b -c $(ZLIB_LIB) -+inffast.obj  -+inflate.obj  -+inftrees.obj
+        wlib -b -c $(ZLIB_LIB) -+trees.obj    -+uncompr.obj  -+zutil.obj
+
+example.exe: $(ZLIB_LIB) example.obj
+	$(LINKER) -fe=example.exe example.obj $(ZLIB_LIB)
+
+minigzip.exe: $(ZLIB_LIB) minigzip.obj
+	$(LINKER) -fe=minigzip.exe minigzip.obj $(ZLIB_LIB)
+
+clean: .SYMBOLIC
+          del *.obj
+          del $(ZLIB_LIB)
+          @echo Cleaning done
diff --git a/compat/zlib/win32/DLL_FAQ.txt b/compat/zlib/win32/DLL_FAQ.txt
new file mode 100644
index 0000000..12c0090
--- /dev/null
+++ b/compat/zlib/win32/DLL_FAQ.txt
@@ -0,0 +1,397 @@
+
+            Frequently Asked Questions about ZLIB1.DLL
+
+
+This document describes the design, the rationale, and the usage
+of the official DLL build of zlib, named ZLIB1.DLL.  If you have
+general questions about zlib, you should see the file "FAQ" found
+in the zlib distribution, or at the following location:
+  http://www.gzip.org/zlib/zlib_faq.html
+
+
+ 1. What is ZLIB1.DLL, and how can I get it?
+
+  - ZLIB1.DLL is the official build of zlib as a DLL.
+    (Please remark the character '1' in the name.)
+
+    Pointers to a precompiled ZLIB1.DLL can be found in the zlib
+    web site at:
+      http://www.zlib.net/
+
+    Applications that link to ZLIB1.DLL can rely on the following
+    specification:
+
+    * The exported symbols are exclusively defined in the source
+      files "zlib.h" and "zlib.def", found in an official zlib
+      source distribution.
+    * The symbols are exported by name, not by ordinal.
+    * The exported names are undecorated.
+    * The calling convention of functions is "C" (CDECL).
+    * The ZLIB1.DLL binary is linked to MSVCRT.DLL.
+
+    The archive in which ZLIB1.DLL is bundled contains compiled
+    test programs that must run with a valid build of ZLIB1.DLL.
+    It is recommended to download the prebuilt DLL from the zlib
+    web site, instead of building it yourself, to avoid potential
+    incompatibilities that could be introduced by your compiler
+    and build settings.  If you do build the DLL yourself, please
+    make sure that it complies with all the above requirements,
+    and it runs with the precompiled test programs, bundled with
+    the original ZLIB1.DLL distribution.
+
+    If, for any reason, you need to build an incompatible DLL,
+    please use a different file name.
+
+
+ 2. Why did you change the name of the DLL to ZLIB1.DLL?
+    What happened to the old ZLIB.DLL?
+
+  - The old ZLIB.DLL, built from zlib-1.1.4 or earlier, required
+    compilation settings that were incompatible to those used by
+    a static build.  The DLL settings were supposed to be enabled
+    by defining the macro ZLIB_DLL, before including "zlib.h".
+    Incorrect handling of this macro was silently accepted at
+    build time, resulting in two major problems:
+
+    * ZLIB_DLL was missing from the old makefile.  When building
+      the DLL, not all people added it to the build options.  In
+      consequence, incompatible incarnations of ZLIB.DLL started
+      to circulate around the net.
+
+    * When switching from using the static library to using the
+      DLL, applications had to define the ZLIB_DLL macro and
+      to recompile all the sources that contained calls to zlib
+      functions.  Failure to do so resulted in creating binaries
+      that were unable to run with the official ZLIB.DLL build.
+
+    The only possible solution that we could foresee was to make
+    a binary-incompatible change in the DLL interface, in order to
+    remove the dependency on the ZLIB_DLL macro, and to release
+    the new DLL under a different name.
+
+    We chose the name ZLIB1.DLL, where '1' indicates the major
+    zlib version number.  We hope that we will not have to break
+    the binary compatibility again, at least not as long as the
+    zlib-1.x series will last.
+
+    There is still a ZLIB_DLL macro, that can trigger a more
+    efficient build and use of the DLL, but compatibility no
+    longer dependents on it.
+
+
+ 3. Can I build ZLIB.DLL from the new zlib sources, and replace
+    an old ZLIB.DLL, that was built from zlib-1.1.4 or earlier?
+
+  - In principle, you can do it by assigning calling convention
+    keywords to the macros ZEXPORT and ZEXPORTVA.  In practice,
+    it depends on what you mean by "an old ZLIB.DLL", because the
+    old DLL exists in several mutually-incompatible versions.
+    You have to find out first what kind of calling convention is
+    being used in your particular ZLIB.DLL build, and to use the
+    same one in the new build.  If you don't know what this is all
+    about, you might be better off if you would just leave the old
+    DLL intact.
+
+
+ 4. Can I compile my application using the new zlib interface, and
+    link it to an old ZLIB.DLL, that was built from zlib-1.1.4 or
+    earlier?
+
+  - The official answer is "no"; the real answer depends again on
+    what kind of ZLIB.DLL you have.  Even if you are lucky, this
+    course of action is unreliable.
+
+    If you rebuild your application and you intend to use a newer
+    version of zlib (post- 1.1.4), it is strongly recommended to
+    link it to the new ZLIB1.DLL.
+
+
+ 5. Why are the zlib symbols exported by name, and not by ordinal?
+
+  - Although exporting symbols by ordinal is a little faster, it
+    is risky.  Any single glitch in the maintenance or use of the
+    DEF file that contains the ordinals can result in incompatible
+    builds and frustrating crashes.  Simply put, the benefits of
+    exporting symbols by ordinal do not justify the risks.
+
+    Technically, it should be possible to maintain ordinals in
+    the DEF file, and still export the symbols by name.  Ordinals
+    exist in every DLL, and even if the dynamic linking performed
+    at the DLL startup is searching for names, ordinals serve as
+    hints, for a faster name lookup.  However, if the DEF file
+    contains ordinals, the Microsoft linker automatically builds
+    an implib that will cause the executables linked to it to use
+    those ordinals, and not the names.  It is interesting to
+    notice that the GNU linker for Win32 does not suffer from this
+    problem.
+
+    It is possible to avoid the DEF file if the exported symbols
+    are accompanied by a "__declspec(dllexport)" attribute in the
+    source files.  You can do this in zlib by predefining the
+    ZLIB_DLL macro.
+
+
+ 6. I see that the ZLIB1.DLL functions use the "C" (CDECL) calling
+    convention.  Why not use the STDCALL convention?
+    STDCALL is the standard convention in Win32, and I need it in
+    my Visual Basic project!
+
+    (For readability, we use CDECL to refer to the convention
+     triggered by the "__cdecl" keyword, STDCALL to refer to
+     the convention triggered by "__stdcall", and FASTCALL to
+     refer to the convention triggered by "__fastcall".)
+
+  - Most of the native Windows API functions (without varargs) use
+    indeed the WINAPI convention (which translates to STDCALL in
+    Win32), but the standard C functions use CDECL.  If a user
+    application is intrinsically tied to the Windows API (e.g.
+    it calls native Windows API functions such as CreateFile()),
+    sometimes it makes sense to decorate its own functions with
+    WINAPI.  But if ANSI C or POSIX portability is a goal (e.g.
+    it calls standard C functions such as fopen()), it is not a
+    sound decision to request the inclusion of <windows.h>, or to
+    use non-ANSI constructs, for the sole purpose to make the user
+    functions STDCALL-able.
+
+    The functionality offered by zlib is not in the category of
+    "Windows functionality", but is more like "C functionality".
+
+    Technically, STDCALL is not bad; in fact, it is slightly
+    faster than CDECL, and it works with variable-argument
+    functions, just like CDECL.  It is unfortunate that, in spite
+    of using STDCALL in the Windows API, it is not the default
+    convention used by the C compilers that run under Windows.
+    The roots of the problem reside deep inside the unsafety of
+    the K&R-style function prototypes, where the argument types
+    are not specified; but that is another story for another day.
+
+    The remaining fact is that CDECL is the default convention.
+    Even if an explicit convention is hard-coded into the function
+    prototypes inside C headers, problems may appear.  The
+    necessity to expose the convention in users' callbacks is one
+    of these problems.
+
+    The calling convention issues are also important when using
+    zlib in other programming languages.  Some of them, like Ada
+    (GNAT) and Fortran (GNU G77), have C bindings implemented
+    initially on Unix, and relying on the C calling convention.
+    On the other hand, the pre- .NET versions of Microsoft Visual
+    Basic require STDCALL, while Borland Delphi prefers, although
+    it does not require, FASTCALL.
+
+    In fairness to all possible uses of zlib outside the C
+    programming language, we choose the default "C" convention.
+    Anyone interested in different bindings or conventions is
+    encouraged to maintain specialized projects.  The "contrib/"
+    directory from the zlib distribution already holds a couple
+    of foreign bindings, such as Ada, C++, and Delphi.
+
+
+ 7. I need a DLL for my Visual Basic project.  What can I do?
+
+  - Define the ZLIB_WINAPI macro before including "zlib.h", when
+    building both the DLL and the user application (except that
+    you don't need to define anything when using the DLL in Visual
+    Basic).  The ZLIB_WINAPI macro will switch on the WINAPI
+    (STDCALL) convention.  The name of this DLL must be different
+    than the official ZLIB1.DLL.
+
+    Gilles Vollant has contributed a build named ZLIBWAPI.DLL,
+    with the ZLIB_WINAPI macro turned on, and with the minizip
+    functionality built in.  For more information, please read
+    the notes inside "contrib/vstudio/readme.txt", found in the
+    zlib distribution.
+
+
+ 8. I need to use zlib in my Microsoft .NET project.  What can I
+    do?
+
+  - Henrik Ravn has contributed a .NET wrapper around zlib.  Look
+    into contrib/dotzlib/, inside the zlib distribution.
+
+
+ 9. If my application uses ZLIB1.DLL, should I link it to
+    MSVCRT.DLL?  Why?
+
+  - It is not required, but it is recommended to link your
+    application to MSVCRT.DLL, if it uses ZLIB1.DLL.
+
+    The executables (.EXE, .DLL, etc.) that are involved in the
+    same process and are using the C run-time library (i.e. they
+    are calling standard C functions), must link to the same
+    library.  There are several libraries in the Win32 system:
+    CRTDLL.DLL, MSVCRT.DLL, the static C libraries, etc.
+    Since ZLIB1.DLL is linked to MSVCRT.DLL, the executables that
+    depend on it should also be linked to MSVCRT.DLL.
+
+
+10. Why are you saying that ZLIB1.DLL and my application should
+    be linked to the same C run-time (CRT) library?  I linked my
+    application and my DLLs to different C libraries (e.g. my
+    application to a static library, and my DLLs to MSVCRT.DLL),
+    and everything works fine.
+
+  - If a user library invokes only pure Win32 API (accessible via
+    <windows.h> and the related headers), its DLL build will work
+    in any context.  But if this library invokes standard C API,
+    things get more complicated.
+
+    There is a single Win32 library in a Win32 system.  Every
+    function in this library resides in a single DLL module, that
+    is safe to call from anywhere.  On the other hand, there are
+    multiple versions of the C library, and each of them has its
+    own separate internal state.  Standalone executables and user
+    DLLs that call standard C functions must link to a C run-time
+    (CRT) library, be it static or shared (DLL).  Intermixing
+    occurs when an executable (not necessarily standalone) and a
+    DLL are linked to different CRTs, and both are running in the
+    same process.
+
+    Intermixing multiple CRTs is possible, as long as their
+    internal states are kept intact.  The Microsoft Knowledge Base
+    articles KB94248 "HOWTO: Use the C Run-Time" and KB140584
+    "HOWTO: Link with the Correct C Run-Time (CRT) Library"
+    mention the potential problems raised by intermixing.
+
+    If intermixing works for you, it's because your application
+    and DLLs are avoiding the corruption of each of the CRTs'
+    internal states, maybe by careful design, or maybe by fortune.
+
+    Also note that linking ZLIB1.DLL to non-Microsoft CRTs, such
+    as those provided by Borland, raises similar problems.
+
+
+11. Why are you linking ZLIB1.DLL to MSVCRT.DLL?
+
+  - MSVCRT.DLL exists on every Windows 95 with a new service pack
+    installed, or with Microsoft Internet Explorer 4 or later, and
+    on all other Windows 4.x or later (Windows 98, Windows NT 4,
+    or later).  It is freely distributable; if not present in the
+    system, it can be downloaded from Microsoft or from other
+    software provider for free.
+
+    The fact that MSVCRT.DLL does not exist on a virgin Windows 95
+    is not so problematic.  Windows 95 is scarcely found nowadays,
+    Microsoft ended its support a long time ago, and many recent
+    applications from various vendors, including Microsoft, do not
+    even run on it.  Furthermore, no serious user should run
+    Windows 95 without a proper update installed.
+
+
+12. Why are you not linking ZLIB1.DLL to
+    <<my favorite C run-time library>> ?
+
+  - We considered and abandoned the following alternatives:
+
+    * Linking ZLIB1.DLL to a static C library (LIBC.LIB, or
+      LIBCMT.LIB) is not a good option.  People are using the DLL
+      mainly to save disk space.  If you are linking your program
+      to a static C library, you may as well consider linking zlib
+      in statically, too.
+
+    * Linking ZLIB1.DLL to CRTDLL.DLL looks appealing, because
+      CRTDLL.DLL is present on every Win32 installation.
+      Unfortunately, it has a series of problems: it does not
+      work properly with Microsoft's C++ libraries, it does not
+      provide support for 64-bit file offsets, (and so on...),
+      and Microsoft discontinued its support a long time ago.
+
+    * Linking ZLIB1.DLL to MSVCR70.DLL or MSVCR71.DLL, supplied
+      with the Microsoft .NET platform, and Visual C++ 7.0/7.1,
+      raises problems related to the status of ZLIB1.DLL as a
+      system component.  According to the Microsoft Knowledge Base
+      article KB326922 "INFO: Redistribution of the Shared C
+      Runtime Component in Visual C++ .NET", MSVCR70.DLL and
+      MSVCR71.DLL are not supposed to function as system DLLs,
+      because they may clash with MSVCRT.DLL.  Instead, the
+      application's installer is supposed to put these DLLs
+      (if needed) in the application's private directory.
+      If ZLIB1.DLL depends on a non-system runtime, it cannot
+      function as a redistributable system component.
+
+    * Linking ZLIB1.DLL to non-Microsoft runtimes, such as
+      Borland's, or Cygwin's, raises problems related to the
+      reliable presence of these runtimes on Win32 systems.
+      It's easier to let the DLL build of zlib up to the people
+      who distribute these runtimes, and who may proceed as
+      explained in the answer to Question 14.
+
+
+13. If ZLIB1.DLL cannot be linked to MSVCR70.DLL or MSVCR71.DLL,
+    how can I build/use ZLIB1.DLL in Microsoft Visual C++ 7.0
+    (Visual Studio .NET) or newer?
+
+  - Due to the problems explained in the Microsoft Knowledge Base
+    article KB326922 (see the previous answer), the C runtime that
+    comes with the VC7 environment is no longer considered a
+    system component.  That is, it should not be assumed that this
+    runtime exists, or may be installed in a system directory.
+    Since ZLIB1.DLL is supposed to be a system component, it may
+    not depend on a non-system component.
+
+    In order to link ZLIB1.DLL and your application to MSVCRT.DLL
+    in VC7, you need the library of Visual C++ 6.0 or older.  If
+    you don't have this library at hand, it's probably best not to
+    use ZLIB1.DLL.
+
+    We are hoping that, in the future, Microsoft will provide a
+    way to build applications linked to a proper system runtime,
+    from the Visual C++ environment.  Until then, you have a
+    couple of alternatives, such as linking zlib in statically.
+    If your application requires dynamic linking, you may proceed
+    as explained in the answer to Question 14.
+
+
+14. I need to link my own DLL build to a CRT different than
+    MSVCRT.DLL.  What can I do?
+
+  - Feel free to rebuild the DLL from the zlib sources, and link
+    it the way you want.  You should, however, clearly state that
+    your build is unofficial.  You should give it a different file
+    name, and/or install it in a private directory that can be
+    accessed by your application only, and is not visible to the
+    others (i.e. it's neither in the PATH, nor in the SYSTEM or
+    SYSTEM32 directories).  Otherwise, your build may clash with
+    applications that link to the official build.
+
+    For example, in Cygwin, zlib is linked to the Cygwin runtime
+    CYGWIN1.DLL, and it is distributed under the name CYGZ.DLL.
+
+
+15. May I include additional pieces of code that I find useful,
+    link them in ZLIB1.DLL, and export them?
+
+  - No.  A legitimate build of ZLIB1.DLL must not include code
+    that does not originate from the official zlib source code.
+    But you can make your own private DLL build, under a different
+    file name, as suggested in the previous answer.
+
+    For example, zlib is a part of the VCL library, distributed
+    with Borland Delphi and C++ Builder.  The DLL build of VCL
+    is a redistributable file, named VCLxx.DLL.
+
+
+16. May I remove some functionality out of ZLIB1.DLL, by enabling
+    macros like NO_GZCOMPRESS or NO_GZIP at compile time?
+
+  - No.  A legitimate build of ZLIB1.DLL must provide the complete
+    zlib functionality, as implemented in the official zlib source
+    code.  But you can make your own private DLL build, under a
+    different file name, as suggested in the previous answer.
+
+
+17. I made my own ZLIB1.DLL build.  Can I test it for compliance?
+
+  - We prefer that you download the official DLL from the zlib
+    web site.  If you need something peculiar from this DLL, you
+    can send your suggestion to the zlib mailing list.
+
+    However, in case you do rebuild the DLL yourself, you can run
+    it with the test programs found in the DLL distribution.
+    Running these test programs is not a guarantee of compliance,
+    but a failure can imply a detected problem.
+
+**
+
+This document is written and maintained by
+Cosmin Truta <cosmint@cs.ubbcluj.ro>
diff --git a/compat/zlib/win32/Makefile.bor b/compat/zlib/win32/Makefile.bor
new file mode 100644
index 0000000..d152bbb
--- /dev/null
+++ b/compat/zlib/win32/Makefile.bor
@@ -0,0 +1,110 @@
+# Makefile for zlib
+# Borland C++ for Win32
+#
+# Usage:
+#  make -f win32/Makefile.bor
+#  make -f win32/Makefile.bor LOCAL_ZLIB=-DASMV OBJA=match.obj OBJPA=+match.obj
+
+# ------------ Borland C++ ------------
+
+# Optional nonstandard preprocessor flags (e.g. -DMAX_MEM_LEVEL=7)
+# should be added to the environment via "set LOCAL_ZLIB=-DFOO" or
+# added to the declaration of LOC here:
+LOC = $(LOCAL_ZLIB)
+
+CC = bcc32
+AS = bcc32
+LD = bcc32
+AR = tlib
+CFLAGS  = -a -d -k- -O2 $(LOC)
+ASFLAGS = $(LOC)
+LDFLAGS = $(LOC)
+
+
+# variables
+ZLIB_LIB = zlib.lib
+
+OBJ1 = adler32.obj compress.obj crc32.obj deflate.obj gzclose.obj gzlib.obj gzread.obj
+OBJ2 = gzwrite.obj infback.obj inffast.obj inflate.obj inftrees.obj trees.obj uncompr.obj zutil.obj
+#OBJA =
+OBJP1 = +adler32.obj+compress.obj+crc32.obj+deflate.obj+gzclose.obj+gzlib.obj+gzread.obj
+OBJP2 = +gzwrite.obj+infback.obj+inffast.obj+inflate.obj+inftrees.obj+trees.obj+uncompr.obj+zutil.obj
+#OBJPA=
+
+
+# targets
+all: $(ZLIB_LIB) example.exe minigzip.exe
+
+.c.obj:
+	$(CC) -c $(CFLAGS) $<
+
+.asm.obj:
+	$(AS) -c $(ASFLAGS) $<
+
+adler32.obj: adler32.c zlib.h zconf.h
+
+compress.obj: compress.c zlib.h zconf.h
+
+crc32.obj: crc32.c zlib.h zconf.h crc32.h
+
+deflate.obj: deflate.c deflate.h zutil.h zlib.h zconf.h
+
+gzclose.obj: gzclose.c zlib.h zconf.h gzguts.h
+
+gzlib.obj: gzlib.c zlib.h zconf.h gzguts.h
+
+gzread.obj: gzread.c zlib.h zconf.h gzguts.h
+
+gzwrite.obj: gzwrite.c zlib.h zconf.h gzguts.h
+
+infback.obj: infback.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
+ inffast.h inffixed.h
+
+inffast.obj: inffast.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
+ inffast.h
+
+inflate.obj: inflate.c zutil.h zlib.h zconf.h inftrees.h inflate.h \
+ inffast.h inffixed.h
+
+inftrees.obj: inftrees.c zutil.h zlib.h zconf.h inftrees.h
+
+trees.obj: trees.c zutil.h zlib.h zconf.h deflate.h trees.h
+
+uncompr.obj: uncompr.c zlib.h zconf.h
+
+zutil.obj: zutil.c zutil.h zlib.h zconf.h
+
+example.obj: test/example.c zlib.h zconf.h
+
+minigzip.obj: test/minigzip.c zlib.h zconf.h
+
+
+# For the sake of the old Borland make,
+# the command line is cut to fit in the MS-DOS 128 byte limit:
+$(ZLIB_LIB): $(OBJ1) $(OBJ2) $(OBJA)
+	-del $(ZLIB_LIB)
+	$(AR) $(ZLIB_LIB) $(OBJP1)
+	$(AR) $(ZLIB_LIB) $(OBJP2)
+	$(AR) $(ZLIB_LIB) $(OBJPA)
+
+
+# testing
+test: example.exe minigzip.exe
+	example
+	echo hello world | minigzip | minigzip -d
+
+example.exe: example.obj $(ZLIB_LIB)
+	$(LD) $(LDFLAGS) example.obj $(ZLIB_LIB)
+
+minigzip.exe: minigzip.obj $(ZLIB_LIB)
+	$(LD) $(LDFLAGS) minigzip.obj $(ZLIB_LIB)
+
+
+# cleanup
+clean:
+	-del $(ZLIB_LIB)
+	-del *.obj
+	-del *.exe
+	-del *.tds
+	-del zlib.bak
+	-del foo.gz
diff --git a/compat/zlib/win32/Makefile.gcc b/compat/zlib/win32/Makefile.gcc
new file mode 100644
index 0000000..6d1ded6
--- /dev/null
+++ b/compat/zlib/win32/Makefile.gcc
@@ -0,0 +1,182 @@
+# Makefile for zlib, derived from Makefile.dj2.
+# Modified for mingw32 by C. Spieler, 6/16/98.
+# Updated for zlib 1.2.x by Christian Spieler and Cosmin Truta, Mar-2003.
+# Last updated: Mar 2012.
+# Tested under Cygwin and MinGW.
+
+# Copyright (C) 1995-2003 Jean-loup Gailly.
+# For conditions of distribution and use, see copyright notice in zlib.h
+
+# To compile, or to compile and test, type from the top level zlib directory:
+#
+#   make -fwin32/Makefile.gcc;  make test testdll -fwin32/Makefile.gcc
+#
+# To use the asm code, type:
+#   cp contrib/asm?86/match.S ./match.S
+#   make LOC=-DASMV OBJA=match.o -fwin32/Makefile.gcc
+#
+# To install libz.a, zconf.h and zlib.h in the system directories, type:
+#
+#   make install -fwin32/Makefile.gcc
+#
+# BINARY_PATH, INCLUDE_PATH and LIBRARY_PATH must be set.
+#
+# To install the shared lib, append SHARED_MODE=1 to the make command :
+#
+#   make install -fwin32/Makefile.gcc SHARED_MODE=1
+
+# Note:
+# If the platform is *not* MinGW (e.g. it is Cygwin or UWIN),
+# the DLL name should be changed from "zlib1.dll".
+
+STATICLIB = libz.a
+SHAREDLIB = zlib1.dll
+IMPLIB    = libz.dll.a
+
+#
+# Set to 1 if shared object needs to be installed
+#
+SHARED_MODE=0
+
+#LOC = -DASMV
+#LOC = -DDEBUG -g
+
+PREFIX =
+CC = $(PREFIX)gcc
+CFLAGS = $(LOC) -O3 -Wall
+
+AS = $(CC)
+ASFLAGS = $(LOC) -Wall
+
+LD = $(CC)
+LDFLAGS = $(LOC)
+
+AR = $(PREFIX)ar
+ARFLAGS = rcs
+
+RC = $(PREFIX)windres
+RCFLAGS = --define GCC_WINDRES
+
+STRIP = $(PREFIX)strip
+
+CP = cp -fp
+# If GNU install is available, replace $(CP) with install.
+INSTALL = $(CP)
+RM = rm -f
+
+prefix ?= /usr/local
+exec_prefix = $(prefix)
+
+OBJS = adler32.o compress.o crc32.o deflate.o gzclose.o gzlib.o gzread.o \
+       gzwrite.o infback.o inffast.o inflate.o inftrees.o trees.o uncompr.o zutil.o
+OBJA =
+
+all: $(STATICLIB) $(SHAREDLIB) $(IMPLIB) example.exe minigzip.exe example_d.exe minigzip_d.exe
+
+test: example.exe minigzip.exe
+	./example
+	echo hello world | ./minigzip | ./minigzip -d
+
+testdll: example_d.exe minigzip_d.exe
+	./example_d
+	echo hello world | ./minigzip_d | ./minigzip_d -d
+
+.c.o:
+	$(CC) $(CFLAGS) -c -o $@ $<
+
+.S.o:
+	$(AS) $(ASFLAGS) -c -o $@ $<
+
+$(STATICLIB): $(OBJS) $(OBJA)
+	$(AR) $(ARFLAGS) $@ $(OBJS) $(OBJA)
+
+$(IMPLIB): $(SHAREDLIB)
+
+$(SHAREDLIB): win32/zlib.def $(OBJS) $(OBJA) zlibrc.o
+	$(CC) -shared -Wl,--out-implib,$(IMPLIB) $(LDFLAGS) \
+	-o $@ win32/zlib.def $(OBJS) $(OBJA) zlibrc.o
+	$(STRIP) $@
+
+example.exe: example.o $(STATICLIB)
+	$(LD) $(LDFLAGS) -o $@ example.o $(STATICLIB)
+	$(STRIP) $@
+
+minigzip.exe: minigzip.o $(STATICLIB)
+	$(LD) $(LDFLAGS) -o $@ minigzip.o $(STATICLIB)
+	$(STRIP) $@
+
+example_d.exe: example.o $(IMPLIB)
+	$(LD) $(LDFLAGS) -o $@ example.o $(IMPLIB)
+	$(STRIP) $@
+
+minigzip_d.exe: minigzip.o $(IMPLIB)
+	$(LD) $(LDFLAGS) -o $@ minigzip.o $(IMPLIB)
+	$(STRIP) $@
+
+example.o: test/example.c zlib.h zconf.h
+	$(CC) $(CFLAGS) -I. -c -o $@ test/example.c
+
+minigzip.o: test/minigzip.c zlib.h zconf.h
+	$(CC) $(CFLAGS) -I. -c -o $@ test/minigzip.c
+
+zlibrc.o: win32/zlib1.rc
+	$(RC) $(RCFLAGS) -o $@ win32/zlib1.rc
+
+.PHONY: install uninstall clean
+
+install: zlib.h zconf.h $(STATICLIB) $(IMPLIB)
+	@if test -z "$(DESTDIR)$(INCLUDE_PATH)" -o -z "$(DESTDIR)$(LIBRARY_PATH)" -o -z "$(DESTDIR)$(BINARY_PATH)"; then \
+		echo INCLUDE_PATH, LIBRARY_PATH, and BINARY_PATH must be specified; \
+		exit 1; \
+	fi
+	-@mkdir -p '$(DESTDIR)$(INCLUDE_PATH)'
+	-@mkdir -p '$(DESTDIR)$(LIBRARY_PATH)' '$(DESTDIR)$(LIBRARY_PATH)'/pkgconfig
+	-if [ "$(SHARED_MODE)" = "1" ]; then \
+		mkdir -p '$(DESTDIR)$(BINARY_PATH)'; \
+		$(INSTALL) $(SHAREDLIB) '$(DESTDIR)$(BINARY_PATH)'; \
+		$(INSTALL) $(IMPLIB) '$(DESTDIR)$(LIBRARY_PATH)'; \
+	fi
+	-$(INSTALL) zlib.h '$(DESTDIR)$(INCLUDE_PATH)'
+	-$(INSTALL) zconf.h '$(DESTDIR)$(INCLUDE_PATH)'
+	-$(INSTALL) $(STATICLIB) '$(DESTDIR)$(LIBRARY_PATH)'
+	sed \
+		-e 's|@prefix@|${prefix}|g' \
+		-e 's|@exec_prefix@|${exec_prefix}|g' \
+		-e 's|@libdir@|$(LIBRARY_PATH)|g' \
+		-e 's|@sharedlibdir@|$(LIBRARY_PATH)|g' \
+		-e 's|@includedir@|$(INCLUDE_PATH)|g' \
+		-e 's|@VERSION@|'`sed -n -e '/VERSION "/s/.*"\(.*\)".*/\1/p' zlib.h`'|g' \
+		zlib.pc.in > '$(DESTDIR)$(LIBRARY_PATH)'/pkgconfig/zlib.pc
+
+uninstall:
+	-if [ "$(SHARED_MODE)" = "1" ]; then \
+		$(RM) '$(DESTDIR)$(BINARY_PATH)'/$(SHAREDLIB); \
+		$(RM) '$(DESTDIR)$(LIBRARY_PATH)'/$(IMPLIB); \
+	fi
+	-$(RM) '$(DESTDIR)$(INCLUDE_PATH)'/zlib.h
+	-$(RM) '$(DESTDIR)$(INCLUDE_PATH)'/zconf.h
+	-$(RM) '$(DESTDIR)$(LIBRARY_PATH)'/$(STATICLIB)
+
+clean:
+	-$(RM) $(STATICLIB)
+	-$(RM) $(SHAREDLIB)
+	-$(RM) $(IMPLIB)
+	-$(RM) *.o
+	-$(RM) *.exe
+	-$(RM) foo.gz
+
+adler32.o: zlib.h zconf.h
+compress.o: zlib.h zconf.h
+crc32.o: crc32.h zlib.h zconf.h
+deflate.o: deflate.h zutil.h zlib.h zconf.h
+gzclose.o: zlib.h zconf.h gzguts.h
+gzlib.o: zlib.h zconf.h gzguts.h
+gzread.o: zlib.h zconf.h gzguts.h
+gzwrite.o: zlib.h zconf.h gzguts.h
+inffast.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h
+inflate.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h
+infback.o: zutil.h zlib.h zconf.h inftrees.h inflate.h inffast.h
+inftrees.o: zutil.h zlib.h zconf.h inftrees.h
+trees.o: deflate.h zutil.h zlib.h zconf.h trees.h
+uncompr.o: zlib.h zconf.h
+zutil.o: zutil.h zlib.h zconf.h
diff --git a/compat/zlib/win32/Makefile.msc b/compat/zlib/win32/Makefile.msc
new file mode 100644
index 0000000..67b7731
--- /dev/null
+++ b/compat/zlib/win32/Makefile.msc
@@ -0,0 +1,163 @@
+# Makefile for zlib using Microsoft (Visual) C
+# zlib is copyright (C) 1995-2006 Jean-loup Gailly and Mark Adler
+#
+# Usage:
+#   nmake -f win32/Makefile.msc                          (standard build)
+#   nmake -f win32/Makefile.msc LOC=-DFOO                (nonstandard build)
+#   nmake -f win32/Makefile.msc LOC="-DASMV -DASMINF" \
+#         OBJA="inffas32.obj match686.obj"               (use ASM code, x86)
+#   nmake -f win32/Makefile.msc AS=ml64 LOC="-DASMV -DASMINF -I." \
+#         OBJA="inffasx64.obj gvmat64.obj inffas8664.obj"  (use ASM code, x64)
+
+# The toplevel directory of the source tree.
+#
+TOP = .
+
+# optional build flags
+LOC =
+
+# variables
+STATICLIB = zlib.lib
+SHAREDLIB = zlib1.dll
+IMPLIB    = zdll.lib
+
+CC = cl
+AS = ml
+LD = link
+AR = lib
+RC = rc
+CFLAGS  = -nologo -MD -W3 -O2 -Oy- -Zi -Fd"zlib" $(LOC)
+WFLAGS  = -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE
+ASFLAGS = -coff -Zi $(LOC)
+LDFLAGS = -nologo -debug -incremental:no -opt:ref
+ARFLAGS = -nologo
+RCFLAGS = /dWIN32 /r
+
+OBJS = adler32.obj compress.obj crc32.obj deflate.obj gzclose.obj gzlib.obj gzread.obj \
+       gzwrite.obj infback.obj inflate.obj inftrees.obj inffast.obj trees.obj uncompr.obj zutil.obj
+OBJA =
+
+
+# targets
+all: $(STATICLIB) $(SHAREDLIB) $(IMPLIB) \
+     example.exe minigzip.exe example_d.exe minigzip_d.exe
+
+$(STATICLIB): $(OBJS) $(OBJA)
+	$(AR) $(ARFLAGS) -out:$@ $(OBJS) $(OBJA)
+
+$(IMPLIB): $(SHAREDLIB)
+
+$(SHAREDLIB): $(TOP)/win32/zlib.def $(OBJS) $(OBJA) zlib1.res
+	$(LD) $(LDFLAGS) -def:$(TOP)/win32/zlib.def -dll -implib:$(IMPLIB) \
+	  -out:$@ -base:0x5A4C0000 $(OBJS) $(OBJA) zlib1.res
+	if exist $@.manifest \
+	  mt -nologo -manifest $@.manifest -outputresource:$@;2
+
+example.exe: example.obj $(STATICLIB)
+	$(LD) $(LDFLAGS) example.obj $(STATICLIB)
+	if exist $@.manifest \
+	  mt -nologo -manifest $@.manifest -outputresource:$@;1
+
+minigzip.exe: minigzip.obj $(STATICLIB)
+	$(LD) $(LDFLAGS) minigzip.obj $(STATICLIB)
+	if exist $@.manifest \
+	  mt -nologo -manifest $@.manifest -outputresource:$@;1
+
+example_d.exe: example.obj $(IMPLIB)
+	$(LD) $(LDFLAGS) -out:$@ example.obj $(IMPLIB)
+	if exist $@.manifest \
+	  mt -nologo -manifest $@.manifest -outputresource:$@;1
+
+minigzip_d.exe: minigzip.obj $(IMPLIB)
+	$(LD) $(LDFLAGS) -out:$@ minigzip.obj $(IMPLIB)
+	if exist $@.manifest \
+	  mt -nologo -manifest $@.manifest -outputresource:$@;1
+
+{$(TOP)}.c.obj:
+	$(CC) -c $(WFLAGS) $(CFLAGS) $<
+
+{$(TOP)/test}.c.obj:
+	$(CC) -c -I$(TOP) $(WFLAGS) $(CFLAGS) $<
+
+{$(TOP)/contrib/masmx64}.c.obj:
+	$(CC) -c $(WFLAGS) $(CFLAGS) $<
+
+{$(TOP)/contrib/masmx64}.asm.obj:
+	$(AS) -c $(ASFLAGS) $<
+
+{$(TOP)/contrib/masmx86}.asm.obj:
+	$(AS) -c $(ASFLAGS) $<
+
+adler32.obj: $(TOP)/adler32.c $(TOP)/zlib.h $(TOP)/zconf.h
+
+compress.obj: $(TOP)/compress.c $(TOP)/zlib.h $(TOP)/zconf.h
+
+crc32.obj: $(TOP)/crc32.c $(TOP)/zlib.h $(TOP)/zconf.h $(TOP)/crc32.h
+
+deflate.obj: $(TOP)/deflate.c $(TOP)/deflate.h $(TOP)/zutil.h $(TOP)/zlib.h $(TOP)/zconf.h
+
+gzclose.obj: $(TOP)/gzclose.c $(TOP)/zlib.h $(TOP)/zconf.h $(TOP)/gzguts.h
+
+gzlib.obj: $(TOP)/gzlib.c $(TOP)/zlib.h $(TOP)/zconf.h $(TOP)/gzguts.h
+
+gzread.obj: $(TOP)/gzread.c $(TOP)/zlib.h $(TOP)/zconf.h $(TOP)/gzguts.h
+
+gzwrite.obj: $(TOP)/gzwrite.c $(TOP)/zlib.h $(TOP)/zconf.h $(TOP)/gzguts.h
+
+infback.obj: $(TOP)/infback.c $(TOP)/zutil.h $(TOP)/zlib.h $(TOP)/zconf.h $(TOP)/inftrees.h $(TOP)/inflate.h \
+             $(TOP)/inffast.h $(TOP)/inffixed.h
+
+inffast.obj: $(TOP)/inffast.c $(TOP)/zutil.h $(TOP)/zlib.h $(TOP)/zconf.h $(TOP)/inftrees.h $(TOP)/inflate.h \
+             $(TOP)/inffast.h
+
+inflate.obj: $(TOP)/inflate.c $(TOP)/zutil.h $(TOP)/zlib.h $(TOP)/zconf.h $(TOP)/inftrees.h $(TOP)/inflate.h \
+             $(TOP)/inffast.h $(TOP)/inffixed.h
+
+inftrees.obj: $(TOP)/inftrees.c $(TOP)/zutil.h $(TOP)/zlib.h $(TOP)/zconf.h $(TOP)/inftrees.h
+
+trees.obj: $(TOP)/trees.c $(TOP)/zutil.h $(TOP)/zlib.h $(TOP)/zconf.h $(TOP)/deflate.h $(TOP)/trees.h
+
+uncompr.obj: $(TOP)/uncompr.c $(TOP)/zlib.h $(TOP)/zconf.h
+
+zutil.obj: $(TOP)/zutil.c $(TOP)/zutil.h $(TOP)/zlib.h $(TOP)/zconf.h
+
+gvmat64.obj: $(TOP)/contrib\masmx64\gvmat64.asm
+
+inffasx64.obj: $(TOP)/contrib\masmx64\inffasx64.asm
+
+inffas8664.obj: $(TOP)/contrib\masmx64\inffas8664.c $(TOP)/zutil.h $(TOP)/zlib.h $(TOP)/zconf.h \
+		$(TOP)/inftrees.h $(TOP)/inflate.h $(TOP)/inffast.h
+
+inffas32.obj: $(TOP)/contrib\masmx86\inffas32.asm
+
+match686.obj: $(TOP)/contrib\masmx86\match686.asm
+
+example.obj: $(TOP)/test/example.c $(TOP)/zlib.h $(TOP)/zconf.h
+
+minigzip.obj: $(TOP)/test/minigzip.c $(TOP)/zlib.h $(TOP)/zconf.h
+
+zlib1.res: $(TOP)/win32/zlib1.rc
+	$(RC) $(RCFLAGS) /fo$@ $(TOP)/win32/zlib1.rc
+
+# testing
+test: example.exe minigzip.exe
+	example
+	echo hello world | minigzip | minigzip -d
+
+testdll: example_d.exe minigzip_d.exe
+	example_d
+	echo hello world | minigzip_d | minigzip_d -d
+
+
+# cleanup
+clean:
+	-del $(STATICLIB)
+	-del $(SHAREDLIB)
+	-del $(IMPLIB)
+	-del *.obj
+	-del *.res
+	-del *.exp
+	-del *.exe
+	-del *.pdb
+	-del *.manifest
+	-del foo.gz
diff --git a/compat/zlib/win32/README-WIN32.txt b/compat/zlib/win32/README-WIN32.txt
new file mode 100644
index 0000000..3d77d52
--- /dev/null
+++ b/compat/zlib/win32/README-WIN32.txt
@@ -0,0 +1,103 @@
+ZLIB DATA COMPRESSION LIBRARY
+
+zlib 1.2.8 is a general purpose data compression library.  All the code is
+thread safe.  The data format used by the zlib library is described by RFCs
+(Request for Comments) 1950 to 1952 in the files
+http://www.ietf.org/rfc/rfc1950.txt (zlib format), rfc1951.txt (deflate format)
+and rfc1952.txt (gzip format).
+
+All functions of the compression library are documented in the file zlib.h
+(volunteer to write man pages welcome, contact zlib@gzip.org).  Two compiled
+examples are distributed in this package, example and minigzip.  The example_d
+and minigzip_d flavors validate that the zlib1.dll file is working correctly.
+
+Questions about zlib should be sent to <zlib@gzip.org>.  The zlib home page
+is http://zlib.net/ .  Before reporting a problem, please check this site to
+verify that you have the latest version of zlib; otherwise get the latest
+version and check whether the problem still exists or not.
+
+PLEASE read DLL_FAQ.txt, and the the zlib FAQ http://zlib.net/zlib_faq.html
+before asking for help.
+
+
+Manifest:
+
+The package zlib-1.2.8-win32-x86.zip will contain the following files:
+
+  README-WIN32.txt This document
+  ChangeLog        Changes since previous zlib packages
+  DLL_FAQ.txt      Frequently asked questions about zlib1.dll
+  zlib.3.pdf       Documentation of this library in Adobe Acrobat format
+
+  example.exe      A statically-bound example (using zlib.lib, not the dll)
+  example.pdb      Symbolic information for debugging example.exe
+
+  example_d.exe    A zlib1.dll bound example (using zdll.lib)
+  example_d.pdb    Symbolic information for debugging example_d.exe
+
+  minigzip.exe     A statically-bound test program (using zlib.lib, not the dll)
+  minigzip.pdb     Symbolic information for debugging minigzip.exe
+
+  minigzip_d.exe   A zlib1.dll bound test program (using zdll.lib)
+  minigzip_d.pdb   Symbolic information for debugging minigzip_d.exe
+
+  zlib.h           Install these files into the compilers' INCLUDE path to
+  zconf.h          compile programs which use zlib.lib or zdll.lib
+
+  zdll.lib         Install these files into the compilers' LIB path if linking
+  zdll.exp         a compiled program to the zlib1.dll binary
+
+  zlib.lib         Install these files into the compilers' LIB path to link zlib
+  zlib.pdb         into compiled programs, without zlib1.dll runtime dependency
+                   (zlib.pdb provides debugging info to the compile time linker)
+
+  zlib1.dll        Install this binary shared library into the system PATH, or
+                   the program's runtime directory (where the .exe resides)
+  zlib1.pdb        Install in the same directory as zlib1.dll, in order to debug
+                   an application crash using WinDbg or similar tools.
+
+All .pdb files above are entirely optional, but are very useful to a developer
+attempting to diagnose program misbehavior or a crash.  Many additional
+important files for developers can be found in the zlib127.zip source package
+available from http://zlib.net/ - review that package's README file for details.
+
+
+Acknowledgments:
+
+The deflate format used by zlib was defined by Phil Katz.  The deflate and
+zlib specifications were written by L.  Peter Deutsch.  Thanks to all the
+people who reported problems and suggested various improvements in zlib; they
+are too numerous to cite here.
+
+
+Copyright notice:
+
+  (C) 1995-2012 Jean-loup Gailly and Mark Adler
+
+  This software is provided 'as-is', without any express or implied
+  warranty.  In no event will the authors be held liable for any damages
+  arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any purpose,
+  including commercial applications, and to alter it and redistribute it
+  freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+
+  Jean-loup Gailly        Mark Adler
+  jloup@gzip.org          madler@alumni.caltech.edu
+
+If you use the zlib library in a product, we would appreciate *not* receiving
+lengthy legal documents to sign.  The sources are provided for free but without
+warranty of any kind.  The library has been entirely written by Jean-loup
+Gailly and Mark Adler; it does not include third-party code.
+
+If you redistribute modified sources, we would appreciate that you include in
+the file ChangeLog history information documenting your changes.  Please read
+the FAQ for more information on the distribution of modified source versions.
diff --git a/compat/zlib/win32/README.txt b/compat/zlib/win32/README.txt
new file mode 100644
index 0000000..34a13b3
--- /dev/null
+++ b/compat/zlib/win32/README.txt
@@ -0,0 +1,60 @@
+
+What's here
+===========
+  The official ZLIB1.DLL
+
+
+Source
+======
+  zlib version 1.2.8
+  available at http://www.gzip.org/zlib/
+
+
+Specification and rationale
+===========================
+  See the accompanying DLL_FAQ.txt
+
+
+Usage
+=====
+  See the accompanying USAGE.txt
+
+
+Build info
+==========
+  Contributed by Jan Nijtmans.
+
+  Compiler:
+    i686-w64-mingw32-gcc (GCC) 4.5.3
+  Library:
+    mingw64-i686-runtime/headers: 3.0b_svn5747-1
+  Build commands:
+    i686-w64-mingw32-gcc -c -DASMV contrib/asm686/match.S
+    i686-w64-mingw32-gcc -c -DASMINF -I. -O3 contrib/inflate86/inffas86.c
+    make -f win32/Makefile.gcc PREFIX=i686-w64-mingw32- LOC="-mms-bitfields -DASMV -DASMINF" OBJA="inffas86.o match.o"
+   Finally, from VS commandline (VS2005 or higher):
+    lib -machine:X86 -name:zlib1.dll -def:zlib.def -out:zdll.lib
+
+Copyright notice
+================
+  Copyright (C) 1995-2010 Jean-loup Gailly and Mark Adler
+
+  This software is provided 'as-is', without any express or implied
+  warranty.  In no event will the authors be held liable for any damages
+  arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any purpose,
+  including commercial applications, and to alter it and redistribute it
+  freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+
+  Jean-loup Gailly        Mark Adler
+  jloup@gzip.org          madler@alumni.caltech.edu
+
diff --git a/compat/zlib/win32/USAGE.txt b/compat/zlib/win32/USAGE.txt
new file mode 100644
index 0000000..48e594e
--- /dev/null
+++ b/compat/zlib/win32/USAGE.txt
@@ -0,0 +1,89 @@
+
+Installing ZLIB1.DLL
+====================
+  Copy ZLIB1.DLL to the SYSTEM or the SYSTEM32 directory.
+
+
+Using ZLIB1.DLL with Microsoft Visual C++
+=========================================
+   1. Install the supplied header files "zlib.h" and "zconf.h"
+      into a directory found in the INCLUDE path list.
+
+   2. Install the supplied library file "zdll.lib" into a
+      directory found in the LIB path list.
+
+   3. Add "zdll.lib" to your project.
+
+
+Using ZLIB1.DLL with gcc/MinGW
+==============================
+   1. Install the supplied header files "zlib.h" and "zconf.h"
+      into the INCLUDE directory.
+
+   2. Copy the supplied library file "zdll.lib" to "libzdll.a":
+        cp lib/zdll.lib lib/libzdll.a
+
+      OR
+
+   2' Build the import library from the supplied "zlib.def":
+        dlltool -D zlib1.dll -d lib/zlib.def -l lib/libzdll.a
+
+   3. Install "libzdll.a" into the LIB directory.
+
+   4. Add "libzdll.a" to your project, or use the -lzdll option.
+
+
+Using ZLIB1.DLL with gcc/Cygwin
+===============================
+  ZLIB1.DLL is not designed to work with Cygwin.  The Cygwin
+  system has its own DLL build of zlib, named CYGZ.DLL.
+
+
+Using ZLIB1.DLL with Borland C++
+================================
+   1. Install the supplied header files "zlib.h" and "zconf.h"
+      into a directory found in the INCLUDE path list.
+
+   2. Build the import library using the IMPLIB tool:
+        implib -a -c -f lib\zdllbor.lib zlib1.dll
+
+      OR
+
+   2' Convert the supplied library file "zdll.lib" to OMF format,
+      using the COFF2OMF tool:
+        coff2omf lib\zdll.lib lib\zdllbor.lib
+
+   3. Install "zdllbor.lib" into a directory found in the LIB path
+      list.
+
+   4. Add "zdllbor.lib" to your project.
+
+  Notes:
+  - The modules that are linked with "zdllbor.lib" must be compiled
+    using a 4-byte alignment (option -a):
+        bcc32 -a -c myprog.c
+        bcc32 myprog.obj zdllbor.lib
+  - If you wish, you may use "zlib1.lib" instead of "zdllbor.lib".
+
+
+Rebuilding ZLIB1.DLL
+====================
+  Depending on your build environment, use the appropriate
+  makefile from the win32/ directory, found in the zlib source
+  distribution.
+
+  Your custom build has to comply with the requirements stated
+  in DLL_FAQ.txt, including (but not limited to) the following:
+    - It must be built from an unaltered zlib source distribution.
+    - It must be linked to MSVCRT.DLL.
+    - The macros that compile out certain portions of the zlib
+      code (such as NO_GZCOMPRESS, NO_GZIP) must not be enabled.
+    - The ZLIB_WINAPI macro must not be enabled.
+
+  Furthermore, it has to run successfully with the test suite
+  found in this package.
+
+  It is recommended, however, to use the supplied ZLIB1.DLL,
+  instead of rebuilding it yourself.  You should rebuild it
+  only if you have a special reason.
+
diff --git a/compat/zlib/win32/VisualC.txt b/compat/zlib/win32/VisualC.txt
new file mode 100644
index 0000000..579a5fc
--- /dev/null
+++ b/compat/zlib/win32/VisualC.txt
@@ -0,0 +1,3 @@
+
+To build zlib using the Microsoft Visual C++ environment,
+use the appropriate project from the projects/ directory.
diff --git a/compat/zlib/win32/zdll.lib b/compat/zlib/win32/zdll.lib
new file mode 100644
index 0000000..8e6f719
Binary files /dev/null and b/compat/zlib/win32/zdll.lib differ
diff --git a/compat/zlib/win32/zlib.def b/compat/zlib/win32/zlib.def
new file mode 100644
index 0000000..face655
--- /dev/null
+++ b/compat/zlib/win32/zlib.def
@@ -0,0 +1,86 @@
+; zlib data compression library
+EXPORTS
+; basic functions
+    zlibVersion
+    deflate
+    deflateEnd
+    inflate
+    inflateEnd
+; advanced functions
+    deflateSetDictionary
+    deflateCopy
+    deflateReset
+    deflateParams
+    deflateTune
+    deflateBound
+    deflatePending
+    deflatePrime
+    deflateSetHeader
+    inflateSetDictionary
+    inflateGetDictionary
+    inflateSync
+    inflateCopy
+    inflateReset
+    inflateReset2
+    inflatePrime
+    inflateMark
+    inflateGetHeader
+    inflateBack
+    inflateBackEnd
+    zlibCompileFlags
+; utility functions
+    compress
+    compress2
+    compressBound
+    uncompress
+    gzopen
+    gzdopen
+    gzbuffer
+    gzsetparams
+    gzread
+    gzwrite
+    gzprintf
+    gzvprintf
+    gzputs
+    gzgets
+    gzputc
+    gzgetc
+    gzungetc
+    gzflush
+    gzseek
+    gzrewind
+    gztell
+    gzoffset
+    gzeof
+    gzdirect
+    gzclose
+    gzclose_r
+    gzclose_w
+    gzerror
+    gzclearerr
+; large file functions
+    gzopen64
+    gzseek64
+    gztell64
+    gzoffset64
+    adler32_combine64
+    crc32_combine64
+; checksum functions
+    adler32
+    crc32
+    adler32_combine
+    crc32_combine
+; various hacks, don't look :)
+    deflateInit_
+    deflateInit2_
+    inflateInit_
+    inflateInit2_
+    inflateBackInit_
+    gzgetc_
+    zError
+    inflateSyncPoint
+    get_crc_table
+    inflateUndermine
+    inflateResetKeep
+    deflateResetKeep
+    gzopen_w
diff --git a/compat/zlib/win32/zlib1.dll b/compat/zlib/win32/zlib1.dll
new file mode 100755
index 0000000..9ea38d5
Binary files /dev/null and b/compat/zlib/win32/zlib1.dll differ
diff --git a/compat/zlib/win32/zlib1.rc b/compat/zlib/win32/zlib1.rc
new file mode 100644
index 0000000..5c0feed
--- /dev/null
+++ b/compat/zlib/win32/zlib1.rc
@@ -0,0 +1,40 @@
+#include <winver.h>
+#include "../zlib.h"
+
+#ifdef GCC_WINDRES
+VS_VERSION_INFO		VERSIONINFO
+#else
+VS_VERSION_INFO		VERSIONINFO	MOVEABLE IMPURE LOADONCALL DISCARDABLE
+#endif
+  FILEVERSION		ZLIB_VER_MAJOR,ZLIB_VER_MINOR,ZLIB_VER_REVISION,0
+  PRODUCTVERSION	ZLIB_VER_MAJOR,ZLIB_VER_MINOR,ZLIB_VER_REVISION,0
+  FILEFLAGSMASK		VS_FFI_FILEFLAGSMASK
+#ifdef _DEBUG
+  FILEFLAGS		1
+#else
+  FILEFLAGS		0
+#endif
+  FILEOS		VOS__WINDOWS32
+  FILETYPE		VFT_DLL
+  FILESUBTYPE		0	// not used
+BEGIN
+  BLOCK "StringFileInfo"
+  BEGIN
+    BLOCK "040904E4"
+    //language ID = U.S. English, char set = Windows, Multilingual
+    BEGIN
+      VALUE "FileDescription",	"zlib data compression library\0"
+      VALUE "FileVersion",	ZLIB_VERSION "\0"
+      VALUE "InternalName",	"zlib1.dll\0"
+      VALUE "LegalCopyright",	"(C) 1995-2013 Jean-loup Gailly & Mark Adler\0"
+      VALUE "OriginalFilename",	"zlib1.dll\0"
+      VALUE "ProductName",	"zlib\0"
+      VALUE "ProductVersion",	ZLIB_VERSION "\0"
+      VALUE "Comments",		"For more information visit http://www.zlib.net/\0"
+    END
+  END
+  BLOCK "VarFileInfo"
+  BEGIN
+    VALUE "Translation", 0x0409, 1252
+  END
+END
diff --git a/compat/zlib/win64/libz.dll.a b/compat/zlib/win64/libz.dll.a
new file mode 100644
index 0000000..a3ae403
Binary files /dev/null and b/compat/zlib/win64/libz.dll.a differ
diff --git a/compat/zlib/win64/zdll.lib b/compat/zlib/win64/zdll.lib
new file mode 100644
index 0000000..ac9ffc9
Binary files /dev/null and b/compat/zlib/win64/zdll.lib differ
diff --git a/compat/zlib/win64/zlib1.dll b/compat/zlib/win64/zlib1.dll
new file mode 100755
index 0000000..bd1dbc6
Binary files /dev/null and b/compat/zlib/win64/zlib1.dll differ
diff --git a/compat/zlib/zconf.h b/compat/zlib/zconf.h
new file mode 100644
index 0000000..9987a77
--- /dev/null
+++ b/compat/zlib/zconf.h
@@ -0,0 +1,511 @@
+/* zconf.h -- configuration of the zlib compression library
+ * Copyright (C) 1995-2013 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id$ */
+
+#ifndef ZCONF_H
+#define ZCONF_H
+
+/*
+ * If you *really* need a unique prefix for all types and library functions,
+ * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.
+ * Even better than compiling with -DZ_PREFIX would be to use configure to set
+ * this permanently in zconf.h using "./configure --zprefix".
+ */
+#ifdef Z_PREFIX     /* may be set to #if 1 by ./configure */
+#  define Z_PREFIX_SET
+
+/* all linked symbols */
+#  define _dist_code            z__dist_code
+#  define _length_code          z__length_code
+#  define _tr_align             z__tr_align
+#  define _tr_flush_bits        z__tr_flush_bits
+#  define _tr_flush_block       z__tr_flush_block
+#  define _tr_init              z__tr_init
+#  define _tr_stored_block      z__tr_stored_block
+#  define _tr_tally             z__tr_tally
+#  define adler32               z_adler32
+#  define adler32_combine       z_adler32_combine
+#  define adler32_combine64     z_adler32_combine64
+#  ifndef Z_SOLO
+#    define compress              z_compress
+#    define compress2             z_compress2
+#    define compressBound         z_compressBound
+#  endif
+#  define crc32                 z_crc32
+#  define crc32_combine         z_crc32_combine
+#  define crc32_combine64       z_crc32_combine64
+#  define deflate               z_deflate
+#  define deflateBound          z_deflateBound
+#  define deflateCopy           z_deflateCopy
+#  define deflateEnd            z_deflateEnd
+#  define deflateInit2_         z_deflateInit2_
+#  define deflateInit_          z_deflateInit_
+#  define deflateParams         z_deflateParams
+#  define deflatePending        z_deflatePending
+#  define deflatePrime          z_deflatePrime
+#  define deflateReset          z_deflateReset
+#  define deflateResetKeep      z_deflateResetKeep
+#  define deflateSetDictionary  z_deflateSetDictionary
+#  define deflateSetHeader      z_deflateSetHeader
+#  define deflateTune           z_deflateTune
+#  define deflate_copyright     z_deflate_copyright
+#  define get_crc_table         z_get_crc_table
+#  ifndef Z_SOLO
+#    define gz_error              z_gz_error
+#    define gz_intmax             z_gz_intmax
+#    define gz_strwinerror        z_gz_strwinerror
+#    define gzbuffer              z_gzbuffer
+#    define gzclearerr            z_gzclearerr
+#    define gzclose               z_gzclose
+#    define gzclose_r             z_gzclose_r
+#    define gzclose_w             z_gzclose_w
+#    define gzdirect              z_gzdirect
+#    define gzdopen               z_gzdopen
+#    define gzeof                 z_gzeof
+#    define gzerror               z_gzerror
+#    define gzflush               z_gzflush
+#    define gzgetc                z_gzgetc
+#    define gzgetc_               z_gzgetc_
+#    define gzgets                z_gzgets
+#    define gzoffset              z_gzoffset
+#    define gzoffset64            z_gzoffset64
+#    define gzopen                z_gzopen
+#    define gzopen64              z_gzopen64
+#    ifdef _WIN32
+#      define gzopen_w              z_gzopen_w
+#    endif
+#    define gzprintf              z_gzprintf
+#    define gzvprintf             z_gzvprintf
+#    define gzputc                z_gzputc
+#    define gzputs                z_gzputs
+#    define gzread                z_gzread
+#    define gzrewind              z_gzrewind
+#    define gzseek                z_gzseek
+#    define gzseek64              z_gzseek64
+#    define gzsetparams           z_gzsetparams
+#    define gztell                z_gztell
+#    define gztell64              z_gztell64
+#    define gzungetc              z_gzungetc
+#    define gzwrite               z_gzwrite
+#  endif
+#  define inflate               z_inflate
+#  define inflateBack           z_inflateBack
+#  define inflateBackEnd        z_inflateBackEnd
+#  define inflateBackInit_      z_inflateBackInit_
+#  define inflateCopy           z_inflateCopy
+#  define inflateEnd            z_inflateEnd
+#  define inflateGetHeader      z_inflateGetHeader
+#  define inflateInit2_         z_inflateInit2_
+#  define inflateInit_          z_inflateInit_
+#  define inflateMark           z_inflateMark
+#  define inflatePrime          z_inflatePrime
+#  define inflateReset          z_inflateReset
+#  define inflateReset2         z_inflateReset2
+#  define inflateSetDictionary  z_inflateSetDictionary
+#  define inflateGetDictionary  z_inflateGetDictionary
+#  define inflateSync           z_inflateSync
+#  define inflateSyncPoint      z_inflateSyncPoint
+#  define inflateUndermine      z_inflateUndermine
+#  define inflateResetKeep      z_inflateResetKeep
+#  define inflate_copyright     z_inflate_copyright
+#  define inflate_fast          z_inflate_fast
+#  define inflate_table         z_inflate_table
+#  ifndef Z_SOLO
+#    define uncompress            z_uncompress
+#  endif
+#  define zError                z_zError
+#  ifndef Z_SOLO
+#    define zcalloc               z_zcalloc
+#    define zcfree                z_zcfree
+#  endif
+#  define zlibCompileFlags      z_zlibCompileFlags
+#  define zlibVersion           z_zlibVersion
+
+/* all zlib typedefs in zlib.h and zconf.h */
+#  define Byte                  z_Byte
+#  define Bytef                 z_Bytef
+#  define alloc_func            z_alloc_func
+#  define charf                 z_charf
+#  define free_func             z_free_func
+#  ifndef Z_SOLO
+#    define gzFile                z_gzFile
+#  endif
+#  define gz_header             z_gz_header
+#  define gz_headerp            z_gz_headerp
+#  define in_func               z_in_func
+#  define intf                  z_intf
+#  define out_func              z_out_func
+#  define uInt                  z_uInt
+#  define uIntf                 z_uIntf
+#  define uLong                 z_uLong
+#  define uLongf                z_uLongf
+#  define voidp                 z_voidp
+#  define voidpc                z_voidpc
+#  define voidpf                z_voidpf
+
+/* all zlib structs in zlib.h and zconf.h */
+#  define gz_header_s           z_gz_header_s
+#  define internal_state        z_internal_state
+
+#endif
+
+#if defined(__MSDOS__) && !defined(MSDOS)
+#  define MSDOS
+#endif
+#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2)
+#  define OS2
+#endif
+#if defined(_WINDOWS) && !defined(WINDOWS)
+#  define WINDOWS
+#endif
+#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__)
+#  ifndef WIN32
+#    define WIN32
+#  endif
+#endif
+#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32)
+#  if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__)
+#    ifndef SYS16BIT
+#      define SYS16BIT
+#    endif
+#  endif
+#endif
+
+/*
+ * Compile with -DMAXSEG_64K if the alloc function cannot allocate more
+ * than 64k bytes at a time (needed on systems with 16-bit int).
+ */
+#ifdef SYS16BIT
+#  define MAXSEG_64K
+#endif
+#ifdef MSDOS
+#  define UNALIGNED_OK
+#endif
+
+#ifdef __STDC_VERSION__
+#  ifndef STDC
+#    define STDC
+#  endif
+#  if __STDC_VERSION__ >= 199901L
+#    ifndef STDC99
+#      define STDC99
+#    endif
+#  endif
+#endif
+#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus))
+#  define STDC
+#endif
+#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__))
+#  define STDC
+#endif
+#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32))
+#  define STDC
+#endif
+#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__))
+#  define STDC
+#endif
+
+#if defined(__OS400__) && !defined(STDC)    /* iSeries (formerly AS/400). */
+#  define STDC
+#endif
+
+#ifndef STDC
+#  ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */
+#    define const       /* note: need a more gentle solution here */
+#  endif
+#endif
+
+#if defined(ZLIB_CONST) && !defined(z_const)
+#  define z_const const
+#else
+#  define z_const
+#endif
+
+/* Some Mac compilers merge all .h files incorrectly: */
+#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__)
+#  define NO_DUMMY_DECL
+#endif
+
+/* Maximum value for memLevel in deflateInit2 */
+#ifndef MAX_MEM_LEVEL
+#  ifdef MAXSEG_64K
+#    define MAX_MEM_LEVEL 8
+#  else
+#    define MAX_MEM_LEVEL 9
+#  endif
+#endif
+
+/* Maximum value for windowBits in deflateInit2 and inflateInit2.
+ * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files
+ * created by gzip. (Files created by minigzip can still be extracted by
+ * gzip.)
+ */
+#ifndef MAX_WBITS
+#  define MAX_WBITS   15 /* 32K LZ77 window */
+#endif
+
+/* The memory requirements for deflate are (in bytes):
+            (1 << (windowBits+2)) +  (1 << (memLevel+9))
+ that is: 128K for windowBits=15  +  128K for memLevel = 8  (default values)
+ plus a few kilobytes for small objects. For example, if you want to reduce
+ the default memory requirements from 256K to 128K, compile with
+     make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
+ Of course this will generally degrade compression (there's no free lunch).
+
+   The memory requirements for inflate are (in bytes) 1 << windowBits
+ that is, 32K for windowBits=15 (default value) plus a few kilobytes
+ for small objects.
+*/
+
+                        /* Type declarations */
+
+#ifndef OF /* function prototypes */
+#  ifdef STDC
+#    define OF(args)  args
+#  else
+#    define OF(args)  ()
+#  endif
+#endif
+
+#ifndef Z_ARG /* function prototypes for stdarg */
+#  if defined(STDC) || defined(Z_HAVE_STDARG_H)
+#    define Z_ARG(args)  args
+#  else
+#    define Z_ARG(args)  ()
+#  endif
+#endif
+
+/* The following definitions for FAR are needed only for MSDOS mixed
+ * model programming (small or medium model with some far allocations).
+ * This was tested only with MSC; for other MSDOS compilers you may have
+ * to define NO_MEMCPY in zutil.h.  If you don't need the mixed model,
+ * just define FAR to be empty.
+ */
+#ifdef SYS16BIT
+#  if defined(M_I86SM) || defined(M_I86MM)
+     /* MSC small or medium model */
+#    define SMALL_MEDIUM
+#    ifdef _MSC_VER
+#      define FAR _far
+#    else
+#      define FAR far
+#    endif
+#  endif
+#  if (defined(__SMALL__) || defined(__MEDIUM__))
+     /* Turbo C small or medium model */
+#    define SMALL_MEDIUM
+#    ifdef __BORLANDC__
+#      define FAR _far
+#    else
+#      define FAR far
+#    endif
+#  endif
+#endif
+
+#if defined(WINDOWS) || defined(WIN32)
+   /* If building or using zlib as a DLL, define ZLIB_DLL.
+    * This is not mandatory, but it offers a little performance increase.
+    */
+#  ifdef ZLIB_DLL
+#    if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500))
+#      ifdef ZLIB_INTERNAL
+#        define ZEXTERN extern __declspec(dllexport)
+#      else
+#        define ZEXTERN extern __declspec(dllimport)
+#      endif
+#    endif
+#  endif  /* ZLIB_DLL */
+   /* If building or using zlib with the WINAPI/WINAPIV calling convention,
+    * define ZLIB_WINAPI.
+    * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI.
+    */
+#  ifdef ZLIB_WINAPI
+#    ifdef FAR
+#      undef FAR
+#    endif
+#    include <windows.h>
+     /* No need for _export, use ZLIB.DEF instead. */
+     /* For complete Windows compatibility, use WINAPI, not __stdcall. */
+#    define ZEXPORT WINAPI
+#    ifdef WIN32
+#      define ZEXPORTVA WINAPIV
+#    else
+#      define ZEXPORTVA FAR CDECL
+#    endif
+#  endif
+#endif
+
+#if defined (__BEOS__)
+#  ifdef ZLIB_DLL
+#    ifdef ZLIB_INTERNAL
+#      define ZEXPORT   __declspec(dllexport)
+#      define ZEXPORTVA __declspec(dllexport)
+#    else
+#      define ZEXPORT   __declspec(dllimport)
+#      define ZEXPORTVA __declspec(dllimport)
+#    endif
+#  endif
+#endif
+
+#ifndef ZEXTERN
+#  define ZEXTERN extern
+#endif
+#ifndef ZEXPORT
+#  define ZEXPORT
+#endif
+#ifndef ZEXPORTVA
+#  define ZEXPORTVA
+#endif
+
+#ifndef FAR
+#  define FAR
+#endif
+
+#if !defined(__MACTYPES__)
+typedef unsigned char  Byte;  /* 8 bits */
+#endif
+typedef unsigned int   uInt;  /* 16 bits or more */
+typedef unsigned long  uLong; /* 32 bits or more */
+
+#ifdef SMALL_MEDIUM
+   /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */
+#  define Bytef Byte FAR
+#else
+   typedef Byte  FAR Bytef;
+#endif
+typedef char  FAR charf;
+typedef int   FAR intf;
+typedef uInt  FAR uIntf;
+typedef uLong FAR uLongf;
+
+#ifdef STDC
+   typedef void const *voidpc;
+   typedef void FAR   *voidpf;
+   typedef void       *voidp;
+#else
+   typedef Byte const *voidpc;
+   typedef Byte FAR   *voidpf;
+   typedef Byte       *voidp;
+#endif
+
+#if !defined(Z_U4) && !defined(Z_SOLO) && defined(STDC)
+#  include <limits.h>
+#  if (UINT_MAX == 0xffffffffUL)
+#    define Z_U4 unsigned
+#  elif (ULONG_MAX == 0xffffffffUL)
+#    define Z_U4 unsigned long
+#  elif (USHRT_MAX == 0xffffffffUL)
+#    define Z_U4 unsigned short
+#  endif
+#endif
+
+#ifdef Z_U4
+   typedef Z_U4 z_crc_t;
+#else
+   typedef unsigned long z_crc_t;
+#endif
+
+#ifdef HAVE_UNISTD_H    /* may be set to #if 1 by ./configure */
+#  define Z_HAVE_UNISTD_H
+#endif
+
+#ifdef HAVE_STDARG_H    /* may be set to #if 1 by ./configure */
+#  define Z_HAVE_STDARG_H
+#endif
+
+#ifdef STDC
+#  ifndef Z_SOLO
+#    include <sys/types.h>      /* for off_t */
+#  endif
+#endif
+
+#if defined(STDC) || defined(Z_HAVE_STDARG_H)
+#  ifndef Z_SOLO
+#    include <stdarg.h>         /* for va_list */
+#  endif
+#endif
+
+#ifdef _WIN32
+#  ifndef Z_SOLO
+#    include <stddef.h>         /* for wchar_t */
+#  endif
+#endif
+
+/* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and
+ * "#define _LARGEFILE64_SOURCE 1" as requesting 64-bit operations, (even
+ * though the former does not conform to the LFS document), but considering
+ * both "#undef _LARGEFILE64_SOURCE" and "#define _LARGEFILE64_SOURCE 0" as
+ * equivalently requesting no 64-bit operations
+ */
+#if defined(_LARGEFILE64_SOURCE) && -_LARGEFILE64_SOURCE - -1 == 1
+#  undef _LARGEFILE64_SOURCE
+#endif
+
+#if defined(__WATCOMC__) && !defined(Z_HAVE_UNISTD_H)
+#  define Z_HAVE_UNISTD_H
+#endif
+#ifndef Z_SOLO
+#  if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE)
+#    include <unistd.h>         /* for SEEK_*, off_t, and _LFS64_LARGEFILE */
+#    ifdef VMS
+#      include <unixio.h>       /* for off_t */
+#    endif
+#    ifndef z_off_t
+#      define z_off_t off_t
+#    endif
+#  endif
+#endif
+
+#if defined(_LFS64_LARGEFILE) && _LFS64_LARGEFILE-0
+#  define Z_LFS64
+#endif
+
+#if defined(_LARGEFILE64_SOURCE) && defined(Z_LFS64)
+#  define Z_LARGE64
+#endif
+
+#if defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS-0 == 64 && defined(Z_LFS64)
+#  define Z_WANT64
+#endif
+
+#if !defined(SEEK_SET) && !defined(Z_SOLO)
+#  define SEEK_SET        0       /* Seek from beginning of file.  */
+#  define SEEK_CUR        1       /* Seek from current position.  */
+#  define SEEK_END        2       /* Set file pointer to EOF plus "offset" */
+#endif
+
+#ifndef z_off_t
+#  define z_off_t long
+#endif
+
+#if !defined(_WIN32) && defined(Z_LARGE64)
+#  define z_off64_t off64_t
+#else
+#  if defined(_WIN32) && !defined(__GNUC__) && !defined(Z_SOLO)
+#    define z_off64_t __int64
+#  else
+#    define z_off64_t z_off_t
+#  endif
+#endif
+
+/* MVS linker does not support external names larger than 8 bytes */
+#if defined(__MVS__)
+  #pragma map(deflateInit_,"DEIN")
+  #pragma map(deflateInit2_,"DEIN2")
+  #pragma map(deflateEnd,"DEEND")
+  #pragma map(deflateBound,"DEBND")
+  #pragma map(inflateInit_,"ININ")
+  #pragma map(inflateInit2_,"ININ2")
+  #pragma map(inflateEnd,"INEND")
+  #pragma map(inflateSync,"INSY")
+  #pragma map(inflateSetDictionary,"INSEDI")
+  #pragma map(compressBound,"CMBND")
+  #pragma map(inflate_table,"INTABL")
+  #pragma map(inflate_fast,"INFA")
+  #pragma map(inflate_copyright,"INCOPY")
+#endif
+
+#endif /* ZCONF_H */
diff --git a/compat/zlib/zconf.h.cmakein b/compat/zlib/zconf.h.cmakein
new file mode 100644
index 0000000..043019c
--- /dev/null
+++ b/compat/zlib/zconf.h.cmakein
@@ -0,0 +1,513 @@
+/* zconf.h -- configuration of the zlib compression library
+ * Copyright (C) 1995-2013 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id$ */
+
+#ifndef ZCONF_H
+#define ZCONF_H
+#cmakedefine Z_PREFIX
+#cmakedefine Z_HAVE_UNISTD_H
+
+/*
+ * If you *really* need a unique prefix for all types and library functions,
+ * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.
+ * Even better than compiling with -DZ_PREFIX would be to use configure to set
+ * this permanently in zconf.h using "./configure --zprefix".
+ */
+#ifdef Z_PREFIX     /* may be set to #if 1 by ./configure */
+#  define Z_PREFIX_SET
+
+/* all linked symbols */
+#  define _dist_code            z__dist_code
+#  define _length_code          z__length_code
+#  define _tr_align             z__tr_align
+#  define _tr_flush_bits        z__tr_flush_bits
+#  define _tr_flush_block       z__tr_flush_block
+#  define _tr_init              z__tr_init
+#  define _tr_stored_block      z__tr_stored_block
+#  define _tr_tally             z__tr_tally
+#  define adler32               z_adler32
+#  define adler32_combine       z_adler32_combine
+#  define adler32_combine64     z_adler32_combine64
+#  ifndef Z_SOLO
+#    define compress              z_compress
+#    define compress2             z_compress2
+#    define compressBound         z_compressBound
+#  endif
+#  define crc32                 z_crc32
+#  define crc32_combine         z_crc32_combine
+#  define crc32_combine64       z_crc32_combine64
+#  define deflate               z_deflate
+#  define deflateBound          z_deflateBound
+#  define deflateCopy           z_deflateCopy
+#  define deflateEnd            z_deflateEnd
+#  define deflateInit2_         z_deflateInit2_
+#  define deflateInit_          z_deflateInit_
+#  define deflateParams         z_deflateParams
+#  define deflatePending        z_deflatePending
+#  define deflatePrime          z_deflatePrime
+#  define deflateReset          z_deflateReset
+#  define deflateResetKeep      z_deflateResetKeep
+#  define deflateSetDictionary  z_deflateSetDictionary
+#  define deflateSetHeader      z_deflateSetHeader
+#  define deflateTune           z_deflateTune
+#  define deflate_copyright     z_deflate_copyright
+#  define get_crc_table         z_get_crc_table
+#  ifndef Z_SOLO
+#    define gz_error              z_gz_error
+#    define gz_intmax             z_gz_intmax
+#    define gz_strwinerror        z_gz_strwinerror
+#    define gzbuffer              z_gzbuffer
+#    define gzclearerr            z_gzclearerr
+#    define gzclose               z_gzclose
+#    define gzclose_r             z_gzclose_r
+#    define gzclose_w             z_gzclose_w
+#    define gzdirect              z_gzdirect
+#    define gzdopen               z_gzdopen
+#    define gzeof                 z_gzeof
+#    define gzerror               z_gzerror
+#    define gzflush               z_gzflush
+#    define gzgetc                z_gzgetc
+#    define gzgetc_               z_gzgetc_
+#    define gzgets                z_gzgets
+#    define gzoffset              z_gzoffset
+#    define gzoffset64            z_gzoffset64
+#    define gzopen                z_gzopen
+#    define gzopen64              z_gzopen64
+#    ifdef _WIN32
+#      define gzopen_w              z_gzopen_w
+#    endif
+#    define gzprintf              z_gzprintf
+#    define gzvprintf             z_gzvprintf
+#    define gzputc                z_gzputc
+#    define gzputs                z_gzputs
+#    define gzread                z_gzread
+#    define gzrewind              z_gzrewind
+#    define gzseek                z_gzseek
+#    define gzseek64              z_gzseek64
+#    define gzsetparams           z_gzsetparams
+#    define gztell                z_gztell
+#    define gztell64              z_gztell64
+#    define gzungetc              z_gzungetc
+#    define gzwrite               z_gzwrite
+#  endif
+#  define inflate               z_inflate
+#  define inflateBack           z_inflateBack
+#  define inflateBackEnd        z_inflateBackEnd
+#  define inflateBackInit_      z_inflateBackInit_
+#  define inflateCopy           z_inflateCopy
+#  define inflateEnd            z_inflateEnd
+#  define inflateGetHeader      z_inflateGetHeader
+#  define inflateInit2_         z_inflateInit2_
+#  define inflateInit_          z_inflateInit_
+#  define inflateMark           z_inflateMark
+#  define inflatePrime          z_inflatePrime
+#  define inflateReset          z_inflateReset
+#  define inflateReset2         z_inflateReset2
+#  define inflateSetDictionary  z_inflateSetDictionary
+#  define inflateGetDictionary  z_inflateGetDictionary
+#  define inflateSync           z_inflateSync
+#  define inflateSyncPoint      z_inflateSyncPoint
+#  define inflateUndermine      z_inflateUndermine
+#  define inflateResetKeep      z_inflateResetKeep
+#  define inflate_copyright     z_inflate_copyright
+#  define inflate_fast          z_inflate_fast
+#  define inflate_table         z_inflate_table
+#  ifndef Z_SOLO
+#    define uncompress            z_uncompress
+#  endif
+#  define zError                z_zError
+#  ifndef Z_SOLO
+#    define zcalloc               z_zcalloc
+#    define zcfree                z_zcfree
+#  endif
+#  define zlibCompileFlags      z_zlibCompileFlags
+#  define zlibVersion           z_zlibVersion
+
+/* all zlib typedefs in zlib.h and zconf.h */
+#  define Byte                  z_Byte
+#  define Bytef                 z_Bytef
+#  define alloc_func            z_alloc_func
+#  define charf                 z_charf
+#  define free_func             z_free_func
+#  ifndef Z_SOLO
+#    define gzFile                z_gzFile
+#  endif
+#  define gz_header             z_gz_header
+#  define gz_headerp            z_gz_headerp
+#  define in_func               z_in_func
+#  define intf                  z_intf
+#  define out_func              z_out_func
+#  define uInt                  z_uInt
+#  define uIntf                 z_uIntf
+#  define uLong                 z_uLong
+#  define uLongf                z_uLongf
+#  define voidp                 z_voidp
+#  define voidpc                z_voidpc
+#  define voidpf                z_voidpf
+
+/* all zlib structs in zlib.h and zconf.h */
+#  define gz_header_s           z_gz_header_s
+#  define internal_state        z_internal_state
+
+#endif
+
+#if defined(__MSDOS__) && !defined(MSDOS)
+#  define MSDOS
+#endif
+#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2)
+#  define OS2
+#endif
+#if defined(_WINDOWS) && !defined(WINDOWS)
+#  define WINDOWS
+#endif
+#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__)
+#  ifndef WIN32
+#    define WIN32
+#  endif
+#endif
+#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32)
+#  if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__)
+#    ifndef SYS16BIT
+#      define SYS16BIT
+#    endif
+#  endif
+#endif
+
+/*
+ * Compile with -DMAXSEG_64K if the alloc function cannot allocate more
+ * than 64k bytes at a time (needed on systems with 16-bit int).
+ */
+#ifdef SYS16BIT
+#  define MAXSEG_64K
+#endif
+#ifdef MSDOS
+#  define UNALIGNED_OK
+#endif
+
+#ifdef __STDC_VERSION__
+#  ifndef STDC
+#    define STDC
+#  endif
+#  if __STDC_VERSION__ >= 199901L
+#    ifndef STDC99
+#      define STDC99
+#    endif
+#  endif
+#endif
+#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus))
+#  define STDC
+#endif
+#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__))
+#  define STDC
+#endif
+#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32))
+#  define STDC
+#endif
+#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__))
+#  define STDC
+#endif
+
+#if defined(__OS400__) && !defined(STDC)    /* iSeries (formerly AS/400). */
+#  define STDC
+#endif
+
+#ifndef STDC
+#  ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */
+#    define const       /* note: need a more gentle solution here */
+#  endif
+#endif
+
+#if defined(ZLIB_CONST) && !defined(z_const)
+#  define z_const const
+#else
+#  define z_const
+#endif
+
+/* Some Mac compilers merge all .h files incorrectly: */
+#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__)
+#  define NO_DUMMY_DECL
+#endif
+
+/* Maximum value for memLevel in deflateInit2 */
+#ifndef MAX_MEM_LEVEL
+#  ifdef MAXSEG_64K
+#    define MAX_MEM_LEVEL 8
+#  else
+#    define MAX_MEM_LEVEL 9
+#  endif
+#endif
+
+/* Maximum value for windowBits in deflateInit2 and inflateInit2.
+ * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files
+ * created by gzip. (Files created by minigzip can still be extracted by
+ * gzip.)
+ */
+#ifndef MAX_WBITS
+#  define MAX_WBITS   15 /* 32K LZ77 window */
+#endif
+
+/* The memory requirements for deflate are (in bytes):
+            (1 << (windowBits+2)) +  (1 << (memLevel+9))
+ that is: 128K for windowBits=15  +  128K for memLevel = 8  (default values)
+ plus a few kilobytes for small objects. For example, if you want to reduce
+ the default memory requirements from 256K to 128K, compile with
+     make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
+ Of course this will generally degrade compression (there's no free lunch).
+
+   The memory requirements for inflate are (in bytes) 1 << windowBits
+ that is, 32K for windowBits=15 (default value) plus a few kilobytes
+ for small objects.
+*/
+
+                        /* Type declarations */
+
+#ifndef OF /* function prototypes */
+#  ifdef STDC
+#    define OF(args)  args
+#  else
+#    define OF(args)  ()
+#  endif
+#endif
+
+#ifndef Z_ARG /* function prototypes for stdarg */
+#  if defined(STDC) || defined(Z_HAVE_STDARG_H)
+#    define Z_ARG(args)  args
+#  else
+#    define Z_ARG(args)  ()
+#  endif
+#endif
+
+/* The following definitions for FAR are needed only for MSDOS mixed
+ * model programming (small or medium model with some far allocations).
+ * This was tested only with MSC; for other MSDOS compilers you may have
+ * to define NO_MEMCPY in zutil.h.  If you don't need the mixed model,
+ * just define FAR to be empty.
+ */
+#ifdef SYS16BIT
+#  if defined(M_I86SM) || defined(M_I86MM)
+     /* MSC small or medium model */
+#    define SMALL_MEDIUM
+#    ifdef _MSC_VER
+#      define FAR _far
+#    else
+#      define FAR far
+#    endif
+#  endif
+#  if (defined(__SMALL__) || defined(__MEDIUM__))
+     /* Turbo C small or medium model */
+#    define SMALL_MEDIUM
+#    ifdef __BORLANDC__
+#      define FAR _far
+#    else
+#      define FAR far
+#    endif
+#  endif
+#endif
+
+#if defined(WINDOWS) || defined(WIN32)
+   /* If building or using zlib as a DLL, define ZLIB_DLL.
+    * This is not mandatory, but it offers a little performance increase.
+    */
+#  ifdef ZLIB_DLL
+#    if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500))
+#      ifdef ZLIB_INTERNAL
+#        define ZEXTERN extern __declspec(dllexport)
+#      else
+#        define ZEXTERN extern __declspec(dllimport)
+#      endif
+#    endif
+#  endif  /* ZLIB_DLL */
+   /* If building or using zlib with the WINAPI/WINAPIV calling convention,
+    * define ZLIB_WINAPI.
+    * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI.
+    */
+#  ifdef ZLIB_WINAPI
+#    ifdef FAR
+#      undef FAR
+#    endif
+#    include <windows.h>
+     /* No need for _export, use ZLIB.DEF instead. */
+     /* For complete Windows compatibility, use WINAPI, not __stdcall. */
+#    define ZEXPORT WINAPI
+#    ifdef WIN32
+#      define ZEXPORTVA WINAPIV
+#    else
+#      define ZEXPORTVA FAR CDECL
+#    endif
+#  endif
+#endif
+
+#if defined (__BEOS__)
+#  ifdef ZLIB_DLL
+#    ifdef ZLIB_INTERNAL
+#      define ZEXPORT   __declspec(dllexport)
+#      define ZEXPORTVA __declspec(dllexport)
+#    else
+#      define ZEXPORT   __declspec(dllimport)
+#      define ZEXPORTVA __declspec(dllimport)
+#    endif
+#  endif
+#endif
+
+#ifndef ZEXTERN
+#  define ZEXTERN extern
+#endif
+#ifndef ZEXPORT
+#  define ZEXPORT
+#endif
+#ifndef ZEXPORTVA
+#  define ZEXPORTVA
+#endif
+
+#ifndef FAR
+#  define FAR
+#endif
+
+#if !defined(__MACTYPES__)
+typedef unsigned char  Byte;  /* 8 bits */
+#endif
+typedef unsigned int   uInt;  /* 16 bits or more */
+typedef unsigned long  uLong; /* 32 bits or more */
+
+#ifdef SMALL_MEDIUM
+   /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */
+#  define Bytef Byte FAR
+#else
+   typedef Byte  FAR Bytef;
+#endif
+typedef char  FAR charf;
+typedef int   FAR intf;
+typedef uInt  FAR uIntf;
+typedef uLong FAR uLongf;
+
+#ifdef STDC
+   typedef void const *voidpc;
+   typedef void FAR   *voidpf;
+   typedef void       *voidp;
+#else
+   typedef Byte const *voidpc;
+   typedef Byte FAR   *voidpf;
+   typedef Byte       *voidp;
+#endif
+
+#if !defined(Z_U4) && !defined(Z_SOLO) && defined(STDC)
+#  include <limits.h>
+#  if (UINT_MAX == 0xffffffffUL)
+#    define Z_U4 unsigned
+#  elif (ULONG_MAX == 0xffffffffUL)
+#    define Z_U4 unsigned long
+#  elif (USHRT_MAX == 0xffffffffUL)
+#    define Z_U4 unsigned short
+#  endif
+#endif
+
+#ifdef Z_U4
+   typedef Z_U4 z_crc_t;
+#else
+   typedef unsigned long z_crc_t;
+#endif
+
+#ifdef HAVE_UNISTD_H    /* may be set to #if 1 by ./configure */
+#  define Z_HAVE_UNISTD_H
+#endif
+
+#ifdef HAVE_STDARG_H    /* may be set to #if 1 by ./configure */
+#  define Z_HAVE_STDARG_H
+#endif
+
+#ifdef STDC
+#  ifndef Z_SOLO
+#    include <sys/types.h>      /* for off_t */
+#  endif
+#endif
+
+#if defined(STDC) || defined(Z_HAVE_STDARG_H)
+#  ifndef Z_SOLO
+#    include <stdarg.h>         /* for va_list */
+#  endif
+#endif
+
+#ifdef _WIN32
+#  ifndef Z_SOLO
+#    include <stddef.h>         /* for wchar_t */
+#  endif
+#endif
+
+/* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and
+ * "#define _LARGEFILE64_SOURCE 1" as requesting 64-bit operations, (even
+ * though the former does not conform to the LFS document), but considering
+ * both "#undef _LARGEFILE64_SOURCE" and "#define _LARGEFILE64_SOURCE 0" as
+ * equivalently requesting no 64-bit operations
+ */
+#if defined(_LARGEFILE64_SOURCE) && -_LARGEFILE64_SOURCE - -1 == 1
+#  undef _LARGEFILE64_SOURCE
+#endif
+
+#if defined(__WATCOMC__) && !defined(Z_HAVE_UNISTD_H)
+#  define Z_HAVE_UNISTD_H
+#endif
+#ifndef Z_SOLO
+#  if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE)
+#    include <unistd.h>         /* for SEEK_*, off_t, and _LFS64_LARGEFILE */
+#    ifdef VMS
+#      include <unixio.h>       /* for off_t */
+#    endif
+#    ifndef z_off_t
+#      define z_off_t off_t
+#    endif
+#  endif
+#endif
+
+#if defined(_LFS64_LARGEFILE) && _LFS64_LARGEFILE-0
+#  define Z_LFS64
+#endif
+
+#if defined(_LARGEFILE64_SOURCE) && defined(Z_LFS64)
+#  define Z_LARGE64
+#endif
+
+#if defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS-0 == 64 && defined(Z_LFS64)
+#  define Z_WANT64
+#endif
+
+#if !defined(SEEK_SET) && !defined(Z_SOLO)
+#  define SEEK_SET        0       /* Seek from beginning of file.  */
+#  define SEEK_CUR        1       /* Seek from current position.  */
+#  define SEEK_END        2       /* Set file pointer to EOF plus "offset" */
+#endif
+
+#ifndef z_off_t
+#  define z_off_t long
+#endif
+
+#if !defined(_WIN32) && defined(Z_LARGE64)
+#  define z_off64_t off64_t
+#else
+#  if defined(_WIN32) && !defined(__GNUC__) && !defined(Z_SOLO)
+#    define z_off64_t __int64
+#  else
+#    define z_off64_t z_off_t
+#  endif
+#endif
+
+/* MVS linker does not support external names larger than 8 bytes */
+#if defined(__MVS__)
+  #pragma map(deflateInit_,"DEIN")
+  #pragma map(deflateInit2_,"DEIN2")
+  #pragma map(deflateEnd,"DEEND")
+  #pragma map(deflateBound,"DEBND")
+  #pragma map(inflateInit_,"ININ")
+  #pragma map(inflateInit2_,"ININ2")
+  #pragma map(inflateEnd,"INEND")
+  #pragma map(inflateSync,"INSY")
+  #pragma map(inflateSetDictionary,"INSEDI")
+  #pragma map(compressBound,"CMBND")
+  #pragma map(inflate_table,"INTABL")
+  #pragma map(inflate_fast,"INFA")
+  #pragma map(inflate_copyright,"INCOPY")
+#endif
+
+#endif /* ZCONF_H */
diff --git a/compat/zlib/zconf.h.in b/compat/zlib/zconf.h.in
new file mode 100644
index 0000000..9987a77
--- /dev/null
+++ b/compat/zlib/zconf.h.in
@@ -0,0 +1,511 @@
+/* zconf.h -- configuration of the zlib compression library
+ * Copyright (C) 1995-2013 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id$ */
+
+#ifndef ZCONF_H
+#define ZCONF_H
+
+/*
+ * If you *really* need a unique prefix for all types and library functions,
+ * compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.
+ * Even better than compiling with -DZ_PREFIX would be to use configure to set
+ * this permanently in zconf.h using "./configure --zprefix".
+ */
+#ifdef Z_PREFIX     /* may be set to #if 1 by ./configure */
+#  define Z_PREFIX_SET
+
+/* all linked symbols */
+#  define _dist_code            z__dist_code
+#  define _length_code          z__length_code
+#  define _tr_align             z__tr_align
+#  define _tr_flush_bits        z__tr_flush_bits
+#  define _tr_flush_block       z__tr_flush_block
+#  define _tr_init              z__tr_init
+#  define _tr_stored_block      z__tr_stored_block
+#  define _tr_tally             z__tr_tally
+#  define adler32               z_adler32
+#  define adler32_combine       z_adler32_combine
+#  define adler32_combine64     z_adler32_combine64
+#  ifndef Z_SOLO
+#    define compress              z_compress
+#    define compress2             z_compress2
+#    define compressBound         z_compressBound
+#  endif
+#  define crc32                 z_crc32
+#  define crc32_combine         z_crc32_combine
+#  define crc32_combine64       z_crc32_combine64
+#  define deflate               z_deflate
+#  define deflateBound          z_deflateBound
+#  define deflateCopy           z_deflateCopy
+#  define deflateEnd            z_deflateEnd
+#  define deflateInit2_         z_deflateInit2_
+#  define deflateInit_          z_deflateInit_
+#  define deflateParams         z_deflateParams
+#  define deflatePending        z_deflatePending
+#  define deflatePrime          z_deflatePrime
+#  define deflateReset          z_deflateReset
+#  define deflateResetKeep      z_deflateResetKeep
+#  define deflateSetDictionary  z_deflateSetDictionary
+#  define deflateSetHeader      z_deflateSetHeader
+#  define deflateTune           z_deflateTune
+#  define deflate_copyright     z_deflate_copyright
+#  define get_crc_table         z_get_crc_table
+#  ifndef Z_SOLO
+#    define gz_error              z_gz_error
+#    define gz_intmax             z_gz_intmax
+#    define gz_strwinerror        z_gz_strwinerror
+#    define gzbuffer              z_gzbuffer
+#    define gzclearerr            z_gzclearerr
+#    define gzclose               z_gzclose
+#    define gzclose_r             z_gzclose_r
+#    define gzclose_w             z_gzclose_w
+#    define gzdirect              z_gzdirect
+#    define gzdopen               z_gzdopen
+#    define gzeof                 z_gzeof
+#    define gzerror               z_gzerror
+#    define gzflush               z_gzflush
+#    define gzgetc                z_gzgetc
+#    define gzgetc_               z_gzgetc_
+#    define gzgets                z_gzgets
+#    define gzoffset              z_gzoffset
+#    define gzoffset64            z_gzoffset64
+#    define gzopen                z_gzopen
+#    define gzopen64              z_gzopen64
+#    ifdef _WIN32
+#      define gzopen_w              z_gzopen_w
+#    endif
+#    define gzprintf              z_gzprintf
+#    define gzvprintf             z_gzvprintf
+#    define gzputc                z_gzputc
+#    define gzputs                z_gzputs
+#    define gzread                z_gzread
+#    define gzrewind              z_gzrewind
+#    define gzseek                z_gzseek
+#    define gzseek64              z_gzseek64
+#    define gzsetparams           z_gzsetparams
+#    define gztell                z_gztell
+#    define gztell64              z_gztell64
+#    define gzungetc              z_gzungetc
+#    define gzwrite               z_gzwrite
+#  endif
+#  define inflate               z_inflate
+#  define inflateBack           z_inflateBack
+#  define inflateBackEnd        z_inflateBackEnd
+#  define inflateBackInit_      z_inflateBackInit_
+#  define inflateCopy           z_inflateCopy
+#  define inflateEnd            z_inflateEnd
+#  define inflateGetHeader      z_inflateGetHeader
+#  define inflateInit2_         z_inflateInit2_
+#  define inflateInit_          z_inflateInit_
+#  define inflateMark           z_inflateMark
+#  define inflatePrime          z_inflatePrime
+#  define inflateReset          z_inflateReset
+#  define inflateReset2         z_inflateReset2
+#  define inflateSetDictionary  z_inflateSetDictionary
+#  define inflateGetDictionary  z_inflateGetDictionary
+#  define inflateSync           z_inflateSync
+#  define inflateSyncPoint      z_inflateSyncPoint
+#  define inflateUndermine      z_inflateUndermine
+#  define inflateResetKeep      z_inflateResetKeep
+#  define inflate_copyright     z_inflate_copyright
+#  define inflate_fast          z_inflate_fast
+#  define inflate_table         z_inflate_table
+#  ifndef Z_SOLO
+#    define uncompress            z_uncompress
+#  endif
+#  define zError                z_zError
+#  ifndef Z_SOLO
+#    define zcalloc               z_zcalloc
+#    define zcfree                z_zcfree
+#  endif
+#  define zlibCompileFlags      z_zlibCompileFlags
+#  define zlibVersion           z_zlibVersion
+
+/* all zlib typedefs in zlib.h and zconf.h */
+#  define Byte                  z_Byte
+#  define Bytef                 z_Bytef
+#  define alloc_func            z_alloc_func
+#  define charf                 z_charf
+#  define free_func             z_free_func
+#  ifndef Z_SOLO
+#    define gzFile                z_gzFile
+#  endif
+#  define gz_header             z_gz_header
+#  define gz_headerp            z_gz_headerp
+#  define in_func               z_in_func
+#  define intf                  z_intf
+#  define out_func              z_out_func
+#  define uInt                  z_uInt
+#  define uIntf                 z_uIntf
+#  define uLong                 z_uLong
+#  define uLongf                z_uLongf
+#  define voidp                 z_voidp
+#  define voidpc                z_voidpc
+#  define voidpf                z_voidpf
+
+/* all zlib structs in zlib.h and zconf.h */
+#  define gz_header_s           z_gz_header_s
+#  define internal_state        z_internal_state
+
+#endif
+
+#if defined(__MSDOS__) && !defined(MSDOS)
+#  define MSDOS
+#endif
+#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2)
+#  define OS2
+#endif
+#if defined(_WINDOWS) && !defined(WINDOWS)
+#  define WINDOWS
+#endif
+#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__)
+#  ifndef WIN32
+#    define WIN32
+#  endif
+#endif
+#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32)
+#  if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__)
+#    ifndef SYS16BIT
+#      define SYS16BIT
+#    endif
+#  endif
+#endif
+
+/*
+ * Compile with -DMAXSEG_64K if the alloc function cannot allocate more
+ * than 64k bytes at a time (needed on systems with 16-bit int).
+ */
+#ifdef SYS16BIT
+#  define MAXSEG_64K
+#endif
+#ifdef MSDOS
+#  define UNALIGNED_OK
+#endif
+
+#ifdef __STDC_VERSION__
+#  ifndef STDC
+#    define STDC
+#  endif
+#  if __STDC_VERSION__ >= 199901L
+#    ifndef STDC99
+#      define STDC99
+#    endif
+#  endif
+#endif
+#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus))
+#  define STDC
+#endif
+#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__))
+#  define STDC
+#endif
+#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32))
+#  define STDC
+#endif
+#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__))
+#  define STDC
+#endif
+
+#if defined(__OS400__) && !defined(STDC)    /* iSeries (formerly AS/400). */
+#  define STDC
+#endif
+
+#ifndef STDC
+#  ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */
+#    define const       /* note: need a more gentle solution here */
+#  endif
+#endif
+
+#if defined(ZLIB_CONST) && !defined(z_const)
+#  define z_const const
+#else
+#  define z_const
+#endif
+
+/* Some Mac compilers merge all .h files incorrectly: */
+#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__)
+#  define NO_DUMMY_DECL
+#endif
+
+/* Maximum value for memLevel in deflateInit2 */
+#ifndef MAX_MEM_LEVEL
+#  ifdef MAXSEG_64K
+#    define MAX_MEM_LEVEL 8
+#  else
+#    define MAX_MEM_LEVEL 9
+#  endif
+#endif
+
+/* Maximum value for windowBits in deflateInit2 and inflateInit2.
+ * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files
+ * created by gzip. (Files created by minigzip can still be extracted by
+ * gzip.)
+ */
+#ifndef MAX_WBITS
+#  define MAX_WBITS   15 /* 32K LZ77 window */
+#endif
+
+/* The memory requirements for deflate are (in bytes):
+            (1 << (windowBits+2)) +  (1 << (memLevel+9))
+ that is: 128K for windowBits=15  +  128K for memLevel = 8  (default values)
+ plus a few kilobytes for small objects. For example, if you want to reduce
+ the default memory requirements from 256K to 128K, compile with
+     make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
+ Of course this will generally degrade compression (there's no free lunch).
+
+   The memory requirements for inflate are (in bytes) 1 << windowBits
+ that is, 32K for windowBits=15 (default value) plus a few kilobytes
+ for small objects.
+*/
+
+                        /* Type declarations */
+
+#ifndef OF /* function prototypes */
+#  ifdef STDC
+#    define OF(args)  args
+#  else
+#    define OF(args)  ()
+#  endif
+#endif
+
+#ifndef Z_ARG /* function prototypes for stdarg */
+#  if defined(STDC) || defined(Z_HAVE_STDARG_H)
+#    define Z_ARG(args)  args
+#  else
+#    define Z_ARG(args)  ()
+#  endif
+#endif
+
+/* The following definitions for FAR are needed only for MSDOS mixed
+ * model programming (small or medium model with some far allocations).
+ * This was tested only with MSC; for other MSDOS compilers you may have
+ * to define NO_MEMCPY in zutil.h.  If you don't need the mixed model,
+ * just define FAR to be empty.
+ */
+#ifdef SYS16BIT
+#  if defined(M_I86SM) || defined(M_I86MM)
+     /* MSC small or medium model */
+#    define SMALL_MEDIUM
+#    ifdef _MSC_VER
+#      define FAR _far
+#    else
+#      define FAR far
+#    endif
+#  endif
+#  if (defined(__SMALL__) || defined(__MEDIUM__))
+     /* Turbo C small or medium model */
+#    define SMALL_MEDIUM
+#    ifdef __BORLANDC__
+#      define FAR _far
+#    else
+#      define FAR far
+#    endif
+#  endif
+#endif
+
+#if defined(WINDOWS) || defined(WIN32)
+   /* If building or using zlib as a DLL, define ZLIB_DLL.
+    * This is not mandatory, but it offers a little performance increase.
+    */
+#  ifdef ZLIB_DLL
+#    if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500))
+#      ifdef ZLIB_INTERNAL
+#        define ZEXTERN extern __declspec(dllexport)
+#      else
+#        define ZEXTERN extern __declspec(dllimport)
+#      endif
+#    endif
+#  endif  /* ZLIB_DLL */
+   /* If building or using zlib with the WINAPI/WINAPIV calling convention,
+    * define ZLIB_WINAPI.
+    * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI.
+    */
+#  ifdef ZLIB_WINAPI
+#    ifdef FAR
+#      undef FAR
+#    endif
+#    include <windows.h>
+     /* No need for _export, use ZLIB.DEF instead. */
+     /* For complete Windows compatibility, use WINAPI, not __stdcall. */
+#    define ZEXPORT WINAPI
+#    ifdef WIN32
+#      define ZEXPORTVA WINAPIV
+#    else
+#      define ZEXPORTVA FAR CDECL
+#    endif
+#  endif
+#endif
+
+#if defined (__BEOS__)
+#  ifdef ZLIB_DLL
+#    ifdef ZLIB_INTERNAL
+#      define ZEXPORT   __declspec(dllexport)
+#      define ZEXPORTVA __declspec(dllexport)
+#    else
+#      define ZEXPORT   __declspec(dllimport)
+#      define ZEXPORTVA __declspec(dllimport)
+#    endif
+#  endif
+#endif
+
+#ifndef ZEXTERN
+#  define ZEXTERN extern
+#endif
+#ifndef ZEXPORT
+#  define ZEXPORT
+#endif
+#ifndef ZEXPORTVA
+#  define ZEXPORTVA
+#endif
+
+#ifndef FAR
+#  define FAR
+#endif
+
+#if !defined(__MACTYPES__)
+typedef unsigned char  Byte;  /* 8 bits */
+#endif
+typedef unsigned int   uInt;  /* 16 bits or more */
+typedef unsigned long  uLong; /* 32 bits or more */
+
+#ifdef SMALL_MEDIUM
+   /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */
+#  define Bytef Byte FAR
+#else
+   typedef Byte  FAR Bytef;
+#endif
+typedef char  FAR charf;
+typedef int   FAR intf;
+typedef uInt  FAR uIntf;
+typedef uLong FAR uLongf;
+
+#ifdef STDC
+   typedef void const *voidpc;
+   typedef void FAR   *voidpf;
+   typedef void       *voidp;
+#else
+   typedef Byte const *voidpc;
+   typedef Byte FAR   *voidpf;
+   typedef Byte       *voidp;
+#endif
+
+#if !defined(Z_U4) && !defined(Z_SOLO) && defined(STDC)
+#  include <limits.h>
+#  if (UINT_MAX == 0xffffffffUL)
+#    define Z_U4 unsigned
+#  elif (ULONG_MAX == 0xffffffffUL)
+#    define Z_U4 unsigned long
+#  elif (USHRT_MAX == 0xffffffffUL)
+#    define Z_U4 unsigned short
+#  endif
+#endif
+
+#ifdef Z_U4
+   typedef Z_U4 z_crc_t;
+#else
+   typedef unsigned long z_crc_t;
+#endif
+
+#ifdef HAVE_UNISTD_H    /* may be set to #if 1 by ./configure */
+#  define Z_HAVE_UNISTD_H
+#endif
+
+#ifdef HAVE_STDARG_H    /* may be set to #if 1 by ./configure */
+#  define Z_HAVE_STDARG_H
+#endif
+
+#ifdef STDC
+#  ifndef Z_SOLO
+#    include <sys/types.h>      /* for off_t */
+#  endif
+#endif
+
+#if defined(STDC) || defined(Z_HAVE_STDARG_H)
+#  ifndef Z_SOLO
+#    include <stdarg.h>         /* for va_list */
+#  endif
+#endif
+
+#ifdef _WIN32
+#  ifndef Z_SOLO
+#    include <stddef.h>         /* for wchar_t */
+#  endif
+#endif
+
+/* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and
+ * "#define _LARGEFILE64_SOURCE 1" as requesting 64-bit operations, (even
+ * though the former does not conform to the LFS document), but considering
+ * both "#undef _LARGEFILE64_SOURCE" and "#define _LARGEFILE64_SOURCE 0" as
+ * equivalently requesting no 64-bit operations
+ */
+#if defined(_LARGEFILE64_SOURCE) && -_LARGEFILE64_SOURCE - -1 == 1
+#  undef _LARGEFILE64_SOURCE
+#endif
+
+#if defined(__WATCOMC__) && !defined(Z_HAVE_UNISTD_H)
+#  define Z_HAVE_UNISTD_H
+#endif
+#ifndef Z_SOLO
+#  if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE)
+#    include <unistd.h>         /* for SEEK_*, off_t, and _LFS64_LARGEFILE */
+#    ifdef VMS
+#      include <unixio.h>       /* for off_t */
+#    endif
+#    ifndef z_off_t
+#      define z_off_t off_t
+#    endif
+#  endif
+#endif
+
+#if defined(_LFS64_LARGEFILE) && _LFS64_LARGEFILE-0
+#  define Z_LFS64
+#endif
+
+#if defined(_LARGEFILE64_SOURCE) && defined(Z_LFS64)
+#  define Z_LARGE64
+#endif
+
+#if defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS-0 == 64 && defined(Z_LFS64)
+#  define Z_WANT64
+#endif
+
+#if !defined(SEEK_SET) && !defined(Z_SOLO)
+#  define SEEK_SET        0       /* Seek from beginning of file.  */
+#  define SEEK_CUR        1       /* Seek from current position.  */
+#  define SEEK_END        2       /* Set file pointer to EOF plus "offset" */
+#endif
+
+#ifndef z_off_t
+#  define z_off_t long
+#endif
+
+#if !defined(_WIN32) && defined(Z_LARGE64)
+#  define z_off64_t off64_t
+#else
+#  if defined(_WIN32) && !defined(__GNUC__) && !defined(Z_SOLO)
+#    define z_off64_t __int64
+#  else
+#    define z_off64_t z_off_t
+#  endif
+#endif
+
+/* MVS linker does not support external names larger than 8 bytes */
+#if defined(__MVS__)
+  #pragma map(deflateInit_,"DEIN")
+  #pragma map(deflateInit2_,"DEIN2")
+  #pragma map(deflateEnd,"DEEND")
+  #pragma map(deflateBound,"DEBND")
+  #pragma map(inflateInit_,"ININ")
+  #pragma map(inflateInit2_,"ININ2")
+  #pragma map(inflateEnd,"INEND")
+  #pragma map(inflateSync,"INSY")
+  #pragma map(inflateSetDictionary,"INSEDI")
+  #pragma map(compressBound,"CMBND")
+  #pragma map(inflate_table,"INTABL")
+  #pragma map(inflate_fast,"INFA")
+  #pragma map(inflate_copyright,"INCOPY")
+#endif
+
+#endif /* ZCONF_H */
diff --git a/compat/zlib/zlib.3 b/compat/zlib/zlib.3
new file mode 100644
index 0000000..0160e62
--- /dev/null
+++ b/compat/zlib/zlib.3
@@ -0,0 +1,151 @@
+.TH ZLIB 3 "28 Apr 2013"
+.SH NAME
+zlib \- compression/decompression library
+.SH SYNOPSIS
+[see
+.I zlib.h
+for full description]
+.SH DESCRIPTION
+The
+.I zlib
+library is a general purpose data compression library.
+The code is thread safe, assuming that the standard library functions
+used are thread safe, such as memory allocation routines.
+It provides in-memory compression and decompression functions,
+including integrity checks of the uncompressed data.
+This version of the library supports only one compression method (deflation)
+but other algorithms may be added later
+with the same stream interface.
+.LP
+Compression can be done in a single step if the buffers are large enough
+or can be done by repeated calls of the compression function.
+In the latter case,
+the application must provide more input and/or consume the output
+(providing more output space) before each call.
+.LP
+The library also supports reading and writing files in
+.IR gzip (1)
+(.gz) format
+with an interface similar to that of stdio.
+.LP
+The library does not install any signal handler.
+The decoder checks the consistency of the compressed data,
+so the library should never crash even in the case of corrupted input.
+.LP
+All functions of the compression library are documented in the file
+.IR zlib.h .
+The distribution source includes examples of use of the library
+in the files
+.I test/example.c
+and
+.IR test/minigzip.c,
+as well as other examples in the
+.IR examples/
+directory.
+.LP
+Changes to this version are documented in the file
+.I ChangeLog
+that accompanies the source.
+.LP
+.I zlib
+is available in Java using the java.util.zip package:
+.IP
+http://java.sun.com/developer/technicalArticles/Programming/compression/
+.LP
+A Perl interface to
+.IR zlib ,
+written by Paul Marquess (pmqs@cpan.org),
+is available at CPAN (Comprehensive Perl Archive Network) sites,
+including:
+.IP
+http://search.cpan.org/~pmqs/IO-Compress-Zlib/
+.LP
+A Python interface to
+.IR zlib ,
+written by A.M. Kuchling (amk@magnet.com),
+is available in Python 1.5 and later versions:
+.IP
+http://docs.python.org/library/zlib.html
+.LP
+.I zlib
+is built into
+.IR tcl:
+.IP
+http://wiki.tcl.tk/4610
+.LP
+An experimental package to read and write files in .zip format,
+written on top of
+.I zlib
+by Gilles Vollant (info@winimage.com),
+is available at:
+.IP
+http://www.winimage.com/zLibDll/minizip.html
+and also in the
+.I contrib/minizip
+directory of the main
+.I zlib
+source distribution.
+.SH "SEE ALSO"
+The
+.I zlib
+web site can be found at:
+.IP
+http://zlib.net/
+.LP
+The data format used by the zlib library is described by RFC
+(Request for Comments) 1950 to 1952 in the files:
+.IP
+http://tools.ietf.org/html/rfc1950 (for the zlib header and trailer format)
+.br
+http://tools.ietf.org/html/rfc1951 (for the deflate compressed data format)
+.br
+http://tools.ietf.org/html/rfc1952 (for the gzip header and trailer format)
+.LP
+Mark Nelson wrote an article about
+.I zlib
+for the Jan. 1997 issue of  Dr. Dobb's Journal;
+a copy of the article is available at:
+.IP
+http://marknelson.us/1997/01/01/zlib-engine/
+.SH "REPORTING PROBLEMS"
+Before reporting a problem,
+please check the
+.I zlib
+web site to verify that you have the latest version of
+.IR zlib ;
+otherwise,
+obtain the latest version and see if the problem still exists.
+Please read the
+.I zlib
+FAQ at:
+.IP
+http://zlib.net/zlib_faq.html
+.LP
+before asking for help.
+Send questions and/or comments to zlib@gzip.org,
+or (for the Windows DLL version) to Gilles Vollant (info@winimage.com).
+.SH AUTHORS
+Version 1.2.8
+Copyright (C) 1995-2013 Jean-loup Gailly (jloup@gzip.org)
+and Mark Adler (madler@alumni.caltech.edu).
+.LP
+This software is provided "as-is,"
+without any express or implied warranty.
+In no event will the authors be held liable for any damages
+arising from the use of this software.
+See the distribution directory with respect to requirements
+governing redistribution.
+The deflate format used by
+.I zlib
+was defined by Phil Katz.
+The deflate and
+.I zlib
+specifications were written by L. Peter Deutsch.
+Thanks to all the people who reported problems and suggested various
+improvements in
+.IR zlib ;
+who are too numerous to cite here.
+.LP
+UNIX manual page by R. P. C. Rodgers,
+U.S. National Library of Medicine (rodgers@nlm.nih.gov).
+.\" end of man page
diff --git a/compat/zlib/zlib.3.pdf b/compat/zlib/zlib.3.pdf
new file mode 100644
index 0000000..a346b5d
Binary files /dev/null and b/compat/zlib/zlib.3.pdf differ
diff --git a/compat/zlib/zlib.h b/compat/zlib/zlib.h
new file mode 100644
index 0000000..3e0c767
--- /dev/null
+++ b/compat/zlib/zlib.h
@@ -0,0 +1,1768 @@
+/* zlib.h -- interface of the 'zlib' general purpose compression library
+  version 1.2.8, April 28th, 2013
+
+  Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler
+
+  This software is provided 'as-is', without any express or implied
+  warranty.  In no event will the authors be held liable for any damages
+  arising from the use of this software.
+
+  Permission is granted to anyone to use this software for any purpose,
+  including commercial applications, and to alter it and redistribute it
+  freely, subject to the following restrictions:
+
+  1. The origin of this software must not be misrepresented; you must not
+     claim that you wrote the original software. If you use this software
+     in a product, an acknowledgment in the product documentation would be
+     appreciated but is not required.
+  2. Altered source versions must be plainly marked as such, and must not be
+     misrepresented as being the original software.
+  3. This notice may not be removed or altered from any source distribution.
+
+  Jean-loup Gailly        Mark Adler
+  jloup@gzip.org          madler@alumni.caltech.edu
+
+
+  The data format used by the zlib library is described by RFCs (Request for
+  Comments) 1950 to 1952 in the files http://tools.ietf.org/html/rfc1950
+  (zlib format), rfc1951 (deflate format) and rfc1952 (gzip format).
+*/
+
+#ifndef ZLIB_H
+#define ZLIB_H
+
+#include "zconf.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define ZLIB_VERSION "1.2.8"
+#define ZLIB_VERNUM 0x1280
+#define ZLIB_VER_MAJOR 1
+#define ZLIB_VER_MINOR 2
+#define ZLIB_VER_REVISION 8
+#define ZLIB_VER_SUBREVISION 0
+
+/*
+    The 'zlib' compression library provides in-memory compression and
+  decompression functions, including integrity checks of the uncompressed data.
+  This version of the library supports only one compression method (deflation)
+  but other algorithms will be added later and will have the same stream
+  interface.
+
+    Compression can be done in a single step if the buffers are large enough,
+  or can be done by repeated calls of the compression function.  In the latter
+  case, the application must provide more input and/or consume the output
+  (providing more output space) before each call.
+
+    The compressed data format used by default by the in-memory functions is
+  the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped
+  around a deflate stream, which is itself documented in RFC 1951.
+
+    The library also supports reading and writing files in gzip (.gz) format
+  with an interface similar to that of stdio using the functions that start
+  with "gz".  The gzip format is different from the zlib format.  gzip is a
+  gzip wrapper, documented in RFC 1952, wrapped around a deflate stream.
+
+    This library can optionally read and write gzip streams in memory as well.
+
+    The zlib format was designed to be compact and fast for use in memory
+  and on communications channels.  The gzip format was designed for single-
+  file compression on file systems, has a larger header than zlib to maintain
+  directory information, and uses a different, slower check method than zlib.
+
+    The library does not install any signal handler.  The decoder checks
+  the consistency of the compressed data, so the library should never crash
+  even in case of corrupted input.
+*/
+
+typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size));
+typedef void   (*free_func)  OF((voidpf opaque, voidpf address));
+
+struct internal_state;
+
+typedef struct z_stream_s {
+    z_const Bytef *next_in;     /* next input byte */
+    uInt     avail_in;  /* number of bytes available at next_in */
+    uLong    total_in;  /* total number of input bytes read so far */
+
+    Bytef    *next_out; /* next output byte should be put there */
+    uInt     avail_out; /* remaining free space at next_out */
+    uLong    total_out; /* total number of bytes output so far */
+
+    z_const char *msg;  /* last error message, NULL if no error */
+    struct internal_state FAR *state; /* not visible by applications */
+
+    alloc_func zalloc;  /* used to allocate the internal state */
+    free_func  zfree;   /* used to free the internal state */
+    voidpf     opaque;  /* private data object passed to zalloc and zfree */
+
+    int     data_type;  /* best guess about the data type: binary or text */
+    uLong   adler;      /* adler32 value of the uncompressed data */
+    uLong   reserved;   /* reserved for future use */
+} z_stream;
+
+typedef z_stream FAR *z_streamp;
+
+/*
+     gzip header information passed to and from zlib routines.  See RFC 1952
+  for more details on the meanings of these fields.
+*/
+typedef struct gz_header_s {
+    int     text;       /* true if compressed data believed to be text */
+    uLong   time;       /* modification time */
+    int     xflags;     /* extra flags (not used when writing a gzip file) */
+    int     os;         /* operating system */
+    Bytef   *extra;     /* pointer to extra field or Z_NULL if none */
+    uInt    extra_len;  /* extra field length (valid if extra != Z_NULL) */
+    uInt    extra_max;  /* space at extra (only when reading header) */
+    Bytef   *name;      /* pointer to zero-terminated file name or Z_NULL */
+    uInt    name_max;   /* space at name (only when reading header) */
+    Bytef   *comment;   /* pointer to zero-terminated comment or Z_NULL */
+    uInt    comm_max;   /* space at comment (only when reading header) */
+    int     hcrc;       /* true if there was or will be a header crc */
+    int     done;       /* true when done reading gzip header (not used
+                           when writing a gzip file) */
+} gz_header;
+
+typedef gz_header FAR *gz_headerp;
+
+/*
+     The application must update next_in and avail_in when avail_in has dropped
+   to zero.  It must update next_out and avail_out when avail_out has dropped
+   to zero.  The application must initialize zalloc, zfree and opaque before
+   calling the init function.  All other fields are set by the compression
+   library and must not be updated by the application.
+
+     The opaque value provided by the application will be passed as the first
+   parameter for calls of zalloc and zfree.  This can be useful for custom
+   memory management.  The compression library attaches no meaning to the
+   opaque value.
+
+     zalloc must return Z_NULL if there is not enough memory for the object.
+   If zlib is used in a multi-threaded application, zalloc and zfree must be
+   thread safe.
+
+     On 16-bit systems, the functions zalloc and zfree must be able to allocate
+   exactly 65536 bytes, but will not be required to allocate more than this if
+   the symbol MAXSEG_64K is defined (see zconf.h).  WARNING: On MSDOS, pointers
+   returned by zalloc for objects of exactly 65536 bytes *must* have their
+   offset normalized to zero.  The default allocation function provided by this
+   library ensures this (see zutil.c).  To reduce memory requirements and avoid
+   any allocation of 64K objects, at the expense of compression ratio, compile
+   the library with -DMAX_WBITS=14 (see zconf.h).
+
+     The fields total_in and total_out can be used for statistics or progress
+   reports.  After compression, total_in holds the total size of the
+   uncompressed data and may be saved for use in the decompressor (particularly
+   if the decompressor wants to decompress everything in a single step).
+*/
+
+                        /* constants */
+
+#define Z_NO_FLUSH      0
+#define Z_PARTIAL_FLUSH 1
+#define Z_SYNC_FLUSH    2
+#define Z_FULL_FLUSH    3
+#define Z_FINISH        4
+#define Z_BLOCK         5
+#define Z_TREES         6
+/* Allowed flush values; see deflate() and inflate() below for details */
+
+#define Z_OK            0
+#define Z_STREAM_END    1
+#define Z_NEED_DICT     2
+#define Z_ERRNO        (-1)
+#define Z_STREAM_ERROR (-2)
+#define Z_DATA_ERROR   (-3)
+#define Z_MEM_ERROR    (-4)
+#define Z_BUF_ERROR    (-5)
+#define Z_VERSION_ERROR (-6)
+/* Return codes for the compression/decompression functions. Negative values
+ * are errors, positive values are used for special but normal events.
+ */
+
+#define Z_NO_COMPRESSION         0
+#define Z_BEST_SPEED             1
+#define Z_BEST_COMPRESSION       9
+#define Z_DEFAULT_COMPRESSION  (-1)
+/* compression levels */
+
+#define Z_FILTERED            1
+#define Z_HUFFMAN_ONLY        2
+#define Z_RLE                 3
+#define Z_FIXED               4
+#define Z_DEFAULT_STRATEGY    0
+/* compression strategy; see deflateInit2() below for details */
+
+#define Z_BINARY   0
+#define Z_TEXT     1
+#define Z_ASCII    Z_TEXT   /* for compatibility with 1.2.2 and earlier */
+#define Z_UNKNOWN  2
+/* Possible values of the data_type field (though see inflate()) */
+
+#define Z_DEFLATED   8
+/* The deflate compression method (the only one supported in this version) */
+
+#define Z_NULL  0  /* for initializing zalloc, zfree, opaque */
+
+#define zlib_version zlibVersion()
+/* for compatibility with versions < 1.0.2 */
+
+
+                        /* basic functions */
+
+ZEXTERN const char * ZEXPORT zlibVersion OF((void));
+/* The application can compare zlibVersion and ZLIB_VERSION for consistency.
+   If the first character differs, the library code actually used is not
+   compatible with the zlib.h header file used by the application.  This check
+   is automatically made by deflateInit and inflateInit.
+ */
+
+/*
+ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level));
+
+     Initializes the internal stream state for compression.  The fields
+   zalloc, zfree and opaque must be initialized before by the caller.  If
+   zalloc and zfree are set to Z_NULL, deflateInit updates them to use default
+   allocation functions.
+
+     The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9:
+   1 gives best speed, 9 gives best compression, 0 gives no compression at all
+   (the input data is simply copied a block at a time).  Z_DEFAULT_COMPRESSION
+   requests a default compromise between speed and compression (currently
+   equivalent to level 6).
+
+     deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough
+   memory, Z_STREAM_ERROR if level is not a valid compression level, or
+   Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible
+   with the version assumed by the caller (ZLIB_VERSION).  msg is set to null
+   if there is no error message.  deflateInit does not perform any compression:
+   this will be done by deflate().
+*/
+
+
+ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush));
+/*
+    deflate compresses as much data as possible, and stops when the input
+  buffer becomes empty or the output buffer becomes full.  It may introduce
+  some output latency (reading input without producing any output) except when
+  forced to flush.
+
+    The detailed semantics are as follows.  deflate performs one or both of the
+  following actions:
+
+  - Compress more input starting at next_in and update next_in and avail_in
+    accordingly.  If not all input can be processed (because there is not
+    enough room in the output buffer), next_in and avail_in are updated and
+    processing will resume at this point for the next call of deflate().
+
+  - Provide more output starting at next_out and update next_out and avail_out
+    accordingly.  This action is forced if the parameter flush is non zero.
+    Forcing flush frequently degrades the compression ratio, so this parameter
+    should be set only when necessary (in interactive applications).  Some
+    output may be provided even if flush is not set.
+
+    Before the call of deflate(), the application should ensure that at least
+  one of the actions is possible, by providing more input and/or consuming more
+  output, and updating avail_in or avail_out accordingly; avail_out should
+  never be zero before the call.  The application can consume the compressed
+  output when it wants, for example when the output buffer is full (avail_out
+  == 0), or after each call of deflate().  If deflate returns Z_OK and with
+  zero avail_out, it must be called again after making room in the output
+  buffer because there might be more output pending.
+
+    Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to
+  decide how much data to accumulate before producing output, in order to
+  maximize compression.
+
+    If the parameter flush is set to Z_SYNC_FLUSH, all pending output is
+  flushed to the output buffer and the output is aligned on a byte boundary, so
+  that the decompressor can get all input data available so far.  (In
+  particular avail_in is zero after the call if enough output space has been
+  provided before the call.) Flushing may degrade compression for some
+  compression algorithms and so it should be used only when necessary.  This
+  completes the current deflate block and follows it with an empty stored block
+  that is three bits plus filler bits to the next byte, followed by four bytes
+  (00 00 ff ff).
+
+    If flush is set to Z_PARTIAL_FLUSH, all pending output is flushed to the
+  output buffer, but the output is not aligned to a byte boundary.  All of the
+  input data so far will be available to the decompressor, as for Z_SYNC_FLUSH.
+  This completes the current deflate block and follows it with an empty fixed
+  codes block that is 10 bits long.  This assures that enough bytes are output
+  in order for the decompressor to finish the block before the empty fixed code
+  block.
+
+    If flush is set to Z_BLOCK, a deflate block is completed and emitted, as
+  for Z_SYNC_FLUSH, but the output is not aligned on a byte boundary, and up to
+  seven bits of the current block are held to be written as the next byte after
+  the next deflate block is completed.  In this case, the decompressor may not
+  be provided enough bits at this point in order to complete decompression of
+  the data provided so far to the compressor.  It may need to wait for the next
+  block to be emitted.  This is for advanced applications that need to control
+  the emission of deflate blocks.
+
+    If flush is set to Z_FULL_FLUSH, all output is flushed as with
+  Z_SYNC_FLUSH, and the compression state is reset so that decompression can
+  restart from this point if previous compressed data has been damaged or if
+  random access is desired.  Using Z_FULL_FLUSH too often can seriously degrade
+  compression.
+
+    If deflate returns with avail_out == 0, this function must be called again
+  with the same value of the flush parameter and more output space (updated
+  avail_out), until the flush is complete (deflate returns with non-zero
+  avail_out).  In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that
+  avail_out is greater than six to avoid repeated flush markers due to
+  avail_out == 0 on return.
+
+    If the parameter flush is set to Z_FINISH, pending input is processed,
+  pending output is flushed and deflate returns with Z_STREAM_END if there was
+  enough output space; if deflate returns with Z_OK, this function must be
+  called again with Z_FINISH and more output space (updated avail_out) but no
+  more input data, until it returns with Z_STREAM_END or an error.  After
+  deflate has returned Z_STREAM_END, the only possible operations on the stream
+  are deflateReset or deflateEnd.
+
+    Z_FINISH can be used immediately after deflateInit if all the compression
+  is to be done in a single step.  In this case, avail_out must be at least the
+  value returned by deflateBound (see below).  Then deflate is guaranteed to
+  return Z_STREAM_END.  If not enough output space is provided, deflate will
+  not return Z_STREAM_END, and it must be called again as described above.
+
+    deflate() sets strm->adler to the adler32 checksum of all input read
+  so far (that is, total_in bytes).
+
+    deflate() may update strm->data_type if it can make a good guess about
+  the input data type (Z_BINARY or Z_TEXT).  In doubt, the data is considered
+  binary.  This field is only for information purposes and does not affect the
+  compression algorithm in any manner.
+
+    deflate() returns Z_OK if some progress has been made (more input
+  processed or more output produced), Z_STREAM_END if all input has been
+  consumed and all output has been produced (only when flush is set to
+  Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example
+  if next_in or next_out was Z_NULL), Z_BUF_ERROR if no progress is possible
+  (for example avail_in or avail_out was zero).  Note that Z_BUF_ERROR is not
+  fatal, and deflate() can be called again with more input and more output
+  space to continue compressing.
+*/
+
+
+ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm));
+/*
+     All dynamically allocated data structures for this stream are freed.
+   This function discards any unprocessed input and does not flush any pending
+   output.
+
+     deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the
+   stream state was inconsistent, Z_DATA_ERROR if the stream was freed
+   prematurely (some input or output was discarded).  In the error case, msg
+   may be set but then points to a static string (which must not be
+   deallocated).
+*/
+
+
+/*
+ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm));
+
+     Initializes the internal stream state for decompression.  The fields
+   next_in, avail_in, zalloc, zfree and opaque must be initialized before by
+   the caller.  If next_in is not Z_NULL and avail_in is large enough (the
+   exact value depends on the compression method), inflateInit determines the
+   compression method from the zlib header and allocates all data structures
+   accordingly; otherwise the allocation will be deferred to the first call of
+   inflate.  If zalloc and zfree are set to Z_NULL, inflateInit updates them to
+   use default allocation functions.
+
+     inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough
+   memory, Z_VERSION_ERROR if the zlib library version is incompatible with the
+   version assumed by the caller, or Z_STREAM_ERROR if the parameters are
+   invalid, such as a null pointer to the structure.  msg is set to null if
+   there is no error message.  inflateInit does not perform any decompression
+   apart from possibly reading the zlib header if present: actual decompression
+   will be done by inflate().  (So next_in and avail_in may be modified, but
+   next_out and avail_out are unused and unchanged.) The current implementation
+   of inflateInit() does not process any header information -- that is deferred
+   until inflate() is called.
+*/
+
+
+ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush));
+/*
+    inflate decompresses as much data as possible, and stops when the input
+  buffer becomes empty or the output buffer becomes full.  It may introduce
+  some output latency (reading input without producing any output) except when
+  forced to flush.
+
+  The detailed semantics are as follows.  inflate performs one or both of the
+  following actions:
+
+  - Decompress more input starting at next_in and update next_in and avail_in
+    accordingly.  If not all input can be processed (because there is not
+    enough room in the output buffer), next_in is updated and processing will
+    resume at this point for the next call of inflate().
+
+  - Provide more output starting at next_out and update next_out and avail_out
+    accordingly.  inflate() provides as much output as possible, until there is
+    no more input data or no more space in the output buffer (see below about
+    the flush parameter).
+
+    Before the call of inflate(), the application should ensure that at least
+  one of the actions is possible, by providing more input and/or consuming more
+  output, and updating the next_* and avail_* values accordingly.  The
+  application can consume the uncompressed output when it wants, for example
+  when the output buffer is full (avail_out == 0), or after each call of
+  inflate().  If inflate returns Z_OK and with zero avail_out, it must be
+  called again after making room in the output buffer because there might be
+  more output pending.
+
+    The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH, Z_FINISH,
+  Z_BLOCK, or Z_TREES.  Z_SYNC_FLUSH requests that inflate() flush as much
+  output as possible to the output buffer.  Z_BLOCK requests that inflate()
+  stop if and when it gets to the next deflate block boundary.  When decoding
+  the zlib or gzip format, this will cause inflate() to return immediately
+  after the header and before the first block.  When doing a raw inflate,
+  inflate() will go ahead and process the first block, and will return when it
+  gets to the end of that block, or when it runs out of data.
+
+    The Z_BLOCK option assists in appending to or combining deflate streams.
+  Also to assist in this, on return inflate() will set strm->data_type to the
+  number of unused bits in the last byte taken from strm->next_in, plus 64 if
+  inflate() is currently decoding the last block in the deflate stream, plus
+  128 if inflate() returned immediately after decoding an end-of-block code or
+  decoding the complete header up to just before the first byte of the deflate
+  stream.  The end-of-block will not be indicated until all of the uncompressed
+  data from that block has been written to strm->next_out.  The number of
+  unused bits may in general be greater than seven, except when bit 7 of
+  data_type is set, in which case the number of unused bits will be less than
+  eight.  data_type is set as noted here every time inflate() returns for all
+  flush options, and so can be used to determine the amount of currently
+  consumed input in bits.
+
+    The Z_TREES option behaves as Z_BLOCK does, but it also returns when the
+  end of each deflate block header is reached, before any actual data in that
+  block is decoded.  This allows the caller to determine the length of the
+  deflate block header for later use in random access within a deflate block.
+  256 is added to the value of strm->data_type when inflate() returns
+  immediately after reaching the end of the deflate block header.
+
+    inflate() should normally be called until it returns Z_STREAM_END or an
+  error.  However if all decompression is to be performed in a single step (a
+  single call of inflate), the parameter flush should be set to Z_FINISH.  In
+  this case all pending input is processed and all pending output is flushed;
+  avail_out must be large enough to hold all of the uncompressed data for the
+  operation to complete.  (The size of the uncompressed data may have been
+  saved by the compressor for this purpose.) The use of Z_FINISH is not
+  required to perform an inflation in one step.  However it may be used to
+  inform inflate that a faster approach can be used for the single inflate()
+  call.  Z_FINISH also informs inflate to not maintain a sliding window if the
+  stream completes, which reduces inflate's memory footprint.  If the stream
+  does not complete, either because not all of the stream is provided or not
+  enough output space is provided, then a sliding window will be allocated and
+  inflate() can be called again to continue the operation as if Z_NO_FLUSH had
+  been used.
+
+     In this implementation, inflate() always flushes as much output as
+  possible to the output buffer, and always uses the faster approach on the
+  first call.  So the effects of the flush parameter in this implementation are
+  on the return value of inflate() as noted below, when inflate() returns early
+  when Z_BLOCK or Z_TREES is used, and when inflate() avoids the allocation of
+  memory for a sliding window when Z_FINISH is used.
+
+     If a preset dictionary is needed after this call (see inflateSetDictionary
+  below), inflate sets strm->adler to the Adler-32 checksum of the dictionary
+  chosen by the compressor and returns Z_NEED_DICT; otherwise it sets
+  strm->adler to the Adler-32 checksum of all output produced so far (that is,
+  total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described
+  below.  At the end of the stream, inflate() checks that its computed adler32
+  checksum is equal to that saved by the compressor and returns Z_STREAM_END
+  only if the checksum is correct.
+
+    inflate() can decompress and check either zlib-wrapped or gzip-wrapped
+  deflate data.  The header type is detected automatically, if requested when
+  initializing with inflateInit2().  Any information contained in the gzip
+  header is not retained, so applications that need that information should
+  instead use raw inflate, see inflateInit2() below, or inflateBack() and
+  perform their own processing of the gzip header and trailer.  When processing
+  gzip-wrapped deflate data, strm->adler32 is set to the CRC-32 of the output
+  producted so far.  The CRC-32 is checked against the gzip trailer.
+
+    inflate() returns Z_OK if some progress has been made (more input processed
+  or more output produced), Z_STREAM_END if the end of the compressed data has
+  been reached and all uncompressed output has been produced, Z_NEED_DICT if a
+  preset dictionary is needed at this point, Z_DATA_ERROR if the input data was
+  corrupted (input stream not conforming to the zlib format or incorrect check
+  value), Z_STREAM_ERROR if the stream structure was inconsistent (for example
+  next_in or next_out was Z_NULL), Z_MEM_ERROR if there was not enough memory,
+  Z_BUF_ERROR if no progress is possible or if there was not enough room in the
+  output buffer when Z_FINISH is used.  Note that Z_BUF_ERROR is not fatal, and
+  inflate() can be called again with more input and more output space to
+  continue decompressing.  If Z_DATA_ERROR is returned, the application may
+  then call inflateSync() to look for a good compression block if a partial
+  recovery of the data is desired.
+*/
+
+
+ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm));
+/*
+     All dynamically allocated data structures for this stream are freed.
+   This function discards any unprocessed input and does not flush any pending
+   output.
+
+     inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state
+   was inconsistent.  In the error case, msg may be set but then points to a
+   static string (which must not be deallocated).
+*/
+
+
+                        /* Advanced functions */
+
+/*
+    The following functions are needed only in some special applications.
+*/
+
+/*
+ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm,
+                                     int  level,
+                                     int  method,
+                                     int  windowBits,
+                                     int  memLevel,
+                                     int  strategy));
+
+     This is another version of deflateInit with more compression options.  The
+   fields next_in, zalloc, zfree and opaque must be initialized before by the
+   caller.
+
+     The method parameter is the compression method.  It must be Z_DEFLATED in
+   this version of the library.
+
+     The windowBits parameter is the base two logarithm of the window size
+   (the size of the history buffer).  It should be in the range 8..15 for this
+   version of the library.  Larger values of this parameter result in better
+   compression at the expense of memory usage.  The default value is 15 if
+   deflateInit is used instead.
+
+     windowBits can also be -8..-15 for raw deflate.  In this case, -windowBits
+   determines the window size.  deflate() will then generate raw deflate data
+   with no zlib header or trailer, and will not compute an adler32 check value.
+
+     windowBits can also be greater than 15 for optional gzip encoding.  Add
+   16 to windowBits to write a simple gzip header and trailer around the
+   compressed data instead of a zlib wrapper.  The gzip header will have no
+   file name, no extra data, no comment, no modification time (set to zero), no
+   header crc, and the operating system will be set to 255 (unknown).  If a
+   gzip stream is being written, strm->adler is a crc32 instead of an adler32.
+
+     The memLevel parameter specifies how much memory should be allocated
+   for the internal compression state.  memLevel=1 uses minimum memory but is
+   slow and reduces compression ratio; memLevel=9 uses maximum memory for
+   optimal speed.  The default value is 8.  See zconf.h for total memory usage
+   as a function of windowBits and memLevel.
+
+     The strategy parameter is used to tune the compression algorithm.  Use the
+   value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a
+   filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no
+   string match), or Z_RLE to limit match distances to one (run-length
+   encoding).  Filtered data consists mostly of small values with a somewhat
+   random distribution.  In this case, the compression algorithm is tuned to
+   compress them better.  The effect of Z_FILTERED is to force more Huffman
+   coding and less string matching; it is somewhat intermediate between
+   Z_DEFAULT_STRATEGY and Z_HUFFMAN_ONLY.  Z_RLE is designed to be almost as
+   fast as Z_HUFFMAN_ONLY, but give better compression for PNG image data.  The
+   strategy parameter only affects the compression ratio but not the
+   correctness of the compressed output even if it is not set appropriately.
+   Z_FIXED prevents the use of dynamic Huffman codes, allowing for a simpler
+   decoder for special applications.
+
+     deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
+   memory, Z_STREAM_ERROR if any parameter is invalid (such as an invalid
+   method), or Z_VERSION_ERROR if the zlib library version (zlib_version) is
+   incompatible with the version assumed by the caller (ZLIB_VERSION).  msg is
+   set to null if there is no error message.  deflateInit2 does not perform any
+   compression: this will be done by deflate().
+*/
+
+ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm,
+                                             const Bytef *dictionary,
+                                             uInt  dictLength));
+/*
+     Initializes the compression dictionary from the given byte sequence
+   without producing any compressed output.  When using the zlib format, this
+   function must be called immediately after deflateInit, deflateInit2 or
+   deflateReset, and before any call of deflate.  When doing raw deflate, this
+   function must be called either before any call of deflate, or immediately
+   after the completion of a deflate block, i.e. after all input has been
+   consumed and all output has been delivered when using any of the flush
+   options Z_BLOCK, Z_PARTIAL_FLUSH, Z_SYNC_FLUSH, or Z_FULL_FLUSH.  The
+   compressor and decompressor must use exactly the same dictionary (see
+   inflateSetDictionary).
+
+     The dictionary should consist of strings (byte sequences) that are likely
+   to be encountered later in the data to be compressed, with the most commonly
+   used strings preferably put towards the end of the dictionary.  Using a
+   dictionary is most useful when the data to be compressed is short and can be
+   predicted with good accuracy; the data can then be compressed better than
+   with the default empty dictionary.
+
+     Depending on the size of the compression data structures selected by
+   deflateInit or deflateInit2, a part of the dictionary may in effect be
+   discarded, for example if the dictionary is larger than the window size
+   provided in deflateInit or deflateInit2.  Thus the strings most likely to be
+   useful should be put at the end of the dictionary, not at the front.  In
+   addition, the current implementation of deflate will use at most the window
+   size minus 262 bytes of the provided dictionary.
+
+     Upon return of this function, strm->adler is set to the adler32 value
+   of the dictionary; the decompressor may later use this value to determine
+   which dictionary has been used by the compressor.  (The adler32 value
+   applies to the whole dictionary even if only a subset of the dictionary is
+   actually used by the compressor.) If a raw deflate was requested, then the
+   adler32 value is not computed and strm->adler is not set.
+
+     deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a
+   parameter is invalid (e.g.  dictionary being Z_NULL) or the stream state is
+   inconsistent (for example if deflate has already been called for this stream
+   or if not at a block boundary for raw deflate).  deflateSetDictionary does
+   not perform any compression: this will be done by deflate().
+*/
+
+ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest,
+                                    z_streamp source));
+/*
+     Sets the destination stream as a complete copy of the source stream.
+
+     This function can be useful when several compression strategies will be
+   tried, for example when there are several ways of pre-processing the input
+   data with a filter.  The streams that will be discarded should then be freed
+   by calling deflateEnd.  Note that deflateCopy duplicates the internal
+   compression state which can be quite large, so this strategy is slow and can
+   consume lots of memory.
+
+     deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
+   enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
+   (such as zalloc being Z_NULL).  msg is left unchanged in both source and
+   destination.
+*/
+
+ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm));
+/*
+     This function is equivalent to deflateEnd followed by deflateInit,
+   but does not free and reallocate all the internal compression state.  The
+   stream will keep the same compression level and any other attributes that
+   may have been set by deflateInit2.
+
+     deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
+   stream state was inconsistent (such as zalloc or state being Z_NULL).
+*/
+
+ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm,
+                                      int level,
+                                      int strategy));
+/*
+     Dynamically update the compression level and compression strategy.  The
+   interpretation of level and strategy is as in deflateInit2.  This can be
+   used to switch between compression and straight copy of the input data, or
+   to switch to a different kind of input data requiring a different strategy.
+   If the compression level is changed, the input available so far is
+   compressed with the old level (and may be flushed); the new level will take
+   effect only at the next call of deflate().
+
+     Before the call of deflateParams, the stream state must be set as for
+   a call of deflate(), since the currently available input may have to be
+   compressed and flushed.  In particular, strm->avail_out must be non-zero.
+
+     deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source
+   stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR if
+   strm->avail_out was zero.
+*/
+
+ZEXTERN int ZEXPORT deflateTune OF((z_streamp strm,
+                                    int good_length,
+                                    int max_lazy,
+                                    int nice_length,
+                                    int max_chain));
+/*
+     Fine tune deflate's internal compression parameters.  This should only be
+   used by someone who understands the algorithm used by zlib's deflate for
+   searching for the best matching string, and even then only by the most
+   fanatic optimizer trying to squeeze out the last compressed bit for their
+   specific input data.  Read the deflate.c source code for the meaning of the
+   max_lazy, good_length, nice_length, and max_chain parameters.
+
+     deflateTune() can be called after deflateInit() or deflateInit2(), and
+   returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream.
+ */
+
+ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm,
+                                       uLong sourceLen));
+/*
+     deflateBound() returns an upper bound on the compressed size after
+   deflation of sourceLen bytes.  It must be called after deflateInit() or
+   deflateInit2(), and after deflateSetHeader(), if used.  This would be used
+   to allocate an output buffer for deflation in a single pass, and so would be
+   called before deflate().  If that first deflate() call is provided the
+   sourceLen input bytes, an output buffer allocated to the size returned by
+   deflateBound(), and the flush value Z_FINISH, then deflate() is guaranteed
+   to return Z_STREAM_END.  Note that it is possible for the compressed size to
+   be larger than the value returned by deflateBound() if flush options other
+   than Z_FINISH or Z_NO_FLUSH are used.
+*/
+
+ZEXTERN int ZEXPORT deflatePending OF((z_streamp strm,
+                                       unsigned *pending,
+                                       int *bits));
+/*
+     deflatePending() returns the number of bytes and bits of output that have
+   been generated, but not yet provided in the available output.  The bytes not
+   provided would be due to the available output space having being consumed.
+   The number of bits of output not provided are between 0 and 7, where they
+   await more bits to join them in order to fill out a full byte.  If pending
+   or bits are Z_NULL, then those values are not set.
+
+     deflatePending returns Z_OK if success, or Z_STREAM_ERROR if the source
+   stream state was inconsistent.
+ */
+
+ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm,
+                                     int bits,
+                                     int value));
+/*
+     deflatePrime() inserts bits in the deflate output stream.  The intent
+   is that this function is used to start off the deflate output with the bits
+   leftover from a previous deflate stream when appending to it.  As such, this
+   function can only be used for raw deflate, and must be used before the first
+   deflate() call after a deflateInit2() or deflateReset().  bits must be less
+   than or equal to 16, and that many of the least significant bits of value
+   will be inserted in the output.
+
+     deflatePrime returns Z_OK if success, Z_BUF_ERROR if there was not enough
+   room in the internal buffer to insert the bits, or Z_STREAM_ERROR if the
+   source stream state was inconsistent.
+*/
+
+ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm,
+                                         gz_headerp head));
+/*
+     deflateSetHeader() provides gzip header information for when a gzip
+   stream is requested by deflateInit2().  deflateSetHeader() may be called
+   after deflateInit2() or deflateReset() and before the first call of
+   deflate().  The text, time, os, extra field, name, and comment information
+   in the provided gz_header structure are written to the gzip header (xflag is
+   ignored -- the extra flags are set according to the compression level).  The
+   caller must assure that, if not Z_NULL, name and comment are terminated with
+   a zero byte, and that if extra is not Z_NULL, that extra_len bytes are
+   available there.  If hcrc is true, a gzip header crc is included.  Note that
+   the current versions of the command-line version of gzip (up through version
+   1.3.x) do not support header crc's, and will report that it is a "multi-part
+   gzip file" and give up.
+
+     If deflateSetHeader is not used, the default gzip header has text false,
+   the time set to zero, and os set to 255, with no extra, name, or comment
+   fields.  The gzip header is returned to the default state by deflateReset().
+
+     deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source
+   stream state was inconsistent.
+*/
+
+/*
+ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm,
+                                     int  windowBits));
+
+     This is another version of inflateInit with an extra parameter.  The
+   fields next_in, avail_in, zalloc, zfree and opaque must be initialized
+   before by the caller.
+
+     The windowBits parameter is the base two logarithm of the maximum window
+   size (the size of the history buffer).  It should be in the range 8..15 for
+   this version of the library.  The default value is 15 if inflateInit is used
+   instead.  windowBits must be greater than or equal to the windowBits value
+   provided to deflateInit2() while compressing, or it must be equal to 15 if
+   deflateInit2() was not used.  If a compressed stream with a larger window
+   size is given as input, inflate() will return with the error code
+   Z_DATA_ERROR instead of trying to allocate a larger window.
+
+     windowBits can also be zero to request that inflate use the window size in
+   the zlib header of the compressed stream.
+
+     windowBits can also be -8..-15 for raw inflate.  In this case, -windowBits
+   determines the window size.  inflate() will then process raw deflate data,
+   not looking for a zlib or gzip header, not generating a check value, and not
+   looking for any check values for comparison at the end of the stream.  This
+   is for use with other formats that use the deflate compressed data format
+   such as zip.  Those formats provide their own check values.  If a custom
+   format is developed using the raw deflate format for compressed data, it is
+   recommended that a check value such as an adler32 or a crc32 be applied to
+   the uncompressed data as is done in the zlib, gzip, and zip formats.  For
+   most applications, the zlib format should be used as is.  Note that comments
+   above on the use in deflateInit2() applies to the magnitude of windowBits.
+
+     windowBits can also be greater than 15 for optional gzip decoding.  Add
+   32 to windowBits to enable zlib and gzip decoding with automatic header
+   detection, or add 16 to decode only the gzip format (the zlib format will
+   return a Z_DATA_ERROR).  If a gzip stream is being decoded, strm->adler is a
+   crc32 instead of an adler32.
+
+     inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
+   memory, Z_VERSION_ERROR if the zlib library version is incompatible with the
+   version assumed by the caller, or Z_STREAM_ERROR if the parameters are
+   invalid, such as a null pointer to the structure.  msg is set to null if
+   there is no error message.  inflateInit2 does not perform any decompression
+   apart from possibly reading the zlib header if present: actual decompression
+   will be done by inflate().  (So next_in and avail_in may be modified, but
+   next_out and avail_out are unused and unchanged.) The current implementation
+   of inflateInit2() does not process any header information -- that is
+   deferred until inflate() is called.
+*/
+
+ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm,
+                                             const Bytef *dictionary,
+                                             uInt  dictLength));
+/*
+     Initializes the decompression dictionary from the given uncompressed byte
+   sequence.  This function must be called immediately after a call of inflate,
+   if that call returned Z_NEED_DICT.  The dictionary chosen by the compressor
+   can be determined from the adler32 value returned by that call of inflate.
+   The compressor and decompressor must use exactly the same dictionary (see
+   deflateSetDictionary).  For raw inflate, this function can be called at any
+   time to set the dictionary.  If the provided dictionary is smaller than the
+   window and there is already data in the window, then the provided dictionary
+   will amend what's there.  The application must insure that the dictionary
+   that was used for compression is provided.
+
+     inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a
+   parameter is invalid (e.g.  dictionary being Z_NULL) or the stream state is
+   inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the
+   expected one (incorrect adler32 value).  inflateSetDictionary does not
+   perform any decompression: this will be done by subsequent calls of
+   inflate().
+*/
+
+ZEXTERN int ZEXPORT inflateGetDictionary OF((z_streamp strm,
+                                             Bytef *dictionary,
+                                             uInt  *dictLength));
+/*
+     Returns the sliding dictionary being maintained by inflate.  dictLength is
+   set to the number of bytes in the dictionary, and that many bytes are copied
+   to dictionary.  dictionary must have enough space, where 32768 bytes is
+   always enough.  If inflateGetDictionary() is called with dictionary equal to
+   Z_NULL, then only the dictionary length is returned, and nothing is copied.
+   Similary, if dictLength is Z_NULL, then it is not set.
+
+     inflateGetDictionary returns Z_OK on success, or Z_STREAM_ERROR if the
+   stream state is inconsistent.
+*/
+
+ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm));
+/*
+     Skips invalid compressed data until a possible full flush point (see above
+   for the description of deflate with Z_FULL_FLUSH) can be found, or until all
+   available input is skipped.  No output is provided.
+
+     inflateSync searches for a 00 00 FF FF pattern in the compressed data.
+   All full flush points have this pattern, but not all occurrences of this
+   pattern are full flush points.
+
+     inflateSync returns Z_OK if a possible full flush point has been found,
+   Z_BUF_ERROR if no more input was provided, Z_DATA_ERROR if no flush point
+   has been found, or Z_STREAM_ERROR if the stream structure was inconsistent.
+   In the success case, the application may save the current current value of
+   total_in which indicates where valid compressed data was found.  In the
+   error case, the application may repeatedly call inflateSync, providing more
+   input each time, until success or end of the input data.
+*/
+
+ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest,
+                                    z_streamp source));
+/*
+     Sets the destination stream as a complete copy of the source stream.
+
+     This function can be useful when randomly accessing a large stream.  The
+   first pass through the stream can periodically record the inflate state,
+   allowing restarting inflate at those points when randomly accessing the
+   stream.
+
+     inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
+   enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
+   (such as zalloc being Z_NULL).  msg is left unchanged in both source and
+   destination.
+*/
+
+ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm));
+/*
+     This function is equivalent to inflateEnd followed by inflateInit,
+   but does not free and reallocate all the internal decompression state.  The
+   stream will keep attributes that may have been set by inflateInit2.
+
+     inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
+   stream state was inconsistent (such as zalloc or state being Z_NULL).
+*/
+
+ZEXTERN int ZEXPORT inflateReset2 OF((z_streamp strm,
+                                      int windowBits));
+/*
+     This function is the same as inflateReset, but it also permits changing
+   the wrap and window size requests.  The windowBits parameter is interpreted
+   the same as it is for inflateInit2.
+
+     inflateReset2 returns Z_OK if success, or Z_STREAM_ERROR if the source
+   stream state was inconsistent (such as zalloc or state being Z_NULL), or if
+   the windowBits parameter is invalid.
+*/
+
+ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm,
+                                     int bits,
+                                     int value));
+/*
+     This function inserts bits in the inflate input stream.  The intent is
+   that this function is used to start inflating at a bit position in the
+   middle of a byte.  The provided bits will be used before any bytes are used
+   from next_in.  This function should only be used with raw inflate, and
+   should be used before the first inflate() call after inflateInit2() or
+   inflateReset().  bits must be less than or equal to 16, and that many of the
+   least significant bits of value will be inserted in the input.
+
+     If bits is negative, then the input stream bit buffer is emptied.  Then
+   inflatePrime() can be called again to put bits in the buffer.  This is used
+   to clear out bits leftover after feeding inflate a block description prior
+   to feeding inflate codes.
+
+     inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source
+   stream state was inconsistent.
+*/
+
+ZEXTERN long ZEXPORT inflateMark OF((z_streamp strm));
+/*
+     This function returns two values, one in the lower 16 bits of the return
+   value, and the other in the remaining upper bits, obtained by shifting the
+   return value down 16 bits.  If the upper value is -1 and the lower value is
+   zero, then inflate() is currently decoding information outside of a block.
+   If the upper value is -1 and the lower value is non-zero, then inflate is in
+   the middle of a stored block, with the lower value equaling the number of
+   bytes from the input remaining to copy.  If the upper value is not -1, then
+   it is the number of bits back from the current bit position in the input of
+   the code (literal or length/distance pair) currently being processed.  In
+   that case the lower value is the number of bytes already emitted for that
+   code.
+
+     A code is being processed if inflate is waiting for more input to complete
+   decoding of the code, or if it has completed decoding but is waiting for
+   more output space to write the literal or match data.
+
+     inflateMark() is used to mark locations in the input data for random
+   access, which may be at bit positions, and to note those cases where the
+   output of a code may span boundaries of random access blocks.  The current
+   location in the input stream can be determined from avail_in and data_type
+   as noted in the description for the Z_BLOCK flush parameter for inflate.
+
+     inflateMark returns the value noted above or -1 << 16 if the provided
+   source stream state was inconsistent.
+*/
+
+ZEXTERN int ZEXPORT inflateGetHeader OF((z_streamp strm,
+                                         gz_headerp head));
+/*
+     inflateGetHeader() requests that gzip header information be stored in the
+   provided gz_header structure.  inflateGetHeader() may be called after
+   inflateInit2() or inflateReset(), and before the first call of inflate().
+   As inflate() processes the gzip stream, head->done is zero until the header
+   is completed, at which time head->done is set to one.  If a zlib stream is
+   being decoded, then head->done is set to -1 to indicate that there will be
+   no gzip header information forthcoming.  Note that Z_BLOCK or Z_TREES can be
+   used to force inflate() to return immediately after header processing is
+   complete and before any actual data is decompressed.
+
+     The text, time, xflags, and os fields are filled in with the gzip header
+   contents.  hcrc is set to true if there is a header CRC.  (The header CRC
+   was valid if done is set to one.) If extra is not Z_NULL, then extra_max
+   contains the maximum number of bytes to write to extra.  Once done is true,
+   extra_len contains the actual extra field length, and extra contains the
+   extra field, or that field truncated if extra_max is less than extra_len.
+   If name is not Z_NULL, then up to name_max characters are written there,
+   terminated with a zero unless the length is greater than name_max.  If
+   comment is not Z_NULL, then up to comm_max characters are written there,
+   terminated with a zero unless the length is greater than comm_max.  When any
+   of extra, name, or comment are not Z_NULL and the respective field is not
+   present in the header, then that field is set to Z_NULL to signal its
+   absence.  This allows the use of deflateSetHeader() with the returned
+   structure to duplicate the header.  However if those fields are set to
+   allocated memory, then the application will need to save those pointers
+   elsewhere so that they can be eventually freed.
+
+     If inflateGetHeader is not used, then the header information is simply
+   discarded.  The header is always checked for validity, including the header
+   CRC if present.  inflateReset() will reset the process to discard the header
+   information.  The application would need to call inflateGetHeader() again to
+   retrieve the header from the next gzip stream.
+
+     inflateGetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source
+   stream state was inconsistent.
+*/
+
+/*
+ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits,
+                                        unsigned char FAR *window));
+
+     Initialize the internal stream state for decompression using inflateBack()
+   calls.  The fields zalloc, zfree and opaque in strm must be initialized
+   before the call.  If zalloc and zfree are Z_NULL, then the default library-
+   derived memory allocation routines are used.  windowBits is the base two
+   logarithm of the window size, in the range 8..15.  window is a caller
+   supplied buffer of that size.  Except for special applications where it is
+   assured that deflate was used with small window sizes, windowBits must be 15
+   and a 32K byte window must be supplied to be able to decompress general
+   deflate streams.
+
+     See inflateBack() for the usage of these routines.
+
+     inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of
+   the parameters are invalid, Z_MEM_ERROR if the internal state could not be
+   allocated, or Z_VERSION_ERROR if the version of the library does not match
+   the version of the header file.
+*/
+
+typedef unsigned (*in_func) OF((void FAR *,
+                                z_const unsigned char FAR * FAR *));
+typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned));
+
+ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm,
+                                    in_func in, void FAR *in_desc,
+                                    out_func out, void FAR *out_desc));
+/*
+     inflateBack() does a raw inflate with a single call using a call-back
+   interface for input and output.  This is potentially more efficient than
+   inflate() for file i/o applications, in that it avoids copying between the
+   output and the sliding window by simply making the window itself the output
+   buffer.  inflate() can be faster on modern CPUs when used with large
+   buffers.  inflateBack() trusts the application to not change the output
+   buffer passed by the output function, at least until inflateBack() returns.
+
+     inflateBackInit() must be called first to allocate the internal state
+   and to initialize the state with the user-provided window buffer.
+   inflateBack() may then be used multiple times to inflate a complete, raw
+   deflate stream with each call.  inflateBackEnd() is then called to free the
+   allocated state.
+
+     A raw deflate stream is one with no zlib or gzip header or trailer.
+   This routine would normally be used in a utility that reads zip or gzip
+   files and writes out uncompressed files.  The utility would decode the
+   header and process the trailer on its own, hence this routine expects only
+   the raw deflate stream to decompress.  This is different from the normal
+   behavior of inflate(), which expects either a zlib or gzip header and
+   trailer around the deflate stream.
+
+     inflateBack() uses two subroutines supplied by the caller that are then
+   called by inflateBack() for input and output.  inflateBack() calls those
+   routines until it reads a complete deflate stream and writes out all of the
+   uncompressed data, or until it encounters an error.  The function's
+   parameters and return types are defined above in the in_func and out_func
+   typedefs.  inflateBack() will call in(in_desc, &buf) which should return the
+   number of bytes of provided input, and a pointer to that input in buf.  If
+   there is no input available, in() must return zero--buf is ignored in that
+   case--and inflateBack() will return a buffer error.  inflateBack() will call
+   out(out_desc, buf, len) to write the uncompressed data buf[0..len-1].  out()
+   should return zero on success, or non-zero on failure.  If out() returns
+   non-zero, inflateBack() will return with an error.  Neither in() nor out()
+   are permitted to change the contents of the window provided to
+   inflateBackInit(), which is also the buffer that out() uses to write from.
+   The length written by out() will be at most the window size.  Any non-zero
+   amount of input may be provided by in().
+
+     For convenience, inflateBack() can be provided input on the first call by
+   setting strm->next_in and strm->avail_in.  If that input is exhausted, then
+   in() will be called.  Therefore strm->next_in must be initialized before
+   calling inflateBack().  If strm->next_in is Z_NULL, then in() will be called
+   immediately for input.  If strm->next_in is not Z_NULL, then strm->avail_in
+   must also be initialized, and then if strm->avail_in is not zero, input will
+   initially be taken from strm->next_in[0 ..  strm->avail_in - 1].
+
+     The in_desc and out_desc parameters of inflateBack() is passed as the
+   first parameter of in() and out() respectively when they are called.  These
+   descriptors can be optionally used to pass any information that the caller-
+   supplied in() and out() functions need to do their job.
+
+     On return, inflateBack() will set strm->next_in and strm->avail_in to
+   pass back any unused input that was provided by the last in() call.  The
+   return values of inflateBack() can be Z_STREAM_END on success, Z_BUF_ERROR
+   if in() or out() returned an error, Z_DATA_ERROR if there was a format error
+   in the deflate stream (in which case strm->msg is set to indicate the nature
+   of the error), or Z_STREAM_ERROR if the stream was not properly initialized.
+   In the case of Z_BUF_ERROR, an input or output error can be distinguished
+   using strm->next_in which will be Z_NULL only if in() returned an error.  If
+   strm->next_in is not Z_NULL, then the Z_BUF_ERROR was due to out() returning
+   non-zero.  (in() will always be called before out(), so strm->next_in is
+   assured to be defined if out() returns non-zero.) Note that inflateBack()
+   cannot return Z_OK.
+*/
+
+ZEXTERN int ZEXPORT inflateBackEnd OF((z_streamp strm));
+/*
+     All memory allocated by inflateBackInit() is freed.
+
+     inflateBackEnd() returns Z_OK on success, or Z_STREAM_ERROR if the stream
+   state was inconsistent.
+*/
+
+ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void));
+/* Return flags indicating compile-time options.
+
+    Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other:
+     1.0: size of uInt
+     3.2: size of uLong
+     5.4: size of voidpf (pointer)
+     7.6: size of z_off_t
+
+    Compiler, assembler, and debug options:
+     8: DEBUG
+     9: ASMV or ASMINF -- use ASM code
+     10: ZLIB_WINAPI -- exported functions use the WINAPI calling convention
+     11: 0 (reserved)
+
+    One-time table building (smaller code, but not thread-safe if true):
+     12: BUILDFIXED -- build static block decoding tables when needed
+     13: DYNAMIC_CRC_TABLE -- build CRC calculation tables when needed
+     14,15: 0 (reserved)
+
+    Library content (indicates missing functionality):
+     16: NO_GZCOMPRESS -- gz* functions cannot compress (to avoid linking
+                          deflate code when not needed)
+     17: NO_GZIP -- deflate can't write gzip streams, and inflate can't detect
+                    and decode gzip streams (to avoid linking crc code)
+     18-19: 0 (reserved)
+
+    Operation variations (changes in library functionality):
+     20: PKZIP_BUG_WORKAROUND -- slightly more permissive inflate
+     21: FASTEST -- deflate algorithm with only one, lowest compression level
+     22,23: 0 (reserved)
+
+    The sprintf variant used by gzprintf (zero is best):
+     24: 0 = vs*, 1 = s* -- 1 means limited to 20 arguments after the format
+     25: 0 = *nprintf, 1 = *printf -- 1 means gzprintf() not secure!
+     26: 0 = returns value, 1 = void -- 1 means inferred string length returned
+
+    Remainder:
+     27-31: 0 (reserved)
+ */
+
+#ifndef Z_SOLO
+
+                        /* utility functions */
+
+/*
+     The following utility functions are implemented on top of the basic
+   stream-oriented functions.  To simplify the interface, some default options
+   are assumed (compression level and memory usage, standard memory allocation
+   functions).  The source code of these utility functions can be modified if
+   you need special options.
+*/
+
+ZEXTERN int ZEXPORT compress OF((Bytef *dest,   uLongf *destLen,
+                                 const Bytef *source, uLong sourceLen));
+/*
+     Compresses the source buffer into the destination buffer.  sourceLen is
+   the byte length of the source buffer.  Upon entry, destLen is the total size
+   of the destination buffer, which must be at least the value returned by
+   compressBound(sourceLen).  Upon exit, destLen is the actual size of the
+   compressed buffer.
+
+     compress returns Z_OK if success, Z_MEM_ERROR if there was not
+   enough memory, Z_BUF_ERROR if there was not enough room in the output
+   buffer.
+*/
+
+ZEXTERN int ZEXPORT compress2 OF((Bytef *dest,   uLongf *destLen,
+                                  const Bytef *source, uLong sourceLen,
+                                  int level));
+/*
+     Compresses the source buffer into the destination buffer.  The level
+   parameter has the same meaning as in deflateInit.  sourceLen is the byte
+   length of the source buffer.  Upon entry, destLen is the total size of the
+   destination buffer, which must be at least the value returned by
+   compressBound(sourceLen).  Upon exit, destLen is the actual size of the
+   compressed buffer.
+
+     compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
+   memory, Z_BUF_ERROR if there was not enough room in the output buffer,
+   Z_STREAM_ERROR if the level parameter is invalid.
+*/
+
+ZEXTERN uLong ZEXPORT compressBound OF((uLong sourceLen));
+/*
+     compressBound() returns an upper bound on the compressed size after
+   compress() or compress2() on sourceLen bytes.  It would be used before a
+   compress() or compress2() call to allocate the destination buffer.
+*/
+
+ZEXTERN int ZEXPORT uncompress OF((Bytef *dest,   uLongf *destLen,
+                                   const Bytef *source, uLong sourceLen));
+/*
+     Decompresses the source buffer into the destination buffer.  sourceLen is
+   the byte length of the source buffer.  Upon entry, destLen is the total size
+   of the destination buffer, which must be large enough to hold the entire
+   uncompressed data.  (The size of the uncompressed data must have been saved
+   previously by the compressor and transmitted to the decompressor by some
+   mechanism outside the scope of this compression library.) Upon exit, destLen
+   is the actual size of the uncompressed buffer.
+
+     uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
+   enough memory, Z_BUF_ERROR if there was not enough room in the output
+   buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete.  In
+   the case where there is not enough room, uncompress() will fill the output
+   buffer with the uncompressed data up to that point.
+*/
+
+                        /* gzip file access functions */
+
+/*
+     This library supports reading and writing files in gzip (.gz) format with
+   an interface similar to that of stdio, using the functions that start with
+   "gz".  The gzip format is different from the zlib format.  gzip is a gzip
+   wrapper, documented in RFC 1952, wrapped around a deflate stream.
+*/
+
+typedef struct gzFile_s *gzFile;    /* semi-opaque gzip file descriptor */
+
+/*
+ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode));
+
+     Opens a gzip (.gz) file for reading or writing.  The mode parameter is as
+   in fopen ("rb" or "wb") but can also include a compression level ("wb9") or
+   a strategy: 'f' for filtered data as in "wb6f", 'h' for Huffman-only
+   compression as in "wb1h", 'R' for run-length encoding as in "wb1R", or 'F'
+   for fixed code compression as in "wb9F".  (See the description of
+   deflateInit2 for more information about the strategy parameter.)  'T' will
+   request transparent writing or appending with no compression and not using
+   the gzip format.
+
+     "a" can be used instead of "w" to request that the gzip stream that will
+   be written be appended to the file.  "+" will result in an error, since
+   reading and writing to the same gzip file is not supported.  The addition of
+   "x" when writing will create the file exclusively, which fails if the file
+   already exists.  On systems that support it, the addition of "e" when
+   reading or writing will set the flag to close the file on an execve() call.
+
+     These functions, as well as gzip, will read and decode a sequence of gzip
+   streams in a file.  The append function of gzopen() can be used to create
+   such a file.  (Also see gzflush() for another way to do this.)  When
+   appending, gzopen does not test whether the file begins with a gzip stream,
+   nor does it look for the end of the gzip streams to begin appending.  gzopen
+   will simply append a gzip stream to the existing file.
+
+     gzopen can be used to read a file which is not in gzip format; in this
+   case gzread will directly read from the file without decompression.  When
+   reading, this will be detected automatically by looking for the magic two-
+   byte gzip header.
+
+     gzopen returns NULL if the file could not be opened, if there was
+   insufficient memory to allocate the gzFile state, or if an invalid mode was
+   specified (an 'r', 'w', or 'a' was not provided, or '+' was provided).
+   errno can be checked to determine if the reason gzopen failed was that the
+   file could not be opened.
+*/
+
+ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode));
+/*
+     gzdopen associates a gzFile with the file descriptor fd.  File descriptors
+   are obtained from calls like open, dup, creat, pipe or fileno (if the file
+   has been previously opened with fopen).  The mode parameter is as in gzopen.
+
+     The next call of gzclose on the returned gzFile will also close the file
+   descriptor fd, just like fclose(fdopen(fd, mode)) closes the file descriptor
+   fd.  If you want to keep fd open, use fd = dup(fd_keep); gz = gzdopen(fd,
+   mode);.  The duplicated descriptor should be saved to avoid a leak, since
+   gzdopen does not close fd if it fails.  If you are using fileno() to get the
+   file descriptor from a FILE *, then you will have to use dup() to avoid
+   double-close()ing the file descriptor.  Both gzclose() and fclose() will
+   close the associated file descriptor, so they need to have different file
+   descriptors.
+
+     gzdopen returns NULL if there was insufficient memory to allocate the
+   gzFile state, if an invalid mode was specified (an 'r', 'w', or 'a' was not
+   provided, or '+' was provided), or if fd is -1.  The file descriptor is not
+   used until the next gz* read, write, seek, or close operation, so gzdopen
+   will not detect if fd is invalid (unless fd is -1).
+*/
+
+ZEXTERN int ZEXPORT gzbuffer OF((gzFile file, unsigned size));
+/*
+     Set the internal buffer size used by this library's functions.  The
+   default buffer size is 8192 bytes.  This function must be called after
+   gzopen() or gzdopen(), and before any other calls that read or write the
+   file.  The buffer memory allocation is always deferred to the first read or
+   write.  Two buffers are allocated, either both of the specified size when
+   writing, or one of the specified size and the other twice that size when
+   reading.  A larger buffer size of, for example, 64K or 128K bytes will
+   noticeably increase the speed of decompression (reading).
+
+     The new buffer size also affects the maximum length for gzprintf().
+
+     gzbuffer() returns 0 on success, or -1 on failure, such as being called
+   too late.
+*/
+
+ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy));
+/*
+     Dynamically update the compression level or strategy.  See the description
+   of deflateInit2 for the meaning of these parameters.
+
+     gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not
+   opened for writing.
+*/
+
+ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len));
+/*
+     Reads the given number of uncompressed bytes from the compressed file.  If
+   the input file is not in gzip format, gzread copies the given number of
+   bytes into the buffer directly from the file.
+
+     After reaching the end of a gzip stream in the input, gzread will continue
+   to read, looking for another gzip stream.  Any number of gzip streams may be
+   concatenated in the input file, and will all be decompressed by gzread().
+   If something other than a gzip stream is encountered after a gzip stream,
+   that remaining trailing garbage is ignored (and no error is returned).
+
+     gzread can be used to read a gzip file that is being concurrently written.
+   Upon reaching the end of the input, gzread will return with the available
+   data.  If the error code returned by gzerror is Z_OK or Z_BUF_ERROR, then
+   gzclearerr can be used to clear the end of file indicator in order to permit
+   gzread to be tried again.  Z_OK indicates that a gzip stream was completed
+   on the last gzread.  Z_BUF_ERROR indicates that the input file ended in the
+   middle of a gzip stream.  Note that gzread does not return -1 in the event
+   of an incomplete gzip stream.  This error is deferred until gzclose(), which
+   will return Z_BUF_ERROR if the last gzread ended in the middle of a gzip
+   stream.  Alternatively, gzerror can be used before gzclose to detect this
+   case.
+
+     gzread returns the number of uncompressed bytes actually read, less than
+   len for end of file, or -1 for error.
+*/
+
+ZEXTERN int ZEXPORT gzwrite OF((gzFile file,
+                                voidpc buf, unsigned len));
+/*
+     Writes the given number of uncompressed bytes into the compressed file.
+   gzwrite returns the number of uncompressed bytes written or 0 in case of
+   error.
+*/
+
+ZEXTERN int ZEXPORTVA gzprintf Z_ARG((gzFile file, const char *format, ...));
+/*
+     Converts, formats, and writes the arguments to the compressed file under
+   control of the format string, as in fprintf.  gzprintf returns the number of
+   uncompressed bytes actually written, or 0 in case of error.  The number of
+   uncompressed bytes written is limited to 8191, or one less than the buffer
+   size given to gzbuffer().  The caller should assure that this limit is not
+   exceeded.  If it is exceeded, then gzprintf() will return an error (0) with
+   nothing written.  In this case, there may also be a buffer overflow with
+   unpredictable consequences, which is possible only if zlib was compiled with
+   the insecure functions sprintf() or vsprintf() because the secure snprintf()
+   or vsnprintf() functions were not available.  This can be determined using
+   zlibCompileFlags().
+*/
+
+ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s));
+/*
+     Writes the given null-terminated string to the compressed file, excluding
+   the terminating null character.
+
+     gzputs returns the number of characters written, or -1 in case of error.
+*/
+
+ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len));
+/*
+     Reads bytes from the compressed file until len-1 characters are read, or a
+   newline character is read and transferred to buf, or an end-of-file
+   condition is encountered.  If any characters are read or if len == 1, the
+   string is terminated with a null character.  If no characters are read due
+   to an end-of-file or len < 1, then the buffer is left untouched.
+
+     gzgets returns buf which is a null-terminated string, or it returns NULL
+   for end-of-file or in case of error.  If there was an error, the contents at
+   buf are indeterminate.
+*/
+
+ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c));
+/*
+     Writes c, converted to an unsigned char, into the compressed file.  gzputc
+   returns the value that was written, or -1 in case of error.
+*/
+
+ZEXTERN int ZEXPORT gzgetc OF((gzFile file));
+/*
+     Reads one byte from the compressed file.  gzgetc returns this byte or -1
+   in case of end of file or error.  This is implemented as a macro for speed.
+   As such, it does not do all of the checking the other functions do.  I.e.
+   it does not check to see if file is NULL, nor whether the structure file
+   points to has been clobbered or not.
+*/
+
+ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file));
+/*
+     Push one character back onto the stream to be read as the first character
+   on the next read.  At least one character of push-back is allowed.
+   gzungetc() returns the character pushed, or -1 on failure.  gzungetc() will
+   fail if c is -1, and may fail if a character has been pushed but not read
+   yet.  If gzungetc is used immediately after gzopen or gzdopen, at least the
+   output buffer size of pushed characters is allowed.  (See gzbuffer above.)
+   The pushed character will be discarded if the stream is repositioned with
+   gzseek() or gzrewind().
+*/
+
+ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush));
+/*
+     Flushes all pending output into the compressed file.  The parameter flush
+   is as in the deflate() function.  The return value is the zlib error number
+   (see function gzerror below).  gzflush is only permitted when writing.
+
+     If the flush parameter is Z_FINISH, the remaining data is written and the
+   gzip stream is completed in the output.  If gzwrite() is called again, a new
+   gzip stream will be started in the output.  gzread() is able to read such
+   concatented gzip streams.
+
+     gzflush should be called only when strictly necessary because it will
+   degrade compression if called too often.
+*/
+
+/*
+ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file,
+                                   z_off_t offset, int whence));
+
+     Sets the starting position for the next gzread or gzwrite on the given
+   compressed file.  The offset represents a number of bytes in the
+   uncompressed data stream.  The whence parameter is defined as in lseek(2);
+   the value SEEK_END is not supported.
+
+     If the file is opened for reading, this function is emulated but can be
+   extremely slow.  If the file is opened for writing, only forward seeks are
+   supported; gzseek then compresses a sequence of zeroes up to the new
+   starting position.
+
+     gzseek returns the resulting offset location as measured in bytes from
+   the beginning of the uncompressed stream, or -1 in case of error, in
+   particular if the file is opened for writing and the new starting position
+   would be before the current position.
+*/
+
+ZEXTERN int ZEXPORT    gzrewind OF((gzFile file));
+/*
+     Rewinds the given file. This function is supported only for reading.
+
+     gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET)
+*/
+
+/*
+ZEXTERN z_off_t ZEXPORT    gztell OF((gzFile file));
+
+     Returns the starting position for the next gzread or gzwrite on the given
+   compressed file.  This position represents a number of bytes in the
+   uncompressed data stream, and is zero when starting, even if appending or
+   reading a gzip stream from the middle of a file using gzdopen().
+
+     gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR)
+*/
+
+/*
+ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile file));
+
+     Returns the current offset in the file being read or written.  This offset
+   includes the count of bytes that precede the gzip stream, for example when
+   appending or when using gzdopen() for reading.  When reading, the offset
+   does not include as yet unused buffered input.  This information can be used
+   for a progress indicator.  On error, gzoffset() returns -1.
+*/
+
+ZEXTERN int ZEXPORT gzeof OF((gzFile file));
+/*
+     Returns true (1) if the end-of-file indicator has been set while reading,
+   false (0) otherwise.  Note that the end-of-file indicator is set only if the
+   read tried to go past the end of the input, but came up short.  Therefore,
+   just like feof(), gzeof() may return false even if there is no more data to
+   read, in the event that the last read request was for the exact number of
+   bytes remaining in the input file.  This will happen if the input file size
+   is an exact multiple of the buffer size.
+
+     If gzeof() returns true, then the read functions will return no more data,
+   unless the end-of-file indicator is reset by gzclearerr() and the input file
+   has grown since the previous end of file was detected.
+*/
+
+ZEXTERN int ZEXPORT gzdirect OF((gzFile file));
+/*
+     Returns true (1) if file is being copied directly while reading, or false
+   (0) if file is a gzip stream being decompressed.
+
+     If the input file is empty, gzdirect() will return true, since the input
+   does not contain a gzip stream.
+
+     If gzdirect() is used immediately after gzopen() or gzdopen() it will
+   cause buffers to be allocated to allow reading the file to determine if it
+   is a gzip file.  Therefore if gzbuffer() is used, it should be called before
+   gzdirect().
+
+     When writing, gzdirect() returns true (1) if transparent writing was
+   requested ("wT" for the gzopen() mode), or false (0) otherwise.  (Note:
+   gzdirect() is not needed when writing.  Transparent writing must be
+   explicitly requested, so the application already knows the answer.  When
+   linking statically, using gzdirect() will include all of the zlib code for
+   gzip file reading and decompression, which may not be desired.)
+*/
+
+ZEXTERN int ZEXPORT    gzclose OF((gzFile file));
+/*
+     Flushes all pending output if necessary, closes the compressed file and
+   deallocates the (de)compression state.  Note that once file is closed, you
+   cannot call gzerror with file, since its structures have been deallocated.
+   gzclose must not be called more than once on the same file, just as free
+   must not be called more than once on the same allocation.
+
+     gzclose will return Z_STREAM_ERROR if file is not valid, Z_ERRNO on a
+   file operation error, Z_MEM_ERROR if out of memory, Z_BUF_ERROR if the
+   last read ended in the middle of a gzip stream, or Z_OK on success.
+*/
+
+ZEXTERN int ZEXPORT gzclose_r OF((gzFile file));
+ZEXTERN int ZEXPORT gzclose_w OF((gzFile file));
+/*
+     Same as gzclose(), but gzclose_r() is only for use when reading, and
+   gzclose_w() is only for use when writing or appending.  The advantage to
+   using these instead of gzclose() is that they avoid linking in zlib
+   compression or decompression code that is not used when only reading or only
+   writing respectively.  If gzclose() is used, then both compression and
+   decompression code will be included the application when linking to a static
+   zlib library.
+*/
+
+ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum));
+/*
+     Returns the error message for the last error which occurred on the given
+   compressed file.  errnum is set to zlib error number.  If an error occurred
+   in the file system and not in the compression library, errnum is set to
+   Z_ERRNO and the application may consult errno to get the exact error code.
+
+     The application must not modify the returned string.  Future calls to
+   this function may invalidate the previously returned string.  If file is
+   closed, then the string previously returned by gzerror will no longer be
+   available.
+
+     gzerror() should be used to distinguish errors from end-of-file for those
+   functions above that do not distinguish those cases in their return values.
+*/
+
+ZEXTERN void ZEXPORT gzclearerr OF((gzFile file));
+/*
+     Clears the error and end-of-file flags for file.  This is analogous to the
+   clearerr() function in stdio.  This is useful for continuing to read a gzip
+   file that is being written concurrently.
+*/
+
+#endif /* !Z_SOLO */
+
+                        /* checksum functions */
+
+/*
+     These functions are not related to compression but are exported
+   anyway because they might be useful in applications using the compression
+   library.
+*/
+
+ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len));
+/*
+     Update a running Adler-32 checksum with the bytes buf[0..len-1] and
+   return the updated checksum.  If buf is Z_NULL, this function returns the
+   required initial value for the checksum.
+
+     An Adler-32 checksum is almost as reliable as a CRC32 but can be computed
+   much faster.
+
+   Usage example:
+
+     uLong adler = adler32(0L, Z_NULL, 0);
+
+     while (read_buffer(buffer, length) != EOF) {
+       adler = adler32(adler, buffer, length);
+     }
+     if (adler != original_adler) error();
+*/
+
+/*
+ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2,
+                                          z_off_t len2));
+
+     Combine two Adler-32 checksums into one.  For two sequences of bytes, seq1
+   and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for
+   each, adler1 and adler2.  adler32_combine() returns the Adler-32 checksum of
+   seq1 and seq2 concatenated, requiring only adler1, adler2, and len2.  Note
+   that the z_off_t type (like off_t) is a signed integer.  If len2 is
+   negative, the result has no meaning or utility.
+*/
+
+ZEXTERN uLong ZEXPORT crc32   OF((uLong crc, const Bytef *buf, uInt len));
+/*
+     Update a running CRC-32 with the bytes buf[0..len-1] and return the
+   updated CRC-32.  If buf is Z_NULL, this function returns the required
+   initial value for the crc.  Pre- and post-conditioning (one's complement) is
+   performed within this function so it shouldn't be done by the application.
+
+   Usage example:
+
+     uLong crc = crc32(0L, Z_NULL, 0);
+
+     while (read_buffer(buffer, length) != EOF) {
+       crc = crc32(crc, buffer, length);
+     }
+     if (crc != original_crc) error();
+*/
+
+/*
+ZEXTERN uLong ZEXPORT crc32_combine OF((uLong crc1, uLong crc2, z_off_t len2));
+
+     Combine two CRC-32 check values into one.  For two sequences of bytes,
+   seq1 and seq2 with lengths len1 and len2, CRC-32 check values were
+   calculated for each, crc1 and crc2.  crc32_combine() returns the CRC-32
+   check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and
+   len2.
+*/
+
+
+                        /* various hacks, don't look :) */
+
+/* deflateInit and inflateInit are macros to allow checking the zlib version
+ * and the compiler's view of z_stream:
+ */
+ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level,
+                                     const char *version, int stream_size));
+ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm,
+                                     const char *version, int stream_size));
+ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int  level, int  method,
+                                      int windowBits, int memLevel,
+                                      int strategy, const char *version,
+                                      int stream_size));
+ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int  windowBits,
+                                      const char *version, int stream_size));
+ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits,
+                                         unsigned char FAR *window,
+                                         const char *version,
+                                         int stream_size));
+#define deflateInit(strm, level) \
+        deflateInit_((strm), (level), ZLIB_VERSION, (int)sizeof(z_stream))
+#define inflateInit(strm) \
+        inflateInit_((strm), ZLIB_VERSION, (int)sizeof(z_stream))
+#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \
+        deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\
+                      (strategy), ZLIB_VERSION, (int)sizeof(z_stream))
+#define inflateInit2(strm, windowBits) \
+        inflateInit2_((strm), (windowBits), ZLIB_VERSION, \
+                      (int)sizeof(z_stream))
+#define inflateBackInit(strm, windowBits, window) \
+        inflateBackInit_((strm), (windowBits), (window), \
+                      ZLIB_VERSION, (int)sizeof(z_stream))
+
+#ifndef Z_SOLO
+
+/* gzgetc() macro and its supporting function and exposed data structure.  Note
+ * that the real internal state is much larger than the exposed structure.
+ * This abbreviated structure exposes just enough for the gzgetc() macro.  The
+ * user should not mess with these exposed elements, since their names or
+ * behavior could change in the future, perhaps even capriciously.  They can
+ * only be used by the gzgetc() macro.  You have been warned.
+ */
+struct gzFile_s {
+    unsigned have;
+    unsigned char *next;
+    z_off64_t pos;
+};
+ZEXTERN int ZEXPORT gzgetc_ OF((gzFile file));  /* backward compatibility */
+#ifdef Z_PREFIX_SET
+#  undef z_gzgetc
+#  define z_gzgetc(g) \
+          ((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : gzgetc(g))
+#else
+#  define gzgetc(g) \
+          ((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : gzgetc(g))
+#endif
+
+/* provide 64-bit offset functions if _LARGEFILE64_SOURCE defined, and/or
+ * change the regular functions to 64 bits if _FILE_OFFSET_BITS is 64 (if
+ * both are true, the application gets the *64 functions, and the regular
+ * functions are changed to 64 bits) -- in case these are set on systems
+ * without large file support, _LFS64_LARGEFILE must also be true
+ */
+#ifdef Z_LARGE64
+   ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *));
+   ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int));
+   ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile));
+   ZEXTERN z_off64_t ZEXPORT gzoffset64 OF((gzFile));
+   ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off64_t));
+   ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off64_t));
+#endif
+
+#if !defined(ZLIB_INTERNAL) && defined(Z_WANT64)
+#  ifdef Z_PREFIX_SET
+#    define z_gzopen z_gzopen64
+#    define z_gzseek z_gzseek64
+#    define z_gztell z_gztell64
+#    define z_gzoffset z_gzoffset64
+#    define z_adler32_combine z_adler32_combine64
+#    define z_crc32_combine z_crc32_combine64
+#  else
+#    define gzopen gzopen64
+#    define gzseek gzseek64
+#    define gztell gztell64
+#    define gzoffset gzoffset64
+#    define adler32_combine adler32_combine64
+#    define crc32_combine crc32_combine64
+#  endif
+#  ifndef Z_LARGE64
+     ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *));
+     ZEXTERN z_off_t ZEXPORT gzseek64 OF((gzFile, z_off_t, int));
+     ZEXTERN z_off_t ZEXPORT gztell64 OF((gzFile));
+     ZEXTERN z_off_t ZEXPORT gzoffset64 OF((gzFile));
+     ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t));
+     ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t));
+#  endif
+#else
+   ZEXTERN gzFile ZEXPORT gzopen OF((const char *, const char *));
+   ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile, z_off_t, int));
+   ZEXTERN z_off_t ZEXPORT gztell OF((gzFile));
+   ZEXTERN z_off_t ZEXPORT gzoffset OF((gzFile));
+   ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t));
+   ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t));
+#endif
+
+#else /* Z_SOLO */
+
+   ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t));
+   ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t));
+
+#endif /* !Z_SOLO */
+
+/* hack for buggy compilers */
+#if !defined(ZUTIL_H) && !defined(NO_DUMMY_DECL)
+    struct internal_state {int dummy;};
+#endif
+
+/* undocumented functions */
+ZEXTERN const char   * ZEXPORT zError           OF((int));
+ZEXTERN int            ZEXPORT inflateSyncPoint OF((z_streamp));
+ZEXTERN const z_crc_t FAR * ZEXPORT get_crc_table    OF((void));
+ZEXTERN int            ZEXPORT inflateUndermine OF((z_streamp, int));
+ZEXTERN int            ZEXPORT inflateResetKeep OF((z_streamp));
+ZEXTERN int            ZEXPORT deflateResetKeep OF((z_streamp));
+#if defined(_WIN32) && !defined(Z_SOLO)
+ZEXTERN gzFile         ZEXPORT gzopen_w OF((const wchar_t *path,
+                                            const char *mode));
+#endif
+#if defined(STDC) || defined(Z_HAVE_STDARG_H)
+#  ifndef Z_SOLO
+ZEXTERN int            ZEXPORTVA gzvprintf Z_ARG((gzFile file,
+                                                  const char *format,
+                                                  va_list va));
+#  endif
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* ZLIB_H */
diff --git a/compat/zlib/zlib.map b/compat/zlib/zlib.map
new file mode 100644
index 0000000..55c6647
--- /dev/null
+++ b/compat/zlib/zlib.map
@@ -0,0 +1,83 @@
+ZLIB_1.2.0 {
+  global:
+    compressBound;
+    deflateBound;
+    inflateBack;
+    inflateBackEnd;
+    inflateBackInit_;
+    inflateCopy;
+  local:
+    deflate_copyright;
+    inflate_copyright;
+    inflate_fast;
+    inflate_table;
+    zcalloc;
+    zcfree;
+    z_errmsg;
+    gz_error;
+    gz_intmax;
+    _*;
+};
+
+ZLIB_1.2.0.2 {
+    gzclearerr;
+    gzungetc;
+    zlibCompileFlags;
+} ZLIB_1.2.0;
+
+ZLIB_1.2.0.8 {
+    deflatePrime;
+} ZLIB_1.2.0.2;
+
+ZLIB_1.2.2 {
+    adler32_combine;
+    crc32_combine;
+    deflateSetHeader;
+    inflateGetHeader;
+} ZLIB_1.2.0.8;
+
+ZLIB_1.2.2.3 {
+    deflateTune;
+    gzdirect;
+} ZLIB_1.2.2;
+
+ZLIB_1.2.2.4 {
+    inflatePrime;
+} ZLIB_1.2.2.3;
+
+ZLIB_1.2.3.3 {
+    adler32_combine64;
+    crc32_combine64;
+    gzopen64;
+    gzseek64;
+    gztell64;
+    inflateUndermine;
+} ZLIB_1.2.2.4;
+
+ZLIB_1.2.3.4 {
+    inflateReset2;
+    inflateMark;
+} ZLIB_1.2.3.3;
+
+ZLIB_1.2.3.5 {
+    gzbuffer;
+    gzoffset;
+    gzoffset64;
+    gzclose_r;
+    gzclose_w;
+} ZLIB_1.2.3.4;
+
+ZLIB_1.2.5.1 {
+    deflatePending;
+} ZLIB_1.2.3.5;
+
+ZLIB_1.2.5.2 {
+    deflateResetKeep;
+    gzgetc_;
+    inflateResetKeep;
+} ZLIB_1.2.5.1;
+
+ZLIB_1.2.7.1 {
+    inflateGetDictionary;
+    gzvprintf;
+} ZLIB_1.2.5.2;
diff --git a/compat/zlib/zlib.pc.cmakein b/compat/zlib/zlib.pc.cmakein
new file mode 100644
index 0000000..a5e6429
--- /dev/null
+++ b/compat/zlib/zlib.pc.cmakein
@@ -0,0 +1,13 @@
+prefix=@CMAKE_INSTALL_PREFIX@
+exec_prefix=@CMAKE_INSTALL_PREFIX@
+libdir=@INSTALL_LIB_DIR@
+sharedlibdir=@INSTALL_LIB_DIR@
+includedir=@INSTALL_INC_DIR@
+
+Name: zlib
+Description: zlib compression library
+Version: @VERSION@
+
+Requires:
+Libs: -L${libdir} -L${sharedlibdir} -lz
+Cflags: -I${includedir}
diff --git a/compat/zlib/zlib.pc.in b/compat/zlib/zlib.pc.in
new file mode 100644
index 0000000..7e5acf9
--- /dev/null
+++ b/compat/zlib/zlib.pc.in
@@ -0,0 +1,13 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+sharedlibdir=@sharedlibdir@
+includedir=@includedir@
+
+Name: zlib
+Description: zlib compression library
+Version: @VERSION@
+
+Requires:
+Libs: -L${libdir} -L${sharedlibdir} -lz
+Cflags: -I${includedir}
diff --git a/compat/zlib/zlib2ansi b/compat/zlib/zlib2ansi
new file mode 100644
index 0000000..15e3e16
--- /dev/null
+++ b/compat/zlib/zlib2ansi
@@ -0,0 +1,152 @@
+#!/usr/bin/perl
+
+# Transform K&R C function definitions into ANSI equivalent.
+#
+# Author: Paul Marquess
+# Version: 1.0
+# Date: 3 October 2006
+
+# TODO
+#
+# Asumes no function pointer parameters. unless they are typedefed.
+# Assumes no literal strings that look like function definitions
+# Assumes functions start at the beginning of a line
+
+use strict;
+use warnings;
+
+local $/;
+$_ = <>;
+
+my $sp = qr{ \s* (?: /\* .*? \*/ )? \s* }x; # assume no nested comments
+
+my $d1    = qr{ $sp (?: [\w\*\s]+ $sp)* $sp \w+ $sp [\[\]\s]* $sp }x ;
+my $decl  = qr{ $sp (?: \w+ $sp )+ $d1 }xo ;
+my $dList = qr{ $sp $decl (?: $sp , $d1 )* $sp ; $sp }xo ;
+
+
+while (s/^
+            (                  # Start $1
+                (              #   Start $2
+                    .*?        #     Minimal eat content
+                    ( ^ \w [\w\s\*]+ )    #     $3 -- function name
+                    \s*        #     optional whitespace
+                )              # $2 - Matched up to before parameter list
+
+                \( \s*         # Literal "(" + optional whitespace
+                ( [^\)]+ )     # $4 - one or more anythings except ")"
+                \s* \)         # optional whitespace surrounding a Literal ")"
+
+                ( (?: $dList )+ ) # $5
+
+                $sp ^ {        # literal "{" at start of line
+            )                  # Remember to $1
+        //xsom
+      )
+{
+    my $all = $1 ;
+    my $prefix = $2;
+    my $param_list = $4 ;
+    my $params = $5;
+
+    StripComments($params);
+    StripComments($param_list);
+    $param_list =~ s/^\s+//;
+    $param_list =~ s/\s+$//;
+
+    my $i = 0 ;
+    my %pList = map { $_ => $i++ }
+                split /\s*,\s*/, $param_list;
+    my $pMatch = '(\b' . join('|', keys %pList) . '\b)\W*$' ;
+
+    my @params = split /\s*;\s*/, $params;
+    my @outParams = ();
+    foreach my $p (@params)
+    {
+        if ($p =~ /,/)
+        {
+            my @bits = split /\s*,\s*/, $p;
+            my $first = shift @bits;
+            $first =~ s/^\s*//;
+            push @outParams, $first;
+            $first =~ /^(\w+\s*)/;
+            my $type = $1 ;
+            push @outParams, map { $type . $_ } @bits;
+        }
+        else
+        {
+            $p =~ s/^\s+//;
+            push @outParams, $p;
+        }
+    }
+
+
+    my %tmp = map { /$pMatch/;  $_ => $pList{$1}  }
+              @outParams ;
+
+    @outParams = map  { "    $_" }
+                 sort { $tmp{$a} <=> $tmp{$b} }
+                 @outParams ;
+
+    print $prefix ;
+    print "(\n" . join(",\n", @outParams) . ")\n";
+    print "{" ;
+
+}
+
+# Output any trailing code.
+print ;
+exit 0;
+
+
+sub StripComments
+{
+
+  no warnings;
+
+  # Strip C & C++ coments
+  # From the perlfaq
+  $_[0] =~
+
+    s{
+       /\*         ##  Start of /* ... */ comment
+       [^*]*\*+    ##  Non-* followed by 1-or-more *'s
+       (
+         [^/*][^*]*\*+
+       )*          ##  0-or-more things which don't start with /
+                   ##    but do end with '*'
+       /           ##  End of /* ... */ comment
+
+     |         ##     OR  C++ Comment
+       //          ## Start of C++ comment //
+       [^\n]*      ## followed by 0-or-more non end of line characters
+
+     |         ##     OR  various things which aren't comments:
+
+       (
+         "           ##  Start of " ... " string
+         (
+           \\.           ##  Escaped char
+         |               ##    OR
+           [^"\\]        ##  Non "\
+         )*
+         "           ##  End of " ... " string
+
+       |         ##     OR
+
+         '           ##  Start of ' ... ' string
+         (
+           \\.           ##  Escaped char
+         |               ##    OR
+           [^'\\]        ##  Non '\
+         )*
+         '           ##  End of ' ... ' string
+
+       |         ##     OR
+
+         .           ##  Anything other char
+         [^/"'\\]*   ##  Chars which doesn't start a comment, string or escape
+       )
+     }{$2}gxs;
+
+}
diff --git a/compat/zlib/zutil.c b/compat/zlib/zutil.c
new file mode 100644
index 0000000..23d2ebe
--- /dev/null
+++ b/compat/zlib/zutil.c
@@ -0,0 +1,324 @@
+/* zutil.c -- target dependent utility functions for the compression library
+ * Copyright (C) 1995-2005, 2010, 2011, 2012 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* @(#) $Id$ */
+
+#include "zutil.h"
+#ifndef Z_SOLO
+#  include "gzguts.h"
+#endif
+
+#ifndef NO_DUMMY_DECL
+struct internal_state      {int dummy;}; /* for buggy compilers */
+#endif
+
+z_const char * const z_errmsg[10] = {
+"need dictionary",     /* Z_NEED_DICT       2  */
+"stream end",          /* Z_STREAM_END      1  */
+"",                    /* Z_OK              0  */
+"file error",          /* Z_ERRNO         (-1) */
+"stream error",        /* Z_STREAM_ERROR  (-2) */
+"data error",          /* Z_DATA_ERROR    (-3) */
+"insufficient memory", /* Z_MEM_ERROR     (-4) */
+"buffer error",        /* Z_BUF_ERROR     (-5) */
+"incompatible version",/* Z_VERSION_ERROR (-6) */
+""};
+
+
+const char * ZEXPORT zlibVersion()
+{
+    return ZLIB_VERSION;
+}
+
+uLong ZEXPORT zlibCompileFlags()
+{
+    uLong flags;
+
+    flags = 0;
+    switch ((int)(sizeof(uInt))) {
+    case 2:     break;
+    case 4:     flags += 1;     break;
+    case 8:     flags += 2;     break;
+    default:    flags += 3;
+    }
+    switch ((int)(sizeof(uLong))) {
+    case 2:     break;
+    case 4:     flags += 1 << 2;        break;
+    case 8:     flags += 2 << 2;        break;
+    default:    flags += 3 << 2;
+    }
+    switch ((int)(sizeof(voidpf))) {
+    case 2:     break;
+    case 4:     flags += 1 << 4;        break;
+    case 8:     flags += 2 << 4;        break;
+    default:    flags += 3 << 4;
+    }
+    switch ((int)(sizeof(z_off_t))) {
+    case 2:     break;
+    case 4:     flags += 1 << 6;        break;
+    case 8:     flags += 2 << 6;        break;
+    default:    flags += 3 << 6;
+    }
+#ifdef DEBUG
+    flags += 1 << 8;
+#endif
+#if defined(ASMV) || defined(ASMINF)
+    flags += 1 << 9;
+#endif
+#ifdef ZLIB_WINAPI
+    flags += 1 << 10;
+#endif
+#ifdef BUILDFIXED
+    flags += 1 << 12;
+#endif
+#ifdef DYNAMIC_CRC_TABLE
+    flags += 1 << 13;
+#endif
+#ifdef NO_GZCOMPRESS
+    flags += 1L << 16;
+#endif
+#ifdef NO_GZIP
+    flags += 1L << 17;
+#endif
+#ifdef PKZIP_BUG_WORKAROUND
+    flags += 1L << 20;
+#endif
+#ifdef FASTEST
+    flags += 1L << 21;
+#endif
+#if defined(STDC) || defined(Z_HAVE_STDARG_H)
+#  ifdef NO_vsnprintf
+    flags += 1L << 25;
+#    ifdef HAS_vsprintf_void
+    flags += 1L << 26;
+#    endif
+#  else
+#    ifdef HAS_vsnprintf_void
+    flags += 1L << 26;
+#    endif
+#  endif
+#else
+    flags += 1L << 24;
+#  ifdef NO_snprintf
+    flags += 1L << 25;
+#    ifdef HAS_sprintf_void
+    flags += 1L << 26;
+#    endif
+#  else
+#    ifdef HAS_snprintf_void
+    flags += 1L << 26;
+#    endif
+#  endif
+#endif
+    return flags;
+}
+
+#ifdef DEBUG
+
+#  ifndef verbose
+#    define verbose 0
+#  endif
+int ZLIB_INTERNAL z_verbose = verbose;
+
+void ZLIB_INTERNAL z_error (m)
+    char *m;
+{
+    fprintf(stderr, "%s\n", m);
+    exit(1);
+}
+#endif
+
+/* exported to allow conversion of error code to string for compress() and
+ * uncompress()
+ */
+const char * ZEXPORT zError(err)
+    int err;
+{
+    return ERR_MSG(err);
+}
+
+#if defined(_WIN32_WCE)
+    /* The Microsoft C Run-Time Library for Windows CE doesn't have
+     * errno.  We define it as a global variable to simplify porting.
+     * Its value is always 0 and should not be used.
+     */
+    int errno = 0;
+#endif
+
+#ifndef HAVE_MEMCPY
+
+void ZLIB_INTERNAL zmemcpy(dest, source, len)
+    Bytef* dest;
+    const Bytef* source;
+    uInt  len;
+{
+    if (len == 0) return;
+    do {
+        *dest++ = *source++; /* ??? to be unrolled */
+    } while (--len != 0);
+}
+
+int ZLIB_INTERNAL zmemcmp(s1, s2, len)
+    const Bytef* s1;
+    const Bytef* s2;
+    uInt  len;
+{
+    uInt j;
+
+    for (j = 0; j < len; j++) {
+        if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1;
+    }
+    return 0;
+}
+
+void ZLIB_INTERNAL zmemzero(dest, len)
+    Bytef* dest;
+    uInt  len;
+{
+    if (len == 0) return;
+    do {
+        *dest++ = 0;  /* ??? to be unrolled */
+    } while (--len != 0);
+}
+#endif
+
+#ifndef Z_SOLO
+
+#ifdef SYS16BIT
+
+#ifdef __TURBOC__
+/* Turbo C in 16-bit mode */
+
+#  define MY_ZCALLOC
+
+/* Turbo C malloc() does not allow dynamic allocation of 64K bytes
+ * and farmalloc(64K) returns a pointer with an offset of 8, so we
+ * must fix the pointer. Warning: the pointer must be put back to its
+ * original form in order to free it, use zcfree().
+ */
+
+#define MAX_PTR 10
+/* 10*64K = 640K */
+
+local int next_ptr = 0;
+
+typedef struct ptr_table_s {
+    voidpf org_ptr;
+    voidpf new_ptr;
+} ptr_table;
+
+local ptr_table table[MAX_PTR];
+/* This table is used to remember the original form of pointers
+ * to large buffers (64K). Such pointers are normalized with a zero offset.
+ * Since MSDOS is not a preemptive multitasking OS, this table is not
+ * protected from concurrent access. This hack doesn't work anyway on
+ * a protected system like OS/2. Use Microsoft C instead.
+ */
+
+voidpf ZLIB_INTERNAL zcalloc (voidpf opaque, unsigned items, unsigned size)
+{
+    voidpf buf = opaque; /* just to make some compilers happy */
+    ulg bsize = (ulg)items*size;
+
+    /* If we allocate less than 65520 bytes, we assume that farmalloc
+     * will return a usable pointer which doesn't have to be normalized.
+     */
+    if (bsize < 65520L) {
+        buf = farmalloc(bsize);
+        if (*(ush*)&buf != 0) return buf;
+    } else {
+        buf = farmalloc(bsize + 16L);
+    }
+    if (buf == NULL || next_ptr >= MAX_PTR) return NULL;
+    table[next_ptr].org_ptr = buf;
+
+    /* Normalize the pointer to seg:0 */
+    *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4;
+    *(ush*)&buf = 0;
+    table[next_ptr++].new_ptr = buf;
+    return buf;
+}
+
+void ZLIB_INTERNAL zcfree (voidpf opaque, voidpf ptr)
+{
+    int n;
+    if (*(ush*)&ptr != 0) { /* object < 64K */
+        farfree(ptr);
+        return;
+    }
+    /* Find the original pointer */
+    for (n = 0; n < next_ptr; n++) {
+        if (ptr != table[n].new_ptr) continue;
+
+        farfree(table[n].org_ptr);
+        while (++n < next_ptr) {
+            table[n-1] = table[n];
+        }
+        next_ptr--;
+        return;
+    }
+    ptr = opaque; /* just to make some compilers happy */
+    Assert(0, "zcfree: ptr not found");
+}
+
+#endif /* __TURBOC__ */
+
+
+#ifdef M_I86
+/* Microsoft C in 16-bit mode */
+
+#  define MY_ZCALLOC
+
+#if (!defined(_MSC_VER) || (_MSC_VER <= 600))
+#  define _halloc  halloc
+#  define _hfree   hfree
+#endif
+
+voidpf ZLIB_INTERNAL zcalloc (voidpf opaque, uInt items, uInt size)
+{
+    if (opaque) opaque = 0; /* to make compiler happy */
+    return _halloc((long)items, size);
+}
+
+void ZLIB_INTERNAL zcfree (voidpf opaque, voidpf ptr)
+{
+    if (opaque) opaque = 0; /* to make compiler happy */
+    _hfree(ptr);
+}
+
+#endif /* M_I86 */
+
+#endif /* SYS16BIT */
+
+
+#ifndef MY_ZCALLOC /* Any system without a special alloc function */
+
+#ifndef STDC
+extern voidp  malloc OF((uInt size));
+extern voidp  calloc OF((uInt items, uInt size));
+extern void   free   OF((voidpf ptr));
+#endif
+
+voidpf ZLIB_INTERNAL zcalloc (opaque, items, size)
+    voidpf opaque;
+    unsigned items;
+    unsigned size;
+{
+    if (opaque) items += size - size; /* make compiler happy */
+    return sizeof(uInt) > 2 ? (voidpf)malloc(items * size) :
+                              (voidpf)calloc(items, size);
+}
+
+void ZLIB_INTERNAL zcfree (opaque, ptr)
+    voidpf opaque;
+    voidpf ptr;
+{
+    free(ptr);
+    if (opaque) return; /* make compiler happy */
+}
+
+#endif /* MY_ZCALLOC */
+
+#endif /* !Z_SOLO */
diff --git a/compat/zlib/zutil.h b/compat/zlib/zutil.h
new file mode 100644
index 0000000..24ab06b
--- /dev/null
+++ b/compat/zlib/zutil.h
@@ -0,0 +1,253 @@
+/* zutil.h -- internal interface and configuration of the compression library
+ * Copyright (C) 1995-2013 Jean-loup Gailly.
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+/* WARNING: this file should *not* be used by applications. It is
+   part of the implementation of the compression library and is
+   subject to change. Applications should only use zlib.h.
+ */
+
+/* @(#) $Id$ */
+
+#ifndef ZUTIL_H
+#define ZUTIL_H
+
+#ifdef HAVE_HIDDEN
+#  define ZLIB_INTERNAL __attribute__((visibility ("hidden")))
+#else
+#  define ZLIB_INTERNAL
+#endif
+
+#include "zlib.h"
+
+#if defined(STDC) && !defined(Z_SOLO)
+#  if !(defined(_WIN32_WCE) && defined(_MSC_VER))
+#    include <stddef.h>
+#  endif
+#  include <string.h>
+#  include <stdlib.h>
+#endif
+
+#ifdef Z_SOLO
+   typedef long ptrdiff_t;  /* guess -- will be caught if guess is wrong */
+#endif
+
+#ifndef local
+#  define local static
+#endif
+/* compile with -Dlocal if your debugger can't find static symbols */
+
+typedef unsigned char  uch;
+typedef uch FAR uchf;
+typedef unsigned short ush;
+typedef ush FAR ushf;
+typedef unsigned long  ulg;
+
+extern z_const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
+/* (size given to avoid silly warnings with Visual C++) */
+
+#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)]
+
+#define ERR_RETURN(strm,err) \
+  return (strm->msg = ERR_MSG(err), (err))
+/* To be used only when the state is known to be valid */
+
+        /* common constants */
+
+#ifndef DEF_WBITS
+#  define DEF_WBITS MAX_WBITS
+#endif
+/* default windowBits for decompression. MAX_WBITS is for compression only */
+
+#if MAX_MEM_LEVEL >= 8
+#  define DEF_MEM_LEVEL 8
+#else
+#  define DEF_MEM_LEVEL  MAX_MEM_LEVEL
+#endif
+/* default memLevel */
+
+#define STORED_BLOCK 0
+#define STATIC_TREES 1
+#define DYN_TREES    2
+/* The three kinds of block type */
+
+#define MIN_MATCH  3
+#define MAX_MATCH  258
+/* The minimum and maximum match lengths */
+
+#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */
+
+        /* target dependencies */
+
+#if defined(MSDOS) || (defined(WINDOWS) && !defined(WIN32))
+#  define OS_CODE  0x00
+#  ifndef Z_SOLO
+#    if defined(__TURBOC__) || defined(__BORLANDC__)
+#      if (__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__))
+         /* Allow compilation with ANSI keywords only enabled */
+         void _Cdecl farfree( void *block );
+         void *_Cdecl farmalloc( unsigned long nbytes );
+#      else
+#        include <alloc.h>
+#      endif
+#    else /* MSC or DJGPP */
+#      include <malloc.h>
+#    endif
+#  endif
+#endif
+
+#ifdef AMIGA
+#  define OS_CODE  0x01
+#endif
+
+#if defined(VAXC) || defined(VMS)
+#  define OS_CODE  0x02
+#  define F_OPEN(name, mode) \
+     fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512")
+#endif
+
+#if defined(ATARI) || defined(atarist)
+#  define OS_CODE  0x05
+#endif
+
+#ifdef OS2
+#  define OS_CODE  0x06
+#  if defined(M_I86) && !defined(Z_SOLO)
+#    include <malloc.h>
+#  endif
+#endif
+
+#if defined(MACOS) || defined(TARGET_OS_MAC)
+#  define OS_CODE  0x07
+#  ifndef Z_SOLO
+#    if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os
+#      include <unix.h> /* for fdopen */
+#    else
+#      ifndef fdopen
+#        define fdopen(fd,mode) NULL /* No fdopen() */
+#      endif
+#    endif
+#  endif
+#endif
+
+#ifdef TOPS20
+#  define OS_CODE  0x0a
+#endif
+
+#ifdef WIN32
+#  ifndef __CYGWIN__  /* Cygwin is Unix, not Win32 */
+#    define OS_CODE  0x0b
+#  endif
+#endif
+
+#ifdef __50SERIES /* Prime/PRIMOS */
+#  define OS_CODE  0x0f
+#endif
+
+#if defined(_BEOS_) || defined(RISCOS)
+#  define fdopen(fd,mode) NULL /* No fdopen() */
+#endif
+
+#if (defined(_MSC_VER) && (_MSC_VER > 600)) && !defined __INTERIX
+#  if defined(_WIN32_WCE)
+#    define fdopen(fd,mode) NULL /* No fdopen() */
+#    ifndef _PTRDIFF_T_DEFINED
+       typedef int ptrdiff_t;
+#      define _PTRDIFF_T_DEFINED
+#    endif
+#  else
+#    define fdopen(fd,type)  _fdopen(fd,type)
+#  endif
+#endif
+
+#if defined(__BORLANDC__) && !defined(MSDOS)
+  #pragma warn -8004
+  #pragma warn -8008
+  #pragma warn -8066
+#endif
+
+/* provide prototypes for these when building zlib without LFS */
+#if !defined(_WIN32) && \
+    (!defined(_LARGEFILE64_SOURCE) || _LFS64_LARGEFILE-0 == 0)
+    ZEXTERN uLong ZEXPORT adler32_combine64 OF((uLong, uLong, z_off_t));
+    ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off_t));
+#endif
+
+        /* common defaults */
+
+#ifndef OS_CODE
+#  define OS_CODE  0x03  /* assume Unix */
+#endif
+
+#ifndef F_OPEN
+#  define F_OPEN(name, mode) fopen((name), (mode))
+#endif
+
+         /* functions */
+
+#if defined(pyr) || defined(Z_SOLO)
+#  define NO_MEMCPY
+#endif
+#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__)
+ /* Use our own functions for small and medium model with MSC <= 5.0.
+  * You may have to use the same strategy for Borland C (untested).
+  * The __SC__ check is for Symantec.
+  */
+#  define NO_MEMCPY
+#endif
+#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY)
+#  define HAVE_MEMCPY
+#endif
+#ifdef HAVE_MEMCPY
+#  ifdef SMALL_MEDIUM /* MSDOS small or medium model */
+#    define zmemcpy _fmemcpy
+#    define zmemcmp _fmemcmp
+#    define zmemzero(dest, len) _fmemset(dest, 0, len)
+#  else
+#    define zmemcpy memcpy
+#    define zmemcmp memcmp
+#    define zmemzero(dest, len) memset(dest, 0, len)
+#  endif
+#else
+   void ZLIB_INTERNAL zmemcpy OF((Bytef* dest, const Bytef* source, uInt len));
+   int ZLIB_INTERNAL zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len));
+   void ZLIB_INTERNAL zmemzero OF((Bytef* dest, uInt len));
+#endif
+
+/* Diagnostic functions */
+#ifdef DEBUG
+#  include <stdio.h>
+   extern int ZLIB_INTERNAL z_verbose;
+   extern void ZLIB_INTERNAL z_error OF((char *m));
+#  define Assert(cond,msg) {if(!(cond)) z_error(msg);}
+#  define Trace(x) {if (z_verbose>=0) fprintf x ;}
+#  define Tracev(x) {if (z_verbose>0) fprintf x ;}
+#  define Tracevv(x) {if (z_verbose>1) fprintf x ;}
+#  define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;}
+#  define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;}
+#else
+#  define Assert(cond,msg)
+#  define Trace(x)
+#  define Tracev(x)
+#  define Tracevv(x)
+#  define Tracec(c,x)
+#  define Tracecv(c,x)
+#endif
+
+#ifndef Z_SOLO
+   voidpf ZLIB_INTERNAL zcalloc OF((voidpf opaque, unsigned items,
+                                    unsigned size));
+   void ZLIB_INTERNAL zcfree  OF((voidpf opaque, voidpf ptr));
+#endif
+
+#define ZALLOC(strm, items, size) \
+           (*((strm)->zalloc))((strm)->opaque, (items), (size))
+#define ZFREE(strm, addr)  (*((strm)->zfree))((strm)->opaque, (voidpf)(addr))
+#define TRY_FREE(s, p) {if (p) ZFREE(s, p);}
+
+/* Reverse the bytes in a 32-bit value */
+#define ZSWAP32(q) ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \
+                    (((q) & 0xff00) << 8) + (((q) & 0xff) << 24))
+
+#endif /* ZUTIL_H */
diff --git a/doc/Access.3 b/doc/Access.3
new file mode 100644
index 0000000..699d7ed
--- /dev/null
+++ b/doc/Access.3
@@ -0,0 +1,71 @@
+'\"
+'\" Copyright (c) 1998-1999 Scriptics Corporation
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH Tcl_Access 3 8.1 Tcl "Tcl Library Procedures"
+.so man.macros
+.BS
+.SH NAME
+Tcl_Access, Tcl_Stat \- check file permissions and other attributes
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+int
+\fBTcl_Access\fR(\fIpath\fR, \fImode\fR)
+.sp
+int
+\fBTcl_Stat\fR(\fIpath\fR, \fIstatPtr\fR)
+.SH ARGUMENTS
+.AS "struct stat" *statPtr out
+.AP char *path in
+Native name of the file to check the attributes of.
+.AP int mode in
+Mask consisting of one or more of \fBR_OK\fR, \fBW_OK\fR, \fBX_OK\fR and
+\fBF_OK\fR. \fBR_OK\fR, \fBW_OK\fR and \fBX_OK\fR request checking whether the
+file exists and has read, write and execute permissions, respectively.
+\fBF_OK\fR just requests a check for the existence of the file.
+.AP "struct stat" *statPtr out
+The structure that contains the result.
+.BE
+.SH DESCRIPTION
+.PP
+As of Tcl 8.4, the object-based APIs \fBTcl_FSAccess\fR and \fBTcl_FSStat\fR
+should be used in preference to \fBTcl_Access\fR and \fBTcl_Stat\fR, wherever
+possible. Those functions also support Tcl's virtual filesystem layer, which
+these do not.
+.SS "OBSOLETE FUNCTIONS"
+.PP
+There are two reasons for calling \fBTcl_Access\fR and \fBTcl_Stat\fR rather
+than calling system level functions \fBaccess\fR and \fBstat\fR directly.
+First, the Windows implementation of both functions fixes some bugs in the
+system level calls. Second, both \fBTcl_Access\fR and \fBTcl_Stat\fR (as well
+as \fBTcl_OpenFileChannelProc\fR) hook into a linked list of functions. This
+allows the possibility to reroute file access to alternative media or access
+methods.
+.PP
+\fBTcl_Access\fR checks whether the process would be allowed to read, write or
+test for existence of the file (or other file system object) whose name is
+\fIpath\fR. If \fIpath\fR is a symbolic link on Unix, then permissions of the
+file referred by this symbolic link are tested.
+.PP
+On success (all requested permissions granted), zero is returned. On error (at
+least one bit in mode asked for a permission that is denied, or some other
+error occurred), -1 is returned.
+.PP
+\fBTcl_Stat\fR fills the stat structure \fIstatPtr\fR with information about
+the specified file. You do not need any access rights to the file to get this
+information but you need search rights to all directories named in the path
+leading to the file. The stat structure includes info regarding device, inode
+(always 0 on Windows), privilege mode, nlink (always 1 on Windows), user id
+(always 0 on Windows), group id (always 0 on Windows), rdev (same as device on
+Windows), size, last access time, last modification time, and creation time.
+.PP
+If \fIpath\fR exists, \fBTcl_Stat\fR returns 0 and the stat structure is
+filled with data. Otherwise, -1 is returned, and no stat info is given.
+.SH KEYWORDS
+stat, access
+.SH "SEE ALSO"
+Tcl_FSAccess(3), Tcl_FSStat(3)
diff --git a/doc/AddErrInfo.3 b/doc/AddErrInfo.3
new file mode 100644
index 0000000..caba125
--- /dev/null
+++ b/doc/AddErrInfo.3
@@ -0,0 +1,312 @@
+'\"
+'\" Copyright (c) 1989-1993 The Regents of the University of California.
+'\" Copyright (c) 1994-1997 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH Tcl_AddErrorInfo 3 8.5 Tcl "Tcl Library Procedures"
+.so man.macros
+.BS
+.SH NAME
+Tcl_GetReturnOptions, Tcl_SetReturnOptions, Tcl_AddErrorInfo, Tcl_AppendObjToErrorInfo, Tcl_AddObjErrorInfo, Tcl_SetObjErrorCode, Tcl_SetErrorCode, Tcl_SetErrorCodeVA, Tcl_SetErrorLine, Tcl_GetErrorLine, Tcl_PosixError, Tcl_LogCommandInfo \- retrieve or record information about errors and other return options
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+Tcl_Obj *
+\fBTcl_GetReturnOptions\fR(\fIinterp, code\fR)
+.sp
+int
+\fBTcl_SetReturnOptions\fR(\fIinterp, options\fR)
+.sp
+\fBTcl_AddErrorInfo\fR(\fIinterp, message\fR)
+.sp
+\fBTcl_AppendObjToErrorInfo\fR(\fIinterp, objPtr\fR)
+.sp
+\fBTcl_AddObjErrorInfo\fR(\fIinterp, message, length\fR)
+.sp
+\fBTcl_SetObjErrorCode\fR(\fIinterp, errorObjPtr\fR)
+.sp
+\fBTcl_SetErrorCode\fR(\fIinterp, element, element, ... \fB(char *) NULL\fR)
+.sp
+\fBTcl_SetErrorCodeVA\fR(\fIinterp, argList\fR)
+.sp
+\fBTcl_GetErrorLine\fR(\fIinterp\fR)
+.sp
+\fBTcl_SetErrorLine\fR(\fIinterp, lineNum\fR)
+.sp
+const char *
+\fBTcl_PosixError\fR(\fIinterp\fR)
+.sp
+void
+\fBTcl_LogCommandInfo\fR(\fIinterp, script, command, commandLength\fR)
+.SH ARGUMENTS
+.AS Tcl_Interp commandLength
+.AP Tcl_Interp *interp in
+Interpreter in which to record information.
+.AP int code
+The code returned from script evaluation.
+.AP Tcl_Obj *options
+A dictionary of return options.
+.AP char *message in
+For \fBTcl_AddErrorInfo\fR,
+this is a conventional C string to append to the \fB\-errorinfo\fR return option.
+For \fBTcl_AddObjErrorInfo\fR,
+this points to the first byte of an array of \fIlength\fR bytes
+containing a string to append to the \fB\-errorinfo\fR return option.
+This byte array may contain embedded null bytes
+unless \fIlength\fR is negative.
+.AP Tcl_Obj *objPtr in
+A message to be appended to the \fB\-errorinfo\fR return option
+in the form of a Tcl_Obj value.
+.AP int length in
+The number of bytes to copy from \fImessage\fR when
+appending to the \fB\-errorinfo\fR return option.
+If negative, all bytes up to the first null byte are used.
+.AP Tcl_Obj *errorObjPtr in
+The \fB\-errorcode\fR return option will be set to this value.
+.AP char *element in
+String to record as one element of the \fB\-errorcode\fR return option.
+Last \fIelement\fR argument must be NULL.
+.AP va_list argList in
+An argument list which must have been initialized using
+\fBva_start\fR, and cleared using \fBva_end\fR.
+.AP int lineNum
+The line number of a script where an error occurred.
+.AP "const char" *script in
+Pointer to first character in script containing command (must be <= command)
+.AP "const char" *command in
+Pointer to first character in command that generated the error
+.AP int commandLength in
+Number of bytes in command; -1 means use all bytes up to first null byte
+.BE
+.SH DESCRIPTION
+.PP
+The \fBTcl_SetReturnOptions\fR and \fBTcl_GetReturnOptions\fR
+routines expose the same capabilities as the \fBreturn\fR and
+\fBcatch\fR commands, respectively, in the form of a C interface.
+.PP
+\fBTcl_GetReturnOptions\fR retrieves the dictionary of return options
+from an interpreter following a script evaluation.
+Routines such as \fBTcl_Eval\fR are called to evaluate a
+script in an interpreter.  These routines return an integer
+completion code.  These routines also leave in the interpreter
+both a result and a dictionary of return options generated
+by script evaluation.  Just as \fBTcl_GetObjResult\fR retrieves
+the result, \fBTcl_GetReturnOptions\fR retrieves the dictionary
+of return options.  The integer completion code should be
+passed as the \fIcode\fR argument to \fBTcl_GetReturnOptions\fR
+so that all required options will be present in the dictionary.
+Specifically, a \fIcode\fR value of \fBTCL_ERROR\fR will
+ensure that entries for the keys \fB\-errorinfo\fR,
+\fB\-errorcode\fR, and \fB\-errorline\fR will appear in the
+dictionary.  Also, the entries for the keys \fB\-code\fR
+and \fB\-level\fR will be adjusted if necessary to agree
+with the value of \fIcode\fR.  The \fB(Tcl_Obj *)\fR returned
+by \fBTcl_GetReturnOptions\fR points to an unshared
+\fBTcl_Obj\fR with reference count of zero.  The dictionary
+may be written to, either adding, removing, or overwriting
+any entries in it, without the need to check for a shared value.
+As with any \fBTcl_Obj\fR with reference count of zero, it is up to
+the caller to arrange for its disposal with \fBTcl_DecrRefCount\fR or
+to a reference to it via \fBTcl_IncrRefCount\fR (or one of the many
+functions that call that, notably including \fBTcl_SetObjResult\fR and
+\fBTcl_SetVar2Ex\fR).
+.PP
+A typical usage for \fBTcl_GetReturnOptions\fR is to
+retrieve the stack trace when script evaluation returns
+\fBTCL_ERROR\fR, like so:
+.PP
+.CS
+int code = Tcl_Eval(interp, script);
+if (code == TCL_ERROR) {
+    Tcl_Obj *options = \fBTcl_GetReturnOptions\fR(interp, code);
+    Tcl_Obj *key = Tcl_NewStringObj("-errorinfo", -1);
+    Tcl_Obj *stackTrace;
+    Tcl_IncrRefCount(key);
+    Tcl_DictObjGet(NULL, options, key, &stackTrace);
+    Tcl_DecrRefCount(key);
+    /* Do something with stackTrace */
+    Tcl_DecrRefCount(options);
+}
+.CE
+.PP
+\fBTcl_SetReturnOptions\fR sets the return options
+of \fIinterp\fR to be \fIoptions\fR.  If \fIoptions\fR
+contains any invalid value for any key, TCL_ERROR will
+be returned, and the interp result will be set to an
+appropriate error message.  Otherwise, a completion code
+in agreement with the \fB\-code\fR and \fB\-level\fR
+keys in \fIoptions\fR will be returned.
+.PP
+As an example, Tcl's \fBreturn\fR command itself could
+be implemented in terms of \fBTcl_SetReturnOptions\fR
+like so:
+.PP
+.CS
+if ((objc % 2) == 0) { /* explicit result argument */
+    objc--;
+    Tcl_SetObjResult(interp, objv[objc]);
+}
+return \fBTcl_SetReturnOptions\fR(interp, Tcl_NewListObj(objc-1, objv+1));
+.CE
+.PP
+(It is not really implemented that way.  Internal access
+privileges allow for a more efficient alternative that meshes
+better with the bytecode compiler.)
+.PP
+Note that a newly created \fBTcl_Obj\fR may be passed
+in as the \fIoptions\fR argument without the need to tend
+to any reference counting.  This is analogous to
+\fBTcl_SetObjResult\fR.
+.PP
+While \fBTcl_SetReturnOptions\fR provides a general interface
+to set any collection of return options, there are a handful
+of return options that are very frequently used.  Most
+notably the \fB\-errorinfo\fR and \fB\-errorcode\fR return
+options should be set properly when the command procedure
+of a command returns \fBTCL_ERROR\fR.  The \fB\-errorline\fR
+return option is also read by commands that evaluate scripts
+and wish to supply detailed error location information in
+the stack trace text they append to the \fB\-errorinfo\fR option.
+Tcl provides several simpler interfaces to more directly set
+these return options.
+.PP
+The \fB\-errorinfo\fR option holds a stack trace of the
+operations that were in progress when an error occurred,
+and is intended to be human-readable.
+The \fB\-errorcode\fR option holds a Tcl list of items that
+are intended to be machine-readable.
+The first item in the \fB\-errorcode\fR value identifies the class of
+error that occurred
+(e.g., POSIX means an error occurred in a POSIX system call)
+and additional elements hold additional pieces
+of information that depend on the class.
+See the manual entry on the \fBerrorCode\fR variable for details on the
+various formats for the \fB\-errorcode\fR option used by Tcl's built-in
+commands.
+.PP
+The \fB\-errorinfo\fR option value is gradually built up as an
+error unwinds through the nested operations.
+Each time an error code is returned to \fBTcl_Eval\fR, or
+any of the routines that performs script evaluation,
+the procedure \fBTcl_AddErrorInfo\fR is called to add
+additional text to the \fB\-errorinfo\fR value describing the
+command that was being executed when the error occurred.
+By the time the error has been passed all the way back
+to the application, it will contain a complete trace
+of the activity in progress when the error occurred.
+.PP
+It is sometimes useful to add additional information to
+the \fB\-errorinfo\fR value beyond what can be supplied automatically
+by the script evaluation routines.
+\fBTcl_AddErrorInfo\fR may be used for this purpose:
+its \fImessage\fR argument is an additional
+string to be appended to the \fB\-errorinfo\fR option.
+For example, when an error arises during the \fBsource\fR command,
+the procedure \fBTcl_AddErrorInfo\fR is called to
+record the name of the file being processed and the
+line number on which the error occurred.
+Likewise, when an error arises during evaluation of a
+Tcl procedures, the procedure name and line number
+within the procedure are recorded, and so on.
+The best time to call \fBTcl_AddErrorInfo\fR is just after
+a script evaluation routine has returned \fBTCL_ERROR\fR.
+The value of the \fB\-errorline\fR return option (retrieved
+via a call to \fBTcl_GetReturnOptions\fR) often makes up
+a useful part of the \fImessage\fR passed to \fBTcl_AddErrorInfo\fR.
+.PP
+\fBTcl_AppendObjToErrorInfo\fR is an alternative interface to the
+same functionality as \fBTcl_AddErrorInfo\fR.  \fBTcl_AppendObjToErrorInfo\fR
+is called when the string value to be appended to the \fB\-errorinfo\fR option
+is available as a \fBTcl_Obj\fR instead of as a \fBchar\fR array.
+.PP
+\fBTcl_AddObjErrorInfo\fR is nearly identical
+to \fBTcl_AddErrorInfo\fR, except that it has an additional \fIlength\fR
+argument.  This allows the \fImessage\fR string to contain
+embedded null bytes.  This is essentially never a good idea.
+If the \fImessage\fR needs to contain the null character \fBU+0000\fR,
+Tcl's usual internal encoding rules should be used to avoid
+the need for a null byte.  If the \fBTcl_AddObjErrorInfo\fR
+interface is used at all, it should be with a negative \fIlength\fR value.
+.PP
+The procedure \fBTcl_SetObjErrorCode\fR is used to set the
+\fB\-errorcode\fR return option to the list value \fIerrorObjPtr\fR
+built up by the caller.
+\fBTcl_SetObjErrorCode\fR is typically invoked just
+before returning an error. If an error is
+returned without calling \fBTcl_SetObjErrorCode\fR or
+\fBTcl_SetErrorCode\fR the Tcl interpreter automatically sets
+the \fB\-errorcode\fR return option to \fBNONE\fR.
+.PP
+The procedure \fBTcl_SetErrorCode\fR is also used to set the
+\fB\-errorcode\fR return option. However, it takes one or more strings to
+record instead of a value. Otherwise, it is similar to
+\fBTcl_SetObjErrorCode\fR in behavior.
+.PP
+\fBTcl_SetErrorCodeVA\fR is the same as \fBTcl_SetErrorCode\fR except that
+instead of taking a variable number of arguments it takes an argument list.
+.PP
+The procedure \fBTcl_GetErrorLine\fR is used to read the integer value
+of the \fB\-errorline\fR return option without the overhead of a full
+call to \fBTcl_GetReturnOptions\fR.  Likewise, \fBTcl_SetErrorLine\fR
+sets the \fB\-errorline\fR return option value.
+.PP
+\fBTcl_PosixError\fR
+sets the \fB\-errorcode\fR variable after an error in a POSIX kernel call.
+It reads the value of the \fBerrno\fR C variable and calls
+\fBTcl_SetErrorCode\fR to set the \fB\-errorcode\fR return
+option in the \fBPOSIX\fR format.
+The caller must previously have called \fBTcl_SetErrno\fR to set
+\fBerrno\fR; this is necessary on some platforms (e.g. Windows) where Tcl
+is linked into an application as a shared library, or when the error
+occurs in a dynamically loaded extension. See the manual entry for
+\fBTcl_SetErrno\fR for more information.
+.PP
+\fBTcl_PosixError\fR returns a human-readable diagnostic message
+for the error
+(this is the same value that will appear as the third element
+in the \fB\-errorcode\fR value).
+It may be convenient to include this string as part of the
+error message returned to the application in
+the interpreter's result.
+.PP
+\fBTcl_LogCommandInfo\fR is invoked after an error occurs in an
+interpreter.  It adds information about the command that was being
+executed when the error occurred to the \fB\-errorinfo\fR value, and
+the line number stored internally in the interpreter is set.
+.PP
+In older releases of Tcl, there was no \fBTcl_GetReturnOptions\fR
+routine.  In its place, the global Tcl variables \fBerrorInfo\fR
+and \fBerrorCode\fR were the only place to retrieve the error
+information.  Much existing code written for older Tcl releases
+still access this information via those global variables.
+.PP
+It is important to realize that while reading from those
+global variables remains a supported way to access these
+return option values, it is important not to assume that
+writing to those global variables will properly set the
+corresponding return options.  It has long been emphasized
+in this manual page that it is important to
+call the procedures described here rather than
+setting \fBerrorInfo\fR or \fBerrorCode\fR directly with
+\fBTcl_ObjSetVar2\fR.
+.PP
+If the procedure \fBTcl_ResetResult\fR is called,
+it clears all of the state of the interpreter associated with
+script evaluation, including the entire return options dictionary.
+In particular, the \fB\-errorinfo\fR and \fB\-errorcode\fR options
+are reset.
+If an error had occurred, the \fBTcl_ResetResult\fR call will
+clear the error state to make it appear as if no error had
+occurred after all.
+The global variables \fBerrorInfo\fR and
+\fBerrorCode\fR are not modified by \fBTcl_ResetResult\fR
+so they continue to hold a record of information about the
+most recent error seen in an interpreter.
+.SH "SEE ALSO"
+Tcl_DecrRefCount(3), Tcl_IncrRefCount(3), Tcl_Interp(3), Tcl_ResetResult(3),
+Tcl_SetErrno(3), errorCode(n), errorInfo(n)
+.SH KEYWORDS
+error, value, value result, stack, trace, variable
diff --git a/doc/Alloc.3 b/doc/Alloc.3
new file mode 100644
index 0000000..8f25c52
--- /dev/null
+++ b/doc/Alloc.3
@@ -0,0 +1,92 @@
+'\"
+'\" Copyright (c) 1995-1996 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH Tcl_Alloc 3 7.5 Tcl "Tcl Library Procedures"
+.so man.macros
+.BS
+.SH NAME
+Tcl_Alloc, Tcl_Free, Tcl_Realloc, Tcl_AttemptAlloc, Tcl_AttemptRealloc, ckalloc, ckfree, ckrealloc, attemptckalloc, attemptckrealloc \- allocate or free heap memory
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+char *
+\fBTcl_Alloc\fR(\fIsize\fR)
+.sp
+void
+\fBTcl_Free\fR(\fIptr\fR)
+.sp
+char *
+\fBTcl_Realloc\fR(\fIptr, size\fR)
+.sp
+char *
+\fBTcl_AttemptAlloc\fR(\fIsize\fR)
+.sp
+char *
+\fBTcl_AttemptRealloc\fR(\fIptr, size\fR)
+.sp
+char *
+\fBckalloc\fR(\fIsize\fR)
+.sp
+void
+\fBckfree\fR(\fIptr\fR)
+.sp
+char *
+\fBckrealloc\fR(\fIptr, size\fR)
+.sp
+char *
+\fBattemptckalloc\fR(\fIsize\fR)
+.sp
+char *
+\fBattemptckrealloc\fR(\fIptr, size\fR)
+.SH ARGUMENTS
+.AS char *size
+.AP "unsigned int" size in
+Size in bytes of the memory block to allocate.
+.AP char *ptr in
+Pointer to memory block to free or realloc.
+.BE
+
+.SH DESCRIPTION
+.PP
+These procedures provide a platform and compiler independent interface
+for memory allocation.  Programs that need to transfer ownership of
+memory blocks between Tcl and other modules should use these routines
+rather than the native \fBmalloc()\fR and \fBfree()\fR routines
+provided by the C run-time library.
+.PP
+\fBTcl_Alloc\fR returns a pointer to a block of at least \fIsize\fR
+bytes suitably aligned for any use.
+.PP
+\fBTcl_Free\fR makes the space referred to by \fIptr\fR available for
+further allocation.
+.PP
+\fBTcl_Realloc\fR changes the size of the block pointed to by
+\fIptr\fR to \fIsize\fR bytes and returns a pointer to the new block.
+The contents will be unchanged up to the lesser of the new and old
+sizes.  The returned location may be different from \fIptr\fR.  If
+\fIptr\fR is NULL, this is equivalent to calling \fBTcl_Alloc\fR with
+just the \fIsize\fR argument.
+.PP
+\fBTcl_AttemptAlloc\fR and \fBTcl_AttemptRealloc\fR are identical in
+function to \fBTcl_Alloc\fR and \fBTcl_Realloc\fR, except that
+\fBTcl_AttemptAlloc\fR and \fBTcl_AttemptRealloc\fR will not cause the Tcl
+interpreter to \fBpanic\fR if the memory allocation fails.  If the
+allocation fails, these functions will return NULL.  Note that on some
+platforms, but not all, attempting to allocate a zero-sized block of
+memory will also cause these functions to return NULL.
+.PP
+The procedures \fBckalloc\fR, \fBckfree\fR, \fBckrealloc\fR,
+\fBattemptckalloc\fR, and \fBattemptckrealloc\fR are implemented
+as macros.  Normally, they are synonyms for the corresponding
+procedures documented on this page.  When Tcl and all modules
+calling Tcl are compiled with \fBTCL_MEM_DEBUG\fR defined, however,
+these macros are redefined to be special debugging versions
+of these procedures.  To support Tcl's memory debugging within a
+module, use the macros rather than direct calls to \fBTcl_Alloc\fR, etc.
+
+.SH KEYWORDS
+alloc, allocation, free, malloc, memory, realloc, TCL_MEM_DEBUG
diff --git a/doc/AllowExc.3 b/doc/AllowExc.3
new file mode 100644
index 0000000..172bb30
--- /dev/null
+++ b/doc/AllowExc.3
@@ -0,0 +1,44 @@
+'\"
+'\" Copyright (c) 1989-1993 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH Tcl_AllowExceptions 3 7.4 Tcl "Tcl Library Procedures"
+.so man.macros
+.BS
+.SH NAME
+Tcl_AllowExceptions \- allow all exceptions in next script evaluation
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+\fBTcl_AllowExceptions\fR(\fIinterp\fR)
+.SH ARGUMENTS
+.AS Tcl_Interp *interp
+.AP Tcl_Interp *interp in
+Interpreter in which script will be evaluated.
+.BE
+
+.SH DESCRIPTION
+.PP
+If a script is evaluated at top-level (i.e. no other scripts are
+pending evaluation when the script is invoked), and if the script
+terminates with a completion code other than \fBTCL_OK\fR, \fBTCL_ERROR\fR
+or \fBTCL_RETURN\fR, then Tcl normally converts this into a \fBTCL_ERROR\fR
+return with an appropriate message.  The particular script
+evaluation procedures of Tcl that act in the manner are
+\fBTcl_EvalObjEx\fR, \fBTcl_EvalObjv\fR, \fBTcl_Eval\fR, \fBTcl_EvalEx\fR,
+\fBTcl_GlobalEval\fR, \fBTcl_GlobalEvalObj\fR, \fBTcl_VarEval\fR and
+\fBTcl_VarEvalVA\fR.
+.PP
+However, if \fBTcl_AllowExceptions\fR is invoked immediately before
+calling one of those a procedures, then arbitrary completion
+codes are permitted from the script, and they are returned without
+modification.
+This is useful in cases where the caller can deal with exceptions
+such as \fBTCL_BREAK\fR or \fBTCL_CONTINUE\fR in a meaningful way.
+
+.SH KEYWORDS
+continue, break, exception, interpreter
diff --git a/doc/AppInit.3 b/doc/AppInit.3
new file mode 100644
index 0000000..44b2d6b
--- /dev/null
+++ b/doc/AppInit.3
@@ -0,0 +1,83 @@
+'\"
+'\" Copyright (c) 1993 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH Tcl_AppInit 3 7.0 Tcl "Tcl Library Procedures"
+.so man.macros
+.BS
+.SH NAME
+Tcl_AppInit \- perform application-specific initialization
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+int
+\fBTcl_AppInit\fR(\fIinterp\fR)
+.SH ARGUMENTS
+.AS Tcl_Interp *interp
+.AP Tcl_Interp *interp in
+Interpreter for the application.
+.BE
+
+.SH DESCRIPTION
+.PP
+\fBTcl_AppInit\fR is a
+.QW hook
+procedure that is invoked by
+the main programs for Tcl applications such as \fBtclsh\fR and \fBwish\fR.
+Its purpose is to allow new Tcl applications to be created without
+modifying the main programs provided as part of Tcl and Tk.
+To create a new application you write a new version of
+\fBTcl_AppInit\fR to replace the default version provided by Tcl,
+then link your new \fBTcl_AppInit\fR with the Tcl library.
+.PP
+\fBTcl_AppInit\fR is invoked by \fBTcl_Main\fR and \fBTk_Main\fR
+after their own initialization and before entering the main loop
+to process commands.
+Here are some examples of things that \fBTcl_AppInit\fR might do:
+.IP [1]
+Call initialization procedures for various packages used by
+the application.
+Each initialization procedure adds new commands to \fIinterp\fR
+for its package and performs other package-specific initialization.
+.IP [2]
+Process command-line arguments, which can be accessed from the
+Tcl variables \fBargv\fR and \fBargv0\fR in \fIinterp\fR.
+.IP [3]
+Invoke a startup script to initialize the application.
+.IP [4]
+Use the routines \fBTcl_SetStartupScript\fR and
+\fBTcl_GetStartupScript\fR to set or query the file and encoding
+that the active \fBTcl_Main\fR or \fBTk_Main\fR routine will
+use as a startup script.
+.LP
+\fBTcl_AppInit\fR returns \fBTCL_OK\fR or \fBTCL_ERROR\fR.
+If it returns \fBTCL_ERROR\fR then it must leave an error message in
+for the interpreter's result;  otherwise the result is ignored.
+.PP
+In addition to \fBTcl_AppInit\fR, your application should also contain
+a procedure \fBmain\fR that calls \fBTcl_Main\fR as follows:
+.PP
+.CS
+Tcl_Main(argc, argv, Tcl_AppInit);
+.CE
+.PP
+The third argument to \fBTcl_Main\fR gives the address of the
+application-specific initialization procedure to invoke.
+This means that you do not have to use the name \fBTcl_AppInit\fR
+for the procedure, but in practice the name is nearly always
+\fBTcl_AppInit\fR (in versions before Tcl 7.4 the name \fBTcl_AppInit\fR
+was implicit;  there was no way to specify the procedure explicitly).
+The best way to get started is to make a copy of the file
+\fBtclAppInit.c\fR from the Tcl library or source directory.
+It already contains a \fBmain\fR procedure and a template for
+\fBTcl_AppInit\fR that you can modify for your application.
+
+.SH "SEE ALSO"
+Tcl_Main(3)
+
+.SH KEYWORDS
+application, argument, command, initialization, interpreter
diff --git a/doc/AssocData.3 b/doc/AssocData.3
new file mode 100644
index 0000000..d4fa3d7
--- /dev/null
+++ b/doc/AssocData.3
@@ -0,0 +1,87 @@
+'\"
+'\" Copyright (c) 1995-1996 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH Tcl_SetAssocData 3 7.5 Tcl "Tcl Library Procedures"
+.so man.macros
+.BS
+.SH NAME
+Tcl_GetAssocData, Tcl_SetAssocData, Tcl_DeleteAssocData \- manage associations of string keys and user specified data with Tcl interpreters
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+ClientData
+\fBTcl_GetAssocData\fR(\fIinterp, key, delProcPtr\fR)
+.sp
+\fBTcl_SetAssocData\fR(\fIinterp, key, delProc, clientData\fR)
+.sp
+\fBTcl_DeleteAssocData\fR(\fIinterp, key\fR)
+.SH ARGUMENTS
+.AS Tcl_InterpDeleteProc **delProcPtr
+.AP Tcl_Interp *interp in
+Interpreter in which to execute the specified command.
+.AP "const char" *key in
+Key for association with which to store data or from which to delete or
+retrieve data.  Typically the module prefix for a package.
+.AP Tcl_InterpDeleteProc *delProc in
+Procedure to call when \fIinterp\fR is deleted.
+.AP Tcl_InterpDeleteProc **delProcPtr in
+Pointer to location in which to store address of current deletion procedure
+for association.  Ignored if NULL.
+.AP ClientData clientData in
+Arbitrary one-word value associated with the given key in this
+interpreter.  This data is owned by the caller.
+.BE
+
+.SH DESCRIPTION
+.PP
+These procedures allow extensions to associate their own data with
+a Tcl interpreter.
+An association consists of a string key, typically the name of
+the extension, and a one-word value, which is typically a pointer
+to a data structure holding data specific to the extension.
+Tcl makes no interpretation of either the key or the value for
+an association.
+.PP
+Storage management is facilitated by storing with each association a
+procedure to call when the interpreter is deleted. This
+procedure can dispose of the storage occupied by the client's data in any
+way it sees fit.
+.PP
+\fBTcl_SetAssocData\fR creates an association between a string
+key and a user specified datum in the given interpreter.
+If there is already an association with the given \fIkey\fR,
+\fBTcl_SetAssocData\fR overwrites it with the new information.
+It is up to callers to organize their use of names to avoid conflicts,
+for example, by using package names as the keys.
+If the \fIdeleteProc\fR argument is non-NULL it specifies the address of a
+procedure to invoke if the interpreter is deleted before the association
+is deleted.  \fIDeleteProc\fR should have arguments and result that match
+the type \fBTcl_InterpDeleteProc\fR:
+.PP
+.CS
+typedef void \fBTcl_InterpDeleteProc\fR(
+        ClientData \fIclientData\fR,
+        Tcl_Interp *\fIinterp\fR);
+.CE
+.PP
+When \fIdeleteProc\fR is invoked the \fIclientData\fR and \fIinterp\fR
+arguments will be the same as the corresponding arguments passed to
+\fBTcl_SetAssocData\fR.
+The deletion procedure will \fInot\fR be invoked if the association
+is deleted before the interpreter is deleted.
+.PP
+\fBTcl_GetAssocData\fR returns the datum stored in the association with the
+specified key in the given interpreter, and if the \fIdelProcPtr\fR field
+is non-\fBNULL\fR, the address indicated by it gets the address of the
+delete procedure stored with this association. If no association with the
+specified key exists in the given interpreter \fBTcl_GetAssocData\fR
+returns \fBNULL\fR.
+.PP
+\fBTcl_DeleteAssocData\fR deletes an association with a specified key in
+the given interpreter.  Then it calls the deletion procedure.
+.SH KEYWORDS
+association, data, deletion procedure, interpreter, key
diff --git a/doc/Async.3 b/doc/Async.3
new file mode 100644
index 0000000..347ba3d
--- /dev/null
+++ b/doc/Async.3
@@ -0,0 +1,161 @@
+'\"
+'\" Copyright (c) 1989-1993 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH Tcl_AsyncCreate 3 7.0 Tcl "Tcl Library Procedures"
+.so man.macros
+.BS
+.SH NAME
+Tcl_AsyncCreate, Tcl_AsyncMark, Tcl_AsyncInvoke, Tcl_AsyncDelete, Tcl_AsyncReady \- handle asynchronous events
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+Tcl_AsyncHandler
+\fBTcl_AsyncCreate\fR(\fIproc, clientData\fR)
+.sp
+\fBTcl_AsyncMark\fR(\fIasync\fR)
+.sp
+int
+\fBTcl_AsyncInvoke\fR(\fIinterp, code\fR)
+.sp
+\fBTcl_AsyncDelete\fR(\fIasync\fR)
+.sp
+int
+\fBTcl_AsyncReady\fR()
+.SH ARGUMENTS
+.AS Tcl_AsyncHandler clientData
+.AP Tcl_AsyncProc *proc in
+Procedure to invoke to handle an asynchronous event.
+.AP ClientData clientData in
+One-word value to pass to \fIproc\fR.
+.AP Tcl_AsyncHandler async in
+Token for asynchronous event handler.
+.AP Tcl_Interp *interp in
+Tcl interpreter in which command was being evaluated when handler was
+invoked, or NULL if handler was invoked when there was no interpreter
+active.
+.AP int code in
+Completion code from command that just completed in \fIinterp\fR,
+or 0 if \fIinterp\fR is NULL.
+.BE
+
+.SH DESCRIPTION
+.PP
+These procedures provide a safe mechanism for dealing with
+asynchronous events such as signals.
+If an event such as a signal occurs while a Tcl script is being
+evaluated then it is not safe to take any substantive action to
+process the event.
+For example, it is not safe to evaluate a Tcl script since the
+interpreter may already be in the middle of evaluating a script;
+it may not even be safe to allocate memory, since a memory
+allocation could have been in progress when the event occurred.
+The only safe approach is to set a flag indicating that the event
+occurred, then handle the event later when the world has returned
+to a clean state, such as after the current Tcl command completes.
+.PP
+\fBTcl_AsyncCreate\fR, \fBTcl_AsyncDelete\fR, and \fBTcl_AsyncReady\fR
+are thread sensitive.  They access and/or set a thread-specific data
+structure in the event of a core built with \fI\-\-enable\-threads\fR.  The token
+created by \fBTcl_AsyncCreate\fR contains the needed thread information it
+was called from so that calling \fBTcl_AsyncMark\fR(\fItoken\fR) will only yield
+the origin thread into the asynchronous handler.
+.PP
+\fBTcl_AsyncCreate\fR creates an asynchronous handler and returns
+a token for it.
+The asynchronous handler must be created before
+any occurrences of the asynchronous event that it is intended
+to handle (it is not safe to create a handler at the time of
+an event).
+When an asynchronous event occurs the code that detects the event
+(such as a signal handler) should call \fBTcl_AsyncMark\fR with the
+token for the handler.
+\fBTcl_AsyncMark\fR will mark the handler as ready to execute, but it
+will not invoke the handler immediately.
+Tcl will call the \fIproc\fR associated with the handler later, when
+the world is in a safe state, and \fIproc\fR can then carry out
+the actions associated with the asynchronous event.
+\fIProc\fR should have arguments and result that match the
+type \fBTcl_AsyncProc\fR:
+.PP
+.CS
+typedef int \fBTcl_AsyncProc\fR(
+        ClientData \fIclientData\fR,
+        Tcl_Interp *\fIinterp\fR,
+        int \fIcode\fR);
+.CE
+.PP
+The \fIclientData\fR will be the same as the \fIclientData\fR
+argument passed to \fBTcl_AsyncCreate\fR when the handler was
+created.
+If \fIproc\fR is invoked just after a command has completed
+execution in an interpreter, then \fIinterp\fR will identify
+the interpreter in which the command was evaluated and
+\fIcode\fR will be the completion code returned by that
+command.
+The command's result will be present in the interpreter's result.
+When \fIproc\fR returns, whatever it leaves in the interpreter's result
+will be returned as the result of the command and the integer
+value returned by \fIproc\fR will be used as the new completion
+code for the command.
+.PP
+It is also possible for \fIproc\fR to be invoked when no interpreter
+is active.
+This can happen, for example, if an asynchronous event occurs while
+the application is waiting for interactive input or an X event.
+In this case \fIinterp\fR will be NULL and \fIcode\fR will be
+0, and the return value from \fIproc\fR will be ignored.
+.PP
+The procedure \fBTcl_AsyncInvoke\fR is called to invoke all of the
+handlers that are ready.
+The procedure \fBTcl_AsyncReady\fR will return non-zero whenever any
+asynchronous handlers are ready;  it can be checked to avoid calls
+to \fBTcl_AsyncInvoke\fR when there are no ready handlers.
+Tcl calls \fBTcl_AsyncReady\fR after each command is evaluated
+and calls \fBTcl_AsyncInvoke\fR if needed.
+Applications may also call \fBTcl_AsyncInvoke\fR at interesting
+times for that application.
+For example, Tcl's event handler calls \fBTcl_AsyncReady\fR
+after each event and calls \fBTcl_AsyncInvoke\fR if needed.
+The \fIinterp\fR and \fIcode\fR arguments to \fBTcl_AsyncInvoke\fR
+have the same meaning as for \fIproc\fR:  they identify the active
+interpreter, if any, and the completion code from the command
+that just completed.
+.PP
+\fBTcl_AsyncDelete\fR removes an asynchronous handler so that
+its \fIproc\fR will never be invoked again.
+A handler can be deleted even when ready, and it will still
+not be invoked.
+.PP
+If multiple handlers become active at the same time, the
+handlers are invoked in the order they were created (oldest
+handler first).
+The \fIcode\fR and the interpreter's result for later handlers
+reflect the values returned by earlier handlers, so that
+the most recently created handler has last say about
+the interpreter's result and completion code.
+If new handlers become ready while handlers are executing,
+\fBTcl_AsyncInvoke\fR will invoke them all;  at each point it
+invokes the highest-priority (oldest) ready handler, repeating
+this over and over until there are no longer any ready handlers.
+.SH WARNING
+.PP
+It is almost always a bad idea for an asynchronous event
+handler to modify the interpreter's result or return a code different
+from its \fIcode\fR argument.
+This sort of behavior can disrupt the execution of scripts in
+subtle ways and result in bugs that are extremely difficult
+to track down.
+If an asynchronous event handler needs to evaluate Tcl scripts
+then it should first save the interpreter's state by calling
+\fBTcl_SaveInterpState\fR, passing in the \fIcode\fR argument.
+When the asynchronous handler is finished it should restore
+the interpreter's state by calling \fBTcl_RestoreInterpState\fR,
+and then returning the \fIcode\fR argument.
+
+.SH KEYWORDS
+asynchronous event, handler, signal, Tcl_SaveInterpState, thread
diff --git a/doc/BackgdErr.3 b/doc/BackgdErr.3
new file mode 100644
index 0000000..adbe33c
--- /dev/null
+++ b/doc/BackgdErr.3
@@ -0,0 +1,78 @@
+'\"
+'\" Copyright (c) 1992-1994 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH Tcl_BackgroundError 3 7.5 Tcl "Tcl Library Procedures"
+.so man.macros
+.BS
+.SH NAME
+Tcl_BackgroundException, Tcl_BackgroundError \- report Tcl exception that occurred in background processing
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+\fBTcl_BackgroundException\fR(\fIinterp, code\fR)
+.sp
+\fBTcl_BackgroundError\fR(\fIinterp\fR)
+.SH ARGUMENTS
+.AS Tcl_Interp *interp
+.AP Tcl_Interp *interp in
+Interpreter in which the exception occurred.
+.AP int code in
+The exceptional return code to be reported.
+.BE
+
+.SH DESCRIPTION
+.PP
+This procedure is typically invoked when a Tcl exception (any
+return code other than TCL_OK) occurs during
+.QW "background processing"
+such as executing an event handler.
+When such an exception occurs, the condition is reported to Tcl
+or to a widget or some other C code, and there is not usually any
+obvious way for that code to report the exception to the user.
+In these cases the code calls \fBTcl_BackgroundException\fR with an
+\fIinterp\fR argument identifying the interpreter in which the
+exception occurred, and a \fIcode\fR argument holding the return
+code value of the exception.  The state of the interpreter, including
+any error message in the interpreter result, and the values of
+any entries in the return options dictionary, is captured and
+saved.  \fBTcl_BackgroundException\fR then arranges for the event
+loop to invoke at some later time the command registered
+in that interpreter to handle background errors by the
+\fBinterp bgerror\fR command, passing the captured values as
+arguments.
+The registered handler command is meant to report the exception
+in an application-specific fashion.  The handler command
+receives two arguments, the result of the interp, and the
+return options of the interp at the time the error occurred.
+If the application registers no handler command, the default
+handler command will attempt to call \fBbgerror\fR to report
+the error.  If an error condition arises while invoking the
+handler command, then \fBTcl_BackgroundException\fR reports the
+error itself by printing a message on the standard error file.
+.PP
+\fBTcl_BackgroundException\fR does not invoke the handler command immediately
+because this could potentially interfere with scripts that are in process
+at the time the error occurred.
+Instead, it invokes the handler command later as an idle callback.
+.PP
+It is possible for many background exceptions to accumulate before
+the handler command is invoked.  When this happens, each of the exceptions
+is processed in order.  However, if the handler command returns a
+break exception, then all remaining error reports for the
+interpreter are skipped.
+.PP
+The \fBTcl_BackgroundError\fR routine is an older and simpler interface
+useful when the exception code reported is \fBTCL_ERROR\fR.  It is
+equivalent to:
+.PP
+.CS
+Tcl_BackgroundException(interp, TCL_ERROR);
+.CE
+
+.SH KEYWORDS
+background, bgerror, error, interp
diff --git a/doc/Backslash.3 b/doc/Backslash.3
new file mode 100644
index 0000000..0805f8e
--- /dev/null
+++ b/doc/Backslash.3
@@ -0,0 +1,47 @@
+'\"
+'\" Copyright (c) 1989-1993 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH Tcl_Backslash 3 "8.1" Tcl "Tcl Library Procedures"
+.so man.macros
+.BS
+.SH NAME
+Tcl_Backslash \- parse a backslash sequence
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+char
+\fBTcl_Backslash\fR(\fIsrc, countPtr\fR)
+.SH ARGUMENTS
+.AS char *countPtr out
+.AP char *src in
+Pointer to a string starting with a backslash.
+.AP int *countPtr out
+If \fIcountPtr\fR is not NULL, \fI*countPtr\fR gets filled
+in with number of characters in the backslash sequence, including
+the backslash character.
+.BE
+
+.SH DESCRIPTION
+.PP
+The use of \fBTcl_Backslash\fR is deprecated in favor of
+\fBTcl_UtfBackslash\fR.
+.PP
+This is a utility procedure provided for backwards compatibility with
+non-internationalized Tcl extensions.  It parses a backslash sequence and
+returns the low byte of the Unicode character corresponding to the sequence.
+\fBTcl_Backslash\fR modifies \fI*countPtr\fR to contain the number of
+characters in the backslash sequence.
+.PP
+See the Tcl manual entry for information on the valid backslash sequences.
+All of the sequences described in the Tcl manual entry are supported by
+\fBTcl_Backslash\fR.
+.SH "SEE ALSO"
+Tcl(n), Tcl_UtfBackslash(3)
+
+.SH KEYWORDS
+backslash, parse
diff --git a/doc/BoolObj.3 b/doc/BoolObj.3
new file mode 100644
index 0000000..7268e1f
--- /dev/null
+++ b/doc/BoolObj.3
@@ -0,0 +1,95 @@
+'\"
+'\" Copyright (c) 1996-1997 Sun Microsystems, Inc.
+'\" Contributions from Don Porter, NIST, 2005.  (not subject to US copyright)
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH Tcl_BooleanObj 3 8.5 Tcl "Tcl Library Procedures"
+.so man.macros
+.BS
+.SH NAME
+Tcl_NewBooleanObj, Tcl_SetBooleanObj, Tcl_GetBooleanFromObj \- store/retrieve boolean value in a Tcl_Obj
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+Tcl_Obj *
+\fBTcl_NewBooleanObj\fR(\fIboolValue\fR)
+.sp
+\fBTcl_SetBooleanObj\fR(\fIobjPtr, boolValue\fR)
+.sp
+int
+\fBTcl_GetBooleanFromObj\fR(\fIinterp, objPtr, boolPtr\fR)
+.SH ARGUMENTS
+.AS Tcl_Interp boolValue in/out
+.AP int boolValue in
+Integer value to be stored as a boolean value in a Tcl_Obj.
+.AP Tcl_Obj *objPtr in/out
+Points to the Tcl_Obj in which to store, or from which to
+retrieve a boolean value.
+.AP Tcl_Interp *interp in/out
+If a boolean value cannot be retrieved,
+an error message is left in the interpreter's result value
+unless \fIinterp\fR is NULL.
+.AP int *boolPtr out
+Points to place where \fBTcl_GetBooleanFromObj\fR
+stores the boolean value (0 or 1) obtained from \fIobjPtr\fR.
+.BE
+
+.SH DESCRIPTION
+.PP
+These procedures are used to pass boolean values to and from
+Tcl as Tcl_Obj's.  When storing a boolean value into a Tcl_Obj,
+any non-zero integer value in \fIboolValue\fR is taken to be
+the boolean value \fB1\fR, and the integer value \fB0\fR is
+taken to be the boolean value \fB0\fR.
+.PP
+\fBTcl_NewBooleanObj\fR creates a new Tcl_Obj, stores the boolean
+value \fIboolValue\fR in it, and returns a pointer to the new Tcl_Obj.
+The new Tcl_Obj has reference count of zero.
+.PP
+\fBTcl_SetBooleanObj\fR accepts \fIobjPtr\fR, a pointer to
+an existing Tcl_Obj, and stores in the Tcl_Obj \fI*objPtr\fR
+the boolean value \fIboolValue\fR.  This is a write operation
+on \fI*objPtr\fR, so \fIobjPtr\fR must be unshared.  Attempts to
+write to a shared Tcl_Obj will panic.  A successful write
+of \fIboolValue\fR into \fI*objPtr\fR implies the freeing of
+any former value stored in \fI*objPtr\fR.
+.PP
+\fBTcl_GetBooleanFromObj\fR attempts to retrieve a boolean value
+from the value stored in \fI*objPtr\fR.
+If \fIobjPtr\fR holds a string value recognized by \fBTcl_GetBoolean\fR,
+then the recognized boolean value is written at the address given
+by \fIboolPtr\fR.
+If \fIobjPtr\fR holds any value recognized as
+a number by Tcl, then if that value is zero a 0 is written at
+the address given by \fIboolPtr\fR and if that
+value is non-zero a 1 is written at the address given by \fIboolPtr\fR.
+In all cases where a value is written at the address given
+by \fIboolPtr\fR, \fBTcl_GetBooleanFromObj\fR returns \fBTCL_OK\fR.
+If the value of \fIobjPtr\fR does not meet any of the conditions
+above, then \fBTCL_ERROR\fR is returned and an error message is
+left in the interpreter's result unless \fIinterp\fR is NULL.
+\fBTcl_GetBooleanFromObj\fR may also make changes to the internal
+fields of \fI*objPtr\fR so that future calls to
+\fBTcl_GetBooleanFromObj\fR on the same \fIobjPtr\fR can be
+performed more efficiently.
+.PP
+Note that the routines \fBTcl_GetBooleanFromObj\fR and
+\fBTcl_GetBoolean\fR are not functional equivalents.
+The set of values for which \fBTcl_GetBooleanFromObj\fR
+will return \fBTCL_OK\fR is strictly larger than
+the set of values for which \fBTcl_GetBoolean\fR will do the same.
+For example, the value
+.QW 5
+passed to \fBTcl_GetBooleanFromObj\fR
+will lead to a \fBTCL_OK\fR return (and the boolean value 1),
+while the same value passed to \fBTcl_GetBoolean\fR will lead to
+a \fBTCL_ERROR\fR return.
+
+.SH "SEE ALSO"
+Tcl_NewObj, Tcl_IsShared, Tcl_GetBoolean
+
+.SH KEYWORDS
+boolean, value
diff --git a/doc/ByteArrObj.3 b/doc/ByteArrObj.3
new file mode 100644
index 0000000..ff0b4e1
--- /dev/null
+++ b/doc/ByteArrObj.3
@@ -0,0 +1,91 @@
+'\"
+'\" Copyright (c) 1997 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH Tcl_ByteArrayObj 3 8.1 Tcl "Tcl Library Procedures"
+.so man.macros
+.BS
+.SH NAME
+Tcl_NewByteArrayObj, Tcl_SetByteArrayObj, Tcl_GetByteArrayFromObj, Tcl_SetByteArrayLength \- manipulate Tcl values as a arrays of bytes
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+Tcl_Obj *
+\fBTcl_NewByteArrayObj\fR(\fIbytes, length\fR)
+.sp
+void
+\fBTcl_SetByteArrayObj\fR(\fIobjPtr, bytes, length\fR)
+.sp
+unsigned char *
+\fBTcl_GetByteArrayFromObj\fR(\fIobjPtr, lengthPtr\fR)
+.sp
+unsigned char *
+\fBTcl_SetByteArrayLength\fR(\fIobjPtr, length\fR)
+.SH ARGUMENTS
+.AS "const unsigned char" *lengthPtr in/out
+.AP "const unsigned char" *bytes in
+The array of bytes used to initialize or set a byte-array value. May be NULL
+even if \fIlength\fR is non-zero.
+.AP int length in
+The length of the array of bytes.  It must be >= 0.
+.AP Tcl_Obj *objPtr in/out
+For \fBTcl_SetByteArrayObj\fR, this points to the value to be converted to
+byte-array type.  For \fBTcl_GetByteArrayFromObj\fR and
+\fBTcl_SetByteArrayLength\fR, this points to the value from which to get
+the byte-array value; if \fIobjPtr\fR does not already point to a byte-array
+value, it will be converted to one.
+.AP int *lengthPtr out
+If non-NULL, filled with the length of the array of bytes in the value.
+.BE
+
+.SH DESCRIPTION
+.PP
+These procedures are used to create, modify, and read Tcl byte-array values
+from C code.  Byte-array values are typically used to hold the
+results of binary IO operations or data structures created with the
+\fBbinary\fR command.  In Tcl, an array of bytes is not equivalent to a
+string.  Conceptually, a string is an array of Unicode characters, while a
+byte-array is an array of 8-bit quantities with no implicit meaning.
+Accessor functions are provided to get the string representation of a
+byte-array or to convert an arbitrary value to a byte-array.  Obtaining the
+string representation of a byte-array value (by calling
+\fBTcl_GetStringFromObj\fR) produces a properly formed UTF-8 sequence with a
+one-to-one mapping between the bytes in the internal representation and the
+UTF-8 characters in the string representation.
+.PP
+\fBTcl_NewByteArrayObj\fR and \fBTcl_SetByteArrayObj\fR will
+create a new value of byte-array type or modify an existing value to have a
+byte-array type.  Both of these procedures set the value's type to be
+byte-array and set the value's internal representation to a copy of the
+array of bytes given by \fIbytes\fR. \fBTcl_NewByteArrayObj\fR returns a
+pointer to a newly allocated value with a reference count of zero.
+\fBTcl_SetByteArrayObj\fR invalidates any old string representation and, if
+the value is not already a byte-array value, frees any old internal
+representation. If \fIbytes\fR is NULL then the new byte array contains
+arbitrary values.
+.PP
+\fBTcl_GetByteArrayFromObj\fR converts a Tcl value to byte-array type and
+returns a pointer to the value's new internal representation as an array of
+bytes.  The length of this array is stored in \fIlengthPtr\fR if
+\fIlengthPtr\fR is non-NULL.  The storage for the array of bytes is owned by
+the value and should not be freed.  The contents of the array may be
+modified by the caller only if the value is not shared and the caller
+invalidates the string representation.
+.PP
+\fBTcl_SetByteArrayLength\fR converts the Tcl value to byte-array type
+and changes the length of the value's internal representation as an
+array of bytes.  If \fIlength\fR is greater than the space currently
+allocated for the array, the array is reallocated to the new length; the
+newly allocated bytes at the end of the array have arbitrary values.  If
+\fIlength\fR is less than the space currently allocated for the array,
+the length of array is reduced to the new length.  The return value is a
+pointer to the value's new array of bytes.
+
+.SH "SEE ALSO"
+Tcl_GetStringFromObj, Tcl_NewObj, Tcl_IncrRefCount, Tcl_DecrRefCount
+
+.SH KEYWORDS
+value, binary data, byte array, utf, unicode, internationalization
diff --git a/doc/CallDel.3 b/doc/CallDel.3
new file mode 100644
index 0000000..766621a
--- /dev/null
+++ b/doc/CallDel.3
@@ -0,0 +1,67 @@
+'\"
+'\" Copyright (c) 1993 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\" 
+.TH Tcl_CallWhenDeleted 3 7.0 Tcl "Tcl Library Procedures"
+.so man.macros
+.BS
+.SH NAME
+Tcl_CallWhenDeleted, Tcl_DontCallWhenDeleted \- Arrange for callback when interpreter is deleted
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+\fBTcl_CallWhenDeleted\fR(\fIinterp\fR, \fIproc\fR, \fIclientData\fR)
+.sp
+\fBTcl_DontCallWhenDeleted\fR(\fIinterp\fR, \fIproc\fR, \fIclientData\fR)
+.SH ARGUMENTS
+.AS Tcl_InterpDeleteProc clientData
+.AP Tcl_Interp *interp in
+Interpreter with which to associated callback.
+.AP Tcl_InterpDeleteProc *proc in
+Procedure to call when \fIinterp\fR is deleted.
+.AP ClientData clientData in
+Arbitrary one-word value to pass to \fIproc\fR.
+.BE
+.SH DESCRIPTION
+.PP
+\fBTcl_CallWhenDeleted\fR arranges for \fIproc\fR to be called by
+\fBTcl_DeleteInterp\fR if/when \fIinterp\fR is deleted at some future
+time.  \fIProc\fR will be invoked just before the interpreter
+is deleted, but the interpreter will still be valid at the
+time of the call.
+\fIProc\fR should have arguments and result that match the
+type \fBTcl_InterpDeleteProc\fR:
+.PP
+.CS
+typedef void \fBTcl_InterpDeleteProc\fR(
+        ClientData \fIclientData\fR,
+        Tcl_Interp *\fIinterp\fR);
+.CE
+.PP
+The \fIclientData\fR and \fIinterp\fR parameters are
+copies of the \fIclientData\fR and \fIinterp\fR arguments given
+to \fBTcl_CallWhenDeleted\fR.
+Typically, \fIclientData\fR points to an application-specific
+data structure that \fIproc\fR uses to perform cleanup when an
+interpreter is about to go away.
+\fIProc\fR does not return a value.
+.PP
+\fBTcl_DontCallWhenDeleted\fR cancels a previous call to
+\fBTcl_CallWhenDeleted\fR with the same arguments, so that
+\fIproc\fR will not be called after all when \fIinterp\fR is
+deleted.
+If there is no deletion callback that matches \fIinterp\fR,
+\fIproc\fR, and \fIclientData\fR then the call to
+\fBTcl_DontCallWhenDeleted\fR has no effect.
+.PP
+Note that if the callback is being used to delete a resource that \fImust\fR
+be released on exit, \fBTcl_CreateExitHandler\fR should be used to ensure that
+a callback is received even if the application terminates without deleting the interpreter.
+.SH "SEE ALSO"
+Tcl_CreateExitHandler(3), Tcl_CreateThreadExitHandler(3)
+.SH KEYWORDS
+callback, cleanup, delete, interpreter
diff --git a/doc/Cancel.3 b/doc/Cancel.3
new file mode 100644
index 0000000..847707e
--- /dev/null
+++ b/doc/Cancel.3
@@ -0,0 +1,74 @@
+'\"
+'\" Copyright (c) 2006-2008 Joe Mistachkin.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH Tcl_Cancel 3 8.6 Tcl "Tcl Library Procedures"
+.so man.macros
+.BS
+.SH NAME
+Tcl_CancelEval, Tcl_Canceled \- cancel Tcl scripts
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+int
+\fBTcl_CancelEval\fR(\fIinterp, resultObjPtr, clientData, flags\fR)
+.sp
+int
+\fBTcl_Canceled\fR(\fIinterp, flags\fR)
+.SH ARGUMENTS
+.AS Tcl_Interp *interp
+.AP Tcl_Interp *interp in
+Interpreter in which to cancel the script.
+.AP Tcl_Obj *resultObjPtr in
+Error message to use in the cancellation, or NULL to use a default message. If
+not NULL, this object will have its reference count decremented before
+\fBTcl_CancelEval\fR returns.
+.AP int flags in
+ORed combination of flag bits that specify additional options.
+For \fBTcl_CancelEval\fR, only \fBTCL_CANCEL_UNWIND\fR is currently
+supported.  For \fBTcl_Canceled\fR, only \fBTCL_LEAVE_ERR_MSG\fR and
+\fBTCL_CANCEL_UNWIND\fR are currently supported.
+.AP ClientData clientData in
+Currently reserved for future use.
+It should be set to NULL.
+.BE
+.SH DESCRIPTION
+.PP
+\fBTcl_CancelEval\fR cancels or unwinds the script in progress soon after
+the next invocation of asynchronous handlers, causing \fBTCL_ERROR\fR to be
+the return code for that script.  This function is thread-safe and may be
+called from any thread in the process.
+.PP
+\fBTcl_Canceled\fR checks if the script in progress has been canceled and
+returns \fBTCL_ERROR\fR if it has.  Otherwise, \fBTCL_OK\fR is returned.
+Extensions can use this function to check to see if they should abort a long
+running command.  This function is thread sensitive and may only be called
+from the thread the interpreter was created in.
+.SS "FLAG BITS"
+Any ORed combination of the following values may be used for the
+\fIflags\fR argument to procedures such as \fBTcl_CancelEval\fR:
+.TP 20
+\fBTCL_CANCEL_UNWIND\fR
+.
+This flag is used by \fBTcl_CancelEval\fR and \fBTcl_Canceled\fR.
+For \fBTcl_CancelEval\fR, if this flag is set, the script in progress
+is canceled and the evaluation stack for the interpreter is unwound.
+For \fBTcl_Canceled\fR, if this flag is set, the script in progress
+is considered to be canceled only if the evaluation stack for the
+interpreter is being unwound.
+.TP 20
+\fBTCL_LEAVE_ERR_MSG\fR
+.
+This flag is only used by \fBTcl_Canceled\fR; it is ignored by
+other procedures.  If an error is returned and this bit is set in
+\fIflags\fR, then an error message will be left in the interpreter's
+result, where it can be retrieved with \fBTcl_GetObjResult\fR or
+\fBTcl_GetStringResult\fR.  If this flag bit is not set then no error
+message is left and the interpreter's result will not be modified.
+.SH "SEE ALSO"
+interp(n), Tcl_Eval(3),
+TIP 285
+.SH KEYWORDS
+cancel, unwind
diff --git a/doc/ChnlStack.3 b/doc/ChnlStack.3
new file mode 100644
index 0000000..b046cd2
--- /dev/null
+++ b/doc/ChnlStack.3
@@ -0,0 +1,97 @@
+'\"
+'\" Copyright (c) 1999-2000 Ajuba Solutions.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+.TH Tcl_StackChannel 3 8.3 Tcl "Tcl Library Procedures"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+Tcl_StackChannel, Tcl_UnstackChannel, Tcl_GetStackedChannel, Tcl_GetTopChannel \- manipulate stacked I/O channels
+.SH SYNOPSIS
+.nf
+.nf
+\fB#include <tcl.h>\fR
+.sp
+Tcl_Channel
+\fBTcl_StackChannel\fR(\fIinterp, typePtr, clientData, mask, channel\fR)
+.sp
+int
+\fBTcl_UnstackChannel\fR(\fIinterp, channel\fR)
+.sp
+Tcl_Channel
+\fBTcl_GetStackedChannel\fR(\fIchannel\fR)
+.sp
+Tcl_Channel
+\fBTcl_GetTopChannel\fR(\fIchannel\fR)
+.sp
+.SH ARGUMENTS
+.AS Tcl_ChannelType clientData
+.AP Tcl_Interp *interp in
+Interpreter for error reporting.
+.AP "const Tcl_ChannelType" *typePtr in
+The new channel I/O procedures to use for \fIchannel\fR.
+.AP ClientData clientData in
+Arbitrary one-word value to pass to channel I/O procedures.
+.AP int mask in
+Conditions under which \fIchannel\fR will be used: OR-ed combination of
+\fBTCL_READABLE\fR, \fBTCL_WRITABLE\fR and \fBTCL_EXCEPTION\fR.
+This can be a subset of the operations currently allowed on \fIchannel\fR.
+.AP Tcl_Channel channel in
+An existing Tcl channel such as returned by \fBTcl_CreateChannel\fR.
+.BE
+
+.SH DESCRIPTION
+.PP
+These functions are for use by extensions that add processing layers to Tcl
+I/O channels.  Examples include compression and encryption modules.  These
+functions transparently stack and unstack a new channel on top of an
+existing one.  Any number of channels can be stacked together.
+.PP
+The implementation of the Tcl channel code was rewritten in 8.3.2 to
+correct some problems with the previous implementation with regard to
+stacked channels.  Anyone using stacked channels or creating stacked
+channel drivers should update to the new \fBTCL_CHANNEL_VERSION_2\fR
+\fBTcl_ChannelType\fR structure.  See \fBTcl_CreateChannel\fR for details.
+.PP
+\fBTcl_StackChannel\fR stacks a new \fIchannel\fR on an existing channel
+with the same name that was registered for \fIchannel\fR by
+\fBTcl_RegisterChannel\fR.
+.PP
+\fBTcl_StackChannel\fR works by creating a new channel structure and
+placing itself on top of the channel stack.  EOL translation, encoding and
+buffering options are shared between all channels in the stack.  The hidden
+channel does no buffering, newline translations, or character set encoding.
+Instead, the buffering, newline translations, and encoding functions all
+remain at the top of the channel stack.  A pointer to the new top channel
+structure is returned.  If an error occurs when stacking the channel, NULL
+is returned instead.
+.PP
+The \fImask\fR parameter specifies the operations that are allowed on the
+new channel.  These can be a subset of the operations allowed on the
+original channel.  For example, a read-write channel may become read-only
+after the \fBTcl_StackChannel\fR call.
+.PP
+Closing a channel closes the channels stacked below it.  The close of
+stacked channels is executed in a way that allows buffered data to be
+properly flushed.
+.PP
+\fBTcl_UnstackChannel\fR reverses the process.  The old channel is
+associated with the channel name, and the processing module added by
+\fBTcl_StackChannel\fR is destroyed.  If there is no old channel, then
+\fBTcl_UnstackChannel\fR is equivalent to \fBTcl_Close\fR.  If an error
+occurs unstacking the channel, \fBTCL_ERROR\fR is returned, otherwise
+\fBTCL_OK\fR is returned.
+.PP
+\fBTcl_GetTopChannel\fR returns the top channel in the stack of
+channels the supplied channel is part of.
+.PP
+\fBTcl_GetStackedChannel\fR returns the channel in the stack of
+channels which is just below the supplied channel.
+
+.SH "SEE ALSO"
+Notifier(3), Tcl_CreateChannel(3), Tcl_OpenFileChannel(3), vwait(n).
+
+.SH KEYWORDS
+channel, compression
diff --git a/doc/Class.3 b/doc/Class.3
new file mode 100644
index 0000000..1c3fe08
--- /dev/null
+++ b/doc/Class.3
@@ -0,0 +1,237 @@
+'\"
+'\" Copyright (c) 2007 Donal K. Fellows
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH Tcl_Class 3 0.1 TclOO "TclOO Library Functions"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+Tcl_ClassGetMetadata, Tcl_ClassSetMetadata, Tcl_CopyObjectInstance, Tcl_GetClassAsObject, Tcl_GetObjectAsClass, Tcl_GetObjectCommand, Tcl_GetObjectFromObj, Tcl_GetObjectName, Tcl_GetObjectNamespace, Tcl_NewObjectInstance, Tcl_ObjectDeleted, Tcl_ObjectGetMetadata, Tcl_ObjectGetMethodNameMapper, Tcl_ObjectSetMetadata, Tcl_ObjectSetMethodNameMapper \- manipulate objects and classes
+.SH SYNOPSIS
+.nf
+\fB#include <tclOO.h>\fR
+.sp
+Tcl_Object
+\fBTcl_GetObjectFromObj\fR(\fIinterp, objPtr\fR)
+.sp
+Tcl_Object
+\fBTcl_GetClassAsObject\fR(\fIclass\fR)
+.sp
+Tcl_Class
+\fBTcl_GetObjectAsClass\fR(\fIobject\fR)
+.sp
+Tcl_Obj *
+\fBTcl_GetObjectName\fR(\fIinterp, object\fR)
+.sp
+Tcl_Command
+\fBTcl_GetObjectCommand\fR(\fIobject\fR)
+.sp
+Tcl_Namespace *
+\fBTcl_GetObjectNamespace\fR(\fIobject\fR)
+.sp
+Tcl_Object
+\fBTcl_NewObjectInstance\fR(\fIinterp, class, name, nsName, objc, objv, skip\fR)
+.sp
+Tcl_Object
+\fBTcl_CopyObjectInstance\fR(\fIinterp, object, name, nsName\fR)
+.sp
+int
+\fBTcl_ObjectDeleted\fR(\fIobject\fR)
+.sp
+ClientData
+\fBTcl_ObjectGetMetadata\fR(\fIobject, metaTypePtr\fR)
+.sp
+\fBTcl_ObjectSetMetadata\fR(\fIobject, metaTypePtr, metadata\fR)
+.sp
+ClientData
+\fBTcl_ClassGetMetadata\fR(\fIclass, metaTypePtr\fR)
+.sp
+\fBTcl_ClassSetMetadata\fR(\fIclass, metaTypePtr, metadata\fR)
+.sp
+Tcl_ObjectMapMethodNameProc
+\fBTcl_ObjectGetMethodNameMapper\fR(\fIobject\fR)
+.sp
+\fBTcl_ObjectSetMethodNameMapper\fR(\fIobject\fR, \fImethodNameMapper\fR)
+.SH ARGUMENTS
+.AS ClientData metadata in/out
+.AP Tcl_Interp *interp in/out
+Interpreter providing the context for looking up or creating an object, and
+into whose result error messages will be written on failure.
+.AP Tcl_Obj *objPtr in
+The name of the object to look up.
+.AP Tcl_Object object in
+Reference to the object to operate upon.
+.AP Tcl_Class class in
+Reference to the class to operate upon.
+.AP "const char" *name in
+The name of the object to create, or NULL if a new unused name is to be
+automatically selected.
+.AP "const char" *nsName in
+The name of the namespace to create for the object's private use, or NULL if a
+new unused name is to be automatically selected. The namespace must not
+already exist.
+.AP int objc in
+The number of elements in the \fIobjv\fR array.
+.AP "Tcl_Obj *const" *objv in
+The arguments to the command to create the instance of the class.
+.AP int skip in
+The number of arguments at the start of the argument array, \fIobjv\fR, that
+are not arguments to any constructors.
+.AP Tcl_ObjectMetadataType *metaTypePtr in
+The type of \fImetadata\fR being set with \fBTcl_ClassSetMetadata\fR or
+retrieved with \fBTcl_ClassGetMetadata\fR.
+.AP ClientData metadata in
+An item of metadata to attach to the class, or NULL to remove the metadata
+associated with a particular \fImetaTypePtr\fR.
+.AP "Tcl_ObjectMapMethodNameProc" "methodNameMapper" in
+A pointer to a function to call to adjust the mapping of objects and method
+names to implementations, or NULL when no such mapping is required.
+.BE
+.SH DESCRIPTION
+.PP
+Objects are typed entities that have a set of operations ("methods")
+associated with them. Classes are objects that can manufacture objects. Each
+class can be viewed as an object itself; the object view can be retrieved
+using \fBTcl_GetClassAsObject\fR which always returns the object when applied
+to a non-destroyed class, and an object can be viewed as a class with the aid
+of the \fBTcl_GetObjectAsClass\fR (which either returns the class, or NULL if
+the object is not a class). An object may be looked up using the
+\fBTcl_GetObjectFromObj\fR function, which either returns an object or NULL
+(with an error message in the interpreter result) if the object cannot be
+found. The correct way to look up a class by name is to look up the object
+with that name, and then to use \fBTcl_GetObjectAsClass\fR.
+.PP
+Every object has its own command and namespace associated with it. The command
+may be retrieved using the \fBTcl_GetObjectCommand\fR function, the name of
+the object (and hence the name of the command) with \fBTcl_GetObjectName\fR,
+and the namespace may be retrieved using the \fBTcl_GetObjectNamespace\fR
+function. Note that the Tcl_Obj reference returned by \fBTcl_GetObjectName\fR
+is a shared reference.
+.PP
+Instances of classes are created using \fBTcl_NewObjectInstance\fR, which
+creates an object from any class (and which is internally called by both
+the \fBcreate\fR and \fBnew\fR methods of the \fBoo::class\fR class). It takes
+parameters that optionally give the name of the object and namespace to
+create, and which describe the arguments to pass to the class's constructor
+(if any). The result of the function will be either a reference to the newly
+created object, or NULL if the creation failed (when an error message will be
+left in the interpreter result). In addition, objects may be copied by using
+\fBTcl_CopyObjectInstance\fR which creates a copy of an object without running
+any constructors.
+.SH "OBJECT AND CLASS METADATA"
+.PP
+Every object and every class may have arbitrary amounts of metadata attached
+to it, which the object or class attaches no meaning to beyond what is
+described in a Tcl_ObjectMetadataType structure instance. Metadata to be
+attached is described by the type of the metadata (given in the
+\fImetaTypePtr\fR argument) and an arbitrary pointer (the \fImetadata\fR
+argument) that are given to \fBTcl_ObjectSetMetadata\fR and
+\fBTcl_ClassSetMetadata\fR, and a particular piece of metadata can be
+retrieved given its type using \fBTcl_ObjectGetMetadata\fR and
+\fBTcl_ClassGetMetadata\fR. If the \fImetadata\fR parameter to either
+\fBTcl_ObjectSetMetadata\fR or \fBTcl_ClassSetMetadata\fR is NULL, the
+metadata is removed if it was attached, and the results of
+\fBTcl_ObjectGetMetadata\fR and \fBTcl_ClassGetMetadata\fR are NULL if the
+given type of metadata was not attached. It is not an error to request or
+remove a piece of metadata that was not attached.
+.SS "TCL_OBJECTMETADATATYPE STRUCTURE"
+.PP
+The contents of the Tcl_ObjectMetadataType structure are as follows:
+.PP
+.CS
+typedef const struct {
+    int \fIversion\fR;
+    const char *\fIname\fR;
+    Tcl_ObjectMetadataDeleteProc *\fIdeleteProc\fR;
+    Tcl_CloneProc *\fIcloneProc\fR;
+} \fBTcl_ObjectMetadataType\fR;
+.CE
+.PP
+The \fIversion\fR field allows for future expansion of the structure, and
+should always be declared equal to TCL_OO_METADATA_VERSION_CURRENT. The
+\fIname\fR field provides a human-readable name for the type, and is reserved
+for debugging.
+.PP
+The \fIdeleteProc\fR field gives a function of type
+Tcl_ObjectMetadataDeleteProc that is used to delete a particular piece of
+metadata, and is called when the attached metadata is replaced or removed; the
+field must not be NULL.
+.PP
+The \fIcloneProc\fR field gives a function that is used to copy a piece of
+metadata (used when a copy of an object is created using
+\fBTcl_CopyObjectInstance\fR); if NULL, the metadata will be just directly
+copied.
+.SS "TCL_OBJECTMETADATADELETEPROC FUNCTION SIGNATURE"
+.PP
+Functions matching this signature are used to delete metadata associated with
+a class or object.
+.PP
+.CS
+typedef void \fBTcl_ObjectMetadataDeleteProc\fR(
+        ClientData \fImetadata\fR);
+.CE
+.PP
+The \fImetadata\fR argument gives the address of the metadata to be
+deleted.
+.SS "TCL_CLONEPROC FUNCTION SIGNATURE"
+.PP
+Functions matching this signature are used to create copies of metadata
+associated with a class or object.
+.PP
+.CS
+typedef int \fBTcl_CloneProc\fR(
+        Tcl_Interp *\fIinterp\fR,
+        ClientData \fIsrcMetadata\fR,
+        ClientData *\fIdstMetadataPtr\fR);
+.CE
+.PP
+The \fIinterp\fR argument gives a place to write an error message when the
+attempt to clone the object is to fail, in which case the clone procedure must
+also return TCL_ERROR; it should return TCL_OK otherwise.
+The \fIsrcMetadata\fR argument gives the address of the metadata to be cloned,
+and the cloned metadata should be written into the variable pointed to by
+\fIdstMetadataPtr\fR; a NULL should be written if the metadata is to not be
+cloned but the overall object copy operation is still to succeed.
+.SH "OBJECT METHOD NAME MAPPING"
+It is possible to control, on a per-object basis, what methods are invoked
+when a particular method is invoked. Normally this is done by looking up the
+method name in the object and then in the class hierarchy, but fine control of
+exactly what the value used to perform the look up is afforded through the
+ability to set a method name mapper callback via
+\fBTcl_ObjectSetMethodNameMapper\fR (and its introspection counterpart,
+\fBTcl_ObjectGetMethodNameMapper\fR, which returns the current mapper). The
+current mapper (if any) is invoked immediately before looking up what chain of
+method implementations is to be used.
+.SS "TCL_OBJECTMAPMETHODNAMEPROC FUNCTION SIGNATURE"
+The \fITcl_ObjectMapMethodNameProc\fR callback is defined as follows:
+.PP
+.CS
+typedef int \fBTcl_ObjectMapMethodNameProc\fR(
+        Tcl_Interp *\fIinterp\fR,
+        Tcl_Object \fIobject\fR,
+        Tcl_Class *\fIstartClsPtr\fR,
+        Tcl_Obj *\fImethodNameObj\fR);
+.CE
+.PP
+If the result is TCL_OK, the remapping is assumed to have been done. If the
+result is TCL_ERROR, an error message will have been left in \fIinterp\fR and
+the method call will fail. If the result is TCL_BREAK, the standard method
+name lookup rules will be used; the behavior of other result codes is
+currently undefined. The \fIobject\fR parameter says which object is being
+processed. The \fIstartClsPtr\fR parameter points to a variable that contains
+the first class to provide a definition in the method chain to process, or
+NULL if the whole chain is to be processed (the argument itself is never
+NULL); this variable may be updated by the callback. The \fImethodNameObj\fR
+parameter gives an unshared object containing the name of the method being
+invoked, as provided by the user; this object may be updated by the callback.
+.SH "SEE ALSO"
+Method(3), oo::class(n), oo::copy(n), oo::define(n), oo::object(n)
+.SH KEYWORDS
+class, constructor, object
+.\" Local variables:
+.\" mode: nroff
+.\" fill-column: 78
+.\" End:
diff --git a/doc/CmdCmplt.3 b/doc/CmdCmplt.3
new file mode 100644
index 0000000..25b372e
--- /dev/null
+++ b/doc/CmdCmplt.3
@@ -0,0 +1,34 @@
+'\"
+'\" Copyright (c) 1989-1993 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\" 
+.TH Tcl_CommandComplete 3 "" Tcl "Tcl Library Procedures"
+.so man.macros
+.BS
+.SH NAME
+Tcl_CommandComplete \- Check for unmatched braces in a Tcl command
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+int
+\fBTcl_CommandComplete\fR(\fIcmd\fR)
+.SH ARGUMENTS
+.AS "const char" *cmd
+.AP "const char" *cmd in
+Command string to test for completeness.
+.BE
+
+.SH DESCRIPTION
+.PP
+\fBTcl_CommandComplete\fR takes a Tcl command string
+as argument and determines whether it contains one or more
+complete commands (i.e. there are no unclosed quotes, braces,
+brackets, or variable references).
+If the command string is complete then it returns 1; otherwise it returns 0.
+
+.SH KEYWORDS
+complete command, partial command
diff --git a/doc/Concat.3 b/doc/Concat.3
new file mode 100644
index 0000000..58a0fb6
--- /dev/null
+++ b/doc/Concat.3
@@ -0,0 +1,51 @@
+'\"
+'\" Copyright (c) 1989-1993 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\" 
+.TH Tcl_Concat 3 7.5 Tcl "Tcl Library Procedures"
+.so man.macros
+.BS
+.SH NAME
+Tcl_Concat \- concatenate a collection of strings
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+const char *
+\fBTcl_Concat\fR(\fIargc, argv\fR)
+.SH ARGUMENTS
+.AS "const char *const" argv[]
+.AP int argc in
+Number of strings.
+.AP "const char *const" argv[] in
+Array of strings to concatenate.  Must have \fIargc\fR entries.
+.BE
+
+.SH DESCRIPTION
+.PP
+\fBTcl_Concat\fR is a utility procedure used by several of the
+Tcl commands.  Given a collection of strings, it concatenates
+them together into a single string, with the original strings
+separated by spaces.  This procedure behaves differently than
+\fBTcl_Merge\fR, in that the arguments are simply concatenated:
+no effort is made to ensure proper list structure.
+However, in most common usage the arguments will all be proper
+lists themselves;  if this is true, then the result will also have
+proper list structure.
+.PP
+\fBTcl_Concat\fR eliminates leading and trailing white space as it
+copies strings from \fBargv\fR to the result.  If an element of
+\fBargv\fR consists of nothing but white space, then that string
+is ignored entirely.  This white-space removal was added to make
+the output of the \fBconcat\fR command cleaner-looking.
+.PP
+The result string is dynamically allocated
+using \fBTcl_Alloc\fR;  the caller must eventually release the space
+by calling \fBTcl_Free\fR.
+.SH "SEE ALSO"
+Tcl_ConcatObj
+.SH KEYWORDS
+concatenate, strings
diff --git a/doc/CrtChannel.3 b/doc/CrtChannel.3
new file mode 100644
index 0000000..6ef94b5
--- /dev/null
+++ b/doc/CrtChannel.3
@@ -0,0 +1,928 @@
+'\"
+'\" Copyright (c) 1996-1997 Sun Microsystems, Inc.
+'\" Copyright (c) 1997-2000 Ajuba Solutions.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+.TH Tcl_CreateChannel 3 8.4 Tcl "Tcl Library Procedures"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+Tcl_CreateChannel, Tcl_GetChannelInstanceData, Tcl_GetChannelType, Tcl_GetChannelName, Tcl_GetChannelHandle, Tcl_GetChannelMode, Tcl_GetChannelBufferSize, Tcl_SetChannelBufferSize, Tcl_NotifyChannel, Tcl_BadChannelOption, Tcl_ChannelName, Tcl_ChannelVersion, Tcl_ChannelBlockModeProc, Tcl_ChannelCloseProc, Tcl_ChannelClose2Proc, Tcl_ChannelInputProc, Tcl_ChannelOutputProc, Tcl_ChannelSeekProc, Tcl_ChannelWideSeekProc, Tcl_ChannelTruncateProc, Tcl_ChannelSetOptionProc, Tcl_ChannelGetOptionProc, Tcl_ChannelWatchProc, Tcl_ChannelGetHandleProc, Tcl_ChannelFlushProc, Tcl_ChannelHandlerProc, Tcl_ChannelThreadActionProc, Tcl_IsChannelShared, Tcl_IsChannelRegistered, Tcl_CutChannel, Tcl_SpliceChannel, Tcl_IsChannelExisting, Tcl_ClearChannelHandlers, Tcl_GetChannelThread, Tcl_ChannelBuffered \- procedures for creating and manipulating channels
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+Tcl_Channel
+\fBTcl_CreateChannel\fR(\fItypePtr, channelName, instanceData, mask\fR)
+.sp
+ClientData
+\fBTcl_GetChannelInstanceData\fR(\fIchannel\fR)
+.sp
+const Tcl_ChannelType *
+\fBTcl_GetChannelType\fR(\fIchannel\fR)
+.sp
+const char *
+\fBTcl_GetChannelName\fR(\fIchannel\fR)
+.sp
+int
+\fBTcl_GetChannelHandle\fR(\fIchannel, direction, handlePtr\fR)
+.sp
+Tcl_ThreadId
+\fBTcl_GetChannelThread\fR(\fIchannel\fR)
+.sp
+int
+\fBTcl_GetChannelMode\fR(\fIchannel\fR)
+.sp
+int
+\fBTcl_GetChannelBufferSize\fR(\fIchannel\fR)
+.sp
+\fBTcl_SetChannelBufferSize\fR(\fIchannel, size\fR)
+.sp
+\fBTcl_NotifyChannel\fR(\fIchannel, mask\fR)
+.sp
+int
+\fBTcl_BadChannelOption\fR(\fIinterp, optionName, optionList\fR)
+.sp
+int
+\fBTcl_IsChannelShared\fR(\fIchannel\fR)
+.sp
+int
+\fBTcl_IsChannelRegistered\fR(\fIinterp, channel\fR)
+.sp
+int
+\fBTcl_IsChannelExisting\fR(\fIchannelName\fR)
+.sp
+void
+\fBTcl_CutChannel\fR(\fIchannel\fR)
+.sp
+void
+\fBTcl_SpliceChannel\fR(\fIchannel\fR)
+.sp
+void
+\fBTcl_ClearChannelHandlers\fR(\fIchannel\fR)
+.sp
+int
+\fBTcl_ChannelBuffered\fR(\fIchannel\fR)
+.sp
+const char *
+\fBTcl_ChannelName\fR(\fItypePtr\fR)
+.sp
+Tcl_ChannelTypeVersion
+\fBTcl_ChannelVersion\fR(\fItypePtr\fR)
+.sp
+Tcl_DriverBlockModeProc *
+\fBTcl_ChannelBlockModeProc\fR(\fItypePtr\fR)
+.sp
+Tcl_DriverCloseProc *
+\fBTcl_ChannelCloseProc\fR(\fItypePtr\fR)
+.sp
+Tcl_DriverClose2Proc *
+\fBTcl_ChannelClose2Proc\fR(\fItypePtr\fR)
+.sp
+Tcl_DriverInputProc *
+\fBTcl_ChannelInputProc\fR(\fItypePtr\fR)
+.sp
+Tcl_DriverOutputProc *
+\fBTcl_ChannelOutputProc\fR(\fItypePtr\fR)
+.sp
+Tcl_DriverSeekProc *
+\fBTcl_ChannelSeekProc\fR(\fItypePtr\fR)
+.sp
+Tcl_DriverWideSeekProc *
+\fBTcl_ChannelWideSeekProc\fR(\fItypePtr\fR)
+.sp
+Tcl_DriverThreadActionProc *
+\fBTcl_ChannelThreadActionProc\fR(\fItypePtr\fR)
+.sp
+Tcl_DriverTruncateProc *
+\fBTcl_ChannelTruncateProc\fR(\fItypePtr\fR)
+.sp
+Tcl_DriverSetOptionProc *
+\fBTcl_ChannelSetOptionProc\fR(\fItypePtr\fR)
+.sp
+Tcl_DriverGetOptionProc *
+\fBTcl_ChannelGetOptionProc\fR(\fItypePtr\fR)
+.sp
+Tcl_DriverWatchProc *
+\fBTcl_ChannelWatchProc\fR(\fItypePtr\fR)
+.sp
+Tcl_DriverGetHandleProc *
+\fBTcl_ChannelGetHandleProc\fR(\fItypePtr\fR)
+.sp
+Tcl_DriverFlushProc *
+\fBTcl_ChannelFlushProc\fR(\fItypePtr\fR)
+.sp
+Tcl_DriverHandlerProc *
+\fBTcl_ChannelHandlerProc\fR(\fItypePtr\fR)
+.sp
+.SH ARGUMENTS
+.AS "const Tcl_ChannelType" *channelName
+.AP "const Tcl_ChannelType" *typePtr in
+Points to a structure containing the addresses of procedures that
+can be called to perform I/O and other functions on the channel.
+.AP "const char" *channelName in
+The name of this channel, such as \fBfile3\fR; must not be in use
+by any other channel. Can be NULL, in which case the channel is
+created without a name. If the created channel is assigned to one
+of the standard channels (\fBstdin\fR, \fBstdout\fR or \fBstderr\fR),
+the assigned channel name will be the name of the standard channel.
+.AP ClientData instanceData in
+Arbitrary one-word value to be associated with this channel.  This
+value is passed to procedures in \fItypePtr\fR when they are invoked.
+.AP int mask in
+OR-ed combination of \fBTCL_READABLE\fR and \fBTCL_WRITABLE\fR to indicate
+whether a channel is readable and writable.
+.AP Tcl_Channel channel in
+The channel to operate on.
+.AP int direction in
+\fBTCL_READABLE\fR means the input handle is wanted; \fBTCL_WRITABLE\fR
+means the output handle is wanted.
+.AP ClientData *handlePtr out
+Points to the location where the desired OS-specific handle should be
+stored.
+.AP int size in
+The size, in bytes, of buffers to allocate in this channel.
+.AP int mask in
+An OR-ed combination of \fBTCL_READABLE\fR, \fBTCL_WRITABLE\fR
+and \fBTCL_EXCEPTION\fR that indicates events that have occurred on
+this channel.
+.AP Tcl_Interp *interp in
+Current interpreter. (can be NULL)
+.AP "const char" *optionName in
+Name of the invalid option.
+.AP "const char" *optionList in
+Specific options list (space separated words, without
+.QW \- )
+to append to the standard generic options list.
+Can be NULL for generic options error message only.
+.BE
+.SH DESCRIPTION
+.PP
+Tcl uses a two-layered channel architecture. It provides a generic upper
+layer to enable C and Tcl programs to perform input and output using the
+same APIs for a variety of files, devices, sockets etc. The generic C APIs
+are described in the manual entry for \fBTcl_OpenFileChannel\fR.
+.PP
+The lower layer provides type-specific channel drivers for each type
+of device supported on each platform.  This manual entry describes the
+C APIs used to communicate between the generic layer and the
+type-specific channel drivers.  It also explains how new types of
+channels can be added by providing new channel drivers.
+.PP
+Channel drivers consist of a number of components: First, each channel
+driver provides a \fBTcl_ChannelType\fR structure containing pointers to
+functions implementing the various operations used by the generic layer to
+communicate with the channel driver. The \fBTcl_ChannelType\fR structure
+and the functions referenced by it are described in the section
+\fBTCL_CHANNELTYPE\fR, below.
+.PP
+Second, channel drivers usually provide a Tcl command to create
+instances of that type of channel. For example, the Tcl \fBopen\fR
+command creates channels that use the file and command channel
+drivers, and the Tcl \fBsocket\fR command creates channels that use
+TCP sockets for network communication.
+.PP
+Third, a channel driver optionally provides a C function to open
+channel instances of that type. For example, \fBTcl_OpenFileChannel\fR
+opens a channel that uses the file channel driver, and
+\fBTcl_OpenTcpClient\fR opens a channel that uses the TCP network
+protocol.  These creation functions typically use
+\fBTcl_CreateChannel\fR internally to open the channel.
+.PP
+To add a new type of channel you must implement a C API or a Tcl command
+that opens a channel by invoking \fBTcl_CreateChannel\fR.
+When your driver calls \fBTcl_CreateChannel\fR it passes in
+a \fBTcl_ChannelType\fR structure describing the driver's I/O
+procedures.
+The generic layer will then invoke the functions referenced in that
+structure to perform operations on the channel.
+.PP
+\fBTcl_CreateChannel\fR opens a new channel and associates the supplied
+\fItypePtr\fR and \fIinstanceData\fR with it. The channel is opened in the
+mode indicated by \fImask\fR.
+For a discussion of channel drivers, their operations and the
+\fBTcl_ChannelType\fR structure, see the section \fBTCL_CHANNELTYPE\fR, below.
+.PP
+\fBTcl_CreateChannel\fR interacts with the code managing the standard
+channels. Once a standard channel was initialized either through a
+call to \fBTcl_GetStdChannel\fR or a call to \fBTcl_SetStdChannel\fR
+closing this standard channel will cause the next call to
+\fBTcl_CreateChannel\fR to make the new channel the new standard
+channel too. See \fBTcl_StandardChannels\fR for a general treatise
+about standard channels and the behavior of the Tcl library with
+regard to them.
+.PP
+\fBTcl_GetChannelInstanceData\fR returns the instance data associated with
+the channel in \fIchannel\fR. This is the same as the \fIinstanceData\fR
+argument in the call to \fBTcl_CreateChannel\fR that created this channel.
+.PP
+\fBTcl_GetChannelType\fR returns a pointer to the \fBTcl_ChannelType\fR
+structure used by the channel in the \fIchannel\fR argument. This is
+the same as the \fItypePtr\fR argument in the call to
+\fBTcl_CreateChannel\fR that created this channel.
+.PP
+\fBTcl_GetChannelName\fR returns a string containing the name associated
+with the channel, or NULL if the \fIchannelName\fR argument to
+\fBTcl_CreateChannel\fR was NULL.
+.PP
+\fBTcl_GetChannelHandle\fR places the OS-specific device handle
+associated with \fIchannel\fR for the given \fIdirection\fR in the
+location specified by \fIhandlePtr\fR and returns \fBTCL_OK\fR.  If
+the channel does not have a device handle for the specified direction,
+then \fBTCL_ERROR\fR is returned instead.  Different channel drivers
+will return different types of handle.  Refer to the manual entries
+for each driver to determine what type of handle is returned.
+.PP
+\fBTcl_GetChannelThread\fR returns the id of the thread currently managing
+the specified \fIchannel\fR. This allows channel drivers to send their file
+events to the correct event queue even for a multi-threaded core.
+.PP
+\fBTcl_GetChannelMode\fR returns an OR-ed combination of \fBTCL_READABLE\fR
+and \fBTCL_WRITABLE\fR, indicating whether the channel is open for input
+and output.
+.PP
+\fBTcl_GetChannelBufferSize\fR returns the size, in bytes, of buffers
+allocated to store input or output in \fIchannel\fR. If the value was not set
+by a previous call to \fBTcl_SetChannelBufferSize\fR, described below, then
+the default value of 4096 is returned.
+.PP
+\fBTcl_SetChannelBufferSize\fR sets the size, in bytes, of buffers that
+will be allocated in subsequent operations on the channel to store input or
+output. The \fIsize\fR argument should be between one and one million,
+allowing buffers of one byte to one million bytes. If \fIsize\fR is
+outside this range, \fBTcl_SetChannelBufferSize\fR sets the buffer size to
+4096.
+.PP
+\fBTcl_NotifyChannel\fR is called by a channel driver to indicate to
+the generic layer that the events specified by \fImask\fR have
+occurred on the channel.  Channel drivers are responsible for invoking
+this function whenever the channel handlers need to be called for the
+channel.  See \fBWATCHPROC\fR below for more details.
+.PP
+\fBTcl_BadChannelOption\fR is called from driver specific
+\fIsetOptionProc\fR or \fIgetOptionProc\fR to generate a complete
+error message.
+.PP
+\fBTcl_ChannelBuffered\fR returns the number of bytes of input
+currently buffered in the internal buffer (push back area) of the
+channel itself. It does not report about the data in the overall
+buffers for the stack of channels the supplied channel is part of.
+.PP
+\fBTcl_IsChannelShared\fR checks the refcount of the specified
+\fIchannel\fR and returns whether the \fIchannel\fR was shared among
+multiple interpreters (result == 1) or not (result == 0).
+.PP
+\fBTcl_IsChannelRegistered\fR checks whether the specified \fIchannel\fR is
+registered in the given \fIinterp\fRreter (result == 1) or not
+(result == 0).
+.PP
+\fBTcl_IsChannelExisting\fR checks whether a channel with the specified
+name is registered in the (thread)-global list of all channels (result
+== 1) or not (result == 0).
+.PP
+\fBTcl_CutChannel\fR removes the specified \fIchannel\fR from the
+(thread)global list of all channels (of the current thread).
+Application to a channel still registered in some interpreter
+is not allowed.
+Also notifies the driver if the \fBTcl_ChannelType\fR version is
+\fBTCL_CHANNEL_VERSION_4\fR (or higher), and
+\fBTcl_DriverThreadActionProc\fR is defined for it.
+.PP
+\fBTcl_SpliceChannel\fR adds the specified \fIchannel\fR to the
+(thread)global list of all channels (of the current thread).
+Application to a channel registered in some interpreter is not allowed.
+Also notifies the driver if the \fBTcl_ChannelType\fR version is
+\fBTCL_CHANNEL_VERSION_4\fR (or higher), and
+\fBTcl_DriverThreadActionProc\fR is defined for it.
+.PP
+\fBTcl_ClearChannelHandlers\fR removes all channel handlers and event
+scripts associated with the specified \fIchannel\fR, thus shutting
+down all event processing for this channel.
+.SH TCL_CHANNELTYPE
+.PP
+A channel driver provides a \fBTcl_ChannelType\fR structure that contains
+pointers to functions that implement the various operations on a channel;
+these operations are invoked as needed by the generic layer.  The structure
+was versioned starting in Tcl 8.3.2/8.4 to correct a problem with stacked
+channel drivers.  See the \fBOLD CHANNEL TYPES\fR section below for
+details about the old structure.
+.PP
+The \fBTcl_ChannelType\fR structure contains the following fields:
+.PP
+.CS
+typedef struct Tcl_ChannelType {
+        const char *\fItypeName\fR;
+        Tcl_ChannelTypeVersion \fIversion\fR;
+        Tcl_DriverCloseProc *\fIcloseProc\fR;
+        Tcl_DriverInputProc *\fIinputProc\fR;
+        Tcl_DriverOutputProc *\fIoutputProc\fR;
+        Tcl_DriverSeekProc *\fIseekProc\fR;
+        Tcl_DriverSetOptionProc *\fIsetOptionProc\fR;
+        Tcl_DriverGetOptionProc *\fIgetOptionProc\fR;
+        Tcl_DriverWatchProc *\fIwatchProc\fR;
+        Tcl_DriverGetHandleProc *\fIgetHandleProc\fR;
+        Tcl_DriverClose2Proc *\fIclose2Proc\fR;
+        Tcl_DriverBlockModeProc *\fIblockModeProc\fR;
+        Tcl_DriverFlushProc *\fIflushProc\fR;
+        Tcl_DriverHandlerProc *\fIhandlerProc\fR;
+        Tcl_DriverWideSeekProc *\fIwideSeekProc\fR;
+        Tcl_DriverThreadActionProc *\fIthreadActionProc\fR;
+        Tcl_DriverTruncateProc *\fItruncateProc\fR;
+} \fBTcl_ChannelType\fR;
+.CE
+.PP
+It is not necessary to provide implementations for all channel
+operations.  Those which are not necessary may be set to NULL in the
+struct: \fIblockModeProc\fR, \fIseekProc\fR, \fIsetOptionProc\fR,
+\fIgetOptionProc\fR, \fIgetHandleProc\fR, and \fIclose2Proc\fR, in addition to
+\fIflushProc\fR, \fIhandlerProc\fR, \fIthreadActionProc\fR, and
+\fItruncateProc\fR.  Other functions that cannot be implemented in a
+meaningful way should return \fBEINVAL\fR when called, to indicate
+that the operations they represent are not available. Also note that
+\fIwideSeekProc\fR can be NULL if \fIseekProc\fR is.
+.PP
+The user should only use the above structure for \fBTcl_ChannelType\fR
+instantiation.  When referencing fields in a \fBTcl_ChannelType\fR
+structure, the following functions should be used to obtain the values:
+\fBTcl_ChannelName\fR, \fBTcl_ChannelVersion\fR,
+\fBTcl_ChannelBlockModeProc\fR, \fBTcl_ChannelCloseProc\fR,
+\fBTcl_ChannelClose2Proc\fR, \fBTcl_ChannelInputProc\fR,
+\fBTcl_ChannelOutputProc\fR, \fBTcl_ChannelSeekProc\fR,
+\fBTcl_ChannelWideSeekProc\fR, \fBTcl_ChannelThreadActionProc\fR,
+\fBTcl_ChannelTruncateProc\fR,
+\fBTcl_ChannelSetOptionProc\fR, \fBTcl_ChannelGetOptionProc\fR,
+\fBTcl_ChannelWatchProc\fR, \fBTcl_ChannelGetHandleProc\fR,
+\fBTcl_ChannelFlushProc\fR, or \fBTcl_ChannelHandlerProc\fR.
+.PP
+The change to the structures was made in such a way that standard channel
+types are binary compatible.  However, channel types that use stacked
+channels (i.e. TLS, Trf) have new versions to correspond to the above change
+since the previous code for stacked channels had problems.
+.SS TYPENAME
+.PP
+The \fItypeName\fR field contains a null-terminated string that
+identifies the type of the device implemented by this driver, e.g.
+\fBfile\fR or \fBsocket\fR.
+.PP
+This value can be retrieved with \fBTcl_ChannelName\fR, which returns
+a pointer to the string.
+.SS VERSION
+.PP
+
+The \fIversion\fR field should be set to the version of the structure
+that you require. \fBTCL_CHANNEL_VERSION_2\fR is the minimum recommended.
+\fBTCL_CHANNEL_VERSION_3\fR must be set to specify the \fIwideSeekProc\fR member.
+\fBTCL_CHANNEL_VERSION_4\fR must be set to specify the \fIthreadActionProc\fR member
+(includes \fIwideSeekProc\fR).
+\fBTCL_CHANNEL_VERSION_5\fR must be set to specify the
+\fItruncateProc\fR members (includes
+\fIwideSeekProc\fR and \fIthreadActionProc\fR).
+If it is not set to any of these, then this
+\fBTcl_ChannelType\fR is assumed to have the original structure.  See
+\fBOLD CHANNEL TYPES\fR for more details.  While Tcl will recognize
+and function with either structures, stacked channels must be of at
+least \fBTCL_CHANNEL_VERSION_2\fR to function correctly.
+.PP
+This value can be retrieved with \fBTcl_ChannelVersion\fR, which returns
+one of
+\fBTCL_CHANNEL_VERSION_5\fR,
+\fBTCL_CHANNEL_VERSION_4\fR,
+\fBTCL_CHANNEL_VERSION_3\fR,
+\fBTCL_CHANNEL_VERSION_2\fR or \fBTCL_CHANNEL_VERSION_1\fR.
+.SS BLOCKMODEPROC
+.PP
+The \fIblockModeProc\fR field contains the address of a function called by
+the generic layer to set blocking and nonblocking mode on the device.
+\fIBlockModeProc\fR should match the following prototype:
+.PP
+.CS
+typedef int \fBTcl_DriverBlockModeProc\fR(
+        ClientData \fIinstanceData\fR,
+        int \fImode\fR);
+.CE
+.PP
+The \fIinstanceData\fR is the same as the value passed to
+\fBTcl_CreateChannel\fR when this channel was created.  The \fImode\fR
+argument is either \fBTCL_MODE_BLOCKING\fR or \fBTCL_MODE_NONBLOCKING\fR to
+set the device into blocking or nonblocking mode. The function should
+return zero if the operation was successful, or a nonzero POSIX error code
+if the operation failed.
+.PP
+If the operation is successful, the function can modify the supplied
+\fIinstanceData\fR to record that the channel entered blocking or
+nonblocking mode and to implement the blocking or nonblocking behavior.
+For some device types, the blocking and nonblocking behavior can be
+implemented by the underlying operating system; for other device types, the
+behavior must be emulated in the channel driver.
+.PP
+This value can be retrieved with \fBTcl_ChannelBlockModeProc\fR, which returns
+a pointer to the function.
+.PP
+A channel driver \fBnot\fR supplying a \fIblockModeProc\fR has to be
+very, very careful. It has to tell the generic layer exactly which
+blocking mode is acceptable to it, and should this also document for
+the user so that the blocking mode of the channel is not changed to an
+unacceptable value. Any confusion here may lead the interpreter into a
+(spurious and difficult to find) deadlock.
+.SS "CLOSEPROC AND CLOSE2PROC"
+.PP
+The \fIcloseProc\fR field contains the address of a function called by the
+generic layer to clean up driver-related information when the channel is
+closed. \fICloseProc\fR must match the following prototype:
+.PP
+.CS
+typedef int \fBTcl_DriverCloseProc\fR(
+        ClientData \fIinstanceData\fR,
+        Tcl_Interp *\fIinterp\fR);
+.CE
+.PP
+The \fIinstanceData\fR argument is the same as the value provided to
+\fBTcl_CreateChannel\fR when the channel was created. The function should
+release any storage maintained by the channel driver for this channel, and
+close the input and output devices encapsulated by this channel. All queued
+output will have been flushed to the device before this function is called,
+and no further driver operations will be invoked on this instance after
+calling the \fIcloseProc\fR. If the close operation is successful, the
+procedure should return zero; otherwise it should return a nonzero POSIX
+error code. In addition, if an error occurs and \fIinterp\fR is not NULL,
+the procedure should store an error message in the interpreter's result.
+.PP
+Alternatively, channels that support closing the read and write sides
+independently may set \fIcloseProc\fR to \fBTCL_CLOSE2PROC\fR and set
+\fIclose2Proc\fR to the address of a function that matches the
+following prototype:
+.PP
+.CS
+typedef int \fBTcl_DriverClose2Proc\fR(
+        ClientData \fIinstanceData\fR,
+        Tcl_Interp *\fIinterp\fR,
+        int \fIflags\fR);
+.CE
+.PP
+The \fIclose2Proc\fR will be called with \fIflags\fR set to an OR'ed
+combination of \fBTCL_CLOSE_READ\fR or \fBTCL_CLOSE_WRITE\fR to
+indicate that the driver should close the read and/or write side of
+the channel.  The channel driver may be invoked to perform
+additional operations on the channel after \fIclose2Proc\fR is
+called to close one or both sides of the channel.  If \fIflags\fR is
+\fB0\fR (zero), the driver should close the channel in the manner
+described above for \fIcloseProc\fR.  No further operations will be
+invoked on this instance after \fIclose2Proc\fR is called with all
+flags cleared.  In all cases, the \fIclose2Proc\fR function should
+return zero if the close operation was successful; otherwise it should
+return a nonzero POSIX error code. In addition, if an error occurs and
+\fIinterp\fR is not NULL, the procedure should store an error message
+in the interpreter's result.
+.PP
+The \fIcloseProc\fR and \fIclose2Proc\fR values can be retrieved with
+\fBTcl_ChannelCloseProc\fR or \fBTcl_ChannelClose2Proc\fR, which
+return a pointer to the respective function.
+.SS INPUTPROC
+.PP
+The \fIinputProc\fR field contains the address of a function called by the
+generic layer to read data from the file or device and store it in an
+internal buffer. \fIInputProc\fR must match the following prototype:
+.PP
+.CS
+typedef int \fBTcl_DriverInputProc\fR(
+        ClientData \fIinstanceData\fR,
+        char *\fIbuf\fR,
+        int \fIbufSize\fR,
+        int *\fIerrorCodePtr\fR);
+.CE
+.PP
+\fIInstanceData\fR is the same as the value passed to
+\fBTcl_CreateChannel\fR when the channel was created.  The \fIbuf\fR
+argument points to an array of bytes in which to store input from the
+device, and the \fIbufSize\fR argument indicates how many bytes are
+available at \fIbuf\fR.
+.PP
+The \fIerrorCodePtr\fR argument points to an integer variable provided by
+the generic layer. If an error occurs, the function should set the variable
+to a POSIX error code that identifies the error that occurred.
+.PP
+The function should read data from the input device encapsulated by the
+channel and store it at \fIbuf\fR.  On success, the function should return
+a nonnegative integer indicating how many bytes were read from the input
+device and stored at \fIbuf\fR. On error, the function should return -1. If
+an error occurs after some data has been read from the device, that data is
+lost.
+.PP
+If \fIinputProc\fR can determine that the input device has some data
+available but less than requested by the \fIbufSize\fR argument, the
+function should only attempt to read as much data as is available and
+return without blocking. If the input device has no data available
+whatsoever and the channel is in nonblocking mode, the function should
+return an \fBEAGAIN\fR error. If the input device has no data available
+whatsoever and the channel is in blocking mode, the function should block
+for the shortest possible time until at least one byte of data can be read
+from the device; then, it should return as much data as it can read without
+blocking.
+.PP
+This value can be retrieved with \fBTcl_ChannelInputProc\fR, which returns
+a pointer to the function.
+.SS OUTPUTPROC
+.PP
+The \fIoutputProc\fR field contains the address of a function called by the
+generic layer to transfer data from an internal buffer to the output device.
+\fIOutputProc\fR must match the following prototype:
+.PP
+.CS
+typedef int \fBTcl_DriverOutputProc\fR(
+        ClientData \fIinstanceData\fR,
+        const char *\fIbuf\fR,
+        int \fItoWrite\fR,
+        int *\fIerrorCodePtr\fR);
+.CE
+.PP
+\fIInstanceData\fR is the same as the value passed to
+\fBTcl_CreateChannel\fR when the channel was created. The \fIbuf\fR
+argument contains an array of bytes to be written to the device, and the
+\fItoWrite\fR argument indicates how many bytes are to be written from the
+\fIbuf\fR argument.
+.PP
+The \fIerrorCodePtr\fR argument points to an integer variable provided by
+the generic layer. If an error occurs, the function should set this
+variable to a POSIX error code that identifies the error.
+.PP
+The function should write the data at \fIbuf\fR to the output device
+encapsulated by the channel. On success, the function should return a
+nonnegative integer indicating how many bytes were written to the output
+device.  The return value is normally the same as \fItoWrite\fR, but may be
+less in some cases such as if the output operation is interrupted by a
+signal. If an error occurs the function should return -1.  In case of
+error, some data may have been written to the device.
+.PP
+If the channel is nonblocking and the output device is unable to absorb any
+data whatsoever, the function should return -1 with an \fBEAGAIN\fR error
+without writing any data.
+.PP
+This value can be retrieved with \fBTcl_ChannelOutputProc\fR, which returns
+a pointer to the function.
+.SS "SEEKPROC AND WIDESEEKPROC"
+.PP
+The \fIseekProc\fR field contains the address of a function called by the
+generic layer to move the access point at which subsequent input or output
+operations will be applied. \fISeekProc\fR must match the following
+prototype:
+.PP
+.CS
+typedef int \fBTcl_DriverSeekProc\fR(
+        ClientData \fIinstanceData\fR,
+        long \fIoffset\fR,
+        int \fIseekMode\fR,
+        int *\fIerrorCodePtr\fR);
+.CE
+.PP
+The \fIinstanceData\fR argument is the same as the value given to
+\fBTcl_CreateChannel\fR when this channel was created.  \fIOffset\fR and
+\fIseekMode\fR have the same meaning as for the \fBTcl_Seek\fR
+procedure (described in the manual entry for \fBTcl_OpenFileChannel\fR).
+.PP
+The \fIerrorCodePtr\fR argument points to an integer variable provided by
+the generic layer for returning \fBerrno\fR values from the function.  The
+function should set this variable to a POSIX error code if an error occurs.
+The function should store an \fBEINVAL\fR error code if the channel type
+does not implement seeking.
+.PP
+The return value is the new access point or -1 in case of error. If an
+error occurred, the function should not move the access point.
+.PP
+If there is a non-NULL \fIseekProc\fR field, the \fIwideSeekProc\fR
+field may contain the address of an alternative function to use which
+handles wide (i.e. larger than 32-bit) offsets, so allowing seeks
+within files larger than 2GB.  The \fIwideSeekProc\fR will be called
+in preference to the \fIseekProc\fR, but both must be defined if the
+\fIwideSeekProc\fR is defined.  \fIWideSeekProc\fR must match the
+following prototype:
+.PP
+.CS
+typedef Tcl_WideInt \fBTcl_DriverWideSeekProc\fR(
+        ClientData \fIinstanceData\fR,
+        Tcl_WideInt \fIoffset\fR,
+        int \fIseekMode\fR,
+        int *\fIerrorCodePtr\fR);
+.CE
+.PP
+The arguments and return values mean the same thing as with
+\fIseekProc\fR above, except that the type of offsets and the return
+type are different.
+.PP
+The \fIseekProc\fR value can be retrieved with
+\fBTcl_ChannelSeekProc\fR, which returns a pointer to the function,
+and similarly the \fIwideSeekProc\fR can be retrieved with
+\fBTcl_ChannelWideSeekProc\fR.
+.SS SETOPTIONPROC
+.PP
+The \fIsetOptionProc\fR field contains the address of a function called by
+the generic layer to set a channel type specific option on a channel.
+\fIsetOptionProc\fR must match the following prototype:
+.PP
+.CS
+typedef int \fBTcl_DriverSetOptionProc\fR(
+        ClientData \fIinstanceData\fR,
+        Tcl_Interp *\fIinterp\fR,
+        const char *\fIoptionName\fR,
+        const char *\fInewValue\fR);
+.CE
+.PP
+\fIoptionName\fR is the name of an option to set, and \fInewValue\fR is
+the new value for that option, as a string. The \fIinstanceData\fR is the
+same as the value given to \fBTcl_CreateChannel\fR when this channel was
+created. The function should do whatever channel type specific action is
+required to implement the new value of the option.
+.PP
+Some options are handled by the generic code and this function is never
+called to set them, e.g. \fB\-blockmode\fR. Other options are specific to
+each channel type and the \fIsetOptionProc\fR procedure of the channel
+driver will get called to implement them. The \fIsetOptionProc\fR field can
+be NULL, which indicates that this channel type supports no type specific
+options.
+.PP
+If the option value is successfully modified to the new value, the function
+returns \fBTCL_OK\fR.
+It should call \fBTcl_BadChannelOption\fR which itself returns
+\fBTCL_ERROR\fR if the \fIoptionName\fR is
+unrecognized.
+If \fInewValue\fR specifies a value for the option that
+is not supported or if a system call error occurs,
+the function should leave an error message in the
+\fIresult\fR field of \fIinterp\fR if \fIinterp\fR is not NULL. The
+function should also call \fBTcl_SetErrno\fR to store an appropriate POSIX
+error code.
+.PP
+This value can be retrieved with \fBTcl_ChannelSetOptionProc\fR, which returns
+a pointer to the function.
+.SS GETOPTIONPROC
+.PP
+The \fIgetOptionProc\fR field contains the address of a function called by
+the generic layer to get the value of a channel type specific option on a
+channel. \fIgetOptionProc\fR must match the following prototype:
+.PP
+.CS
+typedef int \fBTcl_DriverGetOptionProc\fR(
+        ClientData \fIinstanceData\fR,
+        Tcl_Interp *\fIinterp\fR,
+        const char *\fIoptionName\fR,
+        Tcl_DString *\fIoptionValue\fR);
+.CE
+.PP
+\fIOptionName\fR is the name of an option supported by this type of
+channel. If the option name is not NULL, the function stores its current
+value, as a string, in the Tcl dynamic string \fIoptionValue\fR.
+If \fIoptionName\fR is NULL, the function stores in \fIoptionValue\fR an
+alternating list of all supported options and their current values.
+On success, the function returns \fBTCL_OK\fR.
+It should call \fBTcl_BadChannelOption\fR which itself returns
+\fBTCL_ERROR\fR if the \fIoptionName\fR is
+unrecognized. If a system call error occurs,
+the function should leave an error message in the
+result of \fIinterp\fR if \fIinterp\fR is not NULL. The
+function should also call \fBTcl_SetErrno\fR to store an appropriate POSIX
+error code.
+.PP
+Some options are handled by the generic code and this function is never
+called to retrieve their value, e.g. \fB\-blockmode\fR. Other options are
+specific to each channel type and the \fIgetOptionProc\fR procedure of the
+channel driver will get called to implement them. The \fIgetOptionProc\fR
+field can be NULL, which indicates that this channel type supports no type
+specific options.
+.PP
+This value can be retrieved with \fBTcl_ChannelGetOptionProc\fR, which returns
+a pointer to the function.
+.SS WATCHPROC
+.PP
+The \fIwatchProc\fR field contains the address of a function called
+by the generic layer to initialize the event notification mechanism to
+notice events of interest on this channel.
+\fIWatchProc\fR should match the following prototype:
+.PP
+.CS
+typedef void \fBTcl_DriverWatchProc\fR(
+        ClientData \fIinstanceData\fR,
+        int \fImask\fR);
+.CE
+.PP
+The \fIinstanceData\fR is the same as the value passed to
+\fBTcl_CreateChannel\fR when this channel was created. The \fImask\fR
+argument is an OR-ed combination of \fBTCL_READABLE\fR, \fBTCL_WRITABLE\fR
+and \fBTCL_EXCEPTION\fR; it indicates events the caller is interested in
+noticing on this channel.
+.PP
+The function should initialize device type specific mechanisms to
+notice when an event of interest is present on the channel.  When one
+or more of the designated events occurs on the channel, the channel
+driver is responsible for calling \fBTcl_NotifyChannel\fR to inform
+the generic channel module.  The driver should take care not to starve
+other channel drivers or sources of callbacks by invoking
+Tcl_NotifyChannel too frequently.  Fairness can be insured by using
+the Tcl event queue to allow the channel event to be scheduled in sequence
+with other events.  See the description of \fBTcl_QueueEvent\fR for
+details on how to queue an event.
+.PP
+This value can be retrieved with \fBTcl_ChannelWatchProc\fR, which returns
+a pointer to the function.
+.SS GETHANDLEPROC
+.PP
+The \fIgetHandleProc\fR field contains the address of a function called by
+the generic layer to retrieve a device-specific handle from the channel.
+\fIGetHandleProc\fR should match the following prototype:
+.PP
+.CS
+typedef int \fBTcl_DriverGetHandleProc\fR(
+        ClientData \fIinstanceData\fR,
+        int \fIdirection\fR,
+        ClientData *\fIhandlePtr\fR);
+.CE
+.PP
+\fIInstanceData\fR is the same as the value passed to
+\fBTcl_CreateChannel\fR when this channel was created. The \fIdirection\fR
+argument is either \fBTCL_READABLE\fR to retrieve the handle used
+for input, or \fBTCL_WRITABLE\fR to retrieve the handle used for
+output.
+.PP
+If the channel implementation has device-specific handles, the
+function should retrieve the appropriate handle associated with the
+channel, according the \fIdirection\fR argument.  The handle should be
+stored in the location referred to by \fIhandlePtr\fR, and
+\fBTCL_OK\fR should be returned.  If the channel is not open for the
+specified direction, or if the channel implementation does not use
+device handles, the function should return \fBTCL_ERROR\fR.
+.PP
+This value can be retrieved with \fBTcl_ChannelGetHandleProc\fR, which returns
+a pointer to the function.
+.SS FLUSHPROC
+.PP
+The \fIflushProc\fR field is currently reserved for future use.
+It should be set to NULL.
+\fIFlushProc\fR should match the following prototype:
+.PP
+.CS
+typedef int \fBTcl_DriverFlushProc\fR(
+        ClientData \fIinstanceData\fR);
+.CE
+.PP
+This value can be retrieved with \fBTcl_ChannelFlushProc\fR, which returns
+a pointer to the function.
+.SS HANDLERPROC
+.PP
+The \fIhandlerProc\fR field contains the address of a function called by
+the generic layer to notify the channel that an event occurred.  It should
+be defined for stacked channel drivers that wish to be notified of events
+that occur on the underlying (stacked) channel.
+\fIHandlerProc\fR should match the following prototype:
+.PP
+.CS
+typedef int \fBTcl_DriverHandlerProc\fR(
+        ClientData \fIinstanceData\fR,
+        int \fIinterestMask\fR);
+.CE
+.PP
+\fIInstanceData\fR is the same as the value passed to \fBTcl_CreateChannel\fR
+when this channel was created.  The \fIinterestMask\fR is an OR-ed
+combination of \fBTCL_READABLE\fR or \fBTCL_WRITABLE\fR; it indicates what
+type of event occurred on this channel.
+.PP
+This value can be retrieved with \fBTcl_ChannelHandlerProc\fR, which returns
+a pointer to the function.
+
+.SS "THREADACTIONPROC"
+.PP
+The \fIthreadActionProc\fR field contains the address of the function
+called by the generic layer when a channel is created, closed, or
+going to move to a different thread, i.e. whenever thread-specific
+driver state might have to initialized or updated. It can be NULL.
+The action \fITCL_CHANNEL_THREAD_REMOVE\fR is used to notify the
+driver that it should update or remove any thread-specific data it
+might be maintaining for the channel.
+.PP
+The action \fITCL_CHANNEL_THREAD_INSERT\fR is used to notify the
+driver that it should update or initialize any thread-specific data it
+might be maintaining using the calling thread as the associate. See
+\fBTcl_CutChannel\fR and \fBTcl_SpliceChannel\fR for more detail.
+.PP
+.CS
+typedef void \fBTcl_DriverThreadActionProc\fR(
+        ClientData \fIinstanceData\fR,
+        int \fIaction\fR);
+.CE
+.PP
+\fIInstanceData\fR is the same as the value passed to
+\fBTcl_CreateChannel\fR when this channel was created.
+.PP
+These values can be retrieved with \fBTcl_ChannelThreadActionProc\fR,
+which returns a pointer to the function.
+.SS "TRUNCATEPROC"
+.PP
+The \fItruncateProc\fR field contains the address of the function
+called by the generic layer when a channel is truncated to some
+length. It can be NULL.
+.PP
+.CS
+typedef int \fBTcl_DriverTruncateProc\fR(
+        ClientData \fIinstanceData\fR,
+        Tcl_WideInt \fIlength\fR);
+.CE
+.PP
+\fIInstanceData\fR is the same as the value passed to
+\fBTcl_CreateChannel\fR when this channel was created, and
+\fIlength\fR is the new length of the underlying file, which should
+not be negative. The result should be 0 on success or an errno code
+(suitable for use with \fBTcl_SetErrno\fR) on failure.
+.PP
+These values can be retrieved with \fBTcl_ChannelTruncateProc\fR,
+which returns a pointer to the function.
+.SH TCL_BADCHANNELOPTION
+.PP
+This procedure generates a
+.QW "bad option"
+error message in an
+(optional) interpreter.  It is used by channel drivers when
+an invalid Set/Get option is requested. Its purpose is to concatenate
+the generic options list to the specific ones and factorize
+the generic options error message string.
+.PP
+It always returns \fBTCL_ERROR\fR
+.PP
+An error message is generated in \fIinterp\fR's result value to
+indicate that a command was invoked with a bad option.
+The message has the form
+.CS
+    bad option "blah": should be one of
+    <...generic options...>+<...specific options...>
+.CE
+so you get for instance:
+.CS
+    bad option "-blah": should be one of -blocking,
+    -buffering, -buffersize, -eofchar, -translation,
+    -peername, or -sockname
+.CE
+when called with \fIoptionList\fR equal to
+.QW "peername sockname"
+.PP
+.QW blah
+is the \fIoptionName\fR argument and
+.QW "<specific options>"
+is a space separated list of specific option words.
+The function takes good care of inserting minus signs before
+each option, commas after, and an
+.QW or
+before the last option.
+.SH "OLD CHANNEL TYPES"
+The original (8.3.1 and below) \fBTcl_ChannelType\fR structure contains
+the following fields:
+.PP
+.CS
+typedef struct Tcl_ChannelType {
+    const char *\fItypeName\fR;
+    Tcl_DriverBlockModeProc *\fIblockModeProc\fR;
+    Tcl_DriverCloseProc *\fIcloseProc\fR;
+    Tcl_DriverInputProc *\fIinputProc\fR;
+    Tcl_DriverOutputProc *\fIoutputProc\fR;
+    Tcl_DriverSeekProc *\fIseekProc\fR;
+    Tcl_DriverSetOptionProc *\fIsetOptionProc\fR;
+    Tcl_DriverGetOptionProc *\fIgetOptionProc\fR;
+    Tcl_DriverWatchProc *\fIwatchProc\fR;
+    Tcl_DriverGetHandleProc *\fIgetHandleProc\fR;
+    Tcl_DriverClose2Proc *\fIclose2Proc\fR;
+} \fBTcl_ChannelType\fR;
+.CE
+.PP
+It is still possible to create channel with the above structure.  The
+internal channel code will determine the version.  It is imperative to use
+the new \fBTcl_ChannelType\fR structure if you are creating a stacked
+channel driver, due to problems with the earlier stacked channel
+implementation (in 8.2.0 to 8.3.1).
+.PP
+Prior to 8.4.0 (i.e. during the later releases of 8.3 and early part
+of the 8.4 development cycle) the \fBTcl_ChannelType\fR structure
+contained the following fields:
+.PP
+.CS
+typedef struct Tcl_ChannelType {
+    const char *\fItypeName\fR;
+    Tcl_ChannelTypeVersion \fIversion\fR;
+    Tcl_DriverCloseProc *\fIcloseProc\fR;
+    Tcl_DriverInputProc *\fIinputProc\fR;
+    Tcl_DriverOutputProc *\fIoutputProc\fR;
+    Tcl_DriverSeekProc *\fIseekProc\fR;
+    Tcl_DriverSetOptionProc *\fIsetOptionProc\fR;
+    Tcl_DriverGetOptionProc *\fIgetOptionProc\fR;
+    Tcl_DriverWatchProc *\fIwatchProc\fR;
+    Tcl_DriverGetHandleProc *\fIgetHandleProc\fR;
+    Tcl_DriverClose2Proc *\fIclose2Proc\fR;
+    Tcl_DriverBlockModeProc *\fIblockModeProc\fR;
+    Tcl_DriverFlushProc *\fIflushProc\fR;
+    Tcl_DriverHandlerProc *\fIhandlerProc\fR;
+    Tcl_DriverTruncateProc *\fItruncateProc\fR;
+} \fBTcl_ChannelType\fR;
+.CE
+.PP
+When the above structure is registered as a channel type, the
+\fIversion\fR field should always be \fBTCL_CHANNEL_VERSION_2\fR.
+.SH "SEE ALSO"
+Tcl_Close(3), Tcl_OpenFileChannel(3), Tcl_SetErrno(3), Tcl_QueueEvent(3), Tcl_StackChannel(3), Tcl_GetStdChannel(3)
+.SH KEYWORDS
+blocking, channel driver, channel registration, channel type, nonblocking
diff --git a/doc/CrtChnlHdlr.3 b/doc/CrtChnlHdlr.3
new file mode 100644
index 0000000..0ecd3c9
--- /dev/null
+++ b/doc/CrtChnlHdlr.3
@@ -0,0 +1,89 @@
+'\"
+'\" Copyright (c) 1996 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH Tcl_CreateChannelHandler 3 7.5 Tcl "Tcl Library Procedures"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+Tcl_CreateChannelHandler, Tcl_DeleteChannelHandler \- call a procedure when a channel becomes readable or writable
+.SH SYNOPSIS
+.nf
+.nf
+\fB#include <tcl.h>\fR
+.sp
+void
+\fBTcl_CreateChannelHandler\fR(\fIchannel, mask, proc, clientData\fR)
+.sp
+void
+\fBTcl_DeleteChannelHandler\fR(\fIchannel, proc, clientData\fR)
+.sp
+.SH ARGUMENTS
+.AS Tcl_ChannelProc clientData
+.AP Tcl_Channel channel in
+Tcl channel such as returned by \fBTcl_CreateChannel\fR.
+.AP int mask in
+Conditions under which \fIproc\fR should be called: OR-ed combination of
+\fBTCL_READABLE\fR, \fBTCL_WRITABLE\fR and \fBTCL_EXCEPTION\fR. Specify
+a zero value to temporarily disable an existing handler.
+.AP Tcl_FileProc *proc in
+Procedure to invoke whenever the channel indicated by \fIchannel\fR meets
+the conditions specified by \fImask\fR.
+.AP ClientData clientData in
+Arbitrary one-word value to pass to \fIproc\fR.
+.BE
+.SH DESCRIPTION
+.PP
+\fBTcl_CreateChannelHandler\fR arranges for \fIproc\fR to be called in the
+future whenever input or output becomes possible on the channel identified
+by \fIchannel\fR, or whenever an exceptional condition exists for
+\fIchannel\fR. The conditions of interest under which \fIproc\fR will be
+invoked are specified by the \fImask\fR argument.
+See the manual entry for \fBfileevent\fR for a precise description of
+what it means for a channel to be readable or writable.
+\fIProc\fR must conform to the following prototype:
+.PP
+.CS
+typedef void \fBTcl_ChannelProc\fR(
+        ClientData \fIclientData\fR,
+        int \fImask\fR);
+.CE
+.PP
+The \fIclientData\fR argument is the same as the value passed to
+\fBTcl_CreateChannelHandler\fR when the handler was created. Typically,
+\fIclientData\fR points to a data structure containing application-specific
+information about the channel. \fIMask\fR is an integer mask indicating
+which of the requested conditions actually exists for the channel; it will
+contain a subset of the bits from the \fImask\fR argument to
+\fBTcl_CreateChannelHandler\fR when the handler was created.
+.PP
+Each channel handler is identified by a unique combination of \fIchannel\fR,
+\fIproc\fR and \fIclientData\fR.
+There may be many handlers for a given channel as long as they do not
+have the same \fIchannel\fR, \fIproc\fR, and \fIclientData\fR.
+If \fBTcl_CreateChannelHandler\fR is invoked when there is already a handler
+for \fIchannel\fR, \fIproc\fR, and \fIclientData\fR, then no new
+handler is created;  instead, the \fImask\fR is changed for the
+existing handler.
+.PP
+\fBTcl_DeleteChannelHandler\fR deletes a channel handler identified by
+\fIchannel\fR, \fIproc\fR and \fIclientData\fR; if no such handler exists,
+the call has no effect.
+.PP
+Channel handlers are invoked via the Tcl event mechanism, so they
+are only useful in applications that are event-driven.
+Note also that the conditions specified in the \fImask\fR argument
+to \fIproc\fR may no longer exist when \fIproc\fR is invoked:  for
+example, if there are two handlers for \fBTCL_READABLE\fR on the same
+channel, the first handler could consume all of the available input
+so that the channel is no longer readable when the second handler
+is invoked.
+For this reason it may be useful to use nonblocking I/O on channels
+for which there are event handlers.
+.SH "SEE ALSO"
+Notifier(3), Tcl_CreateChannel(3), Tcl_OpenFileChannel(3), vwait(n).
+.SH KEYWORDS
+blocking, callback, channel, events, handler, nonblocking.
diff --git a/doc/CrtCloseHdlr.3 b/doc/CrtCloseHdlr.3
new file mode 100644
index 0000000..bac2431
--- /dev/null
+++ b/doc/CrtCloseHdlr.3
@@ -0,0 +1,55 @@
+'\"
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH Tcl_CreateCloseHandler 3 7.5 Tcl "Tcl Library Procedures"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+Tcl_CreateCloseHandler, Tcl_DeleteCloseHandler \- arrange for callbacks when channels are closed
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+void
+\fBTcl_CreateCloseHandler\fR(\fIchannel, proc, clientData\fR)
+.sp
+void
+\fBTcl_DeleteCloseHandler\fR(\fIchannel, proc, clientData\fR)
+.sp
+.SH ARGUMENTS
+.AS Tcl_CloseProc clientData
+.AP Tcl_Channel channel in
+The channel for which to create or delete a close callback.
+.AP Tcl_CloseProc *proc in
+The procedure to call as the callback.
+.AP ClientData clientData in
+Arbitrary one-word value to pass to \fIproc\fR.
+.BE
+.SH DESCRIPTION
+.PP
+\fBTcl_CreateCloseHandler\fR arranges for \fIproc\fR to be called when
+\fIchannel\fR is closed with \fBTcl_Close\fR or
+\fBTcl_UnregisterChannel\fR, or using the Tcl \fBclose\fR command.
+\fIProc\fR should match the following prototype:
+.PP
+.CS
+typedef void \fBTcl_CloseProc\fR(
+        ClientData \fIclientData\fR);
+.CE
+.PP
+The \fIclientData\fR is the same as the value provided in the call to
+\fBTcl_CreateCloseHandler\fR.
+.PP
+\fBTcl_DeleteCloseHandler\fR removes a close callback for \fIchannel\fR.
+The \fIproc\fR and \fIclientData\fR identify which close callback to
+remove; \fBTcl_DeleteCloseHandler\fR does nothing if its \fIproc\fR and
+\fIclientData\fR arguments do not match the \fIproc\fR and \fIclientData\fR
+for a  close handler for \fIchannel\fR.
+.SH "SEE ALSO"
+close(n), Tcl_Close(3), Tcl_UnregisterChannel(3)
+.SH KEYWORDS
+callback, channel closing
diff --git a/doc/CrtCommand.3 b/doc/CrtCommand.3
new file mode 100644
index 0000000..bf76d48
--- /dev/null
+++ b/doc/CrtCommand.3
@@ -0,0 +1,143 @@
+'\"
+'\" Copyright (c) 1989-1993 The Regents of the University of California.
+'\" Copyright (c) 1994-1997 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH Tcl_CreateCommand 3 "" Tcl "Tcl Library Procedures"
+.so man.macros
+.BS
+.SH NAME
+Tcl_CreateCommand \- implement new commands in C
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+Tcl_Command
+\fBTcl_CreateCommand\fR(\fIinterp, cmdName, proc, clientData, deleteProc\fR)
+.SH ARGUMENTS
+.AS Tcl_CmdDeleteProc *deleteProc
+.AP Tcl_Interp *interp in
+Interpreter in which to create new command.
+.AP "const char" *cmdName in
+Name of command.
+.AP Tcl_CmdProc *proc in
+Implementation of new command:  \fIproc\fR will be called whenever
+\fIcmdName\fR is invoked as a command.
+.AP ClientData clientData in
+Arbitrary one-word value to pass to \fIproc\fR and \fIdeleteProc\fR.
+.AP Tcl_CmdDeleteProc *deleteProc in
+Procedure to call before \fIcmdName\fR is deleted from the interpreter;
+allows for command-specific cleanup.  If NULL, then no procedure is
+called before the command is deleted.
+.BE
+.SH DESCRIPTION
+.PP
+\fBTcl_CreateCommand\fR defines a new command in \fIinterp\fR and associates
+it with procedure \fIproc\fR such that whenever \fIcmdName\fR is
+invoked as a Tcl command (via a call to \fBTcl_Eval\fR) the Tcl interpreter
+will call \fIproc\fR to process the command.
+It differs from \fBTcl_CreateObjCommand\fR in that a new string-based
+command is defined;
+that is, a command procedure is defined that takes an array of
+argument strings instead of values.
+The value-based command procedures registered by \fBTcl_CreateObjCommand\fR
+can execute significantly faster than the string-based command procedures
+defined by \fBTcl_CreateCommand\fR.
+This is because they take Tcl values as arguments
+and those values can retain an internal representation that
+can be manipulated more efficiently.
+Also, Tcl's interpreter now uses values internally.
+In order to invoke a string-based command procedure
+registered by \fBTcl_CreateCommand\fR,
+it must generate and fetch a string representation
+from each argument value before the call.
+New commands should be defined using \fBTcl_CreateObjCommand\fR.
+We support \fBTcl_CreateCommand\fR for backwards compatibility.
+.PP
+The procedures \fBTcl_DeleteCommand\fR, \fBTcl_GetCommandInfo\fR,
+and \fBTcl_SetCommandInfo\fR are used in conjunction with
+\fBTcl_CreateCommand\fR.
+.PP
+\fBTcl_CreateCommand\fR will delete an existing command \fIcmdName\fR,
+if one is already associated with the interpreter.
+It returns a token that may be used to refer
+to the command in subsequent calls to \fBTcl_GetCommandName\fR.
+If \fIcmdName\fR contains any \fB::\fR namespace qualifiers,
+then the command is added to the specified namespace;
+otherwise the command is added to the global namespace.
+If \fBTcl_CreateCommand\fR is called for an interpreter that is in
+the process of being deleted, then it does not create a new command
+and it returns NULL.
+\fIProc\fR should have arguments and result that match the type
+\fBTcl_CmdProc\fR:
+.PP
+.CS
+typedef int \fBTcl_CmdProc\fR(
+        ClientData \fIclientData\fR,
+        Tcl_Interp *\fIinterp\fR,
+        int \fIargc\fR,
+        const char *\fIargv\fR[]);
+.CE
+.PP
+When \fIproc\fR is invoked the \fIclientData\fR and \fIinterp\fR
+parameters will be copies of the \fIclientData\fR and \fIinterp\fR
+arguments given to \fBTcl_CreateCommand\fR.
+Typically, \fIclientData\fR points to an application-specific
+data structure that describes what to do when the command procedure
+is invoked.  \fIArgc\fR and \fIargv\fR describe the arguments to
+the command, \fIargc\fR giving the number of arguments (including
+the command name) and \fIargv\fR giving the values of the arguments
+as strings.  The \fIargv\fR array will contain \fIargc\fR+1 values;
+the first \fIargc\fR values point to the argument strings, and the
+last value is NULL.
+Note that the argument strings should not be modified as they may
+point to constant strings or may be shared with other parts of the
+interpreter.
+.PP
+Note that the argument strings are encoded in normalized UTF-8 since
+version 8.1 of Tcl.
+.PP
+\fIProc\fR must return an integer code that is expected to be one of
+\fBTCL_OK\fR, \fBTCL_ERROR\fR, \fBTCL_RETURN\fR, \fBTCL_BREAK\fR, or
+\fBTCL_CONTINUE\fR.  See the Tcl overview man page
+for details on what these codes mean.  Most normal commands will only
+return \fBTCL_OK\fR or \fBTCL_ERROR\fR.  In addition, \fIproc\fR must set
+the interpreter result;
+in the case of a \fBTCL_OK\fR return code this gives the result
+of the command, and in the case of \fBTCL_ERROR\fR it gives an error message.
+The \fBTcl_SetResult\fR procedure provides an easy interface for setting
+the return value;  for complete details on how the interpreter result
+field is managed, see the \fBTcl_Interp\fR man page.
+Before invoking a command procedure,
+\fBTcl_Eval\fR sets the interpreter result to point to an empty string,
+so simple commands can return an empty result by doing nothing at all.
+.PP
+The contents of the \fIargv\fR array belong to Tcl and are not
+guaranteed to persist once \fIproc\fR returns:  \fIproc\fR should
+not modify them, nor should it set the interpreter result to point
+anywhere within the \fIargv\fR values.
+Call \fBTcl_SetResult\fR with status \fBTCL_VOLATILE\fR if you want
+to return something from the \fIargv\fR array.
+.PP
+\fIDeleteProc\fR will be invoked when (if) \fIcmdName\fR is deleted. This can
+occur through a call to \fBTcl_DeleteCommand\fR or \fBTcl_DeleteInterp\fR,
+or by replacing \fIcmdName\fR in another call to \fBTcl_CreateCommand\fR.
+\fIDeleteProc\fR is invoked before the command is deleted, and gives the
+application an opportunity to release any structures associated
+with the command.  \fIDeleteProc\fR should have arguments and
+result that match the type \fBTcl_CmdDeleteProc\fR:
+.PP
+.CS
+typedef void \fBTcl_CmdDeleteProc\fR(
+        ClientData \fIclientData\fR);
+.CE
+.PP
+The \fIclientData\fR argument will be the same as the \fIclientData\fR
+argument passed to \fBTcl_CreateCommand\fR.
+.SH "SEE ALSO"
+Tcl_CreateObjCommand, Tcl_DeleteCommand, Tcl_GetCommandInfo,
+Tcl_SetCommandInfo, Tcl_GetCommandName, Tcl_SetObjResult
+.SH KEYWORDS
+bind, command, create, delete, interpreter, namespace
diff --git a/doc/CrtFileHdlr.3 b/doc/CrtFileHdlr.3
new file mode 100644
index 0000000..c1bc1fa
--- /dev/null
+++ b/doc/CrtFileHdlr.3
@@ -0,0 +1,91 @@
+'\"
+'\" Copyright (c) 1990-1994 The Regents of the University of California.
+'\" Copyright (c) 1994-1997 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\" 
+.TH Tcl_CreateFileHandler 3 8.0 Tcl "Tcl Library Procedures"
+.so man.macros
+.BS
+.SH NAME
+Tcl_CreateFileHandler, Tcl_DeleteFileHandler \- associate procedure callbacks with files or devices (Unix only)
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+\fBTcl_CreateFileHandler\fR(\fIfd, mask, proc, clientData\fR)
+.sp
+\fBTcl_DeleteFileHandler\fR(\fIfd\fR)
+.SH ARGUMENTS
+.AS Tcl_FileProc clientData
+.AP int fd in
+Unix file descriptor for an open file or device.
+.AP int mask in
+Conditions under which \fIproc\fR should be called:
+OR-ed combination of \fBTCL_READABLE\fR, \fBTCL_WRITABLE\fR,
+and \fBTCL_EXCEPTION\fR.  May be set to 0 to temporarily disable
+a handler.
+.AP Tcl_FileProc *proc in
+Procedure to invoke whenever the file or device indicated
+by \fIfile\fR meets the conditions specified by \fImask\fR.
+.AP ClientData clientData in
+Arbitrary one-word value to pass to \fIproc\fR.
+.BE
+.SH DESCRIPTION
+.PP
+\fBTcl_CreateFileHandler\fR arranges for \fIproc\fR to be
+invoked in the future whenever I/O becomes possible on a file
+or an exceptional condition exists for the file.  The file
+is indicated by \fIfd\fR, and the conditions of interest
+are indicated by \fImask\fR.  For example, if \fImask\fR
+is \fBTCL_READABLE\fR, \fIproc\fR will be called when
+the file is readable.
+The callback to \fIproc\fR is made by \fBTcl_DoOneEvent\fR, so
+\fBTcl_CreateFileHandler\fR is only useful in programs that dispatch
+events through \fBTcl_DoOneEvent\fR or through Tcl commands such
+as \fBvwait\fR.
+.PP
+\fIProc\fR should have arguments and result that match the
+type \fBTcl_FileProc\fR:
+.PP
+.CS
+typedef void \fBTcl_FileProc\fR(
+        ClientData \fIclientData\fR,
+        int \fImask\fR);
+.CE
+.PP
+The \fIclientData\fR parameter to \fIproc\fR is a copy
+of the \fIclientData\fR
+argument given to \fBTcl_CreateFileHandler\fR when the callback
+was created.  Typically, \fIclientData\fR points to a data
+structure containing application-specific information about
+the file.  \fIMask\fR is an integer mask indicating which
+of the requested conditions actually exists for the file;  it
+will contain a subset of the bits in the \fImask\fR argument
+to \fBTcl_CreateFileHandler\fR.
+.PP
+There may exist only one handler for a given file at a given time.
+If \fBTcl_CreateFileHandler\fR is called when a handler already
+exists for \fIfd\fR, then the new callback replaces the information
+that was previously recorded.
+.PP
+\fBTcl_DeleteFileHandler\fR may be called to delete the
+file handler for \fIfd\fR;  if no handler exists for the
+file given by \fIfd\fR then the procedure has no effect.
+.PP
+The purpose of file handlers is to enable an application to respond to
+events while waiting for files to become ready for I/O.  For this to work
+correctly, the application may need to use non-blocking I/O operations on
+the files for which handlers are declared.  Otherwise the application may
+block if it reads or writes too much data; while waiting for the I/O to
+complete the application will not be able to service other events. Use
+\fBTcl_SetChannelOption\fR with \fB\-blocking\fR to set the channel into
+blocking or nonblocking mode as required.
+.PP
+Note that these interfaces are only supported by the Unix
+implementation of the Tcl notifier.
+.SH "SEE ALSO"
+fileevent(n), Tcl_CreateTimerHandler(3), Tcl_DoWhenIdle(3)
+.SH KEYWORDS
+callback, file, handler
diff --git a/doc/CrtInterp.3 b/doc/CrtInterp.3
new file mode 100644
index 0000000..679795e
--- /dev/null
+++ b/doc/CrtInterp.3
@@ -0,0 +1,150 @@
+'\"
+'\" Copyright (c) 1989-1993 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\" 
+.TH Tcl_CreateInterp 3 7.5 Tcl "Tcl Library Procedures"
+.so man.macros
+.BS
+.SH NAME
+Tcl_CreateInterp, Tcl_DeleteInterp, Tcl_InterpActive, Tcl_InterpDeleted \- create and delete Tcl command interpreters
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+Tcl_Interp *
+\fBTcl_CreateInterp\fR()
+.sp
+\fBTcl_DeleteInterp\fR(\fIinterp\fR)
+.sp
+int
+\fBTcl_InterpDeleted\fR(\fIinterp\fR)
+.sp
+.VS 8.6
+int
+\fBTcl_InterpActive\fR(\fIinterp\fR)
+.VE 8.6
+.SH ARGUMENTS
+.AS Tcl_Interp *interp
+.AP Tcl_Interp *interp in
+Token for interpreter to be destroyed or queried.
+.BE
+.SH DESCRIPTION
+.PP
+\fBTcl_CreateInterp\fR creates a new interpreter structure and returns
+a token for it. The token is required in calls to most other Tcl
+procedures, such as \fBTcl_CreateCommand\fR, \fBTcl_Eval\fR, and
+\fBTcl_DeleteInterp\fR.  The token returned by \fBTcl_CreateInterp\fR
+may only be passed to Tcl routines called from the same thread as
+the original \fBTcl_CreateInterp\fR call.  It is not safe for multiple
+threads to pass the same token to Tcl's routines.
+The new interpreter is initialized with the built-in Tcl commands
+and with standard variables like \fBtcl_platform\fR and \fBenv\fR. To
+bind in additional commands, call \fBTcl_CreateCommand\fR, and to
+create additional variables, call \fBTcl_SetVar\fR.
+.PP
+\fBTcl_DeleteInterp\fR marks an interpreter as deleted; the interpreter
+will eventually be deleted when all calls to \fBTcl_Preserve\fR for it have
+been matched by calls to \fBTcl_Release\fR. At that time, all of the
+resources associated with it, including variables, procedures, and
+application-specific command bindings, will be deleted. After
+\fBTcl_DeleteInterp\fR returns any attempt to use \fBTcl_Eval\fR on the
+interpreter will fail and return \fBTCL_ERROR\fR. After the call to
+\fBTcl_DeleteInterp\fR it is safe to examine the interpreter's result,
+query or set the values of variables, define, undefine or retrieve
+procedures, and examine the runtime evaluation stack. See below, in the
+section \fBINTERPRETERS AND MEMORY MANAGEMENT\fR for details.
+.PP
+\fBTcl_InterpDeleted\fR returns nonzero if \fBTcl_DeleteInterp\fR was
+called with \fIinterp\fR as its argument; this indicates that the
+interpreter will eventually be deleted, when the last call to
+\fBTcl_Preserve\fR for it is matched by a call to \fBTcl_Release\fR. If
+nonzero is returned, further calls to \fBTcl_Eval\fR in this interpreter
+will return \fBTCL_ERROR\fR.
+.PP
+\fBTcl_InterpDeleted\fR is useful in deletion callbacks to distinguish
+between when only the memory the callback is responsible for is being
+deleted and when the whole interpreter is being deleted. In the former case
+the callback may recreate the data being deleted, but this would lead to an
+infinite loop if the interpreter were being deleted.
+.PP
+.VS 8.6
+\fBTcl_InterpActive\fR is useful for determining whether there is any
+execution of scripts ongoing in an interpreter, which is a useful piece of
+information when Tcl is embedded in a garbage-collected environment and it
+becomes necessary to determine whether the interpreter is a candidate for
+deletion. The function returns a true value if the interpreter has at least
+one active execution running inside it, and a false value otherwise.
+.VE 8.6
+.SH "INTERPRETERS AND MEMORY MANAGEMENT"
+.PP
+\fBTcl_DeleteInterp\fR can be called at any time on an interpreter that may
+be used by nested evaluations and C code in various extensions. Tcl
+implements a simple mechanism that allows callers to use interpreters
+without worrying about the interpreter being deleted in a nested call, and
+without requiring special code to protect the interpreter, in most cases.
+This mechanism ensures that nested uses of an interpreter can safely
+continue using it even after \fBTcl_DeleteInterp\fR is called.
+.PP
+The mechanism relies on matching up calls to \fBTcl_Preserve\fR with calls
+to \fBTcl_Release\fR. If \fBTcl_DeleteInterp\fR has been called, only when
+the last call to \fBTcl_Preserve\fR is matched by a call to
+\fBTcl_Release\fR, will the interpreter be freed. See the manual entry for
+\fBTcl_Preserve\fR for a description of these functions.
+.PP
+The rules for when the user of an interpreter must call \fBTcl_Preserve\fR
+and \fBTcl_Release\fR are simple:
+.TP
+\fBInterpreters Passed As Arguments\fR
+.
+Functions that are passed an interpreter as an argument can safely use the
+interpreter without any special protection. Thus, when you write an
+extension consisting of new Tcl commands, no special code is needed to
+protect interpreters received as arguments. This covers the majority of all
+uses.
+.TP
+\fBInterpreter Creation And Deletion\fR
+.
+When a new interpreter is created and used in a call to \fBTcl_Eval\fR,
+\fBTcl_VarEval\fR, \fBTcl_GlobalEval\fR, \fBTcl_SetVar\fR, or
+\fBTcl_GetVar\fR, a pair of calls to \fBTcl_Preserve\fR and
+\fBTcl_Release\fR should be wrapped around all uses of the interpreter.
+Remember that it is unsafe to use the interpreter once \fBTcl_Release\fR
+has been called. To ensure that the interpreter is properly deleted when
+it is no longer needed, call \fBTcl_InterpDeleted\fR to test if some other
+code already called \fBTcl_DeleteInterp\fR; if not, call
+\fBTcl_DeleteInterp\fR before calling \fBTcl_Release\fR in your own code.
+.TP
+\fBRetrieving An Interpreter From A Data Structure\fR
+.
+When an interpreter is retrieved from a data structure (e.g. the client
+data of a callback) for use in one of the evaluation functions
+(\fBTcl_Eval\fR, \fBTcl_VarEval\fR, \fBTcl_GlobalEval\fR, \fBTcl_EvalObjv\fR,
+etc.) or variable access functions (\fBTcl_SetVar\fR, \fBTcl_GetVar\fR,
+\fBTcl_SetVar2Ex\fR, etc.), a pair of
+calls to \fBTcl_Preserve\fR and \fBTcl_Release\fR should be wrapped around
+all uses of the interpreter; it is unsafe to reuse the interpreter once
+\fBTcl_Release\fR has been called. If an interpreter is stored inside a
+callback data structure, an appropriate deletion cleanup mechanism should
+be set up by the code that creates the data structure so that the
+interpreter is removed from the data structure (e.g. by setting the field
+to NULL) when the interpreter is deleted. Otherwise, you may be using an
+interpreter that has been freed and whose memory may already have been
+reused.
+.PP
+All uses of interpreters in Tcl and Tk have already been protected.
+Extension writers should ensure that their code also properly protects any
+additional interpreters used, as described above.
+.PP
+.VS 8.6
+Note that the protection mechanisms do not work well with conventional garbage
+collection systems. When in such a managed environment, \fBTcl_InterpActive\fR
+should be used to determine when an interpreter is a candidate for deletion
+due to inactivity.
+.VE 8.6
+.SH "SEE ALSO"
+Tcl_Preserve(3), Tcl_Release(3)
+.SH KEYWORDS
+command, create, delete, interpreter
diff --git a/doc/CrtMathFnc.3 b/doc/CrtMathFnc.3
new file mode 100644
index 0000000..acceb5b
--- /dev/null
+++ b/doc/CrtMathFnc.3
@@ -0,0 +1,162 @@
+'\"
+'\" Copyright (c) 1989-1993 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH Tcl_CreateMathFunc 3 8.4 Tcl "Tcl Library Procedures"
+.so man.macros
+.BS
+.SH NAME
+Tcl_CreateMathFunc, Tcl_GetMathFuncInfo, Tcl_ListMathFuncs \- Define, query and enumerate math functions for expressions
+.SH "NOTICE OF EVENTUAL DEPRECATION"
+.PP
+The \fBTcl_CreateMathFunc\fR and \fBTcl_GetMathFuncInfo\fR functions
+are rendered somewhat obsolete by the ability to create functions for
+expressions by placing commands in the \fBtcl::mathfunc\fR namespace,
+as described in the \fBmathfunc\fR manual page; the API described on
+this page is not expected to be maintained indefinitely.
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+void
+\fBTcl_CreateMathFunc\fR(\fIinterp, name, numArgs, argTypes, proc, clientData\fR)
+.sp
+int
+\fBTcl_GetMathFuncInfo\fR(\fIinterp, name, numArgsPtr, argTypesPtr, procPtr,
+                    clientDataPtr\fR)
+.sp
+Tcl_Obj *
+\fBTcl_ListMathFuncs\fR(\fIinterp, pattern\fR)
+.SH ARGUMENTS
+.AS Tcl_ValueType *clientDataPtr out
+.AP Tcl_Interp *interp in
+Interpreter in which new function will be defined.
+.AP "const char" *name in
+Name for new function.
+.AP int numArgs in
+Number of arguments to new function;  also gives size of \fIargTypes\fR array.
+.AP Tcl_ValueType *argTypes in
+Points to an array giving the permissible types for each argument to
+function.
+.AP Tcl_MathProc *proc in
+Procedure that implements the function.
+.AP ClientData clientData in
+Arbitrary one-word value to pass to \fIproc\fR when it is invoked.
+.AP int *numArgsPtr out
+Points to a variable that will be set to contain the number of
+arguments to the function.
+.AP Tcl_ValueType **argTypesPtr out
+Points to a variable that will be set to contain a pointer to an array
+giving the permissible types for each argument to the function which
+will need to be freed up using \fITcl_Free\fR.
+.AP Tcl_MathProc **procPtr out
+Points to a variable that will be set to contain a pointer to the
+implementation code for the function (or NULL if the function is
+implemented directly in bytecode).
+.AP ClientData *clientDataPtr out
+Points to a variable that will be set to contain the clientData
+argument passed to \fITcl_CreateMathFunc\fR when the function was
+created if the function is not implemented directly in bytecode.
+.AP "const char" *pattern in
+Pattern to match against function names so as to filter them (by
+passing to \fITcl_StringMatch\fR), or NULL to not apply any filter.
+.BE
+.SH DESCRIPTION
+.PP
+Tcl allows a number of mathematical functions to be used in
+expressions, such as \fBsin\fR, \fBcos\fR, and \fBhypot\fR.
+These functions are represented by commands in the namespace,
+\fBtcl::mathfunc\fR.  The \fBTcl_CreateMathFunc\fR function is
+an obsolete way for applications to add additional functions
+to those already provided by Tcl or to replace existing functions.
+It should not be used by new applications, which should create
+math functions using \fBTcl_CreateObjCommand\fR to create a command
+in the \fBtcl::mathfunc\fR namespace.
+.PP
+In the \fBTcl_CreateMathFunc\fR interface,
+\fIName\fR is the name of the function as it will appear in expressions.
+If \fIname\fR does not already exist in the \fB::tcl::mathfunc\fR
+namespace, then a new command is created in that namespace.
+If \fIname\fR does exist, then the existing function is replaced.
+\fINumArgs\fR and \fIargTypes\fR describe the arguments to the function.
+Each entry in the \fIargTypes\fR array must be
+one of \fBTCL_INT\fR, \fBTCL_DOUBLE\fR, \fBTCL_WIDE_INT\fR,
+or \fBTCL_EITHER\fR to indicate whether the corresponding argument must be an
+integer, a double-precision floating value, a wide (64-bit) integer,
+or any, respectively.
+.PP
+Whenever the function is invoked in an expression Tcl will invoke
+\fIproc\fR.  \fIProc\fR should have arguments and result that match
+the type \fBTcl_MathProc\fR:
+.PP
+.CS
+typedef int \fBTcl_MathProc\fR(
+        ClientData \fIclientData\fR,
+        Tcl_Interp *\fIinterp\fR,
+        Tcl_Value *\fIargs\fR,
+        Tcl_Value *\fIresultPtr\fR);
+.CE
+.PP
+When \fIproc\fR is invoked the \fIclientData\fR and \fIinterp\fR
+arguments will be the same as those passed to \fBTcl_CreateMathFunc\fR.
+\fIArgs\fR will point to an array of \fInumArgs\fR Tcl_Value structures,
+which describe the actual arguments to the function:
+.PP
+.CS
+typedef struct Tcl_Value {
+    Tcl_ValueType \fItype\fR;
+    long \fIintValue\fR;
+    double \fIdoubleValue\fR;
+    Tcl_WideInt \fIwideValue\fR;
+} \fBTcl_Value\fR;
+.CE
+.PP
+The \fItype\fR field indicates the type of the argument and is
+one of \fBTCL_INT\fR, \fBTCL_DOUBLE\fR or \fBTCL_WIDE_INT\fR.
+It will match the \fIargTypes\fR value specified for the function unless
+the \fIargTypes\fR value was \fBTCL_EITHER\fR. Tcl converts
+the argument supplied in the expression to the type requested in
+\fIargTypes\fR, if that is necessary.
+Depending on the value of the \fItype\fR field, the \fIintValue\fR,
+\fIdoubleValue\fR or \fIwideValue\fR
+field will contain the actual value of the argument.
+.PP
+\fIProc\fR should compute its result and store it either as an integer
+in \fIresultPtr->intValue\fR or as a floating value in
+\fIresultPtr->doubleValue\fR.
+It should set also \fIresultPtr->type\fR to one of
+\fBTCL_INT\fR, \fBTCL_DOUBLE\fR or \fBTCL_WIDE_INT\fR
+to indicate which value was set.
+Under normal circumstances \fIproc\fR should return \fBTCL_OK\fR.
+If an error occurs while executing the function, \fIproc\fR should
+return \fBTCL_ERROR\fR and leave an error message in the interpreter's result.
+.PP
+\fBTcl_GetMathFuncInfo\fR retrieves the values associated with
+function \fIname\fR that were passed to a preceding
+\fBTcl_CreateMathFunc\fR call.  Normally, the return code is
+\fBTCL_OK\fR but if the named function does not exist, \fBTCL_ERROR\fR
+is returned and an error message is placed in the interpreter's
+result.
+.PP
+If an error did not occur, the array reference placed in the variable
+pointed to by \fIargTypesPtr\fR is newly allocated, and should be
+released by passing it to \fBTcl_Free\fR.  Some functions (the
+standard set implemented in the core, and those defined by placing
+commands in the \fBtcl::mathfunc\fR namespace) do not have
+argument type information; attempting to retrieve values for
+them causes a NULL to be stored in the variable pointed to by
+\fIprocPtr\fR and the variable pointed to by \fIclientDataPtr\fR
+will not be modified.  The variable pointed to by \fInumArgsPointer\fR
+will contain -1, and no argument types will be stored in the variable
+pointed to by \fIargTypesPointer\fR.
+.PP
+\fBTcl_ListMathFuncs\fR returns a Tcl value containing a list of all
+the math functions defined in the interpreter whose name matches
+\fIpattern\fR.  The returned value has a reference count of zero.
+.SH "SEE ALSO"
+expr(n), info(n), Tcl_CreateObjCommand(3), Tcl_Free(3), Tcl_NewListObj(3)
+.SH KEYWORDS
+expression, mathematical function
diff --git a/doc/CrtObjCmd.3 b/doc/CrtObjCmd.3
new file mode 100644
index 0000000..6714bd7
--- /dev/null
+++ b/doc/CrtObjCmd.3
@@ -0,0 +1,302 @@
+'\"
+'\" Copyright (c) 1996-1997 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH Tcl_CreateObjCommand 3 8.0 Tcl "Tcl Library Procedures"
+.so man.macros
+.BS
+.SH NAME
+Tcl_CreateObjCommand, Tcl_DeleteCommand, Tcl_DeleteCommandFromToken, Tcl_GetCommandInfo, Tcl_GetCommandInfoFromToken, Tcl_SetCommandInfo, Tcl_SetCommandInfoFromToken, Tcl_GetCommandName, Tcl_GetCommandFullName, Tcl_GetCommandFromObj \- implement new commands in C
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+Tcl_Command
+\fBTcl_CreateObjCommand\fR(\fIinterp, cmdName, proc, clientData, deleteProc\fR)
+.sp
+int
+\fBTcl_DeleteCommand\fR(\fIinterp, cmdName\fR)
+.sp
+int
+\fBTcl_DeleteCommandFromToken\fR(\fIinterp, token\fR)
+.sp
+int
+\fBTcl_GetCommandInfo\fR(\fIinterp, cmdName, infoPtr\fR)
+.sp
+int
+\fBTcl_SetCommandInfo\fR(\fIinterp, cmdName, infoPtr\fR)
+.sp
+int
+\fBTcl_GetCommandInfoFromToken\fR(\fItoken, infoPtr\fR)
+.sp
+int
+\fBTcl_SetCommandInfoFromToken\fR(\fItoken, infoPtr\fR)
+.sp
+const char *
+\fBTcl_GetCommandName\fR(\fIinterp, token\fR)
+.sp
+void
+\fBTcl_GetCommandFullName\fR(\fIinterp, token, objPtr\fR)
+.sp
+Tcl_Command
+\fBTcl_GetCommandFromObj\fR(\fIinterp, objPtr\fR)
+.SH ARGUMENTS
+.AS Tcl_CmdDeleteProc *deleteProc in/out
+.AP Tcl_Interp *interp in
+Interpreter in which to create a new command or that contains a command.
+.AP char *cmdName in
+Name of command.
+.AP Tcl_ObjCmdProc *proc in
+Implementation of the new command: \fIproc\fR will be called whenever
+\fIcmdName\fR is invoked as a command.
+.AP ClientData clientData in
+Arbitrary one-word value to pass to \fIproc\fR and \fIdeleteProc\fR.
+.AP Tcl_CmdDeleteProc *deleteProc in
+Procedure to call before \fIcmdName\fR is deleted from the interpreter;
+allows for command-specific cleanup. If NULL, then no procedure is
+called before the command is deleted.
+.AP Tcl_Command token in
+Token for command, returned by previous call to \fBTcl_CreateObjCommand\fR.
+The command must not have been deleted.
+.AP Tcl_CmdInfo *infoPtr in/out
+Pointer to structure containing various information about a
+Tcl command.
+.AP Tcl_Obj *objPtr in
+Value containing the name of a Tcl command.
+.BE
+.SH DESCRIPTION
+.PP
+\fBTcl_CreateObjCommand\fR defines a new command in \fIinterp\fR
+and associates it with procedure \fIproc\fR
+such that whenever \fIname\fR is
+invoked as a Tcl command (e.g., via a call to \fBTcl_EvalObjEx\fR)
+the Tcl interpreter will call \fIproc\fR to process the command.
+.PP
+\fBTcl_CreateObjCommand\fR deletes any existing command
+\fIname\fR already associated with the interpreter
+(however see below for an exception where the existing command
+is not deleted).
+It returns a token that may be used to refer
+to the command in subsequent calls to \fBTcl_GetCommandName\fR.
+If \fIname\fR contains any \fB::\fR namespace qualifiers,
+then the command is added to the specified namespace;
+otherwise the command is added to the global namespace.
+If \fBTcl_CreateObjCommand\fR is called for an interpreter that is in
+the process of being deleted, then it does not create a new command
+and it returns NULL.
+\fIproc\fR should have arguments and result that match the type
+\fBTcl_ObjCmdProc\fR:
+.PP
+.CS
+typedef int \fBTcl_ObjCmdProc\fR(
+        ClientData \fIclientData\fR,
+        Tcl_Interp *\fIinterp\fR,
+        int \fIobjc\fR,
+        Tcl_Obj *const \fIobjv\fR[]);
+.CE
+.PP
+When \fIproc\fR is invoked, the \fIclientData\fR and \fIinterp\fR parameters
+will be copies of the \fIclientData\fR and \fIinterp\fR arguments given to
+\fBTcl_CreateObjCommand\fR.  Typically, \fIclientData\fR points to an
+application-specific data structure that describes what to do when the
+command procedure is invoked. \fIObjc\fR and \fIobjv\fR describe the
+arguments to the command, \fIobjc\fR giving the number of argument values
+(including the command name) and \fIobjv\fR giving the values of the
+arguments.  The \fIobjv\fR array will contain \fIobjc\fR values, pointing to
+the argument values.  Unlike \fIargv\fR[\fIargv\fR] used in a
+string-based command procedure, \fIobjv\fR[\fIobjc\fR] will not contain NULL.
+.PP
+Additionally, when \fIproc\fR is invoked, it must not modify the contents
+of the \fIobjv\fR array by assigning new pointer values to any element of the
+array (for example, \fIobjv\fR[\fB2\fR] = \fBNULL\fR) because this will
+cause memory to be lost and the runtime stack to be corrupted.  The
+\fBconst\fR in the declaration of \fIobjv\fR will cause ANSI-compliant
+compilers to report any such attempted assignment as an error.  However,
+it is acceptable to modify the internal representation of any individual
+value argument.  For instance, the user may call
+\fBTcl_GetIntFromObj\fR on \fIobjv\fR[\fB2\fR] to obtain the integer
+representation of that value; that call may change the type of the value
+that \fIobjv\fR[\fB2\fR] points at, but will not change where
+\fIobjv\fR[\fB2\fR] points.
+.PP
+\fIproc\fR must return an integer code that is either \fBTCL_OK\fR,
+\fBTCL_ERROR\fR, \fBTCL_RETURN\fR, \fBTCL_BREAK\fR, or \fBTCL_CONTINUE\fR.
+See the Tcl overview man page
+for details on what these codes mean.  Most normal commands will only
+return \fBTCL_OK\fR or \fBTCL_ERROR\fR.
+In addition, if \fIproc\fR needs to return a non-empty result,
+it can call \fBTcl_SetObjResult\fR to set the interpreter's result.
+In the case of a \fBTCL_OK\fR return code this gives the result
+of the command,
+and in the case of \fBTCL_ERROR\fR this gives an error message.
+Before invoking a command procedure,
+\fBTcl_EvalObjEx\fR sets interpreter's result to
+point to a value representing an empty string, so simple
+commands can return an empty result by doing nothing at all.
+.PP
+The contents of the \fIobjv\fR array belong to Tcl and are not
+guaranteed to persist once \fIproc\fR returns: \fIproc\fR should
+not modify them.
+Call \fBTcl_SetObjResult\fR if you want
+to return something from the \fIobjv\fR array.
+.PP
+Ordinarily, \fBTcl_CreateObjCommand\fR deletes any existing command
+\fIname\fR already associated with the interpreter.
+However, if the existing command was created by a previous call to
+\fBTcl_CreateCommand\fR,
+\fBTcl_CreateObjCommand\fR does not delete the command
+but instead arranges for the Tcl interpreter to call the
+\fBTcl_ObjCmdProc\fR \fIproc\fR in the future.
+The old string-based \fBTcl_CmdProc\fR associated with the command
+is retained and its address can be obtained by subsequent
+\fBTcl_GetCommandInfo\fR calls. This is done for backwards compatibility.
+.PP
+\fIDeleteProc\fR will be invoked when (if) \fIname\fR is deleted.
+This can occur through a call to \fBTcl_DeleteCommand\fR,
+\fBTcl_DeleteCommandFromToken\fR, or \fBTcl_DeleteInterp\fR,
+or by replacing \fIname\fR in another call to \fBTcl_CreateObjCommand\fR.
+\fIDeleteProc\fR is invoked before the command is deleted, and gives the
+application an opportunity to release any structures associated
+with the command.  \fIDeleteProc\fR should have arguments and
+result that match the type \fBTcl_CmdDeleteProc\fR:
+.PP
+.CS
+typedef void \fBTcl_CmdDeleteProc\fR(
+        ClientData \fIclientData\fR);
+.CE
+.PP
+The \fIclientData\fR argument will be the same as the \fIclientData\fR
+argument passed to \fBTcl_CreateObjCommand\fR.
+.PP
+\fBTcl_DeleteCommand\fR deletes a command from a command interpreter.
+Once the call completes, attempts to invoke \fIcmdName\fR in
+\fIinterp\fR will result in errors.
+If \fIcmdName\fR is not bound as a command in \fIinterp\fR then
+\fBTcl_DeleteCommand\fR does nothing and returns -1;  otherwise
+it returns 0.
+There are no restrictions on \fIcmdName\fR:  it may refer to
+a built-in command, an application-specific command, or a Tcl procedure.
+If \fIname\fR contains any \fB::\fR namespace qualifiers,
+the command is deleted from the specified namespace.
+.PP
+Given a token returned by \fBTcl_CreateObjCommand\fR,
+\fBTcl_DeleteCommandFromToken\fR deletes the command
+from a command interpreter.
+It will delete a command even if that command has been renamed.
+Once the call completes, attempts to invoke the command in
+\fIinterp\fR will result in errors.
+If the command corresponding to \fItoken\fR
+has already been deleted from \fIinterp\fR then
+\fBTcl_DeleteCommand\fR does nothing and returns -1;
+otherwise it returns 0.
+.PP
+\fBTcl_GetCommandInfo\fR checks to see whether its \fIcmdName\fR argument
+exists as a command in \fIinterp\fR.
+\fIcmdName\fR may include \fB::\fR namespace qualifiers
+to identify a command in a particular namespace.
+If the command is not found, then it returns 0.
+Otherwise it places information about the command
+in the \fBTcl_CmdInfo\fR structure
+pointed to by \fIinfoPtr\fR and returns 1.
+A \fBTcl_CmdInfo\fR structure has the following fields:
+.PP
+.CS
+typedef struct Tcl_CmdInfo {
+    int \fIisNativeObjectProc\fR;
+    Tcl_ObjCmdProc *\fIobjProc\fR;
+    ClientData \fIobjClientData\fR;
+    Tcl_CmdProc *\fIproc\fR;
+    ClientData \fIclientData\fR;
+    Tcl_CmdDeleteProc *\fIdeleteProc\fR;
+    ClientData \fIdeleteData\fR;
+    Tcl_Namespace *\fInamespacePtr\fR;
+} \fBTcl_CmdInfo\fR;
+.CE
+.PP
+The \fIisNativeObjectProc\fR field has the value 1
+if \fBTcl_CreateObjCommand\fR was called to register the command;
+it is 0 if only \fBTcl_CreateCommand\fR was called.
+It allows a program to determine whether it is faster to
+call \fIobjProc\fR or \fIproc\fR:
+\fIobjProc\fR is normally faster
+if \fIisNativeObjectProc\fR has the value 1.
+The fields \fIobjProc\fR and \fIobjClientData\fR
+have the same meaning as the \fIproc\fR and \fIclientData\fR
+arguments to \fBTcl_CreateObjCommand\fR;
+they hold information about the value-based command procedure
+that the Tcl interpreter calls to implement the command.
+The fields \fIproc\fR and \fIclientData\fR
+hold information about the string-based command procedure
+that implements the command.
+If \fBTcl_CreateCommand\fR was called for this command,
+this is the procedure passed to it;
+otherwise, this is a compatibility procedure
+registered by \fBTcl_CreateObjCommand\fR
+that simply calls the command's
+value-based procedure after converting its string arguments to Tcl values.
+The field \fIdeleteData\fR is the ClientData value
+to pass to \fIdeleteProc\fR;  it is normally the same as
+\fIclientData\fR but may be set independently using the
+\fBTcl_SetCommandInfo\fR procedure.
+The field \fInamespacePtr\fR holds a pointer to the
+Tcl_Namespace that contains the command.
+.PP
+\fBTcl_GetCommandInfoFromToken\fR is identical to
+\fBTcl_GetCommandInfo\fR except that it uses a command token returned
+from \fBTcl_CreateObjCommand\fR in place of the command name.  If the
+\fItoken\fR parameter is NULL, it returns 0; otherwise, it returns 1
+and fills in the structure designated by \fIinfoPtr\fR.
+.PP
+\fBTcl_SetCommandInfo\fR is used to modify the procedures and
+ClientData values associated with a command.
+Its \fIcmdName\fR argument is the name of a command in \fIinterp\fR.
+\fIcmdName\fR may include \fB::\fR namespace qualifiers
+to identify a command in a particular namespace.
+If this command does not exist then \fBTcl_SetCommandInfo\fR returns 0.
+Otherwise, it copies the information from \fI*infoPtr\fR to
+Tcl's internal structure for the command and returns 1.
+.PP
+\fBTcl_SetCommandInfoFromToken\fR is identical to
+\fBTcl_SetCommandInfo\fR except that it takes a command token as
+returned by \fBTcl_CreateObjCommand\fR instead of the command name.
+If the \fItoken\fR parameter is NULL, it returns 0.  Otherwise, it
+copies the information from \fI*infoPtr\fR to Tcl's internal structure
+for the command and returns 1.
+.PP
+Note that \fBTcl_SetCommandInfo\fR and
+\fBTcl_SetCommandInfoFromToken\fR both allow the ClientData for a
+command's deletion procedure to be given a different value than the
+ClientData for its command procedure.
+.PP
+Note that neither \fBTcl_SetCommandInfo\fR nor
+\fBTcl_SetCommandInfoFromToken\fR will change a command's namespace.
+Use \fBTcl_Eval\fR to call the \fBrename\fR command to do that.
+.PP
+\fBTcl_GetCommandName\fR provides a mechanism for tracking commands
+that have been renamed.
+Given a token returned by \fBTcl_CreateObjCommand\fR
+when the command was created, \fBTcl_GetCommandName\fR returns the
+string name of the command.  If the command has been renamed since it
+was created, then \fBTcl_GetCommandName\fR returns the current name.
+This name does not include any \fB::\fR namespace qualifiers.
+The command corresponding to \fItoken\fR must not have been deleted.
+The string returned by \fBTcl_GetCommandName\fR is in dynamic memory
+owned by Tcl and is only guaranteed to retain its value as long as the
+command is not deleted or renamed;  callers should copy the string if
+they need to keep it for a long time.
+.PP
+\fBTcl_GetCommandFullName\fR produces the fully qualified name
+of a command from a command token.
+The name, including all namespace prefixes,
+is appended to the value specified by \fIobjPtr\fR.
+.PP
+\fBTcl_GetCommandFromObj\fR returns a token for the command
+specified by the name in a \fBTcl_Obj\fR.
+The command name is resolved relative to the current namespace.
+Returns NULL if the command is not found.
+.SH "SEE ALSO"
+Tcl_CreateCommand(3), Tcl_ResetResult(3), Tcl_SetObjResult(3)
+.SH KEYWORDS
+bind, command, create, delete, namespace, value
diff --git a/doc/CrtSlave.3 b/doc/CrtSlave.3
new file mode 100644
index 0000000..ac681bc
--- /dev/null
+++ b/doc/CrtSlave.3
@@ -0,0 +1,236 @@
+'\"
+'\" Copyright (c) 1995-1996 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH Tcl_CreateSlave 3 7.6 Tcl "Tcl Library Procedures"
+.so man.macros
+.BS
+.SH NAME
+Tcl_IsSafe, Tcl_MakeSafe, Tcl_CreateSlave, Tcl_GetSlave, Tcl_GetMaster, Tcl_GetInterpPath, Tcl_CreateAlias, Tcl_CreateAliasObj, Tcl_GetAlias, Tcl_GetAliasObj, Tcl_ExposeCommand, Tcl_HideCommand \- manage multiple Tcl interpreters, aliases and hidden commands
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+int
+\fBTcl_IsSafe\fR(\fIinterp\fR)
+.sp
+int
+\fBTcl_MakeSafe\fR(\fIinterp\fR)
+.sp
+Tcl_Interp *
+\fBTcl_CreateSlave\fR(\fIinterp, slaveName, isSafe\fR)
+.sp
+Tcl_Interp *
+\fBTcl_GetSlave\fR(\fIinterp, slaveName\fR)
+.sp
+Tcl_Interp *
+\fBTcl_GetMaster\fR(\fIinterp\fR)
+.sp
+int
+\fBTcl_GetInterpPath\fR(\fIaskingInterp, slaveInterp\fR)
+.sp
+int
+\fBTcl_CreateAlias\fR(\fIslaveInterp, slaveCmd, targetInterp, targetCmd,
+                argc, argv\fR)
+.sp
+int
+\fBTcl_CreateAliasObj\fR(\fIslaveInterp, slaveCmd, targetInterp, targetCmd,
+                   objc, objv\fR)
+.sp
+int
+\fBTcl_GetAlias\fR(\fIinterp, slaveCmd, targetInterpPtr, targetCmdPtr,
+             argcPtr, argvPtr\fR)
+.sp
+int
+\fBTcl_GetAliasObj\fR(\fIinterp, slaveCmd, targetInterpPtr, targetCmdPtr,
+                objcPtr, objvPtr\fR)
+.sp
+int
+\fBTcl_ExposeCommand\fR(\fIinterp, hiddenCmdName, cmdName\fR)
+.sp
+int
+\fBTcl_HideCommand\fR(\fIinterp, cmdName, hiddenCmdName\fR)
+.SH ARGUMENTS
+.AS "const char *const" **targetInterpPtr out
+.AP Tcl_Interp *interp in
+Interpreter in which to execute the specified command.
+.AP "const char" *slaveName in
+Name of slave interpreter to create or manipulate.
+.AP int isSafe in
+If non-zero, a
+.QW safe
+slave that is suitable for running untrusted code
+is created, otherwise a trusted slave is created.
+.AP Tcl_Interp *slaveInterp in
+Interpreter to use for creating the source command for an alias (see
+below).
+.AP "const char" *slaveCmd in
+Name of source command for alias.
+.AP Tcl_Interp *targetInterp in
+Interpreter that contains the target command for an alias.
+.AP "const char" *targetCmd in
+Name of target command for alias in \fItargetInterp\fR.
+.AP int argc in
+Count of additional arguments to pass to the alias command.
+.AP "const char *const" *argv in
+Vector of strings, the additional arguments to pass to the alias command.
+This storage is owned by the caller.
+.AP int objc in
+Count of additional value arguments to pass to the aliased command.
+.AP Tcl_Obj **objv in
+Vector of Tcl_Obj structures, the additional value arguments to pass to
+the aliased command.
+This storage is owned by the caller.
+.AP Tcl_Interp **targetInterpPtr in
+Pointer to location to store the address of the interpreter where a target
+command is defined for an alias.
+.AP "const char" **targetCmdPtr out
+Pointer to location to store the address of the name of the target command
+for an alias.
+.AP int *argcPtr out
+Pointer to location to store count of additional arguments to be passed to
+the alias. The location is in storage owned by the caller.
+.AP "const char" ***argvPtr out
+Pointer to location to store a vector of strings, the additional arguments
+to pass to an alias. The location is in storage owned by the caller, the
+vector of strings is owned by the called function.
+.AP int *objcPtr out
+Pointer to location to store count of additional value arguments to be
+passed to the alias. The location is in storage owned by the caller.
+.AP Tcl_Obj ***objvPtr out
+Pointer to location to store a vector of Tcl_Obj structures, the additional
+arguments to pass to an alias command. The location is in storage
+owned by the caller, the vector of Tcl_Obj structures is owned by the
+called function.
+.AP "const char" *cmdName in
+Name of an exposed command to hide or create.
+.AP "const char" *hiddenCmdName in
+Name under which a hidden command is stored and with which it can be
+exposed or invoked.
+.BE
+
+.SH DESCRIPTION
+.PP
+These procedures are intended for access to the multiple interpreter
+facility from inside C programs. They enable managing multiple interpreters
+in a hierarchical relationship, and the management of aliases, commands
+that when invoked in one interpreter execute a command in another
+interpreter. The return value for those procedures that return an \fBint\fR
+is either \fBTCL_OK\fR or \fBTCL_ERROR\fR. If \fBTCL_ERROR\fR is returned
+then the \fBresult\fR field of the interpreter contains an error message.
+.PP
+\fBTcl_CreateSlave\fR creates a new interpreter as a slave of \fIinterp\fR.
+It also creates a slave command named \fIslaveName\fR in \fIinterp\fR which
+allows \fIinterp\fR to manipulate the new slave.
+If \fIisSafe\fR is zero, the command creates a trusted slave in which Tcl
+code has access to all the Tcl commands.
+If it is \fB1\fR, the command creates a
+.QW safe
+slave in which Tcl code has access only to set of Tcl commands defined as
+.QW "Safe Tcl" ;
+see the manual entry for the Tcl \fBinterp\fR command for details.
+If the creation of the new slave interpreter failed, \fBNULL\fR is returned.
+.PP
+\fBTcl_IsSafe\fR returns \fB1\fR if \fIinterp\fR is
+.QW safe
+(was created with the \fBTCL_SAFE_INTERPRETER\fR flag specified),
+\fB0\fR otherwise.
+.PP
+\fBTcl_MakeSafe\fR marks \fIinterp\fR as
+.QW safe ,
+so that future
+calls to \fBTcl_IsSafe\fR will return 1.  It also removes all known
+potentially-unsafe core functionality (both commands and variables)
+from \fIinterp\fR.  However, it cannot know what parts of an extension
+or application are safe and does not make any attempt to remove those
+parts, so safety is not guaranteed after calling \fBTcl_MakeSafe\fR.
+Callers will want to take care with their use of \fBTcl_MakeSafe\fR
+to avoid false claims of safety.  For many situations, \fBTcl_CreateSlave\fR
+may be a better choice, since it creates interpreters in a known-safe state.
+.PP
+\fBTcl_GetSlave\fR returns a pointer to a slave interpreter of
+\fIinterp\fR. The slave interpreter is identified by \fIslaveName\fR.
+If no such slave interpreter exists, \fBNULL\fR is returned.
+.PP
+\fBTcl_GetMaster\fR returns a pointer to the master interpreter of
+\fIinterp\fR. If \fIinterp\fR has no master (it is a
+top-level interpreter) then \fBNULL\fR is returned.
+.PP
+\fBTcl_GetInterpPath\fR sets the \fIresult\fR field in \fIaskingInterp\fR
+to the relative path between \fIaskingInterp\fR and \fIslaveInterp\fR;
+\fIslaveInterp\fR must be a slave of \fIaskingInterp\fR. If the computation
+of the relative path succeeds, \fBTCL_OK\fR is returned, else
+\fBTCL_ERROR\fR is returned and the \fIresult\fR field in
+\fIaskingInterp\fR contains the error message.
+.PP
+\fBTcl_CreateAlias\fR creates a command named \fIslaveCmd\fR in
+\fIslaveInterp\fR that when invoked, will cause the command \fItargetCmd\fR
+to be invoked in \fItargetInterp\fR. The arguments specified by the strings
+contained in \fIargv\fR are always prepended to any arguments supplied in the
+invocation of \fIslaveCmd\fR and passed to \fItargetCmd\fR.
+This operation returns \fBTCL_OK\fR if it succeeds, or \fBTCL_ERROR\fR if
+it fails; in that case, an error message is left in the value result
+of \fIslaveInterp\fR.
+Note that there are no restrictions on the ancestry relationship (as
+created by \fBTcl_CreateSlave\fR) between \fIslaveInterp\fR and
+\fItargetInterp\fR. Any two interpreters can be used, without any
+restrictions on how they are related.
+.PP
+\fBTcl_CreateAliasObj\fR is similar to \fBTcl_CreateAlias\fR except
+that it takes a vector of values to pass as additional arguments instead
+of a vector of strings.
+.PP
+\fBTcl_GetAlias\fR returns information about an alias \fIaliasName\fR
+in \fIinterp\fR. Any of the result fields can be \fBNULL\fR, in
+which case the corresponding datum is not returned. If a result field is
+non\-\fBNULL\fR, the address indicated is set to the corresponding datum.
+For example, if \fItargetNamePtr\fR is non\-\fBNULL\fR it is set to a
+pointer to the string containing the name of the target command.
+.PP
+\fBTcl_GetAliasObj\fR is similar to \fBTcl_GetAlias\fR except that it
+returns a pointer to a vector of Tcl_Obj structures instead of a vector of
+strings.
+.PP
+\fBTcl_ExposeCommand\fR moves the command named \fIhiddenCmdName\fR from
+the set of hidden commands to the set of exposed commands, putting
+it under the name
+\fIcmdName\fR.
+\fIHiddenCmdName\fR must be the name of an existing hidden
+command, or the operation will return \fBTCL_ERROR\fR and leave an error
+message in the \fIresult\fR field in \fIinterp\fR.
+If an exposed command named \fIcmdName\fR already exists,
+the operation returns \fBTCL_ERROR\fR and leaves an error message in the
+value result of \fIinterp\fR.
+If the operation succeeds, it returns \fBTCL_OK\fR.
+After executing this command, attempts to use \fIcmdName\fR in a call to
+\fBTcl_Eval\fR or with the Tcl \fBeval\fR command will again succeed.
+.PP
+\fBTcl_HideCommand\fR moves the command named \fIcmdName\fR from the set of
+exposed commands to the set of hidden commands, under the name
+\fIhiddenCmdName\fR.
+\fICmdName\fR must be the name of an existing exposed
+command, or the operation will return \fBTCL_ERROR\fR and leave an error
+message in the value result of \fIinterp\fR.
+Currently both \fIcmdName\fR and \fIhiddenCmdName\fR must not contain
+namespace qualifiers, or the operation will return \fBTCL_ERROR\fR and
+leave an error message in the value result of \fIinterp\fR.
+The \fICmdName\fR will be looked up in the global namespace, and not
+relative to the current namespace, even if the current namespace is not the
+global one.
+If a hidden command whose name is \fIhiddenCmdName\fR already
+exists, the operation also returns \fBTCL_ERROR\fR and the \fIresult\fR
+field in \fIinterp\fR contains an error message.
+If the operation succeeds, it returns \fBTCL_OK\fR.
+After executing this command, attempts to use \fIcmdName\fR in a call to
+\fBTcl_Eval\fR or with the Tcl \fBeval\fR command will fail.
+.PP
+For a description of the Tcl interface to multiple interpreters, see
+\fIinterp(n)\fR.
+.SH "SEE ALSO"
+interp
+
+.SH KEYWORDS
+alias, command, exposed commands, hidden commands, interpreter, invoke,
+master, slave
diff --git a/doc/CrtTimerHdlr.3 b/doc/CrtTimerHdlr.3
new file mode 100644
index 0000000..f3957c7
--- /dev/null
+++ b/doc/CrtTimerHdlr.3
@@ -0,0 +1,76 @@
+'\"
+'\" Copyright (c) 1990 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\" 
+.TH Tcl_CreateTimerHandler 3 7.5 Tcl "Tcl Library Procedures"
+.so man.macros
+.BS
+.SH NAME
+Tcl_CreateTimerHandler, Tcl_DeleteTimerHandler \- call a procedure at a given time
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+Tcl_TimerToken
+\fBTcl_CreateTimerHandler\fR(\fImilliseconds, proc, clientData\fR)
+.sp
+\fBTcl_DeleteTimerHandler\fR(\fItoken\fR)
+.SH ARGUMENTS
+.AS Tcl_TimerToken milliseconds
+.AP int milliseconds  in
+How many milliseconds to wait before invoking \fIproc\fR.
+.AP Tcl_TimerProc *proc in
+Procedure to invoke after \fImilliseconds\fR have elapsed.
+.AP ClientData clientData in
+Arbitrary one-word value to pass to \fIproc\fR.
+.AP Tcl_TimerToken token in
+Token for previously created timer handler (the return value
+from some previous call to \fBTcl_CreateTimerHandler\fR).
+.BE
+.SH DESCRIPTION
+.PP
+\fBTcl_CreateTimerHandler\fR arranges for \fIproc\fR to be
+invoked at a time \fImilliseconds\fR milliseconds in the
+future.
+The callback to \fIproc\fR will be made by \fBTcl_DoOneEvent\fR,
+so \fBTcl_CreateTimerHandler\fR is only useful in programs that
+dispatch events through \fBTcl_DoOneEvent\fR or through Tcl commands
+such as \fBvwait\fR.
+The call to \fIproc\fR may not be made at the exact time given by
+\fImilliseconds\fR:  it will be made at the next opportunity
+after that time.  For example, if \fBTcl_DoOneEvent\fR is not
+called until long after the time has elapsed, or if there
+are other pending events to process before the call to
+\fIproc\fR, then the call to \fIproc\fR will be delayed.
+.PP
+\fIProc\fR should have arguments and return value that match
+the type \fBTcl_TimerProc\fR:
+.PP
+.CS
+typedef void \fBTcl_TimerProc\fR(
+        ClientData \fIclientData\fR);
+.CE
+.PP
+The \fIclientData\fR parameter to \fIproc\fR is a
+copy of the \fIclientData\fR argument given to
+\fBTcl_CreateTimerHandler\fR when the callback
+was created.  Typically, \fIclientData\fR points to a data
+structure containing application-specific information about
+what to do in \fIproc\fR.
+.PP
+\fBTcl_DeleteTimerHandler\fR may be called to delete a
+previously created timer handler.  It deletes the handler
+indicated by \fItoken\fR so that no call to \fIproc\fR
+will be made;  if that handler no longer exists
+(e.g. because the time period has already elapsed and \fIproc\fR
+has been invoked then \fBTcl_DeleteTimerHandler\fR does nothing.
+The tokens returned by \fBTcl_CreateTimerHandler\fR never have
+a value of NULL, so if NULL is passed to \fBTcl_DeleteTimerHandler\fR
+then the procedure does nothing.
+.SH "SEE ALSO"
+after(n), Tcl_CreateFileHandler(3), Tcl_DoWhenIdle(3)
+.SH KEYWORDS
+callback, clock, handler, timer
diff --git a/doc/CrtTrace.3 b/doc/CrtTrace.3
new file mode 100644
index 0000000..d5353ac
--- /dev/null
+++ b/doc/CrtTrace.3
@@ -0,0 +1,191 @@
+'\"
+'\" Copyright (c) 1989-1993 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\" Copyright (c) 2002 by Kevin B. Kenny <kennykb@acm.org>.  All rights reserved.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH Tcl_CreateTrace 3 "" Tcl "Tcl Library Procedures"
+.so man.macros
+.BS
+.SH NAME
+Tcl_CreateTrace, Tcl_CreateObjTrace, Tcl_DeleteTrace \- arrange for command execution to be traced
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+Tcl_Trace
+\fBTcl_CreateTrace\fR(\fIinterp, level, proc, clientData\fR)
+.sp
+Tcl_Trace
+\fBTcl_CreateObjTrace\fR(\fIinterp, level, flags, objProc, clientData, deleteProc\fR)
+.sp
+\fBTcl_DeleteTrace\fR(\fIinterp, trace\fR)
+.SH ARGUMENTS
+.AS Tcl_CmdObjTraceDeleteProc *deleteProc
+.AP Tcl_Interp *interp in
+Interpreter containing command to be traced or untraced.
+.AP int level in
+Only commands at or below this nesting level will be traced unless
+0 is specified.  1 means
+top-level commands only, 2 means top-level commands or those that are
+invoked as immediate consequences of executing top-level commands
+(procedure bodies, bracketed commands, etc.) and so on.
+A value of 0 means that commands at any level are traced.
+.AP int flags in
+Flags governing the trace execution.  See below for details.
+.AP Tcl_CmdObjTraceProc *objProc in
+Procedure to call for each command that is executed.  See below for
+details of the calling sequence.
+.AP Tcl_CmdTraceProc *proc in
+Procedure to call for each command that is executed.  See below for
+details on the calling sequence.
+.AP ClientData clientData in
+Arbitrary one-word value to pass to \fIobjProc\fR or \fIproc\fR.
+.AP Tcl_CmdObjTraceDeleteProc *deleteProc in
+Procedure to call when the trace is deleted.  See below for details of
+the calling sequence.  A NULL pointer is permissible and results in no
+callback when the trace is deleted.
+.AP Tcl_Trace trace in
+Token for trace to be removed (return value from previous call
+to \fBTcl_CreateTrace\fR).
+.BE
+.SH DESCRIPTION
+.PP
+\fBTcl_CreateObjTrace\fR arranges for command tracing.  After it is
+called, \fIobjProc\fR will be invoked before the Tcl interpreter calls
+any command procedure when evaluating commands in \fIinterp\fR.
+The return value from \fBTcl_CreateObjTrace\fR is a token for the trace,
+which may be passed to \fBTcl_DeleteTrace\fR to remove the trace.
+There may be many traces in effect simultaneously for the same
+interpreter.
+.PP
+\fIobjProc\fR should have arguments and result that match the type,
+\fBTcl_CmdObjTraceProc\fR:
+.PP
+.CS
+typedef int \fBTcl_CmdObjTraceProc\fR(
+        \fBClientData\fR \fIclientData\fR,
+        \fBTcl_Interp\fR* \fIinterp\fR,
+        int \fIlevel\fR,
+        const char *\fIcommand\fR,
+        \fBTcl_Command\fR \fIcommandToken\fR,
+        int \fIobjc\fR,
+        \fBTcl_Obj\fR *const \fIobjv\fR[]);
+.CE
+.PP
+The \fIclientData\fR and \fIinterp\fR parameters are copies of the
+corresponding arguments given to \fBTcl_CreateTrace\fR.
+\fIClientData\fR typically points to an application-specific data
+structure that describes what to do when \fIobjProc\fR is invoked.  The
+\fIlevel\fR parameter gives the nesting level of the command (1 for
+top-level commands passed to \fBTcl_Eval\fR by the application, 2 for
+the next-level commands passed to \fBTcl_Eval\fR as part of parsing or
+interpreting level-1 commands, and so on). The \fIcommand\fR parameter
+points to a string containing the text of the command, before any
+argument substitution.  The \fIcommandToken\fR parameter is a Tcl
+command token that identifies the command to be invoked.  The token
+may be passed to \fBTcl_GetCommandName\fR,
+\fBTcl_GetCommandInfoFromToken\fR, or \fBTcl_SetCommandInfoFromToken\fR to
+manipulate the definition of the command. The \fIobjc\fR and \fIobjv\fR
+parameters designate the final parameter count and parameter vector
+that will be passed to the command, and have had all substitutions
+performed.
+.PP
+The \fIobjProc\fR callback is expected to return a standard Tcl status
+return code.  If this code is \fBTCL_OK\fR (the normal case), then
+the Tcl interpreter will invoke the command.  Any other return code
+is treated as if the command returned that status, and the command is
+\fInot\fR invoked.
+.PP
+The \fIobjProc\fR callback must not modify \fIobjv\fR in any way.  It
+is, however, permissible to change the command by calling
+\fBTcl_SetCommandTokenInfo\fR prior to returning.  Any such change
+takes effect immediately, and the command is invoked with the new
+information.
+.PP
+Tracing will only occur for commands at nesting level less than
+or equal to the \fIlevel\fR parameter (i.e. the \fIlevel\fR
+parameter to \fIobjProc\fR will always be less than or equal to the
+\fIlevel\fR parameter to \fBTcl_CreateTrace\fR).
+.PP
+Tracing has a significant effect on runtime performance because it
+causes the bytecode compiler to refrain from generating in-line code
+for Tcl commands such as \fBif\fR and \fBwhile\fR in order that they
+may be traced.  If traces for the built-in commands are not required,
+the \fIflags\fR parameter may be set to the constant value
+\fBTCL_ALLOW_INLINE_COMPILATION\fR.  In this case, traces on built-in
+commands may or may not result in trace callbacks, depending on the
+state of the interpreter, but run-time performance will be improved
+significantly.  (This functionality is desirable, for example, when
+using \fBTcl_CreateObjTrace\fR to implement an execution time
+profiler.)
+.PP
+Calls to \fIobjProc\fR will be made by the Tcl parser immediately before
+it calls the command procedure for the command (\fIcmdProc\fR).  This
+occurs after argument parsing and substitution, so tracing for
+substituted commands occurs before tracing of the commands
+containing the substitutions.  If there is a syntax error in a
+command, or if there is no command procedure associated with a
+command name, then no tracing will occur for that command.  If a
+string passed to Tcl_Eval contains multiple commands (bracketed, or
+on different lines) then multiple calls to \fIobjProc\fR will occur,
+one for each command.
+.PP
+\fBTcl_DeleteTrace\fR removes a trace, so that no future calls will be
+made to the procedure associated with the trace.  After \fBTcl_DeleteTrace\fR
+returns, the caller should never again use the \fItrace\fR token.
+.PP
+When \fBTcl_DeleteTrace\fR is called, the interpreter invokes the
+\fIdeleteProc\fR that was passed as a parameter to
+\fBTcl_CreateObjTrace\fR.  The \fIdeleteProc\fR must match the type,
+\fBTcl_CmdObjTraceDeleteProc\fR:
+.PP
+.CS
+typedef void \fBTcl_CmdObjTraceDeleteProc\fR(
+        \fBClientData\fR \fIclientData\fR);
+.CE
+.PP
+The \fIclientData\fR parameter will be the same as the
+\fIclientData\fR parameter that was originally passed to
+\fBTcl_CreateObjTrace\fR.
+.PP
+\fBTcl_CreateTrace\fR is an alternative interface for command tracing,
+\fInot recommended for new applications\fR.  It is provided for backward
+compatibility with code that was developed for older versions of the
+Tcl interpreter.  It is similar to \fBTcl_CreateObjTrace\fR, except
+that its \fIproc\fR parameter should have arguments and result that
+match the type \fBTcl_CmdTraceProc\fR:
+.PP
+.CS
+typedef void \fBTcl_CmdTraceProc\fR(
+        ClientData \fIclientData\fR,
+        Tcl_Interp *\fIinterp\fR,
+        int \fIlevel\fR,
+        char *\fIcommand\fR,
+        Tcl_CmdProc *\fIcmdProc\fR,
+        ClientData \fIcmdClientData\fR,
+        int \fIargc\fR,
+        const char *\fIargv\fR[]);
+.CE
+.PP
+The parameters to the \fIproc\fR callback are similar to those of the
+\fIobjProc\fR callback above. The \fIcommandToken\fR is
+replaced with \fIcmdProc\fR, a pointer to the (string-based) command
+procedure that will be invoked; and \fIcmdClientData\fR, the client
+data that will be passed to the procedure.  The \fIobjc\fR parameter
+is replaced with an \fIargv\fR parameter, that gives the arguments to
+the command as character strings.
+\fIProc\fR must not modify the \fIcommand\fR or \fIargv\fR strings.
+.PP
+If a trace created with \fBTcl_CreateTrace\fR is in effect, inline
+compilation of Tcl commands such as \fBif\fR and \fBwhile\fR is always
+disabled.  There is no notification when a trace created with
+\fBTcl_CreateTrace\fR is deleted.
+There is no way to be notified when the trace created by
+\fBTcl_CreateTrace\fR is deleted.  There is no way for the \fIproc\fR
+associated with a call to \fBTcl_CreateTrace\fR to abort execution of
+\fIcommand\fR.
+.SH KEYWORDS
+command, create, delete, interpreter, trace
diff --git a/doc/DString.3 b/doc/DString.3
new file mode 100644
index 0000000..00f1b8a
--- /dev/null
+++ b/doc/DString.3
@@ -0,0 +1,153 @@
+'\"
+'\" Copyright (c) 1993 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH Tcl_DString 3 7.4 Tcl "Tcl Library Procedures"
+.so man.macros
+.BS
+.SH NAME
+Tcl_DStringInit, Tcl_DStringAppend, Tcl_DStringAppendElement, Tcl_DStringStartSublist, Tcl_DStringEndSublist, Tcl_DStringLength, Tcl_DStringValue, Tcl_DStringSetLength, Tcl_DStringTrunc, Tcl_DStringFree, Tcl_DStringResult, Tcl_DStringGetResult \- manipulate dynamic strings
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+\fBTcl_DStringInit\fR(\fIdsPtr\fR)
+.sp
+char *
+\fBTcl_DStringAppend\fR(\fIdsPtr, bytes, length\fR)
+.sp
+char *
+\fBTcl_DStringAppendElement\fR(\fIdsPtr, element\fR)
+.sp
+\fBTcl_DStringStartSublist\fR(\fIdsPtr\fR)
+.sp
+\fBTcl_DStringEndSublist\fR(\fIdsPtr\fR)
+.sp
+int
+\fBTcl_DStringLength\fR(\fIdsPtr\fR)
+.sp
+char *
+\fBTcl_DStringValue\fR(\fIdsPtr\fR)
+.sp
+\fBTcl_DStringSetLength\fR(\fIdsPtr, newLength\fR)
+.sp
+\fBTcl_DStringTrunc\fR(\fIdsPtr, newLength\fR)
+.sp
+\fBTcl_DStringFree\fR(\fIdsPtr\fR)
+.sp
+\fBTcl_DStringResult\fR(\fIinterp, dsPtr\fR)
+.sp
+\fBTcl_DStringGetResult\fR(\fIinterp, dsPtr\fR)
+.SH ARGUMENTS
+.AS Tcl_DString newLength in/out
+.AP Tcl_DString *dsPtr in/out
+Pointer to structure that is used to manage a dynamic string.
+.AP "const char" *bytes in
+Pointer to characters to append to dynamic string.
+.AP "const char" *element in
+Pointer to characters to append as list element to dynamic string.
+.AP int length in
+Number of bytes from \fIbytes\fR to add to dynamic string.  If -1,
+add all characters up to null terminating character.
+.AP int newLength in
+New length for dynamic string, not including null terminating
+character.
+.AP Tcl_Interp *interp in/out
+Interpreter whose result is to be set from or moved to the
+dynamic string.
+.BE
+
+.SH DESCRIPTION
+.PP
+Dynamic strings provide a mechanism for building up arbitrarily long
+strings by gradually appending information.  If the dynamic string is
+short then there will be no memory allocation overhead;  as the string
+gets larger, additional space will be allocated as needed.
+.PP
+\fBTcl_DStringInit\fR initializes a dynamic string to zero length.
+The Tcl_DString structure must have been allocated by the caller.
+No assumptions are made about the current state of the structure;
+anything already in it is discarded.
+If the structure has been used previously, \fBTcl_DStringFree\fR should
+be called first to free up any memory allocated for the old
+string.
+.PP
+\fBTcl_DStringAppend\fR adds new information to a dynamic string,
+allocating more memory for the string if needed.
+If \fIlength\fR is less than zero then everything in \fIbytes\fR
+is appended to the dynamic string;  otherwise \fIlength\fR
+specifies the number of bytes to append.
+\fBTcl_DStringAppend\fR returns a pointer to the characters of
+the new string.  The string can also be retrieved from the
+\fIstring\fR field of the Tcl_DString structure.
+.PP
+\fBTcl_DStringAppendElement\fR is similar to \fBTcl_DStringAppend\fR
+except that it does not take a \fIlength\fR argument (it appends
+all of \fIelement\fR) and it converts the string to a proper list element
+before appending.
+\fBTcl_DStringAppendElement\fR adds a separator space before the
+new list element unless the new list element is the first in a
+list or sub-list (i.e. either the current string is empty, or it
+contains the single character
+.QW { ,
+or the last two characters of the current string are
+.QW " {" ).
+\fBTcl_DStringAppendElement\fR returns a pointer to the
+characters of the new string.
+.PP
+\fBTcl_DStringStartSublist\fR and \fBTcl_DStringEndSublist\fR can be
+used to create nested lists.
+To append a list element that is itself a sublist, first
+call \fBTcl_DStringStartSublist\fR, then call \fBTcl_DStringAppendElement\fR
+for each of the elements in the sublist, then call
+\fBTcl_DStringEndSublist\fR to end the sublist.
+\fBTcl_DStringStartSublist\fR appends a space character if needed,
+followed by an open brace;  \fBTcl_DStringEndSublist\fR appends
+a close brace.
+Lists can be nested to any depth.
+.PP
+\fBTcl_DStringLength\fR is a macro that returns the current length
+of a dynamic string (not including the terminating null character).
+\fBTcl_DStringValue\fR is a  macro that returns a pointer to the
+current contents of a dynamic string.
+.PP
+.PP
+\fBTcl_DStringSetLength\fR changes the length of a dynamic string.
+If \fInewLength\fR is less than the string's current length, then
+the string is truncated.
+If \fInewLength\fR is greater than the string's current length,
+then the string will become longer and new space will be allocated
+for the string if needed.
+However, \fBTcl_DStringSetLength\fR will not initialize the new
+space except to provide a terminating null character;  it is up to the
+caller to fill in the new space.
+\fBTcl_DStringSetLength\fR does not free up the string's storage space
+even if the string is truncated to zero length, so \fBTcl_DStringFree\fR
+will still need to be called.
+.PP
+\fBTcl_DStringTrunc\fR changes the length of a dynamic string.
+This procedure is now deprecated.  \fBTcl_DStringSetLength\fR  should
+be used instead.
+.PP
+\fBTcl_DStringFree\fR should be called when you are finished using
+the string.  It frees up any memory that was allocated for the string
+and reinitializes the string's value to an empty string.
+.PP
+\fBTcl_DStringResult\fR sets the result of \fIinterp\fR to the value of
+the dynamic string given by \fIdsPtr\fR.  It does this by moving
+a pointer from \fIdsPtr\fR to the interpreter's result.
+This saves the cost of allocating new memory and copying the string.
+\fBTcl_DStringResult\fR also reinitializes the dynamic string to
+an empty string.
+.PP
+\fBTcl_DStringGetResult\fR does the opposite of \fBTcl_DStringResult\fR.
+It sets the value of \fIdsPtr\fR to the result of \fIinterp\fR and
+it clears \fIinterp\fR's result.
+If possible it does this by moving a pointer rather than by copying
+the string.
+
+.SH KEYWORDS
+append, dynamic string, free, result
diff --git a/doc/DetachPids.3 b/doc/DetachPids.3
new file mode 100644
index 0000000..39a51d3
--- /dev/null
+++ b/doc/DetachPids.3
@@ -0,0 +1,75 @@
+'\"
+'\" Copyright (c) 1989-1993 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\" 
+.TH Tcl_DetachPids 3 "" Tcl "Tcl Library Procedures"
+.so man.macros
+.BS
+.SH NAME
+Tcl_DetachPids, Tcl_ReapDetachedProcs, Tcl_WaitPid \- manage child processes in background
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+\fBTcl_DetachPids\fR(\fInumPids, pidPtr\fR)
+.sp
+\fBTcl_ReapDetachedProcs\fR()
+.sp
+Tcl_Pid
+\fBTcl_WaitPid\fR(\fIpid, statusPtr, options\fR)
+.SH ARGUMENTS
+.AS Tcl_Pid *statusPtr out
+.AP int numPids in
+Number of process ids contained in the array pointed to by \fIpidPtr\fR.
+.AP int *pidPtr in
+Address of array containing \fInumPids\fR process ids.
+.AP Tcl_Pid pid in
+The id of the process (pipe) to wait for.
+.AP int *statusPtr out
+The result of waiting on a process (pipe). Either 0 or ECHILD.
+.AP int options in
+The options controlling the wait. WNOHANG specifies not to wait when
+checking the process.
+.BE
+.SH DESCRIPTION
+.PP
+\fBTcl_DetachPids\fR and \fBTcl_ReapDetachedProcs\fR provide a
+mechanism for managing subprocesses that are running in background.
+These procedures are needed because the parent of a process must
+eventually invoke the \fBwaitpid\fR kernel call (or one of a few other
+similar kernel calls) to wait for the child to exit.  Until the
+parent waits for the child, the child's state cannot be completely
+reclaimed by the system.  If a parent continually creates children
+and doesn't wait on them, the system's process table will eventually
+overflow, even if all the children have exited.
+.PP
+\fBTcl_DetachPids\fR may be called to ask Tcl to take responsibility
+for one or more processes whose process ids are contained in the
+\fIpidPtr\fR array passed as argument.  The caller presumably
+has started these processes running in background and does not
+want to have to deal with them again.
+.PP
+\fBTcl_ReapDetachedProcs\fR invokes the \fBwaitpid\fR kernel call
+on each of the background processes so that its state can be cleaned
+up if it has exited.  If the process has not exited yet,
+\fBTcl_ReapDetachedProcs\fR does not wait for it to exit;  it will check again
+the next time it is invoked.
+Tcl automatically calls \fBTcl_ReapDetachedProcs\fR each time the
+\fBexec\fR command is executed, so in most cases it is not necessary
+for any code outside of Tcl to invoke \fBTcl_ReapDetachedProcs\fR.
+However, if you call \fBTcl_DetachPids\fR in situations where the
+\fBexec\fR command may never get executed, you may wish to call
+\fBTcl_ReapDetachedProcs\fR from time to time so that background
+processes can be cleaned up.
+.PP
+\fBTcl_WaitPid\fR is a thin wrapper around the facilities provided by
+the operating system to wait on the end of a spawned process and to
+check a whether spawned process is still running. It is used by
+\fBTcl_ReapDetachedProcs\fR and the channel system to portably access
+the operating system.
+
+.SH KEYWORDS
+background, child, detach, process, wait
diff --git a/doc/DictObj.3 b/doc/DictObj.3
new file mode 100644
index 0000000..90ca9e3
--- /dev/null
+++ b/doc/DictObj.3
@@ -0,0 +1,234 @@
+'\"
+'\" Copyright (c) 2003 Donal K. Fellows
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\" 
+.TH Tcl_DictObj 3 8.5 Tcl "Tcl Library Procedures"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+Tcl_NewDictObj, Tcl_DictObjPut, Tcl_DictObjGet, Tcl_DictObjRemove, Tcl_DictObjSize, Tcl_DictObjFirst, Tcl_DictObjNext, Tcl_DictObjDone, Tcl_DictObjPutKeyList, Tcl_DictObjRemoveKeyList \- manipulate Tcl values as dictionaries
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+Tcl_Obj *
+\fBTcl_NewDictObj\fR()
+.sp
+int
+\fBTcl_DictObjGet\fR(\fIinterp, dictPtr, keyPtr, valuePtrPtr\fR)
+.sp
+int
+\fBTcl_DictObjPut\fR(\fIinterp, dictPtr, keyPtr, valuePtr\fR)
+.sp
+int
+\fBTcl_DictObjRemove\fR(\fIinterp, dictPtr, keyPtr\fR)
+.sp
+int
+\fBTcl_DictObjSize\fR(\fIinterp, dictPtr, sizePtr\fR)
+.sp
+int
+\fBTcl_DictObjFirst\fR(\fIinterp, dictPtr, searchPtr,
+                 keyPtrPtr, valuePtrPtr, donePtr\fR)
+.sp
+void
+\fBTcl_DictObjNext\fR(\fIsearchPtr, keyPtrPtr, valuePtrPtr, donePtr\fR)
+.sp
+void
+\fBTcl_DictObjDone\fR(\fIsearchPtr\fR)
+.sp
+int
+\fBTcl_DictObjPutKeyList\fR(\fIinterp, dictPtr, keyc, keyv, valuePtr\fR)
+.sp
+int
+\fBTcl_DictObjRemoveKeyList\fR(\fIinterp, dictPtr, keyc, keyv\fR)
+.SH ARGUMENTS
+.AS Tcl_DictSearch "**valuePtrPtr" in/out
+.AP Tcl_Interp *interp in
+If an error occurs while converting a value to be a dictionary value,
+an error message is left in the interpreter's result value
+unless \fIinterp\fR is NULL.
+.AP Tcl_Obj *dictPtr in/out
+Points to the dictionary value to be manipulated.
+If \fIdictPtr\fR does not already point to a dictionary value,
+an attempt will be made to convert it to one.
+.AP Tcl_Obj *keyPtr in
+Points to the key for the key/value pair being manipulated within the
+dictionary value.
+.AP Tcl_Obj **keyPtrPtr out
+Points to a variable that will have the key from a key/value pair
+placed within it.  May be NULL to indicate that the caller is not
+interested in the key.
+.AP Tcl_Obj *valuePtr in
+Points to the value for the key/value pair being manipulated within the
+dictionary value (or sub-value, in the case of
+\fBTcl_DictObjPutKeyList\fR.)
+.AP Tcl_Obj **valuePtrPtr out
+Points to a variable that will have the value from a key/value pair
+placed within it.  For \fBTcl_DictObjFirst\fR and
+\fBTcl_DictObjNext\fR, this may be NULL to indicate that the caller is
+not interested in the value.
+.AP int *sizePtr out
+Points to a variable that will have the number of key/value pairs
+contained within the dictionary placed within it.
+.AP Tcl_DictSearch *searchPtr in/out
+Pointer to record to use to keep track of progress in enumerating all
+key/value pairs in a dictionary.  The contents of the record will be
+initialized by the call to \fBTcl_DictObjFirst\fR.  If the enumerating
+is to be terminated before all values in the dictionary have been
+returned, the search record \fImust\fR be passed to
+\fBTcl_DictObjDone\fR to enable the internal locks to be released.
+.AP int *donePtr out
+Points to a variable that will have a non-zero value written into it
+when the enumeration of the key/value pairs in a dictionary has
+completed, and a zero otherwise.
+.AP int keyc in
+Indicates the number of keys that will be supplied in the \fIkeyv\fR
+array.
+.AP "Tcl_Obj *const" *keyv in
+Array of \fIkeyc\fR pointers to values that
+\fBTcl_DictObjPutKeyList\fR and \fBTcl_DictObjRemoveKeyList\fR will
+use to locate the key/value pair to manipulate within the
+sub-dictionaries of the main dictionary value passed to them.
+.BE
+
+.SH DESCRIPTION
+.PP
+Tcl dictionary values have an internal representation that supports
+efficient mapping from keys to values and which guarantees that the
+particular ordering of keys within the dictionary remains the same
+modulo any keys being deleted (which removes them from the order) or
+added (which adds them to the end of the order). If reinterpreted as a
+list, the values at the even-valued indices in the list will be the
+keys of the dictionary, and each will be followed (in the odd-valued
+index) by the value associated with that key.
+.PP
+The procedures described in this man page are used to
+create, modify, index, and iterate over dictionary values from C code.
+.PP
+\fBTcl_NewDictObj\fR creates a new, empty dictionary value.  The
+string representation of the value will be invalid, and the reference
+count of the value will be zero.
+.PP
+\fBTcl_DictObjGet\fR looks up the given key within the given
+dictionary and writes a pointer to the value associated with that key
+into the variable pointed to by \fIvaluePtrPtr\fR, or a NULL if the
+key has no mapping within the dictionary.  The result of this
+procedure is \fBTCL_OK\fR, or \fBTCL_ERROR\fR if the \fIdictPtr\fR cannot be
+converted to a dictionary.
+.PP
+\fBTcl_DictObjPut\fR updates the given dictionary so that the given
+key maps to the given value; any key may exist at most once in any
+particular dictionary.  The dictionary must not be shared, but the key
+and value may be.  This procedure may increase the reference count of
+both key and value if it proves necessary to store them.  Neither key
+nor value should be NULL.  The result of this procedure is \fBTCL_OK\fR, or
+\fBTCL_ERROR\fR if the \fIdictPtr\fR cannot be converted to a dictionary.
+.PP
+\fBTcl_DictObjRemove\fR updates the given dictionary so that the given
+key has no mapping to any value.  The dictionary must not be shared,
+but the key may be.  The key actually stored in the dictionary will
+have its reference count decremented if it was present.  It is not an
+error if the key did not previously exist.  The result of this
+procedure is \fBTCL_OK\fR, or \fBTCL_ERROR\fR if the \fIdictPtr\fR cannot be
+converted to a dictionary.
+.PP
+\fBTcl_DictObjSize\fR updates the given variable with the number of
+key/value pairs currently in the given dictionary. The result of this
+procedure is \fBTCL_OK\fR, or \fBTCL_ERROR\fR if the \fIdictPtr\fR cannot be
+converted to a dictionary.
+.PP
+\fBTcl_DictObjFirst\fR commences an iteration across all the key/value
+pairs in the given dictionary, placing the key and value in the
+variables pointed to by the \fIkeyPtrPtr\fR and \fIvaluePtrPtr\fR
+arguments (which may be NULL to indicate that the caller is
+uninterested in they key or variable respectively.)  The next
+key/value pair in the dictionary may be retrieved with
+\fBTcl_DictObjNext\fR.  Concurrent updates of the dictionary's
+internal representation will not modify the iteration processing
+unless the dictionary is unshared, when this will trigger premature
+termination of the iteration instead (which Tcl scripts cannot trigger
+via the \fBdict\fR command.)  The \fIsearchPtr\fR argument points to a
+piece of context that is used to identify which particular iteration
+is being performed, and is initialized by the call to
+\fBTcl_DictObjFirst\fR.  The \fIdonePtr\fR argument points to a
+variable that is updated to be zero of there are further key/value
+pairs to be iterated over, or non-zero if the iteration is complete.
+The order of iteration is implementation-defined.  If the
+\fIdictPtr\fR argument cannot be converted to a dictionary,
+\fBTcl_DictObjFirst\fR returns \fBTCL_ERROR\fR and the iteration is not
+commenced, and otherwise it returns \fBTCL_OK\fR.
+.PP
+When \fBTcl_DictObjFirst\fR is called upon a dictionary, a lock is placed on
+the dictionary to enable that dictionary to be iterated over safely without
+regard for whether the dictionary is modified during the iteration. Because of
+this, once the iteration over a dictionary's keys has finished (whether
+because all values have been iterated over as indicated by the variable
+indicated by the \fIdonePtr\fR argument being set to one, or because no
+further values are required) the \fBTcl_DictObjDone\fR function must be called
+with the same \fIsearchPtr\fR as was passed to \fBTcl_DictObjFirst\fR so that
+the internal locks can be released. Once a particular \fIsearchPtr\fR is
+passed to \fBTcl_DictObjDone\fR, passing it to \fBTcl_DictObjNext\fR (without
+first initializing it with \fBTcl_DictObjFirst\fR) will result in no values
+being produced and the variable pointed to by \fIdonePtr\fR being set to one.
+It is safe to call \fBTcl_DictObjDone\fR multiple times on the same
+\fIsearchPtr\fR for each call to \fBTcl_DictObjFirst\fR.
+.PP
+The procedures \fBTcl_DictObjPutKeyList\fR and
+\fBTcl_DictObjRemoveKeyList\fR are the close analogues of
+\fBTcl_DictObjPut\fR and \fBTcl_DictObjRemove\fR respectively, except
+that instead of working with a single dictionary, they are designed to
+operate on a nested tree of dictionaries, with inner dictionaries
+stored as values inside outer dictionaries.  The \fIkeyc\fR and
+\fIkeyv\fR arguments specify a list of keys (with outermost keys
+first) that acts as a path to the key/value pair to be affected.  Note
+that there is no corresponding operation for reading a value for a
+path as this is easy to construct from repeated use of
+\fBTcl_DictObjGet\fR. With \fBTcl_DictObjPutKeyList\fR, nested
+dictionaries are created for non-terminal keys where they do not
+already exist. With \fBTcl_DictObjRemoveKeyList\fR, all non-terminal
+keys must exist and have dictionaries as their values.
+.SH EXAMPLE
+Using the dictionary iteration interface to search determine if there
+is a key that maps to itself:
+.PP
+.CS
+Tcl_DictSearch search;
+Tcl_Obj *key, *value;
+int done;
+
+/*
+ * Assume interp and objPtr are parameters.  This is the
+ * idiomatic way to start an iteration over the dictionary; it
+ * sets a lock on the internal representation that ensures that
+ * there are no concurrent modification issues when normal
+ * reference count management is also used.  The lock is
+ * released automatically when the loop is finished, but must
+ * be released manually when an exceptional exit from the loop
+ * is performed. However it is safe to try to release the lock
+ * even if we've finished iterating over the loop.
+ */
+if (\fBTcl_DictObjFirst\fR(interp, objPtr, &search,
+        &key, &value, &done) != TCL_OK) {
+    return TCL_ERROR;
+}
+for (; !done ; \fBTcl_DictObjNext\fR(&search, &key, &value, &done)) {
+    /*
+     * Note that strcmp() is not a good way of comparing
+     * values and is just used here for demonstration
+     * purposes.
+     */
+    if (!strcmp(Tcl_GetString(key), Tcl_GetString(value))) {
+        break;
+    }
+}
+\fBTcl_DictObjDone\fR(&search);
+Tcl_SetObjResult(interp, Tcl_NewBooleanObj(!done));
+return TCL_OK;
+.CE
+.SH "SEE ALSO"
+Tcl_NewObj, Tcl_DecrRefCount, Tcl_IncrRefCount, Tcl_InitObjHashTable
+.SH KEYWORDS
+dict, dict value, dictionary, dictionary value, hash table, iteration, value
diff --git a/doc/DoOneEvent.3 b/doc/DoOneEvent.3
new file mode 100644
index 0000000..d48afd0
--- /dev/null
+++ b/doc/DoOneEvent.3
@@ -0,0 +1,106 @@
+'\"
+'\" Copyright (c) 1990-1992 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH Tcl_DoOneEvent 3 7.5 Tcl "Tcl Library Procedures"
+.so man.macros
+.BS
+.SH NAME
+Tcl_DoOneEvent \- wait for events and invoke event handlers
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+int
+\fBTcl_DoOneEvent\fR(\fIflags\fR)
+.SH ARGUMENTS
+.AS int flags
+.AP int flags in
+This parameter is normally zero.  It may be an OR-ed combination
+of any of the following flag bits:
+\fBTCL_WINDOW_EVENTS\fR, \fBTCL_FILE_EVENTS\fR,
+\fBTCL_TIMER_EVENTS\fR, \fBTCL_IDLE_EVENTS\fR, \fBTCL_ALL_EVENTS\fR,
+or \fBTCL_DONT_WAIT\fR.
+.BE
+
+.SH DESCRIPTION
+.PP
+This procedure is the entry point to Tcl's event loop; it is responsible for
+waiting for events and dispatching event handlers created with
+procedures such as \fBTk_CreateEventHandler\fR, \fBTcl_CreateFileHandler\fR,
+\fBTcl_CreateTimerHandler\fR, and \fBTcl_DoWhenIdle\fR.
+\fBTcl_DoOneEvent\fR checks to see if
+events are already present on the Tcl event queue; if so,
+it calls the handler(s) for the first (oldest) event, removes it from
+the queue, and returns.
+If there are no events ready to be handled, then \fBTcl_DoOneEvent\fR
+checks for new events from all possible sources.
+If any are found, it puts all of them on Tcl's event queue, calls
+handlers for the first event on the queue, and returns.
+If no events are found, \fBTcl_DoOneEvent\fR checks for \fBTcl_DoWhenIdle\fR
+callbacks; if any are found, it invokes all of them and returns.
+Finally, if no events or idle callbacks have been found, then
+\fBTcl_DoOneEvent\fR sleeps until an event occurs; then it adds any
+new events to the Tcl event queue, calls handlers for the first event,
+and returns.
+The normal return value is 1 to signify that some event
+was processed (see below for other alternatives).
+.PP
+If the \fIflags\fR argument to \fBTcl_DoOneEvent\fR is non-zero,
+it restricts the kinds of events that will be processed by
+\fBTcl_DoOneEvent\fR.
+\fIFlags\fR may be an OR-ed combination of any of the following bits:
+.TP 27
+\fBTCL_WINDOW_EVENTS\fR \-
+Process window system events.
+.TP 27
+\fBTCL_FILE_EVENTS\fR \-
+Process file events.
+.TP 27
+\fBTCL_TIMER_EVENTS\fR \-
+Process timer events.
+.TP 27
+\fBTCL_IDLE_EVENTS\fR \-
+Process idle callbacks.
+.TP 27
+\fBTCL_ALL_EVENTS\fR \-
+Process all kinds of events:  equivalent to OR-ing together all of the
+above flags or specifying none of them.
+.TP 27
+\fBTCL_DONT_WAIT\fR \-
+Do not sleep:  process only events that are ready at the time of the
+call.
+.LP
+If any of the flags \fBTCL_WINDOW_EVENTS\fR, \fBTCL_FILE_EVENTS\fR,
+\fBTCL_TIMER_EVENTS\fR, or \fBTCL_IDLE_EVENTS\fR is set, then the only
+events that will be considered are those for which flags are set.
+Setting none of these flags is equivalent to the value
+\fBTCL_ALL_EVENTS\fR, which causes all event types to be processed.
+If an application has defined additional event sources with
+\fBTcl_CreateEventSource\fR, then additional \fIflag\fR values
+may also be valid, depending on those event sources.
+.PP
+The \fBTCL_DONT_WAIT\fR flag causes \fBTcl_DoOneEvent\fR not to put
+the process to sleep:  it will check for events but if none are found
+then it returns immediately with a return value of 0 to indicate
+that no work was done.
+\fBTcl_DoOneEvent\fR will also return 0 without doing anything if
+the only alternative is to block forever (this can happen, for example,
+if \fIflags\fR is \fBTCL_IDLE_EVENTS\fR and there are no
+\fBTcl_DoWhenIdle\fR callbacks pending, or if no event handlers or
+timer handlers exist).
+.PP
+\fBTcl_DoOneEvent\fR may be invoked recursively.  For example,
+it is possible to invoke \fBTcl_DoOneEvent\fR recursively
+from a handler called by \fBTcl_DoOneEvent\fR.  This sort
+of operation is useful in some modal situations, such
+as when a
+notification dialog has been popped up and an application wishes to
+wait for the user to click a button in the dialog before
+doing anything else.
+
+.SH KEYWORDS
+callback, event, handler, idle, timer
diff --git a/doc/DoWhenIdle.3 b/doc/DoWhenIdle.3
new file mode 100644
index 0000000..3e28b4d
--- /dev/null
+++ b/doc/DoWhenIdle.3
@@ -0,0 +1,87 @@
+'\"
+'\" Copyright (c) 1990 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\" 
+.TH Tcl_DoWhenIdle 3 7.5 Tcl "Tcl Library Procedures"
+.so man.macros
+.BS
+.SH NAME
+Tcl_DoWhenIdle, Tcl_CancelIdleCall \- invoke a procedure when there are no pending events
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+\fBTcl_DoWhenIdle\fR(\fIproc, clientData\fR)
+.sp
+\fBTcl_CancelIdleCall\fR(\fIproc, clientData\fR)
+.SH ARGUMENTS
+.AS Tcl_IdleProc clientData
+.AP Tcl_IdleProc *proc in
+Procedure to invoke.
+.AP ClientData clientData in
+Arbitrary one-word value to pass to \fIproc\fR.
+.BE
+.SH DESCRIPTION
+.PP
+\fBTcl_DoWhenIdle\fR arranges for \fIproc\fR to be invoked
+when the application becomes idle.  The application is
+considered to be idle when \fBTcl_DoOneEvent\fR has been
+called, could not find any events to handle, and is about
+to go to sleep waiting for an event to occur.  At this
+point all pending \fBTcl_DoWhenIdle\fR handlers are
+invoked.  For each call to \fBTcl_DoWhenIdle\fR there will
+be a single call to \fIproc\fR;  after \fIproc\fR is
+invoked the handler is automatically removed.
+\fBTcl_DoWhenIdle\fR is only usable in programs that
+use \fBTcl_DoOneEvent\fR to dispatch events.
+.PP
+\fIProc\fR should have arguments and result that match the
+type \fBTcl_IdleProc\fR:
+.PP
+.CS
+typedef void \fBTcl_IdleProc\fR(
+        ClientData \fIclientData\fR);
+.CE
+.PP
+The \fIclientData\fR parameter to \fIproc\fR is a copy of the \fIclientData\fR
+argument given to \fBTcl_DoWhenIdle\fR.  Typically, \fIclientData\fR
+points to a data structure containing application-specific information about
+what \fIproc\fR should do.
+.PP
+\fBTcl_CancelIdleCall\fR
+may be used to cancel one or more previous
+calls to \fBTcl_DoWhenIdle\fR:  if there is a \fBTcl_DoWhenIdle\fR
+handler registered for \fIproc\fR and \fIclientData\fR, then it
+is removed without invoking it.  If there is more than one
+handler on the idle list that refers to \fIproc\fR and \fIclientData\fR,
+all of the handlers are removed.  If no existing handlers match
+\fIproc\fR and \fIclientData\fR then nothing happens.
+.PP
+\fBTcl_DoWhenIdle\fR is most useful in situations where
+(a) a piece of work will have to be done but (b) it is
+possible that something will happen in the near future
+that will change what has to be done or require something
+different to be done.  \fBTcl_DoWhenIdle\fR allows the
+actual work to be deferred until all pending events have
+been processed.  At this point the exact work to be done
+will presumably be known and it can be done exactly once.
+.PP
+For example, \fBTcl_DoWhenIdle\fR might be used by an editor
+to defer display updates until all pending commands have
+been processed.  Without this feature, redundant redisplays
+might occur in some situations, such as the processing of
+a command file.
+.SH BUGS
+.PP
+At present it is not safe for an idle callback to reschedule itself
+continuously.  This will interact badly with certain features of Tk
+that attempt to wait for all idle callbacks to complete.  If you would
+like for an idle callback to reschedule itself continuously, it is
+better to use a timer handler with a zero timeout period.
+.SH "SEE ALSO"
+after(n), Tcl_CreateFileHandler(3), Tcl_CreateTimerHandler(3)
+.SH KEYWORDS
+callback, defer, idle callback
diff --git a/doc/DoubleObj.3 b/doc/DoubleObj.3
new file mode 100644
index 0000000..85e4de5
--- /dev/null
+++ b/doc/DoubleObj.3
@@ -0,0 +1,64 @@
+'\"
+'\" Copyright (c) 1996-1997 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH Tcl_DoubleObj 3 8.0 Tcl "Tcl Library Procedures"
+.so man.macros
+.BS
+.SH NAME
+Tcl_NewDoubleObj, Tcl_SetDoubleObj, Tcl_GetDoubleFromObj \- manipulate Tcl values as floating-point values
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+Tcl_Obj *
+\fBTcl_NewDoubleObj\fR(\fIdoubleValue\fR)
+.sp
+\fBTcl_SetDoubleObj\fR(\fIobjPtr, doubleValue\fR)
+.sp
+int
+\fBTcl_GetDoubleFromObj\fR(\fIinterp, objPtr, doublePtr\fR)
+.SH ARGUMENTS
+.AS Tcl_Interp doubleValue in/out
+.AP double doubleValue in
+A double-precision floating-point value used to initialize or set a Tcl value.
+.AP Tcl_Obj *objPtr in/out
+For \fBTcl_SetDoubleObj\fR, this points to the value in which to store a
+double value.
+For \fBTcl_GetDoubleFromObj\fR, this refers to the value
+from which to retrieve a double value.
+.AP Tcl_Interp *interp in/out
+When non-NULL, an error message is left here when double value retrieval fails.
+.AP double *doublePtr out
+Points to place to store the double value obtained from \fIobjPtr\fR.
+.BE
+
+.SH DESCRIPTION
+.PP
+These procedures are used to create, modify, and read Tcl values that
+hold double-precision floating-point values.
+.PP
+\fBTcl_NewDoubleObj\fR creates and returns a new Tcl value initialized to
+the double value \fIdoubleValue\fR.  The returned Tcl value is unshared.
+.PP
+\fBTcl_SetDoubleObj\fR sets the value of an existing Tcl value pointed to
+by \fIobjPtr\fR to the double value \fIdoubleValue\fR.  The \fIobjPtr\fR
+argument must point to an unshared Tcl value.  Any attempt to set the value
+of a shared Tcl value violates Tcl's copy-on-write policy.  Any existing
+string representation or internal representation in the unshared Tcl value
+will be freed as a consequence of setting the new value.
+.PP
+\fBTcl_GetDoubleFromObj\fR attempts to retrieve a double value from the
+Tcl value \fIobjPtr\fR.  If the attempt succeeds, then \fBTCL_OK\fR is
+returned, and the double value is written to the storage pointed to by
+\fIdoublePtr\fR.  If the attempt fails, then \fBTCL_ERROR\fR is returned,
+and if \fIinterp\fR is non-NULL, an error message is left in \fIinterp\fR.
+The \fBTcl_ObjType\fR of \fIobjPtr\fR may be changed to make subsequent
+calls to \fBTcl_GetDoubleFromObj\fR more efficient.
+'\" TODO: add discussion of treatment of NaN value
+.SH "SEE ALSO"
+Tcl_NewObj, Tcl_DecrRefCount, Tcl_IncrRefCount, Tcl_GetObjResult
+.SH KEYWORDS
+double, double value, double type, internal representation, value, value type, string representation
diff --git a/doc/DumpActiveMemory.3 b/doc/DumpActiveMemory.3
new file mode 100644
index 0000000..43333da
--- /dev/null
+++ b/doc/DumpActiveMemory.3
@@ -0,0 +1,68 @@
+'\"
+'\" Copyright (c) 1992-1999 Karl Lehenbauer and Mark Diekhans.
+'\" Copyright (c) 2000 by Scriptics Corporation.
+'\" All rights reserved.
+'\"
+.TH "Tcl_DumpActiveMemory" 3 8.1 Tcl "Tcl Library Procedures"
+.so man.macros
+.BS
+.SH NAME
+Tcl_DumpActiveMemory, Tcl_InitMemory, Tcl_ValidateAllMemory \- Validated memory allocation interface
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+int
+\fBTcl_DumpActiveMemory\fR(\fIfileName\fR)
+.sp
+void
+\fBTcl_InitMemory\fR(\fIinterp\fR)
+.sp
+void
+\fBTcl_ValidateAllMemory\fR(\fIfileName, line\fR)
+
+.SH ARGUMENTS
+.AS Tcl_Interp *fileName
+.AP Tcl_Interp *interp in
+Tcl interpreter in which to add commands.
+.AP "const char" *fileName in
+For \fBTcl_DumpActiveMemory\fR, name of the file to which memory
+information will be written.  For \fBTcl_ValidateAllMemory\fR, name of
+the file from which the call is being made (normally \fB__FILE__\fR).
+.AP int line in
+Line number at which the call to \fBTcl_ValidateAllMemory\fR is made
+(normally \fB__LINE__\fR).
+.BE
+
+.SH DESCRIPTION
+These functions provide access to Tcl memory debugging information.
+They are only functional when Tcl has been compiled with
+\fBTCL_MEM_DEBUG\fR defined at compile-time.  When \fBTCL_MEM_DEBUG\fR
+is not defined, these functions are all no-ops.
+.PP
+\fBTcl_DumpActiveMemory\fR will output a list of all currently
+allocated memory to the specified file.  The information output for
+each allocated block of memory is:  starting and ending addresses
+(excluding guard zone), size, source file where \fBckalloc\fR was
+called to allocate the block and line number in that file.  It is
+especially useful to call \fBTcl_DumpActiveMemory\fR after the Tcl
+interpreter has been deleted.
+.PP
+\fBTcl_InitMemory\fR adds the Tcl \fBmemory\fR command to the
+interpreter given by \fIinterp\fR.  \fBTcl_InitMemory\fR is called
+by \fBTcl_Main\fR.
+.PP
+\fBTcl_ValidateAllMemory\fR forces a validation of the guard zones of
+all currently allocated blocks of memory.  Normally validation of a
+block occurs when its freed, unless full validation is enabled, in
+which case validation of all blocks occurs when \fBckalloc\fR and
+\fBckfree\fR are called.  This function forces the validation to occur
+at any point.
+
+.SH "SEE ALSO"
+TCL_MEM_DEBUG, memory
+
+.SH KEYWORDS
+memory, debug
+
+
diff --git a/doc/Encoding.3 b/doc/Encoding.3
new file mode 100644
index 0000000..81ef508
--- /dev/null
+++ b/doc/Encoding.3
@@ -0,0 +1,558 @@
+'\"
+'\" Copyright (c) 1997-1998 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH Tcl_GetEncoding 3 "8.1" Tcl "Tcl Library Procedures"
+.so man.macros
+.BS
+.SH NAME
+Tcl_GetEncoding, Tcl_FreeEncoding, Tcl_GetEncodingFromObj, Tcl_ExternalToUtfDString, Tcl_ExternalToUtf, Tcl_UtfToExternalDString, Tcl_UtfToExternal, Tcl_WinTCharToUtf, Tcl_WinUtfToTChar, Tcl_GetEncodingName, Tcl_SetSystemEncoding, Tcl_GetEncodingNameFromEnvironment, Tcl_GetEncodingNames, Tcl_CreateEncoding, Tcl_GetEncodingSearchPath, Tcl_SetEncodingSearchPath, Tcl_GetDefaultEncodingDir, Tcl_SetDefaultEncodingDir \- procedures for creating and using encodings
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+Tcl_Encoding
+\fBTcl_GetEncoding\fR(\fIinterp, name\fR)
+.sp
+void
+\fBTcl_FreeEncoding\fR(\fIencoding\fR)
+.sp
+int
+\fBTcl_GetEncodingFromObj\fR(\fIinterp, objPtr, encodingPtr\fR)
+.sp
+char *
+\fBTcl_ExternalToUtfDString\fR(\fIencoding, src, srcLen, dstPtr\fR)
+.sp
+char *
+\fBTcl_UtfToExternalDString\fR(\fIencoding, src, srcLen, dstPtr\fR)
+.sp
+int
+\fBTcl_ExternalToUtf\fR(\fIinterp, encoding, src, srcLen, flags, statePtr,
+                  dst, dstLen, srcReadPtr, dstWrotePtr, dstCharsPtr\fR)
+.sp
+int
+\fBTcl_UtfToExternal\fR(\fIinterp, encoding, src, srcLen, flags, statePtr,
+                  dst, dstLen, srcReadPtr, dstWrotePtr, dstCharsPtr\fR)
+.sp
+char *
+\fBTcl_WinTCharToUtf\fR(\fItsrc, srcLen, dstPtr\fR)
+.sp
+TCHAR *
+\fBTcl_WinUtfToTChar\fR(\fIsrc, srcLen, dstPtr\fR)
+.sp
+const char *
+\fBTcl_GetEncodingName\fR(\fIencoding\fR)
+.sp
+int
+\fBTcl_SetSystemEncoding\fR(\fIinterp, name\fR)
+.sp
+const char *
+\fBTcl_GetEncodingNameFromEnvironment\fR(\fIbufPtr\fR)
+.sp
+void
+\fBTcl_GetEncodingNames\fR(\fIinterp\fR)
+.sp
+Tcl_Encoding
+\fBTcl_CreateEncoding\fR(\fItypePtr\fR)
+.sp
+Tcl_Obj *
+\fBTcl_GetEncodingSearchPath\fR()
+.sp
+int
+\fBTcl_SetEncodingSearchPath\fR(\fIsearchPath\fR)
+.sp
+const char *
+\fBTcl_GetDefaultEncodingDir\fR(\fIvoid\fR)
+.sp
+void
+\fBTcl_SetDefaultEncodingDir\fR(\fIpath\fR)
+.SH ARGUMENTS
+.AS "const Tcl_EncodingType" *dstWrotePtr in/out
+.AP Tcl_Interp *interp in
+Interpreter to use for error reporting, or NULL if no error reporting is
+desired.
+.AP "const char" *name in
+Name of encoding to load.
+.AP Tcl_Encoding encoding in
+The encoding to query, free, or use for converting text.  If \fIencoding\fR is
+NULL, the current system encoding is used.
+.AP Tcl_Obj *objPtr in
+Name of encoding to get token for.
+.AP Tcl_Encoding *encodingPtr out
+Points to storage where encoding token is to be written.
+.AP "const char" *src in
+For the \fBTcl_ExternalToUtf\fR functions, an array of bytes in the
+specified encoding that are to be converted to UTF-8.  For the
+\fBTcl_UtfToExternal\fR and \fBTcl_WinUtfToTChar\fR functions, an array of
+UTF-8 characters to be converted to the specified encoding.
+.AP "const TCHAR" *tsrc in
+An array of Windows TCHAR characters to convert to UTF-8.
+.AP int srcLen in
+Length of \fIsrc\fR or \fItsrc\fR in bytes.  If the length is negative, the
+encoding-specific length of the string is used.
+.AP Tcl_DString *dstPtr out
+Pointer to an uninitialized or free \fBTcl_DString\fR in which the converted
+result will be stored.
+.AP int flags in
+Various flag bits OR-ed together.
+\fBTCL_ENCODING_START\fR signifies that the
+source buffer is the first block in a (potentially multi-block) input
+stream, telling the conversion routine to reset to an initial state and
+perform any initialization that needs to occur before the first byte is
+converted. \fBTCL_ENCODING_END\fR signifies that the source buffer is the last
+block in a (potentially multi-block) input stream, telling the conversion
+routine to perform any finalization that needs to occur after the last
+byte is converted and then to reset to an initial state.
+\fBTCL_ENCODING_STOPONERROR\fR signifies that the conversion routine should
+return immediately upon reading a source character that does not exist in
+the target encoding; otherwise a default fallback character will
+automatically be substituted.
+.AP Tcl_EncodingState *statePtr in/out
+Used when converting a (generally long or indefinite length) byte stream
+in a piece-by-piece fashion.  The conversion routine stores its current
+state in \fI*statePtr\fR after \fIsrc\fR (the buffer containing the
+current piece) has been converted; that state information must be passed
+back when converting the next piece of the stream so the conversion
+routine knows what state it was in when it left off at the end of the
+last piece.  May be NULL, in which case the value specified for \fIflags\fR
+is ignored and the source buffer is assumed to contain the complete string to
+convert.
+.AP char *dst out
+Buffer in which the converted result will be stored.  No more than
+\fIdstLen\fR bytes will be stored in \fIdst\fR.
+.AP int dstLen in
+The maximum length of the output buffer \fIdst\fR in bytes.
+.AP int *srcReadPtr out
+Filled with the number of bytes from \fIsrc\fR that were actually
+converted.  This may be less than the original source length if there was
+a problem converting some source characters.  May be NULL.
+.AP int *dstWrotePtr out
+Filled with the number of bytes that were actually stored in the output
+buffer as a result of the conversion.  May be NULL.
+.AP int *dstCharsPtr out
+Filled with the number of characters that correspond to the number of bytes
+stored in the output buffer.  May be NULL.
+.AP Tcl_DString *bufPtr out
+Storage for the prescribed system encoding name.
+.AP "const Tcl_EncodingType" *typePtr in
+Structure that defines a new type of encoding.
+.AP Tcl_Obj *searchPath in
+List of filesystem directories in which to search for encoding data files.
+.AP "const char" *path in
+A path to the location of the encoding file.
+.BE
+.SH INTRODUCTION
+.PP
+These routines convert between Tcl's internal character representation,
+UTF-8, and character representations used by various operating systems or
+file systems, such as Unicode, ASCII, or Shift-JIS.  When operating on
+strings, such as such as obtaining the names of files or displaying
+characters using international fonts, the strings must be translated into
+one or possibly multiple formats that the various system calls can use.  For
+instance, on a Japanese Unix workstation, a user might obtain a filename
+represented in the EUC-JP file encoding and then translate the characters to
+the jisx0208 font encoding in order to display the filename in a Tk widget.
+The purpose of the encoding package is to help bridge the translation gap.
+UTF-8 provides an intermediate staging ground for all the various
+encodings.  In the example above, text would be translated into UTF-8 from
+whatever file encoding the operating system is using.  Then it would be
+translated from UTF-8 into whatever font encoding the display routines
+require.
+.PP
+Some basic encodings are compiled into Tcl.  Others can be defined by the
+user or dynamically loaded from encoding files in a
+platform-independent manner.
+.SH DESCRIPTION
+.PP
+\fBTcl_GetEncoding\fR finds an encoding given its \fIname\fR.  The name may
+refer to a built-in Tcl encoding, a user-defined encoding registered by
+calling \fBTcl_CreateEncoding\fR, or a dynamically-loadable encoding
+file.  The return value is a token that represents the encoding and can be
+used in subsequent calls to procedures such as \fBTcl_GetEncodingName\fR,
+\fBTcl_FreeEncoding\fR, and \fBTcl_UtfToExternal\fR.  If the name did not
+refer to any known or loadable encoding, NULL is returned and an error
+message is returned in \fIinterp\fR.
+.PP
+The encoding package maintains a database of all encodings currently in use.
+The first time \fIname\fR is seen, \fBTcl_GetEncoding\fR returns an
+encoding with a reference count of 1.  If the same \fIname\fR is requested
+further times, then the reference count for that encoding is incremented
+without the overhead of allocating a new encoding and all its associated
+data structures.
+.PP
+When an \fIencoding\fR is no longer needed, \fBTcl_FreeEncoding\fR
+should be called to release it.  When an \fIencoding\fR is no longer in use
+anywhere (i.e., it has been freed as many times as it has been gotten)
+\fBTcl_FreeEncoding\fR will release all storage the encoding was using
+and delete it from the database.
+.PP
+\fBTcl_GetEncodingFromObj\fR treats the string representation of
+\fIobjPtr\fR as an encoding name, and finds an encoding with that
+name, just as \fBTcl_GetEncoding\fR does. When an encoding is found,
+it is cached within the \fBobjPtr\fR value for future reference, the
+\fBTcl_Encoding\fR token is written to the storage pointed to by
+\fIencodingPtr\fR, and the value \fBTCL_OK\fR is returned. If no such
+encoding is found, the value \fBTCL_ERROR\fR is returned, and no
+writing to \fB*\fR\fIencodingPtr\fR takes place. Just as with
+\fBTcl_GetEncoding\fR, the caller should call \fBTcl_FreeEncoding\fR
+on the resulting encoding token when that token will no longer be
+used.
+.PP
+\fBTcl_ExternalToUtfDString\fR converts a source buffer \fIsrc\fR from the
+specified \fIencoding\fR into UTF-8.  The converted bytes are stored in
+\fIdstPtr\fR, which is then null-terminated.  The caller should eventually
+call \fBTcl_DStringFree\fR to free any information stored in \fIdstPtr\fR.
+When converting, if any of the characters in the source buffer cannot be
+represented in the target encoding, a default fallback character will be
+used.  The return value is a pointer to the value stored in the DString.
+.PP
+\fBTcl_ExternalToUtf\fR converts a source buffer \fIsrc\fR from the specified
+\fIencoding\fR into UTF-8.  Up to \fIsrcLen\fR bytes are converted from the
+source buffer and up to \fIdstLen\fR converted bytes are stored in \fIdst\fR.
+In all cases, \fI*srcReadPtr\fR is filled with the number of bytes that were
+successfully converted from \fIsrc\fR and \fI*dstWrotePtr\fR is filled with
+the corresponding number of bytes that were stored in \fIdst\fR.  The return
+value is one of the following:
+.RS
+.IP \fBTCL_OK\fR 29
+All bytes of \fIsrc\fR were converted.
+.IP \fBTCL_CONVERT_NOSPACE\fR 29
+The destination buffer was not large enough for all of the converted data; as
+many characters as could fit were converted though.
+.IP \fBTCL_CONVERT_MULTIBYTE\fR 29
+The last few bytes in the source buffer were the beginning of a multibyte
+sequence, but more bytes were needed to complete this sequence.  A
+subsequent call to the conversion routine should pass a buffer containing
+the unconverted bytes that remained in \fIsrc\fR plus some further bytes
+from the source stream to properly convert the formerly split-up multibyte
+sequence.
+.IP \fBTCL_CONVERT_SYNTAX\fR 29
+The source buffer contained an invalid character sequence.  This may occur
+if the input stream has been damaged or if the input encoding method was
+misidentified.
+.IP \fBTCL_CONVERT_UNKNOWN\fR 29
+The source buffer contained a character that could not be represented in
+the target encoding and \fBTCL_ENCODING_STOPONERROR\fR was specified.
+.RE
+.LP
+\fBTcl_UtfToExternalDString\fR converts a source buffer \fIsrc\fR from UTF-8
+into the specified \fIencoding\fR.  The converted bytes are stored in
+\fIdstPtr\fR, which is then terminated with the appropriate encoding-specific
+null.  The caller should eventually call \fBTcl_DStringFree\fR to free any
+information stored in \fIdstPtr\fR.  When converting, if any of the
+characters in the source buffer cannot be represented in the target
+encoding, a default fallback character will be used.  The return value is
+a pointer to the value stored in the DString.
+.PP
+\fBTcl_UtfToExternal\fR converts a source buffer \fIsrc\fR from UTF-8 into
+the specified \fIencoding\fR.  Up to \fIsrcLen\fR bytes are converted from
+the source buffer and up to \fIdstLen\fR converted bytes are stored in
+\fIdst\fR.  In all cases, \fI*srcReadPtr\fR is filled with the number of
+bytes that were successfully converted from \fIsrc\fR and \fI*dstWrotePtr\fR
+is filled with the corresponding number of bytes that were stored in
+\fIdst\fR.  The return values are the same as the return values for
+\fBTcl_ExternalToUtf\fR.
+.PP
+\fBTcl_WinUtfToTChar\fR and \fBTcl_WinTCharToUtf\fR are
+Windows-only convenience
+functions for converting between UTF-8 and Windows strings
+based on the TCHAR type which is by convention
+a Unicode character on Windows NT.
+These functions are essentially wrappers around
+\fBTcl_UtfToExternalDString\fR and
+\fBTcl_ExternalToUtfDString\fR that convert to and from the
+Unicode encoding.
+.PP
+\fBTcl_GetEncodingName\fR is roughly the inverse of \fBTcl_GetEncoding\fR.
+Given an \fIencoding\fR, the return value is the \fIname\fR argument that
+was used to create the encoding.  The string returned by
+\fBTcl_GetEncodingName\fR is only guaranteed to persist until the
+\fIencoding\fR is deleted.  The caller must not modify this string.
+.PP
+\fBTcl_SetSystemEncoding\fR sets the default encoding that should be used
+whenever the user passes a NULL value for the \fIencoding\fR argument to
+any of the other encoding functions.  If \fIname\fR is NULL, the system
+encoding is reset to the default system encoding, \fBbinary\fR.  If the
+name did not refer to any known or loadable encoding, \fBTCL_ERROR\fR is
+returned and an error message is left in \fIinterp\fR.  Otherwise, this
+procedure increments the reference count of the new system encoding,
+decrements the reference count of the old system encoding, and returns
+\fBTCL_OK\fR.
+.PP
+\fBTcl_GetEncodingNameFromEnvironment\fR provides a means for the Tcl
+library to report the encoding name it believes to be the correct one
+to use as the system encoding, based on system calls and examination of
+the environment suitable for the platform.  It accepts \fIbufPtr\fR,
+a pointer to an uninitialized or freed \fBTcl_DString\fR and writes
+the encoding name to it.  The \fBTcl_DStringValue\fR is returned.
+.PP
+\fBTcl_GetEncodingNames\fR sets the \fIinterp\fR result to a list
+consisting of the names of all the encodings that are currently defined
+or can be dynamically loaded, searching the encoding path specified by
+\fBTcl_SetDefaultEncodingDir\fR.  This procedure does not ensure that the
+dynamically-loadable encoding files contain valid data, but merely that they
+exist.
+.PP
+\fBTcl_CreateEncoding\fR defines a new encoding and registers the C
+procedures that are called back to convert between the encoding and
+UTF-8.  Encodings created by \fBTcl_CreateEncoding\fR are thereafter
+visible in the database used by \fBTcl_GetEncoding\fR.  Just as with the
+\fBTcl_GetEncoding\fR procedure, the return value is a token that
+represents the encoding and can be used in subsequent calls to other
+encoding functions.  \fBTcl_CreateEncoding\fR returns an encoding with a
+reference count of 1. If an encoding with the specified \fIname\fR
+already exists, then its entry in the database is replaced with the new
+encoding; the token for the old encoding will remain valid and continue
+to behave as before, but users of the new token will now call the new
+encoding procedures.
+.PP
+The \fItypePtr\fR argument to \fBTcl_CreateEncoding\fR contains information
+about the name of the encoding and the procedures that will be called to
+convert between this encoding and UTF-8.  It is defined as follows:
+.PP
+.CS
+typedef struct Tcl_EncodingType {
+    const char *\fIencodingName\fR;
+    Tcl_EncodingConvertProc *\fItoUtfProc\fR;
+    Tcl_EncodingConvertProc *\fIfromUtfProc\fR;
+    Tcl_EncodingFreeProc *\fIfreeProc\fR;
+    ClientData \fIclientData\fR;
+    int \fInullSize\fR;
+} \fBTcl_EncodingType\fR;
+.CE
+.PP
+The \fIencodingName\fR provides a string name for the encoding, by
+which it can be referred in other procedures such as
+\fBTcl_GetEncoding\fR.  The \fItoUtfProc\fR refers to a callback
+procedure to invoke to convert text from this encoding into UTF-8.
+The \fIfromUtfProc\fR refers to a callback procedure to invoke to
+convert text from UTF-8 into this encoding.  The \fIfreeProc\fR refers
+to a callback procedure to invoke when this encoding is deleted.  The
+\fIfreeProc\fR field may be NULL.  The \fIclientData\fR contains an
+arbitrary one-word value passed to \fItoUtfProc\fR, \fIfromUtfProc\fR,
+and \fIfreeProc\fR whenever they are called.  Typically, this is a
+pointer to a data structure containing encoding-specific information
+that can be used by the callback procedures.  For instance, two very
+similar encodings such as \fBascii\fR and \fBmacRoman\fR may use the
+same callback procedure, but use different values of \fIclientData\fR
+to control its behavior.  The \fInullSize\fR specifies the number of
+zero bytes that signify end-of-string in this encoding.  It must be
+\fB1\fR (for single-byte or multi-byte encodings like ASCII or
+Shift-JIS) or \fB2\fR (for double-byte encodings like Unicode).
+Constant-sized encodings with 3 or more bytes per character (such as
+CNS11643) are not accepted.
+.PP
+The callback procedures \fItoUtfProc\fR and \fIfromUtfProc\fR should match the
+type \fBTcl_EncodingConvertProc\fR:
+.PP
+.CS
+typedef int \fBTcl_EncodingConvertProc\fR(
+        ClientData \fIclientData\fR,
+        const char *\fIsrc\fR,
+        int \fIsrcLen\fR,
+        int \fIflags\fR,
+        Tcl_EncodingState *\fIstatePtr\fR,
+        char *\fIdst\fR,
+        int \fIdstLen\fR,
+        int *\fIsrcReadPtr\fR,
+        int *\fIdstWrotePtr\fR,
+        int *\fIdstCharsPtr\fR);
+.CE
+.PP
+The \fItoUtfProc\fR and \fIfromUtfProc\fR procedures are called by the
+\fBTcl_ExternalToUtf\fR or \fBTcl_UtfToExternal\fR family of functions to
+perform the actual conversion.  The \fIclientData\fR parameter to these
+procedures is the same as the \fIclientData\fR field specified to
+\fBTcl_CreateEncoding\fR when the encoding was created.  The remaining
+arguments to the callback procedures are the same as the arguments,
+documented at the top, to \fBTcl_ExternalToUtf\fR or
+\fBTcl_UtfToExternal\fR, with the following exceptions.  If the
+\fIsrcLen\fR argument to one of those high-level functions is negative,
+the value passed to the callback procedure will be the appropriate
+encoding-specific string length of \fIsrc\fR.  If any of the \fIsrcReadPtr\fR,
+\fIdstWrotePtr\fR, or \fIdstCharsPtr\fR arguments to one of the high-level
+functions is NULL, the corresponding value passed to the callback
+procedure will be a non-NULL location.
+.PP
+The callback procedure \fIfreeProc\fR, if non-NULL, should match the type
+\fBTcl_EncodingFreeProc\fR:
+.PP
+.CS
+typedef void \fBTcl_EncodingFreeProc\fR(
+        ClientData \fIclientData\fR);
+.CE
+.PP
+This \fIfreeProc\fR function is called when the encoding is deleted.  The
+\fIclientData\fR parameter is the same as the \fIclientData\fR field
+specified to \fBTcl_CreateEncoding\fR when the encoding was created.
+.PP
+\fBTcl_GetEncodingSearchPath\fR and \fBTcl_SetEncodingSearchPath\fR
+are called to access and set the list of filesystem directories searched
+for encoding data files.
+.PP
+The value returned by \fBTcl_GetEncodingSearchPath\fR
+is the value stored by the last successful call to
+\fBTcl_SetEncodingSearchPath\fR.  If no calls to
+\fBTcl_SetEncodingSearchPath\fR have occurred, Tcl will compute an initial
+value based on the environment.  There is one encoding search path for the
+entire process, shared by all threads in the process.
+.PP
+\fBTcl_SetEncodingSearchPath\fR stores \fIsearchPath\fR and returns
+\fBTCL_OK\fR, unless \fIsearchPath\fR is not a valid Tcl list, which
+causes \fBTCL_ERROR\fR to be returned.  The elements of \fIsearchPath\fR
+are not verified as existing readable filesystem directories.  When
+searching for encoding data files takes place, and non-existent or
+non-readable filesystem directories on the \fIsearchPath\fR are silently
+ignored.
+.PP
+\fBTcl_GetDefaultEncodingDir\fR and \fBTcl_SetDefaultEncodingDir\fR
+are obsolete interfaces best replaced with calls to
+\fBTcl_GetEncodingSearchPath\fR and \fBTcl_SetEncodingSearchPath\fR.
+They are called to access and set the first element of the \fIsearchPath\fR
+list.  Since Tcl searches \fIsearchPath\fR for encoding data files in
+list order, these routines establish the
+.QW default
+directory in which to find encoding data files.
+.SH "ENCODING FILES"
+Space would prohibit precompiling into Tcl every possible encoding
+algorithm, so many encodings are stored on disk as dynamically-loadable
+encoding files.  This behavior also allows the user to create additional
+encoding files that can be loaded using the same mechanism.  These
+encoding files contain information about the tables and/or escape
+sequences used to map between an external encoding and Unicode.  The
+external encoding may consist of single-byte, multi-byte, or double-byte
+characters.
+.PP
+Each dynamically-loadable encoding is represented as a text file.  The
+initial line of the file, beginning with a
+.QW #
+symbol, is a comment
+that provides a human-readable description of the file.  The next line
+identifies the type of encoding file.  It can be one of the following
+letters:
+.IP "[1] \fBS\fR"
+A single-byte encoding, where one character is always one byte long in the
+encoding.  An example is \fBiso8859-1\fR, used by many European languages.
+.IP "[2] \fBD\fR"
+A double-byte encoding, where one character is always two bytes long in the
+encoding.  An example is \fBbig5\fR, used for Chinese text.
+.IP "[3] \fBM\fR"
+A multi-byte encoding, where one character may be either one or two bytes long.
+Certain bytes are lead bytes, indicating that another byte must follow
+and that together the two bytes represent one character.  Other bytes are not
+lead bytes and represent themselves.  An example is \fBshiftjis\fR, used by
+many Japanese computers.
+.IP "[4] \fBE\fR"
+An escape-sequence encoding, specifying that certain sequences of bytes
+do not represent characters, but commands that describe how following bytes
+should be interpreted.
+.PP
+The rest of the lines in the file depend on the type.
+.PP
+Cases [1], [2], and [3] are collectively referred to as table-based encoding
+files.  The lines in a table-based encoding file are in the same
+format as this example taken from the \fBshiftjis\fR encoding (this is not
+the complete file):
+.PP
+.CS
+# Encoding file: shiftjis, multi-byte
+M
+003F 0 40
+00
+0000000100020003000400050006000700080009000A000B000C000D000E000F
+0010001100120013001400150016001700180019001A001B001C001D001E001F
+0020002100220023002400250026002700280029002A002B002C002D002E002F
+0030003100320033003400350036003700380039003A003B003C003D003E003F
+0040004100420043004400450046004700480049004A004B004C004D004E004F
+0050005100520053005400550056005700580059005A005B005C005D005E005F
+0060006100620063006400650066006700680069006A006B006C006D006E006F
+0070007100720073007400750076007700780079007A007B007C007D203E007F
+0080000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000FF61FF62FF63FF64FF65FF66FF67FF68FF69FF6AFF6BFF6CFF6DFF6EFF6F
+FF70FF71FF72FF73FF74FF75FF76FF77FF78FF79FF7AFF7BFF7CFF7DFF7EFF7F
+FF80FF81FF82FF83FF84FF85FF86FF87FF88FF89FF8AFF8BFF8CFF8DFF8EFF8F
+FF90FF91FF92FF93FF94FF95FF96FF97FF98FF99FF9AFF9BFF9CFF9DFF9EFF9F
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+81
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+300030013002FF0CFF0E30FBFF1AFF1BFF1FFF01309B309C00B4FF4000A8FF3E
+FFE3FF3F30FD30FE309D309E30034EDD30053006300730FC20152010FF0F005C
+301C2016FF5C2026202520182019201C201DFF08FF0930143015FF3BFF3DFF5B
+FF5D30083009300A300B300C300D300E300F30103011FF0B221200B100D70000
+00F7FF1D2260FF1CFF1E22662267221E22342642264000B0203220332103FFE5
+FF0400A200A3FF05FF03FF06FF0AFF2000A72606260525CB25CF25CE25C725C6
+25A125A025B325B225BD25BC203B301221922190219121933013000000000000
+000000000000000000000000000000002208220B2286228722822283222A2229
+000000000000000000000000000000002227222800AC21D221D4220022030000
+0000000000000000000000000000000000000000222022A52312220222072261
+2252226A226B221A223D221D2235222B222C0000000000000000000000000000
+212B2030266F266D266A2020202100B6000000000000000025EF000000000000
+.CE
+.PP
+The third line of the file is three numbers.  The first number is the
+fallback character (in base 16) to use when converting from UTF-8 to this
+encoding.  The second number is a \fB1\fR if this file represents the
+encoding for a symbol font, or \fB0\fR otherwise.  The last number (in base
+10) is how many pages of data follow.
+.PP
+Subsequent lines in the example above are pages that describe how to map
+from the encoding into 2-byte Unicode.  The first line in a page identifies
+the page number.  Following it are 256 double-byte numbers, arranged as 16
+rows of 16 numbers.  Given a character in the encoding, the high byte of
+that character is used to select which page, and the low byte of that
+character is used as an index to select one of the double-byte numbers in
+that page \- the value obtained being the corresponding Unicode character.
+By examination of the example above, one can see that the characters 0x7E
+and 0x8163 in \fBshiftjis\fR map to 203E and 2026 in Unicode, respectively.
+.PP
+Following the first page will be all the other pages, each in the same
+format as the first: one number identifying the page followed by 256
+double-byte Unicode characters.  If a character in the encoding maps to the
+Unicode character 0000, it means that the character does not actually exist.
+If all characters on a page would map to 0000, that page can be omitted.
+.PP
+Case [4] is the escape-sequence encoding file.  The lines in an this type of
+file are in the same format as this example taken from the \fBiso2022-jp\fR
+encoding:
+.PP
+.CS
+.ta 1.5i
+# Encoding file: iso2022-jp, escape-driven
+E
+init		{}
+final		{}
+iso8859-1	\ex1b(B
+jis0201		\ex1b(J
+jis0208		\ex1b$@
+jis0208		\ex1b$B
+jis0212		\ex1b$(D
+gb2312		\ex1b$A
+ksc5601		\ex1b$(C
+.CE
+.PP
+In the file, the first column represents an option and the second column
+is the associated value.  \fBinit\fR is a string to emit or expect before
+the first character is converted, while \fBfinal\fR is a string to emit
+or expect after the last character.  All other options are names of
+table-based encodings; the associated value is the escape-sequence that
+marks that encoding.  Tcl syntax is used for the values; in the above
+example, for instance,
+.QW \fB{}\fR
+represents the empty string and
+.QW \fB\ex1b\fR
+represents character 27.
+.PP
+When \fBTcl_GetEncoding\fR encounters an encoding \fIname\fR that has not
+been loaded, it attempts to load an encoding file called \fIname\fB.enc\fR
+from the \fBencoding\fR subdirectory of each directory that Tcl searches
+for its script library.  If the encoding file exists, but is
+malformed, an error message will be left in \fIinterp\fR.
+.SH KEYWORDS
+utf, encoding, convert
diff --git a/doc/Ensemble.3 b/doc/Ensemble.3
new file mode 100644
index 0000000..30c1d3b
--- /dev/null
+++ b/doc/Ensemble.3
@@ -0,0 +1,219 @@
+'\"
+'\" Copyright (c) 2005 Donal K. Fellows
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+'\" This documents the C API introduced in TIP#235
+'\"
+.TH Tcl_Ensemble 3 8.5 Tcl "Tcl Library Procedures"
+.so man.macros
+.BS
+.SH NAME
+Tcl_CreateEnsemble, Tcl_FindEnsemble, Tcl_GetEnsembleFlags, Tcl_GetEnsembleMappingDict, Tcl_GetEnsembleNamespace, Tcl_GetEnsembleParameterList, Tcl_GetEnsembleUnknownHandler, Tcl_GetEnsembleSubcommandList, Tcl_IsEnsemble, Tcl_SetEnsembleFlags, Tcl_SetEnsembleMappingDict, Tcl_SetEnsembleParameterList, Tcl_SetEnsembleSubcommandList, Tcl_SetEnsembleUnknownHandler \- manipulate ensemble commands
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+Tcl_Command
+\fBTcl_CreateEnsemble\fR(\fIinterp, name, namespacePtr, ensFlags\fR)
+.sp
+Tcl_Command
+\fBTcl_FindEnsemble\fR(\fIinterp, cmdNameObj, flags\fR)
+.sp
+int
+\fBTcl_IsEnsemble\fR(\fItoken\fR)
+.sp
+int
+\fBTcl_GetEnsembleFlags\fR(\fIinterp, token, ensFlagsPtr\fR)
+.sp
+int
+\fBTcl_SetEnsembleFlags\fR(\fIinterp, token, ensFlags\fR)
+.sp
+int
+\fBTcl_GetEnsembleMappingDict\fR(\fIinterp, token, dictObjPtr\fR)
+.sp
+int
+\fBTcl_SetEnsembleMappingDict\fR(\fIinterp, token, dictObj\fR)
+.sp
+.VS 8.6
+int
+\fBTcl_GetEnsembleParameterList\fR(\fIinterp, token, listObjPtr\fR)
+.sp
+int
+\fBTcl_SetEnsembleParameterList\fR(\fIinterp, token, listObj\fR)
+.VE 8.6
+.sp
+int
+\fBTcl_GetEnsembleSubcommandList\fR(\fIinterp, token, listObjPtr\fR)
+.sp
+int
+\fBTcl_SetEnsembleSubcommandList\fR(\fIinterp, token, listObj\fR)
+.sp
+int
+\fBTcl_GetEnsembleUnknownHandler\fR(\fIinterp, token, listObjPtr\fR)
+.sp
+int
+\fBTcl_SetEnsembleUnknownHandler\fR(\fIinterp, token, listObj\fR)
+.sp
+int
+\fBTcl_GetEnsembleNamespace\fR(\fIinterp, token, namespacePtrPtr\fR)
+.SH ARGUMENTS
+.AS Tcl_Namespace **namespacePtrPtr in/out
+.AP Tcl_Interp *interp in/out
+The interpreter in which the ensemble is to be created or found. Also
+where error result messages are written. The functions whose names
+start with \fBTcl_GetEnsemble\fR may have a NULL for the \fIinterp\fR,
+but all other functions must not.
+.AP "const char" *name in
+The name of the ensemble command to be created.
+.AP Tcl_Namespace *namespacePtr in
+The namespace to which the ensemble command is to be bound, or NULL
+for the current namespace.
+.AP int ensFlags in
+An ORed set of flag bits describing the basic configuration of the
+ensemble. Currently only one bit has meaning, \fBTCL_ENSEMBLE_PREFIX\fR,
+which is present when the ensemble command should also match
+unambiguous prefixes of subcommands.
+.AP Tcl_Obj *cmdNameObj in
+A value holding the name of the ensemble command to look up.
+.AP int flags in
+An ORed set of flag bits controlling the behavior of
+\fBTcl_FindEnsemble\fR. Currently only \fBTCL_LEAVE_ERR_MSG\fR is supported.
+.AP Tcl_Command token in
+A normal command token that refers to an ensemble command, or which
+you wish to use for testing as an ensemble command in \fBTcl_IsEnsemble\fR.
+.AP int *ensFlagsPtr out
+Pointer to a variable into which to write the current ensemble flag
+bits; currently only the bit \fBTCL_ENSEMBLE_PREFIX\fR is defined.
+.AP Tcl_Obj *dictObj in
+A dictionary value to use for the subcommand to implementation command
+prefix mapping dictionary in the ensemble. May be NULL if the mapping
+dictionary is to be removed.
+.AP Tcl_Obj **dictObjPtr out
+Pointer to a variable into which to write the current ensemble mapping
+dictionary.
+.AP Tcl_Obj *listObj in
+A list value to use for the list of formal pre-subcommand parameters, the
+defined list of subcommands in the dictionary or the unknown subcommand
+handler command prefix. May be NULL if the subcommand list or unknown handler
+are to be removed.
+.AP Tcl_Obj **listObjPtr out
+Pointer to a variable into which to write the current list of formal
+pre-subcommand parameters, the defined list of subcommands or the current
+unknown handler prefix.
+.AP Tcl_Namespace **namespacePtrPtr out
+Pointer to a variable into which to write the handle of the namespace
+to which the ensemble is bound.
+.BE
+.SH DESCRIPTION
+An ensemble is a command, bound to some namespace, which consists of a
+collection of subcommands implemented by other Tcl commands. The first
+argument to the ensemble command is always interpreted as a selector
+that states what subcommand to execute.
+.PP
+Ensembles are created using \fBTcl_CreateEnsemble\fR, which takes four
+arguments: the interpreter to work within, the name of the ensemble to
+create, the namespace within the interpreter to bind the ensemble to,
+and the default set of ensemble flags. The result of the function is
+the command token for the ensemble, which may be used to further
+configure the ensemble using the API described below in
+\fBENSEMBLE PROPERTIES\fR.
+.PP
+Given the name of an ensemble command, the token for that command may
+be retrieved using \fBTcl_FindEnsemble\fR. If the given command name
+(in \fIcmdNameObj\fR) does not refer to an ensemble command, the
+result of the function is NULL and (if the \fBTCL_LEAVE_ERR_MSG\fR bit is
+set in \fIflags\fR) an error message is left in the interpreter
+result.
+.PP
+A command token may be checked to see if it refers to an ensemble
+using \fBTcl_IsEnsemble\fR. This returns 1 if the token refers to an
+ensemble, or 0 otherwise.
+.SS "ENSEMBLE PROPERTIES"
+Every ensemble has four read-write properties and a read-only
+property. The properties are:
+.TP
+\fBflags\fR (read-write)
+.
+The set of flags for the ensemble, expressed as a
+bit-field. Currently, the only public flag is \fBTCL_ENSEMBLE_PREFIX\fR
+which is set when unambiguous prefixes of subcommands are permitted to
+be resolved to implementations as well as exact matches. The flags may
+be read and written using \fBTcl_GetEnsembleFlags\fR and
+\fBTcl_SetEnsembleFlags\fR respectively. The result of both of those
+functions is a Tcl result code (\fBTCL_OK\fR, or \fBTCL_ERROR\fR if
+the token does not refer to an ensemble).
+.TP
+\fBmapping dictionary\fR (read-write)
+.
+A dictionary containing a mapping from subcommand names to lists of
+words to use as a command prefix (replacing the first two words of the
+command which are the ensemble command itself and the subcommand
+name), or NULL if every subcommand is to be mapped to the command with
+the same unqualified name in the ensemble's bound namespace. Defaults
+to NULL. May be read and written using
+\fBTcl_GetEnsembleMappingDict\fR and \fBTcl_SetEnsembleMappingDict\fR
+respectively. The result of both of those functions is a Tcl result
+code (\fBTCL_OK\fR, or \fBTCL_ERROR\fR if the token does not refer to an
+ensemble) and the dictionary obtained from
+\fBTcl_GetEnsembleMappingDict\fR should always be treated as immutable
+even if it is unshared.
+All command names in prefixes set via \fBTcl_SetEnsembleMappingDict\fR
+must be fully qualified.
+.TP
+\fBformal pre-subcommand parameter list\fR (read-write)
+.VS 8.6
+A list of formal parameter names (the names only being used when generating
+error messages) that come at invocation of the ensemble between the name of
+the ensemble and the subcommand argument. NULL (the default) is equivalent to
+the empty list. May be read and written using
+\fBTcl_GetEnsembleParameterList\fR and \fBTcl_SetEnsembleParameterList\fR
+respectively. The result of both of those functions is a Tcl result code
+(\fBTCL_OK\fR, or \fBTCL_ERROR\fR if the token does not refer to an
+ensemble) and the
+dictionary obtained from \fBTcl_GetEnsembleParameterList\fR should always be
+treated as immutable even if it is unshared.
+.VE 8.6
+.TP
+\fBsubcommand list\fR (read-write)
+.
+A list of all the subcommand names for the ensemble, or NULL if this
+is to be derived from either the keys of the mapping dictionary (see
+above) or (if that is also NULL) from the set of commands exported by
+the bound namespace. May be read and written using
+\fBTcl_GetEnsembleSubcommandList\fR and
+\fBTcl_SetEnsembleSubcommandList\fR respectively. The result of both
+of those functions is a Tcl result code (\fBTCL_OK\fR, or
+\fBTCL_ERROR\fR if the
+token does not refer to an ensemble) and the list obtained from
+\fBTcl_GetEnsembleSubcommandList\fR should always be treated as
+immutable even if it is unshared.
+.TP
+\fBunknown subcommand handler command prefix\fR (read-write)
+.
+A list of words to prepend on the front of any subcommand when the
+subcommand is unknown to the ensemble (according to the current prefix
+handling rule); see the \fBnamespace ensemble\fR command for more
+details. If NULL, the default behavior \- generate a suitable error
+message \- will be used when an unknown subcommand is encountered. May
+be read and written using \fBTcl_GetEnsembleUnknownHandler\fR and
+\fBTcl_SetEnsembleUnknownHandler\fR respectively. The result of both
+functions is a Tcl result code (\fBTCL_OK\fR, or \fBTCL_ERROR\fR if
+the token does
+not refer to an ensemble) and the list obtained from
+\fBTcl_GetEnsembleUnknownHandler\fR should always be treated as
+immutable even if it is unshared.
+.TP
+\fBbound namespace\fR (read-only)
+.
+The namespace to which the ensemble is bound; when the namespace is
+deleted, so too will the ensemble, and this namespace is also the
+namespace whose list of exported commands is used if both the mapping
+dictionary and the subcommand list properties are NULL. May be read
+using \fBTcl_GetEnsembleNamespace\fR which returns a Tcl result code
+(\fBTCL_OK\fR, or \fBTCL_ERROR\fR if the token does not refer to an ensemble).
+.SH "SEE ALSO"
+namespace(n), Tcl_DeleteCommandFromToken(3)
+.SH KEYWORDS
+command, ensemble
diff --git a/doc/Environment.3 b/doc/Environment.3
new file mode 100644
index 0000000..85880b4
--- /dev/null
+++ b/doc/Environment.3
@@ -0,0 +1,38 @@
+'\"
+'\" Copyright (c) 1997-1998 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\" 
+.TH Tcl_PutEnv 3 "7.5" Tcl "Tcl Library Procedures"
+.so man.macros
+.BS
+.SH NAME
+Tcl_PutEnv \- procedures to manipulate the environment
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+int
+\fBTcl_PutEnv\fR(\fIassignment\fR)
+.SH ARGUMENTS
+.AS "const char" *assignment
+.AP "const char" *assignment in
+Info about environment variable in the format
+.QW \fINAME\fB=\fIvalue\fR .
+The \fIassignment\fR argument is in the system encoding.
+.BE
+.SH DESCRIPTION
+.PP
+\fBTcl_PutEnv\fR sets an environment variable. The information is
+passed in a single string of the form
+.QW \fINAME\fB=\fIvalue\fR .
+This procedure is
+intended to be a stand-in for the UNIX \fBputenv\fR system call. All
+Tcl-based applications using \fBputenv\fR should redefine it to
+\fBTcl_PutEnv\fR so that they will interface properly to the Tcl
+runtime.
+.SH "SEE ALSO"
+env(n)
+.SH KEYWORDS
+environment, variable
diff --git a/doc/Eval.3 b/doc/Eval.3
new file mode 100644
index 0000000..8661923
--- /dev/null
+++ b/doc/Eval.3
@@ -0,0 +1,211 @@
+'\"
+'\" Copyright (c) 1989-1993 The Regents of the University of California.
+'\" Copyright (c) 1994-1997 Sun Microsystems, Inc.
+'\" Copyright (c) 2000 Scriptics Corporation.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH Tcl_Eval 3 8.1 Tcl "Tcl Library Procedures"
+.so man.macros
+.BS
+.SH NAME
+Tcl_EvalObjEx, Tcl_EvalFile, Tcl_EvalObjv, Tcl_Eval, Tcl_EvalEx, Tcl_GlobalEval, Tcl_GlobalEvalObj, Tcl_VarEval, Tcl_VarEvalVA \- execute Tcl scripts
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+int
+\fBTcl_EvalObjEx\fR(\fIinterp, objPtr, flags\fR)
+.sp
+int
+\fBTcl_EvalFile\fR(\fIinterp, fileName\fR)
+.sp
+int
+\fBTcl_EvalObjv\fR(\fIinterp, objc, objv, flags\fR)
+.sp
+int
+\fBTcl_Eval\fR(\fIinterp, script\fR)
+.sp
+int
+\fBTcl_EvalEx\fR(\fIinterp, script, numBytes, flags\fR)
+.sp
+int
+\fBTcl_GlobalEval\fR(\fIinterp, script\fR)
+.sp
+int
+\fBTcl_GlobalEvalObj\fR(\fIinterp, objPtr\fR)
+.sp
+int
+\fBTcl_VarEval\fR(\fIinterp, part, part, ... \fB(char *) NULL\fR)
+.sp
+int
+\fBTcl_VarEvalVA\fR(\fIinterp, argList\fR)
+.SH ARGUMENTS
+.AS Tcl_Interp **termPtr
+.AP Tcl_Interp *interp in
+Interpreter in which to execute the script.  The interpreter's result is
+modified to hold the result or error message from the script.
+.AP Tcl_Obj *objPtr in
+A Tcl value containing the script to execute.
+.AP int flags in
+ORed combination of flag bits that specify additional options.
+\fBTCL_EVAL_GLOBAL\fR and \fBTCL_EVAL_DIRECT\fR are currently supported.
+.AP "const char" *fileName in
+Name of a file containing a Tcl script.
+.AP int objc in
+The number of values in the array pointed to by \fIobjPtr\fR;
+this is also the number of words in the command.
+.AP Tcl_Obj **objv in
+Points to an array of pointers to values; each value holds the
+value of a single word in the command to execute.
+.AP int numBytes in
+The number of bytes in \fIscript\fR, not including any
+null terminating character.  If \-1, then all characters up to the
+first null byte are used.
+.AP "const char" *script in
+Points to first byte of script to execute (null-terminated and UTF-8).
+.AP char *part in
+String forming part of a Tcl script.
+.AP va_list argList in
+An argument list which must have been initialized using
+\fBva_start\fR, and cleared using \fBva_end\fR.
+.BE
+
+.SH DESCRIPTION
+.PP
+The procedures described here are invoked to execute Tcl scripts in
+various forms.
+\fBTcl_EvalObjEx\fR is the core procedure and is used by many of the others.
+It executes the commands in the script stored in \fIobjPtr\fR
+until either an error occurs or the end of the script is reached.
+If this is the first time \fIobjPtr\fR has been executed,
+its commands are compiled into bytecode instructions
+which are then executed.  The
+bytecodes are saved in \fIobjPtr\fR so that the compilation step
+can be skipped if the value is evaluated again in the future.
+.PP
+The return value from \fBTcl_EvalObjEx\fR (and all the other procedures
+described here) is a Tcl completion code with
+one of the values \fBTCL_OK\fR, \fBTCL_ERROR\fR, \fBTCL_RETURN\fR,
+\fBTCL_BREAK\fR, or \fBTCL_CONTINUE\fR, or possibly some other
+integer value originating in an extension.
+In addition, a result value or error message is left in \fIinterp\fR's
+result; it can be retrieved using \fBTcl_GetObjResult\fR.
+.PP
+\fBTcl_EvalFile\fR reads the file given by \fIfileName\fR and evaluates
+its contents as a Tcl script.  It returns the same information as
+\fBTcl_EvalObjEx\fR.
+If the file could not be read then a Tcl error is returned to describe
+why the file could not be read.
+The eofchar for files is
+.QW \e32
+(^Z) for all platforms. If you require a
+.QW ^Z
+in code for string comparison, you can use
+.QW \e032
+or
+.QW \eu001a ,
+which will be safely substituted by the Tcl interpreter into
+.QW ^Z .
+.PP
+\fBTcl_EvalObjv\fR executes a single pre-parsed command instead of a
+script.  The \fIobjc\fR and \fIobjv\fR arguments contain the values
+of the words for the Tcl command, one word in each value in
+\fIobjv\fR.  \fBTcl_EvalObjv\fR evaluates the command and returns
+a completion code and result just like \fBTcl_EvalObjEx\fR.
+The caller of \fBTcl_EvalObjv\fR has to manage the reference count of the
+elements of \fIobjv\fR, insuring that the values are valid until
+\fBTcl_EvalObjv\fR returns.
+.PP
+\fBTcl_Eval\fR is similar to \fBTcl_EvalObjEx\fR except that the script to
+be executed is supplied as a string instead of a value and no compilation
+occurs.  The string should be a proper UTF-8 string as converted by
+\fBTcl_ExternalToUtfDString\fR or \fBTcl_ExternalToUtf\fR when it is known
+to possibly contain upper ASCII characters whose possible combinations
+might be a UTF-8 special code.  The string is parsed and executed directly
+(using \fBTcl_EvalObjv\fR) instead of compiling it and executing the
+bytecodes.  In situations where it is known that the script will never be
+executed again, \fBTcl_Eval\fR may be faster than \fBTcl_EvalObjEx\fR.
+ \fBTcl_Eval\fR returns a completion code and result just like
+\fBTcl_EvalObjEx\fR.  Note: for backward compatibility with versions before
+Tcl 8.0, \fBTcl_Eval\fR copies the value result in \fIinterp\fR to
+\fIinterp->result\fR (use is deprecated) where it can be accessed directly.
+ This makes \fBTcl_Eval\fR somewhat slower than \fBTcl_EvalEx\fR, which
+does not do the copy.
+.PP
+\fBTcl_EvalEx\fR is an extended version of \fBTcl_Eval\fR that takes
+additional arguments \fInumBytes\fR and \fIflags\fR.  For the
+efficiency reason given above, \fBTcl_EvalEx\fR is generally preferred
+over \fBTcl_Eval\fR.
+.PP
+\fBTcl_GlobalEval\fR and \fBTcl_GlobalEvalObj\fR are older procedures
+that are now deprecated.  They are similar to \fBTcl_EvalEx\fR and
+\fBTcl_EvalObjEx\fR except that the script is evaluated in the global
+namespace and its variable context consists of global variables only
+(it ignores any Tcl procedures that are active).  These functions are
+equivalent to using the \fBTCL_EVAL_GLOBAL\fR flag (see below).
+.PP
+\fBTcl_VarEval\fR takes any number of string arguments
+of any length, concatenates them into a single string,
+then calls \fBTcl_Eval\fR to execute that string as a Tcl command.
+It returns the result of the command and also modifies
+\fIinterp->result\fR in the same way as \fBTcl_Eval\fR.
+The last argument to \fBTcl_VarEval\fR must be NULL to indicate the end
+of arguments.  \fBTcl_VarEval\fR is now deprecated.
+.PP
+\fBTcl_VarEvalVA\fR is the same as \fBTcl_VarEval\fR except that
+instead of taking a variable number of arguments it takes an argument
+list. Like \fBTcl_VarEval\fR, \fBTcl_VarEvalVA\fR is deprecated.
+
+.SH "FLAG BITS"
+.PP
+Any ORed combination of the following values may be used for the
+\fIflags\fR argument to procedures such as \fBTcl_EvalObjEx\fR:
+.TP 23
+\fBTCL_EVAL_DIRECT\fR
+.
+This flag is only used by \fBTcl_EvalObjEx\fR; it is ignored by
+other procedures.  If this flag bit is set, the script is not
+compiled to bytecodes; instead it is executed directly
+as is done by \fBTcl_EvalEx\fR.  The
+\fBTCL_EVAL_DIRECT\fR flag is useful in situations where the
+contents of a value are going to change immediately, so the
+bytecodes will not be reused in a future execution.  In this case,
+it is faster to execute the script directly.
+.TP 23
+\fBTCL_EVAL_GLOBAL\fR
+.
+If this flag is set, the script is processed at global level.  This
+means that it is evaluated in the global namespace and its variable
+context consists of global variables only (it ignores any Tcl
+procedures that are active).
+
+.SH "MISCELLANEOUS DETAILS"
+.PP
+During the processing of a Tcl command it is legal to make nested
+calls to evaluate other commands (this is how procedures and
+some control structures are implemented).
+If a code other than \fBTCL_OK\fR is returned
+from a nested \fBTcl_EvalObjEx\fR invocation,
+then the caller should normally return immediately,
+passing that same return code back to its caller,
+and so on until the top-level application is reached.
+A few commands, like \fBfor\fR, will check for certain
+return codes, like \fBTCL_BREAK\fR and \fBTCL_CONTINUE\fR, and process them
+specially without returning.
+.PP
+\fBTcl_EvalObjEx\fR keeps track of how many nested \fBTcl_EvalObjEx\fR
+invocations are in progress for \fIinterp\fR.
+If a code of \fBTCL_RETURN\fR, \fBTCL_BREAK\fR, or \fBTCL_CONTINUE\fR is
+about to be returned from the topmost \fBTcl_EvalObjEx\fR
+invocation for \fIinterp\fR,
+it converts the return code to \fBTCL_ERROR\fR
+and sets \fIinterp\fR's result to an error message indicating that
+the \fBreturn\fR, \fBbreak\fR, or \fBcontinue\fR command was
+invoked in an inappropriate place.
+This means that top-level applications should never see a return code
+from \fBTcl_EvalObjEx\fR other then \fBTCL_OK\fR or \fBTCL_ERROR\fR.
+
+.SH KEYWORDS
+execute, file, global, result, script, value
diff --git a/doc/Exit.3 b/doc/Exit.3
new file mode 100644
index 0000000..9a04db3
--- /dev/null
+++ b/doc/Exit.3
@@ -0,0 +1,140 @@
+'\"
+'\" Copyright (c) 1995-1996 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH Tcl_Exit 3 8.5 Tcl "Tcl Library Procedures"
+.so man.macros
+.BS
+.SH NAME
+Tcl_Exit, Tcl_Finalize, Tcl_CreateExitHandler, Tcl_DeleteExitHandler, Tcl_ExitThread, Tcl_FinalizeThread, Tcl_CreateThreadExitHandler, Tcl_DeleteThreadExitHandler, Tcl_SetExitProc \- end the application or thread (and invoke exit handlers)
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+\fBTcl_Exit\fR(\fIstatus\fR)
+.sp
+\fBTcl_Finalize\fR()
+.sp
+\fBTcl_CreateExitHandler\fR(\fIproc, clientData\fR)
+.sp
+\fBTcl_DeleteExitHandler\fR(\fIproc, clientData\fR)
+.sp
+\fBTcl_ExitThread\fR(\fIstatus\fR)
+.sp
+\fBTcl_FinalizeThread\fR()
+.sp
+\fBTcl_CreateThreadExitHandler\fR(\fIproc, clientData\fR)
+.sp
+\fBTcl_DeleteThreadExitHandler\fR(\fIproc, clientData\fR)
+.sp
+Tcl_ExitProc *
+\fBTcl_SetExitProc\fR(\fIproc\fR)
+.SH ARGUMENTS
+.AS Tcl_ExitProc clientData
+.AP int status  in
+Provides information about why the application or thread exited.
+Exact meaning may
+be platform-specific.  0 usually means a normal exit, any nonzero value
+usually means that an error occurred.
+.AP Tcl_ExitProc *proc in
+Procedure to invoke before exiting application, or (for
+\fBTcl_SetExitProc\fR) NULL to uninstall the current application exit
+procedure.
+.AP ClientData clientData in
+Arbitrary one-word value to pass to \fIproc\fR.
+.BE
+
+.SH DESCRIPTION
+.PP
+The procedures described here provide a graceful mechanism to end the
+execution of a \fBTcl\fR application. Exit handlers are invoked to cleanup the
+application's state before ending the execution of \fBTcl\fR code.
+.PP
+Invoke \fBTcl_Exit\fR to end a \fBTcl\fR application and to exit from this
+process. This procedure is invoked by the \fBexit\fR command, and can be
+invoked anyplace else to terminate the application.
+No-one should ever invoke the \fBexit\fR system procedure directly;  always
+invoke \fBTcl_Exit\fR instead, so that it can invoke exit handlers.
+Note that if other code invokes \fBexit\fR system procedure directly, or
+otherwise causes the application to terminate without calling
+\fBTcl_Exit\fR, the exit handlers will not be run.
+\fBTcl_Exit\fR internally invokes the \fBexit\fR system call, thus it never
+returns control to its caller.
+If an application exit handler has been installed (see
+\fBTcl_SetExitProc\fR), that handler is invoked with an argument
+consisting of the exit status (cast to ClientData); the application
+exit handler should not return control to Tcl.
+.PP
+\fBTcl_Finalize\fR is similar to \fBTcl_Exit\fR except that it does not
+exit from the current process.
+It is useful for cleaning up when a process is finished using \fBTcl\fR but
+wishes to continue executing, and when \fBTcl\fR is used in a dynamically
+loaded extension that is about to be unloaded.
+Your code should always invoke \fBTcl_Finalize\fR when \fBTcl\fR is being
+unloaded, to ensure proper cleanup. \fBTcl_Finalize\fR can be safely called
+more than once.
+.PP
+\fBTcl_ExitThread\fR is used to terminate the current thread and invoke
+per-thread exit handlers.  This finalization is done by
+\fBTcl_FinalizeThread\fR, which you can call if you just want to clean
+up per-thread state and invoke the thread exit handlers.
+\fBTcl_Finalize\fR calls \fBTcl_FinalizeThread\fR for the current
+thread automatically.
+.PP
+\fBTcl_CreateExitHandler\fR arranges for \fIproc\fR to be invoked
+by \fBTcl_Finalize\fR and \fBTcl_Exit\fR.
+\fBTcl_CreateThreadExitHandler\fR arranges for \fIproc\fR to be invoked
+by \fBTcl_FinalizeThread\fR and \fBTcl_ExitThread\fR.
+This provides a hook for cleanup operations such as flushing buffers
+and freeing global memory.
+\fIProc\fR should match the type \fBTcl_ExitProc\fR:
+.PP
+.CS
+typedef void \fBTcl_ExitProc\fR(
+        ClientData \fIclientData\fR);
+.CE
+.PP
+The \fIclientData\fR parameter to \fIproc\fR is a
+copy of the \fIclientData\fR argument given to
+\fBTcl_CreateExitHandler\fR or \fBTcl_CreateThreadExitHandler\fR when
+the callback
+was created.  Typically, \fIclientData\fR points to a data
+structure containing application-specific information about
+what to do in \fIproc\fR.
+.PP
+\fBTcl_DeleteExitHandler\fR and \fBTcl_DeleteThreadExitHandler\fR may be
+called to delete a
+previously-created exit handler.  It removes the handler
+indicated by \fIproc\fR and \fIclientData\fR so that no call
+to \fIproc\fR will be made.  If no such handler exists then
+\fBTcl_DeleteExitHandler\fR or \fBTcl_DeleteThreadExitHandler\fR does nothing.
+.PP
+\fBTcl_Finalize\fR and \fBTcl_Exit\fR execute all registered exit handlers,
+in reverse order from the order in which they were registered.
+This matches the natural order in which extensions are loaded and unloaded;
+if extension \fBA\fR loads extension \fBB\fR, it usually
+unloads \fBB\fR before it itself is unloaded.
+If extension \fBA\fR registers its exit handlers before loading extension
+\fBB\fR, this ensures that any exit handlers for \fBB\fR will be executed
+before the exit handlers for \fBA\fR.
+.PP
+\fBTcl_Finalize\fR and \fBTcl_Exit\fR call \fBTcl_FinalizeThread\fR
+and the thread exit handlers \fIafter\fR
+the process-wide exit handlers.  This is because thread finalization shuts
+down the I/O channel system, so any attempt at I/O by the global exit
+handlers will vanish into the bitbucket.
+.PP
+\fBTcl_SetExitProc\fR installs an application exit handler, returning
+the previously-installed application exit handler or NULL if no
+application handler was installed.  If an application exit handler is
+installed, that exit handler takes over complete responsibility for
+finalization of Tcl's subsystems via \fBTcl_Finalize\fR at an
+appropriate time.  The argument passed to \fIproc\fR when it is
+invoked will be the exit status code (as passed to \fBTcl_Exit\fR)
+cast to a ClientData value.
+.SH "SEE ALSO"
+exit(n)
+.SH KEYWORDS
+abort, callback, cleanup, dynamic loading, end application, exit, unloading, thread
diff --git a/doc/ExprLong.3 b/doc/ExprLong.3
new file mode 100644
index 0000000..0d369ce
--- /dev/null
+++ b/doc/ExprLong.3
@@ -0,0 +1,106 @@
+'\"
+'\" Copyright (c) 1989-1993 The Regents of the University of California.
+'\" Copyright (c) 1994-1997 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH Tcl_ExprLong 3 7.0 Tcl "Tcl Library Procedures"
+.so man.macros
+.BS
+.SH NAME
+Tcl_ExprLong, Tcl_ExprDouble, Tcl_ExprBoolean, Tcl_ExprString \- evaluate an expression
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+int
+\fBTcl_ExprLong\fR(\fIinterp, expr, longPtr\fR)
+.sp
+int
+\fBTcl_ExprDouble\fR(\fIinterp, expr, doublePtr\fR)
+.sp
+int
+\fBTcl_ExprBoolean\fR(\fIinterp, expr, booleanPtr\fR)
+.sp
+int
+\fBTcl_ExprString\fR(\fIinterp, expr\fR)
+.SH ARGUMENTS
+.AS Tcl_Interp *booleanPtr out
+.AP Tcl_Interp *interp in
+Interpreter in whose context to evaluate \fIexpr\fR.
+.AP "const char" *expr in
+Expression to be evaluated.
+.AP long *longPtr out
+Pointer to location in which to store the integer value of the
+expression.
+.AP int *doublePtr out
+Pointer to location in which to store the floating-point value of the
+expression.
+.AP int *booleanPtr out
+Pointer to location in which to store the 0/1 boolean value of the
+expression.
+.BE
+
+.SH DESCRIPTION
+.PP
+These four procedures all evaluate the expression
+given by the \fIexpr\fR argument
+and return the result in one of four different forms.
+The expression can have any of the forms accepted by the \fBexpr\fR command.
+Note that these procedures have been largely replaced by the
+value-based procedures \fBTcl_ExprLongObj\fR, \fBTcl_ExprDoubleObj\fR,
+\fBTcl_ExprBooleanObj\fR, and \fBTcl_ExprObj\fR.
+Those value-based procedures evaluate an expression held in a Tcl value
+instead of a string.
+The value argument can retain an internal representation
+that is more efficient to execute.
+.PP
+The \fIinterp\fR argument refers to an interpreter used to
+evaluate the expression (e.g. for variables and nested Tcl
+commands) and to return error information.
+.PP
+For all of these procedures the return value is a standard
+Tcl result: \fBTCL_OK\fR means the expression was successfully
+evaluated, and \fBTCL_ERROR\fR means that an error occurred while
+evaluating the expression.
+If \fBTCL_ERROR\fR is returned then
+the interpreter's result will hold a message describing the error.
+If an error occurs while executing a Tcl command embedded in
+the expression then that error will be returned.
+.PP
+If the expression is successfully evaluated, then its value is
+returned in one of four forms, depending on which procedure
+is invoked.
+\fBTcl_ExprLong\fR stores an integer value at \fI*longPtr\fR.
+If the expression's actual value is a floating-point number,
+then it is truncated to an integer.
+If the expression's actual value is a non-numeric string then
+an error is returned.
+.PP
+\fBTcl_ExprDouble\fR stores a floating-point value at \fI*doublePtr\fR.
+If the expression's actual value is an integer, it is converted to
+floating-point.
+If the expression's actual value is a non-numeric string then
+an error is returned.
+.PP
+\fBTcl_ExprBoolean\fR stores a 0/1 integer value at \fI*booleanPtr\fR.
+If the expression's actual value is an integer or floating-point
+number, then they store 0 at \fI*booleanPtr\fR if
+the value was zero and 1 otherwise.
+If the expression's actual value is a non-numeric string then
+it must be one of the values accepted by \fBTcl_GetBoolean\fR
+such as
+.QW yes
+or
+.QW no ,
+or else an error occurs.
+.PP
+\fBTcl_ExprString\fR returns the value of the expression as a
+string stored in the interpreter's result.
+
+.SH "SEE ALSO"
+Tcl_ExprLongObj, Tcl_ExprDoubleObj, Tcl_ExprBooleanObj, Tcl_ExprObj
+
+.SH KEYWORDS
+boolean, double, evaluate, expression, integer, value, string
diff --git a/doc/ExprLongObj.3 b/doc/ExprLongObj.3
new file mode 100644
index 0000000..35edb5f
--- /dev/null
+++ b/doc/ExprLongObj.3
@@ -0,0 +1,106 @@
+'\"
+'\" Copyright (c) 1996-1997 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\" 
+.TH Tcl_ExprLongObj 3 8.0 Tcl "Tcl Library Procedures"
+.so man.macros
+.BS
+.SH NAME
+Tcl_ExprLongObj, Tcl_ExprDoubleObj, Tcl_ExprBooleanObj, Tcl_ExprObj \- evaluate an expression
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+int
+\fBTcl_ExprLongObj\fR(\fIinterp, objPtr, longPtr\fR)
+.sp
+int
+\fBTcl_ExprDoubleObj\fR(\fIinterp, objPtr, doublePtr\fR)
+.sp
+int
+\fBTcl_ExprBooleanObj\fR(\fIinterp, objPtr, booleanPtr\fR)
+.sp
+int
+\fBTcl_ExprObj\fR(\fIinterp, objPtr, resultPtrPtr\fR)
+.SH ARGUMENTS
+.AS Tcl_Interp **resultPtrPtr out
+.AP Tcl_Interp *interp in
+Interpreter in whose context to evaluate \fIobjPtr\fR.
+.AP Tcl_Obj *objPtr in
+Pointer to a value containing the expression to evaluate.
+.AP long *longPtr out
+Pointer to location in which to store the integer value of the
+expression.
+.AP int *doublePtr out
+Pointer to location in which to store the floating-point value of the
+expression.
+.AP int *booleanPtr out
+Pointer to location in which to store the 0/1 boolean value of the
+expression.
+.AP Tcl_Obj **resultPtrPtr out
+Pointer to location in which to store a pointer to the value
+that is the result of the expression.
+.BE
+
+.SH DESCRIPTION
+.PP
+These four procedures all evaluate an expression, returning
+the result in one of four different forms.
+The expression is given by the \fIobjPtr\fR argument, and it
+can have any of the forms accepted by the \fBexpr\fR command.
+.PP
+The \fIinterp\fR argument refers to an interpreter used to
+evaluate the expression (e.g. for variables and nested Tcl
+commands) and to return error information.
+.PP
+For all of these procedures the return value is a standard
+Tcl result: \fBTCL_OK\fR means the expression was successfully
+evaluated, and \fBTCL_ERROR\fR means that an error occurred while
+evaluating the expression.
+If \fBTCL_ERROR\fR is returned,
+then a message describing the error
+can be retrieved using \fBTcl_GetObjResult\fR.
+If an error occurs while executing a Tcl command embedded in
+the expression then that error will be returned.
+.PP
+If the expression is successfully evaluated, then its value is
+returned in one of four forms, depending on which procedure
+is invoked.
+\fBTcl_ExprLongObj\fR stores an integer value at \fI*longPtr\fR.
+If the expression's actual value is a floating-point number,
+then it is truncated to an integer.
+If the expression's actual value is a non-numeric string then
+an error is returned.
+.PP
+\fBTcl_ExprDoubleObj\fR stores a floating-point value at \fI*doublePtr\fR.
+If the expression's actual value is an integer, it is converted to
+floating-point.
+If the expression's actual value is a non-numeric string then
+an error is returned.
+.PP
+\fBTcl_ExprBooleanObj\fR stores a 0/1 integer value at \fI*booleanPtr\fR.
+If the expression's actual value is an integer or floating-point
+number, then they store 0 at \fI*booleanPtr\fR if
+the value was zero and 1 otherwise.
+If the expression's actual value is a non-numeric string then
+it must be one of the values accepted by \fBTcl_GetBoolean\fR
+such as
+.QW yes
+or
+.QW no ,
+or else an error occurs.
+.PP
+If \fBTcl_ExprObj\fR successfully evaluates the expression,
+it stores a pointer to the Tcl value
+containing the expression's value at \fI*resultPtrPtr\fR.
+In this case, the caller is responsible for calling
+\fBTcl_DecrRefCount\fR to decrement the value's reference count
+when it is finished with the value.
+
+.SH "SEE ALSO"
+Tcl_ExprLong, Tcl_ExprDouble, Tcl_ExprBoolean, Tcl_ExprString, Tcl_GetObjResult
+
+.SH KEYWORDS
+boolean, double, evaluate, expression, integer, value, string
diff --git a/doc/FileSystem.3 b/doc/FileSystem.3
new file mode 100644
index 0000000..28ee8f0
--- /dev/null
+++ b/doc/FileSystem.3
@@ -0,0 +1,1644 @@
+'\"
+'\" Copyright (c) 2001 Vincent Darley
+'\" Copyright (c) 2008-2010 Donal K. Fellows
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH Filesystem 3 8.4 Tcl "Tcl Library Procedures"
+.so man.macros
+.BS
+.SH NAME
+Tcl_FSRegister, Tcl_FSUnregister, Tcl_FSData, Tcl_FSMountsChanged, Tcl_FSGetFileSystemForPath, Tcl_FSGetPathType, Tcl_FSCopyFile, Tcl_FSCopyDirectory, Tcl_FSCreateDirectory, Tcl_FSDeleteFile, Tcl_FSRemoveDirectory, Tcl_FSRenameFile, Tcl_FSListVolumes, Tcl_FSEvalFile, Tcl_FSEvalFileEx, Tcl_FSLoadFile, Tcl_FSUnloadFile, Tcl_FSMatchInDirectory, Tcl_FSLink, Tcl_FSLstat, Tcl_FSUtime, Tcl_FSFileAttrsGet, Tcl_FSFileAttrsSet, Tcl_FSFileAttrStrings, Tcl_FSStat, Tcl_FSAccess, Tcl_FSOpenFileChannel, Tcl_FSGetCwd, Tcl_FSChdir, Tcl_FSPathSeparator, Tcl_FSJoinPath, Tcl_FSSplitPath, Tcl_FSEqualPaths, Tcl_FSGetNormalizedPath, Tcl_FSJoinToPath, Tcl_FSConvertToPathType, Tcl_FSGetInternalRep, Tcl_FSGetTranslatedPath, Tcl_FSGetTranslatedStringPath, Tcl_FSNewNativePath, Tcl_FSGetNativePath, Tcl_FSFileSystemInfo, Tcl_GetAccessTimeFromStat, Tcl_GetBlockSizeFromStat, Tcl_GetBlocksFromStat, Tcl_GetChangeTimeFromStat, Tcl_GetDeviceTypeFromStat, Tcl_GetFSDeviceFromStat, Tcl_GetFSInodeFromStat, Tcl_GetGroupIdFromStat, Tcl_GetLinkCountFromStat, Tcl_GetModeFromStat, Tcl_GetModificationTimeFromStat, Tcl_GetSizeFromStat, Tcl_GetUserIdFromStat, Tcl_AllocStatBuf \- procedures to interact with any filesystem
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+int
+\fBTcl_FSRegister\fR(\fIclientData, fsPtr\fR)
+.sp
+int
+\fBTcl_FSUnregister\fR(\fIfsPtr\fR)
+.sp
+ClientData
+\fBTcl_FSData\fR(\fIfsPtr\fR)
+.sp
+void
+\fBTcl_FSMountsChanged\fR(\fIfsPtr\fR)
+.sp
+const Tcl_Filesystem *
+\fBTcl_FSGetFileSystemForPath\fR(\fIpathPtr\fR)
+.sp
+Tcl_PathType
+\fBTcl_FSGetPathType\fR(\fIpathPtr\fR)
+.sp
+int
+\fBTcl_FSCopyFile\fR(\fIsrcPathPtr, destPathPtr\fR)
+.sp
+int
+\fBTcl_FSCopyDirectory\fR(\fIsrcPathPtr, destPathPtr, errorPtr\fR)
+.sp
+int
+\fBTcl_FSCreateDirectory\fR(\fIpathPtr\fR)
+.sp
+int
+\fBTcl_FSDeleteFile\fR(\fIpathPtr\fR)
+.sp
+int
+\fBTcl_FSRemoveDirectory\fR(\fIpathPtr, int recursive, errorPtr\fR)
+.sp
+int
+\fBTcl_FSRenameFile\fR(\fIsrcPathPtr, destPathPtr\fR)
+.sp
+Tcl_Obj *
+\fBTcl_FSListVolumes\fR(\fIvoid\fR)
+.sp
+int
+\fBTcl_FSEvalFileEx\fR(\fIinterp, pathPtr, encodingName\fR)
+.sp
+int
+\fBTcl_FSEvalFile\fR(\fIinterp, pathPtr\fR)
+.sp
+int
+\fBTcl_FSLoadFile\fR(\fIinterp, pathPtr, sym1, sym2, proc1Ptr, proc2Ptr,
+               loadHandlePtr, unloadProcPtr\fR)
+.sp
+.VS 8.6
+int
+\fBTcl_FSUnloadFile\fR(\fIinterp, loadHandle\fR)
+.VE 8.6
+.sp
+int
+\fBTcl_FSMatchInDirectory\fR(\fIinterp, resultPtr, pathPtr, pattern, types\fR)
+.sp
+Tcl_Obj *
+\fBTcl_FSLink\fR(\fIlinkNamePtr, toPtr, linkAction\fR)
+.sp
+int
+\fBTcl_FSLstat\fR(\fIpathPtr, statPtr\fR)
+.sp
+int
+\fBTcl_FSUtime\fR(\fIpathPtr, tval\fR)
+.sp
+int
+\fBTcl_FSFileAttrsGet\fR(\fIinterp, int index, pathPtr, objPtrRef\fR)
+.sp
+int
+\fBTcl_FSFileAttrsSet\fR(\fIinterp, int index, pathPtr, Tcl_Obj *objPtr\fR)
+.sp
+const char *const *
+\fBTcl_FSFileAttrStrings\fR(\fIpathPtr, objPtrRef\fR)
+.sp
+int
+\fBTcl_FSStat\fR(\fIpathPtr, statPtr\fR)
+.sp
+int
+\fBTcl_FSAccess\fR(\fIpathPtr, mode\fR)
+.sp
+Tcl_Channel
+\fBTcl_FSOpenFileChannel\fR(\fIinterp, pathPtr, modeString, permissions\fR)
+.sp
+Tcl_Obj *
+\fBTcl_FSGetCwd\fR(\fIinterp\fR)
+.sp
+int
+\fBTcl_FSChdir\fR(\fIpathPtr\fR)
+.sp
+Tcl_Obj *
+\fBTcl_FSPathSeparator\fR(\fIpathPtr\fR)
+.sp
+Tcl_Obj *
+\fBTcl_FSJoinPath\fR(\fIlistObj, elements\fR)
+.sp
+Tcl_Obj *
+\fBTcl_FSSplitPath\fR(\fIpathPtr, lenPtr\fR)
+.sp
+int
+\fBTcl_FSEqualPaths\fR(\fIfirstPtr, secondPtr\fR)
+.sp
+Tcl_Obj *
+\fBTcl_FSGetNormalizedPath\fR(\fIinterp, pathPtr\fR)
+.sp
+Tcl_Obj *
+\fBTcl_FSJoinToPath\fR(\fIbasePtr, objc, objv\fR)
+.sp
+int
+\fBTcl_FSConvertToPathType\fR(\fIinterp, pathPtr\fR)
+.sp
+ClientData
+\fBTcl_FSGetInternalRep\fR(\fIpathPtr, fsPtr\fR)
+.sp
+Tcl_Obj *
+\fBTcl_FSGetTranslatedPath\fR(\fIinterp, pathPtr\fR)
+.sp
+const char *
+\fBTcl_FSGetTranslatedStringPath\fR(\fIinterp, pathPtr\fR)
+.sp
+Tcl_Obj *
+\fBTcl_FSNewNativePath\fR(\fIfsPtr, clientData\fR)
+.sp
+const void *
+\fBTcl_FSGetNativePath\fR(\fIpathPtr\fR)
+.sp
+Tcl_Obj *
+\fBTcl_FSFileSystemInfo\fR(\fIpathPtr\fR)
+.sp
+Tcl_StatBuf *
+\fBTcl_AllocStatBuf\fR()
+.sp
+.VS 8.6
+Tcl_WideInt
+\fBTcl_GetAccessTimeFromStat\fR(\fIstatPtr\fR)
+.sp
+unsigned
+\fBTcl_GetBlockSizeFromStat\fR(\fIstatPtr\fR)
+.sp
+Tcl_WideUInt
+\fBTcl_GetBlocksFromStat\fR(\fIstatPtr\fR)
+.sp
+Tcl_WideInt
+\fBTcl_GetChangeTimeFromStat\fR(\fIstatPtr\fR)
+.sp
+int
+\fBTcl_GetDeviceTypeFromStat\fR(\fIstatPtr\fR)
+.sp
+unsigned
+\fBTcl_GetFSDeviceFromStat\fR(\fIstatPtr\fR)
+.sp
+unsigned
+\fBTcl_GetFSInodeFromStat\fR(\fIstatPtr\fR)
+.sp
+int
+\fBTcl_GetGroupIdFromStat\fR(\fIstatPtr\fR)
+.sp
+int
+\fBTcl_GetLinkCountFromStat\fR(\fIstatPtr\fR)
+.sp
+unsigned
+\fBTcl_GetModeFromStat\fR(\fIstatPtr\fR)
+.sp
+Tcl_WideInt
+\fBTcl_GetModificationTimeFromStat\fR(\fIstatPtr\fR)
+.sp
+Tcl_WideUInt
+\fBTcl_GetSizeFromStat\fR(\fIstatPtr\fR)
+.sp
+int
+\fBTcl_GetUserIdFromStat\fR(\fIstatPtr\fR)
+.VE 8.6
+.SH ARGUMENTS
+.AS Tcl_GlobTypeData **srcPathPtr out
+.AP "const Tcl_Filesystem" *fsPtr in
+Points to a structure containing the addresses of procedures that
+can be called to perform the various filesystem operations.
+.AP Tcl_Obj *pathPtr in
+The path represented by this value is used for the operation in
+question. If the value does not already have an internal \fBpath\fR
+representation, it will be converted to have one.
+.AP Tcl_Obj *srcPathPtr in
+As for \fIpathPtr\fR, but used for the source file for a copy or
+rename operation.
+.AP Tcl_Obj *destPathPtr in
+As for \fIpathPtr\fR, but used for the destination filename for a copy or
+rename operation.
+.AP "const char" *encodingName in
+The encoding of the data stored in the
+file identified by \fIpathPtr\fR and to be evaluated.
+.AP "const char" *pattern in
+Only files or directories matching this pattern will be returned.
+.AP Tcl_GlobTypeData *types in
+Only files or directories matching the type descriptions contained in
+this structure will be returned. This parameter may be NULL.
+.AP Tcl_Interp *interp in
+Interpreter to use either for results, evaluation, or reporting error
+messages.
+.AP ClientData clientData in
+The native description of the path value to create.
+.AP Tcl_Obj *firstPtr in
+The first of two path values to compare. The value may be converted
+to \fBpath\fR type.
+.AP Tcl_Obj *secondPtr in
+The second of two path values to compare. The value may be converted
+to \fBpath\fR type.
+.AP Tcl_Obj *listObj in
+The list of path elements to operate on with a \fBjoin\fR operation.
+.AP int elements in
+If non-negative, the number of elements in the \fIlistObj\fR which should
+be joined together. If negative, then all elements are joined.
+.AP Tcl_Obj **errorPtr out
+In the case of an error, filled with a value containing the name of
+the file which caused an error in the various copy/rename operations.
+.AP Tcl_Obj **objPtrRef out
+Filled with a value containing the result of the operation.
+.AP Tcl_Obj *resultPtr out
+Pre-allocated value in which to store (using
+\fBTcl_ListObjAppendElement\fR) the list of
+files or directories which are successfully matched.
+.AP int mode in
+Mask consisting of one or more of R_OK, W_OK, X_OK and F_OK. R_OK,
+W_OK and X_OK request checking whether the file exists and  has  read,
+write and  execute  permissions, respectively. F_OK just requests
+checking for the existence of the file.
+.AP Tcl_StatBuf *statPtr out
+The structure that contains the result of a stat or lstat operation.
+.AP "const char" *sym1 in
+Name of a procedure to look up in the file's symbol table
+.AP "const char" *sym2 in
+Name of a procedure to look up in the file's symbol table
+.AP Tcl_PackageInitProc **proc1Ptr out
+Filled with the init function for this code.
+.AP Tcl_PackageInitProc **proc2Ptr out
+Filled with the safe-init function for this code.
+.AP ClientData *clientDataPtr out
+Filled with the clientData value to pass to this code's unload
+function when it is called.
+.AP Tcl_LoadHandle *loadHandlePtr out
+Filled with an abstract token representing the loaded file.
+.AP Tcl_FSUnloadFileProc **unloadProcPtr out
+Filled with the function to use to unload this piece of code.
+.AP Tcl_LoadHandle loadHandle in
+Handle to the loaded library to be unloaded.
+.AP utimbuf *tval in
+The access and modification times in this structure are read and
+used to set those values for a given file.
+.AP "const char" *modeString in
+Specifies how the file is to be accessed. May have any of the values
+allowed for the \fImode\fR argument to the Tcl \fBopen\fR command.
+.AP int permissions in
+POSIX-style permission flags such as 0644. If a new file is created, these
+permissions will be set on the created file.
+.AP int *lenPtr out
+If non-NULL, filled with the number of elements in the split path.
+.AP Tcl_Obj *basePtr in
+The base path on to which to join the given elements. May be NULL.
+.AP int objc in
+The number of elements in \fIobjv\fR.
+.AP "Tcl_Obj *const" objv[] in
+The elements to join to the given base path.
+.AP Tcl_Obj *linkNamePtr in
+The name of the link to be created or read.
+.AP Tcl_Obj *toPtr in
+What the link called \fIlinkNamePtr\fR should be linked to, or NULL if
+the symbolic link specified by \fIlinkNamePtr\fR is to be read.
+.AP int linkAction in
+OR-ed combination of flags indicating what kind of link should be
+created (will be ignored if \fItoPtr\fR is NULL). Valid bits to set
+are \fBTCL_CREATE_SYMBOLIC_LINK\fR and \fBTCL_CREATE_HARD_LINK\fR.
+When both flags are set and the underlying filesystem can do either,
+symbolic links are preferred.
+.BE
+.SH DESCRIPTION
+.PP
+There are several reasons for calling the \fBTcl_FS\fR API functions
+(e.g.\ \fBTcl_FSAccess\fR and \fBTcl_FSStat\fR)
+rather than calling system level functions like \fBaccess\fR and
+\fBstat\fR directly. First, they will work cross-platform, so an
+extension which calls them should work unmodified on Unix and
+Windows. Second, the Windows implementation of some of these functions
+fixes some bugs in the system level calls. Third, these function calls
+deal with any
+.QW "Utf to platform-native"
+path conversions which may be
+required (and may cache the results of such conversions for greater
+efficiency on subsequent calls). Fourth, and perhaps most importantly,
+all of these functions are
+.QW "virtual filesystem aware" .
+Any virtual filesystem (VFS for short) which has been registered (through
+\fBTcl_FSRegister\fR) may reroute file access to alternative
+media or access methods. This means that all of these functions (and
+therefore the corresponding \fBfile\fR, \fBglob\fR, \fBpwd\fR, \fBcd\fR,
+\fBopen\fR, etc.\ Tcl commands) may be operate on
+.QW files
+which are not
+native files in the native filesystem. This also means that any Tcl
+extension which accesses the filesystem (FS for short) through this API is
+automatically
+.QW "virtual filesystem aware" .
+Of course, if an extension
+accesses the native filesystem directly (through platform-specific
+APIs, for example), then Tcl cannot intercept such calls.
+.PP
+If appropriate VFSes have been registered, the
+.QW files
+may, to give two
+examples, be remote (e.g.\ situated on a remote ftp server) or archived
+(e.g.\ lying inside a .zip archive). Such registered filesystems provide
+a lookup table of functions to implement all or some of the functionality
+listed here. Finally, the \fBTcl_FSStat\fR and \fBTcl_FSLstat\fR calls
+abstract away from what the
+.QW "struct stat"
+buffer is actually
+declared to be, allowing the same code to be used both on systems with
+and systems without support for files larger than 2GB in size.
+.PP
+The \fBTcl_FS\fR API is \fBTcl_Obj\fR-ified and may cache internal
+representations and other path-related strings (e.g.\ the current working
+directory). One side-effect of this is that one must not pass in values
+with a reference count of zero to any of these functions. If such calls were
+handled, they might result
+in memory leaks (under some circumstances, the filesystem code may wish
+to retain a reference to the passed in value, and so one must not assume
+that after any of these calls return, the value still has a reference count of
+zero - it may have been incremented) or in a direct segmentation fault
+(or other memory access error)
+due to the value being freed part way through the complex value
+manipulation required to ensure that the path is fully normalized and
+absolute for filesystem determination. The practical lesson to learn
+from this is that
+.PP
+.CS
+Tcl_Obj *path = Tcl_NewStringObj(...);
+Tcl_FS\fIWhatever\fR(path);
+Tcl_DecrRefCount(path);
+.CE
+.PP
+is wrong, and may cause memory errors. The \fIpath\fR must have its
+reference count incremented before passing it in, or
+decrementing it. For this reason, values with a reference count of zero are
+considered not to be valid filesystem paths and calling any Tcl_FS API
+function with such a value will result in no action being taken.
+.SS "FS API FUNCTIONS"
+\fBTcl_FSCopyFile\fR attempts to copy the file given by \fIsrcPathPtr\fR to the
+path name given by \fIdestPathPtr\fR. If the two paths given lie in the same
+filesystem (according to \fBTcl_FSGetFileSystemForPath\fR) then that
+filesystem's
+.QW "copy file"
+function is called (if it is non-NULL).
+Otherwise the function returns -1 and sets the \fBerrno\fR global C
+variable to the
+.QW EXDEV
+POSIX error code (which signifies a
+.QW "cross-domain link" ).
+.PP
+\fBTcl_FSCopyDirectory\fR attempts to copy the directory given by \fIsrcPathPtr\fR to the
+path name given by \fIdestPathPtr\fR. If the two paths given lie in the same
+filesystem (according to \fBTcl_FSGetFileSystemForPath\fR) then that
+filesystem's
+.QW "copy file"
+function is called (if it is non-NULL).
+Otherwise the function returns -1 and sets the \fBerrno\fR global C
+variable to the
+.QW EXDEV
+POSIX error code (which signifies a
+.QW "cross-domain link" ).
+.PP
+\fBTcl_FSCreateDirectory\fR attempts to create the directory given by
+\fIpathPtr\fR by calling the owning filesystem's
+.QW "create directory"
+function.
+.PP
+\fBTcl_FSDeleteFile\fR attempts to delete the file given by
+\fIpathPtr\fR by calling the owning filesystem's
+.QW "delete file"
+function.
+.PP
+\fBTcl_FSRemoveDirectory\fR attempts to remove the directory given by
+\fIpathPtr\fR by calling the owning filesystem's
+.QW "remove directory"
+function.
+.PP
+\fBTcl_FSRenameFile\fR attempts to rename the file or directory given by
+\fIsrcPathPtr\fR to the path name given by \fIdestPathPtr\fR. If the two paths
+given lie in the same filesystem (according to
+\fBTcl_FSGetFileSystemForPath\fR) then that filesystem's
+.QW "rename file"
+function is called (if it is non-NULL). Otherwise the function returns -1
+and sets the \fBerrno\fR global C variable to the
+.QW EXDEV
+POSIX error code (which signifies a
+.QW "cross-domain link" ).
+.PP
+\fBTcl_FSListVolumes\fR calls each filesystem which has a non-NULL
+.QW "list volumes"
+function and asks them to return their list of root volumes. It
+accumulates the return values in a list which is returned to the
+caller (with a reference count of 0).
+.PP
+\fBTcl_FSEvalFileEx\fR reads the file given by \fIpathPtr\fR using
+the encoding identified by \fIencodingName\fR and evaluates
+its contents as a Tcl script. It returns the same information as
+\fBTcl_EvalObjEx\fR.
+If \fIencodingName\fR is NULL, the system encoding is used for
+reading the file contents.
+If the file could not be read then a Tcl error is returned to describe
+why the file could not be read.
+The eofchar for files is
+.QW \e32
+(^Z) for all platforms.
+If you require a
+.QW ^Z
+in code for string comparison, you can use
+.QW \e032
+or
+.QW \eu001a ,
+which will be safely substituted by the Tcl interpreter into
+.QW ^Z .
+\fBTcl_FSEvalFile\fR is a simpler version of
+\fBTcl_FSEvalFileEx\fR that always uses the system encoding
+when reading the file.
+.PP
+\fBTcl_FSLoadFile\fR dynamically loads a binary code file into memory and
+returns the addresses of two procedures within that file, if they are
+defined. The appropriate function for the filesystem to which \fIpathPtr\fR
+belongs will be called. If that filesystem does not implement this
+function (most virtual filesystems will not, because of OS limitations
+in dynamically loading binary code), Tcl will attempt to copy the file
+to a temporary directory and load that temporary file.
+.VS 8.6
+\fBTcl_FSUnloadFile\fR reverses the operation, asking for the library
+indicated by the \fIloadHandle\fR to be removed from the process. Note that,
+unlike with the \fBunload\fR command, this does not give the library any
+opportunity to clean up.
+.VE 8.6
+.PP
+Both the above functions return a standard Tcl completion code. If an error
+occurs, an error message is left in the \fIinterp\fR's result.
+.PP
+.VS 8.6
+The token provided via the variable indicated by \fIloadHandlePtr\fR may be
+used with \fBTcl_FindSymbol\fR.
+.VE 8.6
+.PP
+\fBTcl_FSMatchInDirectory\fR is used by the globbing code to search a
+directory for all files which match a given pattern. The appropriate
+function for the filesystem to which \fIpathPtr\fR belongs will be called.
+.PP
+The return value is a standard Tcl result indicating whether an error
+occurred in globbing. Error messages are placed in interp (unless
+interp is NULL, which is allowed), but good results are placed in the
+resultPtr given.
+.PP
+Note that the \fBglob\fR code implements recursive patterns internally, so
+this function will only ever be passed simple patterns, which can be
+matched using the logic of \fBstring match\fR. To handle recursion, Tcl
+will call this function frequently asking only for directories to be
+returned. A special case of being called with a NULL pattern indicates
+that the path needs to be checked only for the correct type.
+.PP
+\fBTcl_FSLink\fR replaces the library version of \fBreadlink\fR, and
+extends it to support the creation of links. The appropriate function
+for the filesystem to which \fIlinkNamePtr\fR belongs will be called.
+.PP
+If the \fItoPtr\fR is NULL, a
+.QW "read link"
+action is performed. The result
+is a Tcl_Obj specifying the contents of the symbolic link given by
+\fIlinkNamePtr\fR, or NULL if the link could not be read. The result is owned
+by the caller, which should call \fBTcl_DecrRefCount\fR when the result is no
+longer needed. If the \fItoPtr\fR is not NULL, Tcl should create a link
+of one of the types passed in in the \fIlinkAction\fR flag. This flag is
+an ORed combination of \fBTCL_CREATE_SYMBOLIC_LINK\fR and \fBTCL_CREATE_HARD_LINK\fR.
+Where a choice exists (i.e.\ more than one flag is passed in), the Tcl
+convention is to prefer symbolic links. When a link is successfully
+created, the return value should be \fItoPtr\fR (which is therefore
+already owned by the caller). If unsuccessful, NULL is returned.
+.PP
+\fBTcl_FSLstat\fR fills the \fITcl_StatBuf\fR structure \fIstatPtr\fR with
+information about the specified file. You do not need any access rights to the
+file to get this information but you need search rights to all
+directories named in the path leading to the file. The \fITcl_StatBuf\fR
+structure includes info regarding device, inode (always 0 on Windows),
+privilege mode, nlink (always 1 on Windows), user id (always 0 on
+Windows), group id (always 0 on Windows), rdev (same as device on
+Windows), size, last access time, last modification time, and
+last metadata change time.
+See \fBPORTABLE STAT RESULT API\fR for a description of how to write
+portable code to allocate and access the \fITcl_StatBuf\fR structure.
+.PP
+If \fIpath\fR exists, \fBTcl_FSLstat\fR returns 0 and the stat structure
+is filled with data. Otherwise, -1 is returned, and no stat info is
+given.
+.PP
+\fBTcl_FSUtime\fR replaces the library version of utime.
+.PP
+This returns 0 on success and -1 on error (as per the \fButime\fR
+documentation). If successful, the function
+will update the
+.QW atime
+and
+.QW mtime
+values of the file given.
+.PP
+\fBTcl_FSFileAttrsGet\fR implements read access for the hookable \fBfile
+attributes\fR subcommand. The appropriate function for the filesystem to
+which \fIpathPtr\fR belongs will be called.
+.PP
+If the result is \fBTCL_OK\fR, then a value was placed in
+\fIobjPtrRef\fR, which
+will only be temporarily valid (unless \fBTcl_IncrRefCount\fR is called).
+.PP
+\fBTcl_FSFileAttrsSet\fR implements write access for the hookable \fBfile
+attributes\fR subcommand. The appropriate function for the filesystem to
+which \fIpathPtr\fR belongs will be called.
+.PP
+\fBTcl_FSFileAttrStrings\fR implements part of the hookable \fBfile
+attributes\fR subcommand. The appropriate function for the filesystem
+to which \fIpathPtr\fR belongs will be called.
+.PP
+The called procedure may either return an array of strings, or may
+instead return NULL and place a Tcl list into the given \fIobjPtrRef\fR. Tcl
+will take that list and first increment its reference count before using it.
+On completion of that use, Tcl will decrement its reference count. Hence if
+the list should be disposed of by Tcl when done, it should have a
+reference count of zero, and if the list should not be disposed of, the
+filesystem should ensure it retains a reference count to the value.
+.PP
+\fBTcl_FSAccess\fR checks whether the process would be allowed to read,
+write or test for existence of the file (or other filesystem object)
+whose name is \fIpathname\fR. If \fIpathname\fR is a symbolic link on Unix,
+then permissions of the file referred by this symbolic link are
+tested.
+.PP
+On success (all requested permissions granted), zero is returned. On
+error (at least one bit in mode asked for a permission that is denied,
+or some other error occurred), -1 is returned.
+.PP
+\fBTcl_FSStat\fR fills the \fITcl_StatBuf\fR structure \fIstatPtr\fR with
+information about the specified file. You do not need any access rights to the
+file to get this information but you need search rights to all
+directories named in the path leading to the file. The \fITcl_StatBuf\fR
+structure includes info regarding device, inode (always 0 on Windows),
+privilege mode, nlink (always 1 on Windows), user id (always 0 on
+Windows), group id (always 0 on Windows), rdev (same as device on
+Windows), size, last access time, last modification time, and
+last metadata change time.
+See \fBPORTABLE STAT RESULT API\fR for a description of how to write
+portable code to allocate and access the \fITcl_StatBuf\fR structure.
+.PP
+If \fIpath\fR exists, \fBTcl_FSStat\fR returns 0 and the stat structure
+is filled with data. Otherwise, -1 is returned, and no stat info is
+given.
+.PP
+\fBTcl_FSOpenFileChannel\fR opens a file specified by \fIpathPtr\fR and
+returns a channel handle that can be used to perform input and output on
+the file. This API is modeled after the \fBfopen\fR procedure of
+the Unix standard I/O library.
+The syntax and meaning of all arguments is similar to those
+given in the Tcl \fBopen\fR command when opening a file.
+If an error occurs while opening the channel, \fBTcl_FSOpenFileChannel\fR
+returns NULL and records a POSIX error code that can be
+retrieved with \fBTcl_GetErrno\fR.
+In addition, if \fIinterp\fR is non-NULL, \fBTcl_FSOpenFileChannel\fR
+leaves an error message in \fIinterp\fR's result after any error.
+.PP
+The newly created channel is not registered in the supplied interpreter; to
+register it, use \fBTcl_RegisterChannel\fR.
+If one of the standard channels, \fBstdin\fR, \fBstdout\fR or \fBstderr\fR was
+previously closed, the act of creating the new channel also assigns it as a
+replacement for the standard channel.
+.PP
+\fBTcl_FSGetCwd\fR replaces the library version of \fBgetcwd\fR.
+.PP
+It returns the Tcl library's current working directory. This may be
+different to the native platform's working directory, which happens when
+the current working directory is not in the native filesystem.
+.PP
+The result is a pointer to a Tcl_Obj specifying the current directory,
+or NULL if the current directory could not be determined. If NULL is
+returned, an error message is left in the \fIinterp\fR's result.
+.PP
+The result already has its reference count incremented for the caller. When
+it is no longer needed, that reference count should be decremented. This is
+needed for thread-safety purposes, to allow multiple threads to access
+this and related functions, while ensuring the results are always
+valid.
+.PP
+\fBTcl_FSChdir\fR replaces the library version of \fBchdir\fR. The path is
+normalized and then passed to the filesystem which claims it. If that
+filesystem does not implement this function, Tcl will fallback to a
+combination of \fBstat\fR and \fBaccess\fR to check whether the directory
+exists and has appropriate permissions.
+.PP
+For results, see \fBchdir\fR documentation. If successful, we keep a
+record of the successful path in \fIcwdPathPtr\fR for subsequent calls to
+\fBTcl_FSGetCwd\fR.
+.PP
+\fBTcl_FSPathSeparator\fR returns the separator character to be used for
+most specific element of the path specified by \fIpathPtr\fR (i.e.\ the last
+part of the path).
+.PP
+The separator is returned as a Tcl_Obj containing a string of length
+1. If the path is invalid, NULL is returned.
+.PP
+\fBTcl_FSJoinPath\fR takes the given Tcl_Obj, which must be a valid
+list (which is allowed to have a reference count of zero), and returns the path
+value given by considering the first \fIelements\fR elements as valid path
+segments (each path segment may be a complete path, a partial path or
+just a single possible directory or file name). If any path segment is
+actually an absolute path, then all prior path segments are discarded.
+If \fIelements\fR is less than 0, we use the entire list.
+.PP
+It is possible that the returned value is actually an element
+of the given list, so the caller should be careful to increment the
+reference count of the result before freeing the list.
+.PP
+The returned value, typically with a reference count of zero (but it
+could be shared
+under some conditions), contains the joined path. The caller must
+add a reference count to the value before using it. In particular, the
+returned value could be an element of the given list, so freeing the
+list might free the value prematurely if no reference count has been taken.
+If the number of elements is zero, then the returned value will be
+an empty-string Tcl_Obj.
+.PP
+\fBTcl_FSSplitPath\fR takes the given Tcl_Obj, which should be a valid path,
+and returns a Tcl list value containing each segment of that path as
+an element.
+It returns a list value with a reference count of zero. If the
+passed in \fIlenPtr\fR is non-NULL, the variable it points to will be
+updated to contain the number of elements in the returned list.
+.PP
+\fBTcl_FSEqualPaths\fR tests whether the two paths given represent the same
+filesystem object.
+It returns 1 if the paths are equal, and 0 if they are different. If
+either path is NULL, 0 is always returned.
+.PP
+\fBTcl_FSGetNormalizedPath\fR this important function attempts to extract
+from the given Tcl_Obj a unique normalized path representation, whose
+string value can be used as a unique identifier for the file.
+.PP
+It returns the normalized path value, owned by Tcl, or NULL if the path
+was invalid or could otherwise not be successfully converted.
+Extraction of absolute, normalized paths is very efficient (because the
+filesystem operates on these representations internally), although the
+result when the filesystem contains numerous symbolic links may not be
+the most user-friendly version of a path. The return value is owned by
+Tcl and has a lifetime equivalent to that of the \fIpathPtr\fR passed in
+(unless that is a relative path, in which case the normalized path
+value may be freed any time the cwd changes) - the caller can of
+course increment the reference count if it wishes to maintain a copy for longer.
+.PP
+\fBTcl_FSJoinToPath\fR takes the given value, which should usually be a
+valid path or NULL, and joins onto it the array of paths segments
+given.
+.PP
+Returns a value, typically with reference count of zero (but it could be shared
+under some conditions), containing the joined path. The caller must
+add a reference count to the value before using it. If any of the values
+passed into this function (\fIpathPtr\fR or \fIpath\fR elements) have
+a reference count
+of zero, they will be freed when this function returns.
+.PP
+\fBTcl_FSConvertToPathType\fR tries to convert the given Tcl_Obj to a valid
+Tcl path type, taking account of the fact that the cwd may have changed
+even if this value is already supposedly of the correct type.
+The filename may begin with
+.QW ~
+(to indicate current user's home directory) or
+.QW ~<user>
+(to indicate any user's home directory).
+.PP
+If the conversion succeeds (i.e.\ the value is a valid path in one of
+the current filesystems), then \fBTCL_OK\fR is returned. Otherwise
+\fBTCL_ERROR\fR is returned, and an error message may
+be left in the interpreter.
+.PP
+\fBTcl_FSGetInternalRep\fR extracts the internal representation of a given
+path value, in the given filesystem. If the path value belongs to a
+different filesystem, we return NULL. If the internal representation is
+currently NULL, we attempt to generate it, by calling the filesystem's
+\fBTcl_FSCreateInternalRepProc\fR.
+.PP
+Returns NULL or a valid internal path representation. This internal
+representation is cached, so that repeated calls to this function will
+not require additional conversions.
+.PP
+\fBTcl_FSGetTranslatedPath\fR attempts to extract the translated path
+from the given Tcl_Obj.
+.PP
+If the translation succeeds (i.e.\ the value is a valid path), then it is
+returned. Otherwise NULL will be returned, and an error message may be
+left in the interpreter. A
+.QW translated
+path is one which contains no
+.QW ~
+or
+.QW ~user
+sequences (these have been expanded to their current
+representation in the filesystem). The value returned is owned by the
+caller, which must store it or call \fBTcl_DecrRefCount\fR to ensure memory is
+freed. This function is of little practical use, and
+\fBTcl_FSGetNormalizedPath\fR or \fBTcl_FSGetNativePath\fR are usually
+better functions to use for most purposes.
+.PP
+\fBTcl_FSGetTranslatedStringPath\fR does the same as
+\fBTcl_FSGetTranslatedPath\fR, but returns a character string or NULL.
+The string returned is dynamically allocated and owned by the caller,
+which must store it or call \fBckfree\fR to ensure it is freed. Again,
+\fBTcl_FSGetNormalizedPath\fR or \fBTcl_FSGetNativePath\fR are usually
+better functions to use for most purposes.
+.PP
+\fBTcl_FSNewNativePath\fR performs something like the reverse of the
+usual obj->path->nativerep conversions. If some code retrieves a path
+in native form (from, e.g.\ \fBreadlink\fR or a native dialog), and that path
+is to be used at the Tcl level, then calling this function is an
+efficient way of creating the appropriate path value type.
+.PP
+The resulting value is a pure
+.QW path
+value, which will only receive
+a UTF-8 string representation if that is required by some Tcl code.
+.PP
+\fBTcl_FSGetNativePath\fR is for use by the Win/Unix native
+filesystems, so that they can easily retrieve the native (char* or
+TCHAR*) representation of a path. This function is a convenience
+wrapper around \fBTcl_FSGetInternalRep\fR. It may be desirable in the
+future to have non-string-based native representations (for example,
+on MacOSX, a representation using a fileSpec of FSRef structure would
+probably be more efficient). On Windows a full Unicode representation
+would allow for paths of unlimited length. Currently the representation
+is simply a character string which may contain either the relative path
+or a complete, absolute normalized path in the native encoding (complex
+conditions dictate which of these will be provided, so neither can be
+relied upon, unless the path is known to be absolute). If you need a
+native path which must be absolute, then you should ask for the native
+version of a normalized path. If for some reason a non-absolute,
+non-normalized version of the path is needed, that must be constructed
+separately (e.g.\ using \fBTcl_FSGetTranslatedPath\fR).
+.PP
+The native representation is cached so that repeated calls to this
+function will not require additional conversions. The return value is
+owned by Tcl and has a lifetime equivalent to that of the \fIpathPtr\fR
+passed in (unless that is a relative path, in which case the native
+representation may be freed any time the cwd changes).
+.PP
+\fBTcl_FSFileSystemInfo\fR returns a list of two elements. The first
+element is the name of the filesystem (e.g.
+.QW native ,
+.QW vfs ,
+.QW zip ,
+or
+.QW prowrap ,
+perhaps), and the second is the particular type of the
+given path within that filesystem (which is filesystem dependent). The
+second element may be empty if the filesystem does not provide a
+further categorization of files.
+.PP
+A valid list value is returned, unless the path value is not
+recognized, when NULL will be returned.
+.PP
+\fBTcl_FSGetFileSystemForPath\fR returns a pointer to the
+\fBTcl_Filesystem\fR which accepts this path as valid.
+.PP
+If no filesystem will accept the path, NULL is returned.
+.PP
+\fBTcl_FSGetPathType\fR determines whether the given path is relative
+to the current directory, relative to the current volume, or
+absolute.
+.PP
+It returns one of \fBTCL_PATH_ABSOLUTE\fR, \fBTCL_PATH_RELATIVE\fR, or
+\fBTCL_PATH_VOLUME_RELATIVE\fR
+.SS "PORTABLE STAT RESULT API"
+.PP
+\fBTcl_AllocStatBuf\fR allocates a \fITcl_StatBuf\fR on the system heap (which
+may be deallocated by being passed to \fBckfree\fR). This allows extensions to
+invoke \fBTcl_FSStat\fR and \fBTcl_FSLstat\fR without being dependent on the
+size of the buffer. That in turn depends on the flags used to build Tcl.
+.PP
+.VS 8.6
+The portable fields of a \fITcl_StatBuf\fR may be read using the following
+functions, each of which returns the value of the corresponding field listed
+in the table below. Note that on some platforms there may be other fields in
+the \fITcl_StatBuf\fR as it is an alias for a suitable system structure, but
+only the portable ones are made available here. See your system documentation
+for a full description of these fields.
+.DS
+.ta \w'\fBTcl_GetModificationTimeFromStat\fR\0\0\0\0'u
+\fIAccess Function\fR	\fIField\fR
+ \fBTcl_GetFSDeviceFromStat\fR	 st_dev
+ \fBTcl_GetFSInodeFromStat\fR	 st_ino
+ \fBTcl_GetModeFromStat\fR	 st_mode
+ \fBTcl_GetLinkCountFromStat\fR	 st_nlink
+ \fBTcl_GetUserIdFromStat\fR	 st_uid
+ \fBTcl_GetGroupIdFromStat\fR	 st_gid
+ \fBTcl_GetDeviceTypeFromStat\fR	 st_rdev
+ \fBTcl_GetAccessTimeFromStat\fR	 st_atime
+ \fBTcl_GetModificationTimeFromStat\fR	 st_mtime
+ \fBTcl_GetChangeTimeFromStat\fR	 st_ctime
+ \fBTcl_GetSizeFromStat\fR	 st_size
+ \fBTcl_GetBlocksFromStat\fR	 st_blocks
+ \fBTcl_GetBlockSizeFromStat\fR	 st_blksize
+.DE
+.VE 8.6
+.SH "THE VIRTUAL FILESYSTEM API"
+.PP
+A filesystem provides a \fBTcl_Filesystem\fR structure that contains
+pointers to functions that implement the various operations on a
+filesystem; these operations are invoked as needed by the generic
+layer, which generally occurs through the functions listed above.
+.PP
+The \fBTcl_Filesystem\fR structures are manipulated using the following
+methods.
+.PP
+\fBTcl_FSRegister\fR takes a pointer to a filesystem structure and an
+optional piece of data to associated with that filesystem. On calling
+this function, Tcl will attach the filesystem to the list of known
+filesystems, and it will become fully functional immediately. Tcl does
+not check if the same filesystem is registered multiple times (and in
+general that is not a good thing to do). \fBTCL_OK\fR will be returned.
+.PP
+\fBTcl_FSUnregister\fR removes the given filesystem structure from
+the list of known filesystems, if it is known, and returns \fBTCL_OK\fR. If
+the filesystem is not currently registered, \fBTCL_ERROR\fR is returned.
+.PP
+\fBTcl_FSData\fR will return the ClientData associated with the given
+filesystem, if that filesystem is registered. Otherwise it will
+return NULL.
+.PP
+\fBTcl_FSMountsChanged\fR is used to inform the Tcl's core that
+the set of mount points for the given (already registered) filesystem
+have changed, and that cached file representations may therefore no
+longer be correct.
+.SS "THE TCL_FILESYSTEM STRUCTURE"
+.PP
+The \fBTcl_Filesystem\fR structure contains the following fields:
+.PP
+.CS
+typedef struct Tcl_Filesystem {
+    const char *\fItypeName\fR;
+    int \fIstructureLength\fR;
+    Tcl_FSVersion \fIversion\fR;
+    Tcl_FSPathInFilesystemProc *\fIpathInFilesystemProc\fR;
+    Tcl_FSDupInternalRepProc *\fIdupInternalRepProc\fR;
+    Tcl_FSFreeInternalRepProc *\fIfreeInternalRepProc\fR;
+    Tcl_FSInternalToNormalizedProc *\fIinternalToNormalizedProc\fR;
+    Tcl_FSCreateInternalRepProc *\fIcreateInternalRepProc\fR;
+    Tcl_FSNormalizePathProc *\fInormalizePathProc\fR;
+    Tcl_FSFilesystemPathTypeProc *\fIfilesystemPathTypeProc\fR;
+    Tcl_FSFilesystemSeparatorProc *\fIfilesystemSeparatorProc\fR;
+    Tcl_FSStatProc *\fIstatProc\fR;
+    Tcl_FSAccessProc *\fIaccessProc\fR;
+    Tcl_FSOpenFileChannelProc *\fIopenFileChannelProc\fR;
+    Tcl_FSMatchInDirectoryProc *\fImatchInDirectoryProc\fR;
+    Tcl_FSUtimeProc *\fIutimeProc\fR;
+    Tcl_FSLinkProc *\fIlinkProc\fR;
+    Tcl_FSListVolumesProc *\fIlistVolumesProc\fR;
+    Tcl_FSFileAttrStringsProc *\fIfileAttrStringsProc\fR;
+    Tcl_FSFileAttrsGetProc *\fIfileAttrsGetProc\fR;
+    Tcl_FSFileAttrsSetProc *\fIfileAttrsSetProc\fR;
+    Tcl_FSCreateDirectoryProc *\fIcreateDirectoryProc\fR;
+    Tcl_FSRemoveDirectoryProc *\fIremoveDirectoryProc\fR;
+    Tcl_FSDeleteFileProc *\fIdeleteFileProc\fR;
+    Tcl_FSCopyFileProc *\fIcopyFileProc\fR;
+    Tcl_FSRenameFileProc *\fIrenameFileProc\fR;
+    Tcl_FSCopyDirectoryProc *\fIcopyDirectoryProc\fR;
+    Tcl_FSLstatProc *\fIlstatProc\fR;
+    Tcl_FSLoadFileProc *\fIloadFileProc\fR;
+    Tcl_FSGetCwdProc *\fIgetCwdProc\fR;
+    Tcl_FSChdirProc *\fIchdirProc\fR;
+} \fBTcl_Filesystem\fR;
+.CE
+.PP
+Except for the first three fields in this structure which contain
+simple data elements, all entries contain addresses of functions called
+by the generic filesystem layer to perform the complete range of
+filesystem related actions.
+.PP
+The many functions in this structure are broken down into three
+categories: infrastructure functions (almost all of which must be
+implemented), operational functions (which must be implemented if a
+complete filesystem is provided), and efficiency functions (which need
+only be implemented if they can be done so efficiently, or if they have
+side-effects which are required by the filesystem; Tcl has less
+efficient emulations it can fall back on). It is important to note
+that, in the current version of Tcl, most of these fallbacks are only
+used to handle commands initiated in Tcl, not in C. What this means is,
+that if a \fBfile rename\fR command is issued in Tcl, and the relevant
+filesystem(s) do not implement their \fITcl_FSRenameFileProc\fR, Tcl's
+core will instead fallback on a combination of other filesystem
+functions (it will use \fITcl_FSCopyFileProc\fR followed by
+\fITcl_FSDeleteFileProc\fR, and if \fITcl_FSCopyFileProc\fR is not
+implemented there is a further fallback). However, if a
+\fITcl_FSRenameFileProc\fR command is issued at the C level, no such
+fallbacks occur. This is true except for the last four entries in the
+filesystem table (\fBlstat\fR, \fBload\fR, \fBgetcwd\fR and \fBchdir\fR)
+for which fallbacks do in fact occur at the C level.
+.PP
+Any functions which take path names in Tcl_Obj form take
+those names in UTF\-8 form. The filesystem infrastructure API is
+designed to support efficient, cached conversion of these UTF\-8 paths
+to other native representations.
+.SS "EXAMPLE FILESYSTEM DEFINITION"
+.PP
+Here is the filesystem lookup table used by the
+.QW vfs
+extension which allows filesystem actions to be implemented in Tcl.
+.PP
+.CS
+static Tcl_Filesystem vfsFilesystem = {
+    "tclvfs",
+    sizeof(Tcl_Filesystem),
+    TCL_FILESYSTEM_VERSION_1,
+    &VfsPathInFilesystem,
+    &VfsDupInternalRep,
+    &VfsFreeInternalRep,
+    /* No internal to normalized, since we don't create
+     * any pure 'internal' Tcl_Obj path representations */
+    NULL,
+    /* No create native rep function, since we don't use
+     * it and don't choose to support uses of
+     * Tcl_FSNewNativePath */
+    NULL,
+    /* Normalize path isn't needed - we assume paths only
+     * have one representation */
+    NULL,
+    &VfsFilesystemPathType,
+    &VfsFilesystemSeparator,
+    &VfsStat,
+    &VfsAccess,
+    &VfsOpenFileChannel,
+    &VfsMatchInDirectory,
+    &VfsUtime,
+    /* We choose not to support symbolic links inside our
+     * VFS's */
+    NULL,
+    &VfsListVolumes,
+    &VfsFileAttrStrings,
+    &VfsFileAttrsGet,
+    &VfsFileAttrsSet,
+    &VfsCreateDirectory,
+    &VfsRemoveDirectory,
+    &VfsDeleteFile,
+    /* No copy file; use the core fallback mechanism */
+    NULL,
+    /* No rename file; use the core fallback mechanism */
+    NULL,
+    /* No copy directory; use the core fallback mechanism */
+    NULL,
+    /* Core will use stat for lstat */
+    NULL,
+    /* No load; use the core fallback mechanism */
+    NULL,
+    /* We don't need a getcwd or chdir; the core's own
+     * internal value is suitable */
+    NULL,
+    NULL
+};
+.CE
+.SH "FILESYSTEM INFRASTRUCTURE"
+.PP
+These fields contain basic information about the filesystem structure
+and addresses of functions which are used to associate
+a particular filesystem with a file path, and deal with the internal
+handling of path representations, for example copying and freeing such
+representations.
+.SS TYPENAME
+.PP
+The \fItypeName\fR field contains a null-terminated string that
+identifies the type of the filesystem implemented, e.g.
+.QW native ,
+.QW zip
+or
+.QW vfs .
+.SS "STRUCTURE LENGTH"
+.PP
+The \fIstructureLength\fR field is generally implemented as
+\fIsizeof(Tcl_Filesystem)\fR, and is there to allow easier
+binary backwards compatibility if the size of the structure
+changes in a future Tcl release.
+.SS VERSION
+.PP
+The \fIversion\fR field should be set to \fBTCL_FILESYSTEM_VERSION_1\fR.
+.SS PATHINFILESYSTEMPROC
+.PP
+The \fIpathInFilesystemProc\fR field contains the address of a function
+which is called to determine whether a given path value belongs to this
+filesystem or not. Tcl will only call the rest of the filesystem
+functions with a path for which this function has returned \fBTCL_OK\fR.
+If the path does not belong, -1 should be returned (the behavior of Tcl
+for any other return value is not defined). If \fBTCL_OK\fR is returned,
+then the optional \fIclientDataPtr\fR output parameter can be used to
+return an internal (filesystem specific) representation of the path,
+which will be cached inside the path value, and may be retrieved
+efficiently by the other filesystem functions. Tcl will simultaneously
+cache the fact that this path belongs to this filesystem. Such caches
+are invalidated when filesystem structures are added or removed from
+Tcl's internal list of known filesystems.
+.PP
+.CS
+typedef int \fBTcl_FSPathInFilesystemProc\fR(
+        Tcl_Obj *\fIpathPtr\fR,
+        ClientData *\fIclientDataPtr\fR);
+.CE
+.SS DUPINTERNALREPPROC
+.PP
+This function makes a copy of a path's internal representation, and is
+called when Tcl needs to duplicate a path value. If NULL, Tcl will
+simply not copy the internal representation, which may then need to be
+regenerated later.
+.PP
+.CS
+typedef ClientData \fBTcl_FSDupInternalRepProc\fR(
+        ClientData \fIclientData\fR);
+.CE
+.SS FREEINTERNALREPPROC
+Free the internal representation. This must be implemented if internal
+representations need freeing (i.e.\ if some memory is allocated when an
+internal representation is generated), but may otherwise be NULL.
+.PP
+.CS
+typedef void \fBTcl_FSFreeInternalRepProc\fR(
+        ClientData \fIclientData\fR);
+.CE
+.SS INTERNALTONORMALIZEDPROC
+.PP
+Function to convert internal representation to a normalized path. Only
+required if the filesystem creates pure path values with no string/path
+representation. The return value is a Tcl value whose string
+representation is the normalized path.
+.PP
+.CS
+typedef Tcl_Obj *\fBTcl_FSInternalToNormalizedProc\fR(
+        ClientData \fIclientData\fR);
+.CE
+.SS CREATEINTERNALREPPROC
+.PP
+Function to take a path value, and calculate an internal
+representation for it, and store that native representation in the
+value. May be NULL if paths have no internal representation, or if
+the \fITcl_FSPathInFilesystemProc\fR for this filesystem always
+immediately creates an internal representation for paths it accepts.
+.PP
+.CS
+typedef ClientData \fBTcl_FSCreateInternalRepProc\fR(
+        Tcl_Obj *\fIpathPtr\fR);
+.CE
+.SS NORMALIZEPATHPROC
+.PP
+Function to normalize a path. Should be implemented for all
+filesystems which can have multiple string representations for the same
+path value. In Tcl, every
+.QW path
+must have a single unique
+.QW normalized
+string representation. Depending on the filesystem,
+there may be more than one unnormalized string representation which
+refers to that path (e.g.\ a relative path, a path with different
+character case if the filesystem is case insensitive, a path contain a
+reference to a home directory such as
+.QW ~ ,
+a path containing symbolic
+links, etc). If the very last component in the path is a symbolic
+link, it should not be converted into the value it points to (but
+its case or other aspects should be made unique). All other path
+components should be converted from symbolic links. This one
+exception is required to agree with Tcl's semantics with \fBfile
+delete\fR, \fBfile rename\fR, \fBfile copy\fR operating on symbolic links.
+This function may be called with \fInextCheckpoint\fR either
+at the beginning of the path (i.e.\ zero), at the end of the path, or
+at any intermediate file separator in the path. It will never
+point to any other arbitrary position in the path. In the last of
+the three valid cases, the implementation can assume that the path
+up to and including the file separator is known and normalized.
+.PP
+.CS
+typedef int \fBTcl_FSNormalizePathProc\fR(
+        Tcl_Interp *\fIinterp\fR,
+        Tcl_Obj *\fIpathPtr\fR,
+        int \fInextCheckpoint\fR);
+.CE
+.SH "FILESYSTEM OPERATIONS"
+.PP
+The fields in this section of the structure contain addresses of
+functions which are called to carry out the basic filesystem
+operations. A filesystem which expects to be used with the complete
+standard Tcl command set must implement all of these. If some of
+them are not implemented, then certain Tcl commands may fail when
+operating on paths within that filesystem. However, in some instances
+this may be desirable (for example, a read-only filesystem should not
+implement the last four functions, and a filesystem which does not
+support symbolic links need not implement the \fBreadlink\fR function,
+etc. The Tcl core expects filesystems to behave in this way).
+.SS FILESYSTEMPATHTYPEPROC
+.PP
+Function to determine the type of a path in this filesystem. May be
+NULL, in which case no type information will be available to users of
+the filesystem. The
+.QW type
+is used only for informational purposes,
+and should be returned as the string representation of the Tcl_Obj
+which is returned. A typical return value might be
+.QW networked ,
+.QW zip
+or
+.QW ftp .
+The Tcl_Obj result is owned by the filesystem and so Tcl will
+increment the reference count of that value if it wishes to retain a reference
+to it.
+.PP
+.CS
+typedef Tcl_Obj *\fBTcl_FSFilesystemPathTypeProc\fR(
+        Tcl_Obj *\fIpathPtr\fR);
+.CE
+.SS FILESYSTEMSEPARATORPROC
+.PP
+Function to return the separator character(s) for this filesystem.
+This need only be implemented if the filesystem wishes to use a
+different separator than the standard string
+.QW / .
+Amongst other
+uses, it is returned by the \fBfile separator\fR command. The
+return value should be a value with reference count of zero.
+.PP
+.CS
+typedef Tcl_Obj *\fBTcl_FSFilesystemSeparatorProc\fR(
+        Tcl_Obj *\fIpathPtr\fR);
+.CE
+.SS STATPROC
+.PP
+Function to process a \fBTcl_FSStat\fR call. Must be implemented for any
+reasonable filesystem, since many Tcl level commands depend crucially
+upon it (e.g.\ \fBfile atime\fR, \fBfile isdirectory\fR, \fBfile size\fR,
+\fBglob\fR).
+.PP
+.CS
+typedef int \fBTcl_FSStatProc\fR(
+        Tcl_Obj *\fIpathPtr\fR,
+        Tcl_StatBuf *\fIstatPtr\fR);
+.CE
+.PP
+The \fBTcl_FSStatProc\fR fills the stat structure \fIstatPtr\fR with
+information about the specified file. You do not need any access
+rights to the file to get this information but you need search rights
+to all directories named in the path leading to the file. The stat
+structure includes info regarding device, inode (always 0 on Windows),
+privilege mode, nlink (always 1 on Windows), user id (always 0 on
+Windows), group id (always 0 on Windows), rdev (same as device on
+Windows), size, last access time, last modification time, and
+last metadata change time.
+.PP
+If the file represented by \fIpathPtr\fR exists, the
+\fBTcl_FSStatProc\fR returns 0 and the stat structure is filled with
+data. Otherwise, -1 is returned, and no stat info is given.
+.SS ACCESSPROC
+.PP
+Function to process a \fBTcl_FSAccess\fR call. Must be implemented for
+any reasonable filesystem, since many Tcl level commands depend crucially
+upon it (e.g.\ \fBfile exists\fR, \fBfile readable\fR).
+.PP
+.CS
+typedef int \fBTcl_FSAccessProc\fR(
+        Tcl_Obj *\fIpathPtr\fR,
+        int \fImode\fR);
+.CE
+.PP
+The \fBTcl_FSAccessProc\fR checks whether the process would be allowed
+to read, write or test for existence of the file (or other filesystem
+object) whose name is in \fIpathPtr\fR. If the pathname refers to a
+symbolic link, then the
+permissions of the file referred by this symbolic link should be tested.
+.PP
+On success (all requested permissions granted), zero is returned. On
+error (at least one bit in mode asked for a permission that is denied,
+or some other  error occurred), -1 is returned.
+.SS OPENFILECHANNELPROC
+.PP
+Function to process a \fBTcl_FSOpenFileChannel\fR call. Must be
+implemented for any reasonable filesystem, since any operations
+which require open or accessing a file's contents will use it
+(e.g.\ \fBopen\fR, \fBencoding\fR, and many Tk commands).
+.PP
+.CS
+typedef Tcl_Channel \fBTcl_FSOpenFileChannelProc\fR(
+        Tcl_Interp *\fIinterp\fR,
+        Tcl_Obj *\fIpathPtr\fR,
+        int \fImode\fR,
+        int \fIpermissions\fR);
+.CE
+.PP
+The \fBTcl_FSOpenFileChannelProc\fR opens a file specified by
+\fIpathPtr\fR and returns a channel handle that can be used to perform
+input and output on the file. This API is modeled after the \fBfopen\fR
+procedure of the Unix standard I/O library. The syntax and meaning of
+all arguments is similar to those given in the Tcl \fBopen\fR command
+when opening a file, where the \fImode\fR argument is a combination of
+the POSIX flags O_RDONLY, O_WRONLY, etc. If an error occurs while
+opening the channel, the \fBTcl_FSOpenFileChannelProc\fR returns NULL and
+records a POSIX error code that can be retrieved with \fBTcl_GetErrno\fR.
+In addition, if \fIinterp\fR is non-NULL, the
+\fBTcl_FSOpenFileChannelProc\fR leaves an error message in \fIinterp\fR's
+result after any error.
+.PP
+The newly created channel must not be registered in the supplied interpreter
+by a \fBTcl_FSOpenFileChannelProc\fR; that task is up to the caller of
+\fBTcl_FSOpenFileChannel\fR (if necessary). If one of
+the standard channels, \fBstdin\fR, \fBstdout\fR or \fBstderr\fR was
+previously closed, the act of creating the new channel also assigns it
+as a replacement for the standard channel.
+.SS MATCHINDIRECTORYPROC
+.PP
+Function to process a \fBTcl_FSMatchInDirectory\fR call. If not
+implemented, then glob and recursive copy functionality will be lacking
+in the filesystem (and this may impact commands like \fBencoding names\fR
+which use glob functionality internally).
+.PP
+.CS
+typedef int \fBTcl_FSMatchInDirectoryProc\fR(
+        Tcl_Interp *\fIinterp\fR,
+        Tcl_Obj *\fIresultPtr\fR,
+        Tcl_Obj *\fIpathPtr\fR,
+        const char *\fIpattern\fR,
+        Tcl_GlobTypeData *\fItypes\fR);
+.CE
+.PP
+The function should return all files or directories (or other filesystem
+objects) which match the given pattern and accord with the \fItypes\fR
+specification given. There are two ways in which this function may be
+called. If \fIpattern\fR is NULL, then \fIpathPtr\fR is a full path
+specification of a single file or directory which should be checked for
+existence and correct type. Otherwise, \fIpathPtr\fR is a directory, the
+contents of which the function should search for files or directories
+which have the correct type. In either case, \fIpathPtr\fR can be
+assumed to be both non-NULL and non-empty. It is not currently
+documented whether \fIpathPtr\fR will have a file separator at its end of
+not, so code should be flexible to both possibilities.
+.PP
+The return value is a standard Tcl result indicating whether an error
+occurred in the matching process. Error messages are placed in
+\fIinterp\fR, unless \fIinterp\fR in NULL in which case no error
+message need be generated; on a \fBTCL_OK\fR result, results should be
+added to the \fIresultPtr\fR value given (which can be assumed to be a
+valid unshared Tcl list). The matches added
+to \fIresultPtr\fR should include any path prefix given in \fIpathPtr\fR
+(this usually means they will be absolute path specifications).
+Note that if no matches are found, that simply leads to an empty
+result; errors are only signaled for actual file or filesystem
+problems which may occur during the matching process.
+.PP
+The \fBTcl_GlobTypeData\fR structure passed in the \fItypes\fR
+parameter contains the following fields:
+.PP
+.CS
+typedef struct Tcl_GlobTypeData {
+    /* Corresponds to bcdpfls as in 'find -t' */
+    int \fItype\fR;
+    /* Corresponds to file permissions */
+    int \fIperm\fR;
+    /* Acceptable mac type */
+    Tcl_Obj *\fImacType\fR;
+    /* Acceptable mac creator */
+    Tcl_Obj *\fImacCreator\fR;
+} \fBTcl_GlobTypeData\fR;
+.CE
+.PP
+There are two specific cases which it is important to handle correctly,
+both when \fItypes\fR is non-NULL. The two cases are when \fItypes->types
+& TCL_GLOB_TYPE_DIR\fR or \fItypes->types & TCL_GLOB_TYPE_MOUNT\fR are
+true (and in particular when the other flags are false). In the first of
+these cases, the function must list the contained directories. Tcl uses
+this to implement recursive globbing, so it is critical that filesystems
+implement directory matching correctly. In the second of these cases,
+with \fBTCL_GLOB_TYPE_MOUNT\fR, the filesystem must list the mount points
+which lie within the given \fIpathPtr\fR (and in this case, \fIpathPtr\fR
+need not lie within the same filesystem - different to all other cases in
+which this function is called). Support for this is critical if Tcl is
+to have seamless transitions between from one filesystem to another.
+.SS UTIMEPROC
+.PP
+Function to process a \fBTcl_FSUtime\fR call. Required to allow setting
+(not reading) of times with \fBfile mtime\fR, \fBfile atime\fR and the
+open-r/open-w/fcopy implementation of \fBfile copy\fR.
+.PP
+.CS
+typedef int \fBTcl_FSUtimeProc\fR(
+        Tcl_Obj *\fIpathPtr\fR,
+        struct utimbuf *\fItval\fR);
+.CE
+.PP
+The access and modification times of the file specified by \fIpathPtr\fR
+should be changed to the values given in the \fItval\fR structure.
+.PP
+The return value should be 0 on success and -1 on an error, as
+with the system \fButime\fR.
+.SS LINKPROC
+.PP
+Function to process a \fBTcl_FSLink\fR call. Should be implemented
+only if the filesystem supports links, and may otherwise be NULL.
+.PP
+.CS
+typedef Tcl_Obj *\fBTcl_FSLinkProc\fR(
+        Tcl_Obj *\fIlinkNamePtr\fR,
+        Tcl_Obj *\fItoPtr\fR,
+        int \fIlinkAction\fR);
+.CE
+.PP
+If \fItoPtr\fR is NULL, the function is being asked to read the
+contents of a link. The result is a Tcl_Obj specifying the contents of
+the link given by \fIlinkNamePtr\fR, or NULL if the link could
+not be read. The result is owned by the caller (and should therefore
+have its ref count incremented before being returned). Any callers
+should call \fBTcl_DecrRefCount\fR on this result when it is no longer needed.
+If \fItoPtr\fR is not NULL, the function should attempt to create a link.
+The result in this case should be \fItoPtr\fR if the link was successful
+and NULL otherwise. In this case the result is not owned by the caller
+(i.e.\ no reference count manipulations on either end are needed). See
+the documentation for \fBTcl_FSLink\fR for the correct interpretation
+of the \fIlinkAction\fR flags.
+.SS LISTVOLUMESPROC
+.PP
+Function to list any filesystem volumes added by this filesystem.
+Should be implemented only if the filesystem adds volumes at the head
+of the filesystem, so that they can be returned by \fBfile volumes\fR.
+.PP
+.CS
+typedef Tcl_Obj *\fBTcl_FSListVolumesProc\fR(void);
+.CE
+.PP
+The result should be a list of volumes added by this filesystem, or
+NULL (or an empty list) if no volumes are provided. The result value
+is considered to be owned by the filesystem (not by Tcl's core), but
+should be given a reference count for Tcl. Tcl will use the contents of the
+list and then decrement that reference count. This allows filesystems to
+choose whether they actually want to retain a
+.QW "master list"
+of volumes
+or not (if not, they generate the list on the fly and pass it to Tcl
+with a reference count of 1 and then forget about the list, if yes, then
+they simply increment the reference count of their master list and pass it
+to Tcl which will copy the contents and then decrement the count back
+to where it was).
+.PP
+Therefore, Tcl considers return values from this proc to be read-only.
+.SS FILEATTRSTRINGSPROC
+.PP
+Function to list all attribute strings which are valid for this
+filesystem. If not implemented the filesystem will not support
+the \fBfile attributes\fR command. This allows arbitrary additional
+information to be attached to files in the filesystem. If it is
+not implemented, there is no need to implement the \fBget\fR and \fBset\fR
+methods.
+.PP
+.CS
+typedef const char *const *\fBTcl_FSFileAttrStringsProc\fR(
+        Tcl_Obj *\fIpathPtr\fR,
+        Tcl_Obj **\fIobjPtrRef\fR);
+.CE
+.PP
+The called function may either return an array of strings, or may
+instead return NULL and place a Tcl list into the given \fIobjPtrRef\fR. Tcl
+will take that list and first increment its reference count before using it.
+On completion of that use, Tcl will decrement its reference count. Hence if
+the list should be disposed of by Tcl when done, it should have a
+reference count of zero, and if the list should not be disposed of, the
+filesystem should ensure it returns a value with a reference count
+of at least one.
+.SS FILEATTRSGETPROC
+.PP
+Function to process a \fBTcl_FSFileAttrsGet\fR call, used by \fBfile
+attributes\fR.
+.PP
+.CS
+typedef int \fBTcl_FSFileAttrsGetProc\fR(
+        Tcl_Interp *\fIinterp\fR,
+        int \fIindex\fR,
+        Tcl_Obj *\fIpathPtr\fR,
+        Tcl_Obj **\fIobjPtrRef\fR);
+.CE
+.PP
+Returns a standard Tcl return code. The attribute value retrieved,
+which corresponds to the \fIindex\fR'th element in the list returned by
+the \fBTcl_FSFileAttrStringsProc\fR, is a Tcl_Obj placed in \fIobjPtrRef\fR (if
+\fBTCL_OK\fR was returned) and is likely to have a reference count of zero. Either
+way we must either store it somewhere (e.g.\ the Tcl result), or
+Incr/Decr its reference count to ensure it is properly freed.
+.SS FILEATTRSSETPROC
+.PP
+Function to process a \fBTcl_FSFileAttrsSet\fR call, used by \fBfile
+attributes\fR. If the filesystem is read-only, there is no need
+to implement this.
+.PP
+.CS
+typedef int \fBTcl_FSFileAttrsSetProc\fR(
+        Tcl_Interp *\fIinterp\fR,
+        int \fIindex\fR,
+        Tcl_Obj *\fIpathPtr\fR,
+        Tcl_Obj *\fIobjPtr\fR);
+.CE
+.PP
+The attribute value of the \fIindex\fR'th element in the list returned by
+the Tcl_FSFileAttrStringsProc should be set to the \fIobjPtr\fR given.
+.SS CREATEDIRECTORYPROC
+.PP
+Function to process a \fBTcl_FSCreateDirectory\fR call. Should be
+implemented unless the FS is read-only.
+.PP
+.CS
+typedef int \fBTcl_FSCreateDirectoryProc\fR(
+        Tcl_Obj *\fIpathPtr\fR);
+.CE
+.PP
+The return value is a standard Tcl result indicating whether an error
+occurred in the process. If successful, a new directory should have
+been added to the filesystem in the location specified by
+\fIpathPtr\fR.
+.SS REMOVEDIRECTORYPROC
+.PP
+Function to process a \fBTcl_FSRemoveDirectory\fR call. Should be
+implemented unless the FS is read-only.
+.PP
+.CS
+typedef int \fBTcl_FSRemoveDirectoryProc\fR(
+        Tcl_Obj *\fIpathPtr\fR,
+        int \fIrecursive\fR,
+        Tcl_Obj **\fIerrorPtr\fR);
+.CE
+.PP
+The return value is a standard Tcl result indicating whether an error
+occurred in the process. If successful, the directory specified by
+\fIpathPtr\fR should have been removed from the filesystem. If the
+\fIrecursive\fR flag is given, then a non-empty directory should be
+deleted without error. If this flag is not given, then and the
+directory is non-empty a POSIX
+.QW EEXIST
+error should be signaled. If an
+error does occur, the name of the file or directory which caused the
+error should be placed in \fIerrorPtr\fR.
+.SS DELETEFILEPROC
+.PP
+Function to process a \fBTcl_FSDeleteFile\fR call. Should be implemented
+unless the FS is read-only.
+.PP
+.CS
+typedef int \fBTcl_FSDeleteFileProc\fR(
+        Tcl_Obj *\fIpathPtr\fR);
+.CE
+.PP
+The return value is a standard Tcl result indicating whether an error
+occurred in the process. If successful, the file specified by
+\fIpathPtr\fR should have been removed from the filesystem. Note that,
+if the filesystem supports symbolic links, Tcl will always call this
+function and not Tcl_FSRemoveDirectoryProc when needed to delete them
+(even if they are symbolic links to directories).
+.SH "FILESYSTEM EFFICIENCY"
+.PP
+These functions need not be implemented for a particular filesystem
+because the core has a fallback implementation available. See each
+individual description for the consequences of leaving the field NULL.
+.SS LSTATPROC
+.PP
+Function to process a \fBTcl_FSLstat\fR call. If not implemented, Tcl
+will attempt to use the \fIstatProc\fR defined above instead. Therefore
+it need only be implemented if a filesystem can differentiate between
+\fBstat\fR and \fBlstat\fR calls.
+.PP
+.CS
+typedef int \fBTcl_FSLstatProc\fR(
+        Tcl_Obj *\fIpathPtr\fR,
+        Tcl_StatBuf *\fIstatPtr\fR);
+.CE
+.PP
+The behavior of this function is very similar to that of the
+\fBTcl_FSStatProc\fR defined above, except that if it is applied
+to a symbolic link, it returns information about the link, not
+about the target file.
+.SS COPYFILEPROC
+.PP
+Function to process a \fBTcl_FSCopyFile\fR call. If not implemented Tcl
+will fall back on \fBopen\fR-r, \fBopen\fR-w and \fBfcopy\fR as a
+copying mechanism.
+Therefore it need only be implemented if the filesystem can perform
+that action more efficiently.
+.PP
+.CS
+typedef int \fBTcl_FSCopyFileProc\fR(
+        Tcl_Obj *\fIsrcPathPtr\fR,
+        Tcl_Obj *\fIdestPathPtr\fR);
+.CE
+.PP
+The return value is a standard Tcl result indicating whether an error
+occurred in the copying process. Note that, \fIdestPathPtr\fR is the
+name of the file which should become the copy of \fIsrcPathPtr\fR. It
+is never the name of a directory into which \fIsrcPathPtr\fR could be
+copied (i.e.\ the function is much simpler than the Tcl level \fBfile
+copy\fR subcommand). Note that,
+if the filesystem supports symbolic links, Tcl will always call this
+function and not \fIcopyDirectoryProc\fR when needed to copy them
+(even if they are symbolic links to directories). Finally, if the
+filesystem determines it cannot support the \fBfile copy\fR action,
+calling \fBTcl_SetErrno(EXDEV)\fR and returning a non-\fBTCL_OK\fR
+result will tell Tcl to use its standard fallback mechanisms.
+.SS RENAMEFILEPROC
+.PP
+Function to process a \fBTcl_FSRenameFile\fR call. If not implemented,
+Tcl will fall back on a copy and delete mechanism. Therefore it need
+only be implemented if the filesystem can perform that action more
+efficiently.
+.PP
+.CS
+typedef int \fBTcl_FSRenameFileProc\fR(
+        Tcl_Obj *\fIsrcPathPtr\fR,
+        Tcl_Obj *\fIdestPathPtr\fR);
+.CE
+.PP
+The return value is a standard Tcl result indicating whether an error
+occurred in the renaming process. If the
+filesystem determines it cannot support the \fBfile rename\fR action,
+calling \fBTcl_SetErrno(EXDEV)\fR and returning a non-\fBTCL_OK\fR
+result will tell Tcl to use its standard fallback mechanisms.
+.SS COPYDIRECTORYPROC
+.PP
+Function to process a \fBTcl_FSCopyDirectory\fR call. If not
+implemented, Tcl will fall back on a recursive \fBfile mkdir\fR, \fBfile copy\fR
+mechanism. Therefore it need only be implemented if the filesystem can
+perform that action more efficiently.
+.PP
+.CS
+typedef int \fBTcl_FSCopyDirectoryProc\fR(
+        Tcl_Obj *\fIsrcPathPtr\fR,
+        Tcl_Obj *\fIdestPathPtr\fR,
+        Tcl_Obj **\fIerrorPtr\fR);
+.CE
+.PP
+The return value is a standard Tcl result indicating whether an error
+occurred in the copying process. If an error does occur, the name of
+the file or directory which caused the error should be placed in
+\fIerrorPtr\fR. Note that, \fIdestPathPtr\fR is the name of the
+directory-name which should become the mirror-image of
+\fIsrcPathPtr\fR. It is not the name of a directory into which
+\fIsrcPathPtr\fR should be copied (i.e.\ the function is much simpler
+than the Tcl level \fBfile copy\fR subcommand). Finally, if the
+filesystem determines it cannot support the directory copy action,
+calling \fBTcl_SetErrno(EXDEV)\fR and returning a non-\fBTCL_OK\fR
+result will tell Tcl to use its standard fallback mechanisms.
+.SS LOADFILEPROC
+.PP
+Function to process a \fBTcl_FSLoadFile\fR call. If not implemented, Tcl
+will fall back on a copy to native-temp followed by a \fBTcl_FSLoadFile\fR on
+that temporary copy. Therefore it need only be implemented if the
+filesystem can load code directly, or it can be implemented simply to
+return \fBTCL_ERROR\fR to disable load functionality in this filesystem
+entirely.
+.PP
+.CS
+typedef int \fBTcl_FSLoadFileProc\fR(
+        Tcl_Interp *\fIinterp\fR,
+        Tcl_Obj *\fIpathPtr\fR,
+        Tcl_LoadHandle *\fIhandlePtr\fR,
+        Tcl_FSUnloadFileProc *\fIunloadProcPtr\fR);
+.CE
+.PP
+Returns a standard Tcl completion code. If an error occurs, an error
+message is left in the \fIinterp\fR's result. The function dynamically loads a
+binary code file into memory. On a successful load, the \fIhandlePtr\fR
+should be filled with a token for the dynamically loaded file, and the
+\fIunloadProcPtr\fR should be filled in with the address of a procedure.
+The unload procedure will be called with the given \fBTcl_LoadHandle\fR as its
+only parameter when Tcl needs to unload the file. For example, for the
+native filesystem, the \fBTcl_LoadHandle\fR returned is currently a token
+which can be used in the private \fBTclpFindSymbol\fR to access functions
+in the new code. Each filesystem is free to define the
+\fBTcl_LoadHandle\fR as it requires. Finally, if the
+filesystem determines it cannot support the file load action,
+calling \fBTcl_SetErrno(EXDEV)\fR and returning a non-\fBTCL_OK\fR
+result will tell Tcl to use its standard fallback mechanisms.
+.SS UNLOADFILEPROC
+.PP
+Function to unload a previously successfully loaded file. If load was
+implemented, then this should also be implemented, if there is any
+cleanup action required.
+.PP
+.CS
+typedef void \fBTcl_FSUnloadFileProc\fR(
+        Tcl_LoadHandle \fIloadHandle\fR);
+.CE
+.SS GETCWDPROC
+.PP
+Function to process a \fBTcl_FSGetCwd\fR call. Most filesystems need not
+implement this. It will usually only be called once, if \fBgetcwd\fR is
+called before \fBchdir\fR. May be NULL.
+.PP
+.CS
+typedef Tcl_Obj *\fBTcl_FSGetCwdProc\fR(
+        Tcl_Interp *\fIinterp\fR);
+.CE
+.PP
+If the filesystem supports a native notion of a current working
+directory (which might perhaps change independent of Tcl), this
+function should return that cwd as the result, or NULL if the current
+directory could not be determined (e.g.\ the user does not have
+appropriate permissions on the cwd directory). If NULL is returned, an
+error message is left in the \fIinterp\fR's result.
+.SS CHDIRPROC
+.PP
+Function to process a \fBTcl_FSChdir\fR call. If filesystems do not
+implement this, it will be emulated by a series of directory access
+checks. Otherwise, virtual filesystems which do implement it need only
+respond with a positive return result if the \fIpathPtr\fR is a valid,
+accessible directory in their filesystem. They need not remember the
+result, since that will be automatically remembered for use by
+\fBTcl_FSGetCwd\fR.
+Real filesystems should carry out the correct action (i.e.\ call the
+correct system \fBchdir\fR API).
+.PP
+.CS
+typedef int \fBTcl_FSChdirProc\fR(
+        Tcl_Obj *\fIpathPtr\fR);
+.CE
+.PP
+The \fBTcl_FSChdirProc\fR changes the applications current working
+directory to the value specified in \fIpathPtr\fR. The function returns
+-1 on error or 0 on success.
+.SH "SEE ALSO"
+cd(n), file(n), filename(n), load(n), open(n), pwd(n), source(n), unload(n)
+.SH KEYWORDS
+stat, access, filesystem, vfs, virtual filesystem
diff --git a/doc/FindExec.3 b/doc/FindExec.3
new file mode 100644
index 0000000..b01315c
--- /dev/null
+++ b/doc/FindExec.3
@@ -0,0 +1,63 @@
+'\"
+'\" Copyright (c) 1995-1996 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\" 
+.TH Tcl_FindExecutable 3 8.1 Tcl "Tcl Library Procedures"
+.so man.macros
+.BS
+.SH NAME
+Tcl_FindExecutable, Tcl_GetNameOfExecutable \- identify or return the name of the binary file containing the application
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+void
+\fBTcl_FindExecutable\fR(\fIargv0\fR)
+.sp
+const char *
+\fBTcl_GetNameOfExecutable\fR()
+.SH ARGUMENTS
+.AS char *argv0
+.AP char *argv0 in
+The first command-line argument to the program, which gives the
+application's name.
+.BE
+
+.SH DESCRIPTION
+.PP
+The \fBTcl_FindExecutable\fR procedure computes the full path name of
+the executable file from which the application was invoked and saves
+it for Tcl's internal use.
+The executable's path name is needed for several purposes in
+Tcl.  For example, it is needed on some platforms in the
+implementation of the \fBload\fR command.
+It is also returned by the \fBinfo nameofexecutable\fR command.
+.PP
+On UNIX platforms this procedure is typically invoked as the very
+first thing in the application's main program;  it must be passed
+\fIargv[0]\fR as its argument.  It is important not to change the
+working directory before the invocation.
+\fBTcl_FindExecutable\fR uses \fIargv0\fR
+along with the \fBPATH\fR environment variable to find the
+application's executable, if possible.  If it fails to find
+the binary, then future calls to \fBinfo nameofexecutable\fR
+will return an empty string.
+.PP
+On Windows platforms this procedure is typically invoked as the very
+first thing in the application's main program as well; Its \fIargv[0]\fR
+argument is only used to indicate whether the executable has a stderr
+channel (any non-null value) or not (the value null). If \fBTcl_SetPanicProc\fR
+is never called and no debugger is running, this determines whether
+the panic message is sent to stderr or to a standard system dialog.
+.PP
+\fBTcl_GetNameOfExecutable\fR simply returns a pointer to the
+internal full path name of the executable file as computed by
+\fBTcl_FindExecutable\fR.  This procedure call is the C API
+equivalent to the \fBinfo nameofexecutable\fR command.  NULL
+is returned if the internal full path name has not been
+computed or unknown.
+
+.SH KEYWORDS
+binary, executable file
diff --git a/doc/GetCwd.3 b/doc/GetCwd.3
new file mode 100644
index 0000000..58abcde
--- /dev/null
+++ b/doc/GetCwd.3
@@ -0,0 +1,52 @@
+'\"
+'\" Copyright (c) 1998-1999 Scriptics Corporation
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\" 
+.TH Tcl_GetCwd 3 8.1 Tcl "Tcl Library Procedures"
+.so man.macros
+.BS
+.SH NAME
+Tcl_GetCwd, Tcl_Chdir \- manipulate the current working directory
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+char *
+\fBTcl_GetCwd\fR(\fIinterp\fR, \fIbufferPtr\fR)
+.sp
+int
+\fBTcl_Chdir\fR(\fIpath\fR)
+.SH ARGUMENTS
+.AS Tcl_DString *bufferPtr in/out
+.AP Tcl_Interp *interp in
+Interpreter in which to report an error, if any.
+.AP Tcl_DString *bufferPtr in/out
+This dynamic string is used to store the current working directory.
+At the time of the call it should be uninitialized or free.  The
+caller must eventually call \fBTcl_DStringFree\fR to free up
+anything stored here.
+.AP char *path in
+File path in UTF\-8 format.
+.BE
+
+.SH DESCRIPTION
+.PP
+These procedures may be used to manipulate the current working
+directory for the application.  They provide C\-level access to
+the same functionality as the Tcl \fBpwd\fR command.
+.PP
+\fBTcl_GetCwd\fR returns a pointer to a string specifying the current
+directory, or NULL if the current directory could not be determined.
+If NULL is returned, an error message is left in the \fIinterp\fR's result.
+Storage for the result string is allocated in bufferPtr; the caller
+must call \fBTcl_DStringFree()\fR when the result is no longer needed.
+The format of the path is UTF\-8.
+.PP
+\fBTcl_Chdir\fR changes the applications current working directory to
+the value specified in \fIpath\fR.  The format of the passed in string
+must be UTF\-8.  The function returns -1 on error or 0 on success.
+
+.SH KEYWORDS
+pwd
diff --git a/doc/GetHostName.3 b/doc/GetHostName.3
new file mode 100644
index 0000000..73432d3
--- /dev/null
+++ b/doc/GetHostName.3
@@ -0,0 +1,27 @@
+'\"
+'\" Copyright (c) 1998-2000 by Scriptics Corporation.
+'\" All rights reserved.
+'\"
+.TH Tcl_GetHostName 3 8.3 Tcl "Tcl Library Procedures"
+.so man.macros
+.BS
+.SH NAME
+Tcl_GetHostName \- get the name of the local host
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+const char *
+\fBTcl_GetHostName\fR()
+.BE
+
+.SH DESCRIPTION
+.PP
+\fBTcl_GetHostName\fR is a utility procedure used by some of the
+Tcl commands.  It returns a pointer to a string containing the name
+for the current machine, or an empty string if the name cannot be
+determined.  The string is statically allocated, and the caller must
+not modify of free it.
+.PP
+.SH KEYWORDS
+hostname
diff --git a/doc/GetIndex.3 b/doc/GetIndex.3
new file mode 100644
index 0000000..fc6f40b
--- /dev/null
+++ b/doc/GetIndex.3
@@ -0,0 +1,104 @@
+'\"
+'\" Copyright (c) 1997 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\" 
+.TH Tcl_GetIndexFromObj 3 8.1 Tcl "Tcl Library Procedures"
+.so man.macros
+.BS
+.SH NAME
+Tcl_GetIndexFromObj, Tcl_GetIndexFromObjStruct \- lookup string in table of keywords
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+int
+\fBTcl_GetIndexFromObj\fR(\fIinterp, objPtr, tablePtr, msg, flags,
+indexPtr\fR)
+.sp
+int
+\fBTcl_GetIndexFromObjStruct\fR(\fIinterp, objPtr, structTablePtr, offset,
+                          msg, flags, indexPtr\fR)
+.SH ARGUMENTS
+.AS "const char" *structTablePtr in/out
+.AP Tcl_Interp *interp in
+Interpreter to use for error reporting; if NULL, then no message is
+provided on errors.
+.AP Tcl_Obj *objPtr in/out
+The string value of this value is used to search through \fItablePtr\fR.
+The internal representation is modified to hold the index of the matching
+table entry.
+.AP "const char *const" *tablePtr in
+An array of null-terminated strings.  The end of the array is marked
+by a NULL string pointer.
+Note that references to the \fItablePtr\fR may be retained in the
+internal representation of \fIobjPtr\fR, so this should represent the
+address of a statically-allocated array.
+.AP "const void" *structTablePtr in
+An array of arbitrary type, typically some \fBstruct\fR type.
+The first member of the structure must be a null-terminated string.
+The size of the structure is given by \fIoffset\fR.
+Note that references to the \fIstructTablePtr\fR may be retained in the
+internal representation of \fIobjPtr\fR, so this should represent the
+address of a statically-allocated array of structures.
+.AP int offset in
+The offset to add to structTablePtr to get to the next entry.
+The end of the array is marked by a NULL string pointer.
+.AP "const char" *msg in
+Null-terminated string describing what is being looked up, such as
+\fBoption\fR.  This string is included in error messages.
+.AP int flags in
+OR-ed combination of bits providing additional information for
+operation.  The only bit that is currently defined is \fBTCL_EXACT\fR.
+.AP int *indexPtr out
+The index of the string in \fItablePtr\fR that matches the value of
+\fIobjPtr\fR is returned here.
+.BE
+.SH DESCRIPTION
+.PP
+These procedures provide an efficient way for looking up keywords,
+switch names, option names, and similar things where the literal value of
+a Tcl value must be chosen from a predefined set.
+\fBTcl_GetIndexFromObj\fR compares \fIobjPtr\fR against each of
+the strings in \fItablePtr\fR to find a match.  A match occurs if
+\fIobjPtr\fR's string value is identical to one of the strings in
+\fItablePtr\fR, or if it is a non-empty unique abbreviation
+for exactly one of the strings in \fItablePtr\fR and the
+\fBTCL_EXACT\fR flag was not specified; in either case
+the index of the matching entry is stored at \fI*indexPtr\fR
+and \fBTCL_OK\fR is returned.
+.PP
+If there is no matching entry,
+\fBTCL_ERROR\fR is returned and an error message is left in \fIinterp\fR's
+result if \fIinterp\fR is not NULL.  \fIMsg\fR is included in the
+error message to indicate what was being looked up.  For example,
+if \fImsg\fR is \fBoption\fR the error message will have a form like
+.QW "\fBbad option \N'34'firt\N'34': must be first, second, or third\fR" .
+.PP
+If \fBTcl_GetIndexFromObj\fR completes successfully it modifies the
+internal representation of \fIobjPtr\fR to hold the address of
+the table and the index of the matching entry.  If \fBTcl_GetIndexFromObj\fR
+is invoked again with the same \fIobjPtr\fR and \fItablePtr\fR
+arguments (e.g. during a reinvocation of a Tcl command), it returns
+the matching index immediately without having to redo the lookup
+operation.  Note: \fBTcl_GetIndexFromObj\fR assumes that the entries
+in \fItablePtr\fR are static: they must not change between
+invocations.  If the value of \fIobjPtr\fR is the empty string,
+\fBTcl_GetIndexFromObj\fR will treat it as a non-matching value
+and return \fBTCL_ERROR\fR.
+.PP
+\fBTcl_GetIndexFromObjStruct\fR works just like
+\fBTcl_GetIndexFromObj\fR, except that instead of treating
+\fItablePtr\fR as an array of string pointers, it treats it as a
+pointer to the first string in a series of strings that have
+\fIoffset\fR bytes between them (i.e. that there is a pointer to the
+first array of characters at \fItablePtr\fR, a pointer to the second
+array of characters at \fItablePtr\fR+\fIoffset\fR bytes, etc.)
+This is particularly useful when processing things like
+\fBTk_ConfigurationSpec\fR, whose string keys are in the same place in
+each of several array elements.
+.SH "SEE ALSO"
+prefix(n), Tcl_WrongNumArgs(3)
+.SH KEYWORDS
+index, option, value, table lookup
diff --git a/doc/GetInt.3 b/doc/GetInt.3
new file mode 100644
index 0000000..4e9d636
--- /dev/null
+++ b/doc/GetInt.3
@@ -0,0 +1,86 @@
+'\"
+'\" Copyright (c) 1989-1993 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\" 
+.TH Tcl_GetInt 3 "" Tcl "Tcl Library Procedures"
+.so man.macros
+.BS
+.SH NAME
+Tcl_GetInt, Tcl_GetDouble, Tcl_GetBoolean \- convert from string to integer, double, or boolean
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+int
+\fBTcl_GetInt\fR(\fIinterp, src, intPtr\fR)
+.sp
+int
+\fBTcl_GetDouble\fR(\fIinterp, src, doublePtr\fR)
+.sp
+int
+\fBTcl_GetBoolean\fR(\fIinterp, src, boolPtr\fR)
+.SH ARGUMENTS
+.AS Tcl_Interp *doublePtr out
+.AP Tcl_Interp *interp in
+Interpreter to use for error reporting.
+.AP "const char" *src in
+Textual value to be converted.
+.AP int *intPtr out
+Points to place to store integer value converted from \fIsrc\fR.
+.AP double *doublePtr out
+Points to place to store double-precision floating-point
+value converted from \fIsrc\fR.
+.AP int *boolPtr out
+Points to place to store boolean value (0 or 1) converted from \fIsrc\fR.
+.BE
+
+.SH DESCRIPTION
+.PP
+These procedures convert from strings to integers or double-precision
+floating-point values or booleans (represented as 0- or 1-valued
+integers).  Each of the procedures takes a \fIsrc\fR argument,
+converts it to an internal form of a particular type, and stores
+the converted value at the location indicated by the procedure's
+third argument.  If all goes well, each of the procedures returns
+\fBTCL_OK\fR.  If \fIsrc\fR does not have the proper syntax for the
+desired type then \fBTCL_ERROR\fR is returned, an error message is left
+in the interpreter's result, and nothing is stored at *\fIintPtr\fR
+or *\fIdoublePtr\fR or *\fIboolPtr\fR.
+.PP
+\fBTcl_GetInt\fR expects \fIsrc\fR to consist of a collection
+of integer digits, optionally signed and optionally preceded by
+white space.  If the first two characters of \fIsrc\fR
+after the optional white space and sign are
+.QW 0x
+then \fIsrc\fR is expected to be in hexadecimal form;  otherwise,
+if the first such character is
+.QW 0
+then \fIsrc\fR
+is expected to be in octal form;  otherwise, \fIsrc\fR is
+expected to be in decimal form.
+.PP
+\fBTcl_GetDouble\fR expects \fIsrc\fR to consist of a floating-point
+number, which is:  white space;  a sign; a sequence of digits;  a
+decimal point;  a sequence of digits;  the letter
+.QW e ;
+a signed decimal exponent;  and more white space.
+Any of the fields may be omitted, except that
+the digits either before or after the decimal point must be present
+and if the
+.QW e
+is present then it must be followed by the exponent number.
+.PP
+\fBTcl_GetBoolean\fR expects \fIsrc\fR to specify a boolean
+value.  If \fIsrc\fR is any of \fB0\fR, \fBfalse\fR,
+\fBno\fR, or \fBoff\fR, then \fBTcl_GetBoolean\fR stores a zero
+value at \fI*boolPtr\fR.
+If \fIsrc\fR is any of \fB1\fR, \fBtrue\fR, \fByes\fR, or \fBon\fR,
+then 1 is stored at \fI*boolPtr\fR.
+Any of these values may be abbreviated, and upper-case spellings
+are also acceptable.
+
+.SH KEYWORDS
+boolean, conversion, double, floating-point, integer
diff --git a/doc/GetOpnFl.3 b/doc/GetOpnFl.3
new file mode 100644
index 0000000..86d1b94
--- /dev/null
+++ b/doc/GetOpnFl.3
@@ -0,0 +1,58 @@
+'\"
+'\" Copyright (c) 1996-1997 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\" 
+.TH Tcl_GetOpenFile 3 8.0 Tcl "Tcl Library Procedures"
+.so man.macros
+.BS
+.SH NAME
+Tcl_GetOpenFile \- Return a FILE* for a channel registered in the given interpreter (Unix only)
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+int
+\fBTcl_GetOpenFile\fR(\fIinterp, chanID, write, checkUsage, filePtr\fR)
+.sp
+.SH ARGUMENTS
+.AS Tcl_Interp checkUsage out
+.AP Tcl_Interp *interp in
+Tcl interpreter from which file handle is to be obtained.
+.AP "const char" *chanID in
+String identifying channel, such as \fBstdin\fR or \fBfile4\fR.
+.AP int write in
+Non-zero means the file will be used for writing, zero means it will
+be used for reading.
+.AP int checkUsage in
+If non-zero, then an error will be generated if the file was not opened
+for the access indicated by \fIwrite\fR.
+.AP ClientData *filePtr out
+Points to word in which to store pointer to FILE structure for
+the file given by \fIchanID\fR.
+.BE
+
+.SH DESCRIPTION
+.PP
+\fBTcl_GetOpenFile\fR takes as argument a file identifier of the form
+returned by the \fBopen\fR command and
+returns at \fI*filePtr\fR a pointer to the FILE structure for
+the file.
+The \fIwrite\fR argument indicates whether the FILE pointer will
+be used for reading or writing.
+In some cases, such as a channel that connects to a pipeline of
+subprocesses, different FILE pointers will be returned for reading
+and writing.
+\fBTcl_GetOpenFile\fR normally returns \fBTCL_OK\fR.
+If an error occurs in \fBTcl_GetOpenFile\fR (e.g. \fIchanID\fR did not
+make any sense or \fIcheckUsage\fR was set and the file was not opened
+for the access specified by \fIwrite\fR) then \fBTCL_ERROR\fR is returned
+and the interpreter's result will contain an error message.
+In the current implementation \fIcheckUsage\fR is ignored and consistency
+checks are always performed.
+.PP
+Note that this interface is only supported on the Unix platform.
+
+.SH KEYWORDS
+channel, file handle, permissions, pipeline, read, write
diff --git a/doc/GetStdChan.3 b/doc/GetStdChan.3
new file mode 100644
index 0000000..be0e79f
--- /dev/null
+++ b/doc/GetStdChan.3
@@ -0,0 +1,86 @@
+'\"
+'\" Copyright (c) 1996 by Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH Tcl_GetStdChannel 3 7.5 Tcl "Tcl Library Procedures"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+Tcl_GetStdChannel, Tcl_SetStdChannel \- procedures for retrieving and replacing the standard channels
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+Tcl_Channel
+\fBTcl_GetStdChannel\fR(\fItype\fR)
+.sp
+\fBTcl_SetStdChannel\fR(\fIchannel, type\fR)
+.sp
+.SH ARGUMENTS
+.AS Tcl_Channel channel
+.AP int type in
+The identifier for the standard channel to retrieve or modify.  Must be one of
+\fBTCL_STDIN\fR, \fBTCL_STDOUT\fR, or \fBTCL_STDERR\fR.
+.AP Tcl_Channel channel in
+The channel to use as the new value for the specified standard channel.
+.BE
+
+.SH DESCRIPTION
+.PP
+Tcl defines three special channels that are used by various I/O related
+commands if no other channels are specified.  The standard input channel
+has a channel name of \fBstdin\fR and is used by \fBread\fR and \fBgets\fR.
+The standard output channel is named \fBstdout\fR and is used by
+\fBputs\fR.  The standard error channel is named \fBstderr\fR and is used for
+reporting errors.  In addition, the standard channels are inherited by any
+child processes created using \fBexec\fR or \fBopen\fR in the absence of any
+other redirections.
+.PP
+The standard channels are actually aliases for other normal channels.  The
+current channel associated with a standard channel can be retrieved by calling
+\fBTcl_GetStdChannel\fR with one of
+\fBTCL_STDIN\fR, \fBTCL_STDOUT\fR, or \fBTCL_STDERR\fR as the \fItype\fR.  The
+return value will be a valid channel, or NULL.
+.PP
+A new channel can be set for the standard channel specified by \fItype\fR
+by calling \fBTcl_SetStdChannel\fR with a new channel or NULL in the
+\fIchannel\fR argument.  If the specified channel is closed by a later call to
+\fBTcl_Close\fR, then the corresponding standard channel will automatically be
+set to NULL.
+.PP
+If a non-NULL value for \fIchannel\fR is passed to \fBTcl_SetStdChannel\fR,
+then that same value should be passed to \fBTcl_RegisterChannel\fR, like so:
+.PP
+.CS
+Tcl_RegisterChannel(NULL, channel);
+.CE
+.PP
+This is a workaround for a misfeature in \fBTcl_SetStdChannel\fR that it
+fails to do some reference counting housekeeping.  This misfeature cannot
+be corrected without contradicting the assumptions of some existing
+code that calls \fBTcl_SetStdChannel\fR.
+.PP
+If \fBTcl_GetStdChannel\fR is called before \fBTcl_SetStdChannel\fR, Tcl will
+construct a new channel to wrap the appropriate platform-specific standard
+file handle.  If \fBTcl_SetStdChannel\fR is called before
+\fBTcl_GetStdChannel\fR, then the default channel will not be created.
+.PP
+If one of the standard channels is set to NULL, either by calling
+\fBTcl_SetStdChannel\fR with a NULL \fIchannel\fR argument, or by calling
+\fBTcl_Close\fR on the channel, then the next call to \fBTcl_CreateChannel\fR
+will automatically set the standard channel with the newly created channel.  If
+more than one standard channel is NULL, then the standard channels will be
+assigned starting with standard input, followed by standard output, with
+standard error being last.
+.PP
+See \fBTcl_StandardChannels\fR for a general treatise about standard
+channels and the behavior of the Tcl library with regard to them.
+
+.SH "SEE ALSO"
+Tcl_Close(3), Tcl_CreateChannel(3), Tcl_Main(3), tclsh(1)
+
+.SH KEYWORDS
+standard channel, standard input, standard output, standard error
diff --git a/doc/GetTime.3 b/doc/GetTime.3
new file mode 100644
index 0000000..6b885ee
--- /dev/null
+++ b/doc/GetTime.3
@@ -0,0 +1,109 @@
+'\"
+'\" Copyright (c) 2001 by Kevin B. Kenny <kennykb@acm.org>.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\" 
+.TH Tcl_GetTime 3 8.4 Tcl "Tcl Library Procedures"
+.so man.macros
+.BS
+.SH NAME
+Tcl_GetTime, Tcl_SetTimeProc, Tcl_QueryTimeProc \- get date and time
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+\fBTcl_GetTime\fR(\fItimePtr\fR)
+.sp
+\fBTcl_SetTimeProc\fR(\fIgetProc, scaleProc, clientData\fR)
+.sp
+\fBTcl_QueryTimeProc\fR(\fIgetProcPtr, scaleProcPtr, clientDataPtr\fR)
+.SH ARGUMENTS
+.AS Tcl_GetTimeProc *getProc in
+.AP Tcl_Time *timePtr out
+Points to memory in which to store the date and time information.
+.AP Tcl_GetTimeProc getProc in
+Pointer to handler function replacing \fBTcl_GetTime\fR's access to the OS.
+.AP Tcl_ScaleTimeProc scaleProc in
+Pointer to handler function for the conversion of time delays in the
+virtual domain to real-time.
+.AP ClientData clientData in
+Value passed through to the two handler functions.
+.AP Tcl_GetTimeProc *getProcPtr out
+Pointer to place the currently registered get handler function into.
+.AP Tcl_ScaleTimeProc *scaleProcPtr out
+Pointer to place the currently registered scale handler function into.
+.AP ClientData *clientDataPtr out
+Pointer to place the currently registered pass-through value into.
+.BE
+.SH DESCRIPTION
+.PP
+The \fBTcl_GetTime\fR function retrieves the current time as a
+\fITcl_Time\fR structure in memory the caller provides.  This
+structure has the following definition:
+.PP
+.CS
+typedef struct Tcl_Time {
+    long \fIsec\fR;
+    long \fIusec\fR;
+} \fBTcl_Time\fR;
+.CE
+.PP
+On return, the \fIsec\fR member of the structure is filled in with the
+number of seconds that have elapsed since the \fIepoch:\fR the epoch
+is the point in time of 00:00 UTC, 1 January 1970.  This number does
+\fInot\fR count leap seconds \- an interval of one day advances it by
+86400 seconds regardless of whether a leap second has been inserted.
+.PP
+The \fIusec\fR member of the structure is filled in with the number of
+microseconds that have elapsed since the start of the second
+designated by \fIsec\fR.  The Tcl library makes every effort to keep
+this number as precise as possible, subject to the limitations of the
+computer system.  On multiprocessor variants of Windows, this number
+may be limited to the 10- or 20-ms granularity of the system clock.
+(On single-processor Windows systems, the \fIusec\fR field is derived
+from a performance counter and is highly precise.)
+.SS "VIRTUALIZED TIME"
+.PP
+The \fBTcl_SetTimeProc\fR function registers two related handler functions
+with the core. The first handler function is a replacement for
+\fBTcl_GetTime\fR, or rather the OS access made by
+\fBTcl_GetTime\fR. The other handler function is used by the Tcl
+notifier to convert wait/block times from the virtual domain into real
+time.
+.PP
+The \fBTcl_QueryTimeProc\fR function returns the currently registered
+handler functions. If no external handlers were set then this will
+return the standard handlers accessing and processing the native time
+of the OS. The arguments to the function are allowed to be NULL; and
+any argument which is NULL is ignored and not set.
+.PP
+The signatures of the handler functions are as follows:
+.PP
+.CS
+typedef void \fBTcl_GetTimeProc\fR(
+        Tcl_Time *\fItimebuf\fR,
+        ClientData \fIclientData\fR);
+typedef void \fBTcl_ScaleTimeProc\fR(
+        Tcl_Time *\fItimebuf\fR,
+        ClientData \fIclientData\fR);
+.CE
+.PP
+The \fItimebuf\fR fields contain the time to manipulate, and the
+\fIclientData\fR fields contain a pointer supplied at the time the handler
+functions were registered.
+.PP
+Any handler pair specified has to return data which is consistent between
+them. In other words, setting one handler of the pair to something assuming a
+10-times slowdown, and the other handler of the pair to something assuming a
+two-times slowdown is wrong and not allowed.
+.PP
+The set handler functions are allowed to run the delivered time backwards,
+however this should be avoided. We have to allow it as the native time can run
+backwards as the user can fiddle with the system time one way or other. Note
+that the insertion of the hooks will not change the behavior of the Tcl core
+with regard to this situation, i.e. the existing behavior is retained.
+.SH "SEE ALSO"
+clock(n)
+.SH KEYWORDS
+date, time
diff --git a/doc/GetVersion.3 b/doc/GetVersion.3
new file mode 100644
index 0000000..3672382
--- /dev/null
+++ b/doc/GetVersion.3
@@ -0,0 +1,48 @@
+'\"
+'\" Copyright (c) 1999 Scriptics Corporation
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH Tcl_GetVersion 3 7.5 Tcl "Tcl Library Procedures"
+.so man.macros
+.BS
+.SH NAME
+Tcl_GetVersion \- get the version of the library at runtime
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+\fBTcl_GetVersion\fR(\fImajor, minor, patchLevel, type\fR)
+.SH ARGUMENTS
+.AS Tcl_ReleaseType *patchLevel out
+.AP int *major out
+Major version number of the Tcl library.
+.AP int *minor out
+Minor version number of the Tcl library.
+.AP int *patchLevel out
+The patch level of the Tcl library (or alpha or beta number).
+.AP Tcl_ReleaseType *type out
+The type of release, also indicates the type of patch level. Can be
+one of \fBTCL_ALPHA_RELEASE\fR, \fBTCL_BETA_RELEASE\fR, or
+\fBTCL_FINAL_RELEASE\fR.
+.BE
+
+.SH DESCRIPTION
+.PP
+\fBTcl_GetVersion\fR should be used to query the version number
+of the Tcl library at runtime.  This is useful when using a
+dynamically loaded Tcl library or when writing a stubs-aware
+extension.  For instance, if you write an extension that is
+linked against the Tcl stubs library, it could be loaded into
+a program linked to an older version of Tcl than you expected.
+Use \fBTcl_GetVersion\fR to verify that fact, and possibly to
+change the behavior of your extension.
+.PP
+\fBTcl_GetVersion\fR accepts NULL for any of the arguments. For instance if
+you do not care about the \fIpatchLevel\fR of the library, pass
+a NULL for the \fIpatchLevel\fR argument.
+
+.SH KEYWORDS
+version, patchlevel, major, minor, alpha, beta, release
+
diff --git a/doc/Hash.3 b/doc/Hash.3
new file mode 100644
index 0000000..4dc3623
--- /dev/null
+++ b/doc/Hash.3
@@ -0,0 +1,334 @@
+'\"
+'\" Copyright (c) 1989-1993 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH Tcl_Hash 3 "" Tcl "Tcl Library Procedures"
+.so man.macros
+.BS
+.SH NAME
+Tcl_InitHashTable, Tcl_InitCustomHashTable, Tcl_InitObjHashTable, Tcl_DeleteHashTable, Tcl_CreateHashEntry, Tcl_DeleteHashEntry, Tcl_FindHashEntry, Tcl_GetHashValue, Tcl_SetHashValue, Tcl_GetHashKey, Tcl_FirstHashEntry, Tcl_NextHashEntry, Tcl_HashStats \- procedures to manage hash tables
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+\fBTcl_InitHashTable\fR(\fItablePtr, keyType\fR)
+.sp
+\fBTcl_InitCustomHashTable\fR(\fItablePtr, keyType, typePtr\fR)
+.sp
+\fBTcl_InitObjHashTable\fR(\fItablePtr\fR)
+.sp
+\fBTcl_DeleteHashTable\fR(\fItablePtr\fR)
+.sp
+Tcl_HashEntry *
+\fBTcl_CreateHashEntry\fR(\fItablePtr, key, newPtr\fR)
+.sp
+\fBTcl_DeleteHashEntry\fR(\fIentryPtr\fR)
+.sp
+Tcl_HashEntry *
+\fBTcl_FindHashEntry\fR(\fItablePtr, key\fR)
+.sp
+ClientData
+\fBTcl_GetHashValue\fR(\fIentryPtr\fR)
+.sp
+\fBTcl_SetHashValue\fR(\fIentryPtr, value\fR)
+.sp
+void *
+\fBTcl_GetHashKey\fR(\fItablePtr, entryPtr\fR)
+.sp
+Tcl_HashEntry *
+\fBTcl_FirstHashEntry\fR(\fItablePtr, searchPtr\fR)
+.sp
+Tcl_HashEntry *
+\fBTcl_NextHashEntry\fR(\fIsearchPtr\fR)
+.sp
+char *
+\fBTcl_HashStats\fR(\fItablePtr\fR)
+.SH ARGUMENTS
+.AS "const Tcl_HashKeyType" *searchPtr out
+.AP Tcl_HashTable *tablePtr in
+Address of hash table structure (for all procedures but
+\fBTcl_InitHashTable\fR, this must have been initialized by
+previous call to \fBTcl_InitHashTable\fR).
+.AP int keyType in
+Kind of keys to use for new hash table.  Must be either
+\fBTCL_STRING_KEYS\fR, \fBTCL_ONE_WORD_KEYS\fR, \fBTCL_CUSTOM_TYPE_KEYS\fR,
+\fBTCL_CUSTOM_PTR_KEYS\fR, or an integer value greater than 1.
+.AP Tcl_HashKeyType *typePtr in
+Address of structure which defines the behavior of the hash table.
+.AP "const void" *key in
+Key to use for probe into table.  Exact form depends on
+\fIkeyType\fR used to create table.
+.AP int *newPtr out
+The word at \fI*newPtr\fR is set to 1 if a new entry was created
+and 0 if there was already an entry for \fIkey\fR.
+.AP Tcl_HashEntry *entryPtr in
+Pointer to hash table entry.
+.AP ClientData value in
+New value to assign to hash table entry.  Need not have type
+ClientData, but must fit in same space as ClientData.
+.AP Tcl_HashSearch *searchPtr in
+Pointer to record to use to keep track of progress in enumerating
+all the entries in a hash table.
+.BE
+.SH DESCRIPTION
+.PP
+A hash table consists of zero or more entries, each consisting of a
+key and a value.  Given the key for an entry, the hashing routines can
+very quickly locate the entry, and hence its value. There may be at
+most one entry in a hash table with a particular key, but many entries
+may have the same value.  Keys can take one of four forms: strings,
+one-word values, integer arrays, or custom keys defined by a
+Tcl_HashKeyType structure (See section \fBTHE TCL_HASHKEYTYPE STRUCTURE\fR
+below). All of the keys in a given table have the same
+form, which is specified when the table is initialized.
+.PP
+The value of a hash table entry can be anything that fits in the same
+space as a
+.QW "char *"
+pointer.  Values for hash table entries are
+managed entirely by clients, not by the hash module itself.  Typically
+each entry's value is a pointer to a data structure managed by client
+code.
+.PP
+Hash tables grow gracefully as the number of entries increases, so
+that there are always less than three entries per hash bucket, on
+average. This allows for fast lookups regardless of the number of
+entries in a table.
+.PP
+The core provides three functions for the initialization of hash
+tables, Tcl_InitHashTable, Tcl_InitObjHashTable and
+Tcl_InitCustomHashTable.
+.PP
+\fBTcl_InitHashTable\fR initializes a structure that describes a new
+hash table.  The space for the structure is provided by the caller,
+not by the hash module.  The value of \fIkeyType\fR indicates what
+kinds of keys will be used for all entries in the table. All of the
+key types described later are allowed, with the exception of
+\fBTCL_CUSTOM_TYPE_KEYS\fR and \fBTCL_CUSTOM_PTR_KEYS\fR.
+.PP
+\fBTcl_InitObjHashTable\fR is a wrapper around
+\fBTcl_InitCustomHashTable\fR and initializes a hash table whose keys
+are Tcl_Obj *.
+.PP
+\fBTcl_InitCustomHashTable\fR initializes a structure that describes a
+new hash table. The space for the structure is provided by the
+caller, not by the hash module.  The value of \fIkeyType\fR indicates
+what kinds of keys will be used for all entries in the table.
+\fIKeyType\fR must have one of the following values:
+.IP \fBTCL_STRING_KEYS\fR 25
+Keys are null-terminated strings.
+They are passed to hashing routines using the address of the
+first character of the string.
+.IP \fBTCL_ONE_WORD_KEYS\fR 25
+Keys are single-word values;  they are passed to hashing routines
+and stored in hash table entries as
+.QW "char *"
+values.
+The pointer value is the key;  it need not (and usually does not)
+actually point to a string.
+.IP \fBTCL_CUSTOM_TYPE_KEYS\fR 25
+Keys are of arbitrary type, and are stored in the entry. Hashing
+and comparison is determined by \fItypePtr\fR. The Tcl_HashKeyType
+structure is described in the section
+\fBTHE TCL_HASHKEYTYPE STRUCTURE\fR below.
+.IP \fBTCL_CUSTOM_PTR_KEYS\fR 25
+Keys are pointers to an arbitrary type, and are stored in the entry. Hashing
+and comparison is determined by \fItypePtr\fR. The Tcl_HashKeyType
+structure is described in the section
+\fBTHE TCL_HASHKEYTYPE STRUCTURE\fR below.
+.IP \fIother\fR 25
+If \fIkeyType\fR is not one of the above,
+then it must be an integer value greater than 1.
+In this case the keys will be arrays of
+.QW int
+values, where
+\fIkeyType\fR gives the number of ints in each key.
+This allows structures to be used as keys.
+All keys must have the same size.
+Array keys are passed into hashing functions using the address
+of the first int in the array.
+.PP
+\fBTcl_DeleteHashTable\fR deletes all of the entries in a hash
+table and frees up the memory associated with the table's
+bucket array and entries.
+It does not free the actual table structure (pointed to
+by \fItablePtr\fR), since that memory is assumed to be managed
+by the client.
+\fBTcl_DeleteHashTable\fR also does not free or otherwise
+manipulate the values of the hash table entries.
+If the entry values point to dynamically-allocated memory, then
+it is the client's responsibility to free these structures
+before deleting the table.
+.PP
+\fBTcl_CreateHashEntry\fR locates the entry corresponding to a
+particular key, creating a new entry in the table if there
+was not already one with the given key.
+If an entry already existed with the given key then \fI*newPtr\fR
+is set to zero.
+If a new entry was created, then \fI*newPtr\fR is set to a non-zero
+value and the value of the new entry will be set to zero.
+The return value from \fBTcl_CreateHashEntry\fR is a pointer to
+the entry, which may be used to retrieve and modify the entry's
+value or to delete the entry from the table.
+.PP
+\fBTcl_DeleteHashEntry\fR will remove an existing entry from a
+table.
+The memory associated with the entry itself will be freed, but
+the client is responsible for any cleanup associated with the
+entry's value, such as freeing a structure that it points to.
+.PP
+\fBTcl_FindHashEntry\fR is similar to \fBTcl_CreateHashEntry\fR
+except that it does not create a new entry if the key doesn't exist;
+instead, it returns NULL as result.
+.PP
+\fBTcl_GetHashValue\fR and \fBTcl_SetHashValue\fR are used to
+read and write an entry's value, respectively.
+Values are stored and retrieved as type
+.QW ClientData ,
+which is
+large enough to hold a pointer value.  On almost all machines this is
+large enough to hold an integer value too.
+.PP
+\fBTcl_GetHashKey\fR returns the key for a given hash table entry,
+either as a pointer to a string, a one-word
+.PQ "char *"
+key, or
+as a pointer to the first word of an array of integers, depending
+on the \fIkeyType\fR used to create a hash table.
+In all cases \fBTcl_GetHashKey\fR returns a result with type
+.QW "char *" .
+When the key is a string or array, the result of \fBTcl_GetHashKey\fR
+points to information in the table entry;  this information will
+remain valid until the entry is deleted or its table is deleted.
+.PP
+\fBTcl_FirstHashEntry\fR and \fBTcl_NextHashEntry\fR may be used
+to scan all of the entries in a hash table.
+A structure of type
+.QW Tcl_HashSearch ,
+provided by the client,
+is used to keep track of progress through the table.
+\fBTcl_FirstHashEntry\fR initializes the search record and
+returns the first entry in the table (or NULL if the table is
+empty).
+Each subsequent call to \fBTcl_NextHashEntry\fR returns the
+next entry in the table or
+NULL if the end of the table has been reached.
+A call to \fBTcl_FirstHashEntry\fR followed by calls to
+\fBTcl_NextHashEntry\fR will return each of the entries in
+the table exactly once, in an arbitrary order.
+It is inadvisable to modify the structure of the table, e.g.
+by creating or deleting entries, while the search is in progress,
+with the exception of deleting the entry returned by
+\fBTcl_FirstHashEntry\fR or \fBTcl_NextHashEntry\fR.
+.PP
+\fBTcl_HashStats\fR returns a dynamically-allocated string with
+overall information about a hash table, such as the number of
+entries it contains, the number of buckets in its hash array,
+and the utilization of the buckets.
+It is the caller's responsibility to free the result string
+by passing it to \fBckfree\fR.
+.PP
+The header file \fBtcl.h\fR defines the actual data structures
+used to implement hash tables.
+This is necessary so that clients can allocate Tcl_HashTable
+structures and so that macros can be used to read and write
+the values of entries.
+However, users of the hashing routines should never refer directly
+to any of the fields of any of the hash-related data structures;
+use the procedures and macros defined here.
+.SH "THE TCL_HASHKEYTYPE STRUCTURE"
+.PP
+Extension writers can define new hash key types by defining four procedures,
+initializing a \fBTcl_HashKeyType\fR structure to describe the type, and
+calling \fBTcl_InitCustomHashTable\fR. The \fBTcl_HashKeyType\fR structure is
+defined as follows:
+.PP
+.CS
+typedef struct Tcl_HashKeyType {
+    int \fIversion\fR;
+    int \fIflags\fR;
+    Tcl_HashKeyProc *\fIhashKeyProc\fR;
+    Tcl_CompareHashKeysProc *\fIcompareKeysProc\fR;
+    Tcl_AllocHashEntryProc *\fIallocEntryProc\fR;
+    Tcl_FreeHashEntryProc *\fIfreeEntryProc\fR;
+} \fBTcl_HashKeyType\fR;
+.CE
+.PP
+The \fIversion\fR member is the version of the table. If this structure is
+extended in future then the version can be used to distinguish between
+different structures. It should be set to \fBTCL_HASH_KEY_TYPE_VERSION\fR.
+.PP
+The \fIflags\fR member is 0 or one or more of the following values OR'ed
+together:
+.IP \fBTCL_HASH_KEY_RANDOMIZE_HASH\fR 25
+There are some things, pointers for example which do not hash well because
+they do not use the lower bits. If this flag is set then the hash table will
+attempt to rectify this by randomizing the bits and then using the upper N
+bits as the index into the table.
+.IP \fBTCL_HASH_KEY_SYSTEM_HASH\fR 25
+This flag forces Tcl to use the memory allocation procedures provided by the
+operating system when allocating and freeing memory used to store the hash
+table data structures, and not any of Tcl's own customized memory allocation
+routines. This is important if the hash table is to be used in the
+implementation of a custom set of allocation routines, or something that a
+custom set of allocation routines might depend on, in order to avoid any
+circular dependency.
+.PP
+The \fIhashKeyProc\fR member contains the address of a function called to
+calculate a hash value for the key.
+.PP
+.CS
+typedef unsigned int \fBTcl_HashKeyProc\fR(
+        Tcl_HashTable *\fItablePtr\fR,
+        void *\fIkeyPtr\fR);
+.CE
+.PP
+If this is NULL then \fIkeyPtr\fR is used and
+\fBTCL_HASH_KEY_RANDOMIZE_HASH\fR is assumed.
+.PP
+The \fIcompareKeysProc\fR member contains the address of a function called to
+compare two keys.
+.PP
+.CS
+typedef int \fBTcl_CompareHashKeysProc\fR(
+        void *\fIkeyPtr\fR,
+        Tcl_HashEntry *\fIhPtr\fR);
+.CE
+.PP
+If this is NULL then the \fIkeyPtr\fR pointers are compared. If the keys do
+not match then the function returns 0, otherwise it returns 1.
+.PP
+The \fIallocEntryProc\fR member contains the address of a function called to
+allocate space for an entry and initialize the key and clientData.
+.PP
+.CS
+typedef Tcl_HashEntry *\fBTcl_AllocHashEntryProc\fR(
+        Tcl_HashTable *\fItablePtr\fR,
+        void *\fIkeyPtr\fR);
+.CE
+.PP
+If this is NULL then \fBTcl_Alloc\fR is used to allocate enough space for a
+Tcl_HashEntry, the key pointer is assigned to key.oneWordValue and the
+clientData is set to NULL. String keys and array keys use this function to
+allocate enough space for the entry and the key in one block, rather than
+doing it in two blocks. This saves space for a pointer to the key from the
+entry and another memory allocation. Tcl_Obj* keys use this function to
+allocate enough space for an entry and increment the reference count on the
+value.
+.PP
+The \fIfreeEntryProc\fR member contains the address of a function called to
+free space for an entry.
+.PP
+.CS
+typedef void \fBTcl_FreeHashEntryProc\fR(
+        Tcl_HashEntry *\fIhPtr\fR);
+.CE
+.PP
+If this is NULL then \fBTcl_Free\fR is used to free the space for the entry.
+Tcl_Obj* keys use this function to decrement the reference count on the
+value.
+.SH KEYWORDS
+hash table, key, lookup, search, value
diff --git a/doc/Init.3 b/doc/Init.3
new file mode 100644
index 0000000..33c27a3
--- /dev/null
+++ b/doc/Init.3
@@ -0,0 +1,34 @@
+'\"
+'\" Copyright (c) 1998-2000 by Scriptics Corporation.
+'\" All rights reserved.
+'\" 
+.TH Tcl_Init 3 8.0 Tcl "Tcl Library Procedures"
+.so man.macros
+.BS
+.SH NAME
+Tcl_Init \- find and source initialization script
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+int
+\fBTcl_Init\fR(\fIinterp\fR)
+.SH ARGUMENTS
+.AS Tcl_Interp *interp
+.AP Tcl_Interp *interp in
+Interpreter to initialize.
+.BE
+
+.SH DESCRIPTION
+.PP
+\fBTcl_Init\fR is a helper procedure that finds and \fBsource\fRs the
+\fBinit.tcl\fR script, which should exist somewhere on the Tcl library
+path.
+.PP
+\fBTcl_Init\fR is typically called from \fBTcl_AppInit\fR procedures.
+
+.SH "SEE ALSO"
+Tcl_AppInit, Tcl_Main
+
+.SH KEYWORDS
+application, initialization, interpreter
diff --git a/doc/InitStubs.3 b/doc/InitStubs.3
new file mode 100644
index 0000000..73c3437
--- /dev/null
+++ b/doc/InitStubs.3
@@ -0,0 +1,89 @@
+'\"
+'\" Copyright (c) 1998-1999 Scriptics Corporation
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\" 
+.TH Tcl_InitStubs 3 8.1 Tcl "Tcl Library Procedures"
+.so man.macros
+.BS
+.SH NAME
+Tcl_InitStubs \- initialize the Tcl stubs mechanism
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+const char *
+\fBTcl_InitStubs\fR(\fIinterp, version, exact\fR)
+.SH ARGUMENTS
+.AS Tcl_Interp *interp
+.AP Tcl_Interp *interp in
+Tcl interpreter handle.
+.AP "const char" *version in
+A version string consisting of one or more decimal numbers
+separated by dots.
+.AP int exact in
+Non-zero means that only the particular version specified by
+\fIversion\fR is acceptable.
+Zero means that versions newer than \fIversion\fR are also
+acceptable as long as they have the same major version number
+as \fIversion\fR.
+.BE
+.SH INTRODUCTION
+.PP
+The Tcl stubs mechanism defines a way to dynamically bind
+extensions to a particular Tcl implementation at run time.
+This provides two significant benefits to Tcl users:
+.IP 1) 5
+Extensions that use the stubs mechanism can be loaded into
+multiple versions of Tcl without being recompiled or
+relinked.
+.IP 2) 5
+Extensions that use the stubs mechanism can be dynamically
+loaded into statically-linked Tcl applications.
+.PP
+The stubs mechanism accomplishes this by exporting function tables
+that define an interface to the Tcl API.  The extension then accesses
+the Tcl API through offsets into the function table, so there are no
+direct references to any of the Tcl library's symbols.  This
+redirection is transparent to the extension, so an extension writer
+can continue to use all public Tcl functions as documented.
+.PP
+The stubs mechanism requires no changes to applications incorporating
+Tcl interpreters.  Only developers creating C-based Tcl extensions
+need to take steps to use the stubs mechanism with their extensions.
+.PP
+Enabling the stubs mechanism for an extension requires the following
+steps:
+.IP 1) 5
+Call \fBTcl_InitStubs\fR in the extension before calling any other
+Tcl functions.
+.IP 2) 5
+Define the \fBUSE_TCL_STUBS\fR symbol.  Typically, you would include the
+\fB\-DUSE_TCL_STUBS\fR flag when compiling the extension.
+.IP 3) 5
+Link the extension with the Tcl stubs library instead of the standard
+Tcl library.  For example, to use the Tcl 8.6 ABI on Unix platforms,
+the library name is \fIlibtclstub8.6.a\fR; on Windows platforms, the
+library name is \fItclstub86.lib\fR.
+.PP
+If the extension also requires the Tk API, it must also call
+\fBTk_InitStubs\fR to initialize the Tk stubs interface and link
+with the Tk stubs libraries.  See the \fBTk_InitStubs\fR page for
+more information.
+.SH DESCRIPTION
+\fBTcl_InitStubs\fR attempts to initialize the stub table pointers
+and ensure that the correct version of Tcl is loaded.  In addition
+to an interpreter handle, it accepts as arguments a version number
+and a Boolean flag indicating whether the extension requires
+an exact version match or not.  If \fIexact\fR is 0, then the
+extension is indicating that newer versions of Tcl are acceptable
+as long as they have the same major version number as \fIversion\fR;
+non-zero means that only the specified \fIversion\fR is acceptable.
+\fBTcl_InitStubs\fR returns a string containing the actual version
+of Tcl satisfying the request, or NULL if the Tcl version is not
+acceptable, does not support stubs, or any other error condition occurred.
+.SH "SEE ALSO"
+Tk_InitStubs
+.SH KEYWORDS
+stubs
diff --git a/doc/IntObj.3 b/doc/IntObj.3
new file mode 100644
index 0000000..dc62642
--- /dev/null
+++ b/doc/IntObj.3
@@ -0,0 +1,152 @@
+'\"
+'\" Copyright (c) 1996-1997 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH Tcl_IntObj 3 8.5 Tcl "Tcl Library Procedures"
+.so man.macros
+.BS
+.SH NAME
+Tcl_NewIntObj, Tcl_NewLongObj, Tcl_NewWideIntObj, Tcl_SetIntObj, Tcl_SetLongObj, Tcl_SetWideIntObj, Tcl_GetIntFromObj, Tcl_GetLongFromObj, Tcl_GetWideIntFromObj, Tcl_NewBignumObj, Tcl_SetBignumObj, Tcl_GetBignumFromObj, Tcl_TakeBignumFromObj \- manipulate Tcl values as integers
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+Tcl_Obj *
+\fBTcl_NewIntObj\fR(\fIintValue\fR)
+.sp
+Tcl_Obj *
+\fBTcl_NewLongObj\fR(\fIlongValue\fR)
+.sp
+Tcl_Obj *
+\fBTcl_NewWideIntObj\fR(\fIwideValue\fR)
+.sp
+\fBTcl_SetIntObj\fR(\fIobjPtr, intValue\fR)
+.sp
+\fBTcl_SetLongObj\fR(\fIobjPtr, longValue\fR)
+.sp
+\fBTcl_SetWideIntObj\fR(\fIobjPtr, wideValue\fR)
+.sp
+int
+\fBTcl_GetIntFromObj\fR(\fIinterp, objPtr, intPtr\fR)
+.sp
+int
+\fBTcl_GetLongFromObj\fR(\fIinterp, objPtr, longPtr\fR)
+.sp
+int
+\fBTcl_GetWideIntFromObj\fR(\fIinterp, objPtr, widePtr\fR)
+.sp
+.sp
+\fB#include <tclTomMath.h>\fR
+.sp
+Tcl_Obj *
+\fBTcl_NewBignumObj\fR(\fIbigValue\fR)
+.sp
+\fBTcl_SetBignumObj\fR(\fIobjPtr, bigValue\fR)
+.sp
+int
+\fBTcl_GetBignumFromObj\fR(\fIinterp, objPtr, bigValue\fR)
+.sp
+int
+\fBTcl_TakeBignumFromObj\fR(\fIinterp, objPtr, bigValue\fR)
+.sp
+int
+\fBTcl_InitBignumFromDouble\fR(\fIinterp, doubleValue, bigValue\fR)
+.SH ARGUMENTS
+.AS Tcl_WideInt doubleValue in/out
+.AP int intValue in
+Integer value used to initialize or set a Tcl value.
+.AP long longValue in
+Long integer value used to initialize or set a Tcl value.
+.AP Tcl_WideInt wideValue in
+Wide integer value used to initialize or set a Tcl value.
+.AP Tcl_Obj *objPtr in/out
+For \fBTcl_SetIntObj\fR, \fBTcl_SetLongObj\fR, \fBTcl_SetWideIntObj\fR,
+and \fBTcl_SetBignumObj\fR, this points to the value in which to store an
+integral value.  For \fBTcl_GetIntFromObj\fR, \fBTcl_GetLongFromObj\fR,
+\fBTcl_GetWideIntFromObj\fR, \fBTcl_GetBignumFromObj\fR, and
+\fBTcl_TakeBignumFromObj\fR, this refers to the value from which
+to retrieve an integral value.
+.AP Tcl_Interp *interp in/out
+When non-NULL, an error message is left here when integral value
+retrieval fails.
+.AP int *intPtr out
+Points to place to store the integer value retrieved from \fIobjPtr\fR.
+.AP long *longPtr out
+Points to place to store the long integer value retrieved from \fIobjPtr\fR.
+.AP Tcl_WideInt *widePtr out
+Points to place to store the wide integer value retrieved from \fIobjPtr\fR.
+.AP mp_int *bigValue in/out
+Points to a multi-precision integer structure declared by the LibTomMath
+library.
+.AP double doubleValue in
+Double value from which the integer part is determined and
+used to initialize a multi-precision integer value.
+.BE
+.SH DESCRIPTION
+.PP
+These procedures are used to create, modify, and read Tcl values
+that hold integral values.
+.PP
+The different routines exist to accommodate different integral types in C
+with which values might be exchanged.  The C integral types for which Tcl
+provides value exchange routines are \fBint\fR, \fBlong int\fR,
+\fBTcl_WideInt\fR, and \fBmp_int\fR.  The \fBint\fR and \fBlong int\fR types
+are provided by the C language standard.  The \fBTcl_WideInt\fR type is a
+typedef defined to be whatever signed integral type covers at least the
+64-bit integer range (-9223372036854775808 to 9223372036854775807).  Depending
+on the platform and the C compiler, the actual type might be
+\fBlong int\fR, \fBlong long int\fR, \fBint64\fR, or something else.
+The \fBmp_int\fR type is a multiple-precision integer type defined
+by the LibTomMath multiple-precision integer library.
+.PP
+The \fBTcl_NewIntObj\fR, \fBTcl_NewLongObj\fR, \fBTcl_NewWideIntObj\fR,
+and \fBTcl_NewBignumObj\fR routines each create and return a new
+Tcl value initialized to the integral value of the argument.  The
+returned Tcl value is unshared.
+.PP
+The \fBTcl_SetIntObj\fR, \fBTcl_SetLongObj\fR, \fBTcl_SetWideIntObj\fR,
+and \fBTcl_SetBignumObj\fR routines each set the value of an existing
+Tcl value pointed to by \fIobjPtr\fR to the integral value provided
+by the other argument.  The \fIobjPtr\fR argument must point to an
+unshared Tcl value.  Any attempt to set the value of a shared Tcl value
+violates Tcl's copy-on-write policy.  Any existing string representation
+or internal representation in the unshared Tcl value will be freed
+as a consequence of setting the new value.
+.PP
+The \fBTcl_GetIntFromObj\fR, \fBTcl_GetLongFromObj\fR,
+\fBTcl_GetWideIntFromObj\fR, \fBTcl_GetBignumFromObj\fR, and
+\fBTcl_TakeBignumFromObj\fR routines attempt to retrieve an integral
+value of the appropriate type from the Tcl value \fIobjPtr\fR.  If the
+attempt succeeds, then \fBTCL_OK\fR is returned, and the value is
+written to the storage provided by the caller.  The attempt might
+fail if \fIobjPtr\fR does not hold an integral value, or if the
+value exceeds the range of the target type.  If the attempt fails,
+then \fBTCL_ERROR\fR is returned, and if \fIinterp\fR is non-NULL,
+an error message is left in \fIinterp\fR.  The \fBTcl_ObjType\fR
+of \fIobjPtr\fR may be changed to make subsequent calls to the
+same routine more efficient. Unlike the other functions,
+\fBTcl_TakeBignumFromObj\fR may set the content of the Tcl value
+\fIobjPtr\fR to an empty string in the process of retrieving the
+multiple-precision integer value.
+.PP
+The choice between \fBTcl_GetBignumFromObj\fR and
+\fBTcl_TakeBignumFromObj\fR is governed by how the caller will
+continue to use \fIobjPtr\fR.  If after the \fBmp_int\fR value
+is retrieved from \fIobjPtr\fR, the caller will make no more
+use of \fIobjPtr\fR, then using \fBTcl_TakeBignumFromObj\fR
+permits Tcl to detect when an unshared \fIobjPtr\fR permits the
+value to be moved instead of copied, which should be more efficient.
+If anything later in the caller requires
+\fIobjPtr\fR to continue to hold the same value, then
+\fBTcl_GetBignumFromObj\fR must be chosen.
+.PP
+The \fBTcl_InitBignumFromDouble\fR routine is a utility procedure
+that extracts the integer part of \fIdoubleValue\fR and stores that
+integer value in the \fBmp_int\fR value \fIbigValue\fR.
+.SH "SEE ALSO"
+Tcl_NewObj, Tcl_DecrRefCount, Tcl_IncrRefCount, Tcl_GetObjResult
+.SH KEYWORDS
+integer, integer value, integer type, internal representation, value,
+value type, string representation
diff --git a/doc/Interp.3 b/doc/Interp.3
new file mode 100644
index 0000000..731007b
--- /dev/null
+++ b/doc/Interp.3
@@ -0,0 +1,134 @@
+'\"
+'\" Copyright (c) 1989-1993 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH Tcl_Interp 3 7.5 Tcl "Tcl Library Procedures"
+.so man.macros
+.BS
+.SH NAME
+Tcl_Interp \- client-visible fields of interpreter structures
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+typedef struct {
+    char *\fIresult\fR;
+    Tcl_FreeProc *\fIfreeProc\fR;
+    int \fIerrorLine\fR;
+} \fBTcl_Interp\fR;
+
+typedef void \fBTcl_FreeProc\fR(
+        char *\fIblockPtr\fR);
+.BE
+.SH DESCRIPTION
+.PP
+The \fBTcl_CreateInterp\fR procedure returns a pointer to a Tcl_Interp
+structure.  Callers of \fBTcl_CreateInterp\fR should use this pointer
+as an opaque token, suitable for nothing other than passing back to
+other routines in the Tcl interface.  Accessing fields directly through
+the pointer as described below is no longer supported.  The supported
+public routines \fBTcl_SetResult\fR, \fBTcl_GetResult\fR,
+\fBTcl_SetErrorLine\fR, \fBTcl_GetErrorLine\fR must be used instead.
+.PP
+For legacy programs and extensions no longer being maintained, compiles
+against the Tcl 8.6 header files are only possible with the compiler
+directives
+.CS
+#define USE_INTERP_RESULT
+.CE
+and/or
+.CS
+#define USE_INTERP_ERRORLINE
+.CE
+depending on which fields of the \fBTcl_Interp\fR struct are accessed.
+These directives may be embedded in code or supplied via compiler options.
+.PP
+The \fIresult\fR and \fIfreeProc\fR fields are used to return
+results or error messages from commands.
+This information is returned by command procedures back to \fBTcl_Eval\fR,
+and by \fBTcl_Eval\fR back to its callers.
+The \fIresult\fR field points to the string that represents the
+result or error message, and the \fIfreeProc\fR field tells how
+to dispose of the storage for the string when it is not needed anymore.
+The easiest way for command procedures to manipulate these
+fields is to call procedures like \fBTcl_SetResult\fR
+or \fBTcl_AppendResult\fR;  they
+will hide all the details of managing the fields.
+The description below is for those procedures that manipulate the
+fields directly.
+.PP
+Whenever a command procedure returns, it must ensure
+that the \fIresult\fR field of its interpreter points to the string
+being returned by the command.
+The \fIresult\fR field must always point to a valid string.
+If a command wishes to return no result then \fIinterp->result\fR
+should point to an empty string.
+Normally, results are assumed to be statically allocated,
+which means that the contents will not change before the next time
+\fBTcl_Eval\fR is called or some other command procedure is invoked.
+In this case, the \fIfreeProc\fR field must be zero.
+Alternatively, a command procedure may dynamically
+allocate its return value (e.g. using \fBTcl_Alloc\fR)
+and store a pointer to it in \fIinterp->result\fR.
+In this case, the command procedure must also set \fIinterp->freeProc\fR
+to the address of a procedure that can free the value, or \fBTCL_DYNAMIC\fR
+if the storage was allocated directly by Tcl or by a call to
+\fBTcl_Alloc\fR.
+If \fIinterp->freeProc\fR is non-zero, then Tcl will call \fIfreeProc\fR
+to free the space pointed to by \fIinterp->result\fR before it
+invokes the next command.
+If a client procedure overwrites \fIinterp->result\fR when
+\fIinterp->freeProc\fR is non-zero, then it is responsible for calling
+\fIfreeProc\fR to free the old \fIinterp->result\fR (the \fBTcl_FreeResult\fR
+macro should be used for this purpose).
+.PP
+\fIFreeProc\fR should have arguments and result that match the
+\fBTcl_FreeProc\fR declaration above:  it receives a single
+argument which is a pointer to the result value to free.
+In most applications \fBTCL_DYNAMIC\fR is the only non-zero value ever
+used for \fIfreeProc\fR.
+However, an application may store a different procedure address
+in \fIfreeProc\fR in order to use an alternate memory allocator
+or in order to do other cleanup when the result memory is freed.
+.PP
+As part of processing each command, \fBTcl_Eval\fR initializes
+\fIinterp->result\fR
+and \fIinterp->freeProc\fR just before calling the command procedure for
+the command.  The \fIfreeProc\fR field will be initialized to zero,
+and \fIinterp->result\fR will point to an empty string.  Commands that
+do not return any value can simply leave the fields alone.
+Furthermore, the empty string pointed to by \fIresult\fR is actually
+part of an array of \fBTCL_RESULT_SIZE\fR characters (approximately 200).
+If a command wishes to return a short string, it can simply copy
+it to the area pointed to by \fIinterp->result\fR.  Or, it can use
+the sprintf procedure to generate a short result string at the location
+pointed to by \fIinterp->result\fR.
+.PP
+It is a general convention in Tcl-based applications that the result
+of an interpreter is normally in the initialized state described
+in the previous paragraph.
+Procedures that manipulate an interpreter's result (e.g. by
+returning an error) will generally assume that the result
+has been initialized when the procedure is called.
+If such a procedure is to be called after the result has been
+changed, then \fBTcl_ResetResult\fR should be called first to
+reset the result to its initialized state.  The direct use of
+\fIinterp->result\fR is strongly deprecated (see \fBTcl_SetResult\fR).
+.PP
+The \fIerrorLine\fR
+field is valid only after \fBTcl_Eval\fR returns
+a \fBTCL_ERROR\fR return code.  In this situation the \fIerrorLine\fR
+field identifies the line number of the command being executed when
+the error occurred.  The line numbers are relative to the command
+being executed:  1 means the first line of the command passed to
+\fBTcl_Eval\fR, 2 means the second line, and so on.
+The \fIerrorLine\fR field is typically used in conjunction with
+\fBTcl_AddErrorInfo\fR to report information about where an error
+occurred.
+\fIErrorLine\fR should not normally be modified except by \fBTcl_Eval\fR.
+
+.SH KEYWORDS
+free, initialized, interpreter, malloc, result
diff --git a/doc/Limit.3 b/doc/Limit.3
new file mode 100644
index 0000000..20a2e02
--- /dev/null
+++ b/doc/Limit.3
@@ -0,0 +1,192 @@
+'\"
+'\" Copyright (c) 2004 Donal K. Fellows
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\" 
+.TH Tcl_LimitCheck 3 8.5 Tcl "Tcl Library Procedures"
+.so man.macros
+.BS
+.SH NAME
+Tcl_LimitAddHandler, Tcl_LimitCheck, Tcl_LimitExceeded, Tcl_LimitGetCommands, Tcl_LimitGetGranularity, Tcl_LimitGetTime, Tcl_LimitReady, Tcl_LimitRemoveHandler, Tcl_LimitSetCommands, Tcl_LimitSetGranularity, Tcl_LimitSetTime, Tcl_LimitTypeEnabled, Tcl_LimitTypeExceeded, Tcl_LimitTypeReset, Tcl_LimitTypeSet \- manage and check resource limits on interpreters
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+int
+\fBTcl_LimitCheck\fR(\fIinterp\fR)
+.sp
+int
+\fBTcl_LimitReady\fR(\fIinterp\fR)
+.sp
+int
+\fBTcl_LimitExceeded\fR(\fIinterp\fR)
+.sp
+int
+\fBTcl_LimitTypeExceeded\fR(\fIinterp, type\fR)
+.sp
+int
+\fBTcl_LimitTypeEnabled\fR(\fIinterp, type\fR)
+.sp
+void
+\fBTcl_LimitTypeSet\fR(\fIinterp, type\fR)
+.sp
+void
+\fBTcl_LimitTypeReset\fR(\fIinterp, type\fR)
+.sp
+int
+\fBTcl_LimitGetCommands\fR(\fIinterp\fR)
+.sp
+void
+\fBTcl_LimitSetCommands\fR(\fIinterp, commandLimit\fR)
+.sp
+void
+\fBTcl_LimitGetTime\fR(\fIinterp, timeLimitPtr\fR)
+.sp
+void
+\fBTcl_LimitSetTime\fR(\fIinterp, timeLimitPtr\fR)
+.sp
+int
+\fBTcl_LimitGetGranularity\fR(\fIinterp, type\fR)
+.sp
+void
+\fBTcl_LimitSetGranularity\fR(\fIinterp, type, granularity\fR)
+.sp
+void
+\fBTcl_LimitAddHandler\fR(\fIinterp, type, handlerProc, clientData, deleteProc\fR)
+.sp
+void
+\fBTcl_LimitRemoveHandler\fR(\fIinterp, type, handlerProc, clientData\fR)
+.SH ARGUMENTS
+.AS Tcl_LimitHandlerDeleteProc commandLimit in/out
+.AP Tcl_Interp *interp in
+Interpreter that the limit being managed applies to or that will have
+its limits checked.
+.AP int type in
+The type of limit that the operation refers to.  This must be either
+\fBTCL_LIMIT_COMMANDS\fR or \fBTCL_LIMIT_TIME\fR.
+.AP int commandLimit in
+The maximum number of commands (as reported by \fBinfo cmdcount\fR)
+that may be executed in the interpreter.
+.AP Tcl_Time *timeLimitPtr in/out
+A pointer to a structure that will either have the new time limit read
+from (\fBTcl_LimitSetTime\fR) or the current time limit written to
+(\fBTcl_LimitGetTime\fR).
+.AP int granularity in
+Divisor that indicates how often a particular limit should really be
+checked.  Must be at least 1.
+.AP Tcl_LimitHandlerProc *handlerProc in
+Function to call when a particular limit is exceeded.  If the
+\fIhandlerProc\fR removes or raises the limit during its processing,
+the limited interpreter will be permitted to continue to process after
+the handler returns.  Many handlers may be attached to the same
+interpreter limit; their order of execution is not defined, and they
+must be identified by \fIhandlerProc\fR and \fIclientData\fR when they
+are deleted.
+.AP ClientData clientData in
+Arbitrary pointer-sized word used to pass some context to the
+\fIhandlerProc\fR function.
+.AP Tcl_LimitHandlerDeleteProc *deleteProc in
+Function to call whenever a handler is deleted.  May be NULL if the
+\fIclientData\fR requires no deletion.
+.BE
+.SH DESCRIPTION
+.PP
+Tcl's interpreter resource limit subsystem allows for close control
+over how much computation time a script may use, and is useful for
+cases where a program is divided into multiple pieces where some parts
+are more trusted than others (e.g. web application servers).
+.PP
+Every interpreter may have a limit on the wall-time for execution, and
+a limit on the number of commands that the interpreter may execute.
+Since checking of these limits is potentially expensive (especially
+the time limit), each limit also has a checking granularity, which is
+a divisor for an internal count of the number of points in the core
+where a check may be performed (which is immediately before executing
+a command and at an unspecified frequency between running commands,
+which can happen in empty-bodied \fBwhile\fR loops).
+.PP
+The final component of the limit engine is a callback scheme which
+allows for notifications of when a limit has been exceeded.  These
+callbacks can just provide logging, or may allocate more resources to
+the interpreter to permit it to continue processing longer.
+.PP
+When a limit is exceeded (and the callbacks have run; the order of
+execution of the callbacks is unspecified) execution in the limited
+interpreter is stopped by raising an error and setting a flag that
+prevents the \fBcatch\fR command in that interpreter from trapping
+that error.  It is up to the context that started execution in that
+interpreter (typically a master interpreter) to handle the error.
+.SH "LIMIT CHECKING API"
+.PP
+To check the resource limits for an interpreter, call
+\fBTcl_LimitCheck\fR, which returns \fBTCL_OK\fR if the limit was not
+exceeded (after processing callbacks) and \fBTCL_ERROR\fR if the limit was
+exceeded (in which case an error message is also placed in the
+interpreter result).  That function should only be called when
+\fBTcl_LimitReady\fR returns non-zero so that granularity policy is
+enforced.  This API is designed to be similar in usage to
+\fBTcl_AsyncReady\fR and \fBTcl_AsyncInvoke\fR.
+.PP
+When writing code that may behave like \fBcatch\fR in respect of
+errors, you should only trap an error if \fBTcl_LimitExceeded\fR
+returns zero.  If it returns non-zero, the interpreter is in a
+limit-exceeded state and errors should be allowed to propagate to the
+calling context.  You can also check whether a particular type of
+limit has been exceeded using \fBTcl_LimitTypeExceeded\fR.
+.SH "LIMIT CONFIGURATION"
+.PP
+To check whether a limit has been set (but not whether it has actually
+been exceeded) on an interpreter, call \fBTcl_LimitTypeEnabled\fR with
+the type of limit you want to check.  To enable a particular limit
+call \fBTcl_LimitTypeSet\fR, and to disable a limit call
+\fBTcl_LimitTypeReset\fR.
+.PP
+The level of a command limit may be set using
+\fBTcl_LimitSetCommands\fR, and retrieved using
+\fBTcl_LimitGetCommands\fR.  Similarly for a time limit with
+\fBTcl_LimitSetTime\fR and \fBTcl_LimitGetTime\fR respectively, but
+with that API the time limit is copied from and to the Tcl_Time
+structure that the \fItimeLimitPtr\fR argument points to.
+.PP
+The checking granularity for a particular limit may be set using
+\fBTcl_LimitSetGranularity\fR and retrieved using
+\fBTcl_LimitGetGranularity\fR.  Note that granularities must always be
+positive.
+.SS "LIMIT CALLBACKS"
+.PP
+To add a handler callback to be invoked when a limit is exceeded, call
+\fBTcl_LimitAddHandler\fR.  The \fIhandlerProc\fR argument describes
+the function that will actually be called; it should have the
+following prototype:
+.PP
+.CS
+typedef void \fBTcl_LimitHandlerProc\fR(
+        ClientData \fIclientData\fR,
+        Tcl_Interp *\fIinterp\fR);
+.CE
+.PP
+The \fIclientData\fR argument to the handler will be whatever is
+passed to the \fIclientData\fR argument to \fBTcl_LimitAddHandler\fR,
+and the \fIinterp\fR is the interpreter that had its limit exceeded.
+.PP
+The \fIdeleteProc\fR argument to \fBTcl_LimitAddHandler\fR is a
+function to call to delete the \fIclientData\fR value.  It may be
+\fBTCL_STATIC\fR or NULL if no deletion action is necessary, or
+\fBTCL_DYNAMIC\fR if all that is necessary is to free the structure with
+\fBTcl_Free\fR.  Otherwise, it should refer to a function with the
+following prototype:
+.PP
+.CS
+typedef void \fBTcl_LimitHandlerDeleteProc\fR(
+        ClientData \fIclientData\fR);
+.CE
+.PP
+A limit handler may be deleted using \fBTcl_LimitRemoveHandler\fR; the
+handler removed will be the first one found (out of the handlers added
+with \fBTcl_LimitAddHandler\fR) with exactly matching \fItype\fR,
+\fIhandlerProc\fR and \fIclientData\fR arguments.  This function
+always invokes the \fIdeleteProc\fR on the \fIclientData\fR (unless
+the \fIdeleteProc\fR was NULL or \fBTCL_STATIC\fR).
+.SH KEYWORDS
+interpreter, resource, limit, commands, time, callback
diff --git a/doc/LinkVar.3 b/doc/LinkVar.3
new file mode 100644
index 0000000..c64720b
--- /dev/null
+++ b/doc/LinkVar.3
@@ -0,0 +1,207 @@
+'\"
+'\" Copyright (c) 1993 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\" 
+.TH Tcl_LinkVar 3 7.5 Tcl "Tcl Library Procedures"
+.so man.macros
+.BS
+.SH NAME
+Tcl_LinkVar, Tcl_UnlinkVar, Tcl_UpdateLinkedVar \- link Tcl variable to C variable
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+int
+\fBTcl_LinkVar\fR(\fIinterp, varName, addr, type\fR)
+.sp
+\fBTcl_UnlinkVar\fR(\fIinterp, varName\fR)
+.sp
+\fBTcl_UpdateLinkedVar\fR(\fIinterp, varName\fR)
+.SH ARGUMENTS
+.AS Tcl_Interp writable
+.AP Tcl_Interp *interp in
+Interpreter that contains \fIvarName\fR.
+Also used by \fBTcl_LinkVar\fR to return error messages.
+.AP "const char" *varName in
+Name of global variable.
+.AP char *addr in
+Address of C variable that is to be linked to \fIvarName\fR.
+.AP int type in
+Type of C variable.  Must be one of \fBTCL_LINK_INT\fR,
+\fBTCL_LINK_UINT\fR, \fBTCL_LINK_CHAR\fR, \fBTCL_LINK_UCHAR\fR,
+\fBTCL_LINK_SHORT\fR, \fBTCL_LINK_USHORT\fR, \fBTCL_LINK_LONG\fR,
+\fBTCL_LINK_ULONG\fR, \fBTCL_LINK_WIDE_INT\fR,
+\fBTCL_LINK_WIDE_UINT\fR, \fBTCL_LINK_FLOAT\fR,
+\fBTCL_LINK_DOUBLE\fR, \fBTCL_LINK_BOOLEAN\fR, or
+\fBTCL_LINK_STRING\fR, optionally OR'ed with \fBTCL_LINK_READ_ONLY\fR
+to make Tcl variable read-only.
+.BE
+.SH DESCRIPTION
+.PP
+\fBTcl_LinkVar\fR uses variable traces to keep the Tcl variable
+named by \fIvarName\fR in sync with the C variable at the address
+given by \fIaddr\fR.
+Whenever the Tcl variable is read the value of the C variable will
+be returned, and whenever the Tcl variable is written the C
+variable will be updated to have the same value.
+\fBTcl_LinkVar\fR normally returns \fBTCL_OK\fR;  if an error occurs
+while setting up the link (e.g. because \fIvarName\fR is the
+name of array) then \fBTCL_ERROR\fR is returned and the interpreter's result
+contains an error message.
+.PP
+The \fItype\fR argument specifies the type of the C variable,
+and must have one of the following values, optionally OR'ed with
+\fBTCL_LINK_READ_ONLY\fR:
+.TP
+\fBTCL_LINK_INT\fR
+The C variable is of type \fBint\fR.
+Any value written into the Tcl variable must have a proper integer
+form acceptable to \fBTcl_GetIntFromObj\fR;  attempts to write
+non-integer values into \fIvarName\fR will be rejected with
+Tcl errors.
+.TP
+\fBTCL_LINK_UINT\fR
+The C variable is of type \fBunsigned int\fR.
+Any value written into the Tcl variable must have a proper unsigned
+integer form acceptable to \fBTcl_GetWideIntFromObj\fR and in the
+platform's defined range for the \fBunsigned int\fR type; attempts to
+write non-integer values (or values outside the range) into
+\fIvarName\fR will be rejected with Tcl errors.
+.TP
+\fBTCL_LINK_CHAR\fR
+The C variable is of type \fBchar\fR.
+Any value written into the Tcl variable must have a proper integer
+form acceptable to \fBTcl_GetIntFromObj\fR and be in the range of the
+\fBchar\fR datatype; attempts to write non-integer or out-of-range
+values into \fIvarName\fR will be rejected with Tcl errors.
+.TP
+\fBTCL_LINK_UCHAR\fR
+The C variable is of type \fBunsigned char\fR.
+Any value written into the Tcl variable must have a proper unsigned
+integer form acceptable to \fBTcl_GetIntFromObj\fR and in the
+platform's defined range for the \fBunsigned char\fR type; attempts to
+write non-integer values (or values outside the range) into
+\fIvarName\fR will be rejected with Tcl errors.
+.TP
+\fBTCL_LINK_SHORT\fR
+The C variable is of type \fBshort\fR.
+Any value written into the Tcl variable must have a proper integer
+form acceptable to \fBTcl_GetIntFromObj\fR and be in the range of the
+\fBshort\fR datatype; attempts to write non-integer or out-of-range
+values into \fIvarName\fR will be rejected with Tcl errors.
+.TP
+\fBTCL_LINK_USHORT\fR
+The C variable is of type \fBunsigned short\fR.
+Any value written into the Tcl variable must have a proper unsigned
+integer form acceptable to \fBTcl_GetIntFromObj\fR and in the
+platform's defined range for the \fBunsigned short\fR type; attempts to
+write non-integer values (or values outside the range) into
+\fIvarName\fR will be rejected with Tcl errors.
+.TP
+\fBTCL_LINK_LONG\fR
+The C variable is of type \fBlong\fR.
+Any value written into the Tcl variable must have a proper integer
+form acceptable to \fBTcl_GetLongFromObj\fR; attempts to write
+non-integer or out-of-range
+values into \fIvarName\fR will be rejected with Tcl errors.
+.TP
+\fBTCL_LINK_ULONG\fR
+The C variable is of type \fBunsigned long\fR.
+Any value written into the Tcl variable must have a proper unsigned
+integer form acceptable to \fBTcl_GetWideIntFromObj\fR and in the
+platform's defined range for the \fBunsigned long\fR type; attempts to
+write non-integer values (or values outside the range) into
+\fIvarName\fR will be rejected with Tcl errors.
+.TP
+\fBTCL_LINK_DOUBLE\fR
+The C variable is of type \fBdouble\fR.
+Any value written into the Tcl variable must have a proper real
+form acceptable to \fBTcl_GetDoubleFromObj\fR;  attempts to write
+non-real values into \fIvarName\fR will be rejected with
+Tcl errors.
+.TP
+\fBTCL_LINK_FLOAT\fR
+The C variable is of type \fBfloat\fR.
+Any value written into the Tcl variable must have a proper real
+form acceptable to \fBTcl_GetDoubleFromObj\fR and must be within the
+range acceptable for a \fBfloat\fR; attempts to
+write non-real values (or values outside the range) into
+\fIvarName\fR will be rejected with Tcl errors.
+.TP
+\fBTCL_LINK_WIDE_INT\fR
+The C variable is of type \fBTcl_WideInt\fR (which is an integer type
+at least 64-bits wide on all platforms that can support it.)
+Any value written into the Tcl variable must have a proper integer
+form acceptable to \fBTcl_GetWideIntFromObj\fR;  attempts to write
+non-integer values into \fIvarName\fR will be rejected with
+Tcl errors.
+.TP
+\fBTCL_LINK_WIDE_UINT\fR
+The C variable is of type \fBTcl_WideUInt\fR (which is an unsigned
+integer type at least 64-bits wide on all platforms that can support
+it.)
+Any value written into the Tcl variable must have a proper unsigned
+integer form acceptable to \fBTcl_GetWideIntFromObj\fR (it will be
+cast to unsigned);
+.\" FIXME! Use bignums instead.
+attempts to write non-integer values into \fIvarName\fR will be
+rejected with Tcl errors.
+.TP
+\fBTCL_LINK_BOOLEAN\fR
+The C variable is of type \fBint\fR.
+If its value is zero then it will read from Tcl as
+.QW 0 ;
+otherwise it will read from Tcl as
+.QW 1 .
+Whenever \fIvarName\fR is
+modified, the C variable will be set to a 0 or 1 value.
+Any value written into the Tcl variable must have a proper boolean
+form acceptable to \fBTcl_GetBooleanFromObj\fR;  attempts to write
+non-boolean values into \fIvarName\fR will be rejected with
+Tcl errors.
+.TP
+\fBTCL_LINK_STRING\fR
+The C variable is of type \fBchar *\fR.
+If its value is not NULL then it must be a pointer to a string
+allocated with \fBTcl_Alloc\fR or \fBckalloc\fR.
+Whenever the Tcl variable is modified the current C string will be
+freed and new memory will be allocated to hold a copy of the variable's
+new value.
+If the C variable contains a NULL pointer then the Tcl variable
+will read as
+.QW NULL .
+.PP
+If the \fBTCL_LINK_READ_ONLY\fR flag is present in \fItype\fR then the
+variable will be read-only from Tcl, so that its value can only be
+changed by modifying the C variable.
+Attempts to write the variable from Tcl will be rejected with errors.
+.PP
+\fBTcl_UnlinkVar\fR removes the link previously set up for the
+variable given by \fIvarName\fR.  If there does not exist a link
+for \fIvarName\fR then the procedure has no effect.
+.PP
+\fBTcl_UpdateLinkedVar\fR may be invoked after the C variable has
+changed to force the Tcl variable to be updated immediately.
+In many cases this procedure is not needed, since any attempt to
+read the Tcl variable will return the latest value of the C variable.
+However, if a trace has been set on the Tcl variable (such as a
+Tk widget that wishes to display the value of the variable), the
+trace will not trigger when the C variable has changed.
+\fBTcl_UpdateLinkedVar\fR ensures that any traces on the Tcl
+variable are invoked.
+.PP
+Note that, as with any call to a Tcl interpreter, \fBTcl_UpdateLinkedVar\fR
+must be called from the same thread that created the interpreter. The safest
+mechanism is to ensure that the C variable is only ever updated from the same
+thread that created the interpreter (possibly in response to an event posted
+with \fBTcl_ThreadQueueEvent\fR), but when it is necessary to update the
+variable in a separate thread, it is advised that \fBTcl_AsyncMark\fR be used
+to indicate to the thread hosting the interpreter that it is ready to run
+\fBTcl_UpdateLinkedVar\fR.
+.SH "SEE ALSO"
+Tcl_TraceVar(3)
+.SH KEYWORDS
+boolean, integer, link, read-only, real, string, trace, variable
diff --git a/doc/ListObj.3 b/doc/ListObj.3
new file mode 100644
index 0000000..dc1ba53
--- /dev/null
+++ b/doc/ListObj.3
@@ -0,0 +1,251 @@
+'\"
+'\" Copyright (c) 1996-1997 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH Tcl_ListObj 3 8.0 Tcl "Tcl Library Procedures"
+.so man.macros
+.BS
+.SH NAME
+Tcl_ListObjAppendList, Tcl_ListObjAppendElement, Tcl_NewListObj, Tcl_SetListObj, Tcl_ListObjGetElements, Tcl_ListObjLength, Tcl_ListObjIndex, Tcl_ListObjReplace \- manipulate Tcl values as lists
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+int
+\fBTcl_ListObjAppendList\fR(\fIinterp, listPtr, elemListPtr\fR)
+.sp
+int
+\fBTcl_ListObjAppendElement\fR(\fIinterp, listPtr, objPtr\fR)
+.sp
+Tcl_Obj *
+\fBTcl_NewListObj\fR(\fIobjc, objv\fR)
+.sp
+\fBTcl_SetListObj\fR(\fIobjPtr, objc, objv\fR)
+.sp
+int
+\fBTcl_ListObjGetElements\fR(\fIinterp, listPtr, objcPtr, objvPtr\fR)
+.sp
+int
+\fBTcl_ListObjLength\fR(\fIinterp, listPtr, intPtr\fR)
+.sp
+int
+\fBTcl_ListObjIndex\fR(\fIinterp, listPtr, index, objPtrPtr\fR)
+.sp
+int
+\fBTcl_ListObjReplace\fR(\fIinterp, listPtr, first, count, objc, objv\fR)
+.SH ARGUMENTS
+.AS "Tcl_Obj *const" *elemListPtr in/out
+.AP Tcl_Interp *interp in
+If an error occurs while converting a value to be a list value,
+an error message is left in the interpreter's result value
+unless \fIinterp\fR is NULL.
+.AP Tcl_Obj *listPtr in/out
+Points to the list value to be manipulated.
+If \fIlistPtr\fR does not already point to a list value,
+an attempt will be made to convert it to one.
+.AP Tcl_Obj *elemListPtr in/out
+For \fBTcl_ListObjAppendList\fR, this points to a list value
+containing elements to be appended onto \fIlistPtr\fR.
+Each element of *\fIelemListPtr\fR will
+become a new element of \fIlistPtr\fR.
+If *\fIelemListPtr\fR is not NULL and
+does not already point to a list value,
+an attempt will be made to convert it to one.
+.AP Tcl_Obj *objPtr in
+For \fBTcl_ListObjAppendElement\fR,
+points to the Tcl value that will be appended to \fIlistPtr\fR.
+For \fBTcl_SetListObj\fR,
+this points to the Tcl value that will be converted to a list value
+containing the \fIobjc\fR elements of the array referenced by \fIobjv\fR.
+.AP int *objcPtr in
+Points to location where \fBTcl_ListObjGetElements\fR
+stores the number of element values in \fIlistPtr\fR.
+.AP Tcl_Obj ***objvPtr out
+A location where \fBTcl_ListObjGetElements\fR stores a pointer to an array
+of pointers to the element values of \fIlistPtr\fR.
+.AP int objc in
+The number of Tcl values that \fBTcl_NewListObj\fR
+will insert into a new list value,
+and \fBTcl_ListObjReplace\fR will insert into \fIlistPtr\fR.
+For \fBTcl_SetListObj\fR,
+the number of Tcl values to insert into \fIobjPtr\fR.
+.AP "Tcl_Obj *const" objv[] in
+An array of pointers to values.
+\fBTcl_NewListObj\fR will insert these values into a new list value
+and \fBTcl_ListObjReplace\fR will insert them into an existing \fIlistPtr\fR.
+Each value will become a separate list element.
+.AP int *intPtr out
+Points to location where \fBTcl_ListObjLength\fR
+stores the length of the list.
+.AP int index in
+Index of the list element that \fBTcl_ListObjIndex\fR
+is to return.
+The first element has index 0.
+.AP Tcl_Obj **objPtrPtr out
+Points to place where \fBTcl_ListObjIndex\fR is to store
+a pointer to the resulting list element value.
+.AP int first in
+Index of the starting list element that \fBTcl_ListObjReplace\fR
+is to replace.
+The list's first element has index 0.
+.AP int count in
+The number of elements that \fBTcl_ListObjReplace\fR
+is to replace.
+.BE
+
+.SH DESCRIPTION
+.PP
+Tcl list values have an internal representation that supports
+the efficient indexing and appending.
+The procedures described in this man page are used to
+create, modify, index, and append to Tcl list values from C code.
+.PP
+\fBTcl_ListObjAppendList\fR and \fBTcl_ListObjAppendElement\fR
+both add one or more values
+to the end of the list value referenced by \fIlistPtr\fR.
+\fBTcl_ListObjAppendList\fR appends each element of the list value
+referenced by \fIelemListPtr\fR while
+\fBTcl_ListObjAppendElement\fR appends the single value
+referenced by \fIobjPtr\fR.
+Both procedures will convert the value referenced by \fIlistPtr\fR
+to a list value if necessary.
+If an error occurs during conversion,
+both procedures return \fBTCL_ERROR\fR and leave an error message
+in the interpreter's result value if \fIinterp\fR is not NULL.
+Similarly, if \fIelemListPtr\fR does not already refer to a list value,
+\fBTcl_ListObjAppendList\fR will attempt to convert it to one
+and if an error occurs during conversion,
+will return \fBTCL_ERROR\fR
+and leave an error message in the interpreter's result value
+if interp is not NULL.
+Both procedures invalidate any old string representation of \fIlistPtr\fR
+and, if it was converted to a list value,
+free any old internal representation.
+Similarly, \fBTcl_ListObjAppendList\fR frees any old internal representation
+of \fIelemListPtr\fR if it converts it to a list value.
+After appending each element in \fIelemListPtr\fR,
+\fBTcl_ListObjAppendList\fR increments the element's reference count
+since \fIlistPtr\fR now also refers to it.
+For the same reason, \fBTcl_ListObjAppendElement\fR
+increments \fIobjPtr\fR's reference count.
+If no error occurs,
+the two procedures return \fBTCL_OK\fR after appending the values.
+.PP
+\fBTcl_NewListObj\fR and \fBTcl_SetListObj\fR
+create a new value or modify an existing value to hold
+the \fIobjc\fR elements of the array referenced by \fIobjv\fR
+where each element is a pointer to a Tcl value.
+If \fIobjc\fR is less than or equal to zero,
+they return an empty value.
+The new value's string representation is left invalid.
+The two procedures increment the reference counts
+of the elements in \fIobjc\fR since the list value now refers to them.
+The new list value returned by \fBTcl_NewListObj\fR
+has reference count zero.
+.PP
+\fBTcl_ListObjGetElements\fR returns a count and a pointer to an array of
+the elements in a list value.  It returns the count by storing it in the
+address \fIobjcPtr\fR.  Similarly, it returns the array pointer by storing
+it in the address \fIobjvPtr\fR.
+The memory pointed to is managed by Tcl and should not be freed or written
+to by the caller. If the list is empty, 0 is stored at \fIobjcPtr\fR
+and NULL at \fIobjvPtr\fR.
+If \fIlistPtr\fR is not already a list value, \fBTcl_ListObjGetElements\fR
+will attempt to convert it to one; if the conversion fails, it returns
+\fBTCL_ERROR\fR and leaves an error message in the interpreter's result
+value if \fIinterp\fR is not NULL.
+Otherwise it returns \fBTCL_OK\fR after storing the count and array pointer.
+.PP
+\fBTcl_ListObjLength\fR returns the number of elements in the list value
+referenced by \fIlistPtr\fR.
+It returns this count by storing an integer in the address \fIintPtr\fR.
+If the value is not already a list value,
+\fBTcl_ListObjLength\fR will attempt to convert it to one;
+if the conversion fails, it returns \fBTCL_ERROR\fR
+and leaves an error message in the interpreter's result value
+if \fIinterp\fR is not NULL.
+Otherwise it returns \fBTCL_OK\fR after storing the list's length.
+.PP
+The procedure \fBTcl_ListObjIndex\fR returns a pointer to the value
+at element \fIindex\fR in the list referenced by \fIlistPtr\fR.
+It returns this value by storing a pointer to it
+in the address \fIobjPtrPtr\fR.
+If \fIlistPtr\fR does not already refer to a list value,
+\fBTcl_ListObjIndex\fR will attempt to convert it to one;
+if the conversion fails, it returns \fBTCL_ERROR\fR
+and leaves an error message in the interpreter's result value
+if \fIinterp\fR is not NULL.
+If the index is out of range,
+that is, \fIindex\fR is negative or
+greater than or equal to the number of elements in the list,
+\fBTcl_ListObjIndex\fR stores a NULL in \fIobjPtrPtr\fR
+and returns \fBTCL_OK\fR.
+Otherwise it returns \fBTCL_OK\fR after storing the element's
+value pointer.
+The reference count for the list element is not incremented;
+the caller must do that if it needs to retain a pointer to the element.
+.PP
+\fBTcl_ListObjReplace\fR replaces zero or more elements
+of the list referenced by \fIlistPtr\fR
+with the \fIobjc\fR values in the array referenced by \fIobjv\fR.
+If \fIlistPtr\fR does not point to a list value,
+\fBTcl_ListObjReplace\fR will attempt to convert it to one;
+if the conversion fails, it returns \fBTCL_ERROR\fR
+and leaves an error message in the interpreter's result value
+if \fIinterp\fR is not NULL.
+Otherwise, it returns \fBTCL_OK\fR after replacing the values.
+If \fIobjv\fR is NULL, no new elements are added.
+If the argument \fIfirst\fR is zero or negative,
+it refers to the first element.
+If \fIfirst\fR is greater than or equal to the
+number of elements in the list, then no elements are deleted;
+the new elements are appended to the list.
+\fIcount\fR gives the number of elements to replace.
+If \fIcount\fR is zero or negative then no elements are deleted;
+the new elements are simply inserted before the one
+designated by \fIfirst\fR.
+\fBTcl_ListObjReplace\fR invalidates \fIlistPtr\fR's
+old string representation.
+The reference counts of any elements inserted from \fIobjv\fR
+are incremented since the resulting list now refers to them.
+Similarly, the reference counts for any replaced values are decremented.
+.PP
+Because \fBTcl_ListObjReplace\fR combines
+both element insertion and deletion,
+it can be used to implement a number of list operations.
+For example, the following code inserts the \fIobjc\fR values
+referenced by the array of value pointers \fIobjv\fR
+just before the element \fIindex\fR of the list referenced by \fIlistPtr\fR:
+.PP
+.CS
+result = \fBTcl_ListObjReplace\fR(interp, listPtr, index, 0,
+        objc, objv);
+.CE
+.PP
+Similarly, the following code appends the \fIobjc\fR values
+referenced by the array \fIobjv\fR
+to the end of the list \fIlistPtr\fR:
+.PP
+.CS
+result = \fBTcl_ListObjLength\fR(interp, listPtr, &length);
+if (result == TCL_OK) {
+    result = \fBTcl_ListObjReplace\fR(interp, listPtr, length, 0,
+            objc, objv);
+}
+.CE
+.PP
+The \fIcount\fR list elements starting at \fIfirst\fR can be deleted
+by simply calling \fBTcl_ListObjReplace\fR
+with a NULL \fIobjvPtr\fR:
+.PP
+.CS
+result = \fBTcl_ListObjReplace\fR(interp, listPtr, first, count,
+        0, NULL);
+.CE
+.SH "SEE ALSO"
+Tcl_NewObj(3), Tcl_DecrRefCount(3), Tcl_IncrRefCount(3), Tcl_GetObjResult(3)
+.SH KEYWORDS
+append, index, insert, internal representation, length, list, list value,
+list type, value, value type, replace, string representation
diff --git a/doc/Load.3 b/doc/Load.3
new file mode 100644
index 0000000..0ffaf57
--- /dev/null
+++ b/doc/Load.3
@@ -0,0 +1,70 @@
+'\"
+'\" Copyright (c) 2009-2010 Kevin B. Kenny
+'\" Copyright (c) 2010 Donal K. Fellows
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\" 
+.TH Load 3 8.6 Tcl "Tcl Library Procedures"
+.so man.macros
+.BS
+.SH NAME
+Tcl_LoadFile, Tcl_FindSymbol \- platform-independent dynamic library loading
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+int
+\fBTcl_LoadFile\fR(\fIinterp, pathPtr, symbols, flags, procPtrs, loadHandlePtr\fR)
+.sp
+void *
+\fBTcl_FindSymbol\fR(\fIinterp, loadHandle, symbol\fR)
+.SH ARGUMENTS
+.AS Tcl_LoadHandle loadHandle in
+.AP Tcl_Interp *interp in
+Interpreter to use for reporting error messages.
+.AP Tcl_Obj *pathPtr in
+The name of the file to load. If it is a single name, the library search path
+of the current environment will be used to resolve it.
+.AP "const char *const" symbols[] in
+Array of names of symbols to be resolved during the load of the library, or
+NULL if no symbols are to be resolved. If an array is given, the last entry in
+the array must be NULL.
+.AP int flags in
+The value should normally be 0, but \fITCL_LOAD_GLOBAL\fR or \fITCL_LOAD_LAZY\fR
+or a combination of those two is allowed as well.
+.AP void *procPtrs out
+Points to an array that will hold the addresses of the functions described in
+the \fIsymbols\fR argument. Should be NULL if no symbols are to be resolved.
+.AP Tcl_LoadHandle *loadHandlePtr out
+Points to a variable that will hold the handle to the abstract token
+describing the library that has been loaded.
+.AP Tcl_LoadHandle loadHandle in
+Abstract token describing the library to look up a symbol in.
+.AP "const char" *symbol in
+The name of the symbol to look up.
+.BE
+.SH DESCRIPTION
+.PP
+\fBTcl_LoadFile\fR loads a file from the filesystem (including potentially any
+virtual filesystem that has been installed) and provides a handle to it that
+may be used in further operations. The \fIsymbols\fR array, if non-NULL,
+supplies a set of names of symbols (typically functions) that must be resolved
+from the library and which will be stored in the array indicated by
+\fIprocPtrs\fR. If any of the symbols is not resolved, the loading of the file
+will fail with an error message left in the interpreter (if that is non-NULL).
+The result of \fBTcl_LoadFile\fR is a standard Tcl error code. The library may
+be unloaded with \fBTcl_FSUnloadFile\fR.
+.PP
+\fBTcl_FindSymbol\fR locates a symbol in a loaded library and returns it. If
+the symbol cannot be found, it returns NULL and sets an error message in the
+given \fIinterp\fR (if that is non-NULL). Note that it is unsafe to use this
+operation on a handle that has been passed to \fBTcl_FSUnloadFile\fR.
+.SH "SEE ALSO"
+Tcl_FSLoadFile(3), Tcl_FSUnloadFile(3), load(n), unload(n)
+.SH KEYWORDS
+binary code, loading, shared library
+'\" Local Variables:
+'\" mode: nroff
+'\" fill-column: 78
+'\" End:
diff --git a/doc/Method.3 b/doc/Method.3
new file mode 100644
index 0000000..225da00
--- /dev/null
+++ b/doc/Method.3
@@ -0,0 +1,251 @@
+'\"
+'\" Copyright (c) 2007 Donal K. Fellows
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH Tcl_Method 3 0.1 TclOO "TclOO Library Functions"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+Tcl_ClassSetConstructor, Tcl_ClassSetDestructor, Tcl_MethodDeclarerClass, Tcl_MethodDeclarerObject, Tcl_MethodIsPublic, Tcl_MethodIsType, Tcl_MethodName, Tcl_NewInstanceMethod, Tcl_NewMethod, Tcl_ObjectContextInvokeNext, Tcl_ObjectContextIsFiltering, Tcl_ObjectContextMethod, Tcl_ObjectContextObject, Tcl_ObjectContextSkippedArgs \- manipulate methods and method-call contexts
+.SH SYNOPSIS
+.nf
+\fB#include <tclOO.h>\fR
+.sp
+Tcl_Method
+\fBTcl_NewMethod\fR(\fIinterp, class, nameObj, isPublic,
+              methodTypePtr, clientData\fR)
+.sp
+Tcl_Method
+\fBTcl_NewInstanceMethod\fR(\fIinterp, object, nameObj, isPublic,
+                      methodTypePtr, clientData\fR)
+.sp
+\fBTcl_ClassSetConstructor\fR(\fIinterp, class, method\fR)
+.sp
+\fBTcl_ClassSetDestructor\fR(\fIinterp, class, method\fR)
+.sp
+Tcl_Class
+\fBTcl_MethodDeclarerClass\fR(\fImethod\fR)
+.sp
+Tcl_Object
+\fBTcl_MethodDeclarerObject\fR(\fImethod\fR)
+.sp
+Tcl_Obj *
+\fBTcl_MethodName\fR(\fImethod\fR)
+.sp
+int
+\fBTcl_MethodIsPublic\fR(\fImethod\fR)
+.sp
+int
+\fBTcl_MethodIsType\fR(\fImethod, methodTypePtr, clientDataPtr\fR)
+.sp
+int
+\fBTcl_ObjectContextInvokeNext\fR(\fIinterp, context, objc, objv, skip\fR)
+.sp
+int
+\fBTcl_ObjectContextIsFiltering\fR(\fIcontext\fR)
+.sp
+Tcl_Method
+\fBTcl_ObjectContextMethod\fR(\fIcontext\fR)
+.sp
+Tcl_Object
+\fBTcl_ObjectContextObject\fR(\fIcontext\fR)
+.sp
+int
+\fBTcl_ObjectContextSkippedArgs\fR(\fIcontext\fR)
+.SH ARGUMENTS
+.AS ClientData clientData in
+.AP Tcl_Interp *interp in/out
+The interpreter holding the object or class to create or update a method in.
+.AP Tcl_Object object in
+The object to create the method in.
+.AP Tcl_Class class in
+The class to create the method in.
+.AP Tcl_Obj *nameObj in
+The name of the method to create. Should not be NULL unless creating
+constructors or destructors.
+.AP int isPublic in
+A flag saying what the visibility of the method is. The only supported public
+values of this flag are 0 for a non-exported method, and 1 for an exported
+method.
+.AP Tcl_MethodType *methodTypePtr in
+A description of the type of the method to create, or the type of method to
+compare against.
+.AP ClientData clientData in
+A piece of data that is passed to the implementation of the method without
+interpretation.
+.AP ClientData *clientDataPtr out
+A pointer to a variable in which to write the \fIclientData\fR value supplied
+when the method was created. If NULL, the \fIclientData\fR value will not be
+retrieved.
+.AP Tcl_Method method in
+A reference to a method to query.
+.AP Tcl_ObjectContext context in
+A reference to a method-call context. Note that client code \fImust not\fR
+retain a reference to a context.
+.AP int objc in
+The number of arguments to pass to the method implementation.
+.AP "Tcl_Obj *const" *objv in
+An array of arguments to pass to the method implementation.
+.AP int skip in
+The number of arguments passed to the method implementation that do not
+represent "real" arguments.
+.BE
+.SH DESCRIPTION
+.PP
+A method is an operation carried out on an object that is associated with the
+object. Every method must be attached to either an object or a class; methods
+attached to a class are associated with all instances (direct and indirect) of
+that class.
+.PP
+Given a method, the entity that declared it can be found using
+\fBTcl_MethodDeclarerClass\fR which returns the class that the method is
+attached to (or NULL if the method is not attached to any class) and
+\fBTcl_MethodDeclarerObject\fR which returns the object that the method is
+attached to (or NULL if the method is not attached to an object). The name of
+the method can be retrieved with \fBTcl_MethodName\fR and whether the method
+is exported is retrieved with \fBTcl_MethodIsPublic\fR. The type of the method
+can also be introspected upon to a limited degree; the function
+\fBTcl_MethodIsType\fR returns whether a method is of a particular type,
+assigning the per-method \fIclientData\fR to the variable pointed to by
+\fIclientDataPtr\fR if (that is non-NULL) if the type is matched.
+.SS "METHOD CREATION"
+.PP
+Methods are created by \fBTcl_NewMethod\fR and \fBTcl_NewInstanceMethod\fR,
+which
+create a method attached to a class or an object respectively. In both cases,
+the \fInameObj\fR argument gives the name of the method to create, the
+\fIisPublic\fR argument states whether the method should be exported
+initially, the \fImethodTypePtr\fR argument describes the implementation of
+the method (see the \fBMETHOD TYPES\fR section below) and the \fIclientData\fR
+argument gives some implementation-specific data that is passed on to the
+implementation of the method when it is called.
+.PP
+When the \fInameObj\fR argument to \fBTcl_NewMethod\fR is NULL, an
+unnamed method is created, which is used for constructors and destructors.
+Constructors should be installed into their class using the
+\fBTcl_ClassSetConstructor\fR function, and destructors (which must not
+require any arguments) should be installed into their class using the
+\fBTcl_ClassSetDestructor\fR function. Unnamed methods should not be used for
+any other purpose, and named methods should not be used as either constructors
+or destructors. Also note that a NULL \fImethodTypePtr\fR is used to provide
+internal signaling, and should not be used in client code.
+.SS "METHOD CALL CONTEXTS"
+.PP
+When a method is called, a method-call context reference is passed in as one
+of the arguments to the implementation function. This context can be inspected
+to provide information about the caller, but should not be retained beyond the
+moment when the method call terminates.
+.PP
+The method that is being called can be retrieved from the context by using
+\fBTcl_ObjectContextMethod\fR, and the object that caused the method to be
+invoked can be retrieved with \fBTcl_ObjectContextObject\fR. The number of
+arguments that are to be skipped (e.g. the object name and method name in a
+normal method call) is read with \fBTcl_ObjectContextSkippedArgs\fR, and the
+context can also report whether it is working as a filter for another method
+through \fBTcl_ObjectContextIsFiltering\fR.
+.PP
+During the execution of a method, the method implementation may choose to
+invoke the stages of the method call chain that come after the current method
+implementation. This (the core of the \fBnext\fR command) is done using
+\fBTcl_ObjectContextInvokeNext\fR. Note that this function does not manipulate
+the call-frame stack, unlike the \fBnext\fR command; if the method
+implementation has pushed one or more extra frames on the stack as part of its
+implementation, it is also responsible for temporarily popping those frames
+from the stack while the \fBTcl_ObjectContextInvokeNext\fR function is
+executing. Note also that the method-call context is \fInever\fR deleted
+during the execution of this function.
+.SH "METHOD TYPES"
+.PP
+The types of methods are described by a pointer to a Tcl_MethodType structure,
+which is defined as:
+.PP
+.CS
+typedef struct {
+    int \fIversion\fR;
+    const char *\fIname\fR;
+    Tcl_MethodCallProc *\fIcallProc\fR;
+    Tcl_MethodDeleteProc *\fIdeleteProc\fR;
+    Tcl_CloneProc *\fIcloneProc\fR;
+} \fBTcl_MethodType\fR;
+.CE
+.PP
+The \fIversion\fR field allows for future expansion of the structure, and
+should always be declared equal to TCL_OO_METHOD_VERSION_CURRENT. The
+\fIname\fR field provides a human-readable name for the type, and is the value
+that is exposed via the \fBinfo class methodtype\fR and
+\fBinfo object methodtype\fR Tcl commands.
+.PP
+The \fIcallProc\fR field gives a function that is called when the method is
+invoked; it must never be NULL.
+.PP
+The \fIdeleteProc\fR field gives a function that is used to delete a
+particular method, and is called when the method is replaced or removed; if
+the field is NULL, it is assumed that the method's \fIclientData\fR needs no
+special action to delete.
+.PP
+The \fIcloneProc\fR field is either a function that is used to copy a method's
+\fIclientData\fR (as part of \fBTcl_CopyObjectInstance\fR) or NULL to indicate
+that the \fIclientData\fR can just be copied directly.
+.SS "TCL_METHODCALLPROC FUNCTION SIGNATURE"
+.PP
+Functions matching this signature are called when the method is invoked.
+.PP
+.CS
+typedef int \fBTcl_MethodCallProc\fR(
+        ClientData \fIclientData\fR,
+        Tcl_Interp *\fIinterp\fR,
+        Tcl_ObjectContext \fIobjectContext\fR,
+        int \fIobjc\fR,
+        Tcl_Obj *const *\fIobjv\fR);
+.CE
+.PP
+The \fIclientData\fR argument to a Tcl_MethodCallProc is the value that was
+given when the method was created, the \fIinterp\fR is a place in which to
+execute scripts and access variables as well as being where to put the result
+of the method, and the \fIobjc\fR and \fIobjv\fR fields give the parameter
+objects to the method. The calling context of the method can be discovered
+through the \fIobjectContext\fR argument, and the return value from a
+Tcl_MethodCallProc is any Tcl return code (e.g. TCL_OK, TCL_ERROR).
+.SS "TCL_METHODDELETEPROC FUNCTION SIGNATURE"
+.PP
+Functions matching this signature are used when a method is deleted, whether
+through a new method being created or because the object or class is deleted.
+.PP
+.CS
+typedef void \fBTcl_MethodDeleteProc\fR(
+        ClientData \fIclientData\fR);
+.CE
+.PP
+The \fIclientData\fR argument to a Tcl_MethodDeleteProc will be the same as
+the value passed to the \fIclientData\fR argument to \fBTcl_NewMethod\fR or
+\fBTcl_NewInstanceMethod\fR when the method was created.
+.SS "TCL_CLONEPROC FUNCTION SIGNATURE"
+.PP
+Functions matching this signature are used to copy a method when the object or
+class is copied using \fBTcl_CopyObjectInstance\fR (or \fBoo::copy\fR).
+.PP
+.CS
+typedef int \fBTcl_CloneProc\fR(
+        Tcl_Interp *\fIinterp\fR,
+        ClientData \fIoldClientData\fR,
+        ClientData *\fInewClientDataPtr\fR);
+.CE
+.PP
+The \fIinterp\fR argument gives a place to write an error message when the
+attempt to clone the object is to fail, in which case the clone procedure must
+also return TCL_ERROR; it should return TCL_OK otherwise.
+The \fIoldClientData\fR field to a Tcl_CloneProc gives the value from the
+method being copied from, and the \fInewClientDataPtr\fR field will point to
+a variable in which to write the value for the method being copied to.
+.SH "SEE ALSO"
+Class(3), oo::class(n), oo::define(n), oo::object(n)
+.SH KEYWORDS
+constructor, method, object
+
+.\" Local variables:
+.\" mode: nroff
+.\" fill-column: 78
+.\" End:
diff --git a/doc/NRE.3 b/doc/NRE.3
new file mode 100644
index 0000000..ff0d108
--- /dev/null
+++ b/doc/NRE.3
@@ -0,0 +1,328 @@
+.\"
+.\" Copyright (c) 2008 by Kevin B. Kenny.
+.\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH NRE 3 8.6 Tcl "Tcl Library Procedures"
+.so man.macros
+.BS
+.SH NAME
+Tcl_NRCreateCommand, Tcl_NRCallObjProc, Tcl_NREvalObj, Tcl_NREvalObjv, Tcl_NRCmdSwap, Tcl_NRExprObj, Tcl_NRAddCallback \- Non-Recursive (stackless) evaluation of Tcl scripts.
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+Tcl_Command
+\fBTcl_NRCreateCommand\fR(\fIinterp, cmdName, proc, nreProc, clientData,
+                    deleteProc\fR)
+.sp
+int
+\fBTcl_NRCallObjProc\fR(\fIinterp, nreProc, clientData, objc, objv\fR)
+.sp
+int
+\fBTcl_NREvalObj\fR(\fIinterp, objPtr, flags\fR)
+.sp
+int
+\fBTcl_NREvalObjv\fR(\fIinterp, objc, objv, flags\fR)
+.sp
+int
+\fBTcl_NRCmdSwap\fR(\fIinterp, cmd, objc, objv, flags\fR)
+.sp
+int
+\fBTcl_NRExprObj\fR(\fIinterp, objPtr, resultPtr\fR)
+.sp
+void
+\fBTcl_NRAddCallback\fR(\fIinterp, postProcPtr, data0, data1, data2, data3\fR)
+.fi
+.SH ARGUMENTS
+.AS Tcl_CmdDeleteProc *interp in
+.AP Tcl_Interp *interp in
+Interpreter in which to create or evaluate a command.
+.AP char *cmdName in
+Name of a new command to create.
+.AP Tcl_ObjCmdProc *proc in
+Implementation of a command that will be called whenever \fIcmdName\fR
+is invoked as a command in the unoptimized way.
+.AP Tcl_ObjCmdProc *nreProc in
+Implementation of a command that will be called whenever \fIcmdName\fR
+is invoked and requested to conserve the C stack.
+.AP ClientData clientData in
+Arbitrary one-word value that will be passed to \fIproc\fR, \fInreProc\fR,
+\fIdeleteProc\fR and \fIobjProc\fR.
+.AP Tcl_CmdDeleteProc *deleteProc in/out
+Procedure to call before \fIcmdName\fR is deleted from the interpreter.
+This procedure allows for command-specific cleanup. If \fIdeleteProc\fR
+is \fBNULL\fR, then no procedure is called before the command is deleted.
+.AP int objc in
+Count of parameters provided to the implementation of a command.
+.AP Tcl_Obj **objv in
+Pointer to an array of Tcl values. Each value holds the value of a
+single word in the command to execute.
+.AP Tcl_Obj *objPtr in
+Pointer to a Tcl_Obj whose value is a script or expression to execute.
+.AP int flags in
+ORed combination of flag bits that specify additional options.
+\fBTCL_EVAL_GLOBAL\fR is the only flag that is currently supported.
+.\" TODO: This is a lie. But kbk didn't grasp TCL_EVAL_INVOKE and
+.\"       TCL_EVAL_NOERR well enough to document them.
+.AP Tcl_Command cmd in
+Token for a command that is to be used instead of the currently
+executing command.
+.AP Tcl_Obj *resultPtr out
+Pointer to an unshared Tcl_Obj where the result of expression
+evaluation is written.
+.AP Tcl_NRPostProc *postProcPtr in
+Pointer to a function that will be invoked when the command currently
+executing in the interpreter designated by \fIinterp\fR completes.
+.AP ClientData data0 in
+.AP ClientData data1 in
+.AP ClientData data2 in
+.AP ClientData data3 in
+\fIdata0\fR through \fIdata3\fR are four one-word values that will be passed
+to the function designated by \fIpostProcPtr\fR when it is invoked.
+.BE
+.SH DESCRIPTION
+.PP
+This series of C functions provides an interface whereby commands that
+are implemented in C can be evaluated, and invoke Tcl commands scripts
+and scripts, without consuming space on the C stack. The non-recursive
+evaluation is done by installing a \fItrampoline\fR, a small piece of
+code that invokes a command or script, and then executes a series of
+callbacks when the command or script returns.
+.PP
+The \fBTcl_NRCreateCommand\fR function creates a Tcl command in the
+interpreter designated by \fIinterp\fR that is prepared to handle
+nonrecursive evaluation with a trampoline. The \fIcmdName\fR argument
+gives the name of the new command. If \fIcmdName\fR contains any
+namespace qualifiers, then the new command is added to the specified
+namespace; otherwise, it is added to the global namespace. \fIproc\fR
+gives the procedure that will be called when the interpreter wishes to
+evaluate the command in an unoptimized manner, and \fInreProc\fR is
+the procedure that will be called when the interpreter wishes to
+evaluate the command using a trampoline. \fIdeleteProc\fR is a
+function that will be called before the command is deleted from the
+interpreter. When any of the three functions is invoked, it is passed
+the \fIclientData\fR parameter.
+.PP
+\fBTcl_NRCreateCommand\fR deletes any existing command
+\fIname\fR already associated with the interpreter
+(however see below for an exception where the existing command
+is not deleted).
+It returns a token that may be used to refer
+to the command in subsequent calls to \fBTcl_GetCommandName\fR.
+If \fBTcl_NRCreateCommand\fR is called for an interpreter that is in
+the process of being deleted, then it does not create a new command,
+does not delete any existing command of the same name, and returns NULL.
+.PP
+The \fIproc\fR and \fInreProc\fR function are expected to conform to
+all the rules set forth for the \fIproc\fR argument to
+\fBTcl_CreateObjCommand\fR(3) (\fIq.v.\fR).
+.PP
+When a command that is written to cope with evaluation via trampoline
+is invoked without a trampoline on the stack, it will usually respond
+to the invocation by creating a trampoline and calling the
+trampoline-enabled implementation of the same command. This call is done by
+means of \fBTcl_NRCallObjProc\fR. In the call to
+\fBTcl_NRCallObjProc\fR, the \fIinterp\fR, \fIclientData\fR,
+\fIobjc\fR and \fIobjv\fR parameters should be the same ones that were
+passed to \fIproc\fR. The \fInreProc\fR parameter should designate the
+trampoline-enabled implementation of the command.
+.PP
+\fBTcl_NREvalObj\fR arranges for the script contained in \fIobjPtr\fR
+to be evaluated in the interpreter designated by \fIinterp\fR after
+the current command (which must be trampoline-enabled) returns. It is
+the method by which a command may invoke a script without consuming
+space on the C stack. Similarly, \fBTcl_NREvalObjv\fR arranges to
+invoke a single Tcl command whose words have already been separated
+and substituted. The \fIobjc\fR and \fIobjv\fR parameters give the
+words of the command to be evaluated when execution reaches the
+trampoline.
+.PP
+\fBTcl_NRCmdSwap\fR allows for trampoline evaluation of a command whose
+resolution is already known.  The \fIcmd\fR parameter gives a
+\fBTcl_Command\fR token (returned from \fBTcl_CreateObjCommand\fR or
+\fBTcl_GetCommandFromObj\fR) identifying the command to be invoked in
+the trampoline; this command must match the word in \fIobjv[0]\fR.
+The remaining arguments are as for \fBTcl_NREvalObjv\fR.
+.PP
+\fBTcl_NREvalObj\fR, \fBTcl_NREvalObjv\fR and \fBTcl_NRCmdSwap\fR
+all accept a \fIflags\fR parameter, which is an OR-ed-together set of
+bits to control evaluation. At the present time, the only supported flag
+available to callers is \fBTCL_EVAL_GLOBAL\fR.
+.\" TODO: Again, this is a lie. Do we want to explain TCL_EVAL_INVOKE
+.\"       and TCL_EVAL_NOERR?
+If the \fBTCL_EVAL_GLOBAL\fR flag is set, the script or command is
+evaluated in the global namespace. If it is not set, it is evaluated
+in the current namespace.
+.PP
+\fBTcl_NRExprObj\fR arranges for the expression contained in \fIobjPtr\fR
+to be evaluated in the interpreter designated by \fIinterp\fR after
+the current command (which must be trampoline-enabled) returns. It is
+the method by which a command may evaluate a Tcl expression without consuming
+space on the C stack.  The argument \fIresultPtr\fR is a pointer to an
+unshared Tcl_Obj where the result of expression evaluation is to be written.
+If expression evaluation returns any code other than TCL_OK, the
+\fIresultPtr\fR value is left untouched.
+.PP
+All of the routines return \fBTCL_OK\fR if command or expression invocation
+has been scheduled successfully. If for any reason the scheduling cannot
+be completed (for example, if the interpreter is unable to find
+the requested command), they return \fBTCL_ERROR\fR with an
+appropriate message left in the interpreter's result.
+.PP
+\fBTcl_NRAddCallback\fR arranges to have a C function called when the
+current trampoline-enabled command in the Tcl interpreter designated
+by \fIinterp\fR returns.  The \fIpostProcPtr\fR argument is a pointer
+to the callback function, which must have arguments and return value
+consistent with the \fBTcl_NRPostProc\fR data type:
+.PP
+.CS
+typedef int
+\fBTcl_NRPostProc\fR(
+        \fBClientData\fR \fIdata\fR[],
+        \fBTcl_Interp\fR *\fIinterp\fR,
+        int \fIresult\fR);
+.CE
+.PP
+When the trampoline invokes the callback function, the \fIdata\fR
+parameter will point to an array containing the four one-word
+quantities that were passed to \fBTcl_NRAddCallback\fR in the
+\fIdata0\fR through \fIdata3\fR parameters. The Tcl interpreter will
+be designated by the \fIinterp\fR parameter, and the \fIresult\fR
+parameter will contain the result (\fBTCL_OK\fR, \fBTCL_ERROR\fR,
+\fBTCL_RETURN\fR, \fBTCL_BREAK\fR or \fBTCL_CONTINUE\fR) that was
+returned by the command evaluation. The callback function is expected,
+in turn, either to return a \fIresult\fR to control further evaluation.
+.PP
+Multiple \fBTcl_NRAddCallback\fR invocations may request multiple
+callbacks, which may be to the same or different callback
+functions. If multiple callbacks are requested, they are executed in
+last-in, first-out order, that is, the most recently requested
+callback is executed first.
+.SH EXAMPLE
+.PP
+The usual pattern for Tcl commands that invoke other Tcl commands
+is something like:
+.PP
+.CS
+int
+\fITheCmdOldObjProc\fR(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const objv[])
+{
+    int result;
+    Tcl_Obj *objPtr;
+
+    \fI... preparation ...\fR
+
+    result = \fBTcl_EvalObjEx\fR(interp, objPtr, 0);
+
+    \fI... postprocessing ...\fR
+
+    return result;
+}
+\fBTcl_CreateObjCommand\fR(interp, "theCommand",
+        \fITheCmdOldObjProc\fR, clientData, TheCmdDeleteProc);
+.CE
+.PP
+To enable a command like this one for trampoline-based evaluation,
+it must be split into three pieces:
+.IP \(bu
+A non-trampoline implementation, \fITheCmdNewObjProc\fR,
+which will simply create a trampoline
+and invoke the trampoline-based implementation.
+.IP \(bu
+A trampoline-enabled implementation, \fITheCmdNRObjProc\fR.  This
+function will perform the initialization, request that the trampoline
+call the postprocessing routine after command evaluation, and finally,
+request that the trampoline call the inner command.
+.IP \(bu
+A postprocessing routine, \fITheCmdPostProc\fR. This function will
+perform the postprocessing formerly done after the return from the
+inner command in \fITheCmdObjProc\fR.
+.PP
+The non-trampoline implementation is simple and stylized, containing
+a single statement:
+.PP
+.CS
+int
+\fITheCmdNewObjProc\fR(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const objv[])
+{
+    return \fBTcl_NRCallObjProc\fR(interp, \fITheCmdNRObjProc\fR,
+            clientData, objc, objv);
+}
+.CE
+.PP
+The trampoline-enabled implementation requests postprocessing,
+and returns to the trampoline requesting command evaluation.
+.PP
+.CS
+int
+\fITheCmdNRObjProc\fR
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const objv[])
+{
+    Tcl_Obj *objPtr;
+
+    \fI... preparation ...\fR
+
+    \fBTcl_NRAddCallback\fR(interp, \fITheCmdPostProc\fR,
+            data0, data1, data2, data3);
+    /* \fIdata0 .. data3\fR are up to four one-word items to
+     * pass to the postprocessing procedure */
+
+    return \fBTcl_NREvalObj\fR(interp, objPtr, 0);
+}
+.CE
+.PP
+The postprocessing procedure does whatever the original command did
+upon return from the inner evaluation.
+.PP
+.CS
+int
+\fITheCmdNRPostProc\fR(
+    ClientData data[],
+    Tcl_Interp *interp,
+    int result)
+{
+    /* \fIdata[0] .. data[3]\fR are the four words of data
+     * passed to \fBTcl_NRAddCallback\fR */
+
+    \fI... postprocessing ...\fR
+
+    return result;
+}
+.CE
+.PP
+If \fItheCommand\fR is a command that results in multiple commands or
+scripts being evaluated, its postprocessing routine may schedule
+additional postprocessing and then request another command evaluation
+by means of \fBTcl_NREvalObj\fR or one of the other evaluation
+routines. Looping and sequencing constructs may be implemented in this way.
+.PP
+Finally, to install a trampoline-enabled command in the interpreter,
+\fBTcl_NRCreateCommand\fR is used in place of
+\fBTcl_CreateObjCommand\fR.  It accepts two command procedures instead
+of one. The first is for use when no trampoline is yet on the stack,
+and the second is for use when there is already a trampoline in place.
+.PP
+.CS
+\fBTcl_NRCreateCommand\fR(interp, "theCommand",
+        \fITheCmdNewObjProc\fR, \fITheCmdNRObjProc\fR, clientData,
+        TheCmdDeleteProc);
+.CE
+.SH "SEE ALSO"
+Tcl_CreateCommand(3), Tcl_CreateObjCommand(3), Tcl_EvalObjEx(3), Tcl_GetCommandFromObj(3), Tcl_ExprObj(3)
+.SH KEYWORDS
+stackless, nonrecursive, execute, command, global, value, result, script
+.SH COPYRIGHT
+Copyright (c) 2008 by Kevin B. Kenny
diff --git a/doc/Namespace.3 b/doc/Namespace.3
new file mode 100644
index 0000000..be89597
--- /dev/null
+++ b/doc/Namespace.3
@@ -0,0 +1,165 @@
+'\"
+'\" Copyright (c) 2003 Donal K. Fellows
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\" 
+'\" Note that some of these functions do not seem to belong, but they
+'\" were all introduced with the same TIP (#139)
+'\" 
+.TH Tcl_Namespace 3 8.5 Tcl "Tcl Library Procedures"
+.so man.macros
+.BS
+.SH NAME
+Tcl_AppendExportList, Tcl_CreateNamespace, Tcl_DeleteNamespace, Tcl_Export, Tcl_FindCommand, Tcl_FindNamespace, Tcl_ForgetImport, Tcl_GetCurrentNamespace, Tcl_GetGlobalNamespace, Tcl_GetNamespaceUnknownHandler, Tcl_Import, Tcl_SetNamespaceUnknownHandler \- manipulate namespaces
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+Tcl_Namespace *
+\fBTcl_CreateNamespace\fR(\fIinterp, name, clientData, deleteProc\fR)
+.sp
+\fBTcl_DeleteNamespace\fR(\fInsPtr\fR)
+.sp
+int
+\fBTcl_AppendExportList\fR(\fIinterp, nsPtr, objPtr\fR)
+.sp
+int
+\fBTcl_Export\fR(\fIinterp, nsPtr, pattern, resetListFirst\fR)
+.sp
+int
+\fBTcl_Import\fR(\fIinterp, nsPtr, pattern, allowOverwrite\fR)
+.sp
+int
+\fBTcl_ForgetImport\fR(\fIinterp, nsPtr, pattern\fR)
+.sp
+Tcl_Namespace *
+\fBTcl_GetCurrentNamespace\fR(\fIinterp\fR)
+.sp
+Tcl_Namespace *
+\fBTcl_GetGlobalNamespace\fR(\fIinterp\fR)
+.sp
+Tcl_Namespace *
+\fBTcl_FindNamespace\fR(\fIinterp, name, contextNsPtr, flags\fR)
+.sp
+Tcl_Command
+\fBTcl_FindCommand\fR(\fIinterp, name, contextNsPtr, flags\fR)
+.sp
+Tcl_Obj *
+\fBTcl_GetNamespaceUnknownHandler(\fIinterp, nsPtr\fR)
+.sp
+int
+\fBTcl_SetNamespaceUnknownHandler(\fIinterp, nsPtr, handlerPtr\fR)
+.SH ARGUMENTS
+.AS Tcl_NamespaceDeleteProc allowOverwrite in/out
+.AP Tcl_Interp *interp in/out
+The interpreter in which the namespace exists and where name lookups
+are performed. Also where error result messages are written.
+.AP "const char" *name in
+The name of the namespace or command to be created or accessed.
+.AP ClientData clientData in
+A context pointer by the creator of the namespace.  Not interpreted by
+Tcl at all.
+.AP Tcl_NamespaceDeleteProc *deleteProc in
+A pointer to function to call when the namespace is deleted, or NULL
+if no such callback is to be performed.
+.AP Tcl_Namespace *nsPtr in
+The namespace to be manipulated, or NULL (for other than
+\fBTcl_DeleteNamespace\fR) to manipulate the current namespace.
+.AP Tcl_Obj *objPtr out
+A reference to an unshared value to which the function output will be
+written.
+.AP "const char" *pattern in
+The glob-style pattern (see \fBTcl_StringMatch\fR) that describes the
+commands to be imported or exported.
+.AP int resetListFirst in
+Whether the list of export patterns should be reset before adding the
+current pattern to it.
+.AP int allowOverwrite in
+Whether new commands created by this import action can overwrite
+existing commands.
+.AP Tcl_Namespace *contextNsPtr in
+The location in the namespace hierarchy where the search for a
+namespace or command should be conducted relative to when the search
+term is not rooted at the global namespace.  NULL indicates the
+current namespace.
+.AP int flags in
+OR-ed combination of bits controlling how the search is to be
+performed.  The following flags are supported: \fBTCL_GLOBAL_ONLY\fR
+(indicates that the search is always to be conducted relative to the
+global namespace), \fBTCL_NAMESPACE_ONLY\fR (just for \fBTcl_FindCommand\fR;
+indicates that the search is always to be conducted relative to the
+context namespace), and \fBTCL_LEAVE_ERR_MSG\fR (indicates that an error
+message should be left in the interpreter if the search fails.)
+.AP Tcl_Obj *handlerPtr in
+A script fragment to be installed as the unknown command handler for the
+namespace, or NULL to reset the handler to its default.
+.BE
+.SH DESCRIPTION
+.PP
+Namespaces are hierarchic naming contexts that can contain commands
+and variables.  They also maintain a list of patterns that describes
+what commands are exported, and can import commands that have been
+exported by other namespaces.  Namespaces can also be manipulated
+through the Tcl command \fBnamespace\fR.
+.PP
+The \fITcl_Namespace\fR structure encapsulates a namespace, and is
+guaranteed to have the following fields in it: \fIname\fR (the local
+name of the namespace, with no namespace separator characters in it,
+with empty denoting the global namespace), \fIfullName\fR (the fully
+specified name of the namespace), \fIclientData\fR, \fIdeleteProc\fR
+(the values specified in the call to \fBTcl_CreateNamespace\fR), and
+\fIparentPtr\fR (a pointer to the containing namespace, or NULL for
+the global namespace.)
+.PP
+\fBTcl_CreateNamespace\fR creates a new namespace.  The
+\fIdeleteProc\fR will have the following type signature:
+.PP
+.CS
+typedef void \fBTcl_NamespaceDeleteProc\fR(
+        ClientData \fIclientData\fR);
+.CE
+.PP
+\fBTcl_DeleteNamespace\fR deletes a namespace, calling the
+\fIdeleteProc\fR defined for the namespace (if any).
+.PP
+\fBTcl_AppendExportList\fR retrieves the export patterns for a
+namespace given namespace and appends them (as list items) to
+\fIobjPtr\fR.
+.PP
+\fBTcl_Export\fR sets and appends to the export patterns for a
+namespace.  Patterns are appended unless the \fIresetListFirst\fR flag
+is true.
+.PP
+\fBTcl_Import\fR imports commands matching a pattern into a
+namespace.  Note that the pattern must include the name of the
+namespace to import from.  This function returns an error if
+an attempt to import a command over an existing command is made,
+unless the \fIallowOverwrite\fR flag has been set.
+.PP
+\fBTcl_ForgetImport\fR removes imports matching a pattern.
+.PP
+\fBTcl_GetCurrentNamespace\fR returns the current namespace for an
+interpreter.
+.PP
+\fBTcl_GetGlobalNamespace\fR returns the global namespace for an
+interpreter.
+.PP
+\fBTcl_FindNamespace\fR searches for a namespace named \fIname\fR
+within the context of the namespace \fIcontextNsPtr\fR.  If the
+namespace cannot be found, NULL is returned.
+.PP
+\fBTcl_FindCommand\fR searches for a command named \fIname\fR within
+the context of the namespace \fIcontextNsPtr\fR.  If the command
+cannot be found, NULL is returned.
+.PP
+\fBTcl_GetNamespaceUnknownHandler\fR returns the unknown command handler
+for the namespace, or NULL if none is set.
+.PP
+\fBTcl_SetNamespaceUnknownHandler\fR sets the unknown command handler for
+the namespace. If \fIhandlerPtr\fR is NULL, then the handler is reset to
+its default.
+.SH "SEE ALSO"
+Tcl_CreateCommand(3), Tcl_ListObjAppendList(3), Tcl_SetVar(3)
+.SH KEYWORDS
+namespace, command
diff --git a/doc/Notifier.3 b/doc/Notifier.3
new file mode 100644
index 0000000..16f9f8d
--- /dev/null
+++ b/doc/Notifier.3
@@ -0,0 +1,635 @@
+'\"
+'\" Copyright (c) 1998-1999 Scriptics Corporation
+'\" Copyright (c) 1995-1997 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH Notifier 3 8.1 Tcl "Tcl Library Procedures"
+.so man.macros
+.BS
+.SH NAME
+Tcl_CreateEventSource, Tcl_DeleteEventSource, Tcl_SetMaxBlockTime, Tcl_QueueEvent, Tcl_ThreadQueueEvent, Tcl_ThreadAlert, Tcl_GetCurrentThread, Tcl_DeleteEvents, Tcl_InitNotifier, Tcl_FinalizeNotifier, Tcl_WaitForEvent, Tcl_AlertNotifier, Tcl_SetTimer, Tcl_ServiceAll, Tcl_ServiceEvent, Tcl_GetServiceMode, Tcl_SetServiceMode, Tcl_ServiceModeHook, Tcl_SetNotifier \- the event queue and notifier interfaces
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+void
+\fBTcl_CreateEventSource\fR(\fIsetupProc, checkProc, clientData\fR)
+.sp
+void
+\fBTcl_DeleteEventSource\fR(\fIsetupProc, checkProc, clientData\fR)
+.sp
+void
+\fBTcl_SetMaxBlockTime\fR(\fItimePtr\fR)
+.sp
+void
+\fBTcl_QueueEvent\fR(\fIevPtr, position\fR)
+.sp
+void
+\fBTcl_ThreadQueueEvent\fR(\fIthreadId, evPtr, position\fR)
+.sp
+void
+\fBTcl_ThreadAlert\fR(\fIthreadId\fR)
+.sp
+Tcl_ThreadId
+\fBTcl_GetCurrentThread\fR()
+.sp
+void
+\fBTcl_DeleteEvents\fR(\fIdeleteProc, clientData\fR)
+.sp
+ClientData
+\fBTcl_InitNotifier\fR()
+.sp
+void
+\fBTcl_FinalizeNotifier\fR(\fIclientData\fR)
+.sp
+int
+\fBTcl_WaitForEvent\fR(\fItimePtr\fR)
+.sp
+void
+\fBTcl_AlertNotifier\fR(\fIclientData\fR)
+.sp
+void
+\fBTcl_SetTimer\fR(\fItimePtr\fR)
+.sp
+int
+\fBTcl_ServiceAll\fR()
+.sp
+int
+\fBTcl_ServiceEvent\fR(\fIflags\fR)
+.sp
+int
+\fBTcl_GetServiceMode\fR()
+.sp
+int
+\fBTcl_SetServiceMode\fR(\fImode\fR)
+.sp
+void
+\fBTcl_ServiceModeHook\fR(\fImode\fR)
+.sp
+void
+\fBTcl_SetNotifier\fR(\fInotifierProcPtr\fR)
+.SH ARGUMENTS
+.AS Tcl_EventDeleteProc *notifierProcPtr
+.AP Tcl_EventSetupProc *setupProc in
+Procedure to invoke to prepare for event wait in \fBTcl_DoOneEvent\fR.
+.AP Tcl_EventCheckProc *checkProc in
+Procedure for \fBTcl_DoOneEvent\fR to invoke after waiting for
+events.  Checks to see if any events have occurred and, if so,
+queues them.
+.AP ClientData clientData in
+Arbitrary one-word value to pass to \fIsetupProc\fR, \fIcheckProc\fR, or
+\fIdeleteProc\fR.
+.AP "const Tcl_Time" *timePtr in
+Indicates the maximum amount of time to wait for an event.  This
+is specified as an interval (how long to wait), not an absolute
+time (when to wakeup).  If the pointer passed to \fBTcl_WaitForEvent\fR
+is NULL, it means there is no maximum wait time:  wait forever if
+necessary.
+.AP Tcl_Event *evPtr in
+An event to add to the event queue.  The storage for the event must
+have been allocated by the caller using \fBTcl_Alloc\fR or \fBckalloc\fR.
+.AP Tcl_QueuePosition position in
+Where to add the new event in the queue:  \fBTCL_QUEUE_TAIL\fR,
+\fBTCL_QUEUE_HEAD\fR, or \fBTCL_QUEUE_MARK\fR.
+.AP Tcl_ThreadId threadId in
+A unique identifier for a thread.
+.AP Tcl_EventDeleteProc *deleteProc in
+Procedure to invoke for each queued event in \fBTcl_DeleteEvents\fR.
+.AP int flags in
+What types of events to service.  These flags are the same as those
+passed to \fBTcl_DoOneEvent\fR.
+.AP int mode in
+Indicates whether events should be serviced by \fBTcl_ServiceAll\fR.
+Must be one of \fBTCL_SERVICE_NONE\fR or \fBTCL_SERVICE_ALL\fR.
+.AP Tcl_NotifierProcs* notifierProcPtr in
+Structure of function pointers describing notifier procedures that are
+to replace the ones installed in the executable.  See
+\fBREPLACING THE NOTIFIER\fR for details.
+.BE
+.SH INTRODUCTION
+.PP
+The interfaces described here are used to customize the Tcl event
+loop.  The two most common customizations are to add new sources of
+events and to merge Tcl's event loop with some other event loop, such
+as one provided by an application in which Tcl is embedded.  Each of
+these tasks is described in a separate section below.
+.PP
+The procedures in this manual entry are the building blocks out of which
+the Tcl event notifier is constructed.  The event notifier is the lowest
+layer in the Tcl event mechanism.  It consists of three things:
+.IP [1]
+Event sources: these represent the ways in which events can be
+generated.  For example, there is a timer event source that implements
+the \fBTcl_CreateTimerHandler\fR procedure and the \fBafter\fR
+command, and there is a file event source that implements the
+\fBTcl_CreateFileHandler\fR procedure on Unix systems.  An event
+source must work with the notifier to detect events at the right
+times, record them on the event queue, and eventually notify
+higher-level software that they have occurred.  The procedures
+\fBTcl_CreateEventSource\fR, \fBTcl_DeleteEventSource\fR,
+and \fBTcl_SetMaxBlockTime\fR, \fBTcl_QueueEvent\fR, and
+\fBTcl_DeleteEvents\fR are used primarily by event sources.
+.IP [2]
+The event queue: for non-threaded applications,
+there is a single queue for the whole application,
+containing events that have been detected but not yet serviced.  Event
+sources place events onto the queue so that they may be processed in
+order at appropriate times during the event loop. The event queue
+guarantees a fair discipline of event handling, so that no event
+source can starve the others.  It also allows events to be saved for
+servicing at a future time.  Threaded applications work in a
+similar manner, except that there is a separate event queue for
+each thread containing a Tcl interpreter.
+\fBTcl_QueueEvent\fR is used (primarily
+by event sources) to add events to the event queue and
+\fBTcl_DeleteEvents\fR is used to remove events from the queue without
+processing them.  In a threaded application, \fBTcl_QueueEvent\fR adds
+an event to the current thread's queue, and \fBTcl_ThreadQueueEvent\fR
+adds an event to a queue in a specific thread.
+.IP [3]
+The event loop: in order to detect and process events, the application
+enters a loop that waits for events to occur, places them on the event
+queue, and then processes them.  Most applications will do this by
+calling the procedure \fBTcl_DoOneEvent\fR, which is described in a
+separate manual entry.
+.PP
+Most Tcl applications need not worry about any of the internals of
+the Tcl notifier.  However, the notifier now has enough flexibility
+to be retargeted either for a new platform or to use an external event
+loop (such as the Motif event loop, when Tcl is embedded in a Motif
+application).  The procedures \fBTcl_WaitForEvent\fR and
+\fBTcl_SetTimer\fR are normally implemented by Tcl, but may be
+replaced with new versions to retarget the notifier (the
+\fBTcl_InitNotifier\fR, \fBTcl_AlertNotifier\fR,
+\fBTcl_FinalizeNotifier\fR, \fBTcl_Sleep\fR,
+\fBTcl_CreateFileHandler\fR, and \fBTcl_DeleteFileHandler\fR must
+also be replaced; see CREATING A NEW NOTIFIER below for details).
+The procedures \fBTcl_ServiceAll\fR, \fBTcl_ServiceEvent\fR,
+\fBTcl_GetServiceMode\fR, and \fBTcl_SetServiceMode\fR are provided
+to help connect Tcl's event loop to an external event loop such as
+Motif's.
+.SH "NOTIFIER BASICS"
+.PP
+The easiest way to understand how the notifier works is to consider
+what happens when \fBTcl_DoOneEvent\fR is called.
+\fBTcl_DoOneEvent\fR is passed a \fIflags\fR argument that indicates
+what sort of events it is OK to process and also whether or not to
+block if no events are ready.  \fBTcl_DoOneEvent\fR does the following
+things:
+.IP [1]
+Check the event queue to see if it contains any events that can
+be serviced.  If so, service the first possible event, remove it
+from the queue, and return.  It does this by calling
+\fBTcl_ServiceEvent\fR and passing in the \fIflags\fR argument.
+.IP [2]
+Prepare to block for an event.  To do this, \fBTcl_DoOneEvent\fR
+invokes a \fIsetup procedure\fR in each event source.
+The event source will perform event-source specific initialization and
+possibly call \fBTcl_SetMaxBlockTime\fR to limit how long
+\fBTcl_WaitForEvent\fR will block if no new events occur.
+.IP [3]
+Call \fBTcl_WaitForEvent\fR.  This procedure is implemented differently
+on different platforms;  it waits for an event to occur, based on the
+information provided by the event sources.
+It may cause the application to block if \fItimePtr\fR specifies
+an interval other than 0.
+\fBTcl_WaitForEvent\fR returns when something has happened,
+such as a file becoming readable or the interval given by \fItimePtr\fR
+expiring.  If there are no events for \fBTcl_WaitForEvent\fR to
+wait for, so that it would block forever, then it returns immediately
+and \fBTcl_DoOneEvent\fR returns 0.
+.IP [4]
+Call a \fIcheck procedure\fR in each event source.  The check
+procedure determines whether any events of interest to this source
+occurred.  If so, the events are added to the event queue.
+.IP [5]
+Check the event queue to see if it contains any events that can
+be serviced.  If so, service the first possible event, remove it
+from the queue, and return.
+.IP [6]
+See if there are idle callbacks pending. If so, invoke all of them and
+return.
+.IP [7]
+Either return 0 to indicate that no events were ready, or go back to
+step [2] if blocking was requested by the caller.
+.SH "CREATING A NEW EVENT SOURCE"
+.PP
+An event source consists of three procedures invoked by the notifier,
+plus additional C procedures that are invoked by higher-level code
+to arrange for event-driven callbacks.  The three procedures called
+by the notifier consist of the setup and check procedures described
+above, plus an additional procedure that is invoked when an event
+is removed from the event queue for servicing.
+.PP
+The procedure \fBTcl_CreateEventSource\fR creates a new event source.
+Its arguments specify the setup procedure and check procedure for
+the event source.
+\fISetupProc\fR should match the following prototype:
+.PP
+.CS
+typedef void \fBTcl_EventSetupProc\fR(
+        ClientData \fIclientData\fR,
+        int \fIflags\fR);
+.CE
+.PP
+The \fIclientData\fR argument will be the same as the \fIclientData\fR
+argument to \fBTcl_CreateEventSource\fR;  it is typically used to
+point to private information managed by the event source.
+The \fIflags\fR argument will be the same as the \fIflags\fR
+argument passed to \fBTcl_DoOneEvent\fR except that it will never
+be 0 (\fBTcl_DoOneEvent\fR replaces 0 with \fBTCL_ALL_EVENTS\fR).
+\fIFlags\fR indicates what kinds of events should be considered;
+if the bit corresponding to this event source is not set, the event
+source should return immediately without doing anything.  For
+example, the file event source checks for the \fBTCL_FILE_EVENTS\fR
+bit.
+.PP
+\fISetupProc\fR's job is to make sure that the application wakes up
+when events of the desired type occur.  This is typically done in a
+platform-dependent fashion.  For example, under Unix an event source
+might call \fBTcl_CreateFileHandler\fR; under Windows it might
+request notification with a Windows event.  For timer-driven event
+sources such as timer events or any polled event, the event source
+can call \fBTcl_SetMaxBlockTime\fR to force the application to wake
+up after a specified time even if no events have occurred.
+If no event source calls \fBTcl_SetMaxBlockTime\fR
+then \fBTcl_WaitForEvent\fR will wait as long as necessary for an
+event to occur; otherwise, it will only wait as long as the shortest
+interval passed to \fBTcl_SetMaxBlockTime\fR by one of the event
+sources.  If an event source knows that it already has events ready to
+report, it can request a zero maximum block time.  For example, the
+setup procedure for the X event source looks to see if there are
+events already queued.  If there are, it calls
+\fBTcl_SetMaxBlockTime\fR with a 0 block time so that
+\fBTcl_WaitForEvent\fR does not block if there is no new data on the X
+connection.
+The \fItimePtr\fR argument to \fBTcl_WaitForEvent\fR points to
+a structure that describes a time interval in seconds and
+microseconds:
+.PP
+.CS
+typedef struct Tcl_Time {
+    long \fIsec\fR;
+    long \fIusec\fR;
+} \fBTcl_Time\fR;
+.CE
+.PP
+The \fIusec\fR field should be less than 1000000.
+.PP
+Information provided to \fBTcl_SetMaxBlockTime\fR
+is only used for the next call to \fBTcl_WaitForEvent\fR; it is
+discarded after \fBTcl_WaitForEvent\fR returns.
+The next time an event wait is done each of the event sources'
+setup procedures will be called again, and they can specify new
+information for that event wait.
+.PP
+If the application uses an external event loop rather than
+\fBTcl_DoOneEvent\fR, the event sources may need to call
+\fBTcl_SetMaxBlockTime\fR at other times.  For example, if a new event
+handler is registered that needs to poll for events, the event source
+may call \fBTcl_SetMaxBlockTime\fR to set the block time to zero to
+force the external event loop to call Tcl.  In this case,
+\fBTcl_SetMaxBlockTime\fR invokes \fBTcl_SetTimer\fR with the shortest
+interval seen since the last call to \fBTcl_DoOneEvent\fR or
+\fBTcl_ServiceAll\fR.
+.PP
+In addition to the generic procedure \fBTcl_SetMaxBlockTime\fR, other
+platform-specific procedures may also be available for
+\fIsetupProc\fR, if there is additional information needed by
+\fBTcl_WaitForEvent\fR on that platform.  For example, on Unix systems
+the \fBTcl_CreateFileHandler\fR interface can be used to wait for file events.
+.PP
+The second procedure provided by each event source is its check
+procedure, indicated by the \fIcheckProc\fR argument to
+\fBTcl_CreateEventSource\fR.  \fICheckProc\fR must match the
+following prototype:
+.PP
+.CS
+typedef void \fBTcl_EventCheckProc\fR(
+        ClientData \fIclientData\fR,
+        int \fIflags\fR);
+.CE
+.PP
+The arguments to this procedure are the same as those for \fIsetupProc\fR.
+\fBCheckProc\fR is invoked by \fBTcl_DoOneEvent\fR after it has waited
+for events.  Presumably at least one event source is now prepared to
+queue an event.  \fBTcl_DoOneEvent\fR calls each of the event sources
+in turn, so they all have a chance to queue any events that are ready.
+The check procedure does two things.  First, it must see if any events
+have triggered.  Different event sources do this in different ways.
+.PP
+If an event source's check procedure detects an interesting event, it
+must add the event to Tcl's event queue.  To do this, the event source
+calls \fBTcl_QueueEvent\fR.  The \fIevPtr\fR argument is a pointer to
+a dynamically allocated structure containing the event (see below for
+more information on memory management issues).  Each event source can
+define its own event structure with whatever information is relevant
+to that event source.  However, the first element of the structure
+must be a structure of type \fBTcl_Event\fR, and the address of this
+structure is used when communicating between the event source and the
+rest of the notifier.  A \fBTcl_Event\fR has the following definition:
+.PP
+.CS
+typedef struct {
+    Tcl_EventProc *\fIproc\fR;
+    struct Tcl_Event *\fInextPtr\fR;
+} \fBTcl_Event\fR;
+.CE
+.PP
+The event source must fill in the \fIproc\fR field of
+the event before calling \fBTcl_QueueEvent\fR.
+The \fInextPtr\fR is used to link together the events in the queue
+and should not be modified by the event source.
+.PP
+An event may be added to the queue at any of three positions, depending
+on the \fIposition\fR argument to \fBTcl_QueueEvent\fR:
+.IP \fBTCL_QUEUE_TAIL\fR 24
+Add the event at the back of the queue, so that all other pending
+events will be serviced first.  This is almost always the right
+place for new events.
+.IP \fBTCL_QUEUE_HEAD\fR 24
+Add the event at the front of the queue, so that it will be serviced
+before all other queued events.
+.IP \fBTCL_QUEUE_MARK\fR 24
+Add the event at the front of the queue, unless there are other
+events at the front whose position is \fBTCL_QUEUE_MARK\fR;  if so,
+add the new event just after all other \fBTCL_QUEUE_MARK\fR events.
+This value of \fIposition\fR is used to insert an ordered sequence of
+events at the front of the queue, such as a series of
+Enter and Leave events synthesized during a grab or ungrab operation
+in Tk.
+.PP
+When it is time to handle an event from the queue (steps 1 and 4
+above) \fBTcl_ServiceEvent\fR will invoke the \fIproc\fR specified
+in the first queued \fBTcl_Event\fR structure.
+\fIProc\fR must match the following prototype:
+.PP
+.CS
+typedef int \fBTcl_EventProc\fR(
+        Tcl_Event *\fIevPtr\fR,
+        int \fIflags\fR);
+.CE
+.PP
+The first argument to \fIproc\fR is a pointer to the event, which will
+be the same as the first argument to the \fBTcl_QueueEvent\fR call that
+added the event to the queue.
+The second argument to \fIproc\fR is the \fIflags\fR argument for the
+current call to \fBTcl_ServiceEvent\fR;  this is used by the event source
+to return immediately if its events are not relevant.
+.PP
+It is up to \fIproc\fR to handle the event, typically by invoking
+one or more Tcl commands or C-level callbacks.
+Once the event source has finished handling the event it returns 1
+to indicate that the event can be removed from the queue.
+If for some reason the event source decides that the event cannot
+be handled at this time, it may return 0 to indicate that the event
+should be deferred for processing later;  in this case \fBTcl_ServiceEvent\fR
+will go on to the next event in the queue and attempt to service it.
+There are several reasons why an event source might defer an event.
+One possibility is that events of this type are excluded by the
+\fIflags\fR argument.
+For example, the file event source will always return 0 if the
+\fBTCL_FILE_EVENTS\fR bit is not set in \fIflags\fR.
+Another example of deferring events happens in Tk if
+\fBTk_RestrictEvents\fR has been invoked to defer certain kinds
+of window events.
+.PP
+When \fIproc\fR returns 1, \fBTcl_ServiceEvent\fR will remove the
+event from the event queue and free its storage.
+Note that the storage for an event must be allocated by
+the event source (using \fBTcl_Alloc\fR or the Tcl macro \fBckalloc\fR)
+before calling \fBTcl_QueueEvent\fR, but it
+will be freed by \fBTcl_ServiceEvent\fR, not by the event source.
+.PP
+Threaded applications work in a
+similar manner, except that there is a separate event queue for
+each thread containing a Tcl interpreter.
+Calling \fBTcl_QueueEvent\fR in a multithreaded application adds
+an event to the current thread's queue.
+To add an event to another thread's queue, use \fBTcl_ThreadQueueEvent\fR.
+\fBTcl_ThreadQueueEvent\fR accepts as an argument a Tcl_ThreadId argument,
+which uniquely identifies a thread in a Tcl application.  To obtain the
+Tcl_ThreadId for the current thread, use the \fBTcl_GetCurrentThread\fR
+procedure.  (A thread would then need to pass this identifier to other
+threads for those threads to be able to add events to its queue.)
+After adding an event to another thread's queue, you then typically
+need to call \fBTcl_ThreadAlert\fR to
+.QW "wake up"
+that thread's notifier to alert it to the new event.
+.PP
+\fBTcl_DeleteEvents\fR can be used to explicitly remove one or more
+events from the event queue.  \fBTcl_DeleteEvents\fR calls \fIproc\fR
+for each event in the queue, deleting those for with the procedure
+returns 1.  Events for which the procedure returns 0 are left in the
+queue.  \fIProc\fR should match the following prototype:
+.PP
+.CS
+typedef int \fBTcl_EventDeleteProc\fR(
+        Tcl_Event *\fIevPtr\fR,
+        ClientData \fIclientData\fR);
+.CE
+.PP
+The \fIclientData\fR argument will be the same as the \fIclientData\fR
+argument to \fBTcl_DeleteEvents\fR; it is typically used to point to
+private information managed by the event source.  The \fIevPtr\fR will
+point to the next event in the queue.
+.PP
+\fBTcl_DeleteEventSource\fR deletes an event source.  The \fIsetupProc\fR,
+\fIcheckProc\fR, and \fIclientData\fR arguments must exactly match those
+provided to the \fBTcl_CreateEventSource\fR for the event source to be deleted.
+If no such source exists, \fBTcl_DeleteEventSource\fR has no effect.
+.SH "CREATING A NEW NOTIFIER"
+.PP
+The notifier consists of all the procedures described in this manual
+entry, plus \fBTcl_DoOneEvent\fR and \fBTcl_Sleep\fR, which are
+available on all platforms, and \fBTcl_CreateFileHandler\fR and
+\fBTcl_DeleteFileHandler\fR, which are Unix-specific.  Most of these
+procedures are generic, in that they are the same for all notifiers.
+However, none of the procedures are notifier-dependent:
+\fBTcl_InitNotifier\fR, \fBTcl_AlertNotifier\fR,
+\fBTcl_FinalizeNotifier\fR, \fBTcl_SetTimer\fR, \fBTcl_Sleep\fR,
+\fBTcl_WaitForEvent\fR, \fBTcl_CreateFileHandler\fR,
+\fBTcl_DeleteFileHandler\fR and \fBTcl_ServiceModeHook\fR.  To support a
+new platform or to integrate Tcl with an application-specific event loop,
+you must write new versions of these procedures.
+.PP
+\fBTcl_InitNotifier\fR initializes the notifier state and returns
+a handle to the notifier state.  Tcl calls this
+procedure when initializing a Tcl interpreter.  Similarly,
+\fBTcl_FinalizeNotifier\fR shuts down the notifier, and is
+called by \fBTcl_Finalize\fR when shutting down a Tcl interpreter.
+.PP
+\fBTcl_WaitForEvent\fR is the lowest-level procedure in the notifier;
+it is responsible for waiting for an
+.QW interesting
+event to occur or
+for a given time to elapse.  Before \fBTcl_WaitForEvent\fR is invoked,
+each of the event sources' setup procedure will have been invoked.
+The \fItimePtr\fR argument to
+\fBTcl_WaitForEvent\fR gives the maximum time to block for an event,
+based on calls to \fBTcl_SetMaxBlockTime\fR made by setup procedures
+and on other information (such as the \fBTCL_DONT_WAIT\fR bit in
+\fIflags\fR).
+.PP
+Ideally, \fBTcl_WaitForEvent\fR should only wait for an event
+to occur; it should not actually process the event in any way.
+Later on, the
+event sources will process the raw events and create Tcl_Events on
+the event queue in their \fIcheckProc\fR procedures.
+However, on some platforms (such as Windows) this is not possible;
+events may be processed in \fBTcl_WaitForEvent\fR, including queuing
+Tcl_Events and more (for example, callbacks for native widgets may be
+invoked).  The return value from \fBTcl_WaitForEvent\fR must be either
+0, 1, or \-1.  On platforms such as Windows where events get processed in
+\fBTcl_WaitForEvent\fR, a return value of 1 means that there may be more
+events still pending that have not been processed.  This is a sign to the
+caller that it must call \fBTcl_WaitForEvent\fR again if it wants all
+pending events to be processed. A 0 return value means that calling
+\fBTcl_WaitForEvent\fR again will not have any effect: either this is a
+platform where \fBTcl_WaitForEvent\fR only waits without doing any event
+processing, or \fBTcl_WaitForEvent\fR knows for sure that there are no
+additional events to process (e.g. it returned because the time
+elapsed).  Finally, a return value of \-1 means that the event loop is
+no longer operational and the application should probably unwind and
+terminate.  Under Windows this happens when a WM_QUIT message is received;
+under Unix it happens when \fBTcl_WaitForEvent\fR would have waited
+forever because there were no active event sources and the timeout was
+infinite.
+.PP
+\fBTcl_AlertNotifier\fR is used in multithreaded applications to allow
+any thread to
+.QW "wake up"
+the notifier to alert it to new events on its
+queue.  \fBTcl_AlertNotifier\fR requires as an argument the notifier
+handle returned by \fBTcl_InitNotifier\fR.
+.PP
+If the notifier will be used with an external event loop, then it must
+also support the \fBTcl_SetTimer\fR interface.  \fBTcl_SetTimer\fR is
+invoked by \fBTcl_SetMaxBlockTime\fR whenever the maximum blocking
+time has been reduced.  \fBTcl_SetTimer\fR should arrange for the
+external event loop to invoke \fBTcl_ServiceAll\fR after the specified
+interval even if no events have occurred.  This interface is needed
+because \fBTcl_WaitForEvent\fR is not invoked when there is an external
+event loop.  If the
+notifier will only be used from \fBTcl_DoOneEvent\fR, then
+\fBTcl_SetTimer\fR need not do anything.
+.PP
+\fBTcl_ServiceModeHook\fR is called by the platform-independent portion
+of the notifier when client code makes a call to
+\fBTcl_SetServiceMode\fR. This hook is provided to support operating
+systems that require special event handling when the application is in
+a modal loop (the Windows notifier, for instance, uses this hook to
+create a communication window).
+.PP
+On Unix systems, the file event source also needs support from the
+notifier.  The file event source consists of the
+\fBTcl_CreateFileHandler\fR and \fBTcl_DeleteFileHandler\fR
+procedures, which are described in the \fBTcl_CreateFileHandler\fR
+manual page.
+.PP
+The \fBTcl_Sleep\fR and \fBTcl_DoOneEvent\fR interfaces are described
+in their respective manual pages.
+.PP
+The easiest way to create a new notifier is to look at the code
+for an existing notifier, such as the files \fBunix/tclUnixNotfy.c\fR
+or \fBwin/tclWinNotify.c\fR in the Tcl source distribution.
+.SH "REPLACING THE NOTIFIER"
+.PP
+A notifier that has been written according to the conventions above
+can also be installed in a running process in place of the standard
+notifier.  This mechanism is used so that a single executable can be
+used (with the standard notifier) as a stand-alone program and reused
+(with a replacement notifier in a loadable extension) as an extension
+to another program, such as a Web browser plugin.
+.PP
+To do this, the extension makes a call to \fBTcl_SetNotifier\fR
+passing a pointer to a \fBTcl_NotifierProcs\fR data structure.  The
+structure has the following layout:
+.PP
+.CS
+typedef struct Tcl_NotifierProcs {
+    Tcl_SetTimerProc *\fIsetTimerProc\fR;
+    Tcl_WaitForEventProc *\fIwaitForEventProc\fR;
+    Tcl_CreateFileHandlerProc *\fIcreateFileHandlerProc\fR;
+    Tcl_DeleteFileHandlerProc *\fIdeleteFileHandlerProc\fR;
+    Tcl_InitNotifierProc *\fIinitNotifierProc\fR;
+    Tcl_FinalizeNotifierProc *\fIfinalizeNotifierProc\fR;
+    Tcl_AlertNotifierProc *\fIalertNotifierProc\fR;
+    Tcl_ServiceModeHookProc *\fIserviceModeHookProc\fR;
+} \fBTcl_NotifierProcs\fR;
+.CE
+.PP
+Following the call to \fBTcl_SetNotifier\fR, the pointers given in
+the \fBTcl_NotifierProcs\fR structure replace whatever notifier had
+been installed in the process.
+.PP
+It is extraordinarily unwise to replace a running notifier. Normally,
+\fBTcl_SetNotifier\fR should be called at process initialization time
+before the first call to \fBTcl_InitNotifier\fR.
+.SH "EXTERNAL EVENT LOOPS"
+.PP
+The notifier interfaces are designed so that Tcl can be embedded into
+applications that have their own private event loops.  In this case,
+the application does not call \fBTcl_DoOneEvent\fR except in the case
+of recursive event loops such as calls to the Tcl commands \fBupdate\fR
+or \fBvwait\fR.  Most of the time is spent in the external event loop
+of the application.  In this case the notifier must arrange for the
+external event loop to call back into Tcl when something
+happens on the various Tcl event sources.  These callbacks should
+arrange for appropriate Tcl events to be placed on the Tcl event queue.
+.PP
+Because the external event loop is not calling \fBTcl_DoOneEvent\fR on
+a regular basis, it is up to the notifier to arrange for
+\fBTcl_ServiceEvent\fR to be called whenever events are pending on the
+Tcl event queue.  The easiest way to do this is to invoke
+\fBTcl_ServiceAll\fR at the end of each callback from the external
+event loop.  This will ensure that all of the event sources are
+polled, any queued events are serviced, and any pending idle handlers
+are processed before returning control to the application.  In
+addition, event sources that need to poll for events can call
+\fBTcl_SetMaxBlockTime\fR to force the external event loop to call
+Tcl even if no events are available on the system event queue.
+.PP
+As a side effect of processing events detected in the main external
+event loop, Tcl may invoke \fBTcl_DoOneEvent\fR to start a recursive event
+loop in commands like \fBvwait\fR.  \fBTcl_DoOneEvent\fR will invoke
+the external event loop, which will result in callbacks as described
+in the preceding paragraph, which will result in calls to
+\fBTcl_ServiceAll\fR.  However, in these cases it is undesirable to
+service events in \fBTcl_ServiceAll\fR.  Servicing events there is
+unnecessary because control will immediately return to the
+external event loop and hence to \fBTcl_DoOneEvent\fR, which can
+service the events itself.  Furthermore, \fBTcl_DoOneEvent\fR is
+supposed to service only a single event, whereas \fBTcl_ServiceAll\fR
+normally services all pending events.  To handle this situation,
+\fBTcl_DoOneEvent\fR sets a flag for \fBTcl_ServiceAll\fR
+that causes it to return without servicing any events.
+This flag is called the \fIservice mode\fR;
+\fBTcl_DoOneEvent\fR restores it to its previous value before it returns.
+.PP
+In some cases, however, it may be necessary for \fBTcl_ServiceAll\fR
+to service events
+even when it has been invoked from \fBTcl_DoOneEvent\fR.  This happens
+when there is yet another recursive event loop invoked via an
+event handler called by \fBTcl_DoOneEvent\fR (such as one that is
+part of a native widget).  In this case, \fBTcl_DoOneEvent\fR may not
+have a chance to service events so \fBTcl_ServiceAll\fR must service
+them all.  Any recursive event loop that calls an external event
+loop rather than \fBTcl_DoOneEvent\fR must reset the service mode so
+that all events get processed in \fBTcl_ServiceAll\fR.  This is done
+by invoking the \fBTcl_SetServiceMode\fR procedure.  If
+\fBTcl_SetServiceMode\fR is passed \fBTCL_SERVICE_NONE\fR, then calls
+to \fBTcl_ServiceAll\fR will return immediately without processing any
+events.  If \fBTcl_SetServiceMode\fR is passed \fBTCL_SERVICE_ALL\fR,
+then calls to \fBTcl_ServiceAll\fR will behave normally.
+\fBTcl_SetServiceMode\fR returns the previous value of the service
+mode, which should be restored when the recursive loop exits.
+\fBTcl_GetServiceMode\fR returns the current value of the service
+mode.
+.SH "SEE ALSO"
+Tcl_CreateFileHandler(3), Tcl_DeleteFileHandler(3), Tcl_Sleep(3),
+Tcl_DoOneEvent(3), Thread(3)
+.SH KEYWORDS
+event, notifier, event queue, event sources, file events, timer, idle, service mode, threads
diff --git a/doc/OOInitStubs.3 b/doc/OOInitStubs.3
new file mode 100644
index 0000000..bc42453
--- /dev/null
+++ b/doc/OOInitStubs.3
@@ -0,0 +1,54 @@
+'\"
+'\" Copyright (c) 2012 Donal K. Fellows
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH Tcl_OOInitStubs 3 1.0 TclOO "TclOO Library Functions"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+Tcl_OOInitStubs \- initialize library access to TclOO functionality
+.SH SYNOPSIS
+.nf
+\fB#include <tclOO.h>\fR
+.sp
+const char *
+\fBTcl_OOInitStubs\fR(\fIinterp\fR)
+.fi
+.SH ARGUMENTS
+.AS Tcl_Interp *interp in
+.AP Tcl_Interp *interp in
+The Tcl interpreter that the TclOO API is integrated with and whose C
+interface is going to be used.
+.BE
+.SH DESCRIPTION
+.PP
+When an extension library is going to use the C interface exposed by TclOO, it
+should use \fBTcl_OOInitStubs\fR to initialize its access to that interface
+from within its \fI*\fB_Init\fR (or \fI*\fB_SafeInit\fR) function, passing in
+the \fIinterp\fR that was passed into that routine as context. If the result
+of calling \fBTcl_OOInitStubs\fR is NULL, the initialization failed and an
+error message will have been left in the interpreter's result. Otherwise, the
+initialization succeeded and the TclOO API may thereafter be used; the
+version of the TclOO API is returned.
+.PP
+When using this function, either the C #define symbol \fBUSE_TCLOO_STUBS\fR
+should be defined and your library code linked against the Tcl stub library,
+or that #define symbol should \fInot\fR be defined and your library code
+linked against the Tcl main library directly.
+.SH "BACKWARD COMPATIBILITY NOTE"
+.PP
+If you are linking against the Tcl 8.5 forward compatibility package for
+TclOO, \fIonly\fR the stub-enabled configuration is supported and you should
+also link against the TclOO independent stub library; that library is an
+integrated part of the main Tcl stub library in Tcl 8.6.
+.SH KEYWORDS
+stubs
+.SH "SEE ALSO"
+Tcl_InitStubs(3)
+.\" Local variables:
+.\" mode: nroff
+.\" fill-column: 78
+.\" End:
diff --git a/doc/Object.3 b/doc/Object.3
new file mode 100644
index 0000000..bf80fe2
--- /dev/null
+++ b/doc/Object.3
@@ -0,0 +1,352 @@
+'\"
+'\" Copyright (c) 1996-1997 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH Tcl_Obj 3 8.5 Tcl "Tcl Library Procedures"
+.so man.macros
+.BS
+.SH NAME
+Tcl_NewObj, Tcl_DuplicateObj, Tcl_IncrRefCount, Tcl_DecrRefCount, Tcl_IsShared, Tcl_InvalidateStringRep \- manipulate Tcl values
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+Tcl_Obj *
+\fBTcl_NewObj\fR()
+.sp
+Tcl_Obj *
+\fBTcl_DuplicateObj\fR(\fIobjPtr\fR)
+.sp
+\fBTcl_IncrRefCount\fR(\fIobjPtr\fR)
+.sp
+\fBTcl_DecrRefCount\fR(\fIobjPtr\fR)
+.sp
+int
+\fBTcl_IsShared\fR(\fIobjPtr\fR)
+.sp
+\fBTcl_InvalidateStringRep\fR(\fIobjPtr\fR)
+.SH ARGUMENTS
+.AS Tcl_Obj *objPtr
+.AP Tcl_Obj *objPtr in
+Points to a value;
+must have been the result of a previous call to \fBTcl_NewObj\fR.
+.BE
+.SH INTRODUCTION
+.PP
+This man page presents an overview of Tcl values (called \fBTcl_Obj\fRs for
+historical reasons) and how they are used.
+It also describes generic procedures for managing Tcl values.
+These procedures are used to create and copy values,
+and increment and decrement the count of references (pointers) to values.
+The procedures are used in conjunction with ones
+that operate on specific types of values such as
+\fBTcl_GetIntFromObj\fR and \fBTcl_ListObjAppendElement\fR.
+The individual procedures are described along with the data structures
+they manipulate.
+.PP
+Tcl's \fIdual-ported\fR values provide a general-purpose mechanism
+for storing and exchanging Tcl values.
+They largely replace the use of strings in Tcl.
+For example, they are used to store variable values,
+command arguments, command results, and scripts.
+Tcl values behave like strings but also hold an internal representation
+that can be manipulated more efficiently.
+For example, a Tcl list is now represented as a value
+that holds the list's string representation
+as well as an array of pointers to the values for each list element.
+Dual-ported values avoid most runtime type conversions.
+They also improve the speed of many operations
+since an appropriate representation is immediately available.
+The compiler itself uses Tcl values to
+cache the instruction bytecodes resulting from compiling scripts.
+.PP
+The two representations are a cache of each other and are computed lazily.
+That is, each representation is only computed when necessary,
+it is computed from the other representation,
+and, once computed, it is saved.
+In addition, a change in one representation invalidates the other one.
+As an example, a Tcl program doing integer calculations can
+operate directly on a variable's internal machine integer
+representation without having to constantly convert
+between integers and strings.
+Only when it needs a string representing the variable's value,
+say to print it,
+will the program regenerate the string representation from the integer.
+Although values contain an internal representation,
+their semantics are defined in terms of strings:
+an up-to-date string can always be obtained,
+and any change to the value will be reflected in that string
+when the value's string representation is fetched.
+Because of this representation invalidation and regeneration,
+it is dangerous for extension writers to access
+\fBTcl_Obj\fR fields directly.
+It is better to access Tcl_Obj information using
+procedures like \fBTcl_GetStringFromObj\fR and \fBTcl_GetString\fR.
+.PP
+Values are allocated on the heap
+and are referenced using a pointer to their \fBTcl_Obj\fR structure.
+Values are shared as much as possible.
+This significantly reduces storage requirements
+because some values such as long lists are very large.
+Also, most Tcl values are only read and never modified.
+This is especially true for procedure arguments,
+which can be shared between the caller and the called procedure.
+Assignment and argument binding is done by
+simply assigning a pointer to the value.
+Reference counting is used to determine when it is safe to
+reclaim a value's storage.
+.PP
+Tcl values are typed.
+A value's internal representation is controlled by its type.
+Several types are predefined in the Tcl core
+including integer, double, list, and bytecode.
+Extension writers can extend the set of types
+by defining their own \fBTcl_ObjType\fR structs.
+.SH "THE TCL_OBJ STRUCTURE"
+.PP
+Each Tcl value is represented by a \fBTcl_Obj\fR structure
+which is defined as follows.
+.PP
+.CS
+typedef struct Tcl_Obj {
+    int \fIrefCount\fR;
+    char *\fIbytes\fR;
+    int \fIlength\fR;
+    const Tcl_ObjType *\fItypePtr\fR;
+    union {
+        long \fIlongValue\fR;
+        double \fIdoubleValue\fR;
+        void *\fIotherValuePtr\fR;
+        Tcl_WideInt \fIwideValue\fR;
+        struct {
+            void *\fIptr1\fR;
+            void *\fIptr2\fR;
+        } \fItwoPtrValue\fR;
+        struct {
+            void *\fIptr\fR;
+            unsigned long \fIvalue\fR;
+        } \fIptrAndLongRep\fR;
+    } \fIinternalRep\fR;
+} \fBTcl_Obj\fR;
+.CE
+.PP
+The \fIbytes\fR and the \fIlength\fR members together hold
+a value's UTF-8 string representation,
+which is a \fIcounted string\fR not containing null bytes (UTF-8 null
+characters should be encoded as a two byte sequence: 192, 128.)
+\fIbytes\fR points to the first byte of the string representation.
+The \fIlength\fR member gives the number of bytes.
+The byte array must always have a null byte after the last data byte,
+at offset \fIlength\fR;
+this allows string representations
+to be treated as conventional null-terminated C strings.
+C programs use \fBTcl_GetStringFromObj\fR and \fBTcl_GetString\fR to get
+a value's string representation.
+If \fIbytes\fR is NULL,
+the string representation is invalid.
+.PP
+A value's type manages its internal representation.
+The member \fItypePtr\fR points to the Tcl_ObjType structure
+that describes the type.
+If \fItypePtr\fR is NULL,
+the internal representation is invalid.
+.PP
+The \fIinternalRep\fR union member holds
+a value's internal representation.
+This is either a (long) integer, a double-precision floating-point number,
+a pointer to a value containing additional information
+needed by the value's type to represent the value, a Tcl_WideInt
+integer, two arbitrary pointers, or a pair made up of an unsigned long
+integer and a pointer.
+.PP
+The \fIrefCount\fR member is used to tell when it is safe to free
+a value's storage.
+It holds the count of active references to the value.
+Maintaining the correct reference count is a key responsibility
+of extension writers.
+Reference counting is discussed below
+in the section \fBSTORAGE MANAGEMENT OF VALUES\fR.
+.PP
+Although extension writers can directly access
+the members of a Tcl_Obj structure,
+it is much better to use the appropriate procedures and macros.
+For example, extension writers should never
+read or update \fIrefCount\fR directly;
+they should use macros such as
+\fBTcl_IncrRefCount\fR and \fBTcl_IsShared\fR instead.
+.PP
+A key property of Tcl values is that they hold two representations.
+A value typically starts out containing only a string representation:
+it is untyped and has a NULL \fItypePtr\fR.
+A value containing an empty string or a copy of a specified string
+is created using \fBTcl_NewObj\fR or \fBTcl_NewStringObj\fR respectively.
+A value's string value is gotten with
+\fBTcl_GetStringFromObj\fR or \fBTcl_GetString\fR
+and changed with \fBTcl_SetStringObj\fR.
+If the value is later passed to a procedure like \fBTcl_GetIntFromObj\fR
+that requires a specific internal representation,
+the procedure will create one and set the value's \fItypePtr\fR.
+The internal representation is computed from the string representation.
+A value's two representations are duals of each other:
+changes made to one are reflected in the other.
+For example, \fBTcl_ListObjReplace\fR will modify a value's
+internal representation and the next call to \fBTcl_GetStringFromObj\fR
+or \fBTcl_GetString\fR will reflect that change.
+.PP
+Representations are recomputed lazily for efficiency.
+A change to one representation made by a procedure
+such as \fBTcl_ListObjReplace\fR is not reflected immediately
+in the other representation.
+Instead, the other representation is marked invalid
+so that it is only regenerated if it is needed later.
+Most C programmers never have to be concerned with how this is done
+and simply use procedures such as \fBTcl_GetBooleanFromObj\fR or
+\fBTcl_ListObjIndex\fR.
+Programmers that implement their own value types
+must check for invalid representations
+and mark representations invalid when necessary.
+The procedure \fBTcl_InvalidateStringRep\fR is used
+to mark a value's string representation invalid and to
+free any storage associated with the old string representation.
+.PP
+Values usually remain one type over their life,
+but occasionally a value must be converted from one type to another.
+For example, a C program might build up a string in a value
+with repeated calls to \fBTcl_AppendToObj\fR,
+and then call \fBTcl_ListObjIndex\fR to extract a list element from
+the value.
+The same value holding the same string value
+can have several different internal representations
+at different times.
+Extension writers can also force a value to be converted from one type
+to another using the \fBTcl_ConvertToType\fR procedure.
+Only programmers that create new value types need to be concerned
+about how this is done.
+A procedure defined as part of the value type's implementation
+creates a new internal representation for a value
+and changes its \fItypePtr\fR.
+See the man page for \fBTcl_RegisterObjType\fR
+to see how to create a new value type.
+.SH "EXAMPLE OF THE LIFETIME OF A VALUE"
+.PP
+As an example of the lifetime of a value,
+consider the following sequence of commands:
+.PP
+.CS
+\fBset x 123\fR
+.CE
+.PP
+This assigns to \fIx\fR an untyped value whose
+\fIbytes\fR member points to \fB123\fR and \fIlength\fR member contains 3.
+The value's \fItypePtr\fR member is NULL.
+.PP
+.CS
+\fBputs "x is $x"\fR
+.CE
+.PP
+\fIx\fR's string representation is valid (since \fIbytes\fR is non-NULL)
+and is fetched for the command.
+.PP
+.CS
+\fBincr x\fR
+.CE
+.PP
+The \fBincr\fR command first gets an integer from \fIx\fR's value
+by calling \fBTcl_GetIntFromObj\fR.
+This procedure checks whether the value is already an integer value.
+Since it is not, it converts the value
+by setting the value's \fIinternalRep.longValue\fR member
+to the integer \fB123\fR
+and setting the value's \fItypePtr\fR
+to point to the integer Tcl_ObjType structure.
+Both representations are now valid.
+\fBincr\fR increments the value's integer internal representation
+then invalidates its string representation
+(by calling \fBTcl_InvalidateStringRep\fR)
+since the string representation
+no longer corresponds to the internal representation.
+.PP
+.CS
+\fBputs "x is now $x"\fR
+.CE
+.PP
+The string representation of \fIx\fR's value is needed
+and is recomputed.
+The string representation is now \fB124\fR
+and both representations are again valid.
+.SH "STORAGE MANAGEMENT OF VALUES"
+.PP
+Tcl values are allocated on the heap and are shared as much as possible
+to reduce storage requirements.
+Reference counting is used to determine when a value is
+no longer needed and can safely be freed.
+A value just created by \fBTcl_NewObj\fR or \fBTcl_NewStringObj\fR
+has \fIrefCount\fR 0.
+The macro \fBTcl_IncrRefCount\fR increments the reference count
+when a new reference to the value is created.
+The macro \fBTcl_DecrRefCount\fR decrements the count
+when a reference is no longer needed and,
+if the value's reference count drops to zero, frees its storage.
+A value shared by different code or data structures has
+\fIrefCount\fR greater than 1.
+Incrementing a value's reference count ensures that
+it will not be freed too early or have its value change accidentally.
+.PP
+As an example, the bytecode interpreter shares argument values
+between calling and called Tcl procedures to avoid having to copy values.
+It assigns the call's argument values to the procedure's
+formal parameter variables.
+In doing so, it calls \fBTcl_IncrRefCount\fR to increment
+the reference count of each argument since there is now a new
+reference to it from the formal parameter.
+When the called procedure returns,
+the interpreter calls \fBTcl_DecrRefCount\fR to decrement
+each argument's reference count.
+When a value's reference count drops less than or equal to zero,
+\fBTcl_DecrRefCount\fR reclaims its storage.
+Most command procedures do not have to be concerned about
+reference counting since they use a value's value immediately
+and do not retain a pointer to the value after they return.
+However, if they do retain a pointer to a value in a data structure,
+they must be careful to increment its reference count
+since the retained pointer is a new reference.
+.PP
+Command procedures that directly modify values
+such as those for \fBlappend\fR and \fBlinsert\fR must be careful to
+copy a shared value before changing it.
+They must first check whether the value is shared
+by calling \fBTcl_IsShared\fR.
+If the value is shared they must copy the value
+by using \fBTcl_DuplicateObj\fR;
+this returns a new duplicate of the original value
+that has \fIrefCount\fR 0.
+If the value is not shared,
+the command procedure
+.QW "owns"
+the value and can safely modify it directly.
+For example, the following code appears in the command procedure
+that implements \fBlinsert\fR.
+This procedure modifies the list value passed to it in \fIobjv[1]\fR
+by inserting \fIobjc-3\fR new elements before \fIindex\fR.
+.PP
+.CS
+listPtr = objv[1];
+if (\fBTcl_IsShared\fR(listPtr)) {
+    listPtr = \fBTcl_DuplicateObj\fR(listPtr);
+}
+result = Tcl_ListObjReplace(interp, listPtr, index, 0,
+        (objc-3), &(objv[3]));
+.CE
+.PP
+As another example, \fBincr\fR's command procedure
+must check whether the variable's value is shared before
+incrementing the integer in its internal representation.
+If it is shared, it needs to duplicate the value
+in order to avoid accidentally changing values in other data structures.
+.SH "SEE ALSO"
+Tcl_ConvertToType(3), Tcl_GetIntFromObj(3), Tcl_ListObjAppendElement(3), Tcl_ListObjIndex(3), Tcl_ListObjReplace(3), Tcl_RegisterObjType(3)
+.SH KEYWORDS
+internal representation, value, value creation, value type,
+reference counting, string representation, type conversion
diff --git a/doc/ObjectType.3 b/doc/ObjectType.3
new file mode 100644
index 0000000..bf414ac
--- /dev/null
+++ b/doc/ObjectType.3
@@ -0,0 +1,256 @@
+'\"
+'\" Copyright (c) 1996-1997 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH Tcl_ObjType 3 8.0 Tcl "Tcl Library Procedures"
+.so man.macros
+.BS
+.SH NAME
+Tcl_RegisterObjType, Tcl_GetObjType, Tcl_AppendAllObjTypes, Tcl_ConvertToType  \- manipulate Tcl value types
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+\fBTcl_RegisterObjType\fR(\fItypePtr\fR)
+.sp
+const Tcl_ObjType *
+\fBTcl_GetObjType\fR(\fItypeName\fR)
+.sp
+int
+\fBTcl_AppendAllObjTypes\fR(\fIinterp, objPtr\fR)
+.sp
+int
+\fBTcl_ConvertToType\fR(\fIinterp, objPtr, typePtr\fR)
+.SH ARGUMENTS
+.AS "const char" *typeName
+.AP "const Tcl_ObjType" *typePtr in
+Points to the structure containing information about the Tcl value type.
+This storage must live forever,
+typically by being statically allocated.
+.AP "const char" *typeName in
+The name of a Tcl value type that \fBTcl_GetObjType\fR should look up.
+.AP Tcl_Interp *interp in
+Interpreter to use for error reporting.
+.AP Tcl_Obj *objPtr in
+For \fBTcl_AppendAllObjTypes\fR, this points to the value onto which
+it appends the name of each value type as a list element.
+For \fBTcl_ConvertToType\fR, this points to a value that
+must have been the result of a previous call to \fBTcl_NewObj\fR.
+.BE
+
+.SH DESCRIPTION
+.PP
+The procedures in this man page manage Tcl value types (sometimes
+referred to as object types or \fBTcl_ObjType\fRs for historical reasons).
+They are used to register new value types, look up types,
+and force conversions from one type to another.
+.PP
+\fBTcl_RegisterObjType\fR registers a new Tcl value type
+in the table of all value types that \fBTcl_GetObjType\fR
+can look up by name.  There are other value types supported by Tcl
+as well, which Tcl chooses not to register.  Extensions can likewise
+choose to register the value types they create or not.
+The argument \fItypePtr\fR points to a Tcl_ObjType structure that
+describes the new type by giving its name
+and by supplying pointers to four procedures
+that implement the type.
+If the type table already contains a type
+with the same name as in \fItypePtr\fR,
+it is replaced with the new type.
+The Tcl_ObjType structure is described
+in the section \fBTHE TCL_OBJTYPE STRUCTURE\fR below.
+.PP
+\fBTcl_GetObjType\fR returns a pointer to the registered Tcl_ObjType
+with name \fItypeName\fR.
+It returns NULL if no type with that name is registered.
+.PP
+\fBTcl_AppendAllObjTypes\fR appends the name of each registered value type
+as a list element onto the Tcl value referenced by \fIobjPtr\fR.
+The return value is \fBTCL_OK\fR unless there was an error
+converting \fIobjPtr\fR to a list value;
+in that case \fBTCL_ERROR\fR is returned.
+.PP
+\fBTcl_ConvertToType\fR converts a value from one type to another
+if possible.
+It creates a new internal representation for \fIobjPtr\fR
+appropriate for the target type \fItypePtr\fR
+and sets its \fItypePtr\fR member as determined by calling the
+\fItypePtr->setFromAnyProc\fR routine.
+Any internal representation for \fIobjPtr\fR's old type is freed.
+If an error occurs during conversion, it returns \fBTCL_ERROR\fR
+and leaves an error message in the result value for \fIinterp\fR
+unless \fIinterp\fR is NULL.
+Otherwise, it returns \fBTCL_OK\fR.
+Passing a NULL \fIinterp\fR allows this procedure to be used
+as a test whether the conversion can be done (and in fact was done).
+.VS 8.5
+.PP
+In many cases, the \fItypePtr->setFromAnyProc\fR routine will
+set \fIobjPtr->typePtr\fR to the argument value \fItypePtr\fR,
+but that is no longer guaranteed.  The \fIsetFromAnyProc\fR is
+free to set the internal representation for \fIobjPtr\fR to make
+use of another related Tcl_ObjType, if it sees fit.
+.VE 8.5
+.SH "THE TCL_OBJTYPE STRUCTURE"
+.PP
+Extension writers can define new value types by defining four
+procedures and
+initializing a Tcl_ObjType structure to describe the type.
+Extension writers may also pass a pointer to their Tcl_ObjType
+structure to \fBTcl_RegisterObjType\fR if they wish to permit
+other extensions to look up their Tcl_ObjType by name with
+the \fBTcl_GetObjType\fR routine.
+The \fBTcl_ObjType\fR structure is defined as follows:
+.PP
+.CS
+typedef struct Tcl_ObjType {
+    const char *\fIname\fR;
+    Tcl_FreeInternalRepProc *\fIfreeIntRepProc\fR;
+    Tcl_DupInternalRepProc *\fIdupIntRepProc\fR;
+    Tcl_UpdateStringProc *\fIupdateStringProc\fR;
+    Tcl_SetFromAnyProc *\fIsetFromAnyProc\fR;
+} \fBTcl_ObjType\fR;
+.CE
+.SS "THE NAME FIELD"
+.PP
+The \fIname\fR member describes the name of the type, e.g. \fBint\fR.
+When a type is registered, this is the name used by callers
+of \fBTcl_GetObjType\fR to lookup the type.  For unregistered
+types, the \fIname\fR field is primarily of value for debugging.
+The remaining four members are pointers to procedures
+called by the generic Tcl value code:
+.SS "THE SETFROMANYPROC FIELD"
+.PP
+The \fIsetFromAnyProc\fR member contains the address of a function
+called to create a valid internal representation
+from a value's string representation.
+.PP
+.CS
+typedef int \fBTcl_SetFromAnyProc\fR(
+        Tcl_Interp *\fIinterp\fR,
+        Tcl_Obj *\fIobjPtr\fR);
+.CE
+.PP
+If an internal representation cannot be created from the string,
+it returns \fBTCL_ERROR\fR and puts a message
+describing the error in the result value for \fIinterp\fR
+unless \fIinterp\fR is NULL.
+If \fIsetFromAnyProc\fR is successful,
+it stores the new internal representation,
+sets \fIobjPtr\fR's \fItypePtr\fR member to point to
+the \fBTcl_ObjType\fR struct corresponding to the new
+internal representation, and returns \fBTCL_OK\fR.
+Before setting the new internal representation,
+the \fIsetFromAnyProc\fR must free any internal representation
+of \fIobjPtr\fR's old type;
+it does this by calling the old type's \fIfreeIntRepProc\fR
+if it is not NULL.
+.PP
+As an example, the \fIsetFromAnyProc\fR for the built-in Tcl list type
+gets an up-to-date string representation for \fIobjPtr\fR
+by calling \fBTcl_GetStringFromObj\fR.
+It parses the string to verify it is in a valid list format and
+to obtain each element value in the list, and, if this succeeds,
+stores the list elements in \fIobjPtr\fR's internal representation
+and sets \fIobjPtr\fR's \fItypePtr\fR member to point to the list type's
+Tcl_ObjType structure.
+.PP
+Do not release \fIobjPtr\fR's old internal representation unless you
+replace it with a new one or reset the \fItypePtr\fR member to NULL.
+.PP
+The \fIsetFromAnyProc\fR member may be set to NULL, if the routines
+making use of the internal representation have no need to derive that
+internal representation from an arbitrary string value.  However, in
+this case, passing a pointer to the type to \fBTcl_ConvertToType\fR will
+lead to a panic, so to avoid this possibility, the type
+should \fInot\fR be registered.
+.SS "THE UPDATESTRINGPROC FIELD"
+.PP
+The \fIupdateStringProc\fR member contains the address of a function
+called to create a valid string representation
+from a value's internal representation.
+.PP
+.CS
+typedef void \fBTcl_UpdateStringProc\fR(
+        Tcl_Obj *\fIobjPtr\fR);
+.CE
+.PP
+\fIobjPtr\fR's \fIbytes\fR member is always NULL when it is called.
+It must always set \fIbytes\fR non-NULL before returning.
+We require the string representation's byte array
+to have a null after the last byte, at offset \fIlength\fR,
+and to have no null bytes before that; this allows string representations
+to be treated as conventional null character-terminated C strings.
+These restrictions are easily met by using Tcl's internal UTF encoding
+for the string representation, same as one would do for other
+Tcl routines accepting string values as arguments.
+Storage for the byte array must be allocated in the heap by \fBTcl_Alloc\fR
+or \fBckalloc\fR.  Note that \fIupdateStringProc\fRs must allocate
+enough storage for the string's bytes and the terminating null byte.
+.PP
+The \fIupdateStringProc\fR for Tcl's built-in double type, for example,
+calls Tcl_PrintDouble to write to a buffer of size TCL_DOUBLE_SPACE,
+then allocates and copies the string representation to just enough
+space to hold it.  A pointer to the allocated space is stored in
+the \fIbytes\fR member.
+.PP
+The \fIupdateStringProc\fR member may be set to NULL, if the routines
+making use of the internal representation are written so that the
+string representation is never invalidated.  Failure to meet this
+obligation will lead to panics or crashes when \fBTcl_GetStringFromObj\fR
+or other similar routines ask for the string representation.
+.SS "THE DUPINTREPPROC FIELD"
+.PP
+The \fIdupIntRepProc\fR member contains the address of a function
+called to copy an internal representation from one value to another.
+.PP
+.CS
+typedef void \fBTcl_DupInternalRepProc\fR(
+        Tcl_Obj *\fIsrcPtr\fR,
+        Tcl_Obj *\fIdupPtr\fR);
+.CE
+.PP
+\fIdupPtr\fR's internal representation is made a copy of \fIsrcPtr\fR's
+internal representation.
+Before the call,
+\fIsrcPtr\fR's internal representation is valid and \fIdupPtr\fR's is not.
+\fIsrcPtr\fR's value type determines what
+copying its internal representation means.
+.PP
+For example, the \fIdupIntRepProc\fR for the Tcl integer type
+simply copies an integer.
+The built-in list type's \fIdupIntRepProc\fR uses a far more
+sophisticated scheme to continue sharing storage as much as it
+reasonably can.
+.SS "THE FREEINTREPPROC FIELD"
+.PP
+The \fIfreeIntRepProc\fR member contains the address of a function
+that is called when a value is freed.
+.PP
+.CS
+typedef void \fBTcl_FreeInternalRepProc\fR(
+        Tcl_Obj *\fIobjPtr\fR);
+.CE
+.PP
+The \fIfreeIntRepProc\fR function can deallocate the storage
+for the value's internal representation
+and do other type-specific processing necessary when a value is freed.
+.PP
+For example, the list type's \fIfreeIntRepProc\fR respects
+the storage sharing scheme established by the \fIdupIntRepProc\fR
+so that it only frees storage when the last value sharing it
+is being freed.
+.PP
+The \fIfreeIntRepProc\fR member can be set to NULL
+to indicate that the internal representation does not require freeing.
+The \fIfreeIntRepProc\fR implementation must not access the
+\fIbytes\fR member of the value, since Tcl makes its own internal
+uses of that field during value deletion.  The defined tasks for
+the \fIfreeIntRepProc\fR have no need to consult the \fIbytes\fR
+member.
+.SH "SEE ALSO"
+Tcl_NewObj(3), Tcl_DecrRefCount(3), Tcl_IncrRefCount(3)
+.SH KEYWORDS
+internal representation, value, value type, string representation, type conversion
diff --git a/doc/OpenFileChnl.3 b/doc/OpenFileChnl.3
new file mode 100644
index 0000000..582ff4b
--- /dev/null
+++ b/doc/OpenFileChnl.3
@@ -0,0 +1,648 @@
+'\"
+'\" Copyright (c) 1996-1997 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH Tcl_OpenFileChannel 3 8.3 Tcl "Tcl Library Procedures"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+Tcl_OpenFileChannel, Tcl_OpenCommandChannel, Tcl_MakeFileChannel, Tcl_GetChannel, Tcl_GetChannelNames, Tcl_GetChannelNamesEx, Tcl_RegisterChannel, Tcl_UnregisterChannel, Tcl_DetachChannel, Tcl_IsStandardChannel, Tcl_Close, Tcl_ReadChars, Tcl_Read, Tcl_GetsObj, Tcl_Gets, Tcl_WriteObj, Tcl_WriteChars, Tcl_Write, Tcl_Flush, Tcl_Seek, Tcl_Tell, Tcl_TruncateChannel, Tcl_GetChannelOption, Tcl_SetChannelOption, Tcl_Eof, Tcl_InputBlocked, Tcl_InputBuffered, Tcl_OutputBuffered, Tcl_Ungets, Tcl_ReadRaw, Tcl_WriteRaw \- buffered I/O facilities using channels
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+Tcl_Channel
+\fBTcl_OpenFileChannel\fR(\fIinterp, fileName, mode, permissions\fR)
+.sp
+Tcl_Channel
+\fBTcl_OpenCommandChannel\fR(\fIinterp, argc, argv, flags\fR)
+.sp
+Tcl_Channel
+\fBTcl_MakeFileChannel\fR(\fIhandle, readOrWrite\fR)
+.sp
+Tcl_Channel
+\fBTcl_GetChannel\fR(\fIinterp, channelName, modePtr\fR)
+.sp
+int
+\fBTcl_GetChannelNames\fR(\fIinterp\fR)
+.sp
+int
+\fBTcl_GetChannelNamesEx\fR(\fIinterp, pattern\fR)
+.sp
+void
+\fBTcl_RegisterChannel\fR(\fIinterp, channel\fR)
+.sp
+int
+\fBTcl_UnregisterChannel\fR(\fIinterp, channel\fR)
+.sp
+int
+\fBTcl_DetachChannel\fR(\fIinterp, channel\fR)
+.sp
+int
+\fBTcl_IsStandardChannel\fR(\fIchannel\fR)
+.sp
+int
+\fBTcl_Close\fR(\fIinterp, channel\fR)
+.sp
+int
+\fBTcl_ReadChars\fR(\fIchannel, readObjPtr, charsToRead, appendFlag\fR)
+.sp
+int
+\fBTcl_Read\fR(\fIchannel, readBuf, bytesToRead\fR)
+.sp
+int
+\fBTcl_GetsObj\fR(\fIchannel, lineObjPtr\fR)
+.sp
+int
+\fBTcl_Gets\fR(\fIchannel, lineRead\fR)
+.sp
+int
+\fBTcl_Ungets\fR(\fIchannel, input, inputLen, addAtEnd\fR)
+.sp
+int
+\fBTcl_WriteObj\fR(\fIchannel, writeObjPtr\fR)
+.sp
+int
+\fBTcl_WriteChars\fR(\fIchannel, charBuf, bytesToWrite\fR)
+.sp
+int
+\fBTcl_Write\fR(\fIchannel, byteBuf, bytesToWrite\fR)
+.sp
+int
+\fBTcl_ReadRaw\fR(\fIchannel, readBuf, bytesToRead\fR)
+.sp
+int
+\fBTcl_WriteRaw\fR(\fIchannel, byteBuf, bytesToWrite\fR)
+.sp
+int
+\fBTcl_Eof\fR(\fIchannel\fR)
+.sp
+int
+\fBTcl_Flush\fR(\fIchannel\fR)
+.sp
+int
+\fBTcl_InputBlocked\fR(\fIchannel\fR)
+.sp
+int
+\fBTcl_InputBuffered\fR(\fIchannel\fR)
+.sp
+int
+\fBTcl_OutputBuffered\fR(\fIchannel\fR)
+.sp
+Tcl_WideInt
+\fBTcl_Seek\fR(\fIchannel, offset, seekMode\fR)
+.sp
+Tcl_WideInt
+\fBTcl_Tell\fR(\fIchannel\fR)
+.sp
+int
+\fBTcl_TruncateChannel\fR(\fIchannel, length\fR)
+.sp
+int
+\fBTcl_GetChannelOption\fR(\fIinterp, channel, optionName, optionValue\fR)
+.sp
+int
+\fBTcl_SetChannelOption\fR(\fIinterp, channel, optionName, newValue\fR)
+.sp
+.SH ARGUMENTS
+.AS Tcl_DString *channelName in/out
+.AP Tcl_Interp *interp in
+Used for error reporting and to look up a channel registered in it.
+.AP "const char" *fileName in
+The name of a local or network file.
+.AP "const char" *mode in
+Specifies how the file is to be accessed.  May have any of the values
+allowed for the \fImode\fR argument to the Tcl \fBopen\fR command.
+.AP int permissions in
+POSIX-style permission flags such as 0644.  If a new file is created, these
+permissions will be set on the created file.
+.AP int argc in
+The number of elements in \fIargv\fR.
+.AP "const char" **argv in
+Arguments for constructing a command pipeline.  These values have the same
+meaning as the non-switch arguments to the Tcl \fBexec\fR command.
+.AP int flags in
+Specifies the disposition of the stdio handles in pipeline: OR-ed
+combination of \fBTCL_STDIN\fR, \fBTCL_STDOUT\fR, \fBTCL_STDERR\fR, and
+\fBTCL_ENFORCE_MODE\fR. If \fBTCL_STDIN\fR is set, stdin for the first child
+in the pipe is the pipe channel, otherwise it is the same as the standard
+input of the invoking process; likewise for \fBTCL_STDOUT\fR and
+\fBTCL_STDERR\fR. If \fBTCL_ENFORCE_MODE\fR is not set, then the pipe can
+redirect stdio handles to override the stdio handles for which
+\fBTCL_STDIN\fR, \fBTCL_STDOUT\fR and \fBTCL_STDERR\fR have been set.  If it
+is set, then such redirections cause an error.
+.AP ClientData handle in
+Operating system specific handle for I/O to a file. For Unix this is a
+file descriptor, for Windows it is a HANDLE.
+.AP int readOrWrite in
+OR-ed combination of \fBTCL_READABLE\fR and \fBTCL_WRITABLE\fR to indicate
+what operations are valid on \fIhandle\fR.
+.AP "const char" *channelName in
+The name of the channel.
+.AP int *modePtr out
+Points at an integer variable that will receive an OR-ed combination of
+\fBTCL_READABLE\fR and \fBTCL_WRITABLE\fR denoting whether the channel is
+open for reading and writing.
+.AP "const char" *pattern in
+The pattern to match on, passed to Tcl_StringMatch, or NULL.
+.AP Tcl_Channel channel in
+A Tcl channel for input or output.  Must have been the return value
+from a procedure such as \fBTcl_OpenFileChannel\fR.
+.AP Tcl_Obj *readObjPtr in/out
+A pointer to a Tcl value in which to store the characters read from the
+channel.
+.AP int charsToRead in
+The number of characters to read from the channel.  If the channel's encoding
+is \fBbinary\fR, this is equivalent to the number of bytes to read from the
+channel.
+.AP int appendFlag in
+If non-zero, data read from the channel will be appended to the value.
+Otherwise, the data will replace the existing contents of the value.
+.AP char *readBuf out
+A buffer in which to store the bytes read from the channel.
+.AP int bytesToRead in
+The number of bytes to read from the channel.  The buffer \fIreadBuf\fR must
+be large enough to hold this many bytes.
+.AP Tcl_Obj *lineObjPtr in/out
+A pointer to a Tcl value in which to store the line read from the
+channel.  The line read will be appended to the current value of the
+value.
+.AP Tcl_DString *lineRead in/out
+A pointer to a Tcl dynamic string in which to store the line read from the
+channel.  Must have been initialized by the caller.  The line read will be
+appended to any data already in the dynamic string.
+.AP "const char" *input in
+The input to add to a channel buffer.
+.AP int inputLen in
+Length of the input
+.AP int addAtEnd in
+Flag indicating whether the input should be added to the end or
+beginning of the channel buffer.
+.AP Tcl_Obj *writeObjPtr in
+A pointer to a Tcl value whose contents will be output to the channel.
+.AP "const char" *charBuf in
+A buffer containing the characters to output to the channel.
+.AP "const char" *byteBuf in
+A buffer containing the bytes to output to the channel.
+.AP int bytesToWrite in
+The number of bytes to consume from \fIcharBuf\fR or \fIbyteBuf\fR and
+output to the channel.
+.AP Tcl_WideInt offset in
+How far to move the access point in the channel at which the next input or
+output operation will be applied, measured in bytes from the position
+given by \fIseekMode\fR.  May be either positive or negative.
+.AP int seekMode in
+Relative to which point to seek; used with \fIoffset\fR to calculate the new
+access point for the channel. Legal values are \fBSEEK_SET\fR,
+\fBSEEK_CUR\fR, and \fBSEEK_END\fR.
+.AP Tcl_WideInt length in
+The (non-negative) length to truncate the channel the channel to.
+.AP "const char" *optionName in
+The name of an option applicable to this channel, such as \fB\-blocking\fR.
+May have any of the values accepted by the \fBfconfigure\fR command.
+.AP Tcl_DString *optionValue in
+Where to store the value of an option or a list of all options and their
+values. Must have been initialized by the caller.
+.AP "const char" *newValue in
+New value for the option given by \fIoptionName\fR.
+.BE
+.SH DESCRIPTION
+.PP
+The Tcl channel mechanism provides a device-independent and
+platform-independent mechanism for performing buffered input
+and output operations on a variety of file, socket, and device
+types.
+The channel mechanism is extensible to new channel types, by
+providing a low-level channel driver for the new type; the channel driver
+interface is described in the manual entry for \fBTcl_CreateChannel\fR. The
+channel mechanism provides a buffering scheme modeled after
+Unix's standard I/O, and it also allows for nonblocking I/O on
+channels.
+.PP
+The procedures described in this manual entry comprise the C APIs of the
+generic layer of the channel architecture. For a description of the channel
+driver architecture and how to implement channel drivers for new types of
+channels, see the manual entry for \fBTcl_CreateChannel\fR.
+.SH TCL_OPENFILECHANNEL
+.PP
+\fBTcl_OpenFileChannel\fR opens a file specified by \fIfileName\fR and
+returns a channel handle that can be used to perform input and output on
+the file. This API is modeled after the \fBfopen\fR procedure of
+the Unix standard I/O library.
+The syntax and meaning of all arguments is similar to those
+given in the Tcl \fBopen\fR command when opening a file.
+If an error occurs while opening the channel, \fBTcl_OpenFileChannel\fR
+returns NULL and records a POSIX error code that can be
+retrieved with \fBTcl_GetErrno\fR.
+In addition, if \fIinterp\fR is non-NULL, \fBTcl_OpenFileChannel\fR
+leaves an error message in \fIinterp\fR's result after any error.
+As of Tcl 8.4, the value-based API \fBTcl_FSOpenFileChannel\fR should
+be used in preference to \fBTcl_OpenFileChannel\fR wherever possible.
+.PP
+The newly created channel is not registered in the supplied interpreter; to
+register it, use \fBTcl_RegisterChannel\fR, described below.
+If one of the standard channels, \fBstdin\fR, \fBstdout\fR or \fBstderr\fR was
+previously closed, the act of creating the new channel also assigns it as a
+replacement for the standard channel.
+.SH TCL_OPENCOMMANDCHANNEL
+.PP
+\fBTcl_OpenCommandChannel\fR provides a C-level interface to the
+functions of the \fBexec\fR and \fBopen\fR commands.
+It creates a sequence of subprocesses specified
+by the \fIargv\fR and \fIargc\fR arguments and returns a channel that can
+be used to communicate with these subprocesses.
+The \fIflags\fR argument indicates what sort of communication will
+exist with the command pipeline.
+.PP
+If the \fBTCL_STDIN\fR flag is set then the standard input for the
+first subprocess will be tied to the channel: writing to the channel
+will provide input to the subprocess.  If \fBTCL_STDIN\fR is not set,
+then standard input for the first subprocess will be the same as this
+application's standard input.  If \fBTCL_STDOUT\fR is set then
+standard output from the last subprocess can be read from the channel;
+otherwise it goes to this application's standard output.  If
+\fBTCL_STDERR\fR is set, standard error output for all subprocesses is
+returned to the channel and results in an error when the channel is
+closed; otherwise it goes to this application's standard error.  If
+\fBTCL_ENFORCE_MODE\fR is not set, then \fIargc\fR and \fIargv\fR can
+redirect the stdio handles to override \fBTCL_STDIN\fR,
+\fBTCL_STDOUT\fR, and \fBTCL_STDERR\fR; if it is set, then it is an
+error for argc and argv to override stdio channels for which
+\fBTCL_STDIN\fR, \fBTCL_STDOUT\fR, and \fBTCL_STDERR\fR have been set.
+.PP
+If an error occurs while opening the channel, \fBTcl_OpenCommandChannel\fR
+returns NULL and records a POSIX error code that can be retrieved with
+\fBTcl_GetErrno\fR.
+In addition, \fBTcl_OpenCommandChannel\fR leaves an error message in
+the interpreter's result if \fIinterp\fR is not NULL.
+.PP
+The newly created channel is not registered in the supplied interpreter; to
+register it, use \fBTcl_RegisterChannel\fR, described below.
+If one of the standard channels, \fBstdin\fR, \fBstdout\fR or \fBstderr\fR was
+previously closed, the act of creating the new channel also assigns it as a
+replacement for the standard channel.
+.SH TCL_MAKEFILECHANNEL
+.PP
+\fBTcl_MakeFileChannel\fR makes a \fBTcl_Channel\fR from an existing,
+platform-specific, file handle.
+The newly created channel is not registered in the supplied interpreter; to
+register it, use \fBTcl_RegisterChannel\fR, described below.
+If one of the standard channels, \fBstdin\fR, \fBstdout\fR or \fBstderr\fR was
+previously closed, the act of creating the new channel also assigns it as a
+replacement for the standard channel.
+.SH TCL_GETCHANNEL
+.PP
+\fBTcl_GetChannel\fR returns a channel given the \fIchannelName\fR used to
+create it with \fBTcl_CreateChannel\fR and a pointer to a Tcl interpreter in
+\fIinterp\fR. If a channel by that name is not registered in that interpreter,
+the procedure returns NULL. If the \fImodePtr\fR argument is not NULL, it
+points at an integer variable that will receive an OR-ed combination of
+\fBTCL_READABLE\fR and \fBTCL_WRITABLE\fR describing whether the channel is
+open for reading and writing.
+.PP
+\fBTcl_GetChannelNames\fR and \fBTcl_GetChannelNamesEx\fR write the
+names of the registered channels to the interpreter's result as a
+list value.  \fBTcl_GetChannelNamesEx\fR will filter these names
+according to the \fIpattern\fR.  If \fIpattern\fR is NULL, then it
+will not do any filtering.  The return value is \fBTCL_OK\fR if no
+errors occurred writing to the result, otherwise it is \fBTCL_ERROR\fR,
+and the error message is left in the interpreter's result.
+.SH TCL_REGISTERCHANNEL
+.PP
+\fBTcl_RegisterChannel\fR adds a channel to the set of channels accessible
+in \fIinterp\fR. After this call, Tcl programs executing in that
+interpreter can refer to the channel in input or output operations using
+the name given in the call to \fBTcl_CreateChannel\fR.  After this call,
+the channel becomes the property of the interpreter, and the caller should
+not call \fBTcl_Close\fR for the channel; the channel will be closed
+automatically when it is unregistered from the interpreter.
+.PP
+Code executing outside of any Tcl interpreter can call
+\fBTcl_RegisterChannel\fR with \fIinterp\fR as NULL, to indicate that it
+wishes to hold a reference to this channel. Subsequently, the channel can
+be registered in a Tcl interpreter and it will only be closed when the
+matching number of calls to \fBTcl_UnregisterChannel\fR have been made.
+This allows code executing outside of any interpreter to safely hold a
+reference to a channel that is also registered in a Tcl interpreter.
+.PP
+This procedure interacts with the code managing the standard
+channels. If no standard channels were initialized before the first
+call to \fBTcl_RegisterChannel\fR, they will get initialized by that
+call. See \fBTcl_StandardChannels\fR for a general treatise about
+standard channels and the behavior of the Tcl library with regard to
+them.
+.SH TCL_UNREGISTERCHANNEL
+.PP
+\fBTcl_UnregisterChannel\fR removes a channel from the set of channels
+accessible in \fIinterp\fR. After this call, Tcl programs will no longer be
+able to use the channel's name to refer to the channel in that interpreter.
+If this operation removed the last registration of the channel in any
+interpreter, the channel is also closed and destroyed.
+.PP
+Code not associated with a Tcl interpreter can call
+\fBTcl_UnregisterChannel\fR with \fIinterp\fR as NULL, to indicate to Tcl
+that it no longer holds a reference to that channel. If this is the last
+reference to the channel, it will now be closed.  \fBTcl_UnregisterChannel\fR
+is very similar to \fBTcl_DetachChannel\fR except that it will also
+close the channel if no further references to it exist.
+.SH TCL_DETACHCHANNEL
+.PP
+\fBTcl_DetachChannel\fR removes a channel from the set of channels
+accessible in \fIinterp\fR. After this call, Tcl programs will no longer be
+able to use the channel's name to refer to the channel in that interpreter.
+Beyond that, this command has no further effect.  It cannot be used on
+the standard channels (\fBstdout\fR, \fBstderr\fR, \fBstdin\fR), and will return
+\fBTCL_ERROR\fR if passed one of those channels.
+.PP
+Code not associated with a Tcl interpreter can call
+\fBTcl_DetachChannel\fR with \fIinterp\fR as NULL, to indicate to Tcl
+that it no longer holds a reference to that channel. If this is the last
+reference to the channel, unlike \fBTcl_UnregisterChannel\fR,
+it will not be closed.
+.SH TCL_ISSTANDARDCHANNEL
+.PP
+\fBTcl_IsStandardChannel\fR tests whether a channel is one of the
+three standard channels, \fBstdin\fR, \fBstdout\fR or \fBstderr\fR.
+If so, it returns 1, otherwise 0.
+.PP
+No attempt is made to check whether the given channel or the standard
+channels are initialized or otherwise valid.
+.SH TCL_CLOSE
+.PP
+\fBTcl_Close\fR destroys the channel \fIchannel\fR, which must denote a
+currently open channel. The channel should not be registered in any
+interpreter when \fBTcl_Close\fR is called. Buffered output is flushed to
+the channel's output device prior to destroying the channel, and any
+buffered input is discarded.  If this is a blocking channel, the call does
+not return until all buffered data is successfully sent to the channel's
+output device.  If this is a nonblocking channel and there is buffered
+output that cannot be written without blocking, the call returns
+immediately; output is flushed in the background and the channel will be
+closed once all of the buffered data has been output.  In this case errors
+during flushing are not reported.
+.PP
+If the channel was closed successfully, \fBTcl_Close\fR returns \fBTCL_OK\fR.
+If an error occurs, \fBTcl_Close\fR returns \fBTCL_ERROR\fR and records a
+POSIX error code that can be retrieved with \fBTcl_GetErrno\fR.
+If the channel is being closed synchronously and an error occurs during
+closing of the channel and \fIinterp\fR is not NULL, an error message is
+left in the interpreter's result.
+.PP
+Note: it is not safe to call \fBTcl_Close\fR on a channel that has been
+registered using \fBTcl_RegisterChannel\fR; see the documentation for
+\fBTcl_RegisterChannel\fR, above, for details. If the channel has ever
+been given as the \fBchan\fR argument in a call to
+\fBTcl_RegisterChannel\fR, you should instead use
+\fBTcl_UnregisterChannel\fR, which will internally call \fBTcl_Close\fR
+when all calls to \fBTcl_RegisterChannel\fR have been matched by
+corresponding calls to \fBTcl_UnregisterChannel\fR.
+.SH "TCL_READCHARS AND TCL_READ"
+.PP
+\fBTcl_ReadChars\fR consumes bytes from \fIchannel\fR, converting the bytes
+to UTF-8 based on the channel's encoding and storing the produced data in
+\fIreadObjPtr\fR's string representation.  The return value of
+\fBTcl_ReadChars\fR is the number of characters, up to \fIcharsToRead\fR,
+that were stored in \fIreadObjPtr\fR.  If an error occurs while reading, the
+return value is \-1 and \fBTcl_ReadChars\fR records a POSIX error code that
+can be retrieved with \fBTcl_GetErrno\fR.
+.PP
+Setting \fIcharsToRead\fR to \fB\-1\fR will cause the command to read
+all characters currently available (non-blocking) or everything until
+eof (blocking mode).
+.PP
+The return value may be smaller than the value to read, indicating that less
+data than requested was available.  This is called a \fIshort read\fR.  In
+blocking mode, this can only happen on an end-of-file.  In nonblocking mode,
+a short read can also occur if there is not enough input currently
+available:  \fBTcl_ReadChars\fR returns a short count rather than waiting
+for more data.
+.PP
+If the channel is in blocking mode, a return value of zero indicates an
+end-of-file condition.  If the channel is in nonblocking mode, a return
+value of zero indicates either that no input is currently available or an
+end-of-file condition.  Use \fBTcl_Eof\fR and \fBTcl_InputBlocked\fR to tell
+which of these conditions actually occurred.
+.PP
+\fBTcl_ReadChars\fR translates the various end-of-line representations into
+the canonical \fB\en\fR internal representation according to the current
+end-of-line recognition mode.  End-of-line recognition and the various
+platform-specific modes are described in the manual entry for the Tcl
+\fBfconfigure\fR command.
+.PP
+As a performance optimization, when reading from a channel with the encoding
+\fBbinary\fR, the bytes are not converted to UTF-8 as they are read.
+Instead, they are stored in \fIreadObjPtr\fR's internal representation as a
+byte-array value.  The string representation of this value will only be
+constructed if it is needed (e.g., because of a call to
+\fBTcl_GetStringFromObj\fR).  In this way, byte-oriented data can be read
+from a channel, manipulated by calling \fBTcl_GetByteArrayFromObj\fR and
+related functions, and then written to a channel without the expense of ever
+converting to or from UTF-8.
+.PP
+\fBTcl_Read\fR is similar to \fBTcl_ReadChars\fR, except that it does not do
+encoding conversions, regardless of the channel's encoding.  It is deprecated
+and exists for backwards compatibility with non-internationalized Tcl
+extensions.  It consumes bytes from \fIchannel\fR and stores them in
+\fIreadBuf\fR, performing end-of-line translations on the way.  The return value
+of \fBTcl_Read\fR is the number of bytes, up to \fIbytesToRead\fR, written in
+\fIreadBuf\fR.  The buffer produced by \fBTcl_Read\fR is not null-terminated.
+Its contents are valid from the zeroth position up to and excluding the
+position indicated by the return value.
+.PP
+\fBTcl_ReadRaw\fR is the same as \fBTcl_Read\fR but does not
+compensate for stacking. While \fBTcl_Read\fR (and the other functions
+in the API) always get their data from the topmost channel in the
+stack the supplied channel is part of, \fBTcl_ReadRaw\fR does
+not. Thus this function is \fBonly\fR usable for transformational
+channel drivers, i.e. drivers used in the middle of a stack of
+channels, to move data from the channel below into the transformation.
+.SH "TCL_GETSOBJ AND TCL_GETS"
+.PP
+\fBTcl_GetsObj\fR consumes bytes from \fIchannel\fR, converting the bytes to
+UTF-8 based on the channel's encoding, until a full line of input has been
+seen.  If the channel's encoding is \fBbinary\fR, each byte read from the
+channel is treated as an individual Unicode character.  All of the
+characters of the line except for the terminating end-of-line character(s)
+are appended to \fIlineObjPtr\fR's string representation.  The end-of-line
+character(s) are read and discarded.
+.PP
+If a line was successfully read, the return value is greater than or equal
+to zero and indicates the number of bytes stored in \fIlineObjPtr\fR.  If an
+error occurs, \fBTcl_GetsObj\fR returns \-1 and records a POSIX error code
+that can be retrieved with \fBTcl_GetErrno\fR.  \fBTcl_GetsObj\fR also
+returns \-1 if the end of the file is reached; the \fBTcl_Eof\fR procedure
+can be used to distinguish an error from an end-of-file condition.
+.PP
+If the channel is in nonblocking mode, the return value can also be \-1 if
+no data was available or the data that was available did not contain an
+end-of-line character.  When \-1 is returned, the \fBTcl_InputBlocked\fR
+procedure may be invoked to determine if the channel is blocked because
+of input unavailability.
+.PP
+\fBTcl_Gets\fR is the same as \fBTcl_GetsObj\fR except the resulting
+characters are appended to the dynamic string given by
+\fIlineRead\fR rather than a Tcl value.
+.SH "TCL_UNGETS"
+.PP
+\fBTcl_Ungets\fR is used to add data to the input queue of a channel,
+at either the head or tail of the queue.  The pointer \fIinput\fR points
+to the data that is to be added.  The length of the input to add is given
+by \fIinputLen\fR.  A non-zero value of \fIaddAtEnd\fR indicates that the
+data is to be added at the end of queue; otherwise it will be added at the
+head of the queue.  If \fIchannel\fR has a
+.QW sticky
+EOF set, no data will be
+added to the input queue.  \fBTcl_Ungets\fR returns \fIinputLen\fR or
+\-1 if an error occurs.
+.SH "TCL_WRITECHARS, TCL_WRITEOBJ, AND TCL_WRITE"
+.PP
+\fBTcl_WriteChars\fR accepts \fIbytesToWrite\fR bytes of character data at
+\fIcharBuf\fR.  The UTF-8 characters in the buffer are converted to the
+channel's encoding and queued for output to \fIchannel\fR.  If
+\fIbytesToWrite\fR is negative, \fBTcl_WriteChars\fR expects \fIcharBuf\fR
+to be null-terminated and it outputs everything up to the null.
+.PP
+Data queued for output may not appear on the output device immediately, due
+to internal buffering.  If the data should appear immediately, call
+\fBTcl_Flush\fR after the call to \fBTcl_WriteChars\fR, or set the
+\fB\-buffering\fR option on the channel to \fBnone\fR.  If you wish the data
+to appear as soon as a complete line is accepted for output, set the
+\fB\-buffering\fR option on the channel to \fBline\fR mode.
+.PP
+The return value of \fBTcl_WriteChars\fR is a count of how many bytes were
+accepted for output to the channel.  This is either greater than zero to
+indicate success or \-1 to indicate that an error occurred.  If an error
+occurs, \fBTcl_WriteChars\fR records a POSIX error code that may be
+retrieved with \fBTcl_GetErrno\fR.
+.PP
+Newline characters in the output data are translated to platform-specific
+end-of-line sequences according to the \fB\-translation\fR option for the
+channel.  This is done even if the channel has no encoding.
+.PP
+\fBTcl_WriteObj\fR is similar to \fBTcl_WriteChars\fR except it
+accepts a Tcl value whose contents will be output to the channel.  The
+UTF-8 characters in \fIwriteObjPtr\fR's string representation are converted
+to the channel's encoding and queued for output to \fIchannel\fR.
+As a performance optimization, when writing to a channel with the encoding
+\fBbinary\fR, UTF-8 characters are not converted as they are written.
+Instead, the bytes in \fIwriteObjPtr\fR's internal representation as a
+byte-array value are written to the channel.  The byte-array representation
+of the value will be constructed if it is needed.  In this way,
+byte-oriented data can be read from a channel, manipulated by calling
+\fBTcl_GetByteArrayFromObj\fR and related functions, and then written to a
+channel without the expense of ever converting to or from UTF-8.
+.PP
+\fBTcl_Write\fR is similar to \fBTcl_WriteChars\fR except that it does not do
+encoding conversions, regardless of the channel's encoding.  It is
+deprecated and exists for backwards compatibility with non-internationalized
+Tcl extensions.  It accepts \fIbytesToWrite\fR bytes of data at
+\fIbyteBuf\fR and queues them for output to \fIchannel\fR.  If
+\fIbytesToWrite\fR is negative, \fBTcl_Write\fR expects \fIbyteBuf\fR to be
+null-terminated and it outputs everything up to the null.
+.PP
+\fBTcl_WriteRaw\fR is the same as \fBTcl_Write\fR but does not
+compensate for stacking. While \fBTcl_Write\fR (and the other
+functions in the API) always feed their input to the topmost channel
+in the stack the supplied channel is part of, \fBTcl_WriteRaw\fR does
+not. Thus this function is \fBonly\fR usable for transformational
+channel drivers, i.e. drivers used in the middle of a stack of
+channels, to move data from the transformation into the channel below
+it.
+.SH TCL_FLUSH
+.PP
+\fBTcl_Flush\fR causes all of the buffered output data for \fIchannel\fR
+to be written to its underlying file or device as soon as possible.
+If the channel is in blocking mode, the call does not return until
+all the buffered data has been sent to the channel or some error occurred.
+The call returns immediately if the channel is nonblocking; it starts
+a background flush that will write the buffered data to the channel
+eventually, as fast as the channel is able to absorb it.
+.PP
+The return value is normally \fBTCL_OK\fR.
+If an error occurs, \fBTcl_Flush\fR returns \fBTCL_ERROR\fR and
+records a POSIX error code that can be retrieved with \fBTcl_GetErrno\fR.
+.SH TCL_SEEK
+.PP
+\fBTcl_Seek\fR moves the access point in \fIchannel\fR where subsequent
+data will be read or written. Buffered output is flushed to the channel and
+buffered input is discarded, prior to the seek operation.
+.PP
+\fBTcl_Seek\fR normally returns the new access point.
+If an error occurs, \fBTcl_Seek\fR returns \-1 and records a POSIX error
+code that can be retrieved with \fBTcl_GetErrno\fR.
+After an error, the access point may or may not have been moved.
+.SH TCL_TELL
+.PP
+\fBTcl_Tell\fR returns the current access point for a channel. The returned
+value is \-1 if the channel does not support seeking.
+.SH TCL_TRUNCATECHANNEL
+.PP
+\fBTcl_TruncateChannel\fR truncates the file underlying \fIchannel\fR
+to a given \fIlength\fR of bytes. It returns \fBTCL_OK\fR if the
+operation succeeded, and \fBTCL_ERROR\fR otherwise.
+.SH TCL_GETCHANNELOPTION
+.PP
+\fBTcl_GetChannelOption\fR retrieves, in \fIoptionValue\fR, the value of one of
+the options currently in effect for a channel, or a list of all options and
+their values.  The \fIchannel\fR argument identifies the channel for which
+to query an option or retrieve all options and their values.
+If \fIoptionName\fR is not NULL, it is the name of the
+option to query; the option's value is copied to the Tcl dynamic string
+denoted by \fIoptionValue\fR. If
+\fIoptionName\fR is NULL, the function stores an alternating list of option
+names and their values in \fIoptionValue\fR, using a series of calls to
+\fBTcl_DStringAppendElement\fR. The various preexisting options and
+their possible values are described in the manual entry for the Tcl
+\fBfconfigure\fR command. Other options can be added by each channel type.
+These channel type specific options are described in the manual entry for
+the Tcl command that creates a channel of that type; for example, the
+additional options for TCP based channels are described in the manual entry
+for the Tcl \fBsocket\fR command.
+The procedure normally returns \fBTCL_OK\fR. If an error occurs, it returns
+\fBTCL_ERROR\fR and calls \fBTcl_SetErrno\fR to store an appropriate POSIX
+error code.
+.SH TCL_SETCHANNELOPTION
+.PP
+\fBTcl_SetChannelOption\fR sets a new value \fInewValue\fR
+for an option \fIoptionName\fR on \fIchannel\fR.
+The procedure normally returns \fBTCL_OK\fR.  If an error occurs,
+it returns \fBTCL_ERROR\fR;  in addition, if \fIinterp\fR is non-NULL,
+\fBTcl_SetChannelOption\fR leaves an error message in the interpreter's result.
+.SH TCL_EOF
+.PP
+\fBTcl_Eof\fR returns a nonzero value if \fIchannel\fR encountered
+an end of file during the last input operation.
+.SH TCL_INPUTBLOCKED
+.PP
+\fBTcl_InputBlocked\fR returns a nonzero value if \fIchannel\fR is in
+nonblocking mode and the last input operation returned less data than
+requested because there was insufficient data available.
+The call always returns zero if the channel is in blocking mode.
+.SH TCL_INPUTBUFFERED
+.PP
+\fBTcl_InputBuffered\fR returns the number of bytes of input currently
+buffered in the internal buffers for a channel. If the channel is not open
+for reading, this function always returns zero.
+.SH TCL_OUTPUTBUFFERED
+.PP
+\fBTcl_OutputBuffered\fR returns the number of bytes of output
+currently buffered in the internal buffers for a channel. If the
+channel is not open for writing, this function always returns zero.
+.SH "PLATFORM ISSUES"
+.PP
+The handles returned from \fBTcl_GetChannelHandle\fR depend on the
+platform and the channel type.  On Unix platforms, the handle is
+always a Unix file descriptor as returned from the \fBopen\fR system
+call.  On Windows platforms, the handle is a file \fBHANDLE\fR when
+the channel was created with \fBTcl_OpenFileChannel\fR,
+\fBTcl_OpenCommandChannel\fR, or \fBTcl_MakeFileChannel\fR.  Other
+channel types may return a different type of handle on Windows
+platforms.
+.SH "SEE ALSO"
+DString(3), fconfigure(n), filename(n), fopen(3), Tcl_CreateChannel(3)
+.SH KEYWORDS
+access point, blocking, buffered I/O, channel, channel driver, end of file,
+flush, input, nonblocking, output, read, seek, write
diff --git a/doc/OpenTcp.3 b/doc/OpenTcp.3
new file mode 100644
index 0000000..9fe2615
--- /dev/null
+++ b/doc/OpenTcp.3
@@ -0,0 +1,169 @@
+'\"
+'\" Copyright (c) 1996-7 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH Tcl_OpenTcpClient 3 8.0 Tcl "Tcl Library Procedures"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+Tcl_OpenTcpClient, Tcl_MakeTcpClientChannel, Tcl_OpenTcpServer \- procedures to open channels using TCP sockets
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h> \fR
+.sp
+Tcl_Channel
+\fBTcl_OpenTcpClient\fR(\fIinterp, port, host, myaddr, myport, async\fR)
+.sp
+Tcl_Channel
+\fBTcl_MakeTcpClientChannel\fR(\fIsock\fR)
+.sp
+Tcl_Channel
+\fBTcl_OpenTcpServer\fR(\fIinterp, port, myaddr, proc, clientData\fR)
+.sp
+.SH ARGUMENTS
+.AS Tcl_TcpAcceptProc clientData
+.AP Tcl_Interp *interp in
+Tcl interpreter to use for error reporting.  If non-NULL and an
+error occurs, an error message is left in the interpreter's result.
+.AP int port in
+A port number to connect to as a client or to listen on as a server.
+.AP "const char" *host in
+A string specifying a host name or address for the remote end of the connection.
+.AP int myport in
+A port number for the client's end of the socket.  If 0, a port number
+is allocated at random.
+.AP "const char" *myaddr in
+A string specifying the host name or address for network interface to use
+for the local end of the connection.  If NULL, a default interface is
+chosen.
+.AP int async in
+If nonzero, the client socket is connected asynchronously to the server.
+.AP ClientData sock in
+Platform-specific handle for client TCP socket.
+.AP Tcl_TcpAcceptProc *proc in
+Pointer to a procedure to invoke each time a new connection is
+accepted via the socket.
+.AP ClientData clientData in
+Arbitrary one-word value to pass to \fIproc\fR.
+.BE
+.SH DESCRIPTION
+.PP
+These functions are convenience procedures for creating
+channels that communicate over TCP sockets.
+The operations on a channel
+are described in the manual entry for \fBTcl_OpenFileChannel\fR.
+.SS TCL_OPENTCPCLIENT
+.PP
+\fBTcl_OpenTcpClient\fR opens a client TCP socket connected to a \fIport\fR
+on a specific \fIhost\fR, and returns a channel that can be used to
+communicate with the server. The host to connect to can be specified either
+as a domain name style name (e.g. \fBwww.sunlabs.com\fR), or as a string
+containing the alphanumeric representation of its four-byte address (e.g.
+\fB127.0.0.1\fR). Use the string \fBlocalhost\fR to connect to a TCP socket on
+the host on which the function is invoked.
+.PP
+The \fImyaddr\fR and \fImyport\fR arguments allow a client to specify an
+address for the local end of the connection.  If \fImyaddr\fR is NULL, then
+an interface is chosen automatically by the operating system.
+If \fImyport\fR is 0, then a port number is chosen at random by
+the operating system.
+.PP
+If \fIasync\fR is zero, the call to \fBTcl_OpenTcpClient\fR returns only
+after the client socket has either successfully connected to the server, or
+the attempted connection has failed.
+If \fIasync\fR is nonzero the socket is connected asynchronously and the
+returned channel may not yet be connected to the server when the call to
+\fBTcl_OpenTcpClient\fR returns. If the channel is in blocking mode and an
+input or output operation is done on the channel before the connection is
+completed or fails, that operation will wait until the connection either
+completes successfully or fails. If the channel is in nonblocking mode, the
+input or output operation will return immediately and a subsequent call to
+\fBTcl_InputBlocked\fR on the channel will return nonzero.
+.PP
+The returned channel is opened for reading and writing.
+If an error occurs in opening the socket, \fBTcl_OpenTcpClient\fR returns
+NULL and records a POSIX error code that can be retrieved
+with \fBTcl_GetErrno\fR.
+In addition, if \fIinterp\fR is non-NULL, an error message
+is left in the interpreter's result.
+.PP
+The newly created channel is not registered in the supplied interpreter; to
+register it, use \fBTcl_RegisterChannel\fR.
+If one of the standard channels, \fBstdin\fR, \fBstdout\fR or \fBstderr\fR was
+previously closed, the act of creating the new channel also assigns it as a
+replacement for the standard channel.
+.SS TCL_MAKETCPCLIENTCHANNEL
+.PP
+\fBTcl_MakeTcpClientChannel\fR creates a \fBTcl_Channel\fR around an
+existing, platform specific, handle for a client TCP socket.
+.PP
+The newly created channel is not registered in the supplied interpreter; to
+register it, use \fBTcl_RegisterChannel\fR.
+If one of the standard channels, \fBstdin\fR, \fBstdout\fR or \fBstderr\fR was
+previously closed, the act of creating the new channel also assigns it as a
+replacement for the standard channel.
+.SS TCL_OPENTCPSERVER
+.PP
+\fBTcl_OpenTcpServer\fR opens a TCP socket on the local host on a specified
+\fIport\fR and uses the Tcl event mechanism to accept requests from clients
+to connect to it. The \fImyaddr\fR argument specifies the network interface.
+If \fImyaddr\fR is NULL the special address INADDR_ANY should be used to
+allow connections from any network interface.
+Each time a client connects to this socket, Tcl creates a channel
+for the new connection and invokes \fIproc\fR with information about
+the channel. \fIProc\fR must match the following prototype:
+.PP
+.CS
+typedef void \fBTcl_TcpAcceptProc\fR(
+        ClientData \fIclientData\fR,
+        Tcl_Channel \fIchannel\fR,
+        char *\fIhostName\fR,
+        int \fIport\fR);
+.CE
+.PP
+The \fIclientData\fR argument will be the same as the \fIclientData\fR
+argument to \fBTcl_OpenTcpServer\fR, \fIchannel\fR will be the handle
+for the new channel, \fIhostName\fR points to a string containing
+the name of the client host making the connection, and \fIport\fR
+will contain the client's port number.
+The new channel
+is opened for both input and output. 
+If \fIproc\fR raises an error, the connection is closed automatically.
+\fIProc\fR has no return value, but if it wishes to reject the
+connection it can close \fIchannel\fR.
+.PP
+\fBTcl_OpenTcpServer\fR normally returns a pointer to a channel
+representing the server socket.
+If an error occurs, \fBTcl_OpenTcpServer\fR returns NULL and
+records a POSIX error code that can be retrieved with \fBTcl_GetErrno\fR.
+In addition, if the interpreter is non-NULL, an error message
+is left in the interpreter's result.
+.PP
+The channel returned by \fBTcl_OpenTcpServer\fR cannot be used for
+either input or output.
+It is simply a handle for the socket used to accept connections.
+The caller can close the channel to shut down the server and disallow
+further connections from new clients.
+.PP
+TCP server channels operate correctly only in applications that dispatch
+events through \fBTcl_DoOneEvent\fR or through Tcl commands such as
+\fBvwait\fR; otherwise Tcl will never notice that a connection request from
+a remote client is pending.
+.PP
+The newly created channel is not registered in the supplied interpreter; to
+register it, use \fBTcl_RegisterChannel\fR.
+If one of the standard channels, \fBstdin\fR, \fBstdout\fR or \fBstderr\fR was
+previously closed, the act of creating the new channel also assigns it as a
+replacement for the standard channel.
+.SH "PLATFORM ISSUES"
+.PP
+On Unix platforms, the socket handle is a Unix file descriptor as
+returned by the \fBsocket\fR system call.  On the Windows platform, the
+socket handle is a \fBSOCKET\fR as defined in the WinSock API.
+.SH "SEE ALSO"
+Tcl_OpenFileChannel(3), Tcl_RegisterChannel(3), vwait(n)
+.SH KEYWORDS
+channel, client, server, socket, TCP
diff --git a/doc/Panic.3 b/doc/Panic.3
new file mode 100644
index 0000000..af86665
--- /dev/null
+++ b/doc/Panic.3
@@ -0,0 +1,89 @@
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH Tcl_Panic 3 8.4 Tcl "Tcl Library Procedures"
+.so man.macros
+.BS
+'\"  Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+Tcl_Panic, Tcl_PanicVA, Tcl_SetPanicProc \- report fatal error and abort
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+void
+\fBTcl_Panic\fR(\fIformat\fR, \fIarg\fR, \fIarg\fR, \fI...\fR)
+.sp
+void
+\fBTcl_PanicVA\fR(\fIformat\fR, \fIargList\fR)
+.sp
+void
+\fBTcl_SetPanicProc\fR(\fIpanicProc\fR)
+.sp
+.SH ARGUMENTS
+.AS Tcl_PanicProc *panicProc
+.AP "const char*" format in
+A printf-style format string.
+.AP "" arg in
+Arguments matching the format string.
+.AP va_list argList in
+An argument list of arguments matching the format string.
+Must have been initialized using \fBva_start\fR,
+and cleared using \fBva_end\fR.
+.AP Tcl_PanicProc *panicProc in
+Procedure to report fatal error message and abort.
+.BE
+.SH DESCRIPTION
+.PP
+When the Tcl library detects that its internal data structures are in an
+inconsistent state, or that its C procedures have been called in a
+manner inconsistent with their documentation, it calls \fBTcl_Panic\fR
+to display a message describing the error and abort the process.  The
+\fIformat\fR argument is a format string describing how to format the
+remaining arguments \fIarg\fR into an error message, according to the
+same formatting rules used by the \fBprintf\fR family of functions.  The
+same formatting rules are also used by the built-in Tcl command
+\fBformat\fR.
+.PP
+In a freshly loaded Tcl library, \fBTcl_Panic\fR prints the formatted
+error message to the standard error file of the process, and then
+calls \fBabort\fR to terminate the process.  \fBTcl_Panic\fR does not
+return. On Windows, when a debugger is running, the formatted error
+message is sent to the debugger in stead. If the windows executable
+does not have a stderr channel (e.g. \fBwish.exe\fR), then a
+system dialog box is used to display the panic message.
+.PP
+\fBTcl_SetPanicProc\fR may be used to modify the behavior of
+\fBTcl_Panic\fR.  The \fIpanicProc\fR argument should match the
+type \fBTcl_PanicProc\fR:
+.PP
+.CS
+typedef void \fBTcl_PanicProc\fR(
+        const char *\fBformat\fR,
+        \fBarg\fR, \fBarg\fR,...);
+.CE
+.PP
+After \fBTcl_SetPanicProc\fR returns, any future calls to
+\fBTcl_Panic\fR will call \fIpanicProc\fR, passing along the
+\fIformat\fR and \fIarg\fR arguments. \fIpanicProc\fR should avoid
+making calls into the Tcl library, or into other libraries that may
+call the Tcl library, since the original call to \fBTcl_Panic\fR
+indicates the Tcl library is not in a state of reliable operation.
+.PP
+The typical use of \fBTcl_SetPanicProc\fR arranges for the error message
+to be displayed or reported in a manner more suitable for the
+application or the platform.
+.PP
+Although the primary callers of \fBTcl_Panic\fR are the procedures of
+the Tcl library, \fBTcl_Panic\fR is a public function and may be called
+by any extension or application that wishes to abort the process and
+have a panic message displayed the same way that panic messages from Tcl
+will be displayed.
+.PP
+\fBTcl_PanicVA\fR is the same as \fBTcl_Panic\fR except that instead of
+taking a variable number of arguments it takes an argument list.
+.SH "SEE ALSO"
+abort(3), printf(3), exec(n), format(n)
+.SH KEYWORDS
+abort, fatal, error
diff --git a/doc/ParseArgs.3 b/doc/ParseArgs.3
new file mode 100644
index 0000000..df0ad33
--- /dev/null
+++ b/doc/ParseArgs.3
@@ -0,0 +1,198 @@
+'\"
+'\" Copyright (c) 2008 Donal K. Fellows
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\" 
+.TH Tcl_ParseArgsObjv 3 8.6 Tcl "Tcl Library Procedures"
+.so man.macros
+.BS
+.SH NAME
+Tcl_ParseArgsObjv \- parse arguments according to a tabular description
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+int
+\fBTcl_ParseArgsObjv\fR(\fIinterp, argTable, objcPtr, objv, remObjv\fR)
+.SH ARGUMENTS
+.AS "const Tcl_ArgvInfo" ***remObjv in/out
+.AP Tcl_Interp *interp out
+Where to store error messages.
+.AP "const Tcl_ArgvInfo" *argTable in
+Pointer to array of option descriptors.
+.AP int *objcPtr in/out
+A pointer to variable holding number of arguments in \fIobjv\fR. Will be
+modified to hold number of arguments left in the unprocessed argument list
+stored in \fIremObjv\fR.
+.AP "Tcl_Obj *const" *objv in
+The array of arguments to be parsed.
+.AP Tcl_Obj ***remObjv out
+Pointer to a variable that will hold the array of unprocessed arguments.
+Should be NULL if no return of unprocessed arguments is required. If
+\fIobjcPtr\fR is updated to a non-zero value, the array returned through this
+must be deallocated using \fBckfree\fR.
+.BE
+.SH DESCRIPTION
+.PP
+The \fBTcl_ParseArgsObjv\fR function provides a system for parsing argument
+lists of the form
+.QW "\fB\-someName \fIsomeValue\fR ..." .
+Such argument lists are commonly found both in the arguments to a program and
+in the arguments to an individual Tcl command. This parser assumes that the
+order of the arguments does not matter, other than in so far as later copies
+of a duplicated option overriding earlier ones.
+.PP
+The argument array is described by the \fIobjcPtr\fR and \fIobjv\fR
+parameters, and an array of unprocessed arguments is returned through the
+\fIobjcPtr\fR and \fIremObjv\fR parameters; if no return of unprocessed
+arguments is desired, the \fIremObjv\fR parameter should be NULL. If any
+problems happen, including if the
+.QW "generate help"
+option is selected, an error message is left in the interpreter result and
+TCL_ERROR is returned. Otherwise, the interpreter result is left unchanged and
+TCL_OK is returned.
+.PP
+The collection of arguments to be parsed is described by the \fIargTable\fR
+parameter. This points to a table of descriptor structures that is terminated
+by an entry with the \fItype\fR field set to TCL_ARGV_END. As convenience, the
+following prototypical entries are provided:
+.TP
+\fBTCL_ARGV_AUTO_HELP\fR
+.
+Enables the argument processor to provide help when passed the argument
+.QW \fB\-help\fR .
+.TP
+\fBTCL_ARGV_AUTO_REST\fR
+.
+Instructs the argument processor that arguments after
+.QW \fB\-\-\fR
+are to be unprocessed.
+.TP
+\fBTCL_ARGV_TABLE_END\fR
+.
+Marks the end of the table of argument descriptors.
+.SS "ARGUMENT DESCRIPTOR ENTRIES"
+.PP
+Each entry of the argument descriptor table must be a structure of type
+\fBTcl_ArgvInfo\fR. The structure is defined as this:
+.PP
+.CS
+typedef struct {
+    int \fItype\fR;
+    const char *\fIkeyStr\fR;
+    void *\fIsrcPtr\fR;
+    void *\fIdstPtr\fR;
+    const char *\fIhelpStr\fR;
+    ClientData \fIclientData\fR;
+} \fBTcl_ArgvInfo\fR;
+.CE
+.PP
+The \fIkeyStr\fR field contains the name of the option; by convention, this
+will normally begin with a
+.QW \fB\-\fR
+character. The \fItype\fR, \fIsrcPtr\fR, \fIdstPtr\fR and \fIclientData\fR
+fields describe the interpretation of the value of the argument, as described
+below. The \fIhelpStr\fR field gives some text that is used to provide help to
+users when they request it.
+.PP
+As noted above, the \fItype\fR field is used to describe the interpretation of
+the argument's value. The following values are acceptable values for
+\fItype\fR:
+.TP
+\fBTCL_ARGV_CONSTANT\fR
+.
+The argument does not take any following value argument. If this argument is
+present, the int pointed to by the \fIsrcPtr\fR field is copied to the
+\fIdstPtr\fR field. The \fIclientData\fR field is ignored.
+.TP
+\fBTCL_ARGV_END\fR
+.
+This value marks the end of all option descriptors in the table. All other
+fields are ignored.
+.TP
+\fBTCL_ARGV_FLOAT\fR
+.
+This argument takes a following floating point value argument. The value (once
+parsed by \fBTcl_GetDoubleFromObj\fR) will be stored as a double-precision
+value in the variable pointed to by the \fIdstPtr\fR field. The \fIsrcPtr\fR
+and \fIclientData\fR fields are ignored.
+.TP
+\fBTCL_ARGV_FUNC\fR
+.
+This argument optionally takes a following value argument; it is up to the
+handler callback function passed in \fIsrcPtr\fR to decide. That function will
+have the following signature:
+.RS
+.PP
+.CS
+typedef int (\fBTcl_ArgvFuncProc\fR)(
+        ClientData \fIclientData\fR,
+        Tcl_Obj *\fIobjPtr\fR,
+        void *\fIdstPtr\fR);
+.CE
+.PP
+The result is a boolean value indicating whether to consume the following
+argument. The \fIclientData\fR is the value from the table entry, the
+\fIobjPtr\fR is the value that represents the following argument or NULL if
+there are no following arguments at all, and the \fIdstPtr\fR argument to the
+\fBTcl_ArgvFuncProc\fR is the location to write the parsed value to.
+.RE
+.TP
+\fBTCL_ARGV_GENFUNC\fR
+.
+This argument takes zero or more following arguments; the handler callback
+function passed in \fIsrcPtr\fR returns how many (or a negative number to
+signal an error, in which case it should also set the interpreter result). The
+function will have the following signature:
+.RS
+.PP
+.CS
+typedef int (\fBTcl_ArgvGenFuncProc\fR)(
+        ClientData \fIclientData\fR,
+        Tcl_Interp *\fIinterp\fR,
+        int \fIobjc\fR,
+        Tcl_Obj *const *\fIobjv\fR,
+        void *\fIdstPtr\fR);
+.CE
+.PP
+The \fIclientData\fR is the value from the table entry, the \fIinterp\fR is
+where to store any error messages, the \fIkeyStr\fR is the name of the
+argument, \fIobjc\fR and \fIobjv\fR describe an array of all the remaining
+arguments, and \fIdstPtr\fR argument to the \fBTcl_ArgvGenFuncProc\fR is the
+location to write the parsed value (or values) to.
+.RE
+.TP
+\fBTCL_ARGV_HELP\fR
+.
+This special argument does not take any following value argument, but instead
+causes \fBTcl_ParseArgsObjv\fR to generate an error message describing the
+arguments supported. All other fields except the \fIhelpStr\fR field are
+ignored.
+.TP
+\fBTCL_ARGV_INT\fR
+.
+This argument takes a following integer value argument. The value (once parsed
+by \fBTcl_GetIntFromObj\fR) will be stored as an int in the variable pointed
+to by the \fIdstPtr\fR field. The \fIsrcPtr\fR field is ignored.
+.TP
+\fBTCL_ARGV_REST\fR
+.
+This special argument does not take any following value argument, but instead
+marks all following arguments to be left unprocessed. The \fIsrcPtr\fR,
+\fIdstPtr\fR and \fIclientData\fR fields are ignored.
+.TP
+\fBTCL_ARGV_STRING\fR
+.
+This argument takes a following string value argument. A pointer to the string
+will be stored at \fIdstPtr\fR; the string inside will have a lifetime linked
+to the lifetime of the string representation of the argument value that it
+came from, and so should be copied if it needs to be retained. The
+\fIsrcPtr\fR and \fIclientData\fR fields are ignored.
+.SH "SEE ALSO"
+Tcl_GetIndexFromObj(3), Tcl_Main(3), Tcl_CreateObjCommand(3)
+.SH KEYWORDS
+argument, parse
+'\" Local Variables:
+'\" fill-column: 78
+'\" End:
diff --git a/doc/ParseCmd.3 b/doc/ParseCmd.3
new file mode 100644
index 0000000..667d697
--- /dev/null
+++ b/doc/ParseCmd.3
@@ -0,0 +1,467 @@
+'\"
+'\" Copyright (c) 1997 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH Tcl_ParseCommand 3 8.3 Tcl "Tcl Library Procedures"
+.so man.macros
+.BS
+.SH NAME
+Tcl_ParseCommand, Tcl_ParseExpr, Tcl_ParseBraces, Tcl_ParseQuotedString, Tcl_ParseVarName, Tcl_ParseVar, Tcl_FreeParse, Tcl_EvalTokens, Tcl_EvalTokensStandard \- parse Tcl scripts and expressions
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+int
+\fBTcl_ParseCommand\fR(\fIinterp, start, numBytes, nested, parsePtr\fR)
+.sp
+int
+\fBTcl_ParseExpr\fR(\fIinterp, start, numBytes, parsePtr\fR)
+.sp
+int
+\fBTcl_ParseBraces\fR(\fIinterp, start, numBytes, parsePtr, append, termPtr\fR)
+.sp
+int
+\fBTcl_ParseQuotedString\fR(\fIinterp, start, numBytes, parsePtr, append, termPtr\fR)
+.sp
+int
+\fBTcl_ParseVarName\fR(\fIinterp, start, numBytes, parsePtr, append\fR)
+.sp
+const char *
+\fBTcl_ParseVar\fR(\fIinterp, start, termPtr\fR)
+.sp
+\fBTcl_FreeParse\fR(\fIusedParsePtr\fR)
+.sp
+Tcl_Obj *
+\fBTcl_EvalTokens\fR(\fIinterp, tokenPtr, numTokens\fR)
+.sp
+int
+\fBTcl_EvalTokensStandard\fR(\fIinterp, tokenPtr, numTokens\fR)
+.SH ARGUMENTS
+.AS Tcl_Interp *usedParsePtr out
+.AP Tcl_Interp *interp out
+For procedures other than \fBTcl_FreeParse\fR, \fBTcl_EvalTokens\fR
+and \fBTcl_EvalTokensStandard\fR, used only for error reporting;
+if NULL, then no error messages are left after errors.
+For \fBTcl_EvalTokens\fR and \fBTcl_EvalTokensStandard\fR,
+determines the context for evaluating the
+script and also is used for error reporting; must not be NULL.
+.AP "const char" *start in
+Pointer to first character in string to parse.
+.AP int numBytes in
+Number of bytes in string to parse, not including any terminating null
+character.  If less than 0 then the script consists of all characters
+following \fIstart\fR up to the first null character.
+.AP int nested in
+Non-zero means that the script is part of a command substitution so an
+unquoted close bracket should be treated as a command terminator.  If zero,
+close brackets have no special meaning.
+.AP int append in
+Non-zero means that \fI*parsePtr\fR already contains valid tokens; the new
+tokens should be appended to those already present.  Zero means that
+\fI*parsePtr\fR is uninitialized; any information in it is ignored.
+This argument is normally 0.
+.AP Tcl_Parse *parsePtr out
+Points to structure to fill in with information about the parsed
+command, expression, variable name, etc.
+Any previous information in this structure
+is ignored, unless \fIappend\fR is non-zero in a call to
+\fBTcl_ParseBraces\fR, \fBTcl_ParseQuotedString\fR,
+or \fBTcl_ParseVarName\fR.
+.AP "const char" **termPtr out
+If not NULL, points to a location where
+\fBTcl_ParseBraces\fR, \fBTcl_ParseQuotedString\fR, and
+\fBTcl_ParseVar\fR will store a pointer to the character
+just after the terminating character (the close-brace, the last
+character of the variable name, or the close-quote (respectively))
+if the parse was successful.
+.AP Tcl_Parse *usedParsePtr in
+Points to structure that was filled in by a previous call to
+\fBTcl_ParseCommand\fR, \fBTcl_ParseExpr\fR, \fBTcl_ParseVarName\fR, etc.
+.BE
+.SH DESCRIPTION
+.PP
+These procedures parse Tcl commands or portions of Tcl commands such as
+expressions or references to variables.
+Each procedure takes a pointer to a script (or portion thereof)
+and fills in the structure pointed to by \fIparsePtr\fR
+with a collection of tokens describing the information that was parsed.
+The procedures normally return \fBTCL_OK\fR.
+However, if an error occurs then they return \fBTCL_ERROR\fR,
+leave an error message in \fIinterp\fR's result
+(if \fIinterp\fR is not NULL),
+and leave nothing in \fIparsePtr\fR.
+.PP
+\fBTcl_ParseCommand\fR is a procedure that parses Tcl
+scripts.  Given a pointer to a script, it
+parses the first command from the script.  If the command was parsed
+successfully, \fBTcl_ParseCommand\fR returns \fBTCL_OK\fR and fills in the
+structure pointed to by \fIparsePtr\fR with information about the
+structure of the command (see below for details).
+If an error occurred in parsing the command then
+\fBTCL_ERROR\fR is returned, an error message is left in \fIinterp\fR's
+result, and no information is left at \fI*parsePtr\fR.
+.PP
+\fBTcl_ParseExpr\fR parses Tcl expressions.
+Given a pointer to a script containing an expression,
+\fBTcl_ParseExpr\fR parses the expression.
+If the expression was parsed successfully,
+\fBTcl_ParseExpr\fR returns \fBTCL_OK\fR and fills in the
+structure pointed to by \fIparsePtr\fR with information about the
+structure of the expression (see below for details).
+If an error occurred in parsing the command then
+\fBTCL_ERROR\fR is returned, an error message is left in \fIinterp\fR's
+result, and no information is left at \fI*parsePtr\fR.
+.PP
+\fBTcl_ParseBraces\fR parses a string or command argument
+enclosed in braces such as
+\fB{hello}\fR or \fB{string \et with \et tabs}\fR
+from the beginning of its argument \fIstart\fR.
+The first character of \fIstart\fR must be \fB{\fR.
+If the braced string was parsed successfully,
+\fBTcl_ParseBraces\fR returns \fBTCL_OK\fR,
+fills in the structure pointed to by \fIparsePtr\fR
+with information about the structure of the string
+(see below for details),
+and stores a pointer to the character just after the terminating \fB}\fR
+in the location given by \fI*termPtr\fR.
+If an error occurs while parsing the string
+then \fBTCL_ERROR\fR is returned,
+an error message is left in \fIinterp\fR's result,
+and no information is left at \fI*parsePtr\fR or \fI*termPtr\fR.
+.PP
+\fBTcl_ParseQuotedString\fR parses a double-quoted string such as
+\fB"sum is [expr {$a+$b}]"\fR
+from the beginning of the argument \fIstart\fR.
+The first character of \fIstart\fR must be \fB\N'34'\fR.
+If the double-quoted string was parsed successfully,
+\fBTcl_ParseQuotedString\fR returns \fBTCL_OK\fR,
+fills in the structure pointed to by \fIparsePtr\fR
+with information about the structure of the string
+(see below for details),
+and stores a pointer to the character just after the terminating \fB\N'34'\fR
+in the location given by \fI*termPtr\fR.
+If an error occurs while parsing the string
+then \fBTCL_ERROR\fR is returned,
+an error message is left in \fIinterp\fR's result,
+and no information is left at \fI*parsePtr\fR or \fI*termPtr\fR.
+.PP
+\fBTcl_ParseVarName\fR parses a Tcl variable reference such as
+\fB$abc\fR or \fB$x([expr {$index + 1}])\fR from the beginning of its
+\fIstart\fR argument.
+The first character of \fIstart\fR must be \fB$\fR.
+If a variable name was parsed successfully, \fBTcl_ParseVarName\fR
+returns \fBTCL_OK\fR and fills in the structure pointed to by
+\fIparsePtr\fR with information about the structure of the variable name
+(see below for details).  If an error
+occurs while parsing the command then \fBTCL_ERROR\fR is returned, an
+error message is left in \fIinterp\fR's result (if \fIinterp\fR is not
+NULL), and no information is left at \fI*parsePtr\fR.
+.PP
+\fBTcl_ParseVar\fR parse a Tcl variable reference such as \fB$abc\fR
+or \fB$x([expr {$index + 1}])\fR from the beginning of its \fIstart\fR
+argument.  The first character of \fIstart\fR must be \fB$\fR.  If
+the variable name is parsed successfully, \fBTcl_ParseVar\fR returns a
+pointer to the string value of the variable.  If an error occurs while
+parsing, then NULL is returned and an error message is left in
+\fIinterp\fR's result.
+.PP
+The information left at \fI*parsePtr\fR
+by \fBTcl_ParseCommand\fR, \fBTcl_ParseExpr\fR, \fBTcl_ParseBraces\fR,
+\fBTcl_ParseQuotedString\fR, and \fBTcl_ParseVarName\fR
+may include dynamically allocated memory.
+If these five parsing procedures return \fBTCL_OK\fR
+then the caller must invoke \fBTcl_FreeParse\fR to release
+the storage at \fI*parsePtr\fR.
+These procedures ignore any existing information in
+\fI*parsePtr\fR (unless \fIappend\fR is non-zero),
+so if repeated calls are being made to any of them
+then \fBTcl_FreeParse\fR must be invoked once after each call.
+.PP
+\fBTcl_EvalTokensStandard\fR evaluates a sequence of parse tokens from
+a Tcl_Parse structure.  The tokens typically consist
+of all the tokens in a word or all the tokens that make up the index for
+a reference to an array variable.  \fBTcl_EvalTokensStandard\fR performs the
+substitutions requested by the tokens and concatenates the
+resulting values.
+The return value from \fBTcl_EvalTokensStandard\fR is a Tcl completion
+code with one of the values \fBTCL_OK\fR, \fBTCL_ERROR\fR,
+\fBTCL_RETURN\fR, \fBTCL_BREAK\fR, or \fBTCL_CONTINUE\fR, or possibly
+some other integer value originating in an extension.
+In addition, a result value or error message is left in \fIinterp\fR's
+result; it can be retrieved using \fBTcl_GetObjResult\fR.
+.PP
+\fBTcl_EvalTokens\fR differs from \fBTcl_EvalTokensStandard\fR only in
+the return convention used: it returns the result in a new Tcl_Obj.
+The reference count of the value returned as result has been
+incremented, so the caller must
+invoke \fBTcl_DecrRefCount\fR when it is finished with the value.
+If an error or other exception occurs while evaluating the tokens
+(such as a reference to a non-existent variable) then the return value
+is NULL and an error message is left in \fIinterp\fR's result. The use
+of \fBTcl_EvalTokens\fR is deprecated.
+.SH "TCL_PARSE STRUCTURE"
+.PP
+\fBTcl_ParseCommand\fR, \fBTcl_ParseExpr\fR, \fBTcl_ParseBraces\fR,
+\fBTcl_ParseQuotedString\fR, and \fBTcl_ParseVarName\fR
+return parse information in two data structures, Tcl_Parse and Tcl_Token:
+.PP
+.CS
+typedef struct Tcl_Parse {
+    const char *\fIcommentStart\fR;
+    int \fIcommentSize\fR;
+    const char *\fIcommandStart\fR;
+    int \fIcommandSize\fR;
+    int \fInumWords\fR;
+    Tcl_Token *\fItokenPtr\fR;
+    int \fInumTokens\fR;
+    ...
+} \fBTcl_Parse\fR;
+
+typedef struct Tcl_Token {
+    int \fItype\fR;
+    const char *\fIstart\fR;
+    int \fIsize\fR;
+    int \fInumComponents\fR;
+} \fBTcl_Token\fR;
+.CE
+.PP
+The first five fields of a Tcl_Parse structure
+are filled in only by \fBTcl_ParseCommand\fR.
+These fields are not used by the other parsing procedures.
+.PP
+\fBTcl_ParseCommand\fR fills in a Tcl_Parse structure
+with information that describes one Tcl command and any comments that
+precede the command.
+If there are comments,
+the \fIcommentStart\fR field points to the \fB#\fR character that begins
+the first comment and \fIcommentSize\fR indicates the number of bytes
+in all of the comments preceding the command, including the newline
+character that terminates the last comment.
+If the command is not preceded by any comments, \fIcommentSize\fR is 0.
+\fBTcl_ParseCommand\fR also sets the \fIcommandStart\fR field
+to point to the first character of the first
+word in the command (skipping any comments and leading space) and
+\fIcommandSize\fR gives the total number of bytes in the command,
+including the character pointed to by \fIcommandStart\fR up to and
+including the newline, close bracket, or semicolon character that
+terminates the command.  The \fInumWords\fR field gives the
+total number of words in the command.
+.PP
+All parsing procedures set the remaining fields,
+\fItokenPtr\fR and \fInumTokens\fR.
+The \fItokenPtr\fR field points to the first in an array of Tcl_Token
+structures that describe the components of the entity being parsed.
+The \fInumTokens\fR field gives the total number of tokens
+present in the array.
+Each token contains four fields.
+The \fItype\fR field selects one of several token types
+that are described below.  The \fIstart\fR field
+points to the first character in the token and the \fIsize\fR field
+gives the total number of characters in the token.  Some token types,
+such as \fBTCL_TOKEN_WORD\fR and \fBTCL_TOKEN_VARIABLE\fR, consist of
+several component tokens, which immediately follow the parent token;
+the \fInumComponents\fR field describes how many of these there are.
+The \fItype\fR field has one of the following values:
+.TP 20
+\fBTCL_TOKEN_WORD\fR
+.
+This token ordinarily describes one word of a command
+but it may also describe a quoted or braced string in an expression.
+The token describes a component of the script that is
+the result of concatenating together a sequence of subcomponents,
+each described by a separate subtoken.
+The token starts with the first non-blank
+character of the component (which may be a double-quote or open brace)
+and includes all characters in the component up to but not including the
+space, semicolon, close bracket, close quote, or close brace that
+terminates the component.  The \fInumComponents\fR field counts the total
+number of sub-tokens that make up the word, including sub-tokens
+of \fBTCL_TOKEN_VARIABLE\fR and \fBTCL_TOKEN_BS\fR tokens.
+.TP
+\fBTCL_TOKEN_SIMPLE_WORD\fR
+.
+This token has the same meaning as \fBTCL_TOKEN_WORD\fR, except that
+the word is guaranteed to consist of a single \fBTCL_TOKEN_TEXT\fR
+sub-token.  The \fInumComponents\fR field is always 1.
+.TP
+\fBTCL_TOKEN_EXPAND_WORD\fR
+.
+This token has the same meaning as \fBTCL_TOKEN_WORD\fR, except that
+the command parser notes this word began with the expansion
+prefix \fB{*}\fR, indicating that after substitution,
+the list value of this word should be expanded to form multiple
+arguments in command evaluation.  This
+token type can only be created by Tcl_ParseCommand.
+.TP
+\fBTCL_TOKEN_TEXT\fR
+.
+The token describes a range of literal text that is part of a word.
+The \fInumComponents\fR field is always 0.
+.TP
+\fBTCL_TOKEN_BS\fR
+.
+The token describes a backslash sequence such as \fB\en\fR or \fB\e0xa3\fR.
+The \fInumComponents\fR field is always 0.
+.TP
+\fBTCL_TOKEN_COMMAND\fR
+.
+The token describes a command whose result must be substituted into
+the word.  The token includes the square brackets that surround the
+command.  The \fInumComponents\fR field is always 0 (the nested command
+is not parsed; call \fBTcl_ParseCommand\fR recursively if you want to
+see its tokens).
+.TP
+\fBTCL_TOKEN_VARIABLE\fR
+.
+The token describes a variable substitution, including the
+\fB$\fR, variable name, and array index (if there is one) up through the
+close parenthesis that terminates the index.  This token is followed
+by one or more additional tokens that describe the variable name and
+array index.  If \fInumComponents\fR  is 1 then the variable is a
+scalar and the next token is a \fBTCL_TOKEN_TEXT\fR token that gives the
+variable name.  If \fInumComponents\fR is greater than 1 then the
+variable is an array: the first sub-token is a \fBTCL_TOKEN_TEXT\fR
+token giving the array name and the remaining sub-tokens are
+\fBTCL_TOKEN_TEXT\fR, \fBTCL_TOKEN_BS\fR, \fBTCL_TOKEN_COMMAND\fR, and
+\fBTCL_TOKEN_VARIABLE\fR tokens that must be concatenated to produce the
+array index. The \fInumComponents\fR field includes nested sub-tokens
+that are part of \fBTCL_TOKEN_VARIABLE\fR tokens in the array index.
+.TP
+\fBTCL_TOKEN_SUB_EXPR\fR
+.
+The token describes one subexpression of an expression
+(or an entire expression).
+A subexpression may consist of a value
+such as an integer literal, variable substitution,
+or parenthesized subexpression;
+it may also consist of an operator and its operands.
+The token starts with the first non-blank character of the subexpression
+up to but not including the space, brace, close-paren, or bracket
+that terminates the subexpression.
+This token is followed by one or more additional tokens
+that describe the subexpression.
+If the first sub-token after the \fBTCL_TOKEN_SUB_EXPR\fR token
+is a \fBTCL_TOKEN_OPERATOR\fR token,
+the subexpression consists of an operator and its token operands.
+If the operator has no operands, the subexpression consists of
+just the \fBTCL_TOKEN_OPERATOR\fR token.
+Each operand is described by a \fBTCL_TOKEN_SUB_EXPR\fR token.
+Otherwise, the subexpression is a value described by
+one of the token types \fBTCL_TOKEN_WORD\fR, \fBTCL_TOKEN_TEXT\fR,
+\fBTCL_TOKEN_BS\fR, \fBTCL_TOKEN_COMMAND\fR,
+\fBTCL_TOKEN_VARIABLE\fR, and \fBTCL_TOKEN_SUB_EXPR\fR.
+The \fInumComponents\fR field
+counts the total number of sub-tokens that make up the subexpression;
+this includes the sub-tokens for any nested \fBTCL_TOKEN_SUB_EXPR\fR tokens.
+.TP
+\fBTCL_TOKEN_OPERATOR\fR
+.
+The token describes one operator of an expression
+such as \fB&&\fR or \fBhypot\fR.
+A \fBTCL_TOKEN_OPERATOR\fR token is always preceded by a
+\fBTCL_TOKEN_SUB_EXPR\fR token
+that describes the operator and its operands;
+the \fBTCL_TOKEN_SUB_EXPR\fR token's \fInumComponents\fR field
+can be used to determine the number of operands.
+A binary operator such as \fB*\fR
+is followed by two \fBTCL_TOKEN_SUB_EXPR\fR tokens
+that describe its operands.
+A unary operator like \fB\-\fR
+is followed by a single \fBTCL_TOKEN_SUB_EXPR\fR token
+for its operand.
+If the operator is a math function such as \fBlog10\fR,
+the \fBTCL_TOKEN_OPERATOR\fR token will give its name and
+the following \fBTCL_TOKEN_SUB_EXPR\fR tokens will describe
+its operands;
+if there are no operands (as with \fBrand\fR),
+no \fBTCL_TOKEN_SUB_EXPR\fR tokens follow.
+There is one trinary operator, \fB?\fR,
+that appears in if-then-else subexpressions
+such as \fIx\fB?\fIy\fB:\fIz\fR;
+in this case, the \fB?\fR \fBTCL_TOKEN_OPERATOR\fR token
+is followed by three \fBTCL_TOKEN_SUB_EXPR\fR tokens for the operands
+\fIx\fR, \fIy\fR, and \fIz\fR.
+The \fInumComponents\fR field for a \fBTCL_TOKEN_OPERATOR\fR token
+is always 0.
+.PP
+After \fBTcl_ParseCommand\fR returns, the first token pointed to by
+the \fItokenPtr\fR field of the
+Tcl_Parse structure always has type \fBTCL_TOKEN_WORD\fR or
+\fBTCL_TOKEN_SIMPLE_WORD\fR or \fBTCL_TOKEN_EXPAND_WORD\fR.
+It is followed by the sub-tokens
+that must be concatenated to produce the value of that word.
+The next token is the \fBTCL_TOKEN_WORD\fR or \fBTCL_TOKEN_SIMPLE_WORD\fR
+of \fBTCL_TOKEN_EXPAND_WORD\fR token for the second word,
+followed by sub-tokens for that
+word, and so on until all \fInumWords\fR have been accounted
+for.
+.PP
+After \fBTcl_ParseExpr\fR returns, the first token pointed to by
+the \fItokenPtr\fR field of the
+Tcl_Parse structure always has type \fBTCL_TOKEN_SUB_EXPR\fR.
+It is followed by the sub-tokens that must be evaluated
+to produce the value of the expression.
+Only the token information in the Tcl_Parse structure
+is modified: the \fIcommentStart\fR, \fIcommentSize\fR,
+\fIcommandStart\fR, and \fIcommandSize\fR fields are not modified
+by \fBTcl_ParseExpr\fR.
+.PP
+After \fBTcl_ParseBraces\fR returns,
+the array of tokens pointed to by the \fItokenPtr\fR field of the
+Tcl_Parse structure will contain a single \fBTCL_TOKEN_TEXT\fR token
+if the braced string does not contain any backslash-newlines.
+If the string does contain backslash-newlines,
+the array of tokens will contain one or more
+\fBTCL_TOKEN_TEXT\fR or \fBTCL_TOKEN_BS\fR sub-tokens
+that must be concatenated to produce the value of the string.
+If the braced string was just \fB{}\fR
+(that is, the string was empty),
+the single \fBTCL_TOKEN_TEXT\fR token will have a \fIsize\fR field
+containing zero;
+this ensures that at least one token appears
+to describe the braced string.
+Only the token information in the Tcl_Parse structure
+is modified: the \fIcommentStart\fR, \fIcommentSize\fR,
+\fIcommandStart\fR, and \fIcommandSize\fR fields are not modified
+by \fBTcl_ParseBraces\fR.
+.PP
+After \fBTcl_ParseQuotedString\fR returns,
+the array of tokens pointed to by the \fItokenPtr\fR field of the
+Tcl_Parse structure depends on the contents of the quoted string.
+It will consist of one or more \fBTCL_TOKEN_TEXT\fR, \fBTCL_TOKEN_BS\fR,
+\fBTCL_TOKEN_COMMAND\fR, and \fBTCL_TOKEN_VARIABLE\fR sub-tokens.
+The array always contains at least one token;
+for example, if the argument \fIstart\fR is empty,
+the array returned consists of a single \fBTCL_TOKEN_TEXT\fR token
+with a zero \fIsize\fR field.
+Only the token information in the Tcl_Parse structure
+is modified: the \fIcommentStart\fR, \fIcommentSize\fR,
+\fIcommandStart\fR, and \fIcommandSize\fR fields are not modified.
+.PP
+After \fBTcl_ParseVarName\fR returns, the first token pointed to by
+the \fItokenPtr\fR field of the
+Tcl_Parse structure always has type \fBTCL_TOKEN_VARIABLE\fR.  It
+is followed by the sub-tokens that make up the variable name as
+described above.  The total length of the variable name is
+contained in the \fIsize\fR field of the first token.
+As in \fBTcl_ParseExpr\fR,
+only the token information in the Tcl_Parse structure
+is modified by \fBTcl_ParseVarName\fR:
+the \fIcommentStart\fR, \fIcommentSize\fR,
+\fIcommandStart\fR, and \fIcommandSize\fR fields are not modified.
+.PP
+All of the character pointers in the
+Tcl_Parse and Tcl_Token structures refer
+to characters in the \fIstart\fR argument passed to
+\fBTcl_ParseCommand\fR, \fBTcl_ParseExpr\fR, \fBTcl_ParseBraces\fR,
+\fBTcl_ParseQuotedString\fR, and \fBTcl_ParseVarName\fR.
+.PP
+There are additional fields in the Tcl_Parse structure after the
+\fInumTokens\fR field, but these are for the private use of
+\fBTcl_ParseCommand\fR, \fBTcl_ParseExpr\fR, \fBTcl_ParseBraces\fR,
+\fBTcl_ParseQuotedString\fR, and \fBTcl_ParseVarName\fR; they should not be
+referenced by code outside of these procedures.
+.SH KEYWORDS
+backslash substitution, braces, command, expression, parse, token, variable substitution
diff --git a/doc/PkgRequire.3 b/doc/PkgRequire.3
new file mode 100644
index 0000000..71f3acf
--- /dev/null
+++ b/doc/PkgRequire.3
@@ -0,0 +1,97 @@
+'\"
+'\" Copyright (c) 1996 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH Tcl_PkgRequire 3 7.5 Tcl "Tcl Library Procedures"
+.so man.macros
+.BS
+.SH NAME
+Tcl_PkgRequire, Tcl_PkgRequireEx, Tcl_PkgRequireProc, Tcl_PkgPresent, Tcl_PkgPresentEx, Tcl_PkgProvide, Tcl_PkgProvideEx \- package version control
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+const char *
+\fBTcl_PkgRequire\fR(\fIinterp, name, version, exact\fR)
+.sp
+const char *
+\fBTcl_PkgRequireEx\fR(\fIinterp, name, version, exact, clientDataPtr\fR)
+.sp
+int
+\fBTcl_PkgRequireProc\fR(\fIinterp, name, objc, objv, clientDataPtr\fR)
+.sp
+const char *
+\fBTcl_PkgPresent\fR(\fIinterp, name, version, exact\fR)
+.sp
+const char *
+\fBTcl_PkgPresentEx\fR(\fIinterp, name, version, exact, clientDataPtr\fR)
+.sp
+int
+\fBTcl_PkgProvide\fR(\fIinterp, name, version\fR)
+.sp
+int
+\fBTcl_PkgProvideEx\fR(\fIinterp, name, version, clientData\fR)
+.SH ARGUMENTS
+.AS void *clientDataPtr out
+.AP Tcl_Interp *interp in
+Interpreter where package is needed or available.
+.AP "const char" *name in
+Name of package.
+.AP "const char" *version in
+A version string consisting of one or more decimal numbers
+separated by dots.
+.AP int exact in
+Non-zero means that only the particular version specified by
+\fIversion\fR is acceptable.
+Zero means that newer versions than \fIversion\fR are also
+acceptable as long as they have the same major version number
+as \fIversion\fR.
+.AP "const void" *clientData in
+Arbitrary value to be associated with the package.
+.AP void *clientDataPtr out
+Pointer to place to store the value associated with the matching
+package. It is only changed if the pointer is not NULL and the
+function completed successfully. The storage can be any pointer
+type with the same size as a void pointer.
+.AP int objc in
+Number of requirements.
+.AP Tcl_Obj* objv[] in
+Array of requirements.
+.BE
+.SH DESCRIPTION
+.PP
+These procedures provide C-level interfaces to Tcl's package and
+version management facilities.
+.PP
+\fBTcl_PkgRequire\fR is equivalent to the \fBpackage require\fR
+command, \fBTcl_PkgPresent\fR is equivalent to the \fBpackage present\fR
+command, and \fBTcl_PkgProvide\fR is equivalent to the
+\fBpackage provide\fR command.
+.PP
+See the documentation for the Tcl commands for details on what these
+procedures do.
+.PP
+If \fBTcl_PkgPresent\fR or \fBTcl_PkgRequire\fR complete successfully
+they return a pointer to the version string for the version of the package
+that is provided in the interpreter (which may be different than
+\fIversion\fR); if an error occurs they return NULL and leave an error
+message in the interpreter's result.
+.PP
+\fBTcl_PkgProvide\fR returns \fBTCL_OK\fR if it completes successfully;
+if an error occurs it returns \fBTCL_ERROR\fR and leaves an error message
+in the interpreter's result.
+.PP
+\fBTcl_PkgProvideEx\fR, \fBTcl_PkgPresentEx\fR and \fBTcl_PkgRequireEx\fR
+allow the setting and retrieving of the client data associated with
+the package. In all other respects they are equivalent to the matching
+functions.
+.PP
+\fBTcl_PkgRequireProc\fR is the form of \fBpackage require\fR handling
+multiple requirements. The other forms are present for backward
+compatibility and translate their invocations to this form.
+.SH KEYWORDS
+package, present, provide, require, version
+.SH "SEE ALSO"
+package(n), Tcl_StaticPackage(3)
diff --git a/doc/Preserve.3 b/doc/Preserve.3
new file mode 100644
index 0000000..970bded
--- /dev/null
+++ b/doc/Preserve.3
@@ -0,0 +1,110 @@
+'\"
+'\" Copyright (c) 1990 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\" 
+.TH Tcl_Preserve 3 7.5 Tcl "Tcl Library Procedures"
+.so man.macros
+.BS
+.SH NAME
+Tcl_Preserve, Tcl_Release, Tcl_EventuallyFree \- avoid freeing storage while it is being used
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+\fBTcl_Preserve\fR(\fIclientData\fR)
+.sp
+\fBTcl_Release\fR(\fIclientData\fR)
+.sp
+\fBTcl_EventuallyFree\fR(\fIclientData, freeProc\fR)
+.SH ARGUMENTS
+.AS Tcl_FreeProc clientData
+.AP ClientData clientData in
+Token describing structure to be freed or reallocated.  Usually a pointer
+to memory for structure.
+.AP Tcl_FreeProc *freeProc in
+Procedure to invoke to free \fIclientData\fR.
+.BE
+.SH DESCRIPTION
+.PP
+These three procedures help implement a simple reference count mechanism
+for managing storage.  They are designed to solve a problem
+having to do with widget deletion, but are also useful in many other
+situations.  When a widget is deleted, its
+widget record (the structure holding information specific to the
+widget) must be returned to the storage allocator.
+However, it is possible that the widget record is in active use
+by one of the procedures on the stack at the time of the deletion.
+This can happen, for example, if the command associated with a button
+widget causes the button to be destroyed:  an X event causes an
+event-handling C procedure in the button to be invoked, which in
+turn causes the button's associated Tcl command to be executed,
+which in turn causes the button to be deleted, which in turn causes
+the button's widget record to be de-allocated.
+Unfortunately, when the Tcl command returns, the button's
+event-handling procedure will need to reference the
+button's widget record.
+Because of this, the widget record must not be freed as part of the
+deletion, but must be retained until the event-handling procedure has
+finished with it.
+In other situations where the widget is deleted, it may be possible
+to free the widget record immediately.
+.PP
+\fBTcl_Preserve\fR and \fBTcl_Release\fR
+implement short-term reference counts for their \fIclientData\fR
+argument.
+The \fIclientData\fR argument identifies an object and usually
+consists of the address of a structure.
+The reference counts guarantee that an object will not be freed
+until each call to \fBTcl_Preserve\fR for the object has been
+matched by calls to \fBTcl_Release\fR.
+There may be any number of unmatched \fBTcl_Preserve\fR calls
+in effect at once.
+.PP
+\fBTcl_EventuallyFree\fR is invoked to free up its \fIclientData\fR
+argument.
+It checks to see if there are unmatched \fBTcl_Preserve\fR calls
+for the object.
+If not, then \fBTcl_EventuallyFree\fR calls \fIfreeProc\fR immediately.
+Otherwise \fBTcl_EventuallyFree\fR records the fact that \fIclientData\fR
+needs eventually to be freed.
+When all calls to \fBTcl_Preserve\fR have been matched with
+calls to \fBTcl_Release\fR then \fIfreeProc\fR will be called by
+\fBTcl_Release\fR to do the cleanup.
+.PP
+All the work of freeing the object is carried out by \fIfreeProc\fR.
+\fIFreeProc\fR must have arguments and result that match the
+type \fBTcl_FreeProc\fR:
+.PP
+.CS
+typedef void \fBTcl_FreeProc\fR(
+        char *\fIblockPtr\fR);
+.CE
+.PP
+The \fIblockPtr\fR argument to \fIfreeProc\fR will be the
+same as the \fIclientData\fR argument to \fBTcl_EventuallyFree\fR.
+The type of \fIblockPtr\fR (\fBchar *\fR) is different than the type of the
+\fIclientData\fR argument to \fBTcl_EventuallyFree\fR for historical
+reasons, but the value is the same.
+.PP
+When the \fIclientData\fR argument to \fBTcl_EventuallyFree\fR
+refers to storage allocated and returned by a prior call to
+\fBTcl_Alloc\fR, \fBckalloc\fR, or another function of the Tcl library,
+then the \fIfreeProc\fR argument should be given the special value of
+\fBTCL_DYNAMIC\fR.
+.PP
+This mechanism can be used to solve the problem described above
+by placing \fBTcl_Preserve\fR and \fBTcl_Release\fR calls around
+actions that may cause undesired storage re-allocation.  The
+mechanism is intended only for short-term use (i.e. while procedures
+are pending on the stack);  it will not work efficiently as a
+mechanism for long-term reference counts.
+The implementation does not depend in any way on the internal
+structure of the objects being freed;  it keeps the reference
+counts in a separate structure.
+.SH "SEE ALSO"
+Tcl_Interp, Tcl_Alloc
+.SH KEYWORDS
+free, reference count, storage
diff --git a/doc/PrintDbl.3 b/doc/PrintDbl.3
new file mode 100644
index 0000000..730794f
--- /dev/null
+++ b/doc/PrintDbl.3
@@ -0,0 +1,51 @@
+'\"
+'\" Copyright (c) 1989-1993 The Regents of the University of California.
+'\" Copyright (c) 1994-1997 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\" 
+.TH Tcl_PrintDouble 3 8.0 Tcl "Tcl Library Procedures"
+.so man.macros
+.BS
+.SH NAME
+Tcl_PrintDouble \- Convert floating value to string
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+\fBTcl_PrintDouble\fR(\fIinterp, value, dst\fR)
+.SH ARGUMENTS
+.AS Tcl_Interp *interp out
+.AP Tcl_Interp *interp in
+Before Tcl 8.0, the \fBtcl_precision\fR variable in this interpreter
+controlled the conversion.  As of Tcl 8.0, this argument is ignored and
+the conversion is controlled by the \fBtcl_precision\fR variable
+that is now shared by all interpreters.
+.AP double value in
+Floating-point value to be converted.
+.AP char *dst out
+Where to store the string representing \fIvalue\fR.  Must have at
+least \fBTCL_DOUBLE_SPACE\fR characters of storage.
+.BE
+.SH DESCRIPTION
+.PP
+\fBTcl_PrintDouble\fR generates a string that represents the value
+of \fIvalue\fR and stores it in memory at the location given by
+\fIdst\fR.  It uses \fB%g\fR format to generate the string, with one
+special twist: the string is guaranteed to contain either a
+.QW .
+or an
+.QW e
+so that it does not look like an integer.  Where \fB%g\fR would
+generate an integer with no decimal point, \fBTcl_PrintDouble\fR adds
+.QW .0 .
+.PP
+If the \fBtcl_precision\fR value is non-zero, the result will have
+precisely that many digits of significance.  If the value is zero
+(the default), the result will have the fewest digits needed to
+represent the number in such a way that \fBTcl_NewDoubleObj\fR
+will generate the same number when presented with the given string.
+IEEE semantics of rounding to even apply to the conversion.
+.SH KEYWORDS
+conversion, double-precision, floating-point, string
diff --git a/doc/RecEvalObj.3 b/doc/RecEvalObj.3
new file mode 100644
index 0000000..387cc44
--- /dev/null
+++ b/doc/RecEvalObj.3
@@ -0,0 +1,53 @@
+'\"
+'\" Copyright (c) 1997 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\" 
+.TH Tcl_RecordAndEvalObj 3 8.0 Tcl "Tcl Library Procedures"
+.so man.macros
+.BS
+.SH NAME
+Tcl_RecordAndEvalObj \- save command on history list before evaluating
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+int
+\fBTcl_RecordAndEvalObj\fR(\fIinterp, cmdPtr, flags\fR)
+.SH ARGUMENTS
+.AS Tcl_Interp *interp
+.AP Tcl_Interp *interp in
+Tcl interpreter in which to evaluate command.
+.AP Tcl_Obj *cmdPtr in
+Points to a Tcl value containing a command (or sequence of commands)
+to execute.
+.AP int flags in
+An OR'ed combination of flag bits.  \fBTCL_NO_EVAL\fR means record the
+command but do not evaluate it.  \fBTCL_EVAL_GLOBAL\fR means evaluate
+the command at global level instead of the current stack level.
+.BE
+
+.SH DESCRIPTION
+.PP
+\fBTcl_RecordAndEvalObj\fR is invoked to record a command as an event
+on the history list and then execute it using \fBTcl_EvalObjEx\fR
+(or \fBTcl_GlobalEvalObj\fR if the \fBTCL_EVAL_GLOBAL\fR bit is set
+in \fIflags\fR).
+It returns a completion code such as \fBTCL_OK\fR just like \fBTcl_EvalObjEx\fR,
+as well as a result value containing additional information
+(a result value or error message)
+that can be retrieved using \fBTcl_GetObjResult\fR.
+If you do not want the command recorded on the history list then
+you should invoke \fBTcl_EvalObjEx\fR instead of \fBTcl_RecordAndEvalObj\fR.
+Normally \fBTcl_RecordAndEvalObj\fR is only called with top-level
+commands typed by the user, since the purpose of history is to
+allow the user to re-issue recently invoked commands.
+If the \fIflags\fR argument contains the \fBTCL_NO_EVAL\fR bit then
+the command is recorded without being evaluated.
+
+.SH "SEE ALSO"
+Tcl_EvalObjEx, Tcl_GetObjResult
+
+.SH KEYWORDS
+command, event, execute, history, interpreter, value, record
diff --git a/doc/RecordEval.3 b/doc/RecordEval.3
new file mode 100644
index 0000000..e1625ff
--- /dev/null
+++ b/doc/RecordEval.3
@@ -0,0 +1,55 @@
+'\"
+'\" Copyright (c) 1989-1993 The Regents of the University of California.
+'\" Copyright (c) 1994-1997 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\" 
+.TH Tcl_RecordAndEval 3 7.4 Tcl "Tcl Library Procedures"
+.so man.macros
+.BS
+.SH NAME
+Tcl_RecordAndEval \- save command on history list before evaluating
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+int
+\fBTcl_RecordAndEval\fR(\fIinterp, cmd, flags\fR)
+.SH ARGUMENTS
+.AS Tcl_Interp *interp
+.AP Tcl_Interp *interp in
+Tcl interpreter in which to evaluate command.
+.AP "const char" *cmd in
+Command (or sequence of commands) to execute.
+.AP int flags in
+An OR'ed combination of flag bits.  \fBTCL_NO_EVAL\fR means record the
+command but do not evaluate it.  \fBTCL_EVAL_GLOBAL\fR means evaluate
+the command at global level instead of the current stack level.
+.BE
+
+.SH DESCRIPTION
+.PP
+\fBTcl_RecordAndEval\fR is invoked to record a command as an event
+on the history list and then execute it using \fBTcl_Eval\fR
+(or \fBTcl_GlobalEval\fR if the \fBTCL_EVAL_GLOBAL\fR bit is set in \fIflags\fR).
+It returns a completion code such as \fBTCL_OK\fR just like \fBTcl_Eval\fR
+and it leaves information in the interpreter's result.
+If you do not want the command recorded on the history list then
+you should invoke \fBTcl_Eval\fR instead of \fBTcl_RecordAndEval\fR.
+Normally \fBTcl_RecordAndEval\fR is only called with top-level
+commands typed by the user, since the purpose of history is to
+allow the user to re-issue recently-invoked commands.
+If the \fIflags\fR argument contains the \fBTCL_NO_EVAL\fR bit then
+the command is recorded without being evaluated.
+.PP
+Note that \fBTcl_RecordAndEval\fR has been largely replaced by the
+value-based procedure \fBTcl_RecordAndEvalObj\fR.
+That value-based procedure records and optionally executes
+a command held in a Tcl value instead of a string.
+
+.SH "SEE ALSO"
+Tcl_RecordAndEvalObj
+
+.SH KEYWORDS
+command, event, execute, history, interpreter, record
diff --git a/doc/RegConfig.3 b/doc/RegConfig.3
new file mode 100644
index 0000000..d73e3d7
--- /dev/null
+++ b/doc/RegConfig.3
@@ -0,0 +1,111 @@
+'\"
+'\" Copyright (c) 2002 Andreas Kupries <andreas_kupries@users.sourceforge.net>
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH Tcl_RegisterConfig 3 8.4 Tcl "Tcl Library Procedures"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+Tcl_RegisterConfig \- procedures to register embedded configuration information
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+void
+\fBTcl_RegisterConfig\fR(\fIinterp, pkgName, configuration, valEncoding\fR)
+.sp
+.SH ARGUMENTS
+.AS Tcl_Interp *configuration
+.AP Tcl_Interp *interp in
+Refers to the interpreter the embedded configuration information is
+registered for. Must not be NULL.
+.AP "const char" *pkgName in
+Contains the name of the package registering the embedded
+configuration as ASCII string. This means that this information is in
+UTF-8 too. Must not be NULL.
+.AP "const Tcl_Config" *configuration in
+Refers to an array of Tcl_Config entries containing the information
+embedded in the binary library. Must not be NULL. The end of the array
+is signaled by either a key identical to NULL, or a key referring to
+the empty string.
+.AP "const char" *valEncoding in
+Contains the name of the encoding used to store the configuration
+values as ASCII string. This means that this information is in UTF-8
+too. Must not be NULL.
+.BE
+.SH DESCRIPTION
+.PP
+The function described here has its base in TIP 59 and provides
+extensions with support for the embedding of configuration
+information into their binary library and the generation of a
+Tcl-level interface for querying this information.
+.PP
+To embed configuration information into their binary library an
+extension has to define a non-volatile array of Tcl_Config entries in
+one if its source files and then call \fBTcl_RegisterConfig\fR to
+register that information.
+.PP
+\fBTcl_RegisterConfig\fR takes four arguments; first, a reference to
+the interpreter we are registering the information with, second, the
+name of the package registering its configuration information, third,
+a pointer to an array of structures, and fourth a string declaring the
+encoding used by the configuration values.
+.PP
+The string \fIvalEncoding\fR contains the name of an encoding known to
+Tcl.  All these names are use only characters in the ASCII subset of
+UTF-8 and are thus implicitly in the UTF-8 encoding. It is expected
+that keys are legible English text and therefore using the ASCII
+subset of UTF-8. In other words, they are expected to be in UTF-8
+too. The values associated with the keys can be any string
+however. For these the contents of \fIvalEncoding\fR define which
+encoding was used to represent the characters of the strings.
+.PP
+Each element of the \fIconfiguration\fR array refers to two strings
+containing the key and the value associated with that key. The end of
+the array is signaled by either an empty key or a key identical to
+NULL. The function makes \fBno\fR copy of the \fIconfiguration\fR
+array. This means that the caller has to make sure that the memory
+holding this array is never released. This is the meaning behind the
+word \fBnon-volatile\fR used earlier. The easiest way to accomplish
+this is to define a global static array of Tcl_Config entries. See the file
+.QW generic/tclPkgConfig.c
+in the sources of the Tcl core for an example.
+.PP
+When called \fBTcl_RegisterConfig\fR will
+.IP (1)
+create a namespace having the provided \fIpkgName\fR, if not yet
+existing.
+.IP (2)
+create the command \fBpkgconfig\fR in that namespace and link it to
+the provided information so that the keys from \fIconfiguration\fR and
+their associated values can be retrieved through calls to
+\fBpkgconfig\fR.
+.PP
+The command \fBpkgconfig\fR will provide two subcommands, \fBlist\fR
+and \fBget\fR:
+.RS
+.TP
+::\fIpkgName\fR::\fBpkgconfig\fR list
+Returns a list containing the names of all defined keys.
+.TP
+::\fIpkgName\fR::\fBpkgconfig\fR get \fIkey\fR
+Returns the configuration value associated with the specified
+\fIkey\fR.
+.RE
+.SH TCL_CONFIG
+.PP
+The \fBTcl_Config\fR structure contains the following fields:
+.PP
+.CS
+typedef struct Tcl_Config {
+    const char *\fIkey\fR;
+    const char *\fIvalue\fR;
+} \fBTcl_Config\fR;
+.CE
+.\" No cross references yet.
+.\" .SH "SEE ALSO"
+.SH KEYWORDS
+embedding, configuration, binary library
diff --git a/doc/RegExp.3 b/doc/RegExp.3
new file mode 100644
index 0000000..aa757bc
--- /dev/null
+++ b/doc/RegExp.3
@@ -0,0 +1,383 @@
+'\"
+'\" Copyright (c) 1994 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\" Copyright (c) 1998-1999 Scriptics Corporation
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH Tcl_RegExpMatch 3 8.1 Tcl "Tcl Library Procedures"
+.so man.macros
+.BS
+.SH NAME
+Tcl_RegExpMatch, Tcl_RegExpCompile, Tcl_RegExpExec, Tcl_RegExpRange, Tcl_GetRegExpFromObj, Tcl_RegExpMatchObj, Tcl_RegExpExecObj, Tcl_RegExpGetInfo \- Pattern matching with regular expressions
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+int
+\fBTcl_RegExpMatchObj\fR(\fIinterp\fR, \fItextObj\fR, \fIpatObj\fR)
+.sp
+int
+\fBTcl_RegExpMatch\fR(\fIinterp\fR, \fItext\fR, \fIpattern\fR)
+.sp
+Tcl_RegExp
+\fBTcl_RegExpCompile\fR(\fIinterp\fR, \fIpattern\fR)
+.sp
+int
+\fBTcl_RegExpExec\fR(\fIinterp\fR, \fIregexp\fR, \fItext\fR, \fIstart\fR)
+.sp
+void
+\fBTcl_RegExpRange\fR(\fIregexp\fR, \fIindex\fR, \fIstartPtr\fR, \fIendPtr\fR)
+.sp
+Tcl_RegExp
+\fBTcl_GetRegExpFromObj\fR(\fIinterp\fR, \fIpatObj\fR, \fIcflags\fR)
+.sp
+int
+\fBTcl_RegExpExecObj\fR(\fIinterp\fR, \fIregexp\fR, \fItextObj\fR, \fIoffset\fR, \fInmatches\fR, \fIeflags\fR)
+.sp
+void
+\fBTcl_RegExpGetInfo\fR(\fIregexp\fR, \fIinfoPtr\fR)
+.fi
+.SH ARGUMENTS
+.AS Tcl_RegExpInfo *interp in/out
+.AP Tcl_Interp *interp in
+Tcl interpreter to use for error reporting.  The interpreter may be
+NULL if no error reporting is desired.
+.AP Tcl_Obj *textObj in/out
+Refers to the value from which to get the text to search.  The
+internal representation of the value may be converted to a form that
+can be efficiently searched.
+.AP Tcl_Obj *patObj in/out
+Refers to the value from which to get a regular expression. The
+compiled regular expression is cached in the value.
+.AP char *text in
+Text to search for a match with a regular expression.
+.AP "const char" *pattern in
+String in the form of a regular expression pattern.
+.AP Tcl_RegExp regexp in
+Compiled regular expression.  Must have been returned previously
+by \fBTcl_GetRegExpFromObj\fR or \fBTcl_RegExpCompile\fR.
+.AP char *start in
+If \fItext\fR is just a portion of some other string, this argument
+identifies the beginning of the larger string.
+If it is not the same as \fItext\fR, then no
+.QW \fB^\fR
+matches will be allowed.
+.AP int index in
+Specifies which range is desired:  0 means the range of the entire
+match, 1 or greater means the range that matched a parenthesized
+sub-expression.
+.AP "const char" **startPtr out
+The address of the first character in the range is stored here, or
+NULL if there is no such range.
+.AP "const char" **endPtr out
+The address of the character just after the last one in the range
+is stored here, or NULL if there is no such range.
+.AP int cflags in
+OR-ed combination of the compilation flags \fBTCL_REG_ADVANCED\fR,
+\fBTCL_REG_EXTENDED\fR, \fBTCL_REG_BASIC\fR, \fBTCL_REG_EXPANDED\fR,
+\fBTCL_REG_QUOTE\fR, \fBTCL_REG_NOCASE\fR, \fBTCL_REG_NEWLINE\fR,
+\fBTCL_REG_NLSTOP\fR, \fBTCL_REG_NLANCH\fR, \fBTCL_REG_NOSUB\fR, and
+\fBTCL_REG_CANMATCH\fR. See below for more information.
+.AP int offset in
+The character offset into the text where matching should begin.
+The value of the offset has no impact on \fB^\fR matches.  This
+behavior is controlled by \fIeflags\fR.
+.AP int nmatches in
+The number of matching subexpressions that should be remembered for
+later use.  If this value is 0, then no subexpression match
+information will be computed.  If the value is \-1, then
+all of the matching subexpressions will be remembered.  Any other
+value will be taken as the maximum number of subexpressions to
+remember.
+.AP int eflags in
+OR-ed combination of the execution flags \fBTCL_REG_NOTBOL\fR and
+\fBTCL_REG_NOTEOL\fR. See below for more information.
+.AP Tcl_RegExpInfo *infoPtr out
+The address of the location where information about a previous match
+should be stored by \fBTcl_RegExpGetInfo\fR.
+.BE
+.SH DESCRIPTION
+.PP
+\fBTcl_RegExpMatch\fR determines whether its \fIpattern\fR argument
+matches \fIregexp\fR, where \fIregexp\fR is interpreted
+as a regular expression using the rules in the \fBre_syntax\fR
+reference page.
+If there is a match then \fBTcl_RegExpMatch\fR returns 1.
+If there is no match then \fBTcl_RegExpMatch\fR returns 0.
+If an error occurs in the matching process (e.g. \fIpattern\fR
+is not a valid regular expression) then \fBTcl_RegExpMatch\fR
+returns \-1 and leaves an error message in the interpreter result.
+\fBTcl_RegExpMatchObj\fR is similar to \fBTcl_RegExpMatch\fR except it
+operates on the Tcl values \fItextObj\fR and \fIpatObj\fR instead of
+UTF strings.
+\fBTcl_RegExpMatchObj\fR is generally more efficient than
+\fBTcl_RegExpMatch\fR, so it is the preferred interface.
+.PP
+\fBTcl_RegExpCompile\fR, \fBTcl_RegExpExec\fR, and \fBTcl_RegExpRange\fR
+provide lower-level access to the regular expression pattern matcher.
+\fBTcl_RegExpCompile\fR compiles a regular expression string into
+the internal form used for efficient pattern matching.
+The return value is a token for this compiled form, which can be
+used in subsequent calls to \fBTcl_RegExpExec\fR or \fBTcl_RegExpRange\fR.
+If an error occurs while compiling the regular expression then
+\fBTcl_RegExpCompile\fR returns NULL and leaves an error message
+in the interpreter result.
+Note:  the return value from \fBTcl_RegExpCompile\fR is only valid
+up to the next call to \fBTcl_RegExpCompile\fR;  it is not safe to
+retain these values for long periods of time.
+.PP
+\fBTcl_RegExpExec\fR executes the regular expression pattern matcher.
+It returns 1 if \fItext\fR contains a range of characters that
+match \fIregexp\fR, 0 if no match is found, and
+\-1 if an error occurs.
+In the case of an error, \fBTcl_RegExpExec\fR leaves an error
+message in the interpreter result.
+When searching a string for multiple matches of a pattern,
+it is important to distinguish between the start of the original
+string and the start of the current search.
+For example, when searching for the second occurrence of a
+match, the \fItext\fR argument might point to the character
+just after the first match;  however, it is important for the
+pattern matcher to know that this is not the start of the entire string,
+so that it does not allow
+.QW \fB^\fR
+atoms in the pattern to match.
+The \fIstart\fR argument provides this information by pointing
+to the start of the overall string containing \fItext\fR.
+\fIStart\fR will be less than or equal to \fItext\fR;  if it
+is less than \fItext\fR then no \fB^\fR matches will be allowed.
+.PP
+\fBTcl_RegExpRange\fR may be invoked after \fBTcl_RegExpExec\fR
+returns;  it provides detailed information about what ranges of
+the string matched what parts of the pattern.
+\fBTcl_RegExpRange\fR returns a pair of pointers in \fI*startPtr\fR
+and \fI*endPtr\fR that identify a range of characters in
+the source string for the most recent call to \fBTcl_RegExpExec\fR.
+\fIIndex\fR indicates which of several ranges is desired:
+if \fIindex\fR is 0, information is returned about the overall range
+of characters that matched the entire pattern;  otherwise,
+information is returned about the range of characters that matched the
+\fIindex\fR'th parenthesized subexpression within the pattern.
+If there is no range corresponding to \fIindex\fR then NULL
+is stored in \fI*startPtr\fR and \fI*endPtr\fR.
+.PP
+\fBTcl_GetRegExpFromObj\fR, \fBTcl_RegExpExecObj\fR, and
+\fBTcl_RegExpGetInfo\fR are value interfaces that provide the most
+direct control of Henry Spencer's regular expression library.  For
+users that need to modify compilation and execution options directly,
+it is recommended that you use these interfaces instead of calling the
+internal regexp functions.  These interfaces handle the details of UTF
+to Unicode translations as well as providing improved performance
+through caching in the pattern and string values.
+.PP
+\fBTcl_GetRegExpFromObj\fR attempts to return a compiled regular
+expression from the \fIpatObj\fR.  If the value does not already
+contain a compiled regular expression it will attempt to create one
+from the string in the value and assign it to the internal
+representation of the \fIpatObj\fR.  The return value of this function
+is of type \fBTcl_RegExp\fR.  The return value is a token for this
+compiled form, which can be used in subsequent calls to
+\fBTcl_RegExpExecObj\fR or \fBTcl_RegExpGetInfo\fR.  If an error
+occurs while compiling the regular expression then
+\fBTcl_GetRegExpFromObj\fR returns NULL and leaves an error message in
+the interpreter result.  The regular expression token can be used as
+long as the internal representation of \fIpatObj\fR refers to the
+compiled form.  The \fIcflags\fR argument is a bit-wise OR of
+zero or more of the following flags that control the compilation of
+\fIpatObj\fR:
+.RS 2
+.TP
+\fBTCL_REG_ADVANCED\fR
+Compile advanced regular expressions
+.PQ ARE s .
+This mode corresponds to
+the normal regular expression syntax accepted by the Tcl \fBregexp\fR and
+\fBregsub\fR commands.
+.TP
+\fBTCL_REG_EXTENDED\fR
+Compile extended regular expressions
+.PQ ERE s .
+This mode corresponds
+to the regular expression syntax recognized by Tcl 8.0 and earlier
+versions.
+.TP
+\fBTCL_REG_BASIC\fR
+Compile basic regular expressions
+.PQ BRE s .
+This mode corresponds
+to the regular expression syntax recognized by common Unix utilities
+like \fBsed\fR and \fBgrep\fR.  This is the default if no flags are
+specified.
+.TP
+\fBTCL_REG_EXPANDED\fR
+Compile the regular expression (basic, extended, or advanced) using an
+expanded syntax that allows comments and whitespace.  This mode causes
+non-backslashed non-bracket-expression white
+space and #-to-end-of-line comments to be ignored.
+.TP
+\fBTCL_REG_QUOTE\fR
+Compile a literal string, with all characters treated as ordinary characters.
+.TP
+\fBTCL_REG_NOCASE\fR
+Compile for matching that ignores upper/lower case distinctions.
+.TP
+\fBTCL_REG_NEWLINE\fR
+Compile for newline-sensitive matching.  By default, newline is a
+completely ordinary character with no special meaning in either
+regular expressions or strings.  With this flag,
+.QW [^
+bracket expressions and
+.QW .
+never match newline,
+.QW ^
+matches an empty string
+after any newline in addition to its normal function, and
+.QW $
+matches
+an empty string before any newline in addition to its normal function.
+\fBREG_NEWLINE\fR is the bit-wise OR of \fBREG_NLSTOP\fR and
+\fBREG_NLANCH\fR.
+.TP
+\fBTCL_REG_NLSTOP\fR
+Compile for partial newline-sensitive matching,
+with the behavior of
+.QW [^
+bracket expressions and
+.QW .
+affected, but not the behavior of
+.QW ^
+and
+.QW $ .
+In this mode,
+.QW [^
+bracket expressions and
+.QW .
+never match newline.
+.TP
+\fBTCL_REG_NLANCH\fR
+Compile for inverse partial newline-sensitive matching,
+with the behavior of
+.QW ^
+and
+.QW $
+(the
+.QW anchors )
+affected, but not the behavior of
+.QW [^
+bracket expressions and
+.QW . .
+In this mode
+.QW ^
+matches an empty string
+after any newline in addition to its normal function, and
+.QW $
+matches
+an empty string before any newline in addition to its normal function.
+.TP
+\fBTCL_REG_NOSUB\fR
+Compile for matching that reports only success or failure,
+not what was matched.  This reduces compile overhead and may improve
+performance.  Subsequent calls to \fBTcl_RegExpGetInfo\fR or
+\fBTcl_RegExpRange\fR will not report any match information.
+.TP
+\fBTCL_REG_CANMATCH\fR
+Compile for matching that reports the potential to complete a partial
+match given more text (see below).
+.RE
+.PP
+Only one of
+\fBTCL_REG_EXTENDED\fR,
+\fBTCL_REG_ADVANCED\fR,
+\fBTCL_REG_BASIC\fR, and
+\fBTCL_REG_QUOTE\fR may be specified.
+.PP
+\fBTcl_RegExpExecObj\fR executes the regular expression pattern
+matcher.  It returns 1 if \fIobjPtr\fR contains a range of characters
+that match \fIregexp\fR, 0 if no match is found, and \-1 if an error
+occurs.  In the case of an error, \fBTcl_RegExpExecObj\fR leaves an
+error message in the interpreter result.  The \fInmatches\fR value
+indicates to the matcher how many subexpressions are of interest.  If
+\fInmatches\fR is 0, then no subexpression match information is
+recorded, which may allow the matcher to make various optimizations.
+If the value is \-1, then all of the subexpressions in the pattern are
+remembered.  If the value is a positive integer, then only that number
+of subexpressions will be remembered.  Matching begins at the
+specified Unicode character index given by \fIoffset\fR.  Unlike
+\fBTcl_RegExpExec\fR, the behavior of anchors is not affected by the
+offset value.  Instead the behavior of the anchors is explicitly
+controlled by the \fIeflags\fR argument, which is a bit-wise OR of
+zero or more of the following flags:
+.RS 2
+.TP
+\fBTCL_REG_NOTBOL\fR
+The starting character will not be treated as the beginning of a
+line or the beginning of the string, so
+.QW ^
+will not match there.
+Note that this flag has no effect on how
+.QW \fB\eA\fR
+matches.
+.TP
+\fBTCL_REG_NOTEOL\fR
+The last character in the string will not be treated as the end of a
+line or the end of the string, so
+.QW $
+will not match there.
+Note that this flag has no effect on how
+.QW \fB\eZ\fR
+matches.
+.RE
+.PP
+\fBTcl_RegExpGetInfo\fR retrieves information about the last match
+performed with a given regular expression \fIregexp\fR.  The
+\fIinfoPtr\fR argument contains a pointer to a structure that is
+defined as follows:
+.PP
+.CS
+typedef struct Tcl_RegExpInfo {
+    int \fInsubs\fR;
+    Tcl_RegExpIndices *\fImatches\fR;
+    long \fIextendStart\fR;
+} \fBTcl_RegExpInfo\fR;
+.CE
+.PP
+The \fInsubs\fR field contains a count of the number of parenthesized
+subexpressions within the regular expression.  If the \fBTCL_REG_NOSUB\fR
+was used, then this value will be zero.  The \fImatches\fR field
+points to an array of \fInsubs\fR+1 values that indicate the bounds of each
+subexpression matched.  The first element in the array refers to the
+range matched by the entire regular expression, and subsequent elements
+refer to the parenthesized subexpressions in the order that they
+appear in the pattern.  Each element is a structure that is defined as
+follows:
+.PP
+.CS
+typedef struct Tcl_RegExpIndices {
+    long \fIstart\fR;
+    long \fIend\fR;
+} \fBTcl_RegExpIndices\fR;
+.CE
+.PP
+The \fIstart\fR and \fIend\fR values are Unicode character indices
+relative to the offset location within \fIobjPtr\fR where matching began.
+The \fIstart\fR index identifies the first character of the matched
+subexpression.  The \fIend\fR index identifies the first character
+after the matched subexpression.  If the subexpression matched the
+empty string, then \fIstart\fR and \fIend\fR will be equal.  If the
+subexpression did not participate in the match, then \fIstart\fR and
+\fIend\fR will be set to \-1.
+.PP
+The \fIextendStart\fR field in \fBTcl_RegExpInfo\fR is only set if the
+\fBTCL_REG_CANMATCH\fR flag was used.  It indicates the first
+character in the string where a match could occur.  If a match was
+found, this will be the same as the beginning of the current match.
+If no match was found, then it indicates the earliest point at which a
+match might occur if additional text is appended to the string.  If it
+is no match is possible even with further text, this field will be set
+to \-1.
+.SH "SEE ALSO"
+re_syntax(n)
+.SH KEYWORDS
+match, pattern, regular expression, string, subexpression, Tcl_RegExpIndices, Tcl_RegExpInfo
diff --git a/doc/SaveResult.3 b/doc/SaveResult.3
new file mode 100644
index 0000000..b2270a2
--- /dev/null
+++ b/doc/SaveResult.3
@@ -0,0 +1,120 @@
+'\"
+'\" Copyright (c) 1997 by Sun Microsystems, Inc.
+'\" Contributions from Don Porter, NIST, 2004. (not subject to US copyright)
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH Tcl_SaveResult 3 8.1 Tcl "Tcl Library Procedures"
+.so man.macros
+.BS
+.SH NAME
+Tcl_SaveInterpState, Tcl_RestoreInterpState, Tcl_DiscardInterpState, Tcl_SaveResult, Tcl_RestoreResult, Tcl_DiscardResult \- save and restore an interpreter's state
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+Tcl_InterpState
+\fBTcl_SaveInterpState\fR(\fIinterp, status\fR)
+.sp
+int
+\fBTcl_RestoreInterpState\fR(\fIinterp, state\fR)
+.sp
+\fBTcl_DiscardInterpState\fR(\fIstate\fR)
+.sp
+\fBTcl_SaveResult\fR(\fIinterp, savedPtr\fR)
+.sp
+\fBTcl_RestoreResult\fR(\fIinterp, savedPtr\fR)
+.sp
+\fBTcl_DiscardResult\fR(\fIsavedPtr\fR)
+.SH ARGUMENTS
+.AS Tcl_InterpState savedPtr
+.AP Tcl_Interp *interp in
+Interpreter for which state should be saved.
+.AP int status in
+Return code value to save as part of interpreter state.
+.AP Tcl_InterpState state in
+Saved state token to be restored or discarded.
+.AP Tcl_SavedResult *savedPtr in
+Pointer to location where interpreter result should be saved or restored.
+.BE
+.SH DESCRIPTION
+.PP
+These routines allows a C procedure to take a snapshot of the current
+state of an interpreter so that it can be restored after a call
+to \fBTcl_Eval\fR or some other routine that modifies the interpreter
+state.  There are two triplets of routines meant to work together.
+.PP
+The first triplet stores the snapshot of interpreter state in
+an opaque token returned by \fBTcl_SaveInterpState\fR.  That token
+value may then be passed back to one of \fBTcl_RestoreInterpState\fR
+or \fBTcl_DiscardInterpState\fR, depending on whether the interp
+state is to be restored.  So long as one of the latter two routines
+is called, Tcl will take care of memory management.
+.PP
+The second triplet stores the snapshot of only the interpreter
+result (not its complete state) in memory allocated by the caller.
+These routines are passed a pointer to a \fBTcl_SavedResult\fR structure
+that is used to store enough information to restore the interpreter result.
+This structure can be allocated on the stack of the calling
+procedure.  These routines do not save the state of any error
+information in the interpreter (e.g. the \fB\-errorcode\fR or
+\fB\-errorinfo\fR return options, when an error is in progress).
+.PP
+Because the routines \fBTcl_SaveInterpState\fR,
+\fBTcl_RestoreInterpState\fR, and \fBTcl_DiscardInterpState\fR perform
+a superset of the functions provided by the other routines,
+any new code should only make use of the more powerful routines.
+The older, weaker routines \fBTcl_SaveResult\fR, \fBTcl_RestoreResult\fR,
+and \fBTcl_DiscardResult\fR continue to exist only for the sake
+of existing programs that may already be using them.
+.PP
+\fBTcl_SaveInterpState\fR takes a snapshot of those portions of
+interpreter state that make up the full result of script evaluation.
+This include the interpreter result, the return code (passed in
+as the \fIstatus\fR argument, and any return options, including
+\fB\-errorinfo\fR and \fB\-errorcode\fR when an error is in progress.
+This snapshot is returned as an opaque token of type \fBTcl_InterpState\fR.
+The call to \fBTcl_SaveInterpState\fR does not itself change the
+state of the interpreter.  Unlike \fBTcl_SaveResult\fR, it does
+not reset the interpreter.
+.PP
+\fBTcl_RestoreInterpState\fR accepts a \fBTcl_InterpState\fR token
+previously returned by \fBTcl_SaveInterpState\fR and restores the
+state of the interp to the state held in that snapshot.  The return
+value of \fBTcl_RestoreInterpState\fR is the status value originally
+passed to \fBTcl_SaveInterpState\fR when the snapshot token was
+created.
+.PP
+\fBTcl_DiscardInterpState\fR is called to release a \fBTcl_InterpState\fR
+token previously returned by \fBTcl_SaveInterpState\fR when that
+snapshot is not to be restored to an interp.
+.PP
+The \fBTcl_InterpState\fR token returned by \fBTcl_SaveInterpState\fR
+must eventually be passed to either \fBTcl_RestoreInterpState\fR
+or \fBTcl_DiscardInterpState\fR to avoid a memory leak.  Once
+the \fBTcl_InterpState\fR token is passed to one of them, the
+token is no longer valid and should not be used anymore.
+.PP
+\fBTcl_SaveResult\fR moves the string and value results
+of \fIinterp\fR into the location specified by \fIstatePtr\fR.
+\fBTcl_SaveResult\fR clears the result for \fIinterp\fR and
+leaves the result in its normal empty initialized state.
+.PP
+\fBTcl_RestoreResult\fR moves the string and value results from
+\fIstatePtr\fR back into \fIinterp\fR.  Any result or error that was
+already in the interpreter will be cleared.  The \fIstatePtr\fR is left
+in an uninitialized state and cannot be used until another call to
+\fBTcl_SaveResult\fR.
+.PP
+\fBTcl_DiscardResult\fR releases the saved interpreter state
+stored at \fBstatePtr\fR.  The state structure is left in an
+uninitialized state and cannot be used until another call to
+\fBTcl_SaveResult\fR.
+.PP
+Once \fBTcl_SaveResult\fR is called to save the interpreter
+result, either \fBTcl_RestoreResult\fR or
+\fBTcl_DiscardResult\fR must be called to properly clean up the
+memory associated with the saved state.
+.SH KEYWORDS
+result, state, interp
diff --git a/doc/SetChanErr.3 b/doc/SetChanErr.3
new file mode 100644
index 0000000..5bb86be
--- /dev/null
+++ b/doc/SetChanErr.3
@@ -0,0 +1,140 @@
+'\"
+'\" Copyright (c) 2005 Andreas Kupries <andreas_kupries@users.sourceforge.net>
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH Tcl_SetChannelError 3 8.5 Tcl "Tcl Library Procedures"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+Tcl_SetChannelError, Tcl_SetChannelErrorInterp, Tcl_GetChannelError, Tcl_GetChannelErrorInterp \- functions to create/intercept Tcl errors by channel drivers.
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+void
+\fBTcl_SetChannelError\fR(\fIchan, msg\fR)
+.sp
+void
+\fBTcl_SetChannelErrorInterp\fR(\fIinterp, msg\fR)
+.sp
+void
+\fBTcl_GetChannelError\fR(\fIchan, msgPtr\fR)
+.sp
+void
+\fBTcl_GetChannelErrorInterp\fR(\fIinterp, msgPtr\fR)
+.sp
+.SH ARGUMENTS
+.AS Tcl_Channel chan
+.AP Tcl_Channel chan in
+Refers to the Tcl channel whose bypass area is accessed.
+.AP Tcl_Interp* interp in
+Refers to the Tcl interpreter whose bypass area is accessed.
+.AP Tcl_Obj* msg in
+Error message put into a bypass area. A list of return options and values,
+followed by a string message. Both message and the option/value information
+are optional.
+.AP Tcl_Obj** msgPtr out
+Reference to a place where the message stored in the accessed bypass area can
+be stored in.
+.BE
+.SH DESCRIPTION
+.PP
+The current definition of a Tcl channel driver does not permit the direct
+return of arbitrary error messages, except for the setting and retrieval of
+channel options. All other functions are restricted to POSIX error codes.
+.PP
+The functions described here overcome this limitation. Channel drivers are
+allowed to use \fBTcl_SetChannelError\fR and \fBTcl_SetChannelErrorInterp\fR
+to place arbitrary error messages in \fBbypass areas\fR defined for channels
+and interpreters. And the generic I/O layer uses \fBTcl_GetChannelError\fR and
+\fBTcl_GetChannelErrorInterp\fR to look for messages in the bypass areas and
+arrange for their return as errors. The POSIX error codes set by a driver are
+used now if and only if no messages are present.
+.PP
+\fBTcl_SetChannelError\fR stores error information in the bypass area of the
+specified channel. The number of references to the \fBmsg\fR value goes up by
+one. Previously stored information will be discarded, by releasing the
+reference held by the channel. The channel reference must not be NULL.
+.PP
+\fBTcl_SetChannelErrorInterp\fR stores error information in the bypass area of
+the specified interpreter. The number of references to the \fBmsg\fR value
+goes up by one. Previously stored information will be discarded, by releasing
+the reference held by the interpreter. The interpreter reference must not be
+NULL.
+.PP
+\fBTcl_GetChannelError\fR places either the error message held in the bypass
+area of the specified channel into \fImsgPtr\fR, or NULL; and resets the
+bypass, that is, after an invocation all following invocations will return
+NULL, until an intervening invocation of \fBTcl_SetChannelError\fR with a
+non-NULL message. The \fImsgPtr\fR must not be NULL. The reference count of
+the message is not touched.  The reference previously held by the channel is
+now held by the caller of the function and it is its responsibility to release
+that reference when it is done with the value.
+.PP
+\fBTcl_GetChannelErrorInterp\fR places either the error message held in the
+bypass area of the specified interpreter into \fImsgPtr\fR, or NULL; and
+resets the bypass, that is, after an invocation all following invocations will
+return NULL, until an intervening invocation of
+\fBTcl_SetChannelErrorInterp\fR with a non-NULL message. The \fImsgPtr\fR must
+not be NULL. The reference count of the message is not touched.  The reference
+previously held by the interpreter is now held by the caller of the function
+and it is its responsibility to release that reference when it is done with
+the value.
+.PP
+Which functions of a channel driver are allowed to use which bypass function
+is listed below, as is which functions of the public channel API may leave a
+messages in the bypass areas.
+.IP \fBTcl_DriverCloseProc\fR
+May use \fBTcl_SetChannelErrorInterp\fR, and only this function.
+.IP \fBTcl_DriverInputProc\fR
+May use \fBTcl_SetChannelError\fR, and only this function.
+.IP \fBTcl_DriverOutputProc\fR
+May use \fBTcl_SetChannelError\fR, and only this function.
+.IP \fBTcl_DriverSeekProc\fR
+May use \fBTcl_SetChannelError\fR, and only this function.
+.IP \fBTcl_DriverWideSeekProc\fR
+May use \fBTcl_SetChannelError\fR, and only this function.
+.IP \fBTcl_DriverSetOptionProc\fR
+Has already the ability to pass arbitrary error messages. Must \fInot\fR use
+any of the new functions.
+.IP \fBTcl_DriverGetOptionProc\fR
+Has already the ability to pass arbitrary error messages. Must
+\fInot\fR use any of the new functions.
+.IP \fBTcl_DriverWatchProc\fR
+Must \fInot\fR use any of the new functions. Is internally called and has no
+ability to return any type of error whatsoever.
+.IP \fBTcl_DriverBlockModeProc\fR
+May use \fBTcl_SetChannelError\fR, and only this function.
+.IP \fBTcl_DriverGetHandleProc\fR
+Must \fInot\fR use any of the new functions. It is only a low-level function,
+and not used by Tcl commands.
+.IP \fBTcl_DriverHandlerProc\fR
+Must \fInot\fR use any of the new functions. Is internally called and has no
+ability to return any type of error whatsoever.
+.PP
+Given the information above the following public functions of the Tcl C API
+are affected by these changes; when these functions are called, the channel
+may now contain a stored arbitrary error message requiring processing by the
+caller.
+.DS
+.ta 1.9i 4i
+\fBTcl_Flush\fR	\fBTcl_GetsObj\fR	\fBTcl_Gets\fR
+\fBTcl_ReadChars\fR	\fBTcl_ReadRaw\fR	\fBTcl_Read\fR
+\fBTcl_Seek\fR	\fBTcl_StackChannel\fR	\fBTcl_Tell\fR
+\fBTcl_WriteChars\fR	\fBTcl_WriteObj\fR	\fBTcl_WriteRaw\fR
+\fBTcl_Write\fR
+.DE
+.PP
+All other API functions are unchanged. In particular, the functions below
+leave all their error information in the interpreter result.
+.DS
+.ta 1.9i 4i
+\fBTcl_Close\fR	\fBTcl_UnstackChannel\fR	\fBTcl_UnregisterChannel\fR
+.DE
+.SH "SEE ALSO"
+Tcl_Close(3), Tcl_OpenFileChannel(3), Tcl_SetErrno(3)
+.SH KEYWORDS
+channel driver, error messages, channel type
diff --git a/doc/SetErrno.3 b/doc/SetErrno.3
new file mode 100644
index 0000000..21648b1
--- /dev/null
+++ b/doc/SetErrno.3
@@ -0,0 +1,66 @@
+'\"
+'\" Copyright (c) 1996 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\" 
+.TH Tcl_SetErrno 3 8.3 Tcl "Tcl Library Procedures"
+.so man.macros
+.BS
+.SH NAME
+Tcl_SetErrno, Tcl_GetErrno, Tcl_ErrnoId, Tcl_ErrnoMsg \- manipulate errno to store and retrieve error codes
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+void
+\fBTcl_SetErrno\fR(\fIerrorCode\fR)
+.sp
+int
+\fBTcl_GetErrno\fR()
+.sp
+const char *
+\fBTcl_ErrnoId\fR()
+.sp
+const char *
+\fBTcl_ErrnoMsg\fR(\fIerrorCode\fR)
+.sp
+.SH ARGUMENTS
+.AS int errorCode
+.AP int errorCode in
+A POSIX error code such as \fBENOENT\fR.
+.BE
+
+.SH DESCRIPTION
+.PP
+\fBTcl_SetErrno\fR and \fBTcl_GetErrno\fR provide portable access
+to the \fBerrno\fR variable, which is used to record a POSIX error
+code after system calls and other operations such as \fBTcl_Gets\fR.
+These procedures are necessary because global variable accesses cannot
+be made across module boundaries on some platforms.
+.PP
+\fBTcl_SetErrno\fR sets the \fBerrno\fR variable to the value of the
+\fIerrorCode\fR argument
+C procedures that wish to return error information to their callers
+via \fBerrno\fR should call \fBTcl_SetErrno\fR rather than setting
+\fBerrno\fR directly.
+.PP
+\fBTcl_GetErrno\fR returns the current value of \fBerrno\fR.
+Procedures wishing to access \fBerrno\fR should call this procedure
+instead of accessing \fBerrno\fR directly.
+.PP
+\fBTcl_ErrnoId\fR and \fBTcl_ErrnoMsg\fR return string
+representations of \fBerrno\fR values.  \fBTcl_ErrnoId\fR
+returns a machine-readable textual identifier such as
+.QW EACCES
+that corresponds to the current value of \fBerrno\fR.
+\fBTcl_ErrnoMsg\fR returns a human-readable string such as
+.QW "permission denied"
+that corresponds to the value of its
+\fIerrorCode\fR argument.  The \fIerrorCode\fR argument is
+typically the value returned by \fBTcl_GetErrno\fR.
+The strings returned by these functions are
+statically allocated and the caller must not free or modify them.
+
+.SH KEYWORDS
+errno, error code, global variables
diff --git a/doc/SetRecLmt.3 b/doc/SetRecLmt.3
new file mode 100644
index 0000000..904d4ab
--- /dev/null
+++ b/doc/SetRecLmt.3
@@ -0,0 +1,53 @@
+'\"
+'\" Copyright (c) 1989-1993 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\" 
+.TH Tcl_SetRecursionLimit 3 7.0 Tcl "Tcl Library Procedures"
+.so man.macros
+.BS
+.SH NAME
+Tcl_SetRecursionLimit \- set maximum allowable nesting depth in interpreter
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+int
+\fBTcl_SetRecursionLimit\fR(\fIinterp, depth\fR)
+.SH ARGUMENTS
+.AS Tcl_Interp *interp
+.AP Tcl_Interp *interp in
+Interpreter whose recursion limit is to be set.
+Must be greater than zero.
+.AP int depth in
+New limit for nested calls to \fBTcl_Eval\fR for \fIinterp\fR.
+.BE
+
+.SH DESCRIPTION
+.PP
+At any given time Tcl enforces a limit on the number of recursive
+calls that may be active for \fBTcl_Eval\fR and related procedures
+such as \fBTcl_GlobalEval\fR.
+Any call to \fBTcl_Eval\fR that exceeds this depth is aborted with
+an error.
+By default the recursion limit is 1000.
+.PP
+\fBTcl_SetRecursionLimit\fR may be used to change the maximum
+allowable nesting depth for an interpreter.
+The \fIdepth\fR argument specifies a new limit for \fIinterp\fR,
+and \fBTcl_SetRecursionLimit\fR returns the old limit.
+To read out the old limit without modifying it, invoke
+\fBTcl_SetRecursionLimit\fR with \fIdepth\fR equal to 0.
+.PP
+The \fBTcl_SetRecursionLimit\fR only sets the size of the Tcl
+call stack:  it cannot by itself prevent stack overflows on the
+C stack being used by the application.  If your machine has a
+limit on the size of the C stack, you may get stack overflows
+before reaching the limit set by \fBTcl_SetRecursionLimit\fR.
+If this happens, see if there is a mechanism in your system for
+increasing the maximum size of the C stack.
+
+.SH KEYWORDS
+nesting depth, recursion
diff --git a/doc/SetResult.3 b/doc/SetResult.3
new file mode 100644
index 0000000..e5b81d7
--- /dev/null
+++ b/doc/SetResult.3
@@ -0,0 +1,255 @@
+'\"
+'\" Copyright (c) 1989-1993 The Regents of the University of California.
+'\" Copyright (c) 1994-1997 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH Tcl_SetResult 3 8.0 Tcl "Tcl Library Procedures"
+.so man.macros
+.BS
+.SH NAME
+Tcl_SetObjResult, Tcl_GetObjResult, Tcl_SetResult, Tcl_GetStringResult, Tcl_AppendResult, Tcl_AppendResultVA, Tcl_AppendElement, Tcl_ResetResult, Tcl_TransferResult, Tcl_FreeResult \- manipulate Tcl result
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+\fBTcl_SetObjResult\fR(\fIinterp, objPtr\fR)
+.sp
+Tcl_Obj *
+\fBTcl_GetObjResult\fR(\fIinterp\fR)
+.sp
+\fBTcl_SetResult\fR(\fIinterp, result, freeProc\fR)
+.sp
+const char *
+\fBTcl_GetStringResult\fR(\fIinterp\fR)
+.sp
+\fBTcl_AppendResult\fR(\fIinterp, result, result, ... , \fB(char *) NULL\fR)
+.sp
+\fBTcl_AppendResultVA\fR(\fIinterp, argList\fR)
+.sp
+\fBTcl_ResetResult\fR(\fIinterp\fR)
+.sp
+.VS 8.6
+\fBTcl_TransferResult\fR(\fIsourceInterp, result, targetInterp\fR)
+.VE 8.6
+.sp
+\fBTcl_AppendElement\fR(\fIinterp, element\fR)
+.sp
+\fBTcl_FreeResult\fR(\fIinterp\fR)
+.SH ARGUMENTS
+.AS Tcl_FreeProc sourceInterp out
+.AP Tcl_Interp *interp out
+Interpreter whose result is to be modified or read.
+.AP Tcl_Obj *objPtr in
+Tcl value to become result for \fIinterp\fR.
+.AP char *result in
+String value to become result for \fIinterp\fR or to be
+appended to the existing result.
+.AP "const char" *element in
+String value to append as a list element
+to the existing result of \fIinterp\fR.
+.AP Tcl_FreeProc *freeProc in
+Address of procedure to call to release storage at
+\fIresult\fR, or \fBTCL_STATIC\fR, \fBTCL_DYNAMIC\fR, or
+\fBTCL_VOLATILE\fR.
+.AP va_list argList in
+An argument list which must have been initialized using
+\fBva_start\fR, and cleared using \fBva_end\fR.
+.AP Tcl_Interp *sourceInterp in
+.VS 8.6
+Interpreter that the result and error information should be copied from.
+.VE 8.6
+.AP Tcl_Interp *targetInterp in
+.VS 8.6
+Interpreter that the result and error information should be copied to.
+.VE 8.6
+.AP int result in
+.VS 8.6
+If \fBTCL_OK\fR, only copy the result. If \fBTCL_ERROR\fR, copy the error
+information as well.
+.VE 8.6
+.BE
+.SH DESCRIPTION
+.PP
+The procedures described here are utilities for manipulating the
+result value in a Tcl interpreter.
+The interpreter result may be either a Tcl value or a string.
+For example, \fBTcl_SetObjResult\fR and \fBTcl_SetResult\fR
+set the interpreter result to, respectively, a value and a string.
+Similarly, \fBTcl_GetObjResult\fR and \fBTcl_GetStringResult\fR
+return the interpreter result as a value and as a string.
+The procedures always keep the string and value forms
+of the interpreter result consistent.
+For example, if \fBTcl_SetObjResult\fR is called to set
+the result to a value,
+then \fBTcl_GetStringResult\fR is called,
+it will return the value's string representation.
+.PP
+\fBTcl_SetObjResult\fR
+arranges for \fIobjPtr\fR to be the result for \fIinterp\fR,
+replacing any existing result.
+The result is left pointing to the value
+referenced by \fIobjPtr\fR.
+\fIobjPtr\fR's reference count is incremented
+since there is now a new reference to it from \fIinterp\fR.
+The reference count for any old result value
+is decremented and the old result value is freed if no
+references to it remain.
+.PP
+\fBTcl_GetObjResult\fR returns the result for \fIinterp\fR as a value.
+The value's reference count is not incremented;
+if the caller needs to retain a long-term pointer to the value
+they should use \fBTcl_IncrRefCount\fR to increment its reference count
+in order to keep it from being freed too early or accidentally changed.
+.PP
+\fBTcl_SetResult\fR
+arranges for \fIresult\fR to be the result for the current Tcl
+command in \fIinterp\fR, replacing any existing result.
+The \fIfreeProc\fR argument specifies how to manage the storage
+for the \fIresult\fR argument;
+it is discussed in the section
+\fBTHE TCL_FREEPROC ARGUMENT TO TCL_SETRESULT\fR below.
+If \fIresult\fR is \fBNULL\fR, then \fIfreeProc\fR is ignored
+and \fBTcl_SetResult\fR
+re-initializes \fIinterp\fR's result to point to an empty string.
+.PP
+\fBTcl_GetStringResult\fR returns the result for \fIinterp\fR as a string.
+If the result was set to a value by a \fBTcl_SetObjResult\fR call,
+the value form will be converted to a string and returned.
+If the value's string representation contains null bytes,
+this conversion will lose information.
+For this reason, programmers are encouraged to
+write their code to use the new value API procedures
+and to call \fBTcl_GetObjResult\fR instead.
+.PP
+\fBTcl_ResetResult\fR clears the result for \fIinterp\fR
+and leaves the result in its normal empty initialized state.
+If the result is a value,
+its reference count is decremented and the result is left
+pointing to an unshared value representing an empty string.
+If the result is a dynamically allocated string, its memory is free*d
+and the result is left as a empty string.
+\fBTcl_ResetResult\fR also clears the error state managed by
+\fBTcl_AddErrorInfo\fR, \fBTcl_AddObjErrorInfo\fR,
+and \fBTcl_SetErrorCode\fR.
+.PP
+\fBTcl_AppendResult\fR makes it easy to build up Tcl results in pieces.
+It takes each of its \fIresult\fR arguments and appends them in order
+to the current result associated with \fIinterp\fR.
+If the result is in its initialized empty state (e.g. a command procedure
+was just invoked or \fBTcl_ResetResult\fR was just called),
+then \fBTcl_AppendResult\fR sets the result to the concatenation of
+its \fIresult\fR arguments.
+\fBTcl_AppendResult\fR may be called repeatedly as additional pieces
+of the result are produced.
+\fBTcl_AppendResult\fR takes care of all the
+storage management issues associated with managing \fIinterp\fR's
+result, such as allocating a larger result area if necessary.
+It also manages conversion to and from the \fIresult\fR field of the
+\fIinterp\fR so as to handle backward-compatibility with old-style
+extensions.
+Any number of \fIresult\fR arguments may be passed in a single
+call; the last argument in the list must be a NULL pointer.
+.PP
+\fBTcl_AppendResultVA\fR is the same as \fBTcl_AppendResult\fR except that
+instead of taking a variable number of arguments it takes an argument list.
+.PP
+.VS 8.6
+\fBTcl_TransferResult\fR moves a result from one interpreter to another,
+optionally (dependent on the \fIresult\fR parameter) including the error
+information dictionary as well. The interpreters must be in the same thread.
+The source interpreter will have its result reset by this operation.
+.VE 8.6
+.SH "DEPRECATED INTERFACES"
+.SS "OLD STRING PROCEDURES"
+.PP
+Use of the following procedures is deprecated
+since they manipulate the Tcl result as a string.
+Procedures such as \fBTcl_SetObjResult\fR
+that manipulate the result as a value
+can be significantly more efficient.
+.PP
+\fBTcl_AppendElement\fR is similar to \fBTcl_AppendResult\fR in
+that it allows results to be built up in pieces.
+However, \fBTcl_AppendElement\fR takes only a single \fIelement\fR
+argument and it appends that argument to the current result
+as a proper Tcl list element.
+\fBTcl_AppendElement\fR adds backslashes or braces if necessary
+to ensure that \fIinterp\fR's result can be parsed as a list and that
+\fIelement\fR will be extracted as a single element.
+Under normal conditions, \fBTcl_AppendElement\fR will add a space
+character to \fIinterp\fR's result just before adding the new
+list element, so that the list elements in the result are properly
+separated.
+However if the new list element is the first in a list or sub-list
+(i.e. \fIinterp\fR's current result is empty, or consists of the
+single character
+.QW { ,
+or ends in the characters
+.QW " {" )
+then no space is added.
+.PP
+\fBTcl_FreeResult\fR performs part of the work
+of \fBTcl_ResetResult\fR.
+It frees up the memory associated with \fIinterp\fR's result.
+It also sets \fIinterp->freeProc\fR to zero, but does not
+change \fIinterp->result\fR or clear error state.
+\fBTcl_FreeResult\fR is most commonly used when a procedure
+is about to replace one result value with another.
+.SS "DIRECT ACCESS TO INTERP->RESULT"
+.PP
+It used to be legal for programs to
+directly read and write \fIinterp->result\fR
+to manipulate the interpreter result.  The Tcl headers no longer
+permit this access by default, and C code still doing this must
+be updated to use supported routines \fBTcl_GetObjResult\fR,
+\fBTcl_GetStringResult\fR, \fBTcl_SetObjResult\fR, and \fBTcl_SetResult\fR.
+As a migration aid, access can be restored with the compiler directive
+.CS
+#define USE_INTERP_RESULT
+.CE
+but this is meant only to offer life support to otherwise dead code.
+.SH "THE TCL_FREEPROC ARGUMENT TO TCL_SETRESULT"
+.PP
+\fBTcl_SetResult\fR's \fIfreeProc\fR argument specifies how
+the Tcl system is to manage the storage for the \fIresult\fR argument.
+If \fBTcl_SetResult\fR or \fBTcl_SetObjResult\fR are called
+at a time when \fIinterp\fR holds a string result,
+they do whatever is necessary to dispose of the old string result
+(see the \fBTcl_Interp\fR manual entry for details on this).
+.PP
+If \fIfreeProc\fR is \fBTCL_STATIC\fR it means that \fIresult\fR
+refers to an area of static storage that is guaranteed not to be
+modified until at least the next call to \fBTcl_Eval\fR.
+If \fIfreeProc\fR
+is \fBTCL_DYNAMIC\fR it means that \fIresult\fR was allocated with a call
+to \fBTcl_Alloc\fR and is now the property of the Tcl system.
+\fBTcl_SetResult\fR will arrange for the string's storage to be
+released by calling \fBTcl_Free\fR when it is no longer needed.
+If \fIfreeProc\fR is \fBTCL_VOLATILE\fR it means that \fIresult\fR
+points to an area of memory that is likely to be overwritten when
+\fBTcl_SetResult\fR returns (e.g. it points to something in a stack frame).
+In this case \fBTcl_SetResult\fR will make a copy of the string in
+dynamically allocated storage and arrange for the copy to be the
+result for the current Tcl command.
+.PP
+If \fIfreeProc\fR is not one of the values \fBTCL_STATIC\fR,
+\fBTCL_DYNAMIC\fR, and \fBTCL_VOLATILE\fR, then it is the address
+of a procedure that Tcl should call to free the string.
+This allows applications to use non-standard storage allocators.
+When Tcl no longer needs the storage for the string, it will
+call \fIfreeProc\fR. \fIFreeProc\fR should have arguments and
+result that match the type \fBTcl_FreeProc\fR:
+.PP
+.CS
+typedef void \fBTcl_FreeProc\fR(
+        char *\fIblockPtr\fR);
+.CE
+.PP
+When \fIfreeProc\fR is called, its \fIblockPtr\fR will be set to
+the value of \fIresult\fR passed to \fBTcl_SetResult\fR.
+.SH "SEE ALSO"
+Tcl_AddErrorInfo, Tcl_CreateObjCommand, Tcl_SetErrorCode, Tcl_Interp
+.SH KEYWORDS
+append, command, element, list, value, result, return value, interpreter
diff --git a/doc/SetVar.3 b/doc/SetVar.3
new file mode 100644
index 0000000..4aa671a
--- /dev/null
+++ b/doc/SetVar.3
@@ -0,0 +1,249 @@
+'\"
+'\" Copyright (c) 1989-1993 The Regents of the University of California.
+'\" Copyright (c) 1994-1997 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH Tcl_SetVar 3 8.1 Tcl "Tcl Library Procedures"
+.so man.macros
+.BS
+.SH NAME
+Tcl_SetVar2Ex, Tcl_SetVar, Tcl_SetVar2, Tcl_ObjSetVar2, Tcl_GetVar2Ex, Tcl_GetVar, Tcl_GetVar2, Tcl_ObjGetVar2, Tcl_UnsetVar, Tcl_UnsetVar2 \- manipulate Tcl variables
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+Tcl_Obj *
+\fBTcl_SetVar2Ex\fR(\fIinterp, name1, name2, newValuePtr, flags\fR)
+.sp
+const char *
+\fBTcl_SetVar\fR(\fIinterp, varName, newValue, flags\fR)
+.sp
+const char *
+\fBTcl_SetVar2\fR(\fIinterp, name1, name2, newValue, flags\fR)
+.sp
+Tcl_Obj *
+\fBTcl_ObjSetVar2\fR(\fIinterp, part1Ptr, part2Ptr, newValuePtr, flags\fR)
+.sp
+Tcl_Obj *
+\fBTcl_GetVar2Ex\fR(\fIinterp, name1, name2, flags\fR)
+.sp
+const char *
+\fBTcl_GetVar\fR(\fIinterp, varName, flags\fR)
+.sp
+const char *
+\fBTcl_GetVar2\fR(\fIinterp, name1, name2, flags\fR)
+.sp
+Tcl_Obj *
+\fBTcl_ObjGetVar2\fR(\fIinterp, part1Ptr, part2Ptr, flags\fR)
+.sp
+int
+\fBTcl_UnsetVar\fR(\fIinterp, varName, flags\fR)
+.sp
+int
+\fBTcl_UnsetVar2\fR(\fIinterp, name1, name2, flags\fR)
+.SH ARGUMENTS
+.AS Tcl_Interp *newValuePtr
+.AP Tcl_Interp *interp in
+Interpreter containing variable.
+.AP "const char" *name1 in
+Contains the name of an array variable (if \fIname2\fR is non-NULL)
+or (if \fIname2\fR is NULL) either the name of a scalar variable
+or a complete name including both variable name and index.
+May include \fB::\fR namespace qualifiers
+to specify a variable in a particular namespace.
+.AP "const char" *name2 in
+If non-NULL, gives name of element within array; in this
+case \fIname1\fR must refer to an array variable.
+.AP Tcl_Obj *newValuePtr in
+Points to a Tcl value containing the new value for the variable.
+.AP int flags in
+OR-ed combination of bits providing additional information. See below
+for valid values.
+.AP "const char" *varName in
+Name of variable.
+May include \fB::\fR namespace qualifiers
+to specify a variable in a particular namespace.
+May refer to a scalar variable or an element of
+an array.
+.AP "const char" *newValue in
+New value for variable, specified as a null-terminated string.
+A copy of this value is stored in the variable.
+.AP Tcl_Obj *part1Ptr in
+Points to a Tcl value containing the variable's name.
+The name may include a series of \fB::\fR namespace qualifiers
+to specify a variable in a particular namespace.
+May refer to a scalar variable or an element of an array variable.
+.AP Tcl_Obj *part2Ptr in
+If non-NULL, points to a value containing the name of an element
+within an array and \fIpart1Ptr\fR must refer to an array variable.
+.BE
+
+.SH DESCRIPTION
+.PP
+These procedures are used to create, modify, read, and delete
+Tcl variables from C code.
+.PP
+\fBTcl_SetVar2Ex\fR, \fBTcl_SetVar\fR, \fBTcl_SetVar2\fR, and
+\fBTcl_ObjSetVar2\fR
+will create a new variable or modify an existing one.
+These procedures set the given variable to the value
+given by \fInewValuePtr\fR or \fInewValue\fR and return a
+pointer to the variable's new value, which is stored in Tcl's
+variable structure.
+\fBTcl_SetVar2Ex\fR and \fBTcl_ObjSetVar2\fR take the new value as a
+Tcl_Obj and return
+a pointer to a Tcl_Obj.  \fBTcl_SetVar\fR and \fBTcl_SetVar2\fR
+take the new value as a string and return a string; they are
+usually less efficient than \fBTcl_ObjSetVar2\fR.  Note that the
+return value may be different than the \fInewValuePtr\fR or
+\fInewValue\fR argument, due to modifications made by write traces.
+If an error occurs in setting the variable (e.g. an array
+variable is referenced without giving an index into the array)
+NULL is returned and an error message is left in \fIinterp\fR's
+result if the \fBTCL_LEAVE_ERR_MSG\fR \fIflag\fR bit is set.
+.PP
+\fBTcl_GetVar2Ex\fR, \fBTcl_GetVar\fR, \fBTcl_GetVar2\fR, and
+\fBTcl_ObjGetVar2\fR
+return the current value of a variable.
+The arguments to these procedures are treated in the same way
+as the arguments to the procedures described above.
+Under normal circumstances, the return value is a pointer
+to the variable's value.  For \fBTcl_GetVar2Ex\fR and
+\fBTcl_ObjGetVar2\fR the value is
+returned as a pointer to a Tcl_Obj.  For \fBTcl_GetVar\fR and
+\fBTcl_GetVar2\fR the value is returned as a string; this is
+usually less efficient, so \fBTcl_GetVar2Ex\fR or \fBTcl_ObjGetVar2\fR
+are preferred.
+If an error occurs while reading the variable (e.g. the variable
+does not exist or an array element is specified for a scalar
+variable), then NULL is returned and an error message is left
+in \fIinterp\fR's result if the \fBTCL_LEAVE_ERR_MSG\fR \fIflag\fR
+bit is set.
+.PP
+\fBTcl_UnsetVar\fR and \fBTcl_UnsetVar2\fR may be used to remove
+a variable, so that future attempts to read the variable will return
+an error.
+The arguments to these procedures are treated in the same way
+as the arguments to the procedures above.
+If the variable is successfully removed then \fBTCL_OK\fR is returned.
+If the variable cannot be removed because it does not exist then
+\fBTCL_ERROR\fR is returned and an error message is left
+in \fIinterp\fR's result if the \fBTCL_LEAVE_ERR_MSG\fR \fIflag\fR
+bit is set.
+If an array element is specified, the given element is removed
+but the array remains.
+If an array name is specified without an index, then the entire
+array is removed.
+.PP
+The name of a variable may be specified to these procedures in
+four ways:
+.IP [1]
+If \fBTcl_SetVar\fR, \fBTcl_GetVar\fR, or \fBTcl_UnsetVar\fR
+is invoked, the variable name is given as
+a single string, \fIvarName\fR.
+If \fIvarName\fR contains an open parenthesis and ends with a
+close parenthesis, then the value between the parentheses is
+treated as an index (which can have any string value) and
+the characters before the first open
+parenthesis are treated as the name of an array variable.
+If \fIvarName\fR does not have parentheses as described above, then
+the entire string is treated as the name of a scalar variable.
+.IP [2]
+If the \fIname1\fR and \fIname2\fR arguments are provided and
+\fIname2\fR is non-NULL, then an array element is specified and
+the array name and index have
+already been separated by the caller: \fIname1\fR contains the
+name and \fIname2\fR contains the index.  An error is generated
+if \fIname1\fR  contains an open parenthesis and ends with a
+close parenthesis (array element) and \fIname2\fR is non-NULL.
+.IP [3]
+If \fIname2\fR is NULL, \fIname1\fR is treated just like
+\fIvarName\fR in case [1] above (it can be either a scalar or an array
+element variable name).
+.PP
+The \fIflags\fR argument may be used to specify any of several
+options to the procedures.
+It consists of an OR-ed combination of the following bits.
+.TP
+\fBTCL_GLOBAL_ONLY\fR
+Under normal circumstances the procedures look up variables as follows.
+If a procedure call is active in \fIinterp\fR,
+the variable is looked up at the current level of procedure call.
+Otherwise, the variable is looked up first in the current namespace,
+then in the global namespace.
+However, if this bit is set in \fIflags\fR then the variable
+is looked up only in the global namespace
+even if there is a procedure call active.
+If both \fBTCL_GLOBAL_ONLY\fR and \fBTCL_NAMESPACE_ONLY\fR are given,
+\fBTCL_GLOBAL_ONLY\fR is ignored.
+.TP
+\fBTCL_NAMESPACE_ONLY\fR
+If this bit is set in \fIflags\fR then the variable
+is looked up only in the current namespace; if a procedure is active
+its variables are ignored, and the global namespace is also ignored unless
+it is the current namespace.
+.TP
+\fBTCL_LEAVE_ERR_MSG\fR
+If an error is returned and this bit is set in \fIflags\fR, then
+an error message will be left in the interpreter's result,
+where it can be retrieved with \fBTcl_GetObjResult\fR
+or \fBTcl_GetStringResult\fR.
+If this flag bit is not set then no error message is left
+and the interpreter's result will not be modified.
+.TP
+\fBTCL_APPEND_VALUE\fR
+If this bit is set then \fInewValuePtr\fR or \fInewValue\fR is
+appended to the current value instead of replacing it.
+If the variable is currently undefined, then the bit is ignored.
+This bit is only used by the \fBTcl_Set*\fR procedures.
+.TP
+\fBTCL_LIST_ELEMENT\fR
+If this bit is set, then \fInewValue\fR is converted to a valid
+Tcl list element before setting (or appending to) the variable.
+A separator space is appended before the new list element unless
+the list element is going to be the first element in a list or
+sublist (i.e. the variable's current value is empty, or contains
+the single character
+.QW { ,
+or ends in
+.QW " }" ).
+When appending, the original value of the variable must also be
+a valid list, so that the operation is the appending of a new
+list element onto a list.
+.PP
+\fBTcl_GetVar\fR and \fBTcl_GetVar2\fR
+return the current value of a variable.
+The arguments to these procedures are treated in the same way
+as the arguments to \fBTcl_SetVar\fR and \fBTcl_SetVar2\fR.
+Under normal circumstances, the return value is a pointer
+to the variable's value (which is stored in Tcl's variable
+structure and will not change before the next call to \fBTcl_SetVar\fR
+or \fBTcl_SetVar2\fR).
+\fBTcl_GetVar\fR and \fBTcl_GetVar2\fR use the flag bits \fBTCL_GLOBAL_ONLY\fR
+and \fBTCL_LEAVE_ERR_MSG\fR, both of
+which have
+the same meaning as for \fBTcl_SetVar\fR.
+If an error occurs in reading the variable (e.g. the variable
+does not exist or an array element is specified for a scalar
+variable), then NULL is returned.
+.PP
+\fBTcl_UnsetVar\fR and \fBTcl_UnsetVar2\fR may be used to remove
+a variable, so that future calls to \fBTcl_GetVar\fR or \fBTcl_GetVar2\fR
+for the variable will return an error.
+The arguments to these procedures are treated in the same way
+as the arguments to \fBTcl_GetVar\fR and \fBTcl_GetVar2\fR.
+If the variable is successfully removed then \fBTCL_OK\fR is returned.
+If the variable cannot be removed because it does not exist then
+\fBTCL_ERROR\fR is returned.
+If an array element is specified, the given element is removed
+but the array remains.
+If an array name is specified without an index, then the entire
+array is removed.
+
+.SH "SEE ALSO"
+Tcl_GetObjResult, Tcl_GetStringResult, Tcl_TraceVar
+
+.SH KEYWORDS
+array, get variable, interpreter, scalar, set, unset, value, variable
diff --git a/doc/Signal.3 b/doc/Signal.3
new file mode 100644
index 0000000..70b9d91
--- /dev/null
+++ b/doc/Signal.3
@@ -0,0 +1,41 @@
+'\"
+'\" Copyright (c) 2001 ActiveState Tool Corp.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\" 
+.TH Tcl_SignalId 3 8.3 Tcl "Tcl Library Procedures"
+.so man.macros
+.BS
+.SH NAME
+Tcl_SignalId, Tcl_SignalMsg \- Convert signal codes
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+const char *
+\fBTcl_SignalId\fR(\fIsig\fR)
+.sp
+const char *
+\fBTcl_SignalMsg\fR(\fIsig\fR)
+.sp
+.SH ARGUMENTS
+.AS int sig
+.AP int sig in
+A POSIX signal number such as \fBSIGPIPE\fR.
+.BE
+
+.SH DESCRIPTION
+.PP
+\fBTcl_SignalId\fR and \fBTcl_SignalMsg\fR return a string
+representation of the provided signal number (\fIsig\fR).
+\fBTcl_SignalId\fR returns a machine-readable textual identifier such
+as
+.QW SIGPIPE .
+\fBTcl_SignalMsg\fR returns a human-readable string such as
+.QW "bus error" .
+The strings returned by these functions are
+statically allocated and the caller must not free or modify them.
+
+.SH KEYWORDS
+signals, signal numbers
diff --git a/doc/Sleep.3 b/doc/Sleep.3
new file mode 100644
index 0000000..2d36697
--- /dev/null
+++ b/doc/Sleep.3
@@ -0,0 +1,34 @@
+'\"
+'\" Copyright (c) 1990 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\" 
+.TH Tcl_Sleep 3 7.5 Tcl "Tcl Library Procedures"
+.so man.macros
+.BS
+.SH NAME
+Tcl_Sleep \- delay execution for a given number of milliseconds
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+\fBTcl_Sleep\fR(\fIms\fR)
+.SH ARGUMENTS
+.AS int ms
+.AP int ms in
+Number of milliseconds to sleep.
+.BE
+.SH DESCRIPTION
+.PP
+This procedure delays the calling process by the number of
+milliseconds given by the \fIms\fR parameter and returns
+after that time has elapsed.  It is typically used for things
+like flashing a button, where the delay is short and the
+application need not do anything while it waits.  For longer
+delays where the application needs to respond to other events
+during the delay, the procedure \fBTcl_CreateTimerHandler\fR
+should be used instead of \fBTcl_Sleep\fR.
+.SH KEYWORDS
+sleep, time, wait
diff --git a/doc/SourceRCFile.3 b/doc/SourceRCFile.3
new file mode 100644
index 0000000..0afb66b
--- /dev/null
+++ b/doc/SourceRCFile.3
@@ -0,0 +1,32 @@
+'\"
+'\" Copyright (c) 1998-2000 by Scriptics Corporation.
+'\" All rights reserved.
+'\"
+.TH Tcl_SourceRCFile 3 8.3 Tcl "Tcl Library Procedures"
+.so man.macros
+.BS
+.SH NAME
+Tcl_SourceRCFile \- source the Tcl rc file
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+void
+\fBTcl_SourceRCFile\fR(\fIinterp\fR)
+.SH ARGUMENTS
+.AS Tcl_Interp *interp
+.AP Tcl_Interp *interp in
+Tcl interpreter to source rc file into.
+.BE
+
+.SH DESCRIPTION
+.PP
+\fBTcl_SourceRCFile\fR is used to source the Tcl rc file at startup.
+It is typically invoked by Tcl_Main or Tk_Main.  The name of the file
+sourced is obtained from the global variable \fBtcl_rcFileName\fR in
+the interpreter given by \fIinterp\fR.  If this variable is not
+defined, or if the file it indicates cannot be found, no action is
+taken.
+
+.SH KEYWORDS
+application-specific initialization, main program, rc file
diff --git a/doc/SplitList.3 b/doc/SplitList.3
new file mode 100644
index 0000000..3439f2e
--- /dev/null
+++ b/doc/SplitList.3
@@ -0,0 +1,188 @@
+'\"
+'\" Copyright (c) 1989-1993 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\" 
+.TH Tcl_SplitList 3 8.0 Tcl "Tcl Library Procedures"
+.so man.macros
+.BS
+.SH NAME
+Tcl_SplitList, Tcl_Merge, Tcl_ScanElement, Tcl_ConvertElement, Tcl_ScanCountedElement, Tcl_ConvertCountedElement \- manipulate Tcl lists
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+int
+\fBTcl_SplitList\fR(\fIinterp, list, argcPtr, argvPtr\fR)
+.sp
+char *
+\fBTcl_Merge\fR(\fIargc, argv\fR)
+.sp
+int
+\fBTcl_ScanElement\fR(\fIsrc, flagsPtr\fR)
+.sp
+int
+\fBTcl_ScanCountedElement\fR(\fIsrc, length, flagsPtr\fR)
+.sp
+int
+\fBTcl_ConvertElement\fR(\fIsrc, dst, flags\fR)
+.sp
+int
+\fBTcl_ConvertCountedElement\fR(\fIsrc, length, dst, flags\fR)
+.SH ARGUMENTS
+.AS "const char *const" ***argvPtr out
+.AP Tcl_Interp *interp out
+Interpreter to use for error reporting.  If NULL, then no error message
+is left.
+.AP char *list in
+Pointer to a string with proper list structure.
+.AP int *argcPtr out
+Filled in with number of elements in \fIlist\fR.
+.AP "const char" ***argvPtr out
+\fI*argvPtr\fR will be filled in with the address of an array of
+pointers to the strings that are the extracted elements of \fIlist\fR.
+There will be \fI*argcPtr\fR valid entries in the array, followed by
+a NULL entry.
+.AP int argc in
+Number of elements in \fIargv\fR.
+.AP "const char *const" *argv in
+Array of strings to merge together into a single list.
+Each string will become a separate element of the list.
+.AP "const char" *src in
+String that is to become an element of a list.
+.AP int *flagsPtr in
+Pointer to word to fill in with information about \fIsrc\fR.
+The value of *\fIflagsPtr\fR must be passed to \fBTcl_ConvertElement\fR.
+.AP int length in
+Number of bytes in string \fIsrc\fR.
+.AP char *dst in
+Place to copy converted list element.  Must contain enough characters
+to hold converted string.
+.AP int flags in
+Information about \fIsrc\fR. Must be value returned by previous
+call to \fBTcl_ScanElement\fR, possibly OR-ed
+with \fBTCL_DONT_USE_BRACES\fR.
+.BE
+.SH DESCRIPTION
+.PP
+These procedures may be used to disassemble and reassemble Tcl lists.
+\fBTcl_SplitList\fR breaks a list up into its constituent elements,
+returning an array of pointers to the elements using
+\fIargcPtr\fR and \fIargvPtr\fR.
+While extracting the arguments, \fBTcl_SplitList\fR obeys the usual
+rules for backslash substitutions and braces.  The area of
+memory pointed to by \fI*argvPtr\fR is dynamically allocated;  in
+addition to the array of pointers, it
+also holds copies of all the list elements.  It is the caller's
+responsibility to free up all of this storage.
+For example, suppose that you have called \fBTcl_SplitList\fR with
+the following code:
+.PP
+.CS
+int argc, code;
+char *string;
+char **argv;
+\&...
+code = \fBTcl_SplitList\fR(interp, string, &argc, &argv);
+.CE
+.PP
+Then you should eventually free the storage with a call like the
+following:
+.PP
+.CS
+Tcl_Free((char *) argv);
+.CE
+.PP
+\fBTcl_SplitList\fR normally returns \fBTCL_OK\fR, which means the list was
+successfully parsed.
+If there was a syntax error in \fIlist\fR, then \fBTCL_ERROR\fR is returned
+and the interpreter's result will point to an error message describing the
+problem (if \fIinterp\fR was not NULL).
+If \fBTCL_ERROR\fR is returned then no memory is allocated and \fI*argvPtr\fR
+is not modified.
+.PP
+\fBTcl_Merge\fR is the inverse of \fBTcl_SplitList\fR:  it
+takes a collection of strings given by \fIargc\fR
+and \fIargv\fR and generates a result string
+that has proper list structure.
+This means that commands like \fBindex\fR may be used to
+extract the original elements again.
+In addition, if the result of \fBTcl_Merge\fR is passed to \fBTcl_Eval\fR,
+it will be parsed into \fIargc\fR words whose values will
+be the same as the \fIargv\fR strings passed to \fBTcl_Merge\fR.
+\fBTcl_Merge\fR will modify the list elements with braces and/or
+backslashes in order to produce proper Tcl list structure.
+The result string is dynamically allocated
+using \fBTcl_Alloc\fR;  the caller must eventually release the space
+using \fBTcl_Free\fR.
+.PP
+If the result of \fBTcl_Merge\fR is passed to \fBTcl_SplitList\fR,
+the elements returned by \fBTcl_SplitList\fR will be identical to
+those passed into \fBTcl_Merge\fR.
+However, the converse is not true:  if \fBTcl_SplitList\fR
+is passed a given string, and the resulting \fIargc\fR and
+\fIargv\fR are passed to \fBTcl_Merge\fR, the resulting string
+may not be the same as the original string passed to \fBTcl_SplitList\fR.
+This is because \fBTcl_Merge\fR may use backslashes and braces
+differently than the original string.
+.PP
+\fBTcl_ScanElement\fR and \fBTcl_ConvertElement\fR are the
+procedures that do all of the real work of \fBTcl_Merge\fR.
+\fBTcl_ScanElement\fR scans its \fIsrc\fR argument
+and determines how to use backslashes and braces
+when converting it to a list element.
+It returns an overestimate of the number of characters
+required to represent \fIsrc\fR as a list element, and
+it stores information in \fI*flagsPtr\fR that is needed
+by \fBTcl_ConvertElement\fR.
+.PP
+\fBTcl_ConvertElement\fR is a companion procedure to \fBTcl_ScanElement\fR.
+It does the actual work of converting a string to a list element.
+Its \fIflags\fR argument must be the same as the value returned
+by \fBTcl_ScanElement\fR.
+\fBTcl_ConvertElement\fR writes a proper list element to memory
+starting at *\fIdst\fR and returns a count of the total number
+of characters written, which will be no more than the result
+returned by \fBTcl_ScanElement\fR.
+\fBTcl_ConvertElement\fR writes out only the actual list element
+without any leading or trailing spaces: it is up to the caller to
+include spaces between adjacent list elements.
+.PP
+\fBTcl_ConvertElement\fR uses one of two different approaches to
+handle the special characters in \fIsrc\fR.  Wherever possible, it
+handles special characters by surrounding the string with braces.
+This produces clean-looking output, but cannot be used in some situations,
+such as when \fIsrc\fR contains unmatched braces.
+In these situations, \fBTcl_ConvertElement\fR handles special
+characters by generating backslash sequences for them.
+The caller may insist on the second approach by OR-ing the
+flag value returned by \fBTcl_ScanElement\fR with
+\fBTCL_DONT_USE_BRACES\fR.
+Although this will produce an uglier result, it is useful in some
+special situations, such as when \fBTcl_ConvertElement\fR is being
+used to generate a portion of an argument for a Tcl command.
+In this case, surrounding \fIsrc\fR with curly braces would cause
+the command not to be parsed correctly.
+.PP
+By default, \fBTcl_ConvertElement\fR will use quoting in its output
+to be sure the first character of an element is not the hash
+character
+.PQ # .
+This is to be sure the first element of any list
+passed to \fBeval\fR is not mis-parsed as the beginning of a comment.
+When a list element is not the first element of a list, this quoting
+is not necessary.  When the caller can be sure that the element is
+not the first element of a list, it can disable quoting of the leading
+hash character by OR-ing the flag value returned by \fBTcl_ScanElement\fR
+with \fBTCL_DONT_QUOTE_HASH\fR.
+.PP
+\fBTcl_ScanCountedElement\fR and \fBTcl_ConvertCountedElement\fR are
+the same as \fBTcl_ScanElement\fR and \fBTcl_ConvertElement\fR, except
+the length of string \fIsrc\fR is specified by the \fIlength\fR
+argument, and the string may contain embedded nulls.
+.SH "SEE ALSO"
+Tcl_ListObjGetElements(3)
+.SH KEYWORDS
+backslash, convert, element, list, merge, split, strings
diff --git a/doc/SplitPath.3 b/doc/SplitPath.3
new file mode 100644
index 0000000..19cee05
--- /dev/null
+++ b/doc/SplitPath.3
@@ -0,0 +1,97 @@
+'\"
+'\" Copyright (c) 1996 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\" 
+.TH Tcl_SplitPath 3 7.5 Tcl "Tcl Library Procedures"
+.so man.macros
+.BS
+.SH NAME
+Tcl_SplitPath, Tcl_JoinPath, Tcl_GetPathType \- manipulate platform-dependent file paths
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+\fBTcl_SplitPath\fR(\fIpath, argcPtr, argvPtr\fR)
+.sp
+char *
+\fBTcl_JoinPath\fR(\fIargc, argv, resultPtr\fR)
+.sp
+Tcl_PathType
+\fBTcl_GetPathType\fR(\fIpath\fR)
+.SH ARGUMENTS
+.AS "const char *const" ***argvPtr in/out
+.AP "const char" *path in
+File path in a form appropriate for the current platform (see the
+\fBfilename\fR manual entry for acceptable forms for path names).
+.AP int *argcPtr out
+Filled in with number of path elements in \fIpath\fR.
+.AP "const char" ***argvPtr out
+\fI*argvPtr\fR will be filled in with the address of an array of
+pointers to the strings that are the extracted elements of \fIpath\fR.
+There will be \fI*argcPtr\fR valid entries in the array, followed by
+a NULL entry.
+.AP int argc in
+Number of elements in \fIargv\fR.
+.AP "const char *const" *argv in
+Array of path elements to merge together into a single path.
+.AP Tcl_DString *resultPtr in/out
+A pointer to an initialized \fBTcl_DString\fR to which the result of
+\fBTcl_JoinPath\fR will be appended.
+.BE
+
+.SH DESCRIPTION
+.PP
+These procedures have been superseded by the Tcl-value-aware procedures in
+the \fBFileSystem\fR man page, which are more efficient.
+.PP
+These procedures may be used to disassemble and reassemble file
+paths in a platform independent manner: they provide C-level access to
+the same functionality as the \fBfile split\fR, \fBfile join\fR, and
+\fBfile pathtype\fR commands.
+.PP
+\fBTcl_SplitPath\fR breaks a path into its constituent elements,
+returning an array of pointers to the elements using \fIargcPtr\fR and
+\fIargvPtr\fR.  The area of memory pointed to by \fI*argvPtr\fR is
+dynamically allocated; in addition to the array of pointers, it also
+holds copies of all the path elements.  It is the caller's
+responsibility to free all of this storage.
+For example, suppose that you have called \fBTcl_SplitPath\fR with the
+following code:
+.PP
+.CS
+int argc;
+char *path;
+char **argv;
+\&...
+Tcl_SplitPath(string, &argc, &argv);
+.CE
+.PP
+Then you should eventually free the storage with a call like the
+following:
+.PP
+.CS
+Tcl_Free((char *) argv);
+.CE
+.PP
+\fBTcl_JoinPath\fR is the inverse of \fBTcl_SplitPath\fR: it takes a
+collection of path elements given by \fIargc\fR and \fIargv\fR and
+generates a result string that is a properly constructed path. The
+result string is appended to \fIresultPtr\fR.  \fIResultPtr\fR must
+refer to an initialized \fBTcl_DString\fR.
+.PP
+If the result of \fBTcl_SplitPath\fR is passed to \fBTcl_JoinPath\fR,
+the result will refer to the same location, but may not be in the same
+form.  This is because \fBTcl_SplitPath\fR and \fBTcl_JoinPath\fR
+eliminate duplicate path separators and return a normalized form for
+each platform.
+.PP
+\fBTcl_GetPathType\fR returns the type of the specified \fIpath\fR,
+where \fBTcl_PathType\fR is one of \fBTCL_PATH_ABSOLUTE\fR,
+\fBTCL_PATH_RELATIVE\fR, or \fBTCL_PATH_VOLUME_RELATIVE\fR.  See the
+\fBfilename\fR manual entry for a description of the path types for
+each platform.
+
+.SH KEYWORDS
+file, filename, join, path, split, type
diff --git a/doc/StaticPkg.3 b/doc/StaticPkg.3
new file mode 100644
index 0000000..5700ea7
--- /dev/null
+++ b/doc/StaticPkg.3
@@ -0,0 +1,70 @@
+'\"
+'\" Copyright (c) 1995-1996 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\" 
+.TH Tcl_StaticPackage 3 7.5 Tcl "Tcl Library Procedures"
+.so man.macros
+.BS
+.SH NAME
+Tcl_StaticPackage \- make a statically linked package available via the 'load' command
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+\fBTcl_StaticPackage\fR(\fIinterp, pkgName, initProc, safeInitProc\fR)
+.SH ARGUMENTS
+.AS Tcl_PackageInitProc *safeInitProc
+.AP Tcl_Interp *interp in
+If not NULL, points to an interpreter into which the package has
+already been loaded (i.e., the caller has already invoked the
+appropriate initialization procedure).  NULL means the package
+has not yet been incorporated into any interpreter.
+.AP "const char" *pkgName in
+Name of the package;  should be properly capitalized (first letter
+upper-case, all others lower-case).
+.AP Tcl_PackageInitProc *initProc in
+Procedure to invoke to incorporate this package into a trusted
+interpreter.
+.AP Tcl_PackageInitProc *safeInitProc in
+Procedure to call to incorporate this package into a safe interpreter
+(one that will execute untrusted scripts).  NULL means the package
+cannot be used in safe interpreters.
+.BE
+.SH DESCRIPTION
+.PP
+This procedure may be invoked to announce that a package has been
+linked statically with a Tcl application and, optionally, that it
+has already been loaded into an interpreter.
+Once \fBTcl_StaticPackage\fR has been invoked for a package, it
+may be loaded into interpreters using the \fBload\fR command.
+\fBTcl_StaticPackage\fR is normally invoked only by the \fBTcl_AppInit\fR
+procedure for the application, not by packages for themselves
+(\fBTcl_StaticPackage\fR should only be invoked for statically
+loaded packages, and code in the package itself should not need
+to know whether the package is dynamically or statically loaded).
+.PP
+When the \fBload\fR command is used later to load the package into
+an interpreter, one of \fIinitProc\fR and \fIsafeInitProc\fR will
+be invoked, depending on whether the target interpreter is safe
+or not.
+\fIinitProc\fR and \fIsafeInitProc\fR must both match the
+following prototype:
+.PP
+.CS
+typedef int \fBTcl_PackageInitProc\fR(
+        Tcl_Interp *\fIinterp\fR);
+.CE
+.PP
+The \fIinterp\fR argument identifies the interpreter in which the package
+is to be loaded.  The initialization procedure must return \fBTCL_OK\fR or
+\fBTCL_ERROR\fR to indicate whether or not it completed successfully; in
+the event of an error it should set the interpreter's result to point to an
+error message.  The result or error from the initialization procedure will
+be returned as the result of the \fBload\fR command that caused the
+initialization procedure to be invoked.
+.SH KEYWORDS
+initialization procedure, package, static linking
+.SH "SEE ALSO"
+load(n), package(n), Tcl_PkgRequire(3)
diff --git a/doc/StdChannels.3 b/doc/StdChannels.3
new file mode 100644
index 0000000..651ad7d
--- /dev/null
+++ b/doc/StdChannels.3
@@ -0,0 +1,120 @@
+'\"
+'\" Copyright (c) 2001 by ActiveState Corporation
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\" 
+.TH "Standard Channels" 3 7.5 Tcl "Tcl Library Procedures"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+Tcl_StandardChannels \- How the Tcl library deals with the standard channels
+.BE
+
+.SH DESCRIPTION
+.PP
+This page explains the initialization and use of standard channels in
+the Tcl library.
+.PP
+The term \fIstandard channels\fR comes out of the Unix world and
+refers to the three channels automatically opened by the OS for
+each new application. They are \fBstdin\fR, \fBstdout\fR and
+\fBstderr\fR. The first is the standard input an application can read
+from, the other two refer to writable channels, one for regular
+output and the other for error messages.
+.PP
+Tcl generalizes this concept in a cross-platform way and
+exposes standard channels to the script level.
+.SS "APPLICATION PROGRAMMING INTERFACES"
+.PP
+The public API procedures dealing directly with standard channels are
+\fBTcl_GetStdChannel\fR and \fBTcl_SetStdChannel\fR. Additional public
+APIs to consider are \fBTcl_RegisterChannel\fR,
+\fBTcl_CreateChannel\fR and \fBTcl_GetChannel\fR.
+.SH "INITIALIZATION OF TCL STANDARD CHANNELS"
+.PP
+Standard channels are initialized by the Tcl library in three cases:
+when explicitly requested, when implicitly required before returning
+channel information, or when implicitly required during registration
+of a new channel.
+.PP
+These cases differ in how they handle unavailable platform- specific
+standard channels.  (A channel is not
+.QW available
+if it could not be
+successfully opened; for example, in a Tcl application run as a
+Windows NT service.)
+.TP
+1)
+A single standard channel is initialized when it is explicitly
+specified in a call to \fBTcl_SetStdChannel\fR.  The states of the
+other standard channels are unaffected.
+.RS
+.PP
+Missing platform-specific standard channels do not matter here. This
+approach is not available at the script level.
+.RE
+.TP
+2)
+All uninitialized standard channels are initialized to
+platform-specific default values:
+.RS
+.TP
+(a)
+when open channels are listed with \fBTcl_GetChannelNames\fR (or the
+\fBfile channels\fR script command), or
+.TP
+(b)
+when information about any standard channel is requested with a call
+to \fBTcl_GetStdChannel\fR, or with a call to \fBTcl_GetChannel\fR
+which specifies one of the standard names (\fBstdin\fR, \fBstdout\fR
+and \fBstderr\fR).
+.PP
+In case of missing platform-specific standard channels, the Tcl
+standard channels are considered as initialized and then immediately
+closed. This means that the first three Tcl channels then opened by
+the application are designated as the Tcl standard channels.
+.RE
+.TP
+3)
+All uninitialized standard channels are initialized to
+platform-specific default values when a user-requested channel is
+registered with \fBTcl_RegisterChannel\fR.
+.PP
+In case of unavailable platform-specific standard channels the channel
+whose creation caused the initialization of the Tcl standard channels
+is made a normal channel.  The next three Tcl channels opened by the
+application are designated as the Tcl standard channels.  In other
+words, of the first four Tcl channels opened by the application the
+second to fourth are designated as the Tcl standard channels.
+.SH "RE-INITIALIZATION OF TCL STANDARD CHANNELS"
+.PP
+Once a Tcl standard channel is initialized through one of the methods
+above, closing this Tcl standard channel will cause the next call to
+\fBTcl_CreateChannel\fR to make the new channel the new standard
+channel, too. If more than one Tcl standard channel was closed
+\fBTcl_CreateChannel\fR will fill the empty slots in the order
+\fBstdin\fR, \fBstdout\fR and \fBstderr\fR.
+.PP
+\fBTcl_CreateChannel\fR will not try to reinitialize an empty slot if
+that slot was not initialized before. It is this behavior which
+enables an application to employ method 1 of initialization, i.e. to
+create and designate their own Tcl standard channels.
+.SH "SHELL-SPECIFIC DETAILS"
+.SS tclsh
+.PP
+The Tcl shell (or rather the function \fBTcl_Main\fR, which forms the
+core of the shell's implementation) uses method 2 to initialize
+the standard channels.
+.SS wish
+.PP
+The windowing shell (or rather the function \fBTk_MainEx\fR, which
+forms the core of the shell's implementation) uses method 1 to
+initialize the standard channels (See \fBTk_InitConsoleChannels\fR)
+on non-Unix platforms.  On Unix platforms, \fBTk_MainEx\fR implicitly
+uses method 2 to initialize the standard channels.
+.SH "SEE ALSO"
+Tcl_CreateChannel(3), Tcl_RegisterChannel(3), Tcl_GetChannel(3), Tcl_GetStdChannel(3), Tcl_SetStdChannel(3), Tk_InitConsoleChannels(3), tclsh(1), wish(1), Tcl_Main(3), Tk_MainEx(3)
+.SH KEYWORDS
+standard channels
diff --git a/doc/StrMatch.3 b/doc/StrMatch.3
new file mode 100644
index 0000000..f9c2be3
--- /dev/null
+++ b/doc/StrMatch.3
@@ -0,0 +1,49 @@
+'\"
+'\" Copyright (c) 1989-1993 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\" 
+.TH Tcl_StringMatch 3 8.5 Tcl "Tcl Library Procedures"
+.so man.macros
+.BS
+.SH NAME
+Tcl_StringMatch, Tcl_StringCaseMatch \- test whether a string matches a pattern
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+int
+\fBTcl_StringMatch\fR(\fIstr\fR, \fIpattern\fR)
+.sp
+int
+\fBTcl_StringCaseMatch\fR(\fIstr\fR, \fIpattern\fR, \fIflags\fR)
+.SH ARGUMENTS
+.AS "const char" *pattern
+.AP "const char" *str in
+String to test.
+.AP "const char" *pattern in
+Pattern to match against string.  May contain special
+characters from the set *?\e[].
+.AP int flags in
+OR-ed combination of match flags, currently only \fBTCL_MATCH_NOCASE\fR.
+0 specifies a case-sensitive search.
+.BE
+
+.SH DESCRIPTION
+.PP
+This utility procedure determines whether a string matches
+a given pattern.  If it does, then \fBTcl_StringMatch\fR returns
+1.  Otherwise \fBTcl_StringMatch\fR returns 0.  The algorithm
+used for matching is the same algorithm used in the \fBstring match\fR
+Tcl command and is similar to the algorithm used by the C-shell
+for file name matching;  see the Tcl manual entry for details.
+.PP
+In \fBTcl_StringCaseMatch\fR, the algorithm is
+the same, but you have the option to make the matching case-insensitive.
+If you choose this (by passing \fBTCL_MATCH_NOCASE\fR), then the string and
+pattern are essentially matched in the lower case.
+
+.SH KEYWORDS
+match, pattern, string
diff --git a/doc/StringObj.3 b/doc/StringObj.3
new file mode 100644
index 0000000..7042cc8
--- /dev/null
+++ b/doc/StringObj.3
@@ -0,0 +1,387 @@
+'\"
+'\" Copyright (c) 1994-1997 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH Tcl_StringObj 3 8.1 Tcl "Tcl Library Procedures"
+.so man.macros
+.BS
+.SH NAME
+Tcl_NewStringObj, Tcl_NewUnicodeObj, Tcl_SetStringObj, Tcl_SetUnicodeObj, Tcl_GetStringFromObj, Tcl_GetString, Tcl_GetUnicodeFromObj, Tcl_GetUnicode, Tcl_GetUniChar, Tcl_GetCharLength, Tcl_GetRange, Tcl_AppendToObj, Tcl_AppendUnicodeToObj, Tcl_AppendObjToObj, Tcl_AppendStringsToObj, Tcl_AppendStringsToObjVA, Tcl_AppendLimitedToObj, Tcl_Format, Tcl_AppendFormatToObj, Tcl_ObjPrintf, Tcl_AppendPrintfToObj, Tcl_SetObjLength, Tcl_AttemptSetObjLength, Tcl_ConcatObj \- manipulate Tcl values as strings
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+Tcl_Obj *
+\fBTcl_NewStringObj\fR(\fIbytes, length\fR)
+.sp
+Tcl_Obj *
+\fBTcl_NewUnicodeObj\fR(\fIunicode, numChars\fR)
+.sp
+void
+\fBTcl_SetStringObj\fR(\fIobjPtr, bytes, length\fR)
+.sp
+void
+\fBTcl_SetUnicodeObj\fR(\fIobjPtr, unicode, numChars\fR)
+.sp
+char *
+\fBTcl_GetStringFromObj\fR(\fIobjPtr, lengthPtr\fR)
+.sp
+char *
+\fBTcl_GetString\fR(\fIobjPtr\fR)
+.sp
+Tcl_UniChar *
+\fBTcl_GetUnicodeFromObj\fR(\fIobjPtr, lengthPtr\fR)
+.sp
+Tcl_UniChar *
+\fBTcl_GetUnicode\fR(\fIobjPtr\fR)
+.sp
+Tcl_UniChar
+\fBTcl_GetUniChar\fR(\fIobjPtr, index\fR)
+.sp
+int
+\fBTcl_GetCharLength\fR(\fIobjPtr\fR)
+.sp
+Tcl_Obj *
+\fBTcl_GetRange\fR(\fIobjPtr, first, last\fR)
+.sp
+void
+\fBTcl_AppendToObj\fR(\fIobjPtr, bytes, length\fR)
+.sp
+void
+\fBTcl_AppendUnicodeToObj\fR(\fIobjPtr, unicode, numChars\fR)
+.sp
+void
+\fBTcl_AppendObjToObj\fR(\fIobjPtr, appendObjPtr\fR)
+.sp
+void
+\fBTcl_AppendStringsToObj\fR(\fIobjPtr, string, string, ... \fB(char *) NULL\fR)
+.sp
+void
+\fBTcl_AppendStringsToObjVA\fR(\fIobjPtr, argList\fR)
+.sp
+void
+\fBTcl_AppendLimitedToObj\fR(\fIobjPtr, bytes, length, limit, ellipsis\fR)
+.sp
+Tcl_Obj *
+\fBTcl_Format\fR(\fIinterp, format, objc, objv\fR)
+.sp
+int
+\fBTcl_AppendFormatToObj\fR(\fIinterp, objPtr, format, objc, objv\fR)
+.sp
+Tcl_Obj *
+\fBTcl_ObjPrintf\fR(\fIformat, ...\fR)
+.sp
+void
+\fBTcl_AppendPrintfToObj\fR(\fIobjPtr, format, ...\fR)
+.sp
+void
+\fBTcl_SetObjLength\fR(\fIobjPtr, newLength\fR)
+.sp
+int
+\fBTcl_AttemptSetObjLength\fR(\fIobjPtr, newLength\fR)
+.sp
+Tcl_Obj *
+\fBTcl_ConcatObj\fR(\fIobjc, objv\fR)
+.SH ARGUMENTS
+.AS "const Tcl_UniChar" *appendObjPtr in/out
+.AP "const char" *bytes in
+Points to the first byte of an array of UTF-8-encoded bytes
+used to set or append to a string value.
+This byte array may contain embedded null characters
+unless \fInumChars\fR is negative.  (Applications needing null bytes
+should represent them as the two-byte sequence \fI\e700\e600\fR, use
+\fBTcl_ExternalToUtf\fR to convert, or \fBTcl_NewByteArrayObj\fR if
+the string is a collection of uninterpreted bytes.)
+.AP int length in
+The number of bytes to copy from \fIbytes\fR when
+initializing, setting, or appending to a string value.
+If negative, all bytes up to the first null are used.
+.AP "const Tcl_UniChar" *unicode in
+Points to the first byte of an array of Unicode characters
+used to set or append to a string value.
+This byte array may contain embedded null characters
+unless \fInumChars\fR is negative.
+.AP int numChars in
+The number of Unicode characters to copy from \fIunicode\fR when
+initializing, setting, or appending to a string value.
+If negative, all characters up to the first null character are used.
+.AP int index in
+The index of the Unicode character to return.
+.AP int first in
+The index of the first Unicode character in the Unicode range to be
+returned as a new value.
+.AP int last in
+The index of the last Unicode character in the Unicode range to be
+returned as a new value.
+.AP Tcl_Obj *objPtr in/out
+Points to a value to manipulate.
+.AP Tcl_Obj *appendObjPtr in
+The value to append to \fIobjPtr\fR in \fBTcl_AppendObjToObj\fR.
+.AP int *lengthPtr out
+If non-NULL, the location where \fBTcl_GetStringFromObj\fR will store
+the length of a value's string representation.
+.AP "const char" *string in
+Null-terminated string value to append to \fIobjPtr\fR.
+.AP va_list argList in
+An argument list which must have been initialized using
+\fBva_start\fR, and cleared using \fBva_end\fR.
+.AP int limit in
+Maximum number of bytes to be appended.
+.AP "const char" *ellipsis in
+Suffix to append when the limit leads to string truncation.
+If NULL is passed then the suffix
+.QW "..."
+is used.
+.AP "const char" *format in
+Format control string including % conversion specifiers.
+.AP int objc in
+The number of elements to format or concatenate.
+.AP Tcl_Obj *objv[] in
+The array of values to format or concatenate.
+.AP int newLength in
+New length for the string value of \fIobjPtr\fR, not including the
+final null character.
+.BE
+.SH DESCRIPTION
+.PP
+The procedures described in this manual entry allow Tcl values to
+be manipulated as string values.  They use the internal representation
+of the value to store additional information to make the string
+manipulations more efficient.  In particular, they make a series of
+append operations efficient by allocating extra storage space for the
+string so that it does not have to be copied for each append.
+Also, indexing and length computations are optimized because the
+Unicode string representation is calculated and cached as needed.
+When using the \fBTcl_Append*\fR family of functions where the
+interpreter's result is the value being appended to, it is important
+to call Tcl_ResetResult first to ensure you are not unintentionally
+appending to existing data in the result value.
+.PP
+\fBTcl_NewStringObj\fR and \fBTcl_SetStringObj\fR create a new value
+or modify an existing value to hold a copy of the string given by
+\fIbytes\fR and \fIlength\fR.  \fBTcl_NewUnicodeObj\fR and
+\fBTcl_SetUnicodeObj\fR create a new value or modify an existing
+value to hold a copy of the Unicode string given by \fIunicode\fR and
+\fInumChars\fR.  \fBTcl_NewStringObj\fR and \fBTcl_NewUnicodeObj\fR
+return a pointer to a newly created value with reference count zero.
+All four procedures set the value to hold a copy of the specified
+string.  \fBTcl_SetStringObj\fR and \fBTcl_SetUnicodeObj\fR free any
+old string representation as well as any old internal representation
+of the value.
+.PP
+\fBTcl_GetStringFromObj\fR and \fBTcl_GetString\fR return a value's
+string representation.  This is given by the returned byte pointer and
+(for \fBTcl_GetStringFromObj\fR) length, which is stored in
+\fIlengthPtr\fR if it is non-NULL.  If the value's UTF string
+representation is invalid (its byte pointer is NULL), the string
+representation is regenerated from the value's internal
+representation.  The storage referenced by the returned byte pointer
+is owned by the value manager.  It is passed back as a writable
+pointer so that extension author creating their own \fBTcl_ObjType\fR
+will be able to modify the string representation within the
+\fBTcl_UpdateStringProc\fR of their \fBTcl_ObjType\fR.  Except for that
+limited purpose, the pointer returned by \fBTcl_GetStringFromObj\fR
+or \fBTcl_GetString\fR should be treated as read-only.  It is
+recommended that this pointer be assigned to a (const char *) variable.
+Even in the limited situations where writing to this pointer is
+acceptable, one should take care to respect the copy-on-write
+semantics required by \fBTcl_Obj\fR's, with appropriate calls
+to \fBTcl_IsShared\fR and \fBTcl_DuplicateObj\fR prior to any
+in-place modification of the string representation.
+The procedure \fBTcl_GetString\fR is used in the common case
+where the caller does not need the length of the string
+representation.
+.PP
+\fBTcl_GetUnicodeFromObj\fR and \fBTcl_GetUnicode\fR return a value's
+value as a Unicode string.  This is given by the returned pointer and
+(for \fBTcl_GetUnicodeFromObj\fR) length, which is stored in
+\fIlengthPtr\fR if it is non-NULL.  The storage referenced by the returned
+byte pointer is owned by the value manager and should not be modified by
+the caller.  The procedure \fBTcl_GetUnicode\fR is used in the common case
+where the caller does not need the length of the unicode string
+representation.
+.PP
+\fBTcl_GetUniChar\fR returns the \fIindex\fR'th character in the
+value's Unicode representation.
+.PP
+\fBTcl_GetRange\fR returns a newly created value comprised of the
+characters between \fIfirst\fR and \fIlast\fR (inclusive) in the
+value's Unicode representation.  If the value's Unicode
+representation is invalid, the Unicode representation is regenerated
+from the value's string representation.
+.PP
+\fBTcl_GetCharLength\fR returns the number of characters (as opposed
+to bytes) in the string value.
+.PP
+\fBTcl_AppendToObj\fR appends the data given by \fIbytes\fR and
+\fIlength\fR to the string representation of the value specified by
+\fIobjPtr\fR.  If the value has an invalid string representation,
+then an attempt is made to convert \fIbytes\fR is to the Unicode
+format.  If the conversion is successful, then the converted form of
+\fIbytes\fR is appended to the value's Unicode representation.
+Otherwise, the value's Unicode representation is invalidated and
+converted to the UTF format, and \fIbytes\fR is appended to the
+value's new string representation.
+.PP
+\fBTcl_AppendUnicodeToObj\fR appends the Unicode string given by
+\fIunicode\fR and \fInumChars\fR to the value specified by
+\fIobjPtr\fR.  If the value has an invalid Unicode representation,
+then \fIunicode\fR is converted to the UTF format and appended to the
+value's string representation.  Appends are optimized to handle
+repeated appends relatively efficiently (it over-allocates the string
+or Unicode space to avoid repeated reallocations and copies of
+value's string value).
+.PP
+\fBTcl_AppendObjToObj\fR is similar to \fBTcl_AppendToObj\fR, but it
+appends the string or Unicode value (whichever exists and is best
+suited to be appended to \fIobjPtr\fR) of \fIappendObjPtr\fR to
+\fIobjPtr\fR.
+.PP
+\fBTcl_AppendStringsToObj\fR is similar to \fBTcl_AppendToObj\fR
+except that it can be passed more than one value to append and
+each value must be a null-terminated string (i.e. none of the
+values may contain internal null characters).  Any number of
+\fIstring\fR arguments may be provided, but the last argument
+must be a NULL pointer to indicate the end of the list.
+.PP
+\fBTcl_AppendStringsToObjVA\fR is the same as \fBTcl_AppendStringsToObj\fR
+except that instead of taking a variable number of arguments it takes an
+argument list.
+.PP
+\fBTcl_AppendLimitedToObj\fR is similar to \fBTcl_AppendToObj\fR
+except that it imposes a limit on how many bytes are appended.
+This can be handy when the string to be appended might be
+very large, but the value being constructed should not be allowed to grow
+without bound. A common usage is when constructing an error message, where the
+end result should be kept short enough to be read.
+Bytes from \fIbytes\fR are appended to \fIobjPtr\fR, but no more
+than \fIlimit\fR bytes total are to be appended. If the limit prevents
+all \fIlength\fR bytes that are available from being appended, then the
+appending is done so that the last bytes appended are from the
+string \fIellipsis\fR. This allows for an indication of the truncation
+to be left in the string.
+When \fIlength\fR is \fB-1\fR, all bytes up to the first zero byte are appended,
+subject to the limit. When \fIellipsis\fR is NULL, the default
+string \fB...\fR is used. When \fIellipsis\fR is non-NULL, it must point
+to a zero-byte-terminated string in Tcl's internal UTF encoding.
+The number of bytes appended can be less than the lesser
+of \fIlength\fR and \fIlimit\fR when appending fewer
+bytes is necessary to append only whole multi-byte characters.
+.PP
+\fBTcl_Format\fR is the C-level interface to the engine of the \fBformat\fR
+command.  The actual command procedure for \fBformat\fR is little more
+than
+.PP
+.CS
+\fBTcl_Format\fR(interp, \fBTcl_GetString\fR(objv[1]), objc-2, objv+2);
+.CE
+.PP
+The \fIobjc\fR Tcl_Obj values in \fIobjv\fR are formatted into a string
+according to the conversion specification in \fIformat\fR argument, following
+the documentation for the \fBformat\fR command.  The resulting formatted
+string is converted to a new Tcl_Obj with refcount of zero and returned.
+If some error happens during production of the formatted string, NULL is
+returned, and an error message is recorded in \fIinterp\fR, if \fIinterp\fR
+is non-NULL.
+.PP
+\fBTcl_AppendFormatToObj\fR is an appending alternative form
+of \fBTcl_Format\fR with functionality equivalent to:
+.PP
+.CS
+Tcl_Obj *newPtr = \fBTcl_Format\fR(interp, format, objc, objv);
+if (newPtr == NULL) return TCL_ERROR;
+\fBTcl_AppendObjToObj\fR(objPtr, newPtr);
+\fBTcl_DecrRefCount\fR(newPtr);
+return TCL_OK;
+.CE
+.PP
+but with greater convenience and efficiency when the appending
+functionality is needed.
+.PP
+\fBTcl_ObjPrintf\fR serves as a replacement for the common sequence
+.PP
+.CS
+char buf[SOME_SUITABLE_LENGTH];
+sprintf(buf, format, ...);
+\fBTcl_NewStringObj\fR(buf, -1);
+.CE
+.PP
+but with greater convenience and no need to
+determine \fBSOME_SUITABLE_LENGTH\fR. The formatting is done with the same
+core formatting engine used by \fBTcl_Format\fR.  This means the set of
+supported conversion specifiers is that of the \fBformat\fR command and
+not that of the \fBsprintf\fR routine where the two sets differ. When a
+conversion specifier passed to \fBTcl_ObjPrintf\fR includes a precision,
+the value is taken as a number of bytes, as \fBsprintf\fR does, and not
+as a number of characters, as \fBformat\fR does.  This is done on the
+assumption that C code is more likely to know how many bytes it is
+passing around than the number of encoded characters those bytes happen
+to represent.  The variable number of arguments passed in should be of
+the types that would be suitable for passing to \fBsprintf\fR.  Note in
+this example usage, \fIx\fR is of type \fBint\fR.
+.PP
+.CS
+int x = 5;
+Tcl_Obj *objPtr = \fBTcl_ObjPrintf\fR("Value is %d", x);
+.CE
+.PP
+If the value of \fIformat\fR contains internal inconsistencies or invalid
+specifier formats, the formatted string result produced by
+\fBTcl_ObjPrintf\fR will be an error message describing the error.
+It is impossible however to provide runtime protection against
+mismatches between the format and any subsequent arguments.
+Compile-time protection may be provided by some compilers.
+.PP
+\fBTcl_AppendPrintfToObj\fR is an appending alternative form
+of \fBTcl_ObjPrintf\fR with functionality equivalent to
+.PP
+.CS
+Tcl_Obj *newPtr = \fBTcl_ObjPrintf\fR(format, ...);
+\fBTcl_AppendObjToObj\fR(objPtr, newPtr);
+\fBTcl_DecrRefCount\fR(newPtr);
+.CE
+.PP
+but with greater convenience and efficiency when the appending
+functionality is needed.
+.PP
+The \fBTcl_SetObjLength\fR procedure changes the length of the
+string value of its \fIobjPtr\fR argument.  If the \fInewLength\fR
+argument is greater than the space allocated for the value's
+string, then the string space is reallocated and the old value
+is copied to the new space; the bytes between the old length of
+the string and the new length may have arbitrary values.
+If the \fInewLength\fR argument is less than the current length
+of the value's string, with \fIobjPtr->length\fR is reduced without
+reallocating the string space; the original allocated size for the
+string is recorded in the value, so that the string length can be
+enlarged in a subsequent call to \fBTcl_SetObjLength\fR without
+reallocating storage.  In all cases \fBTcl_SetObjLength\fR leaves
+a null character at \fIobjPtr->bytes[newLength]\fR.
+.PP
+\fBTcl_AttemptSetObjLength\fR is identical in function to
+\fBTcl_SetObjLength\fR except that if sufficient memory to satisfy the
+request cannot be allocated, it does not cause the Tcl interpreter to
+\fBpanic\fR.  Thus, if \fInewLength\fR is greater than the space
+allocated for the value's string, and there is not enough memory
+available to satisfy the request, \fBTcl_AttemptSetObjLength\fR will take
+no action and return 0 to indicate failure.  If there is enough memory
+to satisfy the request, \fBTcl_AttemptSetObjLength\fR behaves just like
+\fBTcl_SetObjLength\fR and returns 1 to indicate success.
+.PP
+The \fBTcl_ConcatObj\fR function returns a new string value whose
+value is the space-separated concatenation of the string
+representations of all of the values in the \fIobjv\fR
+array. \fBTcl_ConcatObj\fR eliminates leading and trailing white space
+as it copies the string representations of the \fIobjv\fR array to the
+result. If an element of the \fIobjv\fR array consists of nothing but
+white space, then that value is ignored entirely. This white-space
+removal was added to make the output of the \fBconcat\fR command
+cleaner-looking. \fBTcl_ConcatObj\fR returns a pointer to a
+newly-created value whose ref count is zero.
+.SH "SEE ALSO"
+Tcl_NewObj(3), Tcl_IncrRefCount(3), Tcl_DecrRefCount(3), format(n), sprintf(3)
+.SH KEYWORDS
+append, internal representation, value, value type, string value,
+string type, string representation, concat, concatenate, unicode
diff --git a/doc/SubstObj.3 b/doc/SubstObj.3
new file mode 100644
index 0000000..f582c5a
--- /dev/null
+++ b/doc/SubstObj.3
@@ -0,0 +1,68 @@
+'\"
+'\" Copyright (c) 2001 Donal K. Fellows
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\" 
+.TH Tcl_SubstObj 3 8.4 Tcl "Tcl Library Procedures"
+.so man.macros
+.BS
+.SH NAME
+Tcl_SubstObj \- perform substitutions on Tcl values
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+Tcl_Obj *
+\fBTcl_SubstObj\fR(\fIinterp, objPtr, flags\fR)
+.SH ARGUMENTS
+.AS Tcl_Interp **termPtr
+.AP Tcl_Interp *interp in
+Interpreter in which to execute Tcl scripts and lookup variables.  If
+an error occurs, the interpreter's result is modified to hold an error
+message.
+.AP Tcl_Obj *objPtr in
+A Tcl value containing the string to perform substitutions on.
+.AP int flags in
+ORed combination of flag bits that specify which substitutions to
+perform.  The flags \fBTCL_SUBST_COMMANDS\fR,
+\fBTCL_SUBST_VARIABLES\fR and \fBTCL_SUBST_BACKSLASHES\fR are
+currently supported, and \fBTCL_SUBST_ALL\fR is provided as a
+convenience for the common case where all substitutions are desired.
+.BE
+.SH DESCRIPTION
+.PP
+The \fBTcl_SubstObj\fR function is used to perform substitutions on
+strings in the fashion of the \fBsubst\fR command.  It gets the value
+of the string contained in \fIobjPtr\fR and scans it, copying
+characters and performing the chosen substitutions as it goes to an
+output value which is returned as the result of the function.  In the
+event of an error occurring during the execution of a command or
+variable substitution, the function returns NULL and an error message
+is left in \fIinterp\fR's result.
+.PP
+Three kinds of substitutions are supported.  When the
+\fBTCL_SUBST_BACKSLASHES\fR bit is set in \fIflags\fR, sequences that
+look like backslash substitutions for Tcl commands are replaced by
+their corresponding character.
+.PP
+When the \fBTCL_SUBST_VARIABLES\fR bit is set in \fIflags\fR,
+sequences that look like variable substitutions for Tcl commands are
+replaced by the contents of the named variable.
+.PP
+When the \fBTCL_SUBST_COMMANDS\fR bit is set in \fIflags\fR, sequences
+that look like command substitutions for Tcl commands are replaced by
+the result of evaluating that script.  Where an uncaught
+.QW "continue exception"
+occurs during the evaluation of a command substitution, an
+empty string is substituted for the command.  Where an uncaught
+.QW "break exception"
+occurs during the evaluation of a command substitution, the
+result of the whole substitution on \fIobjPtr\fR will be truncated at
+the point immediately before the start of the command substitution,
+and no characters will be added to the result or substitutions
+performed after that point.
+.SH "SEE ALSO"
+subst(n)
+.SH KEYWORDS
+backslash substitution, command substitution, variable substitution
diff --git a/doc/TCL_MEM_DEBUG.3 b/doc/TCL_MEM_DEBUG.3
new file mode 100644
index 0000000..e3a6809
--- /dev/null
+++ b/doc/TCL_MEM_DEBUG.3
@@ -0,0 +1,80 @@
+'\" 
+'\" Copyright (c) 1992-1999 Karl Lehenbauer and Mark Diekhans.
+'\" Copyright (c) 2000 by Scriptics Corporation.
+'\" All rights reserved.
+'\" 
+.TH TCL_MEM_DEBUG 3 8.1 Tcl "Tcl Library Procedures"
+.so man.macros
+.BS
+.SH NAME
+TCL_MEM_DEBUG \- Compile-time flag to enable Tcl memory debugging
+.BE
+.SH DESCRIPTION
+When Tcl is compiled with \fBTCL_MEM_DEBUG\fR defined, a powerful set
+of memory debugging aids is included in the compiled binary.  This
+includes C and Tcl functions which can aid with debugging
+memory leaks, memory allocation overruns, and other memory related
+errors.
+.SH "ENABLING MEMORY DEBUGGING"
+.PP
+To enable memory debugging, Tcl should be recompiled from scratch with
+\fBTCL_MEM_DEBUG\fR defined (e.g. by passing the
+\fI\-\-enable\-symbols=mem\fR flag to the \fIconfigure\fR script when
+building).  This will also compile in a non-stub
+version of \fBTcl_InitMemory\fR to add the \fBmemory\fR command to Tcl.
+.PP
+\fBTCL_MEM_DEBUG\fR must be either left defined for all modules or undefined
+for all modules that are going to be linked together.  If they are not, link
+errors will occur, with either \fBTcl_DbCkfree\fR and \fBTcl_DbCkalloc\fR or
+\fBTcl_Alloc\fR and \fBTcl_Free\fR being undefined.
+.PP
+Once memory debugging support has been compiled into Tcl, the C
+functions \fBTcl_ValidateAllMemory\fR, and \fBTcl_DumpActiveMemory\fR,
+and the Tcl \fBmemory\fR command can be used to validate and examine
+memory usage.
+.SH "GUARD ZONES"
+.PP
+When memory debugging is enabled, whenever a call to \fBckalloc\fR is
+made, slightly more memory than requested is allocated so the memory
+debugging code can keep track of the allocated memory, and eight-byte
+.QW "guard zones"
+are placed in front of and behind the space that will be
+returned to the caller.  (The sizes of the guard zones are defined by the
+C #define \fBLOW_GUARD_SIZE\fR and #define \fBHIGH_GUARD_SIZE\fR
+in the file \fIgeneric/tclCkalloc.c\fR \(em it can
+be extended if you suspect large overwrite problems, at some cost in
+performance.)  A known pattern is written into the guard zones and, on
+a call to \fBckfree\fR, the guard zones of the space being freed are
+checked to see if either zone has been modified in any way.  If one
+has been, the guard bytes and their new contents are identified, and a
+.QW "low guard failed"
+or
+.QW "high guard failed"
+message is issued.  The
+.QW "guard failed"
+message includes the address of the memory packet and
+the file name and line number of the code that called \fBckfree\fR.
+This allows you to detect the common sorts of one-off problems, where
+not enough space was allocated to contain the data written, for
+example.
+.SH "DEBUGGING DIFFICULT MEMORY CORRUPTION PROBLEMS"
+.PP
+Normally, Tcl compiled with memory debugging enabled will make it easy
+to isolate a corruption problem.  Turning on memory validation with
+the memory command can help isolate difficult problems.  If you
+suspect (or know) that corruption is occurring before the Tcl
+interpreter comes up far enough for you to issue commands, you can set
+\fBMEM_VALIDATE\fR define, recompile tclCkalloc.c and rebuild Tcl.
+This will enable memory validation from the first call to
+\fBckalloc\fR, again, at a large performance impact.
+.PP
+If you are desperate and validating memory on every call to
+\fBckalloc\fR and \fBckfree\fR is not enough, you can explicitly call
+\fBTcl_ValidateAllMemory\fR directly at any point.  It takes a \fIchar
+*\fR and an \fIint\fR which are normally the filename and line number
+of the caller, but they can actually be anything you want.  Remember
+to remove the calls after you find the problem.
+.SH "SEE ALSO"
+ckalloc, memory, Tcl_ValidateAllMemory, Tcl_DumpActiveMemory
+.SH KEYWORDS
+memory, debug
diff --git a/doc/Tcl.n b/doc/Tcl.n
new file mode 100644
index 0000000..fc3b477
--- /dev/null
+++ b/doc/Tcl.n
@@ -0,0 +1,275 @@
+'\"
+'\" Copyright (c) 1993 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH Tcl n "8.6" Tcl "Tcl Built-In Commands"
+.so man.macros
+.BS
+.SH NAME
+Tcl \- Tool Command Language
+.SH SYNOPSIS
+Summary of Tcl language syntax.
+.BE
+.SH DESCRIPTION
+.PP
+The following rules define the syntax and semantics of the Tcl language:
+.IP "[1] \fBCommands.\fR"
+A Tcl script is a string containing one or more commands.
+Semi-colons and newlines are command separators unless quoted as
+described below.
+Close brackets are command terminators during command substitution
+(see below) unless quoted.
+.IP "[2] \fBEvaluation.\fR"
+A command is evaluated in two steps.
+First, the Tcl interpreter breaks the command into \fIwords\fR
+and performs substitutions as described below.
+These substitutions are performed in the same way for all
+commands.
+Secondly, the first word is used to locate a command procedure to
+carry out the command, then all of the words of the command are
+passed to the command procedure.
+The command procedure is free to interpret each of its words
+in any way it likes, such as an integer, variable name, list,
+or Tcl script.
+Different commands interpret their words differently.
+.IP "[3] \fBWords.\fR"
+Words of a command are separated by white space (except for
+newlines, which are command separators).
+.IP "[4] \fBDouble quotes.\fR"
+If the first character of a word is double-quote
+.PQ \N'34'
+then the word is terminated by the next double-quote character.
+If semi-colons, close brackets, or white space characters
+(including newlines) appear between the quotes then they are treated
+as ordinary characters and included in the word.
+Command substitution, variable substitution, and backslash substitution
+are performed on the characters between the quotes as described below.
+The double-quotes are not retained as part of the word.
+.IP "[5] \fBArgument expansion.\fR"
+If a word starts with the string
+.QW {*}
+followed by a non-whitespace character, then the leading
+.QW {*}
+is removed and the rest of the word is parsed and substituted as any other
+word. After substitution, the word is parsed as a list (without command or
+variable substitutions; backslash substitutions are performed as is normal for
+a list and individual internal words may be surrounded by either braces or
+double-quote characters), and its words are added to the command being
+substituted. For instance,
+.QW "cmd a {*}{b [c]} d {*}{$e f {g h}}"
+is equivalent to
+.QW "cmd a b {[c]} d {$e} f {g h}" .
+.IP "[6] \fBBraces.\fR"
+If the first character of a word is an open brace
+.PQ {
+and rule [5] does not apply, then
+the word is terminated by the matching close brace
+.PQ } "" .
+Braces nest within the word: for each additional open
+brace there must be an additional close brace (however,
+if an open brace or close brace within the word is
+quoted with a backslash then it is not counted in locating the
+matching close brace).
+No substitutions are performed on the characters between the
+braces except for backslash-newline substitutions described
+below, nor do semi-colons, newlines, close brackets,
+or white space receive any special interpretation.
+The word will consist of exactly the characters between the
+outer braces, not including the braces themselves.
+.IP "[7] \fBCommand substitution.\fR"
+If a word contains an open bracket
+.PQ [
+then Tcl performs \fIcommand substitution\fR.
+To do this it invokes the Tcl interpreter recursively to process
+the characters following the open bracket as a Tcl script.
+The script may contain any number of commands and must be terminated
+by a close bracket
+.PQ ] "" .
+The result of the script (i.e. the result of its last command) is
+substituted into the word in place of the brackets and all of the
+characters between them.
+There may be any number of command substitutions in a single word.
+Command substitution is not performed on words enclosed in braces.
+.IP "[8] \fBVariable substitution.\fR"
+If a word contains a dollar-sign
+.PQ $
+followed by one of the forms
+described below, then Tcl performs \fIvariable
+substitution\fR:  the dollar-sign and the following characters are
+replaced in the word by the value of a variable.
+Variable substitution may take any of the following forms:
+.RS
+.TP 15
+\fB$\fIname\fR
+.
+\fIName\fR is the name of a scalar variable;  the name is a sequence
+of one or more characters that are a letter, digit, underscore,
+or namespace separators (two or more colons).
+Letters and digits are \fIonly\fR the standard ASCII ones (\fB0\fR\(en\fB9\fR,
+\fBA\fR\(en\fBZ\fR and \fBa\fR\(en\fBz\fR).
+.TP 15
+\fB$\fIname\fB(\fIindex\fB)\fR
+.
+\fIName\fR gives the name of an array variable and \fIindex\fR gives
+the name of an element within that array.
+\fIName\fR must contain only letters, digits, underscores, and
+namespace separators, and may be an empty string.
+Letters and digits are \fIonly\fR the standard ASCII ones (\fB0\fR\(en\fB9\fR,
+\fBA\fR\(en\fBZ\fR and \fBa\fR\(en\fBz\fR).
+Command substitutions, variable substitutions, and backslash
+substitutions are performed on the characters of \fIindex\fR.
+.TP 15
+\fB${\fIname\fB}\fR
+.
+\fIName\fR is the name of a scalar variable or array element.  It may contain
+any characters whatsoever except for close braces.  It indicates an array
+element if \fIname\fR is in the form
+.QW \fIarrayName\fB(\fIindex\fB)\fR
+where \fIarrayName\fR does not contain any open parenthesis characters,
+.QW \fB(\fR ,
+or close brace characters,
+.QW \fB}\fR ,
+and \fIindex\fR can be any sequence of characters except for close brace
+characters.  No further
+substitutions are performed during the parsing of \fIname\fR.
+.PP
+There may be any number of variable substitutions in a single word.
+Variable substitution is not performed on words enclosed in braces.
+.PP
+Note that variables may contain character sequences other than those listed
+above, but in that case other mechanisms must be used to access them (e.g.,
+via the \fBset\fR command's single-argument form).
+.RE
+.IP "[9] \fBBackslash substitution.\fR"
+If a backslash
+.PQ \e
+appears within a word then \fIbackslash substitution\fR occurs.
+In all cases but those described below the backslash is dropped and
+the following character is treated as an ordinary
+character and included in the word.
+This allows characters such as double quotes, close brackets,
+and dollar signs to be included in words without triggering
+special processing.
+The following table lists the backslash sequences that are
+handled specially, along with the value that replaces each sequence.
+.RS
+.TP 7
+\e\fBa\fR
+Audible alert (bell) (Unicode U+000007).
+.TP 7
+\e\fBb\fR
+Backspace (Unicode U+000008).
+.TP 7
+\e\fBf\fR
+Form feed (Unicode U+00000C).
+.TP 7
+\e\fBn\fR
+Newline (Unicode U+00000A).
+.TP 7
+\e\fBr\fR
+Carriage-return (Unicode U+00000D).
+.TP 7
+\e\fBt\fR
+Tab (Unicode U+000009).
+.TP 7
+\e\fBv\fR
+Vertical tab (Unicode U+00000B).
+.TP 7
+\e\fB<newline>\fIwhiteSpace\fR
+.
+A single space character replaces the backslash, newline, and all spaces
+and tabs after the newline.  This backslash sequence is unique in that it
+is replaced in a separate pre-pass before the command is actually parsed.
+This means that it will be replaced even when it occurs between braces,
+and the resulting space will be treated as a word separator if it is not
+in braces or quotes.
+.TP 7
+\e\e
+Backslash
+.PQ \e "" .
+.TP 7
+\e\fIooo\fR
+.
+The digits \fIooo\fR (one, two, or three of them) give a eight-bit octal
+value for the Unicode character that will be inserted, in the range
+\fI000\fR\(en\fI377\fR (i.e., the range U+000000\(enU+0000FF).
+The parser will stop just before this range overflows, or when
+the maximum of three digits is reached.  The upper bits of the Unicode
+character will be 0.
+.TP 7
+\e\fBx\fIhh\fR
+.
+The hexadecimal digits \fIhh\fR (one or two of them) give an eight-bit
+hexadecimal value for the Unicode character that will be inserted.  The upper
+bits of the Unicode character will be 0 (i.e., the character will be in the
+range U+000000\(enU+0000FF).
+.TP 7
+\e\fBu\fIhhhh\fR
+.
+The hexadecimal digits \fIhhhh\fR (one, two, three, or four of them) give a
+sixteen-bit hexadecimal value for the Unicode character that will be
+inserted.  The upper bits of the Unicode character will be 0 (i.e., the
+character will be in the range U+000000\(enU+00FFFF).
+.TP 7
+\e\fBU\fIhhhhhhhh\fR
+.
+The hexadecimal digits \fIhhhhhhhh\fR (one up to eight of them) give a
+twenty-one-bit hexadecimal value for the Unicode character that will be
+inserted, in the range U+000000\(enU+10FFFF.  The parser will stop just
+before this range overflows, or when the maximum of eight digits
+is reached.  The upper bits of the Unicode character will be 0.
+.RS
+.PP
+The range U+010000\(enU+10FFFD is reserved for the future.
+.RE
+.PP
+Backslash substitution is not performed on words enclosed in braces,
+except for backslash-newline as described above.
+.RE
+.IP "[10] \fBComments.\fR"
+If a hash character
+.PQ #
+appears at a point where Tcl is
+expecting the first character of the first word of a command,
+then the hash character and the characters that follow it, up
+through the next newline, are treated as a comment and ignored.
+The comment character only has significance when it appears
+at the beginning of a command.
+.IP "[11] \fBOrder of substitution.\fR"
+Each character is processed exactly once by the Tcl interpreter
+as part of creating the words of a command.
+For example, if variable substitution occurs then no further
+substitutions are performed on the value of the variable;  the
+value is inserted into the word verbatim.
+If command substitution occurs then the nested command is
+processed entirely by the recursive call to the Tcl interpreter;
+no substitutions are performed before making the recursive
+call and no additional substitutions are performed on the result
+of the nested script.
+.RS
+.PP
+Substitutions take place from left to right, and each substitution is
+evaluated completely before attempting to evaluate the next.  Thus, a
+sequence like
+.PP
+.CS
+set y [set x 0][incr x][incr x]
+.CE
+.PP
+will always set the variable \fIy\fR to the value, \fI012\fR.
+.RE
+.IP "[12] \fBSubstitution and word boundaries.\fR"
+Substitutions do not affect the word boundaries of a command,
+except for argument expansion as specified in rule [5].
+For example, during variable substitution the entire value of
+the variable becomes part of a single word, even if the variable's
+value contains spaces.
+.SH KEYWORDS
+backslash, command, comment, script, substitution, variable
+'\" Local Variables:
+'\" mode: nroff
+'\" fill-column: 78
+'\" End:
diff --git a/doc/TclZlib.3 b/doc/TclZlib.3
new file mode 100644
index 0000000..c6a6417
--- /dev/null
+++ b/doc/TclZlib.3
@@ -0,0 +1,276 @@
+'\"
+'\" Copyright (c) 2008 Donal K. Fellows
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\" 
+.TH TclZlib 3 8.6 Tcl "Tcl Library Procedures"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+Tcl_ZlibAdler32, Tcl_ZlibCRC32, Tcl_ZlibDeflate, Tcl_ZlibInflate, Tcl_ZlibStreamChecksum, Tcl_ZlibStreamClose, Tcl_ZlibStreamEof, Tcl_ZlibStreamGet, Tcl_ZlibStreamGetCommandName, Tcl_ZlibStreamInit, Tcl_ZlibStreamPut \- compression and decompression functions
+.SH SYNOPSIS
+.nf
+#include <tcl.h>
+.sp
+int
+\fBTcl_ZlibDeflate\fR(\fIinterp, format, dataObj, level, dictObj\fR)
+.sp
+int
+\fBTcl_ZlibInflate\fR(\fIinterp, format, dataObj, dictObj\fR)
+.sp
+unsigned int
+\fBTcl_ZlibCRC32\fR(\fIinitValue, bytes, length\fR)
+.sp
+unsigned int
+\fBTcl_ZlibAdler32\fR(\fIinitValue, bytes, length\fR)
+.sp
+int
+\fBTcl_ZlibStreamInit\fR(\fIinterp, mode, format, level, dictObj, zshandlePtr\fR)
+.sp
+Tcl_Obj *
+\fBTcl_ZlibStreamGetCommandName\fR(\fIzshandle\fR)
+.sp
+int
+\fBTcl_ZlibStreamEof\fR(\fIzshandle\fR)
+.sp
+int
+\fBTcl_ZlibStreamClose\fR(\fIzshandle\fR)
+.sp
+int
+\fBTcl_ZlibStreamReset\fR(\fIzshandle\fR)
+.sp
+int
+\fBTcl_ZlibStreamChecksum\fR(\fIzshandle\fR)
+.sp
+int
+\fBTcl_ZlibStreamPut\fR(\fIzshandle, dataObj, flush\fR)
+.sp
+int
+\fBTcl_ZlibStreamGet\fR(\fIzshandle, dataObj, count\fR)
+.sp
+\fBTcl_ZlibStreamSetCompressionDictionary\fR(\fIzshandle, compDict\fR)
+.fi
+.SH ARGUMENTS
+.AS Tcl_ZlibStream zshandle in
+.AP Tcl_Interp *interp in
+The interpreter to store resulting compressed or uncompressed data in. Also
+where any error messages are written. For \fBTcl_ZlibStreamInit\fR, this can
+be NULL to create a stream that is not bound to a command.
+.AP int format in
+What format of compressed data to work with. Must be one of
+\fBTCL_ZLIB_FORMAT_ZLIB\fR for zlib-format data, \fBTCL_ZLIB_FORMAT_GZIP\fR
+for gzip-format data, or \fBTCL_ZLIB_FORMAT_RAW\fR for raw compressed data. In
+addition, for decompression only, \fBTCL_ZLIB_FORMAT_AUTO\fR may also be
+chosen which can automatically detect whether the compressed data was in zlib
+or gzip format.
+.AP Tcl_Obj *dataObj in/out
+A byte-array value containing the data to be compressed or decompressed, or
+to which the data extracted from the stream is appended when passed to
+\fBTcl_ZlibStreamGet\fR.
+.AP int level in
+What level of compression to use. Should be a number from 0 to 9 or one of the
+following: \fBTCL_ZLIB_COMPRESS_NONE\fR for no compression,
+\fBTCL_ZLIB_COMPRESS_FAST\fR for fast but inefficient compression,
+\fBTCL_ZLIB_COMPRESS_BEST\fR for slow but maximal compression, or
+\fBTCL_ZLIB_COMPRESS_DEFAULT\fR for the level recommended by the zlib library.
+.AP Tcl_Obj *dictObj in/out
+A dictionary that contains, or which will be updated to contain, a description
+of the gzip header associated with the compressed data. Only useful when the
+\fIformat\fR is \fBTCL_ZLIB_FORMAT_GZIP\fR or \fBTCL_ZLIB_FORMAT_AUTO\fR. If
+a NULL is passed, a default header will be used on compression and the header
+will be ignored (apart from integrity checks) on decompression. See the
+section \fBGZIP OPTIONS DICTIONARY\fR for details about the contents of this
+dictionary.
+.AP "unsigned int" initValue in
+The initial value for the checksum algorithm.
+.AP "unsigned char" *bytes in
+An array of bytes to run the checksum algorithm over, or NULL to get the
+recommended initial value for the checksum algorithm.
+.AP int length in
+The number of bytes in the array.
+.AP int mode in
+What mode to operate the stream in. Should be either
+\fBTCL_ZLIB_STREAM_DEFLATE\fR for a compressing stream or
+\fBTCL_ZLIB_STREAM_INFLATE\fR for a decompressing stream.
+.AP Tcl_ZlibStream *zshandlePtr out
+A pointer to a variable in which to write the abstract token for the stream
+upon successful creation.
+.AP Tcl_ZlibStream zshandle in
+The abstract token for the stream to operate on.
+.AP int flush in
+Whether and how to flush the stream after writing the data to it. Must be one
+of: \fBTCL_ZLIB_NO_FLUSH\fR if no flushing is to be done, \fBTCL_ZLIB_FLUSH\fR
+if the currently compressed data must be made available for access using
+\fBTcl_ZlibStreamGet\fR, \fBTCL_ZLIB_FULLFLUSH\fR if the stream must be put
+into a state where the decompressor can recover from on corruption, or
+\fBTCL_ZLIB_FINALIZE\fR to ensure that the stream is finished and that any
+trailer demanded by the format is written.
+.AP int count in
+The maximum number of bytes to get from the stream, or -1 to get all remaining
+bytes from the stream's buffers.
+.AP Tcl_Obj *compDict in
+A byte array value that is the compression dictionary to use with the stream.
+Note that this is \fInot a Tcl dictionary\fR, and it is recommended that this
+only ever be used with streams that were created with their \fIformat\fR set
+to \fBTCL_ZLIB_FORMAT_ZLIB\fR because the other formats have no mechanism to
+indicate whether a compression dictionary was present other than to fail on
+decompression.
+.BE
+.SH DESCRIPTION
+These functions form the interface from the Tcl library to the Zlib
+library by Jean-loup Gailly and Mark Adler.
+.PP
+\fBTcl_ZlibDeflate\fR and \fBTcl_ZlibInflate\fR respectively compress and
+decompress the data contained in the \fIdataObj\fR argument, according to the
+\fIformat\fR and, for compression, \fIlevel\fR arguments. The dictionary in
+the \fIdictObj\fR parameter is used to convey additional header information
+about the compressed data when the compression format supports it; currently,
+the dictionary is only used when the \fIformat\fR parameter is
+\fBTCL_ZLIB_FORMAT_GZIP\fR or \fBTCL_ZLIB_FORMAT_AUTO\fR. For details of the
+contents of the dictionary, see the \fBGZIP OPTIONS DICTIONARY\fR section
+below. Upon success, both functions leave the resulting compressed or
+decompressed data in a byte-array value that is the Tcl interpreter's result;
+the returned value is a standard Tcl result code.
+.PP
+\fBTcl_ZlibAdler32\fR and \fBTcl_ZlibCRC32\fR compute checksums on arrays of
+bytes, returning the computed checksum. Checksums are computed incrementally,
+allowing data to be processed one block at a time, but this requires the
+caller to maintain the current checksum and pass it in as the \fIinitValue\fR
+parameter; the initial value to use for this can be obtained by using NULL for
+the \fIbytes\fR parameter instead of a pointer to the array of bytes to
+compute the checksum over. Thus, typical usage in the single data block case
+is like this:
+.PP
+.CS
+checksum = \fBTcl_ZlibCRC32\fR(\fBTcl_ZlibCRC32\fR(0,NULL,0), data, length);
+.CE
+.PP
+Note that the Adler-32 algorithm is not a real checksum, but instead is a
+related type of hash that works best on longer data.
+.SS "ZLIB STREAMS"
+.PP
+\fBTcl_ZlibStreamInit\fR creates a compressing or decompressing stream that is
+linked to a Tcl command, according to its arguments, and provides an abstract
+token for the stream and returns a normal Tcl result code;
+\fBTcl_ZlibStreamGetCommandName\fR returns the name of that command given the
+stream token, or NULL if the stream has no command. Streams are not designed
+to be thread-safe; each stream should only ever be used from the thread that
+created it. When working with gzip streams, a dictionary (fields as given in
+the \fBGZIP OPTIONS DICTIONARY\fR section below) can be given via the
+\fIdictObj\fR parameter that on compression allows control over the generated
+headers, and on decompression allows discovery of the existing headers. Note
+that the dictionary will be written to on decompression once sufficient data
+has been read to have a complete header. This means that the dictionary must
+be an unshared value in that case; a blank value created with
+\fBTcl_NewObj\fR is suggested.
+.PP
+Once a stream has been constructed, \fBTcl_ZlibStreamPut\fR is used to add
+data to the stream and \fBTcl_ZlibStreamGet\fR is used to retrieve data from
+the stream after processing. Both return normal Tcl result codes and leave an
+error message in the result of the interpreter that the stream is registered
+with in the error case (if such a registration has been performed). With
+\fBTcl_ZlibStreamPut\fR, the data buffer value passed to it should not be
+modified afterwards. With \fBTcl_ZlibStreamGet\fR, the data buffer value
+passed to it will have the data bytes appended to it. Internally to the
+stream, data is kept compressed so as to minimize the cost of buffer space.
+.PP
+\fBTcl_ZlibStreamChecksum\fR returns the checksum computed over the
+uncompressed data according to the format, and \fBTcl_ZlibStreamEof\fR returns
+a boolean value indicating whether the end of the uncompressed data has been
+reached.
+.PP
+\fBTcl_ZlibStreamSetCompressionDictionary\fR is used to control the
+compression dictionary used with the stream, a compression dictionary being an
+array of bytes (such as might be created with \fBTcl_NewByteArrayObj\fR) that
+is used to initialize the compression engine rather than leaving it to create
+it on the fly from the data being compressed. Setting a compression dictionary
+allows for more efficient compression in the case where the start of the data
+is highly regular, but it does require both the compressor and the
+decompressor to agreee on the value to use. Compression dictionaries are only
+fully supported for zlib-format data; on compression, they must be set before
+any data is sent in with \fBTcl_ZlibStreamPut\fR, and on decompression they
+should be set when \fBTcl_ZlibStreamGet\fR produces an \fBerror\fR with its
+\fB\-errorcode\fR set to
+.QW "\fBZLIB NEED_DICT\fI code\fR" ;
+the \fIcode\fR will be the Adler-32 checksum (see \fBTcl_ZlibAdler32\fR) of
+the compression dictionary sought. (Note that this is only true for
+zlib-format streams; gzip streams ignore compression dictionaries as the
+format specification doesn't permit them, and raw streams just produce a data
+error if the compression dictionary is missing or incorrect.)
+.PP
+If you wish to clear a stream and reuse it for a new compression or
+decompression action, \fBTcl_ZlibStreamReset\fR will do this and return a
+normal Tcl result code to indicate whether it was successful; if the stream is
+registered with an interpreter, an error message will be left in the
+interpreter result when this function returns TCL_ERROR.
+Finally, \fBTcl_ZlibStreamClose\fR will clean up the stream and delete the
+associated command: using \fBTcl_DeleteCommand\fR on the stream's command is
+equivalent (when such a command exists).
+.SH "GZIP OPTIONS DICTIONARY"
+.PP
+The \fIdictObj\fR parameter to \fBTcl_ZlibDeflate\fR, \fBTcl_ZlibInflate\fR
+and \fBTcl_ZlibStreamInit\fR is used to pass a dictionary of options about
+that is used to describe the gzip header in the compressed data. When creating
+compressed data, the dictionary is read and when unpacking compressed data the
+dictionary is written (in which case the \fIdictObj\fR parameter must refer to
+an unshared dictionary value).
+.PP
+The following fields in the dictionary value are understood. All other fields
+are ignored. No field is required when creating a gzip-format stream.
+.TP
+\fBcomment\fR
+.
+This holds the comment field of the header, if present. If absent, no comment
+was supplied (on decompression) or will be created (on compression).
+.TP
+\fBcrc\fR
+.
+A boolean value describing whether a CRC of the header is computed. Note that
+the \fBgzip\fR program does \fInot\fR use or allow a CRC on the header.
+.TP
+\fBfilename\fR
+.
+The name of the file that held the uncompressed data. This should not contain
+any directory separators, and should be sanitized before use on decompression
+with \fBfile tail\fR.
+.TP
+\fBos\fR
+.
+The operating system type code field from the header (if not the
+.QW unknown
+value). See RFC 1952 for the meaning of these codes. On compression, if this
+is absent then the field will be set to the
+.QW unknown
+value.
+.TP
+\fBsize\fR
+.
+The size of the uncompressed data. This is ignored on compression; the size
+of the data compressed depends on how much data is supplied to the
+compression engine.
+.TP
+\fBtime\fR
+.
+The time field from the header if non-zero, expected to be the time that the
+file named by the \fBfilename\fR field was modified. Suitable for use with
+\fBclock format\fR. On creation, the right value to use is that from
+\fBclock seconds\fR or \fBfile mtime\fR.
+.TP
+\fBtype\fR
+.
+The type of the uncompressed data (either \fBbinary\fR or \fBtext\fR) if
+known.
+.SH "PORTABILITY NOTES"
+These functions will fail gracefully if Tcl is not linked with the zlib
+library.
+.SH "SEE ALSO"
+Tcl_NewByteArrayObj(3), zlib(n)
+'\"Tcl_StackChannel(3)
+.SH "KEYWORDS"
+compress, decompress, deflate, gzip, inflate
+'\" Local Variables:
+'\" mode: nroff
+'\" fill-column: 78
+'\" End:
diff --git a/doc/Tcl_Main.3 b/doc/Tcl_Main.3
new file mode 100644
index 0000000..3ec33d1
--- /dev/null
+++ b/doc/Tcl_Main.3
@@ -0,0 +1,196 @@
+'\"
+'\" Copyright (c) 1994 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\" Copyright (c) 2000 Ajuba Solutions.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH Tcl_Main 3 8.4 Tcl "Tcl Library Procedures"
+.so man.macros
+.BS
+.SH NAME
+Tcl_Main, Tcl_SetStartupScript, Tcl_GetStartupScript, Tcl_SetMainLoop \- main program, startup script, and event loop definition for Tcl-based applications
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+\fBTcl_Main\fR(\fIargc, argv, appInitProc\fR)
+.sp
+\fBTcl_SetStartupScript\fR(\fIpath, encoding\fR)
+.sp
+Tcl_Obj *
+\fBTcl_GetStartupScript\fR(\fIencodingPtr\fR)
+.sp
+\fBTcl_SetMainLoop\fR(\fImainLoopProc\fR)
+.SH ARGUMENTS
+.AS Tcl_MainLoopProc *mainLoopProc
+.AP int argc in
+Number of elements in \fIargv\fR.
+.AP char *argv[] in
+Array of strings containing command-line arguments. On Windows, when
+using -DUNICODE, the parameter type changes to wchar_t *.
+.AP Tcl_AppInitProc *appInitProc in
+Address of an application-specific initialization procedure.
+The value for this argument is usually \fBTcl_AppInit\fR.
+.AP Tcl_Obj *path in
+Name of file to use as startup script, or NULL.
+.AP "const char" *encoding in
+Encoding of file to use as startup script, or NULL.
+.AP "const char" **encodingPtr out
+If non-NULL, location to write a copy of the (const char *)
+pointing to the encoding name.
+.AP Tcl_MainLoopProc *mainLoopProc in
+Address of an application-specific event loop procedure.
+.BE
+.SH DESCRIPTION
+.PP
+\fBTcl_Main\fR can serve as the main program for Tcl-based shell
+applications.  A
+.QW "shell application"
+is a program
+like tclsh or wish that supports both interactive interpretation
+of Tcl and evaluation of a script contained in a file given as
+a command line argument.  \fBTcl_Main\fR is offered as a convenience
+to developers of shell applications, so they do not have to
+reproduce all of the code for proper initialization of the Tcl
+library and interactive shell operation.  Other styles of embedding
+Tcl in an application are not supported by \fBTcl_Main\fR.  Those
+must be achieved by calling lower level functions in the Tcl library
+directly.
+.PP
+The \fBTcl_Main\fR function has been offered by the Tcl library
+since release Tcl 7.4.  In older releases of Tcl, the Tcl library
+itself defined a function \fBmain\fR, but that lacks flexibility
+of embedding style and having a function \fBmain\fR in a library
+(particularly a shared library) causes problems on many systems.
+Having \fBmain\fR in the Tcl library would also make it hard to use
+Tcl in C++ programs, since C++ programs must have special C++
+\fBmain\fR functions.
+.PP
+Normally each shell application contains a small \fBmain\fR function
+that does nothing but invoke \fBTcl_Main\fR.
+\fBTcl_Main\fR then does all the work of creating and running a
+\fBtclsh\fR-like application.
+.PP
+\fBTcl_Main\fR is not provided by the public interface of Tcl's
+stub library.  Programs that call \fBTcl_Main\fR must be linked
+against the standard Tcl library.  Extensions (stub-enabled or
+not) are not intended to call \fBTcl_Main\fR.
+.PP
+\fBTcl_Main\fR is not thread-safe.  It should only be called by
+a single master thread of a multi-threaded application.  This
+restriction is not a problem with normal use described above.
+.PP
+\fBTcl_Main\fR and therefore all applications based upon it, like
+\fBtclsh\fR, use \fBTcl_GetStdChannel\fR to initialize the standard
+channels to their default values. See \fBTcl_StandardChannels\fR for
+more information.
+.PP
+\fBTcl_Main\fR supports two modes of operation, depending on
+whether the filename and encoding of a startup script has been
+established.  The routines \fBTcl_SetStartupScript\fR and
+\fBTcl_GetStartupScript\fR are the tools for controlling this
+configuration of \fBTcl_Main\fR.
+.PP
+\fBTcl_SetStartupScript\fR registers the value \fIpath\fR
+as the name of the file for \fBTcl_Main\fR to evaluate as
+its startup script.  The value \fIencoding\fR is Tcl's name
+for the encoding used to store the text in that file.  A
+value of \fBNULL\fR for \fIencoding\fR is a signal to use
+the system encoding.  A value of \fBNULL\fR for \fIpath\fR
+erases any existing registration so that \fBTcl_Main\fR
+will not evaluate any startup script.
+.PP
+\fBTcl_GetStartupScript\fR queries the registered file name
+and encoding set by the most recent \fBTcl_SetStartupScript\fR
+call in the same thread.  The stored file name is returned,
+and the stored encoding name is written to space pointed to
+by \fIencodingPtr\fR, when that is not NULL.
+.PP
+The file name and encoding values managed by the routines
+\fBTcl_SetStartupScript\fR and \fBTcl_GetStartupScript\fR
+are stored per-thread.  Although the storage and retrieval
+functions of these routines work in any thread, only those
+calls in the same master thread as \fBTcl_Main\fR can have
+any influence on it.
+.PP
+The caller of \fBTcl_Main\fR may call \fBTcl_SetStartupScript\fR
+first to establish its desired startup script.  If \fBTcl_Main\fR
+finds that no such startup script has been established, it consults
+the first few arguments in \fIargv\fR.  If they match
+?\fB\-encoding \fIname\fR? \fIfileName\fR,
+where \fIfileName\fR does not begin with the character \fI\-\fR,
+then \fIfileName\fR is taken to be the name of a file containing
+a \fIstartup script\fR, and \fIname\fR is taken to be the name
+of the encoding of the contents of that file.  \fBTcl_Main\fR
+then calls \fBTcl_SetStartupScript\fR with these values.
+.PP
+\fBTcl_Main\fR then defines in its master interpreter
+the Tcl variables \fIargc\fR, \fIargv\fR, \fIargv0\fR, and
+\fItcl_interactive\fR, as described in the documentation for \fBtclsh\fR.
+.PP
+When it has finished its own initialization, but before it processes
+commands, \fBTcl_Main\fR calls the procedure given by the
+\fIappInitProc\fR argument.  This procedure provides a
+.QW hook
+for the application to perform its own initialization of the interpreter
+created by \fBTcl_Main\fR, such as defining application-specific
+commands.  The application initialization routine might also
+call \fBTcl_SetStartupScript\fR to (re-)set the file and encoding
+to be used as a startup script.  The procedure must have an interface
+that matches the type \fBTcl_AppInitProc\fR:
+.PP
+.CS
+typedef int \fBTcl_AppInitProc\fR(
+        Tcl_Interp *\fIinterp\fR);
+.CE
+.PP
+\fIAppInitProc\fR is almost always a pointer to \fBTcl_AppInit\fR; for more
+details on this procedure, see the documentation for \fBTcl_AppInit\fR.
+.PP
+When the \fIappInitProc\fR is finished, \fBTcl_Main\fR calls
+\fBTcl_GetStartupScript\fR to determine what startup script has
+been requested, if any.  If a startup script has been provided,
+\fBTcl_Main\fR attempts to evaluate it.  Otherwise, interactive
+mode begins with examination of the variable \fItcl_rcFileName\fR
+in the master interpreter.  If that variable exists and holds the
+name of a readable file, the contents of that file are evaluated
+in the master interpreter.  Then interactive operations begin,
+with prompts and command evaluation results written to the standard
+output channel, and commands read from the standard input channel
+and then evaluated.  The prompts written to the standard output
+channel may be customized by defining the Tcl variables \fItcl_prompt1\fR
+and \fItcl_prompt2\fR as described in the documentation for \fBtclsh\fR.
+The prompts and command evaluation results are written to the standard
+output channel only if the Tcl variable \fItcl_interactive\fR in the
+master interpreter holds a non-zero integer value.
+.PP
+\fBTcl_SetMainLoop\fR allows setting an event loop procedure to be run.
+This allows, for example, Tk to be dynamically loaded and set its event
+loop.  The event loop will run following the startup script.  If you
+are in interactive mode, setting the main loop procedure will cause the
+prompt to become fileevent based and then the loop procedure is called.
+When the loop procedure returns in interactive mode, interactive operation
+will continue.
+The main loop procedure must have an interface that matches the type
+\fBTcl_MainLoopProc\fR:
+.PP
+.CS
+typedef void \fBTcl_MainLoopProc\fR(void);
+.CE
+.PP
+\fBTcl_Main\fR does not return.  Normally a program based on
+\fBTcl_Main\fR will terminate when the \fBexit\fR command is
+evaluated.  In interactive mode, if an EOF or channel error
+is encountered on the standard input channel, then \fBTcl_Main\fR
+itself will evaluate the \fBexit\fR command after the main loop
+procedure (if any) returns.  In non-interactive mode, after
+\fBTcl_Main\fR evaluates the startup script, and the main loop
+procedure (if any) returns, \fBTcl_Main\fR will also evaluate
+the \fBexit\fR command.
+.SH "SEE ALSO"
+tclsh(1), Tcl_GetStdChannel(3), Tcl_StandardChannels(3), Tcl_AppInit(3),
+exit(n), encoding(n)
+.SH KEYWORDS
+application-specific initialization, command-line arguments, main program
diff --git a/doc/Thread.3 b/doc/Thread.3
new file mode 100644
index 0000000..5966a71
--- /dev/null
+++ b/doc/Thread.3
@@ -0,0 +1,242 @@
+'\"
+'\" Copyright (c) 1999 Scriptics Corporation
+'\" Copyright (c) 1998 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH Threads 3 "8.1" Tcl "Tcl Library Procedures"
+.so man.macros
+.BS
+.SH NAME
+Tcl_ConditionNotify, Tcl_ConditionWait, Tcl_ConditionFinalize, Tcl_GetThreadData, Tcl_MutexLock, Tcl_MutexUnlock, Tcl_MutexFinalize, Tcl_CreateThread, Tcl_JoinThread \- Tcl thread support
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+void
+\fBTcl_ConditionNotify\fR(\fIcondPtr\fR)
+.sp
+void
+\fBTcl_ConditionWait\fR(\fIcondPtr, mutexPtr, timePtr\fR)
+.sp
+void
+\fBTcl_ConditionFinalize\fR(\fIcondPtr\fR)
+.sp
+Void *
+\fBTcl_GetThreadData\fR(\fIkeyPtr, size\fR)
+.sp
+void
+\fBTcl_MutexLock\fR(\fImutexPtr\fR)
+.sp
+void
+\fBTcl_MutexUnlock\fR(\fImutexPtr\fR)
+.sp
+void
+\fBTcl_MutexFinalize\fR(\fImutexPtr\fR)
+.sp
+int
+\fBTcl_CreateThread\fR(\fIidPtr, proc, clientData, stackSize, flags\fR)
+.sp
+int
+\fBTcl_JoinThread\fR(\fIid, result\fR)
+.SH ARGUMENTS
+.AS Tcl_CreateThreadProc proc out
+.AP Tcl_Condition *condPtr in
+A condition variable, which must be associated with a mutex lock.
+.AP Tcl_Mutex *mutexPtr in
+A mutex lock.
+.AP "const Tcl_Time" *timePtr in
+A time limit on the condition wait.  NULL to wait forever.
+Note that a polling value of 0 seconds does not make much sense.
+.AP Tcl_ThreadDataKey *keyPtr in
+This identifies a block of thread local storage.  The key should be
+static and process-wide, yet each thread will end up associating
+a different block of storage with this key.
+.AP int *size in
+The size of the thread local storage block.  This amount of data
+is allocated and initialized to zero the first time each thread
+calls \fBTcl_GetThreadData\fR.
+.AP Tcl_ThreadId *idPtr out
+The referred storage will contain the id of the newly created thread as
+returned by the operating system.
+.AP Tcl_ThreadId id in
+Id of the thread waited upon.
+.AP Tcl_ThreadCreateProc *proc in
+This procedure will act as the \fBmain()\fR of the newly created
+thread. The specified \fIclientData\fR will be its sole argument.
+.AP ClientData clientData in
+Arbitrary information. Passed as sole argument to the \fIproc\fR.
+.AP int stackSize in
+The size of the stack given to the new thread.
+.AP int flags in
+Bitmask containing flags allowing the caller to modify behavior of
+the new thread.
+.AP int *result out
+The referred storage is used to place the exit code of the thread
+waited upon into it.
+.BE
+.SH INTRODUCTION
+Beginning with the 8.1 release, the Tcl core is thread safe, which
+allows you to incorporate Tcl into multithreaded applications without
+customizing the Tcl core.  Starting with the 8.6 release, Tcl
+multithreading support is on by default. To disable Tcl multithreading
+support, you must include the \fB\-\|\-disable-threads\fR option to
+\fBconfigure\fR when you configure and compile your Tcl core.
+.PP
+An important constraint of the Tcl threads implementation is that
+\fIonly the thread that created a Tcl interpreter can use that
+interpreter\fR.  In other words, multiple threads can not access
+the same Tcl interpreter.  (However, a single thread can safely create
+and use multiple interpreters.)
+.SH DESCRIPTION
+Tcl provides \fBTcl_CreateThread\fR for creating threads. The
+caller can determine the size of the stack given to the new thread and
+modify the behavior through the supplied \fIflags\fR. The value
+\fBTCL_THREAD_STACK_DEFAULT\fR for the \fIstackSize\fR indicates that
+the default size as specified by the operating system is to be used
+for the new thread. As for the flags, currently only the values
+\fBTCL_THREAD_NOFLAGS\fR and \fBTCL_THREAD_JOINABLE\fR are defined. The
+first of them invokes the default behavior with no special settings.
+Using the second value marks the new thread as \fIjoinable\fR. This
+means that another thread can wait for the such marked thread to exit
+and join it.
+.PP
+Restrictions: On some UNIX systems the pthread-library does not
+contain the functionality to specify the stack size of a thread. The
+specified value for the stack size is ignored on these systems.
+Windows currently does not support joinable threads. This
+flag value is therefore ignored on this platform.
+.PP
+Tcl provides the \fBTcl_ExitThread\fR and \fBTcl_FinalizeThread\fR functions
+for terminating threads and invoking optional per-thread exit
+handlers.  See the \fBTcl_Exit\fR page for more information on these
+procedures.
+.PP
+The \fBTcl_JoinThread\fR function is provided to allow threads to wait
+upon the exit of another thread, which must have been marked as
+joinable through usage of the \fBTCL_THREAD_JOINABLE\fR-flag during
+its creation via \fBTcl_CreateThread\fR.
+.PP
+Trying to wait for the exit of a non-joinable thread or a thread which
+is already waited upon will result in an error. Waiting for a joinable
+thread which already exited is possible, the system will retain the
+necessary information until after the call to \fBTcl_JoinThread\fR.
+This means that not calling \fBTcl_JoinThread\fR for a joinable thread
+will cause a memory leak.
+.PP
+The \fBTcl_GetThreadData\fR call returns a pointer to a block of
+thread-private data.  Its argument is a key that is shared by all threads
+and a size for the block of storage.  The storage is automatically
+allocated and initialized to all zeros the first time each thread asks for it.
+The storage is automatically deallocated by \fBTcl_FinalizeThread\fR.
+.SS "SYNCHRONIZATION AND COMMUNICATION"
+Tcl provides \fBTcl_ThreadQueueEvent\fR and \fBTcl_ThreadAlert\fR
+for handling event queuing in multithreaded applications.  See
+the \fBNotifier\fR manual page for more information on these procedures.
+.PP
+A mutex is a lock that is used to serialize all threads through a piece
+of code by calling \fBTcl_MutexLock\fR and \fBTcl_MutexUnlock\fR.
+If one thread holds a mutex, any other thread calling \fBTcl_MutexLock\fR will
+block until \fBTcl_MutexUnlock\fR is called.
+A mutex can be destroyed after its use by calling \fBTcl_MutexFinalize\fR.
+The result of locking a mutex twice from the same thread is undefined.
+On some platforms it will result in a deadlock.
+The \fBTcl_MutexLock\fR, \fBTcl_MutexUnlock\fR and \fBTcl_MutexFinalize\fR
+procedures are defined as empty macros if not compiling with threads enabled.
+For declaration of mutexes the \fBTCL_DECLARE_MUTEX\fR macro should be used.
+This macro assures correct mutex handling even when the core is compiled
+without threads enabled.
+.PP
+A condition variable is used as a signaling mechanism:
+a thread can lock a mutex and then wait on a condition variable
+with \fBTcl_ConditionWait\fR.  This atomically releases the mutex lock
+and blocks the waiting thread until another thread calls
+\fBTcl_ConditionNotify\fR.  The caller of \fBTcl_ConditionNotify\fR should
+have the associated mutex held by previously calling \fBTcl_MutexLock\fR,
+but this is not enforced.  Notifying the
+condition variable unblocks all threads waiting on the condition variable,
+but they do not proceed until the mutex is released with \fBTcl_MutexUnlock\fR.
+The implementation of \fBTcl_ConditionWait\fR automatically locks
+the mutex before returning.
+.PP
+The caller of \fBTcl_ConditionWait\fR should be prepared for spurious
+notifications by calling \fBTcl_ConditionWait\fR within a while loop
+that tests some invariant.
+.PP
+A condition variable can be destroyed after its use by calling
+\fBTcl_ConditionFinalize\fR.
+.PP
+The \fBTcl_ConditionNotify\fR, \fBTcl_ConditionWait\fR and
+\fBTcl_ConditionFinalize\fR procedures are defined as empty macros if
+not compiling with threads enabled.
+.SS INITIALIZATION
+.PP
+All of these synchronization objects are self-initializing.
+They are implemented as opaque pointers that should be NULL
+upon first use.
+The mutexes and condition variables are
+either cleaned up by process exit handlers (if living that long) or
+explicitly by calls to \fBTcl_MutexFinalize\fR or
+\fBTcl_ConditionFinalize\fR.
+Thread local storage is reclaimed during \fBTcl_FinalizeThread\fR.
+.SH "SCRIPT-LEVEL ACCESS TO THREADS"
+.PP
+Tcl provides no built-in commands for scripts to use to create,
+manage, or join threads, nor any script-level access to mutex or
+condition variables.  It provides such facilities only via C
+interfaces, and leaves it up to packages to expose these matters to
+the script level.  One such package is the \fBThread\fR package.
+.SH EXAMPLE
+.PP
+To create a thread with portable code, its implementation function should be
+declared as follows:
+.PP
+.CS
+static \fBTcl_ThreadCreateProc\fR MyThreadImplFunc;
+.CE
+.PP
+It should then be defined like this example, which just counts up to a given
+value and then finishes.
+.PP
+.CS
+static \fBTcl_ThreadCreateType\fR
+MyThreadImplFunc(
+    ClientData clientData)
+{
+    int i, limit = (int) clientData;
+    for (i=0 ; i<limit ; i++) {
+        /* doing nothing at all here */
+    }
+    \fBTCL_THREAD_CREATE_RETURN\fR;
+}
+.CE
+.PP
+To create the above thread, make it execute, and wait for it to finish, we
+would do this:
+.PP
+.CS
+int limit = 1000000000;
+ClientData limitData = (void*)((intptr_t) limit);
+Tcl_ThreadId id;    \fI/* holds identity of thread created */\fR
+int result;
+
+if (\fBTcl_CreateThread\fR(&id, MyThreadImplFunc, limitData,
+        \fBTCL_THREAD_STACK_DEFAULT\fR,
+        \fBTCL_THREAD_JOINABLE\fR) != TCL_OK) {
+    \fI/* Thread did not create correctly */\fR
+    return;
+}
+\fI/* Do something else for a while here */\fR
+if (\fBTcl_JoinThread\fR(id, &result) != TCL_OK) {
+    \fI/* Thread did not finish properly */\fR
+    return;
+}
+\fI/* All cleaned up nicely */\fR
+.CE
+.SH "SEE ALSO"
+Tcl_GetCurrentThread(3), Tcl_ThreadQueueEvent(3), Tcl_ThreadAlert(3),
+Tcl_ExitThread(3), Tcl_FinalizeThread(3), Tcl_CreateThreadExitHandler(3),
+Tcl_DeleteThreadExitHandler(3), Thread
+.SH KEYWORDS
+thread, mutex, condition variable, thread local storage
diff --git a/doc/ToUpper.3 b/doc/ToUpper.3
new file mode 100644
index 0000000..b933e9c
--- /dev/null
+++ b/doc/ToUpper.3
@@ -0,0 +1,88 @@
+'\"
+'\" Copyright (c) 1997 by Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH Tcl_UtfToUpper 3 "8.1" Tcl "Tcl Library Procedures"
+.so man.macros
+.BS
+.SH NAME
+Tcl_UniCharToUpper, Tcl_UniCharToLower, Tcl_UniCharToTitle, Tcl_UtfToUpper, Tcl_UtfToLower, Tcl_UtfToTitle \- routines for manipulating the case of Unicode characters and UTF-8 strings
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+Tcl_UniChar
+\fBTcl_UniCharToUpper\fR(\fIch\fR)
+.sp
+Tcl_UniChar
+\fBTcl_UniCharToLower\fR(\fIch\fR)
+.sp
+Tcl_UniChar
+\fBTcl_UniCharToTitle\fR(\fIch\fR)
+.sp
+int
+\fBTcl_UtfToUpper\fR(\fIstr\fR)
+.sp
+int
+\fBTcl_UtfToLower\fR(\fIstr\fR)
+.sp
+int
+\fBTcl_UtfToTitle\fR(\fIstr\fR)
+.SH ARGUMENTS
+.AS char *str in/out
+.AP int ch in
+The Tcl_UniChar to be converted.
+.AP char *str in/out
+Pointer to UTF-8 string to be converted in place.
+.BE
+
+.SH DESCRIPTION
+.PP
+The first three routines convert the case of individual Unicode characters:
+.PP
+If \fIch\fR represents a lower-case character,
+\fBTcl_UniCharToUpper\fR returns the corresponding upper-case
+character.  If no upper-case character is defined, it returns the
+character unchanged.
+.PP
+If \fIch\fR represents an upper-case character,
+\fBTcl_UniCharToLower\fR returns the corresponding lower-case
+character.  If no lower-case character is defined, it returns the
+character unchanged.
+.PP
+If \fIch\fR represents a lower-case character,
+\fBTcl_UniCharToTitle\fR returns the corresponding title-case
+character.  If no title-case character is defined, it returns the
+corresponding upper-case character.  If no upper-case character is
+defined, it returns the character unchanged.  Title-case is defined
+for a small number of characters that have a different appearance when
+they are at the beginning of a capitalized word.
+.PP
+The next three routines convert the case of UTF-8 strings in place in
+memory:
+.PP
+\fBTcl_UtfToUpper\fR changes every UTF-8 character in \fIstr\fR to
+upper-case.  Because changing the case of a character may change its
+size, the byte offset of each character in the resulting string may
+differ from its original location.  \fBTcl_UtfToUpper\fR writes a null
+byte at the end of the converted string.  \fBTcl_UtfToUpper\fR returns
+the new length of the string in bytes.  This new length is guaranteed
+to be no longer than the original string length.
+.PP
+\fBTcl_UtfToLower\fR is the same as \fBTcl_UtfToUpper\fR except it
+turns each character in the string into its lower-case equivalent.
+.PP
+\fBTcl_UtfToTitle\fR is the same as \fBTcl_UtfToUpper\fR except it
+turns the first character in the string into its title-case equivalent
+and all following characters into their lower-case equivalents.
+
+.SH BUGS
+.PP
+At this time, the case conversions are only defined for the ISO8859-1
+characters.  Unicode characters above 0x00ff are not modified by these
+routines.
+
+.SH KEYWORDS
+utf, unicode, toupper, tolower, totitle, case
diff --git a/doc/TraceCmd.3 b/doc/TraceCmd.3
new file mode 100644
index 0000000..99914a6
--- /dev/null
+++ b/doc/TraceCmd.3
@@ -0,0 +1,150 @@
+'\"
+'\" Copyright (c) 2002 Donal K. Fellows
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH Tcl_TraceCommand 3 7.4 Tcl "Tcl Library Procedures"
+.so man.macros
+.BS
+.SH NAME
+Tcl_CommandTraceInfo, Tcl_TraceCommand, Tcl_UntraceCommand \- monitor renames and deletes of a command
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+ClientData
+\fBTcl_CommandTraceInfo(\fIinterp, cmdName, flags, proc, prevClientData\fB)\fR
+.sp
+int
+\fBTcl_TraceCommand(\fIinterp, cmdName, flags, proc, clientData\fB)\fR
+.sp
+void
+\fBTcl_UntraceCommand(\fIinterp, cmdName, flags, proc, clientData\fB)\fR
+.SH ARGUMENTS
+.AS Tcl_CommandTraceProc prevClientData
+.AP Tcl_Interp *interp in
+Interpreter containing the command.
+.AP "const char" *cmdName in
+Name of command.
+.AP int flags in
+OR'ed collection of the values \fBTCL_TRACE_RENAME\fR and
+\fBTCL_TRACE_DELETE\fR.
+.AP Tcl_CommandTraceProc *proc in
+Procedure to call when specified operations occur to \fIcmdName\fR.
+.AP ClientData clientData in
+Arbitrary argument to pass to \fIproc\fR.
+.AP ClientData prevClientData in
+If non-NULL, gives last value returned by \fBTcl_CommandTraceInfo\fR,
+so this call will return information about next trace.  If NULL, this
+call will return information about first trace.
+.BE
+.SH DESCRIPTION
+.PP
+\fBTcl_TraceCommand\fR allows a C procedure to monitor operations
+performed on a Tcl command, so that the C procedure is invoked
+whenever the command is renamed or deleted.  If the trace is created
+successfully then \fBTcl_TraceCommand\fR returns \fBTCL_OK\fR. If an error
+occurred (e.g. \fIcmdName\fR specifies a non-existent command) then
+\fBTCL_ERROR\fR is returned and an error message is left in the
+interpreter's result.
+.PP
+The \fIflags\fR argument to \fBTcl_TraceCommand\fR indicates when the
+trace procedure is to be invoked.  It consists of an OR'ed combination
+of any of the following values:
+.TP
+\fBTCL_TRACE_RENAME\fR
+Invoke \fIproc\fR whenever the command is renamed.
+.TP
+\fBTCL_TRACE_DELETE\fR
+Invoke \fIproc\fR when the command is deleted.
+.PP
+Whenever one of the specified operations occurs to the command,
+\fIproc\fR will be invoked.  It should have arguments and result that
+match the type \fBTcl_CommandTraceProc\fR:
+.PP
+.CS
+typedef void \fBTcl_CommandTraceProc\fR(
+        ClientData \fIclientData\fR,
+        Tcl_Interp *\fIinterp\fR,
+        const char *\fIoldName\fR,
+        const char *\fInewName\fR,
+        int \fIflags\fR);
+.CE
+.PP
+The \fIclientData\fR and \fIinterp\fR parameters will have the same
+values as those passed to \fBTcl_TraceCommand\fR when the trace was
+created.  \fIClientData\fR typically points to an application-specific
+data structure that describes what to do when \fIproc\fR is invoked.
+\fIOldName\fR gives the name of the command being renamed, and
+\fInewName\fR gives the name that the command is being renamed to (or
+NULL when the command is being deleted.)
+\fIFlags\fR is an OR'ed combination of bits potentially providing
+several pieces of information.  One of the bits \fBTCL_TRACE_RENAME\fR and
+\fBTCL_TRACE_DELETE\fR will be set in \fIflags\fR to indicate which
+operation is being performed on the command.  The bit
+\fBTCL_TRACE_DESTROYED\fR will be set in \fIflags\fR if the trace is about
+to be destroyed; this information may be useful to \fIproc\fR so that
+it can clean up its own internal data structures (see the section
+\fBTCL_TRACE_DESTROYED\fR below for more details).  Because the
+deletion of commands can take place as part of the deletion of the interp
+that contains them, \fIproc\fR must be careful about checking what
+the passed in \fIinterp\fR value can be called upon to do.
+The routine \fBTcl_InterpDeleted\fR is an important tool for this.
+When \fBTcl_InterpDeleted\fR returns 1, \fIproc\fR will not be able
+to invoke any scripts in \fIinterp\fR.  The function of \fIproc\fR
+in that circumstance is limited to the cleanup of its own data structures.
+.PP
+\fBTcl_UntraceCommand\fR may be used to remove a trace.  If the
+command specified by \fIinterp\fR, \fIcmdName\fR, and \fIflags\fR has
+a trace set with \fIflags\fR, \fIproc\fR, and \fIclientData\fR, then
+the corresponding trace is removed.  If no such trace exists, then the
+call to \fBTcl_UntraceCommand\fR has no effect.  The same bits are
+valid for \fIflags\fR as for calls to \fBTcl_TraceCommand\fR.
+.PP
+\fBTcl_CommandTraceInfo\fR may be used to retrieve information about
+traces set on a given command.
+The return value from \fBTcl_CommandTraceInfo\fR is the \fIclientData\fR
+associated with a particular trace.
+The trace must be on the command specified by the \fIinterp\fR,
+\fIcmdName\fR, and \fIflags\fR arguments (note that currently the
+flags are ignored; \fIflags\fR should be set to 0 for future
+compatibility) and its trace procedure must the same as the \fIproc\fR
+argument.
+If the \fIprevClientData\fR argument is NULL then the return
+value corresponds to the first (most recently created) matching
+trace, or NULL if there are no matching traces.
+If the \fIprevClientData\fR argument is not NULL, then it should
+be the return value from a previous call to \fBTcl_CommandTraceInfo\fR.
+In this case, the new return value will correspond to the next
+matching trace after the one whose \fIclientData\fR matches
+\fIprevClientData\fR, or NULL if no trace matches \fIprevClientData\fR
+or if there are no more matching traces after it.
+This mechanism makes it possible to step through all of the
+traces for a given command that have the same \fIproc\fR.
+.SH "CALLING COMMANDS DURING TRACES"
+.PP
+During rename traces, the command being renamed is visible with both
+names simultaneously, and the command still exists during delete
+traces, unless the interp that contains it is being deleted.
+However, there is no
+mechanism for signaling that an error occurred in a trace procedure,
+so great care should be taken that errors do not get silently lost.
+.SH "MULTIPLE TRACES"
+.PP
+It is possible for multiple traces to exist on the same command.
+When this happens, all of the trace procedures will be invoked on each
+access, in order from most-recently-created to least-recently-created.
+Attempts to delete the command during a delete trace will fail
+silently, since the command is already scheduled for deletion anyway.
+If the command being renamed is renamed by one of its rename traces,
+that renaming takes precedence over the one that triggered the trace
+and the collection of traces will not be reexecuted; if several traces
+rename the command, the last renaming takes precedence.
+.SH "TCL_TRACE_DESTROYED FLAG"
+.PP
+In a delete callback to \fIproc\fR, the \fBTCL_TRACE_DESTROYED\fR bit
+is set in \fIflags\fR.
+.\" Perhaps need some more comments here? - DKF
+.SH KEYWORDS
+clientData, trace, command
diff --git a/doc/TraceVar.3 b/doc/TraceVar.3
new file mode 100644
index 0000000..19cb467
--- /dev/null
+++ b/doc/TraceVar.3
@@ -0,0 +1,380 @@
+'\"
+'\" Copyright (c) 1989-1993 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH Tcl_TraceVar 3 7.4 Tcl "Tcl Library Procedures"
+.so man.macros
+.BS
+.SH NAME
+Tcl_TraceVar, Tcl_TraceVar2, Tcl_UntraceVar, Tcl_UntraceVar2, Tcl_VarTraceInfo, Tcl_VarTraceInfo2 \- monitor accesses to a variable
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+int
+\fBTcl_TraceVar(\fIinterp, varName, flags, proc, clientData\fB)\fR
+.sp
+int
+\fBTcl_TraceVar2(\fIinterp, name1, name2, flags, proc, clientData\fB)\fR
+.sp
+\fBTcl_UntraceVar(\fIinterp, varName, flags, proc, clientData\fB)\fR
+.sp
+\fBTcl_UntraceVar2(\fIinterp, name1, name2, flags, proc, clientData\fB)\fR
+.sp
+ClientData
+\fBTcl_VarTraceInfo(\fIinterp, varName, flags, proc, prevClientData\fB)\fR
+.sp
+ClientData
+\fBTcl_VarTraceInfo2(\fIinterp, name1, name2, flags, proc, prevClientData\fB)\fR
+.SH ARGUMENTS
+.AS Tcl_VarTraceProc prevClientData
+.AP Tcl_Interp *interp in
+Interpreter containing variable.
+.AP "const char" *varName in
+Name of variable.  May refer to a scalar variable, to
+an array variable with no index, or to an array variable
+with a parenthesized index.
+.AP int flags in
+OR-ed combination of the values \fBTCL_TRACE_READS\fR,
+\fBTCL_TRACE_WRITES\fR, \fBTCL_TRACE_UNSETS\fR, \fBTCL_TRACE_ARRAY\fR,
+\fBTCL_GLOBAL_ONLY\fR, \fBTCL_NAMESPACE_ONLY\fR,
+\fBTCL_TRACE_RESULT_DYNAMIC\fR and \fBTCL_TRACE_RESULT_OBJECT\fR.
+Not all flags are used by all
+procedures.  See below for more information.
+.AP Tcl_VarTraceProc *proc in
+Procedure to invoke whenever one of the traced operations occurs.
+.AP ClientData clientData in
+Arbitrary one-word value to pass to \fIproc\fR.
+.AP "const char" *name1 in
+Name of scalar or array variable (without array index).
+.AP "const char" *name2 in
+For a trace on an element of an array, gives the index of the
+element.  For traces on scalar variables or on whole arrays,
+is NULL.
+.AP ClientData prevClientData in
+If non-NULL, gives last value returned by \fBTcl_VarTraceInfo\fR or
+\fBTcl_VarTraceInfo2\fR, so this call will return information about
+next trace.  If NULL, this call will return information about first
+trace.
+.BE
+.SH DESCRIPTION
+.PP
+\fBTcl_TraceVar\fR allows a C procedure to monitor and control
+access to a Tcl variable, so that the C procedure is invoked
+whenever the variable is read or written or unset.
+If the trace is created successfully then \fBTcl_TraceVar\fR returns
+\fBTCL_OK\fR.  If an error occurred (e.g. \fIvarName\fR specifies an element
+of an array, but the actual variable is not an array) then \fBTCL_ERROR\fR
+is returned and an error message is left in the interpreter's result.
+.PP
+The \fIflags\fR argument to \fBTcl_TraceVar\fR indicates when the
+trace procedure is to be invoked and provides information
+for setting up the trace.  It consists of an OR-ed combination
+of any of the following values:
+.TP
+\fBTCL_GLOBAL_ONLY\fR
+Normally, the variable will be looked up at the current level of
+procedure call;  if this bit is set then the variable will be looked
+up at global level, ignoring any active procedures.
+.TP
+\fBTCL_NAMESPACE_ONLY\fR
+Normally, the variable will be looked up at the current level of
+procedure call;  if this bit is set then the variable will be looked
+up in the current namespace, ignoring any active procedures.
+.TP
+\fBTCL_TRACE_READS\fR
+Invoke \fIproc\fR whenever an attempt is made to read the variable.
+.TP
+\fBTCL_TRACE_WRITES\fR
+Invoke \fIproc\fR whenever an attempt is made to modify the variable.
+.TP
+\fBTCL_TRACE_UNSETS\fR
+Invoke \fIproc\fR whenever the variable is unset.
+A variable may be unset either explicitly by an \fBunset\fR command,
+or implicitly when a procedure returns (its local variables are
+automatically unset) or when the interpreter is deleted (all
+variables are automatically unset).
+.TP
+\fBTCL_TRACE_ARRAY\fR
+Invoke \fIproc\fR whenever the array command is invoked.
+This gives the trace procedure a chance to update the array before
+array names or array get is called.  Note that this is called
+before an array set, but that will trigger write traces.
+.TP
+\fBTCL_TRACE_RESULT_DYNAMIC\fR
+The result of invoking the \fIproc\fR is a dynamically allocated
+string that will be released by the Tcl library via a call to
+\fBckfree\fR.  Must not be specified at the same time as
+\fBTCL_TRACE_RESULT_OBJECT\fR.
+.TP
+\fBTCL_TRACE_RESULT_OBJECT\fR
+The result of invoking the \fIproc\fR is a Tcl_Obj* (cast to a char*)
+with a reference count of at least one.  The ownership of that
+reference will be transferred to the Tcl core for release (when the
+core has finished with it) via a call to \fBTcl_DecrRefCount\fR.  Must
+not be specified at the same time as \fBTCL_TRACE_RESULT_DYNAMIC\fR.
+.PP
+Whenever one of the specified operations occurs on the variable,
+\fIproc\fR will be invoked.
+It should have arguments and result that match the type
+\fBTcl_VarTraceProc\fR:
+.PP
+.CS
+typedef char *\fBTcl_VarTraceProc\fR(
+        ClientData \fIclientData\fR,
+        Tcl_Interp *\fIinterp\fR,
+        char *\fIname1\fR,
+        char *\fIname2\fR,
+        int \fIflags\fR);
+.CE
+.PP
+The \fIclientData\fR and \fIinterp\fR parameters will
+have the same values as those passed to \fBTcl_TraceVar\fR when the
+trace was created.
+\fIClientData\fR typically points to an application-specific
+data structure that describes what to do when \fIproc\fR
+is invoked.
+\fIName1\fR and \fIname2\fR give the name of the traced variable
+in the normal two-part form (see the description of \fBTcl_TraceVar2\fR
+below for details).
+\fIFlags\fR is an OR-ed combination of bits providing several
+pieces of information.
+One of the bits \fBTCL_TRACE_READS\fR, \fBTCL_TRACE_WRITES\fR,
+\fBTCL_TRACE_ARRAY\fR, or \fBTCL_TRACE_UNSETS\fR
+will be set in \fIflags\fR to indicate which operation is being performed
+on the variable.
+The bit \fBTCL_GLOBAL_ONLY\fR will be set whenever the variable being
+accessed is a global one not accessible from the current level of
+procedure call:  the trace procedure will need to pass this flag
+back to variable-related procedures like \fBTcl_GetVar\fR if it
+attempts to access the variable.
+The bit \fBTCL_NAMESPACE_ONLY\fR will be set whenever the variable being
+accessed is a namespace one not accessible from the current level of
+procedure call:  the trace procedure will need to pass this flag
+back to variable-related procedures like \fBTcl_GetVar\fR if it
+attempts to access the variable.
+The bit \fBTCL_TRACE_DESTROYED\fR will be set in \fIflags\fR if the trace is
+about to be destroyed;  this information may be useful to \fIproc\fR
+so that it can clean up its own internal data structures (see
+the section \fBTCL_TRACE_DESTROYED\fR below for more details).
+Lastly, the bit \fBTCL_INTERP_DESTROYED\fR will be set if the entire
+interpreter is being destroyed.
+When this bit is set, \fIproc\fR must be especially careful in
+the things it does (see the section \fBTCL_INTERP_DESTROYED\fR below).
+The trace procedure's return value should normally be NULL;  see
+\fBERROR RETURNS\fR below for information on other possibilities.
+.PP
+\fBTcl_UntraceVar\fR may be used to remove a trace.
+If the variable specified by \fIinterp\fR, \fIvarName\fR, and \fIflags\fR
+has a trace set with \fIflags\fR, \fIproc\fR, and
+\fIclientData\fR, then the corresponding trace is removed.
+If no such trace exists, then the call to \fBTcl_UntraceVar\fR
+has no effect.
+The same bits are valid for \fIflags\fR as for calls to \fBTcl_TraceVar\fR.
+.PP
+\fBTcl_VarTraceInfo\fR may be used to retrieve information about
+traces set on a given variable.
+The return value from \fBTcl_VarTraceInfo\fR is the \fIclientData\fR
+associated with a particular trace.
+The trace must be on the variable specified by the \fIinterp\fR,
+\fIvarName\fR, and \fIflags\fR arguments (only the \fBTCL_GLOBAL_ONLY\fR and
+\fBTCL_NAMESPACE_ONLY\fR bits from \fIflags\fR is used;  other bits are
+ignored) and its trace procedure must the same as the \fIproc\fR
+argument.
+If the \fIprevClientData\fR argument is NULL then the return
+value corresponds to the first (most recently created) matching
+trace, or NULL if there are no matching traces.
+If the \fIprevClientData\fR argument is not NULL, then it should
+be the return value from a previous call to \fBTcl_VarTraceInfo\fR.
+In this case, the new return value will correspond to the next
+matching trace after the one whose \fIclientData\fR matches
+\fIprevClientData\fR, or NULL if no trace matches \fIprevClientData\fR
+or if there are no more matching traces after it.
+This mechanism makes it possible to step through all of the
+traces for a given variable that have the same \fIproc\fR.
+.SH "TWO-PART NAMES"
+.PP
+The procedures \fBTcl_TraceVar2\fR, \fBTcl_UntraceVar2\fR, and
+\fBTcl_VarTraceInfo2\fR are identical to \fBTcl_TraceVar\fR,
+\fBTcl_UntraceVar\fR, and \fBTcl_VarTraceInfo\fR, respectively,
+except that the name of the variable consists of two parts.
+\fIName1\fR gives the name of a scalar variable or array,
+and \fIname2\fR gives the name of an element within an array.
+When \fIname2\fR is NULL,
+\fIname1\fR may contain both an array and an element name:
+if the name contains an open parenthesis and ends with a
+close parenthesis, then the value between the parentheses is
+treated as an element name (which can have any string value) and
+the characters before the first open
+parenthesis are treated as the name of an array variable.
+If \fIname2\fR is NULL and \fIname1\fR does not refer
+to an array element it means that either the variable is
+a scalar or the trace is to be set on the entire array rather
+than an individual element (see WHOLE-ARRAY TRACES below for
+more information).
+.SH "ACCESSING VARIABLES DURING TRACES"
+.PP
+During read, write, and array traces, the
+trace procedure can read, write, or unset the traced
+variable using \fBTcl_GetVar2\fR, \fBTcl_SetVar2\fR, and
+other procedures.
+While \fIproc\fR is executing, traces are temporarily disabled
+for the variable, so that calls to \fBTcl_GetVar2\fR and
+\fBTcl_SetVar2\fR will not cause \fIproc\fR or other trace procedures
+to be invoked again.
+Disabling only occurs for the variable whose trace procedure
+is active;  accesses to other variables will still be traced.
+However, if a variable is unset during a read or write trace then unset
+traces will be invoked.
+.PP
+During unset traces the variable has already been completely
+expunged.
+It is possible for the trace procedure to read or write the
+variable, but this will be a new version of the variable.
+Traces are not disabled during unset traces as they are for
+read and write traces, but existing traces have been removed
+from the variable before any trace procedures are invoked.
+If new traces are set by unset trace procedures, these traces
+will be invoked on accesses to the variable by the trace
+procedures.
+.SH "CALLBACK TIMING"
+.PP
+When read tracing has been specified for a variable, the trace
+procedure will be invoked whenever the variable's value is
+read.  This includes \fBset\fR Tcl commands, \fB$\fR-notation
+in Tcl commands, and invocations of the \fBTcl_GetVar\fR
+and \fBTcl_GetVar2\fR procedures.
+\fIProc\fR is invoked just before the variable's value is
+returned.
+It may modify the value of the variable to affect what
+is returned by the traced access.
+If it unsets the variable then the access will return an error
+just as if the variable never existed.
+.PP
+When write tracing has been specified for a variable, the
+trace procedure will be invoked whenever the variable's value
+is modified.  This includes \fBset\fR commands,
+commands that modify variables as side effects (such as
+\fBcatch\fR and \fBscan\fR), and calls to the \fBTcl_SetVar\fR
+and \fBTcl_SetVar2\fR procedures).
+\fIProc\fR will be invoked after the variable's value has been
+modified, but before the new value of the variable has been
+returned.
+It may modify the value of the variable to override the change
+and to determine the value actually returned by the traced
+access.
+If it deletes the variable then the traced access will return
+an empty string.
+.PP
+When array tracing has been specified, the trace procedure
+will be invoked at the beginning of the array command implementation,
+before any of the operations like get, set, or names have been invoked.
+The trace procedure can modify the array elements with \fBTcl_SetVar\fR
+and \fBTcl_SetVar2\fR.
+.PP
+When unset tracing has been specified, the trace procedure
+will be invoked whenever the variable is destroyed.
+The traces will be called after the variable has been
+completely unset.
+.SH "WHOLE-ARRAY TRACES"
+.PP
+If a call to \fBTcl_TraceVar\fR or \fBTcl_TraceVar2\fR specifies
+the name of an array variable without an index into the array,
+then the trace will be set on the array as a whole.
+This means that \fIproc\fR will be invoked whenever any
+element of the array is accessed in the ways specified by
+\fIflags\fR.
+When an array is unset, a whole-array trace will be invoked
+just once, with \fIname1\fR equal to the name of the array
+and \fIname2\fR NULL;  it will not be invoked once for each
+element.
+.SH "MULTIPLE TRACES"
+.PP
+It is possible for multiple traces to exist on the same variable.
+When this happens, all of the trace procedures will be invoked on each
+access, in order from most-recently-created to least-recently-created.
+When there exist whole-array traces for an array as well as
+traces on individual elements, the whole-array traces are invoked
+before the individual-element traces.
+If a read or write trace unsets the variable then all of the unset
+traces will be invoked but the remainder of the read and write traces
+will be skipped.
+.SH "ERROR RETURNS"
+.PP
+Under normal conditions trace procedures should return NULL, indicating
+successful completion.
+If \fIproc\fR returns a non-NULL value it signifies that an
+error occurred.
+The return value must be a pointer to a static character string
+containing an error message,
+unless (\fIexactly\fR one of) the \fBTCL_TRACE_RESULT_DYNAMIC\fR and
+\fBTCL_TRACE_RESULT_OBJECT\fR flags is set, which specify that the result is
+either a dynamic string (to be released with \fBckfree\fR) or a
+Tcl_Obj* (cast to char* and to be released with
+\fBTcl_DecrRefCount\fR) containing the error message.
+If a trace procedure returns an error, no further traces are
+invoked for the access and the traced access aborts with the
+given message.
+Trace procedures can use this facility to make variables
+read-only, for example (but note that the value of the variable
+will already have been modified before the trace procedure is
+called, so the trace procedure will have to restore the correct
+value).
+.PP
+The return value from \fIproc\fR is only used during read and
+write tracing.
+During unset traces, the return value is ignored and all relevant
+trace procedures will always be invoked.
+.SH "RESTRICTIONS"
+.PP
+A trace procedure can be called at any time, even when there
+is a partially formed result in the interpreter's result area.  If
+the trace procedure does anything that could damage this result (such
+as calling \fBTcl_Eval\fR) then it must save the original values of
+the interpreter's \fBresult\fR and \fBfreeProc\fR fields and restore
+them before it returns.
+.SH "UNDEFINED VARIABLES"
+.PP
+It is legal to set a trace on an undefined variable.
+The variable will still appear to be undefined until the
+first time its value is set.
+If an undefined variable is traced and then unset, the unset will fail
+with an error
+.PQ "no such variable" "" ,
+but the trace procedure will still be invoked.
+.SH "TCL_TRACE_DESTROYED FLAG"
+.PP
+In an unset callback to \fIproc\fR, the \fBTCL_TRACE_DESTROYED\fR bit
+is set in \fIflags\fR if the trace is being removed as part
+of the deletion.
+Traces on a variable are always removed whenever the variable
+is deleted;  the only time \fBTCL_TRACE_DESTROYED\fR is not set is for
+a whole-array trace invoked when only a single element of an
+array is unset.
+.SH "TCL_INTERP_DESTROYED"
+.PP
+When an interpreter is destroyed, unset traces are called for
+all of its variables.
+The \fBTCL_INTERP_DESTROYED\fR bit will be set in the \fIflags\fR
+argument passed to the trace procedures.
+Trace procedures must be extremely careful in what they do if
+the \fBTCL_INTERP_DESTROYED\fR bit is set.
+It is not safe for the procedures to invoke any Tcl procedures
+on the interpreter, since its state is partially deleted.
+All that trace procedures should do under these circumstances is
+to clean up and free their own internal data structures.
+.SH BUGS
+.PP
+Tcl does not do any error checking to prevent trace procedures
+from misusing the interpreter during traces with \fBTCL_INTERP_DESTROYED\fR
+set.
+.PP
+Array traces are not yet integrated with the Tcl \fBinfo exists\fR command,
+nor is there Tcl-level access to array traces.
+.SH "SEE ALSO"
+trace(n)
+.SH KEYWORDS
+clientData, trace, variable
diff --git a/doc/Translate.3 b/doc/Translate.3
new file mode 100644
index 0000000..38831d3
--- /dev/null
+++ b/doc/Translate.3
@@ -0,0 +1,71 @@
+'\"
+'\" Copyright (c) 1989-1993 The Regents of the University of California.
+'\" Copyright (c) 1994-1998 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH Tcl_TranslateFileName 3 8.1 Tcl "Tcl Library Procedures"
+.so man.macros
+.BS
+.SH NAME
+Tcl_TranslateFileName \- convert file name to native form and replace tilde with home directory
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+char *
+\fBTcl_TranslateFileName\fR(\fIinterp\fR, \fIname\fR, \fIbufferPtr\fR)
+.SH ARGUMENTS
+.AS Tcl_DString *bufferPtr in/out
+.AP Tcl_Interp *interp in
+Interpreter in which to report an error, if any.
+.AP "const char" *name in
+File name, which may start with a
+.QW ~ .
+.AP Tcl_DString *bufferPtr in/out
+If needed, this dynamic string is used to store the new file name.
+At the time of the call it should be uninitialized or free.  The
+caller must eventually call \fBTcl_DStringFree\fR to free up
+anything stored here.
+.BE
+.SH DESCRIPTION
+.PP
+This utility procedure translates a file name to a platform-specific form
+which, after being converted to the appropriate encoding, is suitable for
+passing to the local operating system.  In particular, it converts
+network names into native form and does tilde substitution.
+.PP
+However, with the advent of the newer \fBTcl_FSGetNormalizedPath\fR and
+\fBTcl_FSGetNativePath\fR, there is no longer any need to use this
+procedure.  In particular, \fBTcl_FSGetNativePath\fR performs all the
+necessary translation and encoding conversion, is virtual-filesystem
+aware, and caches the native result for faster repeated calls.
+Finally \fBTcl_FSGetNativePath\fR does not require you to free anything
+afterwards.
+.PP
+If
+\fBTcl_TranslateFileName\fR has to do tilde substitution or translate
+the name then it uses
+the dynamic string at \fI*bufferPtr\fR to hold the new string it
+generates.
+After \fBTcl_TranslateFileName\fR returns a non-NULL result, the caller must
+eventually invoke \fBTcl_DStringFree\fR to free any information
+placed in \fI*bufferPtr\fR.  The caller need not know whether or
+not \fBTcl_TranslateFileName\fR actually used the string;  \fBTcl_TranslateFileName\fR
+initializes \fI*bufferPtr\fR even if it does not use it, so the call to
+\fBTcl_DStringFree\fR will be safe in either case.
+.PP
+If an error occurs (e.g. because there was no user by the given
+name) then NULL is returned and an error message will be left
+in the interpreter's result.
+When an error occurs, \fBTcl_TranslateFileName\fR
+frees the dynamic string itself so that the caller need not call
+\fBTcl_DStringFree\fR.
+.PP
+The caller is responsible for making sure that the interpreter's result
+has its default empty value when \fBTcl_TranslateFileName\fR is invoked.
+.SH "SEE ALSO"
+filename(n)
+.SH KEYWORDS
+file name, home directory, tilde, translate, user
diff --git a/doc/UniCharIsAlpha.3 b/doc/UniCharIsAlpha.3
new file mode 100644
index 0000000..2336c34
--- /dev/null
+++ b/doc/UniCharIsAlpha.3
@@ -0,0 +1,91 @@
+'\"
+'\" Copyright (c) 1997 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH Tcl_UniCharIsAlpha 3 "8.1" Tcl "Tcl Library Procedures"
+.so man.macros
+.BS
+.SH NAME
+Tcl_UniCharIsAlnum, Tcl_UniCharIsAlpha, Tcl_UniCharIsControl, Tcl_UniCharIsDigit, Tcl_UniCharIsGraph, Tcl_UniCharIsLower, Tcl_UniCharIsPrint, Tcl_UniCharIsPunct, Tcl_UniCharIsSpace, Tcl_UniCharIsUpper, Tcl_UniCharIsWordChar \- routines for classification of Tcl_UniChar characters
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+int
+\fBTcl_UniCharIsAlnum\fR(\fIch\fR)
+.sp
+int
+\fBTcl_UniCharIsAlpha\fR(\fIch\fR)
+.sp
+int
+\fBTcl_UniCharIsControl\fR(\fIch\fR)
+.sp
+int
+\fBTcl_UniCharIsDigit\fR(\fIch\fR)
+.sp
+int
+\fBTcl_UniCharIsGraph\fR(\fIch\fR)
+.sp
+int
+\fBTcl_UniCharIsLower\fR(\fIch\fR)
+.sp
+int
+\fBTcl_UniCharIsPrint\fR(\fIch\fR)
+.sp
+int
+\fBTcl_UniCharIsPunct\fR(\fIch\fR)
+.sp
+int
+\fBTcl_UniCharIsSpace\fR(\fIch\fR)
+.sp
+int
+\fBTcl_UniCharIsUpper\fR(\fIch\fR)
+.sp
+int
+\fBTcl_UniCharIsWordChar\fR(\fIch\fR)
+.SH ARGUMENTS
+.AS int ch
+.AP int ch in
+The Tcl_UniChar to be examined.
+.BE
+
+.SH DESCRIPTION
+.PP
+All of the routines described examine Tcl_UniChars and return a
+boolean value. A non-zero return value means that the character does
+belong to the character class associated with the called routine. The
+rest of this document just describes the character classes associated
+with the various routines.
+.PP
+Note: A Tcl_UniChar is a Unicode character represented as an unsigned,
+fixed-size quantity.
+
+.SH "CHARACTER CLASSES"
+.PP
+\fBTcl_UniCharIsAlnum\fR tests if the character is an alphanumeric Unicode character.
+.PP
+\fBTcl_UniCharIsAlpha\fR tests if the character is an alphabetic Unicode character.
+.PP
+\fBTcl_UniCharIsControl\fR tests if the character is a Unicode control character.
+.PP
+\fBTcl_UniCharIsDigit\fR tests if the character is a numeric Unicode character.
+.PP
+\fBTcl_UniCharIsGraph\fR tests if the character is any Unicode print character except space.
+.PP
+\fBTcl_UniCharIsLower\fR tests if the character is a lowercase Unicode character.
+.PP
+\fBTcl_UniCharIsPrint\fR tests if the character is a Unicode print character.
+.PP
+\fBTcl_UniCharIsPunct\fR tests if the character is a Unicode punctuation character.
+.PP
+\fBTcl_UniCharIsSpace\fR tests if the character is a whitespace Unicode character.
+.PP
+\fBTcl_UniCharIsUpper\fR tests if the character is an uppercase Unicode character.
+.PP
+\fBTcl_UniCharIsWordChar\fR tests if the character is alphanumeric or
+a connector punctuation mark.
+
+.SH KEYWORDS
+unicode, classification
diff --git a/doc/UpVar.3 b/doc/UpVar.3
new file mode 100644
index 0000000..9e17ed5
--- /dev/null
+++ b/doc/UpVar.3
@@ -0,0 +1,74 @@
+'\"
+'\" Copyright (c) 1994 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH Tcl_UpVar 3 7.4 Tcl "Tcl Library Procedures"
+.so man.macros
+.BS
+.SH NAME
+Tcl_UpVar, Tcl_UpVar2 \- link one variable to another
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+int
+\fBTcl_UpVar(\fIinterp, frameName, sourceName, destName, flags\fB)\fR
+.sp
+int
+\fBTcl_UpVar2(\fIinterp, frameName, name1, name2, destName, flags\fB)\fR
+.SH ARGUMENTS
+.AS "const char" *sourceName
+.AP Tcl_Interp *interp in
+Interpreter containing variables;  also used for error reporting.
+.AP "const char" *frameName in
+Identifies the stack frame containing source variable.
+May have any of the forms accepted by
+the \fBupvar\fR command, such as \fB#0\fR or \fB1\fR.
+.AP "const char" *sourceName in
+Name of source variable, in the frame given by \fIframeName\fR.
+May refer to a scalar variable or to an array variable with a
+parenthesized index.
+.AP "const char" *destName in
+Name of destination variable, which is to be linked to source
+variable so that references to \fIdestName\fR
+refer to the other variable.  Must not currently exist except as
+an upvar-ed variable.
+.AP int flags in
+One of \fBTCL_GLOBAL_ONLY\fR, \fBTCL_NAMESPACE_ONLY\fR or 0;  if non-zero,
+then \fIdestName\fR is a global or namespace variable;  otherwise it is
+local to the current procedure (or current namespace if no procedure is
+active).
+.AP "const char" *name1 in
+First part of source variable's name (scalar name, or name of array
+without array index).
+.AP "const char" *name2 in
+If source variable is an element of an array, gives the index of the element.
+For scalar source variables, is NULL.
+.BE
+
+.SH DESCRIPTION
+.PP
+\fBTcl_UpVar\fR and \fBTcl_UpVar2\fR provide the same functionality
+as the \fBupvar\fR command:  they make a link from a source variable
+to a destination variable, so that references to the destination are
+passed transparently through to the source.
+The name of the source variable may be specified either as a single
+string such as \fBxyx\fR or \fBa(24)\fR (by calling \fBTcl_UpVar\fR)
+or in two parts where the array name has been separated from the
+element name (by calling \fBTcl_UpVar2\fR).
+The destination variable name is specified in a single string;  it
+may not be an array element.
+.PP
+Both procedures return either \fBTCL_OK\fR or \fBTCL_ERROR\fR, and they
+leave an error message in the interpreter's result if an error occurs.
+.PP
+As with the \fBupvar\fR command, the source variable need not exist;
+if it does exist, unsetting it later does not destroy the link.  The
+destination variable may exist at the time of the call, but if so
+it must exist as a linked variable.
+
+.SH KEYWORDS
+linked variable, upvar, variable
diff --git a/doc/Utf.3 b/doc/Utf.3
new file mode 100644
index 0000000..378c806
--- /dev/null
+++ b/doc/Utf.3
@@ -0,0 +1,259 @@
+'\"
+'\" Copyright (c) 1997 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH Utf 3 "8.1" Tcl "Tcl Library Procedures"
+.so man.macros
+.BS
+.SH NAME
+Tcl_UniChar, Tcl_UniCharToUtf, Tcl_UtfToUniChar, Tcl_UniCharToUtfDString, Tcl_UtfToUniCharDString, Tcl_UniCharLen, Tcl_UniCharNcmp, Tcl_UniCharNcasecmp, Tcl_UniCharCaseMatch, Tcl_UtfNcmp, Tcl_UtfNcasecmp, Tcl_UtfCharComplete, Tcl_NumUtfChars, Tcl_UtfFindFirst, Tcl_UtfFindLast, Tcl_UtfNext, Tcl_UtfPrev, Tcl_UniCharAtIndex, Tcl_UtfAtIndex, Tcl_UtfBackslash \- routines for manipulating UTF-8 strings
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+typedef ... \fBTcl_UniChar\fR;
+.sp
+int
+\fBTcl_UniCharToUtf\fR(\fIch, buf\fR)
+.sp
+int
+\fBTcl_UtfToUniChar\fR(\fIsrc, chPtr\fR)
+.sp
+char *
+\fBTcl_UniCharToUtfDString\fR(\fIuniStr, uniLength, dsPtr\fR)
+.sp
+Tcl_UniChar *
+\fBTcl_UtfToUniCharDString\fR(\fIsrc, length, dsPtr\fR)
+.sp
+int
+\fBTcl_UniCharLen\fR(\fIuniStr\fR)
+.sp
+int
+\fBTcl_UniCharNcmp\fR(\fIucs, uct, numChars\fR)
+.sp
+int
+\fBTcl_UniCharNcasecmp\fR(\fIucs, uct, numChars\fR)
+.sp
+int
+\fBTcl_UniCharCaseMatch\fR(\fIuniStr, uniPattern, nocase\fR)
+.sp
+int
+\fBTcl_UtfNcmp\fR(\fIcs, ct, numChars\fR)
+.sp
+int
+\fBTcl_UtfNcasecmp\fR(\fIcs, ct, numChars\fR)
+.sp
+int
+\fBTcl_UtfCharComplete\fR(\fIsrc, length\fR)
+.sp
+int
+\fBTcl_NumUtfChars\fR(\fIsrc, length\fR)
+.sp
+const char *
+\fBTcl_UtfFindFirst\fR(\fIsrc, ch\fR)
+.sp
+const char *
+\fBTcl_UtfFindLast\fR(\fIsrc, ch\fR)
+.sp
+const char *
+\fBTcl_UtfNext\fR(\fIsrc\fR)
+.sp
+const char *
+\fBTcl_UtfPrev\fR(\fIsrc, start\fR)
+.sp
+Tcl_UniChar
+\fBTcl_UniCharAtIndex\fR(\fIsrc, index\fR)
+.sp
+const char *
+\fBTcl_UtfAtIndex\fR(\fIsrc, index\fR)
+.sp
+int
+\fBTcl_UtfBackslash\fR(\fIsrc, readPtr, dst\fR)
+.SH ARGUMENTS
+.AS "const Tcl_UniChar" *uniPattern in/out
+.AP char *buf out
+Buffer in which the UTF-8 representation of the Tcl_UniChar is stored.  At most
+\fBTCL_UTF_MAX\fR bytes are stored in the buffer.
+.AP int ch in
+The Tcl_UniChar to be converted or examined.
+.AP Tcl_UniChar *chPtr out
+Filled with the Tcl_UniChar represented by the head of the UTF-8 string.
+.AP "const char" *src in
+Pointer to a UTF-8 string.
+.AP "const char" *cs in
+Pointer to a UTF-8 string.
+.AP "const char" *ct in
+Pointer to a UTF-8 string.
+.AP "const Tcl_UniChar" *uniStr in
+A null-terminated Unicode string.
+.AP "const Tcl_UniChar" *ucs in
+A null-terminated Unicode string.
+.AP "const Tcl_UniChar" *uct in
+A null-terminated Unicode string.
+.AP "const Tcl_UniChar" *uniPattern in
+A null-terminated Unicode string.
+.AP int length in
+The length of the UTF-8 string in bytes (not UTF-8 characters).  If
+negative, all bytes up to the first null byte are used.
+.AP int uniLength in
+The length of the Unicode string in characters.  Must be greater than or
+equal to 0.
+.AP "Tcl_DString" *dsPtr in/out
+A pointer to a previously initialized \fBTcl_DString\fR.
+.AP "unsigned long" numChars in
+The number of characters to compare.
+.AP "const char" *start in
+Pointer to the beginning of a UTF-8 string.
+.AP int index in
+The index of a character (not byte) in the UTF-8 string.
+.AP int *readPtr out
+If non-NULL, filled with the number of bytes in the backslash sequence,
+including the backslash character.
+.AP char *dst out
+Buffer in which the bytes represented by the backslash sequence are stored.
+At most \fBTCL_UTF_MAX\fR bytes are stored in the buffer.
+.AP int nocase in
+Specifies whether the match should be done case-sensitive (0) or
+case-insensitive (1).
+.BE
+
+.SH DESCRIPTION
+.PP
+These routines convert between UTF-8 strings and Tcl_UniChars.  A
+Tcl_UniChar is a Unicode character represented as an unsigned, fixed-size
+quantity.  A UTF-8 character is a Unicode character represented as
+a varying-length sequence of up to \fBTCL_UTF_MAX\fR bytes.  A multibyte UTF-8
+sequence consists of a lead byte followed by some number of trail bytes.
+.PP
+\fBTCL_UTF_MAX\fR is the maximum number of bytes that it takes to
+represent one Unicode character in the UTF-8 representation.
+.PP
+\fBTcl_UniCharToUtf\fR stores the Tcl_UniChar \fIch\fR as a UTF-8 string
+in starting at \fIbuf\fR.  The return value is the number of bytes stored
+in \fIbuf\fR.
+.PP
+\fBTcl_UtfToUniChar\fR reads one UTF-8 character starting at \fIsrc\fR
+and stores it as a Tcl_UniChar in \fI*chPtr\fR.  The return value is the
+number of bytes read from \fIsrc\fR.  The caller must ensure that the
+source buffer is long enough such that this routine does not run off the
+end and dereference non-existent or random memory; if the source buffer
+is known to be null-terminated, this will not happen.  If the input is
+not in proper UTF-8 format, \fBTcl_UtfToUniChar\fR will store the first
+byte of \fIsrc\fR in \fI*chPtr\fR as a Tcl_UniChar between 0x0000 and
+0x00ff and return 1.
+.PP
+\fBTcl_UniCharToUtfDString\fR converts the given Unicode string
+to UTF-8, storing the result in a previously initialized \fBTcl_DString\fR.
+You must specify \fIuniLength\fR, the length of the given Unicode string.
+The return value is a pointer to the UTF-8 representation of the
+Unicode string.  Storage for the return value is appended to the
+end of the \fBTcl_DString\fR.
+.PP
+\fBTcl_UtfToUniCharDString\fR converts the given UTF-8 string to Unicode,
+storing the result in the previously initialized \fBTcl_DString\fR.
+In the argument \fIlength\fR, you may either specify the length of
+the given UTF-8 string in bytes or
+.QW \-1 ,
+in which case \fBTcl_UtfToUniCharDString\fR uses \fBstrlen\fR to
+calculate the length.  The return value is a pointer to the Unicode
+representation of the UTF-8 string.  Storage for the return value
+is appended to the end of the \fBTcl_DString\fR.  The Unicode string
+is terminated with a Unicode null character.
+.PP
+\fBTcl_UniCharLen\fR corresponds to \fBstrlen\fR for Unicode
+characters.  It accepts a null-terminated Unicode string and returns
+the number of Unicode characters (not bytes) in that string.
+.PP
+\fBTcl_UniCharNcmp\fR and \fBTcl_UniCharNcasecmp\fR correspond to
+\fBstrncmp\fR and \fBstrncasecmp\fR, respectively, for Unicode characters.
+They accept two null-terminated Unicode strings and the number of characters
+to compare.  Both strings are assumed to be at least \fInumChars\fR characters
+long. \fBTcl_UniCharNcmp\fR  compares the two strings character-by-character
+according to the Unicode character ordering.  It returns an integer greater
+than, equal to, or less than 0 if the first string is greater than, equal
+to, or less than the second string respectively.  \fBTcl_UniCharNcasecmp\fR
+is the Unicode case insensitive version.
+.PP
+\fBTcl_UniCharCaseMatch\fR is the Unicode equivalent to
+\fBTcl_StringCaseMatch\fR.  It accepts a null-terminated Unicode string,
+a Unicode pattern, and a boolean value specifying whether the match should
+be case sensitive and returns whether the string matches the pattern.
+.PP
+\fBTcl_UtfNcmp\fR corresponds to \fBstrncmp\fR for UTF-8 strings. It
+accepts two null-terminated UTF-8 strings and the number of characters
+to compare.  (Both strings are assumed to be at least \fInumChars\fR
+characters long.)  \fBTcl_UtfNcmp\fR compares the two strings
+character-by-character according to the Unicode character ordering.
+It returns an integer greater than, equal to, or less than 0 if the
+first string is greater than, equal to, or less than the second string
+respectively.
+.PP
+\fBTcl_UtfNcasecmp\fR corresponds to \fBstrncasecmp\fR for UTF-8
+strings.  It is similar to \fBTcl_UtfNcmp\fR except comparisons ignore
+differences in case when comparing upper, lower or title case
+characters.
+.PP
+\fBTcl_UtfCharComplete\fR returns 1 if the source UTF-8 string \fIsrc\fR
+of \fIlength\fR bytes is long enough to be decoded by
+\fBTcl_UtfToUniChar\fR, or 0 otherwise.  This function does not guarantee
+that the UTF-8 string is properly formed.  This routine is used by
+procedures that are operating on a byte at a time and need to know if a
+full Tcl_UniChar has been seen.
+.PP
+\fBTcl_NumUtfChars\fR corresponds to \fBstrlen\fR for UTF-8 strings.  It
+returns the number of Tcl_UniChars that are represented by the UTF-8 string
+\fIsrc\fR.  The length of the source string is \fIlength\fR bytes.  If the
+length is negative, all bytes up to the first null byte are used.
+.PP
+\fBTcl_UtfFindFirst\fR corresponds to \fBstrchr\fR for UTF-8 strings.  It
+returns a pointer to the first occurrence of the Tcl_UniChar \fIch\fR
+in the null-terminated UTF-8 string \fIsrc\fR.  The null terminator is
+considered part of the UTF-8 string.
+.PP
+\fBTcl_UtfFindLast\fR corresponds to \fBstrrchr\fR for UTF-8 strings.  It
+returns a pointer to the last occurrence of the Tcl_UniChar \fIch\fR
+in the null-terminated UTF-8 string \fIsrc\fR.  The null terminator is
+considered part of the UTF-8 string.
+.PP
+Given \fIsrc\fR, a pointer to some location in a UTF-8 string,
+\fBTcl_UtfNext\fR returns a pointer to the next UTF-8 character in the
+string.  The caller must not ask for the next character after the last
+character in the string if the string is not terminated by a null
+character.
+.PP
+Given \fIsrc\fR, a pointer to some location in a UTF-8 string (or to a
+null byte immediately following such a string), \fBTcl_UtfPrev\fR
+returns a pointer to the closest preceding byte that starts a UTF-8
+character.
+This function will not back up to a position before \fIstart\fR,
+the start of the UTF-8 string.  If \fIsrc\fR was already at \fIstart\fR, the
+return value will be \fIstart\fR.
+.PP
+\fBTcl_UniCharAtIndex\fR corresponds to a C string array dereference or the
+Pascal Ord() function.  It returns the Tcl_UniChar represented at the
+specified character (not byte) \fIindex\fR in the UTF-8 string
+\fIsrc\fR.  The source string must contain at least \fIindex\fR
+characters.  Behavior is undefined if a negative \fIindex\fR is given.
+.PP
+\fBTcl_UtfAtIndex\fR returns a pointer to the specified character (not
+byte) \fIindex\fR in the UTF-8 string \fIsrc\fR.  The source string must
+contain at least \fIindex\fR characters.  This is equivalent to calling
+\fBTcl_UtfNext\fR \fIindex\fR times.  If a negative \fIindex\fR is given,
+the return pointer points to the first character in the source string.
+.PP
+\fBTcl_UtfBackslash\fR is a utility procedure used by several of the Tcl
+commands.  It parses a backslash sequence and stores the properly formed
+UTF-8 character represented by the backslash sequence in the output
+buffer \fIdst\fR.  At most \fBTCL_UTF_MAX\fR bytes are stored in the buffer.
+\fBTcl_UtfBackslash\fR modifies \fI*readPtr\fR to contain the number
+of bytes in the backslash sequence, including the backslash character.
+The return value is the number of bytes stored in the output buffer.
+.PP
+See the \fBTcl\fR manual entry for information on the valid backslash
+sequences.  All of the sequences described in the Tcl manual entry are
+supported by \fBTcl_UtfBackslash\fR.
+
+.SH KEYWORDS
+utf, unicode, backslash
diff --git a/doc/WrongNumArgs.3 b/doc/WrongNumArgs.3
new file mode 100644
index 0000000..93e2ebb
--- /dev/null
+++ b/doc/WrongNumArgs.3
@@ -0,0 +1,79 @@
+'\"
+'\" Copyright (c) 1994-1997 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH Tcl_WrongNumArgs 3 8.0 Tcl "Tcl Library Procedures"
+.so man.macros
+.BS
+.SH NAME
+Tcl_WrongNumArgs \- generate standard error message for wrong number of arguments
+.SH SYNOPSIS
+.nf
+\fB#include <tcl.h>\fR
+.sp
+\fBTcl_WrongNumArgs\fR(\fIinterp, objc, objv, message\fR)
+.SH ARGUMENTS
+.AS "Tcl_Obj *const" *message
+.AP Tcl_Interp interp in
+Interpreter in which error will be reported: error message gets stored
+in its result value.
+.AP int objc in
+Number of leading arguments from \fIobjv\fR to include in error
+message.
+.AP "Tcl_Obj *const" objv[] in
+Arguments to command that had the wrong number of arguments.
+.AP "const char" *message in
+Additional error information to print after leading arguments
+from \fIobjv\fR.  This typically gives the acceptable syntax
+of the command.  This argument may be NULL.
+.BE
+.SH DESCRIPTION
+.PP
+\fBTcl_WrongNumArgs\fR is a utility procedure that is invoked by
+command procedures when they discover that they have received the
+wrong number of arguments.  \fBTcl_WrongNumArgs\fR generates a
+standard error message and stores it in the result value of
+\fIinterp\fR.  The message includes the \fIobjc\fR initial
+elements of \fIobjv\fR plus \fImessage\fR.  For example, if
+\fIobjv\fR consists of the values \fBfoo\fR and \fBbar\fR,
+\fIobjc\fR is 1, and \fImessage\fR is
+.QW "\fBfileName count\fR"
+then \fIinterp\fR's result value will be set to the following
+string:
+.PP
+.CS
+wrong # args: should be "foo fileName count"
+.CE
+.PP
+If \fIobjc\fR is 2, the result will be set to the following string:
+.PP
+.CS
+wrong # args: should be "foo bar fileName count"
+.CE
+.PP
+\fIObjc\fR is usually 1, but may be 2 or more for commands like
+\fBstring\fR and the Tk widget commands, which use the first argument
+as a subcommand.
+.PP
+Some of the values in the \fIobjv\fR array may be abbreviations for
+a subcommand.  The command
+\fBTcl_GetIndexFromObj\fR will convert the abbreviated string value
+into an \fIindexObject\fR.  If an error occurs in the parsing of the
+subcommand we would like to use the full subcommand name rather than
+the abbreviation.  If the \fBTcl_WrongNumArgs\fR command finds any
+\fIindexObjects\fR in the \fIobjv\fR array it will use the full subcommand
+name in the error message instead of the abbreviated name that was
+originally passed in.  Using the above example, let us assume that
+\fIbar\fR is actually an abbreviation for \fIbarfly\fR and the value
+is now an \fIindexObject\fR because it was passed to
+\fBTcl_GetIndexFromObj\fR.  In this case the error message would be:
+.PP
+.CS
+wrong # args: should be "foo barfly fileName count"
+.CE
+.SH "SEE ALSO"
+Tcl_GetIndexFromObj(3)
+.SH KEYWORDS
+command, error message, wrong number of arguments
diff --git a/doc/after.n b/doc/after.n
new file mode 100644
index 0000000..3d0d2c4
--- /dev/null
+++ b/doc/after.n
@@ -0,0 +1,151 @@
+'\"
+'\" Copyright (c) 1990-1994 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH after n 7.5 Tcl "Tcl Built-In Commands"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+after \- Execute a command after a time delay
+.SH SYNOPSIS
+\fBafter \fIms\fR
+.sp
+\fBafter \fIms \fR?\fIscript script script ...\fR?
+.sp
+\fBafter cancel \fIid\fR
+.sp
+\fBafter cancel \fIscript script script ...\fR
+.sp
+\fBafter idle \fR?\fIscript script script ...\fR?
+.sp
+\fBafter info \fR?\fIid\fR?
+.BE
+.SH DESCRIPTION
+.PP
+This command is used to delay execution of the program or to execute
+a command in background sometime in the future.  It has several forms,
+depending on the first argument to the command:
+.TP
+\fBafter \fIms\fR
+.
+\fIMs\fR must be an integer giving a time in milliseconds.
+The command sleeps for \fIms\fR milliseconds and then returns.
+While the command is sleeping the application does not respond to
+events.
+.TP
+\fBafter \fIms \fR?\fIscript script script ...\fR?
+.
+In this form the command returns immediately, but it arranges
+for a Tcl command to be executed \fIms\fR milliseconds later as an
+event handler.
+The command will be executed exactly once, at the given time.
+The delayed command is formed by concatenating all the \fIscript\fR
+arguments in the same fashion as the \fBconcat\fR command.
+The command will be executed at global level (outside the context
+of any Tcl procedure).
+If an error occurs while executing the delayed command then
+the background error will be reported by the command
+registered with \fBinterp bgerror\fR.
+The \fBafter\fR command returns an identifier that can be used
+to cancel the delayed command using \fBafter cancel\fR.
+.TP
+\fBafter cancel \fIid\fR
+.
+Cancels the execution of a delayed command that
+was previously scheduled.
+\fIId\fR indicates which command should be canceled;  it must have
+been the return value from a previous \fBafter\fR command.
+If the command given by \fIid\fR has already been executed then
+the \fBafter cancel\fR command has no effect.
+.TP
+\fBafter cancel \fIscript script ...\fR
+.
+This command also cancels the execution of a delayed command.
+The \fIscript\fR arguments are concatenated together with space
+separators (just as in the \fBconcat\fR command).
+If there is a pending command that matches the string, it is
+canceled and will never be executed;  if no such command is
+currently pending then the \fBafter cancel\fR command has no effect.
+.TP
+\fBafter idle \fIscript \fR?\fIscript script ...\fR?
+.
+Concatenates the \fIscript\fR arguments together with space
+separators (just as in the \fBconcat\fR command), and arranges
+for the resulting script to be evaluated later as an idle callback.
+The script will be run exactly once, the next time the event
+loop is entered and there are no events to process.
+The command returns an identifier that can be used
+to cancel the delayed command using \fBafter cancel\fR.
+If an error occurs while executing the script then the
+background error will be reported by the command
+registered with \fBinterp bgerror\fR.
+.TP
+\fBafter info \fR?\fIid\fR?
+.
+This command returns information about existing event handlers.
+If no \fIid\fR argument is supplied, the command returns
+a list of the identifiers for all existing
+event handlers created by the \fBafter\fR command for this
+interpreter.
+If \fIid\fR is supplied, it specifies an existing handler;
+\fIid\fR must have been the return value from some previous call
+to \fBafter\fR and it must not have triggered yet or been canceled.
+In this case the command returns a list with two elements.
+The first element of the list is the script associated
+with \fIid\fR, and the second element is either
+\fBidle\fR or \fBtimer\fR to indicate what kind of event
+handler it is.
+.LP
+The \fBafter \fIms\fR and \fBafter idle\fR forms of the command
+assume that the application is event driven:  the delayed commands
+will not be executed unless the application enters the event loop.
+In applications that are not normally event-driven, such as
+\fBtclsh\fR, the event loop can be entered with the \fBvwait\fR
+and \fBupdate\fR commands.
+.SH "EXAMPLES"
+This defines a command to make Tcl do nothing at all for \fIN\fR
+seconds:
+.PP
+.CS
+proc sleep {N} {
+    \fBafter\fR [expr {int($N * 1000)}]
+}
+.CE
+.PP
+This arranges for the command \fIwake_up\fR to be run in eight hours
+(providing the event loop is active at that time):
+.PP
+.CS
+\fBafter\fR [expr {1000 * 60 * 60 * 8}] wake_up
+.CE
+.PP
+The following command can be used to do long-running calculations (as
+represented here by \fI::my_calc::one_step\fR, which is assumed to
+return a boolean indicating whether another step should be performed)
+in a step-by-step fashion, though the calculation itself needs to be
+arranged so it can work step-wise.  This technique is extra careful to
+ensure that the event loop is not starved by the rescheduling of
+processing steps (arranging for the next step to be done using an
+already-triggered timer event only when the event queue has been
+drained) and is useful when you want to ensure that a Tk GUI remains
+responsive during a slow task.
+.PP
+.CS
+proc doOneStep {} {
+    if {[::my_calc::one_step]} {
+        \fBafter idle\fR [list \fBafter\fR 0 doOneStep]
+    }
+}
+doOneStep
+.CE
+.SH "SEE ALSO"
+concat(n), interp(n), update(n), vwait(n)
+.SH KEYWORDS
+cancel, delay, idle callback, sleep, time
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/doc/append.n b/doc/append.n
new file mode 100644
index 0000000..e3bf224
--- /dev/null
+++ b/doc/append.n
@@ -0,0 +1,49 @@
+'\"
+'\" Copyright (c) 1993 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH append n "" Tcl "Tcl Built-In Commands"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+append \- Append to variable
+.SH SYNOPSIS
+\fBappend \fIvarName \fR?\fIvalue value value ...\fR?
+.BE
+.SH DESCRIPTION
+.PP
+Append all of the \fIvalue\fR arguments to the current value
+of variable \fIvarName\fR.  If \fIvarName\fR does not exist,
+it is given a value equal to the concatenation of all the
+\fIvalue\fR arguments.
+The result of this command is the new value stored in variable
+\fIvarName\fR.
+This command provides an efficient way to build up long
+variables incrementally.
+For example,
+.QW "\fBappend a $b\fR"
+is much more efficient than
+.QW "\fBset a $a$b\fR"
+if \fB$a\fR is long.
+.SH EXAMPLE
+Building a string of comma-separated numbers piecemeal using a loop.
+.PP
+.CS
+set var 0
+for {set i 1} {$i<=10} {incr i} {
+    \fBappend\fR var "," $i
+}
+puts $var
+# Prints 0,1,2,3,4,5,6,7,8,9,10
+.CE
+.SH "SEE ALSO"
+concat(n), lappend(n)
+.SH KEYWORDS
+append, variable
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/doc/apply.n b/doc/apply.n
new file mode 100644
index 0000000..aeb2227
--- /dev/null
+++ b/doc/apply.n
@@ -0,0 +1,102 @@
+'\"
+'\" Copyright (c) 2006 Miguel Sofer
+'\" Copyright (c) 2006 Donal K. Fellows
+'\"
+.TH apply n "" Tcl "Tcl Built-In Commands"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+apply \- Apply an anonymous function
+.SH SYNOPSIS
+\fBapply \fIfunc\fR ?\fIarg1 arg2 ...\fR?
+.BE
+.SH DESCRIPTION
+.PP
+The command \fBapply\fR applies the function \fIfunc\fR to the arguments
+\fIarg1 arg2 ...\fR and returns the result.
+.PP
+The function \fIfunc\fR is a two element list \fI{args body}\fR or a three
+element list \fI{args body namespace}\fR (as if the
+\fBlist\fR command had been used).
+The first element \fIargs\fR specifies the formal arguments to
+\fIfunc\fR. The specification of the formal arguments \fIargs\fR
+is shared with the \fBproc\fR command, and is described in detail in the
+corresponding manual page.
+.PP
+The contents of \fIbody\fR are executed by the Tcl interpreter
+after the local variables corresponding to the formal arguments are given
+the values of the actual parameters \fIarg1 arg2 ...\fR.
+When \fIbody\fR is being executed, variable names normally refer to
+local variables, which are created automatically when referenced and
+deleted when \fBapply\fR returns.  One local variable is automatically
+created for each of the function's arguments.
+Global variables can only be accessed by invoking
+the \fBglobal\fR command or the \fBupvar\fR command.
+Namespace variables can only be accessed by invoking
+the \fBvariable\fR command or the \fBupvar\fR command.
+.PP
+The invocation of \fBapply\fR adds a call frame to Tcl's evaluation stack
+(the stack of frames accessed via \fBuplevel\fR). The execution of \fIbody\fR
+proceeds in this call frame, in the namespace given by \fInamespace\fR or
+in the global namespace if none was specified. If given, \fInamespace\fR is
+interpreted relative to the global namespace even if its name does not start
+with
+.QW :: .
+.PP
+The semantics of \fBapply\fR can also be described by:
+.PP
+.CS
+proc apply {fun args} {
+    set len [llength $fun]
+    if {($len < 2) || ($len > 3)} {
+         error "can't interpret \e"$fun\e" as anonymous function"
+    }
+    lassign $fun argList body ns
+    set name ::$ns::[getGloballyUniqueName]
+    set body0 {
+         rename [lindex [info level 0] 0] {}
+    }
+    proc $name $argList ${body0}$body
+    set code [catch {uplevel 1 $name $args} res opt]
+    return -options $opt $res
+}
+.CE
+.SH EXAMPLES
+.PP
+This shows how to make a simple general command that applies a transformation
+to each element of a list.
+.PP
+.CS
+proc map {lambda list} {
+    set result {}
+    foreach item $list {
+        lappend result [\fBapply\fR $lambda $item]
+    }
+    return $result
+}
+map {x {return [string length $x]:$x}} {a bb ccc dddd}
+      \fI\(-> 1:a 2:bb 3:ccc 4:dddd\fR
+map {x {expr {$x**2 + 3*$x - 2}}} {-4 -3 -2 -1 0 1 2 3 4}
+      \fI\(-> 2 -2 -4 -4 -2 2 8 16 26\fR
+.CE
+.PP
+The \fBapply\fR command is also useful for defining callbacks for use in the
+\fBtrace\fR command:
+.PP
+.CS
+set vbl "123abc"
+trace add variable vbl write {\fBapply\fR {{v1 v2 op} {
+    upvar 1 $v1 v
+    puts "updated variable to \e"$v\e""
+}}}
+set vbl 123
+set vbl abc
+.CE
+.SH "SEE ALSO"
+proc(n), uplevel(n)
+.SH KEYWORDS
+anonymous function, argument, lambda, procedure,
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/doc/array.n b/doc/array.n
new file mode 100644
index 0000000..25ad0c6
--- /dev/null
+++ b/doc/array.n
@@ -0,0 +1,187 @@
+'\"
+'\" Copyright (c) 1993-1994 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH array n 8.3 Tcl "Tcl Built-In Commands"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+array \- Manipulate array variables
+.SH SYNOPSIS
+\fBarray \fIoption arrayName\fR ?\fIarg arg ...\fR?
+.BE
+.SH DESCRIPTION
+.PP
+This command performs one of several operations on the
+variable given by \fIarrayName\fR.
+Unless otherwise specified for individual commands below,
+\fIarrayName\fR must be the name of an existing array variable.
+The \fIoption\fR argument determines what action is carried
+out by the command.
+The legal \fIoptions\fR (which may be abbreviated) are:
+.TP
+\fBarray anymore \fIarrayName searchId\fR
+Returns 1 if there are any more elements left to be processed
+in an array search, 0 if all elements have already been
+returned.
+\fISearchId\fR indicates which search on \fIarrayName\fR to
+check, and must have been the return value from a previous
+invocation of \fBarray startsearch\fR.
+This option is particularly useful if an array has an element
+with an empty name, since the return value from
+\fBarray nextelement\fR will not indicate whether the search
+has been completed.
+.TP
+\fBarray donesearch \fIarrayName searchId\fR
+This command terminates an array search and destroys all the
+state associated with that search.  \fISearchId\fR indicates
+which search on \fIarrayName\fR to destroy, and must have
+been the return value from a previous invocation of
+\fBarray startsearch\fR.  Returns an empty string.
+.TP
+\fBarray exists \fIarrayName\fR
+Returns 1 if \fIarrayName\fR is an array variable, 0 if there
+is no variable by that name or if it is a scalar variable.
+.TP
+\fBarray get \fIarrayName\fR ?\fIpattern\fR?
+Returns a list containing pairs of elements.  The first
+element in each pair is the name of an element in \fIarrayName\fR
+and the second element of each pair is the value of the
+array element.  The order of the pairs is undefined.
+If \fIpattern\fR is not specified, then all of the elements of the
+array are included in the result.
+If \fIpattern\fR is specified, then only those elements whose names
+match \fIpattern\fR (using the matching rules of
+\fBstring match\fR) are included.
+If \fIarrayName\fR is not the name of an array variable, or if
+the array contains no elements, then an empty list is returned.
+If traces on the array modify the list of elements, the elements
+returned are those that exist both before and after the call to
+\fBarray get\fR.
+.TP
+\fBarray names \fIarrayName\fR ?\fImode\fR? ?\fIpattern\fR?
+Returns a list containing the names of all of the elements in
+the array that match \fIpattern\fR.  \fIMode\fR may be one of
+\fB\-exact\fR, \fB\-glob\fR, or \fB\-regexp\fR.  If specified, \fImode\fR
+designates which matching rules to use to match \fIpattern\fR against
+the names of the elements in the array.  If not specified, \fImode\fR
+defaults to \fB\-glob\fR.  See the documentation for \fBstring match\fR
+for information on glob style matching, and the documentation for
+\fBregexp\fR for information on regexp matching.
+If \fIpattern\fR is omitted then the command returns all of
+the element names in the array.  If there are no (matching) elements
+in the array, or if \fIarrayName\fR is not the name of an array
+variable, then an empty string is returned.
+.TP
+\fBarray nextelement \fIarrayName searchId\fR
+Returns the name of the next element in \fIarrayName\fR, or
+an empty string if all elements of \fIarrayName\fR have
+already been returned in this search.  The \fIsearchId\fR
+argument identifies the search, and must have
+been the return value of an \fBarray startsearch\fR command.
+Warning:  if elements are added to or deleted from the array,
+then all searches are automatically terminated just as if
+\fBarray donesearch\fR had been invoked; this will cause
+\fBarray nextelement\fR operations to fail for those searches.
+.TP
+\fBarray set \fIarrayName list\fR
+Sets the values of one or more elements in \fIarrayName\fR.
+\fIlist\fR must have a form like that returned by \fBarray get\fR,
+consisting of an even number of elements.
+Each odd-numbered element in \fIlist\fR is treated as an element
+name within \fIarrayName\fR, and the following element in \fIlist\fR
+is used as a new value for that array element.
+If the variable \fIarrayName\fR does not already exist
+and \fIlist\fR is empty,
+\fIarrayName\fR is created with an empty array value.
+.TP
+\fBarray size \fIarrayName\fR
+Returns a decimal string giving the number of elements in the
+array.
+If \fIarrayName\fR is not the name of an array then 0 is returned.
+.TP
+\fBarray startsearch \fIarrayName\fR
+This command initializes an element-by-element search through the
+array given by \fIarrayName\fR, such that invocations of the
+\fBarray nextelement\fR command will return the names of the
+individual elements in the array.
+When the search has been completed, the \fBarray donesearch\fR
+command should be invoked.
+The return value is a
+search identifier that must be used in \fBarray nextelement\fR
+and \fBarray donesearch\fR commands; it allows multiple
+searches to be underway simultaneously for the same array.
+It is currently more efficient and easier to use either the \fBarray
+get\fR or \fBarray names\fR, together with \fBforeach\fR, to iterate
+over all but very large arrays.  See the examples below for how to do
+this.
+.TP
+\fBarray statistics \fIarrayName\fR
+Returns statistics about the distribution of data within the hashtable
+that represents the array.  This information includes the number of
+entries in the table, the number of buckets, and the utilization of
+the buckets.
+.TP
+\fBarray unset \fIarrayName\fR ?\fIpattern\fR?
+Unsets all of the elements in the array that match \fIpattern\fR (using the
+matching rules of \fBstring match\fR).  If \fIarrayName\fR is not the name
+of an array variable or there are no matching elements in the array, no
+error will be raised.  If \fIpattern\fR is omitted and \fIarrayName\fR is
+an array variable, then the command unsets the entire array.
+The command always returns an empty string.
+.SH EXAMPLES
+.CS
+\fBarray set\fR colorcount {
+    red   1
+    green 5
+    blue  4
+    white 9
+}
+
+foreach {color count} [\fBarray get\fR colorcount] {
+    puts "Color: $color Count: $count"
+}
+  \fB\(->\fR Color: blue Count: 4
+    Color: white Count: 9
+    Color: green Count: 5
+    Color: red Count: 1
+
+foreach color [\fBarray names\fR colorcount] {
+    puts "Color: $color Count: $colorcount($color)"
+}
+  \fB\(->\fR Color: blue Count: 4
+    Color: white Count: 9
+    Color: green Count: 5
+    Color: red Count: 1
+
+foreach color [lsort [\fBarray names\fR colorcount]] {
+    puts "Color: $color Count: $colorcount($color)"
+}
+  \fB\(->\fR Color: blue Count: 4
+    Color: green Count: 5
+    Color: red Count: 1
+    Color: white Count: 9
+
+\fBarray statistics\fR colorcount
+  \fB\(->\fR 4 entries in table, 4 buckets
+    number of buckets with 0 entries: 1
+    number of buckets with 1 entries: 2
+    number of buckets with 2 entries: 1
+    number of buckets with 3 entries: 0
+    number of buckets with 4 entries: 0
+    number of buckets with 5 entries: 0
+    number of buckets with 6 entries: 0
+    number of buckets with 7 entries: 0
+    number of buckets with 8 entries: 0
+    number of buckets with 9 entries: 0
+    number of buckets with 10 or more entries: 0
+    average search distance for entry: 1.2
+.CE
+.SH "SEE ALSO"
+list(n), string(n), variable(n), trace(n), foreach(n)
+.SH KEYWORDS
+array, element names, search
diff --git a/doc/bgerror.n b/doc/bgerror.n
new file mode 100644
index 0000000..3644b3d
--- /dev/null
+++ b/doc/bgerror.n
@@ -0,0 +1,93 @@
+'\"
+'\" Copyright (c) 1990-1994 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH bgerror n 7.5 Tcl "Tcl Built-In Commands"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+bgerror \- Command invoked to process background errors
+.SH SYNOPSIS
+\fBbgerror \fImessage\fR
+.BE
+.SH DESCRIPTION
+.PP
+Release 8.5 of Tcl supports the \fBinterp bgerror\fR command,
+which allows applications to register in an interpreter the command
+that will handle background errors in that interpreter.  In older
+releases of Tcl, this level of control was not available, and applications
+could control the handling of background errors only by creating
+a command with the particular command name \fBbgerror\fR in the
+global namespace of an interpreter.  The following documentation
+describes the interface requirements of the \fBbgerror\fR command
+an application might define to retain compatibility with pre-8.5
+releases of Tcl.  Applications intending to support only
+Tcl releases 8.5 and later should simply make use of \fBinterp bgerror\fR.
+.PP
+The \fBbgerror\fR command does not exist as built-in part of Tcl.  Instead,
+individual applications or users can define a \fBbgerror\fR
+command (e.g. as a Tcl procedure) if they wish to handle background
+errors.
+.PP
+A background error is one that occurs in an event handler or some
+other command that did not originate with the application.
+For example, if an error occurs while executing a command specified
+with the \fBafter\fR command, then it is a background error.
+For a non-background error, the error can simply be returned up
+through nested Tcl command evaluations until it reaches the top-level
+code in the application; then the application can report the error
+in whatever way it wishes.  When a background error occurs, the
+unwinding ends in the Tcl library and there is no obvious way for Tcl
+to report the error.
+.PP
+When Tcl detects a background error, it saves information about the
+error and invokes a handler command registered by \fBinterp bgerror\fR
+later as an idle event handler.  The default handler command in turn
+calls the \fBbgerror\fR command .
+Before invoking \fBbgerror\fR, Tcl restores the
+\fBerrorInfo\fR and \fBerrorCode\fR variables to their values at the
+time the error occurred, then it invokes \fBbgerror\fR with the error
+message as its only argument.  Tcl assumes that the application has
+implemented the \fBbgerror\fR command, and that the command will
+report the error in a way that makes sense for the application.  Tcl
+will ignore any result returned by the \fBbgerror\fR command as long
+as no error is generated.
+.PP
+If another Tcl error occurs within the \fBbgerror\fR command (for
+example, because no \fBbgerror\fR command has been defined) then Tcl
+reports the error itself by writing a message to stderr.
+.PP
+If several background errors accumulate before \fBbgerror\fR is
+invoked to process them, \fBbgerror\fR will be invoked once for each
+error, in the order they occurred.  However, if \fBbgerror\fR returns
+with a break exception, then any remaining errors are skipped without
+calling \fBbgerror\fR.
+.PP
+If you are writing code that will be used by others as part of a
+package or other kind of library, consider avoiding \fBbgerror\fR.
+The reason for this is that the application programmer may also want
+to define a \fBbgerror\fR, or use other code that does and thus will
+have trouble integrating your code.
+.SH "EXAMPLE"
+.PP
+This \fBbgerror\fR procedure appends errors to a file, with a timestamp.
+.PP
+.CS
+proc bgerror {message} {
+    set timestamp [clock format [clock seconds]]
+    set fl [open mylog.txt {WRONLY CREAT APPEND}]
+    puts $fl "$timestamp: bgerror in $::argv '$message'"
+    close $fl
+}
+.CE
+.SH "SEE ALSO"
+after(n), errorCode(n), errorInfo(n), interp(n)
+.SH KEYWORDS
+background error, reporting
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/doc/binary.n b/doc/binary.n
new file mode 100644
index 0000000..5f25d65
--- /dev/null
+++ b/doc/binary.n
@@ -0,0 +1,908 @@
+'\"
+'\" Copyright (c) 1997 by Sun Microsystems, Inc.
+'\" Copyright (c) 2008 by Donal K. Fellows
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH binary n 8.0 Tcl "Tcl Built-In Commands"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+binary \- Insert and extract fields from binary strings
+.SH SYNOPSIS
+.VS 8.6
+\fBbinary decode \fIformat\fR ?\fI\-option value ...\fR? \fIdata\fR
+.br
+\fBbinary encode \fIformat\fR ?\fI\-option value ...\fR? \fIdata\fR
+.br
+.VE 8.6
+\fBbinary format \fIformatString \fR?\fIarg arg ...\fR?
+.br
+\fBbinary scan \fIstring formatString \fR?\fIvarName varName ...\fR?
+.BE
+.SH DESCRIPTION
+.PP
+This command provides facilities for manipulating binary data.  The
+subcommand \fBbinary format\fR creates a binary string from normal
+Tcl values.  For example, given the values 16 and 22, on a 32-bit
+architecture, it might produce an 8-byte binary string consisting of
+two 4-byte integers, one for each of the numbers.  The subcommand
+\fBbinary scan\fR, does the opposite: it extracts data
+from a binary string and returns it as ordinary Tcl string values.
+.VS 8.6
+The \fBbinary encode\fR and \fBbinary decode\fR subcommands convert
+binary data to or from string encodings such as base64 (used in MIME
+messages for example).
+.VE 8.6
+.PP
+Note that other operations on binary data, such as taking a subsequence of it,
+getting its length, or reinterpreting it as a string in some encoding, are
+done by other Tcl commands (respectively \fBstring range\fR,
+\fBstring length\fR and \fBencoding convertfrom\fR in the example cases).  A
+binary string in Tcl is merely one where all the characters it contains are in
+the range \eu0000\-\eu00FF.
+.SH "BINARY ENCODE AND DECODE"
+.VS 8.6
+.PP
+When encoding binary data as a readable string, the starting binary data is
+passed to the \fBbinary encode\fR command, together with the name of the
+encoding to use and any encoding-specific options desired. Data which has been
+encoded can be converted back to binary form using \fBbinary decode\fR. The
+following formats and options are supported.
+.TP
+\fBbase64\fR
+.
+The \fBbase64\fR binary encoding is commonly used in mail messages and XML
+documents, and uses mostly upper and lower case letters and digits. It has the
+distinction of being able to be rewrapped arbitrarily without losing
+information.
+.RS
+.PP
+During encoding, the following options are supported:
+.TP
+\fB\-maxlen \fIlength\fR
+.
+Indicates that the output should be split into lines of no more than
+\fIlength\fR characters. By default, lines are not split.
+.TP
+\fB\-wrapchar \fIcharacter\fR
+.
+Indicates that, when lines are split because of the \fB\-maxlen\fR option,
+\fIcharacter\fR should be used to separate lines. By default, this is a
+newline character,
+.QW \en .
+.PP
+During decoding, the following options are supported:
+.TP
+\fB\-strict\fR
+.
+Instructs the decoder to throw an error if it encounters whitespace characters. Otherwise it ignores them.
+.RE
+.TP
+\fBhex\fR
+.
+The \fBhex\fR binary encoding converts each byte to a pair of hexadecimal
+digits in big-endian form.
+.RS
+.PP
+No options are supported during encoding. During decoding, the following
+options are supported:
+.TP
+\fB\-strict\fR
+.
+Instructs the decoder to throw an error if it encounters whitespace characters. Otherwise it ignores them.
+.RE
+.TP
+\fBuuencode\fR
+.
+The \fBuuencode\fR binary encoding used to be common for transfer of data
+between Unix systems and on USENET, but is less common these days, having been
+largely superseded by the \fBbase64\fR binary encoding.
+.RS
+.PP
+During encoding, the following options are supported (though changing them may
+produce files that other implementations of decoders cannot process):
+.TP
+\fB\-maxlen \fIlength\fR
+.
+Indicates that the output should be split into lines of no more than
+\fIlength\fR characters. By default, lines are split every 61 characters, and
+this must be in the range 3 to 85 due to limitations in the encoding.
+.TP
+\fB\-wrapchar \fIcharacter\fR
+.
+Indicates that, when lines are split because of the \fB\-maxlen\fR option,
+\fIcharacter\fR should be used to separate lines. By default, this is a
+newline character,
+.QW \en .
+.PP
+During decoding, the following options are supported:
+.TP
+\fB\-strict\fR
+.
+Instructs the decoder to throw an error if it encounters unexpected whitespace
+characters. Otherwise it ignores them.
+.PP
+Note that neither the encoder nor the decoder handle the header and footer of
+the uuencode format.
+.RE
+.VE 8.6
+.SH "BINARY FORMAT"
+.PP
+The \fBbinary format\fR command generates a binary string whose layout
+is specified by the \fIformatString\fR and whose contents come from
+the additional arguments.  The resulting binary value is returned.
+.PP
+The \fIformatString\fR consists of a sequence of zero or more field
+specifiers separated by zero or more spaces.  Each field specifier is
+a single type character followed by an optional flag character followed
+by an optional numeric \fIcount\fR.
+Most field specifiers consume one argument to obtain the value to be
+formatted.  The type character specifies how the value is to be
+formatted.  The \fIcount\fR typically indicates how many items of the
+specified type are taken from the value.  If present, the \fIcount\fR
+is a non-negative decimal integer or \fB*\fR, which normally indicates
+that all of the items in the value are to be used.  If the number of
+arguments does not match the number of fields in the format string
+that consume arguments, then an error is generated. The flag character
+is ignored for \fBbinary format\fR.
+.PP
+Here is a small example to clarify the relation between the field
+specifiers and the arguments:
+.CS
+\fBbinary format\fR d3d {1.0 2.0 3.0 4.0} 0.1
+.CE
+.PP
+The first argument is a list of four numbers, but because of the count
+of 3 for the associated field specifier, only the first three will be
+used. The second argument is associated with the second field
+specifier. The resulting binary string contains the four numbers 1.0,
+2.0, 3.0 and 0.1.
+.PP
+Each type-count pair moves an imaginary cursor through the binary
+data, storing bytes at the current position and advancing the cursor
+to just after the last byte stored.  The cursor is initially at
+position 0 at the beginning of the data.  The type may be any one of
+the following characters:
+.IP \fBa\fR 5
+Stores a byte string of length \fIcount\fR in the output string.
+Every character is taken as modulo 256 (i.e. the low byte of every
+character is used, and the high byte discarded) so when storing
+character strings not wholly expressible using the characters \eu0000-\eu00ff,
+the \fBencoding convertto\fR command should be used first to change
+the string into an external representation
+if this truncation is not desired (i.e. if the characters are
+not part of the ISO 8859\-1 character set.)
+If \fIarg\fR has fewer than \fIcount\fR bytes, then additional zero
+bytes are used to pad out the field.  If \fIarg\fR is longer than the
+specified length, the extra characters will be ignored.  If
+\fIcount\fR is \fB*\fR, then all of the bytes in \fIarg\fR will be
+formatted.  If \fIcount\fR is omitted, then one character will be
+formatted.  For example,
+.RS
+.CS
+\fBbinary format\fR a7a*a alpha bravo charlie
+.CE
+will return a string equivalent to \fBalpha\e000\e000bravoc\fR,
+.CS
+\fBbinary format\fR a* [encoding convertto utf-8 \eu20ac]
+.CE
+will return a string equivalent to \fB\e342\e202\e254\fR (which is the
+UTF-8 byte sequence for a Euro-currency character) and
+.CS
+\fBbinary format\fR a* [encoding convertto iso8859-15 \eu20ac]
+.CE
+will return a string equivalent to \fB\e244\fR (which is the ISO
+8859\-15 byte sequence for a Euro-currency character). Contrast these
+last two with:
+.CS
+\fBbinary format\fR a* \eu20ac
+.CE
+which returns a string equivalent to \fB\e254\fR (i.e. \fB\exac\fR) by
+truncating the high-bits of the character, and which is probably not
+what is desired.
+.RE
+.IP \fBA\fR 5
+This form is the same as \fBa\fR except that spaces are used for
+padding instead of nulls.  For example,
+.RS
+.CS
+\fBbinary format\fR A6A*A alpha bravo charlie
+.CE
+will return \fBalpha bravoc\fR.
+.RE
+.IP \fBb\fR 5
+Stores a string of \fIcount\fR binary digits in low-to-high order
+within each byte in the output string.  \fIArg\fR must contain a
+sequence of \fB1\fR and \fB0\fR characters.  The resulting bytes are
+emitted in first to last order with the bits being formatted in
+low-to-high order within each byte.  If \fIarg\fR has fewer than
+\fIcount\fR digits, then zeros will be used for the remaining bits.
+If \fIarg\fR has more than the specified number of digits, the extra
+digits will be ignored.  If \fIcount\fR is \fB*\fR, then all of the
+digits in \fIarg\fR will be formatted.  If \fIcount\fR is omitted,
+then one digit will be formatted.  If the number of bits formatted
+does not end at a byte boundary, the remaining bits of the last byte
+will be zeros.  For example,
+.RS
+.CS
+\fBbinary format\fR b5b* 11100 111000011010
+.CE
+will return a string equivalent to \fB\ex07\ex87\ex05\fR.
+.RE
+.IP \fBB\fR 5
+This form is the same as \fBb\fR except that the bits are stored in
+high-to-low order within each byte.  For example,
+.RS
+.CS
+\fBbinary format\fR B5B* 11100 111000011010
+.CE
+will return a string equivalent to \fB\exe0\exe1\exa0\fR.
+.RE
+.IP \fBH\fR 5
+Stores a string of \fIcount\fR hexadecimal digits in high-to-low
+within each byte in the output string.  \fIArg\fR must contain a
+sequence of characters in the set
+.QW 0123456789abcdefABCDEF .
+The resulting bytes are emitted in first to last order with the hex digits
+being formatted in high-to-low order within each byte.  If \fIarg\fR
+has fewer than \fIcount\fR digits, then zeros will be used for the
+remaining digits.  If \fIarg\fR has more than the specified number of
+digits, the extra digits will be ignored.  If \fIcount\fR is
+\fB*\fR, then all of the digits in \fIarg\fR will be formatted.  If
+\fIcount\fR is omitted, then one digit will be formatted.  If the
+number of digits formatted does not end at a byte boundary, the
+remaining bits of the last byte will be zeros.  For example,
+.RS
+.CS
+\fBbinary format\fR H3H*H2 ab DEF 987
+.CE
+will return a string equivalent to \fB\exab\ex00\exde\exf0\ex98\fR.
+.RE
+.IP \fBh\fR 5
+This form is the same as \fBH\fR except that the digits are stored in
+low-to-high order within each byte. This is seldom required. For example,
+.RS
+.CS
+\fBbinary format\fR h3h*h2 AB def 987
+.CE
+will return a string equivalent to \fB\exba\ex00\exed\ex0f\ex89\fR.
+.RE
+.IP \fBc\fR 5
+Stores one or more 8-bit integer values in the output string.  If no
+\fIcount\fR is specified, then \fIarg\fR must consist of an integer
+value. If \fIcount\fR is specified, \fIarg\fR must consist of a list
+containing at least that many integers. The low-order 8 bits of each integer
+are stored as a one-byte value at the cursor position.  If \fIcount\fR
+is \fB*\fR, then all of the integers in the list are formatted. If the
+number of elements in the list is greater
+than \fIcount\fR, then the extra elements are ignored.  For example,
+.RS
+.CS
+\fBbinary format\fR c3cc* {3 -3 128 1} 260 {2 5}
+.CE
+will return a string equivalent to
+\fB\ex03\exfd\ex80\ex04\ex02\ex05\fR, whereas
+.CS
+\fBbinary format\fR c {2 5}
+.CE
+will generate an error.
+.RE
+.IP \fBs\fR 5
+This form is the same as \fBc\fR except that it stores one or more
+16-bit integers in little-endian byte order in the output string.  The
+low-order 16-bits of each integer are stored as a two-byte value at
+the cursor position with the least significant byte stored first.  For
+example,
+.RS
+.CS
+\fBbinary format\fR s3 {3 -3 258 1}
+.CE
+will return a string equivalent to
+\fB\ex03\ex00\exfd\exff\ex02\ex01\fR.
+.RE
+.IP \fBS\fR 5
+This form is the same as \fBs\fR except that it stores one or more
+16-bit integers in big-endian byte order in the output string.  For
+example,
+.RS
+.CS
+\fBbinary format\fR S3 {3 -3 258 1}
+.CE
+will return a string equivalent to
+\fB\ex00\ex03\exff\exfd\ex01\ex02\fR.
+.RE
+.IP \fBt\fR 5
+This form (mnemonically \fItiny\fR) is the same as \fBs\fR and \fBS\fR
+except that it stores the 16-bit integers in the output string in the
+native byte order of the machine where the Tcl script is running.
+To determine what the native byte order of the machine is, refer to
+the \fBbyteOrder\fR element of the \fBtcl_platform\fR array.
+.IP \fBi\fR 5
+This form is the same as \fBc\fR except that it stores one or more
+32-bit integers in little-endian byte order in the output string.  The
+low-order 32-bits of each integer are stored as a four-byte value at
+the cursor position with the least significant byte stored first.  For
+example,
+.RS
+.CS
+\fBbinary format\fR i3 {3 -3 65536 1}
+.CE
+will return a string equivalent to
+\fB\ex03\ex00\ex00\ex00\exfd\exff\exff\exff\ex00\ex00\ex01\ex00\fR
+.RE
+.IP \fBI\fR 5
+This form is the same as \fBi\fR except that it stores one or more one
+or more 32-bit integers in big-endian byte order in the output string.
+For example,
+.RS
+.CS
+\fBbinary format\fR I3 {3 -3 65536 1}
+.CE
+will return a string equivalent to
+\fB\ex00\ex00\ex00\ex03\exff\exff\exff\exfd\ex00\ex01\ex00\ex00\fR
+.RE
+.IP \fBn\fR 5
+This form (mnemonically \fInumber\fR or \fInormal\fR) is the same as
+\fBi\fR and \fBI\fR except that it stores the 32-bit integers in the
+output string in the native byte order of the machine where the Tcl
+script is running.
+To determine what the native byte order of the machine is, refer to
+the \fBbyteOrder\fR element of the \fBtcl_platform\fR array.
+.IP \fBw\fR 5
+This form is the same as \fBc\fR except that it stores one or more
+64-bit integers in little-endian byte order in the output string.  The
+low-order 64-bits of each integer are stored as an eight-byte value at
+the cursor position with the least significant byte stored first.  For
+example,
+.RS
+.CS
+\fBbinary format\fR w 7810179016327718216
+.CE
+will return the string \fBHelloTcl\fR
+.RE
+.IP \fBW\fR 5
+This form is the same as \fBw\fR except that it stores one or more one
+or more 64-bit integers in big-endian byte order in the output string.
+For example,
+.RS
+.CS
+\fBbinary format\fR Wc 4785469626960341345 110
+.CE
+will return the string \fBBigEndian\fR
+.RE
+.IP \fBm\fR 5
+This form (mnemonically the mirror of \fBw\fR) is the same as \fBw\fR
+and \fBW\fR except that it stores the 64-bit integers in the output
+string in the native byte order of the machine where the Tcl script is
+running.
+To determine what the native byte order of the machine is, refer to
+the \fBbyteOrder\fR element of the \fBtcl_platform\fR array.
+.IP \fBf\fR 5
+This form is the same as \fBc\fR except that it stores one or more one
+or more single-precision floating point numbers in the machine's native
+representation in the output string.  This representation is not
+portable across architectures, so it should not be used to communicate
+floating point numbers across the network.  The size of a floating
+point number may vary across architectures, so the number of bytes
+that are generated may vary.  If the value overflows the
+machine's native representation, then the value of FLT_MAX
+as defined by the system will be used instead.  Because Tcl uses
+double-precision floating point numbers internally, there may be some
+loss of precision in the conversion to single-precision.  For example,
+on a Windows system running on an Intel Pentium processor,
+.RS
+.CS
+\fBbinary format\fR f2 {1.6 3.4}
+.CE
+will return a string equivalent to
+\fB\excd\excc\excc\ex3f\ex9a\ex99\ex59\ex40\fR.
+.RE
+.IP \fBr\fR 5
+This form (mnemonically \fIreal\fR) is the same as \fBf\fR except that
+it stores the single-precision floating point numbers in little-endian
+order.  This conversion only produces meaningful output when used on
+machines which use the IEEE floating point representation (very
+common, but not universal.)
+.IP \fBR\fR 5
+This form is the same as \fBr\fR except that it stores the
+single-precision floating point numbers in big-endian order.
+.IP \fBd\fR 5
+This form is the same as \fBf\fR except that it stores one or more one
+or more double-precision floating point numbers in the machine's native
+representation in the output string.  For example, on a
+Windows system running on an Intel Pentium processor,
+.RS
+.CS
+\fBbinary format\fR d1 {1.6}
+.CE
+will return a string equivalent to
+\fB\ex9a\ex99\ex99\ex99\ex99\ex99\exf9\ex3f\fR.
+.RE
+.IP \fBq\fR 5
+This form (mnemonically the mirror of \fBd\fR) is the same as \fBd\fR
+except that it stores the double-precision floating point numbers in
+little-endian order.  This conversion only produces meaningful output
+when used on machines which use the IEEE floating point representation
+(very common, but not universal.)
+.IP \fBQ\fR 5
+This form is the same as \fBq\fR except that it stores the
+double-precision floating point numbers in big-endian order.
+.IP \fBx\fR 5
+Stores \fIcount\fR null bytes in the output string.  If \fIcount\fR is
+not specified, stores one null byte.  If \fIcount\fR is \fB*\fR,
+generates an error.  This type does not consume an argument.  For
+example,
+.RS
+.CS
+\fBbinary format\fR a3xa3x2a3 abc def ghi
+.CE
+will return a string equivalent to \fBabc\e000def\e000\e000ghi\fR.
+.RE
+.IP \fBX\fR 5
+Moves the cursor back \fIcount\fR bytes in the output string.  If
+\fIcount\fR is \fB*\fR or is larger than the current cursor position,
+then the cursor is positioned at location 0 so that the next byte
+stored will be the first byte in the result string.  If \fIcount\fR is
+omitted then the cursor is moved back one byte.  This type does not
+consume an argument.  For example,
+.RS
+.CS
+\fBbinary format\fR a3X*a3X2a3 abc def ghi
+.CE
+will return \fBdghi\fR.
+.RE
+.IP \fB@\fR 5
+Moves the cursor to the absolute location in the output string
+specified by \fIcount\fR.  Position 0 refers to the first byte in the
+output string.  If \fIcount\fR refers to a position beyond the last
+byte stored so far, then null bytes will be placed in the uninitialized
+locations and the cursor will be placed at the specified location.  If
+\fIcount\fR is \fB*\fR, then the cursor is moved to the current end of
+the output string.  If \fIcount\fR is omitted, then an error will be
+generated.  This type does not consume an argument. For example,
+.RS
+.CS
+\fBbinary format\fR a5@2a1@*a3@10a1 abcde f ghi j
+.CE
+will return \fBabfdeghi\e000\e000j\fR.
+.RE
+.SH "BINARY SCAN"
+.PP
+The \fBbinary scan\fR command parses fields from a binary string,
+returning the number of conversions performed.  \fIString\fR gives the
+input bytes to be parsed (one byte per character, and characters not
+representable as a byte have their high bits chopped)
+and \fIformatString\fR indicates how to parse it.
+Each \fIvarName\fR gives the name of a variable; when a field is
+scanned from \fIstring\fR the result is assigned to the corresponding
+variable.
+.PP
+As with \fBbinary format\fR, the \fIformatString\fR consists of a
+sequence of zero or more field specifiers separated by zero or more
+spaces.  Each field specifier is a single type character followed by
+an optional flag character followed by an optional numeric \fIcount\fR.
+Most field specifiers consume one
+argument to obtain the variable into which the scanned values should
+be placed.  The type character specifies how the binary data is to be
+interpreted.  The \fIcount\fR typically indicates how many items of
+the specified type are taken from the data.  If present, the
+\fIcount\fR is a non-negative decimal integer or \fB*\fR, which
+normally indicates that all of the remaining items in the data are to
+be used.  If there are not enough bytes left after the current cursor
+position to satisfy the current field specifier, then the
+corresponding variable is left untouched and \fBbinary scan\fR returns
+immediately with the number of variables that were set.  If there are
+not enough arguments for all of the fields in the format string that
+consume arguments, then an error is generated. The flag character
+.QW u
+may be given to cause some types to be read as unsigned values. The flag
+is accepted for all field types but is ignored for non-integer fields.
+.PP
+A similar example as with \fBbinary format\fR should explain the
+relation between field specifiers and arguments in case of the binary
+scan subcommand:
+.CS
+\fBbinary scan\fR $bytes s3s first second
+.CE
+.PP
+This command (provided the binary string in the variable \fIbytes\fR
+is long enough) assigns a list of three integers to the variable
+\fIfirst\fR and assigns a single value to the variable \fIsecond\fR.
+If \fIbytes\fR contains fewer than 8 bytes (i.e. four 2-byte
+integers), no assignment to \fIsecond\fR will be made, and if
+\fIbytes\fR contains fewer than 6 bytes (i.e. three 2-byte integers),
+no assignment to \fIfirst\fR will be made.  Hence:
+.CS
+puts [\fBbinary scan\fR abcdefg s3s first second]
+puts $first
+puts $second
+.CE
+will print (assuming neither variable is set previously):
+.CS
+1
+25185 25699 26213
+can't read "second": no such variable
+.CE
+.PP
+It is \fIimportant\fR to note that the \fBc\fR, \fBs\fR, and \fBS\fR
+(and \fBi\fR and \fBI\fR on 64bit systems) will be scanned into
+long data size values.  In doing this, values that have their high
+bit set (0x80 for chars, 0x8000 for shorts, 0x80000000 for ints),
+will be sign extended.  Thus the following will occur:
+.CS
+set signShort [\fBbinary format\fR s1 0x8000]
+\fBbinary scan\fR $signShort s1 val; \fI# val == 0xFFFF8000\fR
+.CE
+If you require unsigned values you can include the
+.QW u
+flag character following
+the field type. For example, to read an unsigned short value:
+.CS
+set signShort [\fBbinary format\fR s1 0x8000]
+\fBbinary scan\fR $signShort su1 val; \fI# val == 0x00008000\fR
+.CE
+.PP
+Each type-count pair moves an imaginary cursor through the binary data,
+reading bytes from the current position.  The cursor is initially
+at position 0 at the beginning of the data.  The type may be any one of
+the following characters:
+.IP \fBa\fR 5
+The data is a byte string of length \fIcount\fR.  If \fIcount\fR
+is \fB*\fR, then all of the remaining bytes in \fIstring\fR will be
+scanned into the variable.  If \fIcount\fR is omitted, then one
+byte will be scanned.
+All bytes scanned will be interpreted as being characters in the
+range \eu0000-\eu00ff so the \fBencoding convertfrom\fR command will be
+needed if the string is not a binary string or a string encoded in ISO
+8859\-1.
+For example,
+.RS
+.CS
+\fBbinary scan\fR abcde\e000fghi a6a10 var1 var2
+.CE
+will return \fB1\fR with the string equivalent to \fBabcde\e000\fR
+stored in \fIvar1\fR and \fIvar2\fR left unmodified, and
+.CS
+\fBbinary scan\fR \e342\e202\e254 a* var1
+set var2 [encoding convertfrom utf-8 $var1]
+.CE
+will store a Euro-currency character in \fIvar2\fR.
+.RE
+.IP \fBA\fR 5
+This form is the same as \fBa\fR, except trailing blanks and nulls are stripped from
+the scanned value before it is stored in the variable.  For example,
+.RS
+.CS
+\fBbinary scan\fR "abc efghi  \e000" A* var1
+.CE
+will return \fB1\fR with \fBabc efghi\fR stored in \fIvar1\fR.
+.RE
+.IP \fBb\fR 5
+The data is turned into a string of \fIcount\fR binary digits in
+low-to-high order represented as a sequence of
+.QW 1
+and
+.QW 0
+characters.  The data bytes are scanned in first to last order with
+the bits being taken in low-to-high order within each byte.  Any extra
+bits in the last byte are ignored.  If \fIcount\fR is \fB*\fR, then
+all of the remaining bits in \fIstring\fR will be scanned.  If
+\fIcount\fR is omitted, then one bit will be scanned.  For example,
+.RS
+.CS
+\fBbinary scan\fR \ex07\ex87\ex05 b5b* var1 var2
+.CE
+will return \fB2\fR with \fB11100\fR stored in \fIvar1\fR and
+\fB1110000110100000\fR stored in \fIvar2\fR.
+.RE
+.IP \fBB\fR 5
+This form is the same as \fBb\fR, except the bits are taken in
+high-to-low order within each byte.  For example,
+.RS
+.CS
+\fBbinary scan\fR \ex70\ex87\ex05 B5B* var1 var2
+.CE
+will return \fB2\fR with \fB01110\fR stored in \fIvar1\fR and
+\fB1000011100000101\fR stored in \fIvar2\fR.
+.RE
+.IP \fBH\fR 5
+The data is turned into a string of \fIcount\fR hexadecimal digits in
+high-to-low order represented as a sequence of characters in the set
+.QW 0123456789abcdef .
+The data bytes are scanned in first to last
+order with the hex digits being taken in high-to-low order within each
+byte. Any extra bits in the last byte are ignored. If \fIcount\fR is
+\fB*\fR, then all of the remaining hex digits in \fIstring\fR will be
+scanned. If \fIcount\fR is omitted, then one hex digit will be
+scanned. For example,
+.RS
+.CS
+\fBbinary scan\fR \ex07\exC6\ex05\ex1f\ex34 H3H* var1 var2
+.CE
+will return \fB2\fR with \fB07c\fR stored in \fIvar1\fR and
+\fB051f34\fR stored in \fIvar2\fR.
+.RE
+.IP \fBh\fR 5
+This form is the same as \fBH\fR, except the digits are taken in
+reverse (low-to-high) order within each byte. For example,
+.RS
+.CS
+\fBbinary scan\fR \ex07\ex86\ex05\ex12\ex34 h3h* var1 var2
+.CE
+will return \fB2\fR with \fB706\fR stored in \fIvar1\fR and
+\fB502143\fR stored in \fIvar2\fR.
+.PP
+Note that most code that wishes to parse the hexadecimal digits from
+multiple bytes in order should use the \fBH\fR format.
+.RE
+.IP \fBc\fR 5
+The data is turned into \fIcount\fR 8-bit signed integers and stored
+in the corresponding variable as a list. If \fIcount\fR is \fB*\fR,
+then all of the remaining bytes in \fIstring\fR will be scanned.  If
+\fIcount\fR is omitted, then one 8-bit integer will be scanned.  For
+example,
+.RS
+.CS
+\fBbinary scan\fR \ex07\ex86\ex05 c2c* var1 var2
+.CE
+will return \fB2\fR with \fB7 -122\fR stored in \fIvar1\fR and \fB5\fR
+stored in \fIvar2\fR.  Note that the integers returned are signed, but
+they can be converted to unsigned 8-bit quantities using an expression
+like:
+.CS
+set num [expr { $num & 0xff }]
+.CE
+.RE
+.IP \fBs\fR 5
+The data is interpreted as \fIcount\fR 16-bit signed integers
+represented in little-endian byte order.  The integers are stored in
+the corresponding variable as a list.  If \fIcount\fR is \fB*\fR, then
+all of the remaining bytes in \fIstring\fR will be scanned.  If
+\fIcount\fR is omitted, then one 16-bit integer will be scanned.  For
+example,
+.RS
+.CS
+\fBbinary scan\fR \ex05\ex00\ex07\ex00\exf0\exff s2s* var1 var2
+.CE
+will return \fB2\fR with \fB5 7\fR stored in \fIvar1\fR and \fB\-16\fR
+stored in \fIvar2\fR.  Note that the integers returned are signed, but
+they can be converted to unsigned 16-bit quantities using an expression
+like:
+.CS
+set num [expr { $num & 0xffff }]
+.CE
+.RE
+.IP \fBS\fR 5
+This form is the same as \fBs\fR except that the data is interpreted
+as \fIcount\fR 16-bit signed integers represented in big-endian byte
+order.  For example,
+.RS
+.CS
+\fBbinary scan\fR \ex00\ex05\ex00\ex07\exff\exf0 S2S* var1 var2
+.CE
+will return \fB2\fR with \fB5 7\fR stored in \fIvar1\fR and \fB\-16\fR
+stored in \fIvar2\fR.
+.RE
+.IP \fBt\fR 5
+The data is interpreted as \fIcount\fR 16-bit signed integers
+represented in the native byte order of the machine running the Tcl
+script.  It is otherwise identical to \fBs\fR and \fBS\fR.
+To determine what the native byte order of the machine is, refer to
+the \fBbyteOrder\fR element of the \fBtcl_platform\fR array.
+.IP \fBi\fR 5
+The data is interpreted as \fIcount\fR 32-bit signed integers
+represented in little-endian byte order.  The integers are stored in
+the corresponding variable as a list.  If \fIcount\fR is \fB*\fR, then
+all of the remaining bytes in \fIstring\fR will be scanned.  If
+\fIcount\fR is omitted, then one 32-bit integer will be scanned.  For
+example,
+.RS
+.CS
+set str \ex05\ex00\ex00\ex00\ex07\ex00\ex00\ex00\exf0\exff\exff\exff
+\fBbinary scan\fR $str i2i* var1 var2
+.CE
+will return \fB2\fR with \fB5 7\fR stored in \fIvar1\fR and \fB\-16\fR
+stored in \fIvar2\fR.  Note that the integers returned are signed, but
+they can be converted to unsigned 32-bit quantities using an expression
+like:
+.CS
+set num [expr { $num & 0xffffffff }]
+.CE
+.RE
+.IP \fBI\fR 5
+This form is the same as \fBI\fR except that the data is interpreted
+as \fIcount\fR 32-bit signed integers represented in big-endian byte
+order.  For example,
+.RS
+.CS
+set str \ex00\ex00\ex00\ex05\ex00\ex00\ex00\ex07\exff\exff\exff\exf0
+\fBbinary scan\fR $str I2I* var1 var2
+.CE
+will return \fB2\fR with \fB5 7\fR stored in \fIvar1\fR and \fB\-16\fR
+stored in \fIvar2\fR.
+.RE
+.IP \fBn\fR 5
+The data is interpreted as \fIcount\fR 32-bit signed integers
+represented in the native byte order of the machine running the Tcl
+script.  It is otherwise identical to \fBi\fR and \fBI\fR.
+To determine what the native byte order of the machine is, refer to
+the \fBbyteOrder\fR element of the \fBtcl_platform\fR array.
+.IP \fBw\fR 5
+The data is interpreted as \fIcount\fR 64-bit signed integers
+represented in little-endian byte order.  The integers are stored in
+the corresponding variable as a list.  If \fIcount\fR is \fB*\fR, then
+all of the remaining bytes in \fIstring\fR will be scanned.  If
+\fIcount\fR is omitted, then one 64-bit integer will be scanned.  For
+example,
+.RS
+.CS
+set str \ex05\ex00\ex00\ex00\ex07\ex00\ex00\ex00\exf0\exff\exff\exff
+\fBbinary scan\fR $str wi* var1 var2
+.CE
+will return \fB2\fR with \fB30064771077\fR stored in \fIvar1\fR and
+\fB\-16\fR stored in \fIvar2\fR.  Note that the integers returned are
+signed and cannot be represented by Tcl as unsigned values.
+.RE
+.IP \fBW\fR 5
+This form is the same as \fBw\fR except that the data is interpreted
+as \fIcount\fR 64-bit signed integers represented in big-endian byte
+order.  For example,
+.RS
+.CS
+set str \ex00\ex00\ex00\ex05\ex00\ex00\ex00\ex07\exff\exff\exff\exf0
+\fBbinary scan\fR $str WI* var1 var2
+.CE
+will return \fB2\fR with \fB21474836487\fR stored in \fIvar1\fR and \fB\-16\fR
+stored in \fIvar2\fR.
+.RE
+.IP \fBm\fR 5
+The data is interpreted as \fIcount\fR 64-bit signed integers
+represented in the native byte order of the machine running the Tcl
+script.  It is otherwise identical to \fBw\fR and \fBW\fR.
+To determine what the native byte order of the machine is, refer to
+the \fBbyteOrder\fR element of the \fBtcl_platform\fR array.
+.IP \fBf\fR 5
+The data is interpreted as \fIcount\fR single-precision floating point
+numbers in the machine's native representation.  The floating point
+numbers are stored in the corresponding variable as a list.  If
+\fIcount\fR is \fB*\fR, then all of the remaining bytes in
+\fIstring\fR will be scanned.  If \fIcount\fR is omitted, then one
+single-precision floating point number will be scanned.  The size of a
+floating point number may vary across architectures, so the number of
+bytes that are scanned may vary.  If the data does not represent a
+valid floating point number, the resulting value is undefined and
+compiler dependent.  For example, on a Windows system running on an
+Intel Pentium processor,
+.RS
+.CS
+\fBbinary scan\fR \ex3f\excc\excc\excd f var1
+.CE
+will return \fB1\fR with \fB1.6000000238418579\fR stored in
+\fIvar1\fR.
+.RE
+.IP \fBr\fR 5
+This form is the same as \fBf\fR except that the data is interpreted
+as \fIcount\fR single-precision floating point number in little-endian
+order.  This conversion is not portable to the minority of systems not
+using IEEE floating point representations.
+.IP \fBR\fR 5
+This form is the same as \fBf\fR except that the data is interpreted
+as \fIcount\fR single-precision floating point number in big-endian
+order.  This conversion is not portable to the minority of systems not
+using IEEE floating point representations.
+.IP \fBd\fR 5
+This form is the same as \fBf\fR except that the data is interpreted
+as \fIcount\fR double-precision floating point numbers in the
+machine's native representation. For example, on a Windows system
+running on an Intel Pentium processor,
+.RS
+.CS
+\fBbinary scan\fR \ex9a\ex99\ex99\ex99\ex99\ex99\exf9\ex3f d var1
+.CE
+will return \fB1\fR with \fB1.6000000000000001\fR
+stored in \fIvar1\fR.
+.RE
+.IP \fBq\fR 5
+This form is the same as \fBd\fR except that the data is interpreted
+as \fIcount\fR double-precision floating point number in little-endian
+order.  This conversion is not portable to the minority of systems not
+using IEEE floating point representations.
+.IP \fBQ\fR 5
+This form is the same as \fBd\fR except that the data is interpreted
+as \fIcount\fR double-precision floating point number in big-endian
+order.  This conversion is not portable to the minority of systems not
+using IEEE floating point representations.
+.IP \fBx\fR 5
+Moves the cursor forward \fIcount\fR bytes in \fIstring\fR.  If
+\fIcount\fR is \fB*\fR or is larger than the number of bytes after the
+current cursor position, then the cursor is positioned after
+the last byte in \fIstring\fR.  If \fIcount\fR is omitted, then the
+cursor is moved forward one byte.  Note that this type does not
+consume an argument.  For example,
+.RS
+.CS
+\fBbinary scan\fR \ex01\ex02\ex03\ex04 x2H* var1
+.CE
+will return \fB1\fR with \fB0304\fR stored in \fIvar1\fR.
+.RE
+.IP \fBX\fR 5
+Moves the cursor back \fIcount\fR bytes in \fIstring\fR.  If
+\fIcount\fR is \fB*\fR or is larger than the current cursor position,
+then the cursor is positioned at location 0 so that the next byte
+scanned will be the first byte in \fIstring\fR.  If \fIcount\fR
+is omitted then the cursor is moved back one byte.  Note that this
+type does not consume an argument.  For example,
+.RS
+.CS
+\fBbinary scan\fR \ex01\ex02\ex03\ex04 c2XH* var1 var2
+.CE
+will return \fB2\fR with \fB1 2\fR stored in \fIvar1\fR and \fB020304\fR
+stored in \fIvar2\fR.
+.RE
+.IP \fB@\fR 5
+Moves the cursor to the absolute location in the data string specified
+by \fIcount\fR.  Note that position 0 refers to the first byte in
+\fIstring\fR.  If \fIcount\fR refers to a position beyond the end of
+\fIstring\fR, then the cursor is positioned after the last byte.  If
+\fIcount\fR is omitted, then an error will be generated.  For example,
+.RS
+.CS
+\fBbinary scan\fR \ex01\ex02\ex03\ex04 c2@1H* var1 var2
+.CE
+will return \fB2\fR with \fB1 2\fR stored in \fIvar1\fR and \fB020304\fR
+stored in \fIvar2\fR.
+.RE
+.SH "PORTABILITY ISSUES"
+.PP
+The \fBr\fR, \fBR\fR, \fBq\fR and \fBQ\fR conversions will only work
+reliably for transferring data between computers which are all using
+IEEE floating point representations.  This is very common, but not
+universal.  To transfer floating-point numbers portably between all
+architectures, use their textual representation (as produced by
+\fBformat\fR) instead.
+.SH EXAMPLES
+.PP
+This is a procedure to write a Tcl string to a binary-encoded channel as
+UTF-8 data preceded by a length word:
+.PP
+.CS
+proc \fIwriteString\fR {channel string} {
+    set data [encoding convertto utf-8 $string]
+    puts -nonewline [\fBbinary format\fR Ia* \e
+            [string length $data] $data]
+}
+.CE
+.PP
+This procedure reads a string from a channel that was written by the
+previously presented \fIwriteString\fR procedure:
+.PP
+.CS
+proc \fIreadString\fR {channel} {
+    if {![\fBbinary scan\fR [read $channel 4] I length]} {
+        error "missing length"
+    }
+    set data [read $channel $length]
+    return [encoding convertfrom utf-8 $data]
+}
+.CE
+.PP
+This converts the contents of a file (named in the variable \fIfilename\fR) to
+base64 and prints them:
+.PP
+.CS
+set f [open $filename rb]
+set data [read $f]
+close $f
+puts [\fBbinary encode\fR base64 \-maxlen 64 $data]
+.CE
+.SH "SEE ALSO"
+encoding(n), format(n), scan(n), string(n), tcl_platform(n)
+.SH KEYWORDS
+binary, format, scan
+'\" Local Variables:
+'\" mode: nroff
+'\" fill-column: 78
+'\" End:
diff --git a/doc/break.n b/doc/break.n
new file mode 100644
index 0000000..3e4ce5f
--- /dev/null
+++ b/doc/break.n
@@ -0,0 +1,47 @@
+'\"
+'\" Copyright (c) 1993-1994 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\" 
+.TH break n "" Tcl "Tcl Built-In Commands"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+break \- Abort looping command
+.SH SYNOPSIS
+\fBbreak\fR
+.BE
+.SH DESCRIPTION
+.PP
+This command is typically invoked inside the body of a looping command
+such as \fBfor\fR or \fBforeach\fR or \fBwhile\fR.
+It returns a 3 (\fBTCL_BREAK\fR) result code, which causes a break exception
+to occur.
+The exception causes the current script to be aborted
+out to the innermost containing loop command, which then
+aborts its execution and returns normally.
+Break exceptions are also handled in a few other situations, such
+as the \fBcatch\fR command, Tk event bindings, and the outermost
+scripts of procedure bodies.
+.SH EXAMPLE
+.PP
+Print a line for each of the integers from 0 to 5:
+.PP
+.CS
+for {set x 0} {$x<10} {incr x} {
+    if {$x > 5} {
+        \fBbreak\fR
+    }
+    puts "x is $x"
+}
+.CE
+.SH "SEE ALSO"
+catch(n), continue(n), for(n), foreach(n), return(n), while(n)
+.SH KEYWORDS
+abort, break, loop
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/doc/case.n b/doc/case.n
new file mode 100644
index 0000000..54d5bf4
--- /dev/null
+++ b/doc/case.n
@@ -0,0 +1,60 @@
+'\"
+'\" Copyright (c) 1993 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\" 
+.TH case n 7.0 Tcl "Tcl Built-In Commands"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+case \- Evaluate one of several scripts, depending on a given value
+.SH SYNOPSIS
+\fBcase\fI string \fR?\fBin\fR? \fIpatList body \fR?\fIpatList body \fR...?
+.sp
+\fBcase\fI string \fR?\fBin\fR? {\fIpatList body \fR?\fIpatList body \fR...?}
+.BE
+
+.SH DESCRIPTION
+.PP
+\fINote: the \fBcase\fI command is obsolete and is supported only
+for backward compatibility.  At some point in the future it may be
+removed entirely.  You should use the \fBswitch\fI command instead.\fR
+.PP
+The \fBcase\fR command matches \fIstring\fR against each of
+the \fIpatList\fR arguments in order.
+Each \fIpatList\fR argument is a list of one or
+more patterns.  If any of these patterns matches \fIstring\fR then
+\fBcase\fR evaluates the following \fIbody\fR argument
+by passing it recursively to the Tcl interpreter and returns the result
+of that evaluation.
+Each \fIpatList\fR argument consists of a single
+pattern or list of patterns.  Each pattern may contain any of the wild-cards
+described under \fBstring match\fR.  If a \fIpatList\fR
+argument is \fBdefault\fR, the corresponding body will be evaluated
+if no \fIpatList\fR matches \fIstring\fR.  If no \fIpatList\fR argument
+matches \fIstring\fR and no default is given, then the \fBcase\fR
+command returns an empty string.
+.PP
+Two syntaxes are provided for the \fIpatList\fR and \fIbody\fR arguments.
+The first uses a separate argument for each of the patterns and commands;
+this form is convenient if substitutions are desired on some of the
+patterns or commands.
+The second form places all of the patterns and commands together into
+a single argument; the argument must have proper list structure, with
+the elements of the list being the patterns and commands.
+The second form makes it easy to construct multi-line case commands,
+since the braces around the whole list make it unnecessary to include a
+backslash at the end of each line.
+Since the \fIpatList\fR arguments are in braces in the second form,
+no command or variable substitutions are performed on them;  this makes
+the behavior of the second form different than the first form in some
+cases.
+
+.SH "SEE ALSO"
+switch(n)
+
+.SH KEYWORDS
+case, match, regular expression
diff --git a/doc/catch.n b/doc/catch.n
new file mode 100644
index 0000000..d43a7ec
--- /dev/null
+++ b/doc/catch.n
@@ -0,0 +1,125 @@
+'\"
+'\" Copyright (c) 1993-1994 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\" Contributions from Don Porter, NIST, 2003.  (not subject to US copyright)
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH catch n "8.5" Tcl "Tcl Built-In Commands"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+catch \- Evaluate script and trap exceptional returns
+.SH SYNOPSIS
+\fBcatch\fI script \fR?\fIresultVarName\fR? ?\fIoptionsVarName\fR?
+.BE
+.SH DESCRIPTION
+.PP
+The \fBcatch\fR command may be used to prevent errors from aborting command
+interpretation.  The \fBcatch\fR command calls the Tcl interpreter recursively
+to execute \fIscript\fR, and always returns without raising an error,
+regardless of any errors that might occur while executing \fIscript\fR.
+.PP
+If \fIscript\fR raises an error, \fBcatch\fR will return a non-zero integer
+value corresponding to the exceptional return code returned by evaluation
+of \fIscript\fR.  Tcl defines the normal return code from script
+evaluation to be zero (0), or \fBTCL_OK\fR.  Tcl also defines four exceptional
+return codes: 1 (\fBTCL_ERROR\fR), 2 (\fBTCL_RETURN\fR), 3 (\fBTCL_BREAK\fR),
+and 4 (\fBTCL_CONTINUE\fR).  Errors during evaluation of a script are indicated
+by a return code of \fBTCL_ERROR\fR.  The other exceptional return codes are
+returned by the \fBreturn\fR, \fBbreak\fR, and \fBcontinue\fR commands
+and in other special situations as documented.  Tcl packages can define
+new commands that return other integer values as return codes as well,
+and scripts that make use of the \fBreturn \-code\fR command can also
+have return codes other than the five defined by Tcl.
+.PP
+If the \fIresultVarName\fR argument is given, then the variable it names is
+set to the result of the script evaluation.  When the return code from the
+script is 1 (\fBTCL_ERROR\fR), the value stored in \fIresultVarName\fR is an
+error message.  When the return code from the script is 0 (\fBTCL_OK\fR), the
+value stored in \fIresultVarName\fR is the value returned from \fIscript\fR.
+.PP
+If the \fIoptionsVarName\fR argument is given, then the variable it
+names is set to a dictionary of return options returned by evaluation
+of \fIscript\fR.  Tcl specifies two entries that are always
+defined in the dictionary: \fB\-code\fR and \fB\-level\fR.  When
+the return code from evaluation of \fIscript\fR is not \fBTCL_RETURN\fR,
+the value of the \fB\-level\fR entry will be 0, and the value
+of the \fB\-code\fR entry will be the same as the return code.
+Only when the return code is \fBTCL_RETURN\fR will the values of
+the \fB\-level\fR and \fB\-code\fR entries be something else, as
+further described in the documentation for the \fBreturn\fR command.
+.PP
+When the return code from evaluation of \fIscript\fR is
+\fBTCL_ERROR\fR, four additional entries are defined in the dictionary
+of return options stored in \fIoptionsVarName\fR: \fB\-errorinfo\fR,
+\fB\-errorcode\fR, \fB\-errorline\fR, and
+.VS 8.6
+\fB\-errorstack\fR.
+.VE 8.6
+The value of the \fB\-errorinfo\fR entry is a formatted stack trace containing
+more information about the context in which the error happened.  The formatted
+stack trace is meant to be read by a person.  The value of the
+\fB\-errorcode\fR entry is additional information about the error stored as a
+list.  The \fB\-errorcode\fR value is meant to be further processed by
+programs, and may not be particularly readable by people.  The value of the
+\fB\-errorline\fR entry is an integer indicating which line of \fIscript\fR
+was being evaluated when the error occurred.
+.VS 8.6
+The value of the \fB\-errorstack\fR entry is an
+even-sized list made of token-parameter pairs accumulated while
+unwinding the stack. The token may be
+.QW \fBCALL\fR ,
+in which case the parameter is a list made of the proc name and arguments at
+the corresponding level; or it may be
+.QW \fBUP\fR ,
+in which case the parameter is
+the relative level (as in \fBuplevel\fR) of the previous \fBCALL\fR. The
+salient differences with respect to \fB\-errorinfo\fR are that:
+.IP [1]
+it is a machine-readable form that is amenable to processing with
+[\fBforeach\fR {tok prm} ...],
+.IP [2]
+it contains the true (substituted) values passed to the functions, instead of
+the static text of the calling sites, and
+.IP [3]
+it is coarser-grained, with only one element per stack frame (like procs; no
+separate elements for \fBforeach\fR constructs for example).
+.VE 8.6
+.PP
+The values of the \fB\-errorinfo\fR and \fB\-errorcode\fR entries of
+the most recent error are also available as values of the global
+variables \fB::errorInfo\fR and \fB::errorCode\fR respectively.
+.VS 8.6
+The value of the \fB\-errorstack\fR entry surfaces as \fBinfo errorstack\fR.
+.VE 8.6
+.PP
+Tcl packages may provide commands that set other entries in the
+dictionary of return options, and the \fBreturn\fR command may be
+used by scripts to set return options in addition to those defined
+above.
+.SH EXAMPLES
+.PP
+The \fBcatch\fR command may be used in an \fBif\fR to branch based on
+the success of a script.
+.PP
+.CS
+if { [\fBcatch\fR {open $someFile w} fid] } {
+    puts stderr "Could not open $someFile for writing\en$fid"
+    exit 1
+}
+.CE
+.PP
+There are more complex examples of \fBcatch\fR usage in the
+documentation for the \fBreturn\fR command.
+.SH "SEE ALSO"
+break(n), continue(n), dict(n), error(n), errorCode(n), errorInfo(n), info(n),
+return(n)
+.SH KEYWORDS
+catch, error, exception
+'\" Local Variables:
+'\" mode: nroff
+'\" fill-column: 78
+'\" End:
diff --git a/doc/cd.n b/doc/cd.n
new file mode 100644
index 0000000..67cdd17
--- /dev/null
+++ b/doc/cd.n
@@ -0,0 +1,43 @@
+'\"
+'\" Copyright (c) 1993 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\" 
+.TH cd n "" Tcl "Tcl Built-In Commands"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+cd \- Change working directory
+.SH SYNOPSIS
+\fBcd \fR?\fIdirName\fR?
+.BE
+.SH DESCRIPTION
+.PP
+Change the current working directory to \fIdirName\fR, or to the
+home directory (as specified in the HOME environment variable) if
+\fIdirName\fR is not given.
+Returns an empty string.
+Note that the current working directory is a per-process resource; the
+\fBcd\fR command changes the working directory for all interpreters
+and (in a threaded environment) all threads.
+.SH EXAMPLES
+.PP
+Change to the home directory of the user \fBfred\fR:
+.PP
+.CS
+\fBcd\fR ~fred
+.CE
+.PP
+Change to the directory \fBlib\fR that is a sibling directory of the
+current one:
+.PP
+.CS
+\fBcd\fR ../lib
+.CE
+.SH "SEE ALSO"
+filename(n), glob(n), pwd(n)
+.SH KEYWORDS
+working directory
diff --git a/doc/chan.n b/doc/chan.n
new file mode 100644
index 0000000..81aa9f4
--- /dev/null
+++ b/doc/chan.n
@@ -0,0 +1,850 @@
+'\"
+'\" Copyright (c) 2005-2006 Donal K. Fellows
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+.TH chan n 8.5 Tcl "Tcl Built-In Commands"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+chan \- Read, write and manipulate channels
+.SH SYNOPSIS
+\fBchan \fIoption\fR ?\fIarg arg ...\fR?
+.BE
+.SH DESCRIPTION
+.PP
+This command provides several operations for reading from, writing to
+and otherwise manipulating open channels (such as have been created
+with the \fBopen\fR and \fBsocket\fR commands, or the default named
+channels \fBstdin\fR, \fBstdout\fR or \fBstderr\fR which correspond to
+the process's standard input, output and error streams respectively).
+\fIOption\fR indicates what to do with the channel; any unique
+abbreviation for \fIoption\fR is acceptable. Valid options are:
+.TP
+\fBchan blocked \fIchannelId\fR
+.
+This tests whether the last input operation on the channel called
+\fIchannelId\fR failed because it would have otherwise caused the
+process to block, and returns 1 if that was the case. It returns 0
+otherwise. Note that this only ever returns 1 when the channel has
+been configured to be non-blocking; all Tcl channels have blocking
+turned on by default.
+.TP
+\fBchan close \fIchannelId\fR ?\fIdirection\fR?
+.
+Close and destroy the channel called \fIchannelId\fR. Note that this
+deletes all existing file-events registered on the channel.
+.VS 8.6
+If the \fIdirection\fR argument (which must be \fBread\fR or \fBwrite\fR or
+any unique abbreviation of them) is present, the channel will only be
+half-closed, so that it can go from being read-write to write-only or
+read-only respectively. If a read-only channel is closed for reading, it is
+the same as if the channel is fully closed, and respectively similar for
+write-only channels. Without the \fIdirection\fR argument, the channel is
+closed for both reading and writing (but only if those directions are
+currently open). It is an error to close a read-only channel for writing, or a
+write-only channel for reading.
+.VE 8.6
+.RS
+.PP
+As part of closing the channel, all buffered output is flushed to the
+channel's output device (only if the channel is ceasing to be writable), any
+buffered input is discarded (only if the channel is ceasing to be readable),
+the underlying operating system resource is closed and \fIchannelId\fR becomes
+unavailable for future use (both only if the channel is being completely
+closed).
+.PP
+If the channel is blocking and the channel is ceasing to be writable, the
+command does not return until all output is flushed.  If the channel is
+non-blocking and there is unflushed output, the channel remains open and the
+command returns immediately; output will be flushed in the background and the
+channel will be closed when all the flushing is complete.
+.PP
+If \fIchannelId\fR is a blocking channel for a command pipeline then
+\fBchan close\fR waits for the child processes to complete.
+.PP
+If the channel is shared between interpreters, then \fBchan close\fR
+makes \fIchannelId\fR unavailable in the invoking interpreter but has
+no other effect until all of the sharing interpreters have closed the
+channel. When the last interpreter in which the channel is registered
+invokes \fBchan close\fR (or \fBclose\fR), the cleanup actions
+described above occur. With half-closing, the half-close of the channel only
+applies to the current interpreter's view of the channel until all channels
+have closed it in that direction (or completely).
+See the \fBinterp\fR command for a description of channel sharing.
+.PP
+Channels are automatically fully closed when an interpreter is destroyed and
+when the process exits.  Channels are switched to blocking mode, to
+ensure that all output is correctly flushed before the process exits.
+.PP
+The command returns an empty string, and may generate an error if
+an error occurs while flushing output.  If a command in a command
+pipeline created with \fBopen\fR returns an error, \fBchan close\fR
+generates an error (similar to the \fBexec\fR command.)
+.PP
+.VS 8.6
+Note that half-closes of sockets and command pipelines can have important side
+effects because they result in a shutdown() or close() of the underlying
+system resource, which can change how other processes or systems respond to
+the Tcl program.
+.VE 8.6
+.RE
+.TP
+\fBchan configure \fIchannelId\fR ?\fIoptionName\fR? ?\fIvalue\fR? ?\fIoptionName value\fR?...
+.
+Query or set the configuration options of the channel named
+\fIchannelId\fR.
+.RS
+.PP
+If no \fIoptionName\fR or \fIvalue\fR arguments are supplied, the
+command returns a list containing alternating option names and values
+for the channel.  If \fIoptionName\fR is supplied but no \fIvalue\fR
+then the command returns the current value of the given option.  If
+one or more pairs of \fIoptionName\fR and \fIvalue\fR are supplied,
+the command sets each of the named options to the corresponding
+\fIvalue\fR; in this case the return value is an empty string.
+.PP
+The options described below are supported for all channels. In
+addition, each channel type may add options that only it supports. See
+the manual entry for the command that creates each type of channel
+for the options supported by that specific type of channel. For
+example, see the manual entry for the \fBsocket\fR command for additional
+options for sockets, and the \fBopen\fR command for additional options for
+serial devices.
+.TP
+\fB\-blocking\fR \fIboolean\fR
+.
+The \fB\-blocking\fR option determines whether I/O operations on the
+channel can cause the process to block indefinitely.  The value of the
+option must be a proper boolean value.  Channels are normally in
+blocking mode; if a channel is placed into non-blocking mode it will
+affect the operation of the \fBchan gets\fR, \fBchan read\fR, \fBchan
+puts\fR, \fBchan flush\fR, and \fBchan close\fR commands; see the
+documentation for those commands for details.  For non-blocking mode to
+work correctly, the application must be using the Tcl event loop
+(e.g. by calling \fBTcl_DoOneEvent\fR or invoking the \fBvwait\fR
+command).
+.TP
+\fB\-buffering\fR \fInewValue\fR
+.
+If \fInewValue\fR is \fBfull\fR then the I/O system will buffer output
+until its internal buffer is full or until the \fBchan flush\fR
+command is invoked. If \fInewValue\fR is \fBline\fR, then the I/O
+system will automatically flush output for the channel whenever a
+newline character is output. If \fInewValue\fR is \fBnone\fR, the I/O
+system will flush automatically after every output operation.  The
+default is for \fB\-buffering\fR to be set to \fBfull\fR except for
+channels that connect to terminal-like devices; for these channels the
+initial setting is \fBline\fR.  Additionally, \fBstdin\fR and
+\fBstdout\fR are initially set to \fBline\fR, and \fBstderr\fR is set
+to \fBnone\fR.
+.TP
+\fB\-buffersize\fR \fInewSize\fR
+.
+\fINewvalue\fR must be an integer; its value is used to set the size
+of buffers, in bytes, subsequently allocated for this channel to store
+input or output. \fINewvalue\fR must be a number of no more than one
+million, allowing buffers of up to one million bytes in size.
+.TP
+\fB\-encoding\fR \fIname\fR
+.
+This option is used to specify the encoding of the channel as one of
+the named encodings returned by \fBencoding names\fR or the special
+value \fBbinary\fR, so that the data can be converted to and from
+Unicode for use in Tcl.  For instance, in order for Tcl to read
+characters from a Japanese file in \fBshiftjis\fR and properly process
+and display the contents, the encoding would be set to \fBshiftjis\fR.
+Thereafter, when reading from the channel, the bytes in the Japanese
+file would be converted to Unicode as they are read.  Writing is also
+supported \- as Tcl strings are written to the channel they will
+automatically be converted to the specified encoding on output.
+.RS
+.PP
+If a file contains pure binary data (for instance, a JPEG image), the
+encoding for the channel should be configured to be \fBbinary\fR.  Tcl
+will then assign no interpretation to the data in the file and simply
+read or write raw bytes.  The Tcl \fBbinary\fR command can be used to
+manipulate this byte-oriented data.  It is usually better to set the
+\fB\-translation\fR option to \fBbinary\fR when you want to transfer
+binary data, as this turns off the other automatic interpretations of
+the bytes in the stream as well.
+.PP
+The default encoding for newly opened channels is the same platform-
+and locale-dependent system encoding used for interfacing with the
+operating system, as returned by \fBencoding system\fR.
+.RE
+.TP
+\fB\-eofchar\fR \fIchar\fR
+.TP
+\fB\-eofchar\fR \fB{\fIinChar outChar\fB}\fR
+.
+This option supports DOS file systems that use Control-z (\ex1a) as an
+end of file marker.  If \fIchar\fR is not an empty string, then this
+character signals end-of-file when it is encountered during input.
+For output, the end-of-file character is output when the channel is
+closed.  If \fIchar\fR is the empty string, then there is no special
+end of file character marker.  For read-write channels, a two-element
+list specifies the end of file marker for input and output,
+respectively.  As a convenience, when setting the end-of-file
+character for a read-write channel you can specify a single value that
+will apply to both reading and writing.  When querying the end-of-file
+character of a read-write channel, a two-element list will always be
+returned.  The default value for \fB\-eofchar\fR is the empty string
+in all cases except for files under Windows.  In that case the
+\fB\-eofchar\fR is Control-z (\ex1a) for reading and the empty string
+for writing.
+The acceptable range for \fB\-eofchar\fR values is \ex01 - \ex7f;
+attempting to set \fB\-eofchar\fR to a value outside of this range will
+generate an error.
+.TP
+\fB\-translation\fR \fImode\fR
+.TP
+\fB\-translation\fR \fB{\fIinMode outMode\fB}\fR
+.
+In Tcl scripts the end of a line is always represented using a single
+newline character (\en).  However, in actual files and devices the end
+of a line may be represented differently on different platforms, or
+even for different devices on the same platform.  For example, under
+UNIX newlines are used in files, whereas carriage-return-linefeed
+sequences are normally used in network connections.  On input (i.e.,
+with \fBchan gets\fR and \fBchan read\fR) the Tcl I/O system
+automatically translates the external end-of-line representation into
+newline characters.  Upon output (i.e., with \fBchan puts\fR), the I/O
+system translates newlines to the external end-of-line representation.
+The default translation mode, \fBauto\fR, handles all the common cases
+automatically, but the \fB\-translation\fR option provides explicit
+control over the end of line translations.
+.RS
+.PP
+The value associated with \fB\-translation\fR is a single item for
+read-only and write-only channels.  The value is a two-element list for
+read-write channels; the read translation mode is the first element of
+the list, and the write translation mode is the second element.  As a
+convenience, when setting the translation mode for a read-write channel
+you can specify a single value that will apply to both reading and
+writing.  When querying the translation mode of a read-write channel, a
+two-element list will always be returned.  The following values are
+currently supported:
+.TP
+\fBauto\fR
+.
+As the input translation mode, \fBauto\fR treats any of newline
+(\fBlf\fR), carriage return (\fBcr\fR), or carriage return followed by
+a newline (\fBcrlf\fR) as the end of line representation.  The end of
+line representation can even change from line-to-line, and all cases
+are translated to a newline.  As the output translation mode,
+\fBauto\fR chooses a platform specific representation; for sockets on
+all platforms Tcl chooses \fBcrlf\fR, for all Unix flavors, it chooses
+\fBlf\fR, and for the various flavors of Windows it chooses
+\fBcrlf\fR.  The default setting for \fB\-translation\fR is \fBauto\fR
+for both input and output.
+.TP
+\fBbinary\fR
+.
+No end-of-line translations are performed.  This is nearly identical
+to \fBlf\fR mode, except that in addition \fBbinary\fR mode also sets
+the end-of-file character to the empty string (which disables it) and
+sets the encoding to \fBbinary\fR (which disables encoding filtering).
+See the description of \fB\-eofchar\fR and \fB\-encoding\fR for more
+information.
+.TP
+\fBcr\fR
+.
+The end of a line in the underlying file or device is represented by a
+single carriage return character.  As the input translation mode,
+\fBcr\fR mode converts carriage returns to newline characters.  As the
+output translation mode, \fBcr\fR mode translates newline characters
+to carriage returns.
+.TP
+\fBcrlf\fR
+.
+The end of a line in the underlying file or device is represented by a
+carriage return character followed by a linefeed character.  As the
+input translation mode, \fBcrlf\fR mode converts
+carriage-return-linefeed sequences to newline characters.  As the
+output translation mode, \fBcrlf\fR mode translates newline characters
+to carriage-return-linefeed sequences.  This mode is typically used on
+Windows platforms and for network connections.
+.TP
+\fBlf\fR
+.
+The end of a line in the underlying file or device is represented by a
+single newline (linefeed) character.  In this mode no translations
+occur during either input or output.  This mode is typically used on
+UNIX platforms.
+.RE
+.RE
+.TP
+\fBchan copy \fIinputChan outputChan\fR ?\fB\-size \fIsize\fR? ?\fB\-command \fIcallback\fR?
+.
+Copy data from the channel \fIinputChan\fR, which must have been
+opened for reading, to the channel \fIoutputChan\fR, which must have
+been opened for writing. The \fBchan copy\fR command leverages the
+buffering in the Tcl I/O system to avoid extra copies and to avoid
+buffering too much data in main memory when copying large files to
+slow destinations like network sockets.
+.RS
+.PP
+The \fBchan copy\fR command transfers data from \fIinputChan\fR until
+end of file or \fIsize\fR bytes or characters have been transferred;
+\fIsize\fR is in bytes if the two channels are using the same encoding,
+and is in characters otherwise.  If no \fB\-size\fR argument is given,
+then the copy goes until end of file. All the data read from
+\fIinputChan\fR is copied to \fIoutputChan\fR.  Without the
+\fB\-command\fR option, \fBchan copy\fR blocks until the copy is
+complete and returns the number of bytes or characters (using the same
+rules as for the \fB\-size\fR option) written to \fIoutputChan\fR.
+.PP
+The \fB\-command\fR argument makes \fBchan copy\fR work in the
+background.  In this case it returns immediately and the
+\fIcallback\fR is invoked later when the copy completes.  The
+\fIcallback\fR is called with one or two additional arguments that
+indicates how many bytes were written to \fIoutputChan\fR.  If an
+error occurred during the background copy, the second argument is the
+error string associated with the error.  With a background copy, it is
+not necessary to put \fIinputChan\fR or \fIoutputChan\fR into
+non-blocking mode; the \fBchan copy\fR command takes care of that
+automatically.  However, it is necessary to enter the event loop by
+using the \fBvwait\fR command or by using Tk.
+.PP
+You are not allowed to do other I/O operations with \fIinputChan\fR or
+\fIoutputChan\fR during a background \fBchan copy\fR.  If either
+\fIinputChan\fR or \fIoutputChan\fR get closed while the copy is in
+progress, the current copy is stopped and the command callback is
+\fInot\fR made.  If \fIinputChan\fR is closed, then all data already
+queued for \fIoutputChan\fR is written out.
+.PP
+Note that \fIinputChan\fR can become readable during a background
+copy.  You should turn off any \fBchan event\fR or \fBfileevent\fR
+handlers during a background copy so those handlers do not interfere
+with the copy.  Any I/O attempted by a \fBchan event\fR or
+\fBfileevent\fR handler will get a
+.QW "channel busy"
+error.
+.PP
+\fBChan copy\fR translates end-of-line sequences in \fIinputChan\fR
+and \fIoutputChan\fR according to the \fB\-translation\fR option for
+these channels (see \fBchan configure\fR above).  The translations
+mean that the number of bytes read from \fIinputChan\fR can be
+different than the number of bytes written to \fIoutputChan\fR.  Only
+the number of bytes written to \fIoutputChan\fR is reported, either as
+the return value of a synchronous \fBchan copy\fR or as the argument
+to the callback for an asynchronous \fBchan copy\fR.
+.PP
+\fBChan copy\fR obeys the encodings and character translations
+configured for the channels. This means that the incoming characters
+are converted internally first UTF-8 and then into the encoding of the
+channel \fBchan copy\fR writes to (see \fBchan configure\fR above for
+details on the \fB\-encoding\fR and \fB\-translation\fR options). No
+conversion is done if both channels are set to encoding \fBbinary\fR
+and have matching translations. If only the output channel is set to
+encoding \fBbinary\fR the system will write the internal UTF-8
+representation of the incoming characters. If only the input channel
+is set to encoding \fBbinary\fR the system will assume that the
+incoming bytes are valid UTF-8 characters and convert them according
+to the output encoding. The behaviour of the system for bytes which
+are not valid UTF-8 characters is undefined in this case.
+.RE
+.TP
+\fBchan create \fImode cmdPrefix\fR
+.
+This subcommand creates a new script level channel using the command
+prefix \fIcmdPrefix\fR as its handler. Any such channel is called a
+\fBreflected\fR channel. The specified command prefix, \fBcmdPrefix\fR,
+must be a non-empty list, and should provide the API described in the
+\fBrefchan\fR manual page. The handle of the new channel is
+returned as the result of the \fBchan create\fR command, and the
+channel is open. Use either \fBclose\fR or \fBchan close\fR to remove
+the channel.
+.RS
+.PP
+The argument \fImode\fR specifies if the new channel is opened for
+reading, writing, or both. It has to be a list containing any of the
+strings
+.QW \fBread\fR
+or
+.QW \fBwrite\fR .
+The list must have at least one
+element, as a channel you can neither write to nor read from makes no
+sense. The handler command for the new channel must support the chosen
+mode, or an error is thrown.
+.PP
+The command prefix is executed in the global namespace, at the top of
+call stack, following the appending of arguments as described in the
+\fBrefchan\fR manual page. Command resolution happens at the
+time of the call. Renaming the command, or destroying it means that
+the next call of a handler method may fail, causing the channel
+command invoking the handler to fail as well. Depending on the
+subcommand being invoked, the error message may not be able to explain
+the reason for that failure.
+.PP
+Every channel created with this subcommand knows which interpreter it
+was created in, and only ever executes its handler command in that
+interpreter, even if the channel was shared with and/or was moved into
+a different interpreter. Each reflected channel also knows the thread
+it was created in, and executes its handler command only in that
+thread, even if the channel was moved into a different thread. To this
+end all invocations of the handler are forwarded to the original
+thread by posting special events to it. This means that the original
+thread (i.e. the thread that executed the \fBchan create\fR command)
+must have an active event loop, i.e. it must be able to process such
+events. Otherwise the thread sending them will \fIblock
+indefinitely\fR. Deadlock may occur.
+.PP
+Note that this permits the creation of a channel whose two endpoints
+live in two different threads, providing a stream-oriented bridge
+between these threads. In other words, we can provide a way for
+regular stream communication between threads instead of having to send
+commands.
+.PP
+When a thread or interpreter is deleted, all channels created with
+this subcommand and using this thread/interpreter as their computing
+base are deleted as well, in all interpreters they have been shared
+with or moved into, and in whatever thread they have been transferred
+to. While this pulls the rug out under the other thread(s) and/or
+interpreter(s), this cannot be avoided. Trying to use such a channel
+will cause the generation of a regular error about unknown channel
+handles.
+.PP
+This subcommand is \fBsafe\fR and made accessible to safe
+interpreters.  While it arranges for the execution of arbitrary Tcl
+code the system also makes sure that the code is always executed
+within the safe interpreter.
+.RE
+.TP
+\fBchan eof \fIchannelId\fR
+.
+Test whether the last input operation on the channel called
+\fIchannelId\fR failed because the end of the data stream was reached,
+returning 1 if end-of-file was reached, and 0 otherwise.
+.TP
+\fBchan event \fIchannelId event\fR ?\fIscript\fR?
+.
+Arrange for the Tcl script \fIscript\fR to be installed as a \fIfile
+event handler\fR to be called whenever the channel called
+\fIchannelId\fR enters the state described by \fIevent\fR (which must
+be either \fBreadable\fR or \fBwritable\fR); only one such handler may
+be installed per event per channel at a time.  If \fIscript\fR is the
+empty string, the current handler is deleted (this also happens if the
+channel is closed or the interpreter deleted).  If \fIscript\fR is
+omitted, the currently installed script is returned (or an empty
+string if no such handler is installed).  The callback is only
+performed if the event loop is being serviced (e.g. via \fBvwait\fR or
+\fBupdate\fR).
+.RS
+.PP
+A file event handler is a binding between a channel and a script, such
+that the script is evaluated whenever the channel becomes readable or
+writable.  File event handlers are most commonly used to allow data to
+be received from another process on an event-driven basis, so that the
+receiver can continue to interact with the user or with other channels
+while waiting for the data to arrive.  If an application invokes
+\fBchan gets\fR or \fBchan read\fR on a blocking channel when there is
+no input data available, the process will block; until the input data
+arrives, it will not be able to service other events, so it will
+appear to the user to
+.QW "freeze up" .
+With \fBchan event\fR, the
+process can tell when data is present and only invoke \fBchan gets\fR
+or \fBchan read\fR when they will not block.
+.PP
+A channel is considered to be readable if there is unread data
+available on the underlying device.  A channel is also considered to
+be readable if there is unread data in an input buffer, except in the
+special case where the most recent attempt to read from the channel
+was a \fBchan gets\fR call that could not find a complete line in the
+input buffer.  This feature allows a file to be read a line at a time
+in non-blocking mode using events.  A channel is also considered to be
+readable if an end of file or error condition is present on the
+underlying file or device.  It is important for \fIscript\fR to check
+for these conditions and handle them appropriately; for example, if
+there is no special check for end of file, an infinite loop may occur
+where \fIscript\fR reads no data, returns, and is immediately invoked
+again.
+.PP
+A channel is considered to be writable if at least one byte of data
+can be written to the underlying file or device without blocking, or
+if an error condition is present on the underlying file or device.
+Note that client sockets opened in asynchronous mode become writable
+when they become connected or if the connection fails.
+.PP
+Event-driven I/O works best for channels that have been placed into
+non-blocking mode with the \fBchan configure\fR command.  In blocking
+mode, a \fBchan puts\fR command may block if you give it more data
+than the underlying file or device can accept, and a \fBchan gets\fR
+or \fBchan read\fR command will block if you attempt to read more data
+than is ready; no events will be processed while the commands block.
+In non-blocking mode \fBchan puts\fR, \fBchan read\fR, and \fBchan
+gets\fR never block.
+.PP
+The script for a file event is executed at global level (outside the
+context of any Tcl procedure) in the interpreter in which the \fBchan
+event\fR command was invoked.  If an error occurs while executing the
+script then the command registered with \fBinterp bgerror\fR is used
+to report the error.  In addition, the file event handler is deleted
+if it ever returns an error; this is done in order to prevent infinite
+loops due to buggy handlers.
+.RE
+.TP
+\fBchan flush \fIchannelId\fR
+.
+Ensures that all pending output for the channel called \fIchannelId\fR
+is written.
+.RS
+.PP
+If the channel is in blocking mode the command does not return until
+all the buffered output has been flushed to the channel. If the
+channel is in non-blocking mode, the command may return before all
+buffered output has been flushed; the remainder will be flushed in the
+background as fast as the underlying file or device is able to absorb
+it.
+.RE
+.TP
+\fBchan gets \fIchannelId\fR ?\fIvarName\fR?
+.
+Reads the next line from the channel called \fIchannelId\fR. If
+\fIvarName\fR is not specified, the result of the command will be the
+line that has been read (without a trailing newline character) or an
+empty string upon end-of-file or, in non-blocking mode, if the data
+available is exhausted. If \fIvarName\fR is specified, the line that
+has been read will be written to the variable called \fIvarName\fR and
+result will be the number of characters that have been read or -1 if
+end-of-file was reached or, in non-blocking mode, if the data
+available is exhausted.
+.RS
+.PP
+If an end-of-file occurs while part way through reading a line, the
+partial line will be returned (or written into \fIvarName\fR). When
+\fIvarName\fR is not specified, the end-of-file case can be
+distinguished from an empty line using the \fBchan eof\fR command, and
+the partial-line-but-non-blocking case can be distinguished with the
+\fBchan blocked\fR command.
+.RE
+.TP
+\fBchan names\fR ?\fIpattern\fR?
+.
+Produces a list of all channel names. If \fIpattern\fR is specified,
+only those channel names that match it (according to the rules of
+\fBstring match\fR) will be returned.
+.TP
+\fBchan pending \fImode channelId\fR
+.
+Depending on whether \fImode\fR is \fBinput\fR or \fBoutput\fR,
+returns the number of
+bytes of input or output (respectively) currently buffered
+internally for \fIchannelId\fR (especially useful in a readable event
+callback to impose application-specific limits on input line lengths to avoid
+a potential denial-of-service attack where a hostile user crafts
+an extremely long line that exceeds the available memory to buffer it).
+Returns -1 if the channel was not opened for the mode in question.
+.TP
+\fBchan pipe\fR
+.VS 8.6
+Creates a standalone pipe whose read- and write-side channels are
+returned as a 2-element list, the first element being the read side and
+the second the write side. Can be useful e.g. to redirect
+separately \fBstderr\fR and \fBstdout\fR from a subprocess. To do
+this, spawn with "2>@" or
+">@" redirection operators onto the write side of a pipe, and then
+immediately close it in the parent. This is necessary to get an EOF on
+the read side once the child has exited or otherwise closed its output.
+.RS
+.PP
+Note that the pipe buffering semantics can vary at the operating system level
+substantially; it is not safe to assume that a write performed on the output
+side of the pipe will appear instantly to the input side. This is a
+fundamental difference and Tcl cannot conceal it. The overall stream semantics
+\fIare\fR compatible, so blocking reads and writes will not see most of the
+differences, but the details of what exactly gets written when are not. This
+is most likely to show up when using pipelines for testing; care should be
+taken to ensure that deadlocks do not occur and that potential short reads are
+allowed for.
+.RE
+.VE 8.6
+.TP
+\fBchan pop \fIchannelId\fR
+.VS 8.6
+Removes the topmost transformation from the channel \fIchannelId\fR, if there
+is any. If there are no transformations added to \fIchannelId\fR, this is
+equivalent to \fBchan close\fR of that channel. The result is normally the
+empty string, but can be an error in some situations (i.e. where the
+underlying system stream is closed and that results in an error).
+.VE 8.6
+.TP
+\fBchan postevent \fIchannelId eventSpec\fR
+.
+This subcommand is used by command handlers specified with \fBchan
+create\fR. It notifies the channel represented by the handle
+\fIchannelId\fR that the event(s) listed in the \fIeventSpec\fR have
+occurred. The argument has to be a list containing any of the strings
+\fBread\fR and \fBwrite\fR. The list must contain at least one
+element as it does not make sense to invoke the command if there are
+no events to post.
+.RS
+.PP
+Note that this subcommand can only be used with channel handles that
+were created/opened by \fBchan create\fR. All other channels will
+cause this subcommand to report an error.
+.PP
+As only the Tcl level of a channel, i.e. its command handler, should
+post events to it we also restrict the usage of this command to the
+interpreter that created the channel. In other words, posting events
+to a reflected channel from an interpreter that does not contain it's
+implementation is not allowed. Attempting to post an event from any
+other interpreter will cause this subcommand to report an error.
+.PP
+Another restriction is that it is not possible to post events that the
+I/O core has not registered an interest in. Trying to do so will cause
+the method to throw an error. See the command handler method
+\fBwatch\fR described in \fBrefchan\fR, the document specifying
+the API of command handlers for reflected channels.
+.PP
+This command is \fBsafe\fR and made accessible to safe interpreters.
+It can trigger the execution of \fBchan event\fR handlers, whether in the
+current interpreter or in other interpreters or other threads, even
+where the event is posted from a safe interpreter and listened for by
+a trusted interpreter. \fBChan event\fR handlers are \fIalways\fR
+executed in the interpreter that set them up.
+.RE
+.TP
+\fBchan push \fIchannelId cmdPrefix\fR
+.VS 8.6
+Adds a new transformation on top of the channel \fIchannelId\fR. The
+\fIcmdPrefix\fR argument describes a list of one or more words which represent
+a handler that will be used to implement the transformation. The command
+prefix must provide the API described in the \fBtranschan\fR manual page.
+The result of this subcommand is a handle to the transformation. Note that it
+is important to make sure that the transformation is capable of supporting the
+channel mode that it is used with or this can make the channel neither
+readable nor writable.
+.VE 8.6
+.TP
+\fBchan puts\fR ?\fB\-nonewline\fR? ?\fIchannelId\fR? \fIstring\fR
+.
+Writes \fIstring\fR to the channel named \fIchannelId\fR followed by a
+newline character. A trailing newline character is written unless the
+optional flag \fB\-nonewline\fR is given. If \fIchannelId\fR is
+omitted, the string is written to the standard output channel,
+\fBstdout\fR.
+.RS
+.PP
+Newline characters in the output are translated by \fBchan puts\fR to
+platform-specific end-of-line sequences according to the currently
+configured value of the \fB\-translation\fR option for the channel
+(for example, on PCs newlines are normally replaced with
+carriage-return-linefeed sequences; see \fBchan configure\fR above for
+details).
+.PP
+Tcl buffers output internally, so characters written with \fBchan
+puts\fR may not appear immediately on the output file or device; Tcl
+will normally delay output until the buffer is full or the channel is
+closed.  You can force output to appear immediately with the \fBchan
+flush\fR command.
+.PP
+When the output buffer fills up, the \fBchan puts\fR command will
+normally block until all the buffered data has been accepted for
+output by the operating system.  If \fIchannelId\fR is in non-blocking
+mode then the \fBchan puts\fR command will not block even if the
+operating system cannot accept the data.  Instead, Tcl continues to
+buffer the data and writes it in the background as fast as the
+underlying file or device can accept it.  The application must use the
+Tcl event loop for non-blocking output to work; otherwise Tcl never
+finds out that the file or device is ready for more output data.  It
+is possible for an arbitrarily large amount of data to be buffered for
+a channel in non-blocking mode, which could consume a large amount of
+memory.  To avoid wasting memory, non-blocking I/O should normally be
+used in an event-driven fashion with the \fBchan event\fR command
+(do not invoke \fBchan puts\fR unless you have recently been notified
+via a file event that the channel is ready for more output data).
+.RE
+.TP
+\fBchan read \fIchannelId\fR ?\fInumChars\fR?
+.TP
+\fBchan read \fR?\fB\-nonewline\fR? \fIchannelId\fR
+.
+In the first form, the result will be the next \fInumChars\fR
+characters read from the channel named \fIchannelId\fR; if
+\fInumChars\fR is omitted, all characters up to the point when the
+channel would signal a failure (whether an end-of-file, blocked or
+other error condition) are read. In the second form (i.e. when
+\fInumChars\fR has been omitted) the flag \fB\-nonewline\fR may be
+given to indicate that any trailing newline in the string that has
+been read should be trimmed.
+.RS
+.PP
+If \fIchannelId\fR is in non-blocking mode, \fBchan read\fR may not
+read as many characters as requested: once all available input has
+been read, the command will return the data that is available rather
+than blocking for more input.  If the channel is configured to use a
+multi-byte encoding, then there may actually be some bytes remaining
+in the internal buffers that do not form a complete character.  These
+bytes will not be returned until a complete character is available or
+end-of-file is reached.  The \fB\-nonewline\fR switch is ignored if
+the command returns before reaching the end of the file.
+.PP
+\fBChan read\fR translates end-of-line sequences in the input into
+newline characters according to the \fB\-translation\fR option for the
+channel (see \fBchan configure\fR above for a discussion on the ways
+in which \fBchan configure\fR will alter input).
+.PP
+When reading from a serial port, most applications should configure
+the serial port channel to be non-blocking, like this:
+.PP
+.CS
+\fBchan configure \fIchannelId \fB\-blocking \fI0\fR.
+.CE
+.PP
+Then \fBchan read\fR behaves much like described above.  Note that
+most serial ports are comparatively slow; it is entirely possible to
+get a \fBreadable\fR event for each character read from them. Care
+must be taken when using \fBchan read\fR on blocking serial ports:
+.TP
+\fBchan read \fIchannelId numChars\fR
+.
+In this form \fBchan read\fR blocks until \fInumChars\fR have been
+received from the serial port.
+.TP
+\fBchan read \fIchannelId\fR
+.
+In this form \fBchan read\fR blocks until the reception of the
+end-of-file character, see \fBchan configure -eofchar\fR. If there no
+end-of-file character has been configured for the channel, then
+\fBchan read\fR will block forever.
+.RE
+.TP
+\fBchan seek \fIchannelId offset\fR ?\fIorigin\fR?
+.
+Sets the current access position within the underlying data stream for
+the channel named \fIchannelId\fR to be \fIoffset\fR bytes relative to
+\fIorigin\fR. \fIOffset\fR must be an integer (which may be negative)
+and \fIorigin\fR must be one of the following:
+.RS
+.TP 10
+\fBstart\fR
+.
+The new access position will be \fIoffset\fR bytes from the start
+of the underlying file or device.
+.TP 10
+\fBcurrent\fR
+.
+The new access position will be \fIoffset\fR bytes from the current
+access position; a negative \fIoffset\fR moves the access position
+backwards in the underlying file or device.
+.TP 10
+\fBend\fR
+.
+The new access position will be \fIoffset\fR bytes from the end of the
+file or device.  A negative \fIoffset\fR places the access position
+before the end of file, and a positive \fIoffset\fR places the access
+position after the end of file.
+.PP
+The \fIorigin\fR argument defaults to \fBstart\fR.
+.PP
+\fBChan seek\fR flushes all buffered output for the channel before the
+command returns, even if the channel is in non-blocking mode.  It also
+discards any buffered and unread input.  This command returns an empty
+string.  An error occurs if this command is applied to channels whose
+underlying file or device does not support seeking.
+.PP
+Note that \fIoffset\fR values are byte offsets, not character offsets.
+Both \fBchan seek\fR and \fBchan tell\fR operate in terms of bytes,
+not characters, unlike \fBchan read\fR.
+.RE
+.TP
+\fBchan tell \fIchannelId\fR
+.
+Returns a number giving the current access position within the
+underlying data stream for the channel named \fIchannelId\fR. This
+value returned is a byte offset that can be passed to \fBchan seek\fR
+in order to set the channel to a particular position.  Note that this
+value is in terms of bytes, not characters like \fBchan read\fR.  The
+value returned is -1 for channels that do not support seeking.
+.TP
+\fBchan truncate \fIchannelId\fR ?\fIlength\fR?
+.
+Sets the byte length of the underlying data stream for the channel
+named \fIchannelId\fR to be \fIlength\fR (or to the current byte
+offset within the underlying data stream if \fIlength\fR is
+omitted). The channel is flushed before truncation.
+.
+.SH EXAMPLES
+.PP
+This opens a file using a known encoding (CP1252, a very common encoding
+on Windows), searches for a string, rewrites that part, and truncates the
+file after a further two lines.
+.PP
+.CS
+set f [open somefile.txt r+]
+\fBchan configure\fR $f -encoding cp1252
+set offset 0
+
+\fI# Search for string "FOOBAR" in the file\fR
+while {[\fBchan gets\fR $f line] >= 0} {
+    set idx [string first FOOBAR $line]
+    if {$idx > -1} {
+        \fI# Found it; rewrite line\fR
+
+        \fBchan seek\fR $f [expr {$offset + $idx}]
+        \fBchan puts\fR -nonewline $f BARFOO
+
+        \fI# Skip to end of following line, and truncate\fR
+        \fBchan gets\fR $f
+        \fBchan gets\fR $f
+        \fBchan truncate\fR $f
+
+        \fI# Stop searching the file now\fR
+        break
+    }
+
+    \fI# Save offset of start of next line for later\fR
+    set offset [\fBchan tell\fR $f]
+}
+\fBchan close\fR $f
+.CE
+.PP
+A network server that does echoing of its input line-by-line without
+preventing servicing of other connections at the same time.
+.PP
+.CS
+# This is a very simple logger...
+proc log {message} {
+    \fBchan puts\fR stdout $message
+}
+
+# This is called whenever a new client connects to the server
+proc connect {chan host port} {
+    set clientName [format <%s:%d> $host $port]
+    log "connection from $clientName"
+    \fBchan configure\fR $chan -blocking 0 -buffering line
+    \fBchan event\fR $chan readable [list echoLine $chan $clientName]
+}
+
+# This is called whenever either at least one byte of input
+# data is available, or the channel was closed by the client.
+proc echoLine {chan clientName} {
+    \fBchan gets\fR $chan line
+    if {[\fBchan eof\fR $chan]} {
+        log "finishing connection from $clientName"
+        \fBchan close\fR $chan
+    } elseif {![\fBchan blocked\fR $chan]} {
+        # Didn't block waiting for end-of-line
+        log "$clientName - $line"
+        \fBchan puts\fR $chan $line
+    }
+}
+
+# Create the server socket and enter the event-loop to wait
+# for incoming connections...
+socket -server connect 12345
+vwait forever
+.CE
+.SH "SEE ALSO"
+close(n), eof(n), fblocked(n), fconfigure(n), fcopy(n), file(n),
+fileevent(n), flush(n), gets(n), open(n), puts(n), read(n), seek(n),
+socket(n), tell(n), refchan(n), transchan(n)
+.SH KEYWORDS
+channel, input, output, events, offset
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/doc/class.n b/doc/class.n
new file mode 100644
index 0000000..198ae41
--- /dev/null
+++ b/doc/class.n
@@ -0,0 +1,136 @@
+'\"
+'\" Copyright (c) 2007 Donal K. Fellows
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH class n 0.1 TclOO "TclOO Commands"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+oo::class \- class of all classes
+.SH SYNOPSIS
+.nf
+package require TclOO
+
+\fBoo::class\fI method \fR?\fIarg ...\fR?
+.fi
+.SH "CLASS HIERARCHY"
+.nf
+\fBoo::object\fR
+   \(-> \fBoo::class\fR
+.fi
+.BE
+.SH DESCRIPTION
+.PP
+Classes are objects that can manufacture other objects according to a pattern
+stored in the factory object (the class). An instance of the class is created
+by calling one of the class's factory methods, typically either \fBcreate\fR
+if an explicit name is being given, or \fBnew\fR if an arbitrary unique name
+is to be automatically selected.
+.PP
+The \fBoo::class\fR class is the class of all classes; every class is an
+instance of this class, which is consequently an instance of itself. This
+class is a subclass of \fBoo::object\fR, so every class is also an object.
+Additional metaclasses (i.e., classes of classes) can be defined if necessary
+by subclassing \fBoo::class\fR. Note that the \fBoo::class\fR object hides the
+\fBnew\fR method on itself, so new classes should always be made using the
+\fBcreate\fR method.
+.SS CONSTRUCTOR
+.PP
+The constructor of the \fBoo::class\fR class takes an optional argument which,
+if present, is sent to the \fBoo::define\fR command (along with the name of
+the newly-created class) to allow the class to be conveniently configured at
+creation time.
+.SS DESTRUCTOR
+The \fBoo::class\fR class does not define an explicit destructor. However,
+when a class is destroyed, all its subclasses and instances are also
+destroyed, along with all objects that it has been mixed into.
+.SS "EXPORTED METHODS"
+.TP
+\fIcls \fBcreate \fIname \fR?\fIarg ...\fR?
+.
+This creates a new instance of the class \fIcls\fR called \fIname\fR (which is
+resolved within the calling context's namespace if not fully qualified),
+passing the arguments, \fIarg ...\fR, to the constructor, and (if that returns
+a successful result) returning the fully qualified name of the created object
+(the result of the constructor is ignored). If the constructor fails (i.e.
+returns a non-OK result) then the object is destroyed and the error message is
+the result of this method call.
+.TP
+\fIcls \fBnew \fR?\fIarg ...\fR?
+.
+This creates a new instance of the class \fIcls\fR with a new unique name,
+passing the arguments, \fIarg ...\fR, to the constructor, and (if that returns
+a successful result) returning the fully qualified name of the created object
+(the result of the constructor is ignored). If the constructor fails (i.e.,
+returns a non-OK result) then the object is destroyed and the error message is
+the result of this method call.
+.RS
+.PP
+Note that this method is not exported by the \fBoo::class\fR object itself, so
+classes should not be created using this method.
+.RE
+.SS "NON-EXPORTED METHODS"
+.PP
+The \fBoo::class\fR class supports the following non-exported methods:
+.TP
+\fIcls \fBcreateWithNamespace\fI name nsName\fR ?\fIarg ...\fR?
+.
+This creates a new instance of the class \fIcls\fR called \fIname\fR (which is
+resolved within the calling context's namespace if not fully qualified),
+passing the arguments, \fIarg ...\fR, to the constructor, and (if that returns
+a successful result) returning the fully qualified name of the created object
+(the result of the constructor is ignored). The name of the instance's
+internal namespace will be \fInsName\fR unless that namespace already exists
+(when an arbitrary name will be chosen instead). If the constructor fails
+(i.e., returns a non-OK result) then the object is destroyed and the error
+message is the result of this method call.
+.SH EXAMPLES
+.PP
+This example defines a simple class hierarchy and creates a new instance of
+it. It then invokes a method of the object before destroying the hierarchy and
+showing that the destruction is transitive.
+.PP
+.CS
+\fBoo::class create\fR fruit {
+    method eat {} {
+        puts "yummy!"
+    }
+}
+\fBoo::class create\fR banana {
+    superclass fruit
+    constructor {} {
+        my variable peeled
+        set peeled 0
+    }
+    method peel {} {
+        my variable peeled
+        set peeled 1
+        puts "skin now off"
+    }
+    method edible? {} {
+        my variable peeled
+        return $peeled
+    }
+    method eat {} {
+        if {![my edible?]} {
+            my peel
+        }
+        next
+    }
+}
+set b [banana \fBnew\fR]
+$b eat               \fI\(-> prints "skin now off" and "yummy!"\fR
+fruit destroy
+$b eat               \fI\(-> error "unknown command"\fR
+.CE
+.SH "SEE ALSO"
+oo::define(n), oo::object(n)
+.SH KEYWORDS
+class, metaclass, object
+.\" Local variables:
+.\" mode: nroff
+.\" fill-column: 78
+.\" End:
diff --git a/doc/clock.n b/doc/clock.n
new file mode 100644
index 0000000..889a5da
--- /dev/null
+++ b/doc/clock.n
@@ -0,0 +1,938 @@
+'\"
+'\" Generated from file './doc/clock.dt' by tcllib/doctools with format 'nroff'
+'\" Copyright (c) 2004 Kevin B. Kenny <kennykb@acm.org>. All rights reserved.
+'\"
+.TH "clock" n 8.5 Tcl "Tcl Built-In Commands"
+.so man.macros
+.BS
+.SH NAME
+clock \- Obtain and manipulate dates and times
+.SH "SYNOPSIS"
+package require \fBTcl 8.5\fR
+.sp
+\fBclock add\fR \fItimeVal\fR ?\fIcount unit...\fR? ?\fI\-option value\fR?
+.sp
+\fBclock clicks\fR ?\fI\-option\fR?
+.sp
+\fBclock format\fR \fItimeVal\fR ?\fI\-option value\fR...?
+.sp
+\fBclock microseconds\fR
+.sp
+\fBclock milliseconds\fR
+.sp
+\fBclock scan\fR \fIinputString\fR ?\fI\-option value\fR...?
+.sp
+\fBclock seconds\fR
+.sp
+.BE
+.SH "DESCRIPTION"
+.PP
+The \fBclock\fR command performs several operations that obtain and
+manipulate values that represent times.  The command supports several
+subcommands that determine what action is carried out by the command.
+.TP
+\fBclock add\fR \fItimeVal\fR ?\fIcount unit...\fR? ?\fI\-option value\fR?
+Adds a (possibly negative) offset to a time that is expressed as an
+integer number of seconds.  See \fBCLOCK ARITHMETIC\fR for a full description.
+.TP
+\fBclock clicks\fR ?\fI\-option\fR?
+If no \fI\-option\fR argument is supplied, returns a high-resolution
+time value as a system-dependent integer value.  The unit of the value
+is system-dependent but should be the highest resolution clock available
+on the system such as a CPU cycle counter.  See \fBHIGH RESOLUTION TIMERS\fR for a full description.
+.RS
+.PP
+If the \fI\-option\fR argument is \fB\-milliseconds\fR, then the command
+is synonymous with \fBclock milliseconds\fR (see below).  This
+usage is obsolete, and \fBclock milliseconds\fR is to be
+considered the preferred way of obtaining a count of milliseconds.
+.PP
+If the \fI\-option\fR argument is \fB\-microseconds\fR, then the command
+is synonymous with \fBclock microseconds\fR (see below).  This
+usage is obsolete, and \fBclock microseconds\fR is to be
+considered the preferred way of obtaining a count of microseconds.
+.RE
+.TP
+\fBclock format\fR \fItimeVal\fR ?\fI\-option value\fR...?
+Formats a time that is expressed as an integer number of seconds into a format
+intended for consumption by users or external programs.
+See \fBFORMATTING TIMES\fR for a full description.
+.TP
+\fBclock microseconds\fR
+Returns the current time as an integer number of microseconds.  See \fBHIGH RESOLUTION TIMERS\fR for a full description.
+.TP
+\fBclock milliseconds\fR
+Returns the current time as an integer number of milliseconds.  See \fBHIGH RESOLUTION TIMERS\fR for a full description.
+.TP
+\fBclock scan\fR \fIinputString\fR ?\fI\-option value\fR...?
+Scans a time that is expressed as a character string and produces an
+integer number of seconds.
+See \fBSCANNING TIMES\fR for a full description.
+.TP
+\fBclock seconds\fR
+Returns the current time as an integer number of seconds.
+.SS "PARAMETERS"
+.TP
+\fIcount\fR
+An integer representing a count of some unit of time.  See
+\fBCLOCK ARITHMETIC\fR for the details.
+.TP
+\fItimeVal\fR
+An integer value passed to the \fBclock\fR command that represents an
+absolute time as a number of seconds from the \fIepoch time\fR of
+1 January 1970, 00:00 UTC.  Note that the count of seconds does not
+include any leap seconds; seconds are counted as if each UTC day has
+exactly 86400 seconds.  Tcl responds to leap seconds by speeding or
+slowing its clock by a tiny fraction for some minutes until it is
+back in sync with UTC; its data model does not represent minutes that
+have 59 or 61 seconds.
+.TP
+\fIunit\fR
+One of the words, \fBseconds\fR, \fBminutes\fR, \fBhours\fR,
+\fBdays\fR, \fBweeks\fR, \fBmonths\fR, or \fByears\fR, or
+any unique prefix of such a word. Used in conjunction with \fIcount\fR
+to identify an interval of time, for example, \fI3 seconds\fR or
+\fI1 year\fR.
+.SS "OPTIONS"
+.TP
+\fB\-base\fR time
+Specifies that any relative times present in a \fBclock scan\fR command
+are to be given relative to \fItime\fR.  \fItime\fR must be expressed as
+a count of nominal seconds from the epoch time of 1 January 1970, 00:00 UTC.
+.TP
+\fB\-format\fR format
+Specifies the desired output format for \fBclock format\fR or the
+expected input format for \fBclock scan\fR.  The \fIformat\fR string consists
+of any number of characters other than the per-cent sign
+.PQ \fB%\fR
+interspersed with any number of \fIformat groups\fR, which are two-character
+sequences beginning with the per-cent sign.  The permissible format groups,
+and their interpretation, are described under \fBFORMAT GROUPS\fR.
+.RS
+.PP
+On \fBclock format\fR, the default format is
+.PP
+.CS
+%a %b %d %H:%M:%S %Z %Y
+.CE
+.PP
+On \fBclock scan\fR, the lack of a \fB\-format\fR option indicates that a
+.QW "free format scan"
+is requested; see \fBFREE FORM SCAN\fR for a description of what happens.
+.RE
+.TP
+\fB\-gmt\fR boolean
+If \fIboolean\fR is true, specifies that a time specified to \fBclock add\fR,
+\fBclock format\fR or \fBclock scan\fR should be processed in
+UTC.  If \fIboolean\fR is false, the processing defaults to the local time
+zone.  This usage is obsolete; the correct current usage is to
+specify the UTC time zone with
+.QW "\fB\-timezone\fR \fI:UTC\fR"
+or any of the equivalent ways to specify it.
+.TP
+\fB\-locale\fR localeName
+Specifies that locale-dependent scanning and formatting (and date arithmetic
+for dates preceding the adoption of the Gregorian calendar) is to be done in
+the locale identified by \fIlocaleName\fR.  The locale name may be any of
+the locales acceptable to the \fBmsgcat\fR package, or it may be the special
+name \fIsystem\fR, which represents the current locale of the process, or
+the null string, which represents Tcl's default locale.
+.RS
+.PP
+The effect of locale on scanning and formatting is discussed in the
+descriptions of the individual format groups under \fBFORMAT GROUPS\fR.
+The effect of locale on clock arithmetic is discussed under
+\fBCLOCK ARITHMETIC\fR.
+.RE
+.TP
+\fB\-timezone\fR zoneName
+Specifies that clock arithmetic, formatting, and scanning are to be done
+according to the rules for the time zone specified by \fIzoneName\fR.
+The permissible values, and their interpretation, are discussed under
+\fBTIME ZONES\fR.
+On subcommands that expect a \fB\-timezone\fR argument, the default
+is to use the \fIcurrent time zone\fR.  The current time zone is
+determined, in order of preference, by:
+.RS
+.IP [1]
+the environment variable \fBTCL_TZ\fR.
+.IP [2]
+the environment variable \fBTZ\fR.
+.IP [3]
+on Windows systems, the time zone settings from the Control Panel.
+.RE
+.PP
+If none of these is present, the C \fBlocaltime\fR and \fBmktime\fR
+functions are used to attempt to convert times between local and
+Greenwich.  On 32-bit systems, this approach is likely to have bugs,
+particularly for times that lie outside the window (approximately the
+years 1902 to 2037) that can be represented in a 32-bit integer.
+.SH "CLOCK ARITHMETIC"
+.PP
+The \fBclock add\fR command performs clock arithmetic on a value
+(expressed as nominal seconds from the epoch time of 1 January 1970, 00:00 UTC)
+given as its first argument.  The remaining arguments (other than the
+possible \fB\-timezone\fR, \fB\-locale\fR and \fB\-gmt\fR options)
+are integers and keywords in alternation, where the keywords are chosen
+from \fBseconds\fR, \fBminutes\fR, \fBhours\fR,
+\fBdays\fR, \fBweeks\fR, \fBmonths\fR, or \fByears\fR, or
+any unique prefix of such a word.
+.PP
+Addition of seconds, minutes and hours is fairly straightforward;
+the given time increment (times sixty for minutes, or 3600 for hours)
+is simply added to the \fItimeVal\fR given
+to the \fBclock add\fR command.  The result is interpreted as
+a nominal number of seconds from the Epoch.
+.PP
+Surprising results
+may be obtained when crossing a point at which a leap second is
+inserted or removed; the \fBclock add\fR command simply ignores
+leap seconds and therefore assumes that times come in sequence,
+23:59:58, 23:59:59, 00:00:00.  (This assumption is handled by
+the fact that Tcl's model of time reacts to leap seconds by speeding
+or slowing the clock by a minuscule amount until Tcl's time
+is back in step with the world.
+.PP
+The fact that adding and subtracting hours is defined in terms of
+absolute time means that it will add fixed amounts of time in time zones
+that observe summer time (Daylight Saving Time).  For example,
+the following code sets the value of \fBx\fR to \fB04:00:00\fR because
+the clock has changed in the interval in question.
+.PP
+.CS
+set s [\fBclock scan\fR {2004-10-30 05:00:00} \e
+           -format {%Y-%m-%d %H:%M:%S} \e
+           -timezone :America/New_York]
+set a [\fBclock add\fR $s 24 hours -timezone :America/New_York]
+set x [\fBclock format\fR $a \e
+           -format {%H:%M:%S} -timezone :America/New_York]
+.CE
+.PP
+Adding and subtracting days and weeks is accomplished by converting
+the given time to a calendar day and time of day in the appropriate
+time zone and locale.  The requisite number of days (weeks are converted
+to days by multiplying by seven) is added to the calendar day, and
+the date and time are then converted back to a count of seconds from
+the epoch time.
+.PP
+Adding and subtracting a given number of days across the point that
+the time changes at the start or end of summer time (Daylight Saving Time)
+results in the \fIsame local time\fR on the day in question.  For
+instance, the following code sets the value of \fBx\fR to \fB05:00:00\fR.
+.PP
+.CS
+set s [\fBclock scan\fR {2004-10-30 05:00:00} \e
+           -format {%Y-%m-%d %H:%M:%S} \e
+           -timezone :America/New_York]
+set a [\fBclock add\fR $s 1 day -timezone :America/New_York]
+set x [\fBclock format\fR $a \e
+           -format {%H:%M:%S} -timezone :America/New_York]
+.CE
+.PP
+In cases of ambiguity, where the same local time happens twice
+on the same day, the earlier time is used.  In cases where the conversion
+yields an impossible time (for instance, 02:30 during the Spring
+Daylight Saving Time change using US rules), the time is converted
+as if the clock had not changed.  Thus, the following code
+will set the value of \fBx\fR to \fB03:30:00\fR.
+.PP
+.CS
+set s [\fBclock scan\fR {2004-04-03 02:30:00} \e
+           -format {%Y-%m-%d %H:%M:%S} \e
+           -timezone :America/New_York]
+set a [\fBclock add\fR $s 1 day -timezone :America/New_York]
+set x [\fBclock format\fR $a \e
+           -format {%H:%M:%S} -timezone :America/New_York]
+.CE
+.PP
+Adding a given number of days or weeks works correctly across the conversion
+between the Julian and Gregorian calendars; the omitted days are skipped.
+The following code sets \fBz\fR to \fB1752-09-14\fR.
+.PP
+.CS
+set x [\fBclock scan\fR 1752-09-02 -format %Y-%m-%d -locale en_US]
+set y [\fBclock add\fR $x 1 day -locale en_US]
+set z [\fBclock format\fR $y -format %Y-%m-%d -locale en_US]
+.CE
+.PP
+In the bizarre case that adding the given number of days yields a date
+that does not exist because it falls within the dropped days of the
+Julian-to-Gregorian conversion, the date is converted as if it was
+on the Julian calendar.
+.PP
+Adding a number of months, or a number of years, is similar; it
+converts the given time to a calendar date and time of day.  It then
+adds the requisite number of months or years, and reconverts the resulting
+date and time of day to an absolute time.
+.PP
+If the resulting date is impossible because the month has too few days
+(for example, when adding 1 month to 31 January), the last day of the
+month is substituted.  Thus, adding 1 month to 31 January will result in
+28 February in a common year or 29 February in a leap year.
+.PP
+The rules for handling anomalies relating to summer time and to the
+Gregorian calendar are the same when adding/subtracting months and
+years as they are when adding/subtracting days and weeks.
+.PP
+If multiple \fIcount unit\fR pairs are present on the command, they
+are evaluated consecutively, from left to right.
+.SH "HIGH RESOLUTION TIMERS"
+.PP
+Most of the subcommands supported by the \fBclock\fR command deal with
+times represented as a count of seconds from the epoch time, and this is the
+representation that \fBclock seconds\fR returns.  There are three exceptions,
+which are all intended for use where higher-resolution times are required.
+\fBclock milliseconds\fR returns the count of milliseconds from the
+epoch time, and \fBclock microseconds\fR returns the count of microseconds
+from the epoch time. In addition, there is a \fBclock clicks\fR command
+that returns a platform-dependent high-resolution timer.  Unlike
+\fBclock seconds\fR and \fBclock milliseconds\fR, the value
+of \fBclock clicks\fR is not guaranteed to be tied to any fixed
+epoch; it is simply intended to be the most precise interval timer
+available, and is intended only for relative timing studies such as
+benchmarks.
+.SH "FORMATTING TIMES"
+.PP
+The \fBclock format\fR command produces times for display to a user
+or writing to an external medium.  The command accepts times that are
+expressed in seconds from the epoch time of 1 January 1970, 00:00 UTC,
+as returned by \fBclock seconds\fR, \fBclock scan\fR, \fBclock add\fR,
+\fBfile atime\fR or \fBfile mtime\fR.
+.PP
+If a \fB\-format\fR option is present, the following argument is
+a string that specifies how the date and time are to be formatted.
+The string consists
+of any number of characters other than the per-cent sign
+.PQ \fB%\fR
+interspersed with any number of \fIformat groups\fR, which are two-character
+sequences beginning with the per-cent sign.  The permissible format groups,
+and their interpretation, are described under \fBFORMAT GROUPS\fR.
+.PP
+If a \fB\-timezone\fR option is present, the following
+argument is a string that specifies the time zone in which the date and time
+are to be formatted.  As an alternative to
+.QW "\fB\-timezone\fR \fI:UTC\fR" ,
+the obsolete usage
+.QW "\fB\-gmt\fR \fItrue\fR"
+may be used.  See
+\fBTIME ZONES\fR for the permissible variants for the time zone.
+.PP
+If a \fB\-locale\fR option is present, the following argument is
+a string that specifies the locale in which the time is to be formatted,
+in the same format that is used for the \fBmsgcat\fR package.  Note
+that the default, if \fB\-locale\fR is not specified, is the root locale
+\fB{}\fR rather than the current locale.  The current locale may
+be obtained by using \fB\-locale\fR \fBcurrent\fR.
+In addition, some platforms support a \fBsystem\fR locale that
+reflects the user's current choices.  For instance, on Windows, the
+format that the user has selected from dates and times in the Control
+Panel can be obtained by using the \fBsystem\fR locale.  On
+platforms that do not define a user selection of date and time formats
+separate from \fBLC_TIME\fR, \fB\-locale\fR \fBsystem\fR is
+synonymous with \fB\-locale\fR \fBcurrent\fR.
+.SH "SCANNING TIMES"
+.PP
+The \fBclock scan\fR command accepts times that are formatted as
+strings and converts them to counts of seconds from the epoch time
+of 1 January 1970, 00:00 UTC.  It normally takes a \fB\-format\fR
+option that is followed by a string describing
+the expected format of the input.  (See
+\fBFREE FORM SCAN\fR for the effect of \fBclock scan\fR
+without such an argument.)  The string consists of any number of
+characters other than the per-cent sign
+.PQ \fB%\fR "" ,
+interspersed with any number of \fIformat groups\fR, which are two-character
+sequences beginning with the per-cent sign.  The permissible format groups,
+and their interpretation, are described under \fBFORMAT GROUPS\fR.
+.PP
+If a \fB\-timezone\fR option is present, the following
+argument is a string that specifies the time zone in which the date and time
+are to be interpreted.  As an alternative to \fB\-timezone\fR \fI:UTC\fR,
+the obsolete usage \fB\-gmt\fR \fItrue\fR may be used.  See
+\fBTIME ZONES\fR for the permissible variants for the time zone.
+.PP
+If a \fB\-locale\fR option is present, the following argument is
+a string that specifies the locale in which the time is to be interpreted,
+in the same format that is used for the \fBmsgcat\fR package.  Note
+that the default, if \fB\-locale\fR is not specified, is the root locale
+\fB{}\fR rather than the current locale.  The current locale may
+be obtained by using \fB\-locale\fR \fBcurrent\fR.
+In addition, some platforms support a \fBsystem\fR locale that
+reflects the user's current choices.  For instance, on Windows, the
+format that the user has selected from dates and times in the Control
+Panel can be obtained by using the \fBsystem\fR locale.  On
+platforms that do not define a user selection of date and time formats
+separate from \fBLC_TIME\fR, \fB\-locale\fR \fBsystem\fR is
+synonymous with \fB\-locale\fR \fBcurrent\fR.
+.PP
+If a \fB\-base\fR option is present, the following argument is
+a time (expressed in seconds from the epoch time) that is used as
+a \fIbase time\fR for interpreting relative times.  If no
+\fB\-base\fR option is present, the base time is the current time.
+.PP
+Scanning of times in fixed format works by determining three things:
+the date, the time of day, and the time zone.  These three are then
+combined into a point in time, which is returned as the number of seconds
+from the epoch.
+.PP
+Before scanning begins, the format string is preprocessed
+to replace \fB%c\fR, \fB%Ec\fR, \fB%x\fR, \fB%Ex\fR,
+\fB%X\fR. \fB%Ex\fR, \fB%r\fR, \fB%R\fR, \fB%T\fR,
+\fB%D\fR, \fB%EY\fR and \fB%+\fR format groups with counterparts
+that are appropriate to the current locale and contain none of the
+above groups.  For instance, \fB%D\fR will (in the \fBen_US\fR locale)
+be replaced with \fB%m/%d/%Y\fR.
+.PP
+The date is determined according to the fields that are present in the
+preprocessed format string.  In order of preference:
+.IP [1]
+If the string contains a \fB%s\fR format group, representing
+seconds from the epoch, that group is used to determine the date.
+.IP [2]
+If the string contains a \fB%J\fR format group, representing
+the Julian Day Number, that group is used to determine the date.
+.IP [3]
+If the string contains a complete set of format groups specifying
+century, year, month, and day of month; century, year, and day of year;
+or ISO8601 fiscal year, week of year, and day of week; those groups are
+combined and used to determine the date.  If more than one complete
+set is present, the one at the rightmost position in the string is
+used.
+.IP [4]
+If the string lacks a century but contains a set of format
+groups specifying year of century, month and day of month; year of
+century and day of year; or two-digit ISO8601 fiscal year, week of year,
+and day of week; those groups are
+combined and used to determine the date.  If more than one complete
+set is present, the one at the rightmost position in the string is
+used.  The year is presumed to lie in the range 1938 to 2037 inclusive.
+.IP [5]
+If the string entirely lacks any specification for the year
+(or contains the year only on the locale's alternative calendar)
+and contains a set of format groups specifying month and day of month,
+day of year, or week of year and day of week, those groups are
+combined and used to determine the date.  If more than one complete
+set is present, the one at the rightmost position in the string is
+used.  The year is determined by interpreting the base time in the given
+time zone.
+.IP [6]
+If the string contains none of the above sets, but has a day
+of the month or day of the week, the day of the month or day of the week
+are used to determine the date by interpreting the base time in the
+given time zone and returning the given day of the current week or month.
+(The week runs from Monday to Sunday, ISO8601-fashion.)  If both day
+of month and day of week are present, the day of the month takes
+priority.
+.IP [7]
+If none of the above rules results in a usable date, the date
+of the base time in the given time zone is used.
+.PP
+The time is also determined according to the fields that are present in the
+preprocessed format string.  In order of preference:
+.IP [1]
+If the string contains a \fB%s\fR format group, representing
+seconds from the epoch, that group determines the time of day.
+.IP [2]
+If the string contains either an hour on the 24-hour clock
+or an hour on the 12-hour clock plus an AM/PM indicator, that hour determines
+the hour of the day.  If the string further contains a group specifying
+the minute of the hour, that group combines with the hour.  If the string
+further contains a group specifying the second of the minute, that group
+combines with the hour and minute.
+.IP [3]
+If the string contains neither a \fB%s\fR format group nor
+a group specifying the hour of the day, then midnight (\fB00:00\fR, the start
+of the given date) is used.
+The time zone is determined by either the \fB\-timezone\fR or \fB\-gmt\fR
+options, or by using the current time zone.
+.PP
+If a format string lacks a \fB%z\fR or \fB%Z\fR format group,
+it is possible for the time to be ambiguous because it appears twice
+in the same day, once without and once with Daylight Saving Time.
+If this situation occurs, the first occurrence of the time is chosen.
+(For this reason, it is wise to have the input string contain the
+time zone when converting local times.  This caveat does not apply to
+UTC times.)
+.SH "FORMAT GROUPS"
+.PP
+The following format groups are recognized by the \fBclock scan\fR and
+\fBclock format\fR commands.
+.TP
+\fB%a\fR
+On output, receives an abbreviation (\fIe.g.,\fR \fBMon\fR) for the day
+of the week in the given locale.  On input, matches the name of the day
+of the week in the given locale (in either abbreviated or full form, or
+any unique prefix of either form).
+.TP
+\fB%A\fR
+On output, receives the full name (\fIe.g.,\fR \fBMonday\fR) of the day
+of the week in the given locale.  On input, matches the name of the day
+of the week in the given locale (in either abbreviated or full form, or
+any unique prefix of either form).
+.TP
+\fB%b\fR
+On output, receives an abbreviation (\fIe.g.,\fR \fBJan\fR) for the name
+of the month in the given locale.  On input, matches the name of the month
+in the given locale (in either abbreviated or full form, or
+any unique prefix of either form).
+.TP
+\fB%B\fR
+On output, receives the full name (\fIe.g.,\fR \fBJanuary\fR)
+of the month in the given locale.  On input, matches the name of the month
+in the given locale (in either abbreviated or full form, or
+any unique prefix of either form).
+.TP
+\fB%c\fR
+On output, receives a localized representation of date and time of day;
+the localized representation is expected to use the Gregorian calendar.
+On input, matches whatever \fB%c\fR produces.
+.TP
+\fB%C\fR
+On output, receives the number of the century in Indo-Arabic numerals.
+On input, matches one or two digits, possibly with leading whitespace,
+that are expected to be the number of the century.
+.TP
+\fB%d\fR
+On output, produces the number of the day of the month, as two decimal
+digits.  On input, matches one or two digits, possibly with leading
+whitespace, that are expected to be the number of the day of the month.
+.TP
+\fB%D\fR
+This format group is synonymous with \fB%m/%d/%Y\fR.  It should be
+used only in exchanging data within the \fBen_US\fR locale, since
+other locales typically do not use this order for the fields of the date.
+.TP
+\fB%e\fR
+On output, produces the number of the day of the month, as one or
+two decimal digits (with a leading blank for one-digit dates).
+On input, matches one or two digits, possibly with leading
+whitespace, that are expected to be the number of the day of the month.
+.TP
+\fB%Ec\fR
+On output, produces a locale-dependent representation of the date and
+time of day in the locale's alternative calendar.  On input, matches
+whatever \fB%Ec\fR produces.  The locale's alternative calendar need not
+be the Gregorian calendar.
+.TP
+\fB%EC\fR
+On output, produces a locale-dependent name of an era in the locale's
+alternative calendar.  On input, matches the name of the era or any
+unique prefix.
+.TP
+\fB%EE\fR
+On output, produces the string \fBB.C.E.\fR or \fBC.E.\fR, or a
+string of the same meaning in the locale, to indicate whether \fB%Y\fR refers
+to years before or after Year 1 of the Common Era.  On input, accepts
+the string \fBB.C.E.\fR, \fBB.C.\fR, \fBC.E.\fR, \fBA.D.\fR, or the
+abbreviation appropriate to the current locale, and uses it to fix
+whether \fB%Y\fR refers to years before or after Year 1 of the
+Common Era.
+.TP
+\fB%Ex\fR
+On output, produces a locale-dependent representation of the date
+in the locale's alternative calendar.  On input, matches
+whatever \fB%Ex\fR produces.  The locale's alternative calendar need not
+be the Gregorian calendar.
+.TP
+\fB%EX\fR
+On output, produces a locale-dependent representation of the
+time of day in the locale's alternative numerals.  On input, matches
+whatever \fB%EX\fR produces.
+.TP
+\fB%Ey\fR
+On output, produces a locale-dependent number of the year of the era
+in the locale's alternative calendar and numerals.  On input, matches
+such a number.
+.TP
+\fB%EY\fR
+On output, produces a representation of the year in the locale's
+alternative calendar and numerals.  On input, matches what \fB%EY\fR
+produces.  Often synonymous with \fB%EC%Ey\fR.
+.TP
+\fB%g\fR
+On output, produces a two-digit year number suitable for use with
+the week-based ISO8601 calendar; that is, the year number corresponds
+to the week number produced by \fB%V\fR.  On input, accepts such
+a two-digit year number, possibly with leading whitespace.
+.TP
+\fB%G\fR
+On output, produces a four-digit year number suitable for use with
+the week-based ISO8601 calendar; that is, the year number corresponds
+to the week number produced by \fB%V\fR.  On input, accepts such
+a four-digit year number, possibly with leading whitespace.
+.TP
+\fB%h\fR
+This format group is synonymous with \fB%b\fR.
+.TP
+\fB%H\fR
+On output, produces a two-digit number giving the hour of the day
+(00-23) on a 24-hour clock.  On input, accepts such a number.
+.TP
+\fB%I\fR
+On output, produces a two-digit number giving the hour of the day
+(12-11) on a 12-hour clock.  On input, accepts such a number.
+.TP
+\fB%j\fR
+On output, produces a three-digit number giving the day of the year
+(001-366).  On input, accepts such a number.
+.TP
+\fB%J\fR
+On output, produces a string of digits giving the Julian Day Number.
+On input, accepts a string of digits and interprets it as a Julian Day Number.
+The Julian Day Number is a count of the number of calendar days
+that have elapsed since 1 January, 4713 BCE of the proleptic
+Julian calendar.  The epoch time of 1 January 1970 corresponds
+to Julian Day Number 2440588.
+.TP
+\fB%k\fR
+On output, produces a one- or two-digit number giving the hour of the day
+(0-23) on a 24-hour clock.  On input, accepts such a number.
+.TP
+\fB%l\fR
+On output, produces a one- or two-digit number giving the hour of the day
+(12-11) on a 12-hour clock.  On input, accepts such a number.
+.TP
+\fB%m\fR
+On output, produces the number of the month (01-12) with exactly two
+digits.  On input, accepts two digits and interprets them as the number
+of the month.
+.TP
+\fB%M\fR
+On output, produces the number of the minute of the hour (00-59)
+with exactly two digits.  On input, accepts two digits and interprets them
+as the number of the minute of the hour.
+.TP
+\fB%N\fR
+On output, produces the number of the month (1-12) with one or two digits,
+and a leading blank for one-digit dates.
+On input, accepts one or two digits, possibly with leading whitespace,
+and interprets them as the number of the month.
+.TP
+\fB%Od\fR, \fB%Oe\fR, \fB%OH\fR, \fB%OI\fR, \fB%Ok\fR, \fB%Ol\fR, \fB%Om\fR, \fB%OM\fR, \fB%OS\fR, \fB%Ou\fR, \fB%Ow\fR, \fB%Oy\fR
+All of these format groups are synonymous with their counterparts
+without the
+.QW \fBO\fR ,
+except that the string is produced and parsed in the
+locale-dependent alternative numerals.
+.TP
+\fB%p\fR
+On output, produces an indicator for the part of the day, \fBAM\fR
+or \fBPM\fR, appropriate to the given locale.  If the script of the
+given locale supports multiple letterforms, lowercase is preferred.
+On input, matches the representation \fBAM\fR or \fBPM\fR in
+the given locale, in either case.
+.TP
+\fB%P\fR
+On output, produces an indicator for the part of the day, \fBam\fR
+or \fBpm\fR, appropriate to the given locale.  If the script of the
+given locale supports multiple letterforms, uppercase is preferred.
+On input, matches the representation \fBAM\fR or \fBPM\fR in
+the given locale, in either case.
+.TP
+\fB%Q\fR
+This format group is reserved for internal use within the Tcl library.
+.TP
+\fB%r\fR
+On output, produces a locale-dependent time of day representation on a
+12-hour clock. On input, accepts whatever \fB%r\fR produces.
+.TP
+\fB%R\fR
+On output, the time in 24-hour notation (%H:%M). For a version
+including the seconds, see \fB%T\fR below. On input, accepts whatever
+\fB%R\fR produces.
+.TP
+\fB%s\fR
+On output, simply formats the \fItimeVal\fR argument as a decimal
+integer and inserts it into the output string.  On input, accepts
+a decimal integer and uses is as the time value without any further
+processing. Since \fB%s\fR uniquely determines a point in time, it
+overrides all other input formats.
+.TP
+\fB%S\fR
+On output, produces a two-digit number of the second of the minute
+(00-59). On input, accepts two digits and uses them as the second of the
+minute.
+.TP
+\fB%t\fR
+On output, produces a TAB character. On input, matches a TAB character.
+.TP
+\fB%T\fR
+Synonymous with \fB%H:%M:%S\fR.
+.TP
+\fB%u\fR
+On output, produces the number of the day of the week
+(\fB1\fR\(->Monday, \fB7\fR\(->Sunday). On input, accepts a single digit and
+interprets it as the day of the week. Sunday may be either \fB0\fR or
+\fB7\fR.
+.TP
+\fB%U\fR
+On output, produces the ordinal number of the week of the year
+(00-53). The first Sunday of the year is the first day of week 01. On
+input accepts two digits which are otherwise ignored. This format
+group is never used in determining an input date.  This interpretation
+of the week of the year was once common in US banking but is now
+largely obsolete.  See \fB%V\fR for the ISO8601 week number.
+.TP
+\fB%V\fR
+On output, produces the number of the ISO8601 week as a two digit
+number (01-53). Week 01 is the week containing January 4; or the first
+week of the year containing at least 4 days; or the week containing
+the first Thursday of the year (the three statements are
+equivalent). Each week begins on a Monday. On input, accepts the
+ISO8601 week number.
+.TP
+\fB%w\fR
+On output, produces the ordinal number of the day of the week
+(Sunday==0; Saturday==6).  On input, accepts a single digit and
+interprets it as the day of the week; Sunday may be represented as
+either 0 or 7.  Note that \fB%w\fR is not the ISO8601 weekday number,
+which is produced and accepted by \fB%u\fR.
+.TP
+\fB%W\fR
+On output, produces a week number (00-53) within the year; week 01
+begins on the first Monday of the year. On input, accepts two digits,
+which are otherwise ignored. This format group is never used in
+determining an input date.  It is not the ISO8601 week number; that
+week is produced and accepted by \fB%V\fR.
+.TP
+\fB%x\fR
+On output, produces the date in a locale-dependent representation. On
+input, accepts whatever \fB%x\fR produces and is used to determine
+calendar date.
+.TP
+\fB%X\fR
+On output, produces the time of day in a locale-dependent
+representation. On input, accepts whatever \fB%X\fR produces and is used
+to determine time of day.
+.TP
+\fB%y\fR
+On output, produces the two-digit year of the century. On input,
+accepts two digits, and is used to determine calendar date. The
+date is presumed to lie between 1938 and 2037 inclusive. Note
+that \fB%y\fR does not yield a year appropriate for use with the ISO8601
+week number \fB%V\fR; programs should use \fB%g\fR for that purpose.
+.TP
+\fB%Y\fR
+On output, produces the four-digit calendar year. On input,
+accepts four digits and may be used to determine calendar date. Note
+that \fB%Y\fR does not yield a year appropriate for use with the ISO8601
+week number \fB%V\fR; programs should use \fB%G\fR for that purpose.
+.TP
+\fB%z\fR
+On output, produces the current time zone, expressed in hours and
+minutes east (+hhmm) or west (\-hhmm) of Greenwich. On input, accepts a
+time zone specifier (see \fBTIME ZONES\fR below) that will be used to
+determine the time zone.
+.TP
+\fB%Z\fR
+On output, produces the current time zone's name, possibly
+translated to the given locale. On input, accepts a time zone
+specifier (see \fBTIME ZONES\fR below) that will be used to determine the
+time zone. This option should, in general, be used on input only when
+parsing RFC822 dates. Other uses are fraught with ambiguity; for
+instance, the string \fBBST\fR may represent British Summer Time or
+Brazilian Standard Time. It is recommended that date/time strings for
+use by computers use numeric time zones instead.
+.TP
+\fB%%\fR
+On output, produces a literal
+.QW \fB%\fR
+character. On input, matches a literal
+.QW \fB%\fR
+character.
+.TP
+\fB%+\fR
+Synonymous with
+.QW "\fB%a %b %e %H:%M:%S %Z %Y\fR" .
+.SH "TIME ZONES"
+.PP
+When the \fBclock\fR command is processing a local time, it has several
+possible sources for the time zone to use.  In order of preference, they
+are:
+.IP [1]
+A time zone specified inside a string being parsed and matched by a \fB%z\fR
+or \fB%Z\fR format group.
+.IP [2]
+A time zone specified with the \fB\-timezone\fR option to the \fBclock\fR
+command (or, equivalently, by \fB\-gmt\fR \fB1\fR).
+.IP [3]
+A time zone specified in an environment variable \fBTCL_TZ\fR.
+.IP [4]
+A time zone specified in an environment variable \fBTZ\fR.
+.IP [5]
+The local time zone from the Control Panel on Windows systems.
+.IP [6]
+The C library's idea of the local time zone, as defined by the
+\fBmktime\fR and \fBlocaltime\fR functions.
+.PP
+In case [1] \fIonly,\fR the string is tested to see if it is one
+of the strings:
+.PP
+.CS
+ gmt     ut      utc     bst     wet     wat     at
+ nft     nst     ndt     ast     adt     est     edt
+ cst     cdt     mst     mdt     pst     pdt     yst
+ ydt     hst     hdt     cat     ahst    nt      idlw
+ cet     cest    met     mewt    mest    swt     sst
+ eet     eest    bt      it      zp4     zp5     ist
+ zp6     wast    wadt    jt      cct     jst     cast
+ cadt    east    eadt    gst     nzt     nzst    nzdt
+ idle
+.CE
+.PP
+If it is a string in the above list, it designates a known
+time zone, and is interpreted as such.
+.PP
+For time zones in case [1] that do not match any of the above strings,
+and always for cases [2]-[6], the following rules apply.
+.PP
+If the time zone begins with a colon, it is one of a
+standardized list of names like \fB:America/New_York\fR
+that give the rules for various locales.  A complete list
+of the location names is too lengthy to be listed here.
+On most Tcl installations, the definitions of the locations
+are to be found in named files in the directory
+.QW "\fI/no_backup/tools/lib/tcl8.5/clock/tzdata\fR" .
+On some Unix systems, these files are omitted, and the definitions are
+instead obtained from system files in
+.QW "\fI/usr/share/zoneinfo\fR" ,
+.QW "\fI/usr/share/lib/zoneinfo\fR"
+or
+.QW "\fI/usr/local/etc/zoneinfo\fR" .
+As a special case, the name \fB:localtime\fR refers to
+the local time zone as defined by the C library.
+.PP
+A time zone string consisting of a plus or minus sign followed by
+four or six decimal digits is interpreted as an offset in
+hours, minutes, and seconds (if six digits are present) from
+UTC.  The plus sign denotes a sign east of Greenwich;
+the minus sign one west of Greenwich.
+.PP
+A time zone string conforming to the Posix specification of the \fBTZ\fR
+environment variable will be recognized.  The specification
+may be found at
+\fIhttp://www.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap08.html\fR.
+.PP
+If the Posix time zone string contains a DST (Daylight Savings Time)
+part, but doesn't contain a rule stating when DST starts or ends,
+then default rules are used. For Timezones with an offset between 0
+and +12, the current European/Russian rules are used, otherwise the
+current US rules are used. In Europe (offset +0 to +2) the switch
+to summertime is done each last Sunday in March at 1:00 GMT, and
+the switch back is each last Sunday in October at 2:00 GMT. In
+Russia (offset +3 to +12), the switch dates are the same, only
+the switch to summertime is at 2:00 local time, and the switch
+back is at 3:00 local time in all time zones. The US switch to
+summertime takes place each second Sunday in March at 2:00 local
+time, and the switch back is each first Sunday in November at
+3:00 local time. These default rules mean that in all European,
+Russian and US (or compatible) time zones, DST calculations will
+be correct for dates in 2007 and later, unless in the future the
+rules change again.
+.PP
+Any other time zone string is processed by prefixing a colon and attempting
+to use it as a location name, as above.
+.SH "LOCALIZATION"
+.PP
+Developers wishing to localize the date and time formatting and parsing
+are referred to \fIhttp://tip.tcl.tk/173\fR for a
+specification.
+.SH "FREE FORM SCAN"
+.PP
+If the \fBclock scan\fR command is invoked without a \fB\-format\fR
+option, then it requests a \fIfree-form scan.\fR  \fI
+This form of scan is deprecated.\fR  The reason for the deprecation
+is that there are too many ambiguities. (Does the string
+.QW 2000
+represent a year, a time of day, or a quantity?)  No set of rules
+for interpreting free-form dates and times has been found to
+give unsurprising results in all cases.
+.PP
+If free-form scan is used, only the \fB\-base\fR and \fB\-gmt\fR
+options are accepted.  The \fB\-timezone\fR and \fB\-locale\fR
+options will result in an error if \fB\-format\fR is not supplied.
+.PP
+For the benefit of users who need to understand legacy code that
+uses free-form scan, the documentation for how free-form scan
+interprets a string is included here:
+.PP
+If only a time is
+specified, the current date is assumed.  If the \fIinputString\fR
+does not contain a
+time zone mnemonic, the local time zone is assumed, unless the \fB\-gmt\fR
+argument is true, in which case the clock value is calculated assuming
+that the specified time is relative to Greenwich Mean Time.
+\fB\-gmt\fR, if specified, affects only the computed time value; it does not
+impact the interpretation of \fB\-base\fR.
+.PP
+If the \fB\-base\fR flag is specified, the next argument should contain
+an integer clock value.  Only the date in this value is used, not the
+time.  This is useful for determining the time on a specific day or
+doing other date-relative conversions.
+.PP
+The \fIinputString\fR argument consists of zero or more specifications of the
+following form:
+.TP
+\fItime\fR
+A time of day, which is of the form: \fBhh?:mm?:ss?? ?meridian? ?zone?\fR
+or \fBhhmm ?meridian? ?zone?\fR
+If no meridian is specified, \fBhh\fR is interpreted on
+a 24-hour clock.
+.TP
+\fIdate\fR
+A specific month and day with optional year.  The
+acceptable formats are
+.QW "\fBmm/dd\fR?\fB/yy\fR?" ,
+.QW "\fBmonthname dd\fR?\fB, yy\fR?" ,
+.QW "\fBday, dd monthname \fR?\fByy\fR?" ,
+.QW "\fBdd monthname yy\fR" ,
+.QW "?\fBCC\fR?\fByymmdd\fR" ,
+and
+.QW "\fBdd-monthname-\fR?\fBCC\fR?\fByy\fR" .
+The default year is the current year.  If the year is less
+than 100, we treat the years 00-68 as 2000-2068 and the years 69-99
+as 1969-1999.  Not all platforms can represent the years 38-70, so
+an error may result if these years are used.
+.TP
+\fIISO 8601 point-in-time\fR
+An ISO 8601 point-in-time specification, such as
+.QW \fICCyymmdd\fBT\fIhhmmss\fR,
+where \fBT\fR is the literal
+.QW T ,
+.QW "\fICCyymmdd hhmmss\fR" ,
+or
+.QW \fICCyymmdd\fBT\fIhh:mm:ss\fR .
+Note that only these three formats are accepted.
+The command does \fInot\fR accept the full range of point-in-time
+specifications specified in ISO8601.  Other formats can be recognized by
+giving an explicit \fB\-format\fR option to the \fBclock scan\fR command.
+.TP
+\fIrelative time\fR
+A specification relative to the current time.  The format is \fBnumber
+unit\fR. Acceptable units are \fByear\fR, \fBfortnight\fR,
+\fBmonth\fR, \fBweek\fR, \fBday\fR,
+\fBhour\fR, \fBminute\fR (or \fBmin\fR), and \fBsecond\fR (or \fBsec\fR).  The
+unit can be specified as a singular or plural, as in \fB3 weeks\fR.
+These modifiers may also be specified:
+\fBtomorrow\fR, \fByesterday\fR, \fBtoday\fR, \fBnow\fR,
+\fBlast\fR, \fBthis\fR, \fBnext\fR, \fBago\fR.
+.PP
+The actual date is calculated according to the following steps.
+.PP
+First, any absolute date and/or time is processed and converted.
+Using that time as the base, day-of-week specifications are added.
+Next, relative specifications are used.  If a date or day is
+specified, and no absolute or relative time is given, midnight is
+used.  Finally, a correction is applied so that the correct hour of
+the day is produced after allowing for daylight savings time
+differences and the correct date is given when going from the end
+of a long month to a short month.
+.SH "SEE ALSO"
+msgcat(n)
+.SH KEYWORDS
+clock, date, time
+.SH "COPYRIGHT"
+Copyright (c) 2004 Kevin B. Kenny <kennykb@acm.org>. All rights reserved.
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/doc/close.n b/doc/close.n
new file mode 100644
index 0000000..63da75b
--- /dev/null
+++ b/doc/close.n
@@ -0,0 +1,108 @@
+'\"
+'\" Copyright (c) 1993 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\" 
+.TH close n 7.5 Tcl "Tcl Built-In Commands"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+close \- Close an open channel
+.SH SYNOPSIS
+\fBclose \fIchannelId\fR ?r(ead)|w(rite)?
+.BE
+.SH DESCRIPTION
+.PP
+Closes or half-closes the channel given by \fIchannelId\fR.
+.PP
+\fIChannelId\fR must be an identifier for an open channel such as a
+Tcl standard channel (\fBstdin\fR, \fBstdout\fR, or \fBstderr\fR),
+the return value from an invocation of \fBopen\fR or \fBsocket\fR, or
+the result of a channel creation command provided by a Tcl extension.
+.PP
+The single-argument form is a simple
+.QW "full-close" :
+all buffered output is flushed to the channel's output device,
+any buffered input is discarded, the underlying file or device is closed,
+and \fIchannelId\fR becomes unavailable for use.
+.PP
+If the channel is blocking, the command does not return until all output
+is flushed.
+If the channel is nonblocking and there is unflushed output, the
+channel remains open and the command
+returns immediately; output will be flushed in the background and the
+channel will be closed when all the flushing is complete.
+.PP
+If \fIchannelId\fR is a blocking channel for a command pipeline then
+\fBclose\fR waits for the child processes to complete.
+.PP
+If the channel is shared between interpreters, then \fBclose\fR
+makes \fIchannelId\fR unavailable in the invoking interpreter but has no
+other effect until all of the sharing interpreters have closed the
+channel.
+When the last interpreter in which the channel is registered invokes
+\fBclose\fR, the cleanup actions described above occur. See the
+\fBinterp\fR command for a description of channel sharing.
+.PP
+Channels are automatically closed when an interpreter is destroyed and
+when the process exits.
+.VS 8.6
+From 8.6 on (TIP#398), nonblocking channels are no longer switched to blocking mode when exiting; this guarantees a timely exit even when the peer or a communication channel is stalled. To ensure proper flushing of stalled nonblocking channels on exit, one must now either (a) actively switch them back to blocking or (b) use the environment variable TCL_FLUSH_NONBLOCKING_ON_EXIT,  which when set and not equal to "0" restores the previous behavior.
+.VE 8.6
+.PP
+The command returns an empty string, and may generate an error if
+an error occurs while flushing output.  If a command in a command
+pipeline created with \fBopen\fR returns an error, \fBclose\fR
+generates an error (similar to the \fBexec\fR command.)
+.PP
+.VS 8.6
+The two-argument form is a
+.QW "half-close" :
+given a bidirectional channel like a
+socket or command pipeline and a (possibly abbreviated) direction, it closes
+only the sub-stream going in that direction. This means a shutdown() on a
+socket, and a close() of one end of a pipe for a command pipeline. Then, the
+Tcl-level channel data structure is either kept or freed depending on whether
+the other direction is still open.
+.PP
+A single-argument close on an already half-closed bidirectional channel is
+defined to just
+.QW "finish the job" .
+A half-close on an already closed half, or on a wrong-sided unidirectional
+channel, raises an error.
+.PP
+In the case of a command pipeline, the child-reaping duty falls upon the
+shoulders of the last close or half-close, which is thus allowed to report an
+abnormal exit error.
+.PP
+Currently only sockets and command pipelines support half-close. A future
+extension will allow reflected and stacked channels to do so.
+.VE 8.6
+.SH EXAMPLE
+.PP
+This illustrates how you can use Tcl to ensure that files get closed
+even when errors happen by combining \fBcatch\fR, \fBclose\fR and
+\fBreturn\fR:
+.PP
+.CS
+proc withOpenFile {filename channelVar script} {
+    upvar 1 $channelVar chan
+    set chan [open $filename]
+    catch {
+        uplevel 1 $script
+    } result options
+    \fBclose\fR $chan
+    return -options $options $result
+}
+.CE
+.SH "SEE ALSO"
+file(n), open(n), socket(n), eof(n), Tcl_StandardChannels(3)
+.SH KEYWORDS
+blocking, channel, close, nonblocking, half-close
+'\" Local Variables:
+'\" mode: nroff
+'\" fill-column: 78
+'\" End:
diff --git a/doc/concat.n b/doc/concat.n
new file mode 100644
index 0000000..575b9df
--- /dev/null
+++ b/doc/concat.n
@@ -0,0 +1,58 @@
+'\"
+'\" Copyright (c) 1993 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\" 
+.TH concat n 8.3 Tcl "Tcl Built-In Commands"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+concat \- Join lists together
+.SH SYNOPSIS
+\fBconcat\fI \fR?\fIarg arg ...\fR?
+.BE
+.SH DESCRIPTION
+.PP
+This command joins each of its arguments together with spaces after
+trimming leading and trailing white-space from each of them.  If all of the
+arguments are lists, this has the same effect as concatenating them
+into a single list.
+It permits any number of arguments;
+if no \fIarg\fRs are supplied, the result is an empty string.
+.SH EXAMPLES
+Although \fBconcat\fR will concatenate lists, flattening them in the process
+(so giving the following interactive session):
+.PP
+.CS
+\fI%\fR \fBconcat\fR a b {c d e} {f {g h}}
+\fIa b c d e f {g h}\fR
+.CE
+.PP
+it will also concatenate things that are not lists, as can be seen from this
+session:
+.PP
+.CS
+\fI%\fR \fBconcat\fR " a b {c   " d "  e} f"
+\fIa b {c d e} f\fR
+.CE
+.PP
+Note also that the concatenation does not remove spaces from the middle of
+values, as can be seen here:
+.PP
+.CS
+\fI%\fR \fBconcat\fR "a   b   c" { d e f }
+\fIa   b   c d e f\fR
+.CE
+.PP
+(i.e., there are three spaces between each of the \fBa\fR, the \fBb\fR and the
+\fBc\fR).
+.SH "SEE ALSO"
+append(n), eval(n), join(n)
+.SH KEYWORDS
+concatenate, join, list
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/doc/continue.n b/doc/continue.n
new file mode 100644
index 0000000..17d16b4
--- /dev/null
+++ b/doc/continue.n
@@ -0,0 +1,47 @@
+'\"
+'\" Copyright (c) 1993-1994 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\" 
+.TH continue n "" Tcl "Tcl Built-In Commands"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+continue \- Skip to the next iteration of a loop
+.SH SYNOPSIS
+\fBcontinue\fR
+.BE
+.SH DESCRIPTION
+.PP
+This command is typically invoked inside the body of a looping command
+such as \fBfor\fR or \fBforeach\fR or \fBwhile\fR.
+It returns a 4 (\fBTCL_CONTINUE\fR) result code, which causes a continue
+exception to occur.
+The exception causes the current script to be aborted
+out to the innermost containing loop command, which then
+continues with the next iteration of the loop.
+Catch exceptions are also handled in a few other situations, such
+as the \fBcatch\fR command and the outermost scripts of procedure
+bodies.
+.SH EXAMPLE
+.PP
+Print a line for each of the integers from 0 to 10 \fIexcept\fR 5:
+.PP
+.CS
+for {set x 0} {$x<10} {incr x} {
+    if {$x == 5} {
+        \fBcontinue\fR
+    }
+    puts "x is $x"
+}
+.CE
+.SH "SEE ALSO"
+break(n), for(n), foreach(n), return(n), while(n)
+.SH KEYWORDS
+continue, iteration, loop
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/doc/copy.n b/doc/copy.n
new file mode 100644
index 0000000..100d564
--- /dev/null
+++ b/doc/copy.n
@@ -0,0 +1,66 @@
+'\"
+'\" Copyright (c) 2007 Donal K. Fellows
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH copy n 0.1 TclOO "TclOO Commands"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+oo::copy \- create copies of objects and classes
+.SH SYNOPSIS
+.nf
+package require TclOO
+
+\fBoo::copy\fI sourceObject \fR?\fItargetObject\fR?
+.fi
+.BE
+.SH DESCRIPTION
+.PP
+The \fBoo::copy\fR command creates a copy of an object or class. It takes the
+name of the object or class to be copied, \fIsourceObject\fR, and optionally
+the name of the object or class to create, \fItargetObject\fR, which will be
+resolved relative to the current namespace if not an absolute qualified name.
+If \fItargetObject\fR is omitted, a new name is chosen. The copied object will
+be of the same class as the source object, and will have all its per-object
+methods copied. If it is a class, it will also have all the class methods in
+the class copied, but it will not have any of its instances copied.
+.PP
+.VS
+After the \fItargetObject\fR has been created and all definitions of its
+configuration (e.g., methods, filters, mixins) copied, the \fB<cloned>\fR
+method of \fItargetObject\fR will be invoked, to allow for customization of
+the created object such as installing related variable traces. The only
+argument given will be \fIsourceObject\fR. The default implementation of this
+method (in \fBoo::object\fR) just copies the procedures and variables in the
+namespace of \fIsourceObject\fR to the namespace of \fItargetObject\fR. If
+this method call does not return a result that is successful (i.e., an error
+or other kind of exception) then the \fItargetObject\fR will be deleted and an
+error returned.
+.VE
+.PP
+The result of the \fBoo::copy\fR command will be the fully-qualified name of
+the new object or class.
+.SH EXAMPLES
+.PP
+This example creates an object, copies it, modifies the source object, and
+then demonstrates that the copied object is indeed a copy.
+.PP
+.CS
+oo::object create src
+oo::objdefine src method msg {} {puts foo}
+\fBoo::copy\fR src dst
+oo::objdefine src method msg {} {puts bar}
+src msg              \fI\(-> prints "bar"\fR
+dst msg              \fI\(-> prints "foo"\fR
+.CE
+.SH "SEE ALSO"
+oo::class(n), oo::define(n), oo::object(n)
+.SH KEYWORDS
+clone, copy, duplication, object
+.\" Local variables:
+.\" mode: nroff
+.\" fill-column: 78
+.\" End:
diff --git a/doc/coroutine.n b/doc/coroutine.n
new file mode 100644
index 0000000..c99f8d3
--- /dev/null
+++ b/doc/coroutine.n
@@ -0,0 +1,205 @@
+'\"
+'\" Copyright (c) 2009 Donal K. Fellows.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\" 
+.TH coroutine n 8.6 Tcl "Tcl Built-In Commands"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+coroutine, yield, yieldto \- Create and produce values from coroutines
+.SH SYNOPSIS
+.nf
+\fBcoroutine \fIname command\fR ?\fIarg...\fR?
+\fByield\fR ?\fIvalue\fR?
+.VS TIP396
+\fByieldto\fR \fIcommand\fR ?\fIarg...\fR?
+\fIname\fR ?\fIvalue...\fR?
+.VE TIP396
+.fi
+.BE
+.SH DESCRIPTION
+.PP
+The \fBcoroutine\fR command creates a new coroutine context (with associated
+command) named \fIname\fR and executes that context by calling \fIcommand\fR,
+passing in the other remaining arguments without further interpretation. Once
+\fIcommand\fR returns normally or with an exception (e.g., an error) the
+coroutine context \fIname\fR is deleted.
+.PP
+Within the context, values may be generated as results by using the
+\fByield\fR command; if no \fIvalue\fR is supplied, the empty string is used.
+When that is called, the context will suspend execution and the
+\fBcoroutine\fR command will return the argument to \fByield\fR. The execution
+of the context can then be resumed by calling the context command, optionally
+passing in the \fIsingle\fR value to use as the result of the \fByield\fR call
+that caused
+the context to be suspended. If the coroutine context never yields and instead
+returns conventionally, the result of the \fBcoroutine\fR command will be the
+result of the evaluation of the context.
+.PP
+.VS TIP396
+The coroutine may also suspend its execution by use of the \fByieldto\fR
+command, which instead of returning, cedes execution to some command called
+\fIcommand\fR (resolved in the context of the coroutine) and to which \fIany
+number\fR of arguments may be passed. Since every coroutine has a context
+command, \fByieldto\fR can be used to transfer control directly from one
+coroutine to another (this is only advisable if the two coroutines are
+expecting this to happen) but \fIany\fR command may be the target. If a
+coroutine is suspended by this mechanism, the coroutine processing can be
+resumed by calling the context command optionally passing in an arbitrary
+number of arguments. The return value of the \fByieldto\fR call will be the
+list of arguments passed to the context command; it is up to the caller to
+decide what to do with those values.
+.PP
+The recommended way of writing a version of \fByield\fR that allows resumption
+with multiple arguments is by using \fByieldto\fR and the \fBreturn\fR
+command, like this:
+.PP
+.CS
+proc yieldm {value} {
+    \fByieldto\fR return -level 0 $value
+}
+.CE
+.VE TIP396
+.PP
+The coroutine can also be deleted by destroying the command \fIname\fR, and
+the name of the current coroutine can be retrieved by using
+\fBinfo coroutine\fR.
+If there are deletion traces on variables in the coroutine's
+implementation, they will fire at the point when the coroutine is explicitly
+deleted (or, naturally, if the command returns conventionally).
+.PP
+At the point when \fIcommand\fR is called, the current namespace will be the
+global namespace and there will be no stack frames above it (in the sense of
+\fBupvar\fR and \fBuplevel\fR). However, which command to call will be
+determined in the namespace that the \fBcoroutine\fR command was called from.
+.SH EXAMPLES
+.PP
+This example shows a coroutine that will produce an infinite sequence of
+even values, and a loop that consumes the first ten of them.
+.PP
+.CS
+proc allNumbers {} {
+    \fByield\fR
+    set i 0
+    while 1 {
+        \fByield\fR $i
+        incr i 2
+    }
+}
+\fBcoroutine\fR nextNumber allNumbers
+for {set i 0} {$i < 10} {incr i} {
+    puts "received [\fInextNumber\fR]"
+}
+rename nextNumber {}
+.CE
+.PP
+In this example, the coroutine acts to add up the arguments passed to it.
+.PP
+.CS
+\fBcoroutine\fR accumulator apply {{} {
+    set x 0
+    while 1 {
+        incr x [\fByield\fR $x]
+    }
+}}
+for {set i 0} {$i < 10} {incr i} {
+    puts "$i -> [\fIaccumulator\fR $i]"
+}
+.CE
+.PP
+This example demonstrates the use of coroutines to implement the classic Sieve
+of Eratosthenes algorithm for finding prime numbers. Note the creation of
+coroutines inside a coroutine.
+.PP
+.CS
+proc filterByFactor {source n} {
+    \fByield\fR [info coroutine]
+    while 1 {
+        set x [\fI$source\fR]
+        if {$x % $n} {
+            \fByield\fR $x
+        }
+    }
+}
+\fBcoroutine\fR allNumbers apply {{} {while 1 {\fByield\fR [incr x]}}}
+\fBcoroutine\fR eratosthenes apply {c {
+    \fByield\fR
+    while 1 {
+        set n [\fI$c\fR]
+        \fByield\fR $n
+        set c [\fBcoroutine\fR prime$n filterByFactor $c $n]
+    }
+}} allNumbers
+for {set i 1} {$i <= 20} {incr i} {
+    puts "prime#$i = [\fIeratosthenes\fR]"
+}
+.CE
+.PP
+.VS TIP396
+This example shows how a value can be passed around a group of three
+coroutines that yield to each other:
+.PP
+.CS
+proc juggler {name target {value ""}} {
+    if {$value eq ""} {
+        set value [\fByield\fR [info coroutine]]
+    }
+    while {$value ne ""} {
+        puts "$name : $value"
+        set value [string range $value 0 end-1]
+        lassign [\fByieldto\fR $target $value] value
+    }
+}
+\fBcoroutine\fR j1 juggler Larry [
+    \fBcoroutine\fR j2 juggler Curly [
+        \fBcoroutine\fR j3 juggler Moe j1]] "Nyuck!Nyuck!Nyuck!"
+.CE
+.VE TIP396
+.SS "DETAILED SEMANTICS"
+.PP
+This example demonstrates that coroutines start from the global namespace, and
+that \fIcommand\fR resolution happens before the coroutine stack is created.
+.PP
+.CS
+proc report {where level} {
+    # Where was the caller called from?
+    set ns [uplevel 2 {namespace current}]
+    \fByield\fR "made $where $level context=$ns name=[info coroutine]"
+}
+proc example {} {
+    report outer [info level]
+}
+namespace eval demo {
+    proc example {} {
+        report inner [info level]
+    }
+    proc makeExample {} {
+        puts "making from [info level]"
+        puts [\fBcoroutine\fR coroEg example]
+    }
+    makeExample
+}
+.CE
+.PP
+Which produces the output below. In particular, we can see that stack
+manipulation has occurred (comparing the levels from the first and second
+line) and that the parent level in the coroutine is the global namespace. We
+can also see that coroutine names are local to the current namespace if not
+qualified, and that coroutines may yield at depth (e.g., in called
+procedures).
+.PP
+.CS
+making from 2
+made inner 1 context=:: name=::demo::coroEg
+.CE
+.SH "SEE ALSO"
+apply(n), info(n), proc(n), return(n)
+.SH KEYWORDS
+coroutine, generator
+'\" Local Variables:
+'\" mode: nroff
+'\" fill-column: 78
+'\" End:
diff --git a/doc/dde.n b/doc/dde.n
new file mode 100644
index 0000000..ac3d8ed
--- /dev/null
+++ b/doc/dde.n
@@ -0,0 +1,189 @@
+'\"
+'\" Copyright (c) 1997 Sun Microsystems, Inc.
+'\" Copyright (c) 2001 ActiveState Corporation.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH dde n 1.4 dde "Tcl Bundled Packages"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+dde \- Execute a Dynamic Data Exchange command
+.SH SYNOPSIS
+.sp
+\fBpackage require dde 1.4\fR
+.sp
+\fBdde servername\fR ?\fB\-force\fR? ?\fB\-handler \fIproc\fR? ?\fB\-\|\-\fR? ?\fItopic\fR?
+.sp
+.VS 8.6
+\fBdde execute\fR ?\fB\-async\fR? ?\fB\-binary\fR? \fIservice topic data\fR
+.sp
+\fBdde poke\fR ?\fB\-binary\fR? \fIservice topic item data\fR
+.VE 8.6
+.sp
+\fBdde request\fR ?\fB\-binary\fR? \fIservice topic item\fR
+.sp
+\fBdde services \fIservice topic\fR
+.sp
+\fBdde eval\fR ?\fB\-async\fR? \fItopic cmd \fR?\fIarg arg ...\fR?
+.BE
+
+.SH DESCRIPTION
+.PP
+This command allows an application to send Dynamic Data Exchange (DDE)
+command when running under Microsoft Windows. Dynamic Data Exchange is
+a mechanism where applications can exchange raw data. Each DDE
+transaction needs a \fIservice name\fR and a \fItopic\fR. Both the
+\fIservice name\fR and \fItopic\fR are application defined; Tcl uses
+the service name \fBTclEval\fR, while the topic name is the name of the
+interpreter given by \fBdde servername\fR. Other applications have their
+own \fIservice names\fR and \fItopics\fR. For instance, Microsoft Excel
+has the service name \fBExcel\fR.
+.PP
+.SH "DDE COMMANDS"
+.PP
+The following commands are a subset of the full Dynamic Data Exchange
+set of commands.
+.TP
+\fBdde servername \fR?\fB\-force\fR? ?\fB\-handler \fIproc\fR? ?\fB\-\|\-\fR? ?\fItopic\fR?
+.
+\fBdde servername\fR registers the interpreter as a DDE server with
+the service name \fBTclEval\fR and the topic name specified by \fItopic\fR.
+If no \fItopic\fR is given, \fBdde servername\fR returns the name
+of the current topic or the empty string if it is not registered as a
+service. If the given \fItopic\fR name is already in use, then a
+suffix of the form
+.QW " #2"
+or
+.QW " #3"
+is appended to the name to make it
+unique. The command's result will be the name actually used. The
+\fB\-force\fR option is used to force registration of precisely the
+given \fItopic\fR name.
+.RS
+.PP
+The \fB\-handler\fR option specifies a Tcl procedure that will be called to
+process calls to the dde server. If the package has been loaded into a
+safe interpreter then a \fB\-handler\fR procedure must be defined. The
+procedure is called with all the arguments provided by the remote
+call.
+.RE
+.TP
+\fBdde execute\fR ?\fB\-async\fR? ?\fB\-binary\fR? \fIservice topic data\fR
+.
+\fBdde execute\fR takes the \fIdata\fR and sends it to the server indicated
+by \fIservice\fR with the topic indicated by \fItopic\fR. Typically,
+\fIservice\fR is the name of an application, and \fItopic\fR is a file to
+work on.  The \fIdata\fR field is given to the remote application.
+Typically, the application treats the \fIdata\fR field as a script, and the
+script is run in the application.  The \fB\-async\fR option requests
+asynchronous invocation.  The command returns an error message if the
+script did not run, unless the \fB\-async\fR flag was used, in which case
+the command returns immediately with no error.
+.VS 8.6
+Without the \fB\-binary\fR option all data will be sent in unicode. For
+dde clients which don't implement the CF_UNICODE clipboard format, this
+will automatically be translated to the system encoding. You can use
+the \fB\-binary\fR option in combination with the result of
+\fBencoding convertto\fR to send data in any other encoding.
+.VE 8.6
+.TP
+\fBdde poke\fR ?\fB\-binary\fR? \fIservice topic item data\fR
+.
+\fBdde poke\fR passes the \fIdata\fR to the server indicated by
+\fIservice\fR using the \fItopic\fR and \fIitem\fR specified.  Typically,
+\fIservice\fR is the name of an application.  \fItopic\fR is application
+specific but can be a command to the server or the name of a file to work
+on.  The \fIitem\fR is also application specific and is often not used, but
+it must always be non-null.  The \fIdata\fR field is given to the remote
+application.
+.VS 8.6
+Without the \fB\-binary\fR option all data will be sent in unicode. For
+dde clients which don't implement the CF_UNICODE clipboard format, this
+will automatically be translated to the system encoding. You can use
+the \fB\-binary\fR option in combination with the result of
+\fBencoding convertto\fR to send data in any other encoding.
+.VE 8.6
+.TP
+\fBdde request\fR ?\fB\-binary\fR? \fIservice topic item\fR
+.
+\fBdde request\fR is typically used to get the value of something; the
+value of a cell in Microsoft Excel or the text of a selection in
+Microsoft Word. \fIservice\fR is typically the name of an application,
+\fItopic\fR is typically the name of the file, and \fIitem\fR is
+application-specific. The command returns the value of \fIitem\fR as
+defined in the application.  Normally this is interpreted to be a
+string with terminating null.  If \fB\-binary\fR is specified, the
+result is returned as a byte array.
+.TP
+\fBdde services \fIservice topic\fR
+.
+\fBdde services\fR returns a list of service-topic pairs that
+currently exist on the machine. If \fIservice\fR and \fItopic\fR are
+both empty strings ({}), then all service-topic pairs currently
+available on the system are returned. If \fIservice\fR is empty and
+\fItopic\fR is not, then all services with the specified topic are
+returned. If \fIservice\fR is non-empty and \fItopic\fR is, all topics
+for a given service are returned. If both are non-empty, if that
+service-topic pair currently exists, it is returned; otherwise, an
+empty string is returned.
+.TP
+\fBdde eval\fR ?\fB\-async\fR? \fItopic cmd \fR?\fIarg arg ...\fR?
+.
+\fBdde eval\fR evaluates a command and its arguments using the interpreter
+specified by \fItopic\fR. The DDE service must be the \fBTclEval\fR
+service.  The \fB\-async\fR option requests asynchronous invocation.  The
+command returns an error message if the script did not run, unless the
+\fB\-async\fR flag was used, in which case the command returns immediately
+with no error.  This command can be used to replace send on Windows.
+.SH "DDE AND TCL"
+.PP
+A Tcl interpreter always has a service name of \fBTclEval\fR.  Each
+different interpreter of all running Tcl applications must be
+given a unique
+name specified by \fBdde servername\fR. Each interp is available as a
+DDE topic only if the \fBdde servername\fR command was used to set the
+name of the topic for each interp. So a \fBdde services TclEval {}\fR
+command will return a list of service-topic pairs, where each of the
+currently running interps will be a topic.
+.PP
+When Tcl processes a \fBdde execute\fR command, the data for the
+execute is run as a script in the interp named by the topic of the
+\fBdde execute\fR command.
+.PP
+When Tcl processes a \fBdde request\fR command, it returns the value of the
+variable given in the dde command in the context of the interp named by the
+dde topic. Tcl reserves the variable \fB$TCLEVAL$EXECUTE$RESULT\fR for
+internal use, and \fBdde request\fR commands for that variable will give
+unpredictable results.
+.PP
+An external application which wishes to run a script in Tcl should have
+that script store its result in a variable, run the \fBdde execute\fR
+command, and then run \fBdde request\fR to get the value of the
+variable.
+.PP
+When using DDE, be careful to ensure that the event queue is flushed
+using either \fBupdate\fR or \fBvwait\fR.  This happens by default
+when using \fBwish\fR unless a blocking command is called (such as \fBexec\fR
+without adding the \fB&\fR to place the process in the background).
+If for any reason the event queue is not flushed, DDE commands may
+hang until the event queue is flushed.  This can create a deadlock
+situation.
+.SH EXAMPLE
+.PP
+This asks Internet Explorer (which must already be running) to go to a
+particularly important website:
+.PP
+.CS
+package require dde
+\fBdde execute\fR -async iexplore WWW_OpenURL http://www.tcl.tk/
+.CE
+.SH "SEE ALSO"
+tk(n), winfo(n), send(n)
+.SH KEYWORDS
+application, dde, name, remote execution
+'\"Local Variables:
+'\"mode: nroff
+'\"End:
diff --git a/doc/define.n b/doc/define.n
new file mode 100644
index 0000000..7599ec0
--- /dev/null
+++ b/doc/define.n
@@ -0,0 +1,404 @@
+'\"
+'\" Copyright (c) 2007 Donal K. Fellows
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH define n 0.3 TclOO "TclOO Commands"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+oo::define, oo::objdefine \- define and configure classes and objects
+.SH SYNOPSIS
+.nf
+package require TclOO
+
+\fBoo::define\fI class defScript\fR
+\fBoo::define\fI class subcommand arg\fR ?\fIarg ...\fR?
+\fBoo::objdefine\fI object defScript\fR
+\fBoo::objdefine\fI object subcommand arg\fR ?\fIarg ...\fR?
+.fi
+.BE
+
+.SH DESCRIPTION
+The \fBoo::define\fR command is used to control the configuration of classes,
+and the \fBoo::objdefine\fR command is used to control the configuration of
+objects (including classes as instance objects), with the configuration being
+applied to the entity named in the \fIclass\fR or the \fIobject\fR argument.
+Configuring a class also updates the
+configuration of all subclasses of the class and all objects that are
+instances of that class or which mix it in (as modified by any per-instance
+configuration). The way in which the configuration is done is controlled by
+either the \fIdefScript\fR argument or by the \fIsubcommand\fR and following
+\fIarg\fR arguments; when the second is present, it is exactly as if all the
+arguments from \fIsubcommand\fR onwards are made into a list and that list is
+used as the \fIdefScript\fR argument.
+.SS "CONFIGURING CLASSES"
+.PP
+The following commands are supported in the \fIdefScript\fR for
+\fBoo::define\fR, each of which may also be used in the \fIsubcommand\fR form:
+.TP
+\fBconstructor\fI argList bodyScript\fR
+.
+This creates or updates the constructor for a class. The formal arguments to
+the constructor (defined using the same format as for the Tcl \fBproc\fR
+command) will be \fIargList\fR, and the body of the constructor will be
+\fIbodyScript\fR. When the body of the constructor is evaluated, the current
+namespace of the constructor will be a namespace that is unique to the object
+being constructed. Within the constructor, the \fBnext\fR command should be
+used to call the superclasses' constructors. If \fIbodyScript\fR is the empty
+string, the constructor will be deleted.
+.TP
+\fBdeletemethod\fI name\fR ?\fIname ...\fR
+.
+This deletes each of the methods called \fIname\fR from a class. The methods
+must have previously existed in that class. Does not affect the superclasses
+of the class, nor does it affect the subclasses or instances of the class
+(except when they have a call chain through the class being modified).
+.TP
+\fBdestructor\fI bodyScript\fR
+.
+This creates or updates the destructor for a class. Destructors take no
+arguments, and the body of the destructor will be \fIbodyScript\fR. The
+destructor is called when objects of the class are deleted, and when called
+will have the object's unique namespace as the current namespace. Destructors
+should use the \fBnext\fR command to call the superclasses' destructors. Note
+that destructors are not called in all situations (e.g. if the interpreter is
+destroyed). If \fIbodyScript\fR is the empty string, the destructor will be
+deleted.
+.RS
+Note that errors during the evaluation of a destructor \fIare not returned\fR
+to the code that causes the destruction of an object. Instead, they are passed
+to the currently-defined \fBbgerror\fR handler.
+.RE
+.TP
+\fBexport\fI name \fR?\fIname ...\fR?
+.
+This arranges for each of the named methods, \fIname\fR, to be exported
+(i.e. usable outside an instance through the instance object's command) by the
+class being defined. Note that the methods themselves may be actually defined
+by a superclass; subclass exports override superclass visibility, and may in
+turn be overridden by instances.
+.TP
+\fBfilter\fR ?\fI\-slotOperation\fR? ?\fImethodName ...\fR?
+.VS
+This slot (see \fBSLOTTED DEFINITIONS\fR below)
+.VE
+sets or updates the list of method names that are used to guard whether
+method call to instances of the class may be called and what the method's
+results are. Each \fImethodName\fR names a single filtering method (which may
+be exposed or not exposed); it is not an error for a non-existent method to be
+named since they may be defined by subclasses.
+.VS
+By default, this slot works by appending.
+.VE
+.TP
+\fBforward\fI name cmdName \fR?\fIarg ...\fR?
+.
+This creates or updates a forwarded method called \fIname\fR. The method is
+defined be forwarded to the command called \fIcmdName\fR, with additional
+arguments, \fIarg\fR etc., added before those arguments specified by the
+caller of the method. The \fIcmdName\fR will always be resolved using the
+rules of the invoking objects' namespaces, i.e., when \fIcmdName\fR is not
+fully-qualified, the command will be searched for in each object's namespace,
+using the instances' namespace's path, or by looking in the global namespace.
+The method will be exported if \fIname\fR starts with a lower-case letter, and
+non-exported otherwise.
+.TP
+\fBmethod\fI name argList bodyScript\fR
+.
+This creates or updates a method that is implemented as a procedure-like
+script. The name of the method is \fIname\fR, the formal arguments to the
+method (defined using the same format as for the Tcl \fBproc\fR command) will
+be \fIargList\fR, and the body of the method will be \fIbodyScript\fR. When
+the body of the method is evaluated, the current namespace of the method will
+be a namespace that is unique to the current object. The method will be
+exported if \fIname\fR starts with a lower-case letter, and non-exported
+otherwise; this behavior can be overridden via \fBexport\fR and
+\fBunexport\fR.
+.TP
+\fBmixin\fR ?\fI\-slotOperation\fR? ?\fIclassName ...\fR?
+.VS
+This slot (see \fBSLOTTED DEFINITIONS\fR below)
+.VE
+sets or updates the list of additional classes that are to be mixed into
+all the instances of the class being defined. Each \fIclassName\fR argument
+names a single class that is to be mixed in.
+.VS
+By default, this slot works by replacement.
+.VE
+.TP
+\fBrenamemethod\fI fromName toName\fR
+.
+This renames the method called \fIfromName\fR in a class to \fItoName\fR. The
+method must have previously existed in the class, and \fItoName\fR must not
+previously refer to a method in that class. Does not affect the superclasses
+of the class, nor does it affect the subclasses or instances of the class
+(except when they have a call chain through the class being modified). Does
+not change the export status of the method; if it was exported before, it will
+be afterwards.
+.TP
+\fBself\fI subcommand arg ...\fR
+.TP
+\fBself\fI script\fR
+.
+This command is equivalent to calling \fBoo::objdefine\fR on the class being
+defined (see \fBCONFIGURING OBJECTS\fR below for a description of the
+supported values of \fIsubcommand\fR). It follows the same general pattern of
+argument handling as the \fBoo::define\fR and \fBoo::objdefine\fR commands,
+and
+.QW "\fBoo::define \fIcls \fBself \fIsubcommand ...\fR"
+operates identically to
+.QW "\fBoo::objdefine \fIcls subcommand ...\fR" .
+.TP
+\fBsuperclass\fR ?\fI\-slotOperation\fR? ?\fIclassName ...\fR?
+.VS
+This slot (see \fBSLOTTED DEFINITIONS\fR below)
+.VE
+allows the alteration of the superclasses of the class being defined.
+Each \fIclassName\fR argument names one class that is to be a superclass of
+the defined class. Note that objects must not be changed from being classes to
+being non-classes or vice-versa, that an empty parent class is equivalent to
+\fBoo::object\fR, and that the parent classes of \fBoo::object\fR and
+\fBoo::class\fR may not be modified.
+.VS
+By default, this slot works by replacement.
+.VE
+.TP
+\fBunexport\fI name \fR?\fIname ...\fR?
+.
+This arranges for each of the named methods, \fIname\fR, to be not exported
+(i.e. not usable outside the instance through the instance object's command,
+but instead just through the \fBmy\fR command visible in each object's
+context) by the class being defined. Note that the methods themselves may be
+actually defined by a superclass; subclass unexports override superclass
+visibility, and may be overridden by instance unexports.
+.TP
+\fBvariable\fR ?\fI\-slotOperation\fR? ?\fIname ...\fR?
+.VS
+This slot (see \fBSLOTTED DEFINITIONS\fR below) arranges for each of the named
+variables to be automatically made
+available in the methods, constructor and destructor declared by the class
+being defined. Each variable name must not have any namespace
+separators and must not look like an array access. All variables will be
+actually present in the instance object on which the method is executed. Note
+that the variable lists declared by a superclass or subclass are completely
+disjoint, as are variable lists declared by instances; the list of variable
+names is just for methods (and constructors and destructors) declared by this
+class. By default, this slot works by appending.
+.VE
+.SS "CONFIGURING OBJECTS"
+.PP
+The following commands are supported in the \fIdefScript\fR for
+\fBoo::objdefine\fR, each of which may also be used in the \fIsubcommand\fR
+form:
+.TP
+\fBclass\fI className\fR
+.
+This allows the class of an object to be changed after creation. Note that the
+class's constructors are not called when this is done, and so the object may
+well be in an inconsistent state unless additional configuration work is done.
+.TP
+\fBdeletemethod\fI name\fR ?\fIname ...\fR
+.
+This deletes each of the methods called \fIname\fR from an object. The methods
+must have previously existed in that object. Does not affect the classes that
+the object is an instance of.
+.TP
+\fBexport\fI name \fR?\fIname ...\fR?
+.
+This arranges for each of the named methods, \fIname\fR, to be exported
+(i.e. usable outside the object through the object's command) by the object
+being defined. Note that the methods themselves may be actually defined by a
+class or superclass; object exports override class visibility.
+.TP
+\fBfilter\fR ?\fI\-slotOperation\fR? ?\fImethodName ...\fR?
+.VS
+This slot (see \fBSLOTTED DEFINITIONS\fR below)
+.VE
+sets or updates the list of method names that are used to guard whether a
+method call to the object may be called and what the method's results are.
+Each \fImethodName\fR names a single filtering method (which may be exposed or
+not exposed); it is not an error for a non-existent method to be named. Note
+that the actual list of filters also depends on the filters set upon any
+classes that the object is an instance of.
+.VS
+By default, this slot works by appending.
+.VE
+.TP
+\fBforward\fI name cmdName \fR?\fIarg ...\fR?
+.
+This creates or updates a forwarded object method called \fIname\fR. The
+method is defined be forwarded to the command called \fIcmdName\fR, with
+additional arguments, \fIarg\fR etc., added before those arguments specified
+by the caller of the method. Forwarded methods should be deleted using the
+\fBmethod\fR subcommand. The method will be exported if \fIname\fR starts with
+a lower-case letter, and non-exported otherwise.
+.TP
+\fBmethod\fI name argList bodyScript\fR
+.
+This creates, updates or deletes an object method. The name of the method is
+\fIname\fR, the formal arguments to the method (defined using the same format
+as for the Tcl \fBproc\fR command) will be \fIargList\fR, and the body of the
+method will be \fIbodyScript\fR. When the body of the method is evaluated, the
+current namespace of the method will be a namespace that is unique to the
+object. The method will be exported if \fIname\fR starts with a lower-case
+letter, and non-exported otherwise.
+.TP
+\fBmixin\fR ?\fI\-slotOperation\fR? ?\fIclassName ...\fR?
+.VS
+This slot (see \fBSLOTTED DEFINITIONS\fR below)
+.VE
+sets or updates a per-object list of additional classes that are to be
+mixed into the object. Each argument, \fIclassName\fR, names a single class
+that is to be mixed in.
+.VS
+By default, this slot works by replacement.
+.VE
+.TP
+\fBrenamemethod\fI fromName toName\fR
+.
+This renames the method called \fIfromName\fR in an object to \fItoName\fR.
+The method must have previously existed in the object, and \fItoName\fR must
+not previously refer to a method in that object. Does not affect the classes
+that the object is an instance of. Does not change the export status of the
+method; if it was exported before, it will be afterwards.
+.TP
+\fBunexport\fI name \fR?\fIname ...\fR?
+.
+This arranges for each of the named methods, \fIname\fR, to be not exported
+(i.e. not usable outside the object through the object's command, but instead
+just through the \fBmy\fR command visible in the object's context) by the
+object being defined. Note that the methods themselves may be actually defined
+by a class; instance unexports override class visibility.
+.TP
+\fBvariable\fR ?\fI\-slotOperation\fR? ?\fIname ...\fR?
+.VS
+This slot (see \fBSLOTTED DEFINITIONS\fR below) arranges for each of the named
+variables to be automatically made available in the methods declared by the
+object being defined.  Each variable name must not have any namespace
+separators and must not look like an array access. All variables will be
+actually present in the object on which the method is executed. Note that the
+variable lists declared by the classes and mixins of which the object is an
+instance are completely disjoint; the list of variable names is just for
+methods declared by this object. By default, this slot works by appending.
+.SH "SLOTTED DEFINITIONS"
+Some of the configurable definitions of a class or object are \fIslotted
+definitions\fR. This means that the configuration is implemented by a slot
+object, that is an instance of the class \fBoo::Slot\fR, which manages a list
+of values (class names, variable names, etc.) that comprises the contents of
+the slot. The class defines three operations (as methods) that may be done on
+the slot:
+.VE
+.TP
+\fIslot\fR \fB\-append\fR ?\fImember ...\fR?
+.VS
+This appends the given \fImember\fR elements to the slot definition.
+.VE
+.TP
+\fIslot\fR \fB\-clear\fR
+.VS
+This sets the slot definition to the empty list.
+.VE
+.TP
+\fIslot\fR \fB\-set\fR ?\fImember ...\fR?
+.VS
+This replaces the slot definition with the given \fImember\fR elements.
+.PP
+A consequence of this is that any use of a slot's default operation where the
+first member argument begins with a hyphen will be an error. One of the above
+operations should be used explicitly in those circumstances.
+.SS "SLOT IMPLEMENTATION"
+Internally, slot objects also define a method \fB\-\-default\-operation\fR
+which is forwarded to the default operation of the slot (thus, for the class
+.QW \fBvariable\fR
+slot, this is forwarded to
+.QW "\fBmy \-append\fR" ),
+and these methods which provide the implementation interface:
+.VE
+.TP
+\fIslot\fR \fBGet\fR
+.VS
+Returns a list that is the current contents of the slot. This method must
+always be called from a stack frame created by a call to \fBoo::define\fR or
+\fBoo::objdefine\fR.
+.VE
+.TP
+\fIslot\fR \fBSet \fIelementList\fR
+.VS
+Sets the contents of the slot to the list \fIelementList\fR and returns the
+empty string. This method must always be called from a stack frame created by
+a call to \fBoo::define\fR or \fBoo::objdefine\fR.
+.PP
+The implementation of these methods is slot-dependent (and responsible for
+accessing the correct part of the class or object definition). Slots also have
+an unknown method handler to tie all these pieces together, and they hide
+their \fBdestroy\fR method so that it is not invoked inadvertently. It is
+\fIrecommended\fR that any user changes to the slot mechanism be restricted to
+defining new operations whose names start with a hyphen.
+.VE
+.SH EXAMPLES
+This example demonstrates how to use both forms of the \fBoo::define\fR and
+\fBoo::objdefine\fR commands (they work in the same way), as well as
+illustrating four of the subcommands of them.
+.PP
+.CS
+oo::class create c
+c create o
+\fBoo::define\fR c \fBmethod\fR foo {} {
+    puts "world"
+}
+\fBoo::objdefine\fR o {
+    \fBmethod\fR bar {} {
+        my Foo "hello "
+        my foo
+    }
+    \fBforward\fR Foo ::puts -nonewline
+    \fBunexport\fR foo
+}
+o bar                \fI\(-> prints "hello world"\fR
+o foo                \fI\(-> error "unknown method foo"\fR
+o Foo Bar            \fI\(-> error "unknown method Foo"\fR
+\fBoo::objdefine\fR o \fBrenamemethod\fR bar lollipop
+o lollipop           \fI\(-> prints "hello world"\fR
+.CE
+.PP
+This example shows how additional classes can be mixed into an object. It also
+shows how \fBmixin\fR is a slot that supports appending:
+.PP
+.CS
+oo::object create inst
+inst m1              \fI\(-> error "unknown method m1"\fR
+inst m2              \fI\(-> error "unknown method m2"\fR
+
+oo::class create A {
+    \fBmethod\fR m1 {} {
+        puts "red brick"
+    }
+}
+\fBoo::objdefine\fR inst {
+    \fBmixin\fR A
+}
+inst m1              \fI\(-> prints "red brick"\fR
+inst m2              \fI\(-> error "unknown method m2"\fR
+
+oo::class create B {
+    \fBmethod\fR m2 {} {
+        puts "blue brick"
+    }
+}
+\fBoo::objdefine\fR inst {
+    \fBmixin -append\fR B
+}
+inst m1              \fI\(-> prints "red brick"\fR
+inst m2              \fI\(-> prints "blue brick"\fR
+.CE
+.SH "SEE ALSO"
+next(n), oo::class(n), oo::object(n)
+.SH KEYWORDS
+class, definition, method, object, slot
+.\" Local variables:
+.\" mode: nroff
+.\" fill-column: 78
+.\" End:
diff --git a/doc/dict.n b/doc/dict.n
new file mode 100644
index 0000000..fecad85
--- /dev/null
+++ b/doc/dict.n
@@ -0,0 +1,445 @@
+'\"
+'\" Copyright (c) 2003 Donal K. Fellows
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH dict n 8.5 Tcl "Tcl Built-In Commands"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+dict \- Manipulate dictionaries
+.SH SYNOPSIS
+\fBdict \fIoption arg \fR?\fIarg ...\fR?
+.BE
+.SH DESCRIPTION
+.PP
+Performs one of several operations on dictionary values or variables
+containing dictionary values (see the \fBDICTIONARY VALUES\fR section
+below for a description), depending on \fIoption\fR.  The legal
+\fIoption\fRs (which may be abbreviated) are:
+.TP
+\fBdict append \fIdictionaryVariable key \fR?\fIstring ...\fR?
+.
+This appends the given string (or strings) to the value that the given
+key maps to in the dictionary value contained in the given variable,
+writing the resulting dictionary value back to that variable.
+Non-existent keys are treated as if they map to an empty string. The
+updated dictionary value is returned.
+.TP
+\fBdict create \fR?\fIkey value ...\fR?
+.
+Return a new dictionary that contains each of the key/value mappings
+listed as arguments (keys and values alternating, with each key being
+followed by its associated value.)
+.TP
+\fBdict exists \fIdictionaryValue key \fR?\fIkey ...\fR?
+.
+This returns a boolean value indicating whether the given key (or path
+of keys through a set of nested dictionaries) exists in the given
+dictionary value. This returns a true value exactly when \fBdict
+get\fR on that path will succeed.
+.TP
+\fBdict filter \fIdictionaryValue filterType arg \fR?\fIarg ...\fR?
+.
+This takes a dictionary value and returns a new dictionary that
+contains just those key/value pairs that match the specified filter
+type (which may be abbreviated.)  Supported filter types are:
+.RS
+.TP
+\fBdict filter \fIdictionaryValue \fBkey\fR ?\fIglobPattern ...\fR?
+.VS 8.6
+The key rule only matches those key/value pairs whose keys match any
+of the given patterns (in the style of \fBstring match\fR.)
+.VE 8.6
+.TP
+\fBdict filter \fIdictionaryValue \fBscript {\fIkeyVariable valueVariable\fB} \fIscript\fR
+.
+The script rule tests for matching by assigning the key to the
+\fIkeyVariable\fR and the value to the \fIvalueVariable\fR, and then evaluating
+the given script which should return a boolean value (with the
+key/value pair only being included in the result of the \fBdict
+filter\fR when a true value is returned.)  Note that the first
+argument after the rule selection word is a two-element list.  If the
+\fIscript\fR returns with a condition of \fBTCL_BREAK\fR, no further
+key/value pairs are considered for inclusion in the resulting
+dictionary, and a condition of \fBTCL_CONTINUE\fR is equivalent to a false
+result. The key/value pairs are tested in the order in which the keys
+were inserted into the dictionary.
+.TP
+\fBdict filter \fIdictionaryValue \fBvalue \fR?\fIglobPattern ...\fR?
+.VS 8.6
+The value rule only matches those key/value pairs whose values match any
+of the given patterns (in the style of \fBstring match\fR.)
+.VE 8.6
+.RE
+.TP
+\fBdict for {\fIkeyVariable valueVariable\fB} \fIdictionaryValue body\fR
+.
+This command takes three arguments, the first a two-element list of
+variable names (for the key and value respectively of each mapping in
+the dictionary), the second the dictionary value to iterate across,
+and the third a script to be evaluated for each mapping with the key
+and value variables set appropriately (in the manner of \fBforeach\fR.)
+The result of the command is an empty string. If any evaluation of the
+body generates a \fBTCL_BREAK\fR result, no further pairs from the
+dictionary will be iterated over and the \fBdict for\fR command will
+terminate successfully immediately. If any evaluation of the body
+generates a \fBTCL_CONTINUE\fR result, this shall be treated exactly like a
+normal \fBTCL_OK\fR result. The order of iteration is the order in
+which the keys were inserted into the dictionary.
+.TP
+\fBdict get \fIdictionaryValue \fR?\fIkey ...\fR?
+.
+Given a dictionary value (first argument) and a key (second argument),
+this will retrieve the value for that key. Where several keys are
+supplied, the behaviour of the command shall be as if the result of
+\fBdict get $dictVal $key\fR was passed as the first argument to
+\fBdict get\fR with the remaining arguments as second (and possibly
+subsequent) arguments. This facilitates lookups in nested
+dictionaries. For example, the following two commands are equivalent:
+.RS
+.PP
+.CS
+dict get $dict foo bar spong
+dict get [dict get [dict get $dict foo] bar] spong
+.CE
+.PP
+If no keys are provided, \fBdict get\fR will return a list containing pairs of
+elements in a manner similar to \fBarray get\fR. That is, the first
+element of each pair would be the key and the second element would be
+the value for that key.
+.PP
+It is an error to attempt to retrieve a value for a key that is not
+present in the dictionary.
+.RE
+.TP
+\fBdict incr \fIdictionaryVariable key \fR?\fIincrement\fR?
+.
+This adds the given increment value (an integer that defaults to 1 if
+not specified) to the value that the given key maps to in the
+dictionary value contained in the given variable, writing the
+resulting dictionary value back to that variable. Non-existent keys
+are treated as if they map to 0. It is an error to increment a value
+for an existing key if that value is not an integer. The updated
+dictionary value is returned.
+.TP
+\fBdict info \fIdictionaryValue\fR
+.
+This returns information (intended for display to people) about the
+given dictionary though the format of this data is dependent on the
+implementation of the dictionary. For dictionaries that are
+implemented by hash tables, it is expected that this will return the
+string produced by \fBTcl_HashStats\fR, similar to \fBarray statistics\fR.
+.TP
+\fBdict keys \fIdictionaryValue \fR?\fIglobPattern\fR?
+.
+Return a list of all keys in the given dictionary value. If a pattern
+is supplied, only those keys that match it (according to the rules of
+\fBstring match\fR) will be returned. The returned keys will be in the
+order that they were inserted into the dictionary.
+.TP
+\fBdict lappend \fIdictionaryVariable key \fR?\fIvalue ...\fR?
+.
+This appends the given items to the list value that the given key maps
+to in the dictionary value contained in the given variable, writing
+the resulting dictionary value back to that variable. Non-existent
+keys are treated as if they map to an empty list, and it is legal for
+there to be no items to append to the list. It is an error for the
+value that the key maps to to not be representable as a list. The
+updated dictionary value is returned.
+.TP
+\fBdict map \fR{\fIkeyVariable valueVariable\fR} \fIdictionaryValue body\fR
+.
+This command applies a transformation to each element of a dictionary,
+returning a new dictionary. It takes three arguments: the first is a
+two-element list of variable names (for the key and value respectively of each
+mapping in the dictionary), the second the dictionary value to iterate across,
+and the third a script to be evaluated for each mapping with the key and value
+variables set appropriately (in the manner of \fBlmap\fR). In an iteration
+where the evaluated script completes normally (\fBTCL_OK\fR, as opposed to an
+\fBerror\fR, etc.) the result of the script is put into an accumulator
+dictionary using the key that is the current contents of the \fIkeyVariable\fR
+variable at that point. The result of the \fBdict map\fR command is the
+accumulator dictionary after all keys have been iterated over.
+.RS
+.PP
+If the evaluation of the body for any particular step generates a \fBbreak\fR,
+no further pairs from the dictionary will be iterated over and the \fBdict
+map\fR command will terminate successfully immediately. If the evaluation of
+the body for a particular step generates a \fBcontinue\fR result, the current
+iteration is aborted and the accumulator dictionary is not modified. The order
+of iteration is the natural order of the dictionary (typically the order in
+which the keys were added to the dictionary; the order is the same as that
+used in \fBdict for\fR).
+.RE
+.TP
+\fBdict merge \fR?\fIdictionaryValue ...\fR?
+.
+Return a dictionary that contains the contents of each of the
+\fIdictionaryValue\fR arguments.  Where two (or more) dictionaries
+contain a mapping for the same key, the resulting dictionary maps that
+key to the value according to the last dictionary on the command line
+containing a mapping for that key.
+.TP
+\fBdict remove \fIdictionaryValue \fR?\fIkey ...\fR?
+.
+Return a new dictionary that is a copy of an old one passed in as
+first argument except without mappings for each of the keys listed.
+It is legal for there to be no keys to remove, and it also legal for
+any of the keys to be removed to not be present in the input
+dictionary in the first place.
+.TP
+\fBdict replace \fIdictionaryValue \fR?\fIkey value ...\fR?
+.
+Return a new dictionary that is a copy of an old one passed in as
+first argument except with some values different or some extra
+key/value pairs added. It is legal for this command to be called with
+no key/value pairs, but illegal for this command to be called with a
+key but no value.
+.TP
+\fBdict set \fIdictionaryVariable key \fR?\fIkey ...\fR? \fIvalue\fR
+.
+This operation takes the name of a variable containing a dictionary
+value and places an updated dictionary value in that variable
+containing a mapping from the given key to the given value. When
+multiple keys are present, this operation creates or updates a chain
+of nested dictionaries. The updated dictionary value is returned.
+.TP
+\fBdict size \fIdictionaryValue\fR
+.
+Return the number of key/value mappings in the given dictionary value.
+.TP
+\fBdict unset \fIdictionaryVariable key \fR?\fIkey ...\fR?
+.
+This operation (the companion to \fBdict set\fR) takes the name of a
+variable containing a dictionary value and places an updated
+dictionary value in that variable that does not contain a mapping for
+the given key. Where multiple keys are present, this describes a path
+through nested dictionaries to the mapping to remove. At least one key
+must be specified, but the last key on the key-path need not exist.
+All other components on the path must exist. The updated dictionary
+value is returned.
+.TP
+\fBdict update \fIdictionaryVariable key varName \fR?\fIkey varName ...\fR? \fIbody\fR
+.
+Execute the Tcl script in \fIbody\fR with the value for each \fIkey\fR
+(as found by reading the dictionary value in \fIdictionaryVariable\fR)
+mapped to the variable \fIvarName\fR. There may be multiple
+\fIkey\fR/\fIvarName\fR pairs. If a \fIkey\fR does not have a mapping,
+that corresponds to an unset \fIvarName\fR. When \fIbody\fR
+terminates, any changes made to the \fIvarName\fRs is reflected back
+to the dictionary within \fIdictionaryVariable\fR (unless
+\fIdictionaryVariable\fR itself becomes unreadable, when all updates
+are silently discarded), even if the result of \fIbody\fR is an error
+or some other kind of exceptional exit. The result of \fBdict
+update\fR is (unless some kind of error occurs) the result of the
+evaluation of \fIbody\fR.
+.RS
+.PP
+Each \fIvarName\fR is mapped in the scope enclosing the \fBdict update\fR;
+it is recommended that this command only be used in a local scope
+(\fBproc\fRedure, lambda term for \fBapply\fR, or method). Because of
+this, the variables set by \fBdict update\fR will continue to
+exist after the command finishes (unless explicitly \fBunset\fR).
+Note that the mapping of values to variables
+does not use traces; changes to the \fIdictionaryVariable\fR's
+contents only happen when \fIbody\fR terminates.
+.RE
+.TP
+\fBdict values \fIdictionaryValue \fR?\fIglobPattern\fR?
+.
+Return a list of all values in the given dictionary value. If a
+pattern is supplied, only those values that match it (according to the
+rules of \fBstring match\fR) will be returned. The returned values
+will be in the order of that the keys associated with those values
+were inserted into the dictionary.
+.TP
+\fBdict with \fIdictionaryVariable \fR?\fIkey ...\fR? \fIbody\fR
+.
+Execute the Tcl script in \fIbody\fR with the value for each key in
+\fIdictionaryVariable\fR mapped (in a manner similarly to \fBdict
+update\fR) to a variable with the same name. Where one or more
+\fIkey\fRs are available, these indicate a chain of nested
+dictionaries, with the innermost dictionary being the one opened out
+for the execution of \fIbody\fR. As with \fBdict update\fR, making
+\fIdictionaryVariable\fR unreadable will make the updates to the
+dictionary be discarded, and this also happens if the contents of
+\fIdictionaryVariable\fR are adjusted so that the chain of
+dictionaries no longer exists. The result of \fBdict with\fR is
+(unless some kind of error occurs) the result of the evaluation of
+\fIbody\fR.
+.RS
+.PP
+The variables are mapped in the scope enclosing the \fBdict with\fR;
+it is recommended that this command only be used in a local scope
+(\fBproc\fRedure, lambda term for \fBapply\fR, or method). Because of
+this, the variables set by \fBdict with\fR will continue to
+exist after the command finishes (unless explicitly \fBunset\fR).
+Note that the mapping of values to variables does not use
+traces; changes to the \fIdictionaryVariable\fR's contents only happen
+when \fIbody\fR terminates.
+.PP
+If the \fIdictionaryVariable\fR contains a value that is not a dictionary at
+the point when the \fIbody\fR terminates (which can easily happen if the name
+is the same as any of the keys in dictionary) then an error occurs at that
+point. This command is thus not recommended for use when the keys in the
+dictionary are expected to clash with the \fIdictionaryVariable\fR name
+itself. Where the contained key does map to a dictionary, the net effect is to
+combine that inner dictionary into the outer dictionary; see the
+\fBEXAMPLES\fR below for an illustration of this.
+.RE
+.SH "DICTIONARY VALUES"
+.PP
+Dictionaries are values that contain an efficient, order-preserving
+mapping from arbitrary keys to arbitrary values.
+Each key in the dictionary maps to a single value.
+They have a textual format that is exactly that of any list with an
+even number of elements, with each mapping in the dictionary being
+represented as two items in the list. When a command takes a
+dictionary and produces a new dictionary based on it (either returning
+it or writing it back into the variable that the starting dictionary
+was read from) the new dictionary will have the same order of keys,
+modulo any deleted keys and with new keys added on to the end.
+When a string is interpreted as a dictionary and it would otherwise
+have duplicate keys, only the last value for a particular key is used;
+the others are ignored, meaning that,
+.QW "apple banana"
+and
+.QW "apple carrot apple banana"
+are equivalent dictionaries (with different string representations).
+.PP
+Operations that derive a new dictionary from an old one (e.g., updates
+like \fBdict set\fR and \fBdict unset\fR) preserve the order of keys
+in the dictionary. The exceptions to this are for any new keys they
+add, which are appended to the sequence, and any keys that are
+removed, which are excised from the order.
+.SH EXAMPLES
+.PP
+Basic dictionary usage:
+.PP
+.CS
+# Make a dictionary to map extensions to descriptions
+set filetypes [\fBdict create\fR .txt "Text File" .tcl "Tcl File"]
+
+# Add/update the dictionary
+\fBdict set\fR filetypes .tcl "Tcl Script"
+\fBdict set\fR filetypes .tm  "Tcl Module"
+\fBdict set\fR filetypes .gif "GIF Image"
+\fBdict set\fR filetypes .png "PNG Image"
+
+# Simple read from the dictionary
+set ext ".tcl"
+set desc [\fBdict get\fR $filetypes $ext]
+puts "$ext is for a $desc"
+
+# Somewhat more complex, with existence test
+foreach filename [glob *] {
+    set ext [file extension $filename]
+    if {[\fBdict exists\fR $filetypes $ext]} {
+        puts "$filename is a [\fBdict get\fR $filetypes $ext]"
+    }
+}
+.CE
+.PP
+Constructing and using nested dictionaries:
+.PP
+.CS
+# Data for one employee
+\fBdict set\fR employeeInfo 12345-A forenames "Joe"
+\fBdict set\fR employeeInfo 12345-A surname   "Schmoe"
+\fBdict set\fR employeeInfo 12345-A street "147 Short Street"
+\fBdict set\fR employeeInfo 12345-A city   "Springfield"
+\fBdict set\fR employeeInfo 12345-A phone  "555-1234"
+# Data for another employee
+\fBdict set\fR employeeInfo 98372-J forenames "Anne"
+\fBdict set\fR employeeInfo 98372-J surname   "Other"
+\fBdict set\fR employeeInfo 98372-J street "32995 Oakdale Way"
+\fBdict set\fR employeeInfo 98372-J city   "Springfield"
+\fBdict set\fR employeeInfo 98372-J phone  "555-8765"
+# The above data probably ought to come from a database...
+
+# Print out some employee info
+set i 0
+puts "There are [\fBdict size\fR $employeeInfo] employees"
+\fBdict for\fR {id info} $employeeInfo {
+    puts "Employee #[incr i]: $id"
+    \fBdict with\fR info {
+        puts "   Name: $forenames $surname"
+        puts "   Address: $street, $city"
+        puts "   Telephone: $phone"
+    }
+}
+# Another way to iterate and pick out names...
+foreach id [\fBdict keys\fR $employeeInfo] {
+    puts "Hello, [\fBdict get\fR $employeeInfo $id forenames]!"
+}
+.CE
+.PP
+A localizable version of \fBstring toupper\fR:
+.PP
+.CS
+# Set up the basic C locale
+set capital [\fBdict create\fR C [\fBdict create\fR]]
+foreach c [split {abcdefghijklmnopqrstuvwxyz} ""] {
+    \fBdict set\fR capital C $c [string toupper $c]
+}
+
+# English locales can luckily share the "C" locale
+\fBdict set\fR capital en [\fBdict get\fR $capital C]
+\fBdict set\fR capital en_US [\fBdict get\fR $capital C]
+\fBdict set\fR capital en_GB [\fBdict get\fR $capital C]
+
+# ... and so on for other supported languages ...
+
+# Now get the mapping for the current locale and use it.
+set upperCaseMap [\fBdict get\fR $capital $env(LANG)]
+set upperCase [string map $upperCaseMap $string]
+.CE
+.PP
+Showing the detail of \fBdict with\fR:
+.PP
+.CS
+proc sumDictionary {varName} {
+    upvar 1 $varName vbl
+    foreach key [\fBdict keys\fR $vbl] {
+        # Manufacture an entry in the subdictionary
+        \fBdict set\fR vbl $key total 0
+        # Add the values and remove the old
+        \fBdict with\fR vbl $key {
+            set total [expr {$x + $y + $z}]
+            unset x y z
+        }
+    }
+    puts "last total was $total, for key $key"
+}
+
+set myDict {
+    a {x 1 y 2 z 3}
+    b {x 6 y 5 z 4}
+}
+
+sumDictionary myDict
+#    prints: \fIlast total was 15, for key b\fR
+
+puts "dictionary is now \\"$myDict\\""
+#    prints: \fIdictionary is now "a {total 6} b {total 15}"\fR
+.CE
+.PP
+When \fBdict with\fR is used with a key that clashes with the name of the
+dictionary variable:
+.PP
+.CS
+set foo {foo {a b} bar 2 baz 3}
+\fBdict with\fR foo {}
+puts $foo
+#    prints: \fIa b foo {a b} bar 2 baz 3\fR
+.CE
+.SH "SEE ALSO"
+append(n), array(n), foreach(n), mapeach(n), incr(n), list(n), lappend(n), set(n)
+.SH KEYWORDS
+dictionary, create, update, lookup, iterate, filter, map
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/doc/encoding.n b/doc/encoding.n
new file mode 100644
index 0000000..50ad083
--- /dev/null
+++ b/doc/encoding.n
@@ -0,0 +1,115 @@
+'\"
+'\" Copyright (c) 1998 by Scriptics Corporation.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH encoding n "8.1" Tcl "Tcl Built-In Commands"
+.so man.macros
+.BS
+.SH NAME
+encoding \- Manipulate encodings
+.SH SYNOPSIS
+\fBencoding \fIoption\fR ?\fIarg arg ...\fR?
+.BE
+.SH INTRODUCTION
+.PP
+Strings in Tcl are logically a sequence of 16-bit Unicode characters.
+These strings are represented in memory as a sequence of bytes that
+may be in one of several encodings: modified UTF\-8 (which uses 1 to 3
+bytes per character), 16-bit
+.QW Unicode
+(which uses 2 bytes per character, with an endianness that is
+dependent on the host architecture), and binary (which uses a single
+byte per character but only handles a restricted range of characters).
+Tcl does not guarantee to always use the same encoding for the same
+string.
+.PP
+Different operating system interfaces or applications may generate
+strings in other encodings such as Shift\-JIS.  The \fBencoding\fR
+command helps to bridge the gap between Unicode and these other
+formats.
+.SH DESCRIPTION
+.PP
+Performs one of several encoding related operations, depending on
+\fIoption\fR.  The legal \fIoption\fRs are:
+.TP
+\fBencoding convertfrom\fR ?\fIencoding\fR? \fIdata\fR
+.
+Convert \fIdata\fR to Unicode from the specified \fIencoding\fR.  The
+characters in \fIdata\fR are treated as binary data where the lower
+8-bits of each character is taken as a single byte.  The resulting
+sequence of bytes is treated as a string in the specified
+\fIencoding\fR.  If \fIencoding\fR is not specified, the current
+system encoding is used.
+.TP
+\fBencoding convertto\fR ?\fIencoding\fR? \fIstring\fR
+.
+Convert \fIstring\fR from Unicode to the specified \fIencoding\fR.
+The result is a sequence of bytes that represents the converted
+string.  Each byte is stored in the lower 8-bits of a Unicode
+character (indeed, the resulting string is a binary string as far as
+Tcl is concerned, at least initially).  If \fIencoding\fR is not
+specified, the current system encoding is used.
+.TP
+\fBencoding dirs\fR ?\fIdirectoryList\fR?
+.
+Tcl can load encoding data files from the file system that describe
+additional encodings for it to work with. This command sets the search
+path for \fB*.enc\fR encoding data files to the list of directories
+\fIdirectoryList\fR. If \fIdirectoryList\fR is omitted then the
+command returns the current list of directories that make up the
+search path. It is an error for \fIdirectoryList\fR to not be a valid
+list. If, when a search for an encoding data file is happening, an
+element in \fIdirectoryList\fR does not refer to a readable,
+searchable directory, that element is ignored.
+.TP
+\fBencoding names\fR
+.
+Returns a list containing the names of all of the encodings that are
+currently available.
+The encodings
+.QW utf-8
+and
+.QW iso8859-1
+are guaranteed to be present in the list.
+.TP
+\fBencoding system\fR ?\fIencoding\fR?
+.
+Set the system encoding to \fIencoding\fR. If \fIencoding\fR is
+omitted then the command returns the current system encoding.  The
+system encoding is used whenever Tcl passes strings to system calls.
+.SH EXAMPLE
+.PP
+It is common practice to write script files using a text editor that
+produces output in the euc-jp encoding, which represents the ASCII
+characters as singe bytes and Japanese characters as two bytes.  This
+makes it easy to embed literal strings that correspond to non-ASCII
+characters by simply typing the strings in place in the script.
+However, because the \fBsource\fR command always reads files using the
+current system encoding, Tcl will only source such files correctly
+when the encoding used to write the file is the same.  This tends not
+to be true in an internationalized setting.  For example, if such a
+file was sourced in North America (where the ISO8859\-1 is normally
+used), each byte in the file would be treated as a separate character
+that maps to the 00 page in Unicode.  The resulting Tcl strings will
+not contain the expected Japanese characters.  Instead, they will
+contain a sequence of Latin-1 characters that correspond to the bytes
+of the original string.  The \fBencoding\fR command can be used to
+convert this string to the expected Japanese Unicode characters.  For
+example,
+.PP
+.CS
+set s [\fBencoding convertfrom\fR euc-jp "\exA4\exCF"]
+.CE
+.PP
+would return the Unicode string
+.QW "\eu306F" ,
+which is the Hiragana letter HA.
+.SH "SEE ALSO"
+Tcl_GetEncoding(3)
+.SH KEYWORDS
+encoding, unicode
+.\" Local Variables:
+.\" mode: nroff
+.\" End:
diff --git a/doc/eof.n b/doc/eof.n
new file mode 100644
index 0000000..75f3c48
--- /dev/null
+++ b/doc/eof.n
@@ -0,0 +1,61 @@
+'\"
+'\" Copyright (c) 1993 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\" 
+.TH eof n 7.5 Tcl "Tcl Built-In Commands"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+eof \- Check for end of file condition on channel
+.SH SYNOPSIS
+\fBeof \fIchannelId\fR
+.BE
+.SH DESCRIPTION
+.PP
+Returns 1 if an end of file condition occurred during the most
+recent input operation on \fIchannelId\fR (such as \fBgets\fR),
+0 otherwise.
+.PP
+\fIChannelId\fR must be an identifier for an open channel such as a
+Tcl standard channel (\fBstdin\fR, \fBstdout\fR, or \fBstderr\fR),
+the return value from an invocation of \fBopen\fR or \fBsocket\fR, or
+the result of a channel creation command provided by a Tcl extension.
+.SH EXAMPLES
+.PP
+Read and print out the contents of a file line-by-line:
+.PP
+.CS
+set f [open somefile.txt]
+while {1} {
+    set line [gets $f]
+    if {[\fBeof\fR $f]} {
+        close $f
+        break
+    }
+    puts "Read line: $line"
+}
+.CE
+.PP
+Read and print out the contents of a file by fixed-size records:
+.PP
+.CS
+set f [open somefile.dat]
+fconfigure $f -translation binary
+set recordSize 40
+while {1} {
+    set record [read $f $recordSize]
+    if {[\fBeof\fR $f]} {
+        close $f
+        break
+    }
+    puts "Read record: $record"
+}
+.CE
+.SH "SEE ALSO"
+file(n), open(n), close(n), fblocked(n), Tcl_StandardChannels(3)
+.SH KEYWORDS
+channel, end of file
diff --git a/doc/error.n b/doc/error.n
new file mode 100644
index 0000000..c05f8b9
--- /dev/null
+++ b/doc/error.n
@@ -0,0 +1,78 @@
+'\"
+'\" Copyright (c) 1993 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH error n "" Tcl "Tcl Built-In Commands"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+error \- Generate an error
+.SH SYNOPSIS
+\fBerror \fImessage\fR ?\fIinfo\fR? ?\fIcode\fR?
+.BE
+
+.SH DESCRIPTION
+.PP
+Returns a \fBTCL_ERROR\fR code, which causes command interpretation to be
+unwound.  \fIMessage\fR is a string that is returned to the application
+to indicate what went wrong.
+.PP
+The \fB\-errorinfo\fR return option of an interpreter is used
+to accumulate a stack trace of what was in progress when an
+error occurred; as nested commands unwind,
+the Tcl interpreter adds information to the \fB\-errorinfo\fR
+return option.  If the \fIinfo\fR argument is present, it is
+used to initialize the \fB\-errorinfo\fR return options and
+the first increment of unwind information
+will not be added by the Tcl interpreter.
+In other
+words, the command containing the \fBerror\fR command will not appear
+in the stack trace; in its place will be \fIinfo\fR.
+Historically, this feature had been most useful in conjunction
+with the \fBcatch\fR command:
+if a caught error cannot be handled successfully, \fIinfo\fR can be used
+to return a stack trace reflecting the original point of occurrence
+of the error:
+.PP
+.CS
+catch {...} errMsg
+set savedInfo $::errorInfo
+\&...
+\fBerror\fR $errMsg $savedInfo
+.CE
+.PP
+When working with Tcl 8.5 or later, the following code
+should be used instead:
+.PP
+.CS
+catch {...} errMsg options
+\&...
+return -options $options $errMsg
+.CE
+.PP
+If the \fIcode\fR argument is present, then its value is stored
+in the \fB\-errorcode\fR return option.  The \fB\-errorcode\fR
+return option is intended to hold a machine-readable description
+of the error in cases where such information is available; see
+the \fBreturn\fR manual page for information on the proper format
+for this option's value.
+.SH EXAMPLE
+.PP
+Generate an error if a basic mathematical operation fails:
+.PP
+.CS
+if {1+2 != 3} {
+    \fBerror\fR "something is very wrong with addition"
+}
+.CE
+.SH "SEE ALSO"
+catch(n), return(n)
+.SH KEYWORDS
+error, exception
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/doc/eval.n b/doc/eval.n
new file mode 100644
index 0000000..3ef5023
--- /dev/null
+++ b/doc/eval.n
@@ -0,0 +1,84 @@
+'\"
+'\" Copyright (c) 1993 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\" 
+.TH eval n "" Tcl "Tcl Built-In Commands"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+eval \- Evaluate a Tcl script
+.SH SYNOPSIS
+\fBeval \fIarg \fR?\fIarg ...\fR?
+.BE
+.SH DESCRIPTION
+.PP
+\fBEval\fR takes one or more arguments, which together comprise a Tcl
+script containing one or more commands.
+\fBEval\fR concatenates all its arguments in the same
+fashion as the \fBconcat\fR command, passes the concatenated string to the
+Tcl interpreter recursively, and returns the result of that
+evaluation (or any error generated by it).
+Note that the \fBlist\fR command quotes sequences of words in such a
+way that they are not further expanded by the \fBeval\fR command.
+.SH EXAMPLES
+.PP
+Often, it is useful to store a fragment of a script in a variable and
+execute it later on with extra values appended. This technique is used
+in a number of places throughout the Tcl core (e.g. in \fBfcopy\fR,
+\fBlsort\fR and \fBtrace\fR command callbacks). This example shows how
+to do this using core Tcl commands:
+.PP
+.CS
+set script {
+    puts "logging now"
+    lappend $myCurrentLogVar
+}
+set myCurrentLogVar log1
+# Set up a switch of logging variable part way through!
+after 20000 set myCurrentLogVar log2
+
+for {set i 0} {$i<10} {incr i} {
+    # Introduce a random delay
+    after [expr {int(5000 * rand())}]
+    update    ;# Check for the asynch log switch
+    \fBeval\fR $script $i [clock clicks]
+}
+.CE
+.PP
+Note that in the most common case (where the script fragment is
+actually just a list of words forming a command prefix), it is better
+to use \fB{*}$script\fR when doing this sort of invocation
+pattern.  It is less general than the \fBeval\fR command, and hence
+easier to make robust in practice.
+The following procedure acts in a way that is analogous to the
+\fBlappend\fR command, except it inserts the argument values at the
+start of the list in the variable:
+.PP
+.CS
+proc lprepend {varName args} {
+    upvar 1 $varName var
+    # Ensure that the variable exists and contains a list
+    lappend var
+    # Now we insert all the arguments in one go
+    set var [\fBeval\fR [list linsert $var 0] $args]
+}
+.CE
+.PP
+However, the last line would now normally be written without
+\fBeval\fR, like this:
+.PP
+.CS
+set var [linsert $var 0 {*}$args]
+.CE
+.SH "SEE ALSO"
+catch(n), concat(n), error(n), errorCode(n), errorInfo(n), interp(n), list(n),
+namespace(n), subst(n), uplevel(n)
+.SH KEYWORDS
+concatenate, evaluate, script
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/doc/exec.n b/doc/exec.n
new file mode 100644
index 0000000..70ace32
--- /dev/null
+++ b/doc/exec.n
@@ -0,0 +1,452 @@
+'\"
+'\" Copyright (c) 1993 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\" Copyright (c) 2006 Donal K. Fellows.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH exec n 8.5 Tcl "Tcl Built-In Commands"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+exec \- Invoke subprocesses
+.SH SYNOPSIS
+\fBexec \fR?\fIswitches\fR? \fIarg \fR?\fIarg ...\fR? ?\fB&\fR?
+.BE
+.SH DESCRIPTION
+.PP
+This command treats its arguments as the specification
+of one or more subprocesses to execute.
+The arguments take the form of a standard shell pipeline
+where each \fIarg\fR becomes one word of a command, and
+each distinct command becomes a subprocess.
+.PP
+If the initial arguments to \fBexec\fR start with \fB\-\fR then
+they are treated as command-line switches and are not part
+of the pipeline specification.  The following switches are
+currently supported:
+.TP 13
+\fB\-ignorestderr\fR
+.
+Stops the \fBexec\fR command from treating the output of messages to the
+pipeline's standard error channel as an error case.
+.TP 13
+\fB\-keepnewline\fR
+.
+Retains a trailing newline in the pipeline's output.
+Normally a trailing newline will be deleted.
+.TP 13
+\fB\-\|\-\fR
+.
+Marks the end of switches.  The argument following this one will
+be treated as the first \fIarg\fR even if it starts with a \fB\-\fR.
+.PP
+If an \fIarg\fR (or pair of \fIarg\fRs) has one of the forms
+described below then it is used by \fBexec\fR to control the
+flow of input and output among the subprocess(es).
+Such arguments will not be passed to the subprocess(es).  In forms
+such as
+.QW "\fB<\fR \fIfileName\fR" ,
+\fIfileName\fR may either be in a separate argument from
+.QW \fB<\fR
+or in the same argument with no intervening space (i.e.
+.QW \fB<\fIfileName\fR ).
+.TP 15
+\fB|\fR
+.
+Separates distinct commands in the pipeline.  The standard output
+of the preceding command will be piped into the standard input
+of the next command.
+.TP 15
+\fB|&\fR
+.
+Separates distinct commands in the pipeline.  Both standard output
+and standard error of the preceding command will be piped into
+the standard input of the next command.
+This form of redirection overrides forms such as 2> and >&.
+.TP 15
+\fB<\0\fIfileName\fR
+.
+The file named by \fIfileName\fR is opened and used as the standard
+input for the first command in the pipeline.
+.TP 15
+\fB<@\0\fIfileId\fR
+.
+\fIFileId\fR must be the identifier for an open file, such as the return
+value from a previous call to \fBopen\fR.
+It is used as the standard input for the first command in the pipeline.
+\fIFileId\fR must have been opened for reading.
+.TP 15
+\fB<<\0\fIvalue\fR
+.
+\fIValue\fR is passed to the first command as its standard input.
+.TP 15
+\fB>\0\fIfileName\fR
+.
+Standard output from the last command is redirected to the file named
+\fIfileName\fR, overwriting its previous contents.
+.TP 15
+\fB2>\0\fIfileName\fR
+.
+Standard error from all commands in the pipeline is redirected to the
+file named \fIfileName\fR, overwriting its previous contents.
+.TP 15
+\fB>&\0\fIfileName\fR
+.
+Both standard output from the last command and standard error from all
+commands are redirected to the file named \fIfileName\fR, overwriting
+its previous contents.
+.TP 15
+\fB>>\0\fIfileName\fR
+.
+Standard output from the last command is
+redirected to the file named \fIfileName\fR, appending to it rather
+than overwriting it.
+.TP 15
+\fB2>>\0\fIfileName\fR
+.
+Standard error from all commands in the pipeline is
+redirected to the file named \fIfileName\fR, appending to it rather
+than overwriting it.
+.TP 15
+\fB>>&\0\fIfileName\fR
+.
+Both standard output from the last command and standard error from
+all commands are redirected to the file named \fIfileName\fR,
+appending to it rather than overwriting it.
+.TP 15
+\fB>@\0\fIfileId\fR
+.
+\fIFileId\fR must be the identifier for an open file, such as the return
+value from a previous call to \fBopen\fR.
+Standard output from the last command is redirected to \fIfileId\fR's
+file, which must have been opened for writing.
+.TP 15
+\fB2>@\0\fIfileId\fR
+.
+\fIFileId\fR must be the identifier for an open file, such as the return
+value from a previous call to \fBopen\fR.
+Standard error from all commands in the pipeline is
+redirected to \fIfileId\fR's file.
+The file must have been opened for writing.
+.TP 15
+\fB2>@1\0\fR
+.
+Standard error from all commands in the pipeline is redirected to the
+command result.  This operator is only valid at the end of the command
+pipeline.
+.TP 15
+\fB>&@\0\fIfileId\fR
+.
+\fIFileId\fR must be the identifier for an open file, such as the return
+value from a previous call to \fBopen\fR.
+Both standard output from the last command and standard error from
+all commands are redirected to \fIfileId\fR's file.
+The file must have been opened for writing.
+.PP
+If standard output has not been redirected then the \fBexec\fR
+command returns the standard output from the last command
+in the pipeline, unless
+.QW 2>@1
+was specified, in which case standard error is included as well.
+If any of the commands in the pipeline exit abnormally or
+are killed or suspended, then \fBexec\fR will return an error
+and the error message will include the pipeline's output followed by
+error messages describing the abnormal terminations; the
+\fB\-errorcode\fR return option will contain additional information
+about the last abnormal termination encountered.
+If any of the commands writes to its standard error file and that
+standard error is not redirected
+and \fB\-ignorestderr\fR is not specified,
+then \fBexec\fR will return an error;  the error message
+will include the pipeline's standard output, followed by messages
+about abnormal terminations (if any), followed by the standard error
+output.
+.PP
+If the last character of the result or error message
+is a newline then that character is normally deleted
+from the result or error message.
+This is consistent with other Tcl return values, which do not
+normally end with newlines.
+However, if \fB\-keepnewline\fR is specified then the trailing
+newline is retained.
+.PP
+If standard input is not redirected with
+.QW < ,
+.QW <<
+or
+.QW <@
+then the standard input for the first command in the
+pipeline is taken from the application's current standard input.
+.PP
+If the last \fIarg\fR is
+.QW &
+then the pipeline will be executed in background.
+In this case the \fBexec\fR command will return a list whose
+elements are the process identifiers for all of the subprocesses
+in the pipeline.
+The standard output from the last command in the pipeline will
+go to the application's standard output if it has not been
+redirected, and error output from all of
+the commands in the pipeline will go to the application's
+standard error file unless redirected.
+.PP
+The first word in each command is taken as the command name;
+tilde-substitution is performed on it, and if the result contains
+no slashes then the directories
+in the PATH environment variable are searched for
+an executable by the given name.
+If the name contains a slash then it must refer to an executable
+reachable from the current directory.
+No
+.QW glob
+expansion or other shell-like substitutions
+are performed on the arguments to commands.
+.SH "PORTABILITY ISSUES"
+.TP
+\fBWindows\fR (all versions)
+.
+Reading from or writing to a socket, using the
+.QW \fB@\0\fIfileId\fR
+notation, does not work.  When reading from a socket, a 16-bit DOS
+application will hang and a 32-bit application will return immediately with
+end-of-file.  When either type of application writes to a socket, the
+information is instead sent to the console, if one is present, or is
+discarded.
+.RS
+.PP
+The Tk console text widget does not provide real standard IO capabilities.
+Under Tk, when redirecting from standard input, all applications will see an
+immediate end-of-file; information redirected to standard output or standard
+error will be discarded.
+.PP
+Either forward or backward slashes are accepted as path separators for
+arguments to Tcl commands.  When executing an application, the path name
+specified for the application may also contain forward or backward slashes
+as path separators.  Bear in mind, however, that most Windows applications
+accept arguments with forward slashes only as option delimiters and
+backslashes only in paths.  Any arguments to an application that specify a
+path name with forward slashes will not automatically be converted to use
+the backslash character.  If an argument contains forward slashes as the
+path separator, it may or may not be recognized as a path name, depending on
+the program.
+.PP
+Additionally, when calling a 16-bit DOS or Windows 3.X application, all path
+names must use the short, cryptic, path format (e.g., using
+.QW applba~1.def
+instead of
+.QW applbakery.default ),
+which can be obtained with the
+.QW "\fBfile attributes\fI fileName \fB\-shortname\fR"
+command.
+.PP
+Two or more forward or backward slashes in a row in a path refer to a
+network path.  For example, a simple concatenation of the root directory
+\fBc:/\fR with a subdirectory \fB/windows/system\fR will yield
+\fBc://windows/system\fR (two slashes together), which refers to the mount
+point called \fBsystem\fR on the machine called \fBwindows\fR (and the
+\fBc:/\fR is ignored), and is not equivalent to \fBc:/windows/system\fR,
+which describes a directory on the current computer.  The \fBfile join\fR
+command should be used to concatenate path components.
+.PP
+Note that there are two general types of Win32 console applications:
+.RS
+.IP [1]
+CLI \(em CommandLine Interface, simple stdio exchange. \fBnetstat.exe\fR for
+example.
+.IP [2]
+TUI \(em Textmode User Interface, any application that accesses the console
+API for doing such things as cursor movement, setting text color, detecting
+key presses and mouse movement, etc.  An example would be \fBtelnet.exe\fR
+from Windows 2000.  These types of applications are not common in a windows
+environment, but do exist.
+.RE
+.PP
+\fBexec\fR will not work well with TUI applications when a console is not
+present, as is done when launching applications under wish.  It is desirable
+to have console applications hidden and detached.  This is a designed-in
+limitation as \fBexec\fR wants to communicate over pipes.  The Expect
+extension addresses this issue when communicating with a TUI application.
+.PP
+When attempting to execute an application, \fBexec\fR first searches for
+the name as it was specified.  Then, in order,
+\fB.com\fR, \fB.exe\fR, \fB.bat\fR and \fB.cmd\fR
+are appended to the end of the specified name and it searches
+for the longer name.  If a directory name was not specified as part of the
+application name, the following directories are automatically searched in
+order when attempting to locate the application:
+.IP \(bu 3
+The directory from which the Tcl executable was loaded.
+.IP \(bu 3
+The current directory.
+.IP \(bu 3
+The Windows NT 32-bit system directory.
+.IP \(bu 3
+The Windows NT 16-bit system directory.
+.IP \(bu 3
+The Windows NT home directory.
+.IP \(bu 3
+The directories listed in the path.
+.PP
+In order to execute shell built-in commands like \fBdir\fR and \fBcopy\fR,
+the caller must prepend the desired command with
+.QW "\fBcmd.exe /c\0\fR"
+because built-in commands are not implemented using executables.
+.RE
+.TP
+\fBUnix\fR (including Mac OS X)
+.
+The \fBexec\fR command is fully functional and works as described.
+.SH "UNIX EXAMPLES"
+.PP
+Here are some examples of the use of the \fBexec\fR command on Unix.
+To execute a simple program and get its result:
+.PP
+.CS
+\fBexec\fR uname -a
+.CE
+.SS "WORKING WITH NON-ZERO RESULTS"
+.PP
+To execute a program that can return a non-zero result, you should
+wrap the call to \fBexec\fR in \fBcatch\fR and check the contents
+of the \fB\-errorcode\fR return option if you have an error:
+.PP
+.CS
+set status 0
+if {[catch {\fBexec\fR grep foo bar.txt} results options]} {
+    set details [dict get $options -errorcode]
+    if {[lindex $details 0] eq "CHILDSTATUS"} {
+        set status [lindex $details 2]
+    } else {
+        # Some other error; regenerate it to let caller handle
+        return -options $options -level 0 $results
+    }
+}
+.CE
+.VS 8.6
+.PP
+This is more easily written using the \fBtry\fR command, as that makes
+it simpler to trap specific types of errors. This is
+done using code like this:
+.PP
+.CS
+try {
+    set results [\fBexec\fR grep foo bar.txt]
+    set status 0
+} trap CHILDSTATUS {results options} {
+    set status [lindex [dict get $options -errorcode] 2]
+}
+.CE
+.VE 8.6
+.SS "WORKING WITH QUOTED ARGUMENTS"
+.PP
+When translating a command from a Unix shell invocation, care should
+be taken over the fact that single quote characters have no special
+significance to Tcl.  Thus:
+.PP
+.CS
+awk '{sum += $1} END {print sum}' numbers.list
+.CE
+.PP
+would be translated into something like:
+.PP
+.CS
+\fBexec\fR awk {{sum += $1} END {print sum}} numbers.list
+.CE
+.SS "WORKING WITH GLOBBING"
+.PP
+If you are converting invocations involving shell globbing, you should
+remember that Tcl does not handle globbing or expand things into
+multiple arguments by default.  Instead you should write things like
+this:
+.PP
+.CS
+\fBexec\fR ls -l {*}[glob *.tcl]
+.CE
+.SS "WORKING WITH USER-SUPPLIED SHELL SCRIPT FRAGMENTS"
+.PP
+One useful technique can be to expose to users of a script the ability
+to specify a fragment of shell script to execute that will have some
+data passed in on standard input that was produced by the Tcl program.
+This is a common technique for using the \fIlpr\fR program for
+printing. By far the simplest way of doing this is to pass the user's
+script to the user's shell for processing, as this avoids a lot of
+complexity with parsing other languages.
+.PP
+.CS
+set lprScript [\fIget from user...\fR]
+set postscriptData [\fIgenerate somehow...\fR]
+
+\fBexec\fR $env(SHELL) -c $lprScript << $postscriptData
+.CE
+.SH "WINDOWS EXAMPLES"
+.PP
+Here are some examples of the use of the \fBexec\fR command on Windows.
+To start an instance of \fInotepad\fR editing a file without waiting
+for the user to finish editing the file:
+.PP
+.CS
+\fBexec\fR notepad myfile.txt &
+.CE
+.PP
+To print a text file using \fInotepad\fR:
+.PP
+.CS
+\fBexec\fR notepad /p myfile.txt
+.CE
+.SS "WORKING WITH CONSOLE PROGRAMS"
+.PP
+If a program calls other programs, such as is common with compilers,
+then you may need to resort to batch files to hide the console windows
+that sometimes pop up:
+.PP
+.CS
+\fBexec\fR cmp.bat somefile.c -o somefile
+.CE
+.PP
+With the file \fIcmp.bat\fR looking something like:
+.PP
+.CS
+@gcc %1 %2 %3 %4 %5 %6 %7 %8 %9
+.CE
+.SS "WORKING WITH COMMAND BUILT-INS"
+.PP
+Sometimes you need to be careful, as different programs may have the
+same name and be in the path. It can then happen that typing a command
+at the DOS prompt finds \fIa different program\fR than the same
+command run via \fBexec\fR. This is because of the (documented)
+differences in behaviour between \fBexec\fR and DOS batch files.
+.PP
+When in doubt, use the command \fBauto_execok\fR: it will return the
+complete path to the program as seen by the \fBexec\fR command.  This
+applies especially when you want to run
+.QW internal
+commands like
+\fIdir\fR from a Tcl script (if you just want to list filenames, use
+the \fBglob\fR command.)  To do that, use this:
+.PP
+.CS
+\fBexec\fR {*}[auto_execok dir] *.tcl
+.CE
+.SS "WORKING WITH NATIVE FILENAMES"
+.PP
+Many programs on Windows require filename arguments to be passed in with
+backslashes as pathname separators. This is done with the help of the
+\fBfile nativename\fR command. For example, to make a directory (on NTFS)
+encrypted so that only the current user can access it requires use of
+the \fICIPHER\fR command, like this:
+.PP
+.CS
+set secureDir "~/Desktop/Secure Directory"
+file mkdir $secureDir
+\fBexec\fR CIPHER /e /s:[file nativename $secureDir]
+.CE
+.SH "SEE ALSO"
+error(n), file(n), open(n)
+.SH KEYWORDS
+execute, pipeline, redirection, subprocess
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/doc/exit.n b/doc/exit.n
new file mode 100644
index 0000000..9b4ad20
--- /dev/null
+++ b/doc/exit.n
@@ -0,0 +1,51 @@
+'\"
+'\" Copyright (c) 1993 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\" 
+.TH exit n "" Tcl "Tcl Built-In Commands"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+exit \- End the application
+.SH SYNOPSIS
+\fBexit \fR?\fIreturnCode\fR?
+.BE
+
+.SH DESCRIPTION
+.PP
+Terminate the process, returning \fIreturnCode\fR to the
+system as the exit status.
+If \fIreturnCode\fR is not specified then it defaults
+to 0.
+.SH EXAMPLE
+.PP
+Since non-zero exit codes are usually interpreted as error cases by
+the calling process, the \fBexit\fR command is an important part of
+signaling that something fatal has gone wrong. This code fragment is
+useful in scripts to act as a general problem trap:
+.PP
+.CS
+proc main {} {
+    # ... put the real main code in here ...
+}
+
+if {[catch {main} msg options]} {
+    puts stderr "unexpected script error: $msg"
+    if {[info exists env(DEBUG)]} {
+        puts stderr "---- BEGIN TRACE ----"
+        puts stderr [dict get $options -errorinfo]
+        puts stderr "---- END TRACE ----"
+    }
+
+    # Reserve code 1 for "expected" error exits...
+    \fBexit\fR 2
+}
+.CE
+.SH "SEE ALSO"
+exec(n)
+.SH KEYWORDS
+abort, exit, process
diff --git a/doc/expr.n b/doc/expr.n
new file mode 100644
index 0000000..b76b6a2
--- /dev/null
+++ b/doc/expr.n
@@ -0,0 +1,475 @@
+'\"
+'\" Copyright (c) 1993 The Regents of the University of California.
+'\" Copyright (c) 1994-2000 Sun Microsystems, Inc.
+'\" Copyright (c) 2005 by Kevin B. Kenny <kennykb@acm.org>. All rights reserved
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH expr n 8.5 Tcl "Tcl Built-In Commands"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+expr \- Evaluate an expression
+.SH SYNOPSIS
+\fBexpr \fIarg \fR?\fIarg arg ...\fR?
+.BE
+.SH DESCRIPTION
+.PP
+Concatenates \fIarg\fRs (adding separator spaces between them),
+evaluates the result as a Tcl expression, and returns the value.
+The operators permitted in Tcl expressions include a subset of
+the operators permitted in C expressions.  For those operators
+common to both Tcl and C, Tcl applies the same meaning and precedence
+as the corresponding C operators.
+Expressions almost always yield numeric results
+(integer or floating-point values).
+For example, the expression
+.PP
+.CS
+\fBexpr\fR 8.2 + 6
+.CE
+.PP
+evaluates to 14.2.
+Tcl expressions differ from C expressions in the way that
+operands are specified.  Also, Tcl expressions support
+non-numeric operands and string comparisons, as well as some
+additional operators not found in C.
+.SS OPERANDS
+.PP
+A Tcl expression consists of a combination of operands, operators,
+parentheses and commas.
+White space may be used between the operands and operators and
+parentheses (or commas); it is ignored by the expression's instructions.
+Where possible, operands are interpreted as integer values.
+Integer values may be specified in decimal (the normal case), in binary
+(if the first two characters of the operand are \fB0b\fR), in octal
+(if the first two characters of the operand are \fB0o\fR), or in hexadecimal
+(if the first two characters of the operand are \fB0x\fR).  For
+compatibility with older Tcl releases, an octal integer value is also
+indicated simply when the first character of the operand is \fB0\fR,
+whether or not the second character is also \fBo\fR.
+If an operand does not have one of the integer formats given
+above, then it is treated as a floating-point number if that is
+possible.  Floating-point numbers may be specified in any of several
+common formats making use of the decimal digits, the decimal point \fB.\fR,
+the characters \fBe\fR or \fBE\fR indicating scientific notation, and
+the sign characters \fB+\fR or \fB\-\fR.  For example, all of the
+following are valid floating-point numbers:  2.1, 3., 6e4, 7.91e+16.
+Also recognized as floating point values are the strings \fBInf\fR
+and \fBNaN\fR making use of any case for each character.
+If no numeric interpretation is possible (note that all literal
+operands that are not numeric or boolean must be quoted with either
+braces or with double quotes), then an operand is left as a string
+(and only a limited set of operators may be applied to it).
+.PP
+Operands may be specified in any of the following ways:
+.IP [1]
+As a numeric value, either integer or floating-point.
+.IP [2]
+As a boolean value, using any form understood by \fBstring is\fR
+\fBboolean\fR.
+.IP [3]
+As a Tcl variable, using standard \fB$\fR notation.
+The variable's value will be used as the operand.
+.IP [4]
+As a string enclosed in double-quotes.
+The expression parser will perform backslash, variable, and
+command substitutions on the information between the quotes,
+and use the resulting value as the operand
+.IP [5]
+As a string enclosed in braces.
+The characters between the open brace and matching close brace
+will be used as the operand without any substitutions.
+.IP [6]
+As a Tcl command enclosed in brackets.
+The command will be executed and its result will be used as
+the operand.
+.IP [7]
+As a mathematical function whose arguments have any of the above
+forms for operands, such as \fBsin($x)\fR.  See \fBMATH FUNCTIONS\fR below for
+a discussion of how mathematical functions are handled.
+.PP
+Where the above substitutions occur (e.g. inside quoted strings), they
+are performed by the expression's instructions.
+However, the command parser may already have performed one round of
+substitution before the expression processor was called.
+As discussed below, it is usually best to enclose expressions
+in braces to prevent the command parser from performing substitutions
+on the contents.
+.PP
+For some examples of simple expressions, suppose the variable
+\fBa\fR has the value 3 and
+the variable \fBb\fR has the value 6.
+Then the command on the left side of each of the lines below
+will produce the value on the right side of the line:
+.PP
+.CS
+.ta 6c
+\fBexpr\fR 3.1 + $a	\fI6.1\fR
+\fBexpr\fR 2 + "$a.$b"	\fI5.6\fR
+\fBexpr\fR 4*[llength "6 2"]	\fI8\fR
+\fBexpr\fR {{word one} < "word $a"}	\fI0\fR
+.CE
+.SS OPERATORS
+.PP
+The valid operators (most of which are also available as commands in
+the \fBtcl::mathop\fR namespace; see the \fBmathop\fR(n) manual page
+for details) are listed below, grouped in decreasing order of precedence:
+.TP 20
+\fB\-\0\0+\0\0~\0\0!\fR
+.
+Unary minus, unary plus, bit-wise NOT, logical NOT.  None of these operators
+may be applied to string operands, and bit-wise NOT may be
+applied only to integers.
+.TP 20
+\fB**\fR
+.
+Exponentiation.  Valid for any numeric operands.
+.TP 20
+\fB*\0\0/\0\0%\fR
+.
+Multiply, divide, remainder.  None of these operators may be
+applied to string operands, and remainder may be applied only
+to integers.
+The remainder will always have the same sign as the divisor and
+an absolute value smaller than the absolute value of the divisor.
+.RS
+.PP
+When applied to integers, the division and remainder operators can be
+considered to partition the number line into a sequence of equal-sized
+adjacent non-overlapping pieces where each piece is the size of the divisor;
+the division result identifies which piece the divisor lay within, and the
+remainder result identifies where within that piece the divisor lay. A
+consequence of this is that the result of
+.QW "-57 \fB/\fR 10"
+is always -6, and the result of
+.QW "-57 \fB%\fR 10"
+is always 3.
+.RE
+.TP 20
+\fB+\0\0\-\fR
+.
+Add and subtract.  Valid for any numeric operands.
+.TP 20
+\fB<<\0\0>>\fR
+.
+Left and right shift.  Valid for integer operands only.
+A right shift always propagates the sign bit.
+.TP 20
+\fB<\0\0>\0\0<=\0\0>=\fR
+.
+Boolean less, greater, less than or equal, and greater than or equal.
+Each operator produces 1 if the condition is true, 0 otherwise.
+These operators may be applied to strings as well as numeric operands,
+in which case string comparison is used.
+.TP 20
+\fB==\0\0!=\fR
+.
+Boolean equal and not equal.  Each operator produces a zero/one result.
+Valid for all operand types.
+.TP 20
+\fBeq\0\0ne\fR
+.
+Boolean string equal and string not equal.  Each operator produces a
+zero/one result.  The operand types are interpreted only as strings.
+.TP 20
+\fBin\0\0ni\fR
+.
+List containment and negated list containment.  Each operator produces
+a zero/one result and treats its first argument as a string and its
+second argument as a Tcl list.  The \fBin\fR operator indicates
+whether the first argument is a member of the second argument list;
+the \fBni\fR operator inverts the sense of the result.
+.TP 20
+\fB&\fR
+.
+Bit-wise AND.  Valid for integer operands only.
+.TP 20
+\fB^\fR
+.
+Bit-wise exclusive OR.  Valid for integer operands only.
+.TP 20
+\fB|\fR
+.
+Bit-wise OR.  Valid for integer operands only.
+.TP 20
+\fB&&\fR
+.
+Logical AND.  Produces a 1 result if both operands are non-zero,
+0 otherwise.
+Valid for boolean and numeric (integers or floating-point) operands only.
+.TP 20
+\fB||\fR
+.
+Logical OR.  Produces a 0 result if both operands are zero, 1 otherwise.
+Valid for boolean and numeric (integers or floating-point) operands only.
+.TP 20
+\fIx\fB?\fIy\fB:\fIz\fR
+.
+If-then-else, as in C.  If \fIx\fR
+evaluates to non-zero, then the result is the value of \fIy\fR.
+Otherwise the result is the value of \fIz\fR.
+The \fIx\fR operand must have a boolean or numeric value.
+.PP
+See the C manual for more details on the results
+produced by each operator.
+The exponentiation operator promotes types like the multiply and
+divide operators, and produces a result that is the same as the output
+of the \fBpow\fR function (after any type conversions.)
+All of the binary operators but exponentiation group left-to-right
+within the same precedence level; exponentiation groups right-to-left.  For example, the command
+.PP
+.CS
+\fBexpr\fR {4*2 < 7}
+.CE
+.PP
+returns 0, while
+.PP
+.CS
+\fBexpr\fR {2**3**2}
+.CE
+.PP
+returns 512.
+.PP
+The \fB&&\fR, \fB||\fR, and \fB?:\fR operators have
+.QW "lazy evaluation" ,
+just as in C, which means that operands are not evaluated if they are
+not needed to determine the outcome.  For example, in the command
+.PP
+.CS
+\fBexpr\fR {$v ? [a] : [b]}
+.CE
+.PP
+only one of
+.QW \fB[a]\fR
+or
+.QW \fB[b]\fR
+will actually be evaluated,
+depending on the value of \fB$v\fR.  Note, however, that this is
+only true if the entire expression is enclosed in braces;  otherwise
+the Tcl parser will evaluate both
+.QW \fB[a]\fR
+and
+.QW \fB[b]\fR
+before invoking the \fBexpr\fR command.
+.SS "MATH FUNCTIONS"
+.PP
+When the expression parser encounters a mathematical function
+such as \fBsin($x)\fR, it replaces it with a call to an ordinary
+Tcl function in the \fBtcl::mathfunc\fR namespace.  The processing
+of an expression such as:
+.PP
+.CS
+\fBexpr\fR {sin($x+$y)}
+.CE
+.PP
+is the same in every way as the processing of:
+.PP
+.CS
+\fBexpr\fR {[tcl::mathfunc::sin [\fBexpr\fR {$x+$y}]]}
+.CE
+.PP
+which in turn is the same as the processing of:
+.PP
+.CS
+tcl::mathfunc::sin [\fBexpr\fR {$x+$y}]
+.CE
+.PP
+The executor will search for \fBtcl::mathfunc::sin\fR using the usual
+rules for resolving functions in namespaces. Either
+\fB::tcl::mathfunc::sin\fR or \fB[namespace
+current]::tcl::mathfunc::sin\fR will satisfy the request, and others
+may as well (depending on the current \fBnamespace path\fR setting).
+.PP
+Some mathematical functions have several arguments, separated by commas like in C. Thus:
+.PP
+.CS
+\fBexpr\fR {hypot($x,$y)}
+.CE
+.PP
+ends up as
+.PP
+.CS
+tcl::mathfunc::hypot $x $y
+.CE
+.PP
+See the \fBmathfunc\fR(n) manual page for the math functions that are
+available by default.
+.SS "TYPES, OVERFLOW, AND PRECISION"
+.PP
+All internal computations involving integers are done calling on the
+LibTomMath multiple precision integer library as required so that all
+integer calculations are performed exactly.  Note that in Tcl releases
+prior to 8.5, integer calculations were performed with one of the C types
+\fIlong int\fR or \fITcl_WideInt\fR, causing implicit range truncation
+in those calculations where values overflowed the range of those types.
+Any code that relied on these implicit truncations will need to explicitly
+add \fBint()\fR or \fBwide()\fR function calls to expressions at the points
+where such truncation is required to take place.
+.PP
+All internal computations involving floating-point are
+done with the C type \fIdouble\fR.
+When converting a string to floating-point, exponent overflow is
+detected and results in the \fIdouble\fR value of \fBInf\fR or
+\fB\-Inf\fR as appropriate.  Floating-point overflow and underflow
+are detected to the degree supported by the hardware, which is generally
+pretty reliable.
+.PP
+Conversion among internal representations for integer, floating-point,
+and string operands is done automatically as needed.
+For arithmetic computations, integers are used until some
+floating-point number is introduced, after which floating-point is used.
+For example,
+.PP
+.CS
+\fBexpr\fR {5 / 4}
+.CE
+.PP
+returns 1, while
+.PP
+.CS
+\fBexpr\fR {5 / 4.0}
+\fBexpr\fR {5 / ( [string length "abcd"] + 0.0 )}
+.CE
+.PP
+both return 1.25.
+Floating-point values are always returned with a
+.QW \fB.\fR
+or an
+.QW \fBe\fR
+so that they will not look like integer values.  For example,
+.PP
+.CS
+\fBexpr\fR {20.0/5.0}
+.CE
+.PP
+returns \fB4.0\fR, not \fB4\fR.
+.SS "STRING OPERATIONS"
+.PP
+String values may be used as operands of the comparison operators,
+although the expression evaluator tries to do comparisons as integer
+or floating-point when it can,
+i.e., when all arguments to the operator allow numeric interpretations,
+except in the case of the \fBeq\fR and \fBne\fR operators.
+If one of the operands of a comparison is a string and the other
+has a numeric value, a canonical string representation of the numeric
+operand value is generated to compare with the string operand.
+Canonical string representation for integer values is a decimal string
+format.  Canonical string representation for floating-point values
+is that produced by the \fB%g\fR format specifier of Tcl's
+\fBformat\fR command.  For example, the commands
+.PP
+.CS
+\fBexpr\fR {"0x03" > "2"}
+\fBexpr\fR {"0y" > "0x12"}
+.CE
+.PP
+both return 1.  The first comparison is done using integer
+comparison, and the second is done using string comparison.
+Because of Tcl's tendency to treat values as numbers whenever
+possible, it is not generally a good idea to use operators like \fB==\fR
+when you really want string comparison and the values of the
+operands could be arbitrary;  it is better in these cases to use
+the \fBeq\fR or \fBne\fR operators, or the \fBstring\fR command instead.
+.SH "PERFORMANCE CONSIDERATIONS"
+.PP
+Enclose expressions in braces for the best speed and the smallest
+storage requirements.
+This allows the Tcl bytecode compiler to generate the best code.
+.PP
+As mentioned above, expressions are substituted twice:
+once by the Tcl parser and once by the \fBexpr\fR command.
+For example, the commands
+.PP
+.CS
+set a 3
+set b {$a + 2}
+\fBexpr\fR $b*4
+.CE
+.PP
+return 11, not a multiple of 4.
+This is because the Tcl parser will first substitute \fB$a + 2\fR for
+the variable \fBb\fR,
+then the \fBexpr\fR command will evaluate the expression \fB$a + 2*4\fR.
+.PP
+Most expressions do not require a second round of substitutions.
+Either they are enclosed in braces or, if not,
+their variable and command substitutions yield numbers or strings
+that do not themselves require substitutions.
+However, because a few unbraced expressions
+need two rounds of substitutions,
+the bytecode compiler must emit
+additional instructions to handle this situation.
+The most expensive code is required for
+unbraced expressions that contain command substitutions.
+These expressions must be implemented by generating new code
+each time the expression is executed.
+When the expression is unbraced to allow the substitution of a function or
+operator, consider using the commands documented in the \fBmathfunc\fR(n) or
+\fBmathop\fR(n) manual pages directly instead.
+.SH EXAMPLES
+.PP
+Define a procedure that computes an
+.QW interesting
+mathematical function:
+.PP
+.CS
+proc tcl::mathfunc::calc {x y} {
+    \fBexpr\fR { ($x**2 - $y**2) / exp($x**2 + $y**2) }
+}
+.CE
+.PP
+Convert polar coordinates into cartesian coordinates:
+.PP
+.CS
+# convert from ($radius,$angle)
+set x [\fBexpr\fR { $radius * cos($angle) }]
+set y [\fBexpr\fR { $radius * sin($angle) }]
+.CE
+.PP
+Convert cartesian coordinates into polar coordinates:
+.PP
+.CS
+# convert from ($x,$y)
+set radius [\fBexpr\fR { hypot($y, $x) }]
+set angle  [\fBexpr\fR { atan2($y, $x) }]
+.CE
+.PP
+Print a message describing the relationship of two string values to
+each other:
+.PP
+.CS
+puts "a and b are [\fBexpr\fR {$a eq $b ? {equal} : {different}}]"
+.CE
+.PP
+Set a variable to whether an environment variable is both defined at
+all and also set to a true boolean value:
+.PP
+.CS
+set isTrue [\fBexpr\fR {
+    [info exists ::env(SOME_ENV_VAR)] &&
+    [string is true -strict $::env(SOME_ENV_VAR)]
+}]
+.CE
+.PP
+Generate a random integer in the range 0..99 inclusive:
+.PP
+.CS
+set randNum [\fBexpr\fR { int(100 * rand()) }]
+.CE
+.SH "SEE ALSO"
+array(n), for(n), if(n), mathfunc(n), mathop(n), namespace(n), proc(n),
+string(n), Tcl(n), while(n)
+.SH KEYWORDS
+arithmetic, boolean, compare, expression, fuzzy comparison
+.SH COPYRIGHT
+.nf
+Copyright (c) 1993 The Regents of the University of California.
+Copyright (c) 1994-2000 Sun Microsystems Incorporated.
+Copyright (c) 2005 by Kevin B. Kenny <kennykb@acm.org>. All rights reserved.
+.fi
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/doc/fblocked.n b/doc/fblocked.n
new file mode 100644
index 0000000..2841aee
--- /dev/null
+++ b/doc/fblocked.n
@@ -0,0 +1,67 @@
+'\" 
+'\" Copyright (c) 1996 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH fblocked n 7.5 Tcl "Tcl Built-In Commands"
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+fblocked \- Test whether the last input operation exhausted all available input
+.SH SYNOPSIS
+\fBfblocked \fIchannelId\fR
+.BE
+
+.SH DESCRIPTION
+.PP
+The \fBfblocked\fR command returns 1 if the most recent input operation
+on \fIchannelId\fR returned less information than requested because all
+available input was exhausted.
+For example, if \fBgets\fR is invoked when there are only three
+characters available for input and no end-of-line sequence, \fBgets\fR
+returns an empty string and a subsequent call to \fBfblocked\fR will
+return 1.
+.PP
+\fIChannelId\fR must be an identifier for an open channel such as a
+Tcl standard channel (\fBstdin\fR, \fBstdout\fR, or \fBstderr\fR),
+the return value from an invocation of \fBopen\fR or \fBsocket\fR, or
+the result of a channel creation command provided by a Tcl extension.
+.SH EXAMPLE
+The \fBfblocked\fR command is particularly useful when writing network
+servers, as it allows you to write your code in a line-by-line style
+without preventing the servicing of other connections.  This can be
+seen in this simple echo-service:
+.PP
+.CS
+# This is called whenever a new client connects to the server
+proc connect {chan host port} {
+    set clientName [format <%s:%d> $host $port]
+    puts "connection from $clientName"
+    fconfigure $chan -blocking 0 -buffering line
+    fileevent $chan readable [list echoLine $chan $clientName]
+}
+
+# This is called whenever either at least one byte of input
+# data is available, or the channel was closed by the client.
+proc echoLine {chan clientName} {
+    gets $chan line
+    if {[eof $chan]} {
+        puts "finishing connection from $clientName"
+        close $chan
+    } elseif {![\fBfblocked\fR $chan]} {
+        # Didn't block waiting for end-of-line
+        puts "$clientName - $line"
+        puts $chan $line
+    }
+}
+
+# Create the server socket and enter the event-loop to wait
+# for incoming connections...
+socket -server connect 12345
+vwait forever
+.CE
+.SH "SEE ALSO"
+gets(n), open(n), read(n), socket(n), Tcl_StandardChannels(3)
+.SH KEYWORDS
+blocking, nonblocking
diff --git a/doc/fconfigure.n b/doc/fconfigure.n
new file mode 100644
index 0000000..8da76c6
--- /dev/null
+++ b/doc/fconfigure.n
@@ -0,0 +1,289 @@
+'\"
+'\" Copyright (c) 1995-1996 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH fconfigure n 8.3 Tcl "Tcl Built-In Commands"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+fconfigure \- Set and get options on a channel
+.SH SYNOPSIS
+.nf
+\fBfconfigure \fIchannelId\fR
+\fBfconfigure \fIchannelId\fR \fIname\fR
+\fBfconfigure \fIchannelId\fR \fIname value \fR?\fIname value ...\fR?
+.fi
+.BE
+.SH DESCRIPTION
+.PP
+The \fBfconfigure\fR command sets and retrieves options for channels.
+.PP
+\fIChannelId\fR identifies the channel for which to set or query an
+option and must refer to an open channel such as a Tcl standard
+channel (\fBstdin\fR, \fBstdout\fR, or \fBstderr\fR), the return
+value from an invocation of \fBopen\fR or \fBsocket\fR, or the result
+of a channel creation command provided by a Tcl extension.
+.PP
+If no \fIname\fR or \fIvalue\fR arguments are supplied, the command
+returns a list containing alternating option names and values for the channel.
+If \fIname\fR is supplied but no \fIvalue\fR then the command returns
+the current value of the given option.
+If one or more pairs of \fIname\fR and \fIvalue\fR are supplied, the
+command sets each of the named options to the corresponding \fIvalue\fR;
+in this case the return value is an empty string.
+.PP
+The options described below are supported for all channels. In addition,
+each channel type may add options that only it supports. See the manual
+entry for the command that creates each type of channels for the options
+that that specific type of channel supports. For example, see the manual
+entry for the \fBsocket\fR command for additional options for sockets, and
+the \fBopen\fR command for additional options for serial devices.
+.TP
+\fB\-blocking\fR \fIboolean\fR
+The \fB\-blocking\fR option determines whether I/O operations on the
+channel can cause the process to block indefinitely.
+The value of the option must be a proper boolean value.
+Channels are normally in blocking mode;  if a channel is placed into
+nonblocking mode it will affect the operation of the \fBgets\fR,
+\fBread\fR, \fBputs\fR, \fBflush\fR, and \fBclose\fR commands by
+allowing them to operate asynchronously;
+see the documentation for those commands for details.
+For nonblocking mode to work correctly, the application must be
+using the Tcl event loop (e.g. by calling \fBTcl_DoOneEvent\fR or
+invoking the \fBvwait\fR command).
+.TP
+\fB\-buffering\fR \fInewValue\fR
+.
+If \fInewValue\fR is \fBfull\fR then the I/O system will buffer output
+until its internal buffer is full or until the \fBflush\fR command is
+invoked. If \fInewValue\fR is \fBline\fR, then the I/O system will
+automatically flush output for the channel whenever a newline character
+is output. If \fInewValue\fR is \fBnone\fR, the I/O system will flush
+automatically after every output operation.  The default is for
+\fB\-buffering\fR to be set to \fBfull\fR except for channels that
+connect to terminal-like devices; for these channels the initial setting
+is \fBline\fR.  Additionally, \fBstdin\fR and \fBstdout\fR are
+initially set to \fBline\fR, and \fBstderr\fR is set to \fBnone\fR.
+.TP
+\fB\-buffersize\fR \fInewSize\fR
+.
+\fINewvalue\fR must be an integer; its value is used to set the size of
+buffers, in bytes, subsequently allocated for this channel to store input
+or output. \fINewvalue\fR must be between one and one million, allowing
+buffers of one to one million bytes in size.
+.TP
+\fB\-encoding\fR \fIname\fR
+.
+This option is used to specify the encoding of the channel, so that the data
+can be converted to and from Unicode for use in Tcl.  For instance, in
+order for Tcl to read characters from a Japanese file in \fBshiftjis\fR
+and properly process and display the contents, the encoding would be set
+to \fBshiftjis\fR.  Thereafter, when reading from the channel, the bytes in
+the Japanese file would be converted to Unicode as they are read.
+Writing is also supported \- as Tcl strings are written to the channel they
+will automatically be converted to the specified encoding on output.
+.RS
+.PP
+If a file contains pure binary data (for instance, a JPEG image), the
+encoding for the channel should be configured to be \fBbinary\fR.  Tcl
+will then assign no interpretation to the data in the file and simply read or
+write raw bytes.  The Tcl \fBbinary\fR command can be used to manipulate this
+byte-oriented data.  It is usually better to set the
+\fB\-translation\fR option to \fBbinary\fR when you want to transfer
+binary data, as this turns off the other automatic interpretations of
+the bytes in the stream as well.
+.PP
+The default encoding for newly opened channels is the same platform- and
+locale-dependent system encoding used for interfacing with the operating
+system, as returned by \fBencoding system\fR.
+.RE
+.TP
+\fB\-eofchar\fR \fIchar\fR
+.TP
+\fB\-eofchar\fR \fB{\fIinChar outChar\fB}\fR
+.
+This option supports DOS file systems that use Control-z (\ex1a) as an
+end of file marker.  If \fIchar\fR is not an empty string, then this
+character signals end-of-file when it is encountered during input.  For
+output, the end-of-file character is output when the channel is closed.
+If \fIchar\fR is the empty string, then there is no special end of file
+character marker.  For read-write channels, a two-element list specifies
+the end of file marker for input and output, respectively.  As a
+convenience, when setting the end-of-file character for a read-write
+channel you can specify a single value that will apply to both reading
+and writing.  When querying the end-of-file character of a read-write
+channel, a two-element list will always be returned.  The default value
+for \fB\-eofchar\fR is the empty string in all cases except for files
+under Windows.  In that case the \fB\-eofchar\fR is Control-z (\ex1a) for
+reading and the empty string for writing.
+The acceptable range for \fB\-eofchar\fR values is \ex01 - \ex7f;
+attempting to set \fB\-eofchar\fR to a value outside of this range will
+generate an error.
+.TP
+\fB\-translation\fR \fImode\fR
+.TP
+\fB\-translation\fR \fB{\fIinMode outMode\fB}\fR
+.
+In Tcl scripts the end of a line is always represented using a single
+newline character (\en).  However, in actual files and devices the end of
+a line may be represented differently on different platforms, or even for
+different devices on the same platform.  For example, under UNIX newlines
+are used in files, whereas carriage-return-linefeed sequences are
+normally used in network connections.  On input (i.e., with \fBgets\fR
+and \fBread\fR) the Tcl I/O system automatically translates the external
+end-of-line representation into newline characters.  Upon output (i.e.,
+with \fBputs\fR), the I/O system translates newlines to the external
+end-of-line representation.  The default translation mode, \fBauto\fR,
+handles all the common cases automatically, but the \fB\-translation\fR
+option provides explicit control over the end of line translations.
+.RS
+.PP
+The value associated with \fB\-translation\fR is a single item for
+read-only and write-only channels.  The value is a two-element list for
+read-write channels; the read translation mode is the first element of
+the list, and the write translation mode is the second element.  As a
+convenience, when setting the translation mode for a read-write channel
+you can specify a single value that will apply to both reading and
+writing.  When querying the translation mode of a read-write channel, a
+two-element list will always be returned.  The following values are
+currently supported:
+.TP
+\fBauto\fR
+.
+As the input translation mode, \fBauto\fR treats any of newline
+(\fBlf\fR), carriage return (\fBcr\fR), or carriage return followed by a
+newline (\fBcrlf\fR) as the end of line representation.  The end of line
+representation can even change from line-to-line, and all cases are
+translated to a newline.  As the output translation mode, \fBauto\fR
+chooses a platform specific representation; for sockets on all platforms
+Tcl chooses \fBcrlf\fR, for all Unix flavors, it chooses \fBlf\fR, and
+for the various flavors of Windows it chooses \fBcrlf\fR.  The default
+setting for \fB\-translation\fR is \fBauto\fR for both input and output.
+.TP
+\fBbinary\fR
+.
+No end-of-line translations are performed.  This is nearly identical to
+\fBlf\fR mode, except that in addition \fBbinary\fR mode also sets the
+end-of-file character to the empty string (which disables it) and sets the
+encoding to \fBbinary\fR (which disables encoding filtering).  See the
+description of \fB\-eofchar\fR and \fB\-encoding\fR for more information.
+.RS
+.PP
+Internally, i.e. when it comes to the actual behaviour of the
+translator this value \fBis\fR identical to \fBlf\fR and is therefore
+reported as such when queried. Even if \fBbinary\fR was used to set
+the translation.
+.RE
+.TP
+\fBcr\fR
+.
+The end of a line in the underlying file or device is represented by a
+single carriage return character.  As the input translation mode,
+\fBcr\fR mode converts carriage returns to newline characters.  As the
+output translation mode, \fBcr\fR mode translates newline characters to
+carriage returns.
+.TP
+\fBcrlf\fR
+.
+The end of a line in the underlying file or device is represented by a
+carriage return character followed by a linefeed character.  As the input
+translation mode, \fBcrlf\fR mode converts carriage-return-linefeed
+sequences to newline characters.  As the output translation mode,
+\fBcrlf\fR mode translates newline characters to carriage-return-linefeed
+sequences.  This mode is typically used on Windows platforms and for
+network connections.
+.TP
+\fBlf\fR
+.
+The end of a line in the underlying file or device is represented by a
+single newline (linefeed) character.  In this mode no translations occur
+during either input or output.  This mode is typically used on UNIX
+platforms.
+.RE
+.PP
+.SH "STANDARD CHANNELS"
+.PP
+The Tcl standard channels (\fBstdin\fR, \fBstdout\fR, and \fBstderr\fR)
+can be configured through this command like every other channel opened
+by the Tcl library. Beyond the standard options described above they
+will also support any special option according to their current type.
+If, for example, a Tcl application is started by the \fBinet\fR
+super-server common on Unix system its Tcl standard channels will be
+sockets and thus support the socket options.
+.SH EXAMPLES
+.PP
+Instruct Tcl to always send output to \fBstdout\fR immediately,
+whether or not it is to a terminal:
+.PP
+.CS
+\fBfconfigure\fR stdout -buffering none
+.CE
+.PP
+Open a socket and read lines from it without ever blocking the
+processing of other events:
+.PP
+.CS
+set s [socket some.where.com 12345]
+\fBfconfigure\fR $s -blocking 0
+fileevent $s readable "readMe $s"
+proc readMe chan {
+    if {[gets $chan line] < 0} {
+        if {[eof $chan]} {
+            close $chan
+            return
+        }
+        # Could not read a complete line this time; Tcl's
+        # internal buffering will hold the partial line for us
+        # until some more data is available over the socket.
+    } else {
+        puts stdout $line
+    }
+}
+.CE
+.PP
+Read a PPM-format image from a file:
+.PP
+.CS
+# Open the file and put it into Unix ASCII mode
+set f [open teapot.ppm]
+\fBfconfigure\fR $f \-encoding ascii \-translation lf
+
+# Get the header
+if {[gets $f] ne "P6"} {
+    error "not a raw\-bits PPM"
+}
+
+# Read lines until we have got non-comment lines
+# that supply us with three decimal values.
+set words {}
+while {[llength $words] < 3} {
+    gets $f line
+    if {[string match "#*" $line]} continue
+    lappend words {*}[join [scan $line %d%d%d]]
+}
+
+# Those words supply the size of the image and its
+# overall depth per channel. Assign to variables.
+lassign $words xSize ySize depth
+
+# Now switch to binary mode to pull in the data,
+# one byte per channel (red,green,blue) per pixel.
+\fBfconfigure\fR $f \-translation binary
+set numDataBytes [expr {3 * $xSize * $ySize}]
+set data [read $f $numDataBytes]
+
+close $f
+.CE
+.SH "SEE ALSO"
+close(n), flush(n), gets(n), open(n), puts(n), read(n), socket(n),
+Tcl_StandardChannels(3)
+.SH KEYWORDS
+blocking, buffering, carriage return, end of line, flushing, linemode,
+newline, nonblocking, platform, translation, encoding, filter, byte array,
+binary
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/doc/fcopy.n b/doc/fcopy.n
new file mode 100644
index 0000000..d39c803
--- /dev/null
+++ b/doc/fcopy.n
@@ -0,0 +1,182 @@
+'\"
+'\" Copyright (c) 1993 The Regents of the University of California.
+'\" Copyright (c) 1994-1997 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH fcopy n 8.0 Tcl "Tcl Built-In Commands"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+fcopy \- Copy data from one channel to another
+.SH SYNOPSIS
+\fBfcopy \fIinchan\fR \fIoutchan\fR ?\fB\-size \fIsize\fR? ?\fB\-command \fIcallback\fR?
+.BE
+
+.SH DESCRIPTION
+.PP
+The \fBfcopy\fR command copies data from one I/O channel, \fIinchan\fR to another I/O channel, \fIoutchan\fR.
+The \fBfcopy\fR command leverages the buffering in the Tcl I/O system to
+avoid extra copies and to avoid buffering too much data in
+main memory when copying large files to slow destinations like
+network sockets.
+.PP
+The \fBfcopy\fR
+command transfers data from \fIinchan\fR until end of file
+or \fIsize\fR bytes or characters have been
+transferred; \fIsize\fR is in bytes if the two channels are using the
+same encoding, and is in characters otherwise.
+If no \fB\-size\fR argument is given,
+then the copy goes until end of file.
+All the data read from \fIinchan\fR is copied to \fIoutchan\fR.
+Without the \fB\-command\fR option, \fBfcopy\fR blocks until the copy is complete
+and returns the number of bytes or characters (using the same rules as
+for the \fB\-size\fR option) written to \fIoutchan\fR.
+.PP
+The \fB\-command\fR argument makes \fBfcopy\fR work in the background.
+In this case it returns immediately and the \fIcallback\fR is invoked
+later when the copy completes.
+The \fIcallback\fR is called with
+one or two additional
+arguments that indicates how many bytes were written to \fIoutchan\fR.
+If an error occurred during the background copy, the second argument is the
+error string associated with the error.
+With a background copy,
+it is not necessary to put \fIinchan\fR or \fIoutchan\fR into
+non-blocking mode; the \fBfcopy\fR command takes care of that automatically.
+However, it is necessary to enter the event loop by using
+the \fBvwait\fR command or by using Tk.
+.PP
+You are not allowed to do other input operations with \fIinchan\fR, or
+output operations with \fIoutchan\fR, during a background
+\fBfcopy\fR. The converse is entirely legitimate, as exhibited by the
+bidirectional fcopy example below.
+.PP
+If either \fIinchan\fR or \fIoutchan\fR get closed
+while the copy is in progress, the current copy is stopped
+and the command callback is \fInot\fR made.
+If \fIinchan\fR is closed,
+then all data already queued for \fIoutchan\fR is written out.
+.PP
+Note that \fIinchan\fR can become readable during a background copy.
+You should turn off any \fBfileevent\fR handlers during a background
+copy so those handlers do not interfere with the copy.
+Any wrong-sided I/O attempted (by a \fBfileevent\fR handler or otherwise) will get a
+.QW "channel busy"
+error.
+.PP
+\fBFcopy\fR translates end-of-line sequences in \fIinchan\fR and \fIoutchan\fR
+according to the \fB\-translation\fR option
+for these channels.
+See the manual entry for \fBfconfigure\fR for details on the
+\fB\-translation\fR option.
+The translations mean that the number of bytes read from \fIinchan\fR
+can be different than the number of bytes written to \fIoutchan\fR.
+Only the number of bytes written to \fIoutchan\fR is reported,
+either as the return value of a synchronous \fBfcopy\fR or
+as the argument to the callback for an asynchronous \fBfcopy\fR.
+.PP
+\fBFcopy\fR obeys the encodings and character translations configured
+for the channels. This
+means that the incoming characters are converted internally first
+UTF-8 and then into the encoding of the channel \fBfcopy\fR writes
+to. See the manual entry for \fBfconfigure\fR for details on the
+\fB\-encoding\fR and \fB\-translation\fR options. No conversion is
+done if both channels are
+set to encoding
+.QW binary
+and have matching translations. If only the output channel is set to encoding
+.QW binary
+the system will write the internal UTF-8 representation of the incoming
+characters. If only the input channel is set to encoding
+.QW binary
+the system will assume that the incoming
+bytes are valid UTF-8 characters and convert them according to the
+output encoding. The behaviour of the system for bytes which are not
+valid UTF-8 characters is undefined in this case.
+.SH EXAMPLES
+.PP
+The first example transfers the contents of one channel exactly to
+another. Note that when copying one file to another, it is better to
+use \fBfile copy\fR which also copies file metadata (e.g. the file
+access permissions) where possible.
+.PP
+.CS
+fconfigure $in -translation binary
+fconfigure $out -translation binary
+\fBfcopy\fR $in $out
+.CE
+.PP
+This second example shows how the callback gets
+passed the number of bytes transferred.
+It also uses vwait to put the application into the event loop.
+Of course, this simplified example could be done without the command
+callback.
+.PP
+.CS
+proc Cleanup {in out bytes {error {}}} {
+    global total
+    set total $bytes
+    close $in
+    close $out
+    if {[string length $error] != 0} {
+        # error occurred during the copy
+    }
+}
+set in [open $file1]
+set out [socket $server $port]
+\fBfcopy\fR $in $out -command [list Cleanup $in $out]
+vwait total
+.CE
+.PP
+The third example copies in chunks and tests for end of file
+in the command callback.
+.PP
+.CS
+proc CopyMore {in out chunk bytes {error {}}} {
+    global total done
+    incr total $bytes
+    if {([string length $error] != 0) || [eof $in]} {
+        set done $total
+        close $in
+        close $out
+    } else {
+        \fBfcopy\fR $in $out -size $chunk \e
+                -command [list CopyMore $in $out $chunk]
+    }
+}
+set in [open $file1]
+set out [socket $server $port]
+set chunk 1024
+set total 0
+\fBfcopy\fR $in $out -size $chunk \e
+        -command [list CopyMore $in $out $chunk]
+vwait done
+.CE
+.PP
+The fourth example starts an asynchronous, bidirectional fcopy between
+two sockets. Those could also be pipes from two [open "|hal 9000" r+]
+(though their conversation would remain secret to the script, since
+all four fileevent slots are busy).
+.PP
+.CS
+set flows 2
+proc Done {dir args} {
+     global flows done
+     puts "$dir is over."
+     incr flows -1
+     if {$flows<=0} {set done 1}
+}
+\fBfcopy\fR $sok1 $sok2 -command [list Done UP]
+\fBfcopy\fR $sok2 $sok1 -command [list Done DOWN]
+vwait done
+.CE
+.SH "SEE ALSO"
+eof(n), fblocked(n), fconfigure(n), file(n)
+.SH KEYWORDS
+blocking, channel, end of line, end of file, nonblocking, read, translation
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/doc/file.n b/doc/file.n
new file mode 100644
index 0000000..2f8b70c
--- /dev/null
+++ b/doc/file.n
@@ -0,0 +1,549 @@
+'\"
+'\" Copyright (c) 1993 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH file n 8.3 Tcl "Tcl Built-In Commands"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+file \- Manipulate file names and attributes
+.SH SYNOPSIS
+\fBfile \fIoption\fR \fIname\fR ?\fIarg arg ...\fR?
+.BE
+.SH DESCRIPTION
+.PP
+This command provides several operations on a file's name or attributes.
+\fIName\fR is the name of a file; if it starts with a tilde, then tilde
+substitution is done before executing the command (see the manual entry for
+\fBfilename\fR for details).  \fIOption\fR indicates what to do with the
+file name.  Any unique abbreviation for \fIoption\fR is acceptable.  The
+valid options are:
+.TP
+\fBfile atime \fIname\fR ?\fItime\fR?
+.
+Returns a decimal string giving the time at which file \fIname\fR was last
+accessed.  If \fItime\fR is specified, it is an access time to set
+for the file.  The time is measured in the standard POSIX fashion as
+seconds from a fixed starting time (often January 1, 1970).  If the file
+does not exist or its access time cannot be queried or set then an error is
+generated.  On Windows, FAT file systems do not support access time.
+.TP
+\fBfile attributes \fIname\fR
+.TP
+\fBfile attributes \fIname\fR ?\fIoption\fR?
+.TP
+\fBfile attributes \fIname\fR ?\fIoption value option value...\fR?
+.
+This subcommand returns or sets platform specific values associated
+with a file. The first form returns a list of the platform specific
+flags and their values. The second form returns the value for the
+specific option. The third form sets one or more of the values. The
+values are as follows:
+.RS
+.PP
+On Unix, \fB\-group\fR gets or sets the group name for the file. A group id
+can be given to the command, but it returns a group name. \fB\-owner\fR gets
+or sets the user name of the owner of the file. The command returns the
+owner name, but the numerical id can be passed when setting the
+owner. \fB\-permissions\fR sets or retrieves the octal code that chmod(1)
+uses.  This command does also has limited support for setting using the
+symbolic attributes for chmod(1), of the form [ugo]?[[+\-=][rwxst],[...]],
+where multiple symbolic attributes can be separated by commas (example:
+\fBu+s,go\-rw\fR add sticky bit for user, remove read and write
+permissions for group and other).  A simplified \fBls\fR style string,
+of the form rwxrwxrwx (must be 9 characters), is also supported
+(example: \fBrwxr\-xr\-t\fR is equivalent to 01755).
+On versions of Unix supporting file flags, \fB\-readonly\fR gives the
+value or sets or clears the readonly attribute of the file,
+i.e. the user immutable flag \fBuchg\fR to chflags(1).
+.PP
+On Windows, \fB\-archive\fR gives the value or sets or clears the
+archive attribute of the file. \fB\-hidden\fR gives the value or sets
+or clears the hidden attribute of the file. \fB\-longname\fR will
+expand each path element to its long version. This attribute cannot be
+set. \fB\-readonly\fR gives the value or sets or clears the readonly
+attribute of the file. \fB\-shortname\fR gives a string where every
+path element is replaced with its short (8.3) version of the
+name. This attribute cannot be set. \fB\-system\fR gives or sets or
+clears the value of the system attribute of the file.
+.PP
+On Mac OS X and Darwin, \fB\-creator\fR gives or sets the
+Finder creator type of the file. \fB\-hidden\fR gives or sets or clears
+the hidden attribute of the file. \fB\-readonly\fR gives or sets or
+clears the readonly attribute of the file. \fB\-rsrclength\fR gives
+the length of the resource fork of the file, this attribute can only be
+set to the value 0, which results in the resource fork being stripped
+off the file.
+.RE
+.TP
+\fBfile channels\fR ?\fIpattern\fR?
+.
+If \fIpattern\fR is not specified, returns a list of names of all
+registered open channels in this interpreter.  If \fIpattern\fR is
+specified, only those names matching \fIpattern\fR are returned.  Matching
+is determined using the same rules as for \fBstring match\fR.
+.TP
+\fBfile copy \fR?\fB\-force\fR? ?\fB\-\|\-\fR? \fIsource\fR \fItarget\fR
+.TP
+\fBfile copy \fR?\fB\-force\fR? ?\fB\-\|\-\fR? \fIsource\fR ?\fIsource\fR ...? \fItargetDir\fR
+.
+The first form makes a copy of the file or directory \fIsource\fR under
+the pathname \fItarget\fR. If \fItarget\fR is an existing directory,
+then the second form is used.  The second form makes a copy inside
+\fItargetDir\fR of each \fIsource\fR file listed.  If a directory is
+specified as a \fIsource\fR, then the contents of the directory will be
+recursively copied into \fItargetDir\fR. Existing files will not be
+overwritten unless the \fB\-force\fR option is specified (when Tcl will
+also attempt to adjust permissions on the destination file or directory
+if that is necessary to allow the copy to proceed).  When copying
+within a single filesystem, \fIfile copy\fR will copy soft links (i.e.
+the links themselves are copied, not the things they point to).  Trying
+to overwrite a non-empty directory, overwrite a directory with a file,
+or overwrite a file with a directory will all result in errors even if
+\fB\-force\fR was specified.  Arguments are processed in the order
+specified, halting at the first error, if any.  A \fB\-\|\-\fR marks
+the end of switches; the argument following the \fB\-\|\-\fR will be
+treated as a \fIsource\fR even if it starts with a \fB\-\fR.
+.TP
+\fBfile delete \fR?\fB\-force\fR? ?\fB\-\|\-\fR? ?\fIpathname\fR ... ?
+.
+Removes the file or directory specified by each \fIpathname\fR
+argument.  Non-empty directories will be removed only if the
+\fB\-force\fR option is specified.  When operating on symbolic links,
+the links themselves will be deleted, not the objects they point to.
+Trying to delete a non-existent file is not considered an error.
+Trying to delete a read-only file will cause the file to be deleted,
+even if the \fB\-force\fR flags is not specified.  If the \fB\-force\fR
+option is specified on a directory, Tcl will attempt both to change
+permissions and move the current directory
+.QW pwd
+out of the given path if that is necessary to allow the deletion to
+proceed.  Arguments are processed in the order specified, halting at
+the first error, if any.
+A \fB\-\|\-\fR marks the end of switches; the argument following the
+\fB\-\|\-\fR will be treated as a \fIpathname\fR even if it starts with
+a \fB\-\fR.
+.TP
+\fBfile dirname \fIname\fR
+Returns a name comprised of all of the path components in \fIname\fR
+excluding the last element.  If \fIname\fR is a relative file name and
+only contains one path element, then returns
+.QW \fB.\fR .
+If \fIname\fR refers to a root directory, then the root directory is
+returned.  For example,
+.RS
+.PP
+.CS
+\fBfile dirname\fR c:/
+.CE
+.PP
+returns \fBc:/\fR.
+.PP
+Note that tilde substitution will only be
+performed if it is necessary to complete the command. For example,
+.PP
+.CS
+\fBfile dirname\fR ~/src/foo.c
+.CE
+.PP
+returns \fB~/src\fR, whereas
+.PP
+.CS
+\fBfile dirname\fR ~
+.CE
+.PP
+returns \fB/home\fR (or something similar).
+.RE
+.TP
+\fBfile executable \fIname\fR
+.
+Returns \fB1\fR if file \fIname\fR is executable by the current user,
+\fB0\fR otherwise. On Windows, which does not have an executable attribute,
+the command treats all directories and any files with extensions
+\fBexe\fR, \fBcom\fR, \fBcmd\fR or \fBbat\fR as executable.
+.TP
+\fBfile exists \fIname\fR
+.
+Returns \fB1\fR if file \fIname\fR exists and the current user has
+search privileges for the directories leading to it, \fB0\fR otherwise.
+.TP
+\fBfile extension \fIname\fR
+.
+Returns all of the characters in \fIname\fR after and including the last
+dot in the last element of \fIname\fR.  If there is no dot in the last
+element of \fIname\fR then returns the empty string.
+.TP
+\fBfile isdirectory \fIname\fR
+.
+Returns \fB1\fR if file \fIname\fR is a directory, \fB0\fR otherwise.
+.TP
+\fBfile isfile \fIname\fR
+.
+Returns \fB1\fR if file \fIname\fR is a regular file, \fB0\fR otherwise.
+.TP
+\fBfile join \fIname\fR ?\fIname ...\fR?
+.
+Takes one or more file names and combines them, using the correct path
+separator for the current platform.  If a particular \fIname\fR is
+relative, then it will be joined to the previous file name argument.
+Otherwise, any earlier arguments will be discarded, and joining will
+proceed from the current argument.  For example,
+.RS
+.PP
+.CS
+\fBfile join\fR a b /foo bar
+.CE
+.PP
+returns \fB/foo/bar\fR.
+.PP
+Note that any of the names can contain separators, and that the result
+is always canonical for the current platform: \fB/\fR for Unix and
+Windows.
+.RE
+.TP
+\fBfile link\fR ?\fI\-linktype\fR? \fIlinkName\fR ?\fItarget\fR?
+.
+If only one argument is given, that argument is assumed to be
+\fIlinkName\fR, and this command returns the value of the link given by
+\fIlinkName\fR (i.e. the name of the file it points to).  If
+\fIlinkName\fR is not a link or its value cannot be read (as, for example,
+seems to be the case with hard links, which look just like ordinary
+files), then an error is returned.
+.RS
+.PP
+If 2 arguments are given, then these are assumed to be \fIlinkName\fR
+and \fItarget\fR. If \fIlinkName\fR already exists, or if \fItarget\fR
+does not exist, an error will be returned.  Otherwise, Tcl creates a new
+link called \fIlinkName\fR which points to the existing filesystem
+object at \fItarget\fR (which is also the returned value), where the
+type of the link is platform-specific (on Unix a symbolic link will be
+the default).  This is useful for the case where the user wishes to
+create a link in a cross-platform way, and does not care what type of
+link is created.
+.PP
+If the user wishes to make a link of a specific type only, (and signal an
+error if for some reason that is not possible), then the optional
+\fI\-linktype\fR argument should be given.  Accepted values for
+\fI\-linktype\fR are
+.QW \fB\-symbolic\fR
+and
+.QW \fB\-hard\fR .
+.PP
+On Unix, symbolic links can be made to relative paths, and those paths
+must be relative to the actual \fIlinkName\fR's location (not to the
+cwd), but on all other platforms where relative links are not supported,
+target paths will always be converted to absolute, normalized form
+before the link is created (and therefore relative paths are interpreted
+as relative to the cwd).  Furthermore,
+.QW ~user
+paths are always expanded
+to absolute form.  When creating links on filesystems that either do not
+support any links, or do not support the specific type requested, an
+error message will be returned.  Most Unix platforms support both
+symbolic and hard links (the latter for files only). Windows
+supports symbolic directory links and hard file links on NTFS drives.
+.RE
+.TP
+\fBfile lstat \fIname varName\fR
+.
+Same as \fBstat\fR option (see below) except uses the \fIlstat\fR
+kernel call instead of \fIstat\fR.  This means that if \fIname\fR
+refers to a symbolic link the information returned in \fIvarName\fR
+is for the link rather than the file it refers to.  On systems that
+do not support symbolic links this option behaves exactly the same
+as the \fBstat\fR option.
+.TP
+\fBfile mkdir\fR ?\fIdir\fR ...?
+.
+Creates each directory specified.  For each pathname \fIdir\fR specified,
+this command will create all non-existing parent directories as
+well as \fIdir\fR itself.  If an existing directory is specified, then
+no action is taken and no error is returned.  Trying to overwrite an existing
+file with a directory will result in an error.  Arguments are processed in
+the order specified, halting at the first error, if any.
+.TP
+\fBfile mtime \fIname\fR ?\fItime\fR?
+.
+Returns a decimal string giving the time at which file \fIname\fR was last
+modified.  If \fItime\fR is specified, it is a modification time to set for
+the file (equivalent to Unix \fBtouch\fR).  The time is measured in the
+standard POSIX fashion as seconds from a fixed starting time (often January
+1, 1970).  If the file does not exist or its modified time cannot be queried
+or set then an error is generated.
+.TP
+\fBfile nativename \fIname\fR
+.
+Returns the platform-specific name of the file. This is useful if the
+filename is needed to pass to a platform-specific call, such as to a
+subprocess via \fBexec\fR under Windows (see \fBEXAMPLES\fR below).
+.TP
+\fBfile normalize \fIname\fR
+.
+Returns a unique normalized path representation for the file-system
+object (file, directory, link, etc), whose string value can be used as a
+unique identifier for it.  A normalized path is an absolute path which has
+all
+.QW ../
+and
+.QW ./
+removed.  Also it is one which is in the
+.QW standard
+format for the native platform.  On Unix, this means the segments
+leading up to the path must be free of symbolic links/aliases (but the
+very last path component may be a symbolic link), and on Windows it also
+means we want the long form with that form's case-dependence (which
+gives us a unique, case-dependent path).  The one exception concerning the
+last link in the path is necessary, because Tcl or the user may wish to
+operate on the actual symbolic link itself (for example \fBfile delete\fR,
+\fBfile rename\fR, \fBfile copy\fR are defined to operate on symbolic
+links, not on the things that they point to).
+.TP
+\fBfile owned \fIname\fR
+.
+Returns \fB1\fR if file \fIname\fR is owned by the current user, \fB0\fR
+otherwise.
+.TP
+\fBfile pathtype \fIname\fR
+.
+Returns one of \fBabsolute\fR, \fBrelative\fR, \fBvolumerelative\fR. If
+\fIname\fR refers to a specific file on a specific volume, the path type will
+be \fBabsolute\fR. If \fIname\fR refers to a file relative to the current
+working directory, then the path type will be \fBrelative\fR. If \fIname\fR
+refers to a file relative to the current working directory on a specified
+volume, or to a specific file on the current working volume, then the path
+type is \fBvolumerelative\fR.
+.TP
+\fBfile readable \fIname\fR
+.
+Returns \fB1\fR if file \fIname\fR is readable by the current user,
+\fB0\fR otherwise.
+.TP
+\fBfile readlink \fIname\fR
+.
+Returns the value of the symbolic link given by \fIname\fR (i.e. the name
+of the file it points to).  If \fIname\fR is not a symbolic link or its
+value cannot be read, then an error is returned.  On systems that do not
+support symbolic links this option is undefined.
+.TP
+\fBfile rename \fR?\fB\-force\fR? ?\fB\-\|\-\fR? \fIsource\fR \fItarget\fR
+.TP
+\fBfile rename \fR?\fB\-force\fR? ?\fB\-\|\-\fR? \fIsource\fR ?\fIsource\fR ...? \fItargetDir\fR
+.
+The first form takes the file or directory specified by pathname
+\fIsource\fR and renames it to \fItarget\fR, moving the file if the
+pathname \fItarget\fR specifies a name in a different directory.  If
+\fItarget\fR is an existing directory, then the second form is used.
+The second form moves each \fIsource\fR file or directory into the
+directory \fItargetDir\fR. Existing files will not be overwritten
+unless the \fB\-force\fR option is specified.  When operating inside a
+single filesystem, Tcl will rename symbolic links rather than the
+things that they point to.  Trying to overwrite a non-empty directory,
+overwrite a directory with a file, or a file with a directory will all
+result in errors.  Arguments are processed in the order specified,
+halting at the first error, if any.  A \fB\-\|\-\fR marks the end of
+switches; the argument following the \fB\-\|\-\fR will be treated as a
+\fIsource\fR even if it starts with a \fB\-\fR.
+.TP
+\fBfile rootname \fIname\fR
+.
+Returns all of the characters in \fIname\fR up to but not including the
+last
+.QW .
+character in the last component of name.  If the last
+component of \fIname\fR does not contain a dot, then returns \fIname\fR.
+.TP
+\fBfile separator\fR ?\fIname\fR?
+.
+If no argument is given, returns the character which is used to separate
+path segments for native files on this platform.  If a path is given,
+the filesystem responsible for that path is asked to return its
+separator character.  If no file system accepts \fIname\fR, an error
+is generated.
+.TP
+\fBfile size \fIname\fR
+.
+Returns a decimal string giving the size of file \fIname\fR in bytes.  If
+the file does not exist or its size cannot be queried then an error is
+generated.
+.TP
+\fBfile split \fIname\fR
+.
+Returns a list whose elements are the path components in \fIname\fR.  The
+first element of the list will have the same path type as \fIname\fR.
+All other elements will be relative.  Path separators will be discarded
+unless they are needed to ensure that an element is unambiguously relative.
+For example, under Unix
+.RS
+.PP
+.CS
+\fBfile split\fR /foo/~bar/baz
+.CE
+.PP
+returns
+.QW \fB/\0\0foo\0\0./~bar\0\0baz\fR
+to ensure that later commands
+that use the third component do not attempt to perform tilde
+substitution.
+.RE
+.TP
+\fBfile stat  \fIname varName\fR
+.
+Invokes the \fBstat\fR kernel call on \fIname\fR, and uses the variable
+given by \fIvarName\fR to hold information returned from the kernel call.
+\fIVarName\fR is treated as an array variable, and the following elements
+of that variable are set: \fBatime\fR, \fBctime\fR, \fBdev\fR, \fBgid\fR,
+\fBino\fR, \fBmode\fR, \fBmtime\fR, \fBnlink\fR, \fBsize\fR, \fBtype\fR,
+\fBuid\fR.  Each element except \fBtype\fR is a decimal string with the
+value of the corresponding field from the \fBstat\fR return structure;
+see the manual entry for \fBstat\fR for details on the meanings of the
+values.  The \fBtype\fR element gives the type of the file in the same
+form returned by the command \fBfile type\fR.  This command returns an
+empty string.
+.TP
+\fBfile system \fIname\fR
+.
+Returns a list of one or two elements, the first of which is the name of
+the filesystem to use for the file, and the second, if given, an
+arbitrary string representing the filesystem-specific nature or type of
+the location within that filesystem.  If a filesystem only supports one
+type of file, the second element may not be supplied.  For example the
+native files have a first element
+.QW native ,
+and a second element which when given is a platform-specific type name
+for the file's system (e.g.
+.QW NTFS ,
+.QW FAT ,
+on Windows).  A generic virtual file system might return
+the list
+.QW "vfs ftp"
+to represent a file on a remote ftp site mounted as a
+virtual filesystem through an extension called
+.QW vfs .
+If the file does not belong to any filesystem, an error is generated.
+.TP
+\fBfile tail \fIname\fR
+.
+Returns all of the characters in the last filesystem component of
+\fIname\fR.  Any trailing directory separator in \fIname\fR is ignored.
+If \fIname\fR contains no separators then returns \fIname\fR.  So,
+\fBfile tail a/b\fR, \fBfile tail a/b/\fR and \fBfile tail b\fR all
+return \fBb\fR.
+.TP
+\fBfile tempfile\fR ?\fInameVar\fR? ?\fItemplate\fR?
+'\" TIP #210
+.VS 8.6
+Creates a temporary file and returns a read-write channel opened on that file.
+If the \fInameVar\fR is given, it specifies a variable that the name of the
+temporary file will be written into; if absent, Tcl will attempt to arrange
+for the temporary file to be deleted once it is no longer required. If the
+\fItemplate\fR is present, it specifies parts of the template of the filename
+to use when creating it (such as the directory, base-name or extension) though
+some platforms may ignore some or all of these parts and use a built-in
+default instead.
+.RS
+.PP
+Note that temporary files are \fIonly\fR ever created on the native
+filesystem. As such, they can be relied upon to be used with operating-system
+native APIs and external programs that require a filename.
+.RE
+.VE 8.6
+.TP
+\fBfile type \fIname\fR
+.
+Returns a string giving the type of file \fIname\fR, which will be one of
+\fBfile\fR, \fBdirectory\fR, \fBcharacterSpecial\fR, \fBblockSpecial\fR,
+\fBfifo\fR, \fBlink\fR, or \fBsocket\fR.
+.TP
+\fBfile volumes\fR
+.
+Returns the absolute paths to the volumes mounted on the system, as a
+proper Tcl list.  Without any virtual filesystems mounted as root
+volumes, on UNIX, the command will always return
+.QW / ,
+since all filesystems are locally mounted.
+On Windows, it will return a list of the available local drives
+(e.g.
+.QW "a:/ c:/" ).
+If any virtual filesystem has mounted additional
+volumes, they will be in the returned list.
+.TP
+\fBfile writable \fIname\fR
+.
+Returns \fB1\fR if file \fIname\fR is writable by the current user,
+\fB0\fR otherwise.
+.SH "PORTABILITY ISSUES"
+.TP
+\fBUnix\fR\0\0\0\0\0\0\0
+.
+These commands always operate using the real user and group identifiers,
+not the effective ones.
+.TP
+\fBWindows\fR\0\0\0\0
+.
+The \fBfile owned\fR subcommand uses the user identifier (SID) of
+the process token, not the thread token which may be impersonating
+some other user.
+.SH EXAMPLES
+.PP
+This procedure shows how to search for C files in a given directory
+that have a correspondingly-named object file in the current
+directory:
+.PP
+.CS
+proc findMatchingCFiles {dir} {
+    set files {}
+    switch $::tcl_platform(platform) {
+        windows {
+            set ext .obj
+        }
+        unix {
+           set ext .o
+        }
+    }
+    foreach file [glob \-nocomplain \-directory $dir *.c] {
+        set objectFile [\fBfile tail\fR [\fBfile rootname\fR $file]]$ext
+        if {[\fBfile exists\fR $objectFile]} {
+            lappend files $file
+        }
+    }
+    return $files
+}
+.CE
+.PP
+Rename a file and leave a symbolic link pointing from the old location
+to the new place:
+.PP
+.CS
+set oldName foobar.txt
+set newName foo/bar.txt
+# Make sure that where we're going to move to exists...
+if {![\fBfile isdirectory\fR [\fBfile dirname\fR $newName]]} {
+    \fBfile mkdir\fR [\fBfile dirname\fR $newName]
+}
+\fBfile rename\fR $oldName $newName
+\fBfile link\fR \-symbolic $oldName $newName
+.CE
+.PP
+On Windows, a file can be
+.QW started
+easily enough (equivalent to double-clicking on it in the Explorer
+interface) but the name passed to the operating system must be in
+native format:
+.PP
+.CS
+exec {*}[auto_execok start] {} [\fBfile nativename\fR ~/example.txt]
+.CE
+.SH "SEE ALSO"
+filename(n), open(n), close(n), eof(n), gets(n), tell(n), seek(n),
+fblocked(n), flush(n)
+.SH KEYWORDS
+attributes, copy files, delete files, directory, file, move files, name,
+rename files, stat, user
+'\" Local Variables:
+'\" mode: nroff
+'\" fill-column: 78
+'\" End:
diff --git a/doc/fileevent.n b/doc/fileevent.n
new file mode 100644
index 0000000..2751040
--- /dev/null
+++ b/doc/fileevent.n
@@ -0,0 +1,156 @@
+'\"
+'\" Copyright (c) 1994 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\" Copyright (c) 2008 Pat Thoyts
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH fileevent n 7.5 Tcl "Tcl Built-In Commands"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+fileevent \- Execute a script when a channel becomes readable or writable
+.SH SYNOPSIS
+\fBfileevent \fIchannelId \fBreadable \fR?\fIscript\fR?
+.sp
+\fBfileevent \fIchannelId \fBwritable \fR?\fIscript\fR?
+.BE
+
+.SH DESCRIPTION
+.PP
+This command is used to create \fIfile event handlers\fR.  A file event
+handler is a binding between a channel and a script, such that the script
+is evaluated whenever the channel becomes readable or writable.  File event
+handlers are most commonly used to allow data to be received from another
+process on an event-driven basis, so that the receiver can continue to
+interact with the user while waiting for the data to arrive.  If an
+application invokes \fBgets\fR or \fBread\fR on a blocking channel when
+there is no input data available, the process will block; until the input
+data arrives, it will not be able to service other events, so it will
+appear to the user to
+.QW "freeze up" .
+With \fBfileevent\fR, the process can
+tell when data is present and only invoke \fBgets\fR or \fBread\fR when
+they will not block.
+.PP
+The \fIchannelId\fR argument to \fBfileevent\fR refers to an open
+channel such as a Tcl standard channel (\fBstdin\fR, \fBstdout\fR,
+or \fBstderr\fR), the return value from an invocation of \fBopen\fR
+or \fBsocket\fR, or the result of a channel creation command provided
+by a Tcl extension.
+.PP
+If the \fIscript\fR argument is specified, then \fBfileevent\fR
+creates a new event handler:  \fIscript\fR will be evaluated
+whenever the channel becomes readable or writable (depending on the
+second argument to \fBfileevent\fR).
+In this case \fBfileevent\fR returns an empty string.
+The \fBreadable\fR and \fBwritable\fR event handlers for a file
+are independent, and may be created and deleted separately.
+However, there may be at most one \fBreadable\fR and one \fBwritable\fR
+handler for a file at a given time in a given interpreter.
+If \fBfileevent\fR is called when the specified handler already
+exists in the invoking interpreter, the new script replaces the old one.
+.PP
+If the \fIscript\fR argument is not specified, \fBfileevent\fR
+returns the current script for \fIchannelId\fR, or an empty string
+if there is none.
+If the \fIscript\fR argument is specified as an empty string
+then the event handler is deleted, so that no script will be invoked.
+A file event handler is also deleted automatically whenever
+its channel is closed or its interpreter is deleted.
+.PP
+A channel is considered to be readable if there is unread data
+available on the underlying device.
+A channel is also considered to be readable if there is unread
+data in an input buffer, except in the special case where the
+most recent attempt to read from the channel was a \fBgets\fR
+call that could not find a complete line in the input buffer.
+This feature allows a file to be read a line at a time in nonblocking mode
+using events.
+A channel is also considered to be readable if an end of file or
+error condition is present on the underlying file or device.
+It is important for \fIscript\fR to check for these conditions
+and handle them appropriately;  for example, if there is no special
+check for end of file, an infinite loop may occur where \fIscript\fR
+reads no data, returns, and is immediately invoked again.
+.PP
+A channel is considered to be writable if at least one byte of data
+can be written to the underlying file or device without blocking,
+or if an error condition is present on the underlying file or device.
+.PP
+Event-driven I/O works best for channels that have been placed into
+nonblocking mode with the \fBfconfigure\fR command.  In blocking mode,
+a \fBputs\fR command may block if you give it more data than the
+underlying file or device can accept, and a \fBgets\fR or \fBread\fR
+command will block if you attempt to read more data than is ready; a
+readable underlying file or device may not even guarantee that a
+blocking [read 1] will succeed (counter-examples being multi-byte
+encodings, compression or encryption transforms ). In all such cases,
+no events will be processed while the commands block.
+.PP
+In nonblocking mode \fBputs\fR, \fBread\fR, and \fBgets\fR never block.
+See the documentation for the individual commands for information
+on how they handle blocking and nonblocking channels.
+.PP
+Testing for the end of file condition should be done after any attempts
+read the channel data. The eof flag is set once an attempt to read the
+end of data has occurred and testing before this read will require an
+additional event to be fired.
+.PP
+The script for a file event is executed at global level (outside the
+context of any Tcl procedure) in the interpreter in which the
+\fBfileevent\fR command was invoked.
+If an error occurs while executing the script then the
+command registered with \fBinterp bgerror\fR is used to report the error.
+In addition, the file event handler is deleted if it ever returns
+an error;  this is done in order to prevent infinite loops due to
+buggy handlers.
+.SH EXAMPLE
+.PP
+In this setup \fBGetData\fR will be called with the channel as an
+argument whenever $chan becomes readable. The \fBread\fR call will
+read whatever binary data is currently available without blocking.
+Here the channel has the fileevent removed when an end of file
+occurs to avoid being continually called (see above). Alternatively
+the channel may be closed on this condition.
+.PP
+.CS
+proc GetData {chan} {
+    set data [read $chan]
+    puts "[string length $data] $data"
+    if {[eof $chan]} {
+        fileevent $chan readable {}
+    }
+}
+
+fconfigure $chan -blocking 0 -encoding binary
+\fBfileevent\fR $chan readable [list GetData $chan]
+.CE
+.PP
+The next example demonstrates use of \fBgets\fR to read line-oriented
+data.
+.PP
+.CS
+proc GetData {chan} {
+    if {[gets $chan line] >= 0} {
+        puts $line
+    }
+    if {[eof $chan]} {
+        close $chan
+    }
+}
+
+fconfigure $chan -blocking 0 -buffering line -translation crlf
+\fBfileevent\fR $chan readable [list GetData $chan]
+.CE
+.SH CREDITS
+.PP
+\fBfileevent\fR is based on the \fBaddinput\fR command created
+by Mark Diekhans.
+.SH "SEE ALSO"
+fconfigure(n), gets(n), interp(n), puts(n), read(n), Tcl_StandardChannels(3)
+.SH KEYWORDS
+asynchronous I/O, blocking, channel, event handler, nonblocking, readable,
+script, writable.
diff --git a/doc/filename.n b/doc/filename.n
new file mode 100644
index 0000000..87ba467
--- /dev/null
+++ b/doc/filename.n
@@ -0,0 +1,178 @@
+'\"
+'\" Copyright (c) 1995-1996 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH filename n 7.5 Tcl "Tcl Built-In Commands"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+filename \- File name conventions supported by Tcl commands
+.BE
+.SH INTRODUCTION
+.PP
+All Tcl commands and C procedures that take file names as arguments
+expect the file names to be in one of three forms, depending on the
+current platform.  On each platform, Tcl supports file names in the
+standard forms(s) for that platform.  In addition, on all platforms,
+Tcl supports a Unix-like syntax intended to provide a convenient way
+of constructing simple file names.  However, scripts that are intended
+to be portable should not assume a particular form for file names.
+Instead, portable scripts must use the \fBfile split\fR and \fBfile
+join\fR commands to manipulate file names (see the \fBfile\fR manual
+entry for more details).
+.SH "PATH TYPES"
+.PP
+File names are grouped into three general types based on the starting point
+for the path used to specify the file: absolute, relative, and
+volume-relative.  Absolute names are completely qualified, giving a path to
+the file relative to a particular volume and the root directory on that
+volume.  Relative names are unqualified, giving a path to the file relative
+to the current working directory.  Volume-relative names are partially
+qualified, either giving the path relative to the root directory on the
+current volume, or relative to the current directory of the specified
+volume.  The \fBfile pathtype\fR command can be used to determine the
+type of a given path.
+.SH "PATH SYNTAX"
+.PP
+The rules for native names depend on the value reported in the Tcl
+\fBplatform\fR element of the \fBtcl_platform\fR array:
+.TP 10
+\fBUnix\fR
+On Unix and Apple MacOS X platforms, Tcl uses path names where the
+components are separated by slashes.  Path names may be relative or
+absolute, and file names may contain any character other than slash.
+The file names \fB\&.\fR and \fB\&..\fR are special and refer to the
+current directory and the parent of the current directory respectively.
+Multiple adjacent slash characters are interpreted as a single
+separator.  Any number of trailing slash characters at the end of a
+path are simply ignored, so the paths \fBfoo\fR, \fBfoo/\fR and
+\fBfoo//\fR are all identical, and in particular \fBfoo/\fR does not
+necessarily mean a directory is being referred.
+.RS
+.PP
+The following examples illustrate various forms of path
+names:
+.TP 15
+\fB/\fR
+Absolute path to the root directory.
+.TP 15
+\fB/etc/passwd\fR
+Absolute path to the file named \fBpasswd\fR in the directory
+\fBetc\fR in the root directory.
+.TP 15
+\fB\&.\fR
+Relative path to the current directory.
+.TP 15
+\fBfoo\fR
+Relative path to the file \fBfoo\fR in the current directory.
+.TP 15
+\fBfoo/bar\fR
+Relative path to the file \fBbar\fR in the directory \fBfoo\fR in the
+current directory.
+.TP 15
+\fB\&../foo\fR
+Relative path to the file \fBfoo\fR in the directory above the current
+directory.
+.RE
+.TP
+\fBWindows\fR
+On Microsoft Windows platforms, Tcl supports both drive-relative and UNC
+style names.  Both \fB/\fR and \fB\e\fR may be used as directory separators
+in either type of name.  Drive-relative names consist of an optional drive
+specifier followed by an absolute or relative path.  UNC paths follow the
+general form \fB\e\eservername\esharename\epath\efile\fR, but must at
+the very least contain the server and share components, i.e.
+\fB\e\eservername\esharename\fR.  In both forms,
+the file names \fB.\fR and \fB..\fR are special and refer to the current
+directory and the parent of the current directory respectively.  The
+following examples illustrate various forms of path names:
+.RS
+.TP 15
+\fB\&\e\eHost\eshare/file\fR
+Absolute UNC path to a file called \fBfile\fR in the root directory of
+the export point \fBshare\fR on the host \fBHost\fR.  Note that
+repeated use of \fBfile dirname\fR on this path will give
+\fB//Host/share\fR, and will never give just \fB//Host\fR.
+.TP 15
+\fBc:foo\fR
+Volume-relative path to a file \fBfoo\fR in the current directory on drive
+\fBc\fR.
+.TP 15
+\fBc:/foo\fR
+Absolute path to a file \fBfoo\fR in the root directory of drive
+\fBc\fR.
+.TP 15
+\fBfoo\ebar\fR
+Relative path to a file \fBbar\fR in the \fBfoo\fR directory in the current
+directory on the current volume.
+.TP 15
+\fB\&\efoo\fR
+Volume-relative path to a file \fBfoo\fR in the root directory of the current
+volume.
+.TP 15
+\fB\&\e\efoo\fR
+Volume-relative path to a file \fBfoo\fR in the root directory of the current
+volume.  This is not a valid UNC path, so the assumption is that the
+extra backslashes are superfluous.
+.RE
+.SH "TILDE SUBSTITUTION"
+.PP
+In addition to the file name rules described above, Tcl also supports
+\fIcsh\fR-style tilde substitution.  If a file name starts with a tilde,
+then the file name will be interpreted as if the first element is
+replaced with the location of the home directory for the given user.  If
+the tilde is followed immediately by a separator, then the \fB$HOME\fR
+environment variable is substituted.  Otherwise the characters between
+the tilde and the next separator are taken as a user name, which is used
+to retrieve the user's home directory for substitution.  This works on
+Unix, MacOS X and Windows (except very old releases).
+.PP
+Old Windows platforms do not support tilde substitution when a user name
+follows the tilde.  On these platforms, attempts to use a tilde followed
+by a user name will generate an error that the user does not exist when
+Tcl attempts to interpret that part of the path or otherwise access the
+file.  The behaviour of these paths when not trying to interpret them is
+the same as on Unix.  File names that have a tilde without a user name
+will be correctly substituted using the \fB$HOME\fR environment
+variable, just like for Unix.
+.SH "PORTABILITY ISSUES"
+.PP
+Not all file systems are case sensitive, so scripts should avoid code
+that depends on the case of characters in a file name.  In addition,
+the character sets allowed on different devices may differ, so scripts
+should choose file names that do not contain special characters like:
+\fB<>:?"/\e|\fR.
+'\""\" reset emacs highlighting
+The safest approach is to use names consisting of
+alphanumeric characters only.  Care should be taken with filenames
+which contain spaces (common on Windows systems) and
+filenames where the backslash is the directory separator (Windows
+native path names).  Also Windows 3.1 only supports file
+names with a root of no more than 8 characters and an extension of no
+more than 3 characters.
+.PP
+On Windows platforms there are file and path length restrictions.
+Complete paths or filenames longer than about 260 characters will lead
+to errors in most file operations.
+.PP
+Another Windows peculiarity is that any number of trailing dots
+.QW .
+in filenames are totally ignored, so, for example, attempts to create a
+file or directory with a name
+.QW foo.
+will result in the creation of a file/directory with name
+.QW foo .
+This fact is reflected in the results of \fBfile normalize\fR.
+Furthermore, a file name consisting only of dots
+.QW .........
+or dots with trailing characters
+.QW .....abc
+is illegal.
+.SH "SEE ALSO"
+file(n), glob(n)
+.SH KEYWORDS
+current directory, absolute file name, relative file name,
+volume-relative file name, portability
diff --git a/doc/flush.n b/doc/flush.n
new file mode 100644
index 0000000..d266d91
--- /dev/null
+++ b/doc/flush.n
@@ -0,0 +1,45 @@
+'\"
+'\" Copyright (c) 1993 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\" 
+.TH flush n 7.5 Tcl "Tcl Built-In Commands"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+flush \- Flush buffered output for a channel
+.SH SYNOPSIS
+\fBflush \fIchannelId\fR
+.BE
+.SH DESCRIPTION
+.PP
+Flushes any output that has been buffered for \fIchannelId\fR.
+.PP
+\fIChannelId\fR must be an identifier for an open channel such as a
+Tcl standard channel (\fBstdout\fR or \fBstderr\fR), the return
+value from an invocation of \fBopen\fR or \fBsocket\fR, or the result
+of a channel creation command provided by a Tcl extension.  The
+channel must have been opened for writing.
+.PP
+If the channel is in blocking mode the command does not return until all the
+buffered output has been flushed to the channel. If the channel is in
+nonblocking mode, the command may return before all buffered output has been
+flushed; the remainder will be flushed in the background as fast as the
+underlying file or device is able to absorb it.
+.SH EXAMPLE
+.PP
+Prompt for the user to type some information in on the console:
+.PP
+.CS
+puts -nonewline "Please type your name: "
+\fBflush\fR stdout
+gets stdin name
+puts "Hello there, $name!"
+.CE
+.SH "SEE ALSO"
+file(n), open(n), socket(n), Tcl_StandardChannels(3)
+.SH KEYWORDS
+blocking, buffer, channel, flush, nonblocking, output
diff --git a/doc/for.n b/doc/for.n
new file mode 100644
index 0000000..9a3235f
--- /dev/null
+++ b/doc/for.n
@@ -0,0 +1,87 @@
+'\"
+'\" Copyright (c) 1993 The Regents of the University of California.
+'\" Copyright (c) 1994-1997 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH for n "" Tcl "Tcl Built-In Commands"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+for \- 'For' loop
+.SH SYNOPSIS
+\fBfor \fIstart test next body\fR
+.BE
+
+.SH DESCRIPTION
+.PP
+\fBFor\fR is a looping command, similar in structure to the C
+\fBfor\fR statement.  The \fIstart\fR, \fInext\fR, and
+\fIbody\fR arguments must be Tcl command strings, and \fItest\fR
+is an expression string.
+The \fBfor\fR command first invokes the Tcl interpreter to
+execute \fIstart\fR.  Then it repeatedly evaluates \fItest\fR as
+an expression; if the result is non-zero it invokes the Tcl
+interpreter on \fIbody\fR, then invokes the Tcl interpreter on \fInext\fR,
+then repeats the loop.  The command terminates when \fItest\fR evaluates
+to 0.  If a \fBcontinue\fR command is invoked within \fIbody\fR then
+any remaining commands in the current execution of \fIbody\fR are skipped;
+processing continues by invoking the Tcl interpreter on \fInext\fR, then
+evaluating \fItest\fR, and so on.  If a \fBbreak\fR command is invoked
+within \fIbody\fR
+or \fInext\fR,
+then the \fBfor\fR command will
+return immediately.
+The operation of \fBbreak\fR and \fBcontinue\fR are similar to the
+corresponding statements in C.
+\fBFor\fR returns an empty string.
+.PP
+Note: \fItest\fR should almost always be enclosed in braces.  If not,
+variable substitutions will be made before the \fBfor\fR
+command starts executing, which means that variable changes
+made by the loop body will not be considered in the expression.
+This is likely to result in an infinite loop.  If \fItest\fR is
+enclosed in braces, variable substitutions are delayed until the
+expression is evaluated (before
+each loop iteration), so changes in the variables will be visible.
+See below for an example:
+.SH EXAMPLES
+.PP
+Print a line for each of the integers from 0 to 9:
+.PP
+.CS
+\fBfor\fR {set x 0} {$x<10} {incr x} {
+    puts "x is $x"
+}
+.CE
+.PP
+Either loop infinitely or not at all because the expression being
+evaluated is actually the constant, or even generate an error!  The
+actual behaviour will depend on whether the variable \fIx\fR exists
+before the \fBfor\fR command is run and whether its value is a value
+that is less than or greater than/equal to ten, and this is because
+the expression will be substituted before the \fBfor\fR command is
+executed.
+.PP
+.CS
+\fBfor\fR {set x 0} $x<10 {incr x} {
+    puts "x is $x"
+}
+.CE
+.PP
+Print out the powers of two from 1 to 1024:
+.PP
+.CS
+\fBfor\fR {set x 1} {$x<=1024} {set x [expr {$x * 2}]} {
+    puts "x is $x"
+}
+.CE
+.SH "SEE ALSO"
+break(n), continue(n), foreach(n), while(n)
+.SH KEYWORDS
+boolean, for, iteration, loop
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/doc/foreach.n b/doc/foreach.n
new file mode 100644
index 0000000..89a11f6
--- /dev/null
+++ b/doc/foreach.n
@@ -0,0 +1,104 @@
+'\"
+'\" Copyright (c) 1993 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\" 
+.TH foreach n "" Tcl "Tcl Built-In Commands"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+foreach \- Iterate over all elements in one or more lists
+.SH SYNOPSIS
+\fBforeach \fIvarname list body\fR
+.br
+\fBforeach \fIvarlist1 list1\fR ?\fIvarlist2 list2 ...\fR? \fIbody\fR
+.BE
+
+.SH DESCRIPTION
+.PP
+The \fBforeach\fR command implements a loop where the loop
+variable(s) take on values from one or more lists.
+In the simplest case there is one loop variable, \fIvarname\fR,
+and one list, \fIlist\fR, that is a list of values to assign to \fIvarname\fR.
+The \fIbody\fR argument is a Tcl script.
+For each element of \fIlist\fR (in order
+from first to last), \fBforeach\fR assigns the contents of the
+element to \fIvarname\fR as if the \fBlindex\fR command had been used
+to extract the element, then calls the Tcl interpreter to execute
+\fIbody\fR.
+.PP
+In the general case there can be more than one value list
+(e.g., \fIlist1\fR and \fIlist2\fR),
+and each value list can be associated with a list of loop variables
+(e.g., \fIvarlist1\fR and \fIvarlist2\fR).
+During each iteration of the loop
+the variables of each \fIvarlist\fR are assigned
+consecutive values from the corresponding \fIlist\fR.
+Values in each \fIlist\fR are used in order from first to last,
+and each value is used exactly once.
+The total number of loop iterations is large enough to use
+up all the values from all the value lists.
+If a value list does not contain enough
+elements for each of its loop variables in each iteration,
+empty values are used for the missing elements.
+.PP
+The \fBbreak\fR and \fBcontinue\fR statements may be
+invoked inside \fIbody\fR, with the same effect as in the \fBfor\fR
+command.  \fBForeach\fR returns an empty string.
+.SH EXAMPLES
+.PP
+This loop prints every value in a list together with the square and
+cube of the value:
+.PP
+.CS
+'\" Maintainers: notice the tab hacking below!
+.ta 3i
+set values {1 3 5 7 2 4 6 8}	;# Odd numbers first, for fun!
+puts "Value\etSquare\etCube"	;# Neat-looking header
+\fBforeach\fR x $values {	;# Now loop and print...
+    puts " $x\et [expr {$x**2}]\et [expr {$x**3}]"
+}
+.CE
+.PP
+The following loop uses i and j as loop variables to iterate over
+pairs of elements of a single list.
+.PP
+.CS
+set x {}
+\fBforeach\fR {i j} {a b c d e f} {
+    lappend x $j $i
+}
+# The value of x is "b a d c f e"
+# There are 3 iterations of the loop.
+.CE
+.PP
+The next loop uses i and j to iterate over two lists in parallel.
+.PP
+.CS
+set x {}
+\fBforeach\fR i {a b c} j {d e f g} {
+    lappend x $i $j
+}
+# The value of x is "a d b e c f {} g"
+# There are 4 iterations of the loop.
+.CE
+.PP
+The two forms are combined in the following example.
+.PP
+.CS
+set x {}
+\fBforeach\fR i {a b c} {j k} {d e f g} {
+    lappend x $i $j $k
+}
+# The value of x is "a d e b f g c {} {}"
+# There are 3 iterations of the loop.
+.CE
+
+.SH "SEE ALSO"
+for(n), while(n), break(n), continue(n)
+
+.SH KEYWORDS
+foreach, iteration, list, loop
diff --git a/doc/format.n b/doc/format.n
new file mode 100644
index 0000000..ba044f2
--- /dev/null
+++ b/doc/format.n
@@ -0,0 +1,285 @@
+'\"
+'\" Copyright (c) 1993 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH format n 8.1 Tcl "Tcl Built-In Commands"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+format \- Format a string in the style of sprintf
+.SH SYNOPSIS
+\fBformat \fIformatString \fR?\fIarg arg ...\fR?
+.BE
+
+.SH INTRODUCTION
+.PP
+This command generates a formatted string in a fashion similar to the
+ANSI C \fBsprintf\fR procedure.
+\fIFormatString\fR indicates how to format the result, using
+\fB%\fR conversion specifiers as in \fBsprintf\fR, and the additional
+arguments, if any, provide values to be substituted into the result.
+The return value from \fBformat\fR is the formatted string.
+.SH "DETAILS ON FORMATTING"
+.PP
+The command operates by scanning \fIformatString\fR from left to right.
+Each character from the format string is appended to the result
+string unless it is a percent sign.
+If the character is a \fB%\fR then it is not copied to the result string.
+Instead, the characters following the \fB%\fR character are treated as
+a conversion specifier.
+The conversion specifier controls the conversion of the next successive
+\fIarg\fR to a particular format and the result is appended to
+the result string in place of the conversion specifier.
+If there are multiple conversion specifiers in the format string,
+then each one controls the conversion of one additional \fIarg\fR.
+The \fBformat\fR command must be given enough \fIarg\fRs to meet the needs
+of all of the conversion specifiers in \fIformatString\fR.
+.PP
+Each conversion specifier may contain up to six different parts:
+an XPG3 position specifier,
+a set of flags, a minimum field width, a precision, a size modifier,
+and a conversion character.
+Any of these fields may be omitted except for the conversion character.
+The fields that are present must appear in the order given above.
+The paragraphs below discuss each of these fields in turn.
+.SS "OPTIONAL POSITIONAL SPECIFIER"
+.PP
+If the \fB%\fR is followed by a decimal number and a \fB$\fR, as in
+.QW \fB%2$d\fR ,
+then the value to convert is not taken from the next sequential argument.
+Instead, it is taken from the argument indicated by the number,
+where 1 corresponds to the first \fIarg\fR.
+If the conversion specifier requires multiple arguments because
+of \fB*\fR characters in the specifier then
+successive arguments are used, starting with the argument
+given by the number.
+This follows the XPG3 conventions for positional specifiers.
+If there are any positional specifiers in \fIformatString\fR
+then all of the specifiers must be positional.
+.SS "OPTIONAL FLAGS"
+.PP
+The second portion of a conversion specifier may contain any of the
+following flag characters, in any order:
+.TP 10
+\fB\-\fR
+Specifies that the converted argument should be left-justified
+in its field (numbers are normally right-justified with leading
+spaces if needed).
+.TP 10
+\fB+\fR
+Specifies that a number should always be printed with a sign,
+even if positive.
+.TP 10
+\fIspace\fR
+Specifies that a space should be added to the beginning of the
+number if the first character is not a sign.
+.TP 10
+\fB0\fR
+Specifies that the number should be padded on the left with
+zeroes instead of spaces.
+.TP 10
+\fB#\fR
+Requests an alternate output form. For \fBo\fR and \fBO\fR
+conversions it guarantees that the first digit is always \fB0\fR.
+For \fBx\fR or \fBX\fR conversions, \fB0x\fR or \fB0X\fR (respectively)
+will be added to the beginning of the result unless it is zero.
+For \fBb\fR conversions, \fB0b\fR
+will be added to the beginning of the result unless it is zero.
+For all floating-point conversions (\fBe\fR, \fBE\fR, \fBf\fR,
+\fBg\fR, and \fBG\fR) it guarantees that the result always
+has a decimal point.
+For \fBg\fR and \fBG\fR conversions it specifies that
+trailing zeroes should not be removed.
+.SS "OPTIONAL FIELD WIDTH"
+.PP
+The third portion of a conversion specifier is a decimal number giving a
+minimum field width for this conversion.
+It is typically used to make columns line up in tabular printouts.
+If the converted argument contains fewer characters than the
+minimum field width then it will be padded so that it is as wide
+as the minimum field width.
+Padding normally occurs by adding extra spaces on the left of the
+converted argument, but the \fB0\fR and \fB\-\fR flags
+may be used to specify padding with zeroes on the left or with
+spaces on the right, respectively.
+If the minimum field width is specified as \fB*\fR rather than
+a number, then the next argument to the \fBformat\fR command
+determines the minimum field width; it must be an integer value.
+.SS "OPTIONAL PRECISION/BOUND"
+.PP
+The fourth portion of a conversion specifier is a precision,
+which consists of a period followed by a number.
+The number is used in different ways for different conversions.
+For \fBe\fR, \fBE\fR, and \fBf\fR conversions it specifies the number
+of digits to appear to the right of the decimal point.
+For \fBg\fR and \fBG\fR conversions it specifies the total number
+of digits to appear, including those on both sides of the decimal
+point (however, trailing zeroes after the decimal point will still
+be omitted unless the \fB#\fR flag has been specified).
+For integer conversions, it specifies a minimum number of digits
+to print (leading zeroes will be added if necessary).
+For \fBs\fR conversions it specifies the maximum number of characters to be
+printed; if the string is longer than this then the trailing characters will be dropped.
+If the precision is specified with \fB*\fR rather than a number
+then the next argument to the \fBformat\fR command determines the precision;
+it must be a numeric string.
+.SS "OPTIONAL SIZE MODIFIER"
+.PP
+The fifth part of a conversion specifier is a size modifier,
+which must be \fBll\fR, \fBh\fR, or \fBl\fR.
+If it is \fBll\fR it specifies that an integer value is taken
+without truncation for conversion to a formatted substring.
+If it is \fBh\fR it specifies that an integer value is
+truncated to a 16-bit range before converting.  This option is rarely useful.
+If it is \fBl\fR it specifies that the integer value is
+truncated to the same range as that produced by the \fBwide()\fR
+function of the \fBexpr\fR command (at least a 64-bit range).
+If neither \fBh\fR nor \fBl\fR are present, the integer value is
+truncated to the same range as that produced by the \fBint()\fR
+function of the \fBexpr\fR command (at least a 32-bit range, but
+determined by the value of the \fBwordSize\fR element of the
+\fBtcl_platform\fR array).
+.SS "MANDATORY CONVERSION TYPE"
+.PP
+The last thing in a conversion specifier is an alphabetic character
+that determines what kind of conversion to perform.
+The following conversion characters are currently supported:
+.TP 10
+\fBd\fR
+Convert integer to signed decimal string.
+.TP 10
+\fBu\fR
+Convert integer to unsigned decimal string.
+.TP 10
+\fBi\fR
+Convert integer to signed decimal string (equivalent to \fBd\fR).
+.TP 10
+\fBo\fR
+Convert integer to unsigned octal string.
+.TP 10
+\fBx\fR or \fBX\fR
+Convert integer to unsigned hexadecimal string, using digits
+.QW 0123456789abcdef
+for \fBx\fR and
+.QW 0123456789ABCDEF
+for \fBX\fR).
+.TP 10
+\fBb\fR
+Convert integer to binary string, using digits 0 and 1.
+.TP 10
+\fBc\fR
+Convert integer to the Unicode character it represents.
+.TP 10
+\fBs\fR
+No conversion; just insert string.
+.TP 10
+\fBf\fR
+Convert number to signed decimal string of
+the form \fIxx.yyy\fR, where the number of \fIy\fR's is determined by
+the precision (default: 6).
+If the precision is 0 then no decimal point is output.
+.TP 10
+\fBe\fR or \fBE\fR
+Convert number to scientific notation in the
+form \fIx.yyy\fBe\(+-\fIzz\fR, where the number of \fIy\fR's is determined
+by the precision (default: 6).
+If the precision is 0 then no decimal point is output.
+If the \fBE\fR form is used then \fBE\fR is
+printed instead of \fBe\fR.
+.TP 10
+\fBg\fR or \fBG\fR
+If the exponent is less than \-4 or greater than or equal to the
+precision, then convert number as for \fB%e\fR or
+\fB%E\fR.
+Otherwise convert as for \fB%f\fR.
+Trailing zeroes and a trailing decimal point are omitted.
+.TP 10
+\fB%\fR
+No conversion: just insert \fB%\fR.
+.SH "DIFFERENCES FROM ANSI SPRINTF"
+.PP
+The behavior of the format command is the same as the
+ANSI C \fBsprintf\fR procedure except for the following
+differences:
+.IP [1]
+Tcl guarantees that it will be working with UNICODE characters.
+.IP [2]
+\fB%p\fR and \fB%n\fR specifiers are not supported.
+.IP [3]
+For \fB%c\fR conversions the argument must be an integer value,
+which will then be converted to the corresponding character value.
+.IP [4]
+The size modifiers are ignored when formatting floating-point values.
+The \fBll\fR modifier has no \fBsprintf\fR counterpart.
+The \fBb\fR specifier has no \fBsprintf\fR counterpart.
+.SH EXAMPLES
+.PP
+Convert the numeric value of a UNICODE character to the character
+itself:
+.PP
+.CS
+set value 120
+set char [\fBformat\fR %c $value]
+.CE
+.PP
+Convert the output of \fBtime\fR into seconds to an accuracy of
+hundredths of a second:
+.PP
+.CS
+set us [lindex [time $someTclCode] 0]
+puts [\fBformat\fR "%.2f seconds to execute" [expr {$us / 1e6}]]
+.CE
+.PP
+Create a packed X11 literal color specification:
+.PP
+.CS
+# Each color-component should be in range (0..255)
+set color [\fBformat\fR "#%02x%02x%02x" $r $g $b]
+.CE
+.PP
+Use XPG3 format codes to allow reordering of fields (a technique that
+is often used in localized message catalogs; see \fBmsgcat\fR) without
+reordering the data values passed to \fBformat\fR:
+.PP
+.CS
+set fmt1 "Today, %d shares in %s were bought at $%.2f each"
+puts [\fBformat\fR $fmt1 123 "Global BigCorp" 19.37]
+
+set fmt2 "Bought %2\e$s equity ($%3$.2f x %1\e$d) today"
+puts [\fBformat\fR $fmt2 123 "Global BigCorp" 19.37]
+.CE
+.PP
+Print a small table of powers of three:
+.PP
+.CS
+# Set up the column widths
+set w1 5
+set w2 10
+
+# Make a nice header (with separator) for the table first
+set sep +-[string repeat - $w1]-+-[string repeat - $w2]-+
+puts $sep
+puts [\fBformat\fR "| %-*s | %-*s |" $w1 "Index" $w2 "Power"]
+puts $sep
+
+# Print the contents of the table
+set p 1
+for {set i 0} {$i<=20} {incr i} {
+    puts [\fBformat\fR "| %*d | %*ld |" $w1 $i $w2 $p]
+    set p [expr {wide($p) * 3}]
+}
+
+# Finish off by printing the separator again
+puts $sep
+.CE
+.SH "SEE ALSO"
+scan(n), sprintf(3), string(n)
+.SH KEYWORDS
+conversion specifier, format, sprintf, string, substitution
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/doc/gets.n b/doc/gets.n
new file mode 100644
index 0000000..0150f29
--- /dev/null
+++ b/doc/gets.n
@@ -0,0 +1,71 @@
+'\"
+'\" Copyright (c) 1993 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\" 
+.TH gets n 7.5 Tcl "Tcl Built-In Commands"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+gets \- Read a line from a channel
+.SH SYNOPSIS
+\fBgets \fIchannelId\fR ?\fIvarName\fR?
+.BE
+
+.SH DESCRIPTION
+.PP
+This command reads the next line from \fIchannelId\fR, returns everything
+in the line up to (but not including) the end-of-line character(s), and
+discards the end-of-line character(s).
+.PP
+\fIChannelId\fR must be an identifier for an open channel such as the
+Tcl standard input channel (\fBstdin\fR), the return value from an
+invocation of \fBopen\fR or \fBsocket\fR, or the result of a channel
+creation command provided by a Tcl extension. The channel must have
+been opened for input.
+.PP
+If \fIvarName\fR is omitted the line is returned as the result of the
+command.
+If \fIvarName\fR is specified then the line is placed in the variable by
+that name and the return value is a count of the number of characters
+returned.
+.PP
+If end of file occurs while scanning for an end of
+line, the command returns whatever input is available up to the end of file.
+If \fIchannelId\fR is in non-blocking mode and there is not a full
+line of input available, the command returns an empty string and
+does not consume any input.
+If \fIvarName\fR is specified and an empty string is returned in
+\fIvarName\fR because of end-of-file or because of insufficient
+data in non-blocking mode, then the return count is -1.
+Note that if \fIvarName\fR is not specified then the end-of-file
+and no-full-line-available cases can
+produce the same results as if there were an input line consisting
+only of the end-of-line character(s).
+The \fBeof\fR and \fBfblocked\fR commands can be used to distinguish
+these three cases.
+.SH "EXAMPLE"
+This example reads a file one line at a time and prints it out with
+the current line number attached to the start of each line.
+.PP
+.CS
+set chan [open "some.file.txt"]
+set lineNumber 0
+while {[\fBgets\fR $chan line] >= 0} {
+    puts "[incr lineNumber]: $line"
+}
+close $chan
+.CE
+
+.SH "SEE ALSO"
+file(n), eof(n), fblocked(n), Tcl_StandardChannels(3)
+
+.SH KEYWORDS
+blocking, channel, end of file, end of line, line, non-blocking, read
+'\" Local Variables:
+'\" mode: nroff
+'\" fill-column: 78
+'\" End:
diff --git a/doc/glob.n b/doc/glob.n
new file mode 100644
index 0000000..a2cbce2
--- /dev/null
+++ b/doc/glob.n
@@ -0,0 +1,267 @@
+'\"
+'\" Copyright (c) 1993 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+.TH glob n 8.3 Tcl "Tcl Built-In Commands"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+glob \- Return names of files that match patterns
+.SH SYNOPSIS
+\fBglob \fR?\fIswitches\fR? ?\fIpattern ...\fR?
+.BE
+.SH DESCRIPTION
+.PP
+This command performs file name
+.QW globbing
+in a fashion similar to
+the csh shell or bash shell.
+It returns a list of the files whose names match any
+of the \fIpattern\fR arguments. No particular order is guaranteed
+in the list, so if a sorted list is required the caller should use
+\fBlsort\fR.
+.SS OPTIONS
+.PP
+If the initial arguments to \fBglob\fR start with \fB\-\fR then
+they are treated as switches. The following switches are
+currently supported:
+.TP
+\fB\-directory\fR \fIdirectory\fR
+.
+Search for files which match the given patterns starting in the given
+\fIdirectory\fR. This allows searching of directories whose name
+contains glob-sensitive characters without the need to quote such
+characters explicitly. This option may not be used in conjunction with
+\fB\-path\fR, which is used to allow searching for complete file paths
+whose names may contain glob-sensitive characters.
+.TP
+\fB\-join\fR
+.
+The remaining pattern arguments, after option processing, are treated
+as a single pattern obtained by joining the arguments with directory
+separators.
+.TP
+\fB\-nocomplain\fR
+.
+Allows an empty list to be returned without error; without this
+switch an error is returned if the result list would be empty.
+.TP
+\fB\-path\fR \fIpathPrefix\fR
+.
+Search for files with the given \fIpathPrefix\fR where the rest of the name
+matches the given patterns. This allows searching for files with names
+similar to a given file (as opposed to a directory) even when the names
+contain glob-sensitive
+characters. This option may not be used in conjunction with
+\fB\-directory\fR. For example, to find all files with the same root name
+as $path, but differing extensions, you should use
+.QW "\fBglob \-path [file rootname $path] .*\fR"
+which will work even if \fB$path\fR contains
+numerous glob-sensitive characters.
+.TP
+\fB\-tails\fR
+.
+Only return the part of each file found which follows the last directory
+named in any \fB\-directory\fR or \fB\-path\fR path specification.
+Thus
+.QW "\fBglob \-tails \-directory $dir *\fR"
+is equivalent to
+.QW "\fBset pwd [pwd]; cd $dir; glob *; cd $pwd\fR" .
+For \fB\-path\fR specifications, the returned names will include the last
+path segment, so
+.QW "\fBglob \-tails \-path [file rootname ~/foo.tex] .*\fR"
+will return paths like \fBfoo.aux foo.bib foo.tex\fR etc.
+.TP
+\fB\-types\fR \fItypeList\fR
+.
+Only list files or directories which match \fItypeList\fR, where the items
+in the list have two forms. The first form is like the \-type option of
+the Unix find command:
+\fIb\fR (block special file),
+\fIc\fR (character special file),
+\fId\fR (directory),
+\fIf\fR (plain file),
+\fIl\fR (symbolic link),
+\fIp\fR (named pipe),
+or \fIs\fR (socket), where multiple types may be specified in the list.
+\fBGlob\fR will return all files which match at least one of the types given.
+Note that symbolic links will be returned both if \fB\-types l\fR is given,
+or if the target of a link matches the requested type. So, a link to
+a directory will be returned if \fB\-types d\fR was specified.
+.RS
+.PP
+The second form specifies types where all the types given must match.
+These are \fIr\fR, \fIw\fR, \fIx\fR as file permissions, and
+\fIreadonly\fR, \fIhidden\fR as special permission cases. On the
+Macintosh, MacOS types and creators are also supported, where any item
+which is four characters long is assumed to be a MacOS type
+(e.g. \fBTEXT\fR). Items which are of the form \fI{macintosh type XXXX}\fR
+or \fI{macintosh creator XXXX}\fR will match types or creators
+respectively. Unrecognized types, or specifications of multiple MacOS
+types/creators will signal an error.
+.PP
+The two forms may be mixed, so \fB\-types {d f r w}\fR will find all
+regular files OR directories that have both read AND write permissions.
+The following are equivalent:
+.PP
+.CS
+\fBglob \-type d *\fR
+\fBglob */\fR
+.CE
+.PP
+except that the first case doesn't return the trailing
+.QW /
+and is more platform independent.
+.RE
+.TP
+\fB\-\|\-\fR
+.
+Marks the end of switches. The argument following this one will
+be treated as a \fIpattern\fR even if it starts with a \fB\-\fR.
+.SS "GLOBBING PATTERNS"
+.PP
+The \fIpattern\fR arguments may contain any of the following
+special characters, which are a superset of those supported by
+\fBstring match\fR:
+.TP 10
+\fB?\fR
+.
+Matches any single character.
+.TP 10
+\fB*\fR
+.
+Matches any sequence of zero or more characters.
+.TP 10
+\fB[\fIchars\fB]\fR
+.
+Matches any single character in \fIchars\fR. If \fIchars\fR
+contains a sequence of the form \fIa\fB\-\fIb\fR then any
+character between \fIa\fR and \fIb\fR (inclusive) will match.
+.TP 10
+\fB\e\fIx\fR
+.
+Matches the character \fIx\fR.
+.TP 10
+\fB{\fIa\fB,\fIb\fB,\fI...\fR}
+.
+Matches any of the sub-patterns \fIa\fR, \fIb\fR, etc.
+.PP
+On Unix, as with csh, a
+.QW . \|
+at the beginning of a file's name or just after a
+.QW /
+must be matched explicitly or with a {} construct, unless the
+\fB\-types hidden\fR flag is given (since
+.QW . \|
+at the beginning of a file's name indicates that it is hidden). On
+other platforms, files beginning with a
+.QW . \|
+are handled no differently to any others, except the special directories
+.QW . \|
+and
+.QW .. \|
+which must be matched explicitly (this is to avoid a recursive pattern like
+.QW "glob \-join * * * *"
+from recursing up the directory hierarchy as well as down). In addition, all
+.QW /
+characters must be matched explicitly.
+.LP
+If the first character in a \fIpattern\fR is
+.QW ~
+then it refers to the home directory for the user whose name follows the
+.QW ~ .
+If the
+.QW ~
+is followed immediately by
+.QW /
+then the value of the HOME environment variable is used.
+.PP
+The \fBglob\fR command differs from csh globbing in two ways.
+First, it does not sort its result list (use the \fBlsort\fR
+command if you want the list sorted).
+Second, \fBglob\fR only returns the names of files that actually
+exist; in csh no check for existence is made unless a pattern
+contains a ?, *, or [] construct.
+.LP
+When the \fBglob\fR command returns relative paths whose filenames
+start with a tilde
+.QW ~
+(for example through \fBglob *\fR or \fBglob \-tails\fR, the returned
+list will not quote the tilde with
+.QW ./ .
+This means care must be taken if those names are later to
+be used with \fBfile join\fR, to avoid them being interpreted as
+absolute paths pointing to a given user's home directory.
+.SH "WINDOWS PORTABILITY ISSUES"
+.PP
+For Windows UNC names, the servername and sharename components of the path
+may not contain ?, *, or [] constructs. On Windows NT, if \fIpattern\fR is
+of the form
+.QW \fB~\fIusername\fB@\fIdomain\fR ,
+it refers to the home
+directory of the user whose account information resides on the specified NT
+domain server. Otherwise, user account information is obtained from
+the local computer.
+.PP
+Since the backslash character has a special meaning to the glob
+command, glob patterns containing Windows style path separators need
+special care. The pattern
+.QW \fIC:\e\efoo\e\e*\fR
+is interpreted as
+.QW \fIC:\efoo\e*\fR
+where
+.QW \fI\ef\fR
+will match the single character
+.QW \fIf\fR
+and
+.QW \fI\e*\fR
+will match the single character
+.QW \fI*\fR
+and will not be
+interpreted as a wildcard character. One solution to this problem is
+to use the Unix style forward slash as a path separator. Windows style
+paths can be converted to Unix style paths with the command
+.QW "\fBfile join\fR \fB$path\fR"
+or
+.QW "\fBfile normalize\fR \fB$path\fR" .
+.SH EXAMPLES
+.PP
+Find all the Tcl files in the current directory:
+.PP
+.CS
+\fBglob\fR *.tcl
+.CE
+.PP
+Find all the Tcl files in the user's home directory, irrespective of
+what the current directory is:
+.PP
+.CS
+\fBglob\fR \-directory ~ *.tcl
+.CE
+.PP
+Find all subdirectories of the current directory:
+.PP
+.CS
+\fBglob\fR \-type d *
+.CE
+.PP
+Find all files whose name contains an
+.QW a ,
+a
+.QW b
+or the sequence
+.QW cde :
+.PP
+.CS
+\fBglob\fR \-type f *{a,b,cde}*
+.CE
+.SH "SEE ALSO"
+file(n)
+.SH KEYWORDS
+exist, file, glob, pattern
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/doc/global.n b/doc/global.n
new file mode 100644
index 0000000..9848817
--- /dev/null
+++ b/doc/global.n
@@ -0,0 +1,58 @@
+'\"
+'\" Copyright (c) 1993 The Regents of the University of California.
+'\" Copyright (c) 1994-1997 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH global n "" Tcl "Tcl Built-In Commands"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+global \- Access global variables
+.SH SYNOPSIS
+\fBglobal \fR?\fIvarname ...\fR?
+.BE
+.SH DESCRIPTION
+.PP
+This command has no effect unless executed in the context of a proc body.
+If the \fBglobal\fR command is executed in the context of a proc body, it
+creates local variables linked to the corresponding global variables (though
+these linked variables, like those created by \fBupvar\fR, are not included
+in the list returned by \fBinfo locals\fR).
+.PP
+If \fIvarname\fR contains namespace qualifiers, the local variable's name is
+the unqualified name of the global variable, as determined by the
+\fBnamespace tail\fR command.
+.PP
+\fIvarname\fR is always treated as the name of a variable, not an
+array element.  An error is returned if the name looks like an array element,
+such as \fBa(b)\fR.
+.SH EXAMPLES
+.PP
+This procedure sets the namespace variable \fI::a::x\fR
+.PP
+.CS
+proc reset {} {
+    \fBglobal\fR a::x
+    set x 0
+}
+.CE
+.PP
+This procedure accumulates the strings passed to it in a global
+buffer, separated by newlines.  It is useful for situations when you
+want to build a message piece-by-piece (as if with \fBputs\fR) but
+send that full message in a single piece (e.g. over a connection
+opened with \fBsocket\fR or as part of a counted HTTP response).
+.PP
+.CS
+proc accum {string} {
+    \fBglobal\fR accumulator
+    append accumulator $string \en
+}
+.CE
+.SH "SEE ALSO"
+namespace(n), upvar(n), variable(n)
+.SH KEYWORDS
+global, namespace, procedure, variable
diff --git a/doc/history.n b/doc/history.n
new file mode 100644
index 0000000..e1f9781
--- /dev/null
+++ b/doc/history.n
@@ -0,0 +1,102 @@
+'\"
+'\" Copyright (c) 1993 The Regents of the University of California.
+'\" Copyright (c) 1994-1997 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\" 
+.TH history n "" Tcl "Tcl Built-In Commands"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+history \- Manipulate the history list
+.SH SYNOPSIS
+\fBhistory \fR?\fIoption\fR? ?\fIarg arg ...\fR?
+.BE
+.SH DESCRIPTION
+.PP
+The \fBhistory\fR command performs one of several operations related to
+recently-executed commands recorded in a history list.  Each of
+these recorded commands is referred to as an
+.QW event .
+When specifying an event to the \fBhistory\fR command, the following
+forms may be used:
+.IP [1]
+A number:  if positive, it refers to the event with
+that number (all events are numbered starting at 1).  If the number
+is negative, it selects an event relative to the current event
+(\fB\-1\fR refers to the previous event, \fB\-2\fR to the one before that, and
+so on).  Event \fB0\fR refers to the current event.
+.IP [2]
+A string:  selects the most recent event that matches the string.
+An event is considered to match the string either if the string is
+the same as the first characters of the event, or if the string
+matches the event in the sense of the \fBstring match\fR command.
+.PP
+The \fBhistory\fR command can take any of the following forms:
+.TP
+\fBhistory\fR
+Same
+as \fBhistory info\fR, described below.
+.TP
+\fBhistory add\fI command \fR?\fBexec\fR?
+Adds the \fIcommand\fR argument to the history list as a new event.  If
+\fBexec\fR is specified (or abbreviated) then the command is also
+executed and its result is returned.  If \fBexec\fR is not specified
+then an empty string is returned as result.
+.TP
+\fBhistory change\fI newValue\fR ?\fIevent\fR?
+Replaces the value recorded for an event with \fInewValue\fR.  \fIEvent\fR
+specifies the event to replace, and
+defaults to the \fIcurrent\fR event (not event \fB\-1\fR).  This command
+is intended for use in commands that implement new forms of history
+substitution and wish to replace the current event (which invokes the
+substitution) with the command created through substitution.  The return
+value is an empty string.
+.TP
+\fBhistory clear\fR
+Erase the history list.  The current keep limit is retained.
+The history event numbers are reset.
+.TP
+\fBhistory event\fR ?\fIevent\fR?
+Returns the value of the event given by \fIevent\fR.  \fIEvent\fR
+defaults to \fB\-1\fR.
+.TP
+\fBhistory info \fR?\fIcount\fR?
+Returns a formatted string (intended for humans to read) giving
+the event number and contents for each of the events in the history
+list except the current event.  If \fIcount\fR is specified
+then only the most recent \fIcount\fR events are returned.
+.TP
+\fBhistory keep \fR?\fIcount\fR?
+This command may be used to change the size of the history list to
+\fIcount\fR events.  Initially, 20 events are retained in the history
+list.  If \fIcount\fR is not specified, the current keep limit is returned.
+.TP
+\fBhistory nextid\fR
+Returns the number of the next event to be recorded
+in the history list.  It is useful for things like printing the
+event number in command-line prompts.
+.TP
+\fBhistory redo \fR?\fIevent\fR?
+Re-executes the command indicated by \fIevent\fR and returns its result.
+\fIEvent\fR defaults to \fB\-1\fR.  This command results in history
+revision:  see below for details.
+.SH "HISTORY REVISION"
+.PP
+Pre-8.0 Tcl had a complex history revision mechanism.
+The current mechanism is more limited, and the old
+history operations \fBsubstitute\fR and \fBwords\fR have been removed.
+(As a consolation, the \fBclear\fR operation was added.)
+.PP
+The history option \fBredo\fR results in much simpler
+.QW "history revision" .
+When this option is invoked then the most recent event
+is modified to eliminate the history command and replace it with
+the result of the history command.
+If you want to redo an event without modifying history, then use
+the \fBevent\fR operation to retrieve some event,
+and the \fBadd\fR operation to add it to history and execute it.
+.SH KEYWORDS
+event, history, record
diff --git a/doc/http.n b/doc/http.n
new file mode 100644
index 0000000..80ae044
--- /dev/null
+++ b/doc/http.n
@@ -0,0 +1,647 @@
+'\"
+'\" Copyright (c) 1995-1997 Sun Microsystems, Inc.
+'\" Copyright (c) 1998-2000 by Ajuba Solutions.
+'\" Copyright (c) 2004 ActiveState Corporation.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH "http" n 2.7 http "Tcl Bundled Packages"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+http \- Client-side implementation of the HTTP/1.1 protocol
+.SH SYNOPSIS
+\fBpackage require http ?2.7?\fR
+.\" See Also -useragent option documentation in body!
+.sp
+\fB::http::config ?\fI\-option value\fR ...?
+.sp
+\fB::http::geturl \fIurl\fR ?\fI\-option value\fR ...?
+.sp
+\fB::http::formatQuery\fR \fIkey value\fR ?\fIkey value\fR ...?
+.sp
+\fB::http::reset\fR \fItoken\fR ?\fIwhy\fR?
+.sp
+\fB::http::wait \fItoken\fR
+.sp
+\fB::http::status \fItoken\fR
+.sp
+\fB::http::size \fItoken\fR
+.sp
+\fB::http::code \fItoken\fR
+.sp
+\fB::http::ncode \fItoken\fR
+.sp
+\fB::http::meta \fItoken\fR
+.sp
+\fB::http::data \fItoken\fR
+.sp
+\fB::http::error \fItoken\fR
+.sp
+\fB::http::cleanup \fItoken\fR
+.sp
+\fB::http::register \fIproto port command\fR
+.sp
+\fB::http::unregister \fIproto\fR
+.BE
+.SH DESCRIPTION
+.PP
+The \fBhttp\fR package provides the client side of the HTTP/1.1
+protocol, as defined in RFC 2616.
+The package implements the GET, POST, and HEAD operations
+of HTTP/1.1.  It allows configuration of a proxy host to get through
+firewalls.  The package is compatible with the \fBSafesock\fR security
+policy, so it can be used by untrusted applets to do URL fetching from
+a restricted set of hosts. This package can be extended to support
+additional HTTP transport protocols, such as HTTPS, by providing
+a custom \fBsocket\fR command, via \fB::http::register\fR.
+.PP
+The \fB::http::geturl\fR procedure does a HTTP transaction.
+Its \fIoptions \fR determine whether a GET, POST, or HEAD transaction
+is performed.
+The return value of \fB::http::geturl\fR is a token for the transaction.
+The value is also the name of an array in the ::http namespace
+that contains state information about the transaction.  The elements
+of this array are described in the \fBSTATE ARRAY\fR section.
+.PP
+If the \fB\-command\fR option is specified, then
+the HTTP operation is done in the background.
+\fB::http::geturl\fR returns immediately after generating the
+HTTP request and the callback is invoked
+when the transaction completes.  For this to work, the Tcl event loop
+must be active.  In Tk applications this is always true.  For pure-Tcl
+applications, the caller can use \fB::http::wait\fR after calling
+\fB::http::geturl\fR to start the event loop.
+.SH COMMANDS
+.TP
+\fB::http::config\fR ?\fIoptions\fR?
+.
+The \fB::http::config\fR command is used to set and query the name of the
+proxy server and port, and the User-Agent name used in the HTTP
+requests.  If no options are specified, then the current configuration
+is returned.  If a single argument is specified, then it should be one
+of the flags described below.  In this case the current value of
+that setting is returned.  Otherwise, the options should be a set of
+flags and values that define the configuration:
+.RS
+.TP
+\fB\-accept\fR \fImimetypes\fR
+.
+The Accept header of the request.  The default is */*, which means that
+all types of documents are accepted.  Otherwise you can supply a
+comma-separated list of mime type patterns that you are
+willing to receive.  For example,
+.QW "image/gif, image/jpeg, text/*" .
+.TP
+\fB\-proxyhost\fR \fIhostname\fR
+.
+The name of the proxy host, if any.  If this value is the
+empty string, the URL host is contacted directly.
+.TP
+\fB\-proxyport\fR \fInumber\fR
+.
+The proxy port number.
+.TP
+\fB\-proxyfilter\fR \fIcommand\fR
+.
+The command is a callback that is made during
+\fB::http::geturl\fR
+to determine if a proxy is required for a given host.  One argument, a
+host name, is added to \fIcommand\fR when it is invoked.  If a proxy
+is required, the callback should return a two-element list containing
+the proxy server and proxy port.  Otherwise the filter should return
+an empty list.  The default filter returns the values of the
+\fB\-proxyhost\fR and \fB\-proxyport\fR settings if they are
+non-empty.
+.TP
+\fB\-urlencoding\fR \fIencoding\fR
+.
+The \fIencoding\fR used for creating the x-url-encoded URLs with
+\fB::http::formatQuery\fR.  The default is \fButf-8\fR, as specified by RFC
+2718.  Prior to http 2.5 this was unspecified, and that behavior can be
+returned by specifying the empty string (\fB{}\fR), although
+\fIiso8859-1\fR is recommended to restore similar behavior but without the
+\fB::http::formatQuery\fR throwing an error processing non-latin-1
+characters.
+.TP
+\fB\-useragent\fR \fIstring\fR
+.
+The value of the User-Agent header in the HTTP request.  The default is
+.QW "\fBTcl http client package 2.7\fR" .
+.RE
+.TP
+\fB::http::geturl\fR \fIurl\fR ?\fIoptions\fR?
+.
+The \fB::http::geturl\fR command is the main procedure in the package.
+The \fB\-query\fR option causes a POST operation and
+the \fB\-validate\fR option causes a HEAD operation;
+otherwise, a GET operation is performed.  The \fB::http::geturl\fR command
+returns a \fItoken\fR value that can be used to get
+information about the transaction.  See the \fBSTATE ARRAY\fR and
+\fBERRORS\fR section for
+details.  The \fB::http::geturl\fR command blocks until the operation
+completes, unless the \fB\-command\fR option specifies a callback
+that is invoked when the HTTP transaction completes.
+\fB::http::geturl\fR takes several options:
+.RS
+.TP
+\fB\-binary\fR \fIboolean\fR
+.
+Specifies whether to force interpreting the URL data as binary.  Normally
+this is auto-detected (anything not beginning with a \fBtext\fR content
+type or whose content encoding is \fBgzip\fR or \fBcompress\fR is
+considered binary data).
+.TP
+\fB\-blocksize\fR \fIsize\fR
+.
+The block size used when reading the URL.
+At most \fIsize\fR bytes are read at once.  After each block, a call to the
+\fB\-progress\fR callback is made (if that option is specified).
+.TP
+\fB\-channel\fR \fIname\fR
+.
+Copy the URL contents to channel \fIname\fR instead of saving it in
+\fBstate(body)\fR.
+.TP
+\fB\-command\fR \fIcallback\fR
+.
+Invoke \fIcallback\fR after the HTTP transaction completes.
+This option causes \fB::http::geturl\fR to return immediately.
+The \fIcallback\fR gets an additional argument that is the \fItoken\fR returned
+from \fB::http::geturl\fR. This token is the name of an array that is
+described in the \fBSTATE ARRAY\fR section.  Here is a template for the
+callback:
+.RS
+.PP
+.CS
+proc httpCallback {token} {
+    upvar #0 $token state
+    # Access state as a Tcl array
+}
+.CE
+.RE
+.TP
+\fB\-handler\fR \fIcallback\fR
+.
+Invoke \fIcallback\fR whenever HTTP data is available; if present, nothing
+else will be done with the HTTP data.  This procedure gets two additional
+arguments: the socket for the HTTP data and the \fItoken\fR returned from
+\fB::http::geturl\fR.  The token is the name of a global array that is
+described in the \fBSTATE ARRAY\fR section.  The procedure is expected
+to return the number of bytes read from the socket.  Here is a
+template for the callback:
+.RS
+.PP
+.CS
+proc httpHandlerCallback {socket token} {
+    upvar #0 $token state
+    # Access socket, and state as a Tcl array
+    # For example...
+    ...
+    set data [read $socket 1000]
+    set nbytes [string length $data]
+    ...
+    return $nbytes
+}
+.CE
+.RE
+.TP
+\fB\-headers\fR \fIkeyvaluelist\fR
+.
+This option is used to add headers not already specified
+by \fB::http::config\fR to the HTTP request.  The
+\fIkeyvaluelist\fR argument must be a list with an even number of
+elements that alternate between keys and values.  The keys become
+header field names.  Newlines are stripped from the values so the
+header cannot be corrupted.  For example, if \fIkeyvaluelist\fR is
+\fBPragma no-cache\fR then the following header is included in the
+HTTP request:
+.RS
+.PP
+.CS
+Pragma: no-cache
+.CE
+.RE
+.TP
+\fB\-keepalive\fR \fIboolean\fR
+.
+If true, attempt to keep the connection open for servicing
+multiple requests.  Default is 0.
+.TP
+\fB\-method\fR \fItype\fR
+.
+Force the HTTP request method to \fItype\fR. \fB::http::geturl\fR will
+auto-select GET, POST or HEAD based on other options, but this option
+enables choices like PUT and DELETE for webdav support.
+.TP
+\fB\-myaddr\fR \fIaddress\fR
+.
+Pass an specific local address to the underlying \fBsocket\fR call in case
+multiple interfaces are available.
+.TP
+\fB\-progress\fR \fIcallback\fR
+.
+The \fIcallback\fR is made after each transfer of data from the URL.
+The callback gets three additional arguments: the \fItoken\fR from
+\fB::http::geturl\fR, the expected total size of the contents from the
+\fBContent-Length\fR meta-data, and the current number of bytes
+transferred so far.  The expected total size may be unknown, in which
+case zero is passed to the callback.  Here is a template for the
+progress callback:
+.RS
+.PP
+.CS
+proc httpProgress {token total current} {
+    upvar #0 $token state
+}
+.CE
+.RE
+.TP
+\fB\-protocol\fR \fIversion\fR
+.
+Select the HTTP protocol version to use. This should be 1.0 or 1.1 (the
+default). Should only be necessary for servers that do not understand or
+otherwise complain about HTTP/1.1.
+.TP
+\fB\-query\fR \fIquery\fR
+.
+This flag causes \fB::http::geturl\fR to do a POST request that passes the
+\fIquery\fR to the server. The \fIquery\fR must be an x-url-encoding
+formatted query.  The \fB::http::formatQuery\fR procedure can be used to
+do the formatting.
+.TP
+\fB\-queryblocksize\fR \fIsize\fR
+.
+The block size used when posting query data to the URL.
+At most
+\fIsize\fR
+bytes are written at once.  After each block, a call to the
+\fB\-queryprogress\fR
+callback is made (if that option is specified).
+.TP
+\fB\-querychannel\fR \fIchannelID\fR
+.
+This flag causes \fB::http::geturl\fR to do a POST request that passes the
+data contained in \fIchannelID\fR to the server. The data contained in
+\fIchannelID\fR must be an x-url-encoding
+formatted query unless the \fB\-type\fR option below is used.
+If a Content-Length header is not specified via the \fB\-headers\fR options,
+\fB::http::geturl\fR attempts to determine the size of the post data
+in order to create that header.  If it is
+unable to determine the size, it returns an error.
+.TP
+\fB\-queryprogress\fR \fIcallback\fR
+.
+The \fIcallback\fR is made after each transfer of data to the URL
+(i.e. POST) and acts exactly like the \fB\-progress\fR option (the
+callback format is the same).
+.TP
+\fB\-strict\fR \fIboolean\fR
+.
+Whether to enforce RFC 3986 URL validation on the request.  Default is 1.
+.TP
+\fB\-timeout\fR \fImilliseconds\fR
+.
+If \fImilliseconds\fR is non-zero, then \fB::http::geturl\fR sets up a timeout
+to occur after the specified number of milliseconds.
+A timeout results in a call to \fB::http::reset\fR and to
+the \fB\-command\fR callback, if specified.
+The return value of \fB::http::status\fR is \fBtimeout\fR
+after a timeout has occurred.
+.TP
+\fB\-type\fR \fImime-type\fR
+.
+Use \fImime-type\fR as the \fBContent-Type\fR value, instead of the
+default value (\fBapplication/x-www-form-urlencoded\fR) during a
+POST operation.
+.TP
+\fB\-validate\fR \fIboolean\fR
+.
+If \fIboolean\fR is non-zero, then \fB::http::geturl\fR does an HTTP HEAD
+request.  This request returns meta information about the URL, but the
+contents are not returned.  The meta information is available in the
+\fBstate(meta) \fR variable after the transaction.  See the
+\fBSTATE ARRAY\fR section for details.
+.RE
+.TP
+\fB::http::formatQuery\fR \fIkey value\fR ?\fIkey value\fR ...?
+.
+This procedure does x-url-encoding of query data.  It takes an even
+number of arguments that are the keys and values of the query.  It
+encodes the keys and values, and generates one string that has the
+proper & and = separators.  The result is suitable for the
+\fB\-query\fR value passed to \fB::http::geturl\fR.
+.TP
+\fB::http::reset\fR \fItoken\fR ?\fIwhy\fR?
+.
+This command resets the HTTP transaction identified by \fItoken\fR, if any.
+This sets the \fBstate(status)\fR value to \fIwhy\fR, which defaults to
+\fBreset\fR, and then calls the registered \fB\-command\fR callback.
+.TP
+\fB::http::wait\fR \fItoken\fR
+.
+This is a convenience procedure that blocks and waits for the
+transaction to complete.  This only works in trusted code because it
+uses \fBvwait\fR.  Also, it is not useful for the case where
+\fB::http::geturl\fR is called \fIwithout\fR the \fB\-command\fR option
+because in this case the \fB::http::geturl\fR call does not return
+until the HTTP transaction is complete, and thus there is nothing to
+wait for.
+.TP
+\fB::http::data\fR \fItoken\fR
+.
+This is a convenience procedure that returns the \fBbody\fR element
+(i.e., the URL data) of the state array.
+.TP
+\fB::http::error\fR \fItoken\fR
+.
+This is a convenience procedure that returns the \fBerror\fR element
+of the state array.
+.TP
+\fB::http::status\fR \fItoken\fR
+.
+This is a convenience procedure that returns the \fBstatus\fR element of
+the state array.
+.TP
+\fB::http::code\fR \fItoken\fR
+.
+This is a convenience procedure that returns the \fBhttp\fR element of the
+state array.
+.TP
+\fB::http::ncode\fR \fItoken\fR
+.
+This is a convenience procedure that returns just the numeric return
+code (200, 404, etc.) from the \fBhttp\fR element of the state array.
+.TP
+\fB::http::size\fR \fItoken\fR
+.
+This is a convenience procedure that returns the \fBcurrentsize\fR
+element of the state array, which represents the number of bytes
+received from the URL in the \fB::http::geturl\fR call.
+.TP
+\fB::http::meta\fR \fItoken\fR
+.
+This is a convenience procedure that returns the \fBmeta\fR
+element of the state array which contains the HTTP response
+headers. See below for an explanation of this element.
+.TP
+\fB::http::cleanup\fR \fItoken\fR
+.
+This procedure cleans up the state associated with the connection
+identified by \fItoken\fR.  After this call, the procedures
+like \fB::http::data\fR cannot be used to get information
+about the operation.  It is \fIstrongly\fR recommended that you call
+this function after you are done with a given HTTP request.  Not doing
+so will result in memory not being freed, and if your app calls
+\fB::http::geturl\fR enough times, the memory leak could cause a
+performance hit...or worse.
+.TP
+\fB::http::register\fR \fIproto port command\fR
+.
+This procedure allows one to provide custom HTTP transport types
+such as HTTPS, by registering a prefix, the default port, and the
+command to execute to create the Tcl \fBchannel\fR. E.g.:
+.RS
+.PP
+.CS
+package require http
+package require tls
+
+::http::register https 443 ::tls::socket
+
+set token [::http::geturl https://my.secure.site/]
+.CE
+.RE
+.TP
+\fB::http::unregister\fR \fIproto\fR
+.
+This procedure unregisters a protocol handler that was previously
+registered via \fB::http::register\fR.
+.SH ERRORS
+The \fB::http::geturl\fR procedure will raise errors in the following cases:
+invalid command line options,
+an invalid URL,
+a URL on a non-existent host,
+or a URL at a bad port on an existing host.
+These errors mean that it
+cannot even start the network transaction.
+It will also raise an error if it gets an I/O error while
+writing out the HTTP request header.
+For synchronous \fB::http::geturl\fR calls (where \fB\-command\fR is
+not specified), it will raise an error if it gets an I/O error while
+reading the HTTP reply headers or data.  Because \fB::http::geturl\fR
+does not return a token in these cases, it does all the required
+cleanup and there is no issue of your app having to call
+\fB::http::cleanup\fR.
+.PP
+For asynchronous \fB::http::geturl\fR calls, all of the above error
+situations apply, except that if there is any error while reading the
+HTTP reply headers or data, no exception is thrown.  This is because
+after writing the HTTP headers, \fB::http::geturl\fR returns, and the
+rest of the HTTP transaction occurs in the background.  The command
+callback can check if any error occurred during the read by calling
+\fB::http::status\fR to check the status and if its \fIerror\fR,
+calling \fB::http::error\fR to get the error message.
+.PP
+Alternatively, if the main program flow reaches a point where it needs
+to know the result of the asynchronous HTTP request, it can call
+\fB::http::wait\fR and then check status and error, just as the
+callback does.
+.PP
+In any case, you must still call
+\fB::http::cleanup\fR to delete the state array when you are done.
+.PP
+There are other possible results of the HTTP transaction
+determined by examining the status from \fB::http::status\fR.
+These are described below.
+.TP
+\fBok\fR
+.
+If the HTTP transaction completes entirely, then status will be \fBok\fR.
+However, you should still check the \fB::http::code\fR value to get
+the HTTP status.  The \fB::http::ncode\fR procedure provides just
+the numeric error (e.g., 200, 404 or 500) while the \fB::http::code\fR
+procedure returns a value like
+.QW "HTTP 404 File not found" .
+.TP
+\fBeof\fR
+.
+If the server closes the socket without replying, then no error
+is raised, but the status of the transaction will be \fBeof\fR.
+.TP
+\fBerror\fR
+.
+The error message will also be stored in the \fBerror\fR status
+array element, accessible via \fB::http::error\fR.
+.PP
+Another error possibility is that \fB::http::geturl\fR is unable to
+write all the post query data to the server before the server
+responds and closes the socket.
+The error message is saved in the \fBposterror\fR status array
+element and then  \fB::http::geturl\fR attempts to complete the
+transaction.
+If it can read the server's response
+it will end up with an \fBok\fR status, otherwise it will have
+an \fBeof\fR status.
+.SH "STATE ARRAY"
+The \fB::http::geturl\fR procedure returns a \fItoken\fR that can be used to
+get to the state of the HTTP transaction in the form of a Tcl array.
+Use this construct to create an easy-to-use array variable:
+.PP
+.CS
+upvar #0 $token state
+.CE
+.PP
+Once the data associated with the URL is no longer needed, the state
+array should be unset to free up storage.
+The \fB::http::cleanup\fR procedure is provided for that purpose.
+The following elements of
+the array are supported:
+.RS
+.TP
+\fBbody\fR
+.
+The contents of the URL.  This will be empty if the \fB\-channel\fR
+option has been specified.  This value is returned by the \fB::http::data\fR command.
+.TP
+\fBcharset\fR
+.
+The value of the charset attribute from the \fBContent-Type\fR meta-data
+value.  If none was specified, this defaults to the RFC standard
+\fBiso8859-1\fR, or the value of \fB$::http::defaultCharset\fR.  Incoming
+text data will be automatically converted from this charset to utf-8.
+.TP
+\fBcoding\fR
+.
+A copy of the \fBContent-Encoding\fR meta-data value.
+.TP
+\fBcurrentsize\fR
+.
+The current number of bytes fetched from the URL.
+This value is returned by the \fB::http::size\fR command.
+.TP
+\fBerror\fR
+.
+If defined, this is the error string seen when the HTTP transaction
+was aborted.
+.TP
+\fBhttp\fR
+.
+The HTTP status reply from the server.  This value
+is returned by the \fB::http::code\fR command.  The format of this value is:
+.RS
+.PP
+.CS
+\fIHTTP/1.1 code string\fR
+.CE
+.PP
+The \fIcode\fR is a three-digit number defined in the HTTP standard.
+A code of 200 is OK.  Codes beginning with 4 or 5 indicate errors.
+Codes beginning with 3 are redirection errors.  In this case the
+\fBLocation\fR meta-data specifies a new URL that contains the
+requested information.
+.RE
+.TP
+\fBmeta\fR
+.
+The HTTP protocol returns meta-data that describes the URL contents.
+The \fBmeta\fR element of the state array is a list of the keys and
+values of the meta-data.  This is in a format useful for initializing
+an array that just contains the meta-data:
+.RS
+.PP
+.CS
+array set meta $state(meta)
+.CE
+.PP
+Some of the meta-data keys are listed below, but the HTTP standard defines
+more, and servers are free to add their own.
+.TP
+\fBContent-Type\fR
+.
+The type of the URL contents.  Examples include \fBtext/html\fR,
+\fBimage/gif,\fR \fBapplication/postscript\fR and
+\fBapplication/x-tcl\fR.
+.TP
+\fBContent-Length\fR
+.
+The advertised size of the contents.  The actual size obtained by
+\fB::http::geturl\fR is available as \fBstate(currentsize)\fR.
+.TP
+\fBLocation\fR
+.
+An alternate URL that contains the requested data.
+.RE
+.TP
+\fBposterror\fR
+.
+The error, if any, that occurred while writing
+the post query data to the server.
+.TP
+\fBstatus\fR
+.
+Either \fBok\fR, for successful completion, \fBreset\fR for
+user-reset, \fBtimeout\fR if a timeout occurred before the transaction
+could complete, or \fBerror\fR for an error condition.  During the
+transaction this value is the empty string.
+.TP
+\fBtotalsize\fR
+.
+A copy of the \fBContent-Length\fR meta-data value.
+.TP
+\fBtype\fR
+.
+A copy of the \fBContent-Type\fR meta-data value.
+.TP
+\fBurl\fR
+.
+The requested URL.
+.RE
+.SH EXAMPLE
+.PP
+This example creates a procedure to copy a URL to a file while printing a
+progress meter, and prints the meta-data associated with the URL.
+.PP
+.CS
+proc httpcopy { url file {chunk 4096} } {
+    set out [open $file w]
+    set token [\fB::http::geturl\fR $url -channel $out \e
+            -progress httpCopyProgress -blocksize $chunk]
+    close $out
+
+    # This ends the line started by httpCopyProgress
+    puts stderr ""
+
+    upvar #0 $token state
+    set max 0
+    foreach {name value} $state(meta) {
+        if {[string length $name] > $max} {
+            set max [string length $name]
+        }
+        if {[regexp -nocase ^location$ $name]} {
+            # Handle URL redirects
+            puts stderr "Location:$value"
+            return [httpcopy [string trim $value] $file $chunk]
+        }
+    }
+    incr max
+    foreach {name value} $state(meta) {
+        puts [format "%-*s %s" $max $name: $value]
+    }
+
+    return $token
+}
+proc httpCopyProgress {args} {
+    puts -nonewline stderr .
+    flush stderr
+}
+.CE
+.SH "SEE ALSO"
+safe(n), socket(n), safesock(n)
+.SH KEYWORDS
+internet, security policy, socket, www
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/doc/if.n b/doc/if.n
new file mode 100644
index 0000000..776f811
--- /dev/null
+++ b/doc/if.n
@@ -0,0 +1,88 @@
+'\"
+'\" Copyright (c) 1993 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\" 
+.TH if n "" Tcl "Tcl Built-In Commands"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+if \- Execute scripts conditionally
+.SH SYNOPSIS
+\fBif \fIexpr1 \fR?\fBthen\fR? \fIbody1 \fBelseif \fIexpr2 \fR?\fBthen\fR? \fIbody2\fR \fBelseif\fR ... ?\fBelse\fR? ?\fIbodyN\fR?
+.BE
+
+.SH DESCRIPTION
+.PP
+The \fIif\fR command evaluates \fIexpr1\fR as an expression (in the
+same way that \fBexpr\fR evaluates its argument).  The value of the
+expression must be a boolean
+(a numeric value, where 0 is false and
+anything is true, or a string value such as \fBtrue\fR or \fByes\fR
+for true and \fBfalse\fR or \fBno\fR for false);
+if it is true then \fIbody1\fR is executed by passing it to the
+Tcl interpreter.
+Otherwise \fIexpr2\fR is evaluated as an expression and if it is true
+then \fBbody2\fR is executed, and so on.
+If none of the expressions evaluates to true then \fIbodyN\fR is
+executed.
+The \fBthen\fR and \fBelse\fR arguments are optional
+.QW "noise words"
+to make the command easier to read.
+There may be any number of \fBelseif\fR clauses, including zero.
+\fIBodyN\fR may also be omitted as long as \fBelse\fR is omitted too.
+The return value from the command is the result of the body script
+that was executed, or an empty string
+if none of the expressions was non-zero and there was no \fIbodyN\fR.
+.SH EXAMPLES
+.PP
+A simple conditional:
+.PP
+.CS
+\fBif\fR {$vbl == 1} { puts "vbl is one" }
+.CE
+.PP
+With an \fBelse\fR-clause:
+.PP
+.CS
+\fBif\fR {$vbl == 1} {
+    puts "vbl is one"
+} \fBelse\fR {
+    puts "vbl is not one"
+}
+.CE
+.PP
+With an \fBelseif\fR-clause too:
+.PP
+.CS
+\fBif\fR {$vbl == 1} {
+    puts "vbl is one"
+} \fBelseif\fR {$vbl == 2} {
+    puts "vbl is two"
+} \fBelse\fR {
+    puts "vbl is not one or two"
+}
+.CE
+.PP
+Remember, expressions can be multi-line, but in that case it can be a
+good idea to use the optional \fBthen\fR keyword for clarity:
+.PP
+.CS
+\fBif\fR {
+    $vbl == 1
+    || $vbl == 2
+    || $vbl == 3
+} \fBthen\fR {
+    puts "vbl is one, two or three"
+}
+.CE
+.SH "SEE ALSO"
+expr(n), for(n), foreach(n)
+.SH KEYWORDS
+boolean, conditional, else, false, if, true
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/doc/incr.n b/doc/incr.n
new file mode 100644
index 0000000..9052c5a
--- /dev/null
+++ b/doc/incr.n
@@ -0,0 +1,61 @@
+'\"
+'\" Copyright (c) 1993 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\" 
+.TH incr n "" Tcl "Tcl Built-In Commands"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+incr \- Increment the value of a variable
+.SH SYNOPSIS
+\fBincr \fIvarName \fR?\fIincrement\fR?
+.BE
+.SH DESCRIPTION
+.PP
+Increments the value stored in the variable whose name is \fIvarName\fR.
+The value of the variable must be an integer.
+If \fIincrement\fR is supplied then its value (which must be an
+integer) is added to the value of variable \fIvarName\fR;  otherwise
+1 is added to \fIvarName\fR.
+The new value is stored as a decimal string in variable \fIvarName\fR
+and also returned as result.
+.PP
+Starting with the Tcl 8.5 release, the variable \fIvarName\fR passed
+to \fBincr\fR may be unset, and in that case, it will be set to
+the value \fIincrement\fR or to the default increment value of \fB1\fR.
+.SH EXAMPLES
+.PP
+Add one to the contents of the variable \fIx\fR:
+.PP
+.CS
+\fBincr\fR x
+.CE
+.PP
+Add 42 to the contents of the variable \fIx\fR:
+.PP
+.CS
+\fBincr\fR x 42
+.CE
+.PP
+Add the contents of the variable \fIy\fR to the contents of the
+variable \fIx\fR:
+.PP
+.CS
+\fBincr\fR x $y
+.CE
+.PP
+Add nothing at all to the variable \fIx\fR (often useful for checking
+whether an argument to a procedure is actually integral and generating
+an error if it is not):
+.PP
+.CS
+\fBincr\fR x 0
+.CE
+.SH "SEE ALSO"
+expr(n), set(n)
+.SH KEYWORDS
+add, increment, variable, value
diff --git a/doc/info.n b/doc/info.n
new file mode 100644
index 0000000..1ad908d
--- /dev/null
+++ b/doc/info.n
@@ -0,0 +1,777 @@
+'\"
+'\" Copyright (c) 1993 The Regents of the University of California.
+'\" Copyright (c) 1994-1997 Sun Microsystems, Inc.
+'\" Copyright (c) 1993-1997 Bell Labs Innovations for Lucent Technologies
+'\" Copyright (c) 1998-2000 Ajuba Solutions
+'\" Copyright (c) 2007-2012 Donal K. Fellows
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\" 
+.TH info n 8.4 Tcl "Tcl Built-In Commands"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+info \- Return information about the state of the Tcl interpreter
+.SH SYNOPSIS
+\fBinfo \fIoption \fR?\fIarg arg ...\fR?
+.BE
+.SH DESCRIPTION
+.PP
+This command provides information about various internals of the Tcl
+interpreter.
+The legal \fIoption\fRs (which may be abbreviated) are:
+.TP
+\fBinfo args \fIprocname\fR
+.
+Returns a list containing the names of the arguments to procedure
+\fIprocname\fR, in order.  \fIProcname\fR must be the name of a
+Tcl command procedure.
+.TP
+\fBinfo body \fIprocname\fR
+.
+Returns the body of procedure \fIprocname\fR.  \fIProcname\fR must be
+the name of a Tcl command procedure.
+.TP
+\fBinfo class\fI subcommand class\fR ?\fIarg ...\fR
+.VS 8.6
+Returns information about the class, \fIclass\fR. The \fIsubcommand\fRs are
+described in \fBCLASS INTROSPECTION\fR below.
+.VE 8.6
+.TP
+\fBinfo cmdcount\fR
+.
+Returns a count of the total number of commands that have been invoked
+in this interpreter.
+.TP
+\fBinfo commands \fR?\fIpattern\fR?
+.
+If \fIpattern\fR is not specified,
+returns a list of names of all the Tcl commands visible
+(i.e. executable without using a qualified name) to the current namespace,
+including both the built-in commands written in C and
+the command procedures defined using the \fBproc\fR command.
+If \fIpattern\fR is specified,
+only those names matching \fIpattern\fR are returned.
+Matching is determined using the same rules as for \fBstring match\fR.
+\fIpattern\fR can be a qualified name like \fBFoo::print*\fR.
+That is, it may specify a particular namespace
+using a sequence of namespace names separated by double colons (\fB::\fR),
+and may have pattern matching special characters
+at the end to specify a set of commands in that namespace.
+If \fIpattern\fR is a qualified name,
+the resulting list of command names has each one qualified with the name
+of the specified namespace, and only the commands defined in the named
+namespace are returned.
+.\" Technically, most of this hasn't changed; that's mostly just the
+.\" way it always worked. Hardly anyone knew that though.
+.TP
+\fBinfo complete \fIcommand\fR
+.
+Returns 1 if \fIcommand\fR is a complete Tcl command in the sense of
+having no unclosed quotes, braces, brackets or array element names.
+If the command does not appear to be complete then 0 is returned.
+This command is typically used in line-oriented input environments
+to allow users to type in commands that span multiple lines;  if the
+command is not complete, the script can delay evaluating it until additional
+lines have been typed to complete the command.
+.TP
+\fBinfo coroutine\fR
+.VS 8.6
+Returns the name of the currently executing \fBcoroutine\fR, or the empty
+string if either no coroutine is currently executing, or the current coroutine
+has been deleted (but has not yet returned or yielded since deletion).
+.VE 8.6
+.TP
+\fBinfo default \fIprocname arg varname\fR
+.
+\fIProcname\fR must be the name of a Tcl command procedure and \fIarg\fR
+must be the name of an argument to that procedure.  If \fIarg\fR
+does not have a default value then the command returns \fB0\fR.
+Otherwise it returns \fB1\fR and places the default value of \fIarg\fR
+into variable \fIvarname\fR.
+.TP
+\fBinfo errorstack \fR?\fIinterp\fR?
+.VS 8.6
+Returns, in a form that is programmatically easy to parse, the function names
+and arguments at each level from the call stack of the last error in the given
+\fIinterp\fR, or in the current one if not specified.
+.RS
+.PP
+This form is an even-sized list alternating tokens and parameters. Tokens are
+currently either \fBCALL\fR, \fBUP\fR, or \fBINNER\fR, but other values may be
+introduced in the future. \fBCALL\fR indicates a procedure call, and its
+parameter is the corresponding \fBinfo level\fR \fB0\fR. \fBUP\fR indicates a
+shift in variable frames generated by \fBuplevel\fR or similar, and applies to
+the previous \fBCALL\fR item. Its parameter is the level offset. \fBINNER\fR
+identifies the
+.QW "inner context" ,
+which is the innermost atomic command or bytecode instruction that raised the
+error, along with its arguments when available. While \fBCALL\fR and \fBUP\fR
+allow to follow complex call paths, \fBINNER\fR homes in on the offending
+operation in the innermost procedure call, even going to sub-expression
+granularity.
+.PP
+This information is also present in the \fB\-errorstack\fR entry of the
+options dictionary returned by 3-argument \fBcatch\fR; \fBinfo errorstack\fR
+is a convenient way of retrieving it for uncaught errors at top-level in an
+interactive \fBtclsh\fR.
+.RE
+.VE 8.6
+.TP
+\fBinfo exists \fIvarName\fR
+.
+Returns \fB1\fR if the variable named \fIvarName\fR exists in the
+current context (either as a global or local variable) and has been
+defined by being given a value, returns \fB0\fR otherwise.
+.TP
+\fBinfo frame\fR ?\fInumber\fR?
+.
+This command provides access to all frames on the stack, even those
+hidden from \fBinfo level\fR. If \fInumber\fR is not specified, this
+command returns a number giving the frame level of the command. This
+is 1 if the command is invoked at top-level. If \fInumber\fR is
+specified, then the result is a dictionary containing the location
+information for the command at the \fInumber\fRed level on the stack.
+.RS
+.PP
+If \fInumber\fR is positive (> 0) then it selects a particular stack
+level (1 refers to the outer-most active command, 2 to the command it
+called, and so on, up to the current frame level which refers to
+\fBinfo frame\fR itself); otherwise it gives a level relative to the
+current command (0 refers to the current command, i.e., \fBinfo
+frame\fR itself, -1 to its caller, and so on).
+.PP
+This is similar to how \fBinfo level\fR works, except that this
+subcommand reports all frames, like \fBsource\fRd scripts,
+\fBeval\fRs, \fBuplevel\fRs, etc.
+.PP
+Note that for nested commands, like
+.QW "foo [bar [x]]" ,
+only
+.QW x
+will be seen by an \fBinfo frame\fR invoked within
+.QW x .
+This is the same as for \fBinfo level\fR and error stack traces.
+.PP
+The result dictionary may contain the keys listed below, with the
+specified meanings for their values:
+.TP
+\fBtype\fR
+.
+This entry is always present and describes the nature of the location
+for the command. The recognized values are \fBsource\fR, \fBproc\fR,
+\fBeval\fR, and \fBprecompiled\fR.
+.RS
+.TP
+\fBsource\fR\0\0\0\0\0\0\0\0
+.
+means that the command is found in a script loaded by the \fBsource\fR
+command.
+.TP
+\fBproc\fR\0\0\0\0\0\0\0\0
+.
+means that the command is found in dynamically created procedure body.
+.TP
+\fBeval\fR\0\0\0\0\0\0\0\0
+.
+means that the command is executed by \fBeval\fR or \fBuplevel\fR.
+.TP
+\fBprecompiled\fR\0\0\0\0\0\0\0\0
+.
+means that the command is found in a pre-compiled script (loadable by
+the package \fBtbcload\fR), and no further information will be
+available.
+.RE
+.TP
+\fBline\fR
+.
+This entry provides the number of the line the command is at inside of
+the script it is a part of. This information is not present for type
+\fBprecompiled\fR. For type \fBsource\fR this information is counted
+relative to the beginning of the file, whereas for the last two types
+the line is counted relative to the start of the script.
+.TP
+\fBfile\fR
+.
+This entry is present only for type \fBsource\fR. It provides the
+normalized path of the file the command is in.
+.TP
+\fBcmd\fR
+.
+This entry provides the string representation of the command. This is
+usually the unsubstituted form, however for commands which are a
+canonically-constructed list (e.g., as produced by the \fBlist\fR command)
+executed by \fBeval\fR it is the substituted form as they have no other
+string representation. Care is taken that the canonicality property of
+the latter is not spoiled.
+.TP
+\fBproc\fR
+.
+This entry is present only if the command is found in the body of a
+regular Tcl procedure. It then provides the name of that procedure.
+.TP
+\fBlambda\fR
+.
+This entry is present only if the command is found in the body of an
+anonymous Tcl procedure, i.e. a lambda. It then provides the entire
+definition of the lambda in question.
+.TP
+\fBlevel\fR
+.
+This entry is present only if the queried frame has a corresponding
+frame returned by \fBinfo level\fR. It provides the index of this
+frame, relative to the current level (0 and negative numbers).
+.PP
+A thing of note is that for procedures statically defined in files the
+locations of commands in their bodies will be reported with type
+\fBsource\fR and absolute line numbers, and not as type
+\fBproc\fR. The same is true for procedures nested in statically
+defined procedures, and literal eval scripts in files or statically
+defined procedures.
+.PP
+In contrast, procedure definitions and \fBeval\fR within a dynamically
+\fBeval\fRuated environment count line numbers relative to the start of
+their script, even if they would be able to count relative to the
+start of the outer dynamic script. That type of number usually makes
+more sense.
+.PP
+A different way of describing this behaviour is that file based
+locations are tracked as deeply as possible, and where this is not
+possible the lines are counted based on the smallest possible
+\fBeval\fR or procedure body, as that scope is usually easier to find
+than any dynamic outer scope.
+.PP
+The syntactic form \fB{*}\fR is handled like \fBeval\fR. I.e. if it
+is given a literal list argument the system tracks the line number
+within the list words as well, and otherwise all line numbers are
+counted relative to the start of each word (smallest scope)
+.RE
+.TP
+\fBinfo functions \fR?\fIpattern\fR?
+.
+If \fIpattern\fR is not specified, returns a list of all the math
+functions currently defined.
+If \fIpattern\fR is specified, only those functions whose name matches
+\fIpattern\fR are returned.  Matching is determined using the same
+rules as for \fBstring match\fR.
+.TP
+\fBinfo globals \fR?\fIpattern\fR?
+.
+If \fIpattern\fR is not specified, returns a list of all the names
+of currently-defined global variables.
+Global variables are variables in the global namespace.
+If \fIpattern\fR is specified, only those names matching \fIpattern\fR
+are returned.  Matching is determined using the same rules as for
+\fBstring match\fR.
+.TP
+\fBinfo hostname\fR
+.
+Returns the name of the computer on which this invocation is being
+executed.
+Note that this name is not guaranteed to be the fully qualified domain
+name of the host.  Where machines have several different names (as is
+common on systems with both TCP/IP (DNS) and NetBIOS-based networking
+installed,) it is the name that is suitable for TCP/IP networking that
+is returned.
+.TP
+\fBinfo level\fR ?\fInumber\fR?
+.
+If \fInumber\fR is not specified, this command returns a number
+giving the stack level of the invoking procedure, or 0 if the
+command is invoked at top-level.  If \fInumber\fR is specified,
+then the result is a list consisting of the name and arguments for the
+procedure call at level \fInumber\fR on the stack.  If \fInumber\fR
+is positive then it selects a particular stack level (1 refers
+to the top-most active procedure, 2 to the procedure it called, and
+so on); otherwise it gives a level relative to the current level
+(0 refers to the current procedure, -1 to its caller, and so on).
+See the \fBuplevel\fR command for more information on what stack
+levels mean.
+.TP
+\fBinfo library\fR
+.
+Returns the name of the library directory in which standard Tcl
+scripts are stored.
+This is actually the value of the \fBtcl_library\fR
+variable and may be changed by setting \fBtcl_library\fR.
+.TP
+\fBinfo loaded \fR?\fIinterp\fR?
+.
+Returns a list describing all of the packages that have been loaded into
+\fIinterp\fR with the \fBload\fR command.
+Each list element is a sub-list with two elements consisting of the
+name of the file from which the package was loaded and the name of
+the package.
+For statically-loaded packages the file name will be an empty string.
+If \fIinterp\fR is omitted then information is returned for all packages
+loaded in any interpreter in the process.
+To get a list of just the packages in the current interpreter, specify
+an empty string for the \fIinterp\fR argument.
+.TP
+\fBinfo locals \fR?\fIpattern\fR?
+.
+If \fIpattern\fR is not specified, returns a list of all the names
+of currently-defined local variables, including arguments to the
+current procedure, if any.
+Variables defined with the \fBglobal\fR, \fBupvar\fR  and
+\fBvariable\fR commands will not be returned.
+If \fIpattern\fR is specified, only those names matching \fIpattern\fR
+are returned.  Matching is determined using the same rules as for
+\fBstring match\fR.
+.TP
+\fBinfo nameofexecutable\fR
+.
+Returns the full path name of the binary file from which the application
+was invoked.  If Tcl was unable to identify the file, then an empty
+string is returned.
+.TP
+\fBinfo object\fI subcommand object\fR ?\fIarg ...\fR
+.VS 8.6
+Returns information about the object, \fIobject\fR. The \fIsubcommand\fRs are
+described in \fBOBJECT INTROSPECTION\fR below.
+.VE 8.6
+.TP
+\fBinfo patchlevel\fR
+.
+Returns the value of the global variable \fBtcl_patchLevel\fR, which holds
+the exact version of the Tcl library by default.
+.TP
+\fBinfo procs \fR?\fIpattern\fR?
+.
+If \fIpattern\fR is not specified, returns a list of all the
+names of Tcl command procedures in the current namespace.
+If \fIpattern\fR is specified,
+only those procedure names in the current namespace
+matching \fIpattern\fR are returned.
+Matching is determined using the same rules as for
+\fBstring match\fR.
+If \fIpattern\fR contains any namespace separators, they are used to
+select a namespace relative to the current namespace (or relative to
+the global namespace if \fIpattern\fR starts with \fB::\fR) to match
+within; the matching pattern is taken to be the part after the last
+namespace separator.
+.TP
+\fBinfo script\fR ?\fIfilename\fR?
+.
+If a Tcl script file is currently being evaluated (i.e. there is a
+call to \fBTcl_EvalFile\fR active or there is an active invocation
+of the \fBsource\fR command), then this command returns the name
+of the innermost file being processed.  If \fIfilename\fR is specified,
+then the return value of this command will be modified for the
+duration of the active invocation to return that name.  This is
+useful in virtual file system applications.
+Otherwise the command returns an empty string.
+.TP
+\fBinfo sharedlibextension\fR
+.
+Returns the extension used on this platform for the names of files
+containing shared libraries (for example, \fB.so\fR under Solaris).
+If shared libraries are not supported on this platform then an empty
+string is returned.
+.TP
+\fBinfo tclversion\fR
+.
+Returns the value of the global variable \fBtcl_version\fR, which holds the
+major and minor version of the Tcl library by default.
+.TP
+\fBinfo vars\fR ?\fIpattern\fR?
+.
+If \fIpattern\fR is not specified,
+returns a list of all the names of currently-visible variables.
+This includes locals and currently-visible globals.
+If \fIpattern\fR is specified, only those names matching \fIpattern\fR
+are returned.  Matching is determined using the same rules as for
+\fBstring match\fR.
+\fIpattern\fR can be a qualified name like \fBFoo::option*\fR.
+That is, it may specify a particular namespace
+using a sequence of namespace names separated by double colons (\fB::\fR),
+and may have pattern matching special characters
+at the end to specify a set of variables in that namespace.
+If \fIpattern\fR is a qualified name,
+the resulting list of variable names
+has each matching namespace variable qualified with the name
+of its namespace.
+Note that a currently-visible variable may not yet
+.QW exist
+if it has not
+been set (e.g. a variable declared but not set by \fBvariable\fR).
+.SS "CLASS INTROSPECTION"
+.VS 8.6
+.PP
+The following \fIsubcommand\fR values are supported by \fBinfo class\fR:
+.VE 8.6
+.TP
+\fBinfo class call\fI class method\fR
+.VS
+Returns a description of the method implementations that are used to provide a
+stereotypical instance of \fIclass\fR's implementation of \fImethod\fR
+(stereotypical instances being objects instantiated by a class without having
+any object-specific definitions added). This consists of a list of lists of
+four elements, where each sublist consists of a word that describes the
+general type of method implementation (being one of \fBmethod\fR for an
+ordinary method, \fBfilter\fR for an applied filter, and \fBunknown\fR for a
+method that is invoked as part of unknown method handling), a word giving the
+name of the particular method invoked (which is always the same as
+\fImethod\fR for the \fBmethod\fR type, and
+.QW \fBunknown\fR
+for the \fBunknown\fR type), a word giving the fully qualified name of the
+class that defined the method, and a word describing the type of method
+implementation (see \fBinfo class methodtype\fR).
+.RS
+.PP
+Note that there is no inspection of whether the method implementations
+actually use \fBnext\fR to transfer control along the call chain.
+.RE
+.VE 8.6
+.TP
+\fBinfo class constructor\fI class\fR
+.VS 8.6
+This subcommand returns a description of the definition of the constructor of
+class \fIclass\fR. The definition is described as a two element list; the first
+element is the list of arguments to the constructor in a form suitable for
+passing to another call to \fBproc\fR or a method definition, and the second
+element is the body of the constructor. If no constructor is present, this
+returns the empty list.
+.VE 8.6
+.TP
+\fBinfo class definition\fI class method\fR
+.VS 8.6
+This subcommand returns a description of the definition of the method named
+\fImethod\fR of class \fIclass\fR. The definition is described as a two element
+list; the first element is the list of arguments to the method in a form
+suitable for passing to another call to \fBproc\fR or a method definition, and
+the second element is the body of the method.
+.VE 8.6
+.TP
+\fBinfo class destructor\fI class\fR
+.VS 8.6
+This subcommand returns the body of the destructor of class \fIclass\fR. If no
+destructor is present, this returns the empty string.
+.VE 8.6
+.TP
+\fBinfo class filters\fI class\fR
+.VS 8.6
+This subcommand returns the list of filter methods set on the class.
+.VE 8.6
+.TP
+\fBinfo class forward\fI class method\fR
+.VS 8.6
+This subcommand returns the argument list for the method forwarding called
+\fImethod\fR that is set on the class called \fIclass\fR.
+.VE 8.6
+.TP
+\fBinfo class instances\fI class\fR ?\fIpattern\fR?
+.VS 8.6
+This subcommand returns a list of instances of class \fIclass\fR. If the
+optional \fIpattern\fR argument is present, it constrains the list of returned
+instances to those that match it according to the rules of \fBstring match\fR.
+.VE 8.6
+.TP
+\fBinfo class methods\fI class\fR ?\fIoptions...\fR?
+.VS 8.6
+This subcommand returns a list of all public (i.e. exported) methods of the
+class called \fIclass\fR. Any of the following \fIoption\fRs may be
+specified, controlling exactly which method names are returned:
+.RS
+.VE 8.6
+.TP
+\fB\-all\fR
+.VS 8.6
+If the \fB\-all\fR flag is given, the list of methods will include those
+methods defined not just by the class, but also by the class's superclasses
+and mixins.
+.VE 8.6
+.TP
+\fB\-private\fR
+.VS 8.6
+If the \fB\-private\fR flag is given, the list of methods will also include
+the private (i.e. non-exported) methods of the class (and superclasses and
+mixins, if \fB\-all\fR is also given).
+.RE
+.VE 8.6
+.TP
+\fBinfo class methodtype\fI class method\fR
+.VS 8.6
+This subcommand returns a description of the type of implementation used for
+the method named \fImethod\fR of class \fIclass\fR. When the result is
+\fBmethod\fR, further information can be discovered with \fBinfo class
+definition\fR, and when the result is \fBforward\fR, further information can
+be discovered with \fBinfo class forward\fR.
+.VE 8.6
+.TP
+\fBinfo class mixins\fI class\fR
+.VS 8.6
+This subcommand returns a list of all classes that have been mixed into the
+class named \fIclass\fR.
+.VE 8.6
+.TP
+\fBinfo class subclasses\fI class\fR ?\fIpattern\fR?
+.VS 8.6
+This subcommand returns a list of direct subclasses of class \fIclass\fR. If
+the optional \fIpattern\fR argument is present, it constrains the list of
+returned classes to those that match it according to the rules of
+\fBstring match\fR.
+.VE 8.6
+.TP
+\fBinfo class superclasses\fI class\fR
+.VS 8.6
+This subcommand returns a list of direct superclasses of class \fIclass\fR in
+inheritance precedence order.
+.VE 8.6
+.TP
+\fBinfo class variables\fI class\fR
+.VS 8.6
+This subcommand returns a list of all variables that have been declared for
+the class named \fIclass\fR (i.e. that are automatically present in the
+class's methods, constructor and destructor).
+.SS "OBJECT INTROSPECTION"
+.PP
+The following \fIsubcommand\fR values are supported by \fBinfo object\fR:
+.VE 8.6
+.TP
+\fBinfo object call\fI object method\fR
+.VS 8.6
+Returns a description of the method implementations that are used to provide
+\fIobject\fR's implementation of \fImethod\fR.  This consists of a list of
+lists of four elements, where each sublist consists of a word that describes
+the general type of method implementation (being one of \fBmethod\fR for an
+ordinary method, \fBfilter\fR for an applied filter, and \fBunknown\fR for a
+method that is invoked as part of unknown method handling), a word giving the
+name of the particular method invoked (which is always the same as
+\fImethod\fR for the \fBmethod\fR type, and
+.QW \fBunknown\fR
+for the \fBunknown\fR type), a word giving what defined the method (the fully
+qualified name of the class, or the literal string \fBobject\fR if the method
+implementation is on an instance), and a word describing the type of method
+implementation (see \fBinfo object methodtype\fR).
+.RS
+.PP
+Note that there is no inspection of whether the method implementations
+actually use \fBnext\fR to transfer control along the call chain.
+.RE
+.VE 8.6
+.TP
+\fBinfo object class\fI object\fR ?\fIclassName\fR?
+.VS 8.6
+If \fIclassName\fR is unspecified, this subcommand returns class of the
+\fIobject\fR object. If \fIclassName\fR is present, this subcommand returns a
+boolean value indicating whether the \fIobject\fR is of that class.
+.VE 8.6
+.TP
+\fBinfo object definition\fI object method\fR
+.VS 8.6
+This subcommand returns a description of the definition of the method named
+\fImethod\fR of object \fIobject\fR. The definition is described as a two
+element list; the first element is the list of arguments to the method in a
+form suitable for passing to another call to \fBproc\fR or a method definition,
+and the second element is the body of the method.
+.VE 8.6
+.TP
+\fBinfo object filters\fI object\fR
+.VS 8.6
+This subcommand returns the list of filter methods set on the object.
+.VE 8.6
+.TP
+\fBinfo object forward\fI object method\fR
+.VS 8.6
+This subcommand returns the argument list for the method forwarding called
+\fImethod\fR that is set on the object called \fIobject\fR.
+.VE 8.6
+.TP
+\fBinfo object isa\fI category object\fR ?\fIarg\fR?
+.VS 8.6
+This subcommand tests whether an object belongs to a particular category,
+returning a boolean value that indicates whether the \fIobject\fR argument
+meets the criteria for the category. The supported categories are:
+.VE 8.6
+.RS
+.TP
+\fBinfo object isa class\fI object\fR
+.VS 8.6
+This returns whether \fIobject\fR is a class (i.e. an instance of
+\fBoo::class\fR or one of its subclasses).
+.VE 8.6
+.TP
+\fBinfo object isa metaclass\fI object\fR
+.VS 8.6
+This returns whether \fIobject\fR is a class that can manufacture classes
+(i.e. is \fBoo::class\fR or a subclass of it).
+.VE 8.6
+.TP
+\fBinfo object isa mixin\fI object class\fR
+.VS 8.6
+This returns whether \fIclass\fR is directly mixed into \fIobject\fR.
+.VE 8.6
+.TP
+\fBinfo object isa object\fI object\fR
+.VS 8.6
+This returns whether \fIobject\fR really is an object.
+.VE 8.6
+.TP
+\fBinfo object isa typeof\fI object class\fR
+.VS 8.6
+This returns whether \fIclass\fR is the type of \fIobject\fR (i.e. whether
+\fIobject\fR is an instance of \fIclass\fR or one of its subclasses, whether
+direct or indirect).
+.RE
+.VE 8.6
+.TP
+\fBinfo object methods\fI object\fR ?\fIoption...\fR?
+.VS 8.6
+This subcommand returns a list of all public (i.e. exported) methods of the
+object called \fIobject\fR. Any of the following \fIoption\fRs may be
+specified, controlling exactly which method names are returned:
+.RS
+.VE 8.6
+.TP
+\fB\-all\fR
+.VS 8.6
+If the \fB\-all\fR flag is given, the list of methods will include those
+methods defined not just by the object, but also by the object's class and
+mixins, plus the superclasses of those classes.
+.VE 8.6
+.TP
+\fB\-private\fR
+.VS 8.6
+If the \fB\-private\fR flag is given, the list of methods will also include
+the private (i.e. non-exported) methods of the object (and classes, if
+\fB\-all\fR is also given).
+.RE
+.VE 8.6
+.TP
+\fBinfo object methodtype\fI object method\fR
+.VS 8.6
+This subcommand returns a description of the type of implementation used for
+the method named \fImethod\fR of object \fIobject\fR. When the result is
+\fBmethod\fR, further information can be discovered with \fBinfo object
+definition\fR, and when the result is \fBforward\fR, further information can
+be discovered with \fBinfo object forward\fR.
+.VE 8.6
+.TP
+\fBinfo object mixins\fI object\fR
+.VS 8.6
+This subcommand returns a list of all classes that have been mixed into the
+object named \fIobject\fR.
+.VE 8.6
+.TP
+\fBinfo object namespace\fI object\fR
+.VS 8.6
+This subcommand returns the name of the internal namespace of the object named
+\fIobject\fR.
+.VE 8.6
+.TP
+\fBinfo object variables\fI object\fR
+.VS 8.6
+This subcommand returns a list of all variables that have been declared for
+the object named \fIobject\fR (i.e. that are automatically present in the
+object's methods).
+.VE 8.6
+.TP
+\fBinfo object vars\fI object\fR ?\fIpattern\fR?
+.VS 8.6
+This subcommand returns a list of all variables in the private namespace of
+the object named \fIobject\fR. If the optional \fIpattern\fR argument is
+given, it is a filter (in the syntax of a \fBstring match\fR glob pattern)
+that constrains the list of variables returned. Note that this is different
+from the list returned by \fBinfo object variables\fR; that can include
+variables that are currently unset, whereas this can include variables that
+are not automatically included by any of \fIobject\fR's methods (or those of
+its class, superclasses or mixins).
+.VE 8.6
+.SH EXAMPLES
+.PP
+This command prints out a procedure suitable for saving in a Tcl
+script:
+.PP
+.CS
+proc printProc {procName} {
+    set result [list proc $procName]
+    set formals {}
+    foreach var [\fBinfo args\fR $procName] {
+        if {[\fBinfo default\fR $procName $var def]} {
+            lappend formals [list $var $def]
+        } else {
+            # Still need the list-quoting because variable
+            # names may properly contain spaces.
+            lappend formals [list $var]
+        }
+    }
+    puts [lappend result $formals [\fBinfo body\fR $procName]]
+}
+.CE
+.SS "EXAMPLES WITH OBJECTS"
+.VS 8.6
+.PP
+Every object necessarily knows what its class is; this information is
+trivially extractable through introspection:
+.PP
+.CS
+oo::class create c
+c create o
+puts [\fBinfo object class\fR o]
+                     \fI\(-> prints "::c"\fR
+puts [\fBinfo object class\fR c]
+                     \fI\(-> prints "::oo::class"\fR
+.CE
+.PP
+The introspection capabilities can be used to discover what class implements a
+method and get how it is defined. This procedure illustrates how:
+.PP
+.CS
+proc getDef {obj method} {
+    foreach inf [\fBinfo object call\fR $obj $method] {
+        lassign $inf calltype name locus methodtype
+        # Assume no forwards or filters, and hence no $calltype
+        # or $methodtype checks...
+        if {$locus eq "object"} {
+            return [\fBinfo object definition\fR $obj $name]
+        } else {
+            return [\fBinfo class definition\fR $locus $name]
+        }
+    }
+    error "no definition for $method"
+}
+.CE
+.PP
+This is an alternate way of looking up the definition; it is implemented by
+manually scanning the list of methods up the inheritance tree. This code
+assumes that only single inheritance is in use, and that there is no complex
+use of mixed-in classes (in such cases, using \fBinfo object call\fR as above
+is the simplest way of doing this by far):
+.PP
+.CS
+proc getDef {obj method} {
+    if {$method in [\fBinfo object methods\fR $obj]} {
+        # Assume no forwards
+        return [\fBinfo object definition\fR $obj $method]
+    }
+    set cls [\fBinfo object class\fR $obj]
+    while {$method ni [\fBinfo class methods\fR $cls]} {
+        # Assume the simple case
+        set cls [lindex [\fBinfo class superclass\fR $cls] 0]
+        if {$cls eq ""} {
+            error "no definition for $method"
+        }
+    }
+    # Assume no forwards
+    return [\fBinfo class definition\fR $cls $method]
+}
+.CE
+.VE 8.6
+.SH "SEE ALSO"
+.VS 8.6
+global(n), oo::class(n), oo::define(n), oo::object(n), proc(n), self(n),
+.VE 8.6
+tcl_library(n), tcl_patchLevel(n), tcl_version(n)
+.SH KEYWORDS
+command, information, interpreter, introspection, level, namespace,
+.VS 8.6
+object,
+.VE 8.6
+procedure, variable
+'\" Local Variables:
+'\" mode: nroff
+'\" fill-column: 78
+'\" End:
diff --git a/doc/interp.n b/doc/interp.n
new file mode 100644
index 0000000..92113a6
--- /dev/null
+++ b/doc/interp.n
@@ -0,0 +1,910 @@
+'\"
+'\" Copyright (c) 1995-1996 Sun Microsystems, Inc.
+'\" Copyright (c) 2004 Donal K. Fellows
+'\" Copyright (c) 2006-2008 Joe Mistachkin.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\" 
+.TH interp n 8.6 Tcl "Tcl Built-In Commands"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+interp \- Create and manipulate Tcl interpreters
+.SH SYNOPSIS
+\fBinterp \fIsubcommand \fR?\fIarg arg ...\fR?
+.BE
+.SH DESCRIPTION
+.PP
+This command makes it possible to create one or more new Tcl
+interpreters that co-exist with the creating interpreter in the
+same application.  The creating interpreter is called the \fImaster\fR
+and the new interpreter is called a \fIslave\fR.
+A master can create any number of slaves, and each slave can
+itself create additional slaves for which it is master, resulting
+in a hierarchy of interpreters.
+.PP
+Each interpreter is independent from the others: it has its own name
+space for commands, procedures, and global variables.
+A master interpreter may create connections between its slaves and
+itself using a mechanism called an \fIalias\fR.  An \fIalias\fR is
+a command in a slave interpreter which, when invoked, causes a
+command to be invoked in its master interpreter or in another slave
+interpreter.  The only other connections between interpreters are
+through environment variables (the \fBenv\fR variable), which are
+normally shared among all interpreters in the application,
+and by resource limit exceeded callbacks. Note that the
+name space for files (such as the names returned by the \fBopen\fR command)
+is no longer shared between interpreters. Explicit commands are provided to
+share files and to transfer references to open files from one interpreter
+to another.
+.PP
+The \fBinterp\fR command also provides support for \fIsafe\fR
+interpreters.  A safe interpreter is a slave whose functions have
+been greatly restricted, so that it is safe to execute untrusted
+scripts without fear of them damaging other interpreters or the
+application's environment. For example, all IO channel creation
+commands and subprocess creation commands are made inaccessible to safe
+interpreters.
+See \fBSAFE INTERPRETERS\fR below for more information on
+what features are present in a safe interpreter.
+The dangerous functionality is not removed from the safe interpreter;
+instead, it is \fIhidden\fR, so that only trusted interpreters can obtain
+access to it. For a detailed explanation of hidden commands, see
+\fBHIDDEN COMMANDS\fR, below.
+The alias mechanism can be used for protected communication (analogous to a
+kernel call) between a slave interpreter and its master.
+See \fBALIAS INVOCATION\fR, below, for more details
+on how the alias mechanism works.
+.PP
+A qualified interpreter name is a proper Tcl lists containing a subset of its
+ancestors in the interpreter hierarchy, terminated by the string naming the
+interpreter in its immediate master. Interpreter names are relative to the
+interpreter in which they are used. For example, if
+.QW \fBa\fR
+is a slave of the current interpreter and it has a slave
+.QW \fBa1\fR ,
+which in turn has a slave
+.QW \fBa11\fR ,
+the qualified name of
+.QW \fBa11\fR
+in
+.QW \fBa\fR
+is the list
+.QW "\fBa1 a11\fR" .
+.PP
+The \fBinterp\fR command, described below, accepts qualified interpreter
+names as arguments; the interpreter in which the command is being evaluated
+can always be referred to as \fB{}\fR (the empty list or string). Note that
+it is impossible to refer to a master (ancestor) interpreter by name in a
+slave interpreter except through aliases. Also, there is no global name by
+which one can refer to the first interpreter created in an application.
+Both restrictions are motivated by safety concerns.
+.SH "THE INTERP COMMAND"
+.PP
+The \fBinterp\fR command is used to create, delete, and manipulate
+slave interpreters, and to share or transfer
+channels between interpreters.  It can have any of several forms, depending
+on the \fIsubcommand\fR argument:
+.TP
+\fBinterp\fR \fBalias\fR \fIsrcPath\fR \fIsrcToken\fR
+.
+Returns a Tcl list whose elements are the \fItargetCmd\fR and
+\fIarg\fRs associated with the alias represented by \fIsrcToken\fR
+(this is the value returned when the alias was
+created; it is possible that the name of the source command in the
+slave is different from \fIsrcToken\fR).
+.TP
+\fBinterp\fR \fBalias\fR \fIsrcPath\fR \fIsrcToken\fR \fB{}\fR
+.
+Deletes the alias for \fIsrcToken\fR in the slave interpreter identified by
+\fIsrcPath\fR.
+\fIsrcToken\fR refers to the value returned when the alias
+was created;  if the source command has been renamed, the renamed
+command will be deleted.
+.TP
+\fBinterp\fR \fBalias\fR \fIsrcPath\fR \fIsrcCmd\fR \fItargetPath\fR \fItargetCmd \fR?\fIarg arg ...\fR?
+.
+This command creates an alias between one slave and another (see the
+\fBalias\fR slave command below for creating aliases between a slave
+and its master).  In this command, either of the slave interpreters
+may be anywhere in the hierarchy of interpreters under the interpreter
+invoking the command.
+\fISrcPath\fR and \fIsrcCmd\fR identify the source of the alias.
+\fISrcPath\fR is a Tcl list whose elements select a particular
+interpreter.  For example,
+.QW "\fBa b\fR"
+identifies an interpreter
+.QW \fBb\fR ,
+which is a slave of interpreter
+.QW \fBa\fR ,
+which is a slave of the invoking interpreter.  An empty list specifies
+the interpreter invoking the command.  \fIsrcCmd\fR gives the name of
+a new command, which will be created in the source interpreter.
+\fITargetPath\fR and \fItargetCmd\fR specify a target interpreter
+and command, and the \fIarg\fR arguments, if any, specify additional
+arguments to \fItargetCmd\fR which are prepended to any arguments specified
+in the invocation of \fIsrcCmd\fR.
+\fITargetCmd\fR may be undefined at the time of this call, or it may
+already exist; it is not created by this command.
+The alias arranges for the given target command to be invoked
+in the target interpreter whenever the given source command is
+invoked in the source interpreter.  See \fBALIAS INVOCATION\fR below for
+more details.
+The command returns a token that uniquely identifies the command created
+\fIsrcCmd\fR, even if the command is renamed afterwards. The token may but
+does not have to be equal to \fIsrcCmd\fR.
+.TP
+\fBinterp\fR \fBaliases \fR?\fIpath\fR?
+.
+This command returns a Tcl list of the tokens of all the source commands for
+aliases defined in the interpreter identified by \fIpath\fR. The tokens
+correspond to the values returned when
+the aliases were created (which may not be the same
+as the current names of the commands).
+.TP
+\fBinterp bgerror \fIpath\fR ?\fIcmdPrefix\fR?
+.
+This command either gets or sets the current background exception handler
+for the interpreter identified by \fIpath\fR. If \fIcmdPrefix\fR is
+absent, the current background exception handler is returned, and if it is
+present, it is a list of words (of minimum length one) that describes
+what to set the interpreter's background exception handler to. See the
+\fBBACKGROUND EXCEPTION HANDLING\fR section for more details.
+.TP
+\fBinterp\fR \fBcancel \fR?\fB\-unwind\fR? ?\fB\-\|\-\fR? ?\fIpath\fR? ?\fIresult\fR?
+.VS 8.6
+Cancels the script being evaluated in the interpreter identified by
+\fIpath\fR. Without the \fB\-unwind\fR switch the evaluation stack for
+the interpreter is unwound until an enclosing catch command is found or
+there are no further invocations of the interpreter left on the call
+stack. With the \fB\-unwind\fR switch the evaluation stack for the
+interpreter is unwound without regard to any intervening catch command
+until there are no further invocations of the interpreter left on the
+call stack. The \fB\-\|\-\fR switch can be used to mark the end of
+switches; it may be needed if \fIpath\fR is an unusual value such
+as \fB\-safe\fR. If \fIresult\fR is present, it will be used as the
+error message string; otherwise, a default error message string will be
+used.
+.VE 8.6
+.TP
+\fBinterp\fR \fBcreate \fR?\fB\-safe\fR? ?\fB\-\|\-\fR? ?\fIpath\fR?
+.
+Creates a slave interpreter identified by \fIpath\fR and a new command,
+called a \fIslave command\fR. The name of the slave command is the last
+component of \fIpath\fR. The new slave interpreter and the slave command
+are created in the interpreter identified by the path obtained by removing
+the last component from \fIpath\fR. For example, if \fIpath\fR is \fBa b
+c\fR then a new slave interpreter and slave command named \fBc\fR are
+created in the interpreter identified by the path \fBa b\fR.
+The slave command may be used to manipulate the new interpreter as
+described below. If \fIpath\fR is omitted, Tcl creates a unique name of the
+form \fBinterp\fIx\fR, where \fIx\fR is an integer, and uses it for the
+interpreter and the slave command. If the \fB\-safe\fR switch is specified
+(or if the master interpreter is a safe interpreter), the new slave
+interpreter will be created as a safe interpreter with limited
+functionality; otherwise the slave will include the full set of Tcl
+built-in commands and variables. The \fB\-\|\-\fR switch can be used to
+mark the end of switches;  it may be needed if \fIpath\fR is an unusual
+value such as \fB\-safe\fR. The result of the command is the name of the
+new interpreter. The name of a slave interpreter must be unique among all
+the slaves for its master;  an error occurs if a slave interpreter by the
+given name already exists in this master.
+The initial recursion limit of the slave interpreter is set to the
+current recursion limit of its parent interpreter.
+.TP
+\fBinterp\fR \fBdebug \fIpath\fR ?\fB\-frame\fR ?\fIbool\fR??
+.
+Controls whether frame-level stack information is captured in the
+slave interpreter identified by \fIpath\fR.  If no arguments are
+given, option and current setting are returned.  If \fB\-frame\fR
+is given, the debug setting is set to the given boolean if provided
+and the current setting is returned.
+This only effects the output of \fBinfo frame\fR, in that exact
+frame-level information for command invocation at the bytecode level
+is only captured with this setting on.
+.RS
+.PP
+For example, with code like
+.PP
+.CS
+\fBproc\fR mycontrol {... script} {
+  ...
+  \fBuplevel\fR 1 $script
+  ...
+}
+
+\fBproc\fR dosomething {...} {
+  ...
+  mycontrol {
+    somecode
+  }
+}
+.CE
+.PP
+the standard setting will provide a relative line number for the
+command \fBsomecode\fR and the relevant frame will be of type
+\fBeval\fR. With frame-debug active on the other hand the tracking
+extends so far that the system will be able to determine the file and
+absolute line number of this command, and return a frame of type
+\fBsource\fR. This more exact information is paid for with slower
+execution of all commands.
+.PP
+Note that once it is on, this flag cannot be switched back off: such
+attempts are silently ignored. This is needed to maintain the
+consistency of the underlying interpreter's state.
+.RE
+.TP
+\fBinterp\fR \fBdelete \fR?\fIpath ...?\fR
+.
+Deletes zero or more interpreters given by the optional \fIpath\fR
+arguments, and for each interpreter, it also deletes its slaves. The
+command also deletes the slave command for each interpreter deleted.
+For each \fIpath\fR argument, if no interpreter by that name
+exists, the command raises an error.
+.TP
+\fBinterp\fR \fBeval\fR \fIpath arg \fR?\fIarg ...\fR?
+.
+This command concatenates all of the \fIarg\fR arguments in the same
+fashion as the \fBconcat\fR command, then evaluates the resulting string as
+a Tcl script in the slave interpreter identified by \fIpath\fR. The result
+of this evaluation (including all \fBreturn\fR options,
+such as \fB\-errorinfo\fR and \fB\-errorcode\fR information, if an
+error occurs) is returned to the invoking interpreter.
+Note that the script will be executed in the current context stack frame of the
+\fIpath\fR interpreter; this is so that the implementations (in a master
+interpreter) of aliases in a slave interpreter can execute scripts in
+the slave that find out information about the slave's current state
+and stack frame.
+.TP
+\fBinterp exists \fIpath\fR
+.
+Returns \fB1\fR if a slave interpreter by the specified \fIpath\fR
+exists in this master, \fB0\fR otherwise. If \fIpath\fR is omitted, the
+invoking interpreter is used.
+.TP
+\fBinterp expose \fIpath\fR \fIhiddenName\fR ?\fIexposedCmdName\fR?
+.
+Makes the hidden command \fIhiddenName\fR exposed, eventually bringing
+it back under a new \fIexposedCmdName\fR name (this name is currently
+accepted only if it is a valid global name space name without any ::),
+in the interpreter
+denoted by \fIpath\fR.
+If an exposed command with the targeted name already exists, this command
+fails.
+Hidden commands are explained in more detail in \fBHIDDEN COMMANDS\fR, below.
+.TP
+\fBinterp\fR \fBhide\fR \fIpath\fR \fIexposedCmdName\fR ?\fIhiddenCmdName\fR?
+.
+Makes the exposed command \fIexposedCmdName\fR hidden, renaming
+it to the hidden command \fIhiddenCmdName\fR, or keeping the same name if
+\fIhiddenCmdName\fR is not given, in the interpreter denoted
+by \fIpath\fR.
+If a hidden command with the targeted name already exists, this command
+fails.
+Currently both \fIexposedCmdName\fR and \fIhiddenCmdName\fR can
+not contain namespace qualifiers, or an error is raised.
+Commands to be hidden by \fBinterp hide\fR are looked up in the global
+namespace even if the current namespace is not the global one. This
+prevents slaves from fooling a master interpreter into hiding the wrong
+command, by making the current namespace be different from the global one.
+Hidden commands are explained in more detail in \fBHIDDEN COMMANDS\fR, below.
+.TP
+\fBinterp\fR \fBhidden\fR \fIpath\fR
+.
+Returns a list of the names of all hidden commands in the interpreter
+identified by \fIpath\fR.
+.TP
+\fBinterp\fR \fBinvokehidden\fR \fIpath\fR ?\fI\-option ...\fR? \fIhiddenCmdName\fR ?\fIarg ...\fR?
+.
+Invokes the hidden command \fIhiddenCmdName\fR with the arguments supplied
+in the interpreter denoted by \fIpath\fR. No substitutions or evaluation
+are applied to the arguments. Three \fI\-option\fRs are supported, all
+of which start with \fB\-\fR: \fB\-namespace\fR (which takes a single
+argument afterwards, \fInsName\fR), \fB\-global\fR, and \fB\-\|\-\fR.
+If the \fB\-namespace\fR flag is present, the hidden command is invoked in
+the namespace called \fInsName\fR in the target interpreter.
+If the \fB\-global\fR flag is present, the hidden command is invoked at the
+global level in the target interpreter; otherwise it is invoked at the
+current call frame and can access local variables in that and outer call
+frames.
+The \fB\-\|\-\fR flag allows the \fIhiddenCmdName\fR argument to start with a
+.QW \-
+character, and is otherwise unnecessary.
+If both the \fB\-namespace\fR and \fB\-global\fR flags are present, the
+\fB\-namespace\fR flag is ignored.
+Note that the hidden command will be executed (by default) in the
+current context stack frame of the \fIpath\fR interpreter.
+Hidden commands are explained in more detail in \fBHIDDEN COMMANDS\fR, below.
+.TP
+\fBinterp issafe\fR ?\fIpath\fR?
+.
+Returns \fB1\fR if the interpreter identified by the specified \fIpath\fR
+is safe, \fB0\fR otherwise.
+.TP
+\fBinterp\fR \fBlimit\fR \fIpath\fR \fIlimitType\fR ?\fI\-option\fR? ?\fIvalue\fR \fI...\fR?
+.
+Sets up, manipulates and queries the configuration of the resource
+limit \fIlimitType\fR for the interpreter denoted by \fIpath\fR.  If
+no \fI\-option\fR is specified, return the current configuration of the
+limit.  If \fI\-option\fR is the sole argument, return the value of that
+option.  Otherwise, a list of \fI\-option\fR/\fIvalue\fR argument pairs
+must supplied. See \fBRESOURCE LIMITS\fR below for a more detailed
+explanation of what limits and options are supported.
+.TP
+\fBinterp marktrusted\fR \fIpath\fR
+.
+Marks the interpreter identified by \fIpath\fR as trusted. Does
+not expose the hidden commands. This command can only be invoked from a
+trusted interpreter.
+The command has no effect if the interpreter identified by \fIpath\fR is
+already trusted.
+.TP
+\fBinterp\fR \fBrecursionlimit\fR \fIpath\fR ?\fInewlimit\fR?
+.
+Returns the maximum allowable nesting depth for the interpreter
+specified by \fIpath\fR.  If \fInewlimit\fR is specified,
+the interpreter recursion limit will be set so that nesting
+of more than \fInewlimit\fR calls to \fBTcl_Eval\fR
+and related procedures in that interpreter will return an error.
+The \fInewlimit\fR value is also returned.
+The \fInewlimit\fR value must be a positive integer between 1 and the
+maximum value of a non-long integer on the platform.
+.RS
+.PP
+The command sets the maximum size of the Tcl call stack only. It cannot
+by itself prevent stack overflows on the C stack being used by the
+application. If your machine has a limit on the size of the C stack, you
+may get stack overflows before reaching the limit set by the command. If
+this happens, see if there is a mechanism in your system for increasing
+the maximum size of the C stack.
+.RE
+.TP
+\fBinterp\fR \fBshare\fR \fIsrcPath channelId destPath\fR
+.
+Causes the IO channel identified by \fIchannelId\fR to become shared
+between the interpreter identified by \fIsrcPath\fR and the interpreter
+identified by \fIdestPath\fR. Both interpreters have the same permissions
+on the IO channel.
+Both interpreters must close it to close the underlying IO channel; IO
+channels accessible in an interpreter are automatically closed when an
+interpreter is destroyed.
+.TP
+\fBinterp\fR \fBslaves\fR ?\fIpath\fR?
+.
+Returns a Tcl list of the names of all the slave interpreters associated
+with the interpreter identified by \fIpath\fR. If \fIpath\fR is omitted,
+the invoking interpreter is used.
+.TP
+\fBinterp\fR \fBtarget\fR \fIpath alias\fR
+.
+Returns a Tcl list describing the target interpreter for an alias. The
+alias is specified with an interpreter path and source command name, just
+as in \fBinterp alias\fR above. The name of the target interpreter is
+returned as an interpreter path, relative to the invoking interpreter.
+If the target interpreter for the alias is the invoking interpreter then an
+empty list is returned. If the target interpreter for the alias is not the
+invoking interpreter or one of its descendants then an error is generated.
+The target command does not have to be defined at the time of this invocation.
+.TP
+\fBinterp\fR \fBtransfer\fR \fIsrcPath channelId destPath\fR
+.
+Causes the IO channel identified by \fIchannelId\fR to become available in
+the interpreter identified by \fIdestPath\fR and unavailable in the
+interpreter identified by \fIsrcPath\fR.
+.SH "SLAVE COMMAND"
+.PP
+For each slave interpreter created with the \fBinterp\fR command, a
+new Tcl command is created in the master interpreter with the same
+name as the new interpreter. This command may be used to invoke
+various operations on the interpreter.  It has the following
+general form:
+.PP
+.CS
+\fIslave command \fR?\fIarg arg ...\fR?
+.CE
+.PP
+\fISlave\fR is the name of the interpreter, and \fIcommand\fR
+and the \fIarg\fRs determine the exact behavior of the command.
+The valid forms of this command are:
+.TP
+\fIslave \fBaliases\fR
+.
+Returns a Tcl list whose elements are the tokens of all the
+aliases in \fIslave\fR.  The tokens correspond to the values returned when
+the aliases were created (which may not be the same
+as the current names of the commands).
+.TP
+\fIslave \fBalias \fIsrcToken\fR
+.
+Returns a Tcl list whose elements are the \fItargetCmd\fR and
+\fIarg\fRs associated with the alias represented by \fIsrcToken\fR
+(this is the value returned when the alias was
+created; it is possible that the actual source command in the
+slave is different from \fIsrcToken\fR).
+.TP
+\fIslave \fBalias \fIsrcToken \fB{}\fR
+.
+Deletes the alias for \fIsrcToken\fR in the slave interpreter.
+\fIsrcToken\fR refers to the value returned when the alias
+was created;  if the source command has been renamed, the renamed
+command will be deleted.
+.TP
+\fIslave \fBalias \fIsrcCmd targetCmd \fR?\fIarg ..\fR?
+.
+Creates an alias such that whenever \fIsrcCmd\fR is invoked
+in \fIslave\fR, \fItargetCmd\fR is invoked in the master.
+The \fIarg\fR arguments will be passed to \fItargetCmd\fR as additional
+arguments, prepended before any arguments passed in the invocation of
+\fIsrcCmd\fR.
+See \fBALIAS INVOCATION\fR below for details.
+The command returns a token that uniquely identifies the command created
+\fIsrcCmd\fR, even if the command is renamed afterwards. The token may but
+does not have to be equal to \fIsrcCmd\fR.
+.TP
+\fIslave \fBbgerror\fR ?\fIcmdPrefix\fR?
+.
+This command either gets or sets the current background exception handler
+for the \fIslave\fR interpreter. If \fIcmdPrefix\fR is
+absent, the current background exception handler is returned, and if it is
+present, it is a list of words (of minimum length one) that describes
+what to set the interpreter's background exception handler to. See the
+\fBBACKGROUND EXCEPTION HANDLING\fR section for more details.
+.TP
+\fIslave \fBeval \fIarg \fR?\fIarg ..\fR?
+.
+This command concatenates all of the \fIarg\fR arguments in
+the same fashion as the \fBconcat\fR command, then evaluates
+the resulting string as a Tcl script in \fIslave\fR.
+The result of this evaluation (including all \fBreturn\fR options,
+such as \fB\-errorinfo\fR and \fB\-errorcode\fR information, if an
+error occurs) is returned to the invoking interpreter.
+Note that the script will be executed in the current context stack frame
+of \fIslave\fR; this is so that the implementations (in a master
+interpreter) of aliases in a slave interpreter can execute scripts in
+the slave that find out information about the slave's current state
+and stack frame.
+.TP
+\fIslave \fBexpose \fIhiddenName \fR?\fIexposedCmdName\fR?
+.
+This command exposes the hidden command \fIhiddenName\fR, eventually bringing
+it back under a new \fIexposedCmdName\fR name (this name is currently
+accepted only if it is a valid global name space name without any ::),
+in \fIslave\fR.
+If an exposed command with the targeted name already exists, this command
+fails.
+For more details on hidden commands, see \fBHIDDEN COMMANDS\fR, below.
+.TP
+\fIslave \fBhide \fIexposedCmdName\fR ?\fIhiddenCmdName\fR?
+.
+This command hides the exposed command \fIexposedCmdName\fR, renaming it to
+the hidden command \fIhiddenCmdName\fR, or keeping the same name if the
+argument is not given, in the \fIslave\fR interpreter.
+If a hidden command with the targeted name already exists, this command
+fails.
+Currently both \fIexposedCmdName\fR and \fIhiddenCmdName\fR can
+not contain namespace qualifiers, or an error is raised.
+Commands to be hidden are looked up in the global
+namespace even if the current namespace is not the global one. This
+prevents slaves from fooling a master interpreter into hiding the wrong
+command, by making the current namespace be different from the global one.
+For more details on hidden commands, see \fBHIDDEN COMMANDS\fR, below.
+.TP
+\fIslave \fBhidden\fR
+.
+Returns a list of the names of all hidden commands in \fIslave\fR.
+.TP
+\fIslave \fBinvokehidden\fR ?\fI\-option ...\fR? \fIhiddenName \fR?\fIarg ..\fR?
+.
+This command invokes the hidden command \fIhiddenName\fR with the
+supplied arguments, in \fIslave\fR. No substitutions or evaluations are
+applied to the arguments. Three \fI\-option\fRs are supported, all
+of which start with \fB\-\fR: \fB\-namespace\fR (which takes a single
+argument afterwards, \fInsName\fR), \fB\-global\fR, and \fB\-\|\-\fR.
+If the \fB\-namespace\fR flag is given, the hidden command is invoked in
+the specified namespace in the slave.
+If the \fB\-global\fR flag is given, the command is invoked at the global
+level in the slave; otherwise it is invoked at the current call frame and
+can access local variables in that or outer call frames.
+The \fB\-\|\-\fR flag allows the \fIhiddenCmdName\fR argument to start with a
+.QW \-
+character, and is otherwise unnecessary.
+If both the \fB\-namespace\fR and \fB\-global\fR flags are given, the
+\fB\-namespace\fR flag is ignored.
+Note that the hidden command will be executed (by default) in the
+current context stack frame of \fIslave\fR.
+For more details on hidden commands,
+see \fBHIDDEN COMMANDS\fR, below.
+.TP
+\fIslave \fBissafe\fR
+.
+Returns  \fB1\fR if the slave interpreter is safe, \fB0\fR otherwise.
+.TP
+\fIslave \fBlimit\fR \fIlimitType\fR ?\fI\-option\fR? ?\fIvalue\fR \fI...\fR?
+.
+Sets up, manipulates and queries the configuration of the resource
+limit \fIlimitType\fR for the slave interpreter.  If no \fI\-option\fR
+is specified, return the current configuration of the limit.  If
+\fI\-option\fR is the sole argument, return the value of that option.
+Otherwise, a list of \fI\-option\fR/\fIvalue\fR argument pairs must
+supplied. See \fBRESOURCE LIMITS\fR below for a more detailed explanation of
+what limits and options are supported.
+.TP
+\fIslave \fBmarktrusted\fR
+.
+Marks the slave interpreter as trusted. Can only be invoked by a
+trusted interpreter. This command does not expose any hidden
+commands in the slave interpreter. The command has no effect if the slave
+is already trusted.
+.TP
+\fIslave\fR \fBrecursionlimit\fR ?\fInewlimit\fR?
+.
+Returns the maximum allowable nesting depth for the \fIslave\fR interpreter.
+If \fInewlimit\fR is specified, the recursion limit in \fIslave\fR will be
+set so that nesting of more than \fInewlimit\fR calls to \fBTcl_Eval()\fR
+and related procedures in \fIslave\fR will return an error.
+The \fInewlimit\fR value is also returned.
+The \fInewlimit\fR value must be a positive integer between 1 and the
+maximum value of a non-long integer on the platform.
+.RS
+.PP
+The command sets the maximum size of the Tcl call stack only. It cannot
+by itself prevent stack overflows on the C stack being used by the
+application. If your machine has a limit on the size of the C stack, you
+may get stack overflows before reaching the limit set by the command. If
+this happens, see if there is a mechanism in your system for increasing
+the maximum size of the C stack.
+.RE
+.SH "SAFE INTERPRETERS"
+.PP
+A safe interpreter is one with restricted functionality, so that
+is safe to execute an arbitrary script from your worst enemy without
+fear of that script damaging the enclosing application or the rest
+of your computing environment.  In order to make an interpreter
+safe, certain commands and variables are removed from the interpreter.
+For example, commands to create files on disk are removed, and the
+\fBexec\fR command is removed, since it could be used to cause damage
+through subprocesses.
+Limited access to these facilities can be provided, by creating
+aliases to the master interpreter which check their arguments carefully
+and provide restricted access to a safe subset of facilities.
+For example, file creation might be allowed in a particular subdirectory
+and subprocess invocation might be allowed for a carefully selected and
+fixed set of programs.
+.PP
+A safe interpreter is created by specifying the \fB\-safe\fR switch
+to the \fBinterp create\fR command.  Furthermore, any slave created
+by a safe interpreter will also be safe.
+.PP
+A safe interpreter is created with exactly the following set of
+built-in commands:
+.DS
+.ta 1.2i 2.4i 3.6i
+\fBafter\fR	\fBappend\fR	\fBapply\fR	\fBarray\fR
+\fBbinary\fR	\fBbreak\fR	\fBcatch\fR	\fBchan\fR
+\fBclock\fR	\fBclose\fR	\fBconcat\fR	\fBcontinue\fR
+\fBdict\fR	\fBeof\fR	\fBerror\fR	\fBeval\fR
+\fBexpr\fR	\fBfblocked\fR	\fBfcopy\fR	\fBfileevent\fR
+\fBflush\fR	\fBfor\fR	\fBforeach\fR	\fBformat\fR
+\fBgets\fR	\fBglobal\fR	\fBif\fR	\fBincr\fR
+\fBinfo\fR	\fBinterp\fR	\fBjoin\fR	\fBlappend\fR
+\fBlassign\fR	\fBlindex\fR	\fBlinsert\fR	\fBlist\fR
+\fBllength\fR	\fBlrange\fR	\fBlrepeat\fR	\fBlreplace\fR
+\fBlsearch\fR	\fBlset\fR	\fBlsort\fR	\fBnamespace\fR
+\fBpackage\fR	\fBpid\fR	\fBproc\fR	\fBputs\fR
+\fBread\fR	\fBregexp\fR	\fBregsub\fR	\fBrename\fR
+\fBreturn\fR	\fBscan\fR	\fBseek\fR	\fBset\fR
+\fBsplit\fR	\fBstring\fR	\fBsubst\fR	\fBswitch\fR
+\fBtell\fR	\fBtime\fR	\fBtrace\fR	\fBunset\fR
+\fBupdate\fR	\fBuplevel\fR	\fBupvar\fR	\fBvariable\fR
+\fBvwait\fR	\fBwhile\fR
+.DE
+The following commands are hidden by \fBinterp create\fR when it
+creates a safe interpreter:
+.DS
+.ta 1.2i 2.4i 3.6i
+\fBcd\fR	\fBencoding\fR	\fBexec\fR	\fBexit\fR
+\fBfconfigure\fR	\fBfile\fR	\fBglob\fR	\fBload\fR
+\fBopen\fR	\fBpwd\fR	\fBsocket\fR	\fBsource\fR
+\fBunload\fR
+.DE
+These commands can be recreated later as Tcl procedures or aliases, or
+re-exposed by \fBinterp expose\fR.
+.PP
+The following commands from Tcl's library of support procedures are
+not present in a safe interpreter:
+.DS
+.ta 1.6i 3.2i
+\fBauto_exec_ok\fR	\fBauto_import\fR	\fBauto_load\fR
+\fBauto_load_index\fR	\fBauto_qualify\fR	\fBunknown\fR
+.DE
+Note in particular that safe interpreters have no default \fBunknown\fR
+command, so Tcl's default autoloading facilities are not available.
+Autoload access to Tcl's commands that are normally autoloaded:
+.DS
+.ta 2.1i
+\fBauto_mkindex\fR	\fBauto_mkindex_old\fR
+\fBauto_reset\fR	\fBhistory\fR
+\fBparray\fR	\fBpkg_mkIndex\fR
+\fB::pkg::create\fR	\fB::safe::interpAddToAccessPath\fR
+\fB::safe::interpCreate\fR	\fB::safe::interpConfigure\fR
+\fB::safe::interpDelete\fR	\fB::safe::interpFindInAccessPath\fR
+\fB::safe::interpInit\fR	\fB::safe::setLogCmd\fR
+\fBtcl_endOfWord\fR	\fBtcl_findLibrary\fR
+\fBtcl_startOfNextWord\fR	\fBtcl_startOfPreviousWord\fR
+\fBtcl_wordBreakAfter\fR	\fBtcl_wordBreakBefore\fR
+.DE
+can only be provided by explicit definition of an \fBunknown\fR command
+in the safe interpreter.  This will involve exposing the \fBsource\fR
+command.  This is most easily accomplished by creating the safe interpreter
+with Tcl's \fBSafe\-Tcl\fR mechanism.  \fBSafe\-Tcl\fR provides safe
+versions of \fBsource\fR, \fBload\fR, and other Tcl commands needed
+to support autoloading of commands and the loading of packages.
+.PP
+In addition, the \fBenv\fR variable is not present in a safe interpreter,
+so it cannot share environment variables with other interpreters. The
+\fBenv\fR variable poses a security risk, because users can store
+sensitive information in an environment variable. For example, the PGP
+manual recommends storing the PGP private key protection password in
+the environment variable \fIPGPPASS\fR. Making this variable available
+to untrusted code executing in a safe interpreter would incur a
+security risk.
+.PP
+If extensions are loaded into a safe interpreter, they may also restrict
+their own functionality to eliminate unsafe commands. For a discussion of
+management of extensions for safety see the manual entries for
+\fBSafe\-Tcl\fR and the \fBload\fR Tcl command.
+.PP
+A safe interpreter may not alter the recursion limit of any interpreter,
+including itself.
+.SH "ALIAS INVOCATION"
+.PP
+The alias mechanism has been carefully designed so that it can
+be used safely when an untrusted script is executing
+in a safe slave and the target of the alias is a trusted
+master.  The most important thing in guaranteeing safety is to
+ensure that information passed from the slave to the master is
+never evaluated or substituted in the master;  if this were to
+occur, it would enable an evil script in the slave to invoke
+arbitrary functions in the master, which would compromise security.
+.PP
+When the source for an alias is invoked in the slave interpreter, the
+usual Tcl substitutions are performed when parsing that command.
+These substitutions are carried out in the source interpreter just
+as they would be for any other command invoked in that interpreter.
+The command procedure for the source command takes its arguments
+and merges them with the \fItargetCmd\fR and \fIarg\fRs for the
+alias to create a new array of arguments.  If the words
+of \fIsrcCmd\fR were
+.QW "\fIsrcCmd arg1 arg2 ... argN\fR" ,
+the new set of words will be
+.QW "\fItargetCmd arg arg ... arg arg1 arg2 ... argN\fR" ,
+where \fItargetCmd\fR and \fIarg\fRs are the values supplied when the
+alias was created.  \fITargetCmd\fR is then used to locate a command
+procedure in the target interpreter, and that command procedure
+is invoked with the new set of arguments.  An error occurs if
+there is no command named \fItargetCmd\fR in the target interpreter.
+No additional substitutions are performed on the words:  the
+target command procedure is invoked directly, without
+going through the normal Tcl evaluation mechanism.
+Substitutions are thus performed on each word exactly once:
+\fItargetCmd\fR and \fIargs\fR were substituted when parsing the command
+that created the alias, and \fIarg1 - argN\fR are substituted when
+the alias's source command is parsed in the source interpreter.
+.PP
+When writing the \fItargetCmd\fRs for aliases in safe interpreters,
+it is very important that the arguments to that command never be
+evaluated or substituted, since this would provide an escape
+mechanism whereby the slave interpreter could execute arbitrary
+code in the master.  This in turn would compromise the security
+of the system.
+.SH "HIDDEN COMMANDS"
+.PP
+Safe interpreters greatly restrict the functionality available to Tcl
+programs executing within them.
+Allowing the untrusted Tcl program to have direct access to this
+functionality is unsafe, because it can be used for a variety of
+attacks on the environment.
+However, there are times when there is a legitimate need to use the
+dangerous functionality in the context of the safe interpreter. For
+example, sometimes a program must be \fBsource\fRd into the interpreter.
+Another example is Tk, where windows are bound to the hierarchy of windows
+for a specific interpreter; some potentially dangerous functions, e.g.
+window management, must be performed on these windows within the
+interpreter context.
+.PP
+The \fBinterp\fR command provides a solution to this problem in the form of
+\fIhidden commands\fR. Instead of removing the dangerous commands entirely
+from a safe interpreter, these commands are hidden so they become
+unavailable to Tcl scripts executing in the interpreter. However, such
+hidden commands can be invoked by any trusted ancestor of the safe
+interpreter, in the context of the safe interpreter, using \fBinterp
+invoke\fR. Hidden commands and exposed commands reside in separate name
+spaces. It is possible to define a hidden command and an exposed command by
+the same name within one interpreter.
+.PP
+Hidden commands in a slave interpreter can be invoked in the body of
+procedures called in the master during alias invocation. For example, an
+alias for \fBsource\fR could be created in a slave interpreter. When it is
+invoked in the slave interpreter, a procedure is called in the master
+interpreter to check that the operation is allowable (e.g. it asks to
+source a file that the slave interpreter is allowed to access). The
+procedure then it invokes the hidden \fBsource\fR command in the slave
+interpreter to actually source in the contents of the file. Note that two
+commands named \fBsource\fR exist in the slave interpreter: the alias, and
+the hidden command.
+.PP
+Because a master interpreter may invoke a hidden command as part of
+handling an alias invocation, great care must be taken to avoid evaluating
+any arguments passed in through the alias invocation.
+Otherwise, malicious slave interpreters could cause a trusted master
+interpreter to execute dangerous commands on their behalf. See the section
+on \fBALIAS INVOCATION\fR for a more complete discussion of this topic.
+To help avoid this problem, no substitutions or evaluations are
+applied to arguments of \fBinterp invokehidden\fR.
+.PP
+Safe interpreters are not allowed to invoke hidden commands in themselves
+or in their descendants. This prevents safe slaves from gaining access to
+hidden functionality in themselves or their descendants.
+.PP
+The set of hidden commands in an interpreter can be manipulated by a trusted
+interpreter using \fBinterp expose\fR and \fBinterp hide\fR. The \fBinterp
+expose\fR command moves a hidden command to the
+set of exposed commands in the interpreter identified by \fIpath\fR,
+potentially renaming the command in the process. If an exposed command by
+the targeted name already exists, the operation fails. Similarly,
+\fBinterp hide\fR moves an exposed command to the set of hidden commands in
+that interpreter. Safe interpreters are not allowed to move commands
+between the set of hidden and exposed commands, in either themselves or
+their descendants.
+.PP
+Currently, the names of hidden commands cannot contain namespace
+qualifiers, and you must first rename a command in a namespace to the
+global namespace before you can hide it.
+Commands to be hidden by \fBinterp hide\fR are looked up in the global
+namespace even if the current namespace is not the global one. This
+prevents slaves from fooling a master interpreter into hiding the wrong
+command, by making the current namespace be different from the global one.
+.SH "RESOURCE LIMITS"
+.PP
+Every interpreter has two kinds of resource limits that may be imposed by any
+master interpreter upon its slaves. Command limits (of type \fBcommand\fR)
+restrict the total number of Tcl commands that may be executed by an
+interpreter (as can be inspected via the \fBinfo cmdcount\fR command), and
+time limits (of type \fBtime\fR) place a limit by which execution within the
+interpreter must complete. Note that time limits are expressed as
+\fIabsolute\fR times (as in \fBclock seconds\fR) and not relative times (as in
+\fBafter\fR) because they may be modified after creation.
+.PP
+When a limit is exceeded for an interpreter, first any handler callbacks
+defined by master interpreters are called. If those callbacks increase or
+remove the limit, execution within the (previously) limited interpreter
+continues. If the limit is still in force, an error is generated at that point
+and normal processing of errors within the interpreter (by the \fBcatch\fR
+command) is disabled, so the error propagates outwards (building a stack-trace
+as it goes) to the point where the limited interpreter was invoked (e.g. by
+\fBinterp eval\fR) where it becomes the responsibility of the calling code to
+catch and handle.
+.SS "LIMIT OPTIONS"
+.PP
+Every limit has a number of options associated with it, some of which are
+common across all kinds of limits, and others of which are particular to the
+kind of limit.
+.TP
+\fB\-command\fR
+.
+This option (common for all limit types) specifies (if non-empty) a Tcl script
+to be executed in the global namespace of the interpreter reading and writing
+the option when the particular limit in the limited interpreter is exceeded.
+The callback may modify the limit on the interpreter if it wishes the limited
+interpreter to continue executing. If the callback generates an exception, it
+is reported through the background exception mechanism (see
+\fBBACKGROUND EXCEPTION HANDLING\fR).
+Note that the callbacks defined by one interpreter are
+completely isolated from the callbacks defined by another, and that the order
+in which those callbacks are called is undefined.
+.TP
+\fB\-granularity\fR
+.
+This option (common for all limit types) specifies how frequently (out of the
+points when the Tcl interpreter is in a consistent state where limit checking
+is possible) that the limit is actually checked. This allows the tuning of how
+frequently a limit is checked, and hence how often the limit-checking overhead
+(which may be substantial in the case of time limits) is incurred.
+.TP
+\fB\-milliseconds\fR
+.
+This option specifies the number of milliseconds after the moment defined in
+the \fB\-seconds\fR option that the time limit will fire. It should only ever
+be specified in conjunction with the \fB\-seconds\fR option (whether it was
+set previously or is being set this invocation.)
+.TP
+\fB\-seconds\fR
+.
+This option specifies the number of seconds after the epoch (see \fBclock
+seconds\fR) that the time limit for the interpreter will be triggered. The
+limit will be triggered at the start of the second unless specified at a
+sub-second level using the \fB\-milliseconds\fR option. This option may be the
+empty string, which indicates that a time limit is not set for the
+interpreter.
+.TP
+\fB\-value\fR
+.
+This option specifies the number of commands that the interpreter may execute
+before triggering the command limit. This option may be the empty string,
+which indicates that a command limit is not set for the interpreter.
+.PP
+Where an interpreter with a resource limit set on it creates a slave
+interpreter, that slave interpreter will have resource limits imposed on it
+that are at least as restrictive as the limits on the creating master
+interpreter. If the master interpreter of the limited master wishes to relax
+these conditions, it should hide the \fBinterp\fR command in the child and
+then use aliases and the \fBinterp invokehidden\fR subcommand to provide such
+access as it chooses to the \fBinterp\fR command to the limited master as
+necessary.
+.SH "BACKGROUND EXCEPTION HANDLING"
+.PP
+When an exception happens in a situation where it cannot be reported directly up
+the stack (e.g. when processing events in an \fBupdate\fR or \fBvwait\fR call)
+the exception is instead reported through the background exception handling mechanism.
+Every interpreter has a background exception handler registered; the default exception
+handler arranges for the \fBbgerror\fR command in the interpreter's global
+namespace to be called, but other exception handlers may be installed and process
+background exceptions in substantially different ways.
+.PP
+A background exception handler consists of a non-empty list of words to which will
+be appended two further words at invocation time. The first word will be the
+interpreter result at time of the exception, typically an error message,
+and the second will be the dictionary of return options at the time of
+the exception.  These are the same values that \fBcatch\fR can capture
+when it controls script evaluation in a non-background situation.
+The resulting list will then be executed
+in the interpreter's global namespace without further substitutions being
+performed.
+.SH CREDITS
+The safe interpreter mechanism is based on the Safe-Tcl prototype implemented
+by Nathaniel Borenstein and Marshall Rose.
+.SH EXAMPLES
+.PP
+Creating and using an alias for a command in the current interpreter:
+.PP
+.CS
+\fBinterp alias\fR {} getIndex {} lsearch {alpha beta gamma delta}
+set idx [getIndex delta]
+.CE
+.PP
+Executing an arbitrary command in a safe interpreter where every
+invocation of \fBlappend\fR is logged:
+.PP
+.CS
+set i [\fBinterp create\fR -safe]
+\fBinterp hide\fR $i lappend
+\fBinterp alias\fR $i lappend {} loggedLappend $i
+proc loggedLappend {i args} {
+    puts "logged invocation of lappend $args"
+    \fBinterp invokehidden\fR $i lappend {*}$args
+}
+\fBinterp eval\fR $i $someUntrustedScript
+.CE
+.PP
+Setting a resource limit on an interpreter so that an infinite loop
+terminates.
+.PP
+.CS
+set i [\fBinterp create\fR]
+\fBinterp limit\fR $i command -value 1000
+\fBinterp eval\fR $i {
+    set x 0
+    while {1} {
+        puts "Counting up... [incr x]"
+    }
+}
+.CE
+.SH "SEE ALSO"
+bgerror(n), load(n), safe(n), Tcl_CreateSlave(3), Tcl_Eval(3), Tcl_BackgroundException(3)
+.SH KEYWORDS
+alias, master interpreter, safe interpreter, slave interpreter
+'\"Local Variables:
+'\"mode: nroff
+'\"End:
diff --git a/doc/join.n b/doc/join.n
new file mode 100644
index 0000000..c8179bb
--- /dev/null
+++ b/doc/join.n
@@ -0,0 +1,44 @@
+'\"
+'\" Copyright (c) 1993 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\" 
+.TH join n "" Tcl "Tcl Built-In Commands"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+join \- Create a string by joining together list elements
+.SH SYNOPSIS
+\fBjoin \fIlist \fR?\fIjoinString\fR?
+.BE
+.SH DESCRIPTION
+.PP
+The \fIlist\fR argument must be a valid Tcl list.
+This command returns the string
+formed by joining all of the elements of \fIlist\fR together with
+\fIjoinString\fR separating each adjacent pair of elements.
+The \fIjoinString\fR argument defaults to a space character.
+.SH EXAMPLES
+.PP
+Making a comma-separated list:
+.PP
+.CS
+set data {1 2 3 4 5}
+\fBjoin\fR $data ", "
+     \fB\(-> 1, 2, 3, 4, 5\fR
+.CE
+.PP
+Using \fBjoin\fR to flatten a list by a single level:
+.PP
+.CS
+set data {1 {2 3} 4 {5 {6 7} 8}}
+\fBjoin\fR $data
+     \fB\(-> 1 2 3 4 5 {6 7} 8\fR
+.CE
+.SH "SEE ALSO"
+list(n), lappend(n), split(n)
+.SH KEYWORDS
+element, join, list, separator
diff --git a/doc/lappend.n b/doc/lappend.n
new file mode 100644
index 0000000..a324ca3
--- /dev/null
+++ b/doc/lappend.n
@@ -0,0 +1,49 @@
+'\"
+'\" Copyright (c) 1993 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\" Copyright (c) 2001 Kevin B. Kenny <kennykb@acm.org>.  All rights reserved.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\" 
+.TH lappend n "" Tcl "Tcl Built-In Commands"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+lappend \- Append list elements onto a variable
+.SH SYNOPSIS
+\fBlappend \fIvarName \fR?\fIvalue value value ...\fR?
+.BE
+.SH DESCRIPTION
+.PP
+This command treats the variable given by \fIvarName\fR as a list
+and appends each of the \fIvalue\fR arguments to that list as a separate
+element, with spaces between elements.
+If \fIvarName\fR does not exist, it is created as a list with elements
+given by the \fIvalue\fR arguments.
+\fBLappend\fR is similar to \fBappend\fR except that the \fIvalue\fRs
+are appended as list elements rather than raw text.
+This command provides a relatively efficient way to build up
+large lists.  For example,
+.QW "\fBlappend a $b\fR"
+is much more efficient than
+.QW "\fBset a [concat $a [list $b]]\fR"
+when \fB$a\fR is long.
+.SH EXAMPLE
+.PP
+Using \fBlappend\fR to build up a list of numbers.
+.PP
+.CS
+% set var 1
+1
+% \fBlappend\fR var 2
+1 2
+% \fBlappend\fR var 3 4 5
+1 2 3 4 5
+.CE
+.SH "SEE ALSO"
+list(n), lindex(n), linsert(n), llength(n), lset(n),
+lsort(n), lrange(n)
+.SH KEYWORDS
+append, element, list, variable
diff --git a/doc/lassign.n b/doc/lassign.n
new file mode 100644
index 0000000..e250729
--- /dev/null
+++ b/doc/lassign.n
@@ -0,0 +1,60 @@
+'\"
+'\" Copyright (c) 1992-1999 Karl Lehenbauer & Mark Diekhans
+'\" Copyright (c) 2004 Donal K. Fellows
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\" 
+.TH lassign n 8.5 Tcl "Tcl Built-In Commands"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+lassign \- Assign list elements to variables
+.SH SYNOPSIS
+\fBlassign \fIlist \fR?\fIvarName ...\fR?
+.BE
+.SH DESCRIPTION
+.PP
+This command treats the value \fIlist\fR as a list and assigns
+successive elements from that list to the variables given by the
+\fIvarName\fR arguments in order.  If there are more variable names
+than list elements, the remaining variables are set to the empty
+string.  If there are more list elements than variables, a list of
+unassigned elements is returned.
+.SH EXAMPLES
+.PP
+An illustration of how multiple assignment works, and what happens
+when there are either too few or too many elements.
+.PP
+.CS
+\fBlassign\fR {a b c} x y z       ;# Empty return
+puts $x                     ;# Prints "a"
+puts $y                     ;# Prints "b"
+puts $z                     ;# Prints "c"
+
+\fBlassign\fR {d e} x y z         ;# Empty return
+puts $x                     ;# Prints "d"
+puts $y                     ;# Prints "e"
+puts $z                     ;# Prints ""
+
+\fBlassign\fR {f g h i} x y       ;# Returns "h i"
+puts $x                     ;# Prints "f"
+puts $y                     ;# Prints "g"
+.CE
+.PP
+The \fBlassign\fR command has other uses.  It can be used to create
+the analogue of the
+.QW shift
+command in many shell languages like this:
+.PP
+.CS
+set ::argv [\fBlassign\fR $::argv argumentToReadOff]
+.CE
+.SH "SEE ALSO"
+lindex(n), list(n), lrange(n), lset(n), set(n)
+.SH KEYWORDS
+assign, element, list, multiple, set, variable
+'\"Local Variables:
+'\"mode: nroff
+'\"End:
diff --git a/doc/library.n b/doc/library.n
new file mode 100644
index 0000000..6f8f265
--- /dev/null
+++ b/doc/library.n
@@ -0,0 +1,320 @@
+'\"
+'\" Copyright (c) 1991-1993 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH library n "8.0" Tcl "Tcl Built-In Commands"
+.so man.macros
+.BS
+.SH NAME
+auto_execok, auto_import, auto_load, auto_mkindex, auto_qualify, auto_reset, tcl_findLibrary, parray, tcl_endOfWord, tcl_startOfNextWord, tcl_startOfPreviousWord, tcl_wordBreakAfter, tcl_wordBreakBefore \- standard library of Tcl procedures
+.SH SYNOPSIS
+.nf
+\fBauto_execok \fIcmd\fR
+\fBauto_import \fIpattern\fR
+\fBauto_load \fIcmd\fR
+\fBauto_mkindex \fIdir pattern pattern ...\fR
+\fBauto_qualify \fIcommand namespace\fR
+\fBauto_reset\fR
+\fBtcl_findLibrary \fIbasename version patch initScript enVarName varName\fR
+\fBparray \fIarrayName\fR ?\fIpattern\fR?
+\fBtcl_endOfWord \fIstr start\fR
+\fBtcl_startOfNextWord \fIstr start\fR
+\fBtcl_startOfPreviousWord \fIstr start\fR
+\fBtcl_wordBreakAfter \fIstr start\fR
+\fBtcl_wordBreakBefore \fIstr start\fR
+.BE
+.SH INTRODUCTION
+.PP
+Tcl includes a library of Tcl procedures for commonly-needed functions.
+The procedures defined in the Tcl library are generic ones suitable
+for use by many different applications.
+The location of the Tcl library is returned by the \fBinfo library\fR
+command.
+In addition to the Tcl library, each application will normally have
+its own library of support procedures as well;  the location of this
+library is normally given by the value of the \fB$\fIapp\fB_library\fR
+global variable, where \fIapp\fR is the name of the application.
+For example, the location of the Tk library is kept in the variable
+\fBtk_library\fR.
+.PP
+To access the procedures in the Tcl library, an application should
+source the file \fBinit.tcl\fR in the library, for example with
+the Tcl command
+.PP
+.CS
+\fBsource [file join [info library] init.tcl]\fR
+.CE
+.PP
+If the library procedure \fBTcl_Init\fR is invoked from an application's
+\fBTcl_AppInit\fR procedure, this happens automatically.
+The code in \fBinit.tcl\fR will define the \fBunknown\fR procedure
+and arrange for the other procedures to be loaded on-demand using
+the auto-load mechanism defined below.
+.SH "COMMAND PROCEDURES"
+.PP
+The following procedures are provided in the Tcl library:
+.TP
+\fBauto_execok \fIcmd\fR
+Determines whether there is an executable file or shell builtin
+by the name \fIcmd\fR.  If so, it returns a list of arguments to be
+passed to \fBexec\fR to execute the executable file or shell builtin
+named by \fIcmd\fR.  If not, it returns an empty string.  This command
+examines the directories in the current search path (given by the PATH
+environment variable) in its search for an executable file named
+\fIcmd\fR.  On Windows platforms, the search is expanded with the same
+directories and file extensions as used by \fBexec\fR. \fBAuto_execok\fR
+remembers information about previous searches in an array named
+\fBauto_execs\fR;  this avoids the path search in future calls for the
+same \fIcmd\fR.  The command \fBauto_reset\fR may be used to force
+\fBauto_execok\fR to forget its cached information.
+.TP
+\fBauto_import \fIpattern\fR
+\fBAuto_import\fR is invoked during \fBnamespace import\fR to see if
+the imported commands specified by \fIpattern\fR reside in an
+autoloaded library.  If so, the commands are loaded so that they will
+be available to the interpreter for creating the import links.  If the
+commands do not reside in an autoloaded library, \fBauto_import\fR
+does nothing.  The pattern matching is performed according to the
+matching rules of \fBnamespace import\fR.
+.TP
+\fBauto_load \fIcmd\fR
+This command attempts to load the definition for a Tcl command named
+\fIcmd\fR.  To do this, it searches an \fIauto-load path\fR, which is
+a list of one or more directories.  The auto-load path is given by the
+global variable \fBauto_path\fR if it exists.  If there is no
+\fBauto_path\fR variable, then the TCLLIBPATH environment variable is
+used, if it exists.  Otherwise the auto-load path consists of just the
+Tcl library directory.  Within each directory in the auto-load path
+there must be a file \fBtclIndex\fR that describes one or more
+commands defined in that directory and a script to evaluate to load
+each of the commands.  The \fBtclIndex\fR file should be generated
+with the \fBauto_mkindex\fR command.  If \fIcmd\fR is found in an
+index file, then the appropriate script is evaluated to create the
+command.  The \fBauto_load\fR command returns 1 if \fIcmd\fR was
+successfully created.  The command returns 0 if there was no index
+entry for \fIcmd\fR or if the script did not actually define \fIcmd\fR
+(e.g. because index information is out of date).  If an error occurs
+while processing the script, then that error is returned.
+\fBAuto_load\fR only reads the index information once and saves it in
+the array \fBauto_index\fR;  future calls to \fBauto_load\fR check for
+\fIcmd\fR in the array rather than re-reading the index files.  The
+cached index information may be deleted with the command
+\fBauto_reset\fR.  This will force the next \fBauto_load\fR command to
+reload the index database from disk.
+.TP
+\fBauto_mkindex \fIdir pattern pattern ...\fR
+.
+Generates an index suitable for use by \fBauto_load\fR.  The command
+searches \fIdir\fR for all files whose names match any of the
+\fIpattern\fR arguments (matching is done with the \fBglob\fR
+command), generates an index of all the Tcl command procedures defined
+in all the matching files, and stores the index information in a file
+named \fBtclIndex\fR in \fIdir\fR. If no pattern is given a pattern of
+\fB*.tcl\fR will be assumed.  For example, the command
+.RS
+.PP
+.CS
+\fBauto_mkindex foo *.tcl\fR
+.CE
+.PP
+will read all the \fB.tcl\fR files in subdirectory \fBfoo\fR and
+generate a new index file \fBfoo/tclIndex\fR.
+.PP
+\fBAuto_mkindex\fR parses the Tcl scripts by sourcing them into a
+slave interpreter and monitoring the proc and namespace commands that
+are executed.  Extensions can use the (undocumented)
+auto_mkindex_parser package to register other commands that can
+contribute to the auto_load index. You will have to read through
+auto.tcl to see how this works.
+.PP
+\fBAuto_mkindex_old\fR
+(which has the same syntax as \fBauto_mkindex\fR)
+parses the Tcl scripts in a relatively
+unsophisticated way:  if any line contains the word
+.QW \fBproc\fR
+as its first characters then it is assumed to be a procedure
+definition and the next word of the line is taken as the
+procedure's name.
+Procedure definitions that do not appear in this way (e.g.\ they
+have spaces before the \fBproc\fR) will not be indexed.  If your
+script contains
+.QW dangerous
+code, such as global initialization
+code or procedure names with special characters like \fB$\fR,
+\fB*\fR, \fB[\fR or \fB]\fR, you are safer using \fBauto_mkindex_old\fR.
+.RE
+.TP
+\fBauto_reset\fR
+.
+Destroys all the information cached by \fBauto_execok\fR and
+\fBauto_load\fR.  This information will be re-read from disk the next
+time it is needed.  \fBAuto_reset\fR also deletes any procedures
+listed in the auto-load index, so that fresh copies of them will be
+loaded the next time that they are used.
+.TP
+\fBauto_qualify \fIcommand namespace\fR
+Computes a list of fully qualified names for \fIcommand\fR.  This list
+mirrors the path a standard Tcl interpreter follows for command
+lookups:  first it looks for the command in the current namespace, and
+then in the global namespace.  Accordingly, if \fIcommand\fR is
+relative and \fInamespace\fR is not \fB::\fR, the list returned has
+two elements:  \fIcommand\fR scoped by \fInamespace\fR, as if it were
+a command in the \fInamespace\fR namespace; and \fIcommand\fR as if it
+were a command in the global namespace.  Otherwise, if either
+\fIcommand\fR is absolute (it begins with \fB::\fR), or
+\fInamespace\fR is \fB::\fR, the list contains only \fIcommand\fR as
+if it were a command in the global namespace.
+.RS
+.PP
+\fBAuto_qualify\fR is used by the auto-loading facilities in Tcl, both
+for producing auto-loading indexes such as \fIpkgIndex.tcl\fR, and for
+performing the actual auto-loading of functions at runtime.
+.RE
+.TP
+\fBtcl_findLibrary \fIbasename version patch initScript enVarName varName\fR
+This is a standard search procedure for use by extensions during
+their initialization.  They call this procedure to look for their
+script library in several standard directories.
+The last component of the name of the library directory is
+normally \fIbasenameversion\fR
+(e.g., tk8.0), but it might be
+.QW library
+when in the build hierarchies.
+The \fIinitScript\fR file will be sourced into the interpreter
+once it is found.  The directory in which this file is found is
+stored into the global variable \fIvarName\fR.
+If this variable is already defined (e.g., by C code during
+application initialization) then no searching is done.
+Otherwise the search looks in these directories:
+the directory named by the environment variable \fIenVarName\fR;
+relative to the Tcl library directory;
+relative to the executable file in the standard installation
+bin or bin/\fIarch\fR directory;
+relative to the executable file in the current build tree;
+relative to the executable file in a parallel build tree.
+.TP
+\fBparray \fIarrayName\fR ?\fIpattern\fR?
+Prints on standard output the names and values of all the elements in the
+array \fIarrayName\fR, or just the names that match \fIpattern\fR (using the
+matching rules of \fBstring match\fR) and their values if \fIpattern\fR is
+given.
+\fIArrayName\fR must be an array accessible to the caller of \fBparray\fR.
+It may be either local or global.
+.TP
+\fBtcl_endOfWord \fIstr start\fR
+Returns the index of the first end-of-word location that occurs after
+a starting index \fIstart\fR in the string \fIstr\fR.  An end-of-word
+location is defined to be the first non-word character following the
+first word character after the starting point.  Returns -1 if there
+are no more end-of-word locations after the starting point.  See the
+description of \fBtcl_wordchars\fR and \fBtcl_nonwordchars\fR below
+for more details on how Tcl determines which characters are word
+characters.
+.TP
+\fBtcl_startOfNextWord \fIstr start\fR
+Returns the index of the first start-of-word location that occurs
+after a starting index \fIstart\fR in the string \fIstr\fR.  A
+start-of-word location is defined to be the first word character
+following a non-word character.  Returns \-1 if there are no more
+start-of-word locations after the starting point.
+.TP
+\fBtcl_startOfPreviousWord \fIstr start\fR
+Returns the index of the first start-of-word location that occurs
+before a starting index \fIstart\fR in the string \fIstr\fR.  Returns
+\-1 if there are no more start-of-word locations before the starting
+point.
+.TP
+\fBtcl_wordBreakAfter \fIstr start\fR
+Returns the index of the first word boundary after the starting index
+\fIstart\fR in the string \fIstr\fR.  Returns \-1 if there are no more
+boundaries after the starting point in the given string.  The index
+returned refers to the second character of the pair that comprises a
+boundary.
+.TP
+\fBtcl_wordBreakBefore \fIstr start\fR
+Returns the index of the first word boundary before the starting index
+\fIstart\fR in the string \fIstr\fR.  Returns \-1 if there are no more
+boundaries before the starting point in the given string.  The index
+returned refers to the second character of the pair that comprises a
+boundary.
+.SH "VARIABLES"
+.PP
+The following global variables are defined or used by the procedures in
+the Tcl library. They fall into two broad classes, handling unknown
+commands and packages, and determining what are words.
+.SS "AUTOLOADING AND PACKAGE MANAGEMENT VARIABLES"
+.TP
+\fBauto_execs\fR
+Used by \fBauto_execok\fR to record information about whether
+particular commands exist as executable files.
+.TP
+\fBauto_index\fR
+Used by \fBauto_load\fR to save the index information read from
+disk.
+.TP
+\fBauto_noexec\fR
+If set to any value, then \fBunknown\fR will not attempt to auto-exec
+any commands.
+.TP
+\fBauto_noload\fR
+If set to any value, then \fBunknown\fR will not attempt to auto-load
+any commands.
+.TP
+\fBauto_path\fR
+.
+If set, then it must contain a valid Tcl list giving directories to
+search during auto-load operations (including for package index
+files when using the default \fBpackage unknown\fR handler).
+This variable is initialized during startup to contain, in order:
+the directories listed in the \fBTCLLIBPATH\fR environment variable,
+the directory named by the \fBtcl_library\fR global variable,
+the parent directory of \fBtcl_library\fR,
+the directories listed in the \fBtcl_pkgPath\fR variable.
+Additional locations to look for files and package indices should
+normally be added to this variable using \fBlappend\fR.
+.TP
+\fBenv(TCL_LIBRARY)\fR
+If set, then it specifies the location of the directory containing
+library scripts (the value of this variable will be
+assigned to the \fBtcl_library\fR variable and therefore returned by
+the command \fBinfo library\fR).  If this variable is not set then
+a default value is used.
+.TP
+\fBenv(TCLLIBPATH)\fR
+If set, then it must contain a valid Tcl list giving directories to
+search during auto-load operations.  Directories must be specified in
+Tcl format, using
+.QW /
+as the path separator, regardless of platform.
+This variable is only used when initializing the \fBauto_path\fR variable.
+.SS "WORD BOUNDARY DETERMINATION VARIABLES"
+These variables are only used in the \fBtcl_endOfWord\fR,
+\fBtcl_startOfNextWord\fR, \fBtcl_startOfPreviousWord\fR,
+\fBtcl_wordBreakAfter\fR, and \fBtcl_wordBreakBefore\fR commands.
+.TP
+\fBtcl_nonwordchars\fR
+This variable contains a regular expression that is used by routines
+like \fBtcl_endOfWord\fR to identify whether a character is part of a
+word or not.  If the pattern matches a character, the character is
+considered to be a non-word character.  On Windows platforms, spaces,
+tabs, and newlines are considered non-word characters.  Under Unix,
+everything but numbers, letters and underscores are considered
+non-word characters.
+.TP
+\fBtcl_wordchars\fR
+This variable contains a regular expression that is used by routines
+like \fBtcl_endOfWord\fR to identify whether a character is part of a
+word or not.  If the pattern matches a character, the character is
+considered to be a word character.  On Windows platforms, words are
+comprised of any character that is not a space, tab, or newline.  Under
+Unix, words are comprised of numbers, letters or underscores.
+.SH "SEE ALSO"
+env(n), info(n), re_syntax(n)
+.SH KEYWORDS
+auto-exec, auto-load, library, unknown, word, whitespace
+'\"Local Variables:
+'\"mode: nroff
+'\"End:
diff --git a/doc/lindex.n b/doc/lindex.n
new file mode 100644
index 0000000..d5605bc
--- /dev/null
+++ b/doc/lindex.n
@@ -0,0 +1,125 @@
+'\"
+'\" Copyright (c) 1993 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\" Copyright (c) 2001 by Kevin B. Kenny <kennykb@acm.org>.  All rights reserved.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH lindex n 8.4 Tcl "Tcl Built-In Commands"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+lindex \- Retrieve an element from a list
+.SH SYNOPSIS
+\fBlindex \fIlist ?index ...?\fR
+.BE
+.SH DESCRIPTION
+.PP
+The \fBlindex\fR command accepts a parameter, \fIlist\fR, which
+it treats as a Tcl list. It also accepts zero or more \fIindices\fR into
+the list.  The indices may be presented either consecutively on the
+command line, or grouped in a
+Tcl list and presented as a single argument.
+.PP
+If no indices are presented, the command takes the form:
+.PP
+.CS
+\fBlindex \fIlist\fR
+.CE
+.PP
+or
+.PP
+.CS
+\fBlindex \fIlist\fR {}
+.CE
+.PP
+In this case, the return value of \fBlindex\fR is simply the value of the
+\fIlist\fR parameter.
+.PP
+When presented with a single index, the \fBlindex\fR command
+treats \fIlist\fR as a Tcl list and returns the
+\fIindex\fR'th element from it (0 refers to the first element of the list).
+In extracting the element, \fBlindex\fR observes the same rules
+concerning braces and quotes and backslashes as the Tcl command
+interpreter; however, variable
+substitution and command substitution do not occur.
+If \fIindex\fR is negative or greater than or equal to the number
+of elements in \fIvalue\fR, then an empty
+string is returned.
+The interpretation of each simple \fIindex\fR value is the same as
+for the command \fBstring index\fR, supporting simple index
+arithmetic and indices relative to the end of the list.
+.PP
+If additional \fIindex\fR arguments are supplied, then each argument is
+used in turn to select an element from the previous indexing operation,
+allowing the script to select elements from sublists.  The command,
+.PP
+.CS
+\fBlindex\fR $a 1 2 3
+.CE
+.PP
+or
+.PP
+.CS
+\fBlindex\fR $a {1 2 3}
+.CE
+.PP
+is synonymous with
+.PP
+.CS
+\fBlindex\fR [\fBlindex\fR [\fBlindex\fR $a 1] 2] 3
+.CE
+.SH EXAMPLES
+.PP
+Lists can be indexed into from either end:
+.PP
+.CS
+\fBlindex\fR {a b c} 0
+      \fI\(-> a\fR
+\fBlindex\fR {a b c} 2
+      \fI\(-> c\fR
+\fBlindex\fR {a b c} end
+      \fI\(-> c\fR
+\fBlindex\fR {a b c} end-1
+      \fI\(-> b\fR
+.CE
+.PP
+Lists or sequences of indices allow selection into lists of lists:
+.PP
+.CS
+\fBlindex\fR {a b c}
+      \fI\(-> a b c\fR
+\fBlindex\fR {a b c} {}
+      \fI\(-> a b c\fR
+\fBlindex\fR {{a b c} {d e f} {g h i}} 2 1
+      \fI\(-> h\fR
+\fBlindex\fR {{a b c} {d e f} {g h i}} {2 1}
+      \fI\(-> h\fR
+\fBlindex\fR {{{a b} {c d}} {{e f} {g h}}} 1 1 0
+      \fI\(-> g\fR
+\fBlindex\fR {{{a b} {c d}} {{e f} {g h}}} {1 1 0}
+      \fI\(-> g\fR
+.CE
+.PP
+List indices may also perform limited computation, adding or subtracting fixed
+amounts from other indices:
+.PP
+.CS
+set idx 1
+\fBlindex\fR {a b c d e f} $idx+2
+      \fI\(-> d\fR
+set idx 3
+\fBlindex\fR {a b c d e f} $idx+2
+      \fI\(-> f\fR
+.CE
+.SH "SEE ALSO"
+list(n), lappend(n), linsert(n), llength(n), lsearch(n),
+lset(n), lsort(n), lrange(n), lreplace(n),
+string(n)
+.SH KEYWORDS
+element, index, list
+'\"Local Variables:
+'\"mode: nroff
+'\"End:
diff --git a/doc/linsert.n b/doc/linsert.n
new file mode 100644
index 0000000..91db726
--- /dev/null
+++ b/doc/linsert.n
@@ -0,0 +1,55 @@
+'\"
+'\" Copyright (c) 1993 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\" Copyright (c) 2001 Kevin B. Kenny <kennykb@acm.org>.  All rights reserved.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH linsert n 8.2 Tcl "Tcl Built-In Commands"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+linsert \- Insert elements into a list
+.SH SYNOPSIS
+\fBlinsert \fIlist index \fR?\fIelement element ...\fR?
+.BE
+.SH DESCRIPTION
+.PP
+This command produces a new list from \fIlist\fR by inserting all of the
+\fIelement\fR arguments just before the \fIindex\fR'th element of
+\fIlist\fR.  Each \fIelement\fR argument will become a separate element of
+the new list.  If \fIindex\fR is less than or equal to zero, then the new
+elements are inserted at the beginning of the list, and if \fIindex\fR is
+greater or equal to the length of \fIlist\fR, it is as if it was \fBend\fR.
+As with \fBstring index\fR, the \fIindex\fR value supports both simple index
+arithmetic and end-relative indexing.
+.PP
+Subject to the restrictions that indices must refer to locations inside the
+list and that the \fIelement\fRs will always be inserted in order, insertions
+are done so that when \fIindex\fR is start-relative, the first \fIelement\fR
+will be at that index in the resulting list, and when \fIindex\fR is
+end-relative, the last \fIelement\fR will be at that index in the resulting
+list.
+.SH EXAMPLE
+.PP
+Putting some values into a list, first indexing from the start and
+then indexing from the end, and then chaining them together:
+.PP
+.CS
+set oldList {the fox jumps over the dog}
+set midList [\fBlinsert\fR $oldList 1 quick]
+set newList [\fBlinsert\fR $midList end-1 lazy]
+# The old lists still exist though...
+set newerList [\fBlinsert\fR [\fBlinsert\fR $oldList end-1 quick] 1 lazy]
+.CE
+.SH "SEE ALSO"
+list(n), lappend(n), lindex(n), llength(n), lsearch(n),
+lset(n), lsort(n), lrange(n), lreplace(n),
+string(n)
+.SH KEYWORDS
+element, insert, list
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/doc/list.n b/doc/list.n
new file mode 100644
index 0000000..c2797f3
--- /dev/null
+++ b/doc/list.n
@@ -0,0 +1,56 @@
+'\"
+'\" Copyright (c) 1993 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\" Copyright (c) 2001 Kevin B. Kenny <kennykb@acm.org>.  All rights reserved.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\" 
+.TH list n "" Tcl "Tcl Built-In Commands"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+list \- Create a list
+.SH SYNOPSIS
+\fBlist \fR?\fIarg arg ...\fR?
+.BE
+.SH DESCRIPTION
+.PP
+This command returns a list comprised of all the \fIarg\fRs,
+or an empty string if no \fIarg\fRs are specified.
+Braces and backslashes get added as necessary, so that the \fBlindex\fR command
+may be used on the result to re-extract the original arguments, and also
+so that \fBeval\fR may be used to execute the resulting list, with
+\fIarg1\fR comprising the command's name and the other \fIarg\fRs comprising
+its arguments.  \fBList\fR produces slightly different results than
+\fBconcat\fR:  \fBconcat\fR removes one level of grouping before forming
+the list, while \fBlist\fR works directly from the original arguments.
+.SH EXAMPLE
+.PP
+The command
+.PP
+.CS
+\fBlist\fR a b "c d e  " "  f {g h}"
+.CE
+.PP
+will return
+.PP
+.CS
+\fBa b {c d e  } {  f {g h}}\fR
+.CE
+.PP
+while \fBconcat\fR with the same arguments will return
+.PP
+.CS
+\fBa b c d e f {g h}\fR
+.CE
+.SH "SEE ALSO"
+lappend(n), lindex(n), linsert(n), llength(n), lrange(n),
+lrepeat(n),
+lreplace(n), lsearch(n), lset(n), lsort(n)
+.SH KEYWORDS
+element, list, quoting
+'\"Local Variables:
+'\"mode: nroff
+'\"End:
diff --git a/doc/llength.n b/doc/llength.n
new file mode 100644
index 0000000..79f93c0
--- /dev/null
+++ b/doc/llength.n
@@ -0,0 +1,55 @@
+'\"
+'\" Copyright (c) 1993 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\" Copyright (c) 2001 Kevin B. Kenny <kennykb@acm.org>.  All rights reserved.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH llength n "" Tcl "Tcl Built-In Commands"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+llength \- Count the number of elements in a list
+.SH SYNOPSIS
+\fBllength \fIlist\fR
+.BE
+.SH DESCRIPTION
+.PP
+Treats \fIlist\fR as a list and returns a decimal string giving
+the number of elements in it.
+.SH EXAMPLES
+.PP
+The result is the number of elements:
+.PP
+.CS
+% \fBllength\fR {a b c d e}
+5
+% \fBllength\fR {a b c}
+3
+% \fBllength\fR {}
+0
+.CE
+.PP
+Elements are not guaranteed to be exactly words in a dictionary sense
+of course, especially when quoting is used:
+.PP
+.CS
+% \fBllength\fR {a b {c d} e}
+4
+% \fBllength\fR {a b { } c d e}
+6
+.CE
+.PP
+An empty list is not necessarily an empty string:
+.PP
+.CS
+% set var { }; puts "[string length $var],[\fBllength\fR $var]"
+1,0
+.CE
+.SH "SEE ALSO"
+list(n), lappend(n), lindex(n), linsert(n), lsearch(n),
+lset(n), lsort(n), lrange(n), lreplace(n)
+.SH KEYWORDS
+element, list, length
diff --git a/doc/lmap.n b/doc/lmap.n
new file mode 100644
index 0000000..1a7858d
--- /dev/null
+++ b/doc/lmap.n
@@ -0,0 +1,85 @@
+'\"
+'\" Copyright (c) 2012 Trevor Davel
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH lmap n "" Tcl "Tcl Built-In Commands"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+lmap \- Iterate over all elements in one or more lists and collect results
+.SH SYNOPSIS
+\fBlmap \fIvarname list body\fR
+.br
+\fBlmap \fIvarlist1 list1\fR ?\fIvarlist2 list2 ...\fR? \fIbody\fR
+.BE
+.SH DESCRIPTION
+.PP
+The \fBlmap\fR command implements a loop where the loop variable(s) take on
+values from one or more lists, and the loop returns a list of results
+collected from each iteration.
+.PP
+In the simplest case there is one loop variable, \fIvarname\fR, and one list,
+\fIlist\fR, that is a list of values to assign to \fIvarname\fR. The
+\fIbody\fR argument is a Tcl script. For each element of \fIlist\fR (in order
+from first to last), \fBlmap\fR assigns the contents of the element to
+\fIvarname\fR as if the \fBlindex\fR command had been used to extract the
+element, then calls the Tcl interpreter to execute \fIbody\fR. If execution of
+the body completes normally then the result of the body is appended to an
+accumulator list. \fBlmap\fR returns the accumulator list.
+.PP
+In the general case there can be more than one value list (e.g., \fIlist1\fR
+and \fIlist2\fR), and each value list can be associated with a list of loop
+variables (e.g., \fIvarlist1\fR and \fIvarlist2\fR). During each iteration of
+the loop the variables of each \fIvarlist\fR are assigned consecutive values
+from the corresponding \fIlist\fR. Values in each \fIlist\fR are used in order
+from first to last, and each value is used exactly once. The total number of
+loop iterations is large enough to use up all the values from all the value
+lists. If a value list does not contain enough elements for each of its loop
+variables in each iteration, empty values are used for the missing elements.
+.PP
+The \fBbreak\fR and \fBcontinue\fR statements may be invoked inside
+\fIbody\fR, with the same effect as in the \fBfor\fR and \fBforeach\fR
+commands. In these cases the body does not complete normally and the result is
+not appended to the accumulator list.
+.SH EXAMPLES
+.PP
+Zip lists together:
+.PP
+.CS
+set list1 {a b c d}
+set list2 {1 2 3 4}
+set zipped [\fBlmap\fR a $list1 b $list2 {list $a $b}]
+# The value of zipped is "{a 1} {b 2} {c 3} {d 4}"
+.CE
+.PP
+Filter a list to remove odd values:
+.PP
+.CS
+set values {1 2 3 4 5 6 7 8}
+proc isEven {n} {expr {($n % 2) == 0}}
+set goodOnes [\fBlmap\fR x $values {expr {
+    [isEven $x] ? $x : [continue]
+}}]
+# The value of goodOnes is "2 4 6 8"
+.CE
+.PP
+Take a prefix from a list based on the contents of the list:
+.PP
+.CS
+set values {8 7 6 5 4 3 2 1}
+proc isGood {counter} {expr {$n > 3}}
+set prefix [\fBlmap\fR x $values {expr {
+    [isGood $x] ? $x : [break]
+}}]
+# The value of prefix is "8 7 6 5 4"
+.CE
+.SH "SEE ALSO"
+break(n), continue(n), for(n), foreach(n), while(n)
+.SH KEYWORDS
+foreach, iteration, list, loop, map
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/doc/load.n b/doc/load.n
new file mode 100644
index 0000000..2ab8f2e
--- /dev/null
+++ b/doc/load.n
@@ -0,0 +1,196 @@
+'\"
+'\" Copyright (c) 1995-1996 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\" 
+.TH load n 7.5 Tcl "Tcl Built-In Commands"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+load \- Load machine code and initialize new commands
+.SH SYNOPSIS
+\fBload\fR ?\fB\-global\fR? ?\fB\-lazy\fR? ?\fB\-\-\fR? \fIfileName\fR
+.br
+\fBload\fR ?\fB\-global\fR? ?\fB\-lazy\fR? ?\fB\-\-\fR? \fIfileName packageName\fR
+.br
+\fBload\fR ?\fB\-global\fR? ?\fB\-lazy\fR? ?\fB\-\-\fR? \fIfileName packageName interp\fR
+.BE
+.SH DESCRIPTION
+.PP
+This command loads binary code from a file into the
+application's address space and calls an initialization procedure
+in the package to incorporate it into an interpreter.  \fIfileName\fR
+is the name of the file containing the code;  its exact form varies
+from system to system but on most systems it is a shared library,
+such as a \fB.so\fR file under Solaris or a DLL under Windows.
+\fIpackageName\fR is the name of the package, and is used to
+compute the name of an initialization procedure.
+\fIinterp\fR is the path name of the interpreter into which to load
+the package (see the \fBinterp\fR manual entry for details);
+if \fIinterp\fR is omitted, it defaults to the
+interpreter in which the \fBload\fR command was invoked.
+.PP
+Once the file has been loaded into the application's address space,
+one of two initialization procedures will be invoked in the new code.
+Typically the initialization procedure will add new commands to a
+Tcl interpreter.
+The name of the initialization procedure is determined by
+\fIpackageName\fR and whether or not the target interpreter
+is a safe one.  For normal interpreters the name of the initialization
+procedure will have the form \fIpkg\fB_Init\fR, where \fIpkg\fR
+is the same as \fIpackageName\fR except that the first letter is
+converted to upper case and all other letters
+are converted to lower case.  For example, if \fIpackageName\fR is
+\fBfoo\fR or \fBFOo\fR, the initialization procedure's name will
+be \fBFoo_Init\fR.
+.PP
+If the target interpreter is a safe interpreter, then the name
+of the initialization procedure will be \fIpkg\fB_SafeInit\fR
+instead of \fIpkg\fB_Init\fR.
+The \fIpkg\fB_SafeInit\fR function should be written carefully, so that it
+initializes the safe interpreter only with partial functionality provided
+by the package that is safe for use by untrusted code. For more information
+on Safe\-Tcl, see the \fBsafe\fR manual entry.
+.PP
+The initialization procedure must match the following prototype:
+.PP
+.CS
+typedef int \fBTcl_PackageInitProc\fR(
+        Tcl_Interp *\fIinterp\fR);
+.CE
+.PP
+The \fIinterp\fR argument identifies the interpreter in which the
+package is to be loaded.  The initialization procedure must return
+\fBTCL_OK\fR or \fBTCL_ERROR\fR to indicate whether or not it completed
+successfully;  in the event of an error it should set the interpreter's result
+to point to an error message.  The result of the \fBload\fR command
+will be the result returned by the initialization procedure.
+.PP
+The actual loading of a file will only be done once for each \fIfileName\fR
+in an application.  If a given \fIfileName\fR is loaded into multiple
+interpreters, then the first \fBload\fR will load the code and
+call the initialization procedure;  subsequent \fBload\fRs will
+call the initialization procedure without loading the code again.
+For Tcl versions lower than 8.5, it is not possible to unload or reload a
+package. From version 8.5 however, the \fBunload\fR command allows the unloading
+of libraries loaded with \fBload\fR, for libraries that are aware of the
+Tcl's unloading mechanism.
+.PP
+The \fBload\fR command also supports packages that are statically
+linked with the application, if those packages have been registered
+by calling the \fBTcl_StaticPackage\fR procedure.
+If \fIfileName\fR is an empty string, then \fIpackageName\fR must
+be specified.
+.PP
+If \fIpackageName\fR is omitted or specified as an empty string,
+Tcl tries to guess the name of the package.
+This may be done differently on different platforms.
+The default guess, which is used on most UNIX platforms, is to
+take the last element of \fIfileName\fR, strip off the first
+three characters if they are \fBlib\fR, and use any following
+alphabetic and underline characters as the module name.
+For example, the command \fBload libxyz4.2.so\fR uses the module
+name \fBxyz\fR and the command \fBload bin/last.so {}\fR uses the
+module name \fBlast\fR.
+.PP
+If \fIfileName\fR is an empty string, then \fIpackageName\fR must
+be specified.
+The \fBload\fR command first searches for a statically loaded package
+(one that has been registered by calling the \fBTcl_StaticPackage\fR
+procedure) by that name; if one is found, it is used.
+Otherwise, the \fBload\fR command searches for a dynamically loaded
+package by that name, and uses it if it is found.  If several
+different files have been \fBload\fRed with different versions of
+the package, Tcl picks the file that was loaded first.
+.PP
+If \fB\-global\fR is specified preceding the filename, all symbols
+found in the shared library are exported for global use by other
+libraries. The option \fB\-lazy\fR delays the actual loading of
+symbols until their first actual use. The options may be abbreviated.
+The option \fB\-\-\fR indicates the end of the options, and should
+be used if you wish to use a filename which starts with \fB\-\fR
+and you provide a packageName to the \fBload\fR command.
+.PP
+On platforms which do not support the \fB\-global\fR or \fB\-lazy\fR
+options, the options still exist but have no effect. Note that use
+of the \fB\-global\fR or \fB\-lazy\fR option may lead to crashes
+in your application later (in case of symbol conflicts resp. missing
+symbols), which cannot be detected during the \fBload\fR. So, only
+use this when you know what you are doing, you will not get a nice
+error message when something is wrong with the loaded library.
+.SH "PORTABILITY ISSUES"
+.TP
+\fBWindows\fR\0\0\0\0\0
+.
+When a load fails with
+.QW "library not found"
+error, it is also possible
+that a dependent library was not found.  To see the dependent libraries,
+type
+.QW "dumpbin -imports <dllname>"
+in a DOS console to see what the library must import.
+When loading a DLL in the current directory, Windows will ignore
+.QW ./
+as a path specifier and use a search heuristic to find the DLL instead.
+To avoid this, load the DLL with:
+.RS
+.PP
+.CS
+\fBload\fR [file join [pwd] mylib.DLL]
+.CE
+.RE
+.SH BUGS
+.PP
+If the same file is \fBload\fRed by different \fIfileName\fRs, it will
+be loaded into the process's address space multiple times.  The
+behavior of this varies from system to system (some systems may
+detect the redundant loads, others may not).
+.SH EXAMPLE
+.PP
+The following is a minimal extension:
+.PP
+.CS
+#include <tcl.h>
+#include <stdio.h>
+static int fooCmd(ClientData clientData,
+        Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) {
+    printf("called with %d arguments\en", objc);
+    return TCL_OK;
+}
+int Foo_Init(Tcl_Interp *interp) {
+    if (Tcl_InitStubs(interp, "8.1", 0) == NULL) {
+	return TCL_ERROR;
+    }
+    printf("creating foo command");
+    Tcl_CreateObjCommand(interp, "foo", fooCmd, NULL, NULL);
+    return TCL_OK;
+}
+.CE
+.PP
+When built into a shared/dynamic library with a suitable name
+(e.g. \fBfoo.dll\fR on Windows, \fBlibfoo.so\fR on Solaris and Linux)
+it can then be loaded into Tcl with the following:
+.PP
+.CS
+# Load the extension
+switch $tcl_platform(platform) {
+    windows {
+        \fBload\fR [file join [pwd] foo.dll]
+    }
+    unix {
+        \fBload\fR [file join [pwd] libfoo[info sharedlibextension]]
+    }
+}
+
+# Now execute the command defined by the extension
+foo
+.CE
+.SH "SEE ALSO"
+info sharedlibextension, package(n), Tcl_StaticPackage(3), safe(n)
+.SH KEYWORDS
+binary code, dynamic library, load, safe interpreter, shared library
+'\"Local Variables:
+'\"mode: nroff
+'\"End:
diff --git a/doc/lrange.n b/doc/lrange.n
new file mode 100644
index 0000000..ffa6dba
--- /dev/null
+++ b/doc/lrange.n
@@ -0,0 +1,78 @@
+'\"
+'\" Copyright (c) 1993 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\" Copyright (c) 2001 Kevin B. Kenny <kennykb@acm.org>.  All rights reserved.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH lrange n 7.4 Tcl "Tcl Built-In Commands"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+lrange \- Return one or more adjacent elements from a list
+.SH SYNOPSIS
+\fBlrange \fIlist first last\fR
+.BE
+.SH DESCRIPTION
+.PP
+\fIList\fR must be a valid Tcl list.  This command will
+return a new list consisting of elements
+\fIfirst\fR through \fIlast\fR, inclusive.
+The index values \fIfirst\fR and \fIlast\fR are interpreted
+the same as index values for the command \fBstring index\fR,
+supporting simple index arithmetic and indices relative to the
+end of the list.
+If \fIfirst\fR is less than zero, it is treated as if it were zero.
+If \fIlast\fR is greater than or equal to the number of elements
+in the list, then it is treated as if it were \fBend\fR.
+If \fIfirst\fR is greater than \fIlast\fR then an empty string
+is returned.
+Note:
+.QW "\fBlrange \fIlist first first\fR"
+does not always produce the same result as
+.QW "\fBlindex \fIlist first\fR"
+(although it often does for simple fields that are not enclosed in
+braces); it does, however, produce exactly the same results as
+.QW "\fBlist [lindex \fIlist first\fB]\fR"
+.SH EXAMPLES
+.PP
+Selecting the first two elements:
+.PP
+.CS
+% \fBlrange\fR {a b c d e} 0 1
+a b
+.CE
+.PP
+Selecting the last three elements:
+.PP
+.CS
+% \fBlrange\fR {a b c d e} end-2 end
+c d e
+.CE
+.PP
+Selecting everything except the first and last element:
+.PP
+.CS
+% \fBlrange\fR {a b c d e} 1 end-1
+b c d
+.CE
+.PP
+Selecting a single element with \fBlrange\fR is not the same as doing
+so with \fBlindex\fR:
+.PP
+.CS
+% set var {some {elements to} select}
+some {elements to} select
+% lindex $var 1
+elements to
+% \fBlrange\fR $var 1 1
+{elements to}
+.CE
+.SH "SEE ALSO"
+list(n), lappend(n), lindex(n), linsert(n), llength(n), lsearch(n),
+lset(n), lreplace(n), lsort(n),
+string(n)
+.SH KEYWORDS
+element, list, range, sublist
diff --git a/doc/lrepeat.n b/doc/lrepeat.n
new file mode 100644
index 0000000..466339d
--- /dev/null
+++ b/doc/lrepeat.n
@@ -0,0 +1,38 @@
+'\"
+'\" Copyright (c) 2003 by Simon Geard.  All rights reserved.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\" 
+.TH lrepeat n 8.5 Tcl "Tcl Built-In Commands"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+lrepeat \- Build a list by repeating elements
+.SH SYNOPSIS
+\fBlrepeat \fIcount \fR?\fIelement ...\fR?
+.BE
+.SH DESCRIPTION
+.PP
+The \fBlrepeat\fR command creates a list of size \fIcount * number of
+elements\fR by repeating \fIcount\fR times the sequence of elements
+\fIelement ...\fR.  \fIcount\fR must be a non-negative integer,
+\fIelement\fR can be any Tcl value.  Note that \fBlrepeat 1 element ...\fR
+is identical to \fBlist element ...\fR.
+.SH EXAMPLES
+.CS
+\fBlrepeat\fR 3 a
+      \fI\(-> a a a\fR
+\fBlrepeat\fR 3 [\fBlrepeat\fR 3 0]
+      \fI\(-> {0 0 0} {0 0 0} {0 0 0}\fR
+\fBlrepeat\fR 3 a b c
+      \fI\(-> a b c a b c a b c\fR
+\fBlrepeat\fR 3 [\fBlrepeat\fR 2 a] b c
+      \fI\(-> {a a} b c {a a} b c {a a} b c\fR
+.CE
+.SH "SEE ALSO"
+list(n), lappend(n), linsert(n), llength(n), lset(n)
+
+.SH KEYWORDS
+element, index, list
diff --git a/doc/lreplace.n b/doc/lreplace.n
new file mode 100644
index 0000000..d19f0cd
--- /dev/null
+++ b/doc/lreplace.n
@@ -0,0 +1,86 @@
+'\"
+'\" Copyright (c) 1993 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\" Copyright (c) 2001 Kevin B. Kenny <kennykb@acm.org>.  All rights reserved.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH lreplace n 7.4 Tcl "Tcl Built-In Commands"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+lreplace \- Replace elements in a list with new elements
+.SH SYNOPSIS
+\fBlreplace \fIlist first last \fR?\fIelement element ...\fR?
+.BE
+.SH DESCRIPTION
+.PP
+\fBlreplace\fR returns a new list formed by replacing one or more elements of
+\fIlist\fR with the \fIelement\fR arguments.
+\fIfirst\fR and \fIlast\fR are index values specifying the first and
+last elements of the range to replace.
+The index values \fIfirst\fR and \fIlast\fR are interpreted
+the same as index values for the command \fBstring index\fR,
+supporting simple index arithmetic and indices relative to the
+end of the list.
+0 refers to the first element of the
+list, and \fBend\fR refers to the last element of the list.
+If \fIlist\fR is empty, then \fIfirst\fR and \fIlast\fR are ignored.
+.PP
+If \fIfirst\fR is less than zero, it is considered to refer to before the
+first element of the list.  For non-empty lists, the element indicated
+by \fIfirst\fR must exist or \fIfirst\fR must indicate before the
+start of the list.
+.PP
+If \fIlast\fR is less than \fIfirst\fR, then any specified elements
+will be inserted into the list before the point specified by \fIfirst\fR
+with no elements being deleted.
+.PP
+The \fIelement\fR arguments specify zero or more new arguments to
+be added to the list in place of those that were deleted.
+Each \fIelement\fR argument will become a separate element of
+the list.  If no \fIelement\fR arguments are specified, then the elements
+between \fIfirst\fR and \fIlast\fR are simply deleted.  If \fIlist\fR
+is empty, any \fIelement\fR arguments are added to the end of the list.
+.SH EXAMPLES
+.PP
+Replacing an element of a list with another:
+.PP
+.CS
+% \fBlreplace\fR {a b c d e} 1 1 foo
+a foo c d e
+.CE
+.PP
+Replacing two elements of a list with three:
+.PP
+.CS
+% \fBlreplace\fR {a b c d e} 1 2 three more elements
+a three more elements d e
+.CE
+.PP
+Deleting the last element from a list in a variable:
+.PP
+.CS
+% set var {a b c d e}
+a b c d e
+% set var [\fBlreplace\fR $var end end]
+a b c d
+.CE
+.PP
+A procedure to delete a given element from a list:
+.PP
+.CS
+proc lremove {listVariable value} {
+    upvar 1 $listVariable var
+    set idx [lsearch -exact $var $value]
+    set var [\fBlreplace\fR $var $idx $idx]
+}
+.CE
+.SH "SEE ALSO"
+list(n), lappend(n), lindex(n), linsert(n), llength(n), lsearch(n),
+lset(n), lrange(n), lsort(n),
+string(n)
+.SH KEYWORDS
+element, list, replace
diff --git a/doc/lreverse.n b/doc/lreverse.n
new file mode 100644
index 0000000..51a9e57
--- /dev/null
+++ b/doc/lreverse.n
@@ -0,0 +1,34 @@
+'\"
+'\" Copyright (c) 2006 by Donal K. Fellows.  All rights reserved.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\" 
+.TH lreverse n 8.5 Tcl "Tcl Built-In Commands"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+lreverse \- Reverse the order of a list
+.SH SYNOPSIS
+\fBlreverse \fIlist\fR
+.BE
+.SH DESCRIPTION
+.PP
+The \fBlreverse\fR command returns a list that has the same elements as its
+input list, \fIlist\fR, except with the elements in the reverse order.
+.SH EXAMPLES
+.CS
+\fBlreverse\fR {a a b c}
+      \fI\(-> c b a a\fR
+\fBlreverse\fR {a b {c d} e f}
+      \fI\(-> f e {c d} b a\fR
+.CE
+.SH "SEE ALSO"
+list(n), lsearch(n), lsort(n)
+
+.SH KEYWORDS
+element, list, reverse
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/doc/lsearch.n b/doc/lsearch.n
new file mode 100644
index 0000000..c2644b8
--- /dev/null
+++ b/doc/lsearch.n
@@ -0,0 +1,220 @@
+'\"
+'\" Copyright (c) 1993 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\" Copyright (c) 2001 Kevin B. Kenny <kennykb@acm.org>.  All rights reserved.
+'\" Copyright (c) 2003-2004 Donal K. Fellows.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH lsearch n 8.6 Tcl "Tcl Built-In Commands"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+lsearch \- See if a list contains a particular element
+.SH SYNOPSIS
+\fBlsearch \fR?\fIoptions\fR? \fIlist pattern\fR
+.BE
+.SH DESCRIPTION
+.PP
+This command searches the elements of \fIlist\fR to see if one
+of them matches \fIpattern\fR.  If so, the command returns the index
+of the first matching element
+(unless the options \fB\-all\fR or \fB\-inline\fR are specified.)
+If not, the command returns \fB\-1\fR.  The \fIoption\fR arguments
+indicates how the elements of the list are to be matched against
+\fIpattern\fR and must have one of the values below:
+.SS "MATCHING STYLE OPTIONS"
+.PP
+If all matching style options are omitted, the default matching style
+is \fB\-glob\fR.  If more than one matching style is specified, the
+last matching style given takes precedence.
+.TP
+\fB\-exact\fR
+.
+\fIPattern\fR is a literal string that is compared for exact equality
+against each list element.
+.TP
+\fB\-glob\fR
+.
+\fIPattern\fR is a glob-style pattern which is matched against each list
+element using the same rules as the \fBstring match\fR command.
+.TP
+\fB\-regexp\fR
+.
+\fIPattern\fR is treated as a regular expression and matched against
+each list element using the rules described in the \fBre_syntax\fR
+reference page.
+.TP
+\fB\-sorted\fR
+.
+The list elements are in sorted order.  If this option is specified,
+\fBlsearch\fR will use a more efficient searching algorithm to search
+\fIlist\fR.  If no other options are specified, \fIlist\fR is assumed
+to be sorted in increasing order, and to contain ASCII strings.  This
+option is mutually exclusive with \fB\-glob\fR and \fB\-regexp\fR, and
+is treated exactly like \fB\-exact\fR when either \fB\-all\fR or
+\fB\-not\fR are specified.
+.SS "GENERAL MODIFIER OPTIONS"
+.PP
+These options may be given with all matching styles.
+.TP
+\fB\-all\fR
+.
+Changes the result to be the list of all matching indices (or all matching
+values if \fB\-inline\fR is specified as well.) If indices are returned, the
+indices will be in numeric order. If values are returned, the order of the
+values will be the order of those values within the input \fIlist\fR.
+.TP
+\fB\-inline\fR
+.
+The matching value is returned instead of its index (or an empty
+string if no value matches.)  If \fB\-all\fR is also specified, then
+the result of the command is the list of all values that matched.
+.TP
+\fB\-not\fR
+.
+This negates the sense of the match, returning the index of the first
+non-matching value in the list.
+.TP
+\fB\-start\fR\0\fIindex\fR
+.
+The list is searched starting at position \fIindex\fR.
+The interpretation of the \fIindex\fR value is the same as
+for the command \fBstring index\fR, supporting simple index
+arithmetic and indices relative to the end of the list.
+.SS "CONTENTS DESCRIPTION OPTIONS"
+.PP
+These options describe how to interpret the items in the list being
+searched.  They are only meaningful when used with the \fB\-exact\fR
+and \fB\-sorted\fR options.  If more than one is specified, the last
+one takes precedence.  The default is \fB\-ascii\fR.
+.TP
+\fB\-ascii\fR
+.
+The list elements are to be examined as Unicode strings (the name is
+for backward-compatibility reasons.)
+.TP
+\fB\-dictionary\fR
+.
+The list elements are to be compared using dictionary-style
+comparisons (see \fBlsort\fR for a fuller description). Note that this
+only makes a meaningful difference from the \fB\-ascii\fR option when
+the \fB\-sorted\fR option is given, because values are only
+dictionary-equal when exactly equal.
+.TP
+\fB\-integer\fR
+.
+The list elements are to be compared as integers.
+.TP
+\fB\-nocase\fR
+.
+Causes comparisons to be handled in a case-insensitive manner.  Has no
+effect if combined with the \fB\-dictionary\fR, \fB\-integer\fR, or
+\fB\-real\fR options.
+.TP
+\fB\-real\fR
+.
+The list elements are to be compared as floating-point values.
+.SS "SORTED LIST OPTIONS"
+.PP
+These options (only meaningful with the \fB\-sorted\fR option) specify
+how the list is sorted.  If more than one is given, the last one takes
+precedence.  The default option is \fB\-increasing\fR.
+.TP
+\fB\-decreasing\fR
+.
+The list elements are sorted in decreasing order.  This option is only
+meaningful when used with \fB\-sorted\fR.
+.TP
+\fB\-increasing\fR
+.
+The list elements are sorted in increasing order.  This option is only
+meaningful when used with \fB\-sorted\fR.
+.TP
+\fB\-bisect\fR
+.VS 8.6
+Inexact search when the list elements are in sorted order. For an increasing
+list the last index where the element is less than or equal to the pattern
+is returned. For a decreasing list the last index where the element is greater
+than or equal to the pattern is returned. If the pattern is before the first
+element or the list is empty, -1 is returned.
+This option implies \fB\-sorted\fR and cannot be used with either \fB\-all\fR
+or \fB\-not\fR.
+.VE 8.6
+.SS "NESTED LIST OPTIONS"
+.PP
+These options are used to search lists of lists.  They may be used
+with any other options.
+.TP
+\fB\-index\fR\0\fIindexList\fR
+.
+This option is designed for use when searching within nested lists.
+The \fIindexList\fR argument gives a path of indices (much as might be
+used with the \fBlindex\fR or \fBlset\fR commands) within each element
+to allow the location of the term being matched against.
+.TP
+\fB\-subindices\fR
+.
+If this option is given, the index result from this command (or every
+index result when \fB\-all\fR is also specified) will be a complete
+path (suitable for use with \fBlindex\fR or \fBlset\fR) within the
+overall list to the term found.  This option has no effect unless the
+\fB\-index\fR is also specified, and is just a convenience short-cut.
+.SH EXAMPLES
+.PP
+Basic searching:
+.PP
+.CS
+\fBlsearch\fR {a b c d e} c
+      \fI\(-> 2\fR
+\fBlsearch\fR -all {a b c a b c} c
+      \fI\(-> 2 5\fR
+.CE
+.PP
+Using \fBlsearch\fR to filter lists:
+.PP
+.CS
+\fBlsearch\fR -inline {a20 b35 c47} b*
+      \fI\(-> b35\fR
+\fBlsearch\fR -inline -not {a20 b35 c47} b*
+      \fI\(-> a20\fR
+\fBlsearch\fR -all -inline -not {a20 b35 c47} b*
+      \fI\(-> a20 c47\fR
+\fBlsearch\fR -all -not {a20 b35 c47} b*
+      \fI\(-> 0 2\fR
+.CE
+.PP
+This can even do a
+.QW set-like
+removal operation:
+.PP
+.CS
+\fBlsearch\fR -all -inline -not -exact {a b c a d e a f g a} a
+      \fI\(-> b c d e f g\fR
+.CE
+.PP
+Searching may start part-way through the list:
+.PP
+.CS
+\fBlsearch\fR -start 3 {a b c a b c} c
+      \fI\(-> 5\fR
+.CE
+.PP
+It is also possible to search inside elements:
+.PP
+.CS
+\fBlsearch\fR -index 1 -all -inline {{a abc} {b bcd} {c cde}} *bc*
+      \fI\(-> {a abc} {b bcd}\fR
+.CE
+.SH "SEE ALSO"
+foreach(n), list(n), lappend(n), lindex(n), linsert(n), llength(n),
+lset(n), lsort(n), lrange(n), lreplace(n),
+string(n)
+.SH KEYWORDS
+binary search, linear search,
+list, match, pattern, regular expression, search, string
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/doc/lset.n b/doc/lset.n
new file mode 100644
index 0000000..e425274
--- /dev/null
+++ b/doc/lset.n
@@ -0,0 +1,146 @@
+'\"
+'\" Copyright (c) 2001 by Kevin B. Kenny <kennykb@acm.org>.  All rights reserved.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH lset n 8.4 Tcl "Tcl Built-In Commands"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+lset \- Change an element in a list
+.SH SYNOPSIS
+\fBlset \fIvarName ?index ...? newValue\fR
+.BE
+.SH DESCRIPTION
+.PP
+The \fBlset\fR command accepts a parameter, \fIvarName\fR, which
+it interprets as the name of a variable containing a Tcl list.
+It also accepts zero or more \fIindices\fR into
+the list.  The indices may be presented either consecutively on the
+command line, or grouped in a
+Tcl list and presented as a single argument.
+Finally, it accepts a new value for an element of \fIvarName\fR.
+.PP
+If no indices are presented, the command takes the form:
+.PP
+.CS
+\fBlset\fR varName newValue
+.CE
+.PP
+or
+.PP
+.CS
+\fBlset\fR varName {} newValue
+.CE
+.PP
+In this case, \fInewValue\fR replaces the old value of the variable
+\fIvarName\fR.
+.PP
+When presented with a single index, the \fBlset\fR command
+treats the content of the \fIvarName\fR variable as a Tcl list.
+It addresses the \fIindex\fR'th element in it
+(0 refers to the first element of the list).
+When interpreting the list, \fBlset\fR observes the same rules
+concerning braces and quotes and backslashes as the Tcl command
+interpreter; however, variable
+substitution and command substitution do not occur.
+The command constructs a new list in which the designated element is
+replaced with \fInewValue\fR.  This new list is stored in the
+variable \fIvarName\fR, and is also the return value from the \fBlset\fR
+command.
+.PP
+If \fIindex\fR is negative or greater than the number
+of elements in \fI$varName\fR, then an error occurs.
+.PP
+If \fIindex\fR is equal to the number of elements in \fI$varName\fR,
+then the given element is appended to the list.
+.PP
+The interpretation of each simple \fIindex\fR value is the same as
+for the command \fBstring index\fR, supporting simple index
+arithmetic and indices relative to the end of the list.
+.PP
+If additional \fIindex\fR arguments are supplied, then each argument is
+used in turn to address an element within a sublist designated
+by the previous indexing operation,
+allowing the script to alter elements in sublists (or append elements
+to sublists).  The command,
+.PP
+.CS
+\fBlset\fR a 1 2 newValue
+.CE
+.PP
+or
+.PP
+.CS
+\fBlset\fR a {1 2} newValue
+.CE
+.PP
+replaces element 2 of sublist 1 with \fInewValue\fR.
+.PP
+The integer appearing in each \fIindex\fR argument must be greater
+than or equal to zero.  The integer appearing in each \fIindex\fR
+argument must be less than or equal to the length of the corresponding
+list.  In other words, the \fBlset\fR command can change the size
+of a list only by appending an element (setting the one after the current
+end).  If an index is outside the permitted range, an error is reported.
+.SH EXAMPLES
+.PP
+In each of these examples, the initial value of \fIx\fR is:
+.PP
+.CS
+set x [list [list a b c] [list d e f] [list g h i]]
+      \fI\(-> {a b c} {d e f} {g h i}\fR
+.CE
+.PP
+The indicated return value also becomes the new value of \fIx\fR
+(except in the last case, which is an error which leaves the value of
+\fIx\fR unchanged.)
+.PP
+.CS
+\fBlset\fR x {j k l}
+      \fI\(-> j k l\fR
+\fBlset\fR x {} {j k l}
+      \fI\(-> j k l\fR
+\fBlset\fR x 0 j
+      \fI\(-> j {d e f} {g h i}\fR
+\fBlset\fR x 2 j
+      \fI\(-> {a b c} {d e f} j\fR
+\fBlset\fR x end j
+      \fI\(-> {a b c} {d e f} j\fR
+\fBlset\fR x end-1 j
+      \fI\(-> {a b c} j {g h i}\fR
+\fBlset\fR x 2 1 j
+      \fI\(-> {a b c} {d e f} {g j i}\fR
+\fBlset\fR x {2 1} j
+      \fI\(-> {a b c} {d e f} {g j i}\fR
+\fBlset\fR x {2 3} j
+      \fI\(-> list index out of range\fR
+.CE
+.PP
+In the following examples, the initial value of \fIx\fR is:
+.PP
+.CS
+set x [list [list [list a b] [list c d]] \e
+            [list [list e f] [list g h]]]
+      \fI\(-> {{a b} {c d}} {{e f} {g h}}\fR
+.CE
+.PP
+The indicated return value also becomes the new value of \fIx\fR.
+.PP
+.CS
+\fBlset\fR x 1 1 0 j
+      \fI\(-> {{a b} {c d}} {{e f} {j h}}\fR
+\fBlset\fR x {1 1 0} j
+      \fI\(-> {{a b} {c d}} {{e f} {j h}}\fR
+.CE
+.SH "SEE ALSO"
+list(n), lappend(n), lindex(n), linsert(n), llength(n), lsearch(n),
+lsort(n), lrange(n), lreplace(n),
+string(n)
+.SH KEYWORDS
+element, index, list, replace, set
+'\"Local Variables:
+'\"mode: nroff
+'\"End:
diff --git a/doc/lsort.n b/doc/lsort.n
new file mode 100644
index 0000000..b0f7973
--- /dev/null
+++ b/doc/lsort.n
@@ -0,0 +1,274 @@
+'\"
+'\" Copyright (c) 1993 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\" Copyright (c) 1999 Scriptics Corporation
+'\" Copyright (c) 2001 Kevin B. Kenny <kennykb@acm.org>.  All rights reserved.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH lsort n 8.5 Tcl "Tcl Built-In Commands"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+lsort \- Sort the elements of a list
+.SH SYNOPSIS
+\fBlsort \fR?\fIoptions\fR? \fIlist\fR
+.BE
+.SH DESCRIPTION
+.PP
+This command sorts the elements of \fIlist\fR, returning a new
+list in sorted order.  The implementation of the \fBlsort\fR command
+uses the merge\-sort algorithm which is a stable sort that has O(n log
+n) performance characteristics.
+.PP
+By default ASCII sorting is used with the result returned in
+increasing order.  However, any of the following options may be
+specified before \fIlist\fR to control the sorting process (unique
+abbreviations are accepted):
+.TP
+\fB\-ascii\fR
+.
+Use string comparison with Unicode code-point collation order (the
+name is for backward-compatibility reasons.)  This is the default.
+.TP
+\fB\-dictionary\fR
+.
+Use dictionary-style comparison.  This is the same as \fB\-ascii\fR
+except (a) case is ignored except as a tie-breaker and (b) if two
+strings contain embedded numbers, the numbers compare as integers,
+not characters.  For example, in \fB\-dictionary\fR mode, \fBbigBoy\fR
+sorts between \fBbigbang\fR and \fBbigboy\fR, and \fBx10y\fR
+sorts between \fBx9y\fR and \fBx11y\fR.
+.TP
+\fB\-integer\fR
+.
+Convert list elements to integers and use integer comparison.
+.TP
+\fB\-real\fR
+.
+Convert list elements to floating-point values and use floating comparison.
+.TP
+\fB\-command\0\fIcommand\fR
+.
+Use \fIcommand\fR as a comparison command.
+To compare two elements, evaluate a Tcl script consisting of
+\fIcommand\fR with the two elements appended as additional
+arguments.  The script should return an integer less than,
+equal to, or greater than zero if the first element is to
+be considered less than, equal to, or greater than the second,
+respectively.
+.TP
+\fB\-increasing\fR
+.
+Sort the list in increasing order
+.PQ smallest "items first" .
+This is the default.
+.TP
+\fB\-decreasing\fR
+.
+Sort the list in decreasing order
+.PQ largest "items first" .
+.TP
+\fB\-indices\fR
+.
+Return a list of indices into \fIlist\fR in sorted order instead of
+the values themselves.
+.TP
+\fB\-index\0\fIindexList\fR
+.
+If this option is specified, each of the elements of \fIlist\fR must
+itself be a proper Tcl sublist (unless \fB\-stride\fR is used).
+Instead of sorting based on whole sublists, \fBlsort\fR will extract
+the \fIindexList\fR'th element from each sublist (as if the overall
+element and the \fIindexList\fR were passed to \fBlindex\fR) and sort
+based on the given element.
+For example,
+.RS
+.PP
+.CS
+\fBlsort\fR -integer -index 1 \e
+      {{First 24} {Second 18} {Third 30}}
+.CE
+.PP
+returns \fB{Second 18} {First 24} {Third 30}\fR,
+.PP
+'\"
+'\" This example is from the test suite!
+'\"
+.CS
+\fBlsort\fR -index end-1 \e
+        {{a 1 e i} {b 2 3 f g} {c 4 5 6 d h}}
+.CE
+.PP
+returns \fB{c 4 5 6 d h} {a 1 e i} {b 2 3 f g}\fR,
+and
+.PP
+.CS
+\fBlsort\fR -index {0 1} {
+    {{b i g} 12345}
+    {{d e m o} 34512}
+    {{c o d e} 54321}
+}
+.CE
+.PP
+returns \fB{{d e m o} 34512} {{b i g} 12345} {{c o d e} 54321}\fR
+(because \fBe\fR sorts before \fBi\fR which sorts before \fBo\fR.)
+This option is much more efficient than using \fB\-command\fR
+to achieve the same effect.
+.RE
+.TP
+\fB\-stride\0\fIstrideLength\fR
+.
+If this option is specified, the list is treated as consisting of
+groups of \fIstrideLength\fR elements and the groups are sorted by
+either their first element or, if the \fB\-index\fR option is used,
+by the element within each group given by the first index passed to
+\fB\-index\fR (which is then ignored by \fB\-index\fR). Elements
+always remain in the same position within their group.
+.RS
+.PP
+The list length must be an integer multiple of \fIstrideLength\fR, which
+in turn must be at least 2.
+.PP
+For example,
+.PP
+.CS
+\fBlsort\fR \-stride 2 {carrot 10 apple 50 banana 25}
+.CE
+.PP
+returns
+.QW "apple 50 banana 25 carrot 10" ,
+and
+.PP
+.CS
+\fBlsort\fR \-stride 2 \-index 1 \-integer {carrot 10 apple 50 banana 25}
+.CE
+.PP
+returns
+.QW "carrot 10 banana 25 apple 50" .
+.RE
+.TP
+\fB\-nocase\fR
+.
+Causes comparisons to be handled in a case-insensitive manner.  Has no
+effect if combined with the \fB\-dictionary\fR, \fB\-integer\fR, or
+\fB\-real\fR options.
+.TP
+\fB\-unique\fR
+.
+If this option is specified, then only the last set of duplicate
+elements found in the list will be retained.  Note that duplicates are
+determined relative to the comparison used in the sort.  Thus if
+\fB\-index 0\fR is used, \fB{1 a}\fR and \fB{1 b}\fR would be
+considered duplicates and only the second element, \fB{1 b}\fR, would
+be retained.
+.SH "NOTES"
+.PP
+The options to \fBlsort\fR only control what sort of comparison is
+used, and do not necessarily constrain what the values themselves
+actually are.  This distinction is only noticeable when the list to be
+sorted has fewer than two elements.
+.PP
+The \fBlsort\fR command is reentrant, meaning it is safe to use as
+part of the implementation of a command used in the \fB\-command\fR
+option.
+.SH "EXAMPLES"
+.PP
+Sorting a list using ASCII sorting:
+.PP
+.CS
+\fI%\fR \fBlsort\fR {a10 B2 b1 a1 a2}
+B2 a1 a10 a2 b1
+.CE
+.PP
+Sorting a list using Dictionary sorting:
+.PP
+.CS
+\fI%\fR \fBlsort\fR -dictionary {a10 B2 b1 a1 a2}
+a1 a2 a10 b1 B2
+.CE
+.PP
+Sorting lists of integers:
+.PP
+.CS
+\fI%\fR \fBlsort\fR -integer {5 3 1 2 11 4}
+1 2 3 4 5 11
+\fI%\fR \fBlsort\fR -integer {1 2 0x5 7 0 4 -1}
+-1 0 1 2 4 0x5 7
+.CE
+.PP
+Sorting lists of floating-point numbers:
+.PP
+.CS
+\fI%\fR \fBlsort\fR -real {5 3 1 2 11 4}
+1 2 3 4 5 11
+\fI%\fR \fBlsort\fR -real {.5 0.07e1 0.4 6e-1}
+0.4 .5 6e-1 0.07e1
+.CE
+.PP
+Sorting using indices:
+.PP
+.CS
+\fI%\fR # Note the space character before the c
+\fI%\fR \fBlsort\fR {{a 5} { c 3} {b 4} {e 1} {d 2}}
+{ c 3} {a 5} {b 4} {d 2} {e 1}
+\fI%\fR \fBlsort\fR -index 0 {{a 5} { c 3} {b 4} {e 1} {d 2}}
+{a 5} {b 4} { c 3} {d 2} {e 1}
+\fI%\fR \fBlsort\fR -index 1 {{a 5} { c 3} {b 4} {e 1} {d 2}}
+{e 1} {d 2} { c 3} {b 4} {a 5}
+.CE
+.PP
+.VS 8.6
+Sorting a dictionary:
+.PP
+.CS
+\fI%\fR set d [dict create c d a b h i f g c e]
+c e a b h i f g
+\fI%\fR \fBlsort\fR -stride 2 $d
+a b c e f g h i
+.CE
+.PP
+Sorting using striding and multiple indices:
+.PP
+.CS
+\fI%\fR # Note the first index value is relative to the group
+\fI%\fR \fBlsort\fR \-stride 3 \-index {0 1} \e
+     {{Bob Smith} 25 Audi {Jane Doe} 40 Ford}
+{{Jane Doe} 40 Ford {Bob Smith} 25 Audi}
+.CE
+.VE 8.6
+.PP
+Stripping duplicate values using sorting:
+.PP
+.CS
+\fI%\fR \fBlsort\fR -unique {a b c a b c a b c}
+a b c
+.CE
+.PP
+More complex sorting using a comparison function:
+.PP
+.CS
+\fI%\fR proc compare {a b} {
+    set a0 [lindex $a 0]
+    set b0 [lindex $b 0]
+    if {$a0 < $b0} {
+        return -1
+    } elseif {$a0 > $b0} {
+        return 1
+    }
+    return [string compare [lindex $a 1] [lindex $b 1]]
+}
+\fI%\fR \fBlsort\fR -command compare \e
+        {{3 apple} {0x2 carrot} {1 dingo} {2 banana}}
+{1 dingo} {2 banana} {0x2 carrot} {3 apple}
+.CE
+.SH "SEE ALSO"
+list(n), lappend(n), lindex(n), linsert(n), llength(n), lsearch(n),
+lset(n), lrange(n), lreplace(n)
+.SH KEYWORDS
+element, list, order, sort
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/doc/man.macros b/doc/man.macros
new file mode 100644
index 0000000..ddd073d
--- /dev/null
+++ b/doc/man.macros
@@ -0,0 +1,267 @@
+.\" The -*- nroff -*- definitions below are for supplemental macros used
+.\" in Tcl/Tk manual entries.
+.\"
+.\" .AP type name in/out ?indent?
+.\"	Start paragraph describing an argument to a library procedure.
+.\"	type is type of argument (int, etc.), in/out is either "in", "out",
+.\"	or "in/out" to describe whether procedure reads or modifies arg,
+.\"	and indent is equivalent to second arg of .IP (shouldn't ever be
+.\"	needed;  use .AS below instead)
+.\"
+.\" .AS ?type? ?name?
+.\"	Give maximum sizes of arguments for setting tab stops.  Type and
+.\"	name are examples of largest possible arguments that will be passed
+.\"	to .AP later.  If args are omitted, default tab stops are used.
+.\"
+.\" .BS
+.\"	Start box enclosure.  From here until next .BE, everything will be
+.\"	enclosed in one large box.
+.\"
+.\" .BE
+.\"	End of box enclosure.
+.\"
+.\" .CS
+.\"	Begin code excerpt.
+.\"
+.\" .CE
+.\"	End code excerpt.
+.\"
+.\" .VS ?version? ?br?
+.\"	Begin vertical sidebar, for use in marking newly-changed parts
+.\"	of man pages.  The first argument is ignored and used for recording
+.\"	the version when the .VS was added, so that the sidebars can be
+.\"	found and removed when they reach a certain age.  If another argument
+.\"	is present, then a line break is forced before starting the sidebar.
+.\"
+.\" .VE
+.\"	End of vertical sidebar.
+.\"
+.\" .DS
+.\"	Begin an indented unfilled display.
+.\"
+.\" .DE
+.\"	End of indented unfilled display.
+.\"
+.\" .SO ?manpage?
+.\"	Start of list of standard options for a Tk widget. The manpage
+.\"	argument defines where to look up the standard options; if
+.\"	omitted, defaults to "options". The options follow on successive
+.\"	lines, in three columns separated by tabs.
+.\"
+.\" .SE
+.\"	End of list of standard options for a Tk widget.
+.\"
+.\" .OP cmdName dbName dbClass
+.\"	Start of description of a specific option.  cmdName gives the
+.\"	option's name as specified in the class command, dbName gives
+.\"	the option's name in the option database, and dbClass gives
+.\"	the option's class in the option database.
+.\"
+.\" .UL arg1 arg2
+.\"	Print arg1 underlined, then print arg2 normally.
+.\"
+.\" .QW arg1 ?arg2?
+.\"	Print arg1 in quotes, then arg2 normally (for trailing punctuation).
+.\"
+.\" .PQ arg1 ?arg2?
+.\"	Print an open parenthesis, arg1 in quotes, then arg2 normally
+.\"	(for trailing punctuation) and then a closing parenthesis.
+.\"
+.\"	# Set up traps and other miscellaneous stuff for Tcl/Tk man pages.
+.if t .wh -1.3i ^B
+.nr ^l \n(.l
+.ad b
+.\"	# Start an argument description
+.de AP
+.ie !"\\$4"" .TP \\$4
+.el \{\
+.   ie !"\\$2"" .TP \\n()Cu
+.   el          .TP 15
+.\}
+.ta \\n()Au \\n()Bu
+.ie !"\\$3"" \{\
+\&\\$1 \\fI\\$2\\fP (\\$3)
+.\".b
+.\}
+.el \{\
+.br
+.ie !"\\$2"" \{\
+\&\\$1	\\fI\\$2\\fP
+.\}
+.el \{\
+\&\\fI\\$1\\fP
+.\}
+.\}
+..
+.\"	# define tabbing values for .AP
+.de AS
+.nr )A 10n
+.if !"\\$1"" .nr )A \\w'\\$1'u+3n
+.nr )B \\n()Au+15n
+.\"
+.if !"\\$2"" .nr )B \\w'\\$2'u+\\n()Au+3n
+.nr )C \\n()Bu+\\w'(in/out)'u+2n
+..
+.AS Tcl_Interp Tcl_CreateInterp in/out
+.\"	# BS - start boxed text
+.\"	# ^y = starting y location
+.\"	# ^b = 1
+.de BS
+.br
+.mk ^y
+.nr ^b 1u
+.if n .nf
+.if n .ti 0
+.if n \l'\\n(.lu\(ul'
+.if n .fi
+..
+.\"	# BE - end boxed text (draw box now)
+.de BE
+.nf
+.ti 0
+.mk ^t
+.ie n \l'\\n(^lu\(ul'
+.el \{\
+.\"	Draw four-sided box normally, but don't draw top of
+.\"	box if the box started on an earlier page.
+.ie !\\n(^b-1 \{\
+\h'-1.5n'\L'|\\n(^yu-1v'\l'\\n(^lu+3n\(ul'\L'\\n(^tu+1v-\\n(^yu'\l'|0u-1.5n\(ul'
+.\}
+.el \}\
+\h'-1.5n'\L'|\\n(^yu-1v'\h'\\n(^lu+3n'\L'\\n(^tu+1v-\\n(^yu'\l'|0u-1.5n\(ul'
+.\}
+.\}
+.fi
+.br
+.nr ^b 0
+..
+.\"	# VS - start vertical sidebar
+.\"	# ^Y = starting y location
+.\"	# ^v = 1 (for troff;  for nroff this doesn't matter)
+.de VS
+.if !"\\$2"" .br
+.mk ^Y
+.ie n 'mc \s12\(br\s0
+.el .nr ^v 1u
+..
+.\"	# VE - end of vertical sidebar
+.de VE
+.ie n 'mc
+.el \{\
+.ev 2
+.nf
+.ti 0
+.mk ^t
+\h'|\\n(^lu+3n'\L'|\\n(^Yu-1v\(bv'\v'\\n(^tu+1v-\\n(^Yu'\h'-|\\n(^lu+3n'
+.sp -1
+.fi
+.ev
+.\}
+.nr ^v 0
+..
+.\"	# Special macro to handle page bottom:  finish off current
+.\"	# box/sidebar if in box/sidebar mode, then invoked standard
+.\"	# page bottom macro.
+.de ^B
+.ev 2
+'ti 0
+'nf
+.mk ^t
+.if \\n(^b \{\
+.\"	Draw three-sided box if this is the box's first page,
+.\"	draw two sides but no top otherwise.
+.ie !\\n(^b-1 \h'-1.5n'\L'|\\n(^yu-1v'\l'\\n(^lu+3n\(ul'\L'\\n(^tu+1v-\\n(^yu'\h'|0u'\c
+.el \h'-1.5n'\L'|\\n(^yu-1v'\h'\\n(^lu+3n'\L'\\n(^tu+1v-\\n(^yu'\h'|0u'\c
+.\}
+.if \\n(^v \{\
+.nr ^x \\n(^tu+1v-\\n(^Yu
+\kx\h'-\\nxu'\h'|\\n(^lu+3n'\ky\L'-\\n(^xu'\v'\\n(^xu'\h'|0u'\c
+.\}
+.bp
+'fi
+.ev
+.if \\n(^b \{\
+.mk ^y
+.nr ^b 2
+.\}
+.if \\n(^v \{\
+.mk ^Y
+.\}
+..
+.\"	# DS - begin display
+.de DS
+.RS
+.nf
+.sp
+..
+.\"	# DE - end display
+.de DE
+.fi
+.RE
+.sp
+..
+.\"	# SO - start of list of standard options
+.de SO
+'ie '\\$1'' .ds So \\fBoptions\\fR
+'el .ds So \\fB\\$1\\fR
+.SH "STANDARD OPTIONS"
+.LP
+.nf
+.ta 5.5c 11c
+.ft B
+..
+.\"	# SE - end of list of standard options
+.de SE
+.fi
+.ft R
+.LP
+See the \\*(So manual entry for details on the standard options.
+..
+.\"	# OP - start of full description for a single option
+.de OP
+.LP
+.nf
+.ta 4c
+Command-Line Name:	\\fB\\$1\\fR
+Database Name:	\\fB\\$2\\fR
+Database Class:	\\fB\\$3\\fR
+.fi
+.IP
+..
+.\"	# CS - begin code excerpt
+.de CS
+.RS
+.nf
+.ta .25i .5i .75i 1i
+..
+.\"	# CE - end code excerpt
+.de CE
+.fi
+.RE
+..
+.\"	# UL - underline word
+.de UL
+\\$1\l'|0\(ul'\\$2
+..
+.\"	# QW - apply quotation marks to word
+.de QW
+.ie '\\*(lq'"' ``\\$1''\\$2
+.\"" fix emacs highlighting
+.el \\*(lq\\$1\\*(rq\\$2
+..
+.\"	# PQ - apply parens and quotation marks to word
+.de PQ
+.ie '\\*(lq'"' (``\\$1''\\$2)\\$3
+.\"" fix emacs highlighting
+.el (\\*(lq\\$1\\*(rq\\$2)\\$3
+..
+.\"	# QR - quoted range
+.de QR
+.ie '\\*(lq'"' ``\\$1''\\-``\\$2''\\$3
+.\"" fix emacs highlighting
+.el \\*(lq\\$1\\*(rq\\-\\*(lq\\$2\\*(rq\\$3
+..
+.\"	# MT - "empty" string
+.de MT
+.QW ""
+..
diff --git a/doc/mathfunc.n b/doc/mathfunc.n
new file mode 100644
index 0000000..7233d46
--- /dev/null
+++ b/doc/mathfunc.n
@@ -0,0 +1,305 @@
+'\"
+'\" Copyright (c) 1993 The Regents of the University of California.
+'\" Copyright (c) 1994-2000 Sun Microsystems, Inc.
+'\" Copyright (c) 2005 by Kevin B. Kenny <kennykb@acm.org>. All rights reserved
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH mathfunc n 8.5 Tcl "Tcl Mathematical Functions"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+mathfunc \- Mathematical functions for Tcl expressions
+.SH SYNOPSIS
+package require \fBTcl 8.5\fR
+.sp
+\fB::tcl::mathfunc::abs\fR \fIarg\fR
+.br
+\fB::tcl::mathfunc::acos\fR \fIarg\fR
+.br
+\fB::tcl::mathfunc::asin\fR \fIarg\fR
+.br
+\fB::tcl::mathfunc::atan\fR \fIarg\fR
+.br
+\fB::tcl::mathfunc::atan2\fR \fIy\fR \fIx\fR
+.br
+\fB::tcl::mathfunc::bool\fR \fIarg\fR
+.br
+\fB::tcl::mathfunc::ceil\fR \fIarg\fR
+.br
+\fB::tcl::mathfunc::cos\fR \fIarg\fR
+.br
+\fB::tcl::mathfunc::cosh\fR \fIarg\fR
+.br
+\fB::tcl::mathfunc::double\fR \fIarg\fR
+.br
+\fB::tcl::mathfunc::entier\fR \fIarg\fR
+.br
+\fB::tcl::mathfunc::exp\fR \fIarg\fR
+.br
+\fB::tcl::mathfunc::floor\fR \fIarg\fR
+.br
+\fB::tcl::mathfunc::fmod\fR \fIx\fR \fIy\fR
+.br
+\fB::tcl::mathfunc::hypot\fR \fIx\fR \fIy\fR
+.br
+\fB::tcl::mathfunc::int\fR \fIarg\fR
+.br
+\fB::tcl::mathfunc::isqrt\fR \fIarg\fR
+.br
+\fB::tcl::mathfunc::log\fR \fIarg\fR
+.br
+\fB::tcl::mathfunc::log10\fR \fIarg\fR
+.br
+\fB::tcl::mathfunc::max\fR \fIarg\fR ?\fIarg\fR ...?
+.br
+\fB::tcl::mathfunc::min\fR \fIarg\fR ?\fIarg\fR ...?
+.br
+\fB::tcl::mathfunc::pow\fR \fIx\fR \fIy\fR
+.br
+\fB::tcl::mathfunc::rand\fR
+.br
+\fB::tcl::mathfunc::round\fR \fIarg\fR
+.br
+\fB::tcl::mathfunc::sin\fR \fIarg\fR
+.br
+\fB::tcl::mathfunc::sinh\fR \fIarg\fR
+.br
+\fB::tcl::mathfunc::sqrt\fR \fIarg\fR
+.br
+\fB::tcl::mathfunc::srand\fR \fIarg\fR
+.br
+\fB::tcl::mathfunc::tan\fR \fIarg\fR
+.br
+\fB::tcl::mathfunc::tanh\fR \fIarg\fR
+.br
+\fB::tcl::mathfunc::wide\fR \fIarg\fR
+.sp
+.BE
+.SH "DESCRIPTION"
+.PP
+The \fBexpr\fR command handles mathematical functions of the form
+\fBsin($x)\fR or \fBatan2($y,$x)\fR by converting them to calls of the
+form \fB[tcl::mathfunc::sin [expr {$x}]]\fR or
+\fB[tcl::mathfunc::atan2 [expr {$y}] [expr {$x}]]\fR.
+A number of math functions are available by default within the
+namespace \fB::tcl::mathfunc\fR; these functions are also available
+for code apart from \fBexpr\fR, by invoking the given commands
+directly.
+.PP
+Tcl supports the following mathematical functions in expressions, all
+of which work solely with floating-point numbers unless otherwise noted:
+.DS
+.ta 3c 6c 9c
+\fBabs\fR	\fBacos\fR	\fBasin\fR	\fBatan\fR
+\fBatan2\fR	\fBbool\fR	\fBceil\fR	\fBcos\fR
+\fBcosh\fR	\fBdouble\fR	\fBentier\fR	\fBexp\fR
+\fBfloor\fR	\fBfmod\fR	\fBhypot\fR	\fBint\fR
+\fBisqrt\fR	\fBlog\fR	\fBlog10\fR	\fBmax\fR
+\fBmin\fR	\fBpow\fR	\fBrand\fR	\fBround\fR
+\fBsin\fR	\fBsinh\fR	\fBsqrt\fR	\fBsrand\fR
+\fBtan\fR	\fBtanh\fR	\fBwide\fR
+.DE
+.PP
+In addition to these predefined functions, applications may
+define additional functions by using \fBproc\fR (or any other method,
+such as \fBinterp alias\fR or \fBTcl_CreateObjCommand\fR) to define
+new commands in the \fBtcl::mathfunc\fR namespace.  In addition, an
+obsolete interface named \fBTcl_CreateMathFunc\fR() is available to
+extensions that are written in C. The latter interface is not recommended
+for new implementations.
+.SS "DETAILED DEFINITIONS"
+.TP
+\fBabs \fIarg\fR
+.
+Returns the absolute value of \fIarg\fR.  \fIArg\fR may be either
+integer or floating-point, and the result is returned in the same form.
+.TP
+\fBacos \fIarg\fR
+.
+Returns the arc cosine of \fIarg\fR, in the range [\fI0\fR,\fIpi\fR]
+radians. \fIArg\fR should be in the range [\fI\-1\fR,\fI1\fR].
+.TP
+\fBasin \fIarg\fR
+.
+Returns the arc sine of \fIarg\fR, in the range [\fI\-pi/2\fR,\fIpi/2\fR]
+radians.  \fIArg\fR should be in the range [\fI\-1\fR,\fI1\fR].
+.TP
+\fBatan \fIarg\fR
+.
+Returns the arc tangent of \fIarg\fR, in the range [\fI\-pi/2\fR,\fIpi/2\fR]
+radians.
+.TP
+\fBatan2 \fIy x\fR
+.
+Returns the arc tangent of \fIy\fR/\fIx\fR, in the range [\fI\-pi\fR,\fIpi\fR]
+radians.  \fIx\fR and \fIy\fR cannot both be 0.  If \fIx\fR is greater
+than \fI0\fR, this is equivalent to
+.QW "\fBatan \fR[\fBexpr\fR {\fIy\fB/\fIx\fR}]" .
+.TP
+\fBbool \fIarg\fR
+.
+Accepts any numeric value, or any string acceptable to
+\fBstring is boolean\fR, and returns the corresponding
+boolean value \fB0\fR or \fB1\fR.  Non-zero numbers are true.
+Other numbers are false.  Non-numeric strings produce boolean value in
+agreement with \fBstring is true\fR and \fBstring is false\fR.
+.TP
+\fBceil \fIarg\fR
+.
+Returns the smallest integral floating-point value (i.e. with a zero
+fractional part) not less than \fIarg\fR.  The argument may be any
+numeric value.
+.TP
+\fBcos \fIarg\fR
+.
+Returns the cosine of \fIarg\fR, measured in radians.
+.TP
+\fBcosh \fIarg\fR
+.
+Returns the hyperbolic cosine of \fIarg\fR.  If the result would cause
+an overflow, an error is returned.
+.TP
+\fBdouble \fIarg\fR
+.
+The argument may be any numeric value,
+If \fIarg\fR is a floating-point value, returns \fIarg\fR, otherwise converts
+\fIarg\fR to floating-point and returns the converted value.  May return
+\fBInf\fR or \fB\-Inf\fR when the argument is a numeric value that exceeds
+the floating-point range.
+.TP
+\fBentier \fIarg\fR
+.
+The argument may be any numeric value.  The integer part of \fIarg\fR
+is determined and returned.  The integer range returned by this function
+is unlimited, unlike \fBint\fR and \fBwide\fR which
+truncate their range to fit in particular storage widths.
+.TP
+\fBexp \fIarg\fR
+.
+Returns the exponential of \fIarg\fR, defined as \fIe\fR**\fIarg\fR.
+If the result would cause an overflow, an error is returned.
+.TP
+\fBfloor \fIarg\fR
+.
+Returns the largest integral floating-point value (i.e. with a zero
+fractional part) not greater than \fIarg\fR.  The argument may be
+any numeric value.
+.TP
+\fBfmod \fIx y\fR
+.
+Returns the floating-point remainder of the division of \fIx\fR by
+\fIy\fR.  If \fIy\fR is 0, an error is returned.
+.TP
+\fBhypot \fIx y\fR
+.
+Computes the length of the hypotenuse of a right-angled triangle,
+approximately
+.QW "\fBsqrt\fR [\fBexpr\fR {\fIx\fB*\fIx\fB+\fIy\fB*\fIy\fR}]"
+except for being more numerically stable when the two arguments have
+substantially different magnitudes.
+.TP
+\fBint \fIarg\fR
+.
+The argument may be any numeric value.  The integer part of \fIarg\fR
+is determined, and then the low order bits of that integer value up
+to the machine word size are returned as an integer value.  For reference,
+the number of bytes in the machine word are stored in the \fBwordSize\fR
+element of the \fBtcl_platform\fR array.
+.TP
+\fBisqrt \fIarg\fR
+.
+Computes the integer part of the square root of \fIarg\fR.  \fIArg\fR must be
+a positive value, either an integer or a floating point number.
+Unlike \fBsqrt\fR, which is limited to the precision of a floating point
+number, \fIisqrt\fR will return a result of arbitrary precision.
+.TP
+\fBlog \fIarg\fR
+.
+Returns the natural logarithm of \fIarg\fR.  \fIArg\fR must be a
+positive value.
+.TP
+\fBlog10 \fIarg\fR
+.
+Returns the base 10 logarithm of \fIarg\fR.  \fIArg\fR must be a
+positive value.
+.TP
+\fBmax \fIarg\fB \fI...\fR
+.
+Accepts one or more numeric arguments.  Returns the one argument
+with the greatest value.
+.TP
+\fBmin \fIarg\fB \fI...\fR
+.
+Accepts one or more numeric arguments.  Returns the one argument
+with the least value.
+.TP
+\fBpow \fIx y\fR
+.
+Computes the value of \fIx\fR raised to the power \fIy\fR.  If \fIx\fR
+is negative, \fIy\fR must be an integer value.
+.TP
+\fBrand\fR
+.
+Returns a pseudo-random floating-point value in the range (\fI0\fR,\fI1\fR).
+The generator algorithm is a simple linear congruential generator that
+is not cryptographically secure.  Each result from \fBrand\fR completely
+determines all future results from subsequent calls to \fBrand\fR, so
+\fBrand\fR should not be used to generate a sequence of secrets, such as
+one-time passwords.  The seed of the generator is initialized from the
+internal clock of the machine or may be set with the \fBsrand\fR function.
+.TP
+\fBround \fIarg\fR
+.
+If \fIarg\fR is an integer value, returns \fIarg\fR, otherwise converts
+\fIarg\fR to integer by rounding and returns the converted value.
+.TP
+\fBsin \fIarg\fR
+.
+Returns the sine of \fIarg\fR, measured in radians.
+.TP
+\fBsinh \fIarg\fR
+.
+Returns the hyperbolic sine of \fIarg\fR.  If the result would cause
+an overflow, an error is returned.
+.TP
+\fBsqrt \fIarg\fR
+.
+The argument may be any non-negative numeric value.  Returns a floating-point
+value that is the square root of \fIarg\fR.  May return \fBInf\fR when the
+argument is a numeric value that exceeds the square of the maximum value of
+the floating-point range.
+.TP
+\fBsrand \fIarg\fR
+.
+The \fIarg\fR, which must be an integer, is used to reset the seed for
+the random number generator of \fBrand\fR.  Returns the first random
+number (see \fBrand\fR) from that seed.  Each interpreter has its own seed.
+.TP
+\fBtan \fIarg\fR
+.
+Returns the tangent of \fIarg\fR, measured in radians.
+.TP
+\fBtanh \fIarg\fR
+.
+Returns the hyperbolic tangent of \fIarg\fR.
+.TP
+\fBwide \fIarg\fR
+.
+The argument may be any numeric value.  The integer part of \fIarg\fR
+is determined, and then the low order 64 bits of that integer value
+are returned as an integer value.
+.SH "SEE ALSO"
+expr(n), mathop(n), namespace(n)
+.SH "COPYRIGHT"
+.nf
+Copyright (c) 1993 The Regents of the University of California.
+Copyright (c) 1994-2000 Sun Microsystems Incorporated.
+Copyright (c) 2005, 2006 by Kevin B. Kenny <kennykb@acm.org>.
+.fi
+'\" Local Variables:
+'\" mode: nroff
+'\" fill-column: 78
+'\" End:
diff --git a/doc/mathop.n b/doc/mathop.n
new file mode 100644
index 0000000..4c16d76
--- /dev/null
+++ b/doc/mathop.n
@@ -0,0 +1,310 @@
+.\"
+.\" Copyright (c) 2006-2007 Donal K. Fellows.
+.\"
+.\" See the file "license.terms" for information on usage and redistribution
+.\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+.\"
+.TH mathop n 8.5 Tcl "Tcl Mathematical Operator Commands"
+.so man.macros
+.BS
+.\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+mathop \- Mathematical operators as Tcl commands
+.SH SYNOPSIS
+package require \fBTcl 8.5\fR
+.sp
+\fB::tcl::mathop::!\fR \fInumber\fR
+.br
+\fB::tcl::mathop::~\fR \fInumber\fR
+.br
+\fB::tcl::mathop::+\fR ?\fInumber\fR ...?
+.br
+\fB::tcl::mathop::\-\fR \fInumber\fR ?\fInumber\fR ...?
+.br
+\fB::tcl::mathop::*\fR ?\fInumber\fR ...?
+.br
+\fB::tcl::mathop::/\fR \fInumber\fR ?\fInumber\fR ...?
+.br
+\fB::tcl::mathop::%\fR \fInumber number\fR
+.br
+\fB::tcl::mathop::**\fR ?\fInumber\fR ...?
+.br
+\fB::tcl::mathop::&\fR ?\fInumber\fR ...?
+.br
+\fB::tcl::mathop::|\fR ?\fInumber\fR ...?
+.br
+\fB::tcl::mathop::^\fR ?\fInumber\fR ...?
+.br
+\fB::tcl::mathop::<<\fR \fInumber number\fR
+.br
+\fB::tcl::mathop::>>\fR \fInumber number\fR
+.br
+\fB::tcl::mathop::==\fR ?\fIarg\fR ...?
+.br
+\fB::tcl::mathop::!=\fR \fIarg arg\fR
+.br
+\fB::tcl::mathop::<\fR ?\fIarg\fR ...?
+.br
+\fB::tcl::mathop::<=\fR ?\fIarg\fR ...?
+.br
+\fB::tcl::mathop::>=\fR ?\fIarg\fR ...?
+.br
+\fB::tcl::mathop::>\fR ?\fIarg\fR ...?
+.br
+\fB::tcl::mathop::eq\fR ?\fIarg\fR ...?
+.br
+\fB::tcl::mathop::ne\fR \fIarg arg\fR
+.br
+\fB::tcl::mathop::in\fR \fIarg list\fR
+.br
+\fB::tcl::mathop::ni\fR \fIarg list\fR
+.sp
+.BE
+.SH DESCRIPTION
+.PP
+The commands in the \fB::tcl::mathop\fR namespace implement the same set of
+operations as supported by the \fBexpr\fR command. All are exported from the
+namespace, but are not imported into any other namespace by default. Note that
+renaming, reimplementing or deleting any of the commands in the namespace does
+\fInot\fR alter the way that the \fBexpr\fR command behaves, and nor does
+defining any new commands in the \fB::tcl::mathop\fR namespace.
+.PP
+The following operator commands are supported:
+.DS
+.ta 2c 4c 6c 8c
+\fB~\fR	\fB!\fR	\fB+\fR	\fB\-\fR	\fB*\fR
+\fB/\fR	\fB%\fR	\fB**\fR	\fB&\fR	\fB|\fR
+\fB^\fR	\fB>>\fR	\fB<<\fR	\fB==\fR	\fBeq\fR
+\fB!=\fR	\fBne\fR	\fB<\fR	\fB<=\fR	\fB>\fR
+\fB>=\fR	\fBin\fR	\fBni\fR
+.DE
+.SS "MATHEMATICAL OPERATORS"
+.PP
+The behaviors of the mathematical operator commands are as follows:
+.TP
+\fB!\fR \fIboolean\fR
+.
+Returns the boolean negation of \fIboolean\fR, where \fIboolean\fR may be any
+numeric value or any other form of boolean value (i.e. it returns truth if the
+argument is falsity or zero, and falsity if the argument is truth or
+non-zero).
+.TP
+\fB+\fR ?\fInumber\fR ...?
+.
+Returns the sum of arbitrarily many arguments. Each \fInumber\fR argument may
+be any numeric value. If no arguments are given, the result will be zero (the
+summation identity).
+.TP
+\fB\-\fR \fInumber\fR ?\fInumber\fR ...?
+.
+If only a single \fInumber\fR argument is given, returns the negation of that
+numeric value. Otherwise returns the number that results when all subsequent
+numeric values are subtracted from the first one. All \fInumber\fR arguments
+must be numeric values. At least one argument must be given.
+.TP
+\fB*\fR ?\fInumber\fR ...?
+.
+Returns the product of arbitrarily many arguments. Each \fInumber\fR may be
+any numeric value. If no arguments are given, the result will be one (the
+multiplicative identity).
+.TP
+\fB/\fR \fInumber\fR ?\fInumber\fR ...?
+.
+If only a single \fInumber\fR argument is given, returns the reciprocal of that
+numeric value (i.e. the value obtained by dividing 1.0 by that value).
+Otherwise returns the number that results when the first numeric argument is
+divided by all subsequent numeric arguments. All \fInumber\fR arguments must
+be numeric values. At least one argument must be given.
+.RS
+.PP
+Note that when the leading values in the list of arguments are integers,
+integer division will be used for those initial steps (i.e. the intermediate
+results will be as if the functions \fIfloor\fR and \fIint\fR are applied to
+them, in that order). If all values in the operation are integers, the result
+will be an integer.
+.RE
+.TP
+\fB%\fR \fInumber number\fR
+.
+Returns the integral modulus (i.e., remainder) of the first argument
+with respect to the second.
+Each \fInumber\fR must have an integral value.
+Also, the sign of the result will be the same as the sign of the second
+\fInumber\fR, which must not be zero.
+.RS
+.PP
+Note that Tcl defines this operation exactly even for negative numbers, so
+that the following command returns a true value (omitting the namespace for
+clarity):
+.PP
+.CS
+\fB==\fR [\fB*\fR [\fB/\fI x y\fR] \fIy\fR] [\fB\-\fI x\fR [\fB%\fI x y\fR]]
+.CE
+.RE
+.TP
+\fB**\fR ?\fInumber\fR ...?
+.
+Returns the result of raising each value to the power of the result of
+recursively operating on the result of processing the following arguments, so
+.QW "\fB** 2 3 4\fR"
+is the same as
+.QW "\fB** 2 [** 3 4]\fR" .
+Each \fInumber\fR may be
+any numeric value, though the second number must not be fractional if the
+first is negative. If no arguments are given, the result will be one, and if
+only one argument is given, the result will be that argument. The
+result will have an integral value only when all arguments are
+integral values.
+.SS "COMPARISON OPERATORS"
+.PP
+The behaviors of the comparison operator commands (most of which operate
+preferentially on numeric arguments) are as follows:
+.TP
+\fB==\fR ?\fIarg\fR ...?
+.
+Returns whether each argument is equal to the arguments on each side of it in
+the sense of the \fBexpr\fR == operator (\fIi.e.\fR, numeric comparison if
+possible, exact string comparison otherwise). If fewer than two arguments
+are given, this operation always returns a true value.
+.TP
+\fBeq\fR ?\fIarg\fR ...?
+.
+Returns whether each argument is equal to the arguments on each side of it
+using exact string comparison. If fewer than two arguments are given, this
+operation always returns a true value.
+.TP
+\fB!=\fR \fIarg arg\fR
+.
+Returns whether the two arguments are not equal to each other, in the sense of
+the \fBexpr\fR != operator (\fIi.e.\fR, numeric comparison if possible, exact
+string comparison otherwise).
+.TP
+\fBne\fR \fIarg arg\fR
+.
+Returns whether the two arguments are not equal to each other using exact
+string comparison.
+.TP
+\fB<\fR ?\fIarg\fR ...?
+.
+Returns whether the arbitrarily-many arguments are ordered, with each argument
+after the first having to be strictly more than the one preceding it.
+Comparisons are performed preferentially on the numeric values, and are
+otherwise performed using UNICODE string comparison. If fewer than two
+arguments are present, this operation always returns a true value. When the
+arguments are numeric but should be compared as strings, the \fBstring
+compare\fR command should be used instead.
+.TP
+\fB<=\fR ?\fIarg\fR ...?
+.
+Returns whether the arbitrarily-many arguments are ordered, with each argument
+after the first having to be equal to or more than the one preceding it.
+Comparisons are performed preferentially on the numeric values, and are
+otherwise performed using UNICODE string comparison. If fewer than two
+arguments are present, this operation always returns a true value. When the
+arguments are numeric but should be compared as strings, the \fBstring
+compare\fR command should be used instead.
+.TP
+\fB>\fR ?\fIarg\fR ...?
+.
+Returns whether the arbitrarily-many arguments are ordered, with each argument
+after the first having to be strictly less than the one preceding it.
+Comparisons are performed preferentially on the numeric values, and are
+otherwise performed using UNICODE string comparison. If fewer than two
+arguments are present, this operation always returns a true value. When the
+arguments are numeric but should be compared as strings, the \fBstring
+compare\fR command should be used instead.
+.TP
+\fB>=\fR ?\fIarg\fR ...?
+.
+Returns whether the arbitrarily-many arguments are ordered, with each argument
+after the first having to be equal to or less than the one preceding it.
+Comparisons are performed preferentially on the numeric values, and are
+otherwise performed using UNICODE string comparison. If fewer than two
+arguments are present, this operation always returns a true value. When the
+arguments are numeric but should be compared as strings, the \fBstring
+compare\fR command should be used instead.
+.SS "BIT-WISE OPERATORS"
+.PP
+The behaviors of the bit-wise operator commands (all of which only operate on
+integral arguments) are as follows:
+.TP
+\fB~\fR \fInumber\fR
+.
+Returns the bit-wise negation of \fInumber\fR. \fINumber\fR may be an integer
+of any size. Note that the result of this operation will always have the
+opposite sign to the input \fInumber\fR.
+.TP
+\fB&\fR ?\fInumber\fR ...?
+.
+Returns the bit-wise AND of each of the arbitrarily many arguments. Each
+\fInumber\fR must have an integral value. If no arguments are given, the
+result will be minus one.
+.TP
+\fB|\fR ?\fInumber\fR ...?
+.
+Returns the bit-wise OR of each of the arbitrarily many arguments. Each
+\fInumber\fR must have an integral value. If no arguments are given, the
+result will be zero.
+.TP
+\fB^\fR ?\fInumber\fR ...?
+.
+Returns the bit-wise XOR of each of the arbitrarily many arguments. Each
+\fInumber\fR must have an integral value. If no arguments are given, the
+result will be zero.
+.TP
+\fB<<\fR \fInumber number\fR
+.
+Returns the result of bit-wise shifting the first argument left by the
+number of bits specified in the second argument. Each \fInumber\fR
+must have an integral value.
+.TP
+\fB>>\fR \fInumber number\fR
+.
+Returns the result of bit-wise shifting the first argument right by
+the number of bits specified in the second argument. Each \fInumber\fR
+must have an integral value.
+.SS "LIST OPERATORS"
+.PP
+The behaviors of the list-oriented operator commands are as follows:
+.TP
+\fBin\fR \fIarg list\fR
+.
+Returns whether the value \fIarg\fR is present in the list \fIlist\fR
+(according to exact string comparison of elements).
+.TP
+\fBni\fR \fIarg list\fR
+.
+Returns whether the value \fIarg\fR is not present in the list \fIlist\fR
+(according to exact string comparison of elements).
+.SH EXAMPLES
+.PP
+The simplest way to use the operators is often by using \fBnamespace path\fR
+to make the commands available. This has the advantage of not affecting the
+set of commands defined by the current namespace.
+.PP
+.CS
+namespace path {\fB::tcl::mathop\fR ::tcl::mathfunc}
+
+\fI# Compute the sum of some numbers\fR
+set sum [\fB+\fR 1 2 3]
+
+\fI# Compute the average of a list\fR
+set list {1 2 3 4 5 6}
+set mean [\fB/\fR [\fB+\fR {*}$list] [double [llength $list]]]
+
+\fI# Test for list membership\fR
+set gotIt [\fBin\fR 3 $list]
+
+\fI# Test to see if a value is within some defined range\fR
+set inRange [\fB<=\fR 1 $x 5]
+
+\fI# Test to see if a list is sorted\fR
+set sorted [\fB<=\fR {*}$list]
+.CE
+.SH "SEE ALSO"
+expr(n), mathfunc(n), namespace(n)
+.SH KEYWORDS
+command, expression, operator
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/doc/memory.n b/doc/memory.n
new file mode 100644
index 0000000..c8cdb21
--- /dev/null
+++ b/doc/memory.n
@@ -0,0 +1,115 @@
+'\"
+'\" Copyright (c) 1992-1999 by Karl Lehenbauer and Mark Diekhans
+'\" Copyright (c) 2000 by Scriptics Corporation.
+'\" All rights reserved.
+'\"
+.TH memory n 8.1 Tcl "Tcl Built-In Commands"
+.so man.macros
+.BS
+.SH NAME
+memory \- Control Tcl memory debugging capabilities
+.SH SYNOPSIS
+\fBmemory \fIoption \fR?\fIarg arg ...\fR?
+.BE
+.SH DESCRIPTION
+.PP
+The \fBmemory\fR command gives the Tcl developer control of Tcl's memory
+debugging capabilities.  The memory command has several suboptions, which are
+described below.  It is only available when Tcl has been compiled with
+memory debugging enabled (when \fBTCL_MEM_DEBUG\fR is defined at
+compile time), and after \fBTcl_InitMemory\fR has been called.
+.TP
+\fBmemory active\fR \fIfile\fR
+.
+Write a list of all currently allocated memory to the specified \fIfile\fR.
+.TP
+\fBmemory break_on_malloc\fR \fIcount\fR
+.
+After the \fIcount\fR allocations have been performed, \fBckalloc\fR
+outputs a message to this effect and that it is now attempting to enter
+the C debugger.  Tcl will then issue a \fISIGINT\fR signal against itself.
+If you are running Tcl under a C debugger, it should then enter the debugger
+command mode.
+.TP
+\fBmemory info\fR
+.
+Returns a report containing the total allocations and frees since
+Tcl began, the current packets allocated (the current
+number of calls to \fBckalloc\fR not met by a corresponding call
+to \fBckfree\fR), the current bytes allocated, and the maximum number
+of packets and bytes allocated.
+.TP
+\fBmemory init \fR[\fBon\fR|\fBoff\fR]
+.
+Turn on or off the pre-initialization of all allocated memory
+with bogus bytes.  Useful for detecting the use of uninitialized
+values.
+.TP
+\fBmemory objs \fIfile\fR
+.
+Causes a list of all allocated Tcl_Obj values to be written to the specified
+\fIfile\fR immediately, together with where they were allocated.  Useful for
+checking for leaks of values.
+.TP
+\fBmemory onexit\fR \fIfile\fR
+.
+Causes a list of all allocated memory to be written to the specified \fIfile\fR
+during the finalization of Tcl's memory subsystem.  Useful for checking
+that memory is properly cleaned up during process exit.
+.TP
+\fBmemory tag\fR \fIstring\fR
+.
+Each packet of memory allocated by \fBckalloc\fR can have associated
+with it a string-valued tag.  In the lists of allocated memory generated
+by \fBmemory active\fR and \fBmemory onexit\fR, the tag for each packet
+is printed along with other information about the packet.  The
+\fBmemory tag\fR command sets the tag value for subsequent calls
+to \fBckalloc\fR to be \fIstring\fR.
+.TP
+\fBmemory trace \fR[\fBon\fR|\fBoff\fR]
+.
+Turns memory tracing on or off.  When memory tracing is on, every call
+to \fBckalloc\fR causes a line of trace information to be written to
+\fIstderr\fR, consisting of the word \fIckalloc\fR, followed by the
+address returned, the amount of memory allocated, and the C filename
+and line number of the code performing the allocation.  For example:
+.RS
+.PP
+.CS
+ckalloc 40e478 98 tclProc.c 1406
+.CE
+.PP
+Calls to \fBckfree\fR are traced in the same manner.
+.RE
+.TP
+\fBmemory trace_on_at_malloc\fR \fIcount\fR
+.
+Enable memory tracing after \fIcount\fR \fBckalloc\fRs have been performed.
+For example, if you enter \fBmemory trace_on_at_malloc 100\fR,
+after the 100th call to \fBckalloc\fR, memory trace information will begin
+being displayed for all allocations and frees.  Since there can be a lot
+of memory activity before a problem occurs, judicious use of this option
+can reduce the slowdown caused by tracing (and the amount of trace information
+produced), if you can identify a number of allocations that occur before
+the problem sets in.  The current number of memory allocations that have
+occurred since Tcl started is printed on a guard zone failure.
+.TP
+\fBmemory validate \fR[\fBon\fR|\fBoff\fR]
+.
+Turns memory validation on or off. When memory validation is enabled,
+on every call to \fBckalloc\fR or \fBckfree\fR, the guard zones are
+checked for every piece of memory currently in existence that was
+allocated by \fBckalloc\fR.  This has a large performance impact and
+should only be used when overwrite problems are strongly suspected.
+The advantage of enabling memory validation is that a guard zone
+overwrite can be detected on the first call to \fBckalloc\fR or
+\fBckfree\fR after the overwrite occurred, rather than when the
+specific memory with the overwritten guard zone(s) is freed, which may
+occur long after the overwrite occurred.
+.SH "SEE ALSO"
+ckalloc, ckfree, Tcl_ValidateAllMemory, Tcl_DumpActiveMemory, TCL_MEM_DEBUG
+.SH KEYWORDS
+memory, debug
+'\"Local Variables:
+'\"mode: nroff
+'\"End:
diff --git a/doc/msgcat.n b/doc/msgcat.n
new file mode 100644
index 0000000..2fc1eee
--- /dev/null
+++ b/doc/msgcat.n
@@ -0,0 +1,651 @@
+'\"
+'\" Copyright (c) 1998 Mark Harrison.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH "msgcat" n 1.5 msgcat "Tcl Bundled Packages"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+msgcat \- Tcl message catalog
+.SH SYNOPSIS
+\fBpackage require Tcl 8.5\fR
+.sp
+\fBpackage require msgcat 1.6\fR
+.sp
+\fB::msgcat::mc \fIsrc-string\fR ?\fIarg arg ...\fR?
+.sp
+\fB::msgcat::mcmax ?\fIsrc-string src-string ...\fR?
+.sp
+.VS "TIP 412"
+\fB::msgcat::mcexists\fR ?\fB-exactnamespace\fR? ?\fB-exactlocale\fR? \fIsrc-string\fR
+.VE "TIP 412"
+.sp
+\fB::msgcat::mclocale \fR?\fInewLocale\fR?
+.sp
+\fB::msgcat::mcpreferences\fR
+.sp
+.VS "TIP 412"
+\fB::msgcat::mcloadedlocales subcommand\fR ?\fIlocale\fR?
+.VE "TIP 412"
+.sp
+\fB::msgcat::mcload \fIdirname\fR
+.sp
+\fB::msgcat::mcset \fIlocale src-string \fR?\fItranslate-string\fR?
+.sp
+\fB::msgcat::mcmset \fIlocale src-trans-list\fR
+.sp
+\fB::msgcat::mcflset \fIsrc-string \fR?\fItranslate-string\fR?
+.sp
+\fB::msgcat::mcflmset \fIsrc-trans-list\fR
+.sp
+\fB::msgcat::mcunknown \fIlocale src-string\fR ?\fIarg arg ...\fR?
+.sp
+.VS "TIP 412"
+\fB::msgcat::mcpackagelocale subcommand\fR ?\fIlocale\fR?
+.sp
+\fB::msgcat::mcpackageconfig subcommand\fR \fIoption\fR ?\fIvalue\fR?
+.sp
+\fB::msgcat::mcforgetpackage\fR
+.VE "TIP 412"
+.BE
+.SH DESCRIPTION
+.PP
+The \fBmsgcat\fR package provides a set of functions
+that can be used to manage multi-lingual user interfaces.
+Text strings are defined in a
+.QW "message catalog"
+which is independent from the application, and
+which can be edited or localized without modifying
+the application source code.  New languages
+or locales may be provided by adding a new file to
+the message catalog.
+.PP
+\fBmsgcat\fR distinguises packages by its namespace.
+Each package has its own message catalog and configuration settings in \fBmsgcat\fR.
+.PP
+A \fIlocale\fR is a specification string describing a user language like \fBde_ch\fR for Swiss German.
+In \fBmsgcat\fR, there is a global locale initialized by the system locale of the current system.
+Each package may decide to use the global locale or to use a package specific locale.
+.PP
+The global locale may be changed on demand, for example by a user initiated language change or within a multi user application like a web server.
+.SH COMMANDS
+.TP
+\fB::msgcat::mc \fIsrc-string\fR ?\fIarg arg ...\fR?
+.
+Returns a translation of \fIsrc-string\fR according to the
+current locale.  If additional arguments past \fIsrc-string\fR
+are given, the \fBformat\fR command is used to substitute the
+additional arguments in the translation of \fIsrc-string\fR.
+.RS
+.PP
+\fB::msgcat::mc\fR will search the messages defined
+in the current namespace for a translation of \fIsrc-string\fR; if
+none is found, it will search in the parent of the current namespace,
+and so on until it reaches the global namespace.  If no translation
+string exists, \fB::msgcat::mcunknown\fR is called and the string
+returned from \fB::msgcat::mcunknown\fR is returned.
+.PP
+\fB::msgcat::mc\fR is the main function used to localize an
+application.  Instead of using an English string directly, an
+application can pass the English string through \fB::msgcat::mc\fR and
+use the result.  If an application is written for a single language in
+this fashion, then it is easy to add support for additional languages
+later simply by defining new message catalog entries.
+.RE
+.TP
+\fB::msgcat::mcmax ?\fIsrc-string src-string ...\fR?
+.
+Given several source strings, \fB::msgcat::mcmax\fR returns the length
+of the longest translated string.  This is useful when designing
+localized GUIs, which may require that all buttons, for example, be a
+fixed width (which will be the width of the widest button).
+.TP
+\fB::msgcat::mcexists\fR ?\fB-exactnamespace\fR? ?\fB-exactlocale\fR? \fIsrc-string\fR
+.
+.VS "TIP 412"
+Return true, if there is a translation for the given \fIsrc-string\fR.
+.PP
+.RS
+The search may be limited by the option \fB\-exactnamespace\fR to only check the current namespace and not any parent namespaces.
+.PP
+It may also be limited by the option \fB\-exactlocale\fR to only check the first prefered locale (e.g. first element returned by \fB::msgcat::mcpreferences\fR if global locale is used).
+.RE
+.VE "TIP 412"
+.TP
+\fB::msgcat::mclocale \fR?\fInewLocale\fR?
+.
+This function sets the locale to \fInewLocale\fR.  If \fInewLocale\fR
+is omitted, the current locale is returned, otherwise the current locale
+is set to \fInewLocale\fR.  msgcat stores and compares the locale in a
+case-insensitive manner, and returns locales in lowercase.
+The initial locale is determined by the locale specified in
+the user's environment.  See \fBLOCALE SPECIFICATION\fR
+below for a description of the locale string format.
+.RS
+.PP
+.VS "TIP 412"
+If the locale is set, the preference list of locales is evaluated.
+Locales in this list are loaded now, if not jet loaded.
+.VE "TIP 412"
+.RE
+.TP
+\fB::msgcat::mcpreferences\fR
+.
+Returns an ordered list of the locales preferred by
+the user, based on the user's language specification.
+The list is ordered from most specific to least
+preference.  The list is derived from the current
+locale set in msgcat by \fB::msgcat::mclocale\fR, and
+cannot be set independently.  For example, if the
+current locale is en_US_funky, then \fB::msgcat::mcpreferences\fR
+returns \fB{en_us_funky en_us en {}}\fR.
+.TP
+\fB::msgcat:mcloadedlocales subcommand\fR ?\fIlocale\fR?
+.
+This group of commands manage the list of loaded locales for packages not setting a package locale.
+.PP
+.RS
+The subcommand \fBget\fR returns the list of currently loaded locales.
+.PP
+The subcommand \fBpresent\fR requires the argument \fIlocale\fR and returns true, if this locale is loaded.
+.PP
+The subcommand \fBclear\fR removes all locales and their data, which are not in the current preference list.
+.RE
+.TP
+\fB::msgcat::mcload \fIdirname\fR
+.
+.VS "TIP 412"
+Searches the specified directory for files that match
+the language specifications returned by \fB::msgcat::mcloadedlocales get\fR
+(or \fBmsgcat::mcpackagelocale preferences\fR if a package locale is set) (note that these are all lowercase), extended by the file extension
+.QW .msg .
+Each matching file is
+read in order, assuming a UTF-8 encoding.  The file contents are
+then evaluated as a Tcl script.  This means that Unicode characters
+may be present in the message file either directly in their UTF-8
+encoded form, or by use of the backslash-u quoting recognized by Tcl
+evaluation.  The number of message files which matched the specification
+and were loaded is returned.
+.RS
+.PP
+In addition, the given folder is stored in the \fBmsgcat\fR package configuration option \fImcfolder\fR to eventually load message catalog files required by a locale change.
+.VE "TIP 412"
+.RE
+.TP
+\fB::msgcat::mcset \fIlocale src-string \fR?\fItranslate-string\fR?
+.
+Sets the translation for \fIsrc-string\fR to \fItranslate-string\fR
+in the specified \fIlocale\fR and the current namespace.  If
+\fItranslate-string\fR is not specified, \fIsrc-string\fR is used
+for both.  The function returns \fItranslate-string\fR.
+.TP
+\fB::msgcat::mcmset \fIlocale src-trans-list\fR
+.
+Sets the translation for multiple source strings in
+\fIsrc-trans-list\fR in the specified \fIlocale\fR and the current
+namespace.
+\fIsrc-trans-list\fR must have an even number of elements and is in
+the form {\fIsrc-string translate-string\fR ?\fIsrc-string
+translate-string ...\fR?} \fB::msgcat::mcmset\fR can be significantly
+faster than multiple invocations of \fB::msgcat::mcset\fR. The function
+returns the number of translations set.
+.TP
+\fB::msgcat::mcflset \fIsrc-string \fR?\fItranslate-string\fR?
+Sets the translation for \fIsrc-string\fR to \fItranslate-string\fR in the
+current namespace for the locale implied by the name of the message catalog
+being loaded via \fB::msgcat::mcload\fR.  If \fItranslate-string\fR is not
+specified, \fIsrc-string\fR is used for both.  The function returns
+\fItranslate-string\fR.
+.TP
+\fB::msgcat::mcflmset \fIsrc-trans-list\fR
+Sets the translation for multiple source strings in \fIsrc-trans-list\fR in
+the current namespace for the locale implied by the name of the message
+catalog being loaded via \fB::msgcat::mcload\fR. \fIsrc-trans-list\fR must
+have an even number of elements and is in the form {\fIsrc-string
+translate-string\fR ?\fIsrc-string translate-string ...\fR?}
+\fB::msgcat::mcflmset\fR can be significantly faster than multiple invocations
+of \fB::msgcat::mcflset\fR. The function returns the number of translations set.
+.TP
+\fB::msgcat::mcunknown \fIlocale src-string\fR ?\fIarg arg ...\fR?
+.
+This routine is called by \fB::msgcat::mc\fR in the case when
+a translation for \fIsrc-string\fR is not defined in the
+current locale.  The default action is to return
+\fIsrc-string\fR passed by format if there are any arguments.  This
+procedure can be redefined by the
+application, for example to log error messages for each unknown
+string.  The \fB::msgcat::mcunknown\fR procedure is invoked at the
+same stack context as the call to \fB::msgcat::mc\fR.  The return value
+of \fB::msgcat::mcunknown\fR is used as the return value for the call
+to \fB::msgcat::mc\fR.
+.VS "TIP 412"
+.RS
+.PP
+Note that this routine is only called if the concerned package did not set a package locale unknown command name.
+.RE
+.TP
+\fB::msgcat::mcforgetpackage\fR
+.
+The calling package clears all its state within the \fBmsgcat\fR package including all settings and translations.
+.VE "TIP 412"
+.PP
+.SH "LOCALE SPECIFICATION"
+.PP
+The locale is specified to \fBmsgcat\fR by a locale string
+passed to \fB::msgcat::mclocale\fR.
+The locale string consists of
+a language code, an optional country code, and an optional
+system-specific code, each separated by
+.QW _ .
+The country and language
+codes are specified in standards ISO-639 and ISO-3166.
+For example, the locale
+.QW en
+specifies English and
+.QW en_US
+specifies U.S. English.
+.PP
+When the msgcat package is first loaded, the locale is initialized
+according to the user's environment.  The variables \fBenv(LC_ALL)\fR,
+\fBenv(LC_MESSAGES)\fR, and \fBenv(LANG)\fR are examined in order.
+The first of them to have a non-empty value is used to determine the
+initial locale.  The value is parsed according to the XPG4 pattern
+.PP
+.CS
+language[_country][.codeset][@modifier]
+.CE
+.PP
+to extract its parts.  The initial locale is then set by calling
+\fB::msgcat::mclocale\fR with the argument
+.PP
+.CS
+language[_country][_modifier]
+.CE
+.PP
+On Windows and Cygwin, if none of those environment variables is set,
+msgcat will attempt to extract locale information from the registry.
+From Windows Vista on, the RFC4747 locale name "lang-script-country-options"
+is transformed to the locale as "lang_country_script" (Example:
+sr-Latn-CS -> sr_cs_latin). For Windows XP, the language id is
+transformed analoguously (Example: 0c1a -> sr_yu_cyrillic).
+If all these attempts to discover an initial locale from the user's
+environment fail, msgcat defaults to an initial locale of
+.QW C .
+.PP
+When a locale is specified by the user, a
+.QW "best match"
+search is performed during string translation.  For example, if a user
+specifies
+en_GB_Funky, the locales
+.QW en_gb_funky ,
+.QW en_gb ,
+.QW en
+and
+.MT
+(the empty string)
+are searched in order until a matching translation
+string is found.  If no translation string is available, then
+the unknown handler is called.
+.SH "NAMESPACES AND MESSAGE CATALOGS"
+.PP
+Strings stored in the message catalog are stored relative
+to the namespace from which they were added.  This allows
+multiple packages to use the same strings without fear
+of collisions with other packages.  It also allows the
+source string to be shorter and less prone to typographical
+error.
+.PP
+For example, executing the code
+.PP
+.CS
+\fB::msgcat::mcset\fR en hello "hello from ::"
+namespace eval foo {
+    \fB::msgcat::mcset\fR en hello "hello from ::foo"
+}
+puts [\fB::msgcat::mc\fR hello]
+namespace eval foo {puts [\fB::msgcat::mc\fR hello]}
+.CE
+.PP
+will print
+.PP
+.CS
+hello from ::
+hello from ::foo
+.CE
+.PP
+When searching for a translation of a message, the
+message catalog will search first the current namespace,
+then the parent of the current namespace, and so on until
+the global namespace is reached.  This allows child namespaces to
+.QW inherit
+messages from their parent namespace.
+.PP
+For example, executing (in the
+.QW en
+locale) the code
+.PP
+.CS
+\fB::msgcat::mcset\fR en m1 ":: message1"
+\fB::msgcat::mcset\fR en m2 ":: message2"
+\fB::msgcat::mcset\fR en m3 ":: message3"
+namespace eval ::foo {
+    \fB::msgcat::mcset\fR en m2 "::foo message2"
+    \fB::msgcat::mcset\fR en m3 "::foo message3"
+}
+namespace eval ::foo::bar {
+    \fB::msgcat::mcset\fR en m3 "::foo::bar message3"
+}
+namespace import \fB::msgcat::mc\fR
+puts "[\fBmc\fR m1]; [\fBmc\fR m2]; [\fBmc\fR m3]"
+namespace eval ::foo {puts "[\fBmc\fR m1]; [\fBmc\fR m2]; [\fBmc\fR m3]"}
+namespace eval ::foo::bar {puts "[\fBmc\fR m1]; [\fBmc\fR m2]; [\fBmc\fR m3]"}
+.CE
+.PP
+will print
+.PP
+.CS
+:: message1; :: message2; :: message3
+:: message1; ::foo message2; ::foo message3
+:: message1; ::foo message2; ::foo::bar message3
+.CE
+.SH "LOCATION AND FORMAT OF MESSAGE FILES"
+.PP
+Message files can be located in any directory, subject
+to the following conditions:
+.IP [1]
+All message files for a package are in the same directory.
+.IP [2]
+The message file name is a msgcat locale specifier (all lowercase) followed by
+.QW .msg .
+For example:
+.PP
+.CS
+es.msg    \(em spanish
+en_gb.msg \(em United Kingdom English
+.CE
+.PP
+\fIException:\fR The message file for the root locale
+.MT
+is called
+.QW \fBROOT.msg\fR .
+This exception is made so as not to
+cause peculiar behavior, such as marking the message file as
+.QW hidden
+on Unix file systems.
+.IP [3]
+The file contains a series of calls to \fBmcflset\fR and
+\fBmcflmset\fR, setting the necessary translation strings
+for the language, likely enclosed in a \fBnamespace eval\fR
+so that all source strings are tied to the namespace of
+the package. For example, a short \fBes.msg\fR might contain:
+.PP
+.CS
+namespace eval ::mypackage {
+    \fB::msgcat::mcflset\fR "Free Beer" "Cerveza Gratis"
+}
+.CE
+.SH "RECOMMENDED MESSAGE SETUP FOR PACKAGES"
+.PP
+If a package is installed into a subdirectory of the
+\fBtcl_pkgPath\fR and loaded via \fBpackage require\fR, the
+following procedure is recommended.
+.IP [1]
+During package installation, create a subdirectory
+\fBmsgs\fR under your package directory.
+.IP [2]
+Copy your *.msg files into that directory.
+.IP [3]
+Add the following command to your package initialization script:
+.PP
+.CS
+# load language files, stored in msgs subdirectory
+\fB::msgcat::mcload\fR [file join [file dirname [info script]] msgs]
+.CE
+.SH "POSITIONAL CODES FOR FORMAT AND SCAN COMMANDS"
+.PP
+It is possible that a message string used as an argument
+to \fBformat\fR might have positionally dependent parameters that
+might need to be repositioned.  For example, it might be
+syntactically desirable to rearrange the sentence structure
+while translating.
+.PP
+.CS
+format "We produced %d units in location %s" $num $city
+format "In location %s we produced %d units" $city $num
+.CE
+.PP
+This can be handled by using the positional
+parameters:
+.PP
+.CS
+format "We produced %1\e$d units in location %2\e$s" $num $city
+format "In location %2\e$s we produced %1\e$d units" $num $city
+.CE
+.PP
+Similarly, positional parameters can be used with \fBscan\fR to
+extract values from internationalized strings. Note that it is not
+necessary to pass the output of \fB::msgcat::mc\fR to \fBformat\fR
+directly; by passing the values to substitute in as arguments, the
+formatting substitution is done directly.
+.PP
+.CS
+\fBmsgcat::mc\fR {Produced %1$d at %2$s} $num $city
+# ... where that key is mapped to one of the
+# human-oriented versions by \fBmsgcat::mcset\fR
+.CE
+.VS "TIP 412"
+.SH Package private locale
+.PP
+A package using \fBmsgcat\fR may choose to use its own package private
+locale and its own set of loaded locales, independent to the global
+locale set by \fB::msgcat::mclocale\fR.
+.PP
+This allows a package to change its locale without causing any locales load or removal in other packages and not to invoke the global locale change callback (see below).
+.PP
+This action is controled by the following ensemble:
+.TP
+\fB::msgcat::mcpackagelocale set\fR ?\fIlocale\fR?
+.
+Set or change a package private locale.
+The package private locale is set to the given \fIlocale\fR if the \fIlocale\fR is given.
+If the option \fIlocale\fR is not given, the package is set to package private locale mode, but no locale is changed (e.g. if the global locale was valid for the package before, it is copied to the package private locale).
+.PP
+.RS
+This command may cause the load of locales.
+.RE
+.TP
+\fB::msgcat::mcpackagelocale get\fR
+.
+Return the package private locale or the global locale, if no package private locale is set.
+.TP
+\fB::msgcat::mcpackagelocale preferences\fR
+.
+Return the package private preferences or the global preferences,
+if no package private locale is set.
+.TP
+\fB::msgcat::mcpackagelocale loaded\fR
+.
+Return the list of locales loaded for this package.
+.TP
+\fB::msgcat::mcpackagelocale isset\fR
+.
+Returns true, if a package private locale is set.
+.TP
+\fB::msgcat::mcpackagelocale unset\fR
+.
+Unset the package private locale and use the globale locale.
+Load and remove locales to adjust the list of loaded locales for the
+package to the global loaded locales list.
+.TP
+\fB::msgcat::mcpackagelocale present\fR \fIlocale\fR
+.
+Returns true, if the given locale is loaded for the package.
+.TP
+\fB::msgcat::mcpackagelocale clear\fR
+.
+Clear any loaded locales of the package not present in the package preferences.
+.PP
+.SH Changing package options
+.PP
+Each package using msgcat has a set of options within \fBmsgcat\fR.
+The package options are described in the next sectionPackage options.
+Each package option may be set or unset individually using the following ensemble:
+.TP
+\fB::msgcat::mcpackageconfig get\fR \fIoption\fR
+.
+Return the current value of the given \fIoption\fR.
+This call returns an error if the option is not set for the package.
+.TP
+\fB::msgcat::mcpackageconfig isset\fR \fIoption\fR
+.
+Returns 1, if the given \fIoption\fR is set for the package, 0 otherwise.
+.TP
+\fB::msgcat::mcpackageconfig set\fR \fIoption\fR \fIvalue\fR
+.
+Set the given \fIoption\fR to the given \fIvalue\fR.
+This may invoke additional actions in dependency of the \fIoption\fR.
+The return value is 0 or the number of loaded packages for the option \fBmcfolder\fR.
+.TP
+\fB::msgcat::mcpackageconfig unset\fR \fIoption\fR
+.
+Unsets the given \fIoption\fR for the package.
+No action is taken if the \fIoption\fR is not set for the package.
+The empty string is returned.
+.SS Package options
+.PP
+The following package options are available for each package:
+.TP
+\fBmcfolder\fR
+.
+This is the message folder of the package. This option is set by mcload and by the subcommand set. Both are identical and both return the number of loaded message catalog files.
+.RS
+.PP
+Setting or changing this value will load all locales contained in the preferences valid for the package. This implies also to invoke any set loadcmd (see below).
+.PP
+Unsetting this value will disable message file load for the package.
+.RE
+.TP
+\fBloadcmd\fR
+.
+This callback is invoked before a set of message catalog files are loaded for the package which has this property set.
+.PP
+.RS
+This callback may be used to do any preparation work for message file load or to get the message data from another source like a data base. In this case, no message files are used (mcfolder is unset).
+.PP
+See section \fBcallback invocation\fR below.
+The parameter list appended to this callback is the list of locales to load.
+.PP
+If this callback is changed, it is called with the preferences valid for the package.
+.RE
+.TP
+\fBchangecmd\fR
+.
+This callback is invoked when a default local change was performed. Its purpose is to allow a package to update any dependency on the default locale like showing the GUI in another language.
+.PP
+.RS
+See the callback invocation section below.
+The parameter list appended to this callback is \fBmcpreferences\fR.
+The registered callbacks are invoked in no particular order.
+.RE
+.TP
+\fBunknowncmd\fR
+.
+Use a package locale mcunknown procedure instead of the standard version supplied by the msgcat package (msgcat::mcunknown).
+.PP
+.RS
+The called procedure must return the formatted message which will finally be returned by msgcat::mc.
+.PP
+A generic unknown handler is used if set to the empty string. This consists in returning the key if no arguments are given. With given arguments, format is used to process the arguments.
+.PP
+See section \fBcallback invocation\fR below.
+The appended arguments are identical to \fB::msgcat::mcunknown\fR.
+.RE
+.SS Callback invocation
+A package may decide to register one or multiple callbacks, as described above.
+.PP
+Callbacks are invoked, if:
+.PP
+1. the callback command is set,
+.PP
+2. the command is not the empty string,
+.PP
+3. the registering namespace exists.
+.PP
+If a called routine fails with an error, the \fBbgerror\fR routine for the interpreter is invoked after command completion.
+Only exception is the callback \fBunknowncmd\fR, where an error causes the invoking \fBmc\fR-command to fail with that error.
+.PP
+.SS Examples
+Packages which display a GUI may update their widgets when the global locale changes.
+To register to a callback, use:
+.CS
+namespace eval gui {
+    msgcat::mcpackageconfig changecmd updateGUI
+
+    proc updateGui args {
+        puts "New locale is '[lindex $args 0]'."
+    }
+}
+% msgcat::mclocale fr
+fr
+% New locale is 'fr'.
+.CE
+.PP
+If locales (or additional locales) are contained in another source like a data base, a package may use the load callback and not mcload:
+.CS
+namespace eval db {
+    msgcat::mcpackageconfig loadcmd loadMessages
+
+    proc loadMessages args {
+        foreach locale $args {
+            if {[LocaleInDB $locale]} {
+                msgcat::mcmset $locale [GetLocaleList $locale]
+            }
+        }
+    }
+}
+.CE
+.PP
+The \fBclock\fR command implementation uses \fBmsgcat\fR with a package locale to implement the command line parameter \fB-locale\fR.
+Here are some sketches of the implementation:
+.PP
+First, a package locale is initialized and the generic unknown function is desactivated:
+.CS
+msgcat::mcpackagelocale set
+msgcat::mcpackageconfig unknowncmd ""
+.CE
+As an example, the user requires the week day in a certain locale as follows:
+.CS
+clock format clock seconds -format %A -locale fr
+.CE
+\fBclock\fR sets the package locale to \fBfr\fR and looks for the day name as follows:
+.CS
+msgcat::mcpackagelocale set $locale
+return [lindex [msgcat::mc DAYS_OF_WEEK_FULL] $day]
+### Returns "mercredi"
+.CE
+Within \fBclock\fR, some message-catalog items are heavy in computation and thus are dynamically cached using:
+.CS
+proc ::tcl::clock::LocalizeFormat { locale format } {
+    set key FORMAT_$format
+    if { [::msgcat::mcexists -exactlocale -exactnamespace $key] } {
+        return [mc $key]
+    }
+    #...expensive computation of format clipped...
+    mcset $locale $key $format
+    return $format
+}
+.CE
+.VE "TIP 412"
+.SH CREDITS
+.PP
+The message catalog code was developed by Mark Harrison.
+.SH "SEE ALSO"
+format(n), scan(n), namespace(n), package(n)
+.SH KEYWORDS
+internationalization, i18n, localization, l10n, message, text, translation
+.\" Local Variables:
+.\" mode: nroff
+.\" End:
diff --git a/doc/my.n b/doc/my.n
new file mode 100644
index 0000000..2a9769b
--- /dev/null
+++ b/doc/my.n
@@ -0,0 +1,56 @@
+'\"
+'\" Copyright (c) 2007 Donal K. Fellows
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH my n 0.1 TclOO "TclOO Commands"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+my \- invoke any method of current object
+.SH SYNOPSIS
+.nf
+package require TclOO
+
+\fBmy\fI methodName\fR ?\fIarg ...\fR?
+.fi
+.BE
+.SH DESCRIPTION
+.PP
+The \fBmy\fR command is used to allow methods of objects to invoke any method
+of the object (or its class). In particular, the set of valid values for
+\fImethodName\fR is the set of all methods supported by an object and its
+superclasses, including those that are not exported. The object upon which the
+method is invoked is always the one that is the current context of the method
+(i.e. the object that is returned by \fBself object\fR) from which the
+\fBmy\fR command is invoked.
+.PP
+Each object has its own \fBmy\fR command, contained in its instance namespace.
+.SH EXAMPLES
+.PP
+This example shows basic use of \fBmy\fR to use the \fBvariables\fR method of
+the \fBoo::object\fR class, which is not publicly visible by default:
+.PP
+.CS
+oo::class create c {
+    method count {} {
+        \fBmy\fR variable counter
+        puts [incr counter]
+    }
+}
+c create o
+o count              \fI\(-> prints "1"\fR
+o count              \fI\(-> prints "2"\fR
+o count              \fI\(-> prints "3"\fR
+.CE
+.SH "SEE ALSO"
+next(n), oo::object(n), self(n)
+.SH KEYWORDS
+method, method visibility, object, private method, public method
+
+.\" Local variables:
+.\" mode: nroff
+.\" fill-column: 78
+.\" End:
diff --git a/doc/namespace.n b/doc/namespace.n
new file mode 100644
index 0000000..1f4e85f
--- /dev/null
+++ b/doc/namespace.n
@@ -0,0 +1,969 @@
+'\"
+'\" Copyright (c) 1993-1997 Bell Labs Innovations for Lucent Technologies
+'\" Copyright (c) 1997 Sun Microsystems, Inc.
+'\" Copyright (c) 2000 Scriptics Corporation.
+'\" Copyright (c) 2004-2005 Donal K. Fellows.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH namespace n 8.5 Tcl "Tcl Built-In Commands"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+namespace \- create and manipulate contexts for commands and variables
+.SH SYNOPSIS
+\fBnamespace \fR?\fIsubcommand\fR? ?\fIarg ...\fR?
+.BE
+.SH DESCRIPTION
+.PP
+The \fBnamespace\fR command lets you create, access, and destroy
+separate contexts for commands and variables.
+See the section \fBWHAT IS A NAMESPACE?\fR below
+for a brief overview of namespaces.
+The legal values of \fIsubcommand\fR are listed below.
+Note that you can abbreviate the \fIsubcommand\fRs.
+.TP
+\fBnamespace children \fR?\fInamespace\fR? ?\fIpattern\fR?
+.
+Returns a list of all child namespaces that belong to the
+namespace \fInamespace\fR.
+If \fInamespace\fR is not specified,
+then the children are returned for the current namespace.
+This command returns fully-qualified names,
+which start with a double colon (\fB::\fR).
+If the optional \fIpattern\fR is given,
+then this command returns only the names that match the glob-style pattern.
+The actual pattern used is determined as follows:
+a pattern that starts with double colon (\fB::\fR) is used directly,
+otherwise the namespace \fInamespace\fR
+(or the fully-qualified name of the current namespace)
+is prepended onto the pattern.
+.TP
+\fBnamespace code \fIscript\fR
+.
+Captures the current namespace context for later execution
+of the script \fIscript\fR.
+It returns a new script in which \fIscript\fR has been wrapped
+in a \fBnamespace inscope\fR command.
+The new script has two important properties.
+First, it can be evaluated in any namespace and will cause
+\fIscript\fR to be evaluated in the current namespace
+(the one where the \fBnamespace code\fR command was invoked).
+Second, additional arguments can be appended to the resulting script
+and they will be passed to \fIscript\fR as additional arguments.
+For example, suppose the command
+\fBset script [namespace code {foo bar}]\fR
+is invoked in namespace \fB::a::b\fR.
+Then \fBeval $script [list x y]\fR
+can be executed in any namespace (assuming the value of
+\fBscript\fR has been passed in properly)
+and will have the same effect as the command
+\fB::namespace eval ::a::b {foo bar x y}\fR.
+This command is needed because
+extensions like Tk normally execute callback scripts
+in the global namespace.
+A scoped command captures a command together with its namespace context
+in a way that allows it to be executed properly later.
+See the section \fBSCOPED SCRIPTS\fR for some examples
+of how this is used to create callback scripts.
+.TP
+\fBnamespace current\fR
+.
+Returns the fully-qualified name for the current namespace.
+The actual name of the global namespace is
+.MT
+(i.e., an empty string),
+but this command returns \fB::\fR for the global namespace
+as a convenience to programmers.
+.TP
+\fBnamespace delete \fR?\fInamespace namespace ...\fR?
+.
+Each namespace \fInamespace\fR is deleted
+and all variables, procedures, and child namespaces
+contained in the namespace are deleted.
+If a procedure is currently executing inside the namespace,
+the namespace will be kept alive until the procedure returns;
+however, the namespace is marked to prevent other code from
+looking it up by name.
+If a namespace does not exist, this command returns an error.
+If no namespace names are given, this command does nothing.
+.TP
+\fBnamespace ensemble\fR \fIsubcommand\fR ?\fIarg ...\fR?
+.
+Creates and manipulates a command that is formed out of an ensemble of
+subcommands.  See the section \fBENSEMBLES\fR below for further
+details.
+.TP
+\fBnamespace eval\fR \fInamespace arg\fR ?\fIarg ...\fR?
+.
+Activates a namespace called \fInamespace\fR and evaluates some code
+in that context.
+If the namespace does not already exist, it is created.
+If more than one \fIarg\fR argument is specified,
+the arguments are concatenated together with a space between each one
+in the same fashion as the \fBeval\fR command,
+and the result is evaluated.
+.RS
+.PP
+If \fInamespace\fR has leading namespace qualifiers
+and any leading namespaces do not exist,
+they are automatically created.
+.RE
+.TP
+\fBnamespace exists\fR \fInamespace\fR
+.
+Returns \fB1\fR if \fInamespace\fR is a valid namespace in the current
+context, returns \fB0\fR otherwise.
+.TP
+\fBnamespace export \fR?\fB\-clear\fR? ?\fIpattern pattern ...\fR?
+.
+Specifies which commands are exported from a namespace.
+The exported commands are those that can be later imported
+into another namespace using a \fBnamespace import\fR command.
+Both commands defined in a namespace and
+commands the namespace has previously imported
+can be exported by a namespace.
+The commands do not have to be defined
+at the time the \fBnamespace export\fR command is executed.
+Each \fIpattern\fR may contain glob-style special characters,
+but it may not include any namespace qualifiers.
+That is, the pattern can only specify commands
+in the current (exporting) namespace.
+Each \fIpattern\fR is appended onto the namespace's list of export patterns.
+If the \fB\-clear\fR flag is given,
+the namespace's export pattern list is reset to empty before any
+\fIpattern\fR arguments are appended.
+If no \fIpattern\fRs are given and the \fB\-clear\fR flag is not given,
+this command returns the namespace's current export list.
+.TP
+\fBnamespace forget \fR?\fIpattern pattern ...\fR?
+.
+Removes previously imported commands from a namespace.
+Each \fIpattern\fR is a simple or qualified name such as
+\fBx\fR, \fBfoo::x\fR or \fBa::b::p*\fR.
+Qualified names contain double colons (\fB::\fR) and qualify a name
+with the name of one or more namespaces.
+Each
+.QW "qualified pattern"
+is qualified with the name of an exporting namespace
+and may have glob-style special characters in the command name
+at the end of the qualified name.
+Glob characters may not appear in a namespace name.
+For each
+.QW "simple pattern"
+this command deletes the matching commands of the
+current namespace that were imported from a different namespace.
+For
+.QW "qualified patterns" ,
+this command first finds the matching exported commands.
+It then checks whether any of those commands
+were previously imported by the current namespace.
+If so, this command deletes the corresponding imported commands.
+In effect, this un-does the action of a \fBnamespace import\fR command.
+.TP
+\fBnamespace import \fR?\fB\-force\fR? ?\fIpattern\fR \fIpattern ...\fR?
+.
+Imports commands into a namespace, or queries the set of imported
+commands in a namespace.  When no arguments are present,
+\fBnamespace import\fR returns the list of commands in
+the current namespace that have been imported from other
+namespaces.  The commands in the returned list are in
+the format of simple names, with no namespace qualifiers at all.
+This format is suitable for composition with \fBnamespace forget\fR
+(see \fBEXAMPLES\fR below).
+.RS
+.PP
+When \fIpattern\fR arguments are present,
+each \fIpattern\fR is a qualified name like
+\fBfoo::x\fR or \fBa::p*\fR.
+That is, it includes the name of an exporting namespace
+and may have glob-style special characters in the command name
+at the end of the qualified name.
+Glob characters may not appear in a namespace name.
+When the namespace name is not fully qualified (i.e., does not start
+with a namespace separator) it is resolved as a namespace name in the
+way described in the \fBNAME RESOLUTION\fR section; it is an error if
+no namespace with that name can be found.
+.PP
+All the commands that match a \fIpattern\fR string
+and which are currently exported from their namespace
+are added to the current namespace.
+This is done by creating a new command in the current namespace
+that points to the exported command in its original namespace;
+when the new imported command is called, it invokes the exported command.
+This command normally returns an error
+if an imported command conflicts with an existing command.
+However, if the \fB\-force\fR option is given,
+imported commands will silently replace existing commands.
+The \fBnamespace import\fR command has snapshot semantics:
+that is, only requested commands that are currently defined
+in the exporting namespace are imported.
+In other words, you can import only the commands that are in a namespace
+at the time when the \fBnamespace import\fR command is executed.
+If another command is defined and exported in this namespace later on,
+it will not be imported.
+.RE
+.TP
+\fBnamespace inscope\fR \fInamespace\fR \fIscript\fR ?\fIarg ...\fR?
+.
+Executes a script in the context of the specified \fInamespace\fR.
+This command is not expected to be used directly by programmers;
+calls to it are generated implicitly when applications
+use \fBnamespace code\fR commands to create callback scripts
+that the applications then register with, e.g., Tk widgets.
+The \fBnamespace inscope\fR command is much like the \fBnamespace eval\fR
+command except that the \fInamespace\fR must already exist,
+and \fBnamespace inscope\fR appends additional \fIarg\fRs
+as proper list elements.
+.RS
+.PP
+.CS
+\fBnamespace inscope ::foo $script $x $y $z\fR
+.CE
+.PP
+is equivalent to
+.PP
+.CS
+\fBnamespace eval ::foo [concat $script [list $x $y $z]]\fR
+.CE
+.PP
+thus additional arguments will not undergo a second round of substitution,
+as is the case with \fBnamespace eval\fR.
+.RE
+.TP
+\fBnamespace origin \fIcommand\fR
+.
+Returns the fully-qualified name of the original command
+to which the imported command \fIcommand\fR refers.
+When a command is imported into a namespace,
+a new command is created in that namespace
+that points to the actual command in the exporting namespace.
+If a command is imported into a sequence of namespaces
+\fIa, b,...,n\fR where each successive namespace
+just imports the command from the previous namespace,
+this command returns the fully-qualified name of the original command
+in the first namespace, \fIa\fR.
+If \fIcommand\fR does not refer to an imported command,
+the command's own fully-qualified name is returned.
+.TP
+\fBnamespace parent\fR ?\fInamespace\fR?
+.
+Returns the fully-qualified name of the parent namespace
+for namespace \fInamespace\fR.
+If \fInamespace\fR is not specified,
+the fully-qualified name of the current namespace's parent is returned.
+.TP
+\fBnamespace path\fR ?\fInamespaceList\fR?
+.
+Returns the command resolution path of the current namespace. If
+\fInamespaceList\fR is specified as a list of named namespaces, the
+current namespace's command resolution path is set to those namespaces
+and returns the empty list. The default command resolution path is
+always empty. See the section \fBNAME RESOLUTION\fR below for an
+explanation of the rules regarding name resolution.
+.TP
+\fBnamespace qualifiers\fR \fIstring\fR
+.
+Returns any leading namespace qualifiers for \fIstring\fR.
+Qualifiers are namespace names separated by double colons (\fB::\fR).
+For the \fIstring\fR \fB::foo::bar::x\fR,
+this command returns \fB::foo::bar\fR,
+and for \fB::\fR it returns an empty string.
+This command is the complement of the \fBnamespace tail\fR command.
+Note that it does not check whether the
+namespace names are, in fact,
+the names of currently defined namespaces.
+.TP
+\fBnamespace tail\fR \fIstring\fR
+.
+Returns the simple name at the end of a qualified string.
+Qualifiers are namespace names separated by double colons (\fB::\fR).
+For the \fIstring\fR \fB::foo::bar::x\fR,
+this command returns \fBx\fR,
+and for \fB::\fR it returns an empty string.
+This command is the complement of the \fBnamespace qualifiers\fR command.
+It does not check whether the namespace names are, in fact,
+the names of currently defined namespaces.
+.TP
+\fBnamespace upvar\fR \fInamespace\fR ?\fIotherVar myVar \fR...?
+.
+This command arranges for zero or more local variables in the current
+procedure to refer to variables in \fInamespace\fR. The namespace name is
+resolved as described in section \fBNAME RESOLUTION\fR.
+The command
+\fBnamespace upvar $ns a b\fR has the same behaviour as
+\fBupvar 0 ${ns}::a b\fR, with the sole exception of the resolution rules
+used for qualified namespace or variable names.
+\fBnamespace upvar\fR returns an empty string.
+.TP
+\fBnamespace unknown\fR ?\fIscript\fR?
+.
+Sets or returns the unknown command handler for the current namespace.
+The handler is invoked when a command called from within the namespace
+cannot be found in the current namespace, the namespace's path nor in
+the global namespace. 
+The \fIscript\fR argument, if given, should be a well
+formed list representing a command name and optional arguments. When
+the handler is invoked, the full invocation line will be appended to the
+script and the result evaluated in the context of the namespace. The
+default handler for all namespaces is \fB::unknown\fR. If no argument
+is given, it returns the handler for the current namespace.
+.TP
+\fBnamespace which\fR ?\fB\-command\fR? ?\fB\-variable\fR? \fIname\fR
+.
+Looks up \fIname\fR as either a command or variable
+and returns its fully-qualified name.
+For example, if \fIname\fR does not exist in the current namespace
+but does exist in the global namespace,
+this command returns a fully-qualified name in the global namespace.
+If the command or variable does not exist,
+this command returns an empty string.  If the variable has been
+created but not defined, such as with the \fBvariable\fR command
+or through a \fBtrace\fR on the variable, this command will return the
+fully-qualified name of the variable.
+If no flag is given, \fIname\fR is treated as a command name.
+See the section \fBNAME RESOLUTION\fR below for an explanation of
+the rules regarding name resolution.
+.SH "WHAT IS A NAMESPACE?"
+.PP
+A namespace is a collection of commands and variables.
+It encapsulates the commands and variables to ensure that they
+will not interfere with the commands and variables of other namespaces.
+Tcl has always had one such collection,
+which we refer to as the \fIglobal namespace\fR.
+The global namespace holds all global variables and commands.
+The \fBnamespace eval\fR command lets you create new namespaces.
+For example,
+.PP
+.CS
+\fBnamespace eval\fR Counter {
+    \fBnamespace export\fR bump
+    variable num 0
+
+    proc bump {} {
+        variable num
+        incr num
+    }
+}
+.CE
+.PP
+creates a new namespace containing the variable \fBnum\fR and
+the procedure \fBbump\fR.
+The commands and variables in this namespace are separate from
+other commands and variables in the same program.
+If there is a command named \fBbump\fR in the global namespace,
+for example, it will be different from the command \fBbump\fR
+in the \fBCounter\fR namespace.
+.PP
+Namespace variables resemble global variables in Tcl.
+They exist outside of the procedures in a namespace
+but can be accessed in a procedure via the \fBvariable\fR command,
+as shown in the example above.
+.PP
+Namespaces are dynamic.
+You can add and delete commands and variables at any time,
+so you can build up the contents of a
+namespace over time using a series of \fBnamespace eval\fR commands.
+For example, the following series of commands has the same effect
+as the namespace definition shown above:
+.PP
+.CS
+\fBnamespace eval\fR Counter {
+    variable num 0
+    proc bump {} {
+        variable num
+        return [incr num]
+    }
+}
+\fBnamespace eval\fR Counter {
+    proc test {args} {
+        return $args
+    }
+}
+\fBnamespace eval\fR Counter {
+     rename test ""
+}
+.CE
+.PP
+Note that the \fBtest\fR procedure is added to the \fBCounter\fR namespace,
+and later removed via the \fBrename\fR command.
+.PP
+Namespaces can have other namespaces within them,
+so they nest hierarchically.
+A nested namespace is encapsulated inside its parent namespace
+and can not interfere with other namespaces.
+.SH "QUALIFIED NAMES"
+.PP
+Each namespace has a textual name such as
+\fBhistory\fR or \fB::safe::interp\fR.
+Since namespaces may nest,
+qualified names are used to refer to
+commands, variables, and child namespaces contained inside namespaces.
+Qualified names are similar to the hierarchical path names for
+Unix files or Tk widgets,
+except that \fB::\fR is used as the separator
+instead of \fB/\fR or \fB.\fR.
+The topmost or global namespace has the name
+.MT
+(i.e., an empty string), although \fB::\fR is a synonym.
+As an example, the name \fB::safe::interp::create\fR
+refers to the command \fBcreate\fR in the namespace \fBinterp\fR
+that is a child of namespace \fB::safe\fR,
+which in turn is a child of the global namespace, \fB::\fR.
+.PP
+If you want to access commands and variables from another namespace,
+you must use some extra syntax.
+Names must be qualified by the namespace that contains them.
+From the global namespace,
+we might access the \fBCounter\fR procedures like this:
+.PP
+.CS
+Counter::bump 5
+Counter::Reset
+.CE
+.PP
+We could access the current count like this:
+.PP
+.CS
+puts "count = $Counter::num"
+.CE
+.PP
+When one namespace contains another, you may need more than one
+qualifier to reach its elements.
+If we had a namespace \fBFoo\fR that contained the namespace \fBCounter\fR,
+you could invoke its \fBbump\fR procedure
+from the global namespace like this:
+.PP
+.CS
+Foo::Counter::bump 3
+.CE
+.PP
+You can also use qualified names when you create and rename commands.
+For example, you could add a procedure to the \fBFoo\fR
+namespace like this:
+.PP
+.CS
+proc Foo::Test {args} {return $args}
+.CE
+.PP
+And you could move the same procedure to another namespace like this:
+.PP
+.CS
+rename Foo::Test Bar::Test
+.CE
+.PP
+There are a few remaining points about qualified names
+that we should cover.
+Namespaces have nonempty names except for the global namespace.
+\fB::\fR is disallowed in simple command, variable, and namespace names
+except as a namespace separator.
+Extra colons in any separator part of a qualified name are ignored;
+i.e. two or more colons are treated as a namespace separator.
+A trailing \fB::\fR in a qualified variable or command name
+refers to the variable or command named {}.
+However, a trailing \fB::\fR in a qualified namespace name is ignored.
+.SH "NAME RESOLUTION"
+.PP
+In general, all Tcl commands that take variable and command names
+support qualified names.
+This means you can give qualified names to such commands as
+\fBset\fR, \fBproc\fR, \fBrename\fR, and \fBinterp alias\fR.
+If you provide a fully-qualified name that starts with a \fB::\fR,
+there is no question about what command, variable, or namespace
+you mean.
+However, if the name does not start with a \fB::\fR
+(i.e., is \fIrelative\fR),
+Tcl follows basic rules for looking it up:
+.IP \(bu
+\fBVariable names\fR are always resolved by looking first in the current
+namespace, and then in the global namespace.
+.IP \(bu
+\fBCommand names\fR are always resolved by looking in the current namespace
+first. If not found there, they are searched for in every namespace on the
+current namespace's command path (which is empty by default). If not found
+there, command names are looked up in the global namespace (or, failing that,
+are processed by the appropriate \fBnamespace unknown\fR handler.)
+.IP \(bu
+\fBNamespace names\fR are always resolved by looking in only the current
+namespace.
+.PP
+In the following example,
+.PP
+.CS
+set traceLevel 0
+\fBnamespace eval\fR Debug {
+    printTrace $traceLevel
+}
+.CE
+.PP
+Tcl looks for \fBtraceLevel\fR in the namespace \fBDebug\fR
+and then in the global namespace.
+It looks up the command \fBprintTrace\fR in the same way.
+If a variable or command name is not found in either context,
+the name is undefined.
+To make this point absolutely clear, consider the following example:
+.PP
+.CS
+set traceLevel 0
+\fBnamespace eval\fR Foo {
+    variable traceLevel 3
+
+    \fBnamespace eval\fR Debug {
+        printTrace $traceLevel
+    }
+}
+.CE
+.PP
+Here Tcl looks for \fBtraceLevel\fR first in the namespace \fBFoo::Debug\fR.
+Since it is not found there, Tcl then looks for it
+in the global namespace.
+The variable \fBFoo::traceLevel\fR is completely ignored
+during the name resolution process.
+.PP
+You can use the \fBnamespace which\fR command to clear up any question
+about name resolution.
+For example, the command:
+.PP
+.CS
+\fBnamespace eval\fR Foo::Debug {\fBnamespace which\fR \-variable traceLevel}
+.CE
+.PP
+returns \fB::traceLevel\fR.
+On the other hand, the command,
+.PP
+.CS
+\fBnamespace eval\fR Foo {\fBnamespace which\fR \-variable traceLevel}
+.CE
+.PP
+returns \fB::Foo::traceLevel\fR.
+.PP
+As mentioned above,
+namespace names are looked up differently
+than the names of variables and commands.
+Namespace names are always resolved in the current namespace.
+This means, for example,
+that a \fBnamespace eval\fR command that creates a new namespace
+always creates a child of the current namespace
+unless the new namespace name begins with \fB::\fR.
+.PP
+Tcl has no access control to limit what variables, commands,
+or namespaces you can reference.
+If you provide a qualified name that resolves to an element
+by the name resolution rule above,
+you can access the element.
+.PP
+You can access a namespace variable
+from a procedure in the same namespace
+by using the \fBvariable\fR command.
+Much like the \fBglobal\fR command,
+this creates a local link to the namespace variable.
+If necessary, it also creates the variable in the current namespace
+and initializes it.
+Note that the \fBglobal\fR command only creates links
+to variables in the global namespace.
+It is not necessary to use a \fBvariable\fR command
+if you always refer to the namespace variable using an
+appropriate qualified name.
+.SH "IMPORTING COMMANDS"
+.PP
+Namespaces are often used to represent libraries.
+Some library commands are used so frequently
+that it is a nuisance to type their qualified names.
+For example, suppose that all of the commands in a package
+like BLT are contained in a namespace called \fBBlt\fR.
+Then you might access these commands like this:
+.PP
+.CS
+Blt::graph .g \-background red
+Blt::table . .g 0,0
+.CE
+.PP
+If you use the \fBgraph\fR and \fBtable\fR commands frequently,
+you may want to access them without the \fBBlt::\fR prefix.
+You can do this by importing the commands into the current namespace,
+like this:
+.PP
+.CS
+\fBnamespace import\fR Blt::*
+.CE
+.PP
+This adds all exported commands from the \fBBlt\fR namespace
+into the current namespace context, so you can write code like this:
+.PP
+.CS
+graph .g \-background red
+table . .g 0,0
+.CE
+.PP
+The \fBnamespace import\fR command only imports commands
+from a namespace that that namespace exported
+with a \fBnamespace export\fR command.
+.PP
+Importing \fIevery\fR command from a namespace is generally
+a bad idea since you do not know what you will get.
+It is better to import just the specific commands you need.
+For example, the command
+.PP
+.CS
+\fBnamespace import\fR Blt::graph Blt::table
+.CE
+.PP
+imports only the \fBgraph\fR and \fBtable\fR commands into the
+current context.
+.PP
+If you try to import a command that already exists, you will get an
+error.  This prevents you from importing the same command from two
+different packages.  But from time to time (perhaps when debugging),
+you may want to get around this restriction.  You may want to
+reissue the \fBnamespace import\fR command to pick up new commands
+that have appeared in a namespace.  In that case, you can use the
+\fB\-force\fR option, and existing commands will be silently overwritten:
+.PP
+.CS
+\fBnamespace import\fR \-force Blt::graph Blt::table
+.CE
+.PP
+If for some reason, you want to stop using the imported commands,
+you can remove them with a \fBnamespace forget\fR command, like this:
+.PP
+.CS
+\fBnamespace forget\fR Blt::*
+.CE
+.PP
+This searches the current namespace for any commands imported from \fBBlt\fR.
+If it finds any, it removes them.  Otherwise, it does nothing.
+After this, the \fBBlt\fR commands must be accessed with the \fBBlt::\fR
+prefix.
+.PP
+When you delete a command from the exporting namespace like this:
+.PP
+.CS
+rename Blt::graph ""
+.CE
+.PP
+the command is automatically removed from all namespaces that import it.
+.SH "EXPORTING COMMANDS"
+You can export commands from a namespace like this:
+.PP
+.CS
+\fBnamespace eval\fR Counter {
+    \fBnamespace export\fR bump reset
+    variable Num 0
+    variable Max 100
+
+    proc bump {{by 1}} {
+        variable Num
+        incr Num $by
+        Check
+        return $Num
+    }
+    proc reset {} {
+        variable Num
+        set Num 0
+    }
+    proc Check {} {
+        variable Num
+        variable Max
+        if {$Num > $Max} {
+            error "too high!"
+        }
+    }
+}
+.CE
+.PP
+The procedures \fBbump\fR and \fBreset\fR are exported,
+so they are included when you import from the \fBCounter\fR namespace,
+like this:
+.PP
+.CS
+\fBnamespace import\fR Counter::*
+.CE
+.PP
+However, the \fBCheck\fR procedure is not exported,
+so it is ignored by the import operation.
+.PP
+The \fBnamespace import\fR command only imports commands
+that were declared as exported by their namespace.
+The \fBnamespace export\fR command specifies what commands
+may be imported by other namespaces.
+If a \fBnamespace import\fR command specifies a command
+that is not exported, the command is not imported.
+.SH "SCOPED SCRIPTS"
+.PP
+The \fBnamespace code\fR command is the means by which a script may be
+packaged for evaluation in a namespace other than the one in which it
+was created.  It is used most often to create event handlers, Tk bindings,
+and traces for evaluation in the global context.  For instance, the following
+code indicates how to direct a variable \fBtrace\fR callback into the current
+namespace:
+.PP
+.CS
+\fBnamespace eval\fR a {
+    variable b
+    proc theTraceCallback { n1 n2 op } {
+        upvar 1 $n1 var
+        puts "the value of $n1 has changed to $var"
+        return
+    }
+    trace add variable b write [\fBnamespace code\fR theTraceCallback]
+}
+set a::b c
+.CE
+.PP
+When executed, it prints the message:
+.PP
+.CS
+the value of a::b has changed to c
+.CE
+.SH ENSEMBLES
+.PP
+The \fBnamespace ensemble\fR is used to create and manipulate ensemble
+commands, which are commands formed by grouping subcommands together.
+The commands typically come from the current namespace when the
+ensemble was created, though this is configurable.  Note that there
+may be any number of ensembles associated with any namespace
+(including none, which is true of all namespaces by default), though
+all the ensembles associated with a namespace are deleted when that
+namespace is deleted.  The link between an ensemble command and its
+namespace is maintained however the ensemble is renamed.
+.PP
+Three subcommands of the \fBnamespace ensemble\fR command are defined:
+.TP
+\fBnamespace ensemble create\fR ?\fIoption value ...\fR?
+.
+Creates a new ensemble command linked to the current namespace,
+returning the fully qualified name of the command created.  The
+arguments to \fBnamespace ensemble create\fR allow the configuration
+of the command as if with the \fBnamespace ensemble configure\fR
+command.  If not overridden with the \fB\-command\fR option, this
+command creates an ensemble with exactly the same name as the linked
+namespace.  See the section \fBENSEMBLE OPTIONS\fR below for a full
+list of options supported and their effects.
+.TP
+\fBnamespace ensemble configure \fIcommand\fR ?\fIoption\fR? ?\fIvalue ...\fR?
+.
+Retrieves the value of an option associated with the ensemble command
+named \fIcommand\fR, or updates some options associated with that
+ensemble command.  See the section \fBENSEMBLE OPTIONS\fR below for a
+full list of options supported and their effects.
+.TP
+\fBnamespace ensemble exists\fR \fIcommand\fR
+.
+Returns a boolean value that describes whether the command
+\fIcommand\fR exists and is an ensemble command.  This command only
+ever returns an error if the number of arguments to the command is
+wrong.
+.PP
+When called, an ensemble command takes its first argument and looks it
+up (according to the rules described below) to discover a list of
+words to replace the ensemble command and subcommand with.  The
+resulting list of words is then evaluated (with no further
+substitutions) as if that was what was typed originally (i.e. by
+passing the list of words through \fBTcl_EvalObjv\fR) and returning
+the result of the command.  Note that it is legal to make the target
+of an ensemble rewrite be another (or even the same) ensemble
+command.  The ensemble command will not be visible through the use of
+the \fBuplevel\fR or \fBinfo level\fR commands.
+.SS "ENSEMBLE OPTIONS"
+.PP
+The following options, supported by the \fBnamespace ensemble
+create\fR and \fBnamespace ensemble configure\fR commands, control how
+an ensemble command behaves:
+.TP
+\fB\-map\fR
+.
+When non-empty, this option supplies a dictionary that provides a
+mapping from subcommand names to a list of prefix words to substitute
+in place of the ensemble command and subcommand words (in a manner
+similar to an alias created with \fBinterp alias\fR; the words are not
+reparsed after substitution); if the first word of any target is not
+fully qualified when set, it is assumed to be relative to the
+\fIcurrent\fR namespace and changed to be exactly that (that is, it is
+always fully qualified when read). When this option is empty, the mapping
+will be from the local name of the subcommand to its fully-qualified
+name.  Note that when this option is non-empty and the
+\fB\-subcommands\fR option is empty, the ensemble subcommand names
+will be exactly those words that have mappings in the dictionary.
+.TP
+\fB\-parameters\fR
+.VS 8.6
+This option gives a list of named arguments (the names being used during
+generation of error messages) that are passed by the caller of the ensemble
+between the name of the ensemble and the subcommand argument. By default, it
+is the empty list.
+.VE 8.6
+.TP
+\fB\-prefixes\fR
+.
+This option (which is enabled by default) controls whether the
+ensemble command recognizes unambiguous prefixes of its subcommands.
+When turned off, the ensemble command requires exact matching of
+subcommand names.
+.TP
+\fB\-subcommands\fR
+.
+When non-empty, this option lists exactly what subcommands are in the
+ensemble.  The mapping for each of those commands will be either whatever
+is defined in the \fB\-map\fR option, or to the command with the same
+name in the namespace linked to the ensemble.  If this option is
+empty, the subcommands of the namespace will either be the keys of the
+dictionary listed in the \fB\-map\fR option or the exported commands
+of the linked namespace at the time of the invocation of the ensemble
+command.
+.TP
+\fB\-unknown\fR
+.
+When non-empty, this option provides a partial command (to which all
+the words that are arguments to the ensemble command, including the
+fully-qualified name of the ensemble, are appended) to handle the case
+where an ensemble subcommand is not recognized and would otherwise
+generate an error.  When empty (the default) an error (in the style of
+\fBTcl_GetIndexFromObj\fR) is generated whenever the ensemble is
+unable to determine how to implement a particular subcommand.  See
+\fBUNKNOWN HANDLER BEHAVIOUR\fR for more details.
+.PP
+The following extra option is allowed by \fBnamespace ensemble
+create\fR:
+.TP
+\fB\-command\fR
+.
+This write-only option allows the name of the ensemble created by
+\fBnamespace ensemble create\fR to be anything in any existing
+namespace.  The default value for this option is the fully-qualified
+name of the namespace in which the \fBnamespace ensemble create\fR
+command is invoked.
+.PP
+The following extra option is allowed by \fBnamespace ensemble
+configure\fR:
+.TP
+\fB\-namespace\fR
+.
+This read-only option allows the retrieval of the fully-qualified name
+of the namespace which the ensemble was created within.
+.SS "UNKNOWN HANDLER BEHAVIOUR"
+.PP
+If an unknown handler is specified for an ensemble, that handler is
+called when the ensemble command would otherwise return an error due
+to it being unable to decide which subcommand to invoke. The exact
+conditions under which that occurs are controlled by the
+\fB\-subcommands\fR, \fB\-map\fR and \fB\-prefixes\fR options as
+described above.
+.PP
+To execute the unknown handler, the ensemble mechanism takes the
+specified \fB\-unknown\fR option and appends each argument of the
+attempted ensemble command invocation (including the ensemble command
+itself, expressed as a fully qualified name). It invokes the resulting
+command in the scope of the attempted call. If the execution of the
+unknown handler terminates normally, the ensemble engine reparses the
+subcommand (as described below) and tries to dispatch it again, which
+is ideal for when the ensemble's configuration has been updated by the
+unknown subcommand handler. Any other kind of termination of the
+unknown handler is treated as an error.
+.PP
+The result of the unknown handler is expected to be a list (it is an
+error if it is not). If the list is an empty list, the ensemble
+command attempts to look up the original subcommand again and, if it
+is not found this time, an error will be generated just as if the
+\fB\-unknown\fR handler was not there (i.e. for any particular
+invocation of an ensemble, its unknown handler will be called at most
+once.) This makes it easy for the unknown handler to update the
+ensemble or its backing namespace so as to provide an implementation
+of the desired subcommand and reparse.
+.PP
+When the result is a non-empty list, the words of that list are used
+to replace the ensemble command and subcommand, just as if they had
+been looked up in the \fB\-map\fR. It is up to the unknown handler to
+supply all namespace qualifiers if the implementing subcommand is not
+in the namespace of the caller of the ensemble command. Also note that
+when ensemble commands are chained (e.g. if you make one of the
+commands that implement an ensemble subcommand into an ensemble, in a
+manner similar to the \fBtext\fR widget's tag and mark subcommands) then the
+rewrite happens in the context of the caller of the outermost
+ensemble. That is to say that ensembles do not in themselves place any
+namespace contexts on the Tcl call stack.
+.PP
+Where an empty \fB\-unknown\fR handler is given (the default), the
+ensemble command will generate an error message based on the list of
+commands that the ensemble has defined (formatted similarly to the
+error message from \fBTcl_GetIndexFromObj\fR). This is the error that
+will be thrown when the subcommand is still not recognized during
+reparsing. It is also an error for an \fB\-unknown\fR handler to
+delete its namespace.
+.SH EXAMPLES
+Create a namespace containing a variable and an exported command:
+.PP
+.CS
+\fBnamespace eval\fR foo {
+    variable bar 0
+    proc grill {} {
+        variable bar
+        puts "called [incr bar] times"
+    }
+    \fBnamespace export\fR grill
+}
+.CE
+.PP
+Call the command defined in the previous example in various ways.
+.PP
+.CS
+# Direct call
+::foo::grill
+
+# Use the command resolution path to find the name
+\fBnamespace eval\fR boo {
+    \fBnamespace path\fR ::foo
+    grill
+}
+
+# Import into current namespace, then call local alias
+\fBnamespace import\fR foo::grill
+grill
+
+# Create two ensembles, one with the default name and one with a
+# specified name.  Then call through the ensembles.
+\fBnamespace eval\fR foo {
+    \fBnamespace ensemble\fR create
+    \fBnamespace ensemble\fR create -command ::foobar
+}
+foo grill
+foobar grill
+.CE
+.PP
+Look up where the command imported in the previous example came from:
+.PP
+.CS
+puts "grill came from [\fBnamespace origin\fR grill]"
+.CE
+.PP
+Remove all imported commands from the current namespace:
+.PP
+.CS
+namespace forget {*}[namespace import]
+.CE
+.PP
+.VS 8.6
+Create an ensemble for simple working with numbers, using the
+\fB\-parameters\fR option to allow the operator to be put between the first
+and second arguments.
+.PP
+.CS
+\fBnamespace eval\fR do {
+    \fBnamespace export\fR *
+    \fBnamespace ensemble\fR create -parameters x
+    proc plus  {x y} {expr { $x + $y }}
+    proc minus {x y} {expr { $x - $y }}
+}
+
+# In use, the ensemble works like this:
+puts [do 1 plus [do 9 minus 7]]
+.CE
+.VE 8.6
+.SH "SEE ALSO"
+interp(n), upvar(n), variable(n)
+.SH KEYWORDS
+command, ensemble, exported, internal, variable
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/doc/next.n b/doc/next.n
new file mode 100644
index 0000000..62782e5
--- /dev/null
+++ b/doc/next.n
@@ -0,0 +1,208 @@
+'\"
+'\" Copyright (c) 2007 Donal K. Fellows
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH next n 0.1 TclOO "TclOO Commands"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+next, nextto \- invoke superclass method implementations
+.SH SYNOPSIS
+.nf
+package require TclOO
+
+\fBnext\fR ?\fIarg ...\fR?
+\fBnextto\fI class\fR ?\fIarg ...\fR?
+.fi
+.BE
+
+.SH DESCRIPTION
+.PP
+The \fBnext\fR command is used to call implementations of a method by a class,
+superclass or mixin that are overridden by the current method. It can only be
+used from within a method. It is also used within filters to indicate the
+point where a filter calls the actual implementation (the filter may decide to
+not go along the chain, and may process the results of going along the chain
+of methods as it chooses). The result of the \fBnext\fR command is the result
+of the next method in the method chain; if there are no further methods in the
+method chain, the result of \fBnext\fR will be an error. The arguments,
+\fIarg\fR, to \fBnext\fR are the arguments to pass to the next method in the
+chain.
+.PP
+The \fBnextto\fR command is the same as the \fBnext\fR command, except that it
+takes an additional \fIclass\fR argument that identifies a class whose
+implementation of the current method chain (see \fBinfo object\fR \fBcall\fR) should
+be used; the method implementation selected will be the one provided by the
+given class, and it must refer to an existing non-filter invocation that lies
+further along the chain than the current implementation.
+.SH "THE METHOD CHAIN"
+.PP
+When a method of an object is invoked, things happen in several stages:
+.IP [1]
+The structure of the object, its class, superclasses, filters, and mixins, are
+examined to build a \fImethod chain\fR, which contains a list of method
+implementations to invoke.
+.IP [2]
+The first method implementation on the chain is invoked.
+.IP [3]
+If that method implementation invokes the \fBnext\fR command, the next method
+implementation is invoked (with its arguments being those that were passed to
+\fBnext\fR).
+.IP [4]
+The result from the overall method call is the result from the outermost
+method implementation; inner method implementations return their results
+through \fBnext\fR.
+.IP [5]
+The method chain is cached for future use.
+.SS "METHOD SEARCH ORDER"
+.PP
+When constructing the method chain, method implementations are searched for in
+the following order:
+.IP [1]
+In the classes mixed into the object, in class traversal order. The list of
+mixins is checked in natural order.
+.IP [2]
+In the classes mixed into the classes of the object, with sources of mixing in
+being searched in class traversal order. Within each class, the list of mixins
+is processed in natural order.
+.IP [3]
+In the object itself.
+.IP [4]
+In the object's class.
+.IP [5]
+In the superclasses of the class, following each superclass in a depth-first
+fashion in the natural order of the superclass list.
+.PP
+Any particular method implementation always comes as \fIlate\fR in the
+resulting list of implementations as possible; this means that if some class,
+A, is both mixed into a class, B, and is also a superclass of B, the instances
+of B will always treat A as a superclass from the perspective of inheritance.
+This is true even when the multiple inheritance is processed indirectly.
+.SS FILTERS
+.PP
+When an object has a list of filter names set upon it, or is an instance of a
+class (or has mixed in a class) that has a list of filter names set upon it,
+before every invocation of any method the filters are processed. Filter
+implementations are found in class traversal order, as are the lists of filter
+names (each of which is traversed in natural list order). Explicitly invoking
+a method used as a filter will cause that method to be invoked twice, once as
+a filter and once as a normal method.
+.PP
+Each filter should decide for itself whether to permit the execution to go
+forward to the proper implementation of the method (which it does by invoking
+the \fBnext\fR command as filters are inserted into the front of the method
+call chain) and is responsible for returning the result of \fBnext\fR.
+.PP
+Filters are invoked when processing an invokation of the \fBunknown\fR
+method because of a failure to locate a method implementation, but \fInot\fR
+when invoking either constructors or destructors. (Note however that the
+\fBdestroy\fR method is a conventional method, and filters are invoked as
+normal when it is called.)
+.SH EXAMPLES
+.PP
+This example demonstrates how to use the \fBnext\fR command to call the
+(super)class's implementation of a method. The script:
+.PP
+.CS
+oo::class create theSuperclass {
+    method example {args} {
+        puts "in the superclass, args = $args"
+    }
+}
+oo::class create theSubclass {
+    superclass theSuperclass
+    method example {args} {
+        puts "before chaining from subclass, args = $args"
+        \fBnext\fR a {*}$args b
+        \fBnext\fR pureSynthesis
+        puts "after chaining from subclass"
+    }
+}
+theSubclass create obj
+oo::objdefine obj method example args {
+    puts "per-object method, args = $args"
+    \fBnext\fR x {*}$args y
+    \fBnext\fR
+}
+obj example 1 2 3
+.CE
+.PP
+prints the following:
+.PP
+.CS
+per-object method, args = 1 2 3
+before chaining from subclass, args = x 1 2 3 y
+in the superclass, args = a x 1 2 3 y b
+in the superclass, args = pureSynthesis
+after chaining from subclass
+before chaining from subclass, args = 
+in the superclass, args = a b
+in the superclass, args = pureSynthesis
+after chaining from subclass
+.CE
+.PP
+This example demonstrates how to build a simple cache class that applies
+memoization to all the method calls of the objects it is mixed into, and shows
+how it can make a difference to computation times:
+.PP
+.CS
+oo::class create cache {
+    filter Memoize
+    method Memoize args {
+        \fI# Do not filter the core method implementations\fR
+        if {[lindex [self target] 0] eq "::oo::object"} {
+            return [\fBnext\fR {*}$args]
+        }
+
+        \fI# Check if the value is already in the cache\fR
+        my variable ValueCache
+        set key [self target],$args
+        if {[info exist ValueCache($key)]} {
+            return $ValueCache($key)
+        }
+
+        \fI# Compute value, insert into cache, and return it\fR
+        return [set ValueCache($key) [\fBnext\fR {*}$args]]
+    }
+    method flushCache {} {
+        my variable ValueCache
+        unset ValueCache
+        \fI# Skip the caching\fR
+        return -level 2 ""
+    }
+}
+
+oo::object create demo
+oo::objdefine demo {
+    mixin cache
+    method compute {a b c} {
+        after 3000 \fI;# Simulate deep thought\fR
+        return [expr {$a + $b * $c}]
+    }
+    method compute2 {a b c} {
+        after 3000 \fI;# Simulate deep thought\fR
+        return [expr {$a * $b + $c}]
+    }
+}
+
+puts [demo compute  1 2 3]      \fI\(-> prints "7" after delay\fR
+puts [demo compute2 4 5 6]      \fI\(-> prints "26" after delay\fR
+puts [demo compute  1 2 3]      \fI\(-> prints "7" instantly\fR
+puts [demo compute2 4 5 6]      \fI\(-> prints "26" instantly\fR
+puts [demo compute  4 5 6]      \fI\(-> prints "34" after delay\fR
+puts [demo compute  4 5 6]      \fI\(-> prints "34" instantly\fR
+puts [demo compute  1 2 3]      \fI\(-> prints "7" instantly\fR
+demo flushCache
+puts [demo compute  1 2 3]      \fI\(-> prints "7" after delay\fR
+.CE
+.SH "SEE ALSO"
+oo::class(n), oo::define(n), oo::object(n), self(n)
+.SH KEYWORDS
+call, method, method chain
+.\" Local variables:
+.\" mode: nroff
+.\" fill-column: 78
+.\" End:
diff --git a/doc/object.n b/doc/object.n
new file mode 100644
index 0000000..df657a9
--- /dev/null
+++ b/doc/object.n
@@ -0,0 +1,128 @@
+'\"
+'\" Copyright (c) 2007-2008 Donal K. Fellows
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH object n 0.1 TclOO "TclOO Commands"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+oo::object \- root class of the class hierarchy
+.SH SYNOPSIS
+.nf
+package require TclOO
+
+\fBoo::object\fI method \fR?\fIarg ...\fR?
+.fi
+.SH "CLASS HIERARCHY"
+.nf
+\fBoo::object\fR
+.fi
+.BE
+.SH DESCRIPTION
+.PP
+The \fBoo::object\fR class is the root class of the object hierarchy; every
+object is an instance of this class. Since classes are themselves objects,
+they are instances of this class too. Objects are always referred to by their
+name, and may be \fBrename\fRd while maintaining their identity.
+.PP
+Instances of objects may be made with either the \fBcreate\fR or \fBnew\fR
+methods of the \fBoo::object\fR object itself, or by invoking those methods on
+any of the subclass objects; see \fBoo::class\fR for more details. The
+configuration of individual objects (i.e., instance-specific methods, mixed-in
+classes, etc.) may be controlled with the \fBoo::objdefine\fR command.
+.PP
+Each object has a unique namespace associated with it, the instance namespace.
+This namespace holds all the instance variables of the object, and will be the
+current namespace whenever a method of the object is invoked (including a
+method of the class of the object). When the object is destroyed, its instance
+namespace is deleted. The instance namespace contains the object's \fBmy\fR
+command, which may be used to invoke non-exported methods of the object or to
+create a reference to the object for the purpose of invocation which persists
+across renamings of the object.
+.SS CONSTRUCTOR
+The \fBoo::object\fR class does not define an explicit constructor.
+.SS DESTRUCTOR
+The \fBoo::object\fR class does not define an explicit destructor.
+.SS "EXPORTED METHODS"
+The \fBoo::object\fR class supports the following exported methods:
+.TP
+\fIobj \fBdestroy\fR
+.
+This method destroys the object, \fIobj\fR, that it is invoked upon, invoking
+any destructors on the object's class in the process. It is equivalent to
+using \fBrename\fR to delete the object command. The result of this method is
+always the empty string.
+.SS "NON-EXPORTED METHODS"
+.PP
+The \fBoo::object\fR class supports the following non-exported methods:
+.TP
+\fIobj \fBeval\fR ?\fIarg ...\fR?
+.
+This method concatenates the arguments, \fIarg\fR, as if with \fBconcat\fR,
+and then evaluates the resulting script in the namespace that is uniquely
+associated with \fIobj\fR, returning the result of the evaluation.
+.TP
+\fIobj \fBunknown ?\fImethodName\fR? ?\fIarg ...\fR?
+.
+This method is called when an attempt to invoke the method \fImethodName\fR on
+object \fIobj\fR fails. The arguments that the user supplied to the method are
+given as \fIarg\fR arguments.
+.VS
+If \fImethodName\fR is absent, the object was invoked with no method name at
+all (or any other arguments).
+.VE
+The default implementation (i.e., the one defined by the \fBoo::object\fR
+class) generates a suitable error, detailing what methods the object supports
+given whether the object was invoked by its public name or through the
+\fBmy\fR command.
+.TP
+\fIobj \fBvariable \fR?\fIvarName ...\fR?
+.
+This method arranges for each variable called \fIvarName\fR to be linked from
+the object \fIobj\fR's unique namespace into the caller's context. Thus, if it
+is invoked from inside a procedure then the namespace variable in the object
+is linked to the local variable in the procedure. Each \fIvarName\fR argument
+must not have any namespace separators in it. The result is the empty string.
+.TP
+\fIobj \fBvarname \fIvarName\fR
+.
+This method returns the globally qualified name of the variable \fIvarName\fR
+in the unique namespace for the object \fIobj\fR.
+.TP
+\fIobj \fB<cloned> \fIsourceObjectName\fR
+.VS
+This method is used by the \fBoo::object\fR command to copy the state of one
+object to another. It is responsible for copying the procedures and variables
+of the namespace of the source object (\fIsourceObjectName\fR) to the current
+object. It does not copy any other types of commands or any traces on the
+variables; that can be added if desired by overriding this method in a
+subclass.
+.VE
+.SH EXAMPLES
+.PP
+This example demonstrates basic use of an object.
+.PP
+.CS
+set obj [\fBoo::object\fR new]
+$obj foo             \fI\(-> error "unknown method foo"\fR
+oo::objdefine $obj method foo {} {
+    my \fBvariable\fR count
+    puts "bar[incr count]"
+}
+$obj foo             \fI\(-> prints "bar1"\fR
+$obj foo             \fI\(-> prints "bar2"\fR
+$obj variable count  \fI\(-> error "unknown method variable"\fR
+$obj \fBdestroy\fR
+$obj foo             \fI\(-> error "unknown command obj"\fR
+.CE
+.SH "SEE ALSO"
+my(n), oo::class(n)
+.SH KEYWORDS
+base class, class, object, root class
+.\" Local variables:
+.\" mode: nroff
+.\" fill-column: 78
+.\" End:
diff --git a/doc/open.n b/doc/open.n
new file mode 100644
index 0000000..1cccc0a
--- /dev/null
+++ b/doc/open.n
@@ -0,0 +1,430 @@
+'\"
+'\" Copyright (c) 1993 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH open n 8.3 Tcl "Tcl Built-In Commands"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+open \- Open a file-based or command pipeline channel
+.SH SYNOPSIS
+.sp
+\fBopen \fIfileName\fR
+.br
+\fBopen \fIfileName access\fR
+.br
+\fBopen \fIfileName access permissions\fR
+.BE
+.SH DESCRIPTION
+.PP
+This command opens a file, serial port, or command pipeline and returns a
+channel identifier that may be used in future invocations of commands like
+\fBread\fR, \fBputs\fR, and \fBclose\fR.
+If the first character of \fIfileName\fR is not \fB|\fR then
+the command opens a file:
+\fIfileName\fR gives the name of the file to open, and it must conform to the
+conventions described in the \fBfilename\fR manual entry.
+.PP
+The \fIaccess\fR argument, if present, indicates the way in which the file
+(or command pipeline) is to be accessed.
+In the first form \fIaccess\fR may have any of the following values:
+.TP 15
+\fBr\fR
+.
+Open the file for reading only; the file must already exist. This is the
+default value if \fIaccess\fR is not specified.
+.TP 15
+\fBr+\fR
+.
+Open the file for both reading and writing; the file must
+already exist.
+.TP 15
+\fBw\fR
+.
+Open the file for writing only.  Truncate it if it exists.  If it does not
+exist, create a new file.
+.TP 15
+\fBw+\fR
+.
+Open the file for reading and writing.  Truncate it if it exists.
+If it does not exist, create a new file.
+.TP 15
+\fBa\fR
+.
+Open the file for writing only.  If the file does not exist,
+create a new empty file.
+Set the file pointer to the end of the file prior to each write.
+.TP 15
+\fBa+\fR
+.
+Open the file for reading and writing.  If the file does not exist,
+create a new empty file.
+Set the initial access position  to the end of the file.
+.PP
+All of the legal \fIaccess\fR values above may have the character
+\fBb\fR added as the second or third character in the value to
+indicate that the opened channel should be configured as if with the
+\fBfconfigure\fR \fB\-translation binary\fR option, making the channel suitable for
+reading or writing of binary data.
+.PP
+In the second form, \fIaccess\fR consists of a list of any of the
+following flags, all of which have the standard POSIX meanings.
+One of the flags must be either \fBRDONLY\fR, \fBWRONLY\fR or \fBRDWR\fR.
+.TP 15
+\fBRDONLY\fR
+.
+Open the file for reading only.
+.TP 15
+\fBWRONLY\fR
+.
+Open the file for writing only.
+.TP 15
+\fBRDWR\fR
+.
+Open the file for both reading and writing.
+.TP 15
+\fBAPPEND\fR
+.
+Set the file pointer to the end of the file prior to each write.
+.TP 15
+\fBBINARY\fR
+.
+Configure the opened channel with the \fB\-translation binary\fR option.
+.TP 15
+\fBCREAT\fR
+.
+Create the file if it does not already exist (without this flag it
+is an error for the file not to exist).
+.TP 15
+\fBEXCL\fR
+.
+If \fBCREAT\fR is also specified, an error is returned if the
+file already exists.
+.TP 15
+\fBNOCTTY\fR
+.
+If the file is a terminal device, this flag prevents the file from
+becoming the controlling terminal of the process.
+.TP 15
+\fBNONBLOCK\fR
+.
+Prevents the process from blocking while opening the file, and
+possibly in subsequent I/O operations.  The exact behavior of
+this flag is system- and device-dependent;  its use is discouraged
+(it is better to use the \fBfconfigure\fR command to put a file
+in nonblocking mode).
+For details refer to your system documentation on the \fBopen\fR system
+call's \fBO_NONBLOCK\fR flag.
+.TP 15
+\fBTRUNC\fR
+.
+If the file exists it is truncated to zero length.
+.PP
+If a new file is created as part of opening it, \fIpermissions\fR
+(an integer) is used to set the permissions for the new file in
+conjunction with the process's file mode creation mask.
+\fIPermissions\fR defaults to 0666.
+.SH "COMMAND PIPELINES"
+.PP
+If the first character of \fIfileName\fR is
+.QW \fB|\fR
+then the
+remaining characters of \fIfileName\fR are treated as a list of arguments
+that describe a command pipeline to invoke, in the same style as the
+arguments for \fBexec\fR.
+In this case, the channel identifier returned by \fBopen\fR may be used
+to write to the command's input pipe or read from its output pipe,
+depending on the value of \fIaccess\fR.
+If write-only access is used (e.g. \fIaccess\fR is
+.QW \fBw\fR ),
+then standard output for the pipeline is directed to the current standard
+output unless overridden by the command.
+If read-only access is used (e.g. \fIaccess\fR is
+.QW \fBr\fR ),
+standard input for the pipeline is taken from the current standard
+input unless overridden by the command.
+The id of the spawned process is accessible through the \fBpid\fR
+command, using the channel id returned by \fBopen\fR as argument.
+.PP
+If the command (or one of the commands) executed in the command
+pipeline returns an error (according to the definition in \fBexec\fR),
+a Tcl error is generated when \fBclose\fR is called on the channel
+unless the pipeline is in non-blocking mode then no exit status is
+returned (a silent \fBclose\fR with -blocking 0).
+.PP
+It is often useful to use the \fBfileevent\fR command with pipelines
+so other processing may happen at the same time as running the command
+in the background.
+.SH "SERIAL COMMUNICATIONS"
+.PP
+If \fIfileName\fR refers to a serial port, then the specified serial port
+is opened and initialized in a platform-dependent manner.  Acceptable
+values for the \fIfileName\fR to use to open a serial port are described in
+the PORTABILITY ISSUES section.
+.PP
+The \fBfconfigure\fR command can be used to query and set additional
+configuration options specific to serial ports (where supported):
+.TP
+\fB\-mode\fR \fIbaud\fB,\fIparity\fB,\fIdata\fB,\fIstop\fR
+.
+This option is a set of 4 comma-separated values: the baud rate, parity,
+number of data bits, and number of stop bits for this serial port.  The
+\fIbaud\fR rate is a simple integer that specifies the connection speed.
+\fIParity\fR is one of the following letters: \fBn\fR, \fBo\fR, \fBe\fR,
+\fBm\fR, \fBs\fR; respectively signifying the parity options of
+.QW none ,
+.QW odd ,
+.QW even ,
+.QW mark ,
+or
+.QW space .
+\fIData\fR is the number of
+data bits and should be an integer from 5 to 8, while \fIstop\fR is the
+number of stop bits and should be the integer 1 or 2.
+.TP
+\fB\-handshake\fR \fItype\fR
+.
+(Windows and Unix). This option is used to setup automatic handshake
+control. Note that not all handshake types maybe supported by your operating
+system. The \fItype\fR parameter is case-independent.
+.RS
+.PP
+If \fItype\fR is \fBnone\fR then any handshake is switched off.
+\fBrtscts\fR activates hardware handshake. Hardware handshake signals
+are described below.
+For software handshake \fBxonxoff\fR the handshake characters can be redefined
+with \fB\-xchar\fR.
+An additional hardware handshake \fBdtrdsr\fR is available only under Windows.
+There is no default handshake configuration, the initial value depends
+on your operating system settings.
+The \fB\-handshake\fR option cannot be queried.
+.RE
+.TP
+\fB\-queue\fR
+.
+(Windows and Unix). The \fB\-queue\fR option can only be queried.
+It returns a list of two integers representing the current number
+of bytes in the input and output queue respectively.
+.TP
+\fB\-timeout\fR \fImsec\fR
+.
+(Windows and Unix). This option is used to set the timeout for blocking
+read operations. It specifies the maximum interval between the
+reception of two bytes in milliseconds.
+For Unix systems the granularity is 100 milliseconds.
+The \fB\-timeout\fR option does not affect write operations or
+nonblocking reads.
+This option cannot be queried.
+.TP
+\fB\-ttycontrol\fR \fI{signal boolean signal boolean ...}\fR
+.
+(Windows and Unix). This option is used to setup the handshake
+output lines (see below) permanently or to send a BREAK over the serial line.
+The \fIsignal\fR names are case-independent.
+\fB{RTS 1 DTR 0}\fR sets the RTS output to high and the DTR output to low.
+The BREAK condition (see below) is enabled and disabled with \fB{BREAK 1}\fR and
+\fB{BREAK 0}\fR respectively.
+It is not a good idea to change the \fBRTS\fR (or \fBDTR\fR) signal
+with active hardware handshake \fBrtscts\fR (or \fBdtrdsr\fR).
+The result is unpredictable.
+The \fB\-ttycontrol\fR option cannot be queried.
+.TP
+\fB\-ttystatus\fR
+.
+(Windows and Unix). The \fB\-ttystatus\fR option can only be
+queried.  It returns the current modem status and handshake input signals
+(see below).
+The result is a list of signal,value pairs with a fixed order,
+e.g. \fB{CTS 1 DSR 0 RING 1 DCD 0}\fR.
+The \fIsignal\fR names are returned upper case.
+.TP
+\fB\-xchar\fR \fI{xonChar xoffChar}\fR
+.
+(Windows and Unix). This option is used to query or change the software
+handshake characters. Normally the operating system default should be
+DC1 (0x11) and DC3 (0x13) representing the ASCII standard
+XON and XOFF characters.
+.TP
+\fB\-pollinterval\fR \fImsec\fR
+.
+(Windows only). This option is used to set the maximum time between
+polling for fileevents.
+This affects the time interval between checking for events throughout the Tcl
+interpreter (the smallest value always wins).  Use this option only if
+you want to poll the serial port more or less often than 10 msec
+(the default).
+.TP
+\fB\-sysbuffer\fR \fIinSize\fR
+.TP
+\fB\-sysbuffer\fR \fI{inSize outSize}\fR
+.
+(Windows only). This option is used to change the size of Windows
+system buffers for a serial channel. Especially at higher communication
+rates the default input buffer size of 4096 bytes can overrun
+for latent systems. The first form specifies the input buffer size,
+in the second form both input and output buffers are defined.
+.TP
+\fB\-lasterror\fR
+.
+(Windows only). This option is query only.
+In case of a serial communication error, \fBread\fR or \fBputs\fR
+returns a general Tcl file I/O error.
+\fBfconfigure\fR \fB\-lasterror\fR can be called to get a list of error details.
+See below for an explanation of the various error codes.
+.SH "SERIAL PORT SIGNALS"
+.PP
+RS-232 is the most commonly used standard electrical interface for serial
+communications. A negative voltage (-3V..-12V) define a mark (on=1) bit and
+a positive voltage (+3..+12V) define a space (off=0) bit (RS-232C).  The
+following signals are specified for incoming and outgoing data, status
+lines and handshaking. Here we are using the terms \fIworkstation\fR for
+your computer and \fImodem\fR for the external device, because some signal
+names (DCD, RI) come from modems. Of course your external device may use
+these signal lines for other purposes.
+.IP \fBTXD\fR(output)
+\fBTransmitted Data:\fR Outgoing serial data.
+.IP \fBRXD\fR(input)
+\fBReceived Data:\fRIncoming serial data.
+.IP \fBRTS\fR(output)
+\fBRequest To Send:\fR This hardware handshake line informs the modem that
+your workstation is ready to receive data. Your workstation may
+automatically reset this signal to indicate that the input buffer is full.
+.IP \fBCTS\fR(input)
+\fBClear To Send:\fR The complement to RTS. Indicates that the modem is
+ready to receive data.
+.IP \fBDTR\fR(output)
+\fBData Terminal Ready:\fR This signal tells the modem that the workstation
+is ready to establish a link. DTR is often enabled automatically whenever a
+serial port is opened.
+.IP \fBDSR\fR(input)
+\fBData Set Ready:\fR The complement to DTR. Tells the workstation that the
+modem is ready to establish a link.
+.IP \fBDCD\fR(input)
+\fBData Carrier Detect:\fR This line becomes active when a modem detects a
+.QW Carrier
+signal.
+.IP \fBRI\fR(input)
+\fBRing Indicator:\fR Goes active when the modem detects an incoming call.
+.IP \fBBREAK\fR
+A BREAK condition is not a hardware signal line, but a logical zero on the
+TXD or RXD lines for a long period of time, usually 250 to 500
+milliseconds.  Normally a receive or transmit data signal stays at the mark
+(on=1) voltage until the next character is transferred. A BREAK is sometimes
+used to reset the communications line or change the operating mode of
+communications hardware.
+.SH "ERROR CODES (Windows only)"
+.PP
+A lot of different errors may occur during serial read operations or during
+event polling in background. The external device may have been switched
+off, the data lines may be noisy, system buffers may overrun or your mode
+settings may be wrong.  That is why a reliable software should always
+\fBcatch\fR serial read operations.  In cases of an error Tcl returns a
+general file I/O error.  Then \fBfconfigure\fR \fB\-lasterror\fR may help to
+locate the problem.  The following error codes may be returned.
+.TP 10
+\fBRXOVER\fR
+.
+Windows input buffer overrun. The data comes faster than your scripts reads
+it or your system is overloaded. Use \fBfconfigure\fR \fB\-sysbuffer\fR to avoid a
+temporary bottleneck and/or make your script faster.
+.TP 10
+\fBTXFULL\fR
+.
+Windows output buffer overrun. Complement to RXOVER. This error should
+practically not happen, because Tcl cares about the output buffer status.
+.TP 10
+\fBOVERRUN\fR
+.
+UART buffer overrun (hardware) with data lost.
+The data comes faster than the system driver receives it.
+Check your advanced serial port settings to enable the FIFO (16550) buffer
+and/or setup a lower(1) interrupt threshold value.
+.TP 10
+\fBRXPARITY\fR
+.
+A parity error has been detected by your UART.
+Wrong parity settings with \fBfconfigure\fR \fB\-mode\fR or a noisy data line (RXD)
+may cause this error.
+.TP 10
+\fBFRAME\fR
+.
+A stop-bit error has been detected by your UART.
+Wrong mode settings with \fBfconfigure\fR \fB\-mode\fR or a noisy data line (RXD)
+may cause this error.
+.TP 10
+\fBBREAK\fR
+.
+A BREAK condition has been detected by your UART (see above).
+.SH "PORTABILITY ISSUES"
+.TP
+\fBWindows \fR
+.
+Valid values for \fIfileName\fR to open a serial port are of the form
+\fBcom\fIX\fB\fR, where \fIX\fR is a number, generally from 1 to 9.
+A legacy form accepted as well is \fBcom\fIX\fB:\fR. This notation only
+works for serial ports from 1 to 9.  An attempt to open a serial port that
+does not exist or has a number greater than 9 will fail.  An alternate
+form of opening serial ports is to use the filename \fB//./comX\fR,
+where X is any number that corresponds to a serial port.
+.PP
+.RS
+When running Tcl interactively, there may be some strange interactions
+between the real console, if one is present, and a command pipeline that uses
+standard input or output.  If a command pipeline is opened for reading, some
+of the lines entered at the console will be sent to the command pipeline and
+some will be sent to the Tcl evaluator.  If a command pipeline is opened for
+writing, keystrokes entered into the console are not visible until the
+pipe is closed.  These problems only occur because both Tcl and the child
+application are competing for the console at the same time.  If the command
+pipeline is started from a script, so that Tcl is not accessing the console,
+or if the command pipeline does not use standard input or output, but is
+redirected from or to a file, then the above problems do not occur.
+.RE
+.TP
+\fBUnix\fR\0\0\0\0\0\0\0
+.
+Valid values for \fIfileName\fR to open a serial port are generally of the
+form \fB/dev/tty\fIX\fR, where \fIX\fR is \fBa\fR or \fBb\fR, but the name
+of any pseudo-file that maps to a serial port may be used.
+Advanced configuration options are only supported for serial ports
+when Tcl is built to use the POSIX serial interface.
+.RS
+.PP
+When running Tcl interactively, there may be some strange interactions
+between the console, if one is present, and a command pipeline that uses
+standard input.  If a command pipeline is opened for reading, some
+of the lines entered at the console will be sent to the command pipeline and
+some will be sent to the Tcl evaluator.  This problem only occurs because
+both Tcl and the child application are competing for the console at the
+same time.  If the command pipeline is started from a script, so that Tcl is
+not accessing the console, or if the command pipeline does not use standard
+input, but is redirected from a file, then the above problem does not occur.
+.RE
+.PP
+See the \fBPORTABILITY ISSUES\fR section of the \fBexec\fR command for
+additional information not specific to command pipelines about executing
+applications on the various platforms
+.SH "EXAMPLE"
+.PP
+Open a command pipeline and catch any errors:
+.PP
+.CS
+set fl [\fBopen\fR "| ls this_file_does_not_exist"]
+set data [read $fl]
+if {[catch {close $fl} err]} {
+    puts "ls command failed: $err"
+}
+.CE
+.SH "SEE ALSO"
+file(n), close(n), filename(n), fconfigure(n), gets(n), read(n),
+puts(n), exec(n), pid(n), fopen(3)
+.SH KEYWORDS
+access mode, append, create, file, non-blocking, open, permissions,
+pipeline, process, serial
+'\"Local Variables:
+'\"mode: nroff
+'\"End:
diff --git a/doc/package.n b/doc/package.n
new file mode 100644
index 0000000..a6a972f
--- /dev/null
+++ b/doc/package.n
@@ -0,0 +1,370 @@
+'\"
+'\" Copyright (c) 1996 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH package n 7.5 Tcl "Tcl Built-In Commands"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+package \- Facilities for package loading and version control
+.SH SYNOPSIS
+.nf
+\fBpackage forget\fR ?\fIpackage package ...\fR?
+\fBpackage ifneeded \fIpackage version\fR ?\fIscript\fR?
+\fBpackage names\fR
+\fBpackage present \fIpackage \fR?\fIrequirement...\fR?
+\fBpackage present \-exact \fIpackage version\fR
+\fBpackage provide \fIpackage \fR?\fIversion\fR?
+\fBpackage require \fIpackage \fR?\fIrequirement...\fR?
+\fBpackage require \-exact \fIpackage version\fR
+\fBpackage unknown \fR?\fIcommand\fR?
+\fBpackage vcompare \fIversion1 version2\fR
+\fBpackage versions \fIpackage\fR
+\fBpackage vsatisfies \fIversion requirement...\fR
+\fBpackage prefer \fR?\fBlatest\fR|\fBstable\fR?
+.fi
+.BE
+.SH DESCRIPTION
+.PP
+This command keeps a simple database of the packages available for
+use by the current interpreter and how to load them into the
+interpreter.
+It supports multiple versions of each package and arranges
+for the correct version of a package to be loaded based on what
+is needed by the application.
+This command also detects and reports version clashes.
+Typically, only the \fBpackage require\fR and \fBpackage provide\fR
+commands are invoked in normal Tcl scripts;  the other commands are used
+primarily by system scripts that maintain the package database.
+.PP
+The behavior of the \fBpackage\fR command is determined by its first argument.
+The following forms are permitted:
+.TP
+\fBpackage forget\fR ?\fIpackage package ...\fR?
+.
+Removes all information about each specified package from this interpreter,
+including information provided by both \fBpackage ifneeded\fR and
+\fBpackage provide\fR.
+.TP
+\fBpackage ifneeded \fIpackage version\fR ?\fIscript\fR?
+.
+This command typically appears only in system configuration
+scripts to set up the package database.
+It indicates that a particular version of
+a particular package is available if needed, and that the package
+can be added to the interpreter by executing \fIscript\fR.
+The script is saved in a database for use by subsequent
+\fBpackage require\fR commands;  typically, \fIscript\fR
+sets up auto-loading for the commands in the package (or calls
+\fBload\fR and/or \fBsource\fR directly), then invokes
+\fBpackage provide\fR to indicate that the package is present.
+There may be information in the database for several different
+versions of a single package.
+If the database already contains information for \fIpackage\fR
+and \fIversion\fR, the new \fIscript\fR replaces the existing
+one.
+If the \fIscript\fR argument is omitted, the current script for
+version \fIversion\fR of package \fIpackage\fR is returned,
+or an empty string if no \fBpackage ifneeded\fR command has
+been invoked for this \fIpackage\fR and \fIversion\fR.
+.TP
+\fBpackage names\fR
+.
+Returns a list of the names of all packages in the
+interpreter for which a version has been provided (via
+\fBpackage provide\fR) or for which a \fBpackage ifneeded\fR
+script is available.
+The order of elements in the list is arbitrary.
+.TP
+\fBpackage present\fR ?\fB\-exact\fR? \fIpackage\fR ?\fIrequirement...\fR?
+.
+This command is equivalent to \fBpackage require\fR except that it
+does not try and load the package if it is not already loaded.
+.TP
+\fBpackage provide \fIpackage \fR?\fIversion\fR?
+.
+This command is invoked to indicate that version \fIversion\fR
+of package \fIpackage\fR is now present in the interpreter.
+It is typically invoked once as part of an \fBifneeded\fR script,
+and again by the package itself when it is finally loaded.
+An error occurs if a different version of \fIpackage\fR has been
+provided by a previous \fBpackage provide\fR command.
+If the \fIversion\fR argument is omitted, then the command
+returns the version number that is currently provided, or an
+empty string if no \fBpackage provide\fR command has been
+invoked for \fIpackage\fR in this interpreter.
+.TP
+\fBpackage require \fR\fIpackage \fR?\fIrequirement...\fR?
+.
+This command is typically invoked by Tcl code that wishes to use
+a particular version of a particular package.  The arguments
+indicate which package is wanted, and the command ensures that
+a suitable version of the package is loaded into the interpreter.
+If the command succeeds, it returns the version number that is
+loaded;  otherwise it generates an error.
+.RS
+.PP
+A suitable version of the package is any version which satisfies at
+least one of the requirements, per the rules of \fBpackage
+vsatisfies\fR. If multiple versions are suitable the implementation
+with the highest version is chosen. This last part is additionally
+influenced by the selection mode set with \fBpackage prefer\fR.
+.PP
+In the
+.QW stable
+selection mode the command will select the highest
+stable version satisfying the requirements, if any. If no stable
+version satisfies the requirements, the highest unstable version
+satisfying the requirements will be selected.  In the
+.QW latest
+selection mode the command will accept the highest version satisfying
+all the requirements, regardless of its stableness.
+.PP
+If a version of \fIpackage\fR has already been provided (by invoking
+the \fBpackage provide\fR command), then its version number must
+satisfy the \fIrequirement\fRs and the command returns immediately.
+Otherwise, the command searches the database of information provided by
+previous \fBpackage ifneeded\fR commands to see if an acceptable
+version of the package is available.
+If so, the script for the highest acceptable version number is evaluated
+in the global namespace;
+it must do whatever is necessary to load the package,
+including calling \fBpackage provide\fR for the package.
+If the \fBpackage ifneeded\fR database does not contain an acceptable
+version of the package and a \fBpackage unknown\fR command has been
+specified for the interpreter then that command is evaluated in the
+global namespace;  when
+it completes, Tcl checks again to see if the package is now provided
+or if there is a \fBpackage ifneeded\fR script for it.
+If all of these steps fail to provide an acceptable version of the
+package, then the command returns an error.
+.RE
+.TP
+\fBpackage require \-exact \fIpackage version\fR
+.
+This form of the command is used when only the given \fIversion\fR
+of \fIpackage\fR is acceptable to the caller.  This command is
+equivalent to \fBpackage require \fIpackage version\fR-\fIversion\fR.
+.TP
+\fBpackage unknown \fR?\fIcommand\fR?
+.
+This command supplies a
+.QW "last resort"
+command to invoke during
+\fBpackage require\fR if no suitable version of a package can be found
+in the \fBpackage ifneeded\fR database.
+If the \fIcommand\fR argument is supplied, it contains the first part
+of a command;  when the command is invoked during a \fBpackage require\fR
+command, Tcl appends one or more additional arguments giving the desired
+package name and requirements.
+For example, if \fIcommand\fR is \fBfoo bar\fR and later the command
+\fBpackage require test 2.4\fR is invoked, then Tcl will execute
+the command \fBfoo bar test 2.4\fR to load the package.
+If no requirements are supplied to the \fBpackage require\fR command,
+then only the name will be added to invoked command.
+If the \fBpackage unknown\fR command is invoked without a \fIcommand\fR
+argument, then the current \fBpackage unknown\fR script is returned,
+or an empty string if there is none.
+If \fIcommand\fR is specified as an empty string, then the current
+\fBpackage unknown\fR script is removed, if there is one.
+.TP
+\fBpackage vcompare \fIversion1 version2\fR
+.
+Compares the two version numbers given by \fIversion1\fR and \fIversion2\fR.
+Returns -1 if \fIversion1\fR is an earlier version than \fIversion2\fR,
+0 if they are equal, and 1 if \fIversion1\fR is later than \fIversion2\fR.
+.TP
+\fBpackage versions \fIpackage\fR
+.
+Returns a list of all the version numbers of \fIpackage\fR
+for which information has been provided by \fBpackage ifneeded\fR
+commands.
+.TP
+\fBpackage vsatisfies \fIversion requirement...\fR
+.
+Returns 1 if the \fIversion\fR satisfies at least one of the given
+requirements, and 0 otherwise. Each \fIrequirement\fR is allowed to
+have any of the forms:
+.RS
+.TP
+min
+.
+This form is called
+.QW min-bounded .
+.TP
+min-
+.
+This form is called
+.QW min-unbound .
+.TP
+min-max
+.
+This form is called
+.QW bounded .
+.RE
+.RS
+.PP
+where
+.QW min
+and
+.QW max
+are valid version numbers. The legacy syntax is
+a special case of the extended syntax, keeping backward
+compatibility. Regarding satisfaction the rules are:
+.RE
+.RS
+.IP [1]
+The \fIversion\fR has to pass at least one of the listed
+\fIrequirement\fRs to be satisfactory.
+.IP [2]
+A version satisfies a
+.QW bounded
+requirement when
+.RS
+.IP [a]
+For \fImin\fR equal to the \fImax\fR if, and only if the \fIversion\fR
+is equal to the \fImin\fR.
+.IP [b]
+Otherwise if, and only if the \fIversion\fR is greater than or equal
+to the \fImin\fR, and less than the \fImax\fR, where both \fImin\fR
+and \fImax\fR have been padded internally with
+.QW a0 .
+Note that while the comparison to \fImin\fR is inclusive, the
+comparison to \fImax\fR is exclusive.
+.RE
+.IP [3]
+A
+.QW min-bounded
+requirement is a
+.QW bounded
+requirement in disguise,
+with the \fImax\fR part implicitly specified as the next higher major
+version number of the \fImin\fR part. A version satisfies it per the
+rules above.
+.IP [4]
+A \fIversion\fR satisfies a
+.QW min-unbound
+requirement if, and only if it is greater than or equal to the
+\fImin\fR, where the \fImin\fR has been padded internally with
+.QW a0 .
+There is no constraint to a maximum.
+.RE
+.TP
+\fBpackage prefer \fR?\fBlatest\fR|\fBstable\fR?
+With no arguments, the commands returns either
+.QW latest
+or
+.QW stable ,
+whichever describes the current mode of selection logic used by
+\fBpackage require\fR.
+.RS
+.PP
+When passed the argument
+.QW latest ,
+it sets the selection logic mode to
+.QW latest .
+.PP
+When passed the argument
+.QW stable ,
+if the mode is already
+.QW stable ,
+that value is kept.  If the mode is already
+.QW latest ,
+then the attempt to set it back to
+.QW stable
+is ineffective and the mode value remains
+.QW latest .
+.PP
+When passed any other value as an argument, raise an invalid argument
+error.
+.PP
+When an interpreter is created, its initial selection mode value is set to
+.QW stable
+unless the environment variable \fBTCL_PKG_PREFER_LATEST\fR
+is set.  If that environment variable is defined (with any value) then
+the initial (and permanent) selection mode value is set to
+.QW latest .
+.RE
+.SH "VERSION NUMBERS"
+.PP
+Version numbers consist of one or more decimal numbers separated
+by dots, such as 2 or 1.162 or 3.1.13.1.
+The first number is called the major version number.
+Larger numbers correspond to later versions of a package, with
+leftmost numbers having greater significance.
+For example, version 2.1 is later than 1.3 and version
+3.4.6 is later than 3.3.5.
+Missing fields are equivalent to zeroes:  version 1.3 is the
+same as version 1.3.0 and 1.3.0.0, so it is earlier than 1.3.1 or 1.3.0.2.
+In addition, the letters
+.QW a
+(alpha) and/or
+.QW b
+(beta) may appear
+exactly once to replace a dot for separation. These letters
+semantically add a negative specifier into the version, where
+.QW a
+is \-2, and
+.QW b
+is \-1. Each may be specified only once, and
+.QW a
+or
+.QW b
+are mutually exclusive in a specifier. Thus 1.3a1 becomes (semantically)
+1.3.\-2.1, 1.3b1 is 1.3.\-1.1. Negative numbers are not directly allowed
+in version specifiers.
+A version number not containing the letters
+.QW a
+or
+.QW b
+as specified
+above is called a \fBstable\fR version, whereas presence of the letters
+causes the version to be called is \fBunstable\fR.
+A later version number is assumed to be upwards compatible with
+an earlier version number as long as both versions have the same
+major version number.
+For example, Tcl scripts written for version 2.3 of a package should
+work unchanged under versions 2.3.2, 2.4, and 2.5.1.
+Changes in the major version number signify incompatible changes:
+if code is written to use version 2.1 of a package, it is not guaranteed
+to work unmodified with either version 1.7.3 or version 3.1.
+.SH "PACKAGE INDICES"
+.PP
+The recommended way to use packages in Tcl is to invoke \fBpackage require\fR
+and \fBpackage provide\fR commands in scripts, and use the procedure
+\fBpkg_mkIndex\fR to create package index files.
+Once you have done this, packages will be loaded automatically
+in response to \fBpackage require\fR commands.
+See the documentation for \fBpkg_mkIndex\fR for details.
+.SH EXAMPLES
+.PP
+To state that a Tcl script requires the Tk and http packages, put this
+at the top of the script:
+.PP
+.CS
+\fBpackage require\fR Tk
+\fBpackage require\fR http
+.CE
+.PP
+To test to see if the Snack package is available and load if it is
+(often useful for optional enhancements to programs where the loss of
+the functionality is not critical) do this:
+.PP
+.CS
+if {[catch {\fBpackage require\fR Snack}]} {
+    # Error thrown - package not found.
+    # Set up a dummy interface to work around the absence
+} else {
+    # We have the package, configure the app to use it
+}
+.CE
+.SH "SEE ALSO"
+msgcat(n), packagens(n), pkgMkIndex(n)
+.SH KEYWORDS
+package, version
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/doc/packagens.n b/doc/packagens.n
new file mode 100644
index 0000000..61e7eca
--- /dev/null
+++ b/doc/packagens.n
@@ -0,0 +1,50 @@
+'\"
+'\" Copyright (c) 1998-2000 by Scriptics Corporation.
+'\" All rights reserved.
+'\" 
+.TH pkg::create n 8.3 Tcl "Tcl Built-In Commands"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+pkg::create \- Construct an appropriate 'package ifneeded' command for a given package specification
+.SH SYNOPSIS
+\fB::pkg::create\fR \fB\-name \fIpackageName \fB\-version \fIpackageVersion\fR ?\fB\-load \fIfilespec\fR? ... ?\fB\-source \fIfilespec\fR? ...
+.BE
+
+.SH DESCRIPTION
+.PP
+\fB::pkg::create\fR is a utility procedure that is part of the standard Tcl
+library.  It is used to create an appropriate \fBpackage ifneeded\fR
+command for a given package specification.  It can be used to construct a
+\fBpkgIndex.tcl\fR file for use with the \fBpackage\fR mechanism.
+
+.SH OPTIONS
+The parameters supported are:
+.TP
+\fB\-name \fIpackageName\fR
+This parameter specifies the name of the package.  It is required.
+.TP
+\fB\-version \fIpackageVersion\fR
+This parameter specifies the version of the package.  It is required.
+.TP
+\fB\-load \fIfilespec\fR
+This parameter specifies a binary library that must be loaded with the
+\fBload\fR command.  \fIfilespec\fR is a list with two elements.  The
+first element is the name of the file to load.  The second, optional
+element is a list of commands supplied by loading that file.  If the
+list of procedures is empty or omitted, \fB::pkg::create\fR will
+set up the library for direct loading (see \fBpkg_mkIndex\fR).  Any
+number of \fB\-load\fR parameters may be specified.
+.TP
+\fB\-source \fIfilespec\fR
+This parameter is similar to the \fB\-load\fR parameter, except that it
+specifies a Tcl library that must be loaded with the
+\fBsource\fR command.  Any number of \fB\-source\fR parameters may be
+specified.
+.PP
+At least one \fB\-load\fR or \fB\-source\fR parameter must be given.
+.SH "SEE ALSO"
+package(n)
+.SH KEYWORDS
+auto-load, index, package, version
diff --git a/doc/pid.n b/doc/pid.n
new file mode 100644
index 0000000..a4df2f3
--- /dev/null
+++ b/doc/pid.n
@@ -0,0 +1,48 @@
+'\"
+'\" Copyright (c) 1993 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\" 
+.TH pid n 7.0 Tcl "Tcl Built-In Commands"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+pid \- Retrieve process identifiers
+.SH SYNOPSIS
+\fBpid \fR?\fIfileId\fR?
+.BE
+
+.SH DESCRIPTION
+.PP
+If the \fIfileId\fR argument is given then it should normally
+refer to a process pipeline created with the \fBopen\fR command.
+In this case the \fBpid\fR command will return a list whose elements
+are the process identifiers of all the processes in the pipeline,
+in order.
+The list will be empty if \fIfileId\fR refers to an open file
+that is not a process pipeline.
+If no \fIfileId\fR argument is given then \fBpid\fR returns the process
+identifier of the current process.
+All process identifiers are returned as decimal strings.
+.SH EXAMPLE
+Print process information about the processes in a pipeline using the
+SysV \fBps\fR program before reading the output of that pipeline:
+.PP
+.CS
+set pipeline [open "| zcat somefile.gz | grep foobar | sort -u"]
+# Print process information
+exec ps -fp [\fBpid\fR $pipeline] >@stdout
+# Print a separator and then the output of the pipeline
+puts [string repeat - 70]
+puts [read $pipeline]
+close $pipeline
+.CE
+
+.SH "SEE ALSO"
+exec(n), open(n)
+
+.SH KEYWORDS
+file, pipeline, process identifier
diff --git a/doc/pkgMkIndex.n b/doc/pkgMkIndex.n
new file mode 100644
index 0000000..ec39be9
--- /dev/null
+++ b/doc/pkgMkIndex.n
@@ -0,0 +1,233 @@
+'\"
+'\" Copyright (c) 1996 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH pkg_mkIndex n 8.3 Tcl "Tcl Built-In Commands"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+pkg_mkIndex \- Build an index for automatic loading of packages
+.SH SYNOPSIS
+.nf
+\fBpkg_mkIndex\fR ?\fIoptions...\fR? \fIdir\fR ?\fIpattern pattern ...\fR?
+.fi
+.BE
+.SH DESCRIPTION
+.PP
+\fBPkg_mkIndex\fR is a utility procedure that is part of the standard
+Tcl library.
+It is used to create index files that allow packages to be loaded
+automatically when \fBpackage require\fR commands are executed.
+To use \fBpkg_mkIndex\fR, follow these steps:
+.IP [1]
+Create the package(s).
+Each package may consist of one or more Tcl script files or binary files.
+Binary files must be suitable for loading with the \fBload\fR command
+with a single argument;  for example, if the file is \fBtest.so\fR it must
+be possible to load this file with the command \fBload test.so\fR.
+Each script file must contain a \fBpackage provide\fR command to declare
+the package and version number, and each binary file must contain
+a call to \fBTcl_PkgProvide\fR.
+.IP [2]
+Create the index by invoking \fBpkg_mkIndex\fR.
+The \fIdir\fR argument gives the name of a directory and each
+\fIpattern\fR argument is a \fBglob\fR-style pattern that selects
+script or binary files in \fIdir\fR.
+The default pattern is \fB*.tcl\fR and \fB*.[info sharedlibextension]\fR.
+.RS
+.PP
+\fBPkg_mkIndex\fR will create a file \fBpkgIndex.tcl\fR in \fIdir\fR
+with package information about all the files given by the \fIpattern\fR
+arguments.
+It does this by loading each file into a slave
+interpreter and seeing what packages
+and new commands appear (this is why it is essential to have
+\fBpackage provide\fR commands or \fBTcl_PkgProvide\fR calls
+in the files, as described above).
+If you have a package split among scripts and binary files,
+or if you have dependencies among files,
+you may have to use the \fB\-load\fR option
+or adjust the order in which \fBpkg_mkIndex\fR processes
+the files.  See \fBCOMPLEX CASES\fR below.
+.RE
+.IP [3]
+Install the package as a subdirectory of one of the directories given by
+the \fBtcl_pkgPath\fR variable.  If \fB$tcl_pkgPath\fR contains more
+than one directory, machine-dependent packages (e.g., those that
+contain binary shared libraries) should normally be installed
+under the first directory and machine-independent packages (e.g.,
+those that contain only Tcl scripts) should be installed under the
+second directory.
+The subdirectory should include
+the package's script and/or binary files as well as the \fBpkgIndex.tcl\fR
+file.  As long as the package is installed as a subdirectory of a
+directory in \fB$tcl_pkgPath\fR it will automatically be found during
+\fBpackage require\fR commands.
+.RS
+.PP
+If you install the package anywhere else, then you must ensure that
+the directory containing the package is in the \fBauto_path\fR global variable
+or an immediate subdirectory of one of the directories in \fBauto_path\fR.
+\fBAuto_path\fR contains a list of directories that are searched
+by both the auto-loader and the package loader; by default it
+includes \fB$tcl_pkgPath\fR.
+The package loader also checks all of the subdirectories of the
+directories in \fBauto_path\fR.
+You can add a directory to \fBauto_path\fR explicitly in your
+application, or you can add the directory to your \fBTCLLIBPATH\fR
+environment variable:  if this environment variable is present,
+Tcl initializes \fBauto_path\fR from it during application startup.
+.RE
+.IP [4]
+Once the above steps have been taken, all you need to do to use a
+package is to invoke \fBpackage require\fR.
+For example, if versions 2.1, 2.3, and 3.1 of package \fBTest\fR
+have been indexed by \fBpkg_mkIndex\fR, the command
+\fBpackage require Test\fR will make version 3.1 available
+and the command \fBpackage require \-exact Test 2.1\fR will
+make version 2.1 available.
+There may be many versions of a package in the various index files
+in \fBauto_path\fR, but only one will actually be loaded in a given
+interpreter, based on the first call to \fBpackage require\fR.
+Different versions of a package may be loaded in different
+interpreters.
+.SH OPTIONS
+The optional switches are:
+.TP 15
+\fB\-direct\fR
+The generated index will implement direct loading of the package
+upon \fBpackage require\fR.  This is the default.
+.TP 15
+\fB\-lazy\fR
+The generated index will manage to delay loading the package until the
+use of one of the commands provided by the package, instead of loading
+it immediately upon \fBpackage require\fR.  This is not compatible with
+the use of \fIauto_reset\fR, and therefore its use is discouraged.
+.TP 15
+\fB\-load \fIpkgPat\fR
+The index process will pre-load any packages that exist in the
+current interpreter and match \fIpkgPat\fR into the slave interpreter used to
+generate the index.  The pattern match uses string match rules, but without
+making case distinctions.
+See \fBCOMPLEX CASES\fR below.
+.TP 15
+\fB\-verbose\fR
+Generate output during the indexing process.  Output is via
+the \fBtclLog\fR procedure, which by default prints to stderr.
+.TP 15
+\fB\-\-\fR
+End of the flags, in case \fIdir\fR begins with a dash.
+.SH "PACKAGES AND THE AUTO-LOADER"
+.PP
+The package management facilities overlap somewhat with the auto-loader,
+in that both arrange for files to be loaded on-demand.
+However, package management is a higher-level mechanism that uses
+the auto-loader for the last step in the loading process.
+It is generally better to index a package with \fBpkg_mkIndex\fR
+rather than \fBauto_mkindex\fR because the package mechanism provides
+version control:  several versions of a package can be made available
+in the index files, with different applications using different
+versions based on \fBpackage require\fR commands.
+In contrast, \fBauto_mkindex\fR does not understand versions so
+it can only handle a single version of each package.
+It is probably not a good idea to index a given package with both
+\fBpkg_mkIndex\fR and \fBauto_mkindex\fR.
+If you use \fBpkg_mkIndex\fR to index a package, its commands cannot
+be invoked until \fBpackage require\fR has been used to select a
+version;  in contrast, packages indexed with \fBauto_mkindex\fR
+can be used immediately since there is no version control.
+.SH "HOW IT WORKS"
+.PP
+\fBPkg_mkIndex\fR depends on the \fBpackage unknown\fR command,
+the \fBpackage ifneeded\fR command, and the auto-loader.
+The first time a \fBpackage require\fR command is invoked,
+the \fBpackage unknown\fR script is invoked.
+This is set by Tcl initialization to a script that
+evaluates all of the \fBpkgIndex.tcl\fR files in the
+\fBauto_path\fR.
+The \fBpkgIndex.tcl\fR files contain \fBpackage ifneeded\fR
+commands for each version of each available package;  these commands
+invoke \fBpackage provide\fR commands to announce the
+availability of the package, and they setup auto-loader
+information to load the files of the package.
+If the \fB\-lazy\fR flag was provided when the \fBpkgIndex.tcl\fR
+was generated,
+a given file of a given version of a given package is not
+actually loaded until the first time one of its commands
+is invoked.
+Thus, after invoking \fBpackage require\fR you may
+not see the package's commands in the interpreter, but you will be able
+to invoke the commands and they will be auto-loaded.
+.SH "DIRECT LOADING"
+.PP
+Some packages, for instance packages which use namespaces and export
+commands or those which require special initialization, might select
+that their package files be loaded immediately upon \fBpackage require\fR
+instead of delaying the actual loading to the first use of one of the
+package's command. This is the default mode when generating the package
+index.  It can be overridden by specifying the \fB\-lazy\fR argument.
+.SH "COMPLEX CASES"
+Most complex cases of dependencies among scripts
+and binary files, and packages being split among scripts and
+binary files are handled OK.  However, you may have to adjust
+the order in which files are processed by \fBpkg_mkIndex\fR.
+These issues are described in detail below.
+.PP
+If each script or file contains one package, and packages
+are only contained in one file, then things are easy.
+You simply specify all files to be indexed in any order
+with some glob patterns.
+.PP
+In general, it is OK for scripts to have dependencies on other
+packages.
+If scripts contain \fBpackage require\fR commands, these are
+stubbed out in the interpreter used to process the scripts,
+so these do not cause problems.
+If scripts call into other packages in global code,
+these calls are handled by a stub \fBunknown\fR command.
+However, if scripts make variable references to other package's
+variables in global code, these will cause errors.  That is
+also bad coding style.
+.PP
+If binary files have dependencies on other packages, things
+can become tricky because it is not possible to stub out
+C-level APIs such as \fBTcl_PkgRequire\fR API
+when loading a binary file.
+For example, suppose the BLT package requires Tk, and expresses
+this with a call to \fBTcl_PkgRequire\fR in its \fBBlt_Init\fR routine.
+To support this, you must run \fBpkg_mkIndex\fR in an interpreter that
+has Tk loaded.  You can achieve this with the
+\fB\-load \fIpkgPat\fR option.  If you specify this option,
+\fBpkg_mkIndex\fR will load any packages listed by
+\fBinfo loaded\fR and that match \fIpkgPat\fR
+into the interpreter used to process files.
+In most cases this will satisfy the \fBTcl_PkgRequire\fR calls
+made by binary files.
+.PP
+If you are indexing two binary files and one depends on the other,
+you should specify the one that has dependencies last.
+This way the one without dependencies will get loaded and indexed,
+and then the package it provides
+will be available when the second file is processed.
+You may also need to load the first package into the
+temporary interpreter used to create the index by using
+the \fB\-load\fR flag;
+it will not hurt to specify package patterns that are not yet loaded.
+.PP
+If you have a package that is split across scripts and a binary file,
+then you should avoid the \fB\-load\fR flag. The problem is that
+if you load a package before computing the index it masks any
+other files that provide part of the same package.
+If you must use \fB\-load\fR,
+then you must specify the scripts first; otherwise the package loaded from
+the binary file may mask the package defined by the scripts.
+.SH "SEE ALSO"
+package(n)
+.SH KEYWORDS
+auto-load, index, package, version
+'\"Local Variables:
+'\"mode: nroff
+'\"End:
diff --git a/doc/platform.n b/doc/platform.n
new file mode 100644
index 0000000..6abc289
--- /dev/null
+++ b/doc/platform.n
@@ -0,0 +1,86 @@
+'\"
+'\" Copyright (c) 2006 ActiveState Software Inc
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\" 
+.TH "platform" n 1.0.4 platform "Tcl Bundled Packages"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+platform \- System identification support code and utilities
+.SH SYNOPSIS
+.nf
+\fBpackage require platform ?1.0.10?\fR
+.sp
+\fBplatform::generic\fR
+\fBplatform::identify\fR
+\fBplatform::patterns \fIidentifier\fR
+.fi
+.BE
+.SH DESCRIPTION
+.PP
+The \fBplatform\fR package provides several utility commands useful
+for the identification of the architecture of a machine running Tcl.
+.PP
+Whilst Tcl provides the \fBtcl_platform\fR array for identifying the
+current architecture (in particular, the platform and machine
+elements) this is not always sufficient. This is because (on Unix
+machines) \fBtcl_platform\fR reflects the values returned by the
+\fBuname\fR command and these are not standardized across platforms and
+architectures. In addition, on at least one platform (AIX) the
+\fBtcl_platform(machine)\fR contains the CPU serial number.
+.PP
+Consequently, individual applications need to manipulate the values in
+\fBtcl_platform\fR (along with the output of system specific
+utilities) - which is both inconvenient for developers, and introduces
+the potential for inconsistencies in identifying architectures and in
+naming conventions.
+.PP
+The \fBplatform\fR package prevents such fragmentation - i.e., it
+establishes a standard naming convention for architectures running Tcl
+and makes it more convenient for developers to identify the current
+architecture a Tcl program is running on.
+.SH COMMANDS
+.TP
+\fBplatform::identify\fR
+.
+This command returns an identifier describing the platform the Tcl
+core is running on. The returned identifier has the general format
+\fIOS\fR-\fICPU\fR. The \fIOS\fR part of the identifier may contain
+details like kernel version, libc version, etc., and this information
+may contain dashes as well.  The \fICPU\fR part will not contain
+dashes, making the preceding dash the last dash in the result.
+.TP
+\fBplatform::generic\fR
+.
+This command returns a simplified identifier describing the platform
+the Tcl core is running on. In contrast to \fBplatform::identify\fR it
+leaves out details like kernel version, libc version, etc. The
+returned identifier has the general format \fIOS\fR-\fICPU\fR.
+.TP
+\fBplatform::patterns \fIidentifier\fR
+.
+This command takes an identifier as returned by
+\fBplatform::identify\fR and returns a list of identifiers describing
+compatible architectures.
+.SH EXAMPLE
+.PP
+This can be used to allow an application to be shipped with multiple builds of
+a shared library, so that the same package works on many versions of an
+operating system. For example:
+.PP
+.CS
+\fBpackage require platform\fR
+# Assume that app script is .../theapp/bin/theapp.tcl
+set binDir [file dirname [file normalize [info script]]]
+set libDir [file join $binDir .. lib]
+set platLibDir [file join $libDir [\fBplatform::identify\fR]]
+load [file join $platLibDir support[info sharedlibextension]]
+.CE
+.SH KEYWORDS
+operating system, cpu architecture, platform, architecture
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/doc/platform_shell.n b/doc/platform_shell.n
new file mode 100644
index 0000000..64a2e46
--- /dev/null
+++ b/doc/platform_shell.n
@@ -0,0 +1,57 @@
+'\"
+'\" Copyright (c) 2006-2008 ActiveState Software Inc
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\" 
+.TH "platform::shell" n 1.1.4 platform::shell "Tcl Bundled Packages"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+platform::shell \- System identification support code and utilities
+.SH SYNOPSIS
+.nf
+\fBpackage require platform::shell ?1.1.4?\fR
+.sp
+\fBplatform::shell::generic \fIshell\fR
+\fBplatform::shell::identify \fIshell\fR
+\fBplatform::shell::platform \fIshell\fR
+.fi
+.BE
+.SH DESCRIPTION
+.PP
+The \fBplatform::shell\fR package provides several utility commands useful
+for the identification of the architecture of a specific Tcl shell.
+.PP
+This package allows the identification of the architecture of a
+specific Tcl shell different from the shell running the package. The
+only requirement is that the other shell (identified by its path), is
+actually executable on the current machine.
+.PP
+While for most platform this means that the architecture of the
+interrogated shell is identical to the architecture of the running
+shell this is not generally true. A counter example are all platforms
+which have 32 and 64 bit variants and where a 64bit system is able to
+run 32bit code. For these running and interrogated shell may have
+different 32/64 bit settings and thus different identifiers.
+.PP
+For applications like a code repository it is important to identify
+the architecture of the shell which will actually run the installed
+packages, versus the architecture of the shell running the repository
+software.
+.SH COMMANDS
+.TP
+\fBplatform::shell::identify \fIshell\fR
+This command does the same identification as \fBplatform::identify\fR,
+for the specified Tcl shell, in contrast to the running shell.
+.TP
+\fBplatform::shell::generic \fIshell\fR
+This command does the same identification as \fBplatform::generic\fR,
+for the specified Tcl shell, in contrast to the running shell.
+.TP
+\fBplatform::shell::platform \fIshell\fR
+This command returns the contents of \fBtcl_platform(platform)\fR for
+the specified Tcl shell.
+.SH KEYWORDS
+operating system, cpu architecture, platform, architecture
diff --git a/doc/prefix.n b/doc/prefix.n
new file mode 100644
index 0000000..344ade7
--- /dev/null
+++ b/doc/prefix.n
@@ -0,0 +1,116 @@
+'\"
+'\" Copyright (c) 2008 Peter Spjuth <pspjuth@users.sourceforge.net>
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\" 
+.TH prefix n 8.6 Tcl "Tcl Built-In Commands"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+tcl::prefix \- facilities for prefix matching
+.SH SYNOPSIS
+.nf
+\fB::tcl::prefix all\fR \fItable\fR \fIstring\fR
+\fB::tcl::prefix longest\fR \fItable\fR \fIstring\fR
+\fB::tcl::prefix match\fR \fI?option ...?\fR \fItable\fR \fIstring\fR
+.fi
+.BE
+.SH DESCRIPTION
+.PP
+This document describes commands looking up a prefix in a list of strings.
+The following commands are supported:
+.TP
+\fB::tcl::prefix all\fR \fItable\fR \fIstring\fR
+.
+Returns a list of all elements in \fItable\fR that begin with the prefix
+\fIstring\fR.
+.TP
+\fB::tcl::prefix longest\fR \fItable\fR \fIstring\fR
+.
+Returns the longest common prefix of all elements in \fItable\fR that
+begin with the prefix \fIstring\fR.
+.TP
+\fB::tcl::prefix match\fR ?\fIoptions\fR? \fItable\fR \fIstring\fR
+.
+If \fIstring\fR equals one element in \fItable\fR or is a prefix to exactly
+one element, the matched element is returned. If not, the result depends
+on the \fB\-error\fR option. (It is recommended that the \fItable\fR be sorted
+before use with this subcommand, so that the list of matches presented in the
+error message also becomes sorted, though this is not strictly necessary for
+the operation of this subcommand itself.)
+.RS
+.TP
+\fB\-exact\fR\0
+.
+Accept only exact matches.
+.TP
+\fB\-message\0\fIstring\fR
+.
+Use \fIstring\fR in the error message at a mismatch. Default is
+.QW option .
+.TP
+\fB\-error\0\fIoptions\fR
+.
+The \fIoptions\fR are used when no match is found. If \fIoptions\fR is empty,
+no error is generated and an empty string is returned. Otherwise the
+\fIoptions\fR are used as \fBreturn\fR options when generating the error
+message. The default corresponds to setting
+.QW "\-level 0" .
+Example: If
+.QW "\fB\-error\fR {\-errorcode MyError \-level 1}"
+is used, an error would be generated as:
+.RS
+.PP
+.CS
+return \-errorcode MyError \-level 1 \-code error \e
+       "ambiguous option ..."
+.CE
+.RE
+.RE
+.SH "EXAMPLES"
+.PP
+Basic use:
+.PP
+.CS
+namespace import ::tcl::prefix
+\fBprefix match\fR {apa bepa cepa} apa
+     \fI\(-> apa\fR
+\fBprefix match\fR {apa bepa cepa} a
+     \fI\(-> apa\fR
+\fBprefix match\fR \-exact {apa bepa cepa} a
+     \fI\(-> bad option "a": must be apa, bepa, or cepa\fR
+\fBprefix match\fR \-message "switch" {apa ada bepa cepa} a
+     \fI\(-> ambiguous switch "a": must be apa, ada, bepa, or cepa\fR
+\fBprefix longest\fR {fblocked fconfigure fcopy file fileevent flush} fc
+     \fI\(-> fco\fR
+\fBprefix all\fR {fblocked fconfigure fcopy file fileevent flush} fc
+     \fI\(-> fconfigure fcopy\fR
+.CE
+.PP
+Simplifying option matching:
+.PP
+.CS
+array set opts {\-apa 1 \-bepa "" \-cepa 0}
+foreach {arg val} $args {
+    set opts([\fBprefix match\fR {\-apa \-bepa \-cepa} $arg]) $val
+}
+.CE
+.PP
+Creating a \fBswitch\fR that supports prefixes:
+.PP
+.CS
+switch [\fBprefix match\fR {apa bepa cepa} $arg] {
+    apa  { }
+    bepa { }
+    cepa { }
+}
+.CE
+.SH "SEE ALSO"
+lsearch(n), namespace(n), string(n), Tcl_GetIndexFromObj(3)
+.SH "KEYWORDS"
+prefix, table lookup
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/doc/proc.n b/doc/proc.n
new file mode 100644
index 0000000..fdccaca
--- /dev/null
+++ b/doc/proc.n
@@ -0,0 +1,128 @@
+'\"
+'\" Copyright (c) 1993 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH proc n "" Tcl "Tcl Built-In Commands"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+proc \- Create a Tcl procedure
+.SH SYNOPSIS
+\fBproc \fIname args body\fR
+.BE
+.SH DESCRIPTION
+.PP
+The \fBproc\fR command creates a new Tcl procedure named
+\fIname\fR, replacing
+any existing command or procedure there may have been by that name.
+Whenever the new command is invoked, the contents of \fIbody\fR will
+be executed by the Tcl interpreter.
+Normally, \fIname\fR is unqualified
+(does not include the names of any containing namespaces),
+and the new procedure is created in the current namespace.
+If \fIname\fR includes any namespace qualifiers,
+the procedure is created in the specified namespace.
+\fIArgs\fR specifies the formal arguments to the
+procedure.  It consists of a list, possibly empty, each of whose
+elements specifies
+one argument.  Each argument specifier is also a list with either
+one or two fields.  If there is only a single field in the specifier
+then it is the name of the argument; if there are two fields, then
+the first is the argument name and the second is its default value.
+Arguments with default values that are followed by non-defaulted
+arguments become required arguments; enough actual arguments must be
+supplied to allow all arguments up to and including the last required
+formal argument.
+.PP
+When \fIname\fR is invoked a local variable
+will be created for each of the formal arguments to the procedure; its
+value will be the value of corresponding argument in the invoking command
+or the argument's default value.
+Actual arguments are assigned to formal arguments strictly in order.
+Arguments with default values need not be
+specified in a procedure invocation.  However, there must be enough
+actual arguments for all the
+formal arguments that do not have defaults, and there must not be any extra
+actual arguments.
+Arguments with default values that are followed by non-defaulted
+arguments become de-facto required arguments, though this may change
+in a future version of Tcl; portable code should ensure that all
+optional arguments come after all required arguments.
+.PP
+There is one special case to permit procedures with
+variable numbers of arguments.  If the last formal argument has the name
+.QW \fBargs\fR ,
+then a call to the procedure may contain more actual arguments
+than the procedure has formal arguments.  In this case, all of the actual arguments
+starting at the one that would be assigned to \fBargs\fR are combined into
+a list (as if the \fBlist\fR command had been used); this combined value
+is assigned to the local variable \fBargs\fR.
+.PP
+When \fIbody\fR is being executed, variable names normally refer to
+local variables, which are created automatically when referenced and
+deleted when the procedure returns.  One local variable is automatically
+created for each of the procedure's arguments.
+Other variables can only be accessed by invoking one of the \fBglobal\fR,
+\fBvariable\fR, \fBupvar\fR or \fBnamespace upvar\fR commands.
+The current namespace when \fIbody\fR is executed will be the
+namespace that the procedure's name exists in, which will be the
+namespace that it was created in unless it has been changed with
+\fBrename\fR.
+'\" We may change this! It makes [variable] unstable when renamed and is
+'\" frankly pretty crazy, but doing it right is harder than it looks.
+.PP
+The \fBproc\fR command returns an empty string.  When a procedure is
+invoked, the procedure's return value is the value specified in a
+\fBreturn\fR command.  If the procedure does not execute an explicit
+\fBreturn\fR, then its return value is the value of the last command
+executed in the procedure's body.
+If an error occurs while executing the procedure
+body, then the procedure-as-a-whole will return that same error.
+.SH EXAMPLES
+.PP
+This is a procedure that takes two arguments and prints both their sum
+and their product. It also returns the string
+.QW OK
+to the caller as an explicit result.
+.PP
+.CS
+\fBproc\fR printSumProduct {x y} {
+    set sum [expr {$x + $y}]
+    set prod [expr {$x * $y}]
+    puts "sum is $sum, product is $prod"
+    return "OK"
+}
+.CE
+.PP
+This is a procedure that accepts arbitrarily many arguments and prints
+them out, one by one.
+.PP
+.CS
+\fBproc\fR printArguments args {
+    foreach arg $args {
+        puts $arg
+    }
+}
+.CE
+.PP
+This procedure is a bit like the \fBincr\fR command, except it
+multiplies the contents of the named variable by the value, which
+defaults to \fB2\fR:
+.PP
+.CS
+\fBproc\fR mult {varName {multiplier 2}} {
+    upvar 1 $varName var
+    set var [expr {$var * $multiplier}]
+}
+.CE
+.SH "SEE ALSO"
+info(n), unknown(n)
+.SH KEYWORDS
+argument, procedure
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/doc/puts.n b/doc/puts.n
new file mode 100644
index 0000000..01ca122
--- /dev/null
+++ b/doc/puts.n
@@ -0,0 +1,98 @@
+'\"
+'\" Copyright (c) 1993 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\" 
+.TH puts n 7.5 Tcl "Tcl Built-In Commands"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+puts \- Write to a channel
+.SH SYNOPSIS
+\fBputs \fR?\fB\-nonewline\fR? ?\fIchannelId\fR? \fIstring\fR
+.BE
+.SH DESCRIPTION
+.PP
+Writes the characters given by \fIstring\fR to the channel given
+by \fIchannelId\fR.
+.PP
+\fIChannelId\fR must be an identifier for an open channel such as a
+Tcl standard channel (\fBstdout\fR or \fBstderr\fR), the return
+value from an invocation of \fBopen\fR or \fBsocket\fR, or the result
+of a channel creation command provided by a Tcl extension. The channel
+must have been opened for output.
+.PP
+If no \fIchannelId\fR is specified then it defaults to
+\fBstdout\fR. \fBPuts\fR normally outputs a newline character after
+\fIstring\fR, but this feature may be suppressed by specifying the
+\fB\-nonewline\fR switch.
+.PP
+Newline characters in the output are translated by \fBputs\fR to
+platform-specific end-of-line sequences according to the current
+value of the \fB\-translation\fR option for the channel (for example,
+on PCs newlines are normally replaced with carriage-return-linefeed
+sequences.
+See the \fBfconfigure\fR manual entry for a discussion on ways in
+which \fBfconfigure\fR will alter output.
+.PP
+Tcl buffers output internally, so characters written with \fBputs\fR
+may not appear immediately on the output file or device;  Tcl will
+normally delay output until the buffer is full or the channel is
+closed.
+You can force output to appear immediately with the \fBflush\fR
+command.
+.PP
+When the output buffer fills up, the \fBputs\fR command will normally
+block until all the buffered data has been accepted for output by the
+operating system.
+If \fIchannelId\fR is in nonblocking mode then the \fBputs\fR command
+will not block even if the operating system cannot accept the data.
+Instead, Tcl continues to buffer the data and writes it in the
+background as fast as the underlying file or device can accept it.
+The application must use the Tcl event loop for nonblocking output
+to work;  otherwise Tcl never finds out that the file or device is
+ready for more output data.
+It is possible for an arbitrarily large amount of data to be
+buffered for a channel in nonblocking mode, which could consume a
+large amount of memory.
+To avoid wasting memory, nonblocking I/O should normally
+be used in an event-driven fashion with the \fBfileevent\fR command
+(do not invoke \fBputs\fR unless you have recently been notified
+via a file event that the channel is ready for more output data).
+.SH EXAMPLES
+.PP
+Write a short message to the console (or wherever \fBstdout\fR is
+directed):
+.PP
+.CS
+\fBputs\fR "Hello, World!"
+.CE
+.PP
+Print a message in several parts:
+.PP
+.CS
+\fBputs\fR -nonewline "Hello, "
+\fBputs\fR "World!"
+.CE
+.PP
+Print a message to the standard error channel:
+.PP
+.CS
+\fBputs\fR stderr "Hello, World!"
+.CE
+.PP
+Append a log message to a file:
+.PP
+.CS
+set chan [open my.log a]
+set timestamp [clock format [clock seconds]]
+\fBputs\fR $chan "$timestamp - Hello, World!"
+close $chan
+.CE
+.SH "SEE ALSO"
+file(n), fileevent(n), Tcl_StandardChannels(3)
+.SH KEYWORDS
+channel, newline, output, write
diff --git a/doc/pwd.n b/doc/pwd.n
new file mode 100644
index 0000000..31d378f
--- /dev/null
+++ b/doc/pwd.n
@@ -0,0 +1,39 @@
+'\"
+'\" Copyright (c) 1993 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\" 
+.TH pwd n "" Tcl "Tcl Built-In Commands"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+pwd \- Return the absolute path of the current working directory
+.SH SYNOPSIS
+\fBpwd\fR
+.BE
+.SH DESCRIPTION
+.PP
+Returns the absolute path name of the current working directory.
+.SH EXAMPLE
+.PP
+Sometimes it is useful to change to a known directory when running
+some external command using \fBexec\fR, but it is important to keep
+the application usually running in the directory that it was started
+in (unless the user specifies otherwise) since that minimizes user
+confusion. The way to do this is to save the current directory while
+the external command is being run:
+.PP
+.CS
+set tarFile [file normalize somefile.tar]
+set savedDir [\fBpwd\fR]
+cd /tmp
+exec tar -xf $tarFile
+cd $savedDir
+.CE
+.SH "SEE ALSO"
+file(n), cd(n), glob(n), filename(n)
+.SH KEYWORDS
+working directory
diff --git a/doc/re_syntax.n b/doc/re_syntax.n
new file mode 100644
index 0000000..7988071
--- /dev/null
+++ b/doc/re_syntax.n
@@ -0,0 +1,858 @@
+'\"
+'\" Copyright (c) 1998 Sun Microsystems, Inc.
+'\" Copyright (c) 1999 Scriptics Corporation
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.so man.macros
+.ie '\w'o''\w'\C'^o''' .ds qo \C'^o'
+.el .ds qo u
+.TH re_syntax n "8.1" Tcl "Tcl Built-In Commands"
+.BS
+.SH NAME
+re_syntax \- Syntax of Tcl regular expressions
+.BE
+.SH DESCRIPTION
+.PP
+A \fIregular expression\fR describes strings of characters.
+It's a pattern that matches certain strings and does not match others.
+.SH "DIFFERENT FLAVORS OF REs"
+Regular expressions
+.PQ RE s ,
+as defined by POSIX, come in two flavors: \fIextended\fR REs
+.PQ ERE s
+and \fIbasic\fR REs
+.PQ BRE s .
+EREs are roughly those of the traditional \fIegrep\fR, while BREs are
+roughly those of the traditional \fIed\fR. This implementation adds
+a third flavor, \fIadvanced\fR REs
+.PQ ARE s ,
+basically EREs with some significant extensions.
+.PP
+This manual page primarily describes AREs. BREs mostly exist for
+backward compatibility in some old programs; they will be discussed at
+the end. POSIX EREs are almost an exact subset of AREs. Features of
+AREs that are not present in EREs will be indicated.
+.SH "REGULAR EXPRESSION SYNTAX"
+.PP
+Tcl regular expressions are implemented using the package written by
+Henry Spencer, based on the 1003.2 spec and some (not quite all) of
+the Perl5 extensions (thanks, Henry!). Much of the description of
+regular expressions below is copied verbatim from his manual entry.
+.PP
+An ARE is one or more \fIbranches\fR,
+separated by
+.QW \fB|\fR ,
+matching anything that matches any of the branches.
+.PP
+A branch is zero or more \fIconstraints\fR or \fIquantified atoms\fR,
+concatenated.
+It matches a match for the first, followed by a match for the second, etc;
+an empty branch matches the empty string.
+.SS QUANTIFIERS
+A quantified atom is an \fIatom\fR possibly followed
+by a single \fIquantifier\fR.
+Without a quantifier, it matches a single match for the atom.
+The quantifiers,
+and what a so-quantified atom matches, are:
+.RS 2
+.TP 6
+\fB*\fR
+.
+a sequence of 0 or more matches of the atom
+.TP
+\fB+\fR
+.
+a sequence of 1 or more matches of the atom
+.TP
+\fB?\fR
+.
+a sequence of 0 or 1 matches of the atom
+.TP
+\fB{\fIm\fB}\fR
+.
+a sequence of exactly \fIm\fR matches of the atom
+.TP
+\fB{\fIm\fB,}\fR
+.
+a sequence of \fIm\fR or more matches of the atom
+.TP
+\fB{\fIm\fB,\fIn\fB}\fR
+.
+a sequence of \fIm\fR through \fIn\fR (inclusive) matches of the atom;
+\fIm\fR may not exceed \fIn\fR
+.TP
+\fB*?  +?  ??  {\fIm\fB}?  {\fIm\fB,}?  {\fIm\fB,\fIn\fB}?\fR
+.
+\fInon-greedy\fR quantifiers, which match the same possibilities,
+but prefer the smallest number rather than the largest number
+of matches (see \fBMATCHING\fR)
+.RE
+.PP
+The forms using \fB{\fR and \fB}\fR are known as \fIbound\fRs. The
+numbers \fIm\fR and \fIn\fR are unsigned decimal integers with
+permissible values from 0 to 255 inclusive.
+.SS ATOMS
+An atom is one of:
+.RS 2
+.IP \fB(\fIre\fB)\fR 6
+matches a match for \fIre\fR (\fIre\fR is any regular expression) with
+the match noted for possible reporting
+.IP \fB(?:\fIre\fB)\fR
+as previous, but does no reporting (a
+.QW non-capturing
+set of parentheses)
+.IP \fB()\fR
+matches an empty string, noted for possible reporting
+.IP \fB(?:)\fR
+matches an empty string, without reporting
+.IP \fB[\fIchars\fB]\fR
+a \fIbracket expression\fR, matching any one of the \fIchars\fR (see
+\fBBRACKET EXPRESSIONS\fR for more detail)
+.IP \fB.\fR
+matches any single character
+.IP \fB\e\fIk\fR
+matches the non-alphanumeric character \fIk\fR
+taken as an ordinary character, e.g. \fB\e\e\fR matches a backslash
+character
+.IP \fB\e\fIc\fR
+where \fIc\fR is alphanumeric (possibly followed by other characters),
+an \fIescape\fR (AREs only), see \fBESCAPES\fR below
+.IP \fB{\fR
+when followed by a character other than a digit, matches the
+left-brace character
+.QW \fB{\fR ;
+when followed by a digit, it is the beginning of a \fIbound\fR (see above)
+.IP \fIx\fR
+where \fIx\fR is a single character with no other significance,
+matches that character.
+.RE
+.SS CONSTRAINTS
+A \fIconstraint\fR matches an empty string when specific conditions
+are met. A constraint may not be followed by a quantifier. The
+simple constraints are as follows; some more constraints are described
+later, under \fBESCAPES\fR.
+.RS 2
+.TP 8
+\fB^\fR
+.
+matches at the beginning of a line
+.TP
+\fB$\fR
+.
+matches at the end of a line
+.TP
+\fB(?=\fIre\fB)\fR
+.
+\fIpositive lookahead\fR (AREs only), matches at any point where a
+substring matching \fIre\fR begins
+.TP
+\fB(?!\fIre\fB)\fR
+.
+\fInegative lookahead\fR (AREs only), matches at any point where no
+substring matching \fIre\fR begins
+.RE
+.PP
+The lookahead constraints may not contain back references (see later),
+and all parentheses within them are considered non-capturing.
+.PP
+An RE may not end with
+.QW \fB\e\fR .
+.SH "BRACKET EXPRESSIONS"
+A \fIbracket expression\fR is a list of characters enclosed in
+.QW \fB[\|]\fR .
+It normally matches any single character from the list
+(but see below). If the list begins with
+.QW \fB^\fR ,
+it matches any single character (but see below) \fInot\fR from the
+rest of the list.
+.PP
+If two characters in the list are separated by
+.QW \fB\-\fR ,
+this is shorthand for the full \fIrange\fR of characters between those two
+(inclusive) in the collating sequence, e.g.
+.QW \fB[0\-9]\fR
+in Unicode matches any conventional decimal digit. Two ranges may not share an
+endpoint, so e.g.
+.QW \fBa\-c\-e\fR
+is illegal. Ranges in Tcl always use the
+Unicode collating sequence, but other programs may use other collating
+sequences and this can be a source of incompatibility between programs.
+.PP
+To include a literal \fB]\fR or \fB\-\fR in the list, the simplest
+method is to enclose it in \fB[.\fR and \fB.]\fR to make it a
+collating element (see below). Alternatively, make it the first
+character (following a possible
+.QW \fB^\fR ),
+or (AREs only) precede it with
+.QW \fB\e\fR .
+Alternatively, for
+.QW \fB\-\fR ,
+make it the last character, or the second endpoint of a range. To use
+a literal \fB\-\fR as the first endpoint of a range, make it a
+collating element or (AREs only) precede it with
+.QW \fB\e\fR .
+With the exception of
+these, some combinations using \fB[\fR (see next paragraphs), and
+escapes, all other special characters lose their special significance
+within a bracket expression.
+.SS "CHARACTER CLASSES"
+Within a bracket expression, the name of a \fIcharacter class\fR
+enclosed in \fB[:\fR and \fB:]\fR stands for the list of all
+characters (not all collating elements!) belonging to that class.
+Standard character classes are:
+.IP \fBalpha\fR 8
+A letter.
+.IP \fBupper\fR 8
+An upper-case letter.
+.IP \fBlower\fR 8
+A lower-case letter.
+.IP \fBdigit\fR 8
+A decimal digit.
+.IP \fBxdigit\fR 8
+A hexadecimal digit.
+.IP \fBalnum\fR 8
+An alphanumeric (letter or digit).
+.IP \fBprint\fR 8
+A "printable" (same as graph, except also including space).
+.IP \fBblank\fR 8
+A space or tab character.
+.IP \fBspace\fR 8
+A character producing white space in displayed text.
+.IP \fBpunct\fR 8
+A punctuation character.
+.IP \fBgraph\fR 8
+A character with a visible representation (includes both \fBalnum\fR
+and \fBpunct\fR).
+.IP \fBcntrl\fR 8
+A control character.
+.PP
+A locale may provide others. A character class may not be used as an endpoint
+of a range.
+.RS
+.PP
+(\fINote:\fR the current Tcl implementation has only one locale, the Unicode
+locale, which supports exactly the above classes.)
+.RE
+.SS "BRACKETED CONSTRAINTS"
+There are two special cases of bracket expressions: the bracket
+expressions
+.QW \fB[[:<:]]\fR
+and
+.QW \fB[[:>:]]\fR
+are constraints, matching empty strings at the beginning and end of a word
+respectively.
+.\" note, discussion of escapes below references this definition of word
+A word is defined as a sequence of word characters that is neither preceded
+nor followed by word characters. A word character is an \fIalnum\fR character
+or an underscore
+.PQ \fB_\fR "" .
+These special bracket expressions are deprecated; users of AREs should use
+constraint escapes instead (see below).
+.SS "COLLATING ELEMENTS"
+Within a bracket expression, a collating element (a character, a
+multi-character sequence that collates as if it were a single
+character, or a collating-sequence name for either) enclosed in
+\fB[.\fR and \fB.]\fR stands for the sequence of characters of that
+collating element. The sequence is a single element of the bracket
+expression's list. A bracket expression in a locale that has
+multi-character collating elements can thus match more than one
+character. So (insidiously), a bracket expression that starts with
+\fB^\fR can match multi-character collating elements even if none of
+them appear in the bracket expression!
+.RS
+.PP
+(\fINote:\fR Tcl has no multi-character collating elements. This information
+is only for illustration.)
+.RE
+.PP
+For example, assume the collating sequence includes a \fBch\fR multi-character
+collating element. Then the RE
+.QW \fB[[.ch.]]*c\fR
+(zero or more
+.QW \fBch\fRs
+followed by
+.QW \fBc\fR )
+matches the first five characters of
+.QW \fBchchcc\fR .
+Also, the RE
+.QW \fB[^c]b\fR
+matches all of
+.QW \fBchb\fR
+(because
+.QW \fB[^c]\fR
+matches the multi-character
+.QW \fBch\fR ).
+.SS "EQUIVALENCE CLASSES"
+Within a bracket expression, a collating element enclosed in \fB[=\fR
+and \fB=]\fR is an equivalence class, standing for the sequences of
+characters of all collating elements equivalent to that one, including
+itself. (If there are no other equivalent collating elements, the
+treatment is as if the enclosing delimiters were
+.QW \fB[.\fR \&
+and
+.QW \fB.]\fR .)
+For example, if \fBo\fR and \fB\*(qo\fR are the members of an
+equivalence class, then
+.QW \fB[[=o=]]\fR ,
+.QW \fB[[=\*(qo=]]\fR ,
+and
+.QW \fB[o\*(qo]\fR \&
+are all synonymous. An equivalence class may not be an endpoint of a range.
+.RS
+.PP
+(\fINote:\fR Tcl implements only the Unicode locale. It does not define any
+equivalence classes. The examples above are just illustrations.)
+.RE
+.SH ESCAPES
+Escapes (AREs only), which begin with a \fB\e\fR followed by an
+alphanumeric character, come in several varieties: character entry,
+class shorthands, constraint escapes, and back references. A \fB\e\fR
+followed by an alphanumeric character but not constituting a valid
+escape is illegal in AREs. In EREs, there are no escapes: outside a
+bracket expression, a \fB\e\fR followed by an alphanumeric character
+merely stands for that character as an ordinary character, and inside
+a bracket expression, \fB\e\fR is an ordinary character. (The latter
+is the one actual incompatibility between EREs and AREs.)
+.SS "CHARACTER-ENTRY ESCAPES"
+Character-entry escapes (AREs only) exist to make it easier to specify
+non-printing and otherwise inconvenient characters in REs:
+.RS 2
+.TP 5
+\fB\ea\fR
+.
+alert (bell) character, as in C
+.TP
+\fB\eb\fR
+.
+backspace, as in C
+.TP
+\fB\eB\fR
+.
+synonym for \fB\e\fR to help reduce backslash doubling in some
+applications where there are multiple levels of backslash processing
+.TP
+\fB\ec\fIX\fR
+.
+(where \fIX\fR is any character) the character whose low-order 5 bits
+are the same as those of \fIX\fR, and whose other bits are all zero
+.TP
+\fB\ee\fR
+.
+the character whose collating-sequence name is
+.QW \fBESC\fR ,
+or failing that, the character with octal value 033
+.TP
+\fB\ef\fR
+.
+formfeed, as in C
+.TP
+\fB\en\fR
+.
+newline, as in C
+.TP
+\fB\er\fR
+.
+carriage return, as in C
+.TP
+\fB\et\fR
+.
+horizontal tab, as in C
+.TP
+\fB\eu\fIwxyz\fR
+.
+(where \fIwxyz\fR is one up to four hexadecimal digits) the Unicode
+character \fBU+\fIwxyz\fR in the local byte ordering
+.TP
+\fB\eU\fIstuvwxyz\fR
+.
+(where \fIstuvwxyz\fR is one up to eight hexadecimal digits) reserved
+for a Unicode extension up to 21 bits. The digits are parsed until the
+first non-hexadecimal character is encountered, the maximun of eight
+hexadecimal digits are reached, or an overflow would occur in the maximum
+value of \fBU+\fI10ffff\fR.
+.TP
+\fB\ev\fR
+.
+vertical tab, as in C are all available.
+.TP
+\fB\ex\fIhh\fR
+.
+(where \fIhh\fR is one or two hexadecimal digits) the character
+whose hexadecimal value is \fB0x\fIhh\fR.
+.TP
+\fB\e0\fR
+.
+the character whose value is \fB0\fR
+.TP
+\fB\e\fIxyz\fR
+.
+(where \fIxyz\fR is exactly three octal digits, and is not a \fIback
+reference\fR (see below)) the character whose octal value is
+\fB0\fIxyz\fR. The first digit must be in the range 0-3, otherwise
+the two-digit form is assumed.
+.TP
+\fB\e\fIxy\fR
+.
+(where \fIxy\fR is exactly two octal digits, and is not a \fIback
+reference\fR (see below)) the character whose octal value is
+\fB0\fIxy\fR
+.RE
+.PP
+Hexadecimal digits are
+.QR \fB0\fR \fB9\fR ,
+.QR \fBa\fR \fBf\fR ,
+and
+.QR \fBA\fR \fBF\fR .
+Octal digits are
+.QR \fB0\fR \fB7\fR .
+.PP
+The character-entry escapes are always taken as ordinary characters.
+For example, \fB\e135\fR is \fB]\fR in Unicode, but \fB\e135\fR does
+not terminate a bracket expression. Beware, however, that some
+applications (e.g., C compilers and the Tcl interpreter if the regular
+expression is not quoted with braces) interpret such sequences
+themselves before the regular-expression package gets to see them,
+which may require doubling (quadrupling, etc.) the
+.QW \fB\e\fR .
+.SS "CLASS-SHORTHAND ESCAPES"
+Class-shorthand escapes (AREs only) provide shorthands for certain
+commonly-used character classes:
+.RS 2
+.TP 10
+\fB\ed\fR
+.
+\fB[[:digit:]]\fR
+.TP
+\fB\es\fR
+.
+\fB[[:space:]]\fR
+.TP
+\fB\ew\fR
+.
+\fB[[:alnum:]_]\fR (note underscore)
+.TP
+\fB\eD\fR
+.
+\fB[^[:digit:]]\fR
+.TP
+\fB\eS\fR
+.
+\fB[^[:space:]]\fR
+.TP
+\fB\eW\fR
+.
+\fB[^[:alnum:]_]\fR (note underscore)
+.RE
+.PP
+Within bracket expressions,
+.QW \fB\ed\fR ,
+.QW \fB\es\fR ,
+and
+.QW \fB\ew\fR \&
+lose their outer brackets, and
+.QW \fB\eD\fR ,
+.QW \fB\eS\fR ,
+and
+.QW \fB\eW\fR \&
+are illegal. (So, for example,
+.QW \fB[a-c\ed]\fR
+is equivalent to
+.QW \fB[a-c[:digit:]]\fR .
+Also,
+.QW \fB[a-c\eD]\fR ,
+which is equivalent to
+.QW \fB[a-c^[:digit:]]\fR ,
+is illegal.)
+.SS "CONSTRAINT ESCAPES"
+A constraint escape (AREs only) is a constraint, matching the empty
+string if specific conditions are met, written as an escape:
+.RS 2
+.TP 6
+\fB\eA\fR
+.
+matches only at the beginning of the string (see \fBMATCHING\fR,
+below, for how this differs from
+.QW \fB^\fR )
+.TP
+\fB\em\fR
+.
+matches only at the beginning of a word
+.TP
+\fB\eM\fR
+.
+matches only at the end of a word
+.TP
+\fB\ey\fR
+.
+matches only at the beginning or end of a word
+.TP
+\fB\eY\fR
+.
+matches only at a point that is not the beginning or end of a word
+.TP
+\fB\eZ\fR
+.
+matches only at the end of the string (see \fBMATCHING\fR, below, for
+how this differs from
+.QW \fB$\fR )
+.TP
+\fB\e\fIm\fR
+.
+(where \fIm\fR is a nonzero digit) a \fIback reference\fR, see below
+.TP
+\fB\e\fImnn\fR
+.
+(where \fIm\fR is a nonzero digit, and \fInn\fR is some more digits,
+and the decimal value \fImnn\fR is not greater than the number of
+closing capturing parentheses seen so far) a \fIback reference\fR, see
+below
+.RE
+.PP
+A word is defined as in the specification of
+.QW \fB[[:<:]]\fR
+and
+.QW \fB[[:>:]]\fR
+above. Constraint escapes are illegal within bracket expressions.
+.SS "BACK REFERENCES"
+A back reference (AREs only) matches the same string matched by the
+parenthesized subexpression specified by the number, so that (e.g.)
+.QW \fB([bc])\e1\fR
+matches
+.QW \fBbb\fR
+or
+.QW \fBcc\fR
+but not
+.QW \fBbc\fR .
+The subexpression must entirely precede the back reference in the RE.
+Subexpressions are numbered in the order of their leading parentheses.
+Non-capturing parentheses do not define subexpressions.
+.PP
+There is an inherent historical ambiguity between octal
+character-entry escapes and back references, which is resolved by
+heuristics, as hinted at above. A leading zero always indicates an
+octal escape. A single non-zero digit, not followed by another digit,
+is always taken as a back reference. A multi-digit sequence not
+starting with a zero is taken as a back reference if it comes after a
+suitable subexpression (i.e. the number is in the legal range for a
+back reference), and otherwise is taken as octal.
+.SH "METASYNTAX"
+In addition to the main syntax described above, there are some special
+forms and miscellaneous syntactic facilities available.
+.PP
+Normally the flavor of RE being used is specified by
+application-dependent means. However, this can be overridden by a
+\fIdirector\fR. If an RE of any flavor begins with
+.QW \fB***:\fR ,
+the rest of the RE is an ARE. If an RE of any flavor begins with
+.QW \fB***=\fR ,
+the rest of the RE is taken to be a literal string, with
+all characters considered ordinary characters.
+.PP
+An ARE may begin with \fIembedded options\fR: a sequence
+\fB(?\fIxyz\fB)\fR (where \fIxyz\fR is one or more alphabetic
+characters) specifies options affecting the rest of the RE. These
+supplement, and can override, any options specified by the
+application. The available option letters are:
+.RS 2
+.TP 3
+\fBb\fR
+.
+rest of RE is a BRE
+.TP 3
+\fBc\fR
+.
+case-sensitive matching (usual default)
+.TP 3
+\fBe\fR
+.
+rest of RE is an ERE
+.TP 3
+\fBi\fR
+.
+case-insensitive matching (see \fBMATCHING\fR, below)
+.TP 3
+\fBm\fR
+.
+historical synonym for \fBn\fR
+.TP 3
+\fBn\fR
+.
+newline-sensitive matching (see \fBMATCHING\fR, below)
+.TP 3
+\fBp\fR
+.
+partial newline-sensitive matching (see \fBMATCHING\fR, below)
+.TP 3
+\fBq\fR
+.
+rest of RE is a literal
+.PQ quoted
+string, all ordinary characters
+.TP 3
+\fBs\fR
+.
+non-newline-sensitive matching (usual default)
+.TP 3
+\fBt\fR
+.
+tight syntax (usual default; see below)
+.TP 3
+\fBw\fR
+.
+inverse partial newline-sensitive
+.PQ weird
+matching (see \fBMATCHING\fR, below)
+.TP 3
+\fBx\fR
+.
+expanded syntax (see below)
+.RE
+.PP
+Embedded options take effect at the \fB)\fR terminating the sequence.
+They are available only at the start of an ARE, and may not be used
+later within it.
+.PP
+In addition to the usual (\fItight\fR) RE syntax, in which all
+characters are significant, there is an \fIexpanded\fR syntax,
+available in all flavors of RE with the \fB\-expanded\fR switch, or in
+AREs with the embedded x option. In the expanded syntax, white-space
+characters are ignored and all characters between a \fB#\fR and the
+following newline (or the end of the RE) are ignored, permitting
+paragraphing and commenting a complex RE. There are three exceptions
+to that basic rule:
+.IP \(bu 3
+a white-space character or
+.QW \fB#\fR
+preceded by
+.QW \fB\e\fR
+is retained
+.IP \(bu 3
+white space or
+.QW \fB#\fR
+within a bracket expression is retained
+.IP \(bu 3
+white space and comments are illegal within multi-character symbols
+like the ARE
+.QW \fB(?:\fR
+or the BRE
+.QW \fB\e(\fR
+.PP
+Expanded-syntax white-space characters are blank, tab, newline, and
+any character that belongs to the \fIspace\fR character class.
+.PP
+Finally, in an ARE, outside bracket expressions, the sequence
+.QW \fB(?#\fIttt\fB)\fR
+(where \fIttt\fR is any text not containing a
+.QW \fB)\fR )
+is a comment, completely ignored. Again, this is not
+allowed between the characters of multi-character symbols like
+.QW \fB(?:\fR .
+Such comments are more a historical artifact than a useful facility,
+and their use is deprecated; use the expanded syntax instead.
+.PP
+\fINone\fR of these metasyntax extensions is available if the
+application (or an initial
+.QW \fB***=\fR
+director) has specified that the
+user's input be treated as a literal string rather than as an RE.
+.SH MATCHING
+In the event that an RE could match more than one substring of a given
+string, the RE matches the one starting earliest in the string. If
+the RE could match more than one substring starting at that point, its
+choice is determined by its \fIpreference\fR: either the longest
+substring, or the shortest.
+.PP
+Most atoms, and all constraints, have no preference. A parenthesized
+RE has the same preference (possibly none) as the RE. A quantified
+atom with quantifier \fB{\fIm\fB}\fR or \fB{\fIm\fB}?\fR has the same
+preference (possibly none) as the atom itself. A quantified atom with
+other normal quantifiers (including \fB{\fIm\fB,\fIn\fB}\fR with
+\fIm\fR equal to \fIn\fR) prefers longest match. A quantified atom
+with other non-greedy quantifiers (including \fB{\fIm\fB,\fIn\fB}?\fR
+with \fIm\fR equal to \fIn\fR) prefers shortest match. A branch has
+the same preference as the first quantified atom in it which has a
+preference. An RE consisting of two or more branches connected by the
+\fB|\fR operator prefers longest match.
+.PP
+Subject to the constraints imposed by the rules for matching the whole
+RE, subexpressions also match the longest or shortest possible
+substrings, based on their preferences, with subexpressions starting
+earlier in the RE taking priority over ones starting later. Note that
+outer subexpressions thus take priority over their component
+subexpressions.
+.PP
+The quantifiers \fB{1,1}\fR and \fB{1,1}?\fR can be used to
+force longest and shortest preference, respectively, on a
+subexpression or a whole RE.
+.RS
+.PP
+\fBNOTE:\fR This means that you can usually make a RE be non-greedy overall by
+putting \fB{1,1}?\fR after one of the first non-constraint atoms or
+parenthesized sub-expressions in it. \fIIt pays to experiment\fR with the
+placing of this non-greediness override on a suitable range of input texts
+when you are writing a RE if you are using this level of complexity.
+.PP
+For example, this regular expression is non-greedy, and will match the
+shortest substring possible given that
+.QW \fBabc\fR
+will be matched as early as possible (the quantifier does not change that):
+.PP
+.CS
+ab{1,1}?c.*x.*cba
+.CE
+.PP
+The atom
+.QW \fBa\fR
+has no greediness preference, we explicitly give one for
+.QW \fBb\fR ,
+and the remaining quantifiers are overridden to be non-greedy by the preceding
+non-greedy quantifier.
+.RE
+.PP
+Match lengths are measured in characters, not collating elements. An
+empty string is considered longer than no match at all. For example,
+.QW \fBbb*\fR
+matches the three middle characters of
+.QW \fBabbbc\fR ,
+.QW \fB(week|wee)(night|knights)\fR
+matches all ten characters of
+.QW \fBweeknights\fR ,
+when
+.QW \fB(.*).*\fR
+is matched against
+.QW \fBabc\fR
+the parenthesized subexpression matches all three characters, and when
+.QW \fB(a*)*\fR
+is matched against
+.QW \fBbc\fR
+both the whole RE and the parenthesized subexpression match an empty string.
+.PP
+If case-independent matching is specified, the effect is much as if
+all case distinctions had vanished from the alphabet. When an
+alphabetic that exists in multiple cases appears as an ordinary
+character outside a bracket expression, it is effectively transformed
+into a bracket expression containing both cases, so that \fBx\fR
+becomes
+.QW \fB[xX]\fR .
+When it appears inside a bracket expression,
+all case counterparts of it are added to the bracket expression, so
+that
+.QW \fB[x]\fR
+becomes
+.QW \fB[xX]\fR
+and
+.QW \fB[^x]\fR
+becomes
+.QW \fB[^xX]\fR .
+.PP
+If newline-sensitive matching is specified, \fB.\fR and bracket
+expressions using \fB^\fR will never match the newline character (so
+that matches will never cross newlines unless the RE explicitly
+arranges it) and \fB^\fR and \fB$\fR will match the empty string after
+and before a newline respectively, in addition to matching at
+beginning and end of string respectively. ARE \fB\eA\fR and \fB\eZ\fR
+continue to match beginning or end of string \fIonly\fR.
+.PP
+If partial newline-sensitive matching is specified, this affects
+\fB.\fR and bracket expressions as with newline-sensitive matching,
+but not \fB^\fR and \fB$\fR.
+.PP
+If inverse partial newline-sensitive matching is specified, this
+affects \fB^\fR and \fB$\fR as with newline-sensitive matching, but
+not \fB.\fR and bracket expressions. This is not very useful but is
+provided for symmetry.
+.SH "LIMITS AND COMPATIBILITY"
+No particular limit is imposed on the length of REs. Programs
+intended to be highly portable should not employ REs longer than 256
+bytes, as a POSIX-compliant implementation can refuse to accept such
+REs.
+.PP
+The only feature of AREs that is actually incompatible with POSIX EREs
+is that \fB\e\fR does not lose its special significance inside bracket
+expressions. All other ARE features use syntax which is illegal or
+has undefined or unspecified effects in POSIX EREs; the \fB***\fR
+syntax of directors likewise is outside the POSIX syntax for both BREs
+and EREs.
+.PP
+Many of the ARE extensions are borrowed from Perl, but some have been
+changed to clean them up, and a few Perl extensions are not present.
+Incompatibilities of note include
+.QW \fB\eb\fR ,
+.QW \fB\eB\fR ,
+the lack of special treatment for a trailing newline, the addition of
+complemented bracket expressions to the things affected by
+newline-sensitive matching, the restrictions on parentheses and back
+references in lookahead constraints, and the longest/shortest-match
+(rather than first-match) matching semantics.
+.PP
+The matching rules for REs containing both normal and non-greedy
+quantifiers have changed since early beta-test versions of this
+package. (The new rules are much simpler and cleaner, but do not work
+as hard at guessing the user's real intentions.)
+.PP
+Henry Spencer's original 1986 \fIregexp\fR package, still in
+widespread use (e.g., in pre-8.1 releases of Tcl), implemented an
+early version of today's EREs. There are four incompatibilities
+between \fIregexp\fR's near-EREs
+.PQ RREs " for short"
+and AREs. In roughly increasing order of significance:
+.IP \(bu 3
+In AREs, \fB\e\fR followed by an alphanumeric character is either an
+escape or an error, while in RREs, it was just another way of writing
+the alphanumeric. This should not be a problem because there was no
+reason to write such a sequence in RREs.
+.IP \(bu 3
+\fB{\fR followed by a digit in an ARE is the beginning of a bound,
+while in RREs, \fB{\fR was always an ordinary character. Such
+sequences should be rare, and will often result in an error because
+following characters will not look like a valid bound.
+.IP \(bu 3
+In AREs, \fB\e\fR remains a special character within
+.QW \fB[\|]\fR ,
+so a literal \fB\e\fR within \fB[\|]\fR must be written
+.QW \fB\e\e\fR .
+\fB\e\e\fR also gives a literal \fB\e\fR within \fB[\|]\fR in RREs,
+but only truly paranoid programmers routinely doubled the backslash.
+.IP \(bu 3
+AREs report the longest/shortest match for the RE, rather than the
+first found in a specified search order. This may affect some RREs
+which were written in the expectation that the first match would be
+reported. (The careful crafting of RREs to optimize the search order
+for fast matching is obsolete (AREs examine all possible matches in
+parallel, and their performance is largely insensitive to their
+complexity) but cases where the search order was exploited to
+deliberately find a match which was \fInot\fR the longest/shortest
+will need rewriting.)
+.SH "BASIC REGULAR EXPRESSIONS"
+BREs differ from EREs in several respects.
+.QW \fB|\fR ,
+.QW \fB+\fR ,
+and \fB?\fR are ordinary characters and there is no equivalent for their
+functionality. The delimiters for bounds are \fB\e{\fR and
+.QW \fB\e}\fR ,
+with \fB{\fR and \fB}\fR by themselves ordinary characters. The
+parentheses for nested subexpressions are \fB\e(\fR and
+.QW \fB\e)\fR ,
+with \fB(\fR and \fB)\fR by themselves ordinary
+characters. \fB^\fR is an ordinary character except at the beginning
+of the RE or the beginning of a parenthesized subexpression, \fB$\fR
+is an ordinary character except at the end of the RE or the end of a
+parenthesized subexpression, and \fB*\fR is an ordinary character if
+it appears at the beginning of the RE or the beginning of a
+parenthesized subexpression (after a possible leading
+.QW \fB^\fR ).
+Finally, single-digit back references are available, and \fB\e<\fR and
+\fB\e>\fR are synonyms for
+.QW \fB[[:<:]]\fR
+and
+.QW \fB[[:>:]]\fR
+respectively; no other escapes are available.
+.SH "SEE ALSO"
+RegExp(3), regexp(n), regsub(n), lsearch(n), switch(n), text(n)
+.SH KEYWORDS
+match, regular expression, string
+.\" Local Variables:
+.\" mode: nroff
+.\" End:
diff --git a/doc/read.n b/doc/read.n
new file mode 100644
index 0000000..9a9a7e8
--- /dev/null
+++ b/doc/read.n
@@ -0,0 +1,89 @@
+'\"
+'\" Copyright (c) 1993 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH read n 8.1 Tcl "Tcl Built-In Commands"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+read \- Read from a channel
+.SH SYNOPSIS
+\fBread \fR?\fB\-nonewline\fR? \fIchannelId\fR
+.sp
+\fBread \fIchannelId numChars\fR
+.BE
+.SH DESCRIPTION
+.PP
+In the first form, the \fBread\fR command reads all of the data from
+\fIchannelId\fR up to the end of the file.  If the \fB\-nonewline\fR
+switch is specified then the last character of the file is discarded
+if it is a newline.  In the second form, the extra argument specifies
+how many characters to read.  Exactly that many characters will be
+read and returned, unless there are fewer than \fInumChars\fR left in
+the file; in this case all the remaining characters are returned.  If
+the channel is configured to use a multi-byte encoding, then the
+number of characters read may not be the same as the number of bytes
+read.
+.PP
+\fIChannelId\fR must be an identifier for an open channel such as the
+Tcl standard input channel (\fBstdin\fR), the return value from an
+invocation of \fBopen\fR or \fBsocket\fR, or the result of a channel
+creation command provided by a Tcl extension. The channel must have
+been opened for input.
+.PP
+If \fIchannelId\fR is in nonblocking mode, the command may not read as
+many characters as requested: once all available input has been read,
+the command will return the data that is available rather than
+blocking for more input.  If the channel is configured to use a
+multi-byte encoding, then there may actually be some bytes remaining
+in the internal buffers that do not form a complete character.  These
+bytes will not be returned until a complete character is available or
+end-of-file is reached.  The \fB\-nonewline\fR switch is ignored if
+the command returns before reaching the end of the file.
+.PP
+\fBRead\fR translates end-of-line sequences in the input into
+newline characters according to the \fB\-translation\fR option
+for the channel.
+See the \fBfconfigure\fR manual entry for a discussion on ways in
+which \fBfconfigure\fR will alter input.
+.SH "USE WITH SERIAL PORTS"
+'\" Note:  this advice actually applies to many versions of Tcl
+.PP
+For most applications a channel connected to a serial port should be
+configured to be nonblocking: \fBfconfigure\fI channelId \fB\-blocking
+\fI0\fR.  Then \fBread\fR behaves much like described above.  Care
+must be taken when using \fBread\fR on blocking serial ports:
+.TP
+\fBread \fIchannelId numChars\fR
+.
+In this form \fBread\fR blocks until \fInumChars\fR have been received
+from the serial port.
+.TP
+\fBread \fIchannelId\fR
+.
+In this form \fBread\fR blocks until the reception of the end-of-file
+character, see \fBfconfigure\fR \fB\-eofchar\fR. If there no end-of-file
+character has been configured for the channel, then \fBread\fR will
+block forever.
+.SH "EXAMPLE"
+.PP
+This example code reads a file all at once, and splits it into a list,
+with each line in the file corresponding to an element in the list:
+.PP
+.CS
+set fl [open /proc/meminfo]
+set data [\fBread\fR $fl]
+close $fl
+set lines [split $data \en]
+.CE
+.SH "SEE ALSO"
+file(n), eof(n), fblocked(n), fconfigure(n), Tcl_StandardChannels(3)
+.SH KEYWORDS
+blocking, channel, end of line, end of file, nonblocking, read, translation, encoding
+'\"Local Variables:
+'\"mode: nroff
+'\"End:
diff --git a/doc/refchan.n b/doc/refchan.n
new file mode 100644
index 0000000..2232d50
--- /dev/null
+++ b/doc/refchan.n
@@ -0,0 +1,411 @@
+'\" 
+'\" Copyright (c) 2006 Andreas Kupries <andreas_kupries@users.sourceforge.net>
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH refchan n 8.5 Tcl "Tcl Built-In Commands"
+.so man.macros
+.BS
+.\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+refchan \- command handler API of reflected channels
+.SH SYNOPSIS
+\fBcmdPrefix \fIoption\fR ?\fIarg arg ...\fR?
+.BE
+.SH DESCRIPTION
+.PP
+The Tcl-level handler for a reflected channel has to be a command with
+subcommands (termed an \fIensemble\fR, as it is a command such as that
+created by \fBnamespace ensemble\fR \fBcreate\fR, though the implementation
+of handlers for reflected channel \fIis not\fR tied to \fBnamespace
+ensemble\fRs in any way; see \fBEXAMPLE\fR below for how to build an
+\fBoo::class\fR that supports the API). Note that \fIcmdPrefix\fR is whatever was
+specified in the call to \fBchan create\fR, and may consist of
+multiple arguments; this will be expanded to multiple words in place
+of the prefix.
+.PP
+Of all the possible subcommands, the handler \fImust\fR support
+\fBinitialize\fR, \fBfinalize\fR, and \fBwatch\fR. Support for the
+other subcommands is optional.
+.SS "MANDATORY SUBCOMMANDS"
+.TP
+\fIcmdPrefix \fBinitialize \fIchannelId mode\fR
+.
+An invocation of this subcommand will be the first call the
+\fIcmdPrefix\fR will receive for the specified new \fIchannelId\fR. It
+is the responsibility of this subcommand to set up any internal data
+structures required to keep track of the channel and its state.
+.RS
+.PP
+The return value of the method has to be a list containing the names
+of all subcommands supported by the \fIcmdPrefix\fR. This also tells
+the Tcl core which version of the API for reflected channels is used by
+this command handler.
+.PP
+Any error thrown by the method will abort the creation of the channel
+and no channel will be created. The thrown error will appear as error
+thrown by \fBchan create\fR. Any exception other than an \fBerror\fR
+(e.g.,\ \fBbreak\fR, etc.) is treated as (and converted to) an error.
+.PP
+\fBNote:\fR If the creation of the channel was aborted due to failures
+here, then the \fBfinalize\fR subcommand will not be called.
+.PP
+The \fImode\fR argument tells the handler whether the channel was
+opened for reading, writing, or both. It is a list containing any of
+the strings \fBread\fR or \fBwrite\fR. The list will always
+contain at least one element.
+.PP
+The subcommand must throw an error if the chosen mode is not
+supported by the \fIcmdPrefix\fR.
+.RE
+.TP
+\fIcmdPrefix \fBfinalize \fIchannelId\fR
+.
+An invocation of this subcommand will be the last call the
+\fIcmdPrefix\fR will receive for the specified \fIchannelId\fR. It will
+be generated just before the destruction of the data structures of the
+channel held by the Tcl core. The command handler \fImust not\fR
+access the \fIchannelId\fR anymore in no way. Upon this subcommand being
+called, any internal resources allocated to this channel must be
+cleaned up.
+.RS
+.PP
+The return value of this subcommand is ignored.
+.PP
+If the subcommand throws an error the command which caused its
+invocation (usually \fBchan close\fR) will appear to have thrown this
+error. Any exception beyond \fBerror\fR (e.g.,\ \fBbreak\fR, etc.) is
+treated as (and converted to) an error.
+.PP
+This subcommand is not invoked if the creation of the channel was
+aborted during \fBinitialize\fR (See above).
+.RE
+.TP
+\fIcmdPrefix \fBwatch \fIchannelId eventspec\fR
+.
+This subcommand notifies the \fIcmdPrefix\fR that the specified
+\fIchannelId\fR is interested in the events listed in the
+\fIeventspec\fR. This argument is a list containing any of \fBread\fR
+and \fBwrite\fR. The list may be empty, which signals that the
+channel does not wish to be notified of any events. In that situation,
+the handler should disable event generation completely.
+.RS
+.PP
+\fBWarning:\fR Any return value of the subcommand is ignored. This
+includes all errors thrown by the subcommand, \fBbreak\fR, \fBcontinue\fR, and
+custom return codes.
+.PP
+This subcommand interacts with \fBchan postevent\fR. Trying to post an
+event which was not listed in the last call to \fBwatch\fR will cause
+\fBchan postevent\fR to throw an error.
+.RE
+.SS "OPTIONAL SUBCOMMANDS"
+.TP
+\fIcmdPrefix \fBread \fIchannelId count\fR
+.
+This \fIoptional\fR subcommand is called when the user requests data from the
+channel \fIchannelId\fR. \fIcount\fR specifies how many \fIbytes\fR have been
+requested. If the subcommand is not supported then it is not possible to read
+from the channel handled by the command.
+.RS
+.PP
+The return value of this subcommand is taken as the requested data
+\fIbytes\fR. If the returned data contains more bytes than requested,
+an error will be signaled and later thrown by the command which
+performed the read (usually \fBgets\fR or \fBread\fR). However,
+returning fewer bytes than requested is acceptable.
+.PP
+Note that returning nothing (0 bytes) is a signal to the higher layers
+that \fBEOF\fR has been reached on the channel. To signal that the
+channel is out of data right now, but has not yet reached \fBEOF\fR,
+it is necessary to throw the error "EAGAIN", i.e. to either
+.PP
+.CS
+return -code error EAGAIN
+.CE
+or
+.CS
+error EAGAIN
+.CE
+.PP
+For extensibility any error whose value is a negative integer number
+will cause the higher layers to set the C-level variable "\fBerrno\fR"
+to the absolute value of this number, signaling a system error.
+However, note that the exact mapping between these error numbers and
+their meanings is operating system dependent.
+.PP
+For example, while on Linux both
+.PP
+.CS
+return -code error -11
+.CE
+and
+.CS
+error -11
+.CE
+.PP
+are equivalent to the examples above, using the more readable string "EAGAIN",
+this is not true for BSD, where the equivalent number is -35.
+.PP
+The symbolic string however is the same across systems, and internally
+translated to the correct number. No other error value has such a mapping
+to a symbolic string.
+.PP
+If the subcommand throws any other error, the command which caused its
+invocation (usually \fBgets\fR, or \fBread\fR) will appear to have
+thrown this error. Any exception beyond \fBerror\fR, (e.g.,\ \fBbreak\fR,
+etc.) is treated as and converted to an error.
+.RE
+.TP
+\fIcmdPrefix \fBwrite \fIchannelId data\fR
+.
+This \fIoptional\fR subcommand is called when the user writes data to
+the channel \fIchannelId\fR. The \fIdata\fR argument contains \fIbytes\fR, not
+characters. Any type of transformation (EOL, encoding) configured for
+the channel has already been applied at this point. If this subcommand
+is not supported then it is not possible to write to the channel
+handled by the command.
+.RS
+.PP
+The return value of the subcommand is taken as the number of bytes
+written by the channel. Anything non-numeric will cause an error to be
+signaled and later thrown by the command which performed the write. A
+negative value implies that the write failed. Returning a value
+greater than the number of bytes given to the handler, or zero, is
+forbidden and will cause the Tcl core to throw an error.
+.PP
+To signal that the channel is not able to accept data for writing
+right now, it is necessary to throw the error "EAGAIN", i.e. to either
+.PP
+.CS
+return -code error EAGAIN
+.CE
+or
+.CS
+error EAGAIN
+.CE
+.PP
+For extensibility any error whose value is a negative integer number
+will cause the higher layers to set the C-level variable "\fBerrno\fR"
+to the absolute value of this number, signaling a system error.
+However, note that the exact mapping between these error numbers and
+their meanings is operating system dependent.
+.PP
+For example, while on Linux both
+.PP
+.CS
+return -code error -11
+.CE
+and
+.CS
+error -11
+.CE
+.PP
+are equivalent to the examples above, using the more readable string "EAGAIN",
+this is not true for BSD, where the equivalent number is -35.
+.PP
+The symbolic string however is the same across systems, and internally
+translated to the correct number. No other error value has such a mapping
+to a symbolic string.
+.PP
+If the subcommand throws any other error the command which caused its
+invocation (usually \fBputs\fR) will appear to have thrown this error.
+Any exception beyond \fBerror\fR (e.g.,\ \fBbreak\fR, etc.) is treated
+as and converted to an error.
+.RE
+.TP
+\fIcmdPrefix \fBseek \fIchannelId offset base\fR
+.
+This \fIoptional\fR subcommand is responsible for the handling of
+\fBchan seek\fR and \fBchan tell\fR requests on the channel
+\fIchannelId\fR. If it is not supported then seeking will not be possible for
+the channel.
+.RS
+.PP
+The \fIbase\fR argument is the same as the equivalent argument of the
+builtin \fBchan seek\fR, namely:
+.TP 10
+\fBstart\fR
+.
+Seeking is relative to the beginning of the channel.
+.TP 10
+\fBcurrent\fR
+.
+Seeking is relative to the current seek position.
+.TP 10
+\fBend\fR
+.
+Seeking is relative to the end of the channel.
+.PP
+The \fIoffset\fR is an integer number specifying the amount of
+\fBbytes\fR to seek forward or backward. A positive number should seek
+forward, and a negative number should seek backward.
+A channel may provide only limited seeking. For example sockets can
+seek forward, but not backward.
+.PP
+The return value of the subcommand is taken as the (new) location of
+the channel, counted from the start. This has to be an integer number
+greater than or equal to zero.
+If the subcommand throws an error the command which caused its
+invocation (usually \fBchan seek\fR, or \fBchan tell\fR) will appear to have
+thrown this error. Any exception beyond \fBerror\fR (e.g.,\ \fBbreak\fR,
+etc.) is treated as and converted to an error.
+.PP
+The offset/base combination of 0/\fBcurrent\fR signals a \fBchan tell\fR
+request, i.e.,\ seek nothing relative to the current location, making
+the new location identical to the current one, which is then returned.
+.RE
+.TP
+\fIcmdPrefix \fBconfigure \fIchannelId option value\fR
+.
+This \fIoptional\fR subcommand is for setting the type-specific options of
+channel \fIchannelId\fR. The \fIoption\fR argument indicates the option to be
+written, and the \fIvalue\fR argument indicates the value to set the option to.
+.RS
+.PP
+This subcommand will never try to update more than one option at a
+time; that is behavior implemented in the Tcl channel core.
+.PP
+The return value of the subcommand is ignored.
+.PP
+If the subcommand throws an error the command which performed the
+(re)configuration or query (usually \fBfconfigure\fR or
+\fBchan configure\fR) will appear to have thrown this error. Any exception
+beyond \fBerror\fR (e.g.,\ \fBbreak\fR, etc.) is treated as and
+converted to an error.
+.RE
+.TP
+\fIcmdPrefix \fBcget \fIchannelId option\fR
+.
+This \fIoptional\fR subcommand is used when reading a single type-specific
+option of channel \fIchannelId\fR. If this subcommand is supported then the
+subcommand \fBcgetall\fR must be supported as well.
+.RS
+.PP
+The subcommand should return the value of the specified \fIoption\fR.
+.PP
+If the subcommand throws an error, the command which performed the
+(re)configuration or query (usually \fBfconfigure\fR or \fBchan configure\fR)
+will appear to have thrown this error. Any exception beyond \fIerror\fR
+(e.g.,\ \fBbreak\fR, etc.) is treated as and converted to an error.
+.RE
+.TP
+\fIcmdPrefix \fBcgetall \fIchannelId\fR
+.
+This \fIoptional\fR subcommand is used for reading all type-specific options
+of channel \fIchannelId\fR. If this subcommand is supported then the
+subcommand \fBcget\fR has to be supported as well.
+.RS
+.PP
+The subcommand should return a list of all options and their values.
+This list must have an even number of elements.
+.PP
+If the subcommand throws an error the command which performed the
+(re)configuration or query (usually \fBfconfigure\fR or \fBchan configure\fR)
+will appear to have thrown this error. Any exception beyond \fBerror\fR
+(e.g.,\ \fBbreak\fR, etc.) is treated as and converted to an error.
+.RE
+.TP
+\fIcmdPrefix \fBblocking \fIchannelId mode\fR
+.
+This \fIoptional\fR subcommand handles changes to the blocking mode of the
+channel \fIchannelId\fR. The \fImode\fR is a boolean flag. A true value means
+that the channel has to be set to blocking, and a false value means that the
+channel should be non-blocking.
+.RS
+.PP
+The return value of the subcommand is ignored.
+.PP
+If the subcommand throws an error the command which caused its
+invocation (usually \fBfconfigure\fR or \fBchan configure\fR) will appear to
+have thrown this error. Any exception beyond \fBerror\fR (e.g.,\ \fBbreak\fR,
+etc.) is treated as and converted to an error.
+.RE
+.SH NOTES
+Some of the functions supported in channels defined in Tcl's C
+interface are not available to channels reflected to the Tcl level.
+.PP
+The function \fBTcl_DriverGetHandleProc\fR is not supported;
+i.e.,\ reflected channels do not have OS specific handles.
+.PP
+The function \fBTcl_DriverHandlerProc\fR is not supported. This driver
+function is relevant only for stacked channels, i.e.,\ transformations.
+Reflected channels are always base channels, not transformations.
+.PP
+The function \fBTcl_DriverFlushProc\fR is not supported. This is
+because the current generic I/O layer of Tcl does not use this
+function anywhere at all. Therefore support at the Tcl level makes no
+sense either. This may be altered in the future (through extending the
+API defined here and changing its version number) should the function
+be used at some time in the future.
+.SH EXAMPLE
+.PP
+This demonstrates how to make a channel that reads from a string.
+.PP
+.CS
+oo::class create stringchan {
+    variable data pos
+    constructor {string {encoding {}}} {
+        if {$encoding eq ""} {set encoding [encoding system]}
+        set data [encoding convertto $encoding $string]
+        set pos 0
+    }
+
+    method \fBinitialize\fR {ch mode} {
+        return "initialize finalize watch read seek"
+    }
+    method \fBfinalize\fR {ch} {
+        my destroy
+    }
+    method \fBwatch\fR {ch events} {
+        # Must be present but we ignore it because we do not
+        # post any events
+    }
+
+    # Must be present on a readable channel
+    method \fBread\fR {ch count} {
+        set d [string range $data $pos [expr {$pos+$count-1}]]
+        incr pos [string length $d]
+        return $d
+    }
+
+    # This method is optional, but useful for the example below
+    method \fBseek\fR {ch offset base} {
+        switch $base {
+            start {
+                set pos $offset
+            }
+            current {
+                incr pos $offset
+            }
+            end {
+                set pos [string length $data]
+                incr pos $offset
+            }
+        }
+        if {$pos < 0} {
+            set pos 0
+        } elseif {$pos > [string length $data]} {
+            set pos [string length $data]
+        }
+        return $pos
+    }
+}
+
+# Now we create an instance...
+set string "The quick brown fox jumps over the lazy dog.\\n"
+set ch [\fBchan create\fR read [stringchan new $string]]
+
+puts [gets $ch];   # Prints the whole string
+
+seek $ch -5 end;
+puts [read $ch];   # Prints just the last word
+.CE
+.SH "SEE ALSO"
+chan(n), transchan(n)
+.SH KEYWORDS
+API, channel, ensemble, prefix, reflection
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/doc/regexp.n b/doc/regexp.n
new file mode 100644
index 0000000..6f303a4
--- /dev/null
+++ b/doc/regexp.n
@@ -0,0 +1,208 @@
+'\"
+'\" Copyright (c) 1998 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH regexp n 8.3 Tcl "Tcl Built-In Commands"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+regexp \- Match a regular expression against a string
+.SH SYNOPSIS
+\fBregexp \fR?\fIswitches\fR? \fIexp string \fR?\fImatchVar\fR? ?\fIsubMatchVar subMatchVar ...\fR?
+.BE
+.SH DESCRIPTION
+.PP
+Determines whether the regular expression \fIexp\fR matches part or
+all of \fIstring\fR and returns 1 if it does, 0 if it does not, unless
+\fB\-inline\fR is specified (see below).
+(Regular expression matching is described in the \fBre_syntax\fR
+reference page.)
+.PP
+If additional arguments are specified after \fIstring\fR then they
+are treated as the names of variables in which to return
+information about which part(s) of \fIstring\fR matched \fIexp\fR.
+\fIMatchVar\fR will be set to the range of \fIstring\fR that
+matched all of \fIexp\fR.  The first \fIsubMatchVar\fR will contain
+the characters in \fIstring\fR that matched the leftmost parenthesized
+subexpression within \fIexp\fR, the next \fIsubMatchVar\fR will
+contain the characters that matched the next parenthesized
+subexpression to the right in \fIexp\fR, and so on.
+.PP
+If the initial arguments to \fBregexp\fR start with \fB\-\fR then
+they are treated as switches.  The following switches are
+currently supported:
+.TP 15
+\fB\-about\fR
+.
+Instead of attempting to match the regular expression, returns a list
+containing information about the regular expression.  The first
+element of the list is a subexpression count.  The second element is a
+list of property names that describe various attributes of the regular
+expression. This switch is primarily intended for debugging purposes.
+.TP 15
+\fB\-expanded\fR
+.
+Enables use of the expanded regular expression syntax where
+whitespace and comments are ignored.  This is the same as specifying
+the \fB(?x)\fR embedded option (see the \fBre_syntax\fR manual page).
+.TP 15
+\fB\-indices\fR
+.
+Changes what is stored in the \fImatchVar\fR and \fIsubMatchVar\fRs.
+Instead of storing the matching characters from \fIstring\fR,
+each variable
+will contain a list of two decimal strings giving the indices
+in \fIstring\fR of the first and last characters in the matching
+range of characters.
+.TP 15
+\fB\-line\fR
+.
+Enables newline-sensitive matching.  By default, newline is a
+completely ordinary character with no special meaning.  With this
+flag,
+.QW [^
+bracket expressions and
+.QW .
+never match newline,
+.QW ^
+matches an empty string after any newline in addition to its normal
+function, and
+.QW $
+matches an empty string before any newline in
+addition to its normal function.  This flag is equivalent to
+specifying both \fB\-linestop\fR and \fB\-lineanchor\fR, or the
+\fB(?n)\fR embedded option (see the \fBre_syntax\fR manual page).
+.TP 15
+\fB\-linestop\fR
+.
+Changes the behavior of
+.QW [^
+bracket expressions and
+.QW .
+so that they
+stop at newlines.  This is the same as specifying the \fB(?p)\fR
+embedded option (see the \fBre_syntax\fR manual page).
+.TP 15
+\fB\-lineanchor\fR
+.
+Changes the behavior of
+.QW ^
+and
+.QW $
+(the
+.QW anchors )
+so they match the
+beginning and end of a line respectively.  This is the same as
+specifying the \fB(?w)\fR embedded option (see the \fBre_syntax\fR
+manual page).
+.TP 15
+\fB\-nocase\fR
+.
+Causes upper-case characters in \fIstring\fR to be treated as
+lower case during the matching process.
+.TP 15
+\fB\-all\fR
+.
+Causes the regular expression to be matched as many times as possible
+in the string, returning the total number of matches found.  If this
+is specified with match variables, they will contain information for
+the last match only.
+.TP 15
+\fB\-inline\fR
+.
+Causes the command to return, as a list, the data that would otherwise
+be placed in match variables.  When using \fB\-inline\fR,
+match variables may not be specified.  If used with \fB\-all\fR, the
+list will be concatenated at each iteration, such that a flat list is
+always returned.  For each match iteration, the command will append the
+overall match data, plus one element for each subexpression in the
+regular expression.  Examples are:
+.RS
+.PP
+.CS
+\fBregexp\fR -inline -- {\ew(\ew)} " inlined "
+      \fI\(-> in n\fR
+\fBregexp\fR -all -inline -- {\ew(\ew)} " inlined "
+      \fI\(-> in n li i ne e\fR
+.CE
+.RE
+.TP 15
+\fB\-start\fR \fIindex\fR
+.
+Specifies a character index offset into the string to start
+matching the regular expression at.
+The \fIindex\fR value is interpreted in the same manner
+as the \fIindex\fR argument to \fBstring index\fR.
+When using this switch,
+.QW ^
+will not match the beginning of the line, and \eA will still
+match the start of the string at \fIindex\fR.  If \fB\-indices\fR
+is specified, the indices will be indexed starting from the
+absolute beginning of the input string.
+\fIindex\fR will be constrained to the bounds of the input string.
+.TP 15
+\fB\-\|\-\fR
+.
+Marks the end of switches.  The argument following this one will
+be treated as \fIexp\fR even if it starts with a \fB\-\fR.
+.PP
+If there are more \fIsubMatchVar\fRs than parenthesized
+subexpressions within \fIexp\fR, or if a particular subexpression
+in \fIexp\fR does not match the string (e.g. because it was in a
+portion of the expression that was not matched), then the corresponding
+\fIsubMatchVar\fR will be set to
+.QW "\fB\-1 \-1\fR"
+if \fB\-indices\fR has been specified or to an empty string otherwise.
+.SH EXAMPLES
+.PP
+Find the first occurrence of a word starting with \fBfoo\fR in a
+string that is not actually an instance of \fBfoobar\fR, and get the
+letters following it up to the end of the word into a variable:
+.PP
+.CS
+\fBregexp\fR {\emfoo(?!bar\eM)(\ew*)} $string \-> restOfWord
+.CE
+.PP
+Note that the whole matched substring has been placed in the variable
+.QW \fB\->\fR ,
+which is a name chosen to look nice given that we are not
+actually interested in its contents.
+.PP
+Find the index of the word \fBbadger\fR (in any case) within a string
+and store that in the variable \fBlocation\fR:
+.PP
+.CS
+\fBregexp\fR \-indices {(?i)\embadger\eM} $string location
+.CE
+.PP
+This could also be written as a \fIbasic\fR regular expression (as opposed
+to using the default syntax of \fIadvanced\fR regular expressions) match by
+prefixing the expression with a suitable flag:
+.PP
+.CS
+\fBregexp\fR \-indices {(?ib)\e<badger\e>} $string location
+.CE
+.PP
+This counts the number of octal digits in a string:
+.PP
+.CS
+\fBregexp\fR \-all {[0\-7]} $string
+.CE
+.PP
+This lists all words (consisting of all sequences of non-whitespace
+characters) in a string, and is useful as a more powerful version of the
+\fBsplit\fR command:
+.PP
+.CS
+\fBregexp\fR \-all \-inline {\eS+} $string
+.CE
+.SH "SEE ALSO"
+re_syntax(n), regsub(n), string(n)
+.SH KEYWORDS
+match, parsing, pattern, regular expression, splitting, string
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/doc/registry.n b/doc/registry.n
new file mode 100644
index 0000000..001def9
--- /dev/null
+++ b/doc/registry.n
@@ -0,0 +1,218 @@
+'\"
+'\" Copyright (c) 1997 Sun Microsystems, Inc.
+'\" Copyright (c) 2002 ActiveState Corporation.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH registry n 1.1 registry "Tcl Bundled Packages"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+registry \- Manipulate the Windows registry
+.SH SYNOPSIS
+.sp
+\fBpackage require registry 1.3\fR
+.sp
+\fBregistry \fR?\fI\-mode\fR? \fIoption\fR \fIkeyName\fR ?\fIarg arg ...\fR?
+.BE
+.SH DESCRIPTION
+.PP
+The \fBregistry\fR package provides a general set of operations for
+manipulating the Windows registry.  The package implements the
+\fBregistry\fR Tcl command.  This command is only supported on the
+Windows platform.  Warning: this command should be used with caution
+as a corrupted registry can leave your system in an unusable state.
+.PP
+\fIKeyName\fR is the name of a registry key.  Registry keys must be
+one of the following forms:
+.RS
+.PP
+\fB\e\e\fIhostname\fB\e\fIrootname\fB\e\fIkeypath\fR
+.PP
+\fIrootname\fB\e\fIkeypath\fR
+.PP
+\fIrootname\fR
+.RE
+.PP
+\fIHostname\fR specifies the name of any valid Windows
+host that exports its registry.  The \fIrootname\fR component must be
+one of \fBHKEY_LOCAL_MACHINE\fR, \fBHKEY_USERS\fR,
+\fBHKEY_CLASSES_ROOT\fR, \fBHKEY_CURRENT_USER\fR,
+\fBHKEY_CURRENT_CONFIG\fR, \fBHKEY_PERFORMANCE_DATA\fR, or
+\fBHKEY_DYN_DATA\fR.  The \fIkeypath\fR can be one or more
+registry key names separated by backslash (\fB\e\fR) characters.
+.PP
+.VS 8.6
+The optional \fI\-mode\fR argument indicates which registry to work
+with; when it is \fB\-32bit\fR the 32-bit registry will be used, and
+when it is \fB\-64bit\fR the 64-bit registry will be used. If this
+argument is omitted, the system's default registry will be the subject
+of the requested operation.
+.VE 8.6
+.PP
+\fIOption\fR indicates what to do with the registry key name.  Any
+unique abbreviation for \fIoption\fR is acceptable.  The valid options
+are:
+.TP
+\fBregistry broadcast \fIkeyName\fR ?\fB\-timeout \fImilliseconds\fR?
+.
+Sends a broadcast message to the system and running programs to notify them
+of certain updates.  This is necessary to propagate changes to key registry
+keys like Environment.  The timeout specifies the amount of time, in
+milliseconds, to wait for applications to respond to the broadcast message.
+It defaults to 3000.  The following example demonstrates how to add a path
+to the global Environment and notify applications of the change without
+requiring a logoff/logon step (assumes admin privileges):
+.RS
+.PP
+.CS
+set regPath [join {
+    HKEY_LOCAL_MACHINE
+    SYSTEM
+    CurrentControlSet
+    Control
+    {Session Manager}
+    Environment
+} "\e\e"]
+set curPath [\fBregistry get\fR $regPath "Path"]
+\fBregistry set\fR $regPath "Path" "$curPath;$addPath"
+\fBregistry broadcast\fR "Environment"
+.CE
+.RE
+.TP
+\fBregistry delete \fIkeyName\fR ?\fIvalueName\fR?
+.
+If the optional \fIvalueName\fR argument is present, the specified
+value under \fIkeyName\fR will be deleted from the registry.  If the
+optional \fIvalueName\fR is omitted, the specified key and any subkeys
+or values beneath it in the registry hierarchy will be deleted.  If
+the key could not be deleted then an error is generated.  If the key
+did not exist, the command has no effect.
+.TP
+\fBregistry get \fIkeyName valueName\fR
+.
+Returns the data associated with the value \fIvalueName\fR under the key
+\fIkeyName\fR.  If either the key or the value does not exist, then an
+error is generated.  For more details on the format of the returned
+data, see \fBSUPPORTED TYPES\fR, below.
+.TP
+\fBregistry keys \fIkeyName\fR ?\fIpattern\fR?
+.
+If \fIpattern\fR is not specified, returns a list of names of all the
+subkeys of \fIkeyName\fR.  If \fIpattern\fR is specified, only those
+names matching \fIpattern\fR are returned.  Matching is determined
+using the same rules as for \fBstring match\fR.  If the
+specified \fIkeyName\fR does not exist, then an error is generated.
+.TP
+\fBregistry set \fIkeyName\fR ?\fIvalueName data \fR?\fItype\fR??
+.
+If \fIvalueName\fR is not specified, creates the key \fIkeyName\fR if
+it does not already exist.  If \fIvalueName\fR is specified, creates
+the key \fIkeyName\fR and value \fIvalueName\fR if necessary.  The
+contents of \fIvalueName\fR are set to \fIdata\fR with the type
+indicated by \fItype\fR.  If \fItype\fR is not specified, the type
+\fBsz\fR is assumed.  For more details on the data and type arguments,
+see \fBSUPPORTED TYPES\fR below.
+.TP
+\fBregistry type \fIkeyName valueName\fR
+.
+Returns the type of the value \fIvalueName\fR in the key
+\fIkeyName\fR.  For more information on the possible types, see
+\fBSUPPORTED TYPES\fR, below.
+.TP
+\fBregistry values \fIkeyName\fR ?\fIpattern\fR?
+.
+If \fIpattern\fR is not specified, returns a list of names of all the
+values of \fIkeyName\fR.  If \fIpattern\fR is specified, only those
+names matching \fIpattern\fR are returned.  Matching is determined
+using the same rules as for \fBstring match\fR.
+.SH "SUPPORTED TYPES"
+Each value under a key in the registry contains some data of a
+particular type in a type-specific representation.  The \fBregistry\fR
+command converts between this internal representation and one that can
+be manipulated by Tcl scripts.  In most cases, the data is simply
+returned as a Tcl string.  The type indicates the intended use for the
+data, but does not actually change the representation.  For some
+types, the \fBregistry\fR command returns the data in a different form to
+make it easier to manipulate.  The following types are recognized by the
+registry command:
+.TP 17
+\fBbinary\fR
+.
+The registry value contains arbitrary binary data.  The data is represented
+exactly in Tcl, including any embedded nulls.
+.TP
+\fBnone\fR
+.
+The registry value contains arbitrary binary data with no defined
+type.  The data is represented exactly in Tcl, including any embedded
+nulls.
+.TP
+\fBsz\fR
+.
+The registry value contains a null-terminated string.  The data is 
+represented in Tcl as a string.
+.TP
+\fBexpand_sz\fR
+.
+The registry value contains a null-terminated string that contains
+unexpanded references to environment variables in the normal Windows
+style (for example,
+.QW %PATH% ).
+The data is represented in Tcl as a string.
+.TP
+\fBdword\fR
+.
+The registry value contains a little-endian 32-bit number.  The data is
+represented in Tcl as a decimal string.
+.TP
+\fBdword_big_endian\fR
+.
+The registry value contains a big-endian 32-bit number.  The data is
+represented in Tcl as a decimal string.
+.TP
+\fBlink\fR
+.
+The registry value contains a symbolic link.  The data is represented
+exactly in Tcl, including any embedded nulls.
+.TP
+\fBmulti_sz\fR
+.
+The registry value contains an array of null-terminated strings.  The
+data is represented in Tcl as a list of strings.
+.TP
+\fBresource_list\fR
+.
+The registry value contains a device-driver resource list.  The data
+is represented exactly in Tcl, including any embedded nulls.
+.PP
+In addition to the symbolically named types listed above, unknown
+types are identified using a 32-bit integer that corresponds to the
+type code returned by the system interfaces.  In this case, the data
+is represented exactly in Tcl, including any embedded nulls.
+.SH "PORTABILITY ISSUES"
+The registry command is only available on Windows.
+.SH EXAMPLE
+Print out how double-clicking on a Tcl script file will invoke a Tcl
+interpreter:
+.PP
+.CS
+package require registry
+set ext .tcl
+
+# Read the type name
+set type [\fBregistry get\fR HKEY_CLASSES_ROOT\e\e$ext {}]
+# Work out where to look for the command
+set path HKEY_CLASSES_ROOT\e\e$type\e\eShell\e\eOpen\e\ecommand
+# Read the command!
+set command [\fBregistry get\fR $path {}]
+
+puts "$ext opens with $command"
+.CE
+.SH KEYWORDS
+registry
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/doc/regsub.n b/doc/regsub.n
new file mode 100644
index 0000000..a5b79de
--- /dev/null
+++ b/doc/regsub.n
@@ -0,0 +1,192 @@
+'\"
+'\" Copyright (c) 1993 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\" Copyright (c) 2000 Scriptics Corporation.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH regsub n 8.3 Tcl "Tcl Built-In Commands"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+regsub \- Perform substitutions based on regular expression pattern matching
+.SH SYNOPSIS
+\fBregsub \fR?\fIswitches\fR? \fIexp string subSpec \fR?\fIvarName\fR?
+.BE
+.SH DESCRIPTION
+.PP
+This command matches the regular expression \fIexp\fR against
+\fIstring\fR,
+and either copies \fIstring\fR to the variable whose name is
+given by \fIvarName\fR or returns \fIstring\fR if \fIvarName\fR is not
+present.
+(Regular expression matching is described in the \fBre_syntax\fR
+reference page.)
+If there is a match, then while copying \fIstring\fR to \fIvarName\fR
+(or to the result of this command if \fIvarName\fR is not present)
+the portion of \fIstring\fR that
+matched \fIexp\fR is replaced with \fIsubSpec\fR.
+If \fIsubSpec\fR contains a
+.QW &
+or
+.QW \e0 ,
+then it is replaced in the substitution with the portion of
+\fIstring\fR that matched \fIexp\fR.
+If \fIsubSpec\fR contains a
+.QW \e\fIn\fR ,
+where \fIn\fR is a digit
+between 1 and 9, then it is replaced in the substitution with
+the portion of \fIstring\fR that matched the \fIn\fR'th
+parenthesized subexpression of \fIexp\fR.
+Additional backslashes may be used in \fIsubSpec\fR to prevent special
+interpretation of
+.QW & ,
+.QW \e0 ,
+.QW \e\fIn\fR
+and backslashes.
+The use of backslashes in \fIsubSpec\fR tends to interact badly
+with the Tcl parser's use of backslashes, so it is generally
+safest to enclose \fIsubSpec\fR in braces if it includes
+backslashes.
+.LP
+If the initial arguments to \fBregsub\fR start with \fB\-\fR then
+they are treated as switches.  The following switches are
+currently supported:
+.TP
+\fB\-all\fR
+.
+All ranges in \fIstring\fR that match \fIexp\fR are found and
+substitution is performed for each of these ranges.
+Without this switch only the first
+matching range is found and substituted.
+If \fB\-all\fR is specified, then
+.QW &
+and
+.QW \e\fIn\fR
+sequences are handled for each substitution using the information
+from the corresponding match.
+.TP
+\fB\-expanded\fR
+.
+Enables use of the expanded regular expression syntax where
+whitespace and comments are ignored.  This is the same as specifying
+the \fB(?x)\fR embedded option (see the \fBre_syntax\fR manual page).
+.TP
+\fB\-line\fR
+.
+Enables newline-sensitive matching.  By default, newline is a
+completely ordinary character with no special meaning.  With this flag,
+.QW [^
+bracket expressions and
+.QW .
+never match newline,
+.QW ^
+matches an empty string after any newline in addition to its normal
+function, and
+.QW $
+matches an empty string before any newline in
+addition to its normal function.  This flag is equivalent to
+specifying both \fB\-linestop\fR and \fB\-lineanchor\fR, or the
+\fB(?n)\fR embedded option (see the \fBre_syntax\fR manual page).
+.TP
+\fB\-linestop\fR
+.
+Changes the behavior of
+.QW [^
+bracket expressions and
+.QW .
+so that they
+stop at newlines.  This is the same as specifying the \fB(?p)\fR
+embedded option (see the \fBre_syntax\fR manual page).
+.TP
+\fB\-lineanchor\fR
+.
+Changes the behavior of
+.QW ^
+and
+.QW $
+(the
+.QW anchors )
+so they match the
+beginning and end of a line respectively.  This is the same as
+specifying the \fB(?w)\fR embedded option (see the \fBre_syntax\fR
+manual page).
+.TP
+\fB\-nocase\fR
+.
+Upper-case characters in \fIstring\fR will be converted to lower-case
+before matching against \fIexp\fR;  however, substitutions specified
+by \fIsubSpec\fR use the original unconverted form of \fIstring\fR.
+.TP
+\fB\-start\fR \fIindex\fR
+.
+Specifies a character index offset into the string to start
+matching the regular expression at.
+The \fIindex\fR value is interpreted in the same manner
+as the \fIindex\fR argument to \fBstring index\fR.
+When using this switch,
+.QW ^
+will not match the beginning of the line, and \eA will still
+match the start of the string at \fIindex\fR.
+\fIindex\fR will be constrained to the bounds of the input string.
+.TP
+\fB\-\|\-\fR
+.
+Marks the end of switches.  The argument following this one will
+be treated as \fIexp\fR even if it starts with a \fB\-\fR.
+.PP
+If \fIvarName\fR is supplied, the command returns a count of the
+number of matching ranges that were found and replaced, otherwise the
+string after replacement is returned.
+See the manual entry for \fBregexp\fR for details on the interpretation
+of regular expressions.
+.SH EXAMPLES
+.PP
+Replace (in the string in variable \fIstring\fR) every instance of
+\fBfoo\fR which is a word by itself with \fBbar\fR:
+.PP
+.CS
+\fBregsub\fR -all {\emfoo\eM} $string bar string
+.CE
+.PP
+or (using the
+.QW "basic regular expression"
+syntax):
+.PP
+.CS
+\fBregsub\fR -all {(?b)\e<foo\e>} $string bar string
+.CE
+.PP
+Insert double-quotes around the first instance of the word
+\fBinteresting\fR, however it is capitalized.
+.PP
+.CS
+\fBregsub\fR -nocase {\eyinteresting\ey} $string {"&"} string
+.CE
+.PP
+Convert all non-ASCII and Tcl-significant characters into \eu escape
+sequences by using \fBregsub\fR and \fBsubst\fR in combination:
+.PP
+.CS
+# This RE is just a character class for almost everything "bad"
+set RE {[][{};#\e\e\e$ \er\et\eu0080-\euffff]}
+
+# We will substitute with a fragment of Tcl script in brackets
+set substitution {[format \e\e\e\eu%04x [scan "\e\e&" %c]]}
+
+# Now we apply the substitution to get a subst-string that
+# will perform the computational parts of the conversion. Note
+# that newline is handled specially through \fBstring map\fR since
+# backslash-newline is a special sequence.
+set quoted [subst [string map {\en {\e\eu000a}} \e
+        [\fBregsub\fR -all $RE $string $substitution]]]
+.CE
+.SH "SEE ALSO"
+regexp(n), re_syntax(n), subst(n), string(n)
+.SH KEYWORDS
+match, pattern, quoting, regular expression, substitution
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/doc/rename.n b/doc/rename.n
new file mode 100644
index 0000000..744bf5a
--- /dev/null
+++ b/doc/rename.n
@@ -0,0 +1,45 @@
+'\"
+'\" Copyright (c) 1993 The Regents of the University of California.
+'\" Copyright (c) 1994-1997 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\" 
+.TH rename n "" Tcl "Tcl Built-In Commands"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+rename \- Rename or delete a command
+.SH SYNOPSIS
+\fBrename \fIoldName newName\fR
+.BE
+.SH DESCRIPTION
+.PP
+Rename the command that used to be called \fIoldName\fR so that it
+is now called \fInewName\fR.
+If \fInewName\fR is an empty string then \fIoldName\fR is deleted.
+\fIoldName\fR and \fInewName\fR may include namespace qualifiers
+(names of containing namespaces).
+If a command is renamed into a different namespace,
+future invocations of it will execute in the new namespace.
+The \fBrename\fR command returns an empty string as result.
+.SH EXAMPLE
+.PP
+The \fBrename\fR command can be used to wrap the standard Tcl commands
+with your own monitoring machinery.  For example, you might wish to
+count how often the \fBsource\fR command is called:
+.PP
+.CS
+\fBrename\fR ::source ::theRealSource
+set sourceCount 0
+proc ::source args {
+    global sourceCount
+    puts "called source for the [incr sourceCount]'th time"
+    uplevel 1 ::theRealSource $args
+}
+.CE
+.SH "SEE ALSO"
+namespace(n), proc(n)
+.SH KEYWORDS
+command, delete, namespace, rename
diff --git a/doc/return.n b/doc/return.n
new file mode 100644
index 0000000..ea590ea
--- /dev/null
+++ b/doc/return.n
@@ -0,0 +1,326 @@
+'\"
+'\" Copyright (c) 1993 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\" Contributions from Don Porter, NIST, 2003.  (not subject to US copyright)
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH return n 8.5 Tcl "Tcl Built-In Commands"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+return \- Return from a procedure, or set return code of a script
+.SH SYNOPSIS
+\fBreturn \fR?\fIresult\fR?
+.sp
+\fBreturn \fR?\fB\-code \fIcode\fR? ?\fIresult\fR?
+.sp
+\fBreturn \fR?\fIoption value \fR...? ?\fIresult\fR?
+.BE
+.SH DESCRIPTION
+.PP
+In its simplest usage, the \fBreturn\fR command is used without options
+in the body of a procedure to immediately return control to the caller
+of the procedure.  If a \fIresult\fR argument is provided, its value
+becomes the result of the procedure passed back to the caller.
+If \fIresult\fR is not specified then an empty string will be returned
+to the caller as the result of the procedure.
+.PP
+The \fBreturn\fR command serves a similar function within script
+files that are evaluated by the \fBsource\fR command.  When \fBsource\fR
+evaluates the contents of a file as a script, an invocation of
+the \fBreturn\fR command will cause script evaluation
+to immediately cease, and the value \fIresult\fR (or an empty string)
+will be returned as the result of the \fBsource\fR command.
+.SH "EXCEPTIONAL RETURN CODES"
+.PP
+In addition to the result of a procedure, the return
+code of a procedure may also be set by \fBreturn\fR
+through use of the \fB\-code\fR option.
+In the usual case where the \fB\-code\fR option is not
+specified the procedure will return normally.
+However, the \fB\-code\fR option may be used to generate an
+exceptional return from the procedure.
+\fICode\fR may have any of the following values:
+.TP 13
+\fBok\fR (or \fB0\fR)
+.
+Normal return:  same as if the option is omitted.  The return code
+of the procedure is 0 (\fBTCL_OK\fR).
+.TP 13
+\fBerror\fR (or \fB1\fR)
+.
+Error return: the return code of the procedure is 1 (\fBTCL_ERROR\fR).
+The procedure command behaves in its calling context as if it
+were the command \fBerror\fR \fIresult\fR.  See below for additional
+options.
+.TP 13
+\fBreturn\fR (or \fB2\fR)
+.
+The return code of the procedure is 2 (\fBTCL_RETURN\fR).  The
+procedure command behaves in its calling context as if it
+were the command \fBreturn\fR (with no arguments).
+.TP 13
+\fBbreak\fR (or \fB3\fR)
+.
+The return code of the procedure is 3 (\fBTCL_BREAK\fR).  The
+procedure command behaves in its calling context as if it
+were the command \fBbreak\fR.
+.TP 13
+\fBcontinue\fR (or \fB4\fR)
+.
+The return code of the procedure is 4 (\fBTCL_CONTINUE\fR).  The
+procedure command behaves in its calling context as if it
+were the command \fBcontinue\fR.
+.TP 13
+\fIvalue\fR
+.
+\fIValue\fR must be an integer;  it will be returned as the
+return code for the current procedure.
+.LP
+When a procedure wants to signal that it has received invalid
+arguments from its caller, it may use \fBreturn -code error\fR
+with \fIresult\fR set to a suitable error message.  Otherwise
+usage of the \fBreturn -code\fR option is mostly limited to
+procedures that implement a new control structure.
+.PP
+The \fBreturn \-code\fR command acts similarly within script
+files that are evaluated by the \fBsource\fR command.  During the
+evaluation of the contents of a file as a script by \fBsource\fR,
+an invocation of the \fBreturn \-code \fIcode\fR command will cause
+the return code of \fBsource\fR to be \fIcode\fR.
+.SH "RETURN OPTIONS"
+.PP
+In addition to a result and a return code, evaluation of a command
+in Tcl also produces a dictionary of return options.  In general
+usage, all \fIoption value\fR pairs given as arguments to \fBreturn\fR
+become entries in the return options dictionary, and any values at all
+are acceptable except as noted below.  The \fBcatch\fR command may be
+used to capture all of this information \(em the return code, the result,
+and the return options dictionary \(em that arise from evaluation of a
+script.
+.PP
+As documented above, the \fB\-code\fR entry in the return options dictionary
+receives special treatment by Tcl.  There are other return options also
+recognized and treated specially by Tcl.  They are:
+.TP
+\fB\-errorcode \fIlist\fR
+.
+The \fB\-errorcode\fR option receives special treatment only when the value
+of the \fB\-code\fR option is \fBTCL_ERROR\fR.  Then the \fIlist\fR value
+is meant to be additional information about the error,
+presented as a Tcl list for further processing by programs.
+If no \fB\-errorcode\fR option is provided to \fBreturn\fR when
+the \fB\-code error\fR option is provided, Tcl will set the value
+of the \fB\-errorcode\fR entry in the return options dictionary
+to the default value of \fBNONE\fR.  The \fB\-errorcode\fR return
+option will also be stored in the global variable \fBerrorCode\fR.
+.TP
+\fB\-errorinfo \fIinfo\fR
+.
+The \fB\-errorinfo\fR option receives special treatment only when the value
+of the \fB\-code\fR option is \fBTCL_ERROR\fR.  Then \fIinfo\fR is the initial
+stack trace, meant to provide to a human reader additional information
+about the context in which the error occurred.  The stack trace will
+also be stored in the global variable \fBerrorInfo\fR.
+If no \fB\-errorinfo\fR option is provided to \fBreturn\fR when
+the \fB\-code error\fR option is provided, Tcl will provide its own
+initial stack trace value in the entry for \fB\-errorinfo\fR.  Tcl's
+initial stack trace will include only the call to the procedure, and
+stack unwinding will append information about higher stack levels, but
+there will be no information about the context of the error within
+the procedure.  Typically the \fIinfo\fR value is supplied from
+the value of \fB\-errorinfo\fR in a return options dictionary captured
+by the \fBcatch\fR command (or from the copy of that information
+stored in the global variable \fBerrorInfo\fR).
+.TP
+\fB\-errorstack \fIlist\fR
+.VS 8.6
+The \fB\-errorstack\fR option receives special treatment only when the value
+of the \fB\-code\fR option is \fBTCL_ERROR\fR.  Then \fIlist\fR is the initial
+error stack, recording actual argument values passed to each proc level.  The error stack will
+also be reachable through \fBinfo errorstack\fR.
+If no \fB\-errorstack\fR option is provided to \fBreturn\fR when
+the \fB\-code error\fR option is provided, Tcl will provide its own
+initial error stack in the entry for \fB\-errorstack\fR.  Tcl's
+initial error stack will include only the call to the procedure, and
+stack unwinding will append information about higher stack levels, but
+there will be no information about the context of the error within
+the procedure.  Typically the \fIlist\fR value is supplied from
+the value of \fB\-errorstack\fR in a return options dictionary captured
+by the \fBcatch\fR command (or from the copy of that information from
+\fBinfo errorstack\fR).
+.VE 8.6
+.TP
+\fB\-level \fIlevel\fR
+.
+The \fB\-level\fR and \fB\-code\fR options work together to set the return
+code to be returned by one of the commands currently being evaluated.
+The \fIlevel\fR value must be a non-negative integer representing a number
+of levels on the call stack.  It defines the number of levels up the stack
+at which the return code of a command currently being evaluated should
+be \fIcode\fR.  If no \fB\-level\fR option is provided, the default value
+of \fIlevel\fR is 1, so that \fBreturn\fR sets the return code that the
+current procedure returns to its caller, 1 level up the call stack.  The
+mechanism by which these options work is described in more detail below.
+.TP
+\fB\-options \fIoptions\fR
+.
+The value \fIoptions\fR must be a valid dictionary.  The entries of that
+dictionary are treated as additional \fIoption value\fR pairs for the
+\fBreturn\fR command.
+.SH "RETURN CODE HANDLING MECHANISMS"
+.PP
+Return codes are used in Tcl to control program flow.  A Tcl script
+is a sequence of Tcl commands.  So long as each command evaluation
+returns a return code of \fBTCL_OK\fR, evaluation will continue to the next
+command in the script.  Any exceptional return code (non-\fBTCL_OK\fR)
+returned by a command evaluation causes the flow on to the next
+command to be interrupted.  Script evaluation ceases, and the
+exceptional return code from the command becomes the return code
+of the full script evaluation.  This is the mechanism by which
+errors during script evaluation cause an interruption and unwinding
+of the call stack.  It is also the mechanism by which commands
+like \fBbreak\fR, \fBcontinue\fR, and \fBreturn\fR cause script
+evaluation to terminate without evaluating all commands in sequence.
+.PP
+Some of Tcl's built-in commands evaluate scripts as part of their
+functioning.  These commands can make use of exceptional return
+codes to enable special features.  For example, the built-in
+Tcl commands that provide loops \(em such as \fBwhile\fR, \fBfor\fR,
+and \fBforeach\fR \(em evaluate a script that is the body of the
+loop.  If evaluation of the loop body returns the return code
+of \fBTCL_BREAK\fR or \fBTCL_CONTINUE\fR, the loop command can react in such
+a way as to give the \fBbreak\fR and \fBcontinue\fR commands
+their documented interpretation in loops.
+.PP
+Procedure invocation also involves evaluation of a script, the body
+of the procedure.  Procedure invocation provides special treatment
+when evaluation of the procedure body returns the return code
+\fBTCL_RETURN\fR.  In that circumstance, the \fB\-level\fR entry in the
+return options dictionary is decremented.  If after decrementing,
+the value of the \fB\-level\fR entry is 0, then the value of
+the \fB\-code\fR entry becomes the return code of the procedure.
+If after decrementing, the value of the \fB\-level\fR entry is
+greater than zero, then the return code of the procedure is
+\fBTCL_RETURN\fR.  If the procedure invocation occurred during the
+evaluation of the body of another procedure, the process will
+repeat itself up the call stack, decrementing the value of the
+\fB\-level\fR entry at each level, so that the \fIcode\fR will
+be the return code of the current command \fIlevel\fR levels
+up the call stack.  The \fBsource\fR command performs the
+same handling of the \fBTCL_RETURN\fR return code, which explains
+the similarity of \fBreturn\fR invocation during a \fBsource\fR
+to \fBreturn\fR invocation within a procedure.
+.PP
+The return code of the \fBreturn\fR command itself triggers this
+special handling by procedure invocation.  If \fBreturn\fR
+is provided the option \fB\-level 0\fR, then the return code
+of the \fBreturn\fR command itself will be the value \fIcode\fR
+of the \fB\-code\fR option (or \fBTCL_OK\fR by default).  Any other value
+for the \fB\-level\fR option (including the default value of 1)
+will cause the return code of the \fBreturn\fR command itself
+to be \fBTCL_RETURN\fR, triggering a return from the enclosing procedure.
+.SH EXAMPLES
+.PP
+First, a simple example of using \fBreturn\fR to return from a
+procedure, interrupting the procedure body.
+.PP
+.CS
+proc printOneLine {} {
+    puts "line 1"    ;# This line will be printed.
+    \fBreturn\fR
+    puts "line 2"    ;# This line will not be printed.
+}
+.CE
+.PP
+Next, an example of using \fBreturn\fR to set the value
+returned by the procedure.
+.PP
+.CS
+proc returnX {} {\fBreturn\fR X}
+puts [returnX]    ;# prints "X"
+.CE
+.PP
+Next, a more complete example, using \fBreturn -code error\fR
+to report invalid arguments.
+.PP
+.CS
+proc factorial {n} {
+    if {![string is integer $n] || ($n < 0)} {
+        \fBreturn\fR -code error \e
+                "expected non-negative integer,\e
+                but got \e"$n\e""
+    }
+    if {$n < 2} {
+        \fBreturn\fR 1
+    }
+    set m [expr {$n - 1}]
+    set code [catch {factorial $m} factor]
+    if {$code != 0} {
+        \fBreturn\fR -code $code $factor
+    }
+    set product [expr {$n * $factor}]
+    if {$product < 0} {
+        \fBreturn\fR -code error \e
+                "overflow computing factorial of $n"
+    }
+    \fBreturn\fR $product
+}
+.CE
+.PP
+Next, a procedure replacement for \fBbreak\fR.
+.PP
+.CS
+proc myBreak {} {
+    \fBreturn\fR -code break
+}
+.CE
+.PP
+With the \fB\-level 0\fR option, \fBreturn\fR itself can serve
+as a replacement for \fBbreak\fR, with the help of \fBinterp alias\fR.
+.PP
+.CS
+interp alias {} Break {} \fBreturn\fR -level 0 -code break
+.CE
+.PP
+An example of using \fBcatch\fR and \fBreturn -options\fR to
+re-raise a caught error:
+.PP
+.CS
+proc doSomething {} {
+    set resource [allocate]
+    catch {
+        # Long script of operations
+        # that might raise an error
+    } result options
+    deallocate $resource
+    \fBreturn\fR -options $options $result
+}
+.CE
+.PP
+Finally an example of advanced use of the \fBreturn\fR options
+to create a procedure replacement for \fBreturn\fR itself:
+.PP
+.CS
+proc myReturn {args} {
+    set result ""
+    if {[llength $args] % 2} {
+        set result [lindex $args end]
+        set args [lrange $args 0 end-1]
+    }
+    set options [dict merge {-level 1} $args]
+    dict incr options -level
+    \fBreturn\fR -options $options $result
+}
+.CE
+.SH "SEE ALSO"
+break(n), catch(n), continue(n), dict(n), error(n), errorCode(n),
+errorInfo(n), proc(n), source(n), throw(n), try(n)
+.SH KEYWORDS
+break, catch, continue, error, exception, procedure, result, return
+.\" Local Variables:
+.\" mode: nroff
+.\" End:
diff --git a/doc/safe.n b/doc/safe.n
new file mode 100644
index 0000000..b39f2c2
--- /dev/null
+++ b/doc/safe.n
@@ -0,0 +1,359 @@
+'\"
+'\" Copyright (c) 1995-1996 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH "Safe Tcl" n 8.0 Tcl "Tcl Built-In Commands"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+safe \- Creating and manipulating safe interpreters
+.SH SYNOPSIS
+\fB::safe::interpCreate\fR ?\fIslave\fR? ?\fIoptions...\fR?
+.sp
+\fB::safe::interpInit\fR \fIslave\fR ?\fIoptions...\fR?
+.sp
+\fB::safe::interpConfigure\fR \fIslave\fR ?\fIoptions...\fR?
+.sp
+\fB::safe::interpDelete\fR \fIslave\fR
+.sp
+\fB::safe::interpAddToAccessPath\fR \fIslave\fR \fIdirectory\fR
+.sp
+\fB::safe::interpFindInAccessPath\fR \fIslave\fR \fIdirectory\fR
+.sp
+\fB::safe::setLogCmd\fR ?\fIcmd arg...\fR?
+.SS OPTIONS
+.PP
+?\fB\-accessPath\fR \fIpathList\fR?
+?\fB\-statics\fR \fIboolean\fR? ?\fB\-noStatics\fR?
+?\fB\-nested\fR \fIboolean\fR? ?\fB\-nestedLoadOk\fR?
+?\fB\-deleteHook\fR \fIscript\fR?
+.BE
+.SH DESCRIPTION
+Safe Tcl is a mechanism for executing untrusted Tcl scripts
+safely and for providing mediated access by such scripts to
+potentially dangerous functionality.
+.PP
+Safe Tcl ensures that untrusted Tcl scripts cannot harm the
+hosting application.
+It prevents integrity and privacy attacks. Untrusted Tcl
+scripts are prevented from corrupting the state of the hosting
+application or computer. Untrusted scripts are also prevented from
+disclosing information stored on the hosting computer or in the
+hosting application to any party.
+.PP
+Safe Tcl allows a master interpreter to create safe, restricted
+interpreters that contain a set of predefined aliases for the \fBsource\fR,
+\fBload\fR, \fBfile\fR, \fBencoding\fR, and \fBexit\fR commands and
+are able to use the auto-loading and package mechanisms.
+.PP
+No knowledge of the file system structure is leaked to the
+safe interpreter, because it has access only to a virtualized path
+containing tokens. When the safe interpreter requests to source a file, it
+uses the token in the virtual path as part of the file name to source; the
+master interpreter transparently
+translates the token into a real directory name and executes the
+requested operation (see the section \fBSECURITY\fR below for details).
+Different levels of security can be selected by using the optional flags
+of the commands described below.
+.PP
+All commands provided in the master interpreter by Safe Tcl reside in
+the \fBsafe\fR namespace.
+.SH COMMANDS
+The following commands are provided in the master interpreter:
+.TP
+\fB::safe::interpCreate\fR ?\fIslave\fR? ?\fIoptions...\fR?
+Creates a safe interpreter, installs the aliases described in the section
+\fBALIASES\fR and initializes the auto-loading and package mechanism as
+specified by the supplied \fIoptions\fR.
+See the \fBOPTIONS\fR section below for a description of the
+optional arguments.
+If the \fIslave\fR argument is omitted, a name will be generated.
+\fB::safe::interpCreate\fR always returns the interpreter name.
+.TP
+\fB::safe::interpInit\fR \fIslave\fR ?\fIoptions...\fR?
+This command is similar to \fBinterpCreate\fR except it that does not
+create the safe interpreter. \fIslave\fR must have been created by some
+other means, like \fBinterp create\fR \fB\-safe\fR.
+.TP
+\fB::safe::interpConfigure\fR \fIslave\fR ?\fIoptions...\fR?
+If no \fIoptions\fR are given, returns the settings for all options for the
+named safe interpreter as a list of options and their current values
+for that \fIslave\fR.
+If a single additional argument is provided,
+it will return a list of 2 elements \fIname\fR and \fIvalue\fR where
+\fIname\fR is the full name of that option and \fIvalue\fR the current value
+for that option and the \fIslave\fR.
+If more than two additional arguments are provided, it will reconfigure the
+safe interpreter and change each and only the provided options.
+See the section on \fBOPTIONS\fR below for options description.
+Example of use:
+.RS
+.PP
+.CS
+# Create new interp with the same configuration as "$i0":
+set i1 [safe::interpCreate {*}[safe::interpConfigure $i0]]
+
+# Get the current deleteHook
+set dh [safe::interpConfigure $i0  \-del]
+
+# Change (only) the statics loading ok attribute of an
+# interp and its deleteHook (leaving the rest unchanged):
+safe::interpConfigure $i0  \-delete {foo bar} \-statics 0
+.CE
+.RE
+.TP
+\fB::safe::interpDelete\fR \fIslave\fR
+Deletes the safe interpreter and cleans up the corresponding
+master interpreter data structures.
+If a \fIdeleteHook\fR script was specified for this interpreter it is
+evaluated before the interpreter is deleted, with the name of the
+interpreter as an additional argument.
+.TP
+\fB::safe::interpFindInAccessPath\fR \fIslave\fR \fIdirectory\fR
+This command finds and returns the token for the real directory
+\fIdirectory\fR in the safe interpreter's current virtual access path.
+It generates an error if the directory is not found.
+Example of use:
+.RS
+.PP
+.CS
+$slave eval [list set tk_library \e
+      [::safe::interpFindInAccessPath $name $tk_library]]
+.CE
+.RE
+.TP
+\fB::safe::interpAddToAccessPath\fR \fIslave\fR \fIdirectory\fR
+This command adds \fIdirectory\fR to the virtual path maintained for the
+safe interpreter in the master, and returns the token that can be used in
+the safe interpreter to obtain access to files in that directory.
+If the directory is already in the virtual path, it only returns the token
+without adding the directory to the virtual path again.
+Example of use:
+.RS
+.PP
+.CS
+$slave eval [list set tk_library \e
+      [::safe::interpAddToAccessPath $name $tk_library]]
+.CE
+.RE
+.TP
+\fB::safe::setLogCmd\fR ?\fIcmd arg...\fR?
+This command installs a script that will be called when interesting
+life cycle events occur for a safe interpreter.
+When called with no arguments, it returns the currently installed script.
+When called with one argument, an empty string, the currently installed
+script is removed and logging is turned off.
+The script will be invoked with one additional argument, a string
+describing the event of interest.
+The main purpose is to help in debugging safe interpreters.
+Using this facility you can get complete error messages while the safe
+interpreter gets only generic error messages.
+This prevents a safe interpreter from seeing messages about failures
+and other events that might contain sensitive information such as real
+directory names.
+.RS
+.PP
+Example of use:
+.PP
+.CS
+::safe::setLogCmd puts stderr
+.CE
+.PP
+Below is the output of a sample session in which a safe interpreter
+attempted to source a file not found in its virtual access path.
+Note that the safe interpreter only received an error message saying that
+the file was not found:
+.PP
+.CS
+NOTICE for slave interp10 : Created
+NOTICE for slave interp10 : Setting accessPath=(/foo/bar) staticsok=1 nestedok=0 deletehook=()
+NOTICE for slave interp10 : auto_path in interp10 has been set to {$p(:0:)}
+ERROR for slave interp10 : /foo/bar/init.tcl: no such file or directory
+.CE
+.RE
+.SS OPTIONS
+The following options are common to
+\fB::safe::interpCreate\fR, \fB::safe::interpInit\fR,
+and \fB::safe::interpConfigure\fR.
+Any option name can be abbreviated to its minimal
+non-ambiguous name.
+Option names are not case sensitive.
+.TP
+\fB\-accessPath\fR \fIdirectoryList\fR
+This option sets the list of directories from which the safe interpreter
+can \fBsource\fR and \fBload\fR files.
+If this option is not specified, or if it is given as the
+empty list, the safe interpreter will use the same directories as its
+master for auto-loading.
+See the section \fBSECURITY\fR below for more detail about virtual paths,
+tokens and access control.
+.TP
+\fB\-statics\fR \fIboolean\fR
+This option specifies if the safe interpreter will be allowed
+to load statically linked packages (like \fBload {} Tk\fR).
+The default value is \fBtrue\fR :
+safe interpreters are allowed to load statically linked packages.
+.TP
+\fB\-noStatics\fR
+This option is a convenience shortcut for \fB\-statics false\fR and
+thus specifies that the safe interpreter will not be allowed
+to load statically linked packages.
+.TP
+\fB\-nested\fR \fIboolean\fR
+This option specifies if the safe interpreter will be allowed
+to load packages into its own sub-interpreters.
+The default value is \fBfalse\fR :
+safe interpreters are not allowed to load packages into
+their own sub-interpreters.
+.TP
+\fB\-nestedLoadOk\fR
+This option is a convenience shortcut for \fB\-nested true\fR and
+thus specifies the safe interpreter will be allowed
+to load packages into its own sub-interpreters.
+.TP
+\fB\-deleteHook\fR \fIscript\fR
+When this option is given a non-empty \fIscript\fR, it will be
+evaluated in the master with the name of
+the safe interpreter as an additional argument
+just before actually deleting the safe interpreter.
+Giving an empty value removes any currently installed deletion hook
+script for that safe interpreter.
+The default value (\fB{}\fR) is not to have any deletion call back.
+.SH ALIASES
+The following aliases are provided in a safe interpreter:
+.TP
+\fBsource\fR \fIfileName\fR
+The requested file, a Tcl source file, is sourced into the safe interpreter
+if it is found.
+The \fBsource\fR alias can only source files from directories in
+the virtual path for the safe interpreter. The \fBsource\fR alias requires
+the safe interpreter to
+use one of the token names in its virtual path to denote the directory in
+which the file to be sourced can be found.
+See the section on \fBSECURITY\fR for more discussion of restrictions on
+valid filenames.
+.TP
+\fBload\fR \fIfileName\fR
+The requested file, a shared object file, is dynamically loaded into the
+safe interpreter if it is found.
+The filename must contain a token name mentioned in the virtual path for
+the safe interpreter for it to be found successfully.
+Additionally, the shared object file must contain a safe entry point; see
+the manual page for the \fBload\fR command for more details.
+.TP
+\fBfile\fR ?\fIsubCmd args...\fR?
+The \fBfile\fR alias provides access to a safe subset of the subcommands of
+the \fBfile\fR command; it allows only \fBdirname\fR, \fBjoin\fR,
+\fBextension\fR, \fBroot\fR, \fBtail\fR, \fBpathname\fR and \fBsplit\fR
+subcommands. For more details on what these subcommands do see the manual
+page for the \fBfile\fR command.
+.TP
+\fBencoding\fR ?\fIsubCmd args...\fR?
+The \fBencoding\fR alias provides access to a safe subset of the
+subcommands of the \fBencoding\fR command;  it disallows setting of
+the system encoding, but allows all other subcommands including
+\fBsystem\fR to check the current encoding.
+.TP
+\fBexit\fR
+The calling interpreter is deleted and its computation is stopped, but the
+Tcl process in which this interpreter exists is not terminated.
+.SH SECURITY
+Safe Tcl does not attempt to completely prevent annoyance and
+denial of service attacks. These forms of attack prevent the
+application or user from temporarily using the computer to perform
+useful work, for example by consuming all available CPU time or
+all available screen real estate.
+These attacks, while aggravating, are deemed to be of lesser importance
+in general than integrity and privacy attacks that Safe Tcl
+is to prevent.
+.PP
+The commands available in a safe interpreter, in addition to
+the safe set as defined in \fBinterp\fR manual page, are mediated aliases
+for \fBsource\fR, \fBload\fR, \fBexit\fR, and safe subsets of
+\fBfile\fR and \fBencoding\fR. The safe interpreter can also auto-load
+code and it can request that packages be loaded.
+.PP
+Because some of these commands access the local file system, there is a
+potential for information leakage about its directory structure.
+To prevent this, commands that take file names as arguments in a safe
+interpreter use tokens instead of the real directory names.
+These tokens are translated to the real directory name while a request to,
+e.g., source a file is mediated by the master interpreter.
+This virtual path system is maintained in the master interpreter for each safe
+interpreter created by \fB::safe::interpCreate\fR or initialized by
+\fB::safe::interpInit\fR and
+the path maps tokens accessible in the safe interpreter into real path
+names on the local file system thus preventing safe interpreters
+from gaining knowledge about the
+structure of the file system of the host on which the interpreter is
+executing.
+The only valid file names arguments
+for the \fBsource\fR and \fBload\fR aliases provided to the slave
+are path in the form of
+\fB[file join \fItoken filename\fB]\fR (i.e. when using the
+native file path formats: \fItoken\fB/\fIfilename\fR
+on Unix and \fItoken\fB\e\fIfilename\fR on Windows),
+where \fItoken\fR is representing one of the directories
+of the \fIaccessPath\fR list and \fIfilename\fR is
+one file in that directory (no sub directories access are allowed).
+.PP
+When a token is used in a safe interpreter in a request to source or
+load a file, the token is checked and
+translated to a real path name and the file to be
+sourced or loaded is located on the file system.
+The safe interpreter never gains knowledge of the actual path name under
+which the file is stored on the file system.
+.PP
+To further prevent potential information leakage from sensitive files that
+are accidentally included in the set of files that can be sourced by a safe
+interpreter, the \fBsource\fR alias restricts access to files
+meeting the following constraints: the file name must
+fourteen characters or shorter, must not contain more than one dot
+.PQ \fB.\fR "" ,
+must end up with the extension
+.PQ \fB.tcl\fR
+or be called
+.PQ \fBtclIndex\fR .
+.PP
+Each element of the initial access path
+list will be assigned a token that will be set in
+the slave \fBauto_path\fR and the first element of that list will be set as
+the \fBtcl_library\fR for that slave.
+.PP
+If the access path argument is not given or is the empty list,
+the default behavior is to let the slave access the same packages
+as the master has access to (Or to be more precise:
+only packages written in Tcl (which by definition cannot be dangerous
+as they run in the slave interpreter) and C extensions that
+provides a _SafeInit entry point). For that purpose, the master's
+\fBauto_path\fR will be used to construct the slave access path.
+In order that the slave successfully loads the Tcl library files
+(which includes the auto-loading mechanism itself) the \fBtcl_library\fR will be
+added or moved to the first position if necessary, in the
+slave access path, so the slave
+\fBtcl_library\fR will be the same as the master's (its real
+path will still be invisible to the slave though).
+In order that auto-loading works the same for the slave and
+the master in this by default case, the first-level
+sub directories of each directory in the master \fBauto_path\fR will
+also be added (if not already included) to the slave access path.
+You can always specify a more
+restrictive path for which sub directories will never be searched by
+explicitly specifying your directory list with the \fB\-accessPath\fR flag
+instead of relying on this default mechanism.
+.PP
+When the \fIaccessPath\fR is changed after the first creation or
+initialization (i.e. through \fBinterpConfigure -accessPath \fR\fIlist\fR),
+an \fBauto_reset\fR is automatically evaluated in the safe interpreter
+to synchronize its \fBauto_index\fR with the new token list.
+.SH "SEE ALSO"
+interp(n), library(n), load(n), package(n), source(n), unknown(n)
+.SH KEYWORDS
+alias, auto\-loading, auto_mkindex, load, master interpreter, safe
+interpreter, slave interpreter, source
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/doc/scan.n b/doc/scan.n
new file mode 100644
index 0000000..d963d6c
--- /dev/null
+++ b/doc/scan.n
@@ -0,0 +1,293 @@
+'\"
+'\" Copyright (c) 1993 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\" Copyright (c) 2000 Scriptics Corporation.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH scan n 8.4 Tcl "Tcl Built-In Commands"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+scan \- Parse string using conversion specifiers in the style of sscanf
+.SH SYNOPSIS
+\fBscan \fIstring format \fR?\fIvarName varName ...\fR?
+.BE
+.SH INTRODUCTION
+.PP
+This command parses substrings from an input string in a fashion similar
+to the ANSI C \fBsscanf\fR procedure and returns a count of the number of
+conversions performed, or -1 if the end of the input string is reached
+before any conversions have been performed.  \fIString\fR gives the input
+to be parsed and \fIformat\fR indicates how to parse it, using \fB%\fR
+conversion specifiers as in \fBsscanf\fR.  Each \fIvarName\fR gives the
+name of a variable; when a substring is scanned from \fIstring\fR that
+matches a conversion specifier, the substring is assigned to the
+corresponding variable.
+If no \fIvarName\fR variables are specified, then \fBscan\fR works in an
+inline manner, returning the data that would otherwise be stored in the
+variables as a list.  In the inline case, an empty string is returned when
+the end of the input string is reached before any conversions have been
+performed.
+.SH "DETAILS ON SCANNING"
+.PP
+\fBScan\fR operates by scanning \fIstring\fR and \fIformat\fR together.
+If the next character in \fIformat\fR is a blank or tab then it
+matches any number of white space characters in \fIstring\fR (including
+zero).
+Otherwise, if it is not a \fB%\fR character then it
+must match the next character of \fIstring\fR.
+When a \fB%\fR is encountered in \fIformat\fR, it indicates
+the start of a conversion specifier.
+A conversion specifier contains up to four fields after the \fB%\fR:
+a XPG3 position specifier (or a \fB*\fR to indicate the converted
+value is to be discarded instead of assigned to any variable); a number
+indicating a maximum substring width; a size modifier; and a
+conversion character.
+All of these fields are optional except for the conversion character.
+The fields that are present must appear in the order given above.
+.PP
+When \fBscan\fR finds a conversion specifier in \fIformat\fR, it
+first skips any white-space characters in \fIstring\fR (unless the
+conversion character is \fB[\fR or \fBc\fR).
+Then it converts the next input characters according to the
+conversion specifier and stores the result in the variable given
+by the next argument to \fBscan\fR.
+.SS "OPTIONAL POSITIONAL SPECIFIER"
+.PP
+If the \fB%\fR is followed by a decimal number and a \fB$\fR, as in
+.QW \fB%2$d\fR ,
+then the variable to use is not taken from the next
+sequential argument.  Instead, it is taken from the argument indicated
+by the number, where 1 corresponds to the first \fIvarName\fR.  If
+there are any positional specifiers in \fIformat\fR then all of the
+specifiers must be positional.  Every \fIvarName\fR on the argument
+list must correspond to exactly one conversion specifier or an error
+is generated, or in the inline case, any position can be specified
+at most once and the empty positions will be filled in with empty strings.
+.SS "OPTIONAL SIZE MODIFIER"
+.PP
+The size modifier field is used only when scanning a substring into
+one of Tcl's integer values.  The size modifier field dictates the
+integer range acceptable to be stored in a variable, or, for the inline
+case, in a position in the result list.
+The syntactically valid values for the size modifier are \fBh\fR, \fBL\fR,
+\fBl\fR, and \fBll\fR.  The \fBh\fR size modifier value is equivalent
+to the absence of a size modifier in the the conversion specifier.
+Either one indicates the integer range to be stored is limited to
+the same range produced by the \fBint()\fR function of the \fBexpr\fR
+command.  The \fBL\fR size modifier is equivalent to the \fBl\fR size
+modifier. Either one indicates the integer range to be stored is
+limited to the same range produced by the \fBwide()\fR function of
+the \fBexpr\fR command.  The \fBll\fR size modifier indicates that
+the integer range to be stored is unlimited.
+.SS "MANDATORY CONVERSION CHARACTER"
+.PP
+The following conversion characters are supported:
+.TP
+\fBd\fR
+.
+The input substring must be a decimal integer.
+It is read in and the integer value is stored in the variable,
+truncated as required by the size modifier value.
+.TP
+\fBo\fR
+.
+The input substring must be an octal integer. It is read in and the
+integer value is stored in the variable,
+truncated as required by the size modifier value.
+.TP
+\fBx\fR or \fBX\fR
+.
+The input substring must be a hexadecimal integer.
+It is read in and the integer value is stored in the variable,
+truncated as required by the size modifier value.
+.TP
+\fBb\fR
+.
+The input substring must be a binary integer.
+It is read in and the integer value is stored in the variable,
+truncated as required by the size modifier value.
+.TP
+\fBu\fR
+.
+The input substring must be a decimal integer.
+The integer value is truncated as required by the size modifier
+value, and the corresponding unsigned value for that truncated
+range is computed and stored in the variable as a decimal string.
+The conversion makes no sense without reference to a truncation range,
+so the size modifier \fBll\fR is not permitted in combination
+with conversion character \fBu\fR.
+.TP
+\fBi\fR
+.
+The input substring must be an integer.  The base (i.e. decimal, binary,
+octal, or hexadecimal) is determined in the same fashion as described in
+\fBexpr\fR.  The integer value is stored in the variable,
+truncated as required by the size modifier value.
+.TP
+\fBc\fR
+.
+A single character is read in and its Unicode value is stored in
+the variable as an integer value.
+Initial white space is not skipped in this case, so the input
+substring may be a white-space character.
+.TP
+\fBs\fR
+.
+The input substring consists of all the characters up to the next
+white-space character; the characters are copied to the variable.
+.TP
+\fBe\fR or \fBf\fR or \fBg\fR or \fBE\fR or \fBG\fR
+.
+The input substring must be a floating-point number consisting
+of an optional sign, a string of decimal digits possibly
+containing a decimal point, and an optional exponent consisting
+of an \fBe\fR or \fBE\fR followed by an optional sign and a string of
+decimal digits.
+It is read in and stored in the variable as a floating-point value.
+.TP
+\fB[\fIchars\fB]\fR
+.
+The input substring consists of one or more characters in \fIchars\fR.
+The matching string is stored in the variable.
+If the first character between the brackets is a \fB]\fR then
+it is treated as part of \fIchars\fR rather than the closing
+bracket for the set.
+If \fIchars\fR
+contains a sequence of the form \fIa\fB\-\fIb\fR then any
+character between \fIa\fR and \fIb\fR (inclusive) will match.
+If the first or last character between the brackets is a \fB\-\fR, then
+it is treated as part of \fIchars\fR rather than indicating a range.
+.TP
+\fB[^\fIchars\fB]\fR
+.
+The input substring consists of one or more characters not in \fIchars\fR.
+The matching string is stored in the variable.
+If the character immediately following the \fB^\fR is a \fB]\fR then it is
+treated as part of the set rather than the closing bracket for
+the set.
+If \fIchars\fR
+contains a sequence of the form \fIa\fB\-\fIb\fR then any
+character between \fIa\fR and \fIb\fR (inclusive) will be excluded
+from the set.
+If the first or last character between the brackets is a \fB\-\fR, then
+it is treated as part of \fIchars\fR rather than indicating a range value.
+.TP
+\fBn\fR
+.
+No input is consumed from the input string.  Instead, the total number
+of characters scanned from the input string so far is stored in the variable.
+.PP
+The number of characters read from the input for a conversion is the
+largest number that makes sense for that particular conversion (e.g.
+as many decimal digits as possible for \fB%d\fR, as
+many octal digits as possible for \fB%o\fR, and so on).
+The input substring for a given conversion terminates either when a
+white-space character is encountered or when the maximum substring
+width has been reached, whichever comes first.
+If a \fB*\fR is present in the conversion specifier
+then no variable is assigned and the next scan argument is not consumed.
+.SH "DIFFERENCES FROM ANSI SSCANF"
+.PP
+The behavior of the \fBscan\fR command is the same as the behavior of
+the ANSI C \fBsscanf\fR procedure except for the following differences:
+.IP [1]
+\fB%p\fR conversion specifier is not supported.
+.IP [2]
+For \fB%c\fR conversions a single character value is
+converted to a decimal string, which is then assigned to the
+corresponding \fIvarName\fR;
+no substring width may be specified for this conversion.
+.IP [3]
+The \fBh\fR modifier is always ignored and the \fBl\fR and \fBL\fR
+modifiers are ignored when converting real values (i.e. type
+\fBdouble\fR is used for the internal representation).  The \fBll\fR
+modifier has no \fBsscanf\fR counterpart.
+.IP [4]
+If the end of the input string is reached before any conversions have been
+performed and no variables are given, an empty string is returned.
+.SH EXAMPLES
+.PP
+Convert a UNICODE character to its numeric value:
+.PP
+.CS
+set char "x"
+set value [\fBscan\fR $char %c]
+.CE
+.PP
+Parse a simple color specification of the form \fI#RRGGBB\fR using
+hexadecimal conversions with substring sizes:
+.PP
+.CS
+set string "#08D03F"
+\fBscan\fR $string "#%2x%2x%2x" r g b
+.CE
+.PP
+Parse a \fIHH:MM\fR time string, noting that this avoids problems with
+octal numbers by forcing interpretation as decimals (if we did not
+care, we would use the \fB%i\fR conversion instead):
+.PP
+.CS
+set string "08:08"   ;# *Not* octal!
+if {[\fBscan\fR $string "%d:%d" hours minutes] != 2} {
+    error "not a valid time string"
+}
+# We have to understand numeric ranges ourselves...
+if {$minutes < 0 || $minutes > 59} {
+    error "invalid number of minutes"
+}
+.CE
+.PP
+Break a string up into sequences of non-whitespace characters (note
+the use of the \fB%n\fR conversion so that we get skipping over
+leading whitespace correct):
+.PP
+.CS
+set string " a string {with braced words} + leading space "
+set words {}
+while {[\fBscan\fR $string %s%n word length] == 2} {
+    lappend words $word
+    set string [string range $string $length end]
+}
+.CE
+.PP
+Parse a simple coordinate string, checking that it is complete by
+looking for the terminating character explicitly:
+.PP
+.CS
+set string "(5.2,-4e-2)"
+# Note that the spaces before the literal parts of
+# the scan pattern are significant, and that ")" is
+# the Unicode character \eu0029
+if {
+    [\fBscan\fR $string " (%f ,%f %c" x y last] != 3
+    || $last != 0x0029
+} then {
+    error "invalid coordinate string"
+}
+puts "X=$x, Y=$y"
+.CE
+.PP
+An interactive session demonstrating the truncation of integer
+values determined by size modifiers:
+.PP
+.CS
+\fI%\fR set tcl_platform(wordSize)
+4
+\fI%\fR scan 20000000000000000000 %d
+2147483647
+\fI%\fR scan 20000000000000000000 %ld
+9223372036854775807
+\fI%\fR scan 20000000000000000000 %lld
+20000000000000000000
+.CE
+.SH "SEE ALSO"
+format(n), sscanf(3)
+.SH KEYWORDS
+conversion specifier, parse, scan
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/doc/seek.n b/doc/seek.n
new file mode 100644
index 0000000..02c5341
--- /dev/null
+++ b/doc/seek.n
@@ -0,0 +1,92 @@
+'\"
+'\" Copyright (c) 1993 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\" 
+.TH seek n 8.1 Tcl "Tcl Built-In Commands"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+seek \- Change the access position for an open channel
+.SH SYNOPSIS
+\fBseek \fIchannelId offset \fR?\fIorigin\fR?
+.BE
+.SH DESCRIPTION
+.PP
+Changes the current access position for \fIchannelId\fR.
+.PP
+\fIChannelId\fR must be an identifier for an open channel such as a
+Tcl standard channel (\fBstdin\fR, \fBstdout\fR, or \fBstderr\fR),
+the return value from an invocation of \fBopen\fR or \fBsocket\fR, or
+the result of a channel creation command provided by a Tcl extension.
+.PP
+The \fIoffset\fR and \fIorigin\fR
+arguments specify the position at which the next read or write will occur
+for \fIchannelId\fR. \fIOffset\fR must be an integer (which may be
+negative) and \fIorigin\fR must be one of the following:
+.TP 10
+\fBstart\fR
+.
+The new access position will be \fIoffset\fR bytes from the start
+of the underlying file or device.
+.TP 10
+\fBcurrent\fR
+.
+The new access position will be \fIoffset\fR bytes from the current
+access position; a negative \fIoffset\fR moves the access position
+backwards in the underlying file or device.
+.TP 10
+\fBend\fR
+.
+The new access position will be \fIoffset\fR bytes from the end of
+the file or device.  A negative \fIoffset\fR places the access position
+before the end of file, and a positive \fIoffset\fR places the access
+position after the end of file.
+.PP
+The \fIorigin\fR argument defaults to \fBstart\fR.
+.PP
+The command flushes all buffered output for the channel before the command
+returns, even if the channel is in non-blocking mode.
+It also discards any buffered and unread input.
+This command returns an empty string.
+An error occurs if this command is applied to channels whose underlying
+file or device does not support seeking.
+.PP
+Note that \fIoffset\fR values are byte offsets, not character
+offsets.  Both \fBseek\fR and \fBtell\fR operate in terms of bytes,
+not characters, unlike \fBread\fR.
+.SH EXAMPLES
+.PP
+Read a file twice:
+.PP
+.CS
+set f [open file.txt]
+set data1 [read $f]
+\fBseek\fR $f 0
+set data2 [read $f]
+close $f
+# $data1 eq $data2 if the file wasn't updated
+.CE
+.PP
+Read the last 10 bytes from a file:
+.PP
+.CS
+set f [open file.data]
+# This is guaranteed to work with binary data but
+# may fail with other encodings...
+fconfigure $f -translation binary
+\fBseek\fR $f -10 end
+set data [read $f 10]
+close $f
+.CE
+.SH "SEE ALSO"
+file(n), open(n), close(n), gets(n), tell(n), Tcl_StandardChannels(3)
+.SH KEYWORDS
+access position, file, seek
+'\" Local Variables:
+'\" mode: nroff
+'\" fill-column: 78
+'\" End:
diff --git a/doc/self.n b/doc/self.n
new file mode 100644
index 0000000..0ad5428
--- /dev/null
+++ b/doc/self.n
@@ -0,0 +1,152 @@
+'\"
+'\" Copyright (c) 2007 Donal K. Fellows
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH self n 0.1 TclOO "TclOO Commands"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+self \- method call internal introspection
+.SH SYNOPSIS
+.nf
+package require TclOO
+
+\fBself\fR ?\fIsubcommand\fR?
+.fi
+.BE
+.SH DESCRIPTION
+The \fBself\fR command, which should only be used from within the context of a
+call to a method (i.e. inside a method, constructor or destructor body) is
+used to allow the method to discover information about how it was called. It
+takes an argument, \fIsubcommand\fR, that tells it what sort of information is
+actually desired; if omitted the result will be the same as if \fBself
+object\fR was invoked. The supported subcommands are:
+.TP
+\fBself call\fR
+.
+This returns a two-element list describing the method implementations used to
+implement the current call chain. The first element is the same as would be
+reported by \fBinfo object\fR \fBcall\fR for the current method (except that this
+also reports useful values from within constructors and destructors, whose
+names are reported as \fB<constructor>\fR and \fB<destructor>\fR
+respectively), and the second element is an index into the first element's
+list that indicates which actual implementation is currently executing (the
+first implementation to execute is always at index 0).
+.TP
+\fBself caller\fR
+.
+When the method was invoked from inside another object method, this subcommand
+returns a three element list describing the containing object and method. The
+first element describes the declaring object or class of the method, the
+second element is the name of the object on which the containing method was
+invoked, and the third element is the name of the method (with the strings
+\fB<constructor>\fR and \fB<destructor>\fR indicating constructors and
+destructors respectively).
+.TP
+\fBself class\fR
+.
+This returns the name of the class that the current method was defined within.
+Note that this will change as the chain of method implementations is traversed
+with \fBnext\fR, and that if the method was defined on an object then this
+will fail.
+.RS
+.PP
+If you want the class of the current object, you need to use this other
+construct:
+.PP
+.CS
+info object class [\fBself object\fR]
+.CE
+.RE
+.TP
+\fBself filter\fR
+.
+When invoked inside a filter, this subcommand returns a three element list
+describing the filter. The first element gives the name of the object or class
+that declared the filter (note that this may be different from the object or
+class that provided the implementation of the filter), the second element is
+either \fBobject\fR or \fBclass\fR depending on whether the declaring entity
+was an object or class, and the third element is the name of the filter.
+.TP
+\fBself method\fR
+.
+This returns the name of the current method (with the strings
+\fB<constructor>\fR and \fB<destructor>\fR indicating constructors and
+destructors respectively).
+.TP
+\fBself namespace\fR
+.
+This returns the name of the unique namespace of the object that the method
+was invoked upon.
+.TP
+\fBself next\fR
+.
+When invoked from a method that is not at the end of a call chain (i.e. where
+the \fBnext\fR command will invoke an actual method implementation), this
+subcommand returns a two element list describing the next element in the
+method call chain; the first element is the name of the class or object that
+declares the next part of the call chain, and the second element is the name
+of the method (with the strings \fB<constructor>\fR and \fB<destructor>\fR
+indicating constructors and destructors respectively). If invoked from a
+method that is at the end of a call chain, this subcommand returns the empty
+string.
+.TP
+\fBself object\fR
+.
+This returns the name of the object that the method was invoked upon.
+.TP
+\fBself target\fR
+.
+When invoked inside a filter implementation, this subcommand returns a two
+element list describing the method being filtered. The first element will be
+the name of the declarer of the method, and the second element will be the
+actual name of the method.
+.SH EXAMPLES
+.PP
+This example shows basic use of \fBself\fR to provide information about the
+current object:
+.PP
+.CS
+oo::class create c {
+    method foo {} {
+        puts "this is the [\fBself\fR] object"
+    }
+}
+c create a
+c create b
+a foo                \fI\(-> prints "this is the ::a object"\fR
+b foo                \fI\(-> prints "this is the ::b object"\fR
+.CE
+.PP
+This demonstrates what a method call chain looks like, and how traversing
+along it changes the index into it:
+.PP
+.CS
+oo::class create c {
+    method x {} {
+        puts "Cls: [\fBself call\fR]"
+    }
+}
+c create a
+oo::objdefine a {
+    method x {} {
+        puts "Obj: [\fBself call\fR]"
+        next
+        puts "Obj: [\fBself call\fR]"
+    }
+}
+a x     \fI\(-> Obj: {{method x object method} {method x ::c method}} 0\fR
+        \fI\(-> Cls: {{method x object method} {method x ::c method}} 1\fR
+        \fI\(-> Obj: {{method x object method} {method x ::c method}} 0\fR
+.CE
+.SH "SEE ALSO"
+info(n), next(n)
+.SH KEYWORDS
+call, introspection, object
+.\" Local variables:
+.\" mode: nroff
+.\" fill-column: 78
+.\" End:
diff --git a/doc/set.n b/doc/set.n
new file mode 100644
index 0000000..f065087
--- /dev/null
+++ b/doc/set.n
@@ -0,0 +1,75 @@
+'\"
+'\" Copyright (c) 1993 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH set n "" Tcl "Tcl Built-In Commands"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+set \- Read and write variables
+.SH SYNOPSIS
+\fBset \fIvarName \fR?\fIvalue\fR?
+.BE
+.SH DESCRIPTION
+.PP
+Returns the value of variable \fIvarName\fR.
+If \fIvalue\fR is specified, then set
+the value of \fIvarName\fR to \fIvalue\fR, creating a new variable
+if one does not already exist, and return its value.
+If \fIvarName\fR contains an open parenthesis and ends with a
+close parenthesis, then it refers to an array element:  the characters
+before the first open parenthesis are the name of the array,
+and the characters between the parentheses are the index within the array.
+Otherwise \fIvarName\fR refers to a scalar variable.
+.PP
+If \fIvarName\fR includes namespace qualifiers
+(in the array name if it refers to an array element), or if \fIvarName\fR
+is unqualified (does not include the names of any containing namespaces)
+but no procedure is active,
+\fIvarName\fR refers to a namespace variable
+resolved according to the rules described under \fBNAME RESOLUTION\fR in
+the \fBnamespace\fR manual page.
+.PP
+If a procedure is active and \fIvarName\fR is unqualified, then
+\fIvarName\fR refers to a parameter or local variable of the procedure,
+unless \fIvarName\fR was declared to resolve differently through one of the
+\fBglobal\fR, \fBvariable\fR or \fBupvar\fR commands.
+.SH EXAMPLES
+.PP
+Store a random number in the variable \fIr\fR:
+.PP
+.CS
+\fBset\fR r [expr {rand()}]
+.CE
+.PP
+Store a short message in an array element:
+.PP
+.CS
+\fBset\fR anAry(msg) "Hello, World!"
+.CE
+.PP
+Store a short message in an array element specified by a variable:
+.PP
+.CS
+\fBset\fR elemName "msg"
+\fBset\fR anAry($elemName) "Hello, World!"
+.CE
+.PP
+Copy a value into the variable \fIout\fR from a variable whose name is
+stored in the \fIvbl\fR (note that it is often easier to use arrays in
+practice instead of doing double-dereferencing):
+.PP
+.CS
+\fBset\fR in0 "small random"
+\fBset\fR in1 "large random"
+\fBset\fR vbl in[expr {rand() >= 0.5}]
+\fBset\fR out [\fBset\fR $vbl]
+.CE
+.SH "SEE ALSO"
+expr(n), global(n), namespace(n), proc(n), trace(n), unset(n), upvar(n), variable(n)
+.SH KEYWORDS
+read, write, variable
diff --git a/doc/socket.n b/doc/socket.n
new file mode 100644
index 0000000..3efdb37
--- /dev/null
+++ b/doc/socket.n
@@ -0,0 +1,235 @@
+'\"
+'\" Copyright (c) 1996 Sun Microsystems, Inc.
+'\" Copyright (c) 1998-1999 by Scriptics Corporation.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH socket n 8.6 Tcl "Tcl Built-In Commands"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+socket \- Open a TCP network connection
+.SH SYNOPSIS
+.sp
+\fBsocket \fR?\fIoptions\fR? \fIhost port\fR
+.sp
+\fBsocket\fR \fB\-server \fIcommand\fR ?\fIoptions\fR? \fIport\fR
+.BE
+.SH DESCRIPTION
+.PP
+This command opens a network socket and returns a channel identifier
+that may be used in future invocations of commands like \fBread\fR,
+\fBputs\fR and \fBflush\fR.  At present only the TCP network protocol
+is supported over IPv4 and IPv6; future releases may include support
+for additional protocols.  The \fBsocket\fR command may be used to
+open either the client or server side of a connection, depending on
+whether the \fB\-server\fR switch is specified.
+.PP
+Note that the default encoding for \fIall\fR sockets is the system
+encoding, as returned by \fBencoding system\fR.  Most of the time, you
+will need to use \fBchan configure\fR to alter this to something else,
+such as \fIutf\-8\fR (ideal for communicating with other Tcl
+processes) or \fIiso8859\-1\fR (useful for many network protocols,
+especially the older ones).
+.SH "CLIENT SOCKETS"
+.PP
+If the \fB\-server\fR option is not specified, then the client side of a
+connection is opened and the command returns a channel identifier
+that can be used for both reading and writing.
+\fIPort\fR and \fIhost\fR specify a port
+to connect to;  there must be a server accepting connections on
+this port.  \fIPort\fR is an integer port number
+(or service name, where supported and understood by the host operating
+system) and \fIhost\fR
+is either a domain-style name such as \fBwww.tcl.tk\fR or
+a numerical IPv4 or IPv6 address such as \fB127.0.0.1\fR or \fB2001:DB8::1\fR.
+Use \fIlocalhost\fR to refer to the host on which the command is invoked.
+.PP
+The following options may also be present before \fIhost\fR
+to specify additional information about the connection:
+.TP
+\fB\-myaddr\fI addr\fR
+.
+\fIAddr\fR gives the domain-style name or numerical IP address of
+the client-side network interface to use for the connection.
+This option may be useful if the client machine has multiple network
+interfaces.  If the option is omitted then the client-side interface
+will be chosen by the system software.
+.TP
+\fB\-myport\fI port\fR
+.
+\fIPort\fR specifies an integer port number (or service name, where
+supported and understood by the host operating system) to use for the
+client's
+side of the connection.  If this option is omitted, the client's
+port number will be chosen at random by the system software.
+.TP
+\fB\-async\fR
+.
+This option will cause the client socket to be connected
+asynchronously. This means that the socket will be created immediately
+but may not yet be connected to the server, when the call to
+\fBsocket\fR returns.
+.RS
+.PP
+When a \fBgets\fR or \fBflush\fR is done on the socket before the
+connection attempt succeeds or fails, if the socket is in blocking
+mode, the operation will wait until the connection is completed or
+fails. If the socket is in nonblocking mode and a \fBgets\fR or
+\fBflush\fR is done on the socket before the connection attempt
+succeeds or fails, the operation returns immediately and
+\fBfblocked\fR on the socket returns 1. Synchronous client sockets may
+be switched (after they have connected) to operating in asynchronous
+mode using:
+.PP
+.CS
+\fBchan configure \fIchan \fB\-blocking 0\fR
+.CE
+.PP
+See the \fBchan configure\fR command for more details.
+.PP
+The Tcl event loop should be running while an asynchronous connection
+is in progress, because it may have to do several connection attempts
+in the background. Running the event loop also allows you to set up a
+writable channel event on the socket to get notified when the
+asynchronous connection has succeeded or failed. See the \fBvwait\fR
+and the \fBchan\fR commands for more details on the event loop and
+channel events.
+.PP
+The \fBchan configure\fR option \fB-connecting\fR may be used to check if the connect is still running. To verify a successful connect, the option \fB-error\fR may be checked when \fB-connecting\fR returned 0.
+.PP
+Operation without the event queue requires at the moment calls to \fBchan configure\fR to advance the internal state machine.
+.RE
+.SH "SERVER SOCKETS"
+.PP
+If the \fB\-server\fR option is specified then the new socket will be
+a server that listens on the given \fIport\fR (either an integer or a
+service name, where supported and understood by the host operating
+system; if \fIport\fR is zero, the operating system will allocate a
+free port to the server socket which may be discovered by using
+\fBchan configure\fR to read the \fB\-sockname\fR option). If the host
+supports both, IPv4 and IPv6, the socket will listen on both address
+families. Tcl will automatically accept connections to the given port.
+For each connection Tcl will create a new channel that may be used to
+communicate with the client.  Tcl then invokes \fIcommand\fR (properly
+a command prefix list, see the \fBEXAMPLES\fR below) with three
+additional arguments: the name of the new channel, the address, in
+network address notation, of the client's host, and the client's port
+number.
+.PP
+The following additional option may also be specified before \fIport\fR:
+.TP
+\fB\-myaddr\fI addr\fR
+.
+\fIAddr\fR gives the domain-style name or numerical IP address of the
+server-side network interface to use for the connection.  This option
+may be useful if the server machine has multiple network interfaces.
+If the option is omitted then the server socket is bound to the
+wildcard address so that it can accept connections from any
+interface. If \fIaddr\fR is a domain name that resolves to multiple IP
+addresses that are available on the local machine, the socket will
+listen on all of them.
+.PP
+Server channels cannot be used for input or output; their sole use is to
+accept new client connections. The channels created for each incoming
+client connection are opened for input and output. Closing the server
+channel shuts down the server so that no new connections will be
+accepted;  however, existing connections will be unaffected.
+.PP
+Server sockets depend on the Tcl event mechanism to find out when
+new connections are opened.  If the application does not enter the
+event loop, for example by invoking the \fBvwait\fR command or
+calling the C procedure \fBTcl_DoOneEvent\fR, then no connections
+will be accepted.
+.PP
+If \fIport\fR is specified as zero, the operating system will allocate
+an unused port for use as a server socket.  The port number actually
+allocated may be retrieved from the created server socket using the
+\fBchan configure\fR command to retrieve the \fB\-sockname\fR option as
+described below.
+.SH "CONFIGURATION OPTIONS"
+.PP
+The \fBchan configure\fR command can be used to query several readonly
+configuration options for socket channels:
+.TP
+\fB\-error\fR
+.
+This option gets the current error status of the given socket.  This
+is useful when you need to determine if an asynchronous connect
+operation succeeded.  If there was an error, the error message is
+returned.  If there was no error, an empty string is returned.
+.RS
+.PP
+Note that the error status is reset by the read operation; this mimics
+the underlying getsockopt(SO_ERROR) call.
+.RE
+.TP
+\fB\-sockname\fR
+.
+For client sockets (including the channels that get created when a
+client connects to a server socket) this option returns a list of
+three elements, the address, the host name and the port number for the
+socket. If the host name cannot be computed, the second element is
+identical to the address, the first element of the list.
+.RS
+.PP
+For server sockets this option returns a list of a multiple of three
+elements each group of which have the same meaning as described
+above. The list contains more than one group when the server socket
+was created without \fB\-myaddr\fR or with the argument to
+\fB\-myaddr\fR being a domain name that resolves multiple IP addresses
+that are local to the invoking host.
+.RE
+.TP
+\fB\-peername\fR
+.
+This option is not supported by server sockets. For client and accepted
+sockets, this option returns a list of three elements; these are the
+address, the host name and the port to which the peer socket is connected
+or bound. If the host name cannot be computed, the second element of the
+list is identical to the address, its first element.
+.TP
+\fB\-connecting\fR
+.
+This option is not supported by server sockets. For client sockets, this option returns 1 if an asyncroneous connect is still in progress, 0 otherwise.
+.PP
+.SH "EXAMPLES"
+.PP
+Here is a very simple time server:
+.PP
+.CS
+proc Server {startTime channel clientaddr clientport} {
+    puts "Connection from $clientaddr registered"
+    set now [clock seconds]
+    puts $channel [clock format $now]
+    puts $channel "[expr {$now - $startTime}] since start"
+    close $channel
+}
+
+\fBsocket -server\fR [list Server [clock seconds]] 9900
+vwait forever
+.CE
+.PP
+And here is the corresponding client to talk to the server and extract
+some information:
+.PP
+.CS
+set server localhost
+set sockChan [\fBsocket\fR $server 9900]
+gets $sockChan line1
+gets $sockChan line2
+close $sockChan
+puts "The time on $server is $line1"
+puts "That is [lindex $line2 0]s since the server started"
+.CE
+.SH "HISTORY"
+Support for IPv6 was added in Tcl 8.6.
+.SH "SEE ALSO"
+chan(n), flush(n), open(n), read(n)
+.SH KEYWORDS
+asynchronous I/O, bind, channel, connection, domain name, host, network address, socket, tcp
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/doc/source.n b/doc/source.n
new file mode 100644
index 0000000..67d4b6b
--- /dev/null
+++ b/doc/source.n
@@ -0,0 +1,71 @@
+'\"
+'\" Copyright (c) 1993 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\" Copyright (c) 2000 Scriptics Corporation.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\" 
+.TH source n "" Tcl "Tcl Built-In Commands"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+source \- Evaluate a file or resource as a Tcl script
+.SH SYNOPSIS
+\fBsource \fIfileName\fR
+.sp
+\fBsource\fR \fB\-encoding \fIencodingName fileName\fR
+.BE
+.SH DESCRIPTION
+.PP
+This command takes the contents of the specified file or resource
+and passes it to the Tcl interpreter as a text script.  The return
+value from \fBsource\fR is the return value of the last command
+executed in the script.  If an error occurs in evaluating the contents
+of the script then the \fBsource\fR command will return that error.
+If a \fBreturn\fR command is invoked from within the script then the
+remainder of the file will be skipped and the \fBsource\fR command
+will return normally with the result from the \fBreturn\fR command.
+.PP
+The end-of-file character for files is
+.QW \e32
+(^Z) for all platforms.
+The source command will read files up to this character.  This
+restriction does not exist for the \fBread\fR or \fBgets\fR commands,
+allowing for files containing code and data segments (scripted documents).
+If you require a
+.QW ^Z
+in code for string comparison, you can use
+.QW \e032
+or
+.QW \eu001a ,
+which will be safely substituted by the Tcl interpreter into
+.QW ^Z .
+.PP
+A leading BOM (Byte order mark) contained in the file is ignored for unicode encodings (utf-8, unicode).
+.PP
+The \fB\-encoding\fR option is used to specify the encoding of
+the data stored in \fIfileName\fR.  When the \fB\-encoding\fR option
+is omitted, the system encoding is assumed.
+.SH EXAMPLE
+.PP
+Run the script in the file \fBfoo.tcl\fR and then the script in the
+file \fBbar.tcl\fR:
+.PP
+.CS
+\fBsource\fR foo.tcl
+\fBsource\fR bar.tcl
+.CE
+.PP
+Alternatively:
+.PP
+.CS
+foreach scriptFile {foo.tcl bar.tcl} {
+    \fBsource\fR $scriptFile
+}
+.CE
+.SH "SEE ALSO"
+file(n), cd(n), encoding(n), info(n)
+.SH KEYWORDS
+file, script
diff --git a/doc/split.n b/doc/split.n
new file mode 100644
index 0000000..f1c66d0
--- /dev/null
+++ b/doc/split.n
@@ -0,0 +1,93 @@
+'\"
+'\" Copyright (c) 1993 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\" 
+.TH split n "" Tcl "Tcl Built-In Commands"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+split \- Split a string into a proper Tcl list
+.SH SYNOPSIS
+\fBsplit \fIstring \fR?\fIsplitChars\fR?
+.BE
+.SH DESCRIPTION
+.PP
+Returns a list created by splitting \fIstring\fR at each character
+that is in the \fIsplitChars\fR argument.
+Each element of the result list will consist of the
+characters from \fIstring\fR that lie between instances of the
+characters in \fIsplitChars\fR.
+Empty list elements will be generated if \fIstring\fR contains
+adjacent characters in \fIsplitChars\fR, or if the first or last
+character of \fIstring\fR is in \fIsplitChars\fR.
+If \fIsplitChars\fR is an empty string then each character of
+\fIstring\fR becomes a separate element of the result list.
+\fISplitChars\fR defaults to the standard white-space characters.
+.SH EXAMPLES
+.PP
+Divide up a USENET group name into its hierarchical components:
+.PP
+.CS
+\fBsplit\fR "comp.lang.tcl" .
+      \fI\(-> comp lang tcl\fR
+.CE
+.PP
+See how the \fBsplit\fR command splits on \fIevery\fR character in
+\fIsplitChars\fR, which can result in information loss if you are not
+careful:
+.PP
+.CS
+\fBsplit\fR "alpha beta gamma" "temp"
+      \fI\(-> al {ha b} {} {a ga} {} a\fR
+.CE
+.PP
+Extract the list words from a string that is not a well-formed list:
+.PP
+.CS
+\fBsplit\fR "Example with {unbalanced brace character"
+      \fI\(-> Example with \e{unbalanced brace character\fR
+.CE
+.PP
+Split a string into its constituent characters
+.PP
+.CS
+\fBsplit\fR "Hello world" {}
+      \fI\(-> H e l l o { } w o r l d\fR
+.CE
+.SS "PARSING RECORD-ORIENTED FILES"
+.PP
+Parse a Unix /etc/passwd file, which consists of one entry per line,
+with each line consisting of a colon-separated list of fields:
+.PP
+.CS
+## Read the file
+set fid [open /etc/passwd]
+set content [read $fid]
+close $fid
+
+## Split into records on newlines
+set records [\fBsplit\fR $content "\en"]
+
+## Iterate over the records
+foreach rec $records {
+
+    ## Split into fields on colons
+    set fields [\fBsplit\fR $rec ":"]
+
+    ## Assign fields to variables and print some out...
+    lassign $fields \e
+            userName password uid grp longName homeDir shell
+    puts "$longName uses [file tail $shell] for a login shell"
+}
+.CE
+.SH "SEE ALSO"
+join(n), list(n), string(n)
+.SH KEYWORDS
+list, split, string
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/doc/string.n b/doc/string.n
new file mode 100644
index 0000000..00ce85c
--- /dev/null
+++ b/doc/string.n
@@ -0,0 +1,485 @@
+.\"
+.\" Copyright (c) 1993 The Regents of the University of California.
+.\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+.\"
+.\" See the file "license.terms" for information on usage and redistribution
+.\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+.\"
+.TH string n 8.1 Tcl "Tcl Built-In Commands"
+.so man.macros
+.BS
+.\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+string \- Manipulate strings
+.SH SYNOPSIS
+\fBstring \fIoption arg \fR?\fIarg ...?\fR
+.BE
+.SH DESCRIPTION
+.PP
+Performs one of several string operations, depending on \fIoption\fR.
+The legal \fIoption\fRs (which may be abbreviated) are:
+.TP
+\fBstring cat\fR ?\fIstring1\fR? ?\fIstring2...\fR?
+.VS 8.6.2
+Concatenate the given \fIstring\fRs just like placing them directly
+next to each other and return the resulting compound string.  If no
+\fIstring\fRs are present, the result is an empty string.
+.RS
+.PP
+This primitive is occasionally handier than juxtaposition of strings
+when mixed quoting is wanted, or when the aim is to return the result
+of a concatenation without resorting to \fBreturn\fR \fB\-level 0\fR,
+and is more efficient than building a list of arguments and using
+\fBjoin\fR with an empty join string.
+.RE
+.VE
+.TP
+\fBstring compare\fR ?\fB\-nocase\fR? ?\fB\-length\fI length\fR? \fIstring1 string2\fR
+.
+Perform a character-by-character comparison of strings \fIstring1\fR
+and \fIstring2\fR.  Returns \-1, 0, or 1, depending on whether
+\fIstring1\fR is lexicographically less than, equal to, or greater
+than \fIstring2\fR.  If \fB\-length\fR is specified, then only the
+first \fIlength\fR characters are used in the comparison.  If
+\fB\-length\fR is negative, it is ignored.  If \fB\-nocase\fR is
+specified, then the strings are compared in a case-insensitive manner.
+.TP
+\fBstring equal\fR ?\fB\-nocase\fR? ?\fB\-length\fI length\fR? \fIstring1 string2\fR
+.
+Perform a character-by-character comparison of strings \fIstring1\fR
+and \fIstring2\fR.  Returns 1 if \fIstring1\fR and \fIstring2\fR are
+identical, or 0 when not.  If \fB\-length\fR is specified, then only
+the first \fIlength\fR characters are used in the comparison.  If
+\fB\-length\fR is negative, it is ignored.  If \fB\-nocase\fR is
+specified, then the strings are compared in a case-insensitive manner.
+.TP
+\fBstring first \fIneedleString haystackString\fR ?\fIstartIndex\fR?
+.
+Search \fIhaystackString\fR for a sequence of characters that exactly match
+the characters in \fIneedleString\fR.  If found, return the index of the
+first character in the first such match within \fIhaystackString\fR.  If not
+found, return \-1.  If \fIstartIndex\fR is specified (in any of the
+forms described in \fBSTRING INDICES\fR), then the search is
+constrained to start with the character in \fIhaystackString\fR specified by
+the index.  For example,
+.RS
+.PP
+.CS
+\fBstring first a 0a23456789abcdef 5\fR
+.CE
+.PP
+will return \fB10\fR, but
+.PP
+.CS
+\fBstring first a 0123456789abcdef 11\fR
+.CE
+.PP
+will return \fB\-1\fR.
+.RE
+.TP
+\fBstring index \fIstring charIndex\fR
+.
+Returns the \fIcharIndex\fR'th character of the \fIstring\fR argument.
+A \fIcharIndex\fR of 0 corresponds to the first character of the
+string.  \fIcharIndex\fR may be specified as described in the
+\fBSTRING INDICES\fR section.
+.RS
+.PP
+If \fIcharIndex\fR is less than 0 or greater than or equal to the
+length of the string then this command returns an empty string.
+.RE
+.TP
+\fBstring is \fIclass\fR ?\fB\-strict\fR? ?\fB\-failindex \fIvarname\fR? \fIstring\fR
+.
+Returns 1 if \fIstring\fR is a valid member of the specified character
+class, otherwise returns 0.  If \fB\-strict\fR is specified, then an
+empty string returns 0, otherwise an empty string will return 1 on
+any class.  If \fB\-failindex\fR is specified, then if the function
+returns 0, the index in the string where the class was no longer valid
+will be stored in the variable named \fIvarname\fR.  The \fIvarname\fR
+will not be set if \fBstring is\fR returns 1.  The following character
+classes are recognized (the class name can be abbreviated):
+.RS
+.IP \fBalnum\fR 12
+Any Unicode alphabet or digit character.
+.IP \fBalpha\fR 12
+Any Unicode alphabet character.
+.IP \fBascii\fR 12
+Any character with a value less than \eu0080 (those that are in the
+7\-bit ascii range).
+.IP \fBboolean\fR 12
+Any of the forms allowed to \fBTcl_GetBoolean\fR.
+.IP \fBcontrol\fR 12
+Any Unicode control character.
+.IP \fBdigit\fR 12
+Any Unicode digit character.  Note that this includes characters
+outside of the [0\-9] range.
+.IP \fBdouble\fR 12
+Any of the valid forms for a double in Tcl, with optional surrounding
+whitespace.  In case of under/overflow in the value, 0 is returned and
+the \fIvarname\fR will contain \-1.
+.IP \fBentier\fR 12
+.VS 8.6
+Any of the valid string formats for an integer value of arbitrary size
+in Tcl, with optional surrounding whitespace. The formats accepted are
+exactly those accepted by the C routine \fBTcl_GetBignumFromObj\fR.
+.VE
+.IP \fBfalse\fR 12
+Any of the forms allowed to \fBTcl_GetBoolean\fR where the value is
+false.
+.IP \fBgraph\fR 12
+Any Unicode printing character, except space.
+.IP \fBinteger\fR 12
+Any of the valid string formats for a 32-bit integer value in Tcl,
+with optional surrounding whitespace.  In case of under/overflow in
+the value, 0 is returned and the \fIvarname\fR will contain \-1.
+.IP \fBlist\fR 12
+Any proper list structure, with optional surrounding whitespace. In
+case of improper list structure, 0 is returned and the \fIvarname\fR
+will contain the index of the
+.QW element
+where the list parsing fails, or \-1 if this cannot be determined.
+.IP \fBlower\fR 12
+Any Unicode lower case alphabet character.
+.IP \fBprint\fR 12
+Any Unicode printing character, including space.
+.IP \fBpunct\fR 12
+Any Unicode punctuation character.
+.IP \fBspace\fR 12
+Any Unicode whitespace character, mongolian vowel separator
+(U+180e), zero width space (U+200b), word joiner (U+2060) or
+zero width no-break space (U+feff) (=BOM).
+.IP \fBtrue\fR 12
+Any of the forms allowed to \fBTcl_GetBoolean\fR where the value is
+true.
+.IP \fBupper\fR 12
+Any upper case alphabet character in the Unicode character set.
+.IP \fBwideinteger\fR 12
+Any of the valid forms for a wide integer in Tcl, with optional
+surrounding whitespace.  In case of under/overflow in the value, 0 is
+returned and the \fIvarname\fR will contain \-1.
+.IP \fBwordchar\fR 12
+Any Unicode word character.  That is any alphanumeric character, and
+any Unicode connector punctuation characters (e.g. underscore).
+.IP \fBxdigit\fR 12
+Any hexadecimal digit character ([0\-9A\-Fa\-f]).
+.PP
+In the case of \fBboolean\fR, \fBtrue\fR and \fBfalse\fR, if the
+function will return 0, then the \fIvarname\fR will always be set to
+0, due to the varied nature of a valid boolean value.
+.RE
+.TP
+\fBstring last \fIneedleString haystackString\fR ?\fIlastIndex\fR?
+.
+Search \fIhaystackString\fR for a sequence of characters that exactly match
+the characters in \fIneedleString\fR.  If found, return the index of the
+first character in the last such match within \fIhaystackString\fR.  If there
+is no match, then return \-1.  If \fIlastIndex\fR is specified (in any
+of the forms described in \fBSTRING INDICES\fR), then only the
+characters in \fIhaystackString\fR at or before the specified \fIlastIndex\fR
+will be considered by the search.  For example,
+.RS
+.PP
+.CS
+\fBstring last a 0a23456789abcdef 15\fR
+.CE
+.PP
+will return \fB10\fR, but
+.PP
+.CS
+\fBstring last a 0a23456789abcdef 9\fR
+.CE
+.PP
+will return \fB1\fR.
+.RE
+.TP
+\fBstring length \fIstring\fR
+.
+Returns a decimal string giving the number of characters in
+\fIstring\fR.  Note that this is not necessarily the same as the
+number of bytes used to store the string.  If the value is a
+byte array value (such as those returned from reading a binary encoded
+channel), then this will return the actual byte length of the value.
+.TP
+\fBstring map\fR ?\fB\-nocase\fR? \fImapping string\fR
+.
+Replaces substrings in \fIstring\fR based on the key-value pairs in
+\fImapping\fR.  \fImapping\fR is a list of \fIkey value key value ...\fR
+as in the form returned by \fBarray get\fR.  Each instance of a
+key in the string will be replaced with its corresponding value.  If
+\fB\-nocase\fR is specified, then matching is done without regard to
+case differences. Both \fIkey\fR and \fIvalue\fR may be multiple
+characters.  Replacement is done in an ordered manner, so the key
+appearing first in the list will be checked first, and so on.
+\fIstring\fR is only iterated over once, so earlier key replacements
+will have no affect for later key matches.  For example,
+.RS
+.PP
+.CS
+\fBstring map {abc 1 ab 2 a 3 1 0} 1abcaababcabababc\fR
+.CE
+.PP
+will return the string \fB01321221\fR.
+.PP
+Note that if an earlier \fIkey\fR is a prefix of a later one, it will
+completely mask the later one.  So if the previous example is
+reordered like this,
+.PP
+.CS
+\fBstring map {1 0 ab 2 a 3 abc 1} 1abcaababcabababc\fR
+.CE
+.PP
+it will return the string \fB02c322c222c\fR.
+.RE
+.TP
+\fBstring match\fR ?\fB\-nocase\fR? \fIpattern\fR \fIstring\fR
+.
+See if \fIpattern\fR matches \fIstring\fR; return 1 if it does, 0 if
+it does not.  If \fB\-nocase\fR is specified, then the pattern attempts
+to match against the string in a case insensitive manner.  For the two
+strings to match, their contents must be identical except that the
+following special sequences may appear in \fIpattern\fR:
+.RS
+.IP \fB*\fR 10
+Matches any sequence of characters in \fIstring\fR, including a null
+string.
+.IP \fB?\fR 10
+Matches any single character in \fIstring\fR.
+.IP \fB[\fIchars\fB]\fR 10
+Matches any character in the set given by \fIchars\fR.  If a sequence
+of the form \fIx\fB\-\fIy\fR appears in \fIchars\fR, then any
+character between \fIx\fR and \fIy\fR, inclusive, will match.  When
+used with \fB\-nocase\fR, the end points of the range are converted to
+lower case first.  Whereas {[A\-z]} matches
+.QW _
+when matching case-sensitively (since
+.QW _
+falls between the
+.QW Z
+and
+.QW a ),
+with \fB\-nocase\fR this is considered like {[A\-Za\-z]} (and
+probably what was meant in the first place).
+.IP \fB\e\fIx\fR 10
+Matches the single character \fIx\fR.  This provides a way of avoiding
+the special interpretation of the characters \fB*?[]\e\fR in
+\fIpattern\fR.
+.RE
+.TP
+\fBstring range \fIstring first last\fR
+.
+Returns a range of consecutive characters from \fIstring\fR, starting
+with the character whose index is \fIfirst\fR and ending with the
+character whose index is \fIlast\fR. An index of 0 refers to the first
+character of the string.  \fIfirst\fR and \fIlast\fR may be specified
+as for the \fBindex\fR method.  If \fIfirst\fR is less than zero then
+it is treated as if it were zero, and if \fIlast\fR is greater than or
+equal to the length of the string then it is treated as if it were
+\fBend\fR.  If \fIfirst\fR is greater than \fIlast\fR then an empty
+string is returned.
+.TP
+\fBstring repeat \fIstring count\fR
+.
+Returns \fIstring\fR repeated \fIcount\fR number of times.
+.TP
+\fBstring replace \fIstring first last\fR ?\fInewstring\fR?
+.
+Removes a range of consecutive characters from \fIstring\fR, starting
+with the character whose index is \fIfirst\fR and ending with the
+character whose index is \fIlast\fR.  An index of 0 refers to the
+first character of the string.  \fIFirst\fR and \fIlast\fR may be
+specified as for the \fBindex\fR method.  If \fInewstring\fR is
+specified, then it is placed in the removed character range.  If
+\fIfirst\fR is less than zero then it is treated as if it were zero,
+and if \fIlast\fR is greater than or equal to the length of the string
+then it is treated as if it were \fBend\fR.  If \fIfirst\fR is greater
+than \fIlast\fR or the length of the initial string, or \fIlast\fR is
+less than 0, then the initial string is returned untouched.
+.TP
+\fBstring reverse \fIstring\fR
+.
+Returns a string that is the same length as \fIstring\fR but with its
+characters in the reverse order.
+.TP
+\fBstring tolower \fIstring\fR ?\fIfirst\fR? ?\fIlast\fR?
+.
+Returns a value equal to \fIstring\fR except that all upper (or title)
+case letters have been converted to lower case.  If \fIfirst\fR is
+specified, it refers to the first char index in the string to start
+modifying.  If \fIlast\fR is specified, it refers to the char index in
+the string to stop at (inclusive).  \fIfirst\fR and \fIlast\fR may be
+specified using the forms described in \fBSTRING INDICES\fR.
+.TP
+\fBstring totitle \fIstring\fR ?\fIfirst\fR? ?\fIlast\fR?
+.
+Returns a value equal to \fIstring\fR except that the first character
+in \fIstring\fR is converted to its Unicode title case variant (or
+upper case if there is no title case variant) and the rest of the
+string is converted to lower case.  If \fIfirst\fR is specified, it
+refers to the first char index in the string to start modifying.  If
+\fIlast\fR is specified, it refers to the char index in the string to
+stop at (inclusive).  \fIfirst\fR and \fIlast\fR may be specified
+using the forms described in \fBSTRING INDICES\fR.
+.TP
+\fBstring toupper \fIstring\fR ?\fIfirst\fR? ?\fIlast\fR?
+.
+Returns a value equal to \fIstring\fR except that all lower (or title)
+case letters have been converted to upper case.  If \fIfirst\fR is
+specified, it refers to the first char index in the string to start
+modifying.  If \fIlast\fR is specified, it refers to the char index in
+the string to stop at (inclusive).  \fIfirst\fR and \fIlast\fR may be
+specified using the forms described in \fBSTRING INDICES\fR.
+.TP
+\fBstring trim \fIstring\fR ?\fIchars\fR?
+.
+Returns a value equal to \fIstring\fR except that any leading or
+trailing characters present in the string given by \fIchars\fR are removed.  If
+\fIchars\fR is not specified then white space is removed (any character
+for which \fBstring is space\fR returns 1, and "\0").
+.TP
+\fBstring trimleft \fIstring\fR ?\fIchars\fR?
+.
+Returns a value equal to \fIstring\fR except that any leading
+characters present in the string given by \fIchars\fR are removed.  If
+\fIchars\fR is not specified then white space is removed (any character
+for which \fBstring is space\fR returns 1, and "\0").
+.TP
+\fBstring trimright \fIstring\fR ?\fIchars\fR?
+.
+Returns a value equal to \fIstring\fR except that any trailing
+characters present in the string given by \fIchars\fR are removed.  If
+\fIchars\fR is not specified then white space is removed (any character
+for which \fBstring is space\fR returns 1, and "\0").
+.SS "OBSOLETE SUBCOMMANDS"
+.PP
+These subcommands are currently supported, but are likely to go away in a
+future release as their functionality is either virtually never used or highly
+misleading.
+.TP
+\fBstring bytelength \fIstring\fR
+.
+Returns a decimal string giving the number of bytes used to represent
+\fIstring\fR in memory when encoded as Tcl's internal modified UTF\-8;
+Tcl may use other encodings for \fIstring\fR as well, and does not
+guarantee to only use a single encoding for a particular \fIstring\fR.
+Because UTF\-8 uses a variable number of bytes to represent Unicode
+characters, the byte length will not be the same as the character
+length in general.  The cases where a script cares about the byte
+length are rare.
+.RS
+.PP
+In almost all cases, you should use the
+\fBstring length\fR operation (including determining the length of a
+Tcl byte array value).  Refer to the \fBTcl_NumUtfChars\fR manual
+entry for more details on the UTF\-8 representation.
+.PP
+Formally, the \fBstring bytelength\fR operation returns the content of
+the \fIlength\fR field of the \fBTcl_Obj\fR structure, after calling
+\fBTcl_GetString\fR to ensure that the \fIbytes\fR field is populated.
+This is highly unlikely to be useful to Tcl scripts, as Tcl's internal
+encoding is not strict UTF\-8, but rather a modified CESU\-8 with a
+denormalized NUL (identical to that used in a number of places by
+Java's serialization mechanism) to enable basic processing with
+non-Unicode-aware C functions.  As this representation should only
+ever be used by Tcl's implementation, the number of bytes used to
+store the representation is of very low value (except to C extension
+code, which has direct access for the purpose of memory management,
+etc.)
+.PP
+\fICompatibility note:\fR it is likely that this subcommand will be
+withdrawn in a future version of Tcl. It is better to use the
+\fBencoding convertto\fR command to convert a string to a known
+encoding and then apply \fBstring length\fR to that.
+.PP
+.CS
+\fBstring length\fR [encoding convertto utf-8 $theString]
+.CE
+.RE
+.TP
+\fBstring wordend \fIstring charIndex\fR
+.
+Returns the index of the character just after the last one in the word
+containing character \fIcharIndex\fR of \fIstring\fR.  \fIcharIndex\fR
+may be specified using the forms in \fBSTRING INDICES\fR.  A word is
+considered to be any contiguous range of alphanumeric (Unicode letters
+or decimal digits) or underscore (Unicode connector punctuation)
+characters, or any single character other than these.
+.TP
+\fBstring wordstart \fIstring charIndex\fR
+.
+Returns the index of the first character in the word containing character
+\fIcharIndex\fR of \fIstring\fR.  \fIcharIndex\fR may be specified using the
+forms in \fBSTRING INDICES\fR.  A word is considered to be any contiguous
+range of alphanumeric (Unicode letters or decimal digits) or underscore
+(Unicode connector punctuation) characters, or any single character other than
+these.
+.SH "STRING INDICES"
+.PP
+When referring to indices into a string (e.g., for \fBstring index\fR
+or \fBstring range\fR) the following formats are supported:
+.IP \fIinteger\fR 10
+For any index value that passes \fBstring is integer \-strict\fR,
+the char specified at this integral index (e.g., \fB2\fR would refer to the
+.QW c
+in
+.QW abcd ).
+.IP \fBend\fR 10
+The last char of the string (e.g., \fBend\fR would refer to the
+.QW d
+in
+.QW abcd ).
+.IP \fBend\-\fIN\fR 10
+The last char of the string minus the specified integer offset \fIN\fR (e.g.,
+.QW \fBend\-1\fR
+would refer to the
+.QW c
+in
+.QW abcd ).
+.IP \fBend+\fIN\fR 10
+The last char of the string plus the specified integer offset \fIN\fR (e.g.,
+.QW \fBend+\-1\fR
+would refer to the
+.QW c
+in
+.QW abcd ).
+.IP \fIM\fB+\fIN\fR 10
+The char specified at the integral index that is the sum of
+integer values \fIM\fR and \fIN\fR (e.g.,
+.QW \fB1+1\fR
+would refer to the
+.QW c
+in
+.QW abcd ).
+.IP \fIM\fB\-\fIN\fR 10
+The char specified at the integral index that is the difference of
+integer values \fIM\fR and \fIN\fR (e.g.,
+.QW \fB2\-1\fR
+would refer to the
+.QW b
+in
+.QW abcd ).
+.PP
+In the specifications above, the integer value \fIM\fR contains no
+trailing whitespace and the integer value \fIN\fR contains no
+leading whitespace.
+.SH EXAMPLE
+.PP
+Test if the string in the variable \fIstring\fR is a proper non-empty
+prefix of the string \fBfoobar\fR.
+.PP
+.CS
+set length [\fBstring length\fR $string]
+if {$length == 0} {
+    set isPrefix 0
+} else {
+    set isPrefix [\fBstring equal\fR \-length $length $string "foobar"]
+}
+.CE
+.SH "SEE ALSO"
+expr(n), list(n)
+.SH KEYWORDS
+case conversion, compare, index, match, pattern, string, word, equal,
+ctype, character, reverse
+.\" Local Variables:
+.\" mode: nroff
+.\" End:
diff --git a/doc/subst.n b/doc/subst.n
new file mode 100644
index 0000000..4518140
--- /dev/null
+++ b/doc/subst.n
@@ -0,0 +1,164 @@
+'\"
+'\" Copyright (c) 1994 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\" Copyright (c) 2001 Donal K. Fellows
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH subst n 7.4 Tcl "Tcl Built-In Commands"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+subst \- Perform backslash, command, and variable substitutions
+.SH SYNOPSIS
+\fBsubst \fR?\fB\-nobackslashes\fR? ?\fB\-nocommands\fR? ?\fB\-novariables\fR? \fIstring\fR
+.BE
+.SH DESCRIPTION
+.PP
+This command performs variable substitutions, command substitutions,
+and backslash substitutions on its \fIstring\fR argument and
+returns the fully-substituted result.
+The substitutions are performed in exactly the same way as for
+Tcl commands.
+As a result, the \fIstring\fR argument is actually substituted twice,
+once by the Tcl parser in the usual fashion for Tcl commands, and
+again by the \fIsubst\fR command.
+.PP
+If any of the \fB\-nobackslashes\fR, \fB\-nocommands\fR, or
+\fB\-novariables\fR are specified, then the corresponding substitutions
+are not performed.
+For example, if \fB\-nocommands\fR is specified, command substitution
+is not performed:  open and close brackets are treated as ordinary characters
+with no special interpretation.
+.PP
+Note that the substitution of one kind can include substitution of
+other kinds.  For example, even when the \fB\-novariables\fR option
+is specified, command substitution is performed without restriction.
+This means that any variable substitution necessary to complete the
+command substitution will still take place.  Likewise, any command
+substitution necessary to complete a variable substitution will
+take place, even when \fB\-nocommands\fR is specified.  See the
+\fBEXAMPLES\fR below.
+.PP
+If an error occurs during substitution, then \fBsubst\fR will return
+that error.  If a break exception occurs during command or variable
+substitution, the result of the whole substitution will be the
+string (as substituted) up to the start of the substitution that
+raised the exception.  If a continue exception occurs during the
+evaluation of a command or variable substitution, an empty string
+will be substituted for that entire command or variable substitution
+(as long as it is well-formed Tcl.)  If a return exception occurs,
+or any other return code is returned during command or variable
+substitution, then the returned value is substituted for that
+substitution.  See the \fBEXAMPLES\fR below.  In this way, all exceptional
+return codes are
+.QW caught
+by \fBsubst\fR.  The \fBsubst\fR command
+itself will either return an error, or will complete successfully.
+.SH EXAMPLES
+.PP
+When it performs its substitutions, \fIsubst\fR does not give any
+special treatment to double quotes or curly braces (except within
+command substitutions) so the script
+.PP
+.CS
+set a 44
+\fBsubst\fR {xyz {$a}}
+.CE
+.PP
+returns
+.QW "\fBxyz {44}\fR" ,
+not
+.QW "\fBxyz {$a}\fR"
+and the script
+.PP
+.CS
+set a "p\e} q \e{r"
+\fBsubst\fR {xyz {$a}}
+.CE
+.PP
+returns
+.QW "\fBxyz {p} q {r}\fR" ,
+not
+.QW "\fBxyz {p\e} q \e{r}\fR".
+.PP
+When command substitution is performed, it includes any variable
+substitution necessary to evaluate the script.
+.PP
+.CS
+set a 44
+\fBsubst\fR -novariables {$a [format $a]}
+.CE
+.PP
+returns
+.QW "\fB$a 44\fR" ,
+not
+.QW "\fB$a $a\fR" .
+Similarly, when
+variable substitution is performed, it includes any command
+substitution necessary to retrieve the value of the variable.
+.PP
+.CS
+proc b {} {return c}
+array set a {c c [b] tricky}
+\fBsubst\fR -nocommands {[b] $a([b])}
+.CE
+.PP
+returns
+.QW "\fB[b] c\fR" ,
+not
+.QW "\fB[b] tricky\fR" .
+.PP
+The continue and break exceptions allow command substitutions to
+prevent substitution of the rest of the command substitution and the
+rest of \fIstring\fR respectively, giving script authors more options
+when processing text using \fIsubst\fR.  For example, the script
+.PP
+.CS
+\fBsubst\fR {abc,[break],def}
+.CE
+.PP
+returns
+.QW \fBabc,\fR ,
+not
+.QW \fBabc,,def\fR
+and the script
+.PP
+.CS
+\fBsubst\fR {abc,[continue;expr {1+2}],def}
+.CE
+.PP
+returns
+.QW \fBabc,,def\fR ,
+not
+.QW \fBabc,3,def\fR .
+.PP
+Other exceptional return codes substitute the returned value
+.PP
+.CS
+\fBsubst\fR {abc,[return foo;expr {1+2}],def}
+.CE
+.PP
+returns
+.QW \fBabc,foo,def\fR ,
+not
+.QW \fBabc,3,def\fR
+and
+.PP
+.CS
+\fBsubst\fR {abc,[return -code 10 foo;expr {1+2}],def}
+.CE
+.PP
+also returns
+.QW \fBabc,foo,def\fR ,
+not
+.QW \fBabc,3,def\fR .
+.SH "SEE ALSO"
+Tcl(n), eval(n), break(n), continue(n)
+.SH KEYWORDS
+backslash substitution, command substitution, quoting, substitution, variable substitution
+.\" Local Variables:
+.\" mode: nroff
+.\" End:
diff --git a/doc/switch.n b/doc/switch.n
new file mode 100644
index 0000000..6e27f56
--- /dev/null
+++ b/doc/switch.n
@@ -0,0 +1,186 @@
+'\"
+'\" Copyright (c) 1993 The Regents of the University of California.
+'\" Copyright (c) 1994-1997 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\" 
+.TH switch n 8.5 Tcl "Tcl Built-In Commands"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+switch \- Evaluate one of several scripts, depending on a given value
+.SH SYNOPSIS
+\fBswitch \fR?\fIoptions\fR?\fI string pattern body \fR?\fIpattern body \fR...?
+.sp
+\fBswitch \fR?\fIoptions\fR?\fI string \fR{\fIpattern body \fR?\fIpattern body \fR...?}
+.BE
+.SH DESCRIPTION
+.PP
+The \fBswitch\fR command matches its \fIstring\fR argument against each of
+the \fIpattern\fR arguments in order.
+As soon as it finds a \fIpattern\fR that matches \fIstring\fR it
+evaluates the following \fIbody\fR argument by passing it recursively
+to the Tcl interpreter and returns the result of that evaluation.
+If the last \fIpattern\fR argument is \fBdefault\fR then it matches
+anything.
+If no \fIpattern\fR argument
+matches \fIstring\fR and no default is given, then the \fBswitch\fR
+command returns an empty string.
+.PP
+If the initial arguments to \fBswitch\fR start with \fB\-\fR then
+they are treated as options
+unless there are exactly two arguments to \fBswitch\fR (in which case the
+first must the \fIstring\fR and the second must be the
+\fIpattern\fR/\fIbody\fR list).
+The following options are currently supported:
+.TP 10
+\fB\-exact\fR
+.
+Use exact matching when comparing \fIstring\fR to a pattern.  This
+is the default.
+.TP 10
+\fB\-glob\fR
+.
+When matching \fIstring\fR to the patterns, use glob-style matching
+(i.e. the same as implemented by the \fBstring match\fR command).
+.TP 10
+\fB\-regexp\fR
+.
+When matching \fIstring\fR to the patterns, use regular
+expression matching
+(as described in the \fBre_syntax\fR reference page).
+.TP 10
+\fB\-nocase\fR
+.
+Causes comparisons to be handled in a case-insensitive manner.
+.TP 10
+\fB\-matchvar\fR \fIvarName\fR
+.
+This option (only legal when \fB\-regexp\fR is also specified)
+specifies the name of a variable into which the list of matches
+found by the regular expression engine will be written.  The first
+element of the list written will be the overall substring of the input
+string (i.e. the \fIstring\fR argument to \fBswitch\fR) matched, the
+second element of the list will be the substring matched by the first
+capturing parenthesis in the regular expression that matched, and so
+on.  When a \fBdefault\fR branch is taken, the variable will have the
+empty list written to it.  This option may be specified at the same
+time as the \fB\-indexvar\fR option.
+.TP 10
+\fB\-indexvar\fR \fIvarName\fR
+.
+This option (only legal when \fB\-regexp\fR is also specified)
+specifies the name of a variable into which the list of indices
+referring to matching substrings
+found by the regular expression engine will be written.  The first
+element of the list written will be a two-element list specifying the
+index of the start and index of the first character after the end of
+the overall substring of the input
+string (i.e. the \fIstring\fR argument to \fBswitch\fR) matched, in a
+similar way to the \fB\-indices\fR option to the \fBregexp\fR can
+obtain.  Similarly, the second element of the list refers to the first
+capturing parenthesis in the regular expression that matched, and so
+on.  When a \fBdefault\fR branch is taken, the variable will have the
+empty list written to it.  This option may be specified at the same
+time as the \fB\-matchvar\fR option.
+.TP 10
+\fB\-\|\-\fR
+.
+Marks the end of options.  The argument following this one will
+be treated as \fIstring\fR even if it starts with a \fB\-\fR.
+This is not required when the matching patterns and bodies are grouped
+together in a single argument.
+.PP
+Two syntaxes are provided for the \fIpattern\fR and \fIbody\fR arguments.
+The first uses a separate argument for each of the patterns and commands;
+this form is convenient if substitutions are desired on some of the
+patterns or commands.
+The second form places all of the patterns and commands together into
+a single argument; the argument must have proper list structure, with
+the elements of the list being the patterns and commands.
+The second form makes it easy to construct multi-line switch commands,
+since the braces around the whole list make it unnecessary to include a
+backslash at the end of each line.
+Since the \fIpattern\fR arguments are in braces in the second form,
+no command or variable substitutions are performed on them;  this makes
+the behavior of the second form different than the first form in some
+cases.
+.PP
+If a \fIbody\fR is specified as
+.QW \fB\-\fR
+it means that the \fIbody\fR
+for the next pattern should also be used as the body for this
+pattern (if the next pattern also has a body of
+.QW \fB\-\fR
+then the body after that is used, and so on).
+This feature makes it possible to share a single \fIbody\fR among
+several patterns.
+.PP
+Beware of how you place comments in \fBswitch\fR commands.  Comments
+should only be placed \fBinside\fR the execution body of one of the
+patterns, and not intermingled with the patterns.
+.SH "EXAMPLES"
+.PP
+The \fBswitch\fR command can match against variables and not just
+literals, as shown here (the result is \fI2\fR):
+.PP
+.CS
+set foo "abc"
+\fBswitch\fR abc a \- b {expr {1}} $foo {expr {2}} default {expr {3}}
+.CE
+.PP
+Using glob matching and the fall-through body is an alternative to
+writing regular expressions with alternations, as can be seen here
+(this returns \fI1\fR):
+.PP
+.CS
+\fBswitch\fR \-glob aaab {
+    a*b     \-
+    b       {expr {1}}
+    a*      {expr {2}}
+    default {expr {3}}
+}
+.CE
+.PP
+Whenever nothing matches, the \fBdefault\fR clause (which must be
+last) is taken.  This example has a result of \fI3\fR:
+.PP
+.CS
+\fBswitch\fR xyz {
+    a \-
+    b {
+        # Correct Comment Placement
+        expr {1}
+    }
+    c {
+        expr {2}
+    }
+    default {
+        expr {3}
+    }
+}
+.CE
+.PP
+When matching against regular expressions, information about what
+exactly matched is easily obtained using the \fB\-matchvar\fR option:
+.PP
+.CS
+\fBswitch\fR \-regexp \-matchvar foo \-\- $bar {
+    a(b*)c {
+        puts "Found [string length [lindex $foo 1]] 'b's"
+    }
+    d(e*)f(g*)h {
+        puts "Found [string length [lindex $foo 1]] 'e's and\e
+                [string length [lindex $foo 2]] 'g's"
+    }
+}
+.CE
+.SH "SEE ALSO"
+for(n), if(n), regexp(n)
+.SH KEYWORDS
+switch, match, regular expression
+.\" Local Variables:
+.\" mode: nroff
+.\" End:
diff --git a/doc/tailcall.n b/doc/tailcall.n
new file mode 100644
index 0000000..926c608
--- /dev/null
+++ b/doc/tailcall.n
@@ -0,0 +1,69 @@
+'\"
+'\" Copyright (c) 1993 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\" 
+.TH tailcall n 8.6 Tcl "Tcl Built-In Commands"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+tailcall \- Replace the current procedure with another command
+.SH SYNOPSIS
+\fBtailcall \fIcommand\fR ?\fIarg ...\fR?
+.BE
+.SH DESCRIPTION
+.PP
+The \fBtailcall\fR command replaces the currently executing procedure, lambda
+application, or method with another command. The \fIcommand\fR, which will
+have \fIarg ...\fR passed as arguments if they are supplied, will be looked up
+in the current namespace context, not in the caller's. Apart from that
+difference in resolution, it is equivalent to:
+.PP
+.CS
+return [uplevel 1 [list \fIcommand\fR ?\fIarg ...\fR?]]
+.CE
+.PP
+This command may not be invoked from within an \fBuplevel\fR into a procedure
+or inside a \fBcatch\fR inside a procedure or lambda.
+'\" TODO: sort out the mess with the [try] command!
+.SH EXAMPLE
+.PP
+Compute the factorial of a number.
+.PP
+.CS
+proc factorial {n {accum 1}} {
+    if {$n < 2} {
+        return $accum
+    }
+    \fBtailcall\fR factorial [expr {$n - 1}] [expr {$accum * $n}]
+}
+.CE
+.PP
+Print the elements of a list with alternating lines having different
+indentations.
+.PP
+.CS
+proc printList {theList} {
+    if {[llength $theList]} {
+        puts "> [lindex $theList 0]"
+        \fBtailcall\fR printList2 [lrange $theList 1 end]
+    }
+}
+proc printList2 {theList} {
+    if {[llength $theList]} {
+        puts "< [lindex $theList 0]"
+        \fBtailcall\fR printList [lrange $theList 1 end]
+    }
+}
+.CE
+.SH "SEE ALSO"
+apply(n), proc(n), uplevel(n)
+.SH KEYWORDS
+call, recursion, tail recursion
+'\" Local Variables:
+'\" mode: nroff
+'\" fill-column: 78
+'\" End:
diff --git a/doc/tclsh.1 b/doc/tclsh.1
new file mode 100644
index 0000000..6ed5eb6
--- /dev/null
+++ b/doc/tclsh.1
@@ -0,0 +1,149 @@
+'\"
+'\" Copyright (c) 1993 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\" 
+.TH tclsh 1 "" Tcl "Tcl Applications"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+tclsh \- Simple shell containing Tcl interpreter
+.SH SYNOPSIS
+\fBtclsh\fR ?\fB\-encoding \fIname\fR? ?\fIfileName arg arg ...\fR?
+.BE
+.SH DESCRIPTION
+.PP
+\fBTclsh\fR is a shell-like application that reads Tcl commands
+from its standard input or from a file and evaluates them.
+If invoked with no arguments then it runs interactively, reading
+Tcl commands from standard input and printing command results and
+error messages to standard output.
+It runs until the \fBexit\fR command is invoked or until it
+reaches end-of-file on its standard input.
+If there exists a file \fB.tclshrc\fR (or \fBtclshrc.tcl\fR on
+the Windows platforms) in the home directory of
+the user, interactive \fBtclsh\fR evaluates the file as a Tcl script
+just before reading the first command from standard input.
+.SH "SCRIPT FILES"
+.PP
+If \fBtclsh\fR is invoked with arguments then the first few arguments
+specify the name of a script file, and, optionally, the encoding of
+the text data stored in that script file. Any additional arguments
+are made available to the script as variables (see below).
+Instead of reading commands from standard input \fBtclsh\fR will
+read Tcl commands from the named file;  \fBtclsh\fR will exit
+when it reaches the end of the file.
+The end of the file may be marked either by the physical end of
+the medium, or by the character,
+.QW \e032
+.PQ \eu001a ", control-Z" .
+If this character is present in the file, the \fBtclsh\fR application
+will read text up to but not including the character.  An application
+that requires this character in the file may safely encode it as
+.QW \e032 ,
+.QW \ex1a ,
+or
+.QW \eu001a ;
+or may generate it by use of commands such as \fBformat\fR or \fBbinary\fR.
+There is no automatic evaluation of \fB.tclshrc\fR when the name
+of a script file is presented on the \fBtclsh\fR command
+line, but the script file can always \fBsource\fR it if desired.
+.PP
+If you create a Tcl script in a file whose first line is
+.PP
+.CS
+\fB#!/usr/local/bin/tclsh\fR
+.CE
+.PP
+then you can invoke the script file directly from your shell if
+you mark the file as executable.
+This assumes that \fBtclsh\fR has been installed in the default
+location in /usr/local/bin;  if it is installed somewhere else
+then you will have to modify the above line to match.
+Many UNIX systems do not allow the \fB#!\fR line to exceed about
+30 characters in length, so be sure that the \fBtclsh\fR
+executable can be accessed with a short file name.
+.PP
+An even better approach is to start your script files with the
+following three lines:
+.PP
+.CS
+\fB#!/bin/sh
+# the next line restarts using tclsh \e
+exec tclsh "$0" ${1+"$@"}\fR
+.CE
+.PP
+This approach has three advantages over the approach in the previous
+paragraph.  First, the location of the \fBtclsh\fR binary does not have
+to be hard-wired into the script:  it can be anywhere in your shell
+search path.  Second, it gets around the 30-character file name limit
+in the previous approach.
+Third, this approach will work even if \fBtclsh\fR is
+itself a shell script (this is done on some systems in order to
+handle multiple architectures or operating systems:  the \fBtclsh\fR
+script selects one of several binaries to run).  The three lines
+cause both \fBsh\fR and \fBtclsh\fR to process the script, but the
+\fBexec\fR is only executed by \fBsh\fR.
+\fBsh\fR processes the script first;  it treats the second
+line as a comment and executes the third line.
+The \fBexec\fR statement cause the shell to stop processing and
+instead to start up \fBtclsh\fR to reprocess the entire script.
+When \fBtclsh\fR starts up, it treats all three lines as comments,
+since the backslash at the end of the second line causes the third
+line to be treated as part of the comment on the second line.
+.PP
+You should note that it is also common practice to install tclsh with
+its version number as part of the name.  This has the advantage of
+allowing multiple versions of Tcl to exist on the same system at once,
+but also the disadvantage of making it harder to write scripts that
+start up uniformly across different versions of Tcl.
+.SH "VARIABLES"
+.PP
+\fBTclsh\fR sets the following global Tcl variables in addition to those
+created by the Tcl library itself (such as \fBenv\fR, which maps
+environment variables such as \fBPATH\fR into Tcl):
+.TP 15
+\fBargc\fR
+.
+Contains a count of the number of \fIarg\fR arguments (0 if none),
+not including the name of the script file.
+.TP 15
+\fBargv\fR
+.
+Contains a Tcl list whose elements are the \fIarg\fR arguments,
+in order, or an empty string if there are no \fIarg\fR arguments.
+.TP 15
+\fBargv0\fR
+.
+Contains \fIfileName\fR if it was specified.
+Otherwise, contains the name by which \fBtclsh\fR was invoked.
+.TP 15
+\fBtcl_interactive\fR
+.
+Contains 1 if \fBtclsh\fR is running interactively (no
+\fIfileName\fR was specified and standard input is a terminal-like
+device), 0 otherwise.
+.SH PROMPTS
+.PP
+When \fBtclsh\fR is invoked interactively it normally prompts for each
+command with
+.QW "\fB% \fR" .
+You can change the prompt by setting the global
+variables \fBtcl_prompt1\fR and \fBtcl_prompt2\fR.  If variable
+\fBtcl_prompt1\fR exists then it must consist of a Tcl script
+to output a prompt;  instead of outputting a prompt \fBtclsh\fR
+will evaluate the script in \fBtcl_prompt1\fR.
+The variable \fBtcl_prompt2\fR is used in a similar way when
+a newline is typed but the current command is not yet complete;
+if \fBtcl_prompt2\fR is not set then no prompt is output for
+incomplete commands.
+.SH "STANDARD CHANNELS"
+.PP
+See \fBTcl_StandardChannels\fR for more explanations.
+.SH "SEE ALSO"
+auto_path(n), encoding(n), env(n), fconfigure(n)
+.SH KEYWORDS
+application, argument, interpreter, prompt, script file, shell
diff --git a/doc/tcltest.n b/doc/tcltest.n
new file mode 100644
index 0000000..05c1922
--- /dev/null
+++ b/doc/tcltest.n
@@ -0,0 +1,1259 @@
+'\"
+'\" Copyright (c) 1990-1994 The Regents of the University of California
+'\" Copyright (c) 1994-1997 Sun Microsystems, Inc.
+'\" Copyright (c) 1998-1999 Scriptics Corporation
+'\" Copyright (c) 2000 Ajuba Solutions
+'\" Contributions from Don Porter, NIST, 2002. (not subject to US copyright)
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH "tcltest" n 2.3 tcltest "Tcl Bundled Packages"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+tcltest \- Test harness support code and utilities
+.SH SYNOPSIS
+.nf
+\fBpackage require tcltest\fR ?\fB2.3\fR?
+
+\fBtcltest::test \fIname description\fR ?\fI\-option value ...\fR?
+\fBtcltest::test \fIname description\fR ?\fIconstraints\fR? \fIbody result\fR
+
+\fBtcltest::loadTestedCommands\fR
+\fBtcltest::makeDirectory \fIname\fR ?\fIdirectory\fR?
+\fBtcltest::removeDirectory \fIname\fR ?\fIdirectory\fR?
+\fBtcltest::makeFile \fIcontents name\fR ?\fIdirectory\fR?
+\fBtcltest::removeFile \fIname\fR ?\fIdirectory\fR?
+\fBtcltest::viewFile \fIname\fR ?\fIdirectory\fR?
+\fBtcltest::cleanupTests \fR?\fIrunningMultipleTests\fR?
+\fBtcltest::runAllTests\fR
+
+\fBtcltest::configure\fR
+\fBtcltest::configure \fI\-option\fR
+\fBtcltest::configure \fI\-option value\fR ?\fI\-option value ...\fR?
+\fBtcltest::customMatch \fImode command\fR
+\fBtcltest::testConstraint \fIconstraint\fR ?\fIvalue\fR?
+\fBtcltest::outputChannel \fR?\fIchannelID\fR?
+\fBtcltest::errorChannel \fR?\fIchannelID\fR?
+\fBtcltest::interpreter \fR?\fIinterp\fR?
+
+\fBtcltest::debug \fR?\fIlevel\fR?
+\fBtcltest::errorFile \fR?\fIfilename\fR?
+\fBtcltest::limitConstraints \fR?\fIboolean\fR?
+\fBtcltest::loadFile \fR?\fIfilename\fR?
+\fBtcltest::loadScript \fR?\fIscript\fR?
+\fBtcltest::match \fR?\fIpatternList\fR?
+\fBtcltest::matchDirectories \fR?\fIpatternList\fR?
+\fBtcltest::matchFiles \fR?\fIpatternList\fR?
+\fBtcltest::outputFile \fR?\fIfilename\fR?
+\fBtcltest::preserveCore \fR?\fIlevel\fR?
+\fBtcltest::singleProcess \fR?\fIboolean\fR?
+\fBtcltest::skip \fR?\fIpatternList\fR?
+\fBtcltest::skipDirectories \fR?\fIpatternList\fR?
+\fBtcltest::skipFiles \fR?\fIpatternList\fR?
+\fBtcltest::temporaryDirectory \fR?\fIdirectory\fR?
+\fBtcltest::testsDirectory \fR?\fIdirectory\fR?
+\fBtcltest::verbose \fR?\fIlevel\fR?
+
+\fBtcltest::test \fIname description optionList\fR
+\fBtcltest::bytestring \fIstring\fR
+\fBtcltest::normalizeMsg \fImsg\fR
+\fBtcltest::normalizePath \fIpathVar\fR
+\fBtcltest::workingDirectory \fR?\fIdir\fR?
+.fi
+.BE
+.SH DESCRIPTION
+.PP
+The \fBtcltest\fR package provides several utility commands useful
+in the construction of test suites for code instrumented to be
+run by evaluation of Tcl commands.  Notably the built-in commands
+of the Tcl library itself are tested by a test suite using the
+tcltest package.
+.PP
+All the commands provided by the \fBtcltest\fR package are defined
+in and exported from the \fB::tcltest\fR namespace, as indicated in
+the \fBSYNOPSIS\fR above.  In the following sections, all commands
+will be described by their simple names, in the interest of brevity.
+.PP
+The central command of \fBtcltest\fR is \fBtest\fR that defines
+and runs a test.  Testing with \fBtest\fR involves evaluation
+of a Tcl script and comparing the result to an expected result, as
+configured and controlled by a number of options.  Several other
+commands provided by \fBtcltest\fR govern the configuration of
+\fBtest\fR and the collection of many \fBtest\fR commands into
+test suites.
+.PP
+See \fBCREATING TEST SUITES WITH TCLTEST\fR below for an extended example
+of how to use the commands of \fBtcltest\fR to produce test suites
+for your Tcl-enabled code.
+.SH COMMANDS
+.TP
+\fBtest\fR \fIname description\fR ?\fI\-option value ...\fR?
+.
+Defines and possibly runs a test with the name \fIname\fR and
+description \fIdescription\fR.  The name and description of a test
+are used in messages reported by \fBtest\fR during the
+test, as configured by the options of \fBtcltest\fR.  The
+remaining \fIoption value\fR arguments to \fBtest\fR
+define the test, including the scripts to run, the conditions
+under which to run them, the expected result, and the means
+by which the expected and actual results should be compared.
+See \fBTESTS\fR below for a complete description of the valid
+options and how they define a test.  The \fBtest\fR command
+returns an empty string.
+.TP
+\fBtest\fR \fIname description\fR ?\fIconstraints\fR? \fIbody result\fR
+.
+This form of \fBtest\fR is provided to support test suites written
+for version 1 of the \fBtcltest\fR package, and also a simpler
+interface for a common usage.  It is the same as
+.QW "\fBtest\fR \fIname description\fB \-constraints \fIconstraints\fB \-body \fIbody\fB \-result \fIresult\fR" .
+All other options to \fBtest\fR
+take their default values.  When \fIconstraints\fR is omitted, this
+form of \fBtest\fR can be distinguished from the first because
+all \fIoption\fRs begin with
+.QW \- .
+.TP
+\fBloadTestedCommands\fR
+.
+Evaluates in the caller's context the script specified by
+\fBconfigure \-load\fR or \fBconfigure \-loadfile\fR.
+Returns the result of that script evaluation, including any error
+raised by the script.  Use this command and the related
+configuration options to provide the commands to be tested to
+the interpreter running the test suite.
+.TP
+\fBmakeFile\fR \fIcontents name\fR ?\fIdirectory\fR?
+.
+Creates a file named \fIname\fR relative to
+directory \fIdirectory\fR and write \fIcontents\fR
+to that file using the encoding \fBencoding system\fR.
+If \fIcontents\fR does not end with a newline, a newline
+will be appended so that the file named \fIname\fR
+does end with a newline.  Because the system encoding is used,
+this command is only suitable for making text files.
+The file will be removed by the next evaluation
+of \fBcleanupTests\fR, unless it is removed by
+\fBremoveFile\fR first.  The default value of
+\fIdirectory\fR is the directory \fBconfigure \-tmpdir\fR.
+Returns the full path of the file created.  Use this command
+to create any text file required by a test with contents as needed.
+.TP
+\fBremoveFile\fR \fIname\fR ?\fIdirectory\fR?
+.
+Forces the file referenced by \fIname\fR to be removed.  This file name
+should be relative to \fIdirectory\fR.   The default value of
+\fIdirectory\fR is the directory \fBconfigure \-tmpdir\fR.
+Returns an empty string.  Use this command to delete files
+created by \fBmakeFile\fR.
+.TP
+\fBmakeDirectory\fR \fIname\fR ?\fIdirectory\fR?
+.
+Creates a directory named \fIname\fR relative to directory \fIdirectory\fR.
+The directory will be removed by the next evaluation of \fBcleanupTests\fR,
+unless it is removed by \fBremoveDirectory\fR first.
+The default value of \fIdirectory\fR is the directory
+\fBconfigure \-tmpdir\fR.
+Returns the full path of the directory created.  Use this command
+to create any directories that are required to exist by a test.
+.TP
+\fBremoveDirectory\fR \fIname\fR ?\fIdirectory\fR?
+.
+Forces the directory referenced by \fIname\fR to be removed. This
+directory should be relative to \fIdirectory\fR.
+The default value of \fIdirectory\fR is the directory
+\fBconfigure \-tmpdir\fR.
+Returns an empty string.  Use this command to delete any directories
+created by \fBmakeDirectory\fR.
+.TP
+\fBviewFile\fR \fIfile\fR ?\fIdirectory\fR?
+.
+Returns the contents of \fIfile\fR, except for any
+final newline, just as \fBread \-nonewline\fR would return.
+This file name should be relative to \fIdirectory\fR.
+The default value of \fIdirectory\fR is the directory
+\fBconfigure \-tmpdir\fR.  Use this command
+as a convenient way to turn the contents of a file generated
+by a test into the result of that test for matching against
+an expected result.  The contents of the file are read using
+the system encoding, so its usefulness is limited to text
+files.
+.TP
+\fBcleanupTests\fR
+.
+Intended to clean up and summarize after several tests have been
+run.  Typically called once per test file, at the end of the file
+after all tests have been completed.  For best effectiveness, be
+sure that the \fBcleanupTests\fR is evaluated even if an error
+occurs earlier in the test file evaluation.
+.RS
+.PP
+Prints statistics about the tests run and removes files that were
+created by \fBmakeDirectory\fR and \fBmakeFile\fR since the
+last \fBcleanupTests\fR.  Names of files and directories
+in the directory \fBconfigure \-tmpdir\fR created since
+the last \fBcleanupTests\fR, but not created by
+\fBmakeFile\fR or \fBmakeDirectory\fR are printed
+to \fBoutputChannel\fR.  This command also restores the original
+shell environment, as described by the global \fBenv\fR
+array. Returns an empty string.
+.RE
+.TP
+\fBrunAllTests\fR
+.
+This is a master command meant to run an entire suite of tests,
+spanning multiple files and/or directories, as governed by
+the configurable options of \fBtcltest\fR.  See \fBRUNNING ALL TESTS\fR
+below for a complete description of the many variations possible
+with \fBrunAllTests\fR.
+.SS "CONFIGURATION COMMANDS"
+.TP
+\fBconfigure\fR
+.
+Returns the list of configurable options supported by \fBtcltest\fR.
+See \fBCONFIGURABLE OPTIONS\fR below for the full list of options,
+their valid values, and their effect on \fBtcltest\fR operations.
+.TP
+\fBconfigure \fIoption\fR
+.
+Returns the current value of the supported configurable option \fIoption\fR.
+Raises an error if \fIoption\fR is not a supported configurable option.
+.TP
+\fBconfigure \fIoption value\fR ?\fI\-option value ...\fR?
+.
+Sets the value of each configurable option \fIoption\fR to the
+corresponding value \fIvalue\fR, in order.  Raises an error if
+an \fIoption\fR is not a supported configurable option, or if
+\fIvalue\fR is not a valid value for the corresponding \fIoption\fR,
+or if a \fIvalue\fR is not provided.  When an error is raised, the
+operation of \fBconfigure\fR is halted, and subsequent \fIoption value\fR
+arguments are not processed.
+.RS
+.PP
+If the environment variable \fB::env(TCLTEST_OPTIONS)\fR exists when
+the \fBtcltest\fR package is loaded (by \fBpackage require\fR \fBtcltest\fR)
+then its value is taken as a list of arguments to pass to \fBconfigure\fR.
+This allows the default values of the configuration options to be
+set by the environment.
+.RE
+.TP
+\fBcustomMatch \fImode script\fR
+.
+Registers \fImode\fR as a new legal value of the \fB\-match\fR option
+to \fBtest\fR.  When the \fB\-match \fImode\fR option is
+passed to \fBtest\fR, the script \fIscript\fR will be evaluated
+to compare the actual result of evaluating the body of the test
+to the expected result.
+To perform the match, the \fIscript\fR is completed with two additional
+words, the expected result, and the actual result, and the completed script
+is evaluated in the global namespace.
+The completed script is expected to return a boolean value indicating
+whether or not the results match.  The built-in matching modes of
+\fBtest\fR are \fBexact\fR, \fBglob\fR, and \fBregexp\fR.
+.TP
+\fBtestConstraint \fIconstraint\fR ?\fIboolean\fR?
+.
+Sets or returns the boolean value associated with the named \fIconstraint\fR.
+See \fBTEST CONSTRAINTS\fR below for more information.
+.TP
+\fBinterpreter\fR ?\fIexecutableName\fR?
+.
+Sets or returns the name of the executable to be \fBexec\fRed by
+\fBrunAllTests\fR to run each test file when
+\fBconfigure \-singleproc\fR is false.
+The default value for \fBinterpreter\fR is the name of the
+currently running program as returned by \fBinfo nameofexecutable\fR.
+.TP
+\fBoutputChannel\fR ?\fIchannelID\fR?
+.
+Sets or returns the output channel ID.  This defaults to \fBstdout\fR.
+Any test that prints test related output should send
+that output to \fBoutputChannel\fR rather than letting
+that output default to \fBstdout\fR.
+.TP
+\fBerrorChannel\fR ?\fIchannelID\fR?
+.
+Sets or returns the error channel ID.  This defaults to \fBstderr\fR.
+Any test that prints error messages should send
+that output to \fBerrorChannel\fR rather than printing
+directly to \fBstderr\fR.
+.SS "SHORTCUT CONFIGURATION COMMANDS"
+.TP
+\fBdebug\fR ?\fIlevel\fR?
+.
+Same as
+.QW "\fBconfigure \-debug\fR ?\fIlevel\fR?" .
+.TP
+\fBerrorFile\fR ?\fIfilename\fR?
+.
+Same as
+.QW "\fBconfigure \-errfile\fR ?\fIfilename\fR?" .
+.TP
+\fBlimitConstraints\fR ?\fIboolean\fR?
+.
+Same as
+.QW "\fBconfigure \-limitconstraints\fR ?\fIboolean\fR?" .
+.TP
+\fBloadFile\fR ?\fIfilename\fR?
+.
+Same as
+.QW "\fBconfigure \-loadfile\fR ?\fIfilename\fR?" .
+.TP
+\fBloadScript\fR ?\fIscript\fR?
+.
+Same as
+.QW "\fBconfigure \-load\fR ?\fIscript\fR?" .
+.TP
+\fBmatch\fR ?\fIpatternList\fR?
+.
+Same as
+.QW "\fBconfigure \-match\fR ?\fIpatternList\fR?" .
+.TP
+\fBmatchDirectories\fR ?\fIpatternList\fR?
+.
+Same as
+.QW "\fBconfigure \-relateddir\fR ?\fIpatternList\fR?" .
+.TP
+\fBmatchFiles\fR ?\fIpatternList\fR?
+.
+Same as
+.QW "\fBconfigure \-file\fR ?\fIpatternList\fR?" .
+.TP
+\fBoutputFile\fR ?\fIfilename\fR?
+.
+Same as
+.QW "\fBconfigure \-outfile\fR ?\fIfilename\fR?" .
+.TP
+\fBpreserveCore\fR ?\fIlevel\fR?
+.
+Same as
+.QW "\fBconfigure \-preservecore\fR ?\fIlevel\fR?" .
+.TP
+\fBsingleProcess\fR ?\fIboolean\fR?
+.
+Same as
+.QW "\fBconfigure \-singleproc\fR ?\fIboolean\fR?" .
+.TP
+\fBskip\fR ?\fIpatternList\fR?
+.
+Same as
+.QW "\fBconfigure \-skip\fR ?\fIpatternList\fR?" .
+.TP
+\fBskipDirectories\fR ?\fIpatternList\fR?
+.
+Same as
+.QW "\fBconfigure \-asidefromdir\fR ?\fIpatternList\fR?" .
+.TP
+\fBskipFiles\fR ?\fIpatternList\fR?
+.
+Same as
+.QW "\fBconfigure \-notfile\fR ?\fIpatternList\fR?" .
+.TP
+\fBtemporaryDirectory\fR ?\fIdirectory\fR?
+.
+Same as
+.QW "\fBconfigure \-tmpdir\fR ?\fIdirectory\fR?" .
+.TP
+\fBtestsDirectory\fR ?\fIdirectory\fR?
+.
+Same as
+.QW "\fBconfigure \-testdir\fR ?\fIdirectory\fR?" .
+.TP
+\fBverbose\fR ?\fIlevel\fR?
+.
+Same as
+.QW "\fBconfigure \-verbose\fR ?\fIlevel\fR?" .
+.SS "OTHER COMMANDS"
+.PP
+The remaining commands provided by \fBtcltest\fR have better
+alternatives provided by \fBtcltest\fR or \fBTcl\fR itself.  They
+are retained to support existing test suites, but should be avoided
+in new code.
+.TP
+\fBtest\fR \fIname description optionList\fR
+.
+This form of \fBtest\fR was provided to enable passing many
+options spanning several lines to \fBtest\fR as a single
+argument quoted by braces, rather than needing to backslash quote
+the newlines between arguments to \fBtest\fR.  The \fIoptionList\fR
+argument is expected to be a list with an even number of elements
+representing \fIoption\fR and \fIvalue\fR arguments to pass
+to \fBtest\fR.  However, these values are not passed directly, as
+in the alternate forms of \fBswitch\fR.  Instead, this form makes
+an unfortunate attempt to overthrow Tcl's substitution rules by
+performing substitutions on some of the list elements as an attempt to
+implement a
+.QW "do what I mean"
+interpretation of a brace-enclosed
+.QW block .
+The result is nearly impossible to document clearly, and
+for that reason this form is not recommended.  See the examples in
+\fBCREATING TEST SUITES WITH TCLTEST\fR below to see that this
+form is really not necessary to avoid backslash-quoted newlines.
+If you insist on using this form, examine
+the source code of \fBtcltest\fR if you want to know the substitution
+details, or just enclose the third through last argument
+to \fBtest\fR in braces and hope for the best.
+.TP
+\fBworkingDirectory\fR ?\fIdirectoryName\fR?
+.
+Sets or returns the current working directory when the test suite is
+running.  The default value for workingDirectory is the directory in
+which the test suite was launched.  The Tcl commands \fBcd\fR and
+\fBpwd\fR are sufficient replacements.
+.TP
+\fBnormalizeMsg \fImsg\fR
+.
+Returns the result of removing the
+.QW extra
+newlines from \fImsg\fR, where
+.QW extra
+is rather imprecise.  Tcl offers plenty of string
+processing commands to modify strings as you wish, and
+\fBcustomMatch\fR allows flexible matching of actual and expected
+results.
+.TP
+\fBnormalizePath \fIpathVar\fR
+.
+Resolves symlinks in a path, thus creating a path without internal
+redirection.  It is assumed that \fIpathVar\fR is absolute.
+\fIpathVar\fR is modified in place.  The Tcl command \fBfile normalize\fR
+is a sufficient replacement.
+.TP
+\fBbytestring \fIstring\fR
+.
+Construct a string that consists of the requested sequence of bytes,
+as opposed to a string of properly formed UTF-8 characters using the
+value supplied in \fIstring\fR.  This allows the tester to create
+denormalized or improperly formed strings to pass to C procedures that
+are supposed to accept strings with embedded NULL types and confirm
+that a string result has a certain pattern of bytes.  This is
+exactly equivalent to the Tcl command \fBencoding convertfrom\fR
+\fBidentity\fR.
+.SH TESTS
+.PP
+The \fBtest\fR command is the heart of the \fBtcltest\fR package.
+Its essential function is to evaluate a Tcl script and compare
+the result with an expected result.  The options of \fBtest\fR
+define the test script, the environment in which to evaluate it,
+the expected result, and how the compare the actual result to
+the expected result.  Some configuration options of \fBtcltest\fR
+also influence how \fBtest\fR operates.
+.PP
+The valid options for \fBtest\fR are summarized:
+.PP
+.CS
+\fBtest\fR \fIname\fR \fIdescription\fR
+        ?\fB\-constraints \fIkeywordList|expression\fR?
+        ?\fB\-setup \fIsetupScript\fR?
+        ?\fB\-body \fItestScript\fR?
+        ?\fB\-cleanup \fIcleanupScript\fR?
+        ?\fB\-result \fIexpectedAnswer\fR?
+        ?\fB\-output \fIexpectedOutput\fR?
+        ?\fB\-errorOutput \fIexpectedError\fR?
+        ?\fB\-returnCodes \fIcodeList\fR?
+        ?\fB\-match \fImode\fR?
+.CE
+.PP
+The \fIname\fR may be any string.  It is conventional to choose
+a \fIname\fR according to the pattern:
+.PP
+.CS
+\fItarget\fR-\fImajorNum\fR.\fIminorNum\fR
+.CE
+.PP
+For white-box (regression) tests, the target should be the name of the
+C function or Tcl procedure being tested.  For black-box tests, the
+target should be the name of the feature being tested.  Some conventions
+call for the names of black-box tests to have the suffix \fB_bb\fR.
+Related tests should share a major number.  As a test suite evolves,
+it is best to have the same test name continue to correspond to the
+same test, so that it remains meaningful to say things like
+.QW "Test foo-1.3 passed in all releases up to 3.4, but began failing in release 3.5."
+.PP
+During evaluation of \fBtest\fR, the \fIname\fR will be compared
+to the lists of string matching patterns returned by
+\fBconfigure \-match\fR, and \fBconfigure \-skip\fR.  The test
+will be run only if \fIname\fR matches any of the patterns from
+\fBconfigure \-match\fR and matches none of the patterns
+from \fBconfigure \-skip\fR.
+.PP
+The \fIdescription\fR should be a short textual description of the
+test.  The \fIdescription\fR is included in output produced by the
+test, typically test failure messages.  Good \fIdescription\fR values
+should briefly explain the purpose of the test to users of a test suite.
+The name of a Tcl or C function being tested should be included in the
+description for regression tests.  If the test case exists to reproduce
+a bug, include the bug ID in the description.
+.PP
+Valid attributes and associated values are:
+.TP
+\fB\-constraints \fIkeywordList\fR|\fIexpression\fR
+.
+The optional \fB\-constraints\fR attribute can be list of one or more
+keywords or an expression.  If the \fB\-constraints\fR value is a list of
+keywords, each of these keywords should be the name of a constraint
+defined by a call to \fBtestConstraint\fR.  If any of the listed
+constraints is false or does not exist, the test is skipped.  If the
+\fB\-constraints\fR value is an expression, that expression
+is evaluated. If the expression evaluates to true, then the test is run.
+Note that the expression form of \fB\-constraints\fR may interfere with the
+operation of \fBconfigure \-constraints\fR and
+\fBconfigure \-limitconstraints\fR, and is not recommended.
+Appropriate constraints should be added to any tests that should
+not always be run.  That is, conditional evaluation of a test
+should be accomplished by the \fB\-constraints\fR option, not by
+conditional evaluation of \fBtest\fR.  In that way, the same
+number of tests are always reported by the test suite, though
+the number skipped may change based on the testing environment.
+The default value is an empty list.
+See \fBTEST CONSTRAINTS\fR below for a list of built-in constraints
+and information on how to add your own constraints.
+.TP
+\fB\-setup \fIscript\fR
+.
+The optional \fB\-setup\fR attribute indicates a \fIscript\fR that will be run
+before the script indicated by the \fB\-body\fR attribute.  If evaluation
+of \fIscript\fR raises an error, the test will fail.  The default value
+is an empty script.
+.TP
+\fB\-body \fIscript\fR
+.
+The \fB\-body\fR attribute indicates the \fIscript\fR to run to carry out the
+test, which must return a result that can be checked for correctness.
+If evaluation of \fIscript\fR raises an error, the test will fail
+(unless the \fB\-returnCodes\fR option is used to state that an error
+is expected).
+The default value is an empty script.
+.TP
+\fB\-cleanup \fIscript\fR
+.
+The optional \fB\-cleanup\fR attribute indicates a \fIscript\fR that will be
+run after the script indicated by the \fB\-body\fR attribute.
+If evaluation of \fIscript\fR raises an error, the test will fail.
+The default value is an empty script.
+.TP
+\fB\-match \fImode\fR
+.
+The \fB\-match\fR attribute determines how expected answers supplied by
+\fB\-result\fR, \fB\-output\fR, and \fB\-errorOutput\fR are compared.  Valid
+values for \fImode\fR are \fBregexp\fR, \fBglob\fR, \fBexact\fR, and
+any value registered by a prior call to \fBcustomMatch\fR.  The default
+value is \fBexact\fR.
+.TP
+\fB\-result \fIexpectedValue\fR
+.
+The \fB\-result\fR attribute supplies the \fIexpectedValue\fR against which
+the return value from script will be compared. The default value is
+an empty string.
+.TP
+\fB\-output \fIexpectedValue\fR
+.
+The \fB\-output\fR attribute supplies the \fIexpectedValue\fR against which
+any output sent to \fBstdout\fR or \fBoutputChannel\fR during evaluation
+of the script(s) will be compared.  Note that only output printed using
+the global \fBputs\fR command is used for comparison.  If \fB\-output\fR is
+not specified, output sent to \fBstdout\fR and \fBoutputChannel\fR is not
+processed for comparison.
+.TP
+\fB\-errorOutput \fIexpectedValue\fR
+.
+The \fB\-errorOutput\fR attribute supplies the \fIexpectedValue\fR against
+which any output sent to \fBstderr\fR or \fBerrorChannel\fR during
+evaluation of the script(s) will be compared. Note that only output
+printed using the global \fBputs\fR command is used for comparison.  If
+\fB\-errorOutput\fR is not specified, output sent to \fBstderr\fR and
+\fBerrorChannel\fR is not processed for comparison.
+.TP
+\fB\-returnCodes \fIexpectedCodeList\fR
+.
+The optional \fB\-returnCodes\fR attribute supplies \fIexpectedCodeList\fR,
+a list of return codes that may be accepted from evaluation of the
+\fB\-body\fR script.  If evaluation of the \fB\-body\fR script returns
+a code not in the \fIexpectedCodeList\fR, the test fails.  All
+return codes known to \fBreturn\fR, in both numeric and symbolic
+form, including extended return codes, are acceptable elements in
+the \fIexpectedCodeList\fR.  Default value is
+.QW "\fBok return\fR" .
+.PP
+To pass, a test must successfully evaluate its \fB\-setup\fR, \fB\-body\fR,
+and \fB\-cleanup\fR scripts.  The return code of the \fB\-body\fR script and
+its result must match expected values, and if specified, output and error
+data from the test must match expected \fB\-output\fR and \fB\-errorOutput\fR
+values.  If any of these conditions are not met, then the test fails.
+Note that all scripts are evaluated in the context of the caller
+of \fBtest\fR.
+.PP
+As long as \fBtest\fR is called with valid syntax and legal
+values for all attributes, it will not raise an error.  Test
+failures are instead reported as output written to \fBoutputChannel\fR.
+In default operation, a successful test produces no output.  The output
+messages produced by \fBtest\fR are controlled by the
+\fBconfigure \-verbose\fR option as described in \fBCONFIGURABLE OPTIONS\fR
+below.  Any output produced by the test scripts themselves should be
+produced using \fBputs\fR to \fBoutputChannel\fR or
+\fBerrorChannel\fR, so that users of the test suite may
+easily capture output with the \fBconfigure \-outfile\fR and
+\fBconfigure \-errfile\fR options, and so that the \fB\-output\fR
+and \fB\-errorOutput\fR attributes work properly.
+.SS "TEST CONSTRAINTS"
+.PP
+Constraints are used to determine whether or not a test should be skipped.
+Each constraint has a name, which may be any string, and a boolean
+value.  Each \fBtest\fR has a \fB\-constraints\fR value which is a
+list of constraint names.  There are two modes of constraint control.
+Most frequently, the default mode is used, indicated by a setting
+of \fBconfigure \-limitconstraints\fR to false.  The test will run
+only if all constraints in the list are true-valued.  Thus,
+the \fB\-constraints\fR option of \fBtest\fR is a convenient, symbolic
+way to define any conditions required for the test to be possible or
+meaningful.  For example, a \fBtest\fR with \fB\-constraints unix\fR
+will only be run if the constraint \fBunix\fR is true, which indicates
+the test suite is being run on a Unix platform.
+.PP
+Each \fBtest\fR should include whatever \fB\-constraints\fR are
+required to constrain it to run only where appropriate.  Several
+constraints are pre-defined in the \fBtcltest\fR package, listed
+below.  The registration of user-defined constraints is performed
+by the \fBtestConstraint\fR command.  User-defined constraints
+may appear within a test file, or within the script specified
+by the \fBconfigure \-load\fR or \fBconfigure \-loadfile\fR
+options.
+.PP
+The following is a list of constraints pre-defined by the
+\fBtcltest\fR package itself:
+.TP
+\fIsingleTestInterp\fR
+.
+This test can only be run if all test files are sourced into a single
+interpreter.
+.TP
+\fIunix\fR
+.
+This test can only be run on any Unix platform.
+.TP
+\fIwin\fR
+.
+This test can only be run on any Windows platform.
+.TP
+\fInt\fR
+.
+This test can only be run on any Windows NT platform.
+.TP
+\fImac\fR
+.
+This test can only be run on any Mac platform.
+.TP
+\fIunixOrWin\fR
+.
+This test can only be run on a Unix or Windows platform.
+.TP
+\fImacOrWin\fR
+.
+This test can only be run on a Mac or Windows platform.
+.TP
+\fImacOrUnix\fR
+.
+This test can only be run on a Mac or Unix platform.
+.TP
+\fItempNotWin\fR
+.
+This test can not be run on Windows.  This flag is used to temporarily
+disable a test.
+.TP
+\fItempNotMac\fR
+.
+This test can not be run on a Mac.  This flag is used
+to temporarily disable a test.
+.TP
+\fIunixCrash\fR
+.
+This test crashes if it is run on Unix.  This flag is used to temporarily
+disable a test.
+.TP
+\fIwinCrash\fR
+.
+This test crashes if it is run on Windows.  This flag is used to temporarily
+disable a test.
+.TP
+\fImacCrash\fR
+.
+This test crashes if it is run on a Mac.  This flag is used to temporarily
+disable a test.
+.TP
+\fIemptyTest\fR
+.
+This test is empty, and so not worth running, but it remains as a
+place-holder for a test to be written in the future.  This constraint
+has value false to cause tests to be skipped unless the user specifies
+otherwise.
+.TP
+\fIknownBug\fR
+.
+This test is known to fail and the bug is not yet fixed.  This constraint
+has value false to cause tests to be skipped unless the user specifies
+otherwise.
+.TP
+\fInonPortable\fR
+.
+This test can only be run in some known development environment.
+Some tests are inherently non-portable because they depend on things
+like word length, file system configuration, window manager, etc.
+This constraint has value false to cause tests to be skipped unless
+the user specifies otherwise.
+.TP
+\fIuserInteraction\fR
+.
+This test requires interaction from the user.  This constraint has
+value false to causes tests to be skipped unless the user specifies
+otherwise.
+.TP
+\fIinteractive\fR
+.
+This test can only be run in if the interpreter is in interactive mode
+(when the global tcl_interactive variable is set to 1).
+.TP
+\fInonBlockFiles\fR
+.
+This test can only be run if platform supports setting files into
+nonblocking mode.
+.TP
+\fIasyncPipeClose\fR
+.
+This test can only be run if platform supports async flush and async close
+on a pipe.
+.TP
+\fIunixExecs\fR
+.
+This test can only be run if this machine has Unix-style commands
+\fBcat\fR, \fBecho\fR, \fBsh\fR, \fBwc\fR, \fBrm\fR, \fBsleep\fR,
+\fBfgrep\fR, \fBps\fR, \fBchmod\fR, and \fBmkdir\fR available.
+.TP
+\fIhasIsoLocale\fR
+.
+This test can only be run if can switch to an ISO locale.
+.TP
+\fIroot\fR
+.
+This test can only run if Unix user is root.
+.TP
+\fInotRoot\fR
+.
+This test can only run if Unix user is not root.
+.TP
+\fIeformat\fR
+.
+This test can only run if app has a working version of sprintf with respect
+to the
+.QW e
+format of floating-point numbers.
+.TP
+\fIstdio\fR
+.
+This test can only be run if \fBinterpreter\fR can be \fBopen\fRed
+as a pipe.
+.PP
+The alternative mode of constraint control is enabled by setting
+\fBconfigure \-limitconstraints\fR to true.  With that configuration
+setting, all existing constraints other than those in the constraint
+list returned by \fBconfigure \-constraints\fR are set to false.
+When the value of \fBconfigure \-constraints\fR
+is set, all those constraints are set to true.  The effect is that
+when both options \fBconfigure \-constraints\fR and
+\fBconfigure \-limitconstraints\fR are in use, only those tests including
+only constraints from the \fBconfigure \-constraints\fR list
+are run; all others are skipped.  For example, one might set
+up a configuration with
+.PP
+.CS
+\fBconfigure\fR -constraints knownBug \e
+          -limitconstraints true \e
+          -verbose pass
+.CE
+.PP
+to run exactly those tests that exercise known bugs, and discover
+whether any of them pass, indicating the bug had been fixed.
+.SS "RUNNING ALL TESTS"
+.PP
+The single command \fBrunAllTests\fR is evaluated to run an entire
+test suite, spanning many files and directories.  The configuration
+options of \fBtcltest\fR control the precise operations.  The
+\fBrunAllTests\fR command begins by printing a summary of its
+configuration to \fBoutputChannel\fR.
+.PP
+Test files to be evaluated are sought in the directory
+\fBconfigure \-testdir\fR.  The list of files in that directory
+that match any of the patterns in \fBconfigure \-file\fR and
+match none of the patterns in \fBconfigure \-notfile\fR is generated
+and sorted.  Then each file will be evaluated in turn.  If
+\fBconfigure \-singleproc\fR is true, then each file will
+be \fBsource\fRd in the caller's context.  If it is false,
+then a copy of \fBinterpreter\fR will be \fBexec\fR'd to
+evaluate each file.  The multi-process operation is useful
+when testing can cause errors so severe that a process
+terminates.  Although such an error may terminate a child
+process evaluating one file, the master process can continue
+with the rest of the test suite.  In multi-process operation,
+the configuration of \fBtcltest\fR in the master process is
+passed to the child processes as command line arguments,
+with the exception of \fBconfigure \-outfile\fR.  The
+\fBrunAllTests\fR command in the
+master process collects all output from the child processes
+and collates their results into one master report.  Any
+reports of individual test failures, or messages requested
+by a \fBconfigure \-verbose\fR setting are passed directly
+on to \fBoutputChannel\fR by the master process.
+.PP
+After evaluating all selected test files, a summary of the
+results is printed to \fBoutputChannel\fR.  The summary
+includes the total number of \fBtest\fRs evaluated, broken
+down into those skipped, those passed, and those failed.
+The summary also notes the number of files evaluated, and the names
+of any files with failing tests or errors.  A list of
+the constraints that caused tests to be skipped, and the
+number of tests skipped for each is also printed.  Also,
+messages are printed if it appears that evaluation of
+a test file has caused any temporary files to be left
+behind in \fBconfigure \-tmpdir\fR.
+.PP
+Having completed and summarized all selected test files,
+\fBrunAllTests\fR then recursively acts on subdirectories
+of \fBconfigure \-testdir\fR.  All subdirectories that
+match any of the patterns in \fBconfigure \-relateddir\fR
+and do not match any of the patterns in
+\fBconfigure \-asidefromdir\fR are examined.  If
+a file named \fBall.tcl\fR is found in such a directory,
+it will be \fBsource\fRd in the caller's context.
+Whether or not an examined directory contains an
+\fBall.tcl\fR file, its subdirectories are also scanned
+against the \fBconfigure \-relateddir\fR and
+\fBconfigure \-asidefromdir\fR patterns.  In this way,
+many directories in a directory tree can have all their
+test files evaluated by a single \fBrunAllTests\fR
+command.
+.SH "CONFIGURABLE OPTIONS"
+The \fBconfigure\fR command is used to set and query the configurable
+options of \fBtcltest\fR.  The valid options are:
+.TP
+\fB\-singleproc \fIboolean\fR
+.
+Controls whether or not \fBrunAllTests\fR spawns a child process for
+each test file.  No spawning when \fIboolean\fR is true.  Default
+value is false.
+.TP
+\fB\-debug \fIlevel\fR
+.
+Sets the debug level to \fIlevel\fR, an integer value indicating how
+much debugging information should be printed to \fBstdout\fR.  Note that
+debug messages always go to \fBstdout\fR, independent of the value of
+\fBconfigure \-outfile\fR.  Default value is 0.  Levels are defined as:
+.RS
+.IP 0 4
+Do not display any debug information.
+.IP 1
+Display information regarding whether a test is skipped because it
+does not match any of the tests that were specified using by
+\fBconfigure \-match\fR (userSpecifiedNonMatch) or matches any of
+the tests specified by \fBconfigure \-skip\fR (userSpecifiedSkip).  Also
+print warnings about possible lack of cleanup or balance in test files.
+Also print warnings about any re-use of test names.
+.IP 2
+Display the flag array parsed by the command line processor, the
+contents of the global \fBenv\fR array, and all user-defined variables
+that exist in the current namespace as they are used.
+.IP 3
+Display information regarding what individual procs in the test
+harness are doing.
+.RE
+.TP
+\fB\-verbose \fIlevel\fR
+.
+Sets the type of output verbosity desired to \fIlevel\fR,
+a list of zero or more of the elements \fBbody\fR, \fBpass\fR,
+\fBskip\fR, \fBstart\fR, \fBerror\fR, \fBline\fR, \fBmsec\fR and \fBusec\fR.
+Default value is
+.QW "\fBbody error\fR" .
+Levels are defined as:
+.RS
+.IP "body (\fBb\fR)"
+Display the body of failed tests
+.IP "pass (\fBp\fR)"
+Print output when a test passes
+.IP "skip (\fBs\fR)"
+Print output when a test is skipped
+.IP "start (\fBt\fR)"
+Print output whenever a test starts
+.IP "error (\fBe\fR)"
+Print errorInfo and errorCode, if they exist, when a test return code
+does not match its expected return code
+.IP "line (\fBl\fR)"
+Print source file line information of failed tests
+.IP "msec (\fBm\fR)"
+Print each test's execution time in milliseconds
+.IP "usec (\fBu\fR)"
+Print each test's execution time in microseconds
+.PP
+Note that the \fBmsec\fR and \fBusec\fR verbosity levels are provided as
+indicative measures only. They do not tackle the problem of repeatibility which
+should be considered in performance tests or benchmarks. To use these verbosity
+levels to thoroughly track performance degradations, consider wrapping your
+test bodies with \fBtime\fR commands.
+.PP
+The single letter abbreviations noted above are also recognized
+so that
+.QW "\fBconfigure \-verbose pt\fR"
+is the same as
+.QW "\fBconfigure \-verbose {pass start}\fR" .
+.RE
+.TP
+\fB\-preservecore \fIlevel\fR
+.
+Sets the core preservation level to \fIlevel\fR.  This level
+determines how stringent checks for core files are.  Default
+value is 0.  Levels are defined as:
+.RS
+.IP 0
+No checking \(em do not check for core files at the end of each test
+command, but do check for them in \fBrunAllTests\fR after all
+test files have been evaluated.
+.IP 1
+Also check for core files at the end of each \fBtest\fR command.
+.IP 2
+Check for core files at all times described above, and save a
+copy of each core file produced in \fBconfigure \-tmpdir\fR.
+.RE
+.TP
+\fB\-limitconstraints \fIboolean\fR
+.
+Sets the mode by which \fBtest\fR honors constraints as described
+in \fBTESTS\fR above.  Default value is false.
+.TP
+\fB\-constraints \fIlist\fR
+.
+Sets all the constraints in \fIlist\fR to true.  Also used in
+combination with \fBconfigure \-limitconstraints true\fR to control an
+alternative constraint mode as described in \fBTESTS\fR above.
+Default value is an empty list.
+.TP
+\fB\-tmpdir \fIdirectory\fR
+.
+Sets the temporary directory to be used by \fBmakeFile\fR,
+\fBmakeDirectory\fR, \fBviewFile\fR, \fBremoveFile\fR,
+and \fBremoveDirectory\fR as the default directory where
+temporary files and directories created by test files should
+be created.  Default value is \fBworkingDirectory\fR.
+.TP
+\fB\-testdir \fIdirectory\fR
+.
+Sets the directory searched by \fBrunAllTests\fR for test files
+and subdirectories.  Default value is \fBworkingDirectory\fR.
+.TP
+\fB\-file \fIpatternList\fR
+.
+Sets the list of patterns used by \fBrunAllTests\fR to determine
+what test files to evaluate.  Default value is
+.QW \fB*.test\fR .
+.TP
+\fB\-notfile \fIpatternList\fR
+.
+Sets the list of patterns used by \fBrunAllTests\fR to determine
+what test files to skip.  Default value is
+.QW \fBl.*.test\fR ,
+so that any SCCS lock files are skipped.
+.TP
+\fB\-relateddir \fIpatternList\fR
+.
+Sets the list of patterns used by \fBrunAllTests\fR to determine
+what subdirectories to search for an \fBall.tcl\fR file.  Default
+value is
+.QW \fB*\fR .
+.TP
+\fB\-asidefromdir \fIpatternList\fR
+.
+Sets the list of patterns used by \fBrunAllTests\fR to determine
+what subdirectories to skip when searching for an \fBall.tcl\fR file.
+Default value is an empty list.
+.TP
+\fB\-match \fIpatternList\fR
+.
+Set the list of patterns used by \fBtest\fR to determine whether
+a test should be run.  Default value is
+.QW \fB*\fR .
+.TP
+\fB\-skip \fIpatternList\fR
+.
+Set the list of patterns used by \fBtest\fR to determine whether
+a test should be skipped.  Default value is an empty list.
+.TP
+\fB\-load \fIscript\fR
+.
+Sets a script to be evaluated by \fBloadTestedCommands\fR.
+Default value is an empty script.
+.TP
+\fB\-loadfile \fIfilename\fR
+.
+Sets the filename from which to read a script to be evaluated
+by \fBloadTestedCommands\fR.  This is an alternative to
+\fB\-load\fR.  They cannot be used together.
+.TP
+\fB\-outfile \fIfilename\fR
+.
+Sets the file to which all output produced by tcltest should be
+written.  A file named \fIfilename\fR will be \fBopen\fRed for writing,
+and the resulting channel will be set as the value of \fBoutputChannel\fR.
+.TP
+\fB\-errfile \fIfilename\fR
+.
+Sets the file to which all error output produced by tcltest
+should be written.  A file named \fIfilename\fR will be \fBopen\fRed
+for writing, and the resulting channel will be set as the value
+of \fBerrorChannel\fR.
+.SH "CREATING TEST SUITES WITH TCLTEST"
+.PP
+The fundamental element of a test suite is the individual \fBtest\fR
+command.  We begin with several examples.
+.IP [1]
+Test of a script that returns normally.
+.RS
+.PP
+.CS
+\fBtest\fR example-1.0 {normal return} {
+    format %s value
+} value
+.CE
+.RE
+.IP [2]
+Test of a script that requires context setup and cleanup.  Note the
+bracing and indenting style that avoids any need for line continuation.
+.RS
+.PP
+.CS
+\fBtest\fR example-1.1 {test file existence} -setup {
+    set file [makeFile {} test]
+} -body {
+    file exists $file
+} -cleanup {
+    removeFile test
+} -result 1
+.CE
+.RE
+.IP [3]
+Test of a script that raises an error.
+.RS
+.PP
+.CS
+\fBtest\fR example-1.2 {error return} -body {
+    error message
+} -returnCodes error -result message
+.CE
+.RE
+.IP [4]
+Test with a constraint.
+.RS
+.PP
+.CS
+\fBtest\fR example-1.3 {user owns created files} -constraints {
+    unix
+} -setup {
+    set file [makeFile {} test]
+} -body {
+    file attributes $file -owner
+} -cleanup {
+    removeFile test
+} -result $::tcl_platform(user)
+.CE
+.RE
+.PP
+At the next higher layer of organization, several \fBtest\fR commands
+are gathered together into a single test file.  Test files should have
+names with the
+.QW \fB.test\fR
+extension, because that is the default pattern
+used by \fBrunAllTests\fR to find test files.  It is a good rule of
+thumb to have one test file for each source code file of your project.
+It is good practice to edit the test file and the source code file
+together, keeping tests synchronized with code changes.
+.PP
+Most of the code in the test file should be the \fBtest\fR commands.
+Use constraints to skip tests, rather than conditional evaluation
+of \fBtest\fR.
+.IP [5]
+Recommended system for writing conditional tests, using constraints to
+guard:
+.RS
+.PP
+.CS
+\fBtestConstraint\fR X [expr $myRequirement]
+\fBtest\fR goodConditionalTest {} X {
+    # body
+} result
+.CE
+.RE
+.IP [6]
+Discouraged system for writing conditional tests, using \fBif\fR to
+guard:
+.RS
+.PP
+.CS
+if $myRequirement {
+    \fBtest\fR badConditionalTest {} {
+        #body
+    } result
+}
+.CE
+.RE
+.PP
+Use the \fB\-setup\fR and \fB\-cleanup\fR options to establish and release
+all context requirements of the test body.  Do not make tests depend on
+prior tests in the file.  Those prior tests might be skipped.  If several
+consecutive tests require the same context, the appropriate setup
+and cleanup scripts may be stored in variable for passing to each tests
+\fB\-setup\fR and \fB\-cleanup\fR options.  This is a better solution than
+performing setup outside of \fBtest\fR commands, because the setup will
+only be done if necessary, and any errors during setup will be reported,
+and not cause the test file to abort.
+.PP
+A test file should be able to be combined with other test files and not
+interfere with them, even when \fBconfigure \-singleproc 1\fR causes
+all files to be evaluated in a common interpreter.  A simple way to
+achieve this is to have your tests define all their commands and variables
+in a namespace that is deleted when the test file evaluation is complete.
+A good namespace to use is a child namespace \fBtest\fR of the namespace
+of the module you are testing.
+.PP
+A test file should also be able to be evaluated directly as a script,
+not depending on being called by a master \fBrunAllTests\fR.  This
+means that each test file should process command line arguments to give
+the tester all the configuration control that \fBtcltest\fR provides.
+.PP
+After all \fBtest\fRs in a test file, the command \fBcleanupTests\fR
+should be called.
+.IP [7]
+Here is a sketch of a sample test file illustrating those points:
+.RS
+.PP
+.CS
+package require tcltest 2.2
+eval \fB::tcltest::configure\fR $argv
+package require example
+namespace eval ::example::test {
+    namespace import ::tcltest::*
+    \fBtestConstraint\fR X [expr {...}]
+    variable SETUP {#common setup code}
+    variable CLEANUP {#common cleanup code}
+    \fBtest\fR example-1 {} -setup $SETUP -body {
+        # First test
+    } -cleanup $CLEANUP -result {...}
+    \fBtest\fR example-2 {} -constraints X -setup $SETUP -body {
+        # Second test; constrained
+    } -cleanup $CLEANUP -result {...}
+    \fBtest\fR example-3 {} {
+        # Third test; no context required
+    } {...}
+    \fBcleanupTests\fR
+}
+namespace delete ::example::test
+.CE
+.RE
+.PP
+The next level of organization is a full test suite, made up of several
+test files.  One script is used to control the entire suite.  The
+basic function of this script is to call \fBrunAllTests\fR after
+doing any necessary setup.  This script is usually named \fBall.tcl\fR
+because that is the default name used by \fBrunAllTests\fR when combining
+multiple test suites into one testing run.
+.IP [8]
+Here is a sketch of a sample test suite master script:
+.RS
+.PP
+.CS
+package require Tcl 8.4
+package require tcltest 2.2
+package require example
+\fB::tcltest::configure\fR -testdir \e
+        [file dirname [file normalize [info script]]]
+eval \fB::tcltest::configure\fR $argv
+\fB::tcltest::runAllTests\fR
+.CE
+.RE
+.SH COMPATIBILITY
+.PP
+A number of commands and variables in the \fB::tcltest\fR namespace
+provided by earlier releases of \fBtcltest\fR have not been documented
+here.  They are no longer part of the supported public interface of
+\fBtcltest\fR and should not be used in new test suites.  However,
+to continue to support existing test suites written to the older
+interface specifications, many of those deprecated commands and
+variables still work as before.  For example, in many circumstances,
+\fBconfigure\fR will be automatically called shortly after
+\fBpackage require\fR \fBtcltest 2.1\fR succeeds with arguments
+from the variable \fB::argv\fR.  This is to support test suites
+that depend on the old behavior that \fBtcltest\fR was automatically
+configured from command line arguments.  New test files should not
+depend on this, but should explicitly include
+.PP
+.CS
+eval \fB::tcltest::configure\fR $::argv
+.CE
+.PP
+or
+.PP
+.CS
+\fB::tcltest::configure\fR {*}$::argv
+.CE
+.PP
+to establish a configuration from command line arguments.
+.SH "KNOWN ISSUES"
+There are two known issues related to nested evaluations of \fBtest\fR.
+The first issue relates to the stack level in which test scripts are
+executed.  Tests nested within other tests may be executed at the same
+stack level as the outermost test.  For example, in the following code:
+.PP
+.CS
+\fBtest\fR level-1.1 {level 1} {
+    -body {
+        \fBtest\fR level-2.1 {level 2} {
+        }
+    }
+}
+.CE
+.PP
+any script executed in level-2.1 may be executed at the same stack
+level as the script defined for level-1.1.
+.PP
+In addition, while two \fBtest\fRs have been run, results will only
+be reported by \fBcleanupTests\fR for tests at the same level as
+test level-1.1.  However, test results for all tests run prior to
+level-1.1 will be available when test level-2.1 runs.  What this
+means is that if you try to access the test results for test level-2.1,
+it will may say that
+.QW m
+tests have run,
+.QW n
+tests have been skipped,
+.QW o
+tests have passed and
+.QW p
+tests have failed, where
+.QW m ,
+.QW n ,
+.QW o ,
+and
+.QW p
+refer to tests that were run at the same test level as test level-1.1.
+.PP
+Implementation of output and error comparison in the test command
+depends on usage of \fBputs\fR in your application code.  Output is
+intercepted by redefining the global \fBputs\fR command while the defined test
+script is being run.  Errors thrown by C procedures or printed
+directly from C applications will not be caught by the \fBtest\fR command.
+Therefore, usage of the \fB\-output\fR and \fB\-errorOutput\fR
+options to \fBtest\fR is useful only for pure Tcl applications
+that use \fBputs\fR to produce output.
+.SH KEYWORDS
+test, test harness, test suite
+.\" Local Variables:
+.\" mode: nroff
+.\" End:
diff --git a/doc/tclvars.n b/doc/tclvars.n
new file mode 100644
index 0000000..adefe40
--- /dev/null
+++ b/doc/tclvars.n
@@ -0,0 +1,566 @@
+'\"
+'\" Copyright (c) 1993 The Regents of the University of California.
+'\" Copyright (c) 1994-1997 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH tclvars n 8.0 Tcl "Tcl Built-In Commands"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+argc, argv, argv0, auto_path, env, errorCode, errorInfo, tcl_interactive, tcl_library, tcl_nonwordchars, tcl_patchLevel, tcl_pkgPath, tcl_platform, tcl_precision, tcl_rcFileName, tcl_traceCompile, tcl_traceExec, tcl_wordchars, tcl_version \- Variables used by Tcl
+.BE
+.SH DESCRIPTION
+.PP
+The following global variables are created and managed automatically
+by the Tcl library.  Except where noted below, these variables should
+normally be treated as read-only by application-specific code and by users.
+.TP
+\fBauto_path\fR
+.
+If set, then it must contain a valid Tcl list giving directories to
+search during auto-load operations (including for package index
+files when using the default \fBpackage unknown\fR handler).
+This variable is initialized during startup to contain, in order:
+the directories listed in the \fBTCLLIBPATH\fR environment variable,
+the directory named by the \fBtcl_library\fR global variable,
+the parent directory of \fBtcl_library\fR,
+the directories listed in the \fBtcl_pkgPath\fR variable.
+Additional locations to look for files and package indices should
+normally be added to this variable using \fBlappend\fR.
+.RS
+.PP
+Additional variables relating to package management exist. More
+details are listed in the \fBVARIABLES\fR section of the \fBlibrary\fR
+manual page.
+.RE
+.TP
+\fBenv\fR
+.
+This variable is maintained by Tcl as an array
+whose elements are the environment variables for the process.
+Reading an element will return the value of the corresponding
+environment variable.
+Setting an element of the array will modify the corresponding
+environment variable or create a new one if it does not already
+exist.
+Unsetting an element of \fBenv\fR will remove the corresponding
+environment variable.
+Changes to the \fBenv\fR array will affect the environment
+passed to children by commands like \fBexec\fR.
+If the entire \fBenv\fR array is unset then Tcl will stop
+monitoring \fBenv\fR accesses and will not update environment
+variables.
+.RS
+.PP
+Under Windows, the environment variables PATH and COMSPEC in any
+capitalization are converted automatically to upper case.  For instance, the
+PATH variable could be exported by the operating system as
+.QW path ,
+.QW Path ,
+.QW PaTh ,
+etc., causing otherwise simple Tcl code to have to
+support many special cases.  All other environment variables inherited by
+Tcl are left unmodified.  Setting an env array variable to blank is the
+same as unsetting it as this is the behavior of the underlying Windows OS.
+It should be noted that relying on an existing and empty environment variable
+will not work on Windows and is discouraged for cross-platform usage.
+.PP
+The following elements of \fBenv\fR are special to Tcl:
+.TP
+\fBenv(HOME)\fR
+.
+This environment variable, if set, gives the location of the directory
+considered to be the current user's home directory, and to which a
+call of \fBcd\fR without arguments or with just
+.QW ~
+as an argument will change into. Most platforms set this correctly by
+default; it does not normally need to be set by user code.
+.TP
+\fBenv(TCL_LIBRARY)\fR
+.
+If set, then it specifies the location of the directory containing
+library scripts (the value of this variable will be
+assigned to the \fBtcl_library\fR variable and therefore returned by
+the command \fBinfo library\fR).  If this variable is not set then
+a default value is used.
+.RS
+.PP
+Note that this environment variable should \fInot\fR normally be set.
+.RE
+.TP
+\fBenv(TCLLIBPATH)\fR
+.
+If set, then it must contain a valid Tcl list giving directories to
+search during auto-load operations.  Directories must be specified in
+Tcl format, using
+.QW /
+as the path separator, regardless of platform.
+This variable is only used when initializing the \fBauto_path\fR variable.
+.TP
+\fBenv(TCL_TZ)\fR, \fBenv(TZ)\fR
+.
+These specify the default timezone used for parsing and formatting times and
+dates in the \fBclock\fR command. On many platforms, the TZ environment
+variable is set up by the operating system.
+.TP
+\fBenv(LC_ALL)\fR, \fBenv(LC_MESSAGES)\fR, \fBenv(LANG)\fR
+.
+These environment variables are used by the \fBmsgcat\fR package to
+determine what locale to format messages using.
+.TP
+\fBenv(TCL_INTERP_DEBUG_FRAME)\fR
+.
+If existing, it has the same effect as running \fBinterp debug\fR
+\fB{} -frame 1\fR
+as the very first command of each new Tcl interpreter.
+.RE
+.TP
+\fBerrorCode\fR
+.
+This variable holds the value of the \fB\-errorcode\fR return option
+set by the most recent error that occurred in this interpreter.
+This list value represents additional information about the error
+in a form that is easy to process with programs.
+The first element of the list identifies a general class of
+errors, and determines the format of the rest of the list.
+The following formats for \fB\-errorcode\fR return options
+are used by the Tcl core; individual applications may define
+additional formats.
+.RS
+.TP
+\fBARITH\fI code msg\fR
+.
+This format is used when an arithmetic error occurs (e.g. an attempt
+to divide zero by zero in the \fBexpr\fR command).
+\fICode\fR identifies the precise error and \fImsg\fR provides a
+human-readable description of the error.  \fICode\fR will be either
+DIVZERO (for an attempt to divide by zero),
+DOMAIN (if an argument is outside the domain of a function, such as acos(\-3)),
+IOVERFLOW (for integer overflow),
+OVERFLOW (for a floating-point overflow),
+or UNKNOWN (if the cause of the error cannot be determined).
+.RS
+.PP
+Detection of these errors depends in part on the underlying hardware
+and system libraries.
+.RE
+.TP
+\fBCHILDKILLED\fI pid sigName msg\fR
+.
+This format is used when a child process has been killed because of
+a signal.  The \fIpid\fR element will be the process's identifier (in decimal).
+The \fIsigName\fR element will be the symbolic name of the signal that caused
+the process to terminate; it will be one of the names from the
+include file signal.h, such as \fBSIGPIPE\fR.
+The \fImsg\fR element will be a short human-readable message
+describing the signal, such as
+.QW "write on pipe with no readers"
+for \fBSIGPIPE\fR.
+.TP
+\fBCHILDSTATUS\fI pid code\fR
+.
+This format is used when a child process has exited with a non-zero
+exit status.  The \fIpid\fR element will be the
+process's identifier (in decimal) and the \fIcode\fR element will be the exit
+code returned by the process (also in decimal).
+.TP
+\fBCHILDSUSP\fI pid sigName msg\fR
+.
+This format is used when a child process has been suspended because
+of a signal.
+The \fIpid\fR element will be the process's identifier, in decimal.
+The \fIsigName\fR element will be the symbolic name of the signal that caused
+the process to suspend; this will be one of the names from the
+include file signal.h, such as \fBSIGTTIN\fR.
+The \fImsg\fR element will be a short human-readable message
+describing the signal, such as
+.QW "background tty read"
+for \fBSIGTTIN\fR.
+.TP
+\fBNONE\fR
+.
+This format is used for errors where no additional information is
+available for an error besides the message returned with the
+error.  In these cases the \fB\-errorcode\fR return option
+will consist of a list containing a single element whose
+contents are \fBNONE\fR.
+.TP
+\fBPOSIX \fIerrName msg\fR
+.
+If the first element is \fBPOSIX\fR, then
+the error occurred during a POSIX kernel call.
+The \fIerrName\fR element will contain the symbolic name
+of the error that occurred, such as \fBENOENT\fR; this will
+be one of the values defined in the include file errno.h.
+The \fImsg\fR element will be a human-readable
+message corresponding to \fIerrName\fR, such as
+.QW "no such file or directory"
+for the \fBENOENT\fR case.
+.TP
+\fBTCL\fR ...
+.
+Indicates some sort of problem generated in relation to Tcl itself, e.g. a
+failure to look up a channel or variable.
+.PP
+To set the \fB\-errorcode\fR return option, applications should use library
+procedures such as \fBTcl_SetObjErrorCode\fR, \fBTcl_SetReturnOptions\fR,
+and \fBTcl_PosixError\fR, or they may invoke the \fB\-errorcode\fR
+option of the \fBreturn\fR command.
+If none of these methods for setting the error code has been used,
+the Tcl interpreter will reset the variable to \fBNONE\fR after
+the next error.
+.RE
+.TP
+\fBerrorInfo\fR
+.
+This variable holds the value of the \fB\-errorinfo\fR return option
+set by the most recent error that occurred in this interpreter.
+This string value will contain one or more lines
+identifying the Tcl commands and procedures that were being executed
+when the most recent error occurred.
+Its contents take the form of a stack trace showing the various
+nested Tcl commands that had been invoked at the time of the error.
+.TP
+\fBtcl_library\fR
+.
+This variable holds the name of a directory containing the
+system library of Tcl scripts, such as those used for auto-loading.
+The value of this variable is returned by the \fBinfo library\fR command.
+See the \fBlibrary\fR manual entry for details of the facilities
+provided by the Tcl script library.
+Normally each application or package will have its own application-specific
+script library in addition to the Tcl script library;
+each application should set a global variable with a name like
+\fB$\fIapp\fB_library\fR (where \fIapp\fR is the application's name)
+to hold the network file name for that application's library directory.
+The initial value of \fBtcl_library\fR is set when an interpreter
+is created by searching several different directories until one is
+found that contains an appropriate Tcl startup script.
+If the \fBTCL_LIBRARY\fR environment variable exists, then
+the directory it names is checked first.
+If \fBTCL_LIBRARY\fR is not set or doesn't refer to an appropriate
+directory, then Tcl checks several other directories based on a
+compiled-in default location, the location of the binary containing
+the application, and the current working directory.
+.TP
+\fBtcl_patchLevel\fR
+.
+When an interpreter is created Tcl initializes this variable to
+hold a string giving the current patch level for Tcl, such as
+\fB8.4.16\fR for Tcl 8.4 with the first sixteen official patches, or
+\fB8.5b3\fR for the third beta release of Tcl 8.5.
+The value of this variable is returned by the \fBinfo patchlevel\fR
+command.
+.TP
+\fBtcl_pkgPath\fR
+.
+This variable holds a list of directories indicating where packages are
+normally installed.  It is not used on Windows.  It typically contains
+either one or two entries; if it contains two entries, the first is
+normally a directory for platform-dependent packages (e.g., shared library
+binaries) and the second is normally a directory for platform-independent
+packages (e.g., script files). Typically a package is installed as a
+subdirectory of one of the entries in the \fBtcl_pkgPath\fR
+variable. The directories in the \fBtcl_pkgPath\fR variable are
+included by default in the \fBauto_path\fR
+variable, so they and their immediate subdirectories are automatically
+searched for packages during \fBpackage require\fR commands.  Note:
+\fBtcl_pkgPath\fR is not intended to be modified by the application.  Its
+value is added to \fBauto_path\fR at startup; changes to \fBtcl_pkgPath\fR
+are not reflected in \fBauto_path\fR.  If you want Tcl to search additional
+directories for packages you should add the names of those directories to
+\fBauto_path\fR, not \fBtcl_pkgPath\fR.
+.TP
+\fBtcl_platform\fR
+.
+This is an associative array whose elements contain information about
+the platform on which the application is running, such as the name of
+the operating system, its current release number, and the machine's
+instruction set.  The elements listed below will always
+be defined, but they may have empty strings as values if Tcl could not
+retrieve any relevant information.  In addition, extensions
+and applications may add additional values to the array.  The
+predefined elements are:
+.RS
+.TP
+\fBbyteOrder\fR
+.
+The native byte order of this machine: either \fBlittleEndian\fR or
+\fBbigEndian\fR.
+.TP
+\fBdebug\fR
+.
+If this variable exists, then the interpreter was compiled with and linked
+to a debug-enabled C run-time.  This variable will only exist on Windows,
+so extension writers can specify which package to load depending on the
+C run-time library that is in use.  This is not an indication that this core
+contains symbols.
+.TP
+\fBengine\fR
+.
+The name of the Tcl language implementation.  When the interpreter is first
+created, this is always set to the string \fBTcl\fR.
+.TP
+\fBmachine\fR
+.
+The instruction set executed by this machine, such as
+\fBintel\fR, \fBPPC\fR, \fB68k\fR, or \fBsun4m\fR.  On UNIX machines, this
+is the value returned by \fBuname -m\fR.
+.TP
+\fBos\fR
+.
+The name of the operating system running on this machine,
+such as \fBWindows NT\fR or \fBSunOS\fR.
+On UNIX machines, this is the value returned by \fBuname -s\fR.
+.TP
+\fBosVersion\fR
+.
+The version number for the operating system running on this machine.
+On UNIX machines, this is the value returned by \fBuname -r\fR.
+.TP
+\fBpathSeparator\fR
+.VS 8.6
+'\" Defined by TIP #315
+The character that should be used to \fBsplit\fR PATH-like environment
+variables into their corresponding list of directory names.
+.VE 8.6
+.TP
+\fBplatform\fR
+.
+Either \fBwindows\fR, or \fBunix\fR.  This identifies the
+general operating environment of the machine.
+.TP
+\fBpointerSize\fR
+.
+This gives the size of the native-machine pointer in bytes (strictly, it
+is same as the result of evaluating \fIsizeof(void*)\fR in C.)
+.TP
+\fBthreaded\fR
+.
+If this variable exists, then the interpreter
+was compiled with threads enabled.
+.TP
+\fBuser\fR
+.
+This identifies the
+current user based on the login information available on the platform.
+This value comes from the getuid() and getpwuid() system calls on Unix,
+and the value from the GetUserName() system call on Windows.
+.TP
+\fBwordSize\fR
+.
+This gives the size of the native-machine word in bytes (strictly, it
+is same as the result of evaluating \fIsizeof(long)\fR in C.)
+.RE
+.TP
+\fBtcl_precision\fR
+.
+This variable controls the number of digits to generate
+when converting floating-point values to strings.  It defaults
+to 0.  \fIApplications should not change this value;\fR it is
+provided for compatibility with legacy code.
+.PP
+.RS
+The default value of 0 is special, meaning that Tcl should
+convert numbers using as few digits as possible while still
+distinguishing any floating point number from its nearest
+neighbours.  It differs from using an arbitrarily high value
+for \fItcl_precision\fR in that an inexact number like \fI1.4\fR
+will convert as \fI1.4\fR rather than \fI1.3999999999999999\fR
+even though the latter is nearer to the exact value of the
+binary number.
+.RE
+.PP
+.RS
+If \fBtcl_precision\fR is not zero, then when Tcl converts a floating
+point number, it creates a decimal representation of at most
+\fBtcl_precision\fR significant digits; the result may be shorter if
+the shorter result represents the original number exactly. If no
+result of at most \fBtcl_precision\fR digits is an exact representation
+of the original number, the one that is closest to the original
+number is chosen.
+If the original number lies precisely between two equally accurate
+decimal representations, then the one with an even value for the least
+significant digit is chosen; for instance, if \fBtcl_precision\fR is 3, then
+0.3125 will convert to 0.312, not 0.313, while 0.6875 will convert to
+0.688, not 0.687. Any string of trailing zeroes that remains is trimmed.
+.RE
+.PP
+.RS
+a \fBtcl_precision\fR value of 17 digits is
+.QW perfect
+for IEEE floating-point in that it allows
+double-precision values to be converted to strings and back to
+binary with no loss of information. For this reason, you will often
+see it as a value in legacy code that must run on Tcl versions before
+8.5. It is no longer recommended; as noted above, a zero value is the
+preferred method.
+.RE
+.PP
+.RS
+All interpreters in a thread share a single \fBtcl_precision\fR value:
+changing it in one interpreter will affect all other interpreters as
+well.  Safe interpreters are not allowed to modify the
+variable.
+.RE
+.PP
+.RS
+Valid values for \fBtcl_precision\fR range from 0 to 17.
+.RE
+.TP
+\fBtcl_rcFileName\fR
+.
+This variable is used during initialization to indicate the name of a
+user-specific startup file.  If it is set by application-specific
+initialization, then the Tcl startup code will check for the existence
+of this file and \fBsource\fR it if it exists.  For example, for \fBwish\fR
+the variable is set to \fB~/.wishrc\fR for Unix and \fB~/wishrc.tcl\fR
+for Windows.
+.TP
+\fBtcl_traceCompile\fR
+.
+The value of this variable can be set to control
+how much tracing information
+is displayed during bytecode compilation.
+By default, \fBtcl_traceCompile\fR is zero and no information is displayed.
+Setting \fBtcl_traceCompile\fR to 1 generates a one-line summary in \fBstdout\fR
+whenever a procedure or top-level command is compiled.
+Setting it to 2 generates a detailed listing in \fBstdout\fR of the
+bytecode instructions emitted during every compilation.
+This variable is useful in
+tracking down suspected problems with the Tcl compiler.
+.PP
+.RS
+This variable and functionality only exist if
+\fBTCL_COMPILE_DEBUG\fR was defined during Tcl's compilation.
+.RE
+.TP
+\fBtcl_traceExec\fR
+.
+The value of this variable can be set to control
+how much tracing information
+is displayed during bytecode execution.
+By default, \fBtcl_traceExec\fR is zero and no information is displayed.
+Setting \fBtcl_traceExec\fR to 1 generates a one-line trace in \fBstdout\fR
+on each call to a Tcl procedure.
+Setting it to 2 generates a line of output
+whenever any Tcl command is invoked
+that contains the name of the command and its arguments.
+Setting it to 3 produces a detailed trace showing the result of
+executing each bytecode instruction.
+Note that when \fBtcl_traceExec\fR is 2 or 3,
+commands such as \fBset\fR and \fBincr\fR
+that have been entirely replaced by a sequence
+of bytecode instructions are not shown.
+Setting this variable is useful in
+tracking down suspected problems with the bytecode compiler
+and interpreter.
+.PP
+.RS
+This variable and functionality only exist if
+\fBTCL_COMPILE_DEBUG\fR was defined during Tcl's compilation.
+.RE
+.TP
+\fBtcl_wordchars\fR
+.
+The value of this variable is a regular expression that can be set to
+control what are considered
+.QW word
+characters, for instances like
+selecting a word by double-clicking in text in Tk.  It is platform
+dependent.  On Windows, it defaults to \fB\eS\fR, meaning anything
+but a Unicode space character.  Otherwise it defaults to \fB\ew\fR,
+which is any Unicode word character (number, letter, or underscore).
+.TP
+\fBtcl_nonwordchars\fR
+.
+The value of this variable is a regular expression that can be set to
+control what are considered
+.QW non-word
+characters, for instances like
+selecting a word by double-clicking in text in Tk.  It is platform
+dependent.  On Windows, it defaults to \fB\es\fR, meaning any Unicode space
+character.  Otherwise it defaults to \fB\eW\fR, which is anything but a
+Unicode word character (number, letter, or underscore).
+.TP
+\fBtcl_version\fR
+.
+When an interpreter is created Tcl initializes this variable to
+hold the version number for this version of Tcl in the form \fIx.y\fR.
+Changes to \fIx\fR represent major changes with probable
+incompatibilities and changes to \fIy\fR represent small enhancements and
+bug fixes that retain backward compatibility.
+The value of this variable is returned by the \fBinfo tclversion\fR
+command.
+.SH "OTHER GLOBAL VARIABLES"
+.PP
+The following variables are only guaranteed to exist in \fBtclsh\fR
+and \fBwish\fR executables; the Tcl library does not define them
+itself but many Tcl environments do.
+.TP 6
+\fBargc\fR
+.
+The number of arguments to \fBtclsh\fR or \fBwish\fR.
+.TP 6
+\fBargv\fR
+.
+Tcl list of arguments to \fBtclsh\fR or \fBwish\fR.
+.TP 6
+\fBargv0\fR
+.
+The script that \fBtclsh\fR or \fBwish\fR started executing (if it was
+specified) or otherwise the name by which \fBtclsh\fR or \fBwish\fR
+was invoked.
+.TP 6
+\fBtcl_interactive\fR
+.
+Contains 1 if \fBtclsh\fR or \fBwish\fR is running interactively (no
+script was specified and standard input is a terminal-like device), 0
+otherwise.
+.SH EXAMPLES
+.PP
+To add a directory to the collection of locations searched by
+\fBpackage require\fR, e.g., because of some application-specific
+packages that are used, the \fBauto_path\fR variable needs to be
+updated:
+.PP
+.CS
+lappend ::\fBauto_path\fR [file join [pwd] "theLibDir"]
+.CE
+.PP
+A simple though not very robust way to handle command line arguments
+of the form
+.QW "\-foo 1 \-bar 2"
+is to load them into an array having first loaded in the default settings:
+.CS
+array set arguments {-foo 0 -bar 0 -grill 0}
+array set arguments $::\fBargv\fR
+puts "foo is $arguments(-foo)"
+puts "bar is $arguments(-bar)"
+puts "grill is $arguments(-grill)"
+.CE
+.PP
+The \fBargv0\fR global variable can be used (in conjunction with the
+\fBinfo script\fR command) to determine whether the current script is
+being executed as the main script or loaded as a library.  This is
+useful because it allows a single script to be used as both a library
+and a demonstration of that library:
+.PP
+.CS
+if {$::\fBargv0\fR eq [info script]} {
+    # running as: tclsh example.tcl
+} else {
+    package provide Example 1.0
+}
+.CE
+.SH "SEE ALSO"
+eval(n), library(n), tclsh(1), tkvars(n), wish(1)
+.SH KEYWORDS
+arithmetic, bytecode, compiler, error, environment, POSIX, precision,
+subprocess, user, variables
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/doc/tell.n b/doc/tell.n
new file mode 100644
index 0000000..e8bf3af
--- /dev/null
+++ b/doc/tell.n
@@ -0,0 +1,48 @@
+'\"
+'\" Copyright (c) 1993 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\" 
+.TH tell n 8.1 Tcl "Tcl Built-In Commands"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+tell \- Return current access position for an open channel
+.SH SYNOPSIS
+\fBtell \fIchannelId\fR
+.BE
+.SH DESCRIPTION
+.PP
+Returns an integer string giving the current access position in
+\fIchannelId\fR.  This value returned is a byte offset that can be passed to
+\fBseek\fR in order to set the channel to a particular position.  Note
+that this value is in terms of bytes, not characters like \fBread\fR.
+The value returned is -1 for channels that do not support
+seeking.
+.PP
+\fIChannelId\fR must be an identifier for an open channel such as a
+Tcl standard channel (\fBstdin\fR, \fBstdout\fR, or \fBstderr\fR),
+the return value from an invocation of \fBopen\fR or \fBsocket\fR, or
+the result of a channel creation command provided by a Tcl extension.
+.SH EXAMPLE
+.PP
+Read a line from a file channel only if it starts with \fBfoobar\fR:
+.PP
+.CS
+# Save the offset in case we need to undo the read...
+set offset [\fBtell\fR $chan]
+if {[read $chan 6] eq "foobar"} {
+    gets $chan line
+} else {
+    set line {}
+    # Undo the read...
+    seek $chan $offset
+}
+.CE
+.SH "SEE ALSO"
+file(n), open(n), close(n), gets(n), seek(n), Tcl_StandardChannels(3)
+.SH KEYWORDS
+access position, channel, seeking
diff --git a/doc/throw.n b/doc/throw.n
new file mode 100644
index 0000000..0d1df78
--- /dev/null
+++ b/doc/throw.n
@@ -0,0 +1,48 @@
+'\"
+'\" Copyright (c) 2008 Donal K. Fellows
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\" 
+.TH throw n 8.6 Tcl "Tcl Built-In Commands"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+throw \- Generate a machine-readable error
+.SH SYNOPSIS
+\fBthrow\fI type message\fR
+.BE
+.SH DESCRIPTION
+.PP
+This command causes the current evaluation to be unwound with an error. The
+error created is described by the \fItype\fR and \fImessage\fR arguments:
+\fItype\fR must contain a list of words describing the error in a form that is
+machine-readable (and which will form the error-code part of the result
+dictionary), and \fImessage\fR should contain text that is intended for
+display to a human being.
+.PP
+The stack will be unwound until the error is trapped by a suitable \fBcatch\fR
+or \fBtry\fR command. If it reaches the event loop without being trapped, it
+will be reported through the \fBbgerror\fR mechanism. If it reaches the top
+level of script evaluation in \fBtclsh\fR, it will be printed on the console
+before, in the non-interactive case, causing an exit (the behavior in other
+programs will depend on the details of how Tcl is embedded and used).
+.PP
+By convention, the words in the \fItype\fR argument should go from most
+general to most specific.
+.SH EXAMPLES
+.PP
+The following produces an error that is identical to that produced by
+\fBexpr\fR when trying to divide a value by zero.
+.PP
+.CS
+\fBthrow\fR {ARITH DIVZERO {divide by zero}} {divide by zero}
+.CE
+.SH "SEE ALSO"
+catch(n), error(n), errorCode(n), errorInfo(n), return(n), try(n)
+.SH "KEYWORDS"
+error, exception
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/doc/time.n b/doc/time.n
new file mode 100644
index 0000000..35b41c4
--- /dev/null
+++ b/doc/time.n
@@ -0,0 +1,47 @@
+'\"
+'\" Copyright (c) 1993 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\" 
+.TH time n "" Tcl "Tcl Built-In Commands"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+time \- Time the execution of a script
+.SH SYNOPSIS
+\fBtime \fIscript\fR ?\fIcount\fR?
+.BE
+.SH DESCRIPTION
+.PP
+This command will call the Tcl interpreter \fIcount\fR
+times to evaluate \fIscript\fR (or once if \fIcount\fR is not
+specified).  It will then return a string of the form
+.PP
+.CS
+\fB503.2 microseconds per iteration\fR
+.CE
+.PP
+which indicates the average amount of time required per iteration,
+in microseconds.
+Time is measured in elapsed time, not CPU time.
+.SH EXAMPLE
+Estimate how long it takes for a simple Tcl \fBfor\fR loop to count to
+a thousand:
+.PP
+.CS
+time {
+    for {set i 0} {$i<1000} {incr i} {
+        # empty body
+    }
+}
+.CE
+.SH "SEE ALSO"
+clock(n)
+.SH KEYWORDS
+script, time
+.\" Local Variables:
+.\" mode: nroff
+.\" End:
diff --git a/doc/tm.n b/doc/tm.n
new file mode 100644
index 0000000..5602686
--- /dev/null
+++ b/doc/tm.n
@@ -0,0 +1,308 @@
+'\"
+'\" Copyright (c) 2004-2010 Andreas Kupries <andreas_kupries@users.sourceforge.net>
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\" 
+.TH tm n 8.5 Tcl "Tcl Built-In Commands"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+tm \- Facilities for locating and loading of Tcl Modules
+.SH SYNOPSIS
+.nf
+\fB::tcl::tm::path add \fR?\fIpath\fR...?
+\fB::tcl::tm::path remove \fR?\fIpath\fR...?
+\fB::tcl::tm::path list\fR
+\fB::tcl::tm::roots \fR?\fIpath\fR...?
+.fi
+.BE
+.SH DESCRIPTION
+.PP
+This document describes the facilities for locating and loading Tcl
+Modules (see \fBMODULE DEFINITION\fR for the definition of a Tcl Module).
+The following commands are supported:
+.TP
+\fB::tcl::tm::path add \fR?\fIpath\fR...?
+.
+The paths are added at the head to the list of module paths, in order
+of appearance. This means that the last argument ends up as the new
+head of the list.
+.RS
+.PP
+The command enforces the restriction that no path may be an ancestor
+directory of any other path on the list. If any of the new paths
+violates this restriction an error will be raised, before any of the
+paths have been added. In other words, if only one path argument
+violates the restriction then none will be added.
+.PP
+If a path is already present as is, no error will be raised and no
+action will be taken.
+.PP
+Paths are searched later in the order of their appearance in the
+list. As they are added to the front of the list they are searched in
+reverse order of addition. In other words, the paths added last are
+looked at first.
+.RE
+.TP
+\fB::tcl::tm::path remove \fR?\fIpath\fR...?
+.
+Removes the paths from the list of module paths. The command silently
+ignores all paths which are not on the list.
+.TP
+\fB::tcl::tm::path list\fR
+.
+Returns a list containing all registered module paths, in the order
+that they are searched for modules.
+.TP
+\fB::tcl::tm::roots \fR?\fIpath\fR...?
+.
+Similar to \fBpath add\fR, and layered on top of it. This command
+takes a list of paths, extends each with
+.QW "\fBtcl\fIX\fB/site-tcl\fR" ,
+and
+.QW "\fBtcl\fIX\fB/\fIX\fB.\fIy\fR" ,
+for major version \fIX\fR of the
+Tcl interpreter and minor version \fIy\fR less than or equal to the
+minor version of the interpreter, and adds the resulting set of paths
+to the list of paths to search.
+.RS
+.PP
+This command is used internally by the system to set up the
+system-specific default paths.
+.PP
+The command has been exposed to allow a build system to define
+additional root paths beyond those described by this document.
+.RE
+.SH "MODULE DEFINITION"
+.PP
+A Tcl Module is a Tcl Package contained in a single file, and no other
+files required by it. This file has to be \fBsource\fRable. In other
+words, a Tcl Module is always imported via:
+.PP
+.CS
+source module_file
+.CE
+.PP
+The \fBload\fR command is not directly used. This restriction is not
+an actual limitation, as some may believe.
+Ever since 8.4 the Tcl \fBsource\fR command reads only until the first
+^Z character. This allows us to combine an arbitrary Tcl script with
+arbitrary binary data into one file, where the script processes the
+attached data in any it chooses to fully import and activate the
+package.
+.PP
+The name of a module file has to match the regular expression:
+.PP
+.CS
+([_[:alpha:]][:_[:alnum:]]*)-([[:digit:]].*)\e.tm
+.CE
+.PP
+The first capturing parentheses provides the name of the package, the
+second clause its version. In addition to matching the pattern, the
+extracted version number must not raise an error when used in the
+command:
+.PP
+.CS
+package vcompare $version 0
+.CE
+.SH "FINDING MODULES"
+.PP
+The directory tree for storing Tcl modules is separate from other
+parts of the filesystem and independent of \fBauto_path\fR.
+.PP
+Tcl Modules are searched for in all directories listed in the result
+of the command \fB::tcl::tm::path list\fR.
+This is called the \fIModule path\fR. Neither the \fBauto_path\fR nor
+the \fBtcl_pkgPath\fR variables are used.
+All directories on the module path have to obey one restriction:
+.RS
+.PP
+For any two directories, neither is an ancestor directory of the
+other.
+.RE
+.PP
+This is required to avoid ambiguities in package naming. If for
+example the two directories
+.QW "\fIfoo/\fR"
+and
+.QW "\fIfoo/cool\fR"
+were on
+the path a package named \fBcool::ice\fR could be found via the
+names \fBcool::ice\fR or \fBice\fR, the latter potentially
+obscuring a package named \fBice\fR, unqualified.
+.PP
+Before the search is started, the name of the requested package is
+translated into a partial path, using the following algorithm:
+.RS
+.PP
+All occurrences of
+.QW "\fB::\fR"
+in the package name are replaced by
+the appropriate directory separator character for the platform we are
+on. On Unix, for example, this is
+.QW "\fB/\fR" .
+.RE
+.PP
+Example:
+.RS
+.PP
+The requested package is \fBencoding::base64\fR. The generated
+partial path is
+.QW "\fIencoding/base64\fR" .
+.RE
+.PP
+After this translation the package is looked for in all module paths,
+by combining them one-by-one, first to last with the partial path to
+form a complete search pattern. Note that the search algorithm rejects
+all files where the filename does not match the regular expression
+given in the section \fBMODULE DEFINITION\fR. For the remaining
+files \fIprovide scripts\fR are generated and added to the package
+ifneeded database.
+.PP
+The algorithm falls back to the previous unknown handler when none of
+the found module files satisfy the request. If the request was
+satisfied the fall-back is ignored.
+.PP
+Note that packages in module form have \fIno\fR control over the
+\fIindex\fR and \fIprovide script\fRs entered into the package
+database for them.
+For a module file \fBMF\fR the \fIindex script\fR is always:
+.PP
+.CS
+package ifneeded \fBPNAME PVERSION\fR [list source \fBMF\fR]
+.CE
+.PP
+and the \fIprovide script\fR embedded in the above is:
+.PP
+.CS
+source \fBMF\fR
+.CE
+.PP
+Both package name \fBPNAME\fR and package version \fBPVERSION\fR are
+extracted from the filename \fBMF\fR according to the definition
+below:
+.PP
+.CS
+\fBMF\fR = /module_path/\fBPNAME\(fm\fR-\fBPVERSION\fR.tm
+.CE
+.PP
+Where \fBPNAME\(fm\fR is the partial path of the module as defined in
+section \fBFINDING MODULES\fR, and translated into \fBPNAME\fR by
+changing all directory separators to
+.QW "\fB::\fR" ,
+and \fBmodule_path\fR is the path (from the list of paths to search)
+that we found the module file under.
+.PP
+Note also that we are here creating a connection between package names
+and paths. Tcl is case-sensitive when it comes to comparing package
+names, but there are filesystems which are not, like NTFS. Luckily
+these filesystems do store the case of the name, despite not using the
+information when comparing.
+.PP
+Given the above we allow the names for packages in Tcl modules to have
+mixed-case, but also require that there are no collisions when
+comparing names in a case-insensitive manner. In other words, if a
+package \fBFoo\fR is deployed in the form of a Tcl Module,
+packages like \fBfoo\fR, \fBfOo\fR, etc. are not allowed
+anymore.
+.SH "DEFAULT PATHS"
+.PP
+The default list of paths on the module path is computed by a
+\fBtclsh\fR as follows, where \fIX\fR is the major version of the Tcl
+interpreter and \fIy\fR is less than or equal to the minor version of
+the Tcl interpreter.
+.PP
+All the default paths are added to the module path, even those paths
+which do not exist. Non-existent paths are filtered out during actual
+searches. This enables a user to create one of the paths searched when
+needed and all running applications will automatically pick up any
+modules placed in them.
+.PP
+The paths are added in the order as they are listed below, and for
+lists of paths defined by an environment variable in the order they
+are found in the variable.
+.SS "SYSTEM SPECIFIC PATHS"
+.TP
+\fBfile normalize [info library]/../tcl\fIX\fB/\fIX\fB.\fIy\fR
+.
+In other words, the interpreter will look into a directory specified
+by its major version and whose minor versions are less than or equal
+to the minor version of the interpreter.
+.RS
+.PP
+For example for Tcl 8.4 the paths searched are:
+.PP
+.CS
+\fB[info library]/../tcl8/8.4\fR
+\fB[info library]/../tcl8/8.3\fR
+\fB[info library]/../tcl8/8.2\fR
+\fB[info library]/../tcl8/8.1\fR
+\fB[info library]/../tcl8/8.0\fR
+.CE
+.PP
+This definition assumes that a package defined for Tcl \fIX\fB.\fIy\fR
+can also be used by all interpreters which have the same major number
+\fIX\fR and a minor number greater than \fIy\fR.
+.RE
+.TP
+\fBfile normalize EXEC/tcl\fIX\fB/\fIX\fB.\fIy\fR
+.
+Where \fBEXEC\fR is \fBfile normalize [info nameofexecutable]/../lib\fR
+or \fBfile normalize [::tcl::pkgconfig get libdir,runtime]\fR
+.RS
+.PP
+This sets of paths is handled equivalently to the set coming before,
+except that it is anchored in \fBEXEC_PREFIX\fR.
+For a build with \fBPREFIX\fR = \fBEXEC_PREFIX\fR the two sets are
+identical.
+.RE
+.SS "SITE SPECIFIC PATHS"
+.TP
+\fBfile normalize [info library]/../tcl\fIX\fB/site-tcl\fR
+.
+Note that this is always a single entry because \fIX\fR is always a
+specific value (the current major version of Tcl).
+.SS "USER SPECIFIC PATHS"
+.TP
+\fB$::env(TCL\fIX\fB_\fIy\fB_TM_PATH)\fR
+.
+A list of paths, separated by either \fB:\fR (Unix) or \fB;\fR
+(Windows). This is user and site specific as this environment variable
+can be set not only by the user's profile, but by system configuration
+scripts as well.
+.TP
+\fB$::env(TCL\fIX\fB.\fIy\fB_TM_PATH)\fR
+.
+Same meaning and content as the previous variable. However the use of
+dot '.' to separate major and minor version number makes this name
+less to non-portable and its use is discouraged. Support of this
+variable has been kept only for backward compatibility with the
+original specification, i.e. TIP 189.
+.PP
+These paths are seen and therefore shared by all Tcl shells in the
+\fB$::env(PATH)\fR of the user.
+.PP
+Note that \fIX\fR and \fIy\fR follow the general rules set out
+above. In other words, Tcl 8.4, for example, will look at these 10
+environment variables:
+.PP
+.CS
+\fB$::env(TCL8.4_TM_PATH)\fR  \fB$::env(TCL8_4_TM_PATH)\fR
+\fB$::env(TCL8.3_TM_PATH)\fR  \fB$::env(TCL8_3_TM_PATH)\fR
+\fB$::env(TCL8.2_TM_PATH)\fR  \fB$::env(TCL8_2_TM_PATH)\fR
+\fB$::env(TCL8.1_TM_PATH)\fR  \fB$::env(TCL8_1_TM_PATH)\fR
+\fB$::env(TCL8.0_TM_PATH)\fR  \fB$::env(TCL8_0_TM_PATH)\fR
+.CE
+.SH "SEE ALSO"
+package(n), Tcl Improvement Proposal #189
+.QW "\fITcl Modules\fR"
+(online at http://tip.tcl.tk/189.html), Tcl Improvement Proposal #190
+.QW "\fIImplementation Choices for Tcl Modules\fR"
+(online at http://tip.tcl.tk/190.html)
+.SH "KEYWORDS"
+modules, package
+.\" Local Variables:
+.\" mode: nroff
+.\" End:
diff --git a/doc/trace.n b/doc/trace.n
new file mode 100644
index 0000000..5482e59
--- /dev/null
+++ b/doc/trace.n
@@ -0,0 +1,426 @@
+'\"
+'\" Copyright (c) 1993 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\" Copyright (c) 2000 Ajuba Solutions.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH trace n "8.4" Tcl "Tcl Built-In Commands"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+trace \- Monitor variable accesses, command usages and command executions
+.SH SYNOPSIS
+\fBtrace \fIoption\fR ?\fIarg arg ...\fR?
+.BE
+.SH DESCRIPTION
+.PP
+This command causes Tcl commands to be executed whenever certain operations are
+invoked.  The legal \fIoption\fRs (which may be abbreviated) are:
+.TP
+\fBtrace add \fItype name ops ?args?\fR
+Where \fItype\fR is \fBcommand\fR, \fBexecution\fR, or \fBvariable\fR.
+.RS
+.TP
+\fBtrace add command\fR \fIname ops commandPrefix\fR
+.
+Arrange for \fIcommandPrefix\fR to be executed (with additional arguments)
+whenever command \fIname\fR is modified in one of the ways given by the list
+\fIops\fR. \fIName\fR will be resolved using the usual namespace resolution
+rules used by commands. If the command does not exist, an error will be
+thrown.
+.RS
+.PP
+\fIOps\fR indicates which operations are of interest, and is a list of
+one or more of the following items:
+.TP
+\fBrename\fR
+.
+Invoke \fIcommandPrefix\fR whenever the traced command is renamed.  Note that
+renaming to the empty string is considered deletion, and will not be traced
+with
+.QW \fBrename\fR .
+.TP
+\fBdelete\fR
+.
+Invoke \fIcommandPrefix\fR when the traced command is deleted. Commands can be
+deleted explicitly by using the \fBrename\fR command to rename the command to
+an empty string. Commands are also deleted when the interpreter is deleted,
+but traces will not be invoked because there is no interpreter in which to
+execute them.
+.PP
+When the trace triggers, depending on the operations being traced, a number of
+arguments are appended to \fIcommandPrefix\fR so that the actual command is as
+follows:
+.PP
+.CS
+\fIcommandPrefix oldName newName op\fR
+.CE
+.PP
+\fIOldName\fR and \fInewName\fR give the traced command's current (old) name,
+and the name to which it is being renamed (the empty string if this is a
+.QW delete
+operation).
+\fIOp\fR indicates what operation is being performed on the
+command, and is one of \fBrename\fR or \fBdelete\fR as
+defined above.  The trace operation cannot be used to stop a command
+from being deleted.  Tcl will always remove the command once the trace
+is complete.  Recursive renaming or deleting will not cause further traces
+of the same type to be evaluated, so a delete trace which itself
+deletes the command, or a rename trace which itself renames the
+command will not cause further trace evaluations to occur.
+Both \fIoldName\fR and \fInewName\fR are fully qualified with any namespace(s)
+in which they appear.
+.RE
+.TP
+\fBtrace add execution\fR \fIname ops commandPrefix\fR
+.
+Arrange for \fIcommandPrefix\fR to be executed (with additional arguments)
+whenever command \fIname\fR is executed, with traces occurring at the points
+indicated by the list \fIops\fR.  \fIName\fR will be resolved using the usual
+namespace resolution rules used by commands.  If the command does not exist,
+an error will be thrown.
+.RS
+.PP
+\fIOps\fR indicates which operations are of interest, and is a list of
+one or more of the following items:
+.TP
+\fBenter\fR
+Invoke \fIcommandPrefix\fR whenever the command \fIname\fR is executed,
+just before the actual execution takes place.
+.TP
+\fBleave\fR
+Invoke \fIcommandPrefix\fR whenever the command \fIname\fR is executed,
+just after the actual execution takes place.
+.TP
+\fBenterstep\fR
+.
+Invoke \fIcommandPrefix\fR for every Tcl command which is executed from the
+start of the execution of the procedure \fIname\fR until that
+procedure finishes. \fICommandPrefix\fR is invoked just before the actual
+execution of the Tcl command being reported takes place.  For example
+if we have
+.QW "proc foo {} { puts \N'34'hello\N'34' }" ,
+then an \fIenterstep\fR trace would be invoked just before
+.QW "\fIputs \N'34'hello\N'34'\fR"
+is executed.
+Setting an \fIenterstep\fR trace on a command \fIname\fR that does not refer
+to a procedure will not result in an error and is simply ignored.
+.TP
+\fBleavestep\fR
+.
+Invoke \fIcommandPrefix\fR for every Tcl command which is executed from the
+start of the execution of the procedure \fIname\fR until that
+procedure finishes. \fICommandPrefix\fR is invoked just after the actual
+execution of the Tcl command being reported takes place.
+Setting a \fIleavestep\fR trace on a command \fIname\fR that does not refer to
+a procedure will not result in an error and is simply ignored.
+.PP
+When the trace triggers, depending on the operations being traced, a
+number of arguments are appended to \fIcommandPrefix\fR so that the actual
+command is as follows:
+.PP
+For \fBenter\fR and \fBenterstep\fR operations:
+.PP
+.CS
+\fIcommandPrefix command-string op\fR
+.CE
+.PP
+\fICommand-string\fR gives the complete current command being
+executed (the traced command for a \fBenter\fR operation, an
+arbitrary command for a \fBenterstep\fR operation), including
+all arguments in their fully expanded form.
+\fIOp\fR indicates what operation is being performed on the
+command execution, and is one of \fBenter\fR or \fBenterstep\fR as
+defined above.  The trace operation can be used to stop the
+command from executing, by deleting the command in question.  Of
+course when the command is subsequently executed, an
+.QW "invalid command"
+error will occur.
+.PP
+For \fBleave\fR and \fBleavestep\fR operations:
+.PP
+.CS
+\fIcommandPrefix command-string code result op\fR
+.CE
+.PP
+\fICommand-string\fR gives the complete current command being
+executed (the traced command for a \fBenter\fR operation, an
+arbitrary command for a \fBenterstep\fR operation), including
+all arguments in their fully expanded form.
+\fICode\fR gives the result code of that execution, and \fIresult\fR
+the result string.
+\fIOp\fR indicates what operation is being performed on the
+command execution, and is one of \fBleave\fR or \fBleavestep\fR as
+defined above.
+Note that the creation of many \fBenterstep\fR or
+\fBleavestep\fR traces can lead to unintuitive results, since the
+invoked commands from one trace can themselves lead to further
+command invocations for other traces.
+.PP
+\fICommandPrefix\fR executes in the same context as the code that invoked
+the traced operation: thus the \fIcommandPrefix\fR, if invoked from a
+procedure, will have access to the same local variables as code in the
+procedure. This context may be different than the context in which the trace
+was created. If \fIcommandPrefix\fR invokes a procedure (which it normally
+does) then the procedure will have to use \fBupvar\fR or \fBuplevel\fR
+commands if it wishes to access the local variables of the code which invoked
+the trace operation.
+.PP
+While \fIcommandPrefix\fR is executing during an execution trace, traces
+on \fIname\fR are temporarily disabled. This allows the \fIcommandPrefix\fR
+to execute \fIname\fR in its body without invoking any other traces again.
+If an error occurs while executing the \fIcommandPrefix\fR, then the
+command \fIname\fR as a whole will return that same error.
+.PP
+When multiple traces are set on \fIname\fR, then for \fIenter\fR
+and \fIenterstep\fR operations, the traced commands are invoked
+in the reverse order of how the traces were originally created;
+and for \fIleave\fR and \fIleavestep\fR operations, the traced
+commands are invoked in the original order of creation.
+.PP
+The behavior of execution traces is currently undefined for a command
+\fIname\fR imported into another namespace.
+.RE
+.TP
+\fBtrace add variable\fI name ops commandPrefix\fR
+Arrange for \fIcommandPrefix\fR to be executed whenever variable \fIname\fR
+is accessed in one of the ways given by the list \fIops\fR.  \fIName\fR may
+refer to a normal variable, an element of an array, or to an array
+as a whole (i.e. \fIname\fR may be just the name of an array, with no
+parenthesized index).  If \fIname\fR refers to a whole array, then
+\fIcommandPrefix\fR is invoked whenever any element of the array is
+manipulated.  If the variable does not exist, it will be created but
+will not be given a value, so it will be visible to \fBnamespace which\fR
+queries, but not to \fBinfo exists\fR queries.
+.RS
+.PP
+\fIOps\fR indicates which operations are of interest, and is a list of
+one or more of the following items:
+.TP
+\fBarray\fR
+Invoke \fIcommandPrefix\fR whenever the variable is accessed or modified via
+the \fBarray\fR command, provided that \fIname\fR is not a scalar
+variable at the time that the \fBarray\fR command is invoked.  If
+\fIname\fR is a scalar variable, the access via the \fBarray\fR
+command will not trigger the trace.
+.TP
+\fBread\fR
+Invoke \fIcommandPrefix\fR whenever the variable is read.
+.TP
+\fBwrite\fR
+Invoke \fIcommandPrefix\fR whenever the variable is written.
+.TP
+\fBunset\fR
+Invoke \fIcommandPrefix\fR whenever the variable is unset.  Variables
+can be unset explicitly with the \fBunset\fR command, or
+implicitly when procedures return (all of their local variables
+are unset).  Variables are also unset when interpreters are
+deleted, but traces will not be invoked because there is no
+interpreter in which to execute them.
+.PP
+When the trace triggers, three arguments are appended to
+\fIcommandPrefix\fR so that the actual command is as follows:
+.PP
+.CS
+\fIcommandPrefix name1 name2 op\fR
+.CE
+.PP
+\fIName1\fR and \fIname2\fR give the name(s) for the variable
+being accessed:  if the variable is a scalar then \fIname1\fR
+gives the variable's name and \fIname2\fR is an empty string;
+if the variable is an array element then \fIname1\fR gives the
+name of the array and name2 gives the index into the array;
+if an entire array is being deleted and the trace was registered
+on the overall array, rather than a single element, then \fIname1\fR
+gives the array name and \fIname2\fR is an empty string.
+\fIName1\fR and \fIname2\fR are not necessarily the same as the
+name used in the \fBtrace variable\fR command:  the \fBupvar\fR
+command allows a procedure to reference a variable under a
+different name.
+\fIOp\fR indicates what operation is being performed on the
+variable, and is one of \fBread\fR, \fBwrite\fR, or \fBunset\fR as
+defined above.
+.PP
+\fICommandPrefix\fR executes in the same context as the code that invoked
+the traced operation:  if the variable was accessed as part of a Tcl
+procedure, then \fIcommandPrefix\fR will have access to the same local
+variables as code in the procedure.  This context may be different
+than the context in which the trace was created. If \fIcommandPrefix\fR
+invokes a procedure (which it normally does) then the procedure will
+have to use \fBupvar\fR or \fBuplevel\fR if it wishes to access the
+traced variable.  Note also that \fIname1\fR may not necessarily be
+the same as the name used to set the trace on the variable;
+differences can occur if the access is made through a variable defined
+with the \fBupvar\fR command.
+.PP
+For read and write traces, \fIcommandPrefix\fR can modify the variable to
+affect the result of the traced operation.  If \fIcommandPrefix\fR modifies
+the value of a variable during a read or write trace, then the new
+value will be returned as the result of the traced operation.  The
+return value from  \fIcommandPrefix\fR is ignored except that if it returns
+an error of any sort then the traced operation also returns an error
+with the same error message returned by the trace command (this
+mechanism can be used to implement read-only variables, for example).
+For write traces, \fIcommandPrefix\fR is invoked after the variable's value
+has been changed; it can write a new value into the variable to
+override the original value specified in the write operation.  To
+implement read-only variables, \fIcommandPrefix\fR will have to restore the
+old value of the variable.
+.PP
+While \fIcommandPrefix\fR is executing during a read or write trace, traces
+on the variable are temporarily disabled.  This means that reads and
+writes invoked by \fIcommandPrefix\fR will occur directly, without invoking
+\fIcommandPrefix\fR (or any other traces) again.  However, if
+\fIcommandPrefix\fR unsets the variable then unset traces will be invoked.
+.PP
+When an unset trace is invoked, the variable has already been deleted:
+it will appear to be undefined with no traces.  If an unset occurs
+because of a procedure return, then the trace will be invoked in the
+variable context of the procedure being returned to:  the stack frame
+of the returning procedure will no longer exist.  Traces are not
+disabled during unset traces, so if an unset trace command creates a
+new trace and accesses the variable, the trace will be invoked.  Any
+errors in unset traces are ignored.
+.PP
+If there are multiple traces on a variable they are invoked in order
+of creation, most-recent first.  If one trace returns an error, then
+no further traces are invoked for the variable.  If an array element
+has a trace set, and there is also a trace set on the array as a
+whole, the trace on the overall array is invoked before the one on the
+element.
+.PP
+Once created, the trace remains in effect either until the trace is
+removed with the \fBtrace remove variable\fR command described below,
+until the variable is unset, or until the interpreter is deleted.
+Unsetting an element of array will remove any traces on that element,
+but will not remove traces on the overall array.
+.PP
+This command returns an empty string.
+.RE
+.RE
+.TP
+\fBtrace remove \fItype name opList commandPrefix\fR
+Where \fItype\fR is either \fBcommand\fR, \fBexecution\fR or \fBvariable\fR.
+.RS
+.TP
+\fBtrace remove command\fI name opList commandPrefix\fR
+If there is a trace set on command \fIname\fR with the operations and
+command given by \fIopList\fR and \fIcommandPrefix\fR, then the trace is
+removed, so that \fIcommandPrefix\fR will never again be invoked.  Returns
+an empty string.   If \fIname\fR does not exist, the command will throw
+an error.
+.TP
+\fBtrace remove execution\fI name opList commandPrefix\fR
+If there is a trace set on command \fIname\fR with the operations and
+command given by \fIopList\fR and \fIcommandPrefix\fR, then the trace is
+removed, so that \fIcommandPrefix\fR will never again be invoked.  Returns
+an empty string.   If \fIname\fR does not exist, the command will throw
+an error.
+.TP
+\fBtrace remove variable\fI name opList commandPrefix\fR
+If there is a trace set on variable \fIname\fR with the operations and
+command given by \fIopList\fR and \fIcommandPrefix\fR, then the trace is
+removed, so that \fIcommandPrefix\fR will never again be invoked.  Returns
+an empty string.
+.RE
+.TP
+\fBtrace info \fItype name\fR
+Where \fItype\fR is either \fBcommand\fR, \fBexecution\fR or \fBvariable\fR.
+.RS
+.TP
+\fBtrace info command\fI name\fR
+Returns a list containing one element for each trace currently set on
+command \fIname\fR. Each element of the list is itself a list
+containing two elements, which are the \fIopList\fR and \fIcommandPrefix\fR
+associated with the trace.  If \fIname\fR does not have any traces set,
+then the result of the command will be an empty string.  If \fIname\fR
+does not exist, the command will throw an error.
+.TP
+\fBtrace info execution\fI name\fR
+Returns a list containing one element for each trace currently set on
+command \fIname\fR. Each element of the list is itself a list
+containing two elements, which are the \fIopList\fR and \fIcommandPrefix\fR
+associated with the trace.  If \fIname\fR does not have any traces set,
+then the result of the command will be an empty string.  If \fIname\fR
+does not exist, the command will throw an error.
+.TP
+\fBtrace info variable\fI name\fR
+Returns a list containing one element for each trace currently set on
+variable \fIname\fR.  Each element of the list is itself a list
+containing two elements, which are the \fIopList\fR and \fIcommandPrefix\fR
+associated with the trace.  If \fIname\fR does not exist or does not
+have any traces set, then the result of the command will be an empty
+string.
+.RE
+.PP
+For backwards compatibility, three other subcommands are available:
+.RS
+.TP
+\fBtrace variable \fIname ops command\fR
+This is equivalent to \fBtrace add variable \fIname ops command\fR.
+.TP
+\fBtrace vdelete \fIname ops command\fR
+This is equivalent to \fBtrace remove variable \fIname ops command\fR
+.TP
+\fBtrace vinfo \fIname\fR
+This is equivalent to \fBtrace info variable \fIname\fR
+.RE
+.PP
+These subcommands are deprecated and will likely be removed in a
+future version of Tcl.  They use an older syntax in which \fBarray\fR,
+\fBread\fR, \fBwrite\fR, \fBunset\fR are replaced by \fBa\fR, \fBr\fR,
+\fBw\fR and \fBu\fR respectively, and the \fIops\fR argument is not a
+list, but simply a string concatenation of the operations, such as
+\fBrwua\fR.
+.SH EXAMPLES
+.PP
+Print a message whenever either of the global variables \fBfoo\fR and
+\fBbar\fR are updated, even if they have a different local name at the
+time (which can be done with the \fBupvar\fR command):
+.PP
+.CS
+proc tracer {varname args} {
+    upvar #0 $varname var
+    puts "$varname was updated to be \e"$var\e""
+}
+\fBtrace add\fR variable foo write "tracer foo"
+\fBtrace add\fR variable bar write "tracer bar"
+.CE
+.PP
+Ensure that the global variable \fBfoobar\fR always contains the
+product of the global variables \fBfoo\fR and \fBbar\fR:
+.PP
+.CS
+proc doMult args {
+    global foo bar foobar
+    set foobar [expr {$foo * $bar}]
+}
+\fBtrace add\fR variable foo write doMult
+\fBtrace add\fR variable bar write doMult
+.CE
+.PP
+Print a trace of what commands are executed during the processing of a Tcl
+procedure:
+.PP
+.CS
+proc x {} { y }
+proc y {} { z }
+proc z {} { puts hello }
+proc report args {puts [info level 0]}
+\fBtrace add\fR execution x enterstep report
+x
+  \(-> \fIreport y enterstep\fR
+    \fIreport z enterstep\fR
+    \fIreport {puts hello} enterstep\fR
+    \fIhello\fR
+.CE
+.SH "SEE ALSO"
+set(n), unset(n)
+.SH KEYWORDS
+read, command, rename, variable, write, trace, unset
+.\" Local Variables:
+.\" mode: nroff
+.\" End:
diff --git a/doc/transchan.n b/doc/transchan.n
new file mode 100644
index 0000000..4da74f2
--- /dev/null
+++ b/doc/transchan.n
@@ -0,0 +1,160 @@
+'\"
+'\" Copyright (c) 2008 Donal K. Fellows
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH transchan n 8.6 Tcl "Tcl Built-In Commands"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+transchan \- command handler API of channel transforms
+.SH SYNOPSIS
+\fBcmdPrefix \fIoption\fR ?\fIarg arg ...\fR?
+.BE
+.SH DESCRIPTION
+.PP
+The Tcl-level handler for a channel transformation has to be a command with
+subcommands (termed an \fIensemble\fR despite not implying that it must be
+created with \fBnamespace ensemble create\fR; this mechanism is not tied to
+\fBnamespace ensemble\fR in any way). Note that \fIcmdPrefix\fR is whatever
+was specified in the call to \fBchan push\fR, and may consist of multiple
+arguments; this will be expanded to multiple words in place of the prefix.
+.PP
+Of all the possible subcommands, the handler \fImust\fR support
+\fBinitialize\fR and \fBfinalize\fR. Transformations for writable channels
+must also support \fBwrite\fR, and transformations for readable channels must
+also support \fBread\fR.
+.PP
+Note that in the descriptions below \fIcmdPrefix\fR may be more than one word,
+and \fIhandle\fR is the value returned by the \fBchan push\fR call used to
+create the transformation.
+.SS "GENERIC SUBCOMMANDS"
+.PP
+The following subcommands are relevant to all types of channel.
+.TP
+\fIcmdPrefix \fBclear \fIhandle\fR
+.
+This optional subcommand is called to signify to the transformation that any
+data stored in internal buffers (either incoming or outgoing) must be
+cleared. It is called when a \fBchan seek\fR is performed on the channel being
+transformed.
+.TP
+\fIcmdPrefix \fBfinalize \fIhandle\fR
+.
+This mandatory subcommand is called last for the given \fIhandle\fR, and then
+never again, and it exists to allow for cleaning up any Tcl-level data
+structures associated with the transformation. \fIWarning!\fR Any errors
+thrown by this subcommand will be ignored. It is not guaranteed to be called
+if the interpreter is deleted.
+.TP
+\fIcmdPrefix \fBinitialize \fIhandle mode\fR
+.
+This mandatory subcommand is called first, and then never again (for the given
+\fIhandle\fR). Its responsibility is to initialize all parts of the
+transformation at the Tcl level. The \fImode\fR is a list containing any of
+\fBread \fRand \fBwrite\fR.
+.RS
+.TP
+\fBwrite\fR
+.
+implies that the channel is writable.
+.TP
+\fBread\fR
+.
+implies that the channel is readable.
+.PP
+The return value of the subcommand should be a list containing the names of
+all subcommands supported by this handler. Any error thrown by the subcommand
+will prevent the creation of the transformation. The thrown error will appear
+as error thrown by \fBchan push\fR.
+.RE
+.SS "READ-RELATED SUBCOMMANDS"
+.PP
+These subcommands are used for handling transformations applied to readable
+channels; though strictly \fBread \fRis optional, it must be supported if any
+of the others is or the channel will be made non-readable.
+.TP
+\fIcmdPrefix \fBdrain \fIhandle\fR
+.
+This optional subcommand is called whenever data in the transformation input
+(i.e. read) buffer has to be forced upward, i.e. towards the user or script.
+The result returned by the method is taken as the \fIbinary\fR data to push
+upward to the level above this transformation (the reader or a higher-level
+transformation).
+.RS
+.PP
+In other words, when this method is called the transformation cannot defer the
+actual transformation operation anymore and has to transform all data waiting
+in its internal read buffers and return the result of that action.
+.RE
+.TP
+\fIcmdPrefix \fBlimit? \fIhandle\fR
+.
+This optional subcommand is called to allow the Tcl I/O engine to determine
+how far ahead it should read. If present, it should return an integer number
+greater than zero which indicates how many bytes ahead should be read, or an
+integer less than zero to indicate that the I/O engine may read as far ahead
+as it likes.
+.TP
+\fIcmdPrefix \fBread \fIhandle buffer\fR
+.
+This subcommand, which must be present if the transformation is to work with
+readable channels, is called whenever the base channel, or a transformation
+below this transformation, pushes data upward. The \fIbuffer\fR contains the
+binary data which has been given to us from below. It is the responsibility of
+this subcommand to actually transform the data. The result returned by the
+subcommand is taken as the binary data to push further upward to the
+transformation above this transformation. This can also be the user or script
+that originally read from the channel.
+.RS
+.PP
+Note that the result is allowed to be empty, or even less than the data we
+received; the transformation is not required to transform everything given to
+it right now. It is allowed to store incoming data in internal buffers and to
+defer the actual transformation until it has more data.
+.RE
+.SS "WRITE-RELATED SUBCOMMANDS"
+.PP
+These subcommands are used for handling transformations applied to writable
+channels; though strictly \fBwrite\fR is optional, it must be supported if any
+of the others is or the channel will be made non-writable.
+.TP
+\fIcmdPrefix \fBflush \fIhandle\fR
+.
+This optional subcommand is called whenever data in the transformation 'write'
+buffer has to be forced downward, i.e. towards the base channel. The result
+returned by the subcommand is taken as the binary data to write to the
+transformation below the current transformation. This can be the base channel
+as well.
+.RS
+.PP
+In other words, when this subcommand is called the transformation cannot defer
+the actual transformation operation anymore and has to transform all data
+waiting in its internal write buffers and return the result of that action.
+.RE
+.TP
+\fIcmdPrefix \fBwrite \fIhandle buffer\fR
+.
+This subcommand, which must be present if the transformation is to work with
+writable channels, is called whenever the user, or a transformation above this
+transformation, writes data downward. The \fIbuffer\fR contains the binary
+data which has been written to us. It is the responsibility of this subcommand
+to actually transform the data.
+.RS
+.PP
+The result returned by the subcommand is taken as the binary data to write to
+the transformation below this transformation. This can be the base channel as
+well. Note that the result is allowed to be empty, or less than the data we
+got; the transformation is not required to transform everything which was
+written to it right now. It is allowed to store this data in internal buffers
+and to defer the actual transformation until it has more data.
+.RE
+.SH "SEE ALSO"
+chan(n), refchan(n)
+.SH KEYWORDS
+API, channel, ensemble, prefix, transformation
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/doc/try.n b/doc/try.n
new file mode 100644
index 0000000..eae4dc7
--- /dev/null
+++ b/doc/try.n
@@ -0,0 +1,103 @@
+'\"
+'\" Copyright (c) 2008 Donal K. Fellows
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH try n 8.6 Tcl "Tcl Built-In Commands"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+try \- Trap and process errors and exceptions
+.SH SYNOPSIS
+\fBtry\fI body\fR ?\fIhandler...\fR? ?\fBfinally\fI script\fR?
+.BE
+.SH DESCRIPTION
+.PP
+This command executes the script \fIbody\fR and, depending on what the outcome
+of that script is (normal exit, error, or some other exceptional result), runs
+a handler script to deal with the case. Once that has all happened, if the
+\fBfinally\fR clause is present, the \fIscript\fR it includes will be run and
+the result of the handler (or the \fIbody\fR if no handler matched) is allowed
+to continue to propagate. Note that the \fBfinally\fR clause is processed even
+if an error occurs and irrespective of which, if any, \fIhandler\fR is used.
+.PP
+The \fIhandler\fR clauses are each expressed as several words, and must have
+one of the following forms:
+.TP
+\fBon \fIcode variableList script\fR
+.
+This clause matches if the evaluation of \fIbody\fR completed with the
+exception code \fIcode\fR. The \fIcode\fR may be expressed as an integer or
+one of the following literal words: \fBok\fR, \fBerror\fR, \fBreturn\fR,
+\fBbreak\fR, or \fBcontinue\fR. Those literals correspond to the integers 0
+through 4 respectively.
+.TP
+\fBtrap \fIpattern variableList script\fR
+.
+This clause matches if the evaluation of \fIbody\fR resulted in an error and
+the prefix of the \fB\-errorcode\fR from the interpreter's status dictionary
+is equal to the \fIpattern\fR. The number of prefix words taken from the
+\fB\-errorcode\fR is equal to the list-length of \fIpattern\fR, and inter-word
+spaces are normalized in both the \fB\-errorcode\fR and \fIpattern\fR before
+comparison.
+.PP
+The \fIvariableList\fR word in each \fIhandler\fR is always interpreted as a
+list of variable names. If the first word of the list is present and
+non-empty, it names a variable into which the result of the evaluation of
+\fIbody\fR (from the main \fBtry\fR) will be placed; this will contain the
+human-readable form of any errors. If the second word of the list is present
+and non-empty, it names a variable into which the options dictionary of the
+interpreter at the moment of completion of execution of \fIbody\fR
+will be placed.
+.PP
+The \fIscript\fR word of each \fIhandler\fR is also always interpreted the
+same: as a Tcl script to evaluate if the clause is matched. If \fIscript\fR is
+a literal
+.QW \-
+and the \fIhandler\fR is not the last one, the \fIscript\fR of the following
+\fIhandler\fR is invoked instead (just like with the \fBswitch\fR command).
+.PP
+Note that \fIhandler\fR clauses are matched against in order, and that the
+first matching one is always selected. At most one \fIhandler\fR clause will
+selected. As a consequence, an \fBon error\fR will mask any subsequent
+\fBtrap\fR in the \fBtry\fR. Also note that \fBon error\fR is equivalent to
+\fBtrap {}\fR.
+.PP
+If an exception (i.e. any non-\fBok\fR result) occurs during the evaluation of
+either the \fIhandler\fR or the \fBfinally\fR clause, the original exception's
+status dictionary will be added to the new exception's status dictionary under
+the \fB\-during\fR key.
+.SH EXAMPLES
+.PP
+Ensure that a file is closed no matter what:
+.PP
+.CS
+set f [open /some/file/name a]
+\fBtry\fR {
+    puts $f "some message"
+    # ...
+} \fBfinally\fR {
+    close $f
+}
+.CE
+.PP
+Handle different reasons for a file to not be openable for reading:
+.PP
+.CS
+\fBtry\fR {
+    set f [open /some/file/name w]
+} \fBtrap\fR {POSIX EISDIR} {} {
+    puts "failed to open /some/file/name: it's a directory"
+} \fBtrap\fR {POSIX ENOENT} {} {
+    puts "failed to open /some/file/name: it doesn't exist"
+}
+.CE
+.SH "SEE ALSO"
+catch(n), error(n), return(n), throw(n)
+.SH "KEYWORDS"
+cleanup, error, exception, final, resource management
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/doc/unknown.n b/doc/unknown.n
new file mode 100644
index 0000000..82dcefc
--- /dev/null
+++ b/doc/unknown.n
@@ -0,0 +1,91 @@
+'\"
+'\" Copyright (c) 1993 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH unknown n "" Tcl "Tcl Built-In Commands"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+unknown \- Handle attempts to use non-existent commands
+.SH SYNOPSIS
+\fBunknown \fIcmdName \fR?\fIarg arg ...\fR?
+.BE
+.SH DESCRIPTION
+.PP
+This command is invoked by the Tcl interpreter whenever a script
+tries to invoke a command that does not exist.  The default implementation
+of \fBunknown\fR is a library procedure defined when Tcl initializes an
+interpreter.  You can override the default \fBunknown\fR to change its
+functionality, or you can register a new handler for individual namespaces
+using the \fBnamespace unknown\fR command.  Note that there is no default
+implementation of \fBunknown\fR in a safe interpreter.
+.PP
+If the Tcl interpreter encounters a command name for which there
+is not a defined command (in either the current namespace, or the
+global namespace), then Tcl checks for the existence of
+an unknown handler for the current namespace. By default, this
+handler is a command named \fB::unknown\fR.  If there is no such
+command, then the interpreter returns an error.
+If the \fBunknown\fR command exists (or a new handler has been
+registered for the current namespace), then it is invoked with
+arguments consisting of the fully-substituted name and arguments
+for the original non-existent command.
+The \fBunknown\fR command typically does things like searching
+through library directories for a command procedure with the name
+\fIcmdName\fR, or expanding abbreviated command names to full-length,
+or automatically executing unknown commands as sub-processes.
+In some cases (such as expanding abbreviations) \fBunknown\fR will
+change the original command slightly and then (re-)execute it.
+The result of the \fBunknown\fR command is used as the result for
+the original non-existent command.
+.PP
+The default implementation of \fBunknown\fR behaves as follows.
+It first calls the \fBauto_load\fR library procedure to load the command.
+If this succeeds, then it executes the original command with its
+original arguments.
+If the auto-load fails then \fBunknown\fR calls \fBauto_execok\fR
+to see if there is an executable file by the name \fIcmd\fR.
+If so, it invokes the Tcl \fBexec\fR command
+with \fIcmd\fR and all the \fIargs\fR as arguments.
+If \fIcmd\fR cannot be auto-executed, \fBunknown\fR checks to
+see if the command was invoked at top-level and outside of any
+script.  If so, then \fBunknown\fR takes two additional steps.
+First, it sees if \fIcmd\fR has one of the following three forms:
+\fB!!\fR, \fB!\fIevent\fR, or \fB^\fIold\fB^\fInew\fR?\fB^\fR?.
+If so, then \fBunknown\fR carries out history substitution
+in the same way that \fBcsh\fR would for these constructs.
+Finally, \fBunknown\fR checks to see if \fIcmd\fR is
+a unique abbreviation for an existing Tcl command.
+If so, it expands the command name and executes the command with
+the original arguments.
+If none of the above efforts has been able to execute
+the command, \fBunknown\fR generates an error return.
+If the global variable \fBauto_noload\fR is defined, then the auto-load
+step is skipped.
+If the global variable \fBauto_noexec\fR is defined then the
+auto-exec step is skipped.
+Under normal circumstances the return value from \fBunknown\fR
+is the return value from the command that was eventually
+executed.
+.SH EXAMPLE
+Arrange for the \fBunknown\fR command to have its standard behavior
+except for first logging the fact that a command was not found:
+.PP
+.CS
+# Save the original one so we can chain to it
+rename \fBunknown\fR _original_unknown
+
+# Provide our own implementation
+proc \fBunknown\fR args {
+    puts stderr "WARNING: unknown command: $args"
+    uplevel 1 [list _original_unknown {*}$args]
+}
+.CE
+.SH "SEE ALSO"
+info(n), proc(n), interp(n), library(n), namespace(n)
+.SH KEYWORDS
+error, non-existent command, unknown
diff --git a/doc/unload.n b/doc/unload.n
new file mode 100644
index 0000000..0a8e99b
--- /dev/null
+++ b/doc/unload.n
@@ -0,0 +1,172 @@
+'\"
+'\" Copyright (c) 2003 George Petasis <petasis@iit.demokritos.gr>.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH unload n 8.5 Tcl "Tcl Built-In Commands"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+unload \- Unload machine code
+.SH SYNOPSIS
+\fBunload \fR?\fIswitches\fR? \fIfileName\fR
+.br
+\fBunload \fR?\fIswitches\fR? \fIfileName packageName\fR
+.br
+\fBunload \fR?\fIswitches\fR? \fIfileName packageName interp\fR
+.BE
+.SH DESCRIPTION
+.PP
+This command tries to unload shared libraries previously loaded
+with \fBload\fR from the application's address space.  \fIfileName\fR
+is the name of the file containing the library file to be unload;  it
+must be the same as the filename provided to \fBload\fR for
+loading the library.
+The \fIpackageName\fR argument is the name of the package (as
+determined by or passed to \fBload\fR), and is used to
+compute the name of the unload procedure; if not supplied, it is
+computed from \fIfileName\fR in the same manner as \fBload\fR.
+The \fIinterp\fR argument is the path name of the interpreter from
+which to unload the package (see the \fBinterp\fR manual entry for
+details); if \fIinterp\fR is omitted, it defaults to the
+interpreter in which the \fBunload\fR command was invoked.
+.PP
+If the initial arguments to \fBunload\fR start with \fB\-\fR then
+they are treated as switches.  The following switches are
+currently supported:
+.TP
+\fB\-nocomplain\fR
+.
+Suppresses all error messages. If this switch is given, \fBunload\fR will
+never report an error.
+.TP
+\fB\-keeplibrary\fR
+.
+This switch will prevent \fBunload\fR from issuing the operating system call
+that will unload the library from the process.
+.TP
+\fB\-\|\-\fR
+.
+Marks the end of switches.  The argument following this one will
+be treated as a \fIfileName\fR even if it starts with a \fB\-\fR.
+.SS "UNLOAD OPERATION"
+.PP
+When a file containing a shared library is loaded through the
+\fBload\fR command, Tcl associates two reference counts to the library
+file. The first counter shows how many times the library has been
+loaded into normal (trusted) interpreters while the second describes how many
+times the library has been loaded into safe interpreters. As a file containing
+a shared library can be loaded only once by Tcl (with the first \fBload\fR
+call on the file), these counters track how many interpreters use the library.
+Each subsequent call to \fBload\fR after the first simply increments the
+proper reference count.
+.PP
+\fBunload\fR works in the opposite direction. As a first step, \fBunload\fR
+will check whether the library is unloadable: an unloadable library exports
+a special unload procedure. The name of the unload procedure is determined by
+\fIpackageName\fR and whether or not the target interpreter
+is a safe one.  For normal interpreters the name of the initialization
+procedure will have the form \fIpkg\fB_Unload\fR, where \fIpkg\fR
+is the same as \fIpackageName\fR except that the first letter is
+converted to upper case and all other letters
+are converted to lower case.  For example, if \fIpackageName\fR is
+\fBfoo\fR or \fBFOo\fR, the initialization procedure's name will
+be \fBFoo_Unload\fR.
+If the target interpreter is a safe interpreter, then the name
+of the initialization procedure will be \fIpkg\fB_SafeUnload\fR
+instead of \fIpkg\fB_Unload\fR.
+.PP
+If \fBunload\fR determines that a library is not unloadable (or unload
+functionality has been disabled during compilation), an error will be returned.
+If the library is unloadable, then \fBunload\fR will call the unload
+procedure. If the unload procedure returns \fBTCL_OK\fR, \fBunload\fR will proceed
+and decrease the proper reference count (depending on the target interpreter
+type). When both reference counts have reached 0, the library will be
+detached from the process.
+.SS "UNLOAD HOOK PROTOTYPE"
+.PP
+The unload procedure must match the following prototype:
+.PP
+.CS
+typedef int \fBTcl_PackageUnloadProc\fR(
+        Tcl_Interp *\fIinterp\fR,
+        int \fIflags\fR);
+.CE
+.PP
+The \fIinterp\fR argument identifies the interpreter from which the
+library is to be unloaded.  The unload procedure must return
+\fBTCL_OK\fR or \fBTCL_ERROR\fR to indicate whether or not it completed
+successfully;  in the event of an error it should set the interpreter's result
+to point to an error message.  In this case, the result of the
+\fBunload\fR command will be the result returned by the unload procedure.
+.PP
+The \fIflags\fR argument can be either \fBTCL_UNLOAD_DETACH_FROM_INTERPRETER\fR
+or \fBTCL_UNLOAD_DETACH_FROM_PROCESS\fR. In case the library will remain
+attached to the process after the unload procedure returns (i.e. because
+the library is used by other interpreters),
+\fBTCL_UNLOAD_DETACH_FROM_INTERPRETER\fR will be defined. However, if the
+library is used only by the target interpreter and the library will be
+detached from the application as soon as the unload procedure returns,
+the \fIflags\fR argument will be set to \fBTCL_UNLOAD_DETACH_FROM_PROCESS\fR.
+.SS NOTES
+.PP
+The \fBunload\fR command cannot unload libraries that are statically
+linked with the application.
+If \fIfileName\fR is an empty string, then the \fIpackageName\fR argument must
+be specified.
+.PP
+If \fIpackageName\fR is omitted or specified as an empty string,
+Tcl tries to guess the name of the package.
+This may be done differently on different platforms.
+The default guess, which is used on most UNIX platforms, is to
+take the last element of \fIfileName\fR, strip off the first
+three characters if they are \fBlib\fR, and use any following
+alphabetic and underline characters as the module name.
+For example, the command \fBunload libxyz4.2.so\fR uses the module
+name \fBxyz\fR and the command \fBunload bin/last.so {}\fR uses the
+module name \fBlast\fR.
+.SH "PORTABILITY ISSUES"
+.TP
+\fBUnix\fR\0\0\0\0\0
+.
+Not all unix operating systems support library unloading. Under such
+an operating system \fBunload\fR returns an error (unless \fB\-nocomplain\fR
+has been specified).
+.SH BUGS
+.PP
+If the same file is \fBload\fRed by different \fIfileName\fRs, it will
+be loaded into the process's address space multiple times.  The
+behavior of this varies from system to system (some systems may
+detect the redundant loads, others may not). In case a library has been
+silently detached by the operating system (and as a result Tcl thinks the
+library is still loaded), it may be dangerous to use
+\fBunload\fR on such a library (as the library will be completely detached
+from the application while some interpreters will continue to use it).
+.SH EXAMPLE
+.PP
+If an unloadable module in the file \fBfoobar.dll\fR had been loaded
+using the \fBload\fR command like this (on Windows):
+.PP
+.CS
+load c:/some/dir/foobar.dll
+.CE
+.PP
+then it would be unloaded like this:
+.PP
+.CS
+\fBunload\fR c:/some/dir/foobar.dll
+.CE
+.PP
+This allows a C code module to be installed temporarily into a
+long-running Tcl program and then removed again (either because it is
+no longer needed or because it is being updated with a new version)
+without having to shut down the overall Tcl process.
+.SH "SEE ALSO"
+info sharedlibextension, load(n), safe(n)
+.SH KEYWORDS
+binary code, unloading, safe interpreter, shared library
+.\" Local Variables:
+.\" mode: nroff
+.\" End:
diff --git a/doc/unset.n b/doc/unset.n
new file mode 100644
index 0000000..2cfc63e
--- /dev/null
+++ b/doc/unset.n
@@ -0,0 +1,68 @@
+'\"
+'\" Copyright (c) 1993 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\" Copyright (c) 2000 Ajuba Solutions.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH unset n 8.4 Tcl "Tcl Built-In Commands"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+unset \- Delete variables
+.SH SYNOPSIS
+\fBunset \fR?\fB\-nocomplain\fR? ?\fB\-\-\fR? ?\fIname name name ...\fR?
+.BE
+.SH DESCRIPTION
+.PP
+This command removes one or more variables.
+Each \fIname\fR is a variable name, specified in any of the
+ways acceptable to the \fBset\fR command.
+If a \fIname\fR refers to an element of an array then that
+element is removed without affecting the rest of the array.
+If a \fIname\fR consists of an array name with no parenthesized
+index, then the entire array is deleted.
+The \fBunset\fR command returns an empty string as result.
+If \fB\-nocomplain\fR is specified as the first argument, any possible
+errors are suppressed.  The option may not be abbreviated, in order to
+disambiguate it from possible variable names.  The option \fB\-\-\fR
+indicates the end of the options, and should be used if you wish to
+remove a variable with the same name as any of the options.
+If an error occurs during variable deletion, any variables after the named one
+causing the error are not
+deleted.  An error can occur when the named variable does not exist, or the
+name refers to an array element but the variable is a scalar, or the name
+refers to a variable in a non-existent namespace.
+.SH EXAMPLE
+.PP
+Create an array containing a mapping from some numbers to their
+squares and remove the array elements for non-prime numbers:
+.PP
+.CS
+array set squares {
+    1 1    6 36
+    2 4    7 49
+    3 9    8 64
+    4 16   9 81
+    5 25  10 100
+}
+
+puts "The squares are:"
+parray squares
+
+\fBunset\fR squares(1) squares(4) squares(6)
+\fBunset\fR squares(8) squares(9) squares(10)
+
+puts "The prime squares are:"
+parray squares
+.CE
+.SH "SEE ALSO"
+set(n), trace(n), upvar(n)
+.SH KEYWORDS
+remove, variable
+'\" Local Variables:
+'\" mode: nroff
+'\" fill-column: 78
+'\" End:
diff --git a/doc/update.n b/doc/update.n
new file mode 100644
index 0000000..ce0fb25
--- /dev/null
+++ b/doc/update.n
@@ -0,0 +1,65 @@
+'\"
+'\" Copyright (c) 1990-1992 The Regents of the University of California.
+'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH update n 7.5 Tcl "Tcl Built-In Commands"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+update \- Process pending events and idle callbacks
+.SH SYNOPSIS
+\fBupdate\fR ?\fBidletasks\fR?
+.BE
+.SH DESCRIPTION
+.PP
+This command is used to bring the application
+.QW "up to date"
+by entering the event loop repeatedly until all pending events
+(including idle callbacks) have been processed.
+.PP
+If the \fBidletasks\fR keyword is specified as an argument to the
+command, then no new events or errors are processed;  only idle
+callbacks are invoked.
+This causes operations that are normally deferred, such as display
+updates and window layout calculations, to be performed immediately.
+.PP
+The \fBupdate idletasks\fR command is useful in scripts where
+changes have been made to the application's state and you want those
+changes to appear on the display immediately, rather than waiting
+for the script to complete.  Most display updates are performed as
+idle callbacks, so \fBupdate idletasks\fR will cause them to run.
+However, there are some kinds of updates that only happen in
+response to events, such as those triggered by window size changes;
+these updates will not occur in \fBupdate idletasks\fR.
+.PP
+The \fBupdate\fR command with no options is useful in scripts where
+you are performing a long-running computation but you still want
+the application to respond to events such as user interactions;  if
+you occasionally call \fBupdate\fR then user input will be processed
+during the next call to \fBupdate\fR.
+.SH EXAMPLE
+.PP
+Run computations for about a second and then finish:
+.PP
+.CS
+set x 1000
+set done 0
+after 1000 set done 1
+while {!$done} {
+    # A very silly example!
+    set x [expr {log($x) ** 2.8}]
+
+    # Test to see if our time-limit has been hit.  This would
+    # also give a chance for serving network sockets and, if
+    # the Tk package is loaded, updating a user interface.
+    \fBupdate\fR
+}
+.CE
+.SH "SEE ALSO"
+after(n), interp(n)
+.SH KEYWORDS
+asynchronous I/O, event, flush, handler, idle, update
diff --git a/doc/uplevel.n b/doc/uplevel.n
new file mode 100644
index 0000000..4decc6d
--- /dev/null
+++ b/doc/uplevel.n
@@ -0,0 +1,103 @@
+'\"
+'\" Copyright (c) 1993 The Regents of the University of California.
+'\" Copyright (c) 1994-1997 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH uplevel n "" Tcl "Tcl Built-In Commands"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+uplevel \- Execute a script in a different stack frame
+.SH SYNOPSIS
+\fBuplevel \fR?\fIlevel\fR?\fI arg \fR?\fIarg ...\fR?
+.BE
+.SH DESCRIPTION
+.PP
+All of the \fIarg\fR arguments are concatenated as if they had
+been passed to \fBconcat\fR; the result is then evaluated in the
+variable context indicated by \fIlevel\fR.  \fBUplevel\fR returns
+the result of that evaluation.
+.PP
+If \fIlevel\fR is an integer then
+it gives a distance (up the procedure calling stack) to move before
+executing the command.  If \fIlevel\fR consists of \fB#\fR followed by
+a number then the number gives an absolute level number.  If \fIlevel\fR
+is omitted then it defaults to \fB1\fR.  \fILevel\fR cannot be
+defaulted if the first \fIcommand\fR argument starts with a digit or \fB#\fR.
+.PP
+For example, suppose that procedure \fBa\fR was invoked
+from top-level, and that it called \fBb\fR, and that \fBb\fR called \fBc\fR.
+Suppose that \fBc\fR invokes the \fBuplevel\fR command.  If \fIlevel\fR
+is \fB1\fR or \fB#2\fR  or omitted, then the command will be executed
+in the variable context of \fBb\fR.  If \fIlevel\fR is \fB2\fR or \fB#1\fR
+then the command will be executed in the variable context of \fBa\fR.
+If \fIlevel\fR is \fB3\fR or \fB#0\fR then the command will be executed
+at top-level (only global variables will be visible).
+.PP
+The \fBuplevel\fR command causes the invoking procedure to disappear
+from the procedure calling stack while the command is being executed.
+In the above example, suppose \fBc\fR invokes the command
+.PP
+.CS
+\fBuplevel\fR 1 {set x 43; d}
+.CE
+.PP
+where \fBd\fR is another Tcl procedure.  The \fBset\fR command will
+modify the variable \fBx\fR in \fBb\fR's context, and \fBd\fR will execute
+at level 3, as if called from \fBb\fR.  If it in turn executes
+the command
+.PP
+.CS
+\fBuplevel\fR {set x 42}
+.CE
+.PP
+then the \fBset\fR command will modify the same variable \fBx\fR in \fBb\fR's
+context:  the procedure \fBc\fR does not appear to be on the call stack
+when \fBd\fR is executing.  The \fBinfo level\fR command may
+be used to obtain the level of the current procedure.
+.PP
+\fBUplevel\fR makes it possible to implement new control
+constructs as Tcl procedures (for example, \fBuplevel\fR could
+be used to implement the \fBwhile\fR construct as a Tcl procedure).
+.PP
+The \fBnamespace eval\fR and \fBapply\fR commands offer other ways
+(besides procedure calls) that the Tcl naming context can change.
+They add a call frame to the stack to represent the namespace context.
+This means each \fBnamespace eval\fR command
+counts as another call level for \fBuplevel\fR and \fBupvar\fR commands.
+For example, \fBinfo level 1\fR will return a list
+describing a command that is either
+the outermost procedure call or the outermost \fBnamespace eval\fR command.
+Also, \fBuplevel #0\fR evaluates a script
+at top-level in the outermost namespace (the global namespace).
+.SH EXAMPLE
+As stated above, the \fBuplevel\fR command is useful for creating new
+control constructs.  This example shows how (without error handling)
+it can be used to create a \fBdo\fR command that is the counterpart of
+\fBwhile\fR except for always performing the test after running the
+loop body:
+.PP
+.CS
+proc do {body while condition} {
+    if {$while ne "while"} {
+        error "required word missing"
+    }
+    set conditionCmd [list expr $condition]
+    while {1} {
+        \fBuplevel\fR 1 $body
+        if {![\fBuplevel\fR 1 $conditionCmd]} {
+            break
+        }
+    }
+}
+.CE
+.SH "SEE ALSO"
+apply(n), namespace(n), upvar(n)
+.SH KEYWORDS
+context, level, namespace, stack frame, variable
+.\" Local Variables:
+.\" mode: nroff
+.\" End:
diff --git a/doc/upvar.n b/doc/upvar.n
new file mode 100644
index 0000000..91defe6
--- /dev/null
+++ b/doc/upvar.n
@@ -0,0 +1,122 @@
+'\"
+'\" Copyright (c) 1993 The Regents of the University of California.
+'\" Copyright (c) 1994-1997 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH upvar n "" Tcl "Tcl Built-In Commands"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+upvar \- Create link to variable in a different stack frame
+.SH SYNOPSIS
+\fBupvar \fR?\fIlevel\fR? \fIotherVar myVar \fR?\fIotherVar myVar \fR...?
+.BE
+
+.SH DESCRIPTION
+.PP
+This command arranges for one or more local variables in the current
+procedure to refer to variables in an enclosing procedure call or
+to global variables.
+\fILevel\fR may have any of the forms permitted for the \fBuplevel\fR
+command, and may be omitted (it defaults to \fB1\fR).
+For each \fIotherVar\fR argument, \fBupvar\fR makes the variable
+by that name in the procedure frame given by \fIlevel\fR (or at
+global level, if \fIlevel\fR is \fB#0\fR) accessible
+in the current procedure by the name given in the corresponding
+\fImyVar\fR argument.
+The variable named by \fIotherVar\fR need not exist at the time of the
+call;  it will be created the first time \fImyVar\fR is referenced, just like
+an ordinary variable.  There must not exist a variable by the
+name \fImyVar\fR at the time \fBupvar\fR is invoked.
+\fIMyVar\fR is always treated as the name of a variable, not an
+array element.  An error is returned if the name looks like an array element,
+such as \fBa(b)\fR.
+\fIOtherVar\fR may refer to a scalar variable, an array,
+or an array element.
+\fBUpvar\fR returns an empty string.
+.PP
+The \fBupvar\fR command simplifies the implementation of call-by-name
+procedure calling and also makes it easier to build new control constructs
+as Tcl procedures.
+For example, consider the following procedure:
+.PP
+.CS
+proc \fIadd2\fR name {
+    \fBupvar\fR $name x
+    set x [expr {$x + 2}]
+}
+.CE
+.PP
+If \fIadd2\fR is invoked with an argument giving the name of a variable,
+it adds two to the value of that variable.
+Although \fIadd2\fR could have been implemented using \fBuplevel\fR
+instead of \fBupvar\fR, \fBupvar\fR makes it simpler for \fIadd2\fR
+to access the variable in the caller's procedure frame.
+.PP
+\fBnamespace eval\fR is another way (besides procedure calls)
+that the Tcl naming context can change.
+It adds a call frame to the stack to represent the namespace context.
+This means each \fBnamespace eval\fR command
+counts as another call level for \fBuplevel\fR and \fBupvar\fR commands.
+For example, \fBinfo level\fR \fB1\fR will return a list
+describing a command that is either
+the outermost procedure call or the outermost \fBnamespace eval\fR command.
+Also, \fBuplevel #0\fR evaluates a script
+at top-level in the outermost namespace (the global namespace).
+.PP
+If an upvar variable is unset (e.g. \fBx\fR in \fBadd2\fR above), the
+\fBunset\fR operation affects the variable it is linked to, not the
+upvar variable.  There is no way to unset an upvar variable except
+by exiting the procedure in which it is defined.  However, it is
+possible to retarget an upvar variable by executing another \fBupvar\fR
+command.
+.SH "TRACES AND UPVAR"
+.PP
+Upvar interacts with traces in a straightforward but possibly
+unexpected manner.  If a variable trace is defined on \fIotherVar\fR, that
+trace will be triggered by actions involving \fImyVar\fR.  However,
+the trace procedure will be passed the name of \fImyVar\fR, rather
+than the name of \fIotherVar\fR.  Thus, the output of the following code
+will be
+.QW "\fIlocalVar\fR"
+rather than
+.QW "\fIoriginalVar\fR" :
+.PP
+.CS
+proc \fItraceproc\fR { name index op } {
+    puts $name
+}
+proc \fIsetByUpvar\fR { name value } {
+    \fBupvar\fR $name localVar
+    set localVar $value
+}
+set originalVar 1
+trace variable originalVar w \fItraceproc\fR
+\fIsetByUpvar\fR originalVar 2
+.CE
+.PP
+If \fIotherVar\fR refers to an element of an array, then variable
+traces set for the entire array will not be invoked when \fImyVar\fR
+is accessed (but traces on the particular element will still be
+invoked).  In particular, if the array is \fBenv\fR, then changes
+made to \fImyVar\fR will not be passed to subprocesses correctly.
+.SH EXAMPLE
+A \fBdecr\fR command that works like \fBincr\fR except it subtracts
+the value from the variable instead of adding it:
+.PP
+.CS
+proc decr {varName {decrement 1}} {
+    \fBupvar\fR 1 $varName var
+    incr var [expr {-$decrement}]
+}
+.CE
+.SH "SEE ALSO"
+global(n), namespace(n), uplevel(n), variable(n)
+.SH KEYWORDS
+context, frame, global, level, namespace, procedure, upvar, variable
+.\" Local Variables:
+.\" mode: nroff
+.\" End:
diff --git a/doc/variable.n b/doc/variable.n
new file mode 100644
index 0000000..a6e545f
--- /dev/null
+++ b/doc/variable.n
@@ -0,0 +1,100 @@
+'\"
+'\" Copyright (c) 1993-1997 Bell Labs Innovations for Lucent Technologies
+'\" Copyright (c) 1997 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH variable n 8.0 Tcl "Tcl Built-In Commands"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+variable \- create and initialize a namespace variable
+.SH SYNOPSIS
+\fBvariable \fR\fIname\fR
+.sp
+\fBvariable \fR?\fIname value...\fR?
+.BE
+.SH DESCRIPTION
+.PP
+This command is normally used within a
+\fBnamespace eval\fR command to create one or more variables
+within a namespace.
+Each variable \fIname\fR is initialized with \fIvalue\fR.
+The \fIvalue\fR for the last variable is optional.
+.PP
+If a variable \fIname\fR does not exist, it is created.
+In this case, if \fIvalue\fR is specified,
+it is assigned to the newly created variable.
+If no \fIvalue\fR is specified, the new variable is left undefined.
+If the variable already exists,
+it is set to \fIvalue\fR if \fIvalue\fR is specified
+or left unchanged if no \fIvalue\fR is given.
+Normally, \fIname\fR is unqualified
+(does not include the names of any containing namespaces),
+and the variable is created in the current namespace.
+If \fIname\fR includes any namespace qualifiers,
+the variable is created in the specified namespace.  If the variable
+is not defined, it will be visible to the \fBnamespace which\fR
+command, but not to the \fBinfo exists\fR command.
+.PP
+If the \fBvariable\fR command is executed inside a Tcl procedure,
+it creates local variables
+linked to the corresponding namespace variables (and therefore these
+variables are listed by \fBinfo vars\fR.)
+In this way the \fBvariable\fR command resembles the \fBglobal\fR command,
+although the \fBglobal\fR command
+only links to variables in the global namespace.
+If any \fIvalue\fRs are given,
+they are used to modify the values of the associated namespace variables.
+If a namespace variable does not exist,
+it is created and optionally initialized.
+.PP
+A \fIname\fR argument cannot reference an element within an array.
+Instead, \fIname\fR should reference the entire array,
+and the initialization \fIvalue\fR should be left off.
+After the variable has been declared,
+elements within the array can be set using ordinary
+\fBset\fR or \fBarray\fR commands.
+.SH EXAMPLES
+.PP
+Create a variable in a namespace:
+.PP
+.CS
+namespace eval foo {
+    \fBvariable\fR bar 12345
+}
+.CE
+.PP
+Create an array in a namespace:
+.PP
+.CS
+namespace eval someNS {
+    \fBvariable\fR someAry
+    array set someAry {
+        someName  someValue
+        otherName otherValue
+    }
+}
+.CE
+.PP
+Access variables in namespaces from a procedure:
+.PP
+.CS
+namespace eval foo {
+    proc spong {} {
+        # Variable in this namespace
+        \fBvariable\fR bar
+        puts "bar is $bar"
+
+        # Variable in another namespace
+        \fBvariable\fR ::someNS::someAry
+        parray someAry
+    }
+}
+.CE
+.SH "SEE ALSO"
+global(n), namespace(n), upvar(n)
+.SH KEYWORDS
+global, namespace, procedure, variable
diff --git a/doc/vwait.n b/doc/vwait.n
new file mode 100644
index 0000000..f64d39c
--- /dev/null
+++ b/doc/vwait.n
@@ -0,0 +1,246 @@
+'\"
+'\" Copyright (c) 1995-1996 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH vwait n 8.0 Tcl "Tcl Built-In Commands"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+vwait \- Process events until a variable is written
+.SH SYNOPSIS
+\fBvwait\fR \fIvarName\fR
+.BE
+.SH DESCRIPTION
+.PP
+This command enters the Tcl event loop to process events, blocking
+the application if no events are ready.  It continues processing
+events until some event handler sets the value of the global variable
+\fIvarName\fR.  Once \fIvarName\fR has been set, the \fBvwait\fR
+command will return as soon as the event handler that modified
+\fIvarName\fR completes.  The \fIvarName\fR argument is always interpreted as
+a variable name with respect to the global namespace, but can refer to any
+namespace's variables if the fully-qualified name is given.
+.PP
+In some cases the \fBvwait\fR command may not return immediately
+after \fIvarName\fR is set.  This happens if the event handler
+that sets \fIvarName\fR does not complete immediately.  For example,
+if an event handler sets \fIvarName\fR and then itself calls
+\fBvwait\fR to wait for a different variable, then it may not return
+for a long time.  During this time the top-level \fBvwait\fR is
+blocked waiting for the event handler to complete, so it cannot
+return either. (See the \fBNESTED VWAITS BY EXAMPLE\fR below.)
+.PP
+To be clear, \fImultiple \fBvwait\fI calls will nest and will not happen in
+parallel\fR.  The outermost call to \fBvwait\fR will not return until all the
+inner ones do.  It is recommended that code should never nest \fBvwait\fR
+calls (by avoiding putting them in event callbacks) but when that is not
+possible, care should be taken to add interlock variables to the code to
+prevent all reentrant calls to \fBvwait\fR that are not \fIstrictly\fR
+necessary. Be aware that the synchronous modes of operation of some Tcl
+packages (e.g.,\ \fBhttp\fR) use \fBvwait\fR internally; if using the event
+loop, it is best to use the asynchronous callback-based modes of operation of
+those packages where available.
+.SH EXAMPLES
+.PP
+Run the event-loop continually until some event calls \fBexit\fR.
+(You can use any variable not mentioned elsewhere, but the name
+\fIforever\fR reminds you at a glance of the intent.)
+.PP
+.CS
+\fBvwait\fR forever
+.CE
+.PP
+Wait five seconds for a connection to a server socket, otherwise
+close the socket and continue running the script:
+.PP
+.CS
+# Initialise the state
+after 5000 set state timeout
+set server [socket -server accept 12345]
+proc accept {args} {
+    global state connectionInfo
+    set state accepted
+    set connectionInfo $args
+}
+
+# Wait for something to happen
+\fBvwait\fR state
+
+# Clean up events that could have happened
+close $server
+after cancel set state timeout
+
+# Do something based on how the vwait finished...
+switch $state {
+    timeout {
+        puts "no connection on port 12345"
+    }
+    accepted {
+       puts "connection: $connectionInfo"
+       puts [lindex $connectionInfo 0] "Hello there!"
+    }
+}
+.CE
+.PP
+A command that will wait for some time delay by waiting for a namespace
+variable to be set.  Includes an interlock to prevent nested waits.
+.PP
+.CS
+namespace eval example {
+    variable v done
+    proc wait {delay} {
+        variable v
+        if {$v ne "waiting"} {
+            set v waiting
+            after $delay [namespace code {set v done}]
+            \fBvwait\fR [namespace which -variable v]
+        }
+        return $v
+    }
+}
+.CE
+.PP
+When running inside a \fBcoroutine\fR, an alternative to using \fBvwait\fR is
+to \fByield\fR to an outer event loop and to get recommenced when the variable
+is set, or at an idle moment after that.
+.PP
+.CS
+coroutine task apply {{} {
+    # simulate [after 1000]
+    after 1000 [info coroutine]
+    yield
+
+    # schedule the setting of a global variable, as normal
+    after 2000 {set var 1}
+
+    # simulate [\fBvwait\fR var]
+    proc updatedVar {task args} {
+        after idle $task
+        trace remove variable ::var write "updatedVar $task"
+    }
+    trace add variable ::var write "updatedVar [info coroutine]"
+    yield
+}}
+.CE
+.SS "NESTED VWAITS BY EXAMPLE"
+.PP
+This example demonstrates what can happen when the \fBvwait\fR command is
+nested. The script will never finish because the waiting for the \fIa\fR
+variable never finishes; that \fBvwait\fR command is still waiting for a
+script scheduled with \fBafter\fR to complete, which just happens to be
+running an inner \fBvwait\fR (for \fIb\fR) even though the event that the
+outer \fBvwait\fR was waiting for (the setting of \fIa\fR) has occurred.
+.PP
+.CS
+after 500 {
+    puts "waiting for b"
+    \fBvwait\fR b
+    puts "b was set"
+}
+after 1000 {
+    puts "setting a"
+    set a 10
+}
+puts "waiting for a"
+\fBvwait\fR a
+puts "a was set"
+puts "setting b"
+set b 42
+.CE
+.PP
+If you run the above code, you get this output:
+.PP
+.CS
+waiting for a
+waiting for b
+setting a
+.CE
+.PP
+The script will never print
+.QW "a was set"
+until after it has printed
+.QW "b was set"
+because of the nesting of \fBvwait\fR commands, and yet \fIb\fR will not be
+set until after the outer \fBvwait\fR returns, so the script has deadlocked.
+The only ways to avoid this are to either structure the overall program in
+continuation-passing style or to use \fBcoroutine\fR to make the continuations
+implicit. The first of these options would be written as:
+.PP
+.CS
+after 500 {
+    puts "waiting for b"
+    trace add variable b write {apply {args {
+        global a b
+        trace remove variable ::b write \e
+                [lrange [info level 0] 0 1]
+        puts "b was set"
+        set ::done ok
+    }}}
+}
+after 1000 {
+    puts "setting a"
+    set a 10
+}
+puts "waiting for a"
+trace add variable a write {apply {args {
+    global a b
+    trace remove variable a write [lrange [info level 0] 0 1]
+    puts "a was set"
+    puts "setting b"
+    set b 42
+}}}
+\fBvwait\fR done
+.CE
+.PP
+The second option, with \fBcoroutine\fR and some helper procedures, is done
+like this:
+.PP
+.CS
+# A coroutine-based wait-for-variable command
+proc waitvar globalVar {
+    trace add variable ::$globalVar write \e
+            [list apply {{v c args} {
+        trace remove variable $v write \e
+                [lrange [info level 0] 0 3]
+        after 0 $c
+    }} ::$globalVar [info coroutine]]
+    yield
+}
+# A coroutine-based wait-for-some-time command
+proc waittime ms {
+    after $ms [info coroutine]
+    yield
+}
+
+coroutine task-1 eval {
+    puts "waiting for a"
+    waitvar a
+    puts "a was set"
+    puts "setting b"
+    set b 42
+}
+coroutine task-2 eval {
+    waittime 500
+    puts "waiting for b"
+    waitvar b
+    puts "b was set"
+    set done ok
+}
+coroutine task-3 eval {
+    waittime 1000
+    puts "setting a"
+    set a 10
+}
+\fBvwait\fR done
+.CE
+.SH "SEE ALSO"
+global(n), update(n)
+.SH KEYWORDS
+asynchronous I/O, event, variable, wait
+'\" Local Variables:
+'\" mode: nroff
+'\" fill-column: 78
+'\" End:
diff --git a/doc/while.n b/doc/while.n
new file mode 100644
index 0000000..961260c
--- /dev/null
+++ b/doc/while.n
@@ -0,0 +1,65 @@
+'\"
+'\" Copyright (c) 1993 The Regents of the University of California.
+'\" Copyright (c) 1994-1997 Sun Microsystems, Inc.
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH while n "" Tcl "Tcl Built-In Commands"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+while \- Execute script repeatedly as long as a condition is met
+.SH SYNOPSIS
+\fBwhile \fItest body\fR
+.BE
+.SH DESCRIPTION
+.PP
+The \fBwhile\fR command evaluates \fItest\fR as an expression
+(in the same way that \fBexpr\fR evaluates its argument).
+The value of the expression must a proper boolean
+value; if it is a true value
+then \fIbody\fR is executed by passing it to the Tcl interpreter.
+Once \fIbody\fR has been executed then \fItest\fR is evaluated
+again, and the process repeats until eventually \fItest\fR
+evaluates to a false boolean value.  \fBContinue\fR
+commands may be executed inside \fIbody\fR to terminate the current
+iteration of the loop, and \fBbreak\fR
+commands may be executed inside \fIbody\fR to cause immediate
+termination of the \fBwhile\fR command.  The \fBwhile\fR command
+always returns an empty string.
+.PP
+Note: \fItest\fR should almost always be enclosed in braces.  If not,
+variable substitutions will be made before the \fBwhile\fR
+command starts executing, which means that variable changes
+made by the loop body will not be considered in the expression.
+This is likely to result in an infinite loop.  If \fItest\fR is
+enclosed in braces, variable substitutions are delayed until the
+expression is evaluated (before
+each loop iteration), so changes in the variables will be visible.
+For an example, try the following script with and without the braces
+around \fB$x<10\fR:
+.PP
+.CS
+set x 0
+\fBwhile\fR {$x<10} {
+    puts "x is $x"
+    incr x
+}
+.CE
+.SH EXAMPLE
+.PP
+Read lines from a channel until we get to the end of the stream, and
+print them out with a line-number prepended:
+.PP
+.CS
+set lineCount 0
+\fBwhile\fR {[gets $chan line] >= 0} {
+    puts "[incr lineCount]: $line"
+}
+.CE
+.SH "SEE ALSO"
+break(n), continue(n), for(n), foreach(n)
+.SH KEYWORDS
+boolean, loop, test, while
diff --git a/doc/zlib.n b/doc/zlib.n
new file mode 100644
index 0000000..fd29e0d
--- /dev/null
+++ b/doc/zlib.n
@@ -0,0 +1,466 @@
+'\"
+'\" Copyright (c) 2008-2012 Donal K. Fellows
+'\"
+'\" See the file "license.terms" for information on usage and redistribution
+'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+'\"
+.TH zlib n 8.6 Tcl "Tcl Built-In Commands"
+.so man.macros
+.BS
+'\" Note:  do not modify the .SH NAME line immediately below!
+.SH NAME
+zlib \- compression and decompression operations
+.SH SYNOPSIS
+.nf
+\fBzlib \fIsubcommand arg ...\fR
+.fi
+.BE
+.SH DESCRIPTION
+.PP
+The \fBzlib\fR command provides access to the compression and check-summing
+facilities of the Zlib library by Jean-loup Gailly and Mark Adler. It has the
+following subcommands.
+.SS "COMPRESSION SUBCOMMANDS"
+.TP
+\fBzlib compress\fI string\fR ?\fIlevel\fR?
+.
+Returns the zlib-format compressed binary data of the binary string in
+\fIstring\fR. If present, \fIlevel\fR gives the compression level to use (from
+0, which is uncompressed, to 9, maximally compressed).
+.TP
+\fBzlib decompress\fI string\fR ?\fIbufferSize\fR?
+.
+Returns the uncompressed version of the raw compressed binary data in
+\fIstring\fR. If present, \fIbufferSize\fR is a hint as to what size of buffer
+is to be used to receive the data.
+.TP
+\fBzlib deflate\fI string\fR ?\fIlevel\fR?
+.
+Returns the raw compressed binary data of the binary string in \fIstring\fR.
+If present, \fIlevel\fR gives the compression level to use (from 0, which is
+uncompressed, to 9, maximally compressed).
+.TP
+\fBzlib gunzip\fI string\fR ?\fB\-headerVar \fIvarName\fR?
+.
+Return the uncompressed contents of binary string \fIstring\fR, which must
+have been in gzip format. If \fB\-headerVar\fR is given, store a dictionary
+describing the contents of the gzip header in the variable called
+\fIvarName\fR. The keys of the dictionary that may be present are:
+.RS
+.TP
+\fBcomment\fR
+.
+The comment field from the header, if present.
+.TP
+\fBcrc\fR
+.
+A boolean value describing whether a CRC of the header is computed.
+.TP
+\fBfilename\fR
+.
+The filename field from the header, if present.
+.TP
+\fBos\fR
+.
+The operating system type code field from the header (if not the
+QW unknown
+value). See RFC 1952 for the meaning of these codes.
+.TP
+\fBsize\fR
+.
+The size of the uncompressed data.
+.TP
+\fBtime\fR
+.
+The time field from the header if non-zero, expected to be time that the file
+named by the \fBfilename\fR field was modified. Suitable for use with
+\fBclock format\fR.
+.TP
+\fBtype\fR
+.
+The type of the uncompressed data (\fBbinary\fR or \fBtext\fR) if known.
+.RE
+.TP
+\fBzlib gzip\fI string\fR ?\fB\-level \fIlevel\fR? ?\fB\-header \fIdict\fR?
+.
+Return the compressed contents of binary string \fIstring\fR in gzip format.
+If \fB\-level\fR is given, \fIlevel\fR gives the compression level to use
+(from 0, which is uncompressed, to 9, maximally compressed). If \fB\-header\fR
+is given, \fIdict\fR is a dictionary containing values used for the gzip
+header. The following keys may be defined:
+.RS
+.TP
+\fBcomment\fR
+.
+Add the given comment to the header of the gzip-format data.
+.TP
+\fBcrc\fR
+.
+A boolean saying whether to compute a CRC of the header. Note that if the data
+is to be interchanged with the \fBgzip\fR program, a header CRC should
+\fInot\fR be computed.
+.TP
+\fBfilename\fR
+.
+The name of the file that the data to be compressed came from.
+.TP
+\fBos\fR
+.
+The operating system type code, which should be one of the values described in
+RFC 1952.
+.TP
+\fBtime\fR
+.
+The time that the file named in the \fBfilename\fR key was last modified. This
+will be in the same as is returned by \fBclock seconds\fR or \fBfile mtime\fR.
+.TP
+\fBtype\fR
+.
+The type of the data being compressed, being \fBbinary\fR or \fBtext\fR.
+.RE
+.TP
+\fBzlib inflate\fI string\fR ?\fIbufferSize\fR?
+.
+Returns the uncompressed version of the raw compressed binary data in
+\fIstring\fR. If present, \fIbufferSize\fR is a hint as to what size of buffer
+is to be used to receive the data.
+.SS "CHANNEL SUBCOMMAND"
+.TP
+\fBzlib push\fI mode channel\fR ?\fIoptions ...\fR?
+.
+Pushes a compressing or decompressing transformation onto the channel
+\fIchannel\fR.
+The transformation can be removed again with \fBchan pop\fR.
+The \fImode\fR argument determines what type of transformation
+is pushed; the following are supported:
+.RS
+.TP
+\fBcompress\fR
+.
+The transformation will be a compressing transformation that produces
+zlib-format data on \fIchannel\fR, which must be writable.
+.TP
+\fBdecompress\fR
+.
+The transformation will be a decompressing transformation that reads
+zlib-format data from \fIchannel\fR, which must be readable.
+.TP
+\fBdeflate\fR
+.
+The transformation will be a compressing transformation that produces raw
+compressed data on \fIchannel\fR, which must be writable.
+.TP
+\fBgunzip\fR
+.
+The transformation will be a decompressing transformation that reads
+gzip-format data from \fIchannel\fR, which must be readable.
+.TP
+\fBgzip\fR
+.
+The transformation will be a compressing transformation that produces
+gzip-format data on \fIchannel\fR, which must be writable.
+.TP
+\fBinflate\fR
+.
+The transformation will be a decompressing transformation that reads raw
+compressed data from \fIchannel\fR, which must be readable.
+.PP
+The following options may be set when creating a transformation via
+the
+.QW "\fIoptions ...\fR"
+to the \fBzlib push\fR command:
+.TP
+\fB\-dictionary\fI binData\fR
+.VS "TIP 400"
+Sets the compression dictionary to use when working with compressing or
+decompressing the data to be \fIbinData\fR. Not valid for transformations that
+work with gzip-format data.  The dictionary should consist of strings (byte
+sequences) that are likely to be encountered later in the data to be compressed,
+with the most commonly used strings preferably put towards the end of the
+dictionary. Tcl provides no mechanism for choosing a good such dictionary for
+a particular data sequence.
+.VE
+.TP
+\fB\-header\fI dictionary\fR
+.
+Passes a description of the gzip header to create, in the same format that
+\fBzlib gzip\fR understands.
+.TP
+\fB\-level\fI compressionLevel\fR
+.
+How hard to compress the data. Must be an integer from 0 (uncompressed) to 9
+(maximally compressed).
+.TP
+\fB\-limit\fI readaheadLimit\fR
+.
+The maximum number of bytes ahead to read when decompressing. This defaults to
+1, which ensures that data is always decompressed correctly, but may be
+increased to improve performance. This is more useful when the channel is
+non-blocking.
+.PP
+Both compressing and decompressing channel transformations add extra
+configuration options that may be accessed through \fBchan configure\fR. The
+options are:
+.TP
+\fB\-checksum\fI checksum\fR
+.
+This read-only option gets the current checksum for the uncompressed data that
+the compression engine has seen so far. It is valid for both compressing and
+decompressing transforms, but not for the raw inflate and deflate formats. The
+compression algorithm depends on what format is being produced or consumed.
+.TP
+\fB\-dictionary\fI binData\fR
+.VS "TIP 400"
+This read-write options gets or sets the initial compression dictionary to use
+when working with compressing or decompressing the data to be \fIbinData\fR.
+It is not valid for transformations that work with gzip-format data, and should
+not normally be set on compressing transformations other than at the point where
+the transformation is stacked. Note that this cannot be used to get the
+current active compression dictionary mid-stream, as that information is not
+exposed by the underlying library.
+.VE
+.TP
+\fB\-flush\fI type\fR
+.
+This write-only operation flushes the current state of the compressor to the
+underlying channel. It is only valid for compressing transformations. The
+\fItype\fR must be either \fBsync\fR or \fBfull\fR for a normal flush or an
+expensive flush respectively. Flushing degrades the compression ratio, but
+makes it easier for a decompressor to recover more of the file in the case of
+data corruption.
+.TP
+\fB\-header\fI dictionary\fR
+.
+This read-only option, only valid for decompressing transforms that are
+processing gzip-format data, returns the dictionary describing the header read
+off the data stream.
+.TP
+\fB\-limit\fI readaheadLimit\fR
+.
+This read-write option is used by decompressing channels to control the
+maximum number of bytes ahead to read from the underlying data source. This
+defaults to 1, which ensures that data is always decompressed correctly, but
+may be increased to improve performance. This is more useful when the channel
+is non-blocking.
+.RE
+.SS "STREAMING SUBCOMMAND"
+.TP
+\fBzlib stream\fI mode\fR ?\fIoptions\fR?
+.
+Creates a streaming compression or decompression command based on the
+\fImode\fR, and return the name of the command. For a description of how that
+command works, see \fBSTREAMING INSTANCE COMMAND\fR below. The following modes
+and \fIoptions\fR are supported:
+.RS
+.TP
+\fBzlib stream compress\fR ?\fB\-dictionary \fIbindata\fR? ?\fB\-level \fIlevel\fR?
+.
+The stream will be a compressing stream that produces zlib-format output,
+using compression level \fIlevel\fR (if specified) which will be an integer
+from 0 to 9,
+.VS "TIP 400"
+and the compression dictionary \fIbindata\fR (if specified).
+.VE
+.TP
+\fBzlib stream decompress\fR ?\fB\-dictionary \fIbindata\fR?
+.
+The stream will be a decompressing stream that takes zlib-format input and
+produces uncompressed output.
+.VS "TIP 400"
+If \fIbindata\fR is supplied, it is a compression dictionary to use if
+required.
+.VE
+.TP
+\fBzlib stream deflate\fR ?\fB\-dictionary \fIbindata\fR? ?\fB\-level \fIlevel\fR?
+.
+The stream will be a compressing stream that produces raw output, using
+compression level \fIlevel\fR (if specified) which will be an integer from 0
+to 9,
+.VS "TIP 400"
+and the compression dictionary \fIbindata\fR (if specified). Note that
+the raw compressed data includes no metadata about what compression
+dictionary was used, if any; that is a feature of the zlib-format data.
+.VE
+.TP
+\fBzlib stream gunzip\fR
+.
+The stream will be a decompressing stream that takes gzip-format input and
+produces uncompressed output.
+.TP
+\fBzlib stream gzip\fR ?\fB\-header \fIheader\fR? ?\fB\-level \fIlevel\fR?
+.
+The stream will be a compressing stream that produces gzip-format output,
+using compression level \fIlevel\fR (if specified) which will be an integer
+from 0 to 9, and the header descriptor dictionary \fIheader\fR (if specified;
+for keys see \fBzlib gzip\fR).
+.TP
+\fBzlib stream inflate\fR ?\fB\-dictionary \fIbindata\fR?
+.
+The stream will be a decompressing stream that takes raw compressed input and
+produces uncompressed output.
+.VS "TIP 400"
+If \fIbindata\fR is supplied, it is a compression dictionary to use. Note that
+there are no checks in place to determine whether the compression dictionary
+is correct.
+.VE
+.RE
+.SS "CHECKSUMMING SUBCOMMANDS"
+.TP
+\fBzlib adler32\fI string\fR ?\fIinitValue\fR?
+.
+Compute a checksum of binary string \fIstring\fR using the Adler-32 algorithm.
+If given, \fIinitValue\fR is used to initialize the checksum engine.
+.TP
+\fBzlib crc32\fI string\fR ?\fIinitValue\fR?
+.
+Compute a checksum of binary string \fIstring\fR using the CRC-32 algorithm.
+If given, \fIinitValue\fR is used to initialize the checksum engine.
+.SH "STREAMING INSTANCE COMMAND"
+.PP
+Streaming compression instance commands are produced by the \fBzlib stream\fR
+command. They are used by calling their \fBput\fR subcommand one or more times
+to load data in, and their \fBget\fR subcommand one or more times to extract
+the transformed data.
+.PP
+The full set of subcommands supported by a streaming instance command,
+\fIstream\fR, is as follows:
+.TP
+\fIstream \fBadd\fR ?\fIoption...\fR? \fIdata\fR
+.
+A short-cut for
+.QW "\fIstream \fBput \fR?\fIoption...\fR? \fIdata\fR"
+followed by
+.QW "\fIstream \fBget\fR" .
+.TP
+\fIstream \fBchecksum\fR
+.
+Returns the checksum of the uncompressed data seen so far by this stream.
+.TP
+\fIstream \fBclose\fR
+.
+Deletes this stream and frees up all resources associated with it.
+.TP
+\fIstream \fBeof\fR
+.
+Returns a boolean indicating whether the end of the stream (as determined by
+the compressed data itself) has been reached. Not all formats support
+detection of the end of the stream.
+.TP
+\fIstream \fBfinalize\fR
+.
+A short-cut for
+.QW "\fIstream \fBput \-finalize {}\fR" .
+.TP
+\fIstream \fBflush\fR
+.
+A short-cut for
+.QW "\fIstream \fBput \-flush {}\fR" .
+.TP
+\fIstream \fBfullflush\fR
+.
+A short-cut for
+.QW "\fIstream \fBput \-fullflush {}\fR" .
+.TP
+\fIstream \fBget \fR?\fIcount\fR?
+.
+Return up to \fIcount\fR bytes from \fIstream\fR's internal buffers with the
+transformation applied. If \fIcount\fR is omitted, the entire contents of the
+buffers are returned.
+.
+\fIstream \fBheader\fR
+.
+Return the gzip header description dictionary extracted from the stream. Only
+supported for streams created with their \fImode\fR parameter set to
+\fBgunzip\fR.
+.TP
+\fIstream \fBput\fR ?\fIoption...\fR? \fIdata\fR
+.
+Append the contents of the binary string \fIdata\fR to \fIstream\fR's internal
+buffers while applying the transformation. The following \fIoption\fRs are
+supported (or an unambiguous prefix of them), which are used to modify the
+way in which the transformation is applied:
+.RS
+.TP
+\fB\-dictionary\fI binData\fR
+.VS "TIP 400"
+Sets the compression dictionary to use when working with compressing or
+decompressing the data to be \fIbinData\fR.
+.VE
+.TP
+\fB\-finalize\fR
+.
+Mark the stream as finished, ensuring that all bytes have been wholly
+compressed or decompressed. For gzip streams, this also ensures that the
+footer is written to the stream. The stream will need to be reset before
+having more data written to it after this, though data can still be read out
+of the stream with the \fBget\fR subcommand.
+.RS
+.PP
+This option is mutually exclusive with the \fB\-flush\fR and \fB\-fullflush\fR
+options.
+.RE
+.TP
+\fB\-flush\fR
+.
+Ensure that a decompressor consuming the bytes that the current (compressing)
+stream is producing will be able to produce all the bytes that have been
+compressed so far, at some performance penalty.
+.RS
+.PP
+This option is mutually exclusive with the \fB\-finalize\fR and
+\fB\-fullflush\fR options.
+.RE
+.TP
+\fB\-fullflush\fR
+.
+Ensure that not only can a decompressor handle all the bytes produced so far
+(as with \fB\-flush\fR above) but also that it can restart from this point if
+it detects that the stream is partially corrupt. This incurs a substantial
+performance penalty.
+.RS
+.PP
+This option is mutually exclusive with the \fB\-finalize\fR and \fB\-flush\fR
+options.
+.RE
+.RE
+.TP
+\fIstream \fBreset\fR
+.
+Puts any stream, including those that have been finalized or that have reached
+eof, back into a state where it can process more data. Throws away all
+internally buffered data.
+.SH EXAMPLES
+.PP
+To compress a Tcl string, it should be first converted to a particular charset
+encoding since the \fBzlib\fR command always operates on binary strings.
+.PP
+.CS
+set binData [encoding convertto utf-8 $string]
+set compData [\fBzlib compress\fR $binData]
+.CE
+.PP
+When converting back, it is also important to reverse the charset encoding:
+.PP
+.CS
+set binData [\fBzlib decompress\fR $compData]
+set string [encoding convertfrom utf-8 $binData]
+.CE
+.PP
+The compression operation from above can also be done with streams, which is
+especially helpful when you want to accumulate the data by stages:
+.PP
+.CS
+set strm [\fBzlib stream\fR compress]
+$\fIstrm \fBput\fR [encoding convertto utf-8 $string]
+# ...
+$\fIstrm \fBfinalize\fR
+set compData [$\fIstrm \fBget\fR]
+$\fIstrm \fBclose\fR
+.CE
+.SH "SEE ALSO"
+binary(n), chan(n), encoding(n), Tcl_ZlibDeflate(3), RFC1950 \- RFC1952
+.SH "KEYWORDS"
+compress, decompress, deflate, gzip, inflate, zlib
+'\" Local Variables:
+'\" mode: nroff
+'\" End:
diff --git a/generic/README b/generic/README
new file mode 100644
index 0000000..d1c078e
--- /dev/null
+++ b/generic/README
@@ -0,0 +1,3 @@
+This directory contains Tcl source files that work on all the platforms
+where Tcl runs (e.g. UNIX, PCs, and MacOSX).  Platform-specific
+sources are in the directories ../unix, ../win, and ../macosx.
diff --git a/generic/regc_color.c b/generic/regc_color.c
new file mode 100644
index 0000000..92e0aad
--- /dev/null
+++ b/generic/regc_color.c
@@ -0,0 +1,856 @@
+/*
+ * colorings of characters
+ * This file is #included by regcomp.c.
+ *
+ * Copyright (c) 1998, 1999 Henry Spencer. All rights reserved.
+ *
+ * Development of this software was funded, in part, by Cray Research Inc.,
+ * UUNET Communications Services Inc., Sun Microsystems Inc., and Scriptics
+ * Corporation, none of whom are responsible for the results. The author
+ * thanks all of them.
+ *
+ * Redistribution and use in source and binary forms -- with or without
+ * modification -- are permitted for any purpose, provided that
+ * redistributions in source form retain this entire copyright notice and
+ * indicate the origin and nature of any modifications.
+ *
+ * I'd appreciate being given credit for this package in the documentation of
+ * software which uses it, but that is not a requirement.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * HENRY SPENCER BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Note that there are some incestuous relationships between this code and NFA
+ * arc maintenance, which perhaps ought to be cleaned up sometime.
+ */
+
+#define	CISERR()	VISERR(cm->v)
+#define	CERR(e)		VERR(cm->v, (e))
+
+/*
+ - initcm - set up new colormap
+ ^ static void initcm(struct vars *, struct colormap *);
+ */
+static void
+initcm(
+    struct vars *v,
+    struct colormap *cm)
+{
+    int i;
+    int j;
+    union tree *t;
+    union tree *nextt;
+    struct colordesc *cd;
+
+    cm->magic = CMMAGIC;
+    cm->v = v;
+
+    cm->ncds = NINLINECDS;
+    cm->cd = cm->cdspace;
+    cm->max = 0;
+    cm->free = 0;
+
+    cd = cm->cd;		/* cm->cd[WHITE] */
+    cd->sub = NOSUB;
+    cd->arcs = NULL;
+    cd->flags = 0;
+    cd->nchrs = CHR_MAX - CHR_MIN + 1;
+
+    /*
+     * Upper levels of tree.
+     */
+
+    for (t=&cm->tree[0], j=NBYTS-1 ; j>0 ; t=nextt, j--) {
+	nextt = t + 1;
+	for (i=BYTTAB-1 ; i>=0 ; i--) {
+	    t->tptr[i] = nextt;
+	}
+    }
+
+    /*
+     * Bottom level is solid white.
+     */
+
+    t = &cm->tree[NBYTS-1];
+    for (i=BYTTAB-1 ; i>=0 ; i--) {
+	t->tcolor[i] = WHITE;
+    }
+    cd->block = t;
+}
+
+/*
+ - freecm - free dynamically-allocated things in a colormap
+ ^ static void freecm(struct colormap *);
+ */
+static void
+freecm(
+    struct colormap *cm)
+{
+    size_t i;
+    union tree *cb;
+
+    cm->magic = 0;
+    if (NBYTS > 1) {
+	cmtreefree(cm, cm->tree, 0);
+    }
+    for (i=1 ; i<=cm->max ; i++) {	/* skip WHITE */
+	if (!UNUSEDCOLOR(&cm->cd[i])) {
+	    cb = cm->cd[i].block;
+	    if (cb != NULL) {
+		FREE(cb);
+	    }
+	}
+    }
+    if (cm->cd != cm->cdspace) {
+	FREE(cm->cd);
+    }
+}
+
+/*
+ - cmtreefree - free a non-terminal part of a colormap tree
+ ^ static void cmtreefree(struct colormap *, union tree *, int);
+ */
+static void
+cmtreefree(
+    struct colormap *cm,
+    union tree *tree,
+    int level)			/* level number (top == 0) of this block */
+{
+    int i;
+    union tree *t;
+    union tree *fillt = &cm->tree[level+1];
+    union tree *cb;
+
+    assert(level < NBYTS-1);	/* this level has pointers */
+    for (i=BYTTAB-1 ; i>=0 ; i--) {
+	t = tree->tptr[i];
+	assert(t != NULL);
+	if (t != fillt) {
+	    if (level < NBYTS-2) {	/* more pointer blocks below */
+		cmtreefree(cm, t, level+1);
+		FREE(t);
+	    } else {		/* color block below */
+		cb = cm->cd[t->tcolor[0]].block;
+		if (t != cb) {	/* not a solid block */
+		    FREE(t);
+		}
+	    }
+	}
+    }
+}
+
+/*
+ - setcolor - set the color of a character in a colormap
+ ^ static color setcolor(struct colormap *, pchr, pcolor);
+ */
+static color			/* previous color */
+setcolor(
+    struct colormap *cm,
+    pchr c,
+    pcolor co)
+{
+    uchr uc = c;
+    int shift;
+    int level;
+    int b;
+    int bottom;
+    union tree *t;
+    union tree *newt;
+    union tree *fillt;
+    union tree *lastt;
+    union tree *cb;
+    color prev;
+
+    assert(cm->magic == CMMAGIC);
+    if (CISERR() || co == COLORLESS) {
+	return COLORLESS;
+    }
+
+    t = cm->tree;
+    for (level=0, shift=BYTBITS*(NBYTS-1) ; shift>0; level++, shift-=BYTBITS){
+	b = (uc >> shift) & BYTMASK;
+	lastt = t;
+	t = lastt->tptr[b];
+	assert(t != NULL);
+	fillt = &cm->tree[level+1];
+	bottom = (shift <= BYTBITS) ? 1 : 0;
+	cb = (bottom) ? cm->cd[t->tcolor[0]].block : fillt;
+	if (t == fillt || t == cb) {	/* must allocate a new block */
+	    newt = (union tree *) MALLOC((bottom) ?
+		    sizeof(struct colors) : sizeof(struct ptrs));
+	    if (newt == NULL) {
+		CERR(REG_ESPACE);
+		return COLORLESS;
+	    }
+	    if (bottom) {
+		memcpy(newt->tcolor, t->tcolor, BYTTAB*sizeof(color));
+	    } else {
+		memcpy(newt->tptr, t->tptr, BYTTAB*sizeof(union tree *));
+	    }
+	    t = newt;
+	    lastt->tptr[b] = t;
+	}
+    }
+
+    b = uc & BYTMASK;
+    prev = t->tcolor[b];
+    t->tcolor[b] = (color) co;
+    return prev;
+}
+
+/*
+ - maxcolor - report largest color number in use
+ ^ static color maxcolor(struct colormap *);
+ */
+static color
+maxcolor(
+    struct colormap *cm)
+{
+    if (CISERR()) {
+	return COLORLESS;
+    }
+
+    return (color) cm->max;
+}
+
+/*
+ - newcolor - find a new color (must be subject of setcolor at once)
+ * Beware: may relocate the colordescs.
+ ^ static color newcolor(struct colormap *);
+ */
+static color			/* COLORLESS for error */
+newcolor(
+    struct colormap *cm)
+{
+    struct colordesc *cd;
+    size_t n;
+
+    if (CISERR()) {
+	return COLORLESS;
+    }
+
+    if (cm->free != 0) {
+	assert(cm->free > 0);
+	assert((size_t) cm->free < cm->ncds);
+	cd = &cm->cd[cm->free];
+	assert(UNUSEDCOLOR(cd));
+	assert(cd->arcs == NULL);
+	cm->free = cd->sub;
+    } else if (cm->max < cm->ncds - 1) {
+	cm->max++;
+	cd = &cm->cd[cm->max];
+    } else {
+	struct colordesc *newCd;
+
+	/*
+	 * Oops, must allocate more.
+	 */
+
+	if (cm->max == MAX_COLOR) {
+	    CERR(REG_ECOLORS);
+	    return COLORLESS;		/* too many colors */
+	}
+	n = cm->ncds * 2;
+	if (n > MAX_COLOR + 1) {
+	    n = MAX_COLOR + 1;
+	}
+	if (cm->cd == cm->cdspace) {
+	    newCd = (struct colordesc *) MALLOC(n * sizeof(struct colordesc));
+	    if (newCd != NULL) {
+		memcpy(newCd, cm->cdspace,
+			cm->ncds * sizeof(struct colordesc));
+	    }
+	} else {
+	    newCd = (struct colordesc *)
+		    REALLOC(cm->cd, n * sizeof(struct colordesc));
+	}
+	if (newCd == NULL) {
+	    CERR(REG_ESPACE);
+	    return COLORLESS;
+	}
+	cm->cd = newCd;
+	cm->ncds = n;
+	assert(cm->max < cm->ncds - 1);
+	cm->max++;
+	cd = &cm->cd[cm->max];
+    }
+
+    cd->nchrs = 0;
+    cd->sub = NOSUB;
+    cd->arcs = NULL;
+    cd->flags = 0;
+    cd->block = NULL;
+
+    return (color) (cd - cm->cd);
+}
+
+/*
+ - freecolor - free a color (must have no arcs or subcolor)
+ ^ static void freecolor(struct colormap *, pcolor);
+ */
+static void
+freecolor(
+    struct colormap *cm,
+    pcolor co)
+{
+    struct colordesc *cd = &cm->cd[co];
+    color pco, nco;		/* for freelist scan */
+
+    assert(co >= 0);
+    if (co == WHITE) {
+	return;
+    }
+
+    assert(cd->arcs == NULL);
+    assert(cd->sub == NOSUB);
+    assert(cd->nchrs == 0);
+    cd->flags = FREECOL;
+    if (cd->block != NULL) {
+	FREE(cd->block);
+	cd->block = NULL;	/* just paranoia */
+    }
+
+    if ((size_t) co == cm->max) {
+	while (cm->max > WHITE && UNUSEDCOLOR(&cm->cd[cm->max])) {
+	    cm->max--;
+	}
+	assert(cm->free >= 0);
+	while ((size_t) cm->free > cm->max) {
+	    cm->free = cm->cd[cm->free].sub;
+	}
+	if (cm->free > 0) {
+	    assert((size_t)cm->free < cm->max);
+	    pco = cm->free;
+	    nco = cm->cd[pco].sub;
+	    while (nco > 0) {
+		if ((size_t) nco > cm->max) {
+		    /*
+		     * Take this one out of freelist.
+		     */
+
+		    nco = cm->cd[nco].sub;
+		    cm->cd[pco].sub = nco;
+		} else {
+		    assert((size_t)nco < cm->max);
+		    pco = nco;
+		    nco = cm->cd[pco].sub;
+		}
+	    }
+	}
+    } else {
+	cd->sub = cm->free;
+	cm->free = (color) (cd - cm->cd);
+    }
+}
+
+/*
+ - pseudocolor - allocate a false color, to be managed by other means
+ ^ static color pseudocolor(struct colormap *);
+ */
+static color
+pseudocolor(
+    struct colormap *cm)
+{
+    color co;
+
+    co = newcolor(cm);
+    if (CISERR()) {
+	return COLORLESS;
+    }
+    cm->cd[co].nchrs = 1;
+    cm->cd[co].flags = PSEUDO;
+    return co;
+}
+
+/*
+ - subcolor - allocate a new subcolor (if necessary) to this chr
+ ^ static color subcolor(struct colormap *, pchr c);
+ */
+static color
+subcolor(
+    struct colormap *cm,
+    pchr c)
+{
+    color co;			/* current color of c */
+    color sco;			/* new subcolor */
+
+    co = GETCOLOR(cm, c);
+    sco = newsub(cm, co);
+    if (CISERR()) {
+	return COLORLESS;
+    }
+    assert(sco != COLORLESS);
+
+    if (co == sco) {		/* already in an open subcolor */
+	return co;		/* rest is redundant */
+    }
+    cm->cd[co].nchrs--;
+    cm->cd[sco].nchrs++;
+    setcolor(cm, c, sco);
+    return sco;
+}
+
+/*
+ - newsub - allocate a new subcolor (if necessary) for a color
+ ^ static color newsub(struct colormap *, pcolor);
+ */
+static color
+newsub(
+    struct colormap *cm,
+    pcolor co)
+{
+    color sco;			/* new subcolor */
+
+    sco = cm->cd[co].sub;
+    if (sco == NOSUB) {		/* color has no open subcolor */
+	if (cm->cd[co].nchrs == 1) {	/* optimization */
+	    return co;
+	}
+	sco = newcolor(cm);	/* must create subcolor */
+	if (sco == COLORLESS) {
+	    assert(CISERR());
+	    return COLORLESS;
+	}
+	cm->cd[co].sub = sco;
+	cm->cd[sco].sub = sco;	/* open subcolor points to self */
+    }
+    assert(sco != NOSUB);
+
+    return sco;
+}
+
+/*
+ - subrange - allocate new subcolors to this range of chrs, fill in arcs
+ ^ static void subrange(struct vars *, pchr, pchr, struct state *,
+ ^ 	struct state *);
+ */
+static void
+subrange(
+    struct vars *v,
+    pchr from,
+    pchr to,
+    struct state *lp,
+    struct state *rp)
+{
+    uchr uf;
+    int i;
+
+    assert(from <= to);
+
+    /*
+     * First, align "from" on a tree-block boundary
+     */
+
+    uf = (uchr) from;
+    i = (int) (((uf + BYTTAB - 1) & (uchr) ~BYTMASK) - uf);
+    for (; from<=to && i>0; i--, from++) {
+	newarc(v->nfa, PLAIN, subcolor(v->cm, from), lp, rp);
+    }
+    if (from > to) {		/* didn't reach a boundary */
+	return;
+    }
+
+    /*
+     * Deal with whole blocks.
+     */
+
+    for (; to-from>=BYTTAB ; from+=BYTTAB) {
+	subblock(v, from, lp, rp);
+    }
+
+    /*
+     * Clean up any remaining partial table.
+     */
+
+    for (; from<=to ; from++) {
+	newarc(v->nfa, PLAIN, subcolor(v->cm, from), lp, rp);
+    }
+}
+
+/*
+ - subblock - allocate new subcolors for one tree block of chrs, fill in arcs
+ ^ static void subblock(struct vars *, pchr, struct state *, struct state *);
+ */
+static void
+subblock(
+    struct vars *v,
+    pchr start,			/* first of BYTTAB chrs */
+    struct state *lp,
+    struct state *rp)
+{
+    uchr uc = start;
+    struct colormap *cm = v->cm;
+    int shift;
+    int level;
+    int i;
+    int b;
+    union tree *t;
+    union tree *cb;
+    union tree *fillt;
+    union tree *lastt;
+    int previ;
+    int ndone;
+    color co;
+    color sco;
+
+    assert((uc % BYTTAB) == 0);
+
+    /*
+     * Find its color block, making new pointer blocks as needed.
+     */
+
+    t = cm->tree;
+    fillt = NULL;
+    for (level=0, shift=BYTBITS*(NBYTS-1); shift>0; level++, shift-=BYTBITS) {
+	b = (uc >> shift) & BYTMASK;
+	lastt = t;
+	t = lastt->tptr[b];
+	assert(t != NULL);
+	fillt = &cm->tree[level+1];
+	if (t == fillt && shift > BYTBITS) {	/* need new ptr block */
+	    t = (union tree *) MALLOC(sizeof(struct ptrs));
+	    if (t == NULL) {
+		CERR(REG_ESPACE);
+		return;
+	    }
+	    memcpy(t->tptr, fillt->tptr, BYTTAB*sizeof(union tree *));
+	    lastt->tptr[b] = t;
+	}
+    }
+
+    /*
+     * Special cases: fill block or solid block.
+     */
+    co = t->tcolor[0];
+    cb = cm->cd[co].block;
+    if (t == fillt || t == cb) {
+	/*
+	 * Either way, we want a subcolor solid block.
+	 */
+
+	sco = newsub(cm, co);
+	t = cm->cd[sco].block;
+	if (t == NULL) {	/* must set it up */
+	    t = (union tree *) MALLOC(sizeof(struct colors));
+	    if (t == NULL) {
+		CERR(REG_ESPACE);
+		return;
+	    }
+	    for (i=0 ; i<BYTTAB ; i++) {
+		t->tcolor[i] = sco;
+	    }
+	    cm->cd[sco].block = t;
+	}
+
+	/*
+	 * Find loop must have run at least once.
+	 */
+
+	lastt->tptr[b] = t;
+	newarc(v->nfa, PLAIN, sco, lp, rp);
+	cm->cd[co].nchrs -= BYTTAB;
+	cm->cd[sco].nchrs += BYTTAB;
+	return;
+    }
+
+    /*
+     * General case, a mixed block to be altered.
+     */
+
+    i = 0;
+    while (i < BYTTAB) {
+	co = t->tcolor[i];
+	sco = newsub(cm, co);
+	newarc(v->nfa, PLAIN, sco, lp, rp);
+	previ = i;
+	do {
+	    t->tcolor[i++] = sco;
+	} while (i < BYTTAB && t->tcolor[i] == co);
+	ndone = i - previ;
+	cm->cd[co].nchrs -= ndone;
+	cm->cd[sco].nchrs += ndone;
+    }
+}
+
+/*
+ - okcolors - promote subcolors to full colors
+ ^ static void okcolors(struct nfa *, struct colormap *);
+ */
+static void
+okcolors(
+    struct nfa *nfa,
+    struct colormap *cm)
+{
+    struct colordesc *cd;
+    struct colordesc *end = CDEND(cm);
+    struct colordesc *scd;
+    struct arc *a;
+    color co;
+    color sco;
+
+    for (cd=cm->cd, co=0 ; cd<end ; cd++, co++) {
+	sco = cd->sub;
+	if (UNUSEDCOLOR(cd) || sco == NOSUB) {
+	    /*
+	     * Has no subcolor, no further action.
+	     */
+	} else if (sco == co) {
+	    /*
+	     * Is subcolor, let parent deal with it.
+	     */
+	} else if (cd->nchrs == 0) {
+	    /*
+	     * Parent empty, its arcs change color to subcolor.
+	     */
+
+	    cd->sub = NOSUB;
+	    scd = &cm->cd[sco];
+	    assert(scd->nchrs > 0);
+	    assert(scd->sub == sco);
+	    scd->sub = NOSUB;
+	    while ((a = cd->arcs) != NULL) {
+		assert(a->co == co);
+		uncolorchain(cm, a);
+		a->co = sco;
+		colorchain(cm, a);
+	    }
+	    freecolor(cm, co);
+	} else {
+	    /*
+	     * Parent's arcs must gain parallel subcolor arcs.
+	     */
+
+	    cd->sub = NOSUB;
+	    scd = &cm->cd[sco];
+	    assert(scd->nchrs > 0);
+	    assert(scd->sub == sco);
+	    scd->sub = NOSUB;
+	    for (a=cd->arcs ; a!=NULL ; a=a->colorchain) {
+		assert(a->co == co);
+		newarc(nfa, a->type, sco, a->from, a->to);
+	    }
+	}
+    }
+}
+
+/*
+ - colorchain - add this arc to the color chain of its color
+ ^ static void colorchain(struct colormap *, struct arc *);
+ */
+static void
+colorchain(
+    struct colormap *cm,
+    struct arc *a)
+{
+    struct colordesc *cd = &cm->cd[a->co];
+
+    if (cd->arcs != NULL) {
+	cd->arcs->colorchainRev = a;
+    }
+    a->colorchain = cd->arcs;
+    a->colorchainRev = NULL;
+    cd->arcs = a;
+}
+
+/*
+ - uncolorchain - delete this arc from the color chain of its color
+ ^ static void uncolorchain(struct colormap *, struct arc *);
+ */
+static void
+uncolorchain(
+    struct colormap *cm,
+    struct arc *a)
+{
+    struct colordesc *cd = &cm->cd[a->co];
+    struct arc *aa = a->colorchainRev;
+
+    if (aa == NULL) {
+	assert(cd->arcs == a);
+	cd->arcs = a->colorchain;
+    } else {
+	assert(aa->colorchain == a);
+	aa->colorchain = a->colorchain;
+    }
+    if (a->colorchain != NULL) {
+	a->colorchain->colorchainRev = aa;
+    }
+    a->colorchain = NULL;	/* paranoia */
+    a->colorchainRev = NULL;
+}
+
+/*
+ - rainbow - add arcs of all full colors (but one) between specified states
+ ^ static void rainbow(struct nfa *, struct colormap *, int, pcolor,
+ ^ 	struct state *, struct state *);
+ */
+static void
+rainbow(
+    struct nfa *nfa,
+    struct colormap *cm,
+    int type,
+    pcolor but,			/* COLORLESS if no exceptions */
+    struct state *from,
+    struct state *to)
+{
+    struct colordesc *cd;
+    struct colordesc *end = CDEND(cm);
+    color co;
+
+    for (cd=cm->cd, co=0 ; cd<end && !CISERR(); cd++, co++) {
+	if (!UNUSEDCOLOR(cd) && (cd->sub != co) && (co != but)
+		&& !(cd->flags&PSEUDO)) {
+	    newarc(nfa, type, co, from, to);
+	}
+    }
+}
+
+/*
+ - colorcomplement - add arcs of complementary colors
+ * The calling sequence ought to be reconciled with cloneouts().
+ ^ static void colorcomplement(struct nfa *, struct colormap *, int,
+ ^ 	struct state *, struct state *, struct state *);
+ */
+static void
+colorcomplement(
+    struct nfa *nfa,
+    struct colormap *cm,
+    int type,
+    struct state *of,		/* complements of this guy's PLAIN outarcs */
+    struct state *from,
+    struct state *to)
+{
+    struct colordesc *cd;
+    struct colordesc *end = CDEND(cm);
+    color co;
+
+    assert(of != from);
+    for (cd=cm->cd, co=0 ; cd<end && !CISERR() ; cd++, co++) {
+	if (!UNUSEDCOLOR(cd) && !(cd->flags&PSEUDO)) {
+	    if (findarc(of, PLAIN, co) == NULL) {
+		newarc(nfa, type, co, from, to);
+	    }
+	}
+    }
+}
+
+#ifdef REG_DEBUG
+/*
+ ^ #ifdef REG_DEBUG
+ */
+
+/*
+ - dumpcolors - debugging output
+ ^ static void dumpcolors(struct colormap *, FILE *);
+ */
+static void
+dumpcolors(
+    struct colormap *cm,
+    FILE *f)
+{
+    struct colordesc *cd;
+    struct colordesc *end;
+    color co;
+    chr c;
+    char *has;
+
+    fprintf(f, "max %ld\n", (long) cm->max);
+    if (NBYTS > 1) {
+	fillcheck(cm, cm->tree, 0, f);
+    }
+    end = CDEND(cm);
+    for (cd=cm->cd+1, co=1 ; cd<end ; cd++, co++) {	/* skip 0 */
+	if (!UNUSEDCOLOR(cd)) {
+	    assert(cd->nchrs > 0);
+	    has = (cd->block != NULL) ? "#" : "";
+	    if (cd->flags&PSEUDO) {
+		fprintf(f, "#%2ld%s(ps): ", (long) co, has);
+	    } else {
+		fprintf(f, "#%2ld%s(%2d): ", (long) co, has, cd->nchrs);
+	    }
+
+	    /*
+	     * Unfortunately, it's hard to do this next bit more efficiently.
+	     *
+	     * Spencer's original coding has the loop iterating from CHR_MIN
+	     * to CHR_MAX, but that's utterly unusable for 32-bit chr, or
+	     * even 16-bit.  For debugging purposes it seems fine to print
+	     * only chr codes up to 1000 or so.
+	     */
+
+	    for (c=CHR_MIN ; c<1000 ; c++) {
+		if (GETCOLOR(cm, c) == co) {
+		    dumpchr(c, f);
+		}
+	    }
+	    fprintf(f, "\n");
+	}
+    }
+}
+
+/*
+ - fillcheck - check proper filling of a tree
+ ^ static void fillcheck(struct colormap *, union tree *, int, FILE *);
+ */
+static void
+fillcheck(
+    struct colormap *cm,
+    union tree *tree,
+    int level,			/* level number (top == 0) of this block */
+    FILE *f)
+{
+    int i;
+    union tree *t;
+    union tree *fillt = &cm->tree[level+1];
+
+    assert(level < NBYTS-1);	/* this level has pointers */
+    for (i=BYTTAB-1 ; i>=0 ; i--) {
+	t = tree->tptr[i];
+	if (t == NULL) {
+	    fprintf(f, "NULL found in filled tree!\n");
+	} else if (t == fillt) {
+	    /* empty body */
+	} else if (level < NBYTS-2) {	/* more pointer blocks below */
+	    fillcheck(cm, t, level+1, f);
+	}
+    }
+}
+
+/*
+ - dumpchr - print a chr
+ * Kind of char-centric but works well enough for debug use.
+ ^ static void dumpchr(pchr, FILE *);
+ */
+static void
+dumpchr(
+    pchr c,
+    FILE *f)
+{
+    if (c == '\\') {
+	fprintf(f, "\\\\");
+    } else if (c > ' ' && c <= '~') {
+	putc((char) c, f);
+    } else {
+	fprintf(f, "\\u%04lx", (long) c);
+    }
+}
+
+/*
+ ^ #endif
+ */
+#endif				/* ifdef REG_DEBUG */
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/regc_cvec.c b/generic/regc_cvec.c
new file mode 100644
index 0000000..d450d3e
--- /dev/null
+++ b/generic/regc_cvec.c
@@ -0,0 +1,147 @@
+/*
+ * Utility functions for handling cvecs
+ * This file is #included by regcomp.c.
+ *
+ * Copyright (c) 1998, 1999 Henry Spencer.  All rights reserved.
+ *
+ * Development of this software was funded, in part, by Cray Research Inc.,
+ * UUNET Communications Services Inc., Sun Microsystems Inc., and Scriptics
+ * Corporation, none of whom are responsible for the results. The author
+ * thanks all of them.
+ *
+ * Redistribution and use in source and binary forms -- with or without
+ * modification -- are permitted for any purpose, provided that
+ * redistributions in source form retain this entire copyright notice and
+ * indicate the origin and nature of any modifications.
+ *
+ * I'd appreciate being given credit for this package in the documentation of
+ * software which uses it, but that is not a requirement.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * HENRY SPENCER BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Notes:
+ * Only (selected) functions in _this_ file should treat chr* as non-constant.
+ */
+
+/*
+ - newcvec - allocate a new cvec
+ ^ static struct cvec *newcvec(int, int);
+ */
+static struct cvec *
+newcvec(
+    int nchrs,			/* to hold this many chrs... */
+    int nranges)		/* ... and this many ranges... */
+{
+    size_t nc = (size_t)nchrs + (size_t)nranges*2;
+    size_t n = sizeof(struct cvec) + nc*sizeof(chr);
+    struct cvec *cv = (struct cvec *) MALLOC(n);
+
+    if (cv == NULL) {
+	return NULL;
+    }
+    cv->chrspace = nchrs;
+    cv->chrs = (chr *)(((char *)cv)+sizeof(struct cvec));
+    cv->ranges = cv->chrs + nchrs;
+    cv->rangespace = nranges;
+    return clearcvec(cv);
+}
+
+/*
+ - clearcvec - clear a possibly-new cvec
+ * Returns pointer as convenience.
+ ^ static struct cvec *clearcvec(struct cvec *);
+ */
+static struct cvec *
+clearcvec(
+    struct cvec *cv)		/* character vector */
+{
+    assert(cv != NULL);
+    cv->nchrs = 0;
+    cv->nranges = 0;
+    return cv;
+}
+
+/*
+ - addchr - add a chr to a cvec
+ ^ static void addchr(struct cvec *, pchr);
+ */
+static void
+addchr(
+    struct cvec *cv,		/* character vector */
+    pchr c)			/* character to add */
+{
+    assert(cv->nchrs < cv->chrspace);
+    cv->chrs[cv->nchrs++] = (chr)c;
+}
+
+/*
+ - addrange - add a range to a cvec
+ ^ static void addrange(struct cvec *, pchr, pchr);
+ */
+static void
+addrange(
+    struct cvec *cv,		/* character vector */
+    pchr from,			/* first character of range */
+    pchr to)			/* last character of range */
+{
+    assert(cv->nranges < cv->rangespace);
+    cv->ranges[cv->nranges*2] = (chr)from;
+    cv->ranges[cv->nranges*2 + 1] = (chr)to;
+    cv->nranges++;
+}
+
+/*
+ - getcvec - get a cvec, remembering it as v->cv
+ ^ static struct cvec *getcvec(struct vars *, int, int);
+ */
+static struct cvec *
+getcvec(
+    struct vars *v,		/* context */
+    int nchrs,			/* to hold this many chrs... */
+    int nranges)		/* ... and this many ranges... */
+{
+    if ((v->cv != NULL) && (nchrs <= v->cv->chrspace) &&
+	    (nranges <= v->cv->rangespace)) {
+	return clearcvec(v->cv);
+    }
+
+    if (v->cv != NULL) {
+	freecvec(v->cv);
+    }
+    v->cv = newcvec(nchrs, nranges);
+    if (v->cv == NULL) {
+	ERR(REG_ESPACE);
+    }
+
+    return v->cv;
+}
+
+/*
+ - freecvec - free a cvec
+ ^ static void freecvec(struct cvec *);
+ */
+static void
+freecvec(
+    struct cvec *cv)		/* character vector */
+{
+    FREE(cv);
+}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/regc_lex.c b/generic/regc_lex.c
new file mode 100644
index 0000000..affcb48
--- /dev/null
+++ b/generic/regc_lex.c
@@ -0,0 +1,1195 @@
+/*
+ * lexical analyzer
+ * This file is #included by regcomp.c.
+ *
+ * Copyright (c) 1998, 1999 Henry Spencer.  All rights reserved.
+ *
+ * Development of this software was funded, in part, by Cray Research Inc.,
+ * UUNET Communications Services Inc., Sun Microsystems Inc., and Scriptics
+ * Corporation, none of whom are responsible for the results.  The author
+ * thanks all of them.
+ *
+ * Redistribution and use in source and binary forms -- with or without
+ * modification -- are permitted for any purpose, provided that
+ * redistributions in source form retain this entire copyright notice and
+ * indicate the origin and nature of any modifications.
+ *
+ * I'd appreciate being given credit for this package in the documentation of
+ * software which uses it, but that is not a requirement.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * HENRY SPENCER BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* scanning macros (know about v) */
+#define	ATEOS()		(v->now >= v->stop)
+#define	HAVE(n)		(v->stop - v->now >= (n))
+#define	NEXT1(c)	(!ATEOS() && *v->now == CHR(c))
+#define	NEXT2(a,b)	(HAVE(2) && *v->now == CHR(a) && *(v->now+1) == CHR(b))
+#define	NEXT3(a,b,c) \
+	(HAVE(3) && *v->now == CHR(a) && \
+		*(v->now+1) == CHR(b) && \
+		*(v->now+2) == CHR(c))
+#define	SET(c)		(v->nexttype = (c))
+#define	SETV(c, n)	(v->nexttype = (c), v->nextvalue = (n))
+#define	RET(c)		return (SET(c), 1)
+#define	RETV(c, n)	return (SETV(c, n), 1)
+#define	FAILW(e)	return (ERR(e), 0)	/* ERR does SET(EOS) */
+#define	LASTTYPE(t)	(v->lasttype == (t))
+
+/* lexical contexts */
+#define	L_ERE	1	/* mainline ERE/ARE */
+#define	L_BRE	2	/* mainline BRE */
+#define	L_Q	3	/* REG_QUOTE */
+#define	L_EBND	4	/* ERE/ARE bound */
+#define	L_BBND	5	/* BRE bound */
+#define	L_BRACK	6	/* brackets */
+#define	L_CEL	7	/* collating element */
+#define	L_ECL	8	/* equivalence class */
+#define	L_CCL	9	/* character class */
+#define	INTOCON(c)	(v->lexcon = (c))
+#define	INCON(con)	(v->lexcon == (con))
+
+/* construct pointer past end of chr array */
+#define	ENDOF(array)	((array) + sizeof(array)/sizeof(chr))
+
+/*
+ - lexstart - set up lexical stuff, scan leading options
+ ^ static void lexstart(struct vars *);
+ */
+static void
+lexstart(
+    struct vars *v)
+{
+    prefixes(v);		/* may turn on new type bits etc. */
+    NOERR();
+
+    if (v->cflags&REG_QUOTE) {
+	assert(!(v->cflags&(REG_ADVANCED|REG_EXPANDED|REG_NEWLINE)));
+	INTOCON(L_Q);
+    } else if (v->cflags&REG_EXTENDED) {
+	assert(!(v->cflags&REG_QUOTE));
+	INTOCON(L_ERE);
+    } else {
+	assert(!(v->cflags&(REG_QUOTE|REG_ADVF)));
+	INTOCON(L_BRE);
+    }
+
+    v->nexttype = EMPTY;	/* remember we were at the start */
+    next(v);			/* set up the first token */
+}
+
+/*
+ - prefixes - implement various special prefixes
+ ^ static void prefixes(struct vars *);
+ */
+static void
+prefixes(
+    struct vars *v)
+{
+    /*
+     * Literal string doesn't get any of this stuff.
+     */
+
+    if (v->cflags&REG_QUOTE) {
+	return;
+    }
+
+    /*
+     * Initial "***" gets special things.
+     */
+
+    if (HAVE(4) && NEXT3('*', '*', '*')) {
+	switch (*(v->now + 3)) {
+	case CHR('?'):		/* "***?" error, msg shows version */
+	    ERR(REG_BADPAT);
+	    return;		/* proceed no further */
+	    break;
+	case CHR('='):		/* "***=" shifts to literal string */
+	    NOTE(REG_UNONPOSIX);
+	    v->cflags |= REG_QUOTE;
+	    v->cflags &= ~(REG_ADVANCED|REG_EXPANDED|REG_NEWLINE);
+	    v->now += 4;
+	    return;		/* and there can be no more prefixes */
+	    break;
+	case CHR(':'):		/* "***:" shifts to AREs */
+	    NOTE(REG_UNONPOSIX);
+	    v->cflags |= REG_ADVANCED;
+	    v->now += 4;
+	    break;
+	default:		/* otherwise *** is just an error */
+	    ERR(REG_BADRPT);
+	    return;
+	    break;
+	}
+    }
+
+    /*
+     * BREs and EREs don't get embedded options.
+     */
+
+    if ((v->cflags&REG_ADVANCED) != REG_ADVANCED) {
+	return;
+    }
+
+    /*
+     * Embedded options (AREs only).
+     */
+
+    if (HAVE(3) && NEXT2('(', '?') && iscalpha(*(v->now + 2))) {
+	NOTE(REG_UNONPOSIX);
+	v->now += 2;
+	for (; !ATEOS() && iscalpha(*v->now); v->now++) {
+	    switch (*v->now) {
+	    case CHR('b'):	/* BREs (but why???) */
+		v->cflags &= ~(REG_ADVANCED|REG_QUOTE);
+		break;
+	    case CHR('c'):	/* case sensitive */
+		v->cflags &= ~REG_ICASE;
+		break;
+	    case CHR('e'):	/* plain EREs */
+		v->cflags |= REG_EXTENDED;
+		v->cflags &= ~(REG_ADVF|REG_QUOTE);
+		break;
+	    case CHR('i'):	/* case insensitive */
+		v->cflags |= REG_ICASE;
+		break;
+	    case CHR('m'):	/* Perloid synonym for n */
+	    case CHR('n'):	/* \n affects ^ $ . [^ */
+		v->cflags |= REG_NEWLINE;
+		break;
+	    case CHR('p'):	/* ~Perl, \n affects . [^ */
+		v->cflags |= REG_NLSTOP;
+		v->cflags &= ~REG_NLANCH;
+		break;
+	    case CHR('q'):	/* literal string */
+		v->cflags |= REG_QUOTE;
+		v->cflags &= ~REG_ADVANCED;
+		break;
+	    case CHR('s'):	/* single line, \n ordinary */
+		v->cflags &= ~REG_NEWLINE;
+		break;
+	    case CHR('t'):	/* tight syntax */
+		v->cflags &= ~REG_EXPANDED;
+		break;
+	    case CHR('w'):	/* weird, \n affects ^ $ only */
+		v->cflags &= ~REG_NLSTOP;
+		v->cflags |= REG_NLANCH;
+		break;
+	    case CHR('x'):	/* expanded syntax */
+		v->cflags |= REG_EXPANDED;
+		break;
+	    default:
+		ERR(REG_BADOPT);
+		return;
+	    }
+	}
+	if (!NEXT1(')')) {
+	    ERR(REG_BADOPT);
+	    return;
+	}
+	v->now++;
+	if (v->cflags&REG_QUOTE) {
+	    v->cflags &= ~(REG_EXPANDED|REG_NEWLINE);
+	}
+    }
+}
+
+/*
+ - lexnest - "call a subroutine", interpolating string at the lexical level
+ * Note, this is not a very general facility.  There are a number of
+ * implicit assumptions about what sorts of strings can be subroutines.
+ ^ static void lexnest(struct vars *, const chr *, const chr *);
+ */
+static void
+lexnest(
+    struct vars *v,
+    const chr *beginp,		/* start of interpolation */
+    const chr *endp)		/* one past end of interpolation */
+{
+    assert(v->savenow == NULL);	/* only one level of nesting */
+    v->savenow = v->now;
+    v->savestop = v->stop;
+    v->now = beginp;
+    v->stop = endp;
+}
+
+/*
+ * string constants to interpolate as expansions of things like \d
+ */
+
+static const chr backd[] = {	/* \d */
+    CHR('['), CHR('['), CHR(':'),
+    CHR('d'), CHR('i'), CHR('g'), CHR('i'), CHR('t'),
+    CHR(':'), CHR(']'), CHR(']')
+};
+static const chr backD[] = {	/* \D */
+    CHR('['), CHR('^'), CHR('['), CHR(':'),
+    CHR('d'), CHR('i'), CHR('g'), CHR('i'), CHR('t'),
+    CHR(':'), CHR(']'), CHR(']')
+};
+static const chr brbackd[] = {	/* \d within brackets */
+    CHR('['), CHR(':'),
+    CHR('d'), CHR('i'), CHR('g'), CHR('i'), CHR('t'),
+    CHR(':'), CHR(']')
+};
+static const chr backs[] = {	/* \s */
+    CHR('['), CHR('['), CHR(':'),
+    CHR('s'), CHR('p'), CHR('a'), CHR('c'), CHR('e'),
+    CHR(':'), CHR(']'), CHR(']')
+};
+static const chr backS[] = {	/* \S */
+    CHR('['), CHR('^'), CHR('['), CHR(':'),
+    CHR('s'), CHR('p'), CHR('a'), CHR('c'), CHR('e'),
+    CHR(':'), CHR(']'), CHR(']')
+};
+static const chr brbacks[] = {	/* \s within brackets */
+    CHR('['), CHR(':'),
+    CHR('s'), CHR('p'), CHR('a'), CHR('c'), CHR('e'),
+    CHR(':'), CHR(']')
+};
+
+#define PUNCT_CONN \
+	CHR('_'), \
+	0x203f /* UNDERTIE */, \
+	0x2040 /* CHARACTER TIE */,\
+	0x2054 /* INVERTED UNDERTIE */,\
+	0xfe33 /* PRESENTATION FORM FOR VERTICAL LOW LINE */, \
+	0xfe34 /* PRESENTATION FORM FOR VERTICAL WAVY LOW LINE */, \
+	0xfe4d /* DASHED LOW LINE */, \
+	0xfe4e /* CENTRELINE LOW LINE */, \
+	0xfe4f /* WAVY LOW LINE */, \
+	0xff3f /* FULLWIDTH LOW LINE */
+
+static const chr backw[] = {	/* \w */
+    CHR('['), CHR('['), CHR(':'),
+    CHR('a'), CHR('l'), CHR('n'), CHR('u'), CHR('m'),
+    CHR(':'), CHR(']'), PUNCT_CONN, CHR(']')
+};
+static const chr backW[] = {	/* \W */
+    CHR('['), CHR('^'), CHR('['), CHR(':'),
+    CHR('a'), CHR('l'), CHR('n'), CHR('u'), CHR('m'),
+    CHR(':'), CHR(']'), PUNCT_CONN, CHR(']')
+};
+static const chr brbackw[] = {	/* \w within brackets */
+    CHR('['), CHR(':'),
+    CHR('a'), CHR('l'), CHR('n'), CHR('u'), CHR('m'),
+    CHR(':'), CHR(']'), PUNCT_CONN
+};
+
+/*
+ - lexword - interpolate a bracket expression for word characters
+ * Possibly ought to inquire whether there is a "word" character class.
+ ^ static void lexword(struct vars *);
+ */
+static void
+lexword(
+    struct vars *v)
+{
+    lexnest(v, backw, ENDOF(backw));
+}
+
+/*
+ - next - get next token
+ ^ static int next(struct vars *);
+ */
+static int			/* 1 normal, 0 failure */
+next(
+    struct vars *v)
+{
+    chr c;
+
+    /*
+     * Errors yield an infinite sequence of failures.
+     */
+
+    if (ISERR()) {
+	return 0;		/* the error has set nexttype to EOS */
+    }
+
+    /*
+     * Remember flavor of last token.
+     */
+
+    v->lasttype = v->nexttype;
+
+    /*
+     * REG_BOSONLY
+     */
+
+    if (v->nexttype == EMPTY && (v->cflags&REG_BOSONLY)) {
+	/* at start of a REG_BOSONLY RE */
+	RETV(SBEGIN, 0);	/* same as \A */
+    }
+
+    /*
+     * If we're nested and we've hit end, return to outer level.
+     */
+
+    if (v->savenow != NULL && ATEOS()) {
+	v->now = v->savenow;
+	v->stop = v->savestop;
+	v->savenow = v->savestop = NULL;
+    }
+
+    /*
+     * Skip white space etc. if appropriate (not in literal or [])
+     */
+
+    if (v->cflags&REG_EXPANDED) {
+	switch (v->lexcon) {
+	case L_ERE:
+	case L_BRE:
+	case L_EBND:
+	case L_BBND:
+	    skip(v);
+	    break;
+	}
+    }
+
+    /*
+     * Handle EOS, depending on context.
+     */
+
+    if (ATEOS()) {
+	switch (v->lexcon) {
+	case L_ERE:
+	case L_BRE:
+	case L_Q:
+	    RET(EOS);
+	    break;
+	case L_EBND:
+	case L_BBND:
+	    FAILW(REG_EBRACE);
+	    break;
+	case L_BRACK:
+	case L_CEL:
+	case L_ECL:
+	case L_CCL:
+	    FAILW(REG_EBRACK);
+	    break;
+	}
+	assert(NOTREACHED);
+    }
+
+    /*
+     * Okay, time to actually get a character.
+     */
+
+    c = *v->now++;
+
+    /*
+     * Deal with the easy contexts, punt EREs to code below.
+     */
+
+    switch (v->lexcon) {
+    case L_BRE:			/* punt BREs to separate function */
+	return brenext(v, c);
+	break;
+    case L_ERE:			/* see below */
+	break;
+    case L_Q:			/* literal strings are easy */
+	RETV(PLAIN, c);
+	break;
+    case L_BBND:		/* bounds are fairly simple */
+    case L_EBND:
+	switch (c) {
+	case CHR('0'): case CHR('1'): case CHR('2'): case CHR('3'):
+	case CHR('4'): case CHR('5'): case CHR('6'): case CHR('7'):
+	case CHR('8'): case CHR('9'):
+	    RETV(DIGIT, (chr)DIGITVAL(c));
+	    break;
+	case CHR(','):
+	    RET(',');
+	    break;
+	case CHR('}'):		/* ERE bound ends with } */
+	    if (INCON(L_EBND)) {
+		INTOCON(L_ERE);
+		if ((v->cflags&REG_ADVF) && NEXT1('?')) {
+		    v->now++;
+		    NOTE(REG_UNONPOSIX);
+		    RETV('}', 0);
+		}
+		RETV('}', 1);
+	    } else {
+		FAILW(REG_BADBR);
+	    }
+	    break;
+	case CHR('\\'):		/* BRE bound ends with \} */
+	    if (INCON(L_BBND) && NEXT1('}')) {
+		v->now++;
+		INTOCON(L_BRE);
+		RET('}');
+	    } else {
+		FAILW(REG_BADBR);
+	    }
+	    break;
+	default:
+	    FAILW(REG_BADBR);
+	    break;
+	}
+	assert(NOTREACHED);
+	break;
+    case L_BRACK:		/* brackets are not too hard */
+	switch (c) {
+	case CHR(']'):
+	    if (LASTTYPE('[')) {
+		RETV(PLAIN, c);
+	    } else {
+		INTOCON((v->cflags&REG_EXTENDED) ? L_ERE : L_BRE);
+		RET(']');
+	    }
+	    break;
+	case CHR('\\'):
+	    NOTE(REG_UBBS);
+	    if (!(v->cflags&REG_ADVF)) {
+		RETV(PLAIN, c);
+	    }
+	    NOTE(REG_UNONPOSIX);
+	    if (ATEOS()) {
+		FAILW(REG_EESCAPE);
+	    }
+	    (DISCARD)lexescape(v);
+	    switch (v->nexttype) {	/* not all escapes okay here */
+	    case PLAIN:
+		return 1;
+		break;
+	    case CCLASS:
+		switch (v->nextvalue) {
+		case 'd':
+		    lexnest(v, brbackd, ENDOF(brbackd));
+		    break;
+		case 's':
+		    lexnest(v, brbacks, ENDOF(brbacks));
+		    break;
+		case 'w':
+		    lexnest(v, brbackw, ENDOF(brbackw));
+		    break;
+		default:
+		    FAILW(REG_EESCAPE);
+		    break;
+		}
+
+		/*
+		 * lexnest() done, back up and try again.
+		 */
+
+		v->nexttype = v->lasttype;
+		return next(v);
+		break;
+	    }
+
+	    /*
+	     * Not one of the acceptable escapes.
+	     */
+
+	    FAILW(REG_EESCAPE);
+	    break;
+	case CHR('-'):
+	    if (LASTTYPE('[') || NEXT1(']')) {
+		RETV(PLAIN, c);
+	    } else {
+		RETV(RANGE, c);
+	    }
+	    break;
+	case CHR('['):
+	    if (ATEOS()) {
+		FAILW(REG_EBRACK);
+	    }
+	    switch (*v->now++) {
+	    case CHR('.'):
+		INTOCON(L_CEL);
+
+		/*
+		 * Might or might not be locale-specific.
+		 */
+
+		RET(COLLEL);
+		break;
+	    case CHR('='):
+		INTOCON(L_ECL);
+		NOTE(REG_ULOCALE);
+		RET(ECLASS);
+		break;
+	    case CHR(':'):
+		INTOCON(L_CCL);
+		NOTE(REG_ULOCALE);
+		RET(CCLASS);
+		break;
+	    default:		/* oops */
+		v->now--;
+		RETV(PLAIN, c);
+		break;
+	    }
+	    assert(NOTREACHED);
+	    break;
+	default:
+	    RETV(PLAIN, c);
+	    break;
+	}
+	assert(NOTREACHED);
+	break;
+    case L_CEL:			/* collating elements are easy */
+	if (c == CHR('.') && NEXT1(']')) {
+	    v->now++;
+	    INTOCON(L_BRACK);
+	    RETV(END, '.');
+	} else {
+	    RETV(PLAIN, c);
+	}
+	break;
+    case L_ECL:			/* ditto equivalence classes */
+	if (c == CHR('=') && NEXT1(']')) {
+	    v->now++;
+	    INTOCON(L_BRACK);
+	    RETV(END, '=');
+	} else {
+	    RETV(PLAIN, c);
+	}
+	break;
+    case L_CCL:			/* ditto character classes */
+	if (c == CHR(':') && NEXT1(']')) {
+	    v->now++;
+	    INTOCON(L_BRACK);
+	    RETV(END, ':');
+	} else {
+	    RETV(PLAIN, c);
+	}
+	break;
+    default:
+	assert(NOTREACHED);
+	break;
+    }
+
+    /*
+     * That got rid of everything except EREs and AREs.
+     */
+
+    assert(INCON(L_ERE));
+
+    /*
+     * Deal with EREs and AREs, except for backslashes.
+     */
+
+    switch (c) {
+    case CHR('|'):
+	RET('|');
+	break;
+    case CHR('*'):
+	if ((v->cflags&REG_ADVF) && NEXT1('?')) {
+	    v->now++;
+	    NOTE(REG_UNONPOSIX);
+	    RETV('*', 0);
+	}
+	RETV('*', 1);
+	break;
+    case CHR('+'):
+	if ((v->cflags&REG_ADVF) && NEXT1('?')) {
+	    v->now++;
+	    NOTE(REG_UNONPOSIX);
+	    RETV('+', 0);
+	}
+	RETV('+', 1);
+	break;
+    case CHR('?'):
+	if ((v->cflags&REG_ADVF) && NEXT1('?')) {
+	    v->now++;
+	    NOTE(REG_UNONPOSIX);
+	    RETV('?', 0);
+	}
+	RETV('?', 1);
+	break;
+    case CHR('{'):		/* bounds start or plain character */
+	if (v->cflags&REG_EXPANDED) {
+	    skip(v);
+	}
+	if (ATEOS() || !iscdigit(*v->now)) {
+	    NOTE(REG_UBRACES);
+	    NOTE(REG_UUNSPEC);
+	    RETV(PLAIN, c);
+	} else {
+	    NOTE(REG_UBOUNDS);
+	    INTOCON(L_EBND);
+	    RET('{');
+	}
+	assert(NOTREACHED);
+	break;
+    case CHR('('):		/* parenthesis, or advanced extension */
+	if ((v->cflags&REG_ADVF) && NEXT1('?')) {
+	    NOTE(REG_UNONPOSIX);
+	    v->now++;
+	    switch (*v->now++) {
+	    case CHR(':'):	/* non-capturing paren */
+		RETV('(', 0);
+		break;
+	    case CHR('#'):	/* comment */
+		while (!ATEOS() && *v->now != CHR(')')) {
+		    v->now++;
+		}
+		if (!ATEOS()) {
+		    v->now++;
+		}
+		assert(v->nexttype == v->lasttype);
+		return next(v);
+		break;
+	    case CHR('='):	/* positive lookahead */
+		NOTE(REG_ULOOKAHEAD);
+		RETV(LACON, 1);
+		break;
+	    case CHR('!'):	/* negative lookahead */
+		NOTE(REG_ULOOKAHEAD);
+		RETV(LACON, 0);
+		break;
+	    default:
+		FAILW(REG_BADRPT);
+		break;
+	    }
+	    assert(NOTREACHED);
+	}
+	if (v->cflags&REG_NOSUB) {
+	    RETV('(', 0);	/* all parens non-capturing */
+	} else {
+	    RETV('(', 1);
+	}
+	break;
+    case CHR(')'):
+	if (LASTTYPE('(')) {
+	    NOTE(REG_UUNSPEC);
+	}
+	RETV(')', c);
+	break;
+    case CHR('['):		/* easy except for [[:<:]] and [[:>:]] */
+	if (HAVE(6) &&	*(v->now+0) == CHR('[') &&
+		*(v->now+1) == CHR(':') &&
+		(*(v->now+2) == CHR('<') || *(v->now+2) == CHR('>')) &&
+		*(v->now+3) == CHR(':') &&
+		*(v->now+4) == CHR(']') &&
+		*(v->now+5) == CHR(']')) {
+	    c = *(v->now+2);
+	    v->now += 6;
+	    NOTE(REG_UNONPOSIX);
+	    RET((c == CHR('<')) ? '<' : '>');
+	}
+	INTOCON(L_BRACK);
+	if (NEXT1('^')) {
+	    v->now++;
+	    RETV('[', 0);
+	}
+	RETV('[', 1);
+	break;
+    case CHR('.'):
+	RET('.');
+	break;
+    case CHR('^'):
+	RET('^');
+	break;
+    case CHR('$'):
+	RET('$');
+	break;
+    case CHR('\\'):		/* mostly punt backslashes to code below */
+	if (ATEOS()) {
+	    FAILW(REG_EESCAPE);
+	}
+	break;
+    default:		/* ordinary character */
+	RETV(PLAIN, c);
+	break;
+    }
+
+    /*
+     * ERE/ARE backslash handling; backslash already eaten.
+     */
+
+    assert(!ATEOS());
+    if (!(v->cflags&REG_ADVF)) {/* only AREs have non-trivial escapes */
+	if (iscalnum(*v->now)) {
+	    NOTE(REG_UBSALNUM);
+	    NOTE(REG_UUNSPEC);
+	}
+	RETV(PLAIN, *v->now++);
+    }
+    (DISCARD)lexescape(v);
+    if (ISERR()) {
+	FAILW(REG_EESCAPE);
+    }
+    if (v->nexttype == CCLASS) {/* fudge at lexical level */
+	switch (v->nextvalue) {
+	case 'd':	lexnest(v, backd, ENDOF(backd)); break;
+	case 'D':	lexnest(v, backD, ENDOF(backD)); break;
+	case 's':	lexnest(v, backs, ENDOF(backs)); break;
+	case 'S':	lexnest(v, backS, ENDOF(backS)); break;
+	case 'w':	lexnest(v, backw, ENDOF(backw)); break;
+	case 'W':	lexnest(v, backW, ENDOF(backW)); break;
+	default:
+	    assert(NOTREACHED);
+	    FAILW(REG_ASSERT);
+	    break;
+	}
+	/* lexnest done, back up and try again */
+	v->nexttype = v->lasttype;
+	return next(v);
+    }
+
+    /*
+     * Otherwise, lexescape has already done the work.
+     */
+
+    return !ISERR();
+}
+
+/*
+ - lexescape - parse an ARE backslash escape (backslash already eaten)
+ * Note slightly nonstandard use of the CCLASS type code.
+ ^ static int lexescape(struct vars *);
+ */
+static int			/* not actually used, but convenient for RETV */
+lexescape(
+    struct vars *v)
+{
+    chr c;
+    int i;
+    static const chr alert[] = {
+	CHR('a'), CHR('l'), CHR('e'), CHR('r'), CHR('t')
+    };
+    static const chr esc[] = {
+	CHR('E'), CHR('S'), CHR('C')
+    };
+    const chr *save;
+
+    assert(v->cflags&REG_ADVF);
+
+    assert(!ATEOS());
+    c = *v->now++;
+    if (!iscalnum(c)) {
+	RETV(PLAIN, c);
+    }
+
+    NOTE(REG_UNONPOSIX);
+    switch (c) {
+    case CHR('a'):
+	RETV(PLAIN, chrnamed(v, alert, ENDOF(alert), CHR('\007')));
+	break;
+    case CHR('A'):
+	RETV(SBEGIN, 0);
+	break;
+    case CHR('b'):
+	RETV(PLAIN, CHR('\b'));
+	break;
+    case CHR('B'):
+	RETV(PLAIN, CHR('\\'));
+	break;
+    case CHR('c'):
+	NOTE(REG_UUNPORT);
+	if (ATEOS()) {
+	    FAILW(REG_EESCAPE);
+	}
+	RETV(PLAIN, (chr)(*v->now++ & 037));
+	break;
+    case CHR('d'):
+	NOTE(REG_ULOCALE);
+	RETV(CCLASS, 'd');
+	break;
+    case CHR('D'):
+	NOTE(REG_ULOCALE);
+	RETV(CCLASS, 'D');
+	break;
+    case CHR('e'):
+	NOTE(REG_UUNPORT);
+	RETV(PLAIN, chrnamed(v, esc, ENDOF(esc), CHR('\033')));
+	break;
+    case CHR('f'):
+	RETV(PLAIN, CHR('\f'));
+	break;
+    case CHR('m'):
+	RET('<');
+	break;
+    case CHR('M'):
+	RET('>');
+	break;
+    case CHR('n'):
+	RETV(PLAIN, CHR('\n'));
+	break;
+    case CHR('r'):
+	RETV(PLAIN, CHR('\r'));
+	break;
+    case CHR('s'):
+	NOTE(REG_ULOCALE);
+	RETV(CCLASS, 's');
+	break;
+    case CHR('S'):
+	NOTE(REG_ULOCALE);
+	RETV(CCLASS, 'S');
+	break;
+    case CHR('t'):
+	RETV(PLAIN, CHR('\t'));
+	break;
+    case CHR('u'):
+	c = (uchr) lexdigits(v, 16, 1, 4);
+	if (ISERR()) {
+	    FAILW(REG_EESCAPE);
+	}
+	RETV(PLAIN, c);
+	break;
+    case CHR('U'):
+	i = lexdigits(v, 16, 1, 8);
+	if (ISERR()) {
+	    FAILW(REG_EESCAPE);
+	}
+	if (i > 0xFFFF) {
+	    /* TODO: output a Surrogate pair
+	     */
+	    i = 0xFFFD;
+	}
+	RETV(PLAIN, (uchr) i);
+	break;
+    case CHR('v'):
+	RETV(PLAIN, CHR('\v'));
+	break;
+    case CHR('w'):
+	NOTE(REG_ULOCALE);
+	RETV(CCLASS, 'w');
+	break;
+    case CHR('W'):
+	NOTE(REG_ULOCALE);
+	RETV(CCLASS, 'W');
+	break;
+    case CHR('x'):
+	NOTE(REG_UUNPORT);
+	c = (uchr) lexdigits(v, 16, 1, 2);
+	if (ISERR()) {
+	    FAILW(REG_EESCAPE);
+	}
+	RETV(PLAIN, c);
+	break;
+    case CHR('y'):
+	NOTE(REG_ULOCALE);
+	RETV(WBDRY, 0);
+	break;
+    case CHR('Y'):
+	NOTE(REG_ULOCALE);
+	RETV(NWBDRY, 0);
+	break;
+    case CHR('Z'):
+	RETV(SEND, 0);
+	break;
+    case CHR('1'): case CHR('2'): case CHR('3'): case CHR('4'):
+    case CHR('5'): case CHR('6'): case CHR('7'): case CHR('8'):
+    case CHR('9'):
+	save = v->now;
+	v->now--;		/* put first digit back */
+	c = (uchr) lexdigits(v, 10, 1, 255);	/* REs >255 long outside spec */
+	if (ISERR()) {
+	    FAILW(REG_EESCAPE);
+	}
+
+	/*
+	 * Ugly heuristic (first test is "exactly 1 digit?")
+	 */
+
+	if (v->now - save == 0 || ((int) c > 0 && (int)c <= v->nsubexp)) {
+	    NOTE(REG_UBACKREF);
+	    RETV(BACKREF, (chr)c);
+	}
+
+	/*
+	 * Oops, doesn't look like it's a backref after all...
+	 */
+
+	v->now = save;
+
+	/*
+	 * And fall through into octal number.
+	 */
+
+    case CHR('0'):
+	NOTE(REG_UUNPORT);
+	v->now--;		/* put first digit back */
+	c = (uchr) lexdigits(v, 8, 1, 3);
+	if (ISERR()) {
+	    FAILW(REG_EESCAPE);
+	}
+	if (c > 0xff) {
+	    /* out of range, so we handled one digit too much */
+	    v->now--;
+	    c >>= 3;
+	}
+	RETV(PLAIN, c);
+	break;
+    default:
+	assert(iscalpha(c));
+	FAILW(REG_EESCAPE);	/* unknown alphabetic escape */
+	break;
+    }
+    assert(NOTREACHED);
+}
+
+/*
+ - lexdigits - slurp up digits and return chr value
+ ^ static int lexdigits(struct vars *, int, int, int);
+ */
+static int			/* chr value; errors signalled via ERR */
+lexdigits(
+    struct vars *v,
+    int base,
+    int minlen,
+    int maxlen)
+{
+    int n;
+    int len;
+    chr c;
+    int d;
+    const uchr ub = (uchr) base;
+
+    n = 0;
+    for (len = 0; len < maxlen && !ATEOS(); len++) {
+	if (n > 0x10fff) {
+	    /* Stop when continuing would otherwise overflow */
+	    break;
+	}
+	c = *v->now++;
+	switch (c) {
+	case CHR('0'): case CHR('1'): case CHR('2'): case CHR('3'):
+	case CHR('4'): case CHR('5'): case CHR('6'): case CHR('7'):
+	case CHR('8'): case CHR('9'):
+	    d = DIGITVAL(c);
+	    break;
+	case CHR('a'): case CHR('A'): d = 10; break;
+	case CHR('b'): case CHR('B'): d = 11; break;
+	case CHR('c'): case CHR('C'): d = 12; break;
+	case CHR('d'): case CHR('D'): d = 13; break;
+	case CHR('e'): case CHR('E'): d = 14; break;
+	case CHR('f'): case CHR('F'): d = 15; break;
+	default:
+	    v->now--;		/* oops, not a digit at all */
+	    d = -1;
+	    break;
+	}
+
+	if (d >= base) {	/* not a plausible digit */
+	    v->now--;
+	    d = -1;
+	}
+	if (d < 0) {
+	    break;		/* NOTE BREAK OUT */
+	}
+	n = n*ub + (uchr)d;
+    }
+    if (len < minlen) {
+	ERR(REG_EESCAPE);
+    }
+
+    return n;
+}
+
+/*
+ - brenext - get next BRE token
+ * This is much like EREs except for all the stupid backslashes and the
+ * context-dependency of some things.
+ ^ static int brenext(struct vars *, pchr);
+ */
+static int			/* 1 normal, 0 failure */
+brenext(
+    struct vars *v,
+    pchr pc)
+{
+    chr c = (chr)pc;
+
+    switch (c) {
+    case CHR('*'):
+	if (LASTTYPE(EMPTY) || LASTTYPE('(') || LASTTYPE('^')) {
+	    RETV(PLAIN, c);
+	}
+	RET('*');
+	break;
+    case CHR('['):
+	if (HAVE(6) &&	*(v->now+0) == CHR('[') &&
+		*(v->now+1) == CHR(':') &&
+		(*(v->now+2) == CHR('<') || *(v->now+2) == CHR('>')) &&
+		*(v->now+3) == CHR(':') &&
+		*(v->now+4) == CHR(']') &&
+		*(v->now+5) == CHR(']')) {
+	    c = *(v->now+2);
+	    v->now += 6;
+	    NOTE(REG_UNONPOSIX);
+	    RET((c == CHR('<')) ? '<' : '>');
+	}
+	INTOCON(L_BRACK);
+	if (NEXT1('^')) {
+	    v->now++;
+	    RETV('[', 0);
+	}
+	RETV('[', 1);
+	break;
+    case CHR('.'):
+	RET('.');
+	break;
+    case CHR('^'):
+	if (LASTTYPE(EMPTY)) {
+	    RET('^');
+	}
+	if (LASTTYPE('(')) {
+	    NOTE(REG_UUNSPEC);
+	    RET('^');
+	}
+	RETV(PLAIN, c);
+	break;
+    case CHR('$'):
+	if (v->cflags&REG_EXPANDED) {
+	    skip(v);
+	}
+	if (ATEOS()) {
+	    RET('$');
+	}
+	if (NEXT2('\\', ')')) {
+	    NOTE(REG_UUNSPEC);
+	    RET('$');
+	}
+	RETV(PLAIN, c);
+	break;
+    case CHR('\\'):
+	break;			/* see below */
+    default:
+	RETV(PLAIN, c);
+	break;
+    }
+
+    assert(c == CHR('\\'));
+
+    if (ATEOS()) {
+	FAILW(REG_EESCAPE);
+    }
+
+    c = *v->now++;
+    switch (c) {
+    case CHR('{'):
+	INTOCON(L_BBND);
+	NOTE(REG_UBOUNDS);
+	RET('{');
+	break;
+    case CHR('('):
+	RETV('(', 1);
+	break;
+    case CHR(')'):
+	RETV(')', c);
+	break;
+    case CHR('<'):
+	NOTE(REG_UNONPOSIX);
+	RET('<');
+	break;
+    case CHR('>'):
+	NOTE(REG_UNONPOSIX);
+	RET('>');
+	break;
+    case CHR('1'): case CHR('2'): case CHR('3'): case CHR('4'):
+    case CHR('5'): case CHR('6'): case CHR('7'): case CHR('8'):
+    case CHR('9'):
+	NOTE(REG_UBACKREF);
+	RETV(BACKREF, (chr)DIGITVAL(c));
+	break;
+    default:
+	if (iscalnum(c)) {
+	    NOTE(REG_UBSALNUM);
+	    NOTE(REG_UUNSPEC);
+	}
+	RETV(PLAIN, c);
+	break;
+    }
+
+    assert(NOTREACHED);
+}
+
+/*
+ - skip - skip white space and comments in expanded form
+ ^ static void skip(struct vars *);
+ */
+static void
+skip(
+    struct vars *v)
+{
+    const chr *start = v->now;
+
+    assert(v->cflags&REG_EXPANDED);
+
+    for (;;) {
+	while (!ATEOS() && iscspace(*v->now)) {
+	    v->now++;
+	}
+	if (ATEOS() || *v->now != CHR('#')) {
+	    break;		/* NOTE BREAK OUT */
+	}
+	assert(NEXT1('#'));
+	while (!ATEOS() && *v->now != CHR('\n')) {
+	    v->now++;
+	}
+
+	/*
+	 * Leave the newline to be picked up by the iscspace loop.
+	 */
+    }
+
+    if (v->now != start) {
+	NOTE(REG_UNONPOSIX);
+    }
+}
+
+/*
+ - newline - return the chr for a newline
+ * This helps confine use of CHR to this source file.
+ ^ static chr newline(NOPARMS);
+ */
+static chr
+newline(void)
+{
+    return CHR('\n');
+}
+
+/*
+ - chrnamed - return the chr known by a given (chr string) name
+ * The code is a bit clumsy, but this routine gets only such specialized
+ * use that it hardly matters.
+ ^ static chr chrnamed(struct vars *, const chr *, const chr *, pchr);
+ */
+static chr
+chrnamed(
+    struct vars *v,
+    const chr *startp,		/* start of name */
+    const chr *endp,		/* just past end of name */
+    pchr lastresort)		/* what to return if name lookup fails */
+{
+    celt c;
+    int errsave;
+    int e;
+    struct cvec *cv;
+
+    errsave = v->err;
+    v->err = 0;
+    c = element(v, startp, endp);
+    e = v->err;
+    v->err = errsave;
+
+    if (e != 0) {
+	return (chr)lastresort;
+    }
+
+    cv = range(v, c, c, 0);
+    if (cv->nchrs == 0) {
+	return (chr)lastresort;
+    }
+    return cv->chrs[0];
+}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/regc_locale.c b/generic/regc_locale.c
new file mode 100644
index 0000000..a6958fe
--- /dev/null
+++ b/generic/regc_locale.c
@@ -0,0 +1,1260 @@
+/*
+ * regc_locale.c --
+ *
+ *	This file contains the Unicode locale specific regexp routines.
+ *	This file is #included by regcomp.c.
+ *
+ * Copyright (c) 1998 by Scriptics Corporation.
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+/* ASCII character-name table */
+
+static const struct cname {
+    const char *name;
+    const char code;
+} cnames[] = {
+    {"NUL",		'\0'},
+    {"SOH",		'\001'},
+    {"STX",		'\002'},
+    {"ETX",		'\003'},
+    {"EOT",		'\004'},
+    {"ENQ",		'\005'},
+    {"ACK",		'\006'},
+    {"BEL",		'\007'},
+    {"alert",		'\007'},
+    {"BS",		'\010'},
+    {"backspace",	'\b'},
+    {"HT",		'\011'},
+    {"tab",		'\t'},
+    {"LF",		'\012'},
+    {"newline",		'\n'},
+    {"VT",		'\013'},
+    {"vertical-tab",	'\v'},
+    {"FF",		'\014'},
+    {"form-feed",	'\f'},
+    {"CR",		'\015'},
+    {"carriage-return",	'\r'},
+    {"SO",		'\016'},
+    {"SI",		'\017'},
+    {"DLE",		'\020'},
+    {"DC1",		'\021'},
+    {"DC2",		'\022'},
+    {"DC3",		'\023'},
+    {"DC4",		'\024'},
+    {"NAK",		'\025'},
+    {"SYN",		'\026'},
+    {"ETB",		'\027'},
+    {"CAN",		'\030'},
+    {"EM",		'\031'},
+    {"SUB",		'\032'},
+    {"ESC",		'\033'},
+    {"IS4",		'\034'},
+    {"FS",		'\034'},
+    {"IS3",		'\035'},
+    {"GS",		'\035'},
+    {"IS2",		'\036'},
+    {"RS",		'\036'},
+    {"IS1",		'\037'},
+    {"US",		'\037'},
+    {"space",		' '},
+    {"exclamation-mark",'!'},
+    {"quotation-mark",	'"'},
+    {"number-sign",	'#'},
+    {"dollar-sign",	'$'},
+    {"percent-sign",	'%'},
+    {"ampersand",	'&'},
+    {"apostrophe",	'\''},
+    {"left-parenthesis",'('},
+    {"right-parenthesis", ')'},
+    {"asterisk",	'*'},
+    {"plus-sign",	'+'},
+    {"comma",		','},
+    {"hyphen",		'-'},
+    {"hyphen-minus",	'-'},
+    {"period",		'.'},
+    {"full-stop",	'.'},
+    {"slash",		'/'},
+    {"solidus",		'/'},
+    {"zero",		'0'},
+    {"one",		'1'},
+    {"two",		'2'},
+    {"three",		'3'},
+    {"four",		'4'},
+    {"five",		'5'},
+    {"six",		'6'},
+    {"seven",		'7'},
+    {"eight",		'8'},
+    {"nine",		'9'},
+    {"colon",		':'},
+    {"semicolon",	';'},
+    {"less-than-sign",	'<'},
+    {"equals-sign",	'='},
+    {"greater-than-sign", '>'},
+    {"question-mark",	'?'},
+    {"commercial-at",	'@'},
+    {"left-square-bracket", '['},
+    {"backslash",	'\\'},
+    {"reverse-solidus",	'\\'},
+    {"right-square-bracket", ']'},
+    {"circumflex",	'^'},
+    {"circumflex-accent", '^'},
+    {"underscore",	'_'},
+    {"low-line",	'_'},
+    {"grave-accent",	'`'},
+    {"left-brace",	'{'},
+    {"left-curly-bracket", '{'},
+    {"vertical-line",	'|'},
+    {"right-brace",	'}'},
+    {"right-curly-bracket", '}'},
+    {"tilde",		'~'},
+    {"DEL",		'\177'},
+    {NULL,		0}
+};
+
+/*
+ * Unicode character-class tables.
+ */
+
+typedef struct {
+    chr start;
+    chr end;
+} crange;
+
+/*
+ *	Declarations of Unicode character ranges.  This code
+ *	is automatically generated by the tools/uniClass.tcl script
+ *	and used in generic/regc_locale.c.  Do not modify by hand.
+ */
+
+/*
+ * Unicode: alphabetic characters.
+ */
+
+static const crange alphaRangeTable[] = {
+    {0x41, 0x5a}, {0x61, 0x7a}, {0xc0, 0xd6}, {0xd8, 0xf6},
+    {0xf8, 0x2c1}, {0x2c6, 0x2d1}, {0x2e0, 0x2e4}, {0x370, 0x374},
+    {0x37a, 0x37d}, {0x388, 0x38a}, {0x38e, 0x3a1}, {0x3a3, 0x3f5},
+    {0x3f7, 0x481}, {0x48a, 0x52f}, {0x531, 0x556}, {0x561, 0x587},
+    {0x5d0, 0x5ea}, {0x5f0, 0x5f2}, {0x620, 0x64a}, {0x671, 0x6d3},
+    {0x6fa, 0x6fc}, {0x712, 0x72f}, {0x74d, 0x7a5}, {0x7ca, 0x7ea},
+    {0x800, 0x815}, {0x840, 0x858}, {0x8a0, 0x8b4}, {0x8b6, 0x8bd},
+    {0x904, 0x939}, {0x958, 0x961}, {0x971, 0x980}, {0x985, 0x98c},
+    {0x993, 0x9a8}, {0x9aa, 0x9b0}, {0x9b6, 0x9b9}, {0x9df, 0x9e1},
+    {0xa05, 0xa0a}, {0xa13, 0xa28}, {0xa2a, 0xa30}, {0xa59, 0xa5c},
+    {0xa72, 0xa74}, {0xa85, 0xa8d}, {0xa8f, 0xa91}, {0xa93, 0xaa8},
+    {0xaaa, 0xab0}, {0xab5, 0xab9}, {0xb05, 0xb0c}, {0xb13, 0xb28},
+    {0xb2a, 0xb30}, {0xb35, 0xb39}, {0xb5f, 0xb61}, {0xb85, 0xb8a},
+    {0xb8e, 0xb90}, {0xb92, 0xb95}, {0xba8, 0xbaa}, {0xbae, 0xbb9},
+    {0xc05, 0xc0c}, {0xc0e, 0xc10}, {0xc12, 0xc28}, {0xc2a, 0xc39},
+    {0xc58, 0xc5a}, {0xc85, 0xc8c}, {0xc8e, 0xc90}, {0xc92, 0xca8},
+    {0xcaa, 0xcb3}, {0xcb5, 0xcb9}, {0xd05, 0xd0c}, {0xd0e, 0xd10},
+    {0xd12, 0xd3a}, {0xd54, 0xd56}, {0xd5f, 0xd61}, {0xd7a, 0xd7f},
+    {0xd85, 0xd96}, {0xd9a, 0xdb1}, {0xdb3, 0xdbb}, {0xdc0, 0xdc6},
+    {0xe01, 0xe30}, {0xe40, 0xe46}, {0xe94, 0xe97}, {0xe99, 0xe9f},
+    {0xea1, 0xea3}, {0xead, 0xeb0}, {0xec0, 0xec4}, {0xedc, 0xedf},
+    {0xf40, 0xf47}, {0xf49, 0xf6c}, {0xf88, 0xf8c}, {0x1000, 0x102a},
+    {0x1050, 0x1055}, {0x105a, 0x105d}, {0x106e, 0x1070}, {0x1075, 0x1081},
+    {0x10a0, 0x10c5}, {0x10d0, 0x10fa}, {0x10fc, 0x1248}, {0x124a, 0x124d},
+    {0x1250, 0x1256}, {0x125a, 0x125d}, {0x1260, 0x1288}, {0x128a, 0x128d},
+    {0x1290, 0x12b0}, {0x12b2, 0x12b5}, {0x12b8, 0x12be}, {0x12c2, 0x12c5},
+    {0x12c8, 0x12d6}, {0x12d8, 0x1310}, {0x1312, 0x1315}, {0x1318, 0x135a},
+    {0x1380, 0x138f}, {0x13a0, 0x13f5}, {0x13f8, 0x13fd}, {0x1401, 0x166c},
+    {0x166f, 0x167f}, {0x1681, 0x169a}, {0x16a0, 0x16ea}, {0x16f1, 0x16f8},
+    {0x1700, 0x170c}, {0x170e, 0x1711}, {0x1720, 0x1731}, {0x1740, 0x1751},
+    {0x1760, 0x176c}, {0x176e, 0x1770}, {0x1780, 0x17b3}, {0x1820, 0x1877},
+    {0x1880, 0x1884}, {0x1887, 0x18a8}, {0x18b0, 0x18f5}, {0x1900, 0x191e},
+    {0x1950, 0x196d}, {0x1970, 0x1974}, {0x1980, 0x19ab}, {0x19b0, 0x19c9},
+    {0x1a00, 0x1a16}, {0x1a20, 0x1a54}, {0x1b05, 0x1b33}, {0x1b45, 0x1b4b},
+    {0x1b83, 0x1ba0}, {0x1bba, 0x1be5}, {0x1c00, 0x1c23}, {0x1c4d, 0x1c4f},
+    {0x1c5a, 0x1c7d}, {0x1c80, 0x1c88}, {0x1ce9, 0x1cec}, {0x1cee, 0x1cf1},
+    {0x1d00, 0x1dbf}, {0x1e00, 0x1f15}, {0x1f18, 0x1f1d}, {0x1f20, 0x1f45},
+    {0x1f48, 0x1f4d}, {0x1f50, 0x1f57}, {0x1f5f, 0x1f7d}, {0x1f80, 0x1fb4},
+    {0x1fb6, 0x1fbc}, {0x1fc2, 0x1fc4}, {0x1fc6, 0x1fcc}, {0x1fd0, 0x1fd3},
+    {0x1fd6, 0x1fdb}, {0x1fe0, 0x1fec}, {0x1ff2, 0x1ff4}, {0x1ff6, 0x1ffc},
+    {0x2090, 0x209c}, {0x210a, 0x2113}, {0x2119, 0x211d}, {0x212a, 0x212d},
+    {0x212f, 0x2139}, {0x213c, 0x213f}, {0x2145, 0x2149}, {0x2c00, 0x2c2e},
+    {0x2c30, 0x2c5e}, {0x2c60, 0x2ce4}, {0x2ceb, 0x2cee}, {0x2d00, 0x2d25},
+    {0x2d30, 0x2d67}, {0x2d80, 0x2d96}, {0x2da0, 0x2da6}, {0x2da8, 0x2dae},
+    {0x2db0, 0x2db6}, {0x2db8, 0x2dbe}, {0x2dc0, 0x2dc6}, {0x2dc8, 0x2dce},
+    {0x2dd0, 0x2dd6}, {0x2dd8, 0x2dde}, {0x3031, 0x3035}, {0x3041, 0x3096},
+    {0x309d, 0x309f}, {0x30a1, 0x30fa}, {0x30fc, 0x30ff}, {0x3105, 0x312d},
+    {0x3131, 0x318e}, {0x31a0, 0x31ba}, {0x31f0, 0x31ff}, {0x3400, 0x4db5},
+    {0x4e00, 0x9fd5}, {0xa000, 0xa48c}, {0xa4d0, 0xa4fd}, {0xa500, 0xa60c},
+    {0xa610, 0xa61f}, {0xa640, 0xa66e}, {0xa67f, 0xa69d}, {0xa6a0, 0xa6e5},
+    {0xa717, 0xa71f}, {0xa722, 0xa788}, {0xa78b, 0xa7ae}, {0xa7b0, 0xa7b7},
+    {0xa7f7, 0xa801}, {0xa803, 0xa805}, {0xa807, 0xa80a}, {0xa80c, 0xa822},
+    {0xa840, 0xa873}, {0xa882, 0xa8b3}, {0xa8f2, 0xa8f7}, {0xa90a, 0xa925},
+    {0xa930, 0xa946}, {0xa960, 0xa97c}, {0xa984, 0xa9b2}, {0xa9e0, 0xa9e4},
+    {0xa9e6, 0xa9ef}, {0xa9fa, 0xa9fe}, {0xaa00, 0xaa28}, {0xaa40, 0xaa42},
+    {0xaa44, 0xaa4b}, {0xaa60, 0xaa76}, {0xaa7e, 0xaaaf}, {0xaab9, 0xaabd},
+    {0xaadb, 0xaadd}, {0xaae0, 0xaaea}, {0xaaf2, 0xaaf4}, {0xab01, 0xab06},
+    {0xab09, 0xab0e}, {0xab11, 0xab16}, {0xab20, 0xab26}, {0xab28, 0xab2e},
+    {0xab30, 0xab5a}, {0xab5c, 0xab65}, {0xab70, 0xabe2}, {0xac00, 0xd7a3},
+    {0xd7b0, 0xd7c6}, {0xd7cb, 0xd7fb}, {0xdc00, 0xdc3e}, {0xdc40, 0xdc7e},
+    {0xdc80, 0xdcbe}, {0xdcc0, 0xdcfe}, {0xdd00, 0xdd3e}, {0xdd40, 0xdd7e},
+    {0xdd80, 0xddbe}, {0xddc0, 0xddfe}, {0xde00, 0xde3e}, {0xde40, 0xde7e},
+    {0xde80, 0xdebe}, {0xdec0, 0xdefe}, {0xdf00, 0xdf3e}, {0xdf40, 0xdf7e},
+    {0xdf80, 0xdfbe}, {0xdfc0, 0xdffe}, {0xf900, 0xfa6d}, {0xfa70, 0xfad9},
+    {0xfb00, 0xfb06}, {0xfb13, 0xfb17}, {0xfb1f, 0xfb28}, {0xfb2a, 0xfb36},
+    {0xfb38, 0xfb3c}, {0xfb46, 0xfbb1}, {0xfbd3, 0xfd3d}, {0xfd50, 0xfd8f},
+    {0xfd92, 0xfdc7}, {0xfdf0, 0xfdfb}, {0xfe70, 0xfe74}, {0xfe76, 0xfefc},
+    {0xff21, 0xff3a}, {0xff41, 0xff5a}, {0xff66, 0xffbe}, {0xffc2, 0xffc7},
+    {0xffca, 0xffcf}, {0xffd2, 0xffd7}, {0xffda, 0xffdc}
+#if TCL_UTF_MAX > 4
+    ,{0x10000, 0x1000b}, {0x1000d, 0x10026}, {0x10028, 0x1003a}, {0x1003f, 0x1004d},
+    {0x10050, 0x1005d}, {0x10080, 0x100fa}, {0x10280, 0x1029c}, {0x102a0, 0x102d0},
+    {0x10300, 0x1031f}, {0x10330, 0x10340}, {0x10342, 0x10349}, {0x10350, 0x10375},
+    {0x10380, 0x1039d}, {0x103a0, 0x103c3}, {0x103c8, 0x103cf}, {0x10400, 0x1049d},
+    {0x104b0, 0x104d3}, {0x104d8, 0x104fb}, {0x10500, 0x10527}, {0x10530, 0x10563},
+    {0x10600, 0x10736}, {0x10740, 0x10755}, {0x10760, 0x10767}, {0x10800, 0x10805},
+    {0x1080a, 0x10835}, {0x1083f, 0x10855}, {0x10860, 0x10876}, {0x10880, 0x1089e},
+    {0x108e0, 0x108f2}, {0x10900, 0x10915}, {0x10920, 0x10939}, {0x10980, 0x109b7},
+    {0x10a10, 0x10a13}, {0x10a15, 0x10a17}, {0x10a19, 0x10a33}, {0x10a60, 0x10a7c},
+    {0x10a80, 0x10a9c}, {0x10ac0, 0x10ac7}, {0x10ac9, 0x10ae4}, {0x10b00, 0x10b35},
+    {0x10b40, 0x10b55}, {0x10b60, 0x10b72}, {0x10b80, 0x10b91}, {0x10c00, 0x10c48},
+    {0x10c80, 0x10cb2}, {0x10cc0, 0x10cf2}, {0x11003, 0x11037}, {0x11083, 0x110af},
+    {0x110d0, 0x110e8}, {0x11103, 0x11126}, {0x11150, 0x11172}, {0x11183, 0x111b2},
+    {0x111c1, 0x111c4}, {0x11200, 0x11211}, {0x11213, 0x1122b}, {0x11280, 0x11286},
+    {0x1128a, 0x1128d}, {0x1128f, 0x1129d}, {0x1129f, 0x112a8}, {0x112b0, 0x112de},
+    {0x11305, 0x1130c}, {0x11313, 0x11328}, {0x1132a, 0x11330}, {0x11335, 0x11339},
+    {0x1135d, 0x11361}, {0x11400, 0x11434}, {0x11447, 0x1144a}, {0x11480, 0x114af},
+    {0x11580, 0x115ae}, {0x115d8, 0x115db}, {0x11600, 0x1162f}, {0x11680, 0x116aa},
+    {0x11700, 0x11719}, {0x118a0, 0x118df}, {0x11ac0, 0x11af8}, {0x11c00, 0x11c08},
+    {0x11c0a, 0x11c2e}, {0x11c72, 0x11c8f}, {0x12000, 0x12399}, {0x12480, 0x12543},
+    {0x13000, 0x1342e}, {0x14400, 0x14646}, {0x16800, 0x16a38}, {0x16a40, 0x16a5e},
+    {0x16ad0, 0x16aed}, {0x16b00, 0x16b2f}, {0x16b40, 0x16b43}, {0x16b63, 0x16b77},
+    {0x16b7d, 0x16b8f}, {0x16f00, 0x16f44}, {0x16f93, 0x16f9f}, {0x17000, 0x187ec},
+    {0x18800, 0x18af2}, {0x1bc00, 0x1bc6a}, {0x1bc70, 0x1bc7c}, {0x1bc80, 0x1bc88},
+    {0x1bc90, 0x1bc99}, {0x1d400, 0x1d454}, {0x1d456, 0x1d49c}, {0x1d4a9, 0x1d4ac},
+    {0x1d4ae, 0x1d4b9}, {0x1d4bd, 0x1d4c3}, {0x1d4c5, 0x1d505}, {0x1d507, 0x1d50a},
+    {0x1d50d, 0x1d514}, {0x1d516, 0x1d51c}, {0x1d51e, 0x1d539}, {0x1d53b, 0x1d53e},
+    {0x1d540, 0x1d544}, {0x1d54a, 0x1d550}, {0x1d552, 0x1d6a5}, {0x1d6a8, 0x1d6c0},
+    {0x1d6c2, 0x1d6da}, {0x1d6dc, 0x1d6fa}, {0x1d6fc, 0x1d714}, {0x1d716, 0x1d734},
+    {0x1d736, 0x1d74e}, {0x1d750, 0x1d76e}, {0x1d770, 0x1d788}, {0x1d78a, 0x1d7a8},
+    {0x1d7aa, 0x1d7c2}, {0x1d7c4, 0x1d7cb}, {0x1e800, 0x1e8c4}, {0x1e900, 0x1e943},
+    {0x1ee00, 0x1ee03}, {0x1ee05, 0x1ee1f}, {0x1ee29, 0x1ee32}, {0x1ee34, 0x1ee37},
+    {0x1ee4d, 0x1ee4f}, {0x1ee67, 0x1ee6a}, {0x1ee6c, 0x1ee72}, {0x1ee74, 0x1ee77},
+    {0x1ee79, 0x1ee7c}, {0x1ee80, 0x1ee89}, {0x1ee8b, 0x1ee9b}, {0x1eea1, 0x1eea3},
+    {0x1eea5, 0x1eea9}, {0x1eeab, 0x1eebb}, {0x20000, 0x2a6d6}, {0x2a700, 0x2b734},
+    {0x2b740, 0x2b81d}, {0x2b820, 0x2cea1}, {0x2f800, 0x2fa1d}
+#endif
+};
+
+#define NUM_ALPHA_RANGE (sizeof(alphaRangeTable)/sizeof(crange))
+
+static const chr alphaCharTable[] = {
+    0xaa, 0xb5, 0xba, 0x2ec, 0x2ee, 0x376, 0x377, 0x37f, 0x386,
+    0x38c, 0x559, 0x66e, 0x66f, 0x6d5, 0x6e5, 0x6e6, 0x6ee, 0x6ef,
+    0x6ff, 0x710, 0x7b1, 0x7f4, 0x7f5, 0x7fa, 0x81a, 0x824, 0x828,
+    0x93d, 0x950, 0x98f, 0x990, 0x9b2, 0x9bd, 0x9ce, 0x9dc, 0x9dd,
+    0x9f0, 0x9f1, 0xa0f, 0xa10, 0xa32, 0xa33, 0xa35, 0xa36, 0xa38,
+    0xa39, 0xa5e, 0xab2, 0xab3, 0xabd, 0xad0, 0xae0, 0xae1, 0xaf9,
+    0xb0f, 0xb10, 0xb32, 0xb33, 0xb3d, 0xb5c, 0xb5d, 0xb71, 0xb83,
+    0xb99, 0xb9a, 0xb9c, 0xb9e, 0xb9f, 0xba3, 0xba4, 0xbd0, 0xc3d,
+    0xc60, 0xc61, 0xc80, 0xcbd, 0xcde, 0xce0, 0xce1, 0xcf1, 0xcf2,
+    0xd3d, 0xd4e, 0xdbd, 0xe32, 0xe33, 0xe81, 0xe82, 0xe84, 0xe87,
+    0xe88, 0xe8a, 0xe8d, 0xea5, 0xea7, 0xeaa, 0xeab, 0xeb2, 0xeb3,
+    0xebd, 0xec6, 0xf00, 0x103f, 0x1061, 0x1065, 0x1066, 0x108e, 0x10c7,
+    0x10cd, 0x1258, 0x12c0, 0x17d7, 0x17dc, 0x18aa, 0x1aa7, 0x1bae, 0x1baf,
+    0x1cf5, 0x1cf6, 0x1f59, 0x1f5b, 0x1f5d, 0x1fbe, 0x2071, 0x207f, 0x2102,
+    0x2107, 0x2115, 0x2124, 0x2126, 0x2128, 0x214e, 0x2183, 0x2184, 0x2cf2,
+    0x2cf3, 0x2d27, 0x2d2d, 0x2d6f, 0x2e2f, 0x3005, 0x3006, 0x303b, 0x303c,
+    0xa62a, 0xa62b, 0xa8fb, 0xa8fd, 0xa9cf, 0xaa7a, 0xaab1, 0xaab5, 0xaab6,
+    0xaac0, 0xaac2, 0xfb1d, 0xfb3e, 0xfb40, 0xfb41, 0xfb43, 0xfb44
+#if TCL_UTF_MAX > 4
+    ,0x1003c, 0x1003d, 0x10808, 0x10837, 0x10838, 0x1083c, 0x108f4, 0x108f5, 0x109be,
+    0x109bf, 0x10a00, 0x11176, 0x111da, 0x111dc, 0x11288, 0x1130f, 0x11310, 0x11332,
+    0x11333, 0x1133d, 0x11350, 0x114c4, 0x114c5, 0x114c7, 0x11644, 0x118ff, 0x11c40,
+    0x16f50, 0x16fe0, 0x1b000, 0x1b001, 0x1d49e, 0x1d49f, 0x1d4a2, 0x1d4a5, 0x1d4a6,
+    0x1d4bb, 0x1d546, 0x1ee21, 0x1ee22, 0x1ee24, 0x1ee27, 0x1ee39, 0x1ee3b, 0x1ee42,
+    0x1ee47, 0x1ee49, 0x1ee4b, 0x1ee51, 0x1ee52, 0x1ee54, 0x1ee57, 0x1ee59, 0x1ee5b,
+    0x1ee5d, 0x1ee5f, 0x1ee61, 0x1ee62, 0x1ee64, 0x1ee7e
+#endif
+};
+
+#define NUM_ALPHA_CHAR (sizeof(alphaCharTable)/sizeof(chr))
+
+/*
+ * Unicode: control characters.
+ */
+
+static const crange controlRangeTable[] = {
+    {0x0, 0x1f}, {0x7f, 0x9f}, {0x600, 0x605}, {0x200b, 0x200f},
+    {0x202a, 0x202e}, {0x2060, 0x2064}, {0x2066, 0x206f}, {0xe000, 0xf8ff},
+    {0xfff9, 0xfffb}
+#if TCL_UTF_MAX > 4
+    ,{0x1bca0, 0x1bca3}, {0x1d173, 0x1d17a}, {0xe0020, 0xe007f}, {0xf0000, 0xffffd},
+    {0x100000, 0x10fffd}
+#endif
+};
+
+#define NUM_CONTROL_RANGE (sizeof(controlRangeTable)/sizeof(crange))
+
+static const chr controlCharTable[] = {
+    0xad, 0x61c, 0x6dd, 0x70f, 0x8e2, 0x180e, 0xfeff
+#if TCL_UTF_MAX > 4
+    ,0x110bd, 0xe0001
+#endif
+};
+
+#define NUM_CONTROL_CHAR (sizeof(controlCharTable)/sizeof(chr))
+
+/*
+ * Unicode: decimal digit characters.
+ */
+
+static const crange digitRangeTable[] = {
+    {0x30, 0x39}, {0x660, 0x669}, {0x6f0, 0x6f9}, {0x7c0, 0x7c9},
+    {0x966, 0x96f}, {0x9e6, 0x9ef}, {0xa66, 0xa6f}, {0xae6, 0xaef},
+    {0xb66, 0xb6f}, {0xbe6, 0xbef}, {0xc66, 0xc6f}, {0xce6, 0xcef},
+    {0xd66, 0xd6f}, {0xde6, 0xdef}, {0xe50, 0xe59}, {0xed0, 0xed9},
+    {0xf20, 0xf29}, {0x1040, 0x1049}, {0x1090, 0x1099}, {0x17e0, 0x17e9},
+    {0x1810, 0x1819}, {0x1946, 0x194f}, {0x19d0, 0x19d9}, {0x1a80, 0x1a89},
+    {0x1a90, 0x1a99}, {0x1b50, 0x1b59}, {0x1bb0, 0x1bb9}, {0x1c40, 0x1c49},
+    {0x1c50, 0x1c59}, {0xa620, 0xa629}, {0xa8d0, 0xa8d9}, {0xa900, 0xa909},
+    {0xa9d0, 0xa9d9}, {0xa9f0, 0xa9f9}, {0xaa50, 0xaa59}, {0xabf0, 0xabf9},
+    {0xff10, 0xff19}
+#if TCL_UTF_MAX > 4
+    ,{0x104a0, 0x104a9}, {0x11066, 0x1106f}, {0x110f0, 0x110f9}, {0x11136, 0x1113f},
+    {0x111d0, 0x111d9}, {0x112f0, 0x112f9}, {0x11450, 0x11459}, {0x114d0, 0x114d9},
+    {0x11650, 0x11659}, {0x116c0, 0x116c9}, {0x11730, 0x11739}, {0x118e0, 0x118e9},
+    {0x11c50, 0x11c59}, {0x16a60, 0x16a69}, {0x16b50, 0x16b59}, {0x1d7ce, 0x1d7ff},
+    {0x1e950, 0x1e959}
+#endif
+};
+
+#define NUM_DIGIT_RANGE (sizeof(digitRangeTable)/sizeof(crange))
+
+/*
+ * no singletons of digit characters.
+ */
+
+/*
+ * Unicode: punctuation characters.
+ */
+
+static const crange punctRangeTable[] = {
+    {0x21, 0x23}, {0x25, 0x2a}, {0x2c, 0x2f}, {0x5b, 0x5d},
+    {0x55a, 0x55f}, {0x66a, 0x66d}, {0x700, 0x70d}, {0x7f7, 0x7f9},
+    {0x830, 0x83e}, {0xf04, 0xf12}, {0xf3a, 0xf3d}, {0xfd0, 0xfd4},
+    {0x104a, 0x104f}, {0x1360, 0x1368}, {0x16eb, 0x16ed}, {0x17d4, 0x17d6},
+    {0x17d8, 0x17da}, {0x1800, 0x180a}, {0x1aa0, 0x1aa6}, {0x1aa8, 0x1aad},
+    {0x1b5a, 0x1b60}, {0x1bfc, 0x1bff}, {0x1c3b, 0x1c3f}, {0x1cc0, 0x1cc7},
+    {0x2010, 0x2027}, {0x2030, 0x2043}, {0x2045, 0x2051}, {0x2053, 0x205e},
+    {0x2308, 0x230b}, {0x2768, 0x2775}, {0x27e6, 0x27ef}, {0x2983, 0x2998},
+    {0x29d8, 0x29db}, {0x2cf9, 0x2cfc}, {0x2e00, 0x2e2e}, {0x2e30, 0x2e44},
+    {0x3001, 0x3003}, {0x3008, 0x3011}, {0x3014, 0x301f}, {0xa60d, 0xa60f},
+    {0xa6f2, 0xa6f7}, {0xa874, 0xa877}, {0xa8f8, 0xa8fa}, {0xa9c1, 0xa9cd},
+    {0xaa5c, 0xaa5f}, {0xfe10, 0xfe19}, {0xfe30, 0xfe52}, {0xfe54, 0xfe61},
+    {0xff01, 0xff03}, {0xff05, 0xff0a}, {0xff0c, 0xff0f}, {0xff3b, 0xff3d},
+    {0xff5f, 0xff65}
+#if TCL_UTF_MAX > 4
+    ,{0x10100, 0x10102}, {0x10a50, 0x10a58}, {0x10af0, 0x10af6}, {0x10b39, 0x10b3f},
+    {0x10b99, 0x10b9c}, {0x11047, 0x1104d}, {0x110be, 0x110c1}, {0x11140, 0x11143},
+    {0x111c5, 0x111c9}, {0x111dd, 0x111df}, {0x11238, 0x1123d}, {0x1144b, 0x1144f},
+    {0x115c1, 0x115d7}, {0x11641, 0x11643}, {0x11660, 0x1166c}, {0x1173c, 0x1173e},
+    {0x11c41, 0x11c45}, {0x12470, 0x12474}, {0x16b37, 0x16b3b}, {0x1da87, 0x1da8b}
+#endif
+};
+
+#define NUM_PUNCT_RANGE (sizeof(punctRangeTable)/sizeof(crange))
+
+static const chr punctCharTable[] = {
+    0x3a, 0x3b, 0x3f, 0x40, 0x5f, 0x7b, 0x7d, 0xa1, 0xa7,
+    0xab, 0xb6, 0xb7, 0xbb, 0xbf, 0x37e, 0x387, 0x589, 0x58a,
+    0x5be, 0x5c0, 0x5c3, 0x5c6, 0x5f3, 0x5f4, 0x609, 0x60a, 0x60c,
+    0x60d, 0x61b, 0x61e, 0x61f, 0x6d4, 0x85e, 0x964, 0x965, 0x970,
+    0xaf0, 0xdf4, 0xe4f, 0xe5a, 0xe5b, 0xf14, 0xf85, 0xfd9, 0xfda,
+    0x10fb, 0x1400, 0x166d, 0x166e, 0x169b, 0x169c, 0x1735, 0x1736, 0x1944,
+    0x1945, 0x1a1e, 0x1a1f, 0x1c7e, 0x1c7f, 0x1cd3, 0x207d, 0x207e, 0x208d,
+    0x208e, 0x2329, 0x232a, 0x27c5, 0x27c6, 0x29fc, 0x29fd, 0x2cfe, 0x2cff,
+    0x2d70, 0x3030, 0x303d, 0x30a0, 0x30fb, 0xa4fe, 0xa4ff, 0xa673, 0xa67e,
+    0xa8ce, 0xa8cf, 0xa8fc, 0xa92e, 0xa92f, 0xa95f, 0xa9de, 0xa9df, 0xaade,
+    0xaadf, 0xaaf0, 0xaaf1, 0xabeb, 0xfd3e, 0xfd3f, 0xfe63, 0xfe68, 0xfe6a,
+    0xfe6b, 0xff1a, 0xff1b, 0xff1f, 0xff20, 0xff3f, 0xff5b, 0xff5d
+#if TCL_UTF_MAX > 4
+    ,0x1039f, 0x103d0, 0x1056f, 0x10857, 0x1091f, 0x1093f, 0x10a7f, 0x110bb, 0x110bc,
+    0x11174, 0x11175, 0x111cd, 0x111db, 0x112a9, 0x1145b, 0x1145d, 0x114c6, 0x11c70,
+    0x11c71, 0x16a6e, 0x16a6f, 0x16af5, 0x16b44, 0x1bc9f, 0x1e95e, 0x1e95f
+#endif
+};
+
+#define NUM_PUNCT_CHAR (sizeof(punctCharTable)/sizeof(chr))
+
+/*
+ * Unicode: white space characters.
+ */
+
+static const crange spaceRangeTable[] = {
+    {0x9, 0xd}, {0x2000, 0x200b}
+};
+
+#define NUM_SPACE_RANGE (sizeof(spaceRangeTable)/sizeof(crange))
+
+static const chr spaceCharTable[] = {
+    0x20, 0x85, 0xa0, 0x1680, 0x180e, 0x2028, 0x2029, 0x202f, 0x205f,
+    0x2060, 0x3000, 0xfeff
+};
+
+#define NUM_SPACE_CHAR (sizeof(spaceCharTable)/sizeof(chr))
+
+/*
+ * Unicode: lowercase characters.
+ */
+
+static const crange lowerRangeTable[] = {
+    {0x61, 0x7a}, {0xdf, 0xf6}, {0xf8, 0xff}, {0x17e, 0x180},
+    {0x199, 0x19b}, {0x1bd, 0x1bf}, {0x233, 0x239}, {0x24f, 0x293},
+    {0x295, 0x2af}, {0x37b, 0x37d}, {0x3ac, 0x3ce}, {0x3d5, 0x3d7},
+    {0x3ef, 0x3f3}, {0x430, 0x45f}, {0x561, 0x587}, {0x13f8, 0x13fd},
+    {0x1c80, 0x1c88}, {0x1d00, 0x1d2b}, {0x1d6b, 0x1d77}, {0x1d79, 0x1d9a},
+    {0x1e95, 0x1e9d}, {0x1eff, 0x1f07}, {0x1f10, 0x1f15}, {0x1f20, 0x1f27},
+    {0x1f30, 0x1f37}, {0x1f40, 0x1f45}, {0x1f50, 0x1f57}, {0x1f60, 0x1f67},
+    {0x1f70, 0x1f7d}, {0x1f80, 0x1f87}, {0x1f90, 0x1f97}, {0x1fa0, 0x1fa7},
+    {0x1fb0, 0x1fb4}, {0x1fc2, 0x1fc4}, {0x1fd0, 0x1fd3}, {0x1fe0, 0x1fe7},
+    {0x1ff2, 0x1ff4}, {0x2146, 0x2149}, {0x2c30, 0x2c5e}, {0x2c76, 0x2c7b},
+    {0x2d00, 0x2d25}, {0xa72f, 0xa731}, {0xa771, 0xa778}, {0xa793, 0xa795},
+    {0xab30, 0xab5a}, {0xab60, 0xab65}, {0xab70, 0xabbf}, {0xfb00, 0xfb06},
+    {0xfb13, 0xfb17}, {0xff41, 0xff5a}
+#if TCL_UTF_MAX > 4
+    ,{0x10428, 0x1044f}, {0x104d8, 0x104fb}, {0x10cc0, 0x10cf2}, {0x118c0, 0x118df},
+    {0x1d41a, 0x1d433}, {0x1d44e, 0x1d454}, {0x1d456, 0x1d467}, {0x1d482, 0x1d49b},
+    {0x1d4b6, 0x1d4b9}, {0x1d4bd, 0x1d4c3}, {0x1d4c5, 0x1d4cf}, {0x1d4ea, 0x1d503},
+    {0x1d51e, 0x1d537}, {0x1d552, 0x1d56b}, {0x1d586, 0x1d59f}, {0x1d5ba, 0x1d5d3},
+    {0x1d5ee, 0x1d607}, {0x1d622, 0x1d63b}, {0x1d656, 0x1d66f}, {0x1d68a, 0x1d6a5},
+    {0x1d6c2, 0x1d6da}, {0x1d6dc, 0x1d6e1}, {0x1d6fc, 0x1d714}, {0x1d716, 0x1d71b},
+    {0x1d736, 0x1d74e}, {0x1d750, 0x1d755}, {0x1d770, 0x1d788}, {0x1d78a, 0x1d78f},
+    {0x1d7aa, 0x1d7c2}, {0x1d7c4, 0x1d7c9}, {0x1e922, 0x1e943}
+#endif
+};
+
+#define NUM_LOWER_RANGE (sizeof(lowerRangeTable)/sizeof(crange))
+
+static const chr lowerCharTable[] = {
+    0xb5, 0x101, 0x103, 0x105, 0x107, 0x109, 0x10b, 0x10d, 0x10f,
+    0x111, 0x113, 0x115, 0x117, 0x119, 0x11b, 0x11d, 0x11f, 0x121,
+    0x123, 0x125, 0x127, 0x129, 0x12b, 0x12d, 0x12f, 0x131, 0x133,
+    0x135, 0x137, 0x138, 0x13a, 0x13c, 0x13e, 0x140, 0x142, 0x144,
+    0x146, 0x148, 0x149, 0x14b, 0x14d, 0x14f, 0x151, 0x153, 0x155,
+    0x157, 0x159, 0x15b, 0x15d, 0x15f, 0x161, 0x163, 0x165, 0x167,
+    0x169, 0x16b, 0x16d, 0x16f, 0x171, 0x173, 0x175, 0x177, 0x17a,
+    0x17c, 0x183, 0x185, 0x188, 0x18c, 0x18d, 0x192, 0x195, 0x19e,
+    0x1a1, 0x1a3, 0x1a5, 0x1a8, 0x1aa, 0x1ab, 0x1ad, 0x1b0, 0x1b4,
+    0x1b6, 0x1b9, 0x1ba, 0x1c6, 0x1c9, 0x1cc, 0x1ce, 0x1d0, 0x1d2,
+    0x1d4, 0x1d6, 0x1d8, 0x1da, 0x1dc, 0x1dd, 0x1df, 0x1e1, 0x1e3,
+    0x1e5, 0x1e7, 0x1e9, 0x1eb, 0x1ed, 0x1ef, 0x1f0, 0x1f3, 0x1f5,
+    0x1f9, 0x1fb, 0x1fd, 0x1ff, 0x201, 0x203, 0x205, 0x207, 0x209,
+    0x20b, 0x20d, 0x20f, 0x211, 0x213, 0x215, 0x217, 0x219, 0x21b,
+    0x21d, 0x21f, 0x221, 0x223, 0x225, 0x227, 0x229, 0x22b, 0x22d,
+    0x22f, 0x231, 0x23c, 0x23f, 0x240, 0x242, 0x247, 0x249, 0x24b,
+    0x24d, 0x371, 0x373, 0x377, 0x390, 0x3d0, 0x3d1, 0x3d9, 0x3db,
+    0x3dd, 0x3df, 0x3e1, 0x3e3, 0x3e5, 0x3e7, 0x3e9, 0x3eb, 0x3ed,
+    0x3f5, 0x3f8, 0x3fb, 0x3fc, 0x461, 0x463, 0x465, 0x467, 0x469,
+    0x46b, 0x46d, 0x46f, 0x471, 0x473, 0x475, 0x477, 0x479, 0x47b,
+    0x47d, 0x47f, 0x481, 0x48b, 0x48d, 0x48f, 0x491, 0x493, 0x495,
+    0x497, 0x499, 0x49b, 0x49d, 0x49f, 0x4a1, 0x4a3, 0x4a5, 0x4a7,
+    0x4a9, 0x4ab, 0x4ad, 0x4af, 0x4b1, 0x4b3, 0x4b5, 0x4b7, 0x4b9,
+    0x4bb, 0x4bd, 0x4bf, 0x4c2, 0x4c4, 0x4c6, 0x4c8, 0x4ca, 0x4cc,
+    0x4ce, 0x4cf, 0x4d1, 0x4d3, 0x4d5, 0x4d7, 0x4d9, 0x4db, 0x4dd,
+    0x4df, 0x4e1, 0x4e3, 0x4e5, 0x4e7, 0x4e9, 0x4eb, 0x4ed, 0x4ef,
+    0x4f1, 0x4f3, 0x4f5, 0x4f7, 0x4f9, 0x4fb, 0x4fd, 0x4ff, 0x501,
+    0x503, 0x505, 0x507, 0x509, 0x50b, 0x50d, 0x50f, 0x511, 0x513,
+    0x515, 0x517, 0x519, 0x51b, 0x51d, 0x51f, 0x521, 0x523, 0x525,
+    0x527, 0x529, 0x52b, 0x52d, 0x52f, 0x1e01, 0x1e03, 0x1e05, 0x1e07,
+    0x1e09, 0x1e0b, 0x1e0d, 0x1e0f, 0x1e11, 0x1e13, 0x1e15, 0x1e17, 0x1e19,
+    0x1e1b, 0x1e1d, 0x1e1f, 0x1e21, 0x1e23, 0x1e25, 0x1e27, 0x1e29, 0x1e2b,
+    0x1e2d, 0x1e2f, 0x1e31, 0x1e33, 0x1e35, 0x1e37, 0x1e39, 0x1e3b, 0x1e3d,
+    0x1e3f, 0x1e41, 0x1e43, 0x1e45, 0x1e47, 0x1e49, 0x1e4b, 0x1e4d, 0x1e4f,
+    0x1e51, 0x1e53, 0x1e55, 0x1e57, 0x1e59, 0x1e5b, 0x1e5d, 0x1e5f, 0x1e61,
+    0x1e63, 0x1e65, 0x1e67, 0x1e69, 0x1e6b, 0x1e6d, 0x1e6f, 0x1e71, 0x1e73,
+    0x1e75, 0x1e77, 0x1e79, 0x1e7b, 0x1e7d, 0x1e7f, 0x1e81, 0x1e83, 0x1e85,
+    0x1e87, 0x1e89, 0x1e8b, 0x1e8d, 0x1e8f, 0x1e91, 0x1e93, 0x1e9f, 0x1ea1,
+    0x1ea3, 0x1ea5, 0x1ea7, 0x1ea9, 0x1eab, 0x1ead, 0x1eaf, 0x1eb1, 0x1eb3,
+    0x1eb5, 0x1eb7, 0x1eb9, 0x1ebb, 0x1ebd, 0x1ebf, 0x1ec1, 0x1ec3, 0x1ec5,
+    0x1ec7, 0x1ec9, 0x1ecb, 0x1ecd, 0x1ecf, 0x1ed1, 0x1ed3, 0x1ed5, 0x1ed7,
+    0x1ed9, 0x1edb, 0x1edd, 0x1edf, 0x1ee1, 0x1ee3, 0x1ee5, 0x1ee7, 0x1ee9,
+    0x1eeb, 0x1eed, 0x1eef, 0x1ef1, 0x1ef3, 0x1ef5, 0x1ef7, 0x1ef9, 0x1efb,
+    0x1efd, 0x1fb6, 0x1fb7, 0x1fbe, 0x1fc6, 0x1fc7, 0x1fd6, 0x1fd7, 0x1ff6,
+    0x1ff7, 0x210a, 0x210e, 0x210f, 0x2113, 0x212f, 0x2134, 0x2139, 0x213c,
+    0x213d, 0x214e, 0x2184, 0x2c61, 0x2c65, 0x2c66, 0x2c68, 0x2c6a, 0x2c6c,
+    0x2c71, 0x2c73, 0x2c74, 0x2c81, 0x2c83, 0x2c85, 0x2c87, 0x2c89, 0x2c8b,
+    0x2c8d, 0x2c8f, 0x2c91, 0x2c93, 0x2c95, 0x2c97, 0x2c99, 0x2c9b, 0x2c9d,
+    0x2c9f, 0x2ca1, 0x2ca3, 0x2ca5, 0x2ca7, 0x2ca9, 0x2cab, 0x2cad, 0x2caf,
+    0x2cb1, 0x2cb3, 0x2cb5, 0x2cb7, 0x2cb9, 0x2cbb, 0x2cbd, 0x2cbf, 0x2cc1,
+    0x2cc3, 0x2cc5, 0x2cc7, 0x2cc9, 0x2ccb, 0x2ccd, 0x2ccf, 0x2cd1, 0x2cd3,
+    0x2cd5, 0x2cd7, 0x2cd9, 0x2cdb, 0x2cdd, 0x2cdf, 0x2ce1, 0x2ce3, 0x2ce4,
+    0x2cec, 0x2cee, 0x2cf3, 0x2d27, 0x2d2d, 0xa641, 0xa643, 0xa645, 0xa647,
+    0xa649, 0xa64b, 0xa64d, 0xa64f, 0xa651, 0xa653, 0xa655, 0xa657, 0xa659,
+    0xa65b, 0xa65d, 0xa65f, 0xa661, 0xa663, 0xa665, 0xa667, 0xa669, 0xa66b,
+    0xa66d, 0xa681, 0xa683, 0xa685, 0xa687, 0xa689, 0xa68b, 0xa68d, 0xa68f,
+    0xa691, 0xa693, 0xa695, 0xa697, 0xa699, 0xa69b, 0xa723, 0xa725, 0xa727,
+    0xa729, 0xa72b, 0xa72d, 0xa733, 0xa735, 0xa737, 0xa739, 0xa73b, 0xa73d,
+    0xa73f, 0xa741, 0xa743, 0xa745, 0xa747, 0xa749, 0xa74b, 0xa74d, 0xa74f,
+    0xa751, 0xa753, 0xa755, 0xa757, 0xa759, 0xa75b, 0xa75d, 0xa75f, 0xa761,
+    0xa763, 0xa765, 0xa767, 0xa769, 0xa76b, 0xa76d, 0xa76f, 0xa77a, 0xa77c,
+    0xa77f, 0xa781, 0xa783, 0xa785, 0xa787, 0xa78c, 0xa78e, 0xa791, 0xa797,
+    0xa799, 0xa79b, 0xa79d, 0xa79f, 0xa7a1, 0xa7a3, 0xa7a5, 0xa7a7, 0xa7a9,
+    0xa7b5, 0xa7b7, 0xa7fa
+#if TCL_UTF_MAX > 4
+    ,0x1d4bb, 0x1d7cb
+#endif
+};
+
+#define NUM_LOWER_CHAR (sizeof(lowerCharTable)/sizeof(chr))
+
+/*
+ * Unicode: uppercase characters.
+ */
+
+static const crange upperRangeTable[] = {
+    {0x41, 0x5a}, {0xc0, 0xd6}, {0xd8, 0xde}, {0x189, 0x18b},
+    {0x18e, 0x191}, {0x196, 0x198}, {0x1b1, 0x1b3}, {0x1f6, 0x1f8},
+    {0x243, 0x246}, {0x388, 0x38a}, {0x391, 0x3a1}, {0x3a3, 0x3ab},
+    {0x3d2, 0x3d4}, {0x3fd, 0x42f}, {0x531, 0x556}, {0x10a0, 0x10c5},
+    {0x13a0, 0x13f5}, {0x1f08, 0x1f0f}, {0x1f18, 0x1f1d}, {0x1f28, 0x1f2f},
+    {0x1f38, 0x1f3f}, {0x1f48, 0x1f4d}, {0x1f68, 0x1f6f}, {0x1fb8, 0x1fbb},
+    {0x1fc8, 0x1fcb}, {0x1fd8, 0x1fdb}, {0x1fe8, 0x1fec}, {0x1ff8, 0x1ffb},
+    {0x210b, 0x210d}, {0x2110, 0x2112}, {0x2119, 0x211d}, {0x212a, 0x212d},
+    {0x2130, 0x2133}, {0x2c00, 0x2c2e}, {0x2c62, 0x2c64}, {0x2c6d, 0x2c70},
+    {0x2c7e, 0x2c80}, {0xa7aa, 0xa7ae}, {0xa7b0, 0xa7b4}, {0xff21, 0xff3a}
+#if TCL_UTF_MAX > 4
+    ,{0x10400, 0x10427}, {0x104b0, 0x104d3}, {0x10c80, 0x10cb2}, {0x118a0, 0x118bf},
+    {0x1d400, 0x1d419}, {0x1d434, 0x1d44d}, {0x1d468, 0x1d481}, {0x1d4a9, 0x1d4ac},
+    {0x1d4ae, 0x1d4b5}, {0x1d4d0, 0x1d4e9}, {0x1d507, 0x1d50a}, {0x1d50d, 0x1d514},
+    {0x1d516, 0x1d51c}, {0x1d53b, 0x1d53e}, {0x1d540, 0x1d544}, {0x1d54a, 0x1d550},
+    {0x1d56c, 0x1d585}, {0x1d5a0, 0x1d5b9}, {0x1d5d4, 0x1d5ed}, {0x1d608, 0x1d621},
+    {0x1d63c, 0x1d655}, {0x1d670, 0x1d689}, {0x1d6a8, 0x1d6c0}, {0x1d6e2, 0x1d6fa},
+    {0x1d71c, 0x1d734}, {0x1d756, 0x1d76e}, {0x1d790, 0x1d7a8}, {0x1e900, 0x1e921}
+#endif
+};
+
+#define NUM_UPPER_RANGE (sizeof(upperRangeTable)/sizeof(crange))
+
+static const chr upperCharTable[] = {
+    0x100, 0x102, 0x104, 0x106, 0x108, 0x10a, 0x10c, 0x10e, 0x110,
+    0x112, 0x114, 0x116, 0x118, 0x11a, 0x11c, 0x11e, 0x120, 0x122,
+    0x124, 0x126, 0x128, 0x12a, 0x12c, 0x12e, 0x130, 0x132, 0x134,
+    0x136, 0x139, 0x13b, 0x13d, 0x13f, 0x141, 0x143, 0x145, 0x147,
+    0x14a, 0x14c, 0x14e, 0x150, 0x152, 0x154, 0x156, 0x158, 0x15a,
+    0x15c, 0x15e, 0x160, 0x162, 0x164, 0x166, 0x168, 0x16a, 0x16c,
+    0x16e, 0x170, 0x172, 0x174, 0x176, 0x178, 0x179, 0x17b, 0x17d,
+    0x181, 0x182, 0x184, 0x186, 0x187, 0x193, 0x194, 0x19c, 0x19d,
+    0x19f, 0x1a0, 0x1a2, 0x1a4, 0x1a6, 0x1a7, 0x1a9, 0x1ac, 0x1ae,
+    0x1af, 0x1b5, 0x1b7, 0x1b8, 0x1bc, 0x1c4, 0x1c7, 0x1ca, 0x1cd,
+    0x1cf, 0x1d1, 0x1d3, 0x1d5, 0x1d7, 0x1d9, 0x1db, 0x1de, 0x1e0,
+    0x1e2, 0x1e4, 0x1e6, 0x1e8, 0x1ea, 0x1ec, 0x1ee, 0x1f1, 0x1f4,
+    0x1fa, 0x1fc, 0x1fe, 0x200, 0x202, 0x204, 0x206, 0x208, 0x20a,
+    0x20c, 0x20e, 0x210, 0x212, 0x214, 0x216, 0x218, 0x21a, 0x21c,
+    0x21e, 0x220, 0x222, 0x224, 0x226, 0x228, 0x22a, 0x22c, 0x22e,
+    0x230, 0x232, 0x23a, 0x23b, 0x23d, 0x23e, 0x241, 0x248, 0x24a,
+    0x24c, 0x24e, 0x370, 0x372, 0x376, 0x37f, 0x386, 0x38c, 0x38e,
+    0x38f, 0x3cf, 0x3d8, 0x3da, 0x3dc, 0x3de, 0x3e0, 0x3e2, 0x3e4,
+    0x3e6, 0x3e8, 0x3ea, 0x3ec, 0x3ee, 0x3f4, 0x3f7, 0x3f9, 0x3fa,
+    0x460, 0x462, 0x464, 0x466, 0x468, 0x46a, 0x46c, 0x46e, 0x470,
+    0x472, 0x474, 0x476, 0x478, 0x47a, 0x47c, 0x47e, 0x480, 0x48a,
+    0x48c, 0x48e, 0x490, 0x492, 0x494, 0x496, 0x498, 0x49a, 0x49c,
+    0x49e, 0x4a0, 0x4a2, 0x4a4, 0x4a6, 0x4a8, 0x4aa, 0x4ac, 0x4ae,
+    0x4b0, 0x4b2, 0x4b4, 0x4b6, 0x4b8, 0x4ba, 0x4bc, 0x4be, 0x4c0,
+    0x4c1, 0x4c3, 0x4c5, 0x4c7, 0x4c9, 0x4cb, 0x4cd, 0x4d0, 0x4d2,
+    0x4d4, 0x4d6, 0x4d8, 0x4da, 0x4dc, 0x4de, 0x4e0, 0x4e2, 0x4e4,
+    0x4e6, 0x4e8, 0x4ea, 0x4ec, 0x4ee, 0x4f0, 0x4f2, 0x4f4, 0x4f6,
+    0x4f8, 0x4fa, 0x4fc, 0x4fe, 0x500, 0x502, 0x504, 0x506, 0x508,
+    0x50a, 0x50c, 0x50e, 0x510, 0x512, 0x514, 0x516, 0x518, 0x51a,
+    0x51c, 0x51e, 0x520, 0x522, 0x524, 0x526, 0x528, 0x52a, 0x52c,
+    0x52e, 0x10c7, 0x10cd, 0x1e00, 0x1e02, 0x1e04, 0x1e06, 0x1e08, 0x1e0a,
+    0x1e0c, 0x1e0e, 0x1e10, 0x1e12, 0x1e14, 0x1e16, 0x1e18, 0x1e1a, 0x1e1c,
+    0x1e1e, 0x1e20, 0x1e22, 0x1e24, 0x1e26, 0x1e28, 0x1e2a, 0x1e2c, 0x1e2e,
+    0x1e30, 0x1e32, 0x1e34, 0x1e36, 0x1e38, 0x1e3a, 0x1e3c, 0x1e3e, 0x1e40,
+    0x1e42, 0x1e44, 0x1e46, 0x1e48, 0x1e4a, 0x1e4c, 0x1e4e, 0x1e50, 0x1e52,
+    0x1e54, 0x1e56, 0x1e58, 0x1e5a, 0x1e5c, 0x1e5e, 0x1e60, 0x1e62, 0x1e64,
+    0x1e66, 0x1e68, 0x1e6a, 0x1e6c, 0x1e6e, 0x1e70, 0x1e72, 0x1e74, 0x1e76,
+    0x1e78, 0x1e7a, 0x1e7c, 0x1e7e, 0x1e80, 0x1e82, 0x1e84, 0x1e86, 0x1e88,
+    0x1e8a, 0x1e8c, 0x1e8e, 0x1e90, 0x1e92, 0x1e94, 0x1e9e, 0x1ea0, 0x1ea2,
+    0x1ea4, 0x1ea6, 0x1ea8, 0x1eaa, 0x1eac, 0x1eae, 0x1eb0, 0x1eb2, 0x1eb4,
+    0x1eb6, 0x1eb8, 0x1eba, 0x1ebc, 0x1ebe, 0x1ec0, 0x1ec2, 0x1ec4, 0x1ec6,
+    0x1ec8, 0x1eca, 0x1ecc, 0x1ece, 0x1ed0, 0x1ed2, 0x1ed4, 0x1ed6, 0x1ed8,
+    0x1eda, 0x1edc, 0x1ede, 0x1ee0, 0x1ee2, 0x1ee4, 0x1ee6, 0x1ee8, 0x1eea,
+    0x1eec, 0x1eee, 0x1ef0, 0x1ef2, 0x1ef4, 0x1ef6, 0x1ef8, 0x1efa, 0x1efc,
+    0x1efe, 0x1f59, 0x1f5b, 0x1f5d, 0x1f5f, 0x2102, 0x2107, 0x2115, 0x2124,
+    0x2126, 0x2128, 0x213e, 0x213f, 0x2145, 0x2183, 0x2c60, 0x2c67, 0x2c69,
+    0x2c6b, 0x2c72, 0x2c75, 0x2c82, 0x2c84, 0x2c86, 0x2c88, 0x2c8a, 0x2c8c,
+    0x2c8e, 0x2c90, 0x2c92, 0x2c94, 0x2c96, 0x2c98, 0x2c9a, 0x2c9c, 0x2c9e,
+    0x2ca0, 0x2ca2, 0x2ca4, 0x2ca6, 0x2ca8, 0x2caa, 0x2cac, 0x2cae, 0x2cb0,
+    0x2cb2, 0x2cb4, 0x2cb6, 0x2cb8, 0x2cba, 0x2cbc, 0x2cbe, 0x2cc0, 0x2cc2,
+    0x2cc4, 0x2cc6, 0x2cc8, 0x2cca, 0x2ccc, 0x2cce, 0x2cd0, 0x2cd2, 0x2cd4,
+    0x2cd6, 0x2cd8, 0x2cda, 0x2cdc, 0x2cde, 0x2ce0, 0x2ce2, 0x2ceb, 0x2ced,
+    0x2cf2, 0xa640, 0xa642, 0xa644, 0xa646, 0xa648, 0xa64a, 0xa64c, 0xa64e,
+    0xa650, 0xa652, 0xa654, 0xa656, 0xa658, 0xa65a, 0xa65c, 0xa65e, 0xa660,
+    0xa662, 0xa664, 0xa666, 0xa668, 0xa66a, 0xa66c, 0xa680, 0xa682, 0xa684,
+    0xa686, 0xa688, 0xa68a, 0xa68c, 0xa68e, 0xa690, 0xa692, 0xa694, 0xa696,
+    0xa698, 0xa69a, 0xa722, 0xa724, 0xa726, 0xa728, 0xa72a, 0xa72c, 0xa72e,
+    0xa732, 0xa734, 0xa736, 0xa738, 0xa73a, 0xa73c, 0xa73e, 0xa740, 0xa742,
+    0xa744, 0xa746, 0xa748, 0xa74a, 0xa74c, 0xa74e, 0xa750, 0xa752, 0xa754,
+    0xa756, 0xa758, 0xa75a, 0xa75c, 0xa75e, 0xa760, 0xa762, 0xa764, 0xa766,
+    0xa768, 0xa76a, 0xa76c, 0xa76e, 0xa779, 0xa77b, 0xa77d, 0xa77e, 0xa780,
+    0xa782, 0xa784, 0xa786, 0xa78b, 0xa78d, 0xa790, 0xa792, 0xa796, 0xa798,
+    0xa79a, 0xa79c, 0xa79e, 0xa7a0, 0xa7a2, 0xa7a4, 0xa7a6, 0xa7a8, 0xa7b6
+#if TCL_UTF_MAX > 4
+    ,0x1d49c, 0x1d49e, 0x1d49f, 0x1d4a2, 0x1d4a5, 0x1d4a6, 0x1d504, 0x1d505, 0x1d538,
+    0x1d539, 0x1d546, 0x1d7ca
+#endif
+};
+
+#define NUM_UPPER_CHAR (sizeof(upperCharTable)/sizeof(chr))
+
+/*
+ * Unicode: unicode print characters excluding space.
+ */
+
+static const crange graphRangeTable[] = {
+    {0x21, 0x7e}, {0xa1, 0xac}, {0xae, 0x377}, {0x37a, 0x37f},
+    {0x384, 0x38a}, {0x38e, 0x3a1}, {0x3a3, 0x52f}, {0x531, 0x556},
+    {0x559, 0x55f}, {0x561, 0x587}, {0x58d, 0x58f}, {0x591, 0x5c7},
+    {0x5d0, 0x5ea}, {0x5f0, 0x5f4}, {0x606, 0x61b}, {0x61e, 0x6dc},
+    {0x6de, 0x70d}, {0x710, 0x74a}, {0x74d, 0x7b1}, {0x7c0, 0x7fa},
+    {0x800, 0x82d}, {0x830, 0x83e}, {0x840, 0x85b}, {0x8a0, 0x8b4},
+    {0x8b6, 0x8bd}, {0x8d4, 0x8e1}, {0x8e3, 0x983}, {0x985, 0x98c},
+    {0x993, 0x9a8}, {0x9aa, 0x9b0}, {0x9b6, 0x9b9}, {0x9bc, 0x9c4},
+    {0x9cb, 0x9ce}, {0x9df, 0x9e3}, {0x9e6, 0x9fb}, {0xa01, 0xa03},
+    {0xa05, 0xa0a}, {0xa13, 0xa28}, {0xa2a, 0xa30}, {0xa3e, 0xa42},
+    {0xa4b, 0xa4d}, {0xa59, 0xa5c}, {0xa66, 0xa75}, {0xa81, 0xa83},
+    {0xa85, 0xa8d}, {0xa8f, 0xa91}, {0xa93, 0xaa8}, {0xaaa, 0xab0},
+    {0xab5, 0xab9}, {0xabc, 0xac5}, {0xac7, 0xac9}, {0xacb, 0xacd},
+    {0xae0, 0xae3}, {0xae6, 0xaf1}, {0xb01, 0xb03}, {0xb05, 0xb0c},
+    {0xb13, 0xb28}, {0xb2a, 0xb30}, {0xb35, 0xb39}, {0xb3c, 0xb44},
+    {0xb4b, 0xb4d}, {0xb5f, 0xb63}, {0xb66, 0xb77}, {0xb85, 0xb8a},
+    {0xb8e, 0xb90}, {0xb92, 0xb95}, {0xba8, 0xbaa}, {0xbae, 0xbb9},
+    {0xbbe, 0xbc2}, {0xbc6, 0xbc8}, {0xbca, 0xbcd}, {0xbe6, 0xbfa},
+    {0xc00, 0xc03}, {0xc05, 0xc0c}, {0xc0e, 0xc10}, {0xc12, 0xc28},
+    {0xc2a, 0xc39}, {0xc3d, 0xc44}, {0xc46, 0xc48}, {0xc4a, 0xc4d},
+    {0xc58, 0xc5a}, {0xc60, 0xc63}, {0xc66, 0xc6f}, {0xc78, 0xc83},
+    {0xc85, 0xc8c}, {0xc8e, 0xc90}, {0xc92, 0xca8}, {0xcaa, 0xcb3},
+    {0xcb5, 0xcb9}, {0xcbc, 0xcc4}, {0xcc6, 0xcc8}, {0xcca, 0xccd},
+    {0xce0, 0xce3}, {0xce6, 0xcef}, {0xd01, 0xd03}, {0xd05, 0xd0c},
+    {0xd0e, 0xd10}, {0xd12, 0xd3a}, {0xd3d, 0xd44}, {0xd46, 0xd48},
+    {0xd4a, 0xd4f}, {0xd54, 0xd63}, {0xd66, 0xd7f}, {0xd85, 0xd96},
+    {0xd9a, 0xdb1}, {0xdb3, 0xdbb}, {0xdc0, 0xdc6}, {0xdcf, 0xdd4},
+    {0xdd8, 0xddf}, {0xde6, 0xdef}, {0xdf2, 0xdf4}, {0xe01, 0xe3a},
+    {0xe3f, 0xe5b}, {0xe94, 0xe97}, {0xe99, 0xe9f}, {0xea1, 0xea3},
+    {0xead, 0xeb9}, {0xebb, 0xebd}, {0xec0, 0xec4}, {0xec8, 0xecd},
+    {0xed0, 0xed9}, {0xedc, 0xedf}, {0xf00, 0xf47}, {0xf49, 0xf6c},
+    {0xf71, 0xf97}, {0xf99, 0xfbc}, {0xfbe, 0xfcc}, {0xfce, 0xfda},
+    {0x1000, 0x10c5}, {0x10d0, 0x1248}, {0x124a, 0x124d}, {0x1250, 0x1256},
+    {0x125a, 0x125d}, {0x1260, 0x1288}, {0x128a, 0x128d}, {0x1290, 0x12b0},
+    {0x12b2, 0x12b5}, {0x12b8, 0x12be}, {0x12c2, 0x12c5}, {0x12c8, 0x12d6},
+    {0x12d8, 0x1310}, {0x1312, 0x1315}, {0x1318, 0x135a}, {0x135d, 0x137c},
+    {0x1380, 0x1399}, {0x13a0, 0x13f5}, {0x13f8, 0x13fd}, {0x1400, 0x167f},
+    {0x1681, 0x169c}, {0x16a0, 0x16f8}, {0x1700, 0x170c}, {0x170e, 0x1714},
+    {0x1720, 0x1736}, {0x1740, 0x1753}, {0x1760, 0x176c}, {0x176e, 0x1770},
+    {0x1780, 0x17dd}, {0x17e0, 0x17e9}, {0x17f0, 0x17f9}, {0x1800, 0x180d},
+    {0x1810, 0x1819}, {0x1820, 0x1877}, {0x1880, 0x18aa}, {0x18b0, 0x18f5},
+    {0x1900, 0x191e}, {0x1920, 0x192b}, {0x1930, 0x193b}, {0x1944, 0x196d},
+    {0x1970, 0x1974}, {0x1980, 0x19ab}, {0x19b0, 0x19c9}, {0x19d0, 0x19da},
+    {0x19de, 0x1a1b}, {0x1a1e, 0x1a5e}, {0x1a60, 0x1a7c}, {0x1a7f, 0x1a89},
+    {0x1a90, 0x1a99}, {0x1aa0, 0x1aad}, {0x1ab0, 0x1abe}, {0x1b00, 0x1b4b},
+    {0x1b50, 0x1b7c}, {0x1b80, 0x1bf3}, {0x1bfc, 0x1c37}, {0x1c3b, 0x1c49},
+    {0x1c4d, 0x1c88}, {0x1cc0, 0x1cc7}, {0x1cd0, 0x1cf6}, {0x1d00, 0x1df5},
+    {0x1dfb, 0x1f15}, {0x1f18, 0x1f1d}, {0x1f20, 0x1f45}, {0x1f48, 0x1f4d},
+    {0x1f50, 0x1f57}, {0x1f5f, 0x1f7d}, {0x1f80, 0x1fb4}, {0x1fb6, 0x1fc4},
+    {0x1fc6, 0x1fd3}, {0x1fd6, 0x1fdb}, {0x1fdd, 0x1fef}, {0x1ff2, 0x1ff4},
+    {0x1ff6, 0x1ffe}, {0x2010, 0x2027}, {0x2030, 0x205e}, {0x2074, 0x208e},
+    {0x2090, 0x209c}, {0x20a0, 0x20be}, {0x20d0, 0x20f0}, {0x2100, 0x218b},
+    {0x2190, 0x23fe}, {0x2400, 0x2426}, {0x2440, 0x244a}, {0x2460, 0x2b73},
+    {0x2b76, 0x2b95}, {0x2b98, 0x2bb9}, {0x2bbd, 0x2bc8}, {0x2bca, 0x2bd1},
+    {0x2bec, 0x2bef}, {0x2c00, 0x2c2e}, {0x2c30, 0x2c5e}, {0x2c60, 0x2cf3},
+    {0x2cf9, 0x2d25}, {0x2d30, 0x2d67}, {0x2d7f, 0x2d96}, {0x2da0, 0x2da6},
+    {0x2da8, 0x2dae}, {0x2db0, 0x2db6}, {0x2db8, 0x2dbe}, {0x2dc0, 0x2dc6},
+    {0x2dc8, 0x2dce}, {0x2dd0, 0x2dd6}, {0x2dd8, 0x2dde}, {0x2de0, 0x2e44},
+    {0x2e80, 0x2e99}, {0x2e9b, 0x2ef3}, {0x2f00, 0x2fd5}, {0x2ff0, 0x2ffb},
+    {0x3001, 0x303f}, {0x3041, 0x3096}, {0x3099, 0x30ff}, {0x3105, 0x312d},
+    {0x3131, 0x318e}, {0x3190, 0x31ba}, {0x31c0, 0x31e3}, {0x31f0, 0x321e},
+    {0x3220, 0x32fe}, {0x3300, 0x4db5}, {0x4dc0, 0x9fd5}, {0xa000, 0xa48c},
+    {0xa490, 0xa4c6}, {0xa4d0, 0xa62b}, {0xa640, 0xa6f7}, {0xa700, 0xa7ae},
+    {0xa7b0, 0xa7b7}, {0xa7f7, 0xa82b}, {0xa830, 0xa839}, {0xa840, 0xa877},
+    {0xa880, 0xa8c5}, {0xa8ce, 0xa8d9}, {0xa8e0, 0xa8fd}, {0xa900, 0xa953},
+    {0xa95f, 0xa97c}, {0xa980, 0xa9cd}, {0xa9cf, 0xa9d9}, {0xa9de, 0xa9fe},
+    {0xaa00, 0xaa36}, {0xaa40, 0xaa4d}, {0xaa50, 0xaa59}, {0xaa5c, 0xaac2},
+    {0xaadb, 0xaaf6}, {0xab01, 0xab06}, {0xab09, 0xab0e}, {0xab11, 0xab16},
+    {0xab20, 0xab26}, {0xab28, 0xab2e}, {0xab30, 0xab65}, {0xab70, 0xabed},
+    {0xabf0, 0xabf9}, {0xac00, 0xd7a3}, {0xd7b0, 0xd7c6}, {0xd7cb, 0xd7fb},
+    {0xdc00, 0xdc3e}, {0xdc40, 0xdc7e}, {0xdc80, 0xdcbe}, {0xdcc0, 0xdcfe},
+    {0xdd00, 0xdd3e}, {0xdd40, 0xdd7e}, {0xdd80, 0xddbe}, {0xddc0, 0xddfe},
+    {0xde00, 0xde3e}, {0xde40, 0xde7e}, {0xde80, 0xdebe}, {0xdec0, 0xdefe},
+    {0xdf00, 0xdf3e}, {0xdf40, 0xdf7e}, {0xdf80, 0xdfbe}, {0xdfc0, 0xdffe},
+    {0xf900, 0xfa6d}, {0xfa70, 0xfad9}, {0xfb00, 0xfb06}, {0xfb13, 0xfb17},
+    {0xfb1d, 0xfb36}, {0xfb38, 0xfb3c}, {0xfb46, 0xfbc1}, {0xfbd3, 0xfd3f},
+    {0xfd50, 0xfd8f}, {0xfd92, 0xfdc7}, {0xfdf0, 0xfdfd}, {0xfe00, 0xfe19},
+    {0xfe20, 0xfe52}, {0xfe54, 0xfe66}, {0xfe68, 0xfe6b}, {0xfe70, 0xfe74},
+    {0xfe76, 0xfefc}, {0xff01, 0xffbe}, {0xffc2, 0xffc7}, {0xffca, 0xffcf},
+    {0xffd2, 0xffd7}, {0xffda, 0xffdc}, {0xffe0, 0xffe6}, {0xffe8, 0xffee}
+#if TCL_UTF_MAX > 4
+    ,{0x10000, 0x1000b}, {0x1000d, 0x10026}, {0x10028, 0x1003a}, {0x1003f, 0x1004d},
+    {0x10050, 0x1005d}, {0x10080, 0x100fa}, {0x10100, 0x10102}, {0x10107, 0x10133},
+    {0x10137, 0x1018e}, {0x10190, 0x1019b}, {0x101d0, 0x101fd}, {0x10280, 0x1029c},
+    {0x102a0, 0x102d0}, {0x102e0, 0x102fb}, {0x10300, 0x10323}, {0x10330, 0x1034a},
+    {0x10350, 0x1037a}, {0x10380, 0x1039d}, {0x1039f, 0x103c3}, {0x103c8, 0x103d5},
+    {0x10400, 0x1049d}, {0x104a0, 0x104a9}, {0x104b0, 0x104d3}, {0x104d8, 0x104fb},
+    {0x10500, 0x10527}, {0x10530, 0x10563}, {0x10600, 0x10736}, {0x10740, 0x10755},
+    {0x10760, 0x10767}, {0x10800, 0x10805}, {0x1080a, 0x10835}, {0x1083f, 0x10855},
+    {0x10857, 0x1089e}, {0x108a7, 0x108af}, {0x108e0, 0x108f2}, {0x108fb, 0x1091b},
+    {0x1091f, 0x10939}, {0x10980, 0x109b7}, {0x109bc, 0x109cf}, {0x109d2, 0x10a03},
+    {0x10a0c, 0x10a13}, {0x10a15, 0x10a17}, {0x10a19, 0x10a33}, {0x10a38, 0x10a3a},
+    {0x10a3f, 0x10a47}, {0x10a50, 0x10a58}, {0x10a60, 0x10a9f}, {0x10ac0, 0x10ae6},
+    {0x10aeb, 0x10af6}, {0x10b00, 0x10b35}, {0x10b39, 0x10b55}, {0x10b58, 0x10b72},
+    {0x10b78, 0x10b91}, {0x10b99, 0x10b9c}, {0x10ba9, 0x10baf}, {0x10c00, 0x10c48},
+    {0x10c80, 0x10cb2}, {0x10cc0, 0x10cf2}, {0x10cfa, 0x10cff}, {0x10e60, 0x10e7e},
+    {0x11000, 0x1104d}, {0x11052, 0x1106f}, {0x1107f, 0x110bc}, {0x110be, 0x110c1},
+    {0x110d0, 0x110e8}, {0x110f0, 0x110f9}, {0x11100, 0x11134}, {0x11136, 0x11143},
+    {0x11150, 0x11176}, {0x11180, 0x111cd}, {0x111d0, 0x111df}, {0x111e1, 0x111f4},
+    {0x11200, 0x11211}, {0x11213, 0x1123e}, {0x11280, 0x11286}, {0x1128a, 0x1128d},
+    {0x1128f, 0x1129d}, {0x1129f, 0x112a9}, {0x112b0, 0x112ea}, {0x112f0, 0x112f9},
+    {0x11300, 0x11303}, {0x11305, 0x1130c}, {0x11313, 0x11328}, {0x1132a, 0x11330},
+    {0x11335, 0x11339}, {0x1133c, 0x11344}, {0x1134b, 0x1134d}, {0x1135d, 0x11363},
+    {0x11366, 0x1136c}, {0x11370, 0x11374}, {0x11400, 0x11459}, {0x11480, 0x114c7},
+    {0x114d0, 0x114d9}, {0x11580, 0x115b5}, {0x115b8, 0x115dd}, {0x11600, 0x11644},
+    {0x11650, 0x11659}, {0x11660, 0x1166c}, {0x11680, 0x116b7}, {0x116c0, 0x116c9},
+    {0x11700, 0x11719}, {0x1171d, 0x1172b}, {0x11730, 0x1173f}, {0x118a0, 0x118f2},
+    {0x11ac0, 0x11af8}, {0x11c00, 0x11c08}, {0x11c0a, 0x11c36}, {0x11c38, 0x11c45},
+    {0x11c50, 0x11c6c}, {0x11c70, 0x11c8f}, {0x11c92, 0x11ca7}, {0x11ca9, 0x11cb6},
+    {0x12000, 0x12399}, {0x12400, 0x1246e}, {0x12470, 0x12474}, {0x12480, 0x12543},
+    {0x13000, 0x1342e}, {0x14400, 0x14646}, {0x16800, 0x16a38}, {0x16a40, 0x16a5e},
+    {0x16a60, 0x16a69}, {0x16ad0, 0x16aed}, {0x16af0, 0x16af5}, {0x16b00, 0x16b45},
+    {0x16b50, 0x16b59}, {0x16b5b, 0x16b61}, {0x16b63, 0x16b77}, {0x16b7d, 0x16b8f},
+    {0x16f00, 0x16f44}, {0x16f50, 0x16f7e}, {0x16f8f, 0x16f9f}, {0x17000, 0x187ec},
+    {0x18800, 0x18af2}, {0x1bc00, 0x1bc6a}, {0x1bc70, 0x1bc7c}, {0x1bc80, 0x1bc88},
+    {0x1bc90, 0x1bc99}, {0x1bc9c, 0x1bc9f}, {0x1d000, 0x1d0f5}, {0x1d100, 0x1d126},
+    {0x1d129, 0x1d172}, {0x1d17b, 0x1d1e8}, {0x1d200, 0x1d245}, {0x1d300, 0x1d356},
+    {0x1d360, 0x1d371}, {0x1d400, 0x1d454}, {0x1d456, 0x1d49c}, {0x1d4a9, 0x1d4ac},
+    {0x1d4ae, 0x1d4b9}, {0x1d4bd, 0x1d4c3}, {0x1d4c5, 0x1d505}, {0x1d507, 0x1d50a},
+    {0x1d50d, 0x1d514}, {0x1d516, 0x1d51c}, {0x1d51e, 0x1d539}, {0x1d53b, 0x1d53e},
+    {0x1d540, 0x1d544}, {0x1d54a, 0x1d550}, {0x1d552, 0x1d6a5}, {0x1d6a8, 0x1d7cb},
+    {0x1d7ce, 0x1da8b}, {0x1da9b, 0x1da9f}, {0x1daa1, 0x1daaf}, {0x1e000, 0x1e006},
+    {0x1e008, 0x1e018}, {0x1e01b, 0x1e021}, {0x1e026, 0x1e02a}, {0x1e800, 0x1e8c4},
+    {0x1e8c7, 0x1e8d6}, {0x1e900, 0x1e94a}, {0x1e950, 0x1e959}, {0x1ee00, 0x1ee03},
+    {0x1ee05, 0x1ee1f}, {0x1ee29, 0x1ee32}, {0x1ee34, 0x1ee37}, {0x1ee4d, 0x1ee4f},
+    {0x1ee67, 0x1ee6a}, {0x1ee6c, 0x1ee72}, {0x1ee74, 0x1ee77}, {0x1ee79, 0x1ee7c},
+    {0x1ee80, 0x1ee89}, {0x1ee8b, 0x1ee9b}, {0x1eea1, 0x1eea3}, {0x1eea5, 0x1eea9},
+    {0x1eeab, 0x1eebb}, {0x1f000, 0x1f02b}, {0x1f030, 0x1f093}, {0x1f0a0, 0x1f0ae},
+    {0x1f0b1, 0x1f0bf}, {0x1f0c1, 0x1f0cf}, {0x1f0d1, 0x1f0f5}, {0x1f100, 0x1f10c},
+    {0x1f110, 0x1f12e}, {0x1f130, 0x1f16b}, {0x1f170, 0x1f1ac}, {0x1f1e6, 0x1f202},
+    {0x1f210, 0x1f23b}, {0x1f240, 0x1f248}, {0x1f300, 0x1f6d2}, {0x1f6e0, 0x1f6ec},
+    {0x1f6f0, 0x1f6f6}, {0x1f700, 0x1f773}, {0x1f780, 0x1f7d4}, {0x1f800, 0x1f80b},
+    {0x1f810, 0x1f847}, {0x1f850, 0x1f859}, {0x1f860, 0x1f887}, {0x1f890, 0x1f8ad},
+    {0x1f910, 0x1f91e}, {0x1f920, 0x1f927}, {0x1f933, 0x1f93e}, {0x1f940, 0x1f94b},
+    {0x1f950, 0x1f95e}, {0x1f980, 0x1f991}, {0x20000, 0x2a6d6}, {0x2a700, 0x2b734},
+    {0x2b740, 0x2b81d}, {0x2b820, 0x2cea1}, {0x2f800, 0x2fa1d}, {0xe0100, 0xe01ef}
+#endif
+};
+
+#define NUM_GRAPH_RANGE (sizeof(graphRangeTable)/sizeof(crange))
+
+static const chr graphCharTable[] = {
+    0x38c, 0x589, 0x58a, 0x85e, 0x98f, 0x990, 0x9b2, 0x9c7, 0x9c8,
+    0x9d7, 0x9dc, 0x9dd, 0xa0f, 0xa10, 0xa32, 0xa33, 0xa35, 0xa36,
+    0xa38, 0xa39, 0xa3c, 0xa47, 0xa48, 0xa51, 0xa5e, 0xab2, 0xab3,
+    0xad0, 0xaf9, 0xb0f, 0xb10, 0xb32, 0xb33, 0xb47, 0xb48, 0xb56,
+    0xb57, 0xb5c, 0xb5d, 0xb82, 0xb83, 0xb99, 0xb9a, 0xb9c, 0xb9e,
+    0xb9f, 0xba3, 0xba4, 0xbd0, 0xbd7, 0xc55, 0xc56, 0xcd5, 0xcd6,
+    0xcde, 0xcf1, 0xcf2, 0xd82, 0xd83, 0xdbd, 0xdca, 0xdd6, 0xe81,
+    0xe82, 0xe84, 0xe87, 0xe88, 0xe8a, 0xe8d, 0xea5, 0xea7, 0xeaa,
+    0xeab, 0xec6, 0x10c7, 0x10cd, 0x1258, 0x12c0, 0x1772, 0x1773, 0x1940,
+    0x1cf8, 0x1cf9, 0x1f59, 0x1f5b, 0x1f5d, 0x2070, 0x2071, 0x2d27, 0x2d2d,
+    0x2d6f, 0x2d70, 0xfb3e, 0xfb40, 0xfb41, 0xfb43, 0xfb44, 0xfffc, 0xfffd
+#if TCL_UTF_MAX > 4
+    ,0x1003c, 0x1003d, 0x101a0, 0x1056f, 0x10808, 0x10837, 0x10838, 0x1083c, 0x108f4,
+    0x108f5, 0x1093f, 0x10a05, 0x10a06, 0x11288, 0x1130f, 0x11310, 0x11332, 0x11333,
+    0x11347, 0x11348, 0x11350, 0x11357, 0x1145b, 0x1145d, 0x118ff, 0x16a6e, 0x16a6f,
+    0x16fe0, 0x1b000, 0x1b001, 0x1d49e, 0x1d49f, 0x1d4a2, 0x1d4a5, 0x1d4a6, 0x1d4bb,
+    0x1d546, 0x1e023, 0x1e024, 0x1e95e, 0x1e95f, 0x1ee21, 0x1ee22, 0x1ee24, 0x1ee27,
+    0x1ee39, 0x1ee3b, 0x1ee42, 0x1ee47, 0x1ee49, 0x1ee4b, 0x1ee51, 0x1ee52, 0x1ee54,
+    0x1ee57, 0x1ee59, 0x1ee5b, 0x1ee5d, 0x1ee5f, 0x1ee61, 0x1ee62, 0x1ee64, 0x1ee7e,
+    0x1eef0, 0x1eef1, 0x1f250, 0x1f251, 0x1f930, 0x1f9c0
+#endif
+};
+
+#define NUM_GRAPH_CHAR (sizeof(graphCharTable)/sizeof(chr))
+
+/*
+ *	End of auto-generated Unicode character ranges declarations.
+ */
+
+#define	CH	NOCELT
+
+/*
+ - element - map collating-element name to celt
+ ^ static celt element(struct vars *, const chr *, const chr *);
+ */
+static celt
+element(
+    struct vars *v,		/* context */
+    const chr *startp,		/* points to start of name */
+    const chr *endp)		/* points just past end of name */
+{
+    const struct cname *cn;
+    size_t len;
+    Tcl_DString ds;
+    const char *np;
+
+    /*
+     * Generic: one-chr names stand for themselves.
+     */
+
+    assert(startp < endp);
+    len = endp - startp;
+    if (len == 1) {
+	return *startp;
+    }
+
+    NOTE(REG_ULOCALE);
+
+    /*
+     * Search table.
+     */
+
+    Tcl_DStringInit(&ds);
+    np = Tcl_UniCharToUtfDString(startp, (int)len, &ds);
+    for (cn=cnames; cn->name!=NULL; cn++) {
+	if (strlen(cn->name)==len && strncmp(cn->name, np, len)==0) {
+	    break;			/* NOTE BREAK OUT */
+	}
+    }
+    Tcl_DStringFree(&ds);
+    if (cn->name != NULL) {
+	return CHR(cn->code);
+    }
+
+    /*
+     * Couldn't find it.
+     */
+
+    ERR(REG_ECOLLATE);
+    return 0;
+}
+
+/*
+ - range - supply cvec for a range, including legality check
+ ^ static struct cvec *range(struct vars *, celt, celt, int);
+ */
+static struct cvec *
+range(
+    struct vars *v,		/* context */
+    celt a,			/* range start */
+    celt b,			/* range end, might equal a */
+    int cases)			/* case-independent? */
+{
+    int nchrs;
+    struct cvec *cv;
+    celt c, lc, uc, tc;
+
+    if (a != b && !before(a, b)) {
+	ERR(REG_ERANGE);
+	return NULL;
+    }
+
+    if (!cases) {		/* easy version */
+	cv = getcvec(v, 0, 1);
+	NOERRN();
+	addrange(cv, a, b);
+	return cv;
+    }
+
+    /*
+     * When case-independent, it's hard to decide when cvec ranges are usable,
+     * so for now at least, we won't try. We allocate enough space for two
+     * case variants plus a little extra for the two title case variants.
+     */
+
+    nchrs = (b - a + 1)*2 + 4;
+
+    cv = getcvec(v, nchrs, 0);
+    NOERRN();
+
+    for (c=a; c<=b; c++) {
+	addchr(cv, c);
+	lc = Tcl_UniCharToLower((chr)c);
+	uc = Tcl_UniCharToUpper((chr)c);
+	tc = Tcl_UniCharToTitle((chr)c);
+	if (c != lc) {
+	    addchr(cv, lc);
+	}
+	if (c != uc) {
+	    addchr(cv, uc);
+	}
+	if (c != tc && tc != uc) {
+	    addchr(cv, tc);
+	}
+    }
+
+    return cv;
+}
+
+/*
+ - before - is celt x before celt y, for purposes of range legality?
+ ^ static int before(celt, celt);
+ */
+static int			/* predicate */
+before(
+    celt x, celt y)		/* collating elements */
+{
+    if (x < y) {
+	return 1;
+    }
+    return 0;
+}
+
+/*
+ - eclass - supply cvec for an equivalence class
+ * Must include case counterparts on request.
+ ^ static struct cvec *eclass(struct vars *, celt, int);
+ */
+static struct cvec *
+eclass(
+    struct vars *v,		/* context */
+    celt c,			/* Collating element representing the
+				 * equivalence class. */
+    int cases)			/* all cases? */
+{
+    struct cvec *cv;
+
+    /*
+     * Crude fake equivalence class for testing.
+     */
+
+    if ((v->cflags&REG_FAKE) && c == 'x') {
+	cv = getcvec(v, 4, 0);
+	addchr(cv, (chr)'x');
+	addchr(cv, (chr)'y');
+	if (cases) {
+	    addchr(cv, (chr)'X');
+	    addchr(cv, (chr)'Y');
+	}
+	return cv;
+    }
+
+    /*
+     * Otherwise, none.
+     */
+
+    if (cases) {
+	return allcases(v, c);
+    }
+    cv = getcvec(v, 1, 0);
+    assert(cv != NULL);
+    addchr(cv, (chr)c);
+    return cv;
+}
+
+/*
+ - cclass - supply cvec for a character class
+ * Must include case counterparts on request.
+ ^ static struct cvec *cclass(struct vars *, const chr *, const chr *, int);
+ */
+static struct cvec *
+cclass(
+    struct vars *v,		/* context */
+    const chr *startp,		/* where the name starts */
+    const chr *endp,		/* just past the end of the name */
+    int cases)			/* case-independent? */
+{
+    size_t len;
+    struct cvec *cv = NULL;
+    Tcl_DString ds;
+    const char *np;
+    const char *const *namePtr;
+    int i, index;
+
+    /*
+     * The following arrays define the valid character class names.
+     */
+
+    static const char *const classNames[] = {
+	"alnum", "alpha", "ascii", "blank", "cntrl", "digit", "graph",
+	"lower", "print", "punct", "space", "upper", "xdigit", NULL
+    };
+
+    enum classes {
+	CC_ALNUM, CC_ALPHA, CC_ASCII, CC_BLANK, CC_CNTRL, CC_DIGIT, CC_GRAPH,
+	CC_LOWER, CC_PRINT, CC_PUNCT, CC_SPACE, CC_UPPER, CC_XDIGIT
+    };
+
+
+    /*
+     * Extract the class name
+     */
+
+    len = endp - startp;
+    Tcl_DStringInit(&ds);
+    np = Tcl_UniCharToUtfDString(startp, (int)len, &ds);
+
+    /*
+     * Map the name to the corresponding enumerated value.
+     */
+
+    index = -1;
+    for (namePtr=classNames,i=0 ; *namePtr!=NULL ; namePtr++,i++) {
+	if ((strlen(*namePtr) == len) && (strncmp(*namePtr, np, len) == 0)) {
+	    index = i;
+	    break;
+	}
+    }
+    Tcl_DStringFree(&ds);
+    if (index == -1) {
+	ERR(REG_ECTYPE);
+	return NULL;
+    }
+
+    /*
+     * Remap lower and upper to alpha if the match is case insensitive.
+     */
+
+    if (cases && ((index == CC_LOWER) || (index == CC_UPPER))) {
+	index = CC_ALNUM;
+    }
+
+    /*
+     * Now compute the character class contents.
+     */
+
+    switch((enum classes) index) {
+    case CC_ALNUM:
+	cv = getcvec(v, NUM_ALPHA_CHAR, NUM_DIGIT_RANGE + NUM_ALPHA_RANGE);
+	if (cv) {
+	    for (i=0 ; (size_t)i<NUM_ALPHA_CHAR ; i++) {
+		addchr(cv, alphaCharTable[i]);
+	    }
+	    for (i=0 ; (size_t)i<NUM_ALPHA_RANGE ; i++) {
+		addrange(cv, alphaRangeTable[i].start,
+			alphaRangeTable[i].end);
+	    }
+	    for (i=0 ; (size_t)i<NUM_DIGIT_RANGE ; i++) {
+		addrange(cv, digitRangeTable[i].start,
+			digitRangeTable[i].end);
+	    }
+	}
+	break;
+    case CC_ALPHA:
+	cv = getcvec(v, NUM_ALPHA_CHAR, NUM_ALPHA_RANGE);
+	if (cv) {
+	    for (i=0 ; (size_t)i<NUM_ALPHA_RANGE ; i++) {
+		addrange(cv, alphaRangeTable[i].start,
+			alphaRangeTable[i].end);
+	    }
+	    for (i=0 ; (size_t)i<NUM_ALPHA_CHAR ; i++) {
+		addchr(cv, alphaCharTable[i]);
+	    }
+	}
+	break;
+    case CC_ASCII:
+	cv = getcvec(v, 0, 1);
+	if (cv) {
+	    addrange(cv, 0, 0x7f);
+	}
+	break;
+    case CC_BLANK:
+	cv = getcvec(v, 2, 0);
+	addchr(cv, '\t');
+	addchr(cv, ' ');
+	break;
+    case CC_CNTRL:
+	cv = getcvec(v, NUM_CONTROL_CHAR, NUM_CONTROL_RANGE);
+	if (cv) {
+	    for (i=0 ; (size_t)i<NUM_CONTROL_RANGE ; i++) {
+		addrange(cv, controlRangeTable[i].start,
+			controlRangeTable[i].end);
+	    }
+	    for (i=0 ; (size_t)i<NUM_CONTROL_CHAR ; i++) {
+		addchr(cv, controlCharTable[i]);
+	    }
+	}
+	break;
+    case CC_DIGIT:
+	cv = getcvec(v, 0, NUM_DIGIT_RANGE);
+	if (cv) {
+	    for (i=0 ; (size_t)i<NUM_DIGIT_RANGE ; i++) {
+		addrange(cv, digitRangeTable[i].start,
+			digitRangeTable[i].end);
+	    }
+	}
+	break;
+    case CC_PUNCT:
+	cv = getcvec(v, NUM_PUNCT_CHAR, NUM_PUNCT_RANGE);
+	if (cv) {
+	    for (i=0 ; (size_t)i<NUM_PUNCT_RANGE ; i++) {
+		addrange(cv, punctRangeTable[i].start,
+			punctRangeTable[i].end);
+	    }
+	    for (i=0 ; (size_t)i<NUM_PUNCT_CHAR ; i++) {
+		addchr(cv, punctCharTable[i]);
+	    }
+	}
+	break;
+    case CC_XDIGIT:
+	/*
+	 * This is a 3 instead of (NUM_DIGIT_RANGE+2) because I've no idea how
+	 * to define the digits 'a' through 'f' in non-western locales. The
+	 * concept is quite possibly non portable, or only used in contextx
+	 * where the characters used would be the western ones anyway!
+	 * Whatever is actually the case, the number of ranges is fixed (until
+	 * someone comes up with a better arrangement!)
+	 */
+
+	cv = getcvec(v, 0, 3);
+	if (cv) {
+	    addrange(cv, '0', '9');
+	    addrange(cv, 'a', 'f');
+	    addrange(cv, 'A', 'F');
+	}
+	break;
+    case CC_SPACE:
+	cv = getcvec(v, NUM_SPACE_CHAR, NUM_SPACE_RANGE);
+	if (cv) {
+	    for (i=0 ; (size_t)i<NUM_SPACE_RANGE ; i++) {
+		addrange(cv, spaceRangeTable[i].start,
+			spaceRangeTable[i].end);
+	    }
+	    for (i=0 ; (size_t)i<NUM_SPACE_CHAR ; i++) {
+		addchr(cv, spaceCharTable[i]);
+	    }
+	}
+	break;
+    case CC_LOWER:
+	cv  = getcvec(v, NUM_LOWER_CHAR, NUM_LOWER_RANGE);
+	if (cv) {
+	    for (i=0 ; (size_t)i<NUM_LOWER_RANGE ; i++) {
+		addrange(cv, lowerRangeTable[i].start,
+			lowerRangeTable[i].end);
+	    }
+	    for (i=0 ; (size_t)i<NUM_LOWER_CHAR ; i++) {
+		addchr(cv, lowerCharTable[i]);
+	    }
+	}
+	break;
+    case CC_UPPER:
+	cv  = getcvec(v, NUM_UPPER_CHAR, NUM_UPPER_RANGE);
+	if (cv) {
+	    for (i=0 ; (size_t)i<NUM_UPPER_RANGE ; i++) {
+		addrange(cv, upperRangeTable[i].start,
+			upperRangeTable[i].end);
+	    }
+	    for (i=0 ; (size_t)i<NUM_UPPER_CHAR ; i++) {
+		addchr(cv, upperCharTable[i]);
+	    }
+	}
+	break;
+    case CC_PRINT:
+    	cv  = getcvec(v, NUM_SPACE_CHAR + NUM_GRAPH_CHAR, NUM_SPACE_RANGE + NUM_GRAPH_RANGE  - 1);
+    	if (cv) {
+    	    for (i=1 ; (size_t)i<NUM_SPACE_RANGE ; i++) {
+    		addrange(cv, spaceRangeTable[i].start,
+    				spaceRangeTable[i].end);
+    	    }
+    	    for (i=0 ; (size_t)i<NUM_SPACE_CHAR ; i++) {
+    		addchr(cv, spaceCharTable[i]);
+    	    }
+    	    for (i=0 ; (size_t)i<NUM_GRAPH_RANGE ; i++) {
+    		addrange(cv, graphRangeTable[i].start,
+    				graphRangeTable[i].end);
+    	    }
+    	    for (i=0 ; (size_t)i<NUM_GRAPH_CHAR ; i++) {
+    		addchr(cv, graphCharTable[i]);
+    	    }
+    	}
+    	break;
+    case CC_GRAPH:
+	cv  = getcvec(v, NUM_GRAPH_CHAR, NUM_GRAPH_RANGE);
+	if (cv) {
+	    for (i=0 ; (size_t)i<NUM_GRAPH_RANGE ; i++) {
+		addrange(cv, graphRangeTable[i].start,
+			graphRangeTable[i].end);
+	    }
+	    for (i=0 ; (size_t)i<NUM_GRAPH_CHAR ; i++) {
+		addchr(cv, graphCharTable[i]);
+	    }
+	}
+	break;
+    }
+    if (cv == NULL) {
+	ERR(REG_ESPACE);
+    }
+    return cv;
+}
+
+/*
+ - allcases - supply cvec for all case counterparts of a chr (including itself)
+ * This is a shortcut, preferably an efficient one, for simple characters;
+ * messy cases are done via range().
+ ^ static struct cvec *allcases(struct vars *, pchr);
+ */
+static struct cvec *
+allcases(
+    struct vars *v,		/* context */
+    pchr pc)			/* character to get case equivs of */
+{
+    struct cvec *cv;
+    chr c = (chr)pc;
+    chr lc, uc, tc;
+
+    lc = Tcl_UniCharToLower((chr)c);
+    uc = Tcl_UniCharToUpper((chr)c);
+    tc = Tcl_UniCharToTitle((chr)c);
+
+    if (tc != uc) {
+	cv = getcvec(v, 3, 0);
+	addchr(cv, tc);
+    } else {
+	cv = getcvec(v, 2, 0);
+    }
+    addchr(cv, lc);
+    if (lc != uc) {
+	addchr(cv, uc);
+    }
+    return cv;
+}
+
+/*
+ - cmp - chr-substring compare
+ * Backrefs need this.  It should preferably be efficient.
+ * Note that it does not need to report anything except equal/unequal.
+ * Note also that the length is exact, and the comparison should not
+ * stop at embedded NULs!
+ ^ static int cmp(const chr *, const chr *, size_t);
+ */
+static int			/* 0 for equal, nonzero for unequal */
+cmp(
+    const chr *x, const chr *y,	/* strings to compare */
+    size_t len)			/* exact length of comparison */
+{
+    return memcmp(VS(x), VS(y), len*sizeof(chr));
+}
+
+/*
+ - casecmp - case-independent chr-substring compare
+ * REG_ICASE backrefs need this.  It should preferably be efficient.
+ * Note that it does not need to report anything except equal/unequal.
+ * Note also that the length is exact, and the comparison should not
+ * stop at embedded NULs!
+ ^ static int casecmp(const chr *, const chr *, size_t);
+ */
+static int			/* 0 for equal, nonzero for unequal */
+casecmp(
+    const chr *x, const chr *y,	/* strings to compare */
+    size_t len)			/* exact length of comparison */
+{
+    for (; len > 0; len--, x++, y++) {
+	if ((*x!=*y) && (Tcl_UniCharToLower(*x) != Tcl_UniCharToLower(*y))) {
+	    return 1;
+	}
+    }
+    return 0;
+}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/regc_nfa.c b/generic/regc_nfa.c
new file mode 100644
index 0000000..088c6c0
--- /dev/null
+++ b/generic/regc_nfa.c
@@ -0,0 +1,3213 @@
+/*
+ * NFA utilities.
+ * This file is #included by regcomp.c.
+ *
+ * Copyright (c) 1998, 1999 Henry Spencer. All rights reserved.
+ *
+ * Development of this software was funded, in part, by Cray Research Inc.,
+ * UUNET Communications Services Inc., Sun Microsystems Inc., and Scriptics
+ * Corporation, none of whom are responsible for the results. The author
+ * thanks all of them.
+ *
+ * Redistribution and use in source and binary forms -- with or without
+ * modification -- are permitted for any purpose, provided that
+ * redistributions in source form retain this entire copyright notice and
+ * indicate the origin and nature of any modifications.
+ *
+ * I'd appreciate being given credit for this package in the documentation of
+ * software which uses it, but that is not a requirement.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * HENRY SPENCER BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * One or two things that technically ought to be in here are actually in
+ * color.c, thanks to some incestuous relationships in the color chains.
+ */
+
+#define	NISERR()	VISERR(nfa->v)
+#define	NERR(e)		VERR(nfa->v, (e))
+#define STACK_TOO_DEEP(x) (0)
+#define CANCEL_REQUESTED(x) (0)
+#define REG_CANCEL 777
+
+/*
+ - newnfa - set up an NFA
+ ^ static struct nfa *newnfa(struct vars *, struct colormap *, struct nfa *);
+ */
+static struct nfa *		/* the NFA, or NULL */
+newnfa(
+    struct vars *v,
+    struct colormap *cm,
+    struct nfa *parent)		/* NULL if primary NFA */
+{
+    struct nfa *nfa;
+
+    nfa = (struct nfa *) MALLOC(sizeof(struct nfa));
+    if (nfa == NULL) {
+	ERR(REG_ESPACE);
+	return NULL;
+    }
+
+    nfa->states = NULL;
+    nfa->slast = NULL;
+    nfa->free = NULL;
+    nfa->nstates = 0;
+    nfa->cm = cm;
+    nfa->v = v;
+    nfa->bos[0] = nfa->bos[1] = COLORLESS;
+    nfa->eos[0] = nfa->eos[1] = COLORLESS;
+    nfa->parent = parent;	/* Precedes newfstate so parent is valid. */
+    nfa->post = newfstate(nfa, '@');	/* number 0 */
+    nfa->pre = newfstate(nfa, '>');	/* number 1 */
+
+    nfa->init = newstate(nfa);	/* May become invalid later. */
+    nfa->final = newstate(nfa);
+    if (ISERR()) {
+	freenfa(nfa);
+	return NULL;
+    }
+    rainbow(nfa, nfa->cm, PLAIN, COLORLESS, nfa->pre, nfa->init);
+    newarc(nfa, '^', 1, nfa->pre, nfa->init);
+    newarc(nfa, '^', 0, nfa->pre, nfa->init);
+    rainbow(nfa, nfa->cm, PLAIN, COLORLESS, nfa->final, nfa->post);
+    newarc(nfa, '$', 1, nfa->final, nfa->post);
+    newarc(nfa, '$', 0, nfa->final, nfa->post);
+
+    if (ISERR()) {
+	freenfa(nfa);
+	return NULL;
+    }
+    return nfa;
+}
+
+/*
+ - freenfa - free an entire NFA
+ ^ static void freenfa(struct nfa *);
+ */
+static void
+freenfa(
+    struct nfa *nfa)
+{
+    struct state *s;
+
+    while ((s = nfa->states) != NULL) {
+	s->nins = s->nouts = 0;	/* don't worry about arcs */
+	freestate(nfa, s);
+    }
+    while ((s = nfa->free) != NULL) {
+	nfa->free = s->next;
+	destroystate(nfa, s);
+    }
+
+    nfa->slast = NULL;
+    nfa->nstates = -1;
+    nfa->pre = NULL;
+    nfa->post = NULL;
+    FREE(nfa);
+}
+
+/*
+ - newstate - allocate an NFA state, with zero flag value
+ ^ static struct state *newstate(struct nfa *);
+ */
+static struct state *		/* NULL on error */
+newstate(
+    struct nfa *nfa)
+{
+    struct state *s;
+
+    if (nfa->free != NULL) {
+	s = nfa->free;
+	nfa->free = s->next;
+    } else {
+	if (nfa->v->spaceused >= REG_MAX_COMPILE_SPACE) {
+	    NERR(REG_ETOOBIG);
+	    return NULL;
+	}
+	s = (struct state *) MALLOC(sizeof(struct state));
+	if (s == NULL) {
+	    NERR(REG_ESPACE);
+	    return NULL;
+	}
+	nfa->v->spaceused += sizeof(struct state);
+	s->oas.next = NULL;
+	s->free = NULL;
+	s->noas = 0;
+    }
+
+    assert(nfa->nstates >= 0);
+    s->no = nfa->nstates++;
+    s->flag = 0;
+    if (nfa->states == NULL) {
+	nfa->states = s;
+    }
+    s->nins = 0;
+    s->ins = NULL;
+    s->nouts = 0;
+    s->outs = NULL;
+    s->tmp = NULL;
+    s->next = NULL;
+    if (nfa->slast != NULL) {
+	assert(nfa->slast->next == NULL);
+	nfa->slast->next = s;
+    }
+    s->prev = nfa->slast;
+    nfa->slast = s;
+    return s;
+}
+
+/*
+ - newfstate - allocate an NFA state with a specified flag value
+ ^ static struct state *newfstate(struct nfa *, int flag);
+ */
+static struct state *		/* NULL on error */
+newfstate(
+    struct nfa *nfa,
+    int flag)
+{
+    struct state *s;
+
+    s = newstate(nfa);
+    if (s != NULL) {
+	s->flag = (char) flag;
+    }
+    return s;
+}
+
+/*
+ - dropstate - delete a state's inarcs and outarcs and free it
+ ^ static void dropstate(struct nfa *, struct state *);
+ */
+static void
+dropstate(
+    struct nfa *nfa,
+    struct state *s)
+{
+    struct arc *a;
+
+    while ((a = s->ins) != NULL) {
+	freearc(nfa, a);
+    }
+    while ((a = s->outs) != NULL) {
+	freearc(nfa, a);
+    }
+    freestate(nfa, s);
+}
+
+/*
+ - freestate - free a state, which has no in-arcs or out-arcs
+ ^ static void freestate(struct nfa *, struct state *);
+ */
+static void
+freestate(
+    struct nfa *nfa,
+    struct state *s)
+{
+    assert(s != NULL);
+    assert(s->nins == 0 && s->nouts == 0);
+
+    s->no = FREESTATE;
+    s->flag = 0;
+    if (s->next != NULL) {
+	s->next->prev = s->prev;
+    } else {
+	assert(s == nfa->slast);
+	nfa->slast = s->prev;
+    }
+    if (s->prev != NULL) {
+	s->prev->next = s->next;
+    } else {
+	assert(s == nfa->states);
+	nfa->states = s->next;
+    }
+    s->prev = NULL;
+    s->next = nfa->free;	/* don't delete it, put it on the free list */
+    nfa->free = s;
+}
+
+/*
+ - destroystate - really get rid of an already-freed state
+ ^ static void destroystate(struct nfa *, struct state *);
+ */
+static void
+destroystate(
+    struct nfa *nfa,
+    struct state *s)
+{
+    struct arcbatch *ab;
+    struct arcbatch *abnext;
+
+    assert(s->no == FREESTATE);
+    for (ab=s->oas.next ; ab!=NULL ; ab=abnext) {
+	abnext = ab->next;
+	FREE(ab);
+	nfa->v->spaceused -= sizeof(struct arcbatch);
+    }
+    s->ins = NULL;
+    s->outs = NULL;
+    s->next = NULL;
+    FREE(s);
+    nfa->v->spaceused -= sizeof(struct state);
+}
+
+/*
+ - newarc - set up a new arc within an NFA
+ ^ static void newarc(struct nfa *, int, pcolor, struct state *,
+ ^	struct state *);
+ */
+/*
+ * This function checks to make sure that no duplicate arcs are created.
+ * In general we never want duplicates.
+ */
+static void
+newarc(
+    struct nfa *nfa,
+    int t,
+    pcolor co,
+    struct state *from,
+    struct state *to)
+{
+    struct arc *a;
+
+    assert(from != NULL && to != NULL);
+
+    /* check for duplicate arc, using whichever chain is shorter */
+    if (from->nouts <= to->nins) {
+	for (a = from->outs; a != NULL; a = a->outchain) {
+	    if (a->to == to && a->co == co && a->type == t) {
+		return;
+	    }
+	}
+    } else {
+	for (a = to->ins; a != NULL; a = a->inchain) {
+	    if (a->from == from && a->co == co && a->type == t) {
+		return;
+	    }
+	}
+    }
+
+    /* no dup, so create the arc */
+    createarc(nfa, t, co, from, to);
+}
+
+/*
+ * createarc - create a new arc within an NFA
+ *
+ * This function must *only* be used after verifying that there is no existing
+ * identical arc (same type/color/from/to).
+ */
+static void
+createarc(
+    struct nfa * nfa,
+    int t,
+    pcolor co,
+    struct state * from,
+    struct state * to)
+{
+    struct arc *a;
+
+    /* the arc is physically allocated within its from-state */
+    a = allocarc(nfa, from);
+    if (NISERR()) {
+	return;
+    }
+    assert(a != NULL);
+
+    a->type = t;
+    a->co = (color) co;
+    a->to = to;
+    a->from = from;
+
+    /*
+     * Put the new arc on the beginning, not the end, of the chains; it's
+     * simpler here, and freearc() is the same cost either way.  See also the
+     * logic in moveins() and its cohorts, as well as fixempties().
+     */
+    a->inchain = to->ins;
+    a->inchainRev = NULL;
+    if (to->ins) {
+	to->ins->inchainRev = a;
+    }
+    to->ins = a;
+    a->outchain = from->outs;
+    a->outchainRev = NULL;
+    if (from->outs) {
+	from->outs->outchainRev = a;
+    }
+    from->outs = a;
+
+    from->nouts++;
+    to->nins++;
+
+    if (COLORED(a) && nfa->parent == NULL) {
+	colorchain(nfa->cm, a);
+    }
+}
+
+/*
+ - allocarc - allocate a new out-arc within a state
+ ^ static struct arc *allocarc(struct nfa *, struct state *);
+ */
+static struct arc *		/* NULL for failure */
+allocarc(
+    struct nfa *nfa,
+    struct state *s)
+{
+    struct arc *a;
+
+    /*
+     * Shortcut
+     */
+
+    if (s->free == NULL && s->noas < ABSIZE) {
+	a = &s->oas.a[s->noas];
+	s->noas++;
+	return a;
+    }
+
+    /*
+     * if none at hand, get more
+     */
+
+    if (s->free == NULL) {
+	struct arcbatch *newAb;
+	int i;
+
+	if (nfa->v->spaceused >= REG_MAX_COMPILE_SPACE) {
+	    NERR(REG_ETOOBIG);
+	    return NULL;
+	}
+	newAb = (struct arcbatch *) MALLOC(sizeof(struct arcbatch));
+	if (newAb == NULL) {
+	    NERR(REG_ESPACE);
+	    return NULL;
+	}
+	nfa->v->spaceused += sizeof(struct arcbatch);
+	newAb->next = s->oas.next;
+	s->oas.next = newAb;
+
+	for (i=0 ; i<ABSIZE ; i++) {
+	    newAb->a[i].type = 0;
+	    newAb->a[i].freechain = &newAb->a[i+1];
+	}
+	newAb->a[ABSIZE-1].freechain = NULL;
+	s->free = &newAb->a[0];
+    }
+    assert(s->free != NULL);
+
+    a = s->free;
+    s->free = a->freechain;
+    return a;
+}
+
+/*
+ - freearc - free an arc
+ ^ static void freearc(struct nfa *, struct arc *);
+ */
+static void
+freearc(
+    struct nfa *nfa,
+    struct arc *victim)
+{
+    struct state *from = victim->from;
+    struct state *to = victim->to;
+    struct arc *predecessor;
+
+    assert(victim->type != 0);
+
+    /*
+     * Take it off color chain if necessary.
+     */
+
+    if (COLORED(victim) && nfa->parent == NULL) {
+	uncolorchain(nfa->cm, victim);
+    }
+
+    /*
+     * Take it off source's out-chain.
+     */
+
+    assert(from != NULL);
+    predecessor = victim->outchainRev;
+    if (predecessor == NULL) {
+	assert(from->outs == victim);
+	from->outs = victim->outchain;
+    } else {
+	assert(predecessor->outchain == victim);
+	predecessor->outchain = victim->outchain;
+    }
+    if (victim->outchain != NULL) {
+	assert(victim->outchain->outchainRev == victim);
+	victim->outchain->outchainRev = predecessor;
+    }
+    from->nouts--;
+
+    /*
+     * Take it off target's in-chain.
+     */
+
+    assert(to != NULL);
+    predecessor = victim->inchainRev;
+    if (predecessor == NULL) {
+	assert(to->ins == victim);
+	to->ins = victim->inchain;
+    } else {
+	assert(predecessor->inchain == victim);
+	predecessor->inchain = victim->inchain;
+    }
+    if (victim->inchain != NULL) {
+	assert(victim->inchain->inchainRev == victim);
+	victim->inchain->inchainRev = predecessor;
+    }
+    to->nins--;
+
+    /*
+     * Clean up and place on from-state's free list.
+     */
+
+    victim->type = 0;
+    victim->from = NULL;	/* precautions... */
+    victim->to = NULL;
+    victim->inchain = NULL;
+    victim->inchainRev = NULL;
+    victim->outchain = NULL;
+    victim->outchainRev = NULL;
+    victim->freechain = from->free;
+    from->free = victim;
+}
+
+/*
+ * changearctarget - flip an arc to have a different to state
+ *
+ * Caller must have verified that there is no pre-existing duplicate arc.
+ *
+ * Note that because we store arcs in their from state, we can't easily have
+ * a similar changearcsource function.
+ */
+static void
+changearctarget(struct arc * a, struct state * newto)
+{
+    struct state *oldto = a->to;
+    struct arc *predecessor;
+
+    assert(oldto != newto);
+
+    /* take it off old target's in-chain */
+    assert(oldto != NULL);
+    predecessor = a->inchainRev;
+    if (predecessor == NULL) {
+	assert(oldto->ins == a);
+	oldto->ins = a->inchain;
+    } else {
+	assert(predecessor->inchain == a);
+	predecessor->inchain = a->inchain;
+    }
+    if (a->inchain != NULL) {
+	assert(a->inchain->inchainRev == a);
+	a->inchain->inchainRev = predecessor;
+    }
+    oldto->nins--;
+
+    a->to = newto;
+
+    /* prepend it to new target's in-chain */
+    a->inchain = newto->ins;
+    a->inchainRev = NULL;
+    if (newto->ins) {
+	newto->ins->inchainRev = a;
+    }
+    newto->ins = a;
+    newto->nins++;
+}
+
+/*
+ - hasnonemptyout - Does state have a non-EMPTY out arc?
+ ^ static int hasnonemptyout(struct state *);
+ */
+static int
+hasnonemptyout(
+    struct state *s)
+{
+    struct arc *a;
+
+    for (a = s->outs; a != NULL; a = a->outchain) {
+	if (a->type != EMPTY) {
+	    return 1;
+	}
+    }
+    return 0;
+}
+
+/*
+ - findarc - find arc, if any, from given source with given type and color
+ * If there is more than one such arc, the result is random.
+ ^ static struct arc *findarc(struct state *, int, pcolor);
+ */
+static struct arc *
+findarc(
+    struct state *s,
+    int type,
+    pcolor co)
+{
+    struct arc *a;
+
+    for (a=s->outs ; a!=NULL ; a=a->outchain) {
+	if (a->type == type && a->co == co) {
+	    return a;
+	}
+    }
+    return NULL;
+}
+
+/*
+ - cparc - allocate a new arc within an NFA, copying details from old one
+ ^ static void cparc(struct nfa *, struct arc *, struct state *,
+ ^ 	struct state *);
+ */
+static void
+cparc(
+    struct nfa *nfa,
+    struct arc *oa,
+    struct state *from,
+    struct state *to)
+{
+    newarc(nfa, oa->type, oa->co, from, to);
+}
+
+/*
+ * sortins - sort the in arcs of a state by from/color/type
+ */
+static void
+sortins(
+    struct nfa * nfa,
+    struct state * s)
+{
+    struct arc **sortarray;
+    struct arc *a;
+    int n = s->nins;
+    int i;
+
+    if (n <= 1) {
+	return;		/* nothing to do */
+    }
+    /* make an array of arc pointers ... */
+    sortarray = (struct arc **) MALLOC(n * sizeof(struct arc *));
+    if (sortarray == NULL) {
+	NERR(REG_ESPACE);
+	return;
+    }
+    i = 0;
+    for (a = s->ins; a != NULL; a = a->inchain) {
+	sortarray[i++] = a;
+    }
+    assert(i == n);
+    /* ... sort the array */
+    qsort(sortarray, n, sizeof(struct arc *), sortins_cmp);
+    /* ... and rebuild arc list in order */
+    /* it seems worth special-casing first and last items to simplify loop */
+    a = sortarray[0];
+    s->ins = a;
+    a->inchain = sortarray[1];
+    a->inchainRev = NULL;
+    for (i = 1; i < n - 1; i++) {
+	a = sortarray[i];
+	a->inchain = sortarray[i + 1];
+	a->inchainRev = sortarray[i - 1];
+    }
+    a = sortarray[i];
+    a->inchain = NULL;
+    a->inchainRev = sortarray[i - 1];
+    FREE(sortarray);
+}
+
+static int
+sortins_cmp(
+    const void *a,
+    const void *b)
+{
+    const struct arc *aa = *((const struct arc * const *) a);
+    const struct arc *bb = *((const struct arc * const *) b);
+
+    /* we check the fields in the order they are most likely to be different */
+    if (aa->from->no < bb->from->no) {
+	return -1;
+    }
+    if (aa->from->no > bb->from->no) {
+ 	return 1;
+    }
+    if (aa->co < bb->co) {
+ 	return -1;
+    }
+    if (aa->co > bb->co) {
+ 	return 1;
+    }
+    if (aa->type < bb->type) {
+ 	return -1;
+    }
+    if (aa->type > bb->type) {
+ 	return 1;
+    }
+    return 0;
+}
+
+/*
+ * sortouts - sort the out arcs of a state by to/color/type
+ */
+static void
+sortouts(
+    struct nfa * nfa,
+    struct state * s)
+{
+    struct arc **sortarray;
+    struct arc *a;
+    int	n = s->nouts;
+    int	i;
+
+    if (n <= 1) {
+	return;					/* nothing to do */
+    }
+    /* make an array of arc pointers ... */
+    sortarray = (struct arc **) MALLOC(n * sizeof(struct arc *));
+    if (sortarray == NULL) {
+	NERR(REG_ESPACE);
+	return;
+    }
+    i = 0;
+    for (a = s->outs; a != NULL; a = a->outchain) {
+	sortarray[i++] = a;
+    }
+    assert(i == n);
+    /* ... sort the array */
+    qsort(sortarray, n, sizeof(struct arc *), sortouts_cmp);
+    /* ... and rebuild arc list in order */
+    /* it seems worth special-casing first and last items to simplify loop */
+    a = sortarray[0];
+    s->outs = a;
+    a->outchain = sortarray[1];
+    a->outchainRev = NULL;
+    for (i = 1; i < n - 1; i++) {
+	a = sortarray[i];
+	a->outchain = sortarray[i + 1];
+	a->outchainRev = sortarray[i - 1];
+    }
+    a = sortarray[i];
+    a->outchain = NULL;
+    a->outchainRev = sortarray[i - 1];
+    FREE(sortarray);
+}
+
+static int
+sortouts_cmp(
+    const void *a,
+    const void *b)
+{
+    const struct arc *aa = *((const struct arc * const *) a);
+    const struct arc *bb = *((const struct arc * const *) b);
+
+    /* we check the fields in the order they are most likely to be different */
+    if (aa->to->no < bb->to->no) {
+	return -1;
+    }
+    if (aa->to->no > bb->to->no) {
+	return 1;
+    }
+    if (aa->co < bb->co) {
+	return -1;
+    }
+    if (aa->co > bb->co) {
+	return 1;
+    }
+    if (aa->type < bb->type) {
+	return -1;
+    }
+    if (aa->type > bb->type) {
+	return 1;
+    }
+    return 0;
+}
+
+/*
+ * Common decision logic about whether to use arc-by-arc operations or
+ * sort/merge.  If there's just a few source arcs we cannot recoup the
+ * cost of sorting the destination arc list, no matter how large it is.
+ * Otherwise, limit the number of arc-by-arc comparisons to about 1000
+ * (a somewhat arbitrary choice, but the breakeven point would probably
+ * be machine dependent anyway).
+ */
+#define BULK_ARC_OP_USE_SORT(nsrcarcs, ndestarcs) \
+	((nsrcarcs) < 4 ? 0 : ((nsrcarcs) > 32 || (ndestarcs) > 32))
+
+/*
+ - moveins - move all in arcs of a state to another state
+ * You might think this could be done better by just updating the
+ * existing arcs, and you would be right if it weren't for the need
+ * for duplicate suppression, which makes it easier to just make new
+ * ones to exploit the suppression built into newarc.
+ *
+ * However, if we have a whole lot of arcs to deal with, retail duplicate
+ * checks become too slow.  In that case we proceed by sorting and merging
+ * the arc lists, and then we can indeed just update the arcs in-place.
+ *
+ ^ static void moveins(struct nfa *, struct state *, struct state *);
+ */
+static void
+moveins(
+    struct nfa *nfa,
+    struct state *oldState,
+    struct state *newState)
+{
+    assert(oldState != newState);
+
+    if (!BULK_ARC_OP_USE_SORT(oldState->nins, newState->nins)) {
+	/* With not too many arcs, just do them one at a time */
+	struct arc *a;
+
+	while ((a = oldState->ins) != NULL) {
+	    cparc(nfa, a, a->from, newState);
+	    freearc(nfa, a);
+	}
+    } else {
+	/*
+	 * With many arcs, use a sort-merge approach.  Note changearctarget()
+	 * will put the arc onto the front of newState's chain, so it does not
+	 * break our walk through the sorted part of the chain.
+	 */
+	struct arc *oa;
+	struct arc *na;
+
+	/*
+	 * Because we bypass newarc() in this code path, we'd better include a
+	 * cancel check.
+	 */
+	if (CANCEL_REQUESTED(nfa->v->re)) {
+	    NERR(REG_CANCEL);
+	    return;
+	}
+
+	sortins(nfa, oldState);
+	sortins(nfa, newState);
+	if (NISERR()) {
+	    return;		/* might have failed to sort */
+	}
+	oa = oldState->ins;
+	na = newState->ins;
+	while (oa != NULL && na != NULL) {
+	    struct arc *a = oa;
+
+	    switch (sortins_cmp(&oa, &na)) {
+		case -1:
+		    /* newState does not have anything matching oa */
+		    oa = oa->inchain;
+
+		    /*
+		     * Rather than doing createarc+freearc, we can just unlink
+		     * and relink the existing arc struct.
+		     */
+		    changearctarget(a, newState);
+		    break;
+		case 0:
+		    /* match, advance in both lists */
+		    oa = oa->inchain;
+		    na = na->inchain;
+		    /* ... and drop duplicate arc from oldState */
+		    freearc(nfa, a);
+		    break;
+		case +1:
+		    /* advance only na; oa might have a match later */
+		    na = na->inchain;
+		    break;
+		default:
+		    assert(NOTREACHED);
+	    }
+	}
+	while (oa != NULL) {
+	    /* newState does not have anything matching oa */
+	    struct arc *a = oa;
+
+	    oa = oa->inchain;
+	    changearctarget(a, newState);
+	}
+    }
+
+    assert(oldState->nins == 0);
+    assert(oldState->ins == NULL);
+}
+
+/*
+ - copyins - copy in arcs of a state to another state
+ ^ static VOID copyins(struct nfa *, struct state *, struct state *, int);
+ */
+static void
+copyins(
+    struct nfa *nfa,
+    struct state *oldState,
+    struct state *newState)
+{
+    assert(oldState != newState);
+
+    if (!BULK_ARC_OP_USE_SORT(oldState->nins, newState->nins)) {
+	/* With not too many arcs, just do them one at a time */
+	struct arc *a;
+
+	for (a = oldState->ins; a != NULL; a = a->inchain) {
+	    cparc(nfa, a, a->from, newState);
+	}
+    } else {
+	/*
+	 * With many arcs, use a sort-merge approach.  Note that createarc()
+	 * will put new arcs onto the front of newState's chain, so it does
+	 * not break our walk through the sorted part of the chain.
+	 */
+	struct arc *oa;
+	struct arc *na;
+
+	/*
+	 * Because we bypass newarc() in this code path, we'd better include a
+	 * cancel check.
+	 */
+	if (CANCEL_REQUESTED(nfa->v->re)) {
+	    NERR(REG_CANCEL);
+	    return;
+	}
+
+	sortins(nfa, oldState);
+	sortins(nfa, newState);
+	if (NISERR()) {
+	    return;		/* might have failed to sort */
+	}
+	oa = oldState->ins;
+	na = newState->ins;
+	while (oa != NULL && na != NULL) {
+	    struct arc *a = oa;
+
+	    switch (sortins_cmp(&oa, &na)) {
+		case -1:
+		    /* newState does not have anything matching oa */
+		    oa = oa->inchain;
+		    createarc(nfa, a->type, a->co, a->from, newState);
+		    break;
+		case 0:
+		    /* match, advance in both lists */
+		    oa = oa->inchain;
+		    na = na->inchain;
+		    break;
+		case +1:
+		    /* advance only na; oa might have a match later */
+		    na = na->inchain;
+		    break;
+		default:
+		    assert(NOTREACHED);
+	    }
+	}
+	while (oa != NULL) {
+	    /* newState does not have anything matching oa */
+	    struct arc *a = oa;
+
+	    oa = oa->inchain;
+	    createarc(nfa, a->type, a->co, a->from, newState);
+	}
+    }
+}
+
+/*
+ * mergeins - merge a list of inarcs into a state
+ *
+ * This is much like copyins, but the source arcs are listed in an array,
+ * and are not guaranteed unique.  It's okay to clobber the array contents.
+ */
+static void
+mergeins(
+    struct nfa * nfa,
+    struct state * s,
+    struct arc ** arcarray,
+    int arccount)
+{
+    struct arc *na;
+    int	i;
+    int	j;
+
+    if (arccount <= 0) {
+	return;
+    }
+
+    /*
+     * Because we bypass newarc() in this code path, we'd better include a
+     * cancel check.
+     */
+    if (CANCEL_REQUESTED(nfa->v->re)) {
+	NERR(REG_CANCEL);
+	return;
+    }
+
+    /* Sort existing inarcs as well as proposed new ones */
+    sortins(nfa, s);
+    if (NISERR()) {
+	return;			/* might have failed to sort */
+    }
+
+    qsort(arcarray, arccount, sizeof(struct arc *), sortins_cmp);
+
+    /*
+     * arcarray very likely includes dups, so we must eliminate them.  (This
+     * could be folded into the next loop, but it's not worth the trouble.)
+     */
+    j = 0;
+    for (i = 1; i < arccount; i++) {
+	switch (sortins_cmp(&arcarray[j], &arcarray[i])) {
+	    case -1:
+		/* non-dup */
+		arcarray[++j] = arcarray[i];
+		break;
+	    case 0:
+		/* dup */
+		break;
+	    default:
+		/* trouble */
+		assert(NOTREACHED);
+	}
+    }
+    arccount = j + 1;
+
+    /*
+     * Now merge into s' inchain.  Note that createarc() will put new arcs
+     * onto the front of s's chain, so it does not break our walk through the
+     * sorted part of the chain.
+     */
+    i = 0;
+    na = s->ins;
+    while (i < arccount && na != NULL) {
+	struct arc *a = arcarray[i];
+
+	switch (sortins_cmp(&a, &na)) {
+	    case -1:
+		/* s does not have anything matching a */
+		createarc(nfa, a->type, a->co, a->from, s);
+		i++;
+		break;
+	    case 0:
+		/* match, advance in both lists */
+		i++;
+		na = na->inchain;
+		break;
+	    case +1:
+		/* advance only na; array might have a match later */
+		na = na->inchain;
+		break;
+	    default:
+		assert(NOTREACHED);
+	}
+    }
+    while (i < arccount) {
+	/* s does not have anything matching a */
+	struct arc *a = arcarray[i];
+
+	createarc(nfa, a->type, a->co, a->from, s);
+	i++;
+    }
+}
+
+/*
+ - moveouts - move all out arcs of a state to another state
+ ^ static void moveouts(struct nfa *, struct state *, struct state *);
+ */
+static void
+moveouts(
+    struct nfa *nfa,
+    struct state *oldState,
+    struct state *newState)
+{
+    assert(oldState != newState);
+
+    if (!BULK_ARC_OP_USE_SORT(oldState->nouts, newState->nouts)) {
+	/* With not too many arcs, just do them one at a time */
+	struct arc *a;
+
+	while ((a = oldState->outs) != NULL) {
+	    cparc(nfa, a, newState, a->to);
+	    freearc(nfa, a);
+	}
+    } else {
+	/*
+	 * With many arcs, use a sort-merge approach.  Note that createarc()
+	 * will put new arcs onto the front of newState's chain, so it does
+	 * not break our walk through the sorted part of the chain.
+	 */
+	struct arc *oa;
+	struct arc *na;
+
+	/*
+	 * Because we bypass newarc() in this code path, we'd better include a
+	 * cancel check.
+	 */
+	if (CANCEL_REQUESTED(nfa->v->re)) {
+	    NERR(REG_CANCEL);
+	    return;
+	}
+
+	sortouts(nfa, oldState);
+	sortouts(nfa, newState);
+	if (NISERR()) {
+	    return;	/* might have failed to sort */
+	}
+	oa = oldState->outs;
+	na = newState->outs;
+	while (oa != NULL && na != NULL) {
+	    struct arc *a = oa;
+
+	    switch (sortouts_cmp(&oa, &na)) {
+		case -1:
+		    /* newState does not have anything matching oa */
+		    oa = oa->outchain;
+		    createarc(nfa, a->type, a->co, newState, a->to);
+		    freearc(nfa, a);
+		    break;
+		case 0:
+		    /* match, advance in both lists */
+		    oa = oa->outchain;
+		    na = na->outchain;
+		    /* ... and drop duplicate arc from oldState */
+		    freearc(nfa, a);
+		    break;
+		case +1:
+		    /* advance only na; oa might have a match later */
+		    na = na->outchain;
+		    break;
+		default:
+		    assert(NOTREACHED);
+	    }
+	}
+	while (oa != NULL) {
+	    /* newState does not have anything matching oa */
+	    struct arc *a = oa;
+
+	    oa = oa->outchain;
+	    createarc(nfa, a->type, a->co, newState, a->to);
+	    freearc(nfa, a);
+	}
+    }
+
+    assert(oldState->nouts == 0);
+    assert(oldState->outs == NULL);
+}
+
+/*
+ - copyouts - copy out arcs of a state to another state
+ ^ static VOID copyouts(struct nfa *, struct state *, struct state *, int);
+ */
+static void
+copyouts(
+    struct nfa *nfa,
+    struct state *oldState,
+    struct state *newState)
+{
+    assert(oldState != newState);
+
+    if (!BULK_ARC_OP_USE_SORT(oldState->nouts, newState->nouts)) {
+	/* With not too many arcs, just do them one at a time */
+	struct arc *a;
+
+	for (a = oldState->outs; a != NULL; a = a->outchain) {
+	    cparc(nfa, a, newState, a->to);
+	}
+    } else {
+ 	/*
+	 * With many arcs, use a sort-merge approach.  Note that createarc()
+	 * will put new arcs onto the front of newState's chain, so it does
+	 * not break our walk through the sorted part of the chain.
+	 */
+	struct arc *oa;
+	struct arc *na;
+
+	/*
+	 * Because we bypass newarc() in this code path, we'd better include a
+	 * cancel check.
+	 */
+	if (CANCEL_REQUESTED(nfa->v->re)) {
+	    NERR(REG_CANCEL);
+	    return;
+	}
+
+	sortouts(nfa, oldState);
+	sortouts(nfa, newState);
+	if (NISERR()) {
+	    return;		/* might have failed to sort */
+	}
+	oa = oldState->outs;
+	na = newState->outs;
+	while (oa != NULL && na != NULL) {
+	    struct arc *a = oa;
+
+	    switch (sortouts_cmp(&oa, &na)) {
+		case -1:
+		    /* newState does not have anything matching oa */
+		    oa = oa->outchain;
+		    createarc(nfa, a->type, a->co, newState, a->to);
+		    break;
+		case 0:
+		    /* match, advance in both lists */
+		    oa = oa->outchain;
+		    na = na->outchain;
+		    break;
+		case +1:
+		    /* advance only na; oa might have a match later */
+		    na = na->outchain;
+		    break;
+		default:
+		    assert(NOTREACHED);
+	    }
+	}
+	while (oa != NULL) {
+	    /* newState does not have anything matching oa */
+	    struct arc *a = oa;
+
+	    oa = oa->outchain;
+	    createarc(nfa, a->type, a->co, newState, a->to);
+	}
+    }
+}
+
+/*
+ - cloneouts - copy out arcs of a state to another state pair, modifying type
+ ^ static void cloneouts(struct nfa *, struct state *, struct state *,
+ ^ 	struct state *, int);
+ */
+static void
+cloneouts(
+    struct nfa *nfa,
+    struct state *old,
+    struct state *from,
+    struct state *to,
+    int type)
+{
+    struct arc *a;
+
+    assert(old != from);
+
+    for (a=old->outs ; a!=NULL ; a=a->outchain) {
+	newarc(nfa, type, a->co, from, to);
+    }
+}
+
+/*
+ - delsub - delete a sub-NFA, updating subre pointers if necessary
+ * This uses a recursive traversal of the sub-NFA, marking already-seen
+ * states using their tmp pointer.
+ ^ static void delsub(struct nfa *, struct state *, struct state *);
+ */
+static void
+delsub(
+    struct nfa *nfa,
+    struct state *lp,		/* the sub-NFA goes from here... */
+    struct state *rp)		/* ...to here, *not* inclusive */
+{
+    assert(lp != rp);
+
+    rp->tmp = rp;		/* mark end */
+
+    deltraverse(nfa, lp, lp);
+    assert(lp->nouts == 0 && rp->nins == 0);	/* did the job */
+    assert(lp->no != FREESTATE && rp->no != FREESTATE);	/* no more */
+
+    rp->tmp = NULL;		/* unmark end */
+    lp->tmp = NULL;		/* and begin, marked by deltraverse */
+}
+
+/*
+ - deltraverse - the recursive heart of delsub
+ * This routine's basic job is to destroy all out-arcs of the state.
+ ^ static void deltraverse(struct nfa *, struct state *, struct state *);
+ */
+static void
+deltraverse(
+    struct nfa *nfa,
+    struct state *leftend,
+    struct state *s)
+{
+    struct arc *a;
+    struct state *to;
+
+    if (s->nouts == 0) {
+	return;			/* nothing to do */
+    }
+    if (s->tmp != NULL) {
+	return;			/* already in progress */
+    }
+
+    s->tmp = s;			/* mark as in progress */
+
+    while ((a = s->outs) != NULL) {
+	to = a->to;
+	deltraverse(nfa, leftend, to);
+	assert(to->nouts == 0 || to->tmp != NULL);
+	freearc(nfa, a);
+	if (to->nins == 0 && to->tmp == NULL) {
+	    assert(to->nouts == 0);
+	    freestate(nfa, to);
+	}
+    }
+
+    assert(s->no != FREESTATE);	/* we're still here */
+    assert(s == leftend || s->nins != 0);	/* and still reachable */
+    assert(s->nouts == 0);	/* but have no outarcs */
+
+    s->tmp = NULL;		/* we're done here */
+}
+
+/*
+ - dupnfa - duplicate sub-NFA
+ * Another recursive traversal, this time using tmp to point to duplicates as
+ * well as mark already-seen states. (You knew there was a reason why it's a
+ * state pointer, didn't you? :-))
+ ^ static void dupnfa(struct nfa *, struct state *, struct state *,
+ ^ 	struct state *, struct state *);
+ */
+static void
+dupnfa(
+    struct nfa *nfa,
+    struct state *start,	/* duplicate of subNFA starting here */
+    struct state *stop,		/* and stopping here */
+    struct state *from,		/* stringing duplicate from here */
+    struct state *to)		/* to here */
+{
+    if (start == stop) {
+	newarc(nfa, EMPTY, 0, from, to);
+	return;
+    }
+
+    stop->tmp = to;
+    duptraverse(nfa, start, from, 0);
+    /* done, except for clearing out the tmp pointers */
+
+    stop->tmp = NULL;
+    cleartraverse(nfa, start);
+}
+
+/*
+ - duptraverse - recursive heart of dupnfa
+ ^ static void duptraverse(struct nfa *, struct state *, struct state *);
+ */
+static void
+duptraverse(
+    struct nfa *nfa,
+    struct state *s,
+    struct state *stmp,		/* s's duplicate, or NULL */
+    int depth)
+{
+    struct arc *a;
+
+    if (s->tmp != NULL) {
+	return;			/* already done */
+    }
+
+    s->tmp = (stmp == NULL) ? newstate(nfa) : stmp;
+    if (s->tmp == NULL) {
+	assert(NISERR());
+	return;
+    }
+
+    /*
+     * Arbitrary depth limit. Needs tuning, but this value is sufficient to
+     * make all normal tests (not reg-33.14) pass.
+     */
+#ifndef DUPTRAVERSE_MAX_DEPTH
+#define DUPTRAVERSE_MAX_DEPTH 15000
+#endif
+
+    if (depth++ > DUPTRAVERSE_MAX_DEPTH) {
+	NERR(REG_ESPACE);
+    }
+
+    for (a=s->outs ; a!=NULL && !NISERR() ; a=a->outchain) {
+	duptraverse(nfa, a->to, NULL, depth);
+	if (NISERR()) {
+	    break;
+	}
+	assert(a->to->tmp != NULL);
+	cparc(nfa, a, s->tmp, a->to->tmp);
+    }
+}
+
+/*
+ - cleartraverse - recursive cleanup for algorithms that leave tmp ptrs set
+ ^ static void cleartraverse(struct nfa *, struct state *);
+ */
+static void
+cleartraverse(
+    struct nfa *nfa,
+    struct state *s)
+{
+    struct arc *a;
+
+    if (s->tmp == NULL) {
+	return;
+    }
+    s->tmp = NULL;
+
+    for (a=s->outs ; a!=NULL ; a=a->outchain) {
+	cleartraverse(nfa, a->to);
+    }
+}
+
+/*
+ - specialcolors - fill in special colors for an NFA
+ ^ static void specialcolors(struct nfa *);
+ */
+static void
+specialcolors(
+    struct nfa *nfa)
+{
+    /*
+     * False colors for BOS, BOL, EOS, EOL
+     */
+
+    if (nfa->parent == NULL) {
+	nfa->bos[0] = pseudocolor(nfa->cm);
+	nfa->bos[1] = pseudocolor(nfa->cm);
+	nfa->eos[0] = pseudocolor(nfa->cm);
+	nfa->eos[1] = pseudocolor(nfa->cm);
+    } else {
+	assert(nfa->parent->bos[0] != COLORLESS);
+	nfa->bos[0] = nfa->parent->bos[0];
+	assert(nfa->parent->bos[1] != COLORLESS);
+	nfa->bos[1] = nfa->parent->bos[1];
+	assert(nfa->parent->eos[0] != COLORLESS);
+	nfa->eos[0] = nfa->parent->eos[0];
+	assert(nfa->parent->eos[1] != COLORLESS);
+	nfa->eos[1] = nfa->parent->eos[1];
+    }
+}
+
+/*
+ - optimize - optimize an NFA
+ ^ static long optimize(struct nfa *, FILE *);
+ */
+
+ /*
+  * The main goal of this function is not so much "optimization" (though it
+  * does try to get rid of useless NFA states) as reducing the NFA to a form
+  * the regex executor can handle.  The executor, and indeed the cNFA format
+  * that is its input, can only handle PLAIN and LACON arcs.  The output of
+  * the regex parser also includes EMPTY (do-nothing) arcs, as well as
+  * ^, $, AHEAD, and BEHIND constraint arcs, which we must get rid of here.
+  * We first get rid of EMPTY arcs and then deal with the constraint arcs.
+  * The hardest part of either job is to get rid of circular loops of the
+  * target arc type.  We would have to do that in any case, though, as such a
+  * loop would otherwise allow the executor to cycle through the loop endlessly
+  * without making any progress in the input string.
+  */
+static long			/* re_info bits */
+optimize(
+    struct nfa *nfa,
+    FILE *f)			/* for debug output; NULL none */
+{
+    int verbose = (f != NULL) ? 1 : 0;
+
+    if (verbose) {
+	fprintf(f, "\ninitial cleanup:\n");
+    }
+    cleanup(nfa);		/* may simplify situation */
+    if (verbose) {
+	dumpnfa(nfa, f);
+    }
+    if (verbose) {
+	fprintf(f, "\nempties:\n");
+    }
+    fixempties(nfa, f);		/* get rid of EMPTY arcs */
+    if (verbose) {
+	fprintf(f, "\nconstraints:\n");
+    }
+    fixconstraintloops(nfa, f);	/* get rid of constraint loops */
+    pullback(nfa, f);		/* pull back constraints backward */
+    pushfwd(nfa, f);		/* push fwd constraints forward */
+    if (verbose) {
+	fprintf(f, "\nfinal cleanup:\n");
+    }
+    cleanup(nfa);		/* final tidying */
+#ifdef REG_DEBUG
+    if (verbose) {
+	dumpnfa(nfa, f);
+    }
+#endif
+    return analyze(nfa);	/* and analysis */
+}
+
+/*
+ - pullback - pull back constraints backward to eliminate them
+ ^ static void pullback(struct nfa *, FILE *);
+ */
+static void
+pullback(
+    struct nfa *nfa,
+    FILE *f)			/* for debug output; NULL none */
+{
+    struct state *s;
+    struct state *nexts;
+    struct arc *a;
+    struct arc *nexta;
+    struct state *intermediates;
+    int progress;
+
+    /*
+     * Find and pull until there are no more.
+     */
+
+    do {
+	progress = 0;
+	for (s=nfa->states ; s!=NULL && !NISERR() ; s=nexts) {
+	    nexts = s->next;
+	    intermediates = NULL;
+	    for (a=s->outs ; a!=NULL && !NISERR() ; a=nexta) {
+		nexta = a->outchain;
+		if (a->type == '^' || a->type == BEHIND) {
+		    if (pull(nfa, a, &intermediates)) {
+			progress = 1;
+		    }
+		}
+		assert(nexta == NULL || s->no != FREESTATE);
+	    }
+	    /* clear tmp fields of intermediate states created here */
+	    while (intermediates != NULL) {
+		struct state *ns = intermediates->tmp;
+
+		intermediates->tmp = NULL;
+		intermediates = ns;
+	    }
+	    /* if s is now useless, get rid of it */
+	    if ((s->nins == 0 || s->nouts == 0) && !s->flag) {
+		dropstate(nfa, s);
+	    }
+	}
+	if (progress && f != NULL) {
+	    dumpnfa(nfa, f);
+	}
+    } while (progress && !NISERR());
+    if (NISERR()) {
+	return;
+    }
+
+    /*
+     * Any ^ constraints we were able to pull to the start state can now be
+     * replaced by PLAIN arcs referencing the BOS or BOL colors.  There should
+     * be no other ^ or BEHIND arcs left in the NFA, though we do not check
+     * that here (compact() will fail if so).
+     */
+    for (a=nfa->pre->outs ; a!=NULL ; a=nexta) {
+	nexta = a->outchain;
+	if (a->type == '^') {
+	    assert(a->co == 0 || a->co == 1);
+	    newarc(nfa, PLAIN, nfa->bos[a->co], a->from, a->to);
+	    freearc(nfa, a);
+	}
+    }
+}
+
+/*
+ - pull - pull a back constraint backward past its source state
+ *
+ * Returns 1 if successful (which it always is unless the source is the
+ * start state or we have an internal error), 0 if nothing happened.
+ *
+ * A significant property of this function is that it deletes no pre-existing
+ * states, and no outarcs of the constraint's from state other than the given
+ * constraint arc.  This makes the loops in pullback() safe, at the cost that
+ * we may leave useless states behind.  Therefore, we leave it to pullback()
+ * to delete such states.
+ *
+ * If the from state has multiple back-constraint outarcs, and/or multiple
+ * compatible constraint inarcs, we only need to create one new intermediate
+ * state per combination of predecessor and successor states.  *intermediates
+ * points to a list of such intermediate states for this from state (chained
+ * through their tmp fields).
+ ^ static int pull(struct nfa *, struct arc *);
+ */
+static int
+pull(
+    struct nfa *nfa,
+    struct arc *con,
+    struct state **intermediates)
+{
+    struct state *from = con->from;
+    struct state *to = con->to;
+    struct arc *a;
+    struct arc *nexta;
+    struct state *s;
+
+    assert(from != to);		/* should have gotten rid of this earlier */
+    if (from->flag) {		/* can't pull back beyond start */
+	return 0;
+    }
+    if (from->nins == 0) {	/* unreachable */
+	freearc(nfa, con);
+	return 1;
+    }
+
+    /*
+     * First, clone from state if necessary to avoid other outarcs.  This may
+     * seem wasteful, but it simplifies the logic, and we'll get rid of the
+     * clone state again at the bottom.
+     */
+
+    if (from->nouts > 1) {
+	s = newstate(nfa);
+	if (NISERR()) {
+	    return 0;
+	}
+	copyins(nfa, from, s);	/* duplicate inarcs */
+	cparc(nfa, con, s, to);		/* move constraint arc */
+	freearc(nfa, con);
+	if (NISERR()) {
+	    return 0;
+	}
+	from = s;
+	con = from->outs;
+    }
+    assert(from->nouts == 1);
+
+    /*
+     * Propagate the constraint into the from state's inarcs.
+     */
+
+    for (a=from->ins ; a!=NULL && !NISERR(); a=nexta) {
+	nexta = a->inchain;
+	switch (combine(con, a)) {
+	case INCOMPATIBLE:	/* destroy the arc */
+	    freearc(nfa, a);
+	    break;
+	case SATISFIED:		/* no action needed */
+	    break;
+	case COMPATIBLE:	/* swap the two arcs, more or less */
+	    /* need an intermediate state, but might have one already */
+	    for (s = *intermediates; s != NULL; s = s->tmp) {
+		assert(s->nins > 0 && s->nouts > 0);
+		if (s->ins->from == a->from && s->outs->to == to) {
+		    break;
+		}
+	    }
+	    if (s == NULL) {
+		s = newstate(nfa);
+		if (NISERR()) {
+		    return 0;
+		}
+		s->tmp = *intermediates;
+		*intermediates = s;
+	    }
+  	    cparc(nfa, con, a->from, s);
+	    cparc(nfa, a, s, to);
+ 	    freearc(nfa, a);
+  	    break;
+	default:
+	    assert(NOTREACHED);
+	    break;
+	}
+    }
+
+    /*
+     * Remaining inarcs, if any, incorporate the constraint.
+     */
+
+    moveins(nfa, from, to);
+    freearc(nfa, con);
+    /* from state is now useless, but we leave it to pullback() to clean up */
+    return 1;
+}
+
+/*
+ - pushfwd - push forward constraints forward to eliminate them
+ ^ static void pushfwd(struct nfa *, FILE *);
+ */
+static void
+pushfwd(
+    struct nfa *nfa,
+    FILE *f)			/* for debug output; NULL none */
+{
+    struct state *s;
+    struct state *nexts;
+    struct arc *a;
+    struct arc *nexta;
+    struct state *intermediates;
+    int progress;
+
+    /*
+     * Find and push until there are no more.
+     */
+
+    do {
+	progress = 0;
+	for (s=nfa->states ; s!=NULL && !NISERR() ; s=nexts) {
+	    nexts = s->next;
+	    intermediates = NULL;
+	    for (a = s->ins; a != NULL && !NISERR(); a = nexta) {
+		nexta = a->inchain;
+		if (a->type == '$' || a->type == AHEAD) {
+		    if (push(nfa, a, &intermediates)) {
+			progress = 1;
+		    }
+		}
+	    }
+	    /* clear tmp fields of intermediate states created here */
+	    while (intermediates != NULL) {
+		struct state *ns = intermediates->tmp;
+
+		intermediates->tmp = NULL;
+		intermediates = ns;
+	    }
+	    /* if s is now useless, get rid of it */
+	    if ((s->nins == 0 || s->nouts == 0) && !s->flag) {
+		dropstate(nfa, s);
+	    }
+	}
+	if (progress && f != NULL) {
+	    dumpnfa(nfa, f);
+	}
+    } while (progress && !NISERR());
+    if (NISERR()) {
+	return;
+    }
+
+    /*
+     * Any $ constraints we were able to push to the post state can now be
+     * replaced by PLAIN arcs referencing the EOS or EOL colors.  There should
+     * be no other $ or AHEAD arcs left in the NFA, though we do not check
+     * that here (compact() will fail if so).
+     */
+    for (a = nfa->post->ins; a != NULL; a = nexta) {
+	nexta = a->inchain;
+	if (a->type == '$') {
+	    assert(a->co == 0 || a->co == 1);
+	    newarc(nfa, PLAIN, nfa->eos[a->co], a->from, a->to);
+	    freearc(nfa, a);
+	}
+    }
+}
+
+/*
+ - push - push a forward constraint forward past its destination state
+ *
+ * Returns 1 if successful (which it always is unless the destination is the
+ * post state or we have an internal error), 0 if nothing happened.
+ *
+ * A significant property of this function is that it deletes no pre-existing
+ * states, and no inarcs of the constraint's to state other than the given
+ * constraint arc.  This makes the loops in pushfwd() safe, at the cost that
+ * we may leave useless states behind.  Therefore, we leave it to pushfwd()
+ * to delete such states.
+ *
+ * If the to state has multiple forward-constraint inarcs, and/or multiple
+ * compatible constraint outarcs, we only need to create one new intermediate
+ * state per combination of predecessor and successor states.  *intermediates
+ * points to a list of such intermediate states for this to state (chained
+ * through their tmp fields).
+ ^ static int push(struct nfa *, struct arc *);
+ */
+static int
+push(
+    struct nfa *nfa,
+    struct arc *con,
+    struct state **intermediates)
+{
+    struct state *from = con->from;
+    struct state *to = con->to;
+    struct arc *a;
+    struct arc *nexta;
+    struct state *s;
+
+    assert(to != from);		/* should have gotten rid of this earlier */
+    if (to->flag) {		/* can't push forward beyond end */
+	return 0;
+    }
+    if (to->nouts == 0) {	/* dead end */
+	freearc(nfa, con);
+	return 1;
+    }
+
+    /*
+     * First, clone to state if necessary to avoid other inarcs.  This may
+     * seem wasteful, but it simplifies the logic, and we'll get rid of the
+     * clone state again at the bottom.
+     */
+
+    if (to->nins > 1) {
+	s = newstate(nfa);
+	if (NISERR()) {
+	    return 0;
+	}
+	copyouts(nfa, to, s);		/* duplicate outarcs */
+	cparc(nfa, con, from, s);	/* move constraint arc */
+	freearc(nfa, con);
+	if (NISERR()) {
+	    return 0;
+	}
+	to = s;
+	con = to->ins;
+    }
+    assert(to->nins == 1);
+
+    /*
+     * Propagate the constraint into the to state's outarcs.
+     */
+
+    for (a = to->outs; a != NULL && !NISERR(); a = nexta) {
+	nexta = a->outchain;
+	switch (combine(con, a)) {
+	case INCOMPATIBLE:	/* destroy the arc */
+	    freearc(nfa, a);
+	    break;
+	case SATISFIED:		/* no action needed */
+	    break;
+	case COMPATIBLE:	/* swap the two arcs, more or less */
+	    /* need an intermediate state, but might have one already */
+	    for (s = *intermediates; s != NULL; s = s->tmp) {
+		assert(s->nins > 0 && s->nouts > 0);
+		if (s->ins->from == from && s->outs->to == a->to) {
+		    break;
+		}
+	    }
+	    if (s == NULL) {
+		s = newstate(nfa);
+		if (NISERR()) {
+		    return 0;
+		}
+		s->tmp = *intermediates;
+		*intermediates = s;
+	    }
+	    cparc(nfa, con, s, a->to);
+  	    cparc(nfa, a, from, s);
+  	    freearc(nfa, a);
+  	    break;
+	default:
+	    assert(NOTREACHED);
+	    break;
+	}
+    }
+
+    /*
+     * Remaining outarcs, if any, incorporate the constraint.
+     */
+
+    moveouts(nfa, to, from);
+    freearc(nfa, con);
+    /* to state is now useless, but we leave it to pushfwd() to clean up */
+    return 1;
+}
+
+/*
+ - combine - constraint lands on an arc, what happens?
+ ^ #def	INCOMPATIBLE	1	// destroys arc
+ ^ #def	SATISFIED	2	// constraint satisfied
+ ^ #def	COMPATIBLE	3	// compatible but not satisfied yet
+ ^ static int combine(struct arc *, struct arc *);
+ */
+static int
+combine(
+    struct arc *con,
+    struct arc *a)
+{
+#define CA(ct,at)	(((ct)<<CHAR_BIT) | (at))
+
+    switch (CA(con->type, a->type)) {
+    case CA('^', PLAIN):	/* newlines are handled separately */
+    case CA('$', PLAIN):
+	return INCOMPATIBLE;
+	break;
+    case CA(AHEAD, PLAIN):	/* color constraints meet colors */
+    case CA(BEHIND, PLAIN):
+	if (con->co == a->co) {
+	    return SATISFIED;
+	}
+	return INCOMPATIBLE;
+	break;
+    case CA('^', '^'):		/* collision, similar constraints */
+    case CA('$', '$'):
+    case CA(AHEAD, AHEAD):
+    case CA(BEHIND, BEHIND):
+	if (con->co == a->co) {	/* true duplication */
+	    return SATISFIED;
+	}
+	return INCOMPATIBLE;
+	break;
+    case CA('^', BEHIND):	/* collision, dissimilar constraints */
+    case CA(BEHIND, '^'):
+    case CA('$', AHEAD):
+    case CA(AHEAD, '$'):
+	return INCOMPATIBLE;
+	break;
+    case CA('^', '$'):		/* constraints passing each other */
+    case CA('^', AHEAD):
+    case CA(BEHIND, '$'):
+    case CA(BEHIND, AHEAD):
+    case CA('$', '^'):
+    case CA('$', BEHIND):
+    case CA(AHEAD, '^'):
+    case CA(AHEAD, BEHIND):
+    case CA('^', LACON):
+    case CA(BEHIND, LACON):
+    case CA('$', LACON):
+    case CA(AHEAD, LACON):
+	return COMPATIBLE;
+	break;
+    }
+    assert(NOTREACHED);
+    return INCOMPATIBLE;	/* for benefit of blind compilers */
+}
+
+/*
+ - fixempties - get rid of EMPTY arcs
+ ^ static void fixempties(struct nfa *, FILE *);
+ */
+static void
+fixempties(
+    struct nfa *nfa,
+    FILE *f)			/* for debug output; NULL none */
+{
+    struct state *s;
+    struct state *s2;
+    struct state *nexts;
+    struct arc *a;
+    struct arc *nexta;
+    int totalinarcs;
+    struct arc **inarcsorig;
+    struct arc **arcarray;
+    int arccount;
+    int prevnins;
+    int nskip;
+
+    /*
+     * First, get rid of any states whose sole out-arc is an EMPTY,
+     * since they're basically just aliases for their successor.  The
+     * parsing algorithm creates enough of these that it's worth
+     * special-casing this.
+     */
+    for (s = nfa->states; s != NULL && !NISERR(); s = nexts) {
+	nexts = s->next;
+	if (s->flag || s->nouts != 1) {
+	    continue;
+	}
+	a = s->outs;
+	assert(a != NULL && a->outchain == NULL);
+	if (a->type != EMPTY) {
+	    continue;
+	}
+	if (s != a->to) {
+	    moveins(nfa, s, a->to);
+	}
+	dropstate(nfa, s);
+    }
+
+    /*
+     * Similarly, get rid of any state with a single EMPTY in-arc, by
+     * folding it into its predecessor.
+     */
+    for (s = nfa->states; s != NULL && !NISERR(); s = nexts) {
+	nexts = s->next;
+	/* Ensure tmp fields are clear for next step */
+	assert(s->tmp == NULL);
+	if (s->flag || s->nins != 1) {
+	    continue;
+	}
+	a = s->ins;
+	assert(a != NULL && a->inchain == NULL);
+	if (a->type != EMPTY) {
+	    continue;
+	}
+	if (s != a->from) {
+	    moveouts(nfa, s, a->from);
+	}
+	dropstate(nfa, s);
+    }
+
+    if (NISERR()) {
+	return;
+    }
+
+    /*
+     * For each remaining NFA state, find all other states from which it is
+     * reachable by a chain of one or more EMPTY arcs.  Then generate new arcs
+     * that eliminate the need for each such chain.
+     *
+     * We could replace a chain of EMPTY arcs that leads from a "from" state
+     * to a "to" state either by pushing non-EMPTY arcs forward (linking
+     * directly from "from"'s predecessors to "to") or by pulling them back
+     * (linking directly from "from" to "to"'s successors).  We choose to
+     * always do the former; this choice is somewhat arbitrary, but the
+     * approach below requires that we uniformly do one or the other.
+     *
+     * Suppose we have a chain of N successive EMPTY arcs (where N can easily
+     * approach the size of the NFA).  All of the intermediate states must
+     * have additional inarcs and outarcs, else they'd have been removed by
+     * the steps above.  Assuming their inarcs are mostly not empties, we will
+     * add O(N^2) arcs to the NFA, since a non-EMPTY inarc leading to any one
+     * state in the chain must be duplicated to lead to all its successor
+     * states as well.  So there is no hope of doing less than O(N^2) work;
+     * however, we should endeavor to keep the big-O cost from being even
+     * worse than that, which it can easily become without care.  In
+     * particular, suppose we were to copy all S1's inarcs forward to S2, and
+     * then also to S3, and then later we consider pushing S2's inarcs forward
+     * to S3.  If we include the arcs already copied from S1 in that, we'd be
+     * doing O(N^3) work.  (The duplicate-arc elimination built into newarc()
+     * and its cohorts would get rid of the extra arcs, but not without cost.)
+     *
+     * We can avoid this cost by treating only arcs that existed at the start
+     * of this phase as candidates to be pushed forward.  To identify those,
+     * we remember the first inarc each state had to start with.  We rely on
+     * the fact that newarc() and friends put new arcs on the front of their
+     * to-states' inchains, and that this phase never deletes arcs, so that
+     * the original arcs must be the last arcs in their to-states' inchains.
+     *
+     * So the process here is that, for each state in the NFA, we gather up
+     * all non-EMPTY inarcs of states that can reach the target state via
+     * EMPTY arcs.  We then sort, de-duplicate, and merge these arcs into the
+     * target state's inchain.  (We can safely use sort-merge for this as long
+     * as we update each state's original-arcs pointer after we add arcs to
+     * it; the sort step of mergeins probably changed the order of the old
+     * arcs.)
+     *
+     * Another refinement worth making is that, because we only add non-EMPTY
+     * arcs during this phase, and all added arcs have the same from-state as
+     * the non-EMPTY arc they were cloned from, we know ahead of time that any
+     * states having only EMPTY outarcs will be useless for lack of outarcs
+     * after we drop the EMPTY arcs.  (They cannot gain non-EMPTY outarcs if
+     * they had none to start with.)  So we need not bother to update the
+     * inchains of such states at all.
+     */
+
+    /* Remember the states' first original inarcs */
+    /* ... and while at it, count how many old inarcs there are altogether */
+    inarcsorig = (struct arc **) MALLOC(nfa->nstates * sizeof(struct arc *));
+    if (inarcsorig == NULL) {
+	NERR(REG_ESPACE);
+	return;
+    }
+    totalinarcs = 0;
+    for (s = nfa->states; s != NULL; s = s->next) {
+	inarcsorig[s->no] = s->ins;
+	totalinarcs += s->nins;
+    }
+
+    /*
+     * Create a workspace for accumulating the inarcs to be added to the
+     * current target state.  totalinarcs is probably a considerable
+     * overestimate of the space needed, but the NFA is unlikely to be large
+     * enough at this point to make it worth being smarter.
+     */
+    arcarray = (struct arc **) MALLOC(totalinarcs * sizeof(struct arc *));
+    if (arcarray == NULL) {
+	NERR(REG_ESPACE);
+	FREE(inarcsorig);
+	return;
+    }
+
+    /* And iterate over the target states */
+    for (s = nfa->states; s != NULL && !NISERR(); s = s->next) {
+	/* Ignore target states without non-EMPTY outarcs, per note above */
+	if (!s->flag && !hasnonemptyout(s)) {
+	    continue;
+	}
+
+	/* Find predecessor states and accumulate their original inarcs */
+	arccount = 0;
+	for (s2 = emptyreachable(nfa, s, s, inarcsorig); s2 != s; s2 = nexts) {
+	    /* Add s2's original inarcs to arcarray[], but ignore empties */
+	    for (a = inarcsorig[s2->no]; a != NULL; a = a->inchain) {
+		if (a->type != EMPTY) {
+		    arcarray[arccount++] = a;
+		}
+	    }
+
+  	    /* Reset the tmp fields as we walk back */
+  	    nexts = s2->tmp;
+  	    s2->tmp = NULL;
+  	}
+  	s->tmp = NULL;
+	assert(arccount <= totalinarcs);
+
+	/* Remember how many original inarcs this state has */
+	prevnins = s->nins;
+
+	/* Add non-duplicate inarcs to target state */
+	mergeins(nfa, s, arcarray, arccount);
+
+	/* Now we must update the state's inarcsorig pointer */
+	nskip = s->nins - prevnins;
+	a = s->ins;
+	while (nskip-- > 0) {
+	    a = a->inchain;
+	}
+	inarcsorig[s->no] = a;
+    }
+
+    FREE(arcarray);
+    FREE(inarcsorig);
+
+    if (NISERR()) {
+	return;
+    }
+
+    /*
+     * Remove all the EMPTY arcs, since we don't need them anymore.
+     */
+    for (s = nfa->states; s != NULL; s = s->next) {
+	for (a = s->outs; a != NULL; a = nexta) {
+	    nexta = a->outchain;
+	    if (a->type == EMPTY) {
+		freearc(nfa, a);
+	    }
+	}
+    }
+
+    /*
+     * And remove any states that have become useless.  (This cleanup is
+     * not very thorough, and would be even less so if we tried to
+     * combine it with the previous step; but cleanup() will take care
+     * of anything we miss.)
+     */
+    for (s = nfa->states; s != NULL; s = nexts) {
+	nexts = s->next;
+	if ((s->nins == 0 || s->nouts == 0) && !s->flag) {
+	    dropstate(nfa, s);
+	}
+    }
+
+    if (f != NULL) {
+	dumpnfa(nfa, f);
+    }
+}
+
+/*
+ - emptyreachable - recursively find all states that can reach s by EMPTY arcs
+ * The return value is the last such state found.  Its tmp field links back
+ * to the next-to-last such state, and so on back to s, so that all these
+ * states can be located without searching the whole NFA.
+ *
+ * Since this is only used in fixempties(), we pass in the inarcsorig[] array
+ * maintained by that function.  This lets us skip over all new inarcs, which
+ * are certainly not EMPTY arcs.
+ *
+ * The maximum recursion depth here is equal to the length of the longest
+ * loop-free chain of EMPTY arcs, which is surely no more than the size of
+ * the NFA, and in practice will be less than that.
+ ^ static struct state *emptyreachable(struct state *, struct state *);
+ */
+static struct state *
+emptyreachable(
+    struct nfa *nfa,
+    struct state *s,
+    struct state *lastfound,
+    struct arc **inarcsorig)
+{
+    struct arc *a;
+
+    s->tmp = lastfound;
+    lastfound = s;
+    for (a = inarcsorig[s->no]; a != NULL; a = a->inchain) {
+	if (a->type == EMPTY && a->from->tmp == NULL) {
+	    lastfound = emptyreachable(nfa, a->from, lastfound, inarcsorig);
+	}
+    }
+    return lastfound;
+}
+
+/*
+ * isconstraintarc - detect whether an arc is of a constraint type
+ */
+static inline int
+isconstraintarc(struct arc * a)
+{
+    switch (a->type)
+    {
+	case '^':
+	case '$':
+	case BEHIND:
+	case AHEAD:
+	case LACON:
+	    return 1;
+    }
+    return 0;
+}
+
+/*
+ * hasconstraintout - does state have a constraint out arc?
+ */
+static int
+hasconstraintout(struct state * s)
+{
+    struct arc *a;
+
+    for (a = s->outs; a != NULL; a = a->outchain) {
+	if (isconstraintarc(a)) {
+	    return 1;
+	}
+    }
+    return 0;
+}
+
+/*
+ * fixconstraintloops - get rid of loops containing only constraint arcs
+ *
+ * A loop of states that contains only constraint arcs is useless, since
+ * passing around the loop represents no forward progress.  Moreover, it
+ * would cause infinite looping in pullback/pushfwd, so we need to get rid
+ * of such loops before doing that.
+ */
+static void
+fixconstraintloops(
+    struct nfa * nfa,
+    FILE *f)		/* for debug output; NULL none */
+{
+    struct state *s;
+    struct state *nexts;
+    struct arc *a;
+    struct arc *nexta;
+    int hasconstraints;
+
+    /*
+     * In the trivial case of a state that loops to itself, we can just drop
+     * the constraint arc altogether.  This is worth special-casing because
+     * such loops are far more common than loops containing multiple states.
+     * While we're at it, note whether any constraint arcs survive.
+     */
+    hasconstraints = 0;
+    for (s = nfa->states; s != NULL && !NISERR(); s = nexts) {
+	nexts = s->next;
+	/* while we're at it, ensure tmp fields are clear for next step */
+	assert(s->tmp == NULL);
+	for (a = s->outs; a != NULL && !NISERR(); a = nexta) {
+	    nexta = a->outchain;
+	    if (isconstraintarc(a)) {
+		if (a->to == s) {
+		    freearc(nfa, a);
+		} else {
+		    hasconstraints = 1;
+ 		}
+	    }
+	}
+ 	/* If we removed all the outarcs, the state is useless. */
+ 	if (s->nouts == 0 && !s->flag) {
+ 	    dropstate(nfa, s);
+	}
+    }
+
+    /* Nothing to do if no remaining constraint arcs */
+    if (NISERR() || !hasconstraints) {
+	return;
+    }
+
+    /*
+     * Starting from each remaining NFA state, search outwards for a
+     * constraint loop.  If we find a loop, break the loop, then start the
+     * search over.  (We could possibly retain some state from the first scan,
+     * but it would complicate things greatly, and multi-state constraint
+     * loops are rare enough that it's not worth optimizing the case.)
+     */
+  restart:
+    for (s = nfa->states; s != NULL && !NISERR(); s = s->next) {
+	if (findconstraintloop(nfa, s)) {
+	    goto restart;
+	}
+    }
+
+    if (NISERR()) {
+	return;
+    }
+
+    /*
+     * Now remove any states that have become useless.  (This cleanup is not
+     * very thorough, and would be even less so if we tried to combine it with
+     * the previous step; but cleanup() will take care of anything we miss.)
+     *
+     * Because findconstraintloop intentionally doesn't reset all tmp fields,
+     * we have to clear them after it's done.  This is a convenient place to
+     * do that, too.
+     */
+    for (s = nfa->states; s != NULL; s = nexts) {
+	nexts = s->next;
+	s->tmp = NULL;
+	if ((s->nins == 0 || s->nouts == 0) && !s->flag) {
+	    dropstate(nfa, s);
+	}
+    }
+
+    if (f != NULL) {
+ 	dumpnfa(nfa, f);
+    }
+}
+
+/*
+ * findconstraintloop - recursively find a loop of constraint arcs
+ *
+ * If we find a loop, break it by calling breakconstraintloop(), then
+ * return 1; otherwise return 0.
+ *
+ * State tmp fields are guaranteed all NULL on a success return, because
+ * breakconstraintloop does that.  After a failure return, any state that
+ * is known not to be part of a loop is marked with s->tmp == s; this allows
+ * us not to have to re-prove that fact on later calls.  (This convention is
+ * workable because we already eliminated single-state loops.)
+ *
+ * Note that the found loop doesn't necessarily include the first state we
+ * are called on.  Any loop reachable from that state will do.
+ *
+ * The maximum recursion depth here is one more than the length of the longest
+ * loop-free chain of constraint arcs, which is surely no more than the size
+ * of the NFA, and in practice will be a lot less than that.
+ */
+static int
+findconstraintloop(struct nfa * nfa, struct state * s)
+{
+    struct arc *a;
+
+    /* Since this is recursive, it could be driven to stack overflow */
+    if (STACK_TOO_DEEP(nfa->v->re)) {
+	NERR(REG_ETOOBIG);
+	return 1;		/* to exit as quickly as possible */
+    }
+
+    if (s->tmp != NULL) {
+	/* Already proven uninteresting? */
+	if (s->tmp == s) {
+	    return 0;
+	}
+	/* Found a loop involving s */
+	breakconstraintloop(nfa, s);
+	/* The tmp fields have been cleaned up by breakconstraintloop */
+	return 1;
+    }
+    for (a = s->outs; a != NULL; a = a->outchain) {
+	if (isconstraintarc(a)) {
+	    struct state *sto = a->to;
+
+	    assert(sto != s);
+	    s->tmp = sto;
+	    if (findconstraintloop(nfa, sto)) {
+		return 1;
+	    }
+	}
+    }
+
+    /*
+     * If we get here, no constraint loop exists leading out from s.  Mark it
+     * with s->tmp == s so we need not rediscover that fact again later.
+     */
+    s->tmp = s;
+    return 0;
+}
+
+/*
+ * breakconstraintloop - break a loop of constraint arcs
+ *
+ * sinitial is any one member state of the loop.  Each loop member's tmp
+ * field links to its successor within the loop.  (Note that this function
+ * will reset all the tmp fields to NULL.)
+ *
+ * We can break the loop by, for any one state S1 in the loop, cloning its
+ * loop successor state S2 (and possibly following states), and then moving
+ * all S1->S2 constraint arcs to point to the cloned S2.  The cloned S2 should
+ * copy any non-constraint outarcs of S2.  Constraint outarcs should be
+ * dropped if they point back to S1, else they need to be copied as arcs to
+ * similarly cloned states S3, S4, etc.  In general, each cloned state copies
+ * non-constraint outarcs, drops constraint outarcs that would lead to itself
+ * or any earlier cloned state, and sends other constraint outarcs to newly
+ * cloned states.  No cloned state will have any inarcs that aren't constraint
+ * arcs or do not lead from S1 or earlier-cloned states.  It's okay to drop
+ * constraint back-arcs since they would not take us to any state we've not
+ * already been in; therefore, no new constraint loop is created.  In this way
+ * we generate a modified NFA that can still represent every useful state
+ * sequence, but not sequences that represent state loops with no consumption
+ * of input data.  Note that the set of cloned states will certainly include
+ * all of the loop member states other than S1, and it may also include
+ * non-loop states that are reachable from S2 via constraint arcs.  This is
+ * important because there is no guarantee that findconstraintloop found a
+ * maximal loop (and searching for one would be NP-hard, so don't try).
+ * Frequently the "non-loop states" are actually part of a larger loop that
+ * we didn't notice, and indeed there may be several overlapping loops.
+ * This technique ensures convergence in such cases, while considering only
+ * the originally-found loop does not.
+ *
+ * If there is only one S1->S2 constraint arc, then that constraint is
+ * certainly satisfied when we enter any of the clone states.  This means that
+ * in the common case where many of the constraint arcs are identically
+ * labeled, we can merge together clone states linked by a similarly-labeled
+ * constraint: if we can get to the first one we can certainly get to the
+ * second, so there's no need to distinguish.  This greatly reduces the number
+ * of new states needed, so we preferentially break the given loop at a state
+ * pair where this is true.
+ *
+ * Furthermore, it's fairly common to find that a cloned successor state has
+ * no outarcs, especially if we're a bit aggressive about removing unnecessary
+ * outarcs.  If that happens, then there is simply not any interesting state
+ * that can be reached through the predecessor's loop arcs, which means we can
+ * break the loop just by removing those loop arcs, with no new states added.
+ */
+static void
+breakconstraintloop(struct nfa * nfa, struct state * sinitial)
+{
+    struct state *s;
+    struct state *shead;
+    struct state *stail;
+    struct state *sclone;
+    struct state *nexts;
+    struct arc *refarc;
+    struct arc *a;
+    struct arc *nexta;
+
+    /*
+     * Start by identifying which loop step we want to break at.
+     * Preferentially this is one with only one constraint arc.  (XXX are
+     * there any other secondary heuristics we want to use here?)  Set refarc
+     * to point to the selected lone constraint arc, if there is one.
+     */
+    refarc = NULL;
+    s = sinitial;
+    do {
+	nexts = s->tmp;
+	assert(nexts != s);	/* should not see any one-element loops */
+	if (refarc == NULL) {
+	    int narcs = 0;
+
+	    for (a = s->outs; a != NULL; a = a->outchain) {
+		if (a->to == nexts && isconstraintarc(a)) {
+		    refarc = a;
+		    narcs++;
+		}
+	    }
+	    assert(narcs > 0);
+	    if (narcs > 1) {
+		refarc = NULL;	/* multiple constraint arcs here, no good */
+	    }
+	}
+	s = nexts;
+    } while (s != sinitial);
+
+    if (refarc) {
+	/* break at the refarc */
+	shead = refarc->from;
+	stail = refarc->to;
+	assert(stail == shead->tmp);
+    } else {
+	/* for lack of a better idea, break after sinitial */
+	shead = sinitial;
+	stail = sinitial->tmp;
+    }
+
+    /*
+     * Reset the tmp fields so that we can use them for local storage in
+     * clonesuccessorstates.  (findconstraintloop won't mind, since it's just
+     * going to abandon its search anyway.)
+     */
+    for (s = nfa->states; s != NULL; s = s->next) {
+	s->tmp = NULL;
+    }
+
+    /*
+     * Recursively build clone state(s) as needed.
+     */
+    sclone = newstate(nfa);
+    if (sclone == NULL) {
+	assert(NISERR());
+	return;
+    }
+
+    clonesuccessorstates(nfa, stail, sclone, shead, refarc,
+	    NULL, NULL, nfa->nstates);
+
+    if (NISERR()) {
+	return;
+    }
+
+    /*
+     * It's possible that sclone has no outarcs at all, in which case it's
+     * useless.  (We don't try extremely hard to get rid of useless states
+     * here, but this is an easy and fairly common case.)
+     */
+    if (sclone->nouts == 0) {
+	freestate(nfa, sclone);
+	sclone = NULL;
+    }
+
+    /*
+     * Move shead's constraint-loop arcs to point to sclone, or just drop them
+     * if we discovered we don't need sclone.
+     */
+    for (a = shead->outs; a != NULL; a = nexta) {
+	nexta = a->outchain;
+	if (a->to == stail && isconstraintarc(a)) {
+	    if (sclone) {
+		cparc(nfa, a, shead, sclone);
+	    }
+	    freearc(nfa, a);
+	    if (NISERR()) {
+		break;
+	    }
+	}
+    }
+}
+
+/*
+ * clonesuccessorstates - create a tree of constraint-arc successor states
+ *
+ * ssource is the state to be cloned, and sclone is the state to copy its
+ * outarcs into.  sclone's inarcs, if any, should already be set up.
+ *
+ * spredecessor is the original predecessor state that we are trying to build
+ * successors for (it may not be the immediate predecessor of ssource).
+ * refarc, if not NULL, is the original constraint arc that is known to have
+ * been traversed out of spredecessor to reach the successor(s).
+ *
+ * For each cloned successor state, we transiently create a "donemap" that is
+ * a boolean array showing which source states we've already visited for this
+ * clone state.  This prevents infinite recursion as well as useless repeat
+ * visits to the same state subtree (which can add up fast, since typical NFAs
+ * have multiple redundant arc pathways).  Each donemap is a char array
+ * indexed by state number.  The donemaps are all of the same size "nstates",
+ * which is nfa->nstates as of the start of the recursion.  This is enough to
+ * have entries for all pre-existing states, but *not* entries for clone
+ * states created during the recursion.  That's okay since we have no need to
+ * mark those.
+ *
+ * curdonemap is NULL when recursing to a new sclone state, or sclone's
+ * donemap when we are recursing without having created a new state (which we
+ * do when we decide we can merge a successor state into the current clone
+ * state).  outerdonemap is NULL at the top level and otherwise the parent
+ * clone state's donemap.
+ *
+ * The successor states we create and fill here form a strict tree structure,
+ * with each state having exactly one predecessor, except that the toplevel
+ * state has no inarcs as yet (breakconstraintloop will add its inarcs from
+ * spredecessor after we're done).  Thus, we can examine sclone's inarcs back
+ * to the root, plus refarc if any, to identify the set of constraints already
+ * known valid at the current point.  This allows us to avoid generating extra
+ * successor states.
+ */
+static void
+clonesuccessorstates(
+    struct nfa * nfa,
+    struct state * ssource,
+    struct state * sclone,
+    struct state * spredecessor,
+    struct arc * refarc,
+    char *curdonemap,
+    char *outerdonemap,
+    int nstates)
+{
+    char *donemap;
+    struct arc *a;
+
+    /* Since this is recursive, it could be driven to stack overflow */
+    if (STACK_TOO_DEEP(nfa->v->re)) {
+	NERR(REG_ETOOBIG);
+	return;
+    }
+
+    /* If this state hasn't already got a donemap, create one */
+    donemap = curdonemap;
+    if (donemap == NULL) {
+	donemap = (char *) MALLOC(nstates * sizeof(char));
+	if (donemap == NULL) {
+	    NERR(REG_ESPACE);
+	    return;
+	}
+
+	if (outerdonemap != NULL) {
+	    /*
+	     * Not at outermost recursion level, so copy the outer level's
+	     * donemap; this ensures that we see states in process of being
+	     * visited at outer levels, or already merged into predecessor
+	     * states, as ones we shouldn't traverse back to.
+	     */
+	    memcpy(donemap, outerdonemap, nstates * sizeof(char));
+	} else {
+	    /* At outermost level, only spredecessor is off-limits */
+	    memset(donemap, 0, nstates * sizeof(char));
+	    assert(spredecessor->no < nstates);
+	    donemap[spredecessor->no] = 1;
+	}
+    }
+
+    /* Mark ssource as visited in the donemap */
+    assert(ssource->no < nstates);
+    assert(donemap[ssource->no] == 0);
+    donemap[ssource->no] = 1;
+
+    /*
+     * We proceed by first cloning all of ssource's outarcs, creating new
+     * clone states as needed but not doing more with them than that.  Then in
+     * a second pass, recurse to process the child clone states.  This allows
+     * us to have only one child clone state per reachable source state, even
+     * when there are multiple outarcs leading to the same state.  Also, when
+     * we do visit a child state, its set of inarcs is known exactly, which
+     * makes it safe to apply the constraint-is-already-checked optimization.
+     * Also, this ensures that we've merged all the states we can into the
+     * current clone before we recurse to any children, thus possibly saving
+     * them from making extra images of those states.
+     *
+     * While this function runs, child clone states of the current state are
+     * marked by setting their tmp fields to point to the original state they
+     * were cloned from.  This makes it possible to detect multiple outarcs
+     * leading to the same state, and also makes it easy to distinguish clone
+     * states from original states (which will have tmp == NULL).
+     */
+    for (a = ssource->outs; a != NULL && !NISERR(); a = a->outchain) {
+	struct state *sto = a->to;
+
+	/*
+	 * We do not consider cloning successor states that have no constraint
+	 * outarcs; just link to them as-is.  They cannot be part of a
+	 * constraint loop so there is no need to make copies.  In particular,
+	 * this rule keeps us from trying to clone the post state, which would
+	 * be a bad idea.
+	 */
+	if (isconstraintarc(a) && hasconstraintout(sto)) {
+	    struct state *prevclone;
+	    int canmerge;
+	    struct arc *a2;
+
+	    /*
+	     * Back-link constraint arcs must not be followed.  Nor is there a
+	     * need to revisit states previously merged into this clone.
+	     */
+	    assert(sto->no < nstates);
+	    if (donemap[sto->no] != 0) {
+		continue;
+	    }
+
+	    /*
+	     * Check whether we already have a child clone state for this
+	     * source state.
+	     */
+	    prevclone = NULL;
+	    for (a2 = sclone->outs; a2 != NULL; a2 = a2->outchain) {
+		if (a2->to->tmp == sto) {
+		    prevclone = a2->to;
+		    break;
+		}
+	    }
+
+	    /*
+	     * If this arc is labeled the same as refarc, or the same as any
+	     * arc we must have traversed to get to sclone, then no additional
+	     * constraints need to be met to get to sto, so we should just
+	     * merge its outarcs into sclone.
+	     */
+	    if (refarc && a->type == refarc->type && a->co == refarc->co) {
+		canmerge = 1;
+	    } else {
+		struct state *s;
+
+		canmerge = 0;
+		for (s = sclone; s->ins; s = s->ins->from) {
+		    if (s->nins == 1 &&
+			    a->type == s->ins->type && a->co == s->ins->co) {
+			canmerge = 1;
+			break;
+		    }
+		}
+	    }
+
+	    if (canmerge) {
+		/*
+		 * We can merge into sclone.  If we previously made a child
+		 * clone state, drop it; there's no need to visit it.  (This
+		 * can happen if ssource has multiple pathways to sto, and we
+		 * only just now found one that is provably a no-op.)
+		 */
+		if (prevclone) {
+		    dropstate(nfa, prevclone);	/* kills our outarc, too */
+		}
+
+		/* Recurse to merge sto's outarcs into sclone */
+		clonesuccessorstates(nfa, sto, sclone, spredecessor, refarc,
+			donemap, outerdonemap, nstates);
+		/* sto should now be marked as previously visited */
+		assert(NISERR() || donemap[sto->no] == 1);
+	    } else if (prevclone) {
+		/*
+		 * We already have a clone state for this successor, so just
+		 * make another arc to it.
+		 */
+		cparc(nfa, a, sclone, prevclone);
+	    } else {
+		/*
+		 * We need to create a new successor clone state.
+		 */
+		struct state *stoclone;
+
+		stoclone = newstate(nfa);
+		if (stoclone == NULL) {
+		    assert(NISERR());
+		    break;
+		}
+		/* Mark it as to what it's a clone of */
+		stoclone->tmp = sto;
+		/* ... and add the outarc leading to it */
+		cparc(nfa, a, sclone, stoclone);
+	    }
+	} else {
+	    /*
+	     * Non-constraint outarcs just get copied to sclone, as do outarcs
+	     * leading to states with no constraint outarc.
+	     */
+	    cparc(nfa, a, sclone, sto);
+	}
+    }
+
+    /*
+     * If we are at outer level for this clone state, recurse to all its child
+     * clone states, clearing their tmp fields as we go.  (If we're not
+     * outermost for sclone, leave this to be done by the outer call level.)
+     * Note that if we have multiple outarcs leading to the same clone state,
+     * it will only be recursed-to once.
+     */
+    if (curdonemap == NULL) {
+	for (a = sclone->outs; a != NULL && !NISERR(); a = a->outchain) {
+	    struct state *stoclone = a->to;
+	    struct state *sto = stoclone->tmp;
+
+	    if (sto != NULL) {
+		stoclone->tmp = NULL;
+		clonesuccessorstates(nfa, sto, stoclone, spredecessor, refarc,
+			NULL, donemap, nstates);
+	    }
+	}
+
+	/* Don't forget to free sclone's donemap when done with it */
+	FREE(donemap);
+    }
+}
+
+/*
+ - cleanup - clean up NFA after optimizations
+ ^ static void cleanup(struct nfa *);
+ */
+static void
+cleanup(
+    struct nfa *nfa)
+{
+    struct state *s;
+    struct state *nexts;
+    int n;
+
+    /*
+     * Clear out unreachable or dead-end states. Use pre to mark reachable,
+     * then post to mark can-reach-post.
+     */
+
+    markreachable(nfa, nfa->pre, NULL, nfa->pre);
+    markcanreach(nfa, nfa->post, nfa->pre, nfa->post);
+    for (s = nfa->states; s != NULL; s = nexts) {
+	nexts = s->next;
+	if (s->tmp != nfa->post && !s->flag) {
+	    dropstate(nfa, s);
+	}
+    }
+    assert(nfa->post->nins == 0 || nfa->post->tmp == nfa->post);
+    cleartraverse(nfa, nfa->pre);
+    assert(nfa->post->nins == 0 || nfa->post->tmp == NULL);
+    /* the nins==0 (final unreachable) case will be caught later */
+
+    /*
+     * Renumber surviving states.
+     */
+
+    n = 0;
+    for (s = nfa->states; s != NULL; s = s->next) {
+	s->no = n++;
+    }
+    nfa->nstates = n;
+}
+
+/*
+ - markreachable - recursive marking of reachable states
+ ^ static void markreachable(struct nfa *, struct state *, struct state *,
+ ^ 	struct state *);
+ */
+static void
+markreachable(
+    struct nfa *nfa,
+    struct state *s,
+    struct state *okay,		/* consider only states with this mark */
+    struct state *mark)		/* the value to mark with */
+{
+    struct arc *a;
+
+    if (s->tmp != okay) {
+	return;
+    }
+    s->tmp = mark;
+
+    for (a = s->outs; a != NULL; a = a->outchain) {
+	markreachable(nfa, a->to, okay, mark);
+    }
+}
+
+/*
+ - markcanreach - recursive marking of states which can reach here
+ ^ static void markcanreach(struct nfa *, struct state *, struct state *,
+ ^ 	struct state *);
+ */
+static void
+markcanreach(
+    struct nfa *nfa,
+    struct state *s,
+    struct state *okay,		/* consider only states with this mark */
+    struct state *mark)		/* the value to mark with */
+{
+    struct arc *a;
+
+    if (s->tmp != okay) {
+	return;
+    }
+    s->tmp = mark;
+
+    for (a = s->ins; a != NULL; a = a->inchain) {
+	markcanreach(nfa, a->from, okay, mark);
+    }
+}
+
+/*
+ - analyze - ascertain potentially-useful facts about an optimized NFA
+ ^ static long analyze(struct nfa *);
+ */
+static long			/* re_info bits to be ORed in */
+analyze(
+    struct nfa *nfa)
+{
+    struct arc *a;
+    struct arc *aa;
+
+    if (nfa->pre->outs == NULL) {
+	return REG_UIMPOSSIBLE;
+    }
+    for (a = nfa->pre->outs; a != NULL; a = a->outchain) {
+	for (aa = a->to->outs; aa != NULL; aa = aa->outchain) {
+	    if (aa->to == nfa->post) {
+		return REG_UEMPTYMATCH;
+	    }
+	}
+    }
+    return 0;
+}
+
+/*
+ - compact - construct the compact representation of an NFA
+ ^ static void compact(struct nfa *, struct cnfa *);
+ */
+static void
+compact(
+    struct nfa *nfa,
+    struct cnfa *cnfa)
+{
+    struct state *s;
+    struct arc *a;
+    size_t nstates;
+    size_t narcs;
+    struct carc *ca;
+    struct carc *first;
+
+    assert(!NISERR());
+
+    nstates = 0;
+    narcs = 0;
+    for (s = nfa->states; s != NULL; s = s->next) {
+	nstates++;
+	narcs += s->nouts + 1;	/* need one extra for endmarker */
+    }
+
+    cnfa->stflags = (char *) MALLOC(nstates * sizeof(char));
+    cnfa->states = (struct carc **) MALLOC(nstates * sizeof(struct carc *));
+    cnfa->arcs = (struct carc *) MALLOC(narcs * sizeof(struct carc));
+    if (cnfa->stflags == NULL || cnfa->states == NULL || cnfa->arcs == NULL) {
+	if (cnfa->stflags != NULL) {
+	    FREE(cnfa->stflags);
+	}
+	if (cnfa->states != NULL) {
+	    FREE(cnfa->states);
+	}
+	if (cnfa->arcs != NULL) {
+	    FREE(cnfa->arcs);
+	}
+	NERR(REG_ESPACE);
+	return;
+    }
+    cnfa->nstates = nstates;
+    cnfa->pre = nfa->pre->no;
+    cnfa->post = nfa->post->no;
+    cnfa->bos[0] = nfa->bos[0];
+    cnfa->bos[1] = nfa->bos[1];
+    cnfa->eos[0] = nfa->eos[0];
+    cnfa->eos[1] = nfa->eos[1];
+    cnfa->ncolors = maxcolor(nfa->cm) + 1;
+    cnfa->flags = 0;
+
+    ca = cnfa->arcs;
+    for (s = nfa->states; s != NULL; s = s->next) {
+	assert((size_t) s->no < nstates);
+	cnfa->stflags[s->no] = 0;
+	cnfa->states[s->no] = ca;
+	first = ca;
+	for (a = s->outs; a != NULL; a = a->outchain) {
+	    switch (a->type) {
+	    case PLAIN:
+		ca->co = a->co;
+		ca->to = a->to->no;
+		ca++;
+		break;
+	    case LACON:
+		assert(s->no != cnfa->pre);
+		ca->co = (color) (cnfa->ncolors + a->co);
+		ca->to = a->to->no;
+		ca++;
+		cnfa->flags |= HASLACONS;
+		break;
+	    default:
+		NERR(REG_ASSERT);
+		break;
+	    }
+	}
+	carcsort(first, ca - first);
+	ca->co = COLORLESS;
+	ca->to = 0;
+	ca++;
+    }
+    assert(ca == &cnfa->arcs[narcs]);
+    assert(cnfa->nstates != 0);
+
+    /*
+     * Mark no-progress states.
+     */
+
+    for (a = nfa->pre->outs; a != NULL; a = a->outchain) {
+	cnfa->stflags[a->to->no] = CNFA_NOPROGRESS;
+    }
+    cnfa->stflags[nfa->pre->no] = CNFA_NOPROGRESS;
+}
+
+/*
+ - carcsort - sort compacted-NFA arcs by color
+ ^ static void carcsort(struct carc *, struct carc *);
+ */
+static void
+carcsort(
+    struct carc *first,
+    size_t n)
+{
+    if (n > 1) {
+	qsort(first, n, sizeof(struct carc), carc_cmp);
+    }
+}
+
+static int
+carc_cmp(
+    const void *a,
+    const void *b)
+{
+    const struct carc *aa = (const struct carc *) a;
+    const struct carc *bb = (const struct carc *) b;
+
+    if (aa->co < bb->co) {
+	return -1;
+    }
+    if (aa->co > bb->co) {
+	return +1;
+    }
+    if (aa->to < bb->to) {
+	return -1;
+    }
+    if (aa->to > bb->to) {
+	return +1;
+    }
+    return 0;
+}
+
+/*
+ - freecnfa - free a compacted NFA
+ ^ static void freecnfa(struct cnfa *);
+ */
+static void
+freecnfa(
+    struct cnfa *cnfa)
+{
+    assert(cnfa->nstates != 0);	/* not empty already */
+    cnfa->nstates = 0;
+    FREE(cnfa->stflags);
+    FREE(cnfa->states);
+    FREE(cnfa->arcs);
+}
+
+/*
+ - dumpnfa - dump an NFA in human-readable form
+ ^ static void dumpnfa(struct nfa *, FILE *);
+ */
+static void
+dumpnfa(
+    struct nfa *nfa,
+    FILE *f)
+{
+#ifdef REG_DEBUG
+    struct state *s;
+    int nstates = 0;
+    int narcs = 0;
+
+    fprintf(f, "pre %d, post %d", nfa->pre->no, nfa->post->no);
+    if (nfa->bos[0] != COLORLESS) {
+	fprintf(f, ", bos [%ld]", (long) nfa->bos[0]);
+    }
+    if (nfa->bos[1] != COLORLESS) {
+	fprintf(f, ", bol [%ld]", (long) nfa->bos[1]);
+    }
+    if (nfa->eos[0] != COLORLESS) {
+	fprintf(f, ", eos [%ld]", (long) nfa->eos[0]);
+    }
+    if (nfa->eos[1] != COLORLESS) {
+	fprintf(f, ", eol [%ld]", (long) nfa->eos[1]);
+    }
+    fprintf(f, "\n");
+    for (s = nfa->states; s != NULL; s = s->next) {
+	dumpstate(s, f);
+	nstates++;
+	narcs += s->nouts;
+    }
+    fprintf(f, "total of %d states, %d arcs\n", nstates, narcs);
+    if (nfa->parent == NULL) {
+	dumpcolors(nfa->cm, f);
+    }
+    fflush(f);
+#endif
+}
+
+#ifdef REG_DEBUG		/* subordinates of dumpnfa */
+/*
+ ^ #ifdef REG_DEBUG
+ */
+
+/*
+ - dumpstate - dump an NFA state in human-readable form
+ ^ static void dumpstate(struct state *, FILE *);
+ */
+static void
+dumpstate(
+    struct state *s,
+    FILE *f)
+{
+    struct arc *a;
+
+    fprintf(f, "%d%s%c", s->no, (s->tmp != NULL) ? "T" : "",
+	    (s->flag) ? s->flag : '.');
+    if (s->prev != NULL && s->prev->next != s) {
+	fprintf(f, "\tstate chain bad\n");
+    }
+    if (s->nouts == 0) {
+	fprintf(f, "\tno out arcs\n");
+    } else {
+	dumparcs(s, f);
+    }
+    fflush(f);
+    for (a = s->ins; a != NULL; a = a->inchain) {
+	if (a->to != s) {
+	    fprintf(f, "\tlink from %d to %d on %d's in-chain\n",
+		    a->from->no, a->to->no, s->no);
+	}
+    }
+}
+
+/*
+ - dumparcs - dump out-arcs in human-readable form
+ ^ static void dumparcs(struct state *, FILE *);
+ */
+static void
+dumparcs(
+    struct state *s,
+    FILE *f)
+{
+    int pos;
+    struct arc *a;
+
+    /* printing oldest arcs first is usually clearer */
+    a = s->outs;
+    assert(a != NULL);
+    while (a->outchain != NULL) {
+	a = a->outchain;
+    }
+    pos = 1;
+    do {
+	dumparc(a, s, f);
+	if (pos == 5) {
+	    fprintf(f, "\n");
+	    pos = 1;
+	} else {
+	    pos++;
+	}
+	a = a->outchainRev;
+    } while (a != NULL);
+    if (pos != 1) {
+	fprintf(f, "\n");
+    }
+}
+
+/*
+ - dumparc - dump one outarc in readable form, including prefixing tab
+ ^ static void dumparc(struct arc *, struct state *, FILE *);
+ */
+static void
+dumparc(
+    struct arc *a,
+    struct state *s,
+    FILE *f)
+{
+    struct arc *aa;
+    struct arcbatch *ab;
+
+    fprintf(f, "\t");
+    switch (a->type) {
+    case PLAIN:
+	fprintf(f, "[%ld]", (long) a->co);
+	break;
+    case AHEAD:
+	fprintf(f, ">%ld>", (long) a->co);
+	break;
+    case BEHIND:
+	fprintf(f, "<%ld<", (long) a->co);
+	break;
+    case LACON:
+	fprintf(f, ":%ld:", (long) a->co);
+	break;
+    case '^':
+    case '$':
+	fprintf(f, "%c%d", a->type, (int) a->co);
+	break;
+    case EMPTY:
+	break;
+    default:
+	fprintf(f, "0x%x/0%lo", a->type, (long) a->co);
+	break;
+    }
+    if (a->from != s) {
+	fprintf(f, "?%d?", a->from->no);
+    }
+    for (ab = &a->from->oas; ab != NULL; ab = ab->next) {
+	for (aa = &ab->a[0]; aa < &ab->a[ABSIZE]; aa++) {
+	    if (aa == a) {
+		break;		/* NOTE BREAK OUT */
+	    }
+	}
+	if (aa < &ab->a[ABSIZE]) {	/* propagate break */
+	    break;		/* NOTE BREAK OUT */
+	}
+    }
+    if (ab == NULL) {
+	fprintf(f, "?!?");	/* not in allocated space */
+    }
+    fprintf(f, "->");
+    if (a->to == NULL) {
+	fprintf(f, "NULL");
+	return;
+    }
+    fprintf(f, "%d", a->to->no);
+    for (aa = a->to->ins; aa != NULL; aa = aa->inchain) {
+	if (aa == a) {
+	    break;		/* NOTE BREAK OUT */
+	}
+    }
+    if (aa == NULL) {
+	fprintf(f, "?!?");	/* missing from in-chain */
+    }
+}
+
+/*
+ ^ #endif
+ */
+#endif				/* ifdef REG_DEBUG */
+
+/*
+ - dumpcnfa - dump a compacted NFA in human-readable form
+ ^ static void dumpcnfa(struct cnfa *, FILE *);
+ */
+static void
+dumpcnfa(
+    struct cnfa *cnfa,
+    FILE *f)
+{
+#ifdef REG_DEBUG
+    int st;
+
+    fprintf(f, "pre %d, post %d", cnfa->pre, cnfa->post);
+    if (cnfa->bos[0] != COLORLESS) {
+	fprintf(f, ", bos [%ld]", (long) cnfa->bos[0]);
+    }
+    if (cnfa->bos[1] != COLORLESS) {
+	fprintf(f, ", bol [%ld]", (long) cnfa->bos[1]);
+    }
+    if (cnfa->eos[0] != COLORLESS) {
+	fprintf(f, ", eos [%ld]", (long) cnfa->eos[0]);
+    }
+    if (cnfa->eos[1] != COLORLESS) {
+	fprintf(f, ", eol [%ld]", (long) cnfa->eos[1]);
+    }
+    if (cnfa->flags&HASLACONS) {
+	fprintf(f, ", haslacons");
+    }
+    fprintf(f, "\n");
+    for (st = 0; st < cnfa->nstates; st++) {
+	dumpcstate(st, cnfa, f);
+    }
+    fflush(f);
+#endif
+}
+
+#ifdef REG_DEBUG		/* subordinates of dumpcnfa */
+/*
+ ^ #ifdef REG_DEBUG
+ */
+
+/*
+ - dumpcstate - dump a compacted-NFA state in human-readable form
+ ^ static void dumpcstate(int, struct cnfa *, FILE *);
+ */
+static void
+dumpcstate(
+    int st,
+    struct cnfa *cnfa,
+    FILE *f)
+{
+    struct carc *ca;
+    int pos;
+
+    fprintf(f, "%d%s", st, (cnfa->stflags[st] & CNFA_NOPROGRESS) ? ":" : ".");
+    pos = 1;
+    for (ca = cnfa->states[st]; ca->co != COLORLESS; ca++) {
+	if (ca->co < cnfa->ncolors) {
+	    fprintf(f, "\t[%ld]->%d", (long) ca->co, ca->to);
+	} else {
+	    fprintf(f, "\t:%ld:->%d", (long) (ca->co - cnfa->ncolors), ca->to);
+	}
+	if (pos == 5) {
+	    fprintf(f, "\n");
+	    pos = 1;
+	} else {
+	    pos++;
+	}
+    }
+    if (ca == cnfa->states[st] || pos != 1) {
+	fprintf(f, "\n");
+    }
+    fflush(f);
+}
+
+/*
+ ^ #endif
+ */
+#endif				/* ifdef REG_DEBUG */
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/regcomp.c b/generic/regcomp.c
new file mode 100644
index 0000000..211cd70
--- /dev/null
+++ b/generic/regcomp.c
@@ -0,0 +1,2225 @@
+/*
+ * re_*comp and friends - compile REs
+ * This file #includes several others (see the bottom).
+ *
+ * Copyright (c) 1998, 1999 Henry Spencer. All rights reserved.
+ *
+ * Development of this software was funded, in part, by Cray Research Inc.,
+ * UUNET Communications Services Inc., Sun Microsystems Inc., and Scriptics
+ * Corporation, none of whom are responsible for the results. The author
+ * thanks all of them.
+ *
+ * Redistribution and use in source and binary forms -- with or without
+ * modification -- are permitted for any purpose, provided that
+ * redistributions in source form retain this entire copyright notice and
+ * indicate the origin and nature of any modifications.
+ *
+ * I'd appreciate being given credit for this package in the documentation of
+ * software which uses it, but that is not a requirement.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * HENRY SPENCER BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "regguts.h"
+
+/*
+ * forward declarations, up here so forward datatypes etc. are defined early
+ */
+/* =====^!^===== begin forwards =====^!^===== */
+/* automatically gathered by fwd; do not hand-edit */
+/* === regcomp.c === */
+int compile(regex_t *, const chr *, size_t, int);
+static void moresubs(struct vars *, int);
+static int freev(struct vars *, int);
+static void makesearch(struct vars *, struct nfa *);
+static struct subre *parse(struct vars *, int, int, struct state *, struct state *);
+static struct subre *parsebranch(struct vars *, int, int, struct state *, struct state *, int);
+static void parseqatom(struct vars *, int, int, struct state *, struct state *, struct subre *);
+static void nonword(struct vars *, int, struct state *, struct state *);
+static void word(struct vars *, int, struct state *, struct state *);
+static int scannum(struct vars *);
+static void repeat(struct vars *, struct state *, struct state *, int, int);
+static void bracket(struct vars *, struct state *, struct state *);
+static void cbracket(struct vars *, struct state *, struct state *);
+static void brackpart(struct vars *, struct state *, struct state *);
+static const chr *scanplain(struct vars *);
+static void onechr(struct vars *, pchr, struct state *, struct state *);
+static void dovec(struct vars *, struct cvec *, struct state *, struct state *);
+static void wordchrs(struct vars *);
+static struct subre *subre(struct vars *, int, int, struct state *, struct state *);
+static void freesubre(struct vars *, struct subre *);
+static void freesrnode(struct vars *, struct subre *);
+static void optst(struct vars *, struct subre *);
+static int numst(struct subre *, int);
+static void markst(struct subre *);
+static void cleanst(struct vars *);
+static long nfatree(struct vars *, struct subre *, FILE *);
+static long nfanode(struct vars *, struct subre *, FILE *);
+static int newlacon(struct vars *, struct state *, struct state *, int);
+static void freelacons(struct subre *, int);
+static void rfree(regex_t *);
+static void dump(regex_t *, FILE *);
+static void dumpst(struct subre *, FILE *, int);
+static void stdump(struct subre *, FILE *, int);
+static const char *stid(struct subre *, char *, size_t);
+/* === regc_lex.c === */
+static void lexstart(struct vars *);
+static void prefixes(struct vars *);
+static void lexnest(struct vars *, const chr *, const chr *);
+static void lexword(struct vars *);
+static int next(struct vars *);
+static int lexescape(struct vars *);
+static int lexdigits(struct vars *, int, int, int);
+static int brenext(struct vars *, pchr);
+static void skip(struct vars *);
+static chr newline(NOPARMS);
+static chr chrnamed(struct vars *, const chr *, const chr *, pchr);
+/* === regc_color.c === */
+static void initcm(struct vars *, struct colormap *);
+static void freecm(struct colormap *);
+static void cmtreefree(struct colormap *, union tree *, int);
+static color setcolor(struct colormap *, pchr, pcolor);
+static color maxcolor(struct colormap *);
+static color newcolor(struct colormap *);
+static void freecolor(struct colormap *, pcolor);
+static color pseudocolor(struct colormap *);
+static color subcolor(struct colormap *, pchr c);
+static color newsub(struct colormap *, pcolor);
+static void subrange(struct vars *, pchr, pchr, struct state *, struct state *);
+static void subblock(struct vars *, pchr, struct state *, struct state *);
+static void okcolors(struct nfa *, struct colormap *);
+static void colorchain(struct colormap *, struct arc *);
+static void uncolorchain(struct colormap *, struct arc *);
+static void rainbow(struct nfa *, struct colormap *, int, pcolor, struct state *, struct state *);
+static void colorcomplement(struct nfa *, struct colormap *, int, struct state *, struct state *, struct state *);
+#ifdef REG_DEBUG
+static void dumpcolors(struct colormap *, FILE *);
+static void fillcheck(struct colormap *, union tree *, int, FILE *);
+static void dumpchr(pchr, FILE *);
+#endif
+/* === regc_nfa.c === */
+static struct nfa *newnfa(struct vars *, struct colormap *, struct nfa *);
+static void freenfa(struct nfa *);
+static struct state *newstate(struct nfa *);
+static struct state *newfstate(struct nfa *, int flag);
+static void dropstate(struct nfa *, struct state *);
+static void freestate(struct nfa *, struct state *);
+static void destroystate(struct nfa *, struct state *);
+static void newarc(struct nfa *, int, pcolor, struct state *, struct state *);
+static void createarc(struct nfa *, int, pcolor, struct state *, struct state *);
+static struct arc *allocarc(struct nfa *, struct state *);
+static void freearc(struct nfa *, struct arc *);
+static void changearctarget(struct arc *, struct state *);
+static int hasnonemptyout(struct state *);
+static struct arc *findarc(struct state *, int, pcolor);
+static void cparc(struct nfa *, struct arc *, struct state *, struct state *);
+static void sortins(struct nfa *, struct state *);
+static int sortins_cmp(const void *, const void *);
+static void sortouts(struct nfa *, struct state *);
+static int sortouts_cmp(const void *, const void *);
+static void moveins(struct nfa *, struct state *, struct state *);
+static void copyins(struct nfa *, struct state *, struct state *);
+static void mergeins(struct nfa *, struct state *, struct arc **, int);
+static void moveouts(struct nfa *, struct state *, struct state *);
+static void copyouts(struct nfa *, struct state *, struct state *);
+static void cloneouts(struct nfa *, struct state *, struct state *, struct state *, int);
+static void delsub(struct nfa *, struct state *, struct state *);
+static void deltraverse(struct nfa *, struct state *, struct state *);
+static void dupnfa(struct nfa *, struct state *, struct state *, struct state *, struct state *);
+static void duptraverse(struct nfa *, struct state *, struct state *, int);
+static void cleartraverse(struct nfa *, struct state *);
+static void specialcolors(struct nfa *);
+static long optimize(struct nfa *, FILE *);
+static void pullback(struct nfa *, FILE *);
+static int pull(struct nfa *, struct arc *, struct state **);
+static void pushfwd(struct nfa *, FILE *);
+static int push(struct nfa *, struct arc *, struct state **);
+#define	INCOMPATIBLE	1	/* destroys arc */
+#define	SATISFIED	2	/* constraint satisfied */
+#define	COMPATIBLE	3	/* compatible but not satisfied yet */
+static int combine(struct arc *, struct arc *);
+static void fixempties(struct nfa *, FILE *);
+static struct state *emptyreachable(struct nfa *, struct state *,
+			struct state *, struct arc **);
+static int	isconstraintarc(struct arc *);
+static int	hasconstraintout(struct state *);
+static void fixconstraintloops(struct nfa *, FILE *);
+static int	findconstraintloop(struct nfa *, struct state *);
+static void breakconstraintloop(struct nfa *, struct state *);
+static void clonesuccessorstates(struct nfa *, struct state *, struct state *,
+		 struct state *, struct arc *, char *, char *, int);
+static void cleanup(struct nfa *);
+static void markreachable(struct nfa *, struct state *, struct state *, struct state *);
+static void markcanreach(struct nfa *, struct state *, struct state *, struct state *);
+static long analyze(struct nfa *);
+static void compact(struct nfa *, struct cnfa *);
+static void carcsort(struct carc *, size_t);
+static int carc_cmp(const void *, const void *);
+static void freecnfa(struct cnfa *);
+static void dumpnfa(struct nfa *, FILE *);
+#ifdef REG_DEBUG
+static void dumpstate(struct state *, FILE *);
+static void dumparcs(struct state *, FILE *);
+static void dumparc(struct arc *, struct state *, FILE *);
+#endif
+static void dumpcnfa(struct cnfa *, FILE *);
+#ifdef REG_DEBUG
+static void dumpcstate(int, struct cnfa *, FILE *);
+#endif
+/* === regc_cvec.c === */
+static struct cvec *clearcvec(struct cvec *);
+static void addchr(struct cvec *, pchr);
+static void addrange(struct cvec *, pchr, pchr);
+static struct cvec *newcvec(int, int);
+static struct cvec *getcvec(struct vars *, int, int);
+static void freecvec(struct cvec *);
+/* === regc_locale.c === */
+static celt element(struct vars *, const chr *, const chr *);
+static struct cvec *range(struct vars *, celt, celt, int);
+static int before(celt, celt);
+static struct cvec *eclass(struct vars *, celt, int);
+static struct cvec *cclass(struct vars *, const chr *, const chr *, int);
+static struct cvec *allcases(struct vars *, pchr);
+static int cmp(const chr *, const chr *, size_t);
+static int casecmp(const chr *, const chr *, size_t);
+/* automatically gathered by fwd; do not hand-edit */
+/* =====^!^===== end forwards =====^!^===== */
+
+/* internal variables, bundled for easy passing around */
+struct vars {
+    regex_t *re;
+    const chr *now;		/* scan pointer into string */
+    const chr *stop;		/* end of string */
+    const chr *savenow;		/* saved now and stop for "subroutine call" */
+    const chr *savestop;
+    int err;			/* error code (0 if none) */
+    int cflags;			/* copy of compile flags */
+    int lasttype;		/* type of previous token */
+    int nexttype;		/* type of next token */
+    chr nextvalue;		/* value (if any) of next token */
+    int lexcon;			/* lexical context type (see lex.c) */
+    int nsubexp;		/* subexpression count */
+    struct subre **subs;	/* subRE pointer vector */
+    size_t nsubs;		/* length of vector */
+    struct subre *sub10[10];	/* initial vector, enough for most */
+    struct nfa *nfa;		/* the NFA */
+    struct colormap *cm;	/* character color map */
+    color nlcolor;		/* color of newline */
+    struct state *wordchrs;	/* state in nfa holding word-char outarcs */
+    struct subre *tree;		/* subexpression tree */
+    struct subre *treechain;	/* all tree nodes allocated */
+    struct subre *treefree;	/* any free tree nodes */
+    int ntree;			/* number of tree nodes, plus one */
+    struct cvec *cv;		/* interface cvec */
+    struct cvec *cv2;		/* utility cvec */
+    struct subre *lacons;	/* lookahead-constraint vector */
+    int nlacons;		/* size of lacons */
+    size_t spaceused;		/* approx. space used for compilation */
+};
+
+/* parsing macros; most know that `v' is the struct vars pointer */
+#define	NEXT()	(next(v))		/* advance by one token */
+#define	SEE(t)	(v->nexttype == (t))	/* is next token this? */
+#define	EAT(t)	(SEE(t) && next(v))	/* if next is this, swallow it */
+#define	VISERR(vv)	((vv)->err != 0)/* have we seen an error yet? */
+#define	ISERR()	VISERR(v)
+#define VERR(vv,e)	((vv)->nexttype = EOS, \
+			 (vv)->err = ((vv)->err ? (vv)->err : (e)))
+#define	ERR(e)	VERR(v, e)		/* record an error */
+#define	NOERR()	{if (ISERR()) return;}	/* if error seen, return */
+#define	NOERRN()	{if (ISERR()) return NULL;}	/* NOERR with retval */
+#define	NOERRZ()	{if (ISERR()) return 0;}	/* NOERR with retval */
+#define INSIST(c, e) do { if (!(c)) ERR(e); } while (0)	/* error if c false */
+#define	NOTE(b)	(v->re->re_info |= (b))		/* note visible condition */
+#define	EMPTYARC(x, y)	newarc(v->nfa, EMPTY, 0, x, y)
+
+/* token type codes, some also used as NFA arc types */
+#define	EMPTY	'n'		/* no token present */
+#define	EOS	'e'		/* end of string */
+#define	PLAIN	'p'		/* ordinary character */
+#define	DIGIT	'd'		/* digit (in bound) */
+#define	BACKREF	'b'		/* back reference */
+#define	COLLEL	'I'		/* start of [. */
+#define	ECLASS	'E'		/* start of [= */
+#define	CCLASS	'C'		/* start of [: */
+#define	END	'X'		/* end of [. [= [: */
+#define	RANGE	'R'		/* - within [] which might be range delim. */
+#define	LACON	'L'		/* lookahead constraint subRE */
+#define	AHEAD	'a'		/* color-lookahead arc */
+#define	BEHIND	'r'		/* color-lookbehind arc */
+#define	WBDRY	'w'		/* word boundary constraint */
+#define	NWBDRY	'W'		/* non-word-boundary constraint */
+#define	SBEGIN	'A'		/* beginning of string (even if not BOL) */
+#define	SEND	'Z'		/* end of string (even if not EOL) */
+#define	PREFER	'P'		/* length preference */
+
+/* is an arc colored, and hence on a color chain? */
+#define	COLORED(a) \
+	((a)->type == PLAIN || (a)->type == AHEAD || (a)->type == BEHIND)
+
+/* static function list */
+static const struct fns functions = {
+    rfree,			/* regfree insides */
+};
+
+/*
+ - compile - compile regular expression
+ * Note: on failure, no resources remain allocated, so regfree()
+ * need not be applied to re.
+ ^ int compile(regex_t *, const chr *, size_t, int);
+ */
+int
+compile(
+    regex_t *re,
+    const chr *string,
+    size_t len,
+    int flags)
+{
+    AllocVars(v);
+    struct guts *g;
+    int i;
+    size_t j;
+    FILE *debug = (flags&REG_PROGRESS) ? stdout : NULL;
+#define	CNOERR()	{ if (ISERR()) return freev(v, v->err); }
+
+    /*
+     * Sanity checks.
+     */
+
+    if (re == NULL || string == NULL) {
+	FreeVars(v);
+	return REG_INVARG;
+    }
+    if ((flags&REG_QUOTE) && (flags&(REG_ADVANCED|REG_EXPANDED|REG_NEWLINE))) {
+	FreeVars(v);
+	return REG_INVARG;
+    }
+    if (!(flags&REG_EXTENDED) && (flags&REG_ADVF)) {
+	FreeVars(v);
+	return REG_INVARG;
+    }
+
+    /*
+     * Initial setup (after which freev() is callable).
+     */
+
+    v->re = re;
+    v->now = string;
+    v->stop = v->now + len;
+    v->savenow = v->savestop = NULL;
+    v->err = 0;
+    v->cflags = flags;
+    v->nsubexp = 0;
+    v->subs = v->sub10;
+    v->nsubs = 10;
+    for (j = 0; j < v->nsubs; j++) {
+	v->subs[j] = NULL;
+    }
+    v->nfa = NULL;
+    v->cm = NULL;
+    v->nlcolor = COLORLESS;
+    v->wordchrs = NULL;
+    v->tree = NULL;
+    v->treechain = NULL;
+    v->treefree = NULL;
+    v->cv = NULL;
+    v->cv2 = NULL;
+    v->lacons = NULL;
+    v->nlacons = 0;
+    v->spaceused = 0;
+    re->re_magic = REMAGIC;
+    re->re_info = 0;		/* bits get set during parse */
+    re->re_csize = sizeof(chr);
+    re->re_guts = NULL;
+    re->re_fns = VS(&functions);
+
+    /*
+     * More complex setup, malloced things.
+     */
+
+    re->re_guts = VS(MALLOC(sizeof(struct guts)));
+    if (re->re_guts == NULL) {
+	return freev(v, REG_ESPACE);
+    }
+    g = (struct guts *) re->re_guts;
+    g->tree = NULL;
+    initcm(v, &g->cmap);
+    v->cm = &g->cmap;
+    g->lacons = NULL;
+    g->nlacons = 0;
+    ZAPCNFA(g->search);
+    v->nfa = newnfa(v, v->cm, NULL);
+    CNOERR();
+    v->cv = newcvec(100, 20);
+    if (v->cv == NULL) {
+	return freev(v, REG_ESPACE);
+    }
+
+    /*
+     * Parsing.
+     */
+
+    lexstart(v);		/* also handles prefixes */
+    if ((v->cflags&REG_NLSTOP) || (v->cflags&REG_NLANCH)) {
+	/*
+	 * Assign newline a unique color.
+	 */
+
+	v->nlcolor = subcolor(v->cm, newline());
+	okcolors(v->nfa, v->cm);
+    }
+    CNOERR();
+    v->tree = parse(v, EOS, PLAIN, v->nfa->init, v->nfa->final);
+    assert(SEE(EOS));		/* even if error; ISERR() => SEE(EOS) */
+    CNOERR();
+    assert(v->tree != NULL);
+
+    /*
+     * Finish setup of nfa and its subre tree.
+     */
+
+    specialcolors(v->nfa);
+    CNOERR();
+    if (debug != NULL) {
+	fprintf(debug, "\n\n\n========= RAW ==========\n");
+	dumpnfa(v->nfa, debug);
+	dumpst(v->tree, debug, 1);
+    }
+    optst(v, v->tree);
+    v->ntree = numst(v->tree, 1);
+    markst(v->tree);
+    cleanst(v);
+    if (debug != NULL) {
+	fprintf(debug, "\n\n\n========= TREE FIXED ==========\n");
+	dumpst(v->tree, debug, 1);
+    }
+
+    /*
+     * Build compacted NFAs for tree and lacons.
+     */
+
+    re->re_info |= nfatree(v, v->tree, debug);
+    CNOERR();
+    assert(v->nlacons == 0 || v->lacons != NULL);
+    for (i = 1; i < v->nlacons; i++) {
+	if (debug != NULL) {
+	    fprintf(debug, "\n\n\n========= LA%d ==========\n", i);
+	}
+	nfanode(v, &v->lacons[i], debug);
+    }
+    CNOERR();
+    if (v->tree->flags&SHORTER) {
+	NOTE(REG_USHORTEST);
+    }
+
+    /*
+     * Build compacted NFAs for tree, lacons, fast search.
+     */
+
+    if (debug != NULL) {
+	fprintf(debug, "\n\n\n========= SEARCH ==========\n");
+    }
+
+    /*
+     * Can sacrifice main NFA now, so use it as work area.
+     */
+
+    (DISCARD) optimize(v->nfa, debug);
+    CNOERR();
+    makesearch(v, v->nfa);
+    CNOERR();
+    compact(v->nfa, &g->search);
+    CNOERR();
+
+    /*
+     * Looks okay, package it up.
+     */
+
+    re->re_nsub = v->nsubexp;
+    v->re = NULL;		/* freev no longer frees re */
+    g->magic = GUTSMAGIC;
+    g->cflags = v->cflags;
+    g->info = re->re_info;
+    g->nsub = re->re_nsub;
+    g->tree = v->tree;
+    v->tree = NULL;
+    g->ntree = v->ntree;
+    g->compare = (v->cflags&REG_ICASE) ? casecmp : cmp;
+    g->lacons = v->lacons;
+    v->lacons = NULL;
+    g->nlacons = v->nlacons;
+
+    if (flags&REG_DUMP) {
+	dump(re, stdout);
+    }
+
+    assert(v->err == 0);
+    return freev(v, 0);
+}
+
+/*
+ - moresubs - enlarge subRE vector
+ ^ static void moresubs(struct vars *, int);
+ */
+static void
+moresubs(
+    struct vars *v,
+    int wanted)			/* want enough room for this one */
+{
+    struct subre **p;
+    size_t n;
+
+    assert(wanted > 0 && (size_t)wanted >= v->nsubs);
+    n = (size_t)wanted * 3 / 2 + 1;
+    if (v->subs == v->sub10) {
+	p = (struct subre **) MALLOC(n * sizeof(struct subre *));
+	if (p != NULL) {
+	    memcpy(p, v->subs, v->nsubs * sizeof(struct subre *));
+	}
+    } else {
+	p = (struct subre **) REALLOC(v->subs, n*sizeof(struct subre *));
+    }
+    if (p == NULL) {
+	ERR(REG_ESPACE);
+	return;
+    }
+
+    v->subs = p;
+    for (p = &v->subs[v->nsubs]; v->nsubs < n; p++, v->nsubs++) {
+	*p = NULL;
+    }
+    assert(v->nsubs == n);
+    assert((size_t)wanted < v->nsubs);
+}
+
+/*
+ - freev - free vars struct's substructures where necessary
+ * Optionally does error-number setting, and always returns error code (if
+ * any), to make error-handling code terser.
+ ^ static int freev(struct vars *, int);
+ */
+static int
+freev(
+    struct vars *v,
+    int err)
+{
+    register int ret;
+
+    if (v->re != NULL) {
+	rfree(v->re);
+    }
+    if (v->subs != v->sub10) {
+	FREE(v->subs);
+    }
+    if (v->nfa != NULL) {
+	freenfa(v->nfa);
+    }
+    if (v->tree != NULL) {
+	freesubre(v, v->tree);
+    }
+    if (v->treechain != NULL) {
+	cleanst(v);
+    }
+    if (v->cv != NULL) {
+	freecvec(v->cv);
+    }
+    if (v->cv2 != NULL) {
+	freecvec(v->cv2);
+    }
+    if (v->lacons != NULL) {
+	freelacons(v->lacons, v->nlacons);
+    }
+    ERR(err);			/* nop if err==0 */
+
+    ret = v->err;
+    FreeVars(v);
+    return ret;
+}
+
+/*
+ - makesearch - turn an NFA into a search NFA (implicit prepend of .*?)
+ * NFA must have been optimize()d already.
+ ^ static void makesearch(struct vars *, struct nfa *);
+ */
+static void
+makesearch(
+    struct vars *v,
+    struct nfa *nfa)
+{
+    struct arc *a, *b;
+    struct state *pre = nfa->pre;
+    struct state *s, *s2, *slist;
+
+    /*
+     * No loops are needed if it's anchored.
+     */
+
+    for (a = pre->outs; a != NULL; a = a->outchain) {
+	assert(a->type == PLAIN);
+	if (a->co != nfa->bos[0] && a->co != nfa->bos[1]) {
+	    break;
+	}
+    }
+    if (a != NULL) {
+	/*
+	 * Add implicit .* in front.
+	 */
+
+	rainbow(nfa, v->cm, PLAIN, COLORLESS, pre, pre);
+
+	/*
+	 * And ^* and \A* too -- not always necessary, but harmless.
+	 */
+
+	newarc(nfa, PLAIN, nfa->bos[0], pre, pre);
+	newarc(nfa, PLAIN, nfa->bos[1], pre, pre);
+    }
+
+    /*
+     * Now here's the subtle part. Because many REs have no lookback
+     * constraints, often knowing when you were in the pre state tells you
+     * little; it's the next state(s) that are informative. But some of them
+     * may have other inarcs, i.e. it may be possible to make actual progress
+     * and then return to one of them. We must de-optimize such cases,
+     * splitting each such state into progress and no-progress states.
+     */
+
+    /*
+     * First, make a list of the states.
+     */
+
+    slist = NULL;
+    for (a=pre->outs ; a!=NULL ; a=a->outchain) {
+	s = a->to;
+	for (b=s->ins ; b!=NULL ; b=b->inchain) {
+	    if (b->from != pre) {
+		break;
+	    }
+	}
+
+	/*
+	 * We want to mark states as being in the list already by having non
+	 * NULL tmp fields, but we can't just store the old slist value in tmp
+	 * because that doesn't work for the first such state.  Instead, the
+	 * first list entry gets its own address in tmp.
+	 */
+	if (b != NULL && s->tmp == NULL) {
+	    s->tmp = (slist != NULL) ? slist : s;
+	    slist = s;
+	}
+    }
+
+    /*
+     * Do the splits.
+     */
+
+    for (s=slist ; s!=NULL ; s=s2) {
+	s2 = newstate(nfa);
+	NOERR();
+	copyouts(nfa, s, s2);
+	NOERR();
+	for (a=s->ins ; a!=NULL ; a=b) {
+	    b = a->inchain;
+
+	    if (a->from != pre) {
+		cparc(nfa, a, a->from, s2);
+		freearc(nfa, a);
+	    }
+	}
+	s2 = (s->tmp != s) ? s->tmp : NULL;
+	s->tmp = NULL;		/* clean up while we're at it */
+    }
+}
+
+/*
+ - parse - parse an RE
+ * This is actually just the top level, which parses a bunch of branches tied
+ * together with '|'. They appear in the tree as the left children of a chain
+ * of '|' subres.
+ ^ static struct subre *parse(struct vars *, int, int, struct state *,
+ ^ 	struct state *);
+ */
+static struct subre *
+parse(
+    struct vars *v,
+    int stopper,		/* EOS or ')' */
+    int type,			/* LACON (lookahead subRE) or PLAIN */
+    struct state *init,		/* initial state */
+    struct state *final)	/* final state */
+{
+    struct state *left, *right;	/* scaffolding for branch */
+    struct subre *branches;	/* top level */
+    struct subre *branch;	/* current branch */
+    struct subre *t;		/* temporary */
+    int firstbranch;		/* is this the first branch? */
+
+    assert(stopper == ')' || stopper == EOS);
+
+    branches = subre(v, '|', LONGER, init, final);
+    NOERRN();
+    branch = branches;
+    firstbranch = 1;
+    do {	/* a branch */
+	if (!firstbranch) {
+	    /*
+	     * Need a place to hang the branch.
+	     */
+
+	    branch->right = subre(v, '|', LONGER, init, final);
+	    NOERRN();
+	    branch = branch->right;
+	}
+	firstbranch = 0;
+	left = newstate(v->nfa);
+	right = newstate(v->nfa);
+	NOERRN();
+	EMPTYARC(init, left);
+	EMPTYARC(right, final);
+	NOERRN();
+	branch->left = parsebranch(v, stopper, type, left, right, 0);
+	NOERRN();
+	branch->flags |= UP(branch->flags | branch->left->flags);
+	if ((branch->flags &~ branches->flags) != 0) {	/* new flags */
+	    for (t = branches; t != branch; t = t->right) {
+		t->flags |= branch->flags;
+	    }
+	}
+    } while (EAT('|'));
+    assert(SEE(stopper) || SEE(EOS));
+
+    if (!SEE(stopper)) {
+	assert(stopper == ')' && SEE(EOS));
+	ERR(REG_EPAREN);
+    }
+
+    /*
+     * Optimize out simple cases.
+     */
+
+    if (branch == branches) {	/* only one branch */
+	assert(branch->right == NULL);
+	t = branch->left;
+	branch->left = NULL;
+	freesubre(v, branches);
+	branches = t;
+    } else if (!MESSY(branches->flags)) {	/* no interesting innards */
+	freesubre(v, branches->left);
+	branches->left = NULL;
+	freesubre(v, branches->right);
+	branches->right = NULL;
+	branches->op = '=';
+    }
+
+    return branches;
+}
+
+/*
+ - parsebranch - parse one branch of an RE
+ * This mostly manages concatenation, working closely with parseqatom().
+ * Concatenated things are bundled up as much as possible, with separate
+ * ',' nodes introduced only when necessary due to substructure.
+ ^ static struct subre *parsebranch(struct vars *, int, int, struct state *,
+ ^ 	struct state *, int);
+ */
+static struct subre *
+parsebranch(
+    struct vars *v,
+    int stopper,		/* EOS or ')' */
+    int type,			/* LACON (lookahead subRE) or PLAIN */
+    struct state *left,		/* leftmost state */
+    struct state *right,	/* rightmost state */
+    int partial)		/* is this only part of a branch? */
+{
+    struct state *lp;		/* left end of current construct */
+    int seencontent;		/* is there anything in this branch yet? */
+    struct subre *t;
+
+    lp = left;
+    seencontent = 0;
+    t = subre(v, '=', 0, left, right);	/* op '=' is tentative */
+    NOERRN();
+    while (!SEE('|') && !SEE(stopper) && !SEE(EOS)) {
+	if (seencontent) {	/* implicit concat operator */
+	    lp = newstate(v->nfa);
+	    NOERRN();
+	    moveins(v->nfa, right, lp);
+	}
+	seencontent = 1;
+
+	/* NB, recursion in parseqatom() may swallow rest of branch */
+	parseqatom(v, stopper, type, lp, right, t);
+	NOERRN();
+    }
+
+    if (!seencontent) {		/* empty branch */
+	if (!partial) {
+	    NOTE(REG_UUNSPEC);
+	}
+	assert(lp == left);
+	EMPTYARC(left, right);
+    }
+
+    return t;
+}
+
+/*
+ - parseqatom - parse one quantified atom or constraint of an RE
+ * The bookkeeping near the end cooperates very closely with parsebranch(); in
+ * particular, it contains a recursion that can involve parsing the rest of
+ * the branch, making this function's name somewhat inaccurate.
+ ^ static void parseqatom(struct vars *, int, int, struct state *,
+ ^ 	struct state *, struct subre *);
+ */
+static void
+parseqatom(
+    struct vars *v,
+    int stopper,		/* EOS or ')' */
+    int type,			/* LACON (lookahead subRE) or PLAIN */
+    struct state *lp,		/* left state to hang it on */
+    struct state *rp,		/* right state to hang it on */
+    struct subre *top)		/* subtree top */
+{
+    struct state *s;		/* temporaries for new states */
+    struct state *s2;
+#define	ARCV(t, val)	newarc(v->nfa, t, val, lp, rp)
+    int m, n;
+    struct subre *atom;		/* atom's subtree */
+    struct subre *t;
+    int cap;			/* capturing parens? */
+    int pos;			/* positive lookahead? */
+    int subno;			/* capturing-parens or backref number */
+    int atomtype;
+    int qprefer;		/* quantifier short/long preference */
+    int f;
+    struct subre **atomp;	/* where the pointer to atom is */
+
+    /*
+     * Initial bookkeeping.
+     */
+
+    atom = NULL;
+    assert(lp->nouts == 0);	/* must string new code */
+    assert(rp->nins == 0);	/* between lp and rp */
+    subno = 0;			/* just to shut lint up */
+
+    /*
+     * An atom or constraint...
+     */
+
+    atomtype = v->nexttype;
+    switch (atomtype) {
+	/* first, constraints, which end by returning */
+    case '^':
+	ARCV('^', 1);
+	if (v->cflags&REG_NLANCH) {
+	    ARCV(BEHIND, v->nlcolor);
+	}
+	NEXT();
+	return;
+    case '$':
+	ARCV('$', 1);
+	if (v->cflags&REG_NLANCH) {
+	    ARCV(AHEAD, v->nlcolor);
+	}
+	NEXT();
+	return;
+    case SBEGIN:
+	ARCV('^', 1);		/* BOL */
+	ARCV('^', 0);		/* or BOS */
+	NEXT();
+	return;
+    case SEND:
+	ARCV('$', 1);		/* EOL */
+	ARCV('$', 0);		/* or EOS */
+	NEXT();
+	return;
+    case '<':
+	wordchrs(v);		/* does NEXT() */
+	s = newstate(v->nfa);
+	NOERR();
+	nonword(v, BEHIND, lp, s);
+	word(v, AHEAD, s, rp);
+	return;
+    case '>':
+	wordchrs(v);		/* does NEXT() */
+	s = newstate(v->nfa);
+	NOERR();
+	word(v, BEHIND, lp, s);
+	nonword(v, AHEAD, s, rp);
+	return;
+    case WBDRY:
+	wordchrs(v);		/* does NEXT() */
+	s = newstate(v->nfa);
+	NOERR();
+	nonword(v, BEHIND, lp, s);
+	word(v, AHEAD, s, rp);
+	s = newstate(v->nfa);
+	NOERR();
+	word(v, BEHIND, lp, s);
+	nonword(v, AHEAD, s, rp);
+	return;
+    case NWBDRY:
+	wordchrs(v);		/* does NEXT() */
+	s = newstate(v->nfa);
+	NOERR();
+	word(v, BEHIND, lp, s);
+	word(v, AHEAD, s, rp);
+	s = newstate(v->nfa);
+	NOERR();
+	nonword(v, BEHIND, lp, s);
+	nonword(v, AHEAD, s, rp);
+	return;
+    case LACON:			/* lookahead constraint */
+	pos = v->nextvalue;
+	NEXT();
+	s = newstate(v->nfa);
+	s2 = newstate(v->nfa);
+	NOERR();
+	t = parse(v, ')', LACON, s, s2);
+	freesubre(v, t);	/* internal structure irrelevant */
+	assert(SEE(')') || ISERR());
+	NEXT();
+	n = newlacon(v, s, s2, pos);
+	NOERR();
+	ARCV(LACON, n);
+	return;
+
+	/*
+	 * Then errors, to get them out of the way.
+	 */
+
+    case '*':
+    case '+':
+    case '?':
+    case '{':
+	ERR(REG_BADRPT);
+	return;
+    default:
+	ERR(REG_ASSERT);
+	return;
+
+	/*
+	 * Then plain characters, and minor variants on that theme.
+	 */
+
+    case ')':			/* unbalanced paren */
+	if ((v->cflags&REG_ADVANCED) != REG_EXTENDED) {
+	    ERR(REG_EPAREN);
+	    return;
+	}
+
+	/*
+	 * Legal in EREs due to specification botch.
+	 */
+
+	NOTE(REG_UPBOTCH);
+	/* fallthrough into case PLAIN */
+    case PLAIN:
+	onechr(v, v->nextvalue, lp, rp);
+	okcolors(v->nfa, v->cm);
+	NOERR();
+	NEXT();
+	break;
+    case '[':
+	if (v->nextvalue == 1) {
+	    bracket(v, lp, rp);
+	} else {
+	    cbracket(v, lp, rp);
+	}
+	assert(SEE(']') || ISERR());
+	NEXT();
+	break;
+    case '.':
+	rainbow(v->nfa, v->cm, PLAIN,
+		(v->cflags&REG_NLSTOP) ? v->nlcolor : COLORLESS, lp, rp);
+	NEXT();
+	break;
+
+	/*
+	 * And finally the ugly stuff.
+	 */
+
+    case '(':			/* value flags as capturing or non */
+	cap = (type == LACON) ? 0 : v->nextvalue;
+	if (cap) {
+	    v->nsubexp++;
+	    subno = v->nsubexp;
+	    if ((size_t)subno >= v->nsubs) {
+		moresubs(v, subno);
+	    }
+	    assert((size_t)subno < v->nsubs);
+	} else {
+	    atomtype = PLAIN;	/* something that's not '(' */
+	}
+	NEXT();
+
+	/*
+	 * Need new endpoints because tree will contain pointers.
+	 */
+
+	s = newstate(v->nfa);
+	s2 = newstate(v->nfa);
+	NOERR();
+	EMPTYARC(lp, s);
+	EMPTYARC(s2, rp);
+	NOERR();
+	atom = parse(v, ')', PLAIN, s, s2);
+	assert(SEE(')') || ISERR());
+	NEXT();
+	NOERR();
+	if (cap) {
+	    v->subs[subno] = atom;
+	    t = subre(v, '(', atom->flags|CAP, lp, rp);
+	    NOERR();
+	    t->subno = subno;
+	    t->left = atom;
+	    atom = t;
+	}
+
+	/*
+	 * Postpone everything else pending possible {0}.
+	 */
+
+	break;
+    case BACKREF:		/* the Feature From The Black Lagoon */
+	INSIST(type != LACON, REG_ESUBREG);
+	INSIST(v->nextvalue < v->nsubs, REG_ESUBREG);
+	INSIST(v->subs[v->nextvalue] != NULL, REG_ESUBREG);
+	NOERR();
+	assert(v->nextvalue > 0);
+	atom = subre(v, 'b', BACKR, lp, rp);
+	NOERR();
+	subno = v->nextvalue;
+	atom->subno = subno;
+	EMPTYARC(lp, rp);	/* temporarily, so there's something */
+	NEXT();
+	break;
+    }
+
+    /*
+     * ...and an atom may be followed by a quantifier.
+     */
+
+    switch (v->nexttype) {
+    case '*':
+	m = 0;
+	n = DUPINF;
+	qprefer = (v->nextvalue) ? LONGER : SHORTER;
+	NEXT();
+	break;
+    case '+':
+	m = 1;
+	n = DUPINF;
+	qprefer = (v->nextvalue) ? LONGER : SHORTER;
+	NEXT();
+	break;
+    case '?':
+	m = 0;
+	n = 1;
+	qprefer = (v->nextvalue) ? LONGER : SHORTER;
+	NEXT();
+	break;
+    case '{':
+	NEXT();
+	m = scannum(v);
+	if (EAT(',')) {
+	    if (SEE(DIGIT)) {
+		n = scannum(v);
+	    } else {
+		n = DUPINF;
+	    }
+	    if (m > n) {
+		ERR(REG_BADBR);
+		return;
+	    }
+
+	    /*
+	     * {m,n} exercises preference, even if it's {m,m}
+	     */
+
+	    qprefer = (v->nextvalue) ? LONGER : SHORTER;
+	} else {
+	    n = m;
+	    /*
+	     * {m} passes operand's preference through.
+	     */
+
+	    qprefer = 0;
+	}
+	if (!SEE('}')) {	/* catches errors too */
+	    ERR(REG_BADBR);
+	    return;
+	}
+	NEXT();
+	break;
+    default:			/* no quantifier */
+	m = n = 1;
+	qprefer = 0;
+	break;
+    }
+
+    /*
+     * Annoying special case: {0} or {0,0} cancels everything.
+     */
+
+    if (m == 0 && n == 0) {
+	if (atom != NULL) {
+	    freesubre(v, atom);
+	}
+	if (atomtype == '(') {
+	    v->subs[subno] = NULL;
+	}
+	delsub(v->nfa, lp, rp);
+	EMPTYARC(lp, rp);
+	return;
+    }
+
+    /*
+     * If not a messy case, avoid hard part.
+     */
+
+    assert(!MESSY(top->flags));
+    f = top->flags | qprefer | ((atom != NULL) ? atom->flags : 0);
+    if (atomtype != '(' && atomtype != BACKREF && !MESSY(UP(f))) {
+	if (!(m == 1 && n == 1)) {
+	    repeat(v, lp, rp, m, n);
+	}
+	if (atom != NULL) {
+	    freesubre(v, atom);
+	}
+	top->flags = f;
+	return;
+    }
+
+    /*
+     * hard part: something messy
+     * That is, capturing parens, back reference, short/long clash, or an atom
+     * with substructure containing one of those.
+     */
+
+    /*
+     * Now we'll need a subre for the contents even if they're boring.
+     */
+
+    if (atom == NULL) {
+	atom = subre(v, '=', 0, lp, rp);
+	NOERR();
+    }
+
+    /*
+     * Prepare a general-purpose state skeleton.
+     *
+     * In the no-backrefs case, we want this:
+     *
+     * [lp] ---> [s] ---prefix---> [begin] ---atom---> [end] ---rest---> [rp]
+     *
+     * where prefix is some repetitions of atom.  In the general case we need
+     *
+     * [lp] ---> [s] ---iterator---> [s2] ---rest---> [rp]
+     *
+     * where the iterator wraps around [begin] ---atom---> [end]
+     *
+     * We make the s state here for both cases; s2 is made below if needed
+     */
+
+    s = newstate(v->nfa);	/* first, new endpoints for the atom */
+    s2 = newstate(v->nfa);
+    NOERR();
+    moveouts(v->nfa, lp, s);
+    moveins(v->nfa, rp, s2);
+    NOERR();
+    atom->begin = s;
+    atom->end = s2;
+    s = newstate(v->nfa);	/* set up starting state */
+    NOERR();
+    EMPTYARC(lp, s);
+    NOERR();
+
+    /*
+     * Break remaining subRE into x{...} and what follows.
+     */
+
+    t = subre(v, '.', COMBINE(qprefer, atom->flags), lp, rp);
+    NOERR();
+    t->left = atom;
+    atomp = &t->left;
+
+    /*
+     * Here we should recurse... but we must postpone that to the end.
+     */
+
+    /*
+     * Split top into prefix and remaining.
+     */
+
+    assert(top->op == '=' && top->left == NULL && top->right == NULL);
+    top->left = subre(v, '=', top->flags, top->begin, lp);
+    NOERR();
+    top->op = '.';
+    top->right = t;
+
+    /*
+     * If it's a backref, now is the time to replicate the subNFA.
+     */
+
+    if (atomtype == BACKREF) {
+	assert(atom->begin->nouts == 1);	/* just the EMPTY */
+	delsub(v->nfa, atom->begin, atom->end);
+	assert(v->subs[subno] != NULL);
+
+	/*
+	 * And here's why the recursion got postponed: it must wait until the
+	 * skeleton is filled in, because it may hit a backref that wants to
+	 * copy the filled-in skeleton.
+	 */
+
+	dupnfa(v->nfa, v->subs[subno]->begin, v->subs[subno]->end,
+		atom->begin, atom->end);
+	NOERR();
+    }
+
+    /*
+     * It's quantifier time.  If the atom is just a backref, we'll let it deal
+     * with quantifiers internally.
+     */
+
+    if (atomtype == BACKREF) {
+	/*
+	 * Special case: backrefs have internal quantifiers.
+	 */
+
+	EMPTYARC(s, atom->begin);	/* empty prefix */
+
+	/*
+	 * Just stuff everything into atom.
+	 */
+
+	repeat(v, atom->begin, atom->end, m, n);
+	atom->min = (short) m;
+	atom->max = (short) n;
+	atom->flags |= COMBINE(qprefer, atom->flags);
+	/* rest of branch can be strung starting from atom->end */
+	s2 = atom->end;
+    } else if (m == 1 && n == 1) {
+	/*
+	 * No/vacuous quantifier: done.
+	 */
+
+	EMPTYARC(s, atom->begin);	/* empty prefix */
+	/* rest of branch can be strung starting from atom->end */
+	s2 = atom->end;
+    } else if (m > 0 && !(atom->flags & BACKR)) {
+	/*
+	 * If there's no backrefs involved, we can turn x{m,n} into
+	 * x{m-1,n-1}x, with capturing parens in only the second x.  This
+	 * is valid because we only care about capturing matches from the
+	 * final iteration of the quantifier.  It's a win because we can
+	 * implement the backref-free left side as a plain DFA node, since
+	 * we don't really care where its submatches are.
+	 */
+
+	dupnfa(v->nfa, atom->begin, atom->end, s, atom->begin);
+	assert(m >= 1 && m != DUPINF && n >= 1);
+	repeat(v, s, atom->begin, m-1, (n == DUPINF) ? n : n-1);
+	f = COMBINE(qprefer, atom->flags);
+	t = subre(v, '.', f, s, atom->end);	/* prefix and atom */
+	NOERR();
+	t->left = subre(v, '=', PREF(f), s, atom->begin);
+	NOERR();
+	t->right = atom;
+	*atomp = t;
+	/* rest of branch can be strung starting from atom->end */
+	s2 = atom->end;
+    } else {
+	/* general case: need an iteration node */
+	s2 = newstate(v->nfa);
+	NOERR();
+	moveouts(v->nfa, atom->end, s2);
+	NOERR();
+	dupnfa(v->nfa, atom->begin, atom->end, s, s2);
+	repeat(v, s, s2, m, n);
+	f = COMBINE(qprefer, atom->flags);
+	t = subre(v, '*', f, s, s2);
+	NOERR();
+	t->min = (short) m;
+	t->max = (short) n;
+	t->left = atom;
+	*atomp = t;
+	/* rest of branch is to be strung from iteration's end state */
+    }
+
+    /*
+     * And finally, look after that postponed recursion.
+     */
+
+    t = top->right;
+    if (!(SEE('|') || SEE(stopper) || SEE(EOS))) {
+	t->right = parsebranch(v, stopper, type, s2, rp, 1);
+    } else {
+	EMPTYARC(s2, rp);
+	t->right = subre(v, '=', 0, s2, rp);
+    }
+    NOERR();
+    assert(SEE('|') || SEE(stopper) || SEE(EOS));
+    t->flags |= COMBINE(t->flags, t->right->flags);
+    top->flags |= COMBINE(top->flags, t->flags);
+}
+
+/*
+ - nonword - generate arcs for non-word-character ahead or behind
+ ^ static void nonword(struct vars *, int, struct state *, struct state *);
+ */
+static void
+nonword(
+    struct vars *v,
+    int dir,			/* AHEAD or BEHIND */
+    struct state *lp,
+    struct state *rp)
+{
+    int anchor = (dir == AHEAD) ? '$' : '^';
+
+    assert(dir == AHEAD || dir == BEHIND);
+    newarc(v->nfa, anchor, 1, lp, rp);
+    newarc(v->nfa, anchor, 0, lp, rp);
+    colorcomplement(v->nfa, v->cm, dir, v->wordchrs, lp, rp);
+    /* (no need for special attention to \n) */
+}
+
+/*
+ - word - generate arcs for word character ahead or behind
+ ^ static void word(struct vars *, int, struct state *, struct state *);
+ */
+static void
+word(
+    struct vars *v,
+    int dir,			/* AHEAD or BEHIND */
+    struct state *lp,
+    struct state *rp)
+{
+    assert(dir == AHEAD || dir == BEHIND);
+    cloneouts(v->nfa, v->wordchrs, lp, rp, dir);
+    /* (no need for special attention to \n) */
+}
+
+/*
+ - scannum - scan a number
+ ^ static int scannum(struct vars *);
+ */
+static int			/* value, <= DUPMAX */
+scannum(
+    struct vars *v)
+{
+    int n = 0;
+
+    while (SEE(DIGIT) && n < DUPMAX) {
+	n = n*10 + v->nextvalue;
+	NEXT();
+    }
+    if (SEE(DIGIT) || n > DUPMAX) {
+	ERR(REG_BADBR);
+	return 0;
+    }
+    return n;
+}
+
+/*
+ - repeat - replicate subNFA for quantifiers
+ * The sub-NFA strung from lp to rp is modified to represent m to n
+ * repetitions of its initial contents.
+ * The duplication sequences used here are chosen carefully so that any
+ * pointers starting out pointing into the subexpression end up pointing into
+ * the last occurrence. (Note that it may not be strung between the same left
+ * and right end states, however!) This used to be important for the subRE
+ * tree, although the important bits are now handled by the in-line code in
+ * parse(), and when this is called, it doesn't matter any more.
+ ^ static void repeat(struct vars *, struct state *, struct state *, int, int);
+ */
+static void
+repeat(
+    struct vars *v,
+    struct state *lp,
+    struct state *rp,
+    int m,
+    int n)
+{
+#define	SOME		2
+#define	INF		3
+#define	PAIR(x, y)	((x)*4 + (y))
+#define	REDUCE(x)	( ((x) == DUPINF) ? INF : (((x) > 1) ? SOME : (x)) )
+    const int rm = REDUCE(m);
+    const int rn = REDUCE(n);
+    struct state *s, *s2;
+
+    switch (PAIR(rm, rn)) {
+    case PAIR(0, 0):		/* empty string */
+	delsub(v->nfa, lp, rp);
+	EMPTYARC(lp, rp);
+	break;
+    case PAIR(0, 1):		/* do as x| */
+	EMPTYARC(lp, rp);
+	break;
+    case PAIR(0, SOME):		/* do as x{1,n}| */
+	repeat(v, lp, rp, 1, n);
+	NOERR();
+	EMPTYARC(lp, rp);
+	break;
+    case PAIR(0, INF):		/* loop x around */
+	s = newstate(v->nfa);
+	NOERR();
+	moveouts(v->nfa, lp, s);
+	moveins(v->nfa, rp, s);
+	EMPTYARC(lp, s);
+	EMPTYARC(s, rp);
+	break;
+    case PAIR(1, 1):		/* no action required */
+	break;
+    case PAIR(1, SOME):		/* do as x{0,n-1}x = (x{1,n-1}|)x */
+	s = newstate(v->nfa);
+	NOERR();
+	moveouts(v->nfa, lp, s);
+	dupnfa(v->nfa, s, rp, lp, s);
+	NOERR();
+	repeat(v, lp, s, 1, n-1);
+	NOERR();
+	EMPTYARC(lp, s);
+	break;
+    case PAIR(1, INF):		/* add loopback arc */
+	s = newstate(v->nfa);
+	s2 = newstate(v->nfa);
+	NOERR();
+	moveouts(v->nfa, lp, s);
+	moveins(v->nfa, rp, s2);
+	EMPTYARC(lp, s);
+	EMPTYARC(s2, rp);
+	EMPTYARC(s2, s);
+	break;
+    case PAIR(SOME, SOME):		/* do as x{m-1,n-1}x */
+	s = newstate(v->nfa);
+	NOERR();
+	moveouts(v->nfa, lp, s);
+	dupnfa(v->nfa, s, rp, lp, s);
+	NOERR();
+	repeat(v, lp, s, m-1, n-1);
+	break;
+    case PAIR(SOME, INF):		/* do as x{m-1,}x */
+	s = newstate(v->nfa);
+	NOERR();
+	moveouts(v->nfa, lp, s);
+	dupnfa(v->nfa, s, rp, lp, s);
+	NOERR();
+	repeat(v, lp, s, m-1, n);
+	break;
+    default:
+	ERR(REG_ASSERT);
+	break;
+    }
+}
+
+/*
+ - bracket - handle non-complemented bracket expression
+ * Also called from cbracket for complemented bracket expressions.
+ ^ static void bracket(struct vars *, struct state *, struct state *);
+ */
+static void
+bracket(
+    struct vars *v,
+    struct state *lp,
+    struct state *rp)
+{
+    assert(SEE('['));
+    NEXT();
+    while (!SEE(']') && !SEE(EOS)) {
+	brackpart(v, lp, rp);
+    }
+    assert(SEE(']') || ISERR());
+    okcolors(v->nfa, v->cm);
+}
+
+/*
+ - cbracket - handle complemented bracket expression
+ * We do it by calling bracket() with dummy endpoints, and then complementing
+ * the result. The alternative would be to invoke rainbow(), and then delete
+ * arcs as the b.e. is seen... but that gets messy.
+ ^ static void cbracket(struct vars *, struct state *, struct state *);
+ */
+static void
+cbracket(
+    struct vars *v,
+    struct state *lp,
+    struct state *rp)
+{
+    struct state *left = newstate(v->nfa);
+    struct state *right = newstate(v->nfa);
+
+    NOERR();
+    bracket(v, left, right);
+    if (v->cflags&REG_NLSTOP) {
+	newarc(v->nfa, PLAIN, v->nlcolor, left, right);
+    }
+    NOERR();
+
+    assert(lp->nouts == 0);	/* all outarcs will be ours */
+
+    /*
+     * Easy part of complementing, and all there is to do since the MCCE code
+     * was removed.
+     */
+
+    colorcomplement(v->nfa, v->cm, PLAIN, left, lp, rp);
+    NOERR();
+    dropstate(v->nfa, left);
+    assert(right->nins == 0);
+    freestate(v->nfa, right);
+    return;
+}
+
+/*
+ - brackpart - handle one item (or range) within a bracket expression
+ ^ static void brackpart(struct vars *, struct state *, struct state *);
+ */
+static void
+brackpart(
+    struct vars *v,
+    struct state *lp,
+    struct state *rp)
+{
+    celt startc, endc;
+    struct cvec *cv;
+    const chr *startp, *endp;
+    chr c;
+
+    /*
+     * Parse something, get rid of special cases, take shortcuts.
+     */
+
+    switch (v->nexttype) {
+    case RANGE:			/* a-b-c or other botch */
+	ERR(REG_ERANGE);
+	return;
+	break;
+    case PLAIN:
+	c = v->nextvalue;
+	NEXT();
+
+	/*
+	 * Shortcut for ordinary chr (not range).
+	 */
+
+	if (!SEE(RANGE)) {
+	    onechr(v, c, lp, rp);
+	    return;
+	}
+	startc = element(v, &c, &c+1);
+	NOERR();
+	break;
+    case COLLEL:
+	startp = v->now;
+	endp = scanplain(v);
+	INSIST(startp < endp, REG_ECOLLATE);
+	NOERR();
+	startc = element(v, startp, endp);
+	NOERR();
+	break;
+    case ECLASS:
+	startp = v->now;
+	endp = scanplain(v);
+	INSIST(startp < endp, REG_ECOLLATE);
+	NOERR();
+	startc = element(v, startp, endp);
+	NOERR();
+	cv = eclass(v, startc, (v->cflags&REG_ICASE));
+	NOERR();
+	dovec(v, cv, lp, rp);
+	return;
+	break;
+    case CCLASS:
+	startp = v->now;
+	endp = scanplain(v);
+	INSIST(startp < endp, REG_ECTYPE);
+	NOERR();
+	cv = cclass(v, startp, endp, (v->cflags&REG_ICASE));
+	NOERR();
+	dovec(v, cv, lp, rp);
+	return;
+	break;
+    default:
+	ERR(REG_ASSERT);
+	return;
+	break;
+    }
+
+    if (SEE(RANGE)) {
+	NEXT();
+	switch (v->nexttype) {
+	case PLAIN:
+	case RANGE:
+	    c = v->nextvalue;
+	    NEXT();
+	    endc = element(v, &c, &c+1);
+	    NOERR();
+	    break;
+	case COLLEL:
+	    startp = v->now;
+	    endp = scanplain(v);
+	    INSIST(startp < endp, REG_ECOLLATE);
+	    NOERR();
+	    endc = element(v, startp, endp);
+	    NOERR();
+	    break;
+	default:
+	    ERR(REG_ERANGE);
+	    return;
+	    break;
+	}
+    } else {
+	endc = startc;
+    }
+
+    /*
+     * Ranges are unportable. Actually, standard C does guarantee that digits
+     * are contiguous, but making that an exception is just too complicated.
+     */
+
+    if (startc != endc) {
+	NOTE(REG_UUNPORT);
+    }
+    cv = range(v, startc, endc, (v->cflags&REG_ICASE));
+    NOERR();
+    dovec(v, cv, lp, rp);
+}
+
+/*
+ - scanplain - scan PLAIN contents of [. etc.
+ * Certain bits of trickery in lex.c know that this code does not try to look
+ * past the final bracket of the [. etc.
+ ^ static const chr *scanplain(struct vars *);
+ */
+static const chr *		/* just after end of sequence */
+scanplain(
+    struct vars *v)
+{
+    const chr *endp;
+
+    assert(SEE(COLLEL) || SEE(ECLASS) || SEE(CCLASS));
+    NEXT();
+
+    endp = v->now;
+    while (SEE(PLAIN)) {
+	endp = v->now;
+	NEXT();
+    }
+
+    assert(SEE(END) || ISERR());
+    NEXT();
+
+    return endp;
+}
+
+/*
+ - onechr - fill in arcs for a plain character, and possible case complements
+ * This is mostly a shortcut for efficient handling of the common case.
+ ^ static void onechr(struct vars *, pchr, struct state *, struct state *);
+ */
+static void
+onechr(
+    struct vars *v,
+    pchr c,
+    struct state *lp,
+    struct state *rp)
+{
+    if (!(v->cflags&REG_ICASE)) {
+	newarc(v->nfa, PLAIN, subcolor(v->cm, c), lp, rp);
+	return;
+    }
+
+    /*
+     * Rats, need general case anyway...
+     */
+
+    dovec(v, allcases(v, c), lp, rp);
+}
+
+/*
+ - dovec - fill in arcs for each element of a cvec
+ ^ static void dovec(struct vars *, struct cvec *, struct state *,
+ ^ 	struct state *);
+ */
+static void
+dovec(
+    struct vars *v,
+    struct cvec *cv,
+    struct state *lp,
+    struct state *rp)
+{
+    chr ch, from, to;
+    const chr *p;
+    int i;
+
+    for (p = cv->chrs, i = cv->nchrs; i > 0; p++, i--) {
+	ch = *p;
+	newarc(v->nfa, PLAIN, subcolor(v->cm, ch), lp, rp);
+    }
+
+    for (p = cv->ranges, i = cv->nranges; i > 0; p += 2, i--) {
+	from = *p;
+	to = *(p+1);
+	if (from <= to) {
+	    subrange(v, from, to, lp, rp);
+	}
+    }
+
+}
+
+/*
+ - wordchrs - set up word-chr list for word-boundary stuff, if needed
+ * The list is kept as a bunch of arcs between two dummy states; it's disposed
+ * of by the unreachable-states sweep in NFA optimization. Does NEXT(). Must
+ * not be called from any unusual lexical context. This should be reconciled
+ * with the \w etc. handling in lex.c, and should be cleaned up to reduce
+ * dependencies on input scanning.
+ ^ static void wordchrs(struct vars *);
+ */
+static void
+wordchrs(
+    struct vars *v)
+{
+    struct state *left, *right;
+
+    if (v->wordchrs != NULL) {
+	NEXT();		/* for consistency */
+	return;
+    }
+
+    left = newstate(v->nfa);
+    right = newstate(v->nfa);
+    NOERR();
+
+    /*
+     * Fine point: implemented with [::], and lexer will set REG_ULOCALE.
+     */
+
+    lexword(v);
+    NEXT();
+    assert(v->savenow != NULL && SEE('['));
+    bracket(v, left, right);
+    assert((v->savenow != NULL && SEE(']')) || ISERR());
+    NEXT();
+    NOERR();
+    v->wordchrs = left;
+}
+
+/*
+ - subre - allocate a subre
+ ^ static struct subre *subre(struct vars *, int, int, struct state *,
+ ^	struct state *);
+ */
+static struct subre *
+subre(
+    struct vars *v,
+    int op,
+    int flags,
+    struct state *begin,
+    struct state *end)
+{
+    struct subre *ret = v->treefree;
+
+    if (ret != NULL) {
+	v->treefree = ret->left;
+    } else {
+	ret = (struct subre *) MALLOC(sizeof(struct subre));
+	if (ret == NULL) {
+	    ERR(REG_ESPACE);
+	    return NULL;
+	}
+	ret->chain = v->treechain;
+	v->treechain = ret;
+    }
+
+    assert(strchr("=b|.*(", op) != NULL);
+
+    ret->op = op;
+    ret->flags = flags;
+    ret->id = 0;		/* will be assigned later */
+    ret->subno = 0;
+    ret->min = ret->max = 1;
+    ret->left = NULL;
+    ret->right = NULL;
+    ret->begin = begin;
+    ret->end = end;
+    ZAPCNFA(ret->cnfa);
+
+    return ret;
+}
+
+/*
+ - freesubre - free a subRE subtree
+ ^ static void freesubre(struct vars *, struct subre *);
+ */
+static void
+freesubre(
+    struct vars *v,		/* might be NULL */
+    struct subre *sr)
+{
+    if (sr == NULL) {
+	return;
+    }
+
+    if (sr->left != NULL) {
+	freesubre(v, sr->left);
+    }
+    if (sr->right != NULL) {
+	freesubre(v, sr->right);
+    }
+
+    freesrnode(v, sr);
+}
+
+/*
+ - freesrnode - free one node in a subRE subtree
+ ^ static void freesrnode(struct vars *, struct subre *);
+ */
+static void
+freesrnode(
+    struct vars *v,		/* might be NULL */
+    struct subre *sr)
+{
+    if (sr == NULL) {
+	return;
+    }
+
+    if (!NULLCNFA(sr->cnfa)) {
+	freecnfa(&sr->cnfa);
+    }
+    sr->flags = 0;
+
+    if (v != NULL && v->treechain != NULL) {
+	/* we're still parsing, maybe we can reuse the subre */
+	sr->left = v->treefree;
+	v->treefree = sr;
+    } else {
+	FREE(sr);
+    }
+}
+
+/*
+ - optst - optimize a subRE subtree
+ ^ static void optst(struct vars *, struct subre *);
+ */
+static void
+optst(
+    struct vars *v,
+    struct subre *t)
+{
+    /*
+     * DGP (2007-11-13): I assume it was the programmer's intent to eventually
+     * come back and add code to optimize subRE trees, but the routine coded
+     * just spends effort traversing the tree and doing nothing. We can do
+     * nothing with less effort.
+     */
+
+    return;
+}
+
+/*
+ - numst - number tree nodes (assigning "id" indexes)
+ ^ static int numst(struct subre *, int);
+ */
+static int			/* next number */
+numst(
+    struct subre *t,
+    int start)			/* starting point for subtree numbers */
+{
+    int i;
+
+    assert(t != NULL);
+
+    i = start;
+    t->id = (short) i++;
+    if (t->left != NULL) {
+	i = numst(t->left, i);
+    }
+    if (t->right != NULL) {
+	i = numst(t->right, i);
+    }
+    return i;
+}
+
+/*
+ - markst - mark tree nodes as INUSE
+ * Note: this is a great deal more subtle than it looks.  During initial
+ * parsing of a regex, all subres are linked into the treechain list;
+ * discarded ones are also linked into the treefree list for possible reuse.
+ * After we are done creating all subres required for a regex, we run markst()
+ * then cleanst(), which results in discarding all subres not reachable from
+ * v->tree.  We then clear v->treechain, indicating that subres must be found
+ * by descending from v->tree.  This changes the behavior of freesubre(): it
+ * will henceforth FREE() unwanted subres rather than sticking them into the
+ * treefree list.  (Doing that any earlier would result in dangling links in
+ * the treechain list.)  This all means that freev() will clean up correctly
+ * if invoked before or after markst()+cleanst(); but it would not work if
+ * called partway through this state conversion, so we mustn't error out
+ * in or between these two functions.
+ ^ static void markst(struct subre *);
+ */
+static void
+markst(
+    struct subre *t)
+{
+    assert(t != NULL);
+
+    t->flags |= INUSE;
+    if (t->left != NULL) {
+	markst(t->left);
+    }
+    if (t->right != NULL) {
+	markst(t->right);
+    }
+}
+
+/*
+ - cleanst - free any tree nodes not marked INUSE
+ ^ static void cleanst(struct vars *);
+ */
+static void
+cleanst(
+    struct vars *v)
+{
+    struct subre *t;
+    struct subre *next;
+
+    for (t = v->treechain; t != NULL; t = next) {
+	next = t->chain;
+	if (!(t->flags&INUSE)) {
+	    FREE(t);
+	}
+    }
+    v->treechain = NULL;
+    v->treefree = NULL;		/* just on general principles */
+}
+
+/*
+ - nfatree - turn a subRE subtree into a tree of compacted NFAs
+ ^ static long nfatree(struct vars *, struct subre *, FILE *);
+ */
+static long			/* optimize results from top node */
+nfatree(
+    struct vars *v,
+    struct subre *t,
+    FILE *f)			/* for debug output */
+{
+    assert(t != NULL && t->begin != NULL);
+
+    if (t->left != NULL) {
+	(DISCARD) nfatree(v, t->left, f);
+    }
+    if (t->right != NULL) {
+	(DISCARD) nfatree(v, t->right, f);
+    }
+
+    return nfanode(v, t, f);
+}
+
+/*
+ - nfanode - do one NFA for nfatree
+ ^ static long nfanode(struct vars *, struct subre *, FILE *);
+ */
+static long			/* optimize results */
+nfanode(
+    struct vars *v,
+    struct subre *t,
+    FILE *f)			/* for debug output */
+{
+    struct nfa *nfa;
+    long ret = 0;
+    char idbuf[50];
+
+    assert(t->begin != NULL);
+
+    if (f != NULL) {
+	fprintf(f, "\n\n\n========= TREE NODE %s ==========\n",
+		stid(t, idbuf, sizeof(idbuf)));
+    }
+    nfa = newnfa(v, v->cm, v->nfa);
+    NOERRZ();
+    dupnfa(nfa, t->begin, t->end, nfa->init, nfa->final);
+    if (!ISERR()) {
+	specialcolors(nfa);
+	ret = optimize(nfa, f);
+    }
+    if (!ISERR()) {
+	compact(nfa, &t->cnfa);
+    }
+
+    freenfa(nfa);
+    return ret;
+}
+
+/*
+ - newlacon - allocate a lookahead-constraint subRE
+ ^ static int newlacon(struct vars *, struct state *, struct state *, int);
+ */
+static int			/* lacon number */
+newlacon(
+    struct vars *v,
+    struct state *begin,
+    struct state *end,
+    int pos)
+{
+    int n;
+    struct subre *newlacons;
+    struct subre *sub;
+
+    if (v->nlacons == 0) {
+	n = 1;		/* skip 0th */
+	newlacons = (struct subre *) MALLOC(2 * sizeof(struct subre));
+    } else {
+	n = v->nlacons;
+	newlacons = (struct subre *) REALLOC(v->lacons,
+					     (n + 1) * sizeof(struct subre));
+    }
+
+    if (newlacons == NULL) {
+	ERR(REG_ESPACE);
+	return 0;
+    }
+
+    v->lacons = newlacons;
+    v->nlacons = n + 1;
+    sub = &v->lacons[n];
+    sub->begin = begin;
+    sub->end = end;
+    sub->subno = pos;
+    ZAPCNFA(sub->cnfa);
+    return n;
+}
+
+/*
+ - freelacons - free lookahead-constraint subRE vector
+ ^ static void freelacons(struct subre *, int);
+ */
+static void
+freelacons(
+    struct subre *subs,
+    int n)
+{
+    struct subre *sub;
+    int i;
+
+    assert(n > 0);
+    for (sub=subs+1, i=n-1; i>0; sub++, i--) {	/* no 0th */
+	if (!NULLCNFA(sub->cnfa)) {
+	    freecnfa(&sub->cnfa);
+	}
+    }
+    FREE(subs);
+}
+
+/*
+ - rfree - free a whole RE (insides of regfree)
+ ^ static void rfree(regex_t *);
+ */
+static void
+rfree(
+    regex_t *re)
+{
+    struct guts *g;
+
+    if (re == NULL || re->re_magic != REMAGIC) {
+	return;
+    }
+
+    re->re_magic = 0;	/* invalidate RE */
+    g = (struct guts *) re->re_guts;
+    re->re_guts = NULL;
+    re->re_fns = NULL;
+    if (g != NULL) {
+	g->magic = 0;
+	freecm(&g->cmap);
+	if (g->tree != NULL) {
+	    freesubre(NULL, g->tree);
+	}
+	if (g->lacons != NULL) {
+	    freelacons(g->lacons, g->nlacons);
+	}
+	if (!NULLCNFA(g->search)) {
+	    freecnfa(&g->search);
+	}
+	FREE(g);
+    }
+}
+
+/*
+ - dump - dump an RE in human-readable form
+ ^ static void dump(regex_t *, FILE *);
+ */
+static void
+dump(
+    regex_t *re,
+    FILE *f)
+{
+#ifdef REG_DEBUG
+    struct guts *g;
+    int i;
+
+    if (re->re_magic != REMAGIC) {
+	fprintf(f, "bad magic number (0x%x not 0x%x)\n",
+		re->re_magic, REMAGIC);
+    }
+    if (re->re_guts == NULL) {
+	fprintf(f, "NULL guts!!!\n");
+	return;
+    }
+    g = (struct guts *) re->re_guts;
+    if (g->magic != GUTSMAGIC) {
+	fprintf(f, "bad guts magic number (0x%x not 0x%x)\n",
+		g->magic, GUTSMAGIC);
+    }
+
+    fprintf(f, "\n\n\n========= DUMP ==========\n");
+    fprintf(f, "nsub %d, info 0%lo, csize %d, ntree %d\n",
+	    (int) re->re_nsub, re->re_info, re->re_csize, g->ntree);
+
+    dumpcolors(&g->cmap, f);
+    if (!NULLCNFA(g->search)) {
+	fprintf(f, "\nsearch:\n");
+	dumpcnfa(&g->search, f);
+    }
+    for (i = 1; i < g->nlacons; i++) {
+	fprintf(f, "\nla%d (%s):\n", i,
+		(g->lacons[i].subno) ? "positive" : "negative");
+	dumpcnfa(&g->lacons[i].cnfa, f);
+    }
+    fprintf(f, "\n");
+    dumpst(g->tree, f, 0);
+#endif
+}
+
+/*
+ - dumpst - dump a subRE tree
+ ^ static void dumpst(struct subre *, FILE *, int);
+ */
+static void
+dumpst(
+    struct subre *t,
+    FILE *f,
+    int nfapresent)		/* is the original NFA still around? */
+{
+    if (t == NULL) {
+	fprintf(f, "null tree\n");
+    } else {
+	stdump(t, f, nfapresent);
+    }
+    fflush(f);
+}
+
+/*
+ - stdump - recursive guts of dumpst
+ ^ static void stdump(struct subre *, FILE *, int);
+ */
+static void
+stdump(
+    struct subre *t,
+    FILE *f,
+    int nfapresent)		/* is the original NFA still around? */
+{
+    char idbuf[50];
+
+    fprintf(f, "%s. `%c'", stid(t, idbuf, sizeof(idbuf)), t->op);
+    if (t->flags&LONGER) {
+	fprintf(f, " longest");
+    }
+    if (t->flags&SHORTER) {
+	fprintf(f, " shortest");
+    }
+    if (t->flags&MIXED) {
+	fprintf(f, " hasmixed");
+    }
+    if (t->flags&CAP) {
+	fprintf(f, " hascapture");
+    }
+    if (t->flags&BACKR) {
+	fprintf(f, " hasbackref");
+    }
+    if (!(t->flags&INUSE)) {
+	fprintf(f, " UNUSED");
+    }
+    if (t->subno != 0) {
+	fprintf(f, " (#%d)", t->subno);
+    }
+    if (t->min != 1 || t->max != 1) {
+	fprintf(f, " {%d,", t->min);
+	if (t->max != DUPINF) {
+	    fprintf(f, "%d", t->max);
+	}
+	fprintf(f, "}");
+    }
+    if (nfapresent) {
+	fprintf(f, " %ld-%ld", (long)t->begin->no, (long)t->end->no);
+    }
+    if (t->left != NULL) {
+	fprintf(f, " L:%s", stid(t->left, idbuf, sizeof(idbuf)));
+    }
+    if (t->right != NULL) {
+	fprintf(f, " R:%s", stid(t->right, idbuf, sizeof(idbuf)));
+    }
+    if (!NULLCNFA(t->cnfa)) {
+	fprintf(f, "\n");
+	dumpcnfa(&t->cnfa, f);
+    }
+    fprintf(f, "\n");
+    if (t->left != NULL) {
+	stdump(t->left, f, nfapresent);
+    }
+    if (t->right != NULL) {
+	stdump(t->right, f, nfapresent);
+    }
+}
+
+/*
+ - stid - identify a subtree node for dumping
+ ^ static const char *stid(struct subre *, char *, size_t);
+ */
+static const char *			/* points to buf or constant string */
+stid(
+    struct subre *t,
+    char *buf,
+    size_t bufsize)
+{
+    /*
+     * Big enough for hex int or decimal t->id?
+     */
+
+    if (bufsize < sizeof(void*)*2 + 3 || bufsize < sizeof(t->id)*3 + 1) {
+	return "unable";
+    }
+    if (t->id != 0) {
+	sprintf(buf, "%d", t->id);
+    } else {
+	sprintf(buf, "%p", t);
+    }
+    return buf;
+}
+
+#include "regc_lex.c"
+#include "regc_color.c"
+#include "regc_nfa.c"
+#include "regc_cvec.c"
+#include "regc_locale.c"
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/regcustom.h b/generic/regcustom.h
new file mode 100644
index 0000000..681b97d
--- /dev/null
+++ b/generic/regcustom.h
@@ -0,0 +1,155 @@
+/*
+ * Copyright (c) 1998, 1999 Henry Spencer.  All rights reserved.
+ *
+ * Development of this software was funded, in part, by Cray Research Inc.,
+ * UUNET Communications Services Inc., Sun Microsystems Inc., and Scriptics
+ * Corporation, none of whom are responsible for the results. The author
+ * thanks all of them.
+ *
+ * Redistribution and use in source and binary forms - with or without
+ * modification - are permitted for any purpose, provided that redistributions
+ * in source form retain this entire copyright notice and indicate the origin
+ * and nature of any modifications.
+ *
+ * I'd appreciate being given credit for this package in the documentation of
+ * software which uses it, but that is not a requirement.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * HENRY SPENCER BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Headers if any.
+ */
+
+#include "regex.h"
+
+/*
+ * Overrides for regguts.h definitions, if any.
+ */
+
+#define	FUNCPTR(name, args)	(*name)args
+#define	MALLOC(n)		VS(attemptckalloc(n))
+#define	FREE(p)			ckfree(VS(p))
+#define	REALLOC(p,n)		VS(attemptckrealloc(VS(p),n))
+
+/*
+ * Do not insert extras between the "begin" and "end" lines - this chunk is
+ * automatically extracted to be fitted into regex.h.
+ */
+
+/* --- begin --- */
+/* Ensure certain things don't sneak in from system headers. */
+#ifdef __REG_WIDE_T
+#undef __REG_WIDE_T
+#endif
+#ifdef __REG_WIDE_COMPILE
+#undef __REG_WIDE_COMPILE
+#endif
+#ifdef __REG_WIDE_EXEC
+#undef __REG_WIDE_EXEC
+#endif
+#ifdef __REG_REGOFF_T
+#undef __REG_REGOFF_T
+#endif
+#ifdef __REG_NOFRONT
+#undef __REG_NOFRONT
+#endif
+#ifdef __REG_NOCHAR
+#undef __REG_NOCHAR
+#endif
+/* Interface types */
+#define	__REG_WIDE_T	Tcl_UniChar
+#define	__REG_REGOFF_T	long	/* Not really right, but good enough... */
+/* Names and declarations */
+#define	__REG_WIDE_COMPILE	TclReComp
+#define	__REG_WIDE_EXEC		TclReExec
+#define	__REG_NOFRONT		/* Don't want regcomp() and regexec() */
+#define	__REG_NOCHAR		/* Or the char versions */
+#define	regfree		TclReFree
+#define	regerror	TclReError
+/* --- end --- */
+
+/*
+ * Internal character type and related.
+ */
+
+typedef Tcl_UniChar chr;	/* The type itself. */
+typedef int pchr;		/* What it promotes to. */
+typedef unsigned uchr;		/* Unsigned type that will hold a chr. */
+typedef int celt;		/* Type to hold chr, or NOCELT */
+#define	NOCELT (-1)		/* Celt value which is not valid chr */
+#define	CHR(c) (UCHAR(c))	/* Turn char literal into chr literal */
+#define	DIGITVAL(c) ((c)-'0')	/* Turn chr digit into its value */
+#if TCL_UTF_MAX > 4
+#define	CHRBITS	32		/* Bits in a chr; must not use sizeof */
+#define	CHR_MIN	0x00000000	/* Smallest and largest chr; the value */
+#define	CHR_MAX	0xffffffff	/* CHR_MAX-CHR_MIN+1 should fit in uchr */
+#else
+#define	CHRBITS	16		/* Bits in a chr; must not use sizeof */
+#define	CHR_MIN	0x0000		/* Smallest and largest chr; the value */
+#define	CHR_MAX	0xffff		/* CHR_MAX-CHR_MIN+1 should fit in uchr */
+#endif
+
+/*
+ * Functions operating on chr.
+ */
+
+#define	iscalnum(x)	Tcl_UniCharIsAlnum(x)
+#define	iscalpha(x)	Tcl_UniCharIsAlpha(x)
+#define	iscdigit(x)	Tcl_UniCharIsDigit(x)
+#define	iscspace(x)	Tcl_UniCharIsSpace(x)
+
+/*
+ * Name the external functions.
+ */
+
+#define	compile		TclReComp
+#define	exec		TclReExec
+
+/*
+& Enable/disable debugging code (by whether REG_DEBUG is defined or not).
+*/
+
+#if 0				/* No debug unless requested by makefile. */
+#define	REG_DEBUG	/* */
+#endif
+
+/*
+ * Method of allocating a local workspace. We used a thread-specific data
+ * space to store this because the regular expression engine is never
+ * reentered from the same thread; it doesn't make any callbacks.
+ */
+
+#if 1
+#define AllocVars(vPtr) \
+    static Tcl_ThreadDataKey varsKey; \
+    register struct vars *vPtr = (struct vars *) \
+	    Tcl_GetThreadData(&varsKey, sizeof(struct vars))
+#else
+/*
+ * This strategy for allocating workspace is "more proper" in some sense, but
+ * quite a bit slower. Using TSD (as above) leads to code that is quite a bit
+ * faster in practice (measured!)
+ */
+#define AllocVars(vPtr) \
+    register struct vars *vPtr = (struct vars *) MALLOC(sizeof(struct vars))
+#define FreeVars(vPtr) \
+    FREE(vPtr)
+#endif
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/rege_dfa.c b/generic/rege_dfa.c
new file mode 100644
index 0000000..e5f22c4
--- /dev/null
+++ b/generic/rege_dfa.c
@@ -0,0 +1,805 @@
+/*
+ * DFA routines
+ * This file is #included by regexec.c.
+ *
+ * Copyright (c) 1998, 1999 Henry Spencer.  All rights reserved.
+ *
+ * Development of this software was funded, in part, by Cray Research Inc.,
+ * UUNET Communications Services Inc., Sun Microsystems Inc., and Scriptics
+ * Corporation, none of whom are responsible for the results.  The author
+ * thanks all of them.
+ *
+ * Redistribution and use in source and binary forms -- with or without
+ * modification -- are permitted for any purpose, provided that
+ * redistributions in source form retain this entire copyright notice and
+ * indicate the origin and nature of any modifications.
+ *
+ * I'd appreciate being given credit for this package in the documentation
+ * of software which uses it, but that is not a requirement.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * HENRY SPENCER BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+/*
+ - longest - longest-preferred matching engine
+ ^ static chr *longest(struct vars *, struct dfa *, chr *, chr *, int *);
+ */
+static chr *			/* endpoint, or NULL */
+longest(
+    struct vars *const v,	/* used only for debug and exec flags */
+    struct dfa *const d,
+    chr *const start,		/* where the match should start */
+    chr *const stop,		/* match must end at or before here */
+    int *const hitstopp)	/* record whether hit v->stop, if non-NULL */
+{
+    chr *cp;
+    chr *realstop = (stop == v->stop) ? stop : stop + 1;
+    color co;
+    struct sset *css, *ss;
+    chr *post;
+    int i;
+    struct colormap *cm = d->cm;
+
+    /*
+     * Initialize.
+     */
+
+    css = initialize(v, d, start);
+    cp = start;
+    if (hitstopp != NULL) {
+	*hitstopp = 0;
+    }
+
+    /*
+     * Startup.
+     */
+
+    FDEBUG(("+++ startup +++\n"));
+    if (cp == v->start) {
+	co = d->cnfa->bos[(v->eflags&REG_NOTBOL) ? 0 : 1];
+	FDEBUG(("color %ld\n", (long)co));
+    } else {
+	co = GETCOLOR(cm, *(cp - 1));
+	FDEBUG(("char %c, color %ld\n", (char)*(cp-1), (long)co));
+    }
+    css = miss(v, d, css, co, cp, start);
+    if (css == NULL) {
+	return NULL;
+    }
+    css->lastseen = cp;
+
+    /*
+     * Main loop.
+     */
+
+    if (v->eflags&REG_FTRACE) {
+	while (cp < realstop) {
+	    FDEBUG(("+++ at c%d +++\n", (int) (css - d->ssets)));
+	    co = GETCOLOR(cm, *cp);
+	    FDEBUG(("char %c, color %ld\n", (char)*cp, (long)co));
+	    ss = css->outs[co];
+	    if (ss == NULL) {
+		ss = miss(v, d, css, co, cp+1, start);
+		if (ss == NULL) {
+		    break;	/* NOTE BREAK OUT */
+		}
+	    }
+	    cp++;
+	    ss->lastseen = cp;
+	    css = ss;
+	}
+    } else {
+	while (cp < realstop) {
+	    co = GETCOLOR(cm, *cp);
+	    ss = css->outs[co];
+	    if (ss == NULL) {
+		ss = miss(v, d, css, co, cp+1, start);
+		if (ss == NULL) {
+		    break;	/* NOTE BREAK OUT */
+		}
+	    }
+	    cp++;
+	    ss->lastseen = cp;
+	    css = ss;
+	}
+    }
+
+    /*
+     * Shutdown.
+     */
+
+    FDEBUG(("+++ shutdown at c%d +++\n", (int) (css - d->ssets)));
+    if (cp == v->stop && stop == v->stop) {
+	if (hitstopp != NULL) {
+	    *hitstopp = 1;
+	}
+	co = d->cnfa->eos[(v->eflags&REG_NOTEOL) ? 0 : 1];
+	FDEBUG(("color %ld\n", (long)co));
+	ss = miss(v, d, css, co, cp, start);
+
+	/*
+	 * Special case: match ended at eol?
+	 */
+
+	if (ss != NULL && (ss->flags&POSTSTATE)) {
+	    return cp;
+	} else if (ss != NULL) {
+	    ss->lastseen = cp;	/* to be tidy */
+	}
+    }
+
+    /*
+     * Find last match, if any.
+     */
+
+    post = d->lastpost;
+    for (ss = d->ssets, i = d->nssused; i > 0; ss++, i--) {
+	if ((ss->flags&POSTSTATE) && (post != ss->lastseen) &&
+		(post == NULL || post < ss->lastseen)) {
+	    post = ss->lastseen;
+	}
+    }
+    if (post != NULL) {		/* found one */
+	return post - 1;
+    }
+
+    return NULL;
+}
+
+/*
+ - shortest - shortest-preferred matching engine
+ ^ static chr *shortest(struct vars *, struct dfa *, chr *, chr *, chr *,
+ ^ 	chr **, int *);
+ */
+static chr *			/* endpoint, or NULL */
+shortest(
+    struct vars *const v,
+    struct dfa *const d,
+    chr *const start,		/* where the match should start */
+    chr *const min,		/* match must end at or after here */
+    chr *const max,		/* match must end at or before here */
+    chr **const coldp,		/* store coldstart pointer here, if nonNULL */
+    int *const hitstopp)	/* record whether hit v->stop, if non-NULL */
+{
+    chr *cp;
+    chr *realmin = (min == v->stop) ? min : min + 1;
+    chr *realmax = (max == v->stop) ? max : max + 1;
+    color co;
+    struct sset *css, *ss;
+    struct colormap *cm = d->cm;
+
+    /*
+     * Initialize.
+     */
+
+    css = initialize(v, d, start);
+    cp = start;
+    if (hitstopp != NULL) {
+	*hitstopp = 0;
+    }
+
+    /*
+     * Startup.
+     */
+
+    FDEBUG(("--- startup ---\n"));
+    if (cp == v->start) {
+	co = d->cnfa->bos[(v->eflags&REG_NOTBOL) ? 0 : 1];
+	FDEBUG(("color %ld\n", (long)co));
+    } else {
+	co = GETCOLOR(cm, *(cp - 1));
+	FDEBUG(("char %c, color %ld\n", (char)*(cp-1), (long)co));
+    }
+    css = miss(v, d, css, co, cp, start);
+    if (css == NULL) {
+	return NULL;
+    }
+    css->lastseen = cp;
+    ss = css;
+
+    /*
+     * Main loop.
+     */
+
+    if (v->eflags&REG_FTRACE) {
+	while (cp < realmax) {
+	    FDEBUG(("--- at c%d ---\n", (int) (css - d->ssets)));
+	    co = GETCOLOR(cm, *cp);
+	    FDEBUG(("char %c, color %ld\n", (char)*cp, (long)co));
+	    ss = css->outs[co];
+	    if (ss == NULL) {
+		ss = miss(v, d, css, co, cp+1, start);
+		if (ss == NULL) {
+		    break;	/* NOTE BREAK OUT */
+		}
+	    }
+	    cp++;
+	    ss->lastseen = cp;
+	    css = ss;
+	    if ((ss->flags&POSTSTATE) && cp >= realmin) {
+		break;		/* NOTE BREAK OUT */
+	    }
+	}
+    } else {
+	while (cp < realmax) {
+	    co = GETCOLOR(cm, *cp);
+	    ss = css->outs[co];
+	    if (ss == NULL) {
+		ss = miss(v, d, css, co, cp+1, start);
+		if (ss == NULL) {
+		    break;	/* NOTE BREAK OUT */
+		}
+	    }
+	    cp++;
+	    ss->lastseen = cp;
+	    css = ss;
+	    if ((ss->flags&POSTSTATE) && cp >= realmin) {
+		break;		/* NOTE BREAK OUT */
+	    }
+	}
+    }
+
+    if (ss == NULL) {
+	return NULL;
+    }
+
+    if (coldp != NULL) {	/* report last no-progress state set, if any */
+	*coldp = lastCold(v, d);
+    }
+
+    if ((ss->flags&POSTSTATE) && cp > min) {
+	assert(cp >= realmin);
+	cp--;
+    } else if (cp == v->stop && max == v->stop) {
+	co = d->cnfa->eos[(v->eflags&REG_NOTEOL) ? 0 : 1];
+	FDEBUG(("color %ld\n", (long)co));
+	ss = miss(v, d, css, co, cp, start);
+
+	/*
+	 * Match might have ended at eol.
+	 */
+
+	if ((ss == NULL || !(ss->flags&POSTSTATE)) && hitstopp != NULL) {
+	    *hitstopp = 1;
+	}
+    }
+
+    if (ss == NULL || !(ss->flags&POSTSTATE)) {
+	return NULL;
+    }
+
+    return cp;
+}
+
+/*
+ - lastCold - determine last point at which no progress had been made
+ ^ static chr *lastCold(struct vars *, struct dfa *);
+ */
+static chr *			/* endpoint, or NULL */
+lastCold(
+    struct vars *const v,
+    struct dfa *const d)
+{
+    struct sset *ss;
+    chr *nopr = d->lastnopr;
+    int i;
+
+    if (nopr == NULL) {
+	nopr = v->start;
+    }
+    for (ss = d->ssets, i = d->nssused; i > 0; ss++, i--) {
+	if ((ss->flags&NOPROGRESS) && nopr < ss->lastseen) {
+	    nopr = ss->lastseen;
+	}
+    }
+    return nopr;
+}
+
+/*
+ - newDFA - set up a fresh DFA
+ ^ static struct dfa *newDFA(struct vars *, struct cnfa *,
+ ^ 	struct colormap *, struct smalldfa *);
+ */
+static struct dfa *
+newDFA(
+    struct vars *const v,
+    struct cnfa *const cnfa,
+    struct colormap *const cm,
+    struct smalldfa *sml)	/* preallocated space, may be NULL */
+{
+    struct dfa *d;
+    size_t nss = cnfa->nstates * 2;
+    int wordsper = (cnfa->nstates + UBITS - 1) / UBITS;
+    struct smalldfa *smallwas = sml;
+
+    assert(cnfa != NULL && cnfa->nstates != 0);
+
+    if (nss <= FEWSTATES && cnfa->ncolors <= FEWCOLORS) {
+	assert(wordsper == 1);
+	if (sml == NULL) {
+	    sml = (struct smalldfa *) MALLOC(sizeof(struct smalldfa));
+	    if (sml == NULL) {
+		ERR(REG_ESPACE);
+		return NULL;
+	    }
+	}
+	d = &sml->dfa;
+	d->ssets = sml->ssets;
+	d->statesarea = sml->statesarea;
+	d->work = &d->statesarea[nss];
+	d->outsarea = sml->outsarea;
+	d->incarea = sml->incarea;
+	d->cptsmalloced = 0;
+	d->mallocarea = (smallwas == NULL) ? (char *)sml : NULL;
+    } else {
+	d = (struct dfa *) MALLOC(sizeof(struct dfa));
+	if (d == NULL) {
+	    ERR(REG_ESPACE);
+	    return NULL;
+	}
+	d->ssets = (struct sset *) MALLOC(nss * sizeof(struct sset));
+	d->statesarea = (unsigned *)
+		MALLOC((nss+WORK) * wordsper * sizeof(unsigned));
+	d->work = &d->statesarea[nss * wordsper];
+	d->outsarea = (struct sset **)
+		MALLOC(nss * cnfa->ncolors * sizeof(struct sset *));
+	d->incarea = (struct arcp *)
+		MALLOC(nss * cnfa->ncolors * sizeof(struct arcp));
+	d->cptsmalloced = 1;
+	d->mallocarea = (char *)d;
+	if (d->ssets == NULL || d->statesarea == NULL ||
+		d->outsarea == NULL || d->incarea == NULL) {
+	    freeDFA(d);
+	    ERR(REG_ESPACE);
+	    return NULL;
+	}
+    }
+
+    d->nssets = (v->eflags&REG_SMALL) ? 7 : nss;
+    d->nssused = 0;
+    d->nstates = cnfa->nstates;
+    d->ncolors = cnfa->ncolors;
+    d->wordsper = wordsper;
+    d->cnfa = cnfa;
+    d->cm = cm;
+    d->lastpost = NULL;
+    d->lastnopr = NULL;
+    d->search = d->ssets;
+
+    /*
+     * Initialization of sset fields is done as needed.
+     */
+
+    return d;
+}
+
+/*
+ - freeDFA - free a DFA
+ ^ static void freeDFA(struct dfa *);
+ */
+static void
+freeDFA(
+    struct dfa *const d)
+{
+    if (d->cptsmalloced) {
+	if (d->ssets != NULL) {
+	    FREE(d->ssets);
+	}
+	if (d->statesarea != NULL) {
+	    FREE(d->statesarea);
+	}
+	if (d->outsarea != NULL) {
+	    FREE(d->outsarea);
+	}
+	if (d->incarea != NULL) {
+	    FREE(d->incarea);
+	}
+    }
+
+    if (d->mallocarea != NULL) {
+	FREE(d->mallocarea);
+    }
+}
+
+/*
+ - hash - construct a hash code for a bitvector
+ * There are probably better ways, but they're more expensive.
+ ^ static unsigned hash(unsigned *, int);
+ */
+static unsigned
+hash(
+    unsigned *const uv,
+    const int n)
+{
+    int i;
+    unsigned h;
+
+    h = 0;
+    for (i = 0; i < n; i++) {
+	h ^= uv[i];
+    }
+    return h;
+}
+
+/*
+ - initialize - hand-craft a cache entry for startup, otherwise get ready
+ ^ static struct sset *initialize(struct vars *, struct dfa *, chr *);
+ */
+static struct sset *
+initialize(
+    struct vars *const v,	/* used only for debug flags */
+    struct dfa *const d,
+    chr *const start)
+{
+    struct sset *ss;
+    int i;
+
+    /*
+     * Is previous one still there?
+     */
+
+    if (d->nssused > 0 && (d->ssets[0].flags&STARTER)) {
+	ss = &d->ssets[0];
+    } else {			/* no, must (re)build it */
+	ss = getVacantSS(v, d, start, start);
+	for (i = 0; i < d->wordsper; i++) {
+	    ss->states[i] = 0;
+	}
+	BSET(ss->states, d->cnfa->pre);
+	ss->hash = HASH(ss->states, d->wordsper);
+	assert(d->cnfa->pre != d->cnfa->post);
+	ss->flags = STARTER|LOCKED|NOPROGRESS;
+
+	/*
+	 * lastseen dealt with below
+	 */
+    }
+
+    for (i = 0; i < d->nssused; i++) {
+	d->ssets[i].lastseen = NULL;
+    }
+    ss->lastseen = start;	/* maybe untrue, but harmless */
+    d->lastpost = NULL;
+    d->lastnopr = NULL;
+    return ss;
+}
+
+/*
+ - miss - handle a cache miss
+ ^ static struct sset *miss(struct vars *, struct dfa *, struct sset *,
+ ^ 	pcolor, chr *, chr *);
+ */
+static struct sset *		/* NULL if goes to empty set */
+miss(
+    struct vars *const v,	/* used only for debug flags */
+    struct dfa *const d,
+    struct sset *const css,
+    const pcolor co,
+    chr *const cp,		/* next chr */
+    chr *const start)		/* where the attempt got started */
+{
+    struct cnfa *cnfa = d->cnfa;
+    unsigned h;
+    struct carc *ca;
+    struct sset *p;
+    int i, isPost, noProgress, gotState, doLAConstraints, sawLAConstraints;
+
+    /*
+     * For convenience, we can be called even if it might not be a miss.
+     */
+
+    if (css->outs[co] != NULL) {
+	FDEBUG(("hit\n"));
+	return css->outs[co];
+    }
+    FDEBUG(("miss\n"));
+
+    /*
+     * First, what set of states would we end up in?
+     */
+
+    for (i = 0; i < d->wordsper; i++) {
+	d->work[i] = 0;
+    }
+    isPost = 0;
+    noProgress = 1;
+    gotState = 0;
+    for (i = 0; i < d->nstates; i++) {
+	if (ISBSET(css->states, i)) {
+	    for (ca = cnfa->states[i]; ca->co != COLORLESS; ca++) {
+		if (ca->co == co) {
+		    BSET(d->work, ca->to);
+		    gotState = 1;
+		    if (ca->to == cnfa->post) {
+			isPost = 1;
+		    }
+		    if (!(cnfa->stflags[ca->to] & CNFA_NOPROGRESS)) {
+			noProgress = 0;
+		    }
+		    FDEBUG(("%d -> %d\n", i, ca->to));
+		}
+	    }
+	}
+    }
+    doLAConstraints = (gotState ? (cnfa->flags&HASLACONS) : 0);
+    sawLAConstraints = 0;
+    while (doLAConstraints) {		/* transitive closure */
+	doLAConstraints = 0;
+	for (i = 0; i < d->nstates; i++) {
+	    if (ISBSET(d->work, i)) {
+		for (ca = cnfa->states[i]; ca->co != COLORLESS; ca++) {
+		    if (ca->co < cnfa->ncolors) {
+			continue;	/* NOTE CONTINUE */
+		    }
+		    sawLAConstraints = 1;
+		    if (ISBSET(d->work, ca->to)) {
+			continue;	/* NOTE CONTINUE */
+		    }
+		    if (!checkLAConstraint(v, cnfa, cp, ca->co)) {
+			continue;	/* NOTE CONTINUE */
+		    }
+		    BSET(d->work, ca->to);
+		    doLAConstraints = 1;
+		    if (ca->to == cnfa->post) {
+			isPost = 1;
+		    }
+		    if (!(cnfa->stflags[ca->to] & CNFA_NOPROGRESS)) {
+			noProgress = 0;
+		    }
+		    FDEBUG(("%d :> %d\n", i, ca->to));
+		}
+	    }
+	}
+    }
+    if (!gotState) {
+	return NULL;
+    }
+    h = HASH(d->work, d->wordsper);
+
+    /*
+     * Next, is that in the cache?
+     */
+
+    for (p = d->ssets, i = d->nssused; i > 0; p++, i--) {
+	 if (HIT(h, d->work, p, d->wordsper)) {
+	     FDEBUG(("cached c%d\n", (int) (p - d->ssets)));
+	     break;			/* NOTE BREAK OUT */
+	 }
+    }
+    if (i == 0) {		/* nope, need a new cache entry */
+	p = getVacantSS(v, d, cp, start);
+	assert(p != css);
+	for (i = 0; i < d->wordsper; i++) {
+	    p->states[i] = d->work[i];
+	}
+	p->hash = h;
+	p->flags = (isPost ? POSTSTATE : 0);
+	if (noProgress) {
+	    p->flags |= NOPROGRESS;
+	}
+
+	/*
+	 * lastseen to be dealt with by caller
+	 */
+    }
+
+    if (!sawLAConstraints) {	/* lookahead conds. always cache miss */
+	FDEBUG(("c%d[%d]->c%d\n",
+		(int) (css - d->ssets), co, (int) (p - d->ssets)));
+	css->outs[co] = p;
+	css->inchain[co] = p->ins;
+	p->ins.ss = css;
+	p->ins.co = (color) co;
+    }
+    return p;
+}
+
+/*
+ - checkLAConstraint - lookahead-constraint checker for miss()
+ ^ static int checkLAConstraint(struct vars *, struct cnfa *, chr *, pcolor);
+ */
+static int			/* predicate:  constraint satisfied? */
+checkLAConstraint(
+    struct vars *const v,
+    struct cnfa *const pcnfa,	/* parent cnfa */
+    chr *const cp,
+    const pcolor co)		/* "color" of the lookahead constraint */
+{
+    int n;
+    struct subre *sub;
+    struct dfa *d;
+    struct smalldfa sd;
+    chr *end;
+
+    n = co - pcnfa->ncolors;
+    assert(n < v->g->nlacons && v->g->lacons != NULL);
+    FDEBUG(("=== testing lacon %d\n", n));
+    sub = &v->g->lacons[n];
+    d = newDFA(v, &sub->cnfa, &v->g->cmap, &sd);
+    if (d == NULL) {
+	ERR(REG_ESPACE);
+	return 0;
+    }
+    end = longest(v, d, cp, v->stop, NULL);
+    freeDFA(d);
+    FDEBUG(("=== lacon %d match %d\n", n, (end != NULL)));
+    return (sub->subno) ? (end != NULL) : (end == NULL);
+}
+
+/*
+ - getVacantSS - get a vacant state set
+ * This routine clears out the inarcs and outarcs, but does not otherwise
+ * clear the innards of the state set -- that's up to the caller.
+ ^ static struct sset *getVacantSS(struct vars *, struct dfa *, chr *, chr *);
+ */
+static struct sset *
+getVacantSS(
+    struct vars *const v,	/* used only for debug flags */
+    struct dfa *const d,
+    chr *const cp,
+    chr *const start)
+{
+    int i;
+    struct sset *ss, *p;
+    struct arcp ap, lastap = {NULL, 0}; /* silence gcc 4 warning */
+    color co;
+
+    ss = pickNextSS(v, d, cp, start);
+    assert(!(ss->flags&LOCKED));
+
+    /*
+     * Clear out its inarcs, including self-referential ones.
+     */
+
+    ap = ss->ins;
+    while ((p = ap.ss) != NULL) {
+	co = ap.co;
+	FDEBUG(("zapping c%d's %ld outarc\n", (int) (p - d->ssets), (long)co));
+	p->outs[co] = NULL;
+	ap = p->inchain[co];
+	p->inchain[co].ss = NULL; /* paranoia */
+    }
+    ss->ins.ss = NULL;
+
+    /*
+     * Take it off the inarc chains of the ssets reached by its outarcs.
+     */
+
+    for (i = 0; i < d->ncolors; i++) {
+	p = ss->outs[i];
+	assert(p != ss);	/* not self-referential */
+	if (p == NULL) {
+	    continue;		/* NOTE CONTINUE */
+	}
+	FDEBUG(("del outarc %d from c%d's in chn\n", i, (int) (p - d->ssets)));
+	if (p->ins.ss == ss && p->ins.co == i) {
+	    p->ins = ss->inchain[i];
+	} else {
+	    assert(p->ins.ss != NULL);
+	    for (ap = p->ins; ap.ss != NULL && !(ap.ss == ss && ap.co == i);
+		    ap = ap.ss->inchain[ap.co]) {
+		lastap = ap;
+	    }
+	    assert(ap.ss != NULL);
+	    lastap.ss->inchain[lastap.co] = ss->inchain[i];
+	}
+	ss->outs[i] = NULL;
+	ss->inchain[i].ss = NULL;
+    }
+
+    /*
+     * If ss was a success state, may need to remember location.
+     */
+
+    if ((ss->flags&POSTSTATE) && ss->lastseen != d->lastpost &&
+	    (d->lastpost == NULL || d->lastpost < ss->lastseen)) {
+	d->lastpost = ss->lastseen;
+    }
+
+    /*
+     * Likewise for a no-progress state.
+     */
+
+    if ((ss->flags&NOPROGRESS) && ss->lastseen != d->lastnopr &&
+	    (d->lastnopr == NULL || d->lastnopr < ss->lastseen)) {
+	d->lastnopr = ss->lastseen;
+    }
+
+    return ss;
+}
+
+/*
+ - pickNextSS - pick the next stateset to be used
+ ^ static struct sset *pickNextSS(struct vars *, struct dfa *, chr *, chr *);
+ */
+static struct sset *
+pickNextSS(
+    struct vars *const v,	/* used only for debug flags */
+    struct dfa *const d,
+    chr *const cp,
+    chr *const start)
+{
+    int i;
+    struct sset *ss, *end;
+    chr *ancient;
+
+    /*
+     * Shortcut for cases where cache isn't full.
+     */
+
+    if (d->nssused < d->nssets) {
+	i = d->nssused;
+	d->nssused++;
+	ss = &d->ssets[i];
+	FDEBUG(("new c%d\n", i));
+
+	/*
+	 * Set up innards.
+	 */
+
+	ss->states = &d->statesarea[i * d->wordsper];
+	ss->flags = 0;
+	ss->ins.ss = NULL;
+	ss->ins.co = WHITE;	/* give it some value */
+	ss->outs = &d->outsarea[i * d->ncolors];
+	ss->inchain = &d->incarea[i * d->ncolors];
+	for (i = 0; i < d->ncolors; i++) {
+	    ss->outs[i] = NULL;
+	    ss->inchain[i].ss = NULL;
+	}
+	return ss;
+    }
+
+    /*
+     * Look for oldest, or old enough anyway.
+     */
+
+    if (cp - start > d->nssets*2/3) {	/* oldest 33% are expendable */
+	ancient = cp - d->nssets*2/3;
+    } else {
+	ancient = start;
+    }
+    for (ss = d->search, end = &d->ssets[d->nssets]; ss < end; ss++) {
+	if ((ss->lastseen == NULL || ss->lastseen < ancient)
+		&& !(ss->flags&LOCKED)) {
+	    d->search = ss + 1;
+	    FDEBUG(("replacing c%d\n", (int) (ss - d->ssets)));
+	    return ss;
+	}
+    }
+    for (ss = d->ssets, end = d->search; ss < end; ss++) {
+	if ((ss->lastseen == NULL || ss->lastseen < ancient)
+		&& !(ss->flags&LOCKED)) {
+	    d->search = ss + 1;
+	    FDEBUG(("replacing c%d\n", (int) (ss - d->ssets)));
+	    return ss;
+	}
+    }
+
+    /*
+     * Nobody's old enough?!? -- something's really wrong.
+     */
+
+    FDEBUG(("can't find victim to replace!\n"));
+    assert(NOTREACHED);
+    ERR(REG_ASSERT);
+    return d->ssets;
+}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/regerror.c b/generic/regerror.c
new file mode 100644
index 0000000..49d93ed
--- /dev/null
+++ b/generic/regerror.c
@@ -0,0 +1,129 @@
+/*
+ * regerror - error-code expansion
+ *
+ * Copyright (c) 1998, 1999 Henry Spencer.  All rights reserved.
+ *
+ * Development of this software was funded, in part, by Cray Research Inc.,
+ * UUNET Communications Services Inc., Sun Microsystems Inc., and Scriptics
+ * Corporation, none of whom are responsible for the results.  The author
+ * thanks all of them.
+ *
+ * Redistribution and use in source and binary forms -- with or without
+ * modification -- are permitted for any purpose, provided that
+ * redistributions in source form retain this entire copyright notice and
+ * indicate the origin and nature of any modifications.
+ *
+ * I'd appreciate being given credit for this package in the documentation of
+ * software which uses it, but that is not a requirement.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * HENRY SPENCER BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "regguts.h"
+
+/*
+ * Unknown-error explanation.
+ */
+
+static const char unk[] = "*** unknown regex error code 0x%x ***";
+
+/*
+ * Struct to map among codes, code names, and explanations.
+ */
+
+static const struct rerr {
+    int code;
+    const char *name;
+    const char *explain;
+} rerrs[] = {
+    /* The actual table is built from regex.h */
+#include "regerrs.h"
+    { -1, "", "oops" },		/* explanation special-cased in code */
+};
+
+/*
+ - regerror - the interface to error numbers
+ */
+/* ARGSUSED */
+size_t				/* Actual space needed (including NUL) */
+regerror(
+    int code,			/* Error code, or REG_ATOI or REG_ITOA */
+    const regex_t *preg,	/* Associated regex_t (unused at present) */
+    char *errbuf,		/* Result buffer (unless errbuf_size==0) */
+    size_t errbuf_size)		/* Available space in errbuf, can be 0 */
+{
+    const struct rerr *r;
+    const char *msg;
+    char convbuf[sizeof(unk)+50]; /* 50 = plenty for int */
+    size_t len;
+    int icode;
+
+    switch (code) {
+    case REG_ATOI:		/* Convert name to number */
+	for (r = rerrs; r->code >= 0; r++) {
+	    if (strcmp(r->name, errbuf) == 0) {
+		break;
+	    }
+	}
+	sprintf(convbuf, "%d", r->code); /* -1 for unknown */
+	msg = convbuf;
+	break;
+    case REG_ITOA:		/* Convert number to name */
+	icode = atoi(errbuf);	/* Not our problem if this fails */
+	for (r = rerrs; r->code >= 0; r++) {
+	    if (r->code == icode) {
+		break;
+	    }
+	}
+	if (r->code >= 0) {
+	    msg = r->name;
+	} else {		/* Unknown; tell him the number */
+	    sprintf(convbuf, "REG_%u", (unsigned)icode);
+	    msg = convbuf;
+	}
+	break;
+    default:			/* A real, normal error code */
+	for (r = rerrs; r->code >= 0; r++) {
+	    if (r->code == code) {
+		break;
+	    }
+	}
+	if (r->code >= 0) {
+	    msg = r->explain;
+	} else {		/* Unknown; say so */
+	    sprintf(convbuf, unk, code);
+	    msg = convbuf;
+	}
+	break;
+    }
+
+    len = strlen(msg) + 1;	/* Space needed, including NUL */
+    if (errbuf_size > 0) {
+	if (errbuf_size > len) {
+	    strcpy(errbuf, msg);
+	} else {		/* Truncate to fit */
+	    strncpy(errbuf, msg, errbuf_size-1);
+	    errbuf[errbuf_size-1] = '\0';
+	}
+    }
+
+    return len;
+}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/regerrs.h b/generic/regerrs.h
new file mode 100644
index 0000000..ee203d5
--- /dev/null
+++ b/generic/regerrs.h
@@ -0,0 +1,20 @@
+{ REG_OKAY,	"REG_OKAY",	"no errors detected" },
+{ REG_NOMATCH,	"REG_NOMATCH",	"failed to match" },
+{ REG_BADPAT,	"REG_BADPAT",	"invalid regexp (reg version 0.8)" },
+{ REG_ECOLLATE,	"REG_ECOLLATE",	"invalid collating element" },
+{ REG_ECTYPE,	"REG_ECTYPE",	"invalid character class" },
+{ REG_EESCAPE,	"REG_EESCAPE",	"invalid escape \\ sequence" },
+{ REG_ESUBREG,	"REG_ESUBREG",	"invalid backreference number" },
+{ REG_EBRACK,	"REG_EBRACK",	"brackets [] not balanced" },
+{ REG_EPAREN,	"REG_EPAREN",	"parentheses () not balanced" },
+{ REG_EBRACE,	"REG_EBRACE",	"braces {} not balanced" },
+{ REG_BADBR,	"REG_BADBR",	"invalid repetition count(s)" },
+{ REG_ERANGE,	"REG_ERANGE",	"invalid character range" },
+{ REG_ESPACE,	"REG_ESPACE",	"out of memory" },
+{ REG_BADRPT,	"REG_BADRPT",	"quantifier operand invalid" },
+{ REG_ASSERT,	"REG_ASSERT",	"\"can't happen\" -- you found a bug" },
+{ REG_INVARG,	"REG_INVARG",	"invalid argument to regex function" },
+{ REG_MIXED,	"REG_MIXED",	"character widths of regex and string differ" },
+{ REG_BADOPT,	"REG_BADOPT",	"invalid embedded option" },
+{ REG_ETOOBIG,	"REG_ETOOBIG",	"regular expression is too complex" },
+{ REG_ECOLORS,	"REG_ECOLORS",	"too many colors" },
diff --git a/generic/regex.h b/generic/regex.h
new file mode 100644
index 0000000..8845f72
--- /dev/null
+++ b/generic/regex.h
@@ -0,0 +1,305 @@
+#ifndef _REGEX_H_
+#define	_REGEX_H_	/* never again */
+
+#include "tclInt.h"
+
+/*
+ * regular expressions
+ *
+ * Copyright (c) 1998, 1999 Henry Spencer.  All rights reserved.
+ *
+ * Development of this software was funded, in part, by Cray Research Inc.,
+ * UUNET Communications Services Inc., Sun Microsystems Inc., and Scriptics
+ * Corporation, none of whom are responsible for the results. The author
+ * thanks all of them.
+ *
+ * Redistribution and use in source and binary forms -- with or without
+ * modification -- are permitted for any purpose, provided that
+ * redistributions in source form retain this entire copyright notice and
+ * indicate the origin and nature of any modifications.
+ *
+ * I'd appreciate being given credit for this package in the documentation of
+ * software which uses it, but that is not a requirement.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * HENRY SPENCER BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ * Prototypes etc. marked with "^" within comments get gathered up (and
+ * possibly edited) by the regfwd program and inserted near the bottom of this
+ * file.
+ *
+ * We offer the option of declaring one wide-character version of the RE
+ * functions as well as the char versions. To do that, define __REG_WIDE_T to
+ * the type of wide characters (unfortunately, there is no consensus that
+ * wchar_t is suitable) and __REG_WIDE_COMPILE and __REG_WIDE_EXEC to the
+ * names to be used for the compile and execute functions (suggestion:
+ * re_Xcomp and re_Xexec, where X is a letter suggestive of the wide type,
+ * e.g. re_ucomp and re_uexec for Unicode). For cranky old compilers, it may
+ * be necessary to do something like:
+ * #define	__REG_WIDE_COMPILE(a,b,c,d)	re_Xcomp(a,b,c,d)
+ * #define	__REG_WIDE_EXEC(a,b,c,d,e,f,g)	re_Xexec(a,b,c,d,e,f,g)
+ * rather than just #defining the names as parameterless macros.
+ *
+ * For some specialized purposes, it may be desirable to suppress the
+ * declarations of the "front end" functions, regcomp() and regexec(), or of
+ * the char versions of the compile and execute functions. To suppress the
+ * front-end functions, define __REG_NOFRONT. To suppress the char versions,
+ * define __REG_NOCHAR.
+ *
+ * The right place to do those defines (and some others you may want, see
+ * below) would be <sys/types.h>. If you don't have control of that file, the
+ * right place to add your own defines to this file is marked below. This is
+ * normally done automatically, by the makefile and regmkhdr, based on the
+ * contents of regcustom.h.
+ */
+
+/*
+ * voodoo for C++
+ */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Add your own defines, if needed, here.
+ */
+
+/*
+ * Location where a chunk of regcustom.h is automatically spliced into this
+ * file (working from its prototype, regproto.h).
+ */
+
+/* --- begin --- */
+/* ensure certain things don't sneak in from system headers */
+#ifdef __REG_WIDE_T
+#undef __REG_WIDE_T
+#endif
+#ifdef __REG_WIDE_COMPILE
+#undef __REG_WIDE_COMPILE
+#endif
+#ifdef __REG_WIDE_EXEC
+#undef __REG_WIDE_EXEC
+#endif
+#ifdef __REG_REGOFF_T
+#undef __REG_REGOFF_T
+#endif
+#ifdef __REG_NOFRONT
+#undef __REG_NOFRONT
+#endif
+#ifdef __REG_NOCHAR
+#undef __REG_NOCHAR
+#endif
+/* interface types */
+#define	__REG_WIDE_T	Tcl_UniChar
+#define	__REG_REGOFF_T	long	/* not really right, but good enough... */
+/* names and declarations */
+#define	__REG_WIDE_COMPILE	TclReComp
+#define	__REG_WIDE_EXEC		TclReExec
+#define	__REG_NOFRONT		/* don't want regcomp() and regexec() */
+#define	__REG_NOCHAR		/* or the char versions */
+#define	regfree		TclReFree
+#define	regerror	TclReError
+/* --- end --- */
+
+/*
+ * interface types etc.
+ */
+
+/*
+ * regoff_t has to be large enough to hold either off_t or ssize_t, and must
+ * be signed; it's only a guess that long is suitable, so we offer
+ * <sys/types.h> an override.
+ */
+#ifdef __REG_REGOFF_T
+typedef __REG_REGOFF_T regoff_t;
+#else
+typedef long regoff_t;
+#endif
+
+/*
+ * other interface types
+ */
+
+/* the biggie, a compiled RE (or rather, a front end to same) */
+typedef struct {
+    int re_magic;		/* magic number */
+    size_t re_nsub;		/* number of subexpressions */
+    long re_info;		/* information about RE */
+#define	REG_UBACKREF		000001
+#define	REG_ULOOKAHEAD		000002
+#define	REG_UBOUNDS		000004
+#define	REG_UBRACES		000010
+#define	REG_UBSALNUM		000020
+#define	REG_UPBOTCH		000040
+#define	REG_UBBS		000100
+#define	REG_UNONPOSIX		000200
+#define	REG_UUNSPEC		000400
+#define	REG_UUNPORT		001000
+#define	REG_ULOCALE		002000
+#define	REG_UEMPTYMATCH		004000
+#define	REG_UIMPOSSIBLE		010000
+#define	REG_USHORTEST		020000
+    int re_csize;		/* sizeof(character) */
+    char *re_endp;		/* backward compatibility kludge */
+    /* the rest is opaque pointers to hidden innards */
+    char *re_guts;		/* `char *' is more portable than `void *' */
+    char *re_fns;
+} regex_t;
+
+/* result reporting (may acquire more fields later) */
+typedef struct {
+    regoff_t rm_so;		/* start of substring */
+    regoff_t rm_eo;		/* end of substring */
+} regmatch_t;
+
+/* supplementary control and reporting */
+typedef struct {
+    regmatch_t rm_extend;	/* see REG_EXPECT */
+} rm_detail_t;
+
+/*
+ * compilation
+ ^ #ifndef __REG_NOCHAR
+ ^ int re_comp(regex_t *, const char *, size_t, int);
+ ^ #endif
+ ^ #ifndef __REG_NOFRONT
+ ^ int regcomp(regex_t *, const char *, int);
+ ^ #endif
+ ^ #ifdef __REG_WIDE_T
+ ^ int __REG_WIDE_COMPILE(regex_t *, const __REG_WIDE_T *, size_t, int);
+ ^ #endif
+ */
+#define	REG_BASIC	000000	/* BREs (convenience) */
+#define	REG_EXTENDED	000001	/* EREs */
+#define	REG_ADVF	000002	/* advanced features in EREs */
+#define	REG_ADVANCED	000003	/* AREs (which are also EREs) */
+#define	REG_QUOTE	000004	/* no special characters, none */
+#define	REG_NOSPEC	REG_QUOTE	/* historical synonym */
+#define	REG_ICASE	000010	/* ignore case */
+#define	REG_NOSUB	000020	/* don't care about subexpressions */
+#define	REG_EXPANDED	000040	/* expanded format, white space & comments */
+#define	REG_NLSTOP	000100	/* \n doesn't match . or [^ ] */
+#define	REG_NLANCH	000200	/* ^ matches after \n, $ before */
+#define	REG_NEWLINE	000300	/* newlines are line terminators */
+#define	REG_PEND	000400	/* ugh -- backward-compatibility hack */
+#define	REG_EXPECT	001000	/* report details on partial/limited matches */
+#define	REG_BOSONLY	002000	/* temporary kludge for BOS-only matches */
+#define	REG_DUMP	004000	/* none of your business :-) */
+#define	REG_FAKE	010000	/* none of your business :-) */
+#define	REG_PROGRESS	020000	/* none of your business :-) */
+
+/*
+ * execution
+ ^ #ifndef __REG_NOCHAR
+ ^ int re_exec(regex_t *, const char *, size_t,
+ ^				rm_detail_t *, size_t, regmatch_t [], int);
+ ^ #endif
+ ^ #ifndef __REG_NOFRONT
+ ^ int regexec(regex_t *, const char *, size_t, regmatch_t [], int);
+ ^ #endif
+ ^ #ifdef __REG_WIDE_T
+ ^ int __REG_WIDE_EXEC(regex_t *, const __REG_WIDE_T *, size_t,
+ ^				rm_detail_t *, size_t, regmatch_t [], int);
+ ^ #endif
+ */
+#define	REG_NOTBOL	0001	/* BOS is not BOL */
+#define	REG_NOTEOL	0002	/* EOS is not EOL */
+#define	REG_STARTEND	0004	/* backward compatibility kludge */
+#define	REG_FTRACE	0010	/* none of your business */
+#define	REG_MTRACE	0020	/* none of your business */
+#define	REG_SMALL	0040	/* none of your business */
+
+/*
+ * misc generics (may be more functions here eventually)
+ ^ void regfree(regex_t *);
+ */
+
+/*
+ * error reporting
+ * Be careful if modifying the list of error codes -- the table used by
+ * regerror() is generated automatically from this file!
+ *
+ * Note that there is no wide-char variant of regerror at this time; what kind
+ * of character is used for error reports is independent of what kind is used
+ * in matching.
+ *
+ ^ extern size_t regerror(int, const regex_t *, char *, size_t);
+ */
+#define	REG_OKAY	 0	/* no errors detected */
+#define	REG_NOMATCH	 1	/* failed to match */
+#define	REG_BADPAT	 2	/* invalid regexp */
+#define	REG_ECOLLATE	 3	/* invalid collating element */
+#define	REG_ECTYPE	 4	/* invalid character class */
+#define	REG_EESCAPE	 5	/* invalid escape \ sequence */
+#define	REG_ESUBREG	 6	/* invalid backreference number */
+#define	REG_EBRACK	 7	/* brackets [] not balanced */
+#define	REG_EPAREN	 8	/* parentheses () not balanced */
+#define	REG_EBRACE	 9	/* braces {} not balanced */
+#define	REG_BADBR	10	/* invalid repetition count(s) */
+#define	REG_ERANGE	11	/* invalid character range */
+#define	REG_ESPACE	12	/* out of memory */
+#define	REG_BADRPT	13	/* quantifier operand invalid */
+#define	REG_ASSERT	15	/* "can't happen" -- you found a bug */
+#define	REG_INVARG	16	/* invalid argument to regex function */
+#define	REG_MIXED	17	/* character widths of regex and string differ */
+#define	REG_BADOPT	18	/* invalid embedded option */
+#define	REG_ETOOBIG	19	/* regular expression is too complex */
+#define	REG_ECOLORS	20	/* too many colors */
+/* two specials for debugging and testing */
+#define	REG_ATOI	101	/* convert error-code name to number */
+#define	REG_ITOA	102	/* convert error-code number to name */
+
+/*
+ * the prototypes, as possibly munched by regfwd
+ */
+/* =====^!^===== begin forwards =====^!^===== */
+/* automatically gathered by fwd; do not hand-edit */
+/* === regproto.h === */
+#ifndef __REG_NOCHAR
+int re_comp(regex_t *, const char *, size_t, int);
+#endif
+#ifndef __REG_NOFRONT
+int regcomp(regex_t *, const char *, int);
+#endif
+#ifdef __REG_WIDE_T
+MODULE_SCOPE int __REG_WIDE_COMPILE(regex_t *, const __REG_WIDE_T *, size_t, int);
+#endif
+#ifndef __REG_NOCHAR
+int re_exec(regex_t *, const char *, size_t, rm_detail_t *, size_t, regmatch_t [], int);
+#endif
+#ifndef __REG_NOFRONT
+int regexec(regex_t *, const char *, size_t, regmatch_t [], int);
+#endif
+#ifdef __REG_WIDE_T
+MODULE_SCOPE int __REG_WIDE_EXEC(regex_t *, const __REG_WIDE_T *, size_t, rm_detail_t *, size_t, regmatch_t [], int);
+#endif
+MODULE_SCOPE void regfree(regex_t *);
+MODULE_SCOPE size_t regerror(int, const regex_t *, char *, size_t);
+/* automatically gathered by fwd; do not hand-edit */
+/* =====^!^===== end forwards =====^!^===== */
+
+/*
+ * more C++ voodoo
+ */
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/regexec.c b/generic/regexec.c
new file mode 100644
index 0000000..6d12827
--- /dev/null
+++ b/generic/regexec.c
@@ -0,0 +1,1335 @@
+/*
+ * re_*exec and friends - match REs
+ *
+ * Copyright (c) 1998, 1999 Henry Spencer.  All rights reserved.
+ *
+ * Development of this software was funded, in part, by Cray Research Inc.,
+ * UUNET Communications Services Inc., Sun Microsystems Inc., and Scriptics
+ * Corporation, none of whom are responsible for the results.  The author
+ * thanks all of them.
+ *
+ * Redistribution and use in source and binary forms -- with or without
+ * modification -- are permitted for any purpose, provided that
+ * redistributions in source form retain this entire copyright notice and
+ * indicate the origin and nature of any modifications.
+ *
+ * I'd appreciate being given credit for this package in the documentation of
+ * software which uses it, but that is not a requirement.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * HENRY SPENCER BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "regguts.h"
+
+/*
+ * Lazy-DFA representation.
+ */
+
+struct arcp {			/* "pointer" to an outarc */
+    struct sset *ss;
+    color co;
+};
+
+struct sset {			/* state set */
+    unsigned *states;		/* pointer to bitvector */
+    unsigned hash;		/* hash of bitvector */
+#define	HASH(bv, nw)	(((nw) == 1) ? *(bv) : hash(bv, nw))
+#define	HIT(h,bv,ss,nw)	((ss)->hash == (h) && ((nw) == 1 || \
+	memcmp(VS(bv), VS((ss)->states), (nw)*sizeof(unsigned)) == 0))
+    int flags;
+#define	STARTER		01	/* the initial state set */
+#define	POSTSTATE	02	/* includes the goal state */
+#define	LOCKED		04	/* locked in cache */
+#define	NOPROGRESS	010	/* zero-progress state set */
+    struct arcp ins;		/* chain of inarcs pointing here */
+    chr *lastseen;		/* last entered on arrival here */
+    struct sset **outs;		/* outarc vector indexed by color */
+    struct arcp *inchain;	/* chain-pointer vector for outarcs */
+};
+
+struct dfa {
+    int nssets;			/* size of cache */
+    int nssused;		/* how many entries occupied yet */
+    int nstates;		/* number of states */
+    int ncolors;		/* length of outarc and inchain vectors */
+    int wordsper;		/* length of state-set bitvectors */
+    struct sset *ssets;		/* state-set cache */
+    unsigned *statesarea;	/* bitvector storage */
+    unsigned *work;		/* pointer to work area within statesarea */
+    struct sset **outsarea;	/* outarc-vector storage */
+    struct arcp *incarea;	/* inchain storage */
+    struct cnfa *cnfa;
+    struct colormap *cm;
+    chr *lastpost;		/* location of last cache-flushed success */
+    chr *lastnopr;		/* location of last cache-flushed NOPROGRESS */
+    struct sset *search;	/* replacement-search-pointer memory */
+    int cptsmalloced;		/* were the areas individually malloced? */
+    char *mallocarea;		/* self, or master malloced area, or NULL */
+};
+
+#define	WORK	1		/* number of work bitvectors needed */
+
+/*
+ * Setup for non-malloc allocation for small cases.
+ */
+
+#define	FEWSTATES	20	/* must be less than UBITS */
+#define	FEWCOLORS	15
+struct smalldfa {
+    struct dfa dfa;
+    struct sset ssets[FEWSTATES*2];
+    unsigned statesarea[FEWSTATES*2 + WORK];
+    struct sset *outsarea[FEWSTATES*2 * FEWCOLORS];
+    struct arcp incarea[FEWSTATES*2 * FEWCOLORS];
+};
+#define	DOMALLOC	((struct smalldfa *)NULL)	/* force malloc */
+
+/*
+ * Internal variables, bundled for easy passing around.
+ */
+
+struct vars {
+    regex_t *re;
+    struct guts *g;
+    int eflags;			/* copies of arguments */
+    size_t nmatch;
+    regmatch_t *pmatch;
+    rm_detail_t *details;
+    chr *start;			/* start of string */
+    chr *stop;			/* just past end of string */
+    int err;			/* error code if any (0 none) */
+    struct dfa **subdfas;	/* per-subre DFAs */
+    struct smalldfa dfa1;
+    struct smalldfa dfa2;
+};
+#define	VISERR(vv) ((vv)->err != 0)	/* have we seen an error yet? */
+#define	ISERR()	VISERR(v)
+#define VERR(vv,e) ((vv)->err = ((vv)->err ? (vv)->err : (e)))
+#define	ERR(e)	VERR(v, e)	/* record an error */
+#define	NOERR()	{if (ISERR()) return v->err;}	/* if error seen, return it */
+#define	OFF(p)	((p) - v->start)
+#define	LOFF(p)	((long)OFF(p))
+
+/*
+ * forward declarations
+ */
+/* =====^!^===== begin forwards =====^!^===== */
+/* automatically gathered by fwd; do not hand-edit */
+/* === regexec.c === */
+int exec(regex_t *, const chr *, size_t, rm_detail_t *, size_t, regmatch_t [], int);
+static struct dfa *getsubdfa(struct vars *, struct subre *);
+static int simpleFind(struct vars *const, struct cnfa *const, struct colormap *const);
+static int complicatedFind(struct vars *const, struct cnfa *const, struct colormap *const);
+static int complicatedFindLoop(struct vars *const, struct cnfa *const, struct colormap *const, struct dfa *const, struct dfa *const, chr **const);
+static void zapallsubs(regmatch_t *const, const size_t);
+static void zaptreesubs(struct vars *const, struct subre *const);
+static void subset(struct vars *const, struct subre *const, chr *const, chr *const);
+static int cdissect(struct vars *, struct subre *, chr *, chr *);
+static int ccondissect(struct vars *, struct subre *, chr *, chr *);
+static int crevcondissect(struct vars *, struct subre *, chr *, chr *);
+static int cbrdissect(struct vars *, struct subre *, chr *, chr *);
+static int caltdissect(struct vars *, struct subre *, chr *, chr *);
+static int citerdissect(struct vars *, struct subre *, chr *, chr *);
+static int creviterdissect(struct vars *, struct subre *, chr *, chr *);
+/* === rege_dfa.c === */
+static chr *longest(struct vars *const, struct dfa *const, chr *const, chr *const, int *const);
+static chr *shortest(struct vars *const, struct dfa *const, chr *const, chr *const, chr *const, chr **const, int *const);
+static chr *lastCold(struct vars *const, struct dfa *const);
+static struct dfa *newDFA(struct vars *const, struct cnfa *const, struct colormap *const, struct smalldfa *);
+static void freeDFA(struct dfa *const);
+static unsigned hash(unsigned *const, const int);
+static struct sset *initialize(struct vars *const, struct dfa *const, chr *const);
+static struct sset *miss(struct vars *const, struct dfa *const, struct sset *const, const pcolor, chr *const, chr *const);
+static int checkLAConstraint(struct vars *const, struct cnfa *const, chr *const, const pcolor);
+static struct sset *getVacantSS(struct vars *const, struct dfa *const, chr *const, chr *const);
+static struct sset *pickNextSS(struct vars *const, struct dfa *const, chr *const, chr *const);
+/* automatically gathered by fwd; do not hand-edit */
+/* =====^!^===== end forwards =====^!^===== */
+
+/*
+ - exec - match regular expression
+ ^ int exec(regex_t *, const chr *, size_t, rm_detail_t *,
+ ^					size_t, regmatch_t [], int);
+ */
+int
+exec(
+    regex_t *re,
+    const chr *string,
+    size_t len,
+    rm_detail_t *details,
+    size_t nmatch,
+    regmatch_t pmatch[],
+    int flags)
+{
+    AllocVars(v);
+    int st, backref;
+    size_t n;
+    size_t i;
+#define	LOCALMAT	20
+    regmatch_t mat[LOCALMAT];
+#define LOCALDFAS	40
+    struct dfa *subdfas[LOCALDFAS];
+
+    /*
+     * Sanity checks.
+     */
+
+    if (re == NULL || string == NULL || re->re_magic != REMAGIC) {
+	FreeVars(v);
+	return REG_INVARG;
+    }
+    if (re->re_csize != sizeof(chr)) {
+	FreeVars(v);
+	return REG_MIXED;
+    }
+
+    /*
+     * Setup.
+     */
+
+    v->re = re;
+    v->g = (struct guts *)re->re_guts;
+    if ((v->g->cflags&REG_EXPECT) && details == NULL) {
+	FreeVars(v);
+	return REG_INVARG;
+    }
+    if (v->g->info&REG_UIMPOSSIBLE) {
+	FreeVars(v);
+	return REG_NOMATCH;
+    }
+    backref = (v->g->info&REG_UBACKREF) ? 1 : 0;
+    v->eflags = flags;
+    if (v->g->cflags&REG_NOSUB) {
+	nmatch = 0;		/* override client */
+    }
+    v->nmatch = nmatch;
+    if (backref) {
+	/*
+	 * Need work area.
+	 */
+
+	if (v->g->nsub + 1 <= LOCALMAT) {
+	    v->pmatch = mat;
+	} else {
+	    v->pmatch = (regmatch_t *)
+		    MALLOC((v->g->nsub + 1) * sizeof(regmatch_t));
+	}
+	if (v->pmatch == NULL) {
+	    FreeVars(v);
+	    return REG_ESPACE;
+	}
+	v->nmatch = v->g->nsub + 1;
+    } else {
+	v->pmatch = pmatch;
+    }
+    v->details = details;
+    v->start = (chr *)string;
+    v->stop = (chr *)string + len;
+    v->err = 0;
+    assert(v->g->ntree >= 0);
+    n = (size_t) v->g->ntree;
+    if (n <= LOCALDFAS)
+	v->subdfas = subdfas;
+    else
+	v->subdfas = (struct dfa **) MALLOC(n * sizeof(struct dfa *));
+    if (v->subdfas == NULL) {
+	if (v->pmatch != pmatch && v->pmatch != mat)
+	    FREE(v->pmatch);
+	FreeVars(v);
+	return REG_ESPACE;
+    }
+    for (i = 0; i < n; i++)
+	v->subdfas[i] = NULL;
+
+    /*
+     * Do it.
+     */
+
+    assert(v->g->tree != NULL);
+    if (backref) {
+	st = complicatedFind(v, &v->g->tree->cnfa, &v->g->cmap);
+    } else {
+	st = simpleFind(v, &v->g->tree->cnfa, &v->g->cmap);
+    }
+
+    /*
+     * Copy (portion of) match vector over if necessary.
+     */
+
+    if (st == REG_OKAY && v->pmatch != pmatch && nmatch > 0) {
+	zapallsubs(pmatch, nmatch);
+	n = (nmatch < v->nmatch) ? nmatch : v->nmatch;
+	memcpy(VS(pmatch), VS(v->pmatch), n*sizeof(regmatch_t));
+    }
+
+    /*
+     * Clean up.
+     */
+
+    if (v->pmatch != pmatch && v->pmatch != mat) {
+	FREE(v->pmatch);
+    }
+    n = (size_t) v->g->ntree;
+    for (i = 0; i < n; i++) {
+	if (v->subdfas[i] != NULL)
+	    freeDFA(v->subdfas[i]);
+    }
+    if (v->subdfas != subdfas)
+	FREE(v->subdfas);
+    FreeVars(v);
+    return st;
+}
+
+/*
+ - getsubdfa - create or re-fetch the DFA for a subre node
+ * We only need to create the DFA once per overall regex execution.
+ * The DFA will be freed by the cleanup step in exec().
+ */
+static struct dfa *
+getsubdfa(struct vars * v,
+	  struct subre * t)
+{
+    if (v->subdfas[t->id] == NULL) {
+	v->subdfas[t->id] = newDFA(v, &t->cnfa, &v->g->cmap, DOMALLOC);
+	if (ISERR())
+	    return NULL;
+    }
+    return v->subdfas[t->id];
+}
+
+/*
+ - simpleFind - find a match for the main NFA (no-complications case)
+ ^ static int simpleFind(struct vars *, struct cnfa *, struct colormap *);
+ */
+static int
+simpleFind(
+    struct vars *const v,
+    struct cnfa *const cnfa,
+    struct colormap *const cm)
+{
+    struct dfa *s, *d;
+    chr *begin, *end = NULL;
+    chr *cold;
+    chr *open, *close;		/* Open and close of range of possible
+				 * starts */
+    int hitend;
+    int shorter = (v->g->tree->flags&SHORTER) ? 1 : 0;
+
+    /*
+     * First, a shot with the search RE.
+     */
+
+    s = newDFA(v, &v->g->search, cm, &v->dfa1);
+    assert(!(ISERR() && s != NULL));
+    NOERR();
+    MDEBUG(("\nsearch at %ld\n", LOFF(v->start)));
+    cold = NULL;
+    close = shortest(v, s, v->start, v->start, v->stop, &cold, NULL);
+    freeDFA(s);
+    NOERR();
+    if (v->g->cflags&REG_EXPECT) {
+	assert(v->details != NULL);
+	if (cold != NULL) {
+	    v->details->rm_extend.rm_so = OFF(cold);
+	} else {
+	    v->details->rm_extend.rm_so = OFF(v->stop);
+	}
+	v->details->rm_extend.rm_eo = OFF(v->stop);	/* unknown */
+    }
+    if (close == NULL) {	/* not found */
+	return REG_NOMATCH;
+    }
+    if (v->nmatch == 0) {	/* found, don't need exact location */
+	return REG_OKAY;
+    }
+
+    /*
+     * Find starting point and match.
+     */
+
+    assert(cold != NULL);
+    open = cold;
+    cold = NULL;
+    MDEBUG(("between %ld and %ld\n", LOFF(open), LOFF(close)));
+    d = newDFA(v, cnfa, cm, &v->dfa1);
+    assert(!(ISERR() && d != NULL));
+    NOERR();
+    for (begin = open; begin <= close; begin++) {
+	MDEBUG(("\nfind trying at %ld\n", LOFF(begin)));
+	if (shorter) {
+	    end = shortest(v, d, begin, begin, v->stop, NULL, &hitend);
+	} else {
+	    end = longest(v, d, begin, v->stop, &hitend);
+	}
+	if (ISERR()) {
+	    freeDFA(d);
+	    return v->err;
+	}
+	if (hitend && cold == NULL) {
+	    cold = begin;
+	}
+	if (end != NULL) {
+	    break;		/* NOTE BREAK OUT */
+	}
+    }
+    assert(end != NULL);	/* search RE succeeded so loop should */
+    freeDFA(d);
+
+    /*
+     * And pin down details.
+     */
+
+    assert(v->nmatch > 0);
+    v->pmatch[0].rm_so = OFF(begin);
+    v->pmatch[0].rm_eo = OFF(end);
+    if (v->g->cflags&REG_EXPECT) {
+	if (cold != NULL) {
+	    v->details->rm_extend.rm_so = OFF(cold);
+	} else {
+	    v->details->rm_extend.rm_so = OFF(v->stop);
+	}
+	v->details->rm_extend.rm_eo = OFF(v->stop);	/* unknown */
+    }
+    if (v->nmatch == 1) {	/* no need for submatches */
+	return REG_OKAY;
+    }
+
+    /*
+     * Find submatches.
+     */
+
+    zapallsubs(v->pmatch, v->nmatch);
+    return cdissect(v, v->g->tree, begin, end);
+}
+
+/*
+ - complicatedFind - find a match for the main NFA (with complications)
+ ^ static int complicatedFind(struct vars *, struct cnfa *, struct colormap *);
+ */
+static int
+complicatedFind(
+    struct vars *const v,
+    struct cnfa *const cnfa,
+    struct colormap *const cm)
+{
+    struct dfa *s, *d;
+    chr *cold = NULL; /* silence gcc 4 warning */
+    int ret;
+
+    s = newDFA(v, &v->g->search, cm, &v->dfa1);
+    NOERR();
+    d = newDFA(v, cnfa, cm, &v->dfa2);
+    if (ISERR()) {
+	assert(d == NULL);
+	freeDFA(s);
+	return v->err;
+    }
+
+    ret = complicatedFindLoop(v, cnfa, cm, d, s, &cold);
+
+    freeDFA(d);
+    freeDFA(s);
+    NOERR();
+    if (v->g->cflags&REG_EXPECT) {
+	assert(v->details != NULL);
+	if (cold != NULL) {
+	    v->details->rm_extend.rm_so = OFF(cold);
+	} else {
+	    v->details->rm_extend.rm_so = OFF(v->stop);
+	}
+	v->details->rm_extend.rm_eo = OFF(v->stop);	/* unknown */
+    }
+    return ret;
+}
+
+/*
+ - complicatedFindLoop - the heart of complicatedFind
+ ^ static int complicatedFindLoop(struct vars *, struct cnfa *, struct colormap *,
+ ^	struct dfa *, struct dfa *, chr **);
+ */
+static int
+complicatedFindLoop(
+    struct vars *const v,
+    struct cnfa *const cnfa,
+    struct colormap *const cm,
+    struct dfa *const d,
+    struct dfa *const s,
+    chr **const coldp)		/* where to put coldstart pointer */
+{
+    chr *begin, *end;
+    chr *cold;
+    chr *open, *close;		/* Open and close of range of possible
+				 * starts */
+    chr *estart, *estop;
+    int er, hitend;
+    int shorter = v->g->tree->flags&SHORTER;
+
+    assert(d != NULL && s != NULL);
+    cold = NULL;
+    close = v->start;
+    do {
+	MDEBUG(("\ncsearch at %ld\n", LOFF(close)));
+	close = shortest(v, s, close, close, v->stop, &cold, NULL);
+	if (close == NULL) {
+	    break;		/* NOTE BREAK */
+	}
+	assert(cold != NULL);
+	open = cold;
+	cold = NULL;
+	MDEBUG(("cbetween %ld and %ld\n", LOFF(open), LOFF(close)));
+	for (begin = open; begin <= close; begin++) {
+	    MDEBUG(("\ncomplicatedFind trying at %ld\n", LOFF(begin)));
+	    estart = begin;
+	    estop = v->stop;
+	    for (;;) {
+		if (shorter) {
+		    end = shortest(v, d, begin, estart, estop, NULL, &hitend);
+		} else {
+		    end = longest(v, d, begin, estop, &hitend);
+		}
+		if (hitend && cold == NULL) {
+		    cold = begin;
+		}
+		if (end == NULL) {
+		    break;	/* NOTE BREAK OUT */
+		}
+
+		MDEBUG(("tentative end %ld\n", LOFF(end)));
+		zapallsubs(v->pmatch, v->nmatch);
+		er = cdissect(v, v->g->tree, begin, end);
+		if (er == REG_OKAY) {
+		    if (v->nmatch > 0) {
+			v->pmatch[0].rm_so = OFF(begin);
+			v->pmatch[0].rm_eo = OFF(end);
+		    }
+		    *coldp = cold;
+		    return REG_OKAY;
+		}
+		if (er != REG_NOMATCH) {
+		    ERR(er);
+		    *coldp = cold;
+		    return er;
+		}
+		if ((shorter) ? end == estop : end == begin) {
+		    break;
+		}
+
+		/*
+		 * Go around and try again
+		 */
+
+		if (shorter) {
+		    estart = end + 1;
+		} else {
+		    estop = end - 1;
+		}
+	    }
+	}
+    } while (close < v->stop);
+
+    *coldp = cold;
+    return REG_NOMATCH;
+}
+
+/*
+ - zapallsubs - initialize all subexpression matches to "no match"
+ ^ static void zapallsubs(regmatch_t *, size_t);
+ */
+static void
+zapallsubs(
+    regmatch_t *const p,
+    const size_t n)
+{
+    size_t i;
+
+    for (i = n-1; i > 0; i--) {
+	p[i].rm_so = -1;
+	p[i].rm_eo = -1;
+    }
+}
+
+/*
+ - zaptreesubs - initialize subexpressions within subtree to "no match"
+ ^ static void zaptreesubs(struct vars *, struct subre *);
+ */
+static void
+zaptreesubs(
+    struct vars *const v,
+    struct subre *const t)
+{
+    if (t->op == '(') {
+	int n = t->subno;
+	assert(n > 0);
+	if ((size_t) n < v->nmatch) {
+	    v->pmatch[n].rm_so = -1;
+	    v->pmatch[n].rm_eo = -1;
+	}
+    }
+
+    if (t->left != NULL) {
+	zaptreesubs(v, t->left);
+    }
+    if (t->right != NULL) {
+	zaptreesubs(v, t->right);
+    }
+}
+
+/*
+ - subset - set subexpression match data for a successful subre
+ ^ static void subset(struct vars *, struct subre *, chr *, chr *);
+ */
+static void
+subset(
+    struct vars *const v,
+    struct subre *const sub,
+    chr *const begin,
+    chr *const end)
+{
+    int n = sub->subno;
+
+    assert(n > 0);
+    if ((size_t)n >= v->nmatch) {
+	return;
+    }
+
+    MDEBUG(("setting %d\n", n));
+    v->pmatch[n].rm_so = OFF(begin);
+    v->pmatch[n].rm_eo = OFF(end);
+}
+
+/*
+ - cdissect - check backrefs and determine subexpression matches
+ * cdissect recursively processes a subre tree to check matching of backrefs
+ * and/or identify submatch boundaries for capture nodes.  The proposed match
+ * runs from "begin" to "end" (not including "end"), and we are basically
+ * "dissecting" it to see where the submatches are.
+ * Before calling any level of cdissect, the caller must have run the node's
+ * DFA and found that the proposed substring satisfies the DFA.  (We make
+ * the caller do that because in concatenation and iteration nodes, it's
+ * much faster to check all the substrings against the child DFAs before we
+ * recurse.)  Also, caller must have cleared subexpression match data via
+ * zaptreesubs (or zapallsubs at the top level).
+ ^ static int cdissect(struct vars *, struct subre *, chr *, chr *);
+ */
+static int			/* regexec return code */
+cdissect(
+    struct vars *v,
+    struct subre *t,
+    chr *begin,		/* beginning of relevant substring */
+    chr *end)		/* end of same */
+{
+    int er;
+
+    assert(t != NULL);
+    MDEBUG(("cdissect %ld-%ld %c\n", LOFF(begin), LOFF(end), t->op));
+
+    switch (t->op) {
+    case '=':			/* terminal node */
+	assert(t->left == NULL && t->right == NULL);
+	er = REG_OKAY;		/* no action, parent did the work */
+	break;
+    case 'b':			/* back reference */
+	assert(t->left == NULL && t->right == NULL);
+	er = cbrdissect(v, t, begin, end);
+	break;
+    case '.':			/* concatenation */
+	assert(t->left != NULL && t->right != NULL);
+	if (t->left->flags & SHORTER) /* reverse scan */
+	    er = crevcondissect(v, t, begin, end);
+	else
+	    er = ccondissect(v, t, begin, end);
+	break;
+    case '|':			/* alternation */
+	assert(t->left != NULL);
+	er = caltdissect(v, t, begin, end);
+	break;
+    case '*':			/* iteration */
+	assert(t->left != NULL);
+	if (t->left->flags & SHORTER) /* reverse scan */
+	    er = creviterdissect(v, t, begin, end);
+	else
+	    er = citerdissect(v, t, begin, end);
+	break;
+    case '(':			/* capturing */
+	assert(t->left != NULL && t->right == NULL);
+	assert(t->subno > 0);
+	er = cdissect(v, t->left, begin, end);
+	if (er == REG_OKAY) {
+	    subset(v, t, begin, end);
+	}
+	break;
+    default:
+	er = REG_ASSERT;
+	break;
+    }
+
+    /*
+     * We should never have a match failure unless backrefs lurk below;
+     * otherwise, either caller failed to check the DFA, or there's some
+     * inconsistency between the DFA and the node's innards.
+     */
+    assert(er != REG_NOMATCH || (t->flags & BACKR));
+
+    return er;
+}
+
+/*
+ - ccondissect - dissect match for concatenation node
+ ^ static int ccondissect(struct vars *, struct subre *, chr *, chr *);
+ */
+static int			/* regexec return code */
+ccondissect(
+    struct vars *v,
+    struct subre *t,
+    chr *begin,		/* beginning of relevant substring */
+    chr *end)		/* end of same */
+{
+    struct dfa *d, *d2;
+    chr *mid;
+
+    assert(t->op == '.');
+    assert(t->left != NULL && t->left->cnfa.nstates > 0);
+    assert(t->right != NULL && t->right->cnfa.nstates > 0);
+    assert(!(t->left->flags & SHORTER));
+
+    d = getsubdfa(v, t->left);
+    NOERR();
+    d2 = getsubdfa(v, t->right);
+    NOERR();
+
+    MDEBUG(("cConcat %d\n", t->id));
+
+    /*
+     * Pick a tentative midpoint.
+     */
+    mid = longest(v, d, begin, end, (int *) NULL);
+    if (mid == NULL) {
+	return REG_NOMATCH;
+    }
+    MDEBUG(("tentative midpoint %ld\n", LOFF(mid)));
+
+    /*
+     * Iterate until satisfaction or failure.
+     */
+
+    for (;;) {
+	/*
+	 * Try this midpoint on for size.
+	 */
+
+	if (longest(v, d2, mid, end, NULL) == end) {
+	    int er = cdissect(v, t->left, begin, mid);
+
+	    if (er == REG_OKAY) {
+		er = cdissect(v, t->right, mid, end);
+		if (er == REG_OKAY) {
+		    /*
+		     * Satisfaction.
+		     */
+
+		    MDEBUG(("successful\n"));
+		    return REG_OKAY;
+		}
+	    }
+	    if (er != REG_NOMATCH) {
+		return er;
+	    }
+	}
+
+	/*
+	 * That midpoint didn't work, find a new one.
+	 */
+
+	if (mid == begin) {
+	    /*
+	     * All possibilities exhausted.
+	     */
+
+	    MDEBUG(("%d no midpoint\n", t->id));
+	    return REG_NOMATCH;
+	}
+	mid = longest(v, d, begin, mid-1, NULL);
+	if (mid == NULL) {
+	    /*
+	     * Failed to find a new one.
+	     */
+
+	    MDEBUG(("%d failed midpoint\n", t->id));
+	    return REG_NOMATCH;
+	}
+	MDEBUG(("%d: new midpoint %ld\n", t->id, LOFF(mid)));
+	zaptreesubs(v, t->left);
+	zaptreesubs(v, t->right);
+    }
+}
+
+/*
+ - crevcondissect - dissect match for concatenation node, shortest-first
+ ^ static int crevcondissect(struct vars *, struct subre *, chr *, chr *);
+ */
+static int			/* regexec return code */
+crevcondissect(
+    struct vars *v,
+    struct subre *t,
+    chr *begin,		/* beginning of relevant substring */
+    chr *end)		/* end of same */
+{
+    struct dfa *d, *d2;
+    chr *mid;
+
+    assert(t->op == '.');
+    assert(t->left != NULL && t->left->cnfa.nstates > 0);
+    assert(t->right != NULL && t->right->cnfa.nstates > 0);
+    assert(t->left->flags&SHORTER);
+
+    d = getsubdfa(v, t->left);
+    NOERR();
+    d2 = getsubdfa(v, t->right);
+    NOERR();
+
+    MDEBUG(("crevcon %d\n", t->id));
+
+    /*
+     * Pick a tentative midpoint.
+     */
+
+    mid = shortest(v, d, begin, begin, end, (chr **) NULL, (int *) NULL);
+    if (mid == NULL) {
+	return REG_NOMATCH;
+    }
+    MDEBUG(("tentative midpoint %ld\n", LOFF(mid)));
+
+    /*
+     * Iterate until satisfaction or failure.
+     */
+
+    for (;;) {
+	/*
+	 * Try this midpoint on for size.
+	 */
+
+	if (longest(v, d2, mid, end, NULL) == end) {
+	    int er = cdissect(v, t->left, begin, mid);
+
+	    if (er == REG_OKAY) {
+		er = cdissect(v, t->right, mid, end);
+		if (er == REG_OKAY) {
+		    /*
+		     * Satisfaction.
+		     */
+
+		    MDEBUG(("successful\n"));
+		    return REG_OKAY;
+		}
+	    }
+	    if (er != REG_NOMATCH) {
+		return er;
+	    }
+	}
+
+	/*
+	 * That midpoint didn't work, find a new one.
+	 */
+
+	if (mid == end) {
+	    /*
+	     * All possibilities exhausted.
+	     */
+
+	    MDEBUG(("%d no midpoint\n", t->id));
+	    return REG_NOMATCH;
+	}
+	mid = shortest(v, d, begin, mid+1, end, NULL, NULL);
+	if (mid == NULL) {
+	    /*
+	     * Failed to find a new one.
+	     */
+
+	    MDEBUG(("%d failed midpoint\n", t->id));
+	    return REG_NOMATCH;
+	}
+	MDEBUG(("%d: new midpoint %ld\n", t->id, LOFF(mid)));
+	zaptreesubs(v, t->left);
+	zaptreesubs(v, t->right);
+    }
+}
+
+/*
+ - cbrdissect - dissect match for backref node
+ ^ static int cbrdissect(struct vars *, struct subre *, chr *, chr *);
+ */
+static int			/* regexec return code */
+cbrdissect(
+    struct vars *v,
+    struct subre *t,
+    chr *begin,		/* beginning of relevant substring */
+    chr *end)		/* end of same */
+{
+    int n = t->subno, min = t->min, max = t->max;
+    size_t numreps;
+    size_t tlen;
+    size_t brlen;
+    chr *brstring;
+    chr *p;
+
+    assert(t != NULL);
+    assert(t->op == 'b');
+    assert(n >= 0);
+    assert((size_t)n < v->nmatch);
+
+    MDEBUG(("cbackref n%d %d{%d-%d}\n", t->id, n, min, max));
+
+    /* get the backreferenced string */
+    if (v->pmatch[n].rm_so == -1) {
+	return REG_NOMATCH;
+    }
+    brstring = v->start + v->pmatch[n].rm_so;
+    brlen = v->pmatch[n].rm_eo - v->pmatch[n].rm_so;
+
+    /* special cases for zero-length strings */
+    if (brlen == 0) {
+	/*
+	 * matches only if target is zero length, but any number of
+	 * repetitions can be considered to be present
+	 */
+	if (begin == end && min <= max) {
+	    MDEBUG(("cbackref matched trivially\n"));
+	    return REG_OKAY;
+	}
+	return REG_NOMATCH;
+    }
+    if (begin == end) {
+	/* matches only if zero repetitions are okay */
+	if (min == 0) {
+	    MDEBUG(("cbackref matched trivially\n"));
+	    return REG_OKAY;
+	}
+	return REG_NOMATCH;
+    }
+
+    /*
+     * check target length to see if it could possibly be an allowed number of
+     * repetitions of brstring
+     */
+
+    assert(end > begin);
+    tlen = end - begin;
+    if (tlen % brlen != 0)
+	return REG_NOMATCH;
+    numreps = tlen / brlen;
+    if (numreps < (size_t)min || (numreps > (size_t)max && max != DUPINF))
+	return REG_NOMATCH;
+
+    /* okay, compare the actual string contents */
+    p = begin;
+    while (numreps-- > 0) {
+	if ((*v->g->compare) (brstring, p, brlen) != 0)
+	    return REG_NOMATCH;
+	p += brlen;
+    }
+
+    MDEBUG(("cbackref matched\n"));
+    return REG_OKAY;
+}
+
+/*
+ - caltdissect - dissect match for alternation node
+ ^ static int caltdissect(struct vars *, struct subre *, chr *, chr *);
+ */
+static int			/* regexec return code */
+caltdissect(
+    struct vars *v,
+    struct subre *t,
+    chr *begin,		/* beginning of relevant substring */
+    chr *end)		/* end of same */
+{
+    struct dfa *d;
+    int er;
+
+    /* We loop, rather than tail-recurse, to handle a chain of alternatives */
+    while (t != NULL) {
+	assert(t->op == '|');
+	assert(t->left != NULL && t->left->cnfa.nstates > 0);
+
+	MDEBUG(("calt n%d\n", t->id));
+
+	d = getsubdfa(v, t->left);
+	NOERR();
+	if (longest(v, d, begin, end, (int *) NULL) == end) {
+	    MDEBUG(("calt matched\n"));
+	    er = cdissect(v, t->left, begin, end);
+	    if (er != REG_NOMATCH) {
+		return er;
+	    }
+	}
+
+	t = t->right;
+    }
+
+    return REG_NOMATCH;
+}
+
+/*
+ - citerdissect - dissect match for iteration node
+ ^ static int citerdissect(struct vars *, struct subre *, chr *, chr *);
+ */
+static int			/* regexec return code */
+citerdissect(struct vars * v,
+	     struct subre * t,
+	     chr *begin,	/* beginning of relevant substring */
+	     chr *end)		/* end of same */
+{
+    struct dfa *d;
+    chr	  **endpts;
+    chr	   *limit;
+    int		min_matches;
+    size_t	max_matches;
+    int		nverified;
+    int		k;
+    int		i;
+    int		er;
+
+    assert(t->op == '*');
+    assert(t->left != NULL && t->left->cnfa.nstates > 0);
+    assert(!(t->left->flags & SHORTER));
+    assert(begin <= end);
+
+    /*
+     * If zero matches are allowed, and target string is empty, just declare
+     * victory.  OTOH, if target string isn't empty, zero matches can't work
+     * so we pretend the min is 1.
+     */
+    min_matches = t->min;
+    if (min_matches <= 0) {
+	if (begin == end)
+	    return REG_OKAY;
+	min_matches = 1;
+    }
+
+    /*
+     * We need workspace to track the endpoints of each sub-match.  Normally
+     * we consider only nonzero-length sub-matches, so there can be at most
+     * end-begin of them.  However, if min is larger than that, we will also
+     * consider zero-length sub-matches in order to find enough matches.
+     *
+     * For convenience, endpts[0] contains the "begin" pointer and we store
+     * sub-match endpoints in endpts[1..max_matches].
+     */
+    max_matches = end - begin;
+    if (max_matches > (size_t)t->max && t->max != DUPINF)
+	max_matches = t->max;
+    if (max_matches < (size_t)min_matches)
+	max_matches = min_matches;
+    endpts = (chr **) MALLOC((max_matches + 1) * sizeof(chr *));
+    if (endpts == NULL)
+	return REG_ESPACE;
+    endpts[0] = begin;
+
+    d = getsubdfa(v, t->left);
+    if (ISERR()) {
+	FREE(endpts);
+	return v->err;
+    }
+    MDEBUG(("citer %d\n", t->id));
+
+    /*
+     * Our strategy is to first find a set of sub-match endpoints that are
+     * valid according to the child node's DFA, and then recursively dissect
+     * each sub-match to confirm validity.  If any validity check fails,
+     * backtrack the last sub-match and try again.  And, when we next try for
+     * a validity check, we need not recheck any successfully verified
+     * sub-matches that we didn't move the endpoints of.  nverified remembers
+     * how many sub-matches are currently known okay.
+     */
+
+    /* initialize to consider first sub-match */
+    nverified = 0;
+    k = 1;
+    limit = end;
+
+    /* iterate until satisfaction or failure */
+    while (k > 0) {
+	/* try to find an endpoint for the k'th sub-match */
+	endpts[k] = longest(v, d, endpts[k - 1], limit, (int *) NULL);
+	if (endpts[k] == NULL) {
+	    /* no match possible, so see if we can shorten previous one */
+	    k--;
+	    goto backtrack;
+	}
+	MDEBUG(("%d: working endpoint %d: %ld\n",
+		t->id, k, LOFF(endpts[k])));
+
+	/* k'th sub-match can no longer be considered verified */
+	if (nverified >= k)
+	    nverified = k - 1;
+
+	if (endpts[k] != end) {
+	    /* haven't reached end yet, try another iteration if allowed */
+	    if ((size_t)k >= max_matches) {
+		/* must try to shorten some previous match */
+		k--;
+		goto backtrack;
+	    }
+
+	    /* reject zero-length match unless necessary to achieve min */
+	    if (endpts[k] == endpts[k - 1] &&
+		(k >= min_matches || min_matches - k < end - endpts[k]))
+		goto backtrack;
+
+	    k++;
+	    limit = end;
+	    continue;
+	}
+
+	/*
+	 * We've identified a way to divide the string into k sub-matches
+	 * that works so far as the child DFA can tell.  If k is an allowed
+	 * number of matches, start the slow part: recurse to verify each
+	 * sub-match.  We always have k <= max_matches, needn't check that.
+	 */
+	if (k < min_matches)
+	    goto backtrack;
+
+	MDEBUG(("%d: verifying %d..%d\n", t->id, nverified + 1, k));
+
+	for (i = nverified + 1; i <= k; i++) {
+	    zaptreesubs(v, t->left);
+	    er = cdissect(v, t->left, endpts[i - 1], endpts[i]);
+	    if (er == REG_OKAY) {
+		nverified = i;
+		continue;
+	    }
+	    if (er == REG_NOMATCH)
+		break;
+	    /* oops, something failed */
+	    FREE(endpts);
+	    return er;
+	}
+
+	if (i > k) {
+	    /* satisfaction */
+	    MDEBUG(("%d successful\n", t->id));
+	    FREE(endpts);
+	    return REG_OKAY;
+	}
+
+	/* match failed to verify, so backtrack */
+
+    backtrack:
+	/*
+	 * Must consider shorter versions of the current sub-match.  However,
+	 * we'll only ask for a zero-length match if necessary.
+	 */
+	while (k > 0) {
+	    chr	   *prev_end = endpts[k - 1];
+
+	    if (endpts[k] > prev_end) {
+		limit = endpts[k] - 1;
+		if (limit > prev_end ||
+		    (k < min_matches && min_matches - k >= end - prev_end)) {
+		    /* break out of backtrack loop, continue the outer one */
+		    break;
+		}
+	    }
+	    /* can't shorten k'th sub-match any more, consider previous one */
+	    k--;
+	}
+    }
+
+    /* all possibilities exhausted */
+    MDEBUG(("%d failed\n", t->id));
+    FREE(endpts);
+    return REG_NOMATCH;
+}
+
+/*
+ - creviterdissect - dissect match for iteration node, shortest-first
+ ^ static int creviterdissect(struct vars *, struct subre *, chr *, chr *);
+ */
+static int			/* regexec return code */
+creviterdissect(struct vars * v,
+		struct subre * t,
+		chr *begin,	/* beginning of relevant substring */
+		chr *end)	/* end of same */
+{
+    struct dfa *d;
+    chr	  **endpts;
+    chr	   *limit;
+    int		min_matches;
+    size_t	max_matches;
+    int		nverified;
+    int		k;
+    int		i;
+    int		er;
+
+    assert(t->op == '*');
+    assert(t->left != NULL && t->left->cnfa.nstates > 0);
+    assert(t->left->flags & SHORTER);
+    assert(begin <= end);
+
+    /*
+     * If zero matches are allowed, and target string is empty, just declare
+     * victory.  OTOH, if target string isn't empty, zero matches can't work
+     * so we pretend the min is 1.
+     */
+    min_matches = t->min;
+    if (min_matches <= 0) {
+	if (begin == end)
+	    return REG_OKAY;
+	min_matches = 1;
+    }
+
+    /*
+     * We need workspace to track the endpoints of each sub-match.  Normally
+     * we consider only nonzero-length sub-matches, so there can be at most
+     * end-begin of them.  However, if min is larger than that, we will also
+     * consider zero-length sub-matches in order to find enough matches.
+     *
+     * For convenience, endpts[0] contains the "begin" pointer and we store
+     * sub-match endpoints in endpts[1..max_matches].
+     */
+    max_matches = end - begin;
+    if (max_matches > (size_t)t->max && t->max != DUPINF)
+	max_matches = t->max;
+    if (max_matches < (size_t)min_matches)
+	max_matches = min_matches;
+    endpts = (chr **) MALLOC((max_matches + 1) * sizeof(chr *));
+    if (endpts == NULL)
+	return REG_ESPACE;
+    endpts[0] = begin;
+
+    d = getsubdfa(v, t->left);
+    if (ISERR()) {
+	FREE(endpts);
+	return v->err;
+    }
+    MDEBUG(("creviter %d\n", t->id));
+
+    /*
+     * Our strategy is to first find a set of sub-match endpoints that are
+     * valid according to the child node's DFA, and then recursively dissect
+     * each sub-match to confirm validity.  If any validity check fails,
+     * backtrack the last sub-match and try again.  And, when we next try for
+     * a validity check, we need not recheck any successfully verified
+     * sub-matches that we didn't move the endpoints of.  nverified remembers
+     * how many sub-matches are currently known okay.
+     */
+
+    /* initialize to consider first sub-match */
+    nverified = 0;
+    k = 1;
+    limit = begin;
+
+    /* iterate until satisfaction or failure */
+    while (k > 0) {
+	/* disallow zero-length match unless necessary to achieve min */
+	if (limit == endpts[k - 1] &&
+	    limit != end &&
+	    (k >= min_matches || min_matches - k < end - limit))
+	    limit++;
+
+	/* if this is the last allowed sub-match, it must reach to the end */
+	if ((size_t)k >= max_matches)
+	    limit = end;
+
+	/* try to find an endpoint for the k'th sub-match */
+	endpts[k] = shortest(v, d, endpts[k - 1], limit, end,
+			     (chr **) NULL, (int *) NULL);
+	if (endpts[k] == NULL) {
+	    /* no match possible, so see if we can lengthen previous one */
+	    k--;
+	    goto backtrack;
+	}
+	MDEBUG(("%d: working endpoint %d: %ld\n",
+		t->id, k, LOFF(endpts[k])));
+
+	/* k'th sub-match can no longer be considered verified */
+	if (nverified >= k)
+	    nverified = k - 1;
+
+	if (endpts[k] != end) {
+	    /* haven't reached end yet, try another iteration if allowed */
+	    if ((size_t)k >= max_matches) {
+		/* must try to lengthen some previous match */
+		k--;
+		goto backtrack;
+	    }
+
+	    k++;
+	    limit = endpts[k - 1];
+	    continue;
+	}
+
+	/*
+	 * We've identified a way to divide the string into k sub-matches
+	 * that works so far as the child DFA can tell.  If k is an allowed
+	 * number of matches, start the slow part: recurse to verify each
+	 * sub-match.  We always have k <= max_matches, needn't check that.
+	 */
+	if (k < min_matches)
+	    goto backtrack;
+
+	MDEBUG(("%d: verifying %d..%d\n", t->id, nverified + 1, k));
+
+	for (i = nverified + 1; i <= k; i++) {
+	    zaptreesubs(v, t->left);
+	    er = cdissect(v, t->left, endpts[i - 1], endpts[i]);
+	    if (er == REG_OKAY) {
+		nverified = i;
+		continue;
+	    }
+	    if (er == REG_NOMATCH)
+		break;
+	    /* oops, something failed */
+	    FREE(endpts);
+	    return er;
+	}
+
+	if (i > k) {
+	    /* satisfaction */
+	    MDEBUG(("%d successful\n", t->id));
+	    FREE(endpts);
+	    return REG_OKAY;
+	}
+
+	/* match failed to verify, so backtrack */
+
+    backtrack:
+	/*
+	 * Must consider longer versions of the current sub-match.
+	 */
+	while (k > 0) {
+	    if (endpts[k] < end) {
+		limit = endpts[k] + 1;
+		/* break out of backtrack loop, continue the outer one */
+		break;
+	    }
+	    /* can't lengthen k'th sub-match any more, consider previous one */
+	    k--;
+	}
+    }
+
+    /* all possibilities exhausted */
+    MDEBUG(("%d failed\n", t->id));
+    FREE(endpts);
+    return REG_NOMATCH;
+}
+
+#include "rege_dfa.c"
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/regfree.c b/generic/regfree.c
new file mode 100644
index 0000000..b0aaa70
--- /dev/null
+++ b/generic/regfree.c
@@ -0,0 +1,60 @@
+/*
+ * regfree - free an RE
+ *
+ * Copyright (c) 1998, 1999 Henry Spencer.  All rights reserved.
+ *
+ * Development of this software was funded, in part, by Cray Research Inc.,
+ * UUNET Communications Services Inc., Sun Microsystems Inc., and Scriptics
+ * Corporation, none of whom are responsible for the results.  The author
+ * thanks all of them.
+ *
+ * Redistribution and use in source and binary forms -- with or without
+ * modification -- are permitted for any purpose, provided that
+ * redistributions in source form retain this entire copyright notice and
+ * indicate the origin and nature of any modifications.
+ *
+ * I'd appreciate being given credit for this package in the documentation of
+ * software which uses it, but that is not a requirement.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * HENRY SPENCER BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * You might think that this could be incorporated into regcomp.c, and that
+ * would be a reasonable idea... except that this is a generic function (with
+ * a generic name), applicable to all compiled REs regardless of the size of
+ * their characters, whereas the stuff in regcomp.c gets compiled once per
+ * character size.
+ */
+
+#include "regguts.h"
+
+/*
+ - regfree - free an RE (generic function, punts to RE-specific function)
+ *
+ * Ignoring invocation with NULL is a convenience.
+ */
+void
+regfree(
+    regex_t *re)
+{
+    if (re == NULL) {
+	return;
+    }
+    (*((struct fns *)re->re_fns)->free)(re);
+}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/regfronts.c b/generic/regfronts.c
new file mode 100644
index 0000000..088a640
--- /dev/null
+++ b/generic/regfronts.c
@@ -0,0 +1,91 @@
+/*
+ * regcomp and regexec - front ends to re_ routines
+ *
+ * Mostly for implementation of backward-compatibility kludges. Note that
+ * these routines exist ONLY in char versions.
+ *
+ * Copyright (c) 1998, 1999 Henry Spencer.  All rights reserved.
+ *
+ * Development of this software was funded, in part, by Cray Research Inc.,
+ * UUNET Communications Services Inc., Sun Microsystems Inc., and Scriptics
+ * Corporation, none of whom are responsible for the results.  The author
+ * thanks all of them.
+ *
+ * Redistribution and use in source and binary forms -- with or without
+ * modification -- are permitted for any purpose, provided that
+ * redistributions in source form retain this entire copyright notice and
+ * indicate the origin and nature of any modifications.
+ *
+ * I'd appreciate being given credit for this package in the documentation of
+ * software which uses it, but that is not a requirement.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * HENRY SPENCER BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "regguts.h"
+
+/*
+ - regcomp - compile regular expression
+ */
+int
+regcomp(
+    regex_t *re,
+    const char *str,
+    int flags)
+{
+    size_t len;
+    int f = flags;
+
+    if (f&REG_PEND) {
+	len = re->re_endp - str;
+	f &= ~REG_PEND;
+    } else {
+	len = strlen(str);
+    }
+
+    return re_comp(re, str, len, f);
+}
+
+/*
+ - regexec - execute regular expression
+ */
+int
+regexec(
+    regex_t *re,
+    const char *str,
+    size_t nmatch,
+    regmatch_t pmatch[],
+    int flags)
+{
+    const char *start;
+    size_t len;
+    int f = flags;
+
+    if (f & REG_STARTEND) {
+	start = str + pmatch[0].rm_so;
+	len = pmatch[0].rm_eo - pmatch[0].rm_so;
+	f &= ~REG_STARTEND;
+    } else {
+	start = str;
+	len = strlen(str);
+    }
+
+    return re_exec(re, start, len, nmatch, pmatch, f);
+}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/regguts.h b/generic/regguts.h
new file mode 100644
index 0000000..1ac2465
--- /dev/null
+++ b/generic/regguts.h
@@ -0,0 +1,453 @@
+/*
+ * Internal interface definitions, etc., for the reg package
+ *
+ * Copyright (c) 1998, 1999 Henry Spencer.  All rights reserved.
+ *
+ * Development of this software was funded, in part, by Cray Research Inc.,
+ * UUNET Communications Services Inc., Sun Microsystems Inc., and Scriptics
+ * Corporation, none of whom are responsible for the results.  The author
+ * thanks all of them.
+ *
+ * Redistribution and use in source and binary forms -- with or without
+ * modification -- are permitted for any purpose, provided that
+ * redistributions in source form retain this entire copyright notice and
+ * indicate the origin and nature of any modifications.
+ *
+ * I'd appreciate being given credit for this package in the documentation of
+ * software which uses it, but that is not a requirement.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
+ * HENRY SPENCER BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Environmental customization. It should not (I hope) be necessary to alter
+ * the file you are now reading -- regcustom.h should handle it all, given
+ * care here and elsewhere.
+ */
+#include "regcustom.h"
+
+/*
+ * Things that regcustom.h might override.
+ */
+
+/* assertions */
+#ifndef assert
+#ifndef REG_DEBUG
+#ifndef NDEBUG
+#define	NDEBUG		/* no assertions */
+#endif
+#endif /* !REG_DEBUG */
+#include <assert.h>
+#endif
+
+/* voids */
+#ifndef VOID
+#define	VOID	void		/* for function return values */
+#endif
+#ifndef DISCARD
+#define	DISCARD	void		/* for throwing values away */
+#endif
+#ifndef PVOID
+#define	PVOID	void *		/* generic pointer */
+#endif
+#ifndef VS
+#define	VS(x)	((void*)(x))	/* cast something to generic ptr */
+#endif
+#ifndef NOPARMS
+#define	NOPARMS	void		/* for empty parm lists */
+#endif
+
+/* function-pointer declarator */
+#ifndef FUNCPTR
+#if __STDC__ >= 1
+#define	FUNCPTR(name, args)	(*name)args
+#else
+#define	FUNCPTR(name, args)	(*name)()
+#endif
+#endif
+
+/* memory allocation */
+#ifndef MALLOC
+#define	MALLOC(n)	malloc(n)
+#endif
+#ifndef REALLOC
+#define	REALLOC(p, n)	realloc(VS(p), n)
+#endif
+#ifndef FREE
+#define	FREE(p)		free(VS(p))
+#endif
+
+/* want size of a char in bits, and max value in bounded quantifiers */
+#ifndef _POSIX2_RE_DUP_MAX
+#define	_POSIX2_RE_DUP_MAX 255	/* normally from <limits.h> */
+#endif
+
+/*
+ * misc
+ */
+
+#define	NOTREACHED	0
+#define	xxx		1
+
+#define	DUPMAX	_POSIX2_RE_DUP_MAX
+#define	DUPINF	(DUPMAX+1)
+
+#define	REMAGIC	0xfed7		/* magic number for main struct */
+
+/*
+ * debugging facilities
+ */
+#ifdef REG_DEBUG
+/* FDEBUG does finite-state tracing */
+#define	FDEBUG(arglist)	{ if (v->eflags&REG_FTRACE) printf arglist; }
+/* MDEBUG does higher-level tracing */
+#define	MDEBUG(arglist)	{ if (v->eflags&REG_MTRACE) printf arglist; }
+#else
+#define	FDEBUG(arglist)	{}
+#define	MDEBUG(arglist)	{}
+#endif
+
+/*
+ * bitmap manipulation
+ */
+#define	UBITS	(CHAR_BIT * sizeof(unsigned))
+#define	BSET(uv, sn)	((uv)[(sn)/UBITS] |= (unsigned)1 << ((sn)%UBITS))
+#define	ISBSET(uv, sn)	((uv)[(sn)/UBITS] & ((unsigned)1 << ((sn)%UBITS)))
+
+/*
+ * We dissect a chr into byts for colormap table indexing. Here we define a
+ * byt, which will be the same as a byte on most machines... The exact size of
+ * a byt is not critical, but about 8 bits is good, and extraction of 8-bit
+ * chunks is sometimes especially fast.
+ */
+
+#ifndef BYTBITS
+#define	BYTBITS	8		/* bits in a byt */
+#endif
+#define	BYTTAB	(1<<BYTBITS)	/* size of table with one entry per byt value */
+#define	BYTMASK	(BYTTAB-1)	/* bit mask for byt */
+#define	NBYTS	((CHRBITS+BYTBITS-1)/BYTBITS)
+/* the definition of GETCOLOR(), below, assumes NBYTS <= 4 */
+
+/*
+ * As soon as possible, we map chrs into equivalence classes -- "colors" --
+ * which are of much more manageable number.
+ */
+
+typedef short color;		/* colors of characters */
+typedef int pcolor;		/* what color promotes to */
+#define MAX_COLOR	SHRT_MAX /* max color value */
+#define	COLORLESS	(-1)	/* impossible color */
+#define	WHITE		0	/* default color, parent of all others */
+
+/*
+ * A colormap is a tree -- more precisely, a DAG -- indexed at each level by a
+ * byt of the chr, to map the chr to a color efficiently. Because lower
+ * sections of the tree can be shared, it can exploit the usual sparseness of
+ * such a mapping table. The tree is always NBYTS levels deep (in the past it
+ * was shallower during construction but was "filled" to full depth at the end
+ * of that); areas that are unaltered as yet point to "fill blocks" which are
+ * entirely WHITE in color.
+ */
+
+/* the tree itself */
+struct colors {
+    color ccolor[BYTTAB];
+};
+struct ptrs {
+    union tree *pptr[BYTTAB];
+};
+union tree {
+    struct colors colors;
+    struct ptrs ptrs;
+};
+#define	tcolor	colors.ccolor
+#define	tptr	ptrs.pptr
+
+/* Internal per-color descriptor structure for the color machinery */
+struct colordesc {
+    uchr nchrs;			/* number of chars of this color */
+    color sub;			/* open subcolor (if any); free chain ptr */
+#define	NOSUB	COLORLESS
+    struct arc *arcs;		/* color chain */
+    int flags;
+#define	FREECOL	01		/* currently free */
+#define	PSEUDO	02		/* pseudocolor, no real chars */
+#define	UNUSEDCOLOR(cd)	((cd)->flags&FREECOL)
+    union tree *block;		/* block of solid color, if any */
+};
+
+/*
+ * The color map itself
+ *
+ * Much of the data in the colormap struct is only used at compile time.
+ * However, the bulk of the space usage is in the "tree" structure, so it's
+ * not clear that there's much point in converting the rest to a more compact
+ * form when compilation is finished.
+ */
+struct colormap {
+    int magic;
+#define	CMMAGIC	0x876
+    struct vars *v;		/* for compile error reporting */
+    size_t ncds;		/* number of colordescs */
+    size_t max;			/* highest in use */
+    color free;			/* beginning of free chain (if non-0) */
+    struct colordesc *cd;
+#define	CDEND(cm)	(&(cm)->cd[(cm)->max + 1])
+#define	NINLINECDS	((size_t)10)
+    struct colordesc cdspace[NINLINECDS];
+    union tree tree[NBYTS];	/* tree top, plus fill blocks */
+};
+
+/* optimization magic to do fast chr->color mapping */
+#define	B0(c)	((c) & BYTMASK)
+#define	B1(c)	(((c)>>BYTBITS) & BYTMASK)
+#define	B2(c)	(((c)>>(2*BYTBITS)) & BYTMASK)
+#define	B3(c)	(((c)>>(3*BYTBITS)) & BYTMASK)
+#if NBYTS == 1
+#define	GETCOLOR(cm, c)	((cm)->tree->tcolor[B0(c)])
+#endif
+/* beware, for NBYTS>1, GETCOLOR() is unsafe -- 2nd arg used repeatedly */
+#if NBYTS == 2
+#define	GETCOLOR(cm, c)	((cm)->tree->tptr[B1(c)]->tcolor[B0(c)])
+#endif
+#if NBYTS == 4
+#define	GETCOLOR(cm, c)	((cm)->tree->tptr[B3(c)]->tptr[B2(c)]->tptr[B1(c)]->tcolor[B0(c)])
+#endif
+
+/*
+ * Interface definitions for locale-interface functions in locale.c.
+ */
+
+/* Representation of a set of characters. */
+struct cvec {
+    int nchrs;			/* number of chrs */
+    int chrspace;		/* number of chrs possible */
+    chr *chrs;			/* pointer to vector of chrs */
+    int nranges;		/* number of ranges (chr pairs) */
+    int rangespace;		/* number of chrs possible */
+    chr *ranges;		/* pointer to vector of chr pairs */
+};
+
+/*
+ * definitions for non-deterministic finite autmaton (NFA) internal
+ * representation
+ *
+ * Having a "from" pointer within each arc may seem redundant, but it saves a
+ * lot of hassle.
+ */
+
+struct state;
+
+struct arc {
+    int type;			/* 0 if free, else an NFA arc type code */
+    color co;
+    struct state *from;		/* where it's from (and contained within) */
+    struct state *to;		/* where it's to */
+    struct arc *outchain;	/* link in *from's outs chain or free chain */
+    struct arc *outchainRev;	/* back-link in *from's outs chain */
+#define	freechain outchain	/* we do not maintain "freechainRev" */
+    struct arc *inchain;	/* *to's ins chain */
+    struct arc *inchainRev;	/* back-link in *to's ins chain */
+    struct arc *colorchain;	/* color's arc chain */
+    struct arc *colorchainRev;	/* back-link in color's arc chain */
+};
+
+struct arcbatch {		/* for bulk allocation of arcs */
+    struct arcbatch *next;
+#define	ABSIZE	10
+    struct arc a[ABSIZE];
+};
+
+struct state {
+    int no;
+#define	FREESTATE	(-1)
+    char flag;			/* marks special states */
+    int nins;			/* number of inarcs */
+    struct arc *ins;		/* chain of inarcs */
+    int nouts;			/* number of outarcs */
+    struct arc *outs;		/* chain of outarcs */
+    struct arc *free;		/* chain of free arcs */
+    struct state *tmp;		/* temporary for traversal algorithms */
+    struct state *next;		/* chain for traversing all */
+    struct state *prev;		/* back chain */
+    struct arcbatch oas;	/* first arcbatch, avoid malloc in easy case */
+    int noas;			/* number of arcs used in first arcbatch */
+};
+
+struct nfa {
+    struct state *pre;		/* pre-initial state */
+    struct state *init;		/* initial state */
+    struct state *final;	/* final state */
+    struct state *post;		/* post-final state */
+    int nstates;		/* for numbering states */
+    struct state *states;	/* state-chain header */
+    struct state *slast;	/* tail of the chain */
+    struct state *free;		/* free list */
+    struct colormap *cm;	/* the color map */
+    color bos[2];		/* colors, if any, assigned to BOS and BOL */
+    color eos[2];		/* colors, if any, assigned to EOS and EOL */
+    struct vars *v;		/* simplifies compile error reporting */
+    struct nfa *parent;		/* parent NFA, if any */
+};
+
+/*
+ * definitions for compacted NFA
+ *
+ * The main space savings in a compacted NFA is from making the arcs as small
+ * as possible.  We store only the transition color and next-state number for
+ * each arc.  The list of out arcs for each state is an array beginning at
+ * cnfa.states[statenumber], and terminated by a dummy carc struct with
+ * co == COLORLESS.
+ *
+ * The non-dummy carc structs are of two types: plain arcs and LACON arcs.
+ * Plain arcs just store the transition color number as "co".  LACON arcs
+ * store the lookahead constraint number plus cnfa.ncolors as "co".  LACON
+ * arcs can be distinguished from plain by testing for co >= cnfa.ncolors.
+ */
+
+struct carc {
+    color co;			/* COLORLESS is list terminator */
+    int to;			/* next-state number */
+};
+
+struct cnfa {
+    int nstates;		/* number of states */
+    int ncolors;		/* number of colors */
+    int flags;
+#define	HASLACONS	01	/* uses lookahead constraints */
+    int pre;			/* setup state number */
+    int post;			/* teardown state number */
+    color bos[2];		/* colors, if any, assigned to BOS and BOL */
+    color eos[2];		/* colors, if any, assigned to EOS and EOL */
+    char *stflags;		/* vector of per-state flags bytes */
+#define CNFA_NOPROGRESS	01	/* flag bit for a no-progress state */
+    struct carc **states;	/* vector of pointers to outarc lists */
+    /* states[n] are pointers into a single malloc'd array of arcs */
+    struct carc *arcs;		/* the area for the lists */
+};
+#define	ZAPCNFA(cnfa)	((cnfa).nstates = 0)
+#define	NULLCNFA(cnfa)	((cnfa).nstates == 0)
+
+/*
+ * This symbol limits the transient heap space used by the regex compiler,
+ * and thereby also the maximum complexity of NFAs that we'll deal with.
+ * Currently we only count NFA states and arcs against this; the other
+ * transient data is generally not large enough to notice compared to those.
+ * Note that we do not charge anything for the final output data structures
+ * (the compacted NFA and the colormap).
+ */
+#ifndef REG_MAX_COMPILE_SPACE
+#define REG_MAX_COMPILE_SPACE  \
+	(100000 * sizeof(struct state) + 100000 * sizeof(struct arcbatch))
+#endif
+
+/*
+ * subexpression tree
+ *
+ * "op" is one of:
+ *	'='  plain regex without interesting substructure (implemented as DFA)
+ *	'b'  back-reference (has no substructure either)
+ *	'('  capture node: captures the match of its single child
+ *	'.'  concatenation: matches a match for left, then a match for right
+ *	'|'  alternation: matches a match for left or a match for right
+ *	'*'  iteration: matches some number of matches of its single child
+ *
+ * Note: the right child of an alternation must be another alternation or
+ * NULL; hence, an N-way branch requires N alternation nodes, not N-1 as you
+ * might expect.  This could stand to be changed.  Actually I'd rather see
+ * a single alternation node with N children, but that will take revising
+ * the representation of struct subre.
+ *
+ * Note: when a backref is directly quantified, we stick the min/max counts
+ * into the backref rather than plastering an iteration node on top.  This is
+ * for efficiency: there is no need to search for possible division points.
+ */
+
+struct subre {
+    char op;			/* see type codes above */
+    char flags;
+#define	LONGER	01		/* prefers longer match */
+#define	SHORTER	02		/* prefers shorter match */
+#define	MIXED	04		/* mixed preference below */
+#define	CAP	010		/* capturing parens below */
+#define	BACKR	020		/* back reference below */
+#define	INUSE	0100		/* in use in final tree */
+#define	NOPROP	03		/* bits which may not propagate up */
+#define	LMIX(f)	((f)<<2)	/* LONGER -> MIXED */
+#define	SMIX(f)	((f)<<1)	/* SHORTER -> MIXED */
+#define	UP(f)	(((f)&~NOPROP) | (LMIX(f) & SMIX(f) & MIXED))
+#define	MESSY(f)	((f)&(MIXED|CAP|BACKR))
+#define	PREF(f)	((f)&NOPROP)
+#define	PREF2(f1, f2)	((PREF(f1) != 0) ? PREF(f1) : PREF(f2))
+#define	COMBINE(f1, f2)	(UP((f1)|(f2)) | PREF2(f1, f2))
+    short id;			/* ID of subre (1..ntree-1) */
+    int subno;			/* subexpression number (for 'b' and '(') */
+    short min;			/* min repetitions for iteration or backref */
+    short max;			/* max repetitions for iteration or backref */
+    struct subre *left;		/* left child, if any (also freelist chain) */
+    struct subre *right;	/* right child, if any */
+    struct state *begin;	/* outarcs from here... */
+    struct state *end;		/* ...ending in inarcs here */
+    struct cnfa cnfa;		/* compacted NFA, if any */
+    struct subre *chain;	/* for bookkeeping and error cleanup */
+};
+
+/*
+ * table of function pointers for generic manipulation functions. A regex_t's
+ * re_fns points to one of these.
+ */
+
+struct fns {
+    void FUNCPTR(free, (regex_t *));
+};
+
+/*
+ * the insides of a regex_t, hidden behind a void *
+ */
+
+struct guts {
+    int magic;
+#define	GUTSMAGIC	0xfed9
+    int cflags;			/* copy of compile flags */
+    long info;			/* copy of re_info */
+    size_t nsub;		/* copy of re_nsub */
+    struct subre *tree;
+    struct cnfa search;		/* for fast preliminary search */
+    int ntree;			/* number of subre's, plus one */
+    struct colormap cmap;
+    int FUNCPTR(compare, (const chr *, const chr *, size_t));
+    struct subre *lacons;	/* lookahead-constraint vector */
+    int nlacons;		/* size of lacons */
+};
+
+/*
+ * Magic for allocating a variable workspace. This default version is
+ * stack-hungry.
+ */
+
+#ifndef AllocVars
+#define AllocVars(vPtr) \
+    struct vars var; \
+    register struct vars *vPtr = &var
+#endif
+#ifndef FreeVars
+#define FreeVars(vPtr) ((void) 0)
+#endif
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tcl.decls b/generic/tcl.decls
new file mode 100644
index 0000000..574b49b
--- /dev/null
+++ b/generic/tcl.decls
@@ -0,0 +1,2391 @@
+# tcl.decls --
+#
+#	This file contains the declarations for all supported public
+#	functions that are exported by the Tcl library via the stubs table.
+#	This file is used to generate the tclDecls.h, tclPlatDecls.h
+#	and tclStubInit.c files.
+#
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+# Copyright (c) 2001, 2002 by Kevin B. Kenny.  All rights reserved.
+# Copyright (c) 2007 Daniel A. Steffen <das@users.sourceforge.net>
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+library tcl
+
+# Define the tcl interface with several sub interfaces:
+#     tclPlat	 - platform specific public
+#     tclInt	 - generic private
+#     tclPlatInt - platform specific private
+
+interface tcl
+hooks {tclPlat tclInt tclIntPlat}
+scspec EXTERN
+
+# Declare each of the functions in the public Tcl interface.  Note that
+# the an index should never be reused for a different function in order
+# to preserve backwards compatibility.
+
+declare 0 {
+    int Tcl_PkgProvideEx(Tcl_Interp *interp, const char *name,
+	    const char *version, const void *clientData)
+}
+declare 1 {
+    CONST84_RETURN char *Tcl_PkgRequireEx(Tcl_Interp *interp,
+	    const char *name, const char *version, int exact,
+	    void *clientDataPtr)
+}
+declare 2 {
+    TCL_NORETURN void Tcl_Panic(const char *format, ...)
+}
+declare 3 {
+    char *Tcl_Alloc(unsigned int size)
+}
+declare 4 {
+    void Tcl_Free(char *ptr)
+}
+declare 5 {
+    char *Tcl_Realloc(char *ptr, unsigned int size)
+}
+declare 6 {
+    char *Tcl_DbCkalloc(unsigned int size, const char *file, int line)
+}
+declare 7 {
+    void Tcl_DbCkfree(char *ptr, const char *file, int line)
+}
+declare 8 {
+    char *Tcl_DbCkrealloc(char *ptr, unsigned int size,
+	    const char *file, int line)
+}
+
+# Tcl_CreateFileHandler and Tcl_DeleteFileHandler are only available on unix,
+# but they are part of the old generic interface, so we include them here for
+# compatibility reasons.
+
+declare 9 unix {
+    void Tcl_CreateFileHandler(int fd, int mask, Tcl_FileProc *proc,
+	    ClientData clientData)
+}
+declare 10 unix {
+    void Tcl_DeleteFileHandler(int fd)
+}
+declare 11 {
+    void Tcl_SetTimer(const Tcl_Time *timePtr)
+}
+declare 12 {
+    void Tcl_Sleep(int ms)
+}
+declare 13 {
+    int Tcl_WaitForEvent(const Tcl_Time *timePtr)
+}
+declare 14 {
+    int Tcl_AppendAllObjTypes(Tcl_Interp *interp, Tcl_Obj *objPtr)
+}
+declare 15 {
+    void Tcl_AppendStringsToObj(Tcl_Obj *objPtr, ...)
+}
+declare 16 {
+    void Tcl_AppendToObj(Tcl_Obj *objPtr, const char *bytes, int length)
+}
+declare 17 {
+    Tcl_Obj *Tcl_ConcatObj(int objc, Tcl_Obj *const objv[])
+}
+declare 18 {
+    int Tcl_ConvertToType(Tcl_Interp *interp, Tcl_Obj *objPtr,
+	    const Tcl_ObjType *typePtr)
+}
+declare 19 {
+    void Tcl_DbDecrRefCount(Tcl_Obj *objPtr, const char *file, int line)
+}
+declare 20 {
+    void Tcl_DbIncrRefCount(Tcl_Obj *objPtr, const char *file, int line)
+}
+declare 21 {
+    int Tcl_DbIsShared(Tcl_Obj *objPtr, const char *file, int line)
+}
+declare 22 {
+    Tcl_Obj *Tcl_DbNewBooleanObj(int boolValue, const char *file, int line)
+}
+declare 23 {
+    Tcl_Obj *Tcl_DbNewByteArrayObj(const unsigned char *bytes, int length,
+	    const char *file, int line)
+}
+declare 24 {
+    Tcl_Obj *Tcl_DbNewDoubleObj(double doubleValue, const char *file,
+	    int line)
+}
+declare 25 {
+    Tcl_Obj *Tcl_DbNewListObj(int objc, Tcl_Obj *const *objv,
+	    const char *file, int line)
+}
+declare 26 {
+    Tcl_Obj *Tcl_DbNewLongObj(long longValue, const char *file, int line)
+}
+declare 27 {
+    Tcl_Obj *Tcl_DbNewObj(const char *file, int line)
+}
+declare 28 {
+    Tcl_Obj *Tcl_DbNewStringObj(const char *bytes, int length,
+	    const char *file, int line)
+}
+declare 29 {
+    Tcl_Obj *Tcl_DuplicateObj(Tcl_Obj *objPtr)
+}
+declare 30 {
+    void TclFreeObj(Tcl_Obj *objPtr)
+}
+declare 31 {
+    int Tcl_GetBoolean(Tcl_Interp *interp, const char *src, int *boolPtr)
+}
+declare 32 {
+    int Tcl_GetBooleanFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr,
+	    int *boolPtr)
+}
+declare 33 {
+    unsigned char *Tcl_GetByteArrayFromObj(Tcl_Obj *objPtr, int *lengthPtr)
+}
+declare 34 {
+    int Tcl_GetDouble(Tcl_Interp *interp, const char *src, double *doublePtr)
+}
+declare 35 {
+    int Tcl_GetDoubleFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr,
+	    double *doublePtr)
+}
+declare 36 {
+    int Tcl_GetIndexFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr,
+	    CONST84 char *const *tablePtr, const char *msg, int flags, int *indexPtr)
+}
+declare 37 {
+    int Tcl_GetInt(Tcl_Interp *interp, const char *src, int *intPtr)
+}
+declare 38 {
+    int Tcl_GetIntFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, int *intPtr)
+}
+declare 39 {
+    int Tcl_GetLongFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, long *longPtr)
+}
+declare 40 {
+    CONST86 Tcl_ObjType *Tcl_GetObjType(const char *typeName)
+}
+declare 41 {
+    char *Tcl_GetStringFromObj(Tcl_Obj *objPtr, int *lengthPtr)
+}
+declare 42 {
+    void Tcl_InvalidateStringRep(Tcl_Obj *objPtr)
+}
+declare 43 {
+    int Tcl_ListObjAppendList(Tcl_Interp *interp, Tcl_Obj *listPtr,
+	    Tcl_Obj *elemListPtr)
+}
+declare 44 {
+    int Tcl_ListObjAppendElement(Tcl_Interp *interp, Tcl_Obj *listPtr,
+	    Tcl_Obj *objPtr)
+}
+declare 45 {
+    int Tcl_ListObjGetElements(Tcl_Interp *interp, Tcl_Obj *listPtr,
+	    int *objcPtr, Tcl_Obj ***objvPtr)
+}
+declare 46 {
+    int Tcl_ListObjIndex(Tcl_Interp *interp, Tcl_Obj *listPtr, int index,
+	    Tcl_Obj **objPtrPtr)
+}
+declare 47 {
+    int Tcl_ListObjLength(Tcl_Interp *interp, Tcl_Obj *listPtr,
+	    int *lengthPtr)
+}
+declare 48 {
+    int Tcl_ListObjReplace(Tcl_Interp *interp, Tcl_Obj *listPtr, int first,
+	    int count, int objc, Tcl_Obj *const objv[])
+}
+declare 49 {
+    Tcl_Obj *Tcl_NewBooleanObj(int boolValue)
+}
+declare 50 {
+    Tcl_Obj *Tcl_NewByteArrayObj(const unsigned char *bytes, int length)
+}
+declare 51 {
+    Tcl_Obj *Tcl_NewDoubleObj(double doubleValue)
+}
+declare 52 {
+    Tcl_Obj *Tcl_NewIntObj(int intValue)
+}
+declare 53 {
+    Tcl_Obj *Tcl_NewListObj(int objc, Tcl_Obj *const objv[])
+}
+declare 54 {
+    Tcl_Obj *Tcl_NewLongObj(long longValue)
+}
+declare 55 {
+    Tcl_Obj *Tcl_NewObj(void)
+}
+declare 56 {
+    Tcl_Obj *Tcl_NewStringObj(const char *bytes, int length)
+}
+declare 57 {
+    void Tcl_SetBooleanObj(Tcl_Obj *objPtr, int boolValue)
+}
+declare 58 {
+    unsigned char *Tcl_SetByteArrayLength(Tcl_Obj *objPtr, int length)
+}
+declare 59 {
+    void Tcl_SetByteArrayObj(Tcl_Obj *objPtr, const unsigned char *bytes,
+	    int length)
+}
+declare 60 {
+    void Tcl_SetDoubleObj(Tcl_Obj *objPtr, double doubleValue)
+}
+declare 61 {
+    void Tcl_SetIntObj(Tcl_Obj *objPtr, int intValue)
+}
+declare 62 {
+    void Tcl_SetListObj(Tcl_Obj *objPtr, int objc, Tcl_Obj *const objv[])
+}
+declare 63 {
+    void Tcl_SetLongObj(Tcl_Obj *objPtr, long longValue)
+}
+declare 64 {
+    void Tcl_SetObjLength(Tcl_Obj *objPtr, int length)
+}
+declare 65 {
+    void Tcl_SetStringObj(Tcl_Obj *objPtr, const char *bytes, int length)
+}
+declare 66 {
+    void Tcl_AddErrorInfo(Tcl_Interp *interp, const char *message)
+}
+declare 67 {
+    void Tcl_AddObjErrorInfo(Tcl_Interp *interp, const char *message,
+	    int length)
+}
+declare 68 {
+    void Tcl_AllowExceptions(Tcl_Interp *interp)
+}
+declare 69 {
+    void Tcl_AppendElement(Tcl_Interp *interp, const char *element)
+}
+declare 70 {
+    void Tcl_AppendResult(Tcl_Interp *interp, ...)
+}
+declare 71 {
+    Tcl_AsyncHandler Tcl_AsyncCreate(Tcl_AsyncProc *proc,
+	    ClientData clientData)
+}
+declare 72 {
+    void Tcl_AsyncDelete(Tcl_AsyncHandler async)
+}
+declare 73 {
+    int Tcl_AsyncInvoke(Tcl_Interp *interp, int code)
+}
+declare 74 {
+    void Tcl_AsyncMark(Tcl_AsyncHandler async)
+}
+declare 75 {
+    int Tcl_AsyncReady(void)
+}
+declare 76 {
+    void Tcl_BackgroundError(Tcl_Interp *interp)
+}
+declare 77 {
+    char Tcl_Backslash(const char *src, int *readPtr)
+}
+declare 78 {
+    int Tcl_BadChannelOption(Tcl_Interp *interp, const char *optionName,
+	    const char *optionList)
+}
+declare 79 {
+    void Tcl_CallWhenDeleted(Tcl_Interp *interp, Tcl_InterpDeleteProc *proc,
+	    ClientData clientData)
+}
+declare 80 {
+    void Tcl_CancelIdleCall(Tcl_IdleProc *idleProc, ClientData clientData)
+}
+declare 81 {
+    int Tcl_Close(Tcl_Interp *interp, Tcl_Channel chan)
+}
+declare 82 {
+    int Tcl_CommandComplete(const char *cmd)
+}
+declare 83 {
+    char *Tcl_Concat(int argc, CONST84 char *const *argv)
+}
+declare 84 {
+    int Tcl_ConvertElement(const char *src, char *dst, int flags)
+}
+declare 85 {
+    int Tcl_ConvertCountedElement(const char *src, int length, char *dst,
+	    int flags)
+}
+declare 86 {
+    int Tcl_CreateAlias(Tcl_Interp *slave, const char *slaveCmd,
+	    Tcl_Interp *target, const char *targetCmd, int argc,
+	    CONST84 char *const *argv)
+}
+declare 87 {
+    int Tcl_CreateAliasObj(Tcl_Interp *slave, const char *slaveCmd,
+	    Tcl_Interp *target, const char *targetCmd, int objc,
+	    Tcl_Obj *const objv[])
+}
+declare 88 {
+    Tcl_Channel Tcl_CreateChannel(const Tcl_ChannelType *typePtr,
+	    const char *chanName, ClientData instanceData, int mask)
+}
+declare 89 {
+    void Tcl_CreateChannelHandler(Tcl_Channel chan, int mask,
+	    Tcl_ChannelProc *proc, ClientData clientData)
+}
+declare 90 {
+    void Tcl_CreateCloseHandler(Tcl_Channel chan, Tcl_CloseProc *proc,
+	    ClientData clientData)
+}
+declare 91 {
+    Tcl_Command Tcl_CreateCommand(Tcl_Interp *interp, const char *cmdName,
+	    Tcl_CmdProc *proc, ClientData clientData,
+	    Tcl_CmdDeleteProc *deleteProc)
+}
+declare 92 {
+    void Tcl_CreateEventSource(Tcl_EventSetupProc *setupProc,
+	    Tcl_EventCheckProc *checkProc, ClientData clientData)
+}
+declare 93 {
+    void Tcl_CreateExitHandler(Tcl_ExitProc *proc, ClientData clientData)
+}
+declare 94 {
+    Tcl_Interp *Tcl_CreateInterp(void)
+}
+declare 95 {
+    void Tcl_CreateMathFunc(Tcl_Interp *interp, const char *name,
+	    int numArgs, Tcl_ValueType *argTypes,
+	    Tcl_MathProc *proc, ClientData clientData)
+}
+declare 96 {
+    Tcl_Command Tcl_CreateObjCommand(Tcl_Interp *interp,
+	    const char *cmdName,
+	    Tcl_ObjCmdProc *proc, ClientData clientData,
+	    Tcl_CmdDeleteProc *deleteProc)
+}
+declare 97 {
+    Tcl_Interp *Tcl_CreateSlave(Tcl_Interp *interp, const char *slaveName,
+	    int isSafe)
+}
+declare 98 {
+    Tcl_TimerToken Tcl_CreateTimerHandler(int milliseconds,
+	    Tcl_TimerProc *proc, ClientData clientData)
+}
+declare 99 {
+    Tcl_Trace Tcl_CreateTrace(Tcl_Interp *interp, int level,
+	    Tcl_CmdTraceProc *proc, ClientData clientData)
+}
+declare 100 {
+    void Tcl_DeleteAssocData(Tcl_Interp *interp, const char *name)
+}
+declare 101 {
+    void Tcl_DeleteChannelHandler(Tcl_Channel chan, Tcl_ChannelProc *proc,
+	    ClientData clientData)
+}
+declare 102 {
+    void Tcl_DeleteCloseHandler(Tcl_Channel chan, Tcl_CloseProc *proc,
+	    ClientData clientData)
+}
+declare 103 {
+    int Tcl_DeleteCommand(Tcl_Interp *interp, const char *cmdName)
+}
+declare 104 {
+    int Tcl_DeleteCommandFromToken(Tcl_Interp *interp, Tcl_Command command)
+}
+declare 105 {
+    void Tcl_DeleteEvents(Tcl_EventDeleteProc *proc, ClientData clientData)
+}
+declare 106 {
+    void Tcl_DeleteEventSource(Tcl_EventSetupProc *setupProc,
+	    Tcl_EventCheckProc *checkProc, ClientData clientData)
+}
+declare 107 {
+    void Tcl_DeleteExitHandler(Tcl_ExitProc *proc, ClientData clientData)
+}
+declare 108 {
+    void Tcl_DeleteHashEntry(Tcl_HashEntry *entryPtr)
+}
+declare 109 {
+    void Tcl_DeleteHashTable(Tcl_HashTable *tablePtr)
+}
+declare 110 {
+    void Tcl_DeleteInterp(Tcl_Interp *interp)
+}
+declare 111 {
+    void Tcl_DetachPids(int numPids, Tcl_Pid *pidPtr)
+}
+declare 112 {
+    void Tcl_DeleteTimerHandler(Tcl_TimerToken token)
+}
+declare 113 {
+    void Tcl_DeleteTrace(Tcl_Interp *interp, Tcl_Trace trace)
+}
+declare 114 {
+    void Tcl_DontCallWhenDeleted(Tcl_Interp *interp,
+	    Tcl_InterpDeleteProc *proc, ClientData clientData)
+}
+declare 115 {
+    int Tcl_DoOneEvent(int flags)
+}
+declare 116 {
+    void Tcl_DoWhenIdle(Tcl_IdleProc *proc, ClientData clientData)
+}
+declare 117 {
+    char *Tcl_DStringAppend(Tcl_DString *dsPtr, const char *bytes, int length)
+}
+declare 118 {
+    char *Tcl_DStringAppendElement(Tcl_DString *dsPtr, const char *element)
+}
+declare 119 {
+    void Tcl_DStringEndSublist(Tcl_DString *dsPtr)
+}
+declare 120 {
+    void Tcl_DStringFree(Tcl_DString *dsPtr)
+}
+declare 121 {
+    void Tcl_DStringGetResult(Tcl_Interp *interp, Tcl_DString *dsPtr)
+}
+declare 122 {
+    void Tcl_DStringInit(Tcl_DString *dsPtr)
+}
+declare 123 {
+    void Tcl_DStringResult(Tcl_Interp *interp, Tcl_DString *dsPtr)
+}
+declare 124 {
+    void Tcl_DStringSetLength(Tcl_DString *dsPtr, int length)
+}
+declare 125 {
+    void Tcl_DStringStartSublist(Tcl_DString *dsPtr)
+}
+declare 126 {
+    int Tcl_Eof(Tcl_Channel chan)
+}
+declare 127 {
+    CONST84_RETURN char *Tcl_ErrnoId(void)
+}
+declare 128 {
+    CONST84_RETURN char *Tcl_ErrnoMsg(int err)
+}
+declare 129 {
+    int Tcl_Eval(Tcl_Interp *interp, const char *script)
+}
+# This is obsolete, use Tcl_FSEvalFile
+declare 130 {
+    int Tcl_EvalFile(Tcl_Interp *interp, const char *fileName)
+}
+declare 131 {
+    int Tcl_EvalObj(Tcl_Interp *interp, Tcl_Obj *objPtr)
+}
+declare 132 {
+    void Tcl_EventuallyFree(ClientData clientData, Tcl_FreeProc *freeProc)
+}
+declare 133 {
+    TCL_NORETURN void Tcl_Exit(int status)
+}
+declare 134 {
+    int Tcl_ExposeCommand(Tcl_Interp *interp, const char *hiddenCmdToken,
+	    const char *cmdName)
+}
+declare 135 {
+    int Tcl_ExprBoolean(Tcl_Interp *interp, const char *expr, int *ptr)
+}
+declare 136 {
+    int Tcl_ExprBooleanObj(Tcl_Interp *interp, Tcl_Obj *objPtr, int *ptr)
+}
+declare 137 {
+    int Tcl_ExprDouble(Tcl_Interp *interp, const char *expr, double *ptr)
+}
+declare 138 {
+    int Tcl_ExprDoubleObj(Tcl_Interp *interp, Tcl_Obj *objPtr, double *ptr)
+}
+declare 139 {
+    int Tcl_ExprLong(Tcl_Interp *interp, const char *expr, long *ptr)
+}
+declare 140 {
+    int Tcl_ExprLongObj(Tcl_Interp *interp, Tcl_Obj *objPtr, long *ptr)
+}
+declare 141 {
+    int Tcl_ExprObj(Tcl_Interp *interp, Tcl_Obj *objPtr,
+	    Tcl_Obj **resultPtrPtr)
+}
+declare 142 {
+    int Tcl_ExprString(Tcl_Interp *interp, const char *expr)
+}
+declare 143 {
+    void Tcl_Finalize(void)
+}
+declare 144 {
+    void Tcl_FindExecutable(const char *argv0)
+}
+declare 145 {
+    Tcl_HashEntry *Tcl_FirstHashEntry(Tcl_HashTable *tablePtr,
+	    Tcl_HashSearch *searchPtr)
+}
+declare 146 {
+    int Tcl_Flush(Tcl_Channel chan)
+}
+declare 147 {
+    void Tcl_FreeResult(Tcl_Interp *interp)
+}
+declare 148 {
+    int Tcl_GetAlias(Tcl_Interp *interp, const char *slaveCmd,
+	    Tcl_Interp **targetInterpPtr, CONST84 char **targetCmdPtr,
+	    int *argcPtr, CONST84 char ***argvPtr)
+}
+declare 149 {
+    int Tcl_GetAliasObj(Tcl_Interp *interp, const char *slaveCmd,
+	    Tcl_Interp **targetInterpPtr, CONST84 char **targetCmdPtr,
+	    int *objcPtr, Tcl_Obj ***objv)
+}
+declare 150 {
+    ClientData Tcl_GetAssocData(Tcl_Interp *interp, const char *name,
+	    Tcl_InterpDeleteProc **procPtr)
+}
+declare 151 {
+    Tcl_Channel Tcl_GetChannel(Tcl_Interp *interp, const char *chanName,
+	    int *modePtr)
+}
+declare 152 {
+    int Tcl_GetChannelBufferSize(Tcl_Channel chan)
+}
+declare 153 {
+    int Tcl_GetChannelHandle(Tcl_Channel chan, int direction,
+	    ClientData *handlePtr)
+}
+declare 154 {
+    ClientData Tcl_GetChannelInstanceData(Tcl_Channel chan)
+}
+declare 155 {
+    int Tcl_GetChannelMode(Tcl_Channel chan)
+}
+declare 156 {
+    CONST84_RETURN char *Tcl_GetChannelName(Tcl_Channel chan)
+}
+declare 157 {
+    int Tcl_GetChannelOption(Tcl_Interp *interp, Tcl_Channel chan,
+	    const char *optionName, Tcl_DString *dsPtr)
+}
+declare 158 {
+    CONST86 Tcl_ChannelType *Tcl_GetChannelType(Tcl_Channel chan)
+}
+declare 159 {
+    int Tcl_GetCommandInfo(Tcl_Interp *interp, const char *cmdName,
+	    Tcl_CmdInfo *infoPtr)
+}
+declare 160 {
+    CONST84_RETURN char *Tcl_GetCommandName(Tcl_Interp *interp,
+	    Tcl_Command command)
+}
+declare 161 {
+    int Tcl_GetErrno(void)
+}
+declare 162 {
+    CONST84_RETURN char *Tcl_GetHostName(void)
+}
+declare 163 {
+    int Tcl_GetInterpPath(Tcl_Interp *askInterp, Tcl_Interp *slaveInterp)
+}
+declare 164 {
+    Tcl_Interp *Tcl_GetMaster(Tcl_Interp *interp)
+}
+declare 165 {
+    const char *Tcl_GetNameOfExecutable(void)
+}
+declare 166 {
+    Tcl_Obj *Tcl_GetObjResult(Tcl_Interp *interp)
+}
+
+# Tcl_GetOpenFile is only available on unix, but it is a part of the old
+# generic interface, so we inlcude it here for compatibility reasons.
+
+declare 167 unix {
+    int Tcl_GetOpenFile(Tcl_Interp *interp, const char *chanID, int forWriting,
+	    int checkUsage, ClientData *filePtr)
+}
+# Obsolete.  Should now use Tcl_FSGetPathType which is objectified
+# and therefore usually faster.
+declare 168 {
+    Tcl_PathType Tcl_GetPathType(const char *path)
+}
+declare 169 {
+    int Tcl_Gets(Tcl_Channel chan, Tcl_DString *dsPtr)
+}
+declare 170 {
+    int Tcl_GetsObj(Tcl_Channel chan, Tcl_Obj *objPtr)
+}
+declare 171 {
+    int Tcl_GetServiceMode(void)
+}
+declare 172 {
+    Tcl_Interp *Tcl_GetSlave(Tcl_Interp *interp, const char *slaveName)
+}
+declare 173 {
+    Tcl_Channel Tcl_GetStdChannel(int type)
+}
+declare 174 {
+    CONST84_RETURN char *Tcl_GetStringResult(Tcl_Interp *interp)
+}
+declare 175 {
+    CONST84_RETURN char *Tcl_GetVar(Tcl_Interp *interp, const char *varName,
+	    int flags)
+}
+declare 176 {
+    CONST84_RETURN char *Tcl_GetVar2(Tcl_Interp *interp, const char *part1,
+	    const char *part2, int flags)
+}
+declare 177 {
+    int Tcl_GlobalEval(Tcl_Interp *interp, const char *command)
+}
+declare 178 {
+    int Tcl_GlobalEvalObj(Tcl_Interp *interp, Tcl_Obj *objPtr)
+}
+declare 179 {
+    int Tcl_HideCommand(Tcl_Interp *interp, const char *cmdName,
+	    const char *hiddenCmdToken)
+}
+declare 180 {
+    int Tcl_Init(Tcl_Interp *interp)
+}
+declare 181 {
+    void Tcl_InitHashTable(Tcl_HashTable *tablePtr, int keyType)
+}
+declare 182 {
+    int Tcl_InputBlocked(Tcl_Channel chan)
+}
+declare 183 {
+    int Tcl_InputBuffered(Tcl_Channel chan)
+}
+declare 184 {
+    int Tcl_InterpDeleted(Tcl_Interp *interp)
+}
+declare 185 {
+    int Tcl_IsSafe(Tcl_Interp *interp)
+}
+# Obsolete, use Tcl_FSJoinPath
+declare 186 {
+    char *Tcl_JoinPath(int argc, CONST84 char *const *argv,
+	    Tcl_DString *resultPtr)
+}
+declare 187 {
+    int Tcl_LinkVar(Tcl_Interp *interp, const char *varName, char *addr,
+	    int type)
+}
+
+# This slot is reserved for use by the plus patch:
+#  declare 188 {
+#	Tcl_MainLoop
+#  }
+
+declare 189 {
+    Tcl_Channel Tcl_MakeFileChannel(ClientData handle, int mode)
+}
+declare 190 {
+    int Tcl_MakeSafe(Tcl_Interp *interp)
+}
+declare 191 {
+    Tcl_Channel Tcl_MakeTcpClientChannel(ClientData tcpSocket)
+}
+declare 192 {
+    char *Tcl_Merge(int argc, CONST84 char *const *argv)
+}
+declare 193 {
+    Tcl_HashEntry *Tcl_NextHashEntry(Tcl_HashSearch *searchPtr)
+}
+declare 194 {
+    void Tcl_NotifyChannel(Tcl_Channel channel, int mask)
+}
+declare 195 {
+    Tcl_Obj *Tcl_ObjGetVar2(Tcl_Interp *interp, Tcl_Obj *part1Ptr,
+	    Tcl_Obj *part2Ptr, int flags)
+}
+declare 196 {
+    Tcl_Obj *Tcl_ObjSetVar2(Tcl_Interp *interp, Tcl_Obj *part1Ptr,
+	    Tcl_Obj *part2Ptr, Tcl_Obj *newValuePtr, int flags)
+}
+declare 197 {
+    Tcl_Channel Tcl_OpenCommandChannel(Tcl_Interp *interp, int argc,
+	    CONST84 char **argv, int flags)
+}
+# This is obsolete, use Tcl_FSOpenFileChannel
+declare 198 {
+    Tcl_Channel Tcl_OpenFileChannel(Tcl_Interp *interp, const char *fileName,
+	    const char *modeString, int permissions)
+}
+declare 199 {
+    Tcl_Channel Tcl_OpenTcpClient(Tcl_Interp *interp, int port,
+	    const char *address, const char *myaddr, int myport, int async)
+}
+declare 200 {
+    Tcl_Channel Tcl_OpenTcpServer(Tcl_Interp *interp, int port,
+	    const char *host, Tcl_TcpAcceptProc *acceptProc,
+	    ClientData callbackData)
+}
+declare 201 {
+    void Tcl_Preserve(ClientData data)
+}
+declare 202 {
+    void Tcl_PrintDouble(Tcl_Interp *interp, double value, char *dst)
+}
+declare 203 {
+    int Tcl_PutEnv(const char *assignment)
+}
+declare 204 {
+    CONST84_RETURN char *Tcl_PosixError(Tcl_Interp *interp)
+}
+declare 205 {
+    void Tcl_QueueEvent(Tcl_Event *evPtr, Tcl_QueuePosition position)
+}
+declare 206 {
+    int Tcl_Read(Tcl_Channel chan, char *bufPtr, int toRead)
+}
+declare 207 {
+    void Tcl_ReapDetachedProcs(void)
+}
+declare 208 {
+    int Tcl_RecordAndEval(Tcl_Interp *interp, const char *cmd, int flags)
+}
+declare 209 {
+    int Tcl_RecordAndEvalObj(Tcl_Interp *interp, Tcl_Obj *cmdPtr, int flags)
+}
+declare 210 {
+    void Tcl_RegisterChannel(Tcl_Interp *interp, Tcl_Channel chan)
+}
+declare 211 {
+    void Tcl_RegisterObjType(const Tcl_ObjType *typePtr)
+}
+declare 212 {
+    Tcl_RegExp Tcl_RegExpCompile(Tcl_Interp *interp, const char *pattern)
+}
+declare 213 {
+    int Tcl_RegExpExec(Tcl_Interp *interp, Tcl_RegExp regexp,
+	    const char *text, const char *start)
+}
+declare 214 {
+    int Tcl_RegExpMatch(Tcl_Interp *interp, const char *text,
+	    const char *pattern)
+}
+declare 215 {
+    void Tcl_RegExpRange(Tcl_RegExp regexp, int index,
+	    CONST84 char **startPtr, CONST84 char **endPtr)
+}
+declare 216 {
+    void Tcl_Release(ClientData clientData)
+}
+declare 217 {
+    void Tcl_ResetResult(Tcl_Interp *interp)
+}
+declare 218 {
+    int Tcl_ScanElement(const char *src, int *flagPtr)
+}
+declare 219 {
+    int Tcl_ScanCountedElement(const char *src, int length, int *flagPtr)
+}
+# Obsolete
+declare 220 {
+    int Tcl_SeekOld(Tcl_Channel chan, int offset, int mode)
+}
+declare 221 {
+    int Tcl_ServiceAll(void)
+}
+declare 222 {
+    int Tcl_ServiceEvent(int flags)
+}
+declare 223 {
+    void Tcl_SetAssocData(Tcl_Interp *interp, const char *name,
+	    Tcl_InterpDeleteProc *proc, ClientData clientData)
+}
+declare 224 {
+    void Tcl_SetChannelBufferSize(Tcl_Channel chan, int sz)
+}
+declare 225 {
+    int Tcl_SetChannelOption(Tcl_Interp *interp, Tcl_Channel chan,
+	    const char *optionName, const char *newValue)
+}
+declare 226 {
+    int Tcl_SetCommandInfo(Tcl_Interp *interp, const char *cmdName,
+	    const Tcl_CmdInfo *infoPtr)
+}
+declare 227 {
+    void Tcl_SetErrno(int err)
+}
+declare 228 {
+    void Tcl_SetErrorCode(Tcl_Interp *interp, ...)
+}
+declare 229 {
+    void Tcl_SetMaxBlockTime(const Tcl_Time *timePtr)
+}
+declare 230 {
+    void Tcl_SetPanicProc(TCL_NORETURN1 Tcl_PanicProc *panicProc)
+}
+declare 231 {
+    int Tcl_SetRecursionLimit(Tcl_Interp *interp, int depth)
+}
+declare 232 {
+    void Tcl_SetResult(Tcl_Interp *interp, char *result,
+	    Tcl_FreeProc *freeProc)
+}
+declare 233 {
+    int Tcl_SetServiceMode(int mode)
+}
+declare 234 {
+    void Tcl_SetObjErrorCode(Tcl_Interp *interp, Tcl_Obj *errorObjPtr)
+}
+declare 235 {
+    void Tcl_SetObjResult(Tcl_Interp *interp, Tcl_Obj *resultObjPtr)
+}
+declare 236 {
+    void Tcl_SetStdChannel(Tcl_Channel channel, int type)
+}
+declare 237 {
+    CONST84_RETURN char *Tcl_SetVar(Tcl_Interp *interp, const char *varName,
+	    const char *newValue, int flags)
+}
+declare 238 {
+    CONST84_RETURN char *Tcl_SetVar2(Tcl_Interp *interp, const char *part1,
+	    const char *part2, const char *newValue, int flags)
+}
+declare 239 {
+    CONST84_RETURN char *Tcl_SignalId(int sig)
+}
+declare 240 {
+    CONST84_RETURN char *Tcl_SignalMsg(int sig)
+}
+declare 241 {
+    void Tcl_SourceRCFile(Tcl_Interp *interp)
+}
+declare 242 {
+    int Tcl_SplitList(Tcl_Interp *interp, const char *listStr, int *argcPtr,
+	    CONST84 char ***argvPtr)
+}
+# Obsolete, use Tcl_FSSplitPath
+declare 243 {
+    void Tcl_SplitPath(const char *path, int *argcPtr, CONST84 char ***argvPtr)
+}
+declare 244 {
+    void Tcl_StaticPackage(Tcl_Interp *interp, const char *pkgName,
+	    Tcl_PackageInitProc *initProc, Tcl_PackageInitProc *safeInitProc)
+}
+declare 245 {
+    int Tcl_StringMatch(const char *str, const char *pattern)
+}
+# Obsolete
+declare 246 {
+    int Tcl_TellOld(Tcl_Channel chan)
+}
+declare 247 {
+    int Tcl_TraceVar(Tcl_Interp *interp, const char *varName, int flags,
+	    Tcl_VarTraceProc *proc, ClientData clientData)
+}
+declare 248 {
+    int Tcl_TraceVar2(Tcl_Interp *interp, const char *part1, const char *part2,
+	    int flags, Tcl_VarTraceProc *proc, ClientData clientData)
+}
+declare 249 {
+    char *Tcl_TranslateFileName(Tcl_Interp *interp, const char *name,
+	    Tcl_DString *bufferPtr)
+}
+declare 250 {
+    int Tcl_Ungets(Tcl_Channel chan, const char *str, int len, int atHead)
+}
+declare 251 {
+    void Tcl_UnlinkVar(Tcl_Interp *interp, const char *varName)
+}
+declare 252 {
+    int Tcl_UnregisterChannel(Tcl_Interp *interp, Tcl_Channel chan)
+}
+declare 253 {
+    int Tcl_UnsetVar(Tcl_Interp *interp, const char *varName, int flags)
+}
+declare 254 {
+    int Tcl_UnsetVar2(Tcl_Interp *interp, const char *part1, const char *part2,
+	    int flags)
+}
+declare 255 {
+    void Tcl_UntraceVar(Tcl_Interp *interp, const char *varName, int flags,
+	    Tcl_VarTraceProc *proc, ClientData clientData)
+}
+declare 256 {
+    void Tcl_UntraceVar2(Tcl_Interp *interp, const char *part1,
+	    const char *part2, int flags, Tcl_VarTraceProc *proc,
+	    ClientData clientData)
+}
+declare 257 {
+    void Tcl_UpdateLinkedVar(Tcl_Interp *interp, const char *varName)
+}
+declare 258 {
+    int Tcl_UpVar(Tcl_Interp *interp, const char *frameName,
+	    const char *varName, const char *localName, int flags)
+}
+declare 259 {
+    int Tcl_UpVar2(Tcl_Interp *interp, const char *frameName, const char *part1,
+	    const char *part2, const char *localName, int flags)
+}
+declare 260 {
+    int Tcl_VarEval(Tcl_Interp *interp, ...)
+}
+declare 261 {
+    ClientData Tcl_VarTraceInfo(Tcl_Interp *interp, const char *varName,
+	    int flags, Tcl_VarTraceProc *procPtr, ClientData prevClientData)
+}
+declare 262 {
+    ClientData Tcl_VarTraceInfo2(Tcl_Interp *interp, const char *part1,
+	    const char *part2, int flags, Tcl_VarTraceProc *procPtr,
+	    ClientData prevClientData)
+}
+declare 263 {
+    int Tcl_Write(Tcl_Channel chan, const char *s, int slen)
+}
+declare 264 {
+    void Tcl_WrongNumArgs(Tcl_Interp *interp, int objc,
+	    Tcl_Obj *const objv[], const char *message)
+}
+declare 265 {
+    int Tcl_DumpActiveMemory(const char *fileName)
+}
+declare 266 {
+    void Tcl_ValidateAllMemory(const char *file, int line)
+}
+declare 267 {
+    void Tcl_AppendResultVA(Tcl_Interp *interp, va_list argList)
+}
+declare 268 {
+    void Tcl_AppendStringsToObjVA(Tcl_Obj *objPtr, va_list argList)
+}
+declare 269 {
+    char *Tcl_HashStats(Tcl_HashTable *tablePtr)
+}
+declare 270 {
+    CONST84_RETURN char *Tcl_ParseVar(Tcl_Interp *interp, const char *start,
+	    CONST84 char **termPtr)
+}
+declare 271 {
+    CONST84_RETURN char *Tcl_PkgPresent(Tcl_Interp *interp, const char *name,
+	    const char *version, int exact)
+}
+declare 272 {
+    CONST84_RETURN char *Tcl_PkgPresentEx(Tcl_Interp *interp,
+	    const char *name, const char *version, int exact,
+	    void *clientDataPtr)
+}
+declare 273 {
+    int Tcl_PkgProvide(Tcl_Interp *interp, const char *name,
+	    const char *version)
+}
+# TIP #268: The internally used new Require function is in slot 573.
+declare 274 {
+    CONST84_RETURN char *Tcl_PkgRequire(Tcl_Interp *interp, const char *name,
+	    const char *version, int exact)
+}
+declare 275 {
+    void Tcl_SetErrorCodeVA(Tcl_Interp *interp, va_list argList)
+}
+declare 276 {
+    int  Tcl_VarEvalVA(Tcl_Interp *interp, va_list argList)
+}
+declare 277 {
+    Tcl_Pid Tcl_WaitPid(Tcl_Pid pid, int *statPtr, int options)
+}
+declare 278 {
+    TCL_NORETURN void Tcl_PanicVA(const char *format, va_list argList)
+}
+declare 279 {
+    void Tcl_GetVersion(int *major, int *minor, int *patchLevel, int *type)
+}
+declare 280 {
+    void Tcl_InitMemory(Tcl_Interp *interp)
+}
+
+# Andreas Kupries <a.kupries@westend.com>, 03/21/1999
+# "Trf-Patch for filtering channels"
+#
+# C-Level API for (un)stacking of channels. This allows the introduction
+# of filtering channels with relatively little changes to the core.
+# This patch was created in cooperation with Jan Nijtmans j.nijtmans@chello.nl
+# and is therefore part of his plus-patches too.
+#
+# It would have been possible to place the following definitions according
+# to the alphabetical order used elsewhere in this file, but I decided
+# against that to ease the maintenance of the patch across new tcl versions
+# (patch usually has no problems to integrate the patch file for the last
+# version into the new one).
+
+declare 281 {
+    Tcl_Channel Tcl_StackChannel(Tcl_Interp *interp,
+	    const Tcl_ChannelType *typePtr, ClientData instanceData,
+	    int mask, Tcl_Channel prevChan)
+}
+declare 282 {
+    int Tcl_UnstackChannel(Tcl_Interp *interp, Tcl_Channel chan)
+}
+declare 283 {
+    Tcl_Channel Tcl_GetStackedChannel(Tcl_Channel chan)
+}
+
+# 284 was reserved, but added in 8.4a2
+declare 284 {
+    void Tcl_SetMainLoop(Tcl_MainLoopProc *proc)
+}
+
+# Reserved for future use (8.0.x vs. 8.1)
+#  declare 285 {
+#  }
+
+# Added in 8.1:
+
+declare 286 {
+    void Tcl_AppendObjToObj(Tcl_Obj *objPtr, Tcl_Obj *appendObjPtr)
+}
+declare 287 {
+    Tcl_Encoding Tcl_CreateEncoding(const Tcl_EncodingType *typePtr)
+}
+declare 288 {
+    void Tcl_CreateThreadExitHandler(Tcl_ExitProc *proc, ClientData clientData)
+}
+declare 289 {
+    void Tcl_DeleteThreadExitHandler(Tcl_ExitProc *proc, ClientData clientData)
+}
+declare 290 {
+    void Tcl_DiscardResult(Tcl_SavedResult *statePtr)
+}
+declare 291 {
+    int Tcl_EvalEx(Tcl_Interp *interp, const char *script, int numBytes,
+	    int flags)
+}
+declare 292 {
+    int Tcl_EvalObjv(Tcl_Interp *interp, int objc, Tcl_Obj *const objv[],
+	    int flags)
+}
+declare 293 {
+    int Tcl_EvalObjEx(Tcl_Interp *interp, Tcl_Obj *objPtr, int flags)
+}
+declare 294 {
+    void Tcl_ExitThread(int status)
+}
+declare 295 {
+    int Tcl_ExternalToUtf(Tcl_Interp *interp, Tcl_Encoding encoding,
+	    const char *src, int srcLen, int flags,
+	    Tcl_EncodingState *statePtr, char *dst, int dstLen,
+	    int *srcReadPtr, int *dstWrotePtr, int *dstCharsPtr)
+}
+declare 296 {
+    char *Tcl_ExternalToUtfDString(Tcl_Encoding encoding,
+	    const char *src, int srcLen, Tcl_DString *dsPtr)
+}
+declare 297 {
+    void Tcl_FinalizeThread(void)
+}
+declare 298 {
+    void Tcl_FinalizeNotifier(ClientData clientData)
+}
+declare 299 {
+    void Tcl_FreeEncoding(Tcl_Encoding encoding)
+}
+declare 300 {
+    Tcl_ThreadId Tcl_GetCurrentThread(void)
+}
+declare 301 {
+    Tcl_Encoding Tcl_GetEncoding(Tcl_Interp *interp, const char *name)
+}
+declare 302 {
+    CONST84_RETURN char *Tcl_GetEncodingName(Tcl_Encoding encoding)
+}
+declare 303 {
+    void Tcl_GetEncodingNames(Tcl_Interp *interp)
+}
+declare 304 {
+    int Tcl_GetIndexFromObjStruct(Tcl_Interp *interp, Tcl_Obj *objPtr,
+	    const void *tablePtr, int offset, const char *msg, int flags,
+	    int *indexPtr)
+}
+declare 305 {
+    void *Tcl_GetThreadData(Tcl_ThreadDataKey *keyPtr, int size)
+}
+declare 306 {
+    Tcl_Obj *Tcl_GetVar2Ex(Tcl_Interp *interp, const char *part1,
+	    const char *part2, int flags)
+}
+declare 307 {
+    ClientData Tcl_InitNotifier(void)
+}
+declare 308 {
+    void Tcl_MutexLock(Tcl_Mutex *mutexPtr)
+}
+declare 309 {
+    void Tcl_MutexUnlock(Tcl_Mutex *mutexPtr)
+}
+declare 310 {
+    void Tcl_ConditionNotify(Tcl_Condition *condPtr)
+}
+declare 311 {
+    void Tcl_ConditionWait(Tcl_Condition *condPtr, Tcl_Mutex *mutexPtr,
+	    const Tcl_Time *timePtr)
+}
+declare 312 {
+    int Tcl_NumUtfChars(const char *src, int length)
+}
+declare 313 {
+    int Tcl_ReadChars(Tcl_Channel channel, Tcl_Obj *objPtr, int charsToRead,
+	    int appendFlag)
+}
+declare 314 {
+    void Tcl_RestoreResult(Tcl_Interp *interp, Tcl_SavedResult *statePtr)
+}
+declare 315 {
+    void Tcl_SaveResult(Tcl_Interp *interp, Tcl_SavedResult *statePtr)
+}
+declare 316 {
+    int Tcl_SetSystemEncoding(Tcl_Interp *interp, const char *name)
+}
+declare 317 {
+    Tcl_Obj *Tcl_SetVar2Ex(Tcl_Interp *interp, const char *part1,
+	    const char *part2, Tcl_Obj *newValuePtr, int flags)
+}
+declare 318 {
+    void Tcl_ThreadAlert(Tcl_ThreadId threadId)
+}
+declare 319 {
+    void Tcl_ThreadQueueEvent(Tcl_ThreadId threadId, Tcl_Event *evPtr,
+	    Tcl_QueuePosition position)
+}
+declare 320 {
+    Tcl_UniChar Tcl_UniCharAtIndex(const char *src, int index)
+}
+declare 321 {
+    Tcl_UniChar Tcl_UniCharToLower(int ch)
+}
+declare 322 {
+    Tcl_UniChar Tcl_UniCharToTitle(int ch)
+}
+declare 323 {
+    Tcl_UniChar Tcl_UniCharToUpper(int ch)
+}
+declare 324 {
+    int Tcl_UniCharToUtf(int ch, char *buf)
+}
+declare 325 {
+    CONST84_RETURN char *Tcl_UtfAtIndex(const char *src, int index)
+}
+declare 326 {
+    int Tcl_UtfCharComplete(const char *src, int length)
+}
+declare 327 {
+    int Tcl_UtfBackslash(const char *src, int *readPtr, char *dst)
+}
+declare 328 {
+    CONST84_RETURN char *Tcl_UtfFindFirst(const char *src, int ch)
+}
+declare 329 {
+    CONST84_RETURN char *Tcl_UtfFindLast(const char *src, int ch)
+}
+declare 330 {
+    CONST84_RETURN char *Tcl_UtfNext(const char *src)
+}
+declare 331 {
+    CONST84_RETURN char *Tcl_UtfPrev(const char *src, const char *start)
+}
+declare 332 {
+    int Tcl_UtfToExternal(Tcl_Interp *interp, Tcl_Encoding encoding,
+	    const char *src, int srcLen, int flags,
+	    Tcl_EncodingState *statePtr, char *dst, int dstLen,
+	    int *srcReadPtr, int *dstWrotePtr, int *dstCharsPtr)
+}
+declare 333 {
+    char *Tcl_UtfToExternalDString(Tcl_Encoding encoding,
+	    const char *src, int srcLen, Tcl_DString *dsPtr)
+}
+declare 334 {
+    int Tcl_UtfToLower(char *src)
+}
+declare 335 {
+    int Tcl_UtfToTitle(char *src)
+}
+declare 336 {
+    int Tcl_UtfToUniChar(const char *src, Tcl_UniChar *chPtr)
+}
+declare 337 {
+    int Tcl_UtfToUpper(char *src)
+}
+declare 338 {
+    int Tcl_WriteChars(Tcl_Channel chan, const char *src, int srcLen)
+}
+declare 339 {
+    int Tcl_WriteObj(Tcl_Channel chan, Tcl_Obj *objPtr)
+}
+declare 340 {
+    char *Tcl_GetString(Tcl_Obj *objPtr)
+}
+declare 341 {
+    CONST84_RETURN char *Tcl_GetDefaultEncodingDir(void)
+}
+declare 342 {
+    void Tcl_SetDefaultEncodingDir(const char *path)
+}
+declare 343 {
+    void Tcl_AlertNotifier(ClientData clientData)
+}
+declare 344 {
+    void Tcl_ServiceModeHook(int mode)
+}
+declare 345 {
+    int Tcl_UniCharIsAlnum(int ch)
+}
+declare 346 {
+    int Tcl_UniCharIsAlpha(int ch)
+}
+declare 347 {
+    int Tcl_UniCharIsDigit(int ch)
+}
+declare 348 {
+    int Tcl_UniCharIsLower(int ch)
+}
+declare 349 {
+    int Tcl_UniCharIsSpace(int ch)
+}
+declare 350 {
+    int Tcl_UniCharIsUpper(int ch)
+}
+declare 351 {
+    int Tcl_UniCharIsWordChar(int ch)
+}
+declare 352 {
+    int Tcl_UniCharLen(const Tcl_UniChar *uniStr)
+}
+declare 353 {
+    int Tcl_UniCharNcmp(const Tcl_UniChar *ucs, const Tcl_UniChar *uct,
+	    unsigned long numChars)
+}
+declare 354 {
+    char *Tcl_UniCharToUtfDString(const Tcl_UniChar *uniStr,
+	    int uniLength, Tcl_DString *dsPtr)
+}
+declare 355 {
+    Tcl_UniChar *Tcl_UtfToUniCharDString(const char *src,
+	    int length, Tcl_DString *dsPtr)
+}
+declare 356 {
+    Tcl_RegExp Tcl_GetRegExpFromObj(Tcl_Interp *interp, Tcl_Obj *patObj,
+	    int flags)
+}
+declare 357 {
+    Tcl_Obj *Tcl_EvalTokens(Tcl_Interp *interp, Tcl_Token *tokenPtr,
+	    int count)
+}
+declare 358 {
+    void Tcl_FreeParse(Tcl_Parse *parsePtr)
+}
+declare 359 {
+    void Tcl_LogCommandInfo(Tcl_Interp *interp, const char *script,
+	    const char *command, int length)
+}
+declare 360 {
+    int Tcl_ParseBraces(Tcl_Interp *interp, const char *start, int numBytes,
+	    Tcl_Parse *parsePtr, int append, CONST84 char **termPtr)
+}
+declare 361 {
+    int Tcl_ParseCommand(Tcl_Interp *interp, const char *start, int numBytes,
+	    int nested, Tcl_Parse *parsePtr)
+}
+declare 362 {
+    int Tcl_ParseExpr(Tcl_Interp *interp, const char *start, int numBytes,
+	    Tcl_Parse *parsePtr)
+}
+declare 363 {
+    int Tcl_ParseQuotedString(Tcl_Interp *interp, const char *start,
+	    int numBytes, Tcl_Parse *parsePtr, int append,
+	    CONST84 char **termPtr)
+}
+declare 364 {
+    int Tcl_ParseVarName(Tcl_Interp *interp, const char *start, int numBytes,
+	    Tcl_Parse *parsePtr, int append)
+}
+# These 4 functions are obsolete, use Tcl_FSGetCwd, Tcl_FSChdir,
+# Tcl_FSAccess and Tcl_FSStat
+declare 365 {
+    char *Tcl_GetCwd(Tcl_Interp *interp, Tcl_DString *cwdPtr)
+}
+declare 366 {
+   int Tcl_Chdir(const char *dirName)
+}
+declare 367 {
+   int Tcl_Access(const char *path, int mode)
+}
+declare 368 {
+    int Tcl_Stat(const char *path, struct stat *bufPtr)
+}
+declare 369 {
+    int Tcl_UtfNcmp(const char *s1, const char *s2, unsigned long n)
+}
+declare 370 {
+    int Tcl_UtfNcasecmp(const char *s1, const char *s2, unsigned long n)
+}
+declare 371 {
+    int Tcl_StringCaseMatch(const char *str, const char *pattern, int nocase)
+}
+declare 372 {
+    int Tcl_UniCharIsControl(int ch)
+}
+declare 373 {
+    int Tcl_UniCharIsGraph(int ch)
+}
+declare 374 {
+    int Tcl_UniCharIsPrint(int ch)
+}
+declare 375 {
+    int Tcl_UniCharIsPunct(int ch)
+}
+declare 376 {
+    int Tcl_RegExpExecObj(Tcl_Interp *interp, Tcl_RegExp regexp,
+	    Tcl_Obj *textObj, int offset, int nmatches, int flags)
+}
+declare 377 {
+    void Tcl_RegExpGetInfo(Tcl_RegExp regexp, Tcl_RegExpInfo *infoPtr)
+}
+declare 378 {
+    Tcl_Obj *Tcl_NewUnicodeObj(const Tcl_UniChar *unicode, int numChars)
+}
+declare 379 {
+    void Tcl_SetUnicodeObj(Tcl_Obj *objPtr, const Tcl_UniChar *unicode,
+	    int numChars)
+}
+declare 380 {
+    int Tcl_GetCharLength(Tcl_Obj *objPtr)
+}
+declare 381 {
+    Tcl_UniChar Tcl_GetUniChar(Tcl_Obj *objPtr, int index)
+}
+declare 382 {
+    Tcl_UniChar *Tcl_GetUnicode(Tcl_Obj *objPtr)
+}
+declare 383 {
+    Tcl_Obj *Tcl_GetRange(Tcl_Obj *objPtr, int first, int last)
+}
+declare 384 {
+    void Tcl_AppendUnicodeToObj(Tcl_Obj *objPtr, const Tcl_UniChar *unicode,
+	    int length)
+}
+declare 385 {
+    int Tcl_RegExpMatchObj(Tcl_Interp *interp, Tcl_Obj *textObj,
+	    Tcl_Obj *patternObj)
+}
+declare 386 {
+    void Tcl_SetNotifier(Tcl_NotifierProcs *notifierProcPtr)
+}
+declare 387 {
+    Tcl_Mutex *Tcl_GetAllocMutex(void)
+}
+declare 388 {
+    int Tcl_GetChannelNames(Tcl_Interp *interp)
+}
+declare 389 {
+    int Tcl_GetChannelNamesEx(Tcl_Interp *interp, const char *pattern)
+}
+declare 390 {
+    int Tcl_ProcObjCmd(ClientData clientData, Tcl_Interp *interp,
+	    int objc, Tcl_Obj *const objv[])
+}
+declare 391 {
+    void Tcl_ConditionFinalize(Tcl_Condition *condPtr)
+}
+declare 392 {
+    void Tcl_MutexFinalize(Tcl_Mutex *mutex)
+}
+declare 393 {
+    int Tcl_CreateThread(Tcl_ThreadId *idPtr, Tcl_ThreadCreateProc *proc,
+	    ClientData clientData, int stackSize, int flags)
+}
+
+# Introduced in 8.3.2
+declare 394 {
+    int Tcl_ReadRaw(Tcl_Channel chan, char *dst, int bytesToRead)
+}
+declare 395 {
+    int Tcl_WriteRaw(Tcl_Channel chan, const char *src, int srcLen)
+}
+declare 396 {
+    Tcl_Channel Tcl_GetTopChannel(Tcl_Channel chan)
+}
+declare 397 {
+    int Tcl_ChannelBuffered(Tcl_Channel chan)
+}
+declare 398 {
+    CONST84_RETURN char *Tcl_ChannelName(const Tcl_ChannelType *chanTypePtr)
+}
+declare 399 {
+    Tcl_ChannelTypeVersion Tcl_ChannelVersion(
+	    const Tcl_ChannelType *chanTypePtr)
+}
+declare 400 {
+    Tcl_DriverBlockModeProc *Tcl_ChannelBlockModeProc(
+	    const Tcl_ChannelType *chanTypePtr)
+}
+declare 401 {
+    Tcl_DriverCloseProc *Tcl_ChannelCloseProc(
+	    const Tcl_ChannelType *chanTypePtr)
+}
+declare 402 {
+    Tcl_DriverClose2Proc *Tcl_ChannelClose2Proc(
+	    const Tcl_ChannelType *chanTypePtr)
+}
+declare 403 {
+    Tcl_DriverInputProc *Tcl_ChannelInputProc(
+	    const Tcl_ChannelType *chanTypePtr)
+}
+declare 404 {
+    Tcl_DriverOutputProc *Tcl_ChannelOutputProc(
+	    const Tcl_ChannelType *chanTypePtr)
+}
+declare 405 {
+    Tcl_DriverSeekProc *Tcl_ChannelSeekProc(
+	    const Tcl_ChannelType *chanTypePtr)
+}
+declare 406 {
+    Tcl_DriverSetOptionProc *Tcl_ChannelSetOptionProc(
+	    const Tcl_ChannelType *chanTypePtr)
+}
+declare 407 {
+    Tcl_DriverGetOptionProc *Tcl_ChannelGetOptionProc(
+	    const Tcl_ChannelType *chanTypePtr)
+}
+declare 408 {
+    Tcl_DriverWatchProc *Tcl_ChannelWatchProc(
+	    const Tcl_ChannelType *chanTypePtr)
+}
+declare 409 {
+    Tcl_DriverGetHandleProc *Tcl_ChannelGetHandleProc(
+	    const Tcl_ChannelType *chanTypePtr)
+}
+declare 410 {
+    Tcl_DriverFlushProc *Tcl_ChannelFlushProc(
+	    const Tcl_ChannelType *chanTypePtr)
+}
+declare 411 {
+    Tcl_DriverHandlerProc *Tcl_ChannelHandlerProc(
+	    const Tcl_ChannelType *chanTypePtr)
+}
+
+# Introduced in 8.4a2
+declare 412 {
+    int Tcl_JoinThread(Tcl_ThreadId threadId, int *result)
+}
+declare 413 {
+    int Tcl_IsChannelShared(Tcl_Channel channel)
+}
+declare 414 {
+    int Tcl_IsChannelRegistered(Tcl_Interp *interp, Tcl_Channel channel)
+}
+declare 415 {
+    void Tcl_CutChannel(Tcl_Channel channel)
+}
+declare 416 {
+    void Tcl_SpliceChannel(Tcl_Channel channel)
+}
+declare 417 {
+    void Tcl_ClearChannelHandlers(Tcl_Channel channel)
+}
+declare 418 {
+    int Tcl_IsChannelExisting(const char *channelName)
+}
+declare 419 {
+    int Tcl_UniCharNcasecmp(const Tcl_UniChar *ucs, const Tcl_UniChar *uct,
+	    unsigned long numChars)
+}
+declare 420 {
+    int Tcl_UniCharCaseMatch(const Tcl_UniChar *uniStr,
+	    const Tcl_UniChar *uniPattern, int nocase)
+}
+declare 421 {
+    Tcl_HashEntry *Tcl_FindHashEntry(Tcl_HashTable *tablePtr, const void *key)
+}
+declare 422 {
+    Tcl_HashEntry *Tcl_CreateHashEntry(Tcl_HashTable *tablePtr,
+	    const void *key, int *newPtr)
+}
+declare 423 {
+    void Tcl_InitCustomHashTable(Tcl_HashTable *tablePtr, int keyType,
+	    const Tcl_HashKeyType *typePtr)
+}
+declare 424 {
+    void Tcl_InitObjHashTable(Tcl_HashTable *tablePtr)
+}
+declare 425 {
+    ClientData Tcl_CommandTraceInfo(Tcl_Interp *interp, const char *varName,
+	    int flags, Tcl_CommandTraceProc *procPtr,
+	    ClientData prevClientData)
+}
+declare 426 {
+    int Tcl_TraceCommand(Tcl_Interp *interp, const char *varName, int flags,
+	    Tcl_CommandTraceProc *proc, ClientData clientData)
+}
+declare 427 {
+    void Tcl_UntraceCommand(Tcl_Interp *interp, const char *varName,
+	    int flags, Tcl_CommandTraceProc *proc, ClientData clientData)
+}
+declare 428 {
+    char *Tcl_AttemptAlloc(unsigned int size)
+}
+declare 429 {
+    char *Tcl_AttemptDbCkalloc(unsigned int size, const char *file, int line)
+}
+declare 430 {
+    char *Tcl_AttemptRealloc(char *ptr, unsigned int size)
+}
+declare 431 {
+    char *Tcl_AttemptDbCkrealloc(char *ptr, unsigned int size,
+	    const char *file, int line)
+}
+declare 432 {
+    int Tcl_AttemptSetObjLength(Tcl_Obj *objPtr, int length)
+}
+
+# TIP#10 (thread-aware channels) akupries
+declare 433 {
+    Tcl_ThreadId Tcl_GetChannelThread(Tcl_Channel channel)
+}
+
+# introduced in 8.4a3
+declare 434 {
+    Tcl_UniChar *Tcl_GetUnicodeFromObj(Tcl_Obj *objPtr, int *lengthPtr)
+}
+
+# TIP#15 (math function introspection) dkf
+declare 435 {
+    int Tcl_GetMathFuncInfo(Tcl_Interp *interp, const char *name,
+	    int *numArgsPtr, Tcl_ValueType **argTypesPtr,
+	    Tcl_MathProc **procPtr, ClientData *clientDataPtr)
+}
+declare 436 {
+    Tcl_Obj *Tcl_ListMathFuncs(Tcl_Interp *interp, const char *pattern)
+}
+
+# TIP#36 (better access to 'subst') dkf
+declare 437 {
+    Tcl_Obj *Tcl_SubstObj(Tcl_Interp *interp, Tcl_Obj *objPtr, int flags)
+}
+
+# TIP#17 (virtual filesystem layer) vdarley
+declare 438 {
+    int Tcl_DetachChannel(Tcl_Interp *interp, Tcl_Channel channel)
+}
+declare 439 {
+    int Tcl_IsStandardChannel(Tcl_Channel channel)
+}
+declare 440 {
+    int	Tcl_FSCopyFile(Tcl_Obj *srcPathPtr, Tcl_Obj *destPathPtr)
+}
+declare 441 {
+    int	Tcl_FSCopyDirectory(Tcl_Obj *srcPathPtr,
+	    Tcl_Obj *destPathPtr, Tcl_Obj **errorPtr)
+}
+declare 442 {
+    int	Tcl_FSCreateDirectory(Tcl_Obj *pathPtr)
+}
+declare 443 {
+    int	Tcl_FSDeleteFile(Tcl_Obj *pathPtr)
+}
+declare 444 {
+    int	Tcl_FSLoadFile(Tcl_Interp *interp, Tcl_Obj *pathPtr, const char *sym1,
+	    const char *sym2, Tcl_PackageInitProc **proc1Ptr,
+	    Tcl_PackageInitProc **proc2Ptr, Tcl_LoadHandle *handlePtr,
+	    Tcl_FSUnloadFileProc **unloadProcPtr)
+}
+declare 445 {
+    int	Tcl_FSMatchInDirectory(Tcl_Interp *interp, Tcl_Obj *result,
+	    Tcl_Obj *pathPtr, const char *pattern, Tcl_GlobTypeData *types)
+}
+declare 446 {
+    Tcl_Obj *Tcl_FSLink(Tcl_Obj *pathPtr, Tcl_Obj *toPtr, int linkAction)
+}
+declare 447 {
+    int Tcl_FSRemoveDirectory(Tcl_Obj *pathPtr,
+	    int recursive, Tcl_Obj **errorPtr)
+}
+declare 448 {
+    int	Tcl_FSRenameFile(Tcl_Obj *srcPathPtr, Tcl_Obj *destPathPtr)
+}
+declare 449 {
+    int	Tcl_FSLstat(Tcl_Obj *pathPtr, Tcl_StatBuf *buf)
+}
+declare 450 {
+    int Tcl_FSUtime(Tcl_Obj *pathPtr, struct utimbuf *tval)
+}
+declare 451 {
+    int Tcl_FSFileAttrsGet(Tcl_Interp *interp,
+	    int index, Tcl_Obj *pathPtr, Tcl_Obj **objPtrRef)
+}
+declare 452 {
+    int Tcl_FSFileAttrsSet(Tcl_Interp *interp,
+	    int index, Tcl_Obj *pathPtr, Tcl_Obj *objPtr)
+}
+declare 453 {
+    const char *CONST86 *Tcl_FSFileAttrStrings(Tcl_Obj *pathPtr,
+	    Tcl_Obj **objPtrRef)
+}
+declare 454 {
+    int Tcl_FSStat(Tcl_Obj *pathPtr, Tcl_StatBuf *buf)
+}
+declare 455 {
+    int Tcl_FSAccess(Tcl_Obj *pathPtr, int mode)
+}
+declare 456 {
+    Tcl_Channel Tcl_FSOpenFileChannel(Tcl_Interp *interp, Tcl_Obj *pathPtr,
+	    const char *modeString, int permissions)
+}
+declare 457 {
+    Tcl_Obj *Tcl_FSGetCwd(Tcl_Interp *interp)
+}
+declare 458 {
+    int Tcl_FSChdir(Tcl_Obj *pathPtr)
+}
+declare 459 {
+    int Tcl_FSConvertToPathType(Tcl_Interp *interp, Tcl_Obj *pathPtr)
+}
+declare 460 {
+    Tcl_Obj *Tcl_FSJoinPath(Tcl_Obj *listObj, int elements)
+}
+declare 461 {
+    Tcl_Obj *Tcl_FSSplitPath(Tcl_Obj *pathPtr, int *lenPtr)
+}
+declare 462 {
+    int Tcl_FSEqualPaths(Tcl_Obj *firstPtr, Tcl_Obj *secondPtr)
+}
+declare 463 {
+    Tcl_Obj *Tcl_FSGetNormalizedPath(Tcl_Interp *interp, Tcl_Obj *pathPtr)
+}
+declare 464 {
+    Tcl_Obj *Tcl_FSJoinToPath(Tcl_Obj *pathPtr, int objc,
+	    Tcl_Obj *const objv[])
+}
+declare 465 {
+    ClientData Tcl_FSGetInternalRep(Tcl_Obj *pathPtr,
+	    const Tcl_Filesystem *fsPtr)
+}
+declare 466 {
+    Tcl_Obj *Tcl_FSGetTranslatedPath(Tcl_Interp *interp, Tcl_Obj *pathPtr)
+}
+declare 467 {
+    int Tcl_FSEvalFile(Tcl_Interp *interp, Tcl_Obj *fileName)
+}
+declare 468 {
+    Tcl_Obj *Tcl_FSNewNativePath(const Tcl_Filesystem *fromFilesystem,
+	    ClientData clientData)
+}
+declare 469 {
+    const void *Tcl_FSGetNativePath(Tcl_Obj *pathPtr)
+}
+declare 470 {
+    Tcl_Obj *Tcl_FSFileSystemInfo(Tcl_Obj *pathPtr)
+}
+declare 471 {
+    Tcl_Obj *Tcl_FSPathSeparator(Tcl_Obj *pathPtr)
+}
+declare 472 {
+    Tcl_Obj *Tcl_FSListVolumes(void)
+}
+declare 473 {
+    int Tcl_FSRegister(ClientData clientData, const Tcl_Filesystem *fsPtr)
+}
+declare 474 {
+    int Tcl_FSUnregister(const Tcl_Filesystem *fsPtr)
+}
+declare 475 {
+    ClientData Tcl_FSData(const Tcl_Filesystem *fsPtr)
+}
+declare 476 {
+    const char *Tcl_FSGetTranslatedStringPath(Tcl_Interp *interp,
+	    Tcl_Obj *pathPtr)
+}
+declare 477 {
+    CONST86 Tcl_Filesystem *Tcl_FSGetFileSystemForPath(Tcl_Obj *pathPtr)
+}
+declare 478 {
+    Tcl_PathType Tcl_FSGetPathType(Tcl_Obj *pathPtr)
+}
+
+# TIP#49 (detection of output buffering) akupries
+declare 479 {
+    int Tcl_OutputBuffered(Tcl_Channel chan)
+}
+declare 480 {
+    void Tcl_FSMountsChanged(const Tcl_Filesystem *fsPtr)
+}
+
+# TIP#56 (evaluate a parsed script) msofer
+declare 481 {
+    int Tcl_EvalTokensStandard(Tcl_Interp *interp, Tcl_Token *tokenPtr,
+	    int count)
+}
+
+# TIP#73 (access to current time) kbk
+declare 482 {
+    void Tcl_GetTime(Tcl_Time *timeBuf)
+}
+
+# TIP#32 (object-enabled traces) kbk
+declare 483 {
+    Tcl_Trace Tcl_CreateObjTrace(Tcl_Interp *interp, int level, int flags,
+	    Tcl_CmdObjTraceProc *objProc, ClientData clientData,
+	    Tcl_CmdObjTraceDeleteProc *delProc)
+}
+declare 484 {
+    int Tcl_GetCommandInfoFromToken(Tcl_Command token, Tcl_CmdInfo *infoPtr)
+}
+declare 485 {
+    int Tcl_SetCommandInfoFromToken(Tcl_Command token,
+	    const Tcl_CmdInfo *infoPtr)
+}
+
+### New functions on 64-bit dev branch ###
+# TIP#72 (64-bit values) dkf
+declare 486 {
+    Tcl_Obj *Tcl_DbNewWideIntObj(Tcl_WideInt wideValue,
+	    const char *file, int line)
+}
+declare 487 {
+    int Tcl_GetWideIntFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr,
+	    Tcl_WideInt *widePtr)
+}
+declare 488 {
+    Tcl_Obj *Tcl_NewWideIntObj(Tcl_WideInt wideValue)
+}
+declare 489 {
+    void Tcl_SetWideIntObj(Tcl_Obj *objPtr, Tcl_WideInt wideValue)
+}
+declare 490 {
+    Tcl_StatBuf *Tcl_AllocStatBuf(void)
+}
+declare 491 {
+    Tcl_WideInt Tcl_Seek(Tcl_Channel chan, Tcl_WideInt offset, int mode)
+}
+declare 492 {
+    Tcl_WideInt Tcl_Tell(Tcl_Channel chan)
+}
+
+# TIP#91 (back-compat enhancements for channels) dkf
+declare 493 {
+    Tcl_DriverWideSeekProc *Tcl_ChannelWideSeekProc(
+	    const Tcl_ChannelType *chanTypePtr)
+}
+
+# ----- BASELINE -- FOR -- 8.4.0 ----- #
+
+# TIP#111 (dictionaries) dkf
+declare 494 {
+    int Tcl_DictObjPut(Tcl_Interp *interp, Tcl_Obj *dictPtr,
+	    Tcl_Obj *keyPtr, Tcl_Obj *valuePtr)
+}
+declare 495 {
+    int Tcl_DictObjGet(Tcl_Interp *interp, Tcl_Obj *dictPtr, Tcl_Obj *keyPtr,
+	    Tcl_Obj **valuePtrPtr)
+}
+declare 496 {
+    int Tcl_DictObjRemove(Tcl_Interp *interp, Tcl_Obj *dictPtr,
+	    Tcl_Obj *keyPtr)
+}
+declare 497 {
+    int Tcl_DictObjSize(Tcl_Interp *interp, Tcl_Obj *dictPtr, int *sizePtr)
+}
+declare 498 {
+    int Tcl_DictObjFirst(Tcl_Interp *interp, Tcl_Obj *dictPtr,
+	    Tcl_DictSearch *searchPtr,
+	    Tcl_Obj **keyPtrPtr, Tcl_Obj **valuePtrPtr, int *donePtr)
+}
+declare 499 {
+    void Tcl_DictObjNext(Tcl_DictSearch *searchPtr,
+	    Tcl_Obj **keyPtrPtr, Tcl_Obj **valuePtrPtr, int *donePtr)
+}
+declare 500 {
+    void Tcl_DictObjDone(Tcl_DictSearch *searchPtr)
+}
+declare 501 {
+    int Tcl_DictObjPutKeyList(Tcl_Interp *interp, Tcl_Obj *dictPtr,
+	    int keyc, Tcl_Obj *const *keyv, Tcl_Obj *valuePtr)
+}
+declare 502 {
+    int Tcl_DictObjRemoveKeyList(Tcl_Interp *interp, Tcl_Obj *dictPtr,
+	    int keyc, Tcl_Obj *const *keyv)
+}
+declare 503 {
+    Tcl_Obj *Tcl_NewDictObj(void)
+}
+declare 504 {
+    Tcl_Obj *Tcl_DbNewDictObj(const char *file, int line)
+}
+
+# TIP#59 (configuration reporting) akupries
+declare 505 {
+    void Tcl_RegisterConfig(Tcl_Interp *interp, const char *pkgName,
+	    const Tcl_Config *configuration, const char *valEncoding)
+}
+
+# TIP #139 (partial exposure of namespace API - transferred from tclInt.decls)
+# dkf, API by Brent Welch?
+declare 506 {
+    Tcl_Namespace *Tcl_CreateNamespace(Tcl_Interp *interp, const char *name,
+	    ClientData clientData, Tcl_NamespaceDeleteProc *deleteProc)
+}
+declare 507 {
+    void Tcl_DeleteNamespace(Tcl_Namespace *nsPtr)
+}
+declare 508 {
+    int Tcl_AppendExportList(Tcl_Interp *interp, Tcl_Namespace *nsPtr,
+	    Tcl_Obj *objPtr)
+}
+declare 509 {
+    int Tcl_Export(Tcl_Interp *interp, Tcl_Namespace *nsPtr,
+	    const char *pattern, int resetListFirst)
+}
+declare 510 {
+    int Tcl_Import(Tcl_Interp *interp, Tcl_Namespace *nsPtr,
+	    const char *pattern, int allowOverwrite)
+}
+declare 511 {
+    int Tcl_ForgetImport(Tcl_Interp *interp, Tcl_Namespace *nsPtr,
+	    const char *pattern)
+}
+declare 512 {
+    Tcl_Namespace *Tcl_GetCurrentNamespace(Tcl_Interp *interp)
+}
+declare 513 {
+    Tcl_Namespace *Tcl_GetGlobalNamespace(Tcl_Interp *interp)
+}
+declare 514 {
+    Tcl_Namespace *Tcl_FindNamespace(Tcl_Interp *interp, const char *name,
+	    Tcl_Namespace *contextNsPtr, int flags)
+}
+declare 515 {
+    Tcl_Command Tcl_FindCommand(Tcl_Interp *interp, const char *name,
+	    Tcl_Namespace *contextNsPtr, int flags)
+}
+declare 516 {
+    Tcl_Command Tcl_GetCommandFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr)
+}
+declare 517 {
+    void Tcl_GetCommandFullName(Tcl_Interp *interp, Tcl_Command command,
+	    Tcl_Obj *objPtr)
+}
+
+# TIP#137 (encoding-aware source command) dgp for Anton Kovalenko
+declare 518 {
+    int Tcl_FSEvalFileEx(Tcl_Interp *interp, Tcl_Obj *fileName,
+	    const char *encodingName)
+}
+
+# TIP#121 (exit handler) dkf for Joe Mistachkin
+declare 519 {
+    Tcl_ExitProc *Tcl_SetExitProc(TCL_NORETURN1 Tcl_ExitProc *proc)
+}
+
+# TIP#143 (resource limits) dkf
+declare 520 {
+    void Tcl_LimitAddHandler(Tcl_Interp *interp, int type,
+	    Tcl_LimitHandlerProc *handlerProc, ClientData clientData,
+	    Tcl_LimitHandlerDeleteProc *deleteProc)
+}
+declare 521 {
+    void Tcl_LimitRemoveHandler(Tcl_Interp *interp, int type,
+	    Tcl_LimitHandlerProc *handlerProc, ClientData clientData)
+}
+declare 522 {
+    int Tcl_LimitReady(Tcl_Interp *interp)
+}
+declare 523 {
+    int Tcl_LimitCheck(Tcl_Interp *interp)
+}
+declare 524 {
+    int Tcl_LimitExceeded(Tcl_Interp *interp)
+}
+declare 525 {
+    void Tcl_LimitSetCommands(Tcl_Interp *interp, int commandLimit)
+}
+declare 526 {
+    void Tcl_LimitSetTime(Tcl_Interp *interp, Tcl_Time *timeLimitPtr)
+}
+declare 527 {
+    void Tcl_LimitSetGranularity(Tcl_Interp *interp, int type, int granularity)
+}
+declare 528 {
+    int Tcl_LimitTypeEnabled(Tcl_Interp *interp, int type)
+}
+declare 529 {
+    int Tcl_LimitTypeExceeded(Tcl_Interp *interp, int type)
+}
+declare 530 {
+    void Tcl_LimitTypeSet(Tcl_Interp *interp, int type)
+}
+declare 531 {
+    void Tcl_LimitTypeReset(Tcl_Interp *interp, int type)
+}
+declare 532 {
+    int Tcl_LimitGetCommands(Tcl_Interp *interp)
+}
+declare 533 {
+    void Tcl_LimitGetTime(Tcl_Interp *interp, Tcl_Time *timeLimitPtr)
+}
+declare 534 {
+    int Tcl_LimitGetGranularity(Tcl_Interp *interp, int type)
+}
+
+# TIP#226 (interpreter result state management) dgp
+declare 535 {
+    Tcl_InterpState Tcl_SaveInterpState(Tcl_Interp *interp, int status)
+}
+declare 536 {
+    int Tcl_RestoreInterpState(Tcl_Interp *interp, Tcl_InterpState state)
+}
+declare 537 {
+    void Tcl_DiscardInterpState(Tcl_InterpState state)
+}
+
+# TIP#227 (return options interface) dgp
+declare 538 {
+    int Tcl_SetReturnOptions(Tcl_Interp *interp, Tcl_Obj *options)
+}
+declare 539 {
+    Tcl_Obj *Tcl_GetReturnOptions(Tcl_Interp *interp, int result)
+}
+
+# TIP#235 (ensembles) dkf
+declare 540 {
+    int Tcl_IsEnsemble(Tcl_Command token)
+}
+declare 541 {
+    Tcl_Command Tcl_CreateEnsemble(Tcl_Interp *interp, const char *name,
+	    Tcl_Namespace *namespacePtr, int flags)
+}
+declare 542 {
+    Tcl_Command Tcl_FindEnsemble(Tcl_Interp *interp, Tcl_Obj *cmdNameObj,
+	    int flags)
+}
+declare 543 {
+    int Tcl_SetEnsembleSubcommandList(Tcl_Interp *interp, Tcl_Command token,
+	    Tcl_Obj *subcmdList)
+}
+declare 544 {
+    int Tcl_SetEnsembleMappingDict(Tcl_Interp *interp, Tcl_Command token,
+	    Tcl_Obj *mapDict)
+}
+declare 545 {
+    int Tcl_SetEnsembleUnknownHandler(Tcl_Interp *interp, Tcl_Command token,
+	    Tcl_Obj *unknownList)
+}
+declare 546 {
+    int Tcl_SetEnsembleFlags(Tcl_Interp *interp, Tcl_Command token, int flags)
+}
+declare 547 {
+    int Tcl_GetEnsembleSubcommandList(Tcl_Interp *interp, Tcl_Command token,
+	    Tcl_Obj **subcmdListPtr)
+}
+declare 548 {
+    int Tcl_GetEnsembleMappingDict(Tcl_Interp *interp, Tcl_Command token,
+	    Tcl_Obj **mapDictPtr)
+}
+declare 549 {
+    int Tcl_GetEnsembleUnknownHandler(Tcl_Interp *interp, Tcl_Command token,
+	    Tcl_Obj **unknownListPtr)
+}
+declare 550 {
+    int Tcl_GetEnsembleFlags(Tcl_Interp *interp, Tcl_Command token,
+	    int *flagsPtr)
+}
+declare 551 {
+    int Tcl_GetEnsembleNamespace(Tcl_Interp *interp, Tcl_Command token,
+	    Tcl_Namespace **namespacePtrPtr)
+}
+
+# TIP#233 (virtualized time) akupries
+declare 552 {
+    void Tcl_SetTimeProc(Tcl_GetTimeProc *getProc,
+	    Tcl_ScaleTimeProc *scaleProc,
+	    ClientData clientData)
+}
+declare 553 {
+    void Tcl_QueryTimeProc(Tcl_GetTimeProc **getProc,
+	    Tcl_ScaleTimeProc **scaleProc,
+	    ClientData *clientData)
+}
+
+# TIP#218 (driver thread actions) davygrvy/akupries ChannelType ver 4
+declare 554 {
+    Tcl_DriverThreadActionProc *Tcl_ChannelThreadActionProc(
+	    const Tcl_ChannelType *chanTypePtr)
+}
+
+# TIP#237 (arbitrary-precision integers) kbk
+declare 555 {
+    Tcl_Obj *Tcl_NewBignumObj(mp_int *value)
+}
+declare 556 {
+    Tcl_Obj *Tcl_DbNewBignumObj(mp_int *value, const char *file, int line)
+}
+declare 557 {
+    void Tcl_SetBignumObj(Tcl_Obj *obj, mp_int *value)
+}
+declare 558 {
+    int Tcl_GetBignumFromObj(Tcl_Interp *interp, Tcl_Obj *obj, mp_int *value)
+}
+declare 559 {
+    int Tcl_TakeBignumFromObj(Tcl_Interp *interp, Tcl_Obj *obj, mp_int *value)
+}
+
+# TIP #208 ('chan' command) jeffh
+declare 560 {
+    int Tcl_TruncateChannel(Tcl_Channel chan, Tcl_WideInt length)
+}
+declare 561 {
+    Tcl_DriverTruncateProc *Tcl_ChannelTruncateProc(
+	    const Tcl_ChannelType *chanTypePtr)
+}
+
+# TIP#219 (channel reflection api) akupries
+declare 562 {
+    void Tcl_SetChannelErrorInterp(Tcl_Interp *interp, Tcl_Obj *msg)
+}
+declare 563 {
+    void Tcl_GetChannelErrorInterp(Tcl_Interp *interp, Tcl_Obj **msg)
+}
+declare 564 {
+    void Tcl_SetChannelError(Tcl_Channel chan, Tcl_Obj *msg)
+}
+declare 565 {
+    void Tcl_GetChannelError(Tcl_Channel chan, Tcl_Obj **msg)
+}
+
+# TIP #237 (additional conversion functions for bignum support) kbk/dgp
+declare 566 {
+    int Tcl_InitBignumFromDouble(Tcl_Interp *interp, double initval,
+	    mp_int *toInit)
+}
+
+# TIP#181 (namespace unknown command) dgp for Neil Madden
+declare 567 {
+    Tcl_Obj *Tcl_GetNamespaceUnknownHandler(Tcl_Interp *interp,
+	    Tcl_Namespace *nsPtr)
+}
+declare 568 {
+    int Tcl_SetNamespaceUnknownHandler(Tcl_Interp *interp,
+	    Tcl_Namespace *nsPtr, Tcl_Obj *handlerPtr)
+}
+
+# TIP#258 (enhanced interface for encodings) dgp
+declare 569 {
+    int Tcl_GetEncodingFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr,
+	    Tcl_Encoding *encodingPtr)
+}
+declare 570 {
+    Tcl_Obj *Tcl_GetEncodingSearchPath(void)
+}
+declare 571 {
+    int Tcl_SetEncodingSearchPath(Tcl_Obj *searchPath)
+}
+declare 572 {
+    const char *Tcl_GetEncodingNameFromEnvironment(Tcl_DString *bufPtr)
+}
+
+# TIP#268 (extended version numbers and requirements) akupries
+declare 573 {
+    int Tcl_PkgRequireProc(Tcl_Interp *interp, const char *name,
+	    int objc, Tcl_Obj *const objv[], void *clientDataPtr)
+}
+
+# TIP#270 (utility C routines for string formatting) dgp
+declare 574 {
+    void Tcl_AppendObjToErrorInfo(Tcl_Interp *interp, Tcl_Obj *objPtr)
+}
+declare 575 {
+    void Tcl_AppendLimitedToObj(Tcl_Obj *objPtr, const char *bytes, int length,
+	    int limit, const char *ellipsis)
+}
+declare 576 {
+    Tcl_Obj *Tcl_Format(Tcl_Interp *interp, const char *format, int objc,
+	    Tcl_Obj *const objv[])
+}
+declare 577 {
+    int Tcl_AppendFormatToObj(Tcl_Interp *interp, Tcl_Obj *objPtr,
+	    const char *format, int objc, Tcl_Obj *const objv[])
+}
+declare 578 {
+    Tcl_Obj *Tcl_ObjPrintf(const char *format, ...)
+}
+declare 579 {
+    void Tcl_AppendPrintfToObj(Tcl_Obj *objPtr, const char *format, ...)
+}
+
+# ----- BASELINE -- FOR -- 8.5.0 ----- #
+
+# TIP #285 (script cancellation support) jmistachkin
+declare 580 {
+    int Tcl_CancelEval(Tcl_Interp *interp, Tcl_Obj *resultObjPtr,
+	    ClientData clientData, int flags)
+}
+declare 581 {
+    int Tcl_Canceled(Tcl_Interp *interp, int flags)
+}
+
+# TIP#304 (chan pipe) aferrieux
+declare 582 {
+    int Tcl_CreatePipe(Tcl_Interp  *interp, Tcl_Channel *rchan,
+	    Tcl_Channel *wchan, int flags)
+}
+
+# TIP #322 (NRE public interface) msofer
+declare 583 {
+    Tcl_Command Tcl_NRCreateCommand(Tcl_Interp *interp,
+	    const char *cmdName, Tcl_ObjCmdProc *proc,
+	    Tcl_ObjCmdProc *nreProc, ClientData clientData,
+	    Tcl_CmdDeleteProc *deleteProc)
+}
+declare 584 {
+    int Tcl_NREvalObj(Tcl_Interp *interp, Tcl_Obj *objPtr, int flags)
+}
+declare 585 {
+    int Tcl_NREvalObjv(Tcl_Interp *interp, int objc, Tcl_Obj *const objv[],
+	    int flags)
+}
+declare 586 {
+    int Tcl_NRCmdSwap(Tcl_Interp *interp, Tcl_Command cmd, int objc,
+	    Tcl_Obj *const objv[], int flags)
+}
+declare 587 {
+    void Tcl_NRAddCallback(Tcl_Interp *interp, Tcl_NRPostProc *postProcPtr,
+	    ClientData data0, ClientData data1, ClientData data2,
+	    ClientData data3)
+}
+# For use by NR extenders, to have a simple way to also provide a (required!)
+# classic objProc
+declare 588 {
+    int Tcl_NRCallObjProc(Tcl_Interp *interp, Tcl_ObjCmdProc *objProc,
+	    ClientData clientData, int objc, Tcl_Obj *const objv[])
+}
+
+# TIP#316 (Tcl_StatBuf reader functions) dkf
+declare 589 {
+    unsigned Tcl_GetFSDeviceFromStat(const Tcl_StatBuf *statPtr)
+}
+declare 590 {
+    unsigned Tcl_GetFSInodeFromStat(const Tcl_StatBuf *statPtr)
+}
+declare 591 {
+    unsigned Tcl_GetModeFromStat(const Tcl_StatBuf *statPtr)
+}
+declare 592 {
+    int Tcl_GetLinkCountFromStat(const Tcl_StatBuf *statPtr)
+}
+declare 593 {
+    int Tcl_GetUserIdFromStat(const Tcl_StatBuf *statPtr)
+}
+declare 594 {
+    int Tcl_GetGroupIdFromStat(const Tcl_StatBuf *statPtr)
+}
+declare 595 {
+    int Tcl_GetDeviceTypeFromStat(const Tcl_StatBuf *statPtr)
+}
+declare 596 {
+    Tcl_WideInt Tcl_GetAccessTimeFromStat(const Tcl_StatBuf *statPtr)
+}
+declare 597 {
+    Tcl_WideInt Tcl_GetModificationTimeFromStat(const Tcl_StatBuf *statPtr)
+}
+declare 598 {
+    Tcl_WideInt Tcl_GetChangeTimeFromStat(const Tcl_StatBuf *statPtr)
+}
+declare 599 {
+    Tcl_WideUInt Tcl_GetSizeFromStat(const Tcl_StatBuf *statPtr)
+}
+declare 600 {
+    Tcl_WideUInt Tcl_GetBlocksFromStat(const Tcl_StatBuf *statPtr)
+}
+declare 601 {
+    unsigned Tcl_GetBlockSizeFromStat(const Tcl_StatBuf *statPtr)
+}
+
+# TIP#314 (ensembles with parameters) dkf for Lars Hellstr"om
+declare 602 {
+    int Tcl_SetEnsembleParameterList(Tcl_Interp *interp, Tcl_Command token,
+	    Tcl_Obj *paramList)
+}
+declare 603 {
+    int Tcl_GetEnsembleParameterList(Tcl_Interp *interp, Tcl_Command token,
+	    Tcl_Obj **paramListPtr)
+}
+
+# TIP#265 (option parser) dkf for Sam Bromley
+declare 604 {
+    int Tcl_ParseArgsObjv(Tcl_Interp *interp, const Tcl_ArgvInfo *argTable,
+	    int *objcPtr, Tcl_Obj *const *objv, Tcl_Obj ***remObjv)
+}
+
+# TIP#336 (manipulate the error line) dgp
+declare 605 {
+    int Tcl_GetErrorLine(Tcl_Interp *interp)
+}
+declare 606 {
+    void Tcl_SetErrorLine(Tcl_Interp *interp, int lineNum)
+}
+
+# TIP#307 (move results between interpreters) dkf
+declare 607 {
+    void Tcl_TransferResult(Tcl_Interp *sourceInterp, int result,
+	    Tcl_Interp *targetInterp)
+}
+
+# TIP#335 (detect if interpreter in use) jmistachkin
+declare 608 {
+    int Tcl_InterpActive(Tcl_Interp *interp)
+}
+
+# TIP#337 (log exception for background processing) dgp
+declare 609 {
+    void Tcl_BackgroundException(Tcl_Interp *interp, int code)
+}
+
+# TIP#234 (zlib interface) dkf/Pascal Scheffers
+declare 610 {
+    int Tcl_ZlibDeflate(Tcl_Interp *interp, int format, Tcl_Obj *data,
+	    int level, Tcl_Obj *gzipHeaderDictObj)
+}
+declare 611 {
+    int Tcl_ZlibInflate(Tcl_Interp *interp, int format, Tcl_Obj *data,
+	    int buffersize, Tcl_Obj *gzipHeaderDictObj)
+}
+declare 612 {
+    unsigned int Tcl_ZlibCRC32(unsigned int crc, const unsigned char *buf,
+	    int len)
+}
+declare 613 {
+    unsigned int Tcl_ZlibAdler32(unsigned int adler, const unsigned char *buf,
+	    int len)
+}
+declare 614 {
+    int Tcl_ZlibStreamInit(Tcl_Interp *interp, int mode, int format,
+	    int level, Tcl_Obj *dictObj, Tcl_ZlibStream *zshandle)
+}
+declare 615 {
+    Tcl_Obj *Tcl_ZlibStreamGetCommandName(Tcl_ZlibStream zshandle)
+}
+declare 616 {
+    int Tcl_ZlibStreamEof(Tcl_ZlibStream zshandle)
+}
+declare 617 {
+    int Tcl_ZlibStreamChecksum(Tcl_ZlibStream zshandle)
+}
+declare 618 {
+    int Tcl_ZlibStreamPut(Tcl_ZlibStream zshandle, Tcl_Obj *data, int flush)
+}
+declare 619 {
+    int Tcl_ZlibStreamGet(Tcl_ZlibStream zshandle, Tcl_Obj *data, int count)
+}
+declare 620 {
+    int Tcl_ZlibStreamClose(Tcl_ZlibStream zshandle)
+}
+declare 621 {
+    int Tcl_ZlibStreamReset(Tcl_ZlibStream zshandle)
+}
+
+# TIP 338 (control over startup script) dgp
+declare 622 {
+    void Tcl_SetStartupScript(Tcl_Obj *path, const char *encoding)
+}
+declare 623 {
+    Tcl_Obj *Tcl_GetStartupScript(const char **encodingPtr)
+}
+
+# TIP#332 (half-close made public) aferrieux
+declare 624 {
+    int Tcl_CloseEx(Tcl_Interp *interp, Tcl_Channel chan, int flags)
+}
+
+# TIP #353 (NR-enabled expressions) dgp
+declare 625 {
+    int Tcl_NRExprObj(Tcl_Interp *interp, Tcl_Obj *objPtr, Tcl_Obj *resultPtr)
+}
+
+# TIP #356 (NR-enabled substitution) dgp
+declare 626 {
+    int Tcl_NRSubstObj(Tcl_Interp *interp, Tcl_Obj *objPtr, int flags)
+}
+
+# TIP #357 (Export TclLoadFile and TclpFindSymbol) kbk
+declare 627 {
+    int Tcl_LoadFile(Tcl_Interp *interp, Tcl_Obj *pathPtr,
+		     const char *const symv[], int flags, void *procPtrs,
+		     Tcl_LoadHandle *handlePtr)
+}
+declare 628 {
+    void *Tcl_FindSymbol(Tcl_Interp *interp, Tcl_LoadHandle handle,
+			 const char *symbol)
+}
+declare 629 {
+    int Tcl_FSUnloadFile(Tcl_Interp *interp, Tcl_LoadHandle handlePtr)
+}
+
+# TIP #400
+declare 630 {
+    void Tcl_ZlibStreamSetCompressionDictionary(Tcl_ZlibStream zhandle,
+	    Tcl_Obj *compressionDictionaryObj)
+}
+
+# ----- BASELINE -- FOR -- 8.6.0 ----- #
+
+##############################################################################
+
+# Define the platform specific public Tcl interface. These functions are only
+# available on the designated platform.
+
+interface tclPlat
+
+################################
+# Unix specific functions
+#   (none)
+
+################################
+# Windows specific functions
+
+# Added in Tcl 8.1
+
+declare 0 win {
+    TCHAR *Tcl_WinUtfToTChar(const char *str, int len, Tcl_DString *dsPtr)
+}
+declare 1 win {
+    char *Tcl_WinTCharToUtf(const TCHAR *str, int len, Tcl_DString *dsPtr)
+}
+
+################################
+# Mac OS X specific functions
+
+declare 0 macosx {
+    int Tcl_MacOSXOpenBundleResources(Tcl_Interp *interp,
+	    const char *bundleName, int hasResourceFile,
+	    int maxPathLen, char *libraryPath)
+}
+declare 1 macosx {
+    int Tcl_MacOSXOpenVersionedBundleResources(Tcl_Interp *interp,
+	    const char *bundleName, const char *bundleVersion,
+	    int hasResourceFile, int maxPathLen, char *libraryPath)
+}
+
+##############################################################################
+
+# Public functions that are not accessible via the stubs table.
+
+export {
+    void Tcl_Main(int argc, char **argv, Tcl_AppInitProc *appInitProc)
+}
+export {
+    const char *Tcl_InitStubs(Tcl_Interp *interp, const char *version,
+	int exact)
+}
+export {
+    const char *TclTomMathInitializeStubs(Tcl_Interp* interp,
+	const char* version, int epoch, int revision)
+}
+export {
+    const char *Tcl_PkgInitStubsCheck(Tcl_Interp *interp, const char *version,
+	int exact)
+}
+export {
+    void Tcl_GetMemoryInfo(Tcl_DString *dsPtr)
+}
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/generic/tcl.h b/generic/tcl.h
new file mode 100644
index 0000000..3037ceb
--- /dev/null
+++ b/generic/tcl.h
@@ -0,0 +1,2665 @@
+/*
+ * tcl.h --
+ *
+ *	This header file describes the externally-visible facilities of the
+ *	Tcl interpreter.
+ *
+ * Copyright (c) 1987-1994 The Regents of the University of California.
+ * Copyright (c) 1993-1996 Lucent Technologies.
+ * Copyright (c) 1994-1998 Sun Microsystems, Inc.
+ * Copyright (c) 1998-2000 by Scriptics Corporation.
+ * Copyright (c) 2002 by Kevin B. Kenny.  All rights reserved.
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#ifndef _TCL
+#define _TCL
+
+/*
+ * For C++ compilers, use extern "C"
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * The following defines are used to indicate the various release levels.
+ */
+
+#define TCL_ALPHA_RELEASE	0
+#define TCL_BETA_RELEASE	1
+#define TCL_FINAL_RELEASE	2
+
+/*
+ * When version numbers change here, must also go into the following files and
+ * update the version numbers:
+ *
+ * library/init.tcl	(1 LOC patch)
+ * unix/configure.in	(2 LOC Major, 2 LOC minor, 1 LOC patch)
+ * win/configure.in	(as above)
+ * win/tcl.m4		(not patchlevel)
+ * win/makefile.bc	(not patchlevel) 2 LOC
+ * README		(sections 0 and 2, with and without separator)
+ * macosx/Tcl.pbproj/project.pbxproj (not patchlevel) 1 LOC
+ * macosx/Tcl.pbproj/default.pbxuser (not patchlevel) 1 LOC
+ * macosx/Tcl.xcode/project.pbxproj (not patchlevel) 2 LOC
+ * macosx/Tcl.xcode/default.pbxuser (not patchlevel) 1 LOC
+ * macosx/Tcl-Common.xcconfig (not patchlevel) 1 LOC
+ * win/README		(not patchlevel) (sections 0 and 2)
+ * unix/tcl.spec	(1 LOC patch)
+ * tools/tcl.hpj.in	(not patchlevel, for windows installer)
+ */
+
+#define TCL_MAJOR_VERSION   8
+#define TCL_MINOR_VERSION   6
+#define TCL_RELEASE_LEVEL   TCL_FINAL_RELEASE
+#define TCL_RELEASE_SERIAL  6
+
+#define TCL_VERSION	    "8.6"
+#define TCL_PATCH_LEVEL	    "8.6.6"
+
+/*
+ *----------------------------------------------------------------------------
+ * The following definitions set up the proper options for Windows compilers.
+ * We use this method because there is no autoconf equivalent.
+ */
+
+#ifdef _WIN32
+#   ifndef __WIN32__
+#	define __WIN32__
+#   endif
+#   ifndef WIN32
+#	define WIN32
+#   endif
+#endif
+
+/*
+ * Utility macros: STRINGIFY takes an argument and wraps it in "" (double
+ * quotation marks), JOIN joins two arguments.
+ */
+
+#ifndef STRINGIFY
+#  define STRINGIFY(x) STRINGIFY1(x)
+#  define STRINGIFY1(x) #x
+#endif
+#ifndef JOIN
+#  define JOIN(a,b) JOIN1(a,b)
+#  define JOIN1(a,b) a##b
+#endif
+
+/*
+ * A special definition used to allow this header file to be included from
+ * windows resource files so that they can obtain version information.
+ * RC_INVOKED is defined by default by the windows RC tool.
+ *
+ * Resource compilers don't like all the C stuff, like typedefs and function
+ * declarations, that occur below, so block them out.
+ */
+
+#ifndef RC_INVOKED
+
+/*
+ * Special macro to define mutexes, that doesn't do anything if we are not
+ * using threads.
+ */
+
+#ifdef TCL_THREADS
+#define TCL_DECLARE_MUTEX(name) static Tcl_Mutex name;
+#else
+#define TCL_DECLARE_MUTEX(name)
+#endif
+
+/*
+ * Tcl's public routine Tcl_FSSeek() uses the values SEEK_SET, SEEK_CUR, and
+ * SEEK_END, all #define'd by stdio.h .
+ *
+ * Also, many extensions need stdio.h, and they've grown accustomed to tcl.h
+ * providing it for them rather than #include-ing it themselves as they
+ * should, so also for their sake, we keep the #include to be consistent with
+ * prior Tcl releases.
+ */
+
+#include <stdio.h>
+
+/*
+ *----------------------------------------------------------------------------
+ * Support for functions with a variable number of arguments.
+ *
+ * The following TCL_VARARGS* macros are to support old extensions
+ * written for older versions of Tcl where the macros permitted
+ * support for the varargs.h system as well as stdarg.h .
+ *
+ * New code should just directly be written to use stdarg.h conventions.
+ */
+
+#include <stdarg.h>
+#ifndef TCL_NO_DEPRECATED
+#    define TCL_VARARGS(type, name) (type name, ...)
+#    define TCL_VARARGS_DEF(type, name) (type name, ...)
+#    define TCL_VARARGS_START(type, name, list) (va_start(list, name), name)
+#endif
+#if defined(__GNUC__) && (__GNUC__ > 2)
+#   define TCL_FORMAT_PRINTF(a,b) __attribute__ ((__format__ (__printf__, a, b)))
+#   define TCL_NORETURN __attribute__ ((noreturn))
+#   if defined(BUILD_tcl) || defined(BUILD_tk)
+#	define TCL_NORETURN1 __attribute__ ((noreturn))
+#   else
+#	define TCL_NORETURN1 /* nothing */
+#   endif
+#else
+#   define TCL_FORMAT_PRINTF(a,b)
+#   if defined(_MSC_VER) && (_MSC_VER >= 1310)
+#	define TCL_NORETURN _declspec(noreturn)
+#   else
+#	define TCL_NORETURN /* nothing */
+#   endif
+#   define TCL_NORETURN1 /* nothing */
+#endif
+
+/*
+ * Allow a part of Tcl's API to be explicitly marked as deprecated.
+ *
+ * Used to make TIP 330/336 generate moans even if people use the
+ * compatibility macros. Change your code, guys! We won't support you forever.
+ */
+
+#if defined(__GNUC__) && ((__GNUC__ >= 4) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 1)))
+#   if (__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5))
+#	define TCL_DEPRECATED_API(msg)	__attribute__ ((__deprecated__ (msg)))
+#   else
+#	define TCL_DEPRECATED_API(msg)	__attribute__ ((__deprecated__))
+#   endif
+#else
+#   define TCL_DEPRECATED_API(msg)	/* nothing portable */
+#endif
+
+/*
+ *----------------------------------------------------------------------------
+ * Macros used to declare a function to be exported by a DLL. Used by Windows,
+ * maps to no-op declarations on non-Windows systems. The default build on
+ * windows is for a DLL, which causes the DLLIMPORT and DLLEXPORT macros to be
+ * nonempty. To build a static library, the macro STATIC_BUILD should be
+ * defined.
+ *
+ * Note: when building static but linking dynamically to MSVCRT we must still
+ *       correctly decorate the C library imported function.  Use CRTIMPORT
+ *       for this purpose.  _DLL is defined by the compiler when linking to
+ *       MSVCRT.
+ */
+
+#if (defined(_WIN32) && (defined(_MSC_VER) || (defined(__BORLANDC__) && (__BORLANDC__ >= 0x0550)) || defined(__LCC__) || defined(__WATCOMC__) || (defined(__GNUC__) && defined(__declspec))))
+#   define HAVE_DECLSPEC 1
+#   ifdef STATIC_BUILD
+#       define DLLIMPORT
+#       define DLLEXPORT
+#       ifdef _DLL
+#           define CRTIMPORT __declspec(dllimport)
+#       else
+#           define CRTIMPORT
+#       endif
+#   else
+#       define DLLIMPORT __declspec(dllimport)
+#       define DLLEXPORT __declspec(dllexport)
+#       define CRTIMPORT __declspec(dllimport)
+#   endif
+#else
+#   define DLLIMPORT
+#   if defined(__GNUC__) && __GNUC__ > 3
+#       define DLLEXPORT __attribute__ ((visibility("default")))
+#   else
+#       define DLLEXPORT
+#   endif
+#   define CRTIMPORT
+#endif
+
+/*
+ * These macros are used to control whether functions are being declared for
+ * import or export. If a function is being declared while it is being built
+ * to be included in a shared library, then it should have the DLLEXPORT
+ * storage class. If is being declared for use by a module that is going to
+ * link against the shared library, then it should have the DLLIMPORT storage
+ * class. If the symbol is beind declared for a static build or for use from a
+ * stub library, then the storage class should be empty.
+ *
+ * The convention is that a macro called BUILD_xxxx, where xxxx is the name of
+ * a library we are building, is set on the compile line for sources that are
+ * to be placed in the library. When this macro is set, the storage class will
+ * be set to DLLEXPORT. At the end of the header file, the storage class will
+ * be reset to DLLIMPORT.
+ */
+
+#undef TCL_STORAGE_CLASS
+#ifdef BUILD_tcl
+#   define TCL_STORAGE_CLASS DLLEXPORT
+#else
+#   ifdef USE_TCL_STUBS
+#      define TCL_STORAGE_CLASS
+#   else
+#      define TCL_STORAGE_CLASS DLLIMPORT
+#   endif
+#endif
+
+/*
+ * The following _ANSI_ARGS_ macro is to support old extensions
+ * written for older versions of Tcl where it permitted support
+ * for compilers written in the pre-prototype era of C.
+ *
+ * New code should use prototypes.
+ */
+
+#ifndef TCL_NO_DEPRECATED
+#   undef _ANSI_ARGS_
+#   define _ANSI_ARGS_(x)	x
+#endif
+
+/*
+ * Definitions that allow this header file to be used either with or without
+ * ANSI C features.
+ */
+
+#ifndef INLINE
+#   define INLINE
+#endif
+
+#ifdef NO_CONST
+#   ifndef const
+#      define const
+#   endif
+#endif
+#ifndef CONST
+#   define CONST const
+#endif
+
+#ifdef USE_NON_CONST
+#   ifdef USE_COMPAT_CONST
+#      error define at most one of USE_NON_CONST and USE_COMPAT_CONST
+#   endif
+#   define CONST84
+#   define CONST84_RETURN
+#else
+#   ifdef USE_COMPAT_CONST
+#      define CONST84
+#      define CONST84_RETURN const
+#   else
+#      define CONST84 const
+#      define CONST84_RETURN const
+#   endif
+#endif
+
+#ifndef CONST86
+#      define CONST86 CONST84
+#endif
+
+/*
+ * Make sure EXTERN isn't defined elsewhere.
+ */
+
+#ifdef EXTERN
+#   undef EXTERN
+#endif /* EXTERN */
+
+#ifdef __cplusplus
+#   define EXTERN extern "C" TCL_STORAGE_CLASS
+#else
+#   define EXTERN extern TCL_STORAGE_CLASS
+#endif
+
+/*
+ *----------------------------------------------------------------------------
+ * The following code is copied from winnt.h. If we don't replicate it here,
+ * then <windows.h> can't be included after tcl.h, since tcl.h also defines
+ * VOID. This block is skipped under Cygwin and Mingw.
+ */
+
+#if defined(_WIN32) && !defined(HAVE_WINNT_IGNORE_VOID)
+#ifndef VOID
+#define VOID void
+typedef char CHAR;
+typedef short SHORT;
+typedef long LONG;
+#endif
+#endif /* _WIN32 && !HAVE_WINNT_IGNORE_VOID */
+
+/*
+ * Macro to use instead of "void" for arguments that must have type "void *"
+ * in ANSI C; maps them to type "char *" in non-ANSI systems.
+ */
+
+#ifndef __VXWORKS__
+#   ifndef NO_VOID
+#	define VOID void
+#   else
+#	define VOID char
+#   endif
+#endif
+
+/*
+ * Miscellaneous declarations.
+ */
+
+#ifndef _CLIENTDATA
+#   ifndef NO_VOID
+	typedef void *ClientData;
+#   else
+	typedef int *ClientData;
+#   endif
+#   define _CLIENTDATA
+#endif
+
+/*
+ * Darwin specific configure overrides (to support fat compiles, where
+ * configure runs only once for multiple architectures):
+ */
+
+#ifdef __APPLE__
+#   ifdef __LP64__
+#	undef TCL_WIDE_INT_TYPE
+#	define TCL_WIDE_INT_IS_LONG 1
+#	define TCL_CFG_DO64BIT 1
+#    else /* !__LP64__ */
+#	define TCL_WIDE_INT_TYPE long long
+#	undef TCL_WIDE_INT_IS_LONG
+#	undef TCL_CFG_DO64BIT
+#    endif /* __LP64__ */
+#    undef HAVE_STRUCT_STAT64
+#endif /* __APPLE__ */
+
+/*
+ * Define Tcl_WideInt to be a type that is (at least) 64-bits wide, and define
+ * Tcl_WideUInt to be the unsigned variant of that type (assuming that where
+ * we have one, we can have the other.)
+ *
+ * Also defines the following macros:
+ * TCL_WIDE_INT_IS_LONG - if wide ints are really longs (i.e. we're on a real
+ *	64-bit system.)
+ * Tcl_WideAsLong - forgetful converter from wideInt to long.
+ * Tcl_LongAsWide - sign-extending converter from long to wideInt.
+ * Tcl_WideAsDouble - converter from wideInt to double.
+ * Tcl_DoubleAsWide - converter from double to wideInt.
+ *
+ * The following invariant should hold for any long value 'longVal':
+ *	longVal == Tcl_WideAsLong(Tcl_LongAsWide(longVal))
+ *
+ * Note on converting between Tcl_WideInt and strings. This implementation (in
+ * tclObj.c) depends on the function
+ * sprintf(...,"%" TCL_LL_MODIFIER "d",...).
+ */
+
+#if !defined(TCL_WIDE_INT_TYPE)&&!defined(TCL_WIDE_INT_IS_LONG)
+#   if defined(_WIN32)
+#      define TCL_WIDE_INT_TYPE __int64
+#      ifdef __BORLANDC__
+#         define TCL_LL_MODIFIER	"L"
+#      else /* __BORLANDC__ */
+#         define TCL_LL_MODIFIER	"I64"
+#      endif /* __BORLANDC__ */
+#   elif defined(__GNUC__)
+#      define TCL_WIDE_INT_TYPE long long
+#      define TCL_LL_MODIFIER	"ll"
+#   else /* ! _WIN32 && ! __GNUC__ */
+/*
+ * Don't know what platform it is and configure hasn't discovered what is
+ * going on for us. Try to guess...
+ */
+#      include <limits.h>
+#      if (INT_MAX < LONG_MAX)
+#         define TCL_WIDE_INT_IS_LONG	1
+#      else
+#         define TCL_WIDE_INT_TYPE long long
+#      endif
+#   endif /* _WIN32 */
+#endif /* !TCL_WIDE_INT_TYPE & !TCL_WIDE_INT_IS_LONG */
+#ifdef TCL_WIDE_INT_IS_LONG
+#   undef TCL_WIDE_INT_TYPE
+#   define TCL_WIDE_INT_TYPE	long
+#endif /* TCL_WIDE_INT_IS_LONG */
+
+typedef TCL_WIDE_INT_TYPE		Tcl_WideInt;
+typedef unsigned TCL_WIDE_INT_TYPE	Tcl_WideUInt;
+
+#ifdef TCL_WIDE_INT_IS_LONG
+#   define Tcl_WideAsLong(val)		((long)(val))
+#   define Tcl_LongAsWide(val)		((long)(val))
+#   define Tcl_WideAsDouble(val)	((double)((long)(val)))
+#   define Tcl_DoubleAsWide(val)	((long)((double)(val)))
+#   ifndef TCL_LL_MODIFIER
+#      define TCL_LL_MODIFIER		"l"
+#   endif /* !TCL_LL_MODIFIER */
+#else /* TCL_WIDE_INT_IS_LONG */
+/*
+ * The next short section of defines are only done when not running on Windows
+ * or some other strange platform.
+ */
+#   ifndef TCL_LL_MODIFIER
+#      define TCL_LL_MODIFIER		"ll"
+#   endif /* !TCL_LL_MODIFIER */
+#   define Tcl_WideAsLong(val)		((long)((Tcl_WideInt)(val)))
+#   define Tcl_LongAsWide(val)		((Tcl_WideInt)((long)(val)))
+#   define Tcl_WideAsDouble(val)	((double)((Tcl_WideInt)(val)))
+#   define Tcl_DoubleAsWide(val)	((Tcl_WideInt)((double)(val)))
+#endif /* TCL_WIDE_INT_IS_LONG */
+
+#if defined(_WIN32)
+#   ifdef __BORLANDC__
+	typedef struct stati64 Tcl_StatBuf;
+#   elif defined(_WIN64)
+	typedef struct __stat64 Tcl_StatBuf;
+#   elif (defined(_MSC_VER) && (_MSC_VER < 1400)) || defined(_USE_32BIT_TIME_T)
+	typedef struct _stati64	Tcl_StatBuf;
+#   else
+	typedef struct _stat32i64 Tcl_StatBuf;
+#   endif /* _MSC_VER < 1400 */
+#elif defined(__CYGWIN__)
+    typedef struct {
+	dev_t st_dev;
+	unsigned short st_ino;
+	unsigned short st_mode;
+	short st_nlink;
+	short st_uid;
+	short st_gid;
+	/* Here is a 2-byte gap */
+	dev_t st_rdev;
+	/* Here is a 4-byte gap */
+	long long st_size;
+	struct {long tv_sec;} st_atim;
+	struct {long tv_sec;} st_mtim;
+	struct {long tv_sec;} st_ctim;
+	/* Here is a 4-byte gap */
+    } Tcl_StatBuf;
+#elif defined(HAVE_STRUCT_STAT64) && !defined(__APPLE__)
+    typedef struct stat64 Tcl_StatBuf;
+#else
+    typedef struct stat Tcl_StatBuf;
+#endif
+
+/*
+ *----------------------------------------------------------------------------
+ * Data structures defined opaquely in this module. The definitions below just
+ * provide dummy types. A few fields are made visible in Tcl_Interp
+ * structures, namely those used for returning a string result from commands.
+ * Direct access to the result field is discouraged in Tcl 8.0. The
+ * interpreter result is either an object or a string, and the two values are
+ * kept consistent unless some C code sets interp->result directly.
+ * Programmers should use either the function Tcl_GetObjResult() or
+ * Tcl_GetStringResult() to read the interpreter's result. See the SetResult
+ * man page for details.
+ *
+ * Note: any change to the Tcl_Interp definition below must be mirrored in the
+ * "real" definition in tclInt.h.
+ *
+ * Note: Tcl_ObjCmdProc functions do not directly set result and freeProc.
+ * Instead, they set a Tcl_Obj member in the "real" structure that can be
+ * accessed with Tcl_GetObjResult() and Tcl_SetObjResult().
+ */
+
+typedef struct Tcl_Interp
+#ifndef TCL_NO_DEPRECATED
+{
+    /* TIP #330: Strongly discourage extensions from using the string
+     * result. */
+#ifdef USE_INTERP_RESULT
+    char *result TCL_DEPRECATED_API("use Tcl_GetStringResult/Tcl_SetResult");
+				/* If the last command returned a string
+				 * result, this points to it. */
+    void (*freeProc) (char *blockPtr)
+	    TCL_DEPRECATED_API("use Tcl_GetStringResult/Tcl_SetResult");
+				/* Zero means the string result is statically
+				 * allocated. TCL_DYNAMIC means it was
+				 * allocated with ckalloc and should be freed
+				 * with ckfree. Other values give the address
+				 * of function to invoke to free the result.
+				 * Tcl_Eval must free it before executing next
+				 * command. */
+#else
+    char *resultDontUse; /* Don't use in extensions! */
+    void (*freeProcDontUse) (char *); /* Don't use in extensions! */
+#endif
+#ifdef USE_INTERP_ERRORLINE
+    int errorLine TCL_DEPRECATED_API("use Tcl_GetErrorLine/Tcl_SetErrorLine");
+				/* When TCL_ERROR is returned, this gives the
+				 * line number within the command where the
+				 * error occurred (1 if first line). */
+#else
+    int errorLineDontUse; /* Don't use in extensions! */
+#endif
+}
+#endif /* TCL_NO_DEPRECATED */
+Tcl_Interp;
+
+typedef struct Tcl_AsyncHandler_ *Tcl_AsyncHandler;
+typedef struct Tcl_Channel_ *Tcl_Channel;
+typedef struct Tcl_ChannelTypeVersion_ *Tcl_ChannelTypeVersion;
+typedef struct Tcl_Command_ *Tcl_Command;
+typedef struct Tcl_Condition_ *Tcl_Condition;
+typedef struct Tcl_Dict_ *Tcl_Dict;
+typedef struct Tcl_EncodingState_ *Tcl_EncodingState;
+typedef struct Tcl_Encoding_ *Tcl_Encoding;
+typedef struct Tcl_Event Tcl_Event;
+typedef struct Tcl_InterpState_ *Tcl_InterpState;
+typedef struct Tcl_LoadHandle_ *Tcl_LoadHandle;
+typedef struct Tcl_Mutex_ *Tcl_Mutex;
+typedef struct Tcl_Pid_ *Tcl_Pid;
+typedef struct Tcl_RegExp_ *Tcl_RegExp;
+typedef struct Tcl_ThreadDataKey_ *Tcl_ThreadDataKey;
+typedef struct Tcl_ThreadId_ *Tcl_ThreadId;
+typedef struct Tcl_TimerToken_ *Tcl_TimerToken;
+typedef struct Tcl_Trace_ *Tcl_Trace;
+typedef struct Tcl_Var_ *Tcl_Var;
+typedef struct Tcl_ZLibStream_ *Tcl_ZlibStream;
+
+/*
+ *----------------------------------------------------------------------------
+ * Definition of the interface to functions implementing threads. A function
+ * following this definition is given to each call of 'Tcl_CreateThread' and
+ * will be called as the main fuction of the new thread created by that call.
+ */
+
+#if defined _WIN32
+typedef unsigned (__stdcall Tcl_ThreadCreateProc) (ClientData clientData);
+#else
+typedef void (Tcl_ThreadCreateProc) (ClientData clientData);
+#endif
+
+/*
+ * Threading function return types used for abstracting away platform
+ * differences when writing a Tcl_ThreadCreateProc. See the NewThread function
+ * in generic/tclThreadTest.c for it's usage.
+ */
+
+#if defined _WIN32
+#   define Tcl_ThreadCreateType		unsigned __stdcall
+#   define TCL_THREAD_CREATE_RETURN	return 0
+#else
+#   define Tcl_ThreadCreateType		void
+#   define TCL_THREAD_CREATE_RETURN
+#endif
+
+/*
+ * Definition of values for default stacksize and the possible flags to be
+ * given to Tcl_CreateThread.
+ */
+
+#define TCL_THREAD_STACK_DEFAULT (0)    /* Use default size for stack. */
+#define TCL_THREAD_NOFLAGS	 (0000) /* Standard flags, default
+					 * behaviour. */
+#define TCL_THREAD_JOINABLE	 (0001) /* Mark the thread as joinable. */
+
+/*
+ * Flag values passed to Tcl_StringCaseMatch.
+ */
+
+#define TCL_MATCH_NOCASE	(1<<0)
+
+/*
+ * Flag values passed to Tcl_GetRegExpFromObj.
+ */
+
+#define	TCL_REG_BASIC		000000	/* BREs (convenience). */
+#define	TCL_REG_EXTENDED	000001	/* EREs. */
+#define	TCL_REG_ADVF		000002	/* Advanced features in EREs. */
+#define	TCL_REG_ADVANCED	000003	/* AREs (which are also EREs). */
+#define	TCL_REG_QUOTE		000004	/* No special characters, none. */
+#define	TCL_REG_NOCASE		000010	/* Ignore case. */
+#define	TCL_REG_NOSUB		000020	/* Don't care about subexpressions. */
+#define	TCL_REG_EXPANDED	000040	/* Expanded format, white space &
+					 * comments. */
+#define	TCL_REG_NLSTOP		000100  /* \n doesn't match . or [^ ] */
+#define	TCL_REG_NLANCH		000200  /* ^ matches after \n, $ before. */
+#define	TCL_REG_NEWLINE		000300  /* Newlines are line terminators. */
+#define	TCL_REG_CANMATCH	001000  /* Report details on partial/limited
+					 * matches. */
+
+/*
+ * Flags values passed to Tcl_RegExpExecObj.
+ */
+
+#define	TCL_REG_NOTBOL	0001	/* Beginning of string does not match ^.  */
+#define	TCL_REG_NOTEOL	0002	/* End of string does not match $. */
+
+/*
+ * Structures filled in by Tcl_RegExpInfo. Note that all offset values are
+ * relative to the start of the match string, not the beginning of the entire
+ * string.
+ */
+
+typedef struct Tcl_RegExpIndices {
+    long start;			/* Character offset of first character in
+				 * match. */
+    long end;			/* Character offset of first character after
+				 * the match. */
+} Tcl_RegExpIndices;
+
+typedef struct Tcl_RegExpInfo {
+    int nsubs;			/* Number of subexpressions in the compiled
+				 * expression. */
+    Tcl_RegExpIndices *matches;	/* Array of nsubs match offset pairs. */
+    long extendStart;		/* The offset at which a subsequent match
+				 * might begin. */
+    long reserved;		/* Reserved for later use. */
+} Tcl_RegExpInfo;
+
+/*
+ * Picky compilers complain if this typdef doesn't appear before the struct's
+ * reference in tclDecls.h.
+ */
+
+typedef Tcl_StatBuf *Tcl_Stat_;
+typedef struct stat *Tcl_OldStat_;
+
+/*
+ *----------------------------------------------------------------------------
+ * When a TCL command returns, the interpreter contains a result from the
+ * command. Programmers are strongly encouraged to use one of the functions
+ * Tcl_GetObjResult() or Tcl_GetStringResult() to read the interpreter's
+ * result. See the SetResult man page for details. Besides this result, the
+ * command function returns an integer code, which is one of the following:
+ *
+ * TCL_OK		Command completed normally; the interpreter's result
+ *			contains the command's result.
+ * TCL_ERROR		The command couldn't be completed successfully; the
+ *			interpreter's result describes what went wrong.
+ * TCL_RETURN		The command requests that the current function return;
+ *			the interpreter's result contains the function's
+ *			return value.
+ * TCL_BREAK		The command requests that the innermost loop be
+ *			exited; the interpreter's result is meaningless.
+ * TCL_CONTINUE		Go on to the next iteration of the current loop; the
+ *			interpreter's result is meaningless.
+ */
+
+#define TCL_OK			0
+#define TCL_ERROR		1
+#define TCL_RETURN		2
+#define TCL_BREAK		3
+#define TCL_CONTINUE		4
+
+#define TCL_RESULT_SIZE		200
+
+/*
+ *----------------------------------------------------------------------------
+ * Flags to control what substitutions are performed by Tcl_SubstObj():
+ */
+
+#define TCL_SUBST_COMMANDS	001
+#define TCL_SUBST_VARIABLES	002
+#define TCL_SUBST_BACKSLASHES	004
+#define TCL_SUBST_ALL		007
+
+/*
+ * Argument descriptors for math function callbacks in expressions:
+ */
+
+typedef enum {
+    TCL_INT, TCL_DOUBLE, TCL_EITHER, TCL_WIDE_INT
+} Tcl_ValueType;
+
+typedef struct Tcl_Value {
+    Tcl_ValueType type;		/* Indicates intValue or doubleValue is valid,
+				 * or both. */
+    long intValue;		/* Integer value. */
+    double doubleValue;		/* Double-precision floating value. */
+    Tcl_WideInt wideValue;	/* Wide (min. 64-bit) integer value. */
+} Tcl_Value;
+
+/*
+ * Forward declaration of Tcl_Obj to prevent an error when the forward
+ * reference to Tcl_Obj is encountered in the function types declared below.
+ */
+
+struct Tcl_Obj;
+
+/*
+ *----------------------------------------------------------------------------
+ * Function types defined by Tcl:
+ */
+
+typedef int (Tcl_AppInitProc) (Tcl_Interp *interp);
+typedef int (Tcl_AsyncProc) (ClientData clientData, Tcl_Interp *interp,
+	int code);
+typedef void (Tcl_ChannelProc) (ClientData clientData, int mask);
+typedef void (Tcl_CloseProc) (ClientData data);
+typedef void (Tcl_CmdDeleteProc) (ClientData clientData);
+typedef int (Tcl_CmdProc) (ClientData clientData, Tcl_Interp *interp,
+	int argc, CONST84 char *argv[]);
+typedef void (Tcl_CmdTraceProc) (ClientData clientData, Tcl_Interp *interp,
+	int level, char *command, Tcl_CmdProc *proc,
+	ClientData cmdClientData, int argc, CONST84 char *argv[]);
+typedef int (Tcl_CmdObjTraceProc) (ClientData clientData, Tcl_Interp *interp,
+	int level, const char *command, Tcl_Command commandInfo, int objc,
+	struct Tcl_Obj *const *objv);
+typedef void (Tcl_CmdObjTraceDeleteProc) (ClientData clientData);
+typedef void (Tcl_DupInternalRepProc) (struct Tcl_Obj *srcPtr,
+	struct Tcl_Obj *dupPtr);
+typedef int (Tcl_EncodingConvertProc) (ClientData clientData, const char *src,
+	int srcLen, int flags, Tcl_EncodingState *statePtr, char *dst,
+	int dstLen, int *srcReadPtr, int *dstWrotePtr, int *dstCharsPtr);
+typedef void (Tcl_EncodingFreeProc) (ClientData clientData);
+typedef int (Tcl_EventProc) (Tcl_Event *evPtr, int flags);
+typedef void (Tcl_EventCheckProc) (ClientData clientData, int flags);
+typedef int (Tcl_EventDeleteProc) (Tcl_Event *evPtr, ClientData clientData);
+typedef void (Tcl_EventSetupProc) (ClientData clientData, int flags);
+typedef void (Tcl_ExitProc) (ClientData clientData);
+typedef void (Tcl_FileProc) (ClientData clientData, int mask);
+typedef void (Tcl_FileFreeProc) (ClientData clientData);
+typedef void (Tcl_FreeInternalRepProc) (struct Tcl_Obj *objPtr);
+typedef void (Tcl_FreeProc) (char *blockPtr);
+typedef void (Tcl_IdleProc) (ClientData clientData);
+typedef void (Tcl_InterpDeleteProc) (ClientData clientData,
+	Tcl_Interp *interp);
+typedef int (Tcl_MathProc) (ClientData clientData, Tcl_Interp *interp,
+	Tcl_Value *args, Tcl_Value *resultPtr);
+typedef void (Tcl_NamespaceDeleteProc) (ClientData clientData);
+typedef int (Tcl_ObjCmdProc) (ClientData clientData, Tcl_Interp *interp,
+	int objc, struct Tcl_Obj *const *objv);
+typedef int (Tcl_PackageInitProc) (Tcl_Interp *interp);
+typedef int (Tcl_PackageUnloadProc) (Tcl_Interp *interp, int flags);
+typedef void (Tcl_PanicProc) (const char *format, ...);
+typedef void (Tcl_TcpAcceptProc) (ClientData callbackData, Tcl_Channel chan,
+	char *address, int port);
+typedef void (Tcl_TimerProc) (ClientData clientData);
+typedef int (Tcl_SetFromAnyProc) (Tcl_Interp *interp, struct Tcl_Obj *objPtr);
+typedef void (Tcl_UpdateStringProc) (struct Tcl_Obj *objPtr);
+typedef char * (Tcl_VarTraceProc) (ClientData clientData, Tcl_Interp *interp,
+	CONST84 char *part1, CONST84 char *part2, int flags);
+typedef void (Tcl_CommandTraceProc) (ClientData clientData, Tcl_Interp *interp,
+	const char *oldName, const char *newName, int flags);
+typedef void (Tcl_CreateFileHandlerProc) (int fd, int mask, Tcl_FileProc *proc,
+	ClientData clientData);
+typedef void (Tcl_DeleteFileHandlerProc) (int fd);
+typedef void (Tcl_AlertNotifierProc) (ClientData clientData);
+typedef void (Tcl_ServiceModeHookProc) (int mode);
+typedef ClientData (Tcl_InitNotifierProc) (void);
+typedef void (Tcl_FinalizeNotifierProc) (ClientData clientData);
+typedef void (Tcl_MainLoopProc) (void);
+
+/*
+ *----------------------------------------------------------------------------
+ * The following structure represents a type of object, which is a particular
+ * internal representation for an object plus a set of functions that provide
+ * standard operations on objects of that type.
+ */
+
+typedef struct Tcl_ObjType {
+    const char *name;		/* Name of the type, e.g. "int". */
+    Tcl_FreeInternalRepProc *freeIntRepProc;
+				/* Called to free any storage for the type's
+				 * internal rep. NULL if the internal rep does
+				 * not need freeing. */
+    Tcl_DupInternalRepProc *dupIntRepProc;
+				/* Called to create a new object as a copy of
+				 * an existing object. */
+    Tcl_UpdateStringProc *updateStringProc;
+				/* Called to update the string rep from the
+				 * type's internal representation. */
+    Tcl_SetFromAnyProc *setFromAnyProc;
+				/* Called to convert the object's internal rep
+				 * to this type. Frees the internal rep of the
+				 * old type. Returns TCL_ERROR on failure. */
+} Tcl_ObjType;
+
+/*
+ * One of the following structures exists for each object in the Tcl system.
+ * An object stores a value as either a string, some internal representation,
+ * or both.
+ */
+
+typedef struct Tcl_Obj {
+    int refCount;		/* When 0 the object will be freed. */
+    char *bytes;		/* This points to the first byte of the
+				 * object's string representation. The array
+				 * must be followed by a null byte (i.e., at
+				 * offset length) but may also contain
+				 * embedded null characters. The array's
+				 * storage is allocated by ckalloc. NULL means
+				 * the string rep is invalid and must be
+				 * regenerated from the internal rep.  Clients
+				 * should use Tcl_GetStringFromObj or
+				 * Tcl_GetString to get a pointer to the byte
+				 * array as a readonly value. */
+    int length;			/* The number of bytes at *bytes, not
+				 * including the terminating null. */
+    const Tcl_ObjType *typePtr;	/* Denotes the object's type. Always
+				 * corresponds to the type of the object's
+				 * internal rep. NULL indicates the object has
+				 * no internal rep (has no type). */
+    union {			/* The internal representation: */
+	long longValue;		/*   - an long integer value. */
+	double doubleValue;	/*   - a double-precision floating value. */
+	void *otherValuePtr;	/*   - another, type-specific value,
+	                       not used internally any more. */
+	Tcl_WideInt wideValue;	/*   - a long long value. */
+	struct {		/*   - internal rep as two pointers.
+				 *     the main use of which is a bignum's
+				 *     tightly packed fields, where the alloc,
+				 *     used and signum flags are packed into
+				 *     ptr2 with everything else hung off ptr1. */
+	    void *ptr1;
+	    void *ptr2;
+	} twoPtrValue;
+	struct {		/*   - internal rep as a pointer and a long,
+	                       not used internally any more. */
+	    void *ptr;
+	    unsigned long value;
+	} ptrAndLongRep;
+    } internalRep;
+} Tcl_Obj;
+
+/*
+ * Macros to increment and decrement a Tcl_Obj's reference count, and to test
+ * whether an object is shared (i.e. has reference count > 1). Note: clients
+ * should use Tcl_DecrRefCount() when they are finished using an object, and
+ * should never call TclFreeObj() directly. TclFreeObj() is only defined and
+ * made public in tcl.h to support Tcl_DecrRefCount's macro definition.
+ */
+
+void		Tcl_IncrRefCount(Tcl_Obj *objPtr);
+void		Tcl_DecrRefCount(Tcl_Obj *objPtr);
+int		Tcl_IsShared(Tcl_Obj *objPtr);
+
+/*
+ *----------------------------------------------------------------------------
+ * The following structure contains the state needed by Tcl_SaveResult. No-one
+ * outside of Tcl should access any of these fields. This structure is
+ * typically allocated on the stack.
+ */
+
+typedef struct Tcl_SavedResult {
+    char *result;
+    Tcl_FreeProc *freeProc;
+    Tcl_Obj *objResultPtr;
+    char *appendResult;
+    int appendAvl;
+    int appendUsed;
+    char resultSpace[TCL_RESULT_SIZE+1];
+} Tcl_SavedResult;
+
+/*
+ *----------------------------------------------------------------------------
+ * The following definitions support Tcl's namespace facility. Note: the first
+ * five fields must match exactly the fields in a Namespace structure (see
+ * tclInt.h).
+ */
+
+typedef struct Tcl_Namespace {
+    char *name;			/* The namespace's name within its parent
+				 * namespace. This contains no ::'s. The name
+				 * of the global namespace is "" although "::"
+				 * is an synonym. */
+    char *fullName;		/* The namespace's fully qualified name. This
+				 * starts with ::. */
+    ClientData clientData;	/* Arbitrary value associated with this
+				 * namespace. */
+    Tcl_NamespaceDeleteProc *deleteProc;
+				/* Function invoked when deleting the
+				 * namespace to, e.g., free clientData. */
+    struct Tcl_Namespace *parentPtr;
+				/* Points to the namespace that contains this
+				 * one. NULL if this is the global
+				 * namespace. */
+} Tcl_Namespace;
+
+/*
+ *----------------------------------------------------------------------------
+ * The following structure represents a call frame, or activation record. A
+ * call frame defines a naming context for a procedure call: its local scope
+ * (for local variables) and its namespace scope (used for non-local
+ * variables; often the global :: namespace). A call frame can also define the
+ * naming context for a namespace eval or namespace inscope command: the
+ * namespace in which the command's code should execute. The Tcl_CallFrame
+ * structures exist only while procedures or namespace eval/inscope's are
+ * being executed, and provide a Tcl call stack.
+ *
+ * A call frame is initialized and pushed using Tcl_PushCallFrame and popped
+ * using Tcl_PopCallFrame. Storage for a Tcl_CallFrame must be provided by the
+ * Tcl_PushCallFrame caller, and callers typically allocate them on the C call
+ * stack for efficiency. For this reason, Tcl_CallFrame is defined as a
+ * structure and not as an opaque token. However, most Tcl_CallFrame fields
+ * are hidden since applications should not access them directly; others are
+ * declared as "dummyX".
+ *
+ * WARNING!! The structure definition must be kept consistent with the
+ * CallFrame structure in tclInt.h. If you change one, change the other.
+ */
+
+typedef struct Tcl_CallFrame {
+    Tcl_Namespace *nsPtr;
+    int dummy1;
+    int dummy2;
+    void *dummy3;
+    void *dummy4;
+    void *dummy5;
+    int dummy6;
+    void *dummy7;
+    void *dummy8;
+    int dummy9;
+    void *dummy10;
+    void *dummy11;
+    void *dummy12;
+    void *dummy13;
+} Tcl_CallFrame;
+
+/*
+ *----------------------------------------------------------------------------
+ * Information about commands that is returned by Tcl_GetCommandInfo and
+ * passed to Tcl_SetCommandInfo. objProc is an objc/objv object-based command
+ * function while proc is a traditional Tcl argc/argv string-based function.
+ * Tcl_CreateObjCommand and Tcl_CreateCommand ensure that both objProc and
+ * proc are non-NULL and can be called to execute the command. However, it may
+ * be faster to call one instead of the other. The member isNativeObjectProc
+ * is set to 1 if an object-based function was registered by
+ * Tcl_CreateObjCommand, and to 0 if a string-based function was registered by
+ * Tcl_CreateCommand. The other function is typically set to a compatibility
+ * wrapper that does string-to-object or object-to-string argument conversions
+ * then calls the other function.
+ */
+
+typedef struct Tcl_CmdInfo {
+    int isNativeObjectProc;	/* 1 if objProc was registered by a call to
+				 * Tcl_CreateObjCommand; 0 otherwise.
+				 * Tcl_SetCmdInfo does not modify this
+				 * field. */
+    Tcl_ObjCmdProc *objProc;	/* Command's object-based function. */
+    ClientData objClientData;	/* ClientData for object proc. */
+    Tcl_CmdProc *proc;		/* Command's string-based function. */
+    ClientData clientData;	/* ClientData for string proc. */
+    Tcl_CmdDeleteProc *deleteProc;
+				/* Function to call when command is
+				 * deleted. */
+    ClientData deleteData;	/* Value to pass to deleteProc (usually the
+				 * same as clientData). */
+    Tcl_Namespace *namespacePtr;/* Points to the namespace that contains this
+				 * command. Note that Tcl_SetCmdInfo will not
+				 * change a command's namespace; use
+				 * TclRenameCommand or Tcl_Eval (of 'rename')
+				 * to do that. */
+} Tcl_CmdInfo;
+
+/*
+ *----------------------------------------------------------------------------
+ * The structure defined below is used to hold dynamic strings. The only
+ * fields that clients should use are string and length, accessible via the
+ * macros Tcl_DStringValue and Tcl_DStringLength.
+ */
+
+#define TCL_DSTRING_STATIC_SIZE 200
+typedef struct Tcl_DString {
+    char *string;		/* Points to beginning of string: either
+				 * staticSpace below or a malloced array. */
+    int length;			/* Number of non-NULL characters in the
+				 * string. */
+    int spaceAvl;		/* Total number of bytes available for the
+				 * string and its terminating NULL char. */
+    char staticSpace[TCL_DSTRING_STATIC_SIZE];
+				/* Space to use in common case where string is
+				 * small. */
+} Tcl_DString;
+
+#define Tcl_DStringLength(dsPtr) ((dsPtr)->length)
+#define Tcl_DStringValue(dsPtr) ((dsPtr)->string)
+#define Tcl_DStringTrunc Tcl_DStringSetLength
+
+/*
+ * Definitions for the maximum number of digits of precision that may be
+ * specified in the "tcl_precision" variable, and the number of bytes of
+ * buffer space required by Tcl_PrintDouble.
+ */
+
+#define TCL_MAX_PREC		17
+#define TCL_DOUBLE_SPACE	(TCL_MAX_PREC+10)
+
+/*
+ * Definition for a number of bytes of buffer space sufficient to hold the
+ * string representation of an integer in base 10 (assuming the existence of
+ * 64-bit integers).
+ */
+
+#define TCL_INTEGER_SPACE	24
+
+/*
+ * Flag values passed to Tcl_ConvertElement.
+ * TCL_DONT_USE_BRACES forces it not to enclose the element in braces, but to
+ *	use backslash quoting instead.
+ * TCL_DONT_QUOTE_HASH disables the default quoting of the '#' character. It
+ *	is safe to leave the hash unquoted when the element is not the first
+ *	element of a list, and this flag can be used by the caller to indicate
+ *	that condition.
+ */
+
+#define TCL_DONT_USE_BRACES	1
+#define TCL_DONT_QUOTE_HASH	8
+
+/*
+ * Flag that may be passed to Tcl_GetIndexFromObj to force it to disallow
+ * abbreviated strings.
+ */
+
+#define TCL_EXACT	1
+
+/*
+ *----------------------------------------------------------------------------
+ * Flag values passed to Tcl_RecordAndEval, Tcl_EvalObj, Tcl_EvalObjv.
+ * WARNING: these bit choices must not conflict with the bit choices for
+ * evalFlag bits in tclInt.h!
+ *
+ * Meanings:
+ *	TCL_NO_EVAL:		Just record this command
+ *	TCL_EVAL_GLOBAL:	Execute script in global namespace
+ *	TCL_EVAL_DIRECT:	Do not compile this script
+ *	TCL_EVAL_INVOKE:	Magical Tcl_EvalObjv mode for aliases/ensembles
+ *				o Run in iPtr->lookupNsPtr or global namespace
+ *				o Cut out of error traces
+ *				o Don't reset the flags controlling ensemble
+ *				  error message rewriting.
+ *	TCL_CANCEL_UNWIND:	Magical Tcl_CancelEval mode that causes the
+ *				stack for the script in progress to be
+ *				completely unwound.
+ *	TCL_EVAL_NOERR:	Do no exception reporting at all, just return
+ *				as the caller will report.
+ */
+
+#define TCL_NO_EVAL		0x010000
+#define TCL_EVAL_GLOBAL		0x020000
+#define TCL_EVAL_DIRECT		0x040000
+#define TCL_EVAL_INVOKE		0x080000
+#define TCL_CANCEL_UNWIND	0x100000
+#define TCL_EVAL_NOERR          0x200000
+
+/*
+ * Special freeProc values that may be passed to Tcl_SetResult (see the man
+ * page for details):
+ */
+
+#define TCL_VOLATILE		((Tcl_FreeProc *) 1)
+#define TCL_STATIC		((Tcl_FreeProc *) 0)
+#define TCL_DYNAMIC		((Tcl_FreeProc *) 3)
+
+/*
+ * Flag values passed to variable-related functions.
+ * WARNING: these bit choices must not conflict with the bit choice for
+ * TCL_CANCEL_UNWIND, above.
+ */
+
+#define TCL_GLOBAL_ONLY		 1
+#define TCL_NAMESPACE_ONLY	 2
+#define TCL_APPEND_VALUE	 4
+#define TCL_LIST_ELEMENT	 8
+#define TCL_TRACE_READS		 0x10
+#define TCL_TRACE_WRITES	 0x20
+#define TCL_TRACE_UNSETS	 0x40
+#define TCL_TRACE_DESTROYED	 0x80
+#define TCL_INTERP_DESTROYED	 0x100
+#define TCL_LEAVE_ERR_MSG	 0x200
+#define TCL_TRACE_ARRAY		 0x800
+#ifndef TCL_REMOVE_OBSOLETE_TRACES
+/* Required to support old variable/vdelete/vinfo traces. */
+#define TCL_TRACE_OLD_STYLE	 0x1000
+#endif
+/* Indicate the semantics of the result of a trace. */
+#define TCL_TRACE_RESULT_DYNAMIC 0x8000
+#define TCL_TRACE_RESULT_OBJECT  0x10000
+
+/*
+ * Flag values for ensemble commands.
+ */
+
+#define TCL_ENSEMBLE_PREFIX 0x02/* Flag value to say whether to allow
+				 * unambiguous prefixes of commands or to
+				 * require exact matches for command names. */
+
+/*
+ * Flag values passed to command-related functions.
+ */
+
+#define TCL_TRACE_RENAME	0x2000
+#define TCL_TRACE_DELETE	0x4000
+
+#define TCL_ALLOW_INLINE_COMPILATION 0x20000
+
+/*
+ * The TCL_PARSE_PART1 flag is deprecated and has no effect. The part1 is now
+ * always parsed whenever the part2 is NULL. (This is to avoid a common error
+ * when converting code to use the new object based APIs and forgetting to
+ * give the flag)
+ */
+
+#ifndef TCL_NO_DEPRECATED
+#   define TCL_PARSE_PART1	0x400
+#endif
+
+/*
+ * Types for linked variables:
+ */
+
+#define TCL_LINK_INT		1
+#define TCL_LINK_DOUBLE		2
+#define TCL_LINK_BOOLEAN	3
+#define TCL_LINK_STRING		4
+#define TCL_LINK_WIDE_INT	5
+#define TCL_LINK_CHAR		6
+#define TCL_LINK_UCHAR		7
+#define TCL_LINK_SHORT		8
+#define TCL_LINK_USHORT		9
+#define TCL_LINK_UINT		10
+#define TCL_LINK_LONG		11
+#define TCL_LINK_ULONG		12
+#define TCL_LINK_FLOAT		13
+#define TCL_LINK_WIDE_UINT	14
+#define TCL_LINK_READ_ONLY	0x80
+
+/*
+ *----------------------------------------------------------------------------
+ * Forward declarations of Tcl_HashTable and related types.
+ */
+
+typedef struct Tcl_HashKeyType Tcl_HashKeyType;
+typedef struct Tcl_HashTable Tcl_HashTable;
+typedef struct Tcl_HashEntry Tcl_HashEntry;
+
+typedef unsigned (Tcl_HashKeyProc) (Tcl_HashTable *tablePtr, void *keyPtr);
+typedef int (Tcl_CompareHashKeysProc) (void *keyPtr, Tcl_HashEntry *hPtr);
+typedef Tcl_HashEntry * (Tcl_AllocHashEntryProc) (Tcl_HashTable *tablePtr,
+	void *keyPtr);
+typedef void (Tcl_FreeHashEntryProc) (Tcl_HashEntry *hPtr);
+
+/*
+ * This flag controls whether the hash table stores the hash of a key, or
+ * recalculates it. There should be no reason for turning this flag off as it
+ * is completely binary and source compatible unless you directly access the
+ * bucketPtr member of the Tcl_HashTableEntry structure. This member has been
+ * removed and the space used to store the hash value.
+ */
+
+#ifndef TCL_HASH_KEY_STORE_HASH
+#   define TCL_HASH_KEY_STORE_HASH 1
+#endif
+
+/*
+ * Structure definition for an entry in a hash table. No-one outside Tcl
+ * should access any of these fields directly; use the macros defined below.
+ */
+
+struct Tcl_HashEntry {
+    Tcl_HashEntry *nextPtr;	/* Pointer to next entry in this hash bucket,
+				 * or NULL for end of chain. */
+    Tcl_HashTable *tablePtr;	/* Pointer to table containing entry. */
+#if TCL_HASH_KEY_STORE_HASH
+    void *hash;			/* Hash value, stored as pointer to ensure
+				 * that the offsets of the fields in this
+				 * structure are not changed. */
+#else
+    Tcl_HashEntry **bucketPtr;	/* Pointer to bucket that points to first
+				 * entry in this entry's chain: used for
+				 * deleting the entry. */
+#endif
+    ClientData clientData;	/* Application stores something here with
+				 * Tcl_SetHashValue. */
+    union {			/* Key has one of these forms: */
+	char *oneWordValue;	/* One-word value for key. */
+	Tcl_Obj *objPtr;	/* Tcl_Obj * key value. */
+	int words[1];		/* Multiple integer words for key. The actual
+				 * size will be as large as necessary for this
+				 * table's keys. */
+	char string[1];		/* String for key. The actual size will be as
+				 * large as needed to hold the key. */
+    } key;			/* MUST BE LAST FIELD IN RECORD!! */
+};
+
+/*
+ * Flags used in Tcl_HashKeyType.
+ *
+ * TCL_HASH_KEY_RANDOMIZE_HASH -
+ *				There are some things, pointers for example
+ *				which don't hash well because they do not use
+ *				the lower bits. If this flag is set then the
+ *				hash table will attempt to rectify this by
+ *				randomising the bits and then using the upper
+ *				N bits as the index into the table.
+ * TCL_HASH_KEY_SYSTEM_HASH -	If this flag is set then all memory internally
+ *                              allocated for the hash table that is not for an
+ *                              entry will use the system heap.
+ */
+
+#define TCL_HASH_KEY_RANDOMIZE_HASH 0x1
+#define TCL_HASH_KEY_SYSTEM_HASH    0x2
+
+/*
+ * Structure definition for the methods associated with a hash table key type.
+ */
+
+#define TCL_HASH_KEY_TYPE_VERSION 1
+struct Tcl_HashKeyType {
+    int version;		/* Version of the table. If this structure is
+				 * extended in future then the version can be
+				 * used to distinguish between different
+				 * structures. */
+    int flags;			/* Flags, see above for details. */
+    Tcl_HashKeyProc *hashKeyProc;
+				/* Calculates a hash value for the key. If
+				 * this is NULL then the pointer itself is
+				 * used as a hash value. */
+    Tcl_CompareHashKeysProc *compareKeysProc;
+				/* Compares two keys and returns zero if they
+				 * do not match, and non-zero if they do. If
+				 * this is NULL then the pointers are
+				 * compared. */
+    Tcl_AllocHashEntryProc *allocEntryProc;
+				/* Called to allocate memory for a new entry,
+				 * i.e. if the key is a string then this could
+				 * allocate a single block which contains
+				 * enough space for both the entry and the
+				 * string. Only the key field of the allocated
+				 * Tcl_HashEntry structure needs to be filled
+				 * in. If something else needs to be done to
+				 * the key, i.e. incrementing a reference
+				 * count then that should be done by this
+				 * function. If this is NULL then Tcl_Alloc is
+				 * used to allocate enough space for a
+				 * Tcl_HashEntry and the key pointer is
+				 * assigned to key.oneWordValue. */
+    Tcl_FreeHashEntryProc *freeEntryProc;
+				/* Called to free memory associated with an
+				 * entry. If something else needs to be done
+				 * to the key, i.e. decrementing a reference
+				 * count then that should be done by this
+				 * function. If this is NULL then Tcl_Free is
+				 * used to free the Tcl_HashEntry. */
+};
+
+/*
+ * Structure definition for a hash table.  Must be in tcl.h so clients can
+ * allocate space for these structures, but clients should never access any
+ * fields in this structure.
+ */
+
+#define TCL_SMALL_HASH_TABLE 4
+struct Tcl_HashTable {
+    Tcl_HashEntry **buckets;	/* Pointer to bucket array. Each element
+				 * points to first entry in bucket's hash
+				 * chain, or NULL. */
+    Tcl_HashEntry *staticBuckets[TCL_SMALL_HASH_TABLE];
+				/* Bucket array used for small tables (to
+				 * avoid mallocs and frees). */
+    int numBuckets;		/* Total number of buckets allocated at
+				 * **bucketPtr. */
+    int numEntries;		/* Total number of entries present in
+				 * table. */
+    int rebuildSize;		/* Enlarge table when numEntries gets to be
+				 * this large. */
+    int downShift;		/* Shift count used in hashing function.
+				 * Designed to use high-order bits of
+				 * randomized keys. */
+    int mask;			/* Mask value used in hashing function. */
+    int keyType;		/* Type of keys used in this table. It's
+				 * either TCL_CUSTOM_KEYS, TCL_STRING_KEYS,
+				 * TCL_ONE_WORD_KEYS, or an integer giving the
+				 * number of ints that is the size of the
+				 * key. */
+    Tcl_HashEntry *(*findProc) (Tcl_HashTable *tablePtr, const char *key);
+    Tcl_HashEntry *(*createProc) (Tcl_HashTable *tablePtr, const char *key,
+	    int *newPtr);
+    const Tcl_HashKeyType *typePtr;
+				/* Type of the keys used in the
+				 * Tcl_HashTable. */
+};
+
+/*
+ * Structure definition for information used to keep track of searches through
+ * hash tables:
+ */
+
+typedef struct Tcl_HashSearch {
+    Tcl_HashTable *tablePtr;	/* Table being searched. */
+    int nextIndex;		/* Index of next bucket to be enumerated after
+				 * present one. */
+    Tcl_HashEntry *nextEntryPtr;/* Next entry to be enumerated in the current
+				 * bucket. */
+} Tcl_HashSearch;
+
+/*
+ * Acceptable key types for hash tables:
+ *
+ * TCL_STRING_KEYS:		The keys are strings, they are copied into the
+ *				entry.
+ * TCL_ONE_WORD_KEYS:		The keys are pointers, the pointer is stored
+ *				in the entry.
+ * TCL_CUSTOM_TYPE_KEYS:	The keys are arbitrary types which are copied
+ *				into the entry.
+ * TCL_CUSTOM_PTR_KEYS:		The keys are pointers to arbitrary types, the
+ *				pointer is stored in the entry.
+ *
+ * While maintaining binary compatability the above have to be distinct values
+ * as they are used to differentiate between old versions of the hash table
+ * which don't have a typePtr and new ones which do. Once binary compatability
+ * is discarded in favour of making more wide spread changes TCL_STRING_KEYS
+ * can be the same as TCL_CUSTOM_TYPE_KEYS, and TCL_ONE_WORD_KEYS can be the
+ * same as TCL_CUSTOM_PTR_KEYS because they simply determine how the key is
+ * accessed from the entry and not the behaviour.
+ */
+
+#define TCL_STRING_KEYS		(0)
+#define TCL_ONE_WORD_KEYS	(1)
+#define TCL_CUSTOM_TYPE_KEYS	(-2)
+#define TCL_CUSTOM_PTR_KEYS	(-1)
+
+/*
+ * Structure definition for information used to keep track of searches through
+ * dictionaries. These fields should not be accessed by code outside
+ * tclDictObj.c
+ */
+
+typedef struct {
+    void *next;			/* Search position for underlying hash
+				 * table. */
+    int epoch;			/* Epoch marker for dictionary being searched,
+				 * or -1 if search has terminated. */
+    Tcl_Dict dictionaryPtr;	/* Reference to dictionary being searched. */
+} Tcl_DictSearch;
+
+/*
+ *----------------------------------------------------------------------------
+ * Flag values to pass to Tcl_DoOneEvent to disable searches for some kinds of
+ * events:
+ */
+
+#define TCL_DONT_WAIT		(1<<1)
+#define TCL_WINDOW_EVENTS	(1<<2)
+#define TCL_FILE_EVENTS		(1<<3)
+#define TCL_TIMER_EVENTS	(1<<4)
+#define TCL_IDLE_EVENTS		(1<<5)	/* WAS 0x10 ???? */
+#define TCL_ALL_EVENTS		(~TCL_DONT_WAIT)
+
+/*
+ * The following structure defines a generic event for the Tcl event system.
+ * These are the things that are queued in calls to Tcl_QueueEvent and
+ * serviced later by Tcl_DoOneEvent. There can be many different kinds of
+ * events with different fields, corresponding to window events, timer events,
+ * etc. The structure for a particular event consists of a Tcl_Event header
+ * followed by additional information specific to that event.
+ */
+
+struct Tcl_Event {
+    Tcl_EventProc *proc;	/* Function to call to service this event. */
+    struct Tcl_Event *nextPtr;	/* Next in list of pending events, or NULL. */
+};
+
+/*
+ * Positions to pass to Tcl_QueueEvent:
+ */
+
+typedef enum {
+    TCL_QUEUE_TAIL, TCL_QUEUE_HEAD, TCL_QUEUE_MARK
+} Tcl_QueuePosition;
+
+/*
+ * Values to pass to Tcl_SetServiceMode to specify the behavior of notifier
+ * event routines.
+ */
+
+#define TCL_SERVICE_NONE 0
+#define TCL_SERVICE_ALL 1
+
+/*
+ * The following structure keeps is used to hold a time value, either as an
+ * absolute time (the number of seconds from the epoch) or as an elapsed time.
+ * On Unix systems the epoch is Midnight Jan 1, 1970 GMT.
+ */
+
+typedef struct Tcl_Time {
+    long sec;			/* Seconds. */
+    long usec;			/* Microseconds. */
+} Tcl_Time;
+
+typedef void (Tcl_SetTimerProc) (CONST86 Tcl_Time *timePtr);
+typedef int (Tcl_WaitForEventProc) (CONST86 Tcl_Time *timePtr);
+
+/*
+ * TIP #233 (Virtualized Time)
+ */
+
+typedef void (Tcl_GetTimeProc)   (Tcl_Time *timebuf, ClientData clientData);
+typedef void (Tcl_ScaleTimeProc) (Tcl_Time *timebuf, ClientData clientData);
+
+/*
+ *----------------------------------------------------------------------------
+ * Bits to pass to Tcl_CreateFileHandler and Tcl_CreateChannelHandler to
+ * indicate what sorts of events are of interest:
+ */
+
+#define TCL_READABLE		(1<<1)
+#define TCL_WRITABLE		(1<<2)
+#define TCL_EXCEPTION		(1<<3)
+
+/*
+ * Flag values to pass to Tcl_OpenCommandChannel to indicate the disposition
+ * of the stdio handles. TCL_STDIN, TCL_STDOUT, TCL_STDERR, are also used in
+ * Tcl_GetStdChannel.
+ */
+
+#define TCL_STDIN		(1<<1)
+#define TCL_STDOUT		(1<<2)
+#define TCL_STDERR		(1<<3)
+#define TCL_ENFORCE_MODE	(1<<4)
+
+/*
+ * Bits passed to Tcl_DriverClose2Proc to indicate which side of a channel
+ * should be closed.
+ */
+
+#define TCL_CLOSE_READ		(1<<1)
+#define TCL_CLOSE_WRITE		(1<<2)
+
+/*
+ * Value to use as the closeProc for a channel that supports the close2Proc
+ * interface.
+ */
+
+#define TCL_CLOSE2PROC		((Tcl_DriverCloseProc *) 1)
+
+/*
+ * Channel version tag. This was introduced in 8.3.2/8.4.
+ */
+
+#define TCL_CHANNEL_VERSION_1	((Tcl_ChannelTypeVersion) 0x1)
+#define TCL_CHANNEL_VERSION_2	((Tcl_ChannelTypeVersion) 0x2)
+#define TCL_CHANNEL_VERSION_3	((Tcl_ChannelTypeVersion) 0x3)
+#define TCL_CHANNEL_VERSION_4	((Tcl_ChannelTypeVersion) 0x4)
+#define TCL_CHANNEL_VERSION_5	((Tcl_ChannelTypeVersion) 0x5)
+
+/*
+ * TIP #218: Channel Actions, Ids for Tcl_DriverThreadActionProc.
+ */
+
+#define TCL_CHANNEL_THREAD_INSERT (0)
+#define TCL_CHANNEL_THREAD_REMOVE (1)
+
+/*
+ * Typedefs for the various operations in a channel type:
+ */
+
+typedef int	(Tcl_DriverBlockModeProc) (ClientData instanceData, int mode);
+typedef int	(Tcl_DriverCloseProc) (ClientData instanceData,
+			Tcl_Interp *interp);
+typedef int	(Tcl_DriverClose2Proc) (ClientData instanceData,
+			Tcl_Interp *interp, int flags);
+typedef int	(Tcl_DriverInputProc) (ClientData instanceData, char *buf,
+			int toRead, int *errorCodePtr);
+typedef int	(Tcl_DriverOutputProc) (ClientData instanceData,
+			CONST84 char *buf, int toWrite, int *errorCodePtr);
+typedef int	(Tcl_DriverSeekProc) (ClientData instanceData, long offset,
+			int mode, int *errorCodePtr);
+typedef int	(Tcl_DriverSetOptionProc) (ClientData instanceData,
+			Tcl_Interp *interp, const char *optionName,
+			const char *value);
+typedef int	(Tcl_DriverGetOptionProc) (ClientData instanceData,
+			Tcl_Interp *interp, CONST84 char *optionName,
+			Tcl_DString *dsPtr);
+typedef void	(Tcl_DriverWatchProc) (ClientData instanceData, int mask);
+typedef int	(Tcl_DriverGetHandleProc) (ClientData instanceData,
+			int direction, ClientData *handlePtr);
+typedef int	(Tcl_DriverFlushProc) (ClientData instanceData);
+typedef int	(Tcl_DriverHandlerProc) (ClientData instanceData,
+			int interestMask);
+typedef Tcl_WideInt (Tcl_DriverWideSeekProc) (ClientData instanceData,
+			Tcl_WideInt offset, int mode, int *errorCodePtr);
+/*
+ * TIP #218, Channel Thread Actions
+ */
+typedef void	(Tcl_DriverThreadActionProc) (ClientData instanceData,
+			int action);
+/*
+ * TIP #208, File Truncation (etc.)
+ */
+typedef int	(Tcl_DriverTruncateProc) (ClientData instanceData,
+			Tcl_WideInt length);
+
+/*
+ * struct Tcl_ChannelType:
+ *
+ * One such structure exists for each type (kind) of channel. It collects
+ * together in one place all the functions that are part of the specific
+ * channel type.
+ *
+ * It is recommend that the Tcl_Channel* functions are used to access elements
+ * of this structure, instead of direct accessing.
+ */
+
+typedef struct Tcl_ChannelType {
+    const char *typeName;	/* The name of the channel type in Tcl
+				 * commands. This storage is owned by channel
+				 * type. */
+    Tcl_ChannelTypeVersion version;
+				/* Version of the channel type. */
+    Tcl_DriverCloseProc *closeProc;
+				/* Function to call to close the channel, or
+				 * TCL_CLOSE2PROC if the close2Proc should be
+				 * used instead. */
+    Tcl_DriverInputProc *inputProc;
+				/* Function to call for input on channel. */
+    Tcl_DriverOutputProc *outputProc;
+				/* Function to call for output on channel. */
+    Tcl_DriverSeekProc *seekProc;
+				/* Function to call to seek on the channel.
+				 * May be NULL. */
+    Tcl_DriverSetOptionProc *setOptionProc;
+				/* Set an option on a channel. */
+    Tcl_DriverGetOptionProc *getOptionProc;
+				/* Get an option from a channel. */
+    Tcl_DriverWatchProc *watchProc;
+				/* Set up the notifier to watch for events on
+				 * this channel. */
+    Tcl_DriverGetHandleProc *getHandleProc;
+				/* Get an OS handle from the channel or NULL
+				 * if not supported. */
+    Tcl_DriverClose2Proc *close2Proc;
+				/* Function to call to close the channel if
+				 * the device supports closing the read &
+				 * write sides independently. */
+    Tcl_DriverBlockModeProc *blockModeProc;
+				/* Set blocking mode for the raw channel. May
+				 * be NULL. */
+    /*
+     * Only valid in TCL_CHANNEL_VERSION_2 channels or later.
+     */
+    Tcl_DriverFlushProc *flushProc;
+				/* Function to call to flush a channel. May be
+				 * NULL. */
+    Tcl_DriverHandlerProc *handlerProc;
+				/* Function to call to handle a channel event.
+				 * This will be passed up the stacked channel
+				 * chain. */
+    /*
+     * Only valid in TCL_CHANNEL_VERSION_3 channels or later.
+     */
+    Tcl_DriverWideSeekProc *wideSeekProc;
+				/* Function to call to seek on the channel
+				 * which can handle 64-bit offsets. May be
+				 * NULL, and must be NULL if seekProc is
+				 * NULL. */
+    /*
+     * Only valid in TCL_CHANNEL_VERSION_4 channels or later.
+     * TIP #218, Channel Thread Actions.
+     */
+    Tcl_DriverThreadActionProc *threadActionProc;
+				/* Function to call to notify the driver of
+				 * thread specific activity for a channel. May
+				 * be NULL. */
+    /*
+     * Only valid in TCL_CHANNEL_VERSION_5 channels or later.
+     * TIP #208, File Truncation.
+     */
+    Tcl_DriverTruncateProc *truncateProc;
+				/* Function to call to truncate the underlying
+				 * file to a particular length. May be NULL if
+				 * the channel does not support truncation. */
+} Tcl_ChannelType;
+
+/*
+ * The following flags determine whether the blockModeProc above should set
+ * the channel into blocking or nonblocking mode. They are passed as arguments
+ * to the blockModeProc function in the above structure.
+ */
+
+#define TCL_MODE_BLOCKING	0	/* Put channel into blocking mode. */
+#define TCL_MODE_NONBLOCKING	1	/* Put channel into nonblocking
+					 * mode. */
+
+/*
+ *----------------------------------------------------------------------------
+ * Enum for different types of file paths.
+ */
+
+typedef enum Tcl_PathType {
+    TCL_PATH_ABSOLUTE,
+    TCL_PATH_RELATIVE,
+    TCL_PATH_VOLUME_RELATIVE
+} Tcl_PathType;
+
+/*
+ * The following structure is used to pass glob type data amongst the various
+ * glob routines and Tcl_FSMatchInDirectory.
+ */
+
+typedef struct Tcl_GlobTypeData {
+    int type;			/* Corresponds to bcdpfls as in 'find -t'. */
+    int perm;			/* Corresponds to file permissions. */
+    Tcl_Obj *macType;		/* Acceptable Mac type. */
+    Tcl_Obj *macCreator;	/* Acceptable Mac creator. */
+} Tcl_GlobTypeData;
+
+/*
+ * Type and permission definitions for glob command.
+ */
+
+#define TCL_GLOB_TYPE_BLOCK		(1<<0)
+#define TCL_GLOB_TYPE_CHAR		(1<<1)
+#define TCL_GLOB_TYPE_DIR		(1<<2)
+#define TCL_GLOB_TYPE_PIPE		(1<<3)
+#define TCL_GLOB_TYPE_FILE		(1<<4)
+#define TCL_GLOB_TYPE_LINK		(1<<5)
+#define TCL_GLOB_TYPE_SOCK		(1<<6)
+#define TCL_GLOB_TYPE_MOUNT		(1<<7)
+
+#define TCL_GLOB_PERM_RONLY		(1<<0)
+#define TCL_GLOB_PERM_HIDDEN		(1<<1)
+#define TCL_GLOB_PERM_R			(1<<2)
+#define TCL_GLOB_PERM_W			(1<<3)
+#define TCL_GLOB_PERM_X			(1<<4)
+
+/*
+ * Flags for the unload callback function.
+ */
+
+#define TCL_UNLOAD_DETACH_FROM_INTERPRETER	(1<<0)
+#define TCL_UNLOAD_DETACH_FROM_PROCESS		(1<<1)
+
+/*
+ * Typedefs for the various filesystem operations:
+ */
+
+typedef int (Tcl_FSStatProc) (Tcl_Obj *pathPtr, Tcl_StatBuf *buf);
+typedef int (Tcl_FSAccessProc) (Tcl_Obj *pathPtr, int mode);
+typedef Tcl_Channel (Tcl_FSOpenFileChannelProc) (Tcl_Interp *interp,
+	Tcl_Obj *pathPtr, int mode, int permissions);
+typedef int (Tcl_FSMatchInDirectoryProc) (Tcl_Interp *interp, Tcl_Obj *result,
+	Tcl_Obj *pathPtr, const char *pattern, Tcl_GlobTypeData *types);
+typedef Tcl_Obj * (Tcl_FSGetCwdProc) (Tcl_Interp *interp);
+typedef int (Tcl_FSChdirProc) (Tcl_Obj *pathPtr);
+typedef int (Tcl_FSLstatProc) (Tcl_Obj *pathPtr, Tcl_StatBuf *buf);
+typedef int (Tcl_FSCreateDirectoryProc) (Tcl_Obj *pathPtr);
+typedef int (Tcl_FSDeleteFileProc) (Tcl_Obj *pathPtr);
+typedef int (Tcl_FSCopyDirectoryProc) (Tcl_Obj *srcPathPtr,
+	Tcl_Obj *destPathPtr, Tcl_Obj **errorPtr);
+typedef int (Tcl_FSCopyFileProc) (Tcl_Obj *srcPathPtr, Tcl_Obj *destPathPtr);
+typedef int (Tcl_FSRemoveDirectoryProc) (Tcl_Obj *pathPtr, int recursive,
+	Tcl_Obj **errorPtr);
+typedef int (Tcl_FSRenameFileProc) (Tcl_Obj *srcPathPtr, Tcl_Obj *destPathPtr);
+typedef void (Tcl_FSUnloadFileProc) (Tcl_LoadHandle loadHandle);
+typedef Tcl_Obj * (Tcl_FSListVolumesProc) (void);
+/* We have to declare the utime structure here. */
+struct utimbuf;
+typedef int (Tcl_FSUtimeProc) (Tcl_Obj *pathPtr, struct utimbuf *tval);
+typedef int (Tcl_FSNormalizePathProc) (Tcl_Interp *interp, Tcl_Obj *pathPtr,
+	int nextCheckpoint);
+typedef int (Tcl_FSFileAttrsGetProc) (Tcl_Interp *interp, int index,
+	Tcl_Obj *pathPtr, Tcl_Obj **objPtrRef);
+typedef const char *CONST86 * (Tcl_FSFileAttrStringsProc) (Tcl_Obj *pathPtr,
+	Tcl_Obj **objPtrRef);
+typedef int (Tcl_FSFileAttrsSetProc) (Tcl_Interp *interp, int index,
+	Tcl_Obj *pathPtr, Tcl_Obj *objPtr);
+typedef Tcl_Obj * (Tcl_FSLinkProc) (Tcl_Obj *pathPtr, Tcl_Obj *toPtr,
+	int linkType);
+typedef int (Tcl_FSLoadFileProc) (Tcl_Interp *interp, Tcl_Obj *pathPtr,
+	Tcl_LoadHandle *handlePtr, Tcl_FSUnloadFileProc **unloadProcPtr);
+typedef int (Tcl_FSPathInFilesystemProc) (Tcl_Obj *pathPtr,
+	ClientData *clientDataPtr);
+typedef Tcl_Obj * (Tcl_FSFilesystemPathTypeProc) (Tcl_Obj *pathPtr);
+typedef Tcl_Obj * (Tcl_FSFilesystemSeparatorProc) (Tcl_Obj *pathPtr);
+typedef void (Tcl_FSFreeInternalRepProc) (ClientData clientData);
+typedef ClientData (Tcl_FSDupInternalRepProc) (ClientData clientData);
+typedef Tcl_Obj * (Tcl_FSInternalToNormalizedProc) (ClientData clientData);
+typedef ClientData (Tcl_FSCreateInternalRepProc) (Tcl_Obj *pathPtr);
+
+typedef struct Tcl_FSVersion_ *Tcl_FSVersion;
+
+/*
+ *----------------------------------------------------------------------------
+ * Data structures related to hooking into the filesystem
+ */
+
+/*
+ * Filesystem version tag.  This was introduced in 8.4.
+ */
+
+#define TCL_FILESYSTEM_VERSION_1	((Tcl_FSVersion) 0x1)
+
+/*
+ * struct Tcl_Filesystem:
+ *
+ * One such structure exists for each type (kind) of filesystem. It collects
+ * together in one place all the functions that are part of the specific
+ * filesystem. Tcl always accesses the filesystem through one of these
+ * structures.
+ *
+ * Not all entries need be non-NULL; any which are NULL are simply ignored.
+ * However, a complete filesystem should provide all of these functions. The
+ * explanations in the structure show the importance of each function.
+ */
+
+typedef struct Tcl_Filesystem {
+    const char *typeName;	/* The name of the filesystem. */
+    int structureLength;	/* Length of this structure, so future binary
+				 * compatibility can be assured. */
+    Tcl_FSVersion version;	/* Version of the filesystem type. */
+    Tcl_FSPathInFilesystemProc *pathInFilesystemProc;
+				/* Function to check whether a path is in this
+				 * filesystem. This is the most important
+				 * filesystem function. */
+    Tcl_FSDupInternalRepProc *dupInternalRepProc;
+				/* Function to duplicate internal fs rep. May
+				 * be NULL (but then fs is less efficient). */
+    Tcl_FSFreeInternalRepProc *freeInternalRepProc;
+				/* Function to free internal fs rep. Must be
+				 * implemented if internal representations
+				 * need freeing, otherwise it can be NULL. */
+    Tcl_FSInternalToNormalizedProc *internalToNormalizedProc;
+				/* Function to convert internal representation
+				 * to a normalized path. Only required if the
+				 * fs creates pure path objects with no
+				 * string/path representation. */
+    Tcl_FSCreateInternalRepProc *createInternalRepProc;
+				/* Function to create a filesystem-specific
+				 * internal representation. May be NULL if
+				 * paths have no internal representation, or
+				 * if the Tcl_FSPathInFilesystemProc for this
+				 * filesystem always immediately creates an
+				 * internal representation for paths it
+				 * accepts. */
+    Tcl_FSNormalizePathProc *normalizePathProc;
+				/* Function to normalize a path.  Should be
+				 * implemented for all filesystems which can
+				 * have multiple string representations for
+				 * the same path object. */
+    Tcl_FSFilesystemPathTypeProc *filesystemPathTypeProc;
+				/* Function to determine the type of a path in
+				 * this filesystem. May be NULL. */
+    Tcl_FSFilesystemSeparatorProc *filesystemSeparatorProc;
+				/* Function to return the separator
+				 * character(s) for this filesystem. Must be
+				 * implemented. */
+    Tcl_FSStatProc *statProc;	/* Function to process a 'Tcl_FSStat()' call.
+				 * Must be implemented for any reasonable
+				 * filesystem. */
+    Tcl_FSAccessProc *accessProc;
+				/* Function to process a 'Tcl_FSAccess()'
+				 * call. Must be implemented for any
+				 * reasonable filesystem. */
+    Tcl_FSOpenFileChannelProc *openFileChannelProc;
+				/* Function to process a
+				 * 'Tcl_FSOpenFileChannel()' call. Must be
+				 * implemented for any reasonable
+				 * filesystem. */
+    Tcl_FSMatchInDirectoryProc *matchInDirectoryProc;
+				/* Function to process a
+				 * 'Tcl_FSMatchInDirectory()'.  If not
+				 * implemented, then glob and recursive copy
+				 * functionality will be lacking in the
+				 * filesystem. */
+    Tcl_FSUtimeProc *utimeProc;	/* Function to process a 'Tcl_FSUtime()' call.
+				 * Required to allow setting (not reading) of
+				 * times with 'file mtime', 'file atime' and
+				 * the open-r/open-w/fcopy implementation of
+				 * 'file copy'. */
+    Tcl_FSLinkProc *linkProc;	/* Function to process a 'Tcl_FSLink()' call.
+				 * Should be implemented only if the
+				 * filesystem supports links (reading or
+				 * creating). */
+    Tcl_FSListVolumesProc *listVolumesProc;
+				/* Function to list any filesystem volumes
+				 * added by this filesystem. Should be
+				 * implemented only if the filesystem adds
+				 * volumes at the head of the filesystem. */
+    Tcl_FSFileAttrStringsProc *fileAttrStringsProc;
+				/* Function to list all attributes strings
+				 * which are valid for this filesystem. If not
+				 * implemented the filesystem will not support
+				 * the 'file attributes' command. This allows
+				 * arbitrary additional information to be
+				 * attached to files in the filesystem. */
+    Tcl_FSFileAttrsGetProc *fileAttrsGetProc;
+				/* Function to process a
+				 * 'Tcl_FSFileAttrsGet()' call, used by 'file
+				 * attributes'. */
+    Tcl_FSFileAttrsSetProc *fileAttrsSetProc;
+				/* Function to process a
+				 * 'Tcl_FSFileAttrsSet()' call, used by 'file
+				 * attributes'.  */
+    Tcl_FSCreateDirectoryProc *createDirectoryProc;
+				/* Function to process a
+				 * 'Tcl_FSCreateDirectory()' call. Should be
+				 * implemented unless the FS is read-only. */
+    Tcl_FSRemoveDirectoryProc *removeDirectoryProc;
+				/* Function to process a
+				 * 'Tcl_FSRemoveDirectory()' call. Should be
+				 * implemented unless the FS is read-only. */
+    Tcl_FSDeleteFileProc *deleteFileProc;
+				/* Function to process a 'Tcl_FSDeleteFile()'
+				 * call. Should be implemented unless the FS
+				 * is read-only. */
+    Tcl_FSCopyFileProc *copyFileProc;
+				/* Function to process a 'Tcl_FSCopyFile()'
+				 * call. If not implemented Tcl will fall back
+				 * on open-r, open-w and fcopy as a copying
+				 * mechanism, for copying actions initiated in
+				 * Tcl (not C). */
+    Tcl_FSRenameFileProc *renameFileProc;
+				/* Function to process a 'Tcl_FSRenameFile()'
+				 * call. If not implemented, Tcl will fall
+				 * back on a copy and delete mechanism, for
+				 * rename actions initiated in Tcl (not C). */
+    Tcl_FSCopyDirectoryProc *copyDirectoryProc;
+				/* Function to process a
+				 * 'Tcl_FSCopyDirectory()' call. If not
+				 * implemented, Tcl will fall back on a
+				 * recursive create-dir, file copy mechanism,
+				 * for copying actions initiated in Tcl (not
+				 * C). */
+    Tcl_FSLstatProc *lstatProc;	/* Function to process a 'Tcl_FSLstat()' call.
+				 * If not implemented, Tcl will attempt to use
+				 * the 'statProc' defined above instead. */
+    Tcl_FSLoadFileProc *loadFileProc;
+				/* Function to process a 'Tcl_FSLoadFile()'
+				 * call. If not implemented, Tcl will fall
+				 * back on a copy to native-temp followed by a
+				 * Tcl_FSLoadFile on that temporary copy. */
+    Tcl_FSGetCwdProc *getCwdProc;
+				/* Function to process a 'Tcl_FSGetCwd()'
+				 * call. Most filesystems need not implement
+				 * this. It will usually only be called once,
+				 * if 'getcwd' is called before 'chdir'. May
+				 * be NULL. */
+    Tcl_FSChdirProc *chdirProc;	/* Function to process a 'Tcl_FSChdir()' call.
+				 * If filesystems do not implement this, it
+				 * will be emulated by a series of directory
+				 * access checks. Otherwise, virtual
+				 * filesystems which do implement it need only
+				 * respond with a positive return result if
+				 * the dirName is a valid directory in their
+				 * filesystem. They need not remember the
+				 * result, since that will be automatically
+				 * remembered for use by GetCwd. Real
+				 * filesystems should carry out the correct
+				 * action (i.e. call the correct system
+				 * 'chdir' api). If not implemented, then 'cd'
+				 * and 'pwd' will fail inside the
+				 * filesystem. */
+} Tcl_Filesystem;
+
+/*
+ * The following definitions are used as values for the 'linkAction' flag to
+ * Tcl_FSLink, or the linkProc of any filesystem. Any combination of flags can
+ * be given. For link creation, the linkProc should create a link which
+ * matches any of the types given.
+ *
+ * TCL_CREATE_SYMBOLIC_LINK -	Create a symbolic or soft link.
+ * TCL_CREATE_HARD_LINK -	Create a hard link.
+ */
+
+#define TCL_CREATE_SYMBOLIC_LINK	0x01
+#define TCL_CREATE_HARD_LINK		0x02
+
+/*
+ *----------------------------------------------------------------------------
+ * The following structure represents the Notifier functions that you can
+ * override with the Tcl_SetNotifier call.
+ */
+
+typedef struct Tcl_NotifierProcs {
+    Tcl_SetTimerProc *setTimerProc;
+    Tcl_WaitForEventProc *waitForEventProc;
+    Tcl_CreateFileHandlerProc *createFileHandlerProc;
+    Tcl_DeleteFileHandlerProc *deleteFileHandlerProc;
+    Tcl_InitNotifierProc *initNotifierProc;
+    Tcl_FinalizeNotifierProc *finalizeNotifierProc;
+    Tcl_AlertNotifierProc *alertNotifierProc;
+    Tcl_ServiceModeHookProc *serviceModeHookProc;
+} Tcl_NotifierProcs;
+
+/*
+ *----------------------------------------------------------------------------
+ * The following data structures and declarations are for the new Tcl parser.
+ *
+ * For each word of a command, and for each piece of a word such as a variable
+ * reference, one of the following structures is created to describe the
+ * token.
+ */
+
+typedef struct Tcl_Token {
+    int type;			/* Type of token, such as TCL_TOKEN_WORD; see
+				 * below for valid types. */
+    const char *start;		/* First character in token. */
+    int size;			/* Number of bytes in token. */
+    int numComponents;		/* If this token is composed of other tokens,
+				 * this field tells how many of them there are
+				 * (including components of components, etc.).
+				 * The component tokens immediately follow
+				 * this one. */
+} Tcl_Token;
+
+/*
+ * Type values defined for Tcl_Token structures. These values are defined as
+ * mask bits so that it's easy to check for collections of types.
+ *
+ * TCL_TOKEN_WORD -		The token describes one word of a command,
+ *				from the first non-blank character of the word
+ *				(which may be " or {) up to but not including
+ *				the space, semicolon, or bracket that
+ *				terminates the word. NumComponents counts the
+ *				total number of sub-tokens that make up the
+ *				word. This includes, for example, sub-tokens
+ *				of TCL_TOKEN_VARIABLE tokens.
+ * TCL_TOKEN_SIMPLE_WORD -	This token is just like TCL_TOKEN_WORD except
+ *				that the word is guaranteed to consist of a
+ *				single TCL_TOKEN_TEXT sub-token.
+ * TCL_TOKEN_TEXT -		The token describes a range of literal text
+ *				that is part of a word. NumComponents is
+ *				always 0.
+ * TCL_TOKEN_BS -		The token describes a backslash sequence that
+ *				must be collapsed. NumComponents is always 0.
+ * TCL_TOKEN_COMMAND -		The token describes a command whose result
+ *				must be substituted into the word. The token
+ *				includes the enclosing brackets. NumComponents
+ *				is always 0.
+ * TCL_TOKEN_VARIABLE -		The token describes a variable substitution,
+ *				including the dollar sign, variable name, and
+ *				array index (if there is one) up through the
+ *				right parentheses. NumComponents tells how
+ *				many additional tokens follow to represent the
+ *				variable name. The first token will be a
+ *				TCL_TOKEN_TEXT token that describes the
+ *				variable name. If the variable is an array
+ *				reference then there will be one or more
+ *				additional tokens, of type TCL_TOKEN_TEXT,
+ *				TCL_TOKEN_BS, TCL_TOKEN_COMMAND, and
+ *				TCL_TOKEN_VARIABLE, that describe the array
+ *				index; numComponents counts the total number
+ *				of nested tokens that make up the variable
+ *				reference, including sub-tokens of
+ *				TCL_TOKEN_VARIABLE tokens.
+ * TCL_TOKEN_SUB_EXPR -		The token describes one subexpression of an
+ *				expression, from the first non-blank character
+ *				of the subexpression up to but not including
+ *				the space, brace, or bracket that terminates
+ *				the subexpression. NumComponents counts the
+ *				total number of following subtokens that make
+ *				up the subexpression; this includes all
+ *				subtokens for any nested TCL_TOKEN_SUB_EXPR
+ *				tokens. For example, a numeric value used as a
+ *				primitive operand is described by a
+ *				TCL_TOKEN_SUB_EXPR token followed by a
+ *				TCL_TOKEN_TEXT token. A binary subexpression
+ *				is described by a TCL_TOKEN_SUB_EXPR token
+ *				followed by the TCL_TOKEN_OPERATOR token for
+ *				the operator, then TCL_TOKEN_SUB_EXPR tokens
+ *				for the left then the right operands.
+ * TCL_TOKEN_OPERATOR -		The token describes one expression operator.
+ *				An operator might be the name of a math
+ *				function such as "abs". A TCL_TOKEN_OPERATOR
+ *				token is always preceeded by one
+ *				TCL_TOKEN_SUB_EXPR token for the operator's
+ *				subexpression, and is followed by zero or more
+ *				TCL_TOKEN_SUB_EXPR tokens for the operator's
+ *				operands. NumComponents is always 0.
+ * TCL_TOKEN_EXPAND_WORD -	This token is just like TCL_TOKEN_WORD except
+ *				that it marks a word that began with the
+ *				literal character prefix "{*}". This word is
+ *				marked to be expanded - that is, broken into
+ *				words after substitution is complete.
+ */
+
+#define TCL_TOKEN_WORD		1
+#define TCL_TOKEN_SIMPLE_WORD	2
+#define TCL_TOKEN_TEXT		4
+#define TCL_TOKEN_BS		8
+#define TCL_TOKEN_COMMAND	16
+#define TCL_TOKEN_VARIABLE	32
+#define TCL_TOKEN_SUB_EXPR	64
+#define TCL_TOKEN_OPERATOR	128
+#define TCL_TOKEN_EXPAND_WORD	256
+
+/*
+ * Parsing error types. On any parsing error, one of these values will be
+ * stored in the error field of the Tcl_Parse structure defined below.
+ */
+
+#define TCL_PARSE_SUCCESS		0
+#define TCL_PARSE_QUOTE_EXTRA		1
+#define TCL_PARSE_BRACE_EXTRA		2
+#define TCL_PARSE_MISSING_BRACE		3
+#define TCL_PARSE_MISSING_BRACKET	4
+#define TCL_PARSE_MISSING_PAREN		5
+#define TCL_PARSE_MISSING_QUOTE		6
+#define TCL_PARSE_MISSING_VAR_BRACE	7
+#define TCL_PARSE_SYNTAX		8
+#define TCL_PARSE_BAD_NUMBER		9
+
+/*
+ * A structure of the following type is filled in by Tcl_ParseCommand. It
+ * describes a single command parsed from an input string.
+ */
+
+#define NUM_STATIC_TOKENS 20
+
+typedef struct Tcl_Parse {
+    const char *commentStart;	/* Pointer to # that begins the first of one
+				 * or more comments preceding the command. */
+    int commentSize;		/* Number of bytes in comments (up through
+				 * newline character that terminates the last
+				 * comment). If there were no comments, this
+				 * field is 0. */
+    const char *commandStart;	/* First character in first word of
+				 * command. */
+    int commandSize;		/* Number of bytes in command, including first
+				 * character of first word, up through the
+				 * terminating newline, close bracket, or
+				 * semicolon. */
+    int numWords;		/* Total number of words in command. May be
+				 * 0. */
+    Tcl_Token *tokenPtr;	/* Pointer to first token representing the
+				 * words of the command. Initially points to
+				 * staticTokens, but may change to point to
+				 * malloc-ed space if command exceeds space in
+				 * staticTokens. */
+    int numTokens;		/* Total number of tokens in command. */
+    int tokensAvailable;	/* Total number of tokens available at
+				 * *tokenPtr. */
+    int errorType;		/* One of the parsing error types defined
+				 * above. */
+
+    /*
+     * The fields below are intended only for the private use of the parser.
+     * They should not be used by functions that invoke Tcl_ParseCommand.
+     */
+
+    const char *string;		/* The original command string passed to
+				 * Tcl_ParseCommand. */
+    const char *end;		/* Points to the character just after the last
+				 * one in the command string. */
+    Tcl_Interp *interp;		/* Interpreter to use for error reporting, or
+				 * NULL. */
+    const char *term;		/* Points to character in string that
+				 * terminated most recent token. Filled in by
+				 * ParseTokens. If an error occurs, points to
+				 * beginning of region where the error
+				 * occurred (e.g. the open brace if the close
+				 * brace is missing). */
+    int incomplete;		/* This field is set to 1 by Tcl_ParseCommand
+				 * if the command appears to be incomplete.
+				 * This information is used by
+				 * Tcl_CommandComplete. */
+    Tcl_Token staticTokens[NUM_STATIC_TOKENS];
+				/* Initial space for tokens for command. This
+				 * space should be large enough to accommodate
+				 * most commands; dynamic space is allocated
+				 * for very large commands that don't fit
+				 * here. */
+} Tcl_Parse;
+
+/*
+ *----------------------------------------------------------------------------
+ * The following structure represents a user-defined encoding. It collects
+ * together all the functions that are used by the specific encoding.
+ */
+
+typedef struct Tcl_EncodingType {
+    const char *encodingName;	/* The name of the encoding, e.g. "euc-jp".
+				 * This name is the unique key for this
+				 * encoding type. */
+    Tcl_EncodingConvertProc *toUtfProc;
+				/* Function to convert from external encoding
+				 * into UTF-8. */
+    Tcl_EncodingConvertProc *fromUtfProc;
+				/* Function to convert from UTF-8 into
+				 * external encoding. */
+    Tcl_EncodingFreeProc *freeProc;
+				/* If non-NULL, function to call when this
+				 * encoding is deleted. */
+    ClientData clientData;	/* Arbitrary value associated with encoding
+				 * type. Passed to conversion functions. */
+    int nullSize;		/* Number of zero bytes that signify
+				 * end-of-string in this encoding. This number
+				 * is used to determine the source string
+				 * length when the srcLen argument is
+				 * negative. Must be 1 or 2. */
+} Tcl_EncodingType;
+
+/*
+ * The following definitions are used as values for the conversion control
+ * flags argument when converting text from one character set to another:
+ *
+ * TCL_ENCODING_START -		Signifies that the source buffer is the first
+ *				block in a (potentially multi-block) input
+ *				stream. Tells the conversion function to reset
+ *				to an initial state and perform any
+ *				initialization that needs to occur before the
+ *				first byte is converted. If the source buffer
+ *				contains the entire input stream to be
+ *				converted, this flag should be set.
+ * TCL_ENCODING_END -		Signifies that the source buffer is the last
+ *				block in a (potentially multi-block) input
+ *				stream. Tells the conversion routine to
+ *				perform any finalization that needs to occur
+ *				after the last byte is converted and then to
+ *				reset to an initial state. If the source
+ *				buffer contains the entire input stream to be
+ *				converted, this flag should be set.
+ * TCL_ENCODING_STOPONERROR -	If set, then the converter will return
+ *				immediately upon encountering an invalid byte
+ *				sequence or a source character that has no
+ *				mapping in the target encoding. If clear, then
+ *				the converter will skip the problem,
+ *				substituting one or more "close" characters in
+ *				the destination buffer and then continue to
+ *				convert the source.
+ * TCL_ENCODING_NO_TERMINATE - 	If set, Tcl_ExternalToUtf will not append a
+ *				terminating NUL byte.  Knowing that it will
+ *				not need space to do so, it will fill all
+ *				dstLen bytes with encoded UTF-8 content, as
+ *				other circumstances permit.  If clear, the
+ *				default behavior is to reserve a byte in
+ *				the dst space for NUL termination, and to
+ *				append the NUL byte.
+ * TCL_ENCODING_CHAR_LIMIT -	If set and dstCharsPtr is not NULL, then
+ *				Tcl_ExternalToUtf takes the initial value
+ *				of *dstCharsPtr is taken as a limit of the
+ *				maximum number of chars to produce in the
+ *				encoded UTF-8 content.  Otherwise, the
+ *				number of chars produced is controlled only
+ *				by other limiting factors.
+ */
+
+#define TCL_ENCODING_START		0x01
+#define TCL_ENCODING_END		0x02
+#define TCL_ENCODING_STOPONERROR	0x04
+#define TCL_ENCODING_NO_TERMINATE	0x08
+#define TCL_ENCODING_CHAR_LIMIT		0x10
+
+/*
+ * The following definitions are the error codes returned by the conversion
+ * routines:
+ *
+ * TCL_OK -			All characters were converted.
+ * TCL_CONVERT_NOSPACE -	The output buffer would not have been large
+ *				enough for all of the converted data; as many
+ *				characters as could fit were converted though.
+ * TCL_CONVERT_MULTIBYTE -	The last few bytes in the source string were
+ *				the beginning of a multibyte sequence, but
+ *				more bytes were needed to complete this
+ *				sequence. A subsequent call to the conversion
+ *				routine should pass the beginning of this
+ *				unconverted sequence plus additional bytes
+ *				from the source stream to properly convert the
+ *				formerly split-up multibyte sequence.
+ * TCL_CONVERT_SYNTAX -		The source stream contained an invalid
+ *				character sequence. This may occur if the
+ *				input stream has been damaged or if the input
+ *				encoding method was misidentified. This error
+ *				is reported only if TCL_ENCODING_STOPONERROR
+ *				was specified.
+ * TCL_CONVERT_UNKNOWN -	The source string contained a character that
+ *				could not be represented in the target
+ *				encoding. This error is reported only if
+ *				TCL_ENCODING_STOPONERROR was specified.
+ */
+
+#define TCL_CONVERT_MULTIBYTE	(-1)
+#define TCL_CONVERT_SYNTAX	(-2)
+#define TCL_CONVERT_UNKNOWN	(-3)
+#define TCL_CONVERT_NOSPACE	(-4)
+
+/*
+ * The maximum number of bytes that are necessary to represent a single
+ * Unicode character in UTF-8. The valid values should be 3, 4 or 6
+ * (or perhaps 1 if we want to support a non-unicode enabled core). If 3 or
+ * 4, then Tcl_UniChar must be 2-bytes in size (UCS-2) (the default). If 6,
+ * then Tcl_UniChar must be 4-bytes in size (UCS-4). At this time UCS-2 mode
+ * is the default and recommended mode. UCS-4 is experimental and not
+ * recommended. It works for the core, but most extensions expect UCS-2.
+ */
+
+#ifndef TCL_UTF_MAX
+#define TCL_UTF_MAX		3
+#endif
+
+/*
+ * This represents a Unicode character. Any changes to this should also be
+ * reflected in regcustom.h.
+ */
+
+#if TCL_UTF_MAX > 4
+    /*
+     * unsigned int isn't 100% accurate as it should be a strict 4-byte value
+     * (perhaps wchar_t). 64-bit systems may have troubles. The size of this
+     * value must be reflected correctly in regcustom.h and
+     * in tclEncoding.c.
+     * XXX: Tcl is currently UCS-2 and planning UTF-16 for the Unicode
+     * XXX: string rep that Tcl_UniChar represents.  Changing the size
+     * XXX: of Tcl_UniChar is /not/ supported.
+     */
+typedef unsigned int Tcl_UniChar;
+#else
+typedef unsigned short Tcl_UniChar;
+#endif
+
+/*
+ *----------------------------------------------------------------------------
+ * TIP #59: The following structure is used in calls 'Tcl_RegisterConfig' to
+ * provide the system with the embedded configuration data.
+ */
+
+typedef struct Tcl_Config {
+    const char *key;		/* Configuration key to register. ASCII
+				 * encoded, thus UTF-8. */
+    const char *value;		/* The value associated with the key. System
+				 * encoding. */
+} Tcl_Config;
+
+/*
+ *----------------------------------------------------------------------------
+ * Flags for TIP#143 limits, detailing which limits are active in an
+ * interpreter. Used for Tcl_{Add,Remove}LimitHandler type argument.
+ */
+
+#define TCL_LIMIT_COMMANDS	0x01
+#define TCL_LIMIT_TIME		0x02
+
+/*
+ * Structure containing information about a limit handler to be called when a
+ * command- or time-limit is exceeded by an interpreter.
+ */
+
+typedef void (Tcl_LimitHandlerProc) (ClientData clientData, Tcl_Interp *interp);
+typedef void (Tcl_LimitHandlerDeleteProc) (ClientData clientData);
+
+/*
+ *----------------------------------------------------------------------------
+ * Override definitions for libtommath.
+ */
+
+typedef struct mp_int mp_int;
+#define MP_INT_DECLARED
+typedef unsigned int mp_digit;
+#define MP_DIGIT_DECLARED
+
+/*
+ *----------------------------------------------------------------------------
+ * Definitions needed for Tcl_ParseArgvObj routines.
+ * Based on tkArgv.c.
+ * Modifications from the original are copyright (c) Sam Bromley 2006
+ */
+
+typedef struct {
+    int type;			/* Indicates the option type; see below. */
+    const char *keyStr;		/* The key string that flags the option in the
+				 * argv array. */
+    void *srcPtr;		/* Value to be used in setting dst; usage
+				 * depends on type.*/
+    void *dstPtr;		/* Address of value to be modified; usage
+				 * depends on type.*/
+    const char *helpStr;	/* Documentation message describing this
+				 * option. */
+    ClientData clientData;	/* Word to pass to function callbacks. */
+} Tcl_ArgvInfo;
+
+/*
+ * Legal values for the type field of a Tcl_ArgInfo: see the user
+ * documentation for details.
+ */
+
+#define TCL_ARGV_CONSTANT	15
+#define TCL_ARGV_INT		16
+#define TCL_ARGV_STRING		17
+#define TCL_ARGV_REST		18
+#define TCL_ARGV_FLOAT		19
+#define TCL_ARGV_FUNC		20
+#define TCL_ARGV_GENFUNC	21
+#define TCL_ARGV_HELP		22
+#define TCL_ARGV_END		23
+
+/*
+ * Types of callback functions for the TCL_ARGV_FUNC and TCL_ARGV_GENFUNC
+ * argument types:
+ */
+
+typedef int (Tcl_ArgvFuncProc)(ClientData clientData, Tcl_Obj *objPtr,
+	void *dstPtr);
+typedef int (Tcl_ArgvGenFuncProc)(ClientData clientData, Tcl_Interp *interp,
+	int objc, Tcl_Obj *const *objv, void *dstPtr);
+
+/*
+ * Shorthand for commonly used argTable entries.
+ */
+
+#define TCL_ARGV_AUTO_HELP \
+    {TCL_ARGV_HELP,	"-help",	NULL,	NULL, \
+	    "Print summary of command-line options and abort", NULL}
+#define TCL_ARGV_AUTO_REST \
+    {TCL_ARGV_REST,	"--",		NULL,	NULL, \
+	    "Marks the end of the options", NULL}
+#define TCL_ARGV_TABLE_END \
+    {TCL_ARGV_END, NULL, NULL, NULL, NULL, NULL}
+
+/*
+ *----------------------------------------------------------------------------
+ * Definitions needed for Tcl_Zlib routines. [TIP #234]
+ *
+ * Constants for the format flags describing what sort of data format is
+ * desired/expected for the Tcl_ZlibDeflate, Tcl_ZlibInflate and
+ * Tcl_ZlibStreamInit functions.
+ */
+
+#define TCL_ZLIB_FORMAT_RAW	1
+#define TCL_ZLIB_FORMAT_ZLIB	2
+#define TCL_ZLIB_FORMAT_GZIP	4
+#define TCL_ZLIB_FORMAT_AUTO	8
+
+/*
+ * Constants that describe whether the stream is to operate in compressing or
+ * decompressing mode.
+ */
+
+#define TCL_ZLIB_STREAM_DEFLATE	16
+#define TCL_ZLIB_STREAM_INFLATE	32
+
+/*
+ * Constants giving compression levels. Use of TCL_ZLIB_COMPRESS_DEFAULT is
+ * recommended.
+ */
+
+#define TCL_ZLIB_COMPRESS_NONE	0
+#define TCL_ZLIB_COMPRESS_FAST	1
+#define TCL_ZLIB_COMPRESS_BEST	9
+#define TCL_ZLIB_COMPRESS_DEFAULT (-1)
+
+/*
+ * Constants for types of flushing, used with Tcl_ZlibFlush.
+ */
+
+#define TCL_ZLIB_NO_FLUSH	0
+#define TCL_ZLIB_FLUSH		2
+#define TCL_ZLIB_FULLFLUSH	3
+#define TCL_ZLIB_FINALIZE	4
+
+/*
+ *----------------------------------------------------------------------------
+ * Definitions needed for the Tcl_LoadFile function. [TIP #416]
+ */
+
+#define TCL_LOAD_GLOBAL 1
+#define TCL_LOAD_LAZY 2
+
+/*
+ *----------------------------------------------------------------------------
+ * Single public declaration for NRE.
+ */
+
+typedef int (Tcl_NRPostProc) (ClientData data[], Tcl_Interp *interp,
+				int result);
+
+/*
+ *----------------------------------------------------------------------------
+ * The following constant is used to test for older versions of Tcl in the
+ * stubs tables.
+ *
+ * Jan Nijtman's plus patch uses 0xFCA1BACF, so we need to pick a different
+ * value since the stubs tables don't match.
+ */
+
+#define TCL_STUB_MAGIC		((int) 0xFCA3BACF)
+
+/*
+ * The following function is required to be defined in all stubs aware
+ * extensions. The function is actually implemented in the stub library, not
+ * the main Tcl library, although there is a trivial implementation in the
+ * main library in case an extension is statically linked into an application.
+ */
+
+const char *		Tcl_InitStubs(Tcl_Interp *interp, const char *version,
+			    int exact);
+const char *		TclTomMathInitializeStubs(Tcl_Interp *interp,
+			    const char *version, int epoch, int revision);
+
+/*
+ * When not using stubs, make it a macro.
+ */
+
+#ifndef USE_TCL_STUBS
+#define Tcl_InitStubs(interp, version, exact) \
+    Tcl_PkgInitStubsCheck(interp, version, exact)
+#endif
+
+/*
+ * TODO - tommath stubs export goes here!
+ */
+
+/*
+ * Public functions that are not accessible via the stubs table.
+ * Tcl_GetMemoryInfo is needed for AOLserver. [Bug 1868171]
+ */
+
+#define Tcl_Main(argc, argv, proc) Tcl_MainEx(argc, argv, proc, \
+	    ((Tcl_CreateInterp)()))
+EXTERN void		Tcl_MainEx(int argc, char **argv,
+			    Tcl_AppInitProc *appInitProc, Tcl_Interp *interp);
+EXTERN const char *	Tcl_PkgInitStubsCheck(Tcl_Interp *interp,
+			    const char *version, int exact);
+EXTERN void		Tcl_GetMemoryInfo(Tcl_DString *dsPtr);
+
+/*
+ *----------------------------------------------------------------------------
+ * Include the public function declarations that are accessible via the stubs
+ * table.
+ */
+
+#include "tclDecls.h"
+
+/*
+ * Include platform specific public function declarations that are accessible
+ * via the stubs table. Make all TclOO symbols MODULE_SCOPE (which only
+ * has effect on building it as a shared library). See ticket [3010352].
+ */
+
+#if defined(BUILD_tcl)
+#   undef TCLAPI
+#   define TCLAPI MODULE_SCOPE
+#endif
+
+#include "tclPlatDecls.h"
+
+/*
+ *----------------------------------------------------------------------------
+ * The following declarations either map ckalloc and ckfree to malloc and
+ * free, or they map them to functions with all sorts of debugging hooks
+ * defined in tclCkalloc.c.
+ */
+
+#ifdef TCL_MEM_DEBUG
+
+#   define ckalloc(x) \
+    ((void *) Tcl_DbCkalloc((unsigned)(x), __FILE__, __LINE__))
+#   define ckfree(x) \
+    Tcl_DbCkfree((char *)(x), __FILE__, __LINE__)
+#   define ckrealloc(x,y) \
+    ((void *) Tcl_DbCkrealloc((char *)(x), (unsigned)(y), __FILE__, __LINE__))
+#   define attemptckalloc(x) \
+    ((void *) Tcl_AttemptDbCkalloc((unsigned)(x), __FILE__, __LINE__))
+#   define attemptckrealloc(x,y) \
+    ((void *) Tcl_AttemptDbCkrealloc((char *)(x), (unsigned)(y), __FILE__, __LINE__))
+
+#else /* !TCL_MEM_DEBUG */
+
+/*
+ * If we are not using the debugging allocator, we should call the Tcl_Alloc,
+ * et al. routines in order to guarantee that every module is using the same
+ * memory allocator both inside and outside of the Tcl library.
+ */
+
+#   define ckalloc(x) \
+    ((void *) Tcl_Alloc((unsigned)(x)))
+#   define ckfree(x) \
+    Tcl_Free((char *)(x))
+#   define ckrealloc(x,y) \
+    ((void *) Tcl_Realloc((char *)(x), (unsigned)(y)))
+#   define attemptckalloc(x) \
+    ((void *) Tcl_AttemptAlloc((unsigned)(x)))
+#   define attemptckrealloc(x,y) \
+    ((void *) Tcl_AttemptRealloc((char *)(x), (unsigned)(y)))
+#   undef  Tcl_InitMemory
+#   define Tcl_InitMemory(x)
+#   undef  Tcl_DumpActiveMemory
+#   define Tcl_DumpActiveMemory(x)
+#   undef  Tcl_ValidateAllMemory
+#   define Tcl_ValidateAllMemory(x,y)
+
+#endif /* !TCL_MEM_DEBUG */
+
+#ifdef TCL_MEM_DEBUG
+#   define Tcl_IncrRefCount(objPtr) \
+	Tcl_DbIncrRefCount(objPtr, __FILE__, __LINE__)
+#   define Tcl_DecrRefCount(objPtr) \
+	Tcl_DbDecrRefCount(objPtr, __FILE__, __LINE__)
+#   define Tcl_IsShared(objPtr) \
+	Tcl_DbIsShared(objPtr, __FILE__, __LINE__)
+#else
+#   define Tcl_IncrRefCount(objPtr) \
+	++(objPtr)->refCount
+    /*
+     * Use do/while0 idiom for optimum correctness without compiler warnings.
+     * http://c2.com/cgi/wiki?TrivialDoWhileLoop
+     */
+#   define Tcl_DecrRefCount(objPtr) \
+	do { \
+	    Tcl_Obj *_objPtr = (objPtr); \
+	    if ((_objPtr)->refCount-- <= 1) { \
+		TclFreeObj(_objPtr); \
+	    } \
+	} while(0)
+#   define Tcl_IsShared(objPtr) \
+	((objPtr)->refCount > 1)
+#endif
+
+/*
+ * Macros and definitions that help to debug the use of Tcl objects. When
+ * TCL_MEM_DEBUG is defined, the Tcl_New declarations are overridden to call
+ * debugging versions of the object creation functions.
+ */
+
+#ifdef TCL_MEM_DEBUG
+#  undef  Tcl_NewBignumObj
+#  define Tcl_NewBignumObj(val) \
+     Tcl_DbNewBignumObj(val, __FILE__, __LINE__)
+#  undef  Tcl_NewBooleanObj
+#  define Tcl_NewBooleanObj(val) \
+     Tcl_DbNewBooleanObj(val, __FILE__, __LINE__)
+#  undef  Tcl_NewByteArrayObj
+#  define Tcl_NewByteArrayObj(bytes, len) \
+     Tcl_DbNewByteArrayObj(bytes, len, __FILE__, __LINE__)
+#  undef  Tcl_NewDoubleObj
+#  define Tcl_NewDoubleObj(val) \
+     Tcl_DbNewDoubleObj(val, __FILE__, __LINE__)
+#  undef  Tcl_NewIntObj
+#  define Tcl_NewIntObj(val) \
+     Tcl_DbNewLongObj(val, __FILE__, __LINE__)
+#  undef  Tcl_NewListObj
+#  define Tcl_NewListObj(objc, objv) \
+     Tcl_DbNewListObj(objc, objv, __FILE__, __LINE__)
+#  undef  Tcl_NewLongObj
+#  define Tcl_NewLongObj(val) \
+     Tcl_DbNewLongObj(val, __FILE__, __LINE__)
+#  undef  Tcl_NewObj
+#  define Tcl_NewObj() \
+     Tcl_DbNewObj(__FILE__, __LINE__)
+#  undef  Tcl_NewStringObj
+#  define Tcl_NewStringObj(bytes, len) \
+     Tcl_DbNewStringObj(bytes, len, __FILE__, __LINE__)
+#  undef  Tcl_NewWideIntObj
+#  define Tcl_NewWideIntObj(val) \
+     Tcl_DbNewWideIntObj(val, __FILE__, __LINE__)
+#endif /* TCL_MEM_DEBUG */
+
+/*
+ *----------------------------------------------------------------------------
+ * Macros for clients to use to access fields of hash entries:
+ */
+
+#define Tcl_GetHashValue(h) ((h)->clientData)
+#define Tcl_SetHashValue(h, value) ((h)->clientData = (ClientData) (value))
+#define Tcl_GetHashKey(tablePtr, h) \
+	((void *) (((tablePtr)->keyType == TCL_ONE_WORD_KEYS || \
+		    (tablePtr)->keyType == TCL_CUSTOM_PTR_KEYS) \
+		   ? (h)->key.oneWordValue \
+		   : (h)->key.string))
+
+/*
+ * Macros to use for clients to use to invoke find and create functions for
+ * hash tables:
+ */
+
+#undef  Tcl_FindHashEntry
+#define Tcl_FindHashEntry(tablePtr, key) \
+	(*((tablePtr)->findProc))(tablePtr, (const char *)(key))
+#undef  Tcl_CreateHashEntry
+#define Tcl_CreateHashEntry(tablePtr, key, newPtr) \
+	(*((tablePtr)->createProc))(tablePtr, (const char *)(key), newPtr)
+
+/*
+ *----------------------------------------------------------------------------
+ * Macros that eliminate the overhead of the thread synchronization functions
+ * when compiling without thread support.
+ */
+
+#ifndef TCL_THREADS
+#undef  Tcl_MutexLock
+#define Tcl_MutexLock(mutexPtr)
+#undef  Tcl_MutexUnlock
+#define Tcl_MutexUnlock(mutexPtr)
+#undef  Tcl_MutexFinalize
+#define Tcl_MutexFinalize(mutexPtr)
+#undef  Tcl_ConditionNotify
+#define Tcl_ConditionNotify(condPtr)
+#undef  Tcl_ConditionWait
+#define Tcl_ConditionWait(condPtr, mutexPtr, timePtr)
+#undef  Tcl_ConditionFinalize
+#define Tcl_ConditionFinalize(condPtr)
+#endif /* TCL_THREADS */
+
+/*
+ *----------------------------------------------------------------------------
+ * Deprecated Tcl functions:
+ */
+
+#ifndef TCL_NO_DEPRECATED
+/*
+ * These function have been renamed. The old names are deprecated, but we
+ * define these macros for backwards compatibilty.
+ */
+
+#   define Tcl_Ckalloc		Tcl_Alloc
+#   define Tcl_Ckfree		Tcl_Free
+#   define Tcl_Ckrealloc	Tcl_Realloc
+#   define Tcl_Return		Tcl_SetResult
+#   define Tcl_TildeSubst	Tcl_TranslateFileName
+#   define panic		Tcl_Panic
+#   define panicVA		Tcl_PanicVA
+#endif /* !TCL_NO_DEPRECATED */
+
+/*
+ *----------------------------------------------------------------------------
+ * Convenience declaration of Tcl_AppInit for backwards compatibility. This
+ * function is not *implemented* by the tcl library, so the storage class is
+ * neither DLLEXPORT nor DLLIMPORT.
+ */
+
+extern Tcl_AppInitProc Tcl_AppInit;
+
+#endif /* RC_INVOKED */
+
+/*
+ * end block for C++
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _TCL */
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tclAlloc.c b/generic/tclAlloc.c
new file mode 100644
index 0000000..cda1f38
--- /dev/null
+++ b/generic/tclAlloc.c
@@ -0,0 +1,759 @@
+/*
+ * tclAlloc.c --
+ *
+ *	This is a very fast storage allocator. It allocates blocks of a small
+ *	number of different sizes, and keeps free lists of each size. Blocks
+ *	that don't exactly fit are passed up to the next larger size. Blocks
+ *	over a certain size are directly allocated from the system.
+ *
+ * Copyright (c) 1983 Regents of the University of California.
+ * Copyright (c) 1996-1997 Sun Microsystems, Inc.
+ * Copyright (c) 1998-1999 by Scriptics Corporation.
+ *
+ * Portions contributed by Chris Kingsley, Jack Jansen and Ray Johnson.
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+/*
+ * Windows and Unix use an alternative allocator when building with threads
+ * that has significantly reduced lock contention.
+ */
+
+#include "tclInt.h"
+#if !defined(TCL_THREADS) || !defined(USE_THREAD_ALLOC)
+
+#if USE_TCLALLOC
+
+/*
+ * We should really make use of AC_CHECK_TYPE(caddr_t) here, but it can wait
+ * until Tcl uses config.h properly.
+ */
+
+#if defined(_MSC_VER) || defined(__MSVCRT__) || defined(__BORLANDC__)
+typedef unsigned long caddr_t;
+#endif
+
+/*
+ * The overhead on a block is at least 8 bytes. When free, this space contains
+ * a pointer to the next free block, and the bottom two bits must be zero.
+ * When in use, the first byte is set to MAGIC, and the second byte is the
+ * size index. The remaining bytes are for alignment. If range checking is
+ * enabled then a second word holds the size of the requested block, less 1,
+ * rounded up to a multiple of sizeof(RMAGIC). The order of elements is
+ * critical: ov.magic must overlay the low order bits of ov.next, and ov.magic
+ * can not be a valid ov.next bit pattern.
+ */
+
+union overhead {
+    union overhead *next;		/* when free */
+    unsigned char padding[TCL_ALLOCALIGN];	/* align struct to TCL_ALLOCALIGN bytes */
+    struct {
+	unsigned char magic0;		/* magic number */
+	unsigned char index;		/* bucket # */
+	unsigned char unused;		/* unused */
+	unsigned char magic1;		/* other magic number */
+#ifndef NDEBUG
+	unsigned short rmagic;		/* range magic number */
+	unsigned long size;		/* actual block size */
+	unsigned short unused2;		/* padding to 8-byte align */
+#endif
+    } ovu;
+#define overMagic0	ovu.magic0
+#define overMagic1	ovu.magic1
+#define bucketIndex	ovu.index
+#define rangeCheckMagic	ovu.rmagic
+#define realBlockSize	ovu.size
+};
+
+
+#define MAGIC		0xef	/* magic # on accounting info */
+#define RMAGIC		0x5555	/* magic # on range info */
+
+#ifndef NDEBUG
+#define	RSLOP		sizeof(unsigned short)
+#else
+#define	RSLOP		0
+#endif
+
+#define OVERHEAD (sizeof(union overhead) + RSLOP)
+
+/*
+ * Macro to make it easier to refer to the end-of-block guard magic.
+ */
+
+#define BLOCK_END(overPtr) \
+    (*(unsigned short *)((caddr_t)((overPtr) + 1) + (overPtr)->realBlockSize))
+
+/*
+ * nextf[i] is the pointer to the next free block of size 2^(i+3). The
+ * smallest allocatable block is MINBLOCK bytes. The overhead information
+ * precedes the data area returned to the user.
+ */
+
+#define MINBLOCK	((sizeof(union overhead) + (TCL_ALLOCALIGN-1)) & ~(TCL_ALLOCALIGN-1))
+#define NBUCKETS	(13 - (MINBLOCK >> 4))
+#define MAXMALLOC	(1<<(NBUCKETS+2))
+static union overhead *nextf[NBUCKETS];
+
+/*
+ * The following structure is used to keep track of all system memory
+ * currently owned by Tcl. When finalizing, all this memory will be returned
+ * to the system.
+ */
+
+struct block {
+    struct block *nextPtr;	/* Linked list. */
+    struct block *prevPtr;	/* Linked list for big blocks, ensures 8-byte
+				 * alignment for suballocated blocks. */
+};
+
+static struct block *blockList;	/* Tracks the suballocated blocks. */
+static struct block bigBlocks={	/* Big blocks aren't suballocated. */
+    &bigBlocks, &bigBlocks
+};
+
+/*
+ * The allocator is protected by a special mutex that must be explicitly
+ * initialized. Futhermore, because Tcl_Alloc may be used before anything else
+ * in Tcl, we make this module self-initializing after all with the allocInit
+ * variable.
+ */
+
+#ifdef TCL_THREADS
+static Tcl_Mutex *allocMutexPtr;
+#endif
+static int allocInit = 0;
+
+#ifdef MSTATS
+
+/*
+ * numMallocs[i] is the difference between the number of mallocs and frees for
+ * a given block size.
+ */
+
+static	unsigned int numMallocs[NBUCKETS+1];
+#endif
+
+#if !defined(NDEBUG)
+#define	ASSERT(p)	if (!(p)) Tcl_Panic(# p)
+#define RANGE_ASSERT(p) if (!(p)) Tcl_Panic(# p)
+#else
+#define	ASSERT(p)
+#define RANGE_ASSERT(p)
+#endif
+
+/*
+ * Prototypes for functions used only in this file.
+ */
+
+static void		MoreCore(int bucket);
+
+/*
+ *-------------------------------------------------------------------------
+ *
+ * TclInitAlloc --
+ *
+ *	Initialize the memory system.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Initialize the mutex used to serialize allocations.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+void
+TclInitAlloc(void)
+{
+    if (!allocInit) {
+	allocInit = 1;
+#ifdef TCL_THREADS
+	allocMutexPtr = Tcl_GetAllocMutex();
+#endif
+    }
+}
+
+/*
+ *-------------------------------------------------------------------------
+ *
+ * TclFinalizeAllocSubsystem --
+ *
+ *	Release all resources being used by this subsystem, including
+ *	aggressively freeing all memory allocated by TclpAlloc() that has not
+ *	yet been released with TclpFree().
+ *
+ *	After this function is called, all memory allocated with TclpAlloc()
+ *	should be considered unusable.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	This subsystem is self-initializing, since memory can be allocated
+ *	before Tcl is formally initialized. After this call, this subsystem
+ *	has been reset to its initial state and is usable again.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+void
+TclFinalizeAllocSubsystem(void)
+{
+    unsigned int i;
+    struct block *blockPtr, *nextPtr;
+
+    Tcl_MutexLock(allocMutexPtr);
+    for (blockPtr = blockList; blockPtr != NULL; blockPtr = nextPtr) {
+	nextPtr = blockPtr->nextPtr;
+	TclpSysFree(blockPtr);
+    }
+    blockList = NULL;
+
+    for (blockPtr = bigBlocks.nextPtr; blockPtr != &bigBlocks; ) {
+	nextPtr = blockPtr->nextPtr;
+	TclpSysFree(blockPtr);
+	blockPtr = nextPtr;
+    }
+    bigBlocks.nextPtr = &bigBlocks;
+    bigBlocks.prevPtr = &bigBlocks;
+
+    for (i=0 ; i<NBUCKETS ; i++) {
+	nextf[i] = NULL;
+#ifdef MSTATS
+	numMallocs[i] = 0;
+#endif
+    }
+#ifdef MSTATS
+    numMallocs[i] = 0;
+#endif
+    Tcl_MutexUnlock(allocMutexPtr);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclpAlloc --
+ *
+ *	Allocate more memory.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+char *
+TclpAlloc(
+    unsigned int numBytes)	/* Number of bytes to allocate. */
+{
+    register union overhead *overPtr;
+    register long bucket;
+    register unsigned amount;
+    struct block *bigBlockPtr = NULL;
+
+    if (!allocInit) {
+	/*
+	 * We have to make the "self initializing" because Tcl_Alloc may be
+	 * used before any other part of Tcl. E.g., see main() for tclsh!
+	 */
+
+	TclInitAlloc();
+    }
+    Tcl_MutexLock(allocMutexPtr);
+
+    /*
+     * First the simple case: we simple allocate big blocks directly.
+     */
+
+    if (numBytes >= MAXMALLOC - OVERHEAD) {
+	if (numBytes <= UINT_MAX - OVERHEAD -sizeof(struct block)) {
+	    bigBlockPtr = (struct block *) TclpSysAlloc((unsigned)
+		    (sizeof(struct block) + OVERHEAD + numBytes), 0);
+	}
+	if (bigBlockPtr == NULL) {
+	    Tcl_MutexUnlock(allocMutexPtr);
+	    return NULL;
+	}
+	bigBlockPtr->nextPtr = bigBlocks.nextPtr;
+	bigBlocks.nextPtr = bigBlockPtr;
+	bigBlockPtr->prevPtr = &bigBlocks;
+	bigBlockPtr->nextPtr->prevPtr = bigBlockPtr;
+
+	overPtr = (union overhead *) (bigBlockPtr + 1);
+	overPtr->overMagic0 = overPtr->overMagic1 = MAGIC;
+	overPtr->bucketIndex = 0xff;
+#ifdef MSTATS
+	numMallocs[NBUCKETS]++;
+#endif
+
+#ifndef NDEBUG
+	/*
+	 * Record allocated size of block and bound space with magic numbers.
+	 */
+
+	overPtr->realBlockSize = (numBytes + RSLOP - 1) & ~(RSLOP - 1);
+	overPtr->rangeCheckMagic = RMAGIC;
+	BLOCK_END(overPtr) = RMAGIC;
+#endif
+
+	Tcl_MutexUnlock(allocMutexPtr);
+	return (void *)(overPtr+1);
+    }
+
+    /*
+     * Convert amount of memory requested into closest block size stored in
+     * hash buckets which satisfies request. Account for space used per block
+     * for accounting.
+     */
+
+    amount = MINBLOCK;		/* size of first bucket */
+    bucket = MINBLOCK >> 4;
+
+    while (numBytes + OVERHEAD > amount) {
+	amount <<= 1;
+	if (amount == 0) {
+	    Tcl_MutexUnlock(allocMutexPtr);
+	    return NULL;
+	}
+	bucket++;
+    }
+    ASSERT(bucket < NBUCKETS);
+
+    /*
+     * If nothing in hash bucket right now, request more memory from the
+     * system.
+     */
+
+    if ((overPtr = nextf[bucket]) == NULL) {
+	MoreCore(bucket);
+	if ((overPtr = nextf[bucket]) == NULL) {
+	    Tcl_MutexUnlock(allocMutexPtr);
+	    return NULL;
+	}
+    }
+
+    /*
+     * Remove from linked list
+     */
+
+    nextf[bucket] = overPtr->next;
+    overPtr->overMagic0 = overPtr->overMagic1 = MAGIC;
+    overPtr->bucketIndex = (unsigned char) bucket;
+
+#ifdef MSTATS
+    numMallocs[bucket]++;
+#endif
+
+#ifndef NDEBUG
+    /*
+     * Record allocated size of block and bound space with magic numbers.
+     */
+
+    overPtr->realBlockSize = (numBytes + RSLOP - 1) & ~(RSLOP - 1);
+    overPtr->rangeCheckMagic = RMAGIC;
+    BLOCK_END(overPtr) = RMAGIC;
+#endif
+
+    Tcl_MutexUnlock(allocMutexPtr);
+    return ((char *)(overPtr + 1));
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * MoreCore --
+ *
+ *	Allocate more memory to the indicated bucket.
+ *
+ *	Assumes Mutex is already held.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Attempts to get more memory from the system.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+MoreCore(
+    int bucket)			/* What bucket to allocat to. */
+{
+    register union overhead *overPtr;
+    register long size;		/* size of desired block */
+    long amount;		/* amount to allocate */
+    int numBlocks;		/* how many blocks we get */
+    struct block *blockPtr;
+
+    /*
+     * sbrk_size <= 0 only for big, FLUFFY, requests (about 2^30 bytes on a
+     * VAX, I think) or for a negative arg.
+     */
+
+    size = 1 << (bucket + 3);
+    ASSERT(size > 0);
+
+    amount = MAXMALLOC;
+    numBlocks = amount / size;
+    ASSERT(numBlocks*size == amount);
+
+    blockPtr = (struct block *) TclpSysAlloc((unsigned)
+	    (sizeof(struct block) + amount), 1);
+    /* no more room! */
+    if (blockPtr == NULL) {
+	return;
+    }
+    blockPtr->nextPtr = blockList;
+    blockList = blockPtr;
+
+    overPtr = (union overhead *) (blockPtr + 1);
+
+    /*
+     * Add new memory allocated to that on free list for this hash bucket.
+     */
+
+    nextf[bucket] = overPtr;
+    while (--numBlocks > 0) {
+	overPtr->next = (union overhead *)((caddr_t)overPtr + size);
+	overPtr = (union overhead *)((caddr_t)overPtr + size);
+    }
+    overPtr->next = NULL;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclpFree --
+ *
+ *	Free memory.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclpFree(
+    char *oldPtr)		/* Pointer to memory to free. */
+{
+    register long size;
+    register union overhead *overPtr;
+    struct block *bigBlockPtr;
+
+    if (oldPtr == NULL) {
+	return;
+    }
+
+    Tcl_MutexLock(allocMutexPtr);
+    overPtr = (union overhead *)((caddr_t)oldPtr - sizeof(union overhead));
+
+    ASSERT(overPtr->overMagic0 == MAGIC);	/* make sure it was in use */
+    ASSERT(overPtr->overMagic1 == MAGIC);
+    if (overPtr->overMagic0 != MAGIC || overPtr->overMagic1 != MAGIC) {
+	Tcl_MutexUnlock(allocMutexPtr);
+	return;
+    }
+
+    RANGE_ASSERT(overPtr->rangeCheckMagic == RMAGIC);
+    RANGE_ASSERT(BLOCK_END(overPtr) == RMAGIC);
+    size = overPtr->bucketIndex;
+    if (size == 0xff) {
+#ifdef MSTATS
+	numMallocs[NBUCKETS]--;
+#endif
+
+	bigBlockPtr = (struct block *) overPtr - 1;
+	bigBlockPtr->prevPtr->nextPtr = bigBlockPtr->nextPtr;
+	bigBlockPtr->nextPtr->prevPtr = bigBlockPtr->prevPtr;
+	TclpSysFree(bigBlockPtr);
+
+	Tcl_MutexUnlock(allocMutexPtr);
+	return;
+    }
+    ASSERT(size < NBUCKETS);
+    overPtr->next = nextf[size];	/* also clobbers overMagic */
+    nextf[size] = overPtr;
+
+#ifdef MSTATS
+    numMallocs[size]--;
+#endif
+
+    Tcl_MutexUnlock(allocMutexPtr);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclpRealloc --
+ *
+ *	Reallocate memory.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+char *
+TclpRealloc(
+    char *oldPtr,		/* Pointer to alloced block. */
+    unsigned int numBytes)	/* New size of memory. */
+{
+    int i;
+    union overhead *overPtr;
+    struct block *bigBlockPtr;
+    int expensive;
+    unsigned long maxSize;
+
+    if (oldPtr == NULL) {
+	return TclpAlloc(numBytes);
+    }
+
+    Tcl_MutexLock(allocMutexPtr);
+
+    overPtr = (union overhead *)((caddr_t)oldPtr - sizeof(union overhead));
+
+    ASSERT(overPtr->overMagic0 == MAGIC);	/* make sure it was in use */
+    ASSERT(overPtr->overMagic1 == MAGIC);
+    if (overPtr->overMagic0 != MAGIC || overPtr->overMagic1 != MAGIC) {
+	Tcl_MutexUnlock(allocMutexPtr);
+	return NULL;
+    }
+
+    RANGE_ASSERT(overPtr->rangeCheckMagic == RMAGIC);
+    RANGE_ASSERT(BLOCK_END(overPtr) == RMAGIC);
+    i = overPtr->bucketIndex;
+
+    /*
+     * If the block isn't in a bin, just realloc it.
+     */
+
+    if (i == 0xff) {
+	struct block *prevPtr, *nextPtr;
+	bigBlockPtr = (struct block *) overPtr - 1;
+	prevPtr = bigBlockPtr->prevPtr;
+	nextPtr = bigBlockPtr->nextPtr;
+	bigBlockPtr = (struct block *) TclpSysRealloc(bigBlockPtr,
+		sizeof(struct block) + OVERHEAD + numBytes);
+	if (bigBlockPtr == NULL) {
+	    Tcl_MutexUnlock(allocMutexPtr);
+	    return NULL;
+	}
+
+	if (prevPtr->nextPtr != bigBlockPtr) {
+	    /*
+	     * If the block has moved, splice the new block into the list
+	     * where the old block used to be.
+	     */
+
+	    prevPtr->nextPtr = bigBlockPtr;
+	    nextPtr->prevPtr = bigBlockPtr;
+	}
+
+	overPtr = (union overhead *) (bigBlockPtr + 1);
+
+#ifdef MSTATS
+	numMallocs[NBUCKETS]++;
+#endif
+
+#ifndef NDEBUG
+	/*
+	 * Record allocated size of block and update magic number bounds.
+	 */
+
+	overPtr->realBlockSize = (numBytes + RSLOP - 1) & ~(RSLOP - 1);
+	BLOCK_END(overPtr) = RMAGIC;
+#endif
+
+	Tcl_MutexUnlock(allocMutexPtr);
+	return (char *)(overPtr+1);
+    }
+    maxSize = 1 << (i+3);
+    expensive = 0;
+    if (numBytes+OVERHEAD > maxSize) {
+	expensive = 1;
+    } else if (i>0 && numBytes+OVERHEAD < maxSize/2) {
+	expensive = 1;
+    }
+
+    if (expensive) {
+	void *newPtr;
+
+	Tcl_MutexUnlock(allocMutexPtr);
+
+	newPtr = TclpAlloc(numBytes);
+	if (newPtr == NULL) {
+	    return NULL;
+	}
+	maxSize -= OVERHEAD;
+	if (maxSize < numBytes) {
+	    numBytes = maxSize;
+	}
+	memcpy(newPtr, oldPtr, (size_t) numBytes);
+	TclpFree(oldPtr);
+	return newPtr;
+    }
+
+    /*
+     * Ok, we don't have to copy, it fits as-is
+     */
+
+#ifndef NDEBUG
+    overPtr->realBlockSize = (numBytes + RSLOP - 1) & ~(RSLOP - 1);
+    BLOCK_END(overPtr) = RMAGIC;
+#endif
+
+    Tcl_MutexUnlock(allocMutexPtr);
+    return(oldPtr);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * mstats --
+ *
+ *	Prints two lines of numbers, one showing the length of the free list
+ *	for each size category, the second showing the number of mallocs -
+ *	frees for each size category.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+#ifdef MSTATS
+void
+mstats(
+    char *s)			/* Where to write info. */
+{
+    register int i, j;
+    register union overhead *overPtr;
+    int totalFree = 0, totalUsed = 0;
+
+    Tcl_MutexLock(allocMutexPtr);
+
+    fprintf(stderr, "Memory allocation statistics %s\nTclpFree:\t", s);
+    for (i = 0; i < NBUCKETS; i++) {
+	for (j=0, overPtr=nextf[i]; overPtr; overPtr=overPtr->next, j++) {
+	    fprintf(stderr, " %d", j);
+	}
+	totalFree += j * (1 << (i + 3));
+    }
+
+    fprintf(stderr, "\nused:\t");
+    for (i = 0; i < NBUCKETS; i++) {
+	fprintf(stderr, " %d", numMallocs[i]);
+	totalUsed += numMallocs[i] * (1 << (i + 3));
+    }
+
+    fprintf(stderr, "\n\tTotal small in use: %d, total free: %d\n",
+	    totalUsed, totalFree);
+    fprintf(stderr, "\n\tNumber of big (>%d) blocks in use: %d\n",
+	    MAXMALLOC, numMallocs[NBUCKETS]);
+
+    Tcl_MutexUnlock(allocMutexPtr);
+}
+#endif
+
+#else	/* !USE_TCLALLOC */
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclpAlloc --
+ *
+ *	Allocate more memory.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+char *
+TclpAlloc(
+    unsigned int numBytes)	/* Number of bytes to allocate. */
+{
+    return (char *) malloc(numBytes);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclpFree --
+ *
+ *	Free memory.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclpFree(
+    char *oldPtr)		/* Pointer to memory to free. */
+{
+    free(oldPtr);
+    return;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclpRealloc --
+ *
+ *	Reallocate memory.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+char *
+TclpRealloc(
+    char *oldPtr,		/* Pointer to alloced block. */
+    unsigned int numBytes)	/* New size of memory. */
+{
+    return (char *) realloc(oldPtr, numBytes);
+}
+
+#endif /* !USE_TCLALLOC */
+#endif /* !TCL_THREADS */
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tclAssembly.c b/generic/tclAssembly.c
new file mode 100644
index 0000000..f56da8f
--- /dev/null
+++ b/generic/tclAssembly.c
@@ -0,0 +1,4331 @@
+/*
+ * tclAssembly.c --
+ *
+ *	Assembler for Tcl bytecodes.
+ *
+ * This file contains the procedures that convert Tcl Assembly Language (TAL)
+ * to a sequence of bytecode instructions for the Tcl execution engine.
+ *
+ * Copyright (c) 2010 by Ozgur Dogan Ugurlu.
+ * Copyright (c) 2010 by Kevin B. Kenny.
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+/*-
+ *- THINGS TO DO:
+ *- More instructions:
+ *-   done - alternate exit point (affects stack and exception range checking)
+ *-   break and continue - if exception ranges can be sorted out.
+ *-   foreach_start4, foreach_step4
+ *-   returnImm, returnStk
+ *-   expandStart, expandStkTop, invokeExpanded, expandDrop
+ *-   dictFirst, dictNext, dictDone
+ *-   dictUpdateStart, dictUpdateEnd
+ *-   jumpTable testing
+ *-   syntax (?)
+ *-   returnCodeBranch
+ *-   tclooNext, tclooNextClass
+ */
+
+#include "tclInt.h"
+#include "tclCompile.h"
+#include "tclOOInt.h"
+
+/*
+ * Structure that represents a range of instructions in the bytecode.
+ */
+
+typedef struct CodeRange {
+    int startOffset;		/* Start offset in the bytecode array */
+    int endOffset;		/* End offset in the bytecode array */
+} CodeRange;
+
+/*
+ * State identified for a basic block's catch context.
+ */
+
+typedef enum BasicBlockCatchState {
+    BBCS_UNKNOWN = 0,		/* Catch context has not yet been identified */
+    BBCS_NONE,			/* Block is outside of any catch */
+    BBCS_INCATCH,		/* Block is within a catch context */
+    BBCS_CAUGHT 		/* Block is within a catch context and
+				 * may be executed after an exception fires */
+} BasicBlockCatchState;
+
+/*
+ * Structure that defines a basic block - a linear sequence of bytecode
+ * instructions with no jumps in or out (including not changing the
+ * state of any exception range).
+ */
+
+typedef struct BasicBlock {
+    int originalStartOffset;	/* Instruction offset before JUMP1s were
+				 * substituted with JUMP4's */
+    int startOffset;		/* Instruction offset of the start of the
+				 * block */
+    int startLine;		/* Line number in the input script of the
+				 * instruction at the start of the block */
+    int jumpOffset;		/* Bytecode offset of the 'jump' instruction
+				 * that ends the block, or -1 if there is no
+				 * jump. */
+    int jumpLine;		/* Line number in the input script of the
+				 * 'jump' instruction that ends the block, or
+				 * -1 if there is no jump */
+    struct BasicBlock* prevPtr;	/* Immediate predecessor of this block */
+    struct BasicBlock* predecessor;
+				/* Predecessor of this block in the spanning
+				 * tree */
+    struct BasicBlock* successor1;
+				/* BasicBlock structure of the following
+				 * block: NULL at the end of the bytecode
+				 * sequence. */
+    Tcl_Obj* jumpTarget;	/* Jump target label if the jump target is
+				 * unresolved */
+    int initialStackDepth;	/* Absolute stack depth on entry */
+    int minStackDepth;		/* Low-water relative stack depth */
+    int maxStackDepth;		/* High-water relative stack depth */
+    int finalStackDepth;	/* Relative stack depth on exit */
+    enum BasicBlockCatchState catchState;
+				/* State of the block for 'catch' analysis */
+    int catchDepth;		/* Number of nested catches in which the basic
+				 * block appears */
+    struct BasicBlock* enclosingCatch;
+				/* BasicBlock structure of the last startCatch
+				 * executed on a path to this block, or NULL
+				 * if there is no enclosing catch */
+    int foreignExceptionBase;	/* Base index of foreign exceptions */
+    int foreignExceptionCount;	/* Count of foreign exceptions */
+    ExceptionRange* foreignExceptions;
+				/* ExceptionRange structures for exception
+				 * ranges belonging to embedded scripts and
+				 * expressions in this block */
+    JumptableInfo* jtPtr;	/* Jump table at the end of this basic block */
+    int flags;			/* Boolean flags */
+} BasicBlock;
+
+/*
+ * Flags that pertain to a basic block.
+ */
+
+enum BasicBlockFlags {
+    BB_VISITED = (1 << 0),	/* Block has been visited in the current
+				 * traversal */
+    BB_FALLTHRU = (1 << 1),	/* Control may pass from this block to a
+				 * successor */
+    BB_JUMP1 = (1 << 2),	/* Basic block ends with a 1-byte-offset jump
+				 * and may need expansion */
+    BB_JUMPTABLE = (1 << 3),	/* Basic block ends with a jump table */
+    BB_BEGINCATCH = (1 << 4),	/* Block ends with a 'beginCatch' instruction,
+				 * marking it as the start of a 'catch'
+				 * sequence. The 'jumpTarget' is the exception
+				 * exit from the catch block. */
+    BB_ENDCATCH = (1 << 5)	/* Block ends with an 'endCatch' instruction,
+				 * unwinding the catch from the exception
+				 * stack. */
+};
+
+/*
+ * Source instruction type recognized by the assembler.
+ */
+
+typedef enum TalInstType {
+    ASSEM_1BYTE,		/* Fixed arity, 1-byte instruction */
+    ASSEM_BEGIN_CATCH,		/* Begin catch: one 4-byte jump offset to be
+				 * converted to appropriate exception
+				 * ranges */
+    ASSEM_BOOL,			/* One Boolean operand */
+    ASSEM_BOOL_LVT4,		/* One Boolean, one 4-byte LVT ref. */
+    ASSEM_CONCAT1,		/* 1-byte unsigned-integer operand count, must
+				 * be strictly positive, consumes N, produces
+				 * 1 */
+    ASSEM_DICT_GET,		/* 'dict get' and related - consumes N+1
+				 * operands, produces 1, N > 0 */
+    ASSEM_DICT_SET,		/* specifies key count and LVT index, consumes
+				 * N+1 operands, produces 1, N > 0 */
+    ASSEM_DICT_UNSET,		/* specifies key count and LVT index, consumes
+				 * N operands, produces 1, N > 0 */
+    ASSEM_END_CATCH,		/* End catch. No args. Exception range popped
+				 * from stack and stack pointer restored. */
+    ASSEM_EVAL,			/* 'eval' - evaluate a constant script (by
+				 * compiling it in line with the assembly
+				 * code! I love Tcl!) */
+    ASSEM_INDEX,		/* 4 byte operand, integer or end-integer */
+    ASSEM_INVOKE,		/* 1- or 4-byte operand count, must be
+				 * strictly positive, consumes N, produces
+				 * 1. */
+    ASSEM_JUMP,			/* Jump instructions */
+    ASSEM_JUMP4,		/* Jump instructions forcing a 4-byte offset */
+    ASSEM_JUMPTABLE,		/* Jumptable (switch -exact) */
+    ASSEM_LABEL,		/* The assembly directive that defines a
+				 * label */
+    ASSEM_LINDEX_MULTI,		/* 4-byte operand count, must be strictly
+				 * positive, consumes N, produces 1 */
+    ASSEM_LIST,			/* 4-byte operand count, must be nonnegative,
+				 * consumses N, produces 1 */
+    ASSEM_LSET_FLAT,		/* 4-byte operand count, must be >= 3,
+				 * consumes N, produces 1 */
+    ASSEM_LVT,			/* One operand that references a local
+				 * variable */
+    ASSEM_LVT1,			/* One 1-byte operand that references a local
+				 * variable */
+    ASSEM_LVT1_SINT1,		/* One 1-byte operand that references a local
+				 * variable, one signed-integer 1-byte
+				 * operand */
+    ASSEM_LVT4,			/* One 4-byte operand that references a local
+				 * variable */
+    ASSEM_OVER,			/* OVER: 4-byte operand count, consumes N+1,
+				 * produces N+2 */
+    ASSEM_PUSH,			/* one literal operand */
+    ASSEM_REGEXP,		/* One Boolean operand, but weird mapping to
+				 * call flags */
+    ASSEM_REVERSE,		/* REVERSE: 4-byte operand count, consumes N,
+				 * produces N */
+    ASSEM_SINT1,		/* One 1-byte signed-integer operand
+				 * (INCR_STK_IMM) */
+    ASSEM_SINT4_LVT4		/* Signed 4-byte integer operand followed by
+				 * LVT entry.  Fixed arity */
+} TalInstType;
+
+/*
+ * Description of an instruction recognized by the assembler.
+ */
+
+typedef struct TalInstDesc {
+    const char *name;		/* Name of instruction. */
+    TalInstType instType;	/* The type of instruction */
+    int tclInstCode;		/* Instruction code. For instructions having
+				 * 1- and 4-byte variables, tclInstCode is
+				 * ((1byte)<<8) || (4byte) */
+    int operandsConsumed;	/* Number of operands consumed by the
+				 * operation, or INT_MIN if the operation is
+				 * variadic */
+    int operandsProduced;	/* Number of operands produced by the
+				 * operation. If negative, the operation has a
+				 * net stack effect of -1-operandsProduced */
+} TalInstDesc;
+
+/*
+ * Structure that holds the state of the assembler while generating code.
+ */
+
+typedef struct AssemblyEnv {
+    CompileEnv* envPtr;		/* Compilation environment being used for code
+				 * generation */
+    Tcl_Parse* parsePtr;	/* Parse of the current line of source */
+    Tcl_HashTable labelHash;	/* Hash table whose keys are labels and whose
+				 * values are 'label' objects storing the code
+				 * offsets of the labels. */
+    int cmdLine;		/* Current line number within the assembly
+				 * code */
+    int* clNext;		/* Invisible continuation line for
+				 * [info frame] */
+    BasicBlock* head_bb;	/* First basic block in the code */
+    BasicBlock* curr_bb;	/* Current basic block */
+    int maxDepth;		/* Maximum stack depth encountered */
+    int curCatchDepth;		/* Current depth of catches */
+    int maxCatchDepth;		/* Maximum depth of catches encountered */
+    int flags;			/* Compilation flags (TCL_EVAL_DIRECT) */
+} AssemblyEnv;
+
+/*
+ * Static functions defined in this file.
+ */
+
+static void		AddBasicBlockRangeToErrorInfo(AssemblyEnv*,
+			    BasicBlock*);
+static BasicBlock *	AllocBB(AssemblyEnv*);
+static int		AssembleOneLine(AssemblyEnv* envPtr);
+static void		BBAdjustStackDepth(BasicBlock* bbPtr, int consumed,
+			    int produced);
+static void		BBUpdateStackReqs(BasicBlock* bbPtr, int tblIdx,
+			    int count);
+static void		BBEmitInstInt1(AssemblyEnv* assemEnvPtr, int tblIdx,
+			    int opnd, int count);
+static void		BBEmitInstInt4(AssemblyEnv* assemEnvPtr, int tblIdx,
+			    int opnd, int count);
+static void		BBEmitInst1or4(AssemblyEnv* assemEnvPtr, int tblIdx,
+			    int param, int count);
+static void		BBEmitOpcode(AssemblyEnv* assemEnvPtr, int tblIdx,
+			    int count);
+static int		BuildExceptionRanges(AssemblyEnv* assemEnvPtr);
+static int		CalculateJumpRelocations(AssemblyEnv*, int*);
+static int		CheckForUnclosedCatches(AssemblyEnv*);
+static int		CheckForThrowInWrongContext(AssemblyEnv*);
+static int		CheckNonThrowingBlock(AssemblyEnv*, BasicBlock*);
+static int		BytecodeMightThrow(unsigned char);
+static int		CheckJumpTableLabels(AssemblyEnv*, BasicBlock*);
+static int		CheckNamespaceQualifiers(Tcl_Interp*, const char*,
+			    int);
+static int		CheckNonNegative(Tcl_Interp*, int);
+static int		CheckOneByte(Tcl_Interp*, int);
+static int		CheckSignedOneByte(Tcl_Interp*, int);
+static int		CheckStack(AssemblyEnv*);
+static int		CheckStrictlyPositive(Tcl_Interp*, int);
+static ByteCode *	CompileAssembleObj(Tcl_Interp *interp,
+			    Tcl_Obj *objPtr);
+static void		CompileEmbeddedScript(AssemblyEnv*, Tcl_Token*,
+			    const TalInstDesc*);
+static int		DefineLabel(AssemblyEnv* envPtr, const char* label);
+static void		DeleteMirrorJumpTable(JumptableInfo* jtPtr);
+static void		DupAssembleCodeInternalRep(Tcl_Obj* src,
+			    Tcl_Obj* dest);
+static void		FillInJumpOffsets(AssemblyEnv*);
+static int		CreateMirrorJumpTable(AssemblyEnv* assemEnvPtr,
+			    Tcl_Obj* jumpTable);
+static int		FindLocalVar(AssemblyEnv* envPtr,
+			    Tcl_Token** tokenPtrPtr);
+static int		FinishAssembly(AssemblyEnv*);
+static void		FreeAssembleCodeInternalRep(Tcl_Obj *objPtr);
+static void		FreeAssemblyEnv(AssemblyEnv*);
+static int		GetBooleanOperand(AssemblyEnv*, Tcl_Token**, int*);
+static int		GetListIndexOperand(AssemblyEnv*, Tcl_Token**, int*);
+static int		GetIntegerOperand(AssemblyEnv*, Tcl_Token**, int*);
+static int		GetNextOperand(AssemblyEnv*, Tcl_Token**, Tcl_Obj**);
+static void		LookForFreshCatches(BasicBlock*, BasicBlock**);
+static void		MoveCodeForJumps(AssemblyEnv*, int);
+static void		MoveExceptionRangesToBasicBlock(AssemblyEnv*, int,
+			    int);
+static AssemblyEnv*	NewAssemblyEnv(CompileEnv*, int);
+static int		ProcessCatches(AssemblyEnv*);
+static int		ProcessCatchesInBasicBlock(AssemblyEnv*, BasicBlock*,
+			    BasicBlock*, enum BasicBlockCatchState, int);
+static void		ResetVisitedBasicBlocks(AssemblyEnv*);
+static void		ResolveJumpTableTargets(AssemblyEnv*, BasicBlock*);
+static void		ReportUndefinedLabel(AssemblyEnv*, BasicBlock*,
+			    Tcl_Obj*);
+static void		RestoreEmbeddedExceptionRanges(AssemblyEnv*);
+static int		StackCheckBasicBlock(AssemblyEnv*, BasicBlock *,
+			    BasicBlock *, int);
+static BasicBlock*	StartBasicBlock(AssemblyEnv*, int fallthrough,
+			    Tcl_Obj* jumpLabel);
+/* static int		AdvanceIp(const unsigned char *pc); */
+static int		StackCheckBasicBlock(AssemblyEnv*, BasicBlock *,
+			    BasicBlock *, int);
+static int		StackCheckExit(AssemblyEnv*);
+static void		StackFreshCatches(AssemblyEnv*, BasicBlock*, int,
+			    BasicBlock**, int*);
+static void		SyncStackDepth(AssemblyEnv*);
+static int		TclAssembleCode(CompileEnv* envPtr, const char* code,
+			    int codeLen, int flags);
+static void		UnstackExpiredCatches(CompileEnv*, BasicBlock*, int,
+			    BasicBlock**, int*);
+
+/*
+ * Tcl_ObjType that describes bytecode emitted by the assembler.
+ */
+
+static const Tcl_ObjType assembleCodeType = {
+    "assemblecode",
+    FreeAssembleCodeInternalRep, /* freeIntRepProc */
+    DupAssembleCodeInternalRep,	 /* dupIntRepProc */
+    NULL,			 /* updateStringProc */
+    NULL			 /* setFromAnyProc */
+};
+
+/*
+ * Source instructions recognized in the Tcl Assembly Language (TAL)
+ */
+
+static const TalInstDesc TalInstructionTable[] = {
+    /* PUSH must be first, see the code near the end of TclAssembleCode */
+    {"push",		ASSEM_PUSH,	(INST_PUSH1<<8
+					 | INST_PUSH4),		0,	1},
+
+    {"add",		ASSEM_1BYTE,	INST_ADD,		2,	1},
+    {"append",		ASSEM_LVT,	(INST_APPEND_SCALAR1<<8
+					 | INST_APPEND_SCALAR4),1,	1},
+    {"appendArray",	ASSEM_LVT,	(INST_APPEND_ARRAY1<<8
+					 | INST_APPEND_ARRAY4),	2,	1},
+    {"appendArrayStk",	ASSEM_1BYTE,	INST_APPEND_ARRAY_STK,	3,	1},
+    {"appendStk",	ASSEM_1BYTE,	INST_APPEND_STK,	2,	1},
+    {"arrayExistsImm",	ASSEM_LVT4,	INST_ARRAY_EXISTS_IMM,	0,	1},
+    {"arrayExistsStk",	ASSEM_1BYTE,	INST_ARRAY_EXISTS_STK,	1,	1},
+    {"arrayMakeImm",	ASSEM_LVT4,	INST_ARRAY_MAKE_IMM,	0,	0},
+    {"arrayMakeStk",	ASSEM_1BYTE,	INST_ARRAY_MAKE_STK,	1,	0},
+    {"beginCatch",	ASSEM_BEGIN_CATCH,
+					INST_BEGIN_CATCH4,	0,	0},
+    {"bitand",		ASSEM_1BYTE,	INST_BITAND,		2,	1},
+    {"bitnot",		ASSEM_1BYTE,	INST_BITNOT,		1,	1},
+    {"bitor",		ASSEM_1BYTE,	INST_BITOR,		2,	1},
+    {"bitxor",		ASSEM_1BYTE,	INST_BITXOR,		2,	1},
+    {"concat",		ASSEM_CONCAT1,	INST_STR_CONCAT1,	INT_MIN,1},
+    {"concatStk",	ASSEM_LIST,	INST_CONCAT_STK,	INT_MIN,1},
+    {"coroName",	ASSEM_1BYTE,	INST_COROUTINE_NAME,	0,	1},
+    {"currentNamespace",ASSEM_1BYTE,	INST_NS_CURRENT,	0,	1},
+    {"dictAppend",	ASSEM_LVT4,	INST_DICT_APPEND,	2,	1},
+    {"dictExists",	ASSEM_DICT_GET, INST_DICT_EXISTS,	INT_MIN,1},
+    {"dictExpand",	ASSEM_1BYTE,	INST_DICT_EXPAND,	3,	1},
+    {"dictGet",		ASSEM_DICT_GET, INST_DICT_GET,		INT_MIN,1},
+    {"dictIncrImm",	ASSEM_SINT4_LVT4,
+					INST_DICT_INCR_IMM,	1,	1},
+    {"dictLappend",	ASSEM_LVT4,	INST_DICT_LAPPEND,	2,	1},
+    {"dictRecombineStk",ASSEM_1BYTE,	INST_DICT_RECOMBINE_STK,3,	0},
+    {"dictRecombineImm",ASSEM_LVT4,	INST_DICT_RECOMBINE_IMM,2,	0},
+    {"dictSet",		ASSEM_DICT_SET, INST_DICT_SET,		INT_MIN,1},
+    {"dictUnset",	ASSEM_DICT_UNSET,
+					INST_DICT_UNSET,	INT_MIN,1},
+    {"div",		ASSEM_1BYTE,	INST_DIV,		2,	1},
+    {"dup",		ASSEM_1BYTE,	INST_DUP,		1,	2},
+    {"endCatch",	ASSEM_END_CATCH,INST_END_CATCH,		0,	0},
+    {"eq",		ASSEM_1BYTE,	INST_EQ,		2,	1},
+    {"eval",		ASSEM_EVAL,	INST_EVAL_STK,		1,	1},
+    {"evalStk",		ASSEM_1BYTE,	INST_EVAL_STK,		1,	1},
+    {"exist",		ASSEM_LVT4,	INST_EXIST_SCALAR,	0,	1},
+    {"existArray",	ASSEM_LVT4,	INST_EXIST_ARRAY,	1,	1},
+    {"existArrayStk",	ASSEM_1BYTE,	INST_EXIST_ARRAY_STK,	2,	1},
+    {"existStk",	ASSEM_1BYTE,	INST_EXIST_STK,		1,	1},
+    {"expon",		ASSEM_1BYTE,	INST_EXPON,		2,	1},
+    {"expr",		ASSEM_EVAL,	INST_EXPR_STK,		1,	1},
+    {"exprStk",		ASSEM_1BYTE,	INST_EXPR_STK,		1,	1},
+    {"ge",		ASSEM_1BYTE,	INST_GE,		2,	1},
+    {"gt",		ASSEM_1BYTE,	INST_GT,		2,	1},
+    {"incr",		ASSEM_LVT1,	INST_INCR_SCALAR1,	1,	1},
+    {"incrArray",	ASSEM_LVT1,	INST_INCR_ARRAY1,	2,	1},
+    {"incrArrayImm",	ASSEM_LVT1_SINT1,
+					INST_INCR_ARRAY1_IMM,	1,	1},
+    {"incrArrayStk",	ASSEM_1BYTE,	INST_INCR_ARRAY_STK,	3,	1},
+    {"incrArrayStkImm", ASSEM_SINT1,	INST_INCR_ARRAY_STK_IMM,2,	1},
+    {"incrImm",		ASSEM_LVT1_SINT1,
+					INST_INCR_SCALAR1_IMM,	0,	1},
+    {"incrStk",		ASSEM_1BYTE,	INST_INCR_STK,		2,	1},
+    {"incrStkImm",	ASSEM_SINT1,	INST_INCR_STK_IMM,	1,	1},
+    {"infoLevelArgs",	ASSEM_1BYTE,	INST_INFO_LEVEL_ARGS,	1,	1},
+    {"infoLevelNumber",	ASSEM_1BYTE,	INST_INFO_LEVEL_NUM,	0,	1},
+    {"invokeStk",	ASSEM_INVOKE,	(INST_INVOKE_STK1 << 8
+					 | INST_INVOKE_STK4),	INT_MIN,1},
+    {"jump",		ASSEM_JUMP,	INST_JUMP1,		0,	0},
+    {"jump4",		ASSEM_JUMP4,	INST_JUMP4,		0,	0},
+    {"jumpFalse",	ASSEM_JUMP,	INST_JUMP_FALSE1,	1,	0},
+    {"jumpFalse4",	ASSEM_JUMP4,	INST_JUMP_FALSE4,	1,	0},
+    {"jumpTable",	ASSEM_JUMPTABLE,INST_JUMP_TABLE,	1,	0},
+    {"jumpTrue",	ASSEM_JUMP,	INST_JUMP_TRUE1,	1,	0},
+    {"jumpTrue4",	ASSEM_JUMP4,	INST_JUMP_TRUE4,	1,	0},
+    {"label",		ASSEM_LABEL,	0,			0,	0},
+    {"land",		ASSEM_1BYTE,	INST_LAND,		2,	1},
+    {"lappend",		ASSEM_LVT,	(INST_LAPPEND_SCALAR1<<8
+					 | INST_LAPPEND_SCALAR4),
+								1,	1},
+    {"lappendArray",	ASSEM_LVT,	(INST_LAPPEND_ARRAY1<<8
+					 | INST_LAPPEND_ARRAY4),2,	1},
+    {"lappendArrayStk", ASSEM_1BYTE,	INST_LAPPEND_ARRAY_STK,	3,	1},
+    {"lappendList",	ASSEM_LVT4,	INST_LAPPEND_LIST,	1,	1},
+    {"lappendListArray",ASSEM_LVT4,	INST_LAPPEND_LIST_ARRAY,2,	1},
+    {"lappendListArrayStk", ASSEM_1BYTE,INST_LAPPEND_LIST_ARRAY_STK, 3,	1},
+    {"lappendListStk",	ASSEM_1BYTE,	INST_LAPPEND_LIST_STK,	2,	1},
+    {"lappendStk",	ASSEM_1BYTE,	INST_LAPPEND_STK,	2,	1},
+    {"le",		ASSEM_1BYTE,	INST_LE,		2,	1},
+    {"lindexMulti",	ASSEM_LINDEX_MULTI,
+					INST_LIST_INDEX_MULTI,	INT_MIN,1},
+    {"list",		ASSEM_LIST,	INST_LIST,		INT_MIN,1},
+    {"listConcat",	ASSEM_1BYTE,	INST_LIST_CONCAT,	2,	1},
+    {"listIn",		ASSEM_1BYTE,	INST_LIST_IN,		2,	1},
+    {"listIndex",	ASSEM_1BYTE,	INST_LIST_INDEX,	2,	1},
+    {"listIndexImm",	ASSEM_INDEX,	INST_LIST_INDEX_IMM,	1,	1},
+    {"listLength",	ASSEM_1BYTE,	INST_LIST_LENGTH,	1,	1},
+    {"listNotIn",	ASSEM_1BYTE,	INST_LIST_NOT_IN,	2,	1},
+    {"load",		ASSEM_LVT,	(INST_LOAD_SCALAR1 << 8
+					 | INST_LOAD_SCALAR4),	0,	1},
+    {"loadArray",	ASSEM_LVT,	(INST_LOAD_ARRAY1<<8
+					 | INST_LOAD_ARRAY4),	1,	1},
+    {"loadArrayStk",	ASSEM_1BYTE,	INST_LOAD_ARRAY_STK,	2,	1},
+    {"loadStk",		ASSEM_1BYTE,	INST_LOAD_STK,		1,	1},
+    {"lor",		ASSEM_1BYTE,	INST_LOR,		2,	1},
+    {"lsetFlat",	ASSEM_LSET_FLAT,INST_LSET_FLAT,		INT_MIN,1},
+    {"lsetList",	ASSEM_1BYTE,	INST_LSET_LIST,		3,	1},
+    {"lshift",		ASSEM_1BYTE,	INST_LSHIFT,		2,	1},
+    {"lt",		ASSEM_1BYTE,	INST_LT,		2,	1},
+    {"mod",		ASSEM_1BYTE,	INST_MOD,		2,	1},
+    {"mult",		ASSEM_1BYTE,	INST_MULT,		2,	1},
+    {"neq",		ASSEM_1BYTE,	INST_NEQ,		2,	1},
+    {"nop",		ASSEM_1BYTE,	INST_NOP,		0,	0},
+    {"not",		ASSEM_1BYTE,	INST_LNOT,		1,	1},
+    {"nsupvar",		ASSEM_LVT4,	INST_NSUPVAR,		2,	1},
+    {"numericType",	ASSEM_1BYTE,	INST_NUM_TYPE,		1,	1},
+    {"originCmd",	ASSEM_1BYTE,	INST_ORIGIN_COMMAND,	1,	1},
+    {"over",		ASSEM_OVER,	INST_OVER,		INT_MIN,-1-1},
+    {"pop",		ASSEM_1BYTE,	INST_POP,		1,	0},
+    {"pushReturnCode",	ASSEM_1BYTE,	INST_PUSH_RETURN_CODE,	0,	1},
+    {"pushReturnOpts",	ASSEM_1BYTE,	INST_PUSH_RETURN_OPTIONS,
+								0,	1},
+    {"pushResult",	ASSEM_1BYTE,	INST_PUSH_RESULT,	0,	1},
+    {"regexp",		ASSEM_REGEXP,	INST_REGEXP,		2,	1},
+    {"resolveCmd",	ASSEM_1BYTE,	INST_RESOLVE_COMMAND,	1,	1},
+    {"reverse",		ASSEM_REVERSE,	INST_REVERSE,		INT_MIN,-1-0},
+    {"rshift",		ASSEM_1BYTE,	INST_RSHIFT,		2,	1},
+    {"store",		ASSEM_LVT,	(INST_STORE_SCALAR1<<8
+					 | INST_STORE_SCALAR4),	1,	1},
+    {"storeArray",	ASSEM_LVT,	(INST_STORE_ARRAY1<<8
+					 | INST_STORE_ARRAY4),	2,	1},
+    {"storeArrayStk",	ASSEM_1BYTE,	INST_STORE_ARRAY_STK,	3,	1},
+    {"storeStk",	ASSEM_1BYTE,	INST_STORE_STK,		2,	1},
+    {"strcaseLower",	ASSEM_1BYTE,	INST_STR_LOWER,		1,	1},
+    {"strcaseTitle",	ASSEM_1BYTE,	INST_STR_TITLE,		1,	1},
+    {"strcaseUpper",	ASSEM_1BYTE,	INST_STR_UPPER,		1,	1},
+    {"strcmp",		ASSEM_1BYTE,	INST_STR_CMP,		2,	1},
+    {"strcat",		ASSEM_CONCAT1,	INST_STR_CONCAT1,	INT_MIN,1},
+    {"streq",		ASSEM_1BYTE,	INST_STR_EQ,		2,	1},
+    {"strfind",		ASSEM_1BYTE,	INST_STR_FIND,		2,	1},
+    {"strindex",	ASSEM_1BYTE,	INST_STR_INDEX,		2,	1},
+    {"strlen",		ASSEM_1BYTE,	INST_STR_LEN,		1,	1},
+    {"strmap",		ASSEM_1BYTE,	INST_STR_MAP,		3,	1},
+    {"strmatch",	ASSEM_BOOL,	INST_STR_MATCH,		2,	1},
+    {"strneq",		ASSEM_1BYTE,	INST_STR_NEQ,		2,	1},
+    {"strrange",	ASSEM_1BYTE,	INST_STR_RANGE,		3,	1},
+    {"strreplace",	ASSEM_1BYTE,	INST_STR_REPLACE,	4,	1},
+    {"strrfind",	ASSEM_1BYTE,	INST_STR_FIND_LAST,	2,	1},
+    {"strtrim",		ASSEM_1BYTE,	INST_STR_TRIM,		2,	1},
+    {"strtrimLeft",	ASSEM_1BYTE,	INST_STR_TRIM_LEFT,	2,	1},
+    {"strtrimRight",	ASSEM_1BYTE,	INST_STR_TRIM_RIGHT,	2,	1},
+    {"sub",		ASSEM_1BYTE,	INST_SUB,		2,	1},
+    {"tclooClass",	ASSEM_1BYTE,	INST_TCLOO_CLASS,	1,	1},
+    {"tclooIsObject",	ASSEM_1BYTE,	INST_TCLOO_IS_OBJECT,	1,	1},
+    {"tclooNamespace",	ASSEM_1BYTE,	INST_TCLOO_NS,		1,	1},
+    {"tclooSelf",	ASSEM_1BYTE,	INST_TCLOO_SELF,	0,	1},
+    {"tryCvtToBoolean",	ASSEM_1BYTE,	INST_TRY_CVT_TO_BOOLEAN,1,	2},
+    {"tryCvtToNumeric",	ASSEM_1BYTE,	INST_TRY_CVT_TO_NUMERIC,1,	1},
+    {"uminus",		ASSEM_1BYTE,	INST_UMINUS,		1,	1},
+    {"unset",		ASSEM_BOOL_LVT4,INST_UNSET_SCALAR,	0,	0},
+    {"unsetArray",	ASSEM_BOOL_LVT4,INST_UNSET_ARRAY,	1,	0},
+    {"unsetArrayStk",	ASSEM_BOOL,	INST_UNSET_ARRAY_STK,	2,	0},
+    {"unsetStk",	ASSEM_BOOL,	INST_UNSET_STK,		1,	0},
+    {"uplus",		ASSEM_1BYTE,	INST_UPLUS,		1,	1},
+    {"upvar",		ASSEM_LVT4,	INST_UPVAR,		2,	1},
+    {"variable",	ASSEM_LVT4,	INST_VARIABLE,		1,	0},
+    {"verifyDict",	ASSEM_1BYTE,	INST_DICT_VERIFY,	1,	0},
+    {"yield",		ASSEM_1BYTE,	INST_YIELD,		1,	1},
+    {NULL,		0,		0,			0,	0}
+};
+
+/*
+ * List of instructions that cannot throw an exception under any
+ * circumstances.  These instructions are the ones that are permissible after
+ * an exception is caught but before the corresponding exception range is
+ * popped from the stack.
+ * The instructions must be in ascending order by numeric operation code.
+ */
+
+static const unsigned char NonThrowingByteCodes[] = {
+    INST_PUSH1, INST_PUSH4, INST_POP, INST_DUP,			/* 1-4 */
+    INST_JUMP1, INST_JUMP4,					/* 34-35 */
+    INST_END_CATCH, INST_PUSH_RESULT, INST_PUSH_RETURN_CODE,	/* 70-72 */
+    INST_LIST,							/* 79 */
+    INST_OVER,							/* 95 */
+    INST_PUSH_RETURN_OPTIONS,					/* 108 */
+    INST_REVERSE,						/* 126 */
+    INST_NOP,							/* 132 */
+    INST_STR_MAP,						/* 143 */
+    INST_STR_FIND,						/* 144 */
+    INST_COROUTINE_NAME,					/* 149 */
+    INST_NS_CURRENT,						/* 151 */
+    INST_INFO_LEVEL_NUM,					/* 152 */
+    INST_RESOLVE_COMMAND,					/* 154 */
+    INST_STR_TRIM, INST_STR_TRIM_LEFT, INST_STR_TRIM_RIGHT,	/* 166-168 */
+    INST_CONCAT_STK,						/* 169 */
+    INST_STR_UPPER, INST_STR_LOWER, INST_STR_TITLE,		/* 170-172 */
+    INST_NUM_TYPE						/* 180 */
+};
+
+/*
+ * Helper macros.
+ */
+
+#if defined(TCL_DEBUG_ASSEMBLY) && defined(__GNUC__) && __GNUC__ > 2
+#define DEBUG_PRINT(...)	fprintf(stderr, ##__VA_ARGS__);fflush(stderr)
+#elif defined(__GNUC__) && __GNUC__ > 2
+#define DEBUG_PRINT(...)	/* nothing */
+#else
+#define DEBUG_PRINT		/* nothing */
+#endif
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * BBAdjustStackDepth --
+ *
+ *	When an opcode is emitted, adjusts the stack information in the basic
+ *	block to reflect the number of operands produced and consumed.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Updates minimum, maximum and final stack requirements in the basic
+ *	block.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static void
+BBAdjustStackDepth(
+    BasicBlock *bbPtr,		/* Structure describing the basic block */
+    int consumed,		/* Count of operands consumed by the
+				 * operation */
+    int produced)		/* Count of operands produced by the
+				 * operation */
+{
+    int depth = bbPtr->finalStackDepth;
+
+    depth -= consumed;
+    if (depth < bbPtr->minStackDepth) {
+	bbPtr->minStackDepth = depth;
+    }
+    depth += produced;
+    if (depth > bbPtr->maxStackDepth) {
+	bbPtr->maxStackDepth = depth;
+    }
+    bbPtr->finalStackDepth = depth;
+}
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * BBUpdateStackReqs --
+ *
+ *	Updates the stack requirements of a basic block, given the opcode
+ *	being emitted and an operand count.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Updates min, max and final stack requirements in the basic block.
+ *
+ * Notes:
+ *	This function must not be called for instructions such as REVERSE and
+ *	OVER that are variadic but do not consume all their operands. Instead,
+ *	BBAdjustStackDepth should be called directly.
+ *
+ *	count should be provided only for variadic operations. For operations
+ *	with known arity, count should be 0.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static void
+BBUpdateStackReqs(
+    BasicBlock* bbPtr,		/* Structure describing the basic block */
+    int tblIdx,			/* Index in TalInstructionTable of the
+				 * operation being assembled */
+    int count)			/* Count of operands for variadic insts */
+{
+    int consumed = TalInstructionTable[tblIdx].operandsConsumed;
+    int produced = TalInstructionTable[tblIdx].operandsProduced;
+
+    if (consumed == INT_MIN) {
+	/*
+	 * The instruction is variadic; it consumes 'count' operands.
+	 */
+
+	consumed = count;
+    }
+    if (produced < 0) {
+	/*
+	 * The instruction leaves some of its variadic operands on the stack,
+	 * with net stack effect of '-1-produced'
+	 */
+
+	produced = consumed - produced - 1;
+    }
+    BBAdjustStackDepth(bbPtr, consumed, produced);
+}
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * BBEmitOpcode, BBEmitInstInt1, BBEmitInstInt4 --
+ *
+ *	Emit the opcode part of an instruction, or the entirety of an
+ *	instruction with a 1- or 4-byte operand, and adjust stack
+ *	requirements.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Stores instruction and operand in the operand stream, and adjusts the
+ *	stack.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static void
+BBEmitOpcode(
+    AssemblyEnv* assemEnvPtr,	/* Assembly environment */
+    int tblIdx,			/* Table index in TalInstructionTable of op */
+    int count)			/* Operand count for variadic ops */
+{
+    CompileEnv* envPtr = assemEnvPtr->envPtr;
+				/* Compilation environment */
+    BasicBlock* bbPtr = assemEnvPtr->curr_bb;
+				/* Current basic block */
+    int op = TalInstructionTable[tblIdx].tclInstCode & 0xff;
+
+    /*
+     * If this is the first instruction in a basic block, record its line
+     * number.
+     */
+
+    if (bbPtr->startOffset == envPtr->codeNext - envPtr->codeStart) {
+	bbPtr->startLine = assemEnvPtr->cmdLine;
+    }
+
+    TclEmitInt1(op, envPtr);
+    TclUpdateAtCmdStart(op, envPtr);
+    BBUpdateStackReqs(bbPtr, tblIdx, count);
+}
+
+static void
+BBEmitInstInt1(
+    AssemblyEnv* assemEnvPtr,	/* Assembly environment */
+    int tblIdx,			/* Index in TalInstructionTable of op */
+    int opnd,			/* 1-byte operand */
+    int count)			/* Operand count for variadic ops */
+{
+    BBEmitOpcode(assemEnvPtr, tblIdx, count);
+    TclEmitInt1(opnd, assemEnvPtr->envPtr);
+}
+
+static void
+BBEmitInstInt4(
+    AssemblyEnv* assemEnvPtr,	/* Assembly environment */
+    int tblIdx,			/* Index in TalInstructionTable of op */
+    int opnd,			/* 4-byte operand */
+    int count)			/* Operand count for variadic ops */
+{
+    BBEmitOpcode(assemEnvPtr, tblIdx, count);
+    TclEmitInt4(opnd, assemEnvPtr->envPtr);
+}
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * BBEmitInst1or4 --
+ *
+ *	Emits a 1- or 4-byte operation according to the magnitude of the
+ *	operand.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static void
+BBEmitInst1or4(
+    AssemblyEnv* assemEnvPtr,	/* Assembly environment */
+    int tblIdx,			/* Index in TalInstructionTable of op */
+    int param,			/* Variable-length parameter */
+    int count)			/* Arity if variadic */
+{
+    CompileEnv* envPtr = assemEnvPtr->envPtr;
+				/* Compilation environment */
+    BasicBlock* bbPtr = assemEnvPtr->curr_bb;
+				/* Current basic block */
+    int op = TalInstructionTable[tblIdx].tclInstCode;
+
+    if (param <= 0xff) {
+	op >>= 8;
+    } else {
+	op &= 0xff;
+    }
+    TclEmitInt1(op, envPtr);
+    if (param <= 0xff) {
+	TclEmitInt1(param, envPtr);
+    } else {
+	TclEmitInt4(param, envPtr);
+    }
+    TclUpdateAtCmdStart(op, envPtr);
+    BBUpdateStackReqs(bbPtr, tblIdx, count);
+}
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * Tcl_AssembleObjCmd, TclNRAssembleObjCmd --
+ *
+ *	Direct evaluation path for tcl::unsupported::assemble
+ *
+ * Results:
+ *	Returns a standard Tcl result.
+ *
+ * Side effects:
+ *	Assembles the code in objv[1], and executes it, so side effects
+ *	include whatever the code does.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+int
+Tcl_AssembleObjCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    /*
+     * Boilerplate - make sure that there is an NRE trampoline on the C stack
+     * because there needs to be one in place to execute bytecode.
+     */
+
+    return Tcl_NRCallObjProc(interp, TclNRAssembleObjCmd, dummy, objc, objv);
+}
+
+int
+TclNRAssembleObjCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    ByteCode *codePtr;		/* Pointer to the bytecode to execute */
+    Tcl_Obj* backtrace;		/* Object where extra error information is
+				 * constructed. */
+
+    if (objc != 2) {
+	Tcl_WrongNumArgs(interp, 1, objv, "bytecodeList");
+	return TCL_ERROR;
+    }
+
+    /*
+     * Assemble the source to bytecode.
+     */
+
+    codePtr = CompileAssembleObj(interp, objv[1]);
+
+    /*
+     * On failure, report error line.
+     */
+
+    if (codePtr == NULL) {
+	Tcl_AddErrorInfo(interp, "\n    (\"");
+	Tcl_AppendObjToErrorInfo(interp, objv[0]);
+	Tcl_AddErrorInfo(interp, "\" body, line ");
+	backtrace = Tcl_NewIntObj(Tcl_GetErrorLine(interp));
+	Tcl_AppendObjToErrorInfo(interp, backtrace);
+	Tcl_AddErrorInfo(interp, ")");
+	return TCL_ERROR;
+    }
+
+    /*
+     * Use NRE to evaluate the bytecode from the trampoline.
+     */
+
+    return TclNRExecuteByteCode(interp, codePtr);
+}
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * CompileAssembleObj --
+ *
+ *	Sets up and assembles Tcl bytecode for the direct-execution path in
+ *	the Tcl bytecode assembler.
+ *
+ * Results:
+ *	Returns a pointer to the assembled code. Returns NULL if the assembly
+ *	fails for any reason, with an appropriate error message in the
+ *	interpreter.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static ByteCode *
+CompileAssembleObj(
+    Tcl_Interp *interp,		/* Tcl interpreter */
+    Tcl_Obj *objPtr)		/* Source code to assemble */
+{
+    Interp *iPtr = (Interp *) interp;
+				/* Internals of the interpreter */
+    CompileEnv compEnv;		/* Compilation environment structure */
+    register ByteCode *codePtr = NULL;
+				/* Bytecode resulting from the assembly */
+    Namespace* namespacePtr;	/* Namespace in which variable and command
+				 * names in the bytecode resolve */
+    int status;			/* Status return from Tcl_AssembleCode */
+    const char* source;		/* String representation of the source code */
+    int sourceLen;		/* Length of the source code in bytes */
+
+
+    /*
+     * Get the expression ByteCode from the object. If it exists, make sure it
+     * is valid in the current context.
+     */
+
+    if (objPtr->typePtr == &assembleCodeType) {
+	namespacePtr = iPtr->varFramePtr->nsPtr;
+	codePtr = objPtr->internalRep.twoPtrValue.ptr1;
+	if (((Interp *) *codePtr->interpHandle == iPtr)
+		&& (codePtr->compileEpoch == iPtr->compileEpoch)
+		&& (codePtr->nsPtr == namespacePtr)
+		&& (codePtr->nsEpoch == namespacePtr->resolverEpoch)
+		&& (codePtr->localCachePtr
+			== iPtr->varFramePtr->localCachePtr)) {
+	    return codePtr;
+	}
+
+	/*
+	 * Not valid, so free it and regenerate.
+	 */
+
+	FreeAssembleCodeInternalRep(objPtr);
+    }
+
+    /*
+     * Set up the compilation environment, and assemble the code.
+     */
+
+    source = TclGetStringFromObj(objPtr, &sourceLen);
+    TclInitCompileEnv(interp, &compEnv, source, sourceLen, NULL, 0);
+    status = TclAssembleCode(&compEnv, source, sourceLen, TCL_EVAL_DIRECT);
+    if (status != TCL_OK) {
+	/*
+	 * Assembly failed. Clean up and report the error.
+	 */
+	TclFreeCompileEnv(&compEnv);
+	return NULL;
+    }
+
+    /*
+     * Add a "done" instruction as the last instruction and change the object
+     * into a ByteCode object. Ownership of the literal objects and aux data
+     * items is given to the ByteCode object.
+     */
+
+    TclEmitOpcode(INST_DONE, &compEnv);
+    TclInitByteCodeObj(objPtr, &compEnv);
+    objPtr->typePtr = &assembleCodeType;
+    TclFreeCompileEnv(&compEnv);
+
+    /*
+     * Record the local variable context to which the bytecode pertains
+     */
+
+    codePtr = objPtr->internalRep.twoPtrValue.ptr1;
+    if (iPtr->varFramePtr->localCachePtr) {
+	codePtr->localCachePtr = iPtr->varFramePtr->localCachePtr;
+	codePtr->localCachePtr->refCount++;
+    }
+
+    /*
+     * Report on what the assembler did.
+     */
+
+#ifdef TCL_COMPILE_DEBUG
+    if (tclTraceCompile >= 2) {
+	TclPrintByteCodeObj(interp, objPtr);
+	fflush(stdout);
+    }
+#endif /* TCL_COMPILE_DEBUG */
+
+    return codePtr;
+}
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * TclCompileAssembleCmd --
+ *
+ *	Compilation procedure for the '::tcl::unsupported::assemble' command.
+ *
+ * Results:
+ *	Returns a standard Tcl result.
+ *
+ * Side effects:
+ *	Puts the result of assembling the code into the bytecode stream in
+ *	'compileEnv'.
+ *
+ * This procedure makes sure that the command has a single arg, which is
+ * constant. If that condition is met, the procedure calls TclAssembleCode to
+ * produce bytecode for the given assembly code, and returns any error
+ * resulting from the assembly.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+int
+TclCompileAssembleCmd(
+    Tcl_Interp *interp,		/* Used for error reporting. */
+    Tcl_Parse *parsePtr,	/* Points to a parse structure for the command
+				 * created by Tcl_ParseCommand. */
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)		/* Holds resulting instructions. */
+{
+    Tcl_Token *tokenPtr;	/* Token in the input script */
+
+    int numCommands = envPtr->numCommands;
+    int offset = envPtr->codeNext - envPtr->codeStart;
+    int depth = envPtr->currStackDepth;
+
+    /*
+     * Make sure that the command has a single arg that is a simple word.
+     */
+
+    if (parsePtr->numWords != 2) {
+	return TCL_ERROR;
+    }
+    tokenPtr = TokenAfter(parsePtr->tokenPtr);
+    if (tokenPtr->type != TCL_TOKEN_SIMPLE_WORD) {
+	return TCL_ERROR;
+    }
+
+    /*
+     * Compile the code and convert any error from the compilation into
+     * bytecode reporting the error;
+     */
+
+    if (TCL_ERROR == TclAssembleCode(envPtr, tokenPtr[1].start,
+	    tokenPtr[1].size, TCL_EVAL_DIRECT)) {
+
+	Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf(
+		"\n    (\"%.*s\" body, line %d)",
+		parsePtr->tokenPtr->size, parsePtr->tokenPtr->start,
+		Tcl_GetErrorLine(interp)));
+	envPtr->numCommands = numCommands;
+	envPtr->codeNext = envPtr->codeStart + offset;
+	envPtr->currStackDepth = depth;
+	TclCompileSyntaxError(interp, envPtr);
+    }
+    return TCL_OK;
+}
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * TclAssembleCode --
+ *
+ *	Take a list of instructions in a Tcl_Obj, and assemble them to Tcl
+ *	bytecodes
+ *
+ * Results:
+ *	Returns TCL_OK on success, TCL_ERROR on failure.  If 'flags' includes
+ *	TCL_EVAL_DIRECT, places an error message in the interpreter result.
+ *
+ * Side effects:
+ *	Adds byte codes to the compile environment, and updates the
+ *	environment's stack depth.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static int
+TclAssembleCode(
+    CompileEnv *envPtr,		/* Compilation environment that is to receive
+				 * the generated bytecode */
+    const char* codePtr,	/* Assembly-language code to be processed */
+    int codeLen,		/* Length of the code */
+    int flags)			/* OR'ed combination of flags */
+{
+    Tcl_Interp* interp = (Tcl_Interp*) envPtr->iPtr;
+				/* Tcl interpreter */
+    /*
+     * Walk through the assembly script using the Tcl parser.  Each 'command'
+     * will be an instruction or assembly directive.
+     */
+
+    const char* instPtr = codePtr;
+				/* Where to start looking for a line of code */
+    const char* nextPtr;	/* Pointer to the end of the line of code */
+    int bytesLeft = codeLen;	/* Number of bytes of source code remaining to
+				 * be parsed */
+    int status;			/* Tcl status return */
+    AssemblyEnv* assemEnvPtr = NewAssemblyEnv(envPtr, flags);
+    Tcl_Parse* parsePtr = assemEnvPtr->parsePtr;
+
+    do {
+	/*
+	 * Parse out one command line from the assembly script.
+	 */
+
+	status = Tcl_ParseCommand(interp, instPtr, bytesLeft, 0, parsePtr);
+
+	/*
+	 * Report errors in the parse.
+	 */
+
+	if (status != TCL_OK) {
+	    if (flags & TCL_EVAL_DIRECT) {
+		Tcl_LogCommandInfo(interp, codePtr, parsePtr->commandStart,
+			parsePtr->term + 1 - parsePtr->commandStart);
+	    }
+	    FreeAssemblyEnv(assemEnvPtr);
+	    return TCL_ERROR;
+	}
+
+	/*
+	 * Advance the pointers around any leading commentary.
+	 */
+
+	TclAdvanceLines(&assemEnvPtr->cmdLine, instPtr,
+		parsePtr->commandStart);
+	TclAdvanceContinuations(&assemEnvPtr->cmdLine, &assemEnvPtr->clNext,
+		parsePtr->commandStart - envPtr->source);
+
+	/*
+	 * Process the line of code.
+	 */
+
+	if (parsePtr->numWords > 0) {
+	    int instLen = parsePtr->commandSize;
+		    /* Length in bytes of the current command */
+
+	    if (parsePtr->term == parsePtr->commandStart + instLen - 1) {
+		--instLen;
+	    }
+
+	    /*
+	     * If tracing, show each line assembled as it happens.
+	     */
+
+#ifdef TCL_COMPILE_DEBUG
+	    if ((tclTraceCompile >= 2) && (envPtr->procPtr == NULL)) {
+		printf("  %4ld Assembling: ",
+			(long)(envPtr->codeNext - envPtr->codeStart));
+		TclPrintSource(stdout, parsePtr->commandStart,
+			TclMin(instLen, 55));
+		printf("\n");
+	    }
+#endif
+	    if (AssembleOneLine(assemEnvPtr) != TCL_OK) {
+		if (flags & TCL_EVAL_DIRECT) {
+		    Tcl_LogCommandInfo(interp, codePtr,
+			    parsePtr->commandStart, instLen);
+		}
+		Tcl_FreeParse(parsePtr);
+		FreeAssemblyEnv(assemEnvPtr);
+		return TCL_ERROR;
+	    }
+	}
+
+	/*
+	 * Advance to the next line of code.
+	 */
+
+	nextPtr = parsePtr->commandStart + parsePtr->commandSize;
+	bytesLeft -= (nextPtr - instPtr);
+	instPtr = nextPtr;
+	TclAdvanceLines(&assemEnvPtr->cmdLine, parsePtr->commandStart,
+		instPtr);
+	TclAdvanceContinuations(&assemEnvPtr->cmdLine, &assemEnvPtr->clNext,
+		instPtr - envPtr->source);
+	Tcl_FreeParse(parsePtr);
+    } while (bytesLeft > 0);
+
+    /*
+     * Done with parsing the code.
+     */
+
+    status = FinishAssembly(assemEnvPtr);
+    FreeAssemblyEnv(assemEnvPtr);
+    return status;
+}
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * NewAssemblyEnv --
+ *
+ *	Creates an environment for the assembler to run in.
+ *
+ * Results:
+ *	Allocates, initialises and returns an assembler environment
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static AssemblyEnv*
+NewAssemblyEnv(
+    CompileEnv* envPtr,		/* Compilation environment being used for code
+				 * generation*/
+    int flags)			/* Compilation flags (TCL_EVAL_DIRECT) */
+{
+    Tcl_Interp* interp = (Tcl_Interp*) envPtr->iPtr;
+				/* Tcl interpreter */
+    AssemblyEnv* assemEnvPtr = TclStackAlloc(interp, sizeof(AssemblyEnv));
+				/* Assembler environment under construction */
+    Tcl_Parse* parsePtr = TclStackAlloc(interp, sizeof(Tcl_Parse));
+				/* Parse of one line of assembly code */
+
+    assemEnvPtr->envPtr = envPtr;
+    assemEnvPtr->parsePtr = parsePtr;
+    assemEnvPtr->cmdLine = 1;
+    assemEnvPtr->clNext = envPtr->clNext;
+
+    /*
+     * Make the hashtables that store symbol resolution.
+     */
+
+    Tcl_InitHashTable(&assemEnvPtr->labelHash, TCL_STRING_KEYS);
+
+    /*
+     * Start the first basic block.
+     */
+
+    assemEnvPtr->curr_bb = NULL;
+    assemEnvPtr->head_bb = AllocBB(assemEnvPtr);
+    assemEnvPtr->curr_bb = assemEnvPtr->head_bb;
+    assemEnvPtr->head_bb->startLine = 1;
+
+    /*
+     * Stash compilation flags.
+     */
+
+    assemEnvPtr->flags = flags;
+    return assemEnvPtr;
+}
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * FreeAssemblyEnv --
+ *
+ *	Cleans up the assembler environment when assembly is complete.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static void
+FreeAssemblyEnv(
+    AssemblyEnv* assemEnvPtr)	/* Environment to free */
+{
+    CompileEnv* envPtr = assemEnvPtr->envPtr;
+				/* Compilation environment being used for code
+				 * generation */
+    Tcl_Interp* interp = (Tcl_Interp*) envPtr->iPtr;
+				/* Tcl interpreter */
+    BasicBlock* thisBB;		/* Pointer to a basic block being deleted */
+    BasicBlock* nextBB;		/* Pointer to a deleted basic block's
+				 * successor */
+
+    /*
+     * Free all the basic block structures.
+     */
+
+    for (thisBB = assemEnvPtr->head_bb; thisBB != NULL; thisBB = nextBB) {
+	if (thisBB->jumpTarget != NULL) {
+	    Tcl_DecrRefCount(thisBB->jumpTarget);
+	}
+	if (thisBB->foreignExceptions != NULL) {
+	    ckfree(thisBB->foreignExceptions);
+	}
+	nextBB = thisBB->successor1;
+	if (thisBB->jtPtr != NULL) {
+	    DeleteMirrorJumpTable(thisBB->jtPtr);
+	    thisBB->jtPtr = NULL;
+	}
+	ckfree(thisBB);
+    }
+
+    /*
+     * Dispose what's left.
+     */
+
+    Tcl_DeleteHashTable(&assemEnvPtr->labelHash);
+    TclStackFree(interp, assemEnvPtr->parsePtr);
+    TclStackFree(interp, assemEnvPtr);
+}
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * AssembleOneLine --
+ *
+ *	Assembles a single command from an assembly language source.
+ *
+ * Results:
+ *	Returns TCL_ERROR with an appropriate error message if the assembly
+ *	fails. Returns TCL_OK if the assembly succeeds. Updates the assembly
+ *	environment with the state of the assembly.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static int
+AssembleOneLine(
+    AssemblyEnv* assemEnvPtr)	/* State of the assembly */
+{
+    CompileEnv* envPtr = assemEnvPtr->envPtr;
+				/* Compilation environment being used for code
+				 * gen */
+    Tcl_Interp* interp = (Tcl_Interp*) envPtr->iPtr;
+				/* Tcl interpreter */
+    Tcl_Parse* parsePtr = assemEnvPtr->parsePtr;
+				/* Parse of the line of code */
+    Tcl_Token* tokenPtr;	/* Current token within the line of code */
+    Tcl_Obj* instNameObj;	/* Name of the instruction */
+    int tblIdx;			/* Index in TalInstructionTable of the
+				 * instruction */
+    enum TalInstType instType;	/* Type of the instruction */
+    Tcl_Obj* operand1Obj = NULL;
+				/* First operand to the instruction */
+    const char* operand1;	/* String rep of the operand */
+    int operand1Len;		/* String length of the operand */
+    int opnd;			/* Integer representation of an operand */
+    int litIndex;		/* Literal pool index of a constant */
+    int localVar;		/* LVT index of a local variable */
+    int flags;			/* Flags for a basic block */
+    JumptableInfo* jtPtr;	/* Pointer to a jumptable */
+    int infoIndex;		/* Index of the jumptable in auxdata */
+    int status = TCL_ERROR;	/* Return value from this function */
+
+    /*
+     * Make sure that the instruction name is known at compile time.
+     */
+
+    tokenPtr = parsePtr->tokenPtr;
+    if (GetNextOperand(assemEnvPtr, &tokenPtr, &instNameObj) != TCL_OK) {
+	return TCL_ERROR;
+    }
+
+    /*
+     * Look up the instruction name.
+     */
+
+    if (Tcl_GetIndexFromObjStruct(interp, instNameObj,
+	    &TalInstructionTable[0].name, sizeof(TalInstDesc), "instruction",
+	    TCL_EXACT, &tblIdx) != TCL_OK) {
+	goto cleanup;
+    }
+
+    /*
+     * Vector on the type of instruction being processed.
+     */
+
+    instType = TalInstructionTable[tblIdx].instType;
+    switch (instType) {
+
+    case ASSEM_PUSH:
+	if (parsePtr->numWords != 2) {
+	    Tcl_WrongNumArgs(interp, 1, &instNameObj, "value");
+	    goto cleanup;
+	}
+	if (GetNextOperand(assemEnvPtr, &tokenPtr, &operand1Obj) != TCL_OK) {
+	    goto cleanup;
+	}
+	operand1 = Tcl_GetStringFromObj(operand1Obj, &operand1Len);
+	litIndex = TclRegisterNewLiteral(envPtr, operand1, operand1Len);
+	BBEmitInst1or4(assemEnvPtr, tblIdx, litIndex, 0);
+	break;
+
+    case ASSEM_1BYTE:
+	if (parsePtr->numWords != 1) {
+	    Tcl_WrongNumArgs(interp, 1, &instNameObj, "");
+	    goto cleanup;
+	}
+	BBEmitOpcode(assemEnvPtr, tblIdx, 0);
+	break;
+
+    case ASSEM_BEGIN_CATCH:
+	/*
+	 * Emit the BEGIN_CATCH instruction with the code offset of the
+	 * exception branch target instead of the exception range index. The
+	 * correct index will be generated and inserted later, when catches
+	 * are being resolved.
+	 */
+
+	if (parsePtr->numWords != 2) {
+	    Tcl_WrongNumArgs(interp, 1, &instNameObj, "label");
+	    goto cleanup;
+	}
+	if (GetNextOperand(assemEnvPtr, &tokenPtr, &operand1Obj) != TCL_OK) {
+	    goto cleanup;
+	}
+	assemEnvPtr->curr_bb->jumpLine = assemEnvPtr->cmdLine;
+	assemEnvPtr->curr_bb->jumpOffset = envPtr->codeNext-envPtr->codeStart;
+	BBEmitInstInt4(assemEnvPtr, tblIdx, 0, 0);
+	assemEnvPtr->curr_bb->flags |= BB_BEGINCATCH;
+	StartBasicBlock(assemEnvPtr, BB_FALLTHRU, operand1Obj);
+	break;
+
+    case ASSEM_BOOL:
+	if (parsePtr->numWords != 2) {
+	    Tcl_WrongNumArgs(interp, 1, &instNameObj, "boolean");
+	    goto cleanup;
+	}
+	if (GetBooleanOperand(assemEnvPtr, &tokenPtr, &opnd) != TCL_OK) {
+	    goto cleanup;
+	}
+	BBEmitInstInt1(assemEnvPtr, tblIdx, opnd, 0);
+	break;
+
+    case ASSEM_BOOL_LVT4:
+	if (parsePtr->numWords != 3) {
+	    Tcl_WrongNumArgs(interp, 1, &instNameObj, "boolean varName");
+	    goto cleanup;
+	}
+	if (GetBooleanOperand(assemEnvPtr, &tokenPtr, &opnd) != TCL_OK) {
+	    goto cleanup;
+	}
+	localVar = FindLocalVar(assemEnvPtr, &tokenPtr);
+	if (localVar < 0) {
+	    goto cleanup;
+	}
+	BBEmitInstInt1(assemEnvPtr, tblIdx, opnd, 0);
+	TclEmitInt4(localVar, envPtr);
+	break;
+
+    case ASSEM_CONCAT1:
+	if (parsePtr->numWords != 2) {
+	    Tcl_WrongNumArgs(interp, 1, &instNameObj, "imm8");
+	    goto cleanup;
+	}
+	if (GetIntegerOperand(assemEnvPtr, &tokenPtr, &opnd) != TCL_OK
+		|| CheckOneByte(interp, opnd) != TCL_OK
+		|| CheckStrictlyPositive(interp, opnd) != TCL_OK) {
+	    goto cleanup;
+	}
+	BBEmitInstInt1(assemEnvPtr, tblIdx, opnd, opnd);
+	break;
+
+    case ASSEM_DICT_GET:
+	if (parsePtr->numWords != 2) {
+	    Tcl_WrongNumArgs(interp, 1, &instNameObj, "count");
+	    goto cleanup;
+	}
+	if (GetIntegerOperand(assemEnvPtr, &tokenPtr, &opnd) != TCL_OK
+		|| CheckStrictlyPositive(interp, opnd) != TCL_OK) {
+	    goto cleanup;
+	}
+	BBEmitInstInt4(assemEnvPtr, tblIdx, opnd, opnd+1);
+	break;
+
+    case ASSEM_DICT_SET:
+	if (parsePtr->numWords != 3) {
+	    Tcl_WrongNumArgs(interp, 1, &instNameObj, "count varName");
+	    goto cleanup;
+	}
+	if (GetIntegerOperand(assemEnvPtr, &tokenPtr, &opnd) != TCL_OK
+		|| CheckStrictlyPositive(interp, opnd) != TCL_OK) {
+	    goto cleanup;
+	}
+	localVar = FindLocalVar(assemEnvPtr, &tokenPtr);
+	if (localVar < 0) {
+	    goto cleanup;
+	}
+	BBEmitInstInt4(assemEnvPtr, tblIdx, opnd, opnd+1);
+	TclEmitInt4(localVar, envPtr);
+	break;
+
+    case ASSEM_DICT_UNSET:
+	if (parsePtr->numWords != 3) {
+	    Tcl_WrongNumArgs(interp, 1, &instNameObj, "count varName");
+	    goto cleanup;
+	}
+	if (GetIntegerOperand(assemEnvPtr, &tokenPtr, &opnd) != TCL_OK
+		|| CheckStrictlyPositive(interp, opnd) != TCL_OK) {
+	    goto cleanup;
+	}
+	localVar = FindLocalVar(assemEnvPtr, &tokenPtr);
+	if (localVar < 0) {
+	    goto cleanup;
+	}
+	BBEmitInstInt4(assemEnvPtr, tblIdx, opnd, opnd);
+	TclEmitInt4(localVar, envPtr);
+	break;
+
+    case ASSEM_END_CATCH:
+	if (parsePtr->numWords != 1) {
+	    Tcl_WrongNumArgs(interp, 1, &instNameObj, "");
+	    goto cleanup;
+	}
+	assemEnvPtr->curr_bb->flags |= BB_ENDCATCH;
+	BBEmitOpcode(assemEnvPtr, tblIdx, 0);
+	StartBasicBlock(assemEnvPtr, BB_FALLTHRU, NULL);
+	break;
+
+    case ASSEM_EVAL:
+	/* TODO - Refactor this stuff into a subroutine that takes the inst
+	 * code, the message ("script" or "expression") and an evaluator
+	 * callback that calls TclCompileScript or TclCompileExpr. */
+
+	if (parsePtr->numWords != 2) {
+	    Tcl_WrongNumArgs(interp, 1, &instNameObj,
+		    ((TalInstructionTable[tblIdx].tclInstCode
+		    == INST_EVAL_STK) ? "script" : "expression"));
+	    goto cleanup;
+	}
+	if (tokenPtr->type == TCL_TOKEN_SIMPLE_WORD) {
+	    CompileEmbeddedScript(assemEnvPtr, tokenPtr+1,
+		    TalInstructionTable+tblIdx);
+	} else if (GetNextOperand(assemEnvPtr, &tokenPtr,
+		&operand1Obj) != TCL_OK) {
+	    goto cleanup;
+	} else {
+	    operand1 = Tcl_GetStringFromObj(operand1Obj, &operand1Len);
+	    litIndex = TclRegisterNewLiteral(envPtr, operand1, operand1Len);
+
+	    /*
+	     * Assumes that PUSH is the first slot!
+	     */
+
+	    BBEmitInst1or4(assemEnvPtr, 0, litIndex, 0);
+	    BBEmitOpcode(assemEnvPtr, tblIdx, 0);
+	}
+	break;
+
+    case ASSEM_INVOKE:
+	if (parsePtr->numWords != 2) {
+	    Tcl_WrongNumArgs(interp, 1, &instNameObj, "count");
+	    goto cleanup;
+	}
+	if (GetIntegerOperand(assemEnvPtr, &tokenPtr, &opnd) != TCL_OK
+		|| CheckStrictlyPositive(interp, opnd) != TCL_OK) {
+	    goto cleanup;
+	}
+
+	BBEmitInst1or4(assemEnvPtr, tblIdx, opnd, opnd);
+	break;
+
+    case ASSEM_JUMP:
+    case ASSEM_JUMP4:
+	if (parsePtr->numWords != 2) {
+	    Tcl_WrongNumArgs(interp, 1, &instNameObj, "label");
+	    goto cleanup;
+	}
+	if (GetNextOperand(assemEnvPtr, &tokenPtr, &operand1Obj) != TCL_OK) {
+	    goto cleanup;
+	}
+	assemEnvPtr->curr_bb->jumpOffset = envPtr->codeNext-envPtr->codeStart;
+	if (instType == ASSEM_JUMP) {
+	    flags = BB_JUMP1;
+	    BBEmitInstInt1(assemEnvPtr, tblIdx, 0, 0);
+	} else {
+	    flags = 0;
+	    BBEmitInstInt4(assemEnvPtr, tblIdx, 0, 0);
+	}
+
+	/*
+	 * Start a new basic block at the instruction following the jump.
+	 */
+
+	assemEnvPtr->curr_bb->jumpLine = assemEnvPtr->cmdLine;
+	if (TalInstructionTable[tblIdx].operandsConsumed != 0) {
+	    flags |= BB_FALLTHRU;
+	}
+	StartBasicBlock(assemEnvPtr, flags, operand1Obj);
+	break;
+
+    case ASSEM_JUMPTABLE:
+	if (parsePtr->numWords != 2) {
+	    Tcl_WrongNumArgs(interp, 1, &instNameObj, "table");
+	    goto cleanup;
+	}
+	if (GetNextOperand(assemEnvPtr, &tokenPtr, &operand1Obj) != TCL_OK) {
+	    goto cleanup;
+	}
+
+	jtPtr = ckalloc(sizeof(JumptableInfo));
+
+	Tcl_InitHashTable(&jtPtr->hashTable, TCL_STRING_KEYS);
+	assemEnvPtr->curr_bb->jumpLine = assemEnvPtr->cmdLine;
+	assemEnvPtr->curr_bb->jumpOffset = envPtr->codeNext-envPtr->codeStart;
+	DEBUG_PRINT("bb %p jumpLine %d jumpOffset %d\n",
+		assemEnvPtr->curr_bb, assemEnvPtr->cmdLine,
+		envPtr->codeNext - envPtr->codeStart);
+
+	infoIndex = TclCreateAuxData(jtPtr, &tclJumptableInfoType, envPtr);
+	DEBUG_PRINT("auxdata index=%d\n", infoIndex);
+
+	BBEmitInstInt4(assemEnvPtr, tblIdx, infoIndex, 0);
+	if (CreateMirrorJumpTable(assemEnvPtr, operand1Obj) != TCL_OK) {
+	    goto cleanup;
+	}
+	StartBasicBlock(assemEnvPtr, BB_JUMPTABLE|BB_FALLTHRU, NULL);
+	break;
+
+    case ASSEM_LABEL:
+	if (parsePtr->numWords != 2) {
+	    Tcl_WrongNumArgs(interp, 1, &instNameObj, "name");
+	    goto cleanup;
+	}
+	if (GetNextOperand(assemEnvPtr, &tokenPtr, &operand1Obj) != TCL_OK) {
+	    goto cleanup;
+	}
+
+	/*
+	 * Add the (label_name, address) pair to the hash table.
+	 */
+
+	if (DefineLabel(assemEnvPtr, Tcl_GetString(operand1Obj)) != TCL_OK) {
+	    goto cleanup;
+	}
+	break;
+
+    case ASSEM_LINDEX_MULTI:
+	if (parsePtr->numWords != 2) {
+	    Tcl_WrongNumArgs(interp, 1, &instNameObj, "count");
+	    goto cleanup;
+	}
+	if (GetIntegerOperand(assemEnvPtr, &tokenPtr, &opnd) != TCL_OK
+		|| CheckStrictlyPositive(interp, opnd) != TCL_OK) {
+	    goto cleanup;
+	}
+	BBEmitInstInt4(assemEnvPtr, tblIdx, opnd, opnd);
+	break;
+
+    case ASSEM_LIST:
+	if (parsePtr->numWords != 2) {
+	    Tcl_WrongNumArgs(interp, 1, &instNameObj, "count");
+	    goto cleanup;
+	}
+	if (GetIntegerOperand(assemEnvPtr, &tokenPtr, &opnd) != TCL_OK
+		|| CheckNonNegative(interp, opnd) != TCL_OK) {
+	    goto cleanup;
+	}
+	BBEmitInstInt4(assemEnvPtr, tblIdx, opnd, opnd);
+	break;
+
+    case ASSEM_INDEX:
+	if (parsePtr->numWords != 2) {
+	    Tcl_WrongNumArgs(interp, 1, &instNameObj, "count");
+	    goto cleanup;
+	}
+	if (GetListIndexOperand(assemEnvPtr, &tokenPtr, &opnd) != TCL_OK) {
+	    goto cleanup;
+	}
+	BBEmitInstInt4(assemEnvPtr, tblIdx, opnd, opnd);
+	break;
+
+    case ASSEM_LSET_FLAT:
+	if (parsePtr->numWords != 2) {
+	    Tcl_WrongNumArgs(interp, 1, &instNameObj, "count");
+	    goto cleanup;
+	}
+	if (GetIntegerOperand(assemEnvPtr, &tokenPtr, &opnd) != TCL_OK) {
+	    goto cleanup;
+	}
+	if (opnd < 2) {
+	    if (assemEnvPtr->flags & TCL_EVAL_DIRECT) {
+		Tcl_SetObjResult(interp,
+			Tcl_NewStringObj("operand must be >=2", -1));
+		Tcl_SetErrorCode(interp, "TCL", "ASSEM", "OPERAND>=2", NULL);
+	    }
+	    goto cleanup;
+	}
+	BBEmitInstInt4(assemEnvPtr, tblIdx, opnd, opnd);
+	break;
+
+    case ASSEM_LVT:
+	if (parsePtr->numWords != 2) {
+	    Tcl_WrongNumArgs(interp, 1, &instNameObj, "varname");
+	    goto cleanup;
+	}
+	localVar = FindLocalVar(assemEnvPtr, &tokenPtr);
+	if (localVar < 0) {
+	    goto cleanup;
+	}
+	BBEmitInst1or4(assemEnvPtr, tblIdx, localVar, 0);
+	break;
+
+    case ASSEM_LVT1:
+	if (parsePtr->numWords != 2) {
+	    Tcl_WrongNumArgs(interp, 1, &instNameObj, "varname");
+	    goto cleanup;
+	}
+	localVar = FindLocalVar(assemEnvPtr, &tokenPtr);
+	if (localVar < 0 || CheckOneByte(interp, localVar)) {
+	    goto cleanup;
+	}
+	BBEmitInstInt1(assemEnvPtr, tblIdx, localVar, 0);
+	break;
+
+    case ASSEM_LVT1_SINT1:
+	if (parsePtr->numWords != 3) {
+	    Tcl_WrongNumArgs(interp, 1, &instNameObj, "varName imm8");
+	    goto cleanup;
+	}
+	localVar = FindLocalVar(assemEnvPtr, &tokenPtr);
+	if (localVar < 0 || CheckOneByte(interp, localVar)
+		|| GetIntegerOperand(assemEnvPtr, &tokenPtr, &opnd) != TCL_OK
+		|| CheckSignedOneByte(interp, opnd)) {
+	    goto cleanup;
+	}
+	BBEmitInstInt1(assemEnvPtr, tblIdx, localVar, 0);
+	TclEmitInt1(opnd, envPtr);
+	break;
+
+    case ASSEM_LVT4:
+	if (parsePtr->numWords != 2) {
+	    Tcl_WrongNumArgs(interp, 1, &instNameObj, "varname");
+	    goto cleanup;
+	}
+	localVar = FindLocalVar(assemEnvPtr, &tokenPtr);
+	if (localVar < 0) {
+	    goto cleanup;
+	}
+	BBEmitInstInt4(assemEnvPtr, tblIdx, localVar, 0);
+	break;
+
+    case ASSEM_OVER:
+	if (parsePtr->numWords != 2) {
+	    Tcl_WrongNumArgs(interp, 1, &instNameObj, "count");
+	    goto cleanup;
+	}
+	if (GetIntegerOperand(assemEnvPtr, &tokenPtr, &opnd) != TCL_OK
+		|| CheckNonNegative(interp, opnd) != TCL_OK) {
+	    goto cleanup;
+	}
+	BBEmitInstInt4(assemEnvPtr, tblIdx, opnd, opnd+1);
+	break;
+
+    case ASSEM_REGEXP:
+	if (parsePtr->numWords != 2) {
+	    Tcl_WrongNumArgs(interp, 1, &instNameObj, "boolean");
+	    goto cleanup;
+	}
+	if (GetBooleanOperand(assemEnvPtr, &tokenPtr, &opnd) != TCL_OK) {
+	    goto cleanup;
+	}
+	{
+	    int flags = TCL_REG_ADVANCED | (opnd ? TCL_REG_NOCASE : 0);
+
+	    BBEmitInstInt1(assemEnvPtr, tblIdx, flags, 0);
+	}
+	break;
+
+    case ASSEM_REVERSE:
+	if (parsePtr->numWords != 2) {
+	    Tcl_WrongNumArgs(interp, 1, &instNameObj, "count");
+	    goto cleanup;
+	}
+	if (GetIntegerOperand(assemEnvPtr, &tokenPtr, &opnd) != TCL_OK
+		|| CheckNonNegative(interp, opnd) != TCL_OK) {
+	    goto cleanup;
+	}
+	BBEmitInstInt4(assemEnvPtr, tblIdx, opnd, opnd);
+	break;
+
+    case ASSEM_SINT1:
+	if (parsePtr->numWords != 2) {
+	    Tcl_WrongNumArgs(interp, 1, &instNameObj, "imm8");
+	    goto cleanup;
+	}
+	if (GetIntegerOperand(assemEnvPtr, &tokenPtr, &opnd) != TCL_OK
+		|| CheckSignedOneByte(interp, opnd) != TCL_OK) {
+	    goto cleanup;
+	}
+	BBEmitInstInt1(assemEnvPtr, tblIdx, opnd, 0);
+	break;
+
+    case ASSEM_SINT4_LVT4:
+	if (parsePtr->numWords != 3) {
+	    Tcl_WrongNumArgs(interp, 1, &instNameObj, "count varName");
+	    goto cleanup;
+	}
+	if (GetIntegerOperand(assemEnvPtr, &tokenPtr, &opnd) != TCL_OK) {
+	    goto cleanup;
+	}
+	localVar = FindLocalVar(assemEnvPtr, &tokenPtr);
+	if (localVar < 0) {
+	    goto cleanup;
+	}
+	BBEmitInstInt4(assemEnvPtr, tblIdx, opnd, 0);
+	TclEmitInt4(localVar, envPtr);
+	break;
+
+    default:
+	Tcl_Panic("Instruction \"%s\" could not be found, can't happen\n",
+		Tcl_GetString(instNameObj));
+    }
+
+    status = TCL_OK;
+ cleanup:
+    Tcl_DecrRefCount(instNameObj);
+    if (operand1Obj) {
+	Tcl_DecrRefCount(operand1Obj);
+    }
+    return status;
+}
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * CompileEmbeddedScript --
+ *
+ *	Compile an embedded 'eval' or 'expr' that appears in assembly code.
+ *
+ * This procedure is called when the 'eval' or 'expr' assembly directive is
+ * encountered, and the argument to the directive is a simple word that
+ * requires no substitution. The appropriate compiler (TclCompileScript or
+ * TclCompileExpr) is invoked recursively, and emits bytecode.
+ *
+ * Before the compiler is invoked, the compilation environment's stack
+ * consumption is reset to zero. Upon return from the compilation, the net
+ * stack effect of the compilation is in the compiler env, and this stack
+ * effect is posted to the assembler environment. The compile environment's
+ * stack consumption is then restored to what it was before (which is actually
+ * the state of the stack on entry to the block of assembly code).
+ *
+ * Any exception ranges pushed by the compilation are copied to the basic
+ * block and removed from the compiler environment. They will be rebuilt at
+ * the end of assembly, when the exception stack depth is actually known.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static void
+CompileEmbeddedScript(
+    AssemblyEnv* assemEnvPtr,	/* Assembly environment */
+    Tcl_Token* tokenPtr,	/* Tcl_Token containing the script */
+    const TalInstDesc* instPtr)	/* Instruction that determines whether
+				 * the script is 'expr' or 'eval' */
+{
+    CompileEnv* envPtr = assemEnvPtr->envPtr;
+				/* Compilation environment */
+    Tcl_Interp* interp = (Tcl_Interp*) envPtr->iPtr;
+				/* Tcl interpreter */
+
+    /*
+     * The expression or script is not only known at compile time, but
+     * actually a "simple word". It can be compiled inline by invoking the
+     * compiler recursively.
+     *
+     * Save away the stack depth and reset it before compiling the script.
+     * We'll record the stack usage of the script in the BasicBlock, and
+     * accumulate it together with the stack usage of the enclosing assembly
+     * code.
+     */
+
+    int savedStackDepth = envPtr->currStackDepth;
+    int savedMaxStackDepth = envPtr->maxStackDepth;
+    int savedCodeIndex = envPtr->codeNext - envPtr->codeStart;
+    int savedExceptArrayNext = envPtr->exceptArrayNext;
+
+    envPtr->currStackDepth = 0;
+    envPtr->maxStackDepth = 0;
+
+    StartBasicBlock(assemEnvPtr, BB_FALLTHRU, NULL);
+    switch(instPtr->tclInstCode) {
+    case INST_EVAL_STK:
+	TclCompileScript(interp, tokenPtr->start, tokenPtr->size, envPtr);
+	break;
+    case INST_EXPR_STK:
+	TclCompileExpr(interp, tokenPtr->start, tokenPtr->size, envPtr, 1);
+	break;
+    default:
+	Tcl_Panic("no ASSEM_EVAL case for %s (%d), can't happen",
+		instPtr->name, instPtr->tclInstCode);
+    }
+
+    /*
+     * Roll up the stack usage of the embedded block into the assembler
+     * environment.
+     */
+
+    SyncStackDepth(assemEnvPtr);
+    envPtr->currStackDepth = savedStackDepth;
+    envPtr->maxStackDepth = savedMaxStackDepth;
+
+    /*
+     * Save any exception ranges that were pushed by the compiler; they will
+     * need to be fixed up once the stack depth is known.
+     */
+
+    MoveExceptionRangesToBasicBlock(assemEnvPtr, savedCodeIndex,
+	    savedExceptArrayNext);
+
+    /*
+     * Flush the current basic block.
+     */
+
+    StartBasicBlock(assemEnvPtr, BB_FALLTHRU, NULL);
+}
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * SyncStackDepth --
+ *
+ *	Copies the stack depth from the compile environment to a basic block.
+ *
+ * Side effects:
+ *	Current and max stack depth in the current basic block are adjusted.
+ *
+ * This procedure is called on return from invoking the compiler for the
+ * 'eval' and 'expr' operations. It adjusts the stack depth of the current
+ * basic block to reflect the stack required by the just-compiled code.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static void
+SyncStackDepth(
+    AssemblyEnv* assemEnvPtr)	/* Assembly environment */
+{
+    CompileEnv* envPtr = assemEnvPtr->envPtr;
+				/* Compilation environment */
+    BasicBlock* curr_bb = assemEnvPtr->curr_bb;
+				/* Current basic block */
+    int maxStackDepth = curr_bb->finalStackDepth + envPtr->maxStackDepth;
+				/* Max stack depth in the basic block */
+
+    if (maxStackDepth > curr_bb->maxStackDepth) {
+	curr_bb->maxStackDepth = maxStackDepth;
+    }
+    curr_bb->finalStackDepth += envPtr->currStackDepth;
+}
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * MoveExceptionRangesToBasicBlock --
+ *
+ *	Removes exception ranges that were created by compiling an embedded
+ *	script from the CompileEnv, and stores them in the BasicBlock. They
+ *	will be reinstalled, at the correct stack depth, after control flow
+ *	analysis is complete on the assembly code.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static void
+MoveExceptionRangesToBasicBlock(
+    AssemblyEnv* assemEnvPtr,	/* Assembly environment */
+    int savedCodeIndex,		/* Start of the embedded code */
+    int savedExceptArrayNext)	/* Saved index of the end of the exception
+				 * range array */
+{
+    CompileEnv* envPtr = assemEnvPtr->envPtr;
+				/* Compilation environment */
+    BasicBlock* curr_bb = assemEnvPtr->curr_bb;
+				/* Current basic block */
+    int exceptionCount = envPtr->exceptArrayNext - savedExceptArrayNext;
+				/* Number of ranges that must be moved */
+    int i;
+
+    if (exceptionCount == 0) {
+	/* Nothing to do */
+	return;
+    }
+
+    /*
+     * Save the exception ranges in the basic block. They will be re-added at
+     * the conclusion of assembly; at this time, the INST_BEGIN_CATCH
+     * instructions in the block will be adjusted from whatever range indices
+     * they have [savedExceptArrayNext .. envPtr->exceptArrayNext) to the
+     * indices that the exceptions acquire. The saved exception ranges are
+     * converted to a relative nesting depth. The depth will be recomputed
+     * once flow analysis has determined the actual stack depth of the block.
+     */
+
+    DEBUG_PRINT("basic block %p has %d exceptions starting at %d\n",
+	    curr_bb, exceptionCount, savedExceptArrayNext);
+    curr_bb->foreignExceptionBase = savedExceptArrayNext;
+    curr_bb->foreignExceptionCount = exceptionCount;
+    curr_bb->foreignExceptions =
+	    ckalloc(exceptionCount * sizeof(ExceptionRange));
+    memcpy(curr_bb->foreignExceptions,
+	    envPtr->exceptArrayPtr + savedExceptArrayNext,
+	    exceptionCount * sizeof(ExceptionRange));
+    for (i = 0; i < exceptionCount; ++i) {
+	curr_bb->foreignExceptions[i].nestingLevel -= envPtr->exceptDepth;
+    }
+    envPtr->exceptArrayNext = savedExceptArrayNext;
+}
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * CreateMirrorJumpTable --
+ *
+ *	Makes a jump table with comparison values and assembly code labels.
+ *
+ * Results:
+ *	Returns a standard Tcl status, with an error message in the
+ *	interpreter on error.
+ *
+ * Side effects:
+ *	Initializes the jump table pointer in the current basic block to a
+ *	JumptableInfo. The keys in the JumptableInfo are the comparison
+ *	strings. The values, instead of being jump displacements, are
+ *	Tcl_Obj's with the code labels.
+ */
+
+static int
+CreateMirrorJumpTable(
+    AssemblyEnv* assemEnvPtr,	/* Assembly environment */
+    Tcl_Obj* jumps)		/* List of alternating keywords and labels */
+{
+    int objc;			/* Number of elements in the 'jumps' list */
+    Tcl_Obj** objv;		/* Pointers to the elements in the list */
+    CompileEnv* envPtr = assemEnvPtr->envPtr;
+				/* Compilation environment */
+    Tcl_Interp* interp = (Tcl_Interp*) envPtr->iPtr;
+				/* Tcl interpreter */
+    BasicBlock* bbPtr = assemEnvPtr->curr_bb;
+				/* Current basic block */
+    JumptableInfo* jtPtr;
+    Tcl_HashTable* jtHashPtr;	/* Hashtable in the JumptableInfo */
+    Tcl_HashEntry* hashEntry;	/* Entry for a key in the hashtable */
+    int isNew;			/* Flag==1 if the key is not yet in the
+				 * table. */
+    int i;
+
+    if (Tcl_ListObjGetElements(interp, jumps, &objc, &objv) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    if (objc % 2 != 0) {
+	if (assemEnvPtr->flags & TCL_EVAL_DIRECT) {
+	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		    "jump table must have an even number of list elements",
+		    -1));
+	    Tcl_SetErrorCode(interp, "TCL", "ASSEM", "BADJUMPTABLE", NULL);
+	}
+	return TCL_ERROR;
+    }
+
+    /*
+     * Allocate the jumptable.
+     */
+
+    jtPtr = ckalloc(sizeof(JumptableInfo));
+    jtHashPtr = &jtPtr->hashTable;
+    Tcl_InitHashTable(jtHashPtr, TCL_STRING_KEYS);
+
+    /*
+     * Fill the keys and labels into the table.
+     */
+
+    DEBUG_PRINT("jump table {\n");
+    for (i = 0; i < objc; i+=2) {
+	DEBUG_PRINT("  %s -> %s\n", Tcl_GetString(objv[i]),
+		Tcl_GetString(objv[i+1]));
+	hashEntry = Tcl_CreateHashEntry(jtHashPtr, Tcl_GetString(objv[i]),
+		&isNew);
+	if (!isNew) {
+	    if (assemEnvPtr->flags & TCL_EVAL_DIRECT) {
+		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+			"duplicate entry in jump table for \"%s\"",
+			Tcl_GetString(objv[i])));
+		Tcl_SetErrorCode(interp, "TCL", "ASSEM", "DUPJUMPTABLEENTRY");
+		DeleteMirrorJumpTable(jtPtr);
+		return TCL_ERROR;
+	    }
+	}
+	Tcl_SetHashValue(hashEntry, objv[i+1]);
+	Tcl_IncrRefCount(objv[i+1]);
+    }
+    DEBUG_PRINT("}\n");
+
+    /*
+     * Put the mirror jumptable in the basic block struct.
+     */
+
+    bbPtr->jtPtr = jtPtr;
+    return TCL_OK;
+}
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * DeleteMirrorJumpTable --
+ *
+ *	Cleans up a jump table when the basic block is deleted.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static void
+DeleteMirrorJumpTable(
+    JumptableInfo* jtPtr)
+{
+    Tcl_HashTable* jtHashPtr = &jtPtr->hashTable;
+				/* Hash table pointer */
+    Tcl_HashSearch search;	/* Hash search control */
+    Tcl_HashEntry* entry;	/* Hash table entry containing a jump label */
+    Tcl_Obj* label;		/* Jump label from the hash table */
+
+    for (entry = Tcl_FirstHashEntry(jtHashPtr, &search);
+	    entry != NULL;
+	    entry = Tcl_NextHashEntry(&search)) {
+	label = Tcl_GetHashValue(entry);
+	Tcl_DecrRefCount(label);
+	Tcl_SetHashValue(entry, NULL);
+    }
+    Tcl_DeleteHashTable(jtHashPtr);
+    ckfree(jtPtr);
+}
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * GetNextOperand --
+ *
+ *	Retrieves the next operand in sequence from an assembly instruction,
+ *	and makes sure that its value is known at compile time.
+ *
+ * Results:
+ *	If successful, returns TCL_OK and leaves a Tcl_Obj with the operand
+ *	text in *operandObjPtr. In case of failure, returns TCL_ERROR and
+ *	leaves *operandObjPtr untouched.
+ *
+ * Side effects:
+ *	Advances *tokenPtrPtr around the token just processed.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static int
+GetNextOperand(
+    AssemblyEnv* assemEnvPtr,	/* Assembly environment */
+    Tcl_Token** tokenPtrPtr,	/* INPUT/OUTPUT: Pointer to the token holding
+				 * the operand */
+    Tcl_Obj** operandObjPtr)	/* OUTPUT: Tcl object holding the operand text
+				 * with \-substitutions done. */
+{
+    Tcl_Interp* interp = (Tcl_Interp*) assemEnvPtr->envPtr->iPtr;
+    Tcl_Obj* operandObj = Tcl_NewObj();
+
+    if (!TclWordKnownAtCompileTime(*tokenPtrPtr, operandObj)) {
+	Tcl_DecrRefCount(operandObj);
+	if (assemEnvPtr->flags & TCL_EVAL_DIRECT) {
+	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		    "assembly code may not contain substitutions", -1));
+	    Tcl_SetErrorCode(interp, "TCL", "ASSEM", "NOSUBST", NULL);
+	}
+	return TCL_ERROR;
+    }
+    *tokenPtrPtr = TokenAfter(*tokenPtrPtr);
+    Tcl_IncrRefCount(operandObj);
+    *operandObjPtr = operandObj;
+    return TCL_OK;
+}
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * GetBooleanOperand --
+ *
+ *	Retrieves a Boolean operand from the input stream and advances
+ *	the token pointer.
+ *
+ * Results:
+ *	Returns a standard Tcl result (with an error message in the
+ *	interpreter on failure).
+ *
+ * Side effects:
+ *	Stores the Boolean value in (*result) and advances (*tokenPtrPtr)
+ *	to the next token.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static int
+GetBooleanOperand(
+    AssemblyEnv* assemEnvPtr,	/* Assembly environment */
+    Tcl_Token** tokenPtrPtr,	/* Current token from the parser */
+    int* result)		/* OUTPUT: Integer extracted from the token */
+{
+    CompileEnv* envPtr = assemEnvPtr->envPtr;
+				/* Compilation environment */
+    Tcl_Interp* interp = (Tcl_Interp*) envPtr->iPtr;
+				/* Tcl interpreter */
+    Tcl_Token* tokenPtr = *tokenPtrPtr;
+				/* INOUT: Pointer to the next token in the
+				 * source code */
+    Tcl_Obj* intObj;		/* Integer from the source code */
+    int status;			/* Tcl status return */
+
+    /*
+     * Extract the next token as a string.
+     */
+
+    if (GetNextOperand(assemEnvPtr, tokenPtrPtr, &intObj) != TCL_OK) {
+	return TCL_ERROR;
+    }
+
+    /*
+     * Convert to an integer, advance to the next token and return.
+     */
+
+    status = Tcl_GetBooleanFromObj(interp, intObj, result);
+    Tcl_DecrRefCount(intObj);
+    *tokenPtrPtr = TokenAfter(tokenPtr);
+    return status;
+}
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * GetIntegerOperand --
+ *
+ *	Retrieves an integer operand from the input stream and advances the
+ *	token pointer.
+ *
+ * Results:
+ *	Returns a standard Tcl result (with an error message in the
+ *	interpreter on failure).
+ *
+ * Side effects:
+ *	Stores the integer value in (*result) and advances (*tokenPtrPtr) to
+ *	the next token.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static int
+GetIntegerOperand(
+    AssemblyEnv* assemEnvPtr,	/* Assembly environment */
+    Tcl_Token** tokenPtrPtr,	/* Current token from the parser */
+    int* result)		/* OUTPUT: Integer extracted from the token */
+{
+    CompileEnv* envPtr = assemEnvPtr->envPtr;
+				/* Compilation environment */
+    Tcl_Interp* interp = (Tcl_Interp*) envPtr->iPtr;
+				/* Tcl interpreter */
+    Tcl_Token* tokenPtr = *tokenPtrPtr;
+				/* INOUT: Pointer to the next token in the
+				 * source code */
+    Tcl_Obj* intObj;		/* Integer from the source code */
+    int status;			/* Tcl status return */
+
+    /*
+     * Extract the next token as a string.
+     */
+
+    if (GetNextOperand(assemEnvPtr, tokenPtrPtr, &intObj) != TCL_OK) {
+	return TCL_ERROR;
+    }
+
+    /*
+     * Convert to an integer, advance to the next token and return.
+     */
+
+    status = Tcl_GetIntFromObj(interp, intObj, result);
+    Tcl_DecrRefCount(intObj);
+    *tokenPtrPtr = TokenAfter(tokenPtr);
+    return status;
+}
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * GetListIndexOperand --
+ *
+ *	Gets the value of an operand intended to serve as a list index.
+ *
+ * Results:
+ *	Returns a standard Tcl result: TCL_OK if the parse is successful and
+ *	TCL_ERROR (with an appropriate error message) if the parse fails.
+ *
+ * Side effects:
+ *	Stores the list index at '*index'. Values between -1 and 0x7fffffff
+ *	have their natural meaning; values between -2 and -0x80000000
+ *	represent 'end-2-N'.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static int
+GetListIndexOperand(
+    AssemblyEnv* assemEnvPtr,	/* Assembly environment */
+    Tcl_Token** tokenPtrPtr,	/* Current token from the parser */
+    int* result)		/* OUTPUT: Integer extracted from the token */
+{
+    CompileEnv* envPtr = assemEnvPtr->envPtr;
+				/* Compilation environment */
+    Tcl_Interp* interp = (Tcl_Interp*) envPtr->iPtr;
+				/* Tcl interpreter */
+    Tcl_Token* tokenPtr = *tokenPtrPtr;
+				/* INOUT: Pointer to the next token in the
+				 * source code */
+    Tcl_Obj* intObj;		/* Integer from the source code */
+    int status;			/* Tcl status return */
+
+    /*
+     * Extract the next token as a string.
+     */
+
+    if (GetNextOperand(assemEnvPtr, tokenPtrPtr, &intObj) != TCL_OK) {
+	return TCL_ERROR;
+    }
+
+    /*
+     * Convert to an integer, advance to the next token and return.
+     */
+
+    status = TclGetIntForIndex(interp, intObj, -2, result);
+    Tcl_DecrRefCount(intObj);
+    *tokenPtrPtr = TokenAfter(tokenPtr);
+    return status;
+}
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * FindLocalVar --
+ *
+ *	Gets the name of a local variable from the input stream and advances
+ *	the token pointer.
+ *
+ * Results:
+ *	Returns the LVT index of the local variable.  Returns -1 if the
+ *	variable is non-local, not known at compile time, or cannot be
+ *	installed in the LVT (leaving an error message in the interpreter
+ *	result if necessary).
+ *
+ * Side effects:
+ *	Advances the token pointer.  May define a new LVT slot if the variable
+ *	has not yet been seen and the execution context allows for it.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static int
+FindLocalVar(
+    AssemblyEnv* assemEnvPtr,	/* Assembly environment */
+    Tcl_Token** tokenPtrPtr)
+{
+    CompileEnv* envPtr = assemEnvPtr->envPtr;
+				/* Compilation environment */
+    Tcl_Interp* interp = (Tcl_Interp*) envPtr->iPtr;
+				/* Tcl interpreter */
+    Tcl_Token* tokenPtr = *tokenPtrPtr;
+				/* INOUT: Pointer to the next token in the
+				 * source code. */
+    Tcl_Obj* varNameObj;	/* Name of the variable */
+    const char* varNameStr;
+    int varNameLen;
+    int localVar;		/* Index of the variable in the LVT */
+
+    if (GetNextOperand(assemEnvPtr, tokenPtrPtr, &varNameObj) != TCL_OK) {
+	return -1;
+    }
+    varNameStr = Tcl_GetStringFromObj(varNameObj, &varNameLen);
+    if (CheckNamespaceQualifiers(interp, varNameStr, varNameLen)) {
+	Tcl_DecrRefCount(varNameObj);
+	return -1;
+    }
+    localVar = TclFindCompiledLocal(varNameStr, varNameLen, 1, envPtr);
+    Tcl_DecrRefCount(varNameObj);
+    if (localVar == -1) {
+	if (assemEnvPtr->flags & TCL_EVAL_DIRECT) {
+	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		    "cannot use this instruction to create a variable"
+		    " in a non-proc context", -1));
+	    Tcl_SetErrorCode(interp, "TCL", "ASSEM", "LVT", NULL);
+	}
+	return -1;
+    }
+    *tokenPtrPtr = TokenAfter(tokenPtr);
+    return localVar;
+}
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * CheckNamespaceQualifiers --
+ *
+ *	Verify that a variable name has no namespace qualifiers before
+ *	attempting to install it in the LVT.
+ *
+ * Results:
+ *	On success, returns TCL_OK. On failure, returns TCL_ERROR and stores
+ *	an error message in the interpreter result.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static int
+CheckNamespaceQualifiers(
+    Tcl_Interp* interp,		/* Tcl interpreter for error reporting */
+    const char* name,		/* Variable name to check */
+    int nameLen)		/* Length of the variable */
+{
+    const char* p;
+
+    for (p = name; p+2 < name+nameLen;  p++) {
+	if ((*p == ':') && (p[1] == ':')) {
+	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		    "variable \"%s\" is not local", name));
+	    Tcl_SetErrorCode(interp, "TCL", "ASSEM", "NONLOCAL", name, NULL);
+	    return TCL_ERROR;
+	}
+    }
+    return TCL_OK;
+}
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * CheckOneByte --
+ *
+ *	Verify that a constant fits in a single byte in the instruction
+ *	stream.
+ *
+ * Results:
+ *	On success, returns TCL_OK. On failure, returns TCL_ERROR and stores
+ *	an error message in the interpreter result.
+ *
+ * This code is here primarily to verify that instructions like INCR_SCALAR1
+ * are possible on a given local variable. The fact that there is no
+ * INCR_SCALAR4 is puzzling.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static int
+CheckOneByte(
+    Tcl_Interp* interp,		/* Tcl interpreter for error reporting */
+    int value)			/* Value to check */
+{
+    Tcl_Obj* result;		/* Error message */
+
+    if (value < 0 || value > 0xff) {
+	result = Tcl_NewStringObj("operand does not fit in one byte", -1);
+	Tcl_SetObjResult(interp, result);
+	Tcl_SetErrorCode(interp, "TCL", "ASSEM", "1BYTE", NULL);
+	return TCL_ERROR;
+    }
+    return TCL_OK;
+}
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * CheckSignedOneByte --
+ *
+ *	Verify that a constant fits in a single signed byte in the instruction
+ *	stream.
+ *
+ * Results:
+ *	On success, returns TCL_OK. On failure, returns TCL_ERROR and stores
+ *	an error message in the interpreter result.
+ *
+ * This code is here primarily to verify that instructions like INCR_SCALAR1
+ * are possible on a given local variable. The fact that there is no
+ * INCR_SCALAR4 is puzzling.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static int
+CheckSignedOneByte(
+    Tcl_Interp* interp,		/* Tcl interpreter for error reporting */
+    int value)			/* Value to check */
+{
+    Tcl_Obj* result;		/* Error message */
+
+    if (value > 0x7f || value < -0x80) {
+	result = Tcl_NewStringObj("operand does not fit in one byte", -1);
+	Tcl_SetObjResult(interp, result);
+	Tcl_SetErrorCode(interp, "TCL", "ASSEM", "1BYTE", NULL);
+	return TCL_ERROR;
+    }
+    return TCL_OK;
+}
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * CheckNonNegative --
+ *
+ *	Verify that a constant is nonnegative
+ *
+ * Results:
+ *	On success, returns TCL_OK. On failure, returns TCL_ERROR and stores
+ *	an error message in the interpreter result.
+ *
+ * This code is here primarily to verify that instructions like INCR_INVOKE
+ * are consuming a positive number of operands
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static int
+CheckNonNegative(
+    Tcl_Interp* interp,		/* Tcl interpreter for error reporting */
+    int value)			/* Value to check */
+{
+    Tcl_Obj* result;		/* Error message */
+
+    if (value < 0) {
+	result = Tcl_NewStringObj("operand must be nonnegative", -1);
+	Tcl_SetObjResult(interp, result);
+	Tcl_SetErrorCode(interp, "TCL", "ASSEM", "NONNEGATIVE", NULL);
+	return TCL_ERROR;
+    }
+    return TCL_OK;
+}
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * CheckStrictlyPositive --
+ *
+ *	Verify that a constant is positive
+ *
+ * Results:
+ *	On success, returns TCL_OK. On failure, returns TCL_ERROR and
+ *	stores an error message in the interpreter result.
+ *
+ * This code is here primarily to verify that instructions like INCR_INVOKE
+ * are consuming a positive number of operands
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static int
+CheckStrictlyPositive(
+    Tcl_Interp* interp,		/* Tcl interpreter for error reporting */
+    int value)			/* Value to check */
+{
+    Tcl_Obj* result;		/* Error message */
+
+    if (value <= 0) {
+	result = Tcl_NewStringObj("operand must be positive", -1);
+	Tcl_SetObjResult(interp, result);
+	Tcl_SetErrorCode(interp, "TCL", "ASSEM", "POSITIVE", NULL);
+	return TCL_ERROR;
+    }
+    return TCL_OK;
+}
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * DefineLabel --
+ *
+ *	Defines a label appearing in the assembly sequence.
+ *
+ * Results:
+ *	Returns a standard Tcl result. Returns TCL_OK and an empty result if
+ *	the definition succeeds; returns TCL_ERROR and an appropriate message
+ *	if a duplicate definition is found.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static int
+DefineLabel(
+    AssemblyEnv* assemEnvPtr,	/* Assembly environment */
+    const char* labelName)	/* Label being defined */
+{
+    CompileEnv* envPtr = assemEnvPtr->envPtr;
+				/* Compilation environment */
+    Tcl_Interp* interp = (Tcl_Interp*) envPtr->iPtr;
+				/* Tcl interpreter */
+    Tcl_HashEntry* entry;	/* Label's entry in the symbol table */
+    int isNew;			/* Flag == 1 iff the label was previously
+				 * undefined */
+
+    /* TODO - This can now be simplified! */
+
+    StartBasicBlock(assemEnvPtr, BB_FALLTHRU, NULL);
+
+    /*
+     * Look up the newly-defined label in the symbol table.
+     */
+
+    entry = Tcl_CreateHashEntry(&assemEnvPtr->labelHash, labelName, &isNew);
+    if (!isNew) {
+	/*
+	 * This is a duplicate label.
+	 */
+
+	if (assemEnvPtr->flags & TCL_EVAL_DIRECT) {
+	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		    "duplicate definition of label \"%s\"", labelName));
+	    Tcl_SetErrorCode(interp, "TCL", "ASSEM", "DUPLABEL", labelName,
+		    NULL);
+	}
+	return TCL_ERROR;
+    }
+
+    /*
+     * This is the first appearance of the label in the code.
+     */
+
+    Tcl_SetHashValue(entry, assemEnvPtr->curr_bb);
+    return TCL_OK;
+}
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * StartBasicBlock --
+ *
+ *	Starts a new basic block when a label or jump is encountered.
+ *
+ * Results:
+ *	Returns a pointer to the BasicBlock structure of the new
+ *	basic block.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static BasicBlock*
+StartBasicBlock(
+    AssemblyEnv* assemEnvPtr,	/* Assembly environment */
+    int flags,			/* Flags to apply to the basic block being
+				 * closed, if there is one. */
+    Tcl_Obj* jumpLabel)		/* Label of the location that the block jumps
+				 * to, or NULL if the block does not jump */
+{
+    CompileEnv* envPtr = assemEnvPtr->envPtr;
+				/* Compilation environment */
+    BasicBlock* newBB;		/* BasicBlock structure for the new block */
+    BasicBlock* currBB = assemEnvPtr->curr_bb;
+
+    /*
+     * Coalesce zero-length blocks.
+     */
+
+    if (currBB->startOffset == envPtr->codeNext - envPtr->codeStart) {
+	currBB->startLine = assemEnvPtr->cmdLine;
+	return currBB;
+    }
+
+    /*
+     * Make the new basic block.
+     */
+
+    newBB = AllocBB(assemEnvPtr);
+
+    /*
+     * Record the jump target if there is one.
+     */
+
+    currBB->jumpTarget = jumpLabel;
+    if (jumpLabel != NULL) {
+	Tcl_IncrRefCount(currBB->jumpTarget);
+    }
+
+    /*
+     * Record the fallthrough if there is one.
+     */
+
+    currBB->flags |= flags;
+
+    /*
+     * Record the successor block.
+     */
+
+    currBB->successor1 = newBB;
+    assemEnvPtr->curr_bb = newBB;
+    return newBB;
+}
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * AllocBB --
+ *
+ *	Allocates a new basic block
+ *
+ * Results:
+ *	Returns a pointer to the newly allocated block, which is initialized
+ *	to contain no code and begin at the current instruction pointer.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static BasicBlock *
+AllocBB(
+    AssemblyEnv* assemEnvPtr)	/* Assembly environment */
+{
+    CompileEnv* envPtr = assemEnvPtr->envPtr;
+    BasicBlock *bb = ckalloc(sizeof(BasicBlock));
+
+    bb->originalStartOffset =
+	    bb->startOffset = envPtr->codeNext - envPtr->codeStart;
+    bb->startLine = assemEnvPtr->cmdLine + 1;
+    bb->jumpOffset = -1;
+    bb->jumpLine = -1;
+    bb->prevPtr = assemEnvPtr->curr_bb;
+    bb->predecessor = NULL;
+    bb->successor1 = NULL;
+    bb->jumpTarget = NULL;
+    bb->initialStackDepth = 0;
+    bb->minStackDepth = 0;
+    bb->maxStackDepth = 0;
+    bb->finalStackDepth = 0;
+    bb->catchDepth = 0;
+    bb->enclosingCatch = NULL;
+    bb->foreignExceptionBase = -1;
+    bb->foreignExceptionCount = 0;
+    bb->foreignExceptions = NULL;
+    bb->jtPtr = NULL;
+    bb->flags = 0;
+
+    return bb;
+}
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * FinishAssembly --
+ *
+ *	Postprocessing after all bytecode has been generated for a block of
+ *	assembly code.
+ *
+ * Results:
+ *	Returns a standard Tcl result, with an error message left in the
+ *	interpreter if appropriate.
+ *
+ * Side effects:
+ *	The program is checked to see if any undefined labels remain.  The
+ *	initial stack depth of all the basic blocks in the flow graph is
+ *	calculated and saved.  The stack balance on exit is computed, checked
+ *	and saved.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static int
+FinishAssembly(
+    AssemblyEnv* assemEnvPtr)	/* Assembly environment */
+{
+    int mustMove;		/* Amount by which the code needs to be grown
+				 * because of expanding jumps */
+
+    /*
+     * Resolve the targets of all jumps and determine whether code needs to be
+     * moved around.
+     */
+
+    if (CalculateJumpRelocations(assemEnvPtr, &mustMove)) {
+	return TCL_ERROR;
+    }
+
+    /*
+     * Move the code if necessary.
+     */
+
+    if (mustMove) {
+	MoveCodeForJumps(assemEnvPtr, mustMove);
+    }
+
+    /*
+     * Resolve jump target labels to bytecode offsets.
+     */
+
+    FillInJumpOffsets(assemEnvPtr);
+
+    /*
+     * Label each basic block with its catch context. Quit on inconsistency.
+     */
+
+    if (ProcessCatches(assemEnvPtr) != TCL_OK) {
+	return TCL_ERROR;
+    }
+
+    /*
+     * Make sure that no block accessible from a catch's error exit that hasn't
+     * popped the exception stack can throw an exception.
+     */
+
+    if (CheckForThrowInWrongContext(assemEnvPtr) != TCL_OK) {
+	return TCL_ERROR;
+    }
+
+    /*
+     * Compute stack balance throughout the program.
+     */
+
+    if (CheckStack(assemEnvPtr) != TCL_OK) {
+	return TCL_ERROR;
+    }
+
+    /*
+     * TODO - Check for unreachable code. Or maybe not; unreachable code is
+     * Mostly Harmless.
+     */
+
+    return TCL_OK;
+}
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * CalculateJumpRelocations --
+ *
+ *	Calculate any movement that has to be done in the assembly code to
+ *	expand JUMP1 instructions to JUMP4 (because they jump more than a
+ *	1-byte range).
+ *
+ * Results:
+ *	Returns a standard Tcl result, with an appropriate error message if
+ *	anything fails.
+ *
+ * Side effects:
+ *	Sets the 'startOffset' pointer in every basic block to the new origin
+ *	of the block, and turns off JUMP1 flags on instructions that must be
+ *	expanded (and adjusts them to the corresponding JUMP4's).  Does *not*
+ *	store the jump offsets at this point.
+ *
+ *	Sets *mustMove to 1 if and only if at least one instruction changed
+ *	size so the code must be moved.
+ *
+ *	As a side effect, also checks for undefined labels and reports them.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static int
+CalculateJumpRelocations(
+    AssemblyEnv* assemEnvPtr,	/* Assembly environment */
+    int* mustMove)		/* OUTPUT: Number of bytes that have been
+				 * added to the code */
+{
+    CompileEnv* envPtr = assemEnvPtr->envPtr;
+				/* Compilation environment */
+    BasicBlock* bbPtr;		/* Pointer to a basic block being checked */
+    Tcl_HashEntry* entry;	/* Exit label's entry in the symbol table */
+    BasicBlock* jumpTarget;	/* Basic block where the jump goes */
+    int motion;			/* Amount by which the code has expanded */
+    int offset;			/* Offset in the bytecode from a jump
+				 * instruction to its target */
+    unsigned opcode;		/* Opcode in the bytecode being adjusted */
+
+    /*
+     * Iterate through basic blocks as long as a change results in code
+     * expansion.
+     */
+
+    *mustMove = 0;
+    do {
+	motion = 0;
+	for (bbPtr = assemEnvPtr->head_bb;
+		bbPtr != NULL;
+		bbPtr = bbPtr->successor1) {
+	    /*
+	     * Advance the basic block start offset by however many bytes we
+	     * have inserted in the code up to this point
+	     */
+
+	    bbPtr->startOffset += motion;
+
+	    /*
+	     * If the basic block references a label (and hence performs a
+	     * jump), find the location of the label. Report an error if the
+	     * label is missing.
+	     */
+
+	    if (bbPtr->jumpTarget != NULL) {
+		entry = Tcl_FindHashEntry(&assemEnvPtr->labelHash,
+			Tcl_GetString(bbPtr->jumpTarget));
+		if (entry == NULL) {
+		    ReportUndefinedLabel(assemEnvPtr, bbPtr,
+			    bbPtr->jumpTarget);
+		    return TCL_ERROR;
+		}
+
+		/*
+		 * If the instruction is a JUMP1, turn it into a JUMP4 if its
+		 * target is out of range.
+		 */
+
+		jumpTarget = Tcl_GetHashValue(entry);
+		if (bbPtr->flags & BB_JUMP1) {
+		    offset = jumpTarget->startOffset
+			    - (bbPtr->jumpOffset + motion);
+		    if (offset < -0x80 || offset > 0x7f) {
+			opcode = TclGetUInt1AtPtr(envPtr->codeStart
+				+ bbPtr->jumpOffset);
+			++opcode;
+			TclStoreInt1AtPtr(opcode,
+				envPtr->codeStart + bbPtr->jumpOffset);
+			motion += 3;
+			bbPtr->flags &= ~BB_JUMP1;
+		    }
+		}
+	    }
+
+	    /*
+	     * If the basic block references a jump table, that doesn't affect
+	     * the code locations, but resolve the labels now, and store basic
+	     * block pointers in the jumptable hash.
+	     */
+
+	    if (bbPtr->flags & BB_JUMPTABLE) {
+		if (CheckJumpTableLabels(assemEnvPtr, bbPtr) != TCL_OK) {
+		    return TCL_ERROR;
+		}
+	    }
+	}
+	*mustMove += motion;
+    } while (motion != 0);
+
+    return TCL_OK;
+}
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * CheckJumpTableLabels --
+ *
+ *	Make sure that all the labels in a jump table are defined.
+ *
+ * Results:
+ *	Returns TCL_OK if they are, TCL_ERROR if they aren't.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static int
+CheckJumpTableLabels(
+    AssemblyEnv* assemEnvPtr,	/* Assembly environment */
+    BasicBlock* bbPtr)		/* Basic block that ends in a jump table */
+{
+    Tcl_HashTable* symHash = &bbPtr->jtPtr->hashTable;
+				/* Hash table with the symbols */
+    Tcl_HashSearch search;	/* Hash table iterator */
+    Tcl_HashEntry* symEntryPtr;	/* Hash entry for the symbols */
+    Tcl_Obj* symbolObj;		/* Jump target */
+    Tcl_HashEntry* valEntryPtr;	/* Hash entry for the resolutions */
+
+    /*
+     * Look up every jump target in the jump hash.
+     */
+
+    DEBUG_PRINT("check jump table labels %p {\n", bbPtr);
+    for (symEntryPtr = Tcl_FirstHashEntry(symHash, &search);
+	    symEntryPtr != NULL;
+	    symEntryPtr = Tcl_NextHashEntry(&search)) {
+	symbolObj = Tcl_GetHashValue(symEntryPtr);
+	valEntryPtr = Tcl_FindHashEntry(&assemEnvPtr->labelHash,
+		Tcl_GetString(symbolObj));
+	DEBUG_PRINT("  %s -> %s (%d)\n",
+		(char*) Tcl_GetHashKey(symHash, symEntryPtr),
+		Tcl_GetString(symbolObj), (valEntryPtr != NULL));
+	if (valEntryPtr == NULL) {
+	    ReportUndefinedLabel(assemEnvPtr, bbPtr, symbolObj);
+	    return TCL_ERROR;
+	}
+    }
+    DEBUG_PRINT("}\n");
+    return TCL_OK;
+}
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * ReportUndefinedLabel --
+ *
+ *	Report that a basic block refers to an undefined jump label
+ *
+ * Side effects:
+ *	Stores an error message, error code, and line number information in
+ *	the assembler's Tcl interpreter.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static void
+ReportUndefinedLabel(
+    AssemblyEnv* assemEnvPtr,	/* Assembly environment */
+    BasicBlock* bbPtr,		/* Basic block that contains the undefined
+				 * label */
+    Tcl_Obj* jumpTarget)	/* Label of a jump target */
+{
+    CompileEnv* envPtr = assemEnvPtr->envPtr;
+				/* Compilation environment */
+    Tcl_Interp* interp = (Tcl_Interp*) envPtr->iPtr;
+				/* Tcl interpreter */
+
+    if (assemEnvPtr->flags & TCL_EVAL_DIRECT) {
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		"undefined label \"%s\"", Tcl_GetString(jumpTarget)));
+	Tcl_SetErrorCode(interp, "TCL", "ASSEM", "NOLABEL",
+		Tcl_GetString(jumpTarget), NULL);
+	Tcl_SetErrorLine(interp, bbPtr->jumpLine);
+    }
+}
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * MoveCodeForJumps --
+ *
+ *	Move bytecodes in memory to accommodate JUMP1 instructions that have
+ *	expanded to become JUMP4's.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static void
+MoveCodeForJumps(
+    AssemblyEnv* assemEnvPtr,	/* Assembler environment */
+    int mustMove)		/* Number of bytes of added code */
+{
+    CompileEnv* envPtr = assemEnvPtr->envPtr;
+				/* Compilation environment */
+    BasicBlock* bbPtr;		/* Pointer to a basic block being checked */
+    int topOffset;		/* Bytecode offset of the following basic
+				 * block before code motion */
+
+    /*
+     * Make sure that there is enough space in the bytecode array to
+     * accommodate the expanded code.
+     */
+
+    while (envPtr->codeEnd < envPtr->codeNext + mustMove) {
+	TclExpandCodeArray(envPtr);
+    }
+
+    /*
+     * Iterate through the bytecodes in reverse order, and move them upward to
+     * their new homes.
+     */
+
+    topOffset = envPtr->codeNext - envPtr->codeStart;
+    for (bbPtr = assemEnvPtr->curr_bb; bbPtr != NULL; bbPtr = bbPtr->prevPtr) {
+	DEBUG_PRINT("move code from %d to %d\n",
+		bbPtr->originalStartOffset, bbPtr->startOffset);
+	memmove(envPtr->codeStart + bbPtr->startOffset,
+		envPtr->codeStart + bbPtr->originalStartOffset,
+		topOffset - bbPtr->originalStartOffset);
+	topOffset = bbPtr->originalStartOffset;
+	bbPtr->jumpOffset += (bbPtr->startOffset - bbPtr->originalStartOffset);
+    }
+    envPtr->codeNext += mustMove;
+}
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * FillInJumpOffsets --
+ *
+ *	Fill in the final offsets of all jump instructions once bytecode
+ *	locations have been completely determined.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static void
+FillInJumpOffsets(
+    AssemblyEnv* assemEnvPtr)	/* Assembly environment */
+{
+    CompileEnv* envPtr = assemEnvPtr->envPtr;
+				/* Compilation environment */
+    BasicBlock* bbPtr;		/* Pointer to a basic block being checked */
+    Tcl_HashEntry* entry;	/* Hashtable entry for a jump target label */
+    BasicBlock* jumpTarget;	/* Basic block where a jump goes */
+    int fromOffset;		/* Bytecode location of a jump instruction */
+    int targetOffset;		/* Bytecode location of a jump instruction's
+				 * target */
+
+    for (bbPtr = assemEnvPtr->head_bb;
+	    bbPtr != NULL;
+	    bbPtr = bbPtr->successor1) {
+	if (bbPtr->jumpTarget != NULL) {
+	    entry = Tcl_FindHashEntry(&assemEnvPtr->labelHash,
+		    Tcl_GetString(bbPtr->jumpTarget));
+	    jumpTarget = Tcl_GetHashValue(entry);
+	    fromOffset = bbPtr->jumpOffset;
+	    targetOffset = jumpTarget->startOffset;
+	    if (bbPtr->flags & BB_JUMP1) {
+		TclStoreInt1AtPtr(targetOffset - fromOffset,
+			envPtr->codeStart + fromOffset + 1);
+	    } else {
+		TclStoreInt4AtPtr(targetOffset - fromOffset,
+			envPtr->codeStart + fromOffset + 1);
+	    }
+	}
+	if (bbPtr->flags & BB_JUMPTABLE) {
+	    ResolveJumpTableTargets(assemEnvPtr, bbPtr);
+	}
+    }
+}
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * ResolveJumpTableTargets --
+ *
+ *	Puts bytecode addresses for the targets of a jumptable into the
+ *	table
+ *
+ * Results:
+ *	Returns TCL_OK if they are, TCL_ERROR if they aren't.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static void
+ResolveJumpTableTargets(
+    AssemblyEnv* assemEnvPtr,	/* Assembly environment */
+    BasicBlock* bbPtr)		/* Basic block that ends in a jump table */
+{
+    CompileEnv* envPtr = assemEnvPtr->envPtr;
+				/* Compilation environment */
+    Tcl_HashTable* symHash = &bbPtr->jtPtr->hashTable;
+				/* Hash table with the symbols */
+    Tcl_HashSearch search;	/* Hash table iterator */
+    Tcl_HashEntry* symEntryPtr;	/* Hash entry for the symbols */
+    Tcl_Obj* symbolObj;		/* Jump target */
+    Tcl_HashEntry* valEntryPtr;	/* Hash entry for the resolutions */
+    int auxDataIndex;		/* Index of the auxdata */
+    JumptableInfo* realJumpTablePtr;
+				/* Jump table in the actual code */
+    Tcl_HashTable* realJumpHashPtr;
+				/* Jump table hash in the actual code */
+    Tcl_HashEntry* realJumpEntryPtr;
+				/* Entry in the jump table hash in
+				 * the actual code */
+    BasicBlock* jumpTargetBBPtr;
+				/* Basic block that the jump proceeds to */
+    int junk;
+
+    auxDataIndex = TclGetInt4AtPtr(envPtr->codeStart + bbPtr->jumpOffset + 1);
+    DEBUG_PRINT("bbPtr = %p jumpOffset = %d auxDataIndex = %d\n",
+	    bbPtr, bbPtr->jumpOffset, auxDataIndex);
+    realJumpTablePtr = TclFetchAuxData(envPtr, auxDataIndex);
+    realJumpHashPtr = &realJumpTablePtr->hashTable;
+
+    /*
+     * Look up every jump target in the jump hash.
+     */
+
+    DEBUG_PRINT("resolve jump table {\n");
+    for (symEntryPtr = Tcl_FirstHashEntry(symHash, &search);
+	    symEntryPtr != NULL;
+	    symEntryPtr = Tcl_NextHashEntry(&search)) {
+	symbolObj = Tcl_GetHashValue(symEntryPtr);
+	DEBUG_PRINT("     symbol %s\n", Tcl_GetString(symbolObj));
+
+	valEntryPtr = Tcl_FindHashEntry(&assemEnvPtr->labelHash,
+		Tcl_GetString(symbolObj));
+	jumpTargetBBPtr = Tcl_GetHashValue(valEntryPtr);
+
+	realJumpEntryPtr = Tcl_CreateHashEntry(realJumpHashPtr,
+		Tcl_GetHashKey(symHash, symEntryPtr), &junk);
+	DEBUG_PRINT("  %s -> %s -> bb %p (pc %d)    hash entry %p\n",
+		(char*) Tcl_GetHashKey(symHash, symEntryPtr),
+		Tcl_GetString(symbolObj), jumpTargetBBPtr,
+		jumpTargetBBPtr->startOffset, realJumpEntryPtr);
+
+	Tcl_SetHashValue(realJumpEntryPtr,
+		INT2PTR(jumpTargetBBPtr->startOffset - bbPtr->jumpOffset));
+    }
+    DEBUG_PRINT("}\n");
+}
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * CheckForThrowInWrongContext --
+ *
+ *	Verify that no beginCatch/endCatch sequence can throw an exception
+ *	after an original exception is caught and before its exception context
+ *	is removed from the stack.
+ *
+ * Results:
+ *	Returns a standard Tcl result.
+ *
+ * Side effects:
+ *	Stores an appropriate error message in the interpreter as needed.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static int
+CheckForThrowInWrongContext(
+    AssemblyEnv* assemEnvPtr)	/* Assembly environment */
+{
+    BasicBlock* blockPtr;	/* Current basic block */
+
+    /*
+     * Walk through the basic blocks in turn, checking all the ones that have
+     * caught an exception and not disposed of it properly.
+     */
+
+    for (blockPtr = assemEnvPtr->head_bb;
+	    blockPtr != NULL;
+	    blockPtr = blockPtr->successor1) {
+	if (blockPtr->catchState == BBCS_CAUGHT) {
+	    /*
+	     * Walk through the instructions in the basic block.
+	     */
+
+	    if (CheckNonThrowingBlock(assemEnvPtr, blockPtr) != TCL_OK) {
+		return TCL_ERROR;
+	    }
+	}
+    }
+    return TCL_OK;
+}
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * CheckNonThrowingBlock --
+ *
+ *	Check that a basic block cannot throw an exception.
+ *
+ * Results:
+ *	Returns TCL_ERROR if the block cannot be proven to be nonthrowing.
+ *
+ * Side effects:
+ *	Stashes an error message in the interpreter result.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static int
+CheckNonThrowingBlock(
+    AssemblyEnv* assemEnvPtr,	/* Assembly environment */
+    BasicBlock* blockPtr)	/* Basic block where exceptions are not
+				 * allowed */
+{
+    CompileEnv* envPtr = assemEnvPtr->envPtr;
+				/* Compilation environment */
+    Tcl_Interp* interp = (Tcl_Interp*) envPtr->iPtr;
+				/* Tcl interpreter */
+    BasicBlock* nextPtr;	/* Pointer to the succeeding basic block */
+    int offset;			/* Bytecode offset of the current
+				 * instruction */
+    int bound;			/* Bytecode offset following the last
+				 * instruction of the block. */
+    unsigned char opcode;	/* Current bytecode instruction */
+
+    /*
+     * Determine where in the code array the basic block ends.
+     */
+
+    nextPtr = blockPtr->successor1;
+    if (nextPtr == NULL) {
+	bound = envPtr->codeNext - envPtr->codeStart;
+    } else {
+	bound = nextPtr->startOffset;
+    }
+
+    /*
+     * Walk through the instructions of the block.
+     */
+
+    offset = blockPtr->startOffset;
+    while (offset < bound) {
+	/*
+	 * Determine whether an instruction is nonthrowing.
+	 */
+
+	opcode = (envPtr->codeStart)[offset];
+	if (BytecodeMightThrow(opcode)) {
+	    /*
+	     * Report an error for a throw in the wrong context.
+	     */
+
+	    if (assemEnvPtr->flags & TCL_EVAL_DIRECT) {
+		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+			"\"%s\" instruction may not appear in "
+			"a context where an exception has been "
+			"caught and not disposed of.",
+			tclInstructionTable[opcode].name));
+		Tcl_SetErrorCode(interp, "TCL", "ASSEM", "BADTHROW", NULL);
+		AddBasicBlockRangeToErrorInfo(assemEnvPtr, blockPtr);
+	    }
+	    return TCL_ERROR;
+	}
+	offset += tclInstructionTable[opcode].numBytes;
+    }
+    return TCL_OK;
+}
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * BytecodeMightThrow --
+ *
+ *	Tests if a given bytecode instruction might throw an exception.
+ *
+ * Results:
+ *	Returns 1 if the bytecode might throw an exception, 0 if the
+ *	instruction is known never to throw.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static int
+BytecodeMightThrow(
+    unsigned char opcode)
+{
+    /*
+     * Binary search on the non-throwing bytecode list.
+     */
+
+    int min = 0;
+    int max = sizeof(NonThrowingByteCodes) - 1;
+    int mid;
+    unsigned char c;
+
+    while (max >= min) {
+	mid = (min + max) / 2;
+	c = NonThrowingByteCodes[mid];
+	if (opcode < c) {
+	    max = mid-1;
+	} else if (opcode > c) {
+	    min = mid+1;
+	} else {
+	    /*
+	     * Opcode is nonthrowing.
+	     */
+
+	    return 0;
+	}
+    }
+
+    return 1;
+}
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * CheckStack --
+ *
+ *	Audit stack usage in a block of assembly code.
+ *
+ * Results:
+ *	Returns a standard Tcl result.
+ *
+ * Side effects:
+ *	Updates stack depth on entry for all basic blocks in the flowgraph.
+ *	Calculates the max stack depth used in the program, and updates the
+ *	compilation environment to reflect it.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static int
+CheckStack(
+    AssemblyEnv* assemEnvPtr)	/* Assembly environment */
+{
+    CompileEnv* envPtr = assemEnvPtr->envPtr;
+				/* Compilation environment */
+    int maxDepth;		/* Maximum stack depth overall */
+
+    /*
+     * Checking the head block will check all the other blocks recursively.
+     */
+
+    assemEnvPtr->maxDepth = 0;
+    if (StackCheckBasicBlock(assemEnvPtr, assemEnvPtr->head_bb, NULL,
+	    0) == TCL_ERROR) {
+	return TCL_ERROR;
+    }
+
+    /*
+     * Post the max stack depth back to the compilation environment.
+     */
+
+    maxDepth = assemEnvPtr->maxDepth + envPtr->currStackDepth;
+    if (maxDepth > envPtr->maxStackDepth) {
+	envPtr->maxStackDepth = maxDepth;
+    }
+
+    /*
+     * If the exit is reachable, make sure that the program exits with 1
+     * operand on the stack.
+     */
+
+    if (StackCheckExit(assemEnvPtr) != TCL_OK) {
+	return TCL_ERROR;
+    }
+
+    /*
+     * Reset the visited state on all basic blocks.
+     */
+
+    ResetVisitedBasicBlocks(assemEnvPtr);
+    return TCL_OK;
+}
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * StackCheckBasicBlock --
+ *
+ *	Checks stack consumption for a basic block (and recursively for its
+ *	successors).
+ *
+ * Results:
+ *	Returns a standard Tcl result.
+ *
+ * Side effects:
+ *	Updates initial stack depth for the basic block and its successors.
+ *	(Final and maximum stack depth are relative to initial, and are not
+ *	touched).
+ *
+ * This procedure eventually checks, for the entire flow graph, whether stack
+ * balance is consistent.  It is an error for a given basic block to be
+ * reachable along multiple flow paths with different stack depths.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static int
+StackCheckBasicBlock(
+    AssemblyEnv* assemEnvPtr,	/* Assembly environment */
+    BasicBlock* blockPtr,	/* Pointer to the basic block being checked */
+    BasicBlock* predecessor,	/* Pointer to the block that passed control to
+				 * this one. */
+    int initialStackDepth)	/* Stack depth on entry to the block */
+{
+    CompileEnv* envPtr = assemEnvPtr->envPtr;
+				/* Compilation environment */
+    Tcl_Interp* interp = (Tcl_Interp*) envPtr->iPtr;
+				/* Tcl interpreter */
+    BasicBlock* jumpTarget;	/* Basic block where a jump goes */
+    int stackDepth;		/* Current stack depth */
+    int maxDepth;		/* Maximum stack depth so far */
+    int result;			/* Tcl status return */
+    Tcl_HashSearch jtSearch;	/* Search structure for the jump table */
+    Tcl_HashEntry* jtEntry;	/* Hash entry in the jump table */
+    Tcl_Obj* targetLabel;	/* Target label from the jump table */
+    Tcl_HashEntry* entry;	/* Hash entry in the label table */
+
+    if (blockPtr->flags & BB_VISITED) {
+	/*
+	 * If the block is already visited, check stack depth for consistency
+	 * among the paths that reach it.
+	 */
+
+	if (blockPtr->initialStackDepth == initialStackDepth) {
+	    return TCL_OK;
+	}
+	if (assemEnvPtr->flags & TCL_EVAL_DIRECT) {
+	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		    "inconsistent stack depths on two execution paths", -1));
+
+	    /*
+	     * TODO - add execution trace of both paths
+	     */
+
+	    Tcl_SetErrorLine(interp, blockPtr->startLine);
+	    Tcl_SetErrorCode(interp, "TCL", "ASSEM", "BADSTACK", NULL);
+	}
+	return TCL_ERROR;
+    }
+
+    /*
+     * If the block is not already visited, set the 'predecessor' link to
+     * indicate how control got to it. Set the initial stack depth to the
+     * current stack depth in the flow of control.
+     */
+
+    blockPtr->flags |= BB_VISITED;
+    blockPtr->predecessor = predecessor;
+    blockPtr->initialStackDepth = initialStackDepth;
+
+    /*
+     * Calculate minimum stack depth, and flag an error if the block
+     * underflows the stack.
+     */
+
+    if (initialStackDepth + blockPtr->minStackDepth < 0) {
+	if (assemEnvPtr->flags & TCL_EVAL_DIRECT) {
+	    Tcl_SetObjResult(interp, Tcl_NewStringObj("stack underflow", -1));
+	    Tcl_SetErrorCode(interp, "TCL", "ASSEM", "BADSTACK", NULL);
+	    AddBasicBlockRangeToErrorInfo(assemEnvPtr, blockPtr);
+	    Tcl_SetErrorLine(interp, blockPtr->startLine);
+	}
+	return TCL_ERROR;
+    }
+
+    /*
+     * Make sure that the block doesn't try to pop below the stack level of an
+     * enclosing catch.
+     */
+
+    if (blockPtr->enclosingCatch != 0 &&
+	    initialStackDepth + blockPtr->minStackDepth
+	    < (blockPtr->enclosingCatch->initialStackDepth
+		+ blockPtr->enclosingCatch->finalStackDepth)) {
+	if (assemEnvPtr->flags & TCL_EVAL_DIRECT) {
+	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		    "code pops stack below level of enclosing catch", -1));
+	    Tcl_SetErrorCode(interp, "TCL", "ASSEM", "BADSTACKINCATCH", -1);
+	    AddBasicBlockRangeToErrorInfo(assemEnvPtr, blockPtr);
+	    Tcl_SetErrorLine(interp, blockPtr->startLine);
+	}
+	return TCL_ERROR;
+    }
+
+    /*
+     * Update maximum stgack depth.
+     */
+
+    maxDepth = initialStackDepth + blockPtr->maxStackDepth;
+    if (maxDepth > assemEnvPtr->maxDepth) {
+	assemEnvPtr->maxDepth = maxDepth;
+    }
+
+    /*
+     * Calculate stack depth on exit from the block, and invoke this procedure
+     * recursively to check successor blocks.
+     */
+
+    stackDepth = initialStackDepth + blockPtr->finalStackDepth;
+    result = TCL_OK;
+    if (blockPtr->flags & BB_FALLTHRU) {
+	result = StackCheckBasicBlock(assemEnvPtr, blockPtr->successor1,
+		blockPtr, stackDepth);
+    }
+
+    if (result == TCL_OK && blockPtr->jumpTarget != NULL) {
+	entry = Tcl_FindHashEntry(&assemEnvPtr->labelHash,
+		Tcl_GetString(blockPtr->jumpTarget));
+	jumpTarget = Tcl_GetHashValue(entry);
+	result = StackCheckBasicBlock(assemEnvPtr, jumpTarget, blockPtr,
+		stackDepth);
+    }
+
+    /*
+     * All blocks referenced in a jump table are successors.
+     */
+
+    if (blockPtr->flags & BB_JUMPTABLE) {
+	for (jtEntry = Tcl_FirstHashEntry(&blockPtr->jtPtr->hashTable,
+		    &jtSearch);
+		result == TCL_OK && jtEntry != NULL;
+		jtEntry = Tcl_NextHashEntry(&jtSearch)) {
+	    targetLabel = Tcl_GetHashValue(jtEntry);
+	    entry = Tcl_FindHashEntry(&assemEnvPtr->labelHash,
+		    Tcl_GetString(targetLabel));
+	    jumpTarget = Tcl_GetHashValue(entry);
+	    result = StackCheckBasicBlock(assemEnvPtr, jumpTarget,
+		    blockPtr, stackDepth);
+	}
+    }
+
+    return result;
+}
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * StackCheckExit --
+ *
+ *	Makes sure that the net stack effect of an entire assembly language
+ *	script is to push 1 result.
+ *
+ * Results:
+ *	Returns a standard Tcl result, with an error message in the
+ *	interpreter result if the stack is wrong.
+ *
+ * Side effects:
+ *	If the assembly code had a net stack effect of zero, emits code to the
+ *	concluding block to push a null result. In any case, updates the stack
+ *	depth in the compile environment to reflect the net effect of the
+ *	assembly code.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static int
+StackCheckExit(
+    AssemblyEnv* assemEnvPtr)	/* Assembly environment */
+{
+    CompileEnv* envPtr = assemEnvPtr->envPtr;
+				/* Compilation environment */
+    Tcl_Interp* interp = (Tcl_Interp*) envPtr->iPtr;
+				/* Tcl interpreter */
+    int depth;			/* Net stack effect */
+    int litIndex;		/* Index in the literal pool of the empty
+				 * string */
+    BasicBlock* curr_bb = assemEnvPtr->curr_bb;
+				/* Final basic block in the assembly */
+
+    /*
+     * Don't perform these checks if execution doesn't reach the exit (either
+     * because of an infinite loop or because the only return is from the
+     * middle.
+     */
+
+    if (curr_bb->flags & BB_VISITED) {
+	/*
+	 * Exit with no operands; push an empty one.
+	 */
+
+	depth = curr_bb->finalStackDepth + curr_bb->initialStackDepth;
+	if (depth == 0) {
+	    /*
+	     * Emit a 'push' of the empty literal.
+	     */
+
+	    litIndex = TclRegisterNewLiteral(envPtr, "", 0);
+
+	    /*
+	     * Assumes that 'push' is at slot 0 in TalInstructionTable.
+	     */
+
+	    BBEmitInst1or4(assemEnvPtr, 0, litIndex, 0);
+	    ++depth;
+	}
+
+	/*
+	 * Exit with unbalanced stack.
+	 */
+
+	if (depth != 1) {
+	    if (assemEnvPtr->flags & TCL_EVAL_DIRECT) {
+		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+			"stack is unbalanced on exit from the code (depth=%d)",
+			depth));
+		Tcl_SetErrorCode(interp, "TCL", "ASSEM", "BADSTACK", NULL);
+	    }
+	    return TCL_ERROR;
+	}
+
+	/*
+	 * Record stack usage.
+	 */
+
+	envPtr->currStackDepth += depth;
+    }
+
+    return TCL_OK;
+}
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * ProcessCatches --
+ *
+ *	First pass of 'catch' processing.
+ *
+ * Results:
+ *	Returns a standard Tcl result, with an appropriate error message if
+ *	the result is TCL_ERROR.
+ *
+ * Side effects:
+ *	Labels all basic blocks with their enclosing catches.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static int
+ProcessCatches(
+    AssemblyEnv* assemEnvPtr)	/* Assembly environment */
+{
+    BasicBlock* blockPtr;	/* Pointer to a basic block */
+
+    /*
+     * Clear the catch state of all basic blocks.
+     */
+
+    for (blockPtr = assemEnvPtr->head_bb;
+	    blockPtr != NULL;
+	    blockPtr = blockPtr->successor1) {
+	blockPtr->catchState = BBCS_UNKNOWN;
+	blockPtr->enclosingCatch = NULL;
+    }
+
+    /*
+     * Start the check recursively from the first basic block, which is
+     * outside any exception context
+     */
+
+    if (ProcessCatchesInBasicBlock(assemEnvPtr, assemEnvPtr->head_bb,
+	    NULL, BBCS_NONE, 0) != TCL_OK) {
+	return TCL_ERROR;
+    }
+
+    /*
+     * Check for unclosed catch on exit.
+     */
+
+    if (CheckForUnclosedCatches(assemEnvPtr) != TCL_OK) {
+	return TCL_ERROR;
+    }
+
+    /*
+     * Now there's enough information to build the exception ranges.
+     */
+
+    if (BuildExceptionRanges(assemEnvPtr) != TCL_OK) {
+	return TCL_ERROR;
+    }
+
+    /*
+     * Finally, restore any exception ranges from embedded scripts.
+     */
+
+    RestoreEmbeddedExceptionRanges(assemEnvPtr);
+    return TCL_OK;
+}
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * ProcessCatchesInBasicBlock --
+ *
+ *	First-pass catch processing for one basic block.
+ *
+ * Results:
+ *	Returns a standard Tcl result, with error message in the interpreter
+ *	result if an error occurs.
+ *
+ * This procedure checks consistency of the exception context through the
+ * assembler program, and records the enclosing 'catch' for every basic block.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static int
+ProcessCatchesInBasicBlock(
+    AssemblyEnv* assemEnvPtr,	/* Assembly environment */
+    BasicBlock* bbPtr,		/* Basic block being processed */
+    BasicBlock* enclosing,	/* Start basic block of the enclosing catch */
+    enum BasicBlockCatchState state,
+				/* BBCS_NONE, BBCS_INCATCH, or BBCS_CAUGHT */
+    int catchDepth)		/* Depth of nesting of catches */
+{
+    CompileEnv* envPtr = assemEnvPtr->envPtr;
+				/* Compilation environment */
+    Tcl_Interp* interp = (Tcl_Interp*) envPtr->iPtr;
+				/* Tcl interpreter */
+    int result;			/* Return value from this procedure */
+    BasicBlock* fallThruEnclosing;
+				/* Enclosing catch if execution falls thru */
+    enum BasicBlockCatchState fallThruState;
+				/* Catch state of the successor block */
+    BasicBlock* jumpEnclosing;	/* Enclosing catch if execution goes to jump
+				 * target */
+    enum BasicBlockCatchState jumpState;
+				/* Catch state of the jump target */
+    int changed = 0;		/* Flag == 1 iff successor blocks need to be
+				 * checked because the state of this block has
+				 * changed. */
+    BasicBlock* jumpTarget;	/* Basic block where a jump goes */
+    Tcl_HashSearch jtSearch;	/* Hash search control for a jumptable */
+    Tcl_HashEntry* jtEntry;	/* Entry in a jumptable */
+    Tcl_Obj* targetLabel;	/* Target label from a jumptable */
+    Tcl_HashEntry* entry;	/* Entry from the label table */
+
+    /*
+     * Update the state of the current block, checking for consistency.  Set
+     * 'changed' to 1 if the state changes and successor blocks need to be
+     * rechecked.
+     */
+
+    if (bbPtr->catchState == BBCS_UNKNOWN) {
+	bbPtr->enclosingCatch = enclosing;
+    } else if (bbPtr->enclosingCatch != enclosing) {
+	if (assemEnvPtr->flags & TCL_EVAL_DIRECT) {
+	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		    "execution reaches an instruction in inconsistent "
+		    "exception contexts", -1));
+	    Tcl_SetErrorLine(interp, bbPtr->startLine);
+	    Tcl_SetErrorCode(interp, "TCL", "ASSEM", "BADCATCH", NULL);
+	}
+	return TCL_ERROR;
+    }
+    if (state > bbPtr->catchState) {
+	bbPtr->catchState = state;
+	changed = 1;
+    }
+
+    /*
+     * If this block has been visited before, and its state hasn't changed,
+     * we're done with it for now.
+     */
+
+    if (!changed) {
+	return TCL_OK;
+    }
+    bbPtr->catchDepth = catchDepth;
+
+    /*
+     * Determine enclosing catch and 'caught' state for the fallthrough and
+     * the jump target. Default for both is the state of the current block.
+     */
+
+    fallThruEnclosing = enclosing;
+    fallThruState = state;
+    jumpEnclosing = enclosing;
+    jumpState = state;
+
+    /*
+     * TODO: Make sure that the test cases include validating that a natural
+     * loop can't include 'beginCatch' or 'endCatch'
+     */
+
+    if (bbPtr->flags & BB_BEGINCATCH) {
+	/*
+	 * If the block begins a catch, the state for the successor is 'in
+	 * catch'. The jump target is the exception exit, and the state of the
+	 * jump target is 'caught.'
+	 */
+
+	fallThruEnclosing = bbPtr;
+	fallThruState = BBCS_INCATCH;
+	jumpEnclosing = bbPtr;
+	jumpState = BBCS_CAUGHT;
+	++catchDepth;
+    }
+
+    if (bbPtr->flags & BB_ENDCATCH) {
+	/*
+	 * If the block ends a catch, the state for the successor is whatever
+	 * the state was on entry to the catch.
+	 */
+
+	if (enclosing == NULL) {
+	    if (assemEnvPtr->flags & TCL_EVAL_DIRECT) {
+		Tcl_SetObjResult(interp, Tcl_NewStringObj(
+			"endCatch without a corresponding beginCatch", -1));
+		Tcl_SetErrorLine(interp, bbPtr->startLine);
+		Tcl_SetErrorCode(interp, "TCL", "ASSEM", "BADENDCATCH", NULL);
+	    }
+	    return TCL_ERROR;
+	}
+	fallThruEnclosing = enclosing->enclosingCatch;
+	fallThruState = enclosing->catchState;
+	--catchDepth;
+    }
+
+    /*
+     * Visit any successor blocks with the appropriate exception context
+     */
+
+    result = TCL_OK;
+    if (bbPtr->flags & BB_FALLTHRU) {
+	result = ProcessCatchesInBasicBlock(assemEnvPtr, bbPtr->successor1,
+		fallThruEnclosing, fallThruState, catchDepth);
+    }
+    if (result == TCL_OK && bbPtr->jumpTarget != NULL) {
+	entry = Tcl_FindHashEntry(&assemEnvPtr->labelHash,
+		Tcl_GetString(bbPtr->jumpTarget));
+	jumpTarget = Tcl_GetHashValue(entry);
+	result = ProcessCatchesInBasicBlock(assemEnvPtr, jumpTarget,
+		jumpEnclosing, jumpState, catchDepth);
+    }
+
+    /*
+     * All blocks referenced in a jump table are successors.
+     */
+
+    if (bbPtr->flags & BB_JUMPTABLE) {
+	for (jtEntry = Tcl_FirstHashEntry(&bbPtr->jtPtr->hashTable,&jtSearch);
+		result == TCL_OK && jtEntry != NULL;
+		jtEntry = Tcl_NextHashEntry(&jtSearch)) {
+	    targetLabel = Tcl_GetHashValue(jtEntry);
+	    entry = Tcl_FindHashEntry(&assemEnvPtr->labelHash,
+		    Tcl_GetString(targetLabel));
+	    jumpTarget = Tcl_GetHashValue(entry);
+	    result = ProcessCatchesInBasicBlock(assemEnvPtr, jumpTarget,
+		    jumpEnclosing, jumpState, catchDepth);
+	}
+    }
+
+    return result;
+}
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * CheckForUnclosedCatches --
+ *
+ *	Checks that a sequence of assembly code has no unclosed catches on
+ *	exit.
+ *
+ * Results:
+ *	Returns a standard Tcl result, with an error message for unclosed
+ *	catches.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static int
+CheckForUnclosedCatches(
+    AssemblyEnv* assemEnvPtr)	/* Assembly environment */
+{
+    CompileEnv* envPtr = assemEnvPtr->envPtr;
+				/* Compilation environment */
+    Tcl_Interp* interp = (Tcl_Interp*) envPtr->iPtr;
+				/* Tcl interpreter */
+
+    if (assemEnvPtr->curr_bb->catchState >= BBCS_INCATCH) {
+	if (assemEnvPtr->flags & TCL_EVAL_DIRECT) {
+	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		    "catch still active on exit from assembly code", -1));
+	    Tcl_SetErrorLine(interp,
+		    assemEnvPtr->curr_bb->enclosingCatch->startLine);
+	    Tcl_SetErrorCode(interp, "TCL", "ASSEM", "UNCLOSEDCATCH", NULL);
+	}
+	return TCL_ERROR;
+    }
+    return TCL_OK;
+}
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * BuildExceptionRanges --
+ *
+ *	Walks through the assembly code and builds exception ranges for the
+ *	catches embedded therein.
+ *
+ * Results:
+ *	Returns a standard Tcl result with an error message in the interpreter
+ *	if anything is unsuccessful.
+ *
+ * Side effects:
+ *	Each contiguous block of code with a given catch exit is assigned an
+ *	exception range at the appropriate level.
+ *	Exception ranges in embedded blocks have their levels corrected and
+ *	collated into the table.
+ *	Blocks that end with 'beginCatch' are associated with the innermost
+ *	exception range of the following block.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static int
+BuildExceptionRanges(
+    AssemblyEnv* assemEnvPtr)	/* Assembly environment */
+{
+    CompileEnv* envPtr = assemEnvPtr->envPtr;
+				/* Compilation environment */
+    BasicBlock* bbPtr;		/* Current basic block */
+    BasicBlock* prevPtr = NULL;	/* Previous basic block */
+    int catchDepth = 0;		/* Current catch depth */
+    int maxCatchDepth = 0;	/* Maximum catch depth in the program */
+    BasicBlock** catches;	/* Stack of catches in progress */
+    int* catchIndices;		/* Indices of the exception ranges of catches
+				 * in progress */
+    int i;
+
+    /*
+     * Determine the max catch depth for the entire assembly script
+     * (excluding embedded eval's and expr's, which will be handled later).
+     */
+
+    for (bbPtr=assemEnvPtr->head_bb; bbPtr != NULL; bbPtr=bbPtr->successor1) {
+	if (bbPtr->catchDepth > maxCatchDepth) {
+	    maxCatchDepth = bbPtr->catchDepth;
+	}
+    }
+
+    /*
+     * Allocate memory for a stack of active catches.
+     */
+
+    catches = ckalloc(maxCatchDepth * sizeof(BasicBlock*));
+    catchIndices = ckalloc(maxCatchDepth * sizeof(int));
+    for (i = 0; i < maxCatchDepth; ++i) {
+	catches[i] = NULL;
+	catchIndices[i] = -1;
+    }
+
+    /*
+     * Walk through the basic blocks and manage exception ranges.
+     */
+
+    for (bbPtr=assemEnvPtr->head_bb; bbPtr != NULL; bbPtr=bbPtr->successor1) {
+	UnstackExpiredCatches(envPtr, bbPtr, catchDepth, catches,
+		catchIndices);
+	LookForFreshCatches(bbPtr, catches);
+	StackFreshCatches(assemEnvPtr, bbPtr, catchDepth, catches,
+		catchIndices);
+
+	/*
+	 * If the last block was a 'begin catch', fill in the exception range.
+	 */
+
+	catchDepth = bbPtr->catchDepth;
+	if (prevPtr != NULL && (prevPtr->flags & BB_BEGINCATCH)) {
+	    TclStoreInt4AtPtr(catchIndices[catchDepth-1],
+		    envPtr->codeStart + bbPtr->startOffset - 4);
+	}
+
+	prevPtr = bbPtr;
+    }
+
+    /* Make sure that all catches are closed */
+
+    if (catchDepth != 0) {
+	Tcl_Panic("unclosed catch at end of code in "
+		"tclAssembly.c:BuildExceptionRanges, can't happen");
+    }
+
+    /* Free temp storage */
+
+    ckfree(catchIndices);
+    ckfree(catches);
+
+    return TCL_OK;
+}
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * UnstackExpiredCatches --
+ *
+ *	Unstacks and closes the exception ranges for any catch contexts that
+ *	were active in the previous basic block but are inactive in the
+ *	current one.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static void
+UnstackExpiredCatches(
+    CompileEnv* envPtr,		/* Compilation environment */
+    BasicBlock* bbPtr,		/* Basic block being processed */
+    int catchDepth,		/* Depth of nesting of catches prior to entry
+				 * to this block */
+    BasicBlock** catches,	/* Array of catch contexts */
+    int* catchIndices)		/* Indices of the exception ranges
+				 * corresponding to the catch contexts */
+{
+    ExceptionRange* range;	/* Exception range for a specific catch */
+    BasicBlock* catch;		/* Catch block being examined */
+    BasicBlockCatchState catchState;
+				/* State of the code relative to the catch
+				 * block being examined ("in catch" or
+				 * "caught"). */
+
+    /*
+     * Unstack any catches that are deeper than the nesting level of the basic
+     * block being entered.
+     */
+
+    while (catchDepth > bbPtr->catchDepth) {
+	--catchDepth;
+	if (catches[catchDepth] != NULL) {
+	    range = envPtr->exceptArrayPtr + catchIndices[catchDepth];
+	    range->numCodeBytes = bbPtr->startOffset - range->codeOffset;
+	    catches[catchDepth] = NULL;
+	    catchIndices[catchDepth] = -1;
+	}
+    }
+
+    /*
+     * Unstack any catches that don't match the basic block being entered,
+     * either because they are no longer part of the context, or because the
+     * context has changed from INCATCH to CAUGHT.
+     */
+
+    catchState = bbPtr->catchState;
+    catch = bbPtr->enclosingCatch;
+    while (catchDepth > 0) {
+	--catchDepth;
+	if (catches[catchDepth] != NULL) {
+	    if (catches[catchDepth] != catch || catchState >= BBCS_CAUGHT) {
+		range = envPtr->exceptArrayPtr + catchIndices[catchDepth];
+		range->numCodeBytes = bbPtr->startOffset - range->codeOffset;
+		catches[catchDepth] = NULL;
+		catchIndices[catchDepth] = -1;
+	    }
+	    catchState = catch->catchState;
+	    catch = catch->enclosingCatch;
+	}
+    }
+}
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * LookForFreshCatches --
+ *
+ *	Determines whether a basic block being entered needs any exception
+ *	ranges that are not already stacked.
+ *
+ * Does not create the ranges: this procedure iterates from the innermost
+ * catch outward, but exception ranges must be created from the outermost
+ * catch inward.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static void
+LookForFreshCatches(
+    BasicBlock* bbPtr,		/* Basic block being entered */
+    BasicBlock** catches)	/* Array of catch contexts that are already
+				 * entered */
+{
+    BasicBlockCatchState catchState;
+				/* State ("in catch" or "caught") of the
+				 * current catch. */
+    BasicBlock* catch;		/* Current enclosing catch */
+    int catchDepth;		/* Nesting depth of the current catch */
+
+    catchState = bbPtr->catchState;
+    catch = bbPtr->enclosingCatch;
+    catchDepth = bbPtr->catchDepth;
+    while (catchDepth > 0) {
+	--catchDepth;
+	if (catches[catchDepth] != catch && catchState < BBCS_CAUGHT) {
+	    catches[catchDepth] = catch;
+	}
+	catchState = catch->catchState;
+	catch = catch->enclosingCatch;
+    }
+}
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * StackFreshCatches --
+ *
+ *	Make ExceptionRange records for any catches that are in the basic
+ *	block being entered and were not in the previous basic block.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static void
+StackFreshCatches(
+    AssemblyEnv* assemEnvPtr,	/* Assembly environment */
+    BasicBlock* bbPtr,		/* Basic block being processed */
+    int catchDepth,		/* Depth of nesting of catches prior to entry
+				 * to this block */
+    BasicBlock** catches,	/* Array of catch contexts */
+    int* catchIndices)		/* Indices of the exception ranges
+				 * corresponding to the catch contexts */
+{
+    CompileEnv* envPtr = assemEnvPtr->envPtr;
+				/* Compilation environment */
+    ExceptionRange* range;	/* Exception range for a specific catch */
+    BasicBlock* catch;		/* Catch block being examined */
+    BasicBlock* errorExit;	/* Error exit from the catch block */
+    Tcl_HashEntry* entryPtr;
+
+    catchDepth = 0;
+
+    /*
+     * Iterate through the enclosing catch blocks from the outside in,
+     * looking for ones that don't have exception ranges (and are uncaught)
+     */
+
+    for (catchDepth = 0; catchDepth < bbPtr->catchDepth; ++catchDepth) {
+	if (catchIndices[catchDepth] == -1 && catches[catchDepth] != NULL) {
+	    /*
+	     * Create an exception range for a block that needs one.
+	     */
+
+	    catch = catches[catchDepth];
+	    catchIndices[catchDepth] =
+		    TclCreateExceptRange(CATCH_EXCEPTION_RANGE, envPtr);
+	    range = envPtr->exceptArrayPtr + catchIndices[catchDepth];
+	    range->nestingLevel = envPtr->exceptDepth + catchDepth;
+	    envPtr->maxExceptDepth =
+		    TclMax(range->nestingLevel + 1, envPtr->maxExceptDepth);
+	    range->codeOffset = bbPtr->startOffset;
+
+	    entryPtr = Tcl_FindHashEntry(&assemEnvPtr->labelHash,
+		    Tcl_GetString(catch->jumpTarget));
+	    if (entryPtr == NULL) {
+		Tcl_Panic("undefined label in tclAssembly.c:"
+			"BuildExceptionRanges, can't happen");
+	    }
+
+	    errorExit = Tcl_GetHashValue(entryPtr);
+	    range->catchOffset = errorExit->startOffset;
+	}
+    }
+}
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * RestoreEmbeddedExceptionRanges --
+ *
+ *	Processes an assembly script, replacing any exception ranges that
+ *	were present in embedded code.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static void
+RestoreEmbeddedExceptionRanges(
+    AssemblyEnv* assemEnvPtr)	/* Assembly environment */
+{
+    CompileEnv* envPtr = assemEnvPtr->envPtr;
+				/* Compilation environment */
+    BasicBlock* bbPtr;		/* Current basic block */
+    int rangeBase;		/* Base of the foreign exception ranges when
+				 * they are reinstalled */
+    int rangeIndex;		/* Index of the current foreign exception
+				 * range as reinstalled */
+    ExceptionRange* range;	/* Current foreign exception range */
+    unsigned char opcode;	/* Current instruction's opcode */
+    int catchIndex;		/* Index of the exception range to which the
+				 * current instruction refers */
+    int i;
+
+    /*
+     * Walk the basic blocks looking for exceptions in embedded scripts.
+     */
+
+    for (bbPtr = assemEnvPtr->head_bb;
+	    bbPtr != NULL;
+	    bbPtr = bbPtr->successor1) {
+	if (bbPtr->foreignExceptionCount != 0) {
+	    /*
+	     * Reinstall the embedded exceptions and track their nesting level
+	     */
+
+	    rangeBase = envPtr->exceptArrayNext;
+	    for (i = 0; i < bbPtr->foreignExceptionCount; ++i) {
+		range = bbPtr->foreignExceptions + i;
+		rangeIndex = TclCreateExceptRange(range->type, envPtr);
+		range->nestingLevel += envPtr->exceptDepth + bbPtr->catchDepth;
+		memcpy(envPtr->exceptArrayPtr + rangeIndex, range,
+			sizeof(ExceptionRange));
+		if (range->nestingLevel >= envPtr->maxExceptDepth) {
+		    envPtr->maxExceptDepth = range->nestingLevel + 1;
+		}
+	    }
+
+	    /*
+	     * Walk through the bytecode of the basic block, and relocate
+	     * INST_BEGIN_CATCH4 instructions to the new locations
+	     */
+
+	    i = bbPtr->startOffset;
+	    while (i < bbPtr->successor1->startOffset) {
+		opcode = envPtr->codeStart[i];
+		if (opcode == INST_BEGIN_CATCH4) {
+		    catchIndex = TclGetUInt4AtPtr(envPtr->codeStart + i + 1);
+		    if (catchIndex >= bbPtr->foreignExceptionBase
+			    && catchIndex < (bbPtr->foreignExceptionBase +
+			    bbPtr->foreignExceptionCount)) {
+			catchIndex -= bbPtr->foreignExceptionBase;
+			catchIndex += rangeBase;
+			TclStoreInt4AtPtr(catchIndex, envPtr->codeStart+i+1);
+		    }
+		}
+		i += tclInstructionTable[opcode].numBytes;
+	    }
+	}
+    }
+}
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * ResetVisitedBasicBlocks --
+ *
+ *	Turns off the 'visited' flag in all basic blocks at the conclusion
+ *	of a pass.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static void
+ResetVisitedBasicBlocks(
+    AssemblyEnv* assemEnvPtr)	/* Assembly environment */
+{
+    BasicBlock* block;
+
+    for (block = assemEnvPtr->head_bb; block != NULL;
+	    block = block->successor1) {
+	block->flags &= ~BB_VISITED;
+    }
+}
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * AddBasicBlockRangeToErrorInfo --
+ *
+ *	Updates the error info of the Tcl interpreter to show a given basic
+ *	block in the code.
+ *
+ * This procedure is used to label the callstack with source location
+ * information when reporting an error in stack checking.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static void
+AddBasicBlockRangeToErrorInfo(
+    AssemblyEnv* assemEnvPtr,	/* Assembly environment */
+    BasicBlock* bbPtr)		/* Basic block in which the error is found */
+{
+    CompileEnv* envPtr = assemEnvPtr->envPtr;
+				/* Compilation environment */
+    Tcl_Interp* interp = (Tcl_Interp*) envPtr->iPtr;
+				/* Tcl interpreter */
+    Tcl_Obj* lineNo;		/* Line number in the source */
+
+    Tcl_AddErrorInfo(interp, "\n    in assembly code between lines ");
+    lineNo = Tcl_NewIntObj(bbPtr->startLine);
+    Tcl_IncrRefCount(lineNo);
+    Tcl_AppendObjToErrorInfo(interp, lineNo);
+    Tcl_AddErrorInfo(interp, " and ");
+    if (bbPtr->successor1 != NULL) {
+	Tcl_SetIntObj(lineNo, bbPtr->successor1->startLine);
+	Tcl_AppendObjToErrorInfo(interp, lineNo);
+    } else {
+	Tcl_AddErrorInfo(interp, "end of assembly code");
+    }
+    Tcl_DecrRefCount(lineNo);
+}
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * DupAssembleCodeInternalRep --
+ *
+ *	Part of the Tcl object type implementation for Tcl assembly language
+ *	bytecode. We do not copy the bytecode intrep. Instead, we return
+ *	without setting copyPtr->typePtr, so the copy is a plain string copy
+ *	of the assembly source, and if it is to be used as a compiled
+ *	expression, it will need to be reprocessed.
+ *
+ *	This makes sense, because with Tcl's copy-on-write practices, the
+ *	usual (only?) time Tcl_DuplicateObj() will be called is when the copy
+ *	is about to be modified, which would invalidate any copied bytecode
+ *	anyway. The only reason it might make sense to copy the bytecode is if
+ *	we had some modifying routines that operated directly on the intrep,
+ *	as we do for lists and dicts.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	None.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static void
+DupAssembleCodeInternalRep(
+    Tcl_Obj *srcPtr,
+    Tcl_Obj *copyPtr)
+{
+    return;
+}
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * FreeAssembleCodeInternalRep --
+ *
+ *	Part of the Tcl object type implementation for Tcl expression
+ *	bytecode. Frees the storage allocated to hold the internal rep, unless
+ *	ref counts indicate bytecode execution is still in progress.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	May free allocated memory. Leaves objPtr untyped.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static void
+FreeAssembleCodeInternalRep(
+    Tcl_Obj *objPtr)
+{
+    ByteCode *codePtr = objPtr->internalRep.twoPtrValue.ptr1;
+
+    codePtr->refCount--;
+    if (codePtr->refCount <= 0) {
+	TclCleanupByteCode(codePtr);
+    }
+    objPtr->typePtr = NULL;
+}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tclAsync.c b/generic/tclAsync.c
new file mode 100644
index 0000000..14804e4
--- /dev/null
+++ b/generic/tclAsync.c
@@ -0,0 +1,355 @@
+/*
+ * tclAsync.c --
+ *
+ *	This file provides low-level support needed to invoke signal handlers
+ *	in a safe way. The code here doesn't actually handle signals, though.
+ *	This code is based on proposals made by Mark Diekhans and Don Libes.
+ *
+ * Copyright (c) 1993 The Regents of the University of California.
+ * Copyright (c) 1994 Sun Microsystems, Inc.
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#include "tclInt.h"
+
+/* Forward declaration */
+struct ThreadSpecificData;
+
+/*
+ * One of the following structures exists for each asynchronous handler:
+ */
+
+typedef struct AsyncHandler {
+    int ready;			/* Non-zero means this handler should be
+				 * invoked in the next call to
+				 * Tcl_AsyncInvoke. */
+    struct AsyncHandler *nextPtr;
+				/* Next in list of all handlers for the
+				 * process. */
+    Tcl_AsyncProc *proc;	/* Procedure to call when handler is
+				 * invoked. */
+    ClientData clientData;	/* Value to pass to handler when it is
+				 * invoked. */
+    struct ThreadSpecificData *originTsd;
+				/* Used in Tcl_AsyncMark to modify thread-
+				 * specific data from outside the thread it is
+				 * associated to. */
+    Tcl_ThreadId originThrdId;	/* Origin thread where this token was created
+				 * and where it will be yielded. */
+} AsyncHandler;
+
+typedef struct ThreadSpecificData {
+    /*
+     * The variables below maintain a list of all existing handlers specific
+     * to the calling thread.
+     */
+    AsyncHandler *firstHandler;	/* First handler defined for process, or NULL
+				 * if none. */
+    AsyncHandler *lastHandler;	/* Last handler or NULL. */
+    int asyncReady;		/* This is set to 1 whenever a handler becomes
+				 * ready and it is cleared to zero whenever
+				 * Tcl_AsyncInvoke is called. It can be
+				 * checked elsewhere in the application by
+				 * calling Tcl_AsyncReady to see if
+				 * Tcl_AsyncInvoke should be invoked. */
+    int asyncActive;		/* Indicates whether Tcl_AsyncInvoke is
+				 * currently working. If so then we won't set
+				 * asyncReady again until Tcl_AsyncInvoke
+				 * returns. */
+    Tcl_Mutex asyncMutex;	/* Thread-specific AsyncHandler linked-list
+				 * lock */
+} ThreadSpecificData;
+static Tcl_ThreadDataKey dataKey;
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclFinalizeAsync --
+ *
+ *	Finalizes the mutex in the thread local data structure for the async
+ *	subsystem.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Forgets knowledge of the mutex should it have been created.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclFinalizeAsync(void)
+{
+    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+
+    if (tsdPtr->asyncMutex != NULL) {
+	Tcl_MutexFinalize(&tsdPtr->asyncMutex);
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_AsyncCreate --
+ *
+ *	This procedure creates the data structures for an asynchronous
+ *	handler, so that no memory has to be allocated when the handler is
+ *	activated.
+ *
+ * Results:
+ *	The return value is a token for the handler, which can be used to
+ *	activate it later on.
+ *
+ * Side effects:
+ *	Information about the handler is recorded.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_AsyncHandler
+Tcl_AsyncCreate(
+    Tcl_AsyncProc *proc,	/* Procedure to call when handler is
+				 * invoked. */
+    ClientData clientData)	/* Argument to pass to handler. */
+{
+    AsyncHandler *asyncPtr;
+    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+
+    asyncPtr = ckalloc(sizeof(AsyncHandler));
+    asyncPtr->ready = 0;
+    asyncPtr->nextPtr = NULL;
+    asyncPtr->proc = proc;
+    asyncPtr->clientData = clientData;
+    asyncPtr->originTsd = tsdPtr;
+    asyncPtr->originThrdId = Tcl_GetCurrentThread();
+
+    Tcl_MutexLock(&tsdPtr->asyncMutex);
+    if (tsdPtr->firstHandler == NULL) {
+	tsdPtr->firstHandler = asyncPtr;
+    } else {
+	tsdPtr->lastHandler->nextPtr = asyncPtr;
+    }
+    tsdPtr->lastHandler = asyncPtr;
+    Tcl_MutexUnlock(&tsdPtr->asyncMutex);
+    return (Tcl_AsyncHandler) asyncPtr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_AsyncMark --
+ *
+ *	This procedure is called to request that an asynchronous handler be
+ *	invoked as soon as possible. It's typically called from an interrupt
+ *	handler, where it isn't safe to do anything that depends on or
+ *	modifies application state.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The handler gets marked for invocation later.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_AsyncMark(
+    Tcl_AsyncHandler async)		/* Token for handler. */
+{
+    AsyncHandler *token = (AsyncHandler *) async;
+
+    Tcl_MutexLock(&token->originTsd->asyncMutex);
+    token->ready = 1;
+    if (!token->originTsd->asyncActive) {
+	token->originTsd->asyncReady = 1;
+	Tcl_ThreadAlert(token->originThrdId);
+    }
+    Tcl_MutexUnlock(&token->originTsd->asyncMutex);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_AsyncInvoke --
+ *
+ *	This procedure is called at a "safe" time at background level to
+ *	invoke any active asynchronous handlers.
+ *
+ * Results:
+ *	The return value is a normal Tcl result, which is intended to replace
+ *	the code argument as the current completion code for interp.
+ *
+ * Side effects:
+ *	Depends on the handlers that are active.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_AsyncInvoke(
+    Tcl_Interp *interp,		/* If invoked from Tcl_Eval just after
+				 * completing a command, points to
+				 * interpreter. Otherwise it is NULL. */
+    int code)			/* If interp is non-NULL, this gives
+				 * completion code from command that just
+				 * completed. */
+{
+    AsyncHandler *asyncPtr;
+    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+
+    Tcl_MutexLock(&tsdPtr->asyncMutex);
+
+    if (tsdPtr->asyncReady == 0) {
+	Tcl_MutexUnlock(&tsdPtr->asyncMutex);
+	return code;
+    }
+    tsdPtr->asyncReady = 0;
+    tsdPtr->asyncActive = 1;
+    if (interp == NULL) {
+	code = 0;
+    }
+
+    /*
+     * Make one or more passes over the list of handlers, invoking at most one
+     * handler in each pass. After invoking a handler, go back to the start of
+     * the list again so that (a) if a new higher-priority handler gets marked
+     * while executing a lower priority handler, we execute the higher-
+     * priority handler next, and (b) if a handler gets deleted during the
+     * execution of a handler, then the list structure may change so it isn't
+     * safe to continue down the list anyway.
+     */
+
+    while (1) {
+	for (asyncPtr = tsdPtr->firstHandler; asyncPtr != NULL;
+		asyncPtr = asyncPtr->nextPtr) {
+	    if (asyncPtr->ready) {
+		break;
+	    }
+	}
+	if (asyncPtr == NULL) {
+	    break;
+	}
+	asyncPtr->ready = 0;
+	Tcl_MutexUnlock(&tsdPtr->asyncMutex);
+	code = asyncPtr->proc(asyncPtr->clientData, interp, code);
+	Tcl_MutexLock(&tsdPtr->asyncMutex);
+    }
+    tsdPtr->asyncActive = 0;
+    Tcl_MutexUnlock(&tsdPtr->asyncMutex);
+    return code;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_AsyncDelete --
+ *
+ *	Frees up all the state for an asynchronous handler. The handler should
+ *	never be used again.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The state associated with the handler is deleted.
+ *
+ *	Failure to locate the handler in current thread private list
+ *	of async handlers will result in panic; exception: the list
+ *	is already empty (potential trouble?).
+ *	Consequently, threads should create and delete handlers
+ *	themselves.  I.e. a handler created by one should not be
+ *	deleted by some other thread.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_AsyncDelete(
+    Tcl_AsyncHandler async)		/* Token for handler to delete. */
+{
+    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+    AsyncHandler *asyncPtr = (AsyncHandler *) async;
+    AsyncHandler *prevPtr, *thisPtr;
+
+    /*
+     * Assure early handling of the constraint
+     */
+
+    if (asyncPtr->originThrdId != Tcl_GetCurrentThread()) {
+	Tcl_Panic("Tcl_AsyncDelete: async handler deleted by the wrong thread");
+    }
+
+    /*
+     * If we come to this point when TSD's for the current
+     * thread have already been garbage-collected, we are
+     * in the _serious_ trouble. OTOH, we tolerate calling
+     * with already cleaned-up handler list (should we?).
+     */
+
+    Tcl_MutexLock(&tsdPtr->asyncMutex);
+    if (tsdPtr->firstHandler != NULL) {
+	prevPtr = thisPtr = tsdPtr->firstHandler;
+	while (thisPtr != NULL && thisPtr != asyncPtr) {
+	    prevPtr = thisPtr;
+	    thisPtr = thisPtr->nextPtr;
+	}
+	if (thisPtr == NULL) {
+	    Tcl_Panic("Tcl_AsyncDelete: cannot find async handler");
+	}
+	if (asyncPtr == tsdPtr->firstHandler) {
+	    tsdPtr->firstHandler = asyncPtr->nextPtr;
+	} else {
+	    prevPtr->nextPtr = asyncPtr->nextPtr;
+	}
+	if (asyncPtr == tsdPtr->lastHandler) {
+	    tsdPtr->lastHandler = prevPtr;
+	}
+    }
+    Tcl_MutexUnlock(&tsdPtr->asyncMutex);
+    ckfree(asyncPtr);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_AsyncReady --
+ *
+ *	This procedure can be used to tell whether Tcl_AsyncInvoke needs to be
+ *	called. This procedure is the external interface for checking the
+ *	thread-specific asyncReady variable.
+ *
+ * Results:
+ *	The return value is 1 whenever a handler is ready and is 0 when no
+ *	handlers are ready.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_AsyncReady(void)
+{
+    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+    return tsdPtr->asyncReady;
+}
+
+int *
+TclGetAsyncReadyPtr(void)
+{
+    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+    return &(tsdPtr->asyncReady);
+}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tclBasic.c b/generic/tclBasic.c
new file mode 100644
index 0000000..d6a460d
--- /dev/null
+++ b/generic/tclBasic.c
@@ -0,0 +1,9055 @@
+/*
+ * tclBasic.c --
+ *
+ *	Contains the basic facilities for TCL command interpretation,
+ *	including interpreter creation and deletion, command creation and
+ *	deletion, and command/script execution.
+ *
+ * Copyright (c) 1987-1994 The Regents of the University of California.
+ * Copyright (c) 1994-1997 Sun Microsystems, Inc.
+ * Copyright (c) 1998-1999 by Scriptics Corporation.
+ * Copyright (c) 2001, 2002 by Kevin B. Kenny.  All rights reserved.
+ * Copyright (c) 2007 Daniel A. Steffen <das@users.sourceforge.net>
+ * Copyright (c) 2006-2008 by Joe Mistachkin.  All rights reserved.
+ * Copyright (c) 2008 Miguel Sofer <msofer@users.sourceforge.net>
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#include "tclInt.h"
+#include "tclOOInt.h"
+#include "tclCompile.h"
+#include "tommath.h"
+#include <math.h>
+#include <assert.h>
+
+#define INTERP_STACK_INITIAL_SIZE 2000
+#define CORO_STACK_INITIAL_SIZE    200
+
+/*
+ * Determine whether we're using IEEE floating point
+ */
+
+#if (FLT_RADIX == 2) && (DBL_MANT_DIG == 53) && (DBL_MAX_EXP == 1024)
+#   define IEEE_FLOATING_POINT
+/* Largest odd integer that can be represented exactly in a double */
+#   define MAX_EXACT 9007199254740991.0
+#endif
+
+/*
+ * The following structure defines the client data for a math function
+ * registered with Tcl_CreateMathFunc
+ */
+
+typedef struct OldMathFuncData {
+    Tcl_MathProc *proc;		/* Handler function */
+    int numArgs;		/* Number of args expected */
+    Tcl_ValueType *argTypes;	/* Types of the args */
+    ClientData clientData;	/* Client data for the handler function */
+} OldMathFuncData;
+
+/*
+ * This is the script cancellation struct and hash table. The hash table is
+ * used to keep track of the information necessary to process script
+ * cancellation requests, including the original interp, asynchronous handler
+ * tokens (created by Tcl_AsyncCreate), and the clientData and flags arguments
+ * passed to Tcl_CancelEval on a per-interp basis. The cancelLock mutex is
+ * used for protecting calls to Tcl_CancelEval as well as protecting access to
+ * the hash table below.
+ */
+
+typedef struct {
+    Tcl_Interp *interp;		/* Interp this struct belongs to. */
+    Tcl_AsyncHandler async;	/* Async handler token for script
+				 * cancellation. */
+    char *result;		/* The script cancellation result or NULL for
+				 * a default result. */
+    int length;			/* Length of the above error message. */
+    ClientData clientData;	/* Ignored */
+    int flags;			/* Additional flags */
+} CancelInfo;
+static Tcl_HashTable cancelTable;
+static int cancelTableInitialized = 0;	/* 0 means not yet initialized. */
+TCL_DECLARE_MUTEX(cancelLock)
+
+/*
+ * Declarations for managing contexts for non-recursive coroutines. Contexts
+ * are used to save the evaluation state between NR calls to each coro.
+ */
+
+#define SAVE_CONTEXT(context)				\
+    (context).framePtr = iPtr->framePtr;		\
+    (context).varFramePtr = iPtr->varFramePtr;		\
+    (context).cmdFramePtr = iPtr->cmdFramePtr;		\
+    (context).lineLABCPtr = iPtr->lineLABCPtr
+
+#define RESTORE_CONTEXT(context)			\
+    iPtr->framePtr = (context).framePtr;		\
+    iPtr->varFramePtr = (context).varFramePtr;		\
+    iPtr->cmdFramePtr = (context).cmdFramePtr;		\
+    iPtr->lineLABCPtr = (context).lineLABCPtr
+
+/*
+ * Static functions in this file:
+ */
+
+static char *		CallCommandTraces(Interp *iPtr, Command *cmdPtr,
+			    const char *oldName, const char *newName,
+			    int flags);
+static int		CancelEvalProc(ClientData clientData,
+			    Tcl_Interp *interp, int code);
+static int		CheckDoubleResult(Tcl_Interp *interp, double dResult);
+static void		DeleteCoroutine(ClientData clientData);
+static void		DeleteInterpProc(Tcl_Interp *interp);
+static void		DeleteOpCmdClientData(ClientData clientData);
+#ifdef USE_DTRACE
+static Tcl_ObjCmdProc	DTraceObjCmd;
+static Tcl_NRPostProc	DTraceCmdReturn;
+#else
+#   define DTraceCmdReturn	NULL
+#endif /* USE_DTRACE */
+static Tcl_ObjCmdProc	ExprAbsFunc;
+static Tcl_ObjCmdProc	ExprBinaryFunc;
+static Tcl_ObjCmdProc	ExprBoolFunc;
+static Tcl_ObjCmdProc	ExprCeilFunc;
+static Tcl_ObjCmdProc	ExprDoubleFunc;
+static Tcl_ObjCmdProc	ExprEntierFunc;
+static Tcl_ObjCmdProc	ExprFloorFunc;
+static Tcl_ObjCmdProc	ExprIntFunc;
+static Tcl_ObjCmdProc	ExprIsqrtFunc;
+static Tcl_ObjCmdProc	ExprRandFunc;
+static Tcl_ObjCmdProc	ExprRoundFunc;
+static Tcl_ObjCmdProc	ExprSqrtFunc;
+static Tcl_ObjCmdProc	ExprSrandFunc;
+static Tcl_ObjCmdProc	ExprUnaryFunc;
+static Tcl_ObjCmdProc	ExprWideFunc;
+static void		MathFuncWrongNumArgs(Tcl_Interp *interp, int expected,
+			    int actual, Tcl_Obj *const *objv);
+static Tcl_NRPostProc	NRCoroutineCallerCallback;
+static Tcl_NRPostProc	NRCoroutineExitCallback;
+static Tcl_NRPostProc	NRCommand;
+
+static Tcl_ObjCmdProc	OldMathFuncProc;
+static void		OldMathFuncDeleteProc(ClientData clientData);
+static void		ProcessUnexpectedResult(Tcl_Interp *interp,
+			    int returnCode);
+static int		RewindCoroutine(CoroutineData *corPtr, int result);
+static void		TEOV_SwitchVarFrame(Tcl_Interp *interp);
+static void		TEOV_PushExceptionHandlers(Tcl_Interp *interp,
+			    int objc, Tcl_Obj *const objv[], int flags);
+static inline Command *	TEOV_LookupCmdFromObj(Tcl_Interp *interp,
+			    Tcl_Obj *namePtr, Namespace *lookupNsPtr);
+static int		TEOV_NotFound(Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[], Namespace *lookupNsPtr);
+static int		TEOV_RunEnterTraces(Tcl_Interp *interp,
+			    Command **cmdPtrPtr, Tcl_Obj *commandPtr, int objc,
+			    Tcl_Obj *const objv[]);
+static Tcl_NRPostProc	RewindCoroutineCallback;
+static Tcl_NRPostProc	TEOEx_ByteCodeCallback;
+static Tcl_NRPostProc	TEOEx_ListCallback;
+static Tcl_NRPostProc	TEOV_Error;
+static Tcl_NRPostProc	TEOV_Exception;
+static Tcl_NRPostProc	TEOV_NotFoundCallback;
+static Tcl_NRPostProc	TEOV_RestoreVarFrame;
+static Tcl_NRPostProc	TEOV_RunLeaveTraces;
+static Tcl_NRPostProc	EvalObjvCore;
+static Tcl_NRPostProc	Dispatch;
+
+static Tcl_ObjCmdProc NRCoroInjectObjCmd;
+static Tcl_NRPostProc NRPostInvoke;
+
+MODULE_SCOPE const TclStubs tclStubs;
+
+/*
+ * Magical counts for the number of arguments accepted by a coroutine command
+ * after particular kinds of [yield].
+ */
+
+#define CORO_ACTIVATE_YIELD    PTR2INT(NULL)
+#define CORO_ACTIVATE_YIELDM   PTR2INT(NULL)+1
+
+#define COROUTINE_ARGUMENTS_SINGLE_OPTIONAL     (-1)
+#define COROUTINE_ARGUMENTS_ARBITRARY           (-2)
+
+/*
+ * The following structure define the commands in the Tcl core.
+ */
+
+typedef struct {
+    const char *name;		/* Name of object-based command. */
+    Tcl_ObjCmdProc *objProc;	/* Object-based function for command. */
+    CompileProc *compileProc;	/* Function called to compile command. */
+    Tcl_ObjCmdProc *nreProc;	/* NR-based function for command */
+    int flags;			/* Various flag bits, as defined below. */
+} CmdInfo;
+
+#define CMD_IS_SAFE         1   /* Whether this command is part of the set of
+                                 * commands present by default in a safe
+                                 * interpreter. */
+/* CMD_COMPILES_EXPANDED - Whether the compiler for this command can handle
+ * expansion for itself rather than needing the generic layer to take care of
+ * it for it. Defined in tclInt.h. */
+
+/*
+ * The built-in commands, and the functions that implement them:
+ */
+
+static const CmdInfo builtInCmds[] = {
+    /*
+     * Commands in the generic core.
+     */
+
+    {"append",		Tcl_AppendObjCmd,	TclCompileAppendCmd,	NULL,	CMD_IS_SAFE},
+    {"apply",		Tcl_ApplyObjCmd,	NULL,			TclNRApplyObjCmd,	CMD_IS_SAFE},
+    {"break",		Tcl_BreakObjCmd,	TclCompileBreakCmd,	NULL,	CMD_IS_SAFE},
+#ifndef EXCLUDE_OBSOLETE_COMMANDS
+    {"case",		Tcl_CaseObjCmd,		NULL,			NULL,	CMD_IS_SAFE},
+#endif
+    {"catch",		Tcl_CatchObjCmd,	TclCompileCatchCmd,	TclNRCatchObjCmd,	CMD_IS_SAFE},
+    {"concat",		Tcl_ConcatObjCmd,	TclCompileConcatCmd,	NULL,	CMD_IS_SAFE},
+    {"continue",	Tcl_ContinueObjCmd,	TclCompileContinueCmd,	NULL,	CMD_IS_SAFE},
+    {"coroutine",	NULL,			NULL,			TclNRCoroutineObjCmd,	CMD_IS_SAFE},
+    {"error",		Tcl_ErrorObjCmd,	TclCompileErrorCmd,	NULL,	CMD_IS_SAFE},
+    {"eval",		Tcl_EvalObjCmd,		NULL,			TclNREvalObjCmd,	CMD_IS_SAFE},
+    {"expr",		Tcl_ExprObjCmd,		TclCompileExprCmd,	TclNRExprObjCmd,	CMD_IS_SAFE},
+    {"for",		Tcl_ForObjCmd,		TclCompileForCmd,	TclNRForObjCmd,	CMD_IS_SAFE},
+    {"foreach",		Tcl_ForeachObjCmd,	TclCompileForeachCmd,	TclNRForeachCmd,	CMD_IS_SAFE},
+    {"format",		Tcl_FormatObjCmd,	TclCompileFormatCmd,	NULL,	CMD_IS_SAFE},
+    {"global",		Tcl_GlobalObjCmd,	TclCompileGlobalCmd,	NULL,	CMD_IS_SAFE},
+    {"if",		Tcl_IfObjCmd,		TclCompileIfCmd,	TclNRIfObjCmd,	CMD_IS_SAFE},
+    {"incr",		Tcl_IncrObjCmd,		TclCompileIncrCmd,	NULL,	CMD_IS_SAFE},
+    {"join",		Tcl_JoinObjCmd,		NULL,			NULL,	CMD_IS_SAFE},
+    {"lappend",		Tcl_LappendObjCmd,	TclCompileLappendCmd,	NULL,	CMD_IS_SAFE},
+    {"lassign",		Tcl_LassignObjCmd,	TclCompileLassignCmd,	NULL,	CMD_IS_SAFE},
+    {"lindex",		Tcl_LindexObjCmd,	TclCompileLindexCmd,	NULL,	CMD_IS_SAFE},
+    {"linsert",		Tcl_LinsertObjCmd,	TclCompileLinsertCmd,	NULL,	CMD_IS_SAFE},
+    {"list",		Tcl_ListObjCmd,		TclCompileListCmd,	NULL,	CMD_IS_SAFE|CMD_COMPILES_EXPANDED},
+    {"llength",		Tcl_LlengthObjCmd,	TclCompileLlengthCmd,	NULL,	CMD_IS_SAFE},
+    {"lmap",		Tcl_LmapObjCmd,		TclCompileLmapCmd,	TclNRLmapCmd,	CMD_IS_SAFE},
+    {"lrange",		Tcl_LrangeObjCmd,	TclCompileLrangeCmd,	NULL,	CMD_IS_SAFE},
+    {"lrepeat",		Tcl_LrepeatObjCmd,	NULL,			NULL,	CMD_IS_SAFE},
+    {"lreplace",	Tcl_LreplaceObjCmd,	TclCompileLreplaceCmd,	NULL,	CMD_IS_SAFE},
+    {"lreverse",	Tcl_LreverseObjCmd,	NULL,			NULL,	CMD_IS_SAFE},
+    {"lsearch",		Tcl_LsearchObjCmd,	NULL,			NULL,	CMD_IS_SAFE},
+    {"lset",		Tcl_LsetObjCmd,		TclCompileLsetCmd,	NULL,	CMD_IS_SAFE},
+    {"lsort",		Tcl_LsortObjCmd,	NULL,			NULL,	CMD_IS_SAFE},
+    {"package",		Tcl_PackageObjCmd,	NULL,			NULL,	CMD_IS_SAFE},
+    {"proc",		Tcl_ProcObjCmd,		NULL,			NULL,	CMD_IS_SAFE},
+    {"regexp",		Tcl_RegexpObjCmd,	TclCompileRegexpCmd,	NULL,	CMD_IS_SAFE},
+    {"regsub",		Tcl_RegsubObjCmd,	TclCompileRegsubCmd,	NULL,	CMD_IS_SAFE},
+    {"rename",		Tcl_RenameObjCmd,	NULL,			NULL,	CMD_IS_SAFE},
+    {"return",		Tcl_ReturnObjCmd,	TclCompileReturnCmd,	NULL,	CMD_IS_SAFE},
+    {"scan",		Tcl_ScanObjCmd,		NULL,			NULL,	CMD_IS_SAFE},
+    {"set",		Tcl_SetObjCmd,		TclCompileSetCmd,	NULL,	CMD_IS_SAFE},
+    {"split",		Tcl_SplitObjCmd,	NULL,			NULL,	CMD_IS_SAFE},
+    {"subst",		Tcl_SubstObjCmd,	TclCompileSubstCmd,	TclNRSubstObjCmd,	CMD_IS_SAFE},
+    {"switch",		Tcl_SwitchObjCmd,	TclCompileSwitchCmd,	TclNRSwitchObjCmd, CMD_IS_SAFE},
+    {"tailcall",	NULL,			TclCompileTailcallCmd,	TclNRTailcallObjCmd,	CMD_IS_SAFE},
+    {"throw",		Tcl_ThrowObjCmd,	TclCompileThrowCmd,	NULL,	CMD_IS_SAFE},
+    {"trace",		Tcl_TraceObjCmd,	NULL,			NULL,	CMD_IS_SAFE},
+    {"try",		Tcl_TryObjCmd,		TclCompileTryCmd,	TclNRTryObjCmd,	CMD_IS_SAFE},
+    {"unset",		Tcl_UnsetObjCmd,	TclCompileUnsetCmd,	NULL,	CMD_IS_SAFE},
+    {"uplevel",		Tcl_UplevelObjCmd,	NULL,			TclNRUplevelObjCmd,	CMD_IS_SAFE},
+    {"upvar",		Tcl_UpvarObjCmd,	TclCompileUpvarCmd,	NULL,	CMD_IS_SAFE},
+    {"variable",	Tcl_VariableObjCmd,	TclCompileVariableCmd,	NULL,	CMD_IS_SAFE},
+    {"while",		Tcl_WhileObjCmd,	TclCompileWhileCmd,	TclNRWhileObjCmd,	CMD_IS_SAFE},
+    {"yield",		NULL,			TclCompileYieldCmd,	TclNRYieldObjCmd,	CMD_IS_SAFE},
+    {"yieldto",		NULL,			TclCompileYieldToCmd,	TclNRYieldToObjCmd,	CMD_IS_SAFE},
+
+    /*
+     * Commands in the OS-interface. Note that many of these are unsafe.
+     */
+
+    {"after",		Tcl_AfterObjCmd,	NULL,			NULL,	CMD_IS_SAFE},
+    {"cd",		Tcl_CdObjCmd,		NULL,			NULL,	0},
+    {"close",		Tcl_CloseObjCmd,	NULL,			NULL,	CMD_IS_SAFE},
+    {"eof",		Tcl_EofObjCmd,		NULL,			NULL,	CMD_IS_SAFE},
+    {"encoding",	Tcl_EncodingObjCmd,	NULL,			NULL,	0},
+    {"exec",		Tcl_ExecObjCmd,		NULL,			NULL,	0},
+    {"exit",		Tcl_ExitObjCmd,		NULL,			NULL,	0},
+    {"fblocked",	Tcl_FblockedObjCmd,	NULL,			NULL,	CMD_IS_SAFE},
+    {"fconfigure",	Tcl_FconfigureObjCmd,	NULL,			NULL,	0},
+    {"fcopy",		Tcl_FcopyObjCmd,	NULL,			NULL,	CMD_IS_SAFE},
+    {"fileevent",	Tcl_FileEventObjCmd,	NULL,			NULL,	CMD_IS_SAFE},
+    {"flush",		Tcl_FlushObjCmd,	NULL,			NULL,	CMD_IS_SAFE},
+    {"gets",		Tcl_GetsObjCmd,		NULL,			NULL,	CMD_IS_SAFE},
+    {"glob",		Tcl_GlobObjCmd,		NULL,			NULL,	0},
+    {"load",		Tcl_LoadObjCmd,		NULL,			NULL,	0},
+    {"open",		Tcl_OpenObjCmd,		NULL,			NULL,	0},
+    {"pid",		Tcl_PidObjCmd,		NULL,			NULL,	CMD_IS_SAFE},
+    {"puts",		Tcl_PutsObjCmd,		NULL,			NULL,	CMD_IS_SAFE},
+    {"pwd",		Tcl_PwdObjCmd,		NULL,			NULL,	0},
+    {"read",		Tcl_ReadObjCmd,		NULL,			NULL,	CMD_IS_SAFE},
+    {"seek",		Tcl_SeekObjCmd,		NULL,			NULL,	CMD_IS_SAFE},
+    {"socket",		Tcl_SocketObjCmd,	NULL,			NULL,	0},
+    {"source",		Tcl_SourceObjCmd,	NULL,			TclNRSourceObjCmd,	0},
+    {"tell",		Tcl_TellObjCmd,		NULL,			NULL,	CMD_IS_SAFE},
+    {"time",		Tcl_TimeObjCmd,		NULL,			NULL,	CMD_IS_SAFE},
+    {"unload",		Tcl_UnloadObjCmd,	NULL,			NULL,	0},
+    {"update",		Tcl_UpdateObjCmd,	NULL,			NULL,	CMD_IS_SAFE},
+    {"vwait",		Tcl_VwaitObjCmd,	NULL,			NULL,	CMD_IS_SAFE},
+    {NULL,		NULL,			NULL,			NULL,	0}
+};
+
+/*
+ * Math functions. All are safe.
+ */
+
+typedef struct {
+    const char *name;		/* Name of the function. The full name is
+				 * "::tcl::mathfunc::<name>". */
+    Tcl_ObjCmdProc *objCmdProc;	/* Function that evaluates the function */
+    ClientData clientData;	/* Client data for the function */
+} BuiltinFuncDef;
+static const BuiltinFuncDef BuiltinFuncTable[] = {
+    { "abs",	ExprAbsFunc,	NULL			},
+    { "acos",	ExprUnaryFunc,	(ClientData) acos	},
+    { "asin",	ExprUnaryFunc,	(ClientData) asin	},
+    { "atan",	ExprUnaryFunc,	(ClientData) atan	},
+    { "atan2",	ExprBinaryFunc,	(ClientData) atan2	},
+    { "bool",	ExprBoolFunc,	NULL			},
+    { "ceil",	ExprCeilFunc,	NULL			},
+    { "cos",	ExprUnaryFunc,	(ClientData) cos	},
+    { "cosh",	ExprUnaryFunc,	(ClientData) cosh	},
+    { "double",	ExprDoubleFunc,	NULL			},
+    { "entier",	ExprEntierFunc,	NULL			},
+    { "exp",	ExprUnaryFunc,	(ClientData) exp	},
+    { "floor",	ExprFloorFunc,	NULL			},
+    { "fmod",	ExprBinaryFunc,	(ClientData) fmod	},
+    { "hypot",	ExprBinaryFunc,	(ClientData) hypot	},
+    { "int",	ExprIntFunc,	NULL			},
+    { "isqrt",	ExprIsqrtFunc,	NULL			},
+    { "log",	ExprUnaryFunc,	(ClientData) log	},
+    { "log10",	ExprUnaryFunc,	(ClientData) log10	},
+    { "pow",	ExprBinaryFunc,	(ClientData) pow	},
+    { "rand",	ExprRandFunc,	NULL			},
+    { "round",	ExprRoundFunc,	NULL			},
+    { "sin",	ExprUnaryFunc,	(ClientData) sin	},
+    { "sinh",	ExprUnaryFunc,	(ClientData) sinh	},
+    { "sqrt",	ExprSqrtFunc,	NULL			},
+    { "srand",	ExprSrandFunc,	NULL			},
+    { "tan",	ExprUnaryFunc,	(ClientData) tan	},
+    { "tanh",	ExprUnaryFunc,	(ClientData) tanh	},
+    { "wide",	ExprWideFunc,	NULL			},
+    { NULL, NULL, NULL }
+};
+
+/*
+ * TIP#174's math operators. All are safe.
+ */
+
+typedef struct {
+    const char *name;		/* Name of object-based command. */
+    Tcl_ObjCmdProc *objProc;	/* Object-based function for command. */
+    CompileProc *compileProc;	/* Function called to compile command. */
+    union {
+	int numArgs;
+	int identity;
+    } i;
+    const char *expected;	/* For error message, what argument(s)
+				 * were expected. */
+} OpCmdInfo;
+static const OpCmdInfo mathOpCmds[] = {
+    { "~",	TclSingleOpCmd,		TclCompileInvertOpCmd,
+		/* numArgs */ {1},	"integer"},
+    { "!",	TclSingleOpCmd,		TclCompileNotOpCmd,
+		/* numArgs */ {1},	"boolean"},
+    { "+",	TclVariadicOpCmd,	TclCompileAddOpCmd,
+		/* identity */ {0},	NULL},
+    { "*",	TclVariadicOpCmd,	TclCompileMulOpCmd,
+		/* identity */ {1},	NULL},
+    { "&",	TclVariadicOpCmd,	TclCompileAndOpCmd,
+		/* identity */ {-1},	NULL},
+    { "|",	TclVariadicOpCmd,	TclCompileOrOpCmd,
+		/* identity */ {0},	NULL},
+    { "^",	TclVariadicOpCmd,	TclCompileXorOpCmd,
+		/* identity */ {0},	NULL},
+    { "**",	TclVariadicOpCmd,	TclCompilePowOpCmd,
+		/* identity */ {1},	NULL},
+    { "<<",	TclSingleOpCmd,		TclCompileLshiftOpCmd,
+		/* numArgs */ {2},	"integer shift"},
+    { ">>",	TclSingleOpCmd,		TclCompileRshiftOpCmd,
+		/* numArgs */ {2},	"integer shift"},
+    { "%",	TclSingleOpCmd,		TclCompileModOpCmd,
+		/* numArgs */ {2},	"integer integer"},
+    { "!=",	TclSingleOpCmd,		TclCompileNeqOpCmd,
+		/* numArgs */ {2},	"value value"},
+    { "ne",	TclSingleOpCmd,		TclCompileStrneqOpCmd,
+		/* numArgs */ {2},	"value value"},
+    { "in",	TclSingleOpCmd,		TclCompileInOpCmd,
+		/* numArgs */ {2},	"value list"},
+    { "ni",	TclSingleOpCmd,		TclCompileNiOpCmd,
+		/* numArgs */ {2},	"value list"},
+    { "-",	TclNoIdentOpCmd,	TclCompileMinusOpCmd,
+		/* unused */ {0},	"value ?value ...?"},
+    { "/",	TclNoIdentOpCmd,	TclCompileDivOpCmd,
+		/* unused */ {0},	"value ?value ...?"},
+    { "<",	TclSortingOpCmd,	TclCompileLessOpCmd,
+		/* unused */ {0},	NULL},
+    { "<=",	TclSortingOpCmd,	TclCompileLeqOpCmd,
+		/* unused */ {0},	NULL},
+    { ">",	TclSortingOpCmd,	TclCompileGreaterOpCmd,
+		/* unused */ {0},	NULL},
+    { ">=",	TclSortingOpCmd,	TclCompileGeqOpCmd,
+		/* unused */ {0},	NULL},
+    { "==",	TclSortingOpCmd,	TclCompileEqOpCmd,
+		/* unused */ {0},	NULL},
+    { "eq",	TclSortingOpCmd,	TclCompileStreqOpCmd,
+		/* unused */ {0},	NULL},
+    { NULL,	NULL,			NULL,
+		{0},			NULL}
+};
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclFinalizeEvaluation --
+ *
+ *	Finalizes the script cancellation hash table.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclFinalizeEvaluation(void)
+{
+    Tcl_MutexLock(&cancelLock);
+    if (cancelTableInitialized == 1) {
+	Tcl_DeleteHashTable(&cancelTable);
+	cancelTableInitialized = 0;
+    }
+    Tcl_MutexUnlock(&cancelLock);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_CreateInterp --
+ *
+ *	Create a new TCL command interpreter.
+ *
+ * Results:
+ *	The return value is a token for the interpreter, which may be used in
+ *	calls to functions like Tcl_CreateCmd, Tcl_Eval, or Tcl_DeleteInterp.
+ *
+ * Side effects:
+ *	The command interpreter is initialized with the built-in commands and
+ *	with the variables documented in tclvars(n).
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_Interp *
+Tcl_CreateInterp(void)
+{
+    Interp *iPtr;
+    Tcl_Interp *interp;
+    Command *cmdPtr;
+    const BuiltinFuncDef *builtinFuncPtr;
+    const OpCmdInfo *opcmdInfoPtr;
+    const CmdInfo *cmdInfoPtr;
+    Tcl_Namespace *mathfuncNSPtr, *mathopNSPtr;
+    Tcl_HashEntry *hPtr;
+    int isNew;
+    CancelInfo *cancelInfo;
+    union {
+	char c[sizeof(short)];
+	short s;
+    } order;
+#ifdef TCL_COMPILE_STATS
+    ByteCodeStats *statsPtr;
+#endif /* TCL_COMPILE_STATS */
+    char mathFuncName[32];
+    CallFrame *framePtr;
+
+    TclInitSubsystems();
+
+    /*
+     * Panic if someone updated the CallFrame structure without also updating
+     * the Tcl_CallFrame structure (or vice versa).
+     */
+
+    if (sizeof(Tcl_CallFrame) < sizeof(CallFrame)) {
+	/*NOTREACHED*/
+	Tcl_Panic("Tcl_CallFrame must not be smaller than CallFrame");
+    }
+
+#if defined(_WIN32) && !defined(_WIN64)
+    if (sizeof(time_t) != 4) {
+	/*NOTREACHED*/
+	Tcl_Panic("<time.h> is not compatible with MSVC");
+    }
+    if ((TclOffset(Tcl_StatBuf,st_atime) != 32)
+	    || (TclOffset(Tcl_StatBuf,st_ctime) != 40)) {
+	/*NOTREACHED*/
+	Tcl_Panic("<sys/stat.h> is not compatible with MSVC");
+    }
+#endif
+
+    if (cancelTableInitialized == 0) {
+	Tcl_MutexLock(&cancelLock);
+	if (cancelTableInitialized == 0) {
+	    Tcl_InitHashTable(&cancelTable, TCL_ONE_WORD_KEYS);
+	    cancelTableInitialized = 1;
+	}
+	Tcl_MutexUnlock(&cancelLock);
+    }
+
+    /*
+     * Initialize support for namespaces and create the global namespace
+     * (whose name is ""; an alias is "::"). This also initializes the Tcl
+     * object type table and other object management code.
+     */
+
+    iPtr = ckalloc(sizeof(Interp));
+    interp = (Tcl_Interp *) iPtr;
+
+    iPtr->result = iPtr->resultSpace;
+    iPtr->freeProc = NULL;
+    iPtr->errorLine = 0;
+    iPtr->objResultPtr = Tcl_NewObj();
+    Tcl_IncrRefCount(iPtr->objResultPtr);
+    iPtr->handle = TclHandleCreate(iPtr);
+    iPtr->globalNsPtr = NULL;
+    iPtr->hiddenCmdTablePtr = NULL;
+    iPtr->interpInfo = NULL;
+
+    TCL_CT_ASSERT(sizeof(iPtr->extra) <= sizeof(Tcl_HashTable));
+    iPtr->extra.optimizer = TclOptimizeBytecode;
+
+    iPtr->numLevels = 0;
+    iPtr->maxNestingDepth = MAX_NESTING_DEPTH;
+    iPtr->framePtr = NULL;	/* Initialise as soon as :: is available */
+    iPtr->varFramePtr = NULL;	/* Initialise as soon as :: is available */
+
+    /*
+     * TIP #280 - Initialize the arrays used to extend the ByteCode and Proc
+     * structures.
+     */
+
+    iPtr->cmdFramePtr = NULL;
+    iPtr->linePBodyPtr = ckalloc(sizeof(Tcl_HashTable));
+    iPtr->lineBCPtr = ckalloc(sizeof(Tcl_HashTable));
+    iPtr->lineLAPtr = ckalloc(sizeof(Tcl_HashTable));
+    iPtr->lineLABCPtr = ckalloc(sizeof(Tcl_HashTable));
+    Tcl_InitHashTable(iPtr->linePBodyPtr, TCL_ONE_WORD_KEYS);
+    Tcl_InitHashTable(iPtr->lineBCPtr, TCL_ONE_WORD_KEYS);
+    Tcl_InitHashTable(iPtr->lineLAPtr, TCL_ONE_WORD_KEYS);
+    Tcl_InitHashTable(iPtr->lineLABCPtr, TCL_ONE_WORD_KEYS);
+    iPtr->scriptCLLocPtr = NULL;
+
+    iPtr->activeVarTracePtr = NULL;
+
+    iPtr->returnOpts = NULL;
+    iPtr->errorInfo = NULL;
+    TclNewLiteralStringObj(iPtr->eiVar, "::errorInfo");
+    Tcl_IncrRefCount(iPtr->eiVar);
+    iPtr->errorStack = Tcl_NewListObj(0, NULL);
+    Tcl_IncrRefCount(iPtr->errorStack);
+    iPtr->resetErrorStack = 1;
+    TclNewLiteralStringObj(iPtr->upLiteral,"UP");
+    Tcl_IncrRefCount(iPtr->upLiteral);
+    TclNewLiteralStringObj(iPtr->callLiteral,"CALL");
+    Tcl_IncrRefCount(iPtr->callLiteral);
+    TclNewLiteralStringObj(iPtr->innerLiteral,"INNER");
+    Tcl_IncrRefCount(iPtr->innerLiteral);
+    iPtr->innerContext = Tcl_NewListObj(0, NULL);
+    Tcl_IncrRefCount(iPtr->innerContext);
+    iPtr->errorCode = NULL;
+    TclNewLiteralStringObj(iPtr->ecVar, "::errorCode");
+    Tcl_IncrRefCount(iPtr->ecVar);
+    iPtr->returnLevel = 1;
+    iPtr->returnCode = TCL_OK;
+
+    iPtr->rootFramePtr = NULL;	/* Initialise as soon as :: is available */
+    iPtr->lookupNsPtr = NULL;
+
+    iPtr->appendResult = NULL;
+    iPtr->appendAvl = 0;
+    iPtr->appendUsed = 0;
+
+    Tcl_InitHashTable(&iPtr->packageTable, TCL_STRING_KEYS);
+    iPtr->packageUnknown = NULL;
+
+    /* TIP #268 */
+    if (getenv("TCL_PKG_PREFER_LATEST") == NULL) {
+	iPtr->packagePrefer = PKG_PREFER_STABLE;
+    } else {
+	iPtr->packagePrefer = PKG_PREFER_LATEST;
+    }
+
+    iPtr->cmdCount = 0;
+    TclInitLiteralTable(&iPtr->literalTable);
+    iPtr->compileEpoch = 0;
+    iPtr->compiledProcPtr = NULL;
+    iPtr->resolverPtr = NULL;
+    iPtr->evalFlags = 0;
+    iPtr->scriptFile = NULL;
+    iPtr->flags = 0;
+    iPtr->tracePtr = NULL;
+    iPtr->tracesForbiddingInline = 0;
+    iPtr->activeCmdTracePtr = NULL;
+    iPtr->activeInterpTracePtr = NULL;
+    iPtr->assocData = NULL;
+    iPtr->execEnvPtr = NULL;	/* Set after namespaces initialized. */
+    iPtr->emptyObjPtr = Tcl_NewObj();
+				/* Another empty object. */
+    Tcl_IncrRefCount(iPtr->emptyObjPtr);
+    iPtr->resultSpace[0] = 0;
+    iPtr->threadId = Tcl_GetCurrentThread();
+
+    /* TIP #378 */
+#ifdef TCL_INTERP_DEBUG_FRAME
+    iPtr->flags |= INTERP_DEBUG_FRAME;
+#else
+    if (getenv("TCL_INTERP_DEBUG_FRAME") != NULL) {
+        iPtr->flags |= INTERP_DEBUG_FRAME;
+    }
+#endif
+
+    /*
+     * Initialise the tables for variable traces and searches *before*
+     * creating the global ns - so that the trace on errorInfo can be
+     * recorded.
+     */
+
+    Tcl_InitHashTable(&iPtr->varTraces, TCL_ONE_WORD_KEYS);
+    Tcl_InitHashTable(&iPtr->varSearches, TCL_ONE_WORD_KEYS);
+
+    iPtr->globalNsPtr = NULL;	/* Force creation of global ns below. */
+    iPtr->globalNsPtr = (Namespace *) Tcl_CreateNamespace(interp, "",
+	    NULL, NULL);
+    if (iPtr->globalNsPtr == NULL) {
+	Tcl_Panic("Tcl_CreateInterp: can't create global namespace");
+    }
+
+    /*
+     * Initialise the rootCallframe. It cannot be allocated on the stack, as
+     * it has to be in place before TclCreateExecEnv tries to use a variable.
+     */
+
+    /* This is needed to satisfy GCC 3.3's strict aliasing rules */
+    framePtr = ckalloc(sizeof(CallFrame));
+    (void) Tcl_PushCallFrame(interp, (Tcl_CallFrame *) framePtr,
+	    (Tcl_Namespace *) iPtr->globalNsPtr, /*isProcCallFrame*/ 0);
+    framePtr->objc = 0;
+
+    iPtr->framePtr = framePtr;
+    iPtr->varFramePtr = framePtr;
+    iPtr->rootFramePtr = framePtr;
+
+    /*
+     * Initialize support for code compilation and execution. We call
+     * TclCreateExecEnv after initializing namespaces since it tries to
+     * reference a Tcl variable (it links to the Tcl "tcl_traceExec"
+     * variable).
+     */
+
+    iPtr->execEnvPtr = TclCreateExecEnv(interp, INTERP_STACK_INITIAL_SIZE);
+
+    /*
+     * TIP #219, Tcl Channel Reflection API support.
+     */
+
+    iPtr->chanMsg = NULL;
+
+    /*
+     * TIP #285, Script cancellation support.
+     */
+
+    iPtr->asyncCancelMsg = Tcl_NewObj();
+
+    cancelInfo = ckalloc(sizeof(CancelInfo));
+    cancelInfo->interp = interp;
+
+    iPtr->asyncCancel = Tcl_AsyncCreate(CancelEvalProc, cancelInfo);
+    cancelInfo->async = iPtr->asyncCancel;
+    cancelInfo->result = NULL;
+    cancelInfo->length = 0;
+
+    Tcl_MutexLock(&cancelLock);
+    hPtr = Tcl_CreateHashEntry(&cancelTable, iPtr, &isNew);
+    Tcl_SetHashValue(hPtr, cancelInfo);
+    Tcl_MutexUnlock(&cancelLock);
+
+    /*
+     * Initialize the compilation and execution statistics kept for this
+     * interpreter.
+     */
+
+#ifdef TCL_COMPILE_STATS
+    statsPtr = &iPtr->stats;
+    statsPtr->numExecutions = 0;
+    statsPtr->numCompilations = 0;
+    statsPtr->numByteCodesFreed = 0;
+    memset(statsPtr->instructionCount, 0,
+	    sizeof(statsPtr->instructionCount));
+
+    statsPtr->totalSrcBytes = 0.0;
+    statsPtr->totalByteCodeBytes = 0.0;
+    statsPtr->currentSrcBytes = 0.0;
+    statsPtr->currentByteCodeBytes = 0.0;
+    memset(statsPtr->srcCount, 0, sizeof(statsPtr->srcCount));
+    memset(statsPtr->byteCodeCount, 0, sizeof(statsPtr->byteCodeCount));
+    memset(statsPtr->lifetimeCount, 0, sizeof(statsPtr->lifetimeCount));
+
+    statsPtr->currentInstBytes = 0.0;
+    statsPtr->currentLitBytes = 0.0;
+    statsPtr->currentExceptBytes = 0.0;
+    statsPtr->currentAuxBytes = 0.0;
+    statsPtr->currentCmdMapBytes = 0.0;
+
+    statsPtr->numLiteralsCreated = 0;
+    statsPtr->totalLitStringBytes = 0.0;
+    statsPtr->currentLitStringBytes = 0.0;
+    memset(statsPtr->literalCount, 0, sizeof(statsPtr->literalCount));
+#endif /* TCL_COMPILE_STATS */
+
+    /*
+     * Initialise the stub table pointer.
+     */
+
+    iPtr->stubTable = &tclStubs;
+
+    /*
+     * Initialize the ensemble error message rewriting support.
+     */
+
+    TclResetRewriteEnsemble(interp, 1);
+
+    /*
+     * TIP#143: Initialise the resource limit support.
+     */
+
+    TclInitLimitSupport(interp);
+
+    /*
+     * Initialise the thread-specific data ekeko. Note that the thread's alloc
+     * cache was already initialised by the call to alloc the interp struct.
+     */
+
+#if defined(TCL_THREADS) && defined(USE_THREAD_ALLOC)
+    iPtr->allocCache = TclpGetAllocCache();
+#else
+    iPtr->allocCache = NULL;
+#endif
+    iPtr->pendingObjDataPtr = NULL;
+    iPtr->asyncReadyPtr = TclGetAsyncReadyPtr();
+    iPtr->deferredCallbacks = NULL;
+
+    /*
+     * Create the core commands. Do it here, rather than calling
+     * Tcl_CreateCommand, because it's faster (there's no need to check for a
+     * pre-existing command by the same name). If a command has a Tcl_CmdProc
+     * but no Tcl_ObjCmdProc, set the Tcl_ObjCmdProc to
+     * TclInvokeStringCommand. This is an object-based wrapper function that
+     * extracts strings, calls the string function, and creates an object for
+     * the result. Similarly, if a command has a Tcl_ObjCmdProc but no
+     * Tcl_CmdProc, set the Tcl_CmdProc to TclInvokeObjectCommand.
+     */
+
+    for (cmdInfoPtr = builtInCmds; cmdInfoPtr->name != NULL; cmdInfoPtr++) {
+	if ((cmdInfoPtr->objProc == NULL)
+		&& (cmdInfoPtr->compileProc == NULL)
+		&& (cmdInfoPtr->nreProc == NULL)) {
+	    Tcl_Panic("builtin command with NULL object command proc and a NULL compile proc");
+	}
+
+	hPtr = Tcl_CreateHashEntry(&iPtr->globalNsPtr->cmdTable,
+		cmdInfoPtr->name, &isNew);
+	if (isNew) {
+	    cmdPtr = ckalloc(sizeof(Command));
+	    cmdPtr->hPtr = hPtr;
+	    cmdPtr->nsPtr = iPtr->globalNsPtr;
+	    cmdPtr->refCount = 1;
+	    cmdPtr->cmdEpoch = 0;
+	    cmdPtr->compileProc = cmdInfoPtr->compileProc;
+	    cmdPtr->proc = TclInvokeObjectCommand;
+	    cmdPtr->clientData = cmdPtr;
+	    cmdPtr->objProc = cmdInfoPtr->objProc;
+	    cmdPtr->objClientData = NULL;
+	    cmdPtr->deleteProc = NULL;
+	    cmdPtr->deleteData = NULL;
+	    cmdPtr->flags = 0;
+            if (cmdInfoPtr->flags & CMD_COMPILES_EXPANDED) {
+                cmdPtr->flags |= CMD_COMPILES_EXPANDED;
+            }
+	    cmdPtr->importRefPtr = NULL;
+	    cmdPtr->tracePtr = NULL;
+	    cmdPtr->nreProc = cmdInfoPtr->nreProc;
+	    Tcl_SetHashValue(hPtr, cmdPtr);
+	}
+    }
+
+    /*
+     * Create the "array", "binary", "chan", "dict", "file", "info",
+     * "namespace" and "string" ensembles. Note that all these commands (and
+     * their subcommands that are not present in the global namespace) are
+     * wholly safe *except* for "file".
+     */
+
+    TclInitArrayCmd(interp);
+    TclInitBinaryCmd(interp);
+    TclInitChanCmd(interp);
+    TclInitDictCmd(interp);
+    TclInitFileCmd(interp);
+    TclInitInfoCmd(interp);
+    TclInitNamespaceCmd(interp);
+    TclInitStringCmd(interp);
+    TclInitPrefixCmd(interp);
+
+    /*
+     * Register "clock" subcommands. These *do* go through
+     * Tcl_CreateObjCommand, since they aren't in the global namespace and
+     * involve ensembles.
+     */
+
+    TclClockInit(interp);
+
+    /*
+     * Register the built-in functions. This is empty now that they are
+     * implemented as commands in the ::tcl::mathfunc namespace.
+     */
+
+    /*
+     * Register the default [interp bgerror] handler.
+     */
+
+    Tcl_CreateObjCommand(interp, "::tcl::Bgerror",
+	    TclDefaultBgErrorHandlerObjCmd, NULL, NULL);
+
+    /*
+     * Create unsupported commands for debugging bytecode and objects.
+     */
+
+    Tcl_CreateObjCommand(interp, "::tcl::unsupported::disassemble",
+	    Tcl_DisassembleObjCmd, INT2PTR(0), NULL);
+    Tcl_CreateObjCommand(interp, "::tcl::unsupported::getbytecode",
+	    Tcl_DisassembleObjCmd, INT2PTR(1), NULL);
+    Tcl_CreateObjCommand(interp, "::tcl::unsupported::representation",
+	    Tcl_RepresentationCmd, NULL, NULL);
+
+    /* Adding the bytecode assembler command */
+    cmdPtr = (Command *) Tcl_NRCreateCommand(interp,
+            "::tcl::unsupported::assemble", Tcl_AssembleObjCmd,
+            TclNRAssembleObjCmd, NULL, NULL);
+    cmdPtr->compileProc = &TclCompileAssembleCmd;
+
+    Tcl_NRCreateCommand(interp, "::tcl::unsupported::inject", NULL,
+	    NRCoroInjectObjCmd, NULL, NULL);
+
+#ifdef USE_DTRACE
+    /*
+     * Register the tcl::dtrace command.
+     */
+
+    Tcl_CreateObjCommand(interp, "::tcl::dtrace", DTraceObjCmd, NULL, NULL);
+#endif /* USE_DTRACE */
+
+    /*
+     * Register the builtin math functions.
+     */
+
+    mathfuncNSPtr = Tcl_CreateNamespace(interp, "::tcl::mathfunc", NULL,NULL);
+    if (mathfuncNSPtr == NULL) {
+	Tcl_Panic("Can't create math function namespace");
+    }
+#define MATH_FUNC_PREFIX_LEN 17 /* == strlen("::tcl::mathfunc::") */
+    memcpy(mathFuncName, "::tcl::mathfunc::", MATH_FUNC_PREFIX_LEN);
+    for (builtinFuncPtr = BuiltinFuncTable; builtinFuncPtr->name != NULL;
+	    builtinFuncPtr++) {
+	strcpy(mathFuncName+MATH_FUNC_PREFIX_LEN, builtinFuncPtr->name);
+	Tcl_CreateObjCommand(interp, mathFuncName,
+		builtinFuncPtr->objCmdProc, builtinFuncPtr->clientData, NULL);
+	Tcl_Export(interp, mathfuncNSPtr, builtinFuncPtr->name, 0);
+    }
+
+    /*
+     * Register the mathematical "operator" commands. [TIP #174]
+     */
+
+    mathopNSPtr = Tcl_CreateNamespace(interp, "::tcl::mathop", NULL, NULL);
+    if (mathopNSPtr == NULL) {
+	Tcl_Panic("can't create math operator namespace");
+    }
+    Tcl_Export(interp, mathopNSPtr, "*", 1);
+#define MATH_OP_PREFIX_LEN 15 /* == strlen("::tcl::mathop::") */
+    memcpy(mathFuncName, "::tcl::mathop::", MATH_OP_PREFIX_LEN);
+    for (opcmdInfoPtr=mathOpCmds ; opcmdInfoPtr->name!=NULL ; opcmdInfoPtr++){
+	TclOpCmdClientData *occdPtr = ckalloc(sizeof(TclOpCmdClientData));
+
+	occdPtr->op = opcmdInfoPtr->name;
+	occdPtr->i.numArgs = opcmdInfoPtr->i.numArgs;
+	occdPtr->expected = opcmdInfoPtr->expected;
+	strcpy(mathFuncName + MATH_OP_PREFIX_LEN, opcmdInfoPtr->name);
+	cmdPtr = (Command *) Tcl_CreateObjCommand(interp, mathFuncName,
+		opcmdInfoPtr->objProc, occdPtr, DeleteOpCmdClientData);
+	if (cmdPtr == NULL) {
+	    Tcl_Panic("failed to create math operator %s",
+		    opcmdInfoPtr->name);
+	} else if (opcmdInfoPtr->compileProc != NULL) {
+	    cmdPtr->compileProc = opcmdInfoPtr->compileProc;
+	}
+    }
+
+    /*
+     * Do Multiple/Safe Interps Tcl init stuff
+     */
+
+    TclInterpInit(interp);
+    TclSetupEnv(interp);
+
+    /*
+     * TIP #59: Make embedded configuration information available.
+     */
+
+    TclInitEmbeddedConfigurationInformation(interp);
+
+    /*
+     * TIP #440: Declare the name of the script engine to be "Tcl".
+     */
+
+    Tcl_SetVar2(interp, "tcl_platform", "engine", "Tcl",
+	    TCL_GLOBAL_ONLY);
+
+    /*
+     * Compute the byte order of this machine.
+     */
+
+    order.s = 1;
+    Tcl_SetVar2(interp, "tcl_platform", "byteOrder",
+	    ((order.c[0] == 1) ? "littleEndian" : "bigEndian"),
+	    TCL_GLOBAL_ONLY);
+
+    Tcl_SetVar2Ex(interp, "tcl_platform", "wordSize",
+	    Tcl_NewLongObj((long) sizeof(long)), TCL_GLOBAL_ONLY);
+
+    /* TIP #291 */
+    Tcl_SetVar2Ex(interp, "tcl_platform", "pointerSize",
+	    Tcl_NewLongObj((long) sizeof(void *)), TCL_GLOBAL_ONLY);
+
+    /*
+     * Set up other variables such as tcl_version and tcl_library
+     */
+
+    Tcl_SetVar(interp, "tcl_patchLevel", TCL_PATCH_LEVEL, TCL_GLOBAL_ONLY);
+    Tcl_SetVar(interp, "tcl_version", TCL_VERSION, TCL_GLOBAL_ONLY);
+    Tcl_TraceVar2(interp, "tcl_precision", NULL,
+	    TCL_GLOBAL_ONLY|TCL_TRACE_READS|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
+	    TclPrecTraceProc, NULL);
+    TclpSetVariables(interp);
+
+#ifdef TCL_THREADS
+    /*
+     * The existence of the "threaded" element of the tcl_platform array
+     * indicates that this particular Tcl shell has been compiled with threads
+     * turned on. Using "info exists tcl_platform(threaded)" a Tcl script can
+     * introspect on the interpreter level of thread safety.
+     */
+
+    Tcl_SetVar2(interp, "tcl_platform", "threaded", "1", TCL_GLOBAL_ONLY);
+#endif
+
+    /*
+     * Register Tcl's version number.
+     * TIP #268: Full patchlevel instead of just major.minor
+     */
+
+    Tcl_PkgProvideEx(interp, "Tcl", TCL_PATCH_LEVEL, &tclStubs);
+
+    if (TclTommath_Init(interp) != TCL_OK) {
+	Tcl_Panic("%s", Tcl_GetString(Tcl_GetObjResult(interp)));
+    }
+
+    if (TclOOInit(interp) != TCL_OK) {
+	Tcl_Panic("%s", Tcl_GetString(Tcl_GetObjResult(interp)));
+    }
+
+    /*
+     * Only build in zlib support if we've successfully detected a library to
+     * compile and link against.
+     */
+
+#ifdef HAVE_ZLIB
+    if (TclZlibInit(interp) != TCL_OK) {
+	Tcl_Panic("%s", Tcl_GetString(Tcl_GetObjResult(interp)));
+    }
+#endif
+
+    TOP_CB(iPtr) = NULL;
+    return interp;
+}
+
+static void
+DeleteOpCmdClientData(
+    ClientData clientData)
+{
+    TclOpCmdClientData *occdPtr = clientData;
+
+    ckfree(occdPtr);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclHideUnsafeCommands --
+ *
+ *	Hides base commands that are not marked as safe from this interpreter.
+ *
+ * Results:
+ *	TCL_OK if it succeeds, TCL_ERROR else.
+ *
+ * Side effects:
+ *	Hides functionality in an interpreter.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclHideUnsafeCommands(
+    Tcl_Interp *interp)		/* Hide commands in this interpreter. */
+{
+    register const CmdInfo *cmdInfoPtr;
+
+    if (interp == NULL) {
+	return TCL_ERROR;
+    }
+    for (cmdInfoPtr = builtInCmds; cmdInfoPtr->name != NULL; cmdInfoPtr++) {
+	if (!(cmdInfoPtr->flags & CMD_IS_SAFE)) {
+	    Tcl_HideCommand(interp, cmdInfoPtr->name, cmdInfoPtr->name);
+	}
+    }
+    TclMakeFileCommandSafe(interp);     /* Ugh! */
+    return TCL_OK;
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * Tcl_CallWhenDeleted --
+ *
+ *	Arrange for a function to be called before a given interpreter is
+ *	deleted. The function is called as soon as Tcl_DeleteInterp is called;
+ *	if Tcl_CallWhenDeleted is called on an interpreter that has already
+ *	been deleted, the function will be called when the last Tcl_Release is
+ *	done on the interpreter.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	When Tcl_DeleteInterp is invoked to delete interp, proc will be
+ *	invoked. See the manual entry for details.
+ *
+ *--------------------------------------------------------------
+ */
+
+void
+Tcl_CallWhenDeleted(
+    Tcl_Interp *interp,		/* Interpreter to watch. */
+    Tcl_InterpDeleteProc *proc,	/* Function to call when interpreter is about
+				 * to be deleted. */
+    ClientData clientData)	/* One-word value to pass to proc. */
+{
+    Interp *iPtr = (Interp *) interp;
+    static Tcl_ThreadDataKey assocDataCounterKey;
+    int *assocDataCounterPtr =
+	    Tcl_GetThreadData(&assocDataCounterKey, (int)sizeof(int));
+    int isNew;
+    char buffer[32 + TCL_INTEGER_SPACE];
+    AssocData *dPtr = ckalloc(sizeof(AssocData));
+    Tcl_HashEntry *hPtr;
+
+    sprintf(buffer, "Assoc Data Key #%d", *assocDataCounterPtr);
+    (*assocDataCounterPtr)++;
+
+    if (iPtr->assocData == NULL) {
+	iPtr->assocData = ckalloc(sizeof(Tcl_HashTable));
+	Tcl_InitHashTable(iPtr->assocData, TCL_STRING_KEYS);
+    }
+    hPtr = Tcl_CreateHashEntry(iPtr->assocData, buffer, &isNew);
+    dPtr->proc = proc;
+    dPtr->clientData = clientData;
+    Tcl_SetHashValue(hPtr, dPtr);
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * Tcl_DontCallWhenDeleted --
+ *
+ *	Cancel the arrangement for a function to be called when a given
+ *	interpreter is deleted.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	If proc and clientData were previously registered as a callback via
+ *	Tcl_CallWhenDeleted, they are unregistered. If they weren't previously
+ *	registered then nothing happens.
+ *
+ *--------------------------------------------------------------
+ */
+
+void
+Tcl_DontCallWhenDeleted(
+    Tcl_Interp *interp,		/* Interpreter to watch. */
+    Tcl_InterpDeleteProc *proc,	/* Function to call when interpreter is about
+				 * to be deleted. */
+    ClientData clientData)	/* One-word value to pass to proc. */
+{
+    Interp *iPtr = (Interp *) interp;
+    Tcl_HashTable *hTablePtr;
+    Tcl_HashSearch hSearch;
+    Tcl_HashEntry *hPtr;
+    AssocData *dPtr;
+
+    hTablePtr = iPtr->assocData;
+    if (hTablePtr == NULL) {
+	return;
+    }
+    for (hPtr = Tcl_FirstHashEntry(hTablePtr, &hSearch); hPtr != NULL;
+	    hPtr = Tcl_NextHashEntry(&hSearch)) {
+	dPtr = Tcl_GetHashValue(hPtr);
+	if ((dPtr->proc == proc) && (dPtr->clientData == clientData)) {
+	    ckfree(dPtr);
+	    Tcl_DeleteHashEntry(hPtr);
+	    return;
+	}
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_SetAssocData --
+ *
+ *	Creates a named association between user-specified data, a delete
+ *	function and this interpreter. If the association already exists the
+ *	data is overwritten with the new data. The delete function will be
+ *	invoked when the interpreter is deleted.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Sets the associated data, creates the association if needed.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_SetAssocData(
+    Tcl_Interp *interp,		/* Interpreter to associate with. */
+    const char *name,		/* Name for association. */
+    Tcl_InterpDeleteProc *proc,	/* Proc to call when interpreter is about to
+				 * be deleted. */
+    ClientData clientData)	/* One-word value to pass to proc. */
+{
+    Interp *iPtr = (Interp *) interp;
+    AssocData *dPtr;
+    Tcl_HashEntry *hPtr;
+    int isNew;
+
+    if (iPtr->assocData == NULL) {
+	iPtr->assocData = ckalloc(sizeof(Tcl_HashTable));
+	Tcl_InitHashTable(iPtr->assocData, TCL_STRING_KEYS);
+    }
+    hPtr = Tcl_CreateHashEntry(iPtr->assocData, name, &isNew);
+    if (isNew == 0) {
+	dPtr = Tcl_GetHashValue(hPtr);
+    } else {
+	dPtr = ckalloc(sizeof(AssocData));
+    }
+    dPtr->proc = proc;
+    dPtr->clientData = clientData;
+
+    Tcl_SetHashValue(hPtr, dPtr);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_DeleteAssocData --
+ *
+ *	Deletes a named association of user-specified data with the specified
+ *	interpreter.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Deletes the association.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_DeleteAssocData(
+    Tcl_Interp *interp,		/* Interpreter to associate with. */
+    const char *name)		/* Name of association. */
+{
+    Interp *iPtr = (Interp *) interp;
+    AssocData *dPtr;
+    Tcl_HashEntry *hPtr;
+
+    if (iPtr->assocData == NULL) {
+	return;
+    }
+    hPtr = Tcl_FindHashEntry(iPtr->assocData, name);
+    if (hPtr == NULL) {
+	return;
+    }
+    dPtr = Tcl_GetHashValue(hPtr);
+    if (dPtr->proc != NULL) {
+	dPtr->proc(dPtr->clientData, interp);
+    }
+    ckfree(dPtr);
+    Tcl_DeleteHashEntry(hPtr);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_GetAssocData --
+ *
+ *	Returns the client data associated with this name in the specified
+ *	interpreter.
+ *
+ * Results:
+ *	The client data in the AssocData record denoted by the named
+ *	association, or NULL.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+ClientData
+Tcl_GetAssocData(
+    Tcl_Interp *interp,		/* Interpreter associated with. */
+    const char *name,		/* Name of association. */
+    Tcl_InterpDeleteProc **procPtr)
+				/* Pointer to place to store address of
+				 * current deletion callback. */
+{
+    Interp *iPtr = (Interp *) interp;
+    AssocData *dPtr;
+    Tcl_HashEntry *hPtr;
+
+    if (iPtr->assocData == NULL) {
+	return NULL;
+    }
+    hPtr = Tcl_FindHashEntry(iPtr->assocData, name);
+    if (hPtr == NULL) {
+	return NULL;
+    }
+    dPtr = Tcl_GetHashValue(hPtr);
+    if (procPtr != NULL) {
+	*procPtr = dPtr->proc;
+    }
+    return dPtr->clientData;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_InterpDeleted --
+ *
+ *	Returns nonzero if the interpreter has been deleted with a call to
+ *	Tcl_DeleteInterp.
+ *
+ * Results:
+ *	Nonzero if the interpreter is deleted, zero otherwise.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_InterpDeleted(
+    Tcl_Interp *interp)
+{
+    return (((Interp *) interp)->flags & DELETED) ? 1 : 0;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_DeleteInterp --
+ *
+ *	Ensures that the interpreter will be deleted eventually. If there are
+ *	no Tcl_Preserve calls in effect for this interpreter, it is deleted
+ *	immediately, otherwise the interpreter is deleted when the last
+ *	Tcl_Preserve is matched by a call to Tcl_Release. In either case, the
+ *	function runs the currently registered deletion callbacks.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The interpreter is marked as deleted. The caller may still use it
+ *	safely if there are calls to Tcl_Preserve in effect for the
+ *	interpreter, but further calls to Tcl_Eval etc in this interpreter
+ *	will fail.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_DeleteInterp(
+    Tcl_Interp *interp)		/* Token for command interpreter (returned by
+				 * a previous call to Tcl_CreateInterp). */
+{
+    Interp *iPtr = (Interp *) interp;
+
+    /*
+     * If the interpreter has already been marked deleted, just punt.
+     */
+
+    if (iPtr->flags & DELETED) {
+	return;
+    }
+
+    /*
+     * Mark the interpreter as deleted. No further evals will be allowed.
+     * Increase the compileEpoch as a signal to compiled bytecodes.
+     */
+
+    iPtr->flags |= DELETED;
+    iPtr->compileEpoch++;
+
+    /*
+     * Ensure that the interpreter is eventually deleted.
+     */
+
+    Tcl_EventuallyFree(interp, (Tcl_FreeProc *) DeleteInterpProc);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * DeleteInterpProc --
+ *
+ *	Helper function to delete an interpreter. This function is called when
+ *	the last call to Tcl_Preserve on this interpreter is matched by a call
+ *	to Tcl_Release. The function cleans up all resources used in the
+ *	interpreter and calls all currently registered interpreter deletion
+ *	callbacks.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Whatever the interpreter deletion callbacks do. Frees resources used
+ *	by the interpreter.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+DeleteInterpProc(
+    Tcl_Interp *interp)		/* Interpreter to delete. */
+{
+    Interp *iPtr = (Interp *) interp;
+    Tcl_HashEntry *hPtr;
+    Tcl_HashSearch search;
+    Tcl_HashTable *hTablePtr;
+    ResolverScheme *resPtr, *nextResPtr;
+    int i;
+
+    /*
+     * Punt if there is an error in the Tcl_Release/Tcl_Preserve matchup,
+	 * unless we are exiting.
+     */
+
+    if ((iPtr->numLevels > 0) && !TclInExit()) {
+	Tcl_Panic("DeleteInterpProc called with active evals");
+    }
+
+    /*
+     * The interpreter should already be marked deleted; otherwise how did we
+     * get here?
+     */
+
+    if (!(iPtr->flags & DELETED)) {
+	Tcl_Panic("DeleteInterpProc called on interpreter not marked deleted");
+    }
+
+    /*
+     * TIP #219, Tcl Channel Reflection API. Discard a leftover state.
+     */
+
+    if (iPtr->chanMsg != NULL) {
+	Tcl_DecrRefCount(iPtr->chanMsg);
+	iPtr->chanMsg = NULL;
+    }
+
+    /*
+     * TIP #285, Script cancellation support. Delete this interp from the
+     * global hash table of CancelInfo structs.
+     */
+
+    Tcl_MutexLock(&cancelLock);
+    hPtr = Tcl_FindHashEntry(&cancelTable, (char *) iPtr);
+    if (hPtr != NULL) {
+	CancelInfo *cancelInfo = Tcl_GetHashValue(hPtr);
+
+	if (cancelInfo != NULL) {
+	    if (cancelInfo->result != NULL) {
+		ckfree(cancelInfo->result);
+	    }
+	    ckfree(cancelInfo);
+	}
+
+	Tcl_DeleteHashEntry(hPtr);
+    }
+
+    if (iPtr->asyncCancel != NULL) {
+	Tcl_AsyncDelete(iPtr->asyncCancel);
+	iPtr->asyncCancel = NULL;
+    }
+
+    if (iPtr->asyncCancelMsg != NULL) {
+	Tcl_DecrRefCount(iPtr->asyncCancelMsg);
+	iPtr->asyncCancelMsg = NULL;
+    }
+    Tcl_MutexUnlock(&cancelLock);
+
+    /*
+     * Shut down all limit handler callback scripts that call back into this
+     * interpreter. Then eliminate all limit handlers for this interpreter.
+     */
+
+    TclRemoveScriptLimitCallbacks(interp);
+    TclLimitRemoveAllHandlers(interp);
+
+    /*
+     * Dismantle the namespace here, before we clear the assocData. If any
+     * background errors occur here, they will be deleted below.
+     *
+     * Dismantle the namespace after freeing the iPtr->handle so that each
+     * bytecode releases its literals without caring to update the literal
+     * table, as it will be freed later in this function without further use.
+     */
+
+    TclHandleFree(iPtr->handle);
+    TclTeardownNamespace(iPtr->globalNsPtr);
+
+    /*
+     * Delete all the hidden commands.
+     */
+
+    hTablePtr = iPtr->hiddenCmdTablePtr;
+    if (hTablePtr != NULL) {
+	/*
+	 * Non-pernicious deletion. The deletion callbacks will not be allowed
+	 * to create any new hidden or non-hidden commands.
+	 * Tcl_DeleteCommandFromToken will remove the entry from the
+	 * hiddenCmdTablePtr.
+	 */
+
+	hPtr = Tcl_FirstHashEntry(hTablePtr, &search);
+	for (; hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) {
+	    Tcl_DeleteCommandFromToken(interp, Tcl_GetHashValue(hPtr));
+	}
+	Tcl_DeleteHashTable(hTablePtr);
+	ckfree(hTablePtr);
+    }
+
+    /*
+     * Invoke deletion callbacks; note that a callback can create new
+     * callbacks, so we iterate.
+     */
+
+    while (iPtr->assocData != NULL) {
+	AssocData *dPtr;
+
+	hTablePtr = iPtr->assocData;
+	iPtr->assocData = NULL;
+	for (hPtr = Tcl_FirstHashEntry(hTablePtr, &search);
+		hPtr != NULL;
+		hPtr = Tcl_FirstHashEntry(hTablePtr, &search)) {
+	    dPtr = Tcl_GetHashValue(hPtr);
+	    Tcl_DeleteHashEntry(hPtr);
+	    if (dPtr->proc != NULL) {
+		dPtr->proc(dPtr->clientData, interp);
+	    }
+	    ckfree(dPtr);
+	}
+	Tcl_DeleteHashTable(hTablePtr);
+	ckfree(hTablePtr);
+    }
+
+    /*
+     * Pop the root frame pointer and finish deleting the global
+     * namespace. The order is important [Bug 1658572].
+     */
+
+    if ((iPtr->framePtr != iPtr->rootFramePtr) && !TclInExit()) {
+	Tcl_Panic("DeleteInterpProc: popping rootCallFrame with other frames on top");
+    }
+    Tcl_PopCallFrame(interp);
+    ckfree(iPtr->rootFramePtr);
+    iPtr->rootFramePtr = NULL;
+    Tcl_DeleteNamespace((Tcl_Namespace *) iPtr->globalNsPtr);
+
+    /*
+     * Free up the result *after* deleting variables, since variable deletion
+     * could have transferred ownership of the result string to Tcl.
+     */
+
+    Tcl_FreeResult(interp);
+    iPtr->result = NULL;
+    Tcl_DecrRefCount(iPtr->objResultPtr);
+    iPtr->objResultPtr = NULL;
+    Tcl_DecrRefCount(iPtr->ecVar);
+    if (iPtr->errorCode) {
+	Tcl_DecrRefCount(iPtr->errorCode);
+	iPtr->errorCode = NULL;
+    }
+    Tcl_DecrRefCount(iPtr->eiVar);
+    if (iPtr->errorInfo) {
+	Tcl_DecrRefCount(iPtr->errorInfo);
+	iPtr->errorInfo = NULL;
+    }
+    Tcl_DecrRefCount(iPtr->errorStack);
+    iPtr->errorStack = NULL;
+    Tcl_DecrRefCount(iPtr->upLiteral);
+    Tcl_DecrRefCount(iPtr->callLiteral);
+    Tcl_DecrRefCount(iPtr->innerLiteral);
+    Tcl_DecrRefCount(iPtr->innerContext);
+    if (iPtr->returnOpts) {
+	Tcl_DecrRefCount(iPtr->returnOpts);
+    }
+    if (iPtr->appendResult != NULL) {
+	ckfree(iPtr->appendResult);
+	iPtr->appendResult = NULL;
+    }
+    TclFreePackageInfo(iPtr);
+    while (iPtr->tracePtr != NULL) {
+	Tcl_DeleteTrace((Tcl_Interp *) iPtr, (Tcl_Trace) iPtr->tracePtr);
+    }
+    if (iPtr->execEnvPtr != NULL) {
+	TclDeleteExecEnv(iPtr->execEnvPtr);
+    }
+    if (iPtr->scriptFile) {
+	Tcl_DecrRefCount(iPtr->scriptFile);
+	iPtr->scriptFile = NULL;
+    }
+    Tcl_DecrRefCount(iPtr->emptyObjPtr);
+    iPtr->emptyObjPtr = NULL;
+
+    resPtr = iPtr->resolverPtr;
+    while (resPtr) {
+	nextResPtr = resPtr->nextPtr;
+	ckfree(resPtr->name);
+	ckfree(resPtr);
+	resPtr = nextResPtr;
+    }
+
+    /*
+     * Free up literal objects created for scripts compiled by the
+     * interpreter.
+     */
+
+    TclDeleteLiteralTable(interp, &iPtr->literalTable);
+
+    /*
+     * TIP #280 - Release the arrays for ByteCode/Proc extension, and
+     * contents.
+     */
+
+    for (hPtr = Tcl_FirstHashEntry(iPtr->linePBodyPtr, &search);
+	    hPtr != NULL;
+	    hPtr = Tcl_NextHashEntry(&search)) {
+	CmdFrame *cfPtr = Tcl_GetHashValue(hPtr);
+	Proc *procPtr = (Proc *) Tcl_GetHashKey(iPtr->linePBodyPtr, hPtr);
+
+	procPtr->iPtr = NULL;
+	if (cfPtr) {
+	    if (cfPtr->type == TCL_LOCATION_SOURCE) {
+		Tcl_DecrRefCount(cfPtr->data.eval.path);
+	    }
+	    ckfree(cfPtr->line);
+	    ckfree(cfPtr);
+	}
+	Tcl_DeleteHashEntry(hPtr);
+    }
+    Tcl_DeleteHashTable(iPtr->linePBodyPtr);
+    ckfree(iPtr->linePBodyPtr);
+    iPtr->linePBodyPtr = NULL;
+
+    /*
+     * See also tclCompile.c, TclCleanupByteCode
+     */
+
+    for (hPtr = Tcl_FirstHashEntry(iPtr->lineBCPtr, &search);
+	    hPtr != NULL;
+	    hPtr = Tcl_NextHashEntry(&search)) {
+	ExtCmdLoc *eclPtr = Tcl_GetHashValue(hPtr);
+
+	if (eclPtr->type == TCL_LOCATION_SOURCE) {
+	    Tcl_DecrRefCount(eclPtr->path);
+	}
+	for (i=0; i< eclPtr->nuloc; i++) {
+	    ckfree(eclPtr->loc[i].line);
+	}
+
+	if (eclPtr->loc != NULL) {
+	    ckfree(eclPtr->loc);
+	}
+
+	ckfree(eclPtr);
+	Tcl_DeleteHashEntry(hPtr);
+    }
+    Tcl_DeleteHashTable(iPtr->lineBCPtr);
+    ckfree(iPtr->lineBCPtr);
+    iPtr->lineBCPtr = NULL;
+
+    /*
+     * Location stack for uplevel/eval/... scripts which were passed through
+     * proc arguments. Actually we track all arguments as we do not and cannot
+     * know which arguments will be used as scripts and which will not.
+     */
+
+    if (iPtr->lineLAPtr->numEntries && !TclInExit()) {
+	/*
+	 * When the interp goes away we have nothing on the stack, so there
+	 * are no arguments, so this table has to be empty.
+	 */
+
+	Tcl_Panic("Argument location tracking table not empty");
+    }
+
+    Tcl_DeleteHashTable(iPtr->lineLAPtr);
+    ckfree((char *) iPtr->lineLAPtr);
+    iPtr->lineLAPtr = NULL;
+
+    if (iPtr->lineLABCPtr->numEntries && !TclInExit()) {
+	/*
+	 * When the interp goes away we have nothing on the stack, so there
+	 * are no arguments, so this table has to be empty.
+	 */
+
+	Tcl_Panic("Argument location tracking table not empty");
+    }
+
+    Tcl_DeleteHashTable(iPtr->lineLABCPtr);
+    ckfree(iPtr->lineLABCPtr);
+    iPtr->lineLABCPtr = NULL;
+
+    /*
+     * Squelch the tables of traces on variables and searches over arrays in
+     * the in the interpreter.
+     */
+
+    Tcl_DeleteHashTable(&iPtr->varTraces);
+    Tcl_DeleteHashTable(&iPtr->varSearches);
+
+    ckfree(iPtr);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Tcl_HideCommand --
+ *
+ *	Makes a command hidden so that it cannot be invoked from within an
+ *	interpreter, only from within an ancestor.
+ *
+ * Results:
+ *	A standard Tcl result; also leaves a message in the interp's result if
+ *	an error occurs.
+ *
+ * Side effects:
+ *	Removes a command from the command table and create an entry into the
+ *	hidden command table under the specified token name.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+int
+Tcl_HideCommand(
+    Tcl_Interp *interp,		/* Interpreter in which to hide command. */
+    const char *cmdName,	/* Name of command to hide. */
+    const char *hiddenCmdToken)	/* Token name of the to-be-hidden command. */
+{
+    Interp *iPtr = (Interp *) interp;
+    Tcl_Command cmd;
+    Command *cmdPtr;
+    Tcl_HashTable *hiddenCmdTablePtr;
+    Tcl_HashEntry *hPtr;
+    int isNew;
+
+    if (iPtr->flags & DELETED) {
+	/*
+	 * The interpreter is being deleted. Do not create any new structures,
+	 * because it is not safe to modify the interpreter.
+	 */
+
+	return TCL_ERROR;
+    }
+
+    /*
+     * Disallow hiding of commands that are currently in a namespace or
+     * renaming (as part of hiding) into a namespace (because the current
+     * implementation with a single global table and the needed uniqueness of
+     * names cause problems with namespaces).
+     *
+     * We don't need to check for "::" in cmdName because the real check is on
+     * the nsPtr below.
+     *
+     * hiddenCmdToken is just a string which is not interpreted in any way. It
+     * may contain :: but the string is not interpreted as a namespace
+     * qualifier command name. Thus, hiding foo::bar to foo::bar and then
+     * trying to expose or invoke ::foo::bar will NOT work; but if the
+     * application always uses the same strings it will get consistent
+     * behaviour.
+     *
+     * But as we currently limit ourselves to the global namespace only for
+     * the source, in order to avoid potential confusion, lets prevent "::" in
+     * the token too. - dl
+     */
+
+    if (strstr(hiddenCmdToken, "::") != NULL) {
+	Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		"cannot use namespace qualifiers in hidden command"
+		" token (rename)", -1));
+        Tcl_SetErrorCode(interp, "TCL", "VALUE", "HIDDENTOKEN", NULL);
+	return TCL_ERROR;
+    }
+
+    /*
+     * Find the command to hide. An error is returned if cmdName can't be
+     * found. Look up the command only from the global namespace. Full path of
+     * the command must be given if using namespaces.
+     */
+
+    cmd = Tcl_FindCommand(interp, cmdName, NULL,
+	    /*flags*/ TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY);
+    if (cmd == (Tcl_Command) NULL) {
+	return TCL_ERROR;
+    }
+    cmdPtr = (Command *) cmd;
+
+    /*
+     * Check that the command is really in global namespace
+     */
+
+    if (cmdPtr->nsPtr != iPtr->globalNsPtr) {
+	Tcl_SetObjResult(interp, Tcl_NewStringObj(
+                "can only hide global namespace commands (use rename then hide)",
+                -1));
+        Tcl_SetErrorCode(interp, "TCL", "HIDE", "NON_GLOBAL", NULL);
+	return TCL_ERROR;
+    }
+
+    /*
+     * Initialize the hidden command table if necessary.
+     */
+
+    hiddenCmdTablePtr = iPtr->hiddenCmdTablePtr;
+    if (hiddenCmdTablePtr == NULL) {
+	hiddenCmdTablePtr = ckalloc(sizeof(Tcl_HashTable));
+	Tcl_InitHashTable(hiddenCmdTablePtr, TCL_STRING_KEYS);
+	iPtr->hiddenCmdTablePtr = hiddenCmdTablePtr;
+    }
+
+    /*
+     * It is an error to move an exposed command to a hidden command with
+     * hiddenCmdToken if a hidden command with the name hiddenCmdToken already
+     * exists.
+     */
+
+    hPtr = Tcl_CreateHashEntry(hiddenCmdTablePtr, hiddenCmdToken, &isNew);
+    if (!isNew) {
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+                "hidden command named \"%s\" already exists",
+                hiddenCmdToken));
+        Tcl_SetErrorCode(interp, "TCL", "HIDE", "ALREADY_HIDDEN", NULL);
+	return TCL_ERROR;
+    }
+
+    /*
+     * NB: This code is currently 'like' a rename to a specialy set apart name
+     * table. Changes here and in TclRenameCommand must be kept in synch until
+     * the common parts are actually factorized out.
+     */
+
+    /*
+     * Remove the hash entry for the command from the interpreter command
+     * table. This is like deleting the command, so bump its command epoch;
+     * this invalidates any cached references that point to the command.
+     */
+
+    if (cmdPtr->hPtr != NULL) {
+	Tcl_DeleteHashEntry(cmdPtr->hPtr);
+	cmdPtr->hPtr = NULL;
+	cmdPtr->cmdEpoch++;
+    }
+
+    /*
+     * The list of command exported from the namespace might have changed.
+     * However, we do not need to recompute this just yet; next time we need
+     * the info will be soon enough.
+     */
+
+    TclInvalidateNsCmdLookup(cmdPtr->nsPtr);
+
+    /*
+     * Now link the hash table entry with the command structure. We ensured
+     * above that the nsPtr was right.
+     */
+
+    cmdPtr->hPtr = hPtr;
+    Tcl_SetHashValue(hPtr, cmdPtr);
+
+    /*
+     * If the command being hidden has a compile function, increment the
+     * interpreter's compileEpoch to invalidate its compiled code. This makes
+     * sure that we don't later try to execute old code compiled with
+     * command-specific (i.e., inline) bytecodes for the now-hidden command.
+     * This field is checked in Tcl_EvalObj and ObjInterpProc, and code whose
+     * compilation epoch doesn't match is recompiled.
+     */
+
+    if (cmdPtr->compileProc != NULL) {
+	iPtr->compileEpoch++;
+    }
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_ExposeCommand --
+ *
+ *	Makes a previously hidden command callable from inside the interpreter
+ *	instead of only by its ancestors.
+ *
+ * Results:
+ *	A standard Tcl result. If an error occurs, a message is left in the
+ *	interp's result.
+ *
+ * Side effects:
+ *	Moves commands from one hash table to another.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_ExposeCommand(
+    Tcl_Interp *interp,		/* Interpreter in which to make command
+				 * callable. */
+    const char *hiddenCmdToken,	/* Name of hidden command. */
+    const char *cmdName)	/* Name of to-be-exposed command. */
+{
+    Interp *iPtr = (Interp *) interp;
+    Command *cmdPtr;
+    Namespace *nsPtr;
+    Tcl_HashEntry *hPtr;
+    Tcl_HashTable *hiddenCmdTablePtr;
+    int isNew;
+
+    if (iPtr->flags & DELETED) {
+	/*
+	 * The interpreter is being deleted. Do not create any new structures,
+	 * because it is not safe to modify the interpreter.
+	 */
+
+	return TCL_ERROR;
+    }
+
+    /*
+     * Check that we have a regular name for the command (that the user is not
+     * trying to do an expose and a rename (to another namespace) at the same
+     * time).
+     */
+
+    if (strstr(cmdName, "::") != NULL) {
+	Tcl_SetObjResult(interp, Tcl_NewStringObj(
+                "cannot expose to a namespace (use expose to toplevel, then rename)",
+                -1));
+        Tcl_SetErrorCode(interp, "TCL", "EXPOSE", "NON_GLOBAL", NULL);
+	return TCL_ERROR;
+    }
+
+    /*
+     * Get the command from the hidden command table:
+     */
+
+    hPtr = NULL;
+    hiddenCmdTablePtr = iPtr->hiddenCmdTablePtr;
+    if (hiddenCmdTablePtr != NULL) {
+	hPtr = Tcl_FindHashEntry(hiddenCmdTablePtr, hiddenCmdToken);
+    }
+    if (hPtr == NULL) {
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+                "unknown hidden command \"%s\"", hiddenCmdToken));
+        Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "HIDDENTOKEN",
+                hiddenCmdToken, NULL);
+	return TCL_ERROR;
+    }
+    cmdPtr = Tcl_GetHashValue(hPtr);
+
+    /*
+     * Check that we have a true global namespace command (enforced by
+     * Tcl_HideCommand but let's double check. (If it was not, we would not
+     * really know how to handle it).
+     */
+
+    if (cmdPtr->nsPtr != iPtr->globalNsPtr) {
+	/*
+	 * This case is theoritically impossible, we might rather Tcl_Panic
+	 * than 'nicely' erroring out ?
+	 */
+
+	Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		"trying to expose a non-global command namespace command",
+		-1));
+	return TCL_ERROR;
+    }
+
+    /*
+     * This is the global table.
+     */
+
+    nsPtr = cmdPtr->nsPtr;
+
+    /*
+     * It is an error to overwrite an existing exposed command as a result of
+     * exposing a previously hidden command.
+     */
+
+    hPtr = Tcl_CreateHashEntry(&nsPtr->cmdTable, cmdName, &isNew);
+    if (!isNew) {
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+                "exposed command \"%s\" already exists", cmdName));
+        Tcl_SetErrorCode(interp, "TCL", "EXPOSE", "COMMAND_EXISTS", NULL);
+	return TCL_ERROR;
+    }
+
+    /*
+     * Command resolvers (per-interp, per-namespace) might have resolved to a
+     * command for the given namespace scope with this command not being
+     * registered with the namespace's command table. During BC compilation,
+     * the so-resolved command turns into a CmdName literal. Without
+     * invalidating a possible CmdName literal here explicitly, such literals
+     * keep being reused while pointing to overhauled commands.
+     */
+
+    TclInvalidateCmdLiteral(interp, cmdName, nsPtr);
+
+    /*
+     * The list of command exported from the namespace might have changed.
+     * However, we do not need to recompute this just yet; next time we need
+     * the info will be soon enough.
+     */
+
+    TclInvalidateNsCmdLookup(nsPtr);
+
+    /*
+     * Remove the hash entry for the command from the interpreter hidden
+     * command table.
+     */
+
+    if (cmdPtr->hPtr != NULL) {
+	Tcl_DeleteHashEntry(cmdPtr->hPtr);
+	cmdPtr->hPtr = NULL;
+    }
+
+    /*
+     * Now link the hash table entry with the command structure. This is like
+     * creating a new command, so deal with any shadowing of commands in the
+     * global namespace.
+     */
+
+    cmdPtr->hPtr = hPtr;
+
+    Tcl_SetHashValue(hPtr, cmdPtr);
+
+    /*
+     * Not needed as we are only in the global namespace (but would be needed
+     * again if we supported namespace command hiding)
+     *
+     * TclResetShadowedCmdRefs(interp, cmdPtr);
+     */
+
+    /*
+     * If the command being exposed has a compile function, increment
+     * interpreter's compileEpoch to invalidate its compiled code. This makes
+     * sure that we don't later try to execute old code compiled assuming the
+     * command is hidden. This field is checked in Tcl_EvalObj and
+     * ObjInterpProc, and code whose compilation epoch doesn't match is
+     * recompiled.
+     */
+
+    if (cmdPtr->compileProc != NULL) {
+	iPtr->compileEpoch++;
+    }
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_CreateCommand --
+ *
+ *	Define a new command in a command table.
+ *
+ * Results:
+ *	The return value is a token for the command, which can be used in
+ *	future calls to Tcl_GetCommandName.
+ *
+ * Side effects:
+ *	If a command named cmdName already exists for interp, it is deleted.
+ *	In the future, when cmdName is seen as the name of a command by
+ *	Tcl_Eval, proc will be called. To support the bytecode interpreter,
+ *	the command is created with a wrapper Tcl_ObjCmdProc
+ *	(TclInvokeStringCommand) that eventially calls proc. When the command
+ *	is deleted from the table, deleteProc will be called. See the manual
+ *	entry for details on the calling sequence.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_Command
+Tcl_CreateCommand(
+    Tcl_Interp *interp,		/* Token for command interpreter returned by a
+				 * previous call to Tcl_CreateInterp. */
+    const char *cmdName,	/* Name of command. If it contains namespace
+				 * qualifiers, the new command is put in the
+				 * specified namespace; otherwise it is put in
+				 * the global namespace. */
+    Tcl_CmdProc *proc,		/* Function to associate with cmdName. */
+    ClientData clientData,	/* Arbitrary value passed to string proc. */
+    Tcl_CmdDeleteProc *deleteProc)
+				/* If not NULL, gives a function to call when
+				 * this command is deleted. */
+{
+    Interp *iPtr = (Interp *) interp;
+    ImportRef *oldRefPtr = NULL;
+    Namespace *nsPtr, *dummy1, *dummy2;
+    Command *cmdPtr, *refCmdPtr;
+    Tcl_HashEntry *hPtr;
+    const char *tail;
+    int isNew;
+    ImportedCmdData *dataPtr;
+
+    if (iPtr->flags & DELETED) {
+	/*
+	 * The interpreter is being deleted. Don't create any new commands;
+	 * it's not safe to muck with the interpreter anymore.
+	 */
+
+	return (Tcl_Command) NULL;
+    }
+
+    /*
+     * Determine where the command should reside. If its name contains
+     * namespace qualifiers, we put it in the specified namespace; otherwise,
+     * we always put it in the global namespace.
+     */
+
+    if (strstr(cmdName, "::") != NULL) {
+	TclGetNamespaceForQualName(interp, cmdName, NULL,
+		TCL_CREATE_NS_IF_UNKNOWN, &nsPtr, &dummy1, &dummy2, &tail);
+	if ((nsPtr == NULL) || (tail == NULL)) {
+	    return (Tcl_Command) NULL;
+	}
+    } else {
+	nsPtr = iPtr->globalNsPtr;
+	tail = cmdName;
+    }
+
+    hPtr = Tcl_CreateHashEntry(&nsPtr->cmdTable, tail, &isNew);
+    if (!isNew) {
+	/*
+	 * Command already exists. Delete the old one. Be careful to preserve
+	 * any existing import links so we can restore them down below. That
+	 * way, you can redefine a command and its import status will remain
+	 * intact.
+	 */
+
+	cmdPtr = Tcl_GetHashValue(hPtr);
+	cmdPtr->refCount++;
+	if (cmdPtr->importRefPtr) {
+	    cmdPtr->flags |= CMD_REDEF_IN_PROGRESS;
+	}
+
+	Tcl_DeleteCommandFromToken(interp, (Tcl_Command) cmdPtr);
+
+	if (cmdPtr->flags & CMD_REDEF_IN_PROGRESS) {
+	    oldRefPtr = cmdPtr->importRefPtr;
+	    cmdPtr->importRefPtr = NULL;
+	}
+	TclCleanupCommandMacro(cmdPtr);
+
+	hPtr = Tcl_CreateHashEntry(&nsPtr->cmdTable, tail, &isNew);
+	if (!isNew) {
+	    /*
+	     * If the deletion callback recreated the command, just throw away
+	     * the new command (if we try to delete it again, we could get
+	     * stuck in an infinite loop).
+	     */
+
+	    ckfree(Tcl_GetHashValue(hPtr));
+	}
+    } else {
+	/*
+	 * Command resolvers (per-interp, per-namespace) might have resolved
+	 * to a command for the given namespace scope with this command not
+	 * being registered with the namespace's command table. During BC
+	 * compilation, the so-resolved command turns into a CmdName literal.
+	 * Without invalidating a possible CmdName literal here explicitly,
+	 * such literals keep being reused while pointing to overhauled
+	 * commands.
+	 */
+
+	TclInvalidateCmdLiteral(interp, tail, nsPtr);
+
+	/*
+	 * The list of command exported from the namespace might have changed.
+	 * However, we do not need to recompute this just yet; next time we
+	 * need the info will be soon enough.
+	 */
+
+	TclInvalidateNsCmdLookup(nsPtr);
+	TclInvalidateNsPath(nsPtr);
+    }
+    cmdPtr = ckalloc(sizeof(Command));
+    Tcl_SetHashValue(hPtr, cmdPtr);
+    cmdPtr->hPtr = hPtr;
+    cmdPtr->nsPtr = nsPtr;
+    cmdPtr->refCount = 1;
+    cmdPtr->cmdEpoch = 0;
+    cmdPtr->compileProc = NULL;
+    cmdPtr->objProc = TclInvokeStringCommand;
+    cmdPtr->objClientData = cmdPtr;
+    cmdPtr->proc = proc;
+    cmdPtr->clientData = clientData;
+    cmdPtr->deleteProc = deleteProc;
+    cmdPtr->deleteData = clientData;
+    cmdPtr->flags = 0;
+    cmdPtr->importRefPtr = NULL;
+    cmdPtr->tracePtr = NULL;
+    cmdPtr->nreProc = NULL;
+
+    /*
+     * Plug in any existing import references found above. Be sure to update
+     * all of these references to point to the new command.
+     */
+
+    if (oldRefPtr != NULL) {
+	cmdPtr->importRefPtr = oldRefPtr;
+	while (oldRefPtr != NULL) {
+	    refCmdPtr = oldRefPtr->importedCmdPtr;
+	    dataPtr = refCmdPtr->objClientData;
+	    dataPtr->realCmdPtr = cmdPtr;
+	    oldRefPtr = oldRefPtr->nextPtr;
+	}
+    }
+
+    /*
+     * We just created a command, so in its namespace and all of its parent
+     * namespaces, it may shadow global commands with the same name. If any
+     * shadowed commands are found, invalidate all cached command references
+     * in the affected namespaces.
+     */
+
+    TclResetShadowedCmdRefs(interp, cmdPtr);
+    return (Tcl_Command) cmdPtr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_CreateObjCommand --
+ *
+ *	Define a new object-based command in a command table.
+ *
+ * Results:
+ *	The return value is a token for the command, which can be used in
+ *	future calls to Tcl_GetCommandName.
+ *
+ * Side effects:
+ *	If a command named "cmdName" already exists for interp, it is
+ *	first deleted.  Then the new command is created from the arguments.
+ *	[***] (See below for exception).
+ *
+ *	In the future, during bytecode evaluation when "cmdName" is seen as
+ *	the name of a command by Tcl_EvalObj or Tcl_Eval, the object-based
+ *	Tcl_ObjCmdProc proc will be called. When the command is deleted from
+ *	the table, deleteProc will be called. See the manual entry for details
+ *	on the calling sequence.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_Command
+Tcl_CreateObjCommand(
+    Tcl_Interp *interp,		/* Token for command interpreter (returned by
+				 * previous call to Tcl_CreateInterp). */
+    const char *cmdName,	/* Name of command. If it contains namespace
+				 * qualifiers, the new command is put in the
+				 * specified namespace; otherwise it is put in
+				 * the global namespace. */
+    Tcl_ObjCmdProc *proc,	/* Object-based function to associate with
+				 * name. */
+    ClientData clientData,	/* Arbitrary value to pass to object
+				 * function. */
+    Tcl_CmdDeleteProc *deleteProc)
+				/* If not NULL, gives a function to call when
+				 * this command is deleted. */
+{
+    Interp *iPtr = (Interp *) interp;
+    ImportRef *oldRefPtr = NULL;
+    Namespace *nsPtr, *dummy1, *dummy2;
+    Command *cmdPtr, *refCmdPtr;
+    Tcl_HashEntry *hPtr;
+    const char *tail;
+    int isNew;
+    ImportedCmdData *dataPtr;
+
+    if (iPtr->flags & DELETED) {
+	/*
+	 * The interpreter is being deleted. Don't create any new commands;
+	 * it's not safe to muck with the interpreter anymore.
+	 */
+
+	return (Tcl_Command) NULL;
+    }
+
+    /*
+     * Determine where the command should reside. If its name contains
+     * namespace qualifiers, we put it in the specified namespace; otherwise,
+     * we always put it in the global namespace.
+     */
+
+    if (strstr(cmdName, "::") != NULL) {
+	TclGetNamespaceForQualName(interp, cmdName, NULL,
+		TCL_CREATE_NS_IF_UNKNOWN, &nsPtr, &dummy1, &dummy2, &tail);
+	if ((nsPtr == NULL) || (tail == NULL)) {
+	    return (Tcl_Command) NULL;
+	}
+    } else {
+	nsPtr = iPtr->globalNsPtr;
+	tail = cmdName;
+    }
+
+    hPtr = Tcl_CreateHashEntry(&nsPtr->cmdTable, tail, &isNew);
+    TclInvalidateNsPath(nsPtr);
+    if (!isNew) {
+	cmdPtr = Tcl_GetHashValue(hPtr);
+
+	/* Command already exists. */
+
+	/*
+	 * [***] This is wrong.  See Tcl Bug a16752c252.
+	 * However, this buggy behavior is kept under particular
+	 * circumstances to accommodate deployed binaries of the
+	 * "tclcompiler" program. http://sourceforge.net/projects/tclpro/
+	 * that crash if the bug is fixed.
+	 */
+
+	if (cmdPtr->objProc == TclInvokeStringCommand
+		&& cmdPtr->clientData == clientData
+		&& cmdPtr->deleteData == clientData
+		&& cmdPtr->deleteProc == deleteProc) {
+	    cmdPtr->objProc = proc;
+	    cmdPtr->objClientData = clientData;
+	    return (Tcl_Command) cmdPtr;
+	}
+
+	/*
+	 * Otherwise, we delete the old command. Be careful to preserve any
+	 * existing import links so we can restore them down below. That way,
+	 * you can redefine a command and its import status will remain
+	 * intact.
+	 */
+
+	cmdPtr->refCount++;
+	if (cmdPtr->importRefPtr) {
+	    cmdPtr->flags |= CMD_REDEF_IN_PROGRESS;
+	}
+
+	Tcl_DeleteCommandFromToken(interp, (Tcl_Command) cmdPtr);
+
+	if (cmdPtr->flags & CMD_REDEF_IN_PROGRESS) {
+	    oldRefPtr = cmdPtr->importRefPtr;
+	    cmdPtr->importRefPtr = NULL;
+	}
+	TclCleanupCommandMacro(cmdPtr);
+
+	hPtr = Tcl_CreateHashEntry(&nsPtr->cmdTable, tail, &isNew);
+	if (!isNew) {
+	    /*
+	     * If the deletion callback recreated the command, just throw away
+	     * the new command (if we try to delete it again, we could get
+	     * stuck in an infinite loop).
+	     */
+
+	    ckfree(Tcl_GetHashValue(hPtr));
+	}
+    } else {
+	/*
+	 * Command resolvers (per-interp, per-namespace) might have resolved
+	 * to a command for the given namespace scope with this command not
+	 * being registered with the namespace's command table. During BC
+	 * compilation, the so-resolved command turns into a CmdName literal.
+	 * Without invalidating a possible CmdName literal here explicitly,
+	 * such literals keep being reused while pointing to overhauled
+	 * commands.
+	 */
+
+	TclInvalidateCmdLiteral(interp, tail, nsPtr);
+
+	/*
+	 * The list of command exported from the namespace might have changed.
+	 * However, we do not need to recompute this just yet; next time we
+	 * need the info will be soon enough.
+	 */
+
+	TclInvalidateNsCmdLookup(nsPtr);
+    }
+    cmdPtr = ckalloc(sizeof(Command));
+    Tcl_SetHashValue(hPtr, cmdPtr);
+    cmdPtr->hPtr = hPtr;
+    cmdPtr->nsPtr = nsPtr;
+    cmdPtr->refCount = 1;
+    cmdPtr->cmdEpoch = 0;
+    cmdPtr->compileProc = NULL;
+    cmdPtr->objProc = proc;
+    cmdPtr->objClientData = clientData;
+    cmdPtr->proc = TclInvokeObjectCommand;
+    cmdPtr->clientData = cmdPtr;
+    cmdPtr->deleteProc = deleteProc;
+    cmdPtr->deleteData = clientData;
+    cmdPtr->flags = 0;
+    cmdPtr->importRefPtr = NULL;
+    cmdPtr->tracePtr = NULL;
+    cmdPtr->nreProc = NULL;
+
+    /*
+     * Plug in any existing import references found above. Be sure to update
+     * all of these references to point to the new command.
+     */
+
+    if (oldRefPtr != NULL) {
+	cmdPtr->importRefPtr = oldRefPtr;
+	while (oldRefPtr != NULL) {
+	    refCmdPtr = oldRefPtr->importedCmdPtr;
+	    dataPtr = refCmdPtr->objClientData;
+	    dataPtr->realCmdPtr = cmdPtr;
+	    oldRefPtr = oldRefPtr->nextPtr;
+	}
+    }
+
+    /*
+     * We just created a command, so in its namespace and all of its parent
+     * namespaces, it may shadow global commands with the same name. If any
+     * shadowed commands are found, invalidate all cached command references
+     * in the affected namespaces.
+     */
+
+    TclResetShadowedCmdRefs(interp, cmdPtr);
+    return (Tcl_Command) cmdPtr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclInvokeStringCommand --
+ *
+ *	"Wrapper" Tcl_ObjCmdProc used to call an existing string-based
+ *	Tcl_CmdProc if no object-based function exists for a command. A
+ *	pointer to this function is stored as the Tcl_ObjCmdProc in a Command
+ *	structure. It simply turns around and calls the string Tcl_CmdProc in
+ *	the Command structure.
+ *
+ * Results:
+ *	A standard Tcl object result value.
+ *
+ * Side effects:
+ *	Besides those side effects of the called Tcl_CmdProc,
+ *	TclInvokeStringCommand allocates and frees storage.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclInvokeStringCommand(
+    ClientData clientData,	/* Points to command's Command structure. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    register int objc,		/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    Command *cmdPtr = clientData;
+    int i, result;
+    const char **argv =
+	    TclStackAlloc(interp, (unsigned)(objc + 1) * sizeof(char *));
+
+    for (i = 0; i < objc; i++) {
+	argv[i] = Tcl_GetString(objv[i]);
+    }
+    argv[objc] = 0;
+
+    /*
+     * Invoke the command's string-based Tcl_CmdProc.
+     */
+
+    result = cmdPtr->proc(cmdPtr->clientData, interp, objc, argv);
+
+    TclStackFree(interp, (void *) argv);
+    return result;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclInvokeObjectCommand --
+ *
+ *	"Wrapper" Tcl_CmdProc used to call an existing object-based
+ *	Tcl_ObjCmdProc if no string-based function exists for a command. A
+ *	pointer to this function is stored as the Tcl_CmdProc in a Command
+ *	structure. It simply turns around and calls the object Tcl_ObjCmdProc
+ *	in the Command structure.
+ *
+ * Results:
+ *	A standard Tcl string result value.
+ *
+ * Side effects:
+ *	Besides those side effects of the called Tcl_ObjCmdProc,
+ *	TclInvokeObjectCommand allocates and frees storage.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclInvokeObjectCommand(
+    ClientData clientData,	/* Points to command's Command structure. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int argc,			/* Number of arguments. */
+    register const char **argv)	/* Argument strings. */
+{
+    Command *cmdPtr = clientData;
+    Tcl_Obj *objPtr;
+    int i, length, result;
+    Tcl_Obj **objv =
+	    TclStackAlloc(interp, (unsigned)(argc * sizeof(Tcl_Obj *)));
+
+    for (i = 0; i < argc; i++) {
+	length = strlen(argv[i]);
+	TclNewStringObj(objPtr, argv[i], length);
+	Tcl_IncrRefCount(objPtr);
+	objv[i] = objPtr;
+    }
+
+    /*
+     * Invoke the command's object-based Tcl_ObjCmdProc.
+     */
+
+    if (cmdPtr->objProc != NULL) {
+	result = cmdPtr->objProc(cmdPtr->objClientData, interp, argc, objv);
+    } else {
+	result = Tcl_NRCallObjProc(interp, cmdPtr->nreProc,
+		cmdPtr->objClientData, argc, objv);
+    }
+
+    /*
+     * Move the interpreter's object result to the string result, then reset
+     * the object result.
+     */
+
+    (void) Tcl_GetStringResult(interp);
+
+    /*
+     * Decrement the ref counts for the argument objects created above, then
+     * free the objv array if malloc'ed storage was used.
+     */
+
+    for (i = 0; i < argc; i++) {
+	objPtr = objv[i];
+	Tcl_DecrRefCount(objPtr);
+    }
+    TclStackFree(interp, objv);
+    return result;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclRenameCommand --
+ *
+ *	Called to give an existing Tcl command a different name. Both the old
+ *	command name and the new command name can have "::" namespace
+ *	qualifiers. If the new command has a different namespace context, the
+ *	command will be moved to that namespace and will execute in the
+ *	context of that new namespace.
+ *
+ *	If the new command name is NULL or the null string, the command is
+ *	deleted.
+ *
+ * Results:
+ *	Returns TCL_OK if successful, and TCL_ERROR if anything goes wrong.
+ *
+ * Side effects:
+ *	If anything goes wrong, an error message is returned in the
+ *	interpreter's result object.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclRenameCommand(
+    Tcl_Interp *interp,		/* Current interpreter. */
+    const char *oldName,	/* Existing command name. */
+    const char *newName)	/* New command name. */
+{
+    Interp *iPtr = (Interp *) interp;
+    const char *newTail;
+    Namespace *cmdNsPtr, *newNsPtr, *dummy1, *dummy2;
+    Tcl_Command cmd;
+    Command *cmdPtr;
+    Tcl_HashEntry *hPtr, *oldHPtr;
+    int isNew, result;
+    Tcl_Obj *oldFullName;
+    Tcl_DString newFullName;
+
+    /*
+     * Find the existing command. An error is returned if cmdName can't be
+     * found.
+     */
+
+    cmd = Tcl_FindCommand(interp, oldName, NULL, /*flags*/ 0);
+    cmdPtr = (Command *) cmd;
+    if (cmdPtr == NULL) {
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+                "can't %s \"%s\": command doesn't exist",
+		((newName == NULL)||(*newName == '\0'))? "delete":"rename",
+		oldName));
+        Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "COMMAND", oldName, NULL);
+	return TCL_ERROR;
+    }
+    cmdNsPtr = cmdPtr->nsPtr;
+    oldFullName = Tcl_NewObj();
+    Tcl_IncrRefCount(oldFullName);
+    Tcl_GetCommandFullName(interp, cmd, oldFullName);
+
+    /*
+     * If the new command name is NULL or empty, delete the command. Do this
+     * with Tcl_DeleteCommandFromToken, since we already have the command.
+     */
+
+    if ((newName == NULL) || (*newName == '\0')) {
+	Tcl_DeleteCommandFromToken(interp, cmd);
+	result = TCL_OK;
+	goto done;
+    }
+
+    /*
+     * Make sure that the destination command does not already exist. The
+     * rename operation is like creating a command, so we should automatically
+     * create the containing namespaces just like Tcl_CreateCommand would.
+     */
+
+    TclGetNamespaceForQualName(interp, newName, NULL,
+	    TCL_CREATE_NS_IF_UNKNOWN, &newNsPtr, &dummy1, &dummy2, &newTail);
+
+    if ((newNsPtr == NULL) || (newTail == NULL)) {
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+                "can't rename to \"%s\": bad command name", newName));
+        Tcl_SetErrorCode(interp, "TCL", "VALUE", "COMMAND", NULL);
+	result = TCL_ERROR;
+	goto done;
+    }
+    if (Tcl_FindHashEntry(&newNsPtr->cmdTable, newTail) != NULL) {
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+                "can't rename to \"%s\": command already exists", newName));
+        Tcl_SetErrorCode(interp, "TCL", "OPERATION", "RENAME",
+                "TARGET_EXISTS", NULL);
+	result = TCL_ERROR;
+	goto done;
+    }
+
+    /*
+     * Warning: any changes done in the code here are likely to be needed in
+     * Tcl_HideCommand code too (until the common parts are extracted out).
+     * - dl
+     */
+
+    /*
+     * Put the command in the new namespace so we can check for an alias loop.
+     * Since we are adding a new command to a namespace, we must handle any
+     * shadowing of the global commands that this might create.
+     */
+
+    oldHPtr = cmdPtr->hPtr;
+    hPtr = Tcl_CreateHashEntry(&newNsPtr->cmdTable, newTail, &isNew);
+    Tcl_SetHashValue(hPtr, cmdPtr);
+    cmdPtr->hPtr = hPtr;
+    cmdPtr->nsPtr = newNsPtr;
+    TclResetShadowedCmdRefs(interp, cmdPtr);
+
+    /*
+     * Now check for an alias loop. If we detect one, put everything back the
+     * way it was and report the error.
+     */
+
+    result = TclPreventAliasLoop(interp, interp, (Tcl_Command) cmdPtr);
+    if (result != TCL_OK) {
+	Tcl_DeleteHashEntry(cmdPtr->hPtr);
+	cmdPtr->hPtr = oldHPtr;
+	cmdPtr->nsPtr = cmdNsPtr;
+	goto done;
+    }
+
+    /*
+     * The list of command exported from the namespace might have changed.
+     * However, we do not need to recompute this just yet; next time we need
+     * the info will be soon enough. These might refer to the same variable,
+     * but that's no big deal.
+     */
+
+    TclInvalidateNsCmdLookup(cmdNsPtr);
+    TclInvalidateNsCmdLookup(cmdPtr->nsPtr);
+
+    /*
+     * Command resolvers (per-interp, per-namespace) might have resolved to a
+     * command for the given namespace scope with this command not being
+     * registered with the namespace's command table. During BC compilation,
+     * the so-resolved command turns into a CmdName literal. Without
+     * invalidating a possible CmdName literal here explicitly, such literals
+     * keep being reused while pointing to overhauled commands.
+     */
+
+    TclInvalidateCmdLiteral(interp, newTail, cmdPtr->nsPtr);
+
+    /*
+     * Script for rename traces can delete the command "oldName". Therefore
+     * increment the reference count for cmdPtr so that it's Command structure
+     * is freed only towards the end of this function by calling
+     * TclCleanupCommand.
+     *
+     * The trace function needs to get a fully qualified name for old and new
+     * commands [Tcl bug #651271], or else there's no way for the trace
+     * function to get the namespace from which the old command is being
+     * renamed!
+     */
+
+    Tcl_DStringInit(&newFullName);
+    Tcl_DStringAppend(&newFullName, newNsPtr->fullName, -1);
+    if (newNsPtr != iPtr->globalNsPtr) {
+	TclDStringAppendLiteral(&newFullName, "::");
+    }
+    Tcl_DStringAppend(&newFullName, newTail, -1);
+    cmdPtr->refCount++;
+    CallCommandTraces(iPtr, cmdPtr, Tcl_GetString(oldFullName),
+	    Tcl_DStringValue(&newFullName), TCL_TRACE_RENAME);
+    Tcl_DStringFree(&newFullName);
+
+    /*
+     * The new command name is okay, so remove the command from its current
+     * namespace. This is like deleting the command, so bump the cmdEpoch to
+     * invalidate any cached references to the command.
+     */
+
+    Tcl_DeleteHashEntry(oldHPtr);
+    cmdPtr->cmdEpoch++;
+
+    /*
+     * If the command being renamed has a compile function, increment the
+     * interpreter's compileEpoch to invalidate its compiled code. This makes
+     * sure that we don't later try to execute old code compiled for the
+     * now-renamed command.
+     */
+
+    if (cmdPtr->compileProc != NULL) {
+	iPtr->compileEpoch++;
+    }
+
+    /*
+     * Now free the Command structure, if the "oldName" command has been
+     * deleted by invocation of rename traces.
+     */
+
+    TclCleanupCommandMacro(cmdPtr);
+    result = TCL_OK;
+
+  done:
+    TclDecrRefCount(oldFullName);
+    return result;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_SetCommandInfo --
+ *
+ *	Modifies various information about a Tcl command. Note that this
+ *	function will not change a command's namespace; use TclRenameCommand
+ *	to do that. Also, the isNativeObjectProc member of *infoPtr is
+ *	ignored.
+ *
+ * Results:
+ *	If cmdName exists in interp, then the information at *infoPtr is
+ *	stored with the command in place of the current information and 1 is
+ *	returned. If the command doesn't exist then 0 is returned.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_SetCommandInfo(
+    Tcl_Interp *interp,		/* Interpreter in which to look for
+				 * command. */
+    const char *cmdName,	/* Name of desired command. */
+    const Tcl_CmdInfo *infoPtr)	/* Where to find information to store in the
+				 * command. */
+{
+    Tcl_Command cmd;
+
+    cmd = Tcl_FindCommand(interp, cmdName, NULL, /*flags*/ 0);
+    return Tcl_SetCommandInfoFromToken(cmd, infoPtr);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_SetCommandInfoFromToken --
+ *
+ *	Modifies various information about a Tcl command. Note that this
+ *	function will not change a command's namespace; use TclRenameCommand
+ *	to do that. Also, the isNativeObjectProc member of *infoPtr is
+ *	ignored.
+ *
+ * Results:
+ *	If cmdName exists in interp, then the information at *infoPtr is
+ *	stored with the command in place of the current information and 1 is
+ *	returned. If the command doesn't exist then 0 is returned.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_SetCommandInfoFromToken(
+    Tcl_Command cmd,
+    const Tcl_CmdInfo *infoPtr)
+{
+    Command *cmdPtr;		/* Internal representation of the command */
+
+    if (cmd == NULL) {
+	return 0;
+    }
+
+    /*
+     * The isNativeObjectProc and nsPtr members of *infoPtr are ignored.
+     */
+
+    cmdPtr = (Command *) cmd;
+    cmdPtr->proc = infoPtr->proc;
+    cmdPtr->clientData = infoPtr->clientData;
+    if (infoPtr->objProc == NULL) {
+	cmdPtr->objProc = TclInvokeStringCommand;
+	cmdPtr->objClientData = cmdPtr;
+	cmdPtr->nreProc = NULL;
+    } else {
+	if (infoPtr->objProc != cmdPtr->objProc) {
+	    cmdPtr->nreProc = NULL;
+	    cmdPtr->objProc = infoPtr->objProc;
+	}
+	cmdPtr->objClientData = infoPtr->objClientData;
+    }
+    cmdPtr->deleteProc = infoPtr->deleteProc;
+    cmdPtr->deleteData = infoPtr->deleteData;
+    return 1;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_GetCommandInfo --
+ *
+ *	Returns various information about a Tcl command.
+ *
+ * Results:
+ *	If cmdName exists in interp, then *infoPtr is modified to hold
+ *	information about cmdName and 1 is returned. If the command doesn't
+ *	exist then 0 is returned and *infoPtr isn't modified.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_GetCommandInfo(
+    Tcl_Interp *interp,		/* Interpreter in which to look for
+				 * command. */
+    const char *cmdName,	/* Name of desired command. */
+    Tcl_CmdInfo *infoPtr)	/* Where to store information about
+				 * command. */
+{
+    Tcl_Command cmd;
+
+    cmd = Tcl_FindCommand(interp, cmdName, NULL, /*flags*/ 0);
+    return Tcl_GetCommandInfoFromToken(cmd, infoPtr);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_GetCommandInfoFromToken --
+ *
+ *	Returns various information about a Tcl command.
+ *
+ * Results:
+ *	Copies information from the command identified by 'cmd' into a
+ *	caller-supplied structure and returns 1. If the 'cmd' is NULL, leaves
+ *	the structure untouched and returns 0.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_GetCommandInfoFromToken(
+    Tcl_Command cmd,
+    Tcl_CmdInfo *infoPtr)
+{
+    Command *cmdPtr;		/* Internal representation of the command */
+
+    if (cmd == NULL) {
+	return 0;
+    }
+
+    /*
+     * Set isNativeObjectProc 1 if objProc was registered by a call to
+     * Tcl_CreateObjCommand. Otherwise set it to 0.
+     */
+
+    cmdPtr = (Command *) cmd;
+    infoPtr->isNativeObjectProc =
+	    (cmdPtr->objProc != TclInvokeStringCommand);
+    infoPtr->objProc = cmdPtr->objProc;
+    infoPtr->objClientData = cmdPtr->objClientData;
+    infoPtr->proc = cmdPtr->proc;
+    infoPtr->clientData = cmdPtr->clientData;
+    infoPtr->deleteProc = cmdPtr->deleteProc;
+    infoPtr->deleteData = cmdPtr->deleteData;
+    infoPtr->namespacePtr = (Tcl_Namespace *) cmdPtr->nsPtr;
+
+    return 1;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_GetCommandName --
+ *
+ *	Given a token returned by Tcl_CreateCommand, this function returns the
+ *	current name of the command (which may have changed due to renaming).
+ *
+ * Results:
+ *	The return value is the name of the given command.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+const char *
+Tcl_GetCommandName(
+    Tcl_Interp *interp,		/* Interpreter containing the command. */
+    Tcl_Command command)	/* Token for command returned by a previous
+				 * call to Tcl_CreateCommand. The command must
+				 * not have been deleted. */
+{
+    Command *cmdPtr = (Command *) command;
+
+    if ((cmdPtr == NULL) || (cmdPtr->hPtr == NULL)) {
+	/*
+	 * This should only happen if command was "created" after the
+	 * interpreter began to be deleted, so there isn't really any command.
+	 * Just return an empty string.
+	 */
+
+	return "";
+    }
+
+    return Tcl_GetHashKey(cmdPtr->hPtr->tablePtr, cmdPtr->hPtr);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_GetCommandFullName --
+ *
+ *	Given a token returned by, e.g., Tcl_CreateCommand or Tcl_FindCommand,
+ *	this function appends to an object the command's full name, qualified
+ *	by a sequence of parent namespace names. The command's fully-qualified
+ *	name may have changed due to renaming.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The command's fully-qualified name is appended to the string
+ *	representation of objPtr.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_GetCommandFullName(
+    Tcl_Interp *interp,		/* Interpreter containing the command. */
+    Tcl_Command command,	/* Token for command returned by a previous
+				 * call to Tcl_CreateCommand. The command must
+				 * not have been deleted. */
+    Tcl_Obj *objPtr)		/* Points to the object onto which the
+				 * command's full name is appended. */
+
+{
+    Interp *iPtr = (Interp *) interp;
+    register Command *cmdPtr = (Command *) command;
+    char *name;
+
+    /*
+     * Add the full name of the containing namespace, followed by the "::"
+     * separator, and the command name.
+     */
+
+    if (cmdPtr != NULL) {
+	if (cmdPtr->nsPtr != NULL) {
+	    Tcl_AppendToObj(objPtr, cmdPtr->nsPtr->fullName, -1);
+	    if (cmdPtr->nsPtr != iPtr->globalNsPtr) {
+		Tcl_AppendToObj(objPtr, "::", 2);
+	    }
+	}
+	if (cmdPtr->hPtr != NULL) {
+	    name = Tcl_GetHashKey(cmdPtr->hPtr->tablePtr, cmdPtr->hPtr);
+	    Tcl_AppendToObj(objPtr, name, -1);
+	}
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_DeleteCommand --
+ *
+ *	Remove the given command from the given interpreter.
+ *
+ * Results:
+ *	0 is returned if the command was deleted successfully. -1 is returned
+ *	if there didn't exist a command by that name.
+ *
+ * Side effects:
+ *	cmdName will no longer be recognized as a valid command for interp.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_DeleteCommand(
+    Tcl_Interp *interp,		/* Token for command interpreter (returned by
+				 * a previous Tcl_CreateInterp call). */
+    const char *cmdName)	/* Name of command to remove. */
+{
+    Tcl_Command cmd;
+
+    /*
+     * Find the desired command and delete it.
+     */
+
+    cmd = Tcl_FindCommand(interp, cmdName, NULL, /*flags*/ 0);
+    if (cmd == NULL) {
+	return -1;
+    }
+    return Tcl_DeleteCommandFromToken(interp, cmd);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_DeleteCommandFromToken --
+ *
+ *	Removes the given command from the given interpreter. This function
+ *	resembles Tcl_DeleteCommand, but takes a Tcl_Command token instead of
+ *	a command name for efficiency.
+ *
+ * Results:
+ *	0 is returned if the command was deleted successfully. -1 is returned
+ *	if there didn't exist a command by that name.
+ *
+ * Side effects:
+ *	The command specified by "cmd" will no longer be recognized as a valid
+ *	command for "interp".
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_DeleteCommandFromToken(
+    Tcl_Interp *interp,		/* Token for command interpreter returned by a
+				 * previous call to Tcl_CreateInterp. */
+    Tcl_Command cmd)		/* Token for command to delete. */
+{
+    Interp *iPtr = (Interp *) interp;
+    Command *cmdPtr = (Command *) cmd;
+    ImportRef *refPtr, *nextRefPtr;
+    Tcl_Command importCmd;
+
+    /*
+     * Bump the command epoch counter. This will invalidate all cached
+     * references that point to this command.
+     */
+
+    cmdPtr->cmdEpoch++;
+
+    /*
+     * The code here is tricky. We can't delete the hash table entry before
+     * invoking the deletion callback because there are cases where the
+     * deletion callback needs to invoke the command (e.g. object systems such
+     * as OTcl). However, this means that the callback could try to delete or
+     * rename the command. The deleted flag allows us to detect these cases
+     * and skip nested deletes.
+     */
+
+    if (cmdPtr->flags & CMD_IS_DELETED) {
+	/*
+	 * Another deletion is already in progress. Remove the hash table
+	 * entry now, but don't invoke a callback or free the command
+	 * structure. Take care to only remove the hash entry if it has not
+	 * already been removed; otherwise if we manage to hit this function
+	 * three times, everything goes up in smoke. [Bug 1220058]
+	 */
+
+	if (cmdPtr->hPtr != NULL) {
+	    Tcl_DeleteHashEntry(cmdPtr->hPtr);
+	    cmdPtr->hPtr = NULL;
+	}
+	return 0;
+    }
+
+    /*
+     * We must delete this command, even though both traces and delete procs
+     * may try to avoid this (renaming the command etc). Also traces and
+     * delete procs may try to delete the command themsevles. This flag
+     * declares that a delete is in progress and that recursive deletes should
+     * be ignored.
+     */
+
+    cmdPtr->flags |= CMD_IS_DELETED;
+
+    /*
+     * Call trace functions for the command being deleted. Then delete its
+     * traces.
+     */
+
+    if (cmdPtr->tracePtr != NULL) {
+	CommandTrace *tracePtr;
+	CallCommandTraces(iPtr,cmdPtr,NULL,NULL,TCL_TRACE_DELETE);
+
+	/*
+	 * Now delete these traces.
+	 */
+
+	tracePtr = cmdPtr->tracePtr;
+	while (tracePtr != NULL) {
+	    CommandTrace *nextPtr = tracePtr->nextPtr;
+
+	    if (tracePtr->refCount-- <= 1) {
+		ckfree(tracePtr);
+	    }
+	    tracePtr = nextPtr;
+	}
+	cmdPtr->tracePtr = NULL;
+    }
+
+    /*
+     * The list of command exported from the namespace might have changed.
+     * However, we do not need to recompute this just yet; next time we need
+     * the info will be soon enough.
+     */
+
+    TclInvalidateNsCmdLookup(cmdPtr->nsPtr);
+
+    /*
+     * If the command being deleted has a compile function, increment the
+     * interpreter's compileEpoch to invalidate its compiled code. This makes
+     * sure that we don't later try to execute old code compiled with
+     * command-specific (i.e., inline) bytecodes for the now-deleted command.
+     * This field is checked in Tcl_EvalObj and ObjInterpProc, and code whose
+     * compilation epoch doesn't match is recompiled.
+     */
+
+    if (cmdPtr->compileProc != NULL) {
+	iPtr->compileEpoch++;
+    }
+
+    if (cmdPtr->deleteProc != NULL) {
+	/*
+	 * Delete the command's client data. If this was an imported command
+	 * created when a command was imported into a namespace, this client
+	 * data will be a pointer to a ImportedCmdData structure describing
+	 * the "real" command that this imported command refers to.
+	 *
+	 * If you are getting a crash during the call to deleteProc and
+	 * cmdPtr->deleteProc is a pointer to the function free(), the most
+	 * likely cause is that your extension allocated memory for the
+	 * clientData argument to Tcl_CreateObjCommand with the ckalloc()
+	 * macro and you are now trying to deallocate this memory with free()
+	 * instead of ckfree(). You should pass a pointer to your own method
+	 * that calls ckfree().
+	 */
+
+	cmdPtr->deleteProc(cmdPtr->deleteData);
+    }
+
+    /*
+     * If this command was imported into other namespaces, then imported
+     * commands were created that refer back to this command. Delete these
+     * imported commands now.
+     */
+    if (!(cmdPtr->flags & CMD_REDEF_IN_PROGRESS)) {
+	for (refPtr = cmdPtr->importRefPtr; refPtr != NULL;
+		refPtr = nextRefPtr) {
+	    nextRefPtr = refPtr->nextPtr;
+	    importCmd = (Tcl_Command) refPtr->importedCmdPtr;
+	    Tcl_DeleteCommandFromToken(interp, importCmd);
+	}
+    }
+
+    /*
+     * Don't use hPtr to delete the hash entry here, because it's possible
+     * that the deletion callback renamed the command. Instead, use
+     * cmdPtr->hptr, and make sure that no-one else has already deleted the
+     * hash entry.
+     */
+
+    if (cmdPtr->hPtr != NULL) {
+	Tcl_DeleteHashEntry(cmdPtr->hPtr);
+	cmdPtr->hPtr = NULL;
+    }
+
+    /*
+     * A number of tests for particular kinds of commands are done by checking
+     * whether the objProc field holds a known value. Set the field to NULL so
+     * that such tests won't have false positives when applied to deleted
+     * commands.
+     */
+
+    cmdPtr->objProc = NULL;
+
+    /*
+     * Now free the Command structure, unless there is another reference to it
+     * from a CmdName Tcl object in some ByteCode code sequence. In that case,
+     * delay the cleanup until all references are either discarded (when a
+     * ByteCode is freed) or replaced by a new reference (when a cached
+     * CmdName Command reference is found to be invalid and
+     * TclNRExecuteByteCode looks up the command in the command hashtable).
+     */
+
+    TclCleanupCommandMacro(cmdPtr);
+    return 0;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * CallCommandTraces --
+ *
+ *	Abstraction of the code to call traces on a command.
+ *
+ * Results:
+ *	Currently always NULL.
+ *
+ * Side effects:
+ *	Anything; this may recursively evaluate scripts and code exists to do
+ *	just that.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static char *
+CallCommandTraces(
+    Interp *iPtr,		/* Interpreter containing command. */
+    Command *cmdPtr,		/* Command whose traces are to be invoked. */
+    const char *oldName,	/* Command's old name, or NULL if we must get
+				 * the name from cmdPtr */
+    const char *newName,	/* Command's new name, or NULL if the command
+				 * is not being renamed */
+    int flags)			/* Flags indicating the type of traces to
+				 * trigger, either TCL_TRACE_DELETE or
+				 * TCL_TRACE_RENAME. */
+{
+    register CommandTrace *tracePtr;
+    ActiveCommandTrace active;
+    char *result;
+    Tcl_Obj *oldNamePtr = NULL;
+    Tcl_InterpState state = NULL;
+
+    if (cmdPtr->flags & CMD_TRACE_ACTIVE) {
+	/*
+	 * While a rename trace is active, we will not process any more rename
+	 * traces; while a delete trace is active we will never reach here -
+	 * because Tcl_DeleteCommandFromToken checks for the condition
+	 * (cmdPtr->flags & CMD_IS_DELETED) and returns immediately when a
+	 * command deletion is in progress. For all other traces, delete
+	 * traces will not be invoked but a call to TraceCommandProc will
+	 * ensure that tracePtr->clientData is freed whenever the command
+	 * "oldName" is deleted.
+	 */
+
+	if (cmdPtr->flags & TCL_TRACE_RENAME) {
+	    flags &= ~TCL_TRACE_RENAME;
+	}
+	if (flags == 0) {
+	    return NULL;
+	}
+    }
+    cmdPtr->flags |= CMD_TRACE_ACTIVE;
+    cmdPtr->refCount++;
+
+    result = NULL;
+    active.nextPtr = iPtr->activeCmdTracePtr;
+    active.reverseScan = 0;
+    iPtr->activeCmdTracePtr = &active;
+
+    if (flags & TCL_TRACE_DELETE) {
+	flags |= TCL_TRACE_DESTROYED;
+    }
+    active.cmdPtr = cmdPtr;
+
+    Tcl_Preserve(iPtr);
+
+    for (tracePtr = cmdPtr->tracePtr; tracePtr != NULL;
+	    tracePtr = active.nextTracePtr) {
+	active.nextTracePtr = tracePtr->nextPtr;
+	if (!(tracePtr->flags & flags)) {
+	    continue;
+	}
+	cmdPtr->flags |= tracePtr->flags;
+	if (oldName == NULL) {
+	    TclNewObj(oldNamePtr);
+	    Tcl_IncrRefCount(oldNamePtr);
+	    Tcl_GetCommandFullName((Tcl_Interp *) iPtr,
+		    (Tcl_Command) cmdPtr, oldNamePtr);
+	    oldName = TclGetString(oldNamePtr);
+	}
+	tracePtr->refCount++;
+	if (state == NULL) {
+	    state = Tcl_SaveInterpState((Tcl_Interp *) iPtr, TCL_OK);
+	}
+	tracePtr->traceProc(tracePtr->clientData, (Tcl_Interp *) iPtr,
+		oldName, newName, flags);
+	cmdPtr->flags &= ~tracePtr->flags;
+	if (tracePtr->refCount-- <= 1) {
+	    ckfree(tracePtr);
+	}
+    }
+
+    if (state) {
+	Tcl_RestoreInterpState((Tcl_Interp *) iPtr, state);
+    }
+
+    /*
+     * If a new object was created to hold the full oldName, free it now.
+     */
+
+    if (oldNamePtr != NULL) {
+	TclDecrRefCount(oldNamePtr);
+    }
+
+    /*
+     * Restore the variable's flags, remove the record of our active traces,
+     * and then return.
+     */
+
+    cmdPtr->flags &= ~CMD_TRACE_ACTIVE;
+    cmdPtr->refCount--;
+    iPtr->activeCmdTracePtr = active.nextPtr;
+    Tcl_Release(iPtr);
+    return result;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * CancelEvalProc --
+ *
+ *	Marks this interpreter as being canceled. This causes current
+ *	executions to be unwound as the interpreter enters a state where it
+ *	refuses to execute more commands or handle [catch] or [try], yet the
+ *	interpreter is still able to execute further commands after the
+ *	cancelation is cleared (unlike if it is deleted).
+ *
+ * Results:
+ *	The value given for the code argument.
+ *
+ * Side effects:
+ *	Transfers a message from the cancelation message to the interpreter.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+CancelEvalProc(
+    ClientData clientData,	/* Interp to cancel the script in progress. */
+    Tcl_Interp *interp,		/* Ignored */
+    int code)			/* Current return code from command. */
+{
+    CancelInfo *cancelInfo = clientData;
+    Interp *iPtr;
+
+    if (cancelInfo != NULL) {
+	Tcl_MutexLock(&cancelLock);
+	iPtr = (Interp *) cancelInfo->interp;
+
+	if (iPtr != NULL) {
+	    /*
+	     * Setting the CANCELED flag will cause the script in progress to
+	     * be canceled as soon as possible. The core honors this flag at
+	     * all the necessary places to ensure script cancellation is
+	     * responsive. Extensions can check for this flag by calling
+	     * Tcl_Canceled and checking if TCL_ERROR is returned or they can
+	     * choose to ignore the script cancellation flag and the
+	     * associated functionality altogether. Currently, the only other
+	     * flag we care about here is the TCL_CANCEL_UNWIND flag (from
+	     * Tcl_CancelEval). We do not want to simply combine all the flags
+	     * from original Tcl_CancelEval call with the interp flags here
+	     * just in case the caller passed flags that might cause behaviour
+	     * unrelated to script cancellation.
+	     */
+
+	    TclSetCancelFlags(iPtr, cancelInfo->flags | CANCELED);
+
+	    /*
+	     * Now, we must set the script cancellation flags on all the slave
+	     * interpreters belonging to this one.
+	     */
+
+	    TclSetSlaveCancelFlags((Tcl_Interp *) iPtr,
+		    cancelInfo->flags | CANCELED, 0);
+
+	    /*
+	     * Create the result object now so that Tcl_Canceled can avoid
+	     * locking the cancelLock mutex.
+	     */
+
+	    if (cancelInfo->result != NULL) {
+		Tcl_SetStringObj(iPtr->asyncCancelMsg, cancelInfo->result,
+			cancelInfo->length);
+	    } else {
+		Tcl_SetObjLength(iPtr->asyncCancelMsg, 0);
+	    }
+	}
+	Tcl_MutexUnlock(&cancelLock);
+    }
+
+    return code;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclCleanupCommand --
+ *
+ *	This function frees up a Command structure unless it is still
+ *	referenced from an interpreter's command hashtable or from a CmdName
+ *	Tcl object representing the name of a command in a ByteCode
+ *	instruction sequence.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Memory gets freed unless a reference to the Command structure still
+ *	exists. In that case the cleanup is delayed until the command is
+ *	deleted or when the last ByteCode referring to it is freed.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclCleanupCommand(
+    register Command *cmdPtr)	/* Points to the Command structure to
+				 * be freed. */
+{
+    cmdPtr->refCount--;
+    if (cmdPtr->refCount <= 0) {
+	ckfree(cmdPtr);
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_CreateMathFunc --
+ *
+ *	Creates a new math function for expressions in a given interpreter.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The Tcl function defined by "name" is created or redefined. If the
+ *	function already exists then its definition is replaced; this includes
+ *	the builtin functions. Redefining a builtin function forces all
+ *	existing code to be invalidated since that code may be compiled using
+ *	an instruction specific to the replaced function. In addition,
+ *	redefioning a non-builtin function will force existing code to be
+ *	invalidated if the number of arguments has changed.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_CreateMathFunc(
+    Tcl_Interp *interp,		/* Interpreter in which function is to be
+				 * available. */
+    const char *name,		/* Name of function (e.g. "sin"). */
+    int numArgs,		/* Nnumber of arguments required by
+				 * function. */
+    Tcl_ValueType *argTypes,	/* Array of types acceptable for each
+				 * argument. */
+    Tcl_MathProc *proc,		/* C function that implements the math
+				 * function. */
+    ClientData clientData)	/* Additional value to pass to the
+				 * function. */
+{
+    Tcl_DString bigName;
+    OldMathFuncData *data = ckalloc(sizeof(OldMathFuncData));
+
+    data->proc = proc;
+    data->numArgs = numArgs;
+    data->argTypes = ckalloc(numArgs * sizeof(Tcl_ValueType));
+    memcpy(data->argTypes, argTypes, numArgs * sizeof(Tcl_ValueType));
+    data->clientData = clientData;
+
+    Tcl_DStringInit(&bigName);
+    TclDStringAppendLiteral(&bigName, "::tcl::mathfunc::");
+    Tcl_DStringAppend(&bigName, name, -1);
+
+    Tcl_CreateObjCommand(interp, Tcl_DStringValue(&bigName),
+	    OldMathFuncProc, data, OldMathFuncDeleteProc);
+    Tcl_DStringFree(&bigName);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * OldMathFuncProc --
+ *
+ *	Dispatch to a math function created with Tcl_CreateMathFunc
+ *
+ * Results:
+ *	Returns a standard Tcl result.
+ *
+ * Side effects:
+ *	Whatever the math function does.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+OldMathFuncProc(
+    ClientData clientData,	/* Ponter to OldMathFuncData describing the
+				 * function being called */
+    Tcl_Interp *interp,		/* Tcl interpreter */
+    int objc,			/* Actual parameter count */
+    Tcl_Obj *const *objv)	/* Parameter vector */
+{
+    Tcl_Obj *valuePtr;
+    OldMathFuncData *dataPtr = clientData;
+    Tcl_Value funcResult, *args;
+    int result;
+    int j, k;
+    double d;
+
+    /*
+     * Check argument count.
+     */
+
+    if (objc != dataPtr->numArgs + 1) {
+	MathFuncWrongNumArgs(interp, dataPtr->numArgs+1, objc, objv);
+	return TCL_ERROR;
+    }
+
+    /*
+     * Convert arguments from Tcl_Obj's to Tcl_Value's.
+     */
+
+    args = ckalloc(dataPtr->numArgs * sizeof(Tcl_Value));
+    for (j = 1, k = 0; j < objc; ++j, ++k) {
+	/* TODO: Convert to TclGetNumberFromObj? */
+	valuePtr = objv[j];
+	result = Tcl_GetDoubleFromObj(NULL, valuePtr, &d);
+#ifdef ACCEPT_NAN
+	if ((result != TCL_OK) && (valuePtr->typePtr == &tclDoubleType)) {
+	    d = valuePtr->internalRep.doubleValue;
+	    result = TCL_OK;
+	}
+#endif
+	if (result != TCL_OK) {
+	    /*
+	     * We have a non-numeric argument.
+	     */
+
+	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		    "argument to math function didn't have numeric value",
+		    -1));
+	    TclCheckBadOctal(interp, Tcl_GetString(valuePtr));
+	    ckfree(args);
+	    return TCL_ERROR;
+	}
+
+	/*
+	 * Copy the object's numeric value to the argument record, converting
+	 * it if necessary.
+	 *
+	 * NOTE: no bignum support; use the new mathfunc interface for that.
+	 */
+
+	args[k].type = dataPtr->argTypes[k];
+	switch (args[k].type) {
+	case TCL_EITHER:
+	    if (Tcl_GetLongFromObj(NULL, valuePtr, &args[k].intValue)
+		    == TCL_OK) {
+		args[k].type = TCL_INT;
+		break;
+	    }
+	    if (Tcl_GetWideIntFromObj(interp, valuePtr, &args[k].wideValue)
+		    == TCL_OK) {
+		args[k].type = TCL_WIDE_INT;
+		break;
+	    }
+	    args[k].type = TCL_DOUBLE;
+	    /* FALLTHROUGH */
+
+	case TCL_DOUBLE:
+	    args[k].doubleValue = d;
+	    break;
+	case TCL_INT:
+	    if (ExprIntFunc(NULL, interp, 2, &objv[j-1]) != TCL_OK) {
+		ckfree(args);
+		return TCL_ERROR;
+	    }
+	    valuePtr = Tcl_GetObjResult(interp);
+	    Tcl_GetLongFromObj(NULL, valuePtr, &args[k].intValue);
+	    Tcl_ResetResult(interp);
+	    break;
+	case TCL_WIDE_INT:
+	    if (ExprWideFunc(NULL, interp, 2, &objv[j-1]) != TCL_OK) {
+		ckfree(args);
+		return TCL_ERROR;
+	    }
+	    valuePtr = Tcl_GetObjResult(interp);
+	    Tcl_GetWideIntFromObj(NULL, valuePtr, &args[k].wideValue);
+	    Tcl_ResetResult(interp);
+	    break;
+	}
+    }
+
+    /*
+     * Call the function.
+     */
+
+    errno = 0;
+    result = dataPtr->proc(dataPtr->clientData, interp, args, &funcResult);
+    ckfree(args);
+    if (result != TCL_OK) {
+	return result;
+    }
+
+    /*
+     * Return the result of the call.
+     */
+
+    if (funcResult.type == TCL_INT) {
+	TclNewLongObj(valuePtr, funcResult.intValue);
+    } else if (funcResult.type == TCL_WIDE_INT) {
+	valuePtr = Tcl_NewWideIntObj(funcResult.wideValue);
+    } else {
+	return CheckDoubleResult(interp, funcResult.doubleValue);
+    }
+    Tcl_SetObjResult(interp, valuePtr);
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * OldMathFuncDeleteProc --
+ *
+ *	Cleans up after deleting a math function registered with
+ *	Tcl_CreateMathFunc
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Frees allocated memory.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+OldMathFuncDeleteProc(
+    ClientData clientData)
+{
+    OldMathFuncData *dataPtr = clientData;
+
+    ckfree(dataPtr->argTypes);
+    ckfree(dataPtr);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_GetMathFuncInfo --
+ *
+ *	Discovers how a particular math function was created in a given
+ *	interpreter.
+ *
+ * Results:
+ *	TCL_OK if it succeeds, TCL_ERROR else (leaving an error message in the
+ *	interpreter result if that happens.)
+ *
+ * Side effects:
+ *	If this function succeeds, the variables pointed to by the numArgsPtr
+ *	and argTypePtr arguments will be updated to detail the arguments
+ *	allowed by the function. The variable pointed to by the procPtr
+ *	argument will be set to NULL if the function is a builtin function,
+ *	and will be set to the address of the C function used to implement the
+ *	math function otherwise (in which case the variable pointed to by the
+ *	clientDataPtr argument will also be updated.)
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_GetMathFuncInfo(
+    Tcl_Interp *interp,
+    const char *name,
+    int *numArgsPtr,
+    Tcl_ValueType **argTypesPtr,
+    Tcl_MathProc **procPtr,
+    ClientData *clientDataPtr)
+{
+    Tcl_Obj *cmdNameObj;
+    Command *cmdPtr;
+
+    /*
+     * Get the command that implements the math function.
+     */
+
+    TclNewLiteralStringObj(cmdNameObj, "tcl::mathfunc::");
+    Tcl_AppendToObj(cmdNameObj, name, -1);
+    Tcl_IncrRefCount(cmdNameObj);
+    cmdPtr = (Command *) Tcl_GetCommandFromObj(interp, cmdNameObj);
+    Tcl_DecrRefCount(cmdNameObj);
+
+    /*
+     * Report unknown functions.
+     */
+
+    if (cmdPtr == NULL) {
+        Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+                "unknown math function \"%s\"", name));
+	Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "MATHFUNC", name, NULL);
+	*numArgsPtr = -1;
+	*argTypesPtr = NULL;
+	*procPtr = NULL;
+	*clientDataPtr = NULL;
+	return TCL_ERROR;
+    }
+
+    /*
+     * Retrieve function info for user defined functions; return dummy
+     * information for builtins.
+     */
+
+    if (cmdPtr->objProc == &OldMathFuncProc) {
+	OldMathFuncData *dataPtr = cmdPtr->clientData;
+
+	*procPtr = dataPtr->proc;
+	*numArgsPtr = dataPtr->numArgs;
+	*argTypesPtr = dataPtr->argTypes;
+	*clientDataPtr = dataPtr->clientData;
+    } else {
+	*procPtr = NULL;
+	*numArgsPtr = -1;
+	*argTypesPtr = NULL;
+	*procPtr = NULL;
+	*clientDataPtr = NULL;
+    }
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_ListMathFuncs --
+ *
+ *	Produces a list of all the math functions defined in a given
+ *	interpreter.
+ *
+ * Results:
+ *	A pointer to a Tcl_Obj structure with a reference count of zero, or
+ *	NULL in the case of an error (in which case a suitable error message
+ *	will be left in the interpreter result.)
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_Obj *
+Tcl_ListMathFuncs(
+    Tcl_Interp *interp,
+    const char *pattern)
+{
+    Tcl_Obj *script = Tcl_NewStringObj("::info functions ", -1);
+    Tcl_Obj *result;
+    Tcl_InterpState state;
+
+    if (pattern) {
+	Tcl_Obj *patternObj = Tcl_NewStringObj(pattern, -1);
+	Tcl_Obj *arg = Tcl_NewListObj(1, &patternObj);
+
+	Tcl_AppendObjToObj(script, arg);
+	Tcl_DecrRefCount(arg);	/* Should tear down patternObj too */
+    }
+
+    state = Tcl_SaveInterpState(interp, TCL_OK);
+    Tcl_IncrRefCount(script);
+    if (TCL_OK == Tcl_EvalObjEx(interp, script, 0)) {
+	result = Tcl_DuplicateObj(Tcl_GetObjResult(interp));
+    } else {
+	result = Tcl_NewObj();
+    }
+    Tcl_DecrRefCount(script);
+    Tcl_RestoreInterpState(interp, state);
+
+    return result;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclInterpReady --
+ *
+ *	Check if an interpreter is ready to eval commands or scripts, i.e., if
+ *	it was not deleted and if the nesting level is not too high.
+ *
+ * Results:
+ *	The return value is TCL_OK if it the interpreter is ready, TCL_ERROR
+ *	otherwise.
+ *
+ * Side effects:
+ *	The interpreters object and string results are cleared.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclInterpReady(
+    Tcl_Interp *interp)
+{
+    register Interp *iPtr = (Interp *) interp;
+
+    /*
+     * Reset both the interpreter's string and object results and clear out
+     * any previous error information.
+     */
+
+    Tcl_ResetResult(interp);
+
+    /*
+     * If the interpreter has been deleted, return an error.
+     */
+
+    if (iPtr->flags & DELETED) {
+	Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		"attempt to call eval in deleted interpreter", -1));
+	Tcl_SetErrorCode(interp, "TCL", "IDELETE",
+		"attempt to call eval in deleted interpreter", NULL);
+	return TCL_ERROR;
+    }
+
+    if (iPtr->execEnvPtr->rewind) {
+	return TCL_ERROR;
+    }
+
+    /*
+     * Make sure the script being evaluated (if any) has not been canceled.
+     */
+
+    if (TclCanceled(iPtr) &&
+	    (TCL_OK != Tcl_Canceled(interp, TCL_LEAVE_ERR_MSG))) {
+	return TCL_ERROR;
+    }
+
+    /*
+     * Check depth of nested calls to Tcl_Eval: if this gets too large, it's
+     * probably because of an infinite loop somewhere.
+     */
+
+    if (((iPtr->numLevels) <= iPtr->maxNestingDepth)) {
+	return TCL_OK;
+    }
+
+    Tcl_SetObjResult(interp, Tcl_NewStringObj(
+	    "too many nested evaluations (infinite loop?)", -1));
+    Tcl_SetErrorCode(interp, "TCL", "LIMIT", "STACK", NULL);
+    return TCL_ERROR;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclResetCancellation --
+ *
+ *	Reset the script cancellation flags if the nesting level
+ *	(iPtr->numLevels) for the interp is zero or argument force is
+ *	non-zero.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	The script cancellation flags for the interp may be reset.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclResetCancellation(
+    Tcl_Interp *interp,
+    int force)
+{
+    register Interp *iPtr = (Interp *) interp;
+
+    if (iPtr == NULL) {
+	return TCL_ERROR;
+    }
+
+    if (force || (iPtr->numLevels == 0)) {
+	TclUnsetCancelFlags(iPtr);
+    }
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_Canceled --
+ *
+ *	Check if the script in progress has been canceled, i.e.,
+ *	Tcl_CancelEval was called for this interpreter or any of its master
+ *	interpreters.
+ *
+ * Results:
+ *	The return value is TCL_OK if the script evaluation has not been
+ *	canceled, TCL_ERROR otherwise.
+ *
+ *	If "flags" contains TCL_LEAVE_ERR_MSG, an error message is returned in
+ *	the interpreter's result object. Otherwise, the interpreter's result
+ *	object is left unchanged. If "flags" contains TCL_CANCEL_UNWIND,
+ *	TCL_ERROR will only be returned if the script evaluation is being
+ *	completely unwound.
+ *
+ * Side effects:
+ *	The CANCELED flag for the interp will be reset if it is set.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_Canceled(
+    Tcl_Interp *interp,
+    int flags)
+{
+    register Interp *iPtr = (Interp *) interp;
+
+    /*
+     * Has the current script in progress for this interpreter been canceled
+     * or is the stack being unwound due to the previous script cancellation?
+     */
+
+    if (!TclCanceled(iPtr)) {
+        return TCL_OK;
+    }
+
+    /*
+     * The CANCELED flag is a one-shot flag that is reset immediately upon
+     * being detected; however, if the TCL_CANCEL_UNWIND flag is set we will
+     * continue to report that the script in progress has been canceled
+     * thereby allowing the evaluation stack for the interp to be fully
+     * unwound.
+     */
+
+    iPtr->flags &= ~CANCELED;
+
+    /*
+     * The CANCELED flag was detected and reset; however, if the caller
+     * specified the TCL_CANCEL_UNWIND flag, we only return TCL_ERROR
+     * (indicating that the script in progress has been canceled) if the
+     * evaluation stack for the interp is being fully unwound.
+     */
+
+    if ((flags & TCL_CANCEL_UNWIND) && !(iPtr->flags & TCL_CANCEL_UNWIND)) {
+        return TCL_OK;
+    }
+
+    /*
+     * If the TCL_LEAVE_ERR_MSG flags bit is set, place an error in the
+     * interp's result; otherwise, we leave it alone.
+     */
+
+    if (flags & TCL_LEAVE_ERR_MSG) {
+        const char *id, *message = NULL;
+        int length;
+
+        /*
+         * Setup errorCode variables so that we can differentiate between
+         * being canceled and unwound.
+         */
+
+        if (iPtr->asyncCancelMsg != NULL) {
+            message = Tcl_GetStringFromObj(iPtr->asyncCancelMsg, &length);
+        } else {
+            length = 0;
+        }
+
+        if (iPtr->flags & TCL_CANCEL_UNWIND) {
+            id = "IUNWIND";
+            if (length == 0) {
+                message = "eval unwound";
+            }
+        } else {
+            id = "ICANCEL";
+            if (length == 0) {
+                message = "eval canceled";
+            }
+        }
+
+        Tcl_SetObjResult(interp, Tcl_NewStringObj(message, -1));
+        Tcl_SetErrorCode(interp, "TCL", "CANCEL", id, message, NULL);
+    }
+
+    /*
+     * Return TCL_ERROR to the caller (not necessarily just the Tcl core
+     * itself) that indicates further processing of the script or command in
+     * progress should halt gracefully and as soon as possible.
+     */
+
+    return TCL_ERROR;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_CancelEval --
+ *
+ *	This function schedules the cancellation of the current script in the
+ *	given interpreter.
+ *
+ * Results:
+ *	The return value is a standard Tcl completion code such as TCL_OK or
+ *	TCL_ERROR. Since the interp may belong to a different thread, no error
+ *	message can be left in the interp's result.
+ *
+ * Side effects:
+ *	The script in progress in the specified interpreter will be canceled
+ *	with TCL_ERROR after asynchronous handlers are invoked at the next
+ *	Tcl_Canceled check.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_CancelEval(
+    Tcl_Interp *interp,		/* Interpreter in which to cancel the
+				 * script. */
+    Tcl_Obj *resultObjPtr,	/* The script cancellation error message or
+				 * NULL for a default error message. */
+    ClientData clientData,	/* Passed to CancelEvalProc. */
+    int flags)			/* Collection of OR-ed bits that control
+				 * the cancellation of the script. Only
+				 * TCL_CANCEL_UNWIND is currently
+				 * supported. */
+{
+    Tcl_HashEntry *hPtr;
+    CancelInfo *cancelInfo;
+    int code = TCL_ERROR;
+    const char *result;
+
+    if (interp == NULL) {
+	return TCL_ERROR;
+    }
+
+    Tcl_MutexLock(&cancelLock);
+    if (cancelTableInitialized != 1) {
+	/*
+	 * No CancelInfo hash table (Tcl_CreateInterp has never been called?)
+	 */
+
+	goto done;
+    }
+    hPtr = Tcl_FindHashEntry(&cancelTable, (char *) interp);
+    if (hPtr == NULL) {
+	/*
+	 * No CancelInfo record for this interpreter.
+	 */
+
+	goto done;
+    }
+    cancelInfo = Tcl_GetHashValue(hPtr);
+
+    /*
+     * Populate information needed by the interpreter thread to fulfill the
+     * cancellation request. Currently, clientData is ignored. If the
+     * TCL_CANCEL_UNWIND flags bit is set, the script in progress is not
+     * allowed to catch the script cancellation because the evaluation stack
+     * for the interp is completely unwound.
+     */
+
+    if (resultObjPtr != NULL) {
+	result = Tcl_GetStringFromObj(resultObjPtr, &cancelInfo->length);
+	cancelInfo->result = ckrealloc(cancelInfo->result,cancelInfo->length);
+	memcpy(cancelInfo->result, result, (size_t) cancelInfo->length);
+	TclDecrRefCount(resultObjPtr);	/* Discard their result object. */
+    } else {
+	cancelInfo->result = NULL;
+	cancelInfo->length = 0;
+    }
+    cancelInfo->clientData = clientData;
+    cancelInfo->flags = flags;
+    Tcl_AsyncMark(cancelInfo->async);
+    code = TCL_OK;
+
+  done:
+    Tcl_MutexUnlock(&cancelLock);
+    return code;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_InterpActive --
+ *
+ *	Returns non-zero if the specified interpreter is in use, i.e. if there
+ *	is an evaluation currently active in the interpreter.
+ *
+ * Results:
+ *	See above.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_InterpActive(
+    Tcl_Interp *interp)
+{
+    return ((Interp *) interp)->numLevels > 0;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_EvalObjv --
+ *
+ *	This function evaluates a Tcl command that has already been parsed
+ *	into words, with one Tcl_Obj holding each word.
+ *
+ * Results:
+ *	The return value is a standard Tcl completion code such as TCL_OK or
+ *	TCL_ERROR. A result or error message is left in interp's result.
+ *
+ * Side effects:
+ *	Always pushes a callback. Other side effects depend on the command.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_EvalObjv(
+    Tcl_Interp *interp,		/* Interpreter in which to evaluate the
+				 * command. Also used for error reporting. */
+    int objc,			/* Number of words in command. */
+    Tcl_Obj *const objv[],	/* An array of pointers to objects that are
+				 * the words that make up the command. */
+    int flags)			/* Collection of OR-ed bits that control the
+				 * evaluation of the script. Only
+				 * TCL_EVAL_GLOBAL, TCL_EVAL_INVOKE and
+				 * TCL_EVAL_NOERR are currently supported. */
+{
+    int result;
+    NRE_callback *rootPtr = TOP_CB(interp);
+
+    result = TclNREvalObjv(interp, objc, objv, flags, NULL);
+    return TclNRRunCallbacks(interp, result, rootPtr);
+}
+
+int
+TclNREvalObjv(
+    Tcl_Interp *interp,		/* Interpreter in which to evaluate the
+				 * command. Also used for error reporting. */
+    int objc,			/* Number of words in command. */
+    Tcl_Obj *const objv[],	/* An array of pointers to objects that are
+				 * the words that make up the command. */
+    int flags,			/* Collection of OR-ed bits that control the
+				 * evaluation of the script. Only
+				 * TCL_EVAL_GLOBAL, TCL_EVAL_INVOKE and
+				 * TCL_EVAL_NOERR are currently supported. */
+    Command *cmdPtr)		/* NULL if the Command is to be looked up
+				 * here, otherwise the pointer to the
+				 * requested Command struct to be invoked. */
+{
+    Interp *iPtr = (Interp *) interp;
+
+    /*
+     * data[1] stores a marker for use by tailcalls; it will be set to 1 by
+     * command redirectors (imports, alias, ensembles) so that tailcall skips
+     * this callback (that marks the end of the target command) and goes back
+     * to the end of the source command.
+     */
+
+    if (iPtr->deferredCallbacks) {
+        iPtr->deferredCallbacks = NULL;
+    } else {
+	TclNRAddCallback(interp, NRCommand, NULL, NULL, NULL, NULL);
+    }
+
+    iPtr->numLevels++;
+    TclNRAddCallback(interp, EvalObjvCore, cmdPtr, INT2PTR(flags),
+	    INT2PTR(objc), objv);
+    return TCL_OK;
+}
+
+static int
+EvalObjvCore(
+    ClientData data[],
+    Tcl_Interp *interp,
+    int result)
+{
+    Command *cmdPtr = NULL, *preCmdPtr = data[0];
+    int flags = PTR2INT(data[1]);
+    int objc = PTR2INT(data[2]);
+    Tcl_Obj **objv = data[3];
+    Interp *iPtr = (Interp *) interp;
+    Namespace *lookupNsPtr = NULL;
+    int enterTracesDone = 0;
+
+    /*
+     * Push records for task to be done on return, in INVERSE order. First, if
+     * needed, the exception handlers (as they should happen last).
+     */
+
+    if (!(flags & TCL_EVAL_NOERR)) {
+	TEOV_PushExceptionHandlers(interp, objc, objv, flags);
+    }
+
+    if (TCL_OK != TclInterpReady(interp)) {
+	return TCL_ERROR;
+    }
+
+    if (objc == 0) {
+	return TCL_OK;
+    }
+
+    if (TclLimitExceeded(iPtr->limit)) {
+	return TCL_ERROR;
+    }
+
+    /*
+     * Configure evaluation context to match the requested flags.
+     */
+
+    if (iPtr->lookupNsPtr) {
+
+	/*
+	 * Capture the namespace we should do command name resolution in, as
+	 * instructed by our caller sneaking it in to us in a private interp
+	 * field.  Clear that field right away so we cannot possibly have its
+	 * use leak where it should not.  The sneaky message pass is done.
+	 *
+	 * Use of this mechanism overrides the TCL_EVAL_GLOBAL flag.
+	 * TODO: Is that a bug?
+	 */
+
+	lookupNsPtr = iPtr->lookupNsPtr;
+	iPtr->lookupNsPtr = NULL;
+    } else if (flags & TCL_EVAL_INVOKE) {
+	lookupNsPtr = iPtr->globalNsPtr;
+    } else {
+
+	/*
+	 * TCL_EVAL_INVOKE was not set: clear rewrite rules
+	 */
+
+	TclResetRewriteEnsemble(interp, 1);
+
+	if (flags & TCL_EVAL_GLOBAL) {
+	    TEOV_SwitchVarFrame(interp);
+	    lookupNsPtr = iPtr->globalNsPtr;
+	}
+    }
+
+    /*
+     * Lookup the Command to dispatch.
+     */
+
+    reresolve:
+    assert(cmdPtr == NULL);
+    if (preCmdPtr) {
+	/* Caller gave it to us */
+	if (!(preCmdPtr->flags & CMD_IS_DELETED)) {
+	    /* So long as it exists, use it. */
+	    cmdPtr = preCmdPtr;
+	} else if (flags & TCL_EVAL_NORESOLVE) {
+	    /*
+	     * When it's been deleted, and we're told not to attempt
+	     * resolving it ourselves, all we can do is raise an error.
+	     */
+	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		    "attempt to invoke a deleted command"));
+	    Tcl_SetErrorCode(interp, "TCL", "EVAL", "DELETEDCOMMAND", NULL);
+	    return TCL_ERROR;
+	}
+    }
+    if (cmdPtr == NULL) {
+	cmdPtr = TEOV_LookupCmdFromObj(interp, objv[0], lookupNsPtr);
+	if (!cmdPtr) {
+	    return TEOV_NotFound(interp, objc, objv, lookupNsPtr);
+	}
+    }
+
+    if (enterTracesDone || iPtr->tracePtr
+	    || (cmdPtr->flags & CMD_HAS_EXEC_TRACES)) {
+
+	Tcl_Obj *commandPtr = TclGetSourceFromFrame(
+		flags & TCL_EVAL_SOURCE_IN_FRAME ?  iPtr->cmdFramePtr : NULL,
+		objc, objv);
+	Tcl_IncrRefCount(commandPtr);
+
+	if (!enterTracesDone) {
+
+	    int code = TEOV_RunEnterTraces(interp, &cmdPtr, commandPtr,
+		    objc, objv);
+
+	    /*
+	     * Send any exception from enter traces back as an exception
+	     * raised by the traced command.
+	     * TODO: Is this a bug?  Letting an execution trace BREAK or
+	     * CONTINUE or RETURN in the place of the traced command?
+	     * Would either converting all exceptions to TCL_ERROR, or
+	     * just swallowing them be better?  (Swallowing them has the
+	     * problem of permanently hiding program errors.)
+	     */
+
+	    if (code != TCL_OK) {
+		Tcl_DecrRefCount(commandPtr);
+		return code;
+	    }
+
+	    /*
+	     * If the enter traces made the resolved cmdPtr unusable, go
+	     * back and resolve again, but next time don't run enter
+	     * traces again.
+	     */
+
+	    if (cmdPtr == NULL) {
+		enterTracesDone = 1;
+		Tcl_DecrRefCount(commandPtr);
+		goto reresolve;
+	    }
+	}
+
+	/*
+	 * Schedule leave traces.  Raise the refCount on the resolved
+	 * cmdPtr, so that when it passes to the leave traces we know
+	 * it's still valid.
+	 */
+
+	cmdPtr->refCount++;
+	TclNRAddCallback(interp, TEOV_RunLeaveTraces, INT2PTR(objc),
+		    commandPtr, cmdPtr, objv);
+    }
+
+    TclNRAddCallback(interp, Dispatch,
+	    cmdPtr->nreProc ? cmdPtr->nreProc : cmdPtr->objProc,
+	    cmdPtr->objClientData, INT2PTR(objc), objv);
+    return TCL_OK;
+}
+
+static int
+Dispatch(
+    ClientData data[],
+    Tcl_Interp *interp,
+    int result)
+{
+    Tcl_ObjCmdProc *objProc = data[0];
+    ClientData clientData = data[1];
+    int objc = PTR2INT(data[2]);
+    Tcl_Obj **objv = data[3];
+    Interp *iPtr = (Interp *) interp;
+
+#ifdef USE_DTRACE
+    if (TCL_DTRACE_CMD_ARGS_ENABLED()) {
+	const char *a[10];
+	int i = 0;
+
+	while (i < 10) {
+	    a[i] = i < objc ? TclGetString(objv[i]) : NULL; i++;
+	}
+	TCL_DTRACE_CMD_ARGS(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7],
+		a[8], a[9]);
+    }
+    if (TCL_DTRACE_CMD_INFO_ENABLED() && iPtr->cmdFramePtr) {
+	Tcl_Obj *info = TclInfoFrame(interp, iPtr->cmdFramePtr);
+	const char *a[6]; int i[2];
+
+	TclDTraceInfo(info, a, i);
+	TCL_DTRACE_CMD_INFO(a[0], a[1], a[2], a[3], i[0], i[1], a[4], a[5]);
+	TclDecrRefCount(info);
+    }
+    if ((TCL_DTRACE_CMD_RETURN_ENABLED() || TCL_DTRACE_CMD_RESULT_ENABLED())
+	    && objc) {
+	TclNRAddCallback(interp, DTraceCmdReturn, objv[0], NULL, NULL, NULL);
+    }
+    if (TCL_DTRACE_CMD_ENTRY_ENABLED() && objc) {
+	TCL_DTRACE_CMD_ENTRY(TclGetString(objv[0]), objc - 1,
+		(Tcl_Obj **)(objv + 1));
+    }
+#endif /* USE_DTRACE */
+
+    iPtr->cmdCount++;
+    return objProc(clientData, interp, objc, objv);
+}
+
+int
+TclNRRunCallbacks(
+    Tcl_Interp *interp,
+    int result,
+    struct NRE_callback *rootPtr)
+				/* All callbacks down to rootPtr not inclusive
+				 * are to be run. */
+{
+    Interp *iPtr = (Interp *) interp;
+    NRE_callback *callbackPtr;
+    Tcl_NRPostProc *procPtr;
+
+    /*
+     * If the interpreter has a non-empty string result, the result object is
+     * either empty or stale because some function set interp->result
+     * directly. If so, move the string result to the result object, then
+     * reset the string result.
+     *
+     * This only needs to be done for the first item in the list: all other
+     * are for NR function calls, and those are Tcl_Obj based.
+     */
+
+    if (*(iPtr->result) != 0) {
+	(void) Tcl_GetObjResult(interp);
+    }
+
+    while (TOP_CB(interp) != rootPtr) {
+	callbackPtr = TOP_CB(interp);
+	procPtr = callbackPtr->procPtr;
+	TOP_CB(interp) = callbackPtr->nextPtr;
+	result = procPtr(callbackPtr->data, interp, result);
+	TCLNR_FREE(interp, callbackPtr);
+    }
+    return result;
+}
+
+static int
+NRCommand(
+    ClientData data[],
+    Tcl_Interp *interp,
+    int result)
+{
+    Interp *iPtr = (Interp *) interp;
+
+    iPtr->numLevels--;
+
+     /*
+      * If there is a tailcall, schedule it next
+      */
+
+    if (data[1] && (data[1] != INT2PTR(1))) {
+        TclNRAddCallback(interp, TclNRTailcallEval, data[1], NULL, NULL, NULL);
+    }
+
+    /* OPT ??
+     * Do not interrupt a series of cleanups with async or limit checks:
+     * just check at the end?
+     */
+
+    if (TclAsyncReady(iPtr)) {
+	result = Tcl_AsyncInvoke(interp, result);
+    }
+    if ((result == TCL_OK) && TclCanceled(iPtr)) {
+	result = Tcl_Canceled(interp, TCL_LEAVE_ERR_MSG);
+    }
+    if (result == TCL_OK && TclLimitReady(iPtr->limit)) {
+	result = Tcl_LimitCheck(interp);
+    }
+
+    return result;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TEOV_Exception	 -
+ * TEOV_LookupCmdFromObj -
+ * TEOV_RunEnterTraces	 -
+ * TEOV_RunLeaveTraces	 -
+ * TEOV_NotFound	 -
+ *
+ *	These are helper functions for Tcl_EvalObjv.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+TEOV_PushExceptionHandlers(
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const objv[],
+    int flags)
+{
+    Interp *iPtr = (Interp *) interp;
+
+    /*
+     * If any error processing is necessary, push the appropriate records.
+     * Note that we have to push them in the inverse order: first the one that
+     * has to run last.
+     */
+
+    if (!(flags & TCL_EVAL_INVOKE)) {
+	/*
+	 * Error messages
+	 */
+
+	TclNRAddCallback(interp, TEOV_Error, INT2PTR(objc),
+		(ClientData) objv, NULL, NULL);
+    }
+
+    if (iPtr->numLevels == 1) {
+	/*
+	 * No CONTINUE or BREAK at level 0, manage RETURN
+	 */
+
+	TclNRAddCallback(interp, TEOV_Exception, INT2PTR(iPtr->evalFlags),
+		NULL, NULL, NULL);
+    }
+}
+
+static void
+TEOV_SwitchVarFrame(
+    Tcl_Interp *interp)
+{
+    Interp *iPtr = (Interp *) interp;
+
+    /*
+     * Change the varFrame to be the rootVarFrame, and push a record to
+     * restore things at the end.
+     */
+
+    TclNRAddCallback(interp, TEOV_RestoreVarFrame, iPtr->varFramePtr, NULL,
+	    NULL, NULL);
+    iPtr->varFramePtr = iPtr->rootFramePtr;
+}
+
+static int
+TEOV_RestoreVarFrame(
+    ClientData data[],
+    Tcl_Interp *interp,
+    int result)
+{
+    ((Interp *) interp)->varFramePtr = data[0];
+    return result;
+}
+
+static int
+TEOV_Exception(
+    ClientData data[],
+    Tcl_Interp *interp,
+    int result)
+{
+    Interp *iPtr = (Interp *) interp;
+    int allowExceptions = (PTR2INT(data[0]) & TCL_ALLOW_EXCEPTIONS);
+
+    if (result != TCL_OK) {
+	if (result == TCL_RETURN) {
+	    result = TclUpdateReturnInfo(iPtr);
+	}
+	if ((result != TCL_ERROR) && !allowExceptions) {
+	    ProcessUnexpectedResult(interp, result);
+	    result = TCL_ERROR;
+	}
+    }
+
+    /*
+     * We are returning to level 0, so should process TclResetCancellation. As
+     * numLevels has not *yet* been decreased, do not call it: do the thing
+     * here directly.
+     */
+
+    TclUnsetCancelFlags(iPtr);
+    return result;
+}
+
+static int
+TEOV_Error(
+    ClientData data[],
+    Tcl_Interp *interp,
+    int result)
+{
+    Interp *iPtr = (Interp *) interp;
+    Tcl_Obj *listPtr;
+    const char *cmdString;
+    int cmdLen;
+    int objc = PTR2INT(data[0]);
+    Tcl_Obj **objv = data[1];
+
+    if ((result == TCL_ERROR) && !(iPtr->flags & ERR_ALREADY_LOGGED)){
+	/*
+	 * If there was an error, a command string will be needed for the
+	 * error log: get it out of the itemPtr. The details depend on the
+	 * type.
+	 */
+
+	listPtr = Tcl_NewListObj(objc, objv);
+	cmdString = Tcl_GetStringFromObj(listPtr, &cmdLen);
+	Tcl_LogCommandInfo(interp, cmdString, cmdString, cmdLen);
+	Tcl_DecrRefCount(listPtr);
+    }
+    iPtr->flags &= ~ERR_ALREADY_LOGGED;
+    return result;
+}
+
+static int
+TEOV_NotFound(
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const objv[],
+    Namespace *lookupNsPtr)
+{
+    Command * cmdPtr;
+    Interp *iPtr = (Interp *) interp;
+    int i, newObjc, handlerObjc;
+    Tcl_Obj **newObjv, **handlerObjv;
+    CallFrame *varFramePtr = iPtr->varFramePtr;
+    Namespace *currNsPtr = NULL;/* Used to check for and invoke any registered
+				 * unknown command handler for the current
+				 * namespace (TIP 181). */
+    Namespace *savedNsPtr = NULL;
+
+    currNsPtr = varFramePtr->nsPtr;
+    if ((currNsPtr == NULL) || (currNsPtr->unknownHandlerPtr == NULL)) {
+	currNsPtr = iPtr->globalNsPtr;
+	if (currNsPtr == NULL) {
+	    Tcl_Panic("Tcl_EvalObjv: NULL global namespace pointer");
+	}
+    }
+
+    /*
+     * Check to see if the resolution namespace has lost its unknown handler.
+     * If so, reset it to "::unknown".
+     */
+
+    if (currNsPtr->unknownHandlerPtr == NULL) {
+	TclNewLiteralStringObj(currNsPtr->unknownHandlerPtr, "::unknown");
+	Tcl_IncrRefCount(currNsPtr->unknownHandlerPtr);
+    }
+
+    /*
+     * Get the list of words for the unknown handler and allocate enough space
+     * to hold both the handler prefix and all words of the command invokation
+     * itself.
+     */
+
+    Tcl_ListObjGetElements(NULL, currNsPtr->unknownHandlerPtr,
+	    &handlerObjc, &handlerObjv);
+    newObjc = objc + handlerObjc;
+    newObjv = TclStackAlloc(interp, (int) sizeof(Tcl_Obj *) * newObjc);
+
+    /*
+     * Copy command prefix from unknown handler and add on the real command's
+     * full argument list. Note that we only use memcpy() once because we have
+     * to increment the reference count of all the handler arguments anyway.
+     */
+
+    for (i = 0; i < handlerObjc; ++i) {
+	newObjv[i] = handlerObjv[i];
+	Tcl_IncrRefCount(newObjv[i]);
+    }
+    memcpy(newObjv+handlerObjc, objv, sizeof(Tcl_Obj *) * (unsigned)objc);
+
+    /*
+     * Look up and invoke the handler (by recursive call to this function). If
+     * there is no handler at all, instead of doing the recursive call we just
+     * generate a generic error message; it would be an infinite-recursion
+     * nightmare otherwise.
+     *
+     * In this case we worry a bit less about recursion for now, and call the
+     * "blocking" interface.
+     */
+
+    cmdPtr = TEOV_LookupCmdFromObj(interp, newObjv[0], lookupNsPtr);
+    if (cmdPtr == NULL) {
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+                "invalid command name \"%s\"", TclGetString(objv[0])));
+        Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "COMMAND",
+                TclGetString(objv[0]), NULL);
+
+	/*
+	 * Release any resources we locked and allocated during the handler
+	 * call.
+	 */
+
+	for (i = 0; i < handlerObjc; ++i) {
+	    Tcl_DecrRefCount(newObjv[i]);
+	}
+	TclStackFree(interp, newObjv);
+	return TCL_ERROR;
+    }
+
+    if (lookupNsPtr) {
+	savedNsPtr = varFramePtr->nsPtr;
+	varFramePtr->nsPtr = lookupNsPtr;
+    }
+    TclSkipTailcall(interp);
+    TclNRAddCallback(interp, TEOV_NotFoundCallback, INT2PTR(handlerObjc),
+	    newObjv, savedNsPtr, NULL);
+    return TclNREvalObjv(interp, newObjc, newObjv, TCL_EVAL_NOERR, NULL);
+}
+
+static int
+TEOV_NotFoundCallback(
+    ClientData data[],
+    Tcl_Interp *interp,
+    int result)
+{
+    Interp *iPtr = (Interp *) interp;
+    int objc = PTR2INT(data[0]);
+    Tcl_Obj **objv = data[1];
+    Namespace *savedNsPtr = data[2];
+
+    int i;
+
+    if (savedNsPtr) {
+	iPtr->varFramePtr->nsPtr = savedNsPtr;
+    }
+
+    /*
+     * Release any resources we locked and allocated during the handler call.
+     */
+
+    for (i = 0; i < objc; ++i) {
+	Tcl_DecrRefCount(objv[i]);
+    }
+    TclStackFree(interp, objv);
+
+    return result;
+}
+
+static int
+TEOV_RunEnterTraces(
+    Tcl_Interp *interp,
+    Command **cmdPtrPtr,
+    Tcl_Obj *commandPtr,
+    int objc,
+    Tcl_Obj *const objv[])
+{
+    Interp *iPtr = (Interp *) interp;
+    Command *cmdPtr = *cmdPtrPtr;
+    int newEpoch, cmdEpoch = cmdPtr->cmdEpoch;
+    int length, traceCode = TCL_OK;
+    const char *command = Tcl_GetStringFromObj(commandPtr, &length);
+
+    /*
+     * Call trace functions.
+     * Execute any command or execution traces. Note that we bump up the
+     * command's reference count for the duration of the calling of the
+     * traces so that the structure doesn't go away underneath our feet.
+     */
+
+    cmdPtr->refCount++;
+    if (iPtr->tracePtr) {
+	traceCode = TclCheckInterpTraces(interp, command, length,
+		cmdPtr, TCL_OK, TCL_TRACE_ENTER_EXEC, objc, objv);
+    }
+    if ((cmdPtr->flags & CMD_HAS_EXEC_TRACES) && (traceCode == TCL_OK)) {
+	traceCode = TclCheckExecutionTraces(interp, command, length,
+		cmdPtr, TCL_OK, TCL_TRACE_ENTER_EXEC, objc, objv);
+    }
+    newEpoch = cmdPtr->cmdEpoch;
+    TclCleanupCommandMacro(cmdPtr);
+
+    if (traceCode != TCL_OK) {
+	if (traceCode == TCL_ERROR) {
+	    Tcl_Obj *info;
+
+	    TclNewLiteralStringObj(info, "\n    (enter trace on \"");
+	    Tcl_AppendLimitedToObj(info, command, length, 55, "...");
+	    Tcl_AppendToObj(info, "\")", 2);
+	    Tcl_AppendObjToErrorInfo(interp, info);
+	    iPtr->flags |= ERR_ALREADY_LOGGED;
+	}
+	return traceCode;
+    }
+    if (cmdEpoch != newEpoch) {
+	*cmdPtrPtr = NULL;
+    }
+    return TCL_OK;
+}
+
+static int
+TEOV_RunLeaveTraces(
+    ClientData data[],
+    Tcl_Interp *interp,
+    int result)
+{
+    Interp *iPtr = (Interp *) interp;
+    int traceCode = TCL_OK;
+    int objc = PTR2INT(data[0]);
+    Tcl_Obj *commandPtr = data[1];
+    Command *cmdPtr = data[2];
+    Tcl_Obj **objv = data[3];
+    int length;
+    const char *command = Tcl_GetStringFromObj(commandPtr, &length);
+
+    if (!(cmdPtr->flags & CMD_IS_DELETED)) {
+	if (cmdPtr->flags & CMD_HAS_EXEC_TRACES){
+	    traceCode = TclCheckExecutionTraces(interp, command, length,
+		    cmdPtr, result, TCL_TRACE_LEAVE_EXEC, objc, objv);
+	}
+	if (iPtr->tracePtr != NULL && traceCode == TCL_OK) {
+	    traceCode = TclCheckInterpTraces(interp, command, length,
+		    cmdPtr, result, TCL_TRACE_LEAVE_EXEC, objc, objv);
+	}
+    }
+
+    /*
+     * As cmdPtr is set, TclNRRunCallbacks is about to reduce the numlevels.
+     * Prevent that by resetting the cmdPtr field and dealing right here with
+     * cmdPtr->refCount.
+     */
+
+    TclCleanupCommandMacro(cmdPtr);
+
+    if (traceCode != TCL_OK) {
+	if (traceCode == TCL_ERROR) {
+	    Tcl_Obj *info;
+
+	    TclNewLiteralStringObj(info, "\n    (leave trace on \"");
+	    Tcl_AppendLimitedToObj(info, command, length, 55, "...");
+	    Tcl_AppendToObj(info, "\")", 2);
+	    Tcl_AppendObjToErrorInfo(interp, info);
+	    iPtr->flags |= ERR_ALREADY_LOGGED;
+	}
+	result = traceCode;
+    }
+    Tcl_DecrRefCount(commandPtr);
+    return result;
+}
+
+static inline Command *
+TEOV_LookupCmdFromObj(
+    Tcl_Interp *interp,
+    Tcl_Obj *namePtr,
+    Namespace *lookupNsPtr)
+{
+    Interp *iPtr = (Interp *) interp;
+    Command *cmdPtr;
+    Namespace *savedNsPtr = iPtr->varFramePtr->nsPtr;
+
+    if (lookupNsPtr) {
+	iPtr->varFramePtr->nsPtr = lookupNsPtr;
+    }
+    cmdPtr = (Command *) Tcl_GetCommandFromObj(interp, namePtr);
+    iPtr->varFramePtr->nsPtr = savedNsPtr;
+    return cmdPtr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_EvalTokensStandard --
+ *
+ *	Given an array of tokens parsed from a Tcl command (e.g., the tokens
+ *	that make up a word or the index for an array variable) this function
+ *	evaluates the tokens and concatenates their values to form a single
+ *	result value.
+ *
+ * Results:
+ *	The return value is a standard Tcl completion code such as TCL_OK or
+ *	TCL_ERROR. A result or error message is left in interp's result.
+ *
+ * Side effects:
+ *	Depends on the array of tokens being evaled.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_EvalTokensStandard(
+    Tcl_Interp *interp,		/* Interpreter in which to lookup variables,
+				 * execute nested commands, and report
+				 * errors. */
+    Tcl_Token *tokenPtr,	/* Pointer to first in an array of tokens to
+				 * evaluate and concatenate. */
+    int count)			/* Number of tokens to consider at tokenPtr.
+				 * Must be at least 1. */
+{
+    return TclSubstTokens(interp, tokenPtr, count, /* numLeftPtr */ NULL, 1,
+	    NULL, NULL);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_EvalTokens --
+ *
+ *	Given an array of tokens parsed from a Tcl command (e.g., the tokens
+ *	that make up a word or the index for an array variable) this function
+ *	evaluates the tokens and concatenates their values to form a single
+ *	result value.
+ *
+ * Results:
+ *	The return value is a pointer to a newly allocated Tcl_Obj containing
+ *	the value of the array of tokens. The reference count of the returned
+ *	object has been incremented. If an error occurs in evaluating the
+ *	tokens then a NULL value is returned and an error message is left in
+ *	interp's result.
+ *
+ * Side effects:
+ *	A new object is allocated to hold the result.
+ *
+ *----------------------------------------------------------------------
+ *
+ * This uses a non-standard return convention; its use is now deprecated. It
+ * is a wrapper for the new function Tcl_EvalTokensStandard, and is not used
+ * in the core any longer. It is only kept for backward compatibility.
+ */
+
+Tcl_Obj *
+Tcl_EvalTokens(
+    Tcl_Interp *interp,		/* Interpreter in which to lookup variables,
+				 * execute nested commands, and report
+				 * errors. */
+    Tcl_Token *tokenPtr,	/* Pointer to first in an array of tokens to
+				 * evaluate and concatenate. */
+    int count)			/* Number of tokens to consider at tokenPtr.
+				 * Must be at least 1. */
+{
+    Tcl_Obj *resPtr;
+
+    if (Tcl_EvalTokensStandard(interp, tokenPtr, count) != TCL_OK) {
+	return NULL;
+    }
+    resPtr = Tcl_GetObjResult(interp);
+    Tcl_IncrRefCount(resPtr);
+    Tcl_ResetResult(interp);
+    return resPtr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_EvalEx, TclEvalEx --
+ *
+ *	This function evaluates a Tcl script without using the compiler or
+ *	byte-code interpreter. It just parses the script, creates values for
+ *	each word of each command, then calls EvalObjv to execute each
+ *	command.
+ *
+ * Results:
+ *	The return value is a standard Tcl completion code such as TCL_OK or
+ *	TCL_ERROR. A result or error message is left in interp's result.
+ *
+ * Side effects:
+ *	Depends on the script.
+ *
+ * TIP #280 : Keep public API, internally extended API.
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_EvalEx(
+    Tcl_Interp *interp,		/* Interpreter in which to evaluate the
+				 * script. Also used for error reporting. */
+    const char *script,		/* First character of script to evaluate. */
+    int numBytes,		/* Number of bytes in script. If < 0, the
+				 * script consists of all bytes up to the
+				 * first null character. */
+    int flags)			/* Collection of OR-ed bits that control the
+				 * evaluation of the script. Only
+				 * TCL_EVAL_GLOBAL is currently supported. */
+{
+    return TclEvalEx(interp, script, numBytes, flags, 1, NULL, script);
+}
+
+int
+TclEvalEx(
+    Tcl_Interp *interp,		/* Interpreter in which to evaluate the
+				 * script. Also used for error reporting. */
+    const char *script,		/* First character of script to evaluate. */
+    int numBytes,		/* Number of bytes in script. If < 0, the
+				 * script consists of all bytes up to the
+				 * first NUL character. */
+    int flags,			/* Collection of OR-ed bits that control the
+				 * evaluation of the script. Only
+				 * TCL_EVAL_GLOBAL is currently supported. */
+    int line,			/* The line the script starts on. */
+    int *clNextOuter,		/* Information about an outer context for */
+    const char *outerScript)	/* continuation line data. This is set only in
+				 * TclSubstTokens(), to properly handle
+				 * [...]-nested commands. The 'outerScript'
+				 * refers to the most-outer script containing
+				 * the embedded command, which is refered to
+				 * by 'script'. The 'clNextOuter' refers to
+				 * the current entry in the table of
+				 * continuation lines in this "master script",
+				 * and the character offsets are relative to
+				 * the 'outerScript' as well.
+				 *
+				 * If outerScript == script, then this call is
+				 * for the outer-most script/command. See
+				 * Tcl_EvalEx() and TclEvalObjEx() for places
+				 * generating arguments for which this is
+				 * true. */
+{
+    Interp *iPtr = (Interp *) interp;
+    const char *p, *next;
+    const unsigned int minObjs = 20;
+    Tcl_Obj **objv, **objvSpace;
+    int *expand, *lines, *lineSpace;
+    Tcl_Token *tokenPtr;
+    int commandLength, bytesLeft, expandRequested, code = TCL_OK;
+    CallFrame *savedVarFramePtr;/* Saves old copy of iPtr->varFramePtr in case
+				 * TCL_EVAL_GLOBAL was set. */
+    int allowExceptions = (iPtr->evalFlags & TCL_ALLOW_EXCEPTIONS);
+    int gotParse = 0;
+    unsigned int i, objectsUsed = 0;
+				/* These variables keep track of how much
+				 * state has been allocated while evaluating
+				 * the script, so that it can be freed
+				 * properly if an error occurs. */
+    Tcl_Parse *parsePtr = TclStackAlloc(interp, sizeof(Tcl_Parse));
+    CmdFrame *eeFramePtr = TclStackAlloc(interp, sizeof(CmdFrame));
+    Tcl_Obj **stackObjArray =
+	    TclStackAlloc(interp, minObjs * sizeof(Tcl_Obj *));
+    int *expandStack = TclStackAlloc(interp, minObjs * sizeof(int));
+    int *linesStack = TclStackAlloc(interp, minObjs * sizeof(int));
+				/* TIP #280 Structures for tracking of command
+				 * locations. */
+    int *clNext = NULL;		/* Pointer for the tracking of invisible
+				 * continuation lines. Initialized only if the
+				 * caller gave us a table of locations to
+				 * track, via scriptCLLocPtr. It always refers
+				 * to the table entry holding the location of
+				 * the next invisible continuation line to
+				 * look for, while parsing the script. */
+
+    if (iPtr->scriptCLLocPtr) {
+	if (clNextOuter) {
+	    clNext = clNextOuter;
+	} else {
+	    clNext = &iPtr->scriptCLLocPtr->loc[0];
+	}
+    }
+
+    if (numBytes < 0) {
+	numBytes = strlen(script);
+    }
+    Tcl_ResetResult(interp);
+
+    savedVarFramePtr = iPtr->varFramePtr;
+    if (flags & TCL_EVAL_GLOBAL) {
+	iPtr->varFramePtr = iPtr->rootFramePtr;
+    }
+
+    /*
+     * Each iteration through the following loop parses the next command from
+     * the script and then executes it.
+     */
+
+    objv = objvSpace = stackObjArray;
+    lines = lineSpace = linesStack;
+    expand = expandStack;
+    p = script;
+    bytesLeft = numBytes;
+
+    /*
+     * TIP #280 Initialize tracking. Do not push on the frame stack yet.
+     *
+     * We open a new context, either for a sourced script, or 'eval'.
+     * For sourced files we always have a path object, even if nothing was
+     * specified in the interp itself. That makes code using it simpler as
+     * NULL checks can be left out. Sourced file without path in the
+     * 'scriptFile' is possible during Tcl initialization.
+     */
+
+    eeFramePtr->level = iPtr->cmdFramePtr ? iPtr->cmdFramePtr->level + 1 : 1;
+    eeFramePtr->framePtr = iPtr->framePtr;
+    eeFramePtr->nextPtr = iPtr->cmdFramePtr;
+    eeFramePtr->nline = 0;
+    eeFramePtr->line = NULL;
+    eeFramePtr->cmdObj = NULL;
+
+    iPtr->cmdFramePtr = eeFramePtr;
+    if (iPtr->evalFlags & TCL_EVAL_FILE) {
+	/*
+	 * Set up for a sourced file.
+	 */
+
+	eeFramePtr->type = TCL_LOCATION_SOURCE;
+
+	if (iPtr->scriptFile) {
+	    /*
+	     * Normalization here, to have the correct pwd. Should have
+	     * negligible impact on performance, as the norm should have been
+	     * done already by the 'source' invoking us, and it caches the
+	     * result.
+	     */
+
+	    Tcl_Obj *norm = Tcl_FSGetNormalizedPath(interp, iPtr->scriptFile);
+
+	    if (norm == NULL) {
+		/*
+		 * Error message in the interp result.
+		 */
+
+		code = TCL_ERROR;
+		goto error;
+	    }
+	    eeFramePtr->data.eval.path = norm;
+	} else {
+	    TclNewLiteralStringObj(eeFramePtr->data.eval.path, "");
+	}
+	Tcl_IncrRefCount(eeFramePtr->data.eval.path);
+    } else {
+	/*
+	 * Set up for plain eval.
+	 */
+
+	eeFramePtr->type = TCL_LOCATION_EVAL;
+	eeFramePtr->data.eval.path = NULL;
+    }
+
+    iPtr->evalFlags = 0;
+    do {
+	if (Tcl_ParseCommand(interp, p, bytesLeft, 0, parsePtr) != TCL_OK) {
+	    code = TCL_ERROR;
+	    Tcl_LogCommandInfo(interp, script, parsePtr->commandStart,
+		    parsePtr->term + 1 - parsePtr->commandStart);
+	    goto posterror;
+	}
+
+	/*
+	 * TIP #280 Track lines. The parser may have skipped text till it
+	 * found the command we are now at. We have to count the lines in this
+	 * block, and do not forget invisible continuation lines.
+	 */
+
+	TclAdvanceLines(&line, p, parsePtr->commandStart);
+	TclAdvanceContinuations(&line, &clNext,
+		parsePtr->commandStart - outerScript);
+
+	gotParse = 1;
+	if (parsePtr->numWords > 0) {
+	    /*
+	     * TIP #280. Track lines within the words of the current
+	     * command. We use a separate pointer into the table of
+	     * continuation line locations to not lose our position for the
+	     * per-command parsing.
+	     */
+
+	    int wordLine = line;
+	    const char *wordStart = parsePtr->commandStart;
+	    int *wordCLNext = clNext;
+	    unsigned int objectsNeeded = 0;
+	    unsigned int numWords = parsePtr->numWords;
+
+	    /*
+	     * Generate an array of objects for the words of the command.
+	     */
+
+	    if (numWords > minObjs) {
+		expand =    ckalloc(numWords * sizeof(int));
+		objvSpace = ckalloc(numWords * sizeof(Tcl_Obj *));
+		lineSpace = ckalloc(numWords * sizeof(int));
+	    }
+	    expandRequested = 0;
+	    objv = objvSpace;
+	    lines = lineSpace;
+
+	    iPtr->cmdFramePtr = eeFramePtr->nextPtr;
+	    for (objectsUsed = 0, tokenPtr = parsePtr->tokenPtr;
+		    objectsUsed < numWords;
+		    objectsUsed++, tokenPtr += tokenPtr->numComponents+1) {
+		/*
+		 * TIP #280. Track lines to current word. Save the information
+		 * on a per-word basis, signaling dynamic words as needed.
+		 * Make the information available to the recursively called
+		 * evaluator as well, including the type of context (source
+		 * vs. eval).
+		 */
+
+		TclAdvanceLines(&wordLine, wordStart, tokenPtr->start);
+		TclAdvanceContinuations(&wordLine, &wordCLNext,
+			tokenPtr->start - outerScript);
+		wordStart = tokenPtr->start;
+
+		lines[objectsUsed] = TclWordKnownAtCompileTime(tokenPtr, NULL)
+			? wordLine : -1;
+
+		if (eeFramePtr->type == TCL_LOCATION_SOURCE) {
+		    iPtr->evalFlags |= TCL_EVAL_FILE;
+		}
+
+		code = TclSubstTokens(interp, tokenPtr+1,
+			tokenPtr->numComponents, NULL, wordLine,
+			wordCLNext, outerScript);
+
+		iPtr->evalFlags = 0;
+
+		if (code != TCL_OK) {
+		    break;
+		}
+		objv[objectsUsed] = Tcl_GetObjResult(interp);
+		Tcl_IncrRefCount(objv[objectsUsed]);
+		if (tokenPtr->type == TCL_TOKEN_EXPAND_WORD) {
+		    int numElements;
+
+		    code = TclListObjLength(interp, objv[objectsUsed],
+			    &numElements);
+		    if (code == TCL_ERROR) {
+			/*
+			 * Attempt to expand a non-list.
+			 */
+
+			Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf(
+				"\n    (expanding word %d)", objectsUsed));
+			Tcl_DecrRefCount(objv[objectsUsed]);
+			break;
+		    }
+		    expandRequested = 1;
+		    expand[objectsUsed] = 1;
+
+		    objectsNeeded += (numElements ? numElements : 1);
+		} else {
+		    expand[objectsUsed] = 0;
+		    objectsNeeded++;
+		}
+
+		if (wordCLNext) {
+		    TclContinuationsEnterDerived(objv[objectsUsed],
+			    wordStart - outerScript, wordCLNext);
+		}
+	    } /* for loop */
+	    iPtr->cmdFramePtr = eeFramePtr;
+	    if (code != TCL_OK) {
+		goto error;
+	    }
+	    if (expandRequested) {
+		/*
+		 * Some word expansion was requested. Check for objv resize.
+		 */
+
+		Tcl_Obj **copy = objvSpace;
+		int *lcopy = lineSpace;
+		int wordIdx = numWords;
+		int objIdx = objectsNeeded - 1;
+
+		if ((numWords > minObjs) || (objectsNeeded > minObjs)) {
+		    objv = objvSpace =
+			    ckalloc(objectsNeeded * sizeof(Tcl_Obj *));
+		    lines = lineSpace = ckalloc(objectsNeeded * sizeof(int));
+		}
+
+		objectsUsed = 0;
+		while (wordIdx--) {
+		    if (expand[wordIdx]) {
+			int numElements;
+			Tcl_Obj **elements, *temp = copy[wordIdx];
+
+			Tcl_ListObjGetElements(NULL, temp, &numElements,
+				&elements);
+			objectsUsed += numElements;
+			while (numElements--) {
+			    lines[objIdx] = -1;
+			    objv[objIdx--] = elements[numElements];
+			    Tcl_IncrRefCount(elements[numElements]);
+			}
+			Tcl_DecrRefCount(temp);
+		    } else {
+			lines[objIdx] = lcopy[wordIdx];
+			objv[objIdx--] = copy[wordIdx];
+			objectsUsed++;
+		    }
+		}
+		objv += objIdx+1;
+
+		if (copy != stackObjArray) {
+		    ckfree(copy);
+		}
+		if (lcopy != linesStack) {
+		    ckfree(lcopy);
+		}
+	    }
+
+	    /*
+	     * Execute the command and free the objects for its words.
+	     *
+	     * TIP #280: Remember the command itself for 'info frame'. We
+	     * shorten the visible command by one char to exclude the
+	     * termination character, if necessary. Here is where we put our
+	     * frame on the stack of frames too. _After_ the nested commands
+	     * have been executed.
+	     */
+
+	    eeFramePtr->cmd = parsePtr->commandStart;
+	    eeFramePtr->len = parsePtr->commandSize;
+
+	    if (parsePtr->term ==
+		    parsePtr->commandStart + parsePtr->commandSize - 1) {
+		eeFramePtr->len--;
+	    }
+
+	    eeFramePtr->nline = objectsUsed;
+	    eeFramePtr->line = lines;
+
+	    TclArgumentEnter(interp, objv, objectsUsed, eeFramePtr);
+	    code = Tcl_EvalObjv(interp, objectsUsed, objv,
+		    TCL_EVAL_NOERR | TCL_EVAL_SOURCE_IN_FRAME);
+	    TclArgumentRelease(interp, objv, objectsUsed);
+
+	    eeFramePtr->line = NULL;
+	    eeFramePtr->nline = 0;
+	    if (eeFramePtr->cmdObj) {
+		Tcl_DecrRefCount(eeFramePtr->cmdObj);
+		eeFramePtr->cmdObj = NULL;
+	    }
+
+	    if (code != TCL_OK) {
+		goto error;
+	    }
+	    for (i = 0; i < objectsUsed; i++) {
+		Tcl_DecrRefCount(objv[i]);
+	    }
+	    objectsUsed = 0;
+	    if (objvSpace != stackObjArray) {
+		ckfree(objvSpace);
+		objvSpace = stackObjArray;
+		ckfree(lineSpace);
+		lineSpace = linesStack;
+	    }
+
+	    /*
+	     * Free expand separately since objvSpace could have been
+	     * reallocated above.
+	     */
+
+	    if (expand != expandStack) {
+		ckfree(expand);
+		expand = expandStack;
+	    }
+	}
+
+	/*
+	 * Advance to the next command in the script.
+	 *
+	 * TIP #280 Track Lines. Now we track how many lines were in the
+	 * executed command.
+	 */
+
+	next = parsePtr->commandStart + parsePtr->commandSize;
+	bytesLeft -= next - p;
+	p = next;
+	TclAdvanceLines(&line, parsePtr->commandStart, p);
+	Tcl_FreeParse(parsePtr);
+	gotParse = 0;
+    } while (bytesLeft > 0);
+    iPtr->varFramePtr = savedVarFramePtr;
+    code = TCL_OK;
+    goto cleanup_return;
+
+  error:
+    /*
+     * Generate and log various pieces of error information.
+     */
+
+    if (iPtr->numLevels == 0) {
+	if (code == TCL_RETURN) {
+	    code = TclUpdateReturnInfo(iPtr);
+	}
+	if ((code != TCL_OK) && (code != TCL_ERROR) && !allowExceptions) {
+	    ProcessUnexpectedResult(interp, code);
+	    code = TCL_ERROR;
+	}
+    }
+    if ((code == TCL_ERROR) && !(iPtr->flags & ERR_ALREADY_LOGGED)) {
+	commandLength = parsePtr->commandSize;
+	if (parsePtr->term == parsePtr->commandStart + commandLength - 1) {
+	    /*
+	     * The terminator character (such as ; or ]) of the command where
+	     * the error occurred is the last character in the parsed command.
+	     * Reduce the length by one so that the error message doesn't
+	     * include the terminator character.
+	     */
+
+	    commandLength -= 1;
+	}
+	Tcl_LogCommandInfo(interp, script, parsePtr->commandStart,
+		commandLength);
+    }
+ posterror:
+    iPtr->flags &= ~ERR_ALREADY_LOGGED;
+
+    /*
+     * Then free resources that had been allocated to the command.
+     */
+
+    for (i = 0; i < objectsUsed; i++) {
+	Tcl_DecrRefCount(objv[i]);
+    }
+    if (gotParse) {
+	Tcl_FreeParse(parsePtr);
+    }
+    if (objvSpace != stackObjArray) {
+	ckfree(objvSpace);
+	ckfree(lineSpace);
+    }
+    if (expand != expandStack) {
+	ckfree(expand);
+    }
+    iPtr->varFramePtr = savedVarFramePtr;
+
+ cleanup_return:
+    /*
+     * TIP #280. Release the local CmdFrame, and its contents.
+     */
+
+    iPtr->cmdFramePtr = iPtr->cmdFramePtr->nextPtr;
+    if (eeFramePtr->type == TCL_LOCATION_SOURCE) {
+	Tcl_DecrRefCount(eeFramePtr->data.eval.path);
+    }
+    TclStackFree(interp, linesStack);
+    TclStackFree(interp, expandStack);
+    TclStackFree(interp, stackObjArray);
+    TclStackFree(interp, eeFramePtr);
+    TclStackFree(interp, parsePtr);
+
+    return code;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclAdvanceLines --
+ *
+ *	This function is a helper which counts the number of lines in a block
+ *	of text and advances an external counter.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The specified counter is advanced per the number of lines found.
+ *
+ * TIP #280
+ *----------------------------------------------------------------------
+ */
+
+void
+TclAdvanceLines(
+    int *line,
+    const char *start,
+    const char *end)
+{
+    register const char *p;
+
+    for (p = start; p < end; p++) {
+	if (*p == '\n') {
+	    (*line)++;
+	}
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclAdvanceContinuations --
+ *
+ *	This procedure is a helper which counts the number of continuation
+ *	lines (CL) in a block of text using a table of CL locations and
+ *	advances an external counter, and the pointer into the table.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The specified counter is advanced per the number of continuation lines
+ *	found.
+ *
+ * TIP #280
+ *----------------------------------------------------------------------
+ */
+
+void
+TclAdvanceContinuations(
+    int *line,
+    int **clNextPtrPtr,
+    int loc)
+{
+    /*
+     * Track the invisible continuation lines embedded in a script, if any.
+     * Here they are just spaces (already). They were removed by
+     * TclSubstTokens via TclParseBackslash.
+     *
+     * *clNextPtrPtr         <=> We have continuation lines to track.
+     * **clNextPtrPtr >= 0   <=> We are not beyond the last possible location.
+     * loc >= **clNextPtrPtr <=> We stepped beyond the current cont. line.
+     */
+
+    while (*clNextPtrPtr && (**clNextPtrPtr >= 0)
+	    && (loc >= **clNextPtrPtr)) {
+	/*
+	 * We just stepped over an invisible continuation line. Adjust the
+	 * line counter and step to the table entry holding the location of
+	 * the next continuation line to track.
+	 */
+
+	(*line)++;
+	(*clNextPtrPtr)++;
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ * Note: The whole data structure access for argument location tracking is
+ * hidden behind these three functions. The only parts open are the lineLAPtr
+ * field in the Interp structure. The CFWord definition is internal to here.
+ * Should make it easier to redo the data structures if we find something more
+ * space/time efficient.
+ */
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclArgumentEnter --
+ *
+ *	This procedure is a helper for the TIP #280 uplevel extension. It
+ *	enters location references for the arguments of a command to be
+ *	invoked. Only the first entry has the actual data, further entries
+ *	simply count the usage up.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	May allocate memory.
+ *
+ * TIP #280
+ *----------------------------------------------------------------------
+ */
+
+void
+TclArgumentEnter(
+    Tcl_Interp *interp,
+    Tcl_Obj **objv,
+    int objc,
+    CmdFrame *cfPtr)
+{
+    Interp *iPtr = (Interp *) interp;
+    int new, i;
+    Tcl_HashEntry *hPtr;
+    CFWord *cfwPtr;
+
+    for (i = 1; i < objc; i++) {
+	/*
+	 * Ignore argument words without line information (= dynamic). If they
+	 * are variables they may have location information associated with
+	 * that, either through globally recorded 'set' invokations, or
+	 * literals in bytecode. Eitehr way there is no need to record
+	 * something here.
+	 */
+
+	if (cfPtr->line[i] < 0) {
+	    continue;
+	}
+	hPtr = Tcl_CreateHashEntry(iPtr->lineLAPtr, objv[i], &new);
+	if (new) {
+	    /*
+	     * The word is not on the stack yet, remember the current location
+	     * and initialize references.
+	     */
+
+	    cfwPtr = ckalloc(sizeof(CFWord));
+	    cfwPtr->framePtr = cfPtr;
+	    cfwPtr->word = i;
+	    cfwPtr->refCount = 1;
+	    Tcl_SetHashValue(hPtr, cfwPtr);
+	} else {
+	    /*
+	     * The word is already on the stack, its current location is not
+	     * relevant. Just remember the reference to prevent early removal.
+	     */
+
+	    cfwPtr = Tcl_GetHashValue(hPtr);
+	    cfwPtr->refCount++;
+	}
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclArgumentRelease --
+ *
+ *	This procedure is a helper for the TIP #280 uplevel extension. It
+ *	removes the location references for the arguments of a command just
+ *	done. Usage is counted down, the data is removed only when no user is
+ *	left over.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	May release memory.
+ *
+ * TIP #280
+ *----------------------------------------------------------------------
+ */
+
+void
+TclArgumentRelease(
+    Tcl_Interp *interp,
+    Tcl_Obj **objv,
+    int objc)
+{
+    Interp *iPtr = (Interp *) interp;
+    int i;
+
+    for (i = 1; i < objc; i++) {
+	CFWord *cfwPtr;
+	Tcl_HashEntry *hPtr =
+		Tcl_FindHashEntry(iPtr->lineLAPtr, (char *) objv[i]);
+
+	if (!hPtr) {
+	    continue;
+	}
+	cfwPtr = Tcl_GetHashValue(hPtr);
+
+	cfwPtr->refCount--;
+	if (cfwPtr->refCount > 0) {
+	    continue;
+	}
+
+	ckfree(cfwPtr);
+	Tcl_DeleteHashEntry(hPtr);
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclArgumentBCEnter --
+ *
+ *	This procedure is a helper for the TIP #280 uplevel extension. It
+ *	enters location references for the literal arguments of commands in
+ *	bytecode about to be invoked. Only the first entry has the actual
+ *	data, further entries simply count the usage up.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	May allocate memory.
+ *
+ * TIP #280
+ *----------------------------------------------------------------------
+ */
+
+void
+TclArgumentBCEnter(
+    Tcl_Interp *interp,
+    Tcl_Obj *objv[],
+    int objc,
+    void *codePtr,
+    CmdFrame *cfPtr,
+    int cmd,
+    int pc)
+{
+    ExtCmdLoc *eclPtr;
+    int word;
+    ECL *ePtr;
+    CFWordBC *lastPtr = NULL;
+    Interp *iPtr = (Interp *) interp;
+    Tcl_HashEntry *hePtr =
+	    Tcl_FindHashEntry(iPtr->lineBCPtr, (char *) codePtr);
+
+    if (!hePtr) {
+	return;
+    }
+    eclPtr = Tcl_GetHashValue(hePtr);
+    ePtr = &eclPtr->loc[cmd];
+
+    /*
+     * ePtr->nline is the number of words originally parsed.
+     *
+     * objc is the number of elements getting invoked.
+     *
+     * If they are not the same, we arrived here by compiling an
+     * ensemble dispatch.  Ensemble subcommands that lead to script
+     * evaluation are not supposed to get compiled, because a command
+     * such as [info level] in the script can expose some of the dispatch
+     * shenanigans.  This means that we don't have to tend to the
+     * housekeeping, and can escape now.
+     */
+
+    if (ePtr->nline != objc) {
+        return;
+    }
+
+    /*
+     * Having disposed of the ensemble cases, we can state...
+     * A few truths ...
+     * (1) ePtr->nline == objc
+     * (2) (ePtr->line[word] < 0) => !literal, for all words
+     * (3) (word == 0) => !literal
+     *
+     * Item (2) is why we can use objv to get the literals, and do not
+     * have to save them at compile time.
+     */
+
+    for (word = 1; word < objc; word++) {
+	if (ePtr->line[word] >= 0) {
+	    int isnew;
+	    Tcl_HashEntry *hPtr = Tcl_CreateHashEntry(iPtr->lineLABCPtr,
+		objv[word], &isnew);
+	    CFWordBC *cfwPtr = ckalloc(sizeof(CFWordBC));
+
+	    cfwPtr->framePtr = cfPtr;
+	    cfwPtr->obj = objv[word];
+	    cfwPtr->pc = pc;
+	    cfwPtr->word = word;
+	    cfwPtr->nextPtr = lastPtr;
+	    lastPtr = cfwPtr;
+
+	    if (isnew) {
+		/*
+		 * The word is not on the stack yet, remember the current
+		 * location and initialize references.
+		 */
+
+		cfwPtr->prevPtr = NULL;
+	    } else {
+		/*
+		 * The object is already on the stack, however it may have
+		 * a different location now (literal sharing may map
+		 * multiple location to a single Tcl_Obj*. Save the old
+		 * information in the new structure.
+		 */
+
+		cfwPtr->prevPtr = Tcl_GetHashValue(hPtr);
+	    }
+
+	    Tcl_SetHashValue(hPtr, cfwPtr);
+	}
+    } /* for */
+
+    cfPtr->litarg = lastPtr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclArgumentBCRelease --
+ *
+ *	This procedure is a helper for the TIP #280 uplevel extension. It
+ *	removes the location references for the literal arguments of commands
+ *	in bytecode just done. Usage is counted down, the data is removed only
+ *	when no user is left over.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	May release memory.
+ *
+ * TIP #280
+ *----------------------------------------------------------------------
+ */
+
+void
+TclArgumentBCRelease(
+    Tcl_Interp *interp,
+    CmdFrame *cfPtr)
+{
+    Interp *iPtr = (Interp *) interp;
+    CFWordBC *cfwPtr = (CFWordBC *) cfPtr->litarg;
+
+    while (cfwPtr) {
+	CFWordBC *nextPtr = cfwPtr->nextPtr;
+	Tcl_HashEntry *hPtr =
+		Tcl_FindHashEntry(iPtr->lineLABCPtr, (char *) cfwPtr->obj);
+	CFWordBC *xPtr = Tcl_GetHashValue(hPtr);
+
+	if (xPtr != cfwPtr) {
+	    Tcl_Panic("TclArgumentBC Enter/Release Mismatch");
+	}
+
+	if (cfwPtr->prevPtr) {
+	    Tcl_SetHashValue(hPtr, cfwPtr->prevPtr);
+	} else {
+	    Tcl_DeleteHashEntry(hPtr);
+	}
+
+	ckfree(cfwPtr);
+	cfwPtr = nextPtr;
+    }
+
+    cfPtr->litarg = NULL;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclArgumentGet --
+ *
+ *	This procedure is a helper for the TIP #280 uplevel extension. It
+ *	finds the location references for a Tcl_Obj, if any.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Writes found location information into the result arguments.
+ *
+ * TIP #280
+ *----------------------------------------------------------------------
+ */
+
+void
+TclArgumentGet(
+    Tcl_Interp *interp,
+    Tcl_Obj *obj,
+    CmdFrame **cfPtrPtr,
+    int *wordPtr)
+{
+    Interp *iPtr = (Interp *) interp;
+    Tcl_HashEntry *hPtr;
+    CmdFrame *framePtr;
+
+    /*
+     * An object which either has no string rep or else is a canonical list is
+     * guaranteed to have been generated dynamically: bail out, this cannot
+     * have a usable absolute location. _Do not touch_ the information the set
+     * up by the caller. It knows better than us.
+     */
+
+    if ((obj->bytes == NULL) || TclListObjIsCanonical(obj)) {
+	return;
+    }
+
+    /*
+     * First look for location information recorded in the argument
+     * stack. That is nearest.
+     */
+
+    hPtr = Tcl_FindHashEntry(iPtr->lineLAPtr, (char *) obj);
+    if (hPtr) {
+	CFWord *cfwPtr = Tcl_GetHashValue(hPtr);
+
+	*wordPtr = cfwPtr->word;
+	*cfPtrPtr = cfwPtr->framePtr;
+	return;
+    }
+
+    /*
+     * Check if the Tcl_Obj has location information as a bytecode literal, in
+     * that stack.
+     */
+
+    hPtr = Tcl_FindHashEntry(iPtr->lineLABCPtr, (char *) obj);
+    if (hPtr) {
+	CFWordBC *cfwPtr = Tcl_GetHashValue(hPtr);
+
+	framePtr = cfwPtr->framePtr;
+	framePtr->data.tebc.pc = (char *) (((ByteCode *)
+		framePtr->data.tebc.codePtr)->codeStart + cfwPtr->pc);
+	*cfPtrPtr = cfwPtr->framePtr;
+	*wordPtr = cfwPtr->word;
+	return;
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_Eval --
+ *
+ *	Execute a Tcl command in a string. This function executes the script
+ *	directly, rather than compiling it to bytecodes. Before the arrival of
+ *	the bytecode compiler in Tcl 8.0 Tcl_Eval was the main function used
+ *	for executing Tcl commands, but nowadays it isn't used much.
+ *
+ * Results:
+ *	The return value is one of the return codes defined in tcl.h (such as
+ *	TCL_OK), and interp's result contains a value to supplement the return
+ *	code. The value of the result will persist only until the next call to
+ *	Tcl_Eval or Tcl_EvalObj: you must copy it or lose it!
+ *
+ * Side effects:
+ *	Can be almost arbitrary, depending on the commands in the script.
+ *
+ *----------------------------------------------------------------------
+ */
+
+#undef Tcl_Eval
+int
+Tcl_Eval(
+    Tcl_Interp *interp,		/* Token for command interpreter (returned by
+				 * previous call to Tcl_CreateInterp). */
+    const char *script)		/* Pointer to TCL command to execute. */
+{
+    int code = Tcl_EvalEx(interp, script, -1, 0);
+
+    /*
+     * For backwards compatibility with old C code that predates the object
+     * system in Tcl 8.0, we have to mirror the object result back into the
+     * string result (some callers may expect it there).
+     */
+
+    (void) Tcl_GetStringResult(interp);
+    return code;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_EvalObj, Tcl_GlobalEvalObj --
+ *
+ *	These functions are deprecated but we keep them around for backwards
+ *	compatibility reasons.
+ *
+ * Results:
+ *	See the functions they call.
+ *
+ * Side effects:
+ *	See the functions they call.
+ *
+ *----------------------------------------------------------------------
+ */
+
+#undef Tcl_EvalObj
+int
+Tcl_EvalObj(
+    Tcl_Interp *interp,
+    Tcl_Obj *objPtr)
+{
+    return Tcl_EvalObjEx(interp, objPtr, 0);
+}
+#undef Tcl_GlobalEvalObj
+int
+Tcl_GlobalEvalObj(
+    Tcl_Interp *interp,
+    Tcl_Obj *objPtr)
+{
+    return Tcl_EvalObjEx(interp, objPtr, TCL_EVAL_GLOBAL);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_EvalObjEx, TclEvalObjEx --
+ *
+ *	Execute Tcl commands stored in a Tcl object. These commands are
+ *	compiled into bytecodes if necessary, unless TCL_EVAL_DIRECT is
+ *	specified.
+ *
+ *	If the flag TCL_EVAL_DIRECT is passed in, the value of invoker
+ *	must be NULL.  Support for non-NULL invokers in that mode has
+ *	been removed since it was unused and untested.  Failure to
+ *	follow this limitation will lead to an assertion panic.
+ *
+ * Results:
+ *	The return value is one of the return codes defined in tcl.h (such as
+ *	TCL_OK), and the interpreter's result contains a value to supplement
+ *	the return code.
+ *
+ * Side effects:
+ *	The object is converted, if necessary, to a ByteCode object that holds
+ *	the bytecode instructions for the commands. Executing the commands
+ *	will almost certainly have side effects that depend on those commands.
+ *
+ * TIP #280 : Keep public API, internally extended API.
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_EvalObjEx(
+    Tcl_Interp *interp,		/* Token for command interpreter (returned by
+				 * a previous call to Tcl_CreateInterp). */
+    register Tcl_Obj *objPtr,	/* Pointer to object containing commands to
+				 * execute. */
+    int flags)			/* Collection of OR-ed bits that control the
+				 * evaluation of the script. Supported values
+				 * are TCL_EVAL_GLOBAL and TCL_EVAL_DIRECT. */
+{
+    return TclEvalObjEx(interp, objPtr, flags, NULL, 0);
+}
+
+int
+TclEvalObjEx(
+    Tcl_Interp *interp,		/* Token for command interpreter (returned by
+				 * a previous call to Tcl_CreateInterp). */
+    register Tcl_Obj *objPtr,	/* Pointer to object containing commands to
+				 * execute. */
+    int flags,			/* Collection of OR-ed bits that control the
+				 * evaluation of the script. Supported values
+				 * are TCL_EVAL_GLOBAL and TCL_EVAL_DIRECT. */
+    const CmdFrame *invoker,	/* Frame of the command doing the eval. */
+    int word)			/* Index of the word which is in objPtr. */
+{
+    int result = TCL_OK;
+    NRE_callback *rootPtr = TOP_CB(interp);
+
+    result = TclNREvalObjEx(interp, objPtr, flags, invoker, word);
+    return TclNRRunCallbacks(interp, result, rootPtr);
+}
+
+int
+TclNREvalObjEx(
+    Tcl_Interp *interp,		/* Token for command interpreter (returned by
+				 * a previous call to Tcl_CreateInterp). */
+    register Tcl_Obj *objPtr,	/* Pointer to object containing commands to
+				 * execute. */
+    int flags,			/* Collection of OR-ed bits that control the
+				 * evaluation of the script. Supported values
+				 * are TCL_EVAL_GLOBAL and TCL_EVAL_DIRECT. */
+    const CmdFrame *invoker,	/* Frame of the command doing the eval. */
+    int word)			/* Index of the word which is in objPtr. */
+{
+    Interp *iPtr = (Interp *) interp;
+    int result;
+
+    /*
+     * This function consists of three independent blocks for: direct
+     * evaluation of canonical lists, compilation and bytecode execution and
+     * finally direct evaluation. Precisely one of these blocks will be run.
+     */
+
+    if (TclListObjIsCanonical(objPtr)) {
+	CmdFrame *eoFramePtr = NULL;
+	int objc;
+	Tcl_Obj *listPtr, **objv;
+
+	/*
+	 * Canonical List Optimization:  In this case, we
+	 * can safely use Tcl_EvalObjv instead and get an appreciable
+	 * improvement in execution speed. This is because it allows us to
+	 * avoid a setFromAny step that would just pack everything into a
+	 * string and back out again.
+	 *
+	 * This also preserves any associations between list elements and
+	 * location information for such elements.
+	 */
+
+	/*
+	 * Shimmer protection! Always pass an unshared obj. The caller could
+	 * incr the refCount of objPtr AFTER calling us! To be completely safe
+	 * we always make a copy. The callback takes care od the refCounts for
+	 * both listPtr and objPtr.
+	 *
+	 * TODO: Create a test to demo this need, or eliminate it.
+	 * FIXME OPT: preserve just the internal rep?
+	 */
+
+	Tcl_IncrRefCount(objPtr);
+	listPtr = TclListObjCopy(interp, objPtr);
+	Tcl_IncrRefCount(listPtr);
+
+	if (word != INT_MIN) {
+	    /*
+	     * TIP #280 Structures for tracking lines. As we know that this is
+	     * dynamic execution we ignore the invoker, even if known.
+	     *
+	     * TIP #280. We do _not_ compute all the line numbers for the
+	     * words in the command. For the eval of a pure list the most
+	     * sensible choice is to put all words on line 1. Given that we
+	     * neither need memory for them nor compute anything. 'line' is
+	     * left NULL. The two places using this information (TclInfoFrame,
+	     * and TclInitCompileEnv), are special-cased to use the proper
+	     * line number directly instead of accessing the 'line' array.
+	     *
+	     * Note that we use (word==INTMIN) to signal that no command frame
+	     * should be pushed, as needed by alias and ensemble redirections.
+	     */
+
+	    eoFramePtr = TclStackAlloc(interp, sizeof(CmdFrame));
+	    eoFramePtr->nline = 0;
+	    eoFramePtr->line = NULL;
+
+	    eoFramePtr->type = TCL_LOCATION_EVAL;
+	    eoFramePtr->level = (iPtr->cmdFramePtr == NULL?
+		    1 : iPtr->cmdFramePtr->level + 1);
+	    eoFramePtr->framePtr = iPtr->framePtr;
+	    eoFramePtr->nextPtr = iPtr->cmdFramePtr;
+
+	    eoFramePtr->cmdObj = objPtr;
+	    eoFramePtr->cmd = NULL;
+	    eoFramePtr->len = 0;
+	    eoFramePtr->data.eval.path = NULL;
+
+	    iPtr->cmdFramePtr = eoFramePtr;
+
+	    flags |= TCL_EVAL_SOURCE_IN_FRAME;
+	}
+
+	TclMarkTailcall(interp);
+        TclNRAddCallback(interp, TEOEx_ListCallback, listPtr, eoFramePtr,
+		objPtr, NULL);
+
+	ListObjGetElements(listPtr, objc, objv);
+	return TclNREvalObjv(interp, objc, objv, flags, NULL);
+    }
+
+    if (!(flags & TCL_EVAL_DIRECT)) {
+	/*
+	 * Let the compiler/engine subsystem do the evaluation.
+	 *
+	 * TIP #280 The invoker provides us with the context for the script.
+	 * We transfer this to the byte code compiler.
+	 */
+
+	int allowExceptions = (iPtr->evalFlags & TCL_ALLOW_EXCEPTIONS);
+	ByteCode *codePtr;
+	CallFrame *savedVarFramePtr = NULL;	/* Saves old copy of
+						 * iPtr->varFramePtr in case
+						 * TCL_EVAL_GLOBAL was set. */
+
+        if (TclInterpReady(interp) != TCL_OK) {
+            return TCL_ERROR;
+        }
+	if (flags & TCL_EVAL_GLOBAL) {
+	    savedVarFramePtr = iPtr->varFramePtr;
+	    iPtr->varFramePtr = iPtr->rootFramePtr;
+	}
+	Tcl_IncrRefCount(objPtr);
+	codePtr = TclCompileObj(interp, objPtr, invoker, word);
+
+	TclNRAddCallback(interp, TEOEx_ByteCodeCallback, savedVarFramePtr,
+		objPtr, INT2PTR(allowExceptions), NULL);
+        return TclNRExecuteByteCode(interp, codePtr);
+    }
+
+    {
+	/*
+	 * We're not supposed to use the compiler or byte-code
+	 * interpreter. Let Tcl_EvalEx evaluate the command directly (and
+	 * probably more slowly).
+	 */
+
+	const char *script;
+	int numSrcBytes;
+
+	/*
+	 * Now we check if we have data about invisible continuation lines for
+	 * the script, and make it available to the direct script parser and
+	 * evaluator we are about to call, if so.
+	 *
+	 * It may be possible that the script Tcl_Obj* can be free'd while the
+	 * evaluator is using it, leading to the release of the associated
+	 * ContLineLoc structure as well. To ensure that the latter doesn't
+	 * happen we set a lock on it. We release this lock later in this
+	 * function, after the evaluator is done. The relevant "lineCLPtr"
+	 * hashtable is managed in the file "tclObj.c".
+	 *
+	 * Another important action is to save (and later restore) the
+	 * continuation line information of the caller, in case we are
+	 * executing nested commands in the eval/direct path.
+	 */
+
+	ContLineLoc *saveCLLocPtr = iPtr->scriptCLLocPtr;
+
+	assert(invoker == NULL);
+
+	iPtr->scriptCLLocPtr = TclContinuationsGet(objPtr);
+
+	Tcl_IncrRefCount(objPtr);
+
+	script = Tcl_GetStringFromObj(objPtr, &numSrcBytes);
+	result = Tcl_EvalEx(interp, script, numSrcBytes, flags);
+
+	TclDecrRefCount(objPtr);
+
+	iPtr->scriptCLLocPtr = saveCLLocPtr;
+	return result;
+    }
+}
+
+static int
+TEOEx_ByteCodeCallback(
+    ClientData data[],
+    Tcl_Interp *interp,
+    int result)
+{
+    Interp *iPtr = (Interp *) interp;
+    CallFrame *savedVarFramePtr = data[0];
+    Tcl_Obj *objPtr = data[1];
+    int allowExceptions = PTR2INT(data[2]);
+
+    if (iPtr->numLevels == 0) {
+	if (result == TCL_RETURN) {
+	    result = TclUpdateReturnInfo(iPtr);
+	}
+	if ((result != TCL_OK) && (result != TCL_ERROR) && !allowExceptions) {
+	    const char *script;
+	    int numSrcBytes;
+
+	    ProcessUnexpectedResult(interp, result);
+	    result = TCL_ERROR;
+	    script = Tcl_GetStringFromObj(objPtr, &numSrcBytes);
+	    Tcl_LogCommandInfo(interp, script, script, numSrcBytes);
+	}
+
+	/*
+	 * We are returning to level 0, so should call TclResetCancellation.
+	 * Let us just unset the flags inline.
+	 */
+
+	TclUnsetCancelFlags(iPtr);
+    }
+    iPtr->evalFlags = 0;
+
+    /*
+     * Restore the callFrame if this was a TCL_EVAL_GLOBAL.
+     */
+
+    if (savedVarFramePtr) {
+	iPtr->varFramePtr = savedVarFramePtr;
+    }
+
+    TclDecrRefCount(objPtr);
+    return result;
+}
+
+static int
+TEOEx_ListCallback(
+    ClientData data[],
+    Tcl_Interp *interp,
+    int result)
+{
+    Interp *iPtr = (Interp *) interp;
+    Tcl_Obj *listPtr = data[0];
+    CmdFrame *eoFramePtr = data[1];
+    Tcl_Obj *objPtr = data[2];
+
+    /*
+     * Remove the cmdFrame
+     */
+
+    if (eoFramePtr) {
+	iPtr->cmdFramePtr = eoFramePtr->nextPtr;
+	TclStackFree(interp, eoFramePtr);
+    }
+    TclDecrRefCount(objPtr);
+    TclDecrRefCount(listPtr);
+
+    return result;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ProcessUnexpectedResult --
+ *
+ *	Function called by Tcl_EvalObj to set the interpreter's result value
+ *	to an appropriate error message when the code it evaluates returns an
+ *	unexpected result code (not TCL_OK and not TCL_ERROR) to the topmost
+ *	evaluation level.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The interpreter result is set to an error message appropriate to the
+ *	result code.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+ProcessUnexpectedResult(
+    Tcl_Interp *interp,		/* The interpreter in which the unexpected
+				 * result code was returned. */
+    int returnCode)		/* The unexpected result code. */
+{
+    char buf[TCL_INTEGER_SPACE];
+
+    Tcl_ResetResult(interp);
+    if (returnCode == TCL_BREAK) {
+	Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		"invoked \"break\" outside of a loop", -1));
+    } else if (returnCode == TCL_CONTINUE) {
+	Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		"invoked \"continue\" outside of a loop", -1));
+    } else {
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		"command returned bad code: %d", returnCode));
+    }
+    sprintf(buf, "%d", returnCode);
+    Tcl_SetErrorCode(interp, "TCL", "UNEXPECTED_RESULT_CODE", buf, NULL);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Tcl_ExprLong, Tcl_ExprDouble, Tcl_ExprBoolean --
+ *
+ *	Functions to evaluate an expression and return its value in a
+ *	particular form.
+ *
+ * Results:
+ *	Each of the functions below returns a standard Tcl result. If an error
+ *	occurs then an error message is left in the interp's result. Otherwise
+ *	the value of the expression, in the appropriate form, is stored at
+ *	*ptr. If the expression had a result that was incompatible with the
+ *	desired form then an error is returned.
+ *
+ * Side effects:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+int
+Tcl_ExprLong(
+    Tcl_Interp *interp,		/* Context in which to evaluate the
+				 * expression. */
+    const char *exprstring,	/* Expression to evaluate. */
+    long *ptr)			/* Where to store result. */
+{
+    register Tcl_Obj *exprPtr;
+    int result = TCL_OK;
+    if (*exprstring == '\0') {
+	/*
+	 * Legacy compatibility - return 0 for the zero-length string.
+	 */
+
+	*ptr = 0;
+    } else {
+	exprPtr = Tcl_NewStringObj(exprstring, -1);
+	Tcl_IncrRefCount(exprPtr);
+	result = Tcl_ExprLongObj(interp, exprPtr, ptr);
+	Tcl_DecrRefCount(exprPtr);
+	if (result != TCL_OK) {
+	    (void) Tcl_GetStringResult(interp);
+	}
+    }
+    return result;
+}
+
+int
+Tcl_ExprDouble(
+    Tcl_Interp *interp,		/* Context in which to evaluate the
+				 * expression. */
+    const char *exprstring,	/* Expression to evaluate. */
+    double *ptr)		/* Where to store result. */
+{
+    register Tcl_Obj *exprPtr;
+    int result = TCL_OK;
+
+    if (*exprstring == '\0') {
+	/*
+	 * Legacy compatibility - return 0 for the zero-length string.
+	 */
+
+	*ptr = 0.0;
+    } else {
+	exprPtr = Tcl_NewStringObj(exprstring, -1);
+	Tcl_IncrRefCount(exprPtr);
+	result = Tcl_ExprDoubleObj(interp, exprPtr, ptr);
+	Tcl_DecrRefCount(exprPtr);
+				/* Discard the expression object. */
+	if (result != TCL_OK) {
+	    (void) Tcl_GetStringResult(interp);
+	}
+    }
+    return result;
+}
+
+int
+Tcl_ExprBoolean(
+    Tcl_Interp *interp,		/* Context in which to evaluate the
+				 * expression. */
+    const char *exprstring,	/* Expression to evaluate. */
+    int *ptr)			/* Where to store 0/1 result. */
+{
+    if (*exprstring == '\0') {
+	/*
+	 * An empty string. Just set the result boolean to 0 (false).
+	 */
+
+	*ptr = 0;
+	return TCL_OK;
+    } else {
+	int result;
+	Tcl_Obj *exprPtr = Tcl_NewStringObj(exprstring, -1);
+
+	Tcl_IncrRefCount(exprPtr);
+	result = Tcl_ExprBooleanObj(interp, exprPtr, ptr);
+	Tcl_DecrRefCount(exprPtr);
+	if (result != TCL_OK) {
+	    /*
+	     * Move the interpreter's object result to the string result, then
+	     * reset the object result.
+	     */
+
+	    (void) Tcl_GetStringResult(interp);
+	}
+	return result;
+    }
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * Tcl_ExprLongObj, Tcl_ExprDoubleObj, Tcl_ExprBooleanObj --
+ *
+ *	Functions to evaluate an expression in an object and return its value
+ *	in a particular form.
+ *
+ * Results:
+ *	Each of the functions below returns a standard Tcl result object. If
+ *	an error occurs then an error message is left in the interpreter's
+ *	result. Otherwise the value of the expression, in the appropriate
+ *	form, is stored at *ptr. If the expression had a result that was
+ *	incompatible with the desired form then an error is returned.
+ *
+ * Side effects:
+ *	None.
+ *
+ *--------------------------------------------------------------
+ */
+
+int
+Tcl_ExprLongObj(
+    Tcl_Interp *interp,		/* Context in which to evaluate the
+				 * expression. */
+    register Tcl_Obj *objPtr,	/* Expression to evaluate. */
+    long *ptr)			/* Where to store long result. */
+{
+    Tcl_Obj *resultPtr;
+    int result, type;
+    double d;
+    ClientData internalPtr;
+
+    result = Tcl_ExprObj(interp, objPtr, &resultPtr);
+    if (result != TCL_OK) {
+	return TCL_ERROR;
+    }
+
+    if (TclGetNumberFromObj(interp, resultPtr, &internalPtr, &type)!=TCL_OK) {
+	return TCL_ERROR;
+    }
+
+    switch (type) {
+    case TCL_NUMBER_DOUBLE: {
+	mp_int big;
+
+	d = *((const double *) internalPtr);
+	Tcl_DecrRefCount(resultPtr);
+	if (Tcl_InitBignumFromDouble(interp, d, &big) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	resultPtr = Tcl_NewBignumObj(&big);
+	/* FALLTHROUGH */
+    }
+    case TCL_NUMBER_LONG:
+    case TCL_NUMBER_WIDE:
+    case TCL_NUMBER_BIG:
+	result = TclGetLongFromObj(interp, resultPtr, ptr);
+	break;
+
+    case TCL_NUMBER_NAN:
+	Tcl_GetDoubleFromObj(interp, resultPtr, &d);
+	result = TCL_ERROR;
+    }
+
+    Tcl_DecrRefCount(resultPtr);/* Discard the result object. */
+    return result;
+}
+
+int
+Tcl_ExprDoubleObj(
+    Tcl_Interp *interp,		/* Context in which to evaluate the
+				 * expression. */
+    register Tcl_Obj *objPtr,	/* Expression to evaluate. */
+    double *ptr)		/* Where to store double result. */
+{
+    Tcl_Obj *resultPtr;
+    int result, type;
+    ClientData internalPtr;
+
+    result = Tcl_ExprObj(interp, objPtr, &resultPtr);
+    if (result != TCL_OK) {
+	return TCL_ERROR;
+    }
+
+    result = TclGetNumberFromObj(interp, resultPtr, &internalPtr, &type);
+    if (result == TCL_OK) {
+	switch (type) {
+	case TCL_NUMBER_NAN:
+#ifndef ACCEPT_NAN
+	    result = Tcl_GetDoubleFromObj(interp, resultPtr, ptr);
+	    break;
+#endif
+	case TCL_NUMBER_DOUBLE:
+	    *ptr = *((const double *) internalPtr);
+	    result = TCL_OK;
+	    break;
+	default:
+	    result = Tcl_GetDoubleFromObj(interp, resultPtr, ptr);
+	}
+    }
+    Tcl_DecrRefCount(resultPtr);/* Discard the result object. */
+    return result;
+}
+
+int
+Tcl_ExprBooleanObj(
+    Tcl_Interp *interp,		/* Context in which to evaluate the
+				 * expression. */
+    register Tcl_Obj *objPtr,	/* Expression to evaluate. */
+    int *ptr)			/* Where to store 0/1 result. */
+{
+    Tcl_Obj *resultPtr;
+    int result;
+
+    result = Tcl_ExprObj(interp, objPtr, &resultPtr);
+    if (result == TCL_OK) {
+	result = Tcl_GetBooleanFromObj(interp, resultPtr, ptr);
+	Tcl_DecrRefCount(resultPtr);
+				/* Discard the result object. */
+    }
+    return result;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclObjInvokeNamespace --
+ *
+ *	Object version: Invokes a Tcl command, given an objv/objc, from either
+ *	the exposed or hidden set of commands in the given interpreter.
+ *
+ *	NOTE: The command is invoked in the global stack frame of the
+ *	interpreter or namespace, thus it cannot see any current state on the
+ *	stack of that interpreter.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	Whatever the command does.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclObjInvokeNamespace(
+    Tcl_Interp *interp,		/* Interpreter in which command is to be
+				 * invoked. */
+    int objc,			/* Count of arguments. */
+    Tcl_Obj *const objv[],	/* Argument objects; objv[0] points to the
+				 * name of the command to invoke. */
+    Tcl_Namespace *nsPtr,	/* The namespace to use. */
+    int flags)			/* Combination of flags controlling the call:
+				 * TCL_INVOKE_HIDDEN, TCL_INVOKE_NO_UNKNOWN,
+				 * or TCL_INVOKE_NO_TRACEBACK. */
+{
+    int result;
+    Tcl_CallFrame *framePtr;
+
+    /*
+     * Make the specified namespace the current namespace and invoke the
+     * command.
+     */
+
+    (void) TclPushStackFrame(interp, &framePtr, nsPtr, /*isProcFrame*/0);
+    result = TclObjInvoke(interp, objc, objv, flags);
+
+    TclPopStackFrame(interp);
+    return result;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclObjInvoke --
+ *
+ *	Invokes a Tcl command, given an objv/objc, from either the exposed or
+ *	the hidden sets of commands in the given interpreter.
+ *
+ * Results:
+ *	A standard Tcl object result.
+ *
+ * Side effects:
+ *	Whatever the command does.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclObjInvoke(
+    Tcl_Interp *interp,		/* Interpreter in which command is to be
+				 * invoked. */
+    int objc,			/* Count of arguments. */
+    Tcl_Obj *const objv[],	/* Argument objects; objv[0] points to the
+				 * name of the command to invoke. */
+    int flags)			/* Combination of flags controlling the call:
+				 * TCL_INVOKE_HIDDEN, TCL_INVOKE_NO_UNKNOWN,
+				 * or TCL_INVOKE_NO_TRACEBACK. */
+{
+    if (interp == NULL) {
+	return TCL_ERROR;
+    }
+    if ((objc < 1) || (objv == NULL)) {
+	Tcl_SetObjResult(interp, Tcl_NewStringObj(
+                "illegal argument vector", -1));
+	return TCL_ERROR;
+    }
+    if ((flags & TCL_INVOKE_HIDDEN) == 0) {
+	Tcl_Panic("TclObjInvoke: called without TCL_INVOKE_HIDDEN");
+    }
+    return Tcl_NRCallObjProc(interp, TclNRInvoke, NULL, objc, objv);
+}
+
+int
+TclNRInvoke(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const objv[])
+{
+    register Interp *iPtr = (Interp *) interp;
+    Tcl_HashTable *hTblPtr;	/* Table of hidden commands. */
+    const char *cmdName;	/* Name of the command from objv[0]. */
+    Tcl_HashEntry *hPtr = NULL;
+    Command *cmdPtr;
+
+    cmdName = TclGetString(objv[0]);
+    hTblPtr = iPtr->hiddenCmdTablePtr;
+    if (hTblPtr != NULL) {
+	hPtr = Tcl_FindHashEntry(hTblPtr, cmdName);
+    }
+    if (hPtr == NULL) {
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+                "invalid hidden command name \"%s\"", cmdName));
+        Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "HIDDENTOKEN", cmdName,
+                NULL);
+	return TCL_ERROR;
+    }
+    cmdPtr = Tcl_GetHashValue(hPtr);
+
+    /* Avoid the exception-handling brain damage when numLevels == 0 . */
+    iPtr->numLevels++;
+    Tcl_NRAddCallback(interp, NRPostInvoke, NULL, NULL, NULL, NULL);
+
+    /*
+     * Normal command resolution of objv[0] isn't going to find cmdPtr.
+     * That's the whole point of **hidden** commands.  So tell the
+     * Eval core machinery not to even try (and risk finding something wrong).
+     */
+
+    return TclNREvalObjv(interp, objc, objv, TCL_EVAL_NORESOLVE, cmdPtr);
+}
+
+static int
+NRPostInvoke(
+    ClientData clientData[],
+    Tcl_Interp *interp,
+    int result)
+{
+    Interp *iPtr = (Interp *)interp;
+    iPtr->numLevels--;
+    return result;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Tcl_ExprString --
+ *
+ *	Evaluate an expression in a string and return its value in string
+ *	form.
+ *
+ * Results:
+ *	A standard Tcl result. If the result is TCL_OK, then the interp's
+ *	result is set to the string value of the expression. If the result is
+ *	TCL_ERROR, then the interp's result contains an error message.
+ *
+ * Side effects:
+ *	A Tcl object is allocated to hold a copy of the expression string.
+ *	This expression object is passed to Tcl_ExprObj and then deallocated.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+int
+Tcl_ExprString(
+    Tcl_Interp *interp,		/* Context in which to evaluate the
+				 * expression. */
+    const char *expr)		/* Expression to evaluate. */
+{
+    int code = TCL_OK;
+
+    if (expr[0] == '\0') {
+	/*
+	 * An empty string. Just set the interpreter's result to 0.
+	 */
+
+	Tcl_SetObjResult(interp, Tcl_NewIntObj(0));
+    } else {
+	Tcl_Obj *resultPtr, *exprObj = Tcl_NewStringObj(expr, -1);
+
+	Tcl_IncrRefCount(exprObj);
+	code = Tcl_ExprObj(interp, exprObj, &resultPtr);
+	Tcl_DecrRefCount(exprObj);
+	if (code == TCL_OK) {
+	    Tcl_SetObjResult(interp, resultPtr);
+	    Tcl_DecrRefCount(resultPtr);
+	}
+    }
+
+    /*
+     * Force the string rep of the interp result.
+     */
+
+    (void) Tcl_GetStringResult(interp);
+    return code;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_AppendObjToErrorInfo --
+ *
+ *	Add a Tcl_Obj value to the errorInfo field that describes the current
+ *	error.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The value of the Tcl_obj is appended to the errorInfo field. If we are
+ *	just starting to log an error, errorInfo is initialized from the error
+ *	message in the interpreter's result.
+ *
+ *----------------------------------------------------------------------
+ */
+
+#undef Tcl_AddObjErrorInfo
+void
+Tcl_AppendObjToErrorInfo(
+    Tcl_Interp *interp,		/* Interpreter to which error information
+				 * pertains. */
+    Tcl_Obj *objPtr)		/* Message to record. */
+{
+    int length;
+    const char *message = TclGetStringFromObj(objPtr, &length);
+
+    Tcl_IncrRefCount(objPtr);
+    Tcl_AddObjErrorInfo(interp, message, length);
+    Tcl_DecrRefCount(objPtr);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_AddErrorInfo --
+ *
+ *	Add information to the errorInfo field that describes the current
+ *	error.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The contents of message are appended to the errorInfo field. If we are
+ *	just starting to log an error, errorInfo is initialized from the error
+ *	message in the interpreter's result.
+ *
+ *----------------------------------------------------------------------
+ */
+
+#undef Tcl_AddErrorInfo
+void
+Tcl_AddErrorInfo(
+    Tcl_Interp *interp,		/* Interpreter to which error information
+				 * pertains. */
+    const char *message)	/* Message to record. */
+{
+    Tcl_AddObjErrorInfo(interp, message, -1);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_AddObjErrorInfo --
+ *
+ *	Add information to the errorInfo field that describes the current
+ *	error. This routine differs from Tcl_AddErrorInfo by taking a byte
+ *	pointer and length.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	"length" bytes from "message" are appended to the errorInfo field. If
+ *	"length" is negative, use bytes up to the first NULL byte. If we are
+ *	just starting to log an error, errorInfo is initialized from the error
+ *	message in the interpreter's result.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_AddObjErrorInfo(
+    Tcl_Interp *interp,		/* Interpreter to which error information
+				 * pertains. */
+    const char *message,	/* Points to the first byte of an array of
+				 * bytes of the message. */
+    int length)			/* The number of bytes in the message. If < 0,
+				 * then append all bytes up to a NULL byte. */
+{
+    register Interp *iPtr = (Interp *) interp;
+
+    /*
+     * If we are just starting to log an error, errorInfo is initialized from
+     * the error message in the interpreter's result.
+     */
+
+    iPtr->flags |= ERR_LEGACY_COPY;
+    if (iPtr->errorInfo == NULL) {
+	if (iPtr->result[0] != 0) {
+	    /*
+	     * The interp's string result is set, apparently by some extension
+	     * making a deprecated direct write to it. That extension may
+	     * expect interp->result to continue to be set, so we'll take
+	     * special pains to avoid clearing it, until we drop support for
+	     * interp->result completely.
+	     */
+
+	    iPtr->errorInfo = Tcl_NewStringObj(iPtr->result, -1);
+	} else {
+	    iPtr->errorInfo = iPtr->objResultPtr;
+	}
+	Tcl_IncrRefCount(iPtr->errorInfo);
+	if (!iPtr->errorCode) {
+	    Tcl_SetErrorCode(interp, "NONE", NULL);
+	}
+    }
+
+    /*
+     * Now append "message" to the end of errorInfo.
+     */
+
+    if (length != 0) {
+	if (Tcl_IsShared(iPtr->errorInfo)) {
+	    Tcl_DecrRefCount(iPtr->errorInfo);
+	    iPtr->errorInfo = Tcl_DuplicateObj(iPtr->errorInfo);
+	    Tcl_IncrRefCount(iPtr->errorInfo);
+	}
+	Tcl_AppendToObj(iPtr->errorInfo, message, length);
+    }
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Tcl_VarEvalVA --
+ *
+ *	Given a variable number of string arguments, concatenate them all
+ *	together and execute the result as a Tcl command.
+ *
+ * Results:
+ *	A standard Tcl return result. An error message or other result may be
+ *	left in the interp's result.
+ *
+ * Side effects:
+ *	Depends on what was done by the command.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+int
+Tcl_VarEvalVA(
+    Tcl_Interp *interp,		/* Interpreter in which to evaluate command */
+    va_list argList)		/* Variable argument list. */
+{
+    Tcl_DString buf;
+    char *string;
+    int result;
+
+    /*
+     * Copy the strings one after the other into a single larger string. Use
+     * stack-allocated space for small commands, but if the command gets too
+     * large than call ckalloc to create the space.
+     */
+
+    Tcl_DStringInit(&buf);
+    while (1) {
+	string = va_arg(argList, char *);
+	if (string == NULL) {
+	    break;
+	}
+	Tcl_DStringAppend(&buf, string, -1);
+    }
+
+    result = Tcl_Eval(interp, Tcl_DStringValue(&buf));
+    Tcl_DStringFree(&buf);
+    return result;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_VarEval --
+ *
+ *	Given a variable number of string arguments, concatenate them all
+ *	together and execute the result as a Tcl command.
+ *
+ * Results:
+ *	A standard Tcl return result. An error message or other result may be
+ *	left in interp->result.
+ *
+ * Side effects:
+ *	Depends on what was done by the command.
+ *
+ *----------------------------------------------------------------------
+ */
+	/* ARGSUSED */
+int
+Tcl_VarEval(
+    Tcl_Interp *interp,
+    ...)
+{
+    va_list argList;
+    int result;
+
+    va_start(argList, interp);
+    result = Tcl_VarEvalVA(interp, argList);
+    va_end(argList);
+
+    return result;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_GlobalEval --
+ *
+ *	Evaluate a command at global level in an interpreter.
+ *
+ * Results:
+ *	A standard Tcl result is returned, and the interp's result is modified
+ *	accordingly.
+ *
+ * Side effects:
+ *	The command string is executed in interp, and the execution is carried
+ *	out in the variable context of global level (no functions active),
+ *	just as if an "uplevel #0" command were being executed.
+ *
+ *----------------------------------------------------------------------
+ */
+
+#undef Tcl_GlobalEval
+int
+Tcl_GlobalEval(
+    Tcl_Interp *interp,		/* Interpreter in which to evaluate
+				 * command. */
+    const char *command)	/* Command to evaluate. */
+{
+    register Interp *iPtr = (Interp *) interp;
+    int result;
+    CallFrame *savedVarFramePtr;
+
+    savedVarFramePtr = iPtr->varFramePtr;
+    iPtr->varFramePtr = iPtr->rootFramePtr;
+    result = Tcl_Eval(interp, command);
+    iPtr->varFramePtr = savedVarFramePtr;
+    return result;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_SetRecursionLimit --
+ *
+ *	Set the maximum number of recursive calls that may be active for an
+ *	interpreter at once.
+ *
+ * Results:
+ *	The return value is the old limit on nesting for interp.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_SetRecursionLimit(
+    Tcl_Interp *interp,		/* Interpreter whose nesting limit is to be
+				 * set. */
+    int depth)			/* New value for maximimum depth. */
+{
+    Interp *iPtr = (Interp *) interp;
+    int old;
+
+    old = iPtr->maxNestingDepth;
+    if (depth > 0) {
+	iPtr->maxNestingDepth = depth;
+    }
+    return old;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_AllowExceptions --
+ *
+ *	Sets a flag in an interpreter so that exceptions can occur in the next
+ *	call to Tcl_Eval without them being turned into errors.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The TCL_ALLOW_EXCEPTIONS flag gets set in the interpreter's evalFlags
+ *	structure. See the reference documentation for more details.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_AllowExceptions(
+    Tcl_Interp *interp)		/* Interpreter in which to set flag. */
+{
+    Interp *iPtr = (Interp *) interp;
+
+    iPtr->evalFlags |= TCL_ALLOW_EXCEPTIONS;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_GetVersion --
+ *
+ *	Get the Tcl major, minor, and patchlevel version numbers and the
+ *	release type. A patch is a release type TCL_FINAL_RELEASE with a
+ *	patchLevel > 0.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_GetVersion(
+    int *majorV,
+    int *minorV,
+    int *patchLevelV,
+    int *type)
+{
+    if (majorV != NULL) {
+	*majorV = TCL_MAJOR_VERSION;
+    }
+    if (minorV != NULL) {
+	*minorV = TCL_MINOR_VERSION;
+    }
+    if (patchLevelV != NULL) {
+	*patchLevelV = TCL_RELEASE_SERIAL;
+    }
+    if (type != NULL) {
+	*type = TCL_RELEASE_LEVEL;
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Math Functions --
+ *
+ *	This page contains the functions that implement all of the built-in
+ *	math functions for expressions.
+ *
+ * Results:
+ *	Each function returns TCL_OK if it succeeds and pushes an Tcl object
+ *	holding the result. If it fails it returns TCL_ERROR and leaves an
+ *	error message in the interpreter's result.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+ExprCeilFunc(
+    ClientData clientData,	/* Ignored */
+    Tcl_Interp *interp,		/* The interpreter in which to execute the
+				 * function. */
+    int objc,			/* Actual parameter count. */
+    Tcl_Obj *const *objv)	/* Actual parameter list. */
+{
+    int code;
+    double d;
+    mp_int big;
+
+    if (objc != 2) {
+	MathFuncWrongNumArgs(interp, 2, objc, objv);
+	return TCL_ERROR;
+    }
+    code = Tcl_GetDoubleFromObj(interp, objv[1], &d);
+#ifdef ACCEPT_NAN
+    if ((code != TCL_OK) && (objv[1]->typePtr == &tclDoubleType)) {
+	Tcl_SetObjResult(interp, objv[1]);
+	return TCL_OK;
+    }
+#endif
+    if (code != TCL_OK) {
+	return TCL_ERROR;
+    }
+
+    if (Tcl_GetBignumFromObj(NULL, objv[1], &big) == TCL_OK) {
+	Tcl_SetObjResult(interp, Tcl_NewDoubleObj(TclCeil(&big)));
+	mp_clear(&big);
+    } else {
+	Tcl_SetObjResult(interp, Tcl_NewDoubleObj(ceil(d)));
+    }
+    return TCL_OK;
+}
+
+static int
+ExprFloorFunc(
+    ClientData clientData,	/* Ignored */
+    Tcl_Interp *interp,		/* The interpreter in which to execute the
+				 * function. */
+    int objc,			/* Actual parameter count. */
+    Tcl_Obj *const *objv)	/* Actual parameter list. */
+{
+    int code;
+    double d;
+    mp_int big;
+
+    if (objc != 2) {
+	MathFuncWrongNumArgs(interp, 2, objc, objv);
+	return TCL_ERROR;
+    }
+    code = Tcl_GetDoubleFromObj(interp, objv[1], &d);
+#ifdef ACCEPT_NAN
+    if ((code != TCL_OK) && (objv[1]->typePtr == &tclDoubleType)) {
+	Tcl_SetObjResult(interp, objv[1]);
+	return TCL_OK;
+    }
+#endif
+    if (code != TCL_OK) {
+	return TCL_ERROR;
+    }
+
+    if (Tcl_GetBignumFromObj(NULL, objv[1], &big) == TCL_OK) {
+	Tcl_SetObjResult(interp, Tcl_NewDoubleObj(TclFloor(&big)));
+	mp_clear(&big);
+    } else {
+	Tcl_SetObjResult(interp, Tcl_NewDoubleObj(floor(d)));
+    }
+    return TCL_OK;
+}
+
+static int
+ExprIsqrtFunc(
+    ClientData clientData,	/* Ignored */
+    Tcl_Interp *interp,		/* The interpreter in which to execute. */
+    int objc,			/* Actual parameter count. */
+    Tcl_Obj *const *objv)	/* Actual parameter list. */
+{
+    ClientData ptr;
+    int type;
+    double d;
+    Tcl_WideInt w;
+    mp_int big;
+    int exact = 0;		/* Flag ==1 if the argument can be represented
+				 * in a double as an exact integer. */
+
+    /*
+     * Check syntax.
+     */
+
+    if (objc != 2) {
+	MathFuncWrongNumArgs(interp, 2, objc, objv);
+	return TCL_ERROR;
+    }
+
+    /*
+     * Make sure that the arg is a number.
+     */
+
+    if (TclGetNumberFromObj(interp, objv[1], &ptr, &type) != TCL_OK) {
+	return TCL_ERROR;
+    }
+
+    switch (type) {
+    case TCL_NUMBER_NAN:
+	Tcl_GetDoubleFromObj(interp, objv[1], &d);
+	return TCL_ERROR;
+    case TCL_NUMBER_DOUBLE:
+	d = *((const double *) ptr);
+	if (d < 0) {
+	    goto negarg;
+	}
+#ifdef IEEE_FLOATING_POINT
+	if (d <= MAX_EXACT) {
+	    exact = 1;
+	}
+#endif
+	if (!exact) {
+	    if (Tcl_InitBignumFromDouble(interp, d, &big) != TCL_OK) {
+		return TCL_ERROR;
+	    }
+	}
+	break;
+    case TCL_NUMBER_BIG:
+	if (Tcl_GetBignumFromObj(interp, objv[1], &big) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	if (SIGN(&big) == MP_NEG) {
+	    mp_clear(&big);
+	    goto negarg;
+	}
+	break;
+    default:
+	if (Tcl_GetWideIntFromObj(interp, objv[1], &w) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	if (w < 0) {
+	    goto negarg;
+	}
+	d = (double) w;
+#ifdef IEEE_FLOATING_POINT
+	if (d < MAX_EXACT) {
+	    exact = 1;
+	}
+#endif
+	if (!exact) {
+	    Tcl_GetBignumFromObj(interp, objv[1], &big);
+	}
+	break;
+    }
+
+    if (exact) {
+	Tcl_SetObjResult(interp, Tcl_NewWideIntObj((Tcl_WideInt) sqrt(d)));
+    } else {
+	mp_int root;
+
+	mp_init(&root);
+	mp_sqrt(&big, &root);
+	mp_clear(&big);
+	Tcl_SetObjResult(interp, Tcl_NewBignumObj(&root));
+    }
+    return TCL_OK;
+
+  negarg:
+    Tcl_SetObjResult(interp, Tcl_NewStringObj(
+            "square root of negative argument", -1));
+    Tcl_SetErrorCode(interp, "ARITH", "DOMAIN",
+	    "domain error: argument not in valid range", NULL);
+    return TCL_ERROR;
+}
+
+static int
+ExprSqrtFunc(
+    ClientData clientData,	/* Ignored */
+    Tcl_Interp *interp,		/* The interpreter in which to execute the
+				 * function. */
+    int objc,			/* Actual parameter count. */
+    Tcl_Obj *const *objv)	/* Actual parameter list. */
+{
+    int code;
+    double d;
+    mp_int big;
+
+    if (objc != 2) {
+	MathFuncWrongNumArgs(interp, 2, objc, objv);
+	return TCL_ERROR;
+    }
+    code = Tcl_GetDoubleFromObj(interp, objv[1], &d);
+#ifdef ACCEPT_NAN
+    if ((code != TCL_OK) && (objv[1]->typePtr == &tclDoubleType)) {
+	Tcl_SetObjResult(interp, objv[1]);
+	return TCL_OK;
+    }
+#endif
+    if (code != TCL_OK) {
+	return TCL_ERROR;
+    }
+    if ((d >= 0.0) && TclIsInfinite(d)
+	    && (Tcl_GetBignumFromObj(NULL, objv[1], &big) == TCL_OK)) {
+	mp_int root;
+
+	mp_init(&root);
+	mp_sqrt(&big, &root);
+	mp_clear(&big);
+	Tcl_SetObjResult(interp, Tcl_NewDoubleObj(TclBignumToDouble(&root)));
+	mp_clear(&root);
+    } else {
+	Tcl_SetObjResult(interp, Tcl_NewDoubleObj(sqrt(d)));
+    }
+    return TCL_OK;
+}
+
+static int
+ExprUnaryFunc(
+    ClientData clientData,	/* Contains the address of a function that
+				 * takes one double argument and returns a
+				 * double result. */
+    Tcl_Interp *interp,		/* The interpreter in which to execute the
+				 * function. */
+    int objc,			/* Actual parameter count */
+    Tcl_Obj *const *objv)	/* Actual parameter list */
+{
+    int code;
+    double d;
+    double (*func)(double) = (double (*)(double)) clientData;
+
+    if (objc != 2) {
+	MathFuncWrongNumArgs(interp, 2, objc, objv);
+	return TCL_ERROR;
+    }
+    code = Tcl_GetDoubleFromObj(interp, objv[1], &d);
+#ifdef ACCEPT_NAN
+    if ((code != TCL_OK) && (objv[1]->typePtr == &tclDoubleType)) {
+	d = objv[1]->internalRep.doubleValue;
+	Tcl_ResetResult(interp);
+	code = TCL_OK;
+    }
+#endif
+    if (code != TCL_OK) {
+	return TCL_ERROR;
+    }
+    errno = 0;
+    return CheckDoubleResult(interp, func(d));
+}
+
+static int
+CheckDoubleResult(
+    Tcl_Interp *interp,
+    double dResult)
+{
+#ifndef ACCEPT_NAN
+    if (TclIsNaN(dResult)) {
+	TclExprFloatError(interp, dResult);
+	return TCL_ERROR;
+    }
+#endif
+    if ((errno == ERANGE) && ((dResult == 0.0) || TclIsInfinite(dResult))) {
+	/*
+	 * When ERANGE signals under/overflow, just accept 0.0 or +/-Inf
+	 */
+    } else if (errno != 0) {
+	/*
+	 * Report other errno values as errors.
+	 */
+
+	TclExprFloatError(interp, dResult);
+	return TCL_ERROR;
+    }
+    Tcl_SetObjResult(interp, Tcl_NewDoubleObj(dResult));
+    return TCL_OK;
+}
+
+static int
+ExprBinaryFunc(
+    ClientData clientData,	/* Contains the address of a function that
+				 * takes two double arguments and returns a
+				 * double result. */
+    Tcl_Interp *interp,		/* The interpreter in which to execute the
+				 * function. */
+    int objc,			/* Actual parameter count. */
+    Tcl_Obj *const *objv)	/* Parameter vector. */
+{
+    int code;
+    double d1, d2;
+    double (*func)(double, double) = (double (*)(double, double)) clientData;
+
+    if (objc != 3) {
+	MathFuncWrongNumArgs(interp, 3, objc, objv);
+	return TCL_ERROR;
+    }
+    code = Tcl_GetDoubleFromObj(interp, objv[1], &d1);
+#ifdef ACCEPT_NAN
+    if ((code != TCL_OK) && (objv[1]->typePtr == &tclDoubleType)) {
+	d1 = objv[1]->internalRep.doubleValue;
+	Tcl_ResetResult(interp);
+	code = TCL_OK;
+    }
+#endif
+    if (code != TCL_OK) {
+	return TCL_ERROR;
+    }
+    code = Tcl_GetDoubleFromObj(interp, objv[2], &d2);
+#ifdef ACCEPT_NAN
+    if ((code != TCL_OK) && (objv[2]->typePtr == &tclDoubleType)) {
+	d2 = objv[2]->internalRep.doubleValue;
+	Tcl_ResetResult(interp);
+	code = TCL_OK;
+    }
+#endif
+    if (code != TCL_OK) {
+	return TCL_ERROR;
+    }
+    errno = 0;
+    return CheckDoubleResult(interp, func(d1, d2));
+}
+
+static int
+ExprAbsFunc(
+    ClientData clientData,	/* Ignored. */
+    Tcl_Interp *interp,		/* The interpreter in which to execute the
+				 * function. */
+    int objc,			/* Actual parameter count. */
+    Tcl_Obj *const *objv)	/* Parameter vector. */
+{
+    ClientData ptr;
+    int type;
+    mp_int big;
+
+    if (objc != 2) {
+	MathFuncWrongNumArgs(interp, 2, objc, objv);
+	return TCL_ERROR;
+    }
+
+    if (TclGetNumberFromObj(interp, objv[1], &ptr, &type) != TCL_OK) {
+	return TCL_ERROR;
+    }
+
+    if (type == TCL_NUMBER_LONG) {
+	long l = *((const long *) ptr);
+
+	if (l > (long)0) {
+	    goto unChanged;
+	} else if (l == (long)0) {
+	    const char *string = objv[1]->bytes;
+	    if (string) {
+		while (*string != '0') {
+		    if (*string == '-') {
+			Tcl_SetObjResult(interp, Tcl_NewLongObj(0));
+			return TCL_OK;
+		    }
+		    string++;
+		}
+	    }
+	    goto unChanged;
+	} else if (l == LONG_MIN) {
+	    TclBNInitBignumFromLong(&big, l);
+	    goto tooLarge;
+	}
+	Tcl_SetObjResult(interp, Tcl_NewLongObj(-l));
+	return TCL_OK;
+    }
+
+    if (type == TCL_NUMBER_DOUBLE) {
+	double d = *((const double *) ptr);
+	static const double poszero = 0.0;
+
+	/*
+	 * We need to distinguish here between positive 0.0 and negative -0.0.
+	 * [Bug 2954959]
+	 */
+
+	if (d == -0.0) {
+	    if (!memcmp(&d, &poszero, sizeof(double))) {
+		goto unChanged;
+	    }
+	} else if (d > -0.0) {
+	    goto unChanged;
+	}
+	Tcl_SetObjResult(interp, Tcl_NewDoubleObj(-d));
+	return TCL_OK;
+    }
+
+#ifndef TCL_WIDE_INT_IS_LONG
+    if (type == TCL_NUMBER_WIDE) {
+	Tcl_WideInt w = *((const Tcl_WideInt *) ptr);
+
+	if (w >= (Tcl_WideInt)0) {
+	    goto unChanged;
+	}
+	if (w == LLONG_MIN) {
+	    TclBNInitBignumFromWideInt(&big, w);
+	    goto tooLarge;
+	}
+	Tcl_SetObjResult(interp, Tcl_NewWideIntObj(-w));
+	return TCL_OK;
+    }
+#endif
+
+    if (type == TCL_NUMBER_BIG) {
+	if (mp_cmp_d((const mp_int *) ptr, 0) == MP_LT) {
+	    Tcl_GetBignumFromObj(NULL, objv[1], &big);
+	tooLarge:
+	    mp_neg(&big, &big);
+	    Tcl_SetObjResult(interp, Tcl_NewBignumObj(&big));
+	} else {
+	unChanged:
+	    Tcl_SetObjResult(interp, objv[1]);
+	}
+	return TCL_OK;
+    }
+
+    if (type == TCL_NUMBER_NAN) {
+#ifdef ACCEPT_NAN
+	Tcl_SetObjResult(interp, objv[1]);
+	return TCL_OK;
+#else
+	double d;
+
+	Tcl_GetDoubleFromObj(interp, objv[1], &d);
+	return TCL_ERROR;
+#endif
+    }
+    return TCL_OK;
+}
+
+static int
+ExprBoolFunc(
+    ClientData clientData,	/* Ignored. */
+    Tcl_Interp *interp,		/* The interpreter in which to execute the
+				 * function. */
+    int objc,			/* Actual parameter count. */
+    Tcl_Obj *const *objv)	/* Actual parameter vector. */
+{
+    int value;
+
+    if (objc != 2) {
+	MathFuncWrongNumArgs(interp, 2, objc, objv);
+	return TCL_ERROR;
+    }
+    if (Tcl_GetBooleanFromObj(interp, objv[1], &value) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    Tcl_SetObjResult(interp, Tcl_NewBooleanObj(value));
+    return TCL_OK;
+}
+
+static int
+ExprDoubleFunc(
+    ClientData clientData,	/* Ignored. */
+    Tcl_Interp *interp,		/* The interpreter in which to execute the
+				 * function. */
+    int objc,			/* Actual parameter count. */
+    Tcl_Obj *const *objv)	/* Actual parameter vector. */
+{
+    double dResult;
+
+    if (objc != 2) {
+	MathFuncWrongNumArgs(interp, 2, objc, objv);
+	return TCL_ERROR;
+    }
+    if (Tcl_GetDoubleFromObj(interp, objv[1], &dResult) != TCL_OK) {
+#ifdef ACCEPT_NAN
+	if (objv[1]->typePtr == &tclDoubleType) {
+	    Tcl_SetObjResult(interp, objv[1]);
+	    return TCL_OK;
+	}
+#endif
+	return TCL_ERROR;
+    }
+    Tcl_SetObjResult(interp, Tcl_NewDoubleObj(dResult));
+    return TCL_OK;
+}
+
+static int
+ExprEntierFunc(
+    ClientData clientData,	/* Ignored. */
+    Tcl_Interp *interp,		/* The interpreter in which to execute the
+				 * function. */
+    int objc,			/* Actual parameter count. */
+    Tcl_Obj *const *objv)	/* Actual parameter vector. */
+{
+    double d;
+    int type;
+    ClientData ptr;
+
+    if (objc != 2) {
+	MathFuncWrongNumArgs(interp, 2, objc, objv);
+	return TCL_ERROR;
+    }
+    if (TclGetNumberFromObj(interp, objv[1], &ptr, &type) != TCL_OK) {
+	return TCL_ERROR;
+    }
+
+    if (type == TCL_NUMBER_DOUBLE) {
+	d = *((const double *) ptr);
+	if ((d >= (double)LONG_MAX) || (d <= (double)LONG_MIN)) {
+	    mp_int big;
+
+	    if (Tcl_InitBignumFromDouble(interp, d, &big) != TCL_OK) {
+		/* Infinity */
+		return TCL_ERROR;
+	    }
+	    Tcl_SetObjResult(interp, Tcl_NewBignumObj(&big));
+	    return TCL_OK;
+	} else {
+	    long result = (long) d;
+
+	    Tcl_SetObjResult(interp, Tcl_NewLongObj(result));
+	    return TCL_OK;
+	}
+    }
+
+    if (type != TCL_NUMBER_NAN) {
+	/*
+	 * All integers are already of integer type.
+	 */
+
+	Tcl_SetObjResult(interp, objv[1]);
+	return TCL_OK;
+    }
+
+    /*
+     * Get the error message for NaN.
+     */
+
+    Tcl_GetDoubleFromObj(interp, objv[1], &d);
+    return TCL_ERROR;
+}
+
+static int
+ExprIntFunc(
+    ClientData clientData,	/* Ignored. */
+    Tcl_Interp *interp,		/* The interpreter in which to execute the
+				 * function. */
+    int objc,			/* Actual parameter count. */
+    Tcl_Obj *const *objv)	/* Actual parameter vector. */
+{
+    long iResult;
+    Tcl_Obj *objPtr;
+    if (ExprEntierFunc(NULL, interp, objc, objv) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    objPtr = Tcl_GetObjResult(interp);
+    if (TclGetLongFromObj(NULL, objPtr, &iResult) != TCL_OK) {
+	/*
+	 * Truncate the bignum; keep only bits in long range.
+	 */
+
+	mp_int big;
+
+	Tcl_GetBignumFromObj(NULL, objPtr, &big);
+	mp_mod_2d(&big, (int) CHAR_BIT * sizeof(long), &big);
+	objPtr = Tcl_NewBignumObj(&big);
+	Tcl_IncrRefCount(objPtr);
+	TclGetLongFromObj(NULL, objPtr, &iResult);
+	Tcl_DecrRefCount(objPtr);
+    }
+    Tcl_SetObjResult(interp, Tcl_NewLongObj(iResult));
+    return TCL_OK;
+}
+
+static int
+ExprWideFunc(
+    ClientData clientData,	/* Ignored. */
+    Tcl_Interp *interp,		/* The interpreter in which to execute the
+				 * function. */
+    int objc,			/* Actual parameter count. */
+    Tcl_Obj *const *objv)	/* Actual parameter vector. */
+{
+    Tcl_WideInt wResult;
+    Tcl_Obj *objPtr;
+
+    if (ExprEntierFunc(NULL, interp, objc, objv) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    objPtr = Tcl_GetObjResult(interp);
+    if (Tcl_GetWideIntFromObj(NULL, objPtr, &wResult) != TCL_OK) {
+	/*
+	 * Truncate the bignum; keep only bits in wide int range.
+	 */
+
+	mp_int big;
+
+	Tcl_GetBignumFromObj(NULL, objPtr, &big);
+	mp_mod_2d(&big, (int) CHAR_BIT * sizeof(Tcl_WideInt), &big);
+	objPtr = Tcl_NewBignumObj(&big);
+	Tcl_IncrRefCount(objPtr);
+	Tcl_GetWideIntFromObj(NULL, objPtr, &wResult);
+	Tcl_DecrRefCount(objPtr);
+    }
+    Tcl_SetObjResult(interp, Tcl_NewWideIntObj(wResult));
+    return TCL_OK;
+}
+
+static int
+ExprRandFunc(
+    ClientData clientData,	/* Ignored. */
+    Tcl_Interp *interp,		/* The interpreter in which to execute the
+				 * function. */
+    int objc,			/* Actual parameter count. */
+    Tcl_Obj *const *objv)	/* Actual parameter vector. */
+{
+    Interp *iPtr = (Interp *) interp;
+    double dResult;
+    long tmp;			/* Algorithm assumes at least 32 bits. Only
+				 * long guarantees that. See below. */
+    Tcl_Obj *oResult;
+
+    if (objc != 1) {
+	MathFuncWrongNumArgs(interp, 1, objc, objv);
+	return TCL_ERROR;
+    }
+
+    if (!(iPtr->flags & RAND_SEED_INITIALIZED)) {
+	iPtr->flags |= RAND_SEED_INITIALIZED;
+
+	/*
+	 * Take into consideration the thread this interp is running in order
+	 * to insure different seeds in different threads (bug #416643)
+	 */
+
+	iPtr->randSeed = TclpGetClicks() + (PTR2INT(Tcl_GetCurrentThread())<<12);
+
+	/*
+	 * Make sure 1 <= randSeed <= (2^31) - 2. See below.
+	 */
+
+	iPtr->randSeed &= (unsigned long) 0x7fffffff;
+	if ((iPtr->randSeed == 0) || (iPtr->randSeed == 0x7fffffff)) {
+	    iPtr->randSeed ^= 123459876;
+	}
+    }
+
+    /*
+     * Generate the random number using the linear congruential generator
+     * defined by the following recurrence:
+     *		seed = ( IA * seed ) mod IM
+     * where IA is 16807 and IM is (2^31) - 1. The recurrence maps a seed in
+     * the range [1, IM - 1] to a new seed in that same range. The recurrence
+     * maps IM to 0, and maps 0 back to 0, so those two values must not be
+     * allowed as initial values of seed.
+     *
+     * In order to avoid potential problems with integer overflow, the
+     * recurrence is implemented in terms of additional constants IQ and IR
+     * such that
+     *		IM = IA*IQ + IR
+     * None of the operations in the implementation overflows a 32-bit signed
+     * integer, and the C type long is guaranteed to be at least 32 bits wide.
+     *
+     * For more details on how this algorithm works, refer to the following
+     * papers:
+     *
+     *	S.K. Park & K.W. Miller, "Random number generators: good ones are hard
+     *	to find," Comm ACM 31(10):1192-1201, Oct 1988
+     *
+     *	W.H. Press & S.A. Teukolsky, "Portable random number generators,"
+     *	Computers in Physics 6(5):522-524, Sep/Oct 1992.
+     */
+
+#define RAND_IA		16807
+#define RAND_IM		2147483647
+#define RAND_IQ		127773
+#define RAND_IR		2836
+#define RAND_MASK	123459876
+
+    tmp = iPtr->randSeed/RAND_IQ;
+    iPtr->randSeed = RAND_IA*(iPtr->randSeed - tmp*RAND_IQ) - RAND_IR*tmp;
+    if (iPtr->randSeed < 0) {
+	iPtr->randSeed += RAND_IM;
+    }
+
+    /*
+     * Since the recurrence keeps seed values in the range [1, RAND_IM - 1],
+     * dividing by RAND_IM yields a double in the range (0, 1).
+     */
+
+    dResult = iPtr->randSeed * (1.0/RAND_IM);
+
+    /*
+     * Push a Tcl object with the result.
+     */
+
+    TclNewDoubleObj(oResult, dResult);
+    Tcl_SetObjResult(interp, oResult);
+    return TCL_OK;
+}
+
+static int
+ExprRoundFunc(
+    ClientData clientData,	/* Ignored. */
+    Tcl_Interp *interp,		/* The interpreter in which to execute the
+				 * function. */
+    int objc,			/* Actual parameter count. */
+    Tcl_Obj *const *objv)	/* Parameter vector. */
+{
+    double d;
+    ClientData ptr;
+    int type;
+
+    if (objc != 2) {
+	MathFuncWrongNumArgs(interp, 2, objc, objv);
+	return TCL_ERROR;
+    }
+
+    if (TclGetNumberFromObj(interp, objv[1], &ptr, &type) != TCL_OK) {
+	return TCL_ERROR;
+    }
+
+    if (type == TCL_NUMBER_DOUBLE) {
+	double fractPart, intPart;
+	long max = LONG_MAX, min = LONG_MIN;
+
+	fractPart = modf(*((const double *) ptr), &intPart);
+	if (fractPart <= -0.5) {
+	    min++;
+	} else if (fractPart >= 0.5) {
+	    max--;
+	}
+	if ((intPart >= (double)max) || (intPart <= (double)min)) {
+	    mp_int big;
+
+	    if (Tcl_InitBignumFromDouble(interp, intPart, &big) != TCL_OK) {
+		/* Infinity */
+		return TCL_ERROR;
+	    }
+	    if (fractPart <= -0.5) {
+		mp_sub_d(&big, 1, &big);
+	    } else if (fractPart >= 0.5) {
+		mp_add_d(&big, 1, &big);
+	    }
+	    Tcl_SetObjResult(interp, Tcl_NewBignumObj(&big));
+	    return TCL_OK;
+	} else {
+	    long result = (long)intPart;
+
+	    if (fractPart <= -0.5) {
+		result--;
+	    } else if (fractPart >= 0.5) {
+		result++;
+	    }
+	    Tcl_SetObjResult(interp, Tcl_NewLongObj(result));
+	    return TCL_OK;
+	}
+    }
+
+    if (type != TCL_NUMBER_NAN) {
+	/*
+	 * All integers are already rounded
+	 */
+
+	Tcl_SetObjResult(interp, objv[1]);
+	return TCL_OK;
+    }
+
+    /*
+     * Get the error message for NaN.
+     */
+
+    Tcl_GetDoubleFromObj(interp, objv[1], &d);
+    return TCL_ERROR;
+}
+
+static int
+ExprSrandFunc(
+    ClientData clientData,	/* Ignored. */
+    Tcl_Interp *interp,		/* The interpreter in which to execute the
+				 * function. */
+    int objc,			/* Actual parameter count. */
+    Tcl_Obj *const *objv)	/* Parameter vector. */
+{
+    Interp *iPtr = (Interp *) interp;
+    long i = 0;			/* Initialized to avoid compiler warning. */
+
+    /*
+     * Convert argument and use it to reset the seed.
+     */
+
+    if (objc != 2) {
+	MathFuncWrongNumArgs(interp, 2, objc, objv);
+	return TCL_ERROR;
+    }
+
+    if (TclGetLongFromObj(NULL, objv[1], &i) != TCL_OK) {
+	Tcl_Obj *objPtr;
+	mp_int big;
+
+	if (Tcl_GetBignumFromObj(interp, objv[1], &big) != TCL_OK) {
+	    /* TODO: more ::errorInfo here? or in caller? */
+	    return TCL_ERROR;
+	}
+
+	mp_mod_2d(&big, (int) CHAR_BIT * sizeof(long), &big);
+	objPtr = Tcl_NewBignumObj(&big);
+	Tcl_IncrRefCount(objPtr);
+	TclGetLongFromObj(NULL, objPtr, &i);
+	Tcl_DecrRefCount(objPtr);
+    }
+
+    /*
+     * Reset the seed. Make sure 1 <= randSeed <= 2^31 - 2. See comments in
+     * ExprRandFunc for more details.
+     */
+
+    iPtr->flags |= RAND_SEED_INITIALIZED;
+    iPtr->randSeed = i;
+    iPtr->randSeed &= (unsigned long) 0x7fffffff;
+    if ((iPtr->randSeed == 0) || (iPtr->randSeed == 0x7fffffff)) {
+	iPtr->randSeed ^= 123459876;
+    }
+
+    /*
+     * To avoid duplicating the random number generation code we simply clean
+     * up our state and call the real random number function. That function
+     * will always succeed.
+     */
+
+    return ExprRandFunc(clientData, interp, 1, objv);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * MathFuncWrongNumArgs --
+ *
+ *	Generate an error message when a math function presents the wrong
+ *	number of arguments.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	An error message is stored in the interpreter result.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+MathFuncWrongNumArgs(
+    Tcl_Interp *interp,		/* Tcl interpreter */
+    int expected,		/* Formal parameter count. */
+    int found,			/* Actual parameter count. */
+    Tcl_Obj *const *objv)	/* Actual parameter vector. */
+{
+    const char *name = Tcl_GetString(objv[0]);
+    const char *tail = name + strlen(name);
+
+    while (tail > name+1) {
+	tail--;
+	if (*tail == ':' && tail[-1] == ':') {
+	    name = tail+1;
+	    break;
+	}
+    }
+    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+	    "too %s arguments for math function \"%s\"",
+	    (found < expected ? "few" : "many"), name));
+    Tcl_SetErrorCode(interp, "TCL", "WRONGARGS", NULL);
+}
+
+#ifdef USE_DTRACE
+/*
+ *----------------------------------------------------------------------
+ *
+ * DTraceObjCmd --
+ *
+ *	This function is invoked to process the "::tcl::dtrace" Tcl command.
+ *
+ * Results:
+ *	A standard Tcl object result.
+ *
+ * Side effects:
+ *	The 'tcl-probe' DTrace probe is triggered (if it is enabled).
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+DTraceObjCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    if (TCL_DTRACE_TCL_PROBE_ENABLED()) {
+	char *a[10];
+	int i = 0;
+
+	while (i++ < 10) {
+	    a[i-1] = i < objc ? TclGetString(objv[i]) : NULL;
+	}
+	TCL_DTRACE_TCL_PROBE(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7],
+		a[8], a[9]);
+    }
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclDTraceInfo --
+ *
+ *	Extract information from a TIP280 dict for use by DTrace probes.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclDTraceInfo(
+    Tcl_Obj *info,
+    const char **args,
+    int *argsi)
+{
+    static Tcl_Obj *keys[10] = { NULL };
+    Tcl_Obj **k = keys, *val;
+    int i = 0;
+
+    if (!*k) {
+#define kini(s) TclNewLiteralStringObj(keys[i], s); i++
+	kini("cmd");	kini("type");	kini("proc");	kini("file");
+	kini("method");	kini("class");	kini("lambda");	kini("object");
+	kini("line");	kini("level");
+#undef kini
+    }
+    for (i = 0; i < 6; i++) {
+	Tcl_DictObjGet(NULL, info, *k++, &val);
+	args[i] = val ? TclGetString(val) : NULL;
+    }
+    /* no "proc" -> use "lambda" */
+    if (!args[2]) {
+	Tcl_DictObjGet(NULL, info, *k, &val);
+	args[2] = val ? TclGetString(val) : NULL;
+    }
+    k++;
+    /* no "class" -> use "object" */
+    if (!args[5]) {
+	Tcl_DictObjGet(NULL, info, *k, &val);
+	args[5] = val ? TclGetString(val) : NULL;
+    }
+    k++;
+    for (i = 0; i < 2; i++) {
+	Tcl_DictObjGet(NULL, info, *k++, &val);
+	if (val) {
+	    TclGetIntFromObj(NULL, val, &argsi[i]);
+	} else {
+	    argsi[i] = 0;
+	}
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * DTraceCmdReturn --
+ *
+ *	NR callback for DTrace command return probes.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+DTraceCmdReturn(
+    ClientData data[],
+    Tcl_Interp *interp,
+    int result)
+{
+    char *cmdName = TclGetString((Tcl_Obj *) data[0]);
+
+    if (TCL_DTRACE_CMD_RETURN_ENABLED()) {
+	TCL_DTRACE_CMD_RETURN(cmdName, result);
+    }
+    if (TCL_DTRACE_CMD_RESULT_ENABLED()) {
+	Tcl_Obj *r = Tcl_GetObjResult(interp);
+
+	TCL_DTRACE_CMD_RESULT(cmdName, result, TclGetString(r), r);
+    }
+    return result;
+}
+
+TCL_DTRACE_DEBUG_LOG()
+
+#endif /* USE_DTRACE */
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_NRCallObjProc --
+ *
+ *	This function calls an objProc directly while managing things properly
+ *	if it happens to be an NR objProc. It is meant to be used by extenders
+ *	that provide an NR implementation of a command, as this function
+ *	permits a trivial coding of the non-NR objProc.
+ *
+ * Results:
+ *	The return value is a standard Tcl completion code such as TCL_OK or
+ *	TCL_ERROR. A result or error message is left in interp's result.
+ *
+ * Side effects:
+ *	Depends on the objProc.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_NRCallObjProc(
+    Tcl_Interp *interp,
+    Tcl_ObjCmdProc *objProc,
+    ClientData clientData,
+    int objc,
+    Tcl_Obj *const objv[])
+{
+    NRE_callback *rootPtr = TOP_CB(interp);
+
+    TclNRAddCallback(interp, Dispatch, objProc, clientData,
+	    INT2PTR(objc), objv);
+    return TclNRRunCallbacks(interp, TCL_OK, rootPtr);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_NRCreateCommand --
+ *
+ *	Define a new NRE-enabled object-based command in a command table.
+ *
+ * Results:
+ *	The return value is a token for the command, which can be used in
+ *	future calls to Tcl_GetCommandName.
+ *
+ * Side effects:
+ *	If no command named "cmdName" already exists for interp, one is
+ *	created. Otherwise, if a command does exist, then if the object-based
+ *	Tcl_ObjCmdProc is TclInvokeStringCommand, we assume Tcl_CreateCommand
+ *	was called previously for the same command and just set its
+ *	Tcl_ObjCmdProc to the argument "proc"; otherwise, we delete the old
+ *	command.
+ *
+ *	In the future, during bytecode evaluation when "cmdName" is seen as
+ *	the name of a command by Tcl_EvalObj or Tcl_Eval, the object-based
+ *	Tcl_ObjCmdProc proc will be called. When the command is deleted from
+ *	the table, deleteProc will be called. See the manual entry for details
+ *	on the calling sequence.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_Command
+Tcl_NRCreateCommand(
+    Tcl_Interp *interp,		/* Token for command interpreter (returned by
+				 * previous call to Tcl_CreateInterp). */
+    const char *cmdName,	/* Name of command. If it contains namespace
+				 * qualifiers, the new command is put in the
+				 * specified namespace; otherwise it is put in
+				 * the global namespace. */
+    Tcl_ObjCmdProc *proc,	/* Object-based function to associate with
+				 * name, provides direct access for direct
+				 * calls. */
+    Tcl_ObjCmdProc *nreProc,	/* Object-based function to associate with
+				 * name, provides NR implementation */
+    ClientData clientData,	/* Arbitrary value to pass to object
+				 * function. */
+    Tcl_CmdDeleteProc *deleteProc)
+				/* If not NULL, gives a function to call when
+				 * this command is deleted. */
+{
+    Command *cmdPtr = (Command *)
+	    Tcl_CreateObjCommand(interp,cmdName,proc,clientData,deleteProc);
+
+    cmdPtr->nreProc = nreProc;
+    return (Tcl_Command) cmdPtr;
+}
+
+/****************************************************************************
+ * Stuff for the public api
+ ****************************************************************************/
+
+int
+Tcl_NREvalObj(
+    Tcl_Interp *interp,
+    Tcl_Obj *objPtr,
+    int flags)
+{
+    return TclNREvalObjEx(interp, objPtr, flags, NULL, INT_MIN);
+}
+
+int
+Tcl_NREvalObjv(
+    Tcl_Interp *interp,		/* Interpreter in which to evaluate the
+				 * command. Also used for error reporting. */
+    int objc,			/* Number of words in command. */
+    Tcl_Obj *const objv[],	/* An array of pointers to objects that are
+				 * the words that make up the command. */
+    int flags)			/* Collection of OR-ed bits that control the
+				 * evaluation of the script. Only
+				 * TCL_EVAL_GLOBAL, TCL_EVAL_INVOKE and
+				 * TCL_EVAL_NOERR are currently supported. */
+{
+    return TclNREvalObjv(interp, objc, objv, flags, NULL);
+}
+
+int
+Tcl_NRCmdSwap(
+    Tcl_Interp *interp,
+    Tcl_Command cmd,
+    int objc,
+    Tcl_Obj *const objv[],
+    int flags)
+{
+    return TclNREvalObjv(interp, objc, objv, flags|TCL_EVAL_NOERR,
+	    (Command *) cmd);
+}
+
+/*****************************************************************************
+ * Tailcall related code
+ *****************************************************************************
+ *
+ * The steps of the tailcall dance are as follows:
+ *
+ *   1. when [tailcall] is invoked, it stores the corresponding callback in
+ *      the current CallFrame and returns TCL_RETURN
+ *   2. when the CallFrame is popped, it calls TclSetTailcall to store the
+ *      callback in the proper NRCommand callback - the spot where the command
+ *      that pushed the CallFrame is completely cleaned up
+ *   3. when the NRCommand callback runs, it schedules the tailcall callback
+ *      to run immediately after it returns
+ *
+ *   One delicate point is to properly define the NRCommand where the tailcall
+ *   will execute. There are functions whose purpose is to help define the
+ *   precise spot:
+ *     TclMarkTailcall: if the NEXT command to be pushed tailcalls, execution
+ *         should continue right here
+ *     TclSkipTailcall:  if the NEXT command to be pushed tailcalls, execution
+ *         should continue after the CURRENT command is fully returned ("skip
+ *         the next command: we are redirecting to it, tailcalls should run
+ *         after WE return")
+ *     TclPushTailcallPoint: the search for a tailcalling spot cannot traverse
+ *         this point. This is special for OO, as some of the oo constructs
+ *         that behave like commands may not push an NRCommand callback.
+ */
+
+void
+TclMarkTailcall(
+    Tcl_Interp *interp)
+{
+    Interp *iPtr = (Interp *) interp;
+
+    if (iPtr->deferredCallbacks == NULL) {
+	TclNRAddCallback(interp, NRCommand, NULL, NULL,
+                NULL, NULL);
+        iPtr->deferredCallbacks = TOP_CB(interp);
+    }
+}
+
+void
+TclSkipTailcall(
+    Tcl_Interp *interp)
+{
+    Interp *iPtr = (Interp *) interp;
+
+    TclMarkTailcall(interp);
+    iPtr->deferredCallbacks->data[1] = INT2PTR(1);
+}
+
+void
+TclPushTailcallPoint(
+    Tcl_Interp *interp)
+{
+    TclNRAddCallback(interp, NRCommand, NULL, NULL, NULL, NULL);
+    ((Interp *) interp)->numLevels++;
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclSetTailcall --
+ *
+ *	Splice a tailcall command in the proper spot of the NRE callback
+ *	stack, so that it runs at the right time.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclSetTailcall(
+    Tcl_Interp *interp,
+    Tcl_Obj *listPtr)
+{
+    /*
+     * Find the splicing spot: right before the NRCommand of the thing
+     * being tailcalled. Note that we skip NRCommands marked by a 1 in data[1]
+     * (used by command redirectors).
+     */
+
+    NRE_callback *runPtr;
+
+    for (runPtr = TOP_CB(interp); runPtr; runPtr = runPtr->nextPtr) {
+        if (((runPtr->procPtr) == NRCommand) && !runPtr->data[1]) {
+            break;
+        }
+    }
+    if (!runPtr) {
+        Tcl_Panic("tailcall cannot find the right splicing spot: should not happen!");
+    }
+    runPtr->data[1] = listPtr;
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclNRTailcallObjCmd --
+ *
+ *	Prepare the tailcall as a list and store it in the current
+ *	varFrame. When the frame is later popped the tailcall will be spliced
+ *	at the proper place.
+ *
+ * Results:
+ *	The first NRCommand callback that is not marked to be skipped is
+ *	updated so that its data[1] field contains the tailcall list.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclNRTailcallObjCmd(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const objv[])
+{
+    Interp *iPtr = (Interp *) interp;
+
+    if (objc < 1) {
+	Tcl_WrongNumArgs(interp, 1, objv, "?command? ?arg ...?");
+	return TCL_ERROR;
+    }
+
+    if (!(iPtr->varFramePtr->isProcCallFrame & 1)) {
+        Tcl_SetObjResult(interp, Tcl_NewStringObj(
+                "tailcall can only be called from a proc, lambda or method", -1));
+        Tcl_SetErrorCode(interp, "TCL", "TAILCALL", "ILLEGAL", NULL);
+	return TCL_ERROR;
+    }
+
+    /*
+     * Invocation without args just clears a scheduled tailcall; invocation
+     * with an argument replaces any previously scheduled tailcall.
+     */
+
+    if (iPtr->varFramePtr->tailcallPtr) {
+        Tcl_DecrRefCount(iPtr->varFramePtr->tailcallPtr);
+        iPtr->varFramePtr->tailcallPtr = NULL;
+    }
+
+    /*
+     * Create the callback to actually evaluate the tailcalled
+     * command, then set it in the varFrame so that PopCallFrame can use it
+     * at the proper time.
+     */
+
+    if (objc > 1) {
+        Tcl_Obj *listPtr, *nsObjPtr;
+        Tcl_Namespace *nsPtr = (Tcl_Namespace *) iPtr->varFramePtr->nsPtr;
+        Tcl_Namespace *ns1Ptr;
+
+        /* The tailcall data is in a Tcl list: the first element is the
+         * namespace, the rest the command to be tailcalled. */
+
+        listPtr = Tcl_NewListObj(objc, objv);
+
+        nsObjPtr = Tcl_NewStringObj(nsPtr->fullName, -1);
+        if ((TCL_OK != TclGetNamespaceFromObj(interp, nsObjPtr, &ns1Ptr))
+                || (nsPtr != ns1Ptr)) {
+            Tcl_Panic("Tailcall failed to find the proper namespace");
+        }
+ 	TclListObjSetElement(interp, listPtr, 0, nsObjPtr);
+
+        iPtr->varFramePtr->tailcallPtr = listPtr;
+    }
+    return TCL_RETURN;
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclNRTailcallEval --
+ *
+ *	This NREcallback actually causes the tailcall to be evaluated.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclNRTailcallEval(
+    ClientData data[],
+    Tcl_Interp *interp,
+    int result)
+{
+    Interp *iPtr = (Interp *) interp;
+    Tcl_Obj *listPtr = data[0], *nsObjPtr;
+    Tcl_Namespace *nsPtr;
+    int objc;
+    Tcl_Obj **objv;
+
+    Tcl_ListObjGetElements(interp, listPtr, &objc, &objv);
+    nsObjPtr = objv[0];
+
+    if (result == TCL_OK) {
+	result = TclGetNamespaceFromObj(interp, nsObjPtr, &nsPtr);
+    }
+
+    if (result != TCL_OK) {
+        /*
+         * Tailcall execution was preempted, eg by an intervening catch or by
+         * a now-gone namespace: cleanup and return.
+         */
+
+	Tcl_DecrRefCount(listPtr);
+        return result;
+    }
+
+    /*
+     * Perform the tailcall
+     */
+
+    TclMarkTailcall(interp);
+    TclNRAddCallback(interp, TclNRReleaseValues, listPtr, NULL, NULL,NULL);
+    iPtr->lookupNsPtr = (Namespace *) nsPtr;
+    return TclNREvalObjv(interp, objc-1, objv+1, 0, NULL);
+}
+
+int
+TclNRReleaseValues(
+    ClientData data[],
+    Tcl_Interp *interp,
+    int result)
+{
+    int i = 0;
+    while (i < 4) {
+	if (data[i]) {
+	    Tcl_DecrRefCount((Tcl_Obj *) data[i]);
+	} else {
+	    break;
+	}
+	i++;
+    }
+    return result;
+}
+
+
+void
+Tcl_NRAddCallback(
+    Tcl_Interp *interp,
+    Tcl_NRPostProc *postProcPtr,
+    ClientData data0,
+    ClientData data1,
+    ClientData data2,
+    ClientData data3)
+{
+    if (!(postProcPtr)) {
+	Tcl_Panic("Adding a callback without an objProc?!");
+    }
+    TclNRAddCallback(interp, postProcPtr, data0, data1, data2, data3);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclNRCoroutineObjCmd -- (and friends)
+ *
+ *	This object-based function is invoked to process the "coroutine" Tcl
+ *	command. It is heavily based on "apply".
+ *
+ * Results:
+ *	A standard Tcl object result value.
+ *
+ * Side effects:
+ *	A new procedure gets created.
+ *
+ * ** FIRST EXPERIMENTAL IMPLEMENTATION **
+ *
+ * It is fairly amateurish and not up to our standards - mainly in terms of
+ * error messages and [info] interaction. Just to test the infrastructure in
+ * teov and tebc.
+ *----------------------------------------------------------------------
+ */
+
+#define iPtr ((Interp *) interp)
+
+int
+TclNRYieldObjCmd(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const objv[])
+{
+    CoroutineData *corPtr = iPtr->execEnvPtr->corPtr;
+
+    if (objc > 2) {
+	Tcl_WrongNumArgs(interp, 1, objv, "?returnValue?");
+	return TCL_ERROR;
+    }
+
+    if (!corPtr) {
+	Tcl_SetObjResult(interp, Tcl_NewStringObj(
+                "yield can only be called in a coroutine", -1));
+	Tcl_SetErrorCode(interp, "TCL", "COROUTINE", "ILLEGAL_YIELD", NULL);
+	return TCL_ERROR;
+    }
+
+    if (objc == 2) {
+	Tcl_SetObjResult(interp, objv[1]);
+    }
+
+    NRE_ASSERT(!COR_IS_SUSPENDED(corPtr));
+    TclNRAddCallback(interp, TclNRCoroutineActivateCallback, corPtr,
+            clientData, NULL, NULL);
+    return TCL_OK;
+}
+
+int
+TclNRYieldToObjCmd(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const objv[])
+{
+    CoroutineData *corPtr = iPtr->execEnvPtr->corPtr;
+    Tcl_Obj *listPtr, *nsObjPtr;
+    Tcl_Namespace *nsPtr = TclGetCurrentNamespace(interp);
+
+    if (objc < 2) {
+	Tcl_WrongNumArgs(interp, 1, objv, "command ?arg ...?");
+	return TCL_ERROR;
+    }
+
+    if (!corPtr) {
+	Tcl_SetObjResult(interp, Tcl_NewStringObj(
+                "yieldto can only be called in a coroutine", -1));
+	Tcl_SetErrorCode(interp, "TCL", "COROUTINE", "ILLEGAL_YIELD", NULL);
+	return TCL_ERROR;
+    }
+
+    if (((Namespace *) nsPtr)->flags & NS_DYING) {
+        Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		"yieldto called in deleted namespace", -1));
+        Tcl_SetErrorCode(interp, "TCL", "COROUTINE", "YIELDTO_IN_DELETED",
+		NULL);
+        return TCL_ERROR;
+    }
+
+    /*
+     * Add the tailcall in the caller env, then just yield.
+     *
+     * This is essentially code from TclNRTailcallObjCmd
+     */
+
+    listPtr = Tcl_NewListObj(objc, objv);
+    nsObjPtr = Tcl_NewStringObj(nsPtr->fullName, -1);
+    TclListObjSetElement(interp, listPtr, 0, nsObjPtr);
+
+    /*
+     * Add the callback in the caller's env, then instruct TEBC to yield.
+     */
+
+    iPtr->execEnvPtr = corPtr->callerEEPtr;
+    TclSetTailcall(interp, listPtr);
+    iPtr->execEnvPtr = corPtr->eePtr;
+
+    return TclNRYieldObjCmd(INT2PTR(CORO_ACTIVATE_YIELDM), interp, 1, objv);
+}
+
+static int
+RewindCoroutineCallback(
+    ClientData data[],
+    Tcl_Interp *interp,
+    int result)
+{
+    return Tcl_RestoreInterpState(interp, data[0]);
+}
+
+static int
+RewindCoroutine(
+    CoroutineData *corPtr,
+    int result)
+{
+    Tcl_Interp *interp = corPtr->eePtr->interp;
+    Tcl_InterpState state = Tcl_SaveInterpState(interp, result);
+
+    NRE_ASSERT(COR_IS_SUSPENDED(corPtr));
+    NRE_ASSERT(corPtr->eePtr != NULL);
+    NRE_ASSERT(corPtr->eePtr != iPtr->execEnvPtr);
+
+    corPtr->eePtr->rewind = 1;
+    TclNRAddCallback(interp, RewindCoroutineCallback, state,
+	    NULL, NULL, NULL);
+    return TclNRInterpCoroutine(corPtr, interp, 0, NULL);
+}
+
+static void
+DeleteCoroutine(
+    ClientData clientData)
+{
+    CoroutineData *corPtr = clientData;
+    Tcl_Interp *interp = corPtr->eePtr->interp;
+    NRE_callback *rootPtr = TOP_CB(interp);
+
+    if (COR_IS_SUSPENDED(corPtr)) {
+	TclNRRunCallbacks(interp, RewindCoroutine(corPtr,TCL_OK), rootPtr);
+    }
+}
+
+static int
+NRCoroutineCallerCallback(
+    ClientData data[],
+    Tcl_Interp *interp,
+    int result)
+{
+    CoroutineData *corPtr = data[0];
+    Command *cmdPtr = corPtr->cmdPtr;
+
+    /*
+     * This is the last callback in the caller execEnv, right before switching
+     * to the coroutine's
+     */
+
+    NRE_ASSERT(iPtr->execEnvPtr == corPtr->callerEEPtr);
+
+    if (!corPtr->eePtr) {
+	/*
+	 * The execEnv was wound down but not deleted for our sake. We finish
+	 * the job here. The caller context has already been restored.
+	 */
+
+	NRE_ASSERT(iPtr->varFramePtr == corPtr->caller.varFramePtr);
+	NRE_ASSERT(iPtr->framePtr == corPtr->caller.framePtr);
+	NRE_ASSERT(iPtr->cmdFramePtr == corPtr->caller.cmdFramePtr);
+	ckfree(corPtr);
+	return result;
+    }
+
+    NRE_ASSERT(COR_IS_SUSPENDED(corPtr));
+    SAVE_CONTEXT(corPtr->running);
+    RESTORE_CONTEXT(corPtr->caller);
+
+    if (cmdPtr->flags & CMD_IS_DELETED) {
+	/*
+	 * The command was deleted while it was running: wind down the
+	 * execEnv, this will do the complete cleanup. RewindCoroutine will
+	 * restore both the caller's context and interp state.
+	 */
+
+	return RewindCoroutine(corPtr, result);
+    }
+
+    return result;
+}
+
+static int
+NRCoroutineExitCallback(
+    ClientData data[],
+    Tcl_Interp *interp,
+    int result)
+{
+    CoroutineData *corPtr = data[0];
+    Command *cmdPtr = corPtr->cmdPtr;
+
+    /*
+     * This runs at the bottom of the Coroutine's execEnv: it will be executed
+     * when the coroutine returns or is wound down, but not when it yields. It
+     * deletes the coroutine and restores the caller's environment.
+     */
+
+    NRE_ASSERT(interp == corPtr->eePtr->interp);
+    NRE_ASSERT(TOP_CB(interp) == NULL);
+    NRE_ASSERT(iPtr->execEnvPtr == corPtr->eePtr);
+    NRE_ASSERT(!COR_IS_SUSPENDED(corPtr));
+    NRE_ASSERT((corPtr->callerEEPtr->callbackPtr->procPtr == NRCoroutineCallerCallback));
+
+    cmdPtr->deleteProc = NULL;
+    Tcl_DeleteCommandFromToken(interp, (Tcl_Command) cmdPtr);
+    TclCleanupCommandMacro(cmdPtr);
+
+    corPtr->eePtr->corPtr = NULL;
+    TclDeleteExecEnv(corPtr->eePtr);
+    corPtr->eePtr = NULL;
+
+    corPtr->stackLevel = NULL;
+
+    /*
+     * #280.
+     * Drop the coroutine-owned copy of the lineLABCPtr hashtable for literal
+     * command arguments in bytecode.
+     */
+
+    Tcl_DeleteHashTable(corPtr->lineLABCPtr);
+    ckfree(corPtr->lineLABCPtr);
+    corPtr->lineLABCPtr = NULL;
+
+    RESTORE_CONTEXT(corPtr->caller);
+    iPtr->execEnvPtr = corPtr->callerEEPtr;
+    iPtr->numLevels++;
+
+    return result;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclNRCoroutineActivateCallback --
+ *
+ *      This is the workhorse for coroutines: it implements both yield and
+ *      resume.
+ *
+ *      It is important that both be implemented in the same callback: the
+ *      detection of the impossibility to suspend due to a busy C-stack relies
+ *      on the precise position of a local variable in the stack. We do not
+ *      want the compiler to play tricks on us, either by moving things around
+ *      or inlining.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclNRCoroutineActivateCallback(
+    ClientData data[],
+    Tcl_Interp *interp,
+    int result)
+{
+    CoroutineData *corPtr = data[0];
+    int type = PTR2INT(data[1]);
+    int numLevels, unused;
+    int *stackLevel = &unused;
+
+    if (!corPtr->stackLevel) {
+        /*
+         * -- Coroutine is suspended --
+         * Push the callback to restore the caller's context on yield or
+         * return.
+         */
+
+        TclNRAddCallback(interp, NRCoroutineCallerCallback, corPtr,
+                NULL, NULL, NULL);
+
+        /*
+         * Record the stackLevel at which the resume is happening, then swap
+         * the interp's environment to make it suitable to run this coroutine.
+         */
+
+        corPtr->stackLevel = stackLevel;
+        numLevels = corPtr->auxNumLevels;
+        corPtr->auxNumLevels = iPtr->numLevels;
+
+        SAVE_CONTEXT(corPtr->caller);
+        corPtr->callerEEPtr = iPtr->execEnvPtr;
+        RESTORE_CONTEXT(corPtr->running);
+        iPtr->execEnvPtr = corPtr->eePtr;
+        iPtr->numLevels += numLevels;
+    } else {
+        /*
+         * Coroutine is active: yield
+         */
+
+        if (corPtr->stackLevel != stackLevel) {
+            Tcl_SetObjResult(interp, Tcl_NewStringObj(
+                    "cannot yield: C stack busy", -1));
+            Tcl_SetErrorCode(interp, "TCL", "COROUTINE", "CANT_YIELD",
+                    NULL);
+            return TCL_ERROR;
+        }
+
+        if (type == CORO_ACTIVATE_YIELD) {
+            corPtr->nargs = COROUTINE_ARGUMENTS_SINGLE_OPTIONAL;
+        } else if (type == CORO_ACTIVATE_YIELDM) {
+            corPtr->nargs = COROUTINE_ARGUMENTS_ARBITRARY;
+        } else {
+            Tcl_Panic("Yield received an option which is not implemented");
+        }
+
+        corPtr->stackLevel = NULL;
+
+        numLevels = iPtr->numLevels;
+        iPtr->numLevels = corPtr->auxNumLevels;
+        corPtr->auxNumLevels = numLevels - corPtr->auxNumLevels;
+
+        iPtr->execEnvPtr = corPtr->callerEEPtr;
+    }
+
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * NRCoroInjectObjCmd --
+ *
+ *      Implementation of [::tcl::unsupported::inject] command.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+NRCoroInjectObjCmd(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const objv[])
+{
+    Command *cmdPtr;
+    CoroutineData *corPtr;
+    ExecEnv *savedEEPtr = iPtr->execEnvPtr;
+
+    /*
+     * Usage more or less like tailcall:
+     *   inject coroName cmd ?arg1 arg2 ...?
+     */
+
+    if (objc < 3) {
+	Tcl_WrongNumArgs(interp, 1, objv, "coroName cmd ?arg1 arg2 ...?");
+	return TCL_ERROR;
+    }
+
+    cmdPtr = (Command *) Tcl_GetCommandFromObj(interp, objv[1]);
+    if ((!cmdPtr) || (cmdPtr->nreProc != TclNRInterpCoroutine)) {
+        Tcl_SetObjResult(interp, Tcl_NewStringObj(
+                "can only inject a command into a coroutine", -1));
+        Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "COROUTINE",
+                TclGetString(objv[1]), NULL);
+        return TCL_ERROR;
+    }
+
+    corPtr = cmdPtr->objClientData;
+    if (!COR_IS_SUSPENDED(corPtr)) {
+        Tcl_SetObjResult(interp, Tcl_NewStringObj(
+                "can only inject a command into a suspended coroutine", -1));
+        Tcl_SetErrorCode(interp, "TCL", "COROUTINE", "ACTIVE", NULL);
+        return TCL_ERROR;
+    }
+
+    /*
+     * Add the callback to the coro's execEnv, so that it is the first thing
+     * to happen when the coro is resumed.
+     */
+
+    iPtr->execEnvPtr = corPtr->eePtr;
+    TclNREvalObjEx(interp, Tcl_NewListObj(objc-2, objv+2), 0, NULL, INT_MIN);
+    iPtr->execEnvPtr = savedEEPtr;
+
+    return TCL_OK;
+}
+
+int
+TclNRInterpCoroutine(
+    ClientData clientData,
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    CoroutineData *corPtr = clientData;
+
+    if (!COR_IS_SUSPENDED(corPtr)) {
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+                "coroutine \"%s\" is already running",
+                Tcl_GetString(objv[0])));
+	Tcl_SetErrorCode(interp, "TCL", "COROUTINE", "BUSY", NULL);
+	return TCL_ERROR;
+    }
+
+    /*
+     * Parse all the arguments to work out what to feed as the result of the
+     * [yield]. TRICKY POINT: objc==0 happens here! It occurs when a coroutine
+     * is deleted!
+     */
+
+    switch (corPtr->nargs) {
+    case COROUTINE_ARGUMENTS_SINGLE_OPTIONAL:
+        if (objc == 2) {
+            Tcl_SetObjResult(interp, objv[1]);
+        } else if (objc > 2) {
+            Tcl_WrongNumArgs(interp, 1, objv, "?arg?");
+            return TCL_ERROR;
+        }
+        break;
+    default:
+        if (corPtr->nargs != objc-1) {
+            Tcl_SetObjResult(interp,
+                    Tcl_NewStringObj("wrong coro nargs; how did we get here? "
+                    "not implemented!", -1));
+            Tcl_SetErrorCode(interp, "TCL", "WRONGARGS", NULL);
+            return TCL_ERROR;
+        }
+        /* fallthrough */
+    case COROUTINE_ARGUMENTS_ARBITRARY:
+        if (objc > 1) {
+            Tcl_SetObjResult(interp, Tcl_NewListObj(objc-1, objv+1));
+        }
+        break;
+    }
+
+    TclNRAddCallback(interp, TclNRCoroutineActivateCallback, corPtr,
+            NULL, NULL, NULL);
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclNRCoroutineObjCmd --
+ *
+ *      Implementation of [coroutine] command; see documentation for
+ *      description of what this does.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclNRCoroutineObjCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    Command *cmdPtr;
+    CoroutineData *corPtr;
+    const char *fullName, *procName;
+    Namespace *nsPtr, *altNsPtr, *cxtNsPtr;
+    Tcl_DString ds;
+    Namespace *lookupNsPtr = iPtr->varFramePtr->nsPtr;
+
+    if (objc < 3) {
+	Tcl_WrongNumArgs(interp, 1, objv, "name cmd ?arg ...?");
+	return TCL_ERROR;
+    }
+
+    /*
+     * FIXME: this is copy/pasted from Tcl_ProcObjCommand. Should have
+     * something in tclUtil.c to find the FQ name.
+     */
+
+    fullName = TclGetString(objv[1]);
+    TclGetNamespaceForQualName(interp, fullName, NULL, 0,
+	    &nsPtr, &altNsPtr, &cxtNsPtr, &procName);
+
+    if (nsPtr == NULL) {
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+                "can't create procedure \"%s\": unknown namespace",
+                fullName));
+        Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "NAMESPACE", NULL);
+	return TCL_ERROR;
+    }
+    if (procName == NULL) {
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+                "can't create procedure \"%s\": bad procedure name",
+                fullName));
+        Tcl_SetErrorCode(interp, "TCL", "VALUE", "COMMAND", fullName, NULL);
+	return TCL_ERROR;
+    }
+    if ((nsPtr != iPtr->globalNsPtr)
+	    && (procName != NULL) && (procName[0] == ':')) {
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+                "can't create procedure \"%s\" in non-global namespace with"
+                " name starting with \":\"", procName));
+        Tcl_SetErrorCode(interp, "TCL", "VALUE", "COMMAND", procName, NULL);
+	return TCL_ERROR;
+    }
+
+    /*
+     * We ARE creating the coroutine command: allocate the corresponding
+     * struct and create the corresponding command.
+     */
+
+    corPtr = ckalloc(sizeof(CoroutineData));
+
+    Tcl_DStringInit(&ds);
+    if (nsPtr != iPtr->globalNsPtr) {
+	Tcl_DStringAppend(&ds, nsPtr->fullName, -1);
+	TclDStringAppendLiteral(&ds, "::");
+    }
+    Tcl_DStringAppend(&ds, procName, -1);
+
+    cmdPtr = (Command *) Tcl_NRCreateCommand(interp, Tcl_DStringValue(&ds),
+	    /*objProc*/ NULL, TclNRInterpCoroutine, corPtr, DeleteCoroutine);
+    Tcl_DStringFree(&ds);
+
+    corPtr->cmdPtr = cmdPtr;
+    cmdPtr->refCount++;
+
+    /*
+     * #280.
+     * Provide the new coroutine with its own copy of the lineLABCPtr
+     * hashtable for literal command arguments in bytecode. Note that that
+     * CFWordBC chains are not duplicated, only the entrypoints to them. This
+     * means that in the presence of coroutines each chain is potentially a
+     * tree. Like the chain -> tree conversion of the CmdFrame stack.
+     */
+
+    {
+	Tcl_HashSearch hSearch;
+	Tcl_HashEntry *hePtr;
+
+	corPtr->lineLABCPtr = ckalloc(sizeof(Tcl_HashTable));
+	Tcl_InitHashTable(corPtr->lineLABCPtr, TCL_ONE_WORD_KEYS);
+
+	for (hePtr = Tcl_FirstHashEntry(iPtr->lineLABCPtr,&hSearch);
+		hePtr; hePtr = Tcl_NextHashEntry(&hSearch)) {
+	    int isNew;
+	    Tcl_HashEntry *newPtr =
+		    Tcl_CreateHashEntry(corPtr->lineLABCPtr,
+		    Tcl_GetHashKey(iPtr->lineLABCPtr, hePtr),
+		    &isNew);
+
+	    Tcl_SetHashValue(newPtr, Tcl_GetHashValue(hePtr));
+	}
+    }
+
+    /*
+     * Create the base context.
+     */
+
+    corPtr->running.framePtr = iPtr->rootFramePtr;
+    corPtr->running.varFramePtr = iPtr->rootFramePtr;
+    corPtr->running.cmdFramePtr = NULL;
+    corPtr->running.lineLABCPtr = corPtr->lineLABCPtr;
+    corPtr->stackLevel = NULL;
+    corPtr->auxNumLevels = 0;
+
+    /*
+     * Create the coro's execEnv, switch to it to push the exit and coro
+     * command callbacks, then switch back.
+     */
+
+    corPtr->eePtr = TclCreateExecEnv(interp, CORO_STACK_INITIAL_SIZE);
+    corPtr->callerEEPtr = iPtr->execEnvPtr;
+    corPtr->eePtr->corPtr = corPtr;
+
+    SAVE_CONTEXT(corPtr->caller);
+    corPtr->callerEEPtr = iPtr->execEnvPtr;
+    RESTORE_CONTEXT(corPtr->running);
+    iPtr->execEnvPtr = corPtr->eePtr;
+
+    TclNRAddCallback(interp, NRCoroutineExitCallback, corPtr,
+	    NULL, NULL, NULL);
+
+    /* insure that the command is looked up in the correct namespace */
+    iPtr->lookupNsPtr = lookupNsPtr;
+    Tcl_NREvalObj(interp, Tcl_NewListObj(objc-2, objv+2), 0);
+    iPtr->numLevels--;
+
+    SAVE_CONTEXT(corPtr->running);
+    RESTORE_CONTEXT(corPtr->caller);
+    iPtr->execEnvPtr = corPtr->callerEEPtr;
+
+    /*
+     * Now just resume the coroutine.
+     */
+
+    TclNRAddCallback(interp, TclNRCoroutineActivateCallback, corPtr,
+            NULL, NULL, NULL);
+    return TCL_OK;
+}
+
+/*
+ * This is used in the [info] ensemble
+ */
+
+int
+TclInfoCoroutineCmd(
+    ClientData dummy,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const objv[])
+{
+    CoroutineData *corPtr = iPtr->execEnvPtr->corPtr;
+
+    if (objc != 1) {
+	Tcl_WrongNumArgs(interp, 1, objv, NULL);
+	return TCL_ERROR;
+    }
+
+    if (corPtr && !(corPtr->cmdPtr->flags & CMD_IS_DELETED)) {
+	Tcl_Obj *namePtr;
+
+	TclNewObj(namePtr);
+	Tcl_GetCommandFullName(interp, (Tcl_Command) corPtr->cmdPtr, namePtr);
+	Tcl_SetObjResult(interp, namePtr);
+    }
+    return TCL_OK;
+}
+
+#undef iPtr
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/generic/tclBinary.c b/generic/tclBinary.c
new file mode 100644
index 0000000..981f174
--- /dev/null
+++ b/generic/tclBinary.c
@@ -0,0 +1,2988 @@
+/*
+ * tclBinary.c --
+ *
+ *	This file contains the implementation of the "binary" Tcl built-in
+ *	command and the Tcl binary data object.
+ *
+ * Copyright (c) 1997 by Sun Microsystems, Inc.
+ * Copyright (c) 1998-1999 by Scriptics Corporation.
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#include "tclInt.h"
+#include "tommath.h"
+
+#include <math.h>
+
+/*
+ * The following constants are used by GetFormatSpec to indicate various
+ * special conditions in the parsing of a format specifier.
+ */
+
+#define BINARY_ALL -1		/* Use all elements in the argument. */
+#define BINARY_NOCOUNT -2	/* No count was specified in format. */
+
+/*
+ * The following flags may be ORed together and returned by GetFormatSpec
+ */
+
+#define BINARY_SIGNED 0		/* Field to be read as signed data */
+#define BINARY_UNSIGNED 1	/* Field to be read as unsigned data */
+
+/*
+ * The following defines the maximum number of different (integer) numbers
+ * placed in the object cache by 'binary scan' before it bails out and
+ * switches back to Plan A (creating a new object for each value.)
+ * Theoretically, it would be possible to keep the cache about for the values
+ * that are already in it, but that makes the code slower in practise when
+ * overflow happens, and makes little odds the rest of the time (as measured
+ * on my machine.) It is also slower (on the sample I tried at least) to grow
+ * the cache to hold all items we might want to put in it; presumably the
+ * extra cost of managing the memory for the enlarged table outweighs the
+ * benefit from allocating fewer objects. This is probably because as the
+ * number of objects increases, the likelihood of reuse of any particular one
+ * drops, and there is very little gain from larger maximum cache sizes (the
+ * value below is chosen to allow caching to work in full with conversion of
+ * bytes.) - DKF
+ */
+
+#define BINARY_SCAN_MAX_CACHE	260
+
+/*
+ * Prototypes for local procedures defined in this file:
+ */
+
+static void		DupByteArrayInternalRep(Tcl_Obj *srcPtr,
+			    Tcl_Obj *copyPtr);
+static int		FormatNumber(Tcl_Interp *interp, int type,
+			    Tcl_Obj *src, unsigned char **cursorPtr);
+static void		FreeByteArrayInternalRep(Tcl_Obj *objPtr);
+static int		GetFormatSpec(const char **formatPtr, char *cmdPtr,
+			    int *countPtr, int *flagsPtr);
+static Tcl_Obj *	ScanNumber(unsigned char *buffer, int type,
+			    int flags, Tcl_HashTable **numberCachePtr);
+static int		SetByteArrayFromAny(Tcl_Interp *interp,
+			    Tcl_Obj *objPtr);
+static void		UpdateStringOfByteArray(Tcl_Obj *listPtr);
+static void		DeleteScanNumberCache(Tcl_HashTable *numberCachePtr);
+static int		NeedReversing(int format);
+static void		CopyNumber(const void *from, void *to,
+			    unsigned length, int type);
+/* Binary ensemble commands */
+static int		BinaryFormatCmd(ClientData clientData,
+			    Tcl_Interp *interp,
+			    int objc, Tcl_Obj *const objv[]);
+static int		BinaryScanCmd(ClientData clientData,
+			    Tcl_Interp *interp,
+			    int objc, Tcl_Obj *const objv[]);
+/* Binary encoding sub-ensemble commands */
+static int		BinaryEncodeHex(ClientData clientData,
+			    Tcl_Interp *interp,
+			    int objc, Tcl_Obj *const objv[]);
+static int		BinaryDecodeHex(ClientData clientData,
+			    Tcl_Interp *interp,
+			    int objc, Tcl_Obj *const objv[]);
+static int		BinaryEncode64(ClientData clientData,
+			    Tcl_Interp *interp,
+			    int objc, Tcl_Obj *const objv[]);
+static int		BinaryDecode64(ClientData clientData,
+			    Tcl_Interp *interp,
+			    int objc, Tcl_Obj *const objv[]);
+static int		BinaryEncodeUu(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+static int		BinaryDecodeUu(ClientData clientData,
+			    Tcl_Interp *interp,
+			    int objc, Tcl_Obj *const objv[]);
+
+/*
+ * The following tables are used by the binary encoders
+ */
+
+static const char HexDigits[16] = {
+    '0', '1', '2', '3', '4', '5', '6', '7',
+    '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
+};
+
+static const char UueDigits[65] = {
+    '`', '!', '"', '#', '$', '%', '&', '\'',
+    '(', ')', '*', '+', ',', '-', '.', '/',
+    '0', '1', '2', '3', '4', '5', '6', '7',
+    '8', '9', ':', ';', '<', '=', '>', '?',
+    '@', 'A', 'B', 'C', 'D', 'E', 'F', 'G',
+    'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
+    'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
+    'X', 'Y', 'Z', '[', '\\',']', '^', '_',
+    '`'
+};
+
+static const char B64Digits[65] = {
+    'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
+    'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
+    'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
+    'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
+    'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
+    'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
+    'w', 'x', 'y', 'z', '0', '1', '2', '3',
+    '4', '5', '6', '7', '8', '9', '+', '/',
+    '='
+};
+
+/*
+ * How to construct the ensembles.
+ */
+
+static const EnsembleImplMap binaryMap[] = {
+    { "format", BinaryFormatCmd, TclCompileBasicMin1ArgCmd, NULL, NULL, 0 },
+    { "scan",   BinaryScanCmd, TclCompileBasicMin2ArgCmd, NULL, NULL, 0 },
+    { "encode", NULL, NULL, NULL, NULL, 0 },
+    { "decode", NULL, NULL, NULL, NULL, 0 },
+    { NULL, NULL, NULL, NULL, NULL, 0 }
+};
+static const EnsembleImplMap encodeMap[] = {
+    { "hex",      BinaryEncodeHex, TclCompileBasic1ArgCmd, NULL, NULL, 0 },
+    { "uuencode", BinaryEncodeUu,  NULL, NULL, NULL, 0 },
+    { "base64",   BinaryEncode64,  NULL, NULL, NULL, 0 },
+    { NULL, NULL, NULL, NULL, NULL, 0 }
+};
+static const EnsembleImplMap decodeMap[] = {
+    { "hex",      BinaryDecodeHex, TclCompileBasic1Or2ArgCmd, NULL, NULL, 0 },
+    { "uuencode", BinaryDecodeUu,  TclCompileBasic1Or2ArgCmd, NULL, NULL, 0 },
+    { "base64",   BinaryDecode64,  TclCompileBasic1Or2ArgCmd, NULL, NULL, 0 },
+    { NULL, NULL, NULL, NULL, NULL, 0 }
+};
+
+/*
+ * The following object type represents an array of bytes. An array of bytes
+ * is not equivalent to an internationalized string. Conceptually, a string is
+ * an array of 16-bit quantities organized as a sequence of properly formed
+ * UTF-8 characters, while a ByteArray is an array of 8-bit quantities.
+ * Accessor functions are provided to convert a ByteArray to a String or a
+ * String to a ByteArray. Two or more consecutive bytes in an array of bytes
+ * may look like a single UTF-8 character if the array is casually treated as
+ * a string. But obtaining the String from a ByteArray is guaranteed to
+ * produced properly formed UTF-8 sequences so that there is a one-to-one map
+ * between bytes and characters.
+ *
+ * Converting a ByteArray to a String proceeds by casting each byte in the
+ * array to a 16-bit quantity, treating that number as a Unicode character,
+ * and storing the UTF-8 version of that Unicode character in the String. For
+ * ByteArrays consisting entirely of values 1..127, the corresponding String
+ * representation is the same as the ByteArray representation.
+ *
+ * Converting a String to a ByteArray proceeds by getting the Unicode
+ * representation of each character in the String, casting it to a byte by
+ * truncating the upper 8 bits, and then storing the byte in the ByteArray.
+ * Converting from ByteArray to String and back to ByteArray is not lossy, but
+ * converting an arbitrary String to a ByteArray may be.
+ */
+
+const Tcl_ObjType tclByteArrayType = {
+    "bytearray",
+    FreeByteArrayInternalRep,
+    DupByteArrayInternalRep,
+    UpdateStringOfByteArray,
+    SetByteArrayFromAny
+};
+
+/*
+ * The following structure is the internal rep for a ByteArray object. Keeps
+ * track of how much memory has been used and how much has been allocated for
+ * the byte array to enable growing and shrinking of the ByteArray object with
+ * fewer mallocs.
+ */
+
+typedef struct ByteArray {
+    int used;			/* The number of bytes used in the byte
+				 * array. */
+    int allocated;		/* The amount of space actually allocated
+				 * minus 1 byte. */
+    unsigned char bytes[1];	/* The array of bytes. The actual size of this
+				 * field depends on the 'allocated' field
+				 * above. */
+} ByteArray;
+
+#define BYTEARRAY_SIZE(len) \
+		((unsigned) (TclOffset(ByteArray, bytes) + (len)))
+#define GET_BYTEARRAY(objPtr) \
+		((ByteArray *) (objPtr)->internalRep.twoPtrValue.ptr1)
+#define SET_BYTEARRAY(objPtr, baPtr) \
+		(objPtr)->internalRep.twoPtrValue.ptr1 = (void *) (baPtr)
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_NewByteArrayObj --
+ *
+ *	This procedure is creates a new ByteArray object and initializes it
+ *	from the given array of bytes.
+ *
+ * Results:
+ *	The newly create object is returned. This object will have no initial
+ *	string representation. The returned object has a ref count of 0.
+ *
+ * Side effects:
+ *	Memory allocated for new object and copy of byte array argument.
+ *
+ *----------------------------------------------------------------------
+ */
+
+#undef Tcl_NewByteArrayObj
+
+Tcl_Obj *
+Tcl_NewByteArrayObj(
+    const unsigned char *bytes,	/* The array of bytes used to initialize the
+				 * new object. */
+    int length)			/* Length of the array of bytes, which must be
+				 * >= 0. */
+{
+#ifdef TCL_MEM_DEBUG
+    return Tcl_DbNewByteArrayObj(bytes, length, "unknown", 0);
+#else /* if not TCL_MEM_DEBUG */
+    Tcl_Obj *objPtr;
+
+    TclNewObj(objPtr);
+    Tcl_SetByteArrayObj(objPtr, bytes, length);
+    return objPtr;
+#endif /* TCL_MEM_DEBUG */
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_DbNewByteArrayObj --
+ *
+ *	This procedure is normally called when debugging: i.e., when
+ *	TCL_MEM_DEBUG is defined. It is the same as the Tcl_NewByteArrayObj
+ *	above except that it calls Tcl_DbCkalloc directly with the file name
+ *	and line number from its caller. This simplifies debugging since then
+ *	the [memory active] command will report the correct file name and line
+ *	number when reporting objects that haven't been freed.
+ *
+ *	When TCL_MEM_DEBUG is not defined, this procedure just returns the
+ *	result of calling Tcl_NewByteArrayObj.
+ *
+ * Results:
+ *	The newly create object is returned. This object will have no initial
+ *	string representation. The returned object has a ref count of 0.
+ *
+ * Side effects:
+ *	Memory allocated for new object and copy of byte array argument.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_Obj *
+Tcl_DbNewByteArrayObj(
+    const unsigned char *bytes,	/* The array of bytes used to initialize the
+				 * new object. */
+    int length,			/* Length of the array of bytes, which must be
+				 * >= 0. */
+    const char *file,		/* The name of the source file calling this
+				 * procedure; used for debugging. */
+    int line)			/* Line number in the source file; used for
+				 * debugging. */
+{
+#ifdef TCL_MEM_DEBUG
+    Tcl_Obj *objPtr;
+
+    TclDbNewObj(objPtr, file, line);
+    Tcl_SetByteArrayObj(objPtr, bytes, length);
+    return objPtr;
+#else /* if not TCL_MEM_DEBUG */
+    return Tcl_NewByteArrayObj(bytes, length);
+#endif /* TCL_MEM_DEBUG */
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Tcl_SetByteArrayObj --
+ *
+ *	Modify an object to be a ByteArray object and to have the specified
+ *	array of bytes as its value.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The object's old string rep and internal rep is freed. Memory
+ *	allocated for copy of byte array argument.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_SetByteArrayObj(
+    Tcl_Obj *objPtr,		/* Object to initialize as a ByteArray. */
+    const unsigned char *bytes,	/* The array of bytes to use as the new
+				   value. May be NULL even if length > 0. */
+    int length)			/* Length of the array of bytes, which must
+				   be >= 0. */
+{
+    ByteArray *byteArrayPtr;
+
+    if (Tcl_IsShared(objPtr)) {
+	Tcl_Panic("%s called with shared object", "Tcl_SetByteArrayObj");
+    }
+    TclFreeIntRep(objPtr);
+    TclInvalidateStringRep(objPtr);
+
+    if (length < 0) {
+	length = 0;
+    }
+    byteArrayPtr = ckalloc(BYTEARRAY_SIZE(length));
+    byteArrayPtr->used = length;
+    byteArrayPtr->allocated = length;
+
+    if ((bytes != NULL) && (length > 0)) {
+	memcpy(byteArrayPtr->bytes, bytes, (size_t) length);
+    }
+    objPtr->typePtr = &tclByteArrayType;
+    SET_BYTEARRAY(objPtr, byteArrayPtr);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_GetByteArrayFromObj --
+ *
+ *	Attempt to get the array of bytes from the Tcl object. If the object
+ *	is not already a ByteArray object, an attempt will be made to convert
+ *	it to one.
+ *
+ * Results:
+ *	Pointer to array of bytes representing the ByteArray object.
+ *
+ * Side effects:
+ *	Frees old internal rep. Allocates memory for new internal rep.
+ *
+ *----------------------------------------------------------------------
+ */
+
+unsigned char *
+Tcl_GetByteArrayFromObj(
+    Tcl_Obj *objPtr,		/* The ByteArray object. */
+    int *lengthPtr)		/* If non-NULL, filled with length of the
+				 * array of bytes in the ByteArray object. */
+{
+    ByteArray *baPtr;
+
+    if (objPtr->typePtr != &tclByteArrayType) {
+	SetByteArrayFromAny(NULL, objPtr);
+    }
+    baPtr = GET_BYTEARRAY(objPtr);
+
+    if (lengthPtr != NULL) {
+	*lengthPtr = baPtr->used;
+    }
+    return (unsigned char *) baPtr->bytes;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_SetByteArrayLength --
+ *
+ *	This procedure changes the length of the byte array for this object.
+ *	Once the caller has set the length of the array, it is acceptable to
+ *	directly modify the bytes in the array up until Tcl_GetStringFromObj()
+ *	has been called on this object.
+ *
+ * Results:
+ *	The new byte array of the specified length.
+ *
+ * Side effects:
+ *	Allocates enough memory for an array of bytes of the requested size.
+ *	When growing the array, the old array is copied to the new array; new
+ *	bytes are undefined. When shrinking, the old array is truncated to the
+ *	specified length.
+ *
+ *----------------------------------------------------------------------
+ */
+
+unsigned char *
+Tcl_SetByteArrayLength(
+    Tcl_Obj *objPtr,		/* The ByteArray object. */
+    int length)			/* New length for internal byte array. */
+{
+    ByteArray *byteArrayPtr;
+
+    if (Tcl_IsShared(objPtr)) {
+	Tcl_Panic("%s called with shared object", "Tcl_SetByteArrayLength");
+    }
+    if (objPtr->typePtr != &tclByteArrayType) {
+	SetByteArrayFromAny(NULL, objPtr);
+    }
+
+    byteArrayPtr = GET_BYTEARRAY(objPtr);
+    if (length > byteArrayPtr->allocated) {
+	byteArrayPtr = ckrealloc(byteArrayPtr, BYTEARRAY_SIZE(length));
+	byteArrayPtr->allocated = length;
+	SET_BYTEARRAY(objPtr, byteArrayPtr);
+    }
+    TclInvalidateStringRep(objPtr);
+    byteArrayPtr->used = length;
+    return byteArrayPtr->bytes;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * SetByteArrayFromAny --
+ *
+ *	Generate the ByteArray internal rep from the string rep.
+ *
+ * Results:
+ *	The return value is always TCL_OK.
+ *
+ * Side effects:
+ *	A ByteArray object is stored as the internal rep of objPtr.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+SetByteArrayFromAny(
+    Tcl_Interp *interp,		/* Not used. */
+    Tcl_Obj *objPtr)		/* The object to convert to type ByteArray. */
+{
+    int length;
+    const char *src, *srcEnd;
+    unsigned char *dst;
+    ByteArray *byteArrayPtr;
+    Tcl_UniChar ch;
+
+    if (objPtr->typePtr != &tclByteArrayType) {
+	src = TclGetStringFromObj(objPtr, &length);
+	srcEnd = src + length;
+
+	byteArrayPtr = ckalloc(BYTEARRAY_SIZE(length));
+	for (dst = byteArrayPtr->bytes; src < srcEnd; ) {
+	    src += Tcl_UtfToUniChar(src, &ch);
+	    *dst++ = UCHAR(ch);
+	}
+
+	byteArrayPtr->used = dst - byteArrayPtr->bytes;
+	byteArrayPtr->allocated = length;
+
+	TclFreeIntRep(objPtr);
+	objPtr->typePtr = &tclByteArrayType;
+	SET_BYTEARRAY(objPtr, byteArrayPtr);
+    }
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * FreeByteArrayInternalRep --
+ *
+ *	Deallocate the storage associated with a ByteArray data object's
+ *	internal representation.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Frees memory.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+FreeByteArrayInternalRep(
+    Tcl_Obj *objPtr)		/* Object with internal rep to free. */
+{
+    ckfree(GET_BYTEARRAY(objPtr));
+    objPtr->typePtr = NULL;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * DupByteArrayInternalRep --
+ *
+ *	Initialize the internal representation of a ByteArray Tcl_Obj to a
+ *	copy of the internal representation of an existing ByteArray object.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Allocates memory.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+DupByteArrayInternalRep(
+    Tcl_Obj *srcPtr,		/* Object with internal rep to copy. */
+    Tcl_Obj *copyPtr)		/* Object with internal rep to set. */
+{
+    int length;
+    ByteArray *srcArrayPtr, *copyArrayPtr;
+
+    srcArrayPtr = GET_BYTEARRAY(srcPtr);
+    length = srcArrayPtr->used;
+
+    copyArrayPtr = ckalloc(BYTEARRAY_SIZE(length));
+    copyArrayPtr->used = length;
+    copyArrayPtr->allocated = length;
+    memcpy(copyArrayPtr->bytes, srcArrayPtr->bytes, (size_t) length);
+    SET_BYTEARRAY(copyPtr, copyArrayPtr);
+
+    copyPtr->typePtr = &tclByteArrayType;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * UpdateStringOfByteArray --
+ *
+ *	Update the string representation for a ByteArray data object. Note:
+ *	This procedure does not invalidate an existing old string rep so
+ *	storage will be lost if this has not already been done.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The object's string is set to a valid string that results from the
+ *	ByteArray-to-string conversion.
+ *
+ *	The object becomes a string object -- the internal rep is discarded
+ *	and the typePtr becomes NULL.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+UpdateStringOfByteArray(
+    Tcl_Obj *objPtr)		/* ByteArray object whose string rep to
+				 * update. */
+{
+    int i, length, size;
+    unsigned char *src;
+    char *dst;
+    ByteArray *byteArrayPtr;
+
+    byteArrayPtr = GET_BYTEARRAY(objPtr);
+    src = byteArrayPtr->bytes;
+    length = byteArrayPtr->used;
+
+    /*
+     * How much space will string rep need?
+     */
+
+    size = length;
+    for (i = 0; i < length && size >= 0; i++) {
+	if ((src[i] == 0) || (src[i] > 127)) {
+	    size++;
+	}
+    }
+    if (size < 0) {
+	Tcl_Panic("max size for a Tcl value (%d bytes) exceeded", INT_MAX);
+    }
+
+    dst = ckalloc(size + 1);
+    objPtr->bytes = dst;
+    objPtr->length = size;
+
+    if (size == length) {
+	memcpy(dst, src, (size_t) size);
+	dst[size] = '\0';
+    } else {
+	for (i = 0; i < length; i++) {
+	    dst += Tcl_UniCharToUtf(src[i], dst);
+	}
+	*dst = '\0';
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclAppendBytesToByteArray --
+ *
+ *	This function appends an array of bytes to a byte array object. Note
+ *	that the object *must* be unshared, and the array of bytes *must not*
+ *	refer to the object being appended to.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Allocates enough memory for an array of bytes of the requested total
+ *	size, or possibly larger. [Bug 2992970]
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclAppendBytesToByteArray(
+    Tcl_Obj *objPtr,
+    const unsigned char *bytes,
+    int len)
+{
+    ByteArray *byteArrayPtr;
+    int needed;
+
+    if (Tcl_IsShared(objPtr)) {
+	Tcl_Panic("%s called with shared object","TclAppendBytesToByteArray");
+    }
+    if (len < 0) {
+	Tcl_Panic("%s must be called with definite number of bytes to append",
+		"TclAppendBytesToByteArray");
+    }
+    if (len == 0) {
+	/* Append zero bytes is a no-op. */
+	return;
+    }
+    if (objPtr->typePtr != &tclByteArrayType) {
+	SetByteArrayFromAny(NULL, objPtr);
+    }
+    byteArrayPtr = GET_BYTEARRAY(objPtr);
+
+    if (len > INT_MAX - byteArrayPtr->used) {
+	Tcl_Panic("max size for a Tcl value (%d bytes) exceeded", INT_MAX);
+    }
+
+    needed = byteArrayPtr->used + len;
+    /*
+     * If we need to, resize the allocated space in the byte array.
+     */
+
+    if (needed > byteArrayPtr->allocated) {
+	ByteArray *ptr = NULL;
+	int attempt;
+
+	if (needed <= INT_MAX/2) {
+	    /* Try to allocate double the total space that is needed. */
+	    attempt = 2 * needed;
+	    ptr = attemptckrealloc(byteArrayPtr, BYTEARRAY_SIZE(attempt));
+	}
+	if (ptr == NULL) {
+	    /* Try to allocate double the increment that is needed (plus). */
+	    unsigned int limit = INT_MAX - needed;
+	    unsigned int extra = len + TCL_MIN_GROWTH;
+	    int growth = (int) ((extra > limit) ? limit : extra);
+
+	    attempt = needed + growth;
+	    ptr = attemptckrealloc(byteArrayPtr, BYTEARRAY_SIZE(attempt));
+	}
+	if (ptr == NULL) {
+	    /* Last chance: Try to allocate exactly what is needed. */
+	    attempt = needed;
+	    ptr = ckrealloc(byteArrayPtr, BYTEARRAY_SIZE(attempt));
+	}
+	byteArrayPtr = ptr;
+	byteArrayPtr->allocated = attempt;
+	SET_BYTEARRAY(objPtr, byteArrayPtr);
+    }
+
+    if (bytes) {
+	memcpy(byteArrayPtr->bytes + byteArrayPtr->used, bytes, len);
+    }
+    byteArrayPtr->used += len;
+    TclInvalidateStringRep(objPtr);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclInitBinaryCmd --
+ *
+ *	This function is called to create the "binary" Tcl command. See the
+ *	user documentation for details on what it does.
+ *
+ * Results:
+ *	A command token for the new command.
+ *
+ * Side effects:
+ *	Creates a new binary command as a mapped ensemble.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_Command
+TclInitBinaryCmd(
+    Tcl_Interp *interp)
+{
+    Tcl_Command binaryEnsemble;
+
+    binaryEnsemble = TclMakeEnsemble(interp, "binary", binaryMap);
+    TclMakeEnsemble(interp, "binary encode", encodeMap);
+    TclMakeEnsemble(interp, "binary decode", decodeMap);
+    return binaryEnsemble;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * BinaryFormatCmd --
+ *
+ *	This procedure implements the "binary format" Tcl command.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+BinaryFormatCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    int arg;			/* Index of next argument to consume. */
+    int value = 0;		/* Current integer value to be packed.
+				 * Initialized to avoid compiler warning. */
+    char cmd;			/* Current format character. */
+    int count;			/* Count associated with current format
+				 * character. */
+    int flags;			/* Format field flags */
+    const char *format;	/* Pointer to current position in format
+				 * string. */
+    Tcl_Obj *resultPtr = NULL;	/* Object holding result buffer. */
+    unsigned char *buffer;	/* Start of result buffer. */
+    unsigned char *cursor;	/* Current position within result buffer. */
+    unsigned char *maxPos;	/* Greatest position within result buffer that
+				 * cursor has visited.*/
+    const char *errorString;
+    const char *errorValue, *str;
+    int offset, size, length;
+
+    if (objc < 2) {
+	Tcl_WrongNumArgs(interp, 1, objv, "formatString ?arg ...?");
+	return TCL_ERROR;
+    }
+
+    /*
+     * To avoid copying the data, we format the string in two passes. The
+     * first pass computes the size of the output buffer. The second pass
+     * places the formatted data into the buffer.
+     */
+
+    format = TclGetString(objv[1]);
+    arg = 2;
+    offset = 0;
+    length = 0;
+    while (*format != '\0') {
+	str = format;
+	flags = 0;
+	if (!GetFormatSpec(&format, &cmd, &count, &flags)) {
+	    break;
+	}
+	switch (cmd) {
+	case 'a':
+	case 'A':
+	case 'b':
+	case 'B':
+	case 'h':
+	case 'H':
+	    /*
+	     * For string-type specifiers, the count corresponds to the number
+	     * of bytes in a single argument.
+	     */
+
+	    if (arg >= objc) {
+		goto badIndex;
+	    }
+	    if (count == BINARY_ALL) {
+		Tcl_GetByteArrayFromObj(objv[arg], &count);
+	    } else if (count == BINARY_NOCOUNT) {
+		count = 1;
+	    }
+	    arg++;
+	    if (cmd == 'a' || cmd == 'A') {
+		offset += count;
+	    } else if (cmd == 'b' || cmd == 'B') {
+		offset += (count + 7) / 8;
+	    } else {
+		offset += (count + 1) / 2;
+	    }
+	    break;
+	case 'c':
+	    size = 1;
+	    goto doNumbers;
+	case 't':
+	case 's':
+	case 'S':
+	    size = 2;
+	    goto doNumbers;
+	case 'n':
+	case 'i':
+	case 'I':
+	    size = 4;
+	    goto doNumbers;
+	case 'm':
+	case 'w':
+	case 'W':
+	    size = 8;
+	    goto doNumbers;
+	case 'r':
+	case 'R':
+	case 'f':
+	    size = sizeof(float);
+	    goto doNumbers;
+	case 'q':
+	case 'Q':
+	case 'd':
+	    size = sizeof(double);
+
+	doNumbers:
+	    if (arg >= objc) {
+		goto badIndex;
+	    }
+
+	    /*
+	     * For number-type specifiers, the count corresponds to the number
+	     * of elements in the list stored in a single argument. If no
+	     * count is specified, then the argument is taken as a single
+	     * non-list value.
+	     */
+
+	    if (count == BINARY_NOCOUNT) {
+		arg++;
+		count = 1;
+	    } else {
+		int listc;
+		Tcl_Obj **listv;
+
+		/*
+		 * The macro evals its args more than once: avoid arg++
+		 */
+
+		if (TclListObjGetElements(interp, objv[arg], &listc,
+			&listv) != TCL_OK) {
+		    return TCL_ERROR;
+		}
+		arg++;
+
+		if (count == BINARY_ALL) {
+		    count = listc;
+		} else if (count > listc) {
+		    Tcl_SetObjResult(interp, Tcl_NewStringObj(
+			    "number of elements in list does not match count",
+			    -1));
+		    return TCL_ERROR;
+		}
+	    }
+	    offset += count*size;
+	    break;
+
+	case 'x':
+	    if (count == BINARY_ALL) {
+		Tcl_SetObjResult(interp, Tcl_NewStringObj(
+			"cannot use \"*\" in format string with \"x\"", -1));
+		return TCL_ERROR;
+	    } else if (count == BINARY_NOCOUNT) {
+		count = 1;
+	    }
+	    offset += count;
+	    break;
+	case 'X':
+	    if (count == BINARY_NOCOUNT) {
+		count = 1;
+	    }
+	    if ((count > offset) || (count == BINARY_ALL)) {
+		count = offset;
+	    }
+	    if (offset > length) {
+		length = offset;
+	    }
+	    offset -= count;
+	    break;
+	case '@':
+	    if (offset > length) {
+		length = offset;
+	    }
+	    if (count == BINARY_ALL) {
+		offset = length;
+	    } else if (count == BINARY_NOCOUNT) {
+		goto badCount;
+	    } else {
+		offset = count;
+	    }
+	    break;
+	default:
+	    errorString = str;
+	    goto badField;
+	}
+    }
+    if (offset > length) {
+	length = offset;
+    }
+    if (length == 0) {
+	return TCL_OK;
+    }
+
+    /*
+     * Prepare the result object by preallocating the caclulated number of
+     * bytes and filling with nulls.
+     */
+
+    resultPtr = Tcl_NewObj();
+    buffer = Tcl_SetByteArrayLength(resultPtr, length);
+    memset(buffer, 0, (size_t) length);
+
+    /*
+     * Pack the data into the result object. Note that we can skip the
+     * error checking during this pass, since we have already parsed the
+     * string once.
+     */
+
+    arg = 2;
+    format = TclGetString(objv[1]);
+    cursor = buffer;
+    maxPos = cursor;
+    while (*format != 0) {
+	flags = 0;
+	if (!GetFormatSpec(&format, &cmd, &count, &flags)) {
+	    break;
+	}
+	if ((count == 0) && (cmd != '@')) {
+	    if (cmd != 'x') {
+		arg++;
+	    }
+	    continue;
+	}
+	switch (cmd) {
+	case 'a':
+	case 'A': {
+	    char pad = (char) (cmd == 'a' ? '\0' : ' ');
+	    unsigned char *bytes;
+
+	    bytes = Tcl_GetByteArrayFromObj(objv[arg++], &length);
+
+	    if (count == BINARY_ALL) {
+		count = length;
+	    } else if (count == BINARY_NOCOUNT) {
+		count = 1;
+	    }
+	    if (length >= count) {
+		memcpy(cursor, bytes, (size_t) count);
+	    } else {
+		memcpy(cursor, bytes, (size_t) length);
+		memset(cursor + length, pad, (size_t) (count - length));
+	    }
+	    cursor += count;
+	    break;
+	}
+	case 'b':
+	case 'B': {
+	    unsigned char *last;
+
+	    str = TclGetStringFromObj(objv[arg], &length);
+	    arg++;
+	    if (count == BINARY_ALL) {
+		count = length;
+	    } else if (count == BINARY_NOCOUNT) {
+		count = 1;
+	    }
+	    last = cursor + ((count + 7) / 8);
+	    if (count > length) {
+		count = length;
+	    }
+	    value = 0;
+	    errorString = "binary";
+	    if (cmd == 'B') {
+		for (offset = 0; offset < count; offset++) {
+		    value <<= 1;
+		    if (str[offset] == '1') {
+			value |= 1;
+		    } else if (str[offset] != '0') {
+			errorValue = str;
+			Tcl_DecrRefCount(resultPtr);
+			goto badValue;
+		    }
+		    if (((offset + 1) % 8) == 0) {
+			*cursor++ = UCHAR(value);
+			value = 0;
+		    }
+		}
+	    } else {
+		for (offset = 0; offset < count; offset++) {
+		    value >>= 1;
+		    if (str[offset] == '1') {
+			value |= 128;
+		    } else if (str[offset] != '0') {
+			errorValue = str;
+			Tcl_DecrRefCount(resultPtr);
+			goto badValue;
+		    }
+		    if (!((offset + 1) % 8)) {
+			*cursor++ = UCHAR(value);
+			value = 0;
+		    }
+		}
+	    }
+	    if ((offset % 8) != 0) {
+		if (cmd == 'B') {
+		    value <<= 8 - (offset % 8);
+		} else {
+		    value >>= 8 - (offset % 8);
+		}
+		*cursor++ = UCHAR(value);
+	    }
+	    while (cursor < last) {
+		*cursor++ = '\0';
+	    }
+	    break;
+	}
+	case 'h':
+	case 'H': {
+	    unsigned char *last;
+	    int c;
+
+	    str = TclGetStringFromObj(objv[arg], &length);
+	    arg++;
+	    if (count == BINARY_ALL) {
+		count = length;
+	    } else if (count == BINARY_NOCOUNT) {
+		count = 1;
+	    }
+	    last = cursor + ((count + 1) / 2);
+	    if (count > length) {
+		count = length;
+	    }
+	    value = 0;
+	    errorString = "hexadecimal";
+	    if (cmd == 'H') {
+		for (offset = 0; offset < count; offset++) {
+		    value <<= 4;
+		    if (!isxdigit(UCHAR(str[offset]))) {     /* INTL: digit */
+			errorValue = str;
+			Tcl_DecrRefCount(resultPtr);
+			goto badValue;
+		    }
+		    c = str[offset] - '0';
+		    if (c > 9) {
+			c += ('0' - 'A') + 10;
+		    }
+		    if (c > 16) {
+			c += ('A' - 'a');
+		    }
+		    value |= (c & 0xf);
+		    if (offset % 2) {
+			*cursor++ = (char) value;
+			value = 0;
+		    }
+		}
+	    } else {
+		for (offset = 0; offset < count; offset++) {
+		    value >>= 4;
+
+		    if (!isxdigit(UCHAR(str[offset]))) {     /* INTL: digit */
+			errorValue = str;
+			Tcl_DecrRefCount(resultPtr);
+			goto badValue;
+		    }
+		    c = str[offset] - '0';
+		    if (c > 9) {
+			c += ('0' - 'A') + 10;
+		    }
+		    if (c > 16) {
+			c += ('A' - 'a');
+		    }
+		    value |= ((c << 4) & 0xf0);
+		    if (offset % 2) {
+			*cursor++ = UCHAR(value & 0xff);
+			value = 0;
+		    }
+		}
+	    }
+	    if (offset % 2) {
+		if (cmd == 'H') {
+		    value <<= 4;
+		} else {
+		    value >>= 4;
+		}
+		*cursor++ = UCHAR(value);
+	    }
+
+	    while (cursor < last) {
+		*cursor++ = '\0';
+	    }
+	    break;
+	}
+	case 'c':
+	case 't':
+	case 's':
+	case 'S':
+	case 'n':
+	case 'i':
+	case 'I':
+	case 'm':
+	case 'w':
+	case 'W':
+	case 'r':
+	case 'R':
+	case 'd':
+	case 'q':
+	case 'Q':
+	case 'f': {
+	    int listc, i;
+	    Tcl_Obj **listv;
+
+	    if (count == BINARY_NOCOUNT) {
+		/*
+		 * Note that we are casting away the const-ness of objv, but
+		 * this is safe since we aren't going to modify the array.
+		 */
+
+		listv = (Tcl_Obj **) (objv + arg);
+		listc = 1;
+		count = 1;
+	    } else {
+		TclListObjGetElements(interp, objv[arg], &listc, &listv);
+		if (count == BINARY_ALL) {
+		    count = listc;
+		}
+	    }
+	    arg++;
+	    for (i = 0; i < count; i++) {
+		if (FormatNumber(interp, cmd, listv[i], &cursor)!=TCL_OK) {
+		    Tcl_DecrRefCount(resultPtr);
+		    return TCL_ERROR;
+		}
+	    }
+	    break;
+	}
+	case 'x':
+	    if (count == BINARY_NOCOUNT) {
+		count = 1;
+	    }
+	    memset(cursor, 0, (size_t) count);
+	    cursor += count;
+	    break;
+	case 'X':
+	    if (cursor > maxPos) {
+		maxPos = cursor;
+	    }
+	    if (count == BINARY_NOCOUNT) {
+		count = 1;
+	    }
+	    if ((count == BINARY_ALL) || (count > (cursor - buffer))) {
+		cursor = buffer;
+	    } else {
+		cursor -= count;
+	    }
+	    break;
+	case '@':
+	    if (cursor > maxPos) {
+		maxPos = cursor;
+	    }
+	    if (count == BINARY_ALL) {
+		cursor = maxPos;
+	    } else {
+		cursor = buffer + count;
+	    }
+	    break;
+	}
+    }
+    Tcl_SetObjResult(interp, resultPtr);
+    return TCL_OK;
+
+ badValue:
+    Tcl_ResetResult(interp);
+    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+	    "expected %s string but got \"%s\" instead",
+	    errorString, errorValue));
+    return TCL_ERROR;
+
+ badCount:
+    errorString = "missing count for \"@\" field specifier";
+    goto error;
+
+ badIndex:
+    errorString = "not enough arguments for all format specifiers";
+    goto error;
+
+ badField:
+    {
+	Tcl_UniChar ch;
+	char buf[TCL_UTF_MAX + 1];
+
+	Tcl_UtfToUniChar(errorString, &ch);
+	buf[Tcl_UniCharToUtf(ch, buf)] = '\0';
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		"bad field specifier \"%s\"", buf));
+	return TCL_ERROR;
+    }
+
+ error:
+    Tcl_SetObjResult(interp, Tcl_NewStringObj(errorString, -1));
+    return TCL_ERROR;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * BinaryScanCmd --
+ *
+ *	This procedure implements the "binary scan" Tcl command.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+BinaryScanCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    int arg;			/* Index of next argument to consume. */
+    int value = 0;		/* Current integer value to be packed.
+				 * Initialized to avoid compiler warning. */
+    char cmd;			/* Current format character. */
+    int count;			/* Count associated with current format
+				 * character. */
+    int flags;			/* Format field flags */
+    const char *format;	/* Pointer to current position in format
+				 * string. */
+    Tcl_Obj *resultPtr = NULL;	/* Object holding result buffer. */
+    unsigned char *buffer;	/* Start of result buffer. */
+    const char *errorString;
+    const char *str;
+    int offset, size, length;
+
+    int i;
+    Tcl_Obj *valuePtr, *elementPtr;
+    Tcl_HashTable numberCacheHash;
+    Tcl_HashTable *numberCachePtr;
+
+    if (objc < 3) {
+	Tcl_WrongNumArgs(interp, 1, objv,
+		"value formatString ?varName ...?");
+	return TCL_ERROR;
+    }
+    numberCachePtr = &numberCacheHash;
+    Tcl_InitHashTable(numberCachePtr, TCL_ONE_WORD_KEYS);
+    buffer = Tcl_GetByteArrayFromObj(objv[1], &length);
+    format = TclGetString(objv[2]);
+    arg = 3;
+    offset = 0;
+    while (*format != '\0') {
+	str = format;
+	flags = 0;
+	if (!GetFormatSpec(&format, &cmd, &count, &flags)) {
+	    goto done;
+	}
+	switch (cmd) {
+	case 'a':
+	case 'A': {
+	    unsigned char *src;
+
+	    if (arg >= objc) {
+		DeleteScanNumberCache(numberCachePtr);
+		goto badIndex;
+	    }
+	    if (count == BINARY_ALL) {
+		count = length - offset;
+	    } else {
+		if (count == BINARY_NOCOUNT) {
+		    count = 1;
+		}
+		if (count > (length - offset)) {
+		    goto done;
+		}
+	    }
+
+	    src = buffer + offset;
+	    size = count;
+
+	    /*
+	     * Trim trailing nulls and spaces, if necessary.
+	     */
+
+	    if (cmd == 'A') {
+		while (size > 0) {
+		    if (src[size-1] != '\0' && src[size-1] != ' ') {
+			break;
+		    }
+		    size--;
+		}
+	    }
+
+	    /*
+	     * Have to do this #ifdef-fery because (as part of defining
+	     * Tcl_NewByteArrayObj) we removed the #def that hides this stuff
+	     * normally. If this code ever gets copied to another file, it
+	     * should be changed back to the simpler version.
+	     */
+
+#ifdef TCL_MEM_DEBUG
+	    valuePtr = Tcl_DbNewByteArrayObj(src, size, __FILE__, __LINE__);
+#else
+	    valuePtr = Tcl_NewByteArrayObj(src, size);
+#endif /* TCL_MEM_DEBUG */
+
+	    resultPtr = Tcl_ObjSetVar2(interp, objv[arg], NULL, valuePtr,
+		    TCL_LEAVE_ERR_MSG);
+	    arg++;
+	    if (resultPtr == NULL) {
+		DeleteScanNumberCache(numberCachePtr);
+		return TCL_ERROR;
+	    }
+	    offset += count;
+	    break;
+	}
+	case 'b':
+	case 'B': {
+	    unsigned char *src;
+	    char *dest;
+
+	    if (arg >= objc) {
+		DeleteScanNumberCache(numberCachePtr);
+		goto badIndex;
+	    }
+	    if (count == BINARY_ALL) {
+		count = (length - offset) * 8;
+	    } else {
+		if (count == BINARY_NOCOUNT) {
+		    count = 1;
+		}
+		if (count > (length - offset) * 8) {
+		    goto done;
+		}
+	    }
+	    src = buffer + offset;
+	    valuePtr = Tcl_NewObj();
+	    Tcl_SetObjLength(valuePtr, count);
+	    dest = TclGetString(valuePtr);
+
+	    if (cmd == 'b') {
+		for (i = 0; i < count; i++) {
+		    if (i % 8) {
+			value >>= 1;
+		    } else {
+			value = *src++;
+		    }
+		    *dest++ = (char) ((value & 1) ? '1' : '0');
+		}
+	    } else {
+		for (i = 0; i < count; i++) {
+		    if (i % 8) {
+			value <<= 1;
+		    } else {
+			value = *src++;
+		    }
+		    *dest++ = (char) ((value & 0x80) ? '1' : '0');
+		}
+	    }
+
+	    resultPtr = Tcl_ObjSetVar2(interp, objv[arg], NULL, valuePtr,
+		    TCL_LEAVE_ERR_MSG);
+	    arg++;
+	    if (resultPtr == NULL) {
+		DeleteScanNumberCache(numberCachePtr);
+		return TCL_ERROR;
+	    }
+	    offset += (count + 7) / 8;
+	    break;
+	}
+	case 'h':
+	case 'H': {
+	    char *dest;
+	    unsigned char *src;
+	    static const char hexdigit[] = "0123456789abcdef";
+
+	    if (arg >= objc) {
+		DeleteScanNumberCache(numberCachePtr);
+		goto badIndex;
+	    }
+	    if (count == BINARY_ALL) {
+		count = (length - offset)*2;
+	    } else {
+		if (count == BINARY_NOCOUNT) {
+		    count = 1;
+		}
+		if (count > (length - offset)*2) {
+		    goto done;
+		}
+	    }
+	    src = buffer + offset;
+	    valuePtr = Tcl_NewObj();
+	    Tcl_SetObjLength(valuePtr, count);
+	    dest = TclGetString(valuePtr);
+
+	    if (cmd == 'h') {
+		for (i = 0; i < count; i++) {
+		    if (i % 2) {
+			value >>= 4;
+		    } else {
+			value = *src++;
+		    }
+		    *dest++ = hexdigit[value & 0xf];
+		}
+	    } else {
+		for (i = 0; i < count; i++) {
+		    if (i % 2) {
+			value <<= 4;
+		    } else {
+			value = *src++;
+		    }
+		    *dest++ = hexdigit[(value >> 4) & 0xf];
+		}
+	    }
+
+	    resultPtr = Tcl_ObjSetVar2(interp, objv[arg], NULL, valuePtr,
+		    TCL_LEAVE_ERR_MSG);
+	    arg++;
+	    if (resultPtr == NULL) {
+		DeleteScanNumberCache(numberCachePtr);
+		return TCL_ERROR;
+	    }
+	    offset += (count + 1) / 2;
+	    break;
+	}
+	case 'c':
+	    size = 1;
+	    goto scanNumber;
+	case 't':
+	case 's':
+	case 'S':
+	    size = 2;
+	    goto scanNumber;
+	case 'n':
+	case 'i':
+	case 'I':
+	    size = 4;
+	    goto scanNumber;
+	case 'm':
+	case 'w':
+	case 'W':
+	    size = 8;
+	    goto scanNumber;
+	case 'r':
+	case 'R':
+	case 'f':
+	    size = sizeof(float);
+	    goto scanNumber;
+	case 'q':
+	case 'Q':
+	case 'd': {
+	    unsigned char *src;
+
+	    size = sizeof(double);
+	    /* fall through */
+
+	scanNumber:
+	    if (arg >= objc) {
+		DeleteScanNumberCache(numberCachePtr);
+		goto badIndex;
+	    }
+	    if (count == BINARY_NOCOUNT) {
+		if ((length - offset) < size) {
+		    goto done;
+		}
+		valuePtr = ScanNumber(buffer+offset, cmd, flags,
+			&numberCachePtr);
+		offset += size;
+	    } else {
+		if (count == BINARY_ALL) {
+		    count = (length - offset) / size;
+		}
+		if ((length - offset) < (count * size)) {
+		    goto done;
+		}
+		valuePtr = Tcl_NewObj();
+		src = buffer + offset;
+		for (i = 0; i < count; i++) {
+		    elementPtr = ScanNumber(src, cmd, flags, &numberCachePtr);
+		    src += size;
+		    Tcl_ListObjAppendElement(NULL, valuePtr, elementPtr);
+		}
+		offset += count * size;
+	    }
+
+	    resultPtr = Tcl_ObjSetVar2(interp, objv[arg], NULL, valuePtr,
+		    TCL_LEAVE_ERR_MSG);
+	    arg++;
+	    if (resultPtr == NULL) {
+		DeleteScanNumberCache(numberCachePtr);
+		return TCL_ERROR;
+	    }
+	    break;
+	}
+	case 'x':
+	    if (count == BINARY_NOCOUNT) {
+		count = 1;
+	    }
+	    if ((count == BINARY_ALL) || (count > (length - offset))) {
+		offset = length;
+	    } else {
+		offset += count;
+	    }
+	    break;
+	case 'X':
+	    if (count == BINARY_NOCOUNT) {
+		count = 1;
+	    }
+	    if ((count == BINARY_ALL) || (count > offset)) {
+		offset = 0;
+	    } else {
+		offset -= count;
+	    }
+	    break;
+	case '@':
+	    if (count == BINARY_NOCOUNT) {
+		DeleteScanNumberCache(numberCachePtr);
+		goto badCount;
+	    }
+	    if ((count == BINARY_ALL) || (count > length)) {
+		offset = length;
+	    } else {
+		offset = count;
+	    }
+	    break;
+	default:
+	    DeleteScanNumberCache(numberCachePtr);
+	    errorString = str;
+	    goto badField;
+	}
+    }
+
+    /*
+     * Set the result to the last position of the cursor.
+     */
+
+ done:
+    Tcl_SetObjResult(interp, Tcl_NewLongObj(arg - 3));
+    DeleteScanNumberCache(numberCachePtr);
+
+    return TCL_OK;
+
+ badCount:
+    errorString = "missing count for \"@\" field specifier";
+    goto error;
+
+ badIndex:
+    errorString = "not enough arguments for all format specifiers";
+    goto error;
+
+ badField:
+    {
+	Tcl_UniChar ch;
+	char buf[TCL_UTF_MAX + 1];
+
+	Tcl_UtfToUniChar(errorString, &ch);
+	buf[Tcl_UniCharToUtf(ch, buf)] = '\0';
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		"bad field specifier \"%s\"", buf));
+	return TCL_ERROR;
+    }
+
+ error:
+    Tcl_SetObjResult(interp, Tcl_NewStringObj(errorString, -1));
+    return TCL_ERROR;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * GetFormatSpec --
+ *
+ *	This function parses the format strings used in the binary format and
+ *	scan commands.
+ *
+ * Results:
+ *	Moves the formatPtr to the start of the next command. Returns the
+ *	current command character and count in cmdPtr and countPtr. The count
+ *	is set to BINARY_ALL if the count character was '*' or BINARY_NOCOUNT
+ *	if no count was specified. Returns 1 on success, or 0 if the string
+ *	did not have a format specifier.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+GetFormatSpec(
+    const char **formatPtr,	/* Pointer to format string. */
+    char *cmdPtr,		/* Pointer to location of command char. */
+    int *countPtr,		/* Pointer to repeat count value. */
+    int *flagsPtr)		/* Pointer to field flags */
+{
+    /*
+     * Skip any leading blanks.
+     */
+
+    while (**formatPtr == ' ') {
+	(*formatPtr)++;
+    }
+
+    /*
+     * The string was empty, except for whitespace, so fail.
+     */
+
+    if (!(**formatPtr)) {
+	return 0;
+    }
+
+    /*
+     * Extract the command character and any trailing digits or '*'.
+     */
+
+    *cmdPtr = **formatPtr;
+    (*formatPtr)++;
+    if (**formatPtr == 'u') {
+	(*formatPtr)++;
+	*flagsPtr |= BINARY_UNSIGNED;
+    }
+    if (**formatPtr == '*') {
+	(*formatPtr)++;
+	*countPtr = BINARY_ALL;
+    } else if (isdigit(UCHAR(**formatPtr))) { /* INTL: digit */
+	*countPtr = strtoul(*formatPtr, (char **) formatPtr, 10);
+    } else {
+	*countPtr = BINARY_NOCOUNT;
+    }
+    return 1;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * NeedReversing --
+ *
+ *	This routine determines, if bytes of a number need to be re-ordered,
+ *	and returns a numeric code indicating the re-ordering to be done.
+ *	This depends on the endiannes of the machine and the desired format.
+ *	It is in effect a table (whose contents depend on the endianness of
+ *	the system) describing whether a value needs reversing or not. Anyone
+ *	porting the code to a big-endian platform should take care to make
+ *	sure that they define WORDS_BIGENDIAN though this is already done by
+ *	configure for the Unix build; little-endian platforms (including
+ *	Windows) don't need to do anything.
+ *
+ * Results:
+ *	0	No re-ordering needed.
+ *	1	Reverse the bytes:	01234567 <-> 76543210 (little to big)
+ *	2	Apply this re-ordering: 01234567 <-> 45670123 (Nokia to little)
+ *	3	Apply this re-ordering: 01234567 <-> 32107654 (Nokia to big)
+ *
+ * Side effects:
+ *	None
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+NeedReversing(
+    int format)
+{
+    switch (format) {
+	/* native floats and doubles: never reverse */
+    case 'd':
+    case 'f':
+	/* big endian ints: never reverse */
+    case 'I':
+    case 'S':
+    case 'W':
+#ifdef WORDS_BIGENDIAN
+	/* native ints: reverse if we're little-endian */
+    case 'n':
+    case 't':
+    case 'm':
+	/* f: reverse if we're little-endian */
+    case 'Q':
+    case 'R':
+#else /* !WORDS_BIGENDIAN */
+	/* small endian floats: reverse if we're big-endian */
+    case 'r':
+#endif /* WORDS_BIGENDIAN */
+	return 0;
+
+#ifdef WORDS_BIGENDIAN
+	/* small endian floats: reverse if we're big-endian */
+    case 'q':
+    case 'r':
+#else /* !WORDS_BIGENDIAN */
+	/* native ints: reverse if we're little-endian */
+    case 'n':
+    case 't':
+    case 'm':
+	/* f: reverse if we're little-endian */
+    case 'R':
+#endif /* WORDS_BIGENDIAN */
+	/* small endian ints: always reverse */
+    case 'i':
+    case 's':
+    case 'w':
+	return 1;
+
+#ifndef WORDS_BIGENDIAN
+    /*
+     * The Q and q formats need special handling to account for the unusual
+     * byte ordering of 8-byte floats on Nokia 770 systems, which claim to be
+     * little-endian, but also reverse word order.
+     */
+
+    case 'Q':
+	if (TclNokia770Doubles()) {
+	    return 3;
+	}
+	return 1;
+    case 'q':
+	if (TclNokia770Doubles()) {
+	    return 2;
+	}
+	return 0;
+#endif
+    }
+
+    Tcl_Panic("unexpected fallthrough");
+    return 0;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * CopyNumber --
+ *
+ *	This routine is called by FormatNumber and ScanNumber to copy a
+ *	floating-point number. If required, bytes are reversed while copying.
+ *	The behaviour is only fully defined when used with IEEE float and
+ *	double values (guaranteed to be 4 and 8 bytes long, respectively.)
+ *
+ * Results:
+ *	None
+ *
+ * Side effects:
+ *	Copies length bytes
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+CopyNumber(
+    const void *from,		/* source */
+    void *to,			/* destination */
+    unsigned length,		/* Number of bytes to copy */
+    int type)			/* What type of thing are we copying? */
+{
+    switch (NeedReversing(type)) {
+    case 0:
+	memcpy(to, from, length);
+	break;
+    case 1: {
+	const unsigned char *fromPtr = from;
+	unsigned char *toPtr = to;
+
+	switch (length) {
+	case 4:
+	    toPtr[0] = fromPtr[3];
+	    toPtr[1] = fromPtr[2];
+	    toPtr[2] = fromPtr[1];
+	    toPtr[3] = fromPtr[0];
+	    break;
+	case 8:
+	    toPtr[0] = fromPtr[7];
+	    toPtr[1] = fromPtr[6];
+	    toPtr[2] = fromPtr[5];
+	    toPtr[3] = fromPtr[4];
+	    toPtr[4] = fromPtr[3];
+	    toPtr[5] = fromPtr[2];
+	    toPtr[6] = fromPtr[1];
+	    toPtr[7] = fromPtr[0];
+	    break;
+	}
+	break;
+    }
+    case 2: {
+	const unsigned char *fromPtr = from;
+	unsigned char *toPtr = to;
+
+	toPtr[0] = fromPtr[4];
+	toPtr[1] = fromPtr[5];
+	toPtr[2] = fromPtr[6];
+	toPtr[3] = fromPtr[7];
+	toPtr[4] = fromPtr[0];
+	toPtr[5] = fromPtr[1];
+	toPtr[6] = fromPtr[2];
+	toPtr[7] = fromPtr[3];
+	break;
+    }
+    case 3: {
+	const unsigned char *fromPtr = from;
+	unsigned char *toPtr = to;
+
+	toPtr[0] = fromPtr[3];
+	toPtr[1] = fromPtr[2];
+	toPtr[2] = fromPtr[1];
+	toPtr[3] = fromPtr[0];
+	toPtr[4] = fromPtr[7];
+	toPtr[5] = fromPtr[6];
+	toPtr[6] = fromPtr[5];
+	toPtr[7] = fromPtr[4];
+	break;
+    }
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * FormatNumber --
+ *
+ *	This routine is called by Tcl_BinaryObjCmd to format a number into a
+ *	location pointed at by cursor.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	Moves the cursor to the next location to be written into.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+FormatNumber(
+    Tcl_Interp *interp,		/* Current interpreter, used to report
+				 * errors. */
+    int type,			/* Type of number to format. */
+    Tcl_Obj *src,		/* Number to format. */
+    unsigned char **cursorPtr)	/* Pointer to index into destination buffer. */
+{
+    long value;
+    double dvalue;
+    Tcl_WideInt wvalue;
+    float fvalue;
+
+    switch (type) {
+    case 'd':
+    case 'q':
+    case 'Q':
+	/*
+	 * Double-precision floating point values. Tcl_GetDoubleFromObj
+	 * returns TCL_ERROR for NaN, but we can check by comparing the
+	 * object's type pointer.
+	 */
+
+	if (Tcl_GetDoubleFromObj(interp, src, &dvalue) != TCL_OK) {
+	    if (src->typePtr != &tclDoubleType) {
+		return TCL_ERROR;
+	    }
+	    dvalue = src->internalRep.doubleValue;
+	}
+	CopyNumber(&dvalue, *cursorPtr, sizeof(double), type);
+	*cursorPtr += sizeof(double);
+	return TCL_OK;
+
+    case 'f':
+    case 'r':
+    case 'R':
+	/*
+	 * Single-precision floating point values. Tcl_GetDoubleFromObj
+	 * returns TCL_ERROR for NaN, but we can check by comparing the
+	 * object's type pointer.
+	 */
+
+	if (Tcl_GetDoubleFromObj(interp, src, &dvalue) != TCL_OK) {
+	    if (src->typePtr != &tclDoubleType) {
+		return TCL_ERROR;
+	    }
+	    dvalue = src->internalRep.doubleValue;
+	}
+
+	/*
+	 * Because some compilers will generate floating point exceptions on
+	 * an overflow cast (e.g. Borland), we restrict the values to the
+	 * valid range for float.
+	 */
+
+	if (fabs(dvalue) > (double)FLT_MAX) {
+	    fvalue = (dvalue >= 0.0) ? FLT_MAX : -FLT_MAX;
+	} else {
+	    fvalue = (float) dvalue;
+	}
+	CopyNumber(&fvalue, *cursorPtr, sizeof(float), type);
+	*cursorPtr += sizeof(float);
+	return TCL_OK;
+
+	/*
+	 * 64-bit integer values.
+	 */
+    case 'w':
+    case 'W':
+    case 'm':
+	if (Tcl_GetWideIntFromObj(interp, src, &wvalue) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	if (NeedReversing(type)) {
+	    *(*cursorPtr)++ = UCHAR(wvalue);
+	    *(*cursorPtr)++ = UCHAR(wvalue >> 8);
+	    *(*cursorPtr)++ = UCHAR(wvalue >> 16);
+	    *(*cursorPtr)++ = UCHAR(wvalue >> 24);
+	    *(*cursorPtr)++ = UCHAR(wvalue >> 32);
+	    *(*cursorPtr)++ = UCHAR(wvalue >> 40);
+	    *(*cursorPtr)++ = UCHAR(wvalue >> 48);
+	    *(*cursorPtr)++ = UCHAR(wvalue >> 56);
+	} else {
+	    *(*cursorPtr)++ = UCHAR(wvalue >> 56);
+	    *(*cursorPtr)++ = UCHAR(wvalue >> 48);
+	    *(*cursorPtr)++ = UCHAR(wvalue >> 40);
+	    *(*cursorPtr)++ = UCHAR(wvalue >> 32);
+	    *(*cursorPtr)++ = UCHAR(wvalue >> 24);
+	    *(*cursorPtr)++ = UCHAR(wvalue >> 16);
+	    *(*cursorPtr)++ = UCHAR(wvalue >> 8);
+	    *(*cursorPtr)++ = UCHAR(wvalue);
+	}
+	return TCL_OK;
+
+	/*
+	 * 32-bit integer values.
+	 */
+    case 'i':
+    case 'I':
+    case 'n':
+	if (TclGetLongFromObj(interp, src, &value) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	if (NeedReversing(type)) {
+	    *(*cursorPtr)++ = UCHAR(value);
+	    *(*cursorPtr)++ = UCHAR(value >> 8);
+	    *(*cursorPtr)++ = UCHAR(value >> 16);
+	    *(*cursorPtr)++ = UCHAR(value >> 24);
+	} else {
+	    *(*cursorPtr)++ = UCHAR(value >> 24);
+	    *(*cursorPtr)++ = UCHAR(value >> 16);
+	    *(*cursorPtr)++ = UCHAR(value >> 8);
+	    *(*cursorPtr)++ = UCHAR(value);
+	}
+	return TCL_OK;
+
+	/*
+	 * 16-bit integer values.
+	 */
+    case 's':
+    case 'S':
+    case 't':
+	if (TclGetLongFromObj(interp, src, &value) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	if (NeedReversing(type)) {
+	    *(*cursorPtr)++ = UCHAR(value);
+	    *(*cursorPtr)++ = UCHAR(value >> 8);
+	} else {
+	    *(*cursorPtr)++ = UCHAR(value >> 8);
+	    *(*cursorPtr)++ = UCHAR(value);
+	}
+	return TCL_OK;
+
+	/*
+	 * 8-bit integer values.
+	 */
+    case 'c':
+	if (TclGetLongFromObj(interp, src, &value) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	*(*cursorPtr)++ = UCHAR(value);
+	return TCL_OK;
+
+    default:
+	Tcl_Panic("unexpected fallthrough");
+	return TCL_ERROR;
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ScanNumber --
+ *
+ *	This routine is called by Tcl_BinaryObjCmd to scan a number out of a
+ *	buffer.
+ *
+ * Results:
+ *	Returns a newly created object containing the scanned number. This
+ *	object has a ref count of zero.
+ *
+ * Side effects:
+ *	Might reuse an object in the number cache, place a new object in the
+ *	cache, or delete the cache and set the reference to it (itself passed
+ *	in by reference) to NULL.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static Tcl_Obj *
+ScanNumber(
+    unsigned char *buffer,	/* Buffer to scan number from. */
+    int type,			/* Format character from "binary scan" */
+    int flags,			/* Format field flags */
+    Tcl_HashTable **numberCachePtrPtr)
+				/* Place to look for cache of scanned
+				 * value objects, or NULL if too many
+				 * different numbers have been scanned. */
+{
+    long value;
+    float fvalue;
+    double dvalue;
+    Tcl_WideUInt uwvalue;
+
+    /*
+     * We cannot rely on the compiler to properly sign extend integer values
+     * when we cast from smaller values to larger values because we don't know
+     * the exact size of the integer types. So, we have to handle sign
+     * extension explicitly by checking the high bit and padding with 1's as
+     * needed. This practice is disabled if the BINARY_UNSIGNED flag is set.
+     */
+
+    switch (type) {
+    case 'c':
+	/*
+	 * Characters need special handling. We want to produce a signed
+	 * result, but on some platforms (such as AIX) chars are unsigned. To
+	 * deal with this, check for a value that should be negative but
+	 * isn't.
+	 */
+
+	value = buffer[0];
+	if (!(flags & BINARY_UNSIGNED)) {
+	    if (value & 0x80) {
+		value |= -0x100;
+	    }
+	}
+	goto returnNumericObject;
+
+	/*
+	 * 16-bit numeric values. We need the sign extension trick (see above)
+	 * here as well.
+	 */
+
+    case 's':
+    case 'S':
+    case 't':
+	if (NeedReversing(type)) {
+	    value = (long) (buffer[0] + (buffer[1] << 8));
+	} else {
+	    value = (long) (buffer[1] + (buffer[0] << 8));
+	}
+	if (!(flags & BINARY_UNSIGNED)) {
+	    if (value & 0x8000) {
+		value |= -0x10000;
+	    }
+	}
+	goto returnNumericObject;
+
+	/*
+	 * 32-bit numeric values.
+	 */
+
+    case 'i':
+    case 'I':
+    case 'n':
+	if (NeedReversing(type)) {
+	    value = (long) (buffer[0]
+		    + (buffer[1] << 8)
+		    + (buffer[2] << 16)
+		    + (((long)buffer[3]) << 24));
+	} else {
+	    value = (long) (buffer[3]
+		    + (buffer[2] << 8)
+		    + (buffer[1] << 16)
+		    + (((long) buffer[0]) << 24));
+	}
+
+	/*
+	 * Check to see if the value was sign extended properly on systems
+	 * where an int is more than 32-bits.
+	 * We avoid caching unsigned integers as we cannot distinguish between
+	 * 32bit signed and unsigned in the hash (short and char are ok).
+	 */
+
+	if (flags & BINARY_UNSIGNED) {
+	    return Tcl_NewWideIntObj((Tcl_WideInt)(unsigned long)value);
+	}
+	if ((value & (((unsigned) 1)<<31)) && (value > 0)) {
+	    value -= (((unsigned) 1)<<31);
+	    value -= (((unsigned) 1)<<31);
+	}
+
+    returnNumericObject:
+	if (*numberCachePtrPtr == NULL) {
+	    return Tcl_NewLongObj(value);
+	} else {
+	    register Tcl_HashTable *tablePtr = *numberCachePtrPtr;
+	    register Tcl_HashEntry *hPtr;
+	    int isNew;
+
+	    hPtr = Tcl_CreateHashEntry(tablePtr, INT2PTR(value), &isNew);
+	    if (!isNew) {
+		return Tcl_GetHashValue(hPtr);
+	    }
+	    if (tablePtr->numEntries <= BINARY_SCAN_MAX_CACHE) {
+		register Tcl_Obj *objPtr = Tcl_NewLongObj(value);
+
+		Tcl_IncrRefCount(objPtr);
+		Tcl_SetHashValue(hPtr, objPtr);
+		return objPtr;
+	    }
+
+	    /*
+	     * We've overflowed the cache! Someone's parsing a LOT of varied
+	     * binary data in a single call! Bail out by switching back to the
+	     * old behaviour for the rest of the scan.
+	     *
+	     * Note that anyone just using the 'c' conversion (for bytes)
+	     * cannot trigger this.
+	     */
+
+	    DeleteScanNumberCache(tablePtr);
+	    *numberCachePtrPtr = NULL;
+	    return Tcl_NewLongObj(value);
+	}
+
+	/*
+	 * Do not cache wide (64-bit) values; they are already too large to
+	 * use as keys.
+	 */
+
+    case 'w':
+    case 'W':
+    case 'm':
+	if (NeedReversing(type)) {
+	    uwvalue = ((Tcl_WideUInt) buffer[0])
+		    | (((Tcl_WideUInt) buffer[1]) << 8)
+		    | (((Tcl_WideUInt) buffer[2]) << 16)
+		    | (((Tcl_WideUInt) buffer[3]) << 24)
+		    | (((Tcl_WideUInt) buffer[4]) << 32)
+		    | (((Tcl_WideUInt) buffer[5]) << 40)
+		    | (((Tcl_WideUInt) buffer[6]) << 48)
+		    | (((Tcl_WideUInt) buffer[7]) << 56);
+	} else {
+	    uwvalue = ((Tcl_WideUInt) buffer[7])
+		    | (((Tcl_WideUInt) buffer[6]) << 8)
+		    | (((Tcl_WideUInt) buffer[5]) << 16)
+		    | (((Tcl_WideUInt) buffer[4]) << 24)
+		    | (((Tcl_WideUInt) buffer[3]) << 32)
+		    | (((Tcl_WideUInt) buffer[2]) << 40)
+		    | (((Tcl_WideUInt) buffer[1]) << 48)
+		    | (((Tcl_WideUInt) buffer[0]) << 56);
+	}
+	if (flags & BINARY_UNSIGNED) {
+	    Tcl_Obj *bigObj = NULL;
+	    mp_int big;
+
+	    TclBNInitBignumFromWideUInt(&big, uwvalue);
+	    bigObj = Tcl_NewBignumObj(&big);
+	    return bigObj;
+	}
+	return Tcl_NewWideIntObj((Tcl_WideInt) uwvalue);
+
+	/*
+	 * Do not cache double values; they are already too large to use as
+	 * keys and the values stored are utterly incompatible with the
+	 * integer part of the cache.
+	 */
+
+	/*
+	 * 32-bit IEEE single-precision floating point.
+	 */
+
+    case 'f':
+    case 'R':
+    case 'r':
+	CopyNumber(buffer, &fvalue, sizeof(float), type);
+	return Tcl_NewDoubleObj(fvalue);
+
+	/*
+	 * 64-bit IEEE double-precision floating point.
+	 */
+
+    case 'd':
+    case 'Q':
+    case 'q':
+	CopyNumber(buffer, &dvalue, sizeof(double), type);
+	return Tcl_NewDoubleObj(dvalue);
+    }
+    return NULL;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * DeleteScanNumberCache --
+ *
+ *	Deletes the hash table acting as a scan number cache.
+ *
+ * Results:
+ *	None
+ *
+ * Side effects:
+ *	Decrements the reference counts of the objects in the cache.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+DeleteScanNumberCache(
+    Tcl_HashTable *numberCachePtr)
+				/* Pointer to the hash table, or NULL (when
+				 * the cache has already been deleted due to
+				 * overflow.) */
+{
+    Tcl_HashEntry *hEntry;
+    Tcl_HashSearch search;
+
+    if (numberCachePtr == NULL) {
+	return;
+    }
+
+    hEntry = Tcl_FirstHashEntry(numberCachePtr, &search);
+    while (hEntry != NULL) {
+	register Tcl_Obj *value = Tcl_GetHashValue(hEntry);
+
+	if (value != NULL) {
+	    Tcl_DecrRefCount(value);
+	}
+	hEntry = Tcl_NextHashEntry(&search);
+    }
+    Tcl_DeleteHashTable(numberCachePtr);
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * NOTES --
+ *
+ *	Some measurements show that it is faster to use a table to to perform
+ *	uuencode and base64 value encoding than to calculate the output (at
+ *	least on intel P4 arch).
+ *
+ *	Conversely using a lookup table for the decoding is slower than just
+ *	calculating the values. We therefore use the fastest of each method.
+ *
+ *	Presumably this has to do with the size of the tables. The base64
+ *	decode table is 255 bytes while the encode table is only 65 bytes. The
+ *	choice likely depends on CPU memory cache sizes.
+ */
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * BinaryEncodeHex --
+ *
+ *	Implement the [binary encode hex] binary encoding. clientData must be
+ *	a table to convert values to hexadecimal digits.
+ *
+ * Results:
+ *	Interp result set to an encoded byte array object
+ *
+ * Side effects:
+ *	None
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+BinaryEncodeHex(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const objv[])
+{
+    Tcl_Obj *resultObj = NULL;
+    unsigned char *data = NULL;
+    unsigned char *cursor = NULL;
+    int offset = 0, count = 0;
+
+    if (objc != 2) {
+	Tcl_WrongNumArgs(interp, 1, objv, "data");
+	return TCL_ERROR;
+    }
+
+    TclNewObj(resultObj);
+    data = Tcl_GetByteArrayFromObj(objv[1], &count);
+    cursor = Tcl_SetByteArrayLength(resultObj, count * 2);
+    for (offset = 0; offset < count; ++offset) {
+	*cursor++ = HexDigits[((data[offset] >> 4) & 0x0f)];
+	*cursor++ = HexDigits[(data[offset] & 0x0f)];
+    }
+    Tcl_SetObjResult(interp, resultObj);
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * BinaryDecodeHex --
+ *
+ *	Implement the [binary decode hex] binary encoding.
+ *
+ * Results:
+ *	Interp result set to an decoded byte array object
+ *
+ * Side effects:
+ *	None
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+BinaryDecodeHex(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const objv[])
+{
+    Tcl_Obj *resultObj = NULL;
+    unsigned char *data, *datastart, *dataend;
+    unsigned char *begin, *cursor, c;
+    int i, index, value, size, count = 0, cut = 0, strict = 0;
+    enum {OPT_STRICT };
+    static const char *const optStrings[] = { "-strict", NULL };
+
+    if (objc < 2 || objc > 3) {
+	Tcl_WrongNumArgs(interp, 1, objv, "?options? data");
+	return TCL_ERROR;
+    }
+    for (i = 1; i < objc-1; ++i) {
+	if (Tcl_GetIndexFromObj(interp, objv[i], optStrings, "option",
+		TCL_EXACT, &index) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	switch (index) {
+	case OPT_STRICT:
+	    strict = 1;
+	    break;
+	}
+    }
+
+    TclNewObj(resultObj);
+    datastart = data = (unsigned char *)
+	    TclGetStringFromObj(objv[objc-1], &count);
+    dataend = data + count;
+    size = (count + 1) / 2;
+    begin = cursor = Tcl_SetByteArrayLength(resultObj, size);
+    while (data < dataend) {
+	value = 0;
+	for (i=0 ; i<2 ; i++) {
+	    if (data >= dataend) {
+		value <<= 4;
+		break;
+	    }
+
+	    c = *data++;
+	    if (!isxdigit((int) c)) {
+		if (strict || !isspace(c)) {
+		    goto badChar;
+		}
+		i--;
+		continue;
+	    }
+
+	    value <<= 4;
+	    c -= '0';
+	    if (c > 9) {
+		c += ('0' - 'A') + 10;
+	    }
+	    if (c > 16) {
+		c += ('A' - 'a');
+	    }
+	    value |= (c & 0xf);
+	}
+	if (i < 2) {
+	    cut++;
+	}
+	*cursor++ = UCHAR(value);
+	value = 0;
+    }
+    if (cut > size) {
+	cut = size;
+    }
+    Tcl_SetByteArrayLength(resultObj, cursor - begin - cut);
+    Tcl_SetObjResult(interp, resultObj);
+    return TCL_OK;
+
+  badChar:
+    TclDecrRefCount(resultObj);
+    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+	    "invalid hexadecimal digit \"%c\" at position %d",
+	    c, (int) (data - datastart - 1)));
+    return TCL_ERROR;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * BinaryEncode64 --
+ *
+ *	This implements a generic 6 bit binary encoding. Input is broken into
+ *	6 bit chunks and a lookup table passed in via clientData is used to
+ *	turn these values into output characters. This is used to implement
+ *	base64 binary encodings.
+ *
+ * Results:
+ *	Interp result set to an encoded byte array object
+ *
+ * Side effects:
+ *	None
+ *
+ *----------------------------------------------------------------------
+ */
+
+#define OUTPUT(c) \
+    do {						\
+	*cursor++ = (c);				\
+	outindex++;					\
+	if (maxlen > 0 && cursor != limit) {		\
+	    if (outindex == maxlen) {			\
+		memcpy(cursor, wrapchar, wrapcharlen);	\
+		cursor += wrapcharlen;			\
+		outindex = 0;				\
+	    }						\
+	}						\
+	if (cursor > limit) {				\
+	    Tcl_Panic("limit hit");			\
+	}						\
+    } while (0)
+
+static int
+BinaryEncode64(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const objv[])
+{
+    Tcl_Obj *resultObj;
+    unsigned char *data, *cursor, *limit;
+    int maxlen = 0;
+    const char *wrapchar = "\n";
+    int wrapcharlen = 1;
+    int offset, i, index, size, outindex = 0, count = 0;
+    enum {OPT_MAXLEN, OPT_WRAPCHAR };
+    static const char *const optStrings[] = { "-maxlen", "-wrapchar", NULL };
+
+    if (objc < 2 || objc%2 != 0) {
+	Tcl_WrongNumArgs(interp, 1, objv,
+		"?-maxlen len? ?-wrapchar char? data");
+	return TCL_ERROR;
+    }
+    for (i = 1; i < objc-1; i += 2) {
+	if (Tcl_GetIndexFromObj(interp, objv[i], optStrings, "option",
+		TCL_EXACT, &index) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	switch (index) {
+	case OPT_MAXLEN:
+	    if (Tcl_GetIntFromObj(interp, objv[i+1], &maxlen) != TCL_OK) {
+		return TCL_ERROR;
+	    }
+	    if (maxlen < 0) {
+		Tcl_SetObjResult(interp, Tcl_NewStringObj(
+			"line length out of range", -1));
+		Tcl_SetErrorCode(interp, "TCL", "BINARY", "ENCODE",
+			"LINE_LENGTH", NULL);
+		return TCL_ERROR;
+	    }
+	    break;
+	case OPT_WRAPCHAR:
+	    wrapchar = Tcl_GetStringFromObj(objv[i+1], &wrapcharlen);
+	    if (wrapcharlen == 0) {
+		maxlen = 0;
+	    }
+	    break;
+	}
+    }
+
+    resultObj = Tcl_NewObj();
+    data = Tcl_GetByteArrayFromObj(objv[objc-1], &count);
+    if (count > 0) {
+	size = (((count * 4) / 3) + 3) & ~3; /* ensure 4 byte chunks */
+	if (maxlen > 0 && size > maxlen) {
+	    int adjusted = size + (wrapcharlen * (size / maxlen));
+
+	    if (size % maxlen == 0) {
+		adjusted -= wrapcharlen;
+	    }
+	    size = adjusted;
+	}
+	cursor = Tcl_SetByteArrayLength(resultObj, size);
+	limit = cursor + size;
+	for (offset = 0; offset < count; offset+=3) {
+	    unsigned char d[3] = {0, 0, 0};
+
+	    for (i = 0; i < 3 && offset+i < count; ++i) {
+		d[i] = data[offset + i];
+	    }
+	    OUTPUT(B64Digits[d[0] >> 2]);
+	    OUTPUT(B64Digits[((d[0] & 0x03) << 4) | (d[1] >> 4)]);
+	    if (offset+1 < count) {
+		OUTPUT(B64Digits[((d[1] & 0x0f) << 2) | (d[2] >> 6)]);
+	    } else {
+		OUTPUT(B64Digits[64]);
+	    }
+	    if (offset+2 < count) {
+		OUTPUT(B64Digits[d[2] & 0x3f]);
+	    } else {
+		OUTPUT(B64Digits[64]);
+	    }
+	}
+    }
+    Tcl_SetObjResult(interp, resultObj);
+    return TCL_OK;
+}
+#undef OUTPUT
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * BinaryEncodeUu --
+ *
+ *	This implements the uuencode binary encoding. Input is broken into 6
+ *	bit chunks and a lookup table is used to turn these values into output
+ *	characters. This differs from the generic code above in that line
+ *	lengths are also encoded.
+ *
+ * Results:
+ *	Interp result set to an encoded byte array object
+ *
+ * Side effects:
+ *	None
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+BinaryEncodeUu(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const objv[])
+{
+    Tcl_Obj *resultObj;
+    unsigned char *data, *start, *cursor;
+    int offset, count, rawLength, n, i, j, bits, index;
+    int lineLength = 61;
+    const unsigned char SingleNewline[] = { (unsigned char) '\n' };
+    const unsigned char *wrapchar = SingleNewline;
+    int wrapcharlen = sizeof(SingleNewline);
+    enum { OPT_MAXLEN, OPT_WRAPCHAR };
+    static const char *const optStrings[] = { "-maxlen", "-wrapchar", NULL };
+
+    if (objc < 2 || objc%2 != 0) {
+	Tcl_WrongNumArgs(interp, 1, objv,
+		"?-maxlen len? ?-wrapchar char? data");
+	return TCL_ERROR;
+    }
+    for (i = 1; i < objc-1; i += 2) {
+	if (Tcl_GetIndexFromObj(interp, objv[i], optStrings, "option",
+		TCL_EXACT, &index) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	switch (index) {
+	case OPT_MAXLEN:
+	    if (Tcl_GetIntFromObj(interp, objv[i+1], &lineLength) != TCL_OK) {
+		return TCL_ERROR;
+	    }
+	    if (lineLength < 3 || lineLength > 85) {
+		Tcl_SetObjResult(interp, Tcl_NewStringObj(
+			"line length out of range", -1));
+		Tcl_SetErrorCode(interp, "TCL", "BINARY", "ENCODE",
+			"LINE_LENGTH", NULL);
+		return TCL_ERROR;
+	    }
+	    break;
+	case OPT_WRAPCHAR:
+	    wrapchar = Tcl_GetByteArrayFromObj(objv[i+1], &wrapcharlen);
+	    break;
+	}
+    }
+
+    /*
+     * Allocate the buffer. This is a little bit too long, but is "good
+     * enough".
+     */
+
+    resultObj = Tcl_NewObj();
+    offset = 0;
+    data = Tcl_GetByteArrayFromObj(objv[objc-1], &count);
+    rawLength = (lineLength - 1) * 3 / 4;
+    start = cursor = Tcl_SetByteArrayLength(resultObj,
+	    (lineLength + wrapcharlen) *
+	    ((count + (rawLength - 1)) / rawLength));
+    n = bits = 0;
+
+    /*
+     * Encode the data. Each output line first has the length of raw data
+     * encoded by the output line described in it by one encoded byte, then
+     * the encoded data follows (encoding each 6 bits as one character).
+     * Encoded lines are always terminated by a newline.
+     */
+
+    while (offset < count) {
+	int lineLen = count - offset;
+
+	if (lineLen > rawLength) {
+	    lineLen = rawLength;
+	}
+	*cursor++ = UueDigits[lineLen];
+	for (i=0 ; i<lineLen ; i++) {
+	    n <<= 8;
+	    n |= data[offset++];
+	    for (bits += 8; bits > 6 ; bits -= 6) {
+		*cursor++ = UueDigits[(n >> (bits-6)) & 0x3f];
+	    }
+	}
+	if (bits > 0) {
+	    n <<= 8;
+	    *cursor++ = UueDigits[(n >> (bits + 2)) & 0x3f];
+	    bits = 0;
+	}
+	for (j=0 ; j<wrapcharlen ; ++j) {
+	    *cursor++ = wrapchar[j];
+	}
+    }
+
+    /*
+     * Fix the length of the output bytearray.
+     */
+
+    Tcl_SetByteArrayLength(resultObj, cursor-start);
+    Tcl_SetObjResult(interp, resultObj);
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * BinaryDecodeUu --
+ *
+ *	Decode a uuencoded string.
+ *
+ * Results:
+ *	Interp result set to an byte array object
+ *
+ * Side effects:
+ *	None
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+BinaryDecodeUu(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const objv[])
+{
+    Tcl_Obj *resultObj = NULL;
+    unsigned char *data, *datastart, *dataend;
+    unsigned char *begin, *cursor;
+    int i, index, size, count = 0, strict = 0, lineLen;
+    unsigned char c;
+    enum {OPT_STRICT };
+    static const char *const optStrings[] = { "-strict", NULL };
+
+    if (objc < 2 || objc > 3) {
+	Tcl_WrongNumArgs(interp, 1, objv, "?options? data");
+	return TCL_ERROR;
+    }
+    for (i = 1; i < objc-1; ++i) {
+	if (Tcl_GetIndexFromObj(interp, objv[i], optStrings, "option",
+		TCL_EXACT, &index) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	switch (index) {
+	case OPT_STRICT:
+	    strict = 1;
+	    break;
+	}
+    }
+
+    TclNewObj(resultObj);
+    datastart = data = (unsigned char *)
+	    TclGetStringFromObj(objv[objc-1], &count);
+    dataend = data + count;
+    size = ((count + 3) & ~3) * 3 / 4;
+    begin = cursor = Tcl_SetByteArrayLength(resultObj, size);
+    lineLen = -1;
+
+    /*
+     * The decoding loop. First, we get the length of line (strictly, the
+     * number of data bytes we expect to generate from the line) we're
+     * processing this time round if it is not already known (i.e., when the
+     * lineLen variable is set to the magic value, -1).
+     */
+
+    while (data < dataend) {
+	char d[4] = {0, 0, 0, 0};
+
+	if (lineLen < 0) {
+	    c = *data++;
+	    if (c < 32 || c > 96) {
+		if (strict || !isspace(c)) {
+		    goto badUu;
+		}
+		i--;
+		continue;
+	    }
+	    lineLen = (c - 32) & 0x3f;
+	}
+
+	/*
+	 * Now we read a four-character grouping.
+	 */
+
+	for (i=0 ; i<4 ; i++) {
+	    if (data < dataend) {
+		d[i] = c = *data++;
+		if (c < 32 || c > 96) {
+		    if (strict) {
+			if (!isspace(c)) {
+			    goto badUu;
+			} else if (c == '\n') {
+			    goto shortUu;
+			}
+		    }
+		    i--;
+		    continue;
+		}
+	    }
+	}
+
+	/*
+	 * Translate that grouping into (up to) three binary bytes output.
+	 */
+
+	if (lineLen > 0) {
+	    *cursor++ = (((d[0] - 0x20) & 0x3f) << 2)
+		    | (((d[1] - 0x20) & 0x3f) >> 4);
+	    if (--lineLen > 0) {
+		*cursor++ = (((d[1] - 0x20) & 0x3f) << 4)
+			| (((d[2] - 0x20) & 0x3f) >> 2);
+		if (--lineLen > 0) {
+		    *cursor++ = (((d[2] - 0x20) & 0x3f) << 6)
+			    | (((d[3] - 0x20) & 0x3f));
+		    lineLen--;
+		}
+	    }
+	}
+
+	/*
+	 * If we've reached the end of the line, skip until we process a
+	 * newline.
+	 */
+
+	if (lineLen == 0 && data < dataend) {
+	    lineLen = -1;
+	    do {
+		c = *data++;
+		if (c == '\n') {
+		    break;
+		} else if (c >= 32 && c <= 96) {
+		    data--;
+		    break;
+		} else if (strict || !isspace(c)) {
+		    goto badUu;
+		}
+	    } while (data < dataend);
+	}
+    }
+
+    /*
+     * Sanity check, clean up and finish.
+     */
+
+    if (lineLen > 0 && strict) {
+	goto shortUu;
+    }
+    Tcl_SetByteArrayLength(resultObj, cursor - begin);
+    Tcl_SetObjResult(interp, resultObj);
+    return TCL_OK;
+
+  shortUu:
+    Tcl_SetObjResult(interp, Tcl_ObjPrintf("short uuencode data"));
+    Tcl_SetErrorCode(interp, "TCL", "BINARY", "DECODE", "SHORT", NULL);
+    TclDecrRefCount(resultObj);
+    return TCL_ERROR;
+
+  badUu:
+    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+	    "invalid uuencode character \"%c\" at position %d",
+	    c, (int) (data - datastart - 1)));
+    Tcl_SetErrorCode(interp, "TCL", "BINARY", "DECODE", "INVALID", NULL);
+    TclDecrRefCount(resultObj);
+    return TCL_ERROR;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * BinaryDecode64 --
+ *
+ *	Decode a base64 encoded string.
+ *
+ * Results:
+ *	Interp result set to an byte array object
+ *
+ * Side effects:
+ *	None
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+BinaryDecode64(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const objv[])
+{
+    Tcl_Obj *resultObj = NULL;
+    unsigned char *data, *datastart, *dataend, c = '\0';
+    unsigned char *begin = NULL;
+    unsigned char *cursor = NULL;
+    int strict = 0;
+    int i, index, size, cut = 0, count = 0;
+    enum { OPT_STRICT };
+    static const char *const optStrings[] = { "-strict", NULL };
+
+    if (objc < 2 || objc > 3) {
+	Tcl_WrongNumArgs(interp, 1, objv, "?options? data");
+	return TCL_ERROR;
+    }
+    for (i = 1; i < objc-1; ++i) {
+	if (Tcl_GetIndexFromObj(interp, objv[i], optStrings, "option",
+		TCL_EXACT, &index) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	switch (index) {
+	case OPT_STRICT:
+	    strict = 1;
+	    break;
+	}
+    }
+
+    TclNewObj(resultObj);
+    datastart = data = (unsigned char *)
+	    TclGetStringFromObj(objv[objc-1], &count);
+    dataend = data + count;
+    size = ((count + 3) & ~3) * 3 / 4;
+    begin = cursor = Tcl_SetByteArrayLength(resultObj, size);
+    while (data < dataend) {
+	unsigned long value = 0;
+
+	/*
+	 * Decode the current block. Each base64 block consists of four input
+	 * characters A-Z, a-z, 0-9, +, or /. Each character supplies six bits
+	 * of output data, so each block's output is 24 bits (three bytes) in
+	 * length. The final block can be shorter by one or two bytes, denoted
+	 * by the input ending with one or two ='s, respectively.
+	 */
+
+	for (i = 0; i < 4; i++) {
+	    /*
+	     * Get the next input character. At end of input, pad with at most
+	     * two ='s. If more than two ='s would be needed, instead discard
+	     * the block read thus far.
+	     */
+
+	    if (data < dataend) {
+		c = *data++;
+	    } else if (i > 1) {
+		c = '=';
+	    } else {
+		cut += 3;
+		break;
+	    }
+
+	    /*
+	     * Load the character into the block value. Handle ='s specially
+	     * because they're only valid as the last character or two of the
+	     * final block of input. Unless strict mode is enabled, skip any
+	     * input whitespace characters.
+	     */
+
+	    if (cut) {
+		if (c == '=' && i > 1) {
+		     value <<= 6;
+		     cut++;
+		} else if (!strict && isspace(c)) {
+		     i--;
+		} else {
+		    goto bad64;
+		}
+	    } else if (c >= 'A' && c <= 'Z') {
+		value = (value << 6) | ((c - 'A') & 0x3f);
+	    } else if (c >= 'a' && c <= 'z') {
+		value = (value << 6) | ((c - 'a' + 26) & 0x3f);
+	    } else if (c >= '0' && c <= '9') {
+		value = (value << 6) | ((c - '0' + 52) & 0x3f);
+	    } else if (c == '+') {
+		value = (value << 6) | 0x3e;
+	    } else if (c == '/') {
+		value = (value << 6) | 0x3f;
+	    } else if (c == '=') {
+		value <<= 6;
+		cut++;
+	    } else if (strict || !isspace(c)) {
+		goto bad64;
+	    } else {
+		i--;
+	    }
+	}
+	*cursor++ = UCHAR((value >> 16) & 0xff);
+	*cursor++ = UCHAR((value >> 8) & 0xff);
+	*cursor++ = UCHAR(value & 0xff);
+
+	/*
+	 * Since = is only valid within the final block, if it was encountered
+	 * but there are still more input characters, confirm that strict mode
+	 * is off and all subsequent characters are whitespace.
+	 */
+
+	if (cut && data < dataend) {
+	    if (strict) {
+		goto bad64;
+	    }
+	    for (; data < dataend; data++) {
+		if (!isspace(*data)) {
+		    goto bad64;
+		}
+	    }
+	}
+    }
+    Tcl_SetByteArrayLength(resultObj, cursor - begin - cut);
+    Tcl_SetObjResult(interp, resultObj);
+    return TCL_OK;
+
+  bad64:
+    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+	    "invalid base64 character \"%c\" at position %d",
+	    (char) c, (int) (data - datastart - 1)));
+    TclDecrRefCount(resultObj);
+    return TCL_ERROR;
+}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
+
diff --git a/generic/tclCkalloc.c b/generic/tclCkalloc.c
new file mode 100644
index 0000000..70e64f0
--- /dev/null
+++ b/generic/tclCkalloc.c
@@ -0,0 +1,1328 @@
+/*
+ * tclCkalloc.c --
+ *
+ *    Interface to malloc and free that provides support for debugging
+ *    problems involving overwritten, double freeing memory and loss of
+ *    memory.
+ *
+ * Copyright (c) 1991-1994 The Regents of the University of California.
+ * Copyright (c) 1994-1997 Sun Microsystems, Inc.
+ * Copyright (c) 1998-1999 by Scriptics Corporation.
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ *
+ * This code contributed by Karl Lehenbauer and Mark Diekhans
+ */
+
+#include "tclInt.h"
+
+#define FALSE	0
+#define TRUE	1
+
+#undef Tcl_Alloc
+#undef Tcl_Free
+#undef Tcl_Realloc
+#undef Tcl_AttemptAlloc
+#undef Tcl_AttemptRealloc
+
+#ifdef TCL_MEM_DEBUG
+
+/*
+ * One of the following structures is allocated each time the
+ * "memory tag" command is invoked, to hold the current tag.
+ */
+
+typedef struct MemTag {
+    int refCount;		/* Number of mem_headers referencing this
+				 * tag. */
+    char string[1];		/* Actual size of string will be as large as
+				 * needed for actual tag. This must be the
+				 * last field in the structure. */
+} MemTag;
+
+#define TAG_SIZE(bytesInString) ((unsigned) ((TclOffset(MemTag, string) + 1) + bytesInString))
+
+static MemTag *curTagPtr = NULL;/* Tag to use in all future mem_headers (set
+				 * by "memory tag" command). */
+
+/*
+ * One of the following structures is allocated just before each dynamically
+ * allocated chunk of memory, both to record information about the chunk and
+ * to help detect chunk under-runs.
+ */
+
+#define LOW_GUARD_SIZE (8 + (32 - (sizeof(long) + sizeof(int)))%8)
+struct mem_header {
+    struct mem_header *flink;
+    struct mem_header *blink;
+    MemTag *tagPtr;		/* Tag from "memory tag" command; may be
+				 * NULL. */
+    const char *file;
+    long length;
+    int line;
+    unsigned char low_guard[LOW_GUARD_SIZE];
+				/* Aligns body on 8-byte boundary, plus
+				 * provides at least 8 additional guard bytes
+				 * to detect underruns. */
+    char body[1];		/* First byte of client's space. Actual size
+				 * of this field will be larger than one. */
+};
+
+static struct mem_header *allocHead = NULL;  /* List of allocated structures */
+
+#define GUARD_VALUE  0141
+
+/*
+ * The following macro determines the amount of guard space *above* each chunk
+ * of memory.
+ */
+
+#define HIGH_GUARD_SIZE 8
+
+/*
+ * The following macro computes the offset of the "body" field within
+ * mem_header. It is used to get back to the header pointer from the body
+ * pointer that's used by clients.
+ */
+
+#define BODY_OFFSET \
+	((size_t) (&((struct mem_header *) 0)->body))
+
+static int total_mallocs = 0;
+static int total_frees = 0;
+static size_t current_bytes_malloced = 0;
+static size_t maximum_bytes_malloced = 0;
+static int current_malloc_packets = 0;
+static int maximum_malloc_packets = 0;
+static int break_on_malloc = 0;
+static int trace_on_at_malloc = 0;
+static int alloc_tracing = FALSE;
+static int init_malloced_bodies = TRUE;
+#ifdef MEM_VALIDATE
+static int validate_memory = TRUE;
+#else
+static int validate_memory = FALSE;
+#endif
+
+/*
+ * The following variable indicates to TclFinalizeMemorySubsystem() that it
+ * should dump out the state of memory before exiting. If the value is
+ * non-NULL, it gives the name of the file in which to dump memory usage
+ * information.
+ */
+
+char *tclMemDumpFileName = NULL;
+
+static char *onExitMemDumpFileName = NULL;
+static char dumpFile[100];	/* Records where to dump memory allocation
+				 * information. */
+
+/*
+ * Mutex to serialize allocations. This is a low-level mutex that must be
+ * explicitly initialized. This is necessary because the self initializing
+ * mutexes use ckalloc...
+ */
+
+static Tcl_Mutex *ckallocMutexPtr;
+static int ckallocInit = 0;
+
+/*
+ * Prototypes for procedures defined in this file:
+ */
+
+static int		CheckmemCmd(ClientData clientData, Tcl_Interp *interp,
+			    int argc, const char *argv[]);
+static int		MemoryCmd(ClientData clientData, Tcl_Interp *interp,
+			    int argc, const char *argv[]);
+static void		ValidateMemory(struct mem_header *memHeaderP,
+			    const char *file, int line, int nukeGuards);
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclInitDbCkalloc --
+ *
+ *	Initialize the locks used by the allocator. This is only appropriate
+ *	to call in a single threaded environment, such as during
+ *	TclInitSubsystems.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclInitDbCkalloc(void)
+{
+    if (!ckallocInit) {
+	ckallocInit = 1;
+	ckallocMutexPtr = Tcl_GetAllocMutex();
+#ifndef TCL_THREADS
+	/* Silence compiler warning */
+	(void)ckallocMutexPtr;
+#endif
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclDumpMemoryInfo --
+ *
+ *	Display the global memory management statistics.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclDumpMemoryInfo(
+    ClientData clientData,
+    int flags)
+{
+    char buf[1024];
+
+    if (clientData == NULL) {
+        return 0;
+    }
+    sprintf(buf,
+	    "total mallocs             %10d\n"
+	    "total frees               %10d\n"
+	    "current packets allocated %10d\n"
+	    "current bytes allocated   %10lu\n"
+	    "maximum packets allocated %10d\n"
+	    "maximum bytes allocated   %10lu\n",
+	    total_mallocs,
+	    total_frees,
+	    current_malloc_packets,
+	    (unsigned long)current_bytes_malloced,
+	    maximum_malloc_packets,
+	    (unsigned long)maximum_bytes_malloced);
+    if (flags == 0) {
+	fprintf((FILE *)clientData, "%s", buf);
+    } else {
+	/* Assume objPtr to append to */
+	Tcl_AppendToObj((Tcl_Obj *) clientData, buf, -1);
+    }
+    return 1;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ValidateMemory --
+ *
+ *	Validate memory guard zones for a particular chunk of allocated
+ *	memory.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Prints validation information about the allocated memory to stderr.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+ValidateMemory(
+    struct mem_header *memHeaderP,
+				/* Memory chunk to validate */
+    const char *file,		/* File containing the call to
+				 * Tcl_ValidateAllMemory */
+    int line,			/* Line number of call to
+				 * Tcl_ValidateAllMemory */
+    int nukeGuards)		/* If non-zero, indicates that the memory
+				 * guards are to be reset to 0 after they have
+				 * been printed */
+{
+    unsigned char *hiPtr;
+    size_t idx;
+    int guard_failed = FALSE;
+    int byte;
+
+    for (idx = 0; idx < LOW_GUARD_SIZE; idx++) {
+	byte = *(memHeaderP->low_guard + idx);
+	if (byte != GUARD_VALUE) {
+	    guard_failed = TRUE;
+	    fflush(stdout);
+	    byte &= 0xff;
+	    fprintf(stderr, "low guard byte %d is 0x%x  \t%c\n", (int)idx, byte,
+		    (isprint(UCHAR(byte)) ? byte : ' ')); /* INTL: bytes */
+	}
+    }
+    if (guard_failed) {
+	TclDumpMemoryInfo((ClientData) stderr, 0);
+	fprintf(stderr, "low guard failed at %lx, %s %d\n",
+		(long unsigned) memHeaderP->body, file, line);
+	fflush(stderr);			/* In case name pointer is bad. */
+	fprintf(stderr, "%ld bytes allocated at (%s %d)\n", memHeaderP->length,
+		memHeaderP->file, memHeaderP->line);
+	Tcl_Panic("Memory validation failure");
+    }
+
+    hiPtr = (unsigned char *)memHeaderP->body + memHeaderP->length;
+    for (idx = 0; idx < HIGH_GUARD_SIZE; idx++) {
+	byte = *(hiPtr + idx);
+	if (byte != GUARD_VALUE) {
+	    guard_failed = TRUE;
+	    fflush(stdout);
+	    byte &= 0xff;
+	    fprintf(stderr, "hi guard byte %d is 0x%x  \t%c\n", (int)idx, byte,
+		    (isprint(UCHAR(byte)) ? byte : ' ')); /* INTL: bytes */
+	}
+    }
+
+    if (guard_failed) {
+	TclDumpMemoryInfo((ClientData) stderr, 0);
+	fprintf(stderr, "high guard failed at %lx, %s %d\n",
+		(long unsigned) memHeaderP->body, file, line);
+	fflush(stderr);			/* In case name pointer is bad. */
+	fprintf(stderr, "%ld bytes allocated at (%s %d)\n",
+		memHeaderP->length, memHeaderP->file,
+		memHeaderP->line);
+	Tcl_Panic("Memory validation failure");
+    }
+
+    if (nukeGuards) {
+	memset(memHeaderP->low_guard, 0, LOW_GUARD_SIZE);
+	memset(hiPtr, 0, HIGH_GUARD_SIZE);
+    }
+
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_ValidateAllMemory --
+ *
+ *	Validate memory guard regions for all allocated memory.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Displays memory validation information to stderr.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_ValidateAllMemory(
+    const char *file,		/* File from which Tcl_ValidateAllMemory was
+				 * called. */
+    int line)			/* Line number of call to
+				 * Tcl_ValidateAllMemory */
+{
+    struct mem_header *memScanP;
+
+    if (!ckallocInit) {
+	TclInitDbCkalloc();
+    }
+    Tcl_MutexLock(ckallocMutexPtr);
+    for (memScanP = allocHead; memScanP != NULL; memScanP = memScanP->flink) {
+	ValidateMemory(memScanP, file, line, FALSE);
+    }
+    Tcl_MutexUnlock(ckallocMutexPtr);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_DumpActiveMemory --
+ *
+ *	Displays all allocated memory to a file; if no filename is given,
+ *	information will be written to stderr.
+ *
+ * Results:
+ *	Return TCL_ERROR if an error accessing the file occurs, `errno' will
+ *	have the file error number left in it.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_DumpActiveMemory(
+    const char *fileName)	/* Name of the file to write info to */
+{
+    FILE *fileP;
+    struct mem_header *memScanP;
+    char *address;
+
+    if (fileName == NULL) {
+	fileP = stderr;
+    } else {
+	fileP = fopen(fileName, "w");
+	if (fileP == NULL) {
+	    return TCL_ERROR;
+	}
+    }
+
+    Tcl_MutexLock(ckallocMutexPtr);
+    for (memScanP = allocHead; memScanP != NULL; memScanP = memScanP->flink) {
+	address = &memScanP->body[0];
+	fprintf(fileP, "%8lx - %8lx  %7ld @ %s %d %s",
+		(long unsigned) address,
+		(long unsigned) address + memScanP->length - 1,
+		memScanP->length, memScanP->file, memScanP->line,
+		(memScanP->tagPtr == NULL) ? "" : memScanP->tagPtr->string);
+	(void) fputc('\n', fileP);
+    }
+    Tcl_MutexUnlock(ckallocMutexPtr);
+
+    if (fileP != stderr) {
+	fclose(fileP);
+    }
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_DbCkalloc - debugging ckalloc
+ *
+ *	Allocate the requested amount of space plus some extra for guard bands
+ *	at both ends of the request, plus a size, panicing if there isn't
+ *	enough space, then write in the guard bands and return the address of
+ *	the space in the middle that the user asked for.
+ *
+ *	The second and third arguments are file and line, these contain the
+ *	filename and line number corresponding to the caller. These are sent
+ *	by the ckalloc macro; it uses the preprocessor autodefines __FILE__
+ *	and __LINE__.
+ *
+ *----------------------------------------------------------------------
+ */
+
+char *
+Tcl_DbCkalloc(
+    unsigned int size,
+    const char *file,
+    int line)
+{
+    struct mem_header *result = NULL;
+
+    if (validate_memory) {
+	Tcl_ValidateAllMemory(file, line);
+    }
+
+    /* Don't let size argument to TclpAlloc overflow */
+    if (size <= UINT_MAX - HIGH_GUARD_SIZE -sizeof(struct mem_header)) {
+	result = (struct mem_header *) TclpAlloc((unsigned)size +
+		sizeof(struct mem_header) + HIGH_GUARD_SIZE);
+    }
+    if (result == NULL) {
+	fflush(stdout);
+	TclDumpMemoryInfo((ClientData) stderr, 0);
+	Tcl_Panic("unable to alloc %u bytes, %s line %d", size, file, line);
+    }
+
+    /*
+     * Fill in guard zones and size. Also initialize the contents of the block
+     * with bogus bytes to detect uses of initialized data. Link into
+     * allocated list.
+     */
+
+    if (init_malloced_bodies) {
+	memset(result, GUARD_VALUE,
+		size + sizeof(struct mem_header) + HIGH_GUARD_SIZE);
+    } else {
+	memset(result->low_guard, GUARD_VALUE, LOW_GUARD_SIZE);
+	memset(result->body + size, GUARD_VALUE, HIGH_GUARD_SIZE);
+    }
+    if (!ckallocInit) {
+	TclInitDbCkalloc();
+    }
+    Tcl_MutexLock(ckallocMutexPtr);
+    result->length = size;
+    result->tagPtr = curTagPtr;
+    if (curTagPtr != NULL) {
+	curTagPtr->refCount++;
+    }
+    result->file = file;
+    result->line = line;
+    result->flink = allocHead;
+    result->blink = NULL;
+
+    if (allocHead != NULL) {
+	allocHead->blink = result;
+    }
+    allocHead = result;
+
+    total_mallocs++;
+    if (trace_on_at_malloc && (total_mallocs >= trace_on_at_malloc)) {
+	(void) fflush(stdout);
+	fprintf(stderr, "reached malloc trace enable point (%d)\n",
+		total_mallocs);
+	fflush(stderr);
+	alloc_tracing = TRUE;
+	trace_on_at_malloc = 0;
+    }
+
+    if (alloc_tracing) {
+	fprintf(stderr,"ckalloc %lx %u %s %d\n",
+		(long unsigned int) result->body, size, file, line);
+    }
+
+    if (break_on_malloc && (total_mallocs >= break_on_malloc)) {
+	break_on_malloc = 0;
+	(void) fflush(stdout);
+	Tcl_Panic("reached malloc break limit (%d)", total_mallocs);
+    }
+
+    current_malloc_packets++;
+    if (current_malloc_packets > maximum_malloc_packets) {
+	maximum_malloc_packets = current_malloc_packets;
+    }
+    current_bytes_malloced += size;
+    if (current_bytes_malloced > maximum_bytes_malloced) {
+	maximum_bytes_malloced = current_bytes_malloced;
+    }
+
+    Tcl_MutexUnlock(ckallocMutexPtr);
+
+    return result->body;
+}
+
+char *
+Tcl_AttemptDbCkalloc(
+    unsigned int size,
+    const char *file,
+    int line)
+{
+    struct mem_header *result = NULL;
+
+    if (validate_memory) {
+	Tcl_ValidateAllMemory(file, line);
+    }
+
+    /* Don't let size argument to TclpAlloc overflow */
+    if (size <= UINT_MAX - HIGH_GUARD_SIZE - sizeof(struct mem_header)) {
+	result = (struct mem_header *) TclpAlloc((unsigned)size +
+		sizeof(struct mem_header) + HIGH_GUARD_SIZE);
+    }
+    if (result == NULL) {
+	fflush(stdout);
+	TclDumpMemoryInfo((ClientData) stderr, 0);
+	return NULL;
+    }
+
+    /*
+     * Fill in guard zones and size. Also initialize the contents of the block
+     * with bogus bytes to detect uses of initialized data. Link into
+     * allocated list.
+     */
+    if (init_malloced_bodies) {
+	memset(result, GUARD_VALUE,
+		size + sizeof(struct mem_header) + HIGH_GUARD_SIZE);
+    } else {
+	memset(result->low_guard, GUARD_VALUE, LOW_GUARD_SIZE);
+	memset(result->body + size, GUARD_VALUE, HIGH_GUARD_SIZE);
+    }
+    if (!ckallocInit) {
+	TclInitDbCkalloc();
+    }
+    Tcl_MutexLock(ckallocMutexPtr);
+    result->length = size;
+    result->tagPtr = curTagPtr;
+    if (curTagPtr != NULL) {
+	curTagPtr->refCount++;
+    }
+    result->file = file;
+    result->line = line;
+    result->flink = allocHead;
+    result->blink = NULL;
+
+    if (allocHead != NULL) {
+	allocHead->blink = result;
+    }
+    allocHead = result;
+
+    total_mallocs++;
+    if (trace_on_at_malloc && (total_mallocs >= trace_on_at_malloc)) {
+	(void) fflush(stdout);
+	fprintf(stderr, "reached malloc trace enable point (%d)\n",
+		total_mallocs);
+	fflush(stderr);
+	alloc_tracing = TRUE;
+	trace_on_at_malloc = 0;
+    }
+
+    if (alloc_tracing) {
+	fprintf(stderr,"ckalloc %lx %u %s %d\n",
+		(long unsigned int) result->body, size, file, line);
+    }
+
+    if (break_on_malloc && (total_mallocs >= break_on_malloc)) {
+	break_on_malloc = 0;
+	(void) fflush(stdout);
+	Tcl_Panic("reached malloc break limit (%d)", total_mallocs);
+    }
+
+    current_malloc_packets++;
+    if (current_malloc_packets > maximum_malloc_packets) {
+	maximum_malloc_packets = current_malloc_packets;
+    }
+    current_bytes_malloced += size;
+    if (current_bytes_malloced > maximum_bytes_malloced) {
+	maximum_bytes_malloced = current_bytes_malloced;
+    }
+
+    Tcl_MutexUnlock(ckallocMutexPtr);
+
+    return result->body;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_DbCkfree - debugging ckfree
+ *
+ *	Verify that the low and high guards are intact, and if so then free
+ *	the buffer else Tcl_Panic.
+ *
+ *	The guards are erased after being checked to catch duplicate frees.
+ *
+ *	The second and third arguments are file and line, these contain the
+ *	filename and line number corresponding to the caller. These are sent
+ *	by the ckfree macro; it uses the preprocessor autodefines __FILE__ and
+ *	__LINE__.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_DbCkfree(
+    char *ptr,
+    const char *file,
+    int line)
+{
+    struct mem_header *memp;
+
+    if (ptr == NULL) {
+	return;
+    }
+
+    /*
+     * The following cast is *very* tricky. Must convert the pointer to an
+     * integer before doing arithmetic on it, because otherwise the arithmetic
+     * will be done differently (and incorrectly) on word-addressed machines
+     * such as Crays (will subtract only bytes, even though BODY_OFFSET is in
+     * words on these machines).
+     */
+
+    memp = (struct mem_header *) (((size_t) ptr) - BODY_OFFSET);
+
+    if (alloc_tracing) {
+	fprintf(stderr, "ckfree %lx %ld %s %d\n",
+		(long unsigned int) memp->body, memp->length, file, line);
+    }
+
+    if (validate_memory) {
+	Tcl_ValidateAllMemory(file, line);
+    }
+
+    Tcl_MutexLock(ckallocMutexPtr);
+    ValidateMemory(memp, file, line, TRUE);
+    if (init_malloced_bodies) {
+	memset(ptr, GUARD_VALUE, (size_t) memp->length);
+    }
+
+    total_frees++;
+    current_malloc_packets--;
+    current_bytes_malloced -= memp->length;
+
+    if (memp->tagPtr != NULL) {
+	memp->tagPtr->refCount--;
+	if ((memp->tagPtr->refCount == 0) && (curTagPtr != memp->tagPtr)) {
+	    TclpFree((char *) memp->tagPtr);
+	}
+    }
+
+    /*
+     * Delink from allocated list
+     */
+
+    if (memp->flink != NULL) {
+	memp->flink->blink = memp->blink;
+    }
+    if (memp->blink != NULL) {
+	memp->blink->flink = memp->flink;
+    }
+    if (allocHead == memp) {
+	allocHead = memp->flink;
+    }
+    TclpFree((char *) memp);
+    Tcl_MutexUnlock(ckallocMutexPtr);
+}
+
+/*
+ *--------------------------------------------------------------------
+ *
+ * Tcl_DbCkrealloc - debugging ckrealloc
+ *
+ *	Reallocate a chunk of memory by allocating a new one of the right
+ *	size, copying the old data to the new location, and then freeing the
+ *	old memory space, using all the memory checking features of this
+ *	package.
+ *
+ *--------------------------------------------------------------------
+ */
+
+char *
+Tcl_DbCkrealloc(
+    char *ptr,
+    unsigned int size,
+    const char *file,
+    int line)
+{
+    char *newPtr;
+    unsigned int copySize;
+    struct mem_header *memp;
+
+    if (ptr == NULL) {
+	return Tcl_DbCkalloc(size, file, line);
+    }
+
+    /*
+     * See comment from Tcl_DbCkfree before you change the following line.
+     */
+
+    memp = (struct mem_header *) (((size_t) ptr) - BODY_OFFSET);
+
+    copySize = size;
+    if (copySize > (unsigned int) memp->length) {
+	copySize = memp->length;
+    }
+    newPtr = Tcl_DbCkalloc(size, file, line);
+    memcpy(newPtr, ptr, (size_t) copySize);
+    Tcl_DbCkfree(ptr, file, line);
+    return newPtr;
+}
+
+char *
+Tcl_AttemptDbCkrealloc(
+    char *ptr,
+    unsigned int size,
+    const char *file,
+    int line)
+{
+    char *newPtr;
+    unsigned int copySize;
+    struct mem_header *memp;
+
+    if (ptr == NULL) {
+	return Tcl_AttemptDbCkalloc(size, file, line);
+    }
+
+    /*
+     * See comment from Tcl_DbCkfree before you change the following line.
+     */
+
+    memp = (struct mem_header *) (((size_t) ptr) - BODY_OFFSET);
+
+    copySize = size;
+    if (copySize > (unsigned int) memp->length) {
+	copySize = memp->length;
+    }
+    newPtr = Tcl_AttemptDbCkalloc(size, file, line);
+    if (newPtr == NULL) {
+	return NULL;
+    }
+    memcpy(newPtr, ptr, (size_t) copySize);
+    Tcl_DbCkfree(ptr, file, line);
+    return newPtr;
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_Alloc, et al. --
+ *
+ *	These functions are defined in terms of the debugging versions when
+ *	TCL_MEM_DEBUG is set.
+ *
+ * Results:
+ *	Same as the debug versions.
+ *
+ * Side effects:
+ *	Same as the debug versions.
+ *
+ *----------------------------------------------------------------------
+ */
+
+char *
+Tcl_Alloc(
+    unsigned int size)
+{
+    return Tcl_DbCkalloc(size, "unknown", 0);
+}
+
+char *
+Tcl_AttemptAlloc(
+    unsigned int size)
+{
+    return Tcl_AttemptDbCkalloc(size, "unknown", 0);
+}
+
+void
+Tcl_Free(
+    char *ptr)
+{
+    Tcl_DbCkfree(ptr, "unknown", 0);
+}
+
+char *
+Tcl_Realloc(
+    char *ptr,
+    unsigned int size)
+{
+    return Tcl_DbCkrealloc(ptr, size, "unknown", 0);
+}
+char *
+Tcl_AttemptRealloc(
+    char *ptr,
+    unsigned int size)
+{
+    return Tcl_AttemptDbCkrealloc(ptr, size, "unknown", 0);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * MemoryCmd --
+ *
+ *	Implements the Tcl "memory" command, which provides Tcl-level control
+ *	of Tcl memory debugging information.
+ *		memory active $file
+ *		memory break_on_malloc $count
+ *		memory info
+ *		memory init on|off
+ *		memory onexit $file
+ *		memory tag $string
+ *		memory trace on|off
+ *		memory trace_on_at_malloc $count
+ *		memory validate on|off
+ *
+ * Results:
+ *	Standard TCL results.
+ *
+ *----------------------------------------------------------------------
+ */
+	/* ARGSUSED */
+static int
+MemoryCmd(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int argc,
+    const char *argv[])
+{
+    const char *fileName;
+    FILE *fileP;
+    Tcl_DString buffer;
+    int result;
+    size_t len;
+
+    if (argc < 2) {
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+                "wrong # args: should be \"%s option [args..]\"", argv[0]));
+	return TCL_ERROR;
+    }
+
+    if (strcmp(argv[1], "active") == 0 || strcmp(argv[1], "display") == 0) {
+	if (argc != 3) {
+	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+                    "wrong # args: should be \"%s %s file\"",
+                    argv[0], argv[1]));
+	    return TCL_ERROR;
+	}
+	fileName = Tcl_TranslateFileName(interp, argv[2], &buffer);
+	if (fileName == NULL) {
+	    return TCL_ERROR;
+	}
+	result = Tcl_DumpActiveMemory(fileName);
+	Tcl_DStringFree(&buffer);
+	if (result != TCL_OK) {
+	    Tcl_SetObjResult(interp, Tcl_ObjPrintf("error accessing %s: %s",
+                    argv[2], Tcl_PosixError(interp)));
+	    return TCL_ERROR;
+	}
+	return TCL_OK;
+    }
+    if (strcmp(argv[1],"break_on_malloc") == 0) {
+	if (argc != 3) {
+	    goto argError;
+	}
+	if (Tcl_GetInt(interp, argv[2], &break_on_malloc) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	return TCL_OK;
+    }
+    if (strcmp(argv[1],"info") == 0) {
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		"%-25s %10d\n%-25s %10d\n%-25s %10d\n%-25s %10lu\n%-25s %10d\n%-25s %10lu\n",
+		"total mallocs", total_mallocs, "total frees", total_frees,
+		"current packets allocated", current_malloc_packets,
+		"current bytes allocated", (unsigned long)current_bytes_malloced,
+		"maximum packets allocated", maximum_malloc_packets,
+		"maximum bytes allocated", (unsigned long)maximum_bytes_malloced));
+	return TCL_OK;
+    }
+    if (strcmp(argv[1], "init") == 0) {
+	if (argc != 3) {
+	    goto bad_suboption;
+	}
+	init_malloced_bodies = (strcmp(argv[2],"on") == 0);
+	return TCL_OK;
+    }
+    if (strcmp(argv[1], "objs") == 0) {
+	if (argc != 3) {
+	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+                    "wrong # args: should be \"%s objs file\"", argv[0]));
+	    return TCL_ERROR;
+	}
+	fileName = Tcl_TranslateFileName(interp, argv[2], &buffer);
+	if (fileName == NULL) {
+	    return TCL_ERROR;
+	}
+	fileP = fopen(fileName, "w");
+	if (fileP == NULL) {
+	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+                    "cannot open output file: %s",
+                    Tcl_PosixError(interp)));
+	    return TCL_ERROR;
+	}
+	TclDbDumpActiveObjects(fileP);
+	fclose(fileP);
+	Tcl_DStringFree(&buffer);
+	return TCL_OK;
+    }
+    if (strcmp(argv[1],"onexit") == 0) {
+	if (argc != 3) {
+	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+                    "wrong # args: should be \"%s onexit file\"", argv[0]));
+	    return TCL_ERROR;
+	}
+	fileName = Tcl_TranslateFileName(interp, argv[2], &buffer);
+	if (fileName == NULL) {
+	    return TCL_ERROR;
+	}
+	onExitMemDumpFileName = dumpFile;
+	strcpy(onExitMemDumpFileName,fileName);
+	Tcl_DStringFree(&buffer);
+	return TCL_OK;
+    }
+    if (strcmp(argv[1],"tag") == 0) {
+	if (argc != 3) {
+	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+                    "wrong # args: should be \"%s tag string\"", argv[0]));
+	    return TCL_ERROR;
+	}
+	if ((curTagPtr != NULL) && (curTagPtr->refCount == 0)) {
+	    TclpFree((char *) curTagPtr);
+	}
+	len = strlen(argv[2]);
+	curTagPtr = (MemTag *) TclpAlloc(TAG_SIZE(len));
+	curTagPtr->refCount = 0;
+	memcpy(curTagPtr->string, argv[2], len + 1);
+	return TCL_OK;
+    }
+    if (strcmp(argv[1],"trace") == 0) {
+	if (argc != 3) {
+	    goto bad_suboption;
+	}
+	alloc_tracing = (strcmp(argv[2],"on") == 0);
+	return TCL_OK;
+    }
+
+    if (strcmp(argv[1],"trace_on_at_malloc") == 0) {
+	if (argc != 3) {
+	    goto argError;
+	}
+	if (Tcl_GetInt(interp, argv[2], &trace_on_at_malloc) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	return TCL_OK;
+    }
+    if (strcmp(argv[1],"validate") == 0) {
+	if (argc != 3) {
+	    goto bad_suboption;
+	}
+	validate_memory = (strcmp(argv[2],"on") == 0);
+	return TCL_OK;
+    }
+
+    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+            "bad option \"%s\": should be active, break_on_malloc, info, "
+            "init, objs, onexit, tag, trace, trace_on_at_malloc, or validate",
+            argv[1]));
+    return TCL_ERROR;
+
+  argError:
+    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+            "wrong # args: should be \"%s %s count\"", argv[0], argv[1]));
+    return TCL_ERROR;
+
+  bad_suboption:
+    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+            "wrong # args: should be \"%s %s on|off\"", argv[0], argv[1]));
+    return TCL_ERROR;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * CheckmemCmd --
+ *
+ *	This is the command procedure for the "checkmem" command, which causes
+ *	the application to exit after printing information about memory usage
+ *	to the file passed to this command as its first argument.
+ *
+ * Results:
+ *	Returns a standard Tcl completion code.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+CheckmemCmd(
+    ClientData clientData,	/* Not used. */
+    Tcl_Interp *interp,		/* Interpreter for evaluation. */
+    int argc,			/* Number of arguments. */
+    const char *argv[])		/* String values of arguments. */
+{
+    if (argc != 2) {
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+                "wrong # args: should be \"%s fileName\"", argv[0]));
+	return TCL_ERROR;
+    }
+    tclMemDumpFileName = dumpFile;
+    strcpy(tclMemDumpFileName, argv[1]);
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_InitMemory --
+ *
+ *	Create the "memory" and "checkmem" commands in the given interpreter.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	New commands are added to the interpreter.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_InitMemory(
+    Tcl_Interp *interp)		/* Interpreter in which commands should be
+				 * added */
+{
+    TclInitDbCkalloc();
+    Tcl_CreateCommand(interp, "memory", MemoryCmd, NULL, NULL);
+    Tcl_CreateCommand(interp, "checkmem", CheckmemCmd, NULL, NULL);
+}
+
+
+#else	/* TCL_MEM_DEBUG */
+
+/* This is the !TCL_MEM_DEBUG case */
+
+#undef Tcl_InitMemory
+#undef Tcl_DumpActiveMemory
+#undef Tcl_ValidateAllMemory
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_Alloc --
+ *
+ *	Interface to TclpAlloc when TCL_MEM_DEBUG is disabled. It does check
+ *	that memory was actually allocated.
+ *
+ *----------------------------------------------------------------------
+ */
+
+char *
+Tcl_Alloc(
+    unsigned int size)
+{
+    char *result;
+
+    result = TclpAlloc(size);
+
+    /*
+     * Most systems will not alloc(0), instead bumping it to one so that NULL
+     * isn't returned. Some systems (AIX, Tru64) will alloc(0) by returning
+     * NULL, so we have to check that the NULL we get is not in response to
+     * alloc(0).
+     *
+     * The ANSI spec actually says that systems either return NULL *or* a
+     * special pointer on failure, but we only check for NULL
+     */
+
+    if ((result == NULL) && size) {
+	Tcl_Panic("unable to alloc %u bytes", size);
+    }
+    return result;
+}
+
+char *
+Tcl_DbCkalloc(
+    unsigned int size,
+    const char *file,
+    int line)
+{
+    char *result;
+
+    result = (char *) TclpAlloc(size);
+
+    if ((result == NULL) && size) {
+	fflush(stdout);
+	Tcl_Panic("unable to alloc %u bytes, %s line %d", size, file, line);
+    }
+    return result;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_AttemptAlloc --
+ *
+ *	Interface to TclpAlloc when TCL_MEM_DEBUG is disabled. It does not
+ *	check that memory was actually allocated.
+ *
+ *----------------------------------------------------------------------
+ */
+
+char *
+Tcl_AttemptAlloc(
+    unsigned int size)
+{
+    char *result;
+
+    result = TclpAlloc(size);
+    return result;
+}
+
+char *
+Tcl_AttemptDbCkalloc(
+    unsigned int size,
+    const char *file,
+    int line)
+{
+    char *result;
+
+    result = (char *) TclpAlloc(size);
+    return result;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_Realloc --
+ *
+ *	Interface to TclpRealloc when TCL_MEM_DEBUG is disabled. It does check
+ *	that memory was actually allocated.
+ *
+ *----------------------------------------------------------------------
+ */
+
+char *
+Tcl_Realloc(
+    char *ptr,
+    unsigned int size)
+{
+    char *result;
+
+    result = TclpRealloc(ptr, size);
+
+    if ((result == NULL) && size) {
+	Tcl_Panic("unable to realloc %u bytes", size);
+    }
+    return result;
+}
+
+char *
+Tcl_DbCkrealloc(
+    char *ptr,
+    unsigned int size,
+    const char *file,
+    int line)
+{
+    char *result;
+
+    result = (char *) TclpRealloc(ptr, size);
+
+    if ((result == NULL) && size) {
+	fflush(stdout);
+	Tcl_Panic("unable to realloc %u bytes, %s line %d", size, file, line);
+    }
+    return result;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_AttemptRealloc --
+ *
+ *	Interface to TclpRealloc when TCL_MEM_DEBUG is disabled. It does not
+ *	check that memory was actually allocated.
+ *
+ *----------------------------------------------------------------------
+ */
+
+char *
+Tcl_AttemptRealloc(
+    char *ptr,
+    unsigned int size)
+{
+    char *result;
+
+    result = TclpRealloc(ptr, size);
+    return result;
+}
+
+char *
+Tcl_AttemptDbCkrealloc(
+    char *ptr,
+    unsigned int size,
+    const char *file,
+    int line)
+{
+    char *result;
+
+    result = (char *) TclpRealloc(ptr, size);
+    return result;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_Free --
+ *
+ *	Interface to TclpFree when TCL_MEM_DEBUG is disabled. Done here rather
+ *	in the macro to keep some modules from being compiled with
+ *	TCL_MEM_DEBUG enabled and some with it disabled.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_Free(
+    char *ptr)
+{
+    TclpFree(ptr);
+}
+
+void
+Tcl_DbCkfree(
+    char *ptr,
+    const char *file,
+    int line)
+{
+    TclpFree(ptr);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_InitMemory --
+ *
+ *	Dummy initialization for memory command, which is only available if
+ *	TCL_MEM_DEBUG is on.
+ *
+ *----------------------------------------------------------------------
+ */
+	/* ARGSUSED */
+void
+Tcl_InitMemory(
+    Tcl_Interp *interp)
+{
+}
+
+int
+Tcl_DumpActiveMemory(
+    const char *fileName)
+{
+    return TCL_OK;
+}
+
+void
+Tcl_ValidateAllMemory(
+    const char *file,
+    int line)
+{
+}
+
+int
+TclDumpMemoryInfo(
+    ClientData clientData,
+    int flags)
+{
+    return 1;
+}
+
+#endif	/* TCL_MEM_DEBUG */
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * TclFinalizeMemorySubsystem --
+ *
+ *	This procedure is called to finalize all the structures that are used
+ *	by the memory allocator on a per-process basis.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	This subsystem is self-initializing, since memory can be allocated
+ *	before Tcl is formally initialized. After this call, this subsystem
+ *	has been reset to its initial state and is usable again.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+void
+TclFinalizeMemorySubsystem(void)
+{
+#ifdef TCL_MEM_DEBUG
+    if (tclMemDumpFileName != NULL) {
+	Tcl_DumpActiveMemory(tclMemDumpFileName);
+    } else if (onExitMemDumpFileName != NULL) {
+	Tcl_DumpActiveMemory(onExitMemDumpFileName);
+    }
+
+    Tcl_MutexLock(ckallocMutexPtr);
+
+    if (curTagPtr != NULL) {
+	TclpFree((char *) curTagPtr);
+	curTagPtr = NULL;
+    }
+    allocHead = NULL;
+
+    Tcl_MutexUnlock(ckallocMutexPtr);
+#endif
+
+#if USE_TCLALLOC
+    TclFinalizeAllocSubsystem();
+#endif
+}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/generic/tclClock.c b/generic/tclClock.c
new file mode 100644
index 0000000..c3b29e9
--- /dev/null
+++ b/generic/tclClock.c
@@ -0,0 +1,2079 @@
+/*
+ * tclClock.c --
+ *
+ *	Contains the time and date related commands. This code is derived from
+ *	the time and date facilities of TclX, by Mark Diekhans and Karl
+ *	Lehenbauer.
+ *
+ * Copyright 1991-1995 Karl Lehenbauer and Mark Diekhans.
+ * Copyright (c) 1995 Sun Microsystems, Inc.
+ * Copyright (c) 2004 by Kevin B. Kenny. All rights reserved.
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#include "tclInt.h"
+
+/*
+ * Windows has mktime. The configurators do not check.
+ */
+
+#ifdef _WIN32
+#define HAVE_MKTIME 1
+#endif
+
+/*
+ * Constants
+ */
+
+#define JULIAN_DAY_POSIX_EPOCH		2440588
+#define SECONDS_PER_DAY			86400
+#define JULIAN_SEC_POSIX_EPOCH	      (((Tcl_WideInt) JULIAN_DAY_POSIX_EPOCH) \
+					* SECONDS_PER_DAY)
+#define FOUR_CENTURIES			146097	/* days */
+#define JDAY_1_JAN_1_CE_JULIAN		1721424
+#define JDAY_1_JAN_1_CE_GREGORIAN	1721426
+#define ONE_CENTURY_GREGORIAN		36524	/* days */
+#define FOUR_YEARS			1461	/* days */
+#define ONE_YEAR			365	/* days */
+
+/*
+ * Table of the days in each month, leap and common years
+ */
+
+static const int hath[2][12] = {
+    {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
+    {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
+};
+static const int daysInPriorMonths[2][13] = {
+    {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365},
+    {0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366}
+};
+
+/*
+ * Enumeration of the string literals used in [clock]
+ */
+
+typedef enum ClockLiteral {
+    LIT__NIL,
+    LIT__DEFAULT_FORMAT,
+    LIT_BCE,		LIT_C,
+    LIT_CANNOT_USE_GMT_AND_TIMEZONE,
+    LIT_CE,
+    LIT_DAYOFMONTH,	LIT_DAYOFWEEK,		LIT_DAYOFYEAR,
+    LIT_ERA,		LIT_GMT,		LIT_GREGORIAN,
+    LIT_INTEGER_VALUE_TOO_LARGE,
+    LIT_ISO8601WEEK,	LIT_ISO8601YEAR,
+    LIT_JULIANDAY,	LIT_LOCALSECONDS,
+    LIT_MONTH,
+    LIT_SECONDS,	LIT_TZNAME,		LIT_TZOFFSET,
+    LIT_YEAR,
+    LIT__END
+} ClockLiteral;
+static const char *const literals[] = {
+    "",
+    "%a %b %d %H:%M:%S %Z %Y",
+    "BCE",		"C",
+    "cannot use -gmt and -timezone in same call",
+    "CE",
+    "dayOfMonth",	"dayOfWeek",		"dayOfYear",
+    "era",		":GMT",			"gregorian",
+    "integer value too large to represent",
+    "iso8601Week",	"iso8601Year",
+    "julianDay",	"localSeconds",
+    "month",
+    "seconds",		"tzName",		"tzOffset",
+    "year"
+};
+
+/*
+ * Structure containing the client data for [clock]
+ */
+
+typedef struct ClockClientData {
+    int refCount;		/* Number of live references. */
+    Tcl_Obj **literals;		/* Pool of object literals. */
+} ClockClientData;
+
+/*
+ * Structure containing the fields used in [clock format] and [clock scan]
+ */
+
+typedef struct TclDateFields {
+    Tcl_WideInt seconds;	/* Time expressed in seconds from the Posix
+				 * epoch */
+    Tcl_WideInt localSeconds;	/* Local time expressed in nominal seconds
+				 * from the Posix epoch */
+    int tzOffset;		/* Time zone offset in seconds east of
+				 * Greenwich */
+    Tcl_Obj *tzName;		/* Time zone name */
+    int julianDay;		/* Julian Day Number in local time zone */
+    enum {BCE=1, CE=0} era;	/* Era */
+    int gregorian;		/* Flag == 1 if the date is Gregorian */
+    int year;			/* Year of the era */
+    int dayOfYear;		/* Day of the year (1 January == 1) */
+    int month;			/* Month number */
+    int dayOfMonth;		/* Day of the month */
+    int iso8601Year;		/* ISO8601 week-based year */
+    int iso8601Week;		/* ISO8601 week number */
+    int dayOfWeek;		/* Day of the week */
+} TclDateFields;
+static const char *const eras[] = { "CE", "BCE", NULL };
+
+/*
+ * Thread specific data block holding a 'struct tm' for the 'gmtime' and
+ * 'localtime' library calls.
+ */
+
+static Tcl_ThreadDataKey tmKey;
+
+/*
+ * Mutex protecting 'gmtime', 'localtime' and 'mktime' calls and the statics
+ * in the date parsing code.
+ */
+
+TCL_DECLARE_MUTEX(clockMutex)
+
+/*
+ * Function prototypes for local procedures in this file:
+ */
+
+static int		ConvertUTCToLocal(Tcl_Interp *,
+			    TclDateFields *, Tcl_Obj *, int);
+static int		ConvertUTCToLocalUsingTable(Tcl_Interp *,
+			    TclDateFields *, int, Tcl_Obj *const[]);
+static int		ConvertUTCToLocalUsingC(Tcl_Interp *,
+			    TclDateFields *, int);
+static int		ConvertLocalToUTC(Tcl_Interp *,
+			    TclDateFields *, Tcl_Obj *, int);
+static int		ConvertLocalToUTCUsingTable(Tcl_Interp *,
+			    TclDateFields *, int, Tcl_Obj *const[]);
+static int		ConvertLocalToUTCUsingC(Tcl_Interp *,
+			    TclDateFields *, int);
+static Tcl_Obj *	LookupLastTransition(Tcl_Interp *, Tcl_WideInt,
+			    int, Tcl_Obj *const *);
+static void		GetYearWeekDay(TclDateFields *, int);
+static void		GetGregorianEraYearDay(TclDateFields *, int);
+static void		GetMonthDay(TclDateFields *);
+static void		GetJulianDayFromEraYearWeekDay(TclDateFields *, int);
+static void		GetJulianDayFromEraYearMonthDay(TclDateFields *, int);
+static int		IsGregorianLeapYear(TclDateFields *);
+static int		WeekdayOnOrBefore(int, int);
+static int		ClockClicksObjCmd(
+			    ClientData clientData, Tcl_Interp *interp,
+			    int objc, Tcl_Obj *const objv[]);
+static int		ClockConvertlocaltoutcObjCmd(
+			    ClientData clientData, Tcl_Interp *interp,
+			    int objc, Tcl_Obj *const objv[]);
+static int		ClockGetdatefieldsObjCmd(
+			    ClientData clientData, Tcl_Interp *interp,
+			    int objc, Tcl_Obj *const objv[]);
+static int		ClockGetjuliandayfromerayearmonthdayObjCmd(
+			    ClientData clientData, Tcl_Interp *interp,
+			    int objc, Tcl_Obj *const objv[]);
+static int		ClockGetjuliandayfromerayearweekdayObjCmd(
+			    ClientData clientData, Tcl_Interp *interp,
+			    int objc, Tcl_Obj *const objv[]);
+static int		ClockGetenvObjCmd(
+			    ClientData clientData, Tcl_Interp *interp,
+			    int objc, Tcl_Obj *const objv[]);
+static int		ClockMicrosecondsObjCmd(
+			    ClientData clientData, Tcl_Interp *interp,
+			    int objc, Tcl_Obj *const objv[]);
+static int		ClockMillisecondsObjCmd(
+			    ClientData clientData, Tcl_Interp *interp,
+			    int objc, Tcl_Obj *const objv[]);
+static int		ClockParseformatargsObjCmd(
+			    ClientData clientData, Tcl_Interp *interp,
+			    int objc, Tcl_Obj *const objv[]);
+static int		ClockSecondsObjCmd(
+			    ClientData clientData, Tcl_Interp *interp,
+			    int objc, Tcl_Obj *const objv[]);
+static struct tm *	ThreadSafeLocalTime(const time_t *);
+static void		TzsetIfNecessary(void);
+static void		ClockDeleteCmdProc(ClientData);
+
+/*
+ * Structure containing description of "native" clock commands to create.
+ */
+
+struct ClockCommand {
+    const char *name;		/* The tail of the command name. The full name
+				 * is "::tcl::clock::<name>". When NULL marks
+				 * the end of the table. */
+    Tcl_ObjCmdProc *objCmdProc;	/* Function that implements the command. This
+				 * will always have the ClockClientData sent
+				 * to it, but may well ignore this data. */
+};
+
+static const struct ClockCommand clockCommands[] = {
+    { "clicks",			ClockClicksObjCmd },
+    { "getenv",			ClockGetenvObjCmd },
+    { "microseconds",		ClockMicrosecondsObjCmd },
+    { "milliseconds",		ClockMillisecondsObjCmd },
+    { "seconds",		ClockSecondsObjCmd },
+    { "Oldscan",		TclClockOldscanObjCmd },
+    { "ConvertLocalToUTC",	ClockConvertlocaltoutcObjCmd },
+    { "GetDateFields",		ClockGetdatefieldsObjCmd },
+    { "GetJulianDayFromEraYearMonthDay",
+		ClockGetjuliandayfromerayearmonthdayObjCmd },
+    { "GetJulianDayFromEraYearWeekDay",
+		ClockGetjuliandayfromerayearweekdayObjCmd },
+    { "ParseFormatArgs",	ClockParseformatargsObjCmd },
+    { NULL, NULL }
+};
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclClockInit --
+ *
+ *	Registers the 'clock' subcommands with the Tcl interpreter and
+ *	initializes its client data (which consists mostly of constant
+ *	Tcl_Obj's that it is too much trouble to keep recreating).
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Installs the commands and creates the client data
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclClockInit(
+    Tcl_Interp *interp)		/* Tcl interpreter */
+{
+    const struct ClockCommand *clockCmdPtr;
+    char cmdName[50];		/* Buffer large enough to hold the string
+				 *::tcl::clock::GetJulianDayFromEraYearMonthDay
+				 * plus a terminating NUL. */
+    ClockClientData *data;
+    int i;
+
+    /*
+     * Safe interps get [::clock] as alias to a master, so do not need their
+     * own copies of the support routines.
+     */
+
+    if (Tcl_IsSafe(interp)) {
+	return;
+    }
+
+    /*
+     * Create the client data, which is a refcounted literal pool.
+     */
+
+    data = ckalloc(sizeof(ClockClientData));
+    data->refCount = 0;
+    data->literals = ckalloc(LIT__END * sizeof(Tcl_Obj*));
+    for (i = 0; i < LIT__END; ++i) {
+	data->literals[i] = Tcl_NewStringObj(literals[i], -1);
+	Tcl_IncrRefCount(data->literals[i]);
+    }
+
+    /*
+     * Install the commands.
+     */
+
+#define TCL_CLOCK_PREFIX_LEN 14 /* == strlen("::tcl::clock::") */
+    memcpy(cmdName, "::tcl::clock::", TCL_CLOCK_PREFIX_LEN);
+    for (clockCmdPtr=clockCommands ; clockCmdPtr->name!=NULL ; clockCmdPtr++) {
+	strcpy(cmdName + TCL_CLOCK_PREFIX_LEN, clockCmdPtr->name);
+	data->refCount++;
+	Tcl_CreateObjCommand(interp, cmdName, clockCmdPtr->objCmdProc, data,
+		ClockDeleteCmdProc);
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ClockConvertlocaltoutcObjCmd --
+ *
+ *	Tcl command that converts a UTC time to a local time by whatever means
+ *	is available.
+ *
+ * Usage:
+ *	::tcl::clock::ConvertUTCToLocal dictionary tzdata changeover
+ *
+ * Parameters:
+ *	dict - Dictionary containing a 'localSeconds' entry.
+ *	tzdata - Time zone data
+ *	changeover - Julian Day of the adoption of the Gregorian calendar.
+ *
+ * Results:
+ *	Returns a standard Tcl result.
+ *
+ * Side effects:
+ *	On success, sets the interpreter result to the given dictionary
+ *	augmented with a 'seconds' field giving the UTC time. On failure,
+ *	leaves an error message in the interpreter result.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+ClockConvertlocaltoutcObjCmd(
+    ClientData clientData,	/* Client data */
+    Tcl_Interp *interp,		/* Tcl interpreter */
+    int objc,			/* Parameter count */
+    Tcl_Obj *const *objv)	/* Parameter vector */
+{
+    ClockClientData *data = clientData;
+    Tcl_Obj *const *literals = data->literals;
+    Tcl_Obj *secondsObj;
+    Tcl_Obj *dict;
+    int changeover;
+    TclDateFields fields;
+    int created = 0;
+    int status;
+
+    /*
+     * Check params and convert time.
+     */
+
+    if (objc != 4) {
+	Tcl_WrongNumArgs(interp, 1, objv, "dict tzdata changeover");
+	return TCL_ERROR;
+    }
+    dict = objv[1];
+    if (Tcl_DictObjGet(interp, dict, literals[LIT_LOCALSECONDS],
+	    &secondsObj)!= TCL_OK) {
+	return TCL_ERROR;
+    }
+    if (secondsObj == NULL) {
+	Tcl_SetObjResult(interp, Tcl_NewStringObj("key \"localseconds\" not "
+		"found in dictionary", -1));
+	return TCL_ERROR;
+    }
+    if ((Tcl_GetWideIntFromObj(interp, secondsObj,
+	    &fields.localSeconds) != TCL_OK)
+	|| (TclGetIntFromObj(interp, objv[3], &changeover) != TCL_OK)
+	|| ConvertLocalToUTC(interp, &fields, objv[2], changeover)) {
+	return TCL_ERROR;
+    }
+
+    /*
+     * Copy-on-write; set the 'seconds' field in the dictionary and place the
+     * modified dictionary in the interpreter result.
+     */
+
+    if (Tcl_IsShared(dict)) {
+	dict = Tcl_DuplicateObj(dict);
+	created = 1;
+	Tcl_IncrRefCount(dict);
+    }
+    status = Tcl_DictObjPut(interp, dict, literals[LIT_SECONDS],
+	    Tcl_NewWideIntObj(fields.seconds));
+    if (status == TCL_OK) {
+	Tcl_SetObjResult(interp, dict);
+    }
+    if (created) {
+	Tcl_DecrRefCount(dict);
+    }
+    return status;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ClockGetdatefieldsObjCmd --
+ *
+ *	Tcl command that determines the values that [clock format] will use in
+ *	formatting a date, and populates a dictionary with them.
+ *
+ * Usage:
+ *	::tcl::clock::GetDateFields seconds tzdata changeover
+ *
+ * Parameters:
+ *	seconds - Time expressed in seconds from the Posix epoch.
+ *	tzdata - Time zone data of the time zone in which time is to be
+ *		 expressed.
+ *	changeover - Julian Day Number at which the current locale adopted
+ *		     the Gregorian calendar
+ *
+ * Results:
+ *	Returns a dictonary populated with the fields:
+ *		seconds - Seconds from the Posix epoch
+ *		localSeconds - Nominal seconds from the Posix epoch in the
+ *			       local time zone.
+ *		tzOffset - Time zone offset in seconds east of Greenwich
+ *		tzName - Time zone name
+ *		julianDay - Julian Day Number in the local time zone
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+ClockGetdatefieldsObjCmd(
+    ClientData clientData,	/* Opaque pointer to literal pool, etc. */
+    Tcl_Interp *interp,		/* Tcl interpreter */
+    int objc,			/* Parameter count */
+    Tcl_Obj *const *objv)	/* Parameter vector */
+{
+    TclDateFields fields;
+    Tcl_Obj *dict;
+    ClockClientData *data = clientData;
+    Tcl_Obj *const *literals = data->literals;
+    int changeover;
+
+    /*
+     * Check params.
+     */
+
+    if (objc != 4) {
+	Tcl_WrongNumArgs(interp, 1, objv, "seconds tzdata changeover");
+	return TCL_ERROR;
+    }
+    if (Tcl_GetWideIntFromObj(interp, objv[1], &fields.seconds) != TCL_OK
+	    || TclGetIntFromObj(interp, objv[3], &changeover) != TCL_OK) {
+	return TCL_ERROR;
+    }
+
+    /*
+     * fields.seconds could be an unsigned number that overflowed. Make sure
+     * that it isn't.
+     */
+
+    if (objv[1]->typePtr == &tclBignumType) {
+	Tcl_SetObjResult(interp, literals[LIT_INTEGER_VALUE_TOO_LARGE]);
+	return TCL_ERROR;
+    }
+
+    /*
+     * Convert UTC time to local.
+     */
+
+    if (ConvertUTCToLocal(interp, &fields, objv[2], changeover) != TCL_OK) {
+	return TCL_ERROR;
+    }
+
+    /*
+     * Extract Julian day.
+     */
+
+    fields.julianDay = (int) ((fields.localSeconds + JULIAN_SEC_POSIX_EPOCH)
+	    / SECONDS_PER_DAY);
+
+    /*
+     * Convert to Julian or Gregorian calendar.
+     */
+
+    GetGregorianEraYearDay(&fields, changeover);
+    GetMonthDay(&fields);
+    GetYearWeekDay(&fields, changeover);
+
+    dict = Tcl_NewDictObj();
+    Tcl_DictObjPut(NULL, dict, literals[LIT_LOCALSECONDS],
+	    Tcl_NewWideIntObj(fields.localSeconds));
+    Tcl_DictObjPut(NULL, dict, literals[LIT_SECONDS],
+	    Tcl_NewWideIntObj(fields.seconds));
+    Tcl_DictObjPut(NULL, dict, literals[LIT_TZNAME], fields.tzName);
+    Tcl_DecrRefCount(fields.tzName);
+    Tcl_DictObjPut(NULL, dict, literals[LIT_TZOFFSET],
+	    Tcl_NewIntObj(fields.tzOffset));
+    Tcl_DictObjPut(NULL, dict, literals[LIT_JULIANDAY],
+	    Tcl_NewIntObj(fields.julianDay));
+    Tcl_DictObjPut(NULL, dict, literals[LIT_GREGORIAN],
+	    Tcl_NewIntObj(fields.gregorian));
+    Tcl_DictObjPut(NULL, dict, literals[LIT_ERA],
+	    literals[fields.era ? LIT_BCE : LIT_CE]);
+    Tcl_DictObjPut(NULL, dict, literals[LIT_YEAR],
+	    Tcl_NewIntObj(fields.year));
+    Tcl_DictObjPut(NULL, dict, literals[LIT_DAYOFYEAR],
+	    Tcl_NewIntObj(fields.dayOfYear));
+    Tcl_DictObjPut(NULL, dict, literals[LIT_MONTH],
+	    Tcl_NewIntObj(fields.month));
+    Tcl_DictObjPut(NULL, dict, literals[LIT_DAYOFMONTH],
+	    Tcl_NewIntObj(fields.dayOfMonth));
+    Tcl_DictObjPut(NULL, dict, literals[LIT_ISO8601YEAR],
+	    Tcl_NewIntObj(fields.iso8601Year));
+    Tcl_DictObjPut(NULL, dict, literals[LIT_ISO8601WEEK],
+	    Tcl_NewIntObj(fields.iso8601Week));
+    Tcl_DictObjPut(NULL, dict, literals[LIT_DAYOFWEEK],
+	    Tcl_NewIntObj(fields.dayOfWeek));
+    Tcl_SetObjResult(interp, dict);
+
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ClockGetjuliandayfromerayearmonthdayObjCmd --
+ *
+ *	Tcl command that converts a time from era-year-month-day to a Julian
+ *	Day Number.
+ *
+ * Parameters:
+ *	dict - Dictionary that contains 'era', 'year', 'month' and
+ *	       'dayOfMonth' keys.
+ *	changeover - Julian Day of changeover to the Gregorian calendar
+ *
+ * Results:
+ *	Result is either TCL_OK, with the interpreter result being the
+ *	dictionary augmented with a 'julianDay' key, or TCL_ERROR,
+ *	with the result being an error message.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+FetchEraField(
+    Tcl_Interp *interp,
+    Tcl_Obj *dict,
+    Tcl_Obj *key,
+    int *storePtr)
+{
+    Tcl_Obj *value = NULL;
+
+    if (Tcl_DictObjGet(interp, dict, key, &value) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    if (value == NULL) {
+	Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		"expected key(s) not found in dictionary", -1));
+	return TCL_ERROR;
+    }
+    return Tcl_GetIndexFromObj(interp, value, eras, "era", TCL_EXACT, storePtr);
+}
+
+static int
+FetchIntField(
+    Tcl_Interp *interp,
+    Tcl_Obj *dict,
+    Tcl_Obj *key,
+    int *storePtr)
+{
+    Tcl_Obj *value = NULL;
+
+    if (Tcl_DictObjGet(interp, dict, key, &value) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    if (value == NULL) {
+	Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		"expected key(s) not found in dictionary", -1));
+	return TCL_ERROR;
+    }
+    return TclGetIntFromObj(interp, value, storePtr);
+}
+
+static int
+ClockGetjuliandayfromerayearmonthdayObjCmd(
+    ClientData clientData,	/* Opaque pointer to literal pool, etc. */
+    Tcl_Interp *interp,		/* Tcl interpreter */
+    int objc,			/* Parameter count */
+    Tcl_Obj *const *objv)	/* Parameter vector */
+{
+    TclDateFields fields;
+    Tcl_Obj *dict;
+    ClockClientData *data = clientData;
+    Tcl_Obj *const *literals = data->literals;
+    int changeover;
+    int copied = 0;
+    int status;
+    int era = 0;
+
+    /*
+     * Check params.
+     */
+
+    if (objc != 3) {
+	Tcl_WrongNumArgs(interp, 1, objv, "dict changeover");
+	return TCL_ERROR;
+    }
+    dict = objv[1];
+    if (FetchEraField(interp, dict, literals[LIT_ERA], &era) != TCL_OK
+	    || FetchIntField(interp, dict, literals[LIT_YEAR], &fields.year)
+		!= TCL_OK
+	    || FetchIntField(interp, dict, literals[LIT_MONTH], &fields.month)
+		!= TCL_OK
+	    || FetchIntField(interp, dict, literals[LIT_DAYOFMONTH],
+		&fields.dayOfMonth) != TCL_OK
+	    || TclGetIntFromObj(interp, objv[2], &changeover) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    fields.era = era;
+
+    /*
+     * Get Julian day.
+     */
+
+    GetJulianDayFromEraYearMonthDay(&fields, changeover);
+
+    /*
+     * Store Julian day in the dictionary - copy on write.
+     */
+
+    if (Tcl_IsShared(dict)) {
+	dict = Tcl_DuplicateObj(dict);
+	Tcl_IncrRefCount(dict);
+	copied = 1;
+    }
+    status = Tcl_DictObjPut(interp, dict, literals[LIT_JULIANDAY],
+	    Tcl_NewIntObj(fields.julianDay));
+    if (status == TCL_OK) {
+	Tcl_SetObjResult(interp, dict);
+    }
+    if (copied) {
+	Tcl_DecrRefCount(dict);
+    }
+    return status;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ClockGetjuliandayfromerayearweekdayObjCmd --
+ *
+ *	Tcl command that converts a time from the ISO calendar to a Julian Day
+ *	Number.
+ *
+ * Parameters:
+ *	dict - Dictionary that contains 'era', 'iso8601Year', 'iso8601Week'
+ *	       and 'dayOfWeek' keys.
+ *	changeover - Julian Day of changeover to the Gregorian calendar
+ *
+ * Results:
+ *	Result is either TCL_OK, with the interpreter result being the
+ *	dictionary augmented with a 'julianDay' key, or TCL_ERROR, with the
+ *	result being an error message.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+ClockGetjuliandayfromerayearweekdayObjCmd(
+    ClientData clientData,	/* Opaque pointer to literal pool, etc. */
+    Tcl_Interp *interp,		/* Tcl interpreter */
+    int objc,			/* Parameter count */
+    Tcl_Obj *const *objv)	/* Parameter vector */
+{
+    TclDateFields fields;
+    Tcl_Obj *dict;
+    ClockClientData *data = clientData;
+    Tcl_Obj *const *literals = data->literals;
+    int changeover;
+    int copied = 0;
+    int status;
+    int era = 0;
+
+    /*
+     * Check params.
+     */
+
+    if (objc != 3) {
+	Tcl_WrongNumArgs(interp, 1, objv, "dict changeover");
+	return TCL_ERROR;
+    }
+    dict = objv[1];
+    if (FetchEraField(interp, dict, literals[LIT_ERA], &era) != TCL_OK
+	    || FetchIntField(interp, dict, literals[LIT_ISO8601YEAR],
+		&fields.iso8601Year) != TCL_OK
+	    || FetchIntField(interp, dict, literals[LIT_ISO8601WEEK],
+		&fields.iso8601Week) != TCL_OK
+	    || FetchIntField(interp, dict, literals[LIT_DAYOFWEEK],
+		&fields.dayOfWeek) != TCL_OK
+	    || TclGetIntFromObj(interp, objv[2], &changeover) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    fields.era = era;
+
+    /*
+     * Get Julian day.
+     */
+
+    GetJulianDayFromEraYearWeekDay(&fields, changeover);
+
+    /*
+     * Store Julian day in the dictionary - copy on write.
+     */
+
+    if (Tcl_IsShared(dict)) {
+	dict = Tcl_DuplicateObj(dict);
+	Tcl_IncrRefCount(dict);
+	copied = 1;
+    }
+    status = Tcl_DictObjPut(interp, dict, literals[LIT_JULIANDAY],
+	    Tcl_NewIntObj(fields.julianDay));
+    if (status == TCL_OK) {
+	Tcl_SetObjResult(interp, dict);
+    }
+    if (copied) {
+	Tcl_DecrRefCount(dict);
+    }
+    return status;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ConvertLocalToUTC --
+ *
+ *	Converts a time (in a TclDateFields structure) from the local wall
+ *	clock to UTC.
+ *
+ * Results:
+ *	Returns a standard Tcl result.
+ *
+ * Side effects:
+ *	Populates the 'seconds' field if successful; stores an error message
+ *	in the interpreter result on failure.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+ConvertLocalToUTC(
+    Tcl_Interp *interp,		/* Tcl interpreter */
+    TclDateFields *fields,	/* Fields of the time */
+    Tcl_Obj *tzdata,		/* Time zone data */
+    int changeover)		/* Julian Day of the Gregorian transition */
+{
+    int rowc;			/* Number of rows in tzdata */
+    Tcl_Obj **rowv;		/* Pointers to the rows */
+
+    /*
+     * Unpack the tz data.
+     */
+
+    if (TclListObjGetElements(interp, tzdata, &rowc, &rowv) != TCL_OK) {
+	return TCL_ERROR;
+    }
+
+    /*
+     * Special case: If the time zone is :localtime, the tzdata will be empty.
+     * Use 'mktime' to convert the time to local
+     */
+
+    if (rowc == 0) {
+	return ConvertLocalToUTCUsingC(interp, fields, changeover);
+    } else {
+	return ConvertLocalToUTCUsingTable(interp, fields, rowc, rowv);
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ConvertLocalToUTCUsingTable --
+ *
+ *	Converts a time (in a TclDateFields structure) from local time in a
+ *	given time zone to UTC.
+ *
+ * Results:
+ *	Returns a standard Tcl result.
+ *
+ * Side effects:
+ *	Stores an error message in the interpreter if an error occurs; if
+ *	successful, stores the 'seconds' field in 'fields.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+ConvertLocalToUTCUsingTable(
+    Tcl_Interp *interp,		/* Tcl interpreter */
+    TclDateFields *fields,	/* Time to convert, with 'seconds' filled in */
+    int rowc,			/* Number of points at which time changes */
+    Tcl_Obj *const rowv[])	/* Points at which time changes */
+{
+    Tcl_Obj *row;
+    int cellc;
+    Tcl_Obj **cellv;
+    int have[8];
+    int nHave = 0;
+    int i;
+    int found;
+
+    /*
+     * Perform an initial lookup assuming that local == UTC, and locate the
+     * last time conversion prior to that time. Get the offset from that row,
+     * and look up again. Continue until we find an offset that we found
+     * before. This definition, rather than "the same offset" ensures that we
+     * don't enter an endless loop, as would otherwise happen when trying to
+     * convert a non-existent time such as 02:30 during the US Spring Daylight
+     * Saving Time transition.
+     */
+
+    found = 0;
+    fields->tzOffset = 0;
+    fields->seconds = fields->localSeconds;
+    while (!found) {
+	row = LookupLastTransition(interp, fields->seconds, rowc, rowv);
+	if ((row == NULL)
+		|| TclListObjGetElements(interp, row, &cellc,
+		    &cellv) != TCL_OK
+		|| TclGetIntFromObj(interp, cellv[1],
+		    &fields->tzOffset) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	found = 0;
+	for (i = 0; !found && i < nHave; ++i) {
+	    if (have[i] == fields->tzOffset) {
+		found = 1;
+		break;
+	    }
+	}
+	if (!found) {
+	    if (nHave == 8) {
+		Tcl_Panic("loop in ConvertLocalToUTCUsingTable");
+	    }
+	    have[nHave++] = fields->tzOffset;
+	}
+	fields->seconds = fields->localSeconds - fields->tzOffset;
+    }
+    fields->tzOffset = have[i];
+    fields->seconds = fields->localSeconds - fields->tzOffset;
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ConvertLocalToUTCUsingC --
+ *
+ *	Converts a time from local wall clock to UTC when the local time zone
+ *	cannot be determined. Uses 'mktime' to do the job.
+ *
+ * Results:
+ *	Returns a standard Tcl result.
+ *
+ * Side effects:
+ *	Stores an error message in the interpreter if an error occurs; if
+ *	successful, stores the 'seconds' field in 'fields.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+ConvertLocalToUTCUsingC(
+    Tcl_Interp *interp,		/* Tcl interpreter */
+    TclDateFields *fields,	/* Time to convert, with 'seconds' filled in */
+    int changeover)		/* Julian Day of the Gregorian transition */
+{
+    struct tm timeVal;
+    int localErrno;
+    int secondOfDay;
+    Tcl_WideInt jsec;
+
+    /*
+     * Convert the given time to a date.
+     */
+
+    jsec = fields->localSeconds + JULIAN_SEC_POSIX_EPOCH;
+    fields->julianDay = (int) (jsec / SECONDS_PER_DAY);
+    secondOfDay = (int)(jsec % SECONDS_PER_DAY);
+    if (secondOfDay < 0) {
+	secondOfDay += SECONDS_PER_DAY;
+	fields->julianDay--;
+    }
+    GetGregorianEraYearDay(fields, changeover);
+    GetMonthDay(fields);
+
+    /*
+     * Convert the date/time to a 'struct tm'.
+     */
+
+    timeVal.tm_year = fields->year - 1900;
+    timeVal.tm_mon = fields->month - 1;
+    timeVal.tm_mday = fields->dayOfMonth;
+    timeVal.tm_hour = (secondOfDay / 3600) % 24;
+    timeVal.tm_min = (secondOfDay / 60) % 60;
+    timeVal.tm_sec = secondOfDay % 60;
+    timeVal.tm_isdst = -1;
+    timeVal.tm_wday = -1;
+    timeVal.tm_yday = -1;
+
+    /*
+     * Get local time. It is rumored that mktime is not thread safe on some
+     * platforms, so seize a mutex before attempting this.
+     */
+
+    TzsetIfNecessary();
+    Tcl_MutexLock(&clockMutex);
+    errno = 0;
+    fields->seconds = (Tcl_WideInt) mktime(&timeVal);
+    localErrno = errno;
+    Tcl_MutexUnlock(&clockMutex);
+
+    /*
+     * If conversion fails, report an error.
+     */
+
+    if (localErrno != 0
+	    || (fields->seconds == -1 && timeVal.tm_yday == -1)) {
+	Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		"time value too large/small to represent", -1));
+	return TCL_ERROR;
+    }
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ConvertUTCToLocal --
+ *
+ *	Converts a time (in a TclDateFields structure) from UTC to local time.
+ *
+ * Results:
+ *	Returns a standard Tcl result.
+ *
+ * Side effects:
+ *	Populates the 'tzName' and 'tzOffset' fields.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+ConvertUTCToLocal(
+    Tcl_Interp *interp,		/* Tcl interpreter */
+    TclDateFields *fields,	/* Fields of the time */
+    Tcl_Obj *tzdata,		/* Time zone data */
+    int changeover)		/* Julian Day of the Gregorian transition */
+{
+    int rowc;			/* Number of rows in tzdata */
+    Tcl_Obj **rowv;		/* Pointers to the rows */
+
+    /*
+     * Unpack the tz data.
+     */
+
+    if (TclListObjGetElements(interp, tzdata, &rowc, &rowv) != TCL_OK) {
+	return TCL_ERROR;
+    }
+
+    /*
+     * Special case: If the time zone is :localtime, the tzdata will be empty.
+     * Use 'localtime' to convert the time to local
+     */
+
+    if (rowc == 0) {
+	return ConvertUTCToLocalUsingC(interp, fields, changeover);
+    } else {
+	return ConvertUTCToLocalUsingTable(interp, fields, rowc, rowv);
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ConvertUTCToLocalUsingTable --
+ *
+ *	Converts UTC to local time, given a table of transition points
+ *
+ * Results:
+ *	Returns a standard Tcl result
+ *
+ * Side effects:
+ *	On success, fills fields->tzName, fields->tzOffset and
+ *	fields->localSeconds. On failure, places an error message in the
+ *	interpreter result.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+ConvertUTCToLocalUsingTable(
+    Tcl_Interp *interp,		/* Tcl interpreter */
+    TclDateFields *fields,	/* Fields of the date */
+    int rowc,			/* Number of rows in the conversion table
+				 * (>= 1) */
+    Tcl_Obj *const rowv[])	/* Rows of the conversion table */
+{
+    Tcl_Obj *row;		/* Row containing the current information */
+    int cellc;			/* Count of cells in the row (must be 4) */
+    Tcl_Obj **cellv;		/* Pointers to the cells */
+
+    /*
+     * Look up the nearest transition time.
+     */
+
+    row = LookupLastTransition(interp, fields->seconds, rowc, rowv);
+    if (row == NULL ||
+	    TclListObjGetElements(interp, row, &cellc, &cellv) != TCL_OK ||
+	    TclGetIntFromObj(interp, cellv[1], &fields->tzOffset) != TCL_OK) {
+	return TCL_ERROR;
+    }
+
+    /*
+     * Convert the time.
+     */
+
+    fields->tzName = cellv[3];
+    Tcl_IncrRefCount(fields->tzName);
+    fields->localSeconds = fields->seconds + fields->tzOffset;
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ConvertUTCToLocalUsingC --
+ *
+ *	Converts UTC to localtime in cases where the local time zone is not
+ *	determinable, using the C 'localtime' function to do it.
+ *
+ * Results:
+ *	Returns a standard Tcl result.
+ *
+ * Side effects:
+ *	On success, fills fields->tzName, fields->tzOffset and
+ *	fields->localSeconds. On failure, places an error message in the
+ *	interpreter result.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+ConvertUTCToLocalUsingC(
+    Tcl_Interp *interp,		/* Tcl interpreter */
+    TclDateFields *fields,	/* Time to convert, with 'seconds' filled in */
+    int changeover)		/* Julian Day of the Gregorian transition */
+{
+    time_t tock;
+    struct tm *timeVal;		/* Time after conversion */
+    int diff;			/* Time zone diff local-Greenwich */
+    char buffer[8];		/* Buffer for time zone name */
+
+    /*
+     * Use 'localtime' to determine local year, month, day, time of day.
+     */
+
+    tock = (time_t) fields->seconds;
+    if ((Tcl_WideInt) tock != fields->seconds) {
+	Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		"number too large to represent as a Posix time", -1));
+	Tcl_SetErrorCode(interp, "CLOCK", "argTooLarge", NULL);
+	return TCL_ERROR;
+    }
+    TzsetIfNecessary();
+    timeVal = ThreadSafeLocalTime(&tock);
+    if (timeVal == NULL) {
+	Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		"localtime failed (clock value may be too "
+		"large/small to represent)", -1));
+	Tcl_SetErrorCode(interp, "CLOCK", "localtimeFailed", NULL);
+	return TCL_ERROR;
+    }
+
+    /*
+     * Fill in the date in 'fields' and use it to derive Julian Day.
+     */
+
+    fields->era = CE;
+    fields->year = timeVal->tm_year + 1900;
+    fields->month = timeVal->tm_mon + 1;
+    fields->dayOfMonth = timeVal->tm_mday;
+    GetJulianDayFromEraYearMonthDay(fields, changeover);
+
+    /*
+     * Convert that value to seconds.
+     */
+
+    fields->localSeconds = (((fields->julianDay * (Tcl_WideInt) 24
+	    + timeVal->tm_hour) * 60 + timeVal->tm_min) * 60
+	    + timeVal->tm_sec) - JULIAN_SEC_POSIX_EPOCH;
+
+    /*
+     * Determine a time zone offset and name; just use +hhmm for the name.
+     */
+
+    diff = (int) (fields->localSeconds - fields->seconds);
+    fields->tzOffset = diff;
+    if (diff < 0) {
+	*buffer = '-';
+	diff = -diff;
+    } else {
+	*buffer = '+';
+    }
+    sprintf(buffer+1, "%02d", diff / 3600);
+    diff %= 3600;
+    sprintf(buffer+3, "%02d", diff / 60);
+    diff %= 60;
+    if (diff > 0) {
+	sprintf(buffer+5, "%02d", diff);
+    }
+    fields->tzName = Tcl_NewStringObj(buffer, -1);
+    Tcl_IncrRefCount(fields->tzName);
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * LookupLastTransition --
+ *
+ *	Given a UTC time and a tzdata array, looks up the last transition on
+ *	or before the given time.
+ *
+ * Results:
+ *	Returns a pointer to the row, or NULL if an error occurs.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static Tcl_Obj *
+LookupLastTransition(
+    Tcl_Interp *interp,		/* Interpreter for error messages */
+    Tcl_WideInt tick,		/* Time from the epoch */
+    int rowc,			/* Number of rows of tzdata */
+    Tcl_Obj *const *rowv)	/* Rows in tzdata */
+{
+    int l;
+    int u;
+    Tcl_Obj *compObj;
+    Tcl_WideInt compVal;
+
+    /*
+     * Examine the first row to make sure we're in bounds.
+     */
+
+    if (Tcl_ListObjIndex(interp, rowv[0], 0, &compObj) != TCL_OK
+	    || Tcl_GetWideIntFromObj(interp, compObj, &compVal) != TCL_OK) {
+	return NULL;
+    }
+
+    /*
+     * Bizarre case - first row doesn't begin at MIN_WIDE_INT. Return it
+     * anyway.
+     */
+
+    if (tick < compVal) {
+	return rowv[0];
+    }
+
+    /*
+     * Binary-search to find the transition.
+     */
+
+    l = 0;
+    u = rowc-1;
+    while (l < u) {
+	int m = (l + u + 1) / 2;
+
+	if (Tcl_ListObjIndex(interp, rowv[m], 0, &compObj) != TCL_OK ||
+		Tcl_GetWideIntFromObj(interp, compObj, &compVal) != TCL_OK) {
+	    return NULL;
+	}
+	if (tick >= compVal) {
+	    l = m;
+	} else {
+	    u = m-1;
+	}
+    }
+    return rowv[l];
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * GetYearWeekDay --
+ *
+ *	Given a date with Julian Calendar Day, compute the year, week, and day
+ *	in the ISO8601 calendar.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Stores 'iso8601Year', 'iso8601Week' and 'dayOfWeek' in the date
+ *	fields.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+GetYearWeekDay(
+    TclDateFields *fields,	/* Date to convert, must have 'julianDay' */
+    int changeover)		/* Julian Day Number of the Gregorian
+				 * transition */
+{
+    TclDateFields temp;
+    int dayOfFiscalYear;
+
+    /*
+     * Find the given date, minus three days, plus one year. That date's
+     * iso8601 year is an upper bound on the ISO8601 year of the given date.
+     */
+
+    temp.julianDay = fields->julianDay - 3;
+    GetGregorianEraYearDay(&temp, changeover);
+    if (temp.era == BCE) {
+	temp.iso8601Year = temp.year - 1;
+    } else {
+	temp.iso8601Year = temp.year + 1;
+    }
+    temp.iso8601Week = 1;
+    temp.dayOfWeek = 1;
+    GetJulianDayFromEraYearWeekDay(&temp, changeover);
+
+    /*
+     * temp.julianDay is now the start of an ISO8601 year, either the one
+     * corresponding to the given date, or the one after. If we guessed high,
+     * move one year earlier
+     */
+
+    if (fields->julianDay < temp.julianDay) {
+	if (temp.era == BCE) {
+	    temp.iso8601Year += 1;
+	} else {
+	    temp.iso8601Year -= 1;
+	}
+	GetJulianDayFromEraYearWeekDay(&temp, changeover);
+    }
+
+    fields->iso8601Year = temp.iso8601Year;
+    dayOfFiscalYear = fields->julianDay - temp.julianDay;
+    fields->iso8601Week = (dayOfFiscalYear / 7) + 1;
+    fields->dayOfWeek = (dayOfFiscalYear + 1) % 7;
+    if (fields->dayOfWeek < 1) {
+	fields->dayOfWeek += 7;
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * GetGregorianEraYearDay --
+ *
+ *	Given a Julian Day Number, extracts the year and day of the year and
+ *	puts them into TclDateFields, along with the era (BCE or CE) and a
+ *	flag indicating whether the date is Gregorian or Julian.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Stores 'era', 'gregorian', 'year', and 'dayOfYear'.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+GetGregorianEraYearDay(
+    TclDateFields *fields,	/* Date fields containing 'julianDay' */
+    int changeover)		/* Gregorian transition date */
+{
+    int jday = fields->julianDay;
+    int day;
+    int year;
+    int n;
+
+    if (jday >= changeover) {
+	/*
+	 * Gregorian calendar.
+	 */
+
+	fields->gregorian = 1;
+	year = 1;
+
+	/*
+	 * n = Number of 400-year cycles since 1 January, 1 CE in the
+	 * proleptic Gregorian calendar. day = remaining days.
+	 */
+
+	day = jday - JDAY_1_JAN_1_CE_GREGORIAN;
+	n = day / FOUR_CENTURIES;
+	day %= FOUR_CENTURIES;
+	if (day < 0) {
+	    day += FOUR_CENTURIES;
+	    n--;
+	}
+	year += 400 * n;
+
+	/*
+	 * n = number of centuries since the start of (year);
+	 * day = remaining days
+	 */
+
+	n = day / ONE_CENTURY_GREGORIAN;
+	day %= ONE_CENTURY_GREGORIAN;
+	if (n > 3) {
+	    /*
+	     * 31 December in the last year of a 400-year cycle.
+	     */
+
+	    n = 3;
+	    day += ONE_CENTURY_GREGORIAN;
+	}
+	year += 100 * n;
+    } else {
+	/*
+	 * Julian calendar.
+	 */
+
+	fields->gregorian = 0;
+	year = 1;
+	day = jday - JDAY_1_JAN_1_CE_JULIAN;
+    }
+
+    /*
+     * n = number of 4-year cycles; days = remaining days.
+     */
+
+    n = day / FOUR_YEARS;
+    day %= FOUR_YEARS;
+    if (day < 0) {
+	day += FOUR_YEARS;
+	n--;
+    }
+    year += 4 * n;
+
+    /*
+     * n = number of years; days = remaining days.
+     */
+
+    n = day / ONE_YEAR;
+    day %= ONE_YEAR;
+    if (n > 3) {
+	/*
+	 * 31 December of a leap year.
+	 */
+
+	n = 3;
+	day += 365;
+    }
+    year += n;
+
+    /*
+     * store era/year/day back into fields.
+     */
+
+    if (year <= 0) {
+	fields->era = BCE;
+	fields->year = 1 - year;
+    } else {
+	fields->era = CE;
+	fields->year = year;
+    }
+    fields->dayOfYear = day + 1;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * GetMonthDay --
+ *
+ *	Given a date as year and day-of-year, find month and day.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Stores 'month' and 'dayOfMonth' in the 'fields' structure.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+GetMonthDay(
+    TclDateFields *fields)	/* Date to convert */
+{
+    int day = fields->dayOfYear;
+    int month;
+    const int *h = hath[IsGregorianLeapYear(fields)];
+
+    for (month = 0; month < 12 && day > h[month]; ++month) {
+	day -= h[month];
+    }
+    fields->month = month+1;
+    fields->dayOfMonth = day;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * GetJulianDayFromEraYearWeekDay --
+ *
+ *	Given a TclDateFields structure containing era, ISO8601 year, ISO8601
+ *	week, and day of week, computes the Julian Day Number.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Stores 'julianDay' in the fields.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+GetJulianDayFromEraYearWeekDay(
+    TclDateFields *fields,	/* Date to convert */
+    int changeover)		/* Julian Day Number of the Gregorian
+				 * transition */
+{
+    int firstMonday;		/* Julian day number of week 1, day 1 in the
+				 * given year */
+    TclDateFields firstWeek;
+
+    /*
+     * Find January 4 in the ISO8601 year, which will always be in week 1.
+     */
+
+    firstWeek.era = fields->era;
+    firstWeek.year = fields->iso8601Year;
+    firstWeek.month = 1;
+    firstWeek.dayOfMonth = 4;
+    GetJulianDayFromEraYearMonthDay(&firstWeek, changeover);
+
+    /*
+     * Find Monday of week 1.
+     */
+
+    firstMonday = WeekdayOnOrBefore(1, firstWeek.julianDay);
+
+    /*
+     * Advance to the given week and day.
+     */
+
+    fields->julianDay = firstMonday + 7 * (fields->iso8601Week - 1)
+	    + fields->dayOfWeek - 1;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * GetJulianDayFromEraYearMonthDay --
+ *
+ *	Given era, year, month, and dayOfMonth (in TclDateFields), and the
+ *	Gregorian transition date, computes the Julian Day Number.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Stores day number in 'julianDay'
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+GetJulianDayFromEraYearMonthDay(
+    TclDateFields *fields,	/* Date to convert */
+    int changeover)		/* Gregorian transition date as a Julian Day */
+{
+    int year, ym1, month, mm1, q, r, ym1o4, ym1o100, ym1o400;
+
+    if (fields->era == BCE) {
+	year = 1 - fields->year;
+    } else {
+	year = fields->year;
+    }
+
+    /*
+     * Reduce month modulo 12.
+     */
+
+    month = fields->month;
+    mm1 = month - 1;
+    q = mm1 / 12;
+    r = (mm1 % 12);
+    if (r < 0) {
+	r += 12;
+	q -= 1;
+    }
+    year += q;
+    month = r + 1;
+    ym1 = year - 1;
+
+    /*
+     * Adjust the year after reducing the month.
+     */
+
+    fields->gregorian = 1;
+    if (year < 1) {
+	fields->era = BCE;
+	fields->year = 1-year;
+    } else {
+	fields->era = CE;
+	fields->year = year;
+    }
+
+    /*
+     * Try an initial conversion in the Gregorian calendar.
+     */
+
+#if 0 /* BUG http://core.tcl.tk/tcl/tktview?name=da340d4f32 */
+    ym1o4 = ym1 / 4;
+#else
+    /*
+     * Have to make sure quotient is truncated towards 0 when negative.
+     * See above bug for details. The casts are necessary.
+     */
+    if (ym1 >= 0)
+        ym1o4 = ym1 / 4;
+    else {
+        ym1o4 = - (int) (((unsigned int) -ym1) / 4);
+    }
+#endif
+    if (ym1 % 4 < 0) {
+	ym1o4--;
+    }
+    ym1o100 = ym1 / 100;
+    if (ym1 % 100 < 0) {
+	ym1o100--;
+    }
+    ym1o400 = ym1 / 400;
+    if (ym1 % 400 < 0) {
+	ym1o400--;
+    }
+    fields->julianDay = JDAY_1_JAN_1_CE_GREGORIAN - 1
+	    + fields->dayOfMonth
+	    + daysInPriorMonths[IsGregorianLeapYear(fields)][month - 1]
+	    + (ONE_YEAR * ym1)
+	    + ym1o4
+	    - ym1o100
+	    + ym1o400;
+
+    /*
+     * If the resulting date is before the Gregorian changeover, convert in
+     * the Julian calendar instead.
+     */
+
+    if (fields->julianDay < changeover) {
+	fields->gregorian = 0;
+	fields->julianDay = JDAY_1_JAN_1_CE_JULIAN - 1
+		+ fields->dayOfMonth
+		+ daysInPriorMonths[year%4 == 0][month - 1]
+		+ (365 * ym1)
+		+ ym1o4;
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * IsGregorianLeapYear --
+ *
+ *	Tests whether a given year is a leap year, in either Julian or
+ *	Gregorian calendar.
+ *
+ * Results:
+ *	Returns 1 for a leap year, 0 otherwise.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+IsGregorianLeapYear(
+    TclDateFields *fields)	/* Date to test */
+{
+    int year;
+
+    if (fields->era == BCE) {
+	year = 1 - fields->year;
+    } else {
+	year = fields->year;
+    }
+    if (year%4 != 0) {
+	return 0;
+    } else if (!(fields->gregorian)) {
+	return 1;
+    } else if (year%400 == 0) {
+	return 1;
+    } else if (year%100 == 0) {
+	return 0;
+    } else {
+	return 1;
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * WeekdayOnOrBefore --
+ *
+ *	Finds the Julian Day Number of a given day of the week that falls on
+ *	or before a given date, expressed as Julian Day Number.
+ *
+ * Results:
+ *	Returns the Julian Day Number
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+WeekdayOnOrBefore(
+    int dayOfWeek,		/* Day of week; Sunday == 0 or 7 */
+    int julianDay)		/* Reference date */
+{
+    int k = (dayOfWeek + 6) % 7;
+    if (k < 0) {
+	k += 7;
+    }
+    return julianDay - ((julianDay - k) % 7);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ClockGetenvObjCmd --
+ *
+ *	Tcl command that reads an environment variable from the system
+ *
+ * Usage:
+ *	::tcl::clock::getEnv NAME
+ *
+ * Parameters:
+ *	NAME - Name of the environment variable desired
+ *
+ * Results:
+ *	Returns a standard Tcl result. Returns an error if the variable does
+ *	not exist, with a message left in the interpreter. Returns TCL_OK and
+ *	the value of the variable if the variable does exist,
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+ClockGetenvObjCmd(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const objv[])
+{
+    const char *varName;
+    const char *varValue;
+
+    if (objc != 2) {
+	Tcl_WrongNumArgs(interp, 1, objv, "name");
+	return TCL_ERROR;
+    }
+    varName = TclGetString(objv[1]);
+    varValue = getenv(varName);
+    if (varValue == NULL) {
+	varValue = "";
+    }
+    Tcl_SetObjResult(interp, Tcl_NewStringObj(varValue, -1));
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ThreadSafeLocalTime --
+ *
+ *	Wrapper around the 'localtime' library function to make it thread
+ *	safe.
+ *
+ * Results:
+ *	Returns a pointer to a 'struct tm' in thread-specific data.
+ *
+ * Side effects:
+ *	Invokes localtime or localtime_r as appropriate.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static struct tm *
+ThreadSafeLocalTime(
+    const time_t *timePtr)	/* Pointer to the number of seconds since the
+				 * local system's epoch */
+{
+    /*
+     * Get a thread-local buffer to hold the returned time.
+     */
+
+    struct tm *tmPtr = Tcl_GetThreadData(&tmKey, (int) sizeof(struct tm));
+#ifdef HAVE_LOCALTIME_R
+    localtime_r(timePtr, tmPtr);
+#else
+    struct tm *sysTmPtr;
+
+    Tcl_MutexLock(&clockMutex);
+    sysTmPtr = localtime(timePtr);
+    if (sysTmPtr == NULL) {
+	Tcl_MutexUnlock(&clockMutex);
+	return NULL;
+    }
+    memcpy(tmPtr, localtime(timePtr), sizeof(struct tm));
+    Tcl_MutexUnlock(&clockMutex);
+#endif
+    return tmPtr;
+}
+
+/*----------------------------------------------------------------------
+ *
+ * ClockClicksObjCmd --
+ *
+ *	Returns a high-resolution counter.
+ *
+ * Results:
+ *	Returns a standard Tcl result.
+ *
+ * Side effects:
+ *	None.
+ *
+ * This function implements the 'clock clicks' Tcl command. Refer to the user
+ * documentation for details on what it does.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+ClockClicksObjCmd(
+    ClientData clientData,	/* Client data is unused */
+    Tcl_Interp *interp,		/* Tcl interpreter */
+    int objc,			/* Parameter count */
+    Tcl_Obj *const *objv)	/* Parameter values */
+{
+    static const char *const clicksSwitches[] = {
+	"-milliseconds", "-microseconds", NULL
+    };
+    enum ClicksSwitch {
+	CLICKS_MILLIS, CLICKS_MICROS, CLICKS_NATIVE
+    };
+    int index = CLICKS_NATIVE;
+    Tcl_Time now;
+    Tcl_WideInt clicks = 0;
+
+    switch (objc) {
+    case 1:
+	break;
+    case 2:
+	if (Tcl_GetIndexFromObj(interp, objv[1], clicksSwitches, "option", 0,
+		&index) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	break;
+    default:
+	Tcl_WrongNumArgs(interp, 1, objv, "?-switch?");
+	return TCL_ERROR;
+    }
+
+    switch (index) {
+    case CLICKS_MILLIS:
+	Tcl_GetTime(&now);
+	clicks = (Tcl_WideInt) now.sec * 1000 + now.usec / 1000;
+	break;
+    case CLICKS_NATIVE:
+#ifdef TCL_WIDE_CLICKS
+	clicks = TclpGetWideClicks();
+#else
+	clicks = (Tcl_WideInt) TclpGetClicks();
+#endif
+	break;
+    case CLICKS_MICROS:
+	Tcl_GetTime(&now);
+	clicks = ((Tcl_WideInt) now.sec * 1000000) + now.usec;
+	break;
+    }
+
+    Tcl_SetObjResult(interp, Tcl_NewWideIntObj(clicks));
+    return TCL_OK;
+}
+
+/*----------------------------------------------------------------------
+ *
+ * ClockMillisecondsObjCmd -
+ *
+ *	Returns a count of milliseconds since the epoch.
+ *
+ * Results:
+ *	Returns a standard Tcl result.
+ *
+ * Side effects:
+ *	None.
+ *
+ * This function implements the 'clock milliseconds' Tcl command. Refer to the
+ * user documentation for details on what it does.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+ClockMillisecondsObjCmd(
+    ClientData clientData,	/* Client data is unused */
+    Tcl_Interp *interp,		/* Tcl interpreter */
+    int objc,			/* Parameter count */
+    Tcl_Obj *const *objv)	/* Parameter values */
+{
+    Tcl_Time now;
+
+    if (objc != 1) {
+	Tcl_WrongNumArgs(interp, 1, objv, NULL);
+	return TCL_ERROR;
+    }
+    Tcl_GetTime(&now);
+    Tcl_SetObjResult(interp, Tcl_NewWideIntObj((Tcl_WideInt)
+	    now.sec * 1000 + now.usec / 1000));
+    return TCL_OK;
+}
+
+/*----------------------------------------------------------------------
+ *
+ * ClockMicrosecondsObjCmd -
+ *
+ *	Returns a count of microseconds since the epoch.
+ *
+ * Results:
+ *	Returns a standard Tcl result.
+ *
+ * Side effects:
+ *	None.
+ *
+ * This function implements the 'clock microseconds' Tcl command. Refer to the
+ * user documentation for details on what it does.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+ClockMicrosecondsObjCmd(
+    ClientData clientData,	/* Client data is unused */
+    Tcl_Interp *interp,		/* Tcl interpreter */
+    int objc,			/* Parameter count */
+    Tcl_Obj *const *objv)	/* Parameter values */
+{
+    Tcl_Time now;
+
+    if (objc != 1) {
+	Tcl_WrongNumArgs(interp, 1, objv, NULL);
+	return TCL_ERROR;
+    }
+    Tcl_GetTime(&now);
+    Tcl_SetObjResult(interp, Tcl_NewWideIntObj(
+	    ((Tcl_WideInt) now.sec * 1000000) + now.usec));
+    return TCL_OK;
+}
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * ClockParseformatargsObjCmd --
+ *
+ *	Parses the arguments for [clock format].
+ *
+ * Results:
+ *	Returns a standard Tcl result, whose value is a four-element list
+ *	comprising the time format, the locale, and the timezone.
+ *
+ * This function exists because the loop that parses the [clock format]
+ * options is a known performance "hot spot", and is implemented in an effort
+ * to speed that particular code up.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static int
+ClockParseformatargsObjCmd(
+    ClientData clientData,	/* Client data containing literal pool */
+    Tcl_Interp *interp,		/* Tcl interpreter */
+    int objc,			/* Parameter count */
+    Tcl_Obj *const objv[])	/* Parameter vector */
+{
+    ClockClientData *dataPtr = clientData;
+    Tcl_Obj **litPtr = dataPtr->literals;
+    Tcl_Obj *results[3];	/* Format, locale and timezone */
+#define formatObj results[0]
+#define localeObj results[1]
+#define timezoneObj results[2]
+    int gmtFlag = 0;
+    static const char *const options[] = { /* Command line options expected */
+	"-format",	"-gmt",		"-locale",
+	"-timezone",	NULL };
+    enum optionInd {
+	CLOCK_FORMAT_FORMAT,	CLOCK_FORMAT_GMT,	CLOCK_FORMAT_LOCALE,
+	CLOCK_FORMAT_TIMEZONE
+    };
+    int optionIndex;		/* Index of an option. */
+    int saw = 0;		/* Flag == 1 if option was seen already. */
+    Tcl_WideInt clockVal;	/* Clock value - just used to parse. */
+    int i;
+
+    /*
+     * Args consist of a time followed by keyword-value pairs.
+     */
+
+    if (objc < 2 || (objc % 2) != 0) {
+	Tcl_WrongNumArgs(interp, 0, objv,
+		"clock format clockval ?-format string? "
+		"?-gmt boolean? ?-locale LOCALE? ?-timezone ZONE?");
+	Tcl_SetErrorCode(interp, "CLOCK", "wrongNumArgs", NULL);
+	return TCL_ERROR;
+    }
+
+    /*
+     * Extract values for the keywords.
+     */
+
+    formatObj = litPtr[LIT__DEFAULT_FORMAT];
+    localeObj = litPtr[LIT_C];
+    timezoneObj = litPtr[LIT__NIL];
+    for (i = 2; i < objc; i+=2) {
+	if (Tcl_GetIndexFromObj(interp, objv[i], options, "option", 0,
+		&optionIndex) != TCL_OK) {
+	    Tcl_SetErrorCode(interp, "CLOCK", "badOption",
+		    Tcl_GetString(objv[i]), NULL);
+	    return TCL_ERROR;
+	}
+	switch (optionIndex) {
+	case CLOCK_FORMAT_FORMAT:
+	    formatObj = objv[i+1];
+	    break;
+	case CLOCK_FORMAT_GMT:
+	    if (Tcl_GetBooleanFromObj(interp, objv[i+1], &gmtFlag) != TCL_OK){
+		return TCL_ERROR;
+	    }
+	    break;
+	case CLOCK_FORMAT_LOCALE:
+	    localeObj = objv[i+1];
+	    break;
+	case CLOCK_FORMAT_TIMEZONE:
+	    timezoneObj = objv[i+1];
+	    break;
+	}
+	saw |= 1 << optionIndex;
+    }
+
+    /*
+     * Check options.
+     */
+
+    if (Tcl_GetWideIntFromObj(interp, objv[1], &clockVal) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    if ((saw & (1 << CLOCK_FORMAT_GMT))
+	    && (saw & (1 << CLOCK_FORMAT_TIMEZONE))) {
+	Tcl_SetObjResult(interp, litPtr[LIT_CANNOT_USE_GMT_AND_TIMEZONE]);
+	Tcl_SetErrorCode(interp, "CLOCK", "gmtWithTimezone", NULL);
+	return TCL_ERROR;
+    }
+    if (gmtFlag) {
+	timezoneObj = litPtr[LIT_GMT];
+    }
+
+    /*
+     * Return options as a list.
+     */
+
+    Tcl_SetObjResult(interp, Tcl_NewListObj(3, results));
+    return TCL_OK;
+
+#undef timezoneObj
+#undef localeObj
+#undef formatObj
+}
+
+/*----------------------------------------------------------------------
+ *
+ * ClockSecondsObjCmd -
+ *
+ *	Returns a count of microseconds since the epoch.
+ *
+ * Results:
+ *	Returns a standard Tcl result.
+ *
+ * Side effects:
+ *	None.
+ *
+ * This function implements the 'clock seconds' Tcl command. Refer to the user
+ * documentation for details on what it does.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+ClockSecondsObjCmd(
+    ClientData clientData,	/* Client data is unused */
+    Tcl_Interp *interp,		/* Tcl interpreter */
+    int objc,			/* Parameter count */
+    Tcl_Obj *const *objv)	/* Parameter values */
+{
+    Tcl_Time now;
+
+    if (objc != 1) {
+	Tcl_WrongNumArgs(interp, 1, objv, NULL);
+	return TCL_ERROR;
+    }
+    Tcl_GetTime(&now);
+    Tcl_SetObjResult(interp, Tcl_NewWideIntObj((Tcl_WideInt) now.sec));
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TzsetIfNecessary --
+ *
+ *	Calls the tzset() library function if the contents of the TZ
+ *	environment variable has changed.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Calls tzset.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+TzsetIfNecessary(void)
+{
+    static char* tzWas = INT2PTR(-1);	/* Previous value of TZ, protected by
+				 * clockMutex. */
+    const char *tzIsNow;	/* Current value of TZ */
+
+    Tcl_MutexLock(&clockMutex);
+    tzIsNow = getenv("TZ");
+    if (tzIsNow != NULL && (tzWas == NULL || tzWas == INT2PTR(-1)
+	    || strcmp(tzIsNow, tzWas) != 0)) {
+	tzset();
+	if (tzWas != NULL && tzWas != INT2PTR(-1)) {
+	    ckfree(tzWas);
+	}
+	tzWas = ckalloc(strlen(tzIsNow) + 1);
+	strcpy(tzWas, tzIsNow);
+    } else if (tzIsNow == NULL && tzWas != NULL) {
+	tzset();
+	if (tzWas != INT2PTR(-1)) ckfree(tzWas);
+	tzWas = NULL;
+    }
+    Tcl_MutexUnlock(&clockMutex);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ClockDeleteCmdProc --
+ *
+ *	Remove a reference to the clock client data, and clean up memory
+ *	when it's all gone.
+ *
+ * Results:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+ClockDeleteCmdProc(
+    ClientData clientData)	/* Opaque pointer to the client data */
+{
+    ClockClientData *data = clientData;
+    int i;
+
+    data->refCount--;
+    if (data->refCount == 0) {
+	for (i = 0; i < LIT__END; ++i) {
+	    Tcl_DecrRefCount(data->literals[i]);
+	}
+	ckfree(data->literals);
+	ckfree(data);
+    }
+}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tclCmdAH.c b/generic/tclCmdAH.c
new file mode 100644
index 0000000..88cc17d
--- /dev/null
+++ b/generic/tclCmdAH.c
@@ -0,0 +1,2953 @@
+/*
+ * tclCmdAH.c --
+ *
+ *	This file contains the top-level command routines for most of the Tcl
+ *	built-in commands whose names begin with the letters A to H.
+ *
+ * Copyright (c) 1987-1993 The Regents of the University of California.
+ * Copyright (c) 1994-1997 Sun Microsystems, Inc.
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#include "tclInt.h"
+#ifdef _WIN32
+#   include "tclWinInt.h"
+#endif
+#include <locale.h>
+
+/*
+ * The state structure used by [foreach]. Note that the actual structure has
+ * all its working arrays appended afterwards so they can be allocated and
+ * freed in a single step.
+ */
+
+struct ForeachState {
+    Tcl_Obj *bodyPtr;		/* The script body of the command. */
+    int bodyIdx;		/* The argument index of the body. */
+    int j, maxj;		/* Number of loop iterations. */
+    int numLists;		/* Count of value lists. */
+    int *index;			/* Array of value list indices. */
+    int *varcList;		/* # loop variables per list. */
+    Tcl_Obj ***varvList;	/* Array of var name lists. */
+    Tcl_Obj **vCopyList;	/* Copies of var name list arguments. */
+    int *argcList;		/* Array of value list sizes. */
+    Tcl_Obj ***argvList;	/* Array of value lists. */
+    Tcl_Obj **aCopyList;	/* Copies of value list arguments. */
+    Tcl_Obj *resultList;	/* List of result values from the loop body,
+				 * or NULL if we're not collecting them
+				 * ([lmap] vs [foreach]). */
+};
+
+/*
+ * Prototypes for local procedures defined in this file:
+ */
+
+static int		CheckAccess(Tcl_Interp *interp, Tcl_Obj *pathPtr,
+			    int mode);
+static int		EncodingDirsObjCmd(ClientData dummy,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+static inline int	ForeachAssignments(Tcl_Interp *interp,
+			    struct ForeachState *statePtr);
+static inline void	ForeachCleanup(Tcl_Interp *interp,
+			    struct ForeachState *statePtr);
+static int		GetStatBuf(Tcl_Interp *interp, Tcl_Obj *pathPtr,
+			    Tcl_FSStatProc *statProc, Tcl_StatBuf *statPtr);
+static const char *	GetTypeFromMode(int mode);
+static int		StoreStatData(Tcl_Interp *interp, Tcl_Obj *varName,
+			    Tcl_StatBuf *statPtr);
+static inline int	EachloopCmd(Tcl_Interp *interp, int collect,
+			    int objc, Tcl_Obj *const objv[]);
+static Tcl_NRPostProc	CatchObjCmdCallback;
+static Tcl_NRPostProc	ExprCallback;
+static Tcl_NRPostProc	ForSetupCallback;
+static Tcl_NRPostProc	ForCondCallback;
+static Tcl_NRPostProc	ForNextCallback;
+static Tcl_NRPostProc	ForPostNextCallback;
+static Tcl_NRPostProc	ForeachLoopStep;
+static Tcl_NRPostProc	EvalCmdErrMsg;
+
+static Tcl_ObjCmdProc	BadFileSubcommand;
+static Tcl_ObjCmdProc FileAttrAccessTimeCmd;
+static Tcl_ObjCmdProc FileAttrIsDirectoryCmd;
+static Tcl_ObjCmdProc FileAttrIsExecutableCmd;
+static Tcl_ObjCmdProc FileAttrIsExistingCmd;
+static Tcl_ObjCmdProc FileAttrIsFileCmd;
+static Tcl_ObjCmdProc FileAttrIsOwnedCmd;
+static Tcl_ObjCmdProc FileAttrIsReadableCmd;
+static Tcl_ObjCmdProc FileAttrIsWritableCmd;
+static Tcl_ObjCmdProc FileAttrLinkStatCmd;
+static Tcl_ObjCmdProc FileAttrModifyTimeCmd;
+static Tcl_ObjCmdProc FileAttrSizeCmd;
+static Tcl_ObjCmdProc FileAttrStatCmd;
+static Tcl_ObjCmdProc FileAttrTypeCmd;
+static Tcl_ObjCmdProc FilesystemSeparatorCmd;
+static Tcl_ObjCmdProc FilesystemVolumesCmd;
+static Tcl_ObjCmdProc PathDirNameCmd;
+static Tcl_ObjCmdProc PathExtensionCmd;
+static Tcl_ObjCmdProc PathFilesystemCmd;
+static Tcl_ObjCmdProc PathJoinCmd;
+static Tcl_ObjCmdProc PathNativeNameCmd;
+static Tcl_ObjCmdProc PathNormalizeCmd;
+static Tcl_ObjCmdProc PathRootNameCmd;
+static Tcl_ObjCmdProc PathSplitCmd;
+static Tcl_ObjCmdProc PathTailCmd;
+static Tcl_ObjCmdProc PathTypeCmd;
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_BreakObjCmd --
+ *
+ *	This procedure is invoked to process the "break" Tcl command. See the
+ *	user documentation for details on what it does.
+ *
+ *	With the bytecode compiler, this procedure is only called when a
+ *	command name is computed at runtime, and is "break" or the name to
+ *	which "break" was renamed: e.g., "set z break; $z"
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+	/* ARGSUSED */
+int
+Tcl_BreakObjCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    if (objc != 1) {
+	Tcl_WrongNumArgs(interp, 1, objv, NULL);
+	return TCL_ERROR;
+    }
+    return TCL_BREAK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_CaseObjCmd --
+ *
+ *	This procedure is invoked to process the "case" Tcl command. See the
+ *	user documentation for details on what it does. THIS COMMAND IS
+ *	OBSOLETE AND DEPRECATED. SLATED FOR REMOVAL IN TCL 9.0.
+ *
+ * Results:
+ *	A standard Tcl object result.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+	/* ARGSUSED */
+int
+Tcl_CaseObjCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    register int i;
+    int body, result, caseObjc;
+    const char *stringPtr, *arg;
+    Tcl_Obj *const *caseObjv;
+    Tcl_Obj *armPtr;
+
+    if (objc < 3) {
+	Tcl_WrongNumArgs(interp, 1, objv,
+		"string ?in? ?pattern body ...? ?default body?");
+	return TCL_ERROR;
+    }
+
+    stringPtr = TclGetString(objv[1]);
+    body = -1;
+
+    arg = TclGetString(objv[2]);
+    if (strcmp(arg, "in") == 0) {
+	i = 3;
+    } else {
+	i = 2;
+    }
+    caseObjc = objc - i;
+    caseObjv = objv + i;
+
+    /*
+     * If all of the pattern/command pairs are lumped into a single argument,
+     * split them out again.
+     */
+
+    if (caseObjc == 1) {
+	Tcl_Obj **newObjv;
+
+	TclListObjGetElements(interp, caseObjv[0], &caseObjc, &newObjv);
+	caseObjv = newObjv;
+    }
+
+    for (i = 0;  i < caseObjc;  i += 2) {
+	int patObjc, j;
+	const char **patObjv;
+	const char *pat, *p;
+
+	if (i == caseObjc-1) {
+	    Tcl_ResetResult(interp);
+	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		    "extra case pattern with no body", -1));
+	    return TCL_ERROR;
+	}
+
+	/*
+	 * Check for special case of single pattern (no list) with no
+	 * backslash sequences.
+	 */
+
+	pat = TclGetString(caseObjv[i]);
+	for (p = pat; *p != '\0'; p++) {
+	    if (TclIsSpaceProc(*p) || (*p == '\\')) {
+		break;
+	    }
+	}
+	if (*p == '\0') {
+	    if ((*pat == 'd') && (strcmp(pat, "default") == 0)) {
+		body = i + 1;
+	    }
+	    if (Tcl_StringMatch(stringPtr, pat)) {
+		body = i + 1;
+		goto match;
+	    }
+	    continue;
+	}
+
+	/*
+	 * Break up pattern lists, then check each of the patterns in the
+	 * list.
+	 */
+
+	result = Tcl_SplitList(interp, pat, &patObjc, &patObjv);
+	if (result != TCL_OK) {
+	    return result;
+	}
+	for (j = 0; j < patObjc; j++) {
+	    if (Tcl_StringMatch(stringPtr, patObjv[j])) {
+		body = i + 1;
+		break;
+	    }
+	}
+	ckfree(patObjv);
+	if (j < patObjc) {
+	    break;
+	}
+    }
+
+  match:
+    if (body != -1) {
+	armPtr = caseObjv[body - 1];
+	result = Tcl_EvalObjEx(interp, caseObjv[body], 0);
+	if (result == TCL_ERROR) {
+	    Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf(
+		    "\n    (\"%.50s\" arm line %d)",
+		    TclGetString(armPtr), Tcl_GetErrorLine(interp)));
+	}
+	return result;
+    }
+
+    /*
+     * Nothing matched: return nothing.
+     */
+
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_CatchObjCmd --
+ *
+ *	This object-based procedure is invoked to process the "catch" Tcl
+ *	command. See the user documentation for details on what it does.
+ *
+ * Results:
+ *	A standard Tcl object result.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+	/* ARGSUSED */
+int
+Tcl_CatchObjCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    return Tcl_NRCallObjProc(interp, TclNRCatchObjCmd, dummy, objc, objv);
+}
+
+int
+TclNRCatchObjCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    Tcl_Obj *varNamePtr = NULL;
+    Tcl_Obj *optionVarNamePtr = NULL;
+    Interp *iPtr = (Interp *) interp;
+
+    if ((objc < 2) || (objc > 4)) {
+	Tcl_WrongNumArgs(interp, 1, objv,
+		"script ?resultVarName? ?optionVarName?");
+	return TCL_ERROR;
+    }
+
+    if (objc >= 3) {
+	varNamePtr = objv[2];
+    }
+    if (objc == 4) {
+	optionVarNamePtr = objv[3];
+    }
+
+    TclNRAddCallback(interp, CatchObjCmdCallback, INT2PTR(objc),
+	    varNamePtr, optionVarNamePtr, NULL);
+
+    /*
+     * TIP #280. Make invoking context available to caught script.
+     */
+
+    return TclNREvalObjEx(interp, objv[1], 0, iPtr->cmdFramePtr, 1);
+}
+
+static int
+CatchObjCmdCallback(
+    ClientData data[],
+    Tcl_Interp *interp,
+    int result)
+{
+    Interp *iPtr = (Interp *) interp;
+    int objc = PTR2INT(data[0]);
+    Tcl_Obj *varNamePtr = data[1];
+    Tcl_Obj *optionVarNamePtr = data[2];
+    int rewind = iPtr->execEnvPtr->rewind;
+
+    /*
+     * We disable catch in interpreters where the limit has been exceeded.
+     */
+
+    if (rewind || Tcl_LimitExceeded(interp)) {
+	Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf(
+		"\n    (\"catch\" body line %d)", Tcl_GetErrorLine(interp)));
+	return TCL_ERROR;
+    }
+
+    if (objc >= 3) {
+	if (NULL == Tcl_ObjSetVar2(interp, varNamePtr, NULL,
+		Tcl_GetObjResult(interp), TCL_LEAVE_ERR_MSG)) {
+	    return TCL_ERROR;
+	}
+    }
+    if (objc == 4) {
+	Tcl_Obj *options = Tcl_GetReturnOptions(interp, result);
+
+	if (NULL == Tcl_ObjSetVar2(interp, optionVarNamePtr, NULL,
+		options, TCL_LEAVE_ERR_MSG)) {
+	    /* Do not decrRefCount 'options', it was already done by
+	     * Tcl_ObjSetVar2 */
+	    return TCL_ERROR;
+	}
+    }
+
+    Tcl_ResetResult(interp);
+    Tcl_SetObjResult(interp, Tcl_NewIntObj(result));
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_CdObjCmd --
+ *
+ *	This procedure is invoked to process the "cd" Tcl command. See the
+ *	user documentation for details on what it does.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+	/* ARGSUSED */
+int
+Tcl_CdObjCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    Tcl_Obj *dir;
+    int result;
+
+    if (objc > 2) {
+	Tcl_WrongNumArgs(interp, 1, objv, "?dirName?");
+	return TCL_ERROR;
+    }
+
+    if (objc == 2) {
+	dir = objv[1];
+    } else {
+	TclNewLiteralStringObj(dir, "~");
+	Tcl_IncrRefCount(dir);
+    }
+    if (Tcl_FSConvertToPathType(interp, dir) != TCL_OK) {
+	result = TCL_ERROR;
+    } else {
+	result = Tcl_FSChdir(dir);
+	if (result != TCL_OK) {
+	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		    "couldn't change working directory to \"%s\": %s",
+		    TclGetString(dir), Tcl_PosixError(interp)));
+	    result = TCL_ERROR;
+	}
+    }
+    if (objc != 2) {
+	Tcl_DecrRefCount(dir);
+    }
+    return result;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_ConcatObjCmd --
+ *
+ *	This object-based procedure is invoked to process the "concat" Tcl
+ *	command. See the user documentation for details on what it does.
+ *
+ * Results:
+ *	A standard Tcl object result.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+	/* ARGSUSED */
+int
+Tcl_ConcatObjCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    if (objc >= 2) {
+	Tcl_SetObjResult(interp, Tcl_ConcatObj(objc-1, objv+1));
+    }
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_ContinueObjCmd --
+ *
+ *	This procedure is invoked to process the "continue" Tcl command. See
+ *	the user documentation for details on what it does.
+ *
+ *	With the bytecode compiler, this procedure is only called when a
+ *	command name is computed at runtime, and is "continue" or the name to
+ *	which "continue" was renamed: e.g., "set z continue; $z"
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+	/* ARGSUSED */
+int
+Tcl_ContinueObjCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    if (objc != 1) {
+	Tcl_WrongNumArgs(interp, 1, objv, NULL);
+	return TCL_ERROR;
+    }
+    return TCL_CONTINUE;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_EncodingObjCmd --
+ *
+ *	This command manipulates encodings.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_EncodingObjCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    int index;
+
+    static const char *const optionStrings[] = {
+	"convertfrom", "convertto", "dirs", "names", "system",
+	NULL
+    };
+    enum options {
+	ENC_CONVERTFROM, ENC_CONVERTTO, ENC_DIRS, ENC_NAMES, ENC_SYSTEM
+    };
+
+    if (objc < 2) {
+	Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?");
+	return TCL_ERROR;
+    }
+    if (Tcl_GetIndexFromObj(interp, objv[1], optionStrings, "option", 0,
+	    &index) != TCL_OK) {
+	return TCL_ERROR;
+    }
+
+    switch ((enum options) index) {
+    case ENC_CONVERTTO:
+    case ENC_CONVERTFROM: {
+	Tcl_Obj *data;
+	Tcl_DString ds;
+	Tcl_Encoding encoding;
+	int length;
+	const char *stringPtr;
+
+	if (objc == 3) {
+	    encoding = Tcl_GetEncoding(interp, NULL);
+	    data = objv[2];
+	} else if (objc == 4) {
+	    if (Tcl_GetEncodingFromObj(interp, objv[2], &encoding) != TCL_OK) {
+		return TCL_ERROR;
+	    }
+	    data = objv[3];
+	} else {
+	    Tcl_WrongNumArgs(interp, 2, objv, "?encoding? data");
+	    return TCL_ERROR;
+	}
+
+	if ((enum options) index == ENC_CONVERTFROM) {
+	    /*
+	     * Treat the string as binary data.
+	     */
+
+	    stringPtr = (char *) Tcl_GetByteArrayFromObj(data, &length);
+	    Tcl_ExternalToUtfDString(encoding, stringPtr, length, &ds);
+
+	    /*
+	     * Note that we cannot use Tcl_DStringResult here because it will
+	     * truncate the string at the first null byte.
+	     */
+
+	    Tcl_SetObjResult(interp, TclDStringToObj(&ds));
+	} else {
+	    /*
+	     * Store the result as binary data.
+	     */
+
+	    stringPtr = TclGetStringFromObj(data, &length);
+	    Tcl_UtfToExternalDString(encoding, stringPtr, length, &ds);
+	    Tcl_SetObjResult(interp, Tcl_NewByteArrayObj(
+		    (unsigned char *) Tcl_DStringValue(&ds),
+		    Tcl_DStringLength(&ds)));
+	    Tcl_DStringFree(&ds);
+	}
+
+	Tcl_FreeEncoding(encoding);
+	break;
+    }
+    case ENC_DIRS:
+	return EncodingDirsObjCmd(dummy, interp, objc, objv);
+    case ENC_NAMES:
+	if (objc > 2) {
+	    Tcl_WrongNumArgs(interp, 2, objv, NULL);
+	    return TCL_ERROR;
+	}
+	Tcl_GetEncodingNames(interp);
+	break;
+    case ENC_SYSTEM:
+	if (objc > 3) {
+	    Tcl_WrongNumArgs(interp, 2, objv, "?encoding?");
+	    return TCL_ERROR;
+	}
+	if (objc == 2) {
+	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		    Tcl_GetEncodingName(NULL), -1));
+	} else {
+	    return Tcl_SetSystemEncoding(interp, TclGetString(objv[2]));
+	}
+	break;
+    }
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * EncodingDirsObjCmd --
+ *
+ *	This command manipulates the encoding search path.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	Can set the encoding search path.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+EncodingDirsObjCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    Tcl_Obj *dirListObj;
+
+    if (objc > 3) {
+	Tcl_WrongNumArgs(interp, 2, objv, "?dirList?");
+	return TCL_ERROR;
+    }
+    if (objc == 2) {
+	Tcl_SetObjResult(interp, Tcl_GetEncodingSearchPath());
+	return TCL_OK;
+    }
+
+    dirListObj = objv[2];
+    if (Tcl_SetEncodingSearchPath(dirListObj) == TCL_ERROR) {
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		"expected directory list but got \"%s\"",
+		TclGetString(dirListObj)));
+	Tcl_SetErrorCode(interp, "TCL", "OPERATION", "ENCODING", "BADPATH",
+		NULL);
+	return TCL_ERROR;
+    }
+    Tcl_SetObjResult(interp, dirListObj);
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_ErrorObjCmd --
+ *
+ *	This procedure is invoked to process the "error" Tcl command. See the
+ *	user documentation for details on what it does.
+ *
+ * Results:
+ *	A standard Tcl object result.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+	/* ARGSUSED */
+int
+Tcl_ErrorObjCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    Tcl_Obj *options, *optName;
+
+    if ((objc < 2) || (objc > 4)) {
+	Tcl_WrongNumArgs(interp, 1, objv, "message ?errorInfo? ?errorCode?");
+	return TCL_ERROR;
+    }
+
+    TclNewLiteralStringObj(options, "-code error -level 0");
+
+    if (objc >= 3) {		/* Process the optional info argument */
+	TclNewLiteralStringObj(optName, "-errorinfo");
+	Tcl_ListObjAppendElement(NULL, options, optName);
+	Tcl_ListObjAppendElement(NULL, options, objv[2]);
+    }
+
+    if (objc >= 4) {		/* Process the optional code argument */
+	TclNewLiteralStringObj(optName, "-errorcode");
+	Tcl_ListObjAppendElement(NULL, options, optName);
+	Tcl_ListObjAppendElement(NULL, options, objv[3]);
+    }
+
+    Tcl_SetObjResult(interp, objv[1]);
+    return Tcl_SetReturnOptions(interp, options);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_EvalObjCmd --
+ *
+ *	This object-based procedure is invoked to process the "eval" Tcl
+ *	command. See the user documentation for details on what it does.
+ *
+ * Results:
+ *	A standard Tcl object result.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+	/* ARGSUSED */
+static int
+EvalCmdErrMsg(
+    ClientData data[],
+    Tcl_Interp *interp,
+    int result)
+{
+    if (result == TCL_ERROR) {
+	Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf(
+		"\n    (\"eval\" body line %d)", Tcl_GetErrorLine(interp)));
+    }
+    return result;
+}
+
+int
+Tcl_EvalObjCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    return Tcl_NRCallObjProc(interp, TclNREvalObjCmd, dummy, objc, objv);
+}
+
+int
+TclNREvalObjCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    register Tcl_Obj *objPtr;
+    Interp *iPtr = (Interp *) interp;
+    CmdFrame *invoker = NULL;
+    int word = 0;
+
+    if (objc < 2) {
+	Tcl_WrongNumArgs(interp, 1, objv, "arg ?arg ...?");
+	return TCL_ERROR;
+    }
+
+    if (objc == 2) {
+	/*
+	 * TIP #280. Make argument location available to eval'd script.
+	 */
+
+	invoker = iPtr->cmdFramePtr;
+	word = 1;
+	objPtr = objv[1];
+	TclArgumentGet(interp, objPtr, &invoker, &word);
+    } else {
+	/*
+	 * More than one argument: concatenate them together with spaces
+	 * between, then evaluate the result. Tcl_EvalObjEx will delete the
+	 * object when it decrements its refcount after eval'ing it.
+	 *
+	 * TIP #280. Make invoking context available to eval'd script, done
+	 * with the default values.
+	 */
+
+	objPtr = Tcl_ConcatObj(objc-1, objv+1);
+    }
+    TclNRAddCallback(interp, EvalCmdErrMsg, NULL, NULL, NULL, NULL);
+    return TclNREvalObjEx(interp, objPtr, 0, invoker, word);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_ExitObjCmd --
+ *
+ *	This procedure is invoked to process the "exit" Tcl command. See the
+ *	user documentation for details on what it does.
+ *
+ * Results:
+ *	A standard Tcl object result.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+	/* ARGSUSED */
+int
+Tcl_ExitObjCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    int value;
+
+    if ((objc != 1) && (objc != 2)) {
+	Tcl_WrongNumArgs(interp, 1, objv, "?returnCode?");
+	return TCL_ERROR;
+    }
+
+    if (objc == 1) {
+	value = 0;
+    } else if (Tcl_GetIntFromObj(interp, objv[1], &value) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    Tcl_Exit(value);
+    /*NOTREACHED*/
+    return TCL_OK;		/* Better not ever reach this! */
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_ExprObjCmd --
+ *
+ *	This object-based procedure is invoked to process the "expr" Tcl
+ *	command. See the user documentation for details on what it does.
+ *
+ *	With the bytecode compiler, this procedure is called in two
+ *	circumstances: 1) to execute expr commands that are too complicated or
+ *	too unsafe to try compiling directly into an inline sequence of
+ *	instructions, and 2) to execute commands where the command name is
+ *	computed at runtime and is "expr" or the name to which "expr" was
+ *	renamed (e.g., "set z expr; $z 2+3")
+ *
+ * Results:
+ *	A standard Tcl object result.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+	/* ARGSUSED */
+int
+Tcl_ExprObjCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    return Tcl_NRCallObjProc(interp, TclNRExprObjCmd, dummy, objc, objv);
+}
+
+int
+TclNRExprObjCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    Tcl_Obj *resultPtr, *objPtr;
+
+    if (objc < 2) {
+	Tcl_WrongNumArgs(interp, 1, objv, "arg ?arg ...?");
+	return TCL_ERROR;
+    }
+
+    TclNewObj(resultPtr);
+    Tcl_IncrRefCount(resultPtr);
+    if (objc == 2) {
+	objPtr = objv[1];
+	TclNRAddCallback(interp, ExprCallback, resultPtr, NULL, NULL, NULL);
+    } else {
+	objPtr = Tcl_ConcatObj(objc-1, objv+1);
+	TclNRAddCallback(interp, ExprCallback, resultPtr, objPtr, NULL, NULL);
+    }
+
+    return Tcl_NRExprObj(interp, objPtr, resultPtr);
+}
+
+static int
+ExprCallback(
+    ClientData data[],
+    Tcl_Interp *interp,
+    int result)
+{
+    Tcl_Obj *resultPtr = data[0];
+    Tcl_Obj *objPtr = data[1];
+
+    if (objPtr != NULL) {
+	Tcl_DecrRefCount(objPtr);
+    }
+
+    if (result == TCL_OK) {
+	Tcl_SetObjResult(interp, resultPtr);
+    }
+    Tcl_DecrRefCount(resultPtr);
+    return result;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclInitFileCmd --
+ *
+ *	This function builds the "file" Tcl command ensemble. See the user
+ *	documentation for details on what that ensemble does.
+ *
+ *	PLEASE NOTE THAT THIS FAILS WITH FILENAMES AND PATHS WITH EMBEDDED
+ *	NULLS. With the object-based Tcl_FS APIs, the above NOTE may no longer
+ *	be true. In any case this assertion should be tested.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_Command
+TclInitFileCmd(
+    Tcl_Interp *interp)
+{
+    /*
+     * Note that most subcommands are unsafe because either they manipulate
+     * the native filesystem or because they reveal information about the
+     * native filesystem.
+     */
+
+    static const EnsembleImplMap initMap[] = {
+	{"atime",	FileAttrAccessTimeCmd,	TclCompileBasic1Or2ArgCmd, NULL, NULL, 0},
+	{"attributes",	TclFileAttrsCmd,	NULL, NULL, NULL, 0},
+	{"channels",	TclChannelNamesCmd,	TclCompileBasic0Or1ArgCmd, NULL, NULL, 0},
+	{"copy",	TclFileCopyCmd,		NULL, NULL, NULL, 0},
+	{"delete",	TclFileDeleteCmd,	TclCompileBasicMin0ArgCmd, NULL, NULL, 0},
+	{"dirname",	PathDirNameCmd,		TclCompileBasic1ArgCmd, NULL, NULL, 0},
+	{"executable",	FileAttrIsExecutableCmd, TclCompileBasic1ArgCmd, NULL, NULL, 0},
+	{"exists",	FileAttrIsExistingCmd,	TclCompileBasic1ArgCmd, NULL, NULL, 0},
+	{"extension",	PathExtensionCmd,	TclCompileBasic1ArgCmd, NULL, NULL, 0},
+	{"isdirectory",	FileAttrIsDirectoryCmd,	TclCompileBasic1ArgCmd, NULL, NULL, 0},
+	{"isfile",	FileAttrIsFileCmd,	TclCompileBasic1ArgCmd, NULL, NULL, 0},
+	{"join",	PathJoinCmd,		TclCompileBasicMin1ArgCmd, NULL, NULL, 0},
+	{"link",	TclFileLinkCmd,		TclCompileBasic1To3ArgCmd, NULL, NULL, 0},
+	{"lstat",	FileAttrLinkStatCmd,	TclCompileBasic2ArgCmd, NULL, NULL, 0},
+	{"mtime",	FileAttrModifyTimeCmd,	TclCompileBasic1Or2ArgCmd, NULL, NULL, 0},
+	{"mkdir",	TclFileMakeDirsCmd,	TclCompileBasicMin0ArgCmd, NULL, NULL, 0},
+	{"nativename",	PathNativeNameCmd,	TclCompileBasic1ArgCmd, NULL, NULL, 0},
+	{"normalize",	PathNormalizeCmd,	TclCompileBasic1ArgCmd, NULL, NULL, 0},
+	{"owned",	FileAttrIsOwnedCmd,	TclCompileBasic1ArgCmd, NULL, NULL, 0},
+	{"pathtype",	PathTypeCmd,		TclCompileBasic1ArgCmd, NULL, NULL, 0},
+	{"readable",	FileAttrIsReadableCmd,	TclCompileBasic1ArgCmd, NULL, NULL, 0},
+	{"readlink",	TclFileReadLinkCmd,	TclCompileBasic1ArgCmd, NULL, NULL, 0},
+	{"rename",	TclFileRenameCmd,	NULL, NULL, NULL, 0},
+	{"rootname",	PathRootNameCmd,	TclCompileBasic1ArgCmd, NULL, NULL, 0},
+	{"separator",	FilesystemSeparatorCmd,	TclCompileBasic0Or1ArgCmd, NULL, NULL, 0},
+	{"size",	FileAttrSizeCmd,	TclCompileBasic1ArgCmd, NULL, NULL, 0},
+	{"split",	PathSplitCmd,		TclCompileBasic1ArgCmd, NULL, NULL, 0},
+	{"stat",	FileAttrStatCmd,	TclCompileBasic2ArgCmd, NULL, NULL, 0},
+	{"system",	PathFilesystemCmd,	TclCompileBasic0Or1ArgCmd, NULL, NULL, 0},
+	{"tail",	PathTailCmd,		TclCompileBasic1ArgCmd, NULL, NULL, 0},
+	{"tempfile",	TclFileTemporaryCmd,	TclCompileBasic0To2ArgCmd, NULL, NULL, 0},
+	{"type",	FileAttrTypeCmd,	TclCompileBasic1ArgCmd, NULL, NULL, 0},
+	{"volumes",	FilesystemVolumesCmd,	TclCompileBasic0ArgCmd, NULL, NULL, 0},
+	{"writable",	FileAttrIsWritableCmd,	TclCompileBasic1ArgCmd, NULL, NULL, 0},
+	{NULL, NULL, NULL, NULL, NULL, 0}
+    };
+    return TclMakeEnsemble(interp, "file", initMap);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclMakeFileCommandSafe --
+ *
+ *	This function hides the unsafe subcommands of the "file" Tcl command
+ *	ensemble. It must only be called from TclHideUnsafeCommands.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	Adds commands to the table of hidden commands.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclMakeFileCommandSafe(
+    Tcl_Interp *interp)
+{
+    static const struct {
+	const char *cmdName;
+	int unsafe;
+    } unsafeInfo[] = {
+	{"atime",	 1},
+	{"attributes",	 1},
+	{"channels",	 0},
+	{"copy",	 1},
+	{"delete",	 1},
+	{"dirname",	 1},
+	{"executable",	 1},
+	{"exists",	 1},
+	{"extension",	 1},
+	{"isdirectory",	 1},
+	{"isfile",	 1},
+	{"join",	 0},
+	{"link",	 1},
+	{"lstat",	 1},
+	{"mtime",	 1},
+	{"mkdir",	 1},
+	{"nativename",	 1},
+	{"normalize",	 1},
+	{"owned",	 1},
+	{"pathtype",	 0},
+	{"readable",	 1},
+	{"readlink",	 1},
+	{"rename",	 1},
+	{"rootname",	 1},
+	{"separator",	 0},
+	{"size",	 1},
+	{"split",	 0},
+	{"stat",	 1},
+	{"system",	 0},
+	{"tail",	 1},
+	{"tempfile",	 1},
+	{"type",	 1},
+	{"volumes",	 1},
+	{"writable",	 1},
+	{NULL, 0}
+    };
+    int i;
+    Tcl_DString oldBuf, newBuf;
+
+    Tcl_DStringInit(&oldBuf);
+    TclDStringAppendLiteral(&oldBuf, "::tcl::file::");
+    Tcl_DStringInit(&newBuf);
+    TclDStringAppendLiteral(&newBuf, "tcl:file:");
+    for (i=0 ; unsafeInfo[i].cmdName != NULL ; i++) {
+	if (unsafeInfo[i].unsafe) {
+	    const char *oldName, *newName;
+
+	    Tcl_DStringSetLength(&oldBuf, 13);
+	    oldName = Tcl_DStringAppend(&oldBuf, unsafeInfo[i].cmdName, -1);
+	    Tcl_DStringSetLength(&newBuf, 9);
+	    newName = Tcl_DStringAppend(&newBuf, unsafeInfo[i].cmdName, -1);
+	    if (TclRenameCommand(interp, oldName, "___tmp") != TCL_OK
+		    || Tcl_HideCommand(interp, "___tmp", newName) != TCL_OK) {
+		Tcl_Panic("problem making 'file %s' safe: %s",
+			unsafeInfo[i].cmdName,
+			Tcl_GetString(Tcl_GetObjResult(interp)));
+	    }
+	    Tcl_CreateObjCommand(interp, oldName, BadFileSubcommand,
+		    (ClientData) unsafeInfo[i].cmdName, NULL);
+	}
+    }
+    Tcl_DStringFree(&oldBuf);
+    Tcl_DStringFree(&newBuf);
+
+    /*
+     * Ugh. The [file] command is now actually safe, but it is assumed by
+     * scripts that it is not, which messes up security policies. [Bug
+     * 3211758]
+     */
+
+    if (Tcl_HideCommand(interp, "file", "file") != TCL_OK) {
+	Tcl_Panic("problem making 'file' safe: %s",
+		Tcl_GetString(Tcl_GetObjResult(interp)));
+    }
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * BadFileSubcommand --
+ *
+ *	Command used to act as a backstop implementation when subcommands of
+ *	"file" are unsafe (the real implementations of the subcommands are
+ *	hidden). The clientData is always the full official subcommand name.
+ *
+ * Results:
+ *	A standard Tcl result (always a TCL_ERROR).
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+BadFileSubcommand(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const objv[])
+{
+    const char *subcommandName = (const char *) clientData;
+
+    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+	    "not allowed to invoke subcommand %s of file", subcommandName));
+    Tcl_SetErrorCode(interp, "TCL", "SAFE", "SUBCOMMAND", NULL);
+    return TCL_ERROR;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * FileAttrAccessTimeCmd --
+ *
+ *	This function is invoked to process the "file atime" Tcl command. See
+ *	the user documentation for details on what it does.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	May update the access time on the file, if requested by the user.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+FileAttrAccessTimeCmd(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const objv[])
+{
+    Tcl_StatBuf buf;
+    struct utimbuf tval;
+
+    if (objc < 2 || objc > 3) {
+	Tcl_WrongNumArgs(interp, 1, objv, "name ?time?");
+	return TCL_ERROR;
+    }
+    if (GetStatBuf(interp, objv[1], Tcl_FSStat, &buf) != TCL_OK) {
+	return TCL_ERROR;
+    }
+#if defined(_WIN32)
+    /* We use a value of 0 to indicate the access time not available */
+    if (buf.st_atime == 0) {
+        Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+                             "could not get access time for file \"%s\"",
+                             TclGetString(objv[1])));
+        return TCL_ERROR;
+    }
+#endif
+
+    if (objc == 3) {
+	/*
+	 * Need separate variable for reading longs from an object on 64-bit
+	 * platforms. [Bug 698146]
+	 */
+
+	long newTime;
+
+	if (TclGetLongFromObj(interp, objv[2], &newTime) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+
+	tval.actime = newTime;
+	tval.modtime = buf.st_mtime;
+
+	if (Tcl_FSUtime(objv[1], &tval) != 0) {
+	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		    "could not set access time for file \"%s\": %s",
+		    TclGetString(objv[1]), Tcl_PosixError(interp)));
+	    return TCL_ERROR;
+	}
+
+	/*
+	 * Do another stat to ensure that the we return the new recognized
+	 * atime - hopefully the same as the one we sent in. However, fs's
+	 * like FAT don't even know what atime is.
+	 */
+
+	if (GetStatBuf(interp, objv[1], Tcl_FSStat, &buf) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+    }
+
+    Tcl_SetObjResult(interp, Tcl_NewLongObj((long) buf.st_atime));
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * FileAttrModifyTimeCmd --
+ *
+ *	This function is invoked to process the "file mtime" Tcl command. See
+ *	the user documentation for details on what it does.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	May update the modification time on the file, if requested by the
+ *	user.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+FileAttrModifyTimeCmd(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const objv[])
+{
+    Tcl_StatBuf buf;
+    struct utimbuf tval;
+
+    if (objc < 2 || objc > 3) {
+	Tcl_WrongNumArgs(interp, 1, objv, "name ?time?");
+	return TCL_ERROR;
+    }
+    if (GetStatBuf(interp, objv[1], Tcl_FSStat, &buf) != TCL_OK) {
+	return TCL_ERROR;
+    }
+#if defined(_WIN32)
+    /* We use a value of 0 to indicate the modification time not available */
+    if (buf.st_mtime == 0) {
+        Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+                             "could not get modification time for file \"%s\"",
+                             TclGetString(objv[1])));
+        return TCL_ERROR;
+    }
+#endif
+    if (objc == 3) {
+	/*
+	 * Need separate variable for reading longs from an object on 64-bit
+	 * platforms. [Bug 698146]
+	 */
+
+	long newTime;
+
+	if (TclGetLongFromObj(interp, objv[2], &newTime) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+
+	tval.actime = buf.st_atime;
+	tval.modtime = newTime;
+
+	if (Tcl_FSUtime(objv[1], &tval) != 0) {
+	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		    "could not set modification time for file \"%s\": %s",
+		    TclGetString(objv[1]), Tcl_PosixError(interp)));
+	    return TCL_ERROR;
+	}
+
+	/*
+	 * Do another stat to ensure that the we return the new recognized
+	 * mtime - hopefully the same as the one we sent in.
+	 */
+
+	if (GetStatBuf(interp, objv[1], Tcl_FSStat, &buf) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+    }
+
+    Tcl_SetObjResult(interp, Tcl_NewLongObj((long) buf.st_mtime));
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * FileAttrLinkStatCmd --
+ *
+ *	This function is invoked to process the "file lstat" Tcl command. See
+ *	the user documentation for details on what it does.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	Writes to an array named by the user.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+FileAttrLinkStatCmd(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const objv[])
+{
+    Tcl_StatBuf buf;
+
+    if (objc != 3) {
+	Tcl_WrongNumArgs(interp, 1, objv, "name varName");
+	return TCL_ERROR;
+    }
+    if (GetStatBuf(interp, objv[1], Tcl_FSLstat, &buf) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    return StoreStatData(interp, objv[2], &buf);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * FileAttrStatCmd --
+ *
+ *	This function is invoked to process the "file stat" Tcl command. See
+ *	the user documentation for details on what it does.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	Writes to an array named by the user.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+FileAttrStatCmd(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const objv[])
+{
+    Tcl_StatBuf buf;
+
+    if (objc != 3) {
+	Tcl_WrongNumArgs(interp, 1, objv, "name varName");
+	return TCL_ERROR;
+    }
+    if (GetStatBuf(interp, objv[1], Tcl_FSStat, &buf) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    return StoreStatData(interp, objv[2], &buf);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * FileAttrTypeCmd --
+ *
+ *	This function is invoked to process the "file type" Tcl command. See
+ *	the user documentation for details on what it does.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+FileAttrTypeCmd(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const objv[])
+{
+    Tcl_StatBuf buf;
+
+    if (objc != 2) {
+	Tcl_WrongNumArgs(interp, 1, objv, "name");
+	return TCL_ERROR;
+    }
+    if (GetStatBuf(interp, objv[1], Tcl_FSLstat, &buf) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    Tcl_SetObjResult(interp, Tcl_NewStringObj(
+	    GetTypeFromMode((unsigned short) buf.st_mode), -1));
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * FileAttrSizeCmd --
+ *
+ *	This function is invoked to process the "file size" Tcl command. See
+ *	the user documentation for details on what it does.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+FileAttrSizeCmd(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const objv[])
+{
+    Tcl_StatBuf buf;
+
+    if (objc != 2) {
+	Tcl_WrongNumArgs(interp, 1, objv, "name");
+	return TCL_ERROR;
+    }
+    if (GetStatBuf(interp, objv[1], Tcl_FSStat, &buf) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    Tcl_SetObjResult(interp, Tcl_NewWideIntObj((Tcl_WideInt) buf.st_size));
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * FileAttrIsDirectoryCmd --
+ *
+ *	This function is invoked to process the "file isdirectory" Tcl
+ *	command. See the user documentation for details on what it does.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+FileAttrIsDirectoryCmd(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const objv[])
+{
+    Tcl_StatBuf buf;
+    int value = 0;
+
+    if (objc != 2) {
+	Tcl_WrongNumArgs(interp, 1, objv, "name");
+	return TCL_ERROR;
+    }
+    if (GetStatBuf(NULL, objv[1], Tcl_FSStat, &buf) == TCL_OK) {
+	value = S_ISDIR(buf.st_mode);
+    }
+    Tcl_SetObjResult(interp, Tcl_NewBooleanObj(value));
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * FileAttrIsExecutableCmd --
+ *
+ *	This function is invoked to process the "file executable" Tcl command.
+ *	See the user documentation for details on what it does.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+FileAttrIsExecutableCmd(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const objv[])
+{
+    if (objc != 2) {
+	Tcl_WrongNumArgs(interp, 1, objv, "name");
+	return TCL_ERROR;
+    }
+    return CheckAccess(interp, objv[1], X_OK);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * FileAttrIsExistingCmd --
+ *
+ *	This function is invoked to process the "file exists" Tcl command. See
+ *	the user documentation for details on what it does.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+FileAttrIsExistingCmd(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const objv[])
+{
+    if (objc != 2) {
+	Tcl_WrongNumArgs(interp, 1, objv, "name");
+	return TCL_ERROR;
+    }
+    return CheckAccess(interp, objv[1], F_OK);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * FileAttrIsFileCmd --
+ *
+ *	This function is invoked to process the "file isfile" Tcl command. See
+ *	the user documentation for details on what it does.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+FileAttrIsFileCmd(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const objv[])
+{
+    Tcl_StatBuf buf;
+    int value = 0;
+
+    if (objc != 2) {
+	Tcl_WrongNumArgs(interp, 1, objv, "name");
+	return TCL_ERROR;
+    }
+    if (GetStatBuf(NULL, objv[1], Tcl_FSStat, &buf) == TCL_OK) {
+	value = S_ISREG(buf.st_mode);
+    }
+    Tcl_SetObjResult(interp, Tcl_NewBooleanObj(value));
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * FileAttrIsOwnedCmd --
+ *
+ *	This function is invoked to process the "file owned" Tcl command. See
+ *	the user documentation for details on what it does.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+FileAttrIsOwnedCmd(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const objv[])
+{
+#ifdef __CYGWIN__
+#define geteuid() (short)(geteuid)() 
+#endif
+#if !defined(_WIN32)
+    Tcl_StatBuf buf;
+#endif
+    int value = 0;
+
+    if (objc != 2) {
+	Tcl_WrongNumArgs(interp, 1, objv, "name");
+	return TCL_ERROR;
+    }
+#if defined(_WIN32)
+    value = TclWinFileOwned(objv[1]);
+#else
+    if (GetStatBuf(NULL, objv[1], Tcl_FSStat, &buf) == TCL_OK) {
+	value = (geteuid() == buf.st_uid);
+    }
+#endif
+    Tcl_SetObjResult(interp, Tcl_NewBooleanObj(value));
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * FileAttrIsReadableCmd --
+ *
+ *	This function is invoked to process the "file readable" Tcl command.
+ *	See the user documentation for details on what it does.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+FileAttrIsReadableCmd(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const objv[])
+{
+    if (objc != 2) {
+	Tcl_WrongNumArgs(interp, 1, objv, "name");
+	return TCL_ERROR;
+    }
+    return CheckAccess(interp, objv[1], R_OK);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * FileAttrIsWritableCmd --
+ *
+ *	This function is invoked to process the "file writable" Tcl command.
+ *	See the user documentation for details on what it does.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+FileAttrIsWritableCmd(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const objv[])
+{
+    if (objc != 2) {
+	Tcl_WrongNumArgs(interp, 1, objv, "name");
+	return TCL_ERROR;
+    }
+    return CheckAccess(interp, objv[1], W_OK);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * PathDirNameCmd --
+ *
+ *	This function is invoked to process the "file dirname" Tcl command.
+ *	See the user documentation for details on what it does.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+PathDirNameCmd(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const objv[])
+{
+    Tcl_Obj *dirPtr;
+
+    if (objc != 2) {
+	Tcl_WrongNumArgs(interp, 1, objv, "name");
+	return TCL_ERROR;
+    }
+    dirPtr = TclPathPart(interp, objv[1], TCL_PATH_DIRNAME);
+    if (dirPtr == NULL) {
+	return TCL_ERROR;
+    }
+    Tcl_SetObjResult(interp, dirPtr);
+    Tcl_DecrRefCount(dirPtr);
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * PathExtensionCmd --
+ *
+ *	This function is invoked to process the "file extension" Tcl command.
+ *	See the user documentation for details on what it does.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+PathExtensionCmd(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const objv[])
+{
+    Tcl_Obj *dirPtr;
+
+    if (objc != 2) {
+	Tcl_WrongNumArgs(interp, 1, objv, "name");
+	return TCL_ERROR;
+    }
+    dirPtr = TclPathPart(interp, objv[1], TCL_PATH_EXTENSION);
+    if (dirPtr == NULL) {
+	return TCL_ERROR;
+    }
+    Tcl_SetObjResult(interp, dirPtr);
+    Tcl_DecrRefCount(dirPtr);
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * PathRootNameCmd --
+ *
+ *	This function is invoked to process the "file root" Tcl command. See
+ *	the user documentation for details on what it does.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+PathRootNameCmd(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const objv[])
+{
+    Tcl_Obj *dirPtr;
+
+    if (objc != 2) {
+	Tcl_WrongNumArgs(interp, 1, objv, "name");
+	return TCL_ERROR;
+    }
+    dirPtr = TclPathPart(interp, objv[1], TCL_PATH_ROOT);
+    if (dirPtr == NULL) {
+	return TCL_ERROR;
+    }
+    Tcl_SetObjResult(interp, dirPtr);
+    Tcl_DecrRefCount(dirPtr);
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * PathTailCmd --
+ *
+ *	This function is invoked to process the "file tail" Tcl command. See
+ *	the user documentation for details on what it does.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+PathTailCmd(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const objv[])
+{
+    Tcl_Obj *dirPtr;
+
+    if (objc != 2) {
+	Tcl_WrongNumArgs(interp, 1, objv, "name");
+	return TCL_ERROR;
+    }
+    dirPtr = TclPathPart(interp, objv[1], TCL_PATH_TAIL);
+    if (dirPtr == NULL) {
+	return TCL_ERROR;
+    }
+    Tcl_SetObjResult(interp, dirPtr);
+    Tcl_DecrRefCount(dirPtr);
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * PathFilesystemCmd --
+ *
+ *	This function is invoked to process the "file system" Tcl command. See
+ *	the user documentation for details on what it does.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+PathFilesystemCmd(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const objv[])
+{
+    Tcl_Obj *fsInfo;
+
+    if (objc != 2) {
+	Tcl_WrongNumArgs(interp, 1, objv, "name");
+	return TCL_ERROR;
+    }
+    fsInfo = Tcl_FSFileSystemInfo(objv[1]);
+    if (fsInfo == NULL) {
+	Tcl_SetObjResult(interp, Tcl_NewStringObj("unrecognised path", -1));
+	Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "FILESYSTEM",
+		Tcl_GetString(objv[1]), NULL);
+	return TCL_ERROR;
+    }
+    Tcl_SetObjResult(interp, fsInfo);
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * PathJoinCmd --
+ *
+ *	This function is invoked to process the "file join" Tcl command. See
+ *	the user documentation for details on what it does.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+PathJoinCmd(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const objv[])
+{
+    if (objc < 2) {
+	Tcl_WrongNumArgs(interp, 1, objv, "name ?name ...?");
+	return TCL_ERROR;
+    }
+    Tcl_SetObjResult(interp, TclJoinPath(objc - 1, objv + 1));
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * PathNativeNameCmd --
+ *
+ *	This function is invoked to process the "file nativename" Tcl command.
+ *	See the user documentation for details on what it does.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+PathNativeNameCmd(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const objv[])
+{
+    Tcl_DString ds;
+
+    if (objc != 2) {
+	Tcl_WrongNumArgs(interp, 1, objv, "name");
+	return TCL_ERROR;
+    }
+    if (Tcl_TranslateFileName(interp, TclGetString(objv[1]), &ds) == NULL) {
+	return TCL_ERROR;
+    }
+    Tcl_SetObjResult(interp, TclDStringToObj(&ds));
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * PathNormalizeCmd --
+ *
+ *	This function is invoked to process the "file normalize" Tcl command.
+ *	See the user documentation for details on what it does.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+PathNormalizeCmd(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const objv[])
+{
+    Tcl_Obj *fileName;
+
+    if (objc != 2) {
+	Tcl_WrongNumArgs(interp, 1, objv, "name");
+	return TCL_ERROR;
+    }
+    fileName = Tcl_FSGetNormalizedPath(interp, objv[1]);
+    if (fileName == NULL) {
+	return TCL_ERROR;
+    }
+    Tcl_SetObjResult(interp, fileName);
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * PathSplitCmd --
+ *
+ *	This function is invoked to process the "file split" Tcl command. See
+ *	the user documentation for details on what it does.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+PathSplitCmd(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const objv[])
+{
+    Tcl_Obj *res;
+
+    if (objc != 2) {
+	Tcl_WrongNumArgs(interp, 1, objv, "name");
+	return TCL_ERROR;
+    }
+    res = Tcl_FSSplitPath(objv[1], NULL);
+    if (res == NULL) {
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		"could not read \"%s\": no such file or directory",
+		TclGetString(objv[1])));
+	Tcl_SetErrorCode(interp, "TCL", "OPERATION", "PATHSPLIT", "NONESUCH",
+		NULL);
+	return TCL_ERROR;
+    }
+    Tcl_SetObjResult(interp, res);
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * PathTypeCmd --
+ *
+ *	This function is invoked to process the "file pathtype" Tcl command.
+ *	See the user documentation for details on what it does.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+PathTypeCmd(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const objv[])
+{
+    Tcl_Obj *typeName;
+
+    if (objc != 2) {
+	Tcl_WrongNumArgs(interp, 1, objv, "name");
+	return TCL_ERROR;
+    }
+    switch (Tcl_FSGetPathType(objv[1])) {
+    case TCL_PATH_ABSOLUTE:
+	TclNewLiteralStringObj(typeName, "absolute");
+	break;
+    case TCL_PATH_RELATIVE:
+	TclNewLiteralStringObj(typeName, "relative");
+	break;
+    case TCL_PATH_VOLUME_RELATIVE:
+	TclNewLiteralStringObj(typeName, "volumerelative");
+	break;
+    default:
+	/* Should be unreachable */
+	return TCL_OK;
+    }
+    Tcl_SetObjResult(interp, typeName);
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * FilesystemSeparatorCmd --
+ *
+ *	This function is invoked to process the "file separator" Tcl command.
+ *	See the user documentation for details on what it does.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+FilesystemSeparatorCmd(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const objv[])
+{
+    if (objc < 1 || objc > 2) {
+	Tcl_WrongNumArgs(interp, 1, objv, "?name?");
+	return TCL_ERROR;
+    }
+    if (objc == 1) {
+	const char *separator = NULL; /* lint */
+
+	switch (tclPlatform) {
+	case TCL_PLATFORM_UNIX:
+	    separator = "/";
+	    break;
+	case TCL_PLATFORM_WINDOWS:
+	    separator = "\\";
+	    break;
+	}
+	Tcl_SetObjResult(interp, Tcl_NewStringObj(separator, 1));
+    } else {
+	Tcl_Obj *separatorObj = Tcl_FSPathSeparator(objv[1]);
+
+	if (separatorObj == NULL) {
+	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		    "unrecognised path", -1));
+	    Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "FILESYSTEM",
+		    Tcl_GetString(objv[1]), NULL);
+	    return TCL_ERROR;
+	}
+	Tcl_SetObjResult(interp, separatorObj);
+    }
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * FilesystemVolumesCmd --
+ *
+ *	This function is invoked to process the "file volumes" Tcl command.
+ *	See the user documentation for details on what it does.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+FilesystemVolumesCmd(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const objv[])
+{
+    if (objc != 1) {
+	Tcl_WrongNumArgs(interp, 1, objv, NULL);
+	return TCL_ERROR;
+    }
+    Tcl_SetObjResult(interp, Tcl_FSListVolumes());
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * CheckAccess --
+ *
+ *	Utility procedure used by Tcl_FileObjCmd() to query file attributes
+ *	available through the access() system call.
+ *
+ * Results:
+ *	Always returns TCL_OK. Sets interp's result to boolean true or false
+ *	depending on whether the file has the specified attribute.
+ *
+ * Side effects:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+static int
+CheckAccess(
+    Tcl_Interp *interp,		/* Interp for status return. Must not be
+				 * NULL. */
+    Tcl_Obj *pathPtr,		/* Name of file to check. */
+    int mode)			/* Attribute to check; passed as argument to
+				 * access(). */
+{
+    int value;
+
+    if (Tcl_FSConvertToPathType(interp, pathPtr) != TCL_OK) {
+	value = 0;
+    } else {
+	value = (Tcl_FSAccess(pathPtr, mode) == 0);
+    }
+    Tcl_SetObjResult(interp, Tcl_NewBooleanObj(value));
+
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * GetStatBuf --
+ *
+ *	Utility procedure used by Tcl_FileObjCmd() to query file attributes
+ *	available through the stat() or lstat() system call.
+ *
+ * Results:
+ *	The return value is TCL_OK if the specified file exists and can be
+ *	stat'ed, TCL_ERROR otherwise. If TCL_ERROR is returned, an error
+ *	message is left in interp's result. If TCL_OK is returned, *statPtr is
+ *	filled with information about the specified file.
+ *
+ * Side effects:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+static int
+GetStatBuf(
+    Tcl_Interp *interp,		/* Interp for error return. May be NULL. */
+    Tcl_Obj *pathPtr,		/* Path name to examine. */
+    Tcl_FSStatProc *statProc,	/* Either stat() or lstat() depending on
+				 * desired behavior. */
+    Tcl_StatBuf *statPtr)	/* Filled with info about file obtained by
+				 * calling (*statProc)(). */
+{
+    int status;
+
+    if (Tcl_FSConvertToPathType(interp, pathPtr) != TCL_OK) {
+	return TCL_ERROR;
+    }
+
+    status = statProc(pathPtr, statPtr);
+
+    if (status < 0) {
+	if (interp != NULL) {
+	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		    "could not read \"%s\": %s",
+		    TclGetString(pathPtr), Tcl_PosixError(interp)));
+	}
+	return TCL_ERROR;
+    }
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * StoreStatData --
+ *
+ *	This is a utility procedure that breaks out the fields of a "stat"
+ *	structure and stores them in textual form into the elements of an
+ *	associative array.
+ *
+ * Results:
+ *	Returns a standard Tcl return value. If an error occurs then a message
+ *	is left in interp's result.
+ *
+ * Side effects:
+ *	Elements of the associative array given by "varName" are modified.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+StoreStatData(
+    Tcl_Interp *interp,		/* Interpreter for error reports. */
+    Tcl_Obj *varName,		/* Name of associative array variable in which
+				 * to store stat results. */
+    Tcl_StatBuf *statPtr)	/* Pointer to buffer containing stat data to
+				 * store in varName. */
+{
+    Tcl_Obj *field, *value;
+    register unsigned short mode;
+
+    /*
+     * Assume Tcl_ObjSetVar2() does not keep a copy of the field name!
+     *
+     * Might be a better idea to call Tcl_SetVar2Ex() instead, except we want
+     * to have an object (i.e. possibly cached) array variable name but a
+     * string element name, so no API exists. Messy.
+     */
+
+#define STORE_ARY(fieldName, object) \
+    TclNewLiteralStringObj(field, fieldName);				\
+    Tcl_IncrRefCount(field);						\
+    value = (object);							\
+    if (Tcl_ObjSetVar2(interp,varName,field,value,TCL_LEAVE_ERR_MSG)==NULL) { \
+	TclDecrRefCount(field);						\
+	return TCL_ERROR;						\
+    }									\
+    TclDecrRefCount(field);
+
+    /*
+     * Watch out porters; the inode is meant to be an *unsigned* value, so the
+     * cast might fail when there isn't a real arithmetic 'long long' type...
+     */
+
+    STORE_ARY("dev",	Tcl_NewLongObj((long)statPtr->st_dev));
+    STORE_ARY("ino",	Tcl_NewWideIntObj((Tcl_WideInt)statPtr->st_ino));
+    STORE_ARY("nlink",	Tcl_NewLongObj((long)statPtr->st_nlink));
+    STORE_ARY("uid",	Tcl_NewLongObj((long)statPtr->st_uid));
+    STORE_ARY("gid",	Tcl_NewLongObj((long)statPtr->st_gid));
+    STORE_ARY("size",	Tcl_NewWideIntObj((Tcl_WideInt)statPtr->st_size));
+#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
+    STORE_ARY("blocks",	Tcl_NewWideIntObj((Tcl_WideInt)statPtr->st_blocks));
+#endif
+#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
+    STORE_ARY("blksize", Tcl_NewLongObj((long)statPtr->st_blksize));
+#endif
+    STORE_ARY("atime",	Tcl_NewLongObj((long)statPtr->st_atime));
+    STORE_ARY("mtime",	Tcl_NewLongObj((long)statPtr->st_mtime));
+    STORE_ARY("ctime",	Tcl_NewLongObj((long)statPtr->st_ctime));
+    mode = (unsigned short) statPtr->st_mode;
+    STORE_ARY("mode",	Tcl_NewIntObj(mode));
+    STORE_ARY("type",	Tcl_NewStringObj(GetTypeFromMode(mode), -1));
+#undef STORE_ARY
+
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * GetTypeFromMode --
+ *
+ *	Given a mode word, returns a string identifying the type of a file.
+ *
+ * Results:
+ *	A static text string giving the file type from mode.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static const char *
+GetTypeFromMode(
+    int mode)
+{
+    if (S_ISREG(mode)) {
+	return "file";
+    } else if (S_ISDIR(mode)) {
+	return "directory";
+    } else if (S_ISCHR(mode)) {
+	return "characterSpecial";
+    } else if (S_ISBLK(mode)) {
+	return "blockSpecial";
+    } else if (S_ISFIFO(mode)) {
+	return "fifo";
+#ifdef S_ISLNK
+    } else if (S_ISLNK(mode)) {
+	return "link";
+#endif
+#ifdef S_ISSOCK
+    } else if (S_ISSOCK(mode)) {
+	return "socket";
+#endif
+    }
+    return "unknown";
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_ForObjCmd --
+ *
+ *	This procedure is invoked to process the "for" Tcl command. See the
+ *	user documentation for details on what it does.
+ *
+ *	With the bytecode compiler, this procedure is only called when a
+ *	command name is computed at runtime, and is "for" or the name to which
+ *	"for" was renamed: e.g.,
+ *	"set z for; $z {set i 0} {$i<100} {incr i} {puts $i}"
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ * Notes:
+ *	This command is split into a lot of pieces so that it can avoid doing
+ *	reentrant TEBC calls. This makes things rather hard to follow, but
+ *	here's the plan:
+ *
+ *	NR:	---------------_\
+ *	Direct:	Tcl_ForObjCmd -> TclNRForObjCmd
+ *					|
+ *				ForSetupCallback
+ *					|
+ *	[while] ------------> TclNRForIterCallback <---------.
+ *					|		     |
+ *				 ForCondCallback	     |
+ *					|		     |
+ *				 ForNextCallback ------------|
+ *					|		     |
+ *			       ForPostNextCallback	     |
+ *					|____________________|
+ *
+ *----------------------------------------------------------------------
+ */
+
+	/* ARGSUSED */
+int
+Tcl_ForObjCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    return Tcl_NRCallObjProc(interp, TclNRForObjCmd, dummy, objc, objv);
+}
+
+int
+TclNRForObjCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    Interp *iPtr = (Interp *) interp;
+    ForIterData *iterPtr;
+
+    if (objc != 5) {
+	Tcl_WrongNumArgs(interp, 1, objv, "start test next command");
+	return TCL_ERROR;
+    }
+
+    TclSmallAllocEx(interp, sizeof(ForIterData), iterPtr);
+    iterPtr->cond = objv[2];
+    iterPtr->body = objv[4];
+    iterPtr->next = objv[3];
+    iterPtr->msg  = "\n    (\"for\" body line %d)";
+    iterPtr->word = 4;
+
+    TclNRAddCallback(interp, ForSetupCallback, iterPtr, NULL, NULL, NULL);
+
+    /*
+     * TIP #280. Make invoking context available to initial script.
+     */
+
+    return TclNREvalObjEx(interp, objv[1], 0, iPtr->cmdFramePtr, 1);
+}
+
+static int
+ForSetupCallback(
+    ClientData data[],
+    Tcl_Interp *interp,
+    int result)
+{
+    ForIterData *iterPtr = data[0];
+
+    if (result != TCL_OK) {
+	if (result == TCL_ERROR) {
+	    Tcl_AddErrorInfo(interp, "\n    (\"for\" initial command)");
+	}
+	TclSmallFreeEx(interp, iterPtr);
+	return result;
+    }
+    TclNRAddCallback(interp, TclNRForIterCallback, iterPtr, NULL, NULL, NULL);
+    return TCL_OK;
+}
+
+int
+TclNRForIterCallback(
+    ClientData data[],
+    Tcl_Interp *interp,
+    int result)
+{
+    ForIterData *iterPtr = data[0];
+    Tcl_Obj *boolObj;
+
+    switch (result) {
+    case TCL_OK:
+    case TCL_CONTINUE:
+	/*
+	 * We need to reset the result before evaluating the expression.
+	 * Otherwise, any error message will be appended to the result of the
+	 * last evaluation.
+	 */
+
+	Tcl_ResetResult(interp);
+	TclNewObj(boolObj);
+	TclNRAddCallback(interp, ForCondCallback, iterPtr, boolObj, NULL,
+		NULL);
+	return Tcl_NRExprObj(interp, iterPtr->cond, boolObj);
+    case TCL_BREAK:
+	result = TCL_OK;
+	Tcl_ResetResult(interp);
+	break;
+    case TCL_ERROR:
+	Tcl_AppendObjToErrorInfo(interp,
+		Tcl_ObjPrintf(iterPtr->msg, Tcl_GetErrorLine(interp)));
+    }
+    TclSmallFreeEx(interp, iterPtr);
+    return result;
+}
+
+static int
+ForCondCallback(
+    ClientData data[],
+    Tcl_Interp *interp,
+    int result)
+{
+    Interp *iPtr = (Interp *) interp;
+    ForIterData *iterPtr = data[0];
+    Tcl_Obj *boolObj = data[1];
+    int value;
+
+    if (result != TCL_OK) {
+	Tcl_DecrRefCount(boolObj);
+	TclSmallFreeEx(interp, iterPtr);
+	return result;
+    } else if (Tcl_GetBooleanFromObj(interp, boolObj, &value) != TCL_OK) {
+	Tcl_DecrRefCount(boolObj);
+	TclSmallFreeEx(interp, iterPtr);
+	return TCL_ERROR;
+    }
+    Tcl_DecrRefCount(boolObj);
+
+    if (value) {
+	/* TIP #280. */
+	if (iterPtr->next) {
+	    TclNRAddCallback(interp, ForNextCallback, iterPtr, NULL, NULL,
+		    NULL);
+	} else {
+	    TclNRAddCallback(interp, TclNRForIterCallback, iterPtr, NULL,
+		    NULL, NULL);
+	}
+	return TclNREvalObjEx(interp, iterPtr->body, 0, iPtr->cmdFramePtr,
+		iterPtr->word);
+    }
+    TclSmallFreeEx(interp, iterPtr);
+    return result;
+}
+
+static int
+ForNextCallback(
+    ClientData data[],
+    Tcl_Interp *interp,
+    int result)
+{
+    Interp *iPtr = (Interp *) interp;
+    ForIterData *iterPtr = data[0];
+    Tcl_Obj *next = iterPtr->next;
+
+    if ((result == TCL_OK) || (result == TCL_CONTINUE)) {
+	TclNRAddCallback(interp, ForPostNextCallback, iterPtr, NULL, NULL,
+		NULL);
+
+	/*
+	 * TIP #280. Make invoking context available to next script.
+	 */
+
+	return TclNREvalObjEx(interp, next, 0, iPtr->cmdFramePtr, 3);
+    }
+
+    TclNRAddCallback(interp, TclNRForIterCallback, iterPtr, NULL, NULL, NULL);
+    return result;
+}
+
+static int
+ForPostNextCallback(
+    ClientData data[],
+    Tcl_Interp *interp,
+    int result)
+{
+    ForIterData *iterPtr = data[0];
+
+    if ((result != TCL_BREAK) && (result != TCL_OK)) {
+	if (result == TCL_ERROR) {
+	    Tcl_AddErrorInfo(interp, "\n    (\"for\" loop-end command)");
+	    TclSmallFreeEx(interp, iterPtr);
+	}
+	return result;
+    }
+    TclNRAddCallback(interp, TclNRForIterCallback, iterPtr, NULL, NULL, NULL);
+    return result;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_ForeachObjCmd, TclNRForeachCmd, EachloopCmd --
+ *
+ *	This object-based procedure is invoked to process the "foreach" Tcl
+ *	command. See the user documentation for details on what it does.
+ *
+ * Results:
+ *	A standard Tcl object result.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+	/* ARGSUSED */
+int
+Tcl_ForeachObjCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    return Tcl_NRCallObjProc(interp, TclNRForeachCmd, dummy, objc, objv);
+}
+
+int
+TclNRForeachCmd(
+    ClientData dummy,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const objv[])
+{
+    return EachloopCmd(interp, TCL_EACH_KEEP_NONE, objc, objv);
+}
+
+int
+Tcl_LmapObjCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    return Tcl_NRCallObjProc(interp, TclNRLmapCmd, dummy, objc, objv);
+}
+
+int
+TclNRLmapCmd(
+    ClientData dummy,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const objv[])
+{
+    return EachloopCmd(interp, TCL_EACH_COLLECT, objc, objv);
+}
+
+static inline int
+EachloopCmd(
+    Tcl_Interp *interp,		/* Our context for variables and script
+				 * evaluation. */
+    int collect,		/* Select collecting or accumulating mode
+				 * (TCL_EACH_*) */
+    int objc,			/* The arguments being passed in... */
+    Tcl_Obj *const objv[])
+{
+    int numLists = (objc-2) / 2;
+    register struct ForeachState *statePtr;
+    int i, j, result;
+
+    if (objc < 4 || (objc%2 != 0)) {
+	Tcl_WrongNumArgs(interp, 1, objv,
+		"varList list ?varList list ...? command");
+	return TCL_ERROR;
+    }
+
+    /*
+     * Manage numList parallel value lists.
+     * statePtr->argvList[i] is a value list counted by statePtr->argcList[i];
+     * statePtr->varvList[i] is the list of variables associated with the
+     *		value list;
+     * statePtr->varcList[i] is the number of variables associated with the
+     *		value list;
+     * statePtr->index[i] is the current pointer into the value list
+     *		statePtr->argvList[i].
+     *
+     * The setting up of all of these pointers is moderately messy, but allows
+     * the rest of this code to be simple and for us to use a single memory
+     * allocation for better performance.
+     */
+
+    statePtr = TclStackAlloc(interp,
+	    sizeof(struct ForeachState) + 3 * numLists * sizeof(int)
+	    + 2 * numLists * (sizeof(Tcl_Obj **) + sizeof(Tcl_Obj *)));
+    memset(statePtr, 0,
+	    sizeof(struct ForeachState) + 3 * numLists * sizeof(int)
+	    + 2 * numLists * (sizeof(Tcl_Obj **) + sizeof(Tcl_Obj *)));
+    statePtr->varvList = (Tcl_Obj ***) (statePtr + 1);
+    statePtr->argvList = statePtr->varvList + numLists;
+    statePtr->vCopyList = (Tcl_Obj **) (statePtr->argvList + numLists);
+    statePtr->aCopyList = statePtr->vCopyList + numLists;
+    statePtr->index = (int *) (statePtr->aCopyList + numLists);
+    statePtr->varcList = statePtr->index + numLists;
+    statePtr->argcList = statePtr->varcList + numLists;
+
+    statePtr->numLists = numLists;
+    statePtr->bodyPtr = objv[objc - 1];
+    statePtr->bodyIdx = objc - 1;
+
+    if (collect == TCL_EACH_COLLECT) {
+	statePtr->resultList = Tcl_NewListObj(0, NULL);
+    } else {
+	statePtr->resultList = NULL;
+    }
+
+    /*
+     * Break up the value lists and variable lists into elements.
+     */
+
+    for (i=0 ; i<numLists ; i++) {
+	statePtr->vCopyList[i] = TclListObjCopy(interp, objv[1+i*2]);
+	if (statePtr->vCopyList[i] == NULL) {
+	    result = TCL_ERROR;
+	    goto done;
+	}
+	TclListObjGetElements(NULL, statePtr->vCopyList[i],
+		&statePtr->varcList[i], &statePtr->varvList[i]);
+	if (statePtr->varcList[i] < 1) {
+	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		    "%s varlist is empty",
+		    (statePtr->resultList != NULL ? "lmap" : "foreach")));
+	    Tcl_SetErrorCode(interp, "TCL", "OPERATION",
+		    (statePtr->resultList != NULL ? "LMAP" : "FOREACH"),
+		    "NEEDVARS", NULL);
+	    result = TCL_ERROR;
+	    goto done;
+	}
+
+	statePtr->aCopyList[i] = TclListObjCopy(interp, objv[2+i*2]);
+	if (statePtr->aCopyList[i] == NULL) {
+	    result = TCL_ERROR;
+	    goto done;
+	}
+	TclListObjGetElements(NULL, statePtr->aCopyList[i],
+		&statePtr->argcList[i], &statePtr->argvList[i]);
+
+	j = statePtr->argcList[i] / statePtr->varcList[i];
+	if ((statePtr->argcList[i] % statePtr->varcList[i]) != 0) {
+	    j++;
+	}
+	if (j > statePtr->maxj) {
+	    statePtr->maxj = j;
+	}
+    }
+
+    /*
+     * If there is any work to do, assign the variables and set things going
+     * non-recursively.
+     */
+
+    if (statePtr->maxj > 0) {
+	result = ForeachAssignments(interp, statePtr);
+	if (result == TCL_ERROR) {
+	    goto done;
+	}
+
+	TclNRAddCallback(interp, ForeachLoopStep, statePtr, NULL, NULL, NULL);
+	return TclNREvalObjEx(interp, objv[objc-1], 0,
+		((Interp *) interp)->cmdFramePtr, objc-1);
+    }
+
+    /*
+     * This cleanup stage is only used when an error occurs during setup or if
+     * there is no work to do.
+     */
+
+    result = TCL_OK;
+  done:
+    ForeachCleanup(interp, statePtr);
+    return result;
+}
+
+/*
+ * Post-body processing handler.
+ */
+
+static int
+ForeachLoopStep(
+    ClientData data[],
+    Tcl_Interp *interp,
+    int result)
+{
+    register struct ForeachState *statePtr = data[0];
+
+    /*
+     * Process the result code from this run of the [foreach] body. Note that
+     * this switch uses fallthroughs in several places. Maintainer aware!
+     */
+
+    switch (result) {
+    case TCL_CONTINUE:
+	result = TCL_OK;
+	break;
+    case TCL_OK:
+	if (statePtr->resultList != NULL) {
+	    Tcl_ListObjAppendElement(interp, statePtr->resultList,
+		    Tcl_GetObjResult(interp));
+	}
+	break;
+    case TCL_BREAK:
+	result = TCL_OK;
+	goto finish;
+    case TCL_ERROR:
+	Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf(
+		"\n    (\"%s\" body line %d)",
+		(statePtr->resultList != NULL ? "lmap" : "foreach"),
+		Tcl_GetErrorLine(interp)));
+    default:
+	goto done;
+    }
+
+    /*
+     * Test if there is work still to be done. If so, do the next round of
+     * variable assignments, reschedule ourselves and run the body again.
+     */
+
+    if (statePtr->maxj > ++statePtr->j) {
+	result = ForeachAssignments(interp, statePtr);
+	if (result == TCL_ERROR) {
+	    goto done;
+	}
+
+	TclNRAddCallback(interp, ForeachLoopStep, statePtr, NULL, NULL, NULL);
+	return TclNREvalObjEx(interp, statePtr->bodyPtr, 0,
+		((Interp *) interp)->cmdFramePtr, statePtr->bodyIdx);
+    }
+
+    /*
+     * We're done. Tidy up our work space and finish off.
+     */
+
+  finish:
+    if (statePtr->resultList == NULL) {
+	Tcl_ResetResult(interp);
+    } else {
+	Tcl_SetObjResult(interp, statePtr->resultList);
+	statePtr->resultList = NULL;	/* Don't clean it up */
+    }
+
+  done:
+    ForeachCleanup(interp, statePtr);
+    return result;
+}
+
+/*
+ * Factored out code to do the assignments in [foreach].
+ */
+
+static inline int
+ForeachAssignments(
+    Tcl_Interp *interp,
+    struct ForeachState *statePtr)
+{
+    int i, v, k;
+    Tcl_Obj *valuePtr, *varValuePtr;
+
+    for (i=0 ; i<statePtr->numLists ; i++) {
+	for (v=0 ; v<statePtr->varcList[i] ; v++) {
+	    k = statePtr->index[i]++;
+
+	    if (k < statePtr->argcList[i]) {
+		valuePtr = statePtr->argvList[i][k];
+	    } else {
+		TclNewObj(valuePtr);	/* Empty string */
+	    }
+
+	    varValuePtr = Tcl_ObjSetVar2(interp, statePtr->varvList[i][v],
+		    NULL, valuePtr, TCL_LEAVE_ERR_MSG);
+
+	    if (varValuePtr == NULL) {
+		Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf(
+			"\n    (setting %s loop variable \"%s\")",
+			(statePtr->resultList != NULL ? "lmap" : "foreach"),
+			TclGetString(statePtr->varvList[i][v])));
+		return TCL_ERROR;
+	    }
+	}
+    }
+
+    return TCL_OK;
+}
+
+/*
+ * Factored out code for cleaning up the state of the foreach.
+ */
+
+static inline void
+ForeachCleanup(
+    Tcl_Interp *interp,
+    struct ForeachState *statePtr)
+{
+    int i;
+
+    for (i=0 ; i<statePtr->numLists ; i++) {
+	if (statePtr->vCopyList[i]) {
+	    TclDecrRefCount(statePtr->vCopyList[i]);
+	}
+	if (statePtr->aCopyList[i]) {
+	    TclDecrRefCount(statePtr->aCopyList[i]);
+	}
+    }
+    if (statePtr->resultList != NULL) {
+	TclDecrRefCount(statePtr->resultList);
+    }
+    TclStackFree(interp, statePtr);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_FormatObjCmd --
+ *
+ *	This procedure is invoked to process the "format" Tcl command. See
+ *	the user documentation for details on what it does.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+	/* ARGSUSED */
+int
+Tcl_FormatObjCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    Tcl_Obj *resultPtr;		/* Where result is stored finally. */
+
+    if (objc < 2) {
+	Tcl_WrongNumArgs(interp, 1, objv, "formatString ?arg ...?");
+	return TCL_ERROR;
+    }
+
+    resultPtr = Tcl_Format(interp, TclGetString(objv[1]), objc-2, objv+2);
+    if (resultPtr == NULL) {
+	return TCL_ERROR;
+    }
+    Tcl_SetObjResult(interp, resultPtr);
+    return TCL_OK;
+}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tclCmdIL.c b/generic/tclCmdIL.c
new file mode 100644
index 0000000..0a1b4fe
--- /dev/null
+++ b/generic/tclCmdIL.c
@@ -0,0 +1,4533 @@
+/*
+ * tclCmdIL.c --
+ *
+ *	This file contains the top-level command routines for most of the Tcl
+ *	built-in commands whose names begin with the letters I through L. It
+ *	contains only commands in the generic core (i.e., those that don't
+ *	depend much upon UNIX facilities).
+ *
+ * Copyright (c) 1987-1993 The Regents of the University of California.
+ * Copyright (c) 1993-1997 Lucent Technologies.
+ * Copyright (c) 1994-1997 Sun Microsystems, Inc.
+ * Copyright (c) 1998-1999 by Scriptics Corporation.
+ * Copyright (c) 2001 by Kevin B. Kenny. All rights reserved.
+ * Copyright (c) 2005 Donal K. Fellows.
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#include "tclInt.h"
+#include "tclRegexp.h"
+
+/*
+ * During execution of the "lsort" command, structures of the following type
+ * are used to arrange the objects being sorted into a collection of linked
+ * lists.
+ */
+
+typedef struct SortElement {
+    union {			/* The value that we sorting by. */
+	const char *strValuePtr;
+	Tcl_WideInt wideValue;
+	double doubleValue;
+	Tcl_Obj *objValuePtr;
+    } collationKey;
+    union {			/* Object being sorted, or its index. */
+	Tcl_Obj *objPtr;
+	int index;
+    } payload;
+    struct SortElement *nextPtr;/* Next element in the list, or NULL for end
+				 * of list. */
+} SortElement;
+
+/*
+ * These function pointer types are used with the "lsearch" and "lsort"
+ * commands to facilitate the "-nocase" option.
+ */
+
+typedef int (*SortStrCmpFn_t) (const char *, const char *);
+typedef int (*SortMemCmpFn_t) (const void *, const void *, size_t);
+
+/*
+ * The "lsort" command needs to pass certain information down to the function
+ * that compares two list elements, and the comparison function needs to pass
+ * success or failure information back up to the top-level "lsort" command.
+ * The following structure is used to pass this information.
+ */
+
+typedef struct SortInfo {
+    int isIncreasing;		/* Nonzero means sort in increasing order. */
+    int sortMode;		/* The sort mode. One of SORTMODE_* values
+				 * defined below. */
+    Tcl_Obj *compareCmdPtr;	/* The Tcl comparison command when sortMode is
+				 * SORTMODE_COMMAND. Pre-initialized to hold
+				 * base of command. */
+    int *indexv;		/* If the -index option was specified, this
+				 * holds the indexes contained in the list
+				 * supplied as an argument to that option.
+				 * NULL if no indexes supplied, and points to
+				 * singleIndex field when only one
+				 * supplied. */
+    int indexc;			/* Number of indexes in indexv array. */
+    int singleIndex;		/* Static space for common index case. */
+    int unique;
+    int numElements;
+    Tcl_Interp *interp;		/* The interpreter in which the sort is being
+				 * done. */
+    int resultCode;		/* Completion code for the lsort command. If
+				 * an error occurs during the sort this is
+				 * changed from TCL_OK to TCL_ERROR. */
+} SortInfo;
+
+/*
+ * The "sortMode" field of the SortInfo structure can take on any of the
+ * following values.
+ */
+
+#define SORTMODE_ASCII		0
+#define SORTMODE_INTEGER	1
+#define SORTMODE_REAL		2
+#define SORTMODE_COMMAND	3
+#define SORTMODE_DICTIONARY	4
+#define SORTMODE_ASCII_NC	8
+
+/*
+ * Magic values for the index field of the SortInfo structure. Note that the
+ * index "end-1" will be translated to SORTIDX_END-1, etc.
+ */
+
+#define SORTIDX_NONE	-1	/* Not indexed; use whole value. */
+#define SORTIDX_END	-2	/* Indexed from end. */
+
+/*
+ * Forward declarations for procedures defined in this file:
+ */
+
+static int		DictionaryCompare(const char *left, const char *right);
+static Tcl_NRPostProc	IfConditionCallback;
+static int		InfoArgsCmd(ClientData dummy, Tcl_Interp *interp,
+			    int objc, Tcl_Obj *const objv[]);
+static int		InfoBodyCmd(ClientData dummy, Tcl_Interp *interp,
+			    int objc, Tcl_Obj *const objv[]);
+static int		InfoCmdCountCmd(ClientData dummy, Tcl_Interp *interp,
+			    int objc, Tcl_Obj *const objv[]);
+static int		InfoCommandsCmd(ClientData dummy, Tcl_Interp *interp,
+			    int objc, Tcl_Obj *const objv[]);
+static int		InfoCompleteCmd(ClientData dummy, Tcl_Interp *interp,
+			    int objc, Tcl_Obj *const objv[]);
+static int		InfoDefaultCmd(ClientData dummy, Tcl_Interp *interp,
+			    int objc, Tcl_Obj *const objv[]);
+/* TIP #348 - New 'info' subcommand 'errorstack' */
+static int		InfoErrorStackCmd(ClientData dummy, Tcl_Interp *interp,
+			    int objc, Tcl_Obj *const objv[]);
+/* TIP #280 - New 'info' subcommand 'frame' */
+static int		InfoFrameCmd(ClientData dummy, Tcl_Interp *interp,
+			    int objc, Tcl_Obj *const objv[]);
+static int		InfoFunctionsCmd(ClientData dummy, Tcl_Interp *interp,
+			    int objc, Tcl_Obj *const objv[]);
+static int		InfoHostnameCmd(ClientData dummy, Tcl_Interp *interp,
+			    int objc, Tcl_Obj *const objv[]);
+static int		InfoLevelCmd(ClientData dummy, Tcl_Interp *interp,
+			    int objc, Tcl_Obj *const objv[]);
+static int		InfoLibraryCmd(ClientData dummy, Tcl_Interp *interp,
+			    int objc, Tcl_Obj *const objv[]);
+static int		InfoLoadedCmd(ClientData dummy, Tcl_Interp *interp,
+			    int objc, Tcl_Obj *const objv[]);
+static int		InfoNameOfExecutableCmd(ClientData dummy,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+static int		InfoPatchLevelCmd(ClientData dummy, Tcl_Interp *interp,
+			    int objc, Tcl_Obj *const objv[]);
+static int		InfoProcsCmd(ClientData dummy, Tcl_Interp *interp,
+			    int objc, Tcl_Obj *const objv[]);
+static int		InfoScriptCmd(ClientData dummy, Tcl_Interp *interp,
+			    int objc, Tcl_Obj *const objv[]);
+static int		InfoSharedlibCmd(ClientData dummy, Tcl_Interp *interp,
+			    int objc, Tcl_Obj *const objv[]);
+static int		InfoTclVersionCmd(ClientData dummy, Tcl_Interp *interp,
+			    int objc, Tcl_Obj *const objv[]);
+static SortElement *	MergeLists(SortElement *leftPtr, SortElement *rightPtr,
+			    SortInfo *infoPtr);
+static int		SortCompare(SortElement *firstPtr, SortElement *second,
+			    SortInfo *infoPtr);
+static Tcl_Obj *	SelectObjFromSublist(Tcl_Obj *firstPtr,
+			    SortInfo *infoPtr);
+
+/*
+ * Array of values describing how to implement each standard subcommand of the
+ * "info" command.
+ */
+
+static const EnsembleImplMap defaultInfoMap[] = {
+    {"args",		   InfoArgsCmd,		    TclCompileBasic1ArgCmd, NULL, NULL, 0},
+    {"body",		   InfoBodyCmd,		    TclCompileBasic1ArgCmd, NULL, NULL, 0},
+    {"cmdcount",	   InfoCmdCountCmd,	    TclCompileBasic0ArgCmd, NULL, NULL, 0},
+    {"commands",	   InfoCommandsCmd,	    TclCompileInfoCommandsCmd, NULL, NULL, 0},
+    {"complete",	   InfoCompleteCmd,	    TclCompileBasic1ArgCmd, NULL, NULL, 0},
+    {"coroutine",	   TclInfoCoroutineCmd,     TclCompileInfoCoroutineCmd, NULL, NULL, 0},
+    {"default",		   InfoDefaultCmd,	    TclCompileBasic3ArgCmd, NULL, NULL, 0},
+    {"errorstack",	   InfoErrorStackCmd,	    TclCompileBasic0Or1ArgCmd, NULL, NULL, 0},
+    {"exists",		   TclInfoExistsCmd,	    TclCompileInfoExistsCmd, NULL, NULL, 0},
+    {"frame",		   InfoFrameCmd,	    TclCompileBasic0Or1ArgCmd, NULL, NULL, 0},
+    {"functions",	   InfoFunctionsCmd,	    TclCompileBasic0Or1ArgCmd, NULL, NULL, 0},
+    {"globals",		   TclInfoGlobalsCmd,	    TclCompileBasic0Or1ArgCmd, NULL, NULL, 0},
+    {"hostname",	   InfoHostnameCmd,	    TclCompileBasic0ArgCmd, NULL, NULL, 0},
+    {"level",		   InfoLevelCmd,	    TclCompileInfoLevelCmd, NULL, NULL, 0},
+    {"library",		   InfoLibraryCmd,	    TclCompileBasic0ArgCmd, NULL, NULL, 0},
+    {"loaded",		   InfoLoadedCmd,	    TclCompileBasic0Or1ArgCmd, NULL, NULL, 0},
+    {"locals",		   TclInfoLocalsCmd,	    TclCompileBasic0Or1ArgCmd, NULL, NULL, 0},
+    {"nameofexecutable",   InfoNameOfExecutableCmd, TclCompileBasic0ArgCmd, NULL, NULL, 0},
+    {"patchlevel",	   InfoPatchLevelCmd,	    TclCompileBasic0ArgCmd, NULL, NULL, 0},
+    {"procs",		   InfoProcsCmd,	    TclCompileBasic0Or1ArgCmd, NULL, NULL, 0},
+    {"script",		   InfoScriptCmd,	    TclCompileBasic0Or1ArgCmd, NULL, NULL, 0},
+    {"sharedlibextension", InfoSharedlibCmd,	    TclCompileBasic0ArgCmd, NULL, NULL, 0},
+    {"tclversion",	   InfoTclVersionCmd,	    TclCompileBasic0ArgCmd, NULL, NULL, 0},
+    {"vars",		   TclInfoVarsCmd,	    TclCompileBasic0Or1ArgCmd, NULL, NULL, 0},
+    {NULL, NULL, NULL, NULL, NULL, 0}
+};
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_IfObjCmd --
+ *
+ *	This procedure is invoked to process the "if" Tcl command. See the
+ *	user documentation for details on what it does.
+ *
+ *	With the bytecode compiler, this procedure is only called when a
+ *	command name is computed at runtime, and is "if" or the name to which
+ *	"if" was renamed: e.g., "set z if; $z 1 {puts foo}"
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_IfObjCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    return Tcl_NRCallObjProc(interp, TclNRIfObjCmd, dummy, objc, objv);
+}
+
+int
+TclNRIfObjCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    Tcl_Obj *boolObj;
+
+    if (objc <= 1) {
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		"wrong # args: no expression after \"%s\" argument",
+		TclGetString(objv[0])));
+	Tcl_SetErrorCode(interp, "TCL", "WRONGARGS", NULL);
+	return TCL_ERROR;
+    }
+
+    /*
+     * At this point, objv[1] refers to the main expression to test. The
+     * arguments after the expression must be "then" (optional) and a script
+     * to execute if the expression is true.
+     */
+
+    TclNewObj(boolObj);
+    Tcl_NRAddCallback(interp, IfConditionCallback, INT2PTR(objc),
+	    (ClientData) objv, INT2PTR(1), boolObj);
+    return Tcl_NRExprObj(interp, objv[1], boolObj);
+}
+
+static int
+IfConditionCallback(
+    ClientData data[],
+    Tcl_Interp *interp,
+    int result)
+{
+    Interp *iPtr = (Interp *) interp;
+    int objc = PTR2INT(data[0]);
+    Tcl_Obj *const *objv = data[1];
+    int i = PTR2INT(data[2]);
+    Tcl_Obj *boolObj = data[3];
+    int value, thenScriptIndex = 0;
+    const char *clause;
+
+    if (result != TCL_OK) {
+	TclDecrRefCount(boolObj);
+	return result;
+    }
+    if (Tcl_GetBooleanFromObj(interp, boolObj, &value) != TCL_OK) {
+	TclDecrRefCount(boolObj);
+	return TCL_ERROR;
+    }
+    TclDecrRefCount(boolObj);
+
+    while (1) {
+	i++;
+	if (i >= objc) {
+	    goto missingScript;
+	}
+	clause = TclGetString(objv[i]);
+	if ((i < objc) && (strcmp(clause, "then") == 0)) {
+	    i++;
+	}
+	if (i >= objc) {
+	    goto missingScript;
+	}
+	if (value) {
+	    thenScriptIndex = i;
+	    value = 0;
+	}
+
+	/*
+	 * The expression evaluated to false. Skip the command, then see if
+	 * there is an "else" or "elseif" clause.
+	 */
+
+	i++;
+	if (i >= objc) {
+	    if (thenScriptIndex) {
+		/*
+		 * TIP #280. Make invoking context available to branch.
+		 */
+
+		return TclNREvalObjEx(interp, objv[thenScriptIndex], 0,
+			iPtr->cmdFramePtr, thenScriptIndex);
+	    }
+	    return TCL_OK;
+	}
+	clause = TclGetString(objv[i]);
+	if ((clause[0] != 'e') || (strcmp(clause, "elseif") != 0)) {
+	    break;
+	}
+	i++;
+
+	/*
+	 * At this point in the loop, objv and objc refer to an expression to
+	 * test, either for the main expression or an expression following an
+	 * "elseif". The arguments after the expression must be "then"
+	 * (optional) and a script to execute if the expression is true.
+	 */
+
+	if (i >= objc) {
+	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		    "wrong # args: no expression after \"%s\" argument",
+		    clause));
+	    Tcl_SetErrorCode(interp, "TCL", "WRONGARGS", NULL);
+	    return TCL_ERROR;
+	}
+	if (!thenScriptIndex) {
+	    TclNewObj(boolObj);
+	    Tcl_NRAddCallback(interp, IfConditionCallback, data[0], data[1],
+		    INT2PTR(i), boolObj);
+	    return Tcl_NRExprObj(interp, objv[i], boolObj);
+	}
+    }
+
+    /*
+     * Couldn't find a "then" or "elseif" clause to execute. Check now for an
+     * "else" clause. We know that there's at least one more argument when we
+     * get here.
+     */
+
+    if (strcmp(clause, "else") == 0) {
+	i++;
+	if (i >= objc) {
+	    goto missingScript;
+	}
+    }
+    if (i < objc - 1) {
+	Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		"wrong # args: extra words after \"else\" clause in \"if\" command",
+		-1));
+	Tcl_SetErrorCode(interp, "TCL", "WRONGARGS", NULL);
+	return TCL_ERROR;
+    }
+    if (thenScriptIndex) {
+	/*
+	 * TIP #280. Make invoking context available to branch/else.
+	 */
+
+	return TclNREvalObjEx(interp, objv[thenScriptIndex], 0,
+		iPtr->cmdFramePtr, thenScriptIndex);
+    }
+    return TclNREvalObjEx(interp, objv[i], 0, iPtr->cmdFramePtr, i);
+
+  missingScript:
+    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+	    "wrong # args: no script following \"%s\" argument",
+	    TclGetString(objv[i-1])));
+    Tcl_SetErrorCode(interp, "TCL", "WRONGARGS", NULL);
+    return TCL_ERROR;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_IncrObjCmd --
+ *
+ *	This procedure is invoked to process the "incr" Tcl command. See the
+ *	user documentation for details on what it does.
+ *
+ *	With the bytecode compiler, this procedure is only called when a
+ *	command name is computed at runtime, and is "incr" or the name to
+ *	which "incr" was renamed: e.g., "set z incr; $z i -1"
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_IncrObjCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    Tcl_Obj *newValuePtr, *incrPtr;
+
+    if ((objc != 2) && (objc != 3)) {
+	Tcl_WrongNumArgs(interp, 1, objv, "varName ?increment?");
+	return TCL_ERROR;
+    }
+
+    if (objc == 3) {
+	incrPtr = objv[2];
+    } else {
+	incrPtr = Tcl_NewIntObj(1);
+    }
+    Tcl_IncrRefCount(incrPtr);
+    newValuePtr = TclIncrObjVar2(interp, objv[1], NULL,
+	    incrPtr, TCL_LEAVE_ERR_MSG);
+    Tcl_DecrRefCount(incrPtr);
+
+    if (newValuePtr == NULL) {
+	return TCL_ERROR;
+    }
+
+    /*
+     * Set the interpreter's object result to refer to the variable's new
+     * value object.
+     */
+
+    Tcl_SetObjResult(interp, newValuePtr);
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclInitInfoCmd --
+ *
+ *	This function is called to create the "info" Tcl command. See the user
+ *	documentation for details on what it does.
+ *
+ * Results:
+ *	Handle for the info command, or NULL on failure.
+ *
+ * Side effects:
+ *	none
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_Command
+TclInitInfoCmd(
+    Tcl_Interp *interp)		/* Current interpreter. */
+{
+    return TclMakeEnsemble(interp, "info", defaultInfoMap);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * InfoArgsCmd --
+ *
+ *	Called to implement the "info args" command that returns the argument
+ *	list for a procedure. Handles the following syntax:
+ *
+ *	    info args procName
+ *
+ * Results:
+ *	Returns TCL_OK if successful and TCL_ERROR if there is an error.
+ *
+ * Side effects:
+ *	Returns a result in the interpreter's result object. If there is an
+ *	error, the result is an error message.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+InfoArgsCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    register Interp *iPtr = (Interp *) interp;
+    const char *name;
+    Proc *procPtr;
+    CompiledLocal *localPtr;
+    Tcl_Obj *listObjPtr;
+
+    if (objc != 2) {
+	Tcl_WrongNumArgs(interp, 1, objv, "procname");
+	return TCL_ERROR;
+    }
+
+    name = TclGetString(objv[1]);
+    procPtr = TclFindProc(iPtr, name);
+    if (procPtr == NULL) {
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		"\"%s\" isn't a procedure", name));
+	Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "PROCEDURE", name, NULL);
+	return TCL_ERROR;
+    }
+
+    /*
+     * Build a return list containing the arguments.
+     */
+
+    listObjPtr = Tcl_NewListObj(0, NULL);
+    for (localPtr = procPtr->firstLocalPtr;  localPtr != NULL;
+	    localPtr = localPtr->nextPtr) {
+	if (TclIsVarArgument(localPtr)) {
+	    Tcl_ListObjAppendElement(interp, listObjPtr,
+		    Tcl_NewStringObj(localPtr->name, -1));
+	}
+    }
+    Tcl_SetObjResult(interp, listObjPtr);
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * InfoBodyCmd --
+ *
+ *	Called to implement the "info body" command that returns the body for
+ *	a procedure. Handles the following syntax:
+ *
+ *	    info body procName
+ *
+ * Results:
+ *	Returns TCL_OK if successful and TCL_ERROR if there is an error.
+ *
+ * Side effects:
+ *	Returns a result in the interpreter's result object. If there is an
+ *	error, the result is an error message.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+InfoBodyCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    register Interp *iPtr = (Interp *) interp;
+    const char *name;
+    Proc *procPtr;
+    Tcl_Obj *bodyPtr, *resultPtr;
+
+    if (objc != 2) {
+	Tcl_WrongNumArgs(interp, 1, objv, "procname");
+	return TCL_ERROR;
+    }
+
+    name = TclGetString(objv[1]);
+    procPtr = TclFindProc(iPtr, name);
+    if (procPtr == NULL) {
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		"\"%s\" isn't a procedure", name));
+	Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "PROCEDURE", name, NULL);
+	return TCL_ERROR;
+    }
+
+    /*
+     * Here we used to return procPtr->bodyPtr, except when the body was
+     * bytecompiled - in that case, the return was a copy of the body's string
+     * rep. In order to better isolate the implementation details of the
+     * compiler/engine subsystem, we now always return a copy of the string
+     * rep. It is important to return a copy so that later manipulations of
+     * the object do not invalidate the internal rep.
+     */
+
+    bodyPtr = procPtr->bodyPtr;
+    if (bodyPtr->bytes == NULL) {
+	/*
+	 * The string rep might not be valid if the procedure has never been
+	 * run before. [Bug #545644]
+	 */
+
+	TclGetString(bodyPtr);
+    }
+    resultPtr = Tcl_NewStringObj(bodyPtr->bytes, bodyPtr->length);
+
+    Tcl_SetObjResult(interp, resultPtr);
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * InfoCmdCountCmd --
+ *
+ *	Called to implement the "info cmdcount" command that returns the
+ *	number of commands that have been executed. Handles the following
+ *	syntax:
+ *
+ *	    info cmdcount
+ *
+ * Results:
+ *	Returns TCL_OK if successful and TCL_ERROR if there is an error.
+ *
+ * Side effects:
+ *	Returns a result in the interpreter's result object. If there is an
+ *	error, the result is an error message.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+InfoCmdCountCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    Interp *iPtr = (Interp *) interp;
+
+    if (objc != 1) {
+	Tcl_WrongNumArgs(interp, 1, objv, NULL);
+	return TCL_ERROR;
+    }
+
+    Tcl_SetObjResult(interp, Tcl_NewIntObj(iPtr->cmdCount));
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * InfoCommandsCmd --
+ *
+ *	Called to implement the "info commands" command that returns the list
+ *	of commands in the interpreter that match an optional pattern. The
+ *	pattern, if any, consists of an optional sequence of namespace names
+ *	separated by "::" qualifiers, which is followed by a glob-style
+ *	pattern that restricts which commands are returned. Handles the
+ *	following syntax:
+ *
+ *	    info commands ?pattern?
+ *
+ * Results:
+ *	Returns TCL_OK if successful and TCL_ERROR if there is an error.
+ *
+ * Side effects:
+ *	Returns a result in the interpreter's result object. If there is an
+ *	error, the result is an error message.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+InfoCommandsCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    const char *cmdName, *pattern;
+    const char *simplePattern;
+    register Tcl_HashEntry *entryPtr;
+    Tcl_HashSearch search;
+    Namespace *nsPtr;
+    Namespace *globalNsPtr = (Namespace *) Tcl_GetGlobalNamespace(interp);
+    Namespace *currNsPtr = (Namespace *) Tcl_GetCurrentNamespace(interp);
+    Tcl_Obj *listPtr, *elemObjPtr;
+    int specificNsInPattern = 0;/* Init. to avoid compiler warning. */
+    Tcl_Command cmd;
+    int i;
+
+    /*
+     * Get the pattern and find the "effective namespace" in which to list
+     * commands.
+     */
+
+    if (objc == 1) {
+	simplePattern = NULL;
+	nsPtr = currNsPtr;
+	specificNsInPattern = 0;
+    } else if (objc == 2) {
+	/*
+	 * From the pattern, get the effective namespace and the simple
+	 * pattern (no namespace qualifiers or ::'s) at the end. If an error
+	 * was found while parsing the pattern, return it. Otherwise, if the
+	 * namespace wasn't found, just leave nsPtr NULL: we will return an
+	 * empty list since no commands there can be found.
+	 */
+
+	Namespace *dummy1NsPtr, *dummy2NsPtr;
+
+	pattern = TclGetString(objv[1]);
+	TclGetNamespaceForQualName(interp, pattern, NULL, 0, &nsPtr,
+		&dummy1NsPtr, &dummy2NsPtr, &simplePattern);
+
+	if (nsPtr != NULL) {	/* We successfully found the pattern's ns. */
+	    specificNsInPattern = (strcmp(simplePattern, pattern) != 0);
+	}
+    } else {
+	Tcl_WrongNumArgs(interp, 1, objv, "?pattern?");
+	return TCL_ERROR;
+    }
+
+    /*
+     * Exit as quickly as possible if we couldn't find the namespace.
+     */
+
+    if (nsPtr == NULL) {
+	return TCL_OK;
+    }
+
+    /*
+     * Scan through the effective namespace's command table and create a list
+     * with all commands that match the pattern. If a specific namespace was
+     * requested in the pattern, qualify the command names with the namespace
+     * name.
+     */
+
+    listPtr = Tcl_NewListObj(0, NULL);
+
+    if (simplePattern != NULL && TclMatchIsTrivial(simplePattern)) {
+	/*
+	 * Special case for when the pattern doesn't include any of glob's
+	 * special characters. This lets us avoid scans of any hash tables.
+	 */
+
+	entryPtr = Tcl_FindHashEntry(&nsPtr->cmdTable, simplePattern);
+	if (entryPtr != NULL) {
+	    if (specificNsInPattern) {
+		cmd = Tcl_GetHashValue(entryPtr);
+		elemObjPtr = Tcl_NewObj();
+		Tcl_GetCommandFullName(interp, cmd, elemObjPtr);
+	    } else {
+		cmdName = Tcl_GetHashKey(&nsPtr->cmdTable, entryPtr);
+		elemObjPtr = Tcl_NewStringObj(cmdName, -1);
+	    }
+	    Tcl_ListObjAppendElement(interp, listPtr, elemObjPtr);
+	    Tcl_SetObjResult(interp, listPtr);
+	    return TCL_OK;
+	}
+	if ((nsPtr != globalNsPtr) && !specificNsInPattern) {
+	    Tcl_HashTable *tablePtr = NULL;	/* Quell warning. */
+
+	    for (i=0 ; i<nsPtr->commandPathLength ; i++) {
+		Namespace *pathNsPtr = nsPtr->commandPathArray[i].nsPtr;
+
+		if (pathNsPtr == NULL) {
+		    continue;
+		}
+		tablePtr = &pathNsPtr->cmdTable;
+		entryPtr = Tcl_FindHashEntry(tablePtr, simplePattern);
+		if (entryPtr != NULL) {
+		    break;
+		}
+	    }
+	    if (entryPtr == NULL) {
+		tablePtr = &globalNsPtr->cmdTable;
+		entryPtr = Tcl_FindHashEntry(tablePtr, simplePattern);
+	    }
+	    if (entryPtr != NULL) {
+		cmdName = Tcl_GetHashKey(tablePtr, entryPtr);
+		Tcl_ListObjAppendElement(interp, listPtr,
+			Tcl_NewStringObj(cmdName, -1));
+		Tcl_SetObjResult(interp, listPtr);
+		return TCL_OK;
+	    }
+	}
+    } else if (nsPtr->commandPathLength == 0 || specificNsInPattern) {
+	/*
+	 * The pattern is non-trivial, but either there is no explicit path or
+	 * there is an explicit namespace in the pattern. In both cases, the
+	 * old matching scheme is perfect.
+	 */
+
+	entryPtr = Tcl_FirstHashEntry(&nsPtr->cmdTable, &search);
+	while (entryPtr != NULL) {
+	    cmdName = Tcl_GetHashKey(&nsPtr->cmdTable, entryPtr);
+	    if ((simplePattern == NULL)
+		    || Tcl_StringMatch(cmdName, simplePattern)) {
+		if (specificNsInPattern) {
+		    cmd = Tcl_GetHashValue(entryPtr);
+		    elemObjPtr = Tcl_NewObj();
+		    Tcl_GetCommandFullName(interp, cmd, elemObjPtr);
+		} else {
+		    elemObjPtr = Tcl_NewStringObj(cmdName, -1);
+		}
+		Tcl_ListObjAppendElement(interp, listPtr, elemObjPtr);
+	    }
+	    entryPtr = Tcl_NextHashEntry(&search);
+	}
+
+	/*
+	 * If the effective namespace isn't the global :: namespace, and a
+	 * specific namespace wasn't requested in the pattern, then add in all
+	 * global :: commands that match the simple pattern. Of course, we add
+	 * in only those commands that aren't hidden by a command in the
+	 * effective namespace.
+	 */
+
+	if ((nsPtr != globalNsPtr) && !specificNsInPattern) {
+	    entryPtr = Tcl_FirstHashEntry(&globalNsPtr->cmdTable, &search);
+	    while (entryPtr != NULL) {
+		cmdName = Tcl_GetHashKey(&globalNsPtr->cmdTable, entryPtr);
+		if ((simplePattern == NULL)
+			|| Tcl_StringMatch(cmdName, simplePattern)) {
+		    if (Tcl_FindHashEntry(&nsPtr->cmdTable,cmdName) == NULL) {
+			Tcl_ListObjAppendElement(interp, listPtr,
+				Tcl_NewStringObj(cmdName, -1));
+		    }
+		}
+		entryPtr = Tcl_NextHashEntry(&search);
+	    }
+	}
+    } else {
+	/*
+	 * The pattern is non-trivial (can match more than one command name),
+	 * there is an explicit path, and there is no explicit namespace in
+	 * the pattern. This means that we have to traverse the path to
+	 * discover all the commands defined.
+	 */
+
+	Tcl_HashTable addedCommandsTable;
+	int isNew;
+	int foundGlobal = (nsPtr == globalNsPtr);
+
+	/*
+	 * We keep a hash of the objects already added to the result list.
+	 */
+
+	Tcl_InitObjHashTable(&addedCommandsTable);
+
+	entryPtr = Tcl_FirstHashEntry(&nsPtr->cmdTable, &search);
+	while (entryPtr != NULL) {
+	    cmdName = Tcl_GetHashKey(&nsPtr->cmdTable, entryPtr);
+	    if ((simplePattern == NULL)
+		    || Tcl_StringMatch(cmdName, simplePattern)) {
+		elemObjPtr = Tcl_NewStringObj(cmdName, -1);
+		Tcl_ListObjAppendElement(interp, listPtr, elemObjPtr);
+		(void) Tcl_CreateHashEntry(&addedCommandsTable,
+			elemObjPtr, &isNew);
+	    }
+	    entryPtr = Tcl_NextHashEntry(&search);
+	}
+
+	/*
+	 * Search the path next.
+	 */
+
+	for (i=0 ; i<nsPtr->commandPathLength ; i++) {
+	    Namespace *pathNsPtr = nsPtr->commandPathArray[i].nsPtr;
+
+	    if (pathNsPtr == NULL) {
+		continue;
+	    }
+	    if (pathNsPtr == globalNsPtr) {
+		foundGlobal = 1;
+	    }
+	    entryPtr = Tcl_FirstHashEntry(&pathNsPtr->cmdTable, &search);
+	    while (entryPtr != NULL) {
+		cmdName = Tcl_GetHashKey(&pathNsPtr->cmdTable, entryPtr);
+		if ((simplePattern == NULL)
+			|| Tcl_StringMatch(cmdName, simplePattern)) {
+		    elemObjPtr = Tcl_NewStringObj(cmdName, -1);
+		    (void) Tcl_CreateHashEntry(&addedCommandsTable,
+			    elemObjPtr, &isNew);
+		    if (isNew) {
+			Tcl_ListObjAppendElement(interp, listPtr, elemObjPtr);
+		    } else {
+			TclDecrRefCount(elemObjPtr);
+		    }
+		}
+		entryPtr = Tcl_NextHashEntry(&search);
+	    }
+	}
+
+	/*
+	 * If the effective namespace isn't the global :: namespace, and a
+	 * specific namespace wasn't requested in the pattern, then add in all
+	 * global :: commands that match the simple pattern. Of course, we add
+	 * in only those commands that aren't hidden by a command in the
+	 * effective namespace.
+	 */
+
+	if (!foundGlobal) {
+	    entryPtr = Tcl_FirstHashEntry(&globalNsPtr->cmdTable, &search);
+	    while (entryPtr != NULL) {
+		cmdName = Tcl_GetHashKey(&globalNsPtr->cmdTable, entryPtr);
+		if ((simplePattern == NULL)
+			|| Tcl_StringMatch(cmdName, simplePattern)) {
+		    elemObjPtr = Tcl_NewStringObj(cmdName, -1);
+		    if (Tcl_FindHashEntry(&addedCommandsTable,
+			    (char *) elemObjPtr) == NULL) {
+			Tcl_ListObjAppendElement(interp, listPtr, elemObjPtr);
+		    } else {
+			TclDecrRefCount(elemObjPtr);
+		    }
+		}
+		entryPtr = Tcl_NextHashEntry(&search);
+	    }
+	}
+
+	Tcl_DeleteHashTable(&addedCommandsTable);
+    }
+
+    Tcl_SetObjResult(interp, listPtr);
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * InfoCompleteCmd --
+ *
+ *	Called to implement the "info complete" command that determines
+ *	whether a string is a complete Tcl command. Handles the following
+ *	syntax:
+ *
+ *	    info complete command
+ *
+ * Results:
+ *	Returns TCL_OK if successful and TCL_ERROR if there is an error.
+ *
+ * Side effects:
+ *	Returns a result in the interpreter's result object. If there is an
+ *	error, the result is an error message.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+InfoCompleteCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    if (objc != 2) {
+	Tcl_WrongNumArgs(interp, 1, objv, "command");
+	return TCL_ERROR;
+    }
+
+    Tcl_SetObjResult(interp, Tcl_NewBooleanObj(
+	    TclObjCommandComplete(objv[1])));
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * InfoDefaultCmd --
+ *
+ *	Called to implement the "info default" command that returns the
+ *	default value for a procedure argument. Handles the following syntax:
+ *
+ *	    info default procName arg varName
+ *
+ * Results:
+ *	Returns TCL_OK if successful and TCL_ERROR if there is an error.
+ *
+ * Side effects:
+ *	Returns a result in the interpreter's result object. If there is an
+ *	error, the result is an error message.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+InfoDefaultCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    Interp *iPtr = (Interp *) interp;
+    const char *procName, *argName;
+    Proc *procPtr;
+    CompiledLocal *localPtr;
+    Tcl_Obj *valueObjPtr;
+
+    if (objc != 4) {
+	Tcl_WrongNumArgs(interp, 1, objv, "procname arg varname");
+	return TCL_ERROR;
+    }
+
+    procName = TclGetString(objv[1]);
+    argName = TclGetString(objv[2]);
+
+    procPtr = TclFindProc(iPtr, procName);
+    if (procPtr == NULL) {
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		"\"%s\" isn't a procedure", procName));
+	Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "PROCEDURE", procName,
+		NULL);
+	return TCL_ERROR;
+    }
+
+    for (localPtr = procPtr->firstLocalPtr;  localPtr != NULL;
+	    localPtr = localPtr->nextPtr) {
+	if (TclIsVarArgument(localPtr)
+		&& (strcmp(argName, localPtr->name) == 0)) {
+	    if (localPtr->defValuePtr != NULL) {
+		valueObjPtr = Tcl_ObjSetVar2(interp, objv[3], NULL,
+			localPtr->defValuePtr, TCL_LEAVE_ERR_MSG);
+		if (valueObjPtr == NULL) {
+		    return TCL_ERROR;
+		}
+		Tcl_SetObjResult(interp, Tcl_NewIntObj(1));
+	    } else {
+		Tcl_Obj *nullObjPtr = Tcl_NewObj();
+
+		valueObjPtr = Tcl_ObjSetVar2(interp, objv[3], NULL,
+			nullObjPtr, TCL_LEAVE_ERR_MSG);
+		if (valueObjPtr == NULL) {
+		    return TCL_ERROR;
+		}
+		Tcl_SetObjResult(interp, Tcl_NewIntObj(0));
+	    }
+	    return TCL_OK;
+	}
+    }
+
+    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+	    "procedure \"%s\" doesn't have an argument \"%s\"",
+	    procName, argName));
+    Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "ARGUMENT", argName, NULL);
+    return TCL_ERROR;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * InfoErrorStackCmd --
+ *
+ *	Called to implement the "info errorstack" command that returns information
+ *	about the last error's call stack. Handles the following syntax:
+ *
+ *	    info errorstack ?interp?
+ *
+ * Results:
+ *	Returns TCL_OK if successful and TCL_ERROR if there is an error.
+ *
+ * Side effects:
+ *	Returns a result in the interpreter's result object. If there is an
+ *	error, the result is an error message.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+InfoErrorStackCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    Tcl_Interp *target;
+    Interp *iPtr;
+
+    if ((objc != 1) && (objc != 2)) {
+	Tcl_WrongNumArgs(interp, 1, objv, "?interp?");
+	return TCL_ERROR;
+    }
+
+    target = interp;
+    if (objc == 2) {
+	target = Tcl_GetSlave(interp, Tcl_GetString(objv[1]));
+	if (target == NULL) {
+	    return TCL_ERROR;
+	}
+    }
+
+    iPtr = (Interp *) target;
+    Tcl_SetObjResult(interp, iPtr->errorStack);
+
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclInfoExistsCmd --
+ *
+ *	Called to implement the "info exists" command that determines whether
+ *	a variable exists. Handles the following syntax:
+ *
+ *	    info exists varName
+ *
+ * Results:
+ *	Returns TCL_OK if successful and TCL_ERROR if there is an error.
+ *
+ * Side effects:
+ *	Returns a result in the interpreter's result object. If there is an
+ *	error, the result is an error message.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclInfoExistsCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    const char *varName;
+    Var *varPtr;
+
+    if (objc != 2) {
+	Tcl_WrongNumArgs(interp, 1, objv, "varName");
+	return TCL_ERROR;
+    }
+
+    varName = TclGetString(objv[1]);
+    varPtr = TclVarTraceExists(interp, varName);
+
+    Tcl_SetObjResult(interp,
+	    Tcl_NewBooleanObj(varPtr && varPtr->value.objPtr));
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * InfoFrameCmd --
+ *	TIP #280
+ *
+ *	Called to implement the "info frame" command that returns the location
+ *	of either the currently executing command, or its caller. Handles the
+ *	following syntax:
+ *
+ *		info frame ?number?
+ *
+ * Results:
+ *	Returns TCL_OK if successful and TCL_ERROR if there is an error.
+ *
+ * Side effects:
+ *	Returns a result in the interpreter's result object. If there is an
+ *	error, the result is an error message.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+InfoFrameCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    Interp *iPtr = (Interp *) interp;
+    int level, code = TCL_OK;
+    CmdFrame *framePtr, **cmdFramePtrPtr = &iPtr->cmdFramePtr;
+    CoroutineData *corPtr = iPtr->execEnvPtr->corPtr;
+    int topLevel = 0;
+
+    if (objc > 2) {
+	Tcl_WrongNumArgs(interp, 1, objv, "?number?");
+	return TCL_ERROR;
+    }
+
+    while (corPtr) {
+	while (*cmdFramePtrPtr) {
+	    topLevel++;
+	    cmdFramePtrPtr = &((*cmdFramePtrPtr)->nextPtr);
+	}
+	if (corPtr->caller.cmdFramePtr) {
+	    *cmdFramePtrPtr = corPtr->caller.cmdFramePtr;
+	}
+	corPtr = corPtr->callerEEPtr->corPtr;
+    }
+    topLevel += (*cmdFramePtrPtr)->level;
+
+    if (topLevel != iPtr->cmdFramePtr->level) {
+	framePtr = iPtr->cmdFramePtr;
+	while (framePtr) {
+	    framePtr->level = topLevel--;
+	    framePtr = framePtr->nextPtr;
+	}
+	if (topLevel) {
+	    Tcl_Panic("Broken frame level calculation");
+	}
+	topLevel = iPtr->cmdFramePtr->level;
+    }
+
+    if (objc == 1) {
+	/*
+	 * Just "info frame".
+	 */
+
+	Tcl_SetObjResult(interp, Tcl_NewIntObj(topLevel));
+	goto done;
+    }
+
+    /*
+     * We've got "info frame level" and must parse the level first.
+     */
+
+    if (TclGetIntFromObj(interp, objv[1], &level) != TCL_OK) {
+	code = TCL_ERROR;
+	goto done;
+    }
+
+    if ((level > topLevel) || (level <= - topLevel)) {
+    levelError:
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		"bad level \"%s\"", TclGetString(objv[1])));
+	Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "LEVEL",
+		TclGetString(objv[1]), NULL);
+	code = TCL_ERROR;
+	goto done;
+    }
+
+    /*
+     * Let us convert to relative so that we know how many levels to go back
+     */
+
+    if (level > 0) {
+	level -= topLevel;
+    }
+
+    framePtr = iPtr->cmdFramePtr;
+    while (++level <= 0) {
+	framePtr = framePtr->nextPtr;
+	if (!framePtr) {
+	    goto levelError;
+	}
+    }
+
+    Tcl_SetObjResult(interp, TclInfoFrame(interp, framePtr));
+
+  done:
+    cmdFramePtrPtr = &iPtr->cmdFramePtr;
+    corPtr = iPtr->execEnvPtr->corPtr;
+    while (corPtr) {
+	CmdFrame *endPtr = corPtr->caller.cmdFramePtr;
+
+	if (endPtr) {
+	    if (*cmdFramePtrPtr == endPtr) {
+		*cmdFramePtrPtr = NULL;
+	    } else {
+		CmdFrame *runPtr = *cmdFramePtrPtr;
+
+		while (runPtr->nextPtr != endPtr) {
+		    runPtr->level -= endPtr->level;
+		    runPtr = runPtr->nextPtr;
+		}
+		runPtr->level = 1;
+		runPtr->nextPtr = NULL;
+	    }
+	    cmdFramePtrPtr = &corPtr->caller.cmdFramePtr;
+	}
+	corPtr = corPtr->callerEEPtr->corPtr;
+    }
+    return code;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclInfoFrame --
+ *
+ *	Core of InfoFrameCmd, returns TIP280 dict for a given frame.
+ *
+ * Results:
+ *	Returns TIP280 dict.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_Obj *
+TclInfoFrame(
+    Tcl_Interp *interp,		/* Current interpreter. */
+    CmdFrame *framePtr)		/* Frame to get info for. */
+{
+    Interp *iPtr = (Interp *) interp;
+    Tcl_Obj *tmpObj;
+    Tcl_Obj *lv[20];		/* Keep uptodate when more keys are added to
+				 * the dict. */
+    int lc = 0;
+    /*
+     * This array is indexed by the TCL_LOCATION_... values, except
+     * for _LAST.
+     */
+    static const char *const typeString[TCL_LOCATION_LAST] = {
+	"eval", "eval", "eval", "precompiled", "source", "proc"
+    };
+    Proc *procPtr = framePtr->framePtr ? framePtr->framePtr->procPtr : NULL;
+    int needsFree = -1;
+
+    /*
+     * Pull the information and construct the dictionary to return, as list.
+     * Regarding use of the CmdFrame fields see tclInt.h, and its definition.
+     */
+
+#define ADD_PAIR(name, value) \
+	TclNewLiteralStringObj(tmpObj, name); \
+	lv[lc++] = tmpObj; \
+	lv[lc++] = (value)
+
+    switch (framePtr->type) {
+    case TCL_LOCATION_EVAL:
+	/*
+	 * Evaluation, dynamic script. Type, line, cmd, the latter through
+	 * str.
+	 */
+
+	ADD_PAIR("type", Tcl_NewStringObj(typeString[framePtr->type], -1));
+	if (framePtr->line) {
+	    ADD_PAIR("line", Tcl_NewIntObj(framePtr->line[0]));
+	} else {
+	    ADD_PAIR("line", Tcl_NewIntObj(1));
+	}
+	ADD_PAIR("cmd", TclGetSourceFromFrame(framePtr, 0, NULL));
+	break;
+
+    case TCL_LOCATION_PREBC:
+	/*
+	 * Precompiled. Result contains the type as signal, nothing else.
+	 */
+
+	ADD_PAIR("type", Tcl_NewStringObj(typeString[framePtr->type], -1));
+	break;
+
+    case TCL_LOCATION_BC: {
+	/*
+	 * Execution of bytecode. Talk to the BC engine to fill out the frame.
+	 */
+
+	CmdFrame *fPtr = TclStackAlloc(interp, sizeof(CmdFrame));
+
+	*fPtr = *framePtr;
+
+	/*
+	 * Note:
+	 * Type BC => f.data.eval.path	  is not used.
+	 *	      f.data.tebc.codePtr is used instead.
+	 */
+
+	TclGetSrcInfoForPc(fPtr);
+
+	/*
+	 * Now filled: cmd.str.(cmd,len), line
+	 * Possibly modified: type, path!
+	 */
+
+	ADD_PAIR("type", Tcl_NewStringObj(typeString[fPtr->type], -1));
+	if (fPtr->line) {
+	    ADD_PAIR("line", Tcl_NewIntObj(fPtr->line[0]));
+	}
+
+	if (fPtr->type == TCL_LOCATION_SOURCE) {
+	    ADD_PAIR("file", fPtr->data.eval.path);
+
+	    /*
+	     * Death of reference by TclGetSrcInfoForPc.
+	     */
+
+	    Tcl_DecrRefCount(fPtr->data.eval.path);
+	}
+
+	ADD_PAIR("cmd", TclGetSourceFromFrame(fPtr, 0, NULL));
+	if (fPtr->cmdObj && framePtr->cmdObj == NULL) {
+	    needsFree = lc - 1;
+	}
+	TclStackFree(interp, fPtr);
+	break;
+    }
+
+    case TCL_LOCATION_SOURCE:
+	/*
+	 * Evaluation of a script file.
+	 */
+
+	ADD_PAIR("type", Tcl_NewStringObj(typeString[framePtr->type], -1));
+	ADD_PAIR("line", Tcl_NewIntObj(framePtr->line[0]));
+	ADD_PAIR("file", framePtr->data.eval.path);
+
+	/*
+	 * Refcount framePtr->data.eval.path goes up when lv is converted into
+	 * the result list object.
+	 */
+
+	ADD_PAIR("cmd", TclGetSourceFromFrame(framePtr, 0, NULL));
+	break;
+
+    case TCL_LOCATION_PROC:
+	Tcl_Panic("TCL_LOCATION_PROC found in standard frame");
+	break;
+    }
+
+    /*
+     * 'proc'. Common to all frame types. Conditional on having an associated
+     * Procedure CallFrame.
+     */
+
+    if (procPtr != NULL) {
+	Tcl_HashEntry *namePtr = procPtr->cmdPtr->hPtr;
+
+	if (namePtr) {
+	    Tcl_Obj *procNameObj;
+
+	    /*
+	     * This is a regular command.
+	     */
+
+	    TclNewObj(procNameObj);
+	    Tcl_GetCommandFullName(interp, (Tcl_Command) procPtr->cmdPtr,
+		    procNameObj);
+	    ADD_PAIR("proc", procNameObj);
+	} else if (procPtr->cmdPtr->clientData) {
+	    ExtraFrameInfo *efiPtr = procPtr->cmdPtr->clientData;
+	    int i;
+
+	    /*
+	     * This is a non-standard command. Luckily, it's told us how to
+	     * render extra information about its frame.
+	     */
+
+	    for (i=0 ; i<efiPtr->length ; i++) {
+		lv[lc++] = Tcl_NewStringObj(efiPtr->fields[i].name, -1);
+		if (efiPtr->fields[i].proc) {
+		    lv[lc++] =
+			efiPtr->fields[i].proc(efiPtr->fields[i].clientData);
+		} else {
+		    lv[lc++] = efiPtr->fields[i].clientData;
+		}
+	    }
+	}
+    }
+
+    /*
+     * 'level'. Common to all frame types. Conditional on having an associated
+     * _visible_ CallFrame.
+     */
+
+    if ((framePtr->framePtr != NULL) && (iPtr->varFramePtr != NULL)) {
+	CallFrame *current = framePtr->framePtr;
+	CallFrame *top = iPtr->varFramePtr;
+	CallFrame *idx;
+
+	for (idx=top ; idx!=NULL ; idx=idx->callerVarPtr) {
+	    if (idx == current) {
+		int c = framePtr->framePtr->level;
+		int t = iPtr->varFramePtr->level;
+
+		ADD_PAIR("level", Tcl_NewIntObj(t - c));
+		break;
+	    }
+	}
+    }
+
+    tmpObj = Tcl_NewListObj(lc, lv);
+    if (needsFree >= 0) {
+	Tcl_DecrRefCount(lv[needsFree]);
+    }
+    return tmpObj;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * InfoFunctionsCmd --
+ *
+ *	Called to implement the "info functions" command that returns the list
+ *	of math functions matching an optional pattern. Handles the following
+ *	syntax:
+ *
+ *	    info functions ?pattern?
+ *
+ * Results:
+ *	Returns TCL_OK if successful and TCL_ERROR if there is an error.
+ *
+ * Side effects:
+ *	Returns a result in the interpreter's result object. If there is an
+ *	error, the result is an error message.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+InfoFunctionsCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    Tcl_Obj *script;
+    int code;
+
+    if (objc > 2) {
+	Tcl_WrongNumArgs(interp, 1, objv, "?pattern?");
+	return TCL_ERROR;
+    }
+
+    script = Tcl_NewStringObj(
+"	    ::apply [::list {{pattern *}} {\n"
+"		::set cmds {}\n"
+"		::foreach cmd [::info commands ::tcl::mathfunc::$pattern] {\n"
+"		    ::lappend cmds [::namespace tail $cmd]\n"
+"		}\n"
+"		::foreach cmd [::info commands tcl::mathfunc::$pattern] {\n"
+"		    ::set cmd [::namespace tail $cmd]\n"
+"		    ::if {$cmd ni $cmds} {\n"
+"			::lappend cmds $cmd\n"
+"		    }\n"
+"		}\n"
+"		::return $cmds\n"
+"	    } [::namespace current]] ", -1);
+
+    if (objc == 2) {
+	Tcl_Obj *arg = Tcl_NewListObj(1, &(objv[1]));
+
+	Tcl_AppendObjToObj(script, arg);
+	Tcl_DecrRefCount(arg);
+    }
+
+    Tcl_IncrRefCount(script);
+    code = Tcl_EvalObjEx(interp, script, 0);
+
+    Tcl_DecrRefCount(script);
+
+    return code;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * InfoHostnameCmd --
+ *
+ *	Called to implement the "info hostname" command that returns the host
+ *	name. Handles the following syntax:
+ *
+ *	    info hostname
+ *
+ * Results:
+ *	Returns TCL_OK if successful and TCL_ERROR if there is an error.
+ *
+ * Side effects:
+ *	Returns a result in the interpreter's result object. If there is an
+ *	error, the result is an error message.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+InfoHostnameCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    const char *name;
+
+    if (objc != 1) {
+	Tcl_WrongNumArgs(interp, 1, objv, NULL);
+	return TCL_ERROR;
+    }
+
+    name = Tcl_GetHostName();
+    if (name) {
+	Tcl_SetObjResult(interp, Tcl_NewStringObj(name, -1));
+	return TCL_OK;
+    }
+
+    Tcl_SetObjResult(interp, Tcl_NewStringObj(
+	    "unable to determine name of host", -1));
+    Tcl_SetErrorCode(interp, "TCL", "OPERATION", "HOSTNAME", "UNKNOWN", NULL);
+    return TCL_ERROR;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * InfoLevelCmd --
+ *
+ *	Called to implement the "info level" command that returns information
+ *	about the call stack. Handles the following syntax:
+ *
+ *	    info level ?number?
+ *
+ * Results:
+ *	Returns TCL_OK if successful and TCL_ERROR if there is an error.
+ *
+ * Side effects:
+ *	Returns a result in the interpreter's result object. If there is an
+ *	error, the result is an error message.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+InfoLevelCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    Interp *iPtr = (Interp *) interp;
+
+    if (objc == 1) {		/* Just "info level" */
+	Tcl_SetObjResult(interp, Tcl_NewIntObj(iPtr->varFramePtr->level));
+	return TCL_OK;
+    }
+
+    if (objc == 2) {
+	int level;
+	CallFrame *framePtr, *rootFramePtr = iPtr->rootFramePtr;
+
+	if (TclGetIntFromObj(interp, objv[1], &level) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	if (level <= 0) {
+	    if (iPtr->varFramePtr == rootFramePtr) {
+		goto levelError;
+	    }
+	    level += iPtr->varFramePtr->level;
+	}
+	for (framePtr=iPtr->varFramePtr ; framePtr!=rootFramePtr;
+		framePtr=framePtr->callerVarPtr) {
+	    if (framePtr->level == level) {
+		break;
+	    }
+	}
+	if (framePtr == rootFramePtr) {
+	    goto levelError;
+	}
+
+	Tcl_SetObjResult(interp,
+		Tcl_NewListObj(framePtr->objc, framePtr->objv));
+	return TCL_OK;
+    }
+
+    Tcl_WrongNumArgs(interp, 1, objv, "?number?");
+    return TCL_ERROR;
+
+  levelError:
+    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+	    "bad level \"%s\"", TclGetString(objv[1])));
+    Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "LEVEL",
+	    TclGetString(objv[1]), NULL);
+    return TCL_ERROR;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * InfoLibraryCmd --
+ *
+ *	Called to implement the "info library" command that returns the
+ *	library directory for the Tcl installation. Handles the following
+ *	syntax:
+ *
+ *	    info library
+ *
+ * Results:
+ *	Returns TCL_OK if successful and TCL_ERROR if there is an error.
+ *
+ * Side effects:
+ *	Returns a result in the interpreter's result object. If there is an
+ *	error, the result is an error message.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+InfoLibraryCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    const char *libDirName;
+
+    if (objc != 1) {
+	Tcl_WrongNumArgs(interp, 1, objv, NULL);
+	return TCL_ERROR;
+    }
+
+    libDirName = Tcl_GetVar(interp, "tcl_library", TCL_GLOBAL_ONLY);
+    if (libDirName != NULL) {
+	Tcl_SetObjResult(interp, Tcl_NewStringObj(libDirName, -1));
+	return TCL_OK;
+    }
+
+    Tcl_SetObjResult(interp, Tcl_NewStringObj(
+	    "no library has been specified for Tcl", -1));
+    Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "VARIABLE", "tcl_library",NULL);
+    return TCL_ERROR;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * InfoLoadedCmd --
+ *
+ *	Called to implement the "info loaded" command that returns the
+ *	packages that have been loaded into an interpreter. Handles the
+ *	following syntax:
+ *
+ *	    info loaded ?interp?
+ *
+ * Results:
+ *	Returns TCL_OK if successful and TCL_ERROR if there is an error.
+ *
+ * Side effects:
+ *	Returns a result in the interpreter's result object. If there is an
+ *	error, the result is an error message.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+InfoLoadedCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    const char *interpName;
+
+    if ((objc != 1) && (objc != 2)) {
+	Tcl_WrongNumArgs(interp, 1, objv, "?interp?");
+	return TCL_ERROR;
+    }
+
+    if (objc == 1) {		/* Get loaded pkgs in all interpreters. */
+	interpName = NULL;
+    } else {			/* Get pkgs just in specified interp. */
+	interpName = TclGetString(objv[1]);
+    }
+    return TclGetLoadedPackages(interp, interpName);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * InfoNameOfExecutableCmd --
+ *
+ *	Called to implement the "info nameofexecutable" command that returns
+ *	the name of the binary file running this application. Handles the
+ *	following syntax:
+ *
+ *	    info nameofexecutable
+ *
+ * Results:
+ *	Returns TCL_OK if successful and TCL_ERROR if there is an error.
+ *
+ * Side effects:
+ *	Returns a result in the interpreter's result object. If there is an
+ *	error, the result is an error message.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+InfoNameOfExecutableCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    if (objc != 1) {
+	Tcl_WrongNumArgs(interp, 1, objv, NULL);
+	return TCL_ERROR;
+    }
+    Tcl_SetObjResult(interp, TclGetObjNameOfExecutable());
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * InfoPatchLevelCmd --
+ *
+ *	Called to implement the "info patchlevel" command that returns the
+ *	default value for an argument to a procedure. Handles the following
+ *	syntax:
+ *
+ *	    info patchlevel
+ *
+ * Results:
+ *	Returns TCL_OK if successful and TCL_ERROR if there is an error.
+ *
+ * Side effects:
+ *	Returns a result in the interpreter's result object. If there is an
+ *	error, the result is an error message.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+InfoPatchLevelCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    const char *patchlevel;
+
+    if (objc != 1) {
+	Tcl_WrongNumArgs(interp, 1, objv, NULL);
+	return TCL_ERROR;
+    }
+
+    patchlevel = Tcl_GetVar(interp, "tcl_patchLevel",
+	    (TCL_GLOBAL_ONLY | TCL_LEAVE_ERR_MSG));
+    if (patchlevel != NULL) {
+	Tcl_SetObjResult(interp, Tcl_NewStringObj(patchlevel, -1));
+	return TCL_OK;
+    }
+    return TCL_ERROR;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * InfoProcsCmd --
+ *
+ *	Called to implement the "info procs" command that returns the list of
+ *	procedures in the interpreter that match an optional pattern. The
+ *	pattern, if any, consists of an optional sequence of namespace names
+ *	separated by "::" qualifiers, which is followed by a glob-style
+ *	pattern that restricts which commands are returned. Handles the
+ *	following syntax:
+ *
+ *	    info procs ?pattern?
+ *
+ * Results:
+ *	Returns TCL_OK if successful and TCL_ERROR if there is an error.
+ *
+ * Side effects:
+ *	Returns a result in the interpreter's result object. If there is an
+ *	error, the result is an error message.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+InfoProcsCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    const char *cmdName, *pattern;
+    const char *simplePattern;
+    Namespace *nsPtr;
+#ifdef INFO_PROCS_SEARCH_GLOBAL_NS
+    Namespace *globalNsPtr = (Namespace *) Tcl_GetGlobalNamespace(interp);
+#endif
+    Namespace *currNsPtr = (Namespace *) Tcl_GetCurrentNamespace(interp);
+    Tcl_Obj *listPtr, *elemObjPtr;
+    int specificNsInPattern = 0;/* Init. to avoid compiler warning. */
+    register Tcl_HashEntry *entryPtr;
+    Tcl_HashSearch search;
+    Command *cmdPtr, *realCmdPtr;
+
+    /*
+     * Get the pattern and find the "effective namespace" in which to list
+     * procs.
+     */
+
+    if (objc == 1) {
+	simplePattern = NULL;
+	nsPtr = currNsPtr;
+	specificNsInPattern = 0;
+    } else if (objc == 2) {
+	/*
+	 * From the pattern, get the effective namespace and the simple
+	 * pattern (no namespace qualifiers or ::'s) at the end. If an error
+	 * was found while parsing the pattern, return it. Otherwise, if the
+	 * namespace wasn't found, just leave nsPtr NULL: we will return an
+	 * empty list since no commands there can be found.
+	 */
+
+	Namespace *dummy1NsPtr, *dummy2NsPtr;
+
+	pattern = TclGetString(objv[1]);
+	TclGetNamespaceForQualName(interp, pattern, NULL, /*flags*/ 0, &nsPtr,
+		&dummy1NsPtr, &dummy2NsPtr, &simplePattern);
+
+	if (nsPtr != NULL) {	/* We successfully found the pattern's ns. */
+	    specificNsInPattern = (strcmp(simplePattern, pattern) != 0);
+	}
+    } else {
+	Tcl_WrongNumArgs(interp, 1, objv, "?pattern?");
+	return TCL_ERROR;
+    }
+
+    if (nsPtr == NULL) {
+	return TCL_OK;
+    }
+
+    /*
+     * Scan through the effective namespace's command table and create a list
+     * with all procs that match the pattern. If a specific namespace was
+     * requested in the pattern, qualify the command names with the namespace
+     * name.
+     */
+
+    listPtr = Tcl_NewListObj(0, NULL);
+#ifndef INFO_PROCS_SEARCH_GLOBAL_NS
+    if (simplePattern != NULL && TclMatchIsTrivial(simplePattern)) {
+	entryPtr = Tcl_FindHashEntry(&nsPtr->cmdTable, simplePattern);
+	if (entryPtr != NULL) {
+	    cmdPtr = Tcl_GetHashValue(entryPtr);
+
+	    if (!TclIsProc(cmdPtr)) {
+		realCmdPtr = (Command *)
+			TclGetOriginalCommand((Tcl_Command) cmdPtr);
+		if (realCmdPtr != NULL && TclIsProc(realCmdPtr)) {
+		    goto simpleProcOK;
+		}
+	    } else {
+	    simpleProcOK:
+		if (specificNsInPattern) {
+		    elemObjPtr = Tcl_NewObj();
+		    Tcl_GetCommandFullName(interp, (Tcl_Command) cmdPtr,
+			    elemObjPtr);
+		} else {
+		    elemObjPtr = Tcl_NewStringObj(simplePattern, -1);
+		}
+		Tcl_ListObjAppendElement(interp, listPtr, elemObjPtr);
+	    }
+	}
+    } else
+#endif /* !INFO_PROCS_SEARCH_GLOBAL_NS */
+    {
+	entryPtr = Tcl_FirstHashEntry(&nsPtr->cmdTable, &search);
+	while (entryPtr != NULL) {
+	    cmdName = Tcl_GetHashKey(&nsPtr->cmdTable, entryPtr);
+	    if ((simplePattern == NULL)
+		    || Tcl_StringMatch(cmdName, simplePattern)) {
+		cmdPtr = Tcl_GetHashValue(entryPtr);
+
+		if (!TclIsProc(cmdPtr)) {
+		    realCmdPtr = (Command *)
+			    TclGetOriginalCommand((Tcl_Command) cmdPtr);
+		    if (realCmdPtr != NULL && TclIsProc(realCmdPtr)) {
+			goto procOK;
+		    }
+		} else {
+		procOK:
+		    if (specificNsInPattern) {
+			elemObjPtr = Tcl_NewObj();
+			Tcl_GetCommandFullName(interp, (Tcl_Command) cmdPtr,
+				elemObjPtr);
+		    } else {
+			elemObjPtr = Tcl_NewStringObj(cmdName, -1);
+		    }
+		    Tcl_ListObjAppendElement(interp, listPtr, elemObjPtr);
+		}
+	    }
+	    entryPtr = Tcl_NextHashEntry(&search);
+	}
+
+	/*
+	 * If the effective namespace isn't the global :: namespace, and a
+	 * specific namespace wasn't requested in the pattern, then add in all
+	 * global :: procs that match the simple pattern. Of course, we add in
+	 * only those procs that aren't hidden by a proc in the effective
+	 * namespace.
+	 */
+
+#ifdef INFO_PROCS_SEARCH_GLOBAL_NS
+	/*
+	 * If "info procs" worked like "info commands", returning the commands
+	 * also seen in the global namespace, then you would include this
+	 * code. As this could break backwards compatibilty with 8.0-8.2, we
+	 * decided not to "fix" it in 8.3, leaving the behavior slightly
+	 * different.
+	 */
+
+	if ((nsPtr != globalNsPtr) && !specificNsInPattern) {
+	    entryPtr = Tcl_FirstHashEntry(&globalNsPtr->cmdTable, &search);
+	    while (entryPtr != NULL) {
+		cmdName = Tcl_GetHashKey(&globalNsPtr->cmdTable, entryPtr);
+		if ((simplePattern == NULL)
+			|| Tcl_StringMatch(cmdName, simplePattern)) {
+		    if (Tcl_FindHashEntry(&nsPtr->cmdTable,cmdName) == NULL) {
+			cmdPtr = Tcl_GetHashValue(entryPtr);
+			realCmdPtr = (Command *) TclGetOriginalCommand(
+				(Tcl_Command) cmdPtr);
+
+			if (TclIsProc(cmdPtr) || ((realCmdPtr != NULL)
+				&& TclIsProc(realCmdPtr))) {
+			    Tcl_ListObjAppendElement(interp, listPtr,
+				    Tcl_NewStringObj(cmdName, -1));
+			}
+		    }
+		}
+		entryPtr = Tcl_NextHashEntry(&search);
+	    }
+	}
+#endif
+    }
+
+    Tcl_SetObjResult(interp, listPtr);
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * InfoScriptCmd --
+ *
+ *	Called to implement the "info script" command that returns the script
+ *	file that is currently being evaluated. Handles the following syntax:
+ *
+ *	    info script ?newName?
+ *
+ *	If newName is specified, it will set that as the internal name.
+ *
+ * Results:
+ *	Returns TCL_OK if successful and TCL_ERROR if there is an error.
+ *
+ * Side effects:
+ *	Returns a result in the interpreter's result object. If there is an
+ *	error, the result is an error message. It may change the internal
+ *	script filename.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+InfoScriptCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    Interp *iPtr = (Interp *) interp;
+    if ((objc != 1) && (objc != 2)) {
+	Tcl_WrongNumArgs(interp, 1, objv, "?filename?");
+	return TCL_ERROR;
+    }
+
+    if (objc == 2) {
+	if (iPtr->scriptFile != NULL) {
+	    Tcl_DecrRefCount(iPtr->scriptFile);
+	}
+	iPtr->scriptFile = objv[1];
+	Tcl_IncrRefCount(iPtr->scriptFile);
+    }
+    if (iPtr->scriptFile != NULL) {
+	Tcl_SetObjResult(interp, iPtr->scriptFile);
+    }
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * InfoSharedlibCmd --
+ *
+ *	Called to implement the "info sharedlibextension" command that returns
+ *	the file extension used for shared libraries. Handles the following
+ *	syntax:
+ *
+ *	    info sharedlibextension
+ *
+ * Results:
+ *	Returns TCL_OK if successful and TCL_ERROR if there is an error.
+ *
+ * Side effects:
+ *	Returns a result in the interpreter's result object. If there is an
+ *	error, the result is an error message.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+InfoSharedlibCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    if (objc != 1) {
+	Tcl_WrongNumArgs(interp, 1, objv, NULL);
+	return TCL_ERROR;
+    }
+
+#ifdef TCL_SHLIB_EXT
+    Tcl_SetObjResult(interp, Tcl_NewStringObj(TCL_SHLIB_EXT, -1));
+#endif
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * InfoTclVersionCmd --
+ *
+ *	Called to implement the "info tclversion" command that returns the
+ *	version number for this Tcl library. Handles the following syntax:
+ *
+ *	    info tclversion
+ *
+ * Results:
+ *	Returns TCL_OK if successful and TCL_ERROR if there is an error.
+ *
+ * Side effects:
+ *	Returns a result in the interpreter's result object. If there is an
+ *	error, the result is an error message.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+InfoTclVersionCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    Tcl_Obj *version;
+
+    if (objc != 1) {
+	Tcl_WrongNumArgs(interp, 1, objv, NULL);
+	return TCL_ERROR;
+    }
+
+    version = Tcl_GetVar2Ex(interp, "tcl_version", NULL,
+	    (TCL_GLOBAL_ONLY | TCL_LEAVE_ERR_MSG));
+    if (version != NULL) {
+	Tcl_SetObjResult(interp, version);
+	return TCL_OK;
+    }
+    return TCL_ERROR;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_JoinObjCmd --
+ *
+ *	This procedure is invoked to process the "join" Tcl command. See the
+ *	user documentation for details on what it does.
+ *
+ * Results:
+ *	A standard Tcl object result.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_JoinObjCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* The argument objects. */
+{
+    int listLen, i;
+    Tcl_Obj *resObjPtr, *joinObjPtr, **elemPtrs;
+
+    if ((objc < 2) || (objc > 3)) {
+	Tcl_WrongNumArgs(interp, 1, objv, "list ?joinString?");
+	return TCL_ERROR;
+    }
+
+    /*
+     * Make sure the list argument is a list object and get its length and a
+     * pointer to its array of element pointers.
+     */
+
+    if (TclListObjGetElements(interp, objv[1], &listLen,
+	    &elemPtrs) != TCL_OK) {
+	return TCL_ERROR;
+    }
+
+    joinObjPtr = (objc == 2) ? Tcl_NewStringObj(" ", 1) : objv[2];
+    Tcl_IncrRefCount(joinObjPtr);
+
+    resObjPtr = Tcl_NewObj();
+    for (i = 0;  i < listLen;  i++) {
+	if (i > 0) {
+	    Tcl_AppendObjToObj(resObjPtr, joinObjPtr);
+	}
+	Tcl_AppendObjToObj(resObjPtr, elemPtrs[i]);
+    }
+    Tcl_DecrRefCount(joinObjPtr);
+    Tcl_SetObjResult(interp, resObjPtr);
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_LassignObjCmd --
+ *
+ *	This object-based procedure is invoked to process the "lassign" Tcl
+ *	command. See the user documentation for details on what it does.
+ *
+ * Results:
+ *	A standard Tcl object result.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_LassignObjCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    Tcl_Obj *listCopyPtr;
+    Tcl_Obj **listObjv;		/* The contents of the list. */
+    int listObjc;		/* The length of the list. */
+    int code = TCL_OK;
+
+    if (objc < 2) {
+	Tcl_WrongNumArgs(interp, 1, objv, "list ?varName ...?");
+	return TCL_ERROR;
+    }
+
+    listCopyPtr = TclListObjCopy(interp, objv[1]);
+    if (listCopyPtr == NULL) {
+	return TCL_ERROR;
+    }
+
+    TclListObjGetElements(NULL, listCopyPtr, &listObjc, &listObjv);
+
+    objc -= 2;
+    objv += 2;
+    while (code == TCL_OK && objc > 0 && listObjc > 0) {
+	if (Tcl_ObjSetVar2(interp, *objv++, NULL, *listObjv++,
+		TCL_LEAVE_ERR_MSG) == NULL) {
+	    code = TCL_ERROR;
+	}
+	objc--;
+	listObjc--;
+    }
+
+    if (code == TCL_OK && objc > 0) {
+	Tcl_Obj *emptyObj;
+
+	TclNewObj(emptyObj);
+	Tcl_IncrRefCount(emptyObj);
+	while (code == TCL_OK && objc-- > 0) {
+	    if (Tcl_ObjSetVar2(interp, *objv++, NULL, emptyObj,
+		    TCL_LEAVE_ERR_MSG) == NULL) {
+		code = TCL_ERROR;
+	    }
+	}
+	Tcl_DecrRefCount(emptyObj);
+    }
+
+    if (code == TCL_OK && listObjc > 0) {
+	Tcl_SetObjResult(interp, Tcl_NewListObj(listObjc, listObjv));
+    }
+
+    Tcl_DecrRefCount(listCopyPtr);
+    return code;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_LindexObjCmd --
+ *
+ *	This object-based procedure is invoked to process the "lindex" Tcl
+ *	command. See the user documentation for details on what it does.
+ *
+ * Results:
+ *	A standard Tcl object result.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_LindexObjCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+
+    Tcl_Obj *elemPtr;		/* Pointer to the element being extracted. */
+
+    if (objc < 2) {
+	Tcl_WrongNumArgs(interp, 1, objv, "list ?index ...?");
+	return TCL_ERROR;
+    }
+
+    /*
+     * If objc==3, then objv[2] may be either a single index or a list of
+     * indices: go to TclLindexList to determine which. If objc>=4, or
+     * objc==2, then objv[2 .. objc-2] are all single indices and processed as
+     * such in TclLindexFlat.
+     */
+
+    if (objc == 3) {
+	elemPtr = TclLindexList(interp, objv[1], objv[2]);
+    } else {
+	elemPtr = TclLindexFlat(interp, objv[1], objc-2, objv+2);
+    }
+
+    /*
+     * Set the interpreter's object result to the last element extracted.
+     */
+
+    if (elemPtr == NULL) {
+	return TCL_ERROR;
+    }
+
+    Tcl_SetObjResult(interp, elemPtr);
+    Tcl_DecrRefCount(elemPtr);
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_LinsertObjCmd --
+ *
+ *	This object-based procedure is invoked to process the "linsert" Tcl
+ *	command. See the user documentation for details on what it does.
+ *
+ * Results:
+ *	A new Tcl list object formed by inserting zero or more elements into a
+ *	list.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_LinsertObjCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    register int objc,		/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    Tcl_Obj *listPtr;
+    int index, len, result;
+
+    if (objc < 3) {
+	Tcl_WrongNumArgs(interp, 1, objv, "list index ?element ...?");
+	return TCL_ERROR;
+    }
+
+    result = TclListObjLength(interp, objv[1], &len);
+    if (result != TCL_OK) {
+	return result;
+    }
+
+    /*
+     * Get the index. "end" is interpreted to be the index after the last
+     * element, such that using it will cause any inserted elements to be
+     * appended to the list.
+     */
+
+    result = TclGetIntForIndexM(interp, objv[2], /*end*/ len, &index);
+    if (result != TCL_OK) {
+	return result;
+    }
+    if (index > len) {
+	index = len;
+    }
+
+    /*
+     * If the list object is unshared we can modify it directly. Otherwise we
+     * create a copy to modify: this is "copy on write".
+     */
+
+    listPtr = objv[1];
+    if (Tcl_IsShared(listPtr)) {
+	listPtr = TclListObjCopy(NULL, listPtr);
+    }
+
+    if ((objc == 4) && (index == len)) {
+	/*
+	 * Special case: insert one element at the end of the list.
+	 */
+
+	Tcl_ListObjAppendElement(NULL, listPtr, objv[3]);
+    } else {
+	if (TCL_OK != Tcl_ListObjReplace(interp, listPtr, index, 0,
+		(objc-3), &(objv[3]))) {
+	    return TCL_ERROR;
+	}
+    }
+
+    /*
+     * Set the interpreter's object result.
+     */
+
+    Tcl_SetObjResult(interp, listPtr);
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_ListObjCmd --
+ *
+ *	This procedure is invoked to process the "list" Tcl command. See the
+ *	user documentation for details on what it does.
+ *
+ * Results:
+ *	A standard Tcl object result.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_ListObjCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    register int objc,		/* Number of arguments. */
+    register Tcl_Obj *const objv[])
+				/* The argument objects. */
+{
+    /*
+     * If there are no list elements, the result is an empty object.
+     * Otherwise set the interpreter's result object to be a list object.
+     */
+
+    if (objc > 1) {
+	Tcl_SetObjResult(interp, Tcl_NewListObj(objc-1, &objv[1]));
+    }
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_LlengthObjCmd --
+ *
+ *	This object-based procedure is invoked to process the "llength" Tcl
+ *	command. See the user documentation for details on what it does.
+ *
+ * Results:
+ *	A standard Tcl object result.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_LlengthObjCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    register Tcl_Obj *const objv[])
+				/* Argument objects. */
+{
+    int listLen, result;
+
+    if (objc != 2) {
+	Tcl_WrongNumArgs(interp, 1, objv, "list");
+	return TCL_ERROR;
+    }
+
+    result = TclListObjLength(interp, objv[1], &listLen);
+    if (result != TCL_OK) {
+	return result;
+    }
+
+    /*
+     * Set the interpreter's object result to an integer object holding the
+     * length.
+     */
+
+    Tcl_SetObjResult(interp, Tcl_NewIntObj(listLen));
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_LrangeObjCmd --
+ *
+ *	This procedure is invoked to process the "lrange" Tcl command. See the
+ *	user documentation for details on what it does.
+ *
+ * Results:
+ *	A standard Tcl object result.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_LrangeObjCmd(
+    ClientData notUsed,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    register Tcl_Obj *const objv[])
+				/* Argument objects. */
+{
+    Tcl_Obj **elemPtrs;
+    int listLen, first, last, result;
+
+    if (objc != 4) {
+	Tcl_WrongNumArgs(interp, 1, objv, "list first last");
+	return TCL_ERROR;
+    }
+
+    result = TclListObjLength(interp, objv[1], &listLen);
+    if (result != TCL_OK) {
+	return result;
+    }
+
+    result = TclGetIntForIndexM(interp, objv[2], /*endValue*/ listLen - 1,
+	    &first);
+    if (result != TCL_OK) {
+	return result;
+    }
+    if (first < 0) {
+	first = 0;
+    }
+
+    result = TclGetIntForIndexM(interp, objv[3], /*endValue*/ listLen - 1,
+	    &last);
+    if (result != TCL_OK) {
+	return result;
+    }
+    if (last >= listLen) {
+	last = listLen - 1;
+    }
+
+    if (first > last) {
+	/*
+	 * Returning an empty list is easy.
+	 */
+
+	return TCL_OK;
+    }
+
+    result = TclListObjGetElements(interp, objv[1], &listLen, &elemPtrs);
+    if (result != TCL_OK) {
+	return result;
+    }
+
+    if (Tcl_IsShared(objv[1]) ||
+	    ((ListRepPtr(objv[1])->refCount > 1))) {
+	Tcl_SetObjResult(interp, Tcl_NewListObj(last - first + 1,
+		&elemPtrs[first]));
+    } else {
+	/*
+	 * In-place is possible.
+	 */
+
+	if (last < (listLen - 1)) {
+	    Tcl_ListObjReplace(interp, objv[1], last + 1, listLen - 1 - last,
+		    0, NULL);
+	}
+
+	/*
+	 * This one is not conditioned on (first > 0) in order to preserve the
+	 * string-canonizing effect of [lrange 0 end].
+	 */
+
+	Tcl_ListObjReplace(interp, objv[1], 0, first, 0, NULL);
+	Tcl_SetObjResult(interp, objv[1]);
+    }
+
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_LrepeatObjCmd --
+ *
+ *	This procedure is invoked to process the "lrepeat" Tcl command. See
+ *	the user documentation for details on what it does.
+ *
+ * Results:
+ *	A standard Tcl object result.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_LrepeatObjCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    register int objc,		/* Number of arguments. */
+    register Tcl_Obj *const objv[])
+				/* The argument objects. */
+{
+    int elementCount, i, totalElems;
+    Tcl_Obj *listPtr, **dataArray = NULL;
+
+    /*
+     * Check arguments for legality:
+     *		lrepeat count ?value ...?
+     */
+
+    if (objc < 2) {
+	Tcl_WrongNumArgs(interp, 1, objv, "count ?value ...?");
+	return TCL_ERROR;
+    }
+    if (TCL_OK != TclGetIntFromObj(interp, objv[1], &elementCount)) {
+	return TCL_ERROR;
+    }
+    if (elementCount < 0) {
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		"bad count \"%d\": must be integer >= 0", elementCount));
+	Tcl_SetErrorCode(interp, "TCL", "OPERATION", "LREPEAT", "NEGARG",
+		NULL);
+	return TCL_ERROR;
+    }
+
+    /*
+     * Skip forward to the interesting arguments now we've finished parsing.
+     */
+
+    objc -= 2;
+    objv += 2;
+
+    /* Final sanity check. Do not exceed limits on max list length. */
+
+    if (elementCount && objc > LIST_MAX/elementCount) {
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		"max length of a Tcl list (%d elements) exceeded", LIST_MAX));
+	Tcl_SetErrorCode(interp, "TCL", "MEMORY", NULL);
+	return TCL_ERROR;
+    }
+    totalElems = objc * elementCount;
+
+    /*
+     * Get an empty list object that is allocated large enough to hold each
+     * init value elementCount times.
+     */
+
+    listPtr = Tcl_NewListObj(totalElems, NULL);
+    if (totalElems) {
+	List *listRepPtr = ListRepPtr(listPtr);
+
+	listRepPtr->elemCount = elementCount*objc;
+	dataArray = &listRepPtr->elements;
+    }
+
+    /*
+     * Set the elements. Note that we handle the common degenerate case of a
+     * single value being repeated separately to permit the compiler as much
+     * room as possible to optimize a loop that might be run a very large
+     * number of times.
+     */
+
+    CLANG_ASSERT(dataArray || totalElems == 0 );
+    if (objc == 1) {
+	register Tcl_Obj *tmpPtr = objv[0];
+
+	tmpPtr->refCount += elementCount;
+	for (i=0 ; i<elementCount ; i++) {
+	    dataArray[i] = tmpPtr;
+	}
+    } else {
+	int j, k = 0;
+
+	for (i=0 ; i<elementCount ; i++) {
+	    for (j=0 ; j<objc ; j++) {
+		Tcl_IncrRefCount(objv[j]);
+		dataArray[k++] = objv[j];
+	    }
+	}
+    }
+
+    Tcl_SetObjResult(interp, listPtr);
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_LreplaceObjCmd --
+ *
+ *	This object-based procedure is invoked to process the "lreplace" Tcl
+ *	command. See the user documentation for details on what it does.
+ *
+ * Results:
+ *	A new Tcl list object formed by replacing zero or more elements of a
+ *	list.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_LreplaceObjCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    register Tcl_Obj *listPtr;
+    int first, last, listLen, numToDelete, result;
+
+    if (objc < 4) {
+	Tcl_WrongNumArgs(interp, 1, objv,
+		"list first last ?element ...?");
+	return TCL_ERROR;
+    }
+
+    result = TclListObjLength(interp, objv[1], &listLen);
+    if (result != TCL_OK) {
+	return result;
+    }
+
+    /*
+     * Get the first and last indexes. "end" is interpreted to be the index
+     * for the last element, such that using it will cause that element to be
+     * included for deletion.
+     */
+
+    result = TclGetIntForIndexM(interp, objv[2], /*end*/ listLen-1, &first);
+    if (result != TCL_OK) {
+	return result;
+    }
+
+    result = TclGetIntForIndexM(interp, objv[3], /*end*/ listLen-1, &last);
+    if (result != TCL_OK) {
+	return result;
+    }
+
+    if (first < 0) {
+	first = 0;
+    }
+
+    /*
+     * Complain if the user asked for a start element that is greater than the
+     * list length. This won't ever trigger for the "end-*" case as that will
+     * be properly constrained by TclGetIntForIndex because we use listLen-1
+     * (to allow for replacing the last elem).
+     */
+
+    if ((first > listLen) && (listLen > 0)) {
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		"list doesn't contain element %s", TclGetString(objv[2])));
+	Tcl_SetErrorCode(interp, "TCL", "OPERATION", "LREPLACE", "BADIDX",
+		NULL);
+	return TCL_ERROR;
+    }
+    if (last >= listLen) {
+	last = listLen - 1;
+    }
+    if (first <= last) {
+	numToDelete = last - first + 1;
+    } else {
+	numToDelete = 0;
+    }
+
+    /*
+     * If the list object is unshared we can modify it directly, otherwise we
+     * create a copy to modify: this is "copy on write".
+     */
+
+    listPtr = objv[1];
+    if (Tcl_IsShared(listPtr)) {
+	listPtr = TclListObjCopy(NULL, listPtr);
+    }
+
+    /*
+     * Note that we call Tcl_ListObjReplace even when numToDelete == 0 and
+     * objc == 4. In this case, the list value of listPtr is not changed (no
+     * elements are removed or added), but by making the call we are assured
+     * we end up with a list in canonical form. Resist any temptation to
+     * optimize this case away.
+     */
+
+    if (TCL_OK != Tcl_ListObjReplace(interp, listPtr, first, numToDelete,
+	    objc-4, objv+4)) {
+	return TCL_ERROR;
+    }
+
+    /*
+     * Set the interpreter's object result.
+     */
+
+    Tcl_SetObjResult(interp, listPtr);
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_LreverseObjCmd --
+ *
+ *	This procedure is invoked to process the "lreverse" Tcl command. See
+ *	the user documentation for details on what it does.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_LreverseObjCmd(
+    ClientData clientData,	/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument values. */
+{
+    Tcl_Obj **elemv;
+    int elemc, i, j;
+
+    if (objc != 2) {
+	Tcl_WrongNumArgs(interp, 1, objv, "list");
+	return TCL_ERROR;
+    }
+    if (TclListObjGetElements(interp, objv[1], &elemc, &elemv) != TCL_OK) {
+	return TCL_ERROR;
+    }
+
+    /*
+     * If the list is empty, just return it. [Bug 1876793]
+     */
+
+    if (!elemc) {
+	Tcl_SetObjResult(interp, objv[1]);
+	return TCL_OK;
+    }
+
+    if (Tcl_IsShared(objv[1])
+	    || (ListRepPtr(objv[1])->refCount > 1)) {	/* Bug 1675044 */
+	Tcl_Obj *resultObj, **dataArray;
+	List *listRepPtr;
+
+	resultObj = Tcl_NewListObj(elemc, NULL);
+	listRepPtr = ListRepPtr(resultObj);
+	listRepPtr->elemCount = elemc;
+	dataArray = &listRepPtr->elements;
+
+	for (i=0,j=elemc-1 ; i<elemc ; i++,j--) {
+	    dataArray[j] = elemv[i];
+	    Tcl_IncrRefCount(elemv[i]);
+	}
+
+	Tcl_SetObjResult(interp, resultObj);
+    } else {
+
+	/*
+	 * Not shared, so swap "in place". This relies on Tcl_LOGE above
+	 * returning a pointer to the live array of Tcl_Obj values.
+	 */
+
+	for (i=0,j=elemc-1 ; i<j ; i++,j--) {
+	    Tcl_Obj *tmp = elemv[i];
+
+	    elemv[i] = elemv[j];
+	    elemv[j] = tmp;
+	}
+	TclInvalidateStringRep(objv[1]);
+	Tcl_SetObjResult(interp, objv[1]);
+    }
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_LsearchObjCmd --
+ *
+ *	This procedure is invoked to process the "lsearch" Tcl command. See
+ *	the user documentation for details on what it does.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_LsearchObjCmd(
+    ClientData clientData,	/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument values. */
+{
+    const char *bytes, *patternBytes;
+    int i, match, index, result, listc, length, elemLen, bisect;
+    int dataType, isIncreasing, lower, upper, offset;
+    Tcl_WideInt patWide, objWide;
+    int allMatches, inlineReturn, negatedMatch, returnSubindices, noCase;
+    double patDouble, objDouble;
+    SortInfo sortInfo;
+    Tcl_Obj *patObj, **listv, *listPtr, *startPtr, *itemPtr;
+    SortStrCmpFn_t strCmpFn = strcmp;
+    Tcl_RegExp regexp = NULL;
+    static const char *const options[] = {
+	"-all",	    "-ascii",   "-bisect", "-decreasing", "-dictionary",
+	"-exact",   "-glob",    "-increasing", "-index",
+	"-inline",  "-integer", "-nocase",     "-not",
+	"-real",    "-regexp",  "-sorted",     "-start",
+	"-subindices", NULL
+    };
+    enum options {
+	LSEARCH_ALL, LSEARCH_ASCII, LSEARCH_BISECT, LSEARCH_DECREASING,
+	LSEARCH_DICTIONARY, LSEARCH_EXACT, LSEARCH_GLOB, LSEARCH_INCREASING,
+	LSEARCH_INDEX, LSEARCH_INLINE, LSEARCH_INTEGER, LSEARCH_NOCASE,
+	LSEARCH_NOT, LSEARCH_REAL, LSEARCH_REGEXP, LSEARCH_SORTED,
+	LSEARCH_START, LSEARCH_SUBINDICES
+    };
+    enum datatypes {
+	ASCII, DICTIONARY, INTEGER, REAL
+    };
+    enum modes {
+	EXACT, GLOB, REGEXP, SORTED
+    };
+    enum modes mode;
+
+    mode = GLOB;
+    dataType = ASCII;
+    isIncreasing = 1;
+    allMatches = 0;
+    inlineReturn = 0;
+    returnSubindices = 0;
+    negatedMatch = 0;
+    bisect = 0;
+    listPtr = NULL;
+    startPtr = NULL;
+    offset = 0;
+    noCase = 0;
+    sortInfo.compareCmdPtr = NULL;
+    sortInfo.isIncreasing = 1;
+    sortInfo.sortMode = 0;
+    sortInfo.interp = interp;
+    sortInfo.resultCode = TCL_OK;
+    sortInfo.indexv = NULL;
+    sortInfo.indexc = 0;
+
+    if (objc < 3) {
+	Tcl_WrongNumArgs(interp, 1, objv, "?-option value ...? list pattern");
+	return TCL_ERROR;
+    }
+
+    for (i = 1; i < objc-2; i++) {
+	if (Tcl_GetIndexFromObj(interp, objv[i], options, "option", 0, &index)
+		!= TCL_OK) {
+	    if (startPtr != NULL) {
+		Tcl_DecrRefCount(startPtr);
+	    }
+	    result = TCL_ERROR;
+	    goto done;
+	}
+	switch ((enum options) index) {
+	case LSEARCH_ALL:		/* -all */
+	    allMatches = 1;
+	    break;
+	case LSEARCH_ASCII:		/* -ascii */
+	    dataType = ASCII;
+	    break;
+	case LSEARCH_BISECT:		/* -bisect */
+	    mode = SORTED;
+	    bisect = 1;
+	    break;
+	case LSEARCH_DECREASING:	/* -decreasing */
+	    isIncreasing = 0;
+	    sortInfo.isIncreasing = 0;
+	    break;
+	case LSEARCH_DICTIONARY:	/* -dictionary */
+	    dataType = DICTIONARY;
+	    break;
+	case LSEARCH_EXACT:		/* -increasing */
+	    mode = EXACT;
+	    break;
+	case LSEARCH_GLOB:		/* -glob */
+	    mode = GLOB;
+	    break;
+	case LSEARCH_INCREASING:	/* -increasing */
+	    isIncreasing = 1;
+	    sortInfo.isIncreasing = 1;
+	    break;
+	case LSEARCH_INLINE:		/* -inline */
+	    inlineReturn = 1;
+	    break;
+	case LSEARCH_INTEGER:		/* -integer */
+	    dataType = INTEGER;
+	    break;
+	case LSEARCH_NOCASE:		/* -nocase */
+	    strCmpFn = TclUtfCasecmp;
+	    noCase = 1;
+	    break;
+	case LSEARCH_NOT:		/* -not */
+	    negatedMatch = 1;
+	    break;
+	case LSEARCH_REAL:		/* -real */
+	    dataType = REAL;
+	    break;
+	case LSEARCH_REGEXP:		/* -regexp */
+	    mode = REGEXP;
+	    break;
+	case LSEARCH_SORTED:		/* -sorted */
+	    mode = SORTED;
+	    break;
+	case LSEARCH_SUBINDICES:	/* -subindices */
+	    returnSubindices = 1;
+	    break;
+	case LSEARCH_START:		/* -start */
+	    /*
+	     * If there was a previous -start option, release its saved index
+	     * because it will either be replaced or there will be an error.
+	     */
+
+	    if (startPtr != NULL) {
+		Tcl_DecrRefCount(startPtr);
+	    }
+	    if (i > objc-4) {
+		Tcl_SetObjResult(interp, Tcl_NewStringObj(
+			"missing starting index", -1));
+		Tcl_SetErrorCode(interp, "TCL", "ARGUMENT", "MISSING", NULL);
+		result = TCL_ERROR;
+		goto done;
+	    }
+	    i++;
+	    if (objv[i] == objv[objc - 2]) {
+		/*
+		 * Take copy to prevent shimmering problems. Note that it does
+		 * not matter if the index obj is also a component of the list
+		 * being searched. We only need to copy where the list and the
+		 * index are one-and-the-same.
+		 */
+
+		startPtr = Tcl_DuplicateObj(objv[i]);
+	    } else {
+		startPtr = objv[i];
+		Tcl_IncrRefCount(startPtr);
+	    }
+	    break;
+	case LSEARCH_INDEX: {		/* -index */
+	    Tcl_Obj **indices;
+	    int j;
+
+	    if (sortInfo.indexc > 1) {
+		TclStackFree(interp, sortInfo.indexv);
+	    }
+	    if (i > objc-4) {
+		if (startPtr != NULL) {
+		    Tcl_DecrRefCount(startPtr);
+		}
+		Tcl_SetObjResult(interp, Tcl_NewStringObj(
+			"\"-index\" option must be followed by list index",
+			-1));
+		Tcl_SetErrorCode(interp, "TCL", "ARGUMENT", "MISSING", NULL);
+		return TCL_ERROR;
+	    }
+
+	    /*
+	     * Store the extracted indices for processing by sublist
+	     * extraction. Note that we don't do this using objects because
+	     * that has shimmering problems.
+	     */
+
+	    i++;
+	    if (TclListObjGetElements(interp, objv[i],
+		    &sortInfo.indexc, &indices) != TCL_OK) {
+		if (startPtr != NULL) {
+		    Tcl_DecrRefCount(startPtr);
+		}
+		return TCL_ERROR;
+	    }
+	    switch (sortInfo.indexc) {
+	    case 0:
+		sortInfo.indexv = NULL;
+		break;
+	    case 1:
+		sortInfo.indexv = &sortInfo.singleIndex;
+		break;
+	    default:
+		sortInfo.indexv =
+			TclStackAlloc(interp, sizeof(int) * sortInfo.indexc);
+	    }
+
+	    /*
+	     * Fill the array by parsing each index. We don't know whether
+	     * their scale is sensible yet, but we at least perform the
+	     * syntactic check here.
+	     */
+
+	    for (j=0 ; j<sortInfo.indexc ; j++) {
+		if (TclGetIntForIndexM(interp, indices[j], SORTIDX_END,
+			&sortInfo.indexv[j]) != TCL_OK) {
+		    Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf(
+			    "\n    (-index option item number %d)", j));
+		    result = TCL_ERROR;
+		    goto done;
+		}
+	    }
+	    break;
+	}
+	}
+    }
+
+    /*
+     * Subindices only make sense if asked for with -index option set.
+     */
+
+    if (returnSubindices && sortInfo.indexc==0) {
+	if (startPtr != NULL) {
+	    Tcl_DecrRefCount(startPtr);
+	}
+	Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		"-subindices cannot be used without -index option", -1));
+	Tcl_SetErrorCode(interp, "TCL", "OPERATION", "LSEARCH",
+		"BAD_OPTION_MIX", NULL);
+	return TCL_ERROR;
+    }
+
+    if (bisect && (allMatches || negatedMatch)) {
+	Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		"-bisect is not compatible with -all or -not", -1));
+	Tcl_SetErrorCode(interp, "TCL", "OPERATION", "LSEARCH",
+		"BAD_OPTION_MIX", NULL);
+	return TCL_ERROR;
+    }
+
+    if (mode == REGEXP) {
+	/*
+	 * We can shimmer regexp/list if listv[i] == pattern, so get the
+	 * regexp rep before the list rep. First time round, omit the interp
+	 * and hope that the compilation will succeed. If it fails, we'll
+	 * recompile in "expensive" mode with a place to put error messages.
+	 */
+
+	regexp = Tcl_GetRegExpFromObj(NULL, objv[objc - 1],
+		TCL_REG_ADVANCED | TCL_REG_NOSUB |
+		(noCase ? TCL_REG_NOCASE : 0));
+	if (regexp == NULL) {
+	    /*
+	     * Failed to compile the RE. Try again without the TCL_REG_NOSUB
+	     * flag in case the RE had sub-expressions in it [Bug 1366683]. If
+	     * this fails, an error message will be left in the interpreter.
+	     */
+
+	    regexp = Tcl_GetRegExpFromObj(interp, objv[objc - 1],
+		    TCL_REG_ADVANCED | (noCase ? TCL_REG_NOCASE : 0));
+	}
+
+	if (regexp == NULL) {
+	    if (startPtr != NULL) {
+		Tcl_DecrRefCount(startPtr);
+	    }
+	    result = TCL_ERROR;
+	    goto done;
+	}
+    }
+
+    /*
+     * Make sure the list argument is a list object and get its length and a
+     * pointer to its array of element pointers.
+     */
+
+    result = TclListObjGetElements(interp, objv[objc - 2], &listc, &listv);
+    if (result != TCL_OK) {
+	if (startPtr != NULL) {
+	    Tcl_DecrRefCount(startPtr);
+	}
+	goto done;
+    }
+
+    /*
+     * Get the user-specified start offset.
+     */
+
+    if (startPtr) {
+	result = TclGetIntForIndexM(interp, startPtr, listc-1, &offset);
+	Tcl_DecrRefCount(startPtr);
+	if (result != TCL_OK) {
+	    goto done;
+	}
+	if (offset < 0) {
+	    offset = 0;
+	}
+
+	/*
+	 * If the search started past the end of the list, we just return a
+	 * "did not match anything at all" result straight away. [Bug 1374778]
+	 */
+
+	if (offset > listc-1) {
+	    if (sortInfo.indexc > 1) {
+		TclStackFree(interp, sortInfo.indexv);
+	    }
+	    if (allMatches || inlineReturn) {
+		Tcl_ResetResult(interp);
+	    } else {
+		Tcl_SetObjResult(interp, Tcl_NewIntObj(-1));
+	    }
+	    return TCL_OK;
+	}
+    }
+
+    patObj = objv[objc - 1];
+    patternBytes = NULL;
+    if (mode == EXACT || mode == SORTED) {
+	switch ((enum datatypes) dataType) {
+	case ASCII:
+	case DICTIONARY:
+	    patternBytes = TclGetStringFromObj(patObj, &length);
+	    break;
+	case INTEGER:
+	    result = TclGetWideIntFromObj(interp, patObj, &patWide);
+	    if (result != TCL_OK) {
+		goto done;
+	    }
+
+	    /*
+	     * List representation might have been shimmered; restore it. [Bug
+	     * 1844789]
+	     */
+
+	    TclListObjGetElements(NULL, objv[objc - 2], &listc, &listv);
+	    break;
+	case REAL:
+	    result = Tcl_GetDoubleFromObj(interp, patObj, &patDouble);
+	    if (result != TCL_OK) {
+		goto done;
+	    }
+
+	    /*
+	     * List representation might have been shimmered; restore it. [Bug
+	     * 1844789]
+	     */
+
+	    TclListObjGetElements(NULL, objv[objc - 2], &listc, &listv);
+	    break;
+	}
+    } else {
+	patternBytes = TclGetStringFromObj(patObj, &length);
+    }
+
+    /*
+     * Set default index value to -1, indicating failure; if we find the item
+     * in the course of our search, index will be set to the correct value.
+     */
+
+    index = -1;
+    match = 0;
+
+    if (mode == SORTED && !allMatches && !negatedMatch) {
+	/*
+	 * If the data is sorted, we can do a more intelligent search. Note
+	 * that there is no point in being smart when -all was specified; in
+	 * that case, we have to look at all items anyway, and there is no
+	 * sense in doing this when the match sense is inverted.
+	 */
+
+	lower = offset - 1;
+	upper = listc;
+	while (lower + 1 != upper && sortInfo.resultCode == TCL_OK) {
+	    i = (lower + upper)/2;
+	    if (sortInfo.indexc != 0) {
+		itemPtr = SelectObjFromSublist(listv[i], &sortInfo);
+		if (sortInfo.resultCode != TCL_OK) {
+		    result = sortInfo.resultCode;
+		    goto done;
+		}
+	    } else {
+		itemPtr = listv[i];
+	    }
+	    switch ((enum datatypes) dataType) {
+	    case ASCII:
+		bytes = TclGetString(itemPtr);
+		match = strCmpFn(patternBytes, bytes);
+		break;
+	    case DICTIONARY:
+		bytes = TclGetString(itemPtr);
+		match = DictionaryCompare(patternBytes, bytes);
+		break;
+	    case INTEGER:
+		result = TclGetWideIntFromObj(interp, itemPtr, &objWide);
+		if (result != TCL_OK) {
+		    goto done;
+		}
+		if (patWide == objWide) {
+		    match = 0;
+		} else if (patWide < objWide) {
+		    match = -1;
+		} else {
+		    match = 1;
+		}
+		break;
+	    case REAL:
+		result = Tcl_GetDoubleFromObj(interp, itemPtr, &objDouble);
+		if (result != TCL_OK) {
+		    goto done;
+		}
+		if (patDouble == objDouble) {
+		    match = 0;
+		} else if (patDouble < objDouble) {
+		    match = -1;
+		} else {
+		    match = 1;
+		}
+		break;
+	    }
+	    if (match == 0) {
+		/*
+		 * Normally, binary search is written to stop when it finds a
+		 * match. If there are duplicates of an element in the list,
+		 * our first match might not be the first occurance.
+		 * Consider: 0 0 0 1 1 1 2 2 2
+		 *
+		 * To maintain consistancy with standard lsearch semantics, we
+		 * must find the leftmost occurance of the pattern in the
+		 * list. Thus we don't just stop searching here. This
+		 * variation means that a search always makes log n
+		 * comparisons (normal binary search might "get lucky" with an
+		 * early comparison).
+		 *
+		 * In bisect mode though, we want the last of equals.
+		 */
+
+		index = i;
+		if (bisect) {
+		    lower = i;
+		} else {
+		    upper = i;
+		}
+	    } else if (match > 0) {
+		if (isIncreasing) {
+		    lower = i;
+		} else {
+		    upper = i;
+		}
+	    } else {
+		if (isIncreasing) {
+		    upper = i;
+		} else {
+		    lower = i;
+		}
+	    }
+	}
+	if (bisect && index < 0) {
+	    index = lower;
+	}
+    } else {
+	/*
+	 * We need to do a linear search, because (at least one) of:
+	 *   - our matcher can only tell equal vs. not equal
+	 *   - our matching sense is negated
+	 *   - we're building a list of all matched items
+	 */
+
+	if (allMatches) {
+	    listPtr = Tcl_NewListObj(0, NULL);
+	}
+	for (i = offset; i < listc; i++) {
+	    match = 0;
+	    if (sortInfo.indexc != 0) {
+		itemPtr = SelectObjFromSublist(listv[i], &sortInfo);
+		if (sortInfo.resultCode != TCL_OK) {
+		    if (listPtr != NULL) {
+			Tcl_DecrRefCount(listPtr);
+		    }
+		    result = sortInfo.resultCode;
+		    goto done;
+		}
+	    } else {
+		itemPtr = listv[i];
+	    }
+
+	    switch (mode) {
+	    case SORTED:
+	    case EXACT:
+		switch ((enum datatypes) dataType) {
+		case ASCII:
+		    bytes = TclGetStringFromObj(itemPtr, &elemLen);
+		    if (length == elemLen) {
+			/*
+			 * This split allows for more optimal compilation of
+			 * memcmp/strcasecmp.
+			 */
+
+			if (noCase) {
+			    match = (TclUtfCasecmp(bytes, patternBytes) == 0);
+			} else {
+			    match = (memcmp(bytes, patternBytes,
+				    (size_t) length) == 0);
+			}
+		    }
+		    break;
+
+		case DICTIONARY:
+		    bytes = TclGetString(itemPtr);
+		    match = (DictionaryCompare(bytes, patternBytes) == 0);
+		    break;
+
+		case INTEGER:
+		    result = TclGetWideIntFromObj(interp, itemPtr, &objWide);
+		    if (result != TCL_OK) {
+			if (listPtr != NULL) {
+			    Tcl_DecrRefCount(listPtr);
+			}
+			goto done;
+		    }
+		    match = (objWide == patWide);
+		    break;
+
+		case REAL:
+		    result = Tcl_GetDoubleFromObj(interp,itemPtr, &objDouble);
+		    if (result != TCL_OK) {
+			if (listPtr) {
+			    Tcl_DecrRefCount(listPtr);
+			}
+			goto done;
+		    }
+		    match = (objDouble == patDouble);
+		    break;
+		}
+		break;
+
+	    case GLOB:
+		match = Tcl_StringCaseMatch(TclGetString(itemPtr),
+			patternBytes, noCase);
+		break;
+
+	    case REGEXP:
+		match = Tcl_RegExpExecObj(interp, regexp, itemPtr, 0, 0, 0);
+		if (match < 0) {
+		    Tcl_DecrRefCount(patObj);
+		    if (listPtr != NULL) {
+			Tcl_DecrRefCount(listPtr);
+		    }
+		    result = TCL_ERROR;
+		    goto done;
+		}
+		break;
+	    }
+
+	    /*
+	     * Invert match condition for -not.
+	     */
+
+	    if (negatedMatch) {
+		match = !match;
+	    }
+	    if (!match) {
+		continue;
+	    }
+	    if (!allMatches) {
+		index = i;
+		break;
+	    } else if (inlineReturn) {
+		/*
+		 * Note that these appends are not expected to fail.
+		 */
+
+		if (returnSubindices && (sortInfo.indexc != 0)) {
+		    itemPtr = SelectObjFromSublist(listv[i], &sortInfo);
+		} else {
+		    itemPtr = listv[i];
+		}
+		Tcl_ListObjAppendElement(interp, listPtr, itemPtr);
+	    } else if (returnSubindices) {
+		int j;
+
+		itemPtr = Tcl_NewIntObj(i);
+		for (j=0 ; j<sortInfo.indexc ; j++) {
+		    Tcl_ListObjAppendElement(interp, itemPtr,
+			    Tcl_NewIntObj(sortInfo.indexv[j]));
+		}
+		Tcl_ListObjAppendElement(interp, listPtr, itemPtr);
+	    } else {
+		Tcl_ListObjAppendElement(interp, listPtr, Tcl_NewIntObj(i));
+	    }
+	}
+    }
+
+    /*
+     * Return everything or a single value.
+     */
+
+    if (allMatches) {
+	Tcl_SetObjResult(interp, listPtr);
+    } else if (!inlineReturn) {
+	if (returnSubindices) {
+	    int j;
+
+	    itemPtr = Tcl_NewIntObj(index);
+	    for (j=0 ; j<sortInfo.indexc ; j++) {
+		Tcl_ListObjAppendElement(interp, itemPtr,
+			Tcl_NewIntObj(sortInfo.indexv[j]));
+	    }
+	    Tcl_SetObjResult(interp, itemPtr);
+	} else {
+	    Tcl_SetObjResult(interp, Tcl_NewIntObj(index));
+	}
+    } else if (index < 0) {
+	/*
+	 * Is this superfluous? The result should be a blank object by
+	 * default...
+	 */
+
+	Tcl_SetObjResult(interp, Tcl_NewObj());
+    } else {
+	Tcl_SetObjResult(interp, listv[index]);
+    }
+    result = TCL_OK;
+
+    /*
+     * Cleanup the index list array.
+     */
+
+  done:
+    if (sortInfo.indexc > 1) {
+	TclStackFree(interp, sortInfo.indexv);
+    }
+    return result;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_LsetObjCmd --
+ *
+ *	This procedure is invoked to process the "lset" Tcl command. See the
+ *	user documentation for details on what it does.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_LsetObjCmd(
+    ClientData clientData,	/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument values. */
+{
+    Tcl_Obj *listPtr;		/* Pointer to the list being altered. */
+    Tcl_Obj *finalValuePtr;	/* Value finally assigned to the variable. */
+
+    /*
+     * Check parameter count.
+     */
+
+    if (objc < 3) {
+	Tcl_WrongNumArgs(interp, 1, objv,
+		"listVar ?index? ?index ...? value");
+	return TCL_ERROR;
+    }
+
+    /*
+     * Look up the list variable's value.
+     */
+
+    listPtr = Tcl_ObjGetVar2(interp, objv[1], NULL, TCL_LEAVE_ERR_MSG);
+    if (listPtr == NULL) {
+	return TCL_ERROR;
+    }
+
+    /*
+     * Substitute the value in the value. Return either the value or else an
+     * unshared copy of it.
+     */
+
+    if (objc == 4) {
+	finalValuePtr = TclLsetList(interp, listPtr, objv[2], objv[3]);
+    } else {
+	finalValuePtr = TclLsetFlat(interp, listPtr, objc-3, objv+2,
+		objv[objc-1]);
+    }
+
+    /*
+     * If substitution has failed, bail out.
+     */
+
+    if (finalValuePtr == NULL) {
+	return TCL_ERROR;
+    }
+
+    /*
+     * Finally, update the variable so that traces fire.
+     */
+
+    listPtr = Tcl_ObjSetVar2(interp, objv[1], NULL, finalValuePtr,
+	    TCL_LEAVE_ERR_MSG);
+    Tcl_DecrRefCount(finalValuePtr);
+    if (listPtr == NULL) {
+	return TCL_ERROR;
+    }
+
+    /*
+     * Return the new value of the variable as the interpreter result.
+     */
+
+    Tcl_SetObjResult(interp, listPtr);
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_LsortObjCmd --
+ *
+ *	This procedure is invoked to process the "lsort" Tcl command. See the
+ *	user documentation for details on what it does.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_LsortObjCmd(
+    ClientData clientData,	/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument values. */
+{
+    int i, j, index, indices, length, nocase = 0, indexc;
+    int sortMode = SORTMODE_ASCII;
+    int group, groupSize, groupOffset, idx, allocatedIndexVector = 0;
+    Tcl_Obj *resultPtr, *cmdPtr, **listObjPtrs, *listObj, *indexPtr;
+    SortElement *elementArray, *elementPtr;
+    SortInfo sortInfo;		/* Information about this sort that needs to
+				 * be passed to the comparison function. */
+#   define NUM_LISTS 30
+    SortElement *subList[NUM_LISTS+1];
+				/* This array holds pointers to temporary
+				 * lists built during the merge sort. Element
+				 * i of the array holds a list of length
+				 * 2**i. */
+    static const char *const switches[] = {
+	"-ascii", "-command", "-decreasing", "-dictionary", "-increasing",
+	"-index", "-indices", "-integer", "-nocase", "-real", "-stride",
+	"-unique", NULL
+    };
+    enum Lsort_Switches {
+	LSORT_ASCII, LSORT_COMMAND, LSORT_DECREASING, LSORT_DICTIONARY,
+	LSORT_INCREASING, LSORT_INDEX, LSORT_INDICES, LSORT_INTEGER,
+	LSORT_NOCASE, LSORT_REAL, LSORT_STRIDE, LSORT_UNIQUE
+    };
+
+    if (objc < 2) {
+	Tcl_WrongNumArgs(interp, 1, objv, "?-option value ...? list");
+	return TCL_ERROR;
+    }
+
+    /*
+     * Parse arguments to set up the mode for the sort.
+     */
+
+    sortInfo.isIncreasing = 1;
+    sortInfo.sortMode = SORTMODE_ASCII;
+    sortInfo.indexv = NULL;
+    sortInfo.indexc = 0;
+    sortInfo.unique = 0;
+    sortInfo.interp = interp;
+    sortInfo.resultCode = TCL_OK;
+    cmdPtr = NULL;
+    indices = 0;
+    group = 0;
+    groupSize = 1;
+    groupOffset = 0;
+    indexPtr = NULL;
+    for (i = 1; i < objc-1; i++) {
+	if (Tcl_GetIndexFromObj(interp, objv[i], switches, "option", 0,
+		&index) != TCL_OK) {
+	    sortInfo.resultCode = TCL_ERROR;
+	    goto done2;
+	}
+	switch ((enum Lsort_Switches) index) {
+	case LSORT_ASCII:
+	    sortInfo.sortMode = SORTMODE_ASCII;
+	    break;
+	case LSORT_COMMAND:
+	    if (i == objc-2) {
+		Tcl_SetObjResult(interp, Tcl_NewStringObj(
+			"\"-command\" option must be followed "
+			"by comparison command", -1));
+		Tcl_SetErrorCode(interp, "TCL", "ARGUMENT", "MISSING", NULL);
+		sortInfo.resultCode = TCL_ERROR;
+		goto done2;
+	    }
+	    sortInfo.sortMode = SORTMODE_COMMAND;
+	    cmdPtr = objv[i+1];
+	    i++;
+	    break;
+	case LSORT_DECREASING:
+	    sortInfo.isIncreasing = 0;
+	    break;
+	case LSORT_DICTIONARY:
+	    sortInfo.sortMode = SORTMODE_DICTIONARY;
+	    break;
+	case LSORT_INCREASING:
+	    sortInfo.isIncreasing = 1;
+	    break;
+	case LSORT_INDEX: {
+	    int indexc, dummy;
+	    Tcl_Obj **indexv;
+
+	    if (i == objc-2) {
+		Tcl_SetObjResult(interp, Tcl_NewStringObj(
+			"\"-index\" option must be followed by list index",
+			-1));
+		Tcl_SetErrorCode(interp, "TCL", "ARGUMENT", "MISSING", NULL);
+		sortInfo.resultCode = TCL_ERROR;
+		goto done2;
+	    }
+	    if (TclListObjGetElements(interp, objv[i+1], &indexc,
+		    &indexv) != TCL_OK) {
+		sortInfo.resultCode = TCL_ERROR;
+		goto done2;
+	    }
+
+	    /*
+	     * Check each of the indices for syntactic correctness. Note that
+	     * we do not store the converted values here because we do not
+	     * know if this is the only -index option yet and so we can't
+	     * allocate any space; that happens after the scan through all the
+	     * options is done.
+	     */
+
+	    for (j=0 ; j<indexc ; j++) {
+		if (TclGetIntForIndexM(interp, indexv[j], SORTIDX_END,
+			&dummy) != TCL_OK) {
+		    Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf(
+			    "\n    (-index option item number %d)", j));
+		    sortInfo.resultCode = TCL_ERROR;
+		    goto done2;
+		}
+	    }
+	    indexPtr = objv[i+1];
+	    i++;
+	    break;
+	}
+	case LSORT_INTEGER:
+	    sortInfo.sortMode = SORTMODE_INTEGER;
+	    break;
+	case LSORT_NOCASE:
+	    nocase = 1;
+	    break;
+	case LSORT_REAL:
+	    sortInfo.sortMode = SORTMODE_REAL;
+	    break;
+	case LSORT_UNIQUE:
+	    sortInfo.unique = 1;
+	    break;
+	case LSORT_INDICES:
+	    indices = 1;
+	    break;
+	case LSORT_STRIDE:
+	    if (i == objc-2) {
+		Tcl_SetObjResult(interp, Tcl_NewStringObj(
+			"\"-stride\" option must be "
+			"followed by stride length", -1));
+		Tcl_SetErrorCode(interp, "TCL", "ARGUMENT", "MISSING", NULL);
+		sortInfo.resultCode = TCL_ERROR;
+		goto done2;
+	    }
+	    if (Tcl_GetIntFromObj(interp, objv[i+1], &groupSize) != TCL_OK) {
+		sortInfo.resultCode = TCL_ERROR;
+		goto done2;
+	    }
+	    if (groupSize < 2) {
+		Tcl_SetObjResult(interp, Tcl_NewStringObj(
+			"stride length must be at least 2", -1));
+		Tcl_SetErrorCode(interp, "TCL", "OPERATION", "LSORT",
+			"BADSTRIDE", NULL);
+		sortInfo.resultCode = TCL_ERROR;
+		goto done2;
+	    }
+	    group = 1;
+	    i++;
+	    break;
+	}
+    }
+    if (nocase && (sortInfo.sortMode == SORTMODE_ASCII)) {
+	sortInfo.sortMode = SORTMODE_ASCII_NC;
+    }
+
+    /*
+     * Now extract the -index list for real, if present. No failures are
+     * expected here; the values are all of the right type or convertible to
+     * it.
+     */
+
+    if (indexPtr) {
+	Tcl_Obj **indexv;
+
+	TclListObjGetElements(interp, indexPtr, &sortInfo.indexc, &indexv);
+	switch (sortInfo.indexc) {
+	case 0:
+	    sortInfo.indexv = NULL;
+	    break;
+	case 1:
+	    sortInfo.indexv = &sortInfo.singleIndex;
+	    break;
+	default:
+	    sortInfo.indexv =
+		    TclStackAlloc(interp, sizeof(int) * sortInfo.indexc);
+	    allocatedIndexVector = 1;	/* Cannot use indexc field, as it
+					 * might be decreased by 1 later. */
+	}
+	for (j=0 ; j<sortInfo.indexc ; j++) {
+	    TclGetIntForIndexM(interp, indexv[j], SORTIDX_END,
+		    &sortInfo.indexv[j]);
+	}
+    }
+
+    listObj = objv[objc-1];
+
+    if (sortInfo.sortMode == SORTMODE_COMMAND) {
+	Tcl_Obj *newCommandPtr, *newObjPtr;
+
+	/*
+	 * When sorting using a command, we are reentrant and therefore might
+	 * have the representation of the list being sorted shimmered out from
+	 * underneath our feet. Take a copy (cheap) to prevent this. [Bug
+	 * 1675116]
+	 */
+
+	listObj = TclListObjCopy(interp, listObj);
+	if (listObj == NULL) {
+	    sortInfo.resultCode = TCL_ERROR;
+	    goto done2;
+	}
+
+	/*
+	 * The existing command is a list. We want to flatten it, append two
+	 * dummy arguments on the end, and replace these arguments later.
+	 */
+
+	newCommandPtr = Tcl_DuplicateObj(cmdPtr);
+	TclNewObj(newObjPtr);
+	Tcl_IncrRefCount(newCommandPtr);
+	if (Tcl_ListObjAppendElement(interp, newCommandPtr, newObjPtr)
+		!= TCL_OK) {
+	    TclDecrRefCount(newCommandPtr);
+	    TclDecrRefCount(listObj);
+	    Tcl_IncrRefCount(newObjPtr);
+	    TclDecrRefCount(newObjPtr);
+	    sortInfo.resultCode = TCL_ERROR;
+	    goto done2;
+	}
+	Tcl_ListObjAppendElement(interp, newCommandPtr, Tcl_NewObj());
+	sortInfo.compareCmdPtr = newCommandPtr;
+    }
+
+    sortInfo.resultCode = TclListObjGetElements(interp, listObj,
+	    &length, &listObjPtrs);
+    if (sortInfo.resultCode != TCL_OK || length <= 0) {
+	goto done;
+    }
+
+    /*
+     * Check for sanity when grouping elements of the overall list together
+     * because of the -stride option. [TIP #326]
+     */
+
+    if (group) {
+	if (length % groupSize) {
+	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		    "list size must be a multiple of the stride length",
+		    -1));
+	    Tcl_SetErrorCode(interp, "TCL", "OPERATION", "LSORT", "BADSTRIDE",
+		    NULL);
+	    sortInfo.resultCode = TCL_ERROR;
+	    goto done;
+	}
+	length = length / groupSize;
+	if (sortInfo.indexc > 0) {
+	    /*
+	     * Use the first value in the list supplied to -index as the
+	     * offset of the element within each group by which to sort.
+	     */
+
+	    groupOffset = sortInfo.indexv[0];
+	    if (groupOffset <= SORTIDX_END) {
+		groupOffset = (groupOffset - SORTIDX_END) + groupSize - 1;
+	    }
+	    if (groupOffset < 0 || groupOffset >= groupSize) {
+		Tcl_SetObjResult(interp, Tcl_NewStringObj(
+			"when used with \"-stride\", the leading \"-index\""
+			" value must be within the group", -1));
+		Tcl_SetErrorCode(interp, "TCL", "OPERATION", "LSORT",
+			"BADINDEX", NULL);
+		sortInfo.resultCode = TCL_ERROR;
+		goto done;
+	    }
+	    if (sortInfo.indexc == 1) {
+		sortInfo.indexc = 0;
+		sortInfo.indexv = NULL;
+	    } else {
+		sortInfo.indexc--;
+
+		/*
+		 * Do not shrink the actual memory block used; that doesn't
+		 * work with TclStackAlloc-allocated memory. [Bug 2918962]
+		 */
+
+		for (i = 0; i < sortInfo.indexc; i++) {
+		    sortInfo.indexv[i] = sortInfo.indexv[i+1];
+		}
+	    }
+	}
+    }
+
+    sortInfo.numElements = length;
+
+    indexc = sortInfo.indexc;
+    sortMode = sortInfo.sortMode;
+    if ((sortMode == SORTMODE_ASCII_NC)
+	    || (sortMode == SORTMODE_DICTIONARY)) {
+	/*
+	 * For this function's purpose all string-based modes are equivalent
+	 */
+
+	sortMode = SORTMODE_ASCII;
+    }
+
+    /*
+     * Initialize the sublists. After the following loop, subList[i] will
+     * contain a sorted sublist of length 2**i. Use one extra subList at the
+     * end, always at NULL, to indicate the end of the lists.
+     */
+
+    for (j=0 ; j<=NUM_LISTS ; j++) {
+	subList[j] = NULL;
+    }
+
+    /*
+     * The following loop creates a SortElement for each list element and
+     * begins sorting it into the sublists as it appears.
+     */
+
+    elementArray = TclStackAlloc(interp, length * sizeof(SortElement));
+
+    for (i=0; i < length; i++){
+	idx = groupSize * i + groupOffset;
+	if (indexc) {
+	    /*
+	     * If this is an indexed sort, retrieve the corresponding element
+	     */
+	    indexPtr = SelectObjFromSublist(listObjPtrs[idx], &sortInfo);
+	    if (sortInfo.resultCode != TCL_OK) {
+		goto done1;
+	    }
+	} else {
+	    indexPtr = listObjPtrs[idx];
+	}
+
+	/*
+	 * Determine the "value" of this object for sorting purposes
+	 */
+
+	if (sortMode == SORTMODE_ASCII) {
+	    elementArray[i].collationKey.strValuePtr = TclGetString(indexPtr);
+	} else if (sortMode == SORTMODE_INTEGER) {
+	    Tcl_WideInt a;
+
+	    if (TclGetWideIntFromObj(sortInfo.interp, indexPtr, &a) != TCL_OK) {
+		sortInfo.resultCode = TCL_ERROR;
+		goto done1;
+	    }
+	    elementArray[i].collationKey.wideValue = a;
+	} else if (sortMode == SORTMODE_REAL) {
+	    double a;
+
+	    if (Tcl_GetDoubleFromObj(sortInfo.interp, indexPtr,
+		    &a) != TCL_OK) {
+		sortInfo.resultCode = TCL_ERROR;
+		goto done1;
+	    }
+	    elementArray[i].collationKey.doubleValue = a;
+	} else {
+	    elementArray[i].collationKey.objValuePtr = indexPtr;
+	}
+
+	/*
+	 * Determine the representation of this element in the result: either
+	 * the objPtr itself, or its index in the original list.
+	 */
+
+	if (indices || group) {
+	    elementArray[i].payload.index = idx;
+	} else {
+	    elementArray[i].payload.objPtr = listObjPtrs[idx];
+	}
+
+	/*
+	 * Merge this element in the pre-existing sublists (and merge together
+	 * sublists when we have two of the same size).
+	 */
+
+	elementArray[i].nextPtr = NULL;
+	elementPtr = &elementArray[i];
+	for (j=0 ; subList[j] ; j++) {
+	    elementPtr = MergeLists(subList[j], elementPtr, &sortInfo);
+	    subList[j] = NULL;
+	}
+	if (j >= NUM_LISTS) {
+	    j = NUM_LISTS-1;
+	}
+	subList[j] = elementPtr;
+    }
+
+    /*
+     * Merge all sublists
+     */
+
+    elementPtr = subList[0];
+    for (j=1 ; j<NUM_LISTS ; j++) {
+	elementPtr = MergeLists(subList[j], elementPtr, &sortInfo);
+    }
+
+    /*
+     * Now store the sorted elements in the result list.
+     */
+
+    if (sortInfo.resultCode == TCL_OK) {
+	List *listRepPtr;
+	Tcl_Obj **newArray, *objPtr;
+
+	resultPtr = Tcl_NewListObj(sortInfo.numElements * groupSize, NULL);
+	listRepPtr = ListRepPtr(resultPtr);
+	newArray = &listRepPtr->elements;
+	if (group) {
+	    for (i=0; elementPtr!=NULL ; elementPtr=elementPtr->nextPtr) {
+		idx = elementPtr->payload.index;
+		for (j = 0; j < groupSize; j++) {
+		    if (indices) {
+			objPtr = Tcl_NewIntObj(idx + j - groupOffset);
+			newArray[i++] = objPtr;
+			Tcl_IncrRefCount(objPtr);
+		    } else {
+			objPtr = listObjPtrs[idx + j - groupOffset];
+			newArray[i++] = objPtr;
+			Tcl_IncrRefCount(objPtr);
+		    }
+		}
+	    }
+	} else if (indices) {
+	    for (i=0; elementPtr != NULL ; elementPtr = elementPtr->nextPtr) {
+		objPtr = Tcl_NewIntObj(elementPtr->payload.index);
+		newArray[i++] = objPtr;
+		Tcl_IncrRefCount(objPtr);
+	    }
+	} else {
+	    for (i=0; elementPtr != NULL ; elementPtr = elementPtr->nextPtr) {
+		objPtr = elementPtr->payload.objPtr;
+		newArray[i++] = objPtr;
+		Tcl_IncrRefCount(objPtr);
+	    }
+	}
+	listRepPtr->elemCount = i;
+	Tcl_SetObjResult(interp, resultPtr);
+    }
+
+  done1:
+    TclStackFree(interp, elementArray);
+
+  done:
+    if (sortMode == SORTMODE_COMMAND) {
+	TclDecrRefCount(sortInfo.compareCmdPtr);
+	TclDecrRefCount(listObj);
+	sortInfo.compareCmdPtr = NULL;
+    }
+  done2:
+    if (allocatedIndexVector) {
+	TclStackFree(interp, sortInfo.indexv);
+    }
+    return sortInfo.resultCode;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * MergeLists -
+ *
+ *	This procedure combines two sorted lists of SortElement structures
+ *	into a single sorted list.
+ *
+ * Results:
+ *	The unified list of SortElement structures.
+ *
+ * Side effects:
+ *	If infoPtr->unique is set then infoPtr->numElements may be updated.
+ *	Possibly others, if a user-defined comparison command does something
+ *	weird.
+ *
+ * Note:
+ *	If infoPtr->unique is set, the merge assumes that there are no
+ *	"repeated" elements in each of the left and right lists. In that case,
+ *	if any element of the left list is equivalent to one in the right list
+ *	it is omitted from the merged list.
+ *
+ *	This simplified mechanism works because of the special way our
+ *	MergeSort creates the sublists to be merged and will fail to eliminate
+ *	all repeats in the general case where they are already present in
+ *	either the left or right list. A general code would need to skip
+ *	adjacent initial repeats in the left and right lists before comparing
+ *	their initial elements, at each step.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static SortElement *
+MergeLists(
+    SortElement *leftPtr,	/* First list to be merged; may be NULL. */
+    SortElement *rightPtr,	/* Second list to be merged; may be NULL. */
+    SortInfo *infoPtr)		/* Information needed by the comparison
+				 * operator. */
+{
+    SortElement *headPtr, *tailPtr;
+    int cmp;
+
+    if (leftPtr == NULL) {
+	return rightPtr;
+    }
+    if (rightPtr == NULL) {
+	return leftPtr;
+    }
+    cmp = SortCompare(leftPtr, rightPtr, infoPtr);
+    if (cmp > 0 || (cmp == 0 && infoPtr->unique)) {
+	if (cmp == 0) {
+	    infoPtr->numElements--;
+	    leftPtr = leftPtr->nextPtr;
+	}
+	tailPtr = rightPtr;
+	rightPtr = rightPtr->nextPtr;
+    } else {
+	tailPtr = leftPtr;
+	leftPtr = leftPtr->nextPtr;
+    }
+    headPtr = tailPtr;
+    if (!infoPtr->unique) {
+	while ((leftPtr != NULL) && (rightPtr != NULL)) {
+	    cmp = SortCompare(leftPtr, rightPtr, infoPtr);
+	    if (cmp > 0) {
+		tailPtr->nextPtr = rightPtr;
+		tailPtr = rightPtr;
+		rightPtr = rightPtr->nextPtr;
+	    } else {
+		tailPtr->nextPtr = leftPtr;
+		tailPtr = leftPtr;
+		leftPtr = leftPtr->nextPtr;
+	    }
+	}
+    } else {
+	while ((leftPtr != NULL) && (rightPtr != NULL)) {
+	    cmp = SortCompare(leftPtr, rightPtr, infoPtr);
+	    if (cmp >= 0) {
+		if (cmp == 0) {
+		    infoPtr->numElements--;
+		    leftPtr = leftPtr->nextPtr;
+		}
+		tailPtr->nextPtr = rightPtr;
+		tailPtr = rightPtr;
+		rightPtr = rightPtr->nextPtr;
+	    } else {
+		tailPtr->nextPtr = leftPtr;
+		tailPtr = leftPtr;
+		leftPtr = leftPtr->nextPtr;
+	    }
+	}
+    }
+    if (leftPtr != NULL) {
+	tailPtr->nextPtr = leftPtr;
+    } else {
+	tailPtr->nextPtr = rightPtr;
+    }
+    return headPtr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * SortCompare --
+ *
+ *	This procedure is invoked by MergeLists to determine the proper
+ *	ordering between two elements.
+ *
+ * Results:
+ *	A negative results means the the first element comes before the
+ *	second, and a positive results means that the second element should
+ *	come first. A result of zero means the two elements are equal and it
+ *	doesn't matter which comes first.
+ *
+ * Side effects:
+ *	None, unless a user-defined comparison command does something weird.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+SortCompare(
+    SortElement *elemPtr1, SortElement *elemPtr2,
+				/* Values to be compared. */
+    SortInfo *infoPtr)		/* Information passed from the top-level
+				 * "lsort" command. */
+{
+    int order = 0;
+
+    if (infoPtr->sortMode == SORTMODE_ASCII) {
+	order = strcmp(elemPtr1->collationKey.strValuePtr,
+		elemPtr2->collationKey.strValuePtr);
+    } else if (infoPtr->sortMode == SORTMODE_ASCII_NC) {
+	order = TclUtfCasecmp(elemPtr1->collationKey.strValuePtr,
+		elemPtr2->collationKey.strValuePtr);
+    } else if (infoPtr->sortMode == SORTMODE_DICTIONARY) {
+	order = DictionaryCompare(elemPtr1->collationKey.strValuePtr,
+		elemPtr2->collationKey.strValuePtr);
+    } else if (infoPtr->sortMode == SORTMODE_INTEGER) {
+	Tcl_WideInt a, b;
+
+	a = elemPtr1->collationKey.wideValue;
+	b = elemPtr2->collationKey.wideValue;
+	order = ((a >= b) - (a <= b));
+    } else if (infoPtr->sortMode == SORTMODE_REAL) {
+	double a, b;
+
+	a = elemPtr1->collationKey.doubleValue;
+	b = elemPtr2->collationKey.doubleValue;
+	order = ((a >= b) - (a <= b));
+    } else {
+	Tcl_Obj **objv, *paramObjv[2];
+	int objc;
+	Tcl_Obj *objPtr1, *objPtr2;
+
+	if (infoPtr->resultCode != TCL_OK) {
+	    /*
+	     * Once an error has occurred, skip any future comparisons so as
+	     * to preserve the error message in sortInterp->result.
+	     */
+
+	    return 0;
+	}
+
+
+	objPtr1 = elemPtr1->collationKey.objValuePtr;
+	objPtr2 = elemPtr2->collationKey.objValuePtr;
+
+	paramObjv[0] = objPtr1;
+	paramObjv[1] = objPtr2;
+
+	/*
+	 * We made space in the command list for the two things to compare.
+	 * Replace them and evaluate the result.
+	 */
+
+	TclListObjLength(infoPtr->interp, infoPtr->compareCmdPtr, &objc);
+	Tcl_ListObjReplace(infoPtr->interp, infoPtr->compareCmdPtr, objc - 2,
+		2, 2, paramObjv);
+	TclListObjGetElements(infoPtr->interp, infoPtr->compareCmdPtr,
+		&objc, &objv);
+
+	infoPtr->resultCode = Tcl_EvalObjv(infoPtr->interp, objc, objv, 0);
+
+	if (infoPtr->resultCode != TCL_OK) {
+	    Tcl_AddErrorInfo(infoPtr->interp, "\n    (-compare command)");
+	    return 0;
+	}
+
+	/*
+	 * Parse the result of the command.
+	 */
+
+	if (TclGetIntFromObj(infoPtr->interp,
+		Tcl_GetObjResult(infoPtr->interp), &order) != TCL_OK) {
+	    Tcl_SetObjResult(infoPtr->interp, Tcl_NewStringObj(
+		    "-compare command returned non-integer result", -1));
+	    Tcl_SetErrorCode(infoPtr->interp, "TCL", "OPERATION", "LSORT",
+		    "COMPARISONFAILED", NULL);
+	    infoPtr->resultCode = TCL_ERROR;
+	    return 0;
+	}
+    }
+    if (!infoPtr->isIncreasing) {
+	order = -order;
+    }
+    return order;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * DictionaryCompare
+ *
+ *	This function compares two strings as if they were being used in an
+ *	index or card catalog. The case of alphabetic characters is ignored,
+ *	except to break ties. Thus "B" comes before "b" but after "a". Also,
+ *	integers embedded in the strings compare in numerical order. In other
+ *	words, "x10y" comes after "x9y", not * before it as it would when
+ *	using strcmp().
+ *
+ * Results:
+ *	A negative result means that the first element comes before the
+ *	second, and a positive result means that the second element should
+ *	come first. A result of zero means the two elements are equal and it
+ *	doesn't matter which comes first.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+DictionaryCompare(
+    const char *left, const char *right)	/* The strings to compare. */
+{
+    Tcl_UniChar uniLeft, uniRight, uniLeftLower, uniRightLower;
+    int diff, zeros;
+    int secondaryDiff = 0;
+
+    while (1) {
+	if (isdigit(UCHAR(*right))		/* INTL: digit */
+		&& isdigit(UCHAR(*left))) {	/* INTL: digit */
+	    /*
+	     * There are decimal numbers embedded in the two strings. Compare
+	     * them as numbers, rather than strings. If one number has more
+	     * leading zeros than the other, the number with more leading
+	     * zeros sorts later, but only as a secondary choice.
+	     */
+
+	    zeros = 0;
+	    while ((*right == '0') && isdigit(UCHAR(right[1]))) {
+		right++;
+		zeros--;
+	    }
+	    while ((*left == '0') && isdigit(UCHAR(left[1]))) {
+		left++;
+		zeros++;
+	    }
+	    if (secondaryDiff == 0) {
+		secondaryDiff = zeros;
+	    }
+
+	    /*
+	     * The code below compares the numbers in the two strings without
+	     * ever converting them to integers. It does this by first
+	     * comparing the lengths of the numbers and then comparing the
+	     * digit values.
+	     */
+
+	    diff = 0;
+	    while (1) {
+		if (diff == 0) {
+		    diff = UCHAR(*left) - UCHAR(*right);
+		}
+		right++;
+		left++;
+		if (!isdigit(UCHAR(*right))) {		/* INTL: digit */
+		    if (isdigit(UCHAR(*left))) {	/* INTL: digit */
+			return 1;
+		    } else {
+			/*
+			 * The two numbers have the same length. See if their
+			 * values are different.
+			 */
+
+			if (diff != 0) {
+			    return diff;
+			}
+			break;
+		    }
+		} else if (!isdigit(UCHAR(*left))) {	/* INTL: digit */
+		    return -1;
+		}
+	    }
+	    continue;
+	}
+
+	/*
+	 * Convert character to Unicode for comparison purposes. If either
+	 * string is at the terminating null, do a byte-wise comparison and
+	 * bail out immediately.
+	 */
+
+	if ((*left != '\0') && (*right != '\0')) {
+	    left += Tcl_UtfToUniChar(left, &uniLeft);
+	    right += Tcl_UtfToUniChar(right, &uniRight);
+
+	    /*
+	     * Convert both chars to lower for the comparison, because
+	     * dictionary sorts are case insensitve. Covert to lower, not
+	     * upper, so chars between Z and a will sort before A (where most
+	     * other interesting punctuations occur).
+	     */
+
+	    uniLeftLower = Tcl_UniCharToLower(uniLeft);
+	    uniRightLower = Tcl_UniCharToLower(uniRight);
+	} else {
+	    diff = UCHAR(*left) - UCHAR(*right);
+	    break;
+	}
+
+	diff = uniLeftLower - uniRightLower;
+	if (diff) {
+	    return diff;
+	}
+	if (secondaryDiff == 0) {
+	    if (Tcl_UniCharIsUpper(uniLeft) && Tcl_UniCharIsLower(uniRight)) {
+		secondaryDiff = -1;
+	    } else if (Tcl_UniCharIsUpper(uniRight)
+		    && Tcl_UniCharIsLower(uniLeft)) {
+		secondaryDiff = 1;
+	    }
+	}
+    }
+    if (diff == 0) {
+	diff = secondaryDiff;
+    }
+    return diff;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * SelectObjFromSublist --
+ *
+ *	This procedure is invoked from lsearch and SortCompare. It is used for
+ *	implementing the -index option, for the lsort and lsearch commands.
+ *
+ * Results:
+ *	Returns NULL if a failure occurs, and sets the result in the infoPtr.
+ *	Otherwise returns the Tcl_Obj* to the item.
+ *
+ * Side effects:
+ *	None.
+ *
+ * Note:
+ *	No reference counting is done, as the result is only used internally
+ *	and never passed directly to user code.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static Tcl_Obj *
+SelectObjFromSublist(
+    Tcl_Obj *objPtr,		/* Obj to select sublist from. */
+    SortInfo *infoPtr)		/* Information passed from the top-level
+				 * "lsearch" or "lsort" command. */
+{
+    int i;
+
+    /*
+     * Quick check for case when no "-index" option is there.
+     */
+
+    if (infoPtr->indexc == 0) {
+	return objPtr;
+    }
+
+    /*
+     * Iterate over the indices, traversing through the nested sublists as we
+     * go.
+     */
+
+    for (i=0 ; i<infoPtr->indexc ; i++) {
+	int listLen, index;
+	Tcl_Obj *currentObj;
+
+	if (TclListObjLength(infoPtr->interp, objPtr, &listLen) != TCL_OK) {
+	    infoPtr->resultCode = TCL_ERROR;
+	    return NULL;
+	}
+	index = infoPtr->indexv[i];
+
+	/*
+	 * Adjust for end-based indexing.
+	 */
+
+	if (index < SORTIDX_NONE) {
+	    index += listLen + 1;
+	}
+
+	if (Tcl_ListObjIndex(infoPtr->interp, objPtr, index,
+		&currentObj) != TCL_OK) {
+	    infoPtr->resultCode = TCL_ERROR;
+	    return NULL;
+	}
+	if (currentObj == NULL) {
+	    Tcl_SetObjResult(infoPtr->interp, Tcl_ObjPrintf(
+		    "element %d missing from sublist \"%s\"",
+		    index, TclGetString(objPtr)));
+	    Tcl_SetErrorCode(infoPtr->interp, "TCL", "OPERATION", "LSORT",
+		    "INDEXFAILED", NULL);
+	    infoPtr->resultCode = TCL_ERROR;
+	    return NULL;
+	}
+	objPtr = currentObj;
+    }
+    return objPtr;
+}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * tab-width: 8
+ * End:
+ */
diff --git a/generic/tclCmdMZ.c b/generic/tclCmdMZ.c
new file mode 100644
index 0000000..885a0bc
--- /dev/null
+++ b/generic/tclCmdMZ.c
@@ -0,0 +1,4881 @@
+/*
+ * tclCmdMZ.c --
+ *
+ *	This file contains the top-level command routines for most of the Tcl
+ *	built-in commands whose names begin with the letters M to Z. It
+ *	contains only commands in the generic core (i.e. those that don't
+ *	depend much upon UNIX facilities).
+ *
+ * Copyright (c) 1987-1993 The Regents of the University of California.
+ * Copyright (c) 1994-1997 Sun Microsystems, Inc.
+ * Copyright (c) 1998-2000 Scriptics Corporation.
+ * Copyright (c) 2002 ActiveState Corporation.
+ * Copyright (c) 2003-2009 Donal K. Fellows.
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#include "tclInt.h"
+#include "tclRegexp.h"
+#include "tclStringTrim.h"
+
+static inline Tcl_Obj *	During(Tcl_Interp *interp, int resultCode,
+			    Tcl_Obj *oldOptions, Tcl_Obj *errorInfo);
+static Tcl_NRPostProc	SwitchPostProc;
+static Tcl_NRPostProc	TryPostBody;
+static Tcl_NRPostProc	TryPostFinal;
+static Tcl_NRPostProc	TryPostHandler;
+static int		UniCharIsAscii(int character);
+static int		UniCharIsHexDigit(int character);
+
+/*
+ * Default set of characters to trim in [string trim] and friends. This is a
+ * UTF-8 literal string containing all Unicode space characters [TIP #413]
+ */
+
+const char tclDefaultTrimSet[] =
+	"\x09\x0a\x0b\x0c\x0d " /* ASCII */
+	"\xc0\x80" /*     nul (U+0000) */
+	"\xc2\x85" /*     next line (U+0085) */
+	"\xc2\xa0" /*     non-breaking space (U+00a0) */
+	"\xe1\x9a\x80" /* ogham space mark (U+1680) */
+	"\xe1\xa0\x8e" /* mongolian vowel separator (U+180e) */
+	"\xe2\x80\x80" /* en quad (U+2000) */
+	"\xe2\x80\x81" /* em quad (U+2001) */
+	"\xe2\x80\x82" /* en space (U+2002) */
+	"\xe2\x80\x83" /* em space (U+2003) */
+	"\xe2\x80\x84" /* three-per-em space (U+2004) */
+	"\xe2\x80\x85" /* four-per-em space (U+2005) */
+	"\xe2\x80\x86" /* six-per-em space (U+2006) */
+	"\xe2\x80\x87" /* figure space (U+2007) */
+	"\xe2\x80\x88" /* punctuation space (U+2008) */
+	"\xe2\x80\x89" /* thin space (U+2009) */
+	"\xe2\x80\x8a" /* hair space (U+200a) */
+	"\xe2\x80\x8b" /* zero width space (U+200b) */
+	"\xe2\x80\xa8" /* line separator (U+2028) */
+	"\xe2\x80\xa9" /* paragraph separator (U+2029) */
+	"\xe2\x80\xaf" /* narrow no-break space (U+202f) */
+	"\xe2\x81\x9f" /* medium mathematical space (U+205f) */
+	"\xe2\x81\xa0" /* word joiner (U+2060) */
+	"\xe3\x80\x80" /* ideographic space (U+3000) */
+	"\xef\xbb\xbf" /* zero width no-break space (U+feff) */
+;
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_PwdObjCmd --
+ *
+ *	This procedure is invoked to process the "pwd" Tcl command. See the
+ *	user documentation for details on what it does.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_PwdObjCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    Tcl_Obj *retVal;
+
+    if (objc != 1) {
+	Tcl_WrongNumArgs(interp, 1, objv, NULL);
+	return TCL_ERROR;
+    }
+
+    retVal = Tcl_FSGetCwd(interp);
+    if (retVal == NULL) {
+	return TCL_ERROR;
+    }
+    Tcl_SetObjResult(interp, retVal);
+    Tcl_DecrRefCount(retVal);
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_RegexpObjCmd --
+ *
+ *	This procedure is invoked to process the "regexp" Tcl command. See
+ *	the user documentation for details on what it does.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_RegexpObjCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    int i, indices, match, about, offset, all, doinline, numMatchesSaved;
+    int cflags, eflags, stringLength, matchLength;
+    Tcl_RegExp regExpr;
+    Tcl_Obj *objPtr, *startIndex = NULL, *resultPtr = NULL;
+    Tcl_RegExpInfo info;
+    static const char *const options[] = {
+	"-all",		"-about",	"-indices",	"-inline",
+	"-expanded",	"-line",	"-linestop",	"-lineanchor",
+	"-nocase",	"-start",	"--",		NULL
+    };
+    enum options {
+	REGEXP_ALL,	REGEXP_ABOUT,	REGEXP_INDICES,	REGEXP_INLINE,
+	REGEXP_EXPANDED,REGEXP_LINE,	REGEXP_LINESTOP,REGEXP_LINEANCHOR,
+	REGEXP_NOCASE,	REGEXP_START,	REGEXP_LAST
+    };
+
+    indices = 0;
+    about = 0;
+    cflags = TCL_REG_ADVANCED;
+    offset = 0;
+    all = 0;
+    doinline = 0;
+
+    for (i = 1; i < objc; i++) {
+	const char *name;
+	int index;
+
+	name = TclGetString(objv[i]);
+	if (name[0] != '-') {
+	    break;
+	}
+	if (Tcl_GetIndexFromObj(interp, objv[i], options, "option", TCL_EXACT,
+		&index) != TCL_OK) {
+	    goto optionError;
+	}
+	switch ((enum options) index) {
+	case REGEXP_ALL:
+	    all = 1;
+	    break;
+	case REGEXP_INDICES:
+	    indices = 1;
+	    break;
+	case REGEXP_INLINE:
+	    doinline = 1;
+	    break;
+	case REGEXP_NOCASE:
+	    cflags |= TCL_REG_NOCASE;
+	    break;
+	case REGEXP_ABOUT:
+	    about = 1;
+	    break;
+	case REGEXP_EXPANDED:
+	    cflags |= TCL_REG_EXPANDED;
+	    break;
+	case REGEXP_LINE:
+	    cflags |= TCL_REG_NEWLINE;
+	    break;
+	case REGEXP_LINESTOP:
+	    cflags |= TCL_REG_NLSTOP;
+	    break;
+	case REGEXP_LINEANCHOR:
+	    cflags |= TCL_REG_NLANCH;
+	    break;
+	case REGEXP_START: {
+	    int temp;
+	    if (++i >= objc) {
+		goto endOfForLoop;
+	    }
+	    if (TclGetIntForIndexM(interp, objv[i], 0, &temp) != TCL_OK) {
+		goto optionError;
+	    }
+	    if (startIndex) {
+		Tcl_DecrRefCount(startIndex);
+	    }
+	    startIndex = objv[i];
+	    Tcl_IncrRefCount(startIndex);
+	    break;
+	}
+	case REGEXP_LAST:
+	    i++;
+	    goto endOfForLoop;
+	}
+    }
+
+  endOfForLoop:
+    if ((objc - i) < (2 - about)) {
+	Tcl_WrongNumArgs(interp, 1, objv,
+		"?-option ...? exp string ?matchVar? ?subMatchVar ...?");
+	goto optionError;
+    }
+    objc -= i;
+    objv += i;
+
+    /*
+     * Check if the user requested -inline, but specified match variables; a
+     * no-no.
+     */
+
+    if (doinline && ((objc - 2) != 0)) {
+	Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		"regexp match variables not allowed when using -inline", -1));
+	Tcl_SetErrorCode(interp, "TCL", "OPERATION", "REGEXP",
+		"MIX_VAR_INLINE", NULL);
+	goto optionError;
+    }
+
+    /*
+     * Handle the odd about case separately.
+     */
+
+    if (about) {
+	regExpr = Tcl_GetRegExpFromObj(interp, objv[0], cflags);
+	if ((regExpr == NULL) || (TclRegAbout(interp, regExpr) < 0)) {
+	optionError:
+	    if (startIndex) {
+		Tcl_DecrRefCount(startIndex);
+	    }
+	    return TCL_ERROR;
+	}
+	return TCL_OK;
+    }
+
+    /*
+     * Get the length of the string that we are matching against so we can do
+     * the termination test for -all matches. Do this before getting the
+     * regexp to avoid shimmering problems.
+     */
+
+    objPtr = objv[1];
+    stringLength = Tcl_GetCharLength(objPtr);
+
+    if (startIndex) {
+	TclGetIntForIndexM(NULL, startIndex, stringLength, &offset);
+	Tcl_DecrRefCount(startIndex);
+	if (offset < 0) {
+	    offset = 0;
+	}
+    }
+
+    regExpr = Tcl_GetRegExpFromObj(interp, objv[0], cflags);
+    if (regExpr == NULL) {
+	return TCL_ERROR;
+    }
+
+    objc -= 2;
+    objv += 2;
+
+    if (doinline) {
+	/*
+	 * Save all the subexpressions, as we will return them as a list
+	 */
+
+	numMatchesSaved = -1;
+    } else {
+	/*
+	 * Save only enough subexpressions for matches we want to keep, expect
+	 * in the case of -all, where we need to keep at least one to know
+	 * where to move the offset.
+	 */
+
+	numMatchesSaved = (objc == 0) ? all : objc;
+    }
+
+    /*
+     * The following loop is to handle multiple matches within the same source
+     * string; each iteration handles one match. If "-all" hasn't been
+     * specified then the loop body only gets executed once. We terminate the
+     * loop when the starting offset is past the end of the string.
+     */
+
+    while (1) {
+	/*
+	 * Pass either 0 or TCL_REG_NOTBOL in the eflags. Passing
+	 * TCL_REG_NOTBOL indicates that the character at offset should not be
+	 * considered the start of the line. If for example the pattern {^} is
+	 * passed and -start is positive, then the pattern will not match the
+	 * start of the string unless the previous character is a newline.
+	 */
+
+	if (offset == 0) {
+	    eflags = 0;
+	} else if (offset > stringLength) {
+	    eflags = TCL_REG_NOTBOL;
+	} else if (Tcl_GetUniChar(objPtr, offset-1) == (Tcl_UniChar)'\n') {
+	    eflags = 0;
+	} else {
+	    eflags = TCL_REG_NOTBOL;
+	}
+
+	match = Tcl_RegExpExecObj(interp, regExpr, objPtr, offset,
+		numMatchesSaved, eflags);
+	if (match < 0) {
+	    return TCL_ERROR;
+	}
+
+	if (match == 0) {
+	    /*
+	     * We want to set the value of the intepreter result only when
+	     * this is the first time through the loop.
+	     */
+
+	    if (all <= 1) {
+		/*
+		 * If inlining, the interpreter's object result remains an
+		 * empty list, otherwise set it to an integer object w/ value
+		 * 0.
+		 */
+
+		if (!doinline) {
+		    Tcl_SetObjResult(interp, Tcl_NewIntObj(0));
+		}
+		return TCL_OK;
+	    }
+	    break;
+	}
+
+	/*
+	 * If additional variable names have been specified, return index
+	 * information in those variables.
+	 */
+
+	Tcl_RegExpGetInfo(regExpr, &info);
+	if (doinline) {
+	    /*
+	     * It's the number of substitutions, plus one for the matchVar at
+	     * index 0
+	     */
+
+	    objc = info.nsubs + 1;
+	    if (all <= 1) {
+		resultPtr = Tcl_NewObj();
+	    }
+	}
+	for (i = 0; i < objc; i++) {
+	    Tcl_Obj *newPtr;
+
+	    if (indices) {
+		int start, end;
+		Tcl_Obj *objs[2];
+
+		/*
+		 * Only adjust the match area if there was a match for that
+		 * area. (Scriptics Bug 4391/SF Bug #219232)
+		 */
+
+		if (i <= info.nsubs && info.matches[i].start >= 0) {
+		    start = offset + info.matches[i].start;
+		    end = offset + info.matches[i].end;
+
+		    /*
+		     * Adjust index so it refers to the last character in the
+		     * match instead of the first character after the match.
+		     */
+
+		    if (end >= offset) {
+			end--;
+		    }
+		} else {
+		    start = -1;
+		    end = -1;
+		}
+
+		objs[0] = Tcl_NewLongObj(start);
+		objs[1] = Tcl_NewLongObj(end);
+
+		newPtr = Tcl_NewListObj(2, objs);
+	    } else {
+		if (i <= info.nsubs) {
+		    newPtr = Tcl_GetRange(objPtr,
+			    offset + info.matches[i].start,
+			    offset + info.matches[i].end - 1);
+		} else {
+		    newPtr = Tcl_NewObj();
+		}
+	    }
+	    if (doinline) {
+		if (Tcl_ListObjAppendElement(interp, resultPtr, newPtr)
+			!= TCL_OK) {
+		    Tcl_DecrRefCount(newPtr);
+		    Tcl_DecrRefCount(resultPtr);
+		    return TCL_ERROR;
+		}
+	    } else {
+		if (Tcl_ObjSetVar2(interp, objv[i], NULL, newPtr,
+			TCL_LEAVE_ERR_MSG) == NULL) {
+		    return TCL_ERROR;
+		}
+	    }
+	}
+
+	if (all == 0) {
+	    break;
+	}
+
+	/*
+	 * Adjust the offset to the character just after the last one in the
+	 * matchVar and increment all to count how many times we are making a
+	 * match. We always increment the offset by at least one to prevent
+	 * endless looping (as in the case: regexp -all {a*} a). Otherwise,
+	 * when we match the NULL string at the end of the input string, we
+	 * will loop indefinately (because the length of the match is 0, so
+	 * offset never changes).
+	 */
+
+	matchLength = (info.matches[0].end - info.matches[0].start);
+
+	offset += info.matches[0].end;
+
+	/*
+	 * A match of length zero could happen for {^} {$} or {.*} and in
+	 * these cases we always want to bump the index up one.
+	 */
+
+	if (matchLength == 0) {
+	    offset++;
+	}
+	all++;
+	if (offset >= stringLength) {
+	    break;
+	}
+    }
+
+    /*
+     * Set the interpreter's object result to an integer object with value 1
+     * if -all wasn't specified, otherwise it's all-1 (the number of times
+     * through the while - 1).
+     */
+
+    if (doinline) {
+	Tcl_SetObjResult(interp, resultPtr);
+    } else {
+	Tcl_SetObjResult(interp, Tcl_NewIntObj(all ? all-1 : 1));
+    }
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_RegsubObjCmd --
+ *
+ *	This procedure is invoked to process the "regsub" Tcl command. See the
+ *	user documentation for details on what it does.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_RegsubObjCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    int idx, result, cflags, all, wlen, wsublen, numMatches, offset;
+    int start, end, subStart, subEnd, match;
+    Tcl_RegExp regExpr;
+    Tcl_RegExpInfo info;
+    Tcl_Obj *resultPtr, *subPtr, *objPtr, *startIndex = NULL;
+    Tcl_UniChar ch, *wsrc, *wfirstChar, *wstring, *wsubspec, *wend;
+
+    static const char *const options[] = {
+	"-all",		"-nocase",	"-expanded",
+	"-line",	"-linestop",	"-lineanchor",	"-start",
+	"--",		NULL
+    };
+    enum options {
+	REGSUB_ALL,	REGSUB_NOCASE,	REGSUB_EXPANDED,
+	REGSUB_LINE,	REGSUB_LINESTOP, REGSUB_LINEANCHOR,	REGSUB_START,
+	REGSUB_LAST
+    };
+
+    cflags = TCL_REG_ADVANCED;
+    all = 0;
+    offset = 0;
+    resultPtr = NULL;
+
+    for (idx = 1; idx < objc; idx++) {
+	const char *name;
+	int index;
+
+	name = TclGetString(objv[idx]);
+	if (name[0] != '-') {
+	    break;
+	}
+	if (Tcl_GetIndexFromObj(interp, objv[idx], options, "option",
+		TCL_EXACT, &index) != TCL_OK) {
+	    goto optionError;
+	}
+	switch ((enum options) index) {
+	case REGSUB_ALL:
+	    all = 1;
+	    break;
+	case REGSUB_NOCASE:
+	    cflags |= TCL_REG_NOCASE;
+	    break;
+	case REGSUB_EXPANDED:
+	    cflags |= TCL_REG_EXPANDED;
+	    break;
+	case REGSUB_LINE:
+	    cflags |= TCL_REG_NEWLINE;
+	    break;
+	case REGSUB_LINESTOP:
+	    cflags |= TCL_REG_NLSTOP;
+	    break;
+	case REGSUB_LINEANCHOR:
+	    cflags |= TCL_REG_NLANCH;
+	    break;
+	case REGSUB_START: {
+	    int temp;
+	    if (++idx >= objc) {
+		goto endOfForLoop;
+	    }
+	    if (TclGetIntForIndexM(interp, objv[idx], 0, &temp) != TCL_OK) {
+		goto optionError;
+	    }
+	    if (startIndex) {
+		Tcl_DecrRefCount(startIndex);
+	    }
+	    startIndex = objv[idx];
+	    Tcl_IncrRefCount(startIndex);
+	    break;
+	}
+	case REGSUB_LAST:
+	    idx++;
+	    goto endOfForLoop;
+	}
+    }
+
+  endOfForLoop:
+    if (objc-idx < 3 || objc-idx > 4) {
+	Tcl_WrongNumArgs(interp, 1, objv,
+		"?-option ...? exp string subSpec ?varName?");
+    optionError:
+	if (startIndex) {
+	    Tcl_DecrRefCount(startIndex);
+	}
+	return TCL_ERROR;
+    }
+
+    objc -= idx;
+    objv += idx;
+
+    if (startIndex) {
+	int stringLength = Tcl_GetCharLength(objv[1]);
+
+	TclGetIntForIndexM(NULL, startIndex, stringLength, &offset);
+	Tcl_DecrRefCount(startIndex);
+	if (offset < 0) {
+	    offset = 0;
+	}
+    }
+
+    if (all && (offset == 0)
+	    && (strpbrk(TclGetString(objv[2]), "&\\") == NULL)
+	    && (strpbrk(TclGetString(objv[0]), "*+?{}()[].\\|^$") == NULL)) {
+	/*
+	 * This is a simple one pair string map situation. We make use of a
+	 * slightly modified version of the one pair STR_MAP code.
+	 */
+
+	int slen, nocase;
+	int (*strCmpFn)(const Tcl_UniChar*,const Tcl_UniChar*,unsigned long);
+	Tcl_UniChar *p, wsrclc;
+
+	numMatches = 0;
+	nocase = (cflags & TCL_REG_NOCASE);
+	strCmpFn = nocase ? Tcl_UniCharNcasecmp : Tcl_UniCharNcmp;
+
+	wsrc = Tcl_GetUnicodeFromObj(objv[0], &slen);
+	wstring = Tcl_GetUnicodeFromObj(objv[1], &wlen);
+	wsubspec = Tcl_GetUnicodeFromObj(objv[2], &wsublen);
+	wend = wstring + wlen - (slen ? slen - 1 : 0);
+	result = TCL_OK;
+
+	if (slen == 0) {
+	    /*
+	     * regsub behavior for "" matches between each character. 'string
+	     * map' skips the "" case.
+	     */
+
+	    if (wstring < wend) {
+		resultPtr = Tcl_NewUnicodeObj(wstring, 0);
+		Tcl_IncrRefCount(resultPtr);
+		for (; wstring < wend; wstring++) {
+		    Tcl_AppendUnicodeToObj(resultPtr, wsubspec, wsublen);
+		    Tcl_AppendUnicodeToObj(resultPtr, wstring, 1);
+		    numMatches++;
+		}
+		wlen = 0;
+	    }
+	} else {
+	    wsrclc = Tcl_UniCharToLower(*wsrc);
+	    for (p = wfirstChar = wstring; wstring < wend; wstring++) {
+		if ((*wstring == *wsrc ||
+			(nocase && Tcl_UniCharToLower(*wstring)==wsrclc)) &&
+			(slen==1 || (strCmpFn(wstring, wsrc,
+				(unsigned long) slen) == 0))) {
+		    if (numMatches == 0) {
+			resultPtr = Tcl_NewUnicodeObj(wstring, 0);
+			Tcl_IncrRefCount(resultPtr);
+		    }
+		    if (p != wstring) {
+			Tcl_AppendUnicodeToObj(resultPtr, p, wstring - p);
+			p = wstring + slen;
+		    } else {
+			p += slen;
+		    }
+		    wstring = p - 1;
+
+		    Tcl_AppendUnicodeToObj(resultPtr, wsubspec, wsublen);
+		    numMatches++;
+		}
+	    }
+	    if (numMatches) {
+		wlen    = wfirstChar + wlen - p;
+		wstring = p;
+	    }
+	}
+	objPtr = NULL;
+	subPtr = NULL;
+	goto regsubDone;
+    }
+
+    regExpr = Tcl_GetRegExpFromObj(interp, objv[0], cflags);
+    if (regExpr == NULL) {
+	return TCL_ERROR;
+    }
+
+    /*
+     * Make sure to avoid problems where the objects are shared. This can
+     * cause RegExpObj <> UnicodeObj shimmering that causes data corruption.
+     * [Bug #461322]
+     */
+
+    if (objv[1] == objv[0]) {
+	objPtr = Tcl_DuplicateObj(objv[1]);
+    } else {
+	objPtr = objv[1];
+    }
+    wstring = Tcl_GetUnicodeFromObj(objPtr, &wlen);
+    if (objv[2] == objv[0]) {
+	subPtr = Tcl_DuplicateObj(objv[2]);
+    } else {
+	subPtr = objv[2];
+    }
+    wsubspec = Tcl_GetUnicodeFromObj(subPtr, &wsublen);
+
+    result = TCL_OK;
+
+    /*
+     * The following loop is to handle multiple matches within the same source
+     * string; each iteration handles one match and its corresponding
+     * substitution. If "-all" hasn't been specified then the loop body only
+     * gets executed once. We must use 'offset <= wlen' in particular for the
+     * case where the regexp pattern can match the empty string - this is
+     * useful when doing, say, 'regsub -- ^ $str ...' when $str might be
+     * empty.
+     */
+
+    numMatches = 0;
+    for ( ; offset <= wlen; ) {
+
+	/*
+	 * The flags argument is set if string is part of a larger string, so
+	 * that "^" won't match.
+	 */
+
+	match = Tcl_RegExpExecObj(interp, regExpr, objPtr, offset,
+		10 /* matches */, ((offset > 0 &&
+		(wstring[offset-1] != (Tcl_UniChar)'\n'))
+		? TCL_REG_NOTBOL : 0));
+
+	if (match < 0) {
+	    result = TCL_ERROR;
+	    goto done;
+	}
+	if (match == 0) {
+	    break;
+	}
+	if (numMatches == 0) {
+	    resultPtr = Tcl_NewUnicodeObj(wstring, 0);
+	    Tcl_IncrRefCount(resultPtr);
+	    if (offset > 0) {
+		/*
+		 * Copy the initial portion of the string in if an offset was
+		 * specified.
+		 */
+
+		Tcl_AppendUnicodeToObj(resultPtr, wstring, offset);
+	    }
+	}
+	numMatches++;
+
+	/*
+	 * Copy the portion of the source string before the match to the
+	 * result variable.
+	 */
+
+	Tcl_RegExpGetInfo(regExpr, &info);
+	start = info.matches[0].start;
+	end = info.matches[0].end;
+	Tcl_AppendUnicodeToObj(resultPtr, wstring + offset, start);
+
+	/*
+	 * Append the subSpec argument to the variable, making appropriate
+	 * substitutions. This code is a bit hairy because of the backslash
+	 * conventions and because the code saves up ranges of characters in
+	 * subSpec to reduce the number of calls to Tcl_SetVar.
+	 */
+
+	wsrc = wfirstChar = wsubspec;
+	wend = wsubspec + wsublen;
+	for (ch = *wsrc; wsrc != wend; wsrc++, ch = *wsrc) {
+	    if (ch == '&') {
+		idx = 0;
+	    } else if (ch == '\\') {
+		ch = wsrc[1];
+		if ((ch >= '0') && (ch <= '9')) {
+		    idx = ch - '0';
+		} else if ((ch == '\\') || (ch == '&')) {
+		    *wsrc = ch;
+		    Tcl_AppendUnicodeToObj(resultPtr, wfirstChar,
+			    wsrc - wfirstChar + 1);
+		    *wsrc = '\\';
+		    wfirstChar = wsrc + 2;
+		    wsrc++;
+		    continue;
+		} else {
+		    continue;
+		}
+	    } else {
+		continue;
+	    }
+
+	    if (wfirstChar != wsrc) {
+		Tcl_AppendUnicodeToObj(resultPtr, wfirstChar,
+			wsrc - wfirstChar);
+	    }
+
+	    if (idx <= info.nsubs) {
+		subStart = info.matches[idx].start;
+		subEnd = info.matches[idx].end;
+		if ((subStart >= 0) && (subEnd >= 0)) {
+		    Tcl_AppendUnicodeToObj(resultPtr,
+			    wstring + offset + subStart, subEnd - subStart);
+		}
+	    }
+
+	    if (*wsrc == '\\') {
+		wsrc++;
+	    }
+	    wfirstChar = wsrc + 1;
+	}
+
+	if (wfirstChar != wsrc) {
+	    Tcl_AppendUnicodeToObj(resultPtr, wfirstChar, wsrc - wfirstChar);
+	}
+
+	if (end == 0) {
+	    /*
+	     * Always consume at least one character of the input string in
+	     * order to prevent infinite loops.
+	     */
+
+	    if (offset < wlen) {
+		Tcl_AppendUnicodeToObj(resultPtr, wstring + offset, 1);
+	    }
+	    offset++;
+	} else {
+	    offset += end;
+	    if (start == end) {
+		/*
+		 * We matched an empty string, which means we must go forward
+		 * one more step so we don't match again at the same spot.
+		 */
+
+		if (offset < wlen) {
+		    Tcl_AppendUnicodeToObj(resultPtr, wstring + offset, 1);
+		}
+		offset++;
+	    }
+	}
+	if (!all) {
+	    break;
+	}
+    }
+
+    /*
+     * Copy the portion of the source string after the last match to the
+     * result variable.
+     */
+
+  regsubDone:
+    if (numMatches == 0) {
+	/*
+	 * On zero matches, just ignore the offset, since it shouldn't matter
+	 * to us in this case, and the user may have skewed it.
+	 */
+
+	resultPtr = objv[1];
+	Tcl_IncrRefCount(resultPtr);
+    } else if (offset < wlen) {
+	Tcl_AppendUnicodeToObj(resultPtr, wstring + offset, wlen - offset);
+    }
+    if (objc == 4) {
+	if (Tcl_ObjSetVar2(interp, objv[3], NULL, resultPtr,
+		TCL_LEAVE_ERR_MSG) == NULL) {
+	    result = TCL_ERROR;
+	} else {
+	    /*
+	     * Set the interpreter's object result to an integer object
+	     * holding the number of matches.
+	     */
+
+	    Tcl_SetObjResult(interp, Tcl_NewIntObj(numMatches));
+	}
+    } else {
+	/*
+	 * No varname supplied, so just return the modified string.
+	 */
+
+	Tcl_SetObjResult(interp, resultPtr);
+    }
+
+  done:
+    if (objPtr && (objv[1] == objv[0])) {
+	Tcl_DecrRefCount(objPtr);
+    }
+    if (subPtr && (objv[2] == objv[0])) {
+	Tcl_DecrRefCount(subPtr);
+    }
+    if (resultPtr) {
+	Tcl_DecrRefCount(resultPtr);
+    }
+    return result;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_RenameObjCmd --
+ *
+ *	This procedure is invoked to process the "rename" Tcl command. See the
+ *	user documentation for details on what it does.
+ *
+ * Results:
+ *	A standard Tcl object result.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_RenameObjCmd(
+    ClientData dummy,		/* Arbitrary value passed to the command. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    const char *oldName, *newName;
+
+    if (objc != 3) {
+	Tcl_WrongNumArgs(interp, 1, objv, "oldName newName");
+	return TCL_ERROR;
+    }
+
+    oldName = TclGetString(objv[1]);
+    newName = TclGetString(objv[2]);
+    return TclRenameCommand(interp, oldName, newName);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_ReturnObjCmd --
+ *
+ *	This object-based procedure is invoked to process the "return" Tcl
+ *	command. See the user documentation for details on what it does.
+ *
+ * Results:
+ *	A standard Tcl object result.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_ReturnObjCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    int code, level;
+    Tcl_Obj *returnOpts;
+
+    /*
+     * General syntax: [return ?-option value ...? ?result?]
+     * An even number of words means an explicit result argument is present.
+     */
+
+    int explicitResult = (0 == (objc % 2));
+    int numOptionWords = objc - 1 - explicitResult;
+
+    if (TCL_ERROR == TclMergeReturnOptions(interp, numOptionWords, objv+1,
+	    &returnOpts, &code, &level)) {
+	return TCL_ERROR;
+    }
+
+    code = TclProcessReturn(interp, code, level, returnOpts);
+    if (explicitResult) {
+	Tcl_SetObjResult(interp, objv[objc-1]);
+    }
+    return code;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_SourceObjCmd --
+ *
+ *	This procedure is invoked to process the "source" Tcl command. See the
+ *	user documentation for details on what it does.
+ *
+ * Results:
+ *	A standard Tcl object result.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_SourceObjCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    return Tcl_NRCallObjProc(interp, TclNRSourceObjCmd, dummy, objc, objv);
+}
+
+int
+TclNRSourceObjCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    const char *encodingName = NULL;
+    Tcl_Obj *fileName;
+
+    if (objc != 2 && objc !=4) {
+	Tcl_WrongNumArgs(interp, 1, objv, "?-encoding name? fileName");
+	return TCL_ERROR;
+    }
+
+    fileName = objv[objc-1];
+
+    if (objc == 4) {
+	static const char *const options[] = {
+	    "-encoding", NULL
+	};
+	int index;
+
+	if (TCL_ERROR == Tcl_GetIndexFromObj(interp, objv[1], options,
+		"option", TCL_EXACT, &index)) {
+	    return TCL_ERROR;
+	}
+	encodingName = TclGetString(objv[2]);
+    }
+
+    return TclNREvalFile(interp, fileName, encodingName);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_SplitObjCmd --
+ *
+ *	This procedure is invoked to process the "split" Tcl command. See the
+ *	user documentation for details on what it does.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_SplitObjCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    Tcl_UniChar ch;
+    int len;
+    const char *splitChars;
+    const char *stringPtr;
+    const char *end;
+    int splitCharLen, stringLen;
+    Tcl_Obj *listPtr, *objPtr;
+
+    if (objc == 2) {
+	splitChars = " \n\t\r";
+	splitCharLen = 4;
+    } else if (objc == 3) {
+	splitChars = TclGetStringFromObj(objv[2], &splitCharLen);
+    } else {
+	Tcl_WrongNumArgs(interp, 1, objv, "string ?splitChars?");
+	return TCL_ERROR;
+    }
+
+    stringPtr = TclGetStringFromObj(objv[1], &stringLen);
+    end = stringPtr + stringLen;
+    listPtr = Tcl_NewObj();
+
+    if (stringLen == 0) {
+	/*
+	 * Do nothing.
+	 */
+    } else if (splitCharLen == 0) {
+	Tcl_HashTable charReuseTable;
+	Tcl_HashEntry *hPtr;
+	int isNew;
+
+	/*
+	 * Handle the special case of splitting on every character.
+	 *
+	 * Uses a hash table to ensure that each kind of character has only
+	 * one Tcl_Obj instance (multiply-referenced) in the final list. This
+	 * is a *major* win when splitting on a long string (especially in the
+	 * megabyte range!) - DKF
+	 */
+
+	Tcl_InitHashTable(&charReuseTable, TCL_ONE_WORD_KEYS);
+
+	for ( ; stringPtr < end; stringPtr += len) {
+	    len = TclUtfToUniChar(stringPtr, &ch);
+
+	    /*
+	     * Assume Tcl_UniChar is an integral type...
+	     */
+
+	    hPtr = Tcl_CreateHashEntry(&charReuseTable, INT2PTR((int) ch),
+		    &isNew);
+	    if (isNew) {
+		TclNewStringObj(objPtr, stringPtr, len);
+
+		/*
+		 * Don't need to fiddle with refcount...
+		 */
+
+		Tcl_SetHashValue(hPtr, objPtr);
+	    } else {
+		objPtr = Tcl_GetHashValue(hPtr);
+	    }
+	    Tcl_ListObjAppendElement(NULL, listPtr, objPtr);
+	}
+	Tcl_DeleteHashTable(&charReuseTable);
+
+    } else if (splitCharLen == 1) {
+	char *p;
+
+	/*
+	 * Handle the special case of splitting on a single character. This is
+	 * only true for the one-char ASCII case, as one unicode char is > 1
+	 * byte in length.
+	 */
+
+	while (*stringPtr && (p=strchr(stringPtr,(int)*splitChars)) != NULL) {
+	    objPtr = Tcl_NewStringObj(stringPtr, p - stringPtr);
+	    Tcl_ListObjAppendElement(NULL, listPtr, objPtr);
+	    stringPtr = p + 1;
+	}
+	TclNewStringObj(objPtr, stringPtr, end - stringPtr);
+	Tcl_ListObjAppendElement(NULL, listPtr, objPtr);
+    } else {
+	const char *element, *p, *splitEnd;
+	int splitLen;
+	Tcl_UniChar splitChar;
+
+	/*
+	 * Normal case: split on any of a given set of characters. Discard
+	 * instances of the split characters.
+	 */
+
+	splitEnd = splitChars + splitCharLen;
+
+	for (element = stringPtr; stringPtr < end; stringPtr += len) {
+	    len = TclUtfToUniChar(stringPtr, &ch);
+	    for (p = splitChars; p < splitEnd; p += splitLen) {
+		splitLen = TclUtfToUniChar(p, &splitChar);
+		if (ch == splitChar) {
+		    TclNewStringObj(objPtr, element, stringPtr - element);
+		    Tcl_ListObjAppendElement(NULL, listPtr, objPtr);
+		    element = stringPtr + len;
+		    break;
+		}
+	    }
+	}
+
+	TclNewStringObj(objPtr, element, stringPtr - element);
+	Tcl_ListObjAppendElement(NULL, listPtr, objPtr);
+    }
+    Tcl_SetObjResult(interp, listPtr);
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * StringFirstCmd --
+ *
+ *	This procedure is invoked to process the "string first" Tcl command.
+ *	See the user documentation for details on what it does. Note that this
+ *	command only functions correctly on properly formed Tcl UTF strings.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+StringFirstCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    Tcl_UniChar *needleStr, *haystackStr;
+    int match, start, needleLen, haystackLen;
+
+    if (objc < 3 || objc > 4) {
+	Tcl_WrongNumArgs(interp, 1, objv,
+		"needleString haystackString ?startIndex?");
+	return TCL_ERROR;
+    }
+
+    /*
+     * We are searching haystackStr for the sequence needleStr.
+     */
+
+    match = -1;
+    start = 0;
+    haystackLen = -1;
+
+    needleStr = Tcl_GetUnicodeFromObj(objv[1], &needleLen);
+    haystackStr = Tcl_GetUnicodeFromObj(objv[2], &haystackLen);
+
+    if (objc == 4) {
+	/*
+	 * If a startIndex is specified, we will need to fast forward to that
+	 * point in the string before we think about a match.
+	 */
+
+	if (TclGetIntForIndexM(interp, objv[3], haystackLen-1,
+		&start) != TCL_OK){
+	    return TCL_ERROR;
+	}
+
+	/*
+	 * Reread to prevent shimmering problems.
+	 */
+
+	needleStr = Tcl_GetUnicodeFromObj(objv[1], &needleLen);
+	haystackStr = Tcl_GetUnicodeFromObj(objv[2], &haystackLen);
+
+	if (start >= haystackLen) {
+	    goto str_first_done;
+	} else if (start > 0) {
+	    haystackStr += start;
+	    haystackLen -= start;
+	} else if (start < 0) {
+	    /*
+	     * Invalid start index mapped to string start; Bug #423581
+	     */
+
+	    start = 0;
+	}
+    }
+
+    /*
+     * If the length of the needle is more than the length of the haystack, it
+     * cannot be contained in there so we can avoid searching. [Bug 2960021]
+     */
+
+    if (needleLen > 0 && needleLen <= haystackLen) {
+	register Tcl_UniChar *p, *end;
+
+	end = haystackStr + haystackLen - needleLen + 1;
+	for (p = haystackStr;  p < end;  p++) {
+	    /*
+	     * Scan forward to find the first character.
+	     */
+
+	    if ((*p == *needleStr) && (TclUniCharNcmp(needleStr, p,
+		    (unsigned long) needleLen) == 0)) {
+		match = p - haystackStr;
+		break;
+	    }
+	}
+    }
+
+    /*
+     * Compute the character index of the matching string by counting the
+     * number of characters before the match.
+     */
+
+    if ((match != -1) && (objc == 4)) {
+	match += start;
+    }
+
+  str_first_done:
+    Tcl_SetObjResult(interp, Tcl_NewIntObj(match));
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * StringLastCmd --
+ *
+ *	This procedure is invoked to process the "string last" Tcl command.
+ *	See the user documentation for details on what it does. Note that this
+ *	command only functions correctly on properly formed Tcl UTF strings.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+StringLastCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    Tcl_UniChar *needleStr, *haystackStr, *p;
+    int match, start, needleLen, haystackLen;
+
+    if (objc < 3 || objc > 4) {
+	Tcl_WrongNumArgs(interp, 1, objv,
+		"needleString haystackString ?startIndex?");
+	return TCL_ERROR;
+    }
+
+    /*
+     * We are searching haystackString for the sequence needleString.
+     */
+
+    match = -1;
+    start = 0;
+    haystackLen = -1;
+
+    needleStr = Tcl_GetUnicodeFromObj(objv[1], &needleLen);
+    haystackStr = Tcl_GetUnicodeFromObj(objv[2], &haystackLen);
+
+    if (objc == 4) {
+	/*
+	 * If a startIndex is specified, we will need to restrict the string
+	 * range to that char index in the string
+	 */
+
+	if (TclGetIntForIndexM(interp, objv[3], haystackLen-1,
+		&start) != TCL_OK){
+	    return TCL_ERROR;
+	}
+
+	/*
+	 * Reread to prevent shimmering problems.
+	 */
+
+	needleStr = Tcl_GetUnicodeFromObj(objv[1], &needleLen);
+	haystackStr = Tcl_GetUnicodeFromObj(objv[2], &haystackLen);
+
+	if (start < 0) {
+	    goto str_last_done;
+	} else if (start < haystackLen) {
+	    p = haystackStr + start + 1 - needleLen;
+	} else {
+	    p = haystackStr + haystackLen - needleLen;
+	}
+    } else {
+	p = haystackStr + haystackLen - needleLen;
+    }
+
+    /*
+     * If the length of the needle is more than the length of the haystack, it
+     * cannot be contained in there so we can avoid searching. [Bug 2960021]
+     */
+
+    if (needleLen > 0 && needleLen <= haystackLen) {
+	for (; p >= haystackStr; p--) {
+	    /*
+	     * Scan backwards to find the first character.
+	     */
+
+	    if ((*p == *needleStr) && !memcmp(needleStr, p,
+		    sizeof(Tcl_UniChar) * (size_t)needleLen)) {
+		match = p - haystackStr;
+		break;
+	    }
+	}
+    }
+
+  str_last_done:
+    Tcl_SetObjResult(interp, Tcl_NewIntObj(match));
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * StringIndexCmd --
+ *
+ *	This procedure is invoked to process the "string index" Tcl command.
+ *	See the user documentation for details on what it does. Note that this
+ *	command only functions correctly on properly formed Tcl UTF strings.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+StringIndexCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    int length, index;
+
+    if (objc != 3) {
+	Tcl_WrongNumArgs(interp, 1, objv, "string charIndex");
+	return TCL_ERROR;
+    }
+
+    /*
+     * Get the char length to calulate what 'end' means.
+     */
+
+    length = Tcl_GetCharLength(objv[1]);
+    if (TclGetIntForIndexM(interp, objv[2], length-1, &index) != TCL_OK) {
+	return TCL_ERROR;
+    }
+
+    if ((index >= 0) && (index < length)) {
+	Tcl_UniChar ch = Tcl_GetUniChar(objv[1], index);
+
+	/*
+	 * If we have a ByteArray object, we're careful to generate a new
+	 * bytearray for a result.
+	 */
+
+	if (TclIsPureByteArray(objv[1])) {
+	    unsigned char uch = (unsigned char) ch;
+
+	    Tcl_SetObjResult(interp, Tcl_NewByteArrayObj(&uch, 1));
+	} else {
+	    char buf[TCL_UTF_MAX];
+
+	    length = Tcl_UniCharToUtf(ch, buf);
+	    Tcl_SetObjResult(interp, Tcl_NewStringObj(buf, length));
+	}
+    }
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * StringIsCmd --
+ *
+ *	This procedure is invoked to process the "string is" Tcl command. See
+ *	the user documentation for details on what it does. Note that this
+ *	command only functions correctly on properly formed Tcl UTF strings.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+StringIsCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    const char *string1, *end, *stop;
+    Tcl_UniChar ch;
+    int (*chcomp)(int) = NULL;	/* The UniChar comparison function. */
+    int i, failat = 0, result = 1, strict = 0, index, length1, length2;
+    Tcl_Obj *objPtr, *failVarObj = NULL;
+    Tcl_WideInt w;
+
+    static const char *const isClasses[] = {
+	"alnum",	"alpha",	"ascii",	"control",
+	"boolean",	"digit",	"double",	"entier",
+	"false",	"graph",	"integer",	"list",
+	"lower",	"print",	"punct",	"space",
+	"true",		"upper",	"wideinteger",	"wordchar",
+	"xdigit",	NULL
+    };
+    enum isClasses {
+	STR_IS_ALNUM,	STR_IS_ALPHA,	STR_IS_ASCII,	STR_IS_CONTROL,
+	STR_IS_BOOL,	STR_IS_DIGIT,	STR_IS_DOUBLE,	STR_IS_ENTIER,
+	STR_IS_FALSE,	STR_IS_GRAPH,	STR_IS_INT,	STR_IS_LIST,
+	STR_IS_LOWER,	STR_IS_PRINT,	STR_IS_PUNCT,	STR_IS_SPACE,
+	STR_IS_TRUE,	STR_IS_UPPER,	STR_IS_WIDE,	STR_IS_WORD,
+	STR_IS_XDIGIT
+    };
+    static const char *const isOptions[] = {
+	"-strict", "-failindex", NULL
+    };
+    enum isOptions {
+	OPT_STRICT, OPT_FAILIDX
+    };
+
+    if (objc < 3 || objc > 6) {
+	Tcl_WrongNumArgs(interp, 1, objv,
+		"class ?-strict? ?-failindex var? str");
+	return TCL_ERROR;
+    }
+    if (Tcl_GetIndexFromObj(interp, objv[1], isClasses, "class", 0,
+	    &index) != TCL_OK) {
+	return TCL_ERROR;
+    }
+
+    if (objc != 3) {
+	for (i = 2; i < objc-1; i++) {
+	    int idx2;
+
+	    if (Tcl_GetIndexFromObj(interp, objv[i], isOptions, "option", 0,
+		    &idx2) != TCL_OK) {
+		return TCL_ERROR;
+	    }
+	    switch ((enum isOptions) idx2) {
+	    case OPT_STRICT:
+		strict = 1;
+		break;
+	    case OPT_FAILIDX:
+		if (i+1 >= objc-1) {
+		    Tcl_WrongNumArgs(interp, 2, objv,
+			    "?-strict? ?-failindex var? str");
+		    return TCL_ERROR;
+		}
+		failVarObj = objv[++i];
+		break;
+	    }
+	}
+    }
+
+    /*
+     * We get the objPtr so that we can short-cut for some classes by checking
+     * the object type (int and double), but we need the string otherwise,
+     * because we don't want any conversion of type occuring (as, for example,
+     * Tcl_Get*FromObj would do).
+     */
+
+    objPtr = objv[objc-1];
+
+    /*
+     * When entering here, result == 1 and failat == 0.
+     */
+
+    switch ((enum isClasses) index) {
+    case STR_IS_ALNUM:
+	chcomp = Tcl_UniCharIsAlnum;
+	break;
+    case STR_IS_ALPHA:
+	chcomp = Tcl_UniCharIsAlpha;
+	break;
+    case STR_IS_ASCII:
+	chcomp = UniCharIsAscii;
+	break;
+    case STR_IS_BOOL:
+    case STR_IS_TRUE:
+    case STR_IS_FALSE:
+	if ((objPtr->typePtr != &tclBooleanType)
+		&& (TCL_OK != TclSetBooleanFromAny(NULL, objPtr))) {
+	    if (strict) {
+		result = 0;
+	    } else {
+		string1 = TclGetStringFromObj(objPtr, &length1);
+		result = length1 == 0;
+	    }
+	} else if (((index == STR_IS_TRUE) &&
+		objPtr->internalRep.longValue == 0)
+	    || ((index == STR_IS_FALSE) &&
+		objPtr->internalRep.longValue != 0)) {
+	    result = 0;
+	}
+	break;
+    case STR_IS_CONTROL:
+	chcomp = Tcl_UniCharIsControl;
+	break;
+    case STR_IS_DIGIT:
+	chcomp = Tcl_UniCharIsDigit;
+	break;
+    case STR_IS_DOUBLE: {
+	/* TODO */
+	if ((objPtr->typePtr == &tclDoubleType) ||
+		(objPtr->typePtr == &tclIntType) ||
+#ifndef TCL_WIDE_INT_IS_LONG
+		(objPtr->typePtr == &tclWideIntType) ||
+#endif
+		(objPtr->typePtr == &tclBignumType)) {
+	    break;
+	}
+	string1 = TclGetStringFromObj(objPtr, &length1);
+	if (length1 == 0) {
+	    if (strict) {
+		result = 0;
+	    }
+	    goto str_is_done;
+	}
+	end = string1 + length1;
+	if (TclParseNumber(NULL, objPtr, NULL, NULL, -1,
+		(const char **) &stop, 0) != TCL_OK) {
+	    result = 0;
+	    failat = 0;
+	} else {
+	    failat = stop - string1;
+	    if (stop < end) {
+		result = 0;
+		TclFreeIntRep(objPtr);
+	    }
+	}
+	break;
+    }
+    case STR_IS_GRAPH:
+	chcomp = Tcl_UniCharIsGraph;
+	break;
+    case STR_IS_INT:
+	if (TCL_OK == TclGetIntFromObj(NULL, objPtr, &i)) {
+	    break;
+	}
+	goto failedIntParse;
+    case STR_IS_ENTIER:
+	if ((objPtr->typePtr == &tclIntType) ||
+#ifndef TCL_WIDE_INT_IS_LONG
+		(objPtr->typePtr == &tclWideIntType) ||
+#endif
+		(objPtr->typePtr == &tclBignumType)) {
+	    break;
+	}
+	string1 = TclGetStringFromObj(objPtr, &length1);
+	if (length1 == 0) {
+	    if (strict) {
+		result = 0;
+	    }
+	    goto str_is_done;
+	}
+	end = string1 + length1;
+	if (TclParseNumber(NULL, objPtr, NULL, NULL, -1,
+		(const char **) &stop, TCL_PARSE_INTEGER_ONLY) == TCL_OK) {
+	    if (stop == end) {
+		/*
+		 * Entire string parses as an integer.
+		 */
+
+		break;
+	    } else {
+		/*
+		 * Some prefix parsed as an integer, but not the whole string,
+		 * so return failure index as the point where parsing stopped.
+		 * Clear out the internal rep, since keeping it would leave
+		 * *objPtr in an inconsistent state.
+		 */
+
+		result = 0;
+		failat = stop - string1;
+		TclFreeIntRep(objPtr);
+	    }
+	} else {
+	    /*
+	     * No prefix is a valid integer. Fail at beginning.
+	     */
+
+	    result = 0;
+	    failat = 0;
+	}
+	break;
+    case STR_IS_WIDE:
+	if (TCL_OK == Tcl_GetWideIntFromObj(NULL, objPtr, &w)) {
+	    break;
+	}
+
+    failedIntParse:
+	string1 = TclGetStringFromObj(objPtr, &length1);
+	if (length1 == 0) {
+	    if (strict) {
+		result = 0;
+	    }
+	    goto str_is_done;
+	}
+	result = 0;
+	if (failVarObj == NULL) {
+	    /*
+	     * Don't bother computing the failure point if we're not going to
+	     * return it.
+	     */
+
+	    break;
+	}
+	end = string1 + length1;
+	if (TclParseNumber(NULL, objPtr, NULL, NULL, -1,
+		(const char **) &stop, TCL_PARSE_INTEGER_ONLY) == TCL_OK) {
+	    if (stop == end) {
+		/*
+		 * Entire string parses as an integer, but rejected by
+		 * Tcl_Get(Wide)IntFromObj() so we must have overflowed the
+		 * target type, and our convention is to return failure at
+		 * index -1 in that situation.
+		 */
+
+		failat = -1;
+	    } else {
+		/*
+		 * Some prefix parsed as an integer, but not the whole string,
+		 * so return failure index as the point where parsing stopped.
+		 * Clear out the internal rep, since keeping it would leave
+		 * *objPtr in an inconsistent state.
+		 */
+
+		failat = stop - string1;
+		TclFreeIntRep(objPtr);
+	    }
+	} else {
+	    /*
+	     * No prefix is a valid integer. Fail at beginning.
+	     */
+
+	    failat = 0;
+	}
+	break;
+    case STR_IS_LIST:
+	/*
+	 * We ignore the strictness here, since empty strings are always
+	 * well-formed lists.
+	 */
+
+	if (TCL_OK == TclListObjLength(NULL, objPtr, &length2)) {
+	    break;
+	}
+
+	if (failVarObj != NULL) {
+	    /*
+	     * Need to figure out where the list parsing failed, which is
+	     * fairly expensive. This is adapted from the core of
+	     * SetListFromAny().
+	     */
+
+	    const char *elemStart, *nextElem;
+	    int lenRemain, elemSize;
+	    register const char *p;
+
+	    string1 = TclGetStringFromObj(objPtr, &length1);
+	    end = string1 + length1;
+	    failat = -1;
+	    for (p=string1, lenRemain=length1; lenRemain > 0;
+		    p=nextElem, lenRemain=end-nextElem) {
+		if (TCL_ERROR == TclFindElement(NULL, p, lenRemain,
+			&elemStart, &nextElem, &elemSize, NULL)) {
+		    Tcl_Obj *tmpStr;
+
+		    /*
+		     * This is the simplest way of getting the number of
+		     * characters parsed. Note that this is not the same as
+		     * the number of bytes when parsing strings with non-ASCII
+		     * characters in them.
+		     *
+		     * Skip leading spaces first. This is only really an issue
+		     * if it is the first "element" that has the failure.
+		     */
+
+		    while (TclIsSpaceProc(*p)) {
+			p++;
+		    }
+		    TclNewStringObj(tmpStr, string1, p-string1);
+		    failat = Tcl_GetCharLength(tmpStr);
+		    TclDecrRefCount(tmpStr);
+		    break;
+		}
+	    }
+	}
+	result = 0;
+	break;
+    case STR_IS_LOWER:
+	chcomp = Tcl_UniCharIsLower;
+	break;
+    case STR_IS_PRINT:
+	chcomp = Tcl_UniCharIsPrint;
+	break;
+    case STR_IS_PUNCT:
+	chcomp = Tcl_UniCharIsPunct;
+	break;
+    case STR_IS_SPACE:
+	chcomp = Tcl_UniCharIsSpace;
+	break;
+    case STR_IS_UPPER:
+	chcomp = Tcl_UniCharIsUpper;
+	break;
+    case STR_IS_WORD:
+	chcomp = Tcl_UniCharIsWordChar;
+	break;
+    case STR_IS_XDIGIT:
+	chcomp = UniCharIsHexDigit;
+	break;
+    }
+
+    if (chcomp != NULL) {
+	string1 = TclGetStringFromObj(objPtr, &length1);
+	if (length1 == 0) {
+	    if (strict) {
+		result = 0;
+	    }
+	    goto str_is_done;
+	}
+	end = string1 + length1;
+	for (; string1 < end; string1 += length2, failat++) {
+	    length2 = TclUtfToUniChar(string1, &ch);
+	    if (!chcomp(ch)) {
+		result = 0;
+		break;
+	    }
+	}
+    }
+
+    /*
+     * Only set the failVarObj when we will return 0 and we have indicated a
+     * valid fail index (>= 0).
+     */
+
+ str_is_done:
+    if ((result == 0) && (failVarObj != NULL) &&
+	Tcl_ObjSetVar2(interp, failVarObj, NULL, Tcl_NewIntObj(failat),
+		TCL_LEAVE_ERR_MSG) == NULL) {
+	return TCL_ERROR;
+    }
+    Tcl_SetObjResult(interp, Tcl_NewBooleanObj(result));
+    return TCL_OK;
+}
+
+static int
+UniCharIsAscii(
+    int character)
+{
+    return (character >= 0) && (character < 0x80);
+}
+
+static int
+UniCharIsHexDigit(
+    int character)
+{
+    return (character >= 0) && (character < 0x80) && isxdigit(character);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * StringMapCmd --
+ *
+ *	This procedure is invoked to process the "string map" Tcl command. See
+ *	the user documentation for details on what it does. Note that this
+ *	command only functions correctly on properly formed Tcl UTF strings.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+StringMapCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    int length1, length2, mapElemc, index;
+    int nocase = 0, mapWithDict = 0, copySource = 0;
+    Tcl_Obj **mapElemv, *sourceObj, *resultPtr;
+    Tcl_UniChar *ustring1, *ustring2, *p, *end;
+    int (*strCmpFn)(const Tcl_UniChar*, const Tcl_UniChar*, unsigned long);
+
+    if (objc < 3 || objc > 4) {
+	Tcl_WrongNumArgs(interp, 1, objv, "?-nocase? charMap string");
+	return TCL_ERROR;
+    }
+
+    if (objc == 4) {
+	const char *string = TclGetStringFromObj(objv[1], &length2);
+
+	if ((length2 > 1) &&
+		strncmp(string, "-nocase", (size_t) length2) == 0) {
+	    nocase = 1;
+	} else {
+	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		    "bad option \"%s\": must be -nocase", string));
+	    Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "INDEX", "option",
+		    string, NULL);
+	    return TCL_ERROR;
+	}
+    }
+
+    /*
+     * This test is tricky, but has to be that way or you get other strange
+     * inconsistencies (see test string-10.20 for illustration why!)
+     */
+
+    if (objv[objc-2]->typePtr == &tclDictType && objv[objc-2]->bytes == NULL){
+	int i, done;
+	Tcl_DictSearch search;
+
+	/*
+	 * We know the type exactly, so all dict operations will succeed for
+	 * sure. This shortens this code quite a bit.
+	 */
+
+	Tcl_DictObjSize(interp, objv[objc-2], &mapElemc);
+	if (mapElemc == 0) {
+	    /*
+	     * Empty charMap, just return whatever string was given.
+	     */
+
+	    Tcl_SetObjResult(interp, objv[objc-1]);
+	    return TCL_OK;
+	}
+
+	mapElemc *= 2;
+	mapWithDict = 1;
+
+	/*
+	 * Copy the dictionary out into an array; that's the easiest way to
+	 * adapt this code...
+	 */
+
+	mapElemv = TclStackAlloc(interp, sizeof(Tcl_Obj *) * mapElemc);
+	Tcl_DictObjFirst(interp, objv[objc-2], &search, mapElemv+0,
+		mapElemv+1, &done);
+	for (i=2 ; i<mapElemc ; i+=2) {
+	    Tcl_DictObjNext(&search, mapElemv+i, mapElemv+i+1, &done);
+	}
+	Tcl_DictObjDone(&search);
+    } else {
+	if (TclListObjGetElements(interp, objv[objc-2], &mapElemc,
+		&mapElemv) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	if (mapElemc == 0) {
+	    /*
+	     * empty charMap, just return whatever string was given.
+	     */
+
+	    Tcl_SetObjResult(interp, objv[objc-1]);
+	    return TCL_OK;
+	} else if (mapElemc & 1) {
+	    /*
+	     * The charMap must be an even number of key/value items.
+	     */
+
+	    Tcl_SetObjResult(interp,
+		    Tcl_NewStringObj("char map list unbalanced", -1));
+	    Tcl_SetErrorCode(interp, "TCL", "OPERATION", "MAP",
+		    "UNBALANCED", NULL);
+	    return TCL_ERROR;
+	}
+    }
+
+    /*
+     * Take a copy of the source string object if it is the same as the map
+     * string to cut out nasty sharing crashes. [Bug 1018562]
+     */
+
+    if (objv[objc-2] == objv[objc-1]) {
+	sourceObj = Tcl_DuplicateObj(objv[objc-1]);
+	copySource = 1;
+    } else {
+	sourceObj = objv[objc-1];
+    }
+    ustring1 = Tcl_GetUnicodeFromObj(sourceObj, &length1);
+    if (length1 == 0) {
+	/*
+	 * Empty input string, just stop now.
+	 */
+
+	goto done;
+    }
+    end = ustring1 + length1;
+
+    strCmpFn = (nocase ? Tcl_UniCharNcasecmp : Tcl_UniCharNcmp);
+
+    /*
+     * Force result to be Unicode
+     */
+
+    resultPtr = Tcl_NewUnicodeObj(ustring1, 0);
+
+    if (mapElemc == 2) {
+	/*
+	 * Special case for one map pair which avoids the extra for loop and
+	 * extra calls to get Unicode data. The algorithm is otherwise
+	 * identical to the multi-pair case. This will be >30% faster on
+	 * larger strings.
+	 */
+
+	int mapLen;
+	Tcl_UniChar *mapString, u2lc;
+
+	ustring2 = Tcl_GetUnicodeFromObj(mapElemv[0], &length2);
+	p = ustring1;
+	if ((length2 > length1) || (length2 == 0)) {
+	    /*
+	     * Match string is either longer than input or empty.
+	     */
+
+	    ustring1 = end;
+	} else {
+	    mapString = Tcl_GetUnicodeFromObj(mapElemv[1], &mapLen);
+	    u2lc = (nocase ? Tcl_UniCharToLower(*ustring2) : 0);
+	    for (; ustring1 < end; ustring1++) {
+		if (((*ustring1 == *ustring2) ||
+			(nocase&&Tcl_UniCharToLower(*ustring1)==u2lc)) &&
+			(length2==1 || strCmpFn(ustring1, ustring2,
+				(unsigned long) length2) == 0)) {
+		    if (p != ustring1) {
+			Tcl_AppendUnicodeToObj(resultPtr, p, ustring1-p);
+			p = ustring1 + length2;
+		    } else {
+			p += length2;
+		    }
+		    ustring1 = p - 1;
+
+		    Tcl_AppendUnicodeToObj(resultPtr, mapString, mapLen);
+		}
+	    }
+	}
+    } else {
+	Tcl_UniChar **mapStrings, *u2lc = NULL;
+	int *mapLens;
+
+	/*
+	 * Precompute pointers to the unicode string and length. This saves us
+	 * repeated function calls later, significantly speeding up the
+	 * algorithm. We only need the lowercase first char in the nocase
+	 * case.
+	 */
+
+	mapStrings = TclStackAlloc(interp, mapElemc*2*sizeof(Tcl_UniChar *));
+	mapLens = TclStackAlloc(interp, mapElemc * 2 * sizeof(int));
+	if (nocase) {
+	    u2lc = TclStackAlloc(interp, mapElemc * sizeof(Tcl_UniChar));
+	}
+	for (index = 0; index < mapElemc; index++) {
+	    mapStrings[index] = Tcl_GetUnicodeFromObj(mapElemv[index],
+		    mapLens+index);
+	    if (nocase && ((index % 2) == 0)) {
+		u2lc[index/2] = Tcl_UniCharToLower(*mapStrings[index]);
+	    }
+	}
+	for (p = ustring1; ustring1 < end; ustring1++) {
+	    for (index = 0; index < mapElemc; index += 2) {
+		/*
+		 * Get the key string to match on.
+		 */
+
+		ustring2 = mapStrings[index];
+		length2 = mapLens[index];
+		if ((length2 > 0) && ((*ustring1 == *ustring2) || (nocase &&
+			(Tcl_UniCharToLower(*ustring1) == u2lc[index/2]))) &&
+			/* Restrict max compare length. */
+			(end-ustring1 >= length2) && ((length2 == 1) ||
+			!strCmpFn(ustring2, ustring1, (unsigned) length2))) {
+		    if (p != ustring1) {
+			/*
+			 * Put the skipped chars onto the result first.
+			 */
+
+			Tcl_AppendUnicodeToObj(resultPtr, p, ustring1-p);
+			p = ustring1 + length2;
+		    } else {
+			p += length2;
+		    }
+
+		    /*
+		     * Adjust len to be full length of matched string.
+		     */
+
+		    ustring1 = p - 1;
+
+		    /*
+		     * Append the map value to the unicode string.
+		     */
+
+		    Tcl_AppendUnicodeToObj(resultPtr,
+			    mapStrings[index+1], mapLens[index+1]);
+		    break;
+		}
+	    }
+	}
+	if (nocase) {
+	    TclStackFree(interp, u2lc);
+	}
+	TclStackFree(interp, mapLens);
+	TclStackFree(interp, mapStrings);
+    }
+    if (p != ustring1) {
+	/*
+	 * Put the rest of the unmapped chars onto result.
+	 */
+
+	Tcl_AppendUnicodeToObj(resultPtr, p, ustring1 - p);
+    }
+    Tcl_SetObjResult(interp, resultPtr);
+  done:
+    if (mapWithDict) {
+	TclStackFree(interp, mapElemv);
+    }
+    if (copySource) {
+	Tcl_DecrRefCount(sourceObj);
+    }
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * StringMatchCmd --
+ *
+ *	This procedure is invoked to process the "string match" Tcl command.
+ *	See the user documentation for details on what it does. Note that this
+ *	command only functions correctly on properly formed Tcl UTF strings.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+StringMatchCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    int nocase = 0;
+
+    if (objc < 3 || objc > 4) {
+	Tcl_WrongNumArgs(interp, 1, objv, "?-nocase? pattern string");
+	return TCL_ERROR;
+    }
+
+    if (objc == 4) {
+	int length;
+	const char *string = TclGetStringFromObj(objv[1], &length);
+
+	if ((length > 1) &&
+	    strncmp(string, "-nocase", (size_t) length) == 0) {
+	    nocase = TCL_MATCH_NOCASE;
+	} else {
+	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		    "bad option \"%s\": must be -nocase", string));
+	    Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "INDEX", "option",
+		    string, NULL);
+	    return TCL_ERROR;
+	}
+    }
+    Tcl_SetObjResult(interp, Tcl_NewBooleanObj(
+		TclStringMatchObj(objv[objc-1], objv[objc-2], nocase)));
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * StringRangeCmd --
+ *
+ *	This procedure is invoked to process the "string range" Tcl command.
+ *	See the user documentation for details on what it does. Note that this
+ *	command only functions correctly on properly formed Tcl UTF strings.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+StringRangeCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    int length, first, last;
+
+    if (objc != 4) {
+	Tcl_WrongNumArgs(interp, 1, objv, "string first last");
+	return TCL_ERROR;
+    }
+
+    /*
+     * Get the length in actual characters; Then reduce it by one because
+     * 'end' refers to the last character, not one past it.
+     */
+
+    length = Tcl_GetCharLength(objv[1]) - 1;
+
+    if (TclGetIntForIndexM(interp, objv[2], length, &first) != TCL_OK ||
+	    TclGetIntForIndexM(interp, objv[3], length, &last) != TCL_OK) {
+	return TCL_ERROR;
+    }
+
+    if (first < 0) {
+	first = 0;
+    }
+    if (last >= length) {
+	last = length;
+    }
+    if (last >= first) {
+	Tcl_SetObjResult(interp, Tcl_GetRange(objv[1], first, last));
+    }
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * StringReptCmd --
+ *
+ *	This procedure is invoked to process the "string repeat" Tcl command.
+ *	See the user documentation for details on what it does. Note that this
+ *	command only functions correctly on properly formed Tcl UTF strings.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+StringReptCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    const char *string1;
+    char *string2;
+    int count, index, length1, length2;
+    Tcl_Obj *resultPtr;
+
+    if (objc != 3) {
+	Tcl_WrongNumArgs(interp, 1, objv, "string count");
+	return TCL_ERROR;
+    }
+
+    if (TclGetIntFromObj(interp, objv[2], &count) != TCL_OK) {
+	return TCL_ERROR;
+    }
+
+    /*
+     * Check for cases that allow us to skip copying stuff.
+     */
+
+    if (count == 1) {
+	Tcl_SetObjResult(interp, objv[1]);
+	goto done;
+    } else if (count < 1) {
+	goto done;
+    }
+    string1 = TclGetStringFromObj(objv[1], &length1);
+    if (length1 <= 0) {
+	goto done;
+    }
+
+    /*
+     * Only build up a string that has data. Instead of building it up with
+     * repeated appends, we just allocate the necessary space once and copy
+     * the string value in.
+     *
+     * We have to worry about overflow [Bugs 714106, 2561746].
+     * At this point we know 1 <= length1 <= INT_MAX and 2 <= count <= INT_MAX.
+     * We need to keep 2 <= length2 <= INT_MAX.
+     */
+
+    if (count > INT_MAX/length1) {
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		"result exceeds max size for a Tcl value (%d bytes)",
+		INT_MAX));
+	Tcl_SetErrorCode(interp, "TCL", "MEMORY", NULL);
+	return TCL_ERROR;
+    }
+    length2 = length1 * count;
+
+    /*
+     * Include space for the NUL.
+     */
+
+    string2 = attemptckalloc((unsigned) length2 + 1);
+    if (string2 == NULL) {
+	/*
+	 * Alloc failed. Note that in this case we try to do an error message
+	 * since this is a case that's most likely when the alloc is large and
+	 * that's easy to do with this API. Note that if we fail allocating a
+	 * short string, this will likely keel over too (and fatally).
+	 */
+
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		"string size overflow, out of memory allocating %u bytes",
+		length2 + 1));
+	Tcl_SetErrorCode(interp, "TCL", "MEMORY", NULL);
+	return TCL_ERROR;
+    }
+    for (index = 0; index < count; index++) {
+	memcpy(string2 + (length1 * index), string1, (size_t) length1);
+    }
+    string2[length2] = '\0';
+
+    /*
+     * We have to directly assign this instead of using Tcl_SetStringObj (and
+     * indirectly TclInitStringRep) because that makes another copy of the
+     * data.
+     */
+
+    TclNewObj(resultPtr);
+    resultPtr->bytes = string2;
+    resultPtr->length = length2;
+    Tcl_SetObjResult(interp, resultPtr);
+
+  done:
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * StringRplcCmd --
+ *
+ *	This procedure is invoked to process the "string replace" Tcl command.
+ *	See the user documentation for details on what it does. Note that this
+ *	command only functions correctly on properly formed Tcl UTF strings.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+StringRplcCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    Tcl_UniChar *ustring;
+    int first, last, length;
+
+    if (objc < 4 || objc > 5) {
+	Tcl_WrongNumArgs(interp, 1, objv, "string first last ?string?");
+	return TCL_ERROR;
+    }
+
+    ustring = Tcl_GetUnicodeFromObj(objv[1], &length);
+    length--;
+
+    if (TclGetIntForIndexM(interp, objv[2], length, &first) != TCL_OK ||
+	    TclGetIntForIndexM(interp, objv[3], length, &last) != TCL_OK){
+	return TCL_ERROR;
+    }
+
+    if ((last < first) || (last < 0) || (first > length)) {
+	Tcl_SetObjResult(interp, objv[1]);
+    } else {
+	Tcl_Obj *resultPtr;
+
+	ustring = Tcl_GetUnicodeFromObj(objv[1], &length);
+	length--;
+
+	if (first < 0) {
+	    first = 0;
+	}
+
+	resultPtr = Tcl_NewUnicodeObj(ustring, first);
+	if (objc == 5) {
+	    Tcl_AppendObjToObj(resultPtr, objv[4]);
+	}
+	if (last < length) {
+	    Tcl_AppendUnicodeToObj(resultPtr, ustring + last + 1,
+		    length - last);
+	}
+	Tcl_SetObjResult(interp, resultPtr);
+    }
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * StringRevCmd --
+ *
+ *	This procedure is invoked to process the "string reverse" Tcl command.
+ *	See the user documentation for details on what it does. Note that this
+ *	command only functions correctly on properly formed Tcl UTF strings.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+StringRevCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    if (objc != 2) {
+	Tcl_WrongNumArgs(interp, 1, objv, "string");
+	return TCL_ERROR;
+    }
+
+    Tcl_SetObjResult(interp, TclStringObjReverse(objv[1]));
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * StringStartCmd --
+ *
+ *	This procedure is invoked to process the "string wordstart" Tcl
+ *	command. See the user documentation for details on what it does. Note
+ *	that this command only functions correctly on properly formed Tcl UTF
+ *	strings.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+StringStartCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    Tcl_UniChar ch;
+    const char *p, *string;
+    int cur, index, length, numChars;
+
+    if (objc != 3) {
+	Tcl_WrongNumArgs(interp, 1, objv, "string index");
+	return TCL_ERROR;
+    }
+
+    string = TclGetStringFromObj(objv[1], &length);
+    numChars = Tcl_NumUtfChars(string, length);
+    if (TclGetIntForIndexM(interp, objv[2], numChars-1, &index) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    string = TclGetStringFromObj(objv[1], &length);
+    if (index >= numChars) {
+	index = numChars - 1;
+    }
+    cur = 0;
+    if (index > 0) {
+	p = Tcl_UtfAtIndex(string, index);
+	for (cur = index; cur >= 0; cur--) {
+	    TclUtfToUniChar(p, &ch);
+	    if (!Tcl_UniCharIsWordChar(ch)) {
+		break;
+	    }
+	    p = Tcl_UtfPrev(p, string);
+	}
+	if (cur != index) {
+	    cur += 1;
+	}
+    }
+    Tcl_SetObjResult(interp, Tcl_NewIntObj(cur));
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * StringEndCmd --
+ *
+ *	This procedure is invoked to process the "string wordend" Tcl command.
+ *	See the user documentation for details on what it does. Note that this
+ *	command only functions correctly on properly formed Tcl UTF strings.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+StringEndCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    Tcl_UniChar ch;
+    const char *p, *end, *string;
+    int cur, index, length, numChars;
+
+    if (objc != 3) {
+	Tcl_WrongNumArgs(interp, 1, objv, "string index");
+	return TCL_ERROR;
+    }
+
+    string = TclGetStringFromObj(objv[1], &length);
+    numChars = Tcl_NumUtfChars(string, length);
+    if (TclGetIntForIndexM(interp, objv[2], numChars-1, &index) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    string = TclGetStringFromObj(objv[1], &length);
+    if (index < 0) {
+	index = 0;
+    }
+    if (index < numChars) {
+	p = Tcl_UtfAtIndex(string, index);
+	end = string+length;
+	for (cur = index; p < end; cur++) {
+	    p += TclUtfToUniChar(p, &ch);
+	    if (!Tcl_UniCharIsWordChar(ch)) {
+		break;
+	    }
+	}
+	if (cur == index) {
+	    cur++;
+	}
+    } else {
+	cur = numChars;
+    }
+    Tcl_SetObjResult(interp, Tcl_NewIntObj(cur));
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * StringEqualCmd --
+ *
+ *	This procedure is invoked to process the "string equal" Tcl command.
+ *	See the user documentation for details on what it does. Note that this
+ *	command only functions correctly on properly formed Tcl UTF strings.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+StringEqualCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    /*
+     * Remember to keep code here in some sync with the byte-compiled versions
+     * in tclExecute.c (INST_STR_EQ, INST_STR_NEQ and INST_STR_CMP as well as
+     * the expr string comparison in INST_EQ/INST_NEQ/INST_LT/...).
+     */
+
+    const char *string1, *string2;
+    int length1, length2, i, match, length, nocase = 0, reqlength = -1;
+    typedef int (*strCmpFn_t)(const char *, const char *, unsigned int);
+    strCmpFn_t strCmpFn;
+
+    if (objc < 3 || objc > 6) {
+    str_cmp_args:
+	Tcl_WrongNumArgs(interp, 1, objv,
+		"?-nocase? ?-length int? string1 string2");
+	return TCL_ERROR;
+    }
+
+    for (i = 1; i < objc-2; i++) {
+	string2 = TclGetStringFromObj(objv[i], &length2);
+	if ((length2 > 1) && !strncmp(string2, "-nocase", (size_t)length2)) {
+	    nocase = 1;
+	} else if ((length2 > 1)
+		&& !strncmp(string2, "-length", (size_t)length2)) {
+	    if (i+1 >= objc-2) {
+		goto str_cmp_args;
+	    }
+	    i++;
+	    if (TclGetIntFromObj(interp, objv[i], &reqlength) != TCL_OK) {
+		return TCL_ERROR;
+	    }
+	} else {
+	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		    "bad option \"%s\": must be -nocase or -length",
+		    string2));
+	    Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "INDEX", "option",
+		    string2, NULL);
+	    return TCL_ERROR;
+	}
+    }
+
+    /*
+     * From now on, we only access the two objects at the end of the argument
+     * array.
+     */
+
+    objv += objc-2;
+
+    if ((reqlength == 0) || (objv[0] == objv[1])) {
+	/*
+	 * Always match at 0 chars of if it is the same obj.
+	 */
+
+	Tcl_SetObjResult(interp, Tcl_NewBooleanObj(1));
+	return TCL_OK;
+    }
+
+    if (!nocase && TclIsPureByteArray(objv[0]) &&
+	    TclIsPureByteArray(objv[1])) {
+	/*
+	 * Use binary versions of comparisons since that won't cause undue
+	 * type conversions and it is much faster. Only do this if we're
+	 * case-sensitive (which is all that really makes sense with byte
+	 * arrays anyway, and we have no memcasecmp() for some reason... :^)
+	 */
+
+	string1 = (char *) Tcl_GetByteArrayFromObj(objv[0], &length1);
+	string2 = (char *) Tcl_GetByteArrayFromObj(objv[1], &length2);
+	strCmpFn = (strCmpFn_t) memcmp;
+    } else if ((objv[0]->typePtr == &tclStringType)
+	    && (objv[1]->typePtr == &tclStringType)) {
+	/*
+	 * Do a unicode-specific comparison if both of the args are of String
+	 * type. In benchmark testing this proved the most efficient check
+	 * between the unicode and string comparison operations.
+	 */
+
+	string1 = (char *) Tcl_GetUnicodeFromObj(objv[0], &length1);
+	string2 = (char *) Tcl_GetUnicodeFromObj(objv[1], &length2);
+	strCmpFn = (strCmpFn_t)
+		(nocase ? Tcl_UniCharNcasecmp : Tcl_UniCharNcmp);
+    } else {
+	/*
+	 * As a catch-all we will work with UTF-8. We cannot use memcmp() as
+	 * that is unsafe with any string containing NUL (\xC0\x80 in Tcl's
+	 * utf rep). We can use the more efficient TclpUtfNcmp2 if we are
+	 * case-sensitive and no specific length was requested.
+	 */
+
+	string1 = (char *) TclGetStringFromObj(objv[0], &length1);
+	string2 = (char *) TclGetStringFromObj(objv[1], &length2);
+	if ((reqlength < 0) && !nocase) {
+	    strCmpFn = (strCmpFn_t) TclpUtfNcmp2;
+	} else {
+	    length1 = Tcl_NumUtfChars(string1, length1);
+	    length2 = Tcl_NumUtfChars(string2, length2);
+	    strCmpFn = (strCmpFn_t) (nocase ? Tcl_UtfNcasecmp : Tcl_UtfNcmp);
+	}
+    }
+
+    if ((reqlength < 0) && (length1 != length2)) {
+	match = 1;		/* This will be reversed below. */
+    } else {
+	length = (length1 < length2) ? length1 : length2;
+	if (reqlength > 0 && reqlength < length) {
+	    length = reqlength;
+	} else if (reqlength < 0) {
+	    /*
+	     * The requested length is negative, so we ignore it by setting it
+	     * to length + 1 so we correct the match var.
+	     */
+
+	    reqlength = length + 1;
+	}
+
+	match = strCmpFn(string1, string2, (unsigned) length);
+	if ((match == 0) && (reqlength > length)) {
+	    match = length1 - length2;
+	}
+    }
+
+    Tcl_SetObjResult(interp, Tcl_NewBooleanObj(match ? 0 : 1));
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * StringCmpCmd --
+ *
+ *	This procedure is invoked to process the "string compare" Tcl command.
+ *	See the user documentation for details on what it does. Note that this
+ *	command only functions correctly on properly formed Tcl UTF strings.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+StringCmpCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    /*
+     * Remember to keep code here in some sync with the byte-compiled versions
+     * in tclExecute.c (INST_STR_EQ, INST_STR_NEQ and INST_STR_CMP as well as
+     * the expr string comparison in INST_EQ/INST_NEQ/INST_LT/...).
+     */
+
+    const char *string1, *string2;
+    int length1, length2, i, match, length, nocase = 0, reqlength = -1;
+    typedef int (*strCmpFn_t)(const char *, const char *, unsigned int);
+    strCmpFn_t strCmpFn;
+
+    if (objc < 3 || objc > 6) {
+    str_cmp_args:
+	Tcl_WrongNumArgs(interp, 1, objv,
+		"?-nocase? ?-length int? string1 string2");
+	return TCL_ERROR;
+    }
+
+    for (i = 1; i < objc-2; i++) {
+	string2 = TclGetStringFromObj(objv[i], &length2);
+	if ((length2 > 1) && !strncmp(string2, "-nocase", (size_t)length2)) {
+	    nocase = 1;
+	} else if ((length2 > 1)
+		&& !strncmp(string2, "-length", (size_t)length2)) {
+	    if (i+1 >= objc-2) {
+		goto str_cmp_args;
+	    }
+	    i++;
+	    if (TclGetIntFromObj(interp, objv[i], &reqlength) != TCL_OK) {
+		return TCL_ERROR;
+	    }
+	} else {
+	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		    "bad option \"%s\": must be -nocase or -length",
+		    string2));
+	    Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "INDEX", "option",
+		    string2, NULL);
+	    return TCL_ERROR;
+	}
+    }
+
+    /*
+     * From now on, we only access the two objects at the end of the argument
+     * array.
+     */
+
+    objv += objc-2;
+
+    if ((reqlength == 0) || (objv[0] == objv[1])) {
+	/*
+	 * Always match at 0 chars of if it is the same obj.
+	 */
+
+	Tcl_SetObjResult(interp, Tcl_NewBooleanObj(0));
+	return TCL_OK;
+    }
+
+    if (!nocase && TclIsPureByteArray(objv[0]) &&
+	    TclIsPureByteArray(objv[1])) {
+	/*
+	 * Use binary versions of comparisons since that won't cause undue
+	 * type conversions and it is much faster. Only do this if we're
+	 * case-sensitive (which is all that really makes sense with byte
+	 * arrays anyway, and we have no memcasecmp() for some reason... :^)
+	 */
+
+	string1 = (char *) Tcl_GetByteArrayFromObj(objv[0], &length1);
+	string2 = (char *) Tcl_GetByteArrayFromObj(objv[1], &length2);
+	strCmpFn = (strCmpFn_t) memcmp;
+    } else if ((objv[0]->typePtr == &tclStringType)
+	    && (objv[1]->typePtr == &tclStringType)) {
+	/*
+	 * Do a unicode-specific comparison if both of the args are of String
+	 * type. In benchmark testing this proved the most efficient check
+	 * between the unicode and string comparison operations.
+	 */
+
+	string1 = (char *) Tcl_GetUnicodeFromObj(objv[0], &length1);
+	string2 = (char *) Tcl_GetUnicodeFromObj(objv[1], &length2);
+	strCmpFn = (strCmpFn_t)
+		(nocase ? Tcl_UniCharNcasecmp : Tcl_UniCharNcmp);
+    } else {
+	/*
+	 * As a catch-all we will work with UTF-8. We cannot use memcmp() as
+	 * that is unsafe with any string containing NUL (\xC0\x80 in Tcl's
+	 * utf rep). We can use the more efficient TclpUtfNcmp2 if we are
+	 * case-sensitive and no specific length was requested.
+	 */
+
+	string1 = (char *) TclGetStringFromObj(objv[0], &length1);
+	string2 = (char *) TclGetStringFromObj(objv[1], &length2);
+	if ((reqlength < 0) && !nocase) {
+	    strCmpFn = (strCmpFn_t) TclpUtfNcmp2;
+	} else {
+	    length1 = Tcl_NumUtfChars(string1, length1);
+	    length2 = Tcl_NumUtfChars(string2, length2);
+	    strCmpFn = (strCmpFn_t) (nocase ? Tcl_UtfNcasecmp : Tcl_UtfNcmp);
+	}
+    }
+
+    length = (length1 < length2) ? length1 : length2;
+    if (reqlength > 0 && reqlength < length) {
+	length = reqlength;
+    } else if (reqlength < 0) {
+	/*
+	 * The requested length is negative, so we ignore it by setting it to
+	 * length + 1 so we correct the match var.
+	 */
+
+	reqlength = length + 1;
+    }
+
+    match = strCmpFn(string1, string2, (unsigned) length);
+    if ((match == 0) && (reqlength > length)) {
+	match = length1 - length2;
+    }
+
+    Tcl_SetObjResult(interp,
+	    Tcl_NewIntObj((match > 0) ? 1 : (match < 0) ? -1 : 0));
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * StringCatCmd --
+ *
+ *	This procedure is invoked to process the "string cat" Tcl command.
+ *	See the user documentation for details on what it does.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+StringCatCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    int i;
+    Tcl_Obj *objResultPtr;
+
+    if (objc < 2) {
+	/*
+	 * If there are no args, the result is an empty object.
+	 * Just leave the preset empty interp result.
+	 */
+	return TCL_OK;
+    }
+    if (objc == 2) {
+	/*
+	 * Other trivial case, single arg, just return it.
+	 */
+	Tcl_SetObjResult(interp, objv[1]);
+	return TCL_OK;
+    }
+    objResultPtr = objv[1];
+    if (Tcl_IsShared(objResultPtr)) {
+	objResultPtr = Tcl_DuplicateObj(objResultPtr);
+    }
+    for(i = 2;i < objc;i++) {
+	Tcl_AppendObjToObj(objResultPtr, objv[i]);
+    }
+    Tcl_SetObjResult(interp, objResultPtr);
+
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * StringBytesCmd --
+ *
+ *	This procedure is invoked to process the "string bytelength" Tcl
+ *	command. See the user documentation for details on what it does. Note
+ *	that this command only functions correctly on properly formed Tcl UTF
+ *	strings.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+StringBytesCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    int length;
+
+    if (objc != 2) {
+	Tcl_WrongNumArgs(interp, 1, objv, "string");
+	return TCL_ERROR;
+    }
+
+    (void) TclGetStringFromObj(objv[1], &length);
+    Tcl_SetObjResult(interp, Tcl_NewIntObj(length));
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * StringLenCmd --
+ *
+ *	This procedure is invoked to process the "string length" Tcl command.
+ *	See the user documentation for details on what it does. Note that this
+ *	command only functions correctly on properly formed Tcl UTF strings.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+StringLenCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    if (objc != 2) {
+	Tcl_WrongNumArgs(interp, 1, objv, "string");
+	return TCL_ERROR;
+    }
+
+    Tcl_SetObjResult(interp, Tcl_NewIntObj(Tcl_GetCharLength(objv[1])));
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * StringLowerCmd --
+ *
+ *	This procedure is invoked to process the "string tolower" Tcl command.
+ *	See the user documentation for details on what it does. Note that this
+ *	command only functions correctly on properly formed Tcl UTF strings.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+StringLowerCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    int length1, length2;
+    const char *string1;
+    char *string2;
+
+    if (objc < 2 || objc > 4) {
+	Tcl_WrongNumArgs(interp, 1, objv, "string ?first? ?last?");
+	return TCL_ERROR;
+    }
+
+    string1 = TclGetStringFromObj(objv[1], &length1);
+
+    if (objc == 2) {
+	Tcl_Obj *resultPtr = Tcl_NewStringObj(string1, length1);
+
+	length1 = Tcl_UtfToLower(TclGetString(resultPtr));
+	Tcl_SetObjLength(resultPtr, length1);
+	Tcl_SetObjResult(interp, resultPtr);
+    } else {
+	int first, last;
+	const char *start, *end;
+	Tcl_Obj *resultPtr;
+
+	length1 = Tcl_NumUtfChars(string1, length1) - 1;
+	if (TclGetIntForIndexM(interp,objv[2],length1, &first) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	if (first < 0) {
+	    first = 0;
+	}
+	last = first;
+
+	if ((objc == 4) && (TclGetIntForIndexM(interp, objv[3], length1,
+		&last) != TCL_OK)) {
+	    return TCL_ERROR;
+	}
+
+	if (last >= length1) {
+	    last = length1;
+	}
+	if (last < first) {
+	    Tcl_SetObjResult(interp, objv[1]);
+	    return TCL_OK;
+	}
+
+	string1 = TclGetStringFromObj(objv[1], &length1);
+	start = Tcl_UtfAtIndex(string1, first);
+	end = Tcl_UtfAtIndex(start, last - first + 1);
+	resultPtr = Tcl_NewStringObj(string1, end - string1);
+	string2 = TclGetString(resultPtr) + (start - string1);
+
+	length2 = Tcl_UtfToLower(string2);
+	Tcl_SetObjLength(resultPtr, length2 + (start - string1));
+
+	Tcl_AppendToObj(resultPtr, end, -1);
+	Tcl_SetObjResult(interp, resultPtr);
+    }
+
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * StringUpperCmd --
+ *
+ *	This procedure is invoked to process the "string toupper" Tcl command.
+ *	See the user documentation for details on what it does. Note that this
+ *	command only functions correctly on properly formed Tcl UTF strings.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+StringUpperCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    int length1, length2;
+    const char *string1;
+    char *string2;
+
+    if (objc < 2 || objc > 4) {
+	Tcl_WrongNumArgs(interp, 1, objv, "string ?first? ?last?");
+	return TCL_ERROR;
+    }
+
+    string1 = TclGetStringFromObj(objv[1], &length1);
+
+    if (objc == 2) {
+	Tcl_Obj *resultPtr = Tcl_NewStringObj(string1, length1);
+
+	length1 = Tcl_UtfToUpper(TclGetString(resultPtr));
+	Tcl_SetObjLength(resultPtr, length1);
+	Tcl_SetObjResult(interp, resultPtr);
+    } else {
+	int first, last;
+	const char *start, *end;
+	Tcl_Obj *resultPtr;
+
+	length1 = Tcl_NumUtfChars(string1, length1) - 1;
+	if (TclGetIntForIndexM(interp,objv[2],length1, &first) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	if (first < 0) {
+	    first = 0;
+	}
+	last = first;
+
+	if ((objc == 4) && (TclGetIntForIndexM(interp, objv[3], length1,
+		&last) != TCL_OK)) {
+	    return TCL_ERROR;
+	}
+
+	if (last >= length1) {
+	    last = length1;
+	}
+	if (last < first) {
+	    Tcl_SetObjResult(interp, objv[1]);
+	    return TCL_OK;
+	}
+
+	string1 = TclGetStringFromObj(objv[1], &length1);
+	start = Tcl_UtfAtIndex(string1, first);
+	end = Tcl_UtfAtIndex(start, last - first + 1);
+	resultPtr = Tcl_NewStringObj(string1, end - string1);
+	string2 = TclGetString(resultPtr) + (start - string1);
+
+	length2 = Tcl_UtfToUpper(string2);
+	Tcl_SetObjLength(resultPtr, length2 + (start - string1));
+
+	Tcl_AppendToObj(resultPtr, end, -1);
+	Tcl_SetObjResult(interp, resultPtr);
+    }
+
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * StringTitleCmd --
+ *
+ *	This procedure is invoked to process the "string totitle" Tcl command.
+ *	See the user documentation for details on what it does. Note that this
+ *	command only functions correctly on properly formed Tcl UTF strings.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+StringTitleCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    int length1, length2;
+    const char *string1;
+    char *string2;
+
+    if (objc < 2 || objc > 4) {
+	Tcl_WrongNumArgs(interp, 1, objv, "string ?first? ?last?");
+	return TCL_ERROR;
+    }
+
+    string1 = TclGetStringFromObj(objv[1], &length1);
+
+    if (objc == 2) {
+	Tcl_Obj *resultPtr = Tcl_NewStringObj(string1, length1);
+
+	length1 = Tcl_UtfToTitle(TclGetString(resultPtr));
+	Tcl_SetObjLength(resultPtr, length1);
+	Tcl_SetObjResult(interp, resultPtr);
+    } else {
+	int first, last;
+	const char *start, *end;
+	Tcl_Obj *resultPtr;
+
+	length1 = Tcl_NumUtfChars(string1, length1) - 1;
+	if (TclGetIntForIndexM(interp,objv[2],length1, &first) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	if (first < 0) {
+	    first = 0;
+	}
+	last = first;
+
+	if ((objc == 4) && (TclGetIntForIndexM(interp, objv[3], length1,
+		&last) != TCL_OK)) {
+	    return TCL_ERROR;
+	}
+
+	if (last >= length1) {
+	    last = length1;
+	}
+	if (last < first) {
+	    Tcl_SetObjResult(interp, objv[1]);
+	    return TCL_OK;
+	}
+
+	string1 = TclGetStringFromObj(objv[1], &length1);
+	start = Tcl_UtfAtIndex(string1, first);
+	end = Tcl_UtfAtIndex(start, last - first + 1);
+	resultPtr = Tcl_NewStringObj(string1, end - string1);
+	string2 = TclGetString(resultPtr) + (start - string1);
+
+	length2 = Tcl_UtfToTitle(string2);
+	Tcl_SetObjLength(resultPtr, length2 + (start - string1));
+
+	Tcl_AppendToObj(resultPtr, end, -1);
+	Tcl_SetObjResult(interp, resultPtr);
+    }
+
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * StringTrimCmd --
+ *
+ *	This procedure is invoked to process the "string trim" Tcl command.
+ *	See the user documentation for details on what it does. Note that this
+ *	command only functions correctly on properly formed Tcl UTF strings.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+StringTrimCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    const char *string1, *string2;
+    int triml, trimr, length1, length2;
+
+    if (objc == 3) {
+	string2 = TclGetStringFromObj(objv[2], &length2);
+    } else if (objc == 2) {
+	string2 = tclDefaultTrimSet;
+	length2 = strlen(tclDefaultTrimSet);
+    } else {
+	Tcl_WrongNumArgs(interp, 1, objv, "string ?chars?");
+	return TCL_ERROR;
+    }
+    string1 = TclGetStringFromObj(objv[1], &length1);
+
+    triml = TclTrimLeft(string1, length1, string2, length2);
+    trimr = TclTrimRight(string1 + triml, length1 - triml, string2, length2);
+
+    Tcl_SetObjResult(interp,
+	    Tcl_NewStringObj(string1 + triml, length1 - triml - trimr));
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * StringTrimLCmd --
+ *
+ *	This procedure is invoked to process the "string trimleft" Tcl
+ *	command. See the user documentation for details on what it does. Note
+ *	that this command only functions correctly on properly formed Tcl UTF
+ *	strings.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+StringTrimLCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    const char *string1, *string2;
+    int trim, length1, length2;
+
+    if (objc == 3) {
+	string2 = TclGetStringFromObj(objv[2], &length2);
+    } else if (objc == 2) {
+	string2 = tclDefaultTrimSet;
+	length2 = strlen(tclDefaultTrimSet);
+    } else {
+	Tcl_WrongNumArgs(interp, 1, objv, "string ?chars?");
+	return TCL_ERROR;
+    }
+    string1 = TclGetStringFromObj(objv[1], &length1);
+
+    trim = TclTrimLeft(string1, length1, string2, length2);
+
+    Tcl_SetObjResult(interp, Tcl_NewStringObj(string1+trim, length1-trim));
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * StringTrimRCmd --
+ *
+ *	This procedure is invoked to process the "string trimright" Tcl
+ *	command. See the user documentation for details on what it does. Note
+ *	that this command only functions correctly on properly formed Tcl UTF
+ *	strings.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+StringTrimRCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    const char *string1, *string2;
+    int trim, length1, length2;
+
+    if (objc == 3) {
+	string2 = TclGetStringFromObj(objv[2], &length2);
+    } else if (objc == 2) {
+	string2 = tclDefaultTrimSet;
+	length2 = strlen(tclDefaultTrimSet);
+    } else {
+	Tcl_WrongNumArgs(interp, 1, objv, "string ?chars?");
+	return TCL_ERROR;
+    }
+    string1 = TclGetStringFromObj(objv[1], &length1);
+
+    trim = TclTrimRight(string1, length1, string2, length2);
+
+    Tcl_SetObjResult(interp, Tcl_NewStringObj(string1, length1-trim));
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclInitStringCmd --
+ *
+ *	This procedure creates the "string" Tcl command. See the user
+ *	documentation for details on what it does. Note that this command only
+ *	functions correctly on properly formed Tcl UTF strings.
+ *
+ *	Also note that the primary methods here (equal, compare, match, ...)
+ *	have bytecode equivalents. You will find the code for those in
+ *	tclExecute.c. The code here will only be used in the non-bc case (like
+ *	in an 'eval').
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_Command
+TclInitStringCmd(
+    Tcl_Interp *interp)		/* Current interpreter. */
+{
+    static const EnsembleImplMap stringImplMap[] = {
+	{"bytelength",	StringBytesCmd,	TclCompileBasic1ArgCmd, NULL, NULL, 0},
+	{"cat",		StringCatCmd,	TclCompileStringCatCmd, NULL, NULL, 0},
+	{"compare",	StringCmpCmd,	TclCompileStringCmpCmd, NULL, NULL, 0},
+	{"equal",	StringEqualCmd,	TclCompileStringEqualCmd, NULL, NULL, 0},
+	{"first",	StringFirstCmd,	TclCompileStringFirstCmd, NULL, NULL, 0},
+	{"index",	StringIndexCmd,	TclCompileStringIndexCmd, NULL, NULL, 0},
+	{"is",		StringIsCmd,	TclCompileStringIsCmd, NULL, NULL, 0},
+	{"last",	StringLastCmd,	TclCompileStringLastCmd, NULL, NULL, 0},
+	{"length",	StringLenCmd,	TclCompileStringLenCmd, NULL, NULL, 0},
+	{"map",		StringMapCmd,	TclCompileStringMapCmd, NULL, NULL, 0},
+	{"match",	StringMatchCmd,	TclCompileStringMatchCmd, NULL, NULL, 0},
+	{"range",	StringRangeCmd,	TclCompileStringRangeCmd, NULL, NULL, 0},
+	{"repeat",	StringReptCmd,	TclCompileBasic2ArgCmd, NULL, NULL, 0},
+	{"replace",	StringRplcCmd,	TclCompileStringReplaceCmd, NULL, NULL, 0},
+	{"reverse",	StringRevCmd,	TclCompileBasic1ArgCmd, NULL, NULL, 0},
+	{"tolower",	StringLowerCmd,	TclCompileStringToLowerCmd, NULL, NULL, 0},
+	{"toupper",	StringUpperCmd,	TclCompileStringToUpperCmd, NULL, NULL, 0},
+	{"totitle",	StringTitleCmd,	TclCompileStringToTitleCmd, NULL, NULL, 0},
+	{"trim",	StringTrimCmd,	TclCompileStringTrimCmd, NULL, NULL, 0},
+	{"trimleft",	StringTrimLCmd,	TclCompileStringTrimLCmd, NULL, NULL, 0},
+	{"trimright",	StringTrimRCmd,	TclCompileStringTrimRCmd, NULL, NULL, 0},
+	{"wordend",	StringEndCmd,	TclCompileBasic2ArgCmd, NULL, NULL, 0},
+	{"wordstart",	StringStartCmd,	TclCompileBasic2ArgCmd, NULL, NULL, 0},
+	{NULL, NULL, NULL, NULL, NULL, 0}
+    };
+
+    return TclMakeEnsemble(interp, "string", stringImplMap);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_SubstObjCmd --
+ *
+ *	This procedure is invoked to process the "subst" Tcl command. See the
+ *	user documentation for details on what it does. This command relies on
+ *	Tcl_SubstObj() for its implementation.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclSubstOptions(
+    Tcl_Interp *interp,
+    int numOpts,
+    Tcl_Obj *const opts[],
+    int *flagPtr)
+{
+    static const char *const substOptions[] = {
+	"-nobackslashes", "-nocommands", "-novariables", NULL
+    };
+    enum {
+	SUBST_NOBACKSLASHES, SUBST_NOCOMMANDS, SUBST_NOVARS
+    };
+    int i, flags = TCL_SUBST_ALL;
+
+    for (i = 0; i < numOpts; i++) {
+	int optionIndex;
+
+	if (Tcl_GetIndexFromObj(interp, opts[i], substOptions, "option", 0,
+		&optionIndex) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	switch (optionIndex) {
+	case SUBST_NOBACKSLASHES:
+	    flags &= ~TCL_SUBST_BACKSLASHES;
+	    break;
+	case SUBST_NOCOMMANDS:
+	    flags &= ~TCL_SUBST_COMMANDS;
+	    break;
+	case SUBST_NOVARS:
+	    flags &= ~TCL_SUBST_VARIABLES;
+	    break;
+	default:
+	    Tcl_Panic("Tcl_SubstObjCmd: bad option index to SubstOptions");
+	}
+    }
+    *flagPtr = flags;
+    return TCL_OK;
+}
+
+int
+Tcl_SubstObjCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    return Tcl_NRCallObjProc(interp, TclNRSubstObjCmd, dummy, objc, objv);
+}
+
+int
+TclNRSubstObjCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    int flags;
+
+    if (objc < 2) {
+	Tcl_WrongNumArgs(interp, 1, objv,
+		"?-nobackslashes? ?-nocommands? ?-novariables? string");
+	return TCL_ERROR;
+    }
+
+    if (TclSubstOptions(interp, objc-2, objv+1, &flags) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    return Tcl_NRSubstObj(interp, objv[objc-1], flags);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_SwitchObjCmd --
+ *
+ *	This object-based procedure is invoked to process the "switch" Tcl
+ *	command. See the user documentation for details on what it does.
+ *
+ * Results:
+ *	A standard Tcl object result.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_SwitchObjCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    return Tcl_NRCallObjProc(interp, TclNRSwitchObjCmd, dummy, objc, objv);
+}
+int
+TclNRSwitchObjCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    int i,j, index, mode, foundmode, splitObjs, numMatchesSaved;
+    int noCase, patternLength;
+    const char *pattern;
+    Tcl_Obj *stringObj, *indexVarObj, *matchVarObj;
+    Tcl_Obj *const *savedObjv = objv;
+    Tcl_RegExp regExpr = NULL;
+    Interp *iPtr = (Interp *) interp;
+    int pc = 0;
+    int bidx = 0;		/* Index of body argument. */
+    Tcl_Obj *blist = NULL;	/* List obj which is the body */
+    CmdFrame *ctxPtr;		/* Copy of the topmost cmdframe, to allow us
+				 * to mess with the line information */
+
+    /*
+     * If you add options that make -e and -g not unique prefixes of -exact or
+     * -glob, you *must* fix TclCompileSwitchCmd's option parser as well.
+     */
+
+    static const char *const options[] = {
+	"-exact", "-glob", "-indexvar", "-matchvar", "-nocase", "-regexp",
+	"--", NULL
+    };
+    enum options {
+	OPT_EXACT, OPT_GLOB, OPT_INDEXV, OPT_MATCHV, OPT_NOCASE, OPT_REGEXP,
+	OPT_LAST
+    };
+    typedef int (*strCmpFn_t)(const char *, const char *);
+    strCmpFn_t strCmpFn = strcmp;
+
+    mode = OPT_EXACT;
+    foundmode = 0;
+    indexVarObj = NULL;
+    matchVarObj = NULL;
+    numMatchesSaved = 0;
+    noCase = 0;
+    for (i = 1; i < objc-2; i++) {
+	if (TclGetString(objv[i])[0] != '-') {
+	    break;
+	}
+	if (Tcl_GetIndexFromObj(interp, objv[i], options, "option", 0,
+		&index) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	switch ((enum options) index) {
+	    /*
+	     * General options.
+	     */
+
+	case OPT_LAST:
+	    i++;
+	    goto finishedOptions;
+	case OPT_NOCASE:
+	    strCmpFn = TclUtfCasecmp;
+	    noCase = 1;
+	    break;
+
+	    /*
+	     * Handle the different switch mode options.
+	     */
+
+	default:
+	    if (foundmode) {
+		/*
+		 * Mode already set via -exact, -glob, or -regexp.
+		 */
+
+		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+			"bad option \"%s\": %s option already found",
+			TclGetString(objv[i]), options[mode]));
+		Tcl_SetErrorCode(interp, "TCL", "OPERATION", "SWITCH",
+			"DOUBLEOPT", NULL);
+		return TCL_ERROR;
+	    }
+	    foundmode = 1;
+	    mode = index;
+	    break;
+
+	    /*
+	     * Check for TIP#75 options specifying the variables to write
+	     * regexp information into.
+	     */
+
+	case OPT_INDEXV:
+	    i++;
+	    if (i >= objc-2) {
+		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+			"missing variable name argument to %s option",
+			"-indexvar"));
+		Tcl_SetErrorCode(interp, "TCL", "OPERATION", "SWITCH",
+			"NOVAR", NULL);
+		return TCL_ERROR;
+	    }
+	    indexVarObj = objv[i];
+	    numMatchesSaved = -1;
+	    break;
+	case OPT_MATCHV:
+	    i++;
+	    if (i >= objc-2) {
+		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+			"missing variable name argument to %s option",
+			"-matchvar"));
+		Tcl_SetErrorCode(interp, "TCL", "OPERATION", "SWITCH",
+			"NOVAR", NULL);
+		return TCL_ERROR;
+	    }
+	    matchVarObj = objv[i];
+	    numMatchesSaved = -1;
+	    break;
+	}
+    }
+
+  finishedOptions:
+    if (objc - i < 2) {
+	Tcl_WrongNumArgs(interp, 1, objv,
+		"?-option ...? string ?pattern body ...? ?default body?");
+	return TCL_ERROR;
+    }
+    if (indexVarObj != NULL && mode != OPT_REGEXP) {
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		"%s option requires -regexp option", "-indexvar"));
+	Tcl_SetErrorCode(interp, "TCL", "OPERATION", "SWITCH",
+		"MODERESTRICTION", NULL);
+	return TCL_ERROR;
+    }
+    if (matchVarObj != NULL && mode != OPT_REGEXP) {
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		"%s option requires -regexp option", "-matchvar"));
+	Tcl_SetErrorCode(interp, "TCL", "OPERATION", "SWITCH",
+		"MODERESTRICTION", NULL);
+	return TCL_ERROR;
+    }
+
+    stringObj = objv[i];
+    objc -= i + 1;
+    objv += i + 1;
+    bidx = i + 1;		/* First after the match string. */
+
+    /*
+     * If all of the pattern/command pairs are lumped into a single argument,
+     * split them out again.
+     *
+     * TIP #280: Determine the lines the words in the list start at, based on
+     * the same data for the list word itself. The cmdFramePtr line
+     * information is manipulated directly.
+     */
+
+    splitObjs = 0;
+    if (objc == 1) {
+	Tcl_Obj **listv;
+
+	blist = objv[0];
+	if (TclListObjGetElements(interp, objv[0], &objc, &listv) != TCL_OK){
+	    return TCL_ERROR;
+	}
+
+	/*
+	 * Ensure that the list is non-empty.
+	 */
+
+	if (objc < 1) {
+	    Tcl_WrongNumArgs(interp, 1, savedObjv,
+		    "?-option ...? string {?pattern body ...? ?default body?}");
+	    return TCL_ERROR;
+	}
+	objv = listv;
+	splitObjs = 1;
+    }
+
+    /*
+     * Complain if there is an odd number of words in the list of patterns and
+     * bodies.
+     */
+
+    if (objc % 2) {
+	Tcl_ResetResult(interp);
+	Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		"extra switch pattern with no body", -1));
+	Tcl_SetErrorCode(interp, "TCL", "OPERATION", "SWITCH", "BADARM",
+		NULL);
+
+	/*
+	 * Check if this can be due to a badly placed comment in the switch
+	 * block.
+	 *
+	 * The following is an heuristic to detect the infamous "comment in
+	 * switch" error: just check if a pattern begins with '#'.
+	 */
+
+	if (splitObjs) {
+	    for (i=0 ; i<objc ; i+=2) {
+		if (TclGetString(objv[i])[0] == '#') {
+		    Tcl_AppendToObj(Tcl_GetObjResult(interp),
+			    ", this may be due to a comment incorrectly"
+			    " placed outside of a switch body - see the"
+			    " \"switch\" documentation", -1);
+		    Tcl_SetErrorCode(interp, "TCL", "OPERATION", "SWITCH",
+			    "BADARM", "COMMENT?", NULL);
+		    break;
+		}
+	    }
+	}
+
+	return TCL_ERROR;
+    }
+
+    /*
+     * Complain if the last body is a continuation. Note that this check
+     * assumes that the list is non-empty!
+     */
+
+    if (strcmp(TclGetString(objv[objc-1]), "-") == 0) {
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		"no body specified for pattern \"%s\"",
+		TclGetString(objv[objc-2])));
+	Tcl_SetErrorCode(interp, "TCL", "OPERATION", "SWITCH", "BADARM",
+		"FALLTHROUGH", NULL);
+	return TCL_ERROR;
+    }
+
+    for (i = 0; i < objc; i += 2) {
+	/*
+	 * See if the pattern matches the string.
+	 */
+
+	pattern = TclGetStringFromObj(objv[i], &patternLength);
+
+	if ((i == objc - 2) && (*pattern == 'd')
+		&& (strcmp(pattern, "default") == 0)) {
+	    Tcl_Obj *emptyObj = NULL;
+
+	    /*
+	     * If either indexVarObj or matchVarObj are non-NULL, we're in
+	     * REGEXP mode but have reached the default clause anyway. TIP#75
+	     * specifies that we set the variables to empty lists (== empty
+	     * objects) in that case.
+	     */
+
+	    if (indexVarObj != NULL) {
+		TclNewObj(emptyObj);
+		if (Tcl_ObjSetVar2(interp, indexVarObj, NULL, emptyObj,
+			TCL_LEAVE_ERR_MSG) == NULL) {
+		    return TCL_ERROR;
+		}
+	    }
+	    if (matchVarObj != NULL) {
+		if (emptyObj == NULL) {
+		    TclNewObj(emptyObj);
+		}
+		if (Tcl_ObjSetVar2(interp, matchVarObj, NULL, emptyObj,
+			TCL_LEAVE_ERR_MSG) == NULL) {
+		    return TCL_ERROR;
+		}
+	    }
+	    goto matchFound;
+	}
+
+	switch (mode) {
+	case OPT_EXACT:
+	    if (strCmpFn(TclGetString(stringObj), pattern) == 0) {
+		goto matchFound;
+	    }
+	    break;
+	case OPT_GLOB:
+	    if (Tcl_StringCaseMatch(TclGetString(stringObj),pattern,noCase)) {
+		goto matchFound;
+	    }
+	    break;
+	case OPT_REGEXP:
+	    regExpr = Tcl_GetRegExpFromObj(interp, objv[i],
+		    TCL_REG_ADVANCED | (noCase ? TCL_REG_NOCASE : 0));
+	    if (regExpr == NULL) {
+		return TCL_ERROR;
+	    } else {
+		int matched = Tcl_RegExpExecObj(interp, regExpr, stringObj, 0,
+			numMatchesSaved, 0);
+
+		if (matched < 0) {
+		    return TCL_ERROR;
+		} else if (matched) {
+		    goto matchFoundRegexp;
+		}
+	    }
+	    break;
+	}
+    }
+    return TCL_OK;
+
+  matchFoundRegexp:
+    /*
+     * We are operating in REGEXP mode and we need to store information about
+     * what we matched in some user-nominated arrays. So build the lists of
+     * values and indices to write here. [TIP#75]
+     */
+
+    if (numMatchesSaved) {
+	Tcl_RegExpInfo info;
+	Tcl_Obj *matchesObj, *indicesObj = NULL;
+
+	Tcl_RegExpGetInfo(regExpr, &info);
+	if (matchVarObj != NULL) {
+	    TclNewObj(matchesObj);
+	} else {
+	    matchesObj = NULL;
+	}
+	if (indexVarObj != NULL) {
+	    TclNewObj(indicesObj);
+	}
+
+	for (j=0 ; j<=info.nsubs ; j++) {
+	    if (indexVarObj != NULL) {
+		Tcl_Obj *rangeObjAry[2];
+
+		if (info.matches[j].end > 0) {
+		    rangeObjAry[0] = Tcl_NewLongObj(info.matches[j].start);
+		    rangeObjAry[1] = Tcl_NewLongObj(info.matches[j].end-1);
+		} else {
+		    rangeObjAry[0] = rangeObjAry[1] = Tcl_NewIntObj(-1);
+		}
+
+		/*
+		 * Never fails; the object is always clean at this point.
+		 */
+
+		Tcl_ListObjAppendElement(NULL, indicesObj,
+			Tcl_NewListObj(2, rangeObjAry));
+	    }
+
+	    if (matchVarObj != NULL) {
+		Tcl_Obj *substringObj;
+
+		substringObj = Tcl_GetRange(stringObj,
+			info.matches[j].start, info.matches[j].end-1);
+
+		/*
+		 * Never fails; the object is always clean at this point.
+		 */
+
+		Tcl_ListObjAppendElement(NULL, matchesObj, substringObj);
+	    }
+	}
+
+	if (indexVarObj != NULL) {
+	    if (Tcl_ObjSetVar2(interp, indexVarObj, NULL, indicesObj,
+		    TCL_LEAVE_ERR_MSG) == NULL) {
+		/*
+		 * Careful! Check to see if we have allocated the list of
+		 * matched strings; if so (but there was an error assigning
+		 * the indices list) we have a potential memory leak because
+		 * the match list has not been written to a variable. Except
+		 * that we'll clean that up right now.
+		 */
+
+		if (matchesObj != NULL) {
+		    Tcl_DecrRefCount(matchesObj);
+		}
+		return TCL_ERROR;
+	    }
+	}
+	if (matchVarObj != NULL) {
+	    if (Tcl_ObjSetVar2(interp, matchVarObj, NULL, matchesObj,
+		    TCL_LEAVE_ERR_MSG) == NULL) {
+		/*
+		 * Unlike above, if indicesObj is non-NULL at this point, it
+		 * will have been written to a variable already and will hence
+		 * not be leaked.
+		 */
+
+		return TCL_ERROR;
+	    }
+	}
+    }
+
+    /*
+     * We've got a match. Find a body to execute, skipping bodies that are
+     * "-".
+     */
+
+  matchFound:
+    ctxPtr = TclStackAlloc(interp, sizeof(CmdFrame));
+    *ctxPtr = *iPtr->cmdFramePtr;
+
+    if (splitObjs) {
+	/*
+	 * We have to perform the GetSrc and other type dependent handling of
+	 * the frame here because we are munging with the line numbers,
+	 * something the other commands like if, etc. are not doing. Them are
+	 * fine with simply passing the CmdFrame through and having the
+	 * special handling done in 'info frame', or the bc compiler
+	 */
+
+	if (ctxPtr->type == TCL_LOCATION_BC) {
+	    /*
+	     * Type BC => ctxPtr->data.eval.path    is not used.
+	     *		  ctxPtr->data.tebc.codePtr is used instead.
+	     */
+
+	    TclGetSrcInfoForPc(ctxPtr);
+	    pc = 1;
+
+	    /*
+	     * The line information in the cmdFrame is now a copy we do not
+	     * own.
+	     */
+	}
+
+	if (ctxPtr->type == TCL_LOCATION_SOURCE && ctxPtr->line[bidx] >= 0) {
+	    int bline = ctxPtr->line[bidx];
+
+	    ctxPtr->line = ckalloc(objc * sizeof(int));
+	    ctxPtr->nline = objc;
+	    TclListLines(blist, bline, objc, ctxPtr->line, objv);
+	} else {
+	    /*
+	     * This is either a dynamic code word, when all elements are
+	     * relative to themselves, or something else less expected and
+	     * where we have no information. The result is the same in both
+	     * cases; tell the code to come that it doesn't know where it is,
+	     * which triggers reversion to the old behavior.
+	     */
+
+	    int k;
+
+	    ctxPtr->line = ckalloc(objc * sizeof(int));
+	    ctxPtr->nline = objc;
+	    for (k=0; k < objc; k++) {
+		ctxPtr->line[k] = -1;
+	    }
+	}
+    }
+
+    for (j = i + 1; ; j += 2) {
+	if (j >= objc) {
+	    /*
+	     * This shouldn't happen since we've checked that the last body is
+	     * not a continuation...
+	     */
+
+	    Tcl_Panic("fall-out when searching for body to match pattern");
+	}
+	if (strcmp(TclGetString(objv[j]), "-") != 0) {
+	    break;
+	}
+    }
+
+    /*
+     * TIP #280: Make invoking context available to switch branch.
+     */
+
+    Tcl_NRAddCallback(interp, SwitchPostProc, INT2PTR(splitObjs), ctxPtr,
+	    INT2PTR(pc), (ClientData) pattern);
+    return TclNREvalObjEx(interp, objv[j], 0, ctxPtr, splitObjs ? j : bidx+j);
+}
+
+static int
+SwitchPostProc(
+    ClientData data[],		/* Data passed from Tcl_NRAddCallback above */
+    Tcl_Interp *interp,		/* Tcl interpreter */
+    int result)			/* Result to return*/
+{
+    /* Unpack the preserved data */
+
+    int splitObjs = PTR2INT(data[0]);
+    CmdFrame *ctxPtr = data[1];
+    int pc = PTR2INT(data[2]);
+    const char *pattern = data[3];
+    int patternLength = strlen(pattern);
+
+    /*
+     * Clean up TIP 280 context information
+     */
+
+    if (splitObjs) {
+	ckfree(ctxPtr->line);
+	if (pc && (ctxPtr->type == TCL_LOCATION_SOURCE)) {
+	    /*
+	     * Death of SrcInfo reference.
+	     */
+
+	    Tcl_DecrRefCount(ctxPtr->data.eval.path);
+	}
+    }
+
+    /*
+     * Generate an error message if necessary.
+     */
+
+    if (result == TCL_ERROR) {
+	int limit = 50;
+	int overflow = (patternLength > limit);
+
+	Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf(
+		"\n    (\"%.*s%s\" arm line %d)",
+		(overflow ? limit : patternLength), pattern,
+		(overflow ? "..." : ""), Tcl_GetErrorLine(interp)));
+    }
+    TclStackFree(interp, ctxPtr);
+    return result;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_ThrowObjCmd --
+ *
+ *	This procedure is invoked to process the "throw" Tcl command. See the
+ *	user documentation for details on what it does.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+	/* ARGSUSED */
+int
+Tcl_ThrowObjCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    Tcl_Obj *options;
+    int len;
+
+    if (objc != 3) {
+	Tcl_WrongNumArgs(interp, 1, objv, "type message");
+	return TCL_ERROR;
+    }
+
+    /*
+     * The type must be a list of at least length 1.
+     */
+
+    if (Tcl_ListObjLength(interp, objv[1], &len) != TCL_OK) {
+	return TCL_ERROR;
+    } else if (len < 1) {
+	Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		"type must be non-empty list", -1));
+	Tcl_SetErrorCode(interp, "TCL", "OPERATION", "THROW", "BADEXCEPTION",
+		NULL);
+	return TCL_ERROR;
+    }
+
+    /*
+     * Now prepare the result options dictionary. We use the list API as it is
+     * slightly more convenient.
+     */
+
+    TclNewLiteralStringObj(options, "-code error -level 0 -errorcode");
+    Tcl_ListObjAppendElement(NULL, options, objv[1]);
+
+    /*
+     * We're ready to go. Fire things into the low-level result machinery.
+     */
+
+    Tcl_SetObjResult(interp, objv[2]);
+    return Tcl_SetReturnOptions(interp, options);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_TimeObjCmd --
+ *
+ *	This object-based procedure is invoked to process the "time" Tcl
+ *	command. See the user documentation for details on what it does.
+ *
+ * Results:
+ *	A standard Tcl object result.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_TimeObjCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    register Tcl_Obj *objPtr;
+    Tcl_Obj *objs[4];
+    register int i, result;
+    int count;
+    double totalMicroSec;
+#ifndef TCL_WIDE_CLICKS
+    Tcl_Time start, stop;
+#else
+    Tcl_WideInt start, stop;
+#endif
+
+    if (objc == 2) {
+	count = 1;
+    } else if (objc == 3) {
+	result = TclGetIntFromObj(interp, objv[2], &count);
+	if (result != TCL_OK) {
+	    return result;
+	}
+    } else {
+	Tcl_WrongNumArgs(interp, 1, objv, "command ?count?");
+	return TCL_ERROR;
+    }
+
+    objPtr = objv[1];
+    i = count;
+#ifndef TCL_WIDE_CLICKS
+    Tcl_GetTime(&start);
+#else
+    start = TclpGetWideClicks();
+#endif
+    while (i-- > 0) {
+	result = Tcl_EvalObjEx(interp, objPtr, 0);
+	if (result != TCL_OK) {
+	    return result;
+	}
+    }
+#ifndef TCL_WIDE_CLICKS
+    Tcl_GetTime(&stop);
+    totalMicroSec = ((double) (stop.sec - start.sec)) * 1.0e6
+	    + (stop.usec - start.usec);
+#else
+    stop = TclpGetWideClicks();
+    totalMicroSec = ((double) TclpWideClicksToNanoseconds(stop - start))/1.0e3;
+#endif
+
+    if (count <= 1) {
+	/*
+	 * Use int obj since we know time is not fractional. [Bug 1202178]
+	 */
+
+	objs[0] = Tcl_NewIntObj((count <= 0) ? 0 : (int) totalMicroSec);
+    } else {
+	objs[0] = Tcl_NewDoubleObj(totalMicroSec/count);
+    }
+
+    /*
+     * Construct the result as a list because many programs have always parsed
+     * as such (extracting the first element, typically).
+     */
+
+    TclNewLiteralStringObj(objs[1], "microseconds");
+    TclNewLiteralStringObj(objs[2], "per");
+    TclNewLiteralStringObj(objs[3], "iteration");
+    Tcl_SetObjResult(interp, Tcl_NewListObj(4, objs));
+
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_TryObjCmd, TclNRTryObjCmd --
+ *
+ *	This procedure is invoked to process the "try" Tcl command. See the
+ *	user documentation (or TIP #329) for details on what it does.
+ *
+ * Results:
+ *	A standard Tcl object result.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_TryObjCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    return Tcl_NRCallObjProc(interp, TclNRTryObjCmd, dummy, objc, objv);
+}
+
+int
+TclNRTryObjCmd(
+    ClientData clientData,	/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    Tcl_Obj *bodyObj, *handlersObj, *finallyObj = NULL;
+    int i, bodyShared, haveHandlers, dummy, code;
+    static const char *const handlerNames[] = {
+	"finally", "on", "trap", NULL
+    };
+    enum Handlers {
+	TryFinally, TryOn, TryTrap
+    };
+
+    /*
+     * Parse the arguments. The handlers are passed to subsequent callbacks as
+     * a Tcl_Obj list of the 5-tuples like (type, returnCode, errorCodePrefix,
+     * bindVariables, script), and the finally script is just passed as it is.
+     */
+
+    if (objc < 2) {
+	Tcl_WrongNumArgs(interp, 1, objv,
+		"body ?handler ...? ?finally script?");
+	return TCL_ERROR;
+    }
+    bodyObj = objv[1];
+    handlersObj = Tcl_NewObj();
+    bodyShared = 0;
+    haveHandlers = 0;
+    for (i=2 ; i<objc ; i++) {
+	int type;
+	Tcl_Obj *info[5];
+
+	if (Tcl_GetIndexFromObj(interp, objv[i], handlerNames, "handler type",
+		0, &type) != TCL_OK) {
+	    Tcl_DecrRefCount(handlersObj);
+	    return TCL_ERROR;
+	}
+	switch ((enum Handlers) type) {
+	case TryFinally:	/* finally script */
+	    if (i < objc-2) {
+		Tcl_SetObjResult(interp, Tcl_NewStringObj(
+			"finally clause must be last", -1));
+		Tcl_DecrRefCount(handlersObj);
+		Tcl_SetErrorCode(interp, "TCL", "OPERATION", "TRY", "FINALLY",
+			"NONTERMINAL", NULL);
+		return TCL_ERROR;
+	    } else if (i == objc-1) {
+		Tcl_SetObjResult(interp, Tcl_NewStringObj(
+			"wrong # args to finally clause: must be"
+			" \"... finally script\"", -1));
+		Tcl_DecrRefCount(handlersObj);
+		Tcl_SetErrorCode(interp, "TCL", "OPERATION", "TRY", "FINALLY",
+			"ARGUMENT", NULL);
+		return TCL_ERROR;
+	    }
+	    finallyObj = objv[++i];
+	    break;
+
+	case TryOn:		/* on code variableList script */
+	    if (i > objc-4) {
+		Tcl_SetObjResult(interp, Tcl_NewStringObj(
+			"wrong # args to on clause: must be \"... on code"
+			" variableList script\"", -1));
+		Tcl_DecrRefCount(handlersObj);
+		Tcl_SetErrorCode(interp, "TCL", "OPERATION", "TRY", "ON",
+			"ARGUMENT", NULL);
+		return TCL_ERROR;
+	    }
+	    if (TclGetCompletionCodeFromObj(interp, objv[i+1],
+		    &code) != TCL_OK) {
+		Tcl_DecrRefCount(handlersObj);
+		return TCL_ERROR;
+	    }
+	    info[2] = NULL;
+	    goto commonHandler;
+
+	case TryTrap:		/* trap pattern variableList script */
+	    if (i > objc-4) {
+		Tcl_SetObjResult(interp, Tcl_NewStringObj(
+			"wrong # args to trap clause: "
+			"must be \"... trap pattern variableList script\"",
+			-1));
+		Tcl_DecrRefCount(handlersObj);
+		Tcl_SetErrorCode(interp, "TCL", "OPERATION", "TRY", "TRAP",
+			"ARGUMENT", NULL);
+		return TCL_ERROR;
+	    }
+	    code = 1;
+	    if (Tcl_ListObjLength(NULL, objv[i+1], &dummy) != TCL_OK) {
+		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+			"bad prefix '%s': must be a list",
+			Tcl_GetString(objv[i+1])));
+		Tcl_DecrRefCount(handlersObj);
+		Tcl_SetErrorCode(interp, "TCL", "OPERATION", "TRY", "TRAP",
+			"EXNFORMAT", NULL);
+		return TCL_ERROR;
+	    }
+	    info[2] = objv[i+1];
+
+	commonHandler:
+	    if (Tcl_ListObjLength(interp, objv[i+2], &dummy) != TCL_OK) {
+		Tcl_DecrRefCount(handlersObj);
+		return TCL_ERROR;
+	    }
+
+	    info[0] = objv[i];			/* type */
+	    TclNewIntObj(info[1], code);	/* returnCode */
+	    if (info[2] == NULL) {		/* errorCodePrefix */
+		TclNewObj(info[2]);
+	    }
+	    info[3] = objv[i+2];		/* bindVariables */
+	    info[4] = objv[i+3];		/* script */
+
+	    bodyShared = !strcmp(TclGetString(objv[i+3]), "-");
+	    Tcl_ListObjAppendElement(NULL, handlersObj,
+		    Tcl_NewListObj(5, info));
+	    haveHandlers = 1;
+	    i += 3;
+	    break;
+	}
+    }
+    if (bodyShared) {
+	Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		"last non-finally clause must not have a body of \"-\"", -1));
+	Tcl_DecrRefCount(handlersObj);
+	Tcl_SetErrorCode(interp, "TCL", "OPERATION", "TRY", "BADFALLTHROUGH",
+		NULL);
+	return TCL_ERROR;
+    }
+    if (!haveHandlers) {
+	Tcl_DecrRefCount(handlersObj);
+	handlersObj = NULL;
+    }
+
+    /*
+     * Execute the body.
+     */
+
+    Tcl_NRAddCallback(interp, TryPostBody, handlersObj, finallyObj,
+	    (ClientData)objv, INT2PTR(objc));
+    return TclNREvalObjEx(interp, bodyObj, 0,
+	    ((Interp *) interp)->cmdFramePtr, 1);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * During --
+ *
+ *	This helper function patches together the updates to the interpreter's
+ *	return options that are needed when things fail during the processing
+ *	of a handler or finally script for the [try] command.
+ *
+ * Returns:
+ *	The new option dictionary.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static inline Tcl_Obj *
+During(
+    Tcl_Interp *interp,
+    int resultCode,		/* The result code from the just-evaluated
+				 * script. */
+    Tcl_Obj *oldOptions,	/* The old option dictionary. */
+    Tcl_Obj *errorInfo)		/* An object to append to the errorinfo and
+				 * release, or NULL if nothing is to be added.
+				 * Designed to be used with Tcl_ObjPrintf. */
+{
+    Tcl_Obj *during, *options;
+
+    if (errorInfo != NULL) {
+	Tcl_AppendObjToErrorInfo(interp, errorInfo);
+    }
+    options = Tcl_GetReturnOptions(interp, resultCode);
+    TclNewLiteralStringObj(during, "-during");
+    Tcl_IncrRefCount(during);
+    Tcl_DictObjPut(interp, options, during, oldOptions);
+    Tcl_DecrRefCount(during);
+    Tcl_IncrRefCount(options);
+    Tcl_DecrRefCount(oldOptions);
+    return options;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TryPostBody --
+ *
+ *	Callback to handle the outcome of the execution of the body of a 'try'
+ *	command.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+TryPostBody(
+    ClientData data[],
+    Tcl_Interp *interp,
+    int result)
+{
+    Tcl_Obj *resultObj, *options, *handlersObj, *finallyObj, *cmdObj, **objv;
+    int i, dummy, code, objc;
+    int numHandlers = 0;
+
+    handlersObj = data[0];
+    finallyObj = data[1];
+    objv = data[2];
+    objc = PTR2INT(data[3]);
+
+    cmdObj = objv[0];
+
+    /*
+     * Check for limits/rewinding, which override normal trapping behaviour.
+     */
+
+    if (((Interp*) interp)->execEnvPtr->rewind || Tcl_LimitExceeded(interp)) {
+	Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf(
+		"\n    (\"%s\" body line %d)", TclGetString(cmdObj),
+		Tcl_GetErrorLine(interp)));
+	if (handlersObj != NULL) {
+	    Tcl_DecrRefCount(handlersObj);
+	}
+	return TCL_ERROR;
+    }
+
+    /*
+     * Basic processing of the outcome of the script, including adding of
+     * errorinfo trace.
+     */
+
+    if (result == TCL_ERROR) {
+	Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf(
+		"\n    (\"%s\" body line %d)", TclGetString(cmdObj),
+		Tcl_GetErrorLine(interp)));
+    }
+    resultObj = Tcl_GetObjResult(interp);
+    Tcl_IncrRefCount(resultObj);
+    options = Tcl_GetReturnOptions(interp, result);
+    Tcl_IncrRefCount(options);
+    Tcl_ResetResult(interp);
+
+    /*
+     * Handle the results.
+     */
+
+    if (handlersObj != NULL) {
+	int found = 0;
+	Tcl_Obj **handlers, **info;
+
+	Tcl_ListObjGetElements(NULL, handlersObj, &numHandlers, &handlers);
+	for (i=0 ; i<numHandlers ; i++) {
+	    Tcl_Obj *handlerBodyObj;
+
+	    Tcl_ListObjGetElements(NULL, handlers[i], &dummy, &info);
+	    if (!found) {
+		Tcl_GetIntFromObj(NULL, info[1], &code);
+		if (code != result) {
+		    continue;
+		}
+
+		/*
+		 * When processing an error, we must also perform list-prefix
+		 * matching of the errorcode list. However, if this was an
+		 * 'on' handler, the list that we are matching against will be
+		 * empty.
+		 */
+
+		if (code == TCL_ERROR) {
+		    Tcl_Obj *errorCodeName, *errcode, **bits1, **bits2;
+		    int len1, len2, j;
+
+		    TclNewLiteralStringObj(errorCodeName, "-errorcode");
+		    Tcl_DictObjGet(NULL, options, errorCodeName, &errcode);
+		    Tcl_DecrRefCount(errorCodeName);
+		    Tcl_ListObjGetElements(NULL, info[2], &len1, &bits1);
+		    if (Tcl_ListObjGetElements(NULL, errcode, &len2,
+			    &bits2) != TCL_OK) {
+			continue;
+		    }
+		    if (len2 < len1) {
+			continue;
+		    }
+		    for (j=0 ; j<len1 ; j++) {
+			if (strcmp(TclGetString(bits1[j]),
+				TclGetString(bits2[j])) != 0) {
+			    /*
+			     * Really want 'continue outerloop;', but C does
+			     * not give us that.
+			     */
+
+			    goto didNotMatch;
+			}
+		    }
+		}
+
+		found = 1;
+	    }
+
+	    /*
+	     * Now we need to scan forward over "-" bodies. Note that we've
+	     * already checked that the last body is not a "-", so this search
+	     * will terminate successfully.
+	     */
+
+	    if (!strcmp(TclGetString(info[4]), "-")) {
+		continue;
+	    }
+
+	    /*
+	     * Bind the variables. We already know this is a list of variable
+	     * names, but it might be empty.
+	     */
+
+	    Tcl_ResetResult(interp);
+	    result = TCL_ERROR;
+	    Tcl_ListObjLength(NULL, info[3], &dummy);
+	    if (dummy > 0) {
+		Tcl_Obj *varName;
+
+		Tcl_ListObjIndex(NULL, info[3], 0, &varName);
+		if (Tcl_ObjSetVar2(interp, varName, NULL, resultObj,
+			TCL_LEAVE_ERR_MSG) == NULL) {
+		    Tcl_DecrRefCount(resultObj);
+		    goto handlerFailed;
+		}
+		Tcl_DecrRefCount(resultObj);
+		if (dummy > 1) {
+		    Tcl_ListObjIndex(NULL, info[3], 1, &varName);
+		    if (Tcl_ObjSetVar2(interp, varName, NULL, options,
+			    TCL_LEAVE_ERR_MSG) == NULL) {
+			goto handlerFailed;
+		    }
+		}
+	    } else {
+		/*
+		 * Dispose of the result to prevent a memleak. [Bug 2910044]
+		 */
+
+		Tcl_DecrRefCount(resultObj);
+	    }
+
+	    /*
+	     * Evaluate the handler body and process the outcome. Note that we
+	     * need to keep the kind of handler for debugging purposes, and in
+	     * any case anything we want from info[] must be extracted right
+	     * now because the info[] array is about to become invalid. There
+	     * is very little refcount handling here however, since we know
+	     * that the objects that we still want to refer to now were input
+	     * arguments to [try] and so are still on the Tcl value stack.
+	     */
+
+	    handlerBodyObj = info[4];
+	    Tcl_NRAddCallback(interp, TryPostHandler, objv, options, info[0],
+		    INT2PTR((finallyObj == NULL) ? 0 : objc - 1));
+	    Tcl_DecrRefCount(handlersObj);
+	    return TclNREvalObjEx(interp, handlerBodyObj, 0,
+		    ((Interp *) interp)->cmdFramePtr, 4*i + 5);
+
+	handlerFailed:
+	    resultObj = Tcl_GetObjResult(interp);
+	    Tcl_IncrRefCount(resultObj);
+	    options = During(interp, result, options, NULL);
+	    break;
+
+	didNotMatch:
+	    continue;
+	}
+
+	/*
+	 * No handler matched; get rid of the list of handlers.
+	 */
+
+	Tcl_DecrRefCount(handlersObj);
+    }
+
+    /*
+     * Process the finally clause.
+     */
+
+    if (finallyObj != NULL) {
+	Tcl_NRAddCallback(interp, TryPostFinal, resultObj, options, cmdObj,
+		NULL);
+	return TclNREvalObjEx(interp, finallyObj, 0,
+		((Interp *) interp)->cmdFramePtr, objc - 1);
+    }
+
+    /*
+     * Install the correct result/options into the interpreter and clean up
+     * any temporary storage.
+     */
+
+    result = Tcl_SetReturnOptions(interp, options);
+    Tcl_DecrRefCount(options);
+    Tcl_SetObjResult(interp, resultObj);
+    Tcl_DecrRefCount(resultObj);
+    return result;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TryPostHandler --
+ *
+ *	Callback to handle the outcome of the execution of a handler of a
+ *	'try' command.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+TryPostHandler(
+    ClientData data[],
+    Tcl_Interp *interp,
+    int result)
+{
+    Tcl_Obj *resultObj, *cmdObj, *options, *handlerKindObj, **objv;
+    Tcl_Obj *finallyObj;
+    int finally;
+
+    objv = data[0];
+    options = data[1];
+    handlerKindObj = data[2];
+    finally = PTR2INT(data[3]);
+
+    cmdObj = objv[0];
+    finallyObj = finally ? objv[finally] : 0;
+
+    /*
+     * Check for limits/rewinding, which override normal trapping behaviour.
+     */
+
+    if (((Interp*) interp)->execEnvPtr->rewind || Tcl_LimitExceeded(interp)) {
+	options = During(interp, result, options, Tcl_ObjPrintf(
+		"\n    (\"%s ... %s\" handler line %d)",
+		TclGetString(cmdObj), TclGetString(handlerKindObj),
+		Tcl_GetErrorLine(interp)));
+	Tcl_DecrRefCount(options);
+	return TCL_ERROR;
+    }
+
+    /*
+     * The handler result completely substitutes for the result of the body.
+     */
+
+    resultObj = Tcl_GetObjResult(interp);
+    Tcl_IncrRefCount(resultObj);
+    if (result == TCL_ERROR) {
+	options = During(interp, result, options, Tcl_ObjPrintf(
+		"\n    (\"%s ... %s\" handler line %d)",
+		TclGetString(cmdObj), TclGetString(handlerKindObj),
+		Tcl_GetErrorLine(interp)));
+    } else {
+	Tcl_DecrRefCount(options);
+	options = Tcl_GetReturnOptions(interp, result);
+	Tcl_IncrRefCount(options);
+    }
+
+    /*
+     * Process the finally clause if it is present.
+     */
+
+    if (finallyObj != NULL) {
+	Interp *iPtr = (Interp *) interp;
+
+	Tcl_NRAddCallback(interp, TryPostFinal, resultObj, options, cmdObj,
+		NULL);
+
+	/* The 'finally' script is always the last argument word. */
+	return TclNREvalObjEx(interp, finallyObj, 0, iPtr->cmdFramePtr,
+		finally);
+    }
+
+    /*
+     * Install the correct result/options into the interpreter and clean up
+     * any temporary storage.
+     */
+
+    result = Tcl_SetReturnOptions(interp, options);
+    Tcl_DecrRefCount(options);
+    Tcl_SetObjResult(interp, resultObj);
+    Tcl_DecrRefCount(resultObj);
+    return result;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TryPostFinal --
+ *
+ *	Callback to handle the outcome of the execution of the finally script
+ *	of a 'try' command.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+TryPostFinal(
+    ClientData data[],
+    Tcl_Interp *interp,
+    int result)
+{
+    Tcl_Obj *resultObj, *options, *cmdObj;
+
+    resultObj = data[0];
+    options = data[1];
+    cmdObj = data[2];
+
+    /*
+     * If the result wasn't OK, we need to adjust the result options.
+     */
+
+    if (result != TCL_OK) {
+	Tcl_DecrRefCount(resultObj);
+	resultObj = NULL;
+	if (result == TCL_ERROR) {
+	    options = During(interp, result, options, Tcl_ObjPrintf(
+		    "\n    (\"%s ... finally\" body line %d)",
+		    TclGetString(cmdObj), Tcl_GetErrorLine(interp)));
+	} else {
+	    Tcl_Obj *origOptions = options;
+
+	    options = Tcl_GetReturnOptions(interp, result);
+	    Tcl_IncrRefCount(options);
+	    Tcl_DecrRefCount(origOptions);
+	}
+    }
+
+    /*
+     * Install the correct result/options into the interpreter and clean up
+     * any temporary storage.
+     */
+
+    result = Tcl_SetReturnOptions(interp, options);
+    Tcl_DecrRefCount(options);
+    if (resultObj != NULL) {
+	Tcl_SetObjResult(interp, resultObj);
+	Tcl_DecrRefCount(resultObj);
+    }
+    return result;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_WhileObjCmd --
+ *
+ *	This procedure is invoked to process the "while" Tcl command. See the
+ *	user documentation for details on what it does.
+ *
+ *	With the bytecode compiler, this procedure is only called when a
+ *	command name is computed at runtime, and is "while" or the name to
+ *	which "while" was renamed: e.g., "set z while; $z {$i<100} {}"
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_WhileObjCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    return Tcl_NRCallObjProc(interp, TclNRWhileObjCmd, dummy, objc, objv);
+}
+
+int
+TclNRWhileObjCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    ForIterData *iterPtr;
+
+    if (objc != 3) {
+	Tcl_WrongNumArgs(interp, 1, objv, "test command");
+	return TCL_ERROR;
+    }
+
+    /*
+     * We reuse [for]'s callback, passing a NULL for the 'next' script.
+     */
+
+    TclSmallAllocEx(interp, sizeof(ForIterData), iterPtr);
+    iterPtr->cond = objv[1];
+    iterPtr->body = objv[2];
+    iterPtr->next = NULL;
+    iterPtr->msg  = "\n    (\"while\" body line %d)";
+    iterPtr->word = 2;
+
+    TclNRAddCallback(interp, TclNRForIterCallback, iterPtr, NULL,
+	    NULL, NULL);
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclListLines --
+ *
+ *	???
+ *
+ * Results:
+ *	Filled in array of line numbers?
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclListLines(
+    Tcl_Obj *listObj,		/* Pointer to obj holding a string with list
+				 * structure. Assumed to be valid. Assumed to
+				 * contain n elements. */
+    int line,			/* Line the list as a whole starts on. */
+    int n,			/* #elements in lines */
+    int *lines,			/* Array of line numbers, to fill. */
+    Tcl_Obj *const *elems)      /* The list elems as Tcl_Obj*, in need of
+				 * derived continuation data */
+{
+    const char *listStr = Tcl_GetString(listObj);
+    const char *listHead = listStr;
+    int i, length = strlen(listStr);
+    const char *element = NULL, *next = NULL;
+    ContLineLoc *clLocPtr = TclContinuationsGet(listObj);
+    int *clNext = (clLocPtr ? &clLocPtr->loc[0] : NULL);
+
+    for (i = 0; i < n; i++) {
+	TclFindElement(NULL, listStr, length, &element, &next, NULL, NULL);
+
+	TclAdvanceLines(&line, listStr, element);
+				/* Leading whitespace */
+	TclAdvanceContinuations(&line, &clNext, element - listHead);
+	if (elems && clNext) {
+	    TclContinuationsEnterDerived(elems[i], element-listHead, clNext);
+	}
+	lines[i] = line;
+	length -= (next - listStr);
+	TclAdvanceLines(&line, element, next);
+				/* Element */
+	listStr = next;
+
+	if (*element == 0) {
+	    /* ASSERT i == n */
+	    break;
+	}
+    }
+}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tclCompCmds.c b/generic/tclCompCmds.c
new file mode 100644
index 0000000..3ab03cc
--- /dev/null
+++ b/generic/tclCompCmds.c
@@ -0,0 +1,3511 @@
+/*
+ * tclCompCmds.c --
+ *
+ *	This file contains compilation procedures that compile various Tcl
+ *	commands into a sequence of instructions ("bytecodes").
+ *
+ * Copyright (c) 1997-1998 Sun Microsystems, Inc.
+ * Copyright (c) 2001 by Kevin B. Kenny.  All rights reserved.
+ * Copyright (c) 2002 ActiveState Corporation.
+ * Copyright (c) 2004-2013 by Donal K. Fellows.
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#include "tclInt.h"
+#include "tclCompile.h"
+#include <assert.h>
+
+/*
+ * Prototypes for procedures defined later in this file:
+ */
+
+static ClientData	DupDictUpdateInfo(ClientData clientData);
+static void		FreeDictUpdateInfo(ClientData clientData);
+static void		PrintDictUpdateInfo(ClientData clientData,
+			    Tcl_Obj *appendObj, ByteCode *codePtr,
+			    unsigned int pcOffset);
+static void		DisassembleDictUpdateInfo(ClientData clientData,
+			    Tcl_Obj *dictObj, ByteCode *codePtr,
+			    unsigned int pcOffset);
+static ClientData	DupForeachInfo(ClientData clientData);
+static void		FreeForeachInfo(ClientData clientData);
+static void		PrintForeachInfo(ClientData clientData,
+			    Tcl_Obj *appendObj, ByteCode *codePtr,
+			    unsigned int pcOffset);
+static void		DisassembleForeachInfo(ClientData clientData,
+			    Tcl_Obj *dictObj, ByteCode *codePtr,
+			    unsigned int pcOffset);
+static void		PrintNewForeachInfo(ClientData clientData,
+			    Tcl_Obj *appendObj, ByteCode *codePtr,
+			    unsigned int pcOffset);
+static void		DisassembleNewForeachInfo(ClientData clientData,
+			    Tcl_Obj *dictObj, ByteCode *codePtr,
+			    unsigned int pcOffset);
+static int		CompileEachloopCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    CompileEnv *envPtr, int collect);
+static int		CompileDictEachCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr, int collect);
+
+/*
+ * The structures below define the AuxData types defined in this file.
+ */
+
+static const AuxDataType foreachInfoType = {
+    "ForeachInfo",		/* name */
+    DupForeachInfo,		/* dupProc */
+    FreeForeachInfo,		/* freeProc */
+    PrintForeachInfo,		/* printProc */
+    DisassembleForeachInfo	/* disassembleProc */
+};
+
+static const AuxDataType newForeachInfoType = {
+    "NewForeachInfo",		/* name */
+    DupForeachInfo,		/* dupProc */
+    FreeForeachInfo,		/* freeProc */
+    PrintNewForeachInfo,	/* printProc */
+    DisassembleNewForeachInfo	/* disassembleProc */
+};
+
+static const AuxDataType dictUpdateInfoType = {
+    "DictUpdateInfo",		/* name */
+    DupDictUpdateInfo,		/* dupProc */
+    FreeDictUpdateInfo,		/* freeProc */
+    PrintDictUpdateInfo,	/* printProc */
+    DisassembleDictUpdateInfo	/* disassembleProc */
+};
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclGetAuxDataType --
+ *
+ *	This procedure looks up an Auxdata type by name.
+ *
+ * Results:
+ *	If an AuxData type with name matching "typeName" is found, a pointer
+ *	to its AuxDataType structure is returned; otherwise, NULL is returned.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+const AuxDataType *
+TclGetAuxDataType(
+    const char *typeName)	/* Name of AuxData type to look up. */
+{
+    if (!strcmp(typeName, foreachInfoType.name)) {
+	return &foreachInfoType;
+    } else if (!strcmp(typeName, newForeachInfoType.name)) {
+	return &newForeachInfoType;
+    } else if (!strcmp(typeName, dictUpdateInfoType.name)) {
+	return &dictUpdateInfoType;
+    } else if (!strcmp(typeName, tclJumptableInfoType.name)) {
+	return &tclJumptableInfoType;
+    }
+    return NULL;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclCompileAppendCmd --
+ *
+ *	Procedure called to compile the "append" command.
+ *
+ * Results:
+ *	Returns TCL_OK for a successful compile. Returns TCL_ERROR to defer
+ *	evaluation to runtime.
+ *
+ * Side effects:
+ *	Instructions are added to envPtr to execute the "append" command at
+ *	runtime.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclCompileAppendCmd(
+    Tcl_Interp *interp,		/* Used for error reporting. */
+    Tcl_Parse *parsePtr,	/* Points to a parse structure for the command
+				 * created by Tcl_ParseCommand. */
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)		/* Holds resulting instructions. */
+{
+    Tcl_Token *varTokenPtr, *valueTokenPtr;
+    int isScalar, localIndex, numWords, i;
+    DefineLineInformation;	/* TIP #280 */
+
+    /* TODO: Consider support for compiling expanded args. */
+    numWords = parsePtr->numWords;
+    if (numWords == 1) {
+	return TCL_ERROR;
+    } else if (numWords == 2) {
+	/*
+	 * append varName == set varName
+	 */
+
+	return TclCompileSetCmd(interp, parsePtr, cmdPtr, envPtr);
+    } else if (numWords > 3) {
+	/*
+	 * APPEND instructions currently only handle one value, but we can
+	 * handle some multi-value cases by stringing them together.
+	 */
+
+	goto appendMultiple;
+    }
+
+    /*
+     * Decide if we can use a frame slot for the var/array name or if we need
+     * to emit code to compute and push the name at runtime. We use a frame
+     * slot (entry in the array of local vars) if we are compiling a procedure
+     * body and if the name is simple text that does not include namespace
+     * qualifiers.
+     */
+
+    varTokenPtr = TokenAfter(parsePtr->tokenPtr);
+
+    PushVarNameWord(interp, varTokenPtr, envPtr, 0,
+	    &localIndex, &isScalar, 1);
+
+    /*
+     * We are doing an assignment, otherwise TclCompileSetCmd was called, so
+     * push the new value. This will need to be extended to push a value for
+     * each argument.
+     */
+
+	valueTokenPtr = TokenAfter(varTokenPtr);
+	CompileWord(envPtr, valueTokenPtr, interp, 2);
+
+    /*
+     * Emit instructions to set/get the variable.
+     */
+
+	if (isScalar) {
+	    if (localIndex < 0) {
+		TclEmitOpcode(INST_APPEND_STK, envPtr);
+	    } else {
+		Emit14Inst(INST_APPEND_SCALAR, localIndex, envPtr);
+	    }
+	} else {
+	    if (localIndex < 0) {
+		TclEmitOpcode(INST_APPEND_ARRAY_STK, envPtr);
+	    } else {
+		Emit14Inst(INST_APPEND_ARRAY, localIndex, envPtr);
+	    }
+	}
+
+    return TCL_OK;
+
+  appendMultiple:
+    /*
+     * Can only handle the case where we are appending to a local scalar when
+     * there are multiple values to append.  Fortunately, this is common.
+     */
+
+    varTokenPtr = TokenAfter(parsePtr->tokenPtr);
+
+    localIndex = LocalScalarFromToken(varTokenPtr, envPtr);
+    if (localIndex < 0) {
+	return TCL_ERROR;
+    }
+
+    /*
+     * Definitely appending to a local scalar; generate the words and append
+     * them.
+     */
+
+    valueTokenPtr = TokenAfter(varTokenPtr);
+    for (i = 2 ; i < numWords ; i++) {
+	CompileWord(envPtr, valueTokenPtr, interp, i);
+	valueTokenPtr = TokenAfter(valueTokenPtr);
+    }
+    TclEmitInstInt4(	  INST_REVERSE, numWords-2,		envPtr);
+    for (i = 2 ; i < numWords ;) {
+	Emit14Inst(	  INST_APPEND_SCALAR, localIndex,	envPtr);
+	if (++i < numWords) {
+	    TclEmitOpcode(INST_POP,				envPtr);
+	}
+    }
+
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclCompileArray*Cmd --
+ *
+ *	Functions called to compile "array" sucommands.
+ *
+ * Results:
+ *	All return TCL_OK for a successful compile, and TCL_ERROR to defer
+ *	evaluation to runtime.
+ *
+ * Side effects:
+ *	Instructions are added to envPtr to execute the "array" subcommand at
+ *	runtime.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclCompileArrayExistsCmd(
+    Tcl_Interp *interp,		/* Used for looking up stuff. */
+    Tcl_Parse *parsePtr,	/* Points to a parse structure for the command
+				 * created by Tcl_ParseCommand. */
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)		/* Holds resulting instructions. */
+{
+    DefineLineInformation;	/* TIP #280 */
+    Tcl_Token *tokenPtr;
+    int isScalar, localIndex;
+
+    if (parsePtr->numWords != 2) {
+	return TCL_ERROR;
+    }
+
+    tokenPtr = TokenAfter(parsePtr->tokenPtr);
+    PushVarNameWord(interp, tokenPtr, envPtr, TCL_NO_ELEMENT,
+	    &localIndex, &isScalar, 1);
+    if (!isScalar) {
+	return TCL_ERROR;
+    }
+
+    if (localIndex >= 0) {
+	TclEmitInstInt4(INST_ARRAY_EXISTS_IMM, localIndex,	envPtr);
+    } else {
+	TclEmitOpcode(	INST_ARRAY_EXISTS_STK,			envPtr);
+    }
+    return TCL_OK;
+}
+
+int
+TclCompileArraySetCmd(
+    Tcl_Interp *interp,		/* Used for looking up stuff. */
+    Tcl_Parse *parsePtr,	/* Points to a parse structure for the command
+				 * created by Tcl_ParseCommand. */
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)		/* Holds resulting instructions. */
+{
+    DefineLineInformation;	/* TIP #280 */
+    Tcl_Token *varTokenPtr, *dataTokenPtr;
+    int isScalar, localIndex, code = TCL_OK;
+    int isDataLiteral, isDataValid, isDataEven, len;
+    int keyVar, valVar, infoIndex;
+    int fwd, offsetBack, offsetFwd;
+    Tcl_Obj *literalObj;
+    ForeachInfo *infoPtr;
+
+    if (parsePtr->numWords != 3) {
+	return TCL_ERROR;
+    }
+
+    varTokenPtr = TokenAfter(parsePtr->tokenPtr);
+    dataTokenPtr = TokenAfter(varTokenPtr);
+    literalObj = Tcl_NewObj();
+    isDataLiteral = TclWordKnownAtCompileTime(dataTokenPtr, literalObj);
+    isDataValid = (isDataLiteral
+	    && Tcl_ListObjLength(NULL, literalObj, &len) == TCL_OK);
+    isDataEven = (isDataValid && (len & 1) == 0);
+
+    /*
+     * Special case: literal odd-length argument is always an error.
+     */
+
+    if (isDataValid && !isDataEven) {
+	PushStringLiteral(envPtr, "list must have an even number of elements");
+	PushStringLiteral(envPtr, "-errorcode {TCL ARGUMENT FORMAT}");
+	TclEmitInstInt4(INST_RETURN_IMM, TCL_ERROR,		envPtr);
+	TclEmitInt4(		0,				envPtr);
+	goto done;
+    }
+
+    /*
+     * Except for the special "ensure array" case below, when we're not in
+     * a proc, we cannot do a better compile than generic.
+     */
+
+    if ((varTokenPtr->type != TCL_TOKEN_SIMPLE_WORD) ||
+	    (envPtr->procPtr == NULL && !(isDataEven && len == 0))) {
+	code = TclCompileBasic2ArgCmd(interp, parsePtr, cmdPtr, envPtr);
+	goto done;
+    }
+
+    PushVarNameWord(interp, varTokenPtr, envPtr, TCL_NO_ELEMENT,
+	    &localIndex, &isScalar, 1);
+    if (!isScalar) {
+	code = TCL_ERROR;
+	goto done;
+    }
+
+    /*
+     * Special case: literal empty value argument is just an "ensure array"
+     * operation.
+     */
+
+    if (isDataEven && len == 0) {
+	if (localIndex >= 0) {
+	    TclEmitInstInt4(INST_ARRAY_EXISTS_IMM, localIndex,	envPtr);
+	    TclEmitInstInt1(INST_JUMP_TRUE1, 7,			envPtr);
+	    TclEmitInstInt4(INST_ARRAY_MAKE_IMM, localIndex,	envPtr);
+	} else {
+	    TclEmitOpcode(  INST_DUP,				envPtr);
+	    TclEmitOpcode(  INST_ARRAY_EXISTS_STK,		envPtr);
+	    TclEmitInstInt1(INST_JUMP_TRUE1, 5,			envPtr);
+	    TclEmitOpcode(  INST_ARRAY_MAKE_STK,		envPtr);
+	    TclEmitInstInt1(INST_JUMP1, 3,			envPtr);
+	    /* Each branch decrements stack depth, but we only take one. */
+	    TclAdjustStackDepth(1, envPtr);
+	    TclEmitOpcode(  INST_POP,				envPtr);
+	}
+	PushStringLiteral(envPtr, "");
+	goto done;
+    }
+
+    if (localIndex < 0) {
+	/*
+	 * a non-local variable: upvar from a local one! This consumes the
+	 * variable name that was left at stacktop.
+	 */
+
+	localIndex = TclFindCompiledLocal(varTokenPtr->start,
+		varTokenPtr->size, 1, envPtr);
+	PushStringLiteral(envPtr, "0");
+	TclEmitInstInt4(INST_REVERSE, 2,        		envPtr);
+	TclEmitInstInt4(INST_UPVAR, localIndex, 		envPtr);
+	TclEmitOpcode(INST_POP,          			envPtr);
+    }
+
+    /*
+     * Prepare for the internal foreach.
+     */
+
+    keyVar = AnonymousLocal(envPtr);
+    valVar = AnonymousLocal(envPtr);
+
+    infoPtr = ckalloc(sizeof(ForeachInfo));
+    infoPtr->numLists = 1;
+    infoPtr->varLists[0] = ckalloc(sizeof(ForeachVarList) + sizeof(int));
+    infoPtr->varLists[0]->numVars = 2;
+    infoPtr->varLists[0]->varIndexes[0] = keyVar;
+    infoPtr->varLists[0]->varIndexes[1] = valVar;
+    infoIndex = TclCreateAuxData(infoPtr, &newForeachInfoType, envPtr);
+
+    /*
+     * Start issuing instructions to write to the array.
+     */
+
+    CompileWord(envPtr, dataTokenPtr, interp, 2);
+    if (!isDataLiteral || !isDataValid) {
+	/*
+	 * Only need this safety check if we're handling a non-literal or list
+	 * containing an invalid literal; with valid list literals, we've
+	 * already checked (worth it because literals are a very common
+	 * use-case with [array set]).
+	 */
+
+	TclEmitOpcode(	INST_DUP,				envPtr);
+	TclEmitOpcode(	INST_LIST_LENGTH,			envPtr);
+	PushStringLiteral(envPtr, "1");
+	TclEmitOpcode(	INST_BITAND,				envPtr);
+	offsetFwd = CurrentOffset(envPtr);
+	TclEmitInstInt1(INST_JUMP_FALSE1, 0,			envPtr);
+	PushStringLiteral(envPtr, "list must have an even number of elements");
+	PushStringLiteral(envPtr, "-errorcode {TCL ARGUMENT FORMAT}");
+	TclEmitInstInt4(INST_RETURN_IMM, TCL_ERROR,		envPtr);
+	TclEmitInt4(		0,				envPtr);
+	TclAdjustStackDepth(-1, envPtr);
+	fwd = CurrentOffset(envPtr) - offsetFwd;
+	TclStoreInt1AtPtr(fwd, envPtr->codeStart+offsetFwd+1);
+    }
+
+    TclEmitInstInt4(INST_ARRAY_EXISTS_IMM, localIndex,	envPtr);
+    TclEmitInstInt1(INST_JUMP_TRUE1, 7,			envPtr);
+    TclEmitInstInt4(INST_ARRAY_MAKE_IMM, localIndex,	envPtr);
+    TclEmitInstInt4(INST_FOREACH_START, infoIndex,	envPtr);
+    offsetBack = CurrentOffset(envPtr);
+    Emit14Inst(	INST_LOAD_SCALAR, keyVar,		envPtr);
+    Emit14Inst(	INST_LOAD_SCALAR, valVar,		envPtr);
+    Emit14Inst(	INST_STORE_ARRAY, localIndex,		envPtr);
+    TclEmitOpcode(	INST_POP,			envPtr);
+    infoPtr->loopCtTemp = offsetBack - CurrentOffset(envPtr); /*misuse */
+    TclEmitOpcode( INST_FOREACH_STEP,			envPtr);
+    TclEmitOpcode( INST_FOREACH_END,			envPtr);
+    TclAdjustStackDepth(-3, envPtr);
+    PushStringLiteral(envPtr,	"");
+
+    done:
+    Tcl_DecrRefCount(literalObj);
+    return code;
+}
+
+int
+TclCompileArrayUnsetCmd(
+    Tcl_Interp *interp,		/* Used for looking up stuff. */
+    Tcl_Parse *parsePtr,	/* Points to a parse structure for the command
+				 * created by Tcl_ParseCommand. */
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)		/* Holds resulting instructions. */
+{
+    DefineLineInformation;	/* TIP #280 */
+    Tcl_Token *tokenPtr = TokenAfter(parsePtr->tokenPtr);
+    int isScalar, localIndex;
+
+    if (parsePtr->numWords != 2) {
+	return TclCompileBasic2ArgCmd(interp, parsePtr, cmdPtr, envPtr);
+    }
+
+    PushVarNameWord(interp, tokenPtr, envPtr, TCL_NO_ELEMENT,
+	    &localIndex, &isScalar, 1);
+    if (!isScalar) {
+	return TCL_ERROR;
+    }
+
+    if (localIndex >= 0) {
+	TclEmitInstInt4(INST_ARRAY_EXISTS_IMM, localIndex,	envPtr);
+	TclEmitInstInt1(INST_JUMP_FALSE1, 8,			envPtr);
+	TclEmitInstInt1(INST_UNSET_SCALAR, 1,			envPtr);
+	TclEmitInt4(		localIndex,			envPtr);
+    } else {
+	TclEmitOpcode(	INST_DUP,				envPtr);
+	TclEmitOpcode(	INST_ARRAY_EXISTS_STK,			envPtr);
+	TclEmitInstInt1(INST_JUMP_FALSE1, 6,			envPtr);
+	TclEmitInstInt1(INST_UNSET_STK, 1,			envPtr);
+	TclEmitInstInt1(INST_JUMP1, 3,				envPtr);
+	/* Each branch decrements stack depth, but we only take one. */
+	TclAdjustStackDepth(1, envPtr);
+	TclEmitOpcode(	INST_POP,				envPtr);
+    }
+    PushStringLiteral(envPtr,	"");
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclCompileBreakCmd --
+ *
+ *	Procedure called to compile the "break" command.
+ *
+ * Results:
+ *	Returns TCL_OK for a successful compile. Returns TCL_ERROR to defer
+ *	evaluation to runtime.
+ *
+ * Side effects:
+ *	Instructions are added to envPtr to execute the "break" command at
+ *	runtime.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclCompileBreakCmd(
+    Tcl_Interp *interp,		/* Used for error reporting. */
+    Tcl_Parse *parsePtr,	/* Points to a parse structure for the command
+				 * created by Tcl_ParseCommand. */
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)		/* Holds resulting instructions. */
+{
+    ExceptionRange *rangePtr;
+    ExceptionAux *auxPtr;
+
+    if (parsePtr->numWords != 1) {
+	return TCL_ERROR;
+    }
+
+    /*
+     * Find the innermost exception range that contains this command.
+     */
+
+    rangePtr = TclGetInnermostExceptionRange(envPtr, TCL_BREAK, &auxPtr);
+    if (rangePtr && rangePtr->type == LOOP_EXCEPTION_RANGE) {
+	/*
+	 * Found the target! No need for a nasty INST_BREAK here.
+	 */
+
+	TclCleanupStackForBreakContinue(envPtr, auxPtr);
+	TclAddLoopBreakFixup(envPtr, auxPtr);
+    } else {
+	/*
+	 * Emit a real break.
+	 */
+
+	TclEmitOpcode(INST_BREAK, envPtr);
+    }
+    TclAdjustStackDepth(1, envPtr);
+
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclCompileCatchCmd --
+ *
+ *	Procedure called to compile the "catch" command.
+ *
+ * Results:
+ *	Returns TCL_OK for a successful compile. Returns TCL_ERROR to defer
+ *	evaluation to runtime.
+ *
+ * Side effects:
+ *	Instructions are added to envPtr to execute the "catch" command at
+ *	runtime.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclCompileCatchCmd(
+    Tcl_Interp *interp,		/* Used for error reporting. */
+    Tcl_Parse *parsePtr,	/* Points to a parse structure for the command
+				 * created by Tcl_ParseCommand. */
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)		/* Holds resulting instructions. */
+{
+    JumpFixup jumpFixup;
+    Tcl_Token *cmdTokenPtr, *resultNameTokenPtr, *optsNameTokenPtr;
+    int resultIndex, optsIndex, range, dropScript = 0;
+    DefineLineInformation;	/* TIP #280 */
+    int depth = TclGetStackDepth(envPtr);
+
+    /*
+     * If syntax does not match what we expect for [catch], do not compile.
+     * Let runtime checks determine if syntax has changed.
+     */
+
+    if ((parsePtr->numWords < 2) || (parsePtr->numWords > 4)) {
+	return TCL_ERROR;
+    }
+
+    /*
+     * If variables were specified and the catch command is at global level
+     * (not in a procedure), don't compile it inline: the payoff is too small.
+     */
+
+    if ((parsePtr->numWords >= 3) && !EnvHasLVT(envPtr)) {
+	return TCL_ERROR;
+    }
+
+    /*
+     * Make sure the variable names, if any, have no substitutions and just
+     * refer to local scalars.
+     */
+
+    resultIndex = optsIndex = -1;
+    cmdTokenPtr = TokenAfter(parsePtr->tokenPtr);
+    if (parsePtr->numWords >= 3) {
+	resultNameTokenPtr = TokenAfter(cmdTokenPtr);
+	/* DGP */
+	resultIndex = LocalScalarFromToken(resultNameTokenPtr, envPtr);
+	if (resultIndex < 0) {
+	    return TCL_ERROR;
+	}
+
+	/* DKF */
+	if (parsePtr->numWords == 4) {
+	    optsNameTokenPtr = TokenAfter(resultNameTokenPtr);
+	    optsIndex = LocalScalarFromToken(optsNameTokenPtr, envPtr);
+	    if (optsIndex < 0) {
+		return TCL_ERROR;
+	    }
+	}
+    }
+
+    /*
+     * We will compile the catch command. Declare the exception range that it
+     * uses.
+     *
+     * If the body is a simple word, compile a BEGIN_CATCH instruction,
+     * followed by the instructions to eval the body.
+     * Otherwise, compile instructions to substitute the body text before
+     * starting the catch, then BEGIN_CATCH, and then EVAL_STK to evaluate the
+     * substituted body.
+     * Care has to be taken to make sure that substitution happens outside the
+     * catch range so that errors in the substitution are not caught.
+     * [Bug 219184]
+     * The reason for duplicating the script is that EVAL_STK would otherwise
+     * begin by undeflowing the stack below the mark set by BEGIN_CATCH4.
+     */
+
+    range = TclCreateExceptRange(CATCH_EXCEPTION_RANGE, envPtr);
+    if (cmdTokenPtr->type == TCL_TOKEN_SIMPLE_WORD) {
+	TclEmitInstInt4(	INST_BEGIN_CATCH4, range,	envPtr);
+	ExceptionRangeStarts(envPtr, range);
+	BODY(cmdTokenPtr, 1);
+    } else {
+	SetLineInformation(1);
+	CompileTokens(envPtr, cmdTokenPtr, interp);
+	TclEmitInstInt4(	INST_BEGIN_CATCH4, range,	envPtr);
+	ExceptionRangeStarts(envPtr, range);
+	TclEmitOpcode(		INST_DUP,			envPtr);
+	TclEmitInvoke(envPtr,	INST_EVAL_STK);
+	/* drop the script */
+	dropScript = 1;
+	TclEmitInstInt4(	INST_REVERSE, 2,		envPtr);
+	TclEmitOpcode(		INST_POP,			envPtr);
+    }
+    ExceptionRangeEnds(envPtr, range);
+
+
+    /*
+     * Emit the "no errors" epilogue: push "0" (TCL_OK) as the catch result,
+     * and jump around the "error case" code.
+     */
+
+    TclCheckStackDepth(depth+1, envPtr);
+    PushStringLiteral(envPtr, "0");
+    TclEmitForwardJump(envPtr, TCL_UNCONDITIONAL_JUMP, &jumpFixup);
+
+    /*
+     * Emit the "error case" epilogue. Push the interpreter result and the
+     * return code.
+     */
+
+    ExceptionRangeTarget(envPtr, range, catchOffset);
+    TclSetStackDepth(depth + dropScript, envPtr);
+
+    if (dropScript) {
+	TclEmitOpcode(		INST_POP,			envPtr);
+    }
+
+
+    /* Stack at this point is empty */
+    TclEmitOpcode(		INST_PUSH_RESULT,		envPtr);
+    TclEmitOpcode(		INST_PUSH_RETURN_CODE,		envPtr);
+
+    /* Stack at this point on both branches: result returnCode */
+
+    if (TclFixupForwardJumpToHere(envPtr, &jumpFixup, 127)) {
+	Tcl_Panic("TclCompileCatchCmd: bad jump distance %d",
+		(int)(CurrentOffset(envPtr) - jumpFixup.codeOffset));
+    }
+
+    /*
+     * Push the return options if the caller wants them. This needs to happen
+     * before INST_END_CATCH
+     */
+
+    if (optsIndex != -1) {
+	TclEmitOpcode(		INST_PUSH_RETURN_OPTIONS,	envPtr);
+    }
+
+    /*
+     * End the catch
+     */
+
+    TclEmitOpcode(		INST_END_CATCH,			envPtr);
+
+    /*
+     * Save the result and return options if the caller wants them. This needs
+     * to happen after INST_END_CATCH (compile-3.6/7).
+     */
+
+    if (optsIndex != -1) {
+	Emit14Inst(		INST_STORE_SCALAR, optsIndex,	envPtr);
+	TclEmitOpcode(		INST_POP,			envPtr);
+    }
+
+    /*
+     * At this point, the top of the stack is inconveniently ordered:
+     *		result returnCode
+     * Reverse the stack to store the result.
+     */
+
+    TclEmitInstInt4(	INST_REVERSE, 2,		envPtr);
+    if (resultIndex != -1) {
+	Emit14Inst(	INST_STORE_SCALAR, resultIndex,	envPtr);
+    }
+    TclEmitOpcode(	INST_POP,			envPtr);
+
+    TclCheckStackDepth(depth+1, envPtr);
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclCompileConcatCmd --
+ *
+ *	Procedure called to compile the "concat" command.
+ *
+ * Results:
+ *	Returns TCL_OK for a successful compile. Returns TCL_ERROR to defer
+ *	evaluation to runtime.
+ *
+ * Side effects:
+ *	Instructions are added to envPtr to execute the "concat" command at
+ *	runtime.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclCompileConcatCmd(
+    Tcl_Interp *interp,		/* Used for error reporting. */
+    Tcl_Parse *parsePtr,	/* Points to a parse structure for the command
+				 * created by Tcl_ParseCommand. */
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)		/* Holds resulting instructions. */
+{
+    DefineLineInformation;	/* TIP #280 */
+    Tcl_Obj *objPtr, *listObj;
+    Tcl_Token *tokenPtr;
+    int i;
+
+    /* TODO: Consider compiling expansion case. */
+    if (parsePtr->numWords == 1) {
+	/*
+	 * [concat] without arguments just pushes an empty object.
+	 */
+
+	PushStringLiteral(envPtr, "");
+	return TCL_OK;
+    }
+
+    /*
+     * Test if all arguments are compile-time known. If they are, we can
+     * implement with a simple push.
+     */
+
+    listObj = Tcl_NewObj();
+    for (i = 1, tokenPtr = parsePtr->tokenPtr; i < parsePtr->numWords; i++) {
+	tokenPtr = TokenAfter(tokenPtr);
+	objPtr = Tcl_NewObj();
+	if (!TclWordKnownAtCompileTime(tokenPtr, objPtr)) {
+	    Tcl_DecrRefCount(objPtr);
+	    Tcl_DecrRefCount(listObj);
+	    listObj = NULL;
+	    break;
+	}
+	(void) Tcl_ListObjAppendElement(NULL, listObj, objPtr);
+    }
+    if (listObj != NULL) {
+	Tcl_Obj **objs;
+	const char *bytes;
+	int len;
+
+	Tcl_ListObjGetElements(NULL, listObj, &len, &objs);
+	objPtr = Tcl_ConcatObj(len, objs);
+	Tcl_DecrRefCount(listObj);
+	bytes = Tcl_GetStringFromObj(objPtr, &len);
+	PushLiteral(envPtr, bytes, len);
+	Tcl_DecrRefCount(objPtr);
+	return TCL_OK;
+    }
+
+    /*
+     * General case: runtime concat.
+     */
+
+    for (i = 1, tokenPtr = parsePtr->tokenPtr; i < parsePtr->numWords; i++) {
+	tokenPtr = TokenAfter(tokenPtr);
+	CompileWord(envPtr, tokenPtr, interp, i);
+    }
+
+    TclEmitInstInt4(	INST_CONCAT_STK, i-1,		envPtr);
+
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclCompileContinueCmd --
+ *
+ *	Procedure called to compile the "continue" command.
+ *
+ * Results:
+ *	Returns TCL_OK for a successful compile. Returns TCL_ERROR to defer
+ *	evaluation to runtime.
+ *
+ * Side effects:
+ *	Instructions are added to envPtr to execute the "continue" command at
+ *	runtime.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclCompileContinueCmd(
+    Tcl_Interp *interp,		/* Used for error reporting. */
+    Tcl_Parse *parsePtr,	/* Points to a parse structure for the command
+				 * created by Tcl_ParseCommand. */
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)		/* Holds resulting instructions. */
+{
+    ExceptionRange *rangePtr;
+    ExceptionAux *auxPtr;
+
+    /*
+     * There should be no argument after the "continue".
+     */
+
+    if (parsePtr->numWords != 1) {
+	return TCL_ERROR;
+    }
+
+    /*
+     * See if we can find a valid continueOffset (i.e., not -1) in the
+     * innermost containing exception range.
+     */
+
+    rangePtr = TclGetInnermostExceptionRange(envPtr, TCL_CONTINUE, &auxPtr);
+    if (rangePtr && rangePtr->type == LOOP_EXCEPTION_RANGE) {
+	/*
+	 * Found the target! No need for a nasty INST_CONTINUE here.
+	 */
+
+	TclCleanupStackForBreakContinue(envPtr, auxPtr);
+	TclAddLoopContinueFixup(envPtr, auxPtr);
+    } else {
+	/*
+	 * Emit a real continue.
+	 */
+
+	TclEmitOpcode(INST_CONTINUE, envPtr);
+    }
+    TclAdjustStackDepth(1, envPtr);
+
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclCompileDict*Cmd --
+ *
+ *	Functions called to compile "dict" sucommands.
+ *
+ * Results:
+ *	All return TCL_OK for a successful compile, and TCL_ERROR to defer
+ *	evaluation to runtime.
+ *
+ * Side effects:
+ *	Instructions are added to envPtr to execute the "dict" subcommand at
+ *	runtime.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclCompileDictSetCmd(
+    Tcl_Interp *interp,		/* Used for looking up stuff. */
+    Tcl_Parse *parsePtr,	/* Points to a parse structure for the command
+				 * created by Tcl_ParseCommand. */
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)		/* Holds resulting instructions. */
+{
+    Tcl_Token *tokenPtr;
+    int i, dictVarIndex;
+    DefineLineInformation;	/* TIP #280 */
+    Tcl_Token *varTokenPtr;
+
+    /*
+     * There must be at least one argument after the command.
+     */
+
+    if (parsePtr->numWords < 4) {
+	return TCL_ERROR;
+    }
+
+    /*
+     * The dictionary variable must be a local scalar that is knowable at
+     * compile time; anything else exceeds the complexity of the opcode. So
+     * discover what the index is.
+     */
+
+    varTokenPtr = TokenAfter(parsePtr->tokenPtr);
+    dictVarIndex = LocalScalarFromToken(varTokenPtr, envPtr);
+    if (dictVarIndex < 0) {
+	return TCL_ERROR;
+    }
+
+    /*
+     * Remaining words (key path and value to set) can be handled normally.
+     */
+
+    tokenPtr = TokenAfter(varTokenPtr);
+    for (i=2 ; i< parsePtr->numWords ; i++) {
+	CompileWord(envPtr, tokenPtr, interp, i);
+	tokenPtr = TokenAfter(tokenPtr);
+    }
+
+    /*
+     * Now emit the instruction to do the dict manipulation.
+     */
+
+    TclEmitInstInt4( INST_DICT_SET, parsePtr->numWords-3,	envPtr);
+    TclEmitInt4(     dictVarIndex,			envPtr);
+    TclAdjustStackDepth(-1, envPtr);
+    return TCL_OK;
+}
+
+int
+TclCompileDictIncrCmd(
+    Tcl_Interp *interp,		/* Used for looking up stuff. */
+    Tcl_Parse *parsePtr,	/* Points to a parse structure for the command
+				 * created by Tcl_ParseCommand. */
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)		/* Holds resulting instructions. */
+{
+    DefineLineInformation;	/* TIP #280 */
+    Tcl_Token *varTokenPtr, *keyTokenPtr;
+    int dictVarIndex, incrAmount;
+
+    /*
+     * There must be at least two arguments after the command.
+     */
+
+    if (parsePtr->numWords < 3 || parsePtr->numWords > 4) {
+	return TCL_ERROR;
+    }
+    varTokenPtr = TokenAfter(parsePtr->tokenPtr);
+    keyTokenPtr = TokenAfter(varTokenPtr);
+
+    /*
+     * Parse the increment amount, if present.
+     */
+
+    if (parsePtr->numWords == 4) {
+	const char *word;
+	int numBytes, code;
+	Tcl_Token *incrTokenPtr;
+	Tcl_Obj *intObj;
+
+	incrTokenPtr = TokenAfter(keyTokenPtr);
+	if (incrTokenPtr->type != TCL_TOKEN_SIMPLE_WORD) {
+	    return TclCompileBasic2Or3ArgCmd(interp, parsePtr,cmdPtr, envPtr);
+	}
+	word = incrTokenPtr[1].start;
+	numBytes = incrTokenPtr[1].size;
+
+	intObj = Tcl_NewStringObj(word, numBytes);
+	Tcl_IncrRefCount(intObj);
+	code = TclGetIntFromObj(NULL, intObj, &incrAmount);
+	TclDecrRefCount(intObj);
+	if (code != TCL_OK) {
+	    return TclCompileBasic2Or3ArgCmd(interp, parsePtr,cmdPtr, envPtr);
+	}
+    } else {
+	incrAmount = 1;
+    }
+
+    /*
+     * The dictionary variable must be a local scalar that is knowable at
+     * compile time; anything else exceeds the complexity of the opcode. So
+     * discover what the index is.
+     */
+
+    dictVarIndex = LocalScalarFromToken(varTokenPtr, envPtr);
+    if (dictVarIndex < 0) {
+	return TclCompileBasic2Or3ArgCmd(interp, parsePtr, cmdPtr, envPtr);
+    }
+
+    /*
+     * Emit the key and the code to actually do the increment.
+     */
+
+    CompileWord(envPtr, keyTokenPtr, interp, 2);
+    TclEmitInstInt4( INST_DICT_INCR_IMM, incrAmount,	envPtr);
+    TclEmitInt4(     dictVarIndex,			envPtr);
+    return TCL_OK;
+}
+
+int
+TclCompileDictGetCmd(
+    Tcl_Interp *interp,		/* Used for looking up stuff. */
+    Tcl_Parse *parsePtr,	/* Points to a parse structure for the command
+				 * created by Tcl_ParseCommand. */
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)		/* Holds resulting instructions. */
+{
+    Tcl_Token *tokenPtr;
+    int i;
+    DefineLineInformation;	/* TIP #280 */
+
+    /*
+     * There must be at least two arguments after the command (the single-arg
+     * case is legal, but too special and magic for us to deal with here).
+     */
+
+    /* TODO: Consider support for compiling expanded args. */
+    if (parsePtr->numWords < 3) {
+	return TCL_ERROR;
+    }
+    tokenPtr = TokenAfter(parsePtr->tokenPtr);
+
+    /*
+     * Only compile this because we need INST_DICT_GET anyway.
+     */
+
+    for (i=1 ; i<parsePtr->numWords ; i++) {
+	CompileWord(envPtr, tokenPtr, interp, i);
+	tokenPtr = TokenAfter(tokenPtr);
+    }
+    TclEmitInstInt4(INST_DICT_GET, parsePtr->numWords-2, envPtr);
+    TclAdjustStackDepth(-1, envPtr);
+    return TCL_OK;
+}
+
+int
+TclCompileDictExistsCmd(
+    Tcl_Interp *interp,		/* Used for looking up stuff. */
+    Tcl_Parse *parsePtr,	/* Points to a parse structure for the command
+				 * created by Tcl_ParseCommand. */
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)		/* Holds resulting instructions. */
+{
+    Tcl_Token *tokenPtr;
+    int i;
+    DefineLineInformation;	/* TIP #280 */
+
+    /*
+     * There must be at least two arguments after the command (the single-arg
+     * case is legal, but too special and magic for us to deal with here).
+     */
+
+    /* TODO: Consider support for compiling expanded args. */
+    if (parsePtr->numWords < 3) {
+	return TCL_ERROR;
+    }
+    tokenPtr = TokenAfter(parsePtr->tokenPtr);
+
+    /*
+     * Now we do the code generation.
+     */
+
+    for (i=1 ; i<parsePtr->numWords ; i++) {
+	CompileWord(envPtr, tokenPtr, interp, i);
+	tokenPtr = TokenAfter(tokenPtr);
+    }
+    TclEmitInstInt4(INST_DICT_EXISTS, parsePtr->numWords-2, envPtr);
+    TclAdjustStackDepth(-1, envPtr);
+    return TCL_OK;
+}
+
+int
+TclCompileDictUnsetCmd(
+    Tcl_Interp *interp,		/* Used for looking up stuff. */
+    Tcl_Parse *parsePtr,	/* Points to a parse structure for the command
+				 * created by Tcl_ParseCommand. */
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)		/* Holds resulting instructions. */
+{
+    Tcl_Token *tokenPtr;
+    DefineLineInformation;	/* TIP #280 */
+    int i, dictVarIndex;
+
+    /*
+     * There must be at least one argument after the variable name for us to
+     * compile to bytecode.
+     */
+
+    /* TODO: Consider support for compiling expanded args. */
+    if (parsePtr->numWords < 3) {
+	return TCL_ERROR;
+    }
+
+    /*
+     * The dictionary variable must be a local scalar that is knowable at
+     * compile time; anything else exceeds the complexity of the opcode. So
+     * discover what the index is.
+     */
+
+    tokenPtr = TokenAfter(parsePtr->tokenPtr);
+    dictVarIndex = LocalScalarFromToken(tokenPtr, envPtr);
+    if (dictVarIndex < 0) {
+	return TclCompileBasicMin2ArgCmd(interp, parsePtr, cmdPtr, envPtr);
+    }
+
+    /*
+     * Remaining words (the key path) can be handled normally.
+     */
+
+    for (i=2 ; i<parsePtr->numWords ; i++) {
+	tokenPtr = TokenAfter(tokenPtr);
+	CompileWord(envPtr, tokenPtr, interp, i);
+    }
+
+    /*
+     * Now emit the instruction to do the dict manipulation.
+     */
+
+    TclEmitInstInt4( INST_DICT_UNSET, parsePtr->numWords-2,	envPtr);
+    TclEmitInt4(	dictVarIndex,				envPtr);
+    return TCL_OK;
+}
+
+int
+TclCompileDictCreateCmd(
+    Tcl_Interp *interp,		/* Used for looking up stuff. */
+    Tcl_Parse *parsePtr,	/* Points to a parse structure for the command
+				 * created by Tcl_ParseCommand. */
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)		/* Holds resulting instructions. */
+{
+    DefineLineInformation;	/* TIP #280 */
+    int worker;			/* Temp var for building the value in. */
+    Tcl_Token *tokenPtr;
+    Tcl_Obj *keyObj, *valueObj, *dictObj;
+    const char *bytes;
+    int i, len;
+
+    if ((parsePtr->numWords & 1) == 0) {
+	return TCL_ERROR;
+    }
+
+    /*
+     * See if we can build the value at compile time...
+     */
+
+    tokenPtr = TokenAfter(parsePtr->tokenPtr);
+    dictObj = Tcl_NewObj();
+    Tcl_IncrRefCount(dictObj);
+    for (i=1 ; i<parsePtr->numWords ; i+=2) {
+	keyObj = Tcl_NewObj();
+	Tcl_IncrRefCount(keyObj);
+	if (!TclWordKnownAtCompileTime(tokenPtr, keyObj)) {
+	    Tcl_DecrRefCount(keyObj);
+	    Tcl_DecrRefCount(dictObj);
+	    goto nonConstant;
+	}
+	tokenPtr = TokenAfter(tokenPtr);
+	valueObj = Tcl_NewObj();
+	Tcl_IncrRefCount(valueObj);
+	if (!TclWordKnownAtCompileTime(tokenPtr, valueObj)) {
+	    Tcl_DecrRefCount(keyObj);
+	    Tcl_DecrRefCount(valueObj);
+	    Tcl_DecrRefCount(dictObj);
+	    goto nonConstant;
+	}
+	tokenPtr = TokenAfter(tokenPtr);
+	Tcl_DictObjPut(NULL, dictObj, keyObj, valueObj);
+	Tcl_DecrRefCount(keyObj);
+	Tcl_DecrRefCount(valueObj);
+    }
+
+    /*
+     * We did! Excellent. The "verifyDict" is to do type forcing.
+     */
+
+    bytes = Tcl_GetStringFromObj(dictObj, &len);
+    PushLiteral(envPtr, bytes, len);
+    TclEmitOpcode(		INST_DUP,			envPtr);
+    TclEmitOpcode(		INST_DICT_VERIFY,		envPtr);
+    Tcl_DecrRefCount(dictObj);
+    return TCL_OK;
+
+    /*
+     * Otherwise, we've got to issue runtime code to do the building, which we
+     * do by [dict set]ting into an unnamed local variable. This requires that
+     * we are in a context with an LVT.
+     */
+
+  nonConstant:
+    worker = AnonymousLocal(envPtr);
+    if (worker < 0) {
+	return TclCompileBasicMin0ArgCmd(interp, parsePtr, cmdPtr, envPtr);
+    }
+
+    PushStringLiteral(envPtr,		"");
+    Emit14Inst(			INST_STORE_SCALAR, worker,	envPtr);
+    TclEmitOpcode(		INST_POP,			envPtr);
+    tokenPtr = TokenAfter(parsePtr->tokenPtr);
+    for (i=1 ; i<parsePtr->numWords ; i+=2) {
+	CompileWord(envPtr, tokenPtr, interp, i);
+	tokenPtr = TokenAfter(tokenPtr);
+	CompileWord(envPtr, tokenPtr, interp, i+1);
+	tokenPtr = TokenAfter(tokenPtr);
+	TclEmitInstInt4(	INST_DICT_SET, 1,		envPtr);
+	TclEmitInt4(			worker,			envPtr);
+	TclAdjustStackDepth(-1, envPtr);
+	TclEmitOpcode(		INST_POP,			envPtr);
+    }
+    Emit14Inst(			INST_LOAD_SCALAR, worker,	envPtr);
+    TclEmitInstInt1(		INST_UNSET_SCALAR, 0,		envPtr);
+    TclEmitInt4(			worker,			envPtr);
+    return TCL_OK;
+}
+
+int
+TclCompileDictMergeCmd(
+    Tcl_Interp *interp,		/* Used for looking up stuff. */
+    Tcl_Parse *parsePtr,	/* Points to a parse structure for the command
+				 * created by Tcl_ParseCommand. */
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)		/* Holds resulting instructions. */
+{
+    DefineLineInformation;	/* TIP #280 */
+    Tcl_Token *tokenPtr;
+    int i, workerIndex, infoIndex, outLoop;
+
+    /*
+     * Deal with some special edge cases. Note that in the case with one
+     * argument, the only thing to do is to verify the dict-ness.
+     */
+
+    /* TODO: Consider support for compiling expanded args. (less likely) */
+    if (parsePtr->numWords < 2) {
+	PushStringLiteral(envPtr, "");
+	return TCL_OK;
+    } else if (parsePtr->numWords == 2) {
+	tokenPtr = TokenAfter(parsePtr->tokenPtr);
+	CompileWord(envPtr, tokenPtr, interp, 1);
+	TclEmitOpcode(		INST_DUP,			envPtr);
+	TclEmitOpcode(		INST_DICT_VERIFY,		envPtr);
+	return TCL_OK;
+    }
+
+    /*
+     * There's real merging work to do.
+     *
+     * Allocate some working space. This means we'll only ever compile this
+     * command when there's an LVT present.
+     */
+
+    workerIndex = AnonymousLocal(envPtr);
+    if (workerIndex < 0) {
+	return TclCompileBasicMin2ArgCmd(interp, parsePtr, cmdPtr, envPtr);
+    }
+    infoIndex = AnonymousLocal(envPtr);
+
+    /*
+     * Get the first dictionary and verify that it is so.
+     */
+
+    tokenPtr = TokenAfter(parsePtr->tokenPtr);
+    CompileWord(envPtr, tokenPtr, interp, 1);
+    TclEmitOpcode(		INST_DUP,			envPtr);
+    TclEmitOpcode(		INST_DICT_VERIFY,		envPtr);
+    Emit14Inst(			INST_STORE_SCALAR, workerIndex,	envPtr);
+    TclEmitOpcode(		INST_POP,			envPtr);
+
+    /*
+     * For each of the remaining dictionaries...
+     */
+
+    outLoop = TclCreateExceptRange(CATCH_EXCEPTION_RANGE, envPtr);
+    TclEmitInstInt4(		INST_BEGIN_CATCH4, outLoop,	envPtr);
+    ExceptionRangeStarts(envPtr, outLoop);
+    for (i=2 ; i<parsePtr->numWords ; i++) {
+	/*
+	 * Get the dictionary, and merge its pairs into the first dict (using
+	 * a small loop).
+	 */
+
+	tokenPtr = TokenAfter(tokenPtr);
+	CompileWord(envPtr, tokenPtr, interp, i);
+	TclEmitInstInt4(	INST_DICT_FIRST, infoIndex,	envPtr);
+	TclEmitInstInt1(	INST_JUMP_TRUE1, 24,		envPtr);
+	TclEmitInstInt4(	INST_REVERSE, 2,		envPtr);
+	TclEmitInstInt4(	INST_DICT_SET, 1,		envPtr);
+	TclEmitInt4(			workerIndex,		envPtr);
+	TclAdjustStackDepth(-1, envPtr);
+	TclEmitOpcode(		INST_POP,			envPtr);
+	TclEmitInstInt4(	INST_DICT_NEXT, infoIndex,	envPtr);
+	TclEmitInstInt1(	INST_JUMP_FALSE1, -20,		envPtr);
+	TclEmitOpcode(		INST_POP,			envPtr);
+	TclEmitOpcode(		INST_POP,			envPtr);
+	TclEmitInstInt1(	INST_UNSET_SCALAR, 0,		envPtr);
+	TclEmitInt4(			infoIndex,		envPtr);
+    }
+    ExceptionRangeEnds(envPtr, outLoop);
+    TclEmitOpcode(		INST_END_CATCH,			envPtr);
+
+    /*
+     * Clean up any state left over.
+     */
+
+    Emit14Inst(			INST_LOAD_SCALAR, workerIndex,	envPtr);
+    TclEmitInstInt1(		INST_UNSET_SCALAR, 0,		envPtr);
+    TclEmitInt4(			workerIndex,		envPtr);
+    TclEmitInstInt1(		INST_JUMP1, 18,			envPtr);
+
+    /*
+     * If an exception happens when starting to iterate over the second (and
+     * subsequent) dicts. This is strictly not necessary, but it is nice.
+     */
+
+    TclAdjustStackDepth(-1, envPtr);
+    ExceptionRangeTarget(envPtr, outLoop, catchOffset);
+    TclEmitOpcode(		INST_PUSH_RETURN_OPTIONS,	envPtr);
+    TclEmitOpcode(		INST_PUSH_RESULT,		envPtr);
+    TclEmitOpcode(		INST_END_CATCH,			envPtr);
+    TclEmitInstInt1(		INST_UNSET_SCALAR, 0,		envPtr);
+    TclEmitInt4(			workerIndex,		envPtr);
+    TclEmitInstInt1(		INST_UNSET_SCALAR, 0,		envPtr);
+    TclEmitInt4(			infoIndex,		envPtr);
+    TclEmitOpcode(		INST_RETURN_STK,		envPtr);
+
+    return TCL_OK;
+}
+
+int
+TclCompileDictForCmd(
+    Tcl_Interp *interp,		/* Used for looking up stuff. */
+    Tcl_Parse *parsePtr,	/* Points to a parse structure for the command
+				 * created by Tcl_ParseCommand. */
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)		/* Holds resulting instructions. */
+{
+    return CompileDictEachCmd(interp, parsePtr, cmdPtr, envPtr,
+	    TCL_EACH_KEEP_NONE);
+}
+
+int
+TclCompileDictMapCmd(
+    Tcl_Interp *interp,		/* Used for looking up stuff. */
+    Tcl_Parse *parsePtr,	/* Points to a parse structure for the command
+				 * created by Tcl_ParseCommand. */
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)		/* Holds resulting instructions. */
+{
+    return CompileDictEachCmd(interp, parsePtr, cmdPtr, envPtr,
+	    TCL_EACH_COLLECT);
+}
+
+int
+CompileDictEachCmd(
+    Tcl_Interp *interp,		/* Used for looking up stuff. */
+    Tcl_Parse *parsePtr,	/* Points to a parse structure for the command
+				 * created by Tcl_ParseCommand. */
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr,		/* Holds resulting instructions. */
+    int collect)		/* Flag == TCL_EACH_COLLECT to collect and
+				 * construct a new dictionary with the loop
+				 * body result. */
+{
+    DefineLineInformation;	/* TIP #280 */
+    Tcl_Token *varsTokenPtr, *dictTokenPtr, *bodyTokenPtr;
+    int keyVarIndex, valueVarIndex, nameChars, loopRange, catchRange;
+    int infoIndex, jumpDisplacement, bodyTargetOffset, emptyTargetOffset;
+    int numVars, endTargetOffset;
+    int collectVar = -1;	/* Index of temp var holding the result
+				 * dict. */
+    const char **argv;
+    Tcl_DString buffer;
+
+    /*
+     * There must be three arguments after the command.
+     */
+
+    if (parsePtr->numWords != 4) {
+	return TclCompileBasic3ArgCmd(interp, parsePtr, cmdPtr, envPtr);
+    }
+
+    varsTokenPtr = TokenAfter(parsePtr->tokenPtr);
+    dictTokenPtr = TokenAfter(varsTokenPtr);
+    bodyTokenPtr = TokenAfter(dictTokenPtr);
+    if (varsTokenPtr->type != TCL_TOKEN_SIMPLE_WORD ||
+	    bodyTokenPtr->type != TCL_TOKEN_SIMPLE_WORD) {
+	return TclCompileBasic3ArgCmd(interp, parsePtr, cmdPtr, envPtr);
+    }
+
+    /*
+     * Create temporary variable to capture return values from loop body when
+     * we're collecting results.
+     */
+
+    if (collect == TCL_EACH_COLLECT) {
+	collectVar = AnonymousLocal(envPtr);
+	if (collectVar < 0) {
+	    return TclCompileBasic3ArgCmd(interp, parsePtr, cmdPtr, envPtr);
+	}
+    }
+
+    /*
+     * Check we've got a pair of variables and that they are local variables.
+     * Then extract their indices in the LVT.
+     */
+
+    Tcl_DStringInit(&buffer);
+    TclDStringAppendToken(&buffer, &varsTokenPtr[1]);
+    if (Tcl_SplitList(NULL, Tcl_DStringValue(&buffer), &numVars,
+	    &argv) != TCL_OK) {
+	Tcl_DStringFree(&buffer);
+	return TclCompileBasic3ArgCmd(interp, parsePtr, cmdPtr, envPtr);
+    }
+    Tcl_DStringFree(&buffer);
+    if (numVars != 2) {
+	ckfree(argv);
+	return TclCompileBasic3ArgCmd(interp, parsePtr, cmdPtr, envPtr);
+    }
+
+    nameChars = strlen(argv[0]);
+    keyVarIndex = LocalScalar(argv[0], nameChars, envPtr);
+    nameChars = strlen(argv[1]);
+    valueVarIndex = LocalScalar(argv[1], nameChars, envPtr);
+    ckfree(argv);
+
+    if ((keyVarIndex < 0) || (valueVarIndex < 0)) {
+	return TclCompileBasic3ArgCmd(interp, parsePtr, cmdPtr, envPtr);
+    }
+
+    /*
+     * Allocate a temporary variable to store the iterator reference. The
+     * variable will contain a Tcl_DictSearch reference which will be
+     * allocated by INST_DICT_FIRST and disposed when the variable is unset
+     * (at which point it should also have been finished with).
+     */
+
+    infoIndex = AnonymousLocal(envPtr);
+    if (infoIndex < 0) {
+	return TclCompileBasic3ArgCmd(interp, parsePtr, cmdPtr, envPtr);
+    }
+
+    /*
+     * Preparation complete; issue instructions. Note that this code issues
+     * fixed-sized jumps. That simplifies things a lot!
+     *
+     * First up, initialize the accumulator dictionary if needed.
+     */
+
+    if (collect == TCL_EACH_COLLECT) {
+	PushStringLiteral(envPtr, "");
+	Emit14Inst(	INST_STORE_SCALAR, collectVar,		envPtr);
+	TclEmitOpcode(	INST_POP,				envPtr);
+    }
+
+    /*
+     * Get the dictionary and start the iteration. No catching of errors at
+     * this point.
+     */
+
+    CompileWord(envPtr, dictTokenPtr, interp, 2);
+
+    /*
+     * Now we catch errors from here on so that we can finalize the search
+     * started by Tcl_DictObjFirst above.
+     */
+
+    catchRange = TclCreateExceptRange(CATCH_EXCEPTION_RANGE, envPtr);
+    TclEmitInstInt4(	INST_BEGIN_CATCH4, catchRange,		envPtr);
+    ExceptionRangeStarts(envPtr, catchRange);
+
+    TclEmitInstInt4(	INST_DICT_FIRST, infoIndex,		envPtr);
+    emptyTargetOffset = CurrentOffset(envPtr);
+    TclEmitInstInt4(	INST_JUMP_TRUE4, 0,			envPtr);
+
+    /*
+     * Inside the iteration, write the loop variables.
+     */
+
+    bodyTargetOffset = CurrentOffset(envPtr);
+    Emit14Inst(		INST_STORE_SCALAR, keyVarIndex,		envPtr);
+    TclEmitOpcode(	INST_POP,				envPtr);
+    Emit14Inst(		INST_STORE_SCALAR, valueVarIndex,	envPtr);
+    TclEmitOpcode(	INST_POP,				envPtr);
+
+    /*
+     * Set up the loop exception targets.
+     */
+
+    loopRange = TclCreateExceptRange(LOOP_EXCEPTION_RANGE, envPtr);
+    ExceptionRangeStarts(envPtr, loopRange);
+
+    /*
+     * Compile the loop body itself. It should be stack-neutral.
+     */
+
+    BODY(bodyTokenPtr, 3);
+    if (collect == TCL_EACH_COLLECT) {
+	Emit14Inst(	INST_LOAD_SCALAR, keyVarIndex,		envPtr);
+	TclEmitInstInt4(INST_OVER, 1,				envPtr);
+	TclEmitInstInt4(INST_DICT_SET, 1,			envPtr);
+	TclEmitInt4(		collectVar,			envPtr);
+	TclAdjustStackDepth(-1, envPtr);
+	TclEmitOpcode(	INST_POP,				envPtr);
+    }
+    TclEmitOpcode(	INST_POP,				envPtr);
+
+    /*
+     * Both exception target ranges (error and loop) end here.
+     */
+
+    ExceptionRangeEnds(envPtr, loopRange);
+    ExceptionRangeEnds(envPtr, catchRange);
+
+    /*
+     * Continue (or just normally process) by getting the next pair of items
+     * from the dictionary and jumping back to the code to write them into
+     * variables if there is another pair.
+     */
+
+    ExceptionRangeTarget(envPtr, loopRange, continueOffset);
+    TclEmitInstInt4(	INST_DICT_NEXT, infoIndex,		envPtr);
+    jumpDisplacement = bodyTargetOffset - CurrentOffset(envPtr);
+    TclEmitInstInt4(	INST_JUMP_FALSE4, jumpDisplacement,	envPtr);
+    endTargetOffset = CurrentOffset(envPtr);
+    TclEmitInstInt1(	INST_JUMP1, 0,				envPtr);
+
+    /*
+     * Error handler "finally" clause, which force-terminates the iteration
+     * and rethrows the error.
+     */
+
+    TclAdjustStackDepth(-1, envPtr);
+    ExceptionRangeTarget(envPtr, catchRange, catchOffset);
+    TclEmitOpcode(	INST_PUSH_RETURN_OPTIONS,		envPtr);
+    TclEmitOpcode(	INST_PUSH_RESULT,			envPtr);
+    TclEmitOpcode(	INST_END_CATCH,				envPtr);
+    TclEmitInstInt1(	INST_UNSET_SCALAR, 0,			envPtr);
+    TclEmitInt4(		infoIndex,			envPtr);
+    if (collect == TCL_EACH_COLLECT) {
+	TclEmitInstInt1(INST_UNSET_SCALAR, 0,			envPtr);
+	TclEmitInt4(		collectVar,			envPtr);
+    }
+    TclEmitOpcode(	INST_RETURN_STK,			envPtr);
+
+    /*
+     * Otherwise we're done (the jump after the DICT_FIRST points here) and we
+     * need to pop the bogus key/value pair (pushed to keep stack calculations
+     * easy!) Note that we skip the END_CATCH. [Bug 1382528]
+     */
+
+    jumpDisplacement = CurrentOffset(envPtr) - emptyTargetOffset;
+    TclUpdateInstInt4AtPc(INST_JUMP_TRUE4, jumpDisplacement,
+	    envPtr->codeStart + emptyTargetOffset);
+    jumpDisplacement = CurrentOffset(envPtr) - endTargetOffset;
+    TclUpdateInstInt1AtPc(INST_JUMP1, jumpDisplacement,
+	    envPtr->codeStart + endTargetOffset);
+    TclEmitOpcode(	INST_POP,				envPtr);
+    TclEmitOpcode(	INST_POP,				envPtr);
+    ExceptionRangeTarget(envPtr, loopRange, breakOffset);
+    TclFinalizeLoopExceptionRange(envPtr, loopRange);
+    TclEmitOpcode(	INST_END_CATCH,				envPtr);
+
+    /*
+     * Final stage of the command (normal case) is that we push an empty
+     * object (or push the accumulator as the result object). This is done
+     * last to promote peephole optimization when it's dropped immediately.
+     */
+
+    TclEmitInstInt1(	INST_UNSET_SCALAR, 0,			envPtr);
+    TclEmitInt4(		infoIndex,			envPtr);
+    if (collect == TCL_EACH_COLLECT) {
+	Emit14Inst(	INST_LOAD_SCALAR, collectVar,		envPtr);
+	TclEmitInstInt1(INST_UNSET_SCALAR, 0,			envPtr);
+	TclEmitInt4(		collectVar,			envPtr);
+    } else {
+	PushStringLiteral(envPtr, "");
+    }
+    return TCL_OK;
+}
+
+int
+TclCompileDictUpdateCmd(
+    Tcl_Interp *interp,		/* Used for looking up stuff. */
+    Tcl_Parse *parsePtr,	/* Points to a parse structure for the command
+				 * created by Tcl_ParseCommand. */
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)		/* Holds resulting instructions. */
+{
+    DefineLineInformation;	/* TIP #280 */
+    int i, dictIndex, numVars, range, infoIndex;
+    Tcl_Token **keyTokenPtrs, *dictVarTokenPtr, *bodyTokenPtr, *tokenPtr;
+    DictUpdateInfo *duiPtr;
+    JumpFixup jumpFixup;
+
+    /*
+     * There must be at least one argument after the command.
+     */
+
+    if (parsePtr->numWords < 5) {
+	return TCL_ERROR;
+    }
+
+    /*
+     * Parse the command. Expect the following:
+     *   dict update <lit(eral)> <any> <lit> ?<any> <lit> ...? <lit>
+     */
+
+    if ((parsePtr->numWords - 1) & 1) {
+	return TCL_ERROR;
+    }
+    numVars = (parsePtr->numWords - 3) / 2;
+
+    /*
+     * The dictionary variable must be a local scalar that is knowable at
+     * compile time; anything else exceeds the complexity of the opcode. So
+     * discover what the index is.
+     */
+
+    dictVarTokenPtr = TokenAfter(parsePtr->tokenPtr);
+    dictIndex = LocalScalarFromToken(dictVarTokenPtr, envPtr);
+    if (dictIndex < 0) {
+	goto issueFallback;
+    }
+
+    /*
+     * Assemble the instruction metadata. This is complex enough that it is
+     * represented as auxData; it holds an ordered list of variable indices
+     * that are to be used.
+     */
+
+    duiPtr = ckalloc(sizeof(DictUpdateInfo) + sizeof(int) * (numVars - 1));
+    duiPtr->length = numVars;
+    keyTokenPtrs = TclStackAlloc(interp, sizeof(Tcl_Token *) * numVars);
+    tokenPtr = TokenAfter(dictVarTokenPtr);
+
+    for (i=0 ; i<numVars ; i++) {
+	/*
+	 * Put keys to one side for later compilation to bytecode.
+	 */
+
+	keyTokenPtrs[i] = tokenPtr;
+	tokenPtr = TokenAfter(tokenPtr);
+
+	/*
+	 * Stash the index in the auxiliary data (if it is indeed a local
+	 * scalar that is resolvable at compile-time).
+	 */
+
+	duiPtr->varIndices[i] = LocalScalarFromToken(tokenPtr, envPtr);
+	if (duiPtr->varIndices[i] < 0) {
+	    goto failedUpdateInfoAssembly;
+	}
+	tokenPtr = TokenAfter(tokenPtr);
+    }
+    if (tokenPtr->type != TCL_TOKEN_SIMPLE_WORD) {
+	goto failedUpdateInfoAssembly;
+    }
+    bodyTokenPtr = tokenPtr;
+
+    /*
+     * The list of variables to bind is stored in auxiliary data so that it
+     * can't be snagged by literal sharing and forced to shimmer dangerously.
+     */
+
+    infoIndex = TclCreateAuxData(duiPtr, &dictUpdateInfoType, envPtr);
+
+    for (i=0 ; i<numVars ; i++) {
+	CompileWord(envPtr, keyTokenPtrs[i], interp, 2*i+2);
+    }
+    TclEmitInstInt4(	INST_LIST, numVars,			envPtr);
+    TclEmitInstInt4(	INST_DICT_UPDATE_START, dictIndex,	envPtr);
+    TclEmitInt4(		infoIndex,			envPtr);
+
+    range = TclCreateExceptRange(CATCH_EXCEPTION_RANGE, envPtr);
+    TclEmitInstInt4(	INST_BEGIN_CATCH4, range,		envPtr);
+
+    ExceptionRangeStarts(envPtr, range);
+    BODY(bodyTokenPtr, parsePtr->numWords - 1);
+    ExceptionRangeEnds(envPtr, range);
+
+    /*
+     * Normal termination code: the stack has the key list below the result of
+     * the body evaluation: swap them and finish the update code.
+     */
+
+    TclEmitOpcode(	INST_END_CATCH,				envPtr);
+    TclEmitInstInt4(	INST_REVERSE, 2,			envPtr);
+    TclEmitInstInt4(	INST_DICT_UPDATE_END, dictIndex,	envPtr);
+    TclEmitInt4(		infoIndex,			envPtr);
+
+    /*
+     * Jump around the exceptional termination code.
+     */
+
+    TclEmitForwardJump(envPtr, TCL_UNCONDITIONAL_JUMP, &jumpFixup);
+
+    /*
+     * Termination code for non-ok returns: stash the result and return
+     * options in the stack, bring up the key list, finish the update code,
+     * and finally return with the catched return data
+     */
+
+    ExceptionRangeTarget(envPtr, range, catchOffset);
+    TclEmitOpcode(	INST_PUSH_RESULT,			envPtr);
+    TclEmitOpcode(	INST_PUSH_RETURN_OPTIONS,		envPtr);
+    TclEmitOpcode(	INST_END_CATCH,				envPtr);
+    TclEmitInstInt4(	INST_REVERSE, 3,			envPtr);
+
+    TclEmitInstInt4(	INST_DICT_UPDATE_END, dictIndex,	envPtr);
+    TclEmitInt4(		infoIndex,			envPtr);
+    TclEmitInvoke(envPtr,INST_RETURN_STK);
+
+    if (TclFixupForwardJumpToHere(envPtr, &jumpFixup, 127)) {
+	Tcl_Panic("TclCompileDictCmd(update): bad jump distance %d",
+		(int) (CurrentOffset(envPtr) - jumpFixup.codeOffset));
+    }
+    TclStackFree(interp, keyTokenPtrs);
+    return TCL_OK;
+
+    /*
+     * Clean up after a failure to create the DictUpdateInfo structure.
+     */
+
+  failedUpdateInfoAssembly:
+    ckfree(duiPtr);
+    TclStackFree(interp, keyTokenPtrs);
+  issueFallback:
+    return TclCompileBasicMin2ArgCmd(interp, parsePtr, cmdPtr, envPtr);
+}
+
+int
+TclCompileDictAppendCmd(
+    Tcl_Interp *interp,		/* Used for looking up stuff. */
+    Tcl_Parse *parsePtr,	/* Points to a parse structure for the command
+				 * created by Tcl_ParseCommand. */
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)		/* Holds resulting instructions. */
+{
+    DefineLineInformation;	/* TIP #280 */
+    Tcl_Token *tokenPtr;
+    int i, dictVarIndex;
+
+    /*
+     * There must be at least two argument after the command. And we impose an
+     * (arbirary) safe limit; anyone exceeding it should stop worrying about
+     * speed quite so much. ;-)
+     */
+
+    /* TODO: Consider support for compiling expanded args. */
+    if (parsePtr->numWords<4 || parsePtr->numWords>100) {
+	return TCL_ERROR;
+    }
+
+    /*
+     * Get the index of the local variable that we will be working with.
+     */
+
+    tokenPtr = TokenAfter(parsePtr->tokenPtr);
+    dictVarIndex = LocalScalarFromToken(tokenPtr, envPtr);
+    if (dictVarIndex < 0) {
+	return TclCompileBasicMin2ArgCmd(interp, parsePtr,cmdPtr, envPtr);
+    }
+
+    /*
+     * Produce the string to concatenate onto the dictionary entry.
+     */
+
+    tokenPtr = TokenAfter(tokenPtr);
+    for (i=2 ; i<parsePtr->numWords ; i++) {
+	CompileWord(envPtr, tokenPtr, interp, i);
+	tokenPtr = TokenAfter(tokenPtr);
+    }
+    if (parsePtr->numWords > 4) {
+	TclEmitInstInt1(INST_STR_CONCAT1, parsePtr->numWords-3, envPtr);
+    }
+
+    /*
+     * Do the concatenation.
+     */
+
+    TclEmitInstInt4(INST_DICT_APPEND, dictVarIndex, envPtr);
+    return TCL_OK;
+}
+
+int
+TclCompileDictLappendCmd(
+    Tcl_Interp *interp,		/* Used for looking up stuff. */
+    Tcl_Parse *parsePtr,	/* Points to a parse structure for the command
+				 * created by Tcl_ParseCommand. */
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)		/* Holds resulting instructions. */
+{
+    DefineLineInformation;	/* TIP #280 */
+    Tcl_Token *varTokenPtr, *keyTokenPtr, *valueTokenPtr;
+    int dictVarIndex;
+
+    /*
+     * There must be three arguments after the command.
+     */
+
+    /* TODO: Consider support for compiling expanded args. */
+    /* Probably not.  Why is INST_DICT_LAPPEND limited to one value? */
+    if (parsePtr->numWords != 4) {
+	return TCL_ERROR;
+    }
+
+    /*
+     * Parse the arguments.
+     */
+
+    varTokenPtr = TokenAfter(parsePtr->tokenPtr);
+    keyTokenPtr = TokenAfter(varTokenPtr);
+    valueTokenPtr = TokenAfter(keyTokenPtr);
+    dictVarIndex = LocalScalarFromToken(varTokenPtr, envPtr);
+    if (dictVarIndex < 0) {
+	return TclCompileBasic3ArgCmd(interp, parsePtr, cmdPtr, envPtr);
+    }
+
+    /*
+     * Issue the implementation.
+     */
+
+    CompileWord(envPtr, keyTokenPtr, interp, 2);
+    CompileWord(envPtr, valueTokenPtr, interp, 3);
+    TclEmitInstInt4(	INST_DICT_LAPPEND, dictVarIndex,	envPtr);
+    return TCL_OK;
+}
+
+int
+TclCompileDictWithCmd(
+    Tcl_Interp *interp,		/* Used for looking up stuff. */
+    Tcl_Parse *parsePtr,	/* Points to a parse structure for the command
+				 * created by Tcl_ParseCommand. */
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)		/* Holds resulting instructions. */
+{
+    DefineLineInformation;	/* TIP #280 */
+    int i, range, varNameTmp = -1, pathTmp = -1, keysTmp, gotPath;
+    int dictVar, bodyIsEmpty = 1;
+    Tcl_Token *varTokenPtr, *tokenPtr;
+    JumpFixup jumpFixup;
+    const char *ptr, *end;
+
+    /*
+     * There must be at least one argument after the command.
+     */
+
+    /* TODO: Consider support for compiling expanded args. */
+    if (parsePtr->numWords < 3) {
+	return TCL_ERROR;
+    }
+
+    /*
+     * Parse the command (trivially). Expect the following:
+     *   dict with <any (varName)> ?<any> ...? <literal>
+     */
+
+    varTokenPtr = TokenAfter(parsePtr->tokenPtr);
+    tokenPtr = TokenAfter(varTokenPtr);
+    for (i=3 ; i<parsePtr->numWords ; i++) {
+	tokenPtr = TokenAfter(tokenPtr);
+    }
+    if (tokenPtr->type != TCL_TOKEN_SIMPLE_WORD) {
+	return TclCompileBasicMin2ArgCmd(interp, parsePtr, cmdPtr, envPtr);
+    }
+
+    /*
+     * Test if the last word is an empty script; if so, we can compile it in
+     * all cases, but if it is non-empty we need local variable table entries
+     * to hold the temporary variables (used to keep stack usage simple).
+     */
+
+    for (ptr=tokenPtr[1].start,end=ptr+tokenPtr[1].size ; ptr!=end ; ptr++) {
+	if (*ptr!=' ' && *ptr!='\t' && *ptr!='\n' && *ptr!='\r') {
+	    if (envPtr->procPtr == NULL) {
+		return TclCompileBasicMin2ArgCmd(interp, parsePtr, cmdPtr,
+			envPtr);
+	    }
+	    bodyIsEmpty = 0;
+	    break;
+	}
+    }
+
+    /*
+     * Determine if we're manipulating a dict in a simple local variable.
+     */
+
+    gotPath = (parsePtr->numWords > 3);
+    dictVar = LocalScalarFromToken(varTokenPtr, envPtr);
+
+    /*
+     * Special case: an empty body means we definitely have no need to issue
+     * try-finally style code or to allocate local variable table entries for
+     * storing temporaries. Still need to do both INST_DICT_EXPAND and
+     * INST_DICT_RECOMBINE_* though, because we can't determine if we're free
+     * of traces.
+     */
+
+    if (bodyIsEmpty) {
+	if (dictVar >= 0) {
+	    if (gotPath) {
+		/*
+		 * Case: Path into dict in LVT with empty body.
+		 */
+
+		tokenPtr = TokenAfter(varTokenPtr);
+		for (i=2 ; i<parsePtr->numWords-1 ; i++) {
+		    CompileWord(envPtr, tokenPtr, interp, i);
+		    tokenPtr = TokenAfter(tokenPtr);
+		}
+		TclEmitInstInt4(INST_LIST, parsePtr->numWords-3,envPtr);
+		Emit14Inst(	INST_LOAD_SCALAR, dictVar,	envPtr);
+		TclEmitInstInt4(INST_OVER, 1,			envPtr);
+		TclEmitOpcode(	INST_DICT_EXPAND,		envPtr);
+		TclEmitInstInt4(INST_DICT_RECOMBINE_IMM, dictVar, envPtr);
+	    } else {
+		/*
+		 * Case: Direct dict in LVT with empty body.
+		 */
+
+		PushStringLiteral(envPtr, "");
+		Emit14Inst(	INST_LOAD_SCALAR, dictVar,	envPtr);
+		PushStringLiteral(envPtr, "");
+		TclEmitOpcode(	INST_DICT_EXPAND,		envPtr);
+		TclEmitInstInt4(INST_DICT_RECOMBINE_IMM, dictVar, envPtr);
+	    }
+	} else {
+	    if (gotPath) {
+		/*
+		 * Case: Path into dict in non-simple var with empty body.
+		 */
+
+		tokenPtr = varTokenPtr;
+		for (i=1 ; i<parsePtr->numWords-1 ; i++) {
+		    CompileWord(envPtr, tokenPtr, interp, i);
+		    tokenPtr = TokenAfter(tokenPtr);
+		}
+		TclEmitInstInt4(INST_LIST, parsePtr->numWords-3,envPtr);
+		TclEmitInstInt4(INST_OVER, 1,			envPtr);
+		TclEmitOpcode(	INST_LOAD_STK,			envPtr);
+		TclEmitInstInt4(INST_OVER, 1,			envPtr);
+		TclEmitOpcode(	INST_DICT_EXPAND,		envPtr);
+		TclEmitOpcode(	INST_DICT_RECOMBINE_STK,	envPtr);
+	    } else {
+		/*
+		 * Case: Direct dict in non-simple var with empty body.
+		 */
+
+		CompileWord(envPtr, varTokenPtr, interp, 1);
+		TclEmitOpcode(	INST_DUP,			envPtr);
+		TclEmitOpcode(	INST_LOAD_STK,			envPtr);
+		PushStringLiteral(envPtr, "");
+		TclEmitOpcode(	INST_DICT_EXPAND,		envPtr);
+		PushStringLiteral(envPtr, "");
+		TclEmitInstInt4(INST_REVERSE, 2,		envPtr);
+		TclEmitOpcode(	INST_DICT_RECOMBINE_STK,	envPtr);
+	    }
+	}
+	PushStringLiteral(envPtr, "");
+	return TCL_OK;
+    }
+
+    /*
+     * OK, we have a non-trivial body. This means that the focus is on
+     * generating a try-finally structure where the INST_DICT_RECOMBINE_* goes
+     * in the 'finally' clause.
+     *
+     * Start by allocating local (unnamed, untraced) working variables.
+     */
+
+    if (dictVar == -1) {
+	varNameTmp = AnonymousLocal(envPtr);
+    }
+    if (gotPath) {
+	pathTmp = AnonymousLocal(envPtr);
+    }
+    keysTmp = AnonymousLocal(envPtr);
+
+    /*
+     * Issue instructions. First, the part to expand the dictionary.
+     */
+
+    if (dictVar == -1) {
+	CompileWord(envPtr, varTokenPtr, interp, 1);
+	Emit14Inst(		INST_STORE_SCALAR, varNameTmp,	envPtr);
+    }
+    tokenPtr = TokenAfter(varTokenPtr);
+    if (gotPath) {
+	for (i=2 ; i<parsePtr->numWords-1 ; i++) {
+	    CompileWord(envPtr, tokenPtr, interp, i);
+	    tokenPtr = TokenAfter(tokenPtr);
+	}
+	TclEmitInstInt4(	INST_LIST, parsePtr->numWords-3,envPtr);
+	Emit14Inst(		INST_STORE_SCALAR, pathTmp,	envPtr);
+	TclEmitOpcode(		INST_POP,			envPtr);
+    }
+    if (dictVar == -1) {
+	TclEmitOpcode(		INST_LOAD_STK,			envPtr);
+    } else {
+	Emit14Inst(		INST_LOAD_SCALAR, dictVar,	envPtr);
+    }
+    if (gotPath) {
+	Emit14Inst(		INST_LOAD_SCALAR, pathTmp,	envPtr);
+    } else {
+	PushStringLiteral(envPtr, "");
+    }
+    TclEmitOpcode(		INST_DICT_EXPAND,		envPtr);
+    Emit14Inst(			INST_STORE_SCALAR, keysTmp,	envPtr);
+    TclEmitOpcode(		INST_POP,			envPtr);
+
+    /*
+     * Now the body of the [dict with].
+     */
+
+    range = TclCreateExceptRange(CATCH_EXCEPTION_RANGE, envPtr);
+    TclEmitInstInt4(		INST_BEGIN_CATCH4, range,	envPtr);
+
+    ExceptionRangeStarts(envPtr, range);
+    BODY(tokenPtr, parsePtr->numWords - 1);
+    ExceptionRangeEnds(envPtr, range);
+
+    /*
+     * Now fold the results back into the dictionary in the OK case.
+     */
+
+    TclEmitOpcode(		INST_END_CATCH,			envPtr);
+    if (dictVar == -1) {
+	Emit14Inst(		INST_LOAD_SCALAR, varNameTmp,	envPtr);
+    }
+    if (gotPath) {
+	Emit14Inst(		INST_LOAD_SCALAR, pathTmp,	envPtr);
+    } else {
+	PushStringLiteral(envPtr, "");
+    }
+    Emit14Inst(			INST_LOAD_SCALAR, keysTmp,	envPtr);
+    if (dictVar == -1) {
+	TclEmitOpcode(		INST_DICT_RECOMBINE_STK,	envPtr);
+    } else {
+	TclEmitInstInt4(	INST_DICT_RECOMBINE_IMM, dictVar, envPtr);
+    }
+    TclEmitForwardJump(envPtr, TCL_UNCONDITIONAL_JUMP, &jumpFixup);
+
+    /*
+     * Now fold the results back into the dictionary in the exception case.
+     */
+
+    TclAdjustStackDepth(-1, envPtr);
+    ExceptionRangeTarget(envPtr, range, catchOffset);
+    TclEmitOpcode(		INST_PUSH_RETURN_OPTIONS,	envPtr);
+    TclEmitOpcode(		INST_PUSH_RESULT,		envPtr);
+    TclEmitOpcode(		INST_END_CATCH,			envPtr);
+    if (dictVar == -1) {
+	Emit14Inst(		INST_LOAD_SCALAR, varNameTmp,	envPtr);
+    }
+    if (parsePtr->numWords > 3) {
+	Emit14Inst(		INST_LOAD_SCALAR, pathTmp,	envPtr);
+    } else {
+	PushStringLiteral(envPtr, "");
+    }
+    Emit14Inst(			INST_LOAD_SCALAR, keysTmp,	envPtr);
+    if (dictVar == -1) {
+	TclEmitOpcode(		INST_DICT_RECOMBINE_STK,	envPtr);
+    } else {
+	TclEmitInstInt4(	INST_DICT_RECOMBINE_IMM, dictVar, envPtr);
+    }
+    TclEmitInvoke(envPtr,	INST_RETURN_STK);
+
+    /*
+     * Prepare for the start of the next command.
+     */
+
+    if (TclFixupForwardJumpToHere(envPtr, &jumpFixup, 127)) {
+	Tcl_Panic("TclCompileDictCmd(update): bad jump distance %d",
+		(int) (CurrentOffset(envPtr) - jumpFixup.codeOffset));
+    }
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * DupDictUpdateInfo, FreeDictUpdateInfo --
+ *
+ *	Functions to duplicate, release and print the aux data created for use
+ *	with the INST_DICT_UPDATE_START and INST_DICT_UPDATE_END instructions.
+ *
+ * Results:
+ *	DupDictUpdateInfo: a copy of the auxiliary data
+ *	FreeDictUpdateInfo: none
+ *	PrintDictUpdateInfo: none
+ *	DisassembleDictUpdateInfo: none
+ *
+ * Side effects:
+ *	DupDictUpdateInfo: allocates memory
+ *	FreeDictUpdateInfo: releases memory
+ *	PrintDictUpdateInfo: none
+ *	DisassembleDictUpdateInfo: none
+ *
+ *----------------------------------------------------------------------
+ */
+
+static ClientData
+DupDictUpdateInfo(
+    ClientData clientData)
+{
+    DictUpdateInfo *dui1Ptr, *dui2Ptr;
+    unsigned len;
+
+    dui1Ptr = clientData;
+    len = sizeof(DictUpdateInfo) + sizeof(int) * (dui1Ptr->length - 1);
+    dui2Ptr = ckalloc(len);
+    memcpy(dui2Ptr, dui1Ptr, len);
+    return dui2Ptr;
+}
+
+static void
+FreeDictUpdateInfo(
+    ClientData clientData)
+{
+    ckfree(clientData);
+}
+
+static void
+PrintDictUpdateInfo(
+    ClientData clientData,
+    Tcl_Obj *appendObj,
+    ByteCode *codePtr,
+    unsigned int pcOffset)
+{
+    DictUpdateInfo *duiPtr = clientData;
+    int i;
+
+    for (i=0 ; i<duiPtr->length ; i++) {
+	if (i) {
+	    Tcl_AppendToObj(appendObj, ", ", -1);
+	}
+	Tcl_AppendPrintfToObj(appendObj, "%%v%u", duiPtr->varIndices[i]);
+    }
+}
+
+static void
+DisassembleDictUpdateInfo(
+    ClientData clientData,
+    Tcl_Obj *dictObj,
+    ByteCode *codePtr,
+    unsigned int pcOffset)
+{
+    DictUpdateInfo *duiPtr = clientData;
+    int i;
+    Tcl_Obj *variables = Tcl_NewObj();
+
+    for (i=0 ; i<duiPtr->length ; i++) {
+	Tcl_ListObjAppendElement(NULL, variables,
+		Tcl_NewIntObj(duiPtr->varIndices[i]));
+    }
+    Tcl_DictObjPut(NULL, dictObj, Tcl_NewStringObj("variables", -1),
+	    variables);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclCompileErrorCmd --
+ *
+ *	Procedure called to compile the "error" command.
+ *
+ * Results:
+ *	Returns TCL_OK for a successful compile. Returns TCL_ERROR to defer
+ *	evaluation to runtime.
+ *
+ * Side effects:
+ *	Instructions are added to envPtr to execute the "error" command at
+ *	runtime.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclCompileErrorCmd(
+    Tcl_Interp *interp,		/* Used for context. */
+    Tcl_Parse *parsePtr,	/* Points to a parse structure for the command
+				 * created by Tcl_ParseCommand. */
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)		/* Holds resulting instructions. */
+{
+    /*
+     * General syntax: [error message ?errorInfo? ?errorCode?]
+     */
+
+    Tcl_Token *tokenPtr;
+    DefineLineInformation;	/* TIP #280 */
+
+    if (parsePtr->numWords < 2 || parsePtr->numWords > 4) {
+	return TCL_ERROR;
+    }
+
+    /*
+     * Handle the message.
+     */
+
+    tokenPtr = TokenAfter(parsePtr->tokenPtr);
+    CompileWord(envPtr, tokenPtr, interp, 1);
+
+    /*
+     * Construct the options. Note that -code and -level are not here.
+     */
+
+    if (parsePtr->numWords == 2) {
+	PushStringLiteral(envPtr, "");
+    } else {
+	PushStringLiteral(envPtr, "-errorinfo");
+	tokenPtr = TokenAfter(tokenPtr);
+	CompileWord(envPtr, tokenPtr, interp, 2);
+	if (parsePtr->numWords == 3) {
+	    TclEmitInstInt4(	INST_LIST, 2,			envPtr);
+	} else {
+	    PushStringLiteral(envPtr, "-errorcode");
+	    tokenPtr = TokenAfter(tokenPtr);
+	    CompileWord(envPtr, tokenPtr, interp, 3);
+	    TclEmitInstInt4(	INST_LIST, 4,			envPtr);
+	}
+    }
+
+    /*
+     * Issue the error via 'returnImm error 0'.
+     */
+
+    TclEmitInstInt4(		INST_RETURN_IMM, TCL_ERROR,	envPtr);
+    TclEmitInt4(			0,			envPtr);
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclCompileExprCmd --
+ *
+ *	Procedure called to compile the "expr" command.
+ *
+ * Results:
+ *	Returns TCL_OK for a successful compile. Returns TCL_ERROR to defer
+ *	evaluation to runtime.
+ *
+ * Side effects:
+ *	Instructions are added to envPtr to execute the "expr" command at
+ *	runtime.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclCompileExprCmd(
+    Tcl_Interp *interp,		/* Used for error reporting. */
+    Tcl_Parse *parsePtr,	/* Points to a parse structure for the command
+				 * created by Tcl_ParseCommand. */
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)		/* Holds resulting instructions. */
+{
+    Tcl_Token *firstWordPtr;
+
+    if (parsePtr->numWords == 1) {
+	return TCL_ERROR;
+    }
+
+    /*
+     * TIP #280: Use the per-word line information of the current command.
+     */
+
+    envPtr->line = envPtr->extCmdMapPtr->loc[
+	    envPtr->extCmdMapPtr->nuloc-1].line[1];
+
+    firstWordPtr = TokenAfter(parsePtr->tokenPtr);
+    TclCompileExprWords(interp, firstWordPtr, parsePtr->numWords-1, envPtr);
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclCompileForCmd --
+ *
+ *	Procedure called to compile the "for" command.
+ *
+ * Results:
+ *	Returns TCL_OK for a successful compile. Returns TCL_ERROR to defer
+ *	evaluation to runtime.
+ *
+ * Side effects:
+ *	Instructions are added to envPtr to execute the "for" command at
+ *	runtime.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclCompileForCmd(
+    Tcl_Interp *interp,		/* Used for error reporting. */
+    Tcl_Parse *parsePtr,	/* Points to a parse structure for the command
+				 * created by Tcl_ParseCommand. */
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)		/* Holds resulting instructions. */
+{
+    Tcl_Token *startTokenPtr, *testTokenPtr, *nextTokenPtr, *bodyTokenPtr;
+    JumpFixup jumpEvalCondFixup;
+    int bodyCodeOffset, nextCodeOffset, jumpDist;
+    int bodyRange, nextRange;
+    DefineLineInformation;	/* TIP #280 */
+
+    if (parsePtr->numWords != 5) {
+	return TCL_ERROR;
+    }
+
+    /*
+     * If the test expression requires substitutions, don't compile the for
+     * command inline. E.g., the expression might cause the loop to never
+     * execute or execute forever, as in "for {} "$x > 5" {incr x} {}".
+     */
+
+    startTokenPtr = TokenAfter(parsePtr->tokenPtr);
+    testTokenPtr = TokenAfter(startTokenPtr);
+    if (testTokenPtr->type != TCL_TOKEN_SIMPLE_WORD) {
+	return TCL_ERROR;
+    }
+
+    /*
+     * Bail out also if the body or the next expression require substitutions
+     * in order to insure correct behaviour [Bug 219166]
+     */
+
+    nextTokenPtr = TokenAfter(testTokenPtr);
+    bodyTokenPtr = TokenAfter(nextTokenPtr);
+    if ((nextTokenPtr->type != TCL_TOKEN_SIMPLE_WORD)
+	    || (bodyTokenPtr->type != TCL_TOKEN_SIMPLE_WORD)) {
+	return TCL_ERROR;
+    }
+
+    /*
+     * Inline compile the initial command.
+     */
+
+    BODY(startTokenPtr, 1);
+    TclEmitOpcode(INST_POP, envPtr);
+
+    /*
+     * Jump to the evaluation of the condition. This code uses the "loop
+     * rotation" optimisation (which eliminates one branch from the loop).
+     * "for start cond next body" produces then:
+     *       start
+     *       goto A
+     *    B: body                : bodyCodeOffset
+     *       next                : nextCodeOffset, continueOffset
+     *    A: cond -> result      : testCodeOffset
+     *       if (result) goto B
+     */
+
+    TclEmitForwardJump(envPtr, TCL_UNCONDITIONAL_JUMP, &jumpEvalCondFixup);
+
+    /*
+     * Compile the loop body.
+     */
+
+    bodyRange = TclCreateExceptRange(LOOP_EXCEPTION_RANGE, envPtr);
+    bodyCodeOffset = ExceptionRangeStarts(envPtr, bodyRange);
+    BODY(bodyTokenPtr, 4);
+    ExceptionRangeEnds(envPtr, bodyRange);
+    TclEmitOpcode(INST_POP, envPtr);
+
+    /*
+     * Compile the "next" subcommand. Note that this exception range will not
+     * have a continueOffset (other than -1) connected to it; it won't trap
+     * TCL_CONTINUE but rather just TCL_BREAK.
+     */
+
+    nextRange = TclCreateExceptRange(LOOP_EXCEPTION_RANGE, envPtr);
+    envPtr->exceptAuxArrayPtr[nextRange].supportsContinue = 0;
+    nextCodeOffset = ExceptionRangeStarts(envPtr, nextRange);
+    BODY(nextTokenPtr, 3);
+    ExceptionRangeEnds(envPtr, nextRange);
+    TclEmitOpcode(INST_POP, envPtr);
+
+    /*
+     * Compile the test expression then emit the conditional jump that
+     * terminates the for.
+     */
+
+    if (TclFixupForwardJumpToHere(envPtr, &jumpEvalCondFixup, 127)) {
+	bodyCodeOffset += 3;
+	nextCodeOffset += 3;
+    }
+
+    SetLineInformation(2);
+    TclCompileExprWords(interp, testTokenPtr, 1, envPtr);
+
+    jumpDist = CurrentOffset(envPtr) - bodyCodeOffset;
+    if (jumpDist > 127) {
+	TclEmitInstInt4(INST_JUMP_TRUE4, -jumpDist, envPtr);
+    } else {
+	TclEmitInstInt1(INST_JUMP_TRUE1, -jumpDist, envPtr);
+    }
+
+    /*
+     * Fix the starting points of the exception ranges (may have moved due to
+     * jump type modification) and set where the exceptions target.
+     */
+
+    envPtr->exceptArrayPtr[bodyRange].codeOffset = bodyCodeOffset;
+    envPtr->exceptArrayPtr[bodyRange].continueOffset = nextCodeOffset;
+
+    envPtr->exceptArrayPtr[nextRange].codeOffset = nextCodeOffset;
+
+    ExceptionRangeTarget(envPtr, bodyRange, breakOffset);
+    ExceptionRangeTarget(envPtr, nextRange, breakOffset);
+    TclFinalizeLoopExceptionRange(envPtr, bodyRange);
+    TclFinalizeLoopExceptionRange(envPtr, nextRange);
+
+    /*
+     * The for command's result is an empty string.
+     */
+
+    PushStringLiteral(envPtr, "");
+
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclCompileForeachCmd --
+ *
+ *	Procedure called to compile the "foreach" command.
+ *
+ * Results:
+ *	Returns TCL_OK for a successful compile. Returns TCL_ERROR to defer
+ *	evaluation to runtime.
+ *
+ * Side effects:
+ *	Instructions are added to envPtr to execute the "foreach" command at
+ *	runtime.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclCompileForeachCmd(
+    Tcl_Interp *interp,		/* Used for error reporting. */
+    Tcl_Parse *parsePtr,	/* Points to a parse structure for the command
+				 * created by Tcl_ParseCommand. */
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)		/* Holds resulting instructions. */
+{
+    return CompileEachloopCmd(interp, parsePtr, cmdPtr, envPtr,
+	    TCL_EACH_KEEP_NONE);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclCompileLmapCmd --
+ *
+ *	Procedure called to compile the "lmap" command.
+ *
+ * Results:
+ *	Returns TCL_OK for a successful compile. Returns TCL_ERROR to defer
+ *	evaluation to runtime.
+ *
+ * Side effects:
+ *	Instructions are added to envPtr to execute the "lmap" command at
+ *	runtime.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclCompileLmapCmd(
+    Tcl_Interp *interp,		/* Used for error reporting. */
+    Tcl_Parse *parsePtr,	/* Points to a parse structure for the command
+				 * created by Tcl_ParseCommand. */
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)		/* Holds resulting instructions. */
+{
+    return CompileEachloopCmd(interp, parsePtr, cmdPtr, envPtr,
+	    TCL_EACH_COLLECT);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * CompileEachloopCmd --
+ *
+ *	Procedure called to compile the "foreach" and "lmap" commands.
+ *
+ * Results:
+ *	Returns TCL_OK for a successful compile. Returns TCL_ERROR to defer
+ *	evaluation to runtime.
+ *
+ * Side effects:
+ *	Instructions are added to envPtr to execute the "foreach" command at
+ *	runtime.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+CompileEachloopCmd(
+    Tcl_Interp *interp,		/* Used for error reporting. */
+    Tcl_Parse *parsePtr,	/* Points to a parse structure for the command
+				 * created by Tcl_ParseCommand. */
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr,		/* Holds resulting instructions. */
+    int collect)		/* Select collecting or accumulating mode
+				 * (TCL_EACH_*) */
+{
+    Proc *procPtr = envPtr->procPtr;
+    ForeachInfo *infoPtr=NULL;	/* Points to the structure describing this
+				 * foreach command. Stored in a AuxData
+				 * record in the ByteCode. */
+
+    Tcl_Token *tokenPtr, *bodyTokenPtr;
+    int jumpBackOffset, infoIndex, range;
+    int numWords, numLists, i, j, code = TCL_OK;
+    Tcl_Obj *varListObj = NULL;
+    DefineLineInformation;	/* TIP #280 */
+
+    /*
+     * If the foreach command isn't in a procedure, don't compile it inline:
+     * the payoff is too small.
+     */
+
+    if (procPtr == NULL) {
+	return TCL_ERROR;
+    }
+
+    numWords = parsePtr->numWords;
+    if ((numWords < 4) || (numWords%2 != 0)) {
+	return TCL_ERROR;
+    }
+
+    /*
+     * Bail out if the body requires substitutions in order to insure correct
+     * behaviour. [Bug 219166]
+     */
+
+    for (i = 0, tokenPtr = parsePtr->tokenPtr; i < numWords-1; i++) {
+	tokenPtr = TokenAfter(tokenPtr);
+    }
+    bodyTokenPtr = tokenPtr;
+    if (bodyTokenPtr->type != TCL_TOKEN_SIMPLE_WORD) {
+	return TCL_ERROR;
+    }
+
+    /*
+     * Create and initialize the ForeachInfo and ForeachVarList data
+     * structures describing this command. Then create a AuxData record
+     * pointing to the ForeachInfo structure.
+     */
+
+    numLists = (numWords - 2)/2;
+    infoPtr = ckalloc(sizeof(ForeachInfo)
+	    + (numLists - 1) * sizeof(ForeachVarList *));
+    infoPtr->numLists = 0;	/* Count this up as we go */
+
+    /*
+     * Parse each var list into sequence of var names.  Don't
+     * compile the foreach inline if any var name needs substitutions or isn't
+     * a scalar, or if any var list needs substitutions.
+     */
+
+    varListObj = Tcl_NewObj();
+    for (i = 0, tokenPtr = parsePtr->tokenPtr;
+	    i < numWords-1;
+	    i++, tokenPtr = TokenAfter(tokenPtr)) {
+	ForeachVarList *varListPtr;
+	int numVars;
+
+	if (i%2 != 1) {
+	    continue;
+	}
+
+	/*
+	 * If the variable list is empty, we can enter an infinite loop when
+	 * the interpreted version would not.  Take care to ensure this does
+	 * not happen.  [Bug 1671138]
+	 */
+
+	if (!TclWordKnownAtCompileTime(tokenPtr, varListObj) ||
+		TCL_OK != Tcl_ListObjLength(NULL, varListObj, &numVars) ||
+		numVars == 0) {
+	    code = TCL_ERROR;
+	    goto done;
+	}
+
+	varListPtr = ckalloc(sizeof(ForeachVarList)
+		+ (numVars - 1) * sizeof(int));
+	varListPtr->numVars = numVars;
+	infoPtr->varLists[i/2] = varListPtr;
+	infoPtr->numLists++;
+
+	for (j = 0;  j < numVars;  j++) {
+	    Tcl_Obj *varNameObj;
+	    const char *bytes;
+	    int numBytes, varIndex;
+
+	    Tcl_ListObjIndex(NULL, varListObj, j, &varNameObj);
+	    bytes = Tcl_GetStringFromObj(varNameObj, &numBytes);
+	    varIndex = LocalScalar(bytes, numBytes, envPtr);
+	    if (varIndex < 0) {
+		code = TCL_ERROR;
+		goto done;
+	    }
+	    varListPtr->varIndexes[j] = varIndex;
+	}
+	Tcl_SetObjLength(varListObj, 0);
+    }
+
+    /*
+     * We will compile the foreach command.
+     */
+
+    infoIndex = TclCreateAuxData(infoPtr, &newForeachInfoType, envPtr);
+
+    /*
+     * Create the collecting object, unshared.
+     */
+
+    if (collect == TCL_EACH_COLLECT) {
+	TclEmitInstInt4(INST_LIST, 0, envPtr);
+    }
+
+    /*
+     * Evaluate each value list and leave it on stack.
+     */
+
+    for (i = 0, tokenPtr = parsePtr->tokenPtr;
+	    i < numWords-1;
+	    i++, tokenPtr = TokenAfter(tokenPtr)) {
+	if ((i%2 == 0) && (i > 0)) {
+	    CompileWord(envPtr, tokenPtr, interp, i);
+	}
+    }
+
+    TclEmitInstInt4(INST_FOREACH_START, infoIndex, envPtr);
+
+    /*
+     * Inline compile the loop body.
+     */
+
+    range = TclCreateExceptRange(LOOP_EXCEPTION_RANGE, envPtr);
+
+    ExceptionRangeStarts(envPtr, range);
+    BODY(bodyTokenPtr, numWords - 1);
+    ExceptionRangeEnds(envPtr, range);
+
+    if (collect == TCL_EACH_COLLECT) {
+	TclEmitOpcode(INST_LMAP_COLLECT, envPtr);
+    } else {
+	TclEmitOpcode(		INST_POP,			envPtr);
+    }
+
+    /*
+     * Bottom of loop code: assign each loop variable and check whether
+     * to terminate the loop. Set the loop's break target.
+     */
+
+    ExceptionRangeTarget(envPtr, range, continueOffset);
+    TclEmitOpcode(INST_FOREACH_STEP, envPtr);
+    ExceptionRangeTarget(envPtr, range, breakOffset);
+    TclFinalizeLoopExceptionRange(envPtr, range);
+    TclEmitOpcode(INST_FOREACH_END, envPtr);
+    TclAdjustStackDepth(-(numLists+2), envPtr);
+
+    /*
+     * Set the jumpback distance from INST_FOREACH_STEP to the start of the
+     * body's code. Misuse loopCtTemp for storing the jump size.
+     */
+
+    jumpBackOffset = envPtr->exceptArrayPtr[range].continueOffset -
+	    envPtr->exceptArrayPtr[range].codeOffset;
+    infoPtr->loopCtTemp = -jumpBackOffset;
+
+    /*
+     * The command's result is an empty string if not collecting. If
+     * collecting, it is automatically left on stack after FOREACH_END.
+     */
+
+    if (collect != TCL_EACH_COLLECT) {
+	PushStringLiteral(envPtr, "");
+    }
+
+    done:
+    if (code == TCL_ERROR) {
+	FreeForeachInfo(infoPtr);
+    }
+    Tcl_DecrRefCount(varListObj);
+    return code;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * DupForeachInfo --
+ *
+ *	This procedure duplicates a ForeachInfo structure created as auxiliary
+ *	data during the compilation of a foreach command.
+ *
+ * Results:
+ *	A pointer to a newly allocated copy of the existing ForeachInfo
+ *	structure is returned.
+ *
+ * Side effects:
+ *	Storage for the copied ForeachInfo record is allocated. If the
+ *	original ForeachInfo structure pointed to any ForeachVarList records,
+ *	these structures are also copied and pointers to them are stored in
+ *	the new ForeachInfo record.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static ClientData
+DupForeachInfo(
+    ClientData clientData)	/* The foreach command's compilation auxiliary
+				 * data to duplicate. */
+{
+    register ForeachInfo *srcPtr = clientData;
+    ForeachInfo *dupPtr;
+    register ForeachVarList *srcListPtr, *dupListPtr;
+    int numVars, i, j, numLists = srcPtr->numLists;
+
+    dupPtr = ckalloc(sizeof(ForeachInfo)
+	    + numLists * sizeof(ForeachVarList *));
+    dupPtr->numLists = numLists;
+    dupPtr->firstValueTemp = srcPtr->firstValueTemp;
+    dupPtr->loopCtTemp = srcPtr->loopCtTemp;
+
+    for (i = 0;  i < numLists;  i++) {
+	srcListPtr = srcPtr->varLists[i];
+	numVars = srcListPtr->numVars;
+	dupListPtr = ckalloc(sizeof(ForeachVarList)
+		+ numVars * sizeof(int));
+	dupListPtr->numVars = numVars;
+	for (j = 0;  j < numVars;  j++) {
+	    dupListPtr->varIndexes[j] =	srcListPtr->varIndexes[j];
+	}
+	dupPtr->varLists[i] = dupListPtr;
+    }
+    return dupPtr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * FreeForeachInfo --
+ *
+ *	Procedure to free a ForeachInfo structure created as auxiliary data
+ *	during the compilation of a foreach command.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Storage for the ForeachInfo structure pointed to by the ClientData
+ *	argument is freed as is any ForeachVarList record pointed to by the
+ *	ForeachInfo structure.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+FreeForeachInfo(
+    ClientData clientData)	/* The foreach command's compilation auxiliary
+				 * data to free. */
+{
+    register ForeachInfo *infoPtr = clientData;
+    register ForeachVarList *listPtr;
+    int numLists = infoPtr->numLists;
+    register int i;
+
+    for (i = 0;  i < numLists;  i++) {
+	listPtr = infoPtr->varLists[i];
+	ckfree(listPtr);
+    }
+    ckfree(infoPtr);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * PrintForeachInfo, DisassembleForeachInfo --
+ *
+ *	Functions to write a human-readable or script-readablerepresentation
+ *	of a ForeachInfo structure to a Tcl_Obj for debugging.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+PrintForeachInfo(
+    ClientData clientData,
+    Tcl_Obj *appendObj,
+    ByteCode *codePtr,
+    unsigned int pcOffset)
+{
+    register ForeachInfo *infoPtr = clientData;
+    register ForeachVarList *varsPtr;
+    int i, j;
+
+    Tcl_AppendToObj(appendObj, "data=[", -1);
+
+    for (i=0 ; i<infoPtr->numLists ; i++) {
+	if (i) {
+	    Tcl_AppendToObj(appendObj, ", ", -1);
+	}
+	Tcl_AppendPrintfToObj(appendObj, "%%v%u",
+		(unsigned) (infoPtr->firstValueTemp + i));
+    }
+    Tcl_AppendPrintfToObj(appendObj, "], loop=%%v%u",
+	    (unsigned) infoPtr->loopCtTemp);
+    for (i=0 ; i<infoPtr->numLists ; i++) {
+	if (i) {
+	    Tcl_AppendToObj(appendObj, ",", -1);
+	}
+	Tcl_AppendPrintfToObj(appendObj, "\n\t\t it%%v%u\t[",
+		(unsigned) (infoPtr->firstValueTemp + i));
+	varsPtr = infoPtr->varLists[i];
+	for (j=0 ; j<varsPtr->numVars ; j++) {
+	    if (j) {
+		Tcl_AppendToObj(appendObj, ", ", -1);
+	    }
+	    Tcl_AppendPrintfToObj(appendObj, "%%v%u",
+		    (unsigned) varsPtr->varIndexes[j]);
+	}
+	Tcl_AppendToObj(appendObj, "]", -1);
+    }
+}
+
+static void
+PrintNewForeachInfo(
+    ClientData clientData,
+    Tcl_Obj *appendObj,
+    ByteCode *codePtr,
+    unsigned int pcOffset)
+{
+    register ForeachInfo *infoPtr = clientData;
+    register ForeachVarList *varsPtr;
+    int i, j;
+
+    Tcl_AppendPrintfToObj(appendObj, "jumpOffset=%+d, vars=",
+	    infoPtr->loopCtTemp);
+    for (i=0 ; i<infoPtr->numLists ; i++) {
+	if (i) {
+	    Tcl_AppendToObj(appendObj, ",", -1);
+	}
+	Tcl_AppendToObj(appendObj, "[", -1);
+	varsPtr = infoPtr->varLists[i];
+	for (j=0 ; j<varsPtr->numVars ; j++) {
+	    if (j) {
+		Tcl_AppendToObj(appendObj, ",", -1);
+	    }
+	    Tcl_AppendPrintfToObj(appendObj, "%%v%u",
+		    (unsigned) varsPtr->varIndexes[j]);
+	}
+	Tcl_AppendToObj(appendObj, "]", -1);
+    }
+}
+
+static void
+DisassembleForeachInfo(
+    ClientData clientData,
+    Tcl_Obj *dictObj,
+    ByteCode *codePtr,
+    unsigned int pcOffset)
+{
+    register ForeachInfo *infoPtr = clientData;
+    register ForeachVarList *varsPtr;
+    int i, j;
+    Tcl_Obj *objPtr, *innerPtr;
+
+    /*
+     * Data stores.
+     */
+
+    objPtr = Tcl_NewObj();
+    for (i=0 ; i<infoPtr->numLists ; i++) {
+	Tcl_ListObjAppendElement(NULL, objPtr,
+		Tcl_NewIntObj(infoPtr->firstValueTemp + i));
+    }
+    Tcl_DictObjPut(NULL, dictObj, Tcl_NewStringObj("data", -1), objPtr);
+
+    /*
+     * Loop counter.
+     */
+
+    Tcl_DictObjPut(NULL, dictObj, Tcl_NewStringObj("loop", -1),
+	   Tcl_NewIntObj(infoPtr->loopCtTemp));
+
+    /*
+     * Assignment targets.
+     */
+
+    objPtr = Tcl_NewObj();
+    for (i=0 ; i<infoPtr->numLists ; i++) {
+	innerPtr = Tcl_NewObj();
+	varsPtr = infoPtr->varLists[i];
+	for (j=0 ; j<varsPtr->numVars ; j++) {
+	    Tcl_ListObjAppendElement(NULL, innerPtr,
+		    Tcl_NewIntObj(varsPtr->varIndexes[j]));
+	}
+	Tcl_ListObjAppendElement(NULL, objPtr, innerPtr);
+    }
+    Tcl_DictObjPut(NULL, dictObj, Tcl_NewStringObj("assign", -1), objPtr);
+}
+
+static void
+DisassembleNewForeachInfo(
+    ClientData clientData,
+    Tcl_Obj *dictObj,
+    ByteCode *codePtr,
+    unsigned int pcOffset)
+{
+    register ForeachInfo *infoPtr = clientData;
+    register ForeachVarList *varsPtr;
+    int i, j;
+    Tcl_Obj *objPtr, *innerPtr;
+
+    /*
+     * Jump offset.
+     */
+
+    Tcl_DictObjPut(NULL, dictObj, Tcl_NewStringObj("jumpOffset", -1),
+	   Tcl_NewIntObj(infoPtr->loopCtTemp));
+
+    /*
+     * Assignment targets.
+     */
+
+    objPtr = Tcl_NewObj();
+    for (i=0 ; i<infoPtr->numLists ; i++) {
+	innerPtr = Tcl_NewObj();
+	varsPtr = infoPtr->varLists[i];
+	for (j=0 ; j<varsPtr->numVars ; j++) {
+	    Tcl_ListObjAppendElement(NULL, innerPtr,
+		    Tcl_NewIntObj(varsPtr->varIndexes[j]));
+	}
+	Tcl_ListObjAppendElement(NULL, objPtr, innerPtr);
+    }
+    Tcl_DictObjPut(NULL, dictObj, Tcl_NewStringObj("assign", -1), objPtr);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclCompileFormatCmd --
+ *
+ *	Procedure called to compile the "format" command. Handles cases that
+ *	can be done as constants or simple string concatenation only.
+ *
+ * Results:
+ *	Returns TCL_OK for a successful compile. Returns TCL_ERROR to defer
+ *	evaluation to runtime.
+ *
+ * Side effects:
+ *	Instructions are added to envPtr to execute the "format" command at
+ *	runtime.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclCompileFormatCmd(
+    Tcl_Interp *interp,		/* Used for error reporting. */
+    Tcl_Parse *parsePtr,	/* Points to a parse structure for the command
+				 * created by Tcl_ParseCommand. */
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)		/* Holds resulting instructions. */
+{
+    DefineLineInformation;	/* TIP #280 */
+    Tcl_Token *tokenPtr = parsePtr->tokenPtr;
+    Tcl_Obj **objv, *formatObj, *tmpObj;
+    char *bytes, *start;
+    int i, j, len;
+
+    /*
+     * Don't handle any guaranteed-error cases.
+     */
+
+    if (parsePtr->numWords < 2) {
+	return TCL_ERROR;
+    }
+
+    /*
+     * Check if the argument words are all compile-time-known literals; that's
+     * a case we can handle by compiling to a constant.
+     */
+
+    formatObj = Tcl_NewObj();
+    Tcl_IncrRefCount(formatObj);
+    tokenPtr = TokenAfter(tokenPtr);
+    if (!TclWordKnownAtCompileTime(tokenPtr, formatObj)) {
+	Tcl_DecrRefCount(formatObj);
+	return TCL_ERROR;
+    }
+
+    objv = ckalloc((parsePtr->numWords-2) * sizeof(Tcl_Obj *));
+    for (i=0 ; i+2 < parsePtr->numWords ; i++) {
+	tokenPtr = TokenAfter(tokenPtr);
+	objv[i] = Tcl_NewObj();
+	Tcl_IncrRefCount(objv[i]);
+	if (!TclWordKnownAtCompileTime(tokenPtr, objv[i])) {
+	    goto checkForStringConcatCase;
+	}
+    }
+
+    /*
+     * Everything is a literal, so the result is constant too (or an error if
+     * the format is broken). Do the format now.
+     */
+
+    tmpObj = Tcl_Format(interp, Tcl_GetString(formatObj),
+	    parsePtr->numWords-2, objv);
+    for (; --i>=0 ;) {
+	Tcl_DecrRefCount(objv[i]);
+    }
+    ckfree(objv);
+    Tcl_DecrRefCount(formatObj);
+    if (tmpObj == NULL) {
+	TclCompileSyntaxError(interp, envPtr);
+	return TCL_OK;
+    }
+
+    /*
+     * Not an error, always a constant result, so just push the result as a
+     * literal. Job done.
+     */
+
+    bytes = Tcl_GetStringFromObj(tmpObj, &len);
+    PushLiteral(envPtr, bytes, len);
+    Tcl_DecrRefCount(tmpObj);
+    return TCL_OK;
+
+  checkForStringConcatCase:
+    /*
+     * See if we can generate a sequence of things to concatenate. This
+     * requires that all the % sequences be %s or %%, as everything else is
+     * sufficiently complex that we don't bother.
+     *
+     * First, get the state of the system relatively sensible (cleaning up
+     * after our attempt to spot a literal).
+     */
+
+    for (; i>=0 ; i--) {
+	Tcl_DecrRefCount(objv[i]);
+    }
+    ckfree(objv);
+    tokenPtr = TokenAfter(parsePtr->tokenPtr);
+    tokenPtr = TokenAfter(tokenPtr);
+    i = 0;
+
+    /*
+     * Now scan through and check for non-%s and non-%% substitutions.
+     */
+
+    for (bytes = Tcl_GetString(formatObj) ; *bytes ; bytes++) {
+	if (*bytes == '%') {
+	    bytes++;
+	    if (*bytes == 's') {
+		i++;
+		continue;
+	    } else if (*bytes == '%') {
+		continue;
+	    }
+	    Tcl_DecrRefCount(formatObj);
+	    return TCL_ERROR;
+	}
+    }
+
+    /*
+     * Check if the number of things to concatenate will fit in a byte.
+     */
+
+    if (i+2 != parsePtr->numWords || i > 125) {
+	Tcl_DecrRefCount(formatObj);
+	return TCL_ERROR;
+    }
+
+    /*
+     * Generate the pushes of the things to concatenate, a sequence of
+     * literals and compiled tokens (of which at least one is non-literal or
+     * we'd have the case in the first half of this function) which we will
+     * concatenate.
+     */
+
+    i = 0;			/* The count of things to concat. */
+    j = 2;			/* The index into the argument tokens, for
+				 * TIP#280 handling. */
+    start = Tcl_GetString(formatObj);
+				/* The start of the currently-scanned literal
+				 * in the format string. */
+    tmpObj = Tcl_NewObj();	/* The buffer used to accumulate the literal
+				 * being built. */
+    for (bytes = start ; *bytes ; bytes++) {
+	if (*bytes == '%') {
+	    Tcl_AppendToObj(tmpObj, start, bytes - start);
+	    if (*++bytes == '%') {
+		Tcl_AppendToObj(tmpObj, "%", 1);
+	    } else {
+		char *b = Tcl_GetStringFromObj(tmpObj, &len);
+
+		/*
+		 * If there is a non-empty literal from the format string,
+		 * push it and reset.
+		 */
+
+		if (len > 0) {
+		    PushLiteral(envPtr, b, len);
+		    Tcl_DecrRefCount(tmpObj);
+		    tmpObj = Tcl_NewObj();
+		    i++;
+		}
+
+		/*
+		 * Push the code to produce the string that would be
+		 * substituted with %s, except we'll be concatenating
+		 * directly.
+		 */
+
+		CompileWord(envPtr, tokenPtr, interp, j);
+		tokenPtr = TokenAfter(tokenPtr);
+		j++;
+		i++;
+	    }
+	    start = bytes + 1;
+	}
+    }
+
+    /*
+     * Handle the case of a trailing literal.
+     */
+
+    Tcl_AppendToObj(tmpObj, start, bytes - start);
+    bytes = Tcl_GetStringFromObj(tmpObj, &len);
+    if (len > 0) {
+	PushLiteral(envPtr, bytes, len);
+	i++;
+    }
+    Tcl_DecrRefCount(tmpObj);
+    Tcl_DecrRefCount(formatObj);
+
+    if (i > 1) {
+	/*
+	 * Do the concatenation, which produces the result.
+	 */
+
+	TclEmitInstInt1(INST_STR_CONCAT1, i, envPtr);
+    } else {
+	/*
+	 * EVIL HACK! Force there to be a string representation in the case
+	 * where there's just a "%s" in the format; case covered by the test
+	 * format-20.1 (and it is horrible...)
+	 */
+
+	TclEmitOpcode(INST_DUP, envPtr);
+	PushStringLiteral(envPtr, "");
+	TclEmitOpcode(INST_STR_EQ, envPtr);
+	TclEmitOpcode(INST_POP, envPtr);
+    }
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclLocalScalarFromToken --
+ *
+ *	Get the index into the table of compiled locals that corresponds
+ *	to a local scalar variable name.
+ *
+ * Results:
+ * 	Returns the non-negative integer index value into the table of
+ * 	compiled locals corresponding to a local scalar variable name.
+ * 	If the arguments passed in do not identify a local scalar variable
+ * 	then return -1.
+ *
+ * Side effects:
+ *	May add an entery into the table of compiled locals.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclLocalScalarFromToken(
+    Tcl_Token *tokenPtr,
+    CompileEnv *envPtr)
+{
+    int isScalar, index;
+
+    TclPushVarName(NULL, tokenPtr, envPtr, TCL_NO_ELEMENT, &index, &isScalar);
+    if (!isScalar) {
+	index = -1;
+    }
+    return index;
+}
+
+int
+TclLocalScalar(
+    const char *bytes,
+    int numBytes,
+    CompileEnv *envPtr)
+{
+    Tcl_Token token[2] =        {{TCL_TOKEN_SIMPLE_WORD, NULL, 0, 1},
+                                 {TCL_TOKEN_TEXT, NULL, 0, 0}};
+
+    token[1].start = bytes;
+    token[1].size = numBytes;
+    return TclLocalScalarFromToken(token, envPtr);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclPushVarName --
+ *
+ *	Procedure used in the compiling where pushing a variable name is
+ *	necessary (append, lappend, set).
+ *
+ * Results:
+ *	The values written to *localIndexPtr and *isScalarPtr signal to
+ *	the caller what the instructions emitted by this routine will do:
+ *
+ *	*isScalarPtr	(*localIndexPtr < 0)
+ *	1		1	Push the varname on the stack. (Stack +1)
+ *	1		0	*localIndexPtr is the index of the compiled
+ *				local for this varname.  No instructions
+ *				emitted.	(Stack +0)
+ *	0		1	Push part1 and part2 names of array element
+ *				on the stack.	(Stack +2)
+ *	0		0	*localIndexPtr is the index of the compiled
+ *				local for this array.  Element name is pushed
+ *				on the stack.	(Stack +1)
+ *
+ * Side effects:
+ *	Instructions are added to envPtr.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclPushVarName(
+    Tcl_Interp *interp,		/* Used for error reporting. */
+    Tcl_Token *varTokenPtr,	/* Points to a variable token. */
+    CompileEnv *envPtr,		/* Holds resulting instructions. */
+    int flags,			/* TCL_NO_LARGE_INDEX | TCL_NO_ELEMENT. */
+    int *localIndexPtr,		/* Must not be NULL. */
+    int *isScalarPtr)		/* Must not be NULL. */
+{
+    register const char *p;
+    const char *name, *elName;
+    register int i, n;
+    Tcl_Token *elemTokenPtr = NULL;
+    int nameChars, elNameChars, simpleVarName, localIndex;
+    int elemTokenCount = 0, allocedTokens = 0, removedParen = 0;
+
+    /*
+     * Decide if we can use a frame slot for the var/array name or if we need
+     * to emit code to compute and push the name at runtime. We use a frame
+     * slot (entry in the array of local vars) if we are compiling a procedure
+     * body and if the name is simple text that does not include namespace
+     * qualifiers.
+     */
+
+    simpleVarName = 0;
+    name = elName = NULL;
+    nameChars = elNameChars = 0;
+    localIndex = -1;
+
+    if (varTokenPtr->type == TCL_TOKEN_SIMPLE_WORD) {
+	/*
+	 * A simple variable name. Divide it up into "name" and "elName"
+	 * strings. If it is not a local variable, look it up at runtime.
+	 */
+
+	simpleVarName = 1;
+
+	name = varTokenPtr[1].start;
+	nameChars = varTokenPtr[1].size;
+	if (name[nameChars-1] == ')') {
+	    /*
+	     * last char is ')' => potential array reference.
+	     */
+
+	    for (i=0,p=name ; i<nameChars ; i++,p++) {
+		if (*p == '(') {
+		    elName = p + 1;
+		    elNameChars = nameChars - i - 2;
+		    nameChars = i;
+		    break;
+		}
+	    }
+
+	    if (!(flags & TCL_NO_ELEMENT) && (elName != NULL) && elNameChars) {
+		/*
+		 * An array element, the element name is a simple string:
+		 * assemble the corresponding token.
+		 */
+
+		elemTokenPtr = TclStackAlloc(interp, sizeof(Tcl_Token));
+		allocedTokens = 1;
+		elemTokenPtr->type = TCL_TOKEN_TEXT;
+		elemTokenPtr->start = elName;
+		elemTokenPtr->size = elNameChars;
+		elemTokenPtr->numComponents = 0;
+		elemTokenCount = 1;
+	    }
+	}
+    } else if (interp && ((n = varTokenPtr->numComponents) > 1)
+	    && (varTokenPtr[1].type == TCL_TOKEN_TEXT)
+	    && (varTokenPtr[n].type == TCL_TOKEN_TEXT)
+	    && (varTokenPtr[n].start[varTokenPtr[n].size - 1] == ')')) {
+	/*
+	 * Check for parentheses inside first token.
+	 */
+
+	simpleVarName = 0;
+	for (i = 0, p = varTokenPtr[1].start;
+		i < varTokenPtr[1].size; i++, p++) {
+	    if (*p == '(') {
+		simpleVarName = 1;
+		break;
+	    }
+	}
+	if (simpleVarName) {
+	    int remainingChars;
+
+	    /*
+	     * Check the last token: if it is just ')', do not count it.
+	     * Otherwise, remove the ')' and flag so that it is restored at
+	     * the end.
+	     */
+
+	    if (varTokenPtr[n].size == 1) {
+		n--;
+	    } else {
+		varTokenPtr[n].size--;
+		removedParen = n;
+	    }
+
+	    name = varTokenPtr[1].start;
+	    nameChars = p - varTokenPtr[1].start;
+	    elName = p + 1;
+	    remainingChars = (varTokenPtr[2].start - p) - 1;
+	    elNameChars = (varTokenPtr[n].start-p) + varTokenPtr[n].size - 1;
+
+	    if (!(flags & TCL_NO_ELEMENT)) {
+	      if (remainingChars) {
+		/*
+		 * Make a first token with the extra characters in the first
+		 * token.
+		 */
+
+		elemTokenPtr = TclStackAlloc(interp, n * sizeof(Tcl_Token));
+		allocedTokens = 1;
+		elemTokenPtr->type = TCL_TOKEN_TEXT;
+		elemTokenPtr->start = elName;
+		elemTokenPtr->size = remainingChars;
+		elemTokenPtr->numComponents = 0;
+		elemTokenCount = n;
+
+		/*
+		 * Copy the remaining tokens.
+		 */
+
+		memcpy(elemTokenPtr+1, varTokenPtr+2,
+			(n-1) * sizeof(Tcl_Token));
+	      } else {
+		/*
+		 * Use the already available tokens.
+		 */
+
+		elemTokenPtr = &varTokenPtr[2];
+		elemTokenCount = n - 1;
+	      }
+	    }
+	}
+    }
+
+    if (simpleVarName) {
+	/*
+	 * See whether name has any namespace separators (::'s).
+	 */
+
+	int hasNsQualifiers = 0;
+
+	for (i = 0, p = name;  i < nameChars;  i++, p++) {
+	    if ((*p == ':') && ((i+1) < nameChars) && (*(p+1) == ':')) {
+		hasNsQualifiers = 1;
+		break;
+	    }
+	}
+
+	/*
+	 * Look up the var name's index in the array of local vars in the proc
+	 * frame. If retrieving the var's value and it doesn't already exist,
+	 * push its name and look it up at runtime.
+	 */
+
+	if (!hasNsQualifiers) {
+	    localIndex = TclFindCompiledLocal(name, nameChars, 1, envPtr);
+	    if ((flags & TCL_NO_LARGE_INDEX) && (localIndex > 255)) {
+		/*
+		 * We'll push the name.
+		 */
+
+		localIndex = -1;
+	    }
+	}
+	if (interp && localIndex < 0) {
+	    PushLiteral(envPtr, name, nameChars);
+	}
+
+	/*
+	 * Compile the element script, if any, and only if not inhibited. [Bug
+	 * 3600328]
+	 */
+
+	if (elName != NULL && !(flags & TCL_NO_ELEMENT)) {
+	    if (elNameChars) {
+		TclCompileTokens(interp, elemTokenPtr, elemTokenCount,
+			envPtr);
+	    } else {
+		PushStringLiteral(envPtr, "");
+	    }
+	}
+    } else if (interp) {
+	/*
+	 * The var name isn't simple: compile and push it.
+	 */
+
+	CompileTokens(envPtr, varTokenPtr, interp);
+    }
+
+    if (removedParen) {
+	varTokenPtr[removedParen].size++;
+    }
+    if (allocedTokens) {
+	TclStackFree(interp, elemTokenPtr);
+    }
+    *localIndexPtr = localIndex;
+    *isScalarPtr = (elName == NULL);
+}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tclCompCmdsGR.c b/generic/tclCompCmdsGR.c
new file mode 100644
index 0000000..ffe39ba
--- /dev/null
+++ b/generic/tclCompCmdsGR.c
@@ -0,0 +1,3188 @@
+/*
+ * tclCompCmdsGR.c --
+ *
+ *	This file contains compilation procedures that compile various Tcl
+ *	commands (beginning with the letters 'g' through 'r') into a sequence
+ *	of instructions ("bytecodes").
+ *
+ * Copyright (c) 1997-1998 Sun Microsystems, Inc.
+ * Copyright (c) 2001 by Kevin B. Kenny.  All rights reserved.
+ * Copyright (c) 2002 ActiveState Corporation.
+ * Copyright (c) 2004-2013 by Donal K. Fellows.
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#include "tclInt.h"
+#include "tclCompile.h"
+#include <assert.h>
+
+/*
+ * Prototypes for procedures defined later in this file:
+ */
+
+static void		CompileReturnInternal(CompileEnv *envPtr,
+			    unsigned char op, int code, int level,
+			    Tcl_Obj *returnOpts);
+static int		IndexTailVarIfKnown(Tcl_Interp *interp,
+			    Tcl_Token *varTokenPtr, CompileEnv *envPtr);
+
+#define INDEX_END	(-2)
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * GetIndexFromToken --
+ *
+ *	Parse a token and get the encoded version of the index (as understood
+ *	by TEBC), assuming it is at all knowable at compile time. Only handles
+ *	indices that are integers or 'end' or 'end-integer'.
+ *
+ * Returns:
+ *	TCL_OK if parsing succeeded, and TCL_ERROR if it failed.
+ *
+ * Side effects:
+ *	Sets *index to the index value if successful.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static inline int
+GetIndexFromToken(
+    Tcl_Token *tokenPtr,
+    int *index)
+{
+    Tcl_Obj *tmpObj = Tcl_NewObj();
+    int result, idx;
+
+    if (!TclWordKnownAtCompileTime(tokenPtr, tmpObj)) {
+	Tcl_DecrRefCount(tmpObj);
+	return TCL_ERROR;
+    }
+
+    result = TclGetIntFromObj(NULL, tmpObj, &idx);
+    if (result == TCL_OK) {
+	if (idx < 0) {
+	    result = TCL_ERROR;
+	}
+    } else {
+	result = TclGetIntForIndexM(NULL, tmpObj, INDEX_END, &idx);
+	if (result == TCL_OK && idx > INDEX_END) {
+	    result = TCL_ERROR;
+	}
+    }
+    Tcl_DecrRefCount(tmpObj);
+
+    if (result == TCL_OK) {
+	*index = idx;
+    }
+
+    return result;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclCompileGlobalCmd --
+ *
+ *	Procedure called to compile the "global" command.
+ *
+ * Results:
+ *	Returns TCL_OK for a successful compile. Returns TCL_ERROR to defer
+ *	evaluation to runtime.
+ *
+ * Side effects:
+ *	Instructions are added to envPtr to execute the "global" command at
+ *	runtime.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclCompileGlobalCmd(
+    Tcl_Interp *interp,		/* Used for error reporting. */
+    Tcl_Parse *parsePtr,	/* Points to a parse structure for the command
+				 * created by Tcl_ParseCommand. */
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)		/* Holds resulting instructions. */
+{
+    Tcl_Token *varTokenPtr;
+    int localIndex, numWords, i;
+    DefineLineInformation;	/* TIP #280 */
+
+    /* TODO: Consider support for compiling expanded args. */
+    numWords = parsePtr->numWords;
+    if (numWords < 2) {
+	return TCL_ERROR;
+    }
+
+    /*
+     * 'global' has no effect outside of proc bodies; handle that at runtime
+     */
+
+    if (envPtr->procPtr == NULL) {
+	return TCL_ERROR;
+    }
+
+    /*
+     * Push the namespace
+     */
+
+    PushStringLiteral(envPtr, "::");
+
+    /*
+     * Loop over the variables.
+     */
+
+    varTokenPtr = TokenAfter(parsePtr->tokenPtr);
+    for (i=1; i<numWords; varTokenPtr = TokenAfter(varTokenPtr),i++) {
+	localIndex = IndexTailVarIfKnown(interp, varTokenPtr, envPtr);
+
+	if (localIndex < 0) {
+	    return TCL_ERROR;
+	}
+
+	/* TODO: Consider what value can pass throug the
+	 * IndexTailVarIfKnown() screen.  Full CompileWord()
+	 * likely does not apply here.  Push known value instead. */
+	CompileWord(envPtr, varTokenPtr, interp, i);
+	TclEmitInstInt4(	INST_NSUPVAR, localIndex,	envPtr);
+    }
+
+    /*
+     * Pop the namespace, and set the result to empty
+     */
+
+    TclEmitOpcode(		INST_POP,			envPtr);
+    PushStringLiteral(envPtr, "");
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclCompileIfCmd --
+ *
+ *	Procedure called to compile the "if" command.
+ *
+ * Results:
+ *	Returns TCL_OK for a successful compile. Returns TCL_ERROR to defer
+ *	evaluation to runtime.
+ *
+ * Side effects:
+ *	Instructions are added to envPtr to execute the "if" command at
+ *	runtime.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclCompileIfCmd(
+    Tcl_Interp *interp,		/* Used for error reporting. */
+    Tcl_Parse *parsePtr,	/* Points to a parse structure for the command
+				 * created by Tcl_ParseCommand. */
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)		/* Holds resulting instructions. */
+{
+    JumpFixupArray jumpFalseFixupArray;
+				/* Used to fix the ifFalse jump after each
+				 * test when its target PC is determined. */
+    JumpFixupArray jumpEndFixupArray;
+				/* Used to fix the jump after each "then" body
+				 * to the end of the "if" when that PC is
+				 * determined. */
+    Tcl_Token *tokenPtr, *testTokenPtr;
+    int jumpIndex = 0;		/* Avoid compiler warning. */
+    int jumpFalseDist, numWords, wordIdx, numBytes, j, code;
+    const char *word;
+    int realCond = 1;		/* Set to 0 for static conditions:
+				 * "if 0 {..}" */
+    int boolVal;		/* Value of static condition. */
+    int compileScripts = 1;
+    DefineLineInformation;	/* TIP #280 */
+
+    /*
+     * Only compile the "if" command if all arguments are simple words, in
+     * order to insure correct substitution [Bug 219166]
+     */
+
+    tokenPtr = parsePtr->tokenPtr;
+    wordIdx = 0;
+    numWords = parsePtr->numWords;
+
+    for (wordIdx = 0; wordIdx < numWords; wordIdx++) {
+	if (tokenPtr->type != TCL_TOKEN_SIMPLE_WORD) {
+	    return TCL_ERROR;
+	}
+	tokenPtr = TokenAfter(tokenPtr);
+    }
+
+    TclInitJumpFixupArray(&jumpFalseFixupArray);
+    TclInitJumpFixupArray(&jumpEndFixupArray);
+    code = TCL_OK;
+
+    /*
+     * Each iteration of this loop compiles one "if expr ?then? body" or
+     * "elseif expr ?then? body" clause.
+     */
+
+    tokenPtr = parsePtr->tokenPtr;
+    wordIdx = 0;
+    while (wordIdx < numWords) {
+	/*
+	 * Stop looping if the token isn't "if" or "elseif".
+	 */
+
+	word = tokenPtr[1].start;
+	numBytes = tokenPtr[1].size;
+	if ((tokenPtr == parsePtr->tokenPtr)
+		|| ((numBytes == 6) && (strncmp(word, "elseif", 6) == 0))) {
+	    tokenPtr = TokenAfter(tokenPtr);
+	    wordIdx++;
+	} else {
+	    break;
+	}
+	if (wordIdx >= numWords) {
+	    code = TCL_ERROR;
+	    goto done;
+	}
+
+	/*
+	 * Compile the test expression then emit the conditional jump around
+	 * the "then" part.
+	 */
+
+	testTokenPtr = tokenPtr;
+
+	if (realCond) {
+	    /*
+	     * Find out if the condition is a constant.
+	     */
+
+	    Tcl_Obj *boolObj = Tcl_NewStringObj(testTokenPtr[1].start,
+		    testTokenPtr[1].size);
+
+	    Tcl_IncrRefCount(boolObj);
+	    code = Tcl_GetBooleanFromObj(NULL, boolObj, &boolVal);
+	    TclDecrRefCount(boolObj);
+	    if (code == TCL_OK) {
+		/*
+		 * A static condition.
+		 */
+
+		realCond = 0;
+		if (!boolVal) {
+		    compileScripts = 0;
+		}
+	    } else {
+		SetLineInformation(wordIdx);
+		Tcl_ResetResult(interp);
+		TclCompileExprWords(interp, testTokenPtr, 1, envPtr);
+		if (jumpFalseFixupArray.next >= jumpFalseFixupArray.end) {
+		    TclExpandJumpFixupArray(&jumpFalseFixupArray);
+		}
+		jumpIndex = jumpFalseFixupArray.next;
+		jumpFalseFixupArray.next++;
+		TclEmitForwardJump(envPtr, TCL_FALSE_JUMP,
+			jumpFalseFixupArray.fixup+jumpIndex);
+	    }
+	    code = TCL_OK;
+	}
+
+	/*
+	 * Skip over the optional "then" before the then clause.
+	 */
+
+	tokenPtr = TokenAfter(testTokenPtr);
+	wordIdx++;
+	if (wordIdx >= numWords) {
+	    code = TCL_ERROR;
+	    goto done;
+	}
+	if (tokenPtr->type == TCL_TOKEN_SIMPLE_WORD) {
+	    word = tokenPtr[1].start;
+	    numBytes = tokenPtr[1].size;
+	    if ((numBytes == 4) && (strncmp(word, "then", 4) == 0)) {
+		tokenPtr = TokenAfter(tokenPtr);
+		wordIdx++;
+		if (wordIdx >= numWords) {
+		    code = TCL_ERROR;
+		    goto done;
+		}
+	    }
+	}
+
+	/*
+	 * Compile the "then" command body.
+	 */
+
+	if (compileScripts) {
+	    BODY(tokenPtr, wordIdx);
+	}
+
+	if (realCond) {
+	    /*
+	     * Jump to the end of the "if" command. Both jumpFalseFixupArray
+	     * and jumpEndFixupArray are indexed by "jumpIndex".
+	     */
+
+	    if (jumpEndFixupArray.next >= jumpEndFixupArray.end) {
+		TclExpandJumpFixupArray(&jumpEndFixupArray);
+	    }
+	    jumpEndFixupArray.next++;
+	    TclEmitForwardJump(envPtr, TCL_UNCONDITIONAL_JUMP,
+		    jumpEndFixupArray.fixup+jumpIndex);
+
+	    /*
+	     * Fix the target of the jumpFalse after the test. Generate a 4
+	     * byte jump if the distance is > 120 bytes. This is conservative,
+	     * and ensures that we won't have to replace this jump if we later
+	     * also need to replace the proceeding jump to the end of the "if"
+	     * with a 4 byte jump.
+	     */
+
+	    TclAdjustStackDepth(-1, envPtr);
+	    if (TclFixupForwardJumpToHere(envPtr,
+		    jumpFalseFixupArray.fixup+jumpIndex, 120)) {
+		/*
+		 * Adjust the code offset for the proceeding jump to the end
+		 * of the "if" command.
+		 */
+
+		jumpEndFixupArray.fixup[jumpIndex].codeOffset += 3;
+	    }
+	} else if (boolVal) {
+	    /*
+	     * We were processing an "if 1 {...}"; stop compiling scripts.
+	     */
+
+	    compileScripts = 0;
+	} else {
+	    /*
+	     * We were processing an "if 0 {...}"; reset so that the rest
+	     * (elseif, else) is compiled correctly.
+	     */
+
+	    realCond = 1;
+	    compileScripts = 1;
+	}
+
+	tokenPtr = TokenAfter(tokenPtr);
+	wordIdx++;
+    }
+
+    /*
+     * Check for the optional else clause. Do not compile anything if this was
+     * an "if 1 {...}" case.
+     */
+
+    if ((wordIdx < numWords) && (tokenPtr->type == TCL_TOKEN_SIMPLE_WORD)) {
+	/*
+	 * There is an else clause. Skip over the optional "else" word.
+	 */
+
+	word = tokenPtr[1].start;
+	numBytes = tokenPtr[1].size;
+	if ((numBytes == 4) && (strncmp(word, "else", 4) == 0)) {
+	    tokenPtr = TokenAfter(tokenPtr);
+	    wordIdx++;
+	    if (wordIdx >= numWords) {
+		code = TCL_ERROR;
+		goto done;
+	    }
+	}
+
+	if (compileScripts) {
+	    /*
+	     * Compile the else command body.
+	     */
+
+	    BODY(tokenPtr, wordIdx);
+	}
+
+	/*
+	 * Make sure there are no words after the else clause.
+	 */
+
+	wordIdx++;
+	if (wordIdx < numWords) {
+	    code = TCL_ERROR;
+	    goto done;
+	}
+    } else {
+	/*
+	 * No else clause: the "if" command's result is an empty string.
+	 */
+
+	if (compileScripts) {
+	    PushStringLiteral(envPtr, "");
+	}
+    }
+
+    /*
+     * Fix the unconditional jumps to the end of the "if" command.
+     */
+
+    for (j = jumpEndFixupArray.next;  j > 0;  j--) {
+	jumpIndex = (j - 1);	/* i.e. process the closest jump first. */
+	if (TclFixupForwardJumpToHere(envPtr,
+		jumpEndFixupArray.fixup+jumpIndex, 127)) {
+	    /*
+	     * Adjust the immediately preceeding "ifFalse" jump. We moved it's
+	     * target (just after this jump) down three bytes.
+	     */
+
+	    unsigned char *ifFalsePc = envPtr->codeStart
+		    + jumpFalseFixupArray.fixup[jumpIndex].codeOffset;
+	    unsigned char opCode = *ifFalsePc;
+
+	    if (opCode == INST_JUMP_FALSE1) {
+		jumpFalseDist = TclGetInt1AtPtr(ifFalsePc + 1);
+		jumpFalseDist += 3;
+		TclStoreInt1AtPtr(jumpFalseDist, (ifFalsePc + 1));
+	    } else if (opCode == INST_JUMP_FALSE4) {
+		jumpFalseDist = TclGetInt4AtPtr(ifFalsePc + 1);
+		jumpFalseDist += 3;
+		TclStoreInt4AtPtr(jumpFalseDist, (ifFalsePc + 1));
+	    } else {
+		Tcl_Panic("TclCompileIfCmd: unexpected opcode \"%d\" updating ifFalse jump", (int) opCode);
+	    }
+	}
+    }
+
+    /*
+     * Free the jumpFixupArray array if malloc'ed storage was used.
+     */
+
+  done:
+    TclFreeJumpFixupArray(&jumpFalseFixupArray);
+    TclFreeJumpFixupArray(&jumpEndFixupArray);
+    return code;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclCompileIncrCmd --
+ *
+ *	Procedure called to compile the "incr" command.
+ *
+ * Results:
+ *	Returns TCL_OK for a successful compile. Returns TCL_ERROR to defer
+ *	evaluation to runtime.
+ *
+ * Side effects:
+ *	Instructions are added to envPtr to execute the "incr" command at
+ *	runtime.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclCompileIncrCmd(
+    Tcl_Interp *interp,		/* Used for error reporting. */
+    Tcl_Parse *parsePtr,	/* Points to a parse structure for the command
+				 * created by Tcl_ParseCommand. */
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)		/* Holds resulting instructions. */
+{
+    Tcl_Token *varTokenPtr, *incrTokenPtr;
+    int isScalar, localIndex, haveImmValue, immValue;
+    DefineLineInformation;	/* TIP #280 */
+
+    if ((parsePtr->numWords != 2) && (parsePtr->numWords != 3)) {
+	return TCL_ERROR;
+    }
+
+    varTokenPtr = TokenAfter(parsePtr->tokenPtr);
+
+    PushVarNameWord(interp, varTokenPtr, envPtr, TCL_NO_LARGE_INDEX,
+	    &localIndex, &isScalar, 1);
+
+    /*
+     * If an increment is given, push it, but see first if it's a small
+     * integer.
+     */
+
+    haveImmValue = 0;
+    immValue = 1;
+    if (parsePtr->numWords == 3) {
+	incrTokenPtr = TokenAfter(varTokenPtr);
+	if (incrTokenPtr->type == TCL_TOKEN_SIMPLE_WORD) {
+	    const char *word = incrTokenPtr[1].start;
+	    int numBytes = incrTokenPtr[1].size;
+	    int code;
+	    Tcl_Obj *intObj = Tcl_NewStringObj(word, numBytes);
+
+	    Tcl_IncrRefCount(intObj);
+	    code = TclGetIntFromObj(NULL, intObj, &immValue);
+	    TclDecrRefCount(intObj);
+	    if ((code == TCL_OK) && (-127 <= immValue) && (immValue <= 127)) {
+		haveImmValue = 1;
+	    }
+	    if (!haveImmValue) {
+		PushLiteral(envPtr, word, numBytes);
+	    }
+	} else {
+	    SetLineInformation(2);
+	    CompileTokens(envPtr, incrTokenPtr, interp);
+	}
+    } else {			/* No incr amount given so use 1. */
+	haveImmValue = 1;
+    }
+
+    /*
+     * Emit the instruction to increment the variable.
+     */
+
+    if (isScalar) {	/* Simple scalar variable. */
+	if (localIndex >= 0) {
+	    if (haveImmValue) {
+		TclEmitInstInt1(INST_INCR_SCALAR1_IMM, localIndex, envPtr);
+		TclEmitInt1(immValue, envPtr);
+	    } else {
+		TclEmitInstInt1(INST_INCR_SCALAR1, localIndex,	envPtr);
+	    }
+	} else {
+	    if (haveImmValue) {
+		TclEmitInstInt1(INST_INCR_STK_IMM, immValue, envPtr);
+	    } else {
+		TclEmitOpcode(	INST_INCR_STK,		envPtr);
+	    }
+	}
+    } else {			/* Simple array variable. */
+	if (localIndex >= 0) {
+	    if (haveImmValue) {
+		TclEmitInstInt1(INST_INCR_ARRAY1_IMM, localIndex, envPtr);
+		TclEmitInt1(immValue, envPtr);
+	    } else {
+		TclEmitInstInt1(INST_INCR_ARRAY1, localIndex,	envPtr);
+	    }
+	} else {
+	    if (haveImmValue) {
+		TclEmitInstInt1(INST_INCR_ARRAY_STK_IMM, immValue, envPtr);
+	    } else {
+		TclEmitOpcode(	INST_INCR_ARRAY_STK,		envPtr);
+	    }
+	}
+    }
+
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclCompileInfo*Cmd --
+ *
+ *	Procedures called to compile "info" subcommands.
+ *
+ * Results:
+ *	Returns TCL_OK for a successful compile. Returns TCL_ERROR to defer
+ *	evaluation to runtime.
+ *
+ * Side effects:
+ *	Instructions are added to envPtr to execute the "info" subcommand at
+ *	runtime.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclCompileInfoCommandsCmd(
+    Tcl_Interp *interp,		/* Used for error reporting. */
+    Tcl_Parse *parsePtr,	/* Points to a parse structure for the command
+				 * created by Tcl_ParseCommand. */
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)
+{
+    DefineLineInformation;	/* TIP #280 */
+    Tcl_Token *tokenPtr;
+    Tcl_Obj *objPtr;
+    char *bytes;
+
+    /*
+     * We require one compile-time known argument for the case we can compile.
+     */
+
+    if (parsePtr->numWords == 1) {
+	return TclCompileBasic0ArgCmd(interp, parsePtr, cmdPtr, envPtr);
+    } else if (parsePtr->numWords != 2) {
+	return TCL_ERROR;
+    }
+    tokenPtr = TokenAfter(parsePtr->tokenPtr);
+    objPtr = Tcl_NewObj();
+    Tcl_IncrRefCount(objPtr);
+    if (!TclWordKnownAtCompileTime(tokenPtr, objPtr)) {
+	goto notCompilable;
+    }
+    bytes = Tcl_GetString(objPtr);
+
+    /*
+     * We require that the argument start with "::" and not have any of "*\[?"
+     * in it. (Theoretically, we should look in only the final component, but
+     * the difference is so slight given current naming practices.)
+     */
+
+    if (bytes[0] != ':' || bytes[1] != ':' || !TclMatchIsTrivial(bytes)) {
+	goto notCompilable;
+    }
+    Tcl_DecrRefCount(objPtr);
+
+    /*
+     * Confirmed as a literal that will not frighten the horses. Compile. Note
+     * that the result needs to be list-ified.
+     */
+
+    /* TODO: Just push the known value */
+    CompileWord(envPtr, tokenPtr,		interp, 1);
+    TclEmitOpcode(	INST_RESOLVE_COMMAND,	envPtr);
+    TclEmitOpcode(	INST_DUP,		envPtr);
+    TclEmitOpcode(	INST_STR_LEN,		envPtr);
+    TclEmitInstInt1(	INST_JUMP_FALSE1, 7,	envPtr);
+    TclEmitInstInt4(	INST_LIST, 1,		envPtr);
+    return TCL_OK;
+
+  notCompilable:
+    Tcl_DecrRefCount(objPtr);
+    return TclCompileBasic1ArgCmd(interp, parsePtr, cmdPtr, envPtr);
+}
+
+int
+TclCompileInfoCoroutineCmd(
+    Tcl_Interp *interp,		/* Used for error reporting. */
+    Tcl_Parse *parsePtr,	/* Points to a parse structure for the command
+				 * created by Tcl_ParseCommand. */
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)		/* Holds resulting instructions. */
+{
+    /*
+     * Only compile [info coroutine] without arguments.
+     */
+
+    if (parsePtr->numWords != 1) {
+	return TCL_ERROR;
+    }
+
+    /*
+     * Not much to do; we compile to a single instruction...
+     */
+
+    TclEmitOpcode(		INST_COROUTINE_NAME,		envPtr);
+    return TCL_OK;
+}
+
+int
+TclCompileInfoExistsCmd(
+    Tcl_Interp *interp,		/* Used for error reporting. */
+    Tcl_Parse *parsePtr,	/* Points to a parse structure for the command
+				 * created by Tcl_ParseCommand. */
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)		/* Holds resulting instructions. */
+{
+    Tcl_Token *tokenPtr;
+    int isScalar, localIndex;
+    DefineLineInformation;	/* TIP #280 */
+
+    if (parsePtr->numWords != 2) {
+	return TCL_ERROR;
+    }
+
+    /*
+     * Decide if we can use a frame slot for the var/array name or if we need
+     * to emit code to compute and push the name at runtime. We use a frame
+     * slot (entry in the array of local vars) if we are compiling a procedure
+     * body and if the name is simple text that does not include namespace
+     * qualifiers.
+     */
+
+    tokenPtr = TokenAfter(parsePtr->tokenPtr);
+    PushVarNameWord(interp, tokenPtr, envPtr, 0, &localIndex, &isScalar, 1);
+
+    /*
+     * Emit instruction to check the variable for existence.
+     */
+
+    if (isScalar) {
+	if (localIndex < 0) {
+	    TclEmitOpcode(	INST_EXIST_STK,			envPtr);
+	} else {
+	    TclEmitInstInt4(	INST_EXIST_SCALAR, localIndex,	envPtr);
+	}
+    } else {
+	if (localIndex < 0) {
+	    TclEmitOpcode(	INST_EXIST_ARRAY_STK,		envPtr);
+	} else {
+	    TclEmitInstInt4(	INST_EXIST_ARRAY, localIndex,	envPtr);
+	}
+    }
+
+    return TCL_OK;
+}
+
+int
+TclCompileInfoLevelCmd(
+    Tcl_Interp *interp,		/* Used for error reporting. */
+    Tcl_Parse *parsePtr,	/* Points to a parse structure for the command
+				 * created by Tcl_ParseCommand. */
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)		/* Holds resulting instructions. */
+{
+    /*
+     * Only compile [info level] without arguments or with a single argument.
+     */
+
+    if (parsePtr->numWords == 1) {
+	/*
+	 * Not much to do; we compile to a single instruction...
+	 */
+
+	TclEmitOpcode(		INST_INFO_LEVEL_NUM,		envPtr);
+    } else if (parsePtr->numWords != 2) {
+	return TCL_ERROR;
+    } else {
+	DefineLineInformation;	/* TIP #280 */
+
+	/*
+	 * Compile the argument, then add the instruction to convert it into a
+	 * list of arguments.
+	 */
+
+	CompileWord(envPtr, TokenAfter(parsePtr->tokenPtr), interp, 1);
+	TclEmitOpcode(		INST_INFO_LEVEL_ARGS,		envPtr);
+    }
+    return TCL_OK;
+}
+
+int
+TclCompileInfoObjectClassCmd(
+    Tcl_Interp *interp,		/* Used for error reporting. */
+    Tcl_Parse *parsePtr,	/* Points to a parse structure for the command
+				 * created by Tcl_ParseCommand. */
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)
+{
+    DefineLineInformation;	/* TIP #280 */
+    Tcl_Token *tokenPtr = TokenAfter(parsePtr->tokenPtr);
+
+    if (parsePtr->numWords != 2) {
+	return TCL_ERROR;
+    }
+    CompileWord(envPtr,		tokenPtr,		interp, 1);
+    TclEmitOpcode(		INST_TCLOO_CLASS,	envPtr);
+    return TCL_OK;
+}
+
+int
+TclCompileInfoObjectIsACmd(
+    Tcl_Interp *interp,		/* Used for error reporting. */
+    Tcl_Parse *parsePtr,	/* Points to a parse structure for the command
+				 * created by Tcl_ParseCommand. */
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)
+{
+    DefineLineInformation;	/* TIP #280 */
+    Tcl_Token *tokenPtr = TokenAfter(parsePtr->tokenPtr);
+
+    /*
+     * We only handle [info object isa object <somevalue>]. The first three
+     * words are compressed to a single token by the ensemble compilation
+     * engine.
+     */
+
+    if (parsePtr->numWords != 3) {
+	return TCL_ERROR;
+    }
+    if (tokenPtr->type != TCL_TOKEN_SIMPLE_WORD || tokenPtr[1].size < 1
+	    || strncmp(tokenPtr[1].start, "object", tokenPtr[1].size)) {
+	return TCL_ERROR;
+    }
+    tokenPtr = TokenAfter(tokenPtr);
+
+    /*
+     * Issue the code.
+     */
+
+    CompileWord(envPtr,		tokenPtr,		interp, 2);
+    TclEmitOpcode(		INST_TCLOO_IS_OBJECT,	envPtr);
+    return TCL_OK;
+}
+
+int
+TclCompileInfoObjectNamespaceCmd(
+    Tcl_Interp *interp,		/* Used for error reporting. */
+    Tcl_Parse *parsePtr,	/* Points to a parse structure for the command
+				 * created by Tcl_ParseCommand. */
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)
+{
+    DefineLineInformation;	/* TIP #280 */
+    Tcl_Token *tokenPtr = TokenAfter(parsePtr->tokenPtr);
+
+    if (parsePtr->numWords != 2) {
+	return TCL_ERROR;
+    }
+    CompileWord(envPtr,		tokenPtr,		interp, 1);
+    TclEmitOpcode(		INST_TCLOO_NS,		envPtr);
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclCompileLappendCmd --
+ *
+ *	Procedure called to compile the "lappend" command.
+ *
+ * Results:
+ *	Returns TCL_OK for a successful compile. Returns TCL_ERROR to defer
+ *	evaluation to runtime.
+ *
+ * Side effects:
+ *	Instructions are added to envPtr to execute the "lappend" command at
+ *	runtime.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclCompileLappendCmd(
+    Tcl_Interp *interp,		/* Used for error reporting. */
+    Tcl_Parse *parsePtr,	/* Points to a parse structure for the command
+				 * created by Tcl_ParseCommand. */
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)		/* Holds resulting instructions. */
+{
+    Tcl_Token *varTokenPtr, *valueTokenPtr;
+    int isScalar, localIndex, numWords, i;
+    DefineLineInformation;	/* TIP #280 */
+
+    /* TODO: Consider support for compiling expanded args. */
+    numWords = parsePtr->numWords;
+    if (numWords < 3) {
+	return TCL_ERROR;
+    }
+
+    if (numWords != 3 || envPtr->procPtr == NULL) {
+	goto lappendMultiple;
+    }
+
+    /*
+     * Decide if we can use a frame slot for the var/array name or if we
+     * need to emit code to compute and push the name at runtime. We use a
+     * frame slot (entry in the array of local vars) if we are compiling a
+     * procedure body and if the name is simple text that does not include
+     * namespace qualifiers.
+     */
+
+    varTokenPtr = TokenAfter(parsePtr->tokenPtr);
+
+    PushVarNameWord(interp, varTokenPtr, envPtr, 0,
+	    &localIndex, &isScalar, 1);
+
+    /*
+     * If we are doing an assignment, push the new value. In the no values
+     * case, create an empty object.
+     */
+
+    if (numWords > 2) {
+	Tcl_Token *valueTokenPtr = TokenAfter(varTokenPtr);
+
+	CompileWord(envPtr, valueTokenPtr, interp, 2);
+    }
+
+    /*
+     * Emit instructions to set/get the variable.
+     */
+
+    /*
+     * The *_STK opcodes should be refactored to make better use of existing
+     * LOAD/STORE instructions.
+     */
+
+    if (isScalar) {
+	if (localIndex < 0) {
+	    TclEmitOpcode(	INST_LAPPEND_STK,		envPtr);
+	} else {
+	    Emit14Inst(		INST_LAPPEND_SCALAR, localIndex, envPtr);
+	}
+    } else {
+	if (localIndex < 0) {
+	    TclEmitOpcode(	INST_LAPPEND_ARRAY_STK,		envPtr);
+	} else {
+	    Emit14Inst(		INST_LAPPEND_ARRAY, localIndex,	envPtr);
+	}
+    }
+
+    return TCL_OK;
+
+  lappendMultiple:
+    varTokenPtr = TokenAfter(parsePtr->tokenPtr);
+    PushVarNameWord(interp, varTokenPtr, envPtr, 0,
+	    &localIndex, &isScalar, 1);
+    valueTokenPtr = TokenAfter(varTokenPtr);
+    for (i = 2 ; i < numWords ; i++) {
+	CompileWord(envPtr, valueTokenPtr, interp, i);
+	valueTokenPtr = TokenAfter(valueTokenPtr);
+    }
+    TclEmitInstInt4(	    INST_LIST, numWords-2,		envPtr);
+    if (isScalar) {
+	if (localIndex < 0) {
+	    TclEmitOpcode(  INST_LAPPEND_LIST_STK,		envPtr);
+	} else {
+	    TclEmitInstInt4(INST_LAPPEND_LIST, localIndex,	envPtr);
+	}
+    } else {
+	if (localIndex < 0) {
+	    TclEmitOpcode(  INST_LAPPEND_LIST_ARRAY_STK,	envPtr);
+	} else {
+	    TclEmitInstInt4(INST_LAPPEND_LIST_ARRAY, localIndex,envPtr);
+	}
+    }
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclCompileLassignCmd --
+ *
+ *	Procedure called to compile the "lassign" command.
+ *
+ * Results:
+ *	Returns TCL_OK for a successful compile. Returns TCL_ERROR to defer
+ *	evaluation to runtime.
+ *
+ * Side effects:
+ *	Instructions are added to envPtr to execute the "lassign" command at
+ *	runtime.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclCompileLassignCmd(
+    Tcl_Interp *interp,		/* Used for error reporting. */
+    Tcl_Parse *parsePtr,	/* Points to a parse structure for the command
+				 * created by Tcl_ParseCommand. */
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)		/* Holds resulting instructions. */
+{
+    Tcl_Token *tokenPtr;
+    int isScalar, localIndex, numWords, idx;
+    DefineLineInformation;	/* TIP #280 */
+
+    numWords = parsePtr->numWords;
+
+    /*
+     * Check for command syntax error, but we'll punt that to runtime.
+     */
+
+    if (numWords < 3) {
+	return TCL_ERROR;
+    }
+
+    /*
+     * Generate code to push list being taken apart by [lassign].
+     */
+
+    tokenPtr = TokenAfter(parsePtr->tokenPtr);
+    CompileWord(envPtr, tokenPtr, interp, 1);
+
+    /*
+     * Generate code to assign values from the list to variables.
+     */
+
+    for (idx=0 ; idx<numWords-2 ; idx++) {
+	tokenPtr = TokenAfter(tokenPtr);
+
+	/*
+	 * Generate the next variable name.
+	 */
+
+	PushVarNameWord(interp, tokenPtr, envPtr, 0, &localIndex,
+		&isScalar, idx+2);
+
+	/*
+	 * Emit instructions to get the idx'th item out of the list value on
+	 * the stack and assign it to the variable.
+	 */
+
+	if (isScalar) {
+	    if (localIndex >= 0) {
+		TclEmitOpcode(	INST_DUP,			envPtr);
+		TclEmitInstInt4(INST_LIST_INDEX_IMM, idx,	envPtr);
+		Emit14Inst(	INST_STORE_SCALAR, localIndex,	envPtr);
+		TclEmitOpcode(	INST_POP,			envPtr);
+	    } else {
+		TclEmitInstInt4(INST_OVER, 1,			envPtr);
+		TclEmitInstInt4(INST_LIST_INDEX_IMM, idx,	envPtr);
+		TclEmitOpcode(	INST_STORE_STK,			envPtr);
+		TclEmitOpcode(	INST_POP,			envPtr);
+	    }
+	} else {
+	    if (localIndex >= 0) {
+		TclEmitInstInt4(INST_OVER, 1,			envPtr);
+		TclEmitInstInt4(INST_LIST_INDEX_IMM, idx,	envPtr);
+		Emit14Inst(	INST_STORE_ARRAY, localIndex,	envPtr);
+		TclEmitOpcode(	INST_POP,			envPtr);
+	    } else {
+		TclEmitInstInt4(INST_OVER, 2,			envPtr);
+		TclEmitInstInt4(INST_LIST_INDEX_IMM, idx,	envPtr);
+		TclEmitOpcode(	INST_STORE_ARRAY_STK,		envPtr);
+		TclEmitOpcode(	INST_POP,			envPtr);
+	    }
+	}
+    }
+
+    /*
+     * Generate code to leave the rest of the list on the stack.
+     */
+
+    TclEmitInstInt4(		INST_LIST_RANGE_IMM, idx,	envPtr);
+    TclEmitInt4(			INDEX_END,		envPtr);
+
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclCompileLindexCmd --
+ *
+ *	Procedure called to compile the "lindex" command.
+ *
+ * Results:
+ *	Returns TCL_OK for a successful compile. Returns TCL_ERROR to defer
+ *	evaluation to runtime.
+ *
+ * Side effects:
+ *	Instructions are added to envPtr to execute the "lindex" command at
+ *	runtime.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclCompileLindexCmd(
+    Tcl_Interp *interp,		/* Used for error reporting. */
+    Tcl_Parse *parsePtr,	/* Points to a parse structure for the command
+				 * created by Tcl_ParseCommand. */
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)		/* Holds resulting instructions. */
+{
+    Tcl_Token *idxTokenPtr, *valTokenPtr;
+    int i, idx, numWords = parsePtr->numWords;
+    DefineLineInformation;	/* TIP #280 */
+
+    /*
+     * Quit if too few args.
+     */
+
+    /* TODO: Consider support for compiling expanded args. */
+    if (numWords <= 1) {
+	return TCL_ERROR;
+    }
+
+    valTokenPtr = TokenAfter(parsePtr->tokenPtr);
+    if (numWords != 3) {
+	goto emitComplexLindex;
+    }
+
+    idxTokenPtr = TokenAfter(valTokenPtr);
+    if (GetIndexFromToken(idxTokenPtr, &idx) == TCL_OK) {
+	/*
+	 * All checks have been completed, and we have exactly one of these
+	 * constructs:
+	 *	 lindex <arbitraryValue> <posInt>
+	 *	 lindex <arbitraryValue> end-<posInt>
+	 * This is best compiled as a push of the arbitrary value followed by
+	 * an "immediate lindex" which is the most efficient variety.
+	 */
+
+	CompileWord(envPtr, valTokenPtr, interp, 1);
+	TclEmitInstInt4(	INST_LIST_INDEX_IMM, idx,	envPtr);
+	return TCL_OK;
+    }
+
+    /*
+     * If the value was not known at compile time, the conversion failed or
+     * the value was negative, we just keep on going with the more complex
+     * compilation.
+     */
+
+    /*
+     * Push the operands onto the stack.
+     */
+
+  emitComplexLindex:
+    for (i=1 ; i<numWords ; i++) {
+	CompileWord(envPtr, valTokenPtr, interp, i);
+	valTokenPtr = TokenAfter(valTokenPtr);
+    }
+
+    /*
+     * Emit INST_LIST_INDEX if objc==3, or INST_LIST_INDEX_MULTI if there are
+     * multiple index args.
+     */
+
+    if (numWords == 3) {
+	TclEmitOpcode(		INST_LIST_INDEX,		envPtr);
+    } else {
+	TclEmitInstInt4(	INST_LIST_INDEX_MULTI, numWords-1, envPtr);
+    }
+
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclCompileListCmd --
+ *
+ *	Procedure called to compile the "list" command.
+ *
+ * Results:
+ *	Returns TCL_OK for a successful compile. Returns TCL_ERROR to defer
+ *	evaluation to runtime.
+ *
+ * Side effects:
+ *	Instructions are added to envPtr to execute the "list" command at
+ *	runtime.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclCompileListCmd(
+    Tcl_Interp *interp,		/* Used for error reporting. */
+    Tcl_Parse *parsePtr,	/* Points to a parse structure for the command
+				 * created by Tcl_ParseCommand. */
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)		/* Holds resulting instructions. */
+{
+    DefineLineInformation;	/* TIP #280 */
+    Tcl_Token *valueTokenPtr;
+    int i, numWords, concat, build;
+    Tcl_Obj *listObj, *objPtr;
+
+    if (parsePtr->numWords == 1) {
+	/*
+	 * [list] without arguments just pushes an empty object.
+	 */
+
+	PushStringLiteral(envPtr, "");
+	return TCL_OK;
+    }
+
+    /*
+     * Test if all arguments are compile-time known. If they are, we can
+     * implement with a simple push.
+     */
+
+    numWords = parsePtr->numWords;
+    valueTokenPtr = TokenAfter(parsePtr->tokenPtr);
+    listObj = Tcl_NewObj();
+    for (i = 1; i < numWords && listObj != NULL; i++) {
+	objPtr = Tcl_NewObj();
+	if (TclWordKnownAtCompileTime(valueTokenPtr, objPtr)) {
+	    (void) Tcl_ListObjAppendElement(NULL, listObj, objPtr);
+	} else {
+	    Tcl_DecrRefCount(objPtr);
+	    Tcl_DecrRefCount(listObj);
+	    listObj = NULL;
+	}
+	valueTokenPtr = TokenAfter(valueTokenPtr);
+    }
+    if (listObj != NULL) {
+	TclEmitPush(TclAddLiteralObj(envPtr, listObj, NULL), envPtr);
+	return TCL_OK;
+    }
+
+    /*
+     * Push the all values onto the stack.
+     */
+
+    numWords = parsePtr->numWords;
+    valueTokenPtr = TokenAfter(parsePtr->tokenPtr);
+    concat = build = 0;
+    for (i = 1; i < numWords; i++) {
+	if (valueTokenPtr->type == TCL_TOKEN_EXPAND_WORD && build > 0) {
+	    TclEmitInstInt4(	INST_LIST, build,	envPtr);
+	    if (concat) {
+		TclEmitOpcode(	INST_LIST_CONCAT,	envPtr);
+	    }
+	    build = 0;
+	    concat = 1;
+	}
+	CompileWord(envPtr, valueTokenPtr, interp, i);
+	if (valueTokenPtr->type == TCL_TOKEN_EXPAND_WORD) {
+	    if (concat) {
+		TclEmitOpcode(	INST_LIST_CONCAT,	envPtr);
+	    } else {
+		concat = 1;
+	    }
+	} else {
+	    build++;
+	}
+	valueTokenPtr = TokenAfter(valueTokenPtr);
+    }
+    if (build > 0) {
+	TclEmitInstInt4(	INST_LIST, build,	envPtr);
+	if (concat) {
+	    TclEmitOpcode(	INST_LIST_CONCAT,	envPtr);
+	}
+    }
+
+    /*
+     * If there was just one expanded word, we must ensure that it is a list
+     * at this point. We use an [lrange ... 0 end] for this (instead of
+     * [llength], as with literals) as we must drop any string representation
+     * that might be hanging around.
+     */
+
+    if (concat && numWords == 2) {
+	TclEmitInstInt4(	INST_LIST_RANGE_IMM, 0,	envPtr);
+	TclEmitInt4(			INDEX_END,	envPtr);
+    }
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclCompileLlengthCmd --
+ *
+ *	Procedure called to compile the "llength" command.
+ *
+ * Results:
+ *	Returns TCL_OK for a successful compile. Returns TCL_ERROR to defer
+ *	evaluation to runtime.
+ *
+ * Side effects:
+ *	Instructions are added to envPtr to execute the "llength" command at
+ *	runtime.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclCompileLlengthCmd(
+    Tcl_Interp *interp,		/* Used for error reporting. */
+    Tcl_Parse *parsePtr,	/* Points to a parse structure for the command
+				 * created by Tcl_ParseCommand. */
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)		/* Holds resulting instructions. */
+{
+    Tcl_Token *varTokenPtr;
+    DefineLineInformation;	/* TIP #280 */
+
+    if (parsePtr->numWords != 2) {
+	return TCL_ERROR;
+    }
+    varTokenPtr = TokenAfter(parsePtr->tokenPtr);
+
+    CompileWord(envPtr, varTokenPtr, interp, 1);
+    TclEmitOpcode(		INST_LIST_LENGTH,		envPtr);
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclCompileLrangeCmd --
+ *
+ *	How to compile the "lrange" command. We only bother because we needed
+ *	the opcode anyway for "lassign".
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclCompileLrangeCmd(
+    Tcl_Interp *interp,		/* Tcl interpreter for context. */
+    Tcl_Parse *parsePtr,	/* Points to a parse structure for the
+				 * command. */
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)		/* Holds the resulting instructions. */
+{
+    Tcl_Token *tokenPtr, *listTokenPtr;
+    DefineLineInformation;	/* TIP #280 */
+    int idx1, idx2;
+
+    if (parsePtr->numWords != 4) {
+	return TCL_ERROR;
+    }
+    listTokenPtr = TokenAfter(parsePtr->tokenPtr);
+
+    /*
+     * Parse the indices. Will only compile if both are constants and not an
+     * _integer_ less than zero (since we reserve negative indices here for
+     * end-relative indexing) or an end-based index greater than 'end' itself.
+     */
+
+    tokenPtr = TokenAfter(listTokenPtr);
+    if (GetIndexFromToken(tokenPtr, &idx1) != TCL_OK) {
+	return TCL_ERROR;
+    }
+
+    tokenPtr = TokenAfter(tokenPtr);
+    if (GetIndexFromToken(tokenPtr, &idx2) != TCL_OK) {
+	return TCL_ERROR;
+    }
+
+    /*
+     * Issue instructions. It's not safe to skip doing the LIST_RANGE, as
+     * we've not proved that the 'list' argument is really a list. Not that it
+     * is worth trying to do that given current knowledge.
+     */
+
+    CompileWord(envPtr, listTokenPtr, interp, 1);
+    TclEmitInstInt4(		INST_LIST_RANGE_IMM, idx1,	envPtr);
+    TclEmitInt4(		idx2,				envPtr);
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclCompileLinsertCmd --
+ *
+ *	How to compile the "linsert" command. We only bother with the case
+ *	where the index is constant.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclCompileLinsertCmd(
+    Tcl_Interp *interp,		/* Tcl interpreter for context. */
+    Tcl_Parse *parsePtr,	/* Points to a parse structure for the
+				 * command. */
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)		/* Holds the resulting instructions. */
+{
+    Tcl_Token *tokenPtr, *listTokenPtr;
+    DefineLineInformation;	/* TIP #280 */
+    int idx, i;
+
+    if (parsePtr->numWords < 3) {
+	return TCL_ERROR;
+    }
+    listTokenPtr = TokenAfter(parsePtr->tokenPtr);
+
+    /*
+     * Parse the index. Will only compile if it is constant and not an
+     * _integer_ less than zero (since we reserve negative indices here for
+     * end-relative indexing) or an end-based index greater than 'end' itself.
+     */
+
+    tokenPtr = TokenAfter(listTokenPtr);
+    if (GetIndexFromToken(tokenPtr, &idx) != TCL_OK) {
+	return TCL_ERROR;
+    }
+
+    /*
+     * There are four main cases. If there are no values to insert, this is
+     * just a confirm-listiness check. If the index is '0', this is a prepend.
+     * If the index is 'end' (== INDEX_END), this is an append. Otherwise,
+     * this is a splice (== split, insert values as list, concat-3).
+     */
+
+    CompileWord(envPtr, listTokenPtr, interp, 1);
+    if (parsePtr->numWords == 3) {
+	TclEmitInstInt4(	INST_LIST_RANGE_IMM, 0,		envPtr);
+	TclEmitInt4(			INDEX_END,		envPtr);
+	return TCL_OK;
+    }
+
+    for (i=3 ; i<parsePtr->numWords ; i++) {
+	tokenPtr = TokenAfter(tokenPtr);
+	CompileWord(envPtr, tokenPtr, interp, i);
+    }
+    TclEmitInstInt4(		INST_LIST, i-3,			envPtr);
+
+    if (idx == 0 /*start*/) {
+	TclEmitInstInt4(	INST_REVERSE, 2,		envPtr);
+	TclEmitOpcode(		INST_LIST_CONCAT,		envPtr);
+    } else if (idx == INDEX_END /*end*/) {
+	TclEmitOpcode(		INST_LIST_CONCAT,		envPtr);
+    } else {
+	if (idx < 0) {
+	    idx++;
+	}
+	TclEmitInstInt4(	INST_OVER, 1,			envPtr);
+	TclEmitInstInt4(	INST_LIST_RANGE_IMM, 0,		envPtr);
+	TclEmitInt4(			idx-1,			envPtr);
+	TclEmitInstInt4(	INST_REVERSE, 3,		envPtr);
+	TclEmitInstInt4(	INST_LIST_RANGE_IMM, idx,	envPtr);
+	TclEmitInt4(			INDEX_END,		envPtr);
+	TclEmitOpcode(		INST_LIST_CONCAT,		envPtr);
+	TclEmitOpcode(		INST_LIST_CONCAT,		envPtr);
+    }
+
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclCompileLreplaceCmd --
+ *
+ *	How to compile the "lreplace" command. We only bother with the case
+ *	where the indices are constant.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclCompileLreplaceCmd(
+    Tcl_Interp *interp,		/* Tcl interpreter for context. */
+    Tcl_Parse *parsePtr,	/* Points to a parse structure for the
+				 * command. */
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)		/* Holds the resulting instructions. */
+{
+    Tcl_Token *tokenPtr, *listTokenPtr;
+    DefineLineInformation;	/* TIP #280 */
+    Tcl_Obj *tmpObj;
+    int idx1, idx2, i, offset, offset2;
+
+    if (parsePtr->numWords < 4) {
+	return TCL_ERROR;
+    }
+    listTokenPtr = TokenAfter(parsePtr->tokenPtr);
+
+    /*
+     * Parse the indices. Will only compile if both are constants and not an
+     * _integer_ less than zero (since we reserve negative indices here for
+     * end-relative indexing) or an end-based index greater than 'end' itself.
+     */
+
+    tokenPtr = TokenAfter(listTokenPtr);
+    if (GetIndexFromToken(tokenPtr, &idx1) != TCL_OK) {
+	return TCL_ERROR;
+    }
+
+    tokenPtr = TokenAfter(tokenPtr);
+    if (GetIndexFromToken(tokenPtr, &idx2) != TCL_OK) {
+	return TCL_ERROR;
+    }
+
+    /*
+     * idx1, idx2 are now in canonical form:
+     *
+     *  - integer:	[0,len+1]
+     *  - end index:    INDEX_END
+     *  - -ive offset:  INDEX_END-[len-1,0]
+     *  - +ive offset:  INDEX_END+1
+     */
+
+    /*
+     * Compilation fails when one index is end-based but the other isn't.
+     * Fixing this will require more bytecodes, but this is a workaround for
+     * now. [Bug 47ac84309b]
+     */
+
+    if ((idx1 <= INDEX_END) != (idx2 <= INDEX_END)) {
+	return TCL_ERROR;
+    }
+
+    if (idx2 != INDEX_END && idx2 >= 0 && idx2 < idx1) {
+	idx2 = idx1 - 1;
+    }
+
+    /*
+     * Work out what this [lreplace] is actually doing.
+     */
+
+    tmpObj = NULL;
+    CompileWord(envPtr, listTokenPtr, interp, 1);
+    if (parsePtr->numWords == 4) {
+	if (idx1 == 0) {
+	    if (idx2 == INDEX_END) {
+		goto dropAll;
+	    }
+	    idx1 = idx2 + 1;
+	    idx2 = INDEX_END;
+	    goto dropEnd;
+	} else if (idx2 == INDEX_END) {
+	    idx2 = idx1 - 1;
+	    idx1 = 0;
+	    goto dropEnd;
+	} else {
+	    if (idx2 < idx1) {
+		idx2 = idx1 - 1;
+	    }
+	    if (idx1 > 0) {
+		tmpObj = Tcl_NewIntObj(idx1);
+		Tcl_IncrRefCount(tmpObj);
+	    }
+	    goto dropRange;
+	}
+    }
+
+    tokenPtr = TokenAfter(tokenPtr);
+    for (i=4 ; i<parsePtr->numWords ; i++) {
+	CompileWord(envPtr, tokenPtr, interp, i);
+	tokenPtr = TokenAfter(tokenPtr);
+    }
+    TclEmitInstInt4(		INST_LIST, i - 4,		envPtr);
+    TclEmitInstInt4(		INST_REVERSE, 2,		envPtr);
+    if (idx1 == 0) {
+	if (idx2 == INDEX_END) {
+	    goto replaceAll;
+	}
+	idx1 = idx2 + 1;
+	idx2 = INDEX_END;
+	goto replaceHead;
+    } else if (idx2 == INDEX_END) {
+	idx2 = idx1 - 1;
+	idx1 = 0;
+	goto replaceTail;
+    } else {
+	if (idx2 < idx1) {
+	    idx2 = idx1 - 1;
+	}
+	if (idx1 > 0) {
+	    tmpObj = Tcl_NewIntObj(idx1);
+	    Tcl_IncrRefCount(tmpObj);
+	}
+	goto replaceRange;
+    }
+
+    /*
+     * Issue instructions to perform the operations relating to configurations
+     * that just drop. The only argument pushed on the stack is the list to
+     * operate on.
+     */
+
+  dropAll:			/* This just ensures the arg is a list. */
+    TclEmitOpcode(		INST_LIST_LENGTH,		envPtr);
+    TclEmitOpcode(		INST_POP,			envPtr);
+    PushStringLiteral(envPtr,	"");
+    goto done;
+
+  dropEnd:
+    TclEmitInstInt4(		INST_LIST_RANGE_IMM, idx1,	envPtr);
+    TclEmitInt4(			idx2,			envPtr);
+    goto done;
+
+  dropRange:
+    if (tmpObj != NULL) {
+	/*
+	 * Emit bytecode to check the list length.
+	 */
+
+	TclEmitOpcode(		INST_DUP,			envPtr);
+	TclEmitOpcode(		INST_LIST_LENGTH,		envPtr);
+	TclEmitPush(TclAddLiteralObj(envPtr, tmpObj, NULL),	envPtr);
+	TclEmitOpcode(		INST_GE,			envPtr);
+	offset = CurrentOffset(envPtr);
+	TclEmitInstInt1(	INST_JUMP_TRUE1, 0,		envPtr);
+
+	/*
+	 * Emit an error if we've been given an empty list.
+	 */
+
+	TclEmitOpcode(		INST_DUP,			envPtr);
+	TclEmitOpcode(		INST_LIST_LENGTH,		envPtr);
+	offset2 = CurrentOffset(envPtr);
+	TclEmitInstInt1(	INST_JUMP_FALSE1, 0,		envPtr);
+	TclEmitPush(TclAddLiteralObj(envPtr, Tcl_ObjPrintf(
+		"list doesn't contain element %d", idx1), NULL), envPtr);
+	CompileReturnInternal(envPtr, INST_RETURN_IMM, TCL_ERROR, 0,
+		Tcl_ObjPrintf("-errorcode {TCL OPERATION LREPLACE BADIDX}"));
+	TclStoreInt1AtPtr(CurrentOffset(envPtr) - offset,
+		envPtr->codeStart + offset + 1);
+	TclStoreInt1AtPtr(CurrentOffset(envPtr) - offset2,
+		envPtr->codeStart + offset2 + 1);
+	TclAdjustStackDepth(-1, envPtr);
+    }
+    TclEmitOpcode(		INST_DUP,			envPtr);
+    TclEmitInstInt4(		INST_LIST_RANGE_IMM, 0,		envPtr);
+    TclEmitInt4(			idx1 - 1,		envPtr);
+    TclEmitInstInt4(		INST_REVERSE, 2,		envPtr);
+    TclEmitInstInt4(		INST_LIST_RANGE_IMM, idx2 + 1,	envPtr);
+    TclEmitInt4(			INDEX_END,		envPtr);
+    TclEmitOpcode(		INST_LIST_CONCAT,		envPtr);
+    goto done;
+
+    /*
+     * Issue instructions to perform the operations relating to configurations
+     * that do real replacement. All arguments are pushed and assembled into a
+     * pair: the list of values to replace with, and the list to do the
+     * surgery on.
+     */
+
+  replaceAll:
+    TclEmitOpcode(		INST_LIST_LENGTH,		envPtr);
+    TclEmitOpcode(		INST_POP,			envPtr);
+    goto done;
+
+  replaceHead:
+    TclEmitInstInt4(		INST_LIST_RANGE_IMM, idx1,	envPtr);
+    TclEmitInt4(			idx2,			envPtr);
+    TclEmitOpcode(		INST_LIST_CONCAT,		envPtr);
+    goto done;
+
+  replaceTail:
+    TclEmitInstInt4(		INST_LIST_RANGE_IMM, idx1,	envPtr);
+    TclEmitInt4(			idx2,			envPtr);
+    TclEmitInstInt4(		INST_REVERSE, 2,		envPtr);
+    TclEmitOpcode(		INST_LIST_CONCAT,		envPtr);
+    goto done;
+
+  replaceRange:
+    if (tmpObj != NULL) {
+	/*
+	 * Emit bytecode to check the list length.
+	 */
+
+	TclEmitOpcode(		INST_DUP,			envPtr);
+	TclEmitOpcode(		INST_LIST_LENGTH,		envPtr);
+
+	/*
+	 * Check the list length vs idx1.
+	 */
+
+	TclEmitPush(TclAddLiteralObj(envPtr, tmpObj, NULL),	envPtr);
+	TclEmitOpcode(		INST_GE,			envPtr);
+	offset = CurrentOffset(envPtr);
+	TclEmitInstInt1(	INST_JUMP_TRUE1, 0,		envPtr);
+
+	/*
+	 * Emit an error if we've been given an empty list.
+	 */
+
+	TclEmitOpcode(		INST_DUP,			envPtr);
+	TclEmitOpcode(		INST_LIST_LENGTH,		envPtr);
+	offset2 = CurrentOffset(envPtr);
+	TclEmitInstInt1(	INST_JUMP_FALSE1, 0,		envPtr);
+	TclEmitPush(TclAddLiteralObj(envPtr, Tcl_ObjPrintf(
+		"list doesn't contain element %d", idx1), NULL), envPtr);
+	CompileReturnInternal(envPtr, INST_RETURN_IMM, TCL_ERROR, 0,
+		Tcl_ObjPrintf("-errorcode {TCL OPERATION LREPLACE BADIDX}"));
+	TclStoreInt1AtPtr(CurrentOffset(envPtr) - offset,
+		envPtr->codeStart + offset + 1);
+	TclStoreInt1AtPtr(CurrentOffset(envPtr) - offset2,
+		envPtr->codeStart + offset2 + 1);
+	TclAdjustStackDepth(-1, envPtr);
+    }
+    TclEmitOpcode(		INST_DUP,			envPtr);
+    TclEmitInstInt4(		INST_LIST_RANGE_IMM, 0,		envPtr);
+    TclEmitInt4(			idx1 - 1,		envPtr);
+    TclEmitInstInt4(		INST_REVERSE, 2,		envPtr);
+    TclEmitInstInt4(		INST_LIST_RANGE_IMM, idx2 + 1,	envPtr);
+    TclEmitInt4(			INDEX_END,		envPtr);
+    TclEmitInstInt4(		INST_REVERSE, 3,		envPtr);
+    TclEmitOpcode(		INST_LIST_CONCAT,		envPtr);
+    TclEmitInstInt4(		INST_REVERSE, 2,		envPtr);
+    TclEmitOpcode(		INST_LIST_CONCAT,		envPtr);
+    goto done;
+
+    /*
+     * Clean up the allocated memory.
+     */
+
+  done:
+    if (tmpObj != NULL) {
+	Tcl_DecrRefCount(tmpObj);
+    }
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclCompileLsetCmd --
+ *
+ *	Procedure called to compile the "lset" command.
+ *
+ * Results:
+ *	Returns TCL_OK for a successful compile. Returns TCL_ERROR to defer
+ *	evaluation to runtime.
+ *
+ * Side effects:
+ *	Instructions are added to envPtr to execute the "lset" command at
+ *	runtime.
+ *
+ * The general template for execution of the "lset" command is:
+ *	(1) Instructions to push the variable name, unless the variable is
+ *	    local to the stack frame.
+ *	(2) If the variable is an array element, instructions to push the
+ *	    array element name.
+ *	(3) Instructions to push each of zero or more "index" arguments to the
+ *	    stack, followed with the "newValue" element.
+ *	(4) Instructions to duplicate the variable name and/or array element
+ *	    name onto the top of the stack, if either was pushed at steps (1)
+ *	    and (2).
+ *	(5) The appropriate INST_LOAD_* instruction to place the original
+ *	    value of the list variable at top of stack.
+ *	(6) At this point, the stack contains:
+ *		varName? arrayElementName? index1 index2 ... newValue oldList
+ *	    The compiler emits one of INST_LSET_FLAT or INST_LSET_LIST
+ *	    according as whether there is exactly one index element (LIST) or
+ *	    either zero or else two or more (FLAT). This instruction removes
+ *	    everything from the stack except for the two names and pushes the
+ *	    new value of the variable.
+ *	(7) Finally, INST_STORE_* stores the new value in the variable and
+ *	    cleans up the stack.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclCompileLsetCmd(
+    Tcl_Interp *interp,		/* Tcl interpreter for error reporting. */
+    Tcl_Parse *parsePtr,	/* Points to a parse structure for the
+				 * command. */
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)		/* Holds the resulting instructions. */
+{
+    int tempDepth;		/* Depth used for emitting one part of the
+				 * code burst. */
+    Tcl_Token *varTokenPtr;	/* Pointer to the Tcl_Token representing the
+				 * parse of the variable name. */
+    int localIndex;		/* Index of var in local var table. */
+    int isScalar;		/* Flag == 1 if scalar, 0 if array. */
+    int i;
+    DefineLineInformation;	/* TIP #280 */
+
+    /*
+     * Check argument count.
+     */
+
+    /* TODO: Consider support for compiling expanded args. */
+    if (parsePtr->numWords < 3) {
+	/*
+	 * Fail at run time, not in compilation.
+	 */
+
+	return TCL_ERROR;
+    }
+
+    /*
+     * Decide if we can use a frame slot for the var/array name or if we need
+     * to emit code to compute and push the name at runtime. We use a frame
+     * slot (entry in the array of local vars) if we are compiling a procedure
+     * body and if the name is simple text that does not include namespace
+     * qualifiers.
+     */
+
+    varTokenPtr = TokenAfter(parsePtr->tokenPtr);
+    PushVarNameWord(interp, varTokenPtr, envPtr, 0,
+	    &localIndex, &isScalar, 1);
+
+    /*
+     * Push the "index" args and the new element value.
+     */
+
+    for (i=2 ; i<parsePtr->numWords ; ++i) {
+	varTokenPtr = TokenAfter(varTokenPtr);
+	CompileWord(envPtr, varTokenPtr, interp, i);
+    }
+
+    /*
+     * Duplicate the variable name if it's been pushed.
+     */
+
+    if (localIndex < 0) {
+	if (isScalar) {
+	    tempDepth = parsePtr->numWords - 2;
+	} else {
+	    tempDepth = parsePtr->numWords - 1;
+	}
+	TclEmitInstInt4(	INST_OVER, tempDepth,		envPtr);
+    }
+
+    /*
+     * Duplicate an array index if one's been pushed.
+     */
+
+    if (!isScalar) {
+	if (localIndex < 0) {
+	    tempDepth = parsePtr->numWords - 1;
+	} else {
+	    tempDepth = parsePtr->numWords - 2;
+	}
+	TclEmitInstInt4(	INST_OVER, tempDepth,		envPtr);
+    }
+
+    /*
+     * Emit code to load the variable's value.
+     */
+
+    if (isScalar) {
+	if (localIndex < 0) {
+	    TclEmitOpcode(	INST_LOAD_STK,			envPtr);
+	} else {
+	    Emit14Inst(		INST_LOAD_SCALAR, localIndex,	envPtr);
+	}
+    } else {
+	if (localIndex < 0) {
+	    TclEmitOpcode(	INST_LOAD_ARRAY_STK,		envPtr);
+	} else {
+	    Emit14Inst(		INST_LOAD_ARRAY, localIndex,	envPtr);
+	}
+    }
+
+    /*
+     * Emit the correct variety of 'lset' instruction.
+     */
+
+    if (parsePtr->numWords == 4) {
+	TclEmitOpcode(		INST_LSET_LIST,			envPtr);
+    } else {
+	TclEmitInstInt4(	INST_LSET_FLAT, parsePtr->numWords-1, envPtr);
+    }
+
+    /*
+     * Emit code to put the value back in the variable.
+     */
+
+    if (isScalar) {
+	if (localIndex < 0) {
+	    TclEmitOpcode(	INST_STORE_STK,			envPtr);
+	} else {
+	    Emit14Inst(		INST_STORE_SCALAR, localIndex,	envPtr);
+	}
+    } else {
+	if (localIndex < 0) {
+	    TclEmitOpcode(	INST_STORE_ARRAY_STK,		envPtr);
+	} else {
+	    Emit14Inst(		INST_STORE_ARRAY, localIndex,	envPtr);
+	}
+    }
+
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclCompileNamespace*Cmd --
+ *
+ *	Procedures called to compile the "namespace" command; currently, only
+ *	the subcommands "namespace current" and "namespace upvar" are compiled
+ *	to bytecodes, and the latter only inside a procedure(-like) context.
+ *
+ * Results:
+ *	Returns TCL_OK for a successful compile. Returns TCL_ERROR to defer
+ *	evaluation to runtime.
+ *
+ * Side effects:
+ *	Instructions are added to envPtr to execute the "namespace upvar"
+ *	command at runtime.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclCompileNamespaceCurrentCmd(
+    Tcl_Interp *interp,		/* Used for error reporting. */
+    Tcl_Parse *parsePtr,	/* Points to a parse structure for the command
+				 * created by Tcl_ParseCommand. */
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)		/* Holds resulting instructions. */
+{
+    /*
+     * Only compile [namespace current] without arguments.
+     */
+
+    if (parsePtr->numWords != 1) {
+	return TCL_ERROR;
+    }
+
+    /*
+     * Not much to do; we compile to a single instruction...
+     */
+
+    TclEmitOpcode(		INST_NS_CURRENT,		envPtr);
+    return TCL_OK;
+}
+
+int
+TclCompileNamespaceCodeCmd(
+    Tcl_Interp *interp,		/* Used for error reporting. */
+    Tcl_Parse *parsePtr,	/* Points to a parse structure for the command
+				 * created by Tcl_ParseCommand. */
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)		/* Holds resulting instructions. */
+{
+    Tcl_Token *tokenPtr;
+    DefineLineInformation;	/* TIP #280 */
+
+    if (parsePtr->numWords != 2) {
+	return TCL_ERROR;
+    }
+    tokenPtr = TokenAfter(parsePtr->tokenPtr);
+
+    /*
+     * The specification of [namespace code] is rather shocking, in that it is
+     * supposed to check if the argument is itself the result of [namespace
+     * code] and not apply itself in that case. Which is excessively cautious,
+     * but what the test suite checks for.
+     */
+
+    if (tokenPtr->type != TCL_TOKEN_SIMPLE_WORD || (tokenPtr[1].size > 20
+	    && strncmp(tokenPtr[1].start, "::namespace inscope ", 20) == 0)) {
+	/*
+	 * Technically, we could just pass a literal '::namespace inscope '
+	 * term through, but that's something which really shouldn't be
+	 * occurring as something that the user writes so we'll just punt it.
+	 */
+
+	return TCL_ERROR;
+    }
+
+    /*
+     * Now we can compile using the same strategy as [namespace code]'s normal
+     * implementation does internally. Note that we can't bind the namespace
+     * name directly here, because TclOO plays complex games with namespaces;
+     * the value needs to be determined at runtime for safety.
+     */
+
+    PushStringLiteral(envPtr,		"::namespace");
+    PushStringLiteral(envPtr,		"inscope");
+    TclEmitOpcode(		INST_NS_CURRENT,	envPtr);
+    CompileWord(envPtr,		tokenPtr,		interp, 1);
+    TclEmitInstInt4(		INST_LIST, 4,		envPtr);
+    return TCL_OK;
+}
+
+int
+TclCompileNamespaceOriginCmd(
+    Tcl_Interp *interp,		/* Used for error reporting. */
+    Tcl_Parse *parsePtr,	/* Points to a parse structure for the command
+				 * created by Tcl_ParseCommand. */
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)		/* Holds resulting instructions. */
+{
+    Tcl_Token *tokenPtr;
+    DefineLineInformation;	/* TIP #280 */
+
+    if (parsePtr->numWords != 2) {
+	return TCL_ERROR;
+    }
+    tokenPtr = TokenAfter(parsePtr->tokenPtr);
+
+    CompileWord(envPtr,	tokenPtr,			interp, 1);
+    TclEmitOpcode(	INST_ORIGIN_COMMAND,		envPtr);
+    return TCL_OK;
+}
+
+int
+TclCompileNamespaceQualifiersCmd(
+    Tcl_Interp *interp,		/* Used for error reporting. */
+    Tcl_Parse *parsePtr,	/* Points to a parse structure for the command
+				 * created by Tcl_ParseCommand. */
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)		/* Holds resulting instructions. */
+{
+    Tcl_Token *tokenPtr = TokenAfter(parsePtr->tokenPtr);
+    DefineLineInformation;	/* TIP #280 */
+    int off;
+
+    if (parsePtr->numWords != 2) {
+	return TCL_ERROR;
+    }
+
+    CompileWord(envPtr, tokenPtr, interp, 1);
+    PushStringLiteral(envPtr, "0");
+    PushStringLiteral(envPtr, "::");
+    TclEmitInstInt4(	INST_OVER, 2,			envPtr);
+    TclEmitOpcode(	INST_STR_FIND_LAST,		envPtr);
+    off = CurrentOffset(envPtr);
+    PushStringLiteral(envPtr, "1");
+    TclEmitOpcode(	INST_SUB,			envPtr);
+    TclEmitInstInt4(	INST_OVER, 2,			envPtr);
+    TclEmitInstInt4(	INST_OVER, 1,			envPtr);
+    TclEmitOpcode(	INST_STR_INDEX,			envPtr);
+    PushStringLiteral(envPtr, ":");
+    TclEmitOpcode(	INST_STR_EQ,			envPtr);
+    off = off - CurrentOffset(envPtr);
+    TclEmitInstInt1(	INST_JUMP_TRUE1, off,		envPtr);
+    TclEmitOpcode(	INST_STR_RANGE,			envPtr);
+    return TCL_OK;
+}
+
+int
+TclCompileNamespaceTailCmd(
+    Tcl_Interp *interp,		/* Used for error reporting. */
+    Tcl_Parse *parsePtr,	/* Points to a parse structure for the command
+				 * created by Tcl_ParseCommand. */
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)		/* Holds resulting instructions. */
+{
+    Tcl_Token *tokenPtr = TokenAfter(parsePtr->tokenPtr);
+    DefineLineInformation;	/* TIP #280 */
+    JumpFixup jumpFixup;
+
+    if (parsePtr->numWords != 2) {
+	return TCL_ERROR;
+    }
+
+    /*
+     * Take care; only add 2 to found index if the string was actually found.
+     */
+
+    CompileWord(envPtr, tokenPtr, interp, 1);
+    PushStringLiteral(envPtr, "::");
+    TclEmitInstInt4(	INST_OVER, 1,			envPtr);
+    TclEmitOpcode(	INST_STR_FIND_LAST,		envPtr);
+    TclEmitOpcode(	INST_DUP,			envPtr);
+    PushStringLiteral(envPtr, "0");
+    TclEmitOpcode(	INST_GE,			envPtr);
+    TclEmitForwardJump(envPtr, TCL_FALSE_JUMP, &jumpFixup);
+    PushStringLiteral(envPtr, "2");
+    TclEmitOpcode(	INST_ADD,			envPtr);
+    TclFixupForwardJumpToHere(envPtr, &jumpFixup, 127);
+    PushStringLiteral(envPtr, "end");
+    TclEmitOpcode(	INST_STR_RANGE,			envPtr);
+    return TCL_OK;
+}
+
+int
+TclCompileNamespaceUpvarCmd(
+    Tcl_Interp *interp,		/* Used for error reporting. */
+    Tcl_Parse *parsePtr,	/* Points to a parse structure for the command
+				 * created by Tcl_ParseCommand. */
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)		/* Holds resulting instructions. */
+{
+    Tcl_Token *tokenPtr, *otherTokenPtr, *localTokenPtr;
+    int localIndex, numWords, i;
+    DefineLineInformation;	/* TIP #280 */
+
+    if (envPtr->procPtr == NULL) {
+	return TCL_ERROR;
+    }
+
+    /*
+     * Only compile [namespace upvar ...]: needs an even number of args, >=4
+     */
+
+    numWords = parsePtr->numWords;
+    if ((numWords % 2) || (numWords < 4)) {
+	return TCL_ERROR;
+    }
+
+    /*
+     * Push the namespace
+     */
+
+    tokenPtr = TokenAfter(parsePtr->tokenPtr);
+    CompileWord(envPtr, tokenPtr, interp, 1);
+
+    /*
+     * Loop over the (otherVar, thisVar) pairs. If any of the thisVar is not a
+     * local variable, return an error so that the non-compiled command will
+     * be called at runtime.
+     */
+
+    localTokenPtr = tokenPtr;
+    for (i=2; i<numWords; i+=2) {
+	otherTokenPtr = TokenAfter(localTokenPtr);
+	localTokenPtr = TokenAfter(otherTokenPtr);
+
+	CompileWord(envPtr, otherTokenPtr, interp, i);
+	localIndex = LocalScalarFromToken(localTokenPtr, envPtr);
+	if (localIndex < 0) {
+	    return TCL_ERROR;
+	}
+	TclEmitInstInt4(	INST_NSUPVAR, localIndex,	envPtr);
+    }
+
+    /*
+     * Pop the namespace, and set the result to empty
+     */
+
+    TclEmitOpcode(		INST_POP,			envPtr);
+    PushStringLiteral(envPtr, "");
+    return TCL_OK;
+}
+
+int
+TclCompileNamespaceWhichCmd(
+    Tcl_Interp *interp,		/* Used for error reporting. */
+    Tcl_Parse *parsePtr,	/* Points to a parse structure for the command
+				 * created by Tcl_ParseCommand. */
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)		/* Holds resulting instructions. */
+{
+    DefineLineInformation;	/* TIP #280 */
+    Tcl_Token *tokenPtr, *opt;
+    int idx;
+
+    if (parsePtr->numWords < 2 || parsePtr->numWords > 3) {
+	return TCL_ERROR;
+    }
+    tokenPtr = TokenAfter(parsePtr->tokenPtr);
+    idx = 1;
+
+    /*
+     * If there's an option, check that it's "-command". We don't handle
+     * "-variable" (currently) and anything else is an error.
+     */
+
+    if (parsePtr->numWords == 3) {
+	if (tokenPtr->type != TCL_TOKEN_SIMPLE_WORD) {
+	    return TCL_ERROR;
+	}
+	opt = tokenPtr + 1;
+	if (opt->size < 2 || opt->size > 8
+		|| strncmp(opt->start, "-command", opt->size) != 0) {
+	    return TCL_ERROR;
+	}
+	tokenPtr = TokenAfter(tokenPtr);
+	idx++;
+    }
+
+    /*
+     * Issue the bytecode.
+     */
+
+    CompileWord(envPtr,		tokenPtr,		interp, idx);
+    TclEmitOpcode(		INST_RESOLVE_COMMAND,	envPtr);
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclCompileRegexpCmd --
+ *
+ *	Procedure called to compile the "regexp" command.
+ *
+ * Results:
+ *	Returns TCL_OK for a successful compile. Returns TCL_ERROR to defer
+ *	evaluation to runtime.
+ *
+ * Side effects:
+ *	Instructions are added to envPtr to execute the "regexp" command at
+ *	runtime.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclCompileRegexpCmd(
+    Tcl_Interp *interp,		/* Tcl interpreter for error reporting. */
+    Tcl_Parse *parsePtr,	/* Points to a parse structure for the
+				 * command. */
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)		/* Holds the resulting instructions. */
+{
+    Tcl_Token *varTokenPtr;	/* Pointer to the Tcl_Token representing the
+				 * parse of the RE or string. */
+    int i, len, nocase, exact, sawLast, simple;
+    const char *str;
+    DefineLineInformation;	/* TIP #280 */
+
+    /*
+     * We are only interested in compiling simple regexp cases. Currently
+     * supported compile cases are:
+     *   regexp ?-nocase? ?--? staticString $var
+     *   regexp ?-nocase? ?--? {^staticString$} $var
+     */
+
+    if (parsePtr->numWords < 3) {
+	return TCL_ERROR;
+    }
+
+    simple = 0;
+    nocase = 0;
+    sawLast = 0;
+    varTokenPtr = parsePtr->tokenPtr;
+
+    /*
+     * We only look for -nocase and -- as options. Everything else gets pushed
+     * to runtime execution. This is different than regexp's runtime option
+     * handling, but satisfies our stricter needs.
+     */
+
+    for (i = 1; i < parsePtr->numWords - 2; i++) {
+	varTokenPtr = TokenAfter(varTokenPtr);
+	if (varTokenPtr->type != TCL_TOKEN_SIMPLE_WORD) {
+	    /*
+	     * Not a simple string, so punt to runtime.
+	     */
+
+	    return TCL_ERROR;
+	}
+	str = varTokenPtr[1].start;
+	len = varTokenPtr[1].size;
+	if ((len == 2) && (str[0] == '-') && (str[1] == '-')) {
+	    sawLast++;
+	    i++;
+	    break;
+	} else if ((len > 1) && (strncmp(str,"-nocase",(unsigned)len) == 0)) {
+	    nocase = 1;
+	} else {
+	    /*
+	     * Not an option we recognize.
+	     */
+
+	    return TCL_ERROR;
+	}
+    }
+
+    if ((parsePtr->numWords - i) != 2) {
+	/*
+	 * We don't support capturing to variables.
+	 */
+
+	return TCL_ERROR;
+    }
+
+    /*
+     * Get the regexp string. If it is not a simple string or can't be
+     * converted to a glob pattern, push the word for the INST_REGEXP.
+     * Keep changes here in sync with TclCompileSwitchCmd Switch_Regexp.
+     */
+
+    varTokenPtr = TokenAfter(varTokenPtr);
+
+    if (varTokenPtr->type == TCL_TOKEN_SIMPLE_WORD) {
+	Tcl_DString ds;
+
+	str = varTokenPtr[1].start;
+	len = varTokenPtr[1].size;
+
+	/*
+	 * If it has a '-', it could be an incorrectly formed regexp command.
+	 */
+
+	if ((*str == '-') && !sawLast) {
+	    return TCL_ERROR;
+	}
+
+	if (len == 0) {
+	    /*
+	     * The semantics of regexp are always match on re == "".
+	     */
+
+	    PushStringLiteral(envPtr, "1");
+	    return TCL_OK;
+	}
+
+	/*
+	 * Attempt to convert pattern to glob.  If successful, push the
+	 * converted pattern as a literal.
+	 */
+
+	if (TclReToGlob(NULL, varTokenPtr[1].start, len, &ds, &exact, NULL)
+		== TCL_OK) {
+	    simple = 1;
+	    PushLiteral(envPtr, Tcl_DStringValue(&ds),Tcl_DStringLength(&ds));
+	    Tcl_DStringFree(&ds);
+	}
+    }
+
+    if (!simple) {
+	CompileWord(envPtr, varTokenPtr, interp, parsePtr->numWords-2);
+    }
+
+    /*
+     * Push the string arg.
+     */
+
+    varTokenPtr = TokenAfter(varTokenPtr);
+    CompileWord(envPtr, varTokenPtr, interp, parsePtr->numWords-1);
+
+    if (simple) {
+	if (exact && !nocase) {
+	    TclEmitOpcode(	INST_STR_EQ,			envPtr);
+	} else {
+	    TclEmitInstInt1(	INST_STR_MATCH, nocase,		envPtr);
+	}
+    } else {
+	/*
+	 * Pass correct RE compile flags.  We use only Int1 (8-bit), but
+	 * that handles all the flags we want to pass.
+	 * Don't use TCL_REG_NOSUB as we may have backrefs.
+	 */
+
+	int cflags = TCL_REG_ADVANCED | (nocase ? TCL_REG_NOCASE : 0);
+
+	TclEmitInstInt1(	INST_REGEXP, cflags,		envPtr);
+    }
+
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclCompileRegsubCmd --
+ *
+ *	Procedure called to compile the "regsub" command.
+ *
+ * Results:
+ *	Returns TCL_OK for a successful compile. Returns TCL_ERROR to defer
+ *	evaluation to runtime.
+ *
+ * Side effects:
+ *	Instructions are added to envPtr to execute the "regsub" command at
+ *	runtime.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclCompileRegsubCmd(
+    Tcl_Interp *interp,		/* Tcl interpreter for error reporting. */
+    Tcl_Parse *parsePtr,	/* Points to a parse structure for the
+				 * command. */
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)		/* Holds the resulting instructions. */
+{
+    /*
+     * We only compile the case with [regsub -all] where the pattern is both
+     * known at compile time and simple (i.e., no RE metacharacters). That is,
+     * the pattern must be translatable into a glob like "*foo*" with no other
+     * glob metacharacters inside it; there must be some "foo" in there too.
+     * The substitution string must also be known at compile time and free of
+     * metacharacters ("\digit" and "&"). Finally, there must not be a
+     * variable mentioned in the [regsub] to write the result back to (because
+     * we can't get the count of substitutions that would be the result in
+     * that case). The key is that these are the conditions under which a
+     * [string map] could be used instead, in particular a [string map] of the
+     * form we can compile to bytecode.
+     *
+     * In short, we look for:
+     *
+     *   regsub -all [--] simpleRE string simpleReplacement
+     *
+     * The only optional part is the "--", and no other options are handled.
+     */
+
+    DefineLineInformation;	/* TIP #280 */
+    Tcl_Token *tokenPtr, *stringTokenPtr;
+    Tcl_Obj *patternObj = NULL, *replacementObj = NULL;
+    Tcl_DString pattern;
+    const char *bytes;
+    int len, exact, quantified, result = TCL_ERROR;
+
+    if (parsePtr->numWords < 5 || parsePtr->numWords > 6) {
+	return TCL_ERROR;
+    }
+
+    /*
+     * Parse the "-all", which must be the first argument (other options not
+     * supported, non-"-all" substitution we can't compile).
+     */
+
+    tokenPtr = TokenAfter(parsePtr->tokenPtr);
+    if (tokenPtr->type != TCL_TOKEN_SIMPLE_WORD || tokenPtr[1].size != 4
+	    || strncmp(tokenPtr[1].start, "-all", 4)) {
+	return TCL_ERROR;
+    }
+
+    /*
+     * Get the pattern into patternObj, checking for "--" in the process.
+     */
+
+    Tcl_DStringInit(&pattern);
+    tokenPtr = TokenAfter(tokenPtr);
+    patternObj = Tcl_NewObj();
+    if (!TclWordKnownAtCompileTime(tokenPtr, patternObj)) {
+	goto done;
+    }
+    if (Tcl_GetString(patternObj)[0] == '-') {
+	if (strcmp(Tcl_GetString(patternObj), "--") != 0
+		|| parsePtr->numWords == 5) {
+	    goto done;
+	}
+	tokenPtr = TokenAfter(tokenPtr);
+	Tcl_DecrRefCount(patternObj);
+	patternObj = Tcl_NewObj();
+	if (!TclWordKnownAtCompileTime(tokenPtr, patternObj)) {
+	    goto done;
+	}
+    } else if (parsePtr->numWords == 6) {
+	goto done;
+    }
+
+    /*
+     * Identify the code which produces the string to apply the substitution
+     * to (stringTokenPtr), and the replacement string (into replacementObj).
+     */
+
+    stringTokenPtr = TokenAfter(tokenPtr);
+    tokenPtr = TokenAfter(stringTokenPtr);
+    replacementObj = Tcl_NewObj();
+    if (!TclWordKnownAtCompileTime(tokenPtr, replacementObj)) {
+	goto done;
+    }
+
+    /*
+     * Next, higher-level checks. Is the RE a very simple glob? Is the
+     * replacement "simple"?
+     */
+
+    bytes = Tcl_GetStringFromObj(patternObj, &len);
+    if (TclReToGlob(NULL, bytes, len, &pattern, &exact, &quantified)
+	    != TCL_OK || exact || quantified) {
+	goto done;
+    }
+    bytes = Tcl_DStringValue(&pattern);
+    if (*bytes++ != '*') {
+	goto done;
+    }
+    while (1) {
+	switch (*bytes) {
+	case '*':
+	    if (bytes[1] == '\0') {
+		/*
+		 * OK, we've proved there are no metacharacters except for the
+		 * '*' at each end.
+		 */
+
+		len = Tcl_DStringLength(&pattern) - 2;
+		if (len > 0) {
+		    goto isSimpleGlob;
+		}
+
+		/*
+		 * The pattern is "**"! I believe that should be impossible,
+		 * but we definitely can't handle that at all.
+		 */
+	    }
+	case '\0': case '?': case '[': case '\\':
+	    goto done;
+	}
+	bytes++;
+    }
+  isSimpleGlob:
+    for (bytes = Tcl_GetString(replacementObj); *bytes; bytes++) {
+	switch (*bytes) {
+	case '\\': case '&':
+	    goto done;
+	}
+    }
+
+    /*
+     * Proved the simplicity constraints! Time to issue the code.
+     */
+
+    result = TCL_OK;
+    bytes = Tcl_DStringValue(&pattern) + 1;
+    PushLiteral(envPtr,	bytes, len);
+    bytes = Tcl_GetStringFromObj(replacementObj, &len);
+    PushLiteral(envPtr,	bytes, len);
+    CompileWord(envPtr,	stringTokenPtr, interp, parsePtr->numWords-2);
+    TclEmitOpcode(	INST_STR_MAP,	envPtr);
+
+  done:
+    Tcl_DStringFree(&pattern);
+    if (patternObj) {
+	Tcl_DecrRefCount(patternObj);
+    }
+    if (replacementObj) {
+	Tcl_DecrRefCount(replacementObj);
+    }
+    return result;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclCompileReturnCmd --
+ *
+ *	Procedure called to compile the "return" command.
+ *
+ * Results:
+ *	Returns TCL_OK for a successful compile. Returns TCL_ERROR to defer
+ *	evaluation to runtime.
+ *
+ * Side effects:
+ *	Instructions are added to envPtr to execute the "return" command at
+ *	runtime.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclCompileReturnCmd(
+    Tcl_Interp *interp,		/* Used for error reporting. */
+    Tcl_Parse *parsePtr,	/* Points to a parse structure for the command
+				 * created by Tcl_ParseCommand. */
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)		/* Holds resulting instructions. */
+{
+    /*
+     * General syntax: [return ?-option value ...? ?result?]
+     * An even number of words means an explicit result argument is present.
+     */
+    int level, code, objc, size, status = TCL_OK;
+    int numWords = parsePtr->numWords;
+    int explicitResult = (0 == (numWords % 2));
+    int numOptionWords = numWords - 1 - explicitResult;
+    Tcl_Obj *returnOpts, **objv;
+    Tcl_Token *wordTokenPtr = TokenAfter(parsePtr->tokenPtr);
+    DefineLineInformation;	/* TIP #280 */
+
+    /*
+     * Check for special case which can always be compiled:
+     *	    return -options <opts> <msg>
+     * Unlike the normal [return] compilation, this version does everything at
+     * runtime so it can handle arbitrary words and not just literals. Note
+     * that if INST_RETURN_STK wasn't already needed for something else
+     * ('finally' clause processing) this piece of code would not be present.
+     */
+
+    if ((numWords == 4) && (wordTokenPtr->type == TCL_TOKEN_SIMPLE_WORD)
+	    && (wordTokenPtr[1].size == 8)
+	    && (strncmp(wordTokenPtr[1].start, "-options", 8) == 0)) {
+	Tcl_Token *optsTokenPtr = TokenAfter(wordTokenPtr);
+	Tcl_Token *msgTokenPtr = TokenAfter(optsTokenPtr);
+
+	CompileWord(envPtr, optsTokenPtr, interp, 2);
+	CompileWord(envPtr, msgTokenPtr,  interp, 3);
+	TclEmitInvoke(envPtr, INST_RETURN_STK);
+	return TCL_OK;
+    }
+
+    /*
+     * Allocate some working space.
+     */
+
+    objv = TclStackAlloc(interp, numOptionWords * sizeof(Tcl_Obj *));
+
+    /*
+     * Scan through the return options. If any are unknown at compile time,
+     * there is no value in bytecompiling. Save the option values known in an
+     * objv array for merging into a return options dictionary.
+     *
+     * TODO: There is potential for improvement if all option keys are known
+     * at compile time and all option values relating to '-code' and '-level'
+     * are known at compile time.
+     */
+
+    for (objc = 0; objc < numOptionWords; objc++) {
+	objv[objc] = Tcl_NewObj();
+	Tcl_IncrRefCount(objv[objc]);
+	if (!TclWordKnownAtCompileTime(wordTokenPtr, objv[objc])) {
+	    /*
+	     * Non-literal, so punt to run-time assembly of the dictionary.
+	     */
+
+	    for (; objc>=0 ; objc--) {
+		TclDecrRefCount(objv[objc]);
+	    }
+	    TclStackFree(interp, objv);
+	    goto issueRuntimeReturn;
+	}
+	wordTokenPtr = TokenAfter(wordTokenPtr);
+    }
+    status = TclMergeReturnOptions(interp, objc, objv,
+	    &returnOpts, &code, &level);
+    while (--objc >= 0) {
+	TclDecrRefCount(objv[objc]);
+    }
+    TclStackFree(interp, objv);
+    if (TCL_ERROR == status) {
+	/*
+	 * Something was bogus in the return options. Clear the error message,
+	 * and report back to the compiler that this must be interpreted at
+	 * runtime.
+	 */
+
+	Tcl_ResetResult(interp);
+	return TCL_ERROR;
+    }
+
+    /*
+     * All options are known at compile time, so we're going to bytecompile.
+     * Emit instructions to push the result on the stack.
+     */
+
+    if (explicitResult) {
+	 CompileWord(envPtr, wordTokenPtr, interp, numWords-1);
+    } else {
+	/*
+	 * No explict result argument, so default result is empty string.
+	 */
+
+	PushStringLiteral(envPtr, "");
+    }
+
+    /*
+     * Check for optimization: When [return] is in a proc, and there's no
+     * enclosing [catch], and there are no return options, then the INST_DONE
+     * instruction is equivalent, and may be more efficient.
+     */
+
+    if (numOptionWords == 0 && envPtr->procPtr != NULL) {
+	/*
+	 * We have default return options and we're in a proc ...
+	 */
+
+	int index = envPtr->exceptArrayNext - 1;
+	int enclosingCatch = 0;
+
+	while (index >= 0) {
+	    ExceptionRange range = envPtr->exceptArrayPtr[index];
+
+	    if ((range.type == CATCH_EXCEPTION_RANGE)
+		    && (range.catchOffset == -1)) {
+		enclosingCatch = 1;
+		break;
+	    }
+	    index--;
+	}
+	if (!enclosingCatch) {
+	    /*
+	     * ... and there is no enclosing catch. Issue the maximally
+	     * efficient exit instruction.
+	     */
+
+	    Tcl_DecrRefCount(returnOpts);
+	    TclEmitOpcode(INST_DONE, envPtr);
+	    TclAdjustStackDepth(1, envPtr);
+	    return TCL_OK;
+	}
+    }
+
+    /* Optimize [return -level 0 $x]. */
+    Tcl_DictObjSize(NULL, returnOpts, &size);
+    if (size == 0 && level == 0 && code == TCL_OK) {
+	Tcl_DecrRefCount(returnOpts);
+	return TCL_OK;
+    }
+
+    /*
+     * Could not use the optimization, so we push the return options dict, and
+     * emit the INST_RETURN_IMM instruction with code and level as operands.
+     */
+
+    CompileReturnInternal(envPtr, INST_RETURN_IMM, code, level, returnOpts);
+    return TCL_OK;
+
+  issueRuntimeReturn:
+    /*
+     * Assemble the option dictionary (as a list as that's good enough).
+     */
+
+    wordTokenPtr = TokenAfter(parsePtr->tokenPtr);
+    for (objc=1 ; objc<=numOptionWords ; objc++) {
+	CompileWord(envPtr, wordTokenPtr, interp, objc);
+	wordTokenPtr = TokenAfter(wordTokenPtr);
+    }
+    TclEmitInstInt4(INST_LIST, numOptionWords, envPtr);
+
+    /*
+     * Push the result.
+     */
+
+    if (explicitResult) {
+	CompileWord(envPtr, wordTokenPtr, interp, numWords-1);
+    } else {
+	PushStringLiteral(envPtr, "");
+    }
+
+    /*
+     * Issue the RETURN itself.
+     */
+
+    TclEmitInvoke(envPtr, INST_RETURN_STK);
+    return TCL_OK;
+}
+
+static void
+CompileReturnInternal(
+    CompileEnv *envPtr,
+    unsigned char op,
+    int code,
+    int level,
+    Tcl_Obj *returnOpts)
+{
+    if (level == 0 && (code == TCL_BREAK || code == TCL_CONTINUE)) {
+	ExceptionRange *rangePtr;
+	ExceptionAux *exceptAux;
+
+	rangePtr = TclGetInnermostExceptionRange(envPtr, code, &exceptAux);
+	if (rangePtr && rangePtr->type == LOOP_EXCEPTION_RANGE) {
+	    TclCleanupStackForBreakContinue(envPtr, exceptAux);
+	    if (code == TCL_BREAK) {
+		TclAddLoopBreakFixup(envPtr, exceptAux);
+	    } else {
+		TclAddLoopContinueFixup(envPtr, exceptAux);
+	    }
+	    Tcl_DecrRefCount(returnOpts);
+	    return;
+	}
+    }
+
+    TclEmitPush(TclAddLiteralObj(envPtr, returnOpts, NULL), envPtr);
+    TclEmitInstInt4(op, code, envPtr);
+    TclEmitInt4(level, envPtr);
+}
+
+void
+TclCompileSyntaxError(
+    Tcl_Interp *interp,
+    CompileEnv *envPtr)
+{
+    Tcl_Obj *msg = Tcl_GetObjResult(interp);
+    int numBytes;
+    const char *bytes = TclGetStringFromObj(msg, &numBytes);
+
+    TclErrorStackResetIf(interp, bytes, numBytes);
+    TclEmitPush(TclRegisterNewLiteral(envPtr, bytes, numBytes), envPtr);
+    CompileReturnInternal(envPtr, INST_SYNTAX, TCL_ERROR, 0,
+	    TclNoErrorStack(interp, Tcl_GetReturnOptions(interp, TCL_ERROR)));
+    Tcl_ResetResult(interp);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclCompileUpvarCmd --
+ *
+ *	Procedure called to compile the "upvar" command.
+ *
+ * Results:
+ *	Returns TCL_OK for a successful compile. Returns TCL_ERROR to defer
+ *	evaluation to runtime.
+ *
+ * Side effects:
+ *	Instructions are added to envPtr to execute the "upvar" command at
+ *	runtime.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclCompileUpvarCmd(
+    Tcl_Interp *interp,		/* Used for error reporting. */
+    Tcl_Parse *parsePtr,	/* Points to a parse structure for the command
+				 * created by Tcl_ParseCommand. */
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)		/* Holds resulting instructions. */
+{
+    Tcl_Token *tokenPtr, *otherTokenPtr, *localTokenPtr;
+    int localIndex, numWords, i;
+    DefineLineInformation;	/* TIP #280 */
+    Tcl_Obj *objPtr;
+
+    if (envPtr->procPtr == NULL) {
+	return TCL_ERROR;
+    }
+
+    numWords = parsePtr->numWords;
+    if (numWords < 3) {
+	return TCL_ERROR;
+    }
+
+    /*
+     * Push the frame index if it is known at compile time
+     */
+
+    objPtr = Tcl_NewObj();
+    tokenPtr = TokenAfter(parsePtr->tokenPtr);
+    if (TclWordKnownAtCompileTime(tokenPtr, objPtr)) {
+	CallFrame *framePtr;
+	const Tcl_ObjType *newTypePtr, *typePtr = objPtr->typePtr;
+
+	/*
+	 * Attempt to convert to a level reference. Note that TclObjGetFrame
+	 * only changes the obj type when a conversion was successful.
+	 */
+
+	TclObjGetFrame(interp, objPtr, &framePtr);
+	newTypePtr = objPtr->typePtr;
+	Tcl_DecrRefCount(objPtr);
+
+	if (newTypePtr != typePtr) {
+	    if (numWords%2) {
+		return TCL_ERROR;
+	    }
+	    /* TODO: Push the known value instead? */
+	    CompileWord(envPtr, tokenPtr, interp, 1);
+	    otherTokenPtr = TokenAfter(tokenPtr);
+	    i = 2;
+	} else {
+	    if (!(numWords%2)) {
+		return TCL_ERROR;
+	    }
+	    PushStringLiteral(envPtr, "1");
+	    otherTokenPtr = tokenPtr;
+	    i = 1;
+	}
+    } else {
+	Tcl_DecrRefCount(objPtr);
+	return TCL_ERROR;
+    }
+
+    /*
+     * Loop over the (otherVar, thisVar) pairs. If any of the thisVar is not a
+     * local variable, return an error so that the non-compiled command will
+     * be called at runtime.
+     */
+
+    for (; i<numWords; i+=2, otherTokenPtr = TokenAfter(localTokenPtr)) {
+	localTokenPtr = TokenAfter(otherTokenPtr);
+
+	CompileWord(envPtr, otherTokenPtr, interp, i);
+	localIndex = LocalScalarFromToken(localTokenPtr, envPtr);
+	if (localIndex < 0) {
+	    return TCL_ERROR;
+	}
+	TclEmitInstInt4(	INST_UPVAR, localIndex,		envPtr);
+    }
+
+    /*
+     * Pop the frame index, and set the result to empty
+     */
+
+    TclEmitOpcode(		INST_POP,			envPtr);
+    PushStringLiteral(envPtr, "");
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclCompileVariableCmd --
+ *
+ *	Procedure called to compile the "variable" command.
+ *
+ * Results:
+ *	Returns TCL_OK for a successful compile. Returns TCL_ERROR to defer
+ *	evaluation to runtime.
+ *
+ * Side effects:
+ *	Instructions are added to envPtr to execute the "variable" command at
+ *	runtime.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclCompileVariableCmd(
+    Tcl_Interp *interp,		/* Used for error reporting. */
+    Tcl_Parse *parsePtr,	/* Points to a parse structure for the command
+				 * created by Tcl_ParseCommand. */
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)		/* Holds resulting instructions. */
+{
+    Tcl_Token *varTokenPtr, *valueTokenPtr;
+    int localIndex, numWords, i;
+    DefineLineInformation;	/* TIP #280 */
+
+    numWords = parsePtr->numWords;
+    if (numWords < 2) {
+	return TCL_ERROR;
+    }
+
+    /*
+     * Bail out if not compiling a proc body
+     */
+
+    if (envPtr->procPtr == NULL) {
+	return TCL_ERROR;
+    }
+
+    /*
+     * Loop over the (var, value) pairs.
+     */
+
+    valueTokenPtr = parsePtr->tokenPtr;
+    for (i=1; i<numWords; i+=2) {
+	varTokenPtr = TokenAfter(valueTokenPtr);
+	valueTokenPtr = TokenAfter(varTokenPtr);
+
+	localIndex = IndexTailVarIfKnown(interp, varTokenPtr, envPtr);
+
+	if (localIndex < 0) {
+	    return TCL_ERROR;
+	}
+
+	/* TODO: Consider what value can pass throug the
+	 * IndexTailVarIfKnown() screen.  Full CompileWord()
+	 * likely does not apply here.  Push known value instead. */
+	CompileWord(envPtr, varTokenPtr, interp, i);
+	TclEmitInstInt4(	INST_VARIABLE, localIndex,	envPtr);
+
+	if (i+1 < numWords) {
+	    /*
+	     * A value has been given: set the variable, pop the value
+	     */
+
+	    CompileWord(envPtr, valueTokenPtr, interp, i+1);
+	    Emit14Inst(		INST_STORE_SCALAR, localIndex,	envPtr);
+	    TclEmitOpcode(	INST_POP,			envPtr);
+	}
+    }
+
+    /*
+     * Set the result to empty
+     */
+
+    PushStringLiteral(envPtr, "");
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * IndexTailVarIfKnown --
+ *
+ *	Procedure used in compiling [global] and [variable] commands. It
+ *	inspects the variable name described by varTokenPtr and, if the tail
+ *	is known at compile time, defines a corresponding local variable.
+ *
+ * Results:
+ *	Returns the variable's index in the table of compiled locals if the
+ *	tail is known at compile time, or -1 otherwise.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+IndexTailVarIfKnown(
+    Tcl_Interp *interp,
+    Tcl_Token *varTokenPtr,	/* Token representing the variable name */
+    CompileEnv *envPtr)		/* Holds resulting instructions. */
+{
+    Tcl_Obj *tailPtr;
+    const char *tailName, *p;
+    int len, n = varTokenPtr->numComponents;
+    Tcl_Token *lastTokenPtr;
+    int full, localIndex;
+
+    /*
+     * Determine if the tail is (a) known at compile time, and (b) not an
+     * array element. Should any of these fail, return an error so that the
+     * non-compiled command will be called at runtime.
+     *
+     * In order for the tail to be known at compile time, the last token in
+     * the word has to be constant and contain "::" if it is not the only one.
+     */
+
+    if (!EnvHasLVT(envPtr)) {
+	return -1;
+    }
+
+    TclNewObj(tailPtr);
+    if (TclWordKnownAtCompileTime(varTokenPtr, tailPtr)) {
+	full = 1;
+	lastTokenPtr = varTokenPtr;
+    } else {
+	full = 0;
+	lastTokenPtr = varTokenPtr + n;
+
+	if (lastTokenPtr->type != TCL_TOKEN_TEXT) {
+	    Tcl_DecrRefCount(tailPtr);
+	    return -1;
+	}
+	Tcl_SetStringObj(tailPtr, lastTokenPtr->start, lastTokenPtr->size);
+    }
+
+    tailName = TclGetStringFromObj(tailPtr, &len);
+
+    if (len) {
+	if (*(tailName+len-1) == ')') {
+	    /*
+	     * Possible array: bail out
+	     */
+
+	    Tcl_DecrRefCount(tailPtr);
+	    return -1;
+	}
+
+	/*
+	 * Get the tail: immediately after the last '::'
+	 */
+
+	for (p = tailName + len -1; p > tailName; p--) {
+	    if ((*p == ':') && (*(p-1) == ':')) {
+		p++;
+		break;
+	    }
+	}
+	if (!full && (p == tailName)) {
+	    /*
+	     * No :: in the last component.
+	     */
+
+	    Tcl_DecrRefCount(tailPtr);
+	    return -1;
+	}
+	len -= p - tailName;
+	tailName = p;
+    }
+
+    localIndex = TclFindCompiledLocal(tailName, len, 1, envPtr);
+    Tcl_DecrRefCount(tailPtr);
+    return localIndex;
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * TclCompileObjectNextCmd, TclCompileObjectSelfCmd --
+ *
+ *	Compilations of the TclOO utility commands [next] and [self].
+ *
+ * ----------------------------------------------------------------------
+ */
+
+int
+TclCompileObjectNextCmd(
+    Tcl_Interp *interp,		/* Used for error reporting. */
+    Tcl_Parse *parsePtr,	/* Points to a parse structure for the command
+				 * created by Tcl_ParseCommand. */
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)		/* Holds resulting instructions. */
+{
+    DefineLineInformation;	/* TIP #280 */
+    Tcl_Token *tokenPtr = parsePtr->tokenPtr;
+    int i;
+
+    if (parsePtr->numWords > 255) {
+	return TCL_ERROR;
+    }
+
+    for (i=0 ; i<parsePtr->numWords ; i++) {
+	CompileWord(envPtr, tokenPtr, interp, i);
+	tokenPtr = TokenAfter(tokenPtr);
+    }
+    TclEmitInstInt1(	INST_TCLOO_NEXT, i,		envPtr);
+    return TCL_OK;
+}
+
+int
+TclCompileObjectNextToCmd(
+    Tcl_Interp *interp,		/* Used for error reporting. */
+    Tcl_Parse *parsePtr,	/* Points to a parse structure for the command
+				 * created by Tcl_ParseCommand. */
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)		/* Holds resulting instructions. */
+{
+    DefineLineInformation;	/* TIP #280 */
+    Tcl_Token *tokenPtr = parsePtr->tokenPtr;
+    int i;
+
+    if (parsePtr->numWords < 2 || parsePtr->numWords > 255) {
+	return TCL_ERROR;
+    }
+
+    for (i=0 ; i<parsePtr->numWords ; i++) {
+	CompileWord(envPtr, tokenPtr, interp, i);
+	tokenPtr = TokenAfter(tokenPtr);
+    }
+    TclEmitInstInt1(	INST_TCLOO_NEXT_CLASS, i,	envPtr);
+    return TCL_OK;
+}
+
+int
+TclCompileObjectSelfCmd(
+    Tcl_Interp *interp,		/* Used for error reporting. */
+    Tcl_Parse *parsePtr,	/* Points to a parse structure for the command
+				 * created by Tcl_ParseCommand. */
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)		/* Holds resulting instructions. */
+{
+    /*
+     * We only handle [self] and [self object] (which is the same operation).
+     * These are the only very common operations on [self] for which
+     * bytecoding is at all reasonable.
+     */
+
+    if (parsePtr->numWords == 1) {
+	goto compileSelfObject;
+    } else if (parsePtr->numWords == 2) {
+	Tcl_Token *tokenPtr = TokenAfter(parsePtr->tokenPtr), *subcmd;
+
+	if (tokenPtr->type != TCL_TOKEN_SIMPLE_WORD || tokenPtr[1].size==0) {
+	    return TCL_ERROR;
+	}
+
+	subcmd = tokenPtr + 1;
+	if (strncmp(subcmd->start, "object", subcmd->size) == 0) {
+	    goto compileSelfObject;
+	} else if (strncmp(subcmd->start, "namespace", subcmd->size) == 0) {
+	    goto compileSelfNamespace;
+	}
+    }
+
+    /*
+     * Can't compile; handle with runtime call.
+     */
+
+    return TCL_ERROR;
+
+  compileSelfObject:
+
+    /*
+     * This delegates the entire problem to a single opcode.
+     */
+
+    TclEmitOpcode(		INST_TCLOO_SELF,		envPtr);
+    return TCL_OK;
+
+  compileSelfNamespace:
+
+    /*
+     * This is formally only correct with TclOO methods as they are currently
+     * implemented; it assumes that the current namespace is invariably when a
+     * TclOO context is present is the object's namespace, and that's
+     * technically only something that's a matter of current policy. But it
+     * avoids creating another opcode, so that's all good!
+     */
+
+    TclEmitOpcode(		INST_TCLOO_SELF,		envPtr);
+    TclEmitOpcode(		INST_POP,			envPtr);
+    TclEmitOpcode(		INST_NS_CURRENT,		envPtr);
+    return TCL_OK;
+}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tclCompCmdsSZ.c b/generic/tclCompCmdsSZ.c
new file mode 100644
index 0000000..101edbd
--- /dev/null
+++ b/generic/tclCompCmdsSZ.c
@@ -0,0 +1,4485 @@
+/*
+ * tclCompCmdsSZ.c --
+ *
+ *	This file contains compilation procedures that compile various Tcl
+ *	commands (beginning with the letters 's' through 'z', except for
+ *	[upvar] and [variable]) into a sequence of instructions ("bytecodes").
+ *	Also includes the operator command compilers.
+ *
+ * Copyright (c) 1997-1998 Sun Microsystems, Inc.
+ * Copyright (c) 2001 by Kevin B. Kenny.  All rights reserved.
+ * Copyright (c) 2002 ActiveState Corporation.
+ * Copyright (c) 2004-2010 by Donal K. Fellows.
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#include "tclInt.h"
+#include "tclCompile.h"
+#include "tclStringTrim.h"
+
+/*
+ * Prototypes for procedures defined later in this file:
+ */
+
+static ClientData	DupJumptableInfo(ClientData clientData);
+static void		FreeJumptableInfo(ClientData clientData);
+static void		PrintJumptableInfo(ClientData clientData,
+			    Tcl_Obj *appendObj, ByteCode *codePtr,
+			    unsigned int pcOffset);
+static void		DisassembleJumptableInfo(ClientData clientData,
+			    Tcl_Obj *dictObj, ByteCode *codePtr,
+			    unsigned int pcOffset);
+static int		CompileAssociativeBinaryOpCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, const char *identity,
+			    int instruction, CompileEnv *envPtr);
+static int		CompileComparisonOpCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, int instruction,
+			    CompileEnv *envPtr);
+static int		CompileStrictlyBinaryOpCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, int instruction,
+			    CompileEnv *envPtr);
+static int		CompileUnaryOpCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, int instruction,
+			    CompileEnv *envPtr);
+static void		IssueSwitchChainedTests(Tcl_Interp *interp,
+			    CompileEnv *envPtr, int mode, int noCase,
+			    int valueIndex, int numWords,
+			    Tcl_Token **bodyToken, int *bodyLines,
+			    int **bodyNext);
+static void		IssueSwitchJumpTable(Tcl_Interp *interp,
+			    CompileEnv *envPtr, int valueIndex,
+			    int numWords, Tcl_Token **bodyToken,
+			    int *bodyLines, int **bodyContLines);
+static int		IssueTryClausesInstructions(Tcl_Interp *interp,
+			    CompileEnv *envPtr, Tcl_Token *bodyToken,
+			    int numHandlers, int *matchCodes,
+			    Tcl_Obj **matchClauses, int *resultVarIndices,
+			    int *optionVarIndices, Tcl_Token **handlerTokens);
+static int		IssueTryClausesFinallyInstructions(Tcl_Interp *interp,
+			    CompileEnv *envPtr, Tcl_Token *bodyToken,
+			    int numHandlers, int *matchCodes,
+			    Tcl_Obj **matchClauses, int *resultVarIndices,
+			    int *optionVarIndices, Tcl_Token **handlerTokens,
+			    Tcl_Token *finallyToken);
+static int		IssueTryFinallyInstructions(Tcl_Interp *interp,
+			    CompileEnv *envPtr, Tcl_Token *bodyToken,
+			    Tcl_Token *finallyToken);
+
+/*
+ * The structures below define the AuxData types defined in this file.
+ */
+
+const AuxDataType tclJumptableInfoType = {
+    "JumptableInfo",		/* name */
+    DupJumptableInfo,		/* dupProc */
+    FreeJumptableInfo,		/* freeProc */
+    PrintJumptableInfo,		/* printProc */
+    DisassembleJumptableInfo	/* disassembleProc */
+};
+
+/*
+ * Shorthand macros for instruction issuing.
+ */
+
+#define OP(name)	TclEmitOpcode(INST_##name, envPtr)
+#define OP1(name,val)	TclEmitInstInt1(INST_##name,(val),envPtr)
+#define OP4(name,val)	TclEmitInstInt4(INST_##name,(val),envPtr)
+#define OP14(name,val1,val2) \
+    TclEmitInstInt1(INST_##name,(val1),envPtr);TclEmitInt4((val2),envPtr)
+#define OP44(name,val1,val2) \
+    TclEmitInstInt4(INST_##name,(val1),envPtr);TclEmitInt4((val2),envPtr)
+#define PUSH(str) \
+    PushStringLiteral(envPtr, str)
+#define JUMP4(name,var) \
+    (var) = CurrentOffset(envPtr);TclEmitInstInt4(INST_##name##4,0,envPtr)
+#define FIXJUMP4(var) \
+    TclStoreInt4AtPtr(CurrentOffset(envPtr)-(var),envPtr->codeStart+(var)+1)
+#define JUMP1(name,var) \
+    (var) = CurrentOffset(envPtr);TclEmitInstInt1(INST_##name##1,0,envPtr)
+#define FIXJUMP1(var) \
+    TclStoreInt1AtPtr(CurrentOffset(envPtr)-(var),envPtr->codeStart+(var)+1)
+#define LOAD(idx) \
+    if ((idx)<256) {OP1(LOAD_SCALAR1,(idx));} else {OP4(LOAD_SCALAR4,(idx));}
+#define STORE(idx) \
+    if ((idx)<256) {OP1(STORE_SCALAR1,(idx));} else {OP4(STORE_SCALAR4,(idx));}
+#define INVOKE(name) \
+    TclEmitInvoke(envPtr,INST_##name)
+
+#define INDEX_END	(-2)
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * GetIndexFromToken --
+ *
+ *	Parse a token and get the encoded version of the index (as understood
+ *	by TEBC), assuming it is at all knowable at compile time. Only handles
+ *	indices that are integers or 'end' or 'end-integer'.
+ *
+ * Returns:
+ *	TCL_OK if parsing succeeded, and TCL_ERROR if it failed.
+ *
+ * Side effects:
+ *	Sets *index to the index value if successful.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static inline int
+GetIndexFromToken(
+    Tcl_Token *tokenPtr,
+    int *index)
+{
+    Tcl_Obj *tmpObj = Tcl_NewObj();
+    int result, idx;
+
+    if (!TclWordKnownAtCompileTime(tokenPtr, tmpObj)) {
+	Tcl_DecrRefCount(tmpObj);
+	return TCL_ERROR;
+    }
+
+    result = TclGetIntFromObj(NULL, tmpObj, &idx);
+    if (result == TCL_OK) {
+	if (idx < 0) {
+	    result = TCL_ERROR;
+	}
+    } else {
+	result = TclGetIntForIndexM(NULL, tmpObj, INDEX_END, &idx);
+	if (result == TCL_OK && idx > INDEX_END) {
+	    result = TCL_ERROR;
+	}
+    }
+    Tcl_DecrRefCount(tmpObj);
+
+    if (result == TCL_OK) {
+	*index = idx;
+    }
+
+    return result;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclCompileSetCmd --
+ *
+ *	Procedure called to compile the "set" command.
+ *
+ * Results:
+ *	Returns TCL_OK for a successful compile. Returns TCL_ERROR to defer
+ *	evaluation to runtime.
+ *
+ * Side effects:
+ *	Instructions are added to envPtr to execute the "set" command at
+ *	runtime.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclCompileSetCmd(
+    Tcl_Interp *interp,		/* Used for error reporting. */
+    Tcl_Parse *parsePtr,	/* Points to a parse structure for the command
+				 * created by Tcl_ParseCommand. */
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)		/* Holds resulting instructions. */
+{
+    Tcl_Token *varTokenPtr, *valueTokenPtr;
+    int isAssignment, isScalar, localIndex, numWords;
+    DefineLineInformation;	/* TIP #280 */
+
+    numWords = parsePtr->numWords;
+    if ((numWords != 2) && (numWords != 3)) {
+	return TCL_ERROR;
+    }
+    isAssignment = (numWords == 3);
+
+    /*
+     * Decide if we can use a frame slot for the var/array name or if we need
+     * to emit code to compute and push the name at runtime. We use a frame
+     * slot (entry in the array of local vars) if we are compiling a procedure
+     * body and if the name is simple text that does not include namespace
+     * qualifiers.
+     */
+
+    varTokenPtr = TokenAfter(parsePtr->tokenPtr);
+    PushVarNameWord(interp, varTokenPtr, envPtr, 0,
+	    &localIndex, &isScalar, 1);
+
+    /*
+     * If we are doing an assignment, push the new value.
+     */
+
+    if (isAssignment) {
+	valueTokenPtr = TokenAfter(varTokenPtr);
+	CompileWord(envPtr, valueTokenPtr, interp, 2);
+    }
+
+    /*
+     * Emit instructions to set/get the variable.
+     */
+
+	if (isScalar) {
+	    if (localIndex < 0) {
+		TclEmitOpcode((isAssignment?
+			INST_STORE_STK : INST_LOAD_STK), envPtr);
+	    } else if (localIndex <= 255) {
+		TclEmitInstInt1((isAssignment?
+			INST_STORE_SCALAR1 : INST_LOAD_SCALAR1),
+			localIndex, envPtr);
+	    } else {
+		TclEmitInstInt4((isAssignment?
+			INST_STORE_SCALAR4 : INST_LOAD_SCALAR4),
+			localIndex, envPtr);
+	    }
+	} else {
+	    if (localIndex < 0) {
+		TclEmitOpcode((isAssignment?
+			INST_STORE_ARRAY_STK : INST_LOAD_ARRAY_STK), envPtr);
+	    } else if (localIndex <= 255) {
+		TclEmitInstInt1((isAssignment?
+			INST_STORE_ARRAY1 : INST_LOAD_ARRAY1),
+			localIndex, envPtr);
+	    } else {
+		TclEmitInstInt4((isAssignment?
+			INST_STORE_ARRAY4 : INST_LOAD_ARRAY4),
+			localIndex, envPtr);
+	    }
+	}
+
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclCompileString*Cmd --
+ *
+ *	Procedures called to compile various subcommands of the "string"
+ *	command.
+ *
+ * Results:
+ *	Returns TCL_OK for a successful compile. Returns TCL_ERROR to defer
+ *	evaluation to runtime.
+ *
+ * Side effects:
+ *	Instructions are added to envPtr to execute the "string" command at
+ *	runtime.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclCompileStringCatCmd(
+    Tcl_Interp *interp,		/* Used for error reporting. */
+    Tcl_Parse *parsePtr,	/* Points to a parse structure for the command
+				 * created by Tcl_ParseCommand. */
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)		/* Holds resulting instructions. */
+{
+    int i, numWords = parsePtr->numWords, numArgs;
+    Tcl_Token *wordTokenPtr;
+    Tcl_Obj *obj, *folded;
+    DefineLineInformation;	/* TIP #280 */
+
+    /* Trivial case, no arg */
+
+    if (numWords<2) {
+	PushStringLiteral(envPtr, "");
+	return TCL_OK;
+    }
+
+    /* General case: issue CONCAT1's (by chunks of 254 if needed), folding
+       contiguous constants along the way */
+
+    numArgs = 0;
+    folded = NULL;
+    wordTokenPtr = TokenAfter(parsePtr->tokenPtr);
+    for (i = 1; i < numWords; i++) {
+	obj = Tcl_NewObj();
+	if (TclWordKnownAtCompileTime(wordTokenPtr, obj)) {
+	    if (folded) {
+		Tcl_AppendObjToObj(folded, obj);
+		Tcl_DecrRefCount(obj);
+	    } else {
+		folded = obj;
+	    }
+	} else {
+	    Tcl_DecrRefCount(obj);
+	    if (folded) {
+		int len;
+		const char *bytes = Tcl_GetStringFromObj(folded, &len);
+
+		PushLiteral(envPtr, bytes, len);
+		Tcl_DecrRefCount(folded);
+		folded = NULL;
+		numArgs ++;
+	    }
+	    CompileWord(envPtr, wordTokenPtr, interp, i);
+	    numArgs ++;
+	    if (numArgs >= 254) { /* 254 to take care of the possible +1 of "folded" above */
+		TclEmitInstInt1(INST_STR_CONCAT1, numArgs, envPtr);
+		numArgs = 1;	/* concat pushes 1 obj, the result */
+	    }
+	}
+	wordTokenPtr = TokenAfter(wordTokenPtr);
+    }
+    if (folded) {
+	int len;
+	const char *bytes = Tcl_GetStringFromObj(folded, &len);
+
+	PushLiteral(envPtr, bytes, len);
+	Tcl_DecrRefCount(folded);
+	folded = NULL;
+	numArgs ++;
+    }
+    if (numArgs > 1) {
+	TclEmitInstInt1(INST_STR_CONCAT1, numArgs, envPtr);
+    }
+
+    return TCL_OK;
+}
+
+int
+TclCompileStringCmpCmd(
+    Tcl_Interp *interp,		/* Used for error reporting. */
+    Tcl_Parse *parsePtr,	/* Points to a parse structure for the command
+				 * created by Tcl_ParseCommand. */
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)		/* Holds resulting instructions. */
+{
+    DefineLineInformation;	/* TIP #280 */
+    Tcl_Token *tokenPtr;
+
+    /*
+     * We don't support any flags; the bytecode isn't that sophisticated.
+     */
+
+    if (parsePtr->numWords != 3) {
+	return TCL_ERROR;
+    }
+
+    /*
+     * Push the two operands onto the stack and then the test.
+     */
+
+    tokenPtr = TokenAfter(parsePtr->tokenPtr);
+    CompileWord(envPtr, tokenPtr, interp, 1);
+    tokenPtr = TokenAfter(tokenPtr);
+    CompileWord(envPtr, tokenPtr, interp, 2);
+    TclEmitOpcode(INST_STR_CMP, envPtr);
+    return TCL_OK;
+}
+
+int
+TclCompileStringEqualCmd(
+    Tcl_Interp *interp,		/* Used for error reporting. */
+    Tcl_Parse *parsePtr,	/* Points to a parse structure for the command
+				 * created by Tcl_ParseCommand. */
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)		/* Holds resulting instructions. */
+{
+    DefineLineInformation;	/* TIP #280 */
+    Tcl_Token *tokenPtr;
+
+    /*
+     * We don't support any flags; the bytecode isn't that sophisticated.
+     */
+
+    if (parsePtr->numWords != 3) {
+	return TCL_ERROR;
+    }
+
+    /*
+     * Push the two operands onto the stack and then the test.
+     */
+
+    tokenPtr = TokenAfter(parsePtr->tokenPtr);
+    CompileWord(envPtr, tokenPtr, interp, 1);
+    tokenPtr = TokenAfter(tokenPtr);
+    CompileWord(envPtr, tokenPtr, interp, 2);
+    TclEmitOpcode(INST_STR_EQ, envPtr);
+    return TCL_OK;
+}
+
+int
+TclCompileStringFirstCmd(
+    Tcl_Interp *interp,		/* Used for error reporting. */
+    Tcl_Parse *parsePtr,	/* Points to a parse structure for the command
+				 * created by Tcl_ParseCommand. */
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)		/* Holds resulting instructions. */
+{
+    DefineLineInformation;	/* TIP #280 */
+    Tcl_Token *tokenPtr;
+
+    /*
+     * We don't support any flags; the bytecode isn't that sophisticated.
+     */
+
+    if (parsePtr->numWords != 3) {
+	return TCL_ERROR;
+    }
+
+    /*
+     * Push the two operands onto the stack and then the test.
+     */
+
+    tokenPtr = TokenAfter(parsePtr->tokenPtr);
+    CompileWord(envPtr, tokenPtr, interp, 1);
+    tokenPtr = TokenAfter(tokenPtr);
+    CompileWord(envPtr, tokenPtr, interp, 2);
+    OP(STR_FIND);
+    return TCL_OK;
+}
+
+int
+TclCompileStringLastCmd(
+    Tcl_Interp *interp,		/* Used for error reporting. */
+    Tcl_Parse *parsePtr,	/* Points to a parse structure for the command
+				 * created by Tcl_ParseCommand. */
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)		/* Holds resulting instructions. */
+{
+    DefineLineInformation;	/* TIP #280 */
+    Tcl_Token *tokenPtr;
+
+    /*
+     * We don't support any flags; the bytecode isn't that sophisticated.
+     */
+
+    if (parsePtr->numWords != 3) {
+	return TCL_ERROR;
+    }
+
+    /*
+     * Push the two operands onto the stack and then the test.
+     */
+
+    tokenPtr = TokenAfter(parsePtr->tokenPtr);
+    CompileWord(envPtr, tokenPtr, interp, 1);
+    tokenPtr = TokenAfter(tokenPtr);
+    CompileWord(envPtr, tokenPtr, interp, 2);
+    OP(STR_FIND_LAST);
+    return TCL_OK;
+}
+
+int
+TclCompileStringIndexCmd(
+    Tcl_Interp *interp,		/* Used for error reporting. */
+    Tcl_Parse *parsePtr,	/* Points to a parse structure for the command
+				 * created by Tcl_ParseCommand. */
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)		/* Holds resulting instructions. */
+{
+    DefineLineInformation;	/* TIP #280 */
+    Tcl_Token *tokenPtr;
+
+    if (parsePtr->numWords != 3) {
+	return TCL_ERROR;
+    }
+
+    /*
+     * Push the two operands onto the stack and then the index operation.
+     */
+
+    tokenPtr = TokenAfter(parsePtr->tokenPtr);
+    CompileWord(envPtr, tokenPtr, interp, 1);
+    tokenPtr = TokenAfter(tokenPtr);
+    CompileWord(envPtr, tokenPtr, interp, 2);
+    TclEmitOpcode(INST_STR_INDEX, envPtr);
+    return TCL_OK;
+}
+
+int
+TclCompileStringIsCmd(
+    Tcl_Interp *interp,		/* Used for error reporting. */
+    Tcl_Parse *parsePtr,	/* Points to a parse structure for the command
+				 * created by Tcl_ParseCommand. */
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)		/* Holds resulting instructions. */
+{
+    DefineLineInformation;	/* TIP #280 */
+    Tcl_Token *tokenPtr = TokenAfter(parsePtr->tokenPtr);
+    static const char *const isClasses[] = {
+	"alnum",	"alpha",	"ascii",	"control",
+	"boolean",	"digit",	"double",	"entier",
+	"false",	"graph",	"integer",	"list",
+	"lower",	"print",	"punct",	"space",
+	"true",		"upper",	"wideinteger",	"wordchar",
+	"xdigit",	NULL
+    };
+    enum isClasses {
+	STR_IS_ALNUM,	STR_IS_ALPHA,	STR_IS_ASCII,	STR_IS_CONTROL,
+	STR_IS_BOOL,	STR_IS_DIGIT,	STR_IS_DOUBLE,	STR_IS_ENTIER,
+	STR_IS_FALSE,	STR_IS_GRAPH,	STR_IS_INT,	STR_IS_LIST,
+	STR_IS_LOWER,	STR_IS_PRINT,	STR_IS_PUNCT,	STR_IS_SPACE,
+	STR_IS_TRUE,	STR_IS_UPPER,	STR_IS_WIDE,	STR_IS_WORD,
+	STR_IS_XDIGIT
+    };
+    int t, range, allowEmpty = 0, end;
+    InstStringClassType strClassType;
+    Tcl_Obj *isClass;
+
+    if (parsePtr->numWords < 3 || parsePtr->numWords > 6) {
+	return TCL_ERROR;
+    }
+    isClass = Tcl_NewObj();
+    if (!TclWordKnownAtCompileTime(tokenPtr, isClass)) {
+	Tcl_DecrRefCount(isClass);
+	return TCL_ERROR;
+    } else if (Tcl_GetIndexFromObj(interp, isClass, isClasses, "class", 0,
+	    &t) != TCL_OK) {
+	Tcl_DecrRefCount(isClass);
+	TclCompileSyntaxError(interp, envPtr);
+	return TCL_OK;
+    }
+    Tcl_DecrRefCount(isClass);
+
+#define GotLiteral(tokenPtr, word) \
+    ((tokenPtr)->type == TCL_TOKEN_SIMPLE_WORD &&			\
+     (tokenPtr)[1].size > 1 &&						\
+     (tokenPtr)[1].start[0] == word[0] &&				\
+     strncmp((tokenPtr)[1].start, (word), (tokenPtr)[1].size) == 0)
+
+    /*
+     * Cannot handle the -failindex option at all, and that's the only legal
+     * way to have more than 4 arguments.
+     */
+
+    if (parsePtr->numWords != 3 && parsePtr->numWords != 4) {
+	return TCL_ERROR;
+    }
+
+    tokenPtr = TokenAfter(tokenPtr);
+    if (parsePtr->numWords == 3) {
+	allowEmpty = 1;
+    } else {
+	if (!GotLiteral(tokenPtr, "-strict")) {
+	    return TCL_ERROR;
+	}
+	tokenPtr = TokenAfter(tokenPtr);
+    }
+#undef GotLiteral
+
+    /*
+     * Compile the code. There are several main classes of check here.
+     *	1. Character classes
+     *	2. Booleans
+     *	3. Integers
+     *	4. Floats
+     *	5. Lists
+     */
+
+    CompileWord(envPtr, tokenPtr, interp, parsePtr->numWords-1);
+
+    switch ((enum isClasses) t) {
+    case STR_IS_ALNUM:
+	strClassType = STR_CLASS_ALNUM;
+	goto compileStrClass;
+    case STR_IS_ALPHA:
+	strClassType = STR_CLASS_ALPHA;
+	goto compileStrClass;
+    case STR_IS_ASCII:
+	strClassType = STR_CLASS_ASCII;
+	goto compileStrClass;
+    case STR_IS_CONTROL:
+	strClassType = STR_CLASS_CONTROL;
+	goto compileStrClass;
+    case STR_IS_DIGIT:
+	strClassType = STR_CLASS_DIGIT;
+	goto compileStrClass;
+    case STR_IS_GRAPH:
+	strClassType = STR_CLASS_GRAPH;
+	goto compileStrClass;
+    case STR_IS_LOWER:
+	strClassType = STR_CLASS_LOWER;
+	goto compileStrClass;
+    case STR_IS_PRINT:
+	strClassType = STR_CLASS_PRINT;
+	goto compileStrClass;
+    case STR_IS_PUNCT:
+	strClassType = STR_CLASS_PUNCT;
+	goto compileStrClass;
+    case STR_IS_SPACE:
+	strClassType = STR_CLASS_SPACE;
+	goto compileStrClass;
+    case STR_IS_UPPER:
+	strClassType = STR_CLASS_UPPER;
+	goto compileStrClass;
+    case STR_IS_WORD:
+	strClassType = STR_CLASS_WORD;
+	goto compileStrClass;
+    case STR_IS_XDIGIT:
+	strClassType = STR_CLASS_XDIGIT;
+    compileStrClass:
+	if (allowEmpty) {
+	    OP1(	STR_CLASS, strClassType);
+	} else {
+	    int over, over2;
+
+	    OP(		DUP);
+	    OP1(	STR_CLASS, strClassType);
+	    JUMP1(	JUMP_TRUE, over);
+	    OP(		POP);
+	    PUSH(	"0");
+	    JUMP1(	JUMP, over2);
+	    FIXJUMP1(over);
+	    PUSH(	"");
+	    OP(		STR_NEQ);
+	    FIXJUMP1(over2);
+	}
+	return TCL_OK;
+
+    case STR_IS_BOOL:
+    case STR_IS_FALSE:
+    case STR_IS_TRUE:
+	OP(		TRY_CVT_TO_BOOLEAN);
+	switch (t) {
+	    int over, over2;
+
+	case STR_IS_BOOL:
+	    if (allowEmpty) {
+		JUMP1(	JUMP_TRUE, over);
+		PUSH(	"");
+		OP(	STR_EQ);
+		JUMP1(	JUMP, over2);
+		FIXJUMP1(over);
+		OP(	POP);
+		PUSH(	"1");
+		FIXJUMP1(over2);
+	    } else {
+		OP4(	REVERSE, 2);
+		OP(	POP);
+	    }
+	    return TCL_OK;
+	case STR_IS_TRUE:
+	    JUMP1(	JUMP_TRUE, over);
+	    if (allowEmpty) {
+		PUSH(	"");
+		OP(	STR_EQ);
+	    } else {
+		OP(	POP);
+		PUSH(	"0");
+	    }
+	    FIXJUMP1(	over);
+	    OP(		LNOT);
+	    OP(		LNOT);
+	    return TCL_OK;
+	case STR_IS_FALSE:
+	    JUMP1(	JUMP_TRUE, over);
+	    if (allowEmpty) {
+		PUSH(	"");
+		OP(	STR_NEQ);
+	    } else {
+		OP(	POP);
+		PUSH(	"1");
+	    }
+	    FIXJUMP1(	over);
+	    OP(		LNOT);
+	    return TCL_OK;
+	}
+
+    case STR_IS_DOUBLE: {
+	int satisfied, isEmpty;
+
+	if (allowEmpty) {
+	    OP(		DUP);
+	    PUSH(	"");
+	    OP(		STR_EQ);
+	    JUMP1(	JUMP_TRUE, isEmpty);
+	    OP(		NUM_TYPE);
+	    JUMP1(	JUMP_TRUE, satisfied);
+	    PUSH(	"0");
+	    JUMP1(	JUMP, end);
+	    FIXJUMP1(	isEmpty);
+	    OP(		POP);
+	    FIXJUMP1(	satisfied);
+	} else {
+	    OP(		NUM_TYPE);
+	    JUMP1(	JUMP_TRUE, satisfied);
+	    PUSH(	"0");
+	    JUMP1(	JUMP, end);
+	    TclAdjustStackDepth(-1, envPtr);
+	    FIXJUMP1(	satisfied);
+	}
+	PUSH(		"1");
+	FIXJUMP1(	end);
+	return TCL_OK;
+    }
+
+    case STR_IS_INT:
+    case STR_IS_WIDE:
+    case STR_IS_ENTIER:
+	if (allowEmpty) {
+	    int testNumType;
+
+	    OP(		DUP);
+	    OP(		NUM_TYPE);
+	    OP(		DUP);
+	    JUMP1(	JUMP_TRUE, testNumType);
+	    OP(		POP);
+	    PUSH(	"");
+	    OP(		STR_EQ);
+	    JUMP1(	JUMP, end);
+	    TclAdjustStackDepth(1, envPtr);
+	    FIXJUMP1(	testNumType);
+	    OP4(	REVERSE, 2);
+	    OP(		POP);
+	} else {
+	    OP(		NUM_TYPE);
+	    OP(		DUP);
+	    JUMP1(	JUMP_FALSE, end);
+	}
+
+	switch (t) {
+	case STR_IS_INT:
+	    PUSH(	"1");
+	    OP(		EQ);
+	    break;
+	case STR_IS_WIDE:
+	    PUSH(	"2");
+	    OP(		LE);
+	    break;
+	case STR_IS_ENTIER:
+	    PUSH(	"3");
+	    OP(		LE);
+	    break;
+	}
+	FIXJUMP1(	end);
+	return TCL_OK;
+
+    case STR_IS_LIST:
+	range = TclCreateExceptRange(CATCH_EXCEPTION_RANGE, envPtr);
+	OP4(		BEGIN_CATCH4, range);
+	ExceptionRangeStarts(envPtr, range);
+	OP(		DUP);
+	OP(		LIST_LENGTH);
+	OP(		POP);
+	ExceptionRangeEnds(envPtr, range);
+	ExceptionRangeTarget(envPtr, range, catchOffset);
+	OP(		POP);
+	OP(		PUSH_RETURN_CODE);
+	OP(		END_CATCH);
+	OP(		LNOT);
+	return TCL_OK;
+    }
+
+    return TclCompileBasicMin0ArgCmd(interp, parsePtr, cmdPtr, envPtr);
+}
+
+int
+TclCompileStringMatchCmd(
+    Tcl_Interp *interp,		/* Used for error reporting. */
+    Tcl_Parse *parsePtr,	/* Points to a parse structure for the command
+				 * created by Tcl_ParseCommand. */
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)		/* Holds resulting instructions. */
+{
+    DefineLineInformation;	/* TIP #280 */
+    Tcl_Token *tokenPtr;
+    int i, length, exactMatch = 0, nocase = 0;
+    const char *str;
+
+    if (parsePtr->numWords < 3 || parsePtr->numWords > 4) {
+	return TCL_ERROR;
+    }
+    tokenPtr = TokenAfter(parsePtr->tokenPtr);
+
+    /*
+     * Check if we have a -nocase flag.
+     */
+
+    if (parsePtr->numWords == 4) {
+	if (tokenPtr->type != TCL_TOKEN_SIMPLE_WORD) {
+	    return TclCompileBasic3ArgCmd(interp, parsePtr, cmdPtr, envPtr);
+	}
+	str = tokenPtr[1].start;
+	length = tokenPtr[1].size;
+	if ((length <= 1) || strncmp(str, "-nocase", (size_t) length)) {
+	    /*
+	     * Fail at run time, not in compilation.
+	     */
+
+	    return TclCompileBasic3ArgCmd(interp, parsePtr, cmdPtr, envPtr);
+	}
+	nocase = 1;
+	tokenPtr = TokenAfter(tokenPtr);
+    }
+
+    /*
+     * Push the strings to match against each other.
+     */
+
+    for (i = 0; i < 2; i++) {
+	if (tokenPtr->type == TCL_TOKEN_SIMPLE_WORD) {
+	    str = tokenPtr[1].start;
+	    length = tokenPtr[1].size;
+	    if (!nocase && (i == 0)) {
+		/*
+		 * Trivial matches can be done by 'string equal'. If -nocase
+		 * was specified, we can't do this because INST_STR_EQ has no
+		 * support for nocase.
+		 */
+
+		Tcl_Obj *copy = Tcl_NewStringObj(str, length);
+
+		Tcl_IncrRefCount(copy);
+		exactMatch = TclMatchIsTrivial(TclGetString(copy));
+		TclDecrRefCount(copy);
+	    }
+	    PushLiteral(envPtr, str, length);
+	} else {
+	    SetLineInformation(i+1+nocase);
+	    CompileTokens(envPtr, tokenPtr, interp);
+	}
+	tokenPtr = TokenAfter(tokenPtr);
+    }
+
+    /*
+     * Push the matcher.
+     */
+
+    if (exactMatch) {
+	TclEmitOpcode(INST_STR_EQ, envPtr);
+    } else {
+	TclEmitInstInt1(INST_STR_MATCH, nocase, envPtr);
+    }
+    return TCL_OK;
+}
+
+int
+TclCompileStringLenCmd(
+    Tcl_Interp *interp,		/* Used for error reporting. */
+    Tcl_Parse *parsePtr,	/* Points to a parse structure for the command
+				 * created by Tcl_ParseCommand. */
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)		/* Holds resulting instructions. */
+{
+    DefineLineInformation;	/* TIP #280 */
+    Tcl_Token *tokenPtr;
+    Tcl_Obj *objPtr;
+
+    if (parsePtr->numWords != 2) {
+	return TCL_ERROR;
+    }
+
+    tokenPtr = TokenAfter(parsePtr->tokenPtr);
+    TclNewObj(objPtr);
+    if (TclWordKnownAtCompileTime(tokenPtr, objPtr)) {
+	/*
+	 * Here someone is asking for the length of a static string (or
+	 * something with backslashes). Just push the actual character (not
+	 * byte) length.
+	 */
+
+	char buf[TCL_INTEGER_SPACE];
+	int len = Tcl_GetCharLength(objPtr);
+
+	len = sprintf(buf, "%d", len);
+	PushLiteral(envPtr, buf, len);
+    } else {
+	SetLineInformation(1);
+	CompileTokens(envPtr, tokenPtr, interp);
+	TclEmitOpcode(INST_STR_LEN, envPtr);
+    }
+    TclDecrRefCount(objPtr);
+    return TCL_OK;
+}
+
+int
+TclCompileStringMapCmd(
+    Tcl_Interp *interp,		/* Used for error reporting. */
+    Tcl_Parse *parsePtr,	/* Points to a parse structure for the command
+				 * created by Tcl_ParseCommand. */
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)		/* Holds resulting instructions. */
+{
+    DefineLineInformation;	/* TIP #280 */
+    Tcl_Token *mapTokenPtr, *stringTokenPtr;
+    Tcl_Obj *mapObj, **objv;
+    char *bytes;
+    int len;
+
+    /*
+     * We only handle the case:
+     *
+     *    string map {foo bar} $thing
+     *
+     * That is, a literal two-element list (doesn't need to be brace-quoted,
+     * but does need to be compile-time knowable) and any old argument (the
+     * thing to map).
+     */
+
+    if (parsePtr->numWords != 3) {
+	return TCL_ERROR;
+    }
+    mapTokenPtr = TokenAfter(parsePtr->tokenPtr);
+    stringTokenPtr = TokenAfter(mapTokenPtr);
+    mapObj = Tcl_NewObj();
+    Tcl_IncrRefCount(mapObj);
+    if (!TclWordKnownAtCompileTime(mapTokenPtr, mapObj)) {
+	Tcl_DecrRefCount(mapObj);
+	return TclCompileBasic2ArgCmd(interp, parsePtr, cmdPtr, envPtr);
+    } else if (Tcl_ListObjGetElements(NULL, mapObj, &len, &objv) != TCL_OK) {
+	Tcl_DecrRefCount(mapObj);
+	return TclCompileBasic2ArgCmd(interp, parsePtr, cmdPtr, envPtr);
+    } else if (len != 2) {
+	Tcl_DecrRefCount(mapObj);
+	return TclCompileBasic2ArgCmd(interp, parsePtr, cmdPtr, envPtr);
+    }
+
+    /*
+     * Now issue the opcodes. Note that in the case that we know that the
+     * first word is an empty word, we don't issue the map at all. That is the
+     * correct semantics for mapping.
+     */
+
+    bytes = Tcl_GetStringFromObj(objv[0], &len);
+    if (len == 0) {
+	CompileWord(envPtr, stringTokenPtr, interp, 2);
+    } else {
+	PushLiteral(envPtr, bytes, len);
+	bytes = Tcl_GetStringFromObj(objv[1], &len);
+	PushLiteral(envPtr, bytes, len);
+	CompileWord(envPtr, stringTokenPtr, interp, 2);
+	OP(STR_MAP);
+    }
+    Tcl_DecrRefCount(mapObj);
+    return TCL_OK;
+}
+
+int
+TclCompileStringRangeCmd(
+    Tcl_Interp *interp,		/* Used for error reporting. */
+    Tcl_Parse *parsePtr,	/* Points to a parse structure for the command
+				 * created by Tcl_ParseCommand. */
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)		/* Holds resulting instructions. */
+{
+    DefineLineInformation;	/* TIP #280 */
+    Tcl_Token *stringTokenPtr, *fromTokenPtr, *toTokenPtr;
+    int idx1, idx2;
+
+    if (parsePtr->numWords != 4) {
+	return TCL_ERROR;
+    }
+    stringTokenPtr = TokenAfter(parsePtr->tokenPtr);
+    fromTokenPtr = TokenAfter(stringTokenPtr);
+    toTokenPtr = TokenAfter(fromTokenPtr);
+
+    /*
+     * Parse the two indices.
+     */
+
+    if (GetIndexFromToken(fromTokenPtr, &idx1) != TCL_OK) {
+	goto nonConstantIndices;
+    }
+    if (GetIndexFromToken(toTokenPtr, &idx2) != TCL_OK) {
+	goto nonConstantIndices;
+    }
+
+    /*
+     * Push the operand onto the stack and then the substring operation.
+     */
+
+    CompileWord(envPtr, stringTokenPtr,			interp, 1);
+    OP44(		STR_RANGE_IMM, idx1, idx2);
+    return TCL_OK;
+
+    /*
+     * Push the operands onto the stack and then the substring operation.
+     */
+
+  nonConstantIndices:
+    CompileWord(envPtr, stringTokenPtr,			interp, 1);
+    CompileWord(envPtr, fromTokenPtr,			interp, 2);
+    CompileWord(envPtr, toTokenPtr,			interp, 3);
+    OP(			STR_RANGE);
+    return TCL_OK;
+}
+
+int
+TclCompileStringReplaceCmd(
+    Tcl_Interp *interp,		/* Tcl interpreter for context. */
+    Tcl_Parse *parsePtr,	/* Points to a parse structure for the
+				 * command. */
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)		/* Holds the resulting instructions. */
+{
+    Tcl_Token *tokenPtr, *valueTokenPtr, *replacementTokenPtr = NULL;
+    DefineLineInformation;	/* TIP #280 */
+    int idx1, idx2;
+
+    if (parsePtr->numWords < 4 || parsePtr->numWords > 5) {
+	return TCL_ERROR;
+    }
+    valueTokenPtr = TokenAfter(parsePtr->tokenPtr);
+    if (parsePtr->numWords == 5) {
+	tokenPtr = TokenAfter(valueTokenPtr);
+	tokenPtr = TokenAfter(tokenPtr);
+	replacementTokenPtr = TokenAfter(tokenPtr);
+    }
+
+    /*
+     * Parse the indices. Will only compile special cases if both are
+     * constants and not an _integer_ less than zero (since we reserve
+     * negative indices here for end-relative indexing) or an end-based index
+     * greater than 'end' itself.
+     */
+
+    tokenPtr = TokenAfter(valueTokenPtr);
+    if (GetIndexFromToken(tokenPtr, &idx1) != TCL_OK) {
+	goto genericReplace;
+    }
+
+    tokenPtr = TokenAfter(tokenPtr);
+    if (GetIndexFromToken(tokenPtr, &idx2) != TCL_OK) {
+	goto genericReplace;
+    }
+
+    /*
+     * We handle these replacements specially: first character (where
+     * idx1=idx2=0) and last character (where idx1=idx2=INDEX_END). Anything
+     * else and the semantics get rather screwy.
+     */
+
+    if (idx1 == 0 && idx2 == 0) {
+	int notEq, end;
+
+	/*
+	 * Just working with the first character.
+	 */
+
+	CompileWord(envPtr, valueTokenPtr, interp, 1);
+	if (replacementTokenPtr == NULL) {
+	    /* Drop first */
+	    OP44(	STR_RANGE_IMM, 1, INDEX_END);
+	    return TCL_OK;
+	}
+	/* Replace first */
+	CompileWord(envPtr, replacementTokenPtr, interp, 4);
+	OP4(		OVER, 1);
+	PUSH(		"");
+	OP(		STR_EQ);
+	JUMP1(		JUMP_FALSE, notEq);
+	OP(		POP);
+	JUMP1(		JUMP, end);
+	FIXJUMP1(notEq);
+	TclAdjustStackDepth(1, envPtr);
+	OP4(		REVERSE, 2);
+	OP44(		STR_RANGE_IMM, 1, INDEX_END);
+	OP1(		STR_CONCAT1, 2);
+	FIXJUMP1(end);
+	return TCL_OK;
+
+    } else if (idx1 == INDEX_END && idx2 == INDEX_END) {
+	int notEq, end;
+
+	/*
+	 * Just working with the last character.
+	 */
+
+	CompileWord(envPtr, valueTokenPtr, interp, 1);
+	if (replacementTokenPtr == NULL) {
+	    /* Drop last */
+	    OP44(	STR_RANGE_IMM, 0, INDEX_END-1);
+	    return TCL_OK;
+	}
+	/* Replace last */
+	CompileWord(envPtr, replacementTokenPtr, interp, 4);
+	OP4(		OVER, 1);
+	PUSH(		"");
+	OP(		STR_EQ);
+	JUMP1(		JUMP_FALSE, notEq);
+	OP(		POP);
+	JUMP1(		JUMP, end);
+	FIXJUMP1(notEq);
+	TclAdjustStackDepth(1, envPtr);
+	OP4(		REVERSE, 2);
+	OP44(		STR_RANGE_IMM, 0, INDEX_END-1);
+	OP4(		REVERSE, 2);
+	OP1(		STR_CONCAT1, 2);
+	FIXJUMP1(end);
+	return TCL_OK;
+
+    } else {
+	/*
+	 * Need to process indices at runtime. This could be because the
+	 * indices are not constants, or because we need to resolve them to
+	 * absolute indices to work out if a replacement is going to happen.
+	 * In any case, to runtime it is.
+	 */
+
+    genericReplace:
+	CompileWord(envPtr, valueTokenPtr, interp, 1);
+	tokenPtr = TokenAfter(valueTokenPtr);
+	CompileWord(envPtr, tokenPtr, interp, 2);
+	tokenPtr = TokenAfter(tokenPtr);
+	CompileWord(envPtr, tokenPtr, interp, 3);
+	if (replacementTokenPtr != NULL) {
+	    CompileWord(envPtr, replacementTokenPtr, interp, 4);
+	} else {
+	    PUSH(	"");
+	}
+	OP(		STR_REPLACE);
+	return TCL_OK;
+    }
+}
+
+int
+TclCompileStringTrimLCmd(
+    Tcl_Interp *interp,		/* Used for error reporting. */
+    Tcl_Parse *parsePtr,	/* Points to a parse structure for the command
+				 * created by Tcl_ParseCommand. */
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)		/* Holds resulting instructions. */
+{
+    DefineLineInformation;	/* TIP #280 */
+    Tcl_Token *tokenPtr;
+
+    if (parsePtr->numWords != 2 && parsePtr->numWords != 3) {
+	return TCL_ERROR;
+    }
+
+    tokenPtr = TokenAfter(parsePtr->tokenPtr);
+    CompileWord(envPtr, tokenPtr,			interp, 1);
+    if (parsePtr->numWords == 3) {
+	tokenPtr = TokenAfter(tokenPtr);
+	CompileWord(envPtr, tokenPtr,			interp, 2);
+    } else {
+	PushLiteral(envPtr, tclDefaultTrimSet, strlen(tclDefaultTrimSet));
+    }
+    OP(			STR_TRIM_LEFT);
+    return TCL_OK;
+}
+
+int
+TclCompileStringTrimRCmd(
+    Tcl_Interp *interp,		/* Used for error reporting. */
+    Tcl_Parse *parsePtr,	/* Points to a parse structure for the command
+				 * created by Tcl_ParseCommand. */
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)		/* Holds resulting instructions. */
+{
+    DefineLineInformation;	/* TIP #280 */
+    Tcl_Token *tokenPtr;
+
+    if (parsePtr->numWords != 2 && parsePtr->numWords != 3) {
+	return TCL_ERROR;
+    }
+
+    tokenPtr = TokenAfter(parsePtr->tokenPtr);
+    CompileWord(envPtr, tokenPtr,			interp, 1);
+    if (parsePtr->numWords == 3) {
+	tokenPtr = TokenAfter(tokenPtr);
+	CompileWord(envPtr, tokenPtr,			interp, 2);
+    } else {
+	PushLiteral(envPtr, tclDefaultTrimSet, strlen(tclDefaultTrimSet));
+    }
+    OP(			STR_TRIM_RIGHT);
+    return TCL_OK;
+}
+
+int
+TclCompileStringTrimCmd(
+    Tcl_Interp *interp,		/* Used for error reporting. */
+    Tcl_Parse *parsePtr,	/* Points to a parse structure for the command
+				 * created by Tcl_ParseCommand. */
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)		/* Holds resulting instructions. */
+{
+    DefineLineInformation;	/* TIP #280 */
+    Tcl_Token *tokenPtr;
+
+    if (parsePtr->numWords != 2 && parsePtr->numWords != 3) {
+	return TCL_ERROR;
+    }
+
+    tokenPtr = TokenAfter(parsePtr->tokenPtr);
+    CompileWord(envPtr, tokenPtr,			interp, 1);
+    if (parsePtr->numWords == 3) {
+	tokenPtr = TokenAfter(tokenPtr);
+	CompileWord(envPtr, tokenPtr,			interp, 2);
+    } else {
+	PushLiteral(envPtr, tclDefaultTrimSet, strlen(tclDefaultTrimSet));
+    }
+    OP(			STR_TRIM);
+    return TCL_OK;
+}
+
+int
+TclCompileStringToUpperCmd(
+    Tcl_Interp *interp,		/* Used for error reporting. */
+    Tcl_Parse *parsePtr,	/* Points to a parse structure for the command
+				 * created by Tcl_ParseCommand. */
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)		/* Holds resulting instructions. */
+{
+    DefineLineInformation;	/* TIP #280 */
+    Tcl_Token *tokenPtr;
+
+    if (parsePtr->numWords != 2) {
+	return TclCompileBasic1To3ArgCmd(interp, parsePtr, cmdPtr, envPtr);
+    }
+
+    tokenPtr = TokenAfter(parsePtr->tokenPtr);
+    CompileWord(envPtr, tokenPtr,			interp, 1);
+    OP(			STR_UPPER);
+    return TCL_OK;
+}
+
+int
+TclCompileStringToLowerCmd(
+    Tcl_Interp *interp,		/* Used for error reporting. */
+    Tcl_Parse *parsePtr,	/* Points to a parse structure for the command
+				 * created by Tcl_ParseCommand. */
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)		/* Holds resulting instructions. */
+{
+    DefineLineInformation;	/* TIP #280 */
+    Tcl_Token *tokenPtr;
+
+    if (parsePtr->numWords != 2) {
+	return TclCompileBasic1To3ArgCmd(interp, parsePtr, cmdPtr, envPtr);
+    }
+
+    tokenPtr = TokenAfter(parsePtr->tokenPtr);
+    CompileWord(envPtr, tokenPtr,			interp, 1);
+    OP(			STR_LOWER);
+    return TCL_OK;
+}
+
+int
+TclCompileStringToTitleCmd(
+    Tcl_Interp *interp,		/* Used for error reporting. */
+    Tcl_Parse *parsePtr,	/* Points to a parse structure for the command
+				 * created by Tcl_ParseCommand. */
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)		/* Holds resulting instructions. */
+{
+    DefineLineInformation;	/* TIP #280 */
+    Tcl_Token *tokenPtr;
+
+    if (parsePtr->numWords != 2) {
+	return TclCompileBasic1To3ArgCmd(interp, parsePtr, cmdPtr, envPtr);
+    }
+
+    tokenPtr = TokenAfter(parsePtr->tokenPtr);
+    CompileWord(envPtr, tokenPtr,			interp, 1);
+    OP(			STR_TITLE);
+    return TCL_OK;
+}
+
+/*
+ * Support definitions for the [string is] compilation.
+ */
+
+static int
+UniCharIsAscii(
+    int character)
+{
+    return (character >= 0) && (character < 0x80);
+}
+
+static int
+UniCharIsHexDigit(
+    int character)
+{
+    return (character >= 0) && (character < 0x80) && isxdigit(character);
+}
+
+StringClassDesc const tclStringClassTable[] = {
+    {"alnum",	Tcl_UniCharIsAlnum},
+    {"alpha",	Tcl_UniCharIsAlpha},
+    {"ascii",	UniCharIsAscii},
+    {"control", Tcl_UniCharIsControl},
+    {"digit",	Tcl_UniCharIsDigit},
+    {"graph",	Tcl_UniCharIsGraph},
+    {"lower",	Tcl_UniCharIsLower},
+    {"print",	Tcl_UniCharIsPrint},
+    {"punct",	Tcl_UniCharIsPunct},
+    {"space",	Tcl_UniCharIsSpace},
+    {"upper",	Tcl_UniCharIsUpper},
+    {"word",	Tcl_UniCharIsWordChar},
+    {"xdigit",	UniCharIsHexDigit},
+    {NULL,	NULL}
+};
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclCompileSubstCmd --
+ *
+ *	Procedure called to compile the "subst" command.
+ *
+ * Results:
+ *	Returns TCL_OK for successful compile, or TCL_ERROR to defer
+ *	evaluation to runtime (either when it is too complex to get the
+ *	semantics right, or when we know for sure that it is an error but need
+ *	the error to happen at the right time).
+ *
+ * Side effects:
+ *	Instructions are added to envPtr to execute the "subst" command at
+ *	runtime.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclCompileSubstCmd(
+    Tcl_Interp *interp,		/* Used for error reporting. */
+    Tcl_Parse *parsePtr,	/* Points to a parse structure for the command
+				 * created by Tcl_ParseCommand. */
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)		/* Holds resulting instructions. */
+{
+    int numArgs = parsePtr->numWords - 1;
+    int numOpts = numArgs - 1;
+    int objc, flags = TCL_SUBST_ALL;
+    Tcl_Obj **objv/*, *toSubst = NULL*/;
+    Tcl_Token *wordTokenPtr = TokenAfter(parsePtr->tokenPtr);
+    int code = TCL_ERROR;
+    DefineLineInformation;	/* TIP #280 */
+
+    if (numArgs == 0) {
+	return TCL_ERROR;
+    }
+
+    objv = TclStackAlloc(interp, /*numArgs*/ numOpts * sizeof(Tcl_Obj *));
+
+    for (objc = 0; objc < /*numArgs*/ numOpts; objc++) {
+	objv[objc] = Tcl_NewObj();
+	Tcl_IncrRefCount(objv[objc]);
+	if (!TclWordKnownAtCompileTime(wordTokenPtr, objv[objc])) {
+	    objc++;
+	    goto cleanup;
+	}
+	wordTokenPtr = TokenAfter(wordTokenPtr);
+    }
+
+/*
+    if (TclSubstOptions(NULL, numOpts, objv, &flags) == TCL_OK) {
+	toSubst = objv[numOpts];
+	Tcl_IncrRefCount(toSubst);
+    }
+*/
+
+    /* TODO: Figure out expansion to cover WordKnownAtCompileTime
+     *	The difficulty is that WKACT makes a copy, and if TclSubstParse
+     *	below parses the copy of the original source string, some deep
+     *	parts of the compile machinery get upset.  They want all pointers
+     *	stored in Tcl_Tokens to point back to the same original string.
+     */
+    if (wordTokenPtr->type == TCL_TOKEN_SIMPLE_WORD) {
+	code = TclSubstOptions(NULL, numOpts, objv, &flags);
+    }
+
+  cleanup:
+    while (--objc >= 0) {
+	TclDecrRefCount(objv[objc]);
+    }
+    TclStackFree(interp, objv);
+    if (/*toSubst == NULL*/ code != TCL_OK) {
+	return TCL_ERROR;
+    }
+
+    SetLineInformation(numArgs);
+    TclSubstCompile(interp, wordTokenPtr[1].start, wordTokenPtr[1].size,
+	    flags, mapPtr->loc[eclIndex].line[numArgs], envPtr);
+
+/*    TclDecrRefCount(toSubst);*/
+    return TCL_OK;
+}
+
+void
+TclSubstCompile(
+    Tcl_Interp *interp,
+    const char *bytes,
+    int numBytes,
+    int flags,
+    int line,
+    CompileEnv *envPtr)
+{
+    Tcl_Token *endTokenPtr, *tokenPtr;
+    int breakOffset = 0, count = 0, bline = line;
+    Tcl_Parse parse;
+    Tcl_InterpState state = NULL;
+
+    TclSubstParse(interp, bytes, numBytes, flags, &parse, &state);
+    if (state != NULL) {
+	Tcl_ResetResult(interp);
+    }
+
+    /*
+     * Tricky point! If the first token does not result in a *guaranteed* push
+     * of a Tcl_Obj on the stack, we must push an empty object. Otherwise it
+     * is possible to get to an INST_STR_CONCAT1 or INST_DONE without enough
+     * values on the stack, resulting in a crash. Thanks to Joe Mistachkin for
+     * identifying a script that could trigger this case.
+     */
+
+    tokenPtr = parse.tokenPtr;
+    if (tokenPtr->type != TCL_TOKEN_TEXT && tokenPtr->type != TCL_TOKEN_BS) {
+	PUSH("");
+	count++;
+    }
+
+    for (endTokenPtr = tokenPtr + parse.numTokens;
+	    tokenPtr < endTokenPtr; tokenPtr = TokenAfter(tokenPtr)) {
+	int length, literal, catchRange, breakJump;
+	char buf[TCL_UTF_MAX];
+	JumpFixup startFixup, okFixup, returnFixup, breakFixup;
+	JumpFixup continueFixup, otherFixup, endFixup;
+
+	switch (tokenPtr->type) {
+	case TCL_TOKEN_TEXT:
+	    literal = TclRegisterNewLiteral(envPtr,
+		    tokenPtr->start, tokenPtr->size);
+	    TclEmitPush(literal, envPtr);
+	    TclAdvanceLines(&bline, tokenPtr->start,
+		    tokenPtr->start + tokenPtr->size);
+	    count++;
+	    continue;
+	case TCL_TOKEN_BS:
+	    length = TclParseBackslash(tokenPtr->start, tokenPtr->size,
+		    NULL, buf);
+	    literal = TclRegisterNewLiteral(envPtr, buf, length);
+	    TclEmitPush(literal, envPtr);
+	    count++;
+	    continue;
+	case TCL_TOKEN_VARIABLE:
+	    /*
+	     * Check for simple variable access; see if we can only generate
+	     * TCL_OK or TCL_ERROR from the substituted variable read; if so,
+	     * there is no need to generate elaborate exception-management
+	     * code. Note that the first component of TCL_TOKEN_VARIABLE is
+	     * always TCL_TOKEN_TEXT...
+	     */
+
+	    if (tokenPtr->numComponents > 1) {
+		int i, foundCommand = 0;
+
+		for (i=2 ; i<=tokenPtr->numComponents ; i++) {
+		    if (tokenPtr[i].type == TCL_TOKEN_COMMAND) {
+			foundCommand = 1;
+			break;
+		    }
+		}
+		if (foundCommand) {
+		    break;
+		}
+	    }
+
+	    envPtr->line = bline;
+	    TclCompileVarSubst(interp, tokenPtr, envPtr);
+	    bline = envPtr->line;
+	    count++;
+	    continue;
+	}
+
+	while (count > 255) {
+	    OP1(		STR_CONCAT1, 255);
+	    count -= 254;
+	}
+	if (count > 1) {
+	    OP1(		STR_CONCAT1, count);
+	    count = 1;
+	}
+
+	if (breakOffset == 0) {
+	    /* Jump to the start (jump over the jump to end) */
+	    TclEmitForwardJump(envPtr, TCL_UNCONDITIONAL_JUMP, &startFixup);
+
+	    /* Jump to the end (all BREAKs land here) */
+	    breakOffset = CurrentOffset(envPtr);
+	    TclEmitInstInt4(INST_JUMP4, 0, envPtr);
+
+	    /* Start */
+	    if (TclFixupForwardJumpToHere(envPtr, &startFixup, 127)) {
+		Tcl_Panic("TclCompileSubstCmd: bad start jump distance %d",
+			(int) (CurrentOffset(envPtr) - startFixup.codeOffset));
+	    }
+	}
+
+	envPtr->line = bline;
+	catchRange = TclCreateExceptRange(CATCH_EXCEPTION_RANGE, envPtr);
+	OP4(	BEGIN_CATCH4, catchRange);
+	ExceptionRangeStarts(envPtr, catchRange);
+
+	switch (tokenPtr->type) {
+	case TCL_TOKEN_COMMAND:
+	    TclCompileScript(interp, tokenPtr->start+1, tokenPtr->size-2,
+		    envPtr);
+	    count++;
+	    break;
+	case TCL_TOKEN_VARIABLE:
+	    TclCompileVarSubst(interp, tokenPtr, envPtr);
+	    count++;
+	    break;
+	default:
+	    Tcl_Panic("unexpected token type in TclCompileSubstCmd: %d",
+		    tokenPtr->type);
+	}
+
+	ExceptionRangeEnds(envPtr, catchRange);
+
+	/* Substitution produced TCL_OK */
+	OP(	END_CATCH);
+	TclEmitForwardJump(envPtr, TCL_UNCONDITIONAL_JUMP, &okFixup);
+	TclAdjustStackDepth(-1, envPtr);
+
+	/* Exceptional return codes processed here */
+	ExceptionRangeTarget(envPtr, catchRange, catchOffset);
+	OP(	PUSH_RETURN_OPTIONS);
+	OP(	PUSH_RESULT);
+	OP(	PUSH_RETURN_CODE);
+	OP(	END_CATCH);
+	OP(	RETURN_CODE_BRANCH);
+
+	/* ERROR -> reraise it; NB: can't require BREAK/CONTINUE handling */
+	OP(	RETURN_STK);
+	OP(	NOP);
+
+	/* RETURN */
+	TclEmitForwardJump(envPtr, TCL_UNCONDITIONAL_JUMP, &returnFixup);
+
+	/* BREAK */
+	TclEmitForwardJump(envPtr, TCL_UNCONDITIONAL_JUMP, &breakFixup);
+
+	/* CONTINUE */
+	TclEmitForwardJump(envPtr, TCL_UNCONDITIONAL_JUMP, &continueFixup);
+
+	/* OTHER */
+	TclEmitForwardJump(envPtr, TCL_UNCONDITIONAL_JUMP, &otherFixup);
+
+	TclAdjustStackDepth(1, envPtr);
+	/* BREAK destination */
+	if (TclFixupForwardJumpToHere(envPtr, &breakFixup, 127)) {
+	    Tcl_Panic("TclCompileSubstCmd: bad break jump distance %d",
+		    (int) (CurrentOffset(envPtr) - breakFixup.codeOffset));
+	}
+	OP(	POP);
+	OP(	POP);
+
+	breakJump = CurrentOffset(envPtr) - breakOffset;
+	if (breakJump > 127) {
+	    OP4(JUMP4, -breakJump);
+	} else {
+	    OP1(JUMP1, -breakJump);
+	}
+
+	TclAdjustStackDepth(2, envPtr);
+	/* CONTINUE destination */
+	if (TclFixupForwardJumpToHere(envPtr, &continueFixup, 127)) {
+	    Tcl_Panic("TclCompileSubstCmd: bad continue jump distance %d",
+		    (int) (CurrentOffset(envPtr) - continueFixup.codeOffset));
+	}
+	OP(	POP);
+	OP(	POP);
+	TclEmitForwardJump(envPtr, TCL_UNCONDITIONAL_JUMP, &endFixup);
+
+	TclAdjustStackDepth(2, envPtr);
+	/* RETURN + other destination */
+	if (TclFixupForwardJumpToHere(envPtr, &returnFixup, 127)) {
+	    Tcl_Panic("TclCompileSubstCmd: bad return jump distance %d",
+		    (int) (CurrentOffset(envPtr) - returnFixup.codeOffset));
+	}
+	if (TclFixupForwardJumpToHere(envPtr, &otherFixup, 127)) {
+	    Tcl_Panic("TclCompileSubstCmd: bad other jump distance %d",
+		    (int) (CurrentOffset(envPtr) - otherFixup.codeOffset));
+	}
+
+	/*
+	 * Pull the result to top of stack, discard options dict.
+	 */
+
+	OP4(	REVERSE, 2);
+	OP(	POP);
+
+	/* OK destination */
+	if (TclFixupForwardJumpToHere(envPtr, &okFixup, 127)) {
+	    Tcl_Panic("TclCompileSubstCmd: bad ok jump distance %d",
+		    (int) (CurrentOffset(envPtr) - okFixup.codeOffset));
+	}
+	if (count > 1) {
+	    OP1(STR_CONCAT1, count);
+	    count = 1;
+	}
+
+	/* CONTINUE jump to here */
+	if (TclFixupForwardJumpToHere(envPtr, &endFixup, 127)) {
+	    Tcl_Panic("TclCompileSubstCmd: bad end jump distance %d",
+		    (int) (CurrentOffset(envPtr) - endFixup.codeOffset));
+	}
+	bline = envPtr->line;
+    }
+
+    while (count > 255) {
+	OP1(	STR_CONCAT1, 255);
+	count -= 254;
+    }
+    if (count > 1) {
+	OP1(	STR_CONCAT1, count);
+    }
+
+    Tcl_FreeParse(&parse);
+
+    if (state != NULL) {
+	Tcl_RestoreInterpState(interp, state);
+	TclCompileSyntaxError(interp, envPtr);
+	TclAdjustStackDepth(-1, envPtr);
+    }
+
+    /* Final target of the multi-jump from all BREAKs */
+    if (breakOffset > 0) {
+	TclUpdateInstInt4AtPc(INST_JUMP4, CurrentOffset(envPtr) - breakOffset,
+		envPtr->codeStart + breakOffset);
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclCompileSwitchCmd --
+ *
+ *	Procedure called to compile the "switch" command.
+ *
+ * Results:
+ *	Returns TCL_OK for successful compile, or TCL_ERROR to defer
+ *	evaluation to runtime (either when it is too complex to get the
+ *	semantics right, or when we know for sure that it is an error but need
+ *	the error to happen at the right time).
+ *
+ * Side effects:
+ *	Instructions are added to envPtr to execute the "switch" command at
+ *	runtime.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclCompileSwitchCmd(
+    Tcl_Interp *interp,		/* Used for error reporting. */
+    Tcl_Parse *parsePtr,	/* Points to a parse structure for the command
+				 * created by Tcl_ParseCommand. */
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)		/* Holds resulting instructions. */
+{
+    Tcl_Token *tokenPtr;	/* Pointer to tokens in command. */
+    int numWords;		/* Number of words in command. */
+
+    Tcl_Token *valueTokenPtr;	/* Token for the value to switch on. */
+    enum {Switch_Exact, Switch_Glob, Switch_Regexp} mode;
+				/* What kind of switch are we doing? */
+
+    Tcl_Token *bodyTokenArray;	/* Array of real pattern list items. */
+    Tcl_Token **bodyToken;	/* Array of pointers to pattern list items. */
+    int *bodyLines;		/* Array of line numbers for body list
+				 * items. */
+    int **bodyContLines;	/* Array of continuation line info. */
+    int noCase;			/* Has the -nocase flag been given? */
+    int foundMode = 0;		/* Have we seen a mode flag yet? */
+    int i, valueIndex;
+    int result = TCL_ERROR;
+    DefineLineInformation;	/* TIP #280 */
+    int *clNext = envPtr->clNext;
+
+    /*
+     * Only handle the following versions:
+     *   switch         ?--? word {pattern body ...}
+     *   switch -exact  ?--? word {pattern body ...}
+     *   switch -glob   ?--? word {pattern body ...}
+     *   switch -regexp ?--? word {pattern body ...}
+     *   switch         --   word simpleWordPattern simpleWordBody ...
+     *   switch -exact  --   word simpleWordPattern simpleWordBody ...
+     *   switch -glob   --   word simpleWordPattern simpleWordBody ...
+     *   switch -regexp --   word simpleWordPattern simpleWordBody ...
+     * When the mode is -glob, can also handle a -nocase flag.
+     *
+     * First off, we don't care how the command's word was generated; we're
+     * compiling it anyway! So skip it...
+     */
+
+    tokenPtr = TokenAfter(parsePtr->tokenPtr);
+    valueIndex = 1;
+    numWords = parsePtr->numWords-1;
+
+    /*
+     * Check for options.
+     */
+
+    noCase = 0;
+    mode = Switch_Exact;
+    if (numWords == 2) {
+	/*
+	 * There's just the switch value and the bodies list. In that case, we
+	 * can skip all option parsing and move on to consider switch values
+	 * and the body list.
+	 */
+
+	goto finishedOptionParse;
+    }
+
+    /*
+     * There must be at least one option, --, because without that there is no
+     * way to statically avoid the problems you get from strings-to-be-matched
+     * that start with a - (the interpreted code falls apart if it encounters
+     * them, so we punt if we *might* encounter them as that is the easiest
+     * way of emulating the behaviour).
+     */
+
+    for (; numWords>=3 ; tokenPtr=TokenAfter(tokenPtr),numWords--) {
+	register unsigned size = tokenPtr[1].size;
+	register const char *chrs = tokenPtr[1].start;
+
+	/*
+	 * We only process literal options, and we assume that -e, -g and -n
+	 * are unique prefixes of -exact, -glob and -nocase respectively (true
+	 * at time of writing). Note that -exact and -glob may only be given
+	 * at most once or we bail out (error case).
+	 */
+
+	if (tokenPtr->type != TCL_TOKEN_SIMPLE_WORD || size < 2) {
+	    return TCL_ERROR;
+	}
+
+	if ((size <= 6) && !memcmp(chrs, "-exact", size)) {
+	    if (foundMode) {
+		return TCL_ERROR;
+	    }
+	    mode = Switch_Exact;
+	    foundMode = 1;
+	    valueIndex++;
+	    continue;
+	} else if ((size <= 5) && !memcmp(chrs, "-glob", size)) {
+	    if (foundMode) {
+		return TCL_ERROR;
+	    }
+	    mode = Switch_Glob;
+	    foundMode = 1;
+	    valueIndex++;
+	    continue;
+	} else if ((size <= 7) && !memcmp(chrs, "-regexp", size)) {
+	    if (foundMode) {
+		return TCL_ERROR;
+	    }
+	    mode = Switch_Regexp;
+	    foundMode = 1;
+	    valueIndex++;
+	    continue;
+	} else if ((size <= 7) && !memcmp(chrs, "-nocase", size)) {
+	    noCase = 1;
+	    valueIndex++;
+	    continue;
+	} else if ((size == 2) && !memcmp(chrs, "--", 2)) {
+	    valueIndex++;
+	    break;
+	}
+
+	/*
+	 * The switch command has many flags we cannot compile at all (e.g.
+	 * all the RE-related ones) which we must have encountered. Either
+	 * that or we have run off the end. The action here is the same: punt
+	 * to interpreted version.
+	 */
+
+	return TCL_ERROR;
+    }
+    if (numWords < 3) {
+	return TCL_ERROR;
+    }
+    tokenPtr = TokenAfter(tokenPtr);
+    numWords--;
+    if (noCase && (mode == Switch_Exact)) {
+	/*
+	 * Can't compile this case; no opcode for case-insensitive equality!
+	 */
+
+	return TCL_ERROR;
+    }
+
+    /*
+     * The value to test against is going to always get pushed on the stack.
+     * But not yet; we need to verify that the rest of the command is
+     * compilable too.
+     */
+
+  finishedOptionParse:
+    valueTokenPtr = tokenPtr;
+    /* For valueIndex, see previous loop. */
+    tokenPtr = TokenAfter(tokenPtr);
+    numWords--;
+
+    /*
+     * Build an array of tokens for the matcher terms and script bodies. Note
+     * that in the case of the quoted bodies, this is tricky as we cannot use
+     * copies of the string from the input token for the generated tokens (it
+     * causes a crash during exception handling). When multiple tokens are
+     * available at this point, this is pretty easy.
+     */
+
+    if (numWords == 1) {
+	const char *bytes;
+	int maxLen, numBytes;
+	int bline;		/* TIP #280: line of the pattern/action list,
+				 * and start of list for when tracking the
+				 * location. This list comes immediately after
+				 * the value we switch on. */
+
+	if (tokenPtr->type != TCL_TOKEN_SIMPLE_WORD) {
+	    return TCL_ERROR;
+	}
+	bytes = tokenPtr[1].start;
+	numBytes = tokenPtr[1].size;
+
+	/* Allocate enough space to work in. */
+	maxLen = TclMaxListLength(bytes, numBytes, NULL);
+	if (maxLen < 2)  {
+	    return TCL_ERROR;
+	}
+	bodyTokenArray = ckalloc(sizeof(Tcl_Token) * maxLen);
+	bodyToken = ckalloc(sizeof(Tcl_Token *) * maxLen);
+	bodyLines = ckalloc(sizeof(int) * maxLen);
+	bodyContLines = ckalloc(sizeof(int*) * maxLen);
+
+	bline = mapPtr->loc[eclIndex].line[valueIndex+1];
+	numWords = 0;
+
+	while (numBytes > 0) {
+	    const char *prevBytes = bytes;
+	    int literal;
+
+	    if (TCL_OK != TclFindElement(NULL, bytes, numBytes,
+		    &(bodyTokenArray[numWords].start), &bytes,
+		    &(bodyTokenArray[numWords].size), &literal) || !literal) {
+		goto abort;
+	    }
+
+	    bodyTokenArray[numWords].type = TCL_TOKEN_TEXT;
+	    bodyTokenArray[numWords].numComponents = 0;
+	    bodyToken[numWords] = bodyTokenArray + numWords;
+
+	    /*
+	     * TIP #280: Now determine the line the list element starts on
+	     * (there is no need to do it earlier, due to the possibility of
+	     * aborting, see above).
+	     */
+
+	    TclAdvanceLines(&bline, prevBytes, bodyTokenArray[numWords].start);
+	    TclAdvanceContinuations(&bline, &clNext,
+		    bodyTokenArray[numWords].start - envPtr->source);
+	    bodyLines[numWords] = bline;
+	    bodyContLines[numWords] = clNext;
+	    TclAdvanceLines(&bline, bodyTokenArray[numWords].start, bytes);
+	    TclAdvanceContinuations(&bline, &clNext, bytes - envPtr->source);
+
+	    numBytes -= (bytes - prevBytes);
+	    numWords++;
+	}
+	if (numWords % 2) {
+	abort:
+	    ckfree((char *) bodyToken);
+	    ckfree((char *) bodyTokenArray);
+	    ckfree((char *) bodyLines);
+	    ckfree((char *) bodyContLines);
+	    return TCL_ERROR;
+	}
+    } else if (numWords % 2 || numWords == 0) {
+	/*
+	 * Odd number of words (>1) available, or no words at all available.
+	 * Both are error cases, so punt and let the interpreted-version
+	 * generate the error message. Note that the second case probably
+	 * should get caught earlier, but it's easy to check here again anyway
+	 * because it'd cause a nasty crash otherwise.
+	 */
+
+	return TCL_ERROR;
+    } else {
+	/*
+	 * Multi-word definition of patterns & actions.
+	 */
+
+	bodyToken = ckalloc(sizeof(Tcl_Token *) * numWords);
+	bodyLines = ckalloc(sizeof(int) * numWords);
+	bodyContLines = ckalloc(sizeof(int*) * numWords);
+	bodyTokenArray = NULL;
+	for (i=0 ; i<numWords ; i++) {
+	    /*
+	     * We only handle the very simplest case. Anything more complex is
+	     * a good reason to go to the interpreted case anyway due to
+	     * traces, etc.
+	     */
+
+	    if (tokenPtr->type != TCL_TOKEN_SIMPLE_WORD) {
+		goto freeTemporaries;
+	    }
+	    bodyToken[i] = tokenPtr+1;
+
+	    /*
+	     * TIP #280: Copy line information from regular cmd info.
+	     */
+
+	    bodyLines[i] = mapPtr->loc[eclIndex].line[valueIndex+1+i];
+	    bodyContLines[i] = mapPtr->loc[eclIndex].next[valueIndex+1+i];
+	    tokenPtr = TokenAfter(tokenPtr);
+	}
+    }
+
+    /*
+     * Fall back to interpreted if the last body is a continuation (it's
+     * illegal, but this makes the error happen at the right time).
+     */
+
+    if (bodyToken[numWords-1]->size == 1 &&
+	    bodyToken[numWords-1]->start[0] == '-') {
+	goto freeTemporaries;
+    }
+
+    /*
+     * Now we commit to generating code; the parsing stage per se is done.
+     * Check if we can generate a jump table, since if so that's faster than
+     * doing an explicit compare with each body. Note that we're definitely
+     * over-conservative with determining whether we can do the jump table,
+     * but it handles the most common case well enough.
+     */
+
+    /* Both methods push the value to match against onto the stack. */
+    CompileWord(envPtr, valueTokenPtr, interp, valueIndex);
+
+    if (mode == Switch_Exact) {
+	IssueSwitchJumpTable(interp, envPtr, valueIndex, numWords, bodyToken,
+		bodyLines, bodyContLines);
+    } else {
+	IssueSwitchChainedTests(interp, envPtr, mode, noCase, valueIndex,
+		numWords, bodyToken, bodyLines, bodyContLines);
+    }
+    result = TCL_OK;
+
+    /*
+     * Clean up all our temporary space and return.
+     */
+
+  freeTemporaries:
+    ckfree(bodyToken);
+    ckfree(bodyLines);
+    ckfree(bodyContLines);
+    if (bodyTokenArray != NULL) {
+	ckfree(bodyTokenArray);
+    }
+    return result;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * IssueSwitchChainedTests --
+ *
+ *	Generate instructions for a [switch] command that is to be compiled
+ *	into a sequence of tests. This is the generic handle-everything mode
+ *	that inherently has performance that is (on average) linear in the
+ *	number of tests. It is the only mode that can handle -glob and -regexp
+ *	matches, or anything that is case-insensitive. It does not handle the
+ *	wild-and-wooly end of regexp matching (i.e., capture of match results)
+ *	so that's when we spill to the interpreted version.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+IssueSwitchChainedTests(
+    Tcl_Interp *interp,		/* Context for compiling script bodies. */
+    CompileEnv *envPtr,		/* Holds resulting instructions. */
+    int mode,			/* Exact, Glob or Regexp */
+    int noCase,			/* Case-insensitivity flag. */
+    int valueIndex,		/* The value to match against. */
+    int numBodyTokens,		/* Number of tokens describing things the
+				 * switch can match against and bodies to
+				 * execute when the match succeeds. */
+    Tcl_Token **bodyToken,	/* Array of pointers to pattern list items. */
+    int *bodyLines,		/* Array of line numbers for body list
+				 * items. */
+    int **bodyContLines)	/* Array of continuation line info. */
+{
+    enum {Switch_Exact, Switch_Glob, Switch_Regexp};
+    int foundDefault;		/* Flag to indicate whether a "default" clause
+				 * is present. */
+    JumpFixup *fixupArray;	/* Array of forward-jump fixup records. */
+    unsigned int *fixupTargetArray; /* Array of places for fixups to point at. */
+    int fixupCount;		/* Number of places to fix up. */
+    int contFixIndex;		/* Where the first of the jumps due to a group
+				 * of continuation bodies starts, or -1 if
+				 * there aren't any. */
+    int contFixCount;		/* Number of continuation bodies pointing to
+				 * the current (or next) real body. */
+    int nextArmFixupIndex;
+    int simple, exact;		/* For extracting the type of regexp. */
+    int i;
+
+    /*
+     * Generate a test for each arm.
+     */
+
+    contFixIndex = -1;
+    contFixCount = 0;
+    fixupArray = TclStackAlloc(interp, sizeof(JumpFixup) * numBodyTokens);
+    fixupTargetArray = TclStackAlloc(interp, sizeof(int) * numBodyTokens);
+    memset(fixupTargetArray, 0, numBodyTokens * sizeof(int));
+    fixupCount = 0;
+    foundDefault = 0;
+    for (i=0 ; i<numBodyTokens ; i+=2) {
+	nextArmFixupIndex = -1;
+	if (i!=numBodyTokens-2 || bodyToken[numBodyTokens-2]->size != 7 ||
+		memcmp(bodyToken[numBodyTokens-2]->start, "default", 7)) {
+	    /*
+	     * Generate the test for the arm.
+	     */
+
+	    switch (mode) {
+	    case Switch_Exact:
+		OP(	DUP);
+		TclCompileTokens(interp, bodyToken[i], 1,	envPtr);
+		OP(	STR_EQ);
+		break;
+	    case Switch_Glob:
+		TclCompileTokens(interp, bodyToken[i], 1,	envPtr);
+		OP4(	OVER, 1);
+		OP1(	STR_MATCH, noCase);
+		break;
+	    case Switch_Regexp:
+		simple = exact = 0;
+
+		/*
+		 * Keep in sync with TclCompileRegexpCmd.
+		 */
+
+		if (bodyToken[i]->type == TCL_TOKEN_TEXT) {
+		    Tcl_DString ds;
+
+		    if (bodyToken[i]->size == 0) {
+			/*
+			 * The semantics of regexps are that they always match
+			 * when the RE == "".
+			 */
+
+			PUSH("1");
+			break;
+		    }
+
+		    /*
+		     * Attempt to convert pattern to glob. If successful, push
+		     * the converted pattern.
+		     */
+
+		    if (TclReToGlob(NULL, bodyToken[i]->start,
+			    bodyToken[i]->size, &ds, &exact, NULL) == TCL_OK){
+			simple = 1;
+			PushLiteral(envPtr, Tcl_DStringValue(&ds),
+				Tcl_DStringLength(&ds));
+			Tcl_DStringFree(&ds);
+		    }
+		}
+		if (!simple) {
+		    TclCompileTokens(interp, bodyToken[i], 1, envPtr);
+		}
+
+		OP4(	OVER, 1);
+		if (!simple) {
+		    /*
+		     * Pass correct RE compile flags. We use only Int1
+		     * (8-bit), but that handles all the flags we want to
+		     * pass. Don't use TCL_REG_NOSUB as we may have backrefs
+		     * or capture vars.
+		     */
+
+		    int cflags = TCL_REG_ADVANCED
+			    | (noCase ? TCL_REG_NOCASE : 0);
+
+		    OP1(REGEXP, cflags);
+		} else if (exact && !noCase) {
+		    OP(	STR_EQ);
+		} else {
+		    OP1(STR_MATCH, noCase);
+		}
+		break;
+	    default:
+		Tcl_Panic("unknown switch mode: %d", mode);
+	    }
+
+	    /*
+	     * In a fall-through case, we will jump on _true_ to the place
+	     * where the body starts (generated later, with guarantee of this
+	     * ensured earlier; the final body is never a fall-through).
+	     */
+
+	    if (bodyToken[i+1]->size==1 && bodyToken[i+1]->start[0]=='-') {
+		if (contFixIndex == -1) {
+		    contFixIndex = fixupCount;
+		    contFixCount = 0;
+		}
+		TclEmitForwardJump(envPtr, TCL_TRUE_JUMP,
+			&fixupArray[contFixIndex+contFixCount]);
+		fixupCount++;
+		contFixCount++;
+		continue;
+	    }
+
+	    TclEmitForwardJump(envPtr, TCL_FALSE_JUMP,
+		    &fixupArray[fixupCount]);
+	    nextArmFixupIndex = fixupCount;
+	    fixupCount++;
+	} else {
+	    /*
+	     * Got a default clause; set a flag to inhibit the generation of
+	     * the jump after the body and the cleanup of the intermediate
+	     * value that we are switching against.
+	     *
+	     * Note that default clauses (which are always terminal clauses)
+	     * cannot be fall-through clauses as well, since the last clause
+	     * is never a fall-through clause (which we have already
+	     * verified).
+	     */
+
+	    foundDefault = 1;
+	}
+
+	/*
+	 * Generate the body for the arm. This is guaranteed not to be a
+	 * fall-through case, but it might have preceding fall-through cases,
+	 * so we must process those first.
+	 */
+
+	if (contFixIndex != -1) {
+	    int j;
+
+	    for (j=0 ; j<contFixCount ; j++) {
+		fixupTargetArray[contFixIndex+j] = CurrentOffset(envPtr);
+	    }
+	    contFixIndex = -1;
+	}
+
+	/*
+	 * Now do the actual compilation. Note that we do not use BODY()
+	 * because we may have synthesized the tokens in a non-standard
+	 * pattern.
+	 */
+
+	OP(	POP);
+	envPtr->line = bodyLines[i+1];		/* TIP #280 */
+	envPtr->clNext = bodyContLines[i+1];	/* TIP #280 */
+	TclCompileCmdWord(interp, bodyToken[i+1], 1, envPtr);
+
+	if (!foundDefault) {
+	    TclEmitForwardJump(envPtr, TCL_UNCONDITIONAL_JUMP,
+		    &fixupArray[fixupCount]);
+	    fixupCount++;
+	    fixupTargetArray[nextArmFixupIndex] = CurrentOffset(envPtr);
+	}
+    }
+
+    /*
+     * Discard the value we are matching against unless we've had a default
+     * clause (in which case it will already be gone due to the code at the
+     * start of processing an arm, guaranteed) and make the result of the
+     * command an empty string.
+     */
+
+    if (!foundDefault) {
+	OP(	POP);
+	PUSH("");
+    }
+
+    /*
+     * Do jump fixups for arms that were executed. First, fill in the jumps of
+     * all jumps that don't point elsewhere to point to here.
+     */
+
+    for (i=0 ; i<fixupCount ; i++) {
+	if (fixupTargetArray[i] == 0) {
+	    fixupTargetArray[i] = envPtr->codeNext-envPtr->codeStart;
+	}
+    }
+
+    /*
+     * Now scan backwards over all the jumps (all of which are forward jumps)
+     * doing each one. When we do one and there is a size changes, we must
+     * scan back over all the previous ones and see if they need adjusting
+     * before proceeding with further jump fixups (the interleaved nature of
+     * all the jumps makes this impossible to do without nested loops).
+     */
+
+    for (i=fixupCount-1 ; i>=0 ; i--) {
+	if (TclFixupForwardJump(envPtr, &fixupArray[i],
+		fixupTargetArray[i] - fixupArray[i].codeOffset, 127)) {
+	    int j;
+
+	    for (j=i-1 ; j>=0 ; j--) {
+		if (fixupTargetArray[j] > fixupArray[i].codeOffset) {
+		    fixupTargetArray[j] += 3;
+		}
+	    }
+	}
+    }
+    TclStackFree(interp, fixupTargetArray);
+    TclStackFree(interp, fixupArray);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * IssueSwitchJumpTable --
+ *
+ *	Generate instructions for a [switch] command that is to be compiled
+ *	into a jump table. This only handles the case where case-sensitive,
+ *	exact matching is used, but this is actually the most common case in
+ *	real code.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+IssueSwitchJumpTable(
+    Tcl_Interp *interp,		/* Context for compiling script bodies. */
+    CompileEnv *envPtr,		/* Holds resulting instructions. */
+    int valueIndex,		/* The value to match against. */
+    int numBodyTokens,		/* Number of tokens describing things the
+				 * switch can match against and bodies to
+				 * execute when the match succeeds. */
+    Tcl_Token **bodyToken,	/* Array of pointers to pattern list items. */
+    int *bodyLines,		/* Array of line numbers for body list
+				 * items. */
+    int **bodyContLines)	/* Array of continuation line info. */
+{
+    JumptableInfo *jtPtr;
+    int infoIndex, isNew, *finalFixups, numRealBodies = 0, jumpLocation;
+    int mustGenerate, foundDefault, jumpToDefault, i;
+    Tcl_DString buffer;
+    Tcl_HashEntry *hPtr;
+
+    /*
+     * Compile the switch by using a jump table, which is basically a
+     * hashtable that maps from literal values to match against to the offset
+     * (relative to the INST_JUMP_TABLE instruction) to jump to. The jump
+     * table itself is independent of any invokation of the bytecode, and as
+     * such is stored in an auxData block.
+     *
+     * Start by allocating the jump table itself, plus some workspace.
+     */
+
+    jtPtr = ckalloc(sizeof(JumptableInfo));
+    Tcl_InitHashTable(&jtPtr->hashTable, TCL_STRING_KEYS);
+    infoIndex = TclCreateAuxData(jtPtr, &tclJumptableInfoType, envPtr);
+    finalFixups = TclStackAlloc(interp, sizeof(int) * (numBodyTokens/2));
+    foundDefault = 0;
+    mustGenerate = 1;
+
+    /*
+     * Next, issue the instruction to do the jump, together with what we want
+     * to do if things do not work out (jump to either the default clause or
+     * the "default" default, which just sets the result to empty). Note that
+     * we will come back and rewrite the jump's offset parameter when we know
+     * what it should be, and that all jumps we issue are of the wide kind
+     * because that makes the code much easier to debug!
+     */
+
+    jumpLocation = CurrentOffset(envPtr);
+    OP4(	JUMP_TABLE, infoIndex);
+    jumpToDefault = CurrentOffset(envPtr);
+    OP4(	JUMP4, 0);
+
+    for (i=0 ; i<numBodyTokens ; i+=2) {
+	/*
+	 * For each arm, we must first work out what to do with the match
+	 * term.
+	 */
+
+	if (i!=numBodyTokens-2 || bodyToken[numBodyTokens-2]->size != 7 ||
+		memcmp(bodyToken[numBodyTokens-2]->start, "default", 7)) {
+	    /*
+	     * This is not a default clause, so insert the current location as
+	     * a target in the jump table (assuming it isn't already there,
+	     * which would indicate that this clause is probably masked by an
+	     * earlier one). Note that we use a Tcl_DString here simply
+	     * because the hash API does not let us specify the string length.
+	     */
+
+	    Tcl_DStringInit(&buffer);
+	    TclDStringAppendToken(&buffer, bodyToken[i]);
+	    hPtr = Tcl_CreateHashEntry(&jtPtr->hashTable,
+		    Tcl_DStringValue(&buffer), &isNew);
+	    if (isNew) {
+		/*
+		 * First time we've encountered this match clause, so it must
+		 * point to here.
+		 */
+
+		Tcl_SetHashValue(hPtr, CurrentOffset(envPtr) - jumpLocation);
+	    }
+	    Tcl_DStringFree(&buffer);
+	} else {
+	    /*
+	     * This is a default clause, so patch up the fallthrough from the
+	     * INST_JUMP_TABLE instruction to here.
+	     */
+
+	    foundDefault = 1;
+	    isNew = 1;
+	    TclStoreInt4AtPtr(CurrentOffset(envPtr)-jumpToDefault,
+		    envPtr->codeStart+jumpToDefault+1);
+	}
+
+	/*
+	 * Now, for each arm we must deal with the body of the clause.
+	 *
+	 * If this is a continuation body (never true of a final clause,
+	 * whether default or not) we're done because the next jump target
+	 * will also point here, so we advance to the next clause.
+	 */
+
+	if (bodyToken[i+1]->size == 1 && bodyToken[i+1]->start[0] == '-') {
+	    mustGenerate = 1;
+	    continue;
+	}
+
+	/*
+	 * Also skip this arm if its only match clause is masked. (We could
+	 * probably be more aggressive about this, but that would be much more
+	 * difficult to get right.)
+	 */
+
+	if (!isNew && !mustGenerate) {
+	    continue;
+	}
+	mustGenerate = 0;
+
+	/*
+	 * Compile the body of the arm.
+	 */
+
+	envPtr->line = bodyLines[i+1];		/* TIP #280 */
+	envPtr->clNext = bodyContLines[i+1];	/* TIP #280 */
+	TclCompileCmdWord(interp, bodyToken[i+1], 1, envPtr);
+
+	/*
+	 * Compile a jump in to the end of the command if this body is
+	 * anything other than a user-supplied default arm (to either skip
+	 * over the remaining bodies or the code that generates an empty
+	 * result).
+	 */
+
+	if (i+2 < numBodyTokens || !foundDefault) {
+	    finalFixups[numRealBodies++] = CurrentOffset(envPtr);
+
+	    /*
+	     * Easier by far to issue this jump as a fixed-width jump, since
+	     * otherwise we'd need to do a lot more (and more awkward)
+	     * rewriting when we fixed this all up.
+	     */
+
+	    OP4(	JUMP4, 0);
+	    TclAdjustStackDepth(-1, envPtr);
+	}
+    }
+
+    /*
+     * We're at the end. If we've not already done so through the processing
+     * of a user-supplied default clause, add in a "default" default clause
+     * now.
+     */
+
+    if (!foundDefault) {
+	TclStoreInt4AtPtr(CurrentOffset(envPtr)-jumpToDefault,
+		envPtr->codeStart+jumpToDefault+1);
+	PUSH("");
+    }
+
+    /*
+     * No more instructions to be issued; everything that needs to jump to the
+     * end of the command is fixed up at this point.
+     */
+
+    for (i=0 ; i<numRealBodies ; i++) {
+	TclStoreInt4AtPtr(CurrentOffset(envPtr)-finalFixups[i],
+		envPtr->codeStart+finalFixups[i]+1);
+    }
+
+    /*
+     * Clean up all our temporary space and return.
+     */
+
+    TclStackFree(interp, finalFixups);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * DupJumptableInfo, FreeJumptableInfo --
+ *
+ *	Functions to duplicate, release and print a jump-table created for use
+ *	with the INST_JUMP_TABLE instruction.
+ *
+ * Results:
+ *	DupJumptableInfo: a copy of the jump-table
+ *	FreeJumptableInfo: none
+ *	PrintJumptableInfo: none
+ *	DisassembleJumptableInfo: none
+ *
+ * Side effects:
+ *	DupJumptableInfo: allocates memory
+ *	FreeJumptableInfo: releases memory
+ *	PrintJumptableInfo: none
+ *	DisassembleJumptableInfo: none
+ *
+ *----------------------------------------------------------------------
+ */
+
+static ClientData
+DupJumptableInfo(
+    ClientData clientData)
+{
+    JumptableInfo *jtPtr = clientData;
+    JumptableInfo *newJtPtr = ckalloc(sizeof(JumptableInfo));
+    Tcl_HashEntry *hPtr, *newHPtr;
+    Tcl_HashSearch search;
+    int isNew;
+
+    Tcl_InitHashTable(&newJtPtr->hashTable, TCL_STRING_KEYS);
+    hPtr = Tcl_FirstHashEntry(&jtPtr->hashTable, &search);
+    while (hPtr != NULL) {
+	newHPtr = Tcl_CreateHashEntry(&newJtPtr->hashTable,
+		Tcl_GetHashKey(&jtPtr->hashTable, hPtr), &isNew);
+	Tcl_SetHashValue(newHPtr, Tcl_GetHashValue(hPtr));
+    }
+    return newJtPtr;
+}
+
+static void
+FreeJumptableInfo(
+    ClientData clientData)
+{
+    JumptableInfo *jtPtr = clientData;
+
+    Tcl_DeleteHashTable(&jtPtr->hashTable);
+    ckfree(jtPtr);
+}
+
+static void
+PrintJumptableInfo(
+    ClientData clientData,
+    Tcl_Obj *appendObj,
+    ByteCode *codePtr,
+    unsigned int pcOffset)
+{
+    register JumptableInfo *jtPtr = clientData;
+    Tcl_HashEntry *hPtr;
+    Tcl_HashSearch search;
+    const char *keyPtr;
+    int offset, i = 0;
+
+    hPtr = Tcl_FirstHashEntry(&jtPtr->hashTable, &search);
+    for (; hPtr ; hPtr = Tcl_NextHashEntry(&search)) {
+	keyPtr = Tcl_GetHashKey(&jtPtr->hashTable, hPtr);
+	offset = PTR2INT(Tcl_GetHashValue(hPtr));
+
+	if (i++) {
+	    Tcl_AppendToObj(appendObj, ", ", -1);
+	    if (i%4==0) {
+		Tcl_AppendToObj(appendObj, "\n\t\t", -1);
+	    }
+	}
+	Tcl_AppendPrintfToObj(appendObj, "\"%s\"->pc %d",
+		keyPtr, pcOffset + offset);
+    }
+}
+
+static void
+DisassembleJumptableInfo(
+    ClientData clientData,
+    Tcl_Obj *dictObj,
+    ByteCode *codePtr,
+    unsigned int pcOffset)
+{
+    register JumptableInfo *jtPtr = clientData;
+    Tcl_Obj *mapping = Tcl_NewObj();
+    Tcl_HashEntry *hPtr;
+    Tcl_HashSearch search;
+    const char *keyPtr;
+    int offset;
+
+    hPtr = Tcl_FirstHashEntry(&jtPtr->hashTable, &search);
+    for (; hPtr ; hPtr = Tcl_NextHashEntry(&search)) {
+	keyPtr = Tcl_GetHashKey(&jtPtr->hashTable, hPtr);
+	offset = PTR2INT(Tcl_GetHashValue(hPtr));
+	Tcl_DictObjPut(NULL, mapping, Tcl_NewStringObj(keyPtr, -1),
+		Tcl_NewIntObj(offset));
+    }
+    Tcl_DictObjPut(NULL, dictObj, Tcl_NewStringObj("mapping", -1), mapping);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclCompileTailcallCmd --
+ *
+ *	Procedure called to compile the "tailcall" command.
+ *
+ * Results:
+ *	Returns TCL_OK for a successful compile. Returns TCL_ERROR to defer
+ *	evaluation to runtime.
+ *
+ * Side effects:
+ *	Instructions are added to envPtr to execute the "tailcall" command at
+ *	runtime.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclCompileTailcallCmd(
+    Tcl_Interp *interp,		/* Used for error reporting. */
+    Tcl_Parse *parsePtr,	/* Points to a parse structure for the command
+				 * created by Tcl_ParseCommand. */
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)		/* Holds resulting instructions. */
+{
+    DefineLineInformation;	/* TIP #280 */
+    Tcl_Token *tokenPtr = parsePtr->tokenPtr;
+    int i;
+
+    if (parsePtr->numWords < 2 || parsePtr->numWords > 256
+	    || envPtr->procPtr == NULL) {
+	return TCL_ERROR;
+    }
+
+    /* make room for the nsObjPtr */
+    /* TODO: Doesn't this have to be a known value? */
+    CompileWord(envPtr, tokenPtr, interp, 0);
+    for (i=1 ; i<parsePtr->numWords ; i++) {
+	tokenPtr = TokenAfter(tokenPtr);
+	CompileWord(envPtr, tokenPtr, interp, i);
+    }
+    TclEmitInstInt1(	INST_TAILCALL, parsePtr->numWords,	envPtr);
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclCompileThrowCmd --
+ *
+ *	Procedure called to compile the "throw" command.
+ *
+ * Results:
+ *	Returns TCL_OK for a successful compile. Returns TCL_ERROR to defer
+ *	evaluation to runtime.
+ *
+ * Side effects:
+ *	Instructions are added to envPtr to execute the "throw" command at
+ *	runtime.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclCompileThrowCmd(
+    Tcl_Interp *interp,		/* Used for error reporting. */
+    Tcl_Parse *parsePtr,	/* Points to a parse structure for the command
+				 * created by Tcl_ParseCommand. */
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)		/* Holds resulting instructions. */
+{
+    DefineLineInformation;	/* TIP #280 */
+    int numWords = parsePtr->numWords;
+    Tcl_Token *codeToken, *msgToken;
+    Tcl_Obj *objPtr;
+    int codeKnown, codeIsList, codeIsValid, len;
+
+    if (numWords != 3) {
+	return TCL_ERROR;
+    }
+    codeToken = TokenAfter(parsePtr->tokenPtr);
+    msgToken = TokenAfter(codeToken);
+
+    TclNewObj(objPtr);
+    Tcl_IncrRefCount(objPtr);
+
+    codeKnown = TclWordKnownAtCompileTime(codeToken, objPtr);
+
+    /*
+     * First we must emit the code to substitute the arguments.  This
+     * must come first in case substitution raises errors.
+     */
+    if (!codeKnown) {
+	CompileWord(envPtr, codeToken, interp, 1);
+	PUSH(			"-errorcode");
+    }
+    CompileWord(envPtr, msgToken, interp, 2);
+
+    codeIsList = codeKnown && (TCL_OK ==
+	    Tcl_ListObjLength(interp, objPtr, &len));
+    codeIsValid = codeIsList && (len != 0);
+
+    if (codeIsValid) {
+	Tcl_Obj *errPtr, *dictPtr;
+
+	TclNewLiteralStringObj(errPtr, "-errorcode");
+	TclNewObj(dictPtr);
+	Tcl_DictObjPut(NULL, dictPtr, errPtr, objPtr);
+	TclEmitPush(TclAddLiteralObj(envPtr, dictPtr, NULL), envPtr);
+    }
+    TclDecrRefCount(objPtr);
+
+    /*
+     * Simpler bytecodes when we detect invalid arguments at compile time.
+     */
+    if (codeKnown && !codeIsValid) {
+	OP(			POP);
+	if (codeIsList) {
+	    /* Must be an empty list */
+	    goto issueErrorForEmptyCode;
+	}
+	TclCompileSyntaxError(interp, envPtr);
+	return TCL_OK;
+    }
+
+    if (!codeKnown) {
+	/*
+	 * Argument validity checking has to be done by bytecode at
+	 * run time.
+	 */
+	OP4(			REVERSE, 3);
+	OP(			DUP);
+	OP(			LIST_LENGTH);
+	OP1(			JUMP_FALSE1, 16);
+	OP4(			LIST, 2);
+	OP44(			RETURN_IMM, TCL_ERROR, 0);
+	TclAdjustStackDepth(2, envPtr);
+	OP(			POP);
+	OP(			POP);
+	OP(			POP);
+    issueErrorForEmptyCode:
+	PUSH(			"type must be non-empty list");
+	PUSH(			"-errorcode {TCL OPERATION THROW BADEXCEPTION}");
+    }
+    OP44(			RETURN_IMM, TCL_ERROR, 0);
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclCompileTryCmd --
+ *
+ *	Procedure called to compile the "try" command.
+ *
+ * Results:
+ *	Returns TCL_OK for a successful compile. Returns TCL_ERROR to defer
+ *	evaluation to runtime.
+ *
+ * Side effects:
+ *	Instructions are added to envPtr to execute the "try" command at
+ *	runtime.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclCompileTryCmd(
+    Tcl_Interp *interp,		/* Used for error reporting. */
+    Tcl_Parse *parsePtr,	/* Points to a parse structure for the command
+				 * created by Tcl_ParseCommand. */
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)		/* Holds resulting instructions. */
+{
+    int numWords = parsePtr->numWords, numHandlers, result = TCL_ERROR;
+    Tcl_Token *bodyToken, *finallyToken, *tokenPtr;
+    Tcl_Token **handlerTokens = NULL;
+    Tcl_Obj **matchClauses = NULL;
+    int *matchCodes=NULL, *resultVarIndices=NULL, *optionVarIndices=NULL;
+    int i;
+
+    if (numWords < 2) {
+	return TCL_ERROR;
+    }
+
+    bodyToken = TokenAfter(parsePtr->tokenPtr);
+
+    if (numWords == 2) {
+	/*
+	 * No handlers or finally; do nothing beyond evaluating the body.
+	 */
+
+	DefineLineInformation;	/* TIP #280 */
+	BODY(bodyToken, 1);
+	return TCL_OK;
+    }
+
+    numWords -= 2;
+    tokenPtr = TokenAfter(bodyToken);
+
+    /*
+     * Extract information about what handlers there are.
+     */
+
+    numHandlers = numWords >> 2;
+    numWords -= numHandlers * 4;
+    if (numHandlers > 0) {
+	handlerTokens = TclStackAlloc(interp, sizeof(Tcl_Token*)*numHandlers);
+	matchClauses = TclStackAlloc(interp, sizeof(Tcl_Obj *) * numHandlers);
+	memset(matchClauses, 0, sizeof(Tcl_Obj *) * numHandlers);
+	matchCodes = TclStackAlloc(interp, sizeof(int) * numHandlers);
+	resultVarIndices = TclStackAlloc(interp, sizeof(int) * numHandlers);
+	optionVarIndices = TclStackAlloc(interp, sizeof(int) * numHandlers);
+
+	for (i=0 ; i<numHandlers ; i++) {
+	    Tcl_Obj *tmpObj, **objv;
+	    int objc;
+
+	    if (tokenPtr->type != TCL_TOKEN_SIMPLE_WORD) {
+		goto failedToCompile;
+	    }
+	    if (tokenPtr[1].size == 4
+		    && !strncmp(tokenPtr[1].start, "trap", 4)) {
+		/*
+		 * Parse the list of errorCode words to match against.
+		 */
+
+		matchCodes[i] = TCL_ERROR;
+		tokenPtr = TokenAfter(tokenPtr);
+		TclNewObj(tmpObj);
+		Tcl_IncrRefCount(tmpObj);
+		if (!TclWordKnownAtCompileTime(tokenPtr, tmpObj)
+			|| Tcl_ListObjLength(NULL, tmpObj, &objc) != TCL_OK
+			|| (objc == 0)) {
+		    TclDecrRefCount(tmpObj);
+		    goto failedToCompile;
+		}
+		Tcl_ListObjReplace(NULL, tmpObj, 0, 0, 0, NULL);
+		matchClauses[i] = tmpObj;
+	    } else if (tokenPtr[1].size == 2
+		    && !strncmp(tokenPtr[1].start, "on", 2)) {
+		int code;
+
+		/*
+		 * Parse the result code to look for.
+		 */
+
+		tokenPtr = TokenAfter(tokenPtr);
+		TclNewObj(tmpObj);
+		Tcl_IncrRefCount(tmpObj);
+		if (!TclWordKnownAtCompileTime(tokenPtr, tmpObj)) {
+		    TclDecrRefCount(tmpObj);
+		    goto failedToCompile;
+		}
+		if (TCL_ERROR == TclGetCompletionCodeFromObj(NULL, tmpObj, &code)) {
+		    TclDecrRefCount(tmpObj);
+		    goto failedToCompile;
+		}
+		matchCodes[i] = code;
+		TclDecrRefCount(tmpObj);
+	    } else {
+		goto failedToCompile;
+	    }
+
+	    /*
+	     * Parse the variable binding.
+	     */
+
+	    tokenPtr = TokenAfter(tokenPtr);
+	    TclNewObj(tmpObj);
+	    Tcl_IncrRefCount(tmpObj);
+	    if (!TclWordKnownAtCompileTime(tokenPtr, tmpObj)) {
+		TclDecrRefCount(tmpObj);
+		goto failedToCompile;
+	    }
+	    if (Tcl_ListObjGetElements(NULL, tmpObj, &objc, &objv) != TCL_OK
+		    || (objc > 2)) {
+		TclDecrRefCount(tmpObj);
+		goto failedToCompile;
+	    }
+	    if (objc > 0) {
+		int len;
+		const char *varname = Tcl_GetStringFromObj(objv[0], &len);
+
+		resultVarIndices[i] = LocalScalar(varname, len, envPtr);
+		if (resultVarIndices[i] < 0) {
+		    TclDecrRefCount(tmpObj);
+		    goto failedToCompile;
+		}
+	    } else {
+		resultVarIndices[i] = -1;
+	    }
+	    if (objc == 2) {
+		int len;
+		const char *varname = Tcl_GetStringFromObj(objv[1], &len);
+
+		optionVarIndices[i] = LocalScalar(varname, len, envPtr);
+		if (optionVarIndices[i] < 0) {
+		    TclDecrRefCount(tmpObj);
+		    goto failedToCompile;
+		}
+	    } else {
+		optionVarIndices[i] = -1;
+	    }
+	    TclDecrRefCount(tmpObj);
+
+	    /*
+	     * Extract the body for this handler.
+	     */
+
+	    tokenPtr = TokenAfter(tokenPtr);
+	    if (tokenPtr->type != TCL_TOKEN_SIMPLE_WORD) {
+		goto failedToCompile;
+	    }
+	    if (tokenPtr[1].size == 1 && tokenPtr[1].start[0] == '-') {
+		handlerTokens[i] = NULL;
+	    } else {
+		handlerTokens[i] = tokenPtr;
+	    }
+
+	    tokenPtr = TokenAfter(tokenPtr);
+	}
+
+	if (handlerTokens[numHandlers-1] == NULL) {
+	    goto failedToCompile;
+	}
+    }
+
+    /*
+     * Parse the finally clause
+     */
+
+    if (numWords == 0) {
+	finallyToken = NULL;
+    } else if (numWords == 2) {
+	if (tokenPtr->type != TCL_TOKEN_SIMPLE_WORD || tokenPtr[1].size != 7
+		|| strncmp(tokenPtr[1].start, "finally", 7)) {
+	    goto failedToCompile;
+	}
+	finallyToken = TokenAfter(tokenPtr);
+    } else {
+	goto failedToCompile;
+    }
+
+    /*
+     * Issue the bytecode.
+     */
+
+    if (!finallyToken) {
+	result = IssueTryClausesInstructions(interp, envPtr, bodyToken,
+		numHandlers, matchCodes, matchClauses, resultVarIndices,
+		optionVarIndices, handlerTokens);
+    } else if (numHandlers == 0) {
+	result = IssueTryFinallyInstructions(interp, envPtr, bodyToken,
+		finallyToken);
+    } else {
+	result = IssueTryClausesFinallyInstructions(interp, envPtr, bodyToken,
+		numHandlers, matchCodes, matchClauses, resultVarIndices,
+		optionVarIndices, handlerTokens, finallyToken);
+    }
+
+    /*
+     * Delete any temporary state and finish off.
+     */
+
+  failedToCompile:
+    if (numHandlers > 0) {
+	for (i=0 ; i<numHandlers ; i++) {
+	    if (matchClauses[i]) {
+		TclDecrRefCount(matchClauses[i]);
+	    }
+	}
+	TclStackFree(interp, optionVarIndices);
+	TclStackFree(interp, resultVarIndices);
+	TclStackFree(interp, matchCodes);
+	TclStackFree(interp, matchClauses);
+	TclStackFree(interp, handlerTokens);
+    }
+    return result;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * IssueTryClausesInstructions, IssueTryClausesFinallyInstructions,
+ * IssueTryFinallyInstructions --
+ *
+ *	The code generators for [try]. Split from the parsing engine for
+ *	reasons of developer sanity, and also split between no-finally,
+ *	just-finally and with-finally cases because so many of the details of
+ *	generation vary between the three.
+ *
+ *	The macros below make the instruction issuing easier to follow.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+IssueTryClausesInstructions(
+    Tcl_Interp *interp,
+    CompileEnv *envPtr,
+    Tcl_Token *bodyToken,
+    int numHandlers,
+    int *matchCodes,
+    Tcl_Obj **matchClauses,
+    int *resultVars,
+    int *optionVars,
+    Tcl_Token **handlerTokens)
+{
+    DefineLineInformation;	/* TIP #280 */
+    int range, resultVar, optionsVar;
+    int i, j, len, forwardsNeedFixing = 0, trapZero = 0, afterBody = 0;
+    int *addrsToFix, *forwardsToFix, notCodeJumpSource, notECJumpSource;
+    int *noError;
+    char buf[TCL_INTEGER_SPACE];
+
+    resultVar = AnonymousLocal(envPtr);
+    optionsVar = AnonymousLocal(envPtr);
+    if (resultVar < 0 || optionsVar < 0) {
+	return TCL_ERROR;
+    }
+
+    /*
+     * Check if we're supposed to trap a normal TCL_OK completion of the body.
+     * If not, we can handle that case much more efficiently.
+     */
+
+    for (i=0 ; i<numHandlers ; i++) {
+	if (matchCodes[i] == 0) {
+	    trapZero = 1;
+	    break;
+	}
+    }
+
+    /*
+     * Compile the body, trapping any error in it so that we can trap on it
+     * and/or run a finally clause. Note that there must be at least one
+     * on/trap clause; when none is present, this whole function is not called
+     * (and it's never called when there's a finally clause).
+     */
+
+    range = TclCreateExceptRange(CATCH_EXCEPTION_RANGE, envPtr);
+    OP4(				BEGIN_CATCH4, range);
+    ExceptionRangeStarts(envPtr, range);
+    BODY(				bodyToken, 1);
+    ExceptionRangeEnds(envPtr, range);
+    if (!trapZero) {
+	OP(				END_CATCH);
+	JUMP4(				JUMP, afterBody);
+	TclAdjustStackDepth(-1, envPtr);
+    } else {
+	PUSH(				"0");
+	OP4(				REVERSE, 2);
+	OP1(				JUMP1, 4);
+	TclAdjustStackDepth(-2, envPtr);
+    }
+    ExceptionRangeTarget(envPtr, range, catchOffset);
+    OP(					PUSH_RETURN_CODE);
+    OP(					PUSH_RESULT);
+    OP(					PUSH_RETURN_OPTIONS);
+    OP(					END_CATCH);
+    STORE(				optionsVar);
+    OP(					POP);
+    STORE(				resultVar);
+    OP(					POP);
+
+    /*
+     * Now we handle all the registered 'on' and 'trap' handlers in order.
+     * For us to be here, there must be at least one handler.
+     *
+     * Slight overallocation, but reduces size of this function.
+     */
+
+    addrsToFix = TclStackAlloc(interp, sizeof(int)*numHandlers);
+    forwardsToFix = TclStackAlloc(interp, sizeof(int)*numHandlers);
+    noError = TclStackAlloc(interp, sizeof(int)*numHandlers);
+
+    for (i=0 ; i<numHandlers ; i++) {
+	noError[i] = -1;
+	sprintf(buf, "%d", matchCodes[i]);
+	OP(				DUP);
+	PushLiteral(envPtr, buf, strlen(buf));
+	OP(				EQ);
+	JUMP4(				JUMP_FALSE, notCodeJumpSource);
+	if (matchClauses[i]) {
+	    const char *p;
+	    Tcl_ListObjLength(NULL, matchClauses[i], &len);
+
+	    /*
+	     * Match the errorcode according to try/trap rules.
+	     */
+
+	    LOAD(			optionsVar);
+	    PUSH(			"-errorcode");
+	    OP4(			DICT_GET, 1);
+	    TclAdjustStackDepth(-1, envPtr);
+	    OP44(			LIST_RANGE_IMM, 0, len-1);
+	    p = Tcl_GetStringFromObj(matchClauses[i], &len);
+	    PushLiteral(envPtr, p, len);
+	    OP(				STR_EQ);
+	    JUMP4(			JUMP_FALSE, notECJumpSource);
+	} else {
+	    notECJumpSource = -1; /* LINT */
+	}
+	OP(				POP);
+
+	/*
+	 * There is no finally clause, so we can avoid wrapping a catch
+	 * context around the handler. That simplifies what instructions need
+	 * to be issued a lot since we can let errors just fall through.
+	 */
+
+	if (resultVars[i] >= 0) {
+	    LOAD(			resultVar);
+	    STORE(			resultVars[i]);
+	    OP(				POP);
+	    if (optionVars[i] >= 0) {
+		LOAD(			optionsVar);
+		STORE(			optionVars[i]);
+		OP(			POP);
+	    }
+	}
+	if (!handlerTokens[i]) {
+	    forwardsNeedFixing = 1;
+	    JUMP4(			JUMP, forwardsToFix[i]);
+	    TclAdjustStackDepth(1, envPtr);
+	} else {
+	    int dontChangeOptions;
+
+	    forwardsToFix[i] = -1;
+	    if (forwardsNeedFixing) {
+		forwardsNeedFixing = 0;
+		for (j=0 ; j<i ; j++) {
+		    if (forwardsToFix[j] == -1) {
+			continue;
+		    }
+		    FIXJUMP4(forwardsToFix[j]);
+		    forwardsToFix[j] = -1;
+		}
+	    }
+	    range = TclCreateExceptRange(CATCH_EXCEPTION_RANGE, envPtr);
+	    OP4(			BEGIN_CATCH4, range);
+	    ExceptionRangeStarts(envPtr, range);
+	    BODY(			handlerTokens[i], 5+i*4);
+	    ExceptionRangeEnds(envPtr, range);
+	    OP(				END_CATCH);
+	    JUMP4(			JUMP, noError[i]);
+	    ExceptionRangeTarget(envPtr, range, catchOffset);
+	    TclAdjustStackDepth(-1, envPtr);
+	    OP(				PUSH_RESULT);
+	    OP(				PUSH_RETURN_OPTIONS);
+	    OP(				PUSH_RETURN_CODE);
+	    OP(				END_CATCH);
+	    PUSH(			"1");
+	    OP(				EQ);
+	    JUMP1(			JUMP_FALSE, dontChangeOptions);
+	    LOAD(			optionsVar);
+	    OP4(			REVERSE, 2);
+	    STORE(			optionsVar);
+	    OP(				POP);
+	    PUSH(			"-during");
+	    OP4(			REVERSE, 2);
+	    OP44(			DICT_SET, 1, optionsVar);
+	    TclAdjustStackDepth(-1, envPtr);
+	    FIXJUMP1(		dontChangeOptions);
+	    OP4(			REVERSE, 2);
+	    INVOKE(			RETURN_STK);
+	}
+
+	JUMP4(				JUMP, addrsToFix[i]);
+	if (matchClauses[i]) {
+	    FIXJUMP4(	notECJumpSource);
+	}
+	FIXJUMP4(	notCodeJumpSource);
+    }
+
+    /*
+     * Drop the result code since it didn't match any clause, and reissue the
+     * exception. Note also that INST_RETURN_STK can proceed to the next
+     * instruction.
+     */
+
+    OP(					POP);
+    LOAD(				optionsVar);
+    LOAD(				resultVar);
+    INVOKE(				RETURN_STK);
+
+    /*
+     * Fix all the jumps from taken clauses to here (which is the end of the
+     * [try]).
+     */
+
+    if (!trapZero) {
+	FIXJUMP4(afterBody);
+    }
+    for (i=0 ; i<numHandlers ; i++) {
+	FIXJUMP4(addrsToFix[i]);
+	if (noError[i] != -1) {
+	    FIXJUMP4(noError[i]);
+	}
+    }
+    TclStackFree(interp, noError);
+    TclStackFree(interp, forwardsToFix);
+    TclStackFree(interp, addrsToFix);
+    return TCL_OK;
+}
+
+static int
+IssueTryClausesFinallyInstructions(
+    Tcl_Interp *interp,
+    CompileEnv *envPtr,
+    Tcl_Token *bodyToken,
+    int numHandlers,
+    int *matchCodes,
+    Tcl_Obj **matchClauses,
+    int *resultVars,
+    int *optionVars,
+    Tcl_Token **handlerTokens,
+    Tcl_Token *finallyToken)	/* Not NULL */
+{
+    DefineLineInformation;	/* TIP #280 */
+    int range, resultVar, optionsVar, i, j, len, forwardsNeedFixing = 0;
+    int trapZero = 0, afterBody = 0, finalOK, finalError, noFinalError;
+    int *addrsToFix, *forwardsToFix, notCodeJumpSource, notECJumpSource;
+    char buf[TCL_INTEGER_SPACE];
+
+    resultVar = AnonymousLocal(envPtr);
+    optionsVar = AnonymousLocal(envPtr);
+    if (resultVar < 0 || optionsVar < 0) {
+	return TCL_ERROR;
+    }
+
+    /*
+     * Check if we're supposed to trap a normal TCL_OK completion of the body.
+     * If not, we can handle that case much more efficiently.
+     */
+
+    for (i=0 ; i<numHandlers ; i++) {
+	if (matchCodes[i] == 0) {
+	    trapZero = 1;
+	    break;
+	}
+    }
+
+    /*
+     * Compile the body, trapping any error in it so that we can trap on it
+     * (if any trap matches) and run a finally clause.
+     */
+
+    range = TclCreateExceptRange(CATCH_EXCEPTION_RANGE, envPtr);
+    OP4(				BEGIN_CATCH4, range);
+    ExceptionRangeStarts(envPtr, range);
+    BODY(				bodyToken, 1);
+    ExceptionRangeEnds(envPtr, range);
+    if (!trapZero) {
+	OP(				END_CATCH);
+	STORE(				resultVar);
+	OP(				POP);
+	PUSH(				"-level 0 -code 0");
+	STORE(				optionsVar);
+	OP(				POP);
+	JUMP4(				JUMP, afterBody);
+    } else {
+	PUSH(				"0");
+	OP4(				REVERSE, 2);
+	OP1(				JUMP1, 4);
+	TclAdjustStackDepth(-2, envPtr);
+    }
+    ExceptionRangeTarget(envPtr, range, catchOffset);
+    OP(					PUSH_RETURN_CODE);
+    OP(					PUSH_RESULT);
+    OP(					PUSH_RETURN_OPTIONS);
+    OP(					END_CATCH);
+    STORE(				optionsVar);
+    OP(					POP);
+    STORE(				resultVar);
+    OP(					POP);
+
+    /*
+     * Now we handle all the registered 'on' and 'trap' handlers in order.
+     *
+     * Slight overallocation, but reduces size of this function.
+     */
+
+    addrsToFix = TclStackAlloc(interp, sizeof(int)*numHandlers);
+    forwardsToFix = TclStackAlloc(interp, sizeof(int)*numHandlers);
+
+    for (i=0 ; i<numHandlers ; i++) {
+	int noTrapError, trapError;
+	const char *p;
+
+	sprintf(buf, "%d", matchCodes[i]);
+	OP(				DUP);
+	PushLiteral(envPtr, buf, strlen(buf));
+	OP(				EQ);
+	JUMP4(				JUMP_FALSE, notCodeJumpSource);
+	if (matchClauses[i]) {
+	    Tcl_ListObjLength(NULL, matchClauses[i], &len);
+
+	    /*
+	     * Match the errorcode according to try/trap rules.
+	     */
+
+	    LOAD(			optionsVar);
+	    PUSH(			"-errorcode");
+	    OP4(			DICT_GET, 1);
+	    TclAdjustStackDepth(-1, envPtr);
+	    OP44(			LIST_RANGE_IMM, 0, len-1);
+	    p = Tcl_GetStringFromObj(matchClauses[i], &len);
+	    PushLiteral(envPtr, p, len);
+	    OP(				STR_EQ);
+	    JUMP4(			JUMP_FALSE, notECJumpSource);
+	} else {
+	    notECJumpSource = -1; /* LINT */
+	}
+	OP(				POP);
+
+	/*
+	 * There is a finally clause, so we need a fairly complex sequence of
+	 * instructions to deal with an on/trap handler because we must call
+	 * the finally handler *and* we need to substitute the result from a
+	 * failed trap for the result from the main script.
+	 */
+
+	if (resultVars[i] >= 0 || handlerTokens[i]) {
+	    range = TclCreateExceptRange(CATCH_EXCEPTION_RANGE, envPtr);
+	    OP4(			BEGIN_CATCH4, range);
+	    ExceptionRangeStarts(envPtr, range);
+	}
+	if (resultVars[i] >= 0) {
+	    LOAD(			resultVar);
+	    STORE(			resultVars[i]);
+	    OP(				POP);
+	    if (optionVars[i] >= 0) {
+		LOAD(			optionsVar);
+		STORE(			optionVars[i]);
+		OP(			POP);
+	    }
+
+	    if (!handlerTokens[i]) {
+		/*
+		 * No handler. Will not be the last handler (that is a
+		 * condition that is checked by the caller). Chain to the next
+		 * one.
+		 */
+
+		ExceptionRangeEnds(envPtr, range);
+		OP(			END_CATCH);
+		forwardsNeedFixing = 1;
+		JUMP4(			JUMP, forwardsToFix[i]);
+		goto finishTrapCatchHandling;
+	    }
+	} else if (!handlerTokens[i]) {
+	    /*
+	     * No handler. Will not be the last handler (that condition is
+	     * checked by the caller). Chain to the next one.
+	     */
+
+	    forwardsNeedFixing = 1;
+	    JUMP4(			JUMP, forwardsToFix[i]);
+	    goto endOfThisArm;
+	}
+
+	/*
+	 * Got a handler. Make sure that any pending patch-up actions from
+	 * previous unprocessed handlers are dealt with now that we know where
+	 * they are to jump to.
+	 */
+
+	if (forwardsNeedFixing) {
+	    forwardsNeedFixing = 0;
+	    OP1(			JUMP1, 7);
+	    for (j=0 ; j<i ; j++) {
+		if (forwardsToFix[j] == -1) {
+		    continue;
+		}
+		FIXJUMP4(	forwardsToFix[j]);
+		forwardsToFix[j] = -1;
+	    }
+	    OP4(			BEGIN_CATCH4, range);
+	}
+	BODY(				handlerTokens[i], 5+i*4);
+	ExceptionRangeEnds(envPtr, range);
+	PUSH(				"0");
+	OP(				PUSH_RETURN_OPTIONS);
+	OP4(				REVERSE, 3);
+	OP1(				JUMP1, 5);
+	TclAdjustStackDepth(-3, envPtr);
+	forwardsToFix[i] = -1;
+
+	/*
+	 * Error in handler or setting of variables; replace the stored
+	 * exception with the new one. Note that we only push this if we have
+	 * either a body or some variable setting here. Otherwise this code is
+	 * unreachable.
+	 */
+
+    finishTrapCatchHandling:
+	ExceptionRangeTarget(envPtr, range, catchOffset);
+	OP(				PUSH_RETURN_OPTIONS);
+	OP(				PUSH_RETURN_CODE);
+	OP(				PUSH_RESULT);
+	OP(				END_CATCH);
+	STORE(				resultVar);
+	OP(				POP);
+	PUSH(				"1");
+	OP(				EQ);
+	JUMP1(				JUMP_FALSE, noTrapError);
+	LOAD(				optionsVar);
+	PUSH(				"-during");
+	OP4(				REVERSE, 3);
+	STORE(				optionsVar);
+	OP(				POP);
+	OP44(				DICT_SET, 1, optionsVar);
+	TclAdjustStackDepth(-1, envPtr);
+	JUMP1(				JUMP, trapError);
+	FIXJUMP1(		noTrapError);
+	STORE(				optionsVar);
+	FIXJUMP1(		trapError);
+	/* Skip POP at end; can clean up with subsequent POP */
+	if (i+1 < numHandlers) {
+	    OP(				POP);
+	}
+
+    endOfThisArm:
+	if (i+1 < numHandlers) {
+	    JUMP4(			JUMP, addrsToFix[i]);
+	    TclAdjustStackDepth(1, envPtr);
+	}
+	if (matchClauses[i]) {
+	    FIXJUMP4(		notECJumpSource);
+	}
+	FIXJUMP4(		notCodeJumpSource);
+    }
+
+    /*
+     * Drop the result code, and fix all the jumps from taken clauses - which
+     * drop the result code as their first action - to point straight after
+     * (i.e., to the start of the finally clause).
+     */
+
+    OP(					POP);
+    for (i=0 ; i<numHandlers-1 ; i++) {
+	FIXJUMP4(		addrsToFix[i]);
+    }
+    TclStackFree(interp, forwardsToFix);
+    TclStackFree(interp, addrsToFix);
+
+    /*
+     * Process the finally clause (at last!) Note that we do not wrap this in
+     * error handlers because we would just rethrow immediately anyway. Then
+     * (on normal success) we reissue the exception. Note also that
+     * INST_RETURN_STK can proceed to the next instruction; that'll be the
+     * next command (or some inter-command manipulation).
+     */
+
+    if (!trapZero) {
+	FIXJUMP4(		afterBody);
+    }
+    range = TclCreateExceptRange(CATCH_EXCEPTION_RANGE, envPtr);
+    OP4(				BEGIN_CATCH4, range);
+    ExceptionRangeStarts(envPtr, range);
+    BODY(				finallyToken, 3 + 4*numHandlers);
+    ExceptionRangeEnds(envPtr, range);
+    OP(					END_CATCH);
+    OP(					POP);
+    JUMP1(				JUMP, finalOK);
+    ExceptionRangeTarget(envPtr, range, catchOffset);
+    OP(					PUSH_RESULT);
+    OP(					PUSH_RETURN_OPTIONS);
+    OP(					PUSH_RETURN_CODE);
+    OP(					END_CATCH);
+    PUSH(				"1");
+    OP(					EQ);
+    JUMP1(				JUMP_FALSE, noFinalError);
+    LOAD(				optionsVar);
+    PUSH(				"-during");
+    OP4(				REVERSE, 3);
+    STORE(				optionsVar);
+    OP(					POP);
+    OP44(				DICT_SET, 1, optionsVar);
+    TclAdjustStackDepth(-1, envPtr);
+    OP(					POP);
+    JUMP1(				JUMP, finalError);
+    TclAdjustStackDepth(1, envPtr);
+    FIXJUMP1(			noFinalError);
+    STORE(				optionsVar);
+    OP(					POP);
+    FIXJUMP1(			finalError);
+    STORE(				resultVar);
+    OP(					POP);
+    FIXJUMP1(			finalOK);
+    LOAD(				optionsVar);
+    LOAD(				resultVar);
+    INVOKE(				RETURN_STK);
+
+    return TCL_OK;
+}
+
+static int
+IssueTryFinallyInstructions(
+    Tcl_Interp *interp,
+    CompileEnv *envPtr,
+    Tcl_Token *bodyToken,
+    Tcl_Token *finallyToken)
+{
+    DefineLineInformation;	/* TIP #280 */
+    int range, jumpOK, jumpSplice;
+
+    /*
+     * Note that this one is simple enough that we can issue it without
+     * needing a local variable table, making it a universal compilation.
+     */
+
+    range = TclCreateExceptRange(CATCH_EXCEPTION_RANGE, envPtr);
+    OP4(				BEGIN_CATCH4, range);
+    ExceptionRangeStarts(envPtr, range);
+    BODY(				bodyToken, 1);
+    ExceptionRangeEnds(envPtr, range);
+    OP1(				JUMP1, 3);
+    TclAdjustStackDepth(-1, envPtr);
+    ExceptionRangeTarget(envPtr, range, catchOffset);
+    OP(					PUSH_RESULT);
+    OP(					PUSH_RETURN_OPTIONS);
+    OP(					END_CATCH);
+
+    range = TclCreateExceptRange(CATCH_EXCEPTION_RANGE, envPtr);
+    OP4(				BEGIN_CATCH4, range);
+    ExceptionRangeStarts(envPtr, range);
+    BODY(				finallyToken, 3);
+    ExceptionRangeEnds(envPtr, range);
+    OP(					END_CATCH);
+    OP(					POP);
+    JUMP1(				JUMP, jumpOK);
+    ExceptionRangeTarget(envPtr, range, catchOffset);
+    OP(					PUSH_RESULT);
+    OP(					PUSH_RETURN_OPTIONS);
+    OP(					PUSH_RETURN_CODE);
+    OP(					END_CATCH);
+    PUSH(				"1");
+    OP(					EQ);
+    JUMP1(				JUMP_FALSE, jumpSplice);
+    PUSH(				"-during");
+    OP4(				OVER, 3);
+    OP4(				LIST, 2);
+    OP(					LIST_CONCAT);
+    FIXJUMP1(		jumpSplice);
+    OP4(				REVERSE, 4);
+    OP(					POP);
+    OP(					POP);
+    OP1(				JUMP1, 7);
+    FIXJUMP1(		jumpOK);
+    OP4(				REVERSE, 2);
+    INVOKE(				RETURN_STK);
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclCompileUnsetCmd --
+ *
+ *	Procedure called to compile the "unset" command.
+ *
+ * Results:
+ *	Returns TCL_OK for a successful compile. Returns TCL_ERROR to defer
+ *	evaluation to runtime.
+ *
+ * Side effects:
+ *	Instructions are added to envPtr to execute the "unset" command at
+ *	runtime.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclCompileUnsetCmd(
+    Tcl_Interp *interp,		/* Used for error reporting. */
+    Tcl_Parse *parsePtr,	/* Points to a parse structure for the command
+				 * created by Tcl_ParseCommand. */
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)		/* Holds resulting instructions. */
+{
+    Tcl_Token *varTokenPtr;
+    int isScalar, localIndex, flags = 1, i, varCount = 0, haveFlags = 0;
+    DefineLineInformation;	/* TIP #280 */
+
+    /* TODO: Consider support for compiling expanded args. */
+
+    /*
+     * Verify that all words - except the first non-option one - are known at
+     * compile time so that we can handle them without needing to do a nasty
+     * push/rotate. [Bug 3970f54c4e]
+     */
+
+    for (i=1,varTokenPtr=parsePtr->tokenPtr ; i<parsePtr->numWords ; i++) {
+	Tcl_Obj *leadingWord = Tcl_NewObj();
+
+	varTokenPtr = TokenAfter(varTokenPtr);
+	if (!TclWordKnownAtCompileTime(varTokenPtr, leadingWord)) {
+	    TclDecrRefCount(leadingWord);
+
+	    /*
+	     * We can tolerate non-trivial substitutions in the first variable
+	     * to be unset. If a '--' or '-nocomplain' was present, anything
+	     * goes in that one place! (All subsequent variable names must be
+	     * constants since we don't want to have to push them all first.)
+	     */
+
+	    if (varCount == 0) {
+		if (haveFlags) {
+		    continue;
+		}
+
+		/*
+		 * In fact, we're OK as long as we're the first argument *and*
+		 * we provably don't start with a '-'. If that is true, then
+		 * even if everything else is varying, we still can't be a
+		 * flag. Otherwise we'll spill to runtime to place a limit on
+		 * the trickiness.
+		 */
+
+		if (varTokenPtr->type == TCL_TOKEN_WORD
+			&& varTokenPtr[1].type == TCL_TOKEN_TEXT
+			&& varTokenPtr[1].size > 0
+			&& varTokenPtr[1].start[0] != '-') {
+		    continue;
+		}
+	    }
+	    return TCL_ERROR;
+	}
+	if (varCount == 0) {
+	    const char *bytes;
+	    int len;
+
+	    bytes = Tcl_GetStringFromObj(leadingWord, &len);
+	    if (i == 1 && len == 11 && !strncmp("-nocomplain", bytes, 11)) {
+		flags = 0;
+		haveFlags++;
+	    } else if (i == (2 - flags) && len == 2 && !strncmp("--", bytes, 2)) {
+		haveFlags++;
+	    } else {
+		varCount++;
+	    }
+	} else {
+	    varCount++;
+	}
+	TclDecrRefCount(leadingWord);
+    }
+
+    /*
+     * Issue instructions to unset each of the named variables.
+     */
+
+    varTokenPtr = TokenAfter(parsePtr->tokenPtr);
+    for (i=0; i<haveFlags;i++) {
+	varTokenPtr = TokenAfter(varTokenPtr);
+    }
+    for (i=1+haveFlags ; i<parsePtr->numWords ; i++) {
+	/*
+	 * Decide if we can use a frame slot for the var/array name or if we
+	 * need to emit code to compute and push the name at runtime. We use a
+	 * frame slot (entry in the array of local vars) if we are compiling a
+	 * procedure body and if the name is simple text that does not include
+	 * namespace qualifiers.
+	 */
+
+	PushVarNameWord(interp, varTokenPtr, envPtr, 0,
+		&localIndex, &isScalar, i);
+
+	/*
+	 * Emit instructions to unset the variable.
+	 */
+
+	if (isScalar) {
+	    if (localIndex < 0) {
+		OP1(	UNSET_STK, flags);
+	    } else {
+		OP14(	UNSET_SCALAR, flags, localIndex);
+	    }
+	} else {
+	    if (localIndex < 0) {
+		OP1(	UNSET_ARRAY_STK, flags);
+	    } else {
+		OP14(	UNSET_ARRAY, flags, localIndex);
+	    }
+	}
+
+	varTokenPtr = TokenAfter(varTokenPtr);
+    }
+    PUSH("");
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclCompileWhileCmd --
+ *
+ *	Procedure called to compile the "while" command.
+ *
+ * Results:
+ *	Returns TCL_OK for a successful compile. Returns TCL_ERROR to defer
+ *	evaluation to runtime.
+ *
+ * Side effects:
+ *	Instructions are added to envPtr to execute the "while" command at
+ *	runtime.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclCompileWhileCmd(
+    Tcl_Interp *interp,		/* Used for error reporting. */
+    Tcl_Parse *parsePtr,	/* Points to a parse structure for the command
+				 * created by Tcl_ParseCommand. */
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)		/* Holds resulting instructions. */
+{
+    Tcl_Token *testTokenPtr, *bodyTokenPtr;
+    JumpFixup jumpEvalCondFixup;
+    int testCodeOffset, bodyCodeOffset, jumpDist, range, code, boolVal;
+    int loopMayEnd = 1;		/* This is set to 0 if it is recognized as an
+				 * infinite loop. */
+    Tcl_Obj *boolObj;
+    DefineLineInformation;	/* TIP #280 */
+
+    if (parsePtr->numWords != 3) {
+	return TCL_ERROR;
+    }
+
+    /*
+     * If the test expression requires substitutions, don't compile the while
+     * command inline. E.g., the expression might cause the loop to never
+     * execute or execute forever, as in "while "$x < 5" {}".
+     *
+     * Bail out also if the body expression requires substitutions in order to
+     * insure correct behaviour [Bug 219166]
+     */
+
+    testTokenPtr = TokenAfter(parsePtr->tokenPtr);
+    bodyTokenPtr = TokenAfter(testTokenPtr);
+
+    if ((testTokenPtr->type != TCL_TOKEN_SIMPLE_WORD)
+	    || (bodyTokenPtr->type != TCL_TOKEN_SIMPLE_WORD)) {
+	return TCL_ERROR;
+    }
+
+    /*
+     * Find out if the condition is a constant.
+     */
+
+    boolObj = Tcl_NewStringObj(testTokenPtr[1].start, testTokenPtr[1].size);
+    Tcl_IncrRefCount(boolObj);
+    code = Tcl_GetBooleanFromObj(NULL, boolObj, &boolVal);
+    TclDecrRefCount(boolObj);
+    if (code == TCL_OK) {
+	if (boolVal) {
+	    /*
+	     * It is an infinite loop; flag it so that we generate a more
+	     * efficient body.
+	     */
+
+	    loopMayEnd = 0;
+	} else {
+	    /*
+	     * This is an empty loop: "while 0 {...}" or such. Compile no
+	     * bytecodes.
+	     */
+
+	    goto pushResult;
+	}
+    }
+
+    /*
+     * Create a ExceptionRange record for the loop body. This is used to
+     * implement break and continue.
+     */
+
+    range = TclCreateExceptRange(LOOP_EXCEPTION_RANGE, envPtr);
+
+    /*
+     * Jump to the evaluation of the condition. This code uses the "loop
+     * rotation" optimisation (which eliminates one branch from the loop).
+     * "while cond body" produces then:
+     *       goto A
+     *    B: body                : bodyCodeOffset
+     *    A: cond -> result      : testCodeOffset, continueOffset
+     *       if (result) goto B
+     *
+     * The infinite loop "while 1 body" produces:
+     *    B: body                : all three offsets here
+     *       goto B
+     */
+
+    if (loopMayEnd) {
+	TclEmitForwardJump(envPtr, TCL_UNCONDITIONAL_JUMP,
+		&jumpEvalCondFixup);
+	testCodeOffset = 0;	/* Avoid compiler warning. */
+    } else {
+	/*
+	 * Make sure that the first command in the body is preceded by an
+	 * INST_START_CMD, and hence counted properly. [Bug 1752146]
+	 */
+
+	envPtr->atCmdStart &= ~1;
+	testCodeOffset = CurrentOffset(envPtr);
+    }
+
+    /*
+     * Compile the loop body.
+     */
+
+    bodyCodeOffset = ExceptionRangeStarts(envPtr, range);
+    if (!loopMayEnd) {
+	envPtr->exceptArrayPtr[range].continueOffset = testCodeOffset;
+	envPtr->exceptArrayPtr[range].codeOffset = bodyCodeOffset;
+    }
+    BODY(bodyTokenPtr, 2);
+    ExceptionRangeEnds(envPtr, range);
+    OP(		POP);
+
+    /*
+     * Compile the test expression then emit the conditional jump that
+     * terminates the while. We already know it's a simple word.
+     */
+
+    if (loopMayEnd) {
+	testCodeOffset = CurrentOffset(envPtr);
+	jumpDist = testCodeOffset - jumpEvalCondFixup.codeOffset;
+	if (TclFixupForwardJump(envPtr, &jumpEvalCondFixup, jumpDist, 127)) {
+	    bodyCodeOffset += 3;
+	    testCodeOffset += 3;
+	}
+	SetLineInformation(1);
+	TclCompileExprWords(interp, testTokenPtr, 1, envPtr);
+
+	jumpDist = CurrentOffset(envPtr) - bodyCodeOffset;
+	if (jumpDist > 127) {
+	    TclEmitInstInt4(INST_JUMP_TRUE4, -jumpDist, envPtr);
+	} else {
+	    TclEmitInstInt1(INST_JUMP_TRUE1, -jumpDist, envPtr);
+	}
+    } else {
+	jumpDist = CurrentOffset(envPtr) - bodyCodeOffset;
+	if (jumpDist > 127) {
+	    TclEmitInstInt4(INST_JUMP4, -jumpDist, envPtr);
+	} else {
+	    TclEmitInstInt1(INST_JUMP1, -jumpDist, envPtr);
+	}
+    }
+
+    /*
+     * Set the loop's body, continue and break offsets.
+     */
+
+    envPtr->exceptArrayPtr[range].continueOffset = testCodeOffset;
+    envPtr->exceptArrayPtr[range].codeOffset = bodyCodeOffset;
+    ExceptionRangeTarget(envPtr, range, breakOffset);
+    TclFinalizeLoopExceptionRange(envPtr, range);
+
+    /*
+     * The while command's result is an empty string.
+     */
+
+  pushResult:
+    PUSH("");
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclCompileYieldCmd --
+ *
+ *	Procedure called to compile the "yield" command.
+ *
+ * Results:
+ *	Returns TCL_OK for a successful compile. Returns TCL_ERROR to defer
+ *	evaluation to runtime.
+ *
+ * Side effects:
+ *	Instructions are added to envPtr to execute the "yield" command at
+ *	runtime.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclCompileYieldCmd(
+    Tcl_Interp *interp,		/* Used for error reporting. */
+    Tcl_Parse *parsePtr,	/* Points to a parse structure for the command
+				 * created by Tcl_ParseCommand. */
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)		/* Holds resulting instructions. */
+{
+    if (parsePtr->numWords < 1 || parsePtr->numWords > 2) {
+	return TCL_ERROR;
+    }
+
+    if (parsePtr->numWords == 1) {
+	PUSH("");
+    } else {
+	DefineLineInformation;	/* TIP #280 */
+	Tcl_Token *valueTokenPtr = TokenAfter(parsePtr->tokenPtr);
+
+	CompileWord(envPtr, valueTokenPtr, interp, 1);
+    }
+    OP(		YIELD);
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclCompileYieldToCmd --
+ *
+ *	Procedure called to compile the "yieldto" command.
+ *
+ * Results:
+ *	Returns TCL_OK for a successful compile. Returns TCL_ERROR to defer
+ *	evaluation to runtime.
+ *
+ * Side effects:
+ *	Instructions are added to envPtr to execute the "yieldto" command at
+ *	runtime.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclCompileYieldToCmd(
+    Tcl_Interp *interp,		/* Used for error reporting. */
+    Tcl_Parse *parsePtr,	/* Points to a parse structure for the command
+				 * created by Tcl_ParseCommand. */
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)		/* Holds resulting instructions. */
+{
+    DefineLineInformation;	/* TIP #280 */
+    Tcl_Token *tokenPtr = TokenAfter(parsePtr->tokenPtr);
+    int i;
+
+    if (parsePtr->numWords < 2) {
+	return TCL_ERROR;
+    }
+
+    OP(		NS_CURRENT);
+    for (i = 1 ; i < parsePtr->numWords ; i++) {
+	CompileWord(envPtr, tokenPtr, interp, i);
+	tokenPtr = TokenAfter(tokenPtr);
+    }
+    OP4(	LIST, i);
+    OP(		YIELD_TO_INVOKE);
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * CompileUnaryOpCmd --
+ *
+ *	Utility routine to compile the unary operator commands.
+ *
+ * Results:
+ *	Returns TCL_OK for a successful compile. Returns TCL_ERROR to defer
+ *	evaluation to runtime.
+ *
+ * Side effects:
+ *	Instructions are added to envPtr to execute the compiled command at
+ *	runtime.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+CompileUnaryOpCmd(
+    Tcl_Interp *interp,
+    Tcl_Parse *parsePtr,
+    int instruction,
+    CompileEnv *envPtr)
+{
+    Tcl_Token *tokenPtr;
+    DefineLineInformation;	/* TIP #280 */
+
+    if (parsePtr->numWords != 2) {
+	return TCL_ERROR;
+    }
+    tokenPtr = TokenAfter(parsePtr->tokenPtr);
+    CompileWord(envPtr, tokenPtr, interp, 1);
+    TclEmitOpcode(instruction, envPtr);
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * CompileAssociativeBinaryOpCmd --
+ *
+ *	Utility routine to compile the binary operator commands that accept an
+ *	arbitrary number of arguments, and that are associative operations.
+ *	Because of the associativity, we may combine operations from right to
+ *	left, saving us any effort of re-ordering the arguments on the stack
+ *	after substitutions are completed.
+ *
+ * Results:
+ *	Returns TCL_OK for a successful compile. Returns TCL_ERROR to defer
+ *	evaluation to runtime.
+ *
+ * Side effects:
+ *	Instructions are added to envPtr to execute the compiled command at
+ *	runtime.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+CompileAssociativeBinaryOpCmd(
+    Tcl_Interp *interp,
+    Tcl_Parse *parsePtr,
+    const char *identity,
+    int instruction,
+    CompileEnv *envPtr)
+{
+    Tcl_Token *tokenPtr = parsePtr->tokenPtr;
+    DefineLineInformation;	/* TIP #280 */
+    int words;
+
+    /* TODO: Consider support for compiling expanded args. */
+    for (words=1 ; words<parsePtr->numWords ; words++) {
+	tokenPtr = TokenAfter(tokenPtr);
+	CompileWord(envPtr, tokenPtr, interp, words);
+    }
+    if (parsePtr->numWords <= 2) {
+	PushLiteral(envPtr, identity, -1);
+	words++;
+    }
+    if (words > 3) {
+	/*
+	 * Reverse order of arguments to get precise agreement with [expr] in
+	 * calcuations, including roundoff errors.
+	 */
+
+	OP4(	REVERSE, words-1);
+    }
+    while (--words > 1) {
+	TclEmitOpcode(instruction, envPtr);
+    }
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * CompileStrictlyBinaryOpCmd --
+ *
+ *	Utility routine to compile the binary operator commands, that strictly
+ *	accept exactly two arguments.
+ *
+ * Results:
+ *	Returns TCL_OK for a successful compile. Returns TCL_ERROR to defer
+ *	evaluation to runtime.
+ *
+ * Side effects:
+ *	Instructions are added to envPtr to execute the compiled command at
+ *	runtime.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+CompileStrictlyBinaryOpCmd(
+    Tcl_Interp *interp,
+    Tcl_Parse *parsePtr,
+    int instruction,
+    CompileEnv *envPtr)
+{
+    if (parsePtr->numWords != 3) {
+	return TCL_ERROR;
+    }
+    return CompileAssociativeBinaryOpCmd(interp, parsePtr,
+	    NULL, instruction, envPtr);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * CompileComparisonOpCmd --
+ *
+ *	Utility routine to compile the n-ary comparison operator commands.
+ *
+ * Results:
+ *	Returns TCL_OK for a successful compile. Returns TCL_ERROR to defer
+ *	evaluation to runtime.
+ *
+ * Side effects:
+ *	Instructions are added to envPtr to execute the compiled command at
+ *	runtime.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+CompileComparisonOpCmd(
+    Tcl_Interp *interp,
+    Tcl_Parse *parsePtr,
+    int instruction,
+    CompileEnv *envPtr)
+{
+    Tcl_Token *tokenPtr;
+    DefineLineInformation;	/* TIP #280 */
+
+    /* TODO: Consider support for compiling expanded args. */
+    if (parsePtr->numWords < 3) {
+	PUSH("1");
+    } else if (parsePtr->numWords == 3) {
+	tokenPtr = TokenAfter(parsePtr->tokenPtr);
+	CompileWord(envPtr, tokenPtr, interp, 1);
+	tokenPtr = TokenAfter(tokenPtr);
+	CompileWord(envPtr, tokenPtr, interp, 2);
+	TclEmitOpcode(instruction, envPtr);
+    } else if (envPtr->procPtr == NULL) {
+	/*
+	 * No local variable space!
+	 */
+
+	return TCL_ERROR;
+    } else {
+	int tmpIndex = AnonymousLocal(envPtr);
+	int words;
+
+	tokenPtr = TokenAfter(parsePtr->tokenPtr);
+	CompileWord(envPtr, tokenPtr, interp, 1);
+	tokenPtr = TokenAfter(tokenPtr);
+	CompileWord(envPtr, tokenPtr, interp, 2);
+	STORE(tmpIndex);
+	TclEmitOpcode(instruction, envPtr);
+	for (words=3 ; words<parsePtr->numWords ;) {
+	    LOAD(tmpIndex);
+	    tokenPtr = TokenAfter(tokenPtr);
+	    CompileWord(envPtr, tokenPtr, interp, words);
+	    if (++words < parsePtr->numWords) {
+		STORE(tmpIndex);
+	    }
+	    TclEmitOpcode(instruction, envPtr);
+	}
+	for (; words>3 ; words--) {
+	    OP(	BITAND);
+	}
+
+	/*
+	 * Drop the value from the temp variable; retaining that reference
+	 * might be expensive elsewhere.
+	 */
+
+	OP14(	UNSET_SCALAR, 0, tmpIndex);
+    }
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclCompile*OpCmd --
+ *
+ *	Procedures called to compile the corresponding "::tcl::mathop::*"
+ *	commands. These are all wrappers around the utility operator command
+ *	compiler functions, except for the compilers for subtraction and
+ *	division, which are special.
+ *
+ * Results:
+ *	Returns TCL_OK for a successful compile. Returns TCL_ERROR to defer
+ *	evaluation to runtime.
+ *
+ * Side effects:
+ *	Instructions are added to envPtr to execute the compiled command at
+ *	runtime.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclCompileInvertOpCmd(
+    Tcl_Interp *interp,
+    Tcl_Parse *parsePtr,
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)
+{
+    return CompileUnaryOpCmd(interp, parsePtr, INST_BITNOT, envPtr);
+}
+
+int
+TclCompileNotOpCmd(
+    Tcl_Interp *interp,
+    Tcl_Parse *parsePtr,
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)
+{
+    return CompileUnaryOpCmd(interp, parsePtr, INST_LNOT, envPtr);
+}
+
+int
+TclCompileAddOpCmd(
+    Tcl_Interp *interp,
+    Tcl_Parse *parsePtr,
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)
+{
+    return CompileAssociativeBinaryOpCmd(interp, parsePtr, "0", INST_ADD,
+	    envPtr);
+}
+
+int
+TclCompileMulOpCmd(
+    Tcl_Interp *interp,
+    Tcl_Parse *parsePtr,
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)
+{
+    return CompileAssociativeBinaryOpCmd(interp, parsePtr, "1", INST_MULT,
+	    envPtr);
+}
+
+int
+TclCompileAndOpCmd(
+    Tcl_Interp *interp,
+    Tcl_Parse *parsePtr,
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)
+{
+    return CompileAssociativeBinaryOpCmd(interp, parsePtr, "-1", INST_BITAND,
+	    envPtr);
+}
+
+int
+TclCompileOrOpCmd(
+    Tcl_Interp *interp,
+    Tcl_Parse *parsePtr,
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)
+{
+    return CompileAssociativeBinaryOpCmd(interp, parsePtr, "0", INST_BITOR,
+	    envPtr);
+}
+
+int
+TclCompileXorOpCmd(
+    Tcl_Interp *interp,
+    Tcl_Parse *parsePtr,
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)
+{
+    return CompileAssociativeBinaryOpCmd(interp, parsePtr, "0", INST_BITXOR,
+	    envPtr);
+}
+
+int
+TclCompilePowOpCmd(
+    Tcl_Interp *interp,
+    Tcl_Parse *parsePtr,
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)
+{
+    /*
+     * This one has its own implementation because the ** operator is the only
+     * one with right associativity.
+     */
+
+    Tcl_Token *tokenPtr = parsePtr->tokenPtr;
+    DefineLineInformation;	/* TIP #280 */
+    int words;
+
+    for (words=1 ; words<parsePtr->numWords ; words++) {
+	tokenPtr = TokenAfter(tokenPtr);
+	CompileWord(envPtr, tokenPtr, interp, words);
+    }
+    if (parsePtr->numWords <= 2) {
+	PUSH("1");
+	words++;
+    }
+    while (--words > 1) {
+	TclEmitOpcode(INST_EXPON, envPtr);
+    }
+    return TCL_OK;
+}
+
+int
+TclCompileLshiftOpCmd(
+    Tcl_Interp *interp,
+    Tcl_Parse *parsePtr,
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)
+{
+    return CompileStrictlyBinaryOpCmd(interp, parsePtr, INST_LSHIFT, envPtr);
+}
+
+int
+TclCompileRshiftOpCmd(
+    Tcl_Interp *interp,
+    Tcl_Parse *parsePtr,
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)
+{
+    return CompileStrictlyBinaryOpCmd(interp, parsePtr, INST_RSHIFT, envPtr);
+}
+
+int
+TclCompileModOpCmd(
+    Tcl_Interp *interp,
+    Tcl_Parse *parsePtr,
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)
+{
+    return CompileStrictlyBinaryOpCmd(interp, parsePtr, INST_MOD, envPtr);
+}
+
+int
+TclCompileNeqOpCmd(
+    Tcl_Interp *interp,
+    Tcl_Parse *parsePtr,
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)
+{
+    return CompileStrictlyBinaryOpCmd(interp, parsePtr, INST_NEQ, envPtr);
+}
+
+int
+TclCompileStrneqOpCmd(
+    Tcl_Interp *interp,
+    Tcl_Parse *parsePtr,
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)
+{
+    return CompileStrictlyBinaryOpCmd(interp, parsePtr, INST_STR_NEQ, envPtr);
+}
+
+int
+TclCompileInOpCmd(
+    Tcl_Interp *interp,
+    Tcl_Parse *parsePtr,
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)
+{
+    return CompileStrictlyBinaryOpCmd(interp, parsePtr, INST_LIST_IN, envPtr);
+}
+
+int
+TclCompileNiOpCmd(
+    Tcl_Interp *interp,
+    Tcl_Parse *parsePtr,
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)
+{
+    return CompileStrictlyBinaryOpCmd(interp, parsePtr, INST_LIST_NOT_IN,
+	    envPtr);
+}
+
+int
+TclCompileLessOpCmd(
+    Tcl_Interp *interp,
+    Tcl_Parse *parsePtr,
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)
+{
+    return CompileComparisonOpCmd(interp, parsePtr, INST_LT, envPtr);
+}
+
+int
+TclCompileLeqOpCmd(
+    Tcl_Interp *interp,
+    Tcl_Parse *parsePtr,
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)
+{
+    return CompileComparisonOpCmd(interp, parsePtr, INST_LE, envPtr);
+}
+
+int
+TclCompileGreaterOpCmd(
+    Tcl_Interp *interp,
+    Tcl_Parse *parsePtr,
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)
+{
+    return CompileComparisonOpCmd(interp, parsePtr, INST_GT, envPtr);
+}
+
+int
+TclCompileGeqOpCmd(
+    Tcl_Interp *interp,
+    Tcl_Parse *parsePtr,
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)
+{
+    return CompileComparisonOpCmd(interp, parsePtr, INST_GE, envPtr);
+}
+
+int
+TclCompileEqOpCmd(
+    Tcl_Interp *interp,
+    Tcl_Parse *parsePtr,
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)
+{
+    return CompileComparisonOpCmd(interp, parsePtr, INST_EQ, envPtr);
+}
+
+int
+TclCompileStreqOpCmd(
+    Tcl_Interp *interp,
+    Tcl_Parse *parsePtr,
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)
+{
+    return CompileComparisonOpCmd(interp, parsePtr, INST_STR_EQ, envPtr);
+}
+
+int
+TclCompileMinusOpCmd(
+    Tcl_Interp *interp,
+    Tcl_Parse *parsePtr,
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)
+{
+    Tcl_Token *tokenPtr = parsePtr->tokenPtr;
+    DefineLineInformation;	/* TIP #280 */
+    int words;
+
+    /* TODO: Consider support for compiling expanded args. */
+    if (parsePtr->numWords == 1) {
+	/*
+	 * Fallback to direct eval to report syntax error.
+	 */
+
+	return TCL_ERROR;
+    }
+    for (words=1 ; words<parsePtr->numWords ; words++) {
+	tokenPtr = TokenAfter(tokenPtr);
+	CompileWord(envPtr, tokenPtr, interp, words);
+    }
+    if (words == 2) {
+	TclEmitOpcode(INST_UMINUS, envPtr);
+	return TCL_OK;
+    }
+    if (words == 3) {
+	TclEmitOpcode(INST_SUB, envPtr);
+	return TCL_OK;
+    }
+
+    /*
+     * Reverse order of arguments to get precise agreement with [expr] in
+     * calcuations, including roundoff errors.
+     */
+
+    TclEmitInstInt4(INST_REVERSE, words-1, envPtr);
+    while (--words > 1) {
+	TclEmitInstInt4(INST_REVERSE, 2, envPtr);
+	TclEmitOpcode(INST_SUB, envPtr);
+    }
+    return TCL_OK;
+}
+
+int
+TclCompileDivOpCmd(
+    Tcl_Interp *interp,
+    Tcl_Parse *parsePtr,
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)
+{
+    Tcl_Token *tokenPtr = parsePtr->tokenPtr;
+    DefineLineInformation;	/* TIP #280 */
+    int words;
+
+    /* TODO: Consider support for compiling expanded args. */
+    if (parsePtr->numWords == 1) {
+	/*
+	 * Fallback to direct eval to report syntax error.
+	 */
+
+	return TCL_ERROR;
+    }
+    if (parsePtr->numWords == 2) {
+	PUSH("1.0");
+    }
+    for (words=1 ; words<parsePtr->numWords ; words++) {
+	tokenPtr = TokenAfter(tokenPtr);
+	CompileWord(envPtr, tokenPtr, interp, words);
+    }
+    if (words <= 3) {
+	TclEmitOpcode(INST_DIV, envPtr);
+	return TCL_OK;
+    }
+
+    /*
+     * Reverse order of arguments to get precise agreement with [expr] in
+     * calcuations, including roundoff errors.
+     */
+
+    TclEmitInstInt4(INST_REVERSE, words-1, envPtr);
+    while (--words > 1) {
+	TclEmitInstInt4(INST_REVERSE, 2, envPtr);
+	TclEmitOpcode(INST_DIV, envPtr);
+    }
+    return TCL_OK;
+}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tclCompExpr.c b/generic/tclCompExpr.c
new file mode 100644
index 0000000..4390282
--- /dev/null
+++ b/generic/tclCompExpr.c
@@ -0,0 +1,2806 @@
+/*
+ * tclCompExpr.c --
+ *
+ *	This file contains the code to parse and compile Tcl expressions and
+ *	implementations of the Tcl commands corresponding to expression
+ *	operators, such as the command ::tcl::mathop::+ .
+ *
+ * Contributions from Don Porter, NIST, 2006-2007. (not subject to US copyright)
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#include "tclInt.h"
+#include "tclCompile.h"		/* CompileEnv */
+
+/*
+ * Expression parsing takes place in the routine ParseExpr(). It takes a
+ * string as input, parses that string, and generates a representation of the
+ * expression in the form of a tree of operators, a list of literals, a list
+ * of function names, and an array of Tcl_Token's within a Tcl_Parse struct.
+ * The tree is composed of OpNodes.
+ */
+
+typedef struct OpNode {
+    int left;			/* "Pointer" to the left operand. */
+    int right;			/* "Pointer" to the right operand. */
+    union {
+	int parent;		/* "Pointer" to the parent operand. */
+	int prev;		/* "Pointer" joining incomplete tree stack */
+    } p;
+    unsigned char lexeme;	/* Code that identifies the operator. */
+    unsigned char precedence;	/* Precedence of the operator */
+    unsigned char mark;		/* Mark used to control traversal. */
+    unsigned char constant;	/* Flag marking constant subexpressions. */
+} OpNode;
+
+/*
+ * The storage for the tree is dynamically allocated array of OpNodes. The
+ * array is grown as parsing needs dictate according to a scheme similar to
+ * Tcl's string growth algorithm, so that the resizing costs are O(N) and so
+ * that we use at least half the memory allocated as expressions get large.
+ *
+ * Each OpNode in the tree represents an operator in the expression, either
+ * unary or binary. When parsing is completed successfully, a binary operator
+ * OpNode will have its left and right fields filled with "pointers" to its
+ * left and right operands. A unary operator OpNode will have its right field
+ * filled with a pointer to its single operand. When an operand is a
+ * subexpression the "pointer" takes the form of the index -- a non-negative
+ * integer -- into the OpNode storage array where the root of that
+ * subexpression parse tree is found.
+ *
+ * Non-operator elements of the expression do not get stored in the OpNode
+ * tree. They are stored in the other structures according to their type.
+ * Literal values get appended to the literal list. Elements that denote forms
+ * of quoting or substitution known to the Tcl parser get stored as
+ * Tcl_Tokens. These non-operator elements of the expression are the leaves of
+ * the completed parse tree. When an operand of an OpNode is one of these leaf
+ * elements, the following negative integer codes are used to indicate which
+ * kind of elements it is.
+ */
+
+enum OperandTypes {
+    OT_LITERAL = -3,	/* Operand is a literal in the literal list */
+    OT_TOKENS = -2,	/* Operand is sequence of Tcl_Tokens */
+    OT_EMPTY = -1	/* "Operand" is an empty string. This is a special
+			 * case used only to represent the EMPTY lexeme. See
+			 * below. */
+};
+
+/*
+ * Readable macros to test whether a "pointer" value points to an operator.
+ * They operate on the "non-negative integer -> operator; negative integer ->
+ * a non-operator OperandType" distinction.
+ */
+
+#define IsOperator(l)	((l) >= 0)
+#define NotOperator(l)	((l) < 0)
+
+/*
+ * Note that it is sufficient to store in the tree just the type of leaf
+ * operand, without any explicit pointer to which leaf. This is true because
+ * the traversals of the completed tree we perform are known to visit the
+ * leaves in the same order as the original parse.
+ *
+ * In a completed parse tree, those OpNodes that are themselves (roots of
+ * subexpression trees that are) operands of some operator store in their
+ * p.parent field a "pointer" to the OpNode of that operator. The p.parent
+ * field permits a traversal of the tree within a non-recursive routine
+ * (ConvertTreeToTokens() and CompileExprTree()). This means that even
+ * expression trees of great depth pose no risk of blowing the C stack.
+ *
+ * While the parse tree is being constructed, the same memory space is used to
+ * hold the p.prev field which chains together a stack of incomplete trees
+ * awaiting their right operands.
+ *
+ * The lexeme field is filled in with the lexeme of the operator that is
+ * returned by the ParseLexeme() routine. Only lexemes for unary and binary
+ * operators get stored in an OpNode. Other lexmes get different treatement.
+ *
+ * The precedence field provides a place to store the precedence of the
+ * operator, so it need not be looked up again and again.
+ *
+ * The mark field is use to control the traversal of the tree, so that it can
+ * be done non-recursively. The mark values are:
+ */
+
+enum Marks {
+    MARK_LEFT,		/* Next step of traversal is to visit left subtree */
+    MARK_RIGHT,		/* Next step of traversal is to visit right subtree */
+    MARK_PARENT		/* Next step of traversal is to return to parent */
+};
+
+/*
+ * The constant field is a boolean flag marking which subexpressions are
+ * completely known at compile time, and are eligible for computing then
+ * rather than waiting until run time.
+ */
+
+/*
+ * Each lexeme belongs to one of four categories, which determine its place in
+ * the parse tree. We use the two high bits of the (unsigned char) value to
+ * store a NODE_TYPE code.
+ */
+
+#define NODE_TYPE	0xC0
+
+/*
+ * The four category values are LEAF, UNARY, and BINARY, explained below, and
+ * "uncategorized", which is used either temporarily, until context determines
+ * which of the other three categories is correct, or for lexemes like
+ * INVALID, which aren't really lexemes at all, but indicators of a parsing
+ * error. Note that the codes must be distinct to distinguish categories, but
+ * need not take the form of a bit array.
+ */
+
+#define BINARY		0x40	/* This lexeme is a binary operator. An OpNode
+				 * representing it should go into the parse
+				 * tree, and two operands should be parsed for
+				 * it in the expression. */
+#define UNARY		0x80	/* This lexeme is a unary operator. An OpNode
+				 * representing it should go into the parse
+				 * tree, and one operand should be parsed for
+				 * it in the expression. */
+#define LEAF		0xC0	/* This lexeme is a leaf operand in the parse
+				 * tree. No OpNode will be placed in the tree
+				 * for it. Either a literal value will be
+				 * appended to the list of literals in this
+				 * expression, or appropriate Tcl_Tokens will
+				 * be appended in a Tcl_Parse struct to
+				 * represent those leaves that require some
+				 * form of substitution. */
+
+/* Uncategorized lexemes */
+
+#define PLUS		1	/* Ambiguous. Resolves to UNARY_PLUS or
+				 * BINARY_PLUS according to context. */
+#define MINUS		2	/* Ambiguous. Resolves to UNARY_MINUS or
+				 * BINARY_MINUS according to context. */
+#define BAREWORD	3	/* Ambigous. Resolves to BOOLEAN or to
+				 * FUNCTION or a parse error according to
+				 * context and value. */
+#define INCOMPLETE	4	/* A parse error. Used only when the single
+				 * "=" is encountered.  */
+#define INVALID		5	/* A parse error. Used when any punctuation
+				 * appears that's not a supported operator. */
+
+/* Leaf lexemes */
+
+#define NUMBER		(LEAF | 1)
+				/* For literal numbers */
+#define SCRIPT		(LEAF | 2)
+				/* Script substitution; [foo] */
+#define BOOLEAN		(LEAF | BAREWORD)
+				/* For literal booleans */
+#define BRACED		(LEAF | 4)
+				/* Braced string; {foo bar} */
+#define VARIABLE	(LEAF | 5)
+				/* Variable substitution; $x */
+#define QUOTED		(LEAF | 6)
+				/* Quoted string; "foo $bar [soom]" */
+#define EMPTY		(LEAF | 7)
+				/* Used only for an empty argument list to a
+				 * function. Represents the empty string
+				 * within parens in the expression: rand() */
+
+/* Unary operator lexemes */
+
+#define UNARY_PLUS	(UNARY | PLUS)
+#define UNARY_MINUS	(UNARY | MINUS)
+#define FUNCTION	(UNARY | BAREWORD)
+				/* This is a bit of "creative interpretation"
+				 * on the part of the parser. A function call
+				 * is parsed into the parse tree according to
+				 * the perspective that the function name is a
+				 * unary operator and its argument list,
+				 * enclosed in parens, is its operand. The
+				 * additional requirements not implied
+				 * generally by treatment as a unary operator
+				 * -- for example, the requirement that the
+				 * operand be enclosed in parens -- are hard
+				 * coded in the relevant portions of
+				 * ParseExpr(). We trade off the need to
+				 * include such exceptional handling in the
+				 * code against the need we would otherwise
+				 * have for more lexeme categories. */
+#define START		(UNARY | 4)
+				/* This lexeme isn't parsed from the
+				 * expression text at all. It represents the
+				 * start of the expression and sits at the
+				 * root of the parse tree where it serves as
+				 * the start/end point of traversals. */
+#define OPEN_PAREN	(UNARY | 5)
+				/* Another bit of creative interpretation,
+				 * where we treat "(" as a unary operator with
+				 * the sub-expression between it and its
+				 * matching ")" as its operand. See
+				 * CLOSE_PAREN below. */
+#define NOT		(UNARY | 6)
+#define BIT_NOT		(UNARY | 7)
+
+/* Binary operator lexemes */
+
+#define BINARY_PLUS	(BINARY |  PLUS)
+#define BINARY_MINUS	(BINARY |  MINUS)
+#define COMMA		(BINARY |  3)
+				/* The "," operator is a low precedence binary
+				 * operator that separates the arguments in a
+				 * function call. The additional constraint
+				 * that this operator can only legally appear
+				 * at the right places within a function call
+				 * argument list are hard coded within
+				 * ParseExpr().  */
+#define MULT		(BINARY |  4)
+#define DIVIDE		(BINARY |  5)
+#define MOD		(BINARY |  6)
+#define LESS		(BINARY |  7)
+#define GREATER		(BINARY |  8)
+#define BIT_AND		(BINARY |  9)
+#define BIT_XOR		(BINARY | 10)
+#define BIT_OR		(BINARY | 11)
+#define QUESTION	(BINARY | 12)
+				/* These two lexemes make up the */
+#define COLON		(BINARY | 13)
+				/* ternary conditional operator, $x ? $y : $z.
+				 * We treat them as two binary operators to
+				 * avoid another lexeme category, and code the
+				 * additional constraints directly in
+				 * ParseExpr(). For instance, the right
+				 * operand of a "?" operator must be a ":"
+				 * operator. */
+#define LEFT_SHIFT	(BINARY | 14)
+#define RIGHT_SHIFT	(BINARY | 15)
+#define LEQ		(BINARY | 16)
+#define GEQ		(BINARY | 17)
+#define EQUAL		(BINARY | 18)
+#define NEQ		(BINARY | 19)
+#define AND		(BINARY | 20)
+#define OR		(BINARY | 21)
+#define STREQ		(BINARY | 22)
+#define STRNEQ		(BINARY | 23)
+#define EXPON		(BINARY | 24)
+				/* Unlike the other binary operators, EXPON is
+				 * right associative and this distinction is
+				 * coded directly in ParseExpr(). */
+#define IN_LIST		(BINARY | 25)
+#define NOT_IN_LIST	(BINARY | 26)
+#define CLOSE_PAREN	(BINARY | 27)
+				/* By categorizing the CLOSE_PAREN lexeme as a
+				 * BINARY operator, the normal parsing rules
+				 * for binary operators assure that a close
+				 * paren will not directly follow another
+				 * operator, and the machinery already in
+				 * place to connect operands to operators
+				 * according to precedence performs most of
+				 * the work of matching open and close parens
+				 * for us. In the end though, a close paren is
+				 * not really a binary operator, and some
+				 * special coding in ParseExpr() make sure we
+				 * never put an actual CLOSE_PAREN node in the
+				 * parse tree. The sub-expression between
+				 * parens becomes the single argument of the
+				 * matching OPEN_PAREN unary operator. */
+#define END		(BINARY | 28)
+				/* This lexeme represents the end of the
+				 * string being parsed. Treating it as a
+				 * binary operator follows the same logic as
+				 * the CLOSE_PAREN lexeme and END pairs with
+				 * START, in the same way that CLOSE_PAREN
+				 * pairs with OPEN_PAREN. */
+
+/*
+ * When ParseExpr() builds the parse tree it must choose which operands to
+ * connect to which operators.  This is done according to operator precedence.
+ * The greater an operator's precedence the greater claim it has to link to an
+ * available operand.  The Precedence enumeration lists the precedence values
+ * used by Tcl expression operators, from lowest to highest claim.  Each
+ * precedence level is commented with the operators that hold that precedence.
+ */
+
+enum Precedence {
+    PREC_END = 1,	/* END */
+    PREC_START,		/* START */
+    PREC_CLOSE_PAREN,	/* ")" */
+    PREC_OPEN_PAREN,	/* "(" */
+    PREC_COMMA,		/* "," */
+    PREC_CONDITIONAL,	/* "?", ":" */
+    PREC_OR,		/* "||" */
+    PREC_AND,		/* "&&" */
+    PREC_BIT_OR,	/* "|" */
+    PREC_BIT_XOR,	/* "^" */
+    PREC_BIT_AND,	/* "&" */
+    PREC_EQUAL,		/* "==", "!=", "eq", "ne", "in", "ni" */
+    PREC_COMPARE,	/* "<", ">", "<=", ">=" */
+    PREC_SHIFT,		/* "<<", ">>" */
+    PREC_ADD,		/* "+", "-" */
+    PREC_MULT,		/* "*", "/", "%" */
+    PREC_EXPON,		/* "**" */
+    PREC_UNARY		/* "+", "-", FUNCTION, "!", "~" */
+};
+
+/*
+ * Here the same information contained in the comments above is stored in
+ * inverted form, so that given a lexeme, one can quickly look up its
+ * precedence value.
+ */
+
+static const unsigned char prec[] = {
+    /* Non-operator lexemes */
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,
+    /* Binary operator lexemes */
+    PREC_ADD,		/* BINARY_PLUS */
+    PREC_ADD,		/* BINARY_MINUS */
+    PREC_COMMA,		/* COMMA */
+    PREC_MULT,		/* MULT */
+    PREC_MULT,		/* DIVIDE */
+    PREC_MULT,		/* MOD */
+    PREC_COMPARE,	/* LESS */
+    PREC_COMPARE,	/* GREATER */
+    PREC_BIT_AND,	/* BIT_AND */
+    PREC_BIT_XOR,	/* BIT_XOR */
+    PREC_BIT_OR,	/* BIT_OR */
+    PREC_CONDITIONAL,	/* QUESTION */
+    PREC_CONDITIONAL,	/* COLON */
+    PREC_SHIFT,		/* LEFT_SHIFT */
+    PREC_SHIFT,		/* RIGHT_SHIFT */
+    PREC_COMPARE,	/* LEQ */
+    PREC_COMPARE,	/* GEQ */
+    PREC_EQUAL,		/* EQUAL */
+    PREC_EQUAL,		/* NEQ */
+    PREC_AND,		/* AND */
+    PREC_OR,		/* OR */
+    PREC_EQUAL,		/* STREQ */
+    PREC_EQUAL,		/* STRNEQ */
+    PREC_EXPON,		/* EXPON */
+    PREC_EQUAL,		/* IN_LIST */
+    PREC_EQUAL,		/* NOT_IN_LIST */
+    PREC_CLOSE_PAREN,	/* CLOSE_PAREN */
+    PREC_END,		/* END */
+    /* Expansion room for more binary operators */
+    0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,
+    /* Unary operator lexemes */
+    PREC_UNARY,		/* UNARY_PLUS */
+    PREC_UNARY,		/* UNARY_MINUS */
+    PREC_UNARY,		/* FUNCTION */
+    PREC_START,		/* START */
+    PREC_OPEN_PAREN,	/* OPEN_PAREN */
+    PREC_UNARY,		/* NOT*/
+    PREC_UNARY,		/* BIT_NOT*/
+};
+
+/*
+ * A table mapping lexemes to bytecode instructions, used by CompileExprTree().
+ */
+
+static const unsigned char instruction[] = {
+    /* Non-operator lexemes */
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,
+    /* Binary operator lexemes */
+    INST_ADD,		/* BINARY_PLUS */
+    INST_SUB,		/* BINARY_MINUS */
+    0,			/* COMMA */
+    INST_MULT,		/* MULT */
+    INST_DIV,		/* DIVIDE */
+    INST_MOD,		/* MOD */
+    INST_LT,		/* LESS */
+    INST_GT,		/* GREATER */
+    INST_BITAND,	/* BIT_AND */
+    INST_BITXOR,	/* BIT_XOR */
+    INST_BITOR,		/* BIT_OR */
+    0,			/* QUESTION */
+    0,			/* COLON */
+    INST_LSHIFT,	/* LEFT_SHIFT */
+    INST_RSHIFT,	/* RIGHT_SHIFT */
+    INST_LE,		/* LEQ */
+    INST_GE,		/* GEQ */
+    INST_EQ,		/* EQUAL */
+    INST_NEQ,		/* NEQ */
+    0,			/* AND */
+    0,			/* OR */
+    INST_STR_EQ,	/* STREQ */
+    INST_STR_NEQ,	/* STRNEQ */
+    INST_EXPON,		/* EXPON */
+    INST_LIST_IN,	/* IN_LIST */
+    INST_LIST_NOT_IN,	/* NOT_IN_LIST */
+    0,			/* CLOSE_PAREN */
+    0,			/* END */
+    /* Expansion room for more binary operators */
+    0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+    0,
+    /* Unary operator lexemes */
+    INST_UPLUS,		/* UNARY_PLUS */
+    INST_UMINUS,	/* UNARY_MINUS */
+    0,			/* FUNCTION */
+    0,			/* START */
+    0,			/* OPEN_PAREN */
+    INST_LNOT,		/* NOT*/
+    INST_BITNOT,	/* BIT_NOT*/
+};
+
+/*
+ * A table mapping a byte value to the corresponding lexeme for use by
+ * ParseLexeme().
+ */
+
+static const unsigned char Lexeme[] = {
+	INVALID		/* NUL */,	INVALID		/* SOH */,
+	INVALID		/* STX */,	INVALID		/* ETX */,
+	INVALID		/* EOT */,	INVALID		/* ENQ */,
+	INVALID		/* ACK */,	INVALID		/* BEL */,
+	INVALID		/* BS */,	INVALID		/* HT */,
+	INVALID		/* LF */,	INVALID		/* VT */,
+	INVALID		/* FF */,	INVALID		/* CR */,
+	INVALID		/* SO */,	INVALID		/* SI */,
+	INVALID		/* DLE */,	INVALID		/* DC1 */,
+	INVALID		/* DC2 */,	INVALID		/* DC3 */,
+	INVALID		/* DC4 */,	INVALID		/* NAK */,
+	INVALID		/* SYN */,	INVALID		/* ETB */,
+	INVALID		/* CAN */,	INVALID		/* EM */,
+	INVALID		/* SUB */,	INVALID		/* ESC */,
+	INVALID		/* FS */,	INVALID		/* GS */,
+	INVALID		/* RS */,	INVALID		/* US */,
+	INVALID		/* SPACE */,	0		/* ! or != */,
+	QUOTED		/* " */,	INVALID		/* # */,
+	VARIABLE	/* $ */,	MOD		/* % */,
+	0		/* & or && */,	INVALID		/* ' */,
+	OPEN_PAREN	/* ( */,	CLOSE_PAREN	/* ) */,
+	0		/* * or ** */,	PLUS		/* + */,
+	COMMA		/* , */,	MINUS		/* - */,
+	0		/* . */,	DIVIDE		/* / */,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0,			/* 0-9 */
+	COLON		/* : */,	INVALID		/* ; */,
+	0		/* < or << or <= */,
+	0		/* == or INVALID */,
+	0		/* > or >> or >= */,
+	QUESTION	/* ? */,	INVALID		/* @ */,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,		/* A-M */
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,		/* N-Z */
+	SCRIPT		/* [ */,	INVALID		/* \ */,
+	INVALID		/* ] */,	BIT_XOR		/* ^ */,
+	INVALID		/* _ */,	INVALID		/* ` */,
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,		/* a-m */
+	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,		/* n-z */
+	BRACED		/* { */,	0		/* | or || */,
+	INVALID		/* } */,	BIT_NOT		/* ~ */,
+	INVALID		/* DEL */
+};
+
+/*
+ * The JumpList struct is used to create a stack of data needed for the
+ * TclEmitForwardJump() and TclFixupForwardJump() calls that are performed
+ * when compiling the short-circuiting operators QUESTION/COLON, AND, and OR.
+ * Keeping a stack permits the CompileExprTree() routine to be non-recursive.
+ */
+
+typedef struct JumpList {
+    JumpFixup jump;		/* Pass this argument to matching calls of
+				 * TclEmitForwardJump() and
+				 * TclFixupForwardJump(). */
+    struct JumpList *next;	/* Point to next item on the stack */
+} JumpList;
+
+/*
+ * Declarations for local functions to this file:
+ */
+
+static void		CompileExprTree(Tcl_Interp *interp, OpNode *nodes,
+			    int index, Tcl_Obj *const **litObjvPtr,
+			    Tcl_Obj *const *funcObjv, Tcl_Token *tokenPtr,
+			    CompileEnv *envPtr, int optimize);
+static void		ConvertTreeToTokens(const char *start, int numBytes,
+			    OpNode *nodes, Tcl_Token *tokenPtr,
+			    Tcl_Parse *parsePtr);
+static int		ExecConstantExprTree(Tcl_Interp *interp, OpNode *nodes,
+			    int index, Tcl_Obj * const **litObjvPtr);
+static int		ParseExpr(Tcl_Interp *interp, const char *start,
+			    int numBytes, OpNode **opTreePtr,
+			    Tcl_Obj *litList, Tcl_Obj *funcList,
+			    Tcl_Parse *parsePtr, int parseOnly);
+static int		ParseLexeme(const char *start, int numBytes,
+			    unsigned char *lexemePtr, Tcl_Obj **literalPtr);
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ParseExpr --
+ *
+ *	Given a string, the numBytes bytes starting at start, this function
+ *	parses it as a Tcl expression and constructs a tree representing the
+ *	structure of the expression. The caller must pass in empty lists as
+ *	the funcList and litList arguments. The elements of the parsed
+ *	expression are returned to the caller as that tree, a list of literal
+ *	values, a list of function names, and in Tcl_Tokens added to a
+ *	Tcl_Parse struct passed in by the caller.
+ *
+ * Results:
+ *	If the string is successfully parsed as a valid Tcl expression, TCL_OK
+ *	is returned, and data about the expression structure is written to the
+ *	last four arguments. If the string cannot be parsed as a valid Tcl
+ *	expression, TCL_ERROR is returned, and if interp is non-NULL, an error
+ *	message is written to interp.
+ *
+ * Side effects:
+ *	Memory will be allocated. If TCL_OK is returned, the caller must clean
+ *	up the returned data structures. The (OpNode *) value written to
+ *	opTreePtr should be passed to ckfree() and the parsePtr argument
+ *	should be passed to Tcl_FreeParse(). The elements appended to the
+ *	litList and funcList will automatically be freed whenever the refcount
+ *	on those lists indicates they can be freed.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+ParseExpr(
+    Tcl_Interp *interp,		/* Used for error reporting. */
+    const char *start,		/* Start of source string to parse. */
+    int numBytes,		/* Number of bytes in string. */
+    OpNode **opTreePtr,		/* Points to space where a pointer to the
+				 * allocated OpNode tree should go. */
+    Tcl_Obj *litList,		/* List to append literals to. */
+    Tcl_Obj *funcList,		/* List to append function names to. */
+    Tcl_Parse *parsePtr,	/* Structure to fill with tokens representing
+				 * those operands that require run time
+				 * substitutions. */
+    int parseOnly)		/* A boolean indicating whether the caller's
+				 * aim is just a parse, or whether it will go
+				 * on to compile the expression. Different
+				 * optimizations are appropriate for the two
+				 * scenarios. */
+{
+    OpNode *nodes = NULL;	/* Pointer to the OpNode storage array where
+				 * we build the parse tree. */
+    unsigned int nodesAvailable = 64; /* Initial size of the storage array. This
+				 * value establishes a minimum tree memory
+				 * cost of only about 1 kibyte, and is large
+				 * enough for most expressions to parse with
+				 * no need for array growth and
+				 * reallocation. */
+    unsigned int nodesUsed = 0;	/* Number of OpNodes filled. */
+    int scanned = 0;		/* Capture number of byte scanned by parsing
+				 * routines. */
+    int lastParsed;		/* Stores info about what the lexeme parsed
+				 * the previous pass through the parsing loop
+				 * was. If it was an operator, lastParsed is
+				 * the index of the OpNode for that operator.
+				 * If it was not an operator, lastParsed holds
+				 * an OperandTypes value encoding what we need
+				 * to know about it. */
+    int incomplete;		/* Index of the most recent incomplete tree in
+				 * the OpNode array. Heads a stack of
+				 * incomplete trees linked by p.prev. */
+    int complete = OT_EMPTY;	/* "Index" of the complete tree (that is, a
+				 * complete subexpression) determined at the
+				 * moment. OT_EMPTY is a nonsense value used
+				 * only to silence compiler warnings. During a
+				 * parse, complete will always hold an index
+				 * or an OperandTypes value pointing to an
+				 * actual leaf at the time the complete tree
+				 * is needed. */
+
+    /*
+     * These variables control generation of the error message.
+     */
+
+    Tcl_Obj *msg = NULL;	/* The error message. */
+    Tcl_Obj *post = NULL;	/* In a few cases, an additional postscript
+				 * for the error message, supplying more
+				 * information after the error msg and
+				 * location have been reported. */
+    const char *errCode = NULL;	/* The detail word of the errorCode list, or
+				 * NULL to indicate that no changes to the
+				 * errorCode are to be done. */
+    const char *subErrCode = NULL;
+				/* Extra information for use in generating the
+				 * errorCode. */
+    const char *mark = "_@_";	/* In the portion of the complete error
+				 * message where the error location is
+				 * reported, this "mark" substring is inserted
+				 * into the string being parsed to aid in
+				 * pinpointing the location of the syntax
+				 * error in the expression. */
+    int insertMark = 0;		/* A boolean controlling whether the "mark"
+				 * should be inserted. */
+    const int limit = 25;	/* Portions of the error message are
+				 * constructed out of substrings of the
+				 * original expression. In order to keep the
+				 * error message readable, we impose this
+				 * limit on the substring size we extract. */
+
+    TclParseInit(interp, start, numBytes, parsePtr);
+
+    nodes = attemptckalloc(nodesAvailable * sizeof(OpNode));
+    if (nodes == NULL) {
+	TclNewLiteralStringObj(msg, "not enough memory to parse expression");
+	errCode = "NOMEM";
+	goto error;
+    }
+
+    /*
+     * Initialize the parse tree with the special "START" node.
+     */
+
+    nodes->lexeme = START;
+    nodes->precedence = prec[START];
+    nodes->mark = MARK_RIGHT;
+    nodes->constant = 1;
+    incomplete = lastParsed = nodesUsed;
+    nodesUsed++;
+
+    /*
+     * Main parsing loop parses one lexeme per iteration. We exit the loop
+     * only when there's a syntax error with a "goto error" which takes us to
+     * the error handling code following the loop, or when we've successfully
+     * completed the parse and we return to the caller.
+     */
+
+    while (1) {
+	OpNode *nodePtr;	/* Points to the OpNode we may fill this pass
+				 * through the loop. */
+	unsigned char lexeme;	/* The lexeme we parse this iteration. */
+	Tcl_Obj *literal;	/* Filled by the ParseLexeme() call when a
+				 * literal is parsed that has a Tcl_Obj rep
+				 * worth preserving. */
+
+	/*
+	 * Each pass through this loop adds up to one more OpNode. Allocate
+	 * space for one if required.
+	 */
+
+	if (nodesUsed >= nodesAvailable) {
+	    unsigned int size = nodesUsed * 2;
+	    OpNode *newPtr = NULL;
+
+	    do {
+	      if (size <= UINT_MAX/sizeof(OpNode)) {
+		newPtr = attemptckrealloc(nodes, size * sizeof(OpNode));
+	      }
+	    } while ((newPtr == NULL)
+		    && ((size -= (size - nodesUsed) / 2) > nodesUsed));
+	    if (newPtr == NULL) {
+		TclNewLiteralStringObj(msg,
+			"not enough memory to parse expression");
+		errCode = "NOMEM";
+		goto error;
+	    }
+	    nodesAvailable = size;
+	    nodes = newPtr;
+	}
+	nodePtr = nodes + nodesUsed;
+
+	/*
+	 * Skip white space between lexemes.
+	 */
+
+	scanned = TclParseAllWhiteSpace(start, numBytes);
+	start += scanned;
+	numBytes -= scanned;
+
+	scanned = ParseLexeme(start, numBytes, &lexeme, &literal);
+
+	/*
+	 * Use context to categorize the lexemes that are ambiguous.
+	 */
+
+	if ((NODE_TYPE & lexeme) == 0) {
+	    int b;
+
+	    switch (lexeme) {
+	    case INVALID:
+		msg = Tcl_ObjPrintf("invalid character \"%.*s\"",
+			scanned, start);
+		errCode = "BADCHAR";
+		goto error;
+	    case INCOMPLETE:
+		msg = Tcl_ObjPrintf("incomplete operator \"%.*s\"",
+			scanned, start);
+		errCode = "PARTOP";
+		goto error;
+	    case BAREWORD:
+
+		/*
+		 * Most barewords in an expression are a syntax error. The
+		 * exceptions are that when a bareword is followed by an open
+		 * paren, it might be a function call, and when the bareword
+		 * is a legal literal boolean value, we accept that as well.
+		 */
+
+		if (start[scanned+TclParseAllWhiteSpace(
+			start+scanned, numBytes-scanned)] == '(') {
+		    lexeme = FUNCTION;
+
+		    /*
+		     * When we compile the expression we'll need the function
+		     * name, and there's no place in the parse tree to store
+		     * it, so we keep a separate list of all the function
+		     * names we've parsed in the order we found them.
+		     */
+
+		    Tcl_ListObjAppendElement(NULL, funcList, literal);
+		} else if (Tcl_GetBooleanFromObj(NULL,literal,&b) == TCL_OK) {
+		    lexeme = BOOLEAN;
+		} else {
+		    Tcl_DecrRefCount(literal);
+		    msg = Tcl_ObjPrintf("invalid bareword \"%.*s%s\"",
+			    (scanned < limit) ? scanned : limit - 3, start,
+			    (scanned < limit) ? "" : "...");
+		    post = Tcl_ObjPrintf(
+			    "should be \"$%.*s%s\" or \"{%.*s%s}\"",
+			    (scanned < limit) ? scanned : limit - 3,
+			    start, (scanned < limit) ? "" : "...",
+			    (scanned < limit) ? scanned : limit - 3,
+			    start, (scanned < limit) ? "" : "...");
+		    Tcl_AppendPrintfToObj(post, " or \"%.*s%s(...)\" or ...",
+			    (scanned < limit) ? scanned : limit - 3,
+			    start, (scanned < limit) ? "" : "...");
+		    errCode = "BAREWORD";
+		    if (start[0] == '0') {
+			const char *stop;
+			TclParseNumber(NULL, NULL, NULL, start, scanned,
+				&stop, TCL_PARSE_NO_WHITESPACE);
+
+			if (isdigit(UCHAR(*stop)) || (stop == start + 1)) {
+			    switch (start[1]) {
+			    case 'b':
+				Tcl_AppendToObj(post,
+					" (invalid binary number?)", -1);
+				parsePtr->errorType = TCL_PARSE_BAD_NUMBER;
+				errCode = "BADNUMBER";
+				subErrCode = "BINARY";
+				break;
+			    case 'o':
+				Tcl_AppendToObj(post,
+					" (invalid octal number?)", -1);
+				parsePtr->errorType = TCL_PARSE_BAD_NUMBER;
+				errCode = "BADNUMBER";
+				subErrCode = "OCTAL";
+				break;
+			    default:
+				if (isdigit(UCHAR(start[1]))) {
+				    Tcl_AppendToObj(post,
+					    " (invalid octal number?)", -1);
+				    parsePtr->errorType = TCL_PARSE_BAD_NUMBER;
+				    errCode = "BADNUMBER";
+				    subErrCode = "OCTAL";
+				}
+				break;
+			    }
+			}
+		    }
+		    goto error;
+		}
+		break;
+	    case PLUS:
+	    case MINUS:
+		if (IsOperator(lastParsed)) {
+		    /*
+		     * A "+" or "-" coming just after another operator must be
+		     * interpreted as a unary operator.
+		     */
+
+		    lexeme |= UNARY;
+		} else {
+		    lexeme |= BINARY;
+		}
+	    }
+	}	/* Uncategorized lexemes */
+
+	/*
+	 * Handle lexeme based on its category.
+	 */
+
+	switch (NODE_TYPE & lexeme) {
+	case LEAF: {
+	    /*
+	     * Each LEAF results in either a literal getting appended to the
+	     * litList, or a sequence of Tcl_Tokens representing a Tcl word
+	     * getting appended to the parsePtr->tokens. No OpNode is filled
+	     * for this lexeme.
+	     */
+
+	    Tcl_Token *tokenPtr;
+	    const char *end = start;
+	    int wordIndex;
+	    int code = TCL_OK;
+
+	    /*
+	     * A leaf operand appearing just after something that's not an
+	     * operator is a syntax error.
+	     */
+
+	    if (NotOperator(lastParsed)) {
+		msg = Tcl_ObjPrintf("missing operator at %s", mark);
+		errCode = "MISSING";
+		scanned = 0;
+		insertMark = 1;
+
+		/*
+		 * Free any literal to avoid a memleak.
+		 */
+
+		if ((lexeme == NUMBER) || (lexeme == BOOLEAN)) {
+		    Tcl_DecrRefCount(literal);
+		}
+		goto error;
+	    }
+
+	    switch (lexeme) {
+	    case NUMBER:
+	    case BOOLEAN:
+		/*
+		 * TODO: Consider using a dict or hash to collapse all
+		 * duplicate literals into a single representative value.
+		 * (Like what is done with [split $s {}]).
+		 * Pro:	~75% memory saving on expressions like
+		 *	{1+1+1+1+1+.....+1} (Convert "pointer + Tcl_Obj" cost
+		 *	to "pointer" cost only)
+		 * Con:	Cost of the dict store/retrieve on every literal in
+		 *	every expression when expressions like the above tend
+		 *	to be uncommon.
+		 *	The memory savings is temporary; Compiling to bytecode
+		 *	will collapse things as literals are registered
+		 *	anyway, so the savings applies only to the time
+		 *	between parsing and compiling. Possibly important due
+		 *	to high-water mark nature of memory allocation.
+		 */
+
+		Tcl_ListObjAppendElement(NULL, litList, literal);
+		complete = lastParsed = OT_LITERAL;
+		start += scanned;
+		numBytes -= scanned;
+		continue;
+
+	    default:
+		break;
+	    }
+
+	    /*
+	     * Remaining LEAF cases may involve filling Tcl_Tokens, so make
+	     * room for at least 2 more tokens.
+	     */
+
+	    TclGrowParseTokenArray(parsePtr, 2);
+	    wordIndex = parsePtr->numTokens;
+	    tokenPtr = parsePtr->tokenPtr + wordIndex;
+	    tokenPtr->type = TCL_TOKEN_WORD;
+	    tokenPtr->start = start;
+	    parsePtr->numTokens++;
+
+	    switch (lexeme) {
+	    case QUOTED:
+		code = Tcl_ParseQuotedString(NULL, start, numBytes,
+			parsePtr, 1, &end);
+		scanned = end - start;
+		break;
+
+	    case BRACED:
+		code = Tcl_ParseBraces(NULL, start, numBytes,
+			parsePtr, 1, &end);
+		scanned = end - start;
+		break;
+
+	    case VARIABLE:
+		code = Tcl_ParseVarName(NULL, start, numBytes, parsePtr, 1);
+
+		/*
+		 * Handle the quirk that Tcl_ParseVarName reports a successful
+		 * parse even when it gets only a "$" with no variable name.
+		 */
+
+		tokenPtr = parsePtr->tokenPtr + wordIndex + 1;
+		if (code == TCL_OK && tokenPtr->type != TCL_TOKEN_VARIABLE) {
+		    TclNewLiteralStringObj(msg, "invalid character \"$\"");
+		    errCode = "BADCHAR";
+		    goto error;
+		}
+		scanned = tokenPtr->size;
+		break;
+
+	    case SCRIPT: {
+		Tcl_Parse *nestedPtr =
+			TclStackAlloc(interp, sizeof(Tcl_Parse));
+
+		tokenPtr = parsePtr->tokenPtr + parsePtr->numTokens;
+		tokenPtr->type = TCL_TOKEN_COMMAND;
+		tokenPtr->start = start;
+		tokenPtr->numComponents = 0;
+
+		end = start + numBytes;
+		start++;
+		while (1) {
+		    code = Tcl_ParseCommand(interp, start, end - start, 1,
+			    nestedPtr);
+		    if (code != TCL_OK) {
+			parsePtr->term = nestedPtr->term;
+			parsePtr->errorType = nestedPtr->errorType;
+			parsePtr->incomplete = nestedPtr->incomplete;
+			break;
+		    }
+		    start = nestedPtr->commandStart + nestedPtr->commandSize;
+		    Tcl_FreeParse(nestedPtr);
+		    if ((nestedPtr->term < end) && (nestedPtr->term[0] == ']')
+			    && !nestedPtr->incomplete) {
+			break;
+		    }
+
+		    if (start == end) {
+			TclNewLiteralStringObj(msg, "missing close-bracket");
+			parsePtr->term = tokenPtr->start;
+			parsePtr->errorType = TCL_PARSE_MISSING_BRACKET;
+			parsePtr->incomplete = 1;
+			code = TCL_ERROR;
+			errCode = "UNBALANCED";
+			break;
+		    }
+		}
+		TclStackFree(interp, nestedPtr);
+		end = start;
+		start = tokenPtr->start;
+		scanned = end - start;
+		tokenPtr->size = scanned;
+		parsePtr->numTokens++;
+		break;
+	    }			/* SCRIPT case */
+	    }
+	    if (code != TCL_OK) {
+		/*
+		 * Here we handle all the syntax errors generated by the
+		 * Tcl_Token generating parsing routines called in the switch
+		 * just above. If the value of parsePtr->incomplete is 1, then
+		 * the error was an unbalanced '[', '(', '{', or '"' and
+		 * parsePtr->term is pointing to that unbalanced character. If
+		 * the value of parsePtr->incomplete is 0, then the error is
+		 * one of lacking whitespace following a quoted word, for
+		 * example: expr {[an error {foo}bar]}, and parsePtr->term
+		 * points to where the whitespace is missing. We reset our
+		 * values of start and scanned so that when our error message
+		 * is constructed, the location of the syntax error is sure to
+		 * appear in it, even if the quoted expression is truncated.
+		 */
+
+		start = parsePtr->term;
+		scanned = parsePtr->incomplete;
+		if (parsePtr->incomplete) {
+		    errCode = "UNBALANCED";
+		}
+		goto error;
+	    }
+
+	    tokenPtr = parsePtr->tokenPtr + wordIndex;
+	    tokenPtr->size = scanned;
+	    tokenPtr->numComponents = parsePtr->numTokens - wordIndex - 1;
+	    if (!parseOnly && ((lexeme == QUOTED) || (lexeme == BRACED))) {
+		/*
+		 * When this expression is destined to be compiled, and a
+		 * braced or quoted word within an expression is known at
+		 * compile time (no runtime substitutions in it), we can store
+		 * it as a literal rather than in its tokenized form. This is
+		 * an advantage since the compiled bytecode is going to need
+		 * the argument in Tcl_Obj form eventually, so it's just as
+		 * well to get there now. Another advantage is that with this
+		 * conversion, larger constant expressions might be grown and
+		 * optimized.
+		 *
+		 * On the contrary, if the end goal of this parse is to fill a
+		 * Tcl_Parse for a caller of Tcl_ParseExpr(), then it's
+		 * wasteful to convert to a literal only to convert back again
+		 * later.
+		 */
+
+		literal = Tcl_NewObj();
+		if (TclWordKnownAtCompileTime(tokenPtr, literal)) {
+		    Tcl_ListObjAppendElement(NULL, litList, literal);
+		    complete = lastParsed = OT_LITERAL;
+		    parsePtr->numTokens = wordIndex;
+		    break;
+		}
+		Tcl_DecrRefCount(literal);
+	    }
+	    complete = lastParsed = OT_TOKENS;
+	    break;
+	} /* case LEAF */
+
+	case UNARY:
+
+	    /*
+	     * A unary operator appearing just after something that's not an
+	     * operator is a syntax error -- something trying to be the left
+	     * operand of an operator that doesn't take one.
+	     */
+
+	    if (NotOperator(lastParsed)) {
+		msg = Tcl_ObjPrintf("missing operator at %s", mark);
+		scanned = 0;
+		insertMark = 1;
+		errCode = "MISSING";
+		goto error;
+	    }
+
+	    /*
+	     * Create an OpNode for the unary operator.
+	     */
+
+	    nodePtr->lexeme = lexeme;
+	    nodePtr->precedence = prec[lexeme];
+	    nodePtr->mark = MARK_RIGHT;
+
+	    /*
+	     * A FUNCTION cannot be a constant expression, because Tcl allows
+	     * functions to return variable results with the same arguments;
+	     * for example, rand(). Other unary operators can root a constant
+	     * expression, so long as the argument is a constant expression.
+	     */
+
+	    nodePtr->constant = (lexeme != FUNCTION);
+
+	    /*
+	     * This unary operator is a new incomplete tree, so push it onto
+	     * our stack of incomplete trees. Also remember it as the last
+	     * lexeme we parsed.
+	     */
+
+	    nodePtr->p.prev = incomplete;
+	    incomplete = lastParsed = nodesUsed;
+	    nodesUsed++;
+	    break;
+
+	case BINARY: {
+	    OpNode *incompletePtr;
+	    unsigned char precedence = prec[lexeme];
+
+	    /*
+	     * A binary operator appearing just after another operator is a
+	     * syntax error -- one of the two operators is missing an operand.
+	     */
+
+	    if (IsOperator(lastParsed)) {
+		if ((lexeme == CLOSE_PAREN)
+			&& (nodePtr[-1].lexeme == OPEN_PAREN)) {
+		    if (nodePtr[-2].lexeme == FUNCTION) {
+			/*
+			 * Normally, "()" is a syntax error, but as a special
+			 * case accept it as an argument list for a function.
+			 * Treat this as a special LEAF lexeme, and restart
+			 * the parsing loop with zero characters scanned. We
+			 * will parse the ")" again the next time through, but
+			 * with the OT_EMPTY leaf as the subexpression between
+			 * the parens.
+			 */
+
+			scanned = 0;
+			complete = lastParsed = OT_EMPTY;
+			break;
+		    }
+		    msg = Tcl_ObjPrintf("empty subexpression at %s", mark);
+		    scanned = 0;
+		    insertMark = 1;
+		    errCode = "EMPTY";
+		    goto error;
+		}
+
+		if (nodePtr[-1].precedence > precedence) {
+		    if (nodePtr[-1].lexeme == OPEN_PAREN) {
+			TclNewLiteralStringObj(msg, "unbalanced open paren");
+			parsePtr->errorType = TCL_PARSE_MISSING_PAREN;
+			errCode = "UNBALANCED";
+		    } else if (nodePtr[-1].lexeme == COMMA) {
+			msg = Tcl_ObjPrintf(
+				"missing function argument at %s", mark);
+			scanned = 0;
+			insertMark = 1;
+			errCode = "MISSING";
+		    } else if (nodePtr[-1].lexeme == START) {
+			TclNewLiteralStringObj(msg, "empty expression");
+			errCode = "EMPTY";
+		    }
+		} else if (lexeme == CLOSE_PAREN) {
+		    TclNewLiteralStringObj(msg, "unbalanced close paren");
+		    errCode = "UNBALANCED";
+		} else if ((lexeme == COMMA)
+			&& (nodePtr[-1].lexeme == OPEN_PAREN)
+			&& (nodePtr[-2].lexeme == FUNCTION)) {
+		    msg = Tcl_ObjPrintf("missing function argument at %s",
+			    mark);
+		    scanned = 0;
+		    insertMark = 1;
+		    errCode = "UNBALANCED";
+		}
+		if (msg == NULL) {
+		    msg = Tcl_ObjPrintf("missing operand at %s", mark);
+		    scanned = 0;
+		    insertMark = 1;
+		    errCode = "MISSING";
+		}
+		goto error;
+	    }
+
+	    /*
+	     * Here is where the tree comes together. At this point, we have a
+	     * stack of incomplete trees corresponding to substrings that are
+	     * incomplete expressions, followed by a complete tree
+	     * corresponding to a substring that is itself a complete
+	     * expression, followed by the binary operator we have just
+	     * parsed. The incomplete trees can each be completed by adding a
+	     * right operand.
+	     *
+	     * To illustrate with an example, when we parse the expression
+	     * "1+2*3-4" and we reach this point having just parsed the "-"
+	     * operator, we have these incomplete trees: START, "1+", and
+	     * "2*". Next we have the complete subexpression "3". Last is the
+	     * "-" we've just parsed.
+	     *
+	     * The next step is to join our complete tree to an operator. The
+	     * choice is governed by the precedence and associativity of the
+	     * competing operators. If we connect it as the right operand of
+	     * our most recent incomplete tree, we get a new complete tree,
+	     * and we can repeat the process. The while loop following repeats
+	     * this until precedence indicates it is time to join the complete
+	     * tree as the left operand of the just parsed binary operator.
+	     *
+	     * Continuing the example, the first pass through the loop will
+	     * join "3" to "2*"; the next pass will join "2*3" to "1+". Then
+	     * we'll exit the loop and join "1+2*3" to "-". When we return to
+	     * parse another lexeme, our stack of incomplete trees is START
+	     * and "1+2*3-".
+	     */
+
+	    while (1) {
+		incompletePtr = nodes + incomplete;
+
+		if (incompletePtr->precedence < precedence) {
+		    break;
+		}
+
+		if (incompletePtr->precedence == precedence) {
+		    /*
+		     * Right association rules for exponentiation.
+		     */
+
+		    if (lexeme == EXPON) {
+			break;
+		    }
+
+		    /*
+		     * Special association rules for the conditional
+		     * operators. The "?" and ":" operators have equal
+		     * precedence, but must be linked up in sensible pairs.
+		     */
+
+		    if ((incompletePtr->lexeme == QUESTION)
+			    && (NotOperator(complete)
+			    || (nodes[complete].lexeme != COLON))) {
+			break;
+		    }
+		    if ((incompletePtr->lexeme == COLON)
+			    && (lexeme == QUESTION)) {
+			break;
+		    }
+		}
+
+		/*
+		 * Some special syntax checks...
+		 */
+
+		/* Parens must balance */
+		if ((incompletePtr->lexeme == OPEN_PAREN)
+			&& (lexeme != CLOSE_PAREN)) {
+		    TclNewLiteralStringObj(msg, "unbalanced open paren");
+		    parsePtr->errorType = TCL_PARSE_MISSING_PAREN;
+		    errCode = "UNBALANCED";
+		    goto error;
+		}
+
+		/* Right operand of "?" must be ":" */
+		if ((incompletePtr->lexeme == QUESTION)
+			&& (NotOperator(complete)
+			|| (nodes[complete].lexeme != COLON))) {
+		    msg = Tcl_ObjPrintf("missing operator \":\" at %s", mark);
+		    scanned = 0;
+		    insertMark = 1;
+		    errCode = "MISSING";
+		    goto error;
+		}
+
+		/* Operator ":" may only be right operand of "?" */
+		if (IsOperator(complete)
+			&& (nodes[complete].lexeme == COLON)
+			&& (incompletePtr->lexeme != QUESTION)) {
+		    TclNewLiteralStringObj(msg,
+			    "unexpected operator \":\" "
+			    "without preceding \"?\"");
+		    errCode = "SURPRISE";
+		    goto error;
+		}
+
+		/*
+		 * Attach complete tree as right operand of most recent
+		 * incomplete tree.
+		 */
+
+		incompletePtr->right = complete;
+		if (IsOperator(complete)) {
+		    nodes[complete].p.parent = incomplete;
+		    incompletePtr->constant = incompletePtr->constant
+			    && nodes[complete].constant;
+		} else {
+		    incompletePtr->constant = incompletePtr->constant
+			    && (complete == OT_LITERAL);
+		}
+
+		/*
+		 * The QUESTION/COLON and FUNCTION/OPEN_PAREN combinations
+		 * each make up a single operator. Force them to agree whether
+		 * they have a constant expression.
+		 */
+
+		if ((incompletePtr->lexeme == QUESTION)
+			|| (incompletePtr->lexeme == FUNCTION)) {
+		    nodes[complete].constant = incompletePtr->constant;
+		}
+
+		if (incompletePtr->lexeme == START) {
+		    /*
+		     * Completing the START tree indicates we're done.
+		     * Transfer the parse tree to the caller and return.
+		     */
+
+		    *opTreePtr = nodes;
+		    return TCL_OK;
+		}
+
+		/*
+		 * With a right operand attached, last incomplete tree has
+		 * become the complete tree. Pop it from the incomplete tree
+		 * stack.
+		 */
+
+		complete = incomplete;
+		incomplete = incompletePtr->p.prev;
+
+		/* CLOSE_PAREN can only close one OPEN_PAREN. */
+		if (incompletePtr->lexeme == OPEN_PAREN) {
+		    break;
+		}
+	    }
+
+	    /*
+	     * More syntax checks...
+	     */
+
+	    /* Parens must balance. */
+	    if (lexeme == CLOSE_PAREN) {
+		if (incompletePtr->lexeme != OPEN_PAREN) {
+		    TclNewLiteralStringObj(msg, "unbalanced close paren");
+		    errCode = "UNBALANCED";
+		    goto error;
+		}
+	    }
+
+	    /* Commas must appear only in function argument lists. */
+	    if (lexeme == COMMA) {
+		if  ((incompletePtr->lexeme != OPEN_PAREN)
+			|| (incompletePtr[-1].lexeme != FUNCTION)) {
+		    TclNewLiteralStringObj(msg,
+			    "unexpected \",\" outside function argument list");
+		    errCode = "SURPRISE";
+		    goto error;
+		}
+	    }
+
+	    /* Operator ":" may only be right operand of "?" */
+	    if (IsOperator(complete) && (nodes[complete].lexeme == COLON)) {
+		TclNewLiteralStringObj(msg,
+			"unexpected operator \":\" without preceding \"?\"");
+		errCode = "SURPRISE";
+		goto error;
+	    }
+
+	    /*
+	     * Create no node for a CLOSE_PAREN lexeme.
+	     */
+
+	    if (lexeme == CLOSE_PAREN) {
+		break;
+	    }
+
+	    /*
+	     * Link complete tree as left operand of new node.
+	     */
+
+	    nodePtr->lexeme = lexeme;
+	    nodePtr->precedence = precedence;
+	    nodePtr->mark = MARK_LEFT;
+	    nodePtr->left = complete;
+
+	    /*
+	     * The COMMA operator cannot be optimized, since the function
+	     * needs all of its arguments, and optimization would reduce the
+	     * number. Other binary operators root constant expressions when
+	     * both arguments are constant expressions.
+	     */
+
+	    nodePtr->constant = (lexeme != COMMA);
+
+	    if (IsOperator(complete)) {
+		nodes[complete].p.parent = nodesUsed;
+		nodePtr->constant = nodePtr->constant
+			&& nodes[complete].constant;
+	    } else {
+		nodePtr->constant = nodePtr->constant
+			&& (complete == OT_LITERAL);
+	    }
+
+	    /*
+	     * With a left operand attached and a right operand missing, the
+	     * just-parsed binary operator is root of a new incomplete tree.
+	     * Push it onto the stack of incomplete trees.
+	     */
+
+	    nodePtr->p.prev = incomplete;
+	    incomplete = lastParsed = nodesUsed;
+	    nodesUsed++;
+	    break;
+	}	/* case BINARY */
+	}	/* lexeme handler */
+
+	/* Advance past the just-parsed lexeme */
+	start += scanned;
+	numBytes -= scanned;
+    }	/* main parsing loop */
+
+    /*
+     * We only get here if there's been an error. Any errors that didn't get a
+     * suitable parsePtr->errorType, get recorded as syntax errors.
+     */
+
+  error:
+    if (parsePtr->errorType == TCL_PARSE_SUCCESS) {
+	parsePtr->errorType = TCL_PARSE_SYNTAX;
+    }
+
+    /*
+     * Free any partial parse tree we've built.
+     */
+
+    if (nodes != NULL) {
+	ckfree(nodes);
+    }
+
+    if (interp == NULL) {
+	/*
+	 * Nowhere to report an error message, so just free it.
+	 */
+
+	if (msg) {
+	    Tcl_DecrRefCount(msg);
+	}
+    } else {
+	/*
+	 * Construct the complete error message. Start with the simple error
+	 * message, pulled from the interp result if necessary...
+	 */
+
+	if (msg == NULL) {
+	    msg = Tcl_GetObjResult(interp);
+	}
+
+	/*
+	 * Add a detailed quote from the bad expression, displaying and
+	 * sometimes marking the precise location of the syntax error.
+	 */
+
+	Tcl_AppendPrintfToObj(msg, "\nin expression \"%s%.*s%.*s%s%s%.*s%s\"",
+		((start - limit) < parsePtr->string) ? "" : "...",
+		((start - limit) < parsePtr->string)
+			? (int) (start - parsePtr->string) : limit - 3,
+		((start - limit) < parsePtr->string)
+			? parsePtr->string : start - limit + 3,
+		(scanned < limit) ? scanned : limit - 3, start,
+		(scanned < limit) ? "" : "...", insertMark ? mark : "",
+		(start + scanned + limit > parsePtr->end)
+			? (int) (parsePtr->end - start) - scanned : limit-3,
+		start + scanned,
+		(start + scanned + limit > parsePtr->end) ? "" : "...");
+
+	/*
+	 * Next, append any postscript message.
+	 */
+
+	if (post != NULL) {
+	    Tcl_AppendToObj(msg, ";\n", -1);
+	    Tcl_AppendObjToObj(msg, post);
+	    Tcl_DecrRefCount(post);
+	}
+	Tcl_SetObjResult(interp, msg);
+
+	/*
+	 * Finally, place context information in the errorInfo.
+	 */
+
+	numBytes = parsePtr->end - parsePtr->string;
+	Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf(
+		"\n    (parsing expression \"%.*s%s\")",
+		(numBytes < limit) ? numBytes : limit - 3,
+		parsePtr->string, (numBytes < limit) ? "" : "..."));
+	if (errCode) {
+	    Tcl_SetErrorCode(interp, "TCL", "PARSE", "EXPR", errCode,
+		    subErrCode, NULL);
+	}
+    }
+
+    return TCL_ERROR;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ConvertTreeToTokens --
+ *
+ *	Given a string, the numBytes bytes starting at start, and an OpNode
+ *	tree and Tcl_Token array created by passing that same string to
+ *	ParseExpr(), this function writes into *parsePtr the sequence of
+ *	Tcl_Tokens needed so to satisfy the historical interface provided by
+ *	Tcl_ParseExpr(). Note that this routine exists only for the sake of
+ *	the public Tcl_ParseExpr() routine. It is not used by Tcl itself at
+ *	all.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The Tcl_Parse *parsePtr is filled with Tcl_Tokens representing the
+ *	parsed expression.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+ConvertTreeToTokens(
+    const char *start,
+    int numBytes,
+    OpNode *nodes,
+    Tcl_Token *tokenPtr,
+    Tcl_Parse *parsePtr)
+{
+    int subExprTokenIdx = 0;
+    OpNode *nodePtr = nodes;
+    int next = nodePtr->right;
+
+    while (1) {
+	Tcl_Token *subExprTokenPtr;
+	int scanned, parentIdx;
+	unsigned char lexeme;
+
+	/*
+	 * Advance the mark so the next exit from this node won't retrace
+	 * steps over ground already covered.
+	 */
+
+	nodePtr->mark++;
+
+	/*
+	 * Handle next child node or leaf.
+	 */
+
+	switch (next) {
+	case OT_EMPTY:
+
+	    /* No tokens and no characters for the OT_EMPTY leaf. */
+	    break;
+
+	case OT_LITERAL:
+
+	    /*
+	     * Skip any white space that comes before the literal.
+	     */
+
+	    scanned = TclParseAllWhiteSpace(start, numBytes);
+	    start += scanned;
+	    numBytes -= scanned;
+
+	    /*
+	     * Reparse the literal to get pointers into source string.
+	     */
+
+	    scanned = ParseLexeme(start, numBytes, &lexeme, NULL);
+
+	    TclGrowParseTokenArray(parsePtr, 2);
+	    subExprTokenPtr = parsePtr->tokenPtr + parsePtr->numTokens;
+	    subExprTokenPtr->type = TCL_TOKEN_SUB_EXPR;
+	    subExprTokenPtr->start = start;
+	    subExprTokenPtr->size = scanned;
+	    subExprTokenPtr->numComponents = 1;
+	    subExprTokenPtr[1].type = TCL_TOKEN_TEXT;
+	    subExprTokenPtr[1].start = start;
+	    subExprTokenPtr[1].size = scanned;
+	    subExprTokenPtr[1].numComponents = 0;
+
+	    parsePtr->numTokens += 2;
+	    start += scanned;
+	    numBytes -= scanned;
+	    break;
+
+	case OT_TOKENS: {
+	    /*
+	     * tokenPtr points to a token sequence that came from parsing a
+	     * Tcl word. A Tcl word is made up of a sequence of one or more
+	     * elements. When the word is only a single element, it's been the
+	     * historical practice to replace the TCL_TOKEN_WORD token
+	     * directly with a TCL_TOKEN_SUB_EXPR token. However, when the
+	     * word has multiple elements, a TCL_TOKEN_WORD token is kept as a
+	     * grouping device so that TCL_TOKEN_SUB_EXPR always has only one
+	     * element. Wise or not, these are the rules the Tcl expr parser
+	     * has followed, and for the sake of those few callers of
+	     * Tcl_ParseExpr() we do not change them now. Internally, we can
+	     * do better.
+	     */
+
+	    int toCopy = tokenPtr->numComponents + 1;
+
+	    if (tokenPtr->numComponents == tokenPtr[1].numComponents + 1) {
+		/*
+		 * Single element word. Copy tokens and convert the leading
+		 * token to TCL_TOKEN_SUB_EXPR.
+		 */
+
+		TclGrowParseTokenArray(parsePtr, toCopy);
+		subExprTokenPtr = parsePtr->tokenPtr + parsePtr->numTokens;
+		memcpy(subExprTokenPtr, tokenPtr,
+			(size_t) toCopy * sizeof(Tcl_Token));
+		subExprTokenPtr->type = TCL_TOKEN_SUB_EXPR;
+		parsePtr->numTokens += toCopy;
+	    } else {
+		/*
+		 * Multiple element word. Create a TCL_TOKEN_SUB_EXPR token to
+		 * lead, with fields initialized from the leading token, then
+		 * copy entire set of word tokens.
+		 */
+
+		TclGrowParseTokenArray(parsePtr, toCopy+1);
+		subExprTokenPtr = parsePtr->tokenPtr + parsePtr->numTokens;
+		*subExprTokenPtr = *tokenPtr;
+		subExprTokenPtr->type = TCL_TOKEN_SUB_EXPR;
+		subExprTokenPtr->numComponents++;
+		subExprTokenPtr++;
+		memcpy(subExprTokenPtr, tokenPtr,
+			(size_t) toCopy * sizeof(Tcl_Token));
+		parsePtr->numTokens += toCopy + 1;
+	    }
+
+	    scanned = tokenPtr->start + tokenPtr->size - start;
+	    start += scanned;
+	    numBytes -= scanned;
+	    tokenPtr += toCopy;
+	    break;
+	}
+
+	default:
+
+	    /*
+	     * Advance to the child node, which is an operator.
+	     */
+
+	    nodePtr = nodes + next;
+
+	    /*
+	     * Skip any white space that comes before the subexpression.
+	     */
+
+	    scanned = TclParseAllWhiteSpace(start, numBytes);
+	    start += scanned;
+	    numBytes -= scanned;
+
+	    /*
+	     * Generate tokens for the operator / subexpression...
+	     */
+
+	    switch (nodePtr->lexeme) {
+	    case OPEN_PAREN:
+	    case COMMA:
+	    case COLON:
+
+		/*
+		 * Historical practice has been to have no Tcl_Tokens for
+		 * these operators.
+		 */
+
+		break;
+
+	    default: {
+
+		/*
+		 * Remember the index of the last subexpression we were
+		 * working on -- that of our parent. We'll stack it later.
+		 */
+
+		parentIdx = subExprTokenIdx;
+
+		/*
+		 * Verify space for the two leading Tcl_Tokens representing
+		 * the subexpression rooted by this operator. The first
+		 * Tcl_Token will be of type TCL_TOKEN_SUB_EXPR; the second of
+		 * type TCL_TOKEN_OPERATOR.
+		 */
+
+		TclGrowParseTokenArray(parsePtr, 2);
+		subExprTokenIdx = parsePtr->numTokens;
+		subExprTokenPtr = parsePtr->tokenPtr + subExprTokenIdx;
+		parsePtr->numTokens += 2;
+		subExprTokenPtr->type = TCL_TOKEN_SUB_EXPR;
+		subExprTokenPtr[1].type = TCL_TOKEN_OPERATOR;
+
+		/*
+		 * Our current position scanning the string is the starting
+		 * point for this subexpression.
+		 */
+
+		subExprTokenPtr->start = start;
+
+		/*
+		 * Eventually, we know that the numComponents field of the
+		 * Tcl_Token of type TCL_TOKEN_OPERATOR will be 0. This means
+		 * we can make other use of this field for now to track the
+		 * stack of subexpressions we have pending.
+		 */
+
+		subExprTokenPtr[1].numComponents = parentIdx;
+		break;
+	    }
+	    }
+	    break;
+	}
+
+	/* Determine which way to exit the node on this pass. */
+    router:
+	switch (nodePtr->mark) {
+	case MARK_LEFT:
+	    next = nodePtr->left;
+	    break;
+
+	case MARK_RIGHT:
+	    next = nodePtr->right;
+
+	    /*
+	     * Skip any white space that comes before the operator.
+	     */
+
+	    scanned = TclParseAllWhiteSpace(start, numBytes);
+	    start += scanned;
+	    numBytes -= scanned;
+
+	    /*
+	     * Here we scan from the string the operator corresponding to
+	     * nodePtr->lexeme.
+	     */
+
+	    scanned = ParseLexeme(start, numBytes, &lexeme, NULL);
+
+	    switch(nodePtr->lexeme) {
+	    case OPEN_PAREN:
+	    case COMMA:
+	    case COLON:
+
+		/*
+		 * No tokens for these lexemes -> nothing to do.
+		 */
+
+		break;
+
+	    default:
+
+		/*
+		 * Record in the TCL_TOKEN_OPERATOR token the pointers into
+		 * the string marking where the operator is.
+		 */
+
+		subExprTokenPtr = parsePtr->tokenPtr + subExprTokenIdx;
+		subExprTokenPtr[1].start = start;
+		subExprTokenPtr[1].size = scanned;
+		break;
+	    }
+
+	    start += scanned;
+	    numBytes -= scanned;
+	    break;
+
+	case MARK_PARENT:
+	    switch (nodePtr->lexeme) {
+	    case START:
+
+		/* When we get back to the START node, we're done. */
+		return;
+
+	    case COMMA:
+	    case COLON:
+
+		/* No tokens for these lexemes -> nothing to do. */
+		break;
+
+	    case OPEN_PAREN:
+
+		/*
+		 * Skip past matching close paren.
+		 */
+
+		scanned = TclParseAllWhiteSpace(start, numBytes);
+		start += scanned;
+		numBytes -= scanned;
+		scanned = ParseLexeme(start, numBytes, &lexeme, NULL);
+		start += scanned;
+		numBytes -= scanned;
+		break;
+
+	    default:
+
+		/*
+		 * Before we leave this node/operator/subexpression for the
+		 * last time, finish up its tokens....
+		 *
+		 * Our current position scanning the string is where the
+		 * substring for the subexpression ends.
+		 */
+
+		subExprTokenPtr = parsePtr->tokenPtr + subExprTokenIdx;
+		subExprTokenPtr->size = start - subExprTokenPtr->start;
+
+		/*
+		 * All the Tcl_Tokens allocated and filled belong to
+		 * this subexpresion. The first token is the leading
+		 * TCL_TOKEN_SUB_EXPR token, and all the rest (one fewer)
+		 * are its components.
+		 */
+
+		subExprTokenPtr->numComponents =
+			(parsePtr->numTokens - subExprTokenIdx) - 1;
+
+		/*
+		 * Finally, as we return up the tree to our parent, pop the
+		 * parent subexpression off our subexpression stack, and
+		 * fill in the zero numComponents for the operator Tcl_Token.
+		 */
+
+		parentIdx = subExprTokenPtr[1].numComponents;
+		subExprTokenPtr[1].numComponents = 0;
+		subExprTokenIdx = parentIdx;
+		break;
+	    }
+
+	    /*
+	     * Since we're returning to parent, skip child handling code.
+	     */
+
+	    nodePtr = nodes + nodePtr->p.parent;
+	    goto router;
+	}
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_ParseExpr --
+ *
+ *	Given a string, the numBytes bytes starting at start, this function
+ *	parses it as a Tcl expression and stores information about the
+ *	structure of the expression in the Tcl_Parse struct indicated by the
+ *	caller.
+ *
+ * Results:
+ *	If the string is successfully parsed as a valid Tcl expression, TCL_OK
+ *	is returned, and data about the expression structure is written to
+ *	*parsePtr. If the string cannot be parsed as a valid Tcl expression,
+ *	TCL_ERROR is returned, and if interp is non-NULL, an error message is
+ *	written to interp.
+ *
+ * Side effects:
+ *	If there is insufficient space in parsePtr to hold all the information
+ *	about the expression, then additional space is malloc-ed. If the
+ *	function returns TCL_OK then the caller must eventually invoke
+ *	Tcl_FreeParse to release any additional space that was allocated.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_ParseExpr(
+    Tcl_Interp *interp,		/* Used for error reporting. */
+    const char *start,		/* Start of source string to parse. */
+    int numBytes,		/* Number of bytes in string. If < 0, the
+				 * string consists of all bytes up to the
+				 * first null character. */
+    Tcl_Parse *parsePtr)	/* Structure to fill with information about
+				 * the parsed expression; any previous
+				 * information in the structure is ignored. */
+{
+    int code;
+    OpNode *opTree = NULL;	/* Will point to the tree of operators. */
+    Tcl_Obj *litList = Tcl_NewObj();	/* List to hold the literals. */
+    Tcl_Obj *funcList = Tcl_NewObj();	/* List to hold the functon names. */
+    Tcl_Parse *exprParsePtr = TclStackAlloc(interp, sizeof(Tcl_Parse));
+				/* Holds the Tcl_Tokens of substitutions. */
+
+    if (numBytes < 0) {
+	numBytes = (start ? strlen(start) : 0);
+    }
+
+    code = ParseExpr(interp, start, numBytes, &opTree, litList, funcList,
+	    exprParsePtr, 1 /* parseOnly */);
+    Tcl_DecrRefCount(funcList);
+    Tcl_DecrRefCount(litList);
+
+    TclParseInit(interp, start, numBytes, parsePtr);
+    if (code == TCL_OK) {
+	ConvertTreeToTokens(start, numBytes,
+		opTree, exprParsePtr->tokenPtr, parsePtr);
+    } else {
+	parsePtr->term = exprParsePtr->term;
+	parsePtr->errorType = exprParsePtr->errorType;
+    }
+
+    Tcl_FreeParse(exprParsePtr);
+    TclStackFree(interp, exprParsePtr);
+    ckfree(opTree);
+    return code;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ParseLexeme --
+ *
+ *	Parse a single lexeme from the start of a string, scanning no more
+ *	than numBytes bytes.
+ *
+ * Results:
+ *	Returns the number of bytes scanned to produce the lexeme.
+ *
+ * Side effects:
+ *	Code identifying lexeme parsed is writen to *lexemePtr.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+ParseLexeme(
+    const char *start,		/* Start of lexeme to parse. */
+    int numBytes,		/* Number of bytes in string. */
+    unsigned char *lexemePtr,	/* Write code of parsed lexeme to this
+				 * storage. */
+    Tcl_Obj **literalPtr)	/* Write corresponding literal value to this
+				   storage, if non-NULL. */
+{
+    const char *end;
+    int scanned;
+    Tcl_UniChar ch;
+    Tcl_Obj *literal = NULL;
+    unsigned char byte;
+
+    if (numBytes == 0) {
+	*lexemePtr = END;
+	return 0;
+    }
+    byte = UCHAR(*start);
+    if (byte < sizeof(Lexeme) && Lexeme[byte] != 0) {
+	*lexemePtr = Lexeme[byte];
+	return 1;
+    }
+    switch (byte) {
+    case '*':
+	if ((numBytes > 1) && (start[1] == '*')) {
+	    *lexemePtr = EXPON;
+	    return 2;
+	}
+	*lexemePtr = MULT;
+	return 1;
+
+    case '=':
+	if ((numBytes > 1) && (start[1] == '=')) {
+	    *lexemePtr = EQUAL;
+	    return 2;
+	}
+	*lexemePtr = INCOMPLETE;
+	return 1;
+
+    case '!':
+	if ((numBytes > 1) && (start[1] == '=')) {
+	    *lexemePtr = NEQ;
+	    return 2;
+	}
+	*lexemePtr = NOT;
+	return 1;
+
+    case '&':
+	if ((numBytes > 1) && (start[1] == '&')) {
+	    *lexemePtr = AND;
+	    return 2;
+	}
+	*lexemePtr = BIT_AND;
+	return 1;
+
+    case '|':
+	if ((numBytes > 1) && (start[1] == '|')) {
+	    *lexemePtr = OR;
+	    return 2;
+	}
+	*lexemePtr = BIT_OR;
+	return 1;
+
+    case '<':
+	if (numBytes > 1) {
+	    switch (start[1]) {
+	    case '<':
+		*lexemePtr = LEFT_SHIFT;
+		return 2;
+	    case '=':
+		*lexemePtr = LEQ;
+		return 2;
+	    }
+	}
+	*lexemePtr = LESS;
+	return 1;
+
+    case '>':
+	if (numBytes > 1) {
+	    switch (start[1]) {
+	    case '>':
+		*lexemePtr = RIGHT_SHIFT;
+		return 2;
+	    case '=':
+		*lexemePtr = GEQ;
+		return 2;
+	    }
+	}
+	*lexemePtr = GREATER;
+	return 1;
+
+    case 'i':
+	if ((numBytes > 1) && (start[1] == 'n')
+		&& ((numBytes == 2) || start[2] & 0x80 || !isalpha(UCHAR(start[2])))) {
+	    /*
+	     * Must make this check so we can tell the difference between the
+	     * "in" operator and the "int" function name and the "infinity"
+	     * numeric value.
+	     */
+
+	    *lexemePtr = IN_LIST;
+	    return 2;
+	}
+	break;
+
+    case 'e':
+	if ((numBytes > 1) && (start[1] == 'q')
+		&& ((numBytes == 2) || start[2] & 0x80 || !isalpha(UCHAR(start[2])))) {
+	    *lexemePtr = STREQ;
+	    return 2;
+	}
+	break;
+
+    case 'n':
+	if ((numBytes > 1)
+		&& ((numBytes == 2) || start[2] & 0x80 || !isalpha(UCHAR(start[2])))) {
+	    switch (start[1]) {
+	    case 'e':
+		*lexemePtr = STRNEQ;
+		return 2;
+	    case 'i':
+		*lexemePtr = NOT_IN_LIST;
+		return 2;
+	    }
+	}
+    }
+
+    literal = Tcl_NewObj();
+    if (TclParseNumber(NULL, literal, NULL, start, numBytes, &end,
+	    TCL_PARSE_NO_WHITESPACE) == TCL_OK) {
+	if (end < start + numBytes && !TclIsBareword(*end)) {
+
+	number:
+	    TclInitStringRep(literal, start, end-start);
+	    *lexemePtr = NUMBER;
+	    if (literalPtr) {
+		*literalPtr = literal;
+	    } else {
+		Tcl_DecrRefCount(literal);
+	    }
+	    return (end-start);
+	} else {
+	    unsigned char lexeme;
+
+	    /*
+	     * We have a number followed directly by bareword characters
+	     * (alpha, digit, underscore).  Is this a number followed by
+	     * bareword syntax error?  Or should we join into one bareword?
+	     * Example: Inf + luence + () becomes a valid function call.
+	     * [Bug 3401704]
+	     */
+	    if (literal->typePtr == &tclDoubleType) {
+		const char *p = start;
+
+		while (p < end) {
+		    if (!TclIsBareword(*p++)) {
+			/*
+			 * The number has non-bareword characters, so we
+			 * must treat it as a number.
+			 */
+			goto number;
+		    }
+		}
+	    }
+	    ParseLexeme(end, numBytes-(end-start), &lexeme, NULL);
+	    if ((NODE_TYPE & lexeme) == BINARY) {
+		/*
+		 * The bareword characters following the number take the
+		 * form of an operator (eq, ne, in, ni, ...) so we treat
+		 * as number + operator.
+		 */
+		goto number;
+	    }
+
+	    /*
+	     * Otherwise, fall through and parse the whole as a bareword.
+	     */
+	}
+    }
+
+    /*
+     * We reject leading underscores in bareword.  No sensible reason why.
+     * Might be inspired by reserved identifier rules in C, which of course
+     * have no direct relevance here.
+     */
+
+    if (!TclIsBareword(*start) || *start == '_') {
+	if (Tcl_UtfCharComplete(start, numBytes)) {
+	    scanned = Tcl_UtfToUniChar(start, &ch);
+	} else {
+	    char utfBytes[TCL_UTF_MAX];
+
+	    memcpy(utfBytes, start, (size_t) numBytes);
+	    utfBytes[numBytes] = '\0';
+	    scanned = Tcl_UtfToUniChar(utfBytes, &ch);
+	}
+	*lexemePtr = INVALID;
+	Tcl_DecrRefCount(literal);
+	return scanned;
+    }
+    end = start;
+    while (numBytes && TclIsBareword(*end)) {
+	end += 1;
+	numBytes -= 1;
+    }
+    *lexemePtr = BAREWORD;
+    if (literalPtr) {
+	Tcl_SetStringObj(literal, start, (int) (end-start));
+	*literalPtr = literal;
+    } else {
+	Tcl_DecrRefCount(literal);
+    }
+    return (end-start);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclCompileExpr --
+ *
+ *	This procedure compiles a string containing a Tcl expression into Tcl
+ *	bytecodes.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Adds instructions to envPtr to evaluate the expression at runtime.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclCompileExpr(
+    Tcl_Interp *interp,		/* Used for error reporting. */
+    const char *script,		/* The source script to compile. */
+    int numBytes,		/* Number of bytes in script. */
+    CompileEnv *envPtr,		/* Holds resulting instructions. */
+    int optimize)		/* 0 for one-off expressions. */
+{
+    OpNode *opTree = NULL;	/* Will point to the tree of operators */
+    Tcl_Obj *litList = Tcl_NewObj();	/* List to hold the literals */
+    Tcl_Obj *funcList = Tcl_NewObj();	/* List to hold the functon names*/
+    Tcl_Parse *parsePtr = TclStackAlloc(interp, sizeof(Tcl_Parse));
+				/* Holds the Tcl_Tokens of substitutions */
+
+    int code = ParseExpr(interp, script, numBytes, &opTree, litList,
+	    funcList, parsePtr, 0 /* parseOnly */);
+
+    if (code == TCL_OK) {
+	/*
+	 * Valid parse; compile the tree.
+	 */
+
+	int objc;
+	Tcl_Obj *const *litObjv;
+	Tcl_Obj **funcObjv;
+
+	/* TIP #280 : Track Lines within the expression */
+	TclAdvanceLines(&envPtr->line, script,
+		script + TclParseAllWhiteSpace(script, numBytes));
+
+	TclListObjGetElements(NULL, litList, &objc, (Tcl_Obj ***)&litObjv);
+	TclListObjGetElements(NULL, funcList, &objc, &funcObjv);
+	CompileExprTree(interp, opTree, 0, &litObjv, funcObjv,
+		parsePtr->tokenPtr, envPtr, optimize);
+    } else {
+	TclCompileSyntaxError(interp, envPtr);
+    }
+
+    Tcl_FreeParse(parsePtr);
+    TclStackFree(interp, parsePtr);
+    Tcl_DecrRefCount(funcList);
+    Tcl_DecrRefCount(litList);
+    ckfree(opTree);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ExecConstantExprTree --
+ *	Compiles and executes bytecode for the subexpression tree at index
+ *	in the nodes array.  This subexpression must be constant, made up
+ *	of only constant operators (not functions) and literals.
+ *
+ * Results:
+ *	A standard Tcl return code and result left in interp.
+ *
+ * Side effects:
+ *	Consumes subtree of nodes rooted at index.  Advances the pointer
+ *	*litObjvPtr.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+ExecConstantExprTree(
+    Tcl_Interp *interp,
+    OpNode *nodes,
+    int index,
+    Tcl_Obj *const **litObjvPtr)
+{
+    CompileEnv *envPtr;
+    ByteCode *byteCodePtr;
+    int code;
+    Tcl_Obj *byteCodeObj = Tcl_NewObj();
+    NRE_callback *rootPtr = TOP_CB(interp);
+
+    /*
+     * Note we are compiling an expression with literal arguments. This means
+     * there can be no [info frame] calls when we execute the resulting
+     * bytecode, so there's no need to tend to TIP 280 issues.
+     */
+
+    envPtr = TclStackAlloc(interp, sizeof(CompileEnv));
+    TclInitCompileEnv(interp, envPtr, NULL, 0, NULL, 0);
+    CompileExprTree(interp, nodes, index, litObjvPtr, NULL, NULL, envPtr,
+	    0 /* optimize */);
+    TclEmitOpcode(INST_DONE, envPtr);
+    Tcl_IncrRefCount(byteCodeObj);
+    TclInitByteCodeObj(byteCodeObj, envPtr);
+    TclFreeCompileEnv(envPtr);
+    TclStackFree(interp, envPtr);
+    byteCodePtr = byteCodeObj->internalRep.twoPtrValue.ptr1;
+    TclNRExecuteByteCode(interp, byteCodePtr);
+    code = TclNRRunCallbacks(interp, TCL_OK, rootPtr);
+    Tcl_DecrRefCount(byteCodeObj);
+    return code;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * CompileExprTree --
+ *
+ *	Compiles and writes to envPtr instructions for the subexpression tree
+ *	at index in the nodes array. (*litObjvPtr) must point to the proper
+ *	location in a corresponding literals list. Likewise, when non-NULL,
+ *	funcObjv and tokenPtr must point into matching arrays of function
+ *	names and Tcl_Token's derived from earlier call to ParseExpr(). When
+ *	optimize is true, any constant subexpressions will be precomputed.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Adds instructions to envPtr to evaluate the expression at runtime.
+ *	Consumes subtree of nodes rooted at index. Advances the pointer
+ *	*litObjvPtr.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+CompileExprTree(
+    Tcl_Interp *interp,
+    OpNode *nodes,
+    int index,
+    Tcl_Obj *const **litObjvPtr,
+    Tcl_Obj *const *funcObjv,
+    Tcl_Token *tokenPtr,
+    CompileEnv *envPtr,
+    int optimize)
+{
+    OpNode *nodePtr = nodes + index;
+    OpNode *rootPtr = nodePtr;
+    int numWords = 0;
+    JumpList *jumpPtr = NULL;
+    int convert = 1;
+
+    while (1) {
+	int next;
+	JumpList *freePtr, *newJump;
+
+	if (nodePtr->mark == MARK_LEFT) {
+	    next = nodePtr->left;
+
+	    if (nodePtr->lexeme == QUESTION) {
+		convert = 1;
+	    }
+	} else if (nodePtr->mark == MARK_RIGHT) {
+	    next = nodePtr->right;
+
+	    switch (nodePtr->lexeme) {
+	    case FUNCTION: {
+		Tcl_DString cmdName;
+		const char *p;
+		int length;
+
+		Tcl_DStringInit(&cmdName);
+		TclDStringAppendLiteral(&cmdName, "tcl::mathfunc::");
+		p = TclGetStringFromObj(*funcObjv, &length);
+		funcObjv++;
+		Tcl_DStringAppend(&cmdName, p, length);
+		TclEmitPush(TclRegisterNewCmdLiteral(envPtr,
+			Tcl_DStringValue(&cmdName),
+			Tcl_DStringLength(&cmdName)), envPtr);
+		Tcl_DStringFree(&cmdName);
+
+		/*
+		 * Start a count of the number of words in this function
+		 * command invocation. In case there's already a count in
+		 * progress (nested functions), save it in our unused "left"
+		 * field for restoring later.
+		 */
+
+		nodePtr->left = numWords;
+		numWords = 2;	/* Command plus one argument */
+		break;
+	    }
+	    case QUESTION:
+		newJump = TclStackAlloc(interp, sizeof(JumpList));
+		newJump->next = jumpPtr;
+		jumpPtr = newJump;
+		TclEmitForwardJump(envPtr, TCL_FALSE_JUMP, &jumpPtr->jump);
+		break;
+	    case COLON:
+		newJump = TclStackAlloc(interp, sizeof(JumpList));
+		newJump->next = jumpPtr;
+		jumpPtr = newJump;
+		TclEmitForwardJump(envPtr, TCL_UNCONDITIONAL_JUMP,
+			&jumpPtr->jump);
+		TclAdjustStackDepth(-1, envPtr);
+		if (convert) {
+		    jumpPtr->jump.jumpType = TCL_TRUE_JUMP;
+		}
+		convert = 1;
+		break;
+	    case AND:
+	    case OR:
+		newJump = TclStackAlloc(interp, sizeof(JumpList));
+		newJump->next = jumpPtr;
+		jumpPtr = newJump;
+		TclEmitForwardJump(envPtr, (nodePtr->lexeme == AND)
+			?  TCL_FALSE_JUMP : TCL_TRUE_JUMP, &jumpPtr->jump);
+		break;
+	    }
+	} else {
+	    int pc1, pc2, target;
+
+	    switch (nodePtr->lexeme) {
+	    case START:
+	    case QUESTION:
+		if (convert && (nodePtr == rootPtr)) {
+		    TclEmitOpcode(INST_TRY_CVT_TO_NUMERIC, envPtr);
+		}
+		break;
+	    case OPEN_PAREN:
+
+		/* do nothing */
+		break;
+	    case FUNCTION:
+		/*
+		 * Use the numWords count we've kept to invoke the function
+		 * command with the correct number of arguments.
+		 */
+
+		if (numWords < 255) {
+		    TclEmitInvoke(envPtr, INST_INVOKE_STK1, numWords);
+		} else {
+		    TclEmitInvoke(envPtr, INST_INVOKE_STK4, numWords);
+		}
+
+		/*
+		 * Restore any saved numWords value.
+		 */
+
+		numWords = nodePtr->left;
+		convert = 1;
+		break;
+	    case COMMA:
+		/*
+		 * Each comma implies another function argument.
+		 */
+
+		numWords++;
+		break;
+	    case COLON:
+		CLANG_ASSERT(jumpPtr);
+		if (jumpPtr->jump.jumpType == TCL_TRUE_JUMP) {
+		    jumpPtr->jump.jumpType = TCL_UNCONDITIONAL_JUMP;
+		    convert = 1;
+		}
+		target = jumpPtr->jump.codeOffset + 2;
+		if (TclFixupForwardJumpToHere(envPtr, &jumpPtr->jump, 127)) {
+		    target += 3;
+		}
+		freePtr = jumpPtr;
+		jumpPtr = jumpPtr->next;
+		TclStackFree(interp, freePtr);
+		TclFixupForwardJump(envPtr, &jumpPtr->jump,
+			target - jumpPtr->jump.codeOffset, 127);
+
+		freePtr = jumpPtr;
+		jumpPtr = jumpPtr->next;
+		TclStackFree(interp, freePtr);
+		break;
+	    case AND:
+	    case OR:
+		CLANG_ASSERT(jumpPtr);
+		pc1 = CurrentOffset(envPtr);
+		TclEmitInstInt1((nodePtr->lexeme == AND) ? INST_JUMP_FALSE1
+			: INST_JUMP_TRUE1, 0, envPtr);
+		TclEmitPush(TclRegisterNewLiteral(envPtr,
+			(nodePtr->lexeme == AND) ? "1" : "0", 1), envPtr);
+		pc2 = CurrentOffset(envPtr);
+		TclEmitInstInt1(INST_JUMP1, 0, envPtr);
+		TclAdjustStackDepth(-1, envPtr);
+		TclStoreInt1AtPtr(CurrentOffset(envPtr) - pc1,
+			envPtr->codeStart + pc1 + 1);
+		if (TclFixupForwardJumpToHere(envPtr, &jumpPtr->jump, 127)) {
+		    pc2 += 3;
+		}
+		TclEmitPush(TclRegisterNewLiteral(envPtr,
+			(nodePtr->lexeme == AND) ? "0" : "1", 1), envPtr);
+		TclStoreInt1AtPtr(CurrentOffset(envPtr) - pc2,
+			envPtr->codeStart + pc2 + 1);
+		convert = 0;
+		freePtr = jumpPtr;
+		jumpPtr = jumpPtr->next;
+		TclStackFree(interp, freePtr);
+		break;
+	    default:
+		TclEmitOpcode(instruction[nodePtr->lexeme], envPtr);
+		convert = 0;
+		break;
+	    }
+	    if (nodePtr == rootPtr) {
+		/* We're done */
+
+		return;
+	    }
+	    nodePtr = nodes + nodePtr->p.parent;
+	    continue;
+	}
+
+	nodePtr->mark++;
+	switch (next) {
+	case OT_EMPTY:
+	    numWords = 1;	/* No arguments, so just the command */
+	    break;
+	case OT_LITERAL: {
+	    Tcl_Obj *const *litObjv = *litObjvPtr;
+	    Tcl_Obj *literal = *litObjv;
+
+	    if (optimize) {
+		int length;
+		const char *bytes = TclGetStringFromObj(literal, &length);
+		int index = TclRegisterNewLiteral(envPtr, bytes, length);
+		Tcl_Obj *objPtr = TclFetchLiteral(envPtr, index);
+
+		if ((objPtr->typePtr == NULL) && (literal->typePtr != NULL)) {
+		    /*
+		     * Would like to do this:
+		     *
+		     * lePtr->objPtr = literal;
+		     * Tcl_IncrRefCount(literal);
+		     * Tcl_DecrRefCount(objPtr);
+		     *
+		     * However, the design of the "global" and "local"
+		     * LiteralTable does not permit the value of lePtr->objPtr
+		     * to change. So rather than replace lePtr->objPtr, we do
+		     * surgery to transfer our desired intrep into it.
+		     */
+
+		    objPtr->typePtr = literal->typePtr;
+		    objPtr->internalRep = literal->internalRep;
+		    literal->typePtr = NULL;
+		}
+		TclEmitPush(index, envPtr);
+	    } else {
+		/*
+		 * When optimize==0, we know the expression is a one-off and
+		 * there's nothing to be gained from sharing literals when
+		 * they won't live long, and the copies we have already have
+		 * an appropriate intrep. In this case, skip literal
+		 * registration that would enable sharing, and use the routine
+		 * that preserves intreps.
+		 */
+
+		TclEmitPush(TclAddLiteralObj(envPtr, literal, NULL), envPtr);
+	    }
+	    (*litObjvPtr)++;
+	    break;
+	}
+	case OT_TOKENS:
+	    CompileTokens(envPtr, tokenPtr, interp);
+	    tokenPtr += tokenPtr->numComponents + 1;
+	    break;
+	default:
+	    if (optimize && nodes[next].constant) {
+		Tcl_InterpState save = Tcl_SaveInterpState(interp, TCL_OK);
+
+		if (ExecConstantExprTree(interp, nodes, next, litObjvPtr)
+			== TCL_OK) {
+		    int index;
+		    Tcl_Obj *objPtr = Tcl_GetObjResult(interp);
+
+		    /*
+		     * Don't generate a string rep, but if we have one
+		     * already, then use it to share via the literal table.
+		     */
+
+		    if (objPtr->bytes) {
+			Tcl_Obj *tableValue;
+
+			index = TclRegisterNewLiteral(envPtr, objPtr->bytes,
+				objPtr->length);
+			tableValue = TclFetchLiteral(envPtr, index);
+			if ((tableValue->typePtr == NULL) &&
+				(objPtr->typePtr != NULL)) {
+			    /*
+			     * Same intrep surgery as for OT_LITERAL.
+			     */
+
+			    tableValue->typePtr = objPtr->typePtr;
+			    tableValue->internalRep = objPtr->internalRep;
+			    objPtr->typePtr = NULL;
+			}
+		    } else {
+			index = TclAddLiteralObj(envPtr, objPtr, NULL);
+		    }
+		    TclEmitPush(index, envPtr);
+		} else {
+		    TclCompileSyntaxError(interp, envPtr);
+		}
+		Tcl_RestoreInterpState(interp, save);
+		convert = 0;
+	    } else {
+		nodePtr = nodes + next;
+	    }
+	}
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclSingleOpCmd --
+ *
+ *	Implements the commands: ~, !, <<, >>, %, !=, ne, in, ni
+ *	in the ::tcl::mathop namespace.  These commands have no
+ *	extension to arbitrary arguments; they accept only exactly one
+ *	or exactly two arguments as suitable for the operator.
+ *
+ * Results:
+ *	A standard Tcl return code and result left in interp.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclSingleOpCmd(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const objv[])
+{
+    TclOpCmdClientData *occdPtr = clientData;
+    unsigned char lexeme;
+    OpNode nodes[2];
+    Tcl_Obj *const *litObjv = objv + 1;
+
+    if (objc != 1 + occdPtr->i.numArgs) {
+	Tcl_WrongNumArgs(interp, 1, objv, occdPtr->expected);
+	return TCL_ERROR;
+    }
+
+    ParseLexeme(occdPtr->op, strlen(occdPtr->op), &lexeme, NULL);
+    nodes[0].lexeme = START;
+    nodes[0].mark = MARK_RIGHT;
+    nodes[0].right = 1;
+    nodes[1].lexeme = lexeme;
+    if (objc == 2) {
+	nodes[1].mark = MARK_RIGHT;
+    } else {
+	nodes[1].mark = MARK_LEFT;
+	nodes[1].left = OT_LITERAL;
+    }
+    nodes[1].right = OT_LITERAL;
+    nodes[1].p.parent = 0;
+
+    return ExecConstantExprTree(interp, nodes, 0, &litObjv);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclSortingOpCmd --
+ *	Implements the commands:
+ *		<, <=, >, >=, ==, eq
+ *	in the ::tcl::mathop namespace. These commands are defined for
+ *	arbitrary number of arguments by computing the AND of the base
+ *	operator applied to all neighbor argument pairs.
+ *
+ * Results:
+ *	A standard Tcl return code and result left in interp.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclSortingOpCmd(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const objv[])
+{
+    int code = TCL_OK;
+
+    if (objc < 3) {
+	Tcl_SetObjResult(interp, Tcl_NewBooleanObj(1));
+    } else {
+	TclOpCmdClientData *occdPtr = clientData;
+	Tcl_Obj **litObjv = TclStackAlloc(interp,
+		2 * (objc-2) * sizeof(Tcl_Obj *));
+	OpNode *nodes = TclStackAlloc(interp, 2 * (objc-2) * sizeof(OpNode));
+	unsigned char lexeme;
+	int i, lastAnd = 1;
+	Tcl_Obj *const *litObjPtrPtr = litObjv;
+
+	ParseLexeme(occdPtr->op, strlen(occdPtr->op), &lexeme, NULL);
+
+	litObjv[0] = objv[1];
+	nodes[0].lexeme = START;
+	nodes[0].mark = MARK_RIGHT;
+	for (i=2; i<objc-1; i++) {
+	    litObjv[2*(i-1)-1] = objv[i];
+	    nodes[2*(i-1)-1].lexeme = lexeme;
+	    nodes[2*(i-1)-1].mark = MARK_LEFT;
+	    nodes[2*(i-1)-1].left = OT_LITERAL;
+	    nodes[2*(i-1)-1].right = OT_LITERAL;
+
+	    litObjv[2*(i-1)] = objv[i];
+	    nodes[2*(i-1)].lexeme = AND;
+	    nodes[2*(i-1)].mark = MARK_LEFT;
+	    nodes[2*(i-1)].left = lastAnd;
+	    nodes[lastAnd].p.parent = 2*(i-1);
+
+	    nodes[2*(i-1)].right = 2*(i-1)+1;
+	    nodes[2*(i-1)+1].p.parent= 2*(i-1);
+
+	    lastAnd = 2*(i-1);
+	}
+	litObjv[2*(objc-2)-1] = objv[objc-1];
+
+	nodes[2*(objc-2)-1].lexeme = lexeme;
+	nodes[2*(objc-2)-1].mark = MARK_LEFT;
+	nodes[2*(objc-2)-1].left = OT_LITERAL;
+	nodes[2*(objc-2)-1].right = OT_LITERAL;
+
+	nodes[0].right = lastAnd;
+	nodes[lastAnd].p.parent = 0;
+
+	code = ExecConstantExprTree(interp, nodes, 0, &litObjPtrPtr);
+
+	TclStackFree(interp, nodes);
+	TclStackFree(interp, litObjv);
+    }
+    return code;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclVariadicOpCmd --
+ *	Implements the commands: +, *, &, |, ^, **
+ *	in the ::tcl::mathop namespace. These commands are defined for
+ *	arbitrary number of arguments by repeatedly applying the base
+ *	operator with suitable associative rules. When fewer than two
+ *	arguments are provided, suitable identity values are returned.
+ *
+ * Results:
+ *	A standard Tcl return code and result left in interp.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclVariadicOpCmd(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const objv[])
+{
+    TclOpCmdClientData *occdPtr = clientData;
+    unsigned char lexeme;
+    int code;
+
+    if (objc < 2) {
+	Tcl_SetObjResult(interp, Tcl_NewIntObj(occdPtr->i.identity));
+	return TCL_OK;
+    }
+
+    ParseLexeme(occdPtr->op, strlen(occdPtr->op), &lexeme, NULL);
+    lexeme |= BINARY;
+
+    if (objc == 2) {
+	Tcl_Obj *litObjv[2];
+	OpNode nodes[2];
+	int decrMe = 0;
+	Tcl_Obj *const *litObjPtrPtr = litObjv;
+
+	if (lexeme == EXPON) {
+	    litObjv[1] = Tcl_NewIntObj(occdPtr->i.identity);
+	    Tcl_IncrRefCount(litObjv[1]);
+	    decrMe = 1;
+	    litObjv[0] = objv[1];
+	    nodes[0].lexeme = START;
+	    nodes[0].mark = MARK_RIGHT;
+	    nodes[0].right = 1;
+	    nodes[1].lexeme = lexeme;
+	    nodes[1].mark = MARK_LEFT;
+	    nodes[1].left = OT_LITERAL;
+	    nodes[1].right = OT_LITERAL;
+	    nodes[1].p.parent = 0;
+	} else {
+	    if (lexeme == DIVIDE) {
+		litObjv[0] = Tcl_NewDoubleObj(1.0);
+	    } else {
+		litObjv[0] = Tcl_NewIntObj(occdPtr->i.identity);
+	    }
+	    Tcl_IncrRefCount(litObjv[0]);
+	    litObjv[1] = objv[1];
+	    nodes[0].lexeme = START;
+	    nodes[0].mark = MARK_RIGHT;
+	    nodes[0].right = 1;
+	    nodes[1].lexeme = lexeme;
+	    nodes[1].mark = MARK_LEFT;
+	    nodes[1].left = OT_LITERAL;
+	    nodes[1].right = OT_LITERAL;
+	    nodes[1].p.parent = 0;
+	}
+
+	code = ExecConstantExprTree(interp, nodes, 0, &litObjPtrPtr);
+
+	Tcl_DecrRefCount(litObjv[decrMe]);
+	return code;
+    } else {
+	Tcl_Obj *const *litObjv = objv + 1;
+	OpNode *nodes = TclStackAlloc(interp, (objc-1) * sizeof(OpNode));
+	int i, lastOp = OT_LITERAL;
+
+	nodes[0].lexeme = START;
+	nodes[0].mark = MARK_RIGHT;
+	if (lexeme == EXPON) {
+	    for (i=objc-2; i>0; i--) {
+		nodes[i].lexeme = lexeme;
+		nodes[i].mark = MARK_LEFT;
+		nodes[i].left = OT_LITERAL;
+		nodes[i].right = lastOp;
+		if (lastOp >= 0) {
+		    nodes[lastOp].p.parent = i;
+		}
+		lastOp = i;
+	    }
+	} else {
+	    for (i=1; i<objc-1; i++) {
+		nodes[i].lexeme = lexeme;
+		nodes[i].mark = MARK_LEFT;
+		nodes[i].left = lastOp;
+		if (lastOp >= 0) {
+		    nodes[lastOp].p.parent = i;
+		}
+		nodes[i].right = OT_LITERAL;
+		lastOp = i;
+	    }
+	}
+	nodes[0].right = lastOp;
+	nodes[lastOp].p.parent = 0;
+
+	code = ExecConstantExprTree(interp, nodes, 0, &litObjv);
+
+	TclStackFree(interp, nodes);
+	return code;
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclNoIdentOpCmd --
+ *	Implements the commands: -, /
+ *	in the ::tcl::mathop namespace. These commands are defined for
+ *	arbitrary non-zero number of arguments by repeatedly applying the base
+ *	operator with suitable associative rules. When no arguments are
+ *	provided, an error is raised.
+ *
+ * Results:
+ *	A standard Tcl return code and result left in interp.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclNoIdentOpCmd(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const objv[])
+{
+    TclOpCmdClientData *occdPtr = clientData;
+
+    if (objc < 2) {
+	Tcl_WrongNumArgs(interp, 1, objv, occdPtr->expected);
+	return TCL_ERROR;
+    }
+    return TclVariadicOpCmd(clientData, interp, objc, objv);
+}
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tclCompile.c b/generic/tclCompile.c
new file mode 100644
index 0000000..c0203dd
--- /dev/null
+++ b/generic/tclCompile.c
@@ -0,0 +1,4474 @@
+/*
+ * tclCompile.c --
+ *
+ *	This file contains procedures that compile Tcl commands or parts of
+ *	commands (like quoted strings or nested sub-commands) into a sequence
+ *	of instructions ("bytecodes").
+ *
+ * Copyright (c) 1996-1998 Sun Microsystems, Inc.
+ * Copyright (c) 2001 by Kevin B. Kenny. All rights reserved.
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#include "tclInt.h"
+#include "tclCompile.h"
+#include <assert.h>
+
+/*
+ * Variable that controls whether compilation tracing is enabled and, if so,
+ * what level of tracing is desired:
+ *    0: no compilation tracing
+ *    1: summarize compilation of top level cmds and proc bodies
+ *    2: display all instructions of each ByteCode compiled
+ * This variable is linked to the Tcl variable "tcl_traceCompile".
+ */
+
+#ifdef TCL_COMPILE_DEBUG
+int tclTraceCompile = 0;
+static int traceInitialized = 0;
+#endif
+
+/*
+ * A table describing the Tcl bytecode instructions. Entries in this table
+ * must correspond to the instruction opcode definitions in tclCompile.h. The
+ * names "op1" and "op4" refer to an instruction's one or four byte first
+ * operand. Similarly, "stktop" and "stknext" refer to the topmost and next to
+ * topmost stack elements.
+ *
+ * Note that the load, store, and incr instructions do not distinguish local
+ * from global variables; the bytecode interpreter at runtime uses the
+ * existence of a procedure call frame to distinguish these.
+ */
+
+InstructionDesc const tclInstructionTable[] = {
+    /* Name	      Bytes stackEffect #Opnds  Operand types */
+    {"done",		  1,   -1,         0,	{OPERAND_NONE}},
+	/* Finish ByteCode execution and return stktop (top stack item) */
+    {"push1",		  2,   +1,         1,	{OPERAND_LIT1}},
+	/* Push object at ByteCode objArray[op1] */
+    {"push4",		  5,   +1,         1,	{OPERAND_LIT4}},
+	/* Push object at ByteCode objArray[op4] */
+    {"pop",		  1,   -1,         0,	{OPERAND_NONE}},
+	/* Pop the topmost stack object */
+    {"dup",		  1,   +1,         0,	{OPERAND_NONE}},
+	/* Duplicate the topmost stack object and push the result */
+    {"strcat",		  2,   INT_MIN,    1,	{OPERAND_UINT1}},
+	/* Concatenate the top op1 items and push result */
+    {"invokeStk1",	  2,   INT_MIN,    1,	{OPERAND_UINT1}},
+	/* Invoke command named objv[0]; <objc,objv> = <op1,top op1> */
+    {"invokeStk4",	  5,   INT_MIN,    1,	{OPERAND_UINT4}},
+	/* Invoke command named objv[0]; <objc,objv> = <op4,top op4> */
+    {"evalStk",		  1,   0,          0,	{OPERAND_NONE}},
+	/* Evaluate command in stktop using Tcl_EvalObj. */
+    {"exprStk",		  1,   0,          0,	{OPERAND_NONE}},
+	/* Execute expression in stktop using Tcl_ExprStringObj. */
+
+    {"loadScalar1",	  2,   1,          1,	{OPERAND_LVT1}},
+	/* Load scalar variable at index op1 <= 255 in call frame */
+    {"loadScalar4",	  5,   1,          1,	{OPERAND_LVT4}},
+	/* Load scalar variable at index op1 >= 256 in call frame */
+    {"loadScalarStk",	  1,   0,          0,	{OPERAND_NONE}},
+	/* Load scalar variable; scalar's name is stktop */
+    {"loadArray1",	  2,   0,          1,	{OPERAND_LVT1}},
+	/* Load array element; array at slot op1<=255, element is stktop */
+    {"loadArray4",	  5,   0,          1,	{OPERAND_LVT4}},
+	/* Load array element; array at slot op1 > 255, element is stktop */
+    {"loadArrayStk",	  1,   -1,         0,	{OPERAND_NONE}},
+	/* Load array element; element is stktop, array name is stknext */
+    {"loadStk",		  1,   0,          0,	{OPERAND_NONE}},
+	/* Load general variable; unparsed variable name is stktop */
+    {"storeScalar1",	  2,   0,          1,	{OPERAND_LVT1}},
+	/* Store scalar variable at op1<=255 in frame; value is stktop */
+    {"storeScalar4",	  5,   0,          1,	{OPERAND_LVT4}},
+	/* Store scalar variable at op1 > 255 in frame; value is stktop */
+    {"storeScalarStk",	  1,   -1,         0,	{OPERAND_NONE}},
+	/* Store scalar; value is stktop, scalar name is stknext */
+    {"storeArray1",	  2,   -1,         1,	{OPERAND_LVT1}},
+	/* Store array element; array at op1<=255, value is top then elem */
+    {"storeArray4",	  5,   -1,         1,	{OPERAND_LVT4}},
+	/* Store array element; array at op1>=256, value is top then elem */
+    {"storeArrayStk",	  1,   -2,         0,	{OPERAND_NONE}},
+	/* Store array element; value is stktop, then elem, array names */
+    {"storeStk",	  1,   -1,         0,	{OPERAND_NONE}},
+	/* Store general variable; value is stktop, then unparsed name */
+
+    {"incrScalar1",	  2,   0,          1,	{OPERAND_LVT1}},
+	/* Incr scalar at index op1<=255 in frame; incr amount is stktop */
+    {"incrScalarStk",	  1,   -1,         0,	{OPERAND_NONE}},
+	/* Incr scalar; incr amount is stktop, scalar's name is stknext */
+    {"incrArray1",	  2,   -1,         1,	{OPERAND_LVT1}},
+	/* Incr array elem; arr at slot op1<=255, amount is top then elem */
+    {"incrArrayStk",	  1,   -2,         0,	{OPERAND_NONE}},
+	/* Incr array element; amount is top then elem then array names */
+    {"incrStk",		  1,   -1,         0,	{OPERAND_NONE}},
+	/* Incr general variable; amount is stktop then unparsed var name */
+    {"incrScalar1Imm",	  3,   +1,         2,	{OPERAND_LVT1, OPERAND_INT1}},
+	/* Incr scalar at slot op1 <= 255; amount is 2nd operand byte */
+    {"incrScalarStkImm",  2,   0,          1,	{OPERAND_INT1}},
+	/* Incr scalar; scalar name is stktop; incr amount is op1 */
+    {"incrArray1Imm",	  3,   0,          2,	{OPERAND_LVT1, OPERAND_INT1}},
+	/* Incr array elem; array at slot op1 <= 255, elem is stktop,
+	 * amount is 2nd operand byte */
+    {"incrArrayStkImm",	  2,   -1,         1,	{OPERAND_INT1}},
+	/* Incr array element; elem is top then array name, amount is op1 */
+    {"incrStkImm",	  2,   0,	   1,	{OPERAND_INT1}},
+	/* Incr general variable; unparsed name is top, amount is op1 */
+
+    {"jump1",		  2,   0,          1,	{OPERAND_OFFSET1}},
+	/* Jump relative to (pc + op1) */
+    {"jump4",		  5,   0,          1,	{OPERAND_OFFSET4}},
+	/* Jump relative to (pc + op4) */
+    {"jumpTrue1",	  2,   -1,         1,	{OPERAND_OFFSET1}},
+	/* Jump relative to (pc + op1) if stktop expr object is true */
+    {"jumpTrue4",	  5,   -1,         1,	{OPERAND_OFFSET4}},
+	/* Jump relative to (pc + op4) if stktop expr object is true */
+    {"jumpFalse1",	  2,   -1,         1,	{OPERAND_OFFSET1}},
+	/* Jump relative to (pc + op1) if stktop expr object is false */
+    {"jumpFalse4",	  5,   -1,         1,	{OPERAND_OFFSET4}},
+	/* Jump relative to (pc + op4) if stktop expr object is false */
+
+    {"lor",		  1,   -1,         0,	{OPERAND_NONE}},
+	/* Logical or:	push (stknext || stktop) */
+    {"land",		  1,   -1,         0,	{OPERAND_NONE}},
+	/* Logical and:	push (stknext && stktop) */
+    {"bitor",		  1,   -1,         0,	{OPERAND_NONE}},
+	/* Bitwise or:	push (stknext | stktop) */
+    {"bitxor",		  1,   -1,         0,	{OPERAND_NONE}},
+	/* Bitwise xor	push (stknext ^ stktop) */
+    {"bitand",		  1,   -1,         0,	{OPERAND_NONE}},
+	/* Bitwise and:	push (stknext & stktop) */
+    {"eq",		  1,   -1,         0,	{OPERAND_NONE}},
+	/* Equal:	push (stknext == stktop) */
+    {"neq",		  1,   -1,         0,	{OPERAND_NONE}},
+	/* Not equal:	push (stknext != stktop) */
+    {"lt",		  1,   -1,         0,	{OPERAND_NONE}},
+	/* Less:	push (stknext < stktop) */
+    {"gt",		  1,   -1,         0,	{OPERAND_NONE}},
+	/* Greater:	push (stknext > stktop) */
+    {"le",		  1,   -1,         0,	{OPERAND_NONE}},
+	/* Less or equal: push (stknext <= stktop) */
+    {"ge",		  1,   -1,         0,	{OPERAND_NONE}},
+	/* Greater or equal: push (stknext >= stktop) */
+    {"lshift",		  1,   -1,         0,	{OPERAND_NONE}},
+	/* Left shift:	push (stknext << stktop) */
+    {"rshift",		  1,   -1,         0,	{OPERAND_NONE}},
+	/* Right shift:	push (stknext >> stktop) */
+    {"add",		  1,   -1,         0,	{OPERAND_NONE}},
+	/* Add:		push (stknext + stktop) */
+    {"sub",		  1,   -1,         0,	{OPERAND_NONE}},
+	/* Sub:		push (stkext - stktop) */
+    {"mult",		  1,   -1,         0,	{OPERAND_NONE}},
+	/* Multiply:	push (stknext * stktop) */
+    {"div",		  1,   -1,         0,	{OPERAND_NONE}},
+	/* Divide:	push (stknext / stktop) */
+    {"mod",		  1,   -1,         0,	{OPERAND_NONE}},
+	/* Mod:		push (stknext % stktop) */
+    {"uplus",		  1,   0,          0,	{OPERAND_NONE}},
+	/* Unary plus:	push +stktop */
+    {"uminus",		  1,   0,          0,	{OPERAND_NONE}},
+	/* Unary minus:	push -stktop */
+    {"bitnot",		  1,   0,          0,	{OPERAND_NONE}},
+	/* Bitwise not:	push ~stktop */
+    {"not",		  1,   0,          0,	{OPERAND_NONE}},
+	/* Logical not:	push !stktop */
+    {"callBuiltinFunc1",  2,   1,          1,	{OPERAND_UINT1}},
+	/* Call builtin math function with index op1; any args are on stk */
+    {"callFunc1",	  2,   INT_MIN,    1,	{OPERAND_UINT1}},
+	/* Call non-builtin func objv[0]; <objc,objv>=<op1,top op1> */
+    {"tryCvtToNumeric",	  1,   0,          0,	{OPERAND_NONE}},
+	/* Try converting stktop to first int then double if possible. */
+
+    {"break",		  1,   0,          0,	{OPERAND_NONE}},
+	/* Abort closest enclosing loop; if none, return TCL_BREAK code. */
+    {"continue",	  1,   0,          0,	{OPERAND_NONE}},
+	/* Skip to next iteration of closest enclosing loop; if none, return
+	 * TCL_CONTINUE code. */
+
+    {"foreach_start4",	  5,   0,          1,	{OPERAND_AUX4}},
+	/* Initialize execution of a foreach loop. Operand is aux data index
+	 * of the ForeachInfo structure for the foreach command. */
+    {"foreach_step4",	  5,   +1,         1,	{OPERAND_AUX4}},
+	/* "Step" or begin next iteration of foreach loop. Push 0 if to
+	 * terminate loop, else push 1. */
+
+    {"beginCatch4",	  5,   0,          1,	{OPERAND_UINT4}},
+	/* Record start of catch with the operand's exception index. Push the
+	 * current stack depth onto a special catch stack. */
+    {"endCatch",	  1,   0,          0,	{OPERAND_NONE}},
+	/* End of last catch. Pop the bytecode interpreter's catch stack. */
+    {"pushResult",	  1,   +1,         0,	{OPERAND_NONE}},
+	/* Push the interpreter's object result onto the stack. */
+    {"pushReturnCode",	  1,   +1,         0,	{OPERAND_NONE}},
+	/* Push interpreter's return code (e.g. TCL_OK or TCL_ERROR) as a new
+	 * object onto the stack. */
+
+    {"streq",		  1,   -1,         0,	{OPERAND_NONE}},
+	/* Str Equal:	push (stknext eq stktop) */
+    {"strneq",		  1,   -1,         0,	{OPERAND_NONE}},
+	/* Str !Equal:	push (stknext neq stktop) */
+    {"strcmp",		  1,   -1,         0,	{OPERAND_NONE}},
+	/* Str Compare:	push (stknext cmp stktop) */
+    {"strlen",		  1,   0,          0,	{OPERAND_NONE}},
+	/* Str Length:	push (strlen stktop) */
+    {"strindex",	  1,   -1,         0,	{OPERAND_NONE}},
+	/* Str Index:	push (strindex stknext stktop) */
+    {"strmatch",	  2,   -1,         1,	{OPERAND_INT1}},
+	/* Str Match:	push (strmatch stknext stktop) opnd == nocase */
+
+    {"list",		  5,   INT_MIN,    1,	{OPERAND_UINT4}},
+	/* List:	push (stk1 stk2 ... stktop) */
+    {"listIndex",	  1,   -1,         0,	{OPERAND_NONE}},
+	/* List Index:	push (listindex stknext stktop) */
+    {"listLength",	  1,   0,          0,	{OPERAND_NONE}},
+	/* List Len:	push (listlength stktop) */
+
+    {"appendScalar1",	  2,   0,          1,	{OPERAND_LVT1}},
+	/* Append scalar variable at op1<=255 in frame; value is stktop */
+    {"appendScalar4",	  5,   0,          1,	{OPERAND_LVT4}},
+	/* Append scalar variable at op1 > 255 in frame; value is stktop */
+    {"appendArray1",	  2,   -1,         1,	{OPERAND_LVT1}},
+	/* Append array element; array at op1<=255, value is top then elem */
+    {"appendArray4",	  5,   -1,         1,	{OPERAND_LVT4}},
+	/* Append array element; array at op1>=256, value is top then elem */
+    {"appendArrayStk",	  1,   -2,         0,	{OPERAND_NONE}},
+	/* Append array element; value is stktop, then elem, array names */
+    {"appendStk",	  1,   -1,         0,	{OPERAND_NONE}},
+	/* Append general variable; value is stktop, then unparsed name */
+    {"lappendScalar1",	  2,   0,          1,	{OPERAND_LVT1}},
+	/* Lappend scalar variable at op1<=255 in frame; value is stktop */
+    {"lappendScalar4",	  5,   0,          1,	{OPERAND_LVT4}},
+	/* Lappend scalar variable at op1 > 255 in frame; value is stktop */
+    {"lappendArray1",	  2,   -1,         1,	{OPERAND_LVT1}},
+	/* Lappend array element; array at op1<=255, value is top then elem */
+    {"lappendArray4",	  5,   -1,         1,	{OPERAND_LVT4}},
+	/* Lappend array element; array at op1>=256, value is top then elem */
+    {"lappendArrayStk",	  1,   -2,         0,	{OPERAND_NONE}},
+	/* Lappend array element; value is stktop, then elem, array names */
+    {"lappendStk",	  1,   -1,         0,	{OPERAND_NONE}},
+	/* Lappend general variable; value is stktop, then unparsed name */
+
+    {"lindexMulti",	  5,   INT_MIN,    1,	{OPERAND_UINT4}},
+	/* Lindex with generalized args, operand is number of stacked objs
+	 * used: (operand-1) entries from stktop are the indices; then list to
+	 * process. */
+    {"over",		  5,   +1,         1,	{OPERAND_UINT4}},
+	/* Duplicate the arg-th element from top of stack (TOS=0) */
+    {"lsetList",          1,   -2,         0,	{OPERAND_NONE}},
+	/* Four-arg version of 'lset'. stktop is old value; next is new
+	 * element value, next is the index list; pushes new value */
+    {"lsetFlat",          5,   INT_MIN,    1,	{OPERAND_UINT4}},
+	/* Three- or >=5-arg version of 'lset', operand is number of stacked
+	 * objs: stktop is old value, next is new element value, next come
+	 * (operand-2) indices; pushes the new value.
+	 */
+
+    {"returnImm",	  9,   -1,         2,	{OPERAND_INT4, OPERAND_UINT4}},
+	/* Compiled [return], code, level are operands; options and result
+	 * are on the stack. */
+    {"expon",		  1,   -1,	   0,	{OPERAND_NONE}},
+	/* Binary exponentiation operator: push (stknext ** stktop) */
+
+    /*
+     * NOTE: the stack effects of expandStkTop and invokeExpanded are wrong -
+     * but it cannot be done right at compile time, the stack effect is only
+     * known at run time. The value for invokeExpanded is estimated better at
+     * compile time.
+     * See the comments further down in this file, where INST_INVOKE_EXPANDED
+     * is emitted.
+     */
+    {"expandStart",       1,    0,          0,	{OPERAND_NONE}},
+	/* Start of command with {*} (expanded) arguments */
+    {"expandStkTop",      5,    0,          1,	{OPERAND_UINT4}},
+	/* Expand the list at stacktop: push its elements on the stack */
+    {"invokeExpanded",    1,    0,          0,	{OPERAND_NONE}},
+	/* Invoke the command marked by the last 'expandStart' */
+
+    {"listIndexImm",	  5,	0,	   1,	{OPERAND_IDX4}},
+	/* List Index:	push (lindex stktop op4) */
+    {"listRangeImm",	  9,	0,	   2,	{OPERAND_IDX4, OPERAND_IDX4}},
+	/* List Range:	push (lrange stktop op4 op4) */
+    {"startCommand",	  9,	0,	   2,	{OPERAND_OFFSET4, OPERAND_UINT4}},
+	/* Start of bytecoded command: op is the length of the cmd's code, op2
+	 * is number of commands here */
+
+    {"listIn",		  1,	-1,	   0,	{OPERAND_NONE}},
+	/* List containment: push [lsearch stktop stknext]>=0) */
+    {"listNotIn",	  1,	-1,	   0,	{OPERAND_NONE}},
+	/* List negated containment: push [lsearch stktop stknext]<0) */
+
+    {"pushReturnOpts",	  1,	+1,	   0,	{OPERAND_NONE}},
+	/* Push the interpreter's return option dictionary as an object on the
+	 * stack. */
+    {"returnStk",	  1,	-1,	   0,	{OPERAND_NONE}},
+	/* Compiled [return]; options and result are on the stack, code and
+	 * level are in the options. */
+
+    {"dictGet",		  5,	INT_MIN,   1,	{OPERAND_UINT4}},
+	/* The top op4 words (min 1) are a key path into the dictionary just
+	 * below the keys on the stack, and all those values are replaced by
+	 * the value read out of that key-path (like [dict get]).
+	 * Stack:  ... dict key1 ... keyN => ... value */
+    {"dictSet",		  9,	INT_MIN,   2,	{OPERAND_UINT4, OPERAND_LVT4}},
+	/* Update a dictionary value such that the keys are a path pointing to
+	 * the value. op4#1 = numKeys, op4#2 = LVTindex
+	 * Stack:  ... key1 ... keyN value => ... newDict */
+    {"dictUnset",	  9,	INT_MIN,   2,	{OPERAND_UINT4, OPERAND_LVT4}},
+	/* Update a dictionary value such that the keys are not a path pointing
+	 * to any value. op4#1 = numKeys, op4#2 = LVTindex
+	 * Stack:  ... key1 ... keyN => ... newDict */
+    {"dictIncrImm",	  9,	0,	   2,	{OPERAND_INT4, OPERAND_LVT4}},
+	/* Update a dictionary value such that the value pointed to by key is
+	 * incremented by some value (or set to it if the key isn't in the
+	 * dictionary at all). op4#1 = incrAmount, op4#2 = LVTindex
+	 * Stack:  ... key => ... newDict */
+    {"dictAppend",	  5,	-1,	   1,	{OPERAND_LVT4}},
+	/* Update a dictionary value such that the value pointed to by key has
+	 * some value string-concatenated onto it. op4 = LVTindex
+	 * Stack:  ... key valueToAppend => ... newDict */
+    {"dictLappend",	  5,	-1,	   1,	{OPERAND_LVT4}},
+	/* Update a dictionary value such that the value pointed to by key has
+	 * some value list-appended onto it. op4 = LVTindex
+	 * Stack:  ... key valueToAppend => ... newDict */
+    {"dictFirst",	  5,	+2,	   1,	{OPERAND_LVT4}},
+	/* Begin iterating over the dictionary, using the local scalar
+	 * indicated by op4 to hold the iterator state. The local scalar
+	 * should not refer to a named variable as the value is not wholly
+	 * managed correctly.
+	 * Stack:  ... dict => ... value key doneBool */
+    {"dictNext",	  5,	+3,	   1,	{OPERAND_LVT4}},
+	/* Get the next iteration from the iterator in op4's local scalar.
+	 * Stack:  ... => ... value key doneBool */
+    {"dictDone",	  5,	0,	   1,	{OPERAND_LVT4}},
+	/* Terminate the iterator in op4's local scalar. Use unsetScalar
+	 * instead (with 0 for flags). */
+    {"dictUpdateStart",   9,    0,	   2,	{OPERAND_LVT4, OPERAND_AUX4}},
+	/* Create the variables (described in the aux data referred to by the
+	 * second immediate argument) to mirror the state of the dictionary in
+	 * the variable referred to by the first immediate argument. The list
+	 * of keys (top of the stack, not popped) must be the same length as
+	 * the list of variables.
+	 * Stack:  ... keyList => ... keyList */
+    {"dictUpdateEnd",	  9,    -1,	   2,	{OPERAND_LVT4, OPERAND_AUX4}},
+	/* Reflect the state of local variables (described in the aux data
+	 * referred to by the second immediate argument) back to the state of
+	 * the dictionary in the variable referred to by the first immediate
+	 * argument. The list of keys (popped from the stack) must be the same
+	 * length as the list of variables.
+	 * Stack:  ... keyList => ... */
+    {"jumpTable",	 5,	-1,	   1,	{OPERAND_AUX4}},
+	/* Jump according to the jump-table (in AuxData as indicated by the
+	 * operand) and the argument popped from the list. Always executes the
+	 * next instruction if no match against the table's entries was found.
+	 * Stack:  ... value => ...
+	 * Note that the jump table contains offsets relative to the PC when
+	 * it points to this instruction; the code is relocatable. */
+    {"upvar",            5,    -1,        1,   {OPERAND_LVT4}},
+	/* finds level and otherName in stack, links to local variable at
+	 * index op1. Leaves the level on stack. */
+    {"nsupvar",          5,    -1,        1,   {OPERAND_LVT4}},
+	/* finds namespace and otherName in stack, links to local variable at
+	 * index op1. Leaves the namespace on stack. */
+    {"variable",         5,    -1,        1,   {OPERAND_LVT4}},
+	/* finds namespace and otherName in stack, links to local variable at
+	 * index op1. Leaves the namespace on stack. */
+    {"syntax",		 9,   -1,         2,	{OPERAND_INT4, OPERAND_UINT4}},
+	/* Compiled bytecodes to signal syntax error. Equivalent to returnImm
+	 * except for the ERR_ALREADY_LOGGED flag in the interpreter. */
+    {"reverse",		 5,    0,         1,	{OPERAND_UINT4}},
+	/* Reverse the order of the arg elements at the top of stack */
+
+    {"regexp",		 2,   -1,         1,	{OPERAND_INT1}},
+	/* Regexp:	push (regexp stknext stktop) opnd == nocase */
+
+    {"existScalar",	 5,    1,         1,	{OPERAND_LVT4}},
+	/* Test if scalar variable at index op1 in call frame exists */
+    {"existArray",	 5,    0,         1,	{OPERAND_LVT4}},
+	/* Test if array element exists; array at slot op1, element is
+	 * stktop */
+    {"existArrayStk",	 1,    -1,        0,	{OPERAND_NONE}},
+	/* Test if array element exists; element is stktop, array name is
+	 * stknext */
+    {"existStk",	 1,    0,         0,	{OPERAND_NONE}},
+	/* Test if general variable exists; unparsed variable name is stktop*/
+
+    {"nop",		 1,    0,         0,	{OPERAND_NONE}},
+	/* Do nothing */
+    {"returnCodeBranch", 1,   -1,	  0,	{OPERAND_NONE}},
+	/* Jump to next instruction based on the return code on top of stack
+	 * ERROR: +1;	RETURN: +3;	BREAK: +5;	CONTINUE: +7;
+	 * Other non-OK: +9
+	 */
+
+    {"unsetScalar",	 6,    0,         2,	{OPERAND_UINT1, OPERAND_LVT4}},
+	/* Make scalar variable at index op2 in call frame cease to exist;
+	 * op1 is 1 for errors on problems, 0 otherwise */
+    {"unsetArray",	 6,    -1,        2,	{OPERAND_UINT1, OPERAND_LVT4}},
+	/* Make array element cease to exist; array at slot op2, element is
+	 * stktop; op1 is 1 for errors on problems, 0 otherwise */
+    {"unsetArrayStk",	 2,    -2,        1,	{OPERAND_UINT1}},
+	/* Make array element cease to exist; element is stktop, array name is
+	 * stknext; op1 is 1 for errors on problems, 0 otherwise */
+    {"unsetStk",	 2,    -1,        1,	{OPERAND_UINT1}},
+	/* Make general variable cease to exist; unparsed variable name is
+	 * stktop; op1 is 1 for errors on problems, 0 otherwise */
+
+    {"dictExpand",       1,    -1,        0,    {OPERAND_NONE}},
+        /* Probe into a dict and extract it (or a subdict of it) into
+         * variables with matched names. Produces list of keys bound as
+         * result. Part of [dict with].
+	 * Stack:  ... dict path => ... keyList */
+    {"dictRecombineStk", 1,    -3,        0,    {OPERAND_NONE}},
+        /* Map variable contents back into a dictionary in a variable. Part of
+         * [dict with].
+	 * Stack:  ... dictVarName path keyList => ... */
+    {"dictRecombineImm", 5,    -2,        1,    {OPERAND_LVT4}},
+        /* Map variable contents back into a dictionary in the local variable
+         * indicated by the LVT index. Part of [dict with].
+	 * Stack:  ... path keyList => ... */
+    {"dictExists",	 5,	INT_MIN,  1,	{OPERAND_UINT4}},
+	/* The top op4 words (min 1) are a key path into the dictionary just
+	 * below the keys on the stack, and all those values are replaced by a
+	 * boolean indicating whether it is possible to read out a value from
+	 * that key-path (like [dict exists]).
+	 * Stack:  ... dict key1 ... keyN => ... boolean */
+    {"verifyDict",	 1,    -1,	  0,	{OPERAND_NONE}},
+	/* Verifies that the word on the top of the stack is a dictionary,
+	 * popping it if it is and throwing an error if it is not.
+	 * Stack:  ... value => ... */
+
+    {"strmap",		 1,    -2,	  0,	{OPERAND_NONE}},
+	/* Simplified version of [string map] that only applies one change
+	 * string, and only case-sensitively.
+	 * Stack:  ... from to string => ... changedString */
+    {"strfind",		 1,    -1,	  0,	{OPERAND_NONE}},
+	/* Find the first index of a needle string in a haystack string,
+	 * producing the index (integer) or -1 if nothing found.
+	 * Stack:  ... needle haystack => ... index */
+    {"strrfind",	 1,    -1,	  0,	{OPERAND_NONE}},
+	/* Find the last index of a needle string in a haystack string,
+	 * producing the index (integer) or -1 if nothing found.
+	 * Stack:  ... needle haystack => ... index */
+    {"strrangeImm",	 9,	0,	  2,	{OPERAND_IDX4, OPERAND_IDX4}},
+	/* String Range: push (string range stktop op4 op4) */
+    {"strrange",	 1,    -2,	  0,	{OPERAND_NONE}},
+	/* String Range with non-constant arguments.
+	 * Stack:  ... string idxA idxB => ... substring */
+
+    {"yield",		 1,	0,	  0,	{OPERAND_NONE}},
+	/* Makes the current coroutine yield the value at the top of the
+	 * stack, and places the response back on top of the stack when it
+	 * resumes.
+	 * Stack:  ... valueToYield => ... resumeValue */
+    {"coroName",         1,    +1,	  0,	{OPERAND_NONE}},
+	/* Push the name of the interpreter's current coroutine as an object
+	 * on the stack. */
+    {"tailcall",	 2,    INT_MIN,	  1,	{OPERAND_UINT1}},
+	/* Do a tailcall with the opnd items on the stack as the thing to
+	 * tailcall to; opnd must be greater than 0 for the semantics to work
+	 * right. */
+
+    {"currentNamespace", 1,    +1,	  0,	{OPERAND_NONE}},
+	/* Push the name of the interpreter's current namespace as an object
+	 * on the stack. */
+    {"infoLevelNumber",  1,    +1,	  0,	{OPERAND_NONE}},
+	/* Push the stack depth (i.e., [info level]) of the interpreter as an
+	 * object on the stack. */
+    {"infoLevelArgs",	 1,	0,	  0,	{OPERAND_NONE}},
+	/* Push the argument words to a stack depth (i.e., [info level <n>])
+	 * of the interpreter as an object on the stack.
+	 * Stack:  ... depth => ... argList */
+    {"resolveCmd",	 1,	0,	  0,	{OPERAND_NONE}},
+	/* Resolves the command named on the top of the stack to its fully
+	 * qualified version, or produces the empty string if no such command
+	 * exists. Never generates errors.
+	 * Stack:  ... cmdName => ... fullCmdName */
+
+    {"tclooSelf",	 1,	+1,	  0,	{OPERAND_NONE}},
+	/* Push the identity of the current TclOO object (i.e., the name of
+	 * its current public access command) on the stack. */
+    {"tclooClass",	 1,	0,	  0,	{OPERAND_NONE}},
+	/* Push the class of the TclOO object named at the top of the stack
+	 * onto the stack.
+	 * Stack:  ... object => ... class */
+    {"tclooNamespace",	 1,	0,	  0,	{OPERAND_NONE}},
+	/* Push the namespace of the TclOO object named at the top of the
+	 * stack onto the stack.
+	 * Stack:  ... object => ... namespace */
+    {"tclooIsObject",	 1,	0,	  0,	{OPERAND_NONE}},
+	/* Push whether the value named at the top of the stack is a TclOO
+	 * object (i.e., a boolean). Can corrupt the interpreter result
+	 * despite not throwing, so not safe for use in a post-exception
+	 * context.
+	 * Stack:  ... value => ... boolean */
+
+    {"arrayExistsStk",	 1,	0,	  0,	{OPERAND_NONE}},
+	/* Looks up the element on the top of the stack and tests whether it
+	 * is an array. Pushes a boolean describing whether this is the
+	 * case. Also runs the whole-array trace on the named variable, so can
+	 * throw anything.
+	 * Stack:  ... varName => ... boolean */
+    {"arrayExistsImm",	 5,	+1,	  1,	{OPERAND_LVT4}},
+	/* Looks up the variable indexed by opnd and tests whether it is an
+	 * array. Pushes a boolean describing whether this is the case. Also
+	 * runs the whole-array trace on the named variable, so can throw
+	 * anything.
+	 * Stack:  ... => ... boolean */
+    {"arrayMakeStk",	 1,	-1,	  0,	{OPERAND_NONE}},
+	/* Forces the element on the top of the stack to be the name of an
+	 * array.
+	 * Stack:  ... varName => ... */
+    {"arrayMakeImm",	 5,	0,	  1,	{OPERAND_LVT4}},
+	/* Forces the variable indexed by opnd to be an array. Does not touch
+	 * the stack. */
+
+    {"invokeReplace",	 6,	INT_MIN,  2,	{OPERAND_UINT4,OPERAND_UINT1}},
+	/* Invoke command named objv[0], replacing the first two words with
+	 * the word at the top of the stack;
+	 * <objc,objv> = <op4,top op4 after popping 1> */
+
+    {"listConcat",	 1,	-1,	  0,	{OPERAND_NONE}},
+	/* Concatenates the two lists at the top of the stack into a single
+	 * list and pushes that resulting list onto the stack.
+	 * Stack: ... list1 list2 => ... [lconcat list1 list2] */
+
+    {"expandDrop",       1,    0,          0,	{OPERAND_NONE}},
+	/* Drops an element from the auxiliary stack, popping stack elements
+	 * until the matching stack depth is reached. */
+
+    /* New foreach implementation */
+    {"foreach_start",	 5,	+2,	  1,	{OPERAND_AUX4}},
+	/* Initialize execution of a foreach loop. Operand is aux data index
+	 * of the ForeachInfo structure for the foreach command. It pushes 2
+	 * elements which hold runtime params for foreach_step, they are later
+	 * dropped by foreach_end together with the value lists. NOTE that the
+	 * iterator-tracker and info reference must not be passed to bytecodes
+	 * that handle normal Tcl values. NOTE that this instruction jumps to
+	 * the foreach_step instruction paired with it; the stack info below
+	 * is only nominal.
+	 * Stack: ... listObjs... => ... listObjs... iterTracker info */
+    {"foreach_step",	 1,	 0,	  0,	{OPERAND_NONE}},
+	/* "Step" or begin next iteration of foreach loop. Assigns to foreach
+	 * iteration variables. May jump to straight after the foreach_start
+	 * that pushed the iterTracker and info values. MUST be followed
+	 * immediately by a foreach_end.
+	 * Stack: ... listObjs... iterTracker info =>
+	 *				... listObjs... iterTracker info */
+    {"foreach_end",	 1,	 0,	  0,	{OPERAND_NONE}},
+	/* Clean up a foreach loop by dropping the info value, the tracker
+	 * value and the lists that were being iterated over.
+	 * Stack: ... listObjs... iterTracker info => ... */
+    {"lmap_collect",	 1,	-1,	  0,	{OPERAND_NONE}},
+	/* Appends the value at the top of the stack to the list located on
+	 * the stack the "other side" of the foreach-related values.
+	 * Stack: ... collector listObjs... iterTracker info value =>
+	 *			... collector listObjs... iterTracker info */
+
+    {"strtrim",		 1,	-1,	  0,	{OPERAND_NONE}},
+	/* [string trim] core: removes the characters (designated by the value
+	 * at the top of the stack) from both ends of the string and pushes
+	 * the resulting string.
+	 * Stack: ... string charset => ... trimmedString */
+    {"strtrimLeft",	 1,	-1,	  0,	{OPERAND_NONE}},
+	/* [string trimleft] core: removes the characters (designated by the
+	 * value at the top of the stack) from the left of the string and
+	 * pushes the resulting string.
+	 * Stack: ... string charset => ... trimmedString */
+    {"strtrimRight",	 1,	-1,	  0,	{OPERAND_NONE}},
+	/* [string trimright] core: removes the characters (designated by the
+	 * value at the top of the stack) from the right of the string and
+	 * pushes the resulting string.
+	 * Stack: ... string charset => ... trimmedString */
+
+    {"concatStk",	 5,	INT_MIN,  1,	{OPERAND_UINT4}},
+	/* Wrapper round Tcl_ConcatObj(), used for [concat] and [eval]. opnd
+	 * is number of values to concatenate.
+	 * Operation:	push concat(stk1 stk2 ... stktop) */
+
+    {"strcaseUpper",	 1,	0,	  0,	{OPERAND_NONE}},
+	/* [string toupper] core: converts whole string to upper case using
+	 * the default (extended "C" locale) rules.
+	 * Stack: ... string => ... newString */
+    {"strcaseLower",	 1,	0,	  0,	{OPERAND_NONE}},
+	/* [string tolower] core: converts whole string to upper case using
+	 * the default (extended "C" locale) rules.
+	 * Stack: ... string => ... newString */
+    {"strcaseTitle",	 1,	0,	  0,	{OPERAND_NONE}},
+	/* [string totitle] core: converts whole string to upper case using
+	 * the default (extended "C" locale) rules.
+	 * Stack: ... string => ... newString */
+    {"strreplace",	 1,	-3,	  0,	{OPERAND_NONE}},
+	/* [string replace] core: replaces a non-empty range of one string
+	 * with the contents of another.
+	 * Stack: ... string fromIdx toIdx replacement => ... newString */
+
+    {"originCmd",	 1,	0,	  0,	{OPERAND_NONE}},
+	/* Reports which command was the origin (via namespace import chain)
+	 * of the command named on the top of the stack.
+	 * Stack:  ... cmdName => ... fullOriginalCmdName */
+
+    {"tclooNext",	 2,	INT_MIN,  1,	{OPERAND_UINT1}},
+	/* Call the next item on the TclOO call chain, passing opnd arguments
+	 * (min 1, max 255, *includes* "next").  The result of the invoked
+	 * method implementation will be pushed on the stack in place of the
+	 * arguments (similar to invokeStk).
+	 * Stack:  ... "next" arg2 arg3 -- argN => ... result */
+    {"tclooNextClass",	 2,	INT_MIN,  1,	{OPERAND_UINT1}},
+	/* Call the following item on the TclOO call chain defined by class
+	 * className, passing opnd arguments (min 2, max 255, *includes*
+	 * "nextto" and the class name). The result of the invoked method
+	 * implementation will be pushed on the stack in place of the
+	 * arguments (similar to invokeStk).
+	 * Stack:  ... "nextto" className arg3 arg4 -- argN => ... result */
+
+    {"yieldToInvoke",	 1,	0,	  0,	{OPERAND_NONE}},
+	/* Makes the current coroutine yield the value at the top of the
+	 * stack, invoking the given command/args with resolution in the given
+	 * namespace (all packed into a list), and places the list of values
+	 * that are the response back on top of the stack when it resumes.
+	 * Stack:  ... [list ns cmd arg1 ... argN] => ... resumeList */
+
+    {"numericType",	 1,	0,	  0,	{OPERAND_NONE}},
+	/* Pushes the numeric type code of the word at the top of the stack.
+	 * Stack:  ... value => ... typeCode */
+    {"tryCvtToBoolean",	 1,	+1,	  0,	{OPERAND_NONE}},
+	/* Try converting stktop to boolean if possible. No errors.
+	 * Stack:  ... value => ... value isStrictBool */
+    {"strclass",	 2,	0,	  1,	{OPERAND_SCLS1}},
+	/* See if all the characters of the given string are a member of the
+	 * specified (by opnd) character class. Note that an empty string will
+	 * satisfy the class check (standard definition of "all").
+	 * Stack:  ... stringValue => ... boolean */
+
+    {"lappendList",	 5,	0,	1,	{OPERAND_LVT4}},
+	/* Lappend list to scalar variable at op4 in frame.
+	 * Stack:  ... list => ... listVarContents */
+    {"lappendListArray", 5,	-1,	1,	{OPERAND_LVT4}},
+	/* Lappend list to array element; array at op4.
+	 * Stack:  ... elem list => ... listVarContents */
+    {"lappendListArrayStk", 1,	-2,	0,	{OPERAND_NONE}},
+	/* Lappend list to array element.
+	 * Stack:  ... arrayName elem list => ... listVarContents */
+    {"lappendListStk",	 1,	-1,	0,	{OPERAND_NONE}},
+	/* Lappend list to general variable.
+	 * Stack:  ... varName list => ... listVarContents */
+
+    {NULL, 0, 0, 0, {OPERAND_NONE}}
+};
+
+/*
+ * Prototypes for procedures defined later in this file:
+ */
+
+static ByteCode *	CompileSubstObj(Tcl_Interp *interp, Tcl_Obj *objPtr,
+			    int flags);
+static void		DupByteCodeInternalRep(Tcl_Obj *srcPtr,
+			    Tcl_Obj *copyPtr);
+static unsigned char *	EncodeCmdLocMap(CompileEnv *envPtr,
+			    ByteCode *codePtr, unsigned char *startPtr);
+static void		EnterCmdExtentData(CompileEnv *envPtr,
+			    int cmdNumber, int numSrcBytes, int numCodeBytes);
+static void		EnterCmdStartData(CompileEnv *envPtr,
+			    int cmdNumber, int srcOffset, int codeOffset);
+static void		FreeByteCodeInternalRep(Tcl_Obj *objPtr);
+static void		FreeSubstCodeInternalRep(Tcl_Obj *objPtr);
+static int		GetCmdLocEncodingSize(CompileEnv *envPtr);
+static int		IsCompactibleCompileEnv(Tcl_Interp *interp,
+			    CompileEnv *envPtr);
+#ifdef TCL_COMPILE_STATS
+static void		RecordByteCodeStats(ByteCode *codePtr);
+#endif /* TCL_COMPILE_STATS */
+static int		SetByteCodeFromAny(Tcl_Interp *interp,
+			    Tcl_Obj *objPtr);
+static void		StartExpanding(CompileEnv *envPtr);
+
+/*
+ * TIP #280: Helper for building the per-word line information of all compiled
+ * commands.
+ */
+static void		EnterCmdWordData(ExtCmdLoc *eclPtr, int srcOffset,
+			    Tcl_Token *tokenPtr, const char *cmd, int len,
+			    int numWords, int line, int *clNext, int **lines,
+			    CompileEnv *envPtr);
+static void		ReleaseCmdWordData(ExtCmdLoc *eclPtr);
+
+/*
+ * The structure below defines the bytecode Tcl object type by means of
+ * procedures that can be invoked by generic object code.
+ */
+
+const Tcl_ObjType tclByteCodeType = {
+    "bytecode",			/* name */
+    FreeByteCodeInternalRep,	/* freeIntRepProc */
+    DupByteCodeInternalRep,	/* dupIntRepProc */
+    NULL,			/* updateStringProc */
+    SetByteCodeFromAny		/* setFromAnyProc */
+};
+
+/*
+ * The structure below defines a bytecode Tcl object type to hold the
+ * compiled bytecode for the [subst]itution of Tcl values.
+ */
+
+static const Tcl_ObjType substCodeType = {
+    "substcode",		/* name */
+    FreeSubstCodeInternalRep,	/* freeIntRepProc */
+    DupByteCodeInternalRep,	/* dupIntRepProc - shared with bytecode */
+    NULL,			/* updateStringProc */
+    NULL,			/* setFromAnyProc */
+};
+
+/*
+ * Helper macros.
+ */
+
+#define TclIncrUInt4AtPtr(ptr, delta) \
+    TclStoreInt4AtPtr(TclGetUInt4AtPtr(ptr)+(delta), (ptr));
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclSetByteCodeFromAny --
+ *
+ *	Part of the bytecode Tcl object type implementation. Attempts to
+ *	generate an byte code internal form for the Tcl object "objPtr" by
+ *	compiling its string representation. This function also takes a hook
+ *	procedure that will be invoked to perform any needed post processing
+ *	on the compilation results before generating byte codes. interp is
+ *	compilation context and may not be NULL.
+ *
+ * Results:
+ *	The return value is a standard Tcl object result. If an error occurs
+ *	during compilation, an error message is left in the interpreter's
+ *	result.
+ *
+ * Side effects:
+ *	Frees the old internal representation. If no error occurs, then the
+ *	compiled code is stored as "objPtr"s bytecode representation. Also, if
+ *	debugging, initializes the "tcl_traceCompile" Tcl variable used to
+ *	trace compilations.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclSetByteCodeFromAny(
+    Tcl_Interp *interp,		/* The interpreter for which the code is being
+				 * compiled. Must not be NULL. */
+    Tcl_Obj *objPtr,		/* The object to make a ByteCode object. */
+    CompileHookProc *hookProc,	/* Procedure to invoke after compilation. */
+    ClientData clientData)	/* Hook procedure private data. */
+{
+    Interp *iPtr = (Interp *) interp;
+    CompileEnv compEnv;		/* Compilation environment structure allocated
+				 * in frame. */
+    int length, result = TCL_OK;
+    const char *stringPtr;
+    Proc *procPtr = iPtr->compiledProcPtr;
+    ContLineLoc *clLocPtr;
+
+#ifdef TCL_COMPILE_DEBUG
+    if (!traceInitialized) {
+	if (Tcl_LinkVar(interp, "tcl_traceCompile",
+		(char *) &tclTraceCompile, TCL_LINK_INT) != TCL_OK) {
+	    Tcl_Panic("SetByteCodeFromAny: unable to create link for tcl_traceCompile variable");
+	}
+	traceInitialized = 1;
+    }
+#endif
+
+    stringPtr = TclGetStringFromObj(objPtr, &length);
+
+    /*
+     * TIP #280: Pick up the CmdFrame in which the BC compiler was invoked and
+     * use to initialize the tracking in the compiler. This information was
+     * stored by TclCompEvalObj and ProcCompileProc.
+     */
+
+    TclInitCompileEnv(interp, &compEnv, stringPtr, length,
+	    iPtr->invokeCmdFramePtr, iPtr->invokeWord);
+
+    /*
+     * Now we check if we have data about invisible continuation lines for the
+     * script, and make it available to the compile environment, if so.
+     *
+     * It is not clear if the script Tcl_Obj* can be free'd while the compiler
+     * is using it, leading to the release of the associated ContLineLoc
+     * structure as well. To ensure that the latter doesn't happen we set a
+     * lock on it. We release this lock in the function TclFreeCompileEnv(),
+     * found in this file. The "lineCLPtr" hashtable is managed in the file
+     * "tclObj.c".
+     */
+
+    clLocPtr = TclContinuationsGet(objPtr);
+    if (clLocPtr) {
+	compEnv.clNext = &clLocPtr->loc[0];
+    }
+
+    TclCompileScript(interp, stringPtr, length, &compEnv);
+
+    /*
+     * Successful compilation. Add a "done" instruction at the end.
+     */
+
+    TclEmitOpcode(INST_DONE, &compEnv);
+
+    /*
+     * Check for optimizations!
+     *
+     * Test if the generated code is free of most hazards; if so, recompile
+     * but with generation of INST_START_CMD disabled. This produces somewhat
+     * faster code in some cases, and more compact code in more.
+     */
+
+    if (Tcl_GetMaster(interp) == NULL &&
+	    !Tcl_LimitTypeEnabled(interp, TCL_LIMIT_COMMANDS|TCL_LIMIT_TIME)
+	    && IsCompactibleCompileEnv(interp, &compEnv)) {
+	TclFreeCompileEnv(&compEnv);
+	iPtr->compiledProcPtr = procPtr;
+	TclInitCompileEnv(interp, &compEnv, stringPtr, length,
+		iPtr->invokeCmdFramePtr, iPtr->invokeWord);
+	if (clLocPtr) {
+	    compEnv.clNext = &clLocPtr->loc[0];
+	}
+	compEnv.atCmdStart = 2;		/* The disabling magic. */
+	TclCompileScript(interp, stringPtr, length, &compEnv);
+	assert (compEnv.atCmdStart > 1);
+	TclEmitOpcode(INST_DONE, &compEnv);
+	assert (compEnv.atCmdStart > 1);
+    }
+
+    /*
+     * Apply some peephole optimizations that can cross specific/generic
+     * instruction generator boundaries.
+     */
+
+    if (iPtr->extra.optimizer) {
+	(iPtr->extra.optimizer)(&compEnv);
+    }
+
+    /*
+     * Invoke the compilation hook procedure if one exists.
+     */
+
+    if (hookProc) {
+	result = hookProc(interp, &compEnv, clientData);
+    }
+
+    /*
+     * Change the object into a ByteCode object. Ownership of the literal
+     * objects and aux data items is given to the ByteCode object.
+     */
+
+#ifdef TCL_COMPILE_DEBUG
+    TclVerifyLocalLiteralTable(&compEnv);
+#endif /*TCL_COMPILE_DEBUG*/
+
+    if (result == TCL_OK) {
+	TclInitByteCodeObj(objPtr, &compEnv);
+#ifdef TCL_COMPILE_DEBUG
+	if (tclTraceCompile >= 2) {
+	    TclPrintByteCodeObj(interp, objPtr);
+	    fflush(stdout);
+	}
+#endif /* TCL_COMPILE_DEBUG */
+    }
+
+    TclFreeCompileEnv(&compEnv);
+    return result;
+}
+
+/*
+ *-----------------------------------------------------------------------
+ *
+ * SetByteCodeFromAny --
+ *
+ *	Part of the bytecode Tcl object type implementation. Attempts to
+ *	generate an byte code internal form for the Tcl object "objPtr" by
+ *	compiling its string representation.
+ *
+ * Results:
+ *	The return value is a standard Tcl object result. If an error occurs
+ *	during compilation, an error message is left in the interpreter's
+ *	result unless "interp" is NULL.
+ *
+ * Side effects:
+ *	Frees the old internal representation. If no error occurs, then the
+ *	compiled code is stored as "objPtr"s bytecode representation. Also, if
+ *	debugging, initializes the "tcl_traceCompile" Tcl variable used to
+ *	trace compilations.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+SetByteCodeFromAny(
+    Tcl_Interp *interp,		/* The interpreter for which the code is being
+				 * compiled. Must not be NULL. */
+    Tcl_Obj *objPtr)		/* The object to make a ByteCode object. */
+{
+    if (interp == NULL) {
+	return TCL_ERROR;
+    }
+    return TclSetByteCodeFromAny(interp, objPtr, NULL, NULL);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * DupByteCodeInternalRep --
+ *
+ *	Part of the bytecode Tcl object type implementation. However, it does
+ *	not copy the internal representation of a bytecode Tcl_Obj, but
+ *	instead leaves the new object untyped (with a NULL type pointer).
+ *	Code will be compiled for the new object only if necessary.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+DupByteCodeInternalRep(
+    Tcl_Obj *srcPtr,		/* Object with internal rep to copy. */
+    Tcl_Obj *copyPtr)		/* Object with internal rep to set. */
+{
+    return;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * FreeByteCodeInternalRep --
+ *
+ *	Part of the bytecode Tcl object type implementation. Frees the storage
+ *	associated with a bytecode object's internal representation unless its
+ *	code is actively being executed.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The bytecode object's internal rep is marked invalid and its code gets
+ *	freed unless the code is actively being executed. In that case the
+ *	cleanup is delayed until the last execution of the code completes.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+FreeByteCodeInternalRep(
+    register Tcl_Obj *objPtr)	/* Object whose internal rep to free. */
+{
+    register ByteCode *codePtr = objPtr->internalRep.twoPtrValue.ptr1;
+
+    objPtr->typePtr = NULL;
+    if (codePtr->refCount-- <= 1) {
+	TclCleanupByteCode(codePtr);
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclCleanupByteCode --
+ *
+ *	This procedure does all the real work of freeing up a bytecode
+ *	object's ByteCode structure. It's called only when the structure's
+ *	reference count becomes zero.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Frees objPtr's bytecode internal representation and sets its type NULL
+ *	Also releases its literals and frees its auxiliary data items.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclCleanupByteCode(
+    register ByteCode *codePtr)	/* Points to the ByteCode to free. */
+{
+    Tcl_Interp *interp = (Tcl_Interp *) *codePtr->interpHandle;
+    Interp *iPtr = (Interp *) interp;
+    int numLitObjects = codePtr->numLitObjects;
+    int numAuxDataItems = codePtr->numAuxDataItems;
+    register Tcl_Obj **objArrayPtr, *objPtr;
+    register const AuxData *auxDataPtr;
+    int i;
+#ifdef TCL_COMPILE_STATS
+
+    if (interp != NULL) {
+	ByteCodeStats *statsPtr;
+	Tcl_Time destroyTime;
+	int lifetimeSec, lifetimeMicroSec, log2;
+
+	statsPtr = &iPtr->stats;
+
+	statsPtr->numByteCodesFreed++;
+	statsPtr->currentSrcBytes -= (double) codePtr->numSrcBytes;
+	statsPtr->currentByteCodeBytes -= (double) codePtr->structureSize;
+
+	statsPtr->currentInstBytes -= (double) codePtr->numCodeBytes;
+	statsPtr->currentLitBytes -= (double)
+		codePtr->numLitObjects * sizeof(Tcl_Obj *);
+	statsPtr->currentExceptBytes -= (double)
+		codePtr->numExceptRanges * sizeof(ExceptionRange);
+	statsPtr->currentAuxBytes -= (double)
+		codePtr->numAuxDataItems * sizeof(AuxData);
+	statsPtr->currentCmdMapBytes -= (double) codePtr->numCmdLocBytes;
+
+	Tcl_GetTime(&destroyTime);
+	lifetimeSec = destroyTime.sec - codePtr->createTime.sec;
+	if (lifetimeSec > 2000) {	/* avoid overflow */
+	    lifetimeSec = 2000;
+	}
+	lifetimeMicroSec = 1000000 * lifetimeSec +
+		(destroyTime.usec - codePtr->createTime.usec);
+
+	log2 = TclLog2(lifetimeMicroSec);
+	if (log2 > 31) {
+	    log2 = 31;
+	}
+	statsPtr->lifetimeCount[log2]++;
+    }
+#endif /* TCL_COMPILE_STATS */
+
+    /*
+     * A single heap object holds the ByteCode structure and its code, object,
+     * command location, and auxiliary data arrays. This means we only need to
+     * 1) decrement the ref counts of the LiteralEntry's in its literal array,
+     * 2) call the free procs for the auxiliary data items, 3) free the
+     * localCache if it is unused, and finally 4) free the ByteCode
+     * structure's heap object.
+     *
+     * The case for TCL_BYTECODE_PRECOMPILED (precompiled ByteCodes, like
+     * those generated from tbcload) is special, as they doesn't make use of
+     * the global literal table. They instead maintain private references to
+     * their literals which must be decremented.
+     *
+     * In order to insure a proper and efficient cleanup of the literal array
+     * when it contains non-shared literals [Bug 983660], we also distinguish
+     * the case of an interpreter being deleted (signaled by interp == NULL).
+     * Also, as the interp deletion will remove the global literal table
+     * anyway, we avoid the extra cost of updating it for each literal being
+     * released.
+     */
+
+    if (codePtr->flags & TCL_BYTECODE_PRECOMPILED) {
+
+	objArrayPtr = codePtr->objArrayPtr;
+	for (i = 0;  i < numLitObjects;  i++) {
+	    objPtr = *objArrayPtr;
+	    if (objPtr) {
+		Tcl_DecrRefCount(objPtr);
+	    }
+	    objArrayPtr++;
+	}
+	codePtr->numLitObjects = 0;
+    } else {
+	objArrayPtr = codePtr->objArrayPtr;
+	while (numLitObjects--) {
+	    /* TclReleaseLiteral calls Tcl_DecrRefCount() for us */
+	    TclReleaseLiteral(interp, *objArrayPtr++);
+	}
+    }
+
+    auxDataPtr = codePtr->auxDataArrayPtr;
+    for (i = 0;  i < numAuxDataItems;  i++) {
+	if (auxDataPtr->type->freeProc != NULL) {
+	    auxDataPtr->type->freeProc(auxDataPtr->clientData);
+	}
+	auxDataPtr++;
+    }
+
+    /*
+     * TIP #280. Release the location data associated with this byte code
+     * structure, if any. NOTE: The interp we belong to may be gone already,
+     * and the data with it.
+     *
+     * See also tclBasic.c, DeleteInterpProc
+     */
+
+    if (iPtr) {
+	Tcl_HashEntry *hePtr = Tcl_FindHashEntry(iPtr->lineBCPtr,
+		(char *) codePtr);
+
+	if (hePtr) {
+	    ReleaseCmdWordData(Tcl_GetHashValue(hePtr));
+	    Tcl_DeleteHashEntry(hePtr);
+	}
+    }
+
+    if (codePtr->localCachePtr && (--codePtr->localCachePtr->refCount == 0)) {
+	TclFreeLocalCache(interp, codePtr->localCachePtr);
+    }
+
+    TclHandleRelease(codePtr->interpHandle);
+    ckfree(codePtr);
+}
+
+/*
+ * ---------------------------------------------------------------------
+ *
+ * IsCompactibleCompileEnv --
+ *
+ *	Checks to see if we may apply some basic compaction optimizations to a
+ *	piece of bytecode. Idempotent.
+ *
+ * ---------------------------------------------------------------------
+ */
+
+static int
+IsCompactibleCompileEnv(
+    Tcl_Interp *interp,
+    CompileEnv *envPtr)
+{
+    unsigned char *pc;
+    int size;
+
+    /*
+     * Special: procedures in the '::tcl' namespace (or its children) are
+     * considered to be well-behaved and so can have compaction applied even
+     * if it would otherwise be invalid.
+     */
+
+    if (envPtr->procPtr != NULL && envPtr->procPtr->cmdPtr != NULL
+	    && envPtr->procPtr->cmdPtr->nsPtr != NULL) {
+	Namespace *nsPtr = envPtr->procPtr->cmdPtr->nsPtr;
+
+	if (strcmp(nsPtr->fullName, "::tcl") == 0
+		|| strncmp(nsPtr->fullName, "::tcl::", 7) == 0) {
+	    return 1;
+	}
+    }
+
+    /*
+     * Go through and ensure that no operation involved can cause a desired
+     * change of bytecode sequence during running. This comes down to ensuring
+     * that there are no mapped variables (due to traces) or calls to external
+     * commands (traces, [uplevel] trickery). This is actually a very
+     * conservative check; it turns down a lot of code that is OK in practice.
+     */
+
+    for (pc = envPtr->codeStart ; pc < envPtr->codeNext ; pc += size) {
+	switch (*pc) {
+	    /* Invokes */
+	case INST_INVOKE_STK1:
+	case INST_INVOKE_STK4:
+	case INST_INVOKE_EXPANDED:
+	case INST_INVOKE_REPLACE:
+	    return 0;
+	    /* Runtime evals */
+	case INST_EVAL_STK:
+	case INST_EXPR_STK:
+	case INST_YIELD:
+	    return 0;
+	    /* Upvars */
+	case INST_UPVAR:
+	case INST_NSUPVAR:
+	case INST_VARIABLE:
+	    return 0;
+	default:
+	    size = tclInstructionTable[*pc].numBytes;
+	    assert (size > 0);
+	    break;
+	}
+    }
+
+    return 1;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_SubstObj --
+ *
+ *	This function performs the substitutions specified on the given string
+ *	as described in the user documentation for the "subst" Tcl command.
+ *
+ * Results:
+ *	A Tcl_Obj* containing the substituted string, or NULL to indicate that
+ *	an error occurred.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_Obj *
+Tcl_SubstObj(
+    Tcl_Interp *interp,		/* Interpreter in which substitution occurs */
+    Tcl_Obj *objPtr,		/* The value to be substituted. */
+    int flags)			/* What substitutions to do. */
+{
+    NRE_callback *rootPtr = TOP_CB(interp);
+
+    if (TclNRRunCallbacks(interp, Tcl_NRSubstObj(interp, objPtr, flags),
+	    rootPtr) != TCL_OK) {
+	return NULL;
+    }
+    return Tcl_GetObjResult(interp);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_NRSubstObj --
+ *
+ *	Request substitution of a Tcl value by the NR stack.
+ *
+ * Results:
+ *	Returns TCL_OK.
+ *
+ * Side effects:
+ *	Compiles objPtr into bytecode that performs the substitutions as
+ *	governed by flags and places callbacks on the NR stack to execute
+ *	the bytecode and store the result in the interp.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_NRSubstObj(
+    Tcl_Interp *interp,
+    Tcl_Obj *objPtr,
+    int flags)
+{
+    ByteCode *codePtr = CompileSubstObj(interp, objPtr, flags);
+
+    /* TODO: Confirm we do not need this. */
+    /* Tcl_ResetResult(interp); */
+    return TclNRExecuteByteCode(interp, codePtr);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * CompileSubstObj --
+ *
+ *	Compile a Tcl value into ByteCode implementing its substitution, as
+ *	governed by flags.
+ *
+ * Results:
+ *	A (ByteCode *) is returned pointing to the resulting ByteCode.
+ *	The caller must manage its refCount and arrange for a call to
+ *	TclCleanupByteCode() when the last reference disappears.
+ *
+ * Side effects:
+ *	The Tcl_ObjType of objPtr is changed to the "substcode" type, and the
+ *	ByteCode and governing flags value are kept in the internal rep for
+ *	faster operations the next time CompileSubstObj is called on the same
+ *	value.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static ByteCode *
+CompileSubstObj(
+    Tcl_Interp *interp,
+    Tcl_Obj *objPtr,
+    int flags)
+{
+    Interp *iPtr = (Interp *) interp;
+    ByteCode *codePtr = NULL;
+
+    if (objPtr->typePtr == &substCodeType) {
+	Namespace *nsPtr = iPtr->varFramePtr->nsPtr;
+
+	codePtr = objPtr->internalRep.twoPtrValue.ptr1;
+	if (flags != PTR2INT(objPtr->internalRep.twoPtrValue.ptr2)
+		|| ((Interp *) *codePtr->interpHandle != iPtr)
+		|| (codePtr->compileEpoch != iPtr->compileEpoch)
+		|| (codePtr->nsPtr != nsPtr)
+		|| (codePtr->nsEpoch != nsPtr->resolverEpoch)
+		|| (codePtr->localCachePtr !=
+		iPtr->varFramePtr->localCachePtr)) {
+	    FreeSubstCodeInternalRep(objPtr);
+	}
+    }
+    if (objPtr->typePtr != &substCodeType) {
+	CompileEnv compEnv;
+	int numBytes;
+	const char *bytes = Tcl_GetStringFromObj(objPtr, &numBytes);
+
+	/* TODO: Check for more TIP 280 */
+	TclInitCompileEnv(interp, &compEnv, bytes, numBytes, NULL, 0);
+
+	TclSubstCompile(interp, bytes, numBytes, flags, 1, &compEnv);
+
+	TclEmitOpcode(INST_DONE, &compEnv);
+	TclInitByteCodeObj(objPtr, &compEnv);
+	objPtr->typePtr = &substCodeType;
+	TclFreeCompileEnv(&compEnv);
+
+	codePtr = objPtr->internalRep.twoPtrValue.ptr1;
+	objPtr->internalRep.twoPtrValue.ptr1 = codePtr;
+	objPtr->internalRep.twoPtrValue.ptr2 = INT2PTR(flags);
+	if (iPtr->varFramePtr->localCachePtr) {
+	    codePtr->localCachePtr = iPtr->varFramePtr->localCachePtr;
+	    codePtr->localCachePtr->refCount++;
+	}
+#ifdef TCL_COMPILE_DEBUG
+	if (tclTraceCompile >= 2) {
+	    TclPrintByteCodeObj(interp, objPtr);
+	    fflush(stdout);
+	}
+#endif /* TCL_COMPILE_DEBUG */
+    }
+    return codePtr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * FreeSubstCodeInternalRep --
+ *
+ *	Part of the substcode Tcl object type implementation. Frees the
+ *	storage associated with a substcode object's internal representation
+ *	unless its code is actively being executed.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The substcode object's internal rep is marked invalid and its code
+ *	gets freed unless the code is actively being executed. In that case
+ *	the cleanup is delayed until the last execution of the code completes.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+FreeSubstCodeInternalRep(
+    register Tcl_Obj *objPtr)	/* Object whose internal rep to free. */
+{
+    register ByteCode *codePtr = objPtr->internalRep.twoPtrValue.ptr1;
+
+    objPtr->typePtr = NULL;
+    if (codePtr->refCount-- <= 1) {
+	TclCleanupByteCode(codePtr);
+    }
+}
+
+static void
+ReleaseCmdWordData(
+    ExtCmdLoc *eclPtr)
+{
+    int i;
+
+    if (eclPtr->type == TCL_LOCATION_SOURCE) {
+	Tcl_DecrRefCount(eclPtr->path);
+    }
+    for (i=0 ; i<eclPtr->nuloc ; i++) {
+	ckfree((char *) eclPtr->loc[i].line);
+    }
+
+    if (eclPtr->loc != NULL) {
+	ckfree((char *) eclPtr->loc);
+    }
+
+    ckfree((char *) eclPtr);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclInitCompileEnv --
+ *
+ *	Initializes a CompileEnv compilation environment structure for the
+ *	compilation of a string in an interpreter.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The CompileEnv structure is initialized.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclInitCompileEnv(
+    Tcl_Interp *interp,		/* The interpreter for which a CompileEnv
+				 * structure is initialized. */
+    register CompileEnv *envPtr,/* Points to the CompileEnv structure to
+				 * initialize. */
+    const char *stringPtr,	/* The source string to be compiled. */
+    int numBytes,		/* Number of bytes in source string. */
+    const CmdFrame *invoker,	/* Location context invoking the bcc */
+    int word)			/* Index of the word in that context getting
+				 * compiled */
+{
+    Interp *iPtr = (Interp *) interp;
+
+    assert(tclInstructionTable[LAST_INST_OPCODE+1].name == NULL);
+
+    envPtr->iPtr = iPtr;
+    envPtr->source = stringPtr;
+    envPtr->numSrcBytes = numBytes;
+    envPtr->procPtr = iPtr->compiledProcPtr;
+    iPtr->compiledProcPtr = NULL;
+    envPtr->numCommands = 0;
+    envPtr->exceptDepth = 0;
+    envPtr->maxExceptDepth = 0;
+    envPtr->maxStackDepth = 0;
+    envPtr->currStackDepth = 0;
+    TclInitLiteralTable(&envPtr->localLitTable);
+
+    envPtr->codeStart = envPtr->staticCodeSpace;
+    envPtr->codeNext = envPtr->codeStart;
+    envPtr->codeEnd = envPtr->codeStart + COMPILEENV_INIT_CODE_BYTES;
+    envPtr->mallocedCodeArray = 0;
+
+    envPtr->literalArrayPtr = envPtr->staticLiteralSpace;
+    envPtr->literalArrayNext = 0;
+    envPtr->literalArrayEnd = COMPILEENV_INIT_NUM_OBJECTS;
+    envPtr->mallocedLiteralArray = 0;
+
+    envPtr->exceptArrayPtr = envPtr->staticExceptArraySpace;
+    envPtr->exceptAuxArrayPtr = envPtr->staticExAuxArraySpace;
+    envPtr->exceptArrayNext = 0;
+    envPtr->exceptArrayEnd = COMPILEENV_INIT_EXCEPT_RANGES;
+    envPtr->mallocedExceptArray = 0;
+
+    envPtr->cmdMapPtr = envPtr->staticCmdMapSpace;
+    envPtr->cmdMapEnd = COMPILEENV_INIT_CMD_MAP_SIZE;
+    envPtr->mallocedCmdMap = 0;
+    envPtr->atCmdStart = 1;
+    envPtr->expandCount = 0;
+
+    /*
+     * TIP #280: Set up the extended command location information, based on
+     * the context invoking the byte code compiler. This structure is used to
+     * keep the per-word line information for all compiled commands.
+     *
+     * See also tclBasic.c, TclEvalObjEx, for the equivalent code in the
+     * non-compiling evaluator
+     */
+
+    envPtr->extCmdMapPtr = ckalloc(sizeof(ExtCmdLoc));
+    envPtr->extCmdMapPtr->loc = NULL;
+    envPtr->extCmdMapPtr->nloc = 0;
+    envPtr->extCmdMapPtr->nuloc = 0;
+    envPtr->extCmdMapPtr->path = NULL;
+
+    if (invoker == NULL) {
+	/*
+	 * Initialize the compiler for relative counting in case of a
+	 * dynamic context.
+	 */
+
+	envPtr->line = 1;
+	if (iPtr->evalFlags & TCL_EVAL_FILE) {
+	    iPtr->evalFlags &= ~TCL_EVAL_FILE;
+	    envPtr->extCmdMapPtr->type = TCL_LOCATION_SOURCE;
+
+	    if (iPtr->scriptFile) {
+		/*
+		 * Normalization here, to have the correct pwd. Should have
+		 * negligible impact on performance, as the norm should have
+		 * been done already by the 'source' invoking us, and it
+		 * caches the result.
+		 */
+
+		Tcl_Obj *norm =
+			Tcl_FSGetNormalizedPath(interp, iPtr->scriptFile);
+
+		if (norm == NULL) {
+		    /*
+		     * Error message in the interp result. No place to put it.
+		     * And no place to serve the error itself to either. Fake
+		     * a path, empty string.
+		     */
+
+		    TclNewLiteralStringObj(envPtr->extCmdMapPtr->path, "");
+		} else {
+		    envPtr->extCmdMapPtr->path = norm;
+		}
+	    } else {
+		TclNewLiteralStringObj(envPtr->extCmdMapPtr->path, "");
+	    }
+
+	    Tcl_IncrRefCount(envPtr->extCmdMapPtr->path);
+	} else {
+	    envPtr->extCmdMapPtr->type =
+		(envPtr->procPtr ? TCL_LOCATION_PROC : TCL_LOCATION_BC);
+	}
+    } else {
+	/*
+	 * Initialize the compiler using the context, making counting absolute
+	 * to that context. Note that the context can be byte code execution.
+	 * In that case we have to fill out the missing pieces (line, path,
+	 * ...) which may make change the type as well.
+	 */
+
+	CmdFrame *ctxPtr = TclStackAlloc(interp, sizeof(CmdFrame));
+	int pc = 0;
+
+	*ctxPtr = *invoker;
+	if (invoker->type == TCL_LOCATION_BC) {
+	    /*
+	     * Note: Type BC => ctx.data.eval.path    is not used.
+	     *			ctx.data.tebc.codePtr is used instead.
+	     */
+
+	    TclGetSrcInfoForPc(ctxPtr);
+	    pc = 1;
+	}
+
+	if ((ctxPtr->nline <= word) || (ctxPtr->line[word] < 0)) {
+	    /*
+	     * Word is not a literal, relative counting.
+	     */
+
+	    envPtr->line = 1;
+	    envPtr->extCmdMapPtr->type =
+		    (envPtr->procPtr ? TCL_LOCATION_PROC : TCL_LOCATION_BC);
+
+	    if (pc && (ctxPtr->type == TCL_LOCATION_SOURCE)) {
+		/*
+		 * The reference made by 'TclGetSrcInfoForPc' is dead.
+		 */
+
+		Tcl_DecrRefCount(ctxPtr->data.eval.path);
+	    }
+	} else {
+	    envPtr->line = ctxPtr->line[word];
+	    envPtr->extCmdMapPtr->type = ctxPtr->type;
+
+	    if (ctxPtr->type == TCL_LOCATION_SOURCE) {
+		envPtr->extCmdMapPtr->path = ctxPtr->data.eval.path;
+
+		if (pc) {
+		    /*
+		     * The reference 'TclGetSrcInfoForPc' made is transfered.
+		     */
+
+		    ctxPtr->data.eval.path = NULL;
+		} else {
+		    /*
+		     * We have a new reference here.
+		     */
+
+		    Tcl_IncrRefCount(envPtr->extCmdMapPtr->path);
+		}
+	    }
+	}
+
+	TclStackFree(interp, ctxPtr);
+    }
+
+    envPtr->extCmdMapPtr->start = envPtr->line;
+
+    /*
+     * Initialize the data about invisible continuation lines as empty, i.e.
+     * not used. The caller (TclSetByteCodeFromAny) will set this up, if such
+     * data is available.
+     */
+
+    envPtr->clNext = NULL;
+
+    envPtr->auxDataArrayPtr = envPtr->staticAuxDataArraySpace;
+    envPtr->auxDataArrayNext = 0;
+    envPtr->auxDataArrayEnd = COMPILEENV_INIT_AUX_DATA_SIZE;
+    envPtr->mallocedAuxDataArray = 0;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclFreeCompileEnv --
+ *
+ *	Free the storage allocated in a CompileEnv compilation environment
+ *	structure.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Allocated storage in the CompileEnv structure is freed. Note that its
+ *	local literal table is not deleted and its literal objects are not
+ *	released. In addition, storage referenced by its auxiliary data items
+ *	is not freed. This is done so that, when compilation is successful,
+ *	"ownership" of these objects and aux data items is handed over to the
+ *	corresponding ByteCode structure.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclFreeCompileEnv(
+    register CompileEnv *envPtr)/* Points to the CompileEnv structure. */
+{
+    if (envPtr->localLitTable.buckets != envPtr->localLitTable.staticBuckets){
+	ckfree(envPtr->localLitTable.buckets);
+	envPtr->localLitTable.buckets = envPtr->localLitTable.staticBuckets;
+    }
+    if (envPtr->iPtr) {
+	/*
+	 * We never converted to Bytecode, so free the things we would
+	 * have transferred to it.
+	 */
+
+	int i;
+	LiteralEntry *entryPtr = envPtr->literalArrayPtr;
+	AuxData *auxDataPtr = envPtr->auxDataArrayPtr;
+
+	for (i = 0;  i < envPtr->literalArrayNext;  i++) {
+	    TclReleaseLiteral((Tcl_Interp *)envPtr->iPtr, entryPtr->objPtr);
+	    entryPtr++;
+	}
+
+#ifdef TCL_COMPILE_DEBUG
+	TclVerifyGlobalLiteralTable(envPtr->iPtr);
+#endif /*TCL_COMPILE_DEBUG*/
+
+	for (i = 0;  i < envPtr->auxDataArrayNext;  i++) {
+	    if (auxDataPtr->type->freeProc != NULL) {
+		auxDataPtr->type->freeProc(auxDataPtr->clientData);
+	    }
+	    auxDataPtr++;
+	}
+    }
+    if (envPtr->mallocedCodeArray) {
+	ckfree(envPtr->codeStart);
+    }
+    if (envPtr->mallocedLiteralArray) {
+	ckfree(envPtr->literalArrayPtr);
+    }
+    if (envPtr->mallocedExceptArray) {
+	ckfree(envPtr->exceptArrayPtr);
+	ckfree(envPtr->exceptAuxArrayPtr);
+    }
+    if (envPtr->mallocedCmdMap) {
+	ckfree(envPtr->cmdMapPtr);
+    }
+    if (envPtr->mallocedAuxDataArray) {
+	ckfree(envPtr->auxDataArrayPtr);
+    }
+    if (envPtr->extCmdMapPtr) {
+	ReleaseCmdWordData(envPtr->extCmdMapPtr);
+	envPtr->extCmdMapPtr = NULL;
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclWordKnownAtCompileTime --
+ *
+ *	Test whether the value of a token is completely known at compile time.
+ *
+ * Results:
+ *	Returns true if the tokenPtr argument points to a word value that is
+ *	completely known at compile time. Generally, values that are known at
+ *	compile time can be compiled to their values, while values that cannot
+ *	be known until substitution at runtime must be compiled to bytecode
+ *	instructions that perform that substitution. For several commands,
+ *	whether or not arguments are known at compile time determine whether
+ *	it is worthwhile to compile at all.
+ *
+ * Side effects:
+ *	When returning true, appends the known value of the word to the
+ *	unshared Tcl_Obj (*valuePtr), unless valuePtr is NULL.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclWordKnownAtCompileTime(
+    Tcl_Token *tokenPtr,	/* Points to Tcl_Token we should check */
+    Tcl_Obj *valuePtr)		/* If not NULL, points to an unshared Tcl_Obj
+				 * to which we should append the known value
+				 * of the word. */
+{
+    int numComponents = tokenPtr->numComponents;
+    Tcl_Obj *tempPtr = NULL;
+
+    if (tokenPtr->type == TCL_TOKEN_SIMPLE_WORD) {
+	if (valuePtr != NULL) {
+	    Tcl_AppendToObj(valuePtr, tokenPtr[1].start, tokenPtr[1].size);
+	}
+	return 1;
+    }
+    if (tokenPtr->type != TCL_TOKEN_WORD) {
+	return 0;
+    }
+    tokenPtr++;
+    if (valuePtr != NULL) {
+	tempPtr = Tcl_NewObj();
+	Tcl_IncrRefCount(tempPtr);
+    }
+    while (numComponents--) {
+	switch (tokenPtr->type) {
+	case TCL_TOKEN_TEXT:
+	    if (tempPtr != NULL) {
+		Tcl_AppendToObj(tempPtr, tokenPtr->start, tokenPtr->size);
+	    }
+	    break;
+
+	case TCL_TOKEN_BS:
+	    if (tempPtr != NULL) {
+		char utfBuf[TCL_UTF_MAX];
+		int length = TclParseBackslash(tokenPtr->start,
+			tokenPtr->size, NULL, utfBuf);
+
+		Tcl_AppendToObj(tempPtr, utfBuf, length);
+	    }
+	    break;
+
+	default:
+	    if (tempPtr != NULL) {
+		Tcl_DecrRefCount(tempPtr);
+	    }
+	    return 0;
+	}
+	tokenPtr++;
+    }
+    if (valuePtr != NULL) {
+	Tcl_AppendObjToObj(valuePtr, tempPtr);
+	Tcl_DecrRefCount(tempPtr);
+    }
+    return 1;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclCompileScript --
+ *
+ *	Compile a Tcl script in a string.
+ *
+ * Results:
+ *	The return value is TCL_OK on a successful compilation and TCL_ERROR
+ *	on failure. If TCL_ERROR is returned, then the interpreter's result
+ *	contains an error message.
+ *
+ * Side effects:
+ *	Adds instructions to envPtr to evaluate the script at runtime.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+ExpandRequested(
+    Tcl_Token *tokenPtr,
+    int numWords)
+{
+    /* Determine whether any words of the command require expansion */
+    while (numWords--) {
+	if (tokenPtr->type == TCL_TOKEN_EXPAND_WORD) {
+	    return 1;
+	}
+	tokenPtr = TokenAfter(tokenPtr);
+    }
+    return 0;
+}
+
+static void
+CompileCmdLiteral(
+    Tcl_Interp *interp,
+    Tcl_Obj *cmdObj,
+    CompileEnv *envPtr)
+{
+    int numBytes;
+    const char *bytes = Tcl_GetStringFromObj(cmdObj, &numBytes);
+    int cmdLitIdx = TclRegisterNewCmdLiteral(envPtr, bytes, numBytes);
+    Command *cmdPtr = (Command *) Tcl_GetCommandFromObj(interp, cmdObj);
+
+    if (cmdPtr) {
+	TclSetCmdNameObj(interp, TclFetchLiteral(envPtr, cmdLitIdx), cmdPtr);
+    }
+    TclEmitPush(cmdLitIdx, envPtr);
+}
+
+void
+TclCompileInvocation(
+    Tcl_Interp *interp,
+    Tcl_Token *tokenPtr,
+    Tcl_Obj *cmdObj,
+    int numWords,
+    CompileEnv *envPtr)
+{
+    int wordIdx = 0, depth = TclGetStackDepth(envPtr);
+    DefineLineInformation;
+
+    if (cmdObj) {
+	CompileCmdLiteral(interp, cmdObj, envPtr);
+	wordIdx = 1;
+	tokenPtr = TokenAfter(tokenPtr);
+    }
+
+    for (; wordIdx < numWords; wordIdx++, tokenPtr = TokenAfter(tokenPtr)) {
+	int objIdx;
+
+	SetLineInformation(wordIdx);
+
+	if (tokenPtr->type != TCL_TOKEN_SIMPLE_WORD) {
+	    CompileTokens(envPtr, tokenPtr, interp);
+	    continue;
+	}
+
+	objIdx = TclRegisterNewLiteral(envPtr,
+		tokenPtr[1].start, tokenPtr[1].size);
+	if (envPtr->clNext) {
+	    TclContinuationsEnterDerived(TclFetchLiteral(envPtr, objIdx),
+		    tokenPtr[1].start - envPtr->source, envPtr->clNext);
+	}
+	TclEmitPush(objIdx, envPtr);
+    }
+
+    if (wordIdx <= 255) {
+	TclEmitInvoke(envPtr, INST_INVOKE_STK1, wordIdx);
+    } else {
+	TclEmitInvoke(envPtr, INST_INVOKE_STK4, wordIdx);
+    }
+    TclCheckStackDepth(depth+1, envPtr);
+}
+
+static void
+CompileExpanded(
+    Tcl_Interp *interp,
+    Tcl_Token *tokenPtr,
+    Tcl_Obj *cmdObj,
+    int numWords,
+    CompileEnv *envPtr)
+{
+    int wordIdx = 0;
+    DefineLineInformation;
+    int depth = TclGetStackDepth(envPtr);
+
+    StartExpanding(envPtr);
+    if (cmdObj) {
+	CompileCmdLiteral(interp, cmdObj, envPtr);
+	wordIdx = 1;
+	tokenPtr = TokenAfter(tokenPtr);
+    }
+
+    for (; wordIdx < numWords; wordIdx++, tokenPtr = TokenAfter(tokenPtr)) {
+	int objIdx;
+
+	SetLineInformation(wordIdx);
+
+	if (tokenPtr->type != TCL_TOKEN_SIMPLE_WORD) {
+	    CompileTokens(envPtr, tokenPtr, interp);
+	    if (tokenPtr->type == TCL_TOKEN_EXPAND_WORD) {
+		TclEmitInstInt4(INST_EXPAND_STKTOP,
+			envPtr->currStackDepth, envPtr);
+	    }
+	    continue;
+	}
+
+	objIdx = TclRegisterNewLiteral(envPtr,
+		tokenPtr[1].start, tokenPtr[1].size);
+	if (envPtr->clNext) {
+	    TclContinuationsEnterDerived(TclFetchLiteral(envPtr, objIdx),
+		    tokenPtr[1].start - envPtr->source, envPtr->clNext);
+	}
+	TclEmitPush(objIdx, envPtr);
+    }
+
+    /*
+     * The stack depth during argument expansion can only be managed at
+     * runtime, as the number of elements in the expanded lists is not known
+     * at compile time. We adjust here the stack depth estimate so that it is
+     * correct after the command with expanded arguments returns.
+     *
+     * The end effect of this command's invocation is that all the words of
+     * the command are popped from the stack, and the result is pushed: the
+     * stack top changes by (1-wordIdx).
+     *
+     * Note that the estimates are not correct while the command is being
+     * prepared and run, INST_EXPAND_STKTOP is not stack-neutral in general.
+     */
+
+    TclEmitInvoke(envPtr, INST_INVOKE_EXPANDED, wordIdx);
+    TclCheckStackDepth(depth+1, envPtr);
+}
+
+static int
+CompileCmdCompileProc(
+    Tcl_Interp *interp,
+    Tcl_Parse *parsePtr,
+    Command *cmdPtr,
+    CompileEnv *envPtr)
+{
+    int unwind = 0, incrOffset = -1;
+    DefineLineInformation;
+    int depth = TclGetStackDepth(envPtr);
+
+    /*
+     * Emit of the INST_START_CMD instruction is controlled by the value of
+     * envPtr->atCmdStart:
+     *
+     * atCmdStart == 2	: We are not using the INST_START_CMD instruction.
+     * atCmdStart == 1	: INST_START_CMD was the last instruction emitted.
+     *			: We do not need to emit another.  Instead we
+     *			: increment the number of cmds started at it (except
+     *			: for the special case at the start of a script.)
+     * atCmdStart == 0	: The last instruction was something else.  We need
+     *			: to emit INST_START_CMD here.
+     */
+
+    switch (envPtr->atCmdStart) {
+    case 0:
+	unwind = tclInstructionTable[INST_START_CMD].numBytes;
+	TclEmitInstInt4(INST_START_CMD, 0, envPtr);
+	incrOffset = envPtr->codeNext - envPtr->codeStart;
+	TclEmitInt4(0, envPtr);
+	break;
+    case 1:
+	if (envPtr->codeNext > envPtr->codeStart) {
+	    incrOffset = envPtr->codeNext - 4 - envPtr->codeStart;
+	}
+	break;
+    case 2:
+	/* Nothing to do */
+	;
+    }
+
+    if (TCL_OK == TclAttemptCompileProc(interp, parsePtr, 1, cmdPtr, envPtr)) {
+	if (incrOffset >= 0) {
+	    /*
+	     * We successfully compiled a command.  Increment the number of
+	     * commands that start at the currently active INST_START_CMD.
+	     */
+
+	    unsigned char *incrPtr = envPtr->codeStart + incrOffset;
+	    unsigned char *startPtr = incrPtr - 5;
+
+	    TclIncrUInt4AtPtr(incrPtr, 1);
+	    if (unwind) {
+		/* We started the INST_START_CMD.  Record the code length. */
+		TclStoreInt4AtPtr(envPtr->codeNext - startPtr, startPtr + 1);
+	    }
+	}
+	TclCheckStackDepth(depth+1, envPtr);
+	return TCL_OK;
+    }
+
+    envPtr->codeNext -= unwind; /* Unwind INST_START_CMD */
+
+    /*
+     * Throw out any line information generated by the failed compile attempt.
+     */
+
+    while (mapPtr->nuloc - 1 > eclIndex) {
+	mapPtr->nuloc--;
+	ckfree(mapPtr->loc[mapPtr->nuloc].line);
+	mapPtr->loc[mapPtr->nuloc].line = NULL;
+    }
+
+    /*
+     * Reset the index of next command.  Toss out any from failed nested
+     * partial compiles.
+     */
+
+    envPtr->numCommands = mapPtr->nuloc;
+    return TCL_ERROR;
+}
+
+static int
+CompileCommandTokens(
+    Tcl_Interp *interp,
+    Tcl_Parse *parsePtr,
+    CompileEnv *envPtr)
+{
+    Interp *iPtr = (Interp *) interp;
+    Tcl_Token *tokenPtr = parsePtr->tokenPtr;
+    ExtCmdLoc *eclPtr = envPtr->extCmdMapPtr;
+    Tcl_Obj *cmdObj = Tcl_NewObj();
+    Command *cmdPtr = NULL;
+    int code = TCL_ERROR;
+    int cmdKnown, expand = -1;
+    int *wlines, wlineat;
+    int cmdLine = envPtr->line;
+    int *clNext = envPtr->clNext;
+    int cmdIdx = envPtr->numCommands;
+    int startCodeOffset = envPtr->codeNext - envPtr->codeStart;
+    int depth = TclGetStackDepth(envPtr);
+
+    assert (parsePtr->numWords > 0);
+
+    /* Pre-Compile */
+
+    envPtr->numCommands++;
+    EnterCmdStartData(envPtr, cmdIdx,
+	    parsePtr->commandStart - envPtr->source, startCodeOffset);
+
+    /*
+     * TIP #280. Scan the words and compute the extended location information.
+     * The map first contain full per-word line information for use by the
+     * compiler. This is later replaced by a reduced form which signals
+     * non-literal words, stored in 'wlines'.
+     */
+
+    EnterCmdWordData(eclPtr, parsePtr->commandStart - envPtr->source,
+	    parsePtr->tokenPtr, parsePtr->commandStart,
+	    parsePtr->commandSize, parsePtr->numWords, cmdLine,
+	    clNext, &wlines, envPtr);
+    wlineat = eclPtr->nuloc - 1;
+
+    envPtr->line = eclPtr->loc[wlineat].line[0];
+    envPtr->clNext = eclPtr->loc[wlineat].next[0];
+
+    /* Do we know the command word? */
+    Tcl_IncrRefCount(cmdObj);
+    tokenPtr = parsePtr->tokenPtr;
+    cmdKnown = TclWordKnownAtCompileTime(tokenPtr, cmdObj);
+
+    /* Is this a command we should (try to) compile with a compileProc ? */
+    if (cmdKnown && !(iPtr->flags & DONT_COMPILE_CMDS_INLINE)) {
+	cmdPtr = (Command *) Tcl_GetCommandFromObj(interp, cmdObj);
+	if (cmdPtr) {
+	    /*
+	     * Found a command.  Test the ways we can be told not to attempt
+	     * to compile it.
+	     */
+	    if ((cmdPtr->compileProc == NULL)
+		    || (cmdPtr->nsPtr->flags & NS_SUPPRESS_COMPILATION)
+		    || (cmdPtr->flags & CMD_HAS_EXEC_TRACES)) {
+		cmdPtr = NULL;
+	    }
+	}
+	if (cmdPtr && !(cmdPtr->flags & CMD_COMPILES_EXPANDED)) {
+	    expand = ExpandRequested(parsePtr->tokenPtr, parsePtr->numWords);
+	    if (expand) {
+		/* We need to expand, but compileProc cannot. */
+		cmdPtr = NULL;
+	    }
+	}
+    }
+
+    /* If cmdPtr != NULL, we will try to call cmdPtr->compileProc */
+    if (cmdPtr) {
+	code = CompileCmdCompileProc(interp, parsePtr, cmdPtr, envPtr);
+    }
+
+    if (code == TCL_ERROR) {
+	if (expand < 0) {
+	    expand = ExpandRequested(parsePtr->tokenPtr, parsePtr->numWords);
+	}
+
+	if (expand) {
+	    CompileExpanded(interp, parsePtr->tokenPtr,
+		    cmdKnown ? cmdObj : NULL, parsePtr->numWords, envPtr);
+	} else {
+	    TclCompileInvocation(interp, parsePtr->tokenPtr,
+		    cmdKnown ? cmdObj : NULL, parsePtr->numWords, envPtr);
+	}
+    }
+
+    Tcl_DecrRefCount(cmdObj);
+
+    TclEmitOpcode(INST_POP, envPtr);
+    EnterCmdExtentData(envPtr, cmdIdx,
+	    parsePtr->term - parsePtr->commandStart,
+	    (envPtr->codeNext-envPtr->codeStart) - startCodeOffset);
+
+    /*
+     * TIP #280: Free full form of per-word line data and insert the reduced
+     * form now
+     */
+
+    envPtr->line = cmdLine;
+    envPtr->clNext = clNext;
+    ckfree(eclPtr->loc[wlineat].line);
+    ckfree(eclPtr->loc[wlineat].next);
+    eclPtr->loc[wlineat].line = wlines;
+    eclPtr->loc[wlineat].next = NULL;
+
+    TclCheckStackDepth(depth, envPtr);
+    return cmdIdx;
+}
+
+void
+TclCompileScript(
+    Tcl_Interp *interp,		/* Used for error and status reporting. Also
+				 * serves as context for finding and compiling
+				 * commands. May not be NULL. */
+    const char *script,		/* The source script to compile. */
+    int numBytes,		/* Number of bytes in script. If < 0, the
+				 * script consists of all bytes up to the
+				 * first null character. */
+    CompileEnv *envPtr)		/* Holds resulting instructions. */
+{
+    int lastCmdIdx = -1;	/* Index into envPtr->cmdMapPtr of the last
+				 * command this routine compiles into bytecode.
+				 * Initial value of -1 indicates this routine
+				 * has not yet generated any bytecode. */
+    const char *p = script;	/* Where we are in our compile. */
+    int depth = TclGetStackDepth(envPtr);
+
+    if (envPtr->iPtr == NULL) {
+	Tcl_Panic("TclCompileScript() called on uninitialized CompileEnv");
+    }
+
+    /* Each iteration compiles one command from the script. */
+
+    while (numBytes > 0) {
+	Tcl_Parse parse;
+	const char *next;
+
+	if (TCL_OK != Tcl_ParseCommand(interp, p, numBytes, 0, &parse)) {
+	    /*
+	     * Compile bytecodes to report the parse error at runtime.
+	     */
+
+	    Tcl_LogCommandInfo(interp, script, parse.commandStart,
+		    parse.term + 1 - parse.commandStart);
+	    TclCompileSyntaxError(interp, envPtr);
+	    return;
+	}
+
+#ifdef TCL_COMPILE_DEBUG
+	/*
+	 * If tracing, print a line for each top level command compiled.
+	 * TODO: Suppress when numWords == 0 ?
+	 */
+
+	if ((tclTraceCompile >= 1) && (envPtr->procPtr == NULL)) {
+	    int commandLength = parse.term - parse.commandStart;
+	    fprintf(stdout, "  Compiling: ");
+	    TclPrintSource(stdout, parse.commandStart,
+		    TclMin(commandLength, 55));
+	    fprintf(stdout, "\n");
+	}
+#endif
+
+	/*
+	 * TIP #280: Count newlines before the command start.
+	 * (See test info-30.33).
+	 */
+
+	TclAdvanceLines(&envPtr->line, p, parse.commandStart);
+	TclAdvanceContinuations(&envPtr->line, &envPtr->clNext,
+		parse.commandStart - envPtr->source);
+
+	/*
+	 * Advance parser to the next command in the script.
+	 */
+
+	next = parse.commandStart + parse.commandSize;
+	numBytes -= next - p;
+	p = next;
+
+	if (parse.numWords == 0) {
+	    /*
+	     * The "command" parsed has no words.  In this case we can skip
+	     * the rest of the loop body.  With no words, clearly
+	     * CompileCommandTokens() has nothing to do.  Since the parser
+	     * aggressively sucks up leading comment and white space,
+	     * including newlines, parse.commandStart must be pointing at
+	     * either the end of script, or a command-terminating semi-colon.
+	     * In either case, the TclAdvance*() calls have nothing to do.
+	     * Finally, when no words are parsed, no tokens have been
+	     * allocated at parse.tokenPtr so there's also nothing for
+	     * Tcl_FreeParse() to do.
+	     *
+	     * The advantage of this shortcut is that CompileCommandTokens()
+	     * can be written with an assumption that parse.numWords > 0, with
+	     * the implication the CCT() always generates bytecode.
+	     */
+	    continue;
+	}
+
+	lastCmdIdx = CompileCommandTokens(interp, &parse, envPtr);
+
+	/*
+	 * TIP #280: Track lines in the just compiled command.
+	 */
+
+	TclAdvanceLines(&envPtr->line, parse.commandStart, p);
+	TclAdvanceContinuations(&envPtr->line, &envPtr->clNext,
+		p - envPtr->source);
+	Tcl_FreeParse(&parse);
+    }
+
+    if (lastCmdIdx == -1) {
+	/*
+	 * Compiling the script yielded no bytecode.  The script must be all
+	 * whitespace, comments, and empty commands.  Such scripts are defined
+	 * to successfully produce the empty string result, so we emit the
+	 * simple bytecode that makes that happen.
+	 */
+
+	PushStringLiteral(envPtr, "");
+    } else {
+	/*
+	 * We compiled at least one command to bytecode.  The routine
+	 * CompileCommandTokens() follows the bytecode of each compiled
+	 * command with an INST_POP, so that stack balance is maintained when
+	 * several commands are in sequence.  (The result of each command is
+	 * thrown away before moving on to the next command).  For the last
+	 * command compiled, we need to undo that INST_POP so that the result
+	 * of the last command becomes the result of the script.  The code
+	 * here removes that trailing INST_POP.
+	 */
+
+	envPtr->cmdMapPtr[lastCmdIdx].numCodeBytes--;
+	envPtr->codeNext--;
+	envPtr->currStackDepth++;
+    }
+    TclCheckStackDepth(depth+1, envPtr);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclCompileTokens --
+ *
+ *	Given an array of tokens parsed from a Tcl command (e.g., the tokens
+ *	that make up a word) this procedure emits instructions to evaluate the
+ *	tokens and concatenate their values to form a single result value on
+ *	the interpreter's runtime evaluation stack.
+ *
+ * Results:
+ *	The return value is a standard Tcl result. If an error occurs, an
+ *	error message is left in the interpreter's result.
+ *
+ * Side effects:
+ *	Instructions are added to envPtr to push and evaluate the tokens at
+ *	runtime.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclCompileVarSubst(
+    Tcl_Interp *interp,
+    Tcl_Token *tokenPtr,
+    CompileEnv *envPtr)
+{
+    const char *p, *name = tokenPtr[1].start;
+    int nameBytes = tokenPtr[1].size;
+    int i, localVar, localVarName = 1;
+
+    /*
+     * Determine how the variable name should be handled: if it contains any
+     * namespace qualifiers it is not a local variable (localVarName=-1); if
+     * it looks like an array element and the token has a single component, it
+     * should not be created here [Bug 569438] (localVarName=0); otherwise,
+     * the local variable can safely be created (localVarName=1).
+     */
+
+    for (i = 0, p = name;  i < nameBytes;  i++, p++) {
+	if ((*p == ':') && (i < nameBytes-1) && (*(p+1) == ':')) {
+	    localVarName = -1;
+	    break;
+	} else if ((*p == '(')
+		&& (tokenPtr->numComponents == 1)
+		&& (*(name + nameBytes - 1) == ')')) {
+	    localVarName = 0;
+	    break;
+	}
+    }
+
+    /*
+     * Either push the variable's name, or find its index in the array
+     * of local variables in a procedure frame.
+     */
+
+    localVar = -1;
+    if (localVarName != -1) {
+	localVar = TclFindCompiledLocal(name, nameBytes, localVarName, envPtr);
+    }
+    if (localVar < 0) {
+	PushLiteral(envPtr, name, nameBytes);
+    }
+
+    /*
+     * Emit instructions to load the variable.
+     */
+
+    TclAdvanceLines(&envPtr->line, tokenPtr[1].start,
+	    tokenPtr[1].start + tokenPtr[1].size);
+
+    if (tokenPtr->numComponents == 1) {
+	if (localVar < 0) {
+	    TclEmitOpcode(INST_LOAD_STK, envPtr);
+	} else if (localVar <= 255) {
+	    TclEmitInstInt1(INST_LOAD_SCALAR1, localVar, envPtr);
+	} else {
+	    TclEmitInstInt4(INST_LOAD_SCALAR4, localVar, envPtr);
+	}
+    } else {
+	TclCompileTokens(interp, tokenPtr+2, tokenPtr->numComponents-1, envPtr);
+	if (localVar < 0) {
+	    TclEmitOpcode(INST_LOAD_ARRAY_STK, envPtr);
+	} else if (localVar <= 255) {
+	    TclEmitInstInt1(INST_LOAD_ARRAY1, localVar, envPtr);
+	} else {
+	    TclEmitInstInt4(INST_LOAD_ARRAY4, localVar, envPtr);
+	}
+    }
+}
+
+void
+TclCompileTokens(
+    Tcl_Interp *interp,		/* Used for error and status reporting. */
+    Tcl_Token *tokenPtr,	/* Pointer to first in an array of tokens to
+				 * compile. */
+    int count,			/* Number of tokens to consider at tokenPtr.
+				 * Must be at least 1. */
+    CompileEnv *envPtr)		/* Holds the resulting instructions. */
+{
+    Tcl_DString textBuffer;	/* Holds concatenated chars from adjacent
+				 * TCL_TOKEN_TEXT, TCL_TOKEN_BS tokens. */
+    char buffer[TCL_UTF_MAX];
+    int i, numObjsToConcat, length, adjust;
+    unsigned char *entryCodeNext = envPtr->codeNext;
+#define NUM_STATIC_POS 20
+    int isLiteral, maxNumCL, numCL;
+    int *clPosition = NULL;
+    int depth = TclGetStackDepth(envPtr);
+
+    /*
+     * For the handling of continuation lines in literals we first check if
+     * this is actually a literal. For if not we can forego the additional
+     * processing. Otherwise we pre-allocate a small table to store the
+     * locations of all continuation lines we find in this literal, if any.
+     * The table is extended if needed.
+     *
+     * Note: Different to the equivalent code in function 'TclSubstTokens()'
+     * (see file "tclParse.c") we do not seem to need the 'adjust' variable.
+     * We also do not seem to need code which merges continuation line
+     * information of multiple words which concat'd at runtime. Either that or
+     * I have not managed to find a test case for these two possibilities yet.
+     * It might be a difference between compile- versus run-time processing.
+     */
+
+    numCL = 0;
+    maxNumCL = 0;
+    isLiteral = 1;
+    for (i=0 ; i < count; i++) {
+	if ((tokenPtr[i].type != TCL_TOKEN_TEXT)
+		&& (tokenPtr[i].type != TCL_TOKEN_BS)) {
+	    isLiteral = 0;
+	    break;
+	}
+    }
+
+    if (isLiteral) {
+	maxNumCL = NUM_STATIC_POS;
+	clPosition = ckalloc(maxNumCL * sizeof(int));
+    }
+
+    adjust = 0;
+    Tcl_DStringInit(&textBuffer);
+    numObjsToConcat = 0;
+    for ( ;  count > 0;  count--, tokenPtr++) {
+	switch (tokenPtr->type) {
+	case TCL_TOKEN_TEXT:
+	    TclDStringAppendToken(&textBuffer, tokenPtr);
+	    TclAdvanceLines(&envPtr->line, tokenPtr->start,
+		    tokenPtr->start + tokenPtr->size);
+	    break;
+
+	case TCL_TOKEN_BS:
+	    length = TclParseBackslash(tokenPtr->start, tokenPtr->size,
+		    NULL, buffer);
+	    Tcl_DStringAppend(&textBuffer, buffer, length);
+
+	    /*
+	     * If the backslash sequence we found is in a literal, and
+	     * represented a continuation line, we compute and store its
+	     * location (as char offset to the beginning of the _result_
+	     * script). We may have to extend the table of locations.
+	     *
+	     * Note that the continuation line information is relevant even if
+	     * the word we are processing is not a literal, as it can affect
+	     * nested commands. See the branch for TCL_TOKEN_COMMAND below,
+	     * where the adjustment we are tracking here is taken into
+	     * account. The good thing is that we do not need a table of
+	     * everything, just the number of lines we have to add as
+	     * correction.
+	     */
+
+	    if ((length == 1) && (buffer[0] == ' ') &&
+		(tokenPtr->start[1] == '\n')) {
+		if (isLiteral) {
+		    int clPos = Tcl_DStringLength(&textBuffer);
+
+		    if (numCL >= maxNumCL) {
+			maxNumCL *= 2;
+			clPosition = ckrealloc(clPosition,
+                                maxNumCL * sizeof(int));
+		    }
+		    clPosition[numCL] = clPos;
+		    numCL ++;
+		}
+		adjust++;
+	    }
+	    break;
+
+	case TCL_TOKEN_COMMAND:
+	    /*
+	     * Push any accumulated chars appearing before the command.
+	     */
+
+	    if (Tcl_DStringLength(&textBuffer) > 0) {
+		int literal = TclRegisterDStringLiteral(envPtr, &textBuffer);
+
+		TclEmitPush(literal, envPtr);
+		numObjsToConcat++;
+		Tcl_DStringFree(&textBuffer);
+
+		if (numCL) {
+		    TclContinuationsEnter(TclFetchLiteral(envPtr, literal),
+			    numCL, clPosition);
+		}
+		numCL = 0;
+	    }
+
+	    envPtr->line += adjust;
+	    TclCompileScript(interp, tokenPtr->start+1,
+		    tokenPtr->size-2, envPtr);
+	    envPtr->line -= adjust;
+	    numObjsToConcat++;
+	    break;
+
+	case TCL_TOKEN_VARIABLE:
+	    /*
+	     * Push any accumulated chars appearing before the $<var>.
+	     */
+
+	    if (Tcl_DStringLength(&textBuffer) > 0) {
+		int literal;
+
+		literal = TclRegisterDStringLiteral(envPtr, &textBuffer);
+		TclEmitPush(literal, envPtr);
+		numObjsToConcat++;
+		Tcl_DStringFree(&textBuffer);
+	    }
+
+	    TclCompileVarSubst(interp, tokenPtr, envPtr);
+	    numObjsToConcat++;
+	    count -= tokenPtr->numComponents;
+	    tokenPtr += tokenPtr->numComponents;
+	    break;
+
+	default:
+	    Tcl_Panic("Unexpected token type in TclCompileTokens: %d; %.*s",
+		    tokenPtr->type, tokenPtr->size, tokenPtr->start);
+	}
+    }
+
+    /*
+     * Push any accumulated characters appearing at the end.
+     */
+
+    if (Tcl_DStringLength(&textBuffer) > 0) {
+	int literal = TclRegisterDStringLiteral(envPtr, &textBuffer);
+
+	TclEmitPush(literal, envPtr);
+	numObjsToConcat++;
+	if (numCL) {
+	    TclContinuationsEnter(TclFetchLiteral(envPtr, literal),
+		    numCL, clPosition);
+	}
+	numCL = 0;
+    }
+
+    /*
+     * If necessary, concatenate the parts of the word.
+     */
+
+    while (numObjsToConcat > 255) {
+	TclEmitInstInt1(INST_STR_CONCAT1, 255, envPtr);
+	numObjsToConcat -= 254;	/* concat pushes 1 obj, the result */
+    }
+    if (numObjsToConcat > 1) {
+	TclEmitInstInt1(INST_STR_CONCAT1, numObjsToConcat, envPtr);
+    }
+
+    /*
+     * If the tokens yielded no instructions, push an empty string.
+     */
+
+    if (envPtr->codeNext == entryCodeNext) {
+	PushStringLiteral(envPtr, "");
+    }
+    Tcl_DStringFree(&textBuffer);
+
+    /*
+     * Release the temp table we used to collect the locations of continuation
+     * lines, if any.
+     */
+
+    if (maxNumCL) {
+	ckfree(clPosition);
+    }
+    TclCheckStackDepth(depth+1, envPtr);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclCompileCmdWord --
+ *
+ *	Given an array of parse tokens for a word containing one or more Tcl
+ *	commands, emit inline instructions to execute them. This procedure
+ *	differs from TclCompileTokens in that a simple word such as a loop
+ *	body enclosed in braces is not just pushed as a string, but is itself
+ *	parsed into tokens and compiled.
+ *
+ * Results:
+ *	The return value is a standard Tcl result. If an error occurs, an
+ *	error message is left in the interpreter's result.
+ *
+ * Side effects:
+ *	Instructions are added to envPtr to execute the tokens at runtime.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclCompileCmdWord(
+    Tcl_Interp *interp,		/* Used for error and status reporting. */
+    Tcl_Token *tokenPtr,	/* Pointer to first in an array of tokens for
+				 * a command word to compile inline. */
+    int count,			/* Number of tokens to consider at tokenPtr.
+				 * Must be at least 1. */
+    CompileEnv *envPtr)		/* Holds the resulting instructions. */
+{
+    if ((count == 1) && (tokenPtr->type == TCL_TOKEN_TEXT)) {
+	/*
+	 * Handle the common case: if there is a single text token, compile it
+	 * into an inline sequence of instructions.
+	 */
+
+	TclCompileScript(interp, tokenPtr->start, tokenPtr->size, envPtr);
+    } else {
+	/*
+	 * Multiple tokens or the single token involves substitutions. Emit
+	 * instructions to invoke the eval command procedure at runtime on the
+	 * result of evaluating the tokens.
+	 */
+
+	TclCompileTokens(interp, tokenPtr, count, envPtr);
+	TclEmitInvoke(envPtr, INST_EVAL_STK);
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclCompileExprWords --
+ *
+ *	Given an array of parse tokens representing one or more words that
+ *	contain a Tcl expression, emit inline instructions to execute the
+ *	expression. This procedure differs from TclCompileExpr in that it
+ *	supports Tcl's two-level substitution semantics for expressions that
+ *	appear as command words.
+ *
+ * Results:
+ *	The return value is a standard Tcl result. If an error occurs, an
+ *	error message is left in the interpreter's result.
+ *
+ * Side effects:
+ *	Instructions are added to envPtr to execute the expression.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclCompileExprWords(
+    Tcl_Interp *interp,		/* Used for error and status reporting. */
+    Tcl_Token *tokenPtr,	/* Points to first in an array of word tokens
+				 * tokens for the expression to compile
+				 * inline. */
+    int numWords,		/* Number of word tokens starting at tokenPtr.
+				 * Must be at least 1. Each word token
+				 * contains one or more subtokens. */
+    CompileEnv *envPtr)		/* Holds the resulting instructions. */
+{
+    Tcl_Token *wordPtr;
+    int i, concatItems;
+
+    /*
+     * If the expression is a single word that doesn't require substitutions,
+     * just compile its string into inline instructions.
+     */
+
+    if ((numWords == 1) && (tokenPtr->type == TCL_TOKEN_SIMPLE_WORD)) {
+	TclCompileExpr(interp, tokenPtr[1].start,tokenPtr[1].size, envPtr, 1);
+	return;
+    }
+
+    /*
+     * Emit code to call the expr command proc at runtime. Concatenate the
+     * (already substituted once) expr tokens with a space between each.
+     */
+
+    wordPtr = tokenPtr;
+    for (i = 0;  i < numWords;  i++) {
+	CompileTokens(envPtr, wordPtr, interp);
+	if (i < (numWords - 1)) {
+	    PushStringLiteral(envPtr, " ");
+	}
+	wordPtr += wordPtr->numComponents + 1;
+    }
+    concatItems = 2*numWords - 1;
+    while (concatItems > 255) {
+	TclEmitInstInt1(INST_STR_CONCAT1, 255, envPtr);
+	concatItems -= 254;
+    }
+    if (concatItems > 1) {
+	TclEmitInstInt1(INST_STR_CONCAT1, concatItems, envPtr);
+    }
+    TclEmitOpcode(INST_EXPR_STK, envPtr);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclCompileNoOp --
+ *
+ *	Function called to compile no-op's
+ *
+ * Results:
+ *	The return value is TCL_OK, indicating successful compilation.
+ *
+ * Side effects:
+ *	Instructions are added to envPtr to execute a no-op at runtime. No
+ *	result is pushed onto the stack: the compiler has to take care of this
+ *	itself if the last compiled command is a NoOp.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclCompileNoOp(
+    Tcl_Interp *interp,		/* Used for error reporting. */
+    Tcl_Parse *parsePtr,	/* Points to a parse structure for the command
+				 * created by Tcl_ParseCommand. */
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)		/* Holds resulting instructions. */
+{
+    Tcl_Token *tokenPtr;
+    int i;
+
+    tokenPtr = parsePtr->tokenPtr;
+    for (i = 1; i < parsePtr->numWords; i++) {
+	tokenPtr = tokenPtr + tokenPtr->numComponents + 1;
+
+	if (tokenPtr->type != TCL_TOKEN_SIMPLE_WORD) {
+	    CompileTokens(envPtr, tokenPtr, interp);
+	    TclEmitOpcode(INST_POP, envPtr);
+	}
+    }
+    PushStringLiteral(envPtr, "");
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclInitByteCodeObj --
+ *
+ *	Create a ByteCode structure and initialize it from a CompileEnv
+ *	compilation environment structure. The ByteCode structure is smaller
+ *	and contains just that information needed to execute the bytecode
+ *	instructions resulting from compiling a Tcl script. The resulting
+ *	structure is placed in the specified object.
+ *
+ * Results:
+ *	A newly constructed ByteCode object is stored in the internal
+ *	representation of the objPtr.
+ *
+ * Side effects:
+ *	A single heap object is allocated to hold the new ByteCode structure
+ *	and its code, object, command location, and aux data arrays. Note that
+ *	"ownership" (i.e., the pointers to) the Tcl objects and aux data items
+ *	will be handed over to the new ByteCode structure from the CompileEnv
+ *	structure.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclInitByteCodeObj(
+    Tcl_Obj *objPtr,		/* Points object that should be initialized,
+				 * and whose string rep contains the source
+				 * code. */
+    register CompileEnv *envPtr)/* Points to the CompileEnv structure from
+				 * which to create a ByteCode structure. */
+{
+    register ByteCode *codePtr;
+    size_t codeBytes, objArrayBytes, exceptArrayBytes, cmdLocBytes;
+    size_t auxDataArrayBytes, structureSize;
+    register unsigned char *p;
+#ifdef TCL_COMPILE_DEBUG
+    unsigned char *nextPtr;
+#endif
+    int numLitObjects = envPtr->literalArrayNext;
+    Namespace *namespacePtr;
+    int i, isNew;
+    Interp *iPtr;
+
+    if (envPtr->iPtr == NULL) {
+	Tcl_Panic("TclInitByteCodeObj() called on uninitialized CompileEnv");
+    }
+
+    iPtr = envPtr->iPtr;
+
+    codeBytes = envPtr->codeNext - envPtr->codeStart;
+    objArrayBytes = envPtr->literalArrayNext * sizeof(Tcl_Obj *);
+    exceptArrayBytes = envPtr->exceptArrayNext * sizeof(ExceptionRange);
+    auxDataArrayBytes = envPtr->auxDataArrayNext * sizeof(AuxData);
+    cmdLocBytes = GetCmdLocEncodingSize(envPtr);
+
+    /*
+     * Compute the total number of bytes needed for this bytecode.
+     */
+
+    structureSize = sizeof(ByteCode);
+    structureSize += TCL_ALIGN(codeBytes);	  /* align object array */
+    structureSize += TCL_ALIGN(objArrayBytes);	  /* align exc range arr */
+    structureSize += TCL_ALIGN(exceptArrayBytes); /* align AuxData array */
+    structureSize += auxDataArrayBytes;
+    structureSize += cmdLocBytes;
+
+    if (envPtr->iPtr->varFramePtr != NULL) {
+	namespacePtr = envPtr->iPtr->varFramePtr->nsPtr;
+    } else {
+	namespacePtr = envPtr->iPtr->globalNsPtr;
+    }
+
+    p = ckalloc(structureSize);
+    codePtr = (ByteCode *) p;
+    codePtr->interpHandle = TclHandlePreserve(iPtr->handle);
+    codePtr->compileEpoch = iPtr->compileEpoch;
+    codePtr->nsPtr = namespacePtr;
+    codePtr->nsEpoch = namespacePtr->resolverEpoch;
+    codePtr->refCount = 1;
+    if (namespacePtr->compiledVarResProc || iPtr->resolverPtr) {
+	codePtr->flags = TCL_BYTECODE_RESOLVE_VARS;
+    } else {
+	codePtr->flags = 0;
+    }
+    codePtr->source = envPtr->source;
+    codePtr->procPtr = envPtr->procPtr;
+
+    codePtr->numCommands = envPtr->numCommands;
+    codePtr->numSrcBytes = envPtr->numSrcBytes;
+    codePtr->numCodeBytes = codeBytes;
+    codePtr->numLitObjects = numLitObjects;
+    codePtr->numExceptRanges = envPtr->exceptArrayNext;
+    codePtr->numAuxDataItems = envPtr->auxDataArrayNext;
+    codePtr->numCmdLocBytes = cmdLocBytes;
+    codePtr->maxExceptDepth = envPtr->maxExceptDepth;
+    codePtr->maxStackDepth = envPtr->maxStackDepth;
+
+    p += sizeof(ByteCode);
+    codePtr->codeStart = p;
+    memcpy(p, envPtr->codeStart, (size_t) codeBytes);
+
+    p += TCL_ALIGN(codeBytes);		/* align object array */
+    codePtr->objArrayPtr = (Tcl_Obj **) p;
+    for (i = 0;  i < numLitObjects;  i++) {
+	Tcl_Obj *fetched = TclFetchLiteral(envPtr, i);
+
+	if (objPtr == fetched) {
+	    /*
+	     * Prevent circular reference where the bytecode intrep of
+	     * a value contains a literal which is that same value.
+	     * If this is allowed to happen, refcount decrements may not
+	     * reach zero, and memory may leak.  Bugs 467523, 3357771
+	     *
+	     * NOTE:  [Bugs 3392070, 3389764] We make a copy based completely
+	     * on the string value, and do not call Tcl_DuplicateObj() so we
+             * can be sure we do not have any lingering cycles hiding in
+	     * the intrep.
+	     */
+	    int numBytes;
+	    const char *bytes = Tcl_GetStringFromObj(objPtr, &numBytes);
+
+	    codePtr->objArrayPtr[i] = Tcl_NewStringObj(bytes, numBytes);
+	    Tcl_IncrRefCount(codePtr->objArrayPtr[i]);
+	    TclReleaseLiteral((Tcl_Interp *)iPtr, objPtr);
+	} else {
+	    codePtr->objArrayPtr[i] = fetched;
+	}
+    }
+
+    p += TCL_ALIGN(objArrayBytes);	/* align exception range array */
+    if (exceptArrayBytes > 0) {
+	codePtr->exceptArrayPtr = (ExceptionRange *) p;
+	memcpy(p, envPtr->exceptArrayPtr, (size_t) exceptArrayBytes);
+    } else {
+	codePtr->exceptArrayPtr = NULL;
+    }
+
+    p += TCL_ALIGN(exceptArrayBytes);	/* align AuxData array */
+    if (auxDataArrayBytes > 0) {
+	codePtr->auxDataArrayPtr = (AuxData *) p;
+	memcpy(p, envPtr->auxDataArrayPtr, (size_t) auxDataArrayBytes);
+    } else {
+	codePtr->auxDataArrayPtr = NULL;
+    }
+
+    p += auxDataArrayBytes;
+#ifndef TCL_COMPILE_DEBUG
+    EncodeCmdLocMap(envPtr, codePtr, (unsigned char *) p);
+#else
+    nextPtr = EncodeCmdLocMap(envPtr, codePtr, (unsigned char *) p);
+    if (((size_t)(nextPtr - p)) != cmdLocBytes) {
+	Tcl_Panic("TclInitByteCodeObj: encoded cmd location bytes %lu != expected size %lu", (unsigned long)(nextPtr - p), (unsigned long)cmdLocBytes);
+    }
+#endif
+
+    /*
+     * Record various compilation-related statistics about the new ByteCode
+     * structure. Don't include overhead for statistics-related fields.
+     */
+
+#ifdef TCL_COMPILE_STATS
+    codePtr->structureSize = structureSize
+	    - (sizeof(size_t) + sizeof(Tcl_Time));
+    Tcl_GetTime(&codePtr->createTime);
+
+    RecordByteCodeStats(codePtr);
+#endif /* TCL_COMPILE_STATS */
+
+    /*
+     * Free the old internal rep then convert the object to a bytecode object
+     * by making its internal rep point to the just compiled ByteCode.
+     */
+
+    TclFreeIntRep(objPtr);
+    objPtr->internalRep.twoPtrValue.ptr1 = codePtr;
+    objPtr->typePtr = &tclByteCodeType;
+
+    /*
+     * TIP #280. Associate the extended per-word line information with the
+     * byte code object (internal rep), for use with the bc compiler.
+     */
+
+    Tcl_SetHashValue(Tcl_CreateHashEntry(iPtr->lineBCPtr, codePtr,
+	    &isNew), envPtr->extCmdMapPtr);
+    envPtr->extCmdMapPtr = NULL;
+
+    /* We've used up the CompileEnv.  Mark as uninitialized. */
+    envPtr->iPtr = NULL;
+
+    codePtr->localCachePtr = NULL;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclFindCompiledLocal --
+ *
+ *	This procedure is called at compile time to look up and optionally
+ *	allocate an entry ("slot") for a variable in a procedure's array of
+ *	local variables. If the variable's name is NULL, a new temporary
+ *	variable is always created. (Such temporary variables can only be
+ *	referenced using their slot index.)
+ *
+ * Results:
+ *	If create is 0 and the name is non-NULL, then if the variable is
+ *	found, the index of its entry in the procedure's array of local
+ *	variables is returned; otherwise -1 is returned. If name is NULL, the
+ *	index of a new temporary variable is returned. Finally, if create is 1
+ *	and name is non-NULL, the index of a new entry is returned.
+ *
+ * Side effects:
+ *	Creates and registers a new local variable if create is 1 and the
+ *	variable is unknown, or if the name is NULL.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclFindCompiledLocal(
+    register const char *name,	/* Points to first character of the name of a
+				 * scalar or array variable. If NULL, a
+				 * temporary var should be created. */
+    int nameBytes,		/* Number of bytes in the name. */
+    int create,			/* If 1, allocate a local frame entry for the
+				 * variable if it is new. */
+    CompileEnv *envPtr)		/* Points to the current compile environment*/
+{
+    register CompiledLocal *localPtr;
+    int localVar = -1;
+    register int i;
+    Proc *procPtr;
+
+    /*
+     * If not creating a temporary, does a local variable of the specified
+     * name already exist?
+     */
+
+    procPtr = envPtr->procPtr;
+
+    if (procPtr == NULL) {
+	/*
+	 * Compiling a non-body script: give it read access to the LVT in the
+	 * current localCache
+	 */
+
+	LocalCache *cachePtr = envPtr->iPtr->varFramePtr->localCachePtr;
+	const char *localName;
+	Tcl_Obj **varNamePtr;
+	int len;
+
+	if (!cachePtr || !name) {
+	    return -1;
+	}
+
+	varNamePtr = &cachePtr->varName0;
+	for (i=0; i < cachePtr->numVars; varNamePtr++, i++) {
+	    if (*varNamePtr) {
+		localName = Tcl_GetStringFromObj(*varNamePtr, &len);
+		if ((len == nameBytes) && !strncmp(name, localName, len)) {
+		    return i;
+		}
+	    }
+	}
+	return -1;
+    }
+
+    if (name != NULL) {
+	int localCt = procPtr->numCompiledLocals;
+
+	localPtr = procPtr->firstLocalPtr;
+	for (i = 0;  i < localCt;  i++) {
+	    if (!TclIsVarTemporary(localPtr)) {
+		char *localName = localPtr->name;
+
+		if ((nameBytes == localPtr->nameLength) &&
+			(strncmp(name,localName,(unsigned)nameBytes) == 0)) {
+		    return i;
+		}
+	    }
+	    localPtr = localPtr->nextPtr;
+	}
+    }
+
+    /*
+     * Create a new variable if appropriate.
+     */
+
+    if (create || (name == NULL)) {
+	localVar = procPtr->numCompiledLocals;
+	localPtr = ckalloc(TclOffset(CompiledLocal, name) + nameBytes + 1);
+	if (procPtr->firstLocalPtr == NULL) {
+	    procPtr->firstLocalPtr = procPtr->lastLocalPtr = localPtr;
+	} else {
+	    procPtr->lastLocalPtr->nextPtr = localPtr;
+	    procPtr->lastLocalPtr = localPtr;
+	}
+	localPtr->nextPtr = NULL;
+	localPtr->nameLength = nameBytes;
+	localPtr->frameIndex = localVar;
+	localPtr->flags = 0;
+	if (name == NULL) {
+	    localPtr->flags |= VAR_TEMPORARY;
+	}
+	localPtr->defValuePtr = NULL;
+	localPtr->resolveInfo = NULL;
+
+	if (name != NULL) {
+	    memcpy(localPtr->name, name, (size_t) nameBytes);
+	}
+	localPtr->name[nameBytes] = '\0';
+	procPtr->numCompiledLocals++;
+    }
+    return localVar;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclExpandCodeArray --
+ *
+ *	Procedure that uses malloc to allocate more storage for a CompileEnv's
+ *	code array.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The byte code array in *envPtr is reallocated to a new array of double
+ *	the size, and if envPtr->mallocedCodeArray is non-zero the old array
+ *	is freed. Byte codes are copied from the old array to the new one.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclExpandCodeArray(
+    void *envArgPtr)		/* Points to the CompileEnv whose code array
+				 * must be enlarged. */
+{
+    CompileEnv *envPtr = envArgPtr;
+				/* The CompileEnv containing the code array to
+				 * be doubled in size. */
+
+    /*
+     * envPtr->codeNext is equal to envPtr->codeEnd. The currently defined
+     * code bytes are stored between envPtr->codeStart and envPtr->codeNext-1
+     * [inclusive].
+     */
+
+    size_t currBytes = envPtr->codeNext - envPtr->codeStart;
+    size_t newBytes = 2 * (envPtr->codeEnd - envPtr->codeStart);
+
+    if (envPtr->mallocedCodeArray) {
+	envPtr->codeStart = ckrealloc(envPtr->codeStart, newBytes);
+    } else {
+	/*
+	 * envPtr->codeStart isn't a ckalloc'd pointer, so we must code a
+	 * ckrealloc equivalent for ourselves.
+	 */
+
+	unsigned char *newPtr = ckalloc(newBytes);
+
+	memcpy(newPtr, envPtr->codeStart, currBytes);
+	envPtr->codeStart = newPtr;
+	envPtr->mallocedCodeArray = 1;
+    }
+
+    envPtr->codeNext = envPtr->codeStart + currBytes;
+    envPtr->codeEnd = envPtr->codeStart + newBytes;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * EnterCmdStartData --
+ *
+ *	Registers the starting source and bytecode location of a command. This
+ *	information is used at runtime to map between instruction pc and
+ *	source locations.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Inserts source and code location information into the compilation
+ *	environment envPtr for the command at index cmdIndex. The compilation
+ *	environment's CmdLocation array is grown if necessary.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+EnterCmdStartData(
+    CompileEnv *envPtr,		/* Points to the compilation environment
+				 * structure in which to enter command
+				 * location information. */
+    int cmdIndex,		/* Index of the command whose start data is
+				 * being set. */
+    int srcOffset,		/* Offset of first char of the command. */
+    int codeOffset)		/* Offset of first byte of command code. */
+{
+    CmdLocation *cmdLocPtr;
+
+    if ((cmdIndex < 0) || (cmdIndex >= envPtr->numCommands)) {
+	Tcl_Panic("EnterCmdStartData: bad command index %d", cmdIndex);
+    }
+
+    if (cmdIndex >= envPtr->cmdMapEnd) {
+	/*
+	 * Expand the command location array by allocating more storage from
+	 * the heap. The currently allocated CmdLocation entries are stored
+	 * from cmdMapPtr[0] up to cmdMapPtr[envPtr->cmdMapEnd] (inclusive).
+	 */
+
+	size_t currElems = envPtr->cmdMapEnd;
+	size_t newElems = 2 * currElems;
+	size_t currBytes = currElems * sizeof(CmdLocation);
+	size_t newBytes = newElems * sizeof(CmdLocation);
+
+	if (envPtr->mallocedCmdMap) {
+	    envPtr->cmdMapPtr = ckrealloc(envPtr->cmdMapPtr, newBytes);
+	} else {
+	    /*
+	     * envPtr->cmdMapPtr isn't a ckalloc'd pointer, so we must code a
+	     * ckrealloc equivalent for ourselves.
+	     */
+
+	    CmdLocation *newPtr = ckalloc(newBytes);
+
+	    memcpy(newPtr, envPtr->cmdMapPtr, currBytes);
+	    envPtr->cmdMapPtr = newPtr;
+	    envPtr->mallocedCmdMap = 1;
+	}
+	envPtr->cmdMapEnd = newElems;
+    }
+
+    if (cmdIndex > 0) {
+	if (codeOffset < envPtr->cmdMapPtr[cmdIndex-1].codeOffset) {
+	    Tcl_Panic("EnterCmdStartData: cmd map not sorted by code offset");
+	}
+    }
+
+    cmdLocPtr = &envPtr->cmdMapPtr[cmdIndex];
+    cmdLocPtr->codeOffset = codeOffset;
+    cmdLocPtr->srcOffset = srcOffset;
+    cmdLocPtr->numSrcBytes = -1;
+    cmdLocPtr->numCodeBytes = -1;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * EnterCmdExtentData --
+ *
+ *	Registers the source and bytecode length for a command. This
+ *	information is used at runtime to map between instruction pc and
+ *	source locations.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Inserts source and code length information into the compilation
+ *	environment envPtr for the command at index cmdIndex. Starting source
+ *	and bytecode information for the command must already have been
+ *	registered.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+EnterCmdExtentData(
+    CompileEnv *envPtr,		/* Points to the compilation environment
+				 * structure in which to enter command
+				 * location information. */
+    int cmdIndex,		/* Index of the command whose source and code
+				 * length data is being set. */
+    int numSrcBytes,		/* Number of command source chars. */
+    int numCodeBytes)		/* Offset of last byte of command code. */
+{
+    CmdLocation *cmdLocPtr;
+
+    if ((cmdIndex < 0) || (cmdIndex >= envPtr->numCommands)) {
+	Tcl_Panic("EnterCmdExtentData: bad command index %d", cmdIndex);
+    }
+
+    if (cmdIndex > envPtr->cmdMapEnd) {
+	Tcl_Panic("EnterCmdExtentData: missing start data for command %d",
+		cmdIndex);
+    }
+
+    cmdLocPtr = &envPtr->cmdMapPtr[cmdIndex];
+    cmdLocPtr->numSrcBytes = numSrcBytes;
+    cmdLocPtr->numCodeBytes = numCodeBytes;
+}
+
+/*
+ *----------------------------------------------------------------------
+ * TIP #280
+ *
+ * EnterCmdWordData --
+ *
+ *	Registers the lines for the words of a command. This information is
+ *	used at runtime by 'info frame'.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Inserts word location information into the compilation environment
+ *	envPtr for the command at index cmdIndex. The compilation
+ *	environment's ExtCmdLoc.ECL array is grown if necessary.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+EnterCmdWordData(
+    ExtCmdLoc *eclPtr,		/* Points to the map environment structure in
+				 * which to enter command location
+				 * information. */
+    int srcOffset,		/* Offset of first char of the command. */
+    Tcl_Token *tokenPtr,
+    const char *cmd,
+    int len,
+    int numWords,
+    int line,
+    int *clNext,
+    int **wlines,
+    CompileEnv *envPtr)
+{
+    ECL *ePtr;
+    const char *last;
+    int wordIdx, wordLine, *wwlines, *wordNext;
+
+    if (eclPtr->nuloc >= eclPtr->nloc) {
+	/*
+	 * Expand the ECL array by allocating more storage from the heap. The
+	 * currently allocated ECL entries are stored from eclPtr->loc[0] up
+	 * to eclPtr->loc[eclPtr->nuloc-1] (inclusive).
+	 */
+
+	size_t currElems = eclPtr->nloc;
+	size_t newElems = (currElems ? 2*currElems : 1);
+	size_t newBytes = newElems * sizeof(ECL);
+
+	eclPtr->loc = ckrealloc(eclPtr->loc, newBytes);
+	eclPtr->nloc = newElems;
+    }
+
+    ePtr = &eclPtr->loc[eclPtr->nuloc];
+    ePtr->srcOffset = srcOffset;
+    ePtr->line = ckalloc(numWords * sizeof(int));
+    ePtr->next = ckalloc(numWords * sizeof(int *));
+    ePtr->nline = numWords;
+    wwlines = ckalloc(numWords * sizeof(int));
+
+    last = cmd;
+    wordLine = line;
+    wordNext = clNext;
+    for (wordIdx=0 ; wordIdx<numWords;
+	    wordIdx++, tokenPtr += tokenPtr->numComponents + 1) {
+	TclAdvanceLines(&wordLine, last, tokenPtr->start);
+	TclAdvanceContinuations(&wordLine, &wordNext,
+		tokenPtr->start - envPtr->source);
+	/* See Ticket 4b61afd660 */
+	wwlines[wordIdx] =
+		((wordIdx == 0) || TclWordKnownAtCompileTime(tokenPtr, NULL))
+		? wordLine : -1;
+	ePtr->line[wordIdx] = wordLine;
+	ePtr->next[wordIdx] = wordNext;
+	last = tokenPtr->start;
+    }
+
+    *wlines = wwlines;
+    eclPtr->nuloc ++;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclCreateExceptRange --
+ *
+ *	Procedure that allocates and initializes a new ExceptionRange
+ *	structure of the specified kind in a CompileEnv.
+ *
+ * Results:
+ *	Returns the index for the newly created ExceptionRange.
+ *
+ * Side effects:
+ *	If there is not enough room in the CompileEnv's ExceptionRange array,
+ *	the array in expanded: a new array of double the size is allocated, if
+ *	envPtr->mallocedExceptArray is non-zero the old array is freed, and
+ *	ExceptionRange entries are copied from the old array to the new one.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclCreateExceptRange(
+    ExceptionRangeType type,	/* The kind of ExceptionRange desired. */
+    register CompileEnv *envPtr)/* Points to CompileEnv for which to create a
+				 * new ExceptionRange structure. */
+{
+    register ExceptionRange *rangePtr;
+    register ExceptionAux *auxPtr;
+    int index = envPtr->exceptArrayNext;
+
+    if (index >= envPtr->exceptArrayEnd) {
+	/*
+	 * Expand the ExceptionRange array. The currently allocated entries
+	 * are stored between elements 0 and (envPtr->exceptArrayNext - 1)
+	 * [inclusive].
+	 */
+
+	size_t currBytes =
+		envPtr->exceptArrayNext * sizeof(ExceptionRange);
+	size_t currBytes2 = envPtr->exceptArrayNext * sizeof(ExceptionAux);
+	int newElems = 2*envPtr->exceptArrayEnd;
+	size_t newBytes = newElems * sizeof(ExceptionRange);
+	size_t newBytes2 = newElems * sizeof(ExceptionAux);
+
+	if (envPtr->mallocedExceptArray) {
+	    envPtr->exceptArrayPtr =
+		    ckrealloc(envPtr->exceptArrayPtr, newBytes);
+	    envPtr->exceptAuxArrayPtr =
+		    ckrealloc(envPtr->exceptAuxArrayPtr, newBytes2);
+	} else {
+	    /*
+	     * envPtr->exceptArrayPtr isn't a ckalloc'd pointer, so we must
+	     * code a ckrealloc equivalent for ourselves.
+	     */
+
+	    ExceptionRange *newPtr = ckalloc(newBytes);
+	    ExceptionAux *newPtr2 = ckalloc(newBytes2);
+
+	    memcpy(newPtr, envPtr->exceptArrayPtr, currBytes);
+	    memcpy(newPtr2, envPtr->exceptAuxArrayPtr, currBytes2);
+	    envPtr->exceptArrayPtr = newPtr;
+	    envPtr->exceptAuxArrayPtr = newPtr2;
+	    envPtr->mallocedExceptArray = 1;
+	}
+	envPtr->exceptArrayEnd = newElems;
+    }
+    envPtr->exceptArrayNext++;
+
+    rangePtr = &envPtr->exceptArrayPtr[index];
+    rangePtr->type = type;
+    rangePtr->nestingLevel = envPtr->exceptDepth;
+    rangePtr->codeOffset = -1;
+    rangePtr->numCodeBytes = -1;
+    rangePtr->breakOffset = -1;
+    rangePtr->continueOffset = -1;
+    rangePtr->catchOffset = -1;
+    auxPtr = &envPtr->exceptAuxArrayPtr[index];
+    auxPtr->supportsContinue = 1;
+    auxPtr->stackDepth = envPtr->currStackDepth;
+    auxPtr->expandTarget = envPtr->expandCount;
+    auxPtr->expandTargetDepth = -1;
+    auxPtr->numBreakTargets = 0;
+    auxPtr->breakTargets = NULL;
+    auxPtr->allocBreakTargets = 0;
+    auxPtr->numContinueTargets = 0;
+    auxPtr->continueTargets = NULL;
+    auxPtr->allocContinueTargets = 0;
+    return index;
+}
+
+/*
+ * ---------------------------------------------------------------------
+ *
+ * TclGetInnermostExceptionRange --
+ *
+ *	Returns the innermost exception range that covers the current code
+ *	creation point, and (optionally) the stack depth that is expected at
+ *	that point. Relies on the fact that the range has a numCodeBytes = -1
+ *	when it is being populated and that inner ranges come after outer
+ *	ranges.
+ *
+ * ---------------------------------------------------------------------
+ */
+
+ExceptionRange *
+TclGetInnermostExceptionRange(
+    CompileEnv *envPtr,
+    int returnCode,
+    ExceptionAux **auxPtrPtr)
+{
+    int i = envPtr->exceptArrayNext;
+    ExceptionRange *rangePtr = envPtr->exceptArrayPtr + i;
+
+    while (i > 0) {
+	rangePtr--; i--;
+
+	if (CurrentOffset(envPtr) >= rangePtr->codeOffset &&
+		(rangePtr->numCodeBytes == -1 || CurrentOffset(envPtr) <
+			rangePtr->codeOffset+rangePtr->numCodeBytes) &&
+		(returnCode != TCL_CONTINUE ||
+			envPtr->exceptAuxArrayPtr[i].supportsContinue)) {
+
+	    if (auxPtrPtr) {
+		*auxPtrPtr = envPtr->exceptAuxArrayPtr + i;
+	    }
+	    return rangePtr;
+	}
+    }
+    return NULL;
+}
+
+/*
+ * ---------------------------------------------------------------------
+ *
+ * TclAddLoopBreakFixup, TclAddLoopContinueFixup --
+ *
+ *	Adds a place that wants to break/continue to the loop exception range
+ *	tracking that will be fixed up once the loop can be finalized. These
+ *	functions will generate an INST_JUMP4 that will be fixed up during the
+ *	loop finalization.
+ *
+ * ---------------------------------------------------------------------
+ */
+
+void
+TclAddLoopBreakFixup(
+    CompileEnv *envPtr,
+    ExceptionAux *auxPtr)
+{
+    int range = auxPtr - envPtr->exceptAuxArrayPtr;
+
+    if (envPtr->exceptArrayPtr[range].type != LOOP_EXCEPTION_RANGE) {
+	Tcl_Panic("trying to add 'break' fixup to full exception range");
+    }
+
+    if (++auxPtr->numBreakTargets > auxPtr->allocBreakTargets) {
+	auxPtr->allocBreakTargets *= 2;
+	auxPtr->allocBreakTargets += 2;
+	if (auxPtr->breakTargets) {
+	    auxPtr->breakTargets = ckrealloc(auxPtr->breakTargets,
+		    sizeof(int) * auxPtr->allocBreakTargets);
+	} else {
+	    auxPtr->breakTargets =
+		    ckalloc(sizeof(int) * auxPtr->allocBreakTargets);
+	}
+    }
+    auxPtr->breakTargets[auxPtr->numBreakTargets - 1] = CurrentOffset(envPtr);
+    TclEmitInstInt4(INST_JUMP4, 0, envPtr);
+}
+
+void
+TclAddLoopContinueFixup(
+    CompileEnv *envPtr,
+    ExceptionAux *auxPtr)
+{
+    int range = auxPtr - envPtr->exceptAuxArrayPtr;
+
+    if (envPtr->exceptArrayPtr[range].type != LOOP_EXCEPTION_RANGE) {
+	Tcl_Panic("trying to add 'continue' fixup to full exception range");
+    }
+
+    if (++auxPtr->numContinueTargets > auxPtr->allocContinueTargets) {
+	auxPtr->allocContinueTargets *= 2;
+	auxPtr->allocContinueTargets += 2;
+	if (auxPtr->continueTargets) {
+	    auxPtr->continueTargets = ckrealloc(auxPtr->continueTargets,
+		    sizeof(int) * auxPtr->allocContinueTargets);
+	} else {
+	    auxPtr->continueTargets =
+		    ckalloc(sizeof(int) * auxPtr->allocContinueTargets);
+	}
+    }
+    auxPtr->continueTargets[auxPtr->numContinueTargets - 1] =
+	    CurrentOffset(envPtr);
+    TclEmitInstInt4(INST_JUMP4, 0, envPtr);
+}
+
+/*
+ * ---------------------------------------------------------------------
+ *
+ * TclCleanupStackForBreakContinue --
+ *
+ *	Ditch the extra elements from the auxiliary stack and the main stack.
+ *	How to do this exactly depends on whether there are any elements on
+ *	the auxiliary stack to pop.
+ *
+ * ---------------------------------------------------------------------
+ */
+
+void
+TclCleanupStackForBreakContinue(
+    CompileEnv *envPtr,
+    ExceptionAux *auxPtr)
+{
+    int savedStackDepth = envPtr->currStackDepth;
+    int toPop = envPtr->expandCount - auxPtr->expandTarget;
+
+    if (toPop > 0) {
+	while (toPop --> 0) {
+	    TclEmitOpcode(INST_EXPAND_DROP, envPtr);
+	}
+	TclAdjustStackDepth(auxPtr->expandTargetDepth - envPtr->currStackDepth,
+		envPtr);
+	envPtr->currStackDepth = auxPtr->expandTargetDepth;
+    }
+    toPop = envPtr->currStackDepth - auxPtr->stackDepth;
+    while (toPop --> 0) {
+	TclEmitOpcode(INST_POP, envPtr);
+    }
+    envPtr->currStackDepth = savedStackDepth;
+}
+
+/*
+ * ---------------------------------------------------------------------
+ *
+ * StartExpanding --
+ *
+ *	Pushes an INST_EXPAND_START and does some additional housekeeping so
+ *	that the [break] and [continue] compilers can use an exception-free
+ *	issue to discard it.
+ *
+ * ---------------------------------------------------------------------
+ */
+
+static void
+StartExpanding(
+    CompileEnv *envPtr)
+{
+    int i;
+
+    TclEmitOpcode(INST_EXPAND_START, envPtr);
+
+    /*
+     * Update inner exception ranges with information about the environment
+     * where this expansion started.
+     */
+
+    for (i=0 ; i<envPtr->exceptArrayNext ; i++) {
+	ExceptionRange *rangePtr = &envPtr->exceptArrayPtr[i];
+	ExceptionAux *auxPtr = &envPtr->exceptAuxArrayPtr[i];
+
+	/*
+	 * Ignore loops unless they're still being built.
+	 */
+
+	if (rangePtr->codeOffset > CurrentOffset(envPtr)) {
+	    continue;
+	}
+	if (rangePtr->numCodeBytes != -1) {
+	    continue;
+	}
+
+	/*
+	 * Adequate condition: further out loops and further in exceptions
+	 * don't actually need this information.
+	 */
+
+	if (auxPtr->expandTarget == envPtr->expandCount) {
+	    auxPtr->expandTargetDepth = envPtr->currStackDepth;
+	}
+    }
+
+    /*
+     * There's now one more expansion being processed on the auxiliary stack.
+     */
+
+    envPtr->expandCount++;
+}
+
+/*
+ * ---------------------------------------------------------------------
+ *
+ * TclFinalizeLoopExceptionRange --
+ *
+ *	Finalizes a loop exception range, binding the registered [break] and
+ *	[continue] implementations so that they jump to the correct place.
+ *	Note that this must only be called after *all* the exception range
+ *	target offsets have been set.
+ *
+ * ---------------------------------------------------------------------
+ */
+
+void
+TclFinalizeLoopExceptionRange(
+    CompileEnv *envPtr,
+    int range)
+{
+    ExceptionRange *rangePtr = &envPtr->exceptArrayPtr[range];
+    ExceptionAux *auxPtr = &envPtr->exceptAuxArrayPtr[range];
+    int i, offset;
+    unsigned char *site;
+
+    if (rangePtr->type != LOOP_EXCEPTION_RANGE) {
+	Tcl_Panic("trying to finalize a loop exception range");
+    }
+
+    /*
+     * Do the jump fixups. Note that these are always issued as INST_JUMP4 so
+     * there is no need to fuss around with updating code offsets.
+     */
+
+    for (i=0 ; i<auxPtr->numBreakTargets ; i++) {
+	site = envPtr->codeStart + auxPtr->breakTargets[i];
+	offset = rangePtr->breakOffset - auxPtr->breakTargets[i];
+	TclUpdateInstInt4AtPc(INST_JUMP4, offset, site);
+    }
+    for (i=0 ; i<auxPtr->numContinueTargets ; i++) {
+	site = envPtr->codeStart + auxPtr->continueTargets[i];
+	if (rangePtr->continueOffset == -1) {
+	    int j;
+
+	    /*
+	     * WTF? Can't bind, so revert to an INST_CONTINUE. Not enough
+	     * space to do anything else.
+	     */
+
+	    *site = INST_CONTINUE;
+	    for (j=0 ; j<4 ; j++) {
+		*++site = INST_NOP;
+	    }
+	} else {
+	    offset = rangePtr->continueOffset - auxPtr->continueTargets[i];
+	    TclUpdateInstInt4AtPc(INST_JUMP4, offset, site);
+	}
+    }
+
+    /*
+     * Drop the arrays we were holding the only reference to.
+     */
+
+    if (auxPtr->breakTargets) {
+	ckfree(auxPtr->breakTargets);
+	auxPtr->breakTargets = NULL;
+	auxPtr->numBreakTargets = 0;
+    }
+    if (auxPtr->continueTargets) {
+	ckfree(auxPtr->continueTargets);
+	auxPtr->continueTargets = NULL;
+	auxPtr->numContinueTargets = 0;
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclCreateAuxData --
+ *
+ *	Procedure that allocates and initializes a new AuxData structure in a
+ *	CompileEnv's array of compilation auxiliary data records. These
+ *	AuxData records hold information created during compilation by
+ *	CompileProcs and used by instructions during execution.
+ *
+ * Results:
+ *	Returns the index for the newly created AuxData structure.
+ *
+ * Side effects:
+ *	If there is not enough room in the CompileEnv's AuxData array, the
+ *	AuxData array in expanded: a new array of double the size is
+ *	allocated, if envPtr->mallocedAuxDataArray is non-zero the old array
+ *	is freed, and AuxData entries are copied from the old array to the new
+ *	one.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclCreateAuxData(
+    ClientData clientData,	/* The compilation auxiliary data to store in
+				 * the new aux data record. */
+    const AuxDataType *typePtr,	/* Pointer to the type to attach to this
+				 * AuxData */
+    register CompileEnv *envPtr)/* Points to the CompileEnv for which a new
+				 * aux data structure is to be allocated. */
+{
+    int index;			/* Index for the new AuxData structure. */
+    register AuxData *auxDataPtr;
+				/* Points to the new AuxData structure */
+
+    index = envPtr->auxDataArrayNext;
+    if (index >= envPtr->auxDataArrayEnd) {
+	/*
+	 * Expand the AuxData array. The currently allocated entries are
+	 * stored between elements 0 and (envPtr->auxDataArrayNext - 1)
+	 * [inclusive].
+	 */
+
+	size_t currBytes = envPtr->auxDataArrayNext * sizeof(AuxData);
+	int newElems = 2*envPtr->auxDataArrayEnd;
+	size_t newBytes = newElems * sizeof(AuxData);
+
+	if (envPtr->mallocedAuxDataArray) {
+	    envPtr->auxDataArrayPtr =
+		    ckrealloc(envPtr->auxDataArrayPtr, newBytes);
+	} else {
+	    /*
+	     * envPtr->auxDataArrayPtr isn't a ckalloc'd pointer, so we must
+	     * code a ckrealloc equivalent for ourselves.
+	     */
+
+	    AuxData *newPtr = ckalloc(newBytes);
+
+	    memcpy(newPtr, envPtr->auxDataArrayPtr, currBytes);
+	    envPtr->auxDataArrayPtr = newPtr;
+	    envPtr->mallocedAuxDataArray = 1;
+	}
+	envPtr->auxDataArrayEnd = newElems;
+    }
+    envPtr->auxDataArrayNext++;
+
+    auxDataPtr = &envPtr->auxDataArrayPtr[index];
+    auxDataPtr->clientData = clientData;
+    auxDataPtr->type = typePtr;
+    return index;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclInitJumpFixupArray --
+ *
+ *	Initializes a JumpFixupArray structure to hold some number of jump
+ *	fixup entries.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The JumpFixupArray structure is initialized.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclInitJumpFixupArray(
+    register JumpFixupArray *fixupArrayPtr)
+				/* Points to the JumpFixupArray structure to
+				 * initialize. */
+{
+    fixupArrayPtr->fixup = fixupArrayPtr->staticFixupSpace;
+    fixupArrayPtr->next = 0;
+    fixupArrayPtr->end = JUMPFIXUP_INIT_ENTRIES - 1;
+    fixupArrayPtr->mallocedArray = 0;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclExpandJumpFixupArray --
+ *
+ *	Procedure that uses malloc to allocate more storage for a jump fixup
+ *	array.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The jump fixup array in *fixupArrayPtr is reallocated to a new array
+ *	of double the size, and if fixupArrayPtr->mallocedArray is non-zero
+ *	the old array is freed. Jump fixup structures are copied from the old
+ *	array to the new one.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclExpandJumpFixupArray(
+    register JumpFixupArray *fixupArrayPtr)
+				/* Points to the JumpFixupArray structure to
+				 * enlarge. */
+{
+    /*
+     * The currently allocated jump fixup entries are stored from fixup[0] up
+     * to fixup[fixupArrayPtr->fixupNext] (*not* inclusive). We assume
+     * fixupArrayPtr->fixupNext is equal to fixupArrayPtr->fixupEnd.
+     */
+
+    size_t currBytes = fixupArrayPtr->next * sizeof(JumpFixup);
+    int newElems = 2*(fixupArrayPtr->end + 1);
+    size_t newBytes = newElems * sizeof(JumpFixup);
+
+    if (fixupArrayPtr->mallocedArray) {
+	fixupArrayPtr->fixup = ckrealloc(fixupArrayPtr->fixup, newBytes);
+    } else {
+	/*
+	 * fixupArrayPtr->fixup isn't a ckalloc'd pointer, so we must code a
+	 * ckrealloc equivalent for ourselves.
+	 */
+
+	JumpFixup *newPtr = ckalloc(newBytes);
+
+	memcpy(newPtr, fixupArrayPtr->fixup, currBytes);
+	fixupArrayPtr->fixup = newPtr;
+	fixupArrayPtr->mallocedArray = 1;
+    }
+    fixupArrayPtr->end = newElems;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclFreeJumpFixupArray --
+ *
+ *	Free any storage allocated in a jump fixup array structure.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Allocated storage in the JumpFixupArray structure is freed.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclFreeJumpFixupArray(
+    register JumpFixupArray *fixupArrayPtr)
+				/* Points to the JumpFixupArray structure to
+				 * free. */
+{
+    if (fixupArrayPtr->mallocedArray) {
+	ckfree(fixupArrayPtr->fixup);
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclEmitForwardJump --
+ *
+ *	Procedure to emit a two-byte forward jump of kind "jumpType". Since
+ *	the jump may later have to be grown to five bytes if the jump target
+ *	is more than, say, 127 bytes away, this procedure also initializes a
+ *	JumpFixup record with information about the jump.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The JumpFixup record pointed to by "jumpFixupPtr" is initialized with
+ *	information needed later if the jump is to be grown. Also, a two byte
+ *	jump of the designated type is emitted at the current point in the
+ *	bytecode stream.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclEmitForwardJump(
+    CompileEnv *envPtr,		/* Points to the CompileEnv structure that
+				 * holds the resulting instruction. */
+    TclJumpType jumpType,	/* Indicates the kind of jump: if true or
+				 * false or unconditional. */
+    JumpFixup *jumpFixupPtr)	/* Points to the JumpFixup structure to
+				 * initialize with information about this
+				 * forward jump. */
+{
+    /*
+     * Initialize the JumpFixup structure:
+     *    - codeOffset is offset of first byte of jump below
+     *    - cmdIndex is index of the command after the current one
+     *    - exceptIndex is the index of the first ExceptionRange after the
+     *	    current one.
+     */
+
+    jumpFixupPtr->jumpType = jumpType;
+    jumpFixupPtr->codeOffset = envPtr->codeNext - envPtr->codeStart;
+    jumpFixupPtr->cmdIndex = envPtr->numCommands;
+    jumpFixupPtr->exceptIndex = envPtr->exceptArrayNext;
+
+    switch (jumpType) {
+    case TCL_UNCONDITIONAL_JUMP:
+	TclEmitInstInt1(INST_JUMP1, 0, envPtr);
+	break;
+    case TCL_TRUE_JUMP:
+	TclEmitInstInt1(INST_JUMP_TRUE1, 0, envPtr);
+	break;
+    default:
+	TclEmitInstInt1(INST_JUMP_FALSE1, 0, envPtr);
+	break;
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclFixupForwardJump --
+ *
+ *	Procedure that updates a previously-emitted forward jump to jump a
+ *	specified number of bytes, "jumpDist". If necessary, the jump is grown
+ *	from two to five bytes; this is done if the jump distance is greater
+ *	than "distThreshold" (normally 127 bytes). The jump is described by a
+ *	JumpFixup record previously initialized by TclEmitForwardJump.
+ *
+ * Results:
+ *	1 if the jump was grown and subsequent instructions had to be moved;
+ *	otherwise 0. This result is returned to allow callers to update any
+ *	additional code offsets they may hold.
+ *
+ * Side effects:
+ *	The jump may be grown and subsequent instructions moved. If this
+ *	happens, the code offsets for any commands and any ExceptionRange
+ *	records between the jump and the current code address will be updated
+ *	to reflect the moved code. Also, the bytecode instruction array in the
+ *	CompileEnv structure may be grown and reallocated.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclFixupForwardJump(
+    CompileEnv *envPtr,		/* Points to the CompileEnv structure that
+				 * holds the resulting instruction. */
+    JumpFixup *jumpFixupPtr,	/* Points to the JumpFixup structure that
+				 * describes the forward jump. */
+    int jumpDist,		/* Jump distance to set in jump instr. */
+    int distThreshold)		/* Maximum distance before the two byte jump
+				 * is grown to five bytes. */
+{
+    unsigned char *jumpPc, *p;
+    int firstCmd, lastCmd, firstRange, lastRange, k;
+    unsigned numBytes;
+
+    if (jumpDist <= distThreshold) {
+	jumpPc = envPtr->codeStart + jumpFixupPtr->codeOffset;
+	switch (jumpFixupPtr->jumpType) {
+	case TCL_UNCONDITIONAL_JUMP:
+	    TclUpdateInstInt1AtPc(INST_JUMP1, jumpDist, jumpPc);
+	    break;
+	case TCL_TRUE_JUMP:
+	    TclUpdateInstInt1AtPc(INST_JUMP_TRUE1, jumpDist, jumpPc);
+	    break;
+	default:
+	    TclUpdateInstInt1AtPc(INST_JUMP_FALSE1, jumpDist, jumpPc);
+	    break;
+	}
+	return 0;
+    }
+
+    /*
+     * We must grow the jump then move subsequent instructions down. Note that
+     * if we expand the space for generated instructions, code addresses might
+     * change; be careful about updating any of these addresses held in
+     * variables.
+     */
+
+    if ((envPtr->codeNext + 3) > envPtr->codeEnd) {
+	TclExpandCodeArray(envPtr);
+    }
+    jumpPc = envPtr->codeStart + jumpFixupPtr->codeOffset;
+    numBytes = envPtr->codeNext-jumpPc-2;
+    p = jumpPc+2;
+    memmove(p+3, p, numBytes);
+
+    envPtr->codeNext += 3;
+    jumpDist += 3;
+    switch (jumpFixupPtr->jumpType) {
+    case TCL_UNCONDITIONAL_JUMP:
+	TclUpdateInstInt4AtPc(INST_JUMP4, jumpDist, jumpPc);
+	break;
+    case TCL_TRUE_JUMP:
+	TclUpdateInstInt4AtPc(INST_JUMP_TRUE4, jumpDist, jumpPc);
+	break;
+    default:
+	TclUpdateInstInt4AtPc(INST_JUMP_FALSE4, jumpDist, jumpPc);
+	break;
+    }
+
+    /*
+     * Adjust the code offsets for any commands and any ExceptionRange records
+     * between the jump and the current code address.
+     */
+
+    firstCmd = jumpFixupPtr->cmdIndex;
+    lastCmd = envPtr->numCommands - 1;
+    if (firstCmd < lastCmd) {
+	for (k = firstCmd;  k <= lastCmd;  k++) {
+	    envPtr->cmdMapPtr[k].codeOffset += 3;
+	}
+    }
+
+    firstRange = jumpFixupPtr->exceptIndex;
+    lastRange = envPtr->exceptArrayNext - 1;
+    for (k = firstRange;  k <= lastRange;  k++) {
+	ExceptionRange *rangePtr = &envPtr->exceptArrayPtr[k];
+
+	rangePtr->codeOffset += 3;
+	switch (rangePtr->type) {
+	case LOOP_EXCEPTION_RANGE:
+	    rangePtr->breakOffset += 3;
+	    if (rangePtr->continueOffset != -1) {
+		rangePtr->continueOffset += 3;
+	    }
+	    break;
+	case CATCH_EXCEPTION_RANGE:
+	    rangePtr->catchOffset += 3;
+	    break;
+	default:
+	    Tcl_Panic("TclFixupForwardJump: bad ExceptionRange type %d",
+		    rangePtr->type);
+	}
+    }
+
+    for (k = 0 ; k < envPtr->exceptArrayNext ; k++) {
+	ExceptionAux *auxPtr = &envPtr->exceptAuxArrayPtr[k];
+	int i;
+
+	for (i=0 ; i<auxPtr->numBreakTargets ; i++) {
+	    if (jumpFixupPtr->codeOffset < auxPtr->breakTargets[i]) {
+		auxPtr->breakTargets[i] += 3;
+	    }
+	}
+	for (i=0 ; i<auxPtr->numContinueTargets ; i++) {
+	    if (jumpFixupPtr->codeOffset < auxPtr->continueTargets[i]) {
+		auxPtr->continueTargets[i] += 3;
+	    }
+	}
+    }
+
+    return 1;			/* the jump was grown */
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclEmitInvoke --
+ *
+ *	Emit one of the invoke-related instructions, wrapping it if necessary
+ *	in code that ensures that any break or continue operation passing
+ *	through it gets the stack unwinding correct, converting it into an
+ *	internal jump if in an appropriate context.
+ *
+ * Results:
+ *	None
+ *
+ * Side effects:
+ *	Issues the jump with all correct stack management. May create another
+ *	loop exception range; pointers to ExceptionRange and ExceptionAux
+ *	structures should not be held across this call.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclEmitInvoke(
+    CompileEnv *envPtr,
+    int opcode,
+    ...)
+{
+    va_list argList;
+    ExceptionRange *rangePtr;
+    ExceptionAux *auxBreakPtr, *auxContinuePtr;
+    int arg1, arg2, wordCount = 0, expandCount = 0;
+    int loopRange = 0, breakRange = 0, continueRange = 0;
+    int cleanup, depth = TclGetStackDepth(envPtr);
+
+    /*
+     * Parse the arguments.
+     */
+
+    va_start(argList, opcode);
+    switch (opcode) {
+    case INST_INVOKE_STK1:
+	wordCount = arg1 = cleanup = va_arg(argList, int);
+	arg2 = 0;
+	break;
+    case INST_INVOKE_STK4:
+	wordCount = arg1 = cleanup = va_arg(argList, int);
+	arg2 = 0;
+	break;
+    case INST_INVOKE_REPLACE:
+	arg1 = va_arg(argList, int);
+	arg2 = va_arg(argList, int);
+	wordCount = arg1 + arg2 - 1;
+	cleanup = arg1 + 1;
+	break;
+    default:
+	Tcl_Panic("unexpected opcode");
+    case INST_EVAL_STK:
+	wordCount = cleanup = 1;
+	arg1 = arg2 = 0;
+	break;
+    case INST_RETURN_STK:
+	wordCount = cleanup = 2;
+	arg1 = arg2 = 0;
+	break;
+    case INST_INVOKE_EXPANDED:
+	wordCount = arg1 = cleanup = va_arg(argList, int);
+	arg2 = 0;
+	expandCount = 1;
+	break;
+    }
+    va_end(argList);
+
+    /*
+     * Determine if we need to handle break and continue exceptions with a
+     * special handling exception range (so that we can correctly unwind the
+     * stack).
+     *
+     * These must be done separately; they can be different (especially for
+     * calls from inside a [for] increment clause).
+     */
+
+    rangePtr = TclGetInnermostExceptionRange(envPtr, TCL_CONTINUE,
+	    &auxContinuePtr);
+    if (rangePtr == NULL || rangePtr->type != LOOP_EXCEPTION_RANGE) {
+	auxContinuePtr = NULL;
+    } else if (auxContinuePtr->stackDepth == envPtr->currStackDepth-wordCount
+	    && auxContinuePtr->expandTarget == envPtr->expandCount-expandCount) {
+	auxContinuePtr = NULL;
+    } else {
+	continueRange = auxContinuePtr - envPtr->exceptAuxArrayPtr;
+    }
+
+    rangePtr = TclGetInnermostExceptionRange(envPtr, TCL_BREAK, &auxBreakPtr);
+    if (rangePtr == NULL || rangePtr->type != LOOP_EXCEPTION_RANGE) {
+	auxBreakPtr = NULL;
+    } else if (auxContinuePtr == NULL
+	    && auxBreakPtr->stackDepth == envPtr->currStackDepth-wordCount
+	    && auxBreakPtr->expandTarget == envPtr->expandCount-expandCount) {
+	auxBreakPtr = NULL;
+    } else {
+	breakRange = auxBreakPtr - envPtr->exceptAuxArrayPtr;
+    }
+
+    if (auxBreakPtr != NULL || auxContinuePtr != NULL) {
+	loopRange = TclCreateExceptRange(LOOP_EXCEPTION_RANGE, envPtr);
+	ExceptionRangeStarts(envPtr, loopRange);
+    }
+
+    /*
+     * Issue the invoke itself.
+     */
+
+    switch (opcode) {
+    case INST_INVOKE_STK1:
+	TclEmitInstInt1(INST_INVOKE_STK1, arg1, envPtr);
+	break;
+    case INST_INVOKE_STK4:
+	TclEmitInstInt4(INST_INVOKE_STK4, arg1, envPtr);
+	break;
+    case INST_INVOKE_EXPANDED:
+	TclEmitOpcode(INST_INVOKE_EXPANDED, envPtr);
+	envPtr->expandCount--;
+	TclAdjustStackDepth(1 - arg1, envPtr);
+	break;
+    case INST_EVAL_STK:
+	TclEmitOpcode(INST_EVAL_STK, envPtr);
+	break;
+    case INST_RETURN_STK:
+	TclEmitOpcode(INST_RETURN_STK, envPtr);
+	break;
+    case INST_INVOKE_REPLACE:
+	TclEmitInstInt4(INST_INVOKE_REPLACE, arg1, envPtr);
+	TclEmitInt1(arg2, envPtr);
+	TclAdjustStackDepth(-1, envPtr); /* Correction to stack depth calcs */
+	break;
+    }
+
+    /*
+     * If we're generating a special wrapper exception range, we need to
+     * finish that up now.
+     */
+
+    if (auxBreakPtr != NULL || auxContinuePtr != NULL) {
+	int savedStackDepth = envPtr->currStackDepth;
+	int savedExpandCount = envPtr->expandCount;
+	JumpFixup nonTrapFixup;
+
+	if (auxBreakPtr != NULL) {
+	    auxBreakPtr = envPtr->exceptAuxArrayPtr + breakRange;
+	}
+	if (auxContinuePtr != NULL) {
+	    auxContinuePtr = envPtr->exceptAuxArrayPtr + continueRange;
+	}
+
+	ExceptionRangeEnds(envPtr, loopRange);
+	TclEmitForwardJump(envPtr, TCL_UNCONDITIONAL_JUMP, &nonTrapFixup);
+
+	/*
+	 * Careful! When generating these stack unwinding sequences, the depth
+	 * of stack in the cases where they are taken is not the same as if
+	 * the exception is not taken.
+	 */
+
+	if (auxBreakPtr != NULL) {
+	    TclAdjustStackDepth(-1, envPtr);
+
+	    ExceptionRangeTarget(envPtr, loopRange, breakOffset);
+	    TclCleanupStackForBreakContinue(envPtr, auxBreakPtr);
+	    TclAddLoopBreakFixup(envPtr, auxBreakPtr);
+	    TclAdjustStackDepth(1, envPtr);
+
+	    envPtr->currStackDepth = savedStackDepth;
+	    envPtr->expandCount = savedExpandCount;
+	}
+
+	if (auxContinuePtr != NULL) {
+	    TclAdjustStackDepth(-1, envPtr);
+
+	    ExceptionRangeTarget(envPtr, loopRange, continueOffset);
+	    TclCleanupStackForBreakContinue(envPtr, auxContinuePtr);
+	    TclAddLoopContinueFixup(envPtr, auxContinuePtr);
+	    TclAdjustStackDepth(1, envPtr);
+
+	    envPtr->currStackDepth = savedStackDepth;
+	    envPtr->expandCount = savedExpandCount;
+	}
+
+	TclFinalizeLoopExceptionRange(envPtr, loopRange);
+	TclFixupForwardJumpToHere(envPtr, &nonTrapFixup, 127);
+    }
+    TclCheckStackDepth(depth+1-cleanup, envPtr);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclGetInstructionTable --
+ *
+ *	Returns a pointer to the table describing Tcl bytecode instructions.
+ *	This procedure is defined so that clients can access the pointer from
+ *	outside the TCL DLLs.
+ *
+ * Results:
+ *	Returns a pointer to the global instruction table, same as the
+ *	expression (&tclInstructionTable[0]).
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+const void * /* == InstructionDesc* == */
+TclGetInstructionTable(void)
+{
+    return &tclInstructionTable[0];
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * GetCmdLocEncodingSize --
+ *
+ *	Computes the total number of bytes needed to encode the command
+ *	location information for some compiled code.
+ *
+ * Results:
+ *	The byte count needed to encode the compiled location information.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+GetCmdLocEncodingSize(
+    CompileEnv *envPtr)		/* Points to compilation environment structure
+				 * containing the CmdLocation structure to
+				 * encode. */
+{
+    register CmdLocation *mapPtr = envPtr->cmdMapPtr;
+    int numCmds = envPtr->numCommands;
+    int codeDelta, codeLen, srcDelta, srcLen;
+    int codeDeltaNext, codeLengthNext, srcDeltaNext, srcLengthNext;
+				/* The offsets in their respective byte
+				 * sequences where the next encoded offset or
+				 * length should go. */
+    int prevCodeOffset, prevSrcOffset, i;
+
+    codeDeltaNext = codeLengthNext = srcDeltaNext = srcLengthNext = 0;
+    prevCodeOffset = prevSrcOffset = 0;
+    for (i = 0;  i < numCmds;  i++) {
+	codeDelta = mapPtr[i].codeOffset - prevCodeOffset;
+	if (codeDelta < 0) {
+	    Tcl_Panic("GetCmdLocEncodingSize: bad code offset");
+	} else if (codeDelta <= 127) {
+	    codeDeltaNext++;
+	} else {
+	    codeDeltaNext += 5;	/* 1 byte for 0xFF, 4 for positive delta */
+	}
+	prevCodeOffset = mapPtr[i].codeOffset;
+
+	codeLen = mapPtr[i].numCodeBytes;
+	if (codeLen < 0) {
+	    Tcl_Panic("GetCmdLocEncodingSize: bad code length");
+	} else if (codeLen <= 127) {
+	    codeLengthNext++;
+	} else {
+	    codeLengthNext += 5;/* 1 byte for 0xFF, 4 for length */
+	}
+
+	srcDelta = mapPtr[i].srcOffset - prevSrcOffset;
+	if ((-127 <= srcDelta) && (srcDelta <= 127) && (srcDelta != -1)) {
+	    srcDeltaNext++;
+	} else {
+	    srcDeltaNext += 5;	/* 1 byte for 0xFF, 4 for delta */
+	}
+	prevSrcOffset = mapPtr[i].srcOffset;
+
+	srcLen = mapPtr[i].numSrcBytes;
+	if (srcLen < 0) {
+	    Tcl_Panic("GetCmdLocEncodingSize: bad source length");
+	} else if (srcLen <= 127) {
+	    srcLengthNext++;
+	} else {
+	    srcLengthNext += 5;	/* 1 byte for 0xFF, 4 for length */
+	}
+    }
+
+    return (codeDeltaNext + codeLengthNext + srcDeltaNext + srcLengthNext);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * EncodeCmdLocMap --
+ *
+ *	Encode the command location information for some compiled code into a
+ *	ByteCode structure. The encoded command location map is stored as
+ *	three adjacent byte sequences.
+ *
+ * Results:
+ *	Pointer to the first byte after the encoded command location
+ *	information.
+ *
+ * Side effects:
+ *	The encoded information is stored into the block of memory headed by
+ *	codePtr. Also records pointers to the start of the four byte sequences
+ *	in fields in codePtr's ByteCode header structure.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static unsigned char *
+EncodeCmdLocMap(
+    CompileEnv *envPtr,		/* Points to compilation environment structure
+				 * containing the CmdLocation structure to
+				 * encode. */
+    ByteCode *codePtr,		/* ByteCode in which to encode envPtr's
+				 * command location information. */
+    unsigned char *startPtr)	/* Points to the first byte in codePtr's
+				 * memory block where the location information
+				 * is to be stored. */
+{
+    register CmdLocation *mapPtr = envPtr->cmdMapPtr;
+    int numCmds = envPtr->numCommands;
+    register unsigned char *p = startPtr;
+    int codeDelta, codeLen, srcDelta, srcLen, prevOffset;
+    register int i;
+
+    /*
+     * Encode the code offset for each command as a sequence of deltas.
+     */
+
+    codePtr->codeDeltaStart = p;
+    prevOffset = 0;
+    for (i = 0;  i < numCmds;  i++) {
+	codeDelta = mapPtr[i].codeOffset - prevOffset;
+	if (codeDelta < 0) {
+	    Tcl_Panic("EncodeCmdLocMap: bad code offset");
+	} else if (codeDelta <= 127) {
+	    TclStoreInt1AtPtr(codeDelta, p);
+	    p++;
+	} else {
+	    TclStoreInt1AtPtr(0xFF, p);
+	    p++;
+	    TclStoreInt4AtPtr(codeDelta, p);
+	    p += 4;
+	}
+	prevOffset = mapPtr[i].codeOffset;
+    }
+
+    /*
+     * Encode the code length for each command.
+     */
+
+    codePtr->codeLengthStart = p;
+    for (i = 0;  i < numCmds;  i++) {
+	codeLen = mapPtr[i].numCodeBytes;
+	if (codeLen < 0) {
+	    Tcl_Panic("EncodeCmdLocMap: bad code length");
+	} else if (codeLen <= 127) {
+	    TclStoreInt1AtPtr(codeLen, p);
+	    p++;
+	} else {
+	    TclStoreInt1AtPtr(0xFF, p);
+	    p++;
+	    TclStoreInt4AtPtr(codeLen, p);
+	    p += 4;
+	}
+    }
+
+    /*
+     * Encode the source offset for each command as a sequence of deltas.
+     */
+
+    codePtr->srcDeltaStart = p;
+    prevOffset = 0;
+    for (i = 0;  i < numCmds;  i++) {
+	srcDelta = mapPtr[i].srcOffset - prevOffset;
+	if ((-127 <= srcDelta) && (srcDelta <= 127) && (srcDelta != -1)) {
+	    TclStoreInt1AtPtr(srcDelta, p);
+	    p++;
+	} else {
+	    TclStoreInt1AtPtr(0xFF, p);
+	    p++;
+	    TclStoreInt4AtPtr(srcDelta, p);
+	    p += 4;
+	}
+	prevOffset = mapPtr[i].srcOffset;
+    }
+
+    /*
+     * Encode the source length for each command.
+     */
+
+    codePtr->srcLengthStart = p;
+    for (i = 0;  i < numCmds;  i++) {
+	srcLen = mapPtr[i].numSrcBytes;
+	if (srcLen < 0) {
+	    Tcl_Panic("EncodeCmdLocMap: bad source length");
+	} else if (srcLen <= 127) {
+	    TclStoreInt1AtPtr(srcLen, p);
+	    p++;
+	} else {
+	    TclStoreInt1AtPtr(0xFF, p);
+	    p++;
+	    TclStoreInt4AtPtr(srcLen, p);
+	    p += 4;
+	}
+    }
+
+    return p;
+}
+
+#ifdef TCL_COMPILE_STATS
+/*
+ *----------------------------------------------------------------------
+ *
+ * RecordByteCodeStats --
+ *
+ *	Accumulates various compilation-related statistics for each newly
+ *	compiled ByteCode. Called by the TclInitByteCodeObj when Tcl is
+ *	compiled with the -DTCL_COMPILE_STATS flag
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Accumulates aggregate code-related statistics in the interpreter's
+ *	ByteCodeStats structure. Records statistics specific to a ByteCode in
+ *	its ByteCode structure.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+RecordByteCodeStats(
+    ByteCode *codePtr)		/* Points to ByteCode structure with info
+				 * to add to accumulated statistics. */
+{
+    Interp *iPtr = (Interp *) *codePtr->interpHandle;
+    register ByteCodeStats *statsPtr;
+
+    if (iPtr == NULL) {
+	/* Avoid segfaulting in case we're called in a deleted interp */
+	return;
+    }
+    statsPtr = &(iPtr->stats);
+
+    statsPtr->numCompilations++;
+    statsPtr->totalSrcBytes += (double) codePtr->numSrcBytes;
+    statsPtr->totalByteCodeBytes += (double) codePtr->structureSize;
+    statsPtr->currentSrcBytes += (double) codePtr->numSrcBytes;
+    statsPtr->currentByteCodeBytes += (double) codePtr->structureSize;
+
+    statsPtr->srcCount[TclLog2(codePtr->numSrcBytes)]++;
+    statsPtr->byteCodeCount[TclLog2((int) codePtr->structureSize)]++;
+
+    statsPtr->currentInstBytes += (double) codePtr->numCodeBytes;
+    statsPtr->currentLitBytes += (double)
+	    codePtr->numLitObjects * sizeof(Tcl_Obj *);
+    statsPtr->currentExceptBytes += (double)
+	    codePtr->numExceptRanges * sizeof(ExceptionRange);
+    statsPtr->currentAuxBytes += (double)
+	    codePtr->numAuxDataItems * sizeof(AuxData);
+    statsPtr->currentCmdMapBytes += (double) codePtr->numCmdLocBytes;
+}
+#endif /* TCL_COMPILE_STATS */
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * tab-width: 8
+ * End:
+ */
diff --git a/generic/tclCompile.h b/generic/tclCompile.h
new file mode 100644
index 0000000..d5bc86b
--- /dev/null
+++ b/generic/tclCompile.h
@@ -0,0 +1,1908 @@
+/*
+ * tclCompile.h --
+ *
+ * Copyright (c) 1996-1998 Sun Microsystems, Inc.
+ * Copyright (c) 1998-2000 by Scriptics Corporation.
+ * Copyright (c) 2001 by Kevin B. Kenny. All rights reserved.
+ * Copyright (c) 2007 Daniel A. Steffen <das@users.sourceforge.net>
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#ifndef _TCLCOMPILATION
+#define _TCLCOMPILATION 1
+
+#include "tclInt.h"
+
+struct ByteCode;		/* Forward declaration. */
+
+/*
+ *------------------------------------------------------------------------
+ * Variables related to compilation. These are used in tclCompile.c,
+ * tclExecute.c, tclBasic.c, and their clients.
+ *------------------------------------------------------------------------
+ */
+
+#ifdef TCL_COMPILE_DEBUG
+/*
+ * Variable that controls whether compilation tracing is enabled and, if so,
+ * what level of tracing is desired:
+ *    0: no compilation tracing
+ *    1: summarize compilation of top level cmds and proc bodies
+ *    2: display all instructions of each ByteCode compiled
+ * This variable is linked to the Tcl variable "tcl_traceCompile".
+ */
+
+MODULE_SCOPE int 	tclTraceCompile;
+
+/*
+ * Variable that controls whether execution tracing is enabled and, if so,
+ * what level of tracing is desired:
+ *    0: no execution tracing
+ *    1: trace invocations of Tcl procs only
+ *    2: trace invocations of all (not compiled away) commands
+ *    3: display each instruction executed
+ * This variable is linked to the Tcl variable "tcl_traceExec".
+ */
+
+MODULE_SCOPE int 	tclTraceExec;
+#endif
+
+/*
+ * The type of lambda expressions. Note that every lambda will *always* have a
+ * string representation.
+ */
+
+MODULE_SCOPE const Tcl_ObjType tclLambdaType;
+
+/*
+ *------------------------------------------------------------------------
+ * Data structures related to compilation.
+ *------------------------------------------------------------------------
+ */
+
+/*
+ * The structure used to implement Tcl "exceptions" (exceptional returns): for
+ * example, those generated in loops by the break and continue commands, and
+ * those generated by scripts and caught by the catch command. This
+ * ExceptionRange structure describes a range of code (e.g., a loop body), the
+ * kind of exceptions (e.g., a break or continue) that might occur, and the PC
+ * offsets to jump to if a matching exception does occur. Exception ranges can
+ * nest so this structure includes a nesting level that is used at runtime to
+ * find the closest exception range surrounding a PC. For example, when a
+ * break command is executed, the ExceptionRange structure for the most deeply
+ * nested loop, if any, is found and used. These structures are also generated
+ * for the "next" subcommands of for loops since a break there terminates the
+ * for command. This means a for command actually generates two LoopInfo
+ * structures.
+ */
+
+typedef enum {
+    LOOP_EXCEPTION_RANGE,	/* Exception's range is part of a loop. Break
+				 * and continue "exceptions" cause jumps to
+				 * appropriate PC offsets. */
+    CATCH_EXCEPTION_RANGE	/* Exception's range is controlled by a catch
+				 * command. Errors in the range cause a jump
+				 * to a catch PC offset. */
+} ExceptionRangeType;
+
+typedef struct ExceptionRange {
+    ExceptionRangeType type;	/* The kind of ExceptionRange. */
+    int nestingLevel;		/* Static depth of the exception range. Used
+				 * to find the most deeply-nested range
+				 * surrounding a PC at runtime. */
+    int codeOffset;		/* Offset of the first instruction byte of the
+				 * code range. */
+    int numCodeBytes;		/* Number of bytes in the code range. */
+    int breakOffset;		/* If LOOP_EXCEPTION_RANGE, the target PC
+				 * offset for a break command in the range. */
+    int continueOffset;		/* If LOOP_EXCEPTION_RANGE and not -1, the
+				 * target PC offset for a continue command in
+				 * the code range. Otherwise, ignore this
+				 * range when processing a continue
+				 * command. */
+    int catchOffset;		/* If a CATCH_EXCEPTION_RANGE, the target PC
+				 * offset for any "exception" in range. */
+} ExceptionRange;
+
+/*
+ * Auxiliary data used when issuing (currently just loop) exception ranges,
+ * but which is not required during execution.
+ */
+
+typedef struct ExceptionAux {
+    int supportsContinue;	/* Whether this exception range will have a
+				 * continueOffset created for it; if it is a
+				 * loop exception range that *doesn't* have
+				 * one (see [for] next-clause) then we must
+				 * not pick up the range when scanning for a
+				 * target to continue to. */
+    int stackDepth;		/* The stack depth at the point where the
+				 * exception range was created. This is used
+				 * to calculate the number of POPs required to
+				 * restore the stack to its prior state. */
+    int expandTarget;		/* The number of expansions expected on the
+				 * auxData stack at the time the loop starts;
+				 * we can't currently discard them except by
+				 * doing INST_INVOKE_EXPANDED; this is a known
+				 * problem. */
+    int expandTargetDepth;	/* The stack depth expected at the outermost
+				 * expansion within the loop. Not meaningful
+				 * if there are no open expansions between the
+				 * looping level and the point of jump
+				 * issue. */
+    int numBreakTargets;	/* The number of [break]s that want to be
+				 * targeted to the place where this loop
+				 * exception will be bound to. */
+    unsigned int *breakTargets;	/* The offsets of the INST_JUMP4 instructions
+				 * issued by the [break]s that we must
+				 * update. Note that resizing a jump (via
+				 * TclFixupForwardJump) can cause the contents
+				 * of this array to be updated. When
+				 * numBreakTargets==0, this is NULL. */
+    int allocBreakTargets;	/* The size of the breakTargets array. */
+    int numContinueTargets;	/* The number of [continue]s that want to be
+				 * targeted to the place where this loop
+				 * exception will be bound to. */
+    unsigned int *continueTargets; /* The offsets of the INST_JUMP4 instructions
+				 * issued by the [continue]s that we must
+				 * update. Note that resizing a jump (via
+				 * TclFixupForwardJump) can cause the contents
+				 * of this array to be updated. When
+				 * numContinueTargets==0, this is NULL. */
+    int allocContinueTargets;	/* The size of the continueTargets array. */
+} ExceptionAux;
+
+/*
+ * Structure used to map between instruction pc and source locations. It
+ * defines for each compiled Tcl command its code's starting offset and its
+ * source's starting offset and length. Note that the code offset increases
+ * monotonically: that is, the table is sorted in code offset order. The
+ * source offset is not monotonic.
+ */
+
+typedef struct CmdLocation {
+    int codeOffset;		/* Offset of first byte of command code. */
+    int numCodeBytes;		/* Number of bytes for command's code. */
+    int srcOffset;		/* Offset of first char of the command. */
+    int numSrcBytes;		/* Number of command source chars. */
+} CmdLocation;
+
+/*
+ * TIP #280
+ * Structure to record additional location information for byte code. This
+ * information is internal and not saved. i.e. tbcload'ed code will not have
+ * this information. It records the lines for all words of all commands found
+ * in the byte code. The association with a ByteCode structure BC is done
+ * through the 'lineBCPtr' HashTable in Interp, keyed by the address of BC.
+ * Also recorded is information coming from the context, i.e. type of the
+ * frame and associated information, like the path of a sourced file.
+ */
+
+typedef struct ECL {
+    int srcOffset;		/* Command location to find the entry. */
+    int nline;			/* Number of words in the command */
+    int *line;			/* Line information for all words in the
+				 * command. */
+    int **next;			/* Transient information used by the compiler
+				 * for tracking of hidden continuation
+				 * lines. */
+} ECL;
+
+typedef struct ExtCmdLoc {
+    int type;			/* Context type. */
+    int start;			/* Starting line for compiled script. Needed
+				 * for the extended recompile check in
+				 * tclCompileObj. */
+    Tcl_Obj *path;		/* Path of the sourced file the command is
+				 * in. */
+    ECL *loc;			/* Command word locations (lines). */
+    int nloc;			/* Number of allocated entries in 'loc'. */
+    int nuloc;			/* Number of used entries in 'loc'. */
+} ExtCmdLoc;
+
+/*
+ * CompileProcs need the ability to record information during compilation that
+ * can be used by bytecode instructions during execution. The AuxData
+ * structure provides this "auxiliary data" mechanism. An arbitrary number of
+ * these structures can be stored in the ByteCode record (during compilation
+ * they are stored in a CompileEnv structure). Each AuxData record holds one
+ * word of client-specified data (often a pointer) and is given an index that
+ * instructions can later use to look up the structure and its data.
+ *
+ * The following definitions declare the types of procedures that are called
+ * to duplicate or free this auxiliary data when the containing ByteCode
+ * objects are duplicated and freed. Pointers to these procedures are kept in
+ * the AuxData structure.
+ */
+
+typedef ClientData (AuxDataDupProc)  (ClientData clientData);
+typedef void	   (AuxDataFreeProc) (ClientData clientData);
+typedef void	   (AuxDataPrintProc)(ClientData clientData,
+			    Tcl_Obj *appendObj, struct ByteCode *codePtr,
+			    unsigned int pcOffset);
+
+/*
+ * We define a separate AuxDataType struct to hold type-related information
+ * for the AuxData structure. This separation makes it possible for clients
+ * outside of the TCL core to manipulate (in a limited fashion!) AuxData; for
+ * example, it makes it possible to pickle and unpickle AuxData structs.
+ */
+
+typedef struct AuxDataType {
+    const char *name;		/* The name of the type. Types can be
+				 * registered and found by name */
+    AuxDataDupProc *dupProc;	/* Callback procedure to invoke when the aux
+				 * data is duplicated (e.g., when the ByteCode
+				 * structure containing the aux data is
+				 * duplicated). NULL means just copy the
+				 * source clientData bits; no proc need be
+				 * called. */
+    AuxDataFreeProc *freeProc;	/* Callback procedure to invoke when the aux
+				 * data is freed. NULL means no proc need be
+				 * called. */
+    AuxDataPrintProc *printProc;/* Callback function to invoke when printing
+				 * the aux data as part of debugging. NULL
+				 * means that the data can't be printed. */
+    AuxDataPrintProc *disassembleProc;
+				/* Callback function to invoke when doing a
+				 * disassembly of the aux data (like the
+				 * printProc, except that the output is
+				 * intended to be script-readable). The
+				 * appendObj argument should be filled in with
+				 * a descriptive dictionary; it will start out
+				 * with "name" mapped to the content of the
+				 * name field. NULL means that the printProc
+				 * should be used instead. */
+} AuxDataType;
+
+/*
+ * The definition of the AuxData structure that holds information created
+ * during compilation by CompileProcs and used by instructions during
+ * execution.
+ */
+
+typedef struct AuxData {
+    const AuxDataType *type;	/* Pointer to the AuxData type associated with
+				 * this ClientData. */
+    ClientData clientData;	/* The compilation data itself. */
+} AuxData;
+
+/*
+ * Structure defining the compilation environment. After compilation, fields
+ * describing bytecode instructions are copied out into the more compact
+ * ByteCode structure defined below.
+ */
+
+#define COMPILEENV_INIT_CODE_BYTES    250
+#define COMPILEENV_INIT_NUM_OBJECTS    60
+#define COMPILEENV_INIT_EXCEPT_RANGES   5
+#define COMPILEENV_INIT_CMD_MAP_SIZE   40
+#define COMPILEENV_INIT_AUX_DATA_SIZE   5
+
+typedef struct CompileEnv {
+    Interp *iPtr;		/* Interpreter containing the code being
+				 * compiled. Commands and their compile procs
+				 * are specific to an interpreter so the code
+				 * emitted will depend on the interpreter. */
+    const char *source;		/* The source string being compiled by
+				 * SetByteCodeFromAny. This pointer is not
+				 * owned by the CompileEnv and must not be
+				 * freed or changed by it. */
+    int numSrcBytes;		/* Number of bytes in source. */
+    Proc *procPtr;		/* If a procedure is being compiled, a pointer
+				 * to its Proc structure; otherwise NULL. Used
+				 * to compile local variables. Set from
+				 * information provided by ObjInterpProc in
+				 * tclProc.c. */
+    int numCommands;		/* Number of commands compiled. */
+    int exceptDepth;		/* Current exception range nesting level; -1
+				 * if not in any range currently. */
+    int maxExceptDepth;		/* Max nesting level of exception ranges; -1
+				 * if no ranges have been compiled. */
+    int maxStackDepth;		/* Maximum number of stack elements needed to
+				 * execute the code. Set by compilation
+				 * procedures before returning. */
+    int currStackDepth;		/* Current stack depth. */
+    LiteralTable localLitTable;	/* Contains LiteralEntry's describing all Tcl
+				 * objects referenced by this compiled code.
+				 * Indexed by the string representations of
+				 * the literals. Used to avoid creating
+				 * duplicate objects. */
+    unsigned char *codeStart;	/* Points to the first byte of the code. */
+    unsigned char *codeNext;	/* Points to next code array byte to use. */
+    unsigned char *codeEnd;	/* Points just after the last allocated code
+				 * array byte. */
+    int mallocedCodeArray;	/* Set 1 if code array was expanded and
+				 * codeStart points into the heap.*/
+    LiteralEntry *literalArrayPtr;
+    				/* Points to start of LiteralEntry array. */
+    int literalArrayNext;	/* Index of next free object array entry. */
+    int literalArrayEnd;	/* Index just after last obj array entry. */
+    int mallocedLiteralArray;	/* 1 if object array was expanded and objArray
+				 * points into the heap, else 0. */
+    ExceptionRange *exceptArrayPtr;
+    				/* Points to start of the ExceptionRange
+				 * array. */
+    int exceptArrayNext;	/* Next free ExceptionRange array index.
+				 * exceptArrayNext is the number of ranges and
+				 * (exceptArrayNext-1) is the index of the
+				 * current range's array entry. */
+    int exceptArrayEnd;		/* Index after the last ExceptionRange array
+				 * entry. */
+    int mallocedExceptArray;	/* 1 if ExceptionRange array was expanded and
+				 * exceptArrayPtr points in heap, else 0. */
+    ExceptionAux *exceptAuxArrayPtr;
+				/* Array of information used to restore the
+				 * state when processing BREAK/CONTINUE
+				 * exceptions. Must be the same size as the
+				 * exceptArrayPtr. */
+    CmdLocation *cmdMapPtr;	/* Points to start of CmdLocation array.
+				 * numCommands is the index of the next entry
+				 * to use; (numCommands-1) is the entry index
+				 * for the last command. */
+    int cmdMapEnd;		/* Index after last CmdLocation entry. */
+    int mallocedCmdMap;		/* 1 if command map array was expanded and
+				 * cmdMapPtr points in the heap, else 0. */
+    AuxData *auxDataArrayPtr;	/* Points to auxiliary data array start. */
+    int auxDataArrayNext;	/* Next free compile aux data array index.
+				 * auxDataArrayNext is the number of aux data
+				 * items and (auxDataArrayNext-1) is index of
+				 * current aux data array entry. */
+    int auxDataArrayEnd;	/* Index after last aux data array entry. */
+    int mallocedAuxDataArray;	/* 1 if aux data array was expanded and
+				 * auxDataArrayPtr points in heap else 0. */
+    unsigned char staticCodeSpace[COMPILEENV_INIT_CODE_BYTES];
+				/* Initial storage for code. */
+    LiteralEntry staticLiteralSpace[COMPILEENV_INIT_NUM_OBJECTS];
+				/* Initial storage of LiteralEntry array. */
+    ExceptionRange staticExceptArraySpace[COMPILEENV_INIT_EXCEPT_RANGES];
+				/* Initial ExceptionRange array storage. */
+    ExceptionAux staticExAuxArraySpace[COMPILEENV_INIT_EXCEPT_RANGES];
+				/* Initial static except auxiliary info array
+				 * storage. */
+    CmdLocation staticCmdMapSpace[COMPILEENV_INIT_CMD_MAP_SIZE];
+				/* Initial storage for cmd location map. */
+    AuxData staticAuxDataArraySpace[COMPILEENV_INIT_AUX_DATA_SIZE];
+				/* Initial storage for aux data array. */
+    /* TIP #280 */
+    ExtCmdLoc *extCmdMapPtr;	/* Extended command location information for
+				 * 'info frame'. */
+    int line;			/* First line of the script, based on the
+				 * invoking context, then the line of the
+				 * command currently compiled. */
+    int atCmdStart;		/* Flag to say whether an INST_START_CMD
+				 * should be issued; they should never be
+				 * issued repeatedly, as that is significantly
+				 * inefficient. If set to 2, that instruction
+				 * should not be issued at all (by the generic
+				 * part of the command compiler). */
+    int expandCount;		/* Number of INST_EXPAND_START instructions
+				 * encountered that have not yet been paired
+				 * with a corresponding
+				 * INST_INVOKE_EXPANDED. */
+    int *clNext;		/* If not NULL, it refers to the next slot in
+				 * clLoc to check for an invisible
+				 * continuation line. */
+} CompileEnv;
+
+/*
+ * The structure defining the bytecode instructions resulting from compiling a
+ * Tcl script. Note that this structure is variable length: a single heap
+ * object is allocated to hold the ByteCode structure immediately followed by
+ * the code bytes, the literal object array, the ExceptionRange array, the
+ * CmdLocation map, and the compilation AuxData array.
+ */
+
+/*
+ * A PRECOMPILED bytecode struct is one that was generated from a compiled
+ * image rather than implicitly compiled from source
+ */
+
+#define TCL_BYTECODE_PRECOMPILED		0x0001
+
+/*
+ * When a bytecode is compiled, interp or namespace resolvers have not been
+ * applied yet: this is indicated by the TCL_BYTECODE_RESOLVE_VARS flag.
+ */
+
+#define TCL_BYTECODE_RESOLVE_VARS		0x0002
+
+#define TCL_BYTECODE_RECOMPILE			0x0004
+
+typedef struct ByteCode {
+    TclHandle interpHandle;	/* Handle for interpreter containing the
+				 * compiled code. Commands and their compile
+				 * procs are specific to an interpreter so the
+				 * code emitted will depend on the
+				 * interpreter. */
+    int compileEpoch;		/* Value of iPtr->compileEpoch when this
+				 * ByteCode was compiled. Used to invalidate
+				 * code when, e.g., commands with compile
+				 * procs are redefined. */
+    Namespace *nsPtr;		/* Namespace context in which this code was
+				 * compiled. If the code is executed if a
+				 * different namespace, it must be
+				 * recompiled. */
+    int nsEpoch;		/* Value of nsPtr->resolverEpoch when this
+				 * ByteCode was compiled. Used to invalidate
+				 * code when new namespace resolution rules
+				 * are put into effect. */
+    int refCount;		/* Reference count: set 1 when created plus 1
+				 * for each execution of the code currently
+				 * active. This structure can be freed when
+				 * refCount becomes zero. */
+    unsigned int flags;		/* flags describing state for the codebyte.
+				 * this variable holds ORed values from the
+				 * TCL_BYTECODE_ masks defined above */
+    const char *source;		/* The source string from which this ByteCode
+				 * was compiled. Note that this pointer is not
+				 * owned by the ByteCode and must not be freed
+				 * or modified by it. */
+    Proc *procPtr;		/* If the ByteCode was compiled from a
+				 * procedure body, this is a pointer to its
+				 * Proc structure; otherwise NULL. This
+				 * pointer is also not owned by the ByteCode
+				 * and must not be freed by it. */
+    size_t structureSize;	/* Number of bytes in the ByteCode structure
+				 * itself. Does not include heap space for
+				 * literal Tcl objects or storage referenced
+				 * by AuxData entries. */
+    int numCommands;		/* Number of commands compiled. */
+    int numSrcBytes;		/* Number of source bytes compiled. */
+    int numCodeBytes;		/* Number of code bytes. */
+    int numLitObjects;		/* Number of objects in literal array. */
+    int numExceptRanges;	/* Number of ExceptionRange array elems. */
+    int numAuxDataItems;	/* Number of AuxData items. */
+    int numCmdLocBytes;		/* Number of bytes needed for encoded command
+				 * location information. */
+    int maxExceptDepth;		/* Maximum nesting level of ExceptionRanges;
+				 * -1 if no ranges were compiled. */
+    int maxStackDepth;		/* Maximum number of stack elements needed to
+				 * execute the code. */
+    unsigned char *codeStart;	/* Points to the first byte of the code. This
+				 * is just after the final ByteCode member
+				 * cmdMapPtr. */
+    Tcl_Obj **objArrayPtr;	/* Points to the start of the literal object
+				 * array. This is just after the last code
+				 * byte. */
+    ExceptionRange *exceptArrayPtr;
+    				/* Points to the start of the ExceptionRange
+				 * array. This is just after the last object
+				 * in the object array. */
+    AuxData *auxDataArrayPtr;	/* Points to the start of the auxiliary data
+				 * array. This is just after the last entry in
+				 * the ExceptionRange array. */
+    unsigned char *codeDeltaStart;
+				/* Points to the first of a sequence of bytes
+				 * that encode the change in the starting
+				 * offset of each command's code. If -127 <=
+				 * delta <= 127, it is encoded as 1 byte,
+				 * otherwise 0xFF (128) appears and the delta
+				 * is encoded by the next 4 bytes. Code deltas
+				 * are always positive. This sequence is just
+				 * after the last entry in the AuxData
+				 * array. */
+    unsigned char *codeLengthStart;
+				/* Points to the first of a sequence of bytes
+				 * that encode the length of each command's
+				 * code. The encoding is the same as for code
+				 * deltas. Code lengths are always positive.
+				 * This sequence is just after the last entry
+				 * in the code delta sequence. */
+    unsigned char *srcDeltaStart;
+				/* Points to the first of a sequence of bytes
+				 * that encode the change in the starting
+				 * offset of each command's source. The
+				 * encoding is the same as for code deltas.
+				 * Source deltas can be negative. This
+				 * sequence is just after the last byte in the
+				 * code length sequence. */
+    unsigned char *srcLengthStart;
+				/* Points to the first of a sequence of bytes
+				 * that encode the length of each command's
+				 * source. The encoding is the same as for
+				 * code deltas. Source lengths are always
+				 * positive. This sequence is just after the
+				 * last byte in the source delta sequence. */
+    LocalCache *localCachePtr;	/* Pointer to the start of the cached variable
+				 * names and initialisation data for local
+				 * variables. */
+#ifdef TCL_COMPILE_STATS
+    Tcl_Time createTime;	/* Absolute time when the ByteCode was
+				 * created. */
+#endif /* TCL_COMPILE_STATS */
+} ByteCode;
+
+/*
+ * Opcodes for the Tcl bytecode instructions. These must correspond to the
+ * entries in the table of instruction descriptions, tclInstructionTable, in
+ * tclCompile.c. Also, the order and number of the expression opcodes (e.g.,
+ * INST_LOR) must match the entries in the array operatorStrings in
+ * tclExecute.c.
+ */
+
+/* Opcodes 0 to 9 */
+#define INST_DONE			0
+#define INST_PUSH1			1
+#define INST_PUSH4			2
+#define INST_POP			3
+#define INST_DUP			4
+#define INST_STR_CONCAT1		5
+#define INST_INVOKE_STK1		6
+#define INST_INVOKE_STK4		7
+#define INST_EVAL_STK			8
+#define INST_EXPR_STK			9
+
+/* Opcodes 10 to 23 */
+#define INST_LOAD_SCALAR1		10
+#define INST_LOAD_SCALAR4		11
+#define INST_LOAD_SCALAR_STK		12
+#define INST_LOAD_ARRAY1		13
+#define INST_LOAD_ARRAY4		14
+#define INST_LOAD_ARRAY_STK		15
+#define INST_LOAD_STK			16
+#define INST_STORE_SCALAR1		17
+#define INST_STORE_SCALAR4		18
+#define INST_STORE_SCALAR_STK		19
+#define INST_STORE_ARRAY1		20
+#define INST_STORE_ARRAY4		21
+#define INST_STORE_ARRAY_STK		22
+#define INST_STORE_STK			23
+
+/* Opcodes 24 to 33 */
+#define INST_INCR_SCALAR1		24
+#define INST_INCR_SCALAR_STK		25
+#define INST_INCR_ARRAY1		26
+#define INST_INCR_ARRAY_STK		27
+#define INST_INCR_STK			28
+#define INST_INCR_SCALAR1_IMM		29
+#define INST_INCR_SCALAR_STK_IMM	30
+#define INST_INCR_ARRAY1_IMM		31
+#define INST_INCR_ARRAY_STK_IMM		32
+#define INST_INCR_STK_IMM		33
+
+/* Opcodes 34 to 39 */
+#define INST_JUMP1			34
+#define INST_JUMP4			35
+#define INST_JUMP_TRUE1			36
+#define INST_JUMP_TRUE4			37
+#define INST_JUMP_FALSE1		38
+#define INST_JUMP_FALSE4		39
+
+/* Opcodes 40 to 64 */
+#define INST_LOR			40
+#define INST_LAND			41
+#define INST_BITOR			42
+#define INST_BITXOR			43
+#define INST_BITAND			44
+#define INST_EQ				45
+#define INST_NEQ			46
+#define INST_LT				47
+#define INST_GT				48
+#define INST_LE				49
+#define INST_GE				50
+#define INST_LSHIFT			51
+#define INST_RSHIFT			52
+#define INST_ADD			53
+#define INST_SUB			54
+#define INST_MULT			55
+#define INST_DIV			56
+#define INST_MOD			57
+#define INST_UPLUS			58
+#define INST_UMINUS			59
+#define INST_BITNOT			60
+#define INST_LNOT			61
+#define INST_CALL_BUILTIN_FUNC1		62
+#define INST_CALL_FUNC1			63
+#define INST_TRY_CVT_TO_NUMERIC		64
+
+/* Opcodes 65 to 66 */
+#define INST_BREAK			65
+#define INST_CONTINUE			66
+
+/* Opcodes 67 to 68 */
+#define INST_FOREACH_START4		67 /* DEPRECATED */
+#define INST_FOREACH_STEP4		68 /* DEPRECATED */
+
+/* Opcodes 69 to 72 */
+#define INST_BEGIN_CATCH4		69
+#define INST_END_CATCH			70
+#define INST_PUSH_RESULT		71
+#define INST_PUSH_RETURN_CODE		72
+
+/* Opcodes 73 to 78 */
+#define INST_STR_EQ			73
+#define INST_STR_NEQ			74
+#define INST_STR_CMP			75
+#define INST_STR_LEN			76
+#define INST_STR_INDEX			77
+#define INST_STR_MATCH			78
+
+/* Opcodes 78 to 81 */
+#define INST_LIST			79
+#define INST_LIST_INDEX			80
+#define INST_LIST_LENGTH		81
+
+/* Opcodes 82 to 87 */
+#define INST_APPEND_SCALAR1		82
+#define INST_APPEND_SCALAR4		83
+#define INST_APPEND_ARRAY1		84
+#define INST_APPEND_ARRAY4		85
+#define INST_APPEND_ARRAY_STK		86
+#define INST_APPEND_STK			87
+
+/* Opcodes 88 to 93 */
+#define INST_LAPPEND_SCALAR1		88
+#define INST_LAPPEND_SCALAR4		89
+#define INST_LAPPEND_ARRAY1		90
+#define INST_LAPPEND_ARRAY4		91
+#define INST_LAPPEND_ARRAY_STK		92
+#define INST_LAPPEND_STK		93
+
+/* TIP #22 - LINDEX operator with flat arg list */
+
+#define INST_LIST_INDEX_MULTI		94
+
+/*
+ * TIP #33 - 'lset' command. Code gen also required a Forth-like
+ *	     OVER operation.
+ */
+
+#define INST_OVER			95
+#define INST_LSET_LIST			96
+#define INST_LSET_FLAT			97
+
+/* TIP#90 - 'return' command. */
+
+#define INST_RETURN_IMM			98
+
+/* TIP#123 - exponentiation operator. */
+
+#define INST_EXPON			99
+
+/* TIP #157 - {*}... (word expansion) language syntax support. */
+
+#define INST_EXPAND_START		100
+#define INST_EXPAND_STKTOP		101
+#define INST_INVOKE_EXPANDED		102
+
+/*
+ * TIP #57 - 'lassign' command. Code generation requires immediate
+ *	     LINDEX and LRANGE operators.
+ */
+
+#define INST_LIST_INDEX_IMM		103
+#define INST_LIST_RANGE_IMM		104
+
+#define INST_START_CMD			105
+
+#define INST_LIST_IN			106
+#define INST_LIST_NOT_IN		107
+
+#define INST_PUSH_RETURN_OPTIONS	108
+#define INST_RETURN_STK			109
+
+/*
+ * Dictionary (TIP#111) related commands.
+ */
+
+#define INST_DICT_GET			110
+#define INST_DICT_SET			111
+#define INST_DICT_UNSET			112
+#define INST_DICT_INCR_IMM		113
+#define INST_DICT_APPEND		114
+#define INST_DICT_LAPPEND		115
+#define INST_DICT_FIRST			116
+#define INST_DICT_NEXT			117
+#define INST_DICT_DONE			118
+#define INST_DICT_UPDATE_START		119
+#define INST_DICT_UPDATE_END		120
+
+/*
+ * Instruction to support jumps defined by tables (instead of the classic
+ * [switch] technique of chained comparisons).
+ */
+
+#define INST_JUMP_TABLE			121
+
+/*
+ * Instructions to support compilation of global, variable, upvar and
+ * [namespace upvar].
+ */
+
+#define INST_UPVAR			122
+#define INST_NSUPVAR			123
+#define INST_VARIABLE			124
+
+/* Instruction to support compiling syntax error to bytecode */
+
+#define INST_SYNTAX			125
+
+/* Instruction to reverse N items on top of stack */
+
+#define INST_REVERSE			126
+
+/* regexp instruction */
+
+#define INST_REGEXP			127
+
+/* For [info exists] compilation */
+#define INST_EXIST_SCALAR		128
+#define INST_EXIST_ARRAY		129
+#define INST_EXIST_ARRAY_STK		130
+#define INST_EXIST_STK			131
+
+/* For [subst] compilation */
+#define INST_NOP			132
+#define INST_RETURN_CODE_BRANCH		133
+
+/* For [unset] compilation */
+#define INST_UNSET_SCALAR		134
+#define INST_UNSET_ARRAY		135
+#define INST_UNSET_ARRAY_STK		136
+#define INST_UNSET_STK			137
+
+/* For [dict with], [dict exists], [dict create] and [dict merge] */
+#define INST_DICT_EXPAND		138
+#define INST_DICT_RECOMBINE_STK		139
+#define INST_DICT_RECOMBINE_IMM		140
+#define INST_DICT_EXISTS		141
+#define INST_DICT_VERIFY		142
+
+/* For [string map] and [regsub] compilation */
+#define INST_STR_MAP			143
+#define INST_STR_FIND			144
+#define INST_STR_FIND_LAST		145
+#define INST_STR_RANGE_IMM		146
+#define INST_STR_RANGE			147
+
+/* For operations to do with coroutines and other NRE-manipulators */
+#define INST_YIELD			148
+#define INST_COROUTINE_NAME		149
+#define INST_TAILCALL			150
+
+/* For compilation of basic information operations */
+#define INST_NS_CURRENT			151
+#define INST_INFO_LEVEL_NUM		152
+#define INST_INFO_LEVEL_ARGS		153
+#define INST_RESOLVE_COMMAND		154
+
+/* For compilation relating to TclOO */
+#define INST_TCLOO_SELF			155
+#define INST_TCLOO_CLASS		156
+#define INST_TCLOO_NS			157
+#define INST_TCLOO_IS_OBJECT		158
+
+/* For compilation of [array] subcommands */
+#define INST_ARRAY_EXISTS_STK		159
+#define INST_ARRAY_EXISTS_IMM		160
+#define INST_ARRAY_MAKE_STK		161
+#define INST_ARRAY_MAKE_IMM		162
+
+#define INST_INVOKE_REPLACE		163
+
+#define INST_LIST_CONCAT		164
+
+#define INST_EXPAND_DROP		165
+
+/* New foreach implementation */
+#define INST_FOREACH_START              166
+#define INST_FOREACH_STEP               167
+#define INST_FOREACH_END                168
+#define INST_LMAP_COLLECT               169
+
+/* For compilation of [string trim] and related */
+#define INST_STR_TRIM			170
+#define INST_STR_TRIM_LEFT		171
+#define INST_STR_TRIM_RIGHT		172
+
+#define INST_CONCAT_STK			173
+
+#define INST_STR_UPPER			174
+#define INST_STR_LOWER			175
+#define INST_STR_TITLE			176
+#define INST_STR_REPLACE		177
+
+#define INST_ORIGIN_COMMAND		178
+
+#define INST_TCLOO_NEXT			179
+#define INST_TCLOO_NEXT_CLASS		180
+
+#define INST_YIELD_TO_INVOKE		181
+
+#define INST_NUM_TYPE			182
+#define INST_TRY_CVT_TO_BOOLEAN		183
+#define INST_STR_CLASS			184
+
+#define INST_LAPPEND_LIST		185
+#define INST_LAPPEND_LIST_ARRAY		186
+#define INST_LAPPEND_LIST_ARRAY_STK	187
+#define INST_LAPPEND_LIST_STK		188
+
+/* The last opcode */
+#define LAST_INST_OPCODE		188
+
+/*
+ * Table describing the Tcl bytecode instructions: their name (for displaying
+ * code), total number of code bytes required (including operand bytes), and a
+ * description of the type of each operand. These operand types include signed
+ * and unsigned integers of length one and four bytes. The unsigned integers
+ * are used for indexes or for, e.g., the count of objects to push in a "push"
+ * instruction.
+ */
+
+#define MAX_INSTRUCTION_OPERANDS 2
+
+typedef enum InstOperandType {
+    OPERAND_NONE,
+    OPERAND_INT1,		/* One byte signed integer. */
+    OPERAND_INT4,		/* Four byte signed integer. */
+    OPERAND_UINT1,		/* One byte unsigned integer. */
+    OPERAND_UINT4,		/* Four byte unsigned integer. */
+    OPERAND_IDX4,		/* Four byte signed index (actually an
+				 * integer, but displayed differently.) */
+    OPERAND_LVT1,		/* One byte unsigned index into the local
+				 * variable table. */
+    OPERAND_LVT4,		/* Four byte unsigned index into the local
+				 * variable table. */
+    OPERAND_AUX4,		/* Four byte unsigned index into the aux data
+				 * table. */
+    OPERAND_OFFSET1,		/* One byte signed jump offset. */
+    OPERAND_OFFSET4,		/* Four byte signed jump offset. */
+    OPERAND_LIT1,		/* One byte unsigned index into table of
+				 * literals. */
+    OPERAND_LIT4,		/* Four byte unsigned index into table of
+				 * literals. */
+    OPERAND_SCLS1		/* Index into tclStringClassTable. */
+} InstOperandType;
+
+typedef struct InstructionDesc {
+    const char *name;		/* Name of instruction. */
+    int numBytes;		/* Total number of bytes for instruction. */
+    int stackEffect;		/* The worst-case balance stack effect of the
+				 * instruction, used for stack requirements
+				 * computations. The value INT_MIN signals
+				 * that the instruction's worst case effect is
+				 * (1-opnd1). */
+    int numOperands;		/* Number of operands. */
+    InstOperandType opTypes[MAX_INSTRUCTION_OPERANDS];
+				/* The type of each operand. */
+} InstructionDesc;
+
+MODULE_SCOPE InstructionDesc const tclInstructionTable[];
+
+/*
+ * Constants used by INST_STRING_CLASS to indicate character classes. These
+ * correspond closely by name with what [string is] can support, but there is
+ * no requirement to keep the values the same.
+ */
+
+typedef enum InstStringClassType {
+    STR_CLASS_ALNUM,		/* Unicode alphabet or digit characters. */
+    STR_CLASS_ALPHA,		/* Unicode alphabet characters. */
+    STR_CLASS_ASCII,		/* Characters in range U+000000..U+00007F. */
+    STR_CLASS_CONTROL,		/* Unicode control characters. */
+    STR_CLASS_DIGIT,		/* Unicode digit characters. */
+    STR_CLASS_GRAPH,		/* Unicode printing characters, excluding
+				 * space. */
+    STR_CLASS_LOWER,		/* Unicode lower-case alphabet characters. */
+    STR_CLASS_PRINT,		/* Unicode printing characters, including
+				 * spaces. */
+    STR_CLASS_PUNCT,		/* Unicode punctuation characters. */
+    STR_CLASS_SPACE,		/* Unicode space characters. */
+    STR_CLASS_UPPER,		/* Unicode upper-case alphabet characters. */
+    STR_CLASS_WORD,		/* Unicode word (alphabetic, digit, connector
+				 * punctuation) characters. */
+    STR_CLASS_XDIGIT		/* Characters that can be used as digits in
+				 * hexadecimal numbers ([0-9A-Fa-f]). */
+} InstStringClassType;
+
+typedef struct StringClassDesc {
+    const char *name;		/* Name of the class. */
+    int (*comparator)(int);	/* Function to test if a single unicode
+				 * character is a member of the class. */
+} StringClassDesc;
+
+MODULE_SCOPE StringClassDesc const tclStringClassTable[];
+
+/*
+ * Compilation of some Tcl constructs such as if commands and the logical or
+ * (||) and logical and (&&) operators in expressions requires the generation
+ * of forward jumps. Since the PC target of these jumps isn't known when the
+ * jumps are emitted, we record the offset of each jump in an array of
+ * JumpFixup structures. There is one array for each sequence of jumps to one
+ * target PC. When we learn the target PC, we update the jumps with the
+ * correct distance. Also, if the distance is too great (> 127 bytes), we
+ * replace the single-byte jump with a four byte jump instruction, move the
+ * instructions after the jump down, and update the code offsets for any
+ * commands between the jump and the target.
+ */
+
+typedef enum {
+    TCL_UNCONDITIONAL_JUMP,
+    TCL_TRUE_JUMP,
+    TCL_FALSE_JUMP
+} TclJumpType;
+
+typedef struct JumpFixup {
+    TclJumpType jumpType;	/* Indicates the kind of jump. */
+    unsigned int codeOffset;	/* Offset of the first byte of the one-byte
+				 * forward jump's code. */
+    int cmdIndex;		/* Index of the first command after the one
+				 * for which the jump was emitted. Used to
+				 * update the code offsets for subsequent
+				 * commands if the two-byte jump at jumpPc
+				 * must be replaced with a five-byte one. */
+    int exceptIndex;		/* Index of the first range entry in the
+				 * ExceptionRange array after the current one.
+				 * This field is used to adjust the code
+				 * offsets in subsequent ExceptionRange
+				 * records when a jump is grown from 2 bytes
+				 * to 5 bytes. */
+} JumpFixup;
+
+#define JUMPFIXUP_INIT_ENTRIES	10
+
+typedef struct JumpFixupArray {
+    JumpFixup *fixup;		/* Points to start of jump fixup array. */
+    int next;			/* Index of next free array entry. */
+    int end;			/* Index of last usable entry in array. */
+    int mallocedArray;		/* 1 if array was expanded and fixups points
+				 * into the heap, else 0. */
+    JumpFixup staticFixupSpace[JUMPFIXUP_INIT_ENTRIES];
+				/* Initial storage for jump fixup array. */
+} JumpFixupArray;
+
+/*
+ * The structure describing one variable list of a foreach command. Note that
+ * only foreach commands inside procedure bodies are compiled inline so a
+ * ForeachVarList structure always describes local variables. Furthermore,
+ * only scalar variables are supported for inline-compiled foreach loops.
+ */
+
+typedef struct ForeachVarList {
+    int numVars;		/* The number of variables in the list. */
+    int varIndexes[1];		/* An array of the indexes ("slot numbers")
+				 * for each variable in the procedure's array
+				 * of local variables. Only scalar variables
+				 * are supported. The actual size of this
+				 * field will be large enough to numVars
+				 * indexes. THIS MUST BE THE LAST FIELD IN THE
+				 * STRUCTURE! */
+} ForeachVarList;
+
+/*
+ * Structure used to hold information about a foreach command that is needed
+ * during program execution. These structures are stored in CompileEnv and
+ * ByteCode structures as auxiliary data.
+ */
+
+typedef struct ForeachInfo {
+    int numLists;		/* The number of both the variable and value
+				 * lists of the foreach command. */
+    int firstValueTemp;		/* Index of the first temp var in a proc frame
+				 * used to point to a value list. */
+    int loopCtTemp;		/* Index of temp var in a proc frame holding
+				 * the loop's iteration count. Used to
+				 * determine next value list element to assign
+				 * each loop var. */
+    ForeachVarList *varLists[1];/* An array of pointers to ForeachVarList
+				 * structures describing each var list. The
+				 * actual size of this field will be large
+				 * enough to numVars indexes. THIS MUST BE THE
+				 * LAST FIELD IN THE STRUCTURE! */
+} ForeachInfo;
+
+/*
+ * Structure used to hold information about a switch command that is needed
+ * during program execution. These structures are stored in CompileEnv and
+ * ByteCode structures as auxiliary data.
+ */
+
+typedef struct JumptableInfo {
+    Tcl_HashTable hashTable;	/* Hash that maps strings to signed ints (PC
+				 * offsets). */
+} JumptableInfo;
+
+MODULE_SCOPE const AuxDataType tclJumptableInfoType;
+
+#define JUMPTABLEINFO(envPtr, index) \
+    ((JumptableInfo*)((envPtr)->auxDataArrayPtr[TclGetUInt4AtPtr(index)].clientData))
+
+/*
+ * Structure used to hold information about a [dict update] command that is
+ * needed during program execution. These structures are stored in CompileEnv
+ * and ByteCode structures as auxiliary data.
+ */
+
+typedef struct {
+    int length;			/* Size of array */
+    int varIndices[1];		/* Array of variable indices to manage when
+				 * processing the start and end of a [dict
+				 * update]. There is really more than one
+				 * entry, and the structure is allocated to
+				 * take account of this. MUST BE LAST FIELD IN
+				 * STRUCTURE. */
+} DictUpdateInfo;
+
+/*
+ * ClientData type used by the math operator commands.
+ */
+
+typedef struct {
+    const char *op;		/* Do not call it 'operator': C++ reserved */
+    const char *expected;
+    union {
+	int numArgs;
+	int identity;
+    } i;
+} TclOpCmdClientData;
+
+/*
+ *----------------------------------------------------------------
+ * Procedures exported by tclBasic.c to be used within the engine.
+ *----------------------------------------------------------------
+ */
+
+MODULE_SCOPE Tcl_ObjCmdProc	TclNRInterpCoroutine;
+
+/*
+ *----------------------------------------------------------------
+ * Procedures exported by the engine to be used by tclBasic.c
+ *----------------------------------------------------------------
+ */
+
+MODULE_SCOPE ByteCode *	TclCompileObj(Tcl_Interp *interp, Tcl_Obj *objPtr,
+			    const CmdFrame *invoker, int word);
+
+/*
+ *----------------------------------------------------------------
+ * Procedures shared among Tcl bytecode compilation and execution modules but
+ * not used outside:
+ *----------------------------------------------------------------
+ */
+
+MODULE_SCOPE int	TclAttemptCompileProc(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, int depth, Command *cmdPtr,
+			    CompileEnv *envPtr);
+MODULE_SCOPE void	TclCleanupByteCode(ByteCode *codePtr);
+MODULE_SCOPE void	TclCleanupStackForBreakContinue(CompileEnv *envPtr,
+			    ExceptionAux *auxPtr);
+MODULE_SCOPE void	TclCompileCmdWord(Tcl_Interp *interp,
+			    Tcl_Token *tokenPtr, int count,
+			    CompileEnv *envPtr);
+MODULE_SCOPE void	TclCompileExpr(Tcl_Interp *interp, const char *script,
+			    int numBytes, CompileEnv *envPtr, int optimize);
+MODULE_SCOPE void	TclCompileExprWords(Tcl_Interp *interp,
+			    Tcl_Token *tokenPtr, int numWords,
+			    CompileEnv *envPtr);
+MODULE_SCOPE void	TclCompileInvocation(Tcl_Interp *interp,
+			    Tcl_Token *tokenPtr, Tcl_Obj *cmdObj, int numWords,
+			    CompileEnv *envPtr);
+MODULE_SCOPE void	TclCompileScript(Tcl_Interp *interp,
+			    const char *script, int numBytes,
+			    CompileEnv *envPtr);
+MODULE_SCOPE void	TclCompileSyntaxError(Tcl_Interp *interp,
+			    CompileEnv *envPtr);
+MODULE_SCOPE void	TclCompileTokens(Tcl_Interp *interp,
+			    Tcl_Token *tokenPtr, int count,
+			    CompileEnv *envPtr);
+MODULE_SCOPE void	TclCompileVarSubst(Tcl_Interp *interp,
+			    Tcl_Token *tokenPtr, CompileEnv *envPtr);
+MODULE_SCOPE int	TclCreateAuxData(ClientData clientData,
+			    const AuxDataType *typePtr, CompileEnv *envPtr);
+MODULE_SCOPE int	TclCreateExceptRange(ExceptionRangeType type,
+			    CompileEnv *envPtr);
+MODULE_SCOPE ExecEnv *	TclCreateExecEnv(Tcl_Interp *interp, int size);
+MODULE_SCOPE Tcl_Obj *	TclCreateLiteral(Interp *iPtr, char *bytes,
+			    int length, unsigned int hash, int *newPtr,
+			    Namespace *nsPtr, int flags,
+			    LiteralEntry **globalPtrPtr);
+MODULE_SCOPE void	TclDeleteExecEnv(ExecEnv *eePtr);
+MODULE_SCOPE void	TclDeleteLiteralTable(Tcl_Interp *interp,
+			    LiteralTable *tablePtr);
+MODULE_SCOPE void	TclEmitForwardJump(CompileEnv *envPtr,
+			    TclJumpType jumpType, JumpFixup *jumpFixupPtr);
+MODULE_SCOPE void	TclEmitInvoke(CompileEnv *envPtr, int opcode, ...);
+MODULE_SCOPE ExceptionRange * TclGetExceptionRangeForPc(unsigned char *pc,
+			    int catchOnly, ByteCode *codePtr);
+MODULE_SCOPE void	TclExpandJumpFixupArray(JumpFixupArray *fixupArrayPtr);
+MODULE_SCOPE int	TclNRExecuteByteCode(Tcl_Interp *interp,
+			    ByteCode *codePtr);
+MODULE_SCOPE Tcl_Obj *	TclFetchLiteral(CompileEnv *envPtr, unsigned int index);
+MODULE_SCOPE int	TclFindCompiledLocal(const char *name, int nameChars,
+			    int create, CompileEnv *envPtr);
+MODULE_SCOPE int	TclFixupForwardJump(CompileEnv *envPtr,
+			    JumpFixup *jumpFixupPtr, int jumpDist,
+			    int distThreshold);
+MODULE_SCOPE void	TclFreeCompileEnv(CompileEnv *envPtr);
+MODULE_SCOPE void	TclFreeJumpFixupArray(JumpFixupArray *fixupArrayPtr);
+MODULE_SCOPE void	TclInitByteCodeObj(Tcl_Obj *objPtr,
+			    CompileEnv *envPtr);
+MODULE_SCOPE void	TclInitCompileEnv(Tcl_Interp *interp,
+			    CompileEnv *envPtr, const char *string,
+			    int numBytes, const CmdFrame *invoker, int word);
+MODULE_SCOPE void	TclInitJumpFixupArray(JumpFixupArray *fixupArrayPtr);
+MODULE_SCOPE void	TclInitLiteralTable(LiteralTable *tablePtr);
+MODULE_SCOPE ExceptionRange *TclGetInnermostExceptionRange(CompileEnv *envPtr,
+			    int returnCode, ExceptionAux **auxPtrPtr);
+MODULE_SCOPE void	TclAddLoopBreakFixup(CompileEnv *envPtr,
+			    ExceptionAux *auxPtr);
+MODULE_SCOPE void	TclAddLoopContinueFixup(CompileEnv *envPtr,
+			    ExceptionAux *auxPtr);
+MODULE_SCOPE void	TclFinalizeLoopExceptionRange(CompileEnv *envPtr,
+			    int range);
+#ifdef TCL_COMPILE_STATS
+MODULE_SCOPE char *	TclLiteralStats(LiteralTable *tablePtr);
+MODULE_SCOPE int	TclLog2(int value);
+#endif
+MODULE_SCOPE int	TclLocalScalar(const char *bytes, int numBytes,
+			    CompileEnv *envPtr);
+MODULE_SCOPE int	TclLocalScalarFromToken(Tcl_Token *tokenPtr,
+			    CompileEnv *envPtr);
+MODULE_SCOPE void	TclOptimizeBytecode(void *envPtr);
+#ifdef TCL_COMPILE_DEBUG
+MODULE_SCOPE void	TclPrintByteCodeObj(Tcl_Interp *interp,
+			    Tcl_Obj *objPtr);
+#endif
+MODULE_SCOPE int	TclPrintInstruction(ByteCode *codePtr,
+			    const unsigned char *pc);
+MODULE_SCOPE void	TclPrintObject(FILE *outFile,
+			    Tcl_Obj *objPtr, int maxChars);
+MODULE_SCOPE void	TclPrintSource(FILE *outFile,
+			    const char *string, int maxChars);
+MODULE_SCOPE void	TclPushVarName(Tcl_Interp *interp,
+			    Tcl_Token *varTokenPtr, CompileEnv *envPtr,
+			    int flags, int *localIndexPtr,
+			    int *isScalarPtr);
+MODULE_SCOPE void	TclReleaseLiteral(Tcl_Interp *interp, Tcl_Obj *objPtr);
+MODULE_SCOPE void	TclInvalidateCmdLiteral(Tcl_Interp *interp,
+			    const char *name, Namespace *nsPtr);
+MODULE_SCOPE int	TclSingleOpCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+MODULE_SCOPE int	TclSortingOpCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+MODULE_SCOPE int	TclVariadicOpCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+MODULE_SCOPE int	TclNoIdentOpCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+#ifdef TCL_COMPILE_DEBUG
+MODULE_SCOPE void	TclVerifyGlobalLiteralTable(Interp *iPtr);
+MODULE_SCOPE void	TclVerifyLocalLiteralTable(CompileEnv *envPtr);
+#endif
+MODULE_SCOPE int	TclWordKnownAtCompileTime(Tcl_Token *tokenPtr,
+			    Tcl_Obj *valuePtr);
+MODULE_SCOPE void	TclLogCommandInfo(Tcl_Interp *interp,
+			    const char *script, const char *command,
+			    int length, const unsigned char *pc,
+			    Tcl_Obj **tosPtr);
+MODULE_SCOPE Tcl_Obj	*TclGetInnerContext(Tcl_Interp *interp,
+			    const unsigned char *pc, Tcl_Obj **tosPtr);
+MODULE_SCOPE Tcl_Obj	*TclNewInstNameObj(unsigned char inst);
+MODULE_SCOPE int	TclPushProcCallFrame(ClientData clientData,
+			    register Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[], int isLambda);
+
+
+/*
+ *----------------------------------------------------------------
+ * Macros and flag values used by Tcl bytecode compilation and execution
+ * modules inside the Tcl core but not used outside.
+ *----------------------------------------------------------------
+ */
+
+/*
+ * Simplified form to access AuxData.
+ *
+ * ClientData TclFetchAuxData(CompileEng *envPtr, int index);
+ */
+
+#define TclFetchAuxData(envPtr, index) \
+    (envPtr)->auxDataArrayPtr[(index)].clientData
+
+#define LITERAL_ON_HEAP		0x01
+#define LITERAL_CMD_NAME	0x02
+
+/*
+ * Form of TclRegisterLiteral with flags == 0. In that case, it is safe to
+ * cast away constness, and it is cleanest to do that here, all in one place.
+ *
+ * int TclRegisterNewLiteral(CompileEnv *envPtr, const char *bytes,
+ *			     int length);
+ */
+
+#define TclRegisterNewLiteral(envPtr, bytes, length) \
+    TclRegisterLiteral(envPtr, (char *)(bytes), length, /*flags*/ 0)
+
+/*
+ * Form of TclRegisterLiteral with flags == LITERAL_CMD_NAME. In that case, it
+ * is safe to cast away constness, and it is cleanest to do that here, all in
+ * one place.
+ *
+ * int TclRegisterNewNSLiteral(CompileEnv *envPtr, const char *bytes,
+ *			       int length);
+ */
+
+#define TclRegisterNewCmdLiteral(envPtr, bytes, length) \
+    TclRegisterLiteral(envPtr, (char *)(bytes), length, LITERAL_CMD_NAME)
+
+/*
+ * Macro used to manually adjust the stack requirements; used in cases where
+ * the stack effect cannot be computed from the opcode and its operands, but
+ * is still known at compile time.
+ *
+ * void TclAdjustStackDepth(int delta, CompileEnv *envPtr);
+ */
+
+#define TclAdjustStackDepth(delta, envPtr) \
+    do {								\
+	if ((delta) < 0) {						\
+	    if ((envPtr)->maxStackDepth < (envPtr)->currStackDepth) {	\
+		(envPtr)->maxStackDepth = (envPtr)->currStackDepth;	\
+	    }								\
+	}								\
+	(envPtr)->currStackDepth += (delta);				\
+    } while (0)
+
+#define TclGetStackDepth(envPtr)		\
+    ((envPtr)->currStackDepth)
+
+#define TclSetStackDepth(depth, envPtr)		\
+    (envPtr)->currStackDepth = (depth)
+
+#define TclCheckStackDepth(depth, envPtr)				\
+    do {								\
+	int dd = (depth);						\
+	if (dd != (envPtr)->currStackDepth) {				\
+	    Tcl_Panic("bad stack depth computations: is %i, should be %i", \
+		    (envPtr)->currStackDepth, dd);		\
+	}								\
+    } while (0)
+
+/*
+ * Macro used to update the stack requirements. It is called by the macros
+ * TclEmitOpCode, TclEmitInst1 and TclEmitInst4.
+ * Remark that the very last instruction of a bytecode always reduces the
+ * stack level: INST_DONE or INST_POP, so that the maxStackdepth is always
+ * updated.
+ *
+ * void TclUpdateStackReqs(unsigned char op, int i, CompileEnv *envPtr);
+ */
+
+#define TclUpdateStackReqs(op, i, envPtr) \
+    do {							\
+	int delta = tclInstructionTable[(op)].stackEffect;	\
+	if (delta) {						\
+	    if (delta == INT_MIN) {				\
+		delta = 1 - (i);				\
+	    }							\
+	    TclAdjustStackDepth(delta, envPtr);			\
+	}							\
+    } while (0)
+
+/*
+ * Macros used to update the flag that indicates if we are at the start of a
+ * command, based on whether the opcode is INST_START_COMMAND.
+ *
+ * void TclUpdateAtCmdStart(unsigned char op, CompileEnv *envPtr);
+ */
+
+#define TclUpdateAtCmdStart(op, envPtr) \
+    if ((envPtr)->atCmdStart < 2) {				     \
+	(envPtr)->atCmdStart = ((op) == INST_START_CMD ? 1 : 0);     \
+    }
+
+/*
+ * Macro to emit an opcode byte into a CompileEnv's code array. The ANSI C
+ * "prototype" for this macro is:
+ *
+ * void TclEmitOpcode(unsigned char op, CompileEnv *envPtr);
+ */
+
+#define TclEmitOpcode(op, envPtr) \
+    do {							\
+	if ((envPtr)->codeNext == (envPtr)->codeEnd) {		\
+	    TclExpandCodeArray(envPtr);				\
+	}							\
+	*(envPtr)->codeNext++ = (unsigned char) (op);		\
+	TclUpdateAtCmdStart(op, envPtr);			\
+	TclUpdateStackReqs(op, 0, envPtr);			\
+    } while (0)
+
+/*
+ * Macros to emit an integer operand. The ANSI C "prototype" for these macros
+ * are:
+ *
+ * void TclEmitInt1(int i, CompileEnv *envPtr);
+ * void TclEmitInt4(int i, CompileEnv *envPtr);
+ */
+
+#define TclEmitInt1(i, envPtr) \
+    do {								\
+	if ((envPtr)->codeNext == (envPtr)->codeEnd) {			\
+	    TclExpandCodeArray(envPtr);					\
+	}								\
+	*(envPtr)->codeNext++ = (unsigned char) ((unsigned int) (i));	\
+    } while (0)
+
+#define TclEmitInt4(i, envPtr) \
+    do {								\
+	if (((envPtr)->codeNext + 4) > (envPtr)->codeEnd) {		\
+	    TclExpandCodeArray(envPtr);					\
+	}								\
+	*(envPtr)->codeNext++ =						\
+		(unsigned char) ((unsigned int) (i) >> 24);		\
+	*(envPtr)->codeNext++ =						\
+		(unsigned char) ((unsigned int) (i) >> 16);		\
+	*(envPtr)->codeNext++ =						\
+		(unsigned char) ((unsigned int) (i) >>  8);		\
+	*(envPtr)->codeNext++ =						\
+		(unsigned char) ((unsigned int) (i)      );		\
+    } while (0)
+
+/*
+ * Macros to emit an instruction with signed or unsigned integer operands.
+ * Four byte integers are stored in "big-endian" order with the high order
+ * byte stored at the lowest address. The ANSI C "prototypes" for these macros
+ * are:
+ *
+ * void TclEmitInstInt1(unsigned char op, int i, CompileEnv *envPtr);
+ * void TclEmitInstInt4(unsigned char op, int i, CompileEnv *envPtr);
+ */
+
+#define TclEmitInstInt1(op, i, envPtr) \
+    do {								\
+	if (((envPtr)->codeNext + 2) > (envPtr)->codeEnd) {		\
+	    TclExpandCodeArray(envPtr);					\
+	}								\
+	*(envPtr)->codeNext++ = (unsigned char) (op);			\
+	*(envPtr)->codeNext++ = (unsigned char) ((unsigned int) (i));	\
+	TclUpdateAtCmdStart(op, envPtr);				\
+	TclUpdateStackReqs(op, i, envPtr);				\
+    } while (0)
+
+#define TclEmitInstInt4(op, i, envPtr) \
+    do {							\
+	if (((envPtr)->codeNext + 5) > (envPtr)->codeEnd) {	\
+	    TclExpandCodeArray(envPtr);				\
+	}							\
+	*(envPtr)->codeNext++ = (unsigned char) (op);		\
+	*(envPtr)->codeNext++ =					\
+		(unsigned char) ((unsigned int) (i) >> 24);	\
+	*(envPtr)->codeNext++ =					\
+		(unsigned char) ((unsigned int) (i) >> 16);	\
+	*(envPtr)->codeNext++ =					\
+		(unsigned char) ((unsigned int) (i) >>  8);	\
+	*(envPtr)->codeNext++ =					\
+		(unsigned char) ((unsigned int) (i)      );	\
+	TclUpdateAtCmdStart(op, envPtr);			\
+	TclUpdateStackReqs(op, i, envPtr);			\
+    } while (0)
+
+/*
+ * Macro to push a Tcl object onto the Tcl evaluation stack. It emits the
+ * object's one or four byte array index into the CompileEnv's code array.
+ * These support, respectively, a maximum of 256 (2**8) and 2**32 objects in a
+ * CompileEnv. The ANSI C "prototype" for this macro is:
+ *
+ * void	TclEmitPush(int objIndex, CompileEnv *envPtr);
+ */
+
+#define TclEmitPush(objIndex, envPtr) \
+    do {							 \
+	register int objIndexCopy = (objIndex);			 \
+	if (objIndexCopy <= 255) {				 \
+	    TclEmitInstInt1(INST_PUSH1, objIndexCopy, (envPtr)); \
+	} else {						 \
+	    TclEmitInstInt4(INST_PUSH4, objIndexCopy, (envPtr)); \
+	}							 \
+    } while (0)
+
+/*
+ * Macros to update a (signed or unsigned) integer starting at a pointer. The
+ * two variants depend on the number of bytes. The ANSI C "prototypes" for
+ * these macros are:
+ *
+ * void TclStoreInt1AtPtr(int i, unsigned char *p);
+ * void TclStoreInt4AtPtr(int i, unsigned char *p);
+ */
+
+#define TclStoreInt1AtPtr(i, p) \
+    *(p)   = (unsigned char) ((unsigned int) (i))
+
+#define TclStoreInt4AtPtr(i, p) \
+    do {							\
+	*(p)   = (unsigned char) ((unsigned int) (i) >> 24);	\
+	*(p+1) = (unsigned char) ((unsigned int) (i) >> 16);	\
+	*(p+2) = (unsigned char) ((unsigned int) (i) >>  8);	\
+	*(p+3) = (unsigned char) ((unsigned int) (i)      );	\
+    } while (0)
+
+/*
+ * Macros to update instructions at a particular pc with a new op code and a
+ * (signed or unsigned) int operand. The ANSI C "prototypes" for these macros
+ * are:
+ *
+ * void TclUpdateInstInt1AtPc(unsigned char op, int i, unsigned char *pc);
+ * void TclUpdateInstInt4AtPc(unsigned char op, int i, unsigned char *pc);
+ */
+
+#define TclUpdateInstInt1AtPc(op, i, pc) \
+    do {					\
+	*(pc) = (unsigned char) (op);		\
+	TclStoreInt1AtPtr((i), ((pc)+1));	\
+    } while (0)
+
+#define TclUpdateInstInt4AtPc(op, i, pc) \
+    do {					\
+	*(pc) = (unsigned char) (op);		\
+	TclStoreInt4AtPtr((i), ((pc)+1));	\
+    } while (0)
+
+/*
+ * Macro to fix up a forward jump to point to the current code-generation
+ * position in the bytecode being created (the most common case). The ANSI C
+ * "prototypes" for this macro is:
+ *
+ * int TclFixupForwardJumpToHere(CompileEnv *envPtr, JumpFixup *fixupPtr,
+ *				 int threshold);
+ */
+
+#define TclFixupForwardJumpToHere(envPtr, fixupPtr, threshold) \
+    TclFixupForwardJump((envPtr), (fixupPtr),				\
+	    (envPtr)->codeNext-(envPtr)->codeStart-(fixupPtr)->codeOffset, \
+	    (threshold))
+
+/*
+ * Macros to get a signed integer (GET_INT{1,2}) or an unsigned int
+ * (GET_UINT{1,2}) from a pointer. There are two variants for each return type
+ * that depend on the number of bytes fetched. The ANSI C "prototypes" for
+ * these macros are:
+ *
+ * int TclGetInt1AtPtr(unsigned char *p);
+ * int TclGetInt4AtPtr(unsigned char *p);
+ * unsigned int TclGetUInt1AtPtr(unsigned char *p);
+ * unsigned int TclGetUInt4AtPtr(unsigned char *p);
+ */
+
+/*
+ * The TclGetInt1AtPtr macro is tricky because we want to do sign extension on
+ * the 1-byte value. Unfortunately the "char" type isn't signed on all
+ * platforms so sign-extension doesn't always happen automatically. Sometimes
+ * we can explicitly declare the pointer to be signed, but other times we have
+ * to explicitly sign-extend the value in software.
+ */
+
+#ifndef __CHAR_UNSIGNED__
+#   define TclGetInt1AtPtr(p) ((int) *((char *) p))
+#elif defined(HAVE_SIGNED_CHAR)
+#   define TclGetInt1AtPtr(p) ((int) *((signed char *) p))
+#else
+#   define TclGetInt1AtPtr(p) \
+    (((int) *((char *) p)) | ((*(p) & 0200) ? (-256) : 0))
+#endif
+
+#define TclGetInt4AtPtr(p) \
+    (((int) TclGetInt1AtPtr(p) << 24) |				\
+		     (*((p)+1) << 16) |				\
+		     (*((p)+2) <<  8) |				\
+		     (*((p)+3)))
+
+#define TclGetUInt1AtPtr(p) \
+    ((unsigned int) *(p))
+#define TclGetUInt4AtPtr(p) \
+    ((unsigned int) (*(p)     << 24) |				\
+		    (*((p)+1) << 16) |				\
+		    (*((p)+2) <<  8) |				\
+		    (*((p)+3)))
+
+/*
+ * Macros used to compute the minimum and maximum of two integers. The ANSI C
+ * "prototypes" for these macros are:
+ *
+ * int TclMin(int i, int j);
+ * int TclMax(int i, int j);
+ */
+
+#define TclMin(i, j)	((((int) i) < ((int) j))? (i) : (j))
+#define TclMax(i, j)	((((int) i) > ((int) j))? (i) : (j))
+
+/*
+ * Convenience macros for use when compiling bodies of commands. The ANSI C
+ * "prototype" for these macros are:
+ *
+ * static void		BODY(Tcl_Token *tokenPtr, int word);
+ */
+
+#define BODY(tokenPtr, word)						\
+    SetLineInformation((word));						\
+    TclCompileCmdWord(interp, (tokenPtr)+1, (tokenPtr)->numComponents,	\
+	    envPtr)
+
+/*
+ * Convenience macro for use when compiling tokens to be pushed. The ANSI C
+ * "prototype" for this macro is:
+ *
+ * static void		CompileTokens(CompileEnv *envPtr, Tcl_Token *tokenPtr,
+ *			    Tcl_Interp *interp);
+ */
+
+#define CompileTokens(envPtr, tokenPtr, interp) \
+    TclCompileTokens((interp), (tokenPtr)+1, (tokenPtr)->numComponents, \
+	    (envPtr));
+/*
+ * Convenience macros for use when pushing literals. The ANSI C "prototype" for
+ * these macros are:
+ *
+ * static void		PushLiteral(CompileEnv *envPtr,
+ *			    const char *string, int length);
+ * static void		PushStringLiteral(CompileEnv *envPtr,
+ *			    const char *string);
+ */
+
+#define PushLiteral(envPtr, string, length) \
+    TclEmitPush(TclRegisterNewLiteral((envPtr), (string), (length)), (envPtr))
+#define PushStringLiteral(envPtr, string) \
+    PushLiteral((envPtr), (string), (int) (sizeof(string "") - 1))
+
+/*
+ * Macro to advance to the next token; it is more mnemonic than the address
+ * arithmetic that it replaces. The ANSI C "prototype" for this macro is:
+ *
+ * static Tcl_Token *	TokenAfter(Tcl_Token *tokenPtr);
+ */
+
+#define TokenAfter(tokenPtr) \
+    ((tokenPtr) + ((tokenPtr)->numComponents + 1))
+
+/*
+ * Macro to get the offset to the next instruction to be issued. The ANSI C
+ * "prototype" for this macro is:
+ *
+ * static int	CurrentOffset(CompileEnv *envPtr);
+ */
+
+#define CurrentOffset(envPtr) \
+    ((envPtr)->codeNext - (envPtr)->codeStart)
+
+/*
+ * Note: the exceptDepth is a bit of a misnomer: TEBC only needs the
+ * maximal depth of nested CATCH ranges in order to alloc runtime
+ * memory. These macros should compute precisely that? OTOH, the nesting depth
+ * of LOOP ranges is an interesting datum for debugging purposes, and that is
+ * what we compute now.
+ *
+ * static int	ExceptionRangeStarts(CompileEnv *envPtr, int index);
+ * static void	ExceptionRangeEnds(CompileEnv *envPtr, int index);
+ * static void	ExceptionRangeTarget(CompileEnv *envPtr, int index, LABEL);
+ */
+
+#define ExceptionRangeStarts(envPtr, index) \
+    (((envPtr)->exceptDepth++),						\
+    ((envPtr)->maxExceptDepth =						\
+	    TclMax((envPtr)->exceptDepth, (envPtr)->maxExceptDepth)),	\
+    ((envPtr)->exceptArrayPtr[(index)].codeOffset = CurrentOffset(envPtr)))
+#define ExceptionRangeEnds(envPtr, index) \
+    (((envPtr)->exceptDepth--),						\
+    ((envPtr)->exceptArrayPtr[(index)].numCodeBytes =			\
+	CurrentOffset(envPtr) - (envPtr)->exceptArrayPtr[(index)].codeOffset))
+#define ExceptionRangeTarget(envPtr, index, targetType) \
+    ((envPtr)->exceptArrayPtr[(index)].targetType = CurrentOffset(envPtr))
+
+/*
+ * Check if there is an LVT for compiled locals
+ */
+
+#define EnvHasLVT(envPtr) \
+    (envPtr->procPtr || envPtr->iPtr->varFramePtr->localCachePtr)
+
+/*
+ * Macros for making it easier to deal with tokens and DStrings.
+ */
+
+#define TclDStringAppendToken(dsPtr, tokenPtr) \
+    Tcl_DStringAppend((dsPtr), (tokenPtr)->start, (tokenPtr)->size)
+#define TclRegisterDStringLiteral(envPtr, dsPtr) \
+    TclRegisterLiteral(envPtr, Tcl_DStringValue(dsPtr), \
+	    Tcl_DStringLength(dsPtr), /*flags*/ 0)
+
+/*
+ * Macro that encapsulates an efficiency trick that avoids a function call for
+ * the simplest of compiles. The ANSI C "prototype" for this macro is:
+ *
+ * static void		CompileWord(CompileEnv *envPtr, Tcl_Token *tokenPtr,
+ *			    Tcl_Interp *interp, int word);
+ */
+
+#define CompileWord(envPtr, tokenPtr, interp, word) \
+    if ((tokenPtr)->type == TCL_TOKEN_SIMPLE_WORD) {			\
+	PushLiteral((envPtr), (tokenPtr)[1].start, (tokenPtr)[1].size);	\
+    } else {								\
+	SetLineInformation((word));					\
+	CompileTokens((envPtr), (tokenPtr), (interp));			\
+    }
+
+/*
+ * TIP #280: Remember the per-word line information of the current command. An
+ * index is used instead of a pointer as recursive compilation may reallocate,
+ * i.e. move, the array. This is also the reason to save the nuloc now, it may
+ * change during the course of the function.
+ *
+ * Macro to encapsulate the variable definition and setup.
+ */
+
+#define DefineLineInformation \
+    ExtCmdLoc *mapPtr = envPtr->extCmdMapPtr;				\
+    int eclIndex = mapPtr->nuloc - 1
+
+#define SetLineInformation(word) \
+    envPtr->line = mapPtr->loc[eclIndex].line[(word)];			\
+    envPtr->clNext = mapPtr->loc[eclIndex].next[(word)]
+
+#define PushVarNameWord(i,v,e,f,l,sc,word) \
+    SetLineInformation(word);						\
+    TclPushVarName(i,v,e,f,l,sc)
+
+/*
+ * Often want to issue one of two versions of an instruction based on whether
+ * the argument will fit in a single byte or not. This makes it much clearer.
+ */
+
+#define Emit14Inst(nm,idx,envPtr) \
+    if (idx <= 255) {							\
+	TclEmitInstInt1(nm##1,idx,envPtr);				\
+    } else {								\
+	TclEmitInstInt4(nm##4,idx,envPtr);				\
+    }
+
+/*
+ * How to get an anonymous local variable (used for holding temporary values
+ * off the stack) or a local simple scalar.
+ */
+
+#define AnonymousLocal(envPtr) \
+    (TclFindCompiledLocal(NULL, /*nameChars*/ 0, /*create*/ 1, (envPtr)))
+#define LocalScalar(chars,len,envPtr) \
+    TclLocalScalar(chars, len, envPtr)
+#define LocalScalarFromToken(tokenPtr,envPtr) \
+    TclLocalScalarFromToken(tokenPtr, envPtr)
+
+/*
+ * Flags bits used by TclPushVarName.
+ */
+
+#define TCL_NO_LARGE_INDEX 1	/* Do not return localIndex value > 255 */
+#define TCL_NO_ELEMENT 2	/* Do not push the array element. */
+
+/*
+ * DTrace probe macros (NOPs if DTrace support is not enabled).
+ */
+
+/*
+ * Define the following macros to enable debug logging of the DTrace proc,
+ * cmd, and inst probes. Note that this does _not_ require a platform with
+ * DTrace, it simply logs all probe output to /tmp/tclDTraceDebug-[pid].log.
+ *
+ * If the second macro is defined, logging to file starts immediately,
+ * otherwise only after the first call to [tcl::dtrace]. Note that the debug
+ * probe data is always computed, even when it is not logged to file.
+ *
+ * Defining the third macro enables debug logging of inst probes (disabled
+ * by default due to the significant performance impact).
+ */
+
+/*
+#define TCL_DTRACE_DEBUG 1
+#define TCL_DTRACE_DEBUG_LOG_ENABLED 1
+#define TCL_DTRACE_DEBUG_INST_PROBES 1
+*/
+
+#if !(defined(TCL_DTRACE_DEBUG) && defined(__GNUC__))
+
+#ifdef USE_DTRACE
+
+#if defined(__GNUC__) && __GNUC__ > 2
+/*
+ * Use gcc branch prediction hint to minimize cost of DTrace ENABLED checks.
+ */
+#define unlikely(x) (__builtin_expect((x), 0))
+#else
+#define unlikely(x) (x)
+#endif
+
+#define TCL_DTRACE_PROC_ENTRY_ENABLED()	    unlikely(TCL_PROC_ENTRY_ENABLED())
+#define TCL_DTRACE_PROC_RETURN_ENABLED()    unlikely(TCL_PROC_RETURN_ENABLED())
+#define TCL_DTRACE_PROC_RESULT_ENABLED()    unlikely(TCL_PROC_RESULT_ENABLED())
+#define TCL_DTRACE_PROC_ARGS_ENABLED()	    unlikely(TCL_PROC_ARGS_ENABLED())
+#define TCL_DTRACE_PROC_INFO_ENABLED()	    unlikely(TCL_PROC_INFO_ENABLED())
+#define TCL_DTRACE_PROC_ENTRY(a0, a1, a2)   TCL_PROC_ENTRY(a0, a1, a2)
+#define TCL_DTRACE_PROC_RETURN(a0, a1)	    TCL_PROC_RETURN(a0, a1)
+#define TCL_DTRACE_PROC_RESULT(a0, a1, a2, a3) TCL_PROC_RESULT(a0, a1, a2, a3)
+#define TCL_DTRACE_PROC_ARGS(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9) \
+	TCL_PROC_ARGS(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)
+#define TCL_DTRACE_PROC_INFO(a0, a1, a2, a3, a4, a5, a6, a7) \
+	TCL_PROC_INFO(a0, a1, a2, a3, a4, a5, a6, a7)
+
+#define TCL_DTRACE_CMD_ENTRY_ENABLED()	    unlikely(TCL_CMD_ENTRY_ENABLED())
+#define TCL_DTRACE_CMD_RETURN_ENABLED()	    unlikely(TCL_CMD_RETURN_ENABLED())
+#define TCL_DTRACE_CMD_RESULT_ENABLED()	    unlikely(TCL_CMD_RESULT_ENABLED())
+#define TCL_DTRACE_CMD_ARGS_ENABLED()	    unlikely(TCL_CMD_ARGS_ENABLED())
+#define TCL_DTRACE_CMD_INFO_ENABLED()	    unlikely(TCL_CMD_INFO_ENABLED())
+#define TCL_DTRACE_CMD_ENTRY(a0, a1, a2)    TCL_CMD_ENTRY(a0, a1, a2)
+#define TCL_DTRACE_CMD_RETURN(a0, a1)	    TCL_CMD_RETURN(a0, a1)
+#define TCL_DTRACE_CMD_RESULT(a0, a1, a2, a3) TCL_CMD_RESULT(a0, a1, a2, a3)
+#define TCL_DTRACE_CMD_ARGS(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9) \
+	TCL_CMD_ARGS(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)
+#define TCL_DTRACE_CMD_INFO(a0, a1, a2, a3, a4, a5, a6, a7) \
+	TCL_CMD_INFO(a0, a1, a2, a3, a4, a5, a6, a7)
+
+#define TCL_DTRACE_INST_START_ENABLED()	    unlikely(TCL_INST_START_ENABLED())
+#define TCL_DTRACE_INST_DONE_ENABLED()	    unlikely(TCL_INST_DONE_ENABLED())
+#define TCL_DTRACE_INST_START(a0, a1, a2)   TCL_INST_START(a0, a1, a2)
+#define TCL_DTRACE_INST_DONE(a0, a1, a2)    TCL_INST_DONE(a0, a1, a2)
+
+#define TCL_DTRACE_TCL_PROBE_ENABLED()	    unlikely(TCL_TCL_PROBE_ENABLED())
+#define TCL_DTRACE_TCL_PROBE(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9) \
+	TCL_TCL_PROBE(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)
+
+#define TCL_DTRACE_DEBUG_LOG()
+
+MODULE_SCOPE void	TclDTraceInfo(Tcl_Obj *info, const char **args,
+			    int *argsi);
+
+#else /* USE_DTRACE */
+
+#define TCL_DTRACE_PROC_ENTRY_ENABLED()	    0
+#define TCL_DTRACE_PROC_RETURN_ENABLED()    0
+#define TCL_DTRACE_PROC_RESULT_ENABLED()    0
+#define TCL_DTRACE_PROC_ARGS_ENABLED()	    0
+#define TCL_DTRACE_PROC_INFO_ENABLED()	    0
+#define TCL_DTRACE_PROC_ENTRY(a0, a1, a2)   {if (a0) {}}
+#define TCL_DTRACE_PROC_RETURN(a0, a1)	    {if (a0) {}}
+#define TCL_DTRACE_PROC_RESULT(a0, a1, a2, a3) {if (a0) {}; if (a3) {}}
+#define TCL_DTRACE_PROC_ARGS(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9) {}
+#define TCL_DTRACE_PROC_INFO(a0, a1, a2, a3, a4, a5, a6, a7) {}
+
+#define TCL_DTRACE_CMD_ENTRY_ENABLED()	    0
+#define TCL_DTRACE_CMD_RETURN_ENABLED()	    0
+#define TCL_DTRACE_CMD_RESULT_ENABLED()	    0
+#define TCL_DTRACE_CMD_ARGS_ENABLED()	    0
+#define TCL_DTRACE_CMD_INFO_ENABLED()	    0
+#define TCL_DTRACE_CMD_ENTRY(a0, a1, a2)    {}
+#define TCL_DTRACE_CMD_RETURN(a0, a1)	    {}
+#define TCL_DTRACE_CMD_RESULT(a0, a1, a2, a3) {}
+#define TCL_DTRACE_CMD_ARGS(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9) {}
+#define TCL_DTRACE_CMD_INFO(a0, a1, a2, a3, a4, a5, a6, a7) {}
+
+#define TCL_DTRACE_INST_START_ENABLED()	    0
+#define TCL_DTRACE_INST_DONE_ENABLED()	    0
+#define TCL_DTRACE_INST_START(a0, a1, a2)   {}
+#define TCL_DTRACE_INST_DONE(a0, a1, a2)    {}
+
+#define TCL_DTRACE_TCL_PROBE_ENABLED()	    0
+#define TCL_DTRACE_TCL_PROBE(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9) {}
+
+#define TclDTraceInfo(info, args, argsi)    {*args = ""; *argsi = 0;}
+
+#endif /* USE_DTRACE */
+
+#else /* TCL_DTRACE_DEBUG */
+
+#define USE_DTRACE 1
+
+#if !defined(TCL_DTRACE_DEBUG_LOG_ENABLED) || !(TCL_DTRACE_DEBUG_LOG_ENABLED)
+#undef TCL_DTRACE_DEBUG_LOG_ENABLED
+#define TCL_DTRACE_DEBUG_LOG_ENABLED 0
+#endif
+
+#if !defined(TCL_DTRACE_DEBUG_INST_PROBES) || !(TCL_DTRACE_DEBUG_INST_PROBES)
+#undef TCL_DTRACE_DEBUG_INST_PROBES
+#define TCL_DTRACE_DEBUG_INST_PROBES 0
+#endif
+
+MODULE_SCOPE int tclDTraceDebugEnabled, tclDTraceDebugIndent;
+MODULE_SCOPE FILE *tclDTraceDebugLog;
+MODULE_SCOPE void TclDTraceOpenDebugLog(void);
+MODULE_SCOPE void TclDTraceInfo(Tcl_Obj *info, const char **args, int *argsi);
+
+#define TCL_DTRACE_DEBUG_LOG() \
+    int tclDTraceDebugEnabled = TCL_DTRACE_DEBUG_LOG_ENABLED;	\
+    int tclDTraceDebugIndent = 0;				\
+    FILE *tclDTraceDebugLog = NULL;				\
+    void TclDTraceOpenDebugLog(void) {				\
+	char n[35];						\
+	sprintf(n, "/tmp/tclDTraceDebug-%lu.log",		\
+		(unsigned long) getpid());			\
+	tclDTraceDebugLog = fopen(n, "a");			\
+    }
+
+#define TclDTraceDbgMsg(p, m, ...) \
+    do {								\
+	if (tclDTraceDebugEnabled) {					\
+	    int _l, _t = 0;						\
+	    if (!tclDTraceDebugLog) { TclDTraceOpenDebugLog(); }	\
+	    fprintf(tclDTraceDebugLog, "%.12s:%.4d:%n",			\
+		    strrchr(__FILE__, '/')+1, __LINE__, &_l); _t += _l; \
+	    fprintf(tclDTraceDebugLog, " %.*s():%n",			\
+		    (_t < 18 ? 18 - _t : 0) + 18, __func__, &_l); _t += _l; \
+	    fprintf(tclDTraceDebugLog, "%*s" p "%n",			\
+		    (_t < 40 ? 40 - _t : 0) + 2 * tclDTraceDebugIndent, \
+		    "", &_l); _t += _l;					\
+	    fprintf(tclDTraceDebugLog, "%*s" m "\n",			\
+		    (_t < 64 ? 64 - _t : 1), "", ##__VA_ARGS__);	\
+	    fflush(tclDTraceDebugLog);					\
+	}								\
+    } while (0)
+
+#define TCL_DTRACE_PROC_ENTRY_ENABLED()	    1
+#define TCL_DTRACE_PROC_RETURN_ENABLED()    1
+#define TCL_DTRACE_PROC_RESULT_ENABLED()    1
+#define TCL_DTRACE_PROC_ARGS_ENABLED()	    1
+#define TCL_DTRACE_PROC_INFO_ENABLED()	    1
+#define TCL_DTRACE_PROC_ENTRY(a0, a1, a2) \
+	tclDTraceDebugIndent++; \
+	TclDTraceDbgMsg("-> proc-entry", "%s %d %p", a0, a1, a2)
+#define TCL_DTRACE_PROC_RETURN(a0, a1) \
+	TclDTraceDbgMsg("<- proc-return", "%s %d", a0, a1); \
+	tclDTraceDebugIndent--
+#define TCL_DTRACE_PROC_RESULT(a0, a1, a2, a3) \
+	TclDTraceDbgMsg(" | proc-result", "%s %d %s %p", a0, a1, a2, a3)
+#define TCL_DTRACE_PROC_ARGS(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9) \
+	TclDTraceDbgMsg(" | proc-args", "%s %s %s %s %s %s %s %s %s %s", a0, \
+		a1, a2, a3, a4, a5, a6, a7, a8, a9)
+#define TCL_DTRACE_PROC_INFO(a0, a1, a2, a3, a4, a5, a6, a7) \
+	TclDTraceDbgMsg(" | proc-info", "%s %s %s %s %d %d %s %s", a0, a1, \
+		a2, a3, a4, a5, a6, a7)
+
+#define TCL_DTRACE_CMD_ENTRY_ENABLED()	    1
+#define TCL_DTRACE_CMD_RETURN_ENABLED()	    1
+#define TCL_DTRACE_CMD_RESULT_ENABLED()	    1
+#define TCL_DTRACE_CMD_ARGS_ENABLED()	    1
+#define TCL_DTRACE_CMD_INFO_ENABLED()	    1
+#define TCL_DTRACE_CMD_ENTRY(a0, a1, a2) \
+	tclDTraceDebugIndent++; \
+	TclDTraceDbgMsg("-> cmd-entry", "%s %d %p", a0, a1, a2)
+#define TCL_DTRACE_CMD_RETURN(a0, a1) \
+	TclDTraceDbgMsg("<- cmd-return", "%s %d", a0, a1); \
+	tclDTraceDebugIndent--
+#define TCL_DTRACE_CMD_RESULT(a0, a1, a2, a3) \
+	TclDTraceDbgMsg(" | cmd-result", "%s %d %s %p", a0, a1, a2, a3)
+#define TCL_DTRACE_CMD_ARGS(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9) \
+	TclDTraceDbgMsg(" | cmd-args", "%s %s %s %s %s %s %s %s %s %s", a0, \
+		a1, a2, a3, a4, a5, a6, a7, a8, a9)
+#define TCL_DTRACE_CMD_INFO(a0, a1, a2, a3, a4, a5, a6, a7) \
+	TclDTraceDbgMsg(" | cmd-info", "%s %s %s %s %d %d %s %s", a0, a1, \
+		a2, a3, a4, a5, a6, a7)
+
+#define TCL_DTRACE_INST_START_ENABLED()	    TCL_DTRACE_DEBUG_INST_PROBES
+#define TCL_DTRACE_INST_DONE_ENABLED()	    TCL_DTRACE_DEBUG_INST_PROBES
+#define TCL_DTRACE_INST_START(a0, a1, a2) \
+	TclDTraceDbgMsg(" | inst-start", "%s %d %p", a0, a1, a2)
+#define TCL_DTRACE_INST_DONE(a0, a1, a2) \
+	TclDTraceDbgMsg(" | inst-end", "%s %d %p", a0, a1, a2)
+
+#define TCL_DTRACE_TCL_PROBE_ENABLED()	    1
+#define TCL_DTRACE_TCL_PROBE(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9) \
+    do {								\
+	tclDTraceDebugEnabled = 1;					\
+	TclDTraceDbgMsg(" | tcl-probe", "%s %s %s %s %s %s %s %s %s %s", a0, \
+		a1, a2, a3, a4, a5, a6, a7, a8, a9);			\
+    } while (0)
+
+#endif /* TCL_DTRACE_DEBUG */
+
+#endif /* _TCLCOMPILATION */
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tclConfig.c b/generic/tclConfig.c
new file mode 100644
index 0000000..2fb3e92
--- /dev/null
+++ b/generic/tclConfig.c
@@ -0,0 +1,408 @@
+/*
+ * tclConfig.c --
+ *
+ *	This file provides the facilities which allow Tcl and other packages
+ *	to embed configuration information into their binary libraries.
+ *
+ * Copyright (c) 2002 Andreas Kupries <andreas_kupries@users.sourceforge.net>
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#include "tclInt.h"
+
+/*
+ * Internal structure to hold embedded configuration information.
+ *
+ * Our structure is a two-level dictionary associated with the 'interp'. The
+ * first level is keyed with the package name and maps to the dictionary for
+ * that package. The package dictionary is keyed with metadata keys and maps
+ * to the metadata value for that key. This is package specific. The metadata
+ * values are in UTF-8, converted from the external representation given to us
+ * by the caller.
+ */
+
+#define ASSOC_KEY	"tclPackageAboutDict"
+
+/*
+ * A ClientData struct for the QueryConfig command.  Store the three bits
+ * of data we need; the package name for which we store a config dict,
+ * the (Tcl_Interp *) in which it is stored, and the encoding.
+ */
+
+typedef struct QCCD {
+    Tcl_Obj *pkg;
+    Tcl_Interp *interp;
+    char *encoding;
+} QCCD;
+
+/*
+ * Static functions in this file:
+ */
+
+static int		QueryConfigObjCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    struct Tcl_Obj *const *objv);
+static void		QueryConfigDelete(ClientData clientData);
+static Tcl_Obj *	GetConfigDict(Tcl_Interp *interp);
+static void		ConfigDictDeleteProc(ClientData clientData,
+			    Tcl_Interp *interp);
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_RegisterConfig --
+ *
+ *	See TIP#59 for details on what this function does.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Creates namespace and cfg query command in it as per TIP #59.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_RegisterConfig(
+    Tcl_Interp *interp,		/* Interpreter the configuration command is
+				 * registered in. */
+    const char *pkgName,	/* Name of the package registering the
+				 * embedded configuration. ASCII, thus in
+				 * UTF-8 too. */
+    const Tcl_Config *configuration,	/* Embedded configuration. */
+    const char *valEncoding)	/* Name of the encoding used to store the
+				 * configuration values, ASCII, thus UTF-8. */
+{
+    Tcl_Obj *pDB, *pkgDict;
+    Tcl_DString cmdName;
+    const Tcl_Config *cfg;
+    QCCD *cdPtr = ckalloc(sizeof(QCCD));
+
+    cdPtr->interp = interp;
+    if (valEncoding) {
+	cdPtr->encoding = ckalloc(strlen(valEncoding)+1);
+	strcpy(cdPtr->encoding, valEncoding);
+    } else {
+	cdPtr->encoding = NULL;
+    }
+    cdPtr->pkg = Tcl_NewStringObj(pkgName, -1);
+
+    /*
+     * Phase I: Adding the provided information to the internal database of
+     * package meta data.
+     *
+     * Phase II: Create a command for querying this database, specific to the
+     * package registering its configuration. This is the approved interface
+     * in TIP 59. In the future a more general interface should be done, as
+     * follow-up to TIP 59. Simply because our database is now general across
+     * packages, and not a structure tied to one package.
+     *
+     * Note, the created command will have a reference through its clientdata.
+     */
+
+    Tcl_IncrRefCount(cdPtr->pkg);
+
+    /*
+     * For venc == NULL aka bogus encoding we skip the step setting up the
+     * dictionaries visible at Tcl level. I.e. they are not filled
+     */
+
+    pDB = GetConfigDict(interp);
+
+    /*
+     * Retrieve package specific configuration...
+     */
+
+    if (Tcl_DictObjGet(interp, pDB, cdPtr->pkg, &pkgDict) != TCL_OK
+	    || (pkgDict == NULL)) {
+	pkgDict = Tcl_NewDictObj();
+    } else if (Tcl_IsShared(pkgDict)) {
+	pkgDict = Tcl_DuplicateObj(pkgDict);
+    }
+
+    /*
+     * Extend the package configuration...
+     * We cannot assume that the encodings are initialized, therefore
+     * store the value as-is in a byte array. See Bug [9b2e636361].
+     */
+
+    for (cfg=configuration ; cfg->key!=NULL && cfg->key[0]!='\0' ; cfg++) {
+	Tcl_DictObjPut(interp, pkgDict, Tcl_NewStringObj(cfg->key, -1),
+		Tcl_NewByteArrayObj((unsigned char *)cfg->value, strlen(cfg->value)));
+    }
+
+    /*
+     * Write the changes back into the overall database.
+     */
+
+    Tcl_DictObjPut(interp, pDB, cdPtr->pkg, pkgDict);
+
+    /*
+     * Now create the interface command for retrieval of the package
+     * information.
+     */
+
+    Tcl_DStringInit(&cmdName);
+    TclDStringAppendLiteral(&cmdName, "::");
+    Tcl_DStringAppend(&cmdName, pkgName, -1);
+
+    /*
+     * The incomplete command name is the name of the namespace to place it
+     * in.
+     */
+
+    if (Tcl_FindNamespace(interp, Tcl_DStringValue(&cmdName), NULL,
+	    TCL_GLOBAL_ONLY) == NULL) {
+	if (Tcl_CreateNamespace(interp, Tcl_DStringValue(&cmdName),
+		NULL, NULL) == NULL) {
+	    Tcl_Panic("%s.\n%s: %s",
+		    Tcl_GetStringResult(interp), "Tcl_RegisterConfig",
+		    "Unable to create namespace for package configuration.");
+	}
+    }
+
+    TclDStringAppendLiteral(&cmdName, "::pkgconfig");
+
+    if (Tcl_CreateObjCommand(interp, Tcl_DStringValue(&cmdName),
+	    QueryConfigObjCmd, cdPtr, QueryConfigDelete) == NULL) {
+	Tcl_Panic("%s: %s", "Tcl_RegisterConfig",
+		"Unable to create query command for package configuration");
+    }
+
+    Tcl_DStringFree(&cmdName);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * QueryConfigObjCmd --
+ *
+ *	Implementation of "::<package>::pkgconfig", the command to query
+ *	configuration information embedded into a binary library.
+ *
+ * Results:
+ *	A standard tcl result.
+ *
+ * Side effects:
+ *	See the manual for what this command does.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+QueryConfigObjCmd(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int objc,
+    struct Tcl_Obj *const *objv)
+{
+    QCCD *cdPtr = clientData;
+    Tcl_Obj *pkgName = cdPtr->pkg;
+    Tcl_Obj *pDB, *pkgDict, *val, *listPtr;
+    int n, index;
+    static const char *const subcmdStrings[] = {
+	"get", "list", NULL
+    };
+    enum subcmds {
+	CFG_GET, CFG_LIST
+    };
+    Tcl_DString conv;
+    Tcl_Encoding venc = NULL;
+    const char *value;
+
+    if ((objc < 2) || (objc > 3)) {
+	Tcl_WrongNumArgs(interp, 1, objv, "subcommand ?arg?");
+	return TCL_ERROR;
+    }
+    if (Tcl_GetIndexFromObj(interp, objv[1], subcmdStrings, "subcommand", 0,
+	    &index) != TCL_OK) {
+	return TCL_ERROR;
+    }
+
+    pDB = GetConfigDict(interp);
+    if (Tcl_DictObjGet(interp, pDB, pkgName, &pkgDict) != TCL_OK
+	    || pkgDict == NULL) {
+	/*
+	 * Maybe a Tcl_Panic is better, because the package data has to be
+	 * present.
+	 */
+
+	Tcl_SetObjResult(interp, Tcl_NewStringObj("package not known", -1));
+	Tcl_SetErrorCode(interp, "TCL", "FATAL", "PKGCFG_BASE",
+		Tcl_GetString(pkgName), NULL);
+	return TCL_ERROR;
+    }
+
+    switch ((enum subcmds) index) {
+    case CFG_GET:
+	if (objc != 3) {
+	    Tcl_WrongNumArgs(interp, 2, objv, "key");
+	    return TCL_ERROR;
+	}
+
+	if (Tcl_DictObjGet(interp, pkgDict, objv[2], &val) != TCL_OK
+		|| val == NULL) {
+	    Tcl_SetObjResult(interp, Tcl_NewStringObj("key not known", -1));
+	    Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "CONFIG",
+		    Tcl_GetString(objv[2]), NULL);
+	    return TCL_ERROR;
+	}
+
+	if (cdPtr->encoding) {
+	    venc = Tcl_GetEncoding(interp, cdPtr->encoding);
+	    if (!venc) {
+		return TCL_ERROR;
+	    }
+	}
+	/*
+	 * Value is stored as-is in a byte array, see Bug [9b2e636361],
+	 * so we have to decode it first.
+	 */
+	value = (const char *) Tcl_GetByteArrayFromObj(val, &n);
+	value = Tcl_ExternalToUtfDString(venc, value, n, &conv);
+	Tcl_SetObjResult(interp, Tcl_NewStringObj(value,
+		Tcl_DStringLength(&conv)));
+	Tcl_DStringFree(&conv);
+	return TCL_OK;
+
+    case CFG_LIST:
+	if (objc != 2) {
+	    Tcl_WrongNumArgs(interp, 2, objv, NULL);
+	    return TCL_ERROR;
+	}
+
+	Tcl_DictObjSize(interp, pkgDict, &n);
+	listPtr = Tcl_NewListObj(n, NULL);
+
+	if (!listPtr) {
+	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		    "insufficient memory to create list", -1));
+	    Tcl_SetErrorCode(interp, "TCL", "MEMORY", NULL);
+	    return TCL_ERROR;
+	}
+
+	if (n) {
+	    Tcl_DictSearch s;
+	    Tcl_Obj *key;
+	    int done;
+
+	    for (Tcl_DictObjFirst(interp, pkgDict, &s, &key, NULL, &done);
+		    !done; Tcl_DictObjNext(&s, &key, NULL, &done)) {
+		Tcl_ListObjAppendElement(NULL, listPtr, key);
+	    }
+	}
+
+	Tcl_SetObjResult(interp, listPtr);
+	return TCL_OK;
+
+    default:
+	Tcl_Panic("QueryConfigObjCmd: Unknown subcommand to 'pkgconfig'. This can't happen");
+	break;
+    }
+    return TCL_ERROR;
+}
+
+/*
+ *-------------------------------------------------------------------------
+ *
+ * QueryConfigDelete --
+ *
+ *	Command delete function. Cleans up after the configuration query
+ *	command when it is deleted by the user or during finalization.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Deallocates all non-transient memory allocated by Tcl_RegisterConfig.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+static void
+QueryConfigDelete(
+    ClientData clientData)
+{
+    QCCD *cdPtr = clientData;
+    Tcl_Obj *pkgName = cdPtr->pkg;
+    Tcl_Obj *pDB = GetConfigDict(cdPtr->interp);
+
+    Tcl_DictObjRemove(NULL, pDB, pkgName);
+    Tcl_DecrRefCount(pkgName);
+    if (cdPtr->encoding) {
+	ckfree((char *)cdPtr->encoding);
+    }
+    ckfree((char *)cdPtr);
+}
+
+/*
+ *-------------------------------------------------------------------------
+ *
+ * GetConfigDict --
+ *
+ *	Retrieve the package metadata database from the interpreter.
+ *	Initializes it, if not present yet.
+ *
+ * Results:
+ *	A Tcl_Obj reference
+ *
+ * Side effects:
+ *	May allocate a Tcl_Obj.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+static Tcl_Obj *
+GetConfigDict(
+    Tcl_Interp *interp)
+{
+    Tcl_Obj *pDB = Tcl_GetAssocData(interp, ASSOC_KEY, NULL);
+
+    if (pDB == NULL) {
+	pDB = Tcl_NewDictObj();
+	Tcl_IncrRefCount(pDB);
+	Tcl_SetAssocData(interp, ASSOC_KEY, ConfigDictDeleteProc, pDB);
+    }
+
+    return pDB;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ConfigDictDeleteProc --
+ *
+ *	This function is associated with the "Package About dict" assoc data
+ *	for an interpreter; it is invoked when the interpreter is deleted in
+ *	order to free the information associated with any pending error
+ *	reports.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The package metadata database is freed.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+ConfigDictDeleteProc(
+    ClientData clientData,	/* Pointer to Tcl_Obj. */
+    Tcl_Interp *interp)		/* Interpreter being deleted. */
+{
+    Tcl_Obj *pDB = clientData;
+
+    Tcl_DecrRefCount(pDB);
+}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tclDTrace.d b/generic/tclDTrace.d
new file mode 100644
index 0000000..360bdff
--- /dev/null
+++ b/generic/tclDTrace.d
@@ -0,0 +1,225 @@
+/*
+ * tclDTrace.d --
+ *
+ *	Tcl DTrace provider.
+ *
+ * Copyright (c) 2007-2008 Daniel A. Steffen <das@users.sourceforge.net>
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+typedef struct Tcl_Obj Tcl_Obj;
+typedef const char* TclDTraceStr;
+
+/*
+ * Tcl DTrace probes
+ */
+
+provider tcl {
+    /***************************** proc probes *****************************/
+    /*
+     *	tcl*:::proc-entry probe
+     *	    triggered immediately before proc bytecode execution
+     *		arg0: proc name				(string)
+     *		arg1: number of arguments		(int)
+     *		arg2: array of proc argument objects	(Tcl_Obj**)
+     */
+    probe proc__entry(TclDTraceStr name, int objc, struct Tcl_Obj **objv);
+    /*
+     *	tcl*:::proc-return probe
+     *	    triggered immediately after proc bytecode execution
+     *		arg0: proc name				(string)
+     *		arg1: return code			(int)
+     */
+    probe proc__return(TclDTraceStr name, int code);
+    /*
+     *	tcl*:::proc-result probe
+     *	    triggered after proc-return probe and result processing
+     *		arg0: proc name				(string)
+     *		arg1: return code			(int)
+     *		arg2: proc result			(string)
+     *		arg3: proc result object		(Tcl_Obj*)
+     */
+    probe proc__result(TclDTraceStr name, int code, TclDTraceStr result,
+	    struct Tcl_Obj *resultobj);
+    /*
+     *	tcl*:::proc-args probe
+     *	    triggered before proc-entry probe, gives access to string
+     *	    representation of proc arguments
+     *		arg0: proc name				(string)
+     *		arg1-arg9: proc arguments or NULL	(strings)
+     */
+    probe proc__args(TclDTraceStr name, TclDTraceStr arg1, TclDTraceStr arg2,
+	    TclDTraceStr arg3, TclDTraceStr arg4, TclDTraceStr arg5,
+	    TclDTraceStr arg6, TclDTraceStr arg7, TclDTraceStr arg8,
+	    TclDTraceStr arg9);
+    /*
+     *	tcl*:::proc-info probe
+     *	    triggered before proc-entry probe, gives access to TIP 280
+     *	    information for the proc invocation (i.e. [info frame 0])
+     *		arg0: TIP 280 cmd			(string)
+     *		arg1: TIP 280 type			(string)
+     *		arg2: TIP 280 proc			(string)
+     *		arg3: TIP 280 file			(string)
+     *		arg4: TIP 280 line			(int)
+     *		arg5: TIP 280 level			(int)
+     *		arg6: TclOO method			(string)
+     *		arg7: TclOO class/object		(string)
+     */
+    probe proc__info(TclDTraceStr cmd, TclDTraceStr type, TclDTraceStr proc,
+	    TclDTraceStr file, int line, int level, TclDTraceStr method,
+	    TclDTraceStr class);
+
+    /***************************** cmd probes ******************************/
+    /*
+     *	tcl*:::cmd-entry probe
+     *	    triggered immediately before commmand execution
+     *		arg0: command name			(string)
+     *		arg1: number of arguments		(int)
+     *		arg2: array of command argument objects	(Tcl_Obj**)
+     */
+    probe cmd__entry(TclDTraceStr name, int objc, struct Tcl_Obj **objv);
+    /*
+     *	tcl*:::cmd-return probe
+     *	    triggered immediately after commmand execution
+     *		arg0: command name			(string)
+     *		arg1: return code			(int)
+     */
+    probe cmd__return(TclDTraceStr name, int code);
+    /*
+     *	tcl*:::cmd-result probe
+     *	    triggered after cmd-return probe and result processing
+     *		arg0: command name			(string)
+     *		arg1: return code			(int)
+     *		arg2: command result			(string)
+     *		arg3: command result object		(Tcl_Obj*)
+     */
+    probe cmd__result(TclDTraceStr name, int code, TclDTraceStr result,
+	    struct Tcl_Obj *resultobj);
+    /*
+     *	tcl*:::cmd-args probe
+     *	    triggered before cmd-entry probe, gives access to string
+     *	    representation of command arguments
+     *		arg0: command name			(string)
+     *		arg1-arg9: command arguments or NULL	(strings)
+     */
+    probe cmd__args(TclDTraceStr name, TclDTraceStr arg1, TclDTraceStr arg2,
+	    TclDTraceStr arg3, TclDTraceStr arg4, TclDTraceStr arg5,
+	    TclDTraceStr arg6, TclDTraceStr arg7, TclDTraceStr arg8,
+	    TclDTraceStr arg9);
+    /*
+     *	tcl*:::cmd-info probe
+     *	    triggered before cmd-entry probe, gives access to TIP 280
+     *	    information for the command invocation (i.e. [info frame 0])
+     *		arg0: TIP 280 cmd			(string)
+     *		arg1: TIP 280 type			(string)
+     *		arg2: TIP 280 proc			(string)
+     *		arg3: TIP 280 file			(string)
+     *		arg4: TIP 280 line			(int)
+     *		arg5: TIP 280 level			(int)
+     *		arg6: TclOO method			(string)
+     *		arg7: TclOO class/object		(string)
+     */
+    probe cmd__info(TclDTraceStr cmd, TclDTraceStr type, TclDTraceStr proc,
+	    TclDTraceStr file, int line, int level, TclDTraceStr method,
+	    TclDTraceStr class);
+
+    /***************************** inst probes *****************************/
+    /*
+     *	tcl*:::inst-start probe
+     *	    triggered immediately before execution of a bytecode
+     *		arg0: bytecode name			(string)
+     *		arg1: depth of stack			(int)
+     *		arg2: top of stack			(Tcl_Obj**)
+     */
+    probe inst__start(TclDTraceStr name, int depth, struct Tcl_Obj **stack);
+    /*
+     *	tcl*:::inst-done probe
+     *	    triggered immediately after execution of a bytecode
+     *		arg0: bytecode name			(string)
+     *		arg1: depth of stack			(int)
+     *		arg2: top of stack			(Tcl_Obj**)
+     */
+    probe inst__done(TclDTraceStr name, int depth, struct Tcl_Obj **stack);
+
+    /***************************** obj probes ******************************/
+    /*
+     *	tcl*:::obj-create probe
+     *	    triggered immediately after a new Tcl_Obj has been created
+     *		arg0: object created			(Tcl_Obj*)
+     */
+    probe obj__create(struct Tcl_Obj* obj);
+    /*
+     *	tcl*:::obj-free probe
+     *	    triggered immediately before a Tcl_Obj is freed
+     *		arg0: object to be freed		(Tcl_Obj*)
+     */
+    probe obj__free(struct Tcl_Obj* obj);
+
+    /***************************** tcl probes ******************************/
+    /*
+     *	tcl*:::tcl-probe probe
+     *	    triggered when the ::tcl::dtrace command is called
+     *		arg0-arg9: command arguments		(strings)
+     */
+    probe tcl__probe(TclDTraceStr arg0, TclDTraceStr arg1, TclDTraceStr arg2,
+	    TclDTraceStr arg3, TclDTraceStr arg4, TclDTraceStr arg5,
+	    TclDTraceStr arg6, TclDTraceStr arg7, TclDTraceStr arg8,
+	    TclDTraceStr arg9);
+};
+
+/*
+ * Tcl types and constants for use in DTrace scripts
+ */
+
+typedef struct Tcl_ObjType {
+    char *name;
+    void *freeIntRepProc;
+    void *dupIntRepProc;
+    void *updateStringProc;
+    void *setFromAnyProc;
+} Tcl_ObjType;
+
+struct Tcl_Obj {
+    int refCount;
+    char *bytes;
+    int length;
+    Tcl_ObjType *typePtr;
+    union {
+	long longValue;
+	double doubleValue;
+	void *otherValuePtr;
+	int64_t wideValue;
+	struct {
+	    void *ptr1;
+	    void *ptr2;
+	} twoPtrValue;
+	struct {
+	    void *ptr;
+	    unsigned long value;
+	} ptrAndLongRep;
+    } internalRep;
+};
+
+enum return_codes {
+    TCL_OK = 0,
+    TCL_ERROR,
+    TCL_RETURN,
+    TCL_BREAK,
+    TCL_CONTINUE
+};
+
+#pragma D attributes Evolving/Evolving/Common provider tcl provider
+#pragma D attributes Private/Private/Common provider tcl module
+#pragma D attributes Private/Private/Common provider tcl function
+#pragma D attributes Evolving/Evolving/Common provider tcl name
+#pragma D attributes Evolving/Evolving/Common provider tcl args
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tclDate.c b/generic/tclDate.c
new file mode 100644
index 0000000..e4dd000
--- /dev/null
+++ b/generic/tclDate.c
@@ -0,0 +1,2914 @@
+/* A Bison parser, made by GNU Bison 2.3.  */
+
+/* Skeleton implementation for Bison's Yacc-like parsers in C
+
+   Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+   Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor,
+   Boston, MA 02110-1301, USA.  */
+
+/* As a special exception, you may create a larger work that contains
+   part or all of the Bison parser skeleton and distribute that work
+   under terms of your choice, so long as that work isn't itself a
+   parser generator using the skeleton or a modified version thereof
+   as a parser skeleton.  Alternatively, if you modify or redistribute
+   the parser skeleton itself, you may (at your option) remove this
+   special exception, which will cause the skeleton and the resulting
+   Bison output files to be licensed under the GNU General Public
+   License without this special exception.
+
+   This special exception was added by the Free Software Foundation in
+   version 2.2 of Bison.  */
+
+/* C LALR(1) parser skeleton written by Richard Stallman, by
+   simplifying the original so-called "semantic" parser.  */
+
+/* All symbols defined below should begin with yy or YY, to avoid
+   infringing on user name space.  This should be done even for local
+   variables, as they might otherwise be expanded by user macros.
+   There are some unavoidable exceptions within include files to
+   define necessary library symbols; they are noted "INFRINGES ON
+   USER NAME SPACE" below.  */
+
+/* Identify Bison output.  */
+#define YYBISON 1
+
+/* Bison version.  */
+#define YYBISON_VERSION "2.3"
+
+/* Skeleton name.  */
+#define YYSKELETON_NAME "yacc.c"
+
+/* Pure parsers.  */
+#define YYPURE 1
+
+/* Using locations.  */
+#define YYLSP_NEEDED 1
+
+/* Substitute the variable and function names.  */
+#define yyparse TclDateparse
+#define yylex   TclDatelex
+#define yyerror TclDateerror
+#define yylval  TclDatelval
+#define yychar  TclDatechar
+#define yydebug TclDatedebug
+#define yynerrs TclDatenerrs
+#define yylloc TclDatelloc
+
+/* Tokens.  */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+   /* Put the tokens into the symbol table, so that GDB and other debuggers
+      know about them.  */
+   enum yytokentype {
+     tAGO = 258,
+     tDAY = 259,
+     tDAYZONE = 260,
+     tID = 261,
+     tMERIDIAN = 262,
+     tMONTH = 263,
+     tMONTH_UNIT = 264,
+     tSTARDATE = 265,
+     tSEC_UNIT = 266,
+     tSNUMBER = 267,
+     tUNUMBER = 268,
+     tZONE = 269,
+     tEPOCH = 270,
+     tDST = 271,
+     tISOBASE = 272,
+     tDAY_UNIT = 273,
+     tNEXT = 274
+   };
+#endif
+/* Tokens.  */
+#define tAGO 258
+#define tDAY 259
+#define tDAYZONE 260
+#define tID 261
+#define tMERIDIAN 262
+#define tMONTH 263
+#define tMONTH_UNIT 264
+#define tSTARDATE 265
+#define tSEC_UNIT 266
+#define tSNUMBER 267
+#define tUNUMBER 268
+#define tZONE 269
+#define tEPOCH 270
+#define tDST 271
+#define tISOBASE 272
+#define tDAY_UNIT 273
+#define tNEXT 274
+
+
+
+
+/* Copy the first part of user declarations.  */
+
+
+/*
+ * tclDate.c --
+ *
+ *	This file is generated from a yacc grammar defined in the file
+ *	tclGetDate.y. It should not be edited directly.
+ *
+ * Copyright (c) 1992-1995 Karl Lehenbauer and Mark Diekhans.
+ * Copyright (c) 1995-1997 Sun Microsystems, Inc.
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+#include "tclInt.h"
+
+/*
+ * Bison generates several labels that happen to be unused. MS Visual C++
+ * doesn't like that, and complains. Tell it to shut up.
+ */
+
+#ifdef _MSC_VER
+#pragma warning( disable : 4102 )
+#endif /* _MSC_VER */
+
+/*
+ * yyparse will accept a 'struct DateInfo' as its parameter; that's where the
+ * parsed fields will be returned.
+ */
+
+typedef struct DateInfo {
+
+    Tcl_Obj* messages;		/* Error messages */
+    const char* separatrix;	/* String separating messages */
+
+    time_t dateYear;
+    time_t dateMonth;
+    time_t dateDay;
+    int dateHaveDate;
+
+    time_t dateHour;
+    time_t dateMinutes;
+    time_t dateSeconds;
+    int dateMeridian;
+    int dateHaveTime;
+
+    time_t dateTimezone;
+    int dateDSTmode;
+    int dateHaveZone;
+
+    time_t dateRelMonth;
+    time_t dateRelDay;
+    time_t dateRelSeconds;
+    int dateHaveRel;
+
+    time_t dateMonthOrdinal;
+    int dateHaveOrdinalMonth;
+
+    time_t dateDayOrdinal;
+    time_t dateDayNumber;
+    int dateHaveDay;
+
+    const char *dateStart;
+    const char *dateInput;
+    time_t *dateRelPointer;
+
+    int dateDigitCount;
+} DateInfo;
+
+#define YYMALLOC	ckalloc
+#define YYFREE(x)	(ckfree((void*) (x)))
+
+#define yyDSTmode	(info->dateDSTmode)
+#define yyDayOrdinal	(info->dateDayOrdinal)
+#define yyDayNumber	(info->dateDayNumber)
+#define yyMonthOrdinal	(info->dateMonthOrdinal)
+#define yyHaveDate	(info->dateHaveDate)
+#define yyHaveDay	(info->dateHaveDay)
+#define yyHaveOrdinalMonth (info->dateHaveOrdinalMonth)
+#define yyHaveRel	(info->dateHaveRel)
+#define yyHaveTime	(info->dateHaveTime)
+#define yyHaveZone	(info->dateHaveZone)
+#define yyTimezone	(info->dateTimezone)
+#define yyDay		(info->dateDay)
+#define yyMonth		(info->dateMonth)
+#define yyYear		(info->dateYear)
+#define yyHour		(info->dateHour)
+#define yyMinutes	(info->dateMinutes)
+#define yySeconds	(info->dateSeconds)
+#define yyMeridian	(info->dateMeridian)
+#define yyRelMonth	(info->dateRelMonth)
+#define yyRelDay	(info->dateRelDay)
+#define yyRelSeconds	(info->dateRelSeconds)
+#define yyRelPointer	(info->dateRelPointer)
+#define yyInput		(info->dateInput)
+#define yyDigitCount	(info->dateDigitCount)
+
+#define EPOCH		1970
+#define START_OF_TIME	1902
+#define END_OF_TIME	2037
+
+/*
+ * The offset of tm_year of struct tm returned by localtime, gmtime, etc.
+ * Posix requires 1900.
+ */
+
+#define TM_YEAR_BASE	1900
+
+#define HOUR(x)		((int) (60 * x))
+#define SECSPERDAY	(24L * 60L * 60L)
+#define IsLeapYear(x)	((x % 4 == 0) && (x % 100 != 0 || x % 400 == 0))
+
+/*
+ * An entry in the lexical lookup table.
+ */
+
+typedef struct _TABLE {
+    const char *name;
+    int type;
+    time_t value;
+} TABLE;
+
+/*
+ * Daylight-savings mode: on, off, or not yet known.
+ */
+
+typedef enum _DSTMODE {
+    DSTon, DSToff, DSTmaybe
+} DSTMODE;
+
+/*
+ * Meridian: am, pm, or 24-hour style.
+ */
+
+typedef enum _MERIDIAN {
+    MERam, MERpm, MER24
+} MERIDIAN;
+
+
+
+/* Enabling traces.  */
+#ifndef YYDEBUG
+# define YYDEBUG 0
+#endif
+
+/* Enabling verbose error messages.  */
+#ifdef YYERROR_VERBOSE
+# undef YYERROR_VERBOSE
+# define YYERROR_VERBOSE 1
+#else
+# define YYERROR_VERBOSE 0
+#endif
+
+/* Enabling the token table.  */
+#ifndef YYTOKEN_TABLE
+# define YYTOKEN_TABLE 0
+#endif
+
+#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
+typedef union YYSTYPE
+
+{
+    time_t Number;
+    enum _MERIDIAN Meridian;
+}
+/* Line 187 of yacc.c.  */
+
+	YYSTYPE;
+# define yystype YYSTYPE /* obsolescent; will be withdrawn */
+# define YYSTYPE_IS_DECLARED 1
+# define YYSTYPE_IS_TRIVIAL 1
+#endif
+
+#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED
+typedef struct YYLTYPE
+{
+  int first_line;
+  int first_column;
+  int last_line;
+  int last_column;
+} YYLTYPE;
+# define yyltype YYLTYPE /* obsolescent; will be withdrawn */
+# define YYLTYPE_IS_DECLARED 1
+# define YYLTYPE_IS_TRIVIAL 1
+#endif
+
+
+/* Copy the second part of user declarations.  */
+
+
+
+/*
+ * Prototypes of internal functions.
+ */
+
+static int		LookupWord(YYSTYPE* yylvalPtr, char *buff);
+ static void		TclDateerror(YYLTYPE* location,
+				     DateInfo* info, const char *s);
+ static int		TclDatelex(YYSTYPE* yylvalPtr, YYLTYPE* location,
+				   DateInfo* info);
+static time_t		ToSeconds(time_t Hours, time_t Minutes,
+			    time_t Seconds, MERIDIAN Meridian);
+MODULE_SCOPE int	yyparse(DateInfo*);
+
+
+
+/* Line 216 of yacc.c.  */
+
+
+#ifdef short
+# undef short
+#endif
+
+#ifdef YYTYPE_UINT8
+typedef YYTYPE_UINT8 yytype_uint8;
+#else
+typedef unsigned char yytype_uint8;
+#endif
+
+#ifdef YYTYPE_INT8
+typedef YYTYPE_INT8 yytype_int8;
+#elif (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+typedef signed char yytype_int8;
+#else
+typedef short int yytype_int8;
+#endif
+
+#ifdef YYTYPE_UINT16
+typedef YYTYPE_UINT16 yytype_uint16;
+#else
+typedef unsigned short int yytype_uint16;
+#endif
+
+#ifdef YYTYPE_INT16
+typedef YYTYPE_INT16 yytype_int16;
+#else
+typedef short int yytype_int16;
+#endif
+
+#ifndef YYSIZE_T
+# ifdef __SIZE_TYPE__
+#  define YYSIZE_T __SIZE_TYPE__
+# else
+#  define YYSIZE_T size_t
+# endif
+#endif
+
+#define YYSIZE_MAXIMUM ((YYSIZE_T) -1)
+
+#ifndef YY_
+# if YYENABLE_NLS
+#  if ENABLE_NLS
+#   include <libintl.h> /* INFRINGES ON USER NAME SPACE */
+#   define YY_(msgid) dgettext ("bison-runtime", msgid)
+#  endif
+# endif
+# ifndef YY_
+#  define YY_(msgid) msgid
+# endif
+#endif
+
+/* Suppress unused-variable warnings by "using" E.  */
+#if ! defined lint || defined __GNUC__
+# define YYUSE(e) ((void) (e))
+#else
+# define YYUSE(e) /* empty */
+#endif
+
+/* Identity function, used to suppress warnings about constant conditions.  */
+#ifndef lint
+# define YYID(n) (n)
+#else
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+static int
+YYID (int i)
+#else
+static int
+YYID (i)
+    int i;
+#endif
+{
+  return i;
+}
+#endif
+
+#if ! defined yyoverflow || YYERROR_VERBOSE
+
+/* The parser invokes alloca or malloc; define the necessary symbols.  */
+
+# ifdef YYSTACK_USE_ALLOCA
+#  if YYSTACK_USE_ALLOCA
+#   ifdef __GNUC__
+#    define YYSTACK_ALLOC __builtin_alloca
+#   elif defined __BUILTIN_VA_ARG_INCR
+#    include <alloca.h> /* INFRINGES ON USER NAME SPACE */
+#   elif defined _AIX
+#    define YYSTACK_ALLOC __alloca
+#   elif defined _MSC_VER
+#    include <malloc.h> /* INFRINGES ON USER NAME SPACE */
+#    define alloca _alloca
+#   else
+#    define YYSTACK_ALLOC alloca
+#    if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+#     include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+#     ifndef _STDLIB_H
+#      define _STDLIB_H 1
+#     endif
+#    endif
+#   endif
+#  endif
+# endif
+
+# ifdef YYSTACK_ALLOC
+   /* Pacify GCC's `empty if-body' warning.  */
+#  define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0))
+#  ifndef YYSTACK_ALLOC_MAXIMUM
+    /* The OS might guarantee only one guard page at the bottom of the stack,
+       and a page size can be as small as 4096 bytes.  So we cannot safely
+       invoke alloca (N) if N exceeds 4096.  Use a slightly smaller number
+       to allow for a few compiler-allocated temporary stack slots.  */
+#   define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */
+#  endif
+# else
+#  define YYSTACK_ALLOC YYMALLOC
+#  define YYSTACK_FREE YYFREE
+#  ifndef YYSTACK_ALLOC_MAXIMUM
+#   define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
+#  endif
+#  if (defined __cplusplus && ! defined _STDLIB_H \
+       && ! ((defined YYMALLOC || defined malloc) \
+	     && (defined YYFREE || defined free)))
+#   include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
+#   ifndef _STDLIB_H
+#    define _STDLIB_H 1
+#   endif
+#  endif
+#  ifndef YYMALLOC
+#   define YYMALLOC malloc
+#   if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
+#   endif
+#  endif
+#  ifndef YYFREE
+#   define YYFREE free
+#   if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+void free (void *); /* INFRINGES ON USER NAME SPACE */
+#   endif
+#  endif
+# endif
+#endif /* ! defined yyoverflow || YYERROR_VERBOSE */
+
+
+#if (! defined yyoverflow \
+     && (! defined __cplusplus \
+	 || (defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL \
+	     && defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
+
+/* A type that is properly aligned for any stack member.  */
+union yyalloc
+{
+  yytype_int16 yyss;
+  YYSTYPE yyvs;
+    YYLTYPE yyls;
+};
+
+/* The size of the maximum gap between one aligned stack and the next.  */
+# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
+
+/* The size of an array large to enough to hold all stacks, each with
+   N elements.  */
+# define YYSTACK_BYTES(N) \
+     ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE) + sizeof (YYLTYPE)) \
+      + 2 * YYSTACK_GAP_MAXIMUM)
+
+/* Copy COUNT objects from FROM to TO.  The source and destination do
+   not overlap.  */
+# ifndef YYCOPY
+#  if defined __GNUC__ && 1 < __GNUC__
+#   define YYCOPY(To, From, Count) \
+      __builtin_memcpy (To, From, (Count) * sizeof (*(From)))
+#  else
+#   define YYCOPY(To, From, Count)		\
+      do					\
+	{					\
+	  YYSIZE_T yyi;				\
+	  for (yyi = 0; yyi < (Count); yyi++)	\
+	    (To)[yyi] = (From)[yyi];		\
+	}					\
+      while (YYID (0))
+#  endif
+# endif
+
+/* Relocate STACK from its old location to the new one.  The
+   local variables YYSIZE and YYSTACKSIZE give the old and new number of
+   elements in the stack, and YYPTR gives the new location of the
+   stack.  Advance YYPTR to a properly aligned location for the next
+   stack.  */
+# define YYSTACK_RELOCATE(Stack)					\
+    do									\
+      {									\
+	YYSIZE_T yynewbytes;						\
+	YYCOPY (&yyptr->Stack, Stack, yysize);				\
+	Stack = &yyptr->Stack;						\
+	yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
+	yyptr += yynewbytes / sizeof (*yyptr);				\
+      }									\
+    while (YYID (0))
+
+#endif
+
+/* YYFINAL -- State number of the termination state.  */
+#define YYFINAL  2
+/* YYLAST -- Last index in YYTABLE.  */
+#define YYLAST   79
+
+/* YYNTOKENS -- Number of terminals.  */
+#define YYNTOKENS  26
+/* YYNNTS -- Number of nonterminals.  */
+#define YYNNTS  16
+/* YYNRULES -- Number of rules.  */
+#define YYNRULES  56
+/* YYNRULES -- Number of states.  */
+#define YYNSTATES  83
+
+/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX.  */
+#define YYUNDEFTOK  2
+#define YYMAXUTOK   274
+
+#define YYTRANSLATE(YYX)						\
+  ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
+
+/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX.  */
+static const yytype_uint8 yytranslate[] =
+{
+       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,     2,     2,     2,     2,     2,
+       2,     2,     2,    25,    22,    21,    24,    23,     2,     2,
+       2,     2,     2,     2,     2,     2,     2,     2,    20,     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,     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,     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,     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,     2,     1,     2,     3,     4,
+       5,     6,     7,     8,     9,    10,    11,    12,    13,    14,
+      15,    16,    17,    18,    19
+};
+
+#if YYDEBUG
+/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
+   YYRHS.  */
+static const yytype_uint8 yyprhs[] =
+{
+       0,     0,     3,     4,     7,     9,    11,    13,    15,    17,
+      19,    21,    23,    25,    28,    33,    39,    46,    54,    57,
+      59,    61,    63,    66,    69,    73,    76,    80,    86,    88,
+      94,   100,   103,   108,   111,   113,   117,   120,   124,   128,
+     136,   139,   144,   147,   149,   153,   156,   159,   163,   165,
+     167,   169,   171,   173,   175,   177,   178
+};
+
+/* YYRHS -- A `-1'-separated list of the rules' RHS.  */
+static const yytype_int8 yyrhs[] =
+{
+      27,     0,    -1,    -1,    27,    28,    -1,    29,    -1,    30,
+      -1,    32,    -1,    33,    -1,    31,    -1,    36,    -1,    34,
+      -1,    35,    -1,    40,    -1,    13,     7,    -1,    13,    20,
+      13,    41,    -1,    13,    20,    13,    21,    13,    -1,    13,
+      20,    13,    20,    13,    41,    -1,    13,    20,    13,    20,
+      13,    21,    13,    -1,    14,    16,    -1,    14,    -1,     5,
+      -1,     4,    -1,     4,    22,    -1,    13,     4,    -1,    38,
+      13,     4,    -1,    19,     4,    -1,    13,    23,    13,    -1,
+      13,    23,    13,    23,    13,    -1,    17,    -1,    13,    21,
+       8,    21,    13,    -1,    13,    21,    13,    21,    13,    -1,
+       8,    13,    -1,     8,    13,    22,    13,    -1,    13,     8,
+      -1,    15,    -1,    13,     8,    13,    -1,    19,     8,    -1,
+      19,    13,     8,    -1,    17,    14,    17,    -1,    17,    14,
+      13,    20,    13,    20,    13,    -1,    17,    17,    -1,    10,
+      13,    24,    13,    -1,    37,     3,    -1,    37,    -1,    38,
+      13,    39,    -1,    13,    39,    -1,    19,    39,    -1,    19,
+      13,    39,    -1,    39,    -1,    21,    -1,    25,    -1,    11,
+      -1,    18,    -1,     9,    -1,    13,    -1,    -1,     7,    -1
+};
+
+/* YYRLINE[YYN] -- source line where rule number YYN was defined.  */
+static const yytype_uint16 yyrline[] =
+{
+       0,   225,   225,   226,   229,   232,   235,   238,   241,   244,
+     247,   251,   256,   259,   265,   271,   279,   285,   296,   300,
+     304,   310,   314,   318,   322,   326,   332,   336,   341,   346,
+     351,   356,   360,   365,   369,   374,   381,   385,   391,   400,
+     409,   419,   433,   438,   441,   444,   447,   450,   453,   458,
+     461,   466,   470,   474,   480,   498,   501
+};
+#endif
+
+#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE
+/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
+   First, the terminals, then, starting at YYNTOKENS, nonterminals.  */
+static const char *const yytname[] =
+{
+  "$end", "error", "$undefined", "tAGO", "tDAY", "tDAYZONE", "tID",
+  "tMERIDIAN", "tMONTH", "tMONTH_UNIT", "tSTARDATE", "tSEC_UNIT",
+  "tSNUMBER", "tUNUMBER", "tZONE", "tEPOCH", "tDST", "tISOBASE",
+  "tDAY_UNIT", "tNEXT", "':'", "'-'", "','", "'/'", "'.'", "'+'",
+  "$accept", "spec", "item", "time", "zone", "day", "date", "ordMonth",
+  "iso", "trek", "relspec", "relunits", "sign", "unit", "number",
+  "o_merid", 0
+};
+#endif
+
+# ifdef YYPRINT
+/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to
+   token YYLEX-NUM.  */
+static const yytype_uint16 yytoknum[] =
+{
+       0,   256,   257,   258,   259,   260,   261,   262,   263,   264,
+     265,   266,   267,   268,   269,   270,   271,   272,   273,   274,
+      58,    45,    44,    47,    46,    43
+};
+# endif
+
+/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */
+static const yytype_uint8 yyr1[] =
+{
+       0,    26,    27,    27,    28,    28,    28,    28,    28,    28,
+      28,    28,    28,    29,    29,    29,    29,    29,    30,    30,
+      30,    31,    31,    31,    31,    31,    32,    32,    32,    32,
+      32,    32,    32,    32,    32,    32,    33,    33,    34,    34,
+      34,    35,    36,    36,    37,    37,    37,    37,    37,    38,
+      38,    39,    39,    39,    40,    41,    41
+};
+
+/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN.  */
+static const yytype_uint8 yyr2[] =
+{
+       0,     2,     0,     2,     1,     1,     1,     1,     1,     1,
+       1,     1,     1,     2,     4,     5,     6,     7,     2,     1,
+       1,     1,     2,     2,     3,     2,     3,     5,     1,     5,
+       5,     2,     4,     2,     1,     3,     2,     3,     3,     7,
+       2,     4,     2,     1,     3,     2,     2,     3,     1,     1,
+       1,     1,     1,     1,     1,     0,     1
+};
+
+/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
+   STATE-NUM when YYTABLE doesn't specify something else to do.  Zero
+   means the default is an error.  */
+static const yytype_uint8 yydefact[] =
+{
+       2,     0,     1,    21,    20,     0,    53,     0,    51,    54,
+      19,    34,    28,    52,     0,    49,    50,     3,     4,     5,
+       8,     6,     7,    10,    11,     9,    43,     0,    48,    12,
+      22,    31,     0,    23,    13,    33,     0,     0,     0,    45,
+      18,     0,    40,    25,    36,     0,    46,    42,     0,     0,
+       0,    35,    55,     0,     0,    26,     0,    38,    37,    47,
+      24,    44,    32,    41,    56,     0,     0,    14,     0,     0,
+       0,     0,    55,    15,    29,    30,    27,     0,     0,    16,
+       0,    17,    39
+};
+
+/* YYDEFGOTO[NTERM-NUM].  */
+static const yytype_int8 yydefgoto[] =
+{
+      -1,     1,    17,    18,    19,    20,    21,    22,    23,    24,
+      25,    26,    27,    28,    29,    67
+};
+
+/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
+   STATE-NUM.  */
+#define YYPACT_NINF -22
+static const yytype_int8 yypact[] =
+{
+     -22,     2,   -22,   -21,   -22,    -4,   -22,     1,   -22,    22,
+      18,   -22,     8,   -22,    40,   -22,   -22,   -22,   -22,   -22,
+     -22,   -22,   -22,   -22,   -22,   -22,    32,    28,   -22,   -22,
+     -22,    24,    26,   -22,   -22,    42,    47,    -5,    49,   -22,
+     -22,    15,   -22,   -22,   -22,    48,   -22,   -22,    43,    50,
+      51,   -22,    17,    44,    46,    45,    52,   -22,   -22,   -22,
+     -22,   -22,   -22,   -22,   -22,    56,    57,   -22,    58,    60,
+      61,    62,    -3,   -22,   -22,   -22,   -22,    59,    63,   -22,
+      64,   -22,   -22
+};
+
+/* YYPGOTO[NTERM-NUM].  */
+static const yytype_int8 yypgoto[] =
+{
+     -22,   -22,   -22,   -22,   -22,   -22,   -22,   -22,   -22,   -22,
+     -22,   -22,   -22,    -9,   -22,     6
+};
+
+/* YYTABLE[YYPACT[STATE-NUM]].  What to do in state STATE-NUM.  If
+   positive, shift that token.  If negative, reduce the rule which
+   number is the opposite.  If zero, do what YYDEFACT says.
+   If YYTABLE_NINF, syntax error.  */
+#define YYTABLE_NINF -1
+static const yytype_uint8 yytable[] =
+{
+      39,    30,     2,    53,    64,    46,     3,     4,    54,    31,
+       5,     6,     7,     8,    32,     9,    10,    11,    78,    12,
+      13,    14,    41,    15,    64,    42,    33,    16,    56,    34,
+      35,     6,    57,     8,    40,    47,    59,    65,    66,    61,
+      13,    48,    36,    37,    43,    38,    49,    60,    44,     6,
+      50,     8,     6,    45,     8,    51,    58,     6,    13,     8,
+      52,    13,    55,    62,    63,    68,    13,    69,    70,    72,
+      73,    74,    71,    75,    76,    77,    81,    82,    79,    80
+};
+
+static const yytype_uint8 yycheck[] =
+{
+       9,    22,     0,     8,     7,    14,     4,     5,    13,    13,
+       8,     9,    10,    11,    13,    13,    14,    15,    21,    17,
+      18,    19,    14,    21,     7,    17,     4,    25,    13,     7,
+       8,     9,    17,    11,    16,     3,    45,    20,    21,    48,
+      18,    13,    20,    21,     4,    23,    22,     4,     8,     9,
+      24,    11,     9,    13,    11,    13,     8,     9,    18,    11,
+      13,    18,    13,    13,    13,    21,    18,    21,    23,    13,
+      13,    13,    20,    13,    13,    13,    13,    13,    72,    20
+};
+
+/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
+   symbol of state STATE-NUM.  */
+static const yytype_uint8 yystos[] =
+{
+       0,    27,     0,     4,     5,     8,     9,    10,    11,    13,
+      14,    15,    17,    18,    19,    21,    25,    28,    29,    30,
+      31,    32,    33,    34,    35,    36,    37,    38,    39,    40,
+      22,    13,    13,     4,     7,     8,    20,    21,    23,    39,
+      16,    14,    17,     4,     8,    13,    39,     3,    13,    22,
+      24,    13,    13,     8,    13,    13,    13,    17,     8,    39,
+       4,    39,    13,    13,     7,    20,    21,    41,    21,    21,
+      23,    20,    13,    13,    13,    13,    13,    13,    21,    41,
+      20,    13,    13
+};
+
+#define yyerrok		(yyerrstatus = 0)
+#define yyclearin	(yychar = YYEMPTY)
+#define YYEMPTY		(-2)
+#define YYEOF		0
+
+#define YYACCEPT	goto yyacceptlab
+#define YYABORT		goto yyabortlab
+#define YYERROR		goto yyerrorlab
+
+
+/* Like YYERROR except do call yyerror.  This remains here temporarily
+   to ease the transition to the new meaning of YYERROR, for GCC.
+   Once GCC version 2 has supplanted version 1, this can go.  */
+
+#define YYFAIL		goto yyerrlab
+
+#define YYRECOVERING()  (!!yyerrstatus)
+
+#define YYBACKUP(Token, Value)					\
+do								\
+  if (yychar == YYEMPTY && yylen == 1)				\
+    {								\
+      yychar = (Token);						\
+      yylval = (Value);						\
+      yytoken = YYTRANSLATE (yychar);				\
+      YYPOPSTACK (1);						\
+      goto yybackup;						\
+    }								\
+  else								\
+    {								\
+      yyerror (&yylloc, info, YY_("syntax error: cannot back up")); \
+      YYERROR;							\
+    }								\
+while (YYID (0))
+
+
+#define YYTERROR	1
+#define YYERRCODE	256
+
+
+/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N].
+   If N is 0, then set CURRENT to the empty location which ends
+   the previous symbol: RHS[0] (always defined).  */
+
+#define YYRHSLOC(Rhs, K) ((Rhs)[K])
+#ifndef YYLLOC_DEFAULT
+# define YYLLOC_DEFAULT(Current, Rhs, N)				\
+    do									\
+      if (YYID (N))                                                    \
+	{								\
+	  (Current).first_line   = YYRHSLOC (Rhs, 1).first_line;	\
+	  (Current).first_column = YYRHSLOC (Rhs, 1).first_column;	\
+	  (Current).last_line    = YYRHSLOC (Rhs, N).last_line;		\
+	  (Current).last_column  = YYRHSLOC (Rhs, N).last_column;	\
+	}								\
+      else								\
+	{								\
+	  (Current).first_line   = (Current).last_line   =		\
+	    YYRHSLOC (Rhs, 0).last_line;				\
+	  (Current).first_column = (Current).last_column =		\
+	    YYRHSLOC (Rhs, 0).last_column;				\
+	}								\
+    while (YYID (0))
+#endif
+
+
+/* YY_LOCATION_PRINT -- Print the location on the stream.
+   This macro was not mandated originally: define only if we know
+   we won't break user code: when these are the locations we know.  */
+
+#ifndef YY_LOCATION_PRINT
+# if YYLTYPE_IS_TRIVIAL
+#  define YY_LOCATION_PRINT(File, Loc)			\
+     fprintf (File, "%d.%d-%d.%d",			\
+	      (Loc).first_line, (Loc).first_column,	\
+	      (Loc).last_line,  (Loc).last_column)
+# else
+#  define YY_LOCATION_PRINT(File, Loc) ((void) 0)
+# endif
+#endif
+
+
+/* YYLEX -- calling `yylex' with the right arguments.  */
+
+#ifdef YYLEX_PARAM
+# define YYLEX yylex (&yylval, &yylloc, YYLEX_PARAM)
+#else
+# define YYLEX yylex (&yylval, &yylloc, info)
+#endif
+
+/* Enable debugging if requested.  */
+#if YYDEBUG
+
+# ifndef YYFPRINTF
+#  include <stdio.h> /* INFRINGES ON USER NAME SPACE */
+#  define YYFPRINTF fprintf
+# endif
+
+# define YYDPRINTF(Args)			\
+do {						\
+  if (yydebug)					\
+    YYFPRINTF Args;				\
+} while (YYID (0))
+
+# define YY_SYMBOL_PRINT(Title, Type, Value, Location)			  \
+do {									  \
+  if (yydebug)								  \
+    {									  \
+      YYFPRINTF (stderr, "%s ", Title);					  \
+      yy_symbol_print (stderr,						  \
+		  Type, Value, Location, info); \
+      YYFPRINTF (stderr, "\n");						  \
+    }									  \
+} while (YYID (0))
+
+
+/*--------------------------------.
+| Print this symbol on YYOUTPUT.  |
+`--------------------------------*/
+
+/*ARGSUSED*/
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+static void
+yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp, DateInfo* info)
+#else
+static void
+yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp, info)
+    FILE *yyoutput;
+    int yytype;
+    YYSTYPE const * const yyvaluep;
+    YYLTYPE const * const yylocationp;
+    DateInfo* info;
+#endif
+{
+  if (!yyvaluep)
+    return;
+  YYUSE (yylocationp);
+  YYUSE (info);
+# ifdef YYPRINT
+  if (yytype < YYNTOKENS)
+    YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
+# else
+  YYUSE (yyoutput);
+# endif
+  switch (yytype)
+    {
+      default:
+	break;
+    }
+}
+
+
+/*--------------------------------.
+| Print this symbol on YYOUTPUT.  |
+`--------------------------------*/
+
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+static void
+yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp, DateInfo* info)
+#else
+static void
+yy_symbol_print (yyoutput, yytype, yyvaluep, yylocationp, info)
+    FILE *yyoutput;
+    int yytype;
+    YYSTYPE const * const yyvaluep;
+    YYLTYPE const * const yylocationp;
+    DateInfo* info;
+#endif
+{
+  if (yytype < YYNTOKENS)
+    YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
+  else
+    YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
+
+  YY_LOCATION_PRINT (yyoutput, *yylocationp);
+  YYFPRINTF (yyoutput, ": ");
+  yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp, info);
+  YYFPRINTF (yyoutput, ")");
+}
+
+/*------------------------------------------------------------------.
+| yy_stack_print -- Print the state stack from its BOTTOM up to its |
+| TOP (included).                                                   |
+`------------------------------------------------------------------*/
+
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+static void
+yy_stack_print (yytype_int16 *bottom, yytype_int16 *top)
+#else
+static void
+yy_stack_print (bottom, top)
+    yytype_int16 *bottom;
+    yytype_int16 *top;
+#endif
+{
+  YYFPRINTF (stderr, "Stack now");
+  for (; bottom <= top; ++bottom)
+    YYFPRINTF (stderr, " %d", *bottom);
+  YYFPRINTF (stderr, "\n");
+}
+
+# define YY_STACK_PRINT(Bottom, Top)				\
+do {								\
+  if (yydebug)							\
+    yy_stack_print ((Bottom), (Top));				\
+} while (YYID (0))
+
+
+/*------------------------------------------------.
+| Report that the YYRULE is going to be reduced.  |
+`------------------------------------------------*/
+
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+static void
+yy_reduce_print (YYSTYPE *yyvsp, YYLTYPE *yylsp, int yyrule, DateInfo* info)
+#else
+static void
+yy_reduce_print (yyvsp, yylsp, yyrule, info)
+    YYSTYPE *yyvsp;
+    YYLTYPE *yylsp;
+    int yyrule;
+    DateInfo* info;
+#endif
+{
+  int yynrhs = yyr2[yyrule];
+  int yyi;
+  unsigned long int yylno = yyrline[yyrule];
+  YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n",
+	     yyrule - 1, yylno);
+  /* The symbols being reduced.  */
+  for (yyi = 0; yyi < yynrhs; yyi++)
+    {
+      fprintf (stderr, "   $%d = ", yyi + 1);
+      yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi],
+		       &(yyvsp[(yyi + 1) - (yynrhs)])
+		       , &(yylsp[(yyi + 1) - (yynrhs)])		       , info);
+      fprintf (stderr, "\n");
+    }
+}
+
+# define YY_REDUCE_PRINT(Rule)		\
+do {					\
+  if (yydebug)				\
+    yy_reduce_print (yyvsp, yylsp, Rule, info); \
+} while (YYID (0))
+
+/* Nonzero means print parse trace.  It is left uninitialized so that
+   multiple parsers can coexist.  */
+int yydebug;
+#else /* !YYDEBUG */
+# define YYDPRINTF(Args)
+# define YY_SYMBOL_PRINT(Title, Type, Value, Location)
+# define YY_STACK_PRINT(Bottom, Top)
+# define YY_REDUCE_PRINT(Rule)
+#endif /* !YYDEBUG */
+
+
+/* YYINITDEPTH -- initial size of the parser's stacks.  */
+#ifndef	YYINITDEPTH
+# define YYINITDEPTH 200
+#endif
+
+/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
+   if the built-in stack extension method is used).
+
+   Do not make this value too large; the results are undefined if
+   YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH)
+   evaluated with infinite-precision integer arithmetic.  */
+
+#ifndef YYMAXDEPTH
+# define YYMAXDEPTH 10000
+#endif
+
+
+
+#if YYERROR_VERBOSE
+
+# ifndef yystrlen
+#  if defined __GLIBC__ && defined _STRING_H
+#   define yystrlen strlen
+#  else
+/* Return the length of YYSTR.  */
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+static YYSIZE_T
+yystrlen (const char *yystr)
+#else
+static YYSIZE_T
+yystrlen (yystr)
+    const char *yystr;
+#endif
+{
+  YYSIZE_T yylen;
+  for (yylen = 0; yystr[yylen]; yylen++)
+    continue;
+  return yylen;
+}
+#  endif
+# endif
+
+# ifndef yystpcpy
+#  if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE
+#   define yystpcpy stpcpy
+#  else
+/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
+   YYDEST.  */
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+static char *
+yystpcpy (char *yydest, const char *yysrc)
+#else
+static char *
+yystpcpy (yydest, yysrc)
+    char *yydest;
+    const char *yysrc;
+#endif
+{
+  char *yyd = yydest;
+  const char *yys = yysrc;
+
+  while ((*yyd++ = *yys++) != '\0')
+    continue;
+
+  return yyd - 1;
+}
+#  endif
+# endif
+
+# ifndef yytnamerr
+/* Copy to YYRES the contents of YYSTR after stripping away unnecessary
+   quotes and backslashes, so that it's suitable for yyerror.  The
+   heuristic is that double-quoting is unnecessary unless the string
+   contains an apostrophe, a comma, or backslash (other than
+   backslash-backslash).  YYSTR is taken from yytname.  If YYRES is
+   null, do not copy; instead, return the length of what the result
+   would have been.  */
+static YYSIZE_T
+yytnamerr (char *yyres, const char *yystr)
+{
+  if (*yystr == '"')
+    {
+      YYSIZE_T yyn = 0;
+      char const *yyp = yystr;
+
+      for (;;)
+	switch (*++yyp)
+	  {
+	  case '\'':
+	  case ',':
+	    goto do_not_strip_quotes;
+
+	  case '\\':
+	    if (*++yyp != '\\')
+	      goto do_not_strip_quotes;
+	    /* Fall through.  */
+	  default:
+	    if (yyres)
+	      yyres[yyn] = *yyp;
+	    yyn++;
+	    break;
+
+	  case '"':
+	    if (yyres)
+	      yyres[yyn] = '\0';
+	    return yyn;
+	  }
+    do_not_strip_quotes: ;
+    }
+
+  if (! yyres)
+    return yystrlen (yystr);
+
+  return yystpcpy (yyres, yystr) - yyres;
+}
+# endif
+
+/* Copy into YYRESULT an error message about the unexpected token
+   YYCHAR while in state YYSTATE.  Return the number of bytes copied,
+   including the terminating null byte.  If YYRESULT is null, do not
+   copy anything; just return the number of bytes that would be
+   copied.  As a special case, return 0 if an ordinary "syntax error"
+   message will do.  Return YYSIZE_MAXIMUM if overflow occurs during
+   size calculation.  */
+static YYSIZE_T
+yysyntax_error (char *yyresult, int yystate, int yychar)
+{
+  int yyn = yypact[yystate];
+
+  if (! (YYPACT_NINF < yyn && yyn <= YYLAST))
+    return 0;
+  else
+    {
+      int yytype = YYTRANSLATE (yychar);
+      YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]);
+      YYSIZE_T yysize = yysize0;
+      YYSIZE_T yysize1;
+      int yysize_overflow = 0;
+      enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
+      char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
+      int yyx;
+
+# if 0
+      /* This is so xgettext sees the translatable formats that are
+	 constructed on the fly.  */
+      YY_("syntax error, unexpected %s");
+      YY_("syntax error, unexpected %s, expecting %s");
+      YY_("syntax error, unexpected %s, expecting %s or %s");
+      YY_("syntax error, unexpected %s, expecting %s or %s or %s");
+      YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s");
+# endif
+      char *yyfmt;
+      char const *yyf;
+      static char const yyunexpected[] = "syntax error, unexpected %s";
+      static char const yyexpecting[] = ", expecting %s";
+      static char const yyor[] = " or %s";
+      char yyformat[sizeof yyunexpected
+		    + sizeof yyexpecting - 1
+		    + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2)
+		       * (sizeof yyor - 1))];
+      char const *yyprefix = yyexpecting;
+
+      /* Start YYX at -YYN if negative to avoid negative indexes in
+	 YYCHECK.  */
+      int yyxbegin = yyn < 0 ? -yyn : 0;
+
+      /* Stay within bounds of both yycheck and yytname.  */
+      int yychecklim = YYLAST - yyn + 1;
+      int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
+      int yycount = 1;
+
+      yyarg[0] = yytname[yytype];
+      yyfmt = yystpcpy (yyformat, yyunexpected);
+
+      for (yyx = yyxbegin; yyx < yyxend; ++yyx)
+	if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
+	  {
+	    if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
+	      {
+		yycount = 1;
+		yysize = yysize0;
+		yyformat[sizeof yyunexpected - 1] = '\0';
+		break;
+	      }
+	    yyarg[yycount++] = yytname[yyx];
+	    yysize1 = yysize + yytnamerr (0, yytname[yyx]);
+	    yysize_overflow |= (yysize1 < yysize);
+	    yysize = yysize1;
+	    yyfmt = yystpcpy (yyfmt, yyprefix);
+	    yyprefix = yyor;
+	  }
+
+      yyf = YY_(yyformat);
+      yysize1 = yysize + yystrlen (yyf);
+      yysize_overflow |= (yysize1 < yysize);
+      yysize = yysize1;
+
+      if (yysize_overflow)
+	return YYSIZE_MAXIMUM;
+
+      if (yyresult)
+	{
+	  /* Avoid sprintf, as that infringes on the user's name space.
+	     Don't have undefined behavior even if the translation
+	     produced a string with the wrong number of "%s"s.  */
+	  char *yyp = yyresult;
+	  int yyi = 0;
+	  while ((*yyp = *yyf) != '\0')
+	    {
+	      if (*yyp == '%' && yyf[1] == 's' && yyi < yycount)
+		{
+		  yyp += yytnamerr (yyp, yyarg[yyi++]);
+		  yyf += 2;
+		}
+	      else
+		{
+		  yyp++;
+		  yyf++;
+		}
+	    }
+	}
+      return yysize;
+    }
+}
+#endif /* YYERROR_VERBOSE */
+
+
+/*-----------------------------------------------.
+| Release the memory associated to this symbol.  |
+`-----------------------------------------------*/
+
+/*ARGSUSED*/
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+static void
+yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, YYLTYPE *yylocationp, DateInfo* info)
+#else
+static void
+yydestruct (yymsg, yytype, yyvaluep, yylocationp, info)
+    const char *yymsg;
+    int yytype;
+    YYSTYPE *yyvaluep;
+    YYLTYPE *yylocationp;
+    DateInfo* info;
+#endif
+{
+  YYUSE (yyvaluep);
+  YYUSE (yylocationp);
+  YYUSE (info);
+
+  if (!yymsg)
+    yymsg = "Deleting";
+  YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
+
+  switch (yytype)
+    {
+
+      default:
+	break;
+    }
+}
+
+
+/* Prevent warnings from -Wmissing-prototypes.  */
+
+#ifdef YYPARSE_PARAM
+#if defined __STDC__ || defined __cplusplus
+int yyparse (void *YYPARSE_PARAM);
+#else
+int yyparse ();
+#endif
+#else /* ! YYPARSE_PARAM */
+#if defined __STDC__ || defined __cplusplus
+int yyparse (DateInfo* info);
+#else
+int yyparse ();
+#endif
+#endif /* ! YYPARSE_PARAM */
+
+
+
+
+
+
+/*----------.
+| yyparse.  |
+`----------*/
+
+#ifdef YYPARSE_PARAM
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+int
+yyparse (void *YYPARSE_PARAM)
+#else
+int
+yyparse (YYPARSE_PARAM)
+    void *YYPARSE_PARAM;
+#endif
+#else /* ! YYPARSE_PARAM */
+#if (defined __STDC__ || defined __C99__FUNC__ \
+     || defined __cplusplus || defined _MSC_VER)
+int
+yyparse (DateInfo* info)
+#else
+int
+yyparse (info)
+    DateInfo* info;
+#endif
+#endif
+{
+  /* The look-ahead symbol.  */
+int yychar;
+
+/* The semantic value of the look-ahead symbol.  */
+YYSTYPE yylval;
+
+/* Number of syntax errors so far.  */
+int yynerrs;
+/* Location data for the look-ahead symbol.  */
+YYLTYPE yylloc;
+
+  int yystate;
+  int yyn;
+  int yyresult;
+  /* Number of tokens to shift before error messages enabled.  */
+  int yyerrstatus;
+  /* Look-ahead token as an internal (translated) token number.  */
+  int yytoken = 0;
+#if YYERROR_VERBOSE
+  /* Buffer for error messages, and its allocated size.  */
+  char yymsgbuf[128];
+  char *yymsg = yymsgbuf;
+  YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
+#endif
+
+  /* Three stacks and their tools:
+     `yyss': related to states,
+     `yyvs': related to semantic values,
+     `yyls': related to locations.
+
+     Refer to the stacks thru separate pointers, to allow yyoverflow
+     to reallocate them elsewhere.  */
+
+  /* The state stack.  */
+  yytype_int16 yyssa[YYINITDEPTH];
+  yytype_int16 *yyss = yyssa;
+  yytype_int16 *yyssp;
+
+  /* The semantic value stack.  */
+  YYSTYPE yyvsa[YYINITDEPTH];
+  YYSTYPE *yyvs = yyvsa;
+  YYSTYPE *yyvsp;
+
+  /* The location stack.  */
+  YYLTYPE yylsa[YYINITDEPTH];
+  YYLTYPE *yyls = yylsa;
+  YYLTYPE *yylsp;
+  /* The locations where the error started and ended.  */
+  YYLTYPE yyerror_range[2];
+
+#define YYPOPSTACK(N)   (yyvsp -= (N), yyssp -= (N), yylsp -= (N))
+
+  YYSIZE_T yystacksize = YYINITDEPTH;
+
+  /* The variables used to return semantic value and location from the
+     action routines.  */
+  YYSTYPE yyval;
+  YYLTYPE yyloc;
+
+  /* The number of symbols on the RHS of the reduced rule.
+     Keep to zero when no symbol should be popped.  */
+  int yylen = 0;
+
+  YYDPRINTF ((stderr, "Starting parse\n"));
+
+  yystate = 0;
+  yyerrstatus = 0;
+  yynerrs = 0;
+  yychar = YYEMPTY;		/* Cause a token to be read.  */
+
+  /* Initialize stack pointers.
+     Waste one element of value and location stack
+     so that they stay on the same level as the state stack.
+     The wasted elements are never initialized.  */
+
+  yyssp = yyss;
+  yyvsp = yyvs;
+  yylsp = yyls;
+#if YYLTYPE_IS_TRIVIAL
+  /* Initialize the default location before parsing starts.  */
+  yylloc.first_line   = yylloc.last_line   = 1;
+  yylloc.first_column = yylloc.last_column = 0;
+#endif
+
+  goto yysetstate;
+
+/*------------------------------------------------------------.
+| yynewstate -- Push a new state, which is found in yystate.  |
+`------------------------------------------------------------*/
+ yynewstate:
+  /* In all cases, when you get here, the value and location stacks
+     have just been pushed.  So pushing a state here evens the stacks.  */
+  yyssp++;
+
+ yysetstate:
+  *yyssp = yystate;
+
+  if (yyss + yystacksize - 1 <= yyssp)
+    {
+      /* Get the current used size of the three stacks, in elements.  */
+      YYSIZE_T yysize = yyssp - yyss + 1;
+
+#ifdef yyoverflow
+      {
+	/* Give user a chance to reallocate the stack.  Use copies of
+	   these so that the &'s don't force the real ones into
+	   memory.  */
+	YYSTYPE *yyvs1 = yyvs;
+	yytype_int16 *yyss1 = yyss;
+	YYLTYPE *yyls1 = yyls;
+
+	/* Each stack pointer address is followed by the size of the
+	   data in use in that stack, in bytes.  This used to be a
+	   conditional around just the two extra args, but that might
+	   be undefined if yyoverflow is a macro.  */
+	yyoverflow (YY_("memory exhausted"),
+		    &yyss1, yysize * sizeof (*yyssp),
+		    &yyvs1, yysize * sizeof (*yyvsp),
+		    &yyls1, yysize * sizeof (*yylsp),
+		    &yystacksize);
+	yyls = yyls1;
+	yyss = yyss1;
+	yyvs = yyvs1;
+      }
+#else /* no yyoverflow */
+# ifndef YYSTACK_RELOCATE
+      goto yyexhaustedlab;
+# else
+      /* Extend the stack our own way.  */
+      if (YYMAXDEPTH <= yystacksize)
+	goto yyexhaustedlab;
+      yystacksize *= 2;
+      if (YYMAXDEPTH < yystacksize)
+	yystacksize = YYMAXDEPTH;
+
+      {
+	yytype_int16 *yyss1 = yyss;
+	union yyalloc *yyptr =
+	  (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
+	if (! yyptr)
+	  goto yyexhaustedlab;
+	YYSTACK_RELOCATE (yyss);
+	YYSTACK_RELOCATE (yyvs);
+	YYSTACK_RELOCATE (yyls);
+#  undef YYSTACK_RELOCATE
+	if (yyss1 != yyssa)
+	  YYSTACK_FREE (yyss1);
+      }
+# endif
+#endif /* no yyoverflow */
+
+      yyssp = yyss + yysize - 1;
+      yyvsp = yyvs + yysize - 1;
+      yylsp = yyls + yysize - 1;
+
+      YYDPRINTF ((stderr, "Stack size increased to %lu\n",
+		  (unsigned long int) yystacksize));
+
+      if (yyss + yystacksize - 1 <= yyssp)
+	YYABORT;
+    }
+
+  YYDPRINTF ((stderr, "Entering state %d\n", yystate));
+
+  goto yybackup;
+
+/*-----------.
+| yybackup.  |
+`-----------*/
+yybackup:
+
+  /* Do appropriate processing given the current state.  Read a
+     look-ahead token if we need one and don't already have one.  */
+
+  /* First try to decide what to do without reference to look-ahead token.  */
+  yyn = yypact[yystate];
+  if (yyn == YYPACT_NINF)
+    goto yydefault;
+
+  /* Not known => get a look-ahead token if don't already have one.  */
+
+  /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol.  */
+  if (yychar == YYEMPTY)
+    {
+      YYDPRINTF ((stderr, "Reading a token: "));
+      yychar = YYLEX;
+    }
+
+  if (yychar <= YYEOF)
+    {
+      yychar = yytoken = YYEOF;
+      YYDPRINTF ((stderr, "Now at end of input.\n"));
+    }
+  else
+    {
+      yytoken = YYTRANSLATE (yychar);
+      YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
+    }
+
+  /* If the proper action on seeing token YYTOKEN is to reduce or to
+     detect an error, take that action.  */
+  yyn += yytoken;
+  if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
+    goto yydefault;
+  yyn = yytable[yyn];
+  if (yyn <= 0)
+    {
+      if (yyn == 0 || yyn == YYTABLE_NINF)
+	goto yyerrlab;
+      yyn = -yyn;
+      goto yyreduce;
+    }
+
+  if (yyn == YYFINAL)
+    YYACCEPT;
+
+  /* Count tokens shifted since error; after three, turn off error
+     status.  */
+  if (yyerrstatus)
+    yyerrstatus--;
+
+  /* Shift the look-ahead token.  */
+  YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
+
+  /* Discard the shifted token unless it is eof.  */
+  if (yychar != YYEOF)
+    yychar = YYEMPTY;
+
+  yystate = yyn;
+  *++yyvsp = yylval;
+  *++yylsp = yylloc;
+  goto yynewstate;
+
+
+/*-----------------------------------------------------------.
+| yydefault -- do the default action for the current state.  |
+`-----------------------------------------------------------*/
+yydefault:
+  yyn = yydefact[yystate];
+  if (yyn == 0)
+    goto yyerrlab;
+  goto yyreduce;
+
+
+/*-----------------------------.
+| yyreduce -- Do a reduction.  |
+`-----------------------------*/
+yyreduce:
+  /* yyn is the number of a rule to reduce with.  */
+  yylen = yyr2[yyn];
+
+  /* If YYLEN is nonzero, implement the default value of the action:
+     `$$ = $1'.
+
+     Otherwise, the following line sets YYVAL to garbage.
+     This behavior is undocumented and Bison
+     users should not rely upon it.  Assigning to YYVAL
+     unconditionally makes the parser a bit smaller, and it avoids a
+     GCC warning that YYVAL may be used uninitialized.  */
+  yyval = yyvsp[1-yylen];
+
+  /* Default location.  */
+  YYLLOC_DEFAULT (yyloc, (yylsp - yylen), yylen);
+  YY_REDUCE_PRINT (yyn);
+  switch (yyn)
+    {
+        case 4:
+
+    {
+	    yyHaveTime++;
+	;}
+    break;
+
+  case 5:
+
+    {
+	    yyHaveZone++;
+	;}
+    break;
+
+  case 6:
+
+    {
+	    yyHaveDate++;
+	;}
+    break;
+
+  case 7:
+
+    {
+	    yyHaveOrdinalMonth++;
+	;}
+    break;
+
+  case 8:
+
+    {
+	    yyHaveDay++;
+	;}
+    break;
+
+  case 9:
+
+    {
+	    yyHaveRel++;
+	;}
+    break;
+
+  case 10:
+
+    {
+	    yyHaveTime++;
+	    yyHaveDate++;
+	;}
+    break;
+
+  case 11:
+
+    {
+	    yyHaveTime++;
+	    yyHaveDate++;
+	    yyHaveRel++;
+	;}
+    break;
+
+  case 13:
+
+    {
+	    yyHour = (yyvsp[(1) - (2)].Number);
+	    yyMinutes = 0;
+	    yySeconds = 0;
+	    yyMeridian = (yyvsp[(2) - (2)].Meridian);
+	;}
+    break;
+
+  case 14:
+
+    {
+	    yyHour = (yyvsp[(1) - (4)].Number);
+	    yyMinutes = (yyvsp[(3) - (4)].Number);
+	    yySeconds = 0;
+	    yyMeridian = (yyvsp[(4) - (4)].Meridian);
+	;}
+    break;
+
+  case 15:
+
+    {
+	    yyHour = (yyvsp[(1) - (5)].Number);
+	    yyMinutes = (yyvsp[(3) - (5)].Number);
+	    yyMeridian = MER24;
+	    yyDSTmode = DSToff;
+	    yyTimezone = ((yyvsp[(5) - (5)].Number) % 100 + ((yyvsp[(5) - (5)].Number) / 100) * 60);
+	    ++yyHaveZone;
+	;}
+    break;
+
+  case 16:
+
+    {
+	    yyHour = (yyvsp[(1) - (6)].Number);
+	    yyMinutes = (yyvsp[(3) - (6)].Number);
+	    yySeconds = (yyvsp[(5) - (6)].Number);
+	    yyMeridian = (yyvsp[(6) - (6)].Meridian);
+	;}
+    break;
+
+  case 17:
+
+    {
+	    yyHour = (yyvsp[(1) - (7)].Number);
+	    yyMinutes = (yyvsp[(3) - (7)].Number);
+	    yySeconds = (yyvsp[(5) - (7)].Number);
+	    yyMeridian = MER24;
+	    yyDSTmode = DSToff;
+	    yyTimezone = ((yyvsp[(7) - (7)].Number) % 100 + ((yyvsp[(7) - (7)].Number) / 100) * 60);
+	    ++yyHaveZone;
+	;}
+    break;
+
+  case 18:
+
+    {
+	    yyTimezone = (yyvsp[(1) - (2)].Number);
+	    yyDSTmode = DSTon;
+	;}
+    break;
+
+  case 19:
+
+    {
+	    yyTimezone = (yyvsp[(1) - (1)].Number);
+	    yyDSTmode = DSToff;
+	;}
+    break;
+
+  case 20:
+
+    {
+	    yyTimezone = (yyvsp[(1) - (1)].Number);
+	    yyDSTmode = DSTon;
+	;}
+    break;
+
+  case 21:
+
+    {
+	    yyDayOrdinal = 1;
+	    yyDayNumber = (yyvsp[(1) - (1)].Number);
+	;}
+    break;
+
+  case 22:
+
+    {
+	    yyDayOrdinal = 1;
+	    yyDayNumber = (yyvsp[(1) - (2)].Number);
+	;}
+    break;
+
+  case 23:
+
+    {
+	    yyDayOrdinal = (yyvsp[(1) - (2)].Number);
+	    yyDayNumber = (yyvsp[(2) - (2)].Number);
+	;}
+    break;
+
+  case 24:
+
+    {
+	    yyDayOrdinal = (yyvsp[(1) - (3)].Number) * (yyvsp[(2) - (3)].Number);
+	    yyDayNumber = (yyvsp[(3) - (3)].Number);
+	;}
+    break;
+
+  case 25:
+
+    {
+	    yyDayOrdinal = 2;
+	    yyDayNumber = (yyvsp[(2) - (2)].Number);
+	;}
+    break;
+
+  case 26:
+
+    {
+	    yyMonth = (yyvsp[(1) - (3)].Number);
+	    yyDay = (yyvsp[(3) - (3)].Number);
+	;}
+    break;
+
+  case 27:
+
+    {
+	    yyMonth = (yyvsp[(1) - (5)].Number);
+	    yyDay = (yyvsp[(3) - (5)].Number);
+	    yyYear = (yyvsp[(5) - (5)].Number);
+	;}
+    break;
+
+  case 28:
+
+    {
+	    yyYear = (yyvsp[(1) - (1)].Number) / 10000;
+	    yyMonth = ((yyvsp[(1) - (1)].Number) % 10000)/100;
+	    yyDay = (yyvsp[(1) - (1)].Number) % 100;
+	;}
+    break;
+
+  case 29:
+
+    {
+	    yyDay = (yyvsp[(1) - (5)].Number);
+	    yyMonth = (yyvsp[(3) - (5)].Number);
+	    yyYear = (yyvsp[(5) - (5)].Number);
+	;}
+    break;
+
+  case 30:
+
+    {
+	    yyMonth = (yyvsp[(3) - (5)].Number);
+	    yyDay = (yyvsp[(5) - (5)].Number);
+	    yyYear = (yyvsp[(1) - (5)].Number);
+	;}
+    break;
+
+  case 31:
+
+    {
+	    yyMonth = (yyvsp[(1) - (2)].Number);
+	    yyDay = (yyvsp[(2) - (2)].Number);
+	;}
+    break;
+
+  case 32:
+
+    {
+	    yyMonth = (yyvsp[(1) - (4)].Number);
+	    yyDay = (yyvsp[(2) - (4)].Number);
+	    yyYear = (yyvsp[(4) - (4)].Number);
+	;}
+    break;
+
+  case 33:
+
+    {
+	    yyMonth = (yyvsp[(2) - (2)].Number);
+	    yyDay = (yyvsp[(1) - (2)].Number);
+	;}
+    break;
+
+  case 34:
+
+    {
+	    yyMonth = 1;
+	    yyDay = 1;
+	    yyYear = EPOCH;
+	;}
+    break;
+
+  case 35:
+
+    {
+	    yyMonth = (yyvsp[(2) - (3)].Number);
+	    yyDay = (yyvsp[(1) - (3)].Number);
+	    yyYear = (yyvsp[(3) - (3)].Number);
+	;}
+    break;
+
+  case 36:
+
+    {
+	    yyMonthOrdinal = 1;
+	    yyMonth = (yyvsp[(2) - (2)].Number);
+	;}
+    break;
+
+  case 37:
+
+    {
+	    yyMonthOrdinal = (yyvsp[(2) - (3)].Number);
+	    yyMonth = (yyvsp[(3) - (3)].Number);
+	;}
+    break;
+
+  case 38:
+
+    {
+	    if ((yyvsp[(2) - (3)].Number) != HOUR( 7)) YYABORT;
+	    yyYear = (yyvsp[(1) - (3)].Number) / 10000;
+	    yyMonth = ((yyvsp[(1) - (3)].Number) % 10000)/100;
+	    yyDay = (yyvsp[(1) - (3)].Number) % 100;
+	    yyHour = (yyvsp[(3) - (3)].Number) / 10000;
+	    yyMinutes = ((yyvsp[(3) - (3)].Number) % 10000)/100;
+	    yySeconds = (yyvsp[(3) - (3)].Number) % 100;
+	;}
+    break;
+
+  case 39:
+
+    {
+	    if ((yyvsp[(2) - (7)].Number) != HOUR( 7)) YYABORT;
+	    yyYear = (yyvsp[(1) - (7)].Number) / 10000;
+	    yyMonth = ((yyvsp[(1) - (7)].Number) % 10000)/100;
+	    yyDay = (yyvsp[(1) - (7)].Number) % 100;
+	    yyHour = (yyvsp[(3) - (7)].Number);
+	    yyMinutes = (yyvsp[(5) - (7)].Number);
+	    yySeconds = (yyvsp[(7) - (7)].Number);
+	;}
+    break;
+
+  case 40:
+
+    {
+	    yyYear = (yyvsp[(1) - (2)].Number) / 10000;
+	    yyMonth = ((yyvsp[(1) - (2)].Number) % 10000)/100;
+	    yyDay = (yyvsp[(1) - (2)].Number) % 100;
+	    yyHour = (yyvsp[(2) - (2)].Number) / 10000;
+	    yyMinutes = ((yyvsp[(2) - (2)].Number) % 10000)/100;
+	    yySeconds = (yyvsp[(2) - (2)].Number) % 100;
+	;}
+    break;
+
+  case 41:
+
+    {
+	    /*
+	     * Offset computed year by -377 so that the returned years will be
+	     * in a range accessible with a 32 bit clock seconds value.
+	     */
+
+	    yyYear = (yyvsp[(2) - (4)].Number)/1000 + 2323 - 377;
+	    yyDay  = 1;
+	    yyMonth = 1;
+	    yyRelDay += (((yyvsp[(2) - (4)].Number)%1000)*(365 + IsLeapYear(yyYear)))/1000;
+	    yyRelSeconds += (yyvsp[(4) - (4)].Number) * 144 * 60;
+	;}
+    break;
+
+  case 42:
+
+    {
+	    yyRelSeconds *= -1;
+	    yyRelMonth *= -1;
+	    yyRelDay *= -1;
+	;}
+    break;
+
+  case 44:
+
+    {
+	    *yyRelPointer += (yyvsp[(1) - (3)].Number) * (yyvsp[(2) - (3)].Number) * (yyvsp[(3) - (3)].Number);
+	;}
+    break;
+
+  case 45:
+
+    {
+	    *yyRelPointer += (yyvsp[(1) - (2)].Number) * (yyvsp[(2) - (2)].Number);
+	;}
+    break;
+
+  case 46:
+
+    {
+	    *yyRelPointer += (yyvsp[(2) - (2)].Number);
+	;}
+    break;
+
+  case 47:
+
+    {
+	    *yyRelPointer += (yyvsp[(2) - (3)].Number) * (yyvsp[(3) - (3)].Number);
+	;}
+    break;
+
+  case 48:
+
+    {
+	    *yyRelPointer += (yyvsp[(1) - (1)].Number);
+	;}
+    break;
+
+  case 49:
+
+    {
+	    (yyval.Number) = -1;
+	;}
+    break;
+
+  case 50:
+
+    {
+	    (yyval.Number) =  1;
+	;}
+    break;
+
+  case 51:
+
+    {
+	    (yyval.Number) = (yyvsp[(1) - (1)].Number);
+	    yyRelPointer = &yyRelSeconds;
+	;}
+    break;
+
+  case 52:
+
+    {
+	    (yyval.Number) = (yyvsp[(1) - (1)].Number);
+	    yyRelPointer = &yyRelDay;
+	;}
+    break;
+
+  case 53:
+
+    {
+	    (yyval.Number) = (yyvsp[(1) - (1)].Number);
+	    yyRelPointer = &yyRelMonth;
+	;}
+    break;
+
+  case 54:
+
+    {
+	    if (yyHaveTime && yyHaveDate && !yyHaveRel) {
+		yyYear = (yyvsp[(1) - (1)].Number);
+	    } else {
+		yyHaveTime++;
+		if (yyDigitCount <= 2) {
+		    yyHour = (yyvsp[(1) - (1)].Number);
+		    yyMinutes = 0;
+		} else {
+		    yyHour = (yyvsp[(1) - (1)].Number) / 100;
+		    yyMinutes = (yyvsp[(1) - (1)].Number) % 100;
+		}
+		yySeconds = 0;
+		yyMeridian = MER24;
+	    }
+	;}
+    break;
+
+  case 55:
+
+    {
+	    (yyval.Meridian) = MER24;
+	;}
+    break;
+
+  case 56:
+
+    {
+	    (yyval.Meridian) = (yyvsp[(1) - (1)].Meridian);
+	;}
+    break;
+
+
+/* Line 1267 of yacc.c.  */
+
+      default: break;
+    }
+  YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
+
+  YYPOPSTACK (yylen);
+  yylen = 0;
+  YY_STACK_PRINT (yyss, yyssp);
+
+  *++yyvsp = yyval;
+  *++yylsp = yyloc;
+
+  /* Now `shift' the result of the reduction.  Determine what state
+     that goes to, based on the state we popped back to and the rule
+     number reduced by.  */
+
+  yyn = yyr1[yyn];
+
+  yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
+  if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
+    yystate = yytable[yystate];
+  else
+    yystate = yydefgoto[yyn - YYNTOKENS];
+
+  goto yynewstate;
+
+
+/*------------------------------------.
+| yyerrlab -- here on detecting error |
+`------------------------------------*/
+yyerrlab:
+  /* If not already recovering from an error, report this error.  */
+  if (!yyerrstatus)
+    {
+      ++yynerrs;
+#if ! YYERROR_VERBOSE
+      yyerror (&yylloc, info, YY_("syntax error"));
+#else
+      {
+	YYSIZE_T yysize = yysyntax_error (0, yystate, yychar);
+	if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM)
+	  {
+	    YYSIZE_T yyalloc = 2 * yysize;
+	    if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM))
+	      yyalloc = YYSTACK_ALLOC_MAXIMUM;
+	    if (yymsg != yymsgbuf)
+	      YYSTACK_FREE (yymsg);
+	    yymsg = (char *) YYSTACK_ALLOC (yyalloc);
+	    if (yymsg)
+	      yymsg_alloc = yyalloc;
+	    else
+	      {
+		yymsg = yymsgbuf;
+		yymsg_alloc = sizeof yymsgbuf;
+	      }
+	  }
+
+	if (0 < yysize && yysize <= yymsg_alloc)
+	  {
+	    (void) yysyntax_error (yymsg, yystate, yychar);
+	    yyerror (&yylloc, info, yymsg);
+	  }
+	else
+	  {
+	    yyerror (&yylloc, info, YY_("syntax error"));
+	    if (yysize != 0)
+	      goto yyexhaustedlab;
+	  }
+      }
+#endif
+    }
+
+  yyerror_range[0] = yylloc;
+
+  if (yyerrstatus == 3)
+    {
+      /* If just tried and failed to reuse look-ahead token after an
+	 error, discard it.  */
+
+      if (yychar <= YYEOF)
+	{
+	  /* Return failure if at end of input.  */
+	  if (yychar == YYEOF)
+	    YYABORT;
+	}
+      else
+	{
+	  yydestruct ("Error: discarding",
+		      yytoken, &yylval, &yylloc, info);
+	  yychar = YYEMPTY;
+	}
+    }
+
+  /* Else will try to reuse look-ahead token after shifting the error
+     token.  */
+  goto yyerrlab1;
+
+
+/*---------------------------------------------------.
+| yyerrorlab -- error raised explicitly by YYERROR.  |
+`---------------------------------------------------*/
+yyerrorlab:
+
+  /* Pacify compilers like GCC when the user code never invokes
+     YYERROR and the label yyerrorlab therefore never appears in user
+     code.  */
+  if (/*CONSTCOND*/ 0)
+     goto yyerrorlab;
+
+  yyerror_range[0] = yylsp[1-yylen];
+  /* Do not reclaim the symbols of the rule which action triggered
+     this YYERROR.  */
+  YYPOPSTACK (yylen);
+  yylen = 0;
+  YY_STACK_PRINT (yyss, yyssp);
+  yystate = *yyssp;
+  goto yyerrlab1;
+
+
+/*-------------------------------------------------------------.
+| yyerrlab1 -- common code for both syntax error and YYERROR.  |
+`-------------------------------------------------------------*/
+yyerrlab1:
+  yyerrstatus = 3;	/* Each real token shifted decrements this.  */
+
+  for (;;)
+    {
+      yyn = yypact[yystate];
+      if (yyn != YYPACT_NINF)
+	{
+	  yyn += YYTERROR;
+	  if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
+	    {
+	      yyn = yytable[yyn];
+	      if (0 < yyn)
+		break;
+	    }
+	}
+
+      /* Pop the current state because it cannot handle the error token.  */
+      if (yyssp == yyss)
+	YYABORT;
+
+      yyerror_range[0] = *yylsp;
+      yydestruct ("Error: popping",
+		  yystos[yystate], yyvsp, yylsp, info);
+      YYPOPSTACK (1);
+      yystate = *yyssp;
+      YY_STACK_PRINT (yyss, yyssp);
+    }
+
+  if (yyn == YYFINAL)
+    YYACCEPT;
+
+  *++yyvsp = yylval;
+
+  yyerror_range[1] = yylloc;
+  /* Using YYLLOC is tempting, but would change the location of
+     the look-ahead.  YYLOC is available though.  */
+  YYLLOC_DEFAULT (yyloc, (yyerror_range - 1), 2);
+  *++yylsp = yyloc;
+
+  /* Shift the error token.  */
+  YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp);
+
+  yystate = yyn;
+  goto yynewstate;
+
+
+/*-------------------------------------.
+| yyacceptlab -- YYACCEPT comes here.  |
+`-------------------------------------*/
+yyacceptlab:
+  yyresult = 0;
+  goto yyreturn;
+
+/*-----------------------------------.
+| yyabortlab -- YYABORT comes here.  |
+`-----------------------------------*/
+yyabortlab:
+  yyresult = 1;
+  goto yyreturn;
+
+#ifndef yyoverflow
+/*-------------------------------------------------.
+| yyexhaustedlab -- memory exhaustion comes here.  |
+`-------------------------------------------------*/
+yyexhaustedlab:
+  yyerror (&yylloc, info, YY_("memory exhausted"));
+  yyresult = 2;
+  /* Fall through.  */
+#endif
+
+yyreturn:
+  if (yychar != YYEOF && yychar != YYEMPTY)
+     yydestruct ("Cleanup: discarding lookahead",
+		 yytoken, &yylval, &yylloc, info);
+  /* Do not reclaim the symbols of the rule which action triggered
+     this YYABORT or YYACCEPT.  */
+  YYPOPSTACK (yylen);
+  YY_STACK_PRINT (yyss, yyssp);
+  while (yyssp != yyss)
+    {
+      yydestruct ("Cleanup: popping",
+		  yystos[*yyssp], yyvsp, yylsp, info);
+      YYPOPSTACK (1);
+    }
+#ifndef yyoverflow
+  if (yyss != yyssa)
+    YYSTACK_FREE (yyss);
+#endif
+#if YYERROR_VERBOSE
+  if (yymsg != yymsgbuf)
+    YYSTACK_FREE (yymsg);
+#endif
+  /* Make sure YYID is used.  */
+  return YYID (yyresult);
+}
+
+
+
+
+/*
+ * Month and day table.
+ */
+
+static const TABLE MonthDayTable[] = {
+    { "january",	tMONTH,	 1 },
+    { "february",	tMONTH,	 2 },
+    { "march",		tMONTH,	 3 },
+    { "april",		tMONTH,	 4 },
+    { "may",		tMONTH,	 5 },
+    { "june",		tMONTH,	 6 },
+    { "july",		tMONTH,	 7 },
+    { "august",		tMONTH,	 8 },
+    { "september",	tMONTH,	 9 },
+    { "sept",		tMONTH,	 9 },
+    { "october",	tMONTH, 10 },
+    { "november",	tMONTH, 11 },
+    { "december",	tMONTH, 12 },
+    { "sunday",		tDAY, 0 },
+    { "monday",		tDAY, 1 },
+    { "tuesday",	tDAY, 2 },
+    { "tues",		tDAY, 2 },
+    { "wednesday",	tDAY, 3 },
+    { "wednes",		tDAY, 3 },
+    { "thursday",	tDAY, 4 },
+    { "thur",		tDAY, 4 },
+    { "thurs",		tDAY, 4 },
+    { "friday",		tDAY, 5 },
+    { "saturday",	tDAY, 6 },
+    { NULL, 0, 0 }
+};
+
+/*
+ * Time units table.
+ */
+
+static const TABLE UnitsTable[] = {
+    { "year",		tMONTH_UNIT,	12 },
+    { "month",		tMONTH_UNIT,	 1 },
+    { "fortnight",	tDAY_UNIT,	14 },
+    { "week",		tDAY_UNIT,	 7 },
+    { "day",		tDAY_UNIT,	 1 },
+    { "hour",		tSEC_UNIT, 60 * 60 },
+    { "minute",		tSEC_UNIT,	60 },
+    { "min",		tSEC_UNIT,	60 },
+    { "second",		tSEC_UNIT,	 1 },
+    { "sec",		tSEC_UNIT,	 1 },
+    { NULL, 0, 0 }
+};
+
+/*
+ * Assorted relative-time words.
+ */
+
+static const TABLE OtherTable[] = {
+    { "tomorrow",	tDAY_UNIT,	1 },
+    { "yesterday",	tDAY_UNIT,	-1 },
+    { "today",		tDAY_UNIT,	0 },
+    { "now",		tSEC_UNIT,	0 },
+    { "last",		tUNUMBER,	-1 },
+    { "this",		tSEC_UNIT,	0 },
+    { "next",		tNEXT,		1 },
+#if 0
+    { "first",		tUNUMBER,	1 },
+    { "second",		tUNUMBER,	2 },
+    { "third",		tUNUMBER,	3 },
+    { "fourth",		tUNUMBER,	4 },
+    { "fifth",		tUNUMBER,	5 },
+    { "sixth",		tUNUMBER,	6 },
+    { "seventh",	tUNUMBER,	7 },
+    { "eighth",		tUNUMBER,	8 },
+    { "ninth",		tUNUMBER,	9 },
+    { "tenth",		tUNUMBER,	10 },
+    { "eleventh",	tUNUMBER,	11 },
+    { "twelfth",	tUNUMBER,	12 },
+#endif
+    { "ago",		tAGO,		1 },
+    { "epoch",		tEPOCH,		0 },
+    { "stardate",	tSTARDATE,	0 },
+    { NULL, 0, 0 }
+};
+
+/*
+ * The timezone table. (Note: This table was modified to not use any floating
+ * point constants to work around an SGI compiler bug).
+ */
+
+static const TABLE TimezoneTable[] = {
+    { "gmt",	tZONE,	   HOUR( 0) },	    /* Greenwich Mean */
+    { "ut",	tZONE,	   HOUR( 0) },	    /* Universal (Coordinated) */
+    { "utc",	tZONE,	   HOUR( 0) },
+    { "uct",	tZONE,	   HOUR( 0) },	    /* Universal Coordinated Time */
+    { "wet",	tZONE,	   HOUR( 0) },	    /* Western European */
+    { "bst",	tDAYZONE,  HOUR( 0) },	    /* British Summer */
+    { "wat",	tZONE,	   HOUR( 1) },	    /* West Africa */
+    { "at",	tZONE,	   HOUR( 2) },	    /* Azores */
+#if	0
+    /* For completeness.  BST is also British Summer, and GST is
+     * also Guam Standard. */
+    { "bst",	tZONE,	   HOUR( 3) },	    /* Brazil Standard */
+    { "gst",	tZONE,	   HOUR( 3) },	    /* Greenland Standard */
+#endif
+    { "nft",	tZONE,	   HOUR( 7/2) },    /* Newfoundland */
+    { "nst",	tZONE,	   HOUR( 7/2) },    /* Newfoundland Standard */
+    { "ndt",	tDAYZONE,  HOUR( 7/2) },    /* Newfoundland Daylight */
+    { "ast",	tZONE,	   HOUR( 4) },	    /* Atlantic Standard */
+    { "adt",	tDAYZONE,  HOUR( 4) },	    /* Atlantic Daylight */
+    { "est",	tZONE,	   HOUR( 5) },	    /* Eastern Standard */
+    { "edt",	tDAYZONE,  HOUR( 5) },	    /* Eastern Daylight */
+    { "cst",	tZONE,	   HOUR( 6) },	    /* Central Standard */
+    { "cdt",	tDAYZONE,  HOUR( 6) },	    /* Central Daylight */
+    { "mst",	tZONE,	   HOUR( 7) },	    /* Mountain Standard */
+    { "mdt",	tDAYZONE,  HOUR( 7) },	    /* Mountain Daylight */
+    { "pst",	tZONE,	   HOUR( 8) },	    /* Pacific Standard */
+    { "pdt",	tDAYZONE,  HOUR( 8) },	    /* Pacific Daylight */
+    { "yst",	tZONE,	   HOUR( 9) },	    /* Yukon Standard */
+    { "ydt",	tDAYZONE,  HOUR( 9) },	    /* Yukon Daylight */
+    { "hst",	tZONE,	   HOUR(10) },	    /* Hawaii Standard */
+    { "hdt",	tDAYZONE,  HOUR(10) },	    /* Hawaii Daylight */
+    { "cat",	tZONE,	   HOUR(10) },	    /* Central Alaska */
+    { "ahst",	tZONE,	   HOUR(10) },	    /* Alaska-Hawaii Standard */
+    { "nt",	tZONE,	   HOUR(11) },	    /* Nome */
+    { "idlw",	tZONE,	   HOUR(12) },	    /* International Date Line West */
+    { "cet",	tZONE,	  -HOUR( 1) },	    /* Central European */
+    { "cest",	tDAYZONE, -HOUR( 1) },	    /* Central European Summer */
+    { "met",	tZONE,	  -HOUR( 1) },	    /* Middle European */
+    { "mewt",	tZONE,	  -HOUR( 1) },	    /* Middle European Winter */
+    { "mest",	tDAYZONE, -HOUR( 1) },	    /* Middle European Summer */
+    { "swt",	tZONE,	  -HOUR( 1) },	    /* Swedish Winter */
+    { "sst",	tDAYZONE, -HOUR( 1) },	    /* Swedish Summer */
+    { "fwt",	tZONE,	  -HOUR( 1) },	    /* French Winter */
+    { "fst",	tDAYZONE, -HOUR( 1) },	    /* French Summer */
+    { "eet",	tZONE,	  -HOUR( 2) },	    /* Eastern Europe, USSR Zone 1 */
+    { "bt",	tZONE,	  -HOUR( 3) },	    /* Baghdad, USSR Zone 2 */
+    { "it",	tZONE,	  -HOUR( 7/2) },    /* Iran */
+    { "zp4",	tZONE,	  -HOUR( 4) },	    /* USSR Zone 3 */
+    { "zp5",	tZONE,	  -HOUR( 5) },	    /* USSR Zone 4 */
+    { "ist",	tZONE,	  -HOUR(11/2) },    /* Indian Standard */
+    { "zp6",	tZONE,	  -HOUR( 6) },	    /* USSR Zone 5 */
+#if	0
+    /* For completeness.  NST is also Newfoundland Stanard, nad SST is
+     * also Swedish Summer. */
+    { "nst",	tZONE,	  -HOUR(13/2) },    /* North Sumatra */
+    { "sst",	tZONE,	  -HOUR( 7) },	    /* South Sumatra, USSR Zone 6 */
+#endif	/* 0 */
+    { "wast",	tZONE,	  -HOUR( 7) },	    /* West Australian Standard */
+    { "wadt",	tDAYZONE, -HOUR( 7) },	    /* West Australian Daylight */
+    { "jt",	tZONE,	  -HOUR(15/2) },    /* Java (3pm in Cronusland!) */
+    { "cct",	tZONE,	  -HOUR( 8) },	    /* China Coast, USSR Zone 7 */
+    { "jst",	tZONE,	  -HOUR( 9) },	    /* Japan Standard, USSR Zone 8 */
+    { "jdt",	tDAYZONE, -HOUR( 9) },	    /* Japan Daylight */
+    { "kst",	tZONE,	  -HOUR( 9) },	    /* Korea Standard */
+    { "kdt",	tDAYZONE, -HOUR( 9) },	    /* Korea Daylight */
+    { "cast",	tZONE,	  -HOUR(19/2) },    /* Central Australian Standard */
+    { "cadt",	tDAYZONE, -HOUR(19/2) },    /* Central Australian Daylight */
+    { "east",	tZONE,	  -HOUR(10) },	    /* Eastern Australian Standard */
+    { "eadt",	tDAYZONE, -HOUR(10) },	    /* Eastern Australian Daylight */
+    { "gst",	tZONE,	  -HOUR(10) },	    /* Guam Standard, USSR Zone 9 */
+    { "nzt",	tZONE,	  -HOUR(12) },	    /* New Zealand */
+    { "nzst",	tZONE,	  -HOUR(12) },	    /* New Zealand Standard */
+    { "nzdt",	tDAYZONE, -HOUR(12) },	    /* New Zealand Daylight */
+    { "idle",	tZONE,	  -HOUR(12) },	    /* International Date Line East */
+    /* ADDED BY Marco Nijdam */
+    { "dst",	tDST,	  HOUR( 0) },	    /* DST on (hour is ignored) */
+    /* End ADDED */
+    { NULL, 0, 0 }
+};
+
+/*
+ * Military timezone table.
+ */
+
+static const TABLE MilitaryTable[] = {
+    { "a",	tZONE,	-HOUR( 1) },
+    { "b",	tZONE,	-HOUR( 2) },
+    { "c",	tZONE,	-HOUR( 3) },
+    { "d",	tZONE,	-HOUR( 4) },
+    { "e",	tZONE,	-HOUR( 5) },
+    { "f",	tZONE,	-HOUR( 6) },
+    { "g",	tZONE,	-HOUR( 7) },
+    { "h",	tZONE,	-HOUR( 8) },
+    { "i",	tZONE,	-HOUR( 9) },
+    { "k",	tZONE,	-HOUR(10) },
+    { "l",	tZONE,	-HOUR(11) },
+    { "m",	tZONE,	-HOUR(12) },
+    { "n",	tZONE,	HOUR(  1) },
+    { "o",	tZONE,	HOUR(  2) },
+    { "p",	tZONE,	HOUR(  3) },
+    { "q",	tZONE,	HOUR(  4) },
+    { "r",	tZONE,	HOUR(  5) },
+    { "s",	tZONE,	HOUR(  6) },
+    { "t",	tZONE,	HOUR(  7) },
+    { "u",	tZONE,	HOUR(  8) },
+    { "v",	tZONE,	HOUR(  9) },
+    { "w",	tZONE,	HOUR( 10) },
+    { "x",	tZONE,	HOUR( 11) },
+    { "y",	tZONE,	HOUR( 12) },
+    { "z",	tZONE,	HOUR( 0) },
+    { NULL, 0, 0 }
+};
+
+/*
+ * Dump error messages in the bit bucket.
+ */
+
+static void
+TclDateerror(
+    YYLTYPE* location,
+    DateInfo* infoPtr,
+    const char *s)
+{
+    Tcl_Obj* t;
+    Tcl_AppendToObj(infoPtr->messages, infoPtr->separatrix, -1);
+    Tcl_AppendToObj(infoPtr->messages, s, -1);
+    Tcl_AppendToObj(infoPtr->messages, " (characters ", -1);
+    t = Tcl_NewIntObj(location->first_column);
+    Tcl_IncrRefCount(t);
+    Tcl_AppendObjToObj(infoPtr->messages, t);
+    Tcl_DecrRefCount(t);
+    Tcl_AppendToObj(infoPtr->messages, "-", -1);
+    t = Tcl_NewIntObj(location->last_column);
+    Tcl_IncrRefCount(t);
+    Tcl_AppendObjToObj(infoPtr->messages, t);
+    Tcl_DecrRefCount(t);
+    Tcl_AppendToObj(infoPtr->messages, ")", -1);
+    infoPtr->separatrix = "\n";
+}
+
+static time_t
+ToSeconds(
+    time_t Hours,
+    time_t Minutes,
+    time_t Seconds,
+    MERIDIAN Meridian)
+{
+    if (Minutes < 0 || Minutes > 59 || Seconds < 0 || Seconds > 59) {
+	return -1;
+    }
+    switch (Meridian) {
+    case MER24:
+	if (Hours < 0 || Hours > 23) {
+	    return -1;
+	}
+	return (Hours * 60L + Minutes) * 60L + Seconds;
+    case MERam:
+	if (Hours < 1 || Hours > 12) {
+	    return -1;
+	}
+	return ((Hours % 12) * 60L + Minutes) * 60L + Seconds;
+    case MERpm:
+	if (Hours < 1 || Hours > 12) {
+	    return -1;
+	}
+	return (((Hours % 12) + 12) * 60L + Minutes) * 60L + Seconds;
+    }
+    return -1;			/* Should never be reached */
+}
+
+static int
+LookupWord(
+    YYSTYPE* yylvalPtr,
+    char *buff)
+{
+    register char *p;
+    register char *q;
+    register const TABLE *tp;
+    int i, abbrev;
+
+    /*
+     * Make it lowercase.
+     */
+
+    Tcl_UtfToLower(buff);
+
+    if (strcmp(buff, "am") == 0 || strcmp(buff, "a.m.") == 0) {
+	yylvalPtr->Meridian = MERam;
+	return tMERIDIAN;
+    }
+    if (strcmp(buff, "pm") == 0 || strcmp(buff, "p.m.") == 0) {
+	yylvalPtr->Meridian = MERpm;
+	return tMERIDIAN;
+    }
+
+    /*
+     * See if we have an abbreviation for a month.
+     */
+
+    if (strlen(buff) == 3) {
+	abbrev = 1;
+    } else if (strlen(buff) == 4 && buff[3] == '.') {
+	abbrev = 1;
+	buff[3] = '\0';
+    } else {
+	abbrev = 0;
+    }
+
+    for (tp = MonthDayTable; tp->name; tp++) {
+	if (abbrev) {
+	    if (strncmp(buff, tp->name, 3) == 0) {
+		yylvalPtr->Number = tp->value;
+		return tp->type;
+	    }
+	} else if (strcmp(buff, tp->name) == 0) {
+	    yylvalPtr->Number = tp->value;
+	    return tp->type;
+	}
+    }
+
+    for (tp = TimezoneTable; tp->name; tp++) {
+	if (strcmp(buff, tp->name) == 0) {
+	    yylvalPtr->Number = tp->value;
+	    return tp->type;
+	}
+    }
+
+    for (tp = UnitsTable; tp->name; tp++) {
+	if (strcmp(buff, tp->name) == 0) {
+	    yylvalPtr->Number = tp->value;
+	    return tp->type;
+	}
+    }
+
+    /*
+     * Strip off any plural and try the units table again.
+     */
+
+    i = strlen(buff) - 1;
+    if (i > 0 && buff[i] == 's') {
+	buff[i] = '\0';
+	for (tp = UnitsTable; tp->name; tp++) {
+	    if (strcmp(buff, tp->name) == 0) {
+		yylvalPtr->Number = tp->value;
+		return tp->type;
+	    }
+	}
+    }
+
+    for (tp = OtherTable; tp->name; tp++) {
+	if (strcmp(buff, tp->name) == 0) {
+	    yylvalPtr->Number = tp->value;
+	    return tp->type;
+	}
+    }
+
+    /*
+     * Military timezones.
+     */
+
+    if (buff[1] == '\0' && !(*buff & 0x80)
+	    && isalpha(UCHAR(*buff))) {			/* INTL: ISO only */
+	for (tp = MilitaryTable; tp->name; tp++) {
+	    if (strcmp(buff, tp->name) == 0) {
+		yylvalPtr->Number = tp->value;
+		return tp->type;
+	    }
+	}
+    }
+
+    /*
+     * Drop out any periods and try the timezone table again.
+     */
+
+    for (i = 0, p = q = buff; *q; q++) {
+	if (*q != '.') {
+	    *p++ = *q;
+	} else {
+	    i++;
+	}
+    }
+    *p = '\0';
+    if (i) {
+	for (tp = TimezoneTable; tp->name; tp++) {
+	    if (strcmp(buff, tp->name) == 0) {
+		yylvalPtr->Number = tp->value;
+		return tp->type;
+	    }
+	}
+    }
+
+    return tID;
+}
+
+static int
+TclDatelex(
+    YYSTYPE* yylvalPtr,
+    YYLTYPE* location,
+    DateInfo *info)
+{
+    register char c;
+    register char *p;
+    char buff[20];
+    int Count;
+
+    location->first_column = yyInput - info->dateStart;
+    for ( ; ; ) {
+	while (TclIsSpaceProc(*yyInput)) {
+	    yyInput++;
+	}
+
+	if (isdigit(UCHAR(c = *yyInput))) { /* INTL: digit */
+	    /*
+	     * Convert the string into a number; count the number of digits.
+	     */
+
+	    Count = 0;
+	    for (yylvalPtr->Number = 0;
+		    isdigit(UCHAR(c = *yyInput++)); ) {	  /* INTL: digit */
+		yylvalPtr->Number = 10 * yylvalPtr->Number + c - '0';
+		Count++;
+	    }
+	    yyInput--;
+	    yyDigitCount = Count;
+
+	    /*
+	     * A number with 6 or more digits is considered an ISO 8601 base.
+	     */
+
+	    if (Count >= 6) {
+		location->last_column = yyInput - info->dateStart - 1;
+		return tISOBASE;
+	    } else {
+		location->last_column = yyInput - info->dateStart - 1;
+		return tUNUMBER;
+	    }
+	}
+	if (!(c & 0x80) && isalpha(UCHAR(c))) {		  /* INTL: ISO only. */
+	    for (p = buff; isalpha(UCHAR(c = *yyInput++)) /* INTL: ISO only. */
+		     || c == '.'; ) {
+		if (p < &buff[sizeof buff - 1]) {
+		    *p++ = c;
+		}
+	    }
+	    *p = '\0';
+	    yyInput--;
+	    location->last_column = yyInput - info->dateStart - 1;
+	    return LookupWord(yylvalPtr, buff);
+	}
+	if (c != '(') {
+	    location->last_column = yyInput - info->dateStart;
+	    return *yyInput++;
+	}
+	Count = 0;
+	do {
+	    c = *yyInput++;
+	    if (c == '\0') {
+		location->last_column = yyInput - info->dateStart - 1;
+		return c;
+	    } else if (c == '(') {
+		Count++;
+	    } else if (c == ')') {
+		Count--;
+	    }
+	} while (Count > 0);
+    }
+}
+
+int
+TclClockOldscanObjCmd(
+    ClientData clientData,	/* Unused */
+    Tcl_Interp *interp,		/* Tcl interpreter */
+    int objc,			/* Count of paraneters */
+    Tcl_Obj *const *objv)	/* Parameters */
+{
+    Tcl_Obj *result, *resultElement;
+    int yr, mo, da;
+    DateInfo dateInfo;
+    DateInfo* info = &dateInfo;
+    int status;
+
+    if (objc != 5) {
+	Tcl_WrongNumArgs(interp, 1, objv,
+		"stringToParse baseYear baseMonth baseDay" );
+	return TCL_ERROR;
+    }
+
+    yyInput = Tcl_GetString( objv[1] );
+    dateInfo.dateStart = yyInput;
+
+    yyHaveDate = 0;
+    if (Tcl_GetIntFromObj(interp, objv[2], &yr) != TCL_OK
+	    || Tcl_GetIntFromObj(interp, objv[3], &mo) != TCL_OK
+	    || Tcl_GetIntFromObj(interp, objv[4], &da) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    yyYear = yr; yyMonth = mo; yyDay = da;
+
+    yyHaveTime = 0;
+    yyHour = 0; yyMinutes = 0; yySeconds = 0; yyMeridian = MER24;
+
+    yyHaveZone = 0;
+    yyTimezone = 0; yyDSTmode = DSTmaybe;
+
+    yyHaveOrdinalMonth = 0;
+    yyMonthOrdinal = 0;
+
+    yyHaveDay = 0;
+    yyDayOrdinal = 0; yyDayNumber = 0;
+
+    yyHaveRel = 0;
+    yyRelMonth = 0; yyRelDay = 0; yyRelSeconds = 0; yyRelPointer = NULL;
+
+    dateInfo.messages = Tcl_NewObj();
+    dateInfo.separatrix = "";
+    Tcl_IncrRefCount(dateInfo.messages);
+
+    status = yyparse(&dateInfo);
+    if (status == 1) {
+	Tcl_SetObjResult(interp, dateInfo.messages);
+	Tcl_DecrRefCount(dateInfo.messages);
+	Tcl_SetErrorCode(interp, "TCL", "VALUE", "DATE", "PARSE", NULL);
+	return TCL_ERROR;
+    } else if (status == 2) {
+	Tcl_SetObjResult(interp, Tcl_NewStringObj("memory exhausted", -1));
+	Tcl_DecrRefCount(dateInfo.messages);
+	Tcl_SetErrorCode(interp, "TCL", "MEMORY", NULL);
+	return TCL_ERROR;
+    } else if (status != 0) {
+	Tcl_SetObjResult(interp, Tcl_NewStringObj("Unknown status returned "
+						  "from date parser. Please "
+						  "report this error as a "
+						  "bug in Tcl.", -1));
+	Tcl_DecrRefCount(dateInfo.messages);
+	Tcl_SetErrorCode(interp, "TCL", "BUG", NULL);
+	return TCL_ERROR;
+    }
+    Tcl_DecrRefCount(dateInfo.messages);
+
+    if (yyHaveDate > 1) {
+	Tcl_SetObjResult(interp,
+		Tcl_NewStringObj("more than one date in string", -1));
+	Tcl_SetErrorCode(interp, "TCL", "VALUE", "DATE", "MULTIPLE", NULL);
+	return TCL_ERROR;
+    }
+    if (yyHaveTime > 1) {
+	Tcl_SetObjResult(interp,
+		Tcl_NewStringObj("more than one time of day in string", -1));
+	Tcl_SetErrorCode(interp, "TCL", "VALUE", "DATE", "MULTIPLE", NULL);
+	return TCL_ERROR;
+    }
+    if (yyHaveZone > 1) {
+	Tcl_SetObjResult(interp,
+		Tcl_NewStringObj("more than one time zone in string", -1));
+	Tcl_SetErrorCode(interp, "TCL", "VALUE", "DATE", "MULTIPLE", NULL);
+	return TCL_ERROR;
+    }
+    if (yyHaveDay > 1) {
+	Tcl_SetObjResult(interp,
+		Tcl_NewStringObj("more than one weekday in string", -1));
+	Tcl_SetErrorCode(interp, "TCL", "VALUE", "DATE", "MULTIPLE", NULL);
+	return TCL_ERROR;
+    }
+    if (yyHaveOrdinalMonth > 1) {
+	Tcl_SetObjResult(interp,
+		Tcl_NewStringObj("more than one ordinal month in string", -1));
+	Tcl_SetErrorCode(interp, "TCL", "VALUE", "DATE", "MULTIPLE", NULL);
+	return TCL_ERROR;
+    }
+
+    result = Tcl_NewObj();
+    resultElement = Tcl_NewObj();
+    if (yyHaveDate) {
+	Tcl_ListObjAppendElement(interp, resultElement,
+		Tcl_NewIntObj((int) yyYear));
+	Tcl_ListObjAppendElement(interp, resultElement,
+		Tcl_NewIntObj((int) yyMonth));
+	Tcl_ListObjAppendElement(interp, resultElement,
+		Tcl_NewIntObj((int) yyDay));
+    }
+    Tcl_ListObjAppendElement(interp, result, resultElement);
+
+    if (yyHaveTime) {
+	Tcl_ListObjAppendElement(interp, result, Tcl_NewIntObj((int)
+		ToSeconds(yyHour, yyMinutes, yySeconds, yyMeridian)));
+    } else {
+	Tcl_ListObjAppendElement(interp, result, Tcl_NewObj());
+    }
+
+    resultElement = Tcl_NewObj();
+    if (yyHaveZone) {
+	Tcl_ListObjAppendElement(interp, resultElement,
+		Tcl_NewIntObj((int) -yyTimezone));
+	Tcl_ListObjAppendElement(interp, resultElement,
+		Tcl_NewIntObj(1 - yyDSTmode));
+    }
+    Tcl_ListObjAppendElement(interp, result, resultElement);
+
+    resultElement = Tcl_NewObj();
+    if (yyHaveRel) {
+	Tcl_ListObjAppendElement(interp, resultElement,
+		Tcl_NewIntObj((int) yyRelMonth));
+	Tcl_ListObjAppendElement(interp, resultElement,
+		Tcl_NewIntObj((int) yyRelDay));
+	Tcl_ListObjAppendElement(interp, resultElement,
+		Tcl_NewIntObj((int) yyRelSeconds));
+    }
+    Tcl_ListObjAppendElement(interp, result, resultElement);
+
+    resultElement = Tcl_NewObj();
+    if (yyHaveDay && !yyHaveDate) {
+	Tcl_ListObjAppendElement(interp, resultElement,
+		Tcl_NewIntObj((int) yyDayOrdinal));
+	Tcl_ListObjAppendElement(interp, resultElement,
+		Tcl_NewIntObj((int) yyDayNumber));
+    }
+    Tcl_ListObjAppendElement(interp, result, resultElement);
+
+    resultElement = Tcl_NewObj();
+    if (yyHaveOrdinalMonth) {
+	Tcl_ListObjAppendElement(interp, resultElement,
+		Tcl_NewIntObj((int) yyMonthOrdinal));
+	Tcl_ListObjAppendElement(interp, resultElement,
+		Tcl_NewIntObj((int) yyMonth));
+    }
+    Tcl_ListObjAppendElement(interp, result, resultElement);
+
+    Tcl_SetObjResult(interp, result);
+    return TCL_OK;
+}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
+
diff --git a/generic/tclDecls.h b/generic/tclDecls.h
new file mode 100644
index 0000000..b022d3c
--- /dev/null
+++ b/generic/tclDecls.h
@@ -0,0 +1,3918 @@
+/*
+ * tclDecls.h --
+ *
+ *	Declarations of functions in the platform independent public Tcl API.
+ *
+ * Copyright (c) 1998-1999 by Scriptics Corporation.
+ *
+ * See the file "license.terms" for information on usage and redistribution
+ * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#ifndef _TCLDECLS
+#define _TCLDECLS
+
+#undef TCL_STORAGE_CLASS
+#ifdef BUILD_tcl
+#   define TCL_STORAGE_CLASS DLLEXPORT
+#else
+#   ifdef USE_TCL_STUBS
+#      define TCL_STORAGE_CLASS
+#   else
+#      define TCL_STORAGE_CLASS DLLIMPORT
+#   endif
+#endif
+
+/*
+ * WARNING: This file is automatically generated by the tools/genStubs.tcl
+ * script.  Any modifications to the function declarations below should be made
+ * in the generic/tcl.decls script.
+ */
+
+/* !BEGIN!: Do not edit below this line. */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Exported function declarations:
+ */
+
+/* 0 */
+EXTERN int		Tcl_PkgProvideEx(Tcl_Interp *interp,
+				const char *name, const char *version,
+				const void *clientData);
+/* 1 */
+EXTERN CONST84_RETURN char * Tcl_PkgRequireEx(Tcl_Interp *interp,
+				const char *name, const char *version,
+				int exact, void *clientDataPtr);
+/* 2 */
+EXTERN TCL_NORETURN void Tcl_Panic(const char *format, ...) TCL_FORMAT_PRINTF(1, 2);
+/* 3 */
+EXTERN char *		Tcl_Alloc(unsigned int size);
+/* 4 */
+EXTERN void		Tcl_Free(char *ptr);
+/* 5 */
+EXTERN char *		Tcl_Realloc(char *ptr, unsigned int size);
+/* 6 */
+EXTERN char *		Tcl_DbCkalloc(unsigned int size, const char *file,
+				int line);
+/* 7 */
+EXTERN void		Tcl_DbCkfree(char *ptr, const char *file, int line);
+/* 8 */
+EXTERN char *		Tcl_DbCkrealloc(char *ptr, unsigned int size,
+				const char *file, int line);
+#if !defined(_WIN32) && !defined(MAC_OSX_TCL) /* UNIX */
+/* 9 */
+EXTERN void		Tcl_CreateFileHandler(int fd, int mask,
+				Tcl_FileProc *proc, ClientData clientData);
+#endif /* UNIX */
+#ifdef MAC_OSX_TCL /* MACOSX */
+/* 9 */
+EXTERN void		Tcl_CreateFileHandler(int fd, int mask,
+				Tcl_FileProc *proc, ClientData clientData);
+#endif /* MACOSX */
+#if !defined(_WIN32) && !defined(MAC_OSX_TCL) /* UNIX */
+/* 10 */
+EXTERN void		Tcl_DeleteFileHandler(int fd);
+#endif /* UNIX */
+#ifdef MAC_OSX_TCL /* MACOSX */
+/* 10 */
+EXTERN void		Tcl_DeleteFileHandler(int fd);
+#endif /* MACOSX */
+/* 11 */
+EXTERN void		Tcl_SetTimer(const Tcl_Time *timePtr);
+/* 12 */
+EXTERN void		Tcl_Sleep(int ms);
+/* 13 */
+EXTERN int		Tcl_WaitForEvent(const Tcl_Time *timePtr);
+/* 14 */
+EXTERN int		Tcl_AppendAllObjTypes(Tcl_Interp *interp,
+				Tcl_Obj *objPtr);
+/* 15 */
+EXTERN void		Tcl_AppendStringsToObj(Tcl_Obj *objPtr, ...);
+/* 16 */
+EXTERN void		Tcl_AppendToObj(Tcl_Obj *objPtr, const char *bytes,
+				int length);
+/* 17 */
+EXTERN Tcl_Obj *	Tcl_ConcatObj(int objc, Tcl_Obj *const objv[]);
+/* 18 */
+EXTERN int		Tcl_ConvertToType(Tcl_Interp *interp,
+				Tcl_Obj *objPtr, const Tcl_ObjType *typePtr);
+/* 19 */
+EXTERN void		Tcl_DbDecrRefCount(Tcl_Obj *objPtr, const char *file,
+				int line);
+/* 20 */
+EXTERN void		Tcl_DbIncrRefCount(Tcl_Obj *objPtr, const char *file,
+				int line);
+/* 21 */
+EXTERN int		Tcl_DbIsShared(Tcl_Obj *objPtr, const char *file,
+				int line);
+/* 22 */
+EXTERN Tcl_Obj *	Tcl_DbNewBooleanObj(int boolValue, const char *file,
+				int line);
+/* 23 */
+EXTERN Tcl_Obj *	Tcl_DbNewByteArrayObj(const unsigned char *bytes,
+				int length, const char *file, int line);
+/* 24 */
+EXTERN Tcl_Obj *	Tcl_DbNewDoubleObj(double doubleValue,
+				const char *file, int line);
+/* 25 */
+EXTERN Tcl_Obj *	Tcl_DbNewListObj(int objc, Tcl_Obj *const *objv,
+				const char *file, int line);
+/* 26 */
+EXTERN Tcl_Obj *	Tcl_DbNewLongObj(long longValue, const char *file,
+				int line);
+/* 27 */
+EXTERN Tcl_Obj *	Tcl_DbNewObj(const char *file, int line);
+/* 28 */
+EXTERN Tcl_Obj *	Tcl_DbNewStringObj(const char *bytes, int length,
+				const char *file, int line);
+/* 29 */
+EXTERN Tcl_Obj *	Tcl_DuplicateObj(Tcl_Obj *objPtr);
+/* 30 */
+EXTERN void		TclFreeObj(Tcl_Obj *objPtr);
+/* 31 */
+EXTERN int		Tcl_GetBoolean(Tcl_Interp *interp, const char *src,
+				int *boolPtr);
+/* 32 */
+EXTERN int		Tcl_GetBooleanFromObj(Tcl_Interp *interp,
+				Tcl_Obj *objPtr, int *boolPtr);
+/* 33 */
+EXTERN unsigned char *	Tcl_GetByteArrayFromObj(Tcl_Obj *objPtr,
+				int *lengthPtr);
+/* 34 */
+EXTERN int		Tcl_GetDouble(Tcl_Interp *interp, const char *src,
+				double *doublePtr);
+/* 35 */
+EXTERN int		Tcl_GetDoubleFromObj(Tcl_Interp *interp,
+				Tcl_Obj *objPtr, double *doublePtr);
+/* 36 */
+EXTERN int		Tcl_GetIndexFromObj(Tcl_Interp *interp,
+				Tcl_Obj *objPtr,
+				CONST84 char *const *tablePtr,
+				const char *msg, int flags, int *indexPtr);
+/* 37 */
+EXTERN int		Tcl_GetInt(Tcl_Interp *interp, const char *src,
+				int *intPtr);
+/* 38 */
+EXTERN int		Tcl_GetIntFromObj(Tcl_Interp *interp,
+				Tcl_Obj *objPtr, int *intPtr);
+/* 39 */
+EXTERN int		Tcl_GetLongFromObj(Tcl_Interp *interp,
+				Tcl_Obj *objPtr, long *longPtr);
+/* 40 */
+EXTERN CONST86 Tcl_ObjType * Tcl_GetObjType(const char *typeName);
+/* 41 */
+EXTERN char *		Tcl_GetStringFromObj(Tcl_Obj *objPtr, int *lengthPtr);
+/* 42 */
+EXTERN void		Tcl_InvalidateStringRep(Tcl_Obj *objPtr);
+/* 43 */
+EXTERN int		Tcl_ListObjAppendList(Tcl_Interp *interp,
+				Tcl_Obj *listPtr, Tcl_Obj *elemListPtr);
+/* 44 */
+EXTERN int		Tcl_ListObjAppendElement(Tcl_Interp *interp,
+				Tcl_Obj *listPtr, Tcl_Obj *objPtr);
+/* 45 */
+EXTERN int		Tcl_ListObjGetElements(Tcl_Interp *interp,
+				Tcl_Obj *listPtr, int *objcPtr,
+				Tcl_Obj ***objvPtr);
+/* 46 */
+EXTERN int		Tcl_ListObjIndex(Tcl_Interp *interp,
+				Tcl_Obj *listPtr, int index,
+				Tcl_Obj **objPtrPtr);
+/* 47 */
+EXTERN int		Tcl_ListObjLength(Tcl_Interp *interp,
+				Tcl_Obj *listPtr, int *lengthPtr);
+/* 48 */
+EXTERN int		Tcl_ListObjReplace(Tcl_Interp *interp,
+				Tcl_Obj *listPtr, int first, int count,
+				int objc, Tcl_Obj *const objv[]);
+/* 49 */
+EXTERN Tcl_Obj *	Tcl_NewBooleanObj(int boolValue);
+/* 50 */
+EXTERN Tcl_Obj *	Tcl_NewByteArrayObj(const unsigned char *bytes,
+				int length);
+/* 51 */
+EXTERN Tcl_Obj *	Tcl_NewDoubleObj(double doubleValue);
+/* 52 */
+EXTERN Tcl_Obj *	Tcl_NewIntObj(int intValue);
+/* 53 */
+EXTERN Tcl_Obj *	Tcl_NewListObj(int objc, Tcl_Obj *const objv[]);
+/* 54 */
+EXTERN Tcl_Obj *	Tcl_NewLongObj(long longValue);
+/* 55 */
+EXTERN Tcl_Obj *	Tcl_NewObj(void);
+/* 56 */
+EXTERN Tcl_Obj *	Tcl_NewStringObj(const char *bytes, int length);
+/* 57 */
+EXTERN void		Tcl_SetBooleanObj(Tcl_Obj *objPtr, int boolValue);
+/* 58 */
+EXTERN unsigned char *	Tcl_SetByteArrayLength(Tcl_Obj *objPtr, int length);
+/* 59 */
+EXTERN void		Tcl_SetByteArrayObj(Tcl_Obj *objPtr,
+				const unsigned char *bytes, int length);
+/* 60 */
+EXTERN void		Tcl_SetDoubleObj(Tcl_Obj *objPtr, double doubleValue);
+/* 61 */
+EXTERN void		Tcl_SetIntObj(Tcl_Obj *objPtr, int intValue);
+/* 62 */
+EXTERN void		Tcl_SetListObj(Tcl_Obj *objPtr, int objc,
+				Tcl_Obj *const objv[]);
+/* 63 */
+EXTERN void		Tcl_SetLongObj(Tcl_Obj *objPtr, long longValue);
+/* 64 */
+EXTERN void		Tcl_SetObjLength(Tcl_Obj *objPtr, int length);
+/* 65 */
+EXTERN void		Tcl_SetStringObj(Tcl_Obj *objPtr, const char *bytes,
+				int length);
+/* 66 */
+EXTERN void		Tcl_AddErrorInfo(Tcl_Interp *interp,
+				const char *message);
+/* 67 */
+EXTERN void		Tcl_AddObjErrorInfo(Tcl_Interp *interp,
+				const char *message, int length);
+/* 68 */
+EXTERN void		Tcl_AllowExceptions(Tcl_Interp *interp);
+/* 69 */
+EXTERN void		Tcl_AppendElement(Tcl_Interp *interp,
+				const char *element);
+/* 70 */
+EXTERN void		Tcl_AppendResult(Tcl_Interp *interp, ...);
+/* 71 */
+EXTERN Tcl_AsyncHandler	 Tcl_AsyncCreate(Tcl_AsyncProc *proc,
+				ClientData clientData);
+/* 72 */
+EXTERN void		Tcl_AsyncDelete(Tcl_AsyncHandler async);
+/* 73 */
+EXTERN int		Tcl_AsyncInvoke(Tcl_Interp *interp, int code);
+/* 74 */
+EXTERN void		Tcl_AsyncMark(Tcl_AsyncHandler async);
+/* 75 */
+EXTERN int		Tcl_AsyncReady(void);
+/* 76 */
+EXTERN void		Tcl_BackgroundError(Tcl_Interp *interp);
+/* 77 */
+EXTERN char		Tcl_Backslash(const char *src, int *readPtr);
+/* 78 */
+EXTERN int		Tcl_BadChannelOption(Tcl_Interp *interp,
+				const char *optionName,
+				const char *optionList);
+/* 79 */
+EXTERN void		Tcl_CallWhenDeleted(Tcl_Interp *interp,
+				Tcl_InterpDeleteProc *proc,
+				ClientData clientData);
+/* 80 */
+EXTERN void		Tcl_CancelIdleCall(Tcl_IdleProc *idleProc,
+				ClientData clientData);
+/* 81 */
+EXTERN int		Tcl_Close(Tcl_Interp *interp, Tcl_Channel chan);
+/* 82 */
+EXTERN int		Tcl_CommandComplete(const char *cmd);
+/* 83 */
+EXTERN char *		Tcl_Concat(int argc, CONST84 char *const *argv);
+/* 84 */
+EXTERN int		Tcl_ConvertElement(const char *src, char *dst,
+				int flags);
+/* 85 */
+EXTERN int		Tcl_ConvertCountedElement(const char *src,
+				int length, char *dst, int flags);
+/* 86 */
+EXTERN int		Tcl_CreateAlias(Tcl_Interp *slave,
+				const char *slaveCmd, Tcl_Interp *target,
+				const char *targetCmd, int argc,
+				CONST84 char *const *argv);
+/* 87 */
+EXTERN int		Tcl_CreateAliasObj(Tcl_Interp *slave,
+				const char *slaveCmd, Tcl_Interp *target,
+				const char *targetCmd, int objc,
+				Tcl_Obj *const objv[]);
+/* 88 */
+EXTERN Tcl_Channel	Tcl_CreateChannel(const Tcl_ChannelType *typePtr,
+				const char *chanName,
+				ClientData instanceData, int mask);
+/* 89 */
+EXTERN void		Tcl_CreateChannelHandler(Tcl_Channel chan, int mask,
+				Tcl_ChannelProc *proc, ClientData clientData);
+/* 90 */
+EXTERN void		Tcl_CreateCloseHandler(Tcl_Channel chan,
+				Tcl_CloseProc *proc, ClientData clientData);
+/* 91 */
+EXTERN Tcl_Command	Tcl_CreateCommand(Tcl_Interp *interp,
+				const char *cmdName, Tcl_CmdProc *proc,
+				ClientData clientData,
+				Tcl_CmdDeleteProc *deleteProc);
+/* 92 */
+EXTERN void		Tcl_CreateEventSource(Tcl_EventSetupProc *setupProc,
+				Tcl_EventCheckProc *checkProc,
+				ClientData clientData);
+/* 93 */
+EXTERN void		Tcl_CreateExitHandler(Tcl_ExitProc *proc,
+				ClientData clientData);
+/* 94 */
+EXTERN Tcl_Interp *	Tcl_CreateInterp(void);
+/* 95 */
+EXTERN void		Tcl_CreateMathFunc(Tcl_Interp *interp,
+				const char *name, int numArgs,
+				Tcl_ValueType *argTypes, Tcl_MathProc *proc,
+				ClientData clientData);
+/* 96 */
+EXTERN Tcl_Command	Tcl_CreateObjCommand(Tcl_Interp *interp,
+				const char *cmdName, Tcl_ObjCmdProc *proc,
+				ClientData clientData,
+				Tcl_CmdDeleteProc *deleteProc);
+/* 97 */
+EXTERN Tcl_Interp *	Tcl_CreateSlave(Tcl_Interp *interp,
+				const char *slaveName, int isSafe);
+/* 98 */
+EXTERN Tcl_TimerToken	Tcl_CreateTimerHandler(int milliseconds,
+				Tcl_TimerProc *proc, ClientData clientData);
+/* 99 */
+EXTERN Tcl_Trace	Tcl_CreateTrace(Tcl_Interp *interp, int level,
+				Tcl_CmdTraceProc *proc,
+				ClientData clientData);
+/* 100 */
+EXTERN void		Tcl_DeleteAssocData(Tcl_Interp *interp,
+				const char *name);
+/* 101 */
+EXTERN void		Tcl_DeleteChannelHandler(Tcl_Channel chan,
+				Tcl_ChannelProc *proc, ClientData clientData);
+/* 102 */
+EXTERN void		Tcl_DeleteCloseHandler(Tcl_Channel chan,
+				Tcl_CloseProc *proc, ClientData clientData);
+/* 103 */
+EXTERN int		Tcl_DeleteCommand(Tcl_Interp *interp,
+				const char *cmdName);
+/* 104 */
+EXTERN int		Tcl_DeleteCommandFromToken(Tcl_Interp *interp,
+				Tcl_Command command);
+/* 105 */
+EXTERN void		Tcl_DeleteEvents(Tcl_EventDeleteProc *proc,
+				ClientData clientData);
+/* 106 */
+EXTERN void		Tcl_DeleteEventSource(Tcl_EventSetupProc *setupProc,
+				Tcl_EventCheckProc *checkProc,
+				ClientData clientData);
+/* 107 */
+EXTERN void		Tcl_DeleteExitHandler(Tcl_ExitProc *proc,
+				ClientData clientData);
+/* 108 */
+EXTERN void		Tcl_DeleteHashEntry(Tcl_HashEntry *entryPtr);
+/* 109 */
+EXTERN void		Tcl_DeleteHashTable(Tcl_HashTable *tablePtr);
+/* 110 */
+EXTERN void		Tcl_DeleteInterp(Tcl_Interp *interp);
+/* 111 */
+EXTERN void		Tcl_DetachPids(int numPids, Tcl_Pid *pidPtr);
+/* 112 */
+EXTERN void		Tcl_DeleteTimerHandler(Tcl_TimerToken token);
+/* 113 */
+EXTERN void		Tcl_DeleteTrace(Tcl_Interp *interp, Tcl_Trace trace);
+/* 114 */
+EXTERN void		Tcl_DontCallWhenDeleted(Tcl_Interp *interp,
+				Tcl_InterpDeleteProc *proc,
+				ClientData clientData);
+/* 115 */
+EXTERN int		Tcl_DoOneEvent(int flags);
+/* 116 */
+EXTERN void		Tcl_DoWhenIdle(Tcl_IdleProc *proc,
+				ClientData clientData);
+/* 117 */
+EXTERN char *		Tcl_DStringAppend(Tcl_DString *dsPtr,
+				const char *bytes, int length);
+/* 118 */
+EXTERN char *		Tcl_DStringAppendElement(Tcl_DString *dsPtr,
+				const char *element);
+/* 119 */
+EXTERN void		Tcl_DStringEndSublist(Tcl_DString *dsPtr);
+/* 120 */
+EXTERN void		Tcl_DStringFree(Tcl_DString *dsPtr);
+/* 121 */
+EXTERN void		Tcl_DStringGetResult(Tcl_Interp *interp,
+				Tcl_DString *dsPtr);
+/* 122 */
+EXTERN void		Tcl_DStringInit(Tcl_DString *dsPtr);
+/* 123 */
+EXTERN void		Tcl_DStringResult(Tcl_Interp *interp,
+				Tcl_DString *dsPtr);
+/* 124 */
+EXTERN void		Tcl_DStringSetLength(Tcl_DString *dsPtr, int length);
+/* 125 */
+EXTERN void		Tcl_DStringStartSublist(Tcl_DString *dsPtr);
+/* 126 */
+EXTERN int		Tcl_Eof(Tcl_Channel chan);
+/* 127 */
+EXTERN CONST84_RETURN char * Tcl_ErrnoId(void);
+/* 128 */
+EXTERN CONST84_RETURN char * Tcl_ErrnoMsg(int err);
+/* 129 */
+EXTERN int		Tcl_Eval(Tcl_Interp *interp, const char *script);
+/* 130 */
+EXTERN int		Tcl_EvalFile(Tcl_Interp *interp,
+				const char *fileName);
+/* 131 */
+EXTERN int		Tcl_EvalObj(Tcl_Interp *interp, Tcl_Obj *objPtr);
+/* 132 */
+EXTERN void		Tcl_EventuallyFree(ClientData clientData,
+				Tcl_FreeProc *freeProc);
+/* 133 */
+EXTERN TCL_NORETURN void Tcl_Exit(int status);
+/* 134 */
+EXTERN int		Tcl_ExposeCommand(Tcl_Interp *interp,
+				const char *hiddenCmdToken,
+				const char *cmdName);
+/* 135 */
+EXTERN int		Tcl_ExprBoolean(Tcl_Interp *interp, const char *expr,
+				int *ptr);
+/* 136 */
+EXTERN int		Tcl_ExprBooleanObj(Tcl_Interp *interp,
+				Tcl_Obj *objPtr, int *ptr);
+/* 137 */
+EXTERN int		Tcl_ExprDouble(Tcl_Interp *interp, const char *expr,
+				double *ptr);
+/* 138 */
+EXTERN int		Tcl_ExprDoubleObj(Tcl_Interp *interp,
+				Tcl_Obj *objPtr, double *ptr);
+/* 139 */
+EXTERN int		Tcl_ExprLong(Tcl_Interp *interp, const char *expr,
+				long *ptr);
+/* 140 */
+EXTERN int		Tcl_ExprLongObj(Tcl_Interp *interp, Tcl_Obj *objPtr,
+				long *ptr);
+/* 141 */
+EXTERN int		Tcl_ExprObj(Tcl_Interp *interp, Tcl_Obj *objPtr,
+				Tcl_Obj **resultPtrPtr);
+/* 142 */
+EXTERN int		Tcl_ExprString(Tcl_Interp *interp, const char *expr);
+/* 143 */
+EXTERN void		Tcl_Finalize(void);
+/* 144 */
+EXTERN void		Tcl_FindExecutable(const char *argv0);
+/* 145 */
+EXTERN Tcl_HashEntry *	Tcl_FirstHashEntry(Tcl_HashTable *tablePtr,
+				Tcl_HashSearch *searchPtr);
+/* 146 */
+EXTERN int		Tcl_Flush(Tcl_Channel chan);
+/* 147 */
+EXTERN void		Tcl_FreeResult(Tcl_Interp *interp);
+/* 148 */
+EXTERN int		Tcl_GetAlias(Tcl_Interp *interp,
+				const char *slaveCmd,
+				Tcl_Interp **targetInterpPtr,
+				CONST84 char **targetCmdPtr, int *argcPtr,
+				CONST84 char ***argvPtr);
+/* 149 */
+EXTERN int		Tcl_GetAliasObj(Tcl_Interp *interp,
+				const char *slaveCmd,
+				Tcl_Interp **targetInterpPtr,
+				CONST84 char **targetCmdPtr, int *objcPtr,
+				Tcl_Obj ***objv);
+/* 150 */
+EXTERN ClientData	Tcl_GetAssocData(Tcl_Interp *interp,
+				const char *name,
+				Tcl_InterpDeleteProc **procPtr);
+/* 151 */
+EXTERN Tcl_Channel	Tcl_GetChannel(Tcl_Interp *interp,
+				const char *chanName, int *modePtr);
+/* 152 */
+EXTERN int		Tcl_GetChannelBufferSize(Tcl_Channel chan);
+/* 153 */
+EXTERN int		Tcl_GetChannelHandle(Tcl_Channel chan, int direction,
+				ClientData *handlePtr);
+/* 154 */
+EXTERN ClientData	Tcl_GetChannelInstanceData(Tcl_Channel chan);
+/* 155 */
+EXTERN int		Tcl_GetChannelMode(Tcl_Channel chan);
+/* 156 */
+EXTERN CONST84_RETURN char * Tcl_GetChannelName(Tcl_Channel chan);
+/* 157 */
+EXTERN int		Tcl_GetChannelOption(Tcl_Interp *interp,
+				Tcl_Channel chan, const char *optionName,
+				Tcl_DString *dsPtr);
+/* 158 */
+EXTERN CONST86 Tcl_ChannelType * Tcl_GetChannelType(Tcl_Channel chan);
+/* 159 */
+EXTERN int		Tcl_GetCommandInfo(Tcl_Interp *interp,
+				const char *cmdName, Tcl_CmdInfo *infoPtr);
+/* 160 */
+EXTERN CONST84_RETURN char * Tcl_GetCommandName(Tcl_Interp *interp,
+				Tcl_Command command);
+/* 161 */
+EXTERN int		Tcl_GetErrno(void);
+/* 162 */
+EXTERN CONST84_RETURN char * Tcl_GetHostName(void);
+/* 163 */
+EXTERN int		Tcl_GetInterpPath(Tcl_Interp *askInterp,
+				Tcl_Interp *slaveInterp);
+/* 164 */
+EXTERN Tcl_Interp *	Tcl_GetMaster(Tcl_Interp *interp);
+/* 165 */
+EXTERN const char *	Tcl_GetNameOfExecutable(void);
+/* 166 */
+EXTERN Tcl_Obj *	Tcl_GetObjResult(Tcl_Interp *interp);
+#if !defined(_WIN32) && !defined(MAC_OSX_TCL) /* UNIX */
+/* 167 */
+EXTERN int		Tcl_GetOpenFile(Tcl_Interp *interp,
+				const char *chanID, int forWriting,
+				int checkUsage, ClientData *filePtr);
+#endif /* UNIX */
+#ifdef MAC_OSX_TCL /* MACOSX */
+/* 167 */
+EXTERN int		Tcl_GetOpenFile(Tcl_Interp *interp,
+				const char *chanID, int forWriting,
+				int checkUsage, ClientData *filePtr);
+#endif /* MACOSX */
+/* 168 */
+EXTERN Tcl_PathType	Tcl_GetPathType(const char *path);
+/* 169 */
+EXTERN int		Tcl_Gets(Tcl_Channel chan, Tcl_DString *dsPtr);
+/* 170 */
+EXTERN int		Tcl_GetsObj(Tcl_Channel chan, Tcl_Obj *objPtr);
+/* 171 */
+EXTERN int		Tcl_GetServiceMode(void);
+/* 172 */
+EXTERN Tcl_Interp *	Tcl_GetSlave(Tcl_Interp *interp,
+				const char *slaveName);
+/* 173 */
+EXTERN Tcl_Channel	Tcl_GetStdChannel(int type);
+/* 174 */
+EXTERN CONST84_RETURN char * Tcl_GetStringResult(Tcl_Interp *interp);
+/* 175 */
+EXTERN CONST84_RETURN char * Tcl_GetVar(Tcl_Interp *interp,
+				const char *varName, int flags);
+/* 176 */
+EXTERN CONST84_RETURN char * Tcl_GetVar2(Tcl_Interp *interp,
+				const char *part1, const char *part2,
+				int flags);
+/* 177 */
+EXTERN int		Tcl_GlobalEval(Tcl_Interp *interp,
+				const char *command);
+/* 178 */
+EXTERN int		Tcl_GlobalEvalObj(Tcl_Interp *interp,
+				Tcl_Obj *objPtr);
+/* 179 */
+EXTERN int		Tcl_HideCommand(Tcl_Interp *interp,
+				const char *cmdName,
+				const char *hiddenCmdToken);
+/* 180 */
+EXTERN int		Tcl_Init(Tcl_Interp *interp);
+/* 181 */
+EXTERN void		Tcl_InitHashTable(Tcl_HashTable *tablePtr,
+				int keyType);
+/* 182 */
+EXTERN int		Tcl_InputBlocked(Tcl_Channel chan);
+/* 183 */
+EXTERN int		Tcl_InputBuffered(Tcl_Channel chan);
+/* 184 */
+EXTERN int		Tcl_InterpDeleted(Tcl_Interp *interp);
+/* 185 */
+EXTERN int		Tcl_IsSafe(Tcl_Interp *interp);
+/* 186 */
+EXTERN char *		Tcl_JoinPath(int argc, CONST84 char *const *argv,
+				Tcl_DString *resultPtr);
+/* 187 */
+EXTERN int		Tcl_LinkVar(Tcl_Interp *interp, const char *varName,
+				char *addr, int type);
+/* Slot 188 is reserved */
+/* 189 */
+EXTERN Tcl_Channel	Tcl_MakeFileChannel(ClientData handle, int mode);
+/* 190 */
+EXTERN int		Tcl_MakeSafe(Tcl_Interp *interp);
+/* 191 */
+EXTERN Tcl_Channel	Tcl_MakeTcpClientChannel(ClientData tcpSocket);
+/* 192 */
+EXTERN char *		Tcl_Merge(int argc, CONST84 char *const *argv);
+/* 193 */
+EXTERN Tcl_HashEntry *	Tcl_NextHashEntry(Tcl_HashSearch *searchPtr);
+/* 194 */
+EXTERN void		Tcl_NotifyChannel(Tcl_Channel channel, int mask);
+/* 195 */
+EXTERN Tcl_Obj *	Tcl_ObjGetVar2(Tcl_Interp *interp, Tcl_Obj *part1Ptr,
+				Tcl_Obj *part2Ptr, int flags);
+/* 196 */
+EXTERN Tcl_Obj *	Tcl_ObjSetVar2(Tcl_Interp *interp, Tcl_Obj *part1Ptr,
+				Tcl_Obj *part2Ptr, Tcl_Obj *newValuePtr,
+				int flags);
+/* 197 */
+EXTERN Tcl_Channel	Tcl_OpenCommandChannel(Tcl_Interp *interp, int argc,
+				CONST84 char **argv, int flags);
+/* 198 */
+EXTERN Tcl_Channel	Tcl_OpenFileChannel(Tcl_Interp *interp,
+				const char *fileName, const char *modeString,
+				int permissions);
+/* 199 */
+EXTERN Tcl_Channel	Tcl_OpenTcpClient(Tcl_Interp *interp, int port,
+				const char *address, const char *myaddr,
+				int myport, int async);
+/* 200 */
+EXTERN Tcl_Channel	Tcl_OpenTcpServer(Tcl_Interp *interp, int port,
+				const char *host,
+				Tcl_TcpAcceptProc *acceptProc,
+				ClientData callbackData);
+/* 201 */
+EXTERN void		Tcl_Preserve(ClientData data);
+/* 202 */
+EXTERN void		Tcl_PrintDouble(Tcl_Interp *interp, double value,
+				char *dst);
+/* 203 */
+EXTERN int		Tcl_PutEnv(const char *assignment);
+/* 204 */
+EXTERN CONST84_RETURN char * Tcl_PosixError(Tcl_Interp *interp);
+/* 205 */
+EXTERN void		Tcl_QueueEvent(Tcl_Event *evPtr,
+				Tcl_QueuePosition position);
+/* 206 */
+EXTERN int		Tcl_Read(Tcl_Channel chan, char *bufPtr, int toRead);
+/* 207 */
+EXTERN void		Tcl_ReapDetachedProcs(void);
+/* 208 */
+EXTERN int		Tcl_RecordAndEval(Tcl_Interp *interp,
+				const char *cmd, int flags);
+/* 209 */
+EXTERN int		Tcl_RecordAndEvalObj(Tcl_Interp *interp,
+				Tcl_Obj *cmdPtr, int flags);
+/* 210 */
+EXTERN void		Tcl_RegisterChannel(Tcl_Interp *interp,
+				Tcl_Channel chan);
+/* 211 */
+EXTERN void		Tcl_RegisterObjType(const Tcl_ObjType *typePtr);
+/* 212 */
+EXTERN Tcl_RegExp	Tcl_RegExpCompile(Tcl_Interp *interp,
+				const char *pattern);
+/* 213 */
+EXTERN int		Tcl_RegExpExec(Tcl_Interp *interp, Tcl_RegExp regexp,
+				const char *text, const char *start);
+/* 214 */
+EXTERN int		Tcl_RegExpMatch(Tcl_Interp *interp, const char *text,
+				const char *pattern);
+/* 215 */
+EXTERN void		Tcl_RegExpRange(Tcl_RegExp regexp, int index,
+				CONST84 char **startPtr,
+				CONST84 char **endPtr);
+/* 216 */
+EXTERN void		Tcl_Release(ClientData clientData);
+/* 217 */
+EXTERN void		Tcl_ResetResult(Tcl_Interp *interp);
+/* 218 */
+EXTERN int		Tcl_ScanElement(const char *src, int *flagPtr);
+/* 219 */
+EXTERN int		Tcl_ScanCountedElement(const char *src, int length,
+				int *flagPtr);
+/* 220 */
+EXTERN int		Tcl_SeekOld(Tcl_Channel chan, int offset, int mode);
+/* 221 */
+EXTERN int		Tcl_ServiceAll(void);
+/* 222 */
+EXTERN int		Tcl_ServiceEvent(int flags);
+/* 223 */
+EXTERN void		Tcl_SetAssocData(Tcl_Interp *interp,
+				const char *name, Tcl_InterpDeleteProc *proc,
+				ClientData clientData);
+/* 224 */
+EXTERN void		Tcl_SetChannelBufferSize(Tcl_Channel chan, int sz);
+/* 225 */
+EXTERN int		Tcl_SetChannelOption(Tcl_Interp *interp,
+				Tcl_Channel chan, const char *optionName,
+				const char *newValue);
+/* 226 */
+EXTERN int		Tcl_SetCommandInfo(Tcl_Interp *interp,
+				const char *cmdName,
+				const Tcl_CmdInfo *infoPtr);
+/* 227 */
+EXTERN void		Tcl_SetErrno(int err);
+/* 228 */
+EXTERN void		Tcl_SetErrorCode(Tcl_Interp *interp, ...);
+/* 229 */
+EXTERN void		Tcl_SetMaxBlockTime(const Tcl_Time *timePtr);
+/* 230 */
+EXTERN void		Tcl_SetPanicProc(
+				TCL_NORETURN1 Tcl_PanicProc *panicProc);
+/* 231 */
+EXTERN int		Tcl_SetRecursionLimit(Tcl_Interp *interp, int depth);
+/* 232 */
+EXTERN void		Tcl_SetResult(Tcl_Interp *interp, char *result,
+				Tcl_FreeProc *freeProc);
+/* 233 */
+EXTERN int		Tcl_SetServiceMode(int mode);
+/* 234 */
+EXTERN void		Tcl_SetObjErrorCode(Tcl_Interp *interp,
+				Tcl_Obj *errorObjPtr);
+/* 235 */
+EXTERN void		Tcl_SetObjResult(Tcl_Interp *interp,
+				Tcl_Obj *resultObjPtr);
+/* 236 */
+EXTERN void		Tcl_SetStdChannel(Tcl_Channel channel, int type);
+/* 237 */
+EXTERN CONST84_RETURN char * Tcl_SetVar(Tcl_Interp *interp,
+				const char *varName, const char *newValue,
+				int flags);
+/* 238 */
+EXTERN CONST84_RETURN char * Tcl_SetVar2(Tcl_Interp *interp,
+				const char *part1, const char *part2,
+				const char *newValue, int flags);
+/* 239 */
+EXTERN CONST84_RETURN char * Tcl_SignalId(int sig);
+/* 240 */
+EXTERN CONST84_RETURN char * Tcl_SignalMsg(int sig);
+/* 241 */
+EXTERN void		Tcl_SourceRCFile(Tcl_Interp *interp);
+/* 242 */
+EXTERN int		Tcl_SplitList(Tcl_Interp *interp,
+				const char *listStr, int *argcPtr,
+				CONST84 char ***argvPtr);
+/* 243 */
+EXTERN void		Tcl_SplitPath(const char *path, int *argcPtr,
+				CONST84 char ***argvPtr);
+/* 244 */
+EXTERN void		Tcl_StaticPackage(Tcl_Interp *interp,
+				const char *pkgName,
+				Tcl_PackageInitProc *initProc,
+				Tcl_PackageInitProc *safeInitProc);
+/* 245 */
+EXTERN int		Tcl_StringMatch(const char *str, const char *pattern);
+/* 246 */
+EXTERN int		Tcl_TellOld(Tcl_Channel chan);
+/* 247 */
+EXTERN int		Tcl_TraceVar(Tcl_Interp *interp, const char *varName,
+				int flags, Tcl_VarTraceProc *proc,
+				ClientData clientData);
+/* 248 */
+EXTERN int		Tcl_TraceVar2(Tcl_Interp *interp, const char *part1,
+				const char *part2, int flags,
+				Tcl_VarTraceProc *proc,
+				ClientData clientData);
+/* 249 */
+EXTERN char *		Tcl_TranslateFileName(Tcl_Interp *interp,
+				const char *name, Tcl_DString *bufferPtr);
+/* 250 */
+EXTERN int		Tcl_Ungets(Tcl_Channel chan, const char *str,
+				int len, int atHead);
+/* 251 */
+EXTERN void		Tcl_UnlinkVar(Tcl_Interp *interp,
+				const char *varName);
+/* 252 */
+EXTERN int		Tcl_UnregisterChannel(Tcl_Interp *interp,
+				Tcl_Channel chan);
+/* 253 */
+EXTERN int		Tcl_UnsetVar(Tcl_Interp *interp, const char *varName,
+				int flags);
+/* 254 */
+EXTERN int		Tcl_UnsetVar2(Tcl_Interp *interp, const char *part1,
+				const char *part2, int flags);
+/* 255 */
+EXTERN void		Tcl_UntraceVar(Tcl_Interp *interp,
+				const char *varName, int flags,
+				Tcl_VarTraceProc *proc,
+				ClientData clientData);
+/* 256 */
+EXTERN void		Tcl_UntraceVar2(Tcl_Interp *interp,
+				const char *part1, const char *part2,
+				int flags, Tcl_VarTraceProc *proc,
+				ClientData clientData);
+/* 257 */
+EXTERN void		Tcl_UpdateLinkedVar(Tcl_Interp *interp,
+				const char *varName);
+/* 258 */
+EXTERN int		Tcl_UpVar(Tcl_Interp *interp, const char *frameName,
+				const char *varName, const char *localName,
+				int flags);
+/* 259 */
+EXTERN int		Tcl_UpVar2(Tcl_Interp *interp, const char *frameName,
+				const char *part1, const char *part2,
+				const char *localName, int flags);
+/* 260 */
+EXTERN int		Tcl_VarEval(Tcl_Interp *interp, ...);
+/* 261 */
+EXTERN ClientData	Tcl_VarTraceInfo(Tcl_Interp *interp,
+				const char *varName, int flags,
+				Tcl_VarTraceProc *procPtr,
+				ClientData prevClientData);
+/* 262 */
+EXTERN ClientData	Tcl_VarTraceInfo2(Tcl_Interp *interp,
+				const char *part1, const char *part2,
+				int flags, Tcl_VarTraceProc *procPtr,
+				ClientData prevClientData);
+/* 263 */
+EXTERN int		Tcl_Write(Tcl_Channel chan, const char *s, int slen);
+/* 264 */
+EXTERN void		Tcl_WrongNumArgs(Tcl_Interp *interp, int objc,
+				Tcl_Obj *const objv[], const char *message);
+/* 265 */
+EXTERN int		Tcl_DumpActiveMemory(const char *fileName);
+/* 266 */
+EXTERN void		Tcl_ValidateAllMemory(const char *file, int line);
+/* 267 */
+EXTERN void		Tcl_AppendResultVA(Tcl_Interp *interp,
+				va_list argList);
+/* 268 */
+EXTERN void		Tcl_AppendStringsToObjVA(Tcl_Obj *objPtr,
+				va_list argList);
+/* 269 */
+EXTERN char *		Tcl_HashStats(Tcl_HashTable *tablePtr);
+/* 270 */
+EXTERN CONST84_RETURN char * Tcl_ParseVar(Tcl_Interp *interp,
+				const char *start, CONST84 char **termPtr);
+/* 271 */
+EXTERN CONST84_RETURN char * Tcl_PkgPresent(Tcl_Interp *interp,
+				const char *name, const char *version,
+				int exact);
+/* 272 */
+EXTERN CONST84_RETURN char * Tcl_PkgPresentEx(Tcl_Interp *interp,
+				const char *name, const char *version,
+				int exact, void *clientDataPtr);
+/* 273 */
+EXTERN int		Tcl_PkgProvide(Tcl_Interp *interp, const char *name,
+				const char *version);
+/* 274 */
+EXTERN CONST84_RETURN char * Tcl_PkgRequire(Tcl_Interp *interp,
+				const char *name, const char *version,
+				int exact);
+/* 275 */
+EXTERN void		Tcl_SetErrorCodeVA(Tcl_Interp *interp,
+				va_list argList);
+/* 276 */
+EXTERN int		Tcl_VarEvalVA(Tcl_Interp *interp, va_list argList);
+/* 277 */
+EXTERN Tcl_Pid		Tcl_WaitPid(Tcl_Pid pid, int *statPtr, int options);
+/* 278 */
+EXTERN TCL_NORETURN void Tcl_PanicVA(const char *format, va_list argList);
+/* 279 */
+EXTERN void		Tcl_GetVersion(int *major, int *minor,
+				int *patchLevel, int *type);
+/* 280 */
+EXTERN void		Tcl_InitMemory(Tcl_Interp *interp);
+/* 281 */
+EXTERN Tcl_Channel	Tcl_StackChannel(Tcl_Interp *interp,
+				const Tcl_ChannelType *typePtr,
+				ClientData instanceData, int mask,
+				Tcl_Channel prevChan);
+/* 282 */
+EXTERN int		Tcl_UnstackChannel(Tcl_Interp *interp,
+				Tcl_Channel chan);
+/* 283 */
+EXTERN Tcl_Channel	Tcl_GetStackedChannel(Tcl_Channel chan);
+/* 284 */
+EXTERN void		Tcl_SetMainLoop(Tcl_MainLoopProc *proc);
+/* Slot 285 is reserved */
+/* 286 */
+EXTERN void		Tcl_AppendObjToObj(Tcl_Obj *objPtr,
+				Tcl_Obj *appendObjPtr);
+/* 287 */
+EXTERN Tcl_Encoding	Tcl_CreateEncoding(const Tcl_EncodingType *typePtr);
+/* 288 */
+EXTERN void		Tcl_CreateThreadExitHandler(Tcl_ExitProc *proc,
+				ClientData clientData);
+/* 289 */
+EXTERN void		Tcl_DeleteThreadExitHandler(Tcl_ExitProc *proc,
+				ClientData clientData);
+/* 290 */
+EXTERN void		Tcl_DiscardResult(Tcl_SavedResult *statePtr);
+/* 291 */
+EXTERN int		Tcl_EvalEx(Tcl_Interp *interp, const char *script,
+				int numBytes, int flags);
+/* 292 */
+EXTERN int		Tcl_EvalObjv(Tcl_Interp *interp, int objc,
+				Tcl_Obj *const objv[], int flags);
+/* 293 */
+EXTERN int		Tcl_EvalObjEx(Tcl_Interp *interp, Tcl_Obj *objPtr,
+				int flags);
+/* 294 */
+EXTERN void		Tcl_ExitThread(int status);
+/* 295 */
+EXTERN int		Tcl_ExternalToUtf(Tcl_Interp *interp,
+				Tcl_Encoding encoding, const char *src,
+				int srcLen, int flags,
+				Tcl_EncodingState *statePtr, char *dst,
+				int dstLen, int *srcReadPtr,
+				int *dstWrotePtr, int *dstCharsPtr);
+/* 296 */
+EXTERN char *		Tcl_ExternalToUtfDString(Tcl_Encoding encoding,
+				const char *src, int srcLen,
+				Tcl_DString *dsPtr);
+/* 297 */
+EXTERN void		Tcl_FinalizeThread(void);
+/* 298 */
+EXTERN void		Tcl_FinalizeNotifier(ClientData clientData);
+/* 299 */
+EXTERN void		Tcl_FreeEncoding(Tcl_Encoding encoding);
+/* 300 */
+EXTERN Tcl_ThreadId	Tcl_GetCurrentThread(void);
+/* 301 */
+EXTERN Tcl_Encoding	Tcl_GetEncoding(Tcl_Interp *interp, const char *name);
+/* 302 */
+EXTERN CONST84_RETURN char * Tcl_GetEncodingName(Tcl_Encoding encoding);
+/* 303 */
+EXTERN void		Tcl_GetEncodingNames(Tcl_Interp *interp);
+/* 304 */
+EXTERN int		Tcl_GetIndexFromObjStruct(Tcl_Interp *interp,
+				Tcl_Obj *objPtr, const void *tablePtr,
+				int offset, const char *msg, int flags,
+				int *indexPtr);
+/* 305 */
+EXTERN void *		Tcl_GetThreadData(Tcl_ThreadDataKey *keyPtr,
+				int size);
+/* 306 */
+EXTERN Tcl_Obj *	Tcl_GetVar2Ex(Tcl_Interp *interp, const char *part1,
+				const char *part2, int flags);
+/* 307 */
+EXTERN ClientData	Tcl_InitNotifier(void);
+/* 308 */
+EXTERN void		Tcl_MutexLock(Tcl_Mutex *mutexPtr);
+/* 309 */
+EXTERN void		Tcl_MutexUnlock(Tcl_Mutex *mutexPtr);
+/* 310 */
+EXTERN void		Tcl_ConditionNotify(Tcl_Condition *condPtr);
+/* 311 */
+EXTERN void		Tcl_ConditionWait(Tcl_Condition *condPtr,
+				Tcl_Mutex *mutexPtr, const Tcl_Time *timePtr);
+/* 312 */
+EXTERN int		Tcl_NumUtfChars(const char *src, int length);
+/* 313 */
+EXTERN int		Tcl_ReadChars(Tcl_Channel channel, Tcl_Obj *objPtr,
+				int charsToRead, int appendFlag);
+/* 314 */
+EXTERN void		Tcl_RestoreResult(Tcl_Interp *interp,
+				Tcl_SavedResult *statePtr);
+/* 315 */
+EXTERN void		Tcl_SaveResult(Tcl_Interp *interp,
+				Tcl_SavedResult *statePtr);
+/* 316 */
+EXTERN int		Tcl_SetSystemEncoding(Tcl_Interp *interp,
+				const char *name);
+/* 317 */
+EXTERN Tcl_Obj *	Tcl_SetVar2Ex(Tcl_Interp *interp, const char *part1,
+				const char *part2, Tcl_Obj *newValuePtr,
+				int flags);
+/* 318 */
+EXTERN void		Tcl_ThreadAlert(Tcl_ThreadId threadId);
+/* 319 */
+EXTERN void		Tcl_ThreadQueueEvent(Tcl_ThreadId threadId,
+				Tcl_Event *evPtr, Tcl_QueuePosition position);
+/* 320 */
+EXTERN Tcl_UniChar	Tcl_UniCharAtIndex(const char *src, int index);
+/* 321 */
+EXTERN Tcl_UniChar	Tcl_UniCharToLower(int ch);
+/* 322 */
+EXTERN Tcl_UniChar	Tcl_UniCharToTitle(int ch);
+/* 323 */
+EXTERN Tcl_UniChar	Tcl_UniCharToUpper(int ch);
+/* 324 */
+EXTERN int		Tcl_UniCharToUtf(int ch, char *buf);
+/* 325 */
+EXTERN CONST84_RETURN char * Tcl_UtfAtIndex(const char *src, int index);
+/* 326 */
+EXTERN int		Tcl_UtfCharComplete(const char *src, int length);
+/* 327 */
+EXTERN int		Tcl_UtfBackslash(const char *src, int *readPtr,
+				char *dst);
+/* 328 */
+EXTERN CONST84_RETURN char * Tcl_UtfFindFirst(const char *src, int ch);
+/* 329 */
+EXTERN CONST84_RETURN char * Tcl_UtfFindLast(const char *src, int ch);
+/* 330 */
+EXTERN CONST84_RETURN char * Tcl_UtfNext(const char *src);
+/* 331 */
+EXTERN CONST84_RETURN char * Tcl_UtfPrev(const char *src, const char *start);
+/* 332 */
+EXTERN int		Tcl_UtfToExternal(Tcl_Interp *interp,
+				Tcl_Encoding encoding, const char *src,
+				int srcLen, int flags,
+				Tcl_EncodingState *statePtr, char *dst,
+				int dstLen, int *srcReadPtr,
+				int *dstWrotePtr, int *dstCharsPtr);
+/* 333 */
+EXTERN char *		Tcl_UtfToExternalDString(Tcl_Encoding encoding,
+				const char *src, int srcLen,
+				Tcl_DString *dsPtr);
+/* 334 */
+EXTERN int		Tcl_UtfToLower(char *src);
+/* 335 */
+EXTERN int		Tcl_UtfToTitle(char *src);
+/* 336 */
+EXTERN int		Tcl_UtfToUniChar(const char *src, Tcl_UniChar *chPtr);
+/* 337 */
+EXTERN int		Tcl_UtfToUpper(char *src);
+/* 338 */
+EXTERN int		Tcl_WriteChars(Tcl_Channel chan, const char *src,
+				int srcLen);
+/* 339 */
+EXTERN int		Tcl_WriteObj(Tcl_Channel chan, Tcl_Obj *objPtr);
+/* 340 */
+EXTERN char *		Tcl_GetString(Tcl_Obj *objPtr);
+/* 341 */
+EXTERN CONST84_RETURN char * Tcl_GetDefaultEncodingDir(void);
+/* 342 */
+EXTERN void		Tcl_SetDefaultEncodingDir(const char *path);
+/* 343 */
+EXTERN void		Tcl_AlertNotifier(ClientData clientData);
+/* 344 */
+EXTERN void		Tcl_ServiceModeHook(int mode);
+/* 345 */
+EXTERN int		Tcl_UniCharIsAlnum(int ch);
+/* 346 */
+EXTERN int		Tcl_UniCharIsAlpha(int ch);
+/* 347 */
+EXTERN int		Tcl_UniCharIsDigit(int ch);
+/* 348 */
+EXTERN int		Tcl_UniCharIsLower(int ch);
+/* 349 */
+EXTERN int		Tcl_UniCharIsSpace(int ch);
+/* 350 */
+EXTERN int		Tcl_UniCharIsUpper(int ch);
+/* 351 */
+EXTERN int		Tcl_UniCharIsWordChar(int ch);
+/* 352 */
+EXTERN int		Tcl_UniCharLen(const Tcl_UniChar *uniStr);
+/* 353 */
+EXTERN int		Tcl_UniCharNcmp(const Tcl_UniChar *ucs,
+				const Tcl_UniChar *uct,
+				unsigned long numChars);
+/* 354 */
+EXTERN char *		Tcl_UniCharToUtfDString(const Tcl_UniChar *uniStr,
+				int uniLength, Tcl_DString *dsPtr);
+/* 355 */
+EXTERN Tcl_UniChar *	Tcl_UtfToUniCharDString(const char *src, int length,
+				Tcl_DString *dsPtr);
+/* 356 */
+EXTERN Tcl_RegExp	Tcl_GetRegExpFromObj(Tcl_Interp *interp,
+				Tcl_Obj *patObj, int flags);
+/* 357 */
+EXTERN Tcl_Obj *	Tcl_EvalTokens(Tcl_Interp *interp,
+				Tcl_Token *tokenPtr, int count);
+/* 358 */
+EXTERN void		Tcl_FreeParse(Tcl_Parse *parsePtr);
+/* 359 */
+EXTERN void		Tcl_LogCommandInfo(Tcl_Interp *interp,
+				const char *script, const char *command,
+				int length);
+/* 360 */
+EXTERN int		Tcl_ParseBraces(Tcl_Interp *interp,
+				const char *start, int numBytes,
+				Tcl_Parse *parsePtr, int append,
+				CONST84 char **termPtr);
+/* 361 */
+EXTERN int		Tcl_ParseCommand(Tcl_Interp *interp,
+				const char *start, int numBytes, int nested,
+				Tcl_Parse *parsePtr);
+/* 362 */
+EXTERN int		Tcl_ParseExpr(Tcl_Interp *interp, const char *start,
+				int numBytes, Tcl_Parse *parsePtr);
+/* 363 */
+EXTERN int		Tcl_ParseQuotedString(Tcl_Interp *interp,
+				const char *start, int numBytes,
+				Tcl_Parse *parsePtr, int append,
+				CONST84 char **termPtr);
+/* 364 */
+EXTERN int		Tcl_ParseVarName(Tcl_Interp *interp,
+				const char *start, int numBytes,
+				Tcl_Parse *parsePtr, int append);
+/* 365 */
+EXTERN char *		Tcl_GetCwd(Tcl_Interp *interp, Tcl_DString *cwdPtr);
+/* 366 */
+EXTERN int		Tcl_Chdir(const char *dirName);
+/* 367 */
+EXTERN int		Tcl_Access(const char *path, int mode);
+/* 368 */
+EXTERN int		Tcl_Stat(const char *path, struct stat *bufPtr);
+/* 369 */
+EXTERN int		Tcl_UtfNcmp(const char *s1, const char *s2,
+				unsigned long n);
+/* 370 */
+EXTERN int		Tcl_UtfNcasecmp(const char *s1, const char *s2,
+				unsigned long n);
+/* 371 */
+EXTERN int		Tcl_StringCaseMatch(const char *str,
+				const char *pattern, int nocase);
+/* 372 */
+EXTERN int		Tcl_UniCharIsControl(int ch);
+/* 373 */
+EXTERN int		Tcl_UniCharIsGraph(int ch);
+/* 374 */
+EXTERN int		Tcl_UniCharIsPrint(int ch);
+/* 375 */
+EXTERN int		Tcl_UniCharIsPunct(int ch);
+/* 376 */
+EXTERN int		Tcl_RegExpExecObj(Tcl_Interp *interp,
+				Tcl_RegExp regexp, Tcl_Obj *textObj,
+				int offset, int nmatches, int flags);
+/* 377 */
+EXTERN void		Tcl_RegExpGetInfo(Tcl_RegExp regexp,
+				Tcl_RegExpInfo *infoPtr);
+/* 378 */
+EXTERN Tcl_Obj *	Tcl_NewUnicodeObj(const Tcl_UniChar *unicode,
+				int numChars);
+/* 379 */
+EXTERN void		Tcl_SetUnicodeObj(Tcl_Obj *objPtr,
+				const Tcl_UniChar *unicode, int numChars);
+/* 380 */
+EXTERN int		Tcl_GetCharLength(Tcl_Obj *objPtr);
+/* 381 */
+EXTERN Tcl_UniChar	Tcl_GetUniChar(Tcl_Obj *objPtr, int index);
+/* 382 */
+EXTERN Tcl_UniChar *	Tcl_GetUnicode(Tcl_Obj *objPtr);
+/* 383 */
+EXTERN Tcl_Obj *	Tcl_GetRange(Tcl_Obj *objPtr, int first, int last);
+/* 384 */
+EXTERN void		Tcl_AppendUnicodeToObj(Tcl_Obj *objPtr,
+				const Tcl_UniChar *unicode, int length);
+/* 385 */
+EXTERN int		Tcl_RegExpMatchObj(Tcl_Interp *interp,
+				Tcl_Obj *textObj, Tcl_Obj *patternObj);
+/* 386 */
+EXTERN void		Tcl_SetNotifier(Tcl_NotifierProcs *notifierProcPtr);
+/* 387 */
+EXTERN Tcl_Mutex *	Tcl_GetAllocMutex(void);
+/* 388 */
+EXTERN int		Tcl_GetChannelNames(Tcl_Interp *interp);
+/* 389 */
+EXTERN int		Tcl_GetChannelNamesEx(Tcl_Interp *interp,
+				const char *pattern);
+/* 390 */
+EXTERN int		Tcl_ProcObjCmd(ClientData clientData,
+				Tcl_Interp *interp, int objc,
+				Tcl_Obj *const objv[]);
+/* 391 */
+EXTERN void		Tcl_ConditionFinalize(Tcl_Condition *condPtr);
+/* 392 */
+EXTERN void		Tcl_MutexFinalize(Tcl_Mutex *mutex);
+/* 393 */
+EXTERN int		Tcl_CreateThread(Tcl_ThreadId *idPtr,
+				Tcl_ThreadCreateProc *proc,
+				ClientData clientData, int stackSize,
+				int flags);
+/* 394 */
+EXTERN int		Tcl_ReadRaw(Tcl_Channel chan, char *dst,
+				int bytesToRead);
+/* 395 */
+EXTERN int		Tcl_WriteRaw(Tcl_Channel chan, const char *src,
+				int srcLen);
+/* 396 */
+EXTERN Tcl_Channel	Tcl_GetTopChannel(Tcl_Channel chan);
+/* 397 */
+EXTERN int		Tcl_ChannelBuffered(Tcl_Channel chan);
+/* 398 */
+EXTERN CONST84_RETURN char * Tcl_ChannelName(
+				const Tcl_ChannelType *chanTypePtr);
+/* 399 */
+EXTERN Tcl_ChannelTypeVersion Tcl_ChannelVersion(
+				const Tcl_ChannelType *chanTypePtr);
+/* 400 */
+EXTERN Tcl_DriverBlockModeProc * Tcl_ChannelBlockModeProc(
+				const Tcl_ChannelType *chanTypePtr);
+/* 401 */
+EXTERN Tcl_DriverCloseProc * Tcl_ChannelCloseProc(
+				const Tcl_ChannelType *chanTypePtr);
+/* 402 */
+EXTERN Tcl_DriverClose2Proc * Tcl_ChannelClose2Proc(
+				const Tcl_ChannelType *chanTypePtr);
+/* 403 */
+EXTERN Tcl_DriverInputProc * Tcl_ChannelInputProc(
+				const Tcl_ChannelType *chanTypePtr);
+/* 404 */
+EXTERN Tcl_DriverOutputProc * Tcl_ChannelOutputProc(
+				const Tcl_ChannelType *chanTypePtr);
+/* 405 */
+EXTERN Tcl_DriverSeekProc * Tcl_ChannelSeekProc(
+				const Tcl_ChannelType *chanTypePtr);
+/* 406 */
+EXTERN Tcl_DriverSetOptionProc * Tcl_ChannelSetOptionProc(
+				const Tcl_ChannelType *chanTypePtr);
+/* 407 */
+EXTERN Tcl_DriverGetOptionProc * Tcl_ChannelGetOptionProc(
+				const Tcl_ChannelType *chanTypePtr);
+/* 408 */
+EXTERN Tcl_DriverWatchProc * Tcl_ChannelWatchProc(
+				const Tcl_ChannelType *chanTypePtr);
+/* 409 */
+EXTERN Tcl_DriverGetHandleProc * Tcl_ChannelGetHandleProc(
+				const Tcl_ChannelType *chanTypePtr);
+/* 410 */
+EXTERN Tcl_DriverFlushProc * Tcl_ChannelFlushProc(
+				const Tcl_ChannelType *chanTypePtr);
+/* 411 */
+EXTERN Tcl_DriverHandlerProc * Tcl_ChannelHandlerProc(
+				const Tcl_ChannelType *chanTypePtr);
+/* 412 */
+EXTERN int		Tcl_JoinThread(Tcl_ThreadId threadId, int *result);
+/* 413 */
+EXTERN int		Tcl_IsChannelShared(Tcl_Channel channel);
+/* 414 */
+EXTERN int		Tcl_IsChannelRegistered(Tcl_Interp *interp,
+				Tcl_Channel channel);
+/* 415 */
+EXTERN void		Tcl_CutChannel(Tcl_Channel channel);
+/* 416 */
+EXTERN void		Tcl_SpliceChannel(Tcl_Channel channel);
+/* 417 */
+EXTERN void		Tcl_ClearChannelHandlers(Tcl_Channel channel);
+/* 418 */
+EXTERN int		Tcl_IsChannelExisting(const char *channelName);
+/* 419 */
+EXTERN int		Tcl_UniCharNcasecmp(const Tcl_UniChar *ucs,
+				const Tcl_UniChar *uct,
+				unsigned long numChars);
+/* 420 */
+EXTERN int		Tcl_UniCharCaseMatch(const Tcl_UniChar *uniStr,
+				const Tcl_UniChar *uniPattern, int nocase);
+/* 421 */
+EXTERN Tcl_HashEntry *	Tcl_FindHashEntry(Tcl_HashTable *tablePtr,
+				const void *key);
+/* 422 */
+EXTERN Tcl_HashEntry *	Tcl_CreateHashEntry(Tcl_HashTable *tablePtr,
+				const void *key, int *newPtr);
+/* 423 */
+EXTERN void		Tcl_InitCustomHashTable(Tcl_HashTable *tablePtr,
+				int keyType, const Tcl_HashKeyType *typePtr);
+/* 424 */
+EXTERN void		Tcl_InitObjHashTable(Tcl_HashTable *tablePtr);
+/* 425 */
+EXTERN ClientData	Tcl_CommandTraceInfo(Tcl_Interp *interp,
+				const char *varName, int flags,
+				Tcl_CommandTraceProc *procPtr,
+				ClientData prevClientData);
+/* 426 */
+EXTERN int		Tcl_TraceCommand(Tcl_Interp *interp,
+				const char *varName, int flags,
+				Tcl_CommandTraceProc *proc,
+				ClientData clientData);
+/* 427 */
+EXTERN void		Tcl_UntraceCommand(Tcl_Interp *interp,
+				const char *varName, int flags,
+				Tcl_CommandTraceProc *proc,
+				ClientData clientData);
+/* 428 */
+EXTERN char *		Tcl_AttemptAlloc(unsigned int size);
+/* 429 */
+EXTERN char *		Tcl_AttemptDbCkalloc(unsigned int size,
+				const char *file, int line);
+/* 430 */
+EXTERN char *		Tcl_AttemptRealloc(char *ptr, unsigned int size);
+/* 431 */
+EXTERN char *		Tcl_AttemptDbCkrealloc(char *ptr, unsigned int size,
+				const char *file, int line);
+/* 432 */
+EXTERN int		Tcl_AttemptSetObjLength(Tcl_Obj *objPtr, int length);
+/* 433 */
+EXTERN Tcl_ThreadId	Tcl_GetChannelThread(Tcl_Channel channel);
+/* 434 */
+EXTERN Tcl_UniChar *	Tcl_GetUnicodeFromObj(Tcl_Obj *objPtr,
+				int *lengthPtr);
+/* 435 */
+EXTERN int		Tcl_GetMathFuncInfo(Tcl_Interp *interp,
+				const char *name, int *numArgsPtr,
+				Tcl_ValueType **argTypesPtr,
+				Tcl_MathProc **procPtr,
+				ClientData *clientDataPtr);
+/* 436 */
+EXTERN Tcl_Obj *	Tcl_ListMathFuncs(Tcl_Interp *interp,
+				const char *pattern);
+/* 437 */
+EXTERN Tcl_Obj *	Tcl_SubstObj(Tcl_Interp *interp, Tcl_Obj *objPtr,
+				int flags);
+/* 438 */
+EXTERN int		Tcl_DetachChannel(Tcl_Interp *interp,
+				Tcl_Channel channel);
+/* 439 */
+EXTERN int		Tcl_IsStandardChannel(Tcl_Channel channel);
+/* 440 */
+EXTERN int		Tcl_FSCopyFile(Tcl_Obj *srcPathPtr,
+				Tcl_Obj *destPathPtr);
+/* 441 */
+EXTERN int		Tcl_FSCopyDirectory(Tcl_Obj *srcPathPtr,
+				Tcl_Obj *destPathPtr, Tcl_Obj **errorPtr);
+/* 442 */
+EXTERN int		Tcl_FSCreateDirectory(Tcl_Obj *pathPtr);
+/* 443 */
+EXTERN int		Tcl_FSDeleteFile(Tcl_Obj *pathPtr);
+/* 444 */
+EXTERN int		Tcl_FSLoadFile(Tcl_Interp *interp, Tcl_Obj *pathPtr,
+				const char *sym1, const char *sym2,
+				Tcl_PackageInitProc **proc1Ptr,
+				Tcl_PackageInitProc **proc2Ptr,
+				Tcl_LoadHandle *handlePtr,
+				Tcl_FSUnloadFileProc **unloadProcPtr);
+/* 445 */
+EXTERN int		Tcl_FSMatchInDirectory(Tcl_Interp *interp,
+				Tcl_Obj *result, Tcl_Obj *pathPtr,
+				const char *pattern, Tcl_GlobTypeData *types);
+/* 446 */
+EXTERN Tcl_Obj *	Tcl_FSLink(Tcl_Obj *pathPtr, Tcl_Obj *toPtr,
+				int linkAction);
+/* 447 */
+EXTERN int		Tcl_FSRemoveDirectory(Tcl_Obj *pathPtr,
+				int recursive, Tcl_Obj **errorPtr);
+/* 448 */
+EXTERN int		Tcl_FSRenameFile(Tcl_Obj *srcPathPtr,
+				Tcl_Obj *destPathPtr);
+/* 449 */
+EXTERN int		Tcl_FSLstat(Tcl_Obj *pathPtr, Tcl_StatBuf *buf);
+/* 450 */
+EXTERN int		Tcl_FSUtime(Tcl_Obj *pathPtr, struct utimbuf *tval);
+/* 451 */
+EXTERN int		Tcl_FSFileAttrsGet(Tcl_Interp *interp, int index,
+				Tcl_Obj *pathPtr, Tcl_Obj **objPtrRef);
+/* 452 */
+EXTERN int		Tcl_FSFileAttrsSet(Tcl_Interp *interp, int index,
+				Tcl_Obj *pathPtr, Tcl_Obj *objPtr);
+/* 453 */
+EXTERN const char *CONST86 * Tcl_FSFileAttrStrings(Tcl_Obj *pathPtr,
+				Tcl_Obj **objPtrRef);
+/* 454 */
+EXTERN int		Tcl_FSStat(Tcl_Obj *pathPtr, Tcl_StatBuf *buf);
+/* 455 */
+EXTERN int		Tcl_FSAccess(Tcl_Obj *pathPtr, int mode);
+/* 456 */
+EXTERN Tcl_Channel	Tcl_FSOpenFileChannel(Tcl_Interp *interp,
+				Tcl_Obj *pathPtr, const char *modeString,
+				int permissions);
+/* 457 */
+EXTERN Tcl_Obj *	Tcl_FSGetCwd(Tcl_Interp *interp);
+/* 458 */
+EXTERN int		Tcl_FSChdir(Tcl_Obj *pathPtr);
+/* 459 */
+EXTERN int		Tcl_FSConvertToPathType(Tcl_Interp *interp,
+				Tcl_Obj *pathPtr);
+/* 460 */
+EXTERN Tcl_Obj *	Tcl_FSJoinPath(Tcl_Obj *listObj, int elements);
+/* 461 */
+EXTERN Tcl_Obj *	Tcl_FSSplitPath(Tcl_Obj *pathPtr, int *lenPtr);
+/* 462 */
+EXTERN int		Tcl_FSEqualPaths(Tcl_Obj *firstPtr,
+				Tcl_Obj *secondPtr);
+/* 463 */
+EXTERN Tcl_Obj *	Tcl_FSGetNormalizedPath(Tcl_Interp *interp,
+				Tcl_Obj *pathPtr);
+/* 464 */
+EXTERN Tcl_Obj *	Tcl_FSJoinToPath(Tcl_Obj *pathPtr, int objc,
+				Tcl_Obj *const objv[]);
+/* 465 */
+EXTERN ClientData	Tcl_FSGetInternalRep(Tcl_Obj *pathPtr,
+				const Tcl_Filesystem *fsPtr);
+/* 466 */
+EXTERN Tcl_Obj *	Tcl_FSGetTranslatedPath(Tcl_Interp *interp,
+				Tcl_Obj *pathPtr);
+/* 467 */
+EXTERN int		Tcl_FSEvalFile(Tcl_Interp *interp, Tcl_Obj *fileName);
+/* 468 */
+EXTERN Tcl_Obj *	Tcl_FSNewNativePath(
+				const Tcl_Filesystem *fromFilesystem,
+				ClientData clientData);
+/* 469 */
+EXTERN const void *	Tcl_FSGetNativePath(Tcl_Obj *pathPtr);
+/* 470 */
+EXTERN Tcl_Obj *	Tcl_FSFileSystemInfo(Tcl_Obj *pathPtr);
+/* 471 */
+EXTERN Tcl_Obj *	Tcl_FSPathSeparator(Tcl_Obj *pathPtr);
+/* 472 */
+EXTERN Tcl_Obj *	Tcl_FSListVolumes(void);
+/* 473 */
+EXTERN int		Tcl_FSRegister(ClientData clientData,
+				const Tcl_Filesystem *fsPtr);
+/* 474 */
+EXTERN int		Tcl_FSUnregister(const Tcl_Filesystem *fsPtr);
+/* 475 */
+EXTERN ClientData	Tcl_FSData(const Tcl_Filesystem *fsPtr);
+/* 476 */
+EXTERN const char *	Tcl_FSGetTranslatedStringPath(Tcl_Interp *interp,
+				Tcl_Obj *pathPtr);
+/* 477 */
+EXTERN CONST86 Tcl_Filesystem * Tcl_FSGetFileSystemForPath(Tcl_Obj *pathPtr);
+/* 478 */
+EXTERN Tcl_PathType	Tcl_FSGetPathType(Tcl_Obj *pathPtr);
+/* 479 */
+EXTERN int		Tcl_OutputBuffered(Tcl_Channel chan);
+/* 480 */
+EXTERN void		Tcl_FSMountsChanged(const Tcl_Filesystem *fsPtr);
+/* 481 */
+EXTERN int		Tcl_EvalTokensStandard(Tcl_Interp *interp,
+				Tcl_Token *tokenPtr, int count);
+/* 482 */
+EXTERN void		Tcl_GetTime(Tcl_Time *timeBuf);
+/* 483 */
+EXTERN Tcl_Trace	Tcl_CreateObjTrace(Tcl_Interp *interp, int level,
+				int flags, Tcl_CmdObjTraceProc *objProc,
+				ClientData clientData,
+				Tcl_CmdObjTraceDeleteProc *delProc);
+/* 484 */
+EXTERN int		Tcl_GetCommandInfoFromToken(Tcl_Command token,
+				Tcl_CmdInfo *infoPtr);
+/* 485 */
+EXTERN int		Tcl_SetCommandInfoFromToken(Tcl_Command token,
+				const Tcl_CmdInfo *infoPtr);
+/* 486 */
+EXTERN Tcl_Obj *	Tcl_DbNewWideIntObj(Tcl_WideInt wideValue,
+				const char *file, int line);
+/* 487 */
+EXTERN int		Tcl_GetWideIntFromObj(Tcl_Interp *interp,
+				Tcl_Obj *objPtr, Tcl_WideInt *widePtr);
+/* 488 */
+EXTERN Tcl_Obj *	Tcl_NewWideIntObj(Tcl_WideInt wideValue);
+/* 489 */
+EXTERN void		Tcl_SetWideIntObj(Tcl_Obj *objPtr,
+				Tcl_WideInt wideValue);
+/* 490 */
+EXTERN Tcl_StatBuf *	Tcl_AllocStatBuf(void);
+/* 491 */
+EXTERN Tcl_WideInt	Tcl_Seek(Tcl_Channel chan, Tcl_WideInt offset,
+				int mode);
+/* 492 */
+EXTERN Tcl_WideInt	Tcl_Tell(Tcl_Channel chan);
+/* 493 */
+EXTERN Tcl_DriverWideSeekProc * Tcl_ChannelWideSeekProc(
+				const Tcl_ChannelType *chanTypePtr);
+/* 494 */
+EXTERN int		Tcl_DictObjPut(Tcl_Interp *interp, Tcl_Obj *dictPtr,
+				Tcl_Obj *keyPtr, Tcl_Obj *valuePtr);
+/* 495 */
+EXTERN int		Tcl_DictObjGet(Tcl_Interp *interp, Tcl_Obj *dictPtr,
+				Tcl_Obj *keyPtr, Tcl_Obj **valuePtrPtr);
+/* 496 */
+EXTERN int		Tcl_DictObjRemove(Tcl_Interp *interp,
+				Tcl_Obj *dictPtr, Tcl_Obj *keyPtr);
+/* 497 */
+EXTERN int		Tcl_DictObjSize(Tcl_Interp *interp, Tcl_Obj *dictPtr,
+				int *sizePtr);
+/* 498 */
+EXTERN int		Tcl_DictObjFirst(Tcl_Interp *interp,
+				Tcl_Obj *dictPtr, Tcl_DictSearch *searchPtr,
+				Tcl_Obj **keyPtrPtr, Tcl_Obj **valuePtrPtr,
+				int *donePtr);
+/* 499 */
+EXTERN void		Tcl_DictObjNext(Tcl_DictSearch *searchPtr,
+				Tcl_Obj **keyPtrPtr, Tcl_Obj **valuePtrPtr,
+				int *donePtr);
+/* 500 */
+EXTERN void		Tcl_DictObjDone(Tcl_DictSearch *searchPtr);
+/* 501 */
+EXTERN int		Tcl_DictObjPutKeyList(Tcl_Interp *interp,
+				Tcl_Obj *dictPtr, int keyc,
+				Tcl_Obj *const *keyv, Tcl_Obj *valuePtr);
+/* 502 */
+EXTERN int		Tcl_DictObjRemoveKeyList(Tcl_Interp *interp,
+				Tcl_Obj *dictPtr, int keyc,
+				Tcl_Obj *const *keyv);
+/* 503 */
+EXTERN Tcl_Obj *	Tcl_NewDictObj(void);
+/* 504 */
+EXTERN Tcl_Obj *	Tcl_DbNewDictObj(const char *file, int line);
+/* 505 */
+EXTERN void		Tcl_RegisterConfig(Tcl_Interp *interp,
+				const char *pkgName,
+				const Tcl_Config *configuration,
+				const char *valEncoding);
+/* 506 */
+EXTERN Tcl_Namespace *	Tcl_CreateNamespace(Tcl_Interp *interp,
+				const char *name, ClientData clientData,
+				Tcl_NamespaceDeleteProc *deleteProc);
+/* 507 */
+EXTERN void		Tcl_DeleteNamespace(Tcl_Namespace *nsPtr);
+/* 508 */
+EXTERN int		Tcl_AppendExportList(Tcl_Interp *interp,
+				Tcl_Namespace *nsPtr, Tcl_Obj *objPtr);
+/* 509 */
+EXTERN int		Tcl_Export(Tcl_Interp *interp, Tcl_Namespace *nsPtr,
+				const char *pattern, int resetListFirst);
+/* 510 */
+EXTERN int		Tcl_Import(Tcl_Interp *interp, Tcl_Namespace *nsPtr,
+				const char *pattern, int allowOverwrite);
+/* 511 */
+EXTERN int		Tcl_ForgetImport(Tcl_Interp *interp,
+				Tcl_Namespace *nsPtr, const char *pattern);
+/* 512 */
+EXTERN Tcl_Namespace *	Tcl_GetCurrentNamespace(Tcl_Interp *interp);
+/* 513 */
+EXTERN Tcl_Namespace *	Tcl_GetGlobalNamespace(Tcl_Interp *interp);
+/* 514 */
+EXTERN Tcl_Namespace *	Tcl_FindNamespace(Tcl_Interp *interp,
+				const char *name,
+				Tcl_Namespace *contextNsPtr, int flags);
+/* 515 */
+EXTERN Tcl_Command	Tcl_FindCommand(Tcl_Interp *interp, const char *name,
+				Tcl_Namespace *contextNsPtr, int flags);
+/* 516 */
+EXTERN Tcl_Command	Tcl_GetCommandFromObj(Tcl_Interp *interp,
+				Tcl_Obj *objPtr);
+/* 517 */
+EXTERN void		Tcl_GetCommandFullName(Tcl_Interp *interp,
+				Tcl_Command command, Tcl_Obj *objPtr);
+/* 518 */
+EXTERN int		Tcl_FSEvalFileEx(Tcl_Interp *interp,
+				Tcl_Obj *fileName, const char *encodingName);
+/* 519 */
+EXTERN Tcl_ExitProc *	Tcl_SetExitProc(TCL_NORETURN1 Tcl_ExitProc *proc);
+/* 520 */
+EXTERN void		Tcl_LimitAddHandler(Tcl_Interp *interp, int type,
+				Tcl_LimitHandlerProc *handlerProc,
+				ClientData clientData,
+				Tcl_LimitHandlerDeleteProc *deleteProc);
+/* 521 */
+EXTERN void		Tcl_LimitRemoveHandler(Tcl_Interp *interp, int type,
+				Tcl_LimitHandlerProc *handlerProc,
+				ClientData clientData);
+/* 522 */
+EXTERN int		Tcl_LimitReady(Tcl_Interp *interp);
+/* 523 */
+EXTERN int		Tcl_LimitCheck(Tcl_Interp *interp);
+/* 524 */
+EXTERN int		Tcl_LimitExceeded(Tcl_Interp *interp);
+/* 525 */
+EXTERN void		Tcl_LimitSetCommands(Tcl_Interp *interp,
+				int commandLimit);
+/* 526 */
+EXTERN void		Tcl_LimitSetTime(Tcl_Interp *interp,
+				Tcl_Time *timeLimitPtr);
+/* 527 */
+EXTERN void		Tcl_LimitSetGranularity(Tcl_Interp *interp, int type,
+				int granularity);
+/* 528 */
+EXTERN int		Tcl_LimitTypeEnabled(Tcl_Interp *interp, int type);
+/* 529 */
+EXTERN int		Tcl_LimitTypeExceeded(Tcl_Interp *interp, int type);
+/* 530 */
+EXTERN void		Tcl_LimitTypeSet(Tcl_Interp *interp, int type);
+/* 531 */
+EXTERN void		Tcl_LimitTypeReset(Tcl_Interp *interp, int type);
+/* 532 */
+EXTERN int		Tcl_LimitGetCommands(Tcl_Interp *interp);
+/* 533 */
+EXTERN void		Tcl_LimitGetTime(Tcl_Interp *interp,
+				Tcl_Time *timeLimitPtr);
+/* 534 */
+EXTERN int		Tcl_LimitGetGranularity(Tcl_Interp *interp, int type);
+/* 535 */
+EXTERN Tcl_InterpState	Tcl_SaveInterpState(Tcl_Interp *interp, int status);
+/* 536 */
+EXTERN int		Tcl_RestoreInterpState(Tcl_Interp *interp,
+				Tcl_InterpState state);
+/* 537 */
+EXTERN void		Tcl_DiscardInterpState(Tcl_InterpState state);
+/* 538 */
+EXTERN int		Tcl_SetReturnOptions(Tcl_Interp *interp,
+				Tcl_Obj *options);
+/* 539 */
+EXTERN Tcl_Obj *	Tcl_GetReturnOptions(Tcl_Interp *interp, int result);
+/* 540 */
+EXTERN int		Tcl_IsEnsemble(Tcl_Command token);
+/* 541 */
+EXTERN Tcl_Command	Tcl_CreateEnsemble(Tcl_Interp *interp,
+				const char *name,
+				Tcl_Namespace *namespacePtr, int flags);
+/* 542 */
+EXTERN Tcl_Command	Tcl_FindEnsemble(Tcl_Interp *interp,
+				Tcl_Obj *cmdNameObj, int flags);
+/* 543 */
+EXTERN int		Tcl_SetEnsembleSubcommandList(Tcl_Interp *interp,
+				Tcl_Command token, Tcl_Obj *subcmdList);
+/* 544 */
+EXTERN int		Tcl_SetEnsembleMappingDict(Tcl_Interp *interp,
+				Tcl_Command token, Tcl_Obj *mapDict);
+/* 545 */
+EXTERN int		Tcl_SetEnsembleUnknownHandler(Tcl_Interp *interp,
+				Tcl_Command token, Tcl_Obj *unknownList);
+/* 546 */
+EXTERN int		Tcl_SetEnsembleFlags(Tcl_Interp *interp,
+				Tcl_Command token, int flags);
+/* 547 */
+EXTERN int		Tcl_GetEnsembleSubcommandList(Tcl_Interp *interp,
+				Tcl_Command token, Tcl_Obj **subcmdListPtr);
+/* 548 */
+EXTERN int		Tcl_GetEnsembleMappingDict(Tcl_Interp *interp,
+				Tcl_Command token, Tcl_Obj **mapDictPtr);
+/* 549 */
+EXTERN int		Tcl_GetEnsembleUnknownHandler(Tcl_Interp *interp,
+				Tcl_Command token, Tcl_Obj **unknownListPtr);
+/* 550 */
+EXTERN int		Tcl_GetEnsembleFlags(Tcl_Interp *interp,
+				Tcl_Command token, int *flagsPtr);
+/* 551 */
+EXTERN int		Tcl_GetEnsembleNamespace(Tcl_Interp *interp,
+				Tcl_Command token,
+				Tcl_Namespace **namespacePtrPtr);
+/* 552 */
+EXTERN void		Tcl_SetTimeProc(Tcl_GetTimeProc *getProc,
+				Tcl_ScaleTimeProc *scaleProc,
+				ClientData clientData);
+/* 553 */
+EXTERN void		Tcl_QueryTimeProc(Tcl_GetTimeProc **getProc,
+				Tcl_ScaleTimeProc **scaleProc,
+				ClientData *clientData);
+/* 554 */
+EXTERN Tcl_DriverThreadActionProc * Tcl_ChannelThreadActionProc(
+				const Tcl_ChannelType *chanTypePtr);
+/* 555 */
+EXTERN Tcl_Obj *	Tcl_NewBignumObj(mp_int *value);
+/* 556 */
+EXTERN Tcl_Obj *	Tcl_DbNewBignumObj(mp_int *value, const char *file,
+				int line);
+/* 557 */
+EXTERN void		Tcl_SetBignumObj(Tcl_Obj *obj, mp_int *value);
+/* 558 */
+EXTERN int		Tcl_GetBignumFromObj(Tcl_Interp *interp,
+				Tcl_Obj *obj, mp_int *value);
+/* 559 */
+EXTERN int		Tcl_TakeBignumFromObj(Tcl_Interp *interp,
+				Tcl_Obj *obj, mp_int *value);
+/* 560 */
+EXTERN int		Tcl_TruncateChannel(Tcl_Channel chan,
+				Tcl_WideInt length);
+/* 561 */
+EXTERN Tcl_DriverTruncateProc * Tcl_ChannelTruncateProc(
+				const Tcl_ChannelType *chanTypePtr);
+/* 562 */
+EXTERN void		Tcl_SetChannelErrorInterp(Tcl_Interp *interp,
+				Tcl_Obj *msg);
+/* 563 */
+EXTERN void		Tcl_GetChannelErrorInterp(Tcl_Interp *interp,
+				Tcl_Obj **msg);
+/* 564 */
+EXTERN void		Tcl_SetChannelError(Tcl_Channel chan, Tcl_Obj *msg);
+/* 565 */
+EXTERN void		Tcl_GetChannelError(Tcl_Channel chan, Tcl_Obj **msg);
+/* 566 */
+EXTERN int		Tcl_InitBignumFromDouble(Tcl_Interp *interp,
+				double initval, mp_int *toInit);
+/* 567 */
+EXTERN Tcl_Obj *	Tcl_GetNamespaceUnknownHandler(Tcl_Interp *interp,
+				Tcl_Namespace *nsPtr);
+/* 568 */
+EXTERN int		Tcl_SetNamespaceUnknownHandler(Tcl_Interp *interp,
+				Tcl_Namespace *nsPtr, Tcl_Obj *handlerPtr);
+/* 569 */
+EXTERN int		Tcl_GetEncodingFromObj(Tcl_Interp *interp,
+				Tcl_Obj *objPtr, Tcl_Encoding *encodingPtr);
+/* 570 */
+EXTERN Tcl_Obj *	Tcl_GetEncodingSearchPath(void);
+/* 571 */
+EXTERN int		Tcl_SetEncodingSearchPath(Tcl_Obj *searchPath);
+/* 572 */
+EXTERN const char *	Tcl_GetEncodingNameFromEnvironment(
+				Tcl_DString *bufPtr);
+/* 573 */
+EXTERN int		Tcl_PkgRequireProc(Tcl_Interp *interp,
+				const char *name, int objc,
+				Tcl_Obj *const objv[], void *clientDataPtr);
+/* 574 */
+EXTERN void		Tcl_AppendObjToErrorInfo(Tcl_Interp *interp,
+				Tcl_Obj *objPtr);
+/* 575 */
+EXTERN void		Tcl_AppendLimitedToObj(Tcl_Obj *objPtr,
+				const char *bytes, int length, int limit,
+				const char *ellipsis);
+/* 576 */
+EXTERN Tcl_Obj *	Tcl_Format(Tcl_Interp *interp, const char *format,
+				int objc, Tcl_Obj *const objv[]);
+/* 577 */
+EXTERN int		Tcl_AppendFormatToObj(Tcl_Interp *interp,
+				Tcl_Obj *objPtr, const char *format,
+				int objc, Tcl_Obj *const objv[]);
+/* 578 */
+EXTERN Tcl_Obj *	Tcl_ObjPrintf(const char *format, ...) TCL_FORMAT_PRINTF(1, 2);
+/* 579 */
+EXTERN void		Tcl_AppendPrintfToObj(Tcl_Obj *objPtr,
+				const char *format, ...) TCL_FORMAT_PRINTF(2, 3);
+/* 580 */
+EXTERN int		Tcl_CancelEval(Tcl_Interp *interp,
+				Tcl_Obj *resultObjPtr, ClientData clientData,
+				int flags);
+/* 581 */
+EXTERN int		Tcl_Canceled(Tcl_Interp *interp, int flags);
+/* 582 */
+EXTERN int		Tcl_CreatePipe(Tcl_Interp *interp,
+				Tcl_Channel *rchan, Tcl_Channel *wchan,
+				int flags);
+/* 583 */
+EXTERN Tcl_Command	Tcl_NRCreateCommand(Tcl_Interp *interp,
+				const char *cmdName, Tcl_ObjCmdProc *proc,
+				Tcl_ObjCmdProc *nreProc,
+				ClientData clientData,
+				Tcl_CmdDeleteProc *deleteProc);
+/* 584 */
+EXTERN int		Tcl_NREvalObj(Tcl_Interp *interp, Tcl_Obj *objPtr,
+				int flags);
+/* 585 */
+EXTERN int		Tcl_NREvalObjv(Tcl_Interp *interp, int objc,
+				Tcl_Obj *const objv[], int flags);
+/* 586 */
+EXTERN int		Tcl_NRCmdSwap(Tcl_Interp *interp, Tcl_Command cmd,
+				int objc, Tcl_Obj *const objv[], int flags);
+/* 587 */
+EXTERN void		Tcl_NRAddCallback(Tcl_Interp *interp,
+				Tcl_NRPostProc *postProcPtr,
+				ClientData data0, ClientData data1,
+				ClientData data2, ClientData data3);
+/* 588 */
+EXTERN int		Tcl_NRCallObjProc(Tcl_Interp *interp,
+				Tcl_ObjCmdProc *objProc,
+				ClientData clientData, int objc,
+				Tcl_Obj *const objv[]);
+/* 589 */
+EXTERN unsigned		Tcl_GetFSDeviceFromStat(const Tcl_StatBuf *statPtr);
+/* 590 */
+EXTERN unsigned		Tcl_GetFSInodeFromStat(const Tcl_StatBuf *statPtr);
+/* 591 */
+EXTERN unsigned		Tcl_GetModeFromStat(const Tcl_StatBuf *statPtr);
+/* 592 */
+EXTERN int		Tcl_GetLinkCountFromStat(const Tcl_StatBuf *statPtr);
+/* 593 */
+EXTERN int		Tcl_GetUserIdFromStat(const Tcl_StatBuf *statPtr);
+/* 594 */
+EXTERN int		Tcl_GetGroupIdFromStat(const Tcl_StatBuf *statPtr);
+/* 595 */
+EXTERN int		Tcl_GetDeviceTypeFromStat(const Tcl_StatBuf *statPtr);
+/* 596 */
+EXTERN Tcl_WideInt	Tcl_GetAccessTimeFromStat(const Tcl_StatBuf *statPtr);
+/* 597 */
+EXTERN Tcl_WideInt	Tcl_GetModificationTimeFromStat(
+				const Tcl_StatBuf *statPtr);
+/* 598 */
+EXTERN Tcl_WideInt	Tcl_GetChangeTimeFromStat(const Tcl_StatBuf *statPtr);
+/* 599 */
+EXTERN Tcl_WideUInt	Tcl_GetSizeFromStat(const Tcl_StatBuf *statPtr);
+/* 600 */
+EXTERN Tcl_WideUInt	Tcl_GetBlocksFromStat(const Tcl_StatBuf *statPtr);
+/* 601 */
+EXTERN unsigned		Tcl_GetBlockSizeFromStat(const Tcl_StatBuf *statPtr);
+/* 602 */
+EXTERN int		Tcl_SetEnsembleParameterList(Tcl_Interp *interp,
+				Tcl_Command token, Tcl_Obj *paramList);
+/* 603 */
+EXTERN int		Tcl_GetEnsembleParameterList(Tcl_Interp *interp,
+				Tcl_Command token, Tcl_Obj **paramListPtr);
+/* 604 */
+EXTERN int		Tcl_ParseArgsObjv(Tcl_Interp *interp,
+				const Tcl_ArgvInfo *argTable, int *objcPtr,
+				Tcl_Obj *const *objv, Tcl_Obj ***remObjv);
+/* 605 */
+EXTERN int		Tcl_GetErrorLine(Tcl_Interp *interp);
+/* 606 */
+EXTERN void		Tcl_SetErrorLine(Tcl_Interp *interp, int lineNum);
+/* 607 */
+EXTERN void		Tcl_TransferResult(Tcl_Interp *sourceInterp,
+				int result, Tcl_Interp *targetInterp);
+/* 608 */
+EXTERN int		Tcl_InterpActive(Tcl_Interp *interp);
+/* 609 */
+EXTERN void		Tcl_BackgroundException(Tcl_Interp *interp, int code);
+/* 610 */
+EXTERN int		Tcl_ZlibDeflate(Tcl_Interp *interp, int format,
+				Tcl_Obj *data, int level,
+				Tcl_Obj *gzipHeaderDictObj);
+/* 611 */
+EXTERN int		Tcl_ZlibInflate(Tcl_Interp *interp, int format,
+				Tcl_Obj *data, int buffersize,
+				Tcl_Obj *gzipHeaderDictObj);
+/* 612 */
+EXTERN unsigned int	Tcl_ZlibCRC32(unsigned int crc,
+				const unsigned char *buf, int len);
+/* 613 */
+EXTERN unsigned int	Tcl_ZlibAdler32(unsigned int adler,
+				const unsigned char *buf, int len);
+/* 614 */
+EXTERN int		Tcl_ZlibStreamInit(Tcl_Interp *interp, int mode,
+				int format, int level, Tcl_Obj *dictObj,
+				Tcl_ZlibStream *zshandle);
+/* 615 */
+EXTERN Tcl_Obj *	Tcl_ZlibStreamGetCommandName(Tcl_ZlibStream zshandle);
+/* 616 */
+EXTERN int		Tcl_ZlibStreamEof(Tcl_ZlibStream zshandle);
+/* 617 */
+EXTERN int		Tcl_ZlibStreamChecksum(Tcl_ZlibStream zshandle);
+/* 618 */
+EXTERN int		Tcl_ZlibStreamPut(Tcl_ZlibStream zshandle,
+				Tcl_Obj *data, int flush);
+/* 619 */
+EXTERN int		Tcl_ZlibStreamGet(Tcl_ZlibStream zshandle,
+				Tcl_Obj *data, int count);
+/* 620 */
+EXTERN int		Tcl_ZlibStreamClose(Tcl_ZlibStream zshandle);
+/* 621 */
+EXTERN int		Tcl_ZlibStreamReset(Tcl_ZlibStream zshandle);
+/* 622 */
+EXTERN void		Tcl_SetStartupScript(Tcl_Obj *path,
+				const char *encoding);
+/* 623 */
+EXTERN Tcl_Obj *	Tcl_GetStartupScript(const char **encodingPtr);
+/* 624 */
+EXTERN int		Tcl_CloseEx(Tcl_Interp *interp, Tcl_Channel chan,
+				int flags);
+/* 625 */
+EXTERN int		Tcl_NRExprObj(Tcl_Interp *interp, Tcl_Obj *objPtr,
+				Tcl_Obj *resultPtr);
+/* 626 */
+EXTERN int		Tcl_NRSubstObj(Tcl_Interp *interp, Tcl_Obj *objPtr,
+				int flags);
+/* 627 */
+EXTERN int		Tcl_LoadFile(Tcl_Interp *interp, Tcl_Obj *pathPtr,
+				const char *const symv[], int flags,
+				void *procPtrs, Tcl_LoadHandle *handlePtr);
+/* 628 */
+EXTERN void *		Tcl_FindSymbol(Tcl_Interp *interp,
+				Tcl_LoadHandle handle, const char *symbol);
+/* 629 */
+EXTERN int		Tcl_FSUnloadFile(Tcl_Interp *interp,
+				Tcl_LoadHandle handlePtr);
+/* 630 */
+EXTERN void		Tcl_ZlibStreamSetCompressionDictionary(
+				Tcl_ZlibStream zhandle,
+				Tcl_Obj *compressionDictionaryObj);
+
+typedef struct {
+    const struct TclPlatStubs *tclPlatStubs;
+    const struct TclIntStubs *tclIntStubs;
+    const struct TclIntPlatStubs *tclIntPlatStubs;
+} TclStubHooks;
+
+typedef struct TclStubs {
+    int magic;
+    const TclStubHooks *hooks;
+
+    int (*tcl_PkgProvideEx) (Tcl_Interp *interp, const char *name, const char *version, const void *clientData); /* 0 */
+    CONST84_RETURN char * (*tcl_PkgRequireEx) (Tcl_Interp *interp, const char *name, const char *version, int exact, void *clientDataPtr); /* 1 */
+    TCL_NORETURN1 void (*tcl_Panic) (const char *format, ...) TCL_FORMAT_PRINTF(1, 2); /* 2 */
+    char * (*tcl_Alloc) (unsigned int size); /* 3 */
+    void (*tcl_Free) (char *ptr); /* 4 */
+    char * (*tcl_Realloc) (char *ptr, unsigned int size); /* 5 */
+    char * (*tcl_DbCkalloc) (unsigned int size, const char *file, int line); /* 6 */
+    void (*tcl_DbCkfree) (char *ptr, const char *file, int line); /* 7 */
+    char * (*tcl_DbCkrealloc) (char *ptr, unsigned int size, const char *file, int line); /* 8 */
+#if !defined(_WIN32) && !defined(MAC_OSX_TCL) /* UNIX */
+    void (*tcl_CreateFileHandler) (int fd, int mask, Tcl_FileProc *proc, ClientData clientData); /* 9 */
+#endif /* UNIX */
+#if defined(_WIN32) /* WIN */
+    void (*reserved9)(void);
+#endif /* WIN */
+#ifdef MAC_OSX_TCL /* MACOSX */
+    void (*tcl_CreateFileHandler) (int fd, int mask, Tcl_FileProc *proc, ClientData clientData); /* 9 */
+#endif /* MACOSX */
+#if !defined(_WIN32) && !defined(MAC_OSX_TCL) /* UNIX */
+    void (*tcl_DeleteFileHandler) (int fd); /* 10 */
+#endif /* UNIX */
+#if defined(_WIN32) /* WIN */
+    void (*reserved10)(void);
+#endif /* WIN */
+#ifdef MAC_OSX_TCL /* MACOSX */
+    void (*tcl_DeleteFileHandler) (int fd); /* 10 */
+#endif /* MACOSX */
+    void (*tcl_SetTimer) (const Tcl_Time *timePtr); /* 11 */
+    void (*tcl_Sleep) (int ms); /* 12 */
+    int (*tcl_WaitForEvent) (const Tcl_Time *timePtr); /* 13 */
+    int (*tcl_AppendAllObjTypes) (Tcl_Interp *interp, Tcl_Obj *objPtr); /* 14 */
+    void (*tcl_AppendStringsToObj) (Tcl_Obj *objPtr, ...); /* 15 */
+    void (*tcl_AppendToObj) (Tcl_Obj *objPtr, const char *bytes, int length); /* 16 */
+    Tcl_Obj * (*tcl_ConcatObj) (int objc, Tcl_Obj *const objv[]); /* 17 */
+    int (*tcl_ConvertToType) (Tcl_Interp *interp, Tcl_Obj *objPtr, const Tcl_ObjType *typePtr); /* 18 */
+    void (*tcl_DbDecrRefCount) (Tcl_Obj *objPtr, const char *file, int line); /* 19 */
+    void (*tcl_DbIncrRefCount) (Tcl_Obj *objPtr, const char *file, int line); /* 20 */
+    int (*tcl_DbIsShared) (Tcl_Obj *objPtr, const char *file, int line); /* 21 */
+    Tcl_Obj * (*tcl_DbNewBooleanObj) (int boolValue, const char *file, int line); /* 22 */
+    Tcl_Obj * (*tcl_DbNewByteArrayObj) (const unsigned char *bytes, int length, const char *file, int line); /* 23 */
+    Tcl_Obj * (*tcl_DbNewDoubleObj) (double doubleValue, const char *file, int line); /* 24 */
+    Tcl_Obj * (*tcl_DbNewListObj) (int objc, Tcl_Obj *const *objv, const char *file, int line); /* 25 */
+    Tcl_Obj * (*tcl_DbNewLongObj) (long longValue, const char *file, int line); /* 26 */
+    Tcl_Obj * (*tcl_DbNewObj) (const char *file, int line); /* 27 */
+    Tcl_Obj * (*tcl_DbNewStringObj) (const char *bytes, int length, const char *file, int line); /* 28 */
+    Tcl_Obj * (*tcl_DuplicateObj) (Tcl_Obj *objPtr); /* 29 */
+    void (*tclFreeObj) (Tcl_Obj *objPtr); /* 30 */
+    int (*tcl_GetBoolean) (Tcl_Interp *interp, const char *src, int *boolPtr); /* 31 */
+    int (*tcl_GetBooleanFromObj) (Tcl_Interp *interp, Tcl_Obj *objPtr, int *boolPtr); /* 32 */
+    unsigned char * (*tcl_GetByteArrayFromObj) (Tcl_Obj *objPtr, int *lengthPtr); /* 33 */
+    int (*tcl_GetDouble) (Tcl_Interp *interp, const char *src, double *doublePtr); /* 34 */
+    int (*tcl_GetDoubleFromObj) (Tcl_Interp *interp, Tcl_Obj *objPtr, double *doublePtr); /* 35 */
+    int (*tcl_GetIndexFromObj) (Tcl_Interp *interp, Tcl_Obj *objPtr, CONST84 char *const *tablePtr, const char *msg, int flags, int *indexPtr); /* 36 */
+    int (*tcl_GetInt) (Tcl_Interp *interp, const char *src, int *intPtr); /* 37 */
+    int (*tcl_GetIntFromObj) (Tcl_Interp *interp, Tcl_Obj *objPtr, int *intPtr); /* 38 */
+    int (*tcl_GetLongFromObj) (Tcl_Interp *interp, Tcl_Obj *objPtr, long *longPtr); /* 39 */
+    CONST86 Tcl_ObjType * (*tcl_GetObjType) (const char *typeName); /* 40 */
+    char * (*tcl_GetStringFromObj) (Tcl_Obj *objPtr, int *lengthPtr); /* 41 */
+    void (*tcl_InvalidateStringRep) (Tcl_Obj *objPtr); /* 42 */
+    int (*tcl_ListObjAppendList) (Tcl_Interp *interp, Tcl_Obj *listPtr, Tcl_Obj *elemListPtr); /* 43 */
+    int (*tcl_ListObjAppendElement) (Tcl_Interp *interp, Tcl_Obj *listPtr, Tcl_Obj *objPtr); /* 44 */
+    int (*tcl_ListObjGetElements) (Tcl_Interp *interp, Tcl_Obj *listPtr, int *objcPtr, Tcl_Obj ***objvPtr); /* 45 */
+    int (*tcl_ListObjIndex) (Tcl_Interp *interp, Tcl_Obj *listPtr, int index, Tcl_Obj **objPtrPtr); /* 46 */
+    int (*tcl_ListObjLength) (Tcl_Interp *interp, Tcl_Obj *listPtr, int *lengthPtr); /* 47 */
+    int (*tcl_ListObjReplace) (Tcl_Interp *interp, Tcl_Obj *listPtr, int first, int count, int objc, Tcl_Obj *const objv[]); /* 48 */
+    Tcl_Obj * (*tcl_NewBooleanObj) (int boolValue); /* 49 */
+    Tcl_Obj * (*tcl_NewByteArrayObj) (const unsigned char *bytes, int length); /* 50 */
+    Tcl_Obj * (*tcl_NewDoubleObj) (double doubleValue); /* 51 */
+    Tcl_Obj * (*tcl_NewIntObj) (int intValue); /* 52 */
+    Tcl_Obj * (*tcl_NewListObj) (int objc, Tcl_Obj *const objv[]); /* 53 */
+    Tcl_Obj * (*tcl_NewLongObj) (long longValue); /* 54 */
+    Tcl_Obj * (*tcl_NewObj) (void); /* 55 */
+    Tcl_Obj * (*tcl_NewStringObj) (const char *bytes, int length); /* 56 */
+    void (*tcl_SetBooleanObj) (Tcl_Obj *objPtr, int boolValue); /* 57 */
+    unsigned char * (*tcl_SetByteArrayLength) (Tcl_Obj *objPtr, int length); /* 58 */
+    void (*tcl_SetByteArrayObj) (Tcl_Obj *objPtr, const unsigned char *bytes, int length); /* 59 */
+    void (*tcl_SetDoubleObj) (Tcl_Obj *objPtr, double doubleValue); /* 60 */
+    void (*tcl_SetIntObj) (Tcl_Obj *objPtr, int intValue); /* 61 */
+    void (*tcl_SetListObj) (Tcl_Obj *objPtr, int objc, Tcl_Obj *const objv[]); /* 62 */
+    void (*tcl_SetLongObj) (Tcl_Obj *objPtr, long longValue); /* 63 */
+    void (*tcl_SetObjLength) (Tcl_Obj *objPtr, int length); /* 64 */
+    void (*tcl_SetStringObj) (Tcl_Obj *objPtr, const char *bytes, int length); /* 65 */
+    void (*tcl_AddErrorInfo) (Tcl_Interp *interp, const char *message); /* 66 */
+    void (*tcl_AddObjErrorInfo) (Tcl_Interp *interp, const char *message, int length); /* 67 */
+    void (*tcl_AllowExceptions) (Tcl_Interp *interp); /* 68 */
+    void (*tcl_AppendElement) (Tcl_Interp *interp, const char *element); /* 69 */
+    void (*tcl_AppendResult) (Tcl_Interp *interp, ...); /* 70 */
+    Tcl_AsyncHandler (*tcl_AsyncCreate) (Tcl_AsyncProc *proc, ClientData clientData); /* 71 */
+    void (*tcl_AsyncDelete) (Tcl_AsyncHandler async); /* 72 */
+    int (*tcl_AsyncInvoke) (Tcl_Interp *interp, int code); /* 73 */
+    void (*tcl_AsyncMark) (Tcl_AsyncHandler async); /* 74 */
+    int (*tcl_AsyncReady) (void); /* 75 */
+    void (*tcl_BackgroundError) (Tcl_Interp *interp); /* 76 */
+    char (*tcl_Backslash) (const char *src, int *readPtr); /* 77 */
+    int (*tcl_BadChannelOption) (Tcl_Interp *interp, const char *optionName, const char *optionList); /* 78 */
+    void (*tcl_CallWhenDeleted) (Tcl_Interp *interp, Tcl_InterpDeleteProc *proc, ClientData clientData); /* 79 */
+    void (*tcl_CancelIdleCall) (Tcl_IdleProc *idleProc, ClientData clientData); /* 80 */
+    int (*tcl_Close) (Tcl_Interp *interp, Tcl_Channel chan); /* 81 */
+    int (*tcl_CommandComplete) (const char *cmd); /* 82 */
+    char * (*tcl_Concat) (int argc, CONST84 char *const *argv); /* 83 */
+    int (*tcl_ConvertElement) (const char *src, char *dst, int flags); /* 84 */
+    int (*tcl_ConvertCountedElement) (const char *src, int length, char *dst, int flags); /* 85 */
+    int (*tcl_CreateAlias) (Tcl_Interp *slave, const char *slaveCmd, Tcl_Interp *target, const char *targetCmd, int argc, CONST84 char *const *argv); /* 86 */
+    int (*tcl_CreateAliasObj) (Tcl_Interp *slave, const char *slaveCmd, Tcl_Interp *target, const char *targetCmd, int objc, Tcl_Obj *const objv[]); /* 87 */
+    Tcl_Channel (*tcl_CreateChannel) (const Tcl_ChannelType *typePtr, const char *chanName, ClientData instanceData, int mask); /* 88 */
+    void (*tcl_CreateChannelHandler) (Tcl_Channel chan, int mask, Tcl_ChannelProc *proc, ClientData clientData); /* 89 */
+    void (*tcl_CreateCloseHandler) (Tcl_Channel chan, Tcl_CloseProc *proc, ClientData clientData); /* 90 */
+    Tcl_Command (*tcl_CreateCommand) (Tcl_Interp *interp, const char *cmdName, Tcl_CmdProc *proc, ClientData clientData, Tcl_CmdDeleteProc *deleteProc); /* 91 */
+    void (*tcl_CreateEventSource) (Tcl_EventSetupProc *setupProc, Tcl_EventCheckProc *checkProc, ClientData clientData); /* 92 */
+    void (*tcl_CreateExitHandler) (Tcl_ExitProc *proc, ClientData clientData); /* 93 */
+    Tcl_Interp * (*tcl_CreateInterp) (void); /* 94 */
+    void (*tcl_CreateMathFunc) (Tcl_Interp *interp, const char *name, int numArgs, Tcl_ValueType *argTypes, Tcl_MathProc *proc, ClientData clientData); /* 95 */
+    Tcl_Command (*tcl_CreateObjCommand) (Tcl_Interp *interp, const char *cmdName, Tcl_ObjCmdProc *proc, ClientData clientData, Tcl_CmdDeleteProc *deleteProc); /* 96 */
+    Tcl_Interp * (*tcl_CreateSlave) (Tcl_Interp *interp, const char *slaveName, int isSafe); /* 97 */
+    Tcl_TimerToken (*tcl_CreateTimerHandler) (int milliseconds, Tcl_TimerProc *proc, ClientData clientData); /* 98 */
+    Tcl_Trace (*tcl_CreateTrace) (Tcl_Interp *interp, int level, Tcl_CmdTraceProc *proc, ClientData clientData); /* 99 */
+    void (*tcl_DeleteAssocData) (Tcl_Interp *interp, const char *name); /* 100 */
+    void (*tcl_DeleteChannelHandler) (Tcl_Channel chan, Tcl_ChannelProc *proc, ClientData clientData); /* 101 */
+    void (*tcl_DeleteCloseHandler) (Tcl_Channel chan, Tcl_CloseProc *proc, ClientData clientData); /* 102 */
+    int (*tcl_DeleteCommand) (Tcl_Interp *interp, const char *cmdName); /* 103 */
+    int (*tcl_DeleteCommandFromToken) (Tcl_Interp *interp, Tcl_Command command); /* 104 */
+    void (*tcl_DeleteEvents) (Tcl_EventDeleteProc *proc, ClientData clientData); /* 105 */
+    void (*tcl_DeleteEventSource) (Tcl_EventSetupProc *setupProc, Tcl_EventCheckProc *checkProc, ClientData clientData); /* 106 */
+    void (*tcl_DeleteExitHandler) (Tcl_ExitProc *proc, ClientData clientData); /* 107 */
+    void (*tcl_DeleteHashEntry) (Tcl_HashEntry *entryPtr); /* 108 */
+    void (*tcl_DeleteHashTable) (Tcl_HashTable *tablePtr); /* 109 */
+    void (*tcl_DeleteInterp) (Tcl_Interp *interp); /* 110 */
+    void (*tcl_DetachPids) (int numPids, Tcl_Pid *pidPtr); /* 111 */
+    void (*tcl_DeleteTimerHandler) (Tcl_TimerToken token); /* 112 */
+    void (*tcl_DeleteTrace) (Tcl_Interp *interp, Tcl_Trace trace); /* 113 */
+    void (*tcl_DontCallWhenDeleted) (Tcl_Interp *interp, Tcl_InterpDeleteProc *proc, ClientData clientData); /* 114 */
+    int (*tcl_DoOneEvent) (int flags); /* 115 */
+    void (*tcl_DoWhenIdle) (Tcl_IdleProc *proc, ClientData clientData); /* 116 */
+    char * (*tcl_DStringAppend) (Tcl_DString *dsPtr, const char *bytes, int length); /* 117 */
+    char * (*tcl_DStringAppendElement) (Tcl_DString *dsPtr, const char *element); /* 118 */
+    void (*tcl_DStringEndSublist) (Tcl_DString *dsPtr); /* 119 */
+    void (*tcl_DStringFree) (Tcl_DString *dsPtr); /* 120 */
+    void (*tcl_DStringGetResult) (Tcl_Interp *interp, Tcl_DString *dsPtr); /* 121 */
+    void (*tcl_DStringInit) (Tcl_DString *dsPtr); /* 122 */
+    void (*tcl_DStringResult) (Tcl_Interp *interp, Tcl_DString *dsPtr); /* 123 */
+    void (*tcl_DStringSetLength) (Tcl_DString *dsPtr, int length); /* 124 */
+    void (*tcl_DStringStartSublist) (Tcl_DString *dsPtr); /* 125 */
+    int (*tcl_Eof) (Tcl_Channel chan); /* 126 */
+    CONST84_RETURN char * (*tcl_ErrnoId) (void); /* 127 */
+    CONST84_RETURN char * (*tcl_ErrnoMsg) (int err); /* 128 */
+    int (*tcl_Eval) (Tcl_Interp *interp, const char *script); /* 129 */
+    int (*tcl_EvalFile) (Tcl_Interp *interp, const char *fileName); /* 130 */
+    int (*tcl_EvalObj) (Tcl_Interp *interp, Tcl_Obj *objPtr); /* 131 */
+    void (*tcl_EventuallyFree) (ClientData clientData, Tcl_FreeProc *freeProc); /* 132 */
+    TCL_NORETURN1 void (*tcl_Exit) (int status); /* 133 */
+    int (*tcl_ExposeCommand) (Tcl_Interp *interp, const char *hiddenCmdToken, const char *cmdName); /* 134 */
+    int (*tcl_ExprBoolean) (Tcl_Interp *interp, const char *expr, int *ptr); /* 135 */
+    int (*tcl_ExprBooleanObj) (Tcl_Interp *interp, Tcl_Obj *objPtr, int *ptr); /* 136 */
+    int (*tcl_ExprDouble) (Tcl_Interp *interp, const char *expr, double *ptr); /* 137 */
+    int (*tcl_ExprDoubleObj) (Tcl_Interp *interp, Tcl_Obj *objPtr, double *ptr); /* 138 */
+    int (*tcl_ExprLong) (Tcl_Interp *interp, const char *expr, long *ptr); /* 139 */
+    int (*tcl_ExprLongObj) (Tcl_Interp *interp, Tcl_Obj *objPtr, long *ptr); /* 140 */
+    int (*tcl_ExprObj) (Tcl_Interp *interp, Tcl_Obj *objPtr, Tcl_Obj **resultPtrPtr); /* 141 */
+    int (*tcl_ExprString) (Tcl_Interp *interp, const char *expr); /* 142 */
+    void (*tcl_Finalize) (void); /* 143 */
+    void (*tcl_FindExecutable) (const char *argv0); /* 144 */
+    Tcl_HashEntry * (*tcl_FirstHashEntry) (Tcl_HashTable *tablePtr, Tcl_HashSearch *searchPtr); /* 145 */
+    int (*tcl_Flush) (Tcl_Channel chan); /* 146 */
+    void (*tcl_FreeResult) (Tcl_Interp *interp); /* 147 */
+    int (*tcl_GetAlias) (Tcl_Interp *interp, const char *slaveCmd, Tcl_Interp **targetInterpPtr, CONST84 char **targetCmdPtr, int *argcPtr, CONST84 char ***argvPtr); /* 148 */
+    int (*tcl_GetAliasObj) (Tcl_Interp *interp, const char *slaveCmd, Tcl_Interp **targetInterpPtr, CONST84 char **targetCmdPtr, int *objcPtr, Tcl_Obj ***objv); /* 149 */
+    ClientData (*tcl_GetAssocData) (Tcl_Interp *interp, const char *name, Tcl_InterpDeleteProc **procPtr); /* 150 */
+    Tcl_Channel (*tcl_GetChannel) (Tcl_Interp *interp, const char *chanName, int *modePtr); /* 151 */
+    int (*tcl_GetChannelBufferSize) (Tcl_Channel chan); /* 152 */
+    int (*tcl_GetChannelHandle) (Tcl_Channel chan, int direction, ClientData *handlePtr); /* 153 */
+    ClientData (*tcl_GetChannelInstanceData) (Tcl_Channel chan); /* 154 */
+    int (*tcl_GetChannelMode) (Tcl_Channel chan); /* 155 */
+    CONST84_RETURN char * (*tcl_GetChannelName) (Tcl_Channel chan); /* 156 */
+    int (*tcl_GetChannelOption) (Tcl_Interp *interp, Tcl_Channel chan, const char *optionName, Tcl_DString *dsPtr); /* 157 */
+    CONST86 Tcl_ChannelType * (*tcl_GetChannelType) (Tcl_Channel chan); /* 158 */
+    int (*tcl_GetCommandInfo) (Tcl_Interp *interp, const char *cmdName, Tcl_CmdInfo *infoPtr); /* 159 */
+    CONST84_RETURN char * (*tcl_GetCommandName) (Tcl_Interp *interp, Tcl_Command command); /* 160 */
+    int (*tcl_GetErrno) (void); /* 161 */
+    CONST84_RETURN char * (*tcl_GetHostName) (void); /* 162 */
+    int (*tcl_GetInterpPath) (Tcl_Interp *askInterp, Tcl_Interp *slaveInterp); /* 163 */
+    Tcl_Interp * (*tcl_GetMaster) (Tcl_Interp *interp); /* 164 */
+    const char * (*tcl_GetNameOfExecutable) (void); /* 165 */
+    Tcl_Obj * (*tcl_GetObjResult) (Tcl_Interp *interp); /* 166 */
+#if !defined(_WIN32) && !defined(MAC_OSX_TCL) /* UNIX */
+    int (*tcl_GetOpenFile) (Tcl_Interp *interp, const char *chanID, int forWriting, int checkUsage, ClientData *filePtr); /* 167 */
+#endif /* UNIX */
+#if defined(_WIN32) /* WIN */
+    void (*reserved167)(void);
+#endif /* WIN */
+#ifdef MAC_OSX_TCL /* MACOSX */
+    int (*tcl_GetOpenFile) (Tcl_Interp *interp, const char *chanID, int forWriting, int checkUsage, ClientData *filePtr); /* 167 */
+#endif /* MACOSX */
+    Tcl_PathType (*tcl_GetPathType) (const char *path); /* 168 */
+    int (*tcl_Gets) (Tcl_Channel chan, Tcl_DString *dsPtr); /* 169 */
+    int (*tcl_GetsObj) (Tcl_Channel chan, Tcl_Obj *objPtr); /* 170 */
+    int (*tcl_GetServiceMode) (void); /* 171 */
+    Tcl_Interp * (*tcl_GetSlave) (Tcl_Interp *interp, const char *slaveName); /* 172 */
+    Tcl_Channel (*tcl_GetStdChannel) (int type); /* 173 */
+    CONST84_RETURN char * (*tcl_GetStringResult) (Tcl_Interp *interp); /* 174 */
+    CONST84_RETURN char * (*tcl_GetVar) (Tcl_Interp *interp, const char *varName, int flags); /* 175 */
+    CONST84_RETURN char * (*tcl_GetVar2) (Tcl_Interp *interp, const char *part1, const char *part2, int flags); /* 176 */
+    int (*tcl_GlobalEval) (Tcl_Interp *interp, const char *command); /* 177 */
+    int (*tcl_GlobalEvalObj) (Tcl_Interp *interp, Tcl_Obj *objPtr); /* 178 */
+    int (*tcl_HideCommand) (Tcl_Interp *interp, const char *cmdName, const char *hiddenCmdToken); /* 179 */
+    int (*tcl_Init) (Tcl_Interp *interp); /* 180 */
+    void (*tcl_InitHashTable) (Tcl_HashTable *tablePtr, int keyType); /* 181 */
+    int (*tcl_InputBlocked) (Tcl_Channel chan); /* 182 */
+    int (*tcl_InputBuffered) (Tcl_Channel chan); /* 183 */
+    int (*tcl_InterpDeleted) (Tcl_Interp *interp); /* 184 */
+    int (*tcl_IsSafe) (Tcl_Interp *interp); /* 185 */
+    char * (*tcl_JoinPath) (int argc, CONST84 char *const *argv, Tcl_DString *resultPtr); /* 186 */
+    int (*tcl_LinkVar) (Tcl_Interp *interp, const char *varName, char *addr, int type); /* 187 */
+    void (*reserved188)(void);
+    Tcl_Channel (*tcl_MakeFileChannel) (ClientData handle, int mode); /* 189 */
+    int (*tcl_MakeSafe) (Tcl_Interp *interp); /* 190 */
+    Tcl_Channel (*tcl_MakeTcpClientChannel) (ClientData tcpSocket); /* 191 */
+    char * (*tcl_Merge) (int argc, CONST84 char *const *argv); /* 192 */
+    Tcl_HashEntry * (*tcl_NextHashEntry) (Tcl_HashSearch *searchPtr); /* 193 */
+    void (*tcl_NotifyChannel) (Tcl_Channel channel, int mask); /* 194 */
+    Tcl_Obj * (*tcl_ObjGetVar2) (Tcl_Interp *interp, Tcl_Obj *part1Ptr, Tcl_Obj *part2Ptr, int flags); /* 195 */
+    Tcl_Obj * (*tcl_ObjSetVar2) (Tcl_Interp *interp, Tcl_Obj *part1Ptr, Tcl_Obj *part2Ptr, Tcl_Obj *newValuePtr, int flags); /* 196 */
+    Tcl_Channel (*tcl_OpenCommandChannel) (Tcl_Interp *interp, int argc, CONST84 char **argv, int flags); /* 197 */
+    Tcl_Channel (*tcl_OpenFileChannel) (Tcl_Interp *interp, const char *fileName, const char *modeString, int permissions); /* 198 */
+    Tcl_Channel (*tcl_OpenTcpClient) (Tcl_Interp *interp, int port, const char *address, const char *myaddr, int myport, int async); /* 199 */
+    Tcl_Channel (*tcl_OpenTcpServer) (Tcl_Interp *interp, int port, const char *host, Tcl_TcpAcceptProc *acceptProc, ClientData callbackData); /* 200 */
+    void (*tcl_Preserve) (ClientData data); /* 201 */
+    void (*tcl_PrintDouble) (Tcl_Interp *interp, double value, char *dst); /* 202 */
+    int (*tcl_PutEnv) (const char *assignment); /* 203 */
+    CONST84_RETURN char * (*tcl_PosixError) (Tcl_Interp *interp); /* 204 */
+    void (*tcl_QueueEvent) (Tcl_Event *evPtr, Tcl_QueuePosition position); /* 205 */
+    int (*tcl_Read) (Tcl_Channel chan, char *bufPtr, int toRead); /* 206 */
+    void (*tcl_ReapDetachedProcs) (void); /* 207 */
+    int (*tcl_RecordAndEval) (Tcl_Interp *interp, const char *cmd, int flags); /* 208 */
+    int (*tcl_RecordAndEvalObj) (Tcl_Interp *interp, Tcl_Obj *cmdPtr, int flags); /* 209 */
+    void (*tcl_RegisterChannel) (Tcl_Interp *interp, Tcl_Channel chan); /* 210 */
+    void (*tcl_RegisterObjType) (const Tcl_ObjType *typePtr); /* 211 */
+    Tcl_RegExp (*tcl_RegExpCompile) (Tcl_Interp *interp, const char *pattern); /* 212 */
+    int (*tcl_RegExpExec) (Tcl_Interp *interp, Tcl_RegExp regexp, const char *text, const char *start); /* 213 */
+    int (*tcl_RegExpMatch) (Tcl_Interp *interp, const char *text, const char *pattern); /* 214 */
+    void (*tcl_RegExpRange) (Tcl_RegExp regexp, int index, CONST84 char **startPtr, CONST84 char **endPtr); /* 215 */
+    void (*tcl_Release) (ClientData clientData); /* 216 */
+    void (*tcl_ResetResult) (Tcl_Interp *interp); /* 217 */
+    int (*tcl_ScanElement) (const char *src, int *flagPtr); /* 218 */
+    int (*tcl_ScanCountedElement) (const char *src, int length, int *flagPtr); /* 219 */
+    int (*tcl_SeekOld) (Tcl_Channel chan, int offset, int mode); /* 220 */
+    int (*tcl_ServiceAll) (void); /* 221 */
+    int (*tcl_ServiceEvent) (int flags); /* 222 */
+    void (*tcl_SetAssocData) (Tcl_Interp *interp, const char *name, Tcl_InterpDeleteProc *proc, ClientData clientData); /* 223 */
+    void (*tcl_SetChannelBufferSize) (Tcl_Channel chan, int sz); /* 224 */
+    int (*tcl_SetChannelOption) (Tcl_Interp *interp, Tcl_Channel chan, const char *optionName, const char *newValue); /* 225 */
+    int (*tcl_SetCommandInfo) (Tcl_Interp *interp, const char *cmdName, const Tcl_CmdInfo *infoPtr); /* 226 */
+    void (*tcl_SetErrno) (int err); /* 227 */
+    void (*tcl_SetErrorCode) (Tcl_Interp *interp, ...); /* 228 */
+    void (*tcl_SetMaxBlockTime) (const Tcl_Time *timePtr); /* 229 */
+    void (*tcl_SetPanicProc) (TCL_NORETURN1 Tcl_PanicProc *panicProc); /* 230 */
+    int (*tcl_SetRecursionLimit) (Tcl_Interp *interp, int depth); /* 231 */
+    void (*tcl_SetResult) (Tcl_Interp *interp, char *result, Tcl_FreeProc *freeProc); /* 232 */
+    int (*tcl_SetServiceMode) (int mode); /* 233 */
+    void (*tcl_SetObjErrorCode) (Tcl_Interp *interp, Tcl_Obj *errorObjPtr); /* 234 */
+    void (*tcl_SetObjResult) (Tcl_Interp *interp, Tcl_Obj *resultObjPtr); /* 235 */
+    void (*tcl_SetStdChannel) (Tcl_Channel channel, int type); /* 236 */
+    CONST84_RETURN char * (*tcl_SetVar) (Tcl_Interp *interp, const char *varName, const char *newValue, int flags); /* 237 */
+    CONST84_RETURN char * (*tcl_SetVar2) (Tcl_Interp *interp, const char *part1, const char *part2, const char *newValue, int flags); /* 238 */
+    CONST84_RETURN char * (*tcl_SignalId) (int sig); /* 239 */
+    CONST84_RETURN char * (*tcl_SignalMsg) (int sig); /* 240 */
+    void (*tcl_SourceRCFile) (Tcl_Interp *interp); /* 241 */
+    int (*tcl_SplitList) (Tcl_Interp *interp, const char *listStr, int *argcPtr, CONST84 char ***argvPtr); /* 242 */
+    void (*tcl_SplitPath) (const char *path, int *argcPtr, CONST84 char ***argvPtr); /* 243 */
+    void (*tcl_StaticPackage) (Tcl_Interp *interp, const char *pkgName, Tcl_PackageInitProc *initProc, Tcl_PackageInitProc *safeInitProc); /* 244 */
+    int (*tcl_StringMatch) (const char *str, const char *pattern); /* 245 */
+    int (*tcl_TellOld) (Tcl_Channel chan); /* 246 */
+    int (*tcl_TraceVar) (Tcl_Interp *interp, const char *varName, int flags, Tcl_VarTraceProc *proc, ClientData clientData); /* 247 */
+    int (*tcl_TraceVar2) (Tcl_Interp *interp, const char *part1, const char *part2, int flags, Tcl_VarTraceProc *proc, ClientData clientData); /* 248 */
+    char * (*tcl_TranslateFileName) (Tcl_Interp *interp, const char *name, Tcl_DString *bufferPtr); /* 249 */
+    int (*tcl_Ungets) (Tcl_Channel chan, const char *str, int len, int atHead); /* 250 */
+    void (*tcl_UnlinkVar) (Tcl_Interp *interp, const char *varName); /* 251 */
+    int (*tcl_UnregisterChannel) (Tcl_Interp *interp, Tcl_Channel chan); /* 252 */
+    int (*tcl_UnsetVar) (Tcl_Interp *interp, const char *varName, int flags); /* 253 */
+    int (*tcl_UnsetVar2) (Tcl_Interp *interp, const char *part1, const char *part2, int flags); /* 254 */
+    void (*tcl_UntraceVar) (Tcl_Interp *interp, const char *varName, int flags, Tcl_VarTraceProc *proc, ClientData clientData); /* 255 */
+    void (*tcl_UntraceVar2) (Tcl_Interp *interp, const char *part1, const char *part2, int flags, Tcl_VarTraceProc *proc, ClientData clientData); /* 256 */
+    void (*tcl_UpdateLinkedVar) (Tcl_Interp *interp, const char *varName); /* 257 */
+    int (*tcl_UpVar) (Tcl_Interp *interp, const char *frameName, const char *varName, const char *localName, int flags); /* 258 */
+    int (*tcl_UpVar2) (Tcl_Interp *interp, const char *frameName, const char *part1, const char *part2, const char *localName, int flags); /* 259 */
+    int (*tcl_VarEval) (Tcl_Interp *interp, ...); /* 260 */
+    ClientData (*tcl_VarTraceInfo) (Tcl_Interp *interp, const char *varName, int flags, Tcl_VarTraceProc *procPtr, ClientData prevClientData); /* 261 */
+    ClientData (*tcl_VarTraceInfo2) (Tcl_Interp *interp, const char *part1, const char *part2, int flags, Tcl_VarTraceProc *procPtr, ClientData prevClientData); /* 262 */
+    int (*tcl_Write) (Tcl_Channel chan, const char *s, int slen); /* 263 */
+    void (*tcl_WrongNumArgs) (Tcl_Interp *interp, int objc, Tcl_Obj *const objv[], const char *message); /* 264 */
+    int (*tcl_DumpActiveMemory) (const char *fileName); /* 265 */
+    void (*tcl_ValidateAllMemory) (const char *file, int line); /* 266 */
+    void (*tcl_AppendResultVA) (Tcl_Interp *interp, va_list argList); /* 267 */
+    void (*tcl_AppendStringsToObjVA) (Tcl_Obj *objPtr, va_list argList); /* 268 */
+    char * (*tcl_HashStats) (Tcl_HashTable *tablePtr); /* 269 */
+    CONST84_RETURN char * (*tcl_ParseVar) (Tcl_Interp *interp, const char *start, CONST84 char **termPtr); /* 270 */
+    CONST84_RETURN char * (*tcl_PkgPresent) (Tcl_Interp *interp, const char *name, const char *version, int exact); /* 271 */
+    CONST84_RETURN char * (*tcl_PkgPresentEx) (Tcl_Interp *interp, const char *name, const char *version, int exact, void *clientDataPtr); /* 272 */
+    int (*tcl_PkgProvide) (Tcl_Interp *interp, const char *name, const char *version); /* 273 */
+    CONST84_RETURN char * (*tcl_PkgRequire) (Tcl_Interp *interp, const char *name, const char *version, int exact); /* 274 */
+    void (*tcl_SetErrorCodeVA) (Tcl_Interp *interp, va_list argList); /* 275 */
+    int (*tcl_VarEvalVA) (Tcl_Interp *interp, va_list argList); /* 276 */
+    Tcl_Pid (*tcl_WaitPid) (Tcl_Pid pid, int *statPtr, int options); /* 277 */
+    TCL_NORETURN1 void (*tcl_PanicVA) (const char *format, va_list argList); /* 278 */
+    void (*tcl_GetVersion) (int *major, int *minor, int *patchLevel, int *type); /* 279 */
+    void (*tcl_InitMemory) (Tcl_Interp *interp); /* 280 */
+    Tcl_Channel (*tcl_StackChannel) (Tcl_Interp *interp, const Tcl_ChannelType *typePtr, ClientData instanceData, int mask, Tcl_Channel prevChan); /* 281 */
+    int (*tcl_UnstackChannel) (Tcl_Interp *interp, Tcl_Channel chan); /* 282 */
+    Tcl_Channel (*tcl_GetStackedChannel) (Tcl_Channel chan); /* 283 */
+    void (*tcl_SetMainLoop) (Tcl_MainLoopProc *proc); /* 284 */
+    void (*reserved285)(void);
+    void (*tcl_AppendObjToObj) (Tcl_Obj *objPtr, Tcl_Obj *appendObjPtr); /* 286 */
+    Tcl_Encoding (*tcl_CreateEncoding) (const Tcl_EncodingType *typePtr); /* 287 */
+    void (*tcl_CreateThreadExitHandler) (Tcl_ExitProc *proc, ClientData clientData); /* 288 */
+    void (*tcl_DeleteThreadExitHandler) (Tcl_ExitProc *proc, ClientData clientData); /* 289 */
+    void (*tcl_DiscardResult) (Tcl_SavedResult *statePtr); /* 290 */
+    int (*tcl_EvalEx) (Tcl_Interp *interp, const char *script, int numBytes, int flags); /* 291 */
+    int (*tcl_EvalObjv) (Tcl_Interp *interp, int objc, Tcl_Obj *const objv[], int flags); /* 292 */
+    int (*tcl_EvalObjEx) (Tcl_Interp *interp, Tcl_Obj *objPtr, int flags); /* 293 */
+    void (*tcl_ExitThread) (int status); /* 294 */
+    int (*tcl_ExternalToUtf) (Tcl_Interp *interp, Tcl_Encoding encoding, const char *src, int srcLen, int flags, Tcl_EncodingState *statePtr, char *dst, int dstLen, int *srcReadPtr, int *dstWrotePtr, int *dstCharsPtr); /* 295 */
+    char * (*tcl_ExternalToUtfDString) (Tcl_Encoding encoding, const char *src, int srcLen, Tcl_DString *dsPtr); /* 296 */
+    void (*tcl_FinalizeThread) (void); /* 297 */
+    void (*tcl_FinalizeNotifier) (ClientData clientData); /* 298 */
+    void (*tcl_FreeEncoding) (Tcl_Encoding encoding); /* 299 */
+    Tcl_ThreadId (*tcl_GetCurrentThread) (void); /* 300 */
+    Tcl_Encoding (*tcl_GetEncoding) (Tcl_Interp *interp, const char *name); /* 301 */
+    CONST84_RETURN char * (*tcl_GetEncodingName) (Tcl_Encoding encoding); /* 302 */
+    void (*tcl_GetEncodingNames) (Tcl_Interp *interp); /* 303 */
+    int (*tcl_GetIndexFromObjStruct) (Tcl_Interp *interp, Tcl_Obj *objPtr, const void *tablePtr, int offset, const char *msg, int flags, int *indexPtr); /* 304 */
+    void * (*tcl_GetThreadData) (Tcl_ThreadDataKey *keyPtr, int size); /* 305 */
+    Tcl_Obj * (*tcl_GetVar2Ex) (Tcl_Interp *interp, const char *part1, const char *part2, int flags); /* 306 */
+    ClientData (*tcl_InitNotifier) (void); /* 307 */
+    void (*tcl_MutexLock) (Tcl_Mutex *mutexPtr); /* 308 */
+    void (*tcl_MutexUnlock) (Tcl_Mutex *mutexPtr); /* 309 */
+    void (*tcl_ConditionNotify) (Tcl_Condition *condPtr); /* 310 */
+    void (*tcl_ConditionWait) (Tcl_Condition *condPtr, Tcl_Mutex *mutexPtr, const Tcl_Time *timePtr); /* 311 */
+    int (*tcl_NumUtfChars) (const char *src, int length); /* 312 */
+    int (*tcl_ReadChars) (Tcl_Channel channel, Tcl_Obj *objPtr, int charsToRead, int appendFlag); /* 313 */
+    void (*tcl_RestoreResult) (Tcl_Interp *interp, Tcl_SavedResult *statePtr); /* 314 */
+    void (*tcl_SaveResult) (Tcl_Interp *interp, Tcl_SavedResult *statePtr); /* 315 */
+    int (*tcl_SetSystemEncoding) (Tcl_Interp *interp, const char *name); /* 316 */
+    Tcl_Obj * (*tcl_SetVar2Ex) (Tcl_Interp *interp, const char *part1, const char *part2, Tcl_Obj *newValuePtr, int flags); /* 317 */
+    void (*tcl_ThreadAlert) (Tcl_ThreadId threadId); /* 318 */
+    void (*tcl_ThreadQueueEvent) (Tcl_ThreadId threadId, Tcl_Event *evPtr, Tcl_QueuePosition position); /* 319 */
+    Tcl_UniChar (*tcl_UniCharAtIndex) (const char *src, int index); /* 320 */
+    Tcl_UniChar (*tcl_UniCharToLower) (int ch); /* 321 */
+    Tcl_UniChar (*tcl_UniCharToTitle) (int ch); /* 322 */
+    Tcl_UniChar (*tcl_UniCharToUpper) (int ch); /* 323 */
+    int (*tcl_UniCharToUtf) (int ch, char *buf); /* 324 */
+    CONST84_RETURN char * (*tcl_UtfAtIndex) (const char *src, int index); /* 325 */
+    int (*tcl_UtfCharComplete) (const char *src, int length); /* 326 */
+    int (*tcl_UtfBackslash) (const char *src, int *readPtr, char *dst); /* 327 */
+    CONST84_RETURN char * (*tcl_UtfFindFirst) (const char *src, int ch); /* 328 */
+    CONST84_RETURN char * (*tcl_UtfFindLast) (const char *src, int ch); /* 329 */
+    CONST84_RETURN char * (*tcl_UtfNext) (const char *src); /* 330 */
+    CONST84_RETURN char * (*tcl_UtfPrev) (const char *src, const char *start); /* 331 */
+    int (*tcl_UtfToExternal) (Tcl_Interp *interp, Tcl_Encoding encoding, const char *src, int srcLen, int flags, Tcl_EncodingState *statePtr, char *dst, int dstLen, int *srcReadPtr, int *dstWrotePtr, int *dstCharsPtr); /* 332 */
+    char * (*tcl_UtfToExternalDString) (Tcl_Encoding encoding, const char *src, int srcLen, Tcl_DString *dsPtr); /* 333 */
+    int (*tcl_UtfToLower) (char *src); /* 334 */
+    int (*tcl_UtfToTitle) (char *src); /* 335 */
+    int (*tcl_UtfToUniChar) (const char *src, Tcl_UniChar *chPtr); /* 336 */
+    int (*tcl_UtfToUpper) (char *src); /* 337 */
+    int (*tcl_WriteChars) (Tcl_Channel chan, const char *src, int srcLen); /* 338 */
+    int (*tcl_WriteObj) (Tcl_Channel chan, Tcl_Obj *objPtr); /* 339 */
+    char * (*tcl_GetString) (Tcl_Obj *objPtr); /* 340 */
+    CONST84_RETURN char * (*tcl_GetDefaultEncodingDir) (void); /* 341 */
+    void (*tcl_SetDefaultEncodingDir) (const char *path); /* 342 */
+    void (*tcl_AlertNotifier) (ClientData clientData); /* 343 */
+    void (*tcl_ServiceModeHook) (int mode); /* 344 */
+    int (*tcl_UniCharIsAlnum) (int ch); /* 345 */
+    int (*tcl_UniCharIsAlpha) (int ch); /* 346 */
+    int (*tcl_UniCharIsDigit) (int ch); /* 347 */
+    int (*tcl_UniCharIsLower) (int ch); /* 348 */
+    int (*tcl_UniCharIsSpace) (int ch); /* 349 */
+    int (*tcl_UniCharIsUpper) (int ch); /* 350 */
+    int (*tcl_UniCharIsWordChar) (int ch); /* 351 */
+    int (*tcl_UniCharLen) (const Tcl_UniChar *uniStr); /* 352 */
+    int (*tcl_UniCharNcmp) (const Tcl_UniChar *ucs, const Tcl_UniChar *uct, unsigned long numChars); /* 353 */
+    char * (*tcl_UniCharToUtfDString) (const Tcl_UniChar *uniStr, int uniLength, Tcl_DString *dsPtr); /* 354 */
+    Tcl_UniChar * (*tcl_UtfToUniCharDString) (const char *src, int length, Tcl_DString *dsPtr); /* 355 */
+    Tcl_RegExp (*tcl_GetRegExpFromObj) (Tcl_Interp *interp, Tcl_Obj *patObj, int flags); /* 356 */
+    Tcl_Obj * (*tcl_EvalTokens) (Tcl_Interp *interp, Tcl_Token *tokenPtr, int count); /* 357 */
+    void (*tcl_FreeParse) (Tcl_Parse *parsePtr); /* 358 */
+    void (*tcl_LogCommandInfo) (Tcl_Interp *interp, const char *script, const char *command, int length); /* 359 */
+    int (*tcl_ParseBraces) (Tcl_Interp *interp, const char *start, int numBytes, Tcl_Parse *parsePtr, int append, CONST84 char **termPtr); /* 360 */
+    int (*tcl_ParseCommand) (Tcl_Interp *interp, const char *start, int numBytes, int nested, Tcl_Parse *parsePtr); /* 361 */
+    int (*tcl_ParseExpr) (Tcl_Interp *interp, const char *start, int numBytes, Tcl_Parse *parsePtr); /* 362 */
+    int (*tcl_ParseQuotedString) (Tcl_Interp *interp, const char *start, int numBytes, Tcl_Parse *parsePtr, int append, CONST84 char **termPtr); /* 363 */
+    int (*tcl_ParseVarName) (Tcl_Interp *interp, const char *start, int numBytes, Tcl_Parse *parsePtr, int append); /* 364 */
+    char * (*tcl_GetCwd) (Tcl_Interp *interp, Tcl_DString *cwdPtr); /* 365 */
+    int (*tcl_Chdir) (const char *dirName); /* 366 */
+    int (*tcl_Access) (const char *path, int mode); /* 367 */
+    int (*tcl_Stat) (const char *path, struct stat *bufPtr); /* 368 */
+    int (*tcl_UtfNcmp) (const char *s1, const char *s2, unsigned long n); /* 369 */
+    int (*tcl_UtfNcasecmp) (const char *s1, const char *s2, unsigned long n); /* 370 */
+    int (*tcl_StringCaseMatch) (const char *str, const char *pattern, int nocase); /* 371 */
+    int (*tcl_UniCharIsControl) (int ch); /* 372 */
+    int (*tcl_UniCharIsGraph) (int ch); /* 373 */
+    int (*tcl_UniCharIsPrint) (int ch); /* 374 */
+    int (*tcl_UniCharIsPunct) (int ch); /* 375 */
+    int (*tcl_RegExpExecObj) (Tcl_Interp *interp, Tcl_RegExp regexp, Tcl_Obj *textObj, int offset, int nmatches, int flags); /* 376 */
+    void (*tcl_RegExpGetInfo) (Tcl_RegExp regexp, Tcl_RegExpInfo *infoPtr); /* 377 */
+    Tcl_Obj * (*tcl_NewUnicodeObj) (const Tcl_UniChar *unicode, int numChars); /* 378 */
+    void (*tcl_SetUnicodeObj) (Tcl_Obj *objPtr, const Tcl_UniChar *unicode, int numChars); /* 379 */
+    int (*tcl_GetCharLength) (Tcl_Obj *objPtr); /* 380 */
+    Tcl_UniChar (*tcl_GetUniChar) (Tcl_Obj *objPtr, int index); /* 381 */
+    Tcl_UniChar * (*tcl_GetUnicode) (Tcl_Obj *objPtr); /* 382 */
+    Tcl_Obj * (*tcl_GetRange) (Tcl_Obj *objPtr, int first, int last); /* 383 */
+    void (*tcl_AppendUnicodeToObj) (Tcl_Obj *objPtr, const Tcl_UniChar *unicode, int length); /* 384 */
+    int (*tcl_RegExpMatchObj) (Tcl_Interp *interp, Tcl_Obj *textObj, Tcl_Obj *patternObj); /* 385 */
+    void (*tcl_SetNotifier) (Tcl_NotifierProcs *notifierProcPtr); /* 386 */
+    Tcl_Mutex * (*tcl_GetAllocMutex) (void); /* 387 */
+    int (*tcl_GetChannelNames) (Tcl_Interp *interp); /* 388 */
+    int (*tcl_GetChannelNamesEx) (Tcl_Interp *interp, const char *pattern); /* 389 */
+    int (*tcl_ProcObjCmd) (ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); /* 390 */
+    void (*tcl_ConditionFinalize) (Tcl_Condition *condPtr); /* 391 */
+    void (*tcl_MutexFinalize) (Tcl_Mutex *mutex); /* 392 */
+    int (*tcl_CreateThread) (Tcl_ThreadId *idPtr, Tcl_ThreadCreateProc *proc, ClientData clientData, int stackSize, int flags); /* 393 */
+    int (*tcl_ReadRaw) (Tcl_Channel chan, char *dst, int bytesToRead); /* 394 */
+    int (*tcl_WriteRaw) (Tcl_Channel chan, const char *src, int srcLen); /* 395 */
+    Tcl_Channel (*tcl_GetTopChannel) (Tcl_Channel chan); /* 396 */
+    int (*tcl_ChannelBuffered) (Tcl_Channel chan); /* 397 */
+    CONST84_RETURN char * (*tcl_ChannelName) (const Tcl_ChannelType *chanTypePtr); /* 398 */
+    Tcl_ChannelTypeVersion (*tcl_ChannelVersion) (const Tcl_ChannelType *chanTypePtr); /* 399 */
+    Tcl_DriverBlockModeProc * (*tcl_ChannelBlockModeProc) (const Tcl_ChannelType *chanTypePtr); /* 400 */
+    Tcl_DriverCloseProc * (*tcl_ChannelCloseProc) (const Tcl_ChannelType *chanTypePtr); /* 401 */
+    Tcl_DriverClose2Proc * (*tcl_ChannelClose2Proc) (const Tcl_ChannelType *chanTypePtr); /* 402 */
+    Tcl_DriverInputProc * (*tcl_ChannelInputProc) (const Tcl_ChannelType *chanTypePtr); /* 403 */
+    Tcl_DriverOutputProc * (*tcl_ChannelOutputProc) (const Tcl_ChannelType *chanTypePtr); /* 404 */
+    Tcl_DriverSeekProc * (*tcl_ChannelSeekProc) (const Tcl_ChannelType *chanTypePtr); /* 405 */
+    Tcl_DriverSetOptionProc * (*tcl_ChannelSetOptionProc) (const Tcl_ChannelType *chanTypePtr); /* 406 */
+    Tcl_DriverGetOptionProc * (*tcl_ChannelGetOptionProc) (const Tcl_ChannelType *chanTypePtr); /* 407 */
+    Tcl_DriverWatchProc * (*tcl_ChannelWatchProc) (const Tcl_ChannelType *chanTypePtr); /* 408 */
+    Tcl_DriverGetHandleProc * (*tcl_ChannelGetHandleProc) (const Tcl_ChannelType *chanTypePtr); /* 409 */
+    Tcl_DriverFlushProc * (*tcl_ChannelFlushProc) (const Tcl_ChannelType *chanTypePtr); /* 410 */
+    Tcl_DriverHandlerProc * (*tcl_ChannelHandlerProc) (const Tcl_ChannelType *chanTypePtr); /* 411 */
+    int (*tcl_JoinThread) (Tcl_ThreadId threadId, int *result); /* 412 */
+    int (*tcl_IsChannelShared) (Tcl_Channel channel); /* 413 */
+    int (*tcl_IsChannelRegistered) (Tcl_Interp *interp, Tcl_Channel channel); /* 414 */
+    void (*tcl_CutChannel) (Tcl_Channel channel); /* 415 */
+    void (*tcl_SpliceChannel) (Tcl_Channel channel); /* 416 */
+    void (*tcl_ClearChannelHandlers) (Tcl_Channel channel); /* 417 */
+    int (*tcl_IsChannelExisting) (const char *channelName); /* 418 */
+    int (*tcl_UniCharNcasecmp) (const Tcl_UniChar *ucs, const Tcl_UniChar *uct, unsigned long numChars); /* 419 */
+    int (*tcl_UniCharCaseMatch) (const Tcl_UniChar *uniStr, const Tcl_UniChar *uniPattern, int nocase); /* 420 */
+    Tcl_HashEntry * (*tcl_FindHashEntry) (Tcl_HashTable *tablePtr, const void *key); /* 421 */
+    Tcl_HashEntry * (*tcl_CreateHashEntry) (Tcl_HashTable *tablePtr, const void *key, int *newPtr); /* 422 */
+    void (*tcl_InitCustomHashTable) (Tcl_HashTable *tablePtr, int keyType, const Tcl_HashKeyType *typePtr); /* 423 */
+    void (*tcl_InitObjHashTable) (Tcl_HashTable *tablePtr); /* 424 */
+    ClientData (*tcl_CommandTraceInfo) (Tcl_Interp *interp, const char *varName, int flags, Tcl_CommandTraceProc *procPtr, ClientData prevClientData); /* 425 */
+    int (*tcl_TraceCommand) (Tcl_Interp *interp, const char *varName, int flags, Tcl_CommandTraceProc *proc, ClientData clientData); /* 426 */
+    void (*tcl_UntraceCommand) (Tcl_Interp *interp, const char *varName, int flags, Tcl_CommandTraceProc *proc, ClientData clientData); /* 427 */
+    char * (*tcl_AttemptAlloc) (unsigned int size); /* 428 */
+    char * (*tcl_AttemptDbCkalloc) (unsigned int size, const char *file, int line); /* 429 */
+    char * (*tcl_AttemptRealloc) (char *ptr, unsigned int size); /* 430 */
+    char * (*tcl_AttemptDbCkrealloc) (char *ptr, unsigned int size, const char *file, int line); /* 431 */
+    int (*tcl_AttemptSetObjLength) (Tcl_Obj *objPtr, int length); /* 432 */
+    Tcl_ThreadId (*tcl_GetChannelThread) (Tcl_Channel channel); /* 433 */
+    Tcl_UniChar * (*tcl_GetUnicodeFromObj) (Tcl_Obj *objPtr, int *lengthPtr); /* 434 */
+    int (*tcl_GetMathFuncInfo) (Tcl_Interp *interp, const char *name, int *numArgsPtr, Tcl_ValueType **argTypesPtr, Tcl_MathProc **procPtr, ClientData *clientDataPtr); /* 435 */
+    Tcl_Obj * (*tcl_ListMathFuncs) (Tcl_Interp *interp, const char *pattern); /* 436 */
+    Tcl_Obj * (*tcl_SubstObj) (Tcl_Interp *interp, Tcl_Obj *objPtr, int flags); /* 437 */
+    int (*tcl_DetachChannel) (Tcl_Interp *interp, Tcl_Channel channel); /* 438 */
+    int (*tcl_IsStandardChannel) (Tcl_Channel channel); /* 439 */
+    int (*tcl_FSCopyFile) (Tcl_Obj *srcPathPtr, Tcl_Obj *destPathPtr); /* 440 */
+    int (*tcl_FSCopyDirectory) (Tcl_Obj *srcPathPtr, Tcl_Obj *destPathPtr, Tcl_Obj **errorPtr); /* 441 */
+    int (*tcl_FSCreateDirectory) (Tcl_Obj *pathPtr); /* 442 */
+    int (*tcl_FSDeleteFile) (Tcl_Obj *pathPtr); /* 443 */
+    int (*tcl_FSLoadFile) (Tcl_Interp *interp, Tcl_Obj *pathPtr, const char *sym1, const char *sym2, Tcl_PackageInitProc **proc1Ptr, Tcl_PackageInitProc **proc2Ptr, Tcl_LoadHandle *handlePtr, Tcl_FSUnloadFileProc **unloadProcPtr); /* 444 */
+    int (*tcl_FSMatchInDirectory) (Tcl_Interp *interp, Tcl_Obj *result, Tcl_Obj *pathPtr, const char *pattern, Tcl_GlobTypeData *types); /* 445 */
+    Tcl_Obj * (*tcl_FSLink) (Tcl_Obj *pathPtr, Tcl_Obj *toPtr, int linkAction); /* 446 */
+    int (*tcl_FSRemoveDirectory) (Tcl_Obj *pathPtr, int recursive, Tcl_Obj **errorPtr); /* 447 */
+    int (*tcl_FSRenameFile) (Tcl_Obj *srcPathPtr, Tcl_Obj *destPathPtr); /* 448 */
+    int (*tcl_FSLstat) (Tcl_Obj *pathPtr, Tcl_StatBuf *buf); /* 449 */
+    int (*tcl_FSUtime) (Tcl_Obj *pathPtr, struct utimbuf *tval); /* 450 */
+    int (*tcl_FSFileAttrsGet) (Tcl_Interp *interp, int index, Tcl_Obj *pathPtr, Tcl_Obj **objPtrRef); /* 451 */
+    int (*tcl_FSFileAttrsSet) (Tcl_Interp *interp, int index, Tcl_Obj *pathPtr, Tcl_Obj *objPtr); /* 452 */
+    const char *CONST86 * (*tcl_FSFileAttrStrings) (Tcl_Obj *pathPtr, Tcl_Obj **objPtrRef); /* 453 */
+    int (*tcl_FSStat) (Tcl_Obj *pathPtr, Tcl_StatBuf *buf); /* 454 */
+    int (*tcl_FSAccess) (Tcl_Obj *pathPtr, int mode); /* 455 */
+    Tcl_Channel (*tcl_FSOpenFileChannel) (Tcl_Interp *interp, Tcl_Obj *pathPtr, const char *modeString, int permissions); /* 456 */
+    Tcl_Obj * (*tcl_FSGetCwd) (Tcl_Interp *interp); /* 457 */
+    int (*tcl_FSChdir) (Tcl_Obj *pathPtr); /* 458 */
+    int (*tcl_FSConvertToPathType) (Tcl_Interp *interp, Tcl_Obj *pathPtr); /* 459 */
+    Tcl_Obj * (*tcl_FSJoinPath) (Tcl_Obj *listObj, int elements); /* 460 */
+    Tcl_Obj * (*tcl_FSSplitPath) (Tcl_Obj *pathPtr, int *lenPtr); /* 461 */
+    int (*tcl_FSEqualPaths) (Tcl_Obj *firstPtr, Tcl_Obj *secondPtr); /* 462 */
+    Tcl_Obj * (*tcl_FSGetNormalizedPath) (Tcl_Interp *interp, Tcl_Obj *pathPtr); /* 463 */
+    Tcl_Obj * (*tcl_FSJoinToPath) (Tcl_Obj *pathPtr, int objc, Tcl_Obj *const objv[]); /* 464 */
+    ClientData (*tcl_FSGetInternalRep) (Tcl_Obj *pathPtr, const Tcl_Filesystem *fsPtr); /* 465 */
+    Tcl_Obj * (*tcl_FSGetTranslatedPath) (Tcl_Interp *interp, Tcl_Obj *pathPtr); /* 466 */
+    int (*tcl_FSEvalFile) (Tcl_Interp *interp, Tcl_Obj *fileName); /* 467 */
+    Tcl_Obj * (*tcl_FSNewNativePath) (const Tcl_Filesystem *fromFilesystem, ClientData clientData); /* 468 */
+    const void * (*tcl_FSGetNativePath) (Tcl_Obj *pathPtr); /* 469 */
+    Tcl_Obj * (*tcl_FSFileSystemInfo) (Tcl_Obj *pathPtr); /* 470 */
+    Tcl_Obj * (*tcl_FSPathSeparator) (Tcl_Obj *pathPtr); /* 471 */
+    Tcl_Obj * (*tcl_FSListVolumes) (void); /* 472 */
+    int (*tcl_FSRegister) (ClientData clientData, const Tcl_Filesystem *fsPtr); /* 473 */
+    int (*tcl_FSUnregister) (const Tcl_Filesystem *fsPtr); /* 474 */
+    ClientData (*tcl_FSData) (const Tcl_Filesystem *fsPtr); /* 475 */
+    const char * (*tcl_FSGetTranslatedStringPath) (Tcl_Interp *interp, Tcl_Obj *pathPtr); /* 476 */
+    CONST86 Tcl_Filesystem * (*tcl_FSGetFileSystemForPath) (Tcl_Obj *pathPtr); /* 477 */
+    Tcl_PathType (*tcl_FSGetPathType) (Tcl_Obj *pathPtr); /* 478 */
+    int (*tcl_OutputBuffered) (Tcl_Channel chan); /* 479 */
+    void (*tcl_FSMountsChanged) (const Tcl_Filesystem *fsPtr); /* 480 */
+    int (*tcl_EvalTokensStandard) (Tcl_Interp *interp, Tcl_Token *tokenPtr, int count); /* 481 */
+    void (*tcl_GetTime) (Tcl_Time *timeBuf); /* 482 */
+    Tcl_Trace (*tcl_CreateObjTrace) (Tcl_Interp *interp, int level, int flags, Tcl_CmdObjTraceProc *objProc, ClientData clientData, Tcl_CmdObjTraceDeleteProc *delProc); /* 483 */
+    int (*tcl_GetCommandInfoFromToken) (Tcl_Command token, Tcl_CmdInfo *infoPtr); /* 484 */
+    int (*tcl_SetCommandInfoFromToken) (Tcl_Command token, const Tcl_CmdInfo *infoPtr); /* 485 */
+    Tcl_Obj * (*tcl_DbNewWideIntObj) (Tcl_WideInt wideValue, const char *file, int line); /* 486 */
+    int (*tcl_GetWideIntFromObj) (Tcl_Interp *interp, Tcl_Obj *objPtr, Tcl_WideInt *widePtr); /* 487 */
+    Tcl_Obj * (*tcl_NewWideIntObj) (Tcl_WideInt wideValue); /* 488 */
+    void (*tcl_SetWideIntObj) (Tcl_Obj *objPtr, Tcl_WideInt wideValue); /* 489 */
+    Tcl_StatBuf * (*tcl_AllocStatBuf) (void); /* 490 */
+    Tcl_WideInt (*tcl_Seek) (Tcl_Channel chan, Tcl_WideInt offset, int mode); /* 491 */
+    Tcl_WideInt (*tcl_Tell) (Tcl_Channel chan); /* 492 */
+    Tcl_DriverWideSeekProc * (*tcl_ChannelWideSeekProc) (const Tcl_ChannelType *chanTypePtr); /* 493 */
+    int (*tcl_DictObjPut) (Tcl_Interp *interp, Tcl_Obj *dictPtr, Tcl_Obj *keyPtr, Tcl_Obj *valuePtr); /* 494 */
+    int (*tcl_DictObjGet) (Tcl_Interp *interp, Tcl_Obj *dictPtr, Tcl_Obj *keyPtr, Tcl_Obj **valuePtrPtr); /* 495 */
+    int (*tcl_DictObjRemove) (Tcl_Interp *interp, Tcl_Obj *dictPtr, Tcl_Obj *keyPtr); /* 496 */
+    int (*tcl_DictObjSize) (Tcl_Interp *interp, Tcl_Obj *dictPtr, int *sizePtr); /* 497 */
+    int (*tcl_DictObjFirst) (Tcl_Interp *interp, Tcl_Obj *dictPtr, Tcl_DictSearch *searchPtr, Tcl_Obj **keyPtrPtr, Tcl_Obj **valuePtrPtr, int *donePtr); /* 498 */
+    void (*tcl_DictObjNext) (Tcl_DictSearch *searchPtr, Tcl_Obj **keyPtrPtr, Tcl_Obj **valuePtrPtr, int *donePtr); /* 499 */
+    void (*tcl_DictObjDone) (Tcl_DictSearch *searchPtr); /* 500 */
+    int (*tcl_DictObjPutKeyList) (Tcl_Interp *interp, Tcl_Obj *dictPtr, int keyc, Tcl_Obj *const *keyv, Tcl_Obj *valuePtr); /* 501 */
+    int (*tcl_DictObjRemoveKeyList) (Tcl_Interp *interp, Tcl_Obj *dictPtr, int keyc, Tcl_Obj *const *keyv); /* 502 */
+    Tcl_Obj * (*tcl_NewDictObj) (void); /* 503 */
+    Tcl_Obj * (*tcl_DbNewDictObj) (const char *file, int line); /* 504 */
+    void (*tcl_RegisterConfig) (Tcl_Interp *interp, const char *pkgName, const Tcl_Config *configuration, const char *valEncoding); /* 505 */
+    Tcl_Namespace * (*tcl_CreateNamespace) (Tcl_Interp *interp, const char *name, ClientData clientData, Tcl_NamespaceDeleteProc *deleteProc); /* 506 */
+    void (*tcl_DeleteNamespace) (Tcl_Namespace *nsPtr); /* 507 */
+    int (*tcl_AppendExportList) (Tcl_Interp *interp, Tcl_Namespace *nsPtr, Tcl_Obj *objPtr); /* 508 */
+    int (*tcl_Export) (Tcl_Interp *interp, Tcl_Namespace *nsPtr, const char *pattern, int resetListFirst); /* 509 */
+    int (*tcl_Import) (Tcl_Interp *interp, Tcl_Namespace *nsPtr, const char *pattern, int allowOverwrite); /* 510 */
+    int (*tcl_ForgetImport) (Tcl_Interp *interp, Tcl_Namespace *nsPtr, const char *pattern); /* 511 */
+    Tcl_Namespace * (*tcl_GetCurrentNamespace) (Tcl_Interp *interp); /* 512 */
+    Tcl_Namespace * (*tcl_GetGlobalNamespace) (Tcl_Interp *interp); /* 513 */
+    Tcl_Namespace * (*tcl_FindNamespace) (Tcl_Interp *interp, const char *name, Tcl_Namespace *contextNsPtr, int flags); /* 514 */
+    Tcl_Command (*tcl_FindCommand) (Tcl_Interp *interp, const char *name, Tcl_Namespace *contextNsPtr, int flags); /* 515 */
+    Tcl_Command (*tcl_GetCommandFromObj) (Tcl_Interp *interp, Tcl_Obj *objPtr); /* 516 */
+    void (*tcl_GetCommandFullName) (Tcl_Interp *interp, Tcl_Command command, Tcl_Obj *objPtr); /* 517 */
+    int (*tcl_FSEvalFileEx) (Tcl_Interp *interp, Tcl_Obj *fileName, const char *encodingName); /* 518 */
+    Tcl_ExitProc * (*tcl_SetExitProc) (TCL_NORETURN1 Tcl_ExitProc *proc); /* 519 */
+    void (*tcl_LimitAddHandler) (Tcl_Interp *interp, int type, Tcl_LimitHandlerProc *handlerProc, ClientData clientData, Tcl_LimitHandlerDeleteProc *deleteProc); /* 520 */
+    void (*tcl_LimitRemoveHandler) (Tcl_Interp *interp, int type, Tcl_LimitHandlerProc *handlerProc, ClientData clientData); /* 521 */
+    int (*tcl_LimitReady) (Tcl_Interp *interp); /* 522 */
+    int (*tcl_LimitCheck) (Tcl_Interp *interp); /* 523 */
+    int (*tcl_LimitExceeded) (Tcl_Interp *interp); /* 524 */
+    void (*tcl_LimitSetCommands) (Tcl_Interp *interp, int commandLimit); /* 525 */
+    void (*tcl_LimitSetTime) (Tcl_Interp *interp, Tcl_Time *timeLimitPtr); /* 526 */
+    void (*tcl_LimitSetGranularity) (Tcl_Interp *interp, int type, int granularity); /* 527 */
+    int (*tcl_LimitTypeEnabled) (Tcl_Interp *interp, int type); /* 528 */
+    int (*tcl_LimitTypeExceeded) (Tcl_Interp *interp, int type); /* 529 */
+    void (*tcl_LimitTypeSet) (Tcl_Interp *interp, int type); /* 530 */
+    void (*tcl_LimitTypeReset) (Tcl_Interp *interp, int type); /* 531 */
+    int (*tcl_LimitGetCommands) (Tcl_Interp *interp); /* 532 */
+    void (*tcl_LimitGetTime) (Tcl_Interp *interp, Tcl_Time *timeLimitPtr); /* 533 */
+    int (*tcl_LimitGetGranularity) (Tcl_Interp *interp, int type); /* 534 */
+    Tcl_InterpState (*tcl_SaveInterpState) (Tcl_Interp *interp, int status); /* 535 */
+    int (*tcl_RestoreInterpState) (Tcl_Interp *interp, Tcl_InterpState state); /* 536 */
+    void (*tcl_DiscardInterpState) (Tcl_InterpState state); /* 537 */
+    int (*tcl_SetReturnOptions) (Tcl_Interp *interp, Tcl_Obj *options); /* 538 */
+    Tcl_Obj * (*tcl_GetReturnOptions) (Tcl_Interp *interp, int result); /* 539 */
+    int (*tcl_IsEnsemble) (Tcl_Command token); /* 540 */
+    Tcl_Command (*tcl_CreateEnsemble) (Tcl_Interp *interp, const char *name, Tcl_Namespace *namespacePtr, int flags); /* 541 */
+    Tcl_Command (*tcl_FindEnsemble) (Tcl_Interp *interp, Tcl_Obj *cmdNameObj, int flags); /* 542 */
+    int (*tcl_SetEnsembleSubcommandList) (Tcl_Interp *interp, Tcl_Command token, Tcl_Obj *subcmdList); /* 543 */
+    int (*tcl_SetEnsembleMappingDict) (Tcl_Interp *interp, Tcl_Command token, Tcl_Obj *mapDict); /* 544 */
+    int (*tcl_SetEnsembleUnknownHandler) (Tcl_Interp *interp, Tcl_Command token, Tcl_Obj *unknownList); /* 545 */
+    int (*tcl_SetEnsembleFlags) (Tcl_Interp *interp, Tcl_Command token, int flags); /* 546 */
+    int (*tcl_GetEnsembleSubcommandList) (Tcl_Interp *interp, Tcl_Command token, Tcl_Obj **subcmdListPtr); /* 547 */
+    int (*tcl_GetEnsembleMappingDict) (Tcl_Interp *interp, Tcl_Command token, Tcl_Obj **mapDictPtr); /* 548 */
+    int (*tcl_GetEnsembleUnknownHandler) (Tcl_Interp *interp, Tcl_Command token, Tcl_Obj **unknownListPtr); /* 549 */
+    int (*tcl_GetEnsembleFlags) (Tcl_Interp *interp, Tcl_Command token, int *flagsPtr); /* 550 */
+    int (*tcl_GetEnsembleNamespace) (Tcl_Interp *interp, Tcl_Command token, Tcl_Namespace **namespacePtrPtr); /* 551 */
+    void (*tcl_SetTimeProc) (Tcl_GetTimeProc *getProc, Tcl_ScaleTimeProc *scaleProc, ClientData clientData); /* 552 */
+    void (*tcl_QueryTimeProc) (Tcl_GetTimeProc **getProc, Tcl_ScaleTimeProc **scaleProc, ClientData *clientData); /* 553 */
+    Tcl_DriverThreadActionProc * (*tcl_ChannelThreadActionProc) (const Tcl_ChannelType *chanTypePtr); /* 554 */
+    Tcl_Obj * (*tcl_NewBignumObj) (mp_int *value); /* 555 */
+    Tcl_Obj * (*tcl_DbNewBignumObj) (mp_int *value, const char *file, int line); /* 556 */
+    void (*tcl_SetBignumObj) (Tcl_Obj *obj, mp_int *value); /* 557 */
+    int (*tcl_GetBignumFromObj) (Tcl_Interp *interp, Tcl_Obj *obj, mp_int *value); /* 558 */
+    int (*tcl_TakeBignumFromObj) (Tcl_Interp *interp, Tcl_Obj *obj, mp_int *value); /* 559 */
+    int (*tcl_TruncateChannel) (Tcl_Channel chan, Tcl_WideInt length); /* 560 */
+    Tcl_DriverTruncateProc * (*tcl_ChannelTruncateProc) (const Tcl_ChannelType *chanTypePtr); /* 561 */
+    void (*tcl_SetChannelErrorInterp) (Tcl_Interp *interp, Tcl_Obj *msg); /* 562 */
+    void (*tcl_GetChannelErrorInterp) (Tcl_Interp *interp, Tcl_Obj **msg); /* 563 */
+    void (*tcl_SetChannelError) (Tcl_Channel chan, Tcl_Obj *msg); /* 564 */
+    void (*tcl_GetChannelError) (Tcl_Channel chan, Tcl_Obj **msg); /* 565 */
+    int (*tcl_InitBignumFromDouble) (Tcl_Interp *interp, double initval, mp_int *toInit); /* 566 */
+    Tcl_Obj * (*tcl_GetNamespaceUnknownHandler) (Tcl_Interp *interp, Tcl_Namespace *nsPtr); /* 567 */
+    int (*tcl_SetNamespaceUnknownHandler) (Tcl_Interp *interp, Tcl_Namespace *nsPtr, Tcl_Obj *handlerPtr); /* 568 */
+    int (*tcl_GetEncodingFromObj) (Tcl_Interp *interp, Tcl_Obj *objPtr, Tcl_Encoding *encodingPtr); /* 569 */
+    Tcl_Obj * (*tcl_GetEncodingSearchPath) (void); /* 570 */
+    int (*tcl_SetEncodingSearchPath) (Tcl_Obj *searchPath); /* 571 */
+    const char * (*tcl_GetEncodingNameFromEnvironment) (Tcl_DString *bufPtr); /* 572 */
+    int (*tcl_PkgRequireProc) (Tcl_Interp *interp, const char *name, int objc, Tcl_Obj *const objv[], void *clientDataPtr); /* 573 */
+    void (*tcl_AppendObjToErrorInfo) (Tcl_Interp *interp, Tcl_Obj *objPtr); /* 574 */
+    void (*tcl_AppendLimitedToObj) (Tcl_Obj *objPtr, const char *bytes, int length, int limit, const char *ellipsis); /* 575 */
+    Tcl_Obj * (*tcl_Format) (Tcl_Interp *interp, const char *format, int objc, Tcl_Obj *const objv[]); /* 576 */
+    int (*tcl_AppendFormatToObj) (Tcl_Interp *interp, Tcl_Obj *objPtr, const char *format, int objc, Tcl_Obj *const objv[]); /* 577 */
+    Tcl_Obj * (*tcl_ObjPrintf) (const char *format, ...) TCL_FORMAT_PRINTF(1, 2); /* 578 */
+    void (*tcl_AppendPrintfToObj) (Tcl_Obj *objPtr, const char *format, ...) TCL_FORMAT_PRINTF(2, 3); /* 579 */
+    int (*tcl_CancelEval) (Tcl_Interp *interp, Tcl_Obj *resultObjPtr, ClientData clientData, int flags); /* 580 */
+    int (*tcl_Canceled) (Tcl_Interp *interp, int flags); /* 581 */
+    int (*tcl_CreatePipe) (Tcl_Interp *interp, Tcl_Channel *rchan, Tcl_Channel *wchan, int flags); /* 582 */
+    Tcl_Command (*tcl_NRCreateCommand) (Tcl_Interp *interp, const char *cmdName, Tcl_ObjCmdProc *proc, Tcl_ObjCmdProc *nreProc, ClientData clientData, Tcl_CmdDeleteProc *deleteProc); /* 583 */
+    int (*tcl_NREvalObj) (Tcl_Interp *interp, Tcl_Obj *objPtr, int flags); /* 584 */
+    int (*tcl_NREvalObjv) (Tcl_Interp *interp, int objc, Tcl_Obj *const objv[], int flags); /* 585 */
+    int (*tcl_NRCmdSwap) (Tcl_Interp *interp, Tcl_Command cmd, int objc, Tcl_Obj *const objv[], int flags); /* 586 */
+    void (*tcl_NRAddCallback) (Tcl_Interp *interp, Tcl_NRPostProc *postProcPtr, ClientData data0, ClientData data1, ClientData data2, ClientData data3); /* 587 */
+    int (*tcl_NRCallObjProc) (Tcl_Interp *interp, Tcl_ObjCmdProc *objProc, ClientData clientData, int objc, Tcl_Obj *const objv[]); /* 588 */
+    unsigned (*tcl_GetFSDeviceFromStat) (const Tcl_StatBuf *statPtr); /* 589 */
+    unsigned (*tcl_GetFSInodeFromStat) (const Tcl_StatBuf *statPtr); /* 590 */
+    unsigned (*tcl_GetModeFromStat) (const Tcl_StatBuf *statPtr); /* 591 */
+    int (*tcl_GetLinkCountFromStat) (const Tcl_StatBuf *statPtr); /* 592 */
+    int (*tcl_GetUserIdFromStat) (const Tcl_StatBuf *statPtr); /* 593 */
+    int (*tcl_GetGroupIdFromStat) (const Tcl_StatBuf *statPtr); /* 594 */
+    int (*tcl_GetDeviceTypeFromStat) (const Tcl_StatBuf *statPtr); /* 595 */
+    Tcl_WideInt (*tcl_GetAccessTimeFromStat) (const Tcl_StatBuf *statPtr); /* 596 */
+    Tcl_WideInt (*tcl_GetModificationTimeFromStat) (const Tcl_StatBuf *statPtr); /* 597 */
+    Tcl_WideInt (*tcl_GetChangeTimeFromStat) (const Tcl_StatBuf *statPtr); /* 598 */
+    Tcl_WideUInt (*tcl_GetSizeFromStat) (const Tcl_StatBuf *statPtr); /* 599 */
+    Tcl_WideUInt (*tcl_GetBlocksFromStat) (const Tcl_StatBuf *statPtr); /* 600 */
+    unsigned (*tcl_GetBlockSizeFromStat) (const Tcl_StatBuf *statPtr); /* 601 */
+    int (*tcl_SetEnsembleParameterList) (Tcl_Interp *interp, Tcl_Command token, Tcl_Obj *paramList); /* 602 */
+    int (*tcl_GetEnsembleParameterList) (Tcl_Interp *interp, Tcl_Command token, Tcl_Obj **paramListPtr); /* 603 */
+    int (*tcl_ParseArgsObjv) (Tcl_Interp *interp, const Tcl_ArgvInfo *argTable, int *objcPtr, Tcl_Obj *const *objv, Tcl_Obj ***remObjv); /* 604 */
+    int (*tcl_GetErrorLine) (Tcl_Interp *interp); /* 605 */
+    void (*tcl_SetErrorLine) (Tcl_Interp *interp, int lineNum); /* 606 */
+    void (*tcl_TransferResult) (Tcl_Interp *sourceInterp, int result, Tcl_Interp *targetInterp); /* 607 */
+    int (*tcl_InterpActive) (Tcl_Interp *interp); /* 608 */
+    void (*tcl_BackgroundException) (Tcl_Interp *interp, int code); /* 609 */
+    int (*tcl_ZlibDeflate) (Tcl_Interp *interp, int format, Tcl_Obj *data, int level, Tcl_Obj *gzipHeaderDictObj); /* 610 */
+    int (*tcl_ZlibInflate) (Tcl_Interp *interp, int format, Tcl_Obj *data, int buffersize, Tcl_Obj *gzipHeaderDictObj); /* 611 */
+    unsigned int (*tcl_ZlibCRC32) (unsigned int crc, const unsigned char *buf, int len); /* 612 */
+    unsigned int (*tcl_ZlibAdler32) (unsigned int adler, const unsigned char *buf, int len); /* 613 */
+    int (*tcl_ZlibStreamInit) (Tcl_Interp *interp, int mode, int format, int level, Tcl_Obj *dictObj, Tcl_ZlibStream *zshandle); /* 614 */
+    Tcl_Obj * (*tcl_ZlibStreamGetCommandName) (Tcl_ZlibStream zshandle); /* 615 */
+    int (*tcl_ZlibStreamEof) (Tcl_ZlibStream zshandle); /* 616 */
+    int (*tcl_ZlibStreamChecksum) (Tcl_ZlibStream zshandle); /* 617 */
+    int (*tcl_ZlibStreamPut) (Tcl_ZlibStream zshandle, Tcl_Obj *data, int flush); /* 618 */
+    int (*tcl_ZlibStreamGet) (Tcl_ZlibStream zshandle, Tcl_Obj *data, int count); /* 619 */
+    int (*tcl_ZlibStreamClose) (Tcl_ZlibStream zshandle); /* 620 */
+    int (*tcl_ZlibStreamReset) (Tcl_ZlibStream zshandle); /* 621 */
+    void (*tcl_SetStartupScript) (Tcl_Obj *path, const char *encoding); /* 622 */
+    Tcl_Obj * (*tcl_GetStartupScript) (const char **encodingPtr); /* 623 */
+    int (*tcl_CloseEx) (Tcl_Interp *interp, Tcl_Channel chan, int flags); /* 624 */
+    int (*tcl_NRExprObj) (Tcl_Interp *interp, Tcl_Obj *objPtr, Tcl_Obj *resultPtr); /* 625 */
+    int (*tcl_NRSubstObj) (Tcl_Interp *interp, Tcl_Obj *objPtr, int flags); /* 626 */
+    int (*tcl_LoadFile) (Tcl_Interp *interp, Tcl_Obj *pathPtr, const char *const symv[], int flags, void *procPtrs, Tcl_LoadHandle *handlePtr); /* 627 */
+    void * (*tcl_FindSymbol) (Tcl_Interp *interp, Tcl_LoadHandle handle, const char *symbol); /* 628 */
+    int (*tcl_FSUnloadFile) (Tcl_Interp *interp, Tcl_LoadHandle handlePtr); /* 629 */
+    void (*tcl_ZlibStreamSetCompressionDictionary) (Tcl_ZlibStream zhandle, Tcl_Obj *compressionDictionaryObj); /* 630 */
+} TclStubs;
+
+extern const TclStubs *tclStubsPtr;
+
+#ifdef __cplusplus
+}
+#endif
+
+#if defined(USE_TCL_STUBS)
+
+/*
+ * Inline function declarations:
+ */
+
+#define Tcl_PkgProvideEx \
+	(tclStubsPtr->tcl_PkgProvideEx) /* 0 */
+#define Tcl_PkgRequireEx \
+	(tclStubsPtr->tcl_PkgRequireEx) /* 1 */
+#define Tcl_Panic \
+	(tclStubsPtr->tcl_Panic) /* 2 */
+#define Tcl_Alloc \
+	(tclStubsPtr->tcl_Alloc) /* 3 */
+#define Tcl_Free \
+	(tclStubsPtr->tcl_Free) /* 4 */
+#define Tcl_Realloc \
+	(tclStubsPtr->tcl_Realloc) /* 5 */
+#define Tcl_DbCkalloc \
+	(tclStubsPtr->tcl_DbCkalloc) /* 6 */
+#define Tcl_DbCkfree \
+	(tclStubsPtr->tcl_DbCkfree) /* 7 */
+#define Tcl_DbCkrealloc \
+	(tclStubsPtr->tcl_DbCkrealloc) /* 8 */
+#if !defined(_WIN32) && !defined(MAC_OSX_TCL) /* UNIX */
+#define Tcl_CreateFileHandler \
+	(tclStubsPtr->tcl_CreateFileHandler) /* 9 */
+#endif /* UNIX */
+#ifdef MAC_OSX_TCL /* MACOSX */
+#define Tcl_CreateFileHandler \
+	(tclStubsPtr->tcl_CreateFileHandler) /* 9 */
+#endif /* MACOSX */
+#if !defined(_WIN32) && !defined(MAC_OSX_TCL) /* UNIX */
+#define Tcl_DeleteFileHandler \
+	(tclStubsPtr->tcl_DeleteFileHandler) /* 10 */
+#endif /* UNIX */
+#ifdef MAC_OSX_TCL /* MACOSX */
+#define Tcl_DeleteFileHandler \
+	(tclStubsPtr->tcl_DeleteFileHandler) /* 10 */
+#endif /* MACOSX */
+#define Tcl_SetTimer \
+	(tclStubsPtr->tcl_SetTimer) /* 11 */
+#define Tcl_Sleep \
+	(tclStubsPtr->tcl_Sleep) /* 12 */
+#define Tcl_WaitForEvent \
+	(tclStubsPtr->tcl_WaitForEvent) /* 13 */
+#define Tcl_AppendAllObjTypes \
+	(tclStubsPtr->tcl_AppendAllObjTypes) /* 14 */
+#define Tcl_AppendStringsToObj \
+	(tclStubsPtr->tcl_AppendStringsToObj) /* 15 */
+#define Tcl_AppendToObj \
+	(tclStubsPtr->tcl_AppendToObj) /* 16 */
+#define Tcl_ConcatObj \
+	(tclStubsPtr->tcl_ConcatObj) /* 17 */
+#define Tcl_ConvertToType \
+	(tclStubsPtr->tcl_ConvertToType) /* 18 */
+#define Tcl_DbDecrRefCount \
+	(tclStubsPtr->tcl_DbDecrRefCount) /* 19 */
+#define Tcl_DbIncrRefCount \
+	(tclStubsPtr->tcl_DbIncrRefCount) /* 20 */
+#define Tcl_DbIsShared \
+	(tclStubsPtr->tcl_DbIsShared) /* 21 */
+#define Tcl_DbNewBooleanObj \
+	(tclStubsPtr->tcl_DbNewBooleanObj) /* 22 */
+#define Tcl_DbNewByteArrayObj \
+	(tclStubsPtr->tcl_DbNewByteArrayObj) /* 23 */
+#define Tcl_DbNewDoubleObj \
+	(tclStubsPtr->tcl_DbNewDoubleObj) /* 24 */
+#define Tcl_DbNewListObj \
+	(tclStubsPtr->tcl_DbNewListObj) /* 25 */
+#define Tcl_DbNewLongObj \
+	(tclStubsPtr->tcl_DbNewLongObj) /* 26 */
+#define Tcl_DbNewObj \
+	(tclStubsPtr->tcl_DbNewObj) /* 27 */
+#define Tcl_DbNewStringObj \
+	(tclStubsPtr->tcl_DbNewStringObj) /* 28 */
+#define Tcl_DuplicateObj \
+	(tclStubsPtr->tcl_DuplicateObj) /* 29 */
+#define TclFreeObj \
+	(tclStubsPtr->tclFreeObj) /* 30 */
+#define Tcl_GetBoolean \
+	(tclStubsPtr->tcl_GetBoolean) /* 31 */
+#define Tcl_GetBooleanFromObj \
+	(tclStubsPtr->tcl_GetBooleanFromObj) /* 32 */
+#define Tcl_GetByteArrayFromObj \
+	(tclStubsPtr->tcl_GetByteArrayFromObj) /* 33 */
+#define Tcl_GetDouble \
+	(tclStubsPtr->tcl_GetDouble) /* 34 */
+#define Tcl_GetDoubleFromObj \
+	(tclStubsPtr->tcl_GetDoubleFromObj) /* 35 */
+#define Tcl_GetIndexFromObj \
+	(tclStubsPtr->tcl_GetIndexFromObj) /* 36 */
+#define Tcl_GetInt \
+	(tclStubsPtr->tcl_GetInt) /* 37 */
+#define Tcl_GetIntFromObj \
+	(tclStubsPtr->tcl_GetIntFromObj) /* 38 */
+#define Tcl_GetLongFromObj \
+	(tclStubsPtr->tcl_GetLongFromObj) /* 39 */
+#define Tcl_GetObjType \
+	(tclStubsPtr->tcl_GetObjType) /* 40 */
+#define Tcl_GetStringFromObj \
+	(tclStubsPtr->tcl_GetStringFromObj) /* 41 */
+#define Tcl_InvalidateStringRep \
+	(tclStubsPtr->tcl_InvalidateStringRep) /* 42 */
+#define Tcl_ListObjAppendList \
+	(tclStubsPtr->tcl_ListObjAppendList) /* 43 */
+#define Tcl_ListObjAppendElement \
+	(tclStubsPtr->tcl_ListObjAppendElement) /* 44 */
+#define Tcl_ListObjGetElements \
+	(tclStubsPtr->tcl_ListObjGetElements) /* 45 */
+#define Tcl_ListObjIndex \
+	(tclStubsPtr->tcl_ListObjIndex) /* 46 */
+#define Tcl_ListObjLength \
+	(tclStubsPtr->tcl_ListObjLength) /* 47 */
+#define Tcl_ListObjReplace \
+	(tclStubsPtr->tcl_ListObjReplace) /* 48 */
+#define Tcl_NewBooleanObj \
+	(tclStubsPtr->tcl_NewBooleanObj) /* 49 */
+#define Tcl_NewByteArrayObj \
+	(tclStubsPtr->tcl_NewByteArrayObj) /* 50 */
+#define Tcl_NewDoubleObj \
+	(tclStubsPtr->tcl_NewDoubleObj) /* 51 */
+#define Tcl_NewIntObj \
+	(tclStubsPtr->tcl_NewIntObj) /* 52 */
+#define Tcl_NewListObj \
+	(tclStubsPtr->tcl_NewListObj) /* 53 */
+#define Tcl_NewLongObj \
+	(tclStubsPtr->tcl_NewLongObj) /* 54 */
+#define Tcl_NewObj \
+	(tclStubsPtr->tcl_NewObj) /* 55 */
+#define Tcl_NewStringObj \
+	(tclStubsPtr->tcl_NewStringObj) /* 56 */
+#define Tcl_SetBooleanObj \
+	(tclStubsPtr->tcl_SetBooleanObj) /* 57 */
+#define Tcl_SetByteArrayLength \
+	(tclStubsPtr->tcl_SetByteArrayLength) /* 58 */
+#define Tcl_SetByteArrayObj \
+	(tclStubsPtr->tcl_SetByteArrayObj) /* 59 */
+#define Tcl_SetDoubleObj \
+	(tclStubsPtr->tcl_SetDoubleObj) /* 60 */
+#define Tcl_SetIntObj \
+	(tclStubsPtr->tcl_SetIntObj) /* 61 */
+#define Tcl_SetListObj \
+	(tclStubsPtr->tcl_SetListObj) /* 62 */
+#define Tcl_SetLongObj \
+	(tclStubsPtr->tcl_SetLongObj) /* 63 */
+#define Tcl_SetObjLength \
+	(tclStubsPtr->tcl_SetObjLength) /* 64 */
+#define Tcl_SetStringObj \
+	(tclStubsPtr->tcl_SetStringObj) /* 65 */
+#define Tcl_AddErrorInfo \
+	(tclStubsPtr->tcl_AddErrorInfo) /* 66 */
+#define Tcl_AddObjErrorInfo \
+	(tclStubsPtr->tcl_AddObjErrorInfo) /* 67 */
+#define Tcl_AllowExceptions \
+	(tclStubsPtr->tcl_AllowExceptions) /* 68 */
+#define Tcl_AppendElement \
+	(tclStubsPtr->tcl_AppendElement) /* 69 */
+#define Tcl_AppendResult \
+	(tclStubsPtr->tcl_AppendResult) /* 70 */
+#define Tcl_AsyncCreate \
+	(tclStubsPtr->tcl_AsyncCreate) /* 71 */
+#define Tcl_AsyncDelete \
+	(tclStubsPtr->tcl_AsyncDelete) /* 72 */
+#define Tcl_AsyncInvoke \
+	(tclStubsPtr->tcl_AsyncInvoke) /* 73 */
+#define Tcl_AsyncMark \
+	(tclStubsPtr->tcl_AsyncMark) /* 74 */
+#define Tcl_AsyncReady \
+	(tclStubsPtr->tcl_AsyncReady) /* 75 */
+#define Tcl_BackgroundError \
+	(tclStubsPtr->tcl_BackgroundError) /* 76 */
+#define Tcl_Backslash \
+	(tclStubsPtr->tcl_Backslash) /* 77 */
+#define Tcl_BadChannelOption \
+	(tclStubsPtr->tcl_BadChannelOption) /* 78 */
+#define Tcl_CallWhenDeleted \
+	(tclStubsPtr->tcl_CallWhenDeleted) /* 79 */
+#define Tcl_CancelIdleCall \
+	(tclStubsPtr->tcl_CancelIdleCall) /* 80 */
+#define Tcl_Close \
+	(tclStubsPtr->tcl_Close) /* 81 */
+#define Tcl_CommandComplete \
+	(tclStubsPtr->tcl_CommandComplete) /* 82 */
+#define Tcl_Concat \
+	(tclStubsPtr->tcl_Concat) /* 83 */
+#define Tcl_ConvertElement \
+	(tclStubsPtr->tcl_ConvertElement) /* 84 */
+#define Tcl_ConvertCountedElement \
+	(tclStubsPtr->tcl_ConvertCountedElement) /* 85 */
+#define Tcl_CreateAlias \
+	(tclStubsPtr->tcl_CreateAlias) /* 86 */
+#define Tcl_CreateAliasObj \
+	(tclStubsPtr->tcl_CreateAliasObj) /* 87 */
+#define Tcl_CreateChannel \
+	(tclStubsPtr->tcl_CreateChannel) /* 88 */
+#define Tcl_CreateChannelHandler \
+	(tclStubsPtr->tcl_CreateChannelHandler) /* 89 */
+#define Tcl_CreateCloseHandler \
+	(tclStubsPtr->tcl_CreateCloseHandler) /* 90 */
+#define Tcl_CreateCommand \
+	(tclStubsPtr->tcl_CreateCommand) /* 91 */
+#define Tcl_CreateEventSource \
+	(tclStubsPtr->tcl_CreateEventSource) /* 92 */
+#define Tcl_CreateExitHandler \
+	(tclStubsPtr->tcl_CreateExitHandler) /* 93 */
+#define Tcl_CreateInterp \
+	(tclStubsPtr->tcl_CreateInterp) /* 94 */
+#define Tcl_CreateMathFunc \
+	(tclStubsPtr->tcl_CreateMathFunc) /* 95 */
+#define Tcl_CreateObjCommand \
+	(tclStubsPtr->tcl_CreateObjCommand) /* 96 */
+#define Tcl_CreateSlave \
+	(tclStubsPtr->tcl_CreateSlave) /* 97 */
+#define Tcl_CreateTimerHandler \
+	(tclStubsPtr->tcl_CreateTimerHandler) /* 98 */
+#define Tcl_CreateTrace \
+	(tclStubsPtr->tcl_CreateTrace) /* 99 */
+#define Tcl_DeleteAssocData \
+	(tclStubsPtr->tcl_DeleteAssocData) /* 100 */
+#define Tcl_DeleteChannelHandler \
+	(tclStubsPtr->tcl_DeleteChannelHandler) /* 101 */
+#define Tcl_DeleteCloseHandler \
+	(tclStubsPtr->tcl_DeleteCloseHandler) /* 102 */
+#define Tcl_DeleteCommand \
+	(tclStubsPtr->tcl_DeleteCommand) /* 103 */
+#define Tcl_DeleteCommandFromToken \
+	(tclStubsPtr->tcl_DeleteCommandFromToken) /* 104 */
+#define Tcl_DeleteEvents \
+	(tclStubsPtr->tcl_DeleteEvents) /* 105 */
+#define Tcl_DeleteEventSource \
+	(tclStubsPtr->tcl_DeleteEventSource) /* 106 */
+#define Tcl_DeleteExitHandler \
+	(tclStubsPtr->tcl_DeleteExitHandler) /* 107 */
+#define Tcl_DeleteHashEntry \
+	(tclStubsPtr->tcl_DeleteHashEntry) /* 108 */
+#define Tcl_DeleteHashTable \
+	(tclStubsPtr->tcl_DeleteHashTable) /* 109 */
+#define Tcl_DeleteInterp \
+	(tclStubsPtr->tcl_DeleteInterp) /* 110 */
+#define Tcl_DetachPids \
+	(tclStubsPtr->tcl_DetachPids) /* 111 */
+#define Tcl_DeleteTimerHandler \
+	(tclStubsPtr->tcl_DeleteTimerHandler) /* 112 */
+#define Tcl_DeleteTrace \
+	(tclStubsPtr->tcl_DeleteTrace) /* 113 */
+#define Tcl_DontCallWhenDeleted \
+	(tclStubsPtr->tcl_DontCallWhenDeleted) /* 114 */
+#define Tcl_DoOneEvent \
+	(tclStubsPtr->tcl_DoOneEvent) /* 115 */
+#define Tcl_DoWhenIdle \
+	(tclStubsPtr->tcl_DoWhenIdle) /* 116 */
+#define Tcl_DStringAppend \
+	(tclStubsPtr->tcl_DStringAppend) /* 117 */
+#define Tcl_DStringAppendElement \
+	(tclStubsPtr->tcl_DStringAppendElement) /* 118 */
+#define Tcl_DStringEndSublist \
+	(tclStubsPtr->tcl_DStringEndSublist) /* 119 */
+#define Tcl_DStringFree \
+	(tclStubsPtr->tcl_DStringFree) /* 120 */
+#define Tcl_DStringGetResult \
+	(tclStubsPtr->tcl_DStringGetResult) /* 121 */
+#define Tcl_DStringInit \
+	(tclStubsPtr->tcl_DStringInit) /* 122 */
+#define Tcl_DStringResult \
+	(tclStubsPtr->tcl_DStringResult) /* 123 */
+#define Tcl_DStringSetLength \
+	(tclStubsPtr->tcl_DStringSetLength) /* 124 */
+#define Tcl_DStringStartSublist \
+	(tclStubsPtr->tcl_DStringStartSublist) /* 125 */
+#define Tcl_Eof \
+	(tclStubsPtr->tcl_Eof) /* 126 */
+#define Tcl_ErrnoId \
+	(tclStubsPtr->tcl_ErrnoId) /* 127 */
+#define Tcl_ErrnoMsg \
+	(tclStubsPtr->tcl_ErrnoMsg) /* 128 */
+#define Tcl_Eval \
+	(tclStubsPtr->tcl_Eval) /* 129 */
+#define Tcl_EvalFile \
+	(tclStubsPtr->tcl_EvalFile) /* 130 */
+#define Tcl_EvalObj \
+	(tclStubsPtr->tcl_EvalObj) /* 131 */
+#define Tcl_EventuallyFree \
+	(tclStubsPtr->tcl_EventuallyFree) /* 132 */
+#define Tcl_Exit \
+	(tclStubsPtr->tcl_Exit) /* 133 */
+#define Tcl_ExposeCommand \
+	(tclStubsPtr->tcl_ExposeCommand) /* 134 */
+#define Tcl_ExprBoolean \
+	(tclStubsPtr->tcl_ExprBoolean) /* 135 */
+#define Tcl_ExprBooleanObj \
+	(tclStubsPtr->tcl_ExprBooleanObj) /* 136 */
+#define Tcl_ExprDouble \
+	(tclStubsPtr->tcl_ExprDouble) /* 137 */
+#define Tcl_ExprDoubleObj \
+	(tclStubsPtr->tcl_ExprDoubleObj) /* 138 */
+#define Tcl_ExprLong \
+	(tclStubsPtr->tcl_ExprLong) /* 139 */
+#define Tcl_ExprLongObj \
+	(tclStubsPtr->tcl_ExprLongObj) /* 140 */
+#define Tcl_ExprObj \
+	(tclStubsPtr->tcl_ExprObj) /* 141 */
+#define Tcl_ExprString \
+	(tclStubsPtr->tcl_ExprString) /* 142 */
+#define Tcl_Finalize \
+	(tclStubsPtr->tcl_Finalize) /* 143 */
+#define Tcl_FindExecutable \
+	(tclStubsPtr->tcl_FindExecutable) /* 144 */
+#define Tcl_FirstHashEntry \
+	(tclStubsPtr->tcl_FirstHashEntry) /* 145 */
+#define Tcl_Flush \
+	(tclStubsPtr->tcl_Flush) /* 146 */
+#define Tcl_FreeResult \
+	(tclStubsPtr->tcl_FreeResult) /* 147 */
+#define Tcl_GetAlias \
+	(tclStubsPtr->tcl_GetAlias) /* 148 */
+#define Tcl_GetAliasObj \
+	(tclStubsPtr->tcl_GetAliasObj) /* 149 */
+#define Tcl_GetAssocData \
+	(tclStubsPtr->tcl_GetAssocData) /* 150 */
+#define Tcl_GetChannel \
+	(tclStubsPtr->tcl_GetChannel) /* 151 */
+#define Tcl_GetChannelBufferSize \
+	(tclStubsPtr->tcl_GetChannelBufferSize) /* 152 */
+#define Tcl_GetChannelHandle \
+	(tclStubsPtr->tcl_GetChannelHandle) /* 153 */
+#define Tcl_GetChannelInstanceData \
+	(tclStubsPtr->tcl_GetChannelInstanceData) /* 154 */
+#define Tcl_GetChannelMode \
+	(tclStubsPtr->tcl_GetChannelMode) /* 155 */
+#define Tcl_GetChannelName \
+	(tclStubsPtr->tcl_GetChannelName) /* 156 */
+#define Tcl_GetChannelOption \
+	(tclStubsPtr->tcl_GetChannelOption) /* 157 */
+#define Tcl_GetChannelType \
+	(tclStubsPtr->tcl_GetChannelType) /* 158 */
+#define Tcl_GetCommandInfo \
+	(tclStubsPtr->tcl_GetCommandInfo) /* 159 */
+#define Tcl_GetCommandName \
+	(tclStubsPtr->tcl_GetCommandName) /* 160 */
+#define Tcl_GetErrno \
+	(tclStubsPtr->tcl_GetErrno) /* 161 */
+#define Tcl_GetHostName \
+	(tclStubsPtr->tcl_GetHostName) /* 162 */
+#define Tcl_GetInterpPath \
+	(tclStubsPtr->tcl_GetInterpPath) /* 163 */
+#define Tcl_GetMaster \
+	(tclStubsPtr->tcl_GetMaster) /* 164 */
+#define Tcl_GetNameOfExecutable \
+	(tclStubsPtr->tcl_GetNameOfExecutable) /* 165 */
+#define Tcl_GetObjResult \
+	(tclStubsPtr->tcl_GetObjResult) /* 166 */
+#if !defined(_WIN32) && !defined(MAC_OSX_TCL) /* UNIX */
+#define Tcl_GetOpenFile \
+	(tclStubsPtr->tcl_GetOpenFile) /* 167 */
+#endif /* UNIX */
+#ifdef MAC_OSX_TCL /* MACOSX */
+#define Tcl_GetOpenFile \
+	(tclStubsPtr->tcl_GetOpenFile) /* 167 */
+#endif /* MACOSX */
+#define Tcl_GetPathType \
+	(tclStubsPtr->tcl_GetPathType) /* 168 */
+#define Tcl_Gets \
+	(tclStubsPtr->tcl_Gets) /* 169 */
+#define Tcl_GetsObj \
+	(tclStubsPtr->tcl_GetsObj) /* 170 */
+#define Tcl_GetServiceMode \
+	(tclStubsPtr->tcl_GetServiceMode) /* 171 */
+#define Tcl_GetSlave \
+	(tclStubsPtr->tcl_GetSlave) /* 172 */
+#define Tcl_GetStdChannel \
+	(tclStubsPtr->tcl_GetStdChannel) /* 173 */
+#define Tcl_GetStringResult \
+	(tclStubsPtr->tcl_GetStringResult) /* 174 */
+#define Tcl_GetVar \
+	(tclStubsPtr->tcl_GetVar) /* 175 */
+#define Tcl_GetVar2 \
+	(tclStubsPtr->tcl_GetVar2) /* 176 */
+#define Tcl_GlobalEval \
+	(tclStubsPtr->tcl_GlobalEval) /* 177 */
+#define Tcl_GlobalEvalObj \
+	(tclStubsPtr->tcl_GlobalEvalObj) /* 178 */
+#define Tcl_HideCommand \
+	(tclStubsPtr->tcl_HideCommand) /* 179 */
+#define Tcl_Init \
+	(tclStubsPtr->tcl_Init) /* 180 */
+#define Tcl_InitHashTable \
+	(tclStubsPtr->tcl_InitHashTable) /* 181 */
+#define Tcl_InputBlocked \
+	(tclStubsPtr->tcl_InputBlocked) /* 182 */
+#define Tcl_InputBuffered \
+	(tclStubsPtr->tcl_InputBuffered) /* 183 */
+#define Tcl_InterpDeleted \
+	(tclStubsPtr->tcl_InterpDeleted) /* 184 */
+#define Tcl_IsSafe \
+	(tclStubsPtr->tcl_IsSafe) /* 185 */
+#define Tcl_JoinPath \
+	(tclStubsPtr->tcl_JoinPath) /* 186 */
+#define Tcl_LinkVar \
+	(tclStubsPtr->tcl_LinkVar) /* 187 */
+/* Slot 188 is reserved */
+#define Tcl_MakeFileChannel \
+	(tclStubsPtr->tcl_MakeFileChannel) /* 189 */
+#define Tcl_MakeSafe \
+	(tclStubsPtr->tcl_MakeSafe) /* 190 */
+#define Tcl_MakeTcpClientChannel \
+	(tclStubsPtr->tcl_MakeTcpClientChannel) /* 191 */
+#define Tcl_Merge \
+	(tclStubsPtr->tcl_Merge) /* 192 */
+#define Tcl_NextHashEntry \
+	(tclStubsPtr->tcl_NextHashEntry) /* 193 */
+#define Tcl_NotifyChannel \
+	(tclStubsPtr->tcl_NotifyChannel) /* 194 */
+#define Tcl_ObjGetVar2 \
+	(tclStubsPtr->tcl_ObjGetVar2) /* 195 */
+#define Tcl_ObjSetVar2 \
+	(tclStubsPtr->tcl_ObjSetVar2) /* 196 */
+#define Tcl_OpenCommandChannel \
+	(tclStubsPtr->tcl_OpenCommandChannel) /* 197 */
+#define Tcl_OpenFileChannel \
+	(tclStubsPtr->tcl_OpenFileChannel) /* 198 */
+#define Tcl_OpenTcpClient \
+	(tclStubsPtr->tcl_OpenTcpClient) /* 199 */
+#define Tcl_OpenTcpServer \
+	(tclStubsPtr->tcl_OpenTcpServer) /* 200 */
+#define Tcl_Preserve \
+	(tclStubsPtr->tcl_Preserve) /* 201 */
+#define Tcl_PrintDouble \
+	(tclStubsPtr->tcl_PrintDouble) /* 202 */
+#define Tcl_PutEnv \
+	(tclStubsPtr->tcl_PutEnv) /* 203 */
+#define Tcl_PosixError \
+	(tclStubsPtr->tcl_PosixError) /* 204 */
+#define Tcl_QueueEvent \
+	(tclStubsPtr->tcl_QueueEvent) /* 205 */
+#define Tcl_Read \
+	(tclStubsPtr->tcl_Read) /* 206 */
+#define Tcl_ReapDetachedProcs \
+	(tclStubsPtr->tcl_ReapDetachedProcs) /* 207 */
+#define Tcl_RecordAndEval \
+	(tclStubsPtr->tcl_RecordAndEval) /* 208 */
+#define Tcl_RecordAndEvalObj \
+	(tclStubsPtr->tcl_RecordAndEvalObj) /* 209 */
+#define Tcl_RegisterChannel \
+	(tclStubsPtr->tcl_RegisterChannel) /* 210 */
+#define Tcl_RegisterObjType \
+	(tclStubsPtr->tcl_RegisterObjType) /* 211 */
+#define Tcl_RegExpCompile \
+	(tclStubsPtr->tcl_RegExpCompile) /* 212 */
+#define Tcl_RegExpExec \
+	(tclStubsPtr->tcl_RegExpExec) /* 213 */
+#define Tcl_RegExpMatch \
+	(tclStubsPtr->tcl_RegExpMatch) /* 214 */
+#define Tcl_RegExpRange \
+	(tclStubsPtr->tcl_RegExpRange) /* 215 */
+#define Tcl_Release \
+	(tclStubsPtr->tcl_Release) /* 216 */
+#define Tcl_ResetResult \
+	(tclStubsPtr->tcl_ResetResult) /* 217 */
+#define Tcl_ScanElement \
+	(tclStubsPtr->tcl_ScanElement) /* 218 */
+#define Tcl_ScanCountedElement \
+	(tclStubsPtr->tcl_ScanCountedElement) /* 219 */
+#define Tcl_SeekOld \
+	(tclStubsPtr->tcl_SeekOld) /* 220 */
+#define Tcl_ServiceAll \
+	(tclStubsPtr->tcl_ServiceAll) /* 221 */
+#define Tcl_ServiceEvent \
+	(tclStubsPtr->tcl_ServiceEvent) /* 222 */
+#define Tcl_SetAssocData \
+	(tclStubsPtr->tcl_SetAssocData) /* 223 */
+#define Tcl_SetChannelBufferSize \
+	(tclStubsPtr->tcl_SetChannelBufferSize) /* 224 */
+#define Tcl_SetChannelOption \
+	(tclStubsPtr->tcl_SetChannelOption) /* 225 */
+#define Tcl_SetCommandInfo \
+	(tclStubsPtr->tcl_SetCommandInfo) /* 226 */
+#define Tcl_SetErrno \
+	(tclStubsPtr->tcl_SetErrno) /* 227 */
+#define Tcl_SetErrorCode \
+	(tclStubsPtr->tcl_SetErrorCode) /* 228 */
+#define Tcl_SetMaxBlockTime \
+	(tclStubsPtr->tcl_SetMaxBlockTime) /* 229 */
+#define Tcl_SetPanicProc \
+	(tclStubsPtr->tcl_SetPanicProc) /* 230 */
+#define Tcl_SetRecursionLimit \
+	(tclStubsPtr->tcl_SetRecursionLimit) /* 231 */
+#define Tcl_SetResult \
+	(tclStubsPtr->tcl_SetResult) /* 232 */
+#define Tcl_SetServiceMode \
+	(tclStubsPtr->tcl_SetServiceMode) /* 233 */
+#define Tcl_SetObjErrorCode \
+	(tclStubsPtr->tcl_SetObjErrorCode) /* 234 */
+#define Tcl_SetObjResult \
+	(tclStubsPtr->tcl_SetObjResult) /* 235 */
+#define Tcl_SetStdChannel \
+	(tclStubsPtr->tcl_SetStdChannel) /* 236 */
+#define Tcl_SetVar \
+	(tclStubsPtr->tcl_SetVar) /* 237 */
+#define Tcl_SetVar2 \
+	(tclStubsPtr->tcl_SetVar2) /* 238 */
+#define Tcl_SignalId \
+	(tclStubsPtr->tcl_SignalId) /* 239 */
+#define Tcl_SignalMsg \
+	(tclStubsPtr->tcl_SignalMsg) /* 240 */
+#define Tcl_SourceRCFile \
+	(tclStubsPtr->tcl_SourceRCFile) /* 241 */
+#define Tcl_SplitList \
+	(tclStubsPtr->tcl_SplitList) /* 242 */
+#define Tcl_SplitPath \
+	(tclStubsPtr->tcl_SplitPath) /* 243 */
+#define Tcl_StaticPackage \
+	(tclStubsPtr->tcl_StaticPackage) /* 244 */
+#define Tcl_StringMatch \
+	(tclStubsPtr->tcl_StringMatch) /* 245 */
+#define Tcl_TellOld \
+	(tclStubsPtr->tcl_TellOld) /* 246 */
+#define Tcl_TraceVar \
+	(tclStubsPtr->tcl_TraceVar) /* 247 */
+#define Tcl_TraceVar2 \
+	(tclStubsPtr->tcl_TraceVar2) /* 248 */
+#define Tcl_TranslateFileName \
+	(tclStubsPtr->tcl_TranslateFileName) /* 249 */
+#define Tcl_Ungets \
+	(tclStubsPtr->tcl_Ungets) /* 250 */
+#define Tcl_UnlinkVar \
+	(tclStubsPtr->tcl_UnlinkVar) /* 251 */
+#define Tcl_UnregisterChannel \
+	(tclStubsPtr->tcl_UnregisterChannel) /* 252 */
+#define Tcl_UnsetVar \
+	(tclStubsPtr->tcl_UnsetVar) /* 253 */
+#define Tcl_UnsetVar2 \
+	(tclStubsPtr->tcl_UnsetVar2) /* 254 */
+#define Tcl_UntraceVar \
+	(tclStubsPtr->tcl_UntraceVar) /* 255 */
+#define Tcl_UntraceVar2 \
+	(tclStubsPtr->tcl_UntraceVar2) /* 256 */
+#define Tcl_UpdateLinkedVar \
+	(tclStubsPtr->tcl_UpdateLinkedVar) /* 257 */
+#define Tcl_UpVar \
+	(tclStubsPtr->tcl_UpVar) /* 258 */
+#define Tcl_UpVar2 \
+	(tclStubsPtr->tcl_UpVar2) /* 259 */
+#define Tcl_VarEval \
+	(tclStubsPtr->tcl_VarEval) /* 260 */
+#define Tcl_VarTraceInfo \
+	(tclStubsPtr->tcl_VarTraceInfo) /* 261 */
+#define Tcl_VarTraceInfo2 \
+	(tclStubsPtr->tcl_VarTraceInfo2) /* 262 */
+#define Tcl_Write \
+	(tclStubsPtr->tcl_Write) /* 263 */
+#define Tcl_WrongNumArgs \
+	(tclStubsPtr->tcl_WrongNumArgs) /* 264 */
+#define Tcl_DumpActiveMemory \
+	(tclStubsPtr->tcl_DumpActiveMemory) /* 265 */
+#define Tcl_ValidateAllMemory \
+	(tclStubsPtr->tcl_ValidateAllMemory) /* 266 */
+#define Tcl_AppendResultVA \
+	(tclStubsPtr->tcl_AppendResultVA) /* 267 */
+#define Tcl_AppendStringsToObjVA \
+	(tclStubsPtr->tcl_AppendStringsToObjVA) /* 268 */
+#define Tcl_HashStats \
+	(tclStubsPtr->tcl_HashStats) /* 269 */
+#define Tcl_ParseVar \
+	(tclStubsPtr->tcl_ParseVar) /* 270 */
+#define Tcl_PkgPresent \
+	(tclStubsPtr->tcl_PkgPresent) /* 271 */
+#define Tcl_PkgPresentEx \
+	(tclStubsPtr->tcl_PkgPresentEx) /* 272 */
+#define Tcl_PkgProvide \
+	(tclStubsPtr->tcl_PkgProvide) /* 273 */
+#define Tcl_PkgRequire \
+	(tclStubsPtr->tcl_PkgRequire) /* 274 */
+#define Tcl_SetErrorCodeVA \
+	(tclStubsPtr->tcl_SetErrorCodeVA) /* 275 */
+#define Tcl_VarEvalVA \
+	(tclStubsPtr->tcl_VarEvalVA) /* 276 */
+#define Tcl_WaitPid \
+	(tclStubsPtr->tcl_WaitPid) /* 277 */
+#define Tcl_PanicVA \
+	(tclStubsPtr->tcl_PanicVA) /* 278 */
+#define Tcl_GetVersion \
+	(tclStubsPtr->tcl_GetVersion) /* 279 */
+#define Tcl_InitMemory \
+	(tclStubsPtr->tcl_InitMemory) /* 280 */
+#define Tcl_StackChannel \
+	(tclStubsPtr->tcl_StackChannel) /* 281 */
+#define Tcl_UnstackChannel \
+	(tclStubsPtr->tcl_UnstackChannel) /* 282 */
+#define Tcl_GetStackedChannel \
+	(tclStubsPtr->tcl_GetStackedChannel) /* 283 */
+#define Tcl_SetMainLoop \
+	(tclStubsPtr->tcl_SetMainLoop) /* 284 */
+/* Slot 285 is reserved */
+#define Tcl_AppendObjToObj \
+	(tclStubsPtr->tcl_AppendObjToObj) /* 286 */
+#define Tcl_CreateEncoding \
+	(tclStubsPtr->tcl_CreateEncoding) /* 287 */
+#define Tcl_CreateThreadExitHandler \
+	(tclStubsPtr->tcl_CreateThreadExitHandler) /* 288 */
+#define Tcl_DeleteThreadExitHandler \
+	(tclStubsPtr->tcl_DeleteThreadExitHandler) /* 289 */
+#define Tcl_DiscardResult \
+	(tclStubsPtr->tcl_DiscardResult) /* 290 */
+#define Tcl_EvalEx \
+	(tclStubsPtr->tcl_EvalEx) /* 291 */
+#define Tcl_EvalObjv \
+	(tclStubsPtr->tcl_EvalObjv) /* 292 */
+#define Tcl_EvalObjEx \
+	(tclStubsPtr->tcl_EvalObjEx) /* 293 */
+#define Tcl_ExitThread \
+	(tclStubsPtr->tcl_ExitThread) /* 294 */
+#define Tcl_ExternalToUtf \
+	(tclStubsPtr->tcl_ExternalToUtf) /* 295 */
+#define Tcl_ExternalToUtfDString \
+	(tclStubsPtr->tcl_ExternalToUtfDString) /* 296 */
+#define Tcl_FinalizeThread \
+	(tclStubsPtr->tcl_FinalizeThread) /* 297 */
+#define Tcl_FinalizeNotifier \
+	(tclStubsPtr->tcl_FinalizeNotifier) /* 298 */
+#define Tcl_FreeEncoding \
+	(tclStubsPtr->tcl_FreeEncoding) /* 299 */
+#define Tcl_GetCurrentThread \
+	(tclStubsPtr->tcl_GetCurrentThread) /* 300 */
+#define Tcl_GetEncoding \
+	(tclStubsPtr->tcl_GetEncoding) /* 301 */
+#define Tcl_GetEncodingName \
+	(tclStubsPtr->tcl_GetEncodingName) /* 302 */
+#define Tcl_GetEncodingNames \
+	(tclStubsPtr->tcl_GetEncodingNames) /* 303 */
+#define Tcl_GetIndexFromObjStruct \
+	(tclStubsPtr->tcl_GetIndexFromObjStruct) /* 304 */
+#define Tcl_GetThreadData \
+	(tclStubsPtr->tcl_GetThreadData) /* 305 */
+#define Tcl_GetVar2Ex \
+	(tclStubsPtr->tcl_GetVar2Ex) /* 306 */
+#define Tcl_InitNotifier \
+	(tclStubsPtr->tcl_InitNotifier) /* 307 */
+#define Tcl_MutexLock \
+	(tclStubsPtr->tcl_MutexLock) /* 308 */
+#define Tcl_MutexUnlock \
+	(tclStubsPtr->tcl_MutexUnlock) /* 309 */
+#define Tcl_ConditionNotify \
+	(tclStubsPtr->tcl_ConditionNotify) /* 310 */
+#define Tcl_ConditionWait \
+	(tclStubsPtr->tcl_ConditionWait) /* 311 */
+#define Tcl_NumUtfChars \
+	(tclStubsPtr->tcl_NumUtfChars) /* 312 */
+#define Tcl_ReadChars \
+	(tclStubsPtr->tcl_ReadChars) /* 313 */
+#define Tcl_RestoreResult \
+	(tclStubsPtr->tcl_RestoreResult) /* 314 */
+#define Tcl_SaveResult \
+	(tclStubsPtr->tcl_SaveResult) /* 315 */
+#define Tcl_SetSystemEncoding \
+	(tclStubsPtr->tcl_SetSystemEncoding) /* 316 */
+#define Tcl_SetVar2Ex \
+	(tclStubsPtr->tcl_SetVar2Ex) /* 317 */
+#define Tcl_ThreadAlert \
+	(tclStubsPtr->tcl_ThreadAlert) /* 318 */
+#define Tcl_ThreadQueueEvent \
+	(tclStubsPtr->tcl_ThreadQueueEvent) /* 319 */
+#define Tcl_UniCharAtIndex \
+	(tclStubsPtr->tcl_UniCharAtIndex) /* 320 */
+#define Tcl_UniCharToLower \
+	(tclStubsPtr->tcl_UniCharToLower) /* 321 */
+#define Tcl_UniCharToTitle \
+	(tclStubsPtr->tcl_UniCharToTitle) /* 322 */
+#define Tcl_UniCharToUpper \
+	(tclStubsPtr->tcl_UniCharToUpper) /* 323 */
+#define Tcl_UniCharToUtf \
+	(tclStubsPtr->tcl_UniCharToUtf) /* 324 */
+#define Tcl_UtfAtIndex \
+	(tclStubsPtr->tcl_UtfAtIndex) /* 325 */
+#define Tcl_UtfCharComplete \
+	(tclStubsPtr->tcl_UtfCharComplete) /* 326 */
+#define Tcl_UtfBackslash \
+	(tclStubsPtr->tcl_UtfBackslash) /* 327 */
+#define Tcl_UtfFindFirst \
+	(tclStubsPtr->tcl_UtfFindFirst) /* 328 */
+#define Tcl_UtfFindLast \
+	(tclStubsPtr->tcl_UtfFindLast) /* 329 */
+#define Tcl_UtfNext \
+	(tclStubsPtr->tcl_UtfNext) /* 330 */
+#define Tcl_UtfPrev \
+	(tclStubsPtr->tcl_UtfPrev) /* 331 */
+#define Tcl_UtfToExternal \
+	(tclStubsPtr->tcl_UtfToExternal) /* 332 */
+#define Tcl_UtfToExternalDString \
+	(tclStubsPtr->tcl_UtfToExternalDString) /* 333 */
+#define Tcl_UtfToLower \
+	(tclStubsPtr->tcl_UtfToLower) /* 334 */
+#define Tcl_UtfToTitle \
+	(tclStubsPtr->tcl_UtfToTitle) /* 335 */
+#define Tcl_UtfToUniChar \
+	(tclStubsPtr->tcl_UtfToUniChar) /* 336 */
+#define Tcl_UtfToUpper \
+	(tclStubsPtr->tcl_UtfToUpper) /* 337 */
+#define Tcl_WriteChars \
+	(tclStubsPtr->tcl_WriteChars) /* 338 */
+#define Tcl_WriteObj \
+	(tclStubsPtr->tcl_WriteObj) /* 339 */
+#define Tcl_GetString \
+	(tclStubsPtr->tcl_GetString) /* 340 */
+#define Tcl_GetDefaultEncodingDir \
+	(tclStubsPtr->tcl_GetDefaultEncodingDir) /* 341 */
+#define Tcl_SetDefaultEncodingDir \
+	(tclStubsPtr->tcl_SetDefaultEncodingDir) /* 342 */
+#define Tcl_AlertNotifier \
+	(tclStubsPtr->tcl_AlertNotifier) /* 343 */
+#define Tcl_ServiceModeHook \
+	(tclStubsPtr->tcl_ServiceModeHook) /* 344 */
+#define Tcl_UniCharIsAlnum \
+	(tclStubsPtr->tcl_UniCharIsAlnum) /* 345 */
+#define Tcl_UniCharIsAlpha \
+	(tclStubsPtr->tcl_UniCharIsAlpha) /* 346 */
+#define Tcl_UniCharIsDigit \
+	(tclStubsPtr->tcl_UniCharIsDigit) /* 347 */
+#define Tcl_UniCharIsLower \
+	(tclStubsPtr->tcl_UniCharIsLower) /* 348 */
+#define Tcl_UniCharIsSpace \
+	(tclStubsPtr->tcl_UniCharIsSpace) /* 349 */
+#define Tcl_UniCharIsUpper \
+	(tclStubsPtr->tcl_UniCharIsUpper) /* 350 */
+#define Tcl_UniCharIsWordChar \
+	(tclStubsPtr->tcl_UniCharIsWordChar) /* 351 */
+#define Tcl_UniCharLen \
+	(tclStubsPtr->tcl_UniCharLen) /* 352 */
+#define Tcl_UniCharNcmp \
+	(tclStubsPtr->tcl_UniCharNcmp) /* 353 */
+#define Tcl_UniCharToUtfDString \
+	(tclStubsPtr->tcl_UniCharToUtfDString) /* 354 */
+#define Tcl_UtfToUniCharDString \
+	(tclStubsPtr->tcl_UtfToUniCharDString) /* 355 */
+#define Tcl_GetRegExpFromObj \
+	(tclStubsPtr->tcl_GetRegExpFromObj) /* 356 */
+#define Tcl_EvalTokens \
+	(tclStubsPtr->tcl_EvalTokens) /* 357 */
+#define Tcl_FreeParse \
+	(tclStubsPtr->tcl_FreeParse) /* 358 */
+#define Tcl_LogCommandInfo \
+	(tclStubsPtr->tcl_LogCommandInfo) /* 359 */
+#define Tcl_ParseBraces \
+	(tclStubsPtr->tcl_ParseBraces) /* 360 */
+#define Tcl_ParseCommand \
+	(tclStubsPtr->tcl_ParseCommand) /* 361 */
+#define Tcl_ParseExpr \
+	(tclStubsPtr->tcl_ParseExpr) /* 362 */
+#define Tcl_ParseQuotedString \
+	(tclStubsPtr->tcl_ParseQuotedString) /* 363 */
+#define Tcl_ParseVarName \
+	(tclStubsPtr->tcl_ParseVarName) /* 364 */
+#define Tcl_GetCwd \
+	(tclStubsPtr->tcl_GetCwd) /* 365 */
+#define Tcl_Chdir \
+	(tclStubsPtr->tcl_Chdir) /* 366 */
+#define Tcl_Access \
+	(tclStubsPtr->tcl_Access) /* 367 */
+#define Tcl_Stat \
+	(tclStubsPtr->tcl_Stat) /* 368 */
+#define Tcl_UtfNcmp \
+	(tclStubsPtr->tcl_UtfNcmp) /* 369 */
+#define Tcl_UtfNcasecmp \
+	(tclStubsPtr->tcl_UtfNcasecmp) /* 370 */
+#define Tcl_StringCaseMatch \
+	(tclStubsPtr->tcl_StringCaseMatch) /* 371 */
+#define Tcl_UniCharIsControl \
+	(tclStubsPtr->tcl_UniCharIsControl) /* 372 */
+#define Tcl_UniCharIsGraph \
+	(tclStubsPtr->tcl_UniCharIsGraph) /* 373 */
+#define Tcl_UniCharIsPrint \
+	(tclStubsPtr->tcl_UniCharIsPrint) /* 374 */
+#define Tcl_UniCharIsPunct \
+	(tclStubsPtr->tcl_UniCharIsPunct) /* 375 */
+#define Tcl_RegExpExecObj \
+	(tclStubsPtr->tcl_RegExpExecObj) /* 376 */
+#define Tcl_RegExpGetInfo \
+	(tclStubsPtr->tcl_RegExpGetInfo) /* 377 */
+#define Tcl_NewUnicodeObj \
+	(tclStubsPtr->tcl_NewUnicodeObj) /* 378 */
+#define Tcl_SetUnicodeObj \
+	(tclStubsPtr->tcl_SetUnicodeObj) /* 379 */
+#define Tcl_GetCharLength \
+	(tclStubsPtr->tcl_GetCharLength) /* 380 */
+#define Tcl_GetUniChar \
+	(tclStubsPtr->tcl_GetUniChar) /* 381 */
+#define Tcl_GetUnicode \
+	(tclStubsPtr->tcl_GetUnicode) /* 382 */
+#define Tcl_GetRange \
+	(tclStubsPtr->tcl_GetRange) /* 383 */
+#define Tcl_AppendUnicodeToObj \
+	(tclStubsPtr->tcl_AppendUnicodeToObj) /* 384 */
+#define Tcl_RegExpMatchObj \
+	(tclStubsPtr->tcl_RegExpMatchObj) /* 385 */
+#define Tcl_SetNotifier \
+	(tclStubsPtr->tcl_SetNotifier) /* 386 */
+#define Tcl_GetAllocMutex \
+	(tclStubsPtr->tcl_GetAllocMutex) /* 387 */
+#define Tcl_GetChannelNames \
+	(tclStubsPtr->tcl_GetChannelNames) /* 388 */
+#define Tcl_GetChannelNamesEx \
+	(tclStubsPtr->tcl_GetChannelNamesEx) /* 389 */
+#define Tcl_ProcObjCmd \
+	(tclStubsPtr->tcl_ProcObjCmd) /* 390 */
+#define Tcl_ConditionFinalize \
+	(tclStubsPtr->tcl_ConditionFinalize) /* 391 */
+#define Tcl_MutexFinalize \
+	(tclStubsPtr->tcl_MutexFinalize) /* 392 */
+#define Tcl_CreateThread \
+	(tclStubsPtr->tcl_CreateThread) /* 393 */
+#define Tcl_ReadRaw \
+	(tclStubsPtr->tcl_ReadRaw) /* 394 */
+#define Tcl_WriteRaw \
+	(tclStubsPtr->tcl_WriteRaw) /* 395 */
+#define Tcl_GetTopChannel \
+	(tclStubsPtr->tcl_GetTopChannel) /* 396 */
+#define Tcl_ChannelBuffered \
+	(tclStubsPtr->tcl_ChannelBuffered) /* 397 */
+#define Tcl_ChannelName \
+	(tclStubsPtr->tcl_ChannelName) /* 398 */
+#define Tcl_ChannelVersion \
+	(tclStubsPtr->tcl_ChannelVersion) /* 399 */
+#define Tcl_ChannelBlockModeProc \
+	(tclStubsPtr->tcl_ChannelBlockModeProc) /* 400 */
+#define Tcl_ChannelCloseProc \
+	(tclStubsPtr->tcl_ChannelCloseProc) /* 401 */
+#define Tcl_ChannelClose2Proc \
+	(tclStubsPtr->tcl_ChannelClose2Proc) /* 402 */
+#define Tcl_ChannelInputProc \
+	(tclStubsPtr->tcl_ChannelInputProc) /* 403 */
+#define Tcl_ChannelOutputProc \
+	(tclStubsPtr->tcl_ChannelOutputProc) /* 404 */
+#define Tcl_ChannelSeekProc \
+	(tclStubsPtr->tcl_ChannelSeekProc) /* 405 */
+#define Tcl_ChannelSetOptionProc \
+	(tclStubsPtr->tcl_ChannelSetOptionProc) /* 406 */
+#define Tcl_ChannelGetOptionProc \
+	(tclStubsPtr->tcl_ChannelGetOptionProc) /* 407 */
+#define Tcl_ChannelWatchProc \
+	(tclStubsPtr->tcl_ChannelWatchProc) /* 408 */
+#define Tcl_ChannelGetHandleProc \
+	(tclStubsPtr->tcl_ChannelGetHandleProc) /* 409 */
+#define Tcl_ChannelFlushProc \
+	(tclStubsPtr->tcl_ChannelFlushProc) /* 410 */
+#define Tcl_ChannelHandlerProc \
+	(tclStubsPtr->tcl_ChannelHandlerProc) /* 411 */
+#define Tcl_JoinThread \
+	(tclStubsPtr->tcl_JoinThread) /* 412 */
+#define Tcl_IsChannelShared \
+	(tclStubsPtr->tcl_IsChannelShared) /* 413 */
+#define Tcl_IsChannelRegistered \
+	(tclStubsPtr->tcl_IsChannelRegistered) /* 414 */
+#define Tcl_CutChannel \
+	(tclStubsPtr->tcl_CutChannel) /* 415 */
+#define Tcl_SpliceChannel \
+	(tclStubsPtr->tcl_SpliceChannel) /* 416 */
+#define Tcl_ClearChannelHandlers \
+	(tclStubsPtr->tcl_ClearChannelHandlers) /* 417 */
+#define Tcl_IsChannelExisting \
+	(tclStubsPtr->tcl_IsChannelExisting) /* 418 */
+#define Tcl_UniCharNcasecmp \
+	(tclStubsPtr->tcl_UniCharNcasecmp) /* 419 */
+#define Tcl_UniCharCaseMatch \
+	(tclStubsPtr->tcl_UniCharCaseMatch) /* 420 */
+#define Tcl_FindHashEntry \
+	(tclStubsPtr->tcl_FindHashEntry) /* 421 */
+#define Tcl_CreateHashEntry \
+	(tclStubsPtr->tcl_CreateHashEntry) /* 422 */
+#define Tcl_InitCustomHashTable \
+	(tclStubsPtr->tcl_InitCustomHashTable) /* 423 */
+#define Tcl_InitObjHashTable \
+	(tclStubsPtr->tcl_InitObjHashTable) /* 424 */
+#define Tcl_CommandTraceInfo \
+	(tclStubsPtr->tcl_CommandTraceInfo) /* 425 */
+#define Tcl_TraceCommand \
+	(tclStubsPtr->tcl_TraceCommand) /* 426 */
+#define Tcl_UntraceCommand \
+	(tclStubsPtr->tcl_UntraceCommand) /* 427 */
+#define Tcl_AttemptAlloc \
+	(tclStubsPtr->tcl_AttemptAlloc) /* 428 */
+#define Tcl_AttemptDbCkalloc \
+	(tclStubsPtr->tcl_AttemptDbCkalloc) /* 429 */
+#define Tcl_AttemptRealloc \
+	(tclStubsPtr->tcl_AttemptRealloc) /* 430 */
+#define Tcl_AttemptDbCkrealloc \
+	(tclStubsPtr->tcl_AttemptDbCkrealloc) /* 431 */
+#define Tcl_AttemptSetObjLength \
+	(tclStubsPtr->tcl_AttemptSetObjLength) /* 432 */
+#define Tcl_GetChannelThread \
+	(tclStubsPtr->tcl_GetChannelThread) /* 433 */
+#define Tcl_GetUnicodeFromObj \
+	(tclStubsPtr->tcl_GetUnicodeFromObj) /* 434 */
+#define Tcl_GetMathFuncInfo \
+	(tclStubsPtr->tcl_GetMathFuncInfo) /* 435 */
+#define Tcl_ListMathFuncs \
+	(tclStubsPtr->tcl_ListMathFuncs) /* 436 */
+#define Tcl_SubstObj \
+	(tclStubsPtr->tcl_SubstObj) /* 437 */
+#define Tcl_DetachChannel \
+	(tclStubsPtr->tcl_DetachChannel) /* 438 */
+#define Tcl_IsStandardChannel \
+	(tclStubsPtr->tcl_IsStandardChannel) /* 439 */
+#define Tcl_FSCopyFile \
+	(tclStubsPtr->tcl_FSCopyFile) /* 440 */
+#define Tcl_FSCopyDirectory \
+	(tclStubsPtr->tcl_FSCopyDirectory) /* 441 */
+#define Tcl_FSCreateDirectory \
+	(tclStubsPtr->tcl_FSCreateDirectory) /* 442 */
+#define Tcl_FSDeleteFile \
+	(tclStubsPtr->tcl_FSDeleteFile) /* 443 */
+#define Tcl_FSLoadFile \
+	(tclStubsPtr->tcl_FSLoadFile) /* 444 */
+#define Tcl_FSMatchInDirectory \
+	(tclStubsPtr->tcl_FSMatchInDirectory) /* 445 */
+#define Tcl_FSLink \
+	(tclStubsPtr->tcl_FSLink) /* 446 */
+#define Tcl_FSRemoveDirectory \
+	(tclStubsPtr->tcl_FSRemoveDirectory) /* 447 */
+#define Tcl_FSRenameFile \
+	(tclStubsPtr->tcl_FSRenameFile) /* 448 */
+#define Tcl_FSLstat \
+	(tclStubsPtr->tcl_FSLstat) /* 449 */
+#define Tcl_FSUtime \
+	(tclStubsPtr->tcl_FSUtime) /* 450 */
+#define Tcl_FSFileAttrsGet \
+	(tclStubsPtr->tcl_FSFileAttrsGet) /* 451 */
+#define Tcl_FSFileAttrsSet \
+	(tclStubsPtr->tcl_FSFileAttrsSet) /* 452 */
+#define Tcl_FSFileAttrStrings \
+	(tclStubsPtr->tcl_FSFileAttrStrings) /* 453 */
+#define Tcl_FSStat \
+	(tclStubsPtr->tcl_FSStat) /* 454 */
+#define Tcl_FSAccess \
+	(tclStubsPtr->tcl_FSAccess) /* 455 */
+#define Tcl_FSOpenFileChannel \
+	(tclStubsPtr->tcl_FSOpenFileChannel) /* 456 */
+#define Tcl_FSGetCwd \
+	(tclStubsPtr->tcl_FSGetCwd) /* 457 */
+#define Tcl_FSChdir \
+	(tclStubsPtr->tcl_FSChdir) /* 458 */
+#define Tcl_FSConvertToPathType \
+	(tclStubsPtr->tcl_FSConvertToPathType) /* 459 */
+#define Tcl_FSJoinPath \
+	(tclStubsPtr->tcl_FSJoinPath) /* 460 */
+#define Tcl_FSSplitPath \
+	(tclStubsPtr->tcl_FSSplitPath) /* 461 */
+#define Tcl_FSEqualPaths \
+	(tclStubsPtr->tcl_FSEqualPaths) /* 462 */
+#define Tcl_FSGetNormalizedPath \
+	(tclStubsPtr->tcl_FSGetNormalizedPath) /* 463 */
+#define Tcl_FSJoinToPath \
+	(tclStubsPtr->tcl_FSJoinToPath) /* 464 */
+#define Tcl_FSGetInternalRep \
+	(tclStubsPtr->tcl_FSGetInternalRep) /* 465 */
+#define Tcl_FSGetTranslatedPath \
+	(tclStubsPtr->tcl_FSGetTranslatedPath) /* 466 */
+#define Tcl_FSEvalFile \
+	(tclStubsPtr->tcl_FSEvalFile) /* 467 */
+#define Tcl_FSNewNativePath \
+	(tclStubsPtr->tcl_FSNewNativePath) /* 468 */
+#define Tcl_FSGetNativePath \
+	(tclStubsPtr->tcl_FSGetNativePath) /* 469 */
+#define Tcl_FSFileSystemInfo \
+	(tclStubsPtr->tcl_FSFileSystemInfo) /* 470 */
+#define Tcl_FSPathSeparator \
+	(tclStubsPtr->tcl_FSPathSeparator) /* 471 */
+#define Tcl_FSListVolumes \
+	(tclStubsPtr->tcl_FSListVolumes) /* 472 */
+#define Tcl_FSRegister \
+	(tclStubsPtr->tcl_FSRegister) /* 473 */
+#define Tcl_FSUnregister \
+	(tclStubsPtr->tcl_FSUnregister) /* 474 */
+#define Tcl_FSData \
+	(tclStubsPtr->tcl_FSData) /* 475 */
+#define Tcl_FSGetTranslatedStringPath \
+	(tclStubsPtr->tcl_FSGetTranslatedStringPath) /* 476 */
+#define Tcl_FSGetFileSystemForPath \
+	(tclStubsPtr->tcl_FSGetFileSystemForPath) /* 477 */
+#define Tcl_FSGetPathType \
+	(tclStubsPtr->tcl_FSGetPathType) /* 478 */
+#define Tcl_OutputBuffered \
+	(tclStubsPtr->tcl_OutputBuffered) /* 479 */
+#define Tcl_FSMountsChanged \
+	(tclStubsPtr->tcl_FSMountsChanged) /* 480 */
+#define Tcl_EvalTokensStandard \
+	(tclStubsPtr->tcl_EvalTokensStandard) /* 481 */
+#define Tcl_GetTime \
+	(tclStubsPtr->tcl_GetTime) /* 482 */
+#define Tcl_CreateObjTrace \
+	(tclStubsPtr->tcl_CreateObjTrace) /* 483 */
+#define Tcl_GetCommandInfoFromToken \
+	(tclStubsPtr->tcl_GetCommandInfoFromToken) /* 484 */
+#define Tcl_SetCommandInfoFromToken \
+	(tclStubsPtr->tcl_SetCommandInfoFromToken) /* 485 */
+#define Tcl_DbNewWideIntObj \
+	(tclStubsPtr->tcl_DbNewWideIntObj) /* 486 */
+#define Tcl_GetWideIntFromObj \
+	(tclStubsPtr->tcl_GetWideIntFromObj) /* 487 */
+#define Tcl_NewWideIntObj \
+	(tclStubsPtr->tcl_NewWideIntObj) /* 488 */
+#define Tcl_SetWideIntObj \
+	(tclStubsPtr->tcl_SetWideIntObj) /* 489 */
+#define Tcl_AllocStatBuf \
+	(tclStubsPtr->tcl_AllocStatBuf) /* 490 */
+#define Tcl_Seek \
+	(tclStubsPtr->tcl_Seek) /* 491 */
+#define Tcl_Tell \
+	(tclStubsPtr->tcl_Tell) /* 492 */
+#define Tcl_ChannelWideSeekProc \
+	(tclStubsPtr->tcl_ChannelWideSeekProc) /* 493 */
+#define Tcl_DictObjPut \
+	(tclStubsPtr->tcl_DictObjPut) /* 494 */
+#define Tcl_DictObjGet \
+	(tclStubsPtr->tcl_DictObjGet) /* 495 */
+#define Tcl_DictObjRemove \
+	(tclStubsPtr->tcl_DictObjRemove) /* 496 */
+#define Tcl_DictObjSize \
+	(tclStubsPtr->tcl_DictObjSize) /* 497 */
+#define Tcl_DictObjFirst \
+	(tclStubsPtr->tcl_DictObjFirst) /* 498 */
+#define Tcl_DictObjNext \
+	(tclStubsPtr->tcl_DictObjNext) /* 499 */
+#define Tcl_DictObjDone \
+	(tclStubsPtr->tcl_DictObjDone) /* 500 */
+#define Tcl_DictObjPutKeyList \
+	(tclStubsPtr->tcl_DictObjPutKeyList) /* 501 */
+#define Tcl_DictObjRemoveKeyList \
+	(tclStubsPtr->tcl_DictObjRemoveKeyList) /* 502 */
+#define Tcl_NewDictObj \
+	(tclStubsPtr->tcl_NewDictObj) /* 503 */
+#define Tcl_DbNewDictObj \
+	(tclStubsPtr->tcl_DbNewDictObj) /* 504 */
+#define Tcl_RegisterConfig \
+	(tclStubsPtr->tcl_RegisterConfig) /* 505 */
+#define Tcl_CreateNamespace \
+	(tclStubsPtr->tcl_CreateNamespace) /* 506 */
+#define Tcl_DeleteNamespace \
+	(tclStubsPtr->tcl_DeleteNamespace) /* 507 */
+#define Tcl_AppendExportList \
+	(tclStubsPtr->tcl_AppendExportList) /* 508 */
+#define Tcl_Export \
+	(tclStubsPtr->tcl_Export) /* 509 */
+#define Tcl_Import \
+	(tclStubsPtr->tcl_Import) /* 510 */
+#define Tcl_ForgetImport \
+	(tclStubsPtr->tcl_ForgetImport) /* 511 */
+#define Tcl_GetCurrentNamespace \
+	(tclStubsPtr->tcl_GetCurrentNamespace) /* 512 */
+#define Tcl_GetGlobalNamespace \
+	(tclStubsPtr->tcl_GetGlobalNamespace) /* 513 */
+#define Tcl_FindNamespace \
+	(tclStubsPtr->tcl_FindNamespace) /* 514 */
+#define Tcl_FindCommand \
+	(tclStubsPtr->tcl_FindCommand) /* 515 */
+#define Tcl_GetCommandFromObj \
+	(tclStubsPtr->tcl_GetCommandFromObj) /* 516 */
+#define Tcl_GetCommandFullName \
+	(tclStubsPtr->tcl_GetCommandFullName) /* 517 */
+#define Tcl_FSEvalFileEx \
+	(tclStubsPtr->tcl_FSEvalFileEx) /* 518 */
+#define Tcl_SetExitProc \
+	(tclStubsPtr->tcl_SetExitProc) /* 519 */
+#define Tcl_LimitAddHandler \
+	(tclStubsPtr->tcl_LimitAddHandler) /* 520 */
+#define Tcl_LimitRemoveHandler \
+	(tclStubsPtr->tcl_LimitRemoveHandler) /* 521 */
+#define Tcl_LimitReady \
+	(tclStubsPtr->tcl_LimitReady) /* 522 */
+#define Tcl_LimitCheck \
+	(tclStubsPtr->tcl_LimitCheck) /* 523 */
+#define Tcl_LimitExceeded \
+	(tclStubsPtr->tcl_LimitExceeded) /* 524 */
+#define Tcl_LimitSetCommands \
+	(tclStubsPtr->tcl_LimitSetCommands) /* 525 */
+#define Tcl_LimitSetTime \
+	(tclStubsPtr->tcl_LimitSetTime) /* 526 */
+#define Tcl_LimitSetGranularity \
+	(tclStubsPtr->tcl_LimitSetGranularity) /* 527 */
+#define Tcl_LimitTypeEnabled \
+	(tclStubsPtr->tcl_LimitTypeEnabled) /* 528 */
+#define Tcl_LimitTypeExceeded \
+	(tclStubsPtr->tcl_LimitTypeExceeded) /* 529 */
+#define Tcl_LimitTypeSet \
+	(tclStubsPtr->tcl_LimitTypeSet) /* 530 */
+#define Tcl_LimitTypeReset \
+	(tclStubsPtr->tcl_LimitTypeReset) /* 531 */
+#define Tcl_LimitGetCommands \
+	(tclStubsPtr->tcl_LimitGetCommands) /* 532 */
+#define Tcl_LimitGetTime \
+	(tclStubsPtr->tcl_LimitGetTime) /* 533 */
+#define Tcl_LimitGetGranularity \
+	(tclStubsPtr->tcl_LimitGetGranularity) /* 534 */
+#define Tcl_SaveInterpState \
+	(tclStubsPtr->tcl_SaveInterpState) /* 535 */
+#define Tcl_RestoreInterpState \
+	(tclStubsPtr->tcl_RestoreInterpState) /* 536 */
+#define Tcl_DiscardInterpState \
+	(tclStubsPtr->tcl_DiscardInterpState) /* 537 */
+#define Tcl_SetReturnOptions \
+	(tclStubsPtr->tcl_SetReturnOptions) /* 538 */
+#define Tcl_GetReturnOptions \
+	(tclStubsPtr->tcl_GetReturnOptions) /* 539 */
+#define Tcl_IsEnsemble \
+	(tclStubsPtr->tcl_IsEnsemble) /* 540 */
+#define Tcl_CreateEnsemble \
+	(tclStubsPtr->tcl_CreateEnsemble) /* 541 */
+#define Tcl_FindEnsemble \
+	(tclStubsPtr->tcl_FindEnsemble) /* 542 */
+#define Tcl_SetEnsembleSubcommandList \
+	(tclStubsPtr->tcl_SetEnsembleSubcommandList) /* 543 */
+#define Tcl_SetEnsembleMappingDict \
+	(tclStubsPtr->tcl_SetEnsembleMappingDict) /* 544 */
+#define Tcl_SetEnsembleUnknownHandler \
+	(tclStubsPtr->tcl_SetEnsembleUnknownHandler) /* 545 */
+#define Tcl_SetEnsembleFlags \
+	(tclStubsPtr->tcl_SetEnsembleFlags) /* 546 */
+#define Tcl_GetEnsembleSubcommandList \
+	(tclStubsPtr->tcl_GetEnsembleSubcommandList) /* 547 */
+#define Tcl_GetEnsembleMappingDict \
+	(tclStubsPtr->tcl_GetEnsembleMappingDict) /* 548 */
+#define Tcl_GetEnsembleUnknownHandler \
+	(tclStubsPtr->tcl_GetEnsembleUnknownHandler) /* 549 */
+#define Tcl_GetEnsembleFlags \
+	(tclStubsPtr->tcl_GetEnsembleFlags) /* 550 */
+#define Tcl_GetEnsembleNamespace \
+	(tclStubsPtr->tcl_GetEnsembleNamespace) /* 551 */
+#define Tcl_SetTimeProc \
+	(tclStubsPtr->tcl_SetTimeProc) /* 552 */
+#define Tcl_QueryTimeProc \
+	(tclStubsPtr->tcl_QueryTimeProc) /* 553 */
+#define Tcl_ChannelThreadActionProc \
+	(tclStubsPtr->tcl_ChannelThreadActionProc) /* 554 */
+#define Tcl_NewBignumObj \
+	(tclStubsPtr->tcl_NewBignumObj) /* 555 */
+#define Tcl_DbNewBignumObj \
+	(tclStubsPtr->tcl_DbNewBignumObj) /* 556 */
+#define Tcl_SetBignumObj \
+	(tclStubsPtr->tcl_SetBignumObj) /* 557 */
+#define Tcl_GetBignumFromObj \
+	(tclStubsPtr->tcl_GetBignumFromObj) /* 558 */
+#define Tcl_TakeBignumFromObj \
+	(tclStubsPtr->tcl_TakeBignumFromObj) /* 559 */
+#define Tcl_TruncateChannel \
+	(tclStubsPtr->tcl_TruncateChannel) /* 560 */
+#define Tcl_ChannelTruncateProc \
+	(tclStubsPtr->tcl_ChannelTruncateProc) /* 561 */
+#define Tcl_SetChannelErrorInterp \
+	(tclStubsPtr->tcl_SetChannelErrorInterp) /* 562 */
+#define Tcl_GetChannelErrorInterp \
+	(tclStubsPtr->tcl_GetChannelErrorInterp) /* 563 */
+#define Tcl_SetChannelError \
+	(tclStubsPtr->tcl_SetChannelError) /* 564 */
+#define Tcl_GetChannelError \
+	(tclStubsPtr->tcl_GetChannelError) /* 565 */
+#define Tcl_InitBignumFromDouble \
+	(tclStubsPtr->tcl_InitBignumFromDouble) /* 566 */
+#define Tcl_GetNamespaceUnknownHandler \
+	(tclStubsPtr->tcl_GetNamespaceUnknownHandler) /* 567 */
+#define Tcl_SetNamespaceUnknownHandler \
+	(tclStubsPtr->tcl_SetNamespaceUnknownHandler) /* 568 */
+#define Tcl_GetEncodingFromObj \
+	(tclStubsPtr->tcl_GetEncodingFromObj) /* 569 */
+#define Tcl_GetEncodingSearchPath \
+	(tclStubsPtr->tcl_GetEncodingSearchPath) /* 570 */
+#define Tcl_SetEncodingSearchPath \
+	(tclStubsPtr->tcl_SetEncodingSearchPath) /* 571 */
+#define Tcl_GetEncodingNameFromEnvironment \
+	(tclStubsPtr->tcl_GetEncodingNameFromEnvironment) /* 572 */
+#define Tcl_PkgRequireProc \
+	(tclStubsPtr->tcl_PkgRequireProc) /* 573 */
+#define Tcl_AppendObjToErrorInfo \
+	(tclStubsPtr->tcl_AppendObjToErrorInfo) /* 574 */
+#define Tcl_AppendLimitedToObj \
+	(tclStubsPtr->tcl_AppendLimitedToObj) /* 575 */
+#define Tcl_Format \
+	(tclStubsPtr->tcl_Format) /* 576 */
+#define Tcl_AppendFormatToObj \
+	(tclStubsPtr->tcl_AppendFormatToObj) /* 577 */
+#define Tcl_ObjPrintf \
+	(tclStubsPtr->tcl_ObjPrintf) /* 578 */
+#define Tcl_AppendPrintfToObj \
+	(tclStubsPtr->tcl_AppendPrintfToObj) /* 579 */
+#define Tcl_CancelEval \
+	(tclStubsPtr->tcl_CancelEval) /* 580 */
+#define Tcl_Canceled \
+	(tclStubsPtr->tcl_Canceled) /* 581 */
+#define Tcl_CreatePipe \
+	(tclStubsPtr->tcl_CreatePipe) /* 582 */
+#define Tcl_NRCreateCommand \
+	(tclStubsPtr->tcl_NRCreateCommand) /* 583 */
+#define Tcl_NREvalObj \
+	(tclStubsPtr->tcl_NREvalObj) /* 584 */
+#define Tcl_NREvalObjv \
+	(tclStubsPtr->tcl_NREvalObjv) /* 585 */
+#define Tcl_NRCmdSwap \
+	(tclStubsPtr->tcl_NRCmdSwap) /* 586 */
+#define Tcl_NRAddCallback \
+	(tclStubsPtr->tcl_NRAddCallback) /* 587 */
+#define Tcl_NRCallObjProc \
+	(tclStubsPtr->tcl_NRCallObjProc) /* 588 */
+#define Tcl_GetFSDeviceFromStat \
+	(tclStubsPtr->tcl_GetFSDeviceFromStat) /* 589 */
+#define Tcl_GetFSInodeFromStat \
+	(tclStubsPtr->tcl_GetFSInodeFromStat) /* 590 */
+#define Tcl_GetModeFromStat \
+	(tclStubsPtr->tcl_GetModeFromStat) /* 591 */
+#define Tcl_GetLinkCountFromStat \
+	(tclStubsPtr->tcl_GetLinkCountFromStat) /* 592 */
+#define Tcl_GetUserIdFromStat \
+	(tclStubsPtr->tcl_GetUserIdFromStat) /* 593 */
+#define Tcl_GetGroupIdFromStat \
+	(tclStubsPtr->tcl_GetGroupIdFromStat) /* 594 */
+#define Tcl_GetDeviceTypeFromStat \
+	(tclStubsPtr->tcl_GetDeviceTypeFromStat) /* 595 */
+#define Tcl_GetAccessTimeFromStat \
+	(tclStubsPtr->tcl_GetAccessTimeFromStat) /* 596 */
+#define Tcl_GetModificationTimeFromStat \
+	(tclStubsPtr->tcl_GetModificationTimeFromStat) /* 597 */
+#define Tcl_GetChangeTimeFromStat \
+	(tclStubsPtr->tcl_GetChangeTimeFromStat) /* 598 */
+#define Tcl_GetSizeFromStat \
+	(tclStubsPtr->tcl_GetSizeFromStat) /* 599 */
+#define Tcl_GetBlocksFromStat \
+	(tclStubsPtr->tcl_GetBlocksFromStat) /* 600 */
+#define Tcl_GetBlockSizeFromStat \
+	(tclStubsPtr->tcl_GetBlockSizeFromStat) /* 601 */
+#define Tcl_SetEnsembleParameterList \
+	(tclStubsPtr->tcl_SetEnsembleParameterList) /* 602 */
+#define Tcl_GetEnsembleParameterList \
+	(tclStubsPtr->tcl_GetEnsembleParameterList) /* 603 */
+#define Tcl_ParseArgsObjv \
+	(tclStubsPtr->tcl_ParseArgsObjv) /* 604 */
+#define Tcl_GetErrorLine \
+	(tclStubsPtr->tcl_GetErrorLine) /* 605 */
+#define Tcl_SetErrorLine \
+	(tclStubsPtr->tcl_SetErrorLine) /* 606 */
+#define Tcl_TransferResult \
+	(tclStubsPtr->tcl_TransferResult) /* 607 */
+#define Tcl_InterpActive \
+	(tclStubsPtr->tcl_InterpActive) /* 608 */
+#define Tcl_BackgroundException \
+	(tclStubsPtr->tcl_BackgroundException) /* 609 */
+#define Tcl_ZlibDeflate \
+	(tclStubsPtr->tcl_ZlibDeflate) /* 610 */
+#define Tcl_ZlibInflate \
+	(tclStubsPtr->tcl_ZlibInflate) /* 611 */
+#define Tcl_ZlibCRC32 \
+	(tclStubsPtr->tcl_ZlibCRC32) /* 612 */
+#define Tcl_ZlibAdler32 \
+	(tclStubsPtr->tcl_ZlibAdler32) /* 613 */
+#define Tcl_ZlibStreamInit \
+	(tclStubsPtr->tcl_ZlibStreamInit) /* 614 */
+#define Tcl_ZlibStreamGetCommandName \
+	(tclStubsPtr->tcl_ZlibStreamGetCommandName) /* 615 */
+#define Tcl_ZlibStreamEof \
+	(tclStubsPtr->tcl_ZlibStreamEof) /* 616 */
+#define Tcl_ZlibStreamChecksum \
+	(tclStubsPtr->tcl_ZlibStreamChecksum) /* 617 */
+#define Tcl_ZlibStreamPut \
+	(tclStubsPtr->tcl_ZlibStreamPut) /* 618 */
+#define Tcl_ZlibStreamGet \
+	(tclStubsPtr->tcl_ZlibStreamGet) /* 619 */
+#define Tcl_ZlibStreamClose \
+	(tclStubsPtr->tcl_ZlibStreamClose) /* 620 */
+#define Tcl_ZlibStreamReset \
+	(tclStubsPtr->tcl_ZlibStreamReset) /* 621 */
+#define Tcl_SetStartupScript \
+	(tclStubsPtr->tcl_SetStartupScript) /* 622 */
+#define Tcl_GetStartupScript \
+	(tclStubsPtr->tcl_GetStartupScript) /* 623 */
+#define Tcl_CloseEx \
+	(tclStubsPtr->tcl_CloseEx) /* 624 */
+#define Tcl_NRExprObj \
+	(tclStubsPtr->tcl_NRExprObj) /* 625 */
+#define Tcl_NRSubstObj \
+	(tclStubsPtr->tcl_NRSubstObj) /* 626 */
+#define Tcl_LoadFile \
+	(tclStubsPtr->tcl_LoadFile) /* 627 */
+#define Tcl_FindSymbol \
+	(tclStubsPtr->tcl_FindSymbol) /* 628 */
+#define Tcl_FSUnloadFile \
+	(tclStubsPtr->tcl_FSUnloadFile) /* 629 */
+#define Tcl_ZlibStreamSetCompressionDictionary \
+	(tclStubsPtr->tcl_ZlibStreamSetCompressionDictionary) /* 630 */
+
+#endif /* defined(USE_TCL_STUBS) */
+
+/* !END!: Do not edit above this line. */
+
+#if defined(USE_TCL_STUBS)
+#   undef Tcl_CreateInterp
+#   undef Tcl_FindExecutable
+#   undef Tcl_GetStringResult
+#   undef Tcl_Init
+#   undef Tcl_SetPanicProc
+#   undef Tcl_SetVar
+#   undef Tcl_ObjSetVar2
+#   undef Tcl_StaticPackage
+#   undef TclFSGetNativePath
+#   define Tcl_CreateInterp() (tclStubsPtr->tcl_CreateInterp())
+#   define Tcl_GetStringResult(interp) (tclStubsPtr->tcl_GetStringResult(interp))
+#   define Tcl_Init(interp) (tclStubsPtr->tcl_Init(interp))
+#   define Tcl_SetPanicProc(proc) (tclStubsPtr->tcl_SetPanicProc(proc))
+#   define Tcl_SetVar(interp, varName, newValue, flags) \
+	    (tclStubsPtr->tcl_SetVar(interp, varName, newValue, flags))
+#   define Tcl_ObjSetVar2(interp, part1, part2, newValue, flags) \
+	    (tclStubsPtr->tcl_ObjSetVar2(interp, part1, part2, newValue, flags))
+#endif
+
+#if defined(_WIN32) && defined(UNICODE)
+#   define Tcl_FindExecutable(arg) ((Tcl_FindExecutable)((const char *)(arg)))
+#   define Tcl_MainEx Tcl_MainExW
+    EXTERN void Tcl_MainExW(int argc, wchar_t **argv,
+	    Tcl_AppInitProc *appInitProc, Tcl_Interp *interp);
+#endif
+
+#undef TCL_STORAGE_CLASS
+#define TCL_STORAGE_CLASS DLLIMPORT
+
+#undef Tcl_SeekOld
+#undef Tcl_TellOld
+
+#undef Tcl_PkgPresent
+#define Tcl_PkgPresent(interp, name, version, exact) \
+	Tcl_PkgPresentEx(interp, name, version, exact, NULL)
+#undef Tcl_PkgProvide
+#define Tcl_PkgProvide(interp, name, version) \
+	Tcl_PkgProvideEx(interp, name, version, NULL)
+#undef Tcl_PkgRequire
+#define Tcl_PkgRequire(interp, name, version, exact) \
+	Tcl_PkgRequireEx(interp, name, version, exact, NULL)
+#undef Tcl_GetIndexFromObj
+#define Tcl_GetIndexFromObj(interp, objPtr, tablePtr, msg, flags, indexPtr) \
+	Tcl_GetIndexFromObjStruct(interp, objPtr, tablePtr, \
+	sizeof(char *), msg, flags, indexPtr)
+#undef Tcl_NewBooleanObj
+#define Tcl_NewBooleanObj(boolValue) \
+	Tcl_NewIntObj((boolValue)!=0)
+#undef Tcl_DbNewBooleanObj
+#define Tcl_DbNewBooleanObj(boolValue, file, line) \
+	Tcl_DbNewLongObj((boolValue)!=0, file, line)
+#undef Tcl_SetBooleanObj
+#define Tcl_SetBooleanObj(objPtr, boolValue) \
+	Tcl_SetIntObj((objPtr), (boolValue)!=0)
+#undef Tcl_SetVar
+#define Tcl_SetVar(interp, varName, newValue, flags) \
+	Tcl_SetVar2(interp, varName, NULL, newValue, flags)
+#undef Tcl_UnsetVar
+#define Tcl_UnsetVar(interp, varName, flags) \
+	Tcl_UnsetVar2(interp, varName, NULL, flags)
+#undef Tcl_GetVar
+#define Tcl_GetVar(interp, varName, flags) \
+	Tcl_GetVar2(interp, varName, NULL, flags)
+#undef Tcl_TraceVar
+#define Tcl_TraceVar(interp, varName, flags, proc, clientData) \
+	Tcl_TraceVar2(interp, varName, NULL, flags, proc, clientData)
+#undef Tcl_UntraceVar
+#define Tcl_UntraceVar(interp, varName, flags, proc, clientData) \
+	Tcl_UntraceVar2(interp, varName, NULL, flags, proc, clientData)
+#undef Tcl_VarTraceInfo
+#define Tcl_VarTraceInfo(interp, varName, flags, proc, prevClientData) \
+	Tcl_VarTraceInfo2(interp, varName, NULL, flags, proc, prevClientData)
+#undef Tcl_UpVar
+#define Tcl_UpVar(interp, frameName, varName, localName, flags) \
+	Tcl_UpVar2(interp, frameName, varName, NULL, localName, flags)
+
+#if defined(USE_TCL_STUBS) && !defined(USE_TCL_STUB_PROCS)
+#   if defined(__CYGWIN__) && defined(TCL_WIDE_INT_IS_LONG)
+/* On Cygwin64, long is 64-bit while on Win64 long is 32-bit. Therefore
+ * we have to make sure that all stub entries on Cygwin64 follow the
+ * Win64 signature. Cygwin64 stubbed extensions cannot use those stub
+ * entries any more, they should use the 64-bit alternatives where
+ * possible. Tcl 9 must find a better solution, but that cannot be done
+ * without introducing a binary incompatibility.
+ */
+#	undef Tcl_DbNewLongObj
+#	undef Tcl_GetLongFromObj
+#	undef Tcl_NewLongObj
+#	undef Tcl_SetLongObj
+#	undef Tcl_ExprLong
+#	undef Tcl_ExprLongObj
+#	undef Tcl_UniCharNcmp
+#	undef Tcl_UtfNcmp
+#	undef Tcl_UtfNcasecmp
+#	undef Tcl_UniCharNcasecmp
+#	define Tcl_DbNewLongObj ((Tcl_Obj*(*)(long,const char*,int))Tcl_DbNewWideIntObj)
+#	define Tcl_GetLongFromObj ((int(*)(Tcl_Interp*,Tcl_Obj*,long*))Tcl_GetWideIntFromObj)
+#	define Tcl_NewLongObj ((Tcl_Obj*(*)(long))Tcl_NewWideIntObj)
+#	define Tcl_SetLongObj ((void(*)(Tcl_Obj*,long))Tcl_SetWideIntObj)
+#	define Tcl_ExprLong TclExprLong
+	static inline int TclExprLong(Tcl_Interp *interp, const char *string, long *ptr){
+	    int intValue;
+	    int result = tclStubsPtr->tcl_ExprLong(interp, string, (long *)&intValue);
+	    if (result == TCL_OK) *ptr = (long)intValue;
+	    return result;
+	}
+#	define Tcl_ExprLongObj TclExprLongObj
+	static inline int TclExprLongObj(Tcl_Interp *interp, Tcl_Obj *obj, long *ptr){
+	    int intValue;
+	    int result = tclStubsPtr->tcl_ExprLongObj(interp, obj, (long *)&intValue);
+	    if (result == TCL_OK) *ptr = (long)intValue;
+	    return result;
+	}
+#	define Tcl_UniCharNcmp(ucs,uct,n) \
+		((int(*)(const Tcl_UniChar*,const Tcl_UniChar*,unsigned int))tclStubsPtr->tcl_UniCharNcmp)(ucs,uct,(unsigned int)(n))
+#	define Tcl_UtfNcmp(s1,s2,n) \
+		((int(*)(const char*,const char*,unsigned int))tclStubsPtr->tcl_UtfNcmp)(s1,s2,(unsigned int)(n))
+#	define Tcl_UtfNcasecmp(s1,s2,n) \
+		((int(*)(const char*,const char*,unsigned int))tclStubsPtr->tcl_UtfNcasecmp)(s1,s2,(unsigned int)(n))
+#	define Tcl_UniCharNcasecmp(ucs,uct,n) \
+		((int(*)(const Tcl_UniChar*,const Tcl_UniChar*,unsigned int))tclStubsPtr->tcl_UniCharNcasecmp)(ucs,uct,(unsigned int)(n))
+#   endif
+#endif
+
+/*
+ * Deprecated Tcl procedures:
+ */
+
+#undef Tcl_EvalObj
+#define Tcl_EvalObj(interp,objPtr) \
+    Tcl_EvalObjEx((interp),(objPtr),0)
+#undef Tcl_GlobalEvalObj
+#define Tcl_GlobalEvalObj(interp,objPtr) \
+    Tcl_EvalObjEx((interp),(objPtr),TCL_EVAL_GLOBAL)
+
+#endif /* _TCLDECLS */
diff --git a/generic/tclDictObj.c b/generic/tclDictObj.c
new file mode 100644
index 0000000..428173d
--- /dev/null
+++ b/generic/tclDictObj.c
@@ -0,0 +1,3664 @@
+/*
+ * tclDictObj.c --
+ *
+ *	This file contains functions that implement the Tcl dict object type
+ *	and its accessor command.
+ *
+ * Copyright (c) 2002-2010 by Donal K. Fellows.
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#include "tclInt.h"
+#include "tommath.h"
+
+/*
+ * Forward declaration.
+ */
+struct Dict;
+
+/*
+ * Prototypes for functions defined later in this file:
+ */
+
+static void		DeleteDict(struct Dict *dict);
+static int		DictAppendCmd(ClientData dummy, Tcl_Interp *interp,
+			    int objc, Tcl_Obj *const *objv);
+static int		DictCreateCmd(ClientData dummy, Tcl_Interp *interp,
+			    int objc, Tcl_Obj *const *objv);
+static int		DictExistsCmd(ClientData dummy, Tcl_Interp *interp,
+			    int objc, Tcl_Obj *const *objv);
+static int		DictFilterCmd(ClientData dummy, Tcl_Interp *interp,
+			    int objc, Tcl_Obj *const *objv);
+static int		DictGetCmd(ClientData dummy, Tcl_Interp *interp,
+			    int objc, Tcl_Obj *const *objv);
+static int		DictIncrCmd(ClientData dummy, Tcl_Interp *interp,
+			    int objc, Tcl_Obj *const *objv);
+static int		DictInfoCmd(ClientData dummy, Tcl_Interp *interp,
+			    int objc, Tcl_Obj *const *objv);
+static int		DictKeysCmd(ClientData dummy, Tcl_Interp *interp,
+			    int objc, Tcl_Obj *const *objv);
+static int		DictLappendCmd(ClientData dummy, Tcl_Interp *interp,
+			    int objc, Tcl_Obj *const *objv);
+static int		DictMergeCmd(ClientData dummy, Tcl_Interp *interp,
+			    int objc, Tcl_Obj *const *objv);
+static int		DictRemoveCmd(ClientData dummy, Tcl_Interp *interp,
+			    int objc, Tcl_Obj *const *objv);
+static int		DictReplaceCmd(ClientData dummy, Tcl_Interp *interp,
+			    int objc, Tcl_Obj *const *objv);
+static int		DictSetCmd(ClientData dummy, Tcl_Interp *interp,
+			    int objc, Tcl_Obj *const *objv);
+static int		DictSizeCmd(ClientData dummy, Tcl_Interp *interp,
+			    int objc, Tcl_Obj *const *objv);
+static int		DictUnsetCmd(ClientData dummy, Tcl_Interp *interp,
+			    int objc, Tcl_Obj *const *objv);
+static int		DictUpdateCmd(ClientData dummy, Tcl_Interp *interp,
+			    int objc, Tcl_Obj *const *objv);
+static int		DictValuesCmd(ClientData dummy, Tcl_Interp *interp,
+			    int objc, Tcl_Obj *const *objv);
+static int		DictWithCmd(ClientData dummy, Tcl_Interp *interp,
+			    int objc, Tcl_Obj *const *objv);
+static void		DupDictInternalRep(Tcl_Obj *srcPtr, Tcl_Obj *copyPtr);
+static void		FreeDictInternalRep(Tcl_Obj *dictPtr);
+static void		InvalidateDictChain(Tcl_Obj *dictObj);
+static int		SetDictFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr);
+static void		UpdateStringOfDict(Tcl_Obj *dictPtr);
+static Tcl_HashEntry *	AllocChainEntry(Tcl_HashTable *tablePtr,void *keyPtr);
+static inline void	InitChainTable(struct Dict *dict);
+static inline void	DeleteChainTable(struct Dict *dict);
+static inline Tcl_HashEntry *CreateChainEntry(struct Dict *dict,
+			    Tcl_Obj *keyPtr, int *newPtr);
+static inline int	DeleteChainEntry(struct Dict *dict, Tcl_Obj *keyPtr);
+static Tcl_NRPostProc	FinalizeDictUpdate;
+static Tcl_NRPostProc	FinalizeDictWith;
+static Tcl_ObjCmdProc	DictForNRCmd;
+static Tcl_ObjCmdProc	DictMapNRCmd;
+static Tcl_NRPostProc	DictForLoopCallback;
+static Tcl_NRPostProc	DictMapLoopCallback;
+
+/*
+ * Table of dict subcommand names and implementations.
+ */
+
+static const EnsembleImplMap implementationMap[] = {
+    {"append",	DictAppendCmd,	TclCompileDictAppendCmd, NULL, NULL, 0 },
+    {"create",	DictCreateCmd,	TclCompileDictCreateCmd, NULL, NULL, 0 },
+    {"exists",	DictExistsCmd,	TclCompileDictExistsCmd, NULL, NULL, 0 },
+    {"filter",	DictFilterCmd,	NULL, NULL, NULL, 0 },
+    {"for",	NULL,		TclCompileDictForCmd, DictForNRCmd, NULL, 0 },
+    {"get",	DictGetCmd,	TclCompileDictGetCmd, NULL, NULL, 0 },
+    {"incr",	DictIncrCmd,	TclCompileDictIncrCmd, NULL, NULL, 0 },
+    {"info",	DictInfoCmd,	TclCompileBasic1ArgCmd, NULL, NULL, 0 },
+    {"keys",	DictKeysCmd,	TclCompileBasic1Or2ArgCmd, NULL, NULL, 0 },
+    {"lappend",	DictLappendCmd,	TclCompileDictLappendCmd, NULL, NULL, 0 },
+    {"map", 	NULL,       	TclCompileDictMapCmd, DictMapNRCmd, NULL, 0 },
+    {"merge",	DictMergeCmd,	TclCompileDictMergeCmd, NULL, NULL, 0 },
+    {"remove",	DictRemoveCmd,	TclCompileBasicMin1ArgCmd, NULL, NULL, 0 },
+    {"replace",	DictReplaceCmd, NULL, NULL, NULL, 0 },
+    {"set",	DictSetCmd,	TclCompileDictSetCmd, NULL, NULL, 0 },
+    {"size",	DictSizeCmd,	TclCompileBasic1ArgCmd, NULL, NULL, 0 },
+    {"unset",	DictUnsetCmd,	TclCompileDictUnsetCmd, NULL, NULL, 0 },
+    {"update",	DictUpdateCmd,	TclCompileDictUpdateCmd, NULL, NULL, 0 },
+    {"values",	DictValuesCmd,	TclCompileBasic1Or2ArgCmd, NULL, NULL, 0 },
+    {"with",	DictWithCmd,	TclCompileDictWithCmd, NULL, NULL, 0 },
+    {NULL, NULL, NULL, NULL, NULL, 0}
+};
+
+/*
+ * Internal representation of the entries in the hash table that backs a
+ * dictionary.
+ */
+
+typedef struct ChainEntry {
+    Tcl_HashEntry entry;
+    struct ChainEntry *prevPtr;
+    struct ChainEntry *nextPtr;
+} ChainEntry;
+
+/*
+ * Internal representation of a dictionary.
+ *
+ * The internal representation of a dictionary object is a hash table (with
+ * Tcl_Objs for both keys and values), a reference count and epoch number for
+ * detecting concurrent modifications of the dictionary, and a pointer to the
+ * parent object (used when invalidating string reps of pathed dictionary
+ * trees) which is NULL in normal use. The fact that hash tables know (with
+ * appropriate initialisation) already about objects makes key management /so/
+ * much easier!
+ *
+ * Reference counts are used to enable safe iteration across hashes while
+ * allowing the type of the containing object to be modified.
+ */
+
+typedef struct Dict {
+    Tcl_HashTable table;	/* Object hash table to store mapping in. */
+    ChainEntry *entryChainHead;	/* Linked list of all entries in the
+				 * dictionary. Used for doing traversal of the
+				 * entries in the order that they are
+				 * created. */
+    ChainEntry *entryChainTail;	/* Other end of linked list of all entries in
+				 * the dictionary. Used for doing traversal of
+				 * the entries in the order that they are
+				 * created. */
+    int epoch;			/* Epoch counter */
+    int refcount;		/* Reference counter (see above) */
+    Tcl_Obj *chain;		/* Linked list used for invalidating the
+				 * string representations of updated nested
+				 * dictionaries. */
+} Dict;
+
+/*
+ * Accessor macro for converting between a Tcl_Obj* and a Dict. Note that this
+ * must be assignable as well as readable.
+ */
+
+#define DICT(dictObj)   (*((Dict **)&(dictObj)->internalRep.twoPtrValue.ptr1))
+
+/*
+ * The structure below defines the dictionary object type by means of
+ * functions that can be invoked by generic object code.
+ */
+
+const Tcl_ObjType tclDictType = {
+    "dict",
+    FreeDictInternalRep,		/* freeIntRepProc */
+    DupDictInternalRep,			/* dupIntRepProc */
+    UpdateStringOfDict,			/* updateStringProc */
+    SetDictFromAny			/* setFromAnyProc */
+};
+
+/*
+ * The type of the specially adapted version of the Tcl_Obj*-containing hash
+ * table defined in the tclObj.c code. This version differs in that it
+ * allocates a bit more space in each hash entry in order to hold the pointers
+ * used to keep the hash entries in a linked list.
+ *
+ * Note that this type of hash table is *only* suitable for direct use in
+ * *this* file. Everything else should use the dict iterator API.
+ */
+
+static const Tcl_HashKeyType chainHashType = {
+    TCL_HASH_KEY_TYPE_VERSION,
+    0,
+    TclHashObjKey,
+    TclCompareObjKeys,
+    AllocChainEntry,
+    TclFreeObjEntry
+};
+
+/*
+ * Structure used in implementation of 'dict map' to hold the state that gets
+ * passed between parts of the implementation.
+ */
+
+typedef struct {
+    Tcl_Obj *keyVarObj;		/* The name of the variable that will have
+				 * keys assigned to it. */
+    Tcl_Obj *valueVarObj;	/* The name of the variable that will have
+				 * values assigned to it. */
+    Tcl_DictSearch search;	/* The dictionary search structure. */
+    Tcl_Obj *scriptObj;		/* The script to evaluate each time through
+				 * the loop. */
+    Tcl_Obj *accumulatorObj;	/* The dictionary used to accumulate the
+				 * results. */
+} DictMapStorage;
+
+/***** START OF FUNCTIONS IMPLEMENTING DICT CORE API *****/
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * AllocChainEntry --
+ *
+ *	Allocate space for a Tcl_HashEntry containing the Tcl_Obj * key, and
+ *	which has a bit of extra space afterwards for storing pointers to the
+ *	rest of the chain of entries (the extra pointers are left NULL).
+ *
+ * Results:
+ *	The return value is a pointer to the created entry.
+ *
+ * Side effects:
+ *	Increments the reference count on the object.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static Tcl_HashEntry *
+AllocChainEntry(
+    Tcl_HashTable *tablePtr,
+    void *keyPtr)
+{
+    Tcl_Obj *objPtr = keyPtr;
+    ChainEntry *cPtr;
+
+    cPtr = ckalloc(sizeof(ChainEntry));
+    cPtr->entry.key.objPtr = objPtr;
+    Tcl_IncrRefCount(objPtr);
+    cPtr->entry.clientData = NULL;
+    cPtr->prevPtr = cPtr->nextPtr = NULL;
+
+    return &cPtr->entry;
+}
+
+/*
+ * Helper functions that disguise most of the details relating to how the
+ * linked list of hash entries is managed. In particular, these manage the
+ * creation of the table and initializing of the chain, the deletion of the
+ * table and chain, the adding of an entry to the chain, and the removal of an
+ * entry from the chain.
+ */
+
+static inline void
+InitChainTable(
+    Dict *dict)
+{
+    Tcl_InitCustomHashTable(&dict->table, TCL_CUSTOM_PTR_KEYS,
+	    &chainHashType);
+    dict->entryChainHead = dict->entryChainTail = NULL;
+}
+
+static inline void
+DeleteChainTable(
+    Dict *dict)
+{
+    ChainEntry *cPtr;
+
+    for (cPtr=dict->entryChainHead ; cPtr!=NULL ; cPtr=cPtr->nextPtr) {
+	Tcl_Obj *valuePtr = Tcl_GetHashValue(&cPtr->entry);
+
+	TclDecrRefCount(valuePtr);
+    }
+    Tcl_DeleteHashTable(&dict->table);
+}
+
+static inline Tcl_HashEntry *
+CreateChainEntry(
+    Dict *dict,
+    Tcl_Obj *keyPtr,
+    int *newPtr)
+{
+    ChainEntry *cPtr = (ChainEntry *)
+	    Tcl_CreateHashEntry(&dict->table, keyPtr, newPtr);
+
+    /*
+     * If this is a new entry in the hash table, stitch it into the chain.
+     */
+
+    if (*newPtr) {
+	cPtr->nextPtr = NULL;
+	if (dict->entryChainHead == NULL) {
+	    cPtr->prevPtr = NULL;
+	    dict->entryChainHead = cPtr;
+	    dict->entryChainTail = cPtr;
+	} else {
+	    cPtr->prevPtr = dict->entryChainTail;
+	    dict->entryChainTail->nextPtr = cPtr;
+	    dict->entryChainTail = cPtr;
+	}
+    }
+
+    return &cPtr->entry;
+}
+
+static inline int
+DeleteChainEntry(
+    Dict *dict,
+    Tcl_Obj *keyPtr)
+{
+    ChainEntry *cPtr = (ChainEntry *)
+	    Tcl_FindHashEntry(&dict->table, keyPtr);
+
+    if (cPtr == NULL) {
+	return 0;
+    } else {
+	Tcl_Obj *valuePtr = Tcl_GetHashValue(&cPtr->entry);
+
+	TclDecrRefCount(valuePtr);
+    }
+
+    /*
+     * Unstitch from the chain.
+     */
+
+    if (cPtr->nextPtr) {
+	cPtr->nextPtr->prevPtr = cPtr->prevPtr;
+    } else {
+	dict->entryChainTail = cPtr->prevPtr;
+    }
+    if (cPtr->prevPtr) {
+	cPtr->prevPtr->nextPtr = cPtr->nextPtr;
+    } else {
+	dict->entryChainHead = cPtr->nextPtr;
+    }
+
+    Tcl_DeleteHashEntry(&cPtr->entry);
+    return 1;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * DupDictInternalRep --
+ *
+ *	Initialize the internal representation of a dictionary Tcl_Obj to a
+ *	copy of the internal representation of an existing dictionary object.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	"srcPtr"s dictionary internal rep pointer should not be NULL and we
+ *	assume it is not NULL. We set "copyPtr"s internal rep to a pointer to
+ *	a newly allocated dictionary rep that, in turn, points to "srcPtr"s
+ *	key and value objects. Those objects are not actually copied but are
+ *	shared between "srcPtr" and "copyPtr". The ref count of each key and
+ *	value object is incremented.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+DupDictInternalRep(
+    Tcl_Obj *srcPtr,
+    Tcl_Obj *copyPtr)
+{
+    Dict *oldDict = DICT(srcPtr);
+    Dict *newDict = ckalloc(sizeof(Dict));
+    ChainEntry *cPtr;
+
+    /*
+     * Copy values across from the old hash table.
+     */
+
+    InitChainTable(newDict);
+    for (cPtr=oldDict->entryChainHead ; cPtr!=NULL ; cPtr=cPtr->nextPtr) {
+	Tcl_Obj *key = Tcl_GetHashKey(&oldDict->table, &cPtr->entry);
+	Tcl_Obj *valuePtr = Tcl_GetHashValue(&cPtr->entry);
+	int n;
+	Tcl_HashEntry *hPtr = CreateChainEntry(newDict, key, &n);
+
+	/*
+	 * Fill in the contents.
+	 */
+
+	Tcl_SetHashValue(hPtr, valuePtr);
+	Tcl_IncrRefCount(valuePtr);
+    }
+
+    /*
+     * Initialise other fields.
+     */
+
+    newDict->epoch = 0;
+    newDict->chain = NULL;
+    newDict->refcount = 1;
+
+    /*
+     * Store in the object.
+     */
+
+    DICT(copyPtr) = newDict;
+    copyPtr->internalRep.twoPtrValue.ptr2 = NULL;
+    copyPtr->typePtr = &tclDictType;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * FreeDictInternalRep --
+ *
+ *	Deallocate the storage associated with a dictionary object's internal
+ *	representation.
+ *
+ * Results:
+ *	None
+ *
+ * Side effects:
+ *	Frees the memory holding the dictionary's internal hash table unless
+ *	it is locked by an iteration going over it.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+FreeDictInternalRep(
+    Tcl_Obj *dictPtr)
+{
+    Dict *dict = DICT(dictPtr);
+
+    dict->refcount--;
+    if (dict->refcount <= 0) {
+	DeleteDict(dict);
+    }
+    dictPtr->typePtr = NULL;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * DeleteDict --
+ *
+ *	Delete the structure that is used to implement a dictionary's internal
+ *	representation. Called when either the dictionary object loses its
+ *	internal representation or when the last iteration over the dictionary
+ *	completes.
+ *
+ * Results:
+ *	None
+ *
+ * Side effects:
+ *	Decrements the reference count of all key and value objects in the
+ *	dictionary, which may free them.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+DeleteDict(
+    Dict *dict)
+{
+    DeleteChainTable(dict);
+    ckfree(dict);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * UpdateStringOfDict --
+ *
+ *	Update the string representation for a dictionary object. Note: This
+ *	function does not invalidate an existing old string rep so storage
+ *	will be lost if this has not already been done. This code is based on
+ *	UpdateStringOfList in tclListObj.c
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The object's string is set to a valid string that results from the
+ *	dict-to-string conversion. This string will be empty if the dictionary
+ *	has no key/value pairs. The dictionary internal representation should
+ *	not be NULL and we assume it is not NULL.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+UpdateStringOfDict(
+    Tcl_Obj *dictPtr)
+{
+#define LOCAL_SIZE 20
+    int localFlags[LOCAL_SIZE], *flagPtr = NULL;
+    Dict *dict = DICT(dictPtr);
+    ChainEntry *cPtr;
+    Tcl_Obj *keyPtr, *valuePtr;
+    int i, length, bytesNeeded = 0;
+    const char *elem;
+    char *dst;
+    const int maxFlags = UINT_MAX / sizeof(int);
+
+    /*
+     * This field is the most useful one in the whole hash structure, and it
+     * is not exposed by any API function...
+     */
+
+    int numElems = dict->table.numEntries * 2;
+
+    /* Handle empty list case first, simplifies what follows */
+    if (numElems == 0) {
+	dictPtr->bytes = tclEmptyStringRep;
+	dictPtr->length = 0;
+	return;
+    }
+
+    /*
+     * Pass 1: estimate space, gather flags.
+     */
+
+    if (numElems <= LOCAL_SIZE) {
+	flagPtr = localFlags;
+    } else if (numElems > maxFlags) {
+	Tcl_Panic("max size for a Tcl value (%d bytes) exceeded", INT_MAX);
+    } else {
+	flagPtr = ckalloc(numElems * sizeof(int));
+    }
+    for (i=0,cPtr=dict->entryChainHead; i<numElems; i+=2,cPtr=cPtr->nextPtr) {
+	/*
+	 * Assume that cPtr is never NULL since we know the number of array
+	 * elements already.
+	 */
+
+	flagPtr[i] = ( i ? TCL_DONT_QUOTE_HASH : 0 );
+	keyPtr = Tcl_GetHashKey(&dict->table, &cPtr->entry);
+	elem = TclGetStringFromObj(keyPtr, &length);
+	bytesNeeded += TclScanElement(elem, length, flagPtr+i);
+	if (bytesNeeded < 0) {
+	    Tcl_Panic("max size for a Tcl value (%d bytes) exceeded", INT_MAX);
+	}
+
+	flagPtr[i+1] = TCL_DONT_QUOTE_HASH;
+	valuePtr = Tcl_GetHashValue(&cPtr->entry);
+	elem = TclGetStringFromObj(valuePtr, &length);
+	bytesNeeded += TclScanElement(elem, length, flagPtr+i+1);
+	if (bytesNeeded < 0) {
+	    Tcl_Panic("max size for a Tcl value (%d bytes) exceeded", INT_MAX);
+	}
+    }
+    if (bytesNeeded > INT_MAX - numElems + 1) {
+	Tcl_Panic("max size for a Tcl value (%d bytes) exceeded", INT_MAX);
+    }
+    bytesNeeded += numElems;
+
+    /*
+     * Pass 2: copy into string rep buffer.
+     */
+
+    dictPtr->length = bytesNeeded - 1;
+    dictPtr->bytes = ckalloc(bytesNeeded);
+    dst = dictPtr->bytes;
+    for (i=0,cPtr=dict->entryChainHead; i<numElems; i+=2,cPtr=cPtr->nextPtr) {
+	flagPtr[i] |= ( i ? TCL_DONT_QUOTE_HASH : 0 );
+	keyPtr = Tcl_GetHashKey(&dict->table, &cPtr->entry);
+	elem = TclGetStringFromObj(keyPtr, &length);
+	dst += TclConvertElement(elem, length, dst, flagPtr[i]);
+	*dst++ = ' ';
+
+	flagPtr[i+1] |= TCL_DONT_QUOTE_HASH;
+	valuePtr = Tcl_GetHashValue(&cPtr->entry);
+	elem = TclGetStringFromObj(valuePtr, &length);
+	dst += TclConvertElement(elem, length, dst, flagPtr[i+1]);
+	*dst++ = ' ';
+    }
+    dictPtr->bytes[dictPtr->length] = '\0';
+
+    if (flagPtr != localFlags) {
+	ckfree(flagPtr);
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * SetDictFromAny --
+ *
+ *	Convert a non-dictionary object into a dictionary object. This code is
+ *	very closely related to SetListFromAny in tclListObj.c but does not
+ *	actually guarantee that a dictionary object will have a string rep (as
+ *	conversions from lists are handled with a special case.)
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	If the string can be converted, it loses any old internal
+ *	representation that it had and gains a dictionary's internalRep.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+SetDictFromAny(
+    Tcl_Interp *interp,
+    Tcl_Obj *objPtr)
+{
+    Tcl_HashEntry *hPtr;
+    int isNew;
+    Dict *dict = ckalloc(sizeof(Dict));
+
+    InitChainTable(dict);
+
+    /*
+     * Since lists and dictionaries have very closely-related string
+     * representations (i.e. the same parsing code) we can safely special-case
+     * the conversion from lists to dictionaries.
+     */
+
+    if (objPtr->typePtr == &tclListType) {
+	int objc, i;
+	Tcl_Obj **objv;
+
+	/* Cannot fail, we already know the Tcl_ObjType is "list". */
+	TclListObjGetElements(NULL, objPtr, &objc, &objv);
+	if (objc & 1) {
+	    goto missingValue;
+	}
+
+	for (i=0 ; i<objc ; i+=2) {
+
+	    /* Store key and value in the hash table we're building. */
+	    hPtr = CreateChainEntry(dict, objv[i], &isNew);
+	    if (!isNew) {
+		Tcl_Obj *discardedValue = Tcl_GetHashValue(hPtr);
+
+		/*
+		 * Not really a well-formed dictionary as there are duplicate
+		 * keys, so better get the string rep here so that we can
+		 * convert back.
+		 */
+
+		(void) Tcl_GetString(objPtr);
+
+		TclDecrRefCount(discardedValue);
+	    }
+	    Tcl_SetHashValue(hPtr, objv[i+1]);
+	    Tcl_IncrRefCount(objv[i+1]); /* Since hash now holds ref to it */
+	}
+    } else {
+	int length;
+	const char *nextElem = TclGetStringFromObj(objPtr, &length);
+	const char *limit = (nextElem + length);
+
+	while (nextElem < limit) {
+	    Tcl_Obj *keyPtr, *valuePtr;
+	    const char *elemStart;
+	    int elemSize, literal;
+
+	    if (TclFindDictElement(interp, nextElem, (limit - nextElem),
+		    &elemStart, &nextElem, &elemSize, &literal) != TCL_OK) {
+		goto errorInFindDictElement;
+	    }
+	    if (elemStart == limit) {
+		break;
+	    }
+	    if (nextElem == limit) {
+		goto missingValue;
+	    }
+
+	    if (literal) {
+		TclNewStringObj(keyPtr, elemStart, elemSize);
+	    } else {
+		/* Avoid double copy */
+		TclNewObj(keyPtr);
+		keyPtr->bytes = ckalloc((unsigned) elemSize + 1);
+		keyPtr->length = TclCopyAndCollapse(elemSize, elemStart,
+			keyPtr->bytes);
+	    }
+
+	    if (TclFindDictElement(interp, nextElem, (limit - nextElem),
+		    &elemStart, &nextElem, &elemSize, &literal) != TCL_OK) {
+		TclDecrRefCount(keyPtr);
+		goto errorInFindDictElement;
+	    }
+
+	    if (literal) {
+		TclNewStringObj(valuePtr, elemStart, elemSize);
+	    } else {
+		/* Avoid double copy */
+		TclNewObj(valuePtr);
+		valuePtr->bytes = ckalloc((unsigned) elemSize + 1);
+		valuePtr->length = TclCopyAndCollapse(elemSize, elemStart,
+			valuePtr->bytes);
+	    }
+
+	    /* Store key and value in the hash table we're building. */
+	    hPtr = CreateChainEntry(dict, keyPtr, &isNew);
+	    if (!isNew) {
+		Tcl_Obj *discardedValue = Tcl_GetHashValue(hPtr);
+
+		TclDecrRefCount(keyPtr);
+		TclDecrRefCount(discardedValue);
+	    }
+	    Tcl_SetHashValue(hPtr, valuePtr);
+	    Tcl_IncrRefCount(valuePtr); /* since hash now holds ref to it */
+	}
+    }
+
+    /*
+     * Free the old internalRep before setting the new one. We do this as late
+     * as possible to allow the conversion code, in particular
+     * Tcl_GetStringFromObj, to use that old internalRep.
+     */
+
+    TclFreeIntRep(objPtr);
+    dict->epoch = 0;
+    dict->chain = NULL;
+    dict->refcount = 1;
+    DICT(objPtr) = dict;
+    objPtr->internalRep.twoPtrValue.ptr2 = NULL;
+    objPtr->typePtr = &tclDictType;
+    return TCL_OK;
+
+  missingValue:
+    if (interp != NULL) {
+	Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		"missing value to go with key", -1));
+	Tcl_SetErrorCode(interp, "TCL", "VALUE", "DICTIONARY", NULL);
+    }
+  errorInFindDictElement:
+    DeleteChainTable(dict);
+    ckfree(dict);
+    return TCL_ERROR;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclTraceDictPath --
+ *
+ *	Trace through a tree of dictionaries using the array of keys given. If
+ *	the flags argument has the DICT_PATH_UPDATE flag is set, a
+ *	backward-pointing chain of dictionaries is also built (in the Dict's
+ *	chain field) and the chained dictionaries are made into unshared
+ *	dictionaries (if they aren't already.)
+ *
+ * Results:
+ *	The object at the end of the path, or NULL if there was an error. Note
+ *	that this it is an error for an intermediate dictionary on the path to
+ *	not exist. If the flags argument has the DICT_PATH_EXISTS set, a
+ *	non-existent path gives a DICT_PATH_NON_EXISTENT result.
+ *
+ * Side effects:
+ *	If the flags argument is zero or DICT_PATH_EXISTS, there are no side
+ *	effects (other than potential conversion of objects to dictionaries.)
+ *	If the flags argument is DICT_PATH_UPDATE, the following additional
+ *	side effects occur. Shared dictionaries along the path are converted
+ *	into unshared objects, and a backward-pointing chain is built using
+ *	the chain fields of the dictionaries (for easy invalidation of string
+ *	representations using InvalidateDictChain). If the flags argument has
+ *	the DICT_PATH_CREATE bits set (and not the DICT_PATH_EXISTS bit),
+ *	non-existant keys will be inserted with a value of an empty
+ *	dictionary, resulting in the path being built.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_Obj *
+TclTraceDictPath(
+    Tcl_Interp *interp,
+    Tcl_Obj *dictPtr,
+    int keyc,
+    Tcl_Obj *const keyv[],
+    int flags)
+{
+    Dict *dict, *newDict;
+    int i;
+
+    if (dictPtr->typePtr != &tclDictType
+	    && SetDictFromAny(interp, dictPtr) != TCL_OK) {
+	return NULL;
+    }
+    dict = DICT(dictPtr);
+    if (flags & DICT_PATH_UPDATE) {
+	dict->chain = NULL;
+    }
+
+    for (i=0 ; i<keyc ; i++) {
+	Tcl_HashEntry *hPtr = Tcl_FindHashEntry(&dict->table, keyv[i]);
+	Tcl_Obj *tmpObj;
+
+	if (hPtr == NULL) {
+	    int isNew;			/* Dummy */
+
+	    if (flags & DICT_PATH_EXISTS) {
+		return DICT_PATH_NON_EXISTENT;
+	    }
+	    if ((flags & DICT_PATH_CREATE) != DICT_PATH_CREATE) {
+		if (interp != NULL) {
+		    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+			    "key \"%s\" not known in dictionary",
+			    TclGetString(keyv[i])));
+		    Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "DICT",
+			    TclGetString(keyv[i]), NULL);
+		}
+		return NULL;
+	    }
+
+	    /*
+	     * The next line should always set isNew to 1.
+	     */
+
+	    hPtr = CreateChainEntry(dict, keyv[i], &isNew);
+	    tmpObj = Tcl_NewDictObj();
+	    Tcl_IncrRefCount(tmpObj);
+	    Tcl_SetHashValue(hPtr, tmpObj);
+	} else {
+	    tmpObj = Tcl_GetHashValue(hPtr);
+	    if (tmpObj->typePtr != &tclDictType
+		    && SetDictFromAny(interp, tmpObj) != TCL_OK) {
+		return NULL;
+	    }
+	}
+
+	newDict = DICT(tmpObj);
+	if (flags & DICT_PATH_UPDATE) {
+	    if (Tcl_IsShared(tmpObj)) {
+		TclDecrRefCount(tmpObj);
+		tmpObj = Tcl_DuplicateObj(tmpObj);
+		Tcl_IncrRefCount(tmpObj);
+		Tcl_SetHashValue(hPtr, tmpObj);
+		dict->epoch++;
+		newDict = DICT(tmpObj);
+	    }
+
+	    newDict->chain = dictPtr;
+	}
+	dict = newDict;
+	dictPtr = tmpObj;
+    }
+    return dictPtr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * InvalidateDictChain --
+ *
+ *	Go through a dictionary chain (built by an updating invokation of
+ *	TclTraceDictPath) and invalidate the string representations of all the
+ *	dictionaries on the chain.
+ *
+ * Results:
+ *	None
+ *
+ * Side effects:
+ *	String reps are invalidated and epoch counters (for detecting illegal
+ *	concurrent modifications) are updated through the chain of updated
+ *	dictionaries.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+InvalidateDictChain(
+    Tcl_Obj *dictObj)
+{
+    Dict *dict = DICT(dictObj);
+
+    do {
+	TclInvalidateStringRep(dictObj);
+	dict->epoch++;
+	dictObj = dict->chain;
+	if (dictObj == NULL) {
+	    break;
+	}
+	dict->chain = NULL;
+	dict = DICT(dictObj);
+    } while (dict != NULL);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_DictObjPut --
+ *
+ *	Add a key,value pair to a dictionary, or update the value for a key if
+ *	that key already has a mapping in the dictionary.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	The object pointed to by dictPtr is converted to a dictionary if it is
+ *	not already one, and any string representation that it has is
+ *	invalidated.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_DictObjPut(
+    Tcl_Interp *interp,
+    Tcl_Obj *dictPtr,
+    Tcl_Obj *keyPtr,
+    Tcl_Obj *valuePtr)
+{
+    Dict *dict;
+    Tcl_HashEntry *hPtr;
+    int isNew;
+
+    if (Tcl_IsShared(dictPtr)) {
+	Tcl_Panic("%s called with shared object", "Tcl_DictObjPut");
+    }
+
+    if (dictPtr->typePtr != &tclDictType
+	    && SetDictFromAny(interp, dictPtr) != TCL_OK) {
+	return TCL_ERROR;
+    }
+
+    if (dictPtr->bytes != NULL) {
+	TclInvalidateStringRep(dictPtr);
+    }
+    dict = DICT(dictPtr);
+    hPtr = CreateChainEntry(dict, keyPtr, &isNew);
+    Tcl_IncrRefCount(valuePtr);
+    if (!isNew) {
+	Tcl_Obj *oldValuePtr = Tcl_GetHashValue(hPtr);
+
+	TclDecrRefCount(oldValuePtr);
+    }
+    Tcl_SetHashValue(hPtr, valuePtr);
+    dict->epoch++;
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_DictObjGet --
+ *
+ *	Given a key, get its value from the dictionary (or NULL if key is not
+ *	found in dictionary.)
+ *
+ * Results:
+ *	A standard Tcl result. The variable pointed to by valuePtrPtr is
+ *	updated with the value for the key. Note that it is not an error for
+ *	the key to have no mapping in the dictionary.
+ *
+ * Side effects:
+ *	The object pointed to by dictPtr is converted to a dictionary if it is
+ *	not already one.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_DictObjGet(
+    Tcl_Interp *interp,
+    Tcl_Obj *dictPtr,
+    Tcl_Obj *keyPtr,
+    Tcl_Obj **valuePtrPtr)
+{
+    Dict *dict;
+    Tcl_HashEntry *hPtr;
+
+    if (dictPtr->typePtr != &tclDictType
+	    && SetDictFromAny(interp, dictPtr) != TCL_OK) {
+	*valuePtrPtr = NULL;
+	return TCL_ERROR;
+    }
+
+    dict = DICT(dictPtr);
+    hPtr = Tcl_FindHashEntry(&dict->table, keyPtr);
+    if (hPtr == NULL) {
+	*valuePtrPtr = NULL;
+    } else {
+	*valuePtrPtr = Tcl_GetHashValue(hPtr);
+    }
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_DictObjRemove --
+ *
+ *	Remove the key,value pair with the given key from the dictionary; the
+ *	key does not need to be present in the dictionary.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	The object pointed to by dictPtr is converted to a dictionary if it is
+ *	not already one, and any string representation that it has is
+ *	invalidated.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_DictObjRemove(
+    Tcl_Interp *interp,
+    Tcl_Obj *dictPtr,
+    Tcl_Obj *keyPtr)
+{
+    Dict *dict;
+
+    if (Tcl_IsShared(dictPtr)) {
+	Tcl_Panic("%s called with shared object", "Tcl_DictObjRemove");
+    }
+
+    if (dictPtr->typePtr != &tclDictType
+	    && SetDictFromAny(interp, dictPtr) != TCL_OK) {
+	return TCL_ERROR;
+    }
+
+    dict = DICT(dictPtr);
+    if (DeleteChainEntry(dict, keyPtr)) {
+	if (dictPtr->bytes != NULL) {
+	    TclInvalidateStringRep(dictPtr);
+	}
+	dict->epoch++;
+    }
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_DictObjSize --
+ *
+ *	How many key,value pairs are there in the dictionary?
+ *
+ * Results:
+ *	A standard Tcl result. Updates the variable pointed to by sizePtr with
+ *	the number of key,value pairs in the dictionary.
+ *
+ * Side effects:
+ *	The dictPtr object is converted to a dictionary type if it is not a
+ *	dictionary already.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_DictObjSize(
+    Tcl_Interp *interp,
+    Tcl_Obj *dictPtr,
+    int *sizePtr)
+{
+    Dict *dict;
+
+    if (dictPtr->typePtr != &tclDictType
+	    && SetDictFromAny(interp, dictPtr) != TCL_OK) {
+	return TCL_ERROR;
+    }
+
+    dict = DICT(dictPtr);
+    *sizePtr = dict->table.numEntries;
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_DictObjFirst --
+ *
+ *	Start a traversal of the dictionary. Caller must supply the search
+ *	context, pointers for returning key and value, and a pointer to allow
+ *	indication of whether the dictionary has been traversed (i.e. the
+ *	dictionary is empty). The order of traversal is undefined.
+ *
+ * Results:
+ *	A standard Tcl result. Updates the variables pointed to by keyPtrPtr,
+ *	valuePtrPtr and donePtr. Either of keyPtrPtr and valuePtrPtr may be
+ *	NULL, in which case the key/value is not made available to the caller.
+ *
+ * Side effects:
+ *	The dictPtr object is converted to a dictionary type if it is not a
+ *	dictionary already. The search context is initialised if the search
+ *	has not finished. The dictionary's internal rep is Tcl_Preserve()d if
+ *	the dictionary has at least one element.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_DictObjFirst(
+    Tcl_Interp *interp,		/* For error messages, or NULL if no error
+				 * messages desired. */
+    Tcl_Obj *dictPtr,		/* Dictionary to traverse. */
+    Tcl_DictSearch *searchPtr,	/* Pointer to a dict search context. */
+    Tcl_Obj **keyPtrPtr,	/* Pointer to a variable to have the first key
+				 * written into, or NULL. */
+    Tcl_Obj **valuePtrPtr,	/* Pointer to a variable to have the first
+				 * value written into, or NULL.*/
+    int *donePtr)		/* Pointer to a variable which will have a 1
+				 * written into when there are no further
+				 * values in the dictionary, or a 0
+				 * otherwise. */
+{
+    Dict *dict;
+    ChainEntry *cPtr;
+
+    if (dictPtr->typePtr != &tclDictType
+	    && SetDictFromAny(interp, dictPtr) != TCL_OK) {
+	return TCL_ERROR;
+    }
+
+    dict = DICT(dictPtr);
+    cPtr = dict->entryChainHead;
+    if (cPtr == NULL) {
+	searchPtr->epoch = -1;
+	*donePtr = 1;
+    } else {
+	*donePtr = 0;
+	searchPtr->dictionaryPtr = (Tcl_Dict) dict;
+	searchPtr->epoch = dict->epoch;
+	searchPtr->next = cPtr->nextPtr;
+	dict->refcount++;
+	if (keyPtrPtr != NULL) {
+	    *keyPtrPtr = Tcl_GetHashKey(&dict->table, &cPtr->entry);
+	}
+	if (valuePtrPtr != NULL) {
+	    *valuePtrPtr = Tcl_GetHashValue(&cPtr->entry);
+	}
+    }
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_DictObjNext --
+ *
+ *	Continue a traversal of a dictionary previously started with
+ *	Tcl_DictObjFirst. This function is safe against concurrent
+ *	modification of the underlying object (including type shimmering),
+ *	treating such situations as if the search has terminated, though it is
+ *	up to the caller to ensure that the object itself is not disposed
+ *	until the search has finished. It is _not_ safe against modifications
+ *	from other threads.
+ *
+ * Results:
+ *	Updates the variables pointed to by keyPtrPtr, valuePtrPtr and
+ *	donePtr. Either of keyPtrPtr and valuePtrPtr may be NULL, in which
+ *	case the key/value is not made available to the caller.
+ *
+ * Side effects:
+ *	Removes a reference to the dictionary's internal rep if the search
+ *	terminates.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_DictObjNext(
+    Tcl_DictSearch *searchPtr,	/* Pointer to a hash search context. */
+    Tcl_Obj **keyPtrPtr,	/* Pointer to a variable to have the first key
+				 * written into, or NULL. */
+    Tcl_Obj **valuePtrPtr,	/* Pointer to a variable to have the first
+				 * value written into, or NULL.*/
+    int *donePtr)		/* Pointer to a variable which will have a 1
+				 * written into when there are no further
+				 * values in the dictionary, or a 0
+				 * otherwise. */
+{
+    ChainEntry *cPtr;
+
+    /*
+     * If the searh is done; we do no work.
+     */
+
+    if (searchPtr->epoch == -1) {
+	*donePtr = 1;
+	return;
+    }
+
+    /*
+     * Bail out if the dictionary has had any elements added, modified or
+     * removed. This *shouldn't* happen, but...
+     */
+
+    if (((Dict *)searchPtr->dictionaryPtr)->epoch != searchPtr->epoch) {
+	Tcl_Panic("concurrent dictionary modification and search");
+    }
+
+    cPtr = searchPtr->next;
+    if (cPtr == NULL) {
+	Tcl_DictObjDone(searchPtr);
+	*donePtr = 1;
+	return;
+    }
+
+    searchPtr->next = cPtr->nextPtr;
+    *donePtr = 0;
+    if (keyPtrPtr != NULL) {
+	*keyPtrPtr = Tcl_GetHashKey(
+		&((Dict *)searchPtr->dictionaryPtr)->table, &cPtr->entry);
+    }
+    if (valuePtrPtr != NULL) {
+	*valuePtrPtr = Tcl_GetHashValue(&cPtr->entry);
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_DictObjDone --
+ *
+ *	Call this if you want to stop a search before you reach the end of the
+ *	dictionary (e.g. because of abnormal termination of the search). It
+ *	need not be used if the search reaches its natural end (i.e. if either
+ *	Tcl_DictObjFirst or Tcl_DictObjNext sets its donePtr variable to 1).
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Removes a reference to the dictionary's internal rep.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_DictObjDone(
+    Tcl_DictSearch *searchPtr)		/* Pointer to a hash search context. */
+{
+    Dict *dict;
+
+    if (searchPtr->epoch != -1) {
+	searchPtr->epoch = -1;
+	dict = (Dict *) searchPtr->dictionaryPtr;
+	dict->refcount--;
+	if (dict->refcount <= 0) {
+	    DeleteDict(dict);
+	}
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_DictObjPutKeyList --
+ *
+ *	Add a key...key,value pair to a dictionary tree. The main dictionary
+ *	value must not be shared, though sub-dictionaries may be. All
+ *	intermediate dictionaries on the path must exist.
+ *
+ * Results:
+ *	A standard Tcl result. Note that in the error case, a message is left
+ *	in interp unless that is NULL.
+ *
+ * Side effects:
+ *	If the dictionary and any of its sub-dictionaries on the path have
+ *	string representations, these are invalidated.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_DictObjPutKeyList(
+    Tcl_Interp *interp,
+    Tcl_Obj *dictPtr,
+    int keyc,
+    Tcl_Obj *const keyv[],
+    Tcl_Obj *valuePtr)
+{
+    Dict *dict;
+    Tcl_HashEntry *hPtr;
+    int isNew;
+
+    if (Tcl_IsShared(dictPtr)) {
+	Tcl_Panic("%s called with shared object", "Tcl_DictObjPutKeyList");
+    }
+    if (keyc < 1) {
+	Tcl_Panic("%s called with empty key list", "Tcl_DictObjPutKeyList");
+    }
+
+    dictPtr = TclTraceDictPath(interp, dictPtr, keyc-1,keyv, DICT_PATH_CREATE);
+    if (dictPtr == NULL) {
+	return TCL_ERROR;
+    }
+
+    dict = DICT(dictPtr);
+    hPtr = CreateChainEntry(dict, keyv[keyc-1], &isNew);
+    Tcl_IncrRefCount(valuePtr);
+    if (!isNew) {
+	Tcl_Obj *oldValuePtr = Tcl_GetHashValue(hPtr);
+
+	TclDecrRefCount(oldValuePtr);
+    }
+    Tcl_SetHashValue(hPtr, valuePtr);
+    InvalidateDictChain(dictPtr);
+
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_DictObjRemoveKeyList --
+ *
+ *	Remove a key...key,value pair from a dictionary tree (the value
+ *	removed is implicit in the key path). The main dictionary value must
+ *	not be shared, though sub-dictionaries may be. It is not an error if
+ *	there is no value associated with the given key list, but all
+ *	intermediate dictionaries on the key path must exist.
+ *
+ * Results:
+ *	A standard Tcl result. Note that in the error case, a message is left
+ *	in interp unless that is NULL.
+ *
+ * Side effects:
+ *	If the dictionary and any of its sub-dictionaries on the key path have
+ *	string representations, these are invalidated.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_DictObjRemoveKeyList(
+    Tcl_Interp *interp,
+    Tcl_Obj *dictPtr,
+    int keyc,
+    Tcl_Obj *const keyv[])
+{
+    Dict *dict;
+
+    if (Tcl_IsShared(dictPtr)) {
+	Tcl_Panic("%s called with shared object", "Tcl_DictObjRemoveKeyList");
+    }
+    if (keyc < 1) {
+	Tcl_Panic("%s called with empty key list", "Tcl_DictObjRemoveKeyList");
+    }
+
+    dictPtr = TclTraceDictPath(interp, dictPtr, keyc-1,keyv, DICT_PATH_UPDATE);
+    if (dictPtr == NULL) {
+	return TCL_ERROR;
+    }
+
+    dict = DICT(dictPtr);
+    DeleteChainEntry(dict, keyv[keyc-1]);
+    InvalidateDictChain(dictPtr);
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_NewDictObj --
+ *
+ *	This function is normally called when not debugging: i.e., when
+ *	TCL_MEM_DEBUG is not defined. It creates a new dict object without any
+ *	content.
+ *
+ *	When TCL_MEM_DEBUG is defined, this function just returns the result
+ *	of calling the debugging version Tcl_DbNewDictObj.
+ *
+ * Results:
+ *	A new dict object is returned; it has no keys defined in it. The new
+ *	object's string representation is left NULL, and the ref count of the
+ *	object is 0.
+ *
+ * Side Effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_Obj *
+Tcl_NewDictObj(void)
+{
+#ifdef TCL_MEM_DEBUG
+    return Tcl_DbNewDictObj("unknown", 0);
+#else /* !TCL_MEM_DEBUG */
+
+    Tcl_Obj *dictPtr;
+    Dict *dict;
+
+    TclNewObj(dictPtr);
+    TclInvalidateStringRep(dictPtr);
+    dict = ckalloc(sizeof(Dict));
+    InitChainTable(dict);
+    dict->epoch = 0;
+    dict->chain = NULL;
+    dict->refcount = 1;
+    DICT(dictPtr) = dict;
+    dictPtr->internalRep.twoPtrValue.ptr2 = NULL;
+    dictPtr->typePtr = &tclDictType;
+    return dictPtr;
+#endif
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_DbNewDictObj --
+ *
+ *	This function is normally called when debugging: i.e., when
+ *	TCL_MEM_DEBUG is defined. It creates new dict objects. It is the same
+ *	as the Tcl_NewDictObj function above except that it calls
+ *	Tcl_DbCkalloc directly with the file name and line number from its
+ *	caller. This simplifies debugging since then the [memory active]
+ *	command will report the correct file name and line number when
+ *	reporting objects that haven't been freed.
+ *
+ *	When TCL_MEM_DEBUG is not defined, this function just returns the
+ *	result of calling Tcl_NewDictObj.
+ *
+ * Results:
+ *	A new dict object is returned; it has no keys defined in it. The new
+ *	object's string representation is left NULL, and the ref count of the
+ *	object is 0.
+ *
+ * Side Effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_Obj *
+Tcl_DbNewDictObj(
+    const char *file,
+    int line)
+{
+#ifdef TCL_MEM_DEBUG
+    Tcl_Obj *dictPtr;
+    Dict *dict;
+
+    TclDbNewObj(dictPtr, file, line);
+    TclInvalidateStringRep(dictPtr);
+    dict = ckalloc(sizeof(Dict));
+    InitChainTable(dict);
+    dict->epoch = 0;
+    dict->chain = NULL;
+    dict->refcount = 1;
+    DICT(dictPtr) = dict;
+    dictPtr->internalRep.twoPtrValue.ptr2 = NULL;
+    dictPtr->typePtr = &tclDictType;
+    return dictPtr;
+#else /* !TCL_MEM_DEBUG */
+    return Tcl_NewDictObj();
+#endif
+}
+
+/***** START OF FUNCTIONS IMPLEMENTING TCL COMMANDS *****/
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * DictCreateCmd --
+ *
+ *	This function implements the "dict create" Tcl command. See the user
+ *	documentation for details on what it does, and TIP#111 for the formal
+ *	specification.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+DictCreateCmd(
+    ClientData dummy,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const *objv)
+{
+    Tcl_Obj *dictObj;
+    int i;
+
+    /*
+     * Must have an even number of arguments; note that number of preceding
+     * arguments (i.e. "dict create" is also even, which makes this much
+     * easier.)
+     */
+
+    if ((objc & 1) == 0) {
+	Tcl_WrongNumArgs(interp, 1, objv, "?key value ...?");
+	return TCL_ERROR;
+    }
+
+    dictObj = Tcl_NewDictObj();
+    for (i=1 ; i<objc ; i+=2) {
+	/*
+	 * The next command is assumed to never fail...
+	 */
+	Tcl_DictObjPut(NULL, dictObj, objv[i], objv[i+1]);
+    }
+    Tcl_SetObjResult(interp, dictObj);
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * DictGetCmd --
+ *
+ *	This function implements the "dict get" Tcl command. See the user
+ *	documentation for details on what it does, and TIP#111 for the formal
+ *	specification.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+DictGetCmd(
+    ClientData dummy,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const *objv)
+{
+    Tcl_Obj *dictPtr, *valuePtr = NULL;
+    int result;
+
+    if (objc < 2) {
+	Tcl_WrongNumArgs(interp, 1, objv, "dictionary ?key ...?");
+	return TCL_ERROR;
+    }
+
+    /*
+     * Test for the special case of no keys, which returns a *list* of all
+     * key,value pairs. We produce a copy here because that makes subsequent
+     * list handling more efficient.
+     */
+
+    if (objc == 2) {
+	Tcl_Obj *keyPtr = NULL, *listPtr;
+	Tcl_DictSearch search;
+	int done;
+
+	result = Tcl_DictObjFirst(interp, objv[1], &search,
+		&keyPtr, &valuePtr, &done);
+	if (result != TCL_OK) {
+	    return result;
+	}
+	listPtr = Tcl_NewListObj(0, NULL);
+	while (!done) {
+	    /*
+	     * Assume these won't fail as we have complete control over the
+	     * types of things here.
+	     */
+
+	    Tcl_ListObjAppendElement(interp, listPtr, keyPtr);
+	    Tcl_ListObjAppendElement(interp, listPtr, valuePtr);
+
+	    Tcl_DictObjNext(&search, &keyPtr, &valuePtr, &done);
+	}
+	Tcl_SetObjResult(interp, listPtr);
+	return TCL_OK;
+    }
+
+    /*
+     * Loop through the list of keys, looking up the key at the current index
+     * in the current dictionary each time. Once we've done the lookup, we set
+     * the current dictionary to be the value we looked up (in case the value
+     * was not the last one and we are going through a chain of searches.)
+     * Note that this loop always executes at least once.
+     */
+
+    dictPtr = TclTraceDictPath(interp, objv[1], objc-3,objv+2, DICT_PATH_READ);
+    if (dictPtr == NULL) {
+	return TCL_ERROR;
+    }
+    result = Tcl_DictObjGet(interp, dictPtr, objv[objc-1], &valuePtr);
+    if (result != TCL_OK) {
+	return result;
+    }
+    if (valuePtr == NULL) {
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		"key \"%s\" not known in dictionary",
+		TclGetString(objv[objc-1])));
+	Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "DICT",
+		TclGetString(objv[objc-1]), NULL);
+	return TCL_ERROR;
+    }
+    Tcl_SetObjResult(interp, valuePtr);
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * DictReplaceCmd --
+ *
+ *	This function implements the "dict replace" Tcl command. See the user
+ *	documentation for details on what it does, and TIP#111 for the formal
+ *	specification.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+DictReplaceCmd(
+    ClientData dummy,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const *objv)
+{
+    Tcl_Obj *dictPtr;
+    int i;
+
+    if ((objc < 2) || (objc & 1)) {
+	Tcl_WrongNumArgs(interp, 1, objv, "dictionary ?key value ...?");
+	return TCL_ERROR;
+    }
+
+    dictPtr = objv[1];
+    if (dictPtr->typePtr != &tclDictType
+	    && SetDictFromAny(interp, dictPtr) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    if (Tcl_IsShared(dictPtr)) {
+	dictPtr = Tcl_DuplicateObj(dictPtr);
+    }
+    if (dictPtr->bytes != NULL) {
+	TclInvalidateStringRep(dictPtr);
+    }
+    for (i=2 ; i<objc ; i+=2) {
+	Tcl_DictObjPut(NULL, dictPtr, objv[i], objv[i+1]);
+    }
+    Tcl_SetObjResult(interp, dictPtr);
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * DictRemoveCmd --
+ *
+ *	This function implements the "dict remove" Tcl command. See the user
+ *	documentation for details on what it does, and TIP#111 for the formal
+ *	specification.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+DictRemoveCmd(
+    ClientData dummy,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const *objv)
+{
+    Tcl_Obj *dictPtr;
+    int i;
+
+    if (objc < 2) {
+	Tcl_WrongNumArgs(interp, 1, objv, "dictionary ?key ...?");
+	return TCL_ERROR;
+    }
+
+    dictPtr = objv[1];
+    if (dictPtr->typePtr != &tclDictType
+	    && SetDictFromAny(interp, dictPtr) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    if (Tcl_IsShared(dictPtr)) {
+	dictPtr = Tcl_DuplicateObj(dictPtr);
+    }
+    if (dictPtr->bytes != NULL) {
+	TclInvalidateStringRep(dictPtr);
+    }
+    for (i=2 ; i<objc ; i++) {
+	Tcl_DictObjRemove(NULL, dictPtr, objv[i]);
+    }
+    Tcl_SetObjResult(interp, dictPtr);
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * DictMergeCmd --
+ *
+ *	This function implements the "dict merge" Tcl command. See the user
+ *	documentation for details on what it does, and TIP#163 for the formal
+ *	specification.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+DictMergeCmd(
+    ClientData dummy,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const *objv)
+{
+    Tcl_Obj *targetObj, *keyObj = NULL, *valueObj = NULL;
+    int allocatedDict = 0;
+    int i, done;
+    Tcl_DictSearch search;
+
+    if (objc == 1) {
+	/*
+	 * No dictionary arguments; return default (empty value).
+	 */
+
+	return TCL_OK;
+    }
+
+    /*
+     * Make sure first argument is a dictionary.
+     */
+
+    targetObj = objv[1];
+    if (targetObj->typePtr != &tclDictType
+	    && SetDictFromAny(interp, targetObj) != TCL_OK) {
+	return TCL_ERROR;
+    }
+
+    if (objc == 2) {
+	/*
+	 * Single argument, return it.
+	 */
+
+	Tcl_SetObjResult(interp, objv[1]);
+	return TCL_OK;
+    }
+
+    /*
+     * Normal behaviour: combining two (or more) dictionaries.
+     */
+
+    if (Tcl_IsShared(targetObj)) {
+	targetObj = Tcl_DuplicateObj(targetObj);
+	allocatedDict = 1;
+    }
+    for (i=2 ; i<objc ; i++) {
+	if (Tcl_DictObjFirst(interp, objv[i], &search, &keyObj, &valueObj,
+		&done) != TCL_OK) {
+	    if (allocatedDict) {
+		TclDecrRefCount(targetObj);
+	    }
+	    return TCL_ERROR;
+	}
+	while (!done) {
+	    /*
+	     * Next line can't fail; already know we have a dictionary in
+	     * targetObj.
+	     */
+
+	    Tcl_DictObjPut(NULL, targetObj, keyObj, valueObj);
+	    Tcl_DictObjNext(&search, &keyObj, &valueObj, &done);
+	}
+	Tcl_DictObjDone(&search);
+    }
+    Tcl_SetObjResult(interp, targetObj);
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * DictKeysCmd --
+ *
+ *	This function implements the "dict keys" Tcl command. See the user
+ *	documentation for details on what it does, and TIP#111 for the formal
+ *	specification.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+DictKeysCmd(
+    ClientData dummy,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const *objv)
+{
+    Tcl_Obj *listPtr;
+    const char *pattern = NULL;
+
+    if (objc!=2 && objc!=3) {
+	Tcl_WrongNumArgs(interp, 1, objv, "dictionary ?pattern?");
+	return TCL_ERROR;
+    }
+
+    /*
+     * A direct check that we have a dictionary. We don't start the iteration
+     * yet because that might allocate memory or set locks that we do not
+     * need. [Bug 1705778, leak K04]
+     */
+
+    if (objv[1]->typePtr != &tclDictType
+	    && SetDictFromAny(interp, objv[1]) != TCL_OK) {
+	return TCL_ERROR;
+    }
+
+    if (objc == 3) {
+	pattern = TclGetString(objv[2]);
+    }
+    listPtr = Tcl_NewListObj(0, NULL);
+    if ((pattern != NULL) && TclMatchIsTrivial(pattern)) {
+	Tcl_Obj *valuePtr = NULL;
+
+	Tcl_DictObjGet(interp, objv[1], objv[2], &valuePtr);
+	if (valuePtr != NULL) {
+	    Tcl_ListObjAppendElement(NULL, listPtr, objv[2]);
+	}
+    } else {
+	Tcl_DictSearch search;
+	Tcl_Obj *keyPtr = NULL;
+	int done = 0;
+
+	/*
+	 * At this point, we know we have a dictionary (or at least something
+	 * that can be represented; it could theoretically have shimmered away
+	 * when the pattern was fetched, but that shouldn't be damaging) so we
+	 * can start the iteration process without checking for failures.
+	 */
+
+	Tcl_DictObjFirst(NULL, objv[1], &search, &keyPtr, NULL, &done);
+	for (; !done ; Tcl_DictObjNext(&search, &keyPtr, NULL, &done)) {
+	    if (!pattern || Tcl_StringMatch(TclGetString(keyPtr), pattern)) {
+		Tcl_ListObjAppendElement(NULL, listPtr, keyPtr);
+	    }
+	}
+	Tcl_DictObjDone(&search);
+    }
+
+    Tcl_SetObjResult(interp, listPtr);
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * DictValuesCmd --
+ *
+ *	This function implements the "dict values" Tcl command. See the user
+ *	documentation for details on what it does, and TIP#111 for the formal
+ *	specification.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+DictValuesCmd(
+    ClientData dummy,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const *objv)
+{
+    Tcl_Obj *valuePtr = NULL, *listPtr;
+    Tcl_DictSearch search;
+    int done;
+    const char *pattern;
+
+    if (objc!=2 && objc!=3) {
+	Tcl_WrongNumArgs(interp, 1, objv, "dictionary ?pattern?");
+	return TCL_ERROR;
+    }
+
+    if (Tcl_DictObjFirst(interp, objv[1], &search, NULL, &valuePtr,
+	    &done) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    if (objc == 3) {
+	pattern = TclGetString(objv[2]);
+    } else {
+	pattern = NULL;
+    }
+    listPtr = Tcl_NewListObj(0, NULL);
+    for (; !done ; Tcl_DictObjNext(&search, NULL, &valuePtr, &done)) {
+	if (pattern==NULL || Tcl_StringMatch(TclGetString(valuePtr),pattern)) {
+	    /*
+	     * Assume this operation always succeeds.
+	     */
+
+	    Tcl_ListObjAppendElement(interp, listPtr, valuePtr);
+	}
+    }
+    Tcl_DictObjDone(&search);
+
+    Tcl_SetObjResult(interp, listPtr);
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * DictSizeCmd --
+ *
+ *	This function implements the "dict size" Tcl command. See the user
+ *	documentation for details on what it does, and TIP#111 for the formal
+ *	specification.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+DictSizeCmd(
+    ClientData dummy,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const *objv)
+{
+    int result, size;
+
+    if (objc != 2) {
+	Tcl_WrongNumArgs(interp, 1, objv, "dictionary");
+	return TCL_ERROR;
+    }
+    result = Tcl_DictObjSize(interp, objv[1], &size);
+    if (result == TCL_OK) {
+	Tcl_SetObjResult(interp, Tcl_NewIntObj(size));
+    }
+    return result;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * DictExistsCmd --
+ *
+ *	This function implements the "dict exists" Tcl command. See the user
+ *	documentation for details on what it does, and TIP#111 for the formal
+ *	specification.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+DictExistsCmd(
+    ClientData dummy,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const *objv)
+{
+    Tcl_Obj *dictPtr, *valuePtr;
+
+    if (objc < 3) {
+	Tcl_WrongNumArgs(interp, 1, objv, "dictionary key ?key ...?");
+	return TCL_ERROR;
+    }
+
+    dictPtr = TclTraceDictPath(interp, objv[1], objc-3, objv+2,
+	    DICT_PATH_EXISTS);
+    if (dictPtr == NULL || dictPtr == DICT_PATH_NON_EXISTENT
+	    || Tcl_DictObjGet(interp, dictPtr, objv[objc-1],
+		    &valuePtr) != TCL_OK) {
+	Tcl_SetObjResult(interp, Tcl_NewBooleanObj(0));
+    } else {
+	Tcl_SetObjResult(interp, Tcl_NewBooleanObj(valuePtr != NULL));
+    }
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * DictInfoCmd --
+ *
+ *	This function implements the "dict info" Tcl command. See the user
+ *	documentation for details on what it does, and TIP#111 for the formal
+ *	specification.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+DictInfoCmd(
+    ClientData dummy,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const *objv)
+{
+    Tcl_Obj *dictPtr;
+    Dict *dict;
+    char *statsStr;
+
+    if (objc != 2) {
+	Tcl_WrongNumArgs(interp, 1, objv, "dictionary");
+	return TCL_ERROR;
+    }
+
+    dictPtr = objv[1];
+    if (dictPtr->typePtr != &tclDictType
+	    && SetDictFromAny(interp, dictPtr) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    dict = DICT(dictPtr);
+
+    statsStr = Tcl_HashStats(&dict->table);
+    Tcl_SetObjResult(interp, Tcl_NewStringObj(statsStr, -1));
+    ckfree(statsStr);
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * DictIncrCmd --
+ *
+ *	This function implements the "dict incr" Tcl command. See the user
+ *	documentation for details on what it does, and TIP#111 for the formal
+ *	specification.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+DictIncrCmd(
+    ClientData dummy,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const *objv)
+{
+    int code = TCL_OK;
+    Tcl_Obj *dictPtr, *valuePtr = NULL;
+
+    if (objc < 3 || objc > 4) {
+	Tcl_WrongNumArgs(interp, 1, objv, "dictVarName key ?increment?");
+	return TCL_ERROR;
+    }
+
+    dictPtr = Tcl_ObjGetVar2(interp, objv[1], NULL, 0);
+    if (dictPtr == NULL) {
+	/*
+	 * Variable didn't yet exist. Create new dictionary value.
+	 */
+
+	dictPtr = Tcl_NewDictObj();
+    } else if (Tcl_DictObjGet(interp, dictPtr, objv[2], &valuePtr) != TCL_OK) {
+	/*
+	 * Variable contents are not a dict, report error.
+	 */
+
+	return TCL_ERROR;
+    }
+    if (Tcl_IsShared(dictPtr)) {
+	/*
+	 * A little internals surgery to avoid copying a string rep that will
+	 * soon be no good.
+	 */
+
+	char *saved = dictPtr->bytes;
+	Tcl_Obj *oldPtr = dictPtr;
+
+	dictPtr->bytes = NULL;
+	dictPtr = Tcl_DuplicateObj(dictPtr);
+	oldPtr->bytes = saved;
+    }
+    if (valuePtr == NULL) {
+	/*
+	 * Key not in dictionary. Create new key with increment as value.
+	 */
+
+	if (objc == 4) {
+	    /*
+	     * Verify increment is an integer.
+	     */
+
+	    mp_int increment;
+
+	    code = Tcl_GetBignumFromObj(interp, objv[3], &increment);
+	    if (code != TCL_OK) {
+		Tcl_AddErrorInfo(interp, "\n    (reading increment)");
+	    } else {
+		/*
+		 * Remember to dispose with the bignum as we're not actually
+		 * using it directly. [Bug 2874678]
+		 */
+
+		mp_clear(&increment);
+		Tcl_DictObjPut(NULL, dictPtr, objv[2], objv[3]);
+	    }
+	} else {
+	    Tcl_DictObjPut(NULL, dictPtr, objv[2], Tcl_NewIntObj(1));
+	}
+    } else {
+	/*
+	 * Key in dictionary. Increment its value with minimum dup.
+	 */
+
+	if (Tcl_IsShared(valuePtr)) {
+	    valuePtr = Tcl_DuplicateObj(valuePtr);
+	    Tcl_DictObjPut(NULL, dictPtr, objv[2], valuePtr);
+	}
+	if (objc == 4) {
+	    code = TclIncrObj(interp, valuePtr, objv[3]);
+	} else {
+	    Tcl_Obj *incrPtr = Tcl_NewIntObj(1);
+
+	    Tcl_IncrRefCount(incrPtr);
+	    code = TclIncrObj(interp, valuePtr, incrPtr);
+	    TclDecrRefCount(incrPtr);
+	}
+    }
+    if (code == TCL_OK) {
+	TclInvalidateStringRep(dictPtr);
+	valuePtr = Tcl_ObjSetVar2(interp, objv[1], NULL,
+		dictPtr, TCL_LEAVE_ERR_MSG);
+	if (valuePtr == NULL) {
+	    code = TCL_ERROR;
+	} else {
+	    Tcl_SetObjResult(interp, valuePtr);
+	}
+    } else if (dictPtr->refCount == 0) {
+	TclDecrRefCount(dictPtr);
+    }
+    return code;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * DictLappendCmd --
+ *
+ *	This function implements the "dict lappend" Tcl command. See the user
+ *	documentation for details on what it does, and TIP#111 for the formal
+ *	specification.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+DictLappendCmd(
+    ClientData dummy,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const *objv)
+{
+    Tcl_Obj *dictPtr, *valuePtr, *resultPtr;
+    int i, allocatedDict = 0, allocatedValue = 0;
+
+    if (objc < 3) {
+	Tcl_WrongNumArgs(interp, 1, objv, "dictVarName key ?value ...?");
+	return TCL_ERROR;
+    }
+
+    dictPtr = Tcl_ObjGetVar2(interp, objv[1], NULL, 0);
+    if (dictPtr == NULL) {
+	allocatedDict = 1;
+	dictPtr = Tcl_NewDictObj();
+    } else if (Tcl_IsShared(dictPtr)) {
+	allocatedDict = 1;
+	dictPtr = Tcl_DuplicateObj(dictPtr);
+    }
+
+    if (Tcl_DictObjGet(interp, dictPtr, objv[2], &valuePtr) != TCL_OK) {
+	if (allocatedDict) {
+	    TclDecrRefCount(dictPtr);
+	}
+	return TCL_ERROR;
+    }
+
+    if (valuePtr == NULL) {
+	valuePtr = Tcl_NewListObj(objc-3, objv+3);
+	allocatedValue = 1;
+    } else {
+	if (Tcl_IsShared(valuePtr)) {
+	    allocatedValue = 1;
+	    valuePtr = Tcl_DuplicateObj(valuePtr);
+	}
+
+	for (i=3 ; i<objc ; i++) {
+	    if (Tcl_ListObjAppendElement(interp, valuePtr,
+		    objv[i]) != TCL_OK) {
+		if (allocatedValue) {
+		    TclDecrRefCount(valuePtr);
+		}
+		if (allocatedDict) {
+		    TclDecrRefCount(dictPtr);
+		}
+		return TCL_ERROR;
+	    }
+	}
+    }
+
+    if (allocatedValue) {
+	Tcl_DictObjPut(NULL, dictPtr, objv[2], valuePtr);
+    } else if (dictPtr->bytes != NULL) {
+	TclInvalidateStringRep(dictPtr);
+    }
+
+    resultPtr = Tcl_ObjSetVar2(interp, objv[1], NULL, dictPtr,
+	    TCL_LEAVE_ERR_MSG);
+    if (resultPtr == NULL) {
+	return TCL_ERROR;
+    }
+    Tcl_SetObjResult(interp, resultPtr);
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * DictAppendCmd --
+ *
+ *	This function implements the "dict append" Tcl command. See the user
+ *	documentation for details on what it does, and TIP#111 for the formal
+ *	specification.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+DictAppendCmd(
+    ClientData dummy,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const *objv)
+{
+    Tcl_Obj *dictPtr, *valuePtr, *resultPtr;
+    int i, allocatedDict = 0;
+
+    if (objc < 3) {
+	Tcl_WrongNumArgs(interp, 1, objv, "dictVarName key ?value ...?");
+	return TCL_ERROR;
+    }
+
+    dictPtr = Tcl_ObjGetVar2(interp, objv[1], NULL, 0);
+    if (dictPtr == NULL) {
+	allocatedDict = 1;
+	dictPtr = Tcl_NewDictObj();
+    } else if (Tcl_IsShared(dictPtr)) {
+	allocatedDict = 1;
+	dictPtr = Tcl_DuplicateObj(dictPtr);
+    }
+
+    if (Tcl_DictObjGet(interp, dictPtr, objv[2], &valuePtr) != TCL_OK) {
+	if (allocatedDict) {
+	    TclDecrRefCount(dictPtr);
+	}
+	return TCL_ERROR;
+    }
+
+    if (valuePtr == NULL) {
+	TclNewObj(valuePtr);
+    } else if (Tcl_IsShared(valuePtr)) {
+	valuePtr = Tcl_DuplicateObj(valuePtr);
+    }
+
+    for (i=3 ; i<objc ; i++) {
+	Tcl_AppendObjToObj(valuePtr, objv[i]);
+    }
+
+    Tcl_DictObjPut(NULL, dictPtr, objv[2], valuePtr);
+
+    resultPtr = Tcl_ObjSetVar2(interp, objv[1], NULL, dictPtr,
+	    TCL_LEAVE_ERR_MSG);
+    if (resultPtr == NULL) {
+	return TCL_ERROR;
+    }
+    Tcl_SetObjResult(interp, resultPtr);
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * DictForNRCmd --
+ *
+ *	These functions implement the "dict for" Tcl command.  See the user
+ *	documentation for details on what it does, and TIP#111 for the formal
+ *	specification.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+DictForNRCmd(
+    ClientData dummy,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const *objv)
+{
+    Interp *iPtr = (Interp *) interp;
+    Tcl_Obj *scriptObj, *keyVarObj, *valueVarObj;
+    Tcl_Obj **varv, *keyObj, *valueObj;
+    Tcl_DictSearch *searchPtr;
+    int varc, done;
+
+    if (objc != 4) {
+	Tcl_WrongNumArgs(interp, 1, objv,
+		"{keyVarName valueVarName} dictionary script");
+	return TCL_ERROR;
+    }
+
+    /*
+     * Parse arguments.
+     */
+
+    if (TclListObjGetElements(interp, objv[1], &varc, &varv) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    if (varc != 2) {
+	Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		"must have exactly two variable names", -1));
+	Tcl_SetErrorCode(interp, "TCL", "SYNTAX", "dict", "for", NULL);
+	return TCL_ERROR;
+    }
+    searchPtr = TclStackAlloc(interp, sizeof(Tcl_DictSearch));
+    if (Tcl_DictObjFirst(interp, objv[2], searchPtr, &keyObj, &valueObj,
+	    &done) != TCL_OK) {
+	TclStackFree(interp, searchPtr);
+	return TCL_ERROR;
+    }
+    if (done) {
+	TclStackFree(interp, searchPtr);
+	return TCL_OK;
+    }
+    TclListObjGetElements(NULL, objv[1], &varc, &varv);
+    keyVarObj = varv[0];
+    valueVarObj = varv[1];
+    scriptObj = objv[3];
+
+    /*
+     * Make sure that these objects (which we need throughout the body of the
+     * loop) don't vanish. Note that the dictionary internal rep is locked
+     * internally so that updates, shimmering, etc are not a problem.
+     */
+
+    Tcl_IncrRefCount(keyVarObj);
+    Tcl_IncrRefCount(valueVarObj);
+    Tcl_IncrRefCount(scriptObj);
+
+    /*
+     * Stop the value from getting hit in any way by any traces on the key
+     * variable.
+     */
+
+    Tcl_IncrRefCount(valueObj);
+    if (Tcl_ObjSetVar2(interp, keyVarObj, NULL, keyObj,
+	    TCL_LEAVE_ERR_MSG) == NULL) {
+	TclDecrRefCount(valueObj);
+	goto error;
+    }
+    TclDecrRefCount(valueObj);
+    if (Tcl_ObjSetVar2(interp, valueVarObj, NULL, valueObj,
+	    TCL_LEAVE_ERR_MSG) == NULL) {
+	goto error;
+    }
+
+    /*
+     * Run the script.
+     */
+
+    TclNRAddCallback(interp, DictForLoopCallback, searchPtr, keyVarObj,
+	    valueVarObj, scriptObj);
+    return TclNREvalObjEx(interp, scriptObj, 0, iPtr->cmdFramePtr, 3);
+
+    /*
+     * For unwinding everything on error.
+     */
+
+  error:
+    TclDecrRefCount(keyVarObj);
+    TclDecrRefCount(valueVarObj);
+    TclDecrRefCount(scriptObj);
+    Tcl_DictObjDone(searchPtr);
+    TclStackFree(interp, searchPtr);
+    return TCL_ERROR;
+}
+
+static int
+DictForLoopCallback(
+    ClientData data[],
+    Tcl_Interp *interp,
+    int result)
+{
+    Interp *iPtr = (Interp *) interp;
+    Tcl_DictSearch *searchPtr = data[0];
+    Tcl_Obj *keyVarObj = data[1];
+    Tcl_Obj *valueVarObj = data[2];
+    Tcl_Obj *scriptObj = data[3];
+    Tcl_Obj *keyObj, *valueObj;
+    int done;
+
+    /*
+     * Process the result from the previous execution of the script body.
+     */
+
+    if (result == TCL_CONTINUE) {
+	result = TCL_OK;
+    } else if (result != TCL_OK) {
+	if (result == TCL_BREAK) {
+	    Tcl_ResetResult(interp);
+	    result = TCL_OK;
+	} else if (result == TCL_ERROR) {
+	    Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf(
+		    "\n    (\"dict for\" body line %d)",
+		    Tcl_GetErrorLine(interp)));
+	}
+	goto done;
+    }
+
+    /*
+     * Get the next mapping from the dictionary.
+     */
+
+    Tcl_DictObjNext(searchPtr, &keyObj, &valueObj, &done);
+    if (done) {
+	Tcl_ResetResult(interp);
+	goto done;
+    }
+
+    /*
+     * Stop the value from getting hit in any way by any traces on the key
+     * variable.
+     */
+
+    Tcl_IncrRefCount(valueObj);
+    if (Tcl_ObjSetVar2(interp, keyVarObj, NULL, keyObj,
+	    TCL_LEAVE_ERR_MSG) == NULL) {
+	TclDecrRefCount(valueObj);
+	result = TCL_ERROR;
+	goto done;
+    }
+    TclDecrRefCount(valueObj);
+    if (Tcl_ObjSetVar2(interp, valueVarObj, NULL, valueObj,
+	    TCL_LEAVE_ERR_MSG) == NULL) {
+	result = TCL_ERROR;
+	goto done;
+    }
+
+    /*
+     * Run the script.
+     */
+
+    TclNRAddCallback(interp, DictForLoopCallback, searchPtr, keyVarObj,
+	    valueVarObj, scriptObj);
+    return TclNREvalObjEx(interp, scriptObj, 0, iPtr->cmdFramePtr, 3);
+
+    /*
+     * For unwinding everything once the iterating is done.
+     */
+
+  done:
+    TclDecrRefCount(keyVarObj);
+    TclDecrRefCount(valueVarObj);
+    TclDecrRefCount(scriptObj);
+    Tcl_DictObjDone(searchPtr);
+    TclStackFree(interp, searchPtr);
+    return result;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * DictMapNRCmd --
+ *
+ *	These functions implement the "dict map" Tcl command.  See the user
+ *	documentation for details on what it does, and TIP#405 for the formal
+ *	specification.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+DictMapNRCmd(
+    ClientData dummy,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const *objv)
+{
+    Interp *iPtr = (Interp *) interp;
+    Tcl_Obj **varv, *keyObj, *valueObj;
+    DictMapStorage *storagePtr;
+    int varc, done;
+
+    if (objc != 4) {
+	Tcl_WrongNumArgs(interp, 1, objv,
+		"{keyVarName valueVarName} dictionary script");
+	return TCL_ERROR;
+    }
+
+    /*
+     * Parse arguments.
+     */
+
+    if (TclListObjGetElements(interp, objv[1], &varc, &varv) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    if (varc != 2) {
+	Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		"must have exactly two variable names", -1));
+	Tcl_SetErrorCode(interp, "TCL", "SYNTAX", "dict", "map", NULL);
+	return TCL_ERROR;
+    }
+    storagePtr = TclStackAlloc(interp, sizeof(DictMapStorage));
+    if (Tcl_DictObjFirst(interp, objv[2], &storagePtr->search, &keyObj,
+	    &valueObj, &done) != TCL_OK) {
+	TclStackFree(interp, storagePtr);
+	return TCL_ERROR;
+    }
+    if (done) {
+	/*
+	 * Note that this exit leaves an empty value in the result (due to
+	 * command calling conventions) but that is OK since an empty value is
+	 * an empty dictionary.
+	 */
+
+	TclStackFree(interp, storagePtr);
+	return TCL_OK;
+    }
+    TclNewObj(storagePtr->accumulatorObj);
+    TclListObjGetElements(NULL, objv[1], &varc, &varv);
+    storagePtr->keyVarObj = varv[0];
+    storagePtr->valueVarObj = varv[1];
+    storagePtr->scriptObj = objv[3];
+
+    /*
+     * Make sure that these objects (which we need throughout the body of the
+     * loop) don't vanish. Note that the dictionary internal rep is locked
+     * internally so that updates, shimmering, etc are not a problem.
+     */
+
+    Tcl_IncrRefCount(storagePtr->accumulatorObj);
+    Tcl_IncrRefCount(storagePtr->keyVarObj);
+    Tcl_IncrRefCount(storagePtr->valueVarObj);
+    Tcl_IncrRefCount(storagePtr->scriptObj);
+
+    /*
+     * Stop the value from getting hit in any way by any traces on the key
+     * variable.
+     */
+
+    Tcl_IncrRefCount(valueObj);
+    if (Tcl_ObjSetVar2(interp, storagePtr->keyVarObj, NULL, keyObj,
+	    TCL_LEAVE_ERR_MSG) == NULL) {
+	TclDecrRefCount(valueObj);
+	goto error;
+    }
+    if (Tcl_ObjSetVar2(interp, storagePtr->valueVarObj, NULL, valueObj,
+	    TCL_LEAVE_ERR_MSG) == NULL) {
+	TclDecrRefCount(valueObj);
+	goto error;
+    }
+    TclDecrRefCount(valueObj);
+
+    /*
+     * Run the script.
+     */
+
+    TclNRAddCallback(interp, DictMapLoopCallback, storagePtr, NULL,NULL,NULL);
+    return TclNREvalObjEx(interp, storagePtr->scriptObj, 0,
+	    iPtr->cmdFramePtr, 3);
+
+    /*
+     * For unwinding everything on error.
+     */
+
+  error:
+    TclDecrRefCount(storagePtr->keyVarObj);
+    TclDecrRefCount(storagePtr->valueVarObj);
+    TclDecrRefCount(storagePtr->scriptObj);
+    TclDecrRefCount(storagePtr->accumulatorObj);
+    Tcl_DictObjDone(&storagePtr->search);
+    TclStackFree(interp, storagePtr);
+    return TCL_ERROR;
+}
+
+static int
+DictMapLoopCallback(
+    ClientData data[],
+    Tcl_Interp *interp,
+    int result)
+{
+    Interp *iPtr = (Interp *) interp;
+    DictMapStorage *storagePtr = data[0];
+    Tcl_Obj *keyObj, *valueObj;
+    int done;
+
+    /*
+     * Process the result from the previous execution of the script body.
+     */
+
+    if (result == TCL_CONTINUE) {
+	result = TCL_OK;
+    } else if (result != TCL_OK) {
+	if (result == TCL_BREAK) {
+	    Tcl_ResetResult(interp);
+	    result = TCL_OK;
+	} else if (result == TCL_ERROR) {
+	    Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf(
+		    "\n    (\"dict map\" body line %d)",
+		    Tcl_GetErrorLine(interp)));
+	}
+	goto done;
+    } else {
+	keyObj = Tcl_ObjGetVar2(interp, storagePtr->keyVarObj, NULL,
+		TCL_LEAVE_ERR_MSG);
+	if (keyObj == NULL) {
+	    result = TCL_ERROR;
+	    goto done;
+	}
+	Tcl_DictObjPut(NULL, storagePtr->accumulatorObj, keyObj,
+		Tcl_GetObjResult(interp));
+    }
+
+    /*
+     * Get the next mapping from the dictionary.
+     */
+
+    Tcl_DictObjNext(&storagePtr->search, &keyObj, &valueObj, &done);
+    if (done) {
+	Tcl_SetObjResult(interp, storagePtr->accumulatorObj);
+	goto done;
+    }
+
+    /*
+     * Stop the value from getting hit in any way by any traces on the key
+     * variable.
+     */
+
+    Tcl_IncrRefCount(valueObj);
+    if (Tcl_ObjSetVar2(interp, storagePtr->keyVarObj, NULL, keyObj,
+	    TCL_LEAVE_ERR_MSG) == NULL) {
+	TclDecrRefCount(valueObj);
+	result = TCL_ERROR;
+	goto done;
+    }
+    if (Tcl_ObjSetVar2(interp, storagePtr->valueVarObj, NULL, valueObj,
+	    TCL_LEAVE_ERR_MSG) == NULL) {
+	TclDecrRefCount(valueObj);
+	result = TCL_ERROR;
+	goto done;
+    }
+    TclDecrRefCount(valueObj);
+
+    /*
+     * Run the script.
+     */
+
+    TclNRAddCallback(interp, DictMapLoopCallback, storagePtr, NULL,NULL,NULL);
+    return TclNREvalObjEx(interp, storagePtr->scriptObj, 0,
+	    iPtr->cmdFramePtr, 3);
+
+    /*
+     * For unwinding everything once the iterating is done.
+     */
+
+  done:
+    TclDecrRefCount(storagePtr->keyVarObj);
+    TclDecrRefCount(storagePtr->valueVarObj);
+    TclDecrRefCount(storagePtr->scriptObj);
+    TclDecrRefCount(storagePtr->accumulatorObj);
+    Tcl_DictObjDone(&storagePtr->search);
+    TclStackFree(interp, storagePtr);
+    return result;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * DictSetCmd --
+ *
+ *	This function implements the "dict set" Tcl command. See the user
+ *	documentation for details on what it does, and TIP#111 for the formal
+ *	specification.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+DictSetCmd(
+    ClientData dummy,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const *objv)
+{
+    Tcl_Obj *dictPtr, *resultPtr;
+    int result, allocatedDict = 0;
+
+    if (objc < 4) {
+	Tcl_WrongNumArgs(interp, 1, objv, "dictVarName key ?key ...? value");
+	return TCL_ERROR;
+    }
+
+    dictPtr = Tcl_ObjGetVar2(interp, objv[1], NULL, 0);
+    if (dictPtr == NULL) {
+	allocatedDict = 1;
+	dictPtr = Tcl_NewDictObj();
+    } else if (Tcl_IsShared(dictPtr)) {
+	allocatedDict = 1;
+	dictPtr = Tcl_DuplicateObj(dictPtr);
+    }
+
+    result = Tcl_DictObjPutKeyList(interp, dictPtr, objc-3, objv+2,
+	    objv[objc-1]);
+    if (result != TCL_OK) {
+	if (allocatedDict) {
+	    TclDecrRefCount(dictPtr);
+	}
+	return TCL_ERROR;
+    }
+
+    resultPtr = Tcl_ObjSetVar2(interp, objv[1], NULL, dictPtr,
+	    TCL_LEAVE_ERR_MSG);
+    if (resultPtr == NULL) {
+	return TCL_ERROR;
+    }
+    Tcl_SetObjResult(interp, resultPtr);
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * DictUnsetCmd --
+ *
+ *	This function implements the "dict unset" Tcl command. See the user
+ *	documentation for details on what it does, and TIP#111 for the formal
+ *	specification.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+DictUnsetCmd(
+    ClientData dummy,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const *objv)
+{
+    Tcl_Obj *dictPtr, *resultPtr;
+    int result, allocatedDict = 0;
+
+    if (objc < 3) {
+	Tcl_WrongNumArgs(interp, 1, objv, "dictVarName key ?key ...?");
+	return TCL_ERROR;
+    }
+
+    dictPtr = Tcl_ObjGetVar2(interp, objv[1], NULL, 0);
+    if (dictPtr == NULL) {
+	allocatedDict = 1;
+	dictPtr = Tcl_NewDictObj();
+    } else if (Tcl_IsShared(dictPtr)) {
+	allocatedDict = 1;
+	dictPtr = Tcl_DuplicateObj(dictPtr);
+    }
+
+    result = Tcl_DictObjRemoveKeyList(interp, dictPtr, objc-2, objv+2);
+    if (result != TCL_OK) {
+	if (allocatedDict) {
+	    TclDecrRefCount(dictPtr);
+	}
+	return TCL_ERROR;
+    }
+
+    resultPtr = Tcl_ObjSetVar2(interp, objv[1], NULL, dictPtr,
+	    TCL_LEAVE_ERR_MSG);
+    if (resultPtr == NULL) {
+	return TCL_ERROR;
+    }
+    Tcl_SetObjResult(interp, resultPtr);
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * DictFilterCmd --
+ *
+ *	This function implements the "dict filter" Tcl command. See the user
+ *	documentation for details on what it does, and TIP#111 for the formal
+ *	specification.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+DictFilterCmd(
+    ClientData dummy,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const *objv)
+{
+    Interp *iPtr = (Interp *) interp;
+    static const char *const filters[] = {
+	"key", "script", "value", NULL
+    };
+    enum FilterTypes {
+	FILTER_KEYS, FILTER_SCRIPT, FILTER_VALUES
+    };
+    Tcl_Obj *scriptObj, *keyVarObj, *valueVarObj;
+    Tcl_Obj **varv, *keyObj = NULL, *valueObj = NULL, *resultObj, *boolObj;
+    Tcl_DictSearch search;
+    int index, varc, done, result, satisfied;
+    const char *pattern;
+
+    if (objc < 3) {
+	Tcl_WrongNumArgs(interp, 1, objv, "dictionary filterType ?arg ...?");
+	return TCL_ERROR;
+    }
+    if (Tcl_GetIndexFromObj(interp, objv[2], filters, "filterType",
+	     0, &index) != TCL_OK) {
+	return TCL_ERROR;
+    }
+
+    switch ((enum FilterTypes) index) {
+    case FILTER_KEYS:
+	/*
+	 * Create a dictionary whose keys all match a certain pattern.
+	 */
+
+	if (Tcl_DictObjFirst(interp, objv[1], &search,
+		&keyObj, &valueObj, &done) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	if (objc == 3) {
+	    /*
+	     * Nothing to match, so return nothing (== empty dictionary).
+	     */
+
+	    Tcl_DictObjDone(&search);
+	    return TCL_OK;
+	} else if (objc == 4) {
+	    pattern = TclGetString(objv[3]);
+	    resultObj = Tcl_NewDictObj();
+	    if (TclMatchIsTrivial(pattern)) {
+		/*
+		 * Must release the search lock here to prevent a memory leak
+		 * since we are not exhausing the search. [Bug 1705778, leak
+		 * K05]
+		 */
+
+		Tcl_DictObjDone(&search);
+		Tcl_DictObjGet(interp, objv[1], objv[3], &valueObj);
+		if (valueObj != NULL) {
+		    Tcl_DictObjPut(NULL, resultObj, objv[3], valueObj);
+		}
+	    } else {
+		while (!done) {
+		    if (Tcl_StringMatch(TclGetString(keyObj), pattern)) {
+			Tcl_DictObjPut(NULL, resultObj, keyObj, valueObj);
+		    }
+		    Tcl_DictObjNext(&search, &keyObj, &valueObj, &done);
+		}
+	    }
+	} else {
+	    /*
+	     * Can't optimize this match for trivial globbing: would disturb
+	     * order.
+	     */
+
+	    resultObj = Tcl_NewDictObj();
+	    while (!done) {
+		int i;
+
+		for (i=3 ; i<objc ; i++) {
+		    pattern = TclGetString(objv[i]);
+		    if (Tcl_StringMatch(TclGetString(keyObj), pattern)) {
+			Tcl_DictObjPut(NULL, resultObj, keyObj, valueObj);
+			break;		/* stop inner loop */
+		    }
+		}
+		Tcl_DictObjNext(&search, &keyObj, &valueObj, &done);
+	    }
+	}
+	Tcl_SetObjResult(interp, resultObj);
+	return TCL_OK;
+
+    case FILTER_VALUES:
+	/*
+	 * Create a dictionary whose values all match a certain pattern.
+	 */
+
+	if (Tcl_DictObjFirst(interp, objv[1], &search,
+		&keyObj, &valueObj, &done) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	resultObj = Tcl_NewDictObj();
+	while (!done) {
+	    int i;
+
+	    for (i=3 ; i<objc ; i++) {
+		pattern = TclGetString(objv[i]);
+		if (Tcl_StringMatch(TclGetString(valueObj), pattern)) {
+		    Tcl_DictObjPut(NULL, resultObj, keyObj, valueObj);
+		    break;		/* stop inner loop */
+		}
+	    }
+	    Tcl_DictObjNext(&search, &keyObj, &valueObj, &done);
+	}
+	Tcl_SetObjResult(interp, resultObj);
+	return TCL_OK;
+
+    case FILTER_SCRIPT:
+	if (objc != 5) {
+	    Tcl_WrongNumArgs(interp, 1, objv,
+		    "dictionary script {keyVarName valueVarName} filterScript");
+	    return TCL_ERROR;
+	}
+
+	/*
+	 * Create a dictionary whose key,value pairs all satisfy a script
+	 * (i.e. get a true boolean result from its evaluation). Massive
+	 * copying from the "dict for" implementation has occurred!
+	 */
+
+	if (TclListObjGetElements(interp, objv[3], &varc, &varv) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	if (varc != 2) {
+	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		    "must have exactly two variable names", -1));
+	    Tcl_SetErrorCode(interp, "TCL", "SYNTAX", "dict", "filter", NULL);
+	    return TCL_ERROR;
+	}
+	keyVarObj = varv[0];
+	valueVarObj = varv[1];
+	scriptObj = objv[4];
+
+	/*
+	 * Make sure that these objects (which we need throughout the body of
+	 * the loop) don't vanish. Note that the dictionary internal rep is
+	 * locked internally so that updates, shimmering, etc are not a
+	 * problem.
+	 */
+
+	Tcl_IncrRefCount(keyVarObj);
+	Tcl_IncrRefCount(valueVarObj);
+	Tcl_IncrRefCount(scriptObj);
+
+	result = Tcl_DictObjFirst(interp, objv[1],
+		&search, &keyObj, &valueObj, &done);
+	if (result != TCL_OK) {
+	    TclDecrRefCount(keyVarObj);
+	    TclDecrRefCount(valueVarObj);
+	    TclDecrRefCount(scriptObj);
+	    return TCL_ERROR;
+	}
+
+	resultObj = Tcl_NewDictObj();
+
+	while (!done) {
+	    /*
+	     * Stop the value from getting hit in any way by any traces on the
+	     * key variable.
+	     */
+
+	    Tcl_IncrRefCount(keyObj);
+	    Tcl_IncrRefCount(valueObj);
+	    if (Tcl_ObjSetVar2(interp, keyVarObj, NULL, keyObj,
+		    TCL_LEAVE_ERR_MSG) == NULL) {
+		Tcl_AddErrorInfo(interp,
+			"\n    (\"dict filter\" filter script key variable)");
+		result = TCL_ERROR;
+		goto abnormalResult;
+	    }
+	    if (Tcl_ObjSetVar2(interp, valueVarObj, NULL, valueObj,
+		    TCL_LEAVE_ERR_MSG) == NULL) {
+		Tcl_AddErrorInfo(interp,
+			"\n    (\"dict filter\" filter script value variable)");
+		result = TCL_ERROR;
+		goto abnormalResult;
+	    }
+
+	    /*
+	     * TIP #280. Make invoking context available to loop body.
+	     */
+
+	    result = TclEvalObjEx(interp, scriptObj, 0, iPtr->cmdFramePtr, 4);
+	    switch (result) {
+	    case TCL_OK:
+		boolObj = Tcl_GetObjResult(interp);
+		Tcl_IncrRefCount(boolObj);
+		Tcl_ResetResult(interp);
+		if (Tcl_GetBooleanFromObj(interp, boolObj,
+			&satisfied) != TCL_OK) {
+		    TclDecrRefCount(boolObj);
+		    result = TCL_ERROR;
+		    goto abnormalResult;
+		}
+		TclDecrRefCount(boolObj);
+		if (satisfied) {
+		    Tcl_DictObjPut(NULL, resultObj, keyObj, valueObj);
+		}
+		break;
+	    case TCL_BREAK:
+		/*
+		 * Force loop termination by calling Tcl_DictObjDone; this
+		 * makes the next Tcl_DictObjNext say there is nothing more to
+		 * do.
+		 */
+
+		Tcl_ResetResult(interp);
+		Tcl_DictObjDone(&search);
+	    case TCL_CONTINUE:
+		result = TCL_OK;
+		break;
+	    case TCL_ERROR:
+		Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf(
+			"\n    (\"dict filter\" script line %d)",
+			Tcl_GetErrorLine(interp)));
+	    default:
+		goto abnormalResult;
+	    }
+
+	    TclDecrRefCount(keyObj);
+	    TclDecrRefCount(valueObj);
+
+	    Tcl_DictObjNext(&search, &keyObj, &valueObj, &done);
+	}
+
+	/*
+	 * Stop holding a reference to these objects.
+	 */
+
+	TclDecrRefCount(keyVarObj);
+	TclDecrRefCount(valueVarObj);
+	TclDecrRefCount(scriptObj);
+	Tcl_DictObjDone(&search);
+
+	if (result == TCL_OK) {
+	    Tcl_SetObjResult(interp, resultObj);
+	} else {
+	    TclDecrRefCount(resultObj);
+	}
+	return result;
+
+    abnormalResult:
+	Tcl_DictObjDone(&search);
+	TclDecrRefCount(keyObj);
+	TclDecrRefCount(valueObj);
+	TclDecrRefCount(keyVarObj);
+	TclDecrRefCount(valueVarObj);
+	TclDecrRefCount(scriptObj);
+	TclDecrRefCount(resultObj);
+	return result;
+    }
+    Tcl_Panic("unexpected fallthrough");
+    /* Control never reaches this point. */
+    return TCL_ERROR;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * DictUpdateCmd --
+ *
+ *	This function implements the "dict update" Tcl command. See the user
+ *	documentation for details on what it does, and TIP#212 for the formal
+ *	specification.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+DictUpdateCmd(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const *objv)
+{
+    Interp *iPtr = (Interp *) interp;
+    Tcl_Obj *dictPtr, *objPtr;
+    int i, dummy;
+
+    if (objc < 5 || !(objc & 1)) {
+	Tcl_WrongNumArgs(interp, 1, objv,
+		"dictVarName key varName ?key varName ...? script");
+	return TCL_ERROR;
+    }
+
+    dictPtr = Tcl_ObjGetVar2(interp, objv[1], NULL, TCL_LEAVE_ERR_MSG);
+    if (dictPtr == NULL) {
+	return TCL_ERROR;
+    }
+    if (Tcl_DictObjSize(interp, dictPtr, &dummy) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    Tcl_IncrRefCount(dictPtr);
+    for (i=2 ; i+2<objc ; i+=2) {
+	if (Tcl_DictObjGet(interp, dictPtr, objv[i], &objPtr) != TCL_OK) {
+	    TclDecrRefCount(dictPtr);
+	    return TCL_ERROR;
+	}
+	if (objPtr == NULL) {
+	    /* ??? */
+	    Tcl_UnsetVar(interp, Tcl_GetString(objv[i+1]), 0);
+	} else if (Tcl_ObjSetVar2(interp, objv[i+1], NULL, objPtr,
+		TCL_LEAVE_ERR_MSG) == NULL) {
+	    TclDecrRefCount(dictPtr);
+	    return TCL_ERROR;
+	}
+    }
+    TclDecrRefCount(dictPtr);
+
+    /*
+     * Execute the body after setting up the NRE handler to process the
+     * results.
+     */
+
+    objPtr = Tcl_NewListObj(objc-3, objv+2);
+    Tcl_IncrRefCount(objPtr);
+    Tcl_IncrRefCount(objv[1]);
+    TclNRAddCallback(interp, FinalizeDictUpdate, objv[1], objPtr, NULL,NULL);
+
+    return TclNREvalObjEx(interp, objv[objc-1], 0, iPtr->cmdFramePtr, objc-1);
+}
+
+static int
+FinalizeDictUpdate(
+    ClientData data[],
+    Tcl_Interp *interp,
+    int result)
+{
+    Tcl_Obj *dictPtr, *objPtr, **objv;
+    Tcl_InterpState state;
+    int i, objc;
+    Tcl_Obj *varName = data[0];
+    Tcl_Obj *argsObj = data[1];
+
+    /*
+     * ErrorInfo handling.
+     */
+
+    if (result == TCL_ERROR) {
+	Tcl_AddErrorInfo(interp, "\n    (body of \"dict update\")");
+    }
+
+    /*
+     * If the dictionary variable doesn't exist, drop everything silently.
+     */
+
+    dictPtr = Tcl_ObjGetVar2(interp, varName, NULL, 0);
+    if (dictPtr == NULL) {
+	TclDecrRefCount(varName);
+	TclDecrRefCount(argsObj);
+	return result;
+    }
+
+    /*
+     * Double-check that it is still a dictionary.
+     */
+
+    state = Tcl_SaveInterpState(interp, result);
+    if (Tcl_DictObjSize(interp, dictPtr, &objc) != TCL_OK) {
+	Tcl_DiscardInterpState(state);
+	TclDecrRefCount(varName);
+	TclDecrRefCount(argsObj);
+	return TCL_ERROR;
+    }
+
+    if (Tcl_IsShared(dictPtr)) {
+	dictPtr = Tcl_DuplicateObj(dictPtr);
+    }
+
+    /*
+     * Write back the values from the variables, treating failure to read as
+     * an instruction to remove the key.
+     */
+
+    Tcl_ListObjGetElements(NULL, argsObj, &objc, &objv);
+    for (i=0 ; i<objc ; i+=2) {
+	objPtr = Tcl_ObjGetVar2(interp, objv[i+1], NULL, 0);
+	if (objPtr == NULL) {
+	    Tcl_DictObjRemove(NULL, dictPtr, objv[i]);
+	} else if (objPtr == dictPtr) {
+	    /*
+	     * Someone is messing us around, trying to build a recursive
+	     * structure. [Bug 1786481]
+	     */
+
+	    Tcl_DictObjPut(NULL, dictPtr, objv[i], Tcl_DuplicateObj(objPtr));
+	} else {
+	    /* Shouldn't fail */
+	    Tcl_DictObjPut(NULL, dictPtr, objv[i], objPtr);
+	}
+    }
+    TclDecrRefCount(argsObj);
+
+    /*
+     * Write the dictionary back to its variable.
+     */
+
+    if (Tcl_ObjSetVar2(interp, varName, NULL, dictPtr,
+	    TCL_LEAVE_ERR_MSG) == NULL) {
+	Tcl_DiscardInterpState(state);
+	TclDecrRefCount(varName);
+	return TCL_ERROR;
+    }
+
+    TclDecrRefCount(varName);
+    return Tcl_RestoreInterpState(interp, state);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * DictWithCmd --
+ *
+ *	This function implements the "dict with" Tcl command. See the user
+ *	documentation for details on what it does, and TIP#212 for the formal
+ *	specification.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+DictWithCmd(
+    ClientData dummy,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const *objv)
+{
+    Interp *iPtr = (Interp *) interp;
+    Tcl_Obj *dictPtr, *keysPtr, *pathPtr;
+
+    if (objc < 3) {
+	Tcl_WrongNumArgs(interp, 1, objv, "dictVarName ?key ...? script");
+	return TCL_ERROR;
+    }
+
+    /*
+     * Get the dictionary to open out.
+     */
+
+    dictPtr = Tcl_ObjGetVar2(interp, objv[1], NULL, TCL_LEAVE_ERR_MSG);
+    if (dictPtr == NULL) {
+	return TCL_ERROR;
+    }
+
+    keysPtr = TclDictWithInit(interp, dictPtr, objc-3, objv+2);
+    if (keysPtr == NULL) {
+	return TCL_ERROR;
+    }
+    Tcl_IncrRefCount(keysPtr);
+
+    /*
+     * Execute the body, while making the invoking context available to the
+     * loop body (TIP#280) and postponing the cleanup until later (NRE).
+     */
+
+    pathPtr = NULL;
+    if (objc > 3) {
+	pathPtr = Tcl_NewListObj(objc-3, objv+2);
+	Tcl_IncrRefCount(pathPtr);
+    }
+    Tcl_IncrRefCount(objv[1]);
+    TclNRAddCallback(interp, FinalizeDictWith, objv[1], keysPtr, pathPtr,
+	    NULL);
+
+    return TclNREvalObjEx(interp, objv[objc-1], 0, iPtr->cmdFramePtr, objc-1);
+}
+
+static int
+FinalizeDictWith(
+    ClientData data[],
+    Tcl_Interp *interp,
+    int result)
+{
+    Tcl_Obj **pathv;
+    int pathc;
+    Tcl_InterpState state;
+    Tcl_Obj *varName = data[0];
+    Tcl_Obj *keysPtr = data[1];
+    Tcl_Obj *pathPtr = data[2];
+    Var *varPtr, *arrayPtr;
+
+    if (result == TCL_ERROR) {
+	Tcl_AddErrorInfo(interp, "\n    (body of \"dict with\")");
+    }
+
+    /*
+     * Save the result state; TDWF doesn't guarantee to not modify that on
+     * TCL_OK result.
+     */
+
+    state = Tcl_SaveInterpState(interp, result);
+    if (pathPtr != NULL) {
+	Tcl_ListObjGetElements(NULL, pathPtr, &pathc, &pathv);
+    } else {
+	pathc = 0;
+	pathv = NULL;
+    }
+
+    /*
+     * Pack from local variables back into the dictionary.
+     */
+
+    varPtr = TclObjLookupVarEx(interp, varName, NULL, TCL_LEAVE_ERR_MSG, "set",
+	    /*createPart1*/ 1, /*createPart2*/ 1, &arrayPtr);
+    if (varPtr == NULL) {
+	result = TCL_ERROR;
+    } else {
+	result = TclDictWithFinish(interp, varPtr, arrayPtr, varName, NULL, -1,
+		pathc, pathv, keysPtr);
+    }
+
+    /*
+     * Tidy up and return the real result (unless we had an error).
+     */
+
+    TclDecrRefCount(varName);
+    TclDecrRefCount(keysPtr);
+    if (pathPtr != NULL) {
+	TclDecrRefCount(pathPtr);
+    }
+    if (result != TCL_OK) {
+	Tcl_DiscardInterpState(state);
+	return TCL_ERROR;
+    }
+    return Tcl_RestoreInterpState(interp, state);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclDictWithInit --
+ *
+ *	Part of the core of [dict with]. Pokes into a dictionary and converts
+ *	the mappings there into assignments to (presumably) local variables.
+ *	Returns a list of all the names that were mapped so that removal of
+ *	either the variable or the dictionary entry won't surprise us when we
+ *	come to stuffing everything back.
+ *
+ * Result:
+ *	List of mapped names, or NULL if there was an error.
+ *
+ * Side effects:
+ *	Assigns to variables, so potentially legion due to traces.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_Obj *
+TclDictWithInit(
+    Tcl_Interp *interp,
+    Tcl_Obj *dictPtr,
+    int pathc,
+    Tcl_Obj *const pathv[])
+{
+    Tcl_DictSearch s;
+    Tcl_Obj *keyPtr, *valPtr, *keysPtr;
+    int done;
+
+    if (pathc > 0) {
+	dictPtr = TclTraceDictPath(interp, dictPtr, pathc, pathv,
+		DICT_PATH_READ);
+	if (dictPtr == NULL) {
+	    return NULL;
+	}
+    }
+
+    /*
+     * Go over the list of keys and write each corresponding value to a
+     * variable in the current context with the same name. Also keep a copy of
+     * the keys so we can write back properly later on even if the dictionary
+     * has been structurally modified.
+     */
+
+    if (Tcl_DictObjFirst(interp, dictPtr, &s, &keyPtr, &valPtr,
+	    &done) != TCL_OK) {
+	return NULL;
+    }
+
+    TclNewObj(keysPtr);
+
+    for (; !done ; Tcl_DictObjNext(&s, &keyPtr, &valPtr, &done)) {
+	Tcl_ListObjAppendElement(NULL, keysPtr, keyPtr);
+	if (Tcl_ObjSetVar2(interp, keyPtr, NULL, valPtr,
+		TCL_LEAVE_ERR_MSG) == NULL) {
+	    TclDecrRefCount(keysPtr);
+	    Tcl_DictObjDone(&s);
+	    return NULL;
+	}
+    }
+
+    return keysPtr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclDictWithFinish --
+ *
+ *	Part of the core of [dict with]. Reassembles the piece of the dict (in
+ *	varName, location given by pathc/pathv) from the variables named in
+ *	the keysPtr argument. NB, does not try to preserve errors or manage
+ *	argument lifetimes.
+ *
+ * Result:
+ *	TCL_OK if we succeeded, or TCL_ERROR if we failed.
+ *
+ * Side effects:
+ *	Assigns to a variable, so potentially legion due to traces. Updates
+ *	the dictionary in the named variable.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclDictWithFinish(
+    Tcl_Interp *interp,		/* Command interpreter in which variable
+				 * exists. Used for state management, traces
+				 * and error reporting. */
+    Var *varPtr,		/* Reference to the variable holding the
+				 * dictionary. */
+    Var *arrayPtr,		/* Reference to the array containing the
+				 * variable, or NULL if the variable is a
+				 * scalar. */
+    Tcl_Obj *part1Ptr,		/* Name of an array (if part2 is non-NULL) or
+				 * the name of a variable. NULL if the 'index'
+				 * parameter is >= 0 */
+    Tcl_Obj *part2Ptr,		/* If non-NULL, gives the name of an element
+				 * in the array part1. */
+    int index,			/* Index into the local variable table of the
+				 * variable, or -1. Only used when part1Ptr is
+				 * NULL. */
+    int pathc,			/* The number of elements in the path into the
+				 * dictionary. */
+    Tcl_Obj *const pathv[],	/* The elements of the path to the subdict. */
+    Tcl_Obj *keysPtr)		/* List of keys to be synchronized. This is
+				 * the result value from TclDictWithInit. */
+{
+    Tcl_Obj *dictPtr, *leafPtr, *valPtr;
+    int i, allocdict, keyc;
+    Tcl_Obj **keyv;
+
+    /*
+     * If the dictionary variable doesn't exist, drop everything silently.
+     */
+
+    dictPtr = TclPtrGetVar(interp, varPtr, arrayPtr, part1Ptr, part2Ptr,
+	    TCL_LEAVE_ERR_MSG, index);
+    if (dictPtr == NULL) {
+	return TCL_OK;
+    }
+
+    /*
+     * Double-check that it is still a dictionary.
+     */
+
+    if (Tcl_DictObjSize(interp, dictPtr, &i) != TCL_OK) {
+	return TCL_ERROR;
+    }
+
+    if (Tcl_IsShared(dictPtr)) {
+	dictPtr = Tcl_DuplicateObj(dictPtr);
+	allocdict = 1;
+    } else {
+	allocdict = 0;
+    }
+
+    if (pathc > 0) {
+	/*
+	 * Want to get to the dictionary which we will update; need to do
+	 * prepare-for-update de-sharing along the path *but* avoid generating
+	 * an error on a non-existant path (we'll treat that the same as a
+	 * non-existant variable. Luckily, the de-sharing operation isn't
+	 * deeply damaging if we don't go on to update; it's just less than
+	 * perfectly efficient (but no memory should be leaked).
+	 */
+
+	leafPtr = TclTraceDictPath(interp, dictPtr, pathc, pathv,
+		DICT_PATH_EXISTS | DICT_PATH_UPDATE);
+	if (leafPtr == NULL) {
+	    if (allocdict) {
+		TclDecrRefCount(dictPtr);
+	    }
+	    return TCL_ERROR;
+	}
+	if (leafPtr == DICT_PATH_NON_EXISTENT) {
+	    if (allocdict) {
+		TclDecrRefCount(dictPtr);
+	    }
+	    return TCL_OK;
+	}
+    } else {
+	leafPtr = dictPtr;
+    }
+
+    /*
+     * Now process our updates on the leaf dictionary.
+     */
+
+    TclListObjGetElements(NULL, keysPtr, &keyc, &keyv);
+    for (i=0 ; i<keyc ; i++) {
+	valPtr = Tcl_ObjGetVar2(interp, keyv[i], NULL, 0);
+	if (valPtr == NULL) {
+	    Tcl_DictObjRemove(NULL, leafPtr, keyv[i]);
+	} else if (leafPtr == valPtr) {
+	    /*
+	     * Someone is messing us around, trying to build a recursive
+	     * structure. [Bug 1786481]
+	     */
+
+	    Tcl_DictObjPut(NULL, leafPtr, keyv[i], Tcl_DuplicateObj(valPtr));
+	} else {
+	    Tcl_DictObjPut(NULL, leafPtr, keyv[i], valPtr);
+	}
+    }
+
+    /*
+     * Ensure that none of the dictionaries in the chain still have a string
+     * rep.
+     */
+
+    if (pathc > 0) {
+	InvalidateDictChain(leafPtr);
+    }
+
+    /*
+     * Write back the outermost dictionary to the variable.
+     */
+
+    if (TclPtrSetVar(interp, varPtr, arrayPtr, part1Ptr, part2Ptr, dictPtr,
+	    TCL_LEAVE_ERR_MSG, index) == NULL) {
+	if (allocdict) {
+	    TclDecrRefCount(dictPtr);
+	}
+	return TCL_ERROR;
+    }
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclInitDictCmd --
+ *
+ *	This function is create the "dict" Tcl command. See the user
+ *	documentation for details on what it does, and TIP#111 for the formal
+ *	specification.
+ *
+ * Results:
+ *	A Tcl command handle.
+ *
+ * Side effects:
+ *	May advance compilation epoch.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_Command
+TclInitDictCmd(
+    Tcl_Interp *interp)
+{
+    return TclMakeEnsemble(interp, "dict", implementationMap);
+}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tclDisassemble.c b/generic/tclDisassemble.c
new file mode 100644
index 0000000..1d616fb
--- /dev/null
+++ b/generic/tclDisassemble.c
@@ -0,0 +1,1636 @@
+/*
+ * tclDisassemble.c --
+ *
+ *	This file contains procedures that disassemble bytecode into either
+ *	human-readable or Tcl-processable forms.
+ *
+ * Copyright (c) 1996-1998 Sun Microsystems, Inc.
+ * Copyright (c) 2001 by Kevin B. Kenny. All rights reserved.
+ * Copyright (c) 2013-2016 Donal K. Fellows.
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#include "tclInt.h"
+#include "tclCompile.h"
+#include "tclOOInt.h"
+#include <assert.h>
+
+/*
+ * Prototypes for procedures defined later in this file:
+ */
+
+static Tcl_Obj *	DisassembleByteCodeAsDicts(Tcl_Interp *interp,
+			    Tcl_Obj *objPtr);
+static Tcl_Obj *	DisassembleByteCodeObj(Tcl_Interp *interp,
+			    Tcl_Obj *objPtr);
+static int		FormatInstruction(ByteCode *codePtr,
+			    const unsigned char *pc, Tcl_Obj *bufferObj);
+static void		GetLocationInformation(Tcl_Interp *interp,
+			    Proc *procPtr, Tcl_Obj **fileObjPtr,
+			    int *linePtr);
+static void		PrintSourceToObj(Tcl_Obj *appendObj,
+			    const char *stringPtr, int maxChars);
+static void		UpdateStringOfInstName(Tcl_Obj *objPtr);
+
+/*
+ * The structure below defines an instruction name Tcl object to allow
+ * reporting of inner contexts in errorstack without string allocation.
+ */
+
+static const Tcl_ObjType tclInstNameType = {
+    "instname",			/* name */
+    NULL,			/* freeIntRepProc */
+    NULL,			/* dupIntRepProc */
+    UpdateStringOfInstName,	/* updateStringProc */
+    NULL,			/* setFromAnyProc */
+};
+
+/*
+ * How to get the bytecode out of a Tcl_Obj.
+ */
+
+#define BYTECODE(objPtr)					\
+    ((ByteCode *) (objPtr)->internalRep.twoPtrValue.ptr1)
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * GetLocationInformation --
+ *
+ *	This procedure looks up the information about where a procedure was
+ *	originally declared.
+ *
+ * Results:
+ *	Writes to the variables pointed at by fileObjPtr and linePtr.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+GetLocationInformation(
+    Tcl_Interp *interp,		/* Where to look up the location
+				 * information. */
+    Proc *procPtr,		/* What to look up the information for. */
+    Tcl_Obj **fileObjPtr,	/* Where to write the information about what
+				 * file the code came from. Will be written
+				 * to, either with the object (assume shared!)
+				 * that describes what the file was, or with
+				 * NULL if the information is not
+				 * available. */
+    int *linePtr)		/* Where to write the information about what
+				 * line number represented the start of the
+				 * code in question. Will be written to,
+				 * either with the line number or with -1 if
+				 * the information is not available. */
+{
+    Interp *iPtr = (Interp *) interp;
+    Tcl_HashEntry *hePtr;
+    CmdFrame *cfPtr;
+
+    *fileObjPtr = NULL;
+    *linePtr = -1;
+    if (iPtr != NULL && procPtr != NULL) {
+	hePtr = Tcl_FindHashEntry(iPtr->linePBodyPtr, procPtr);
+	if (hePtr != NULL && (cfPtr = Tcl_GetHashValue(hePtr)) != NULL) {
+	    *linePtr = cfPtr->line[0];
+	    if (cfPtr->type == TCL_LOCATION_SOURCE) {
+		*fileObjPtr = cfPtr->data.eval.path;
+	    }
+	}
+    }
+}
+
+#ifdef TCL_COMPILE_DEBUG
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclPrintByteCodeObj --
+ *
+ *	This procedure prints ("disassembles") the instructions of a bytecode
+ *	object to stdout.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclPrintByteCodeObj(
+    Tcl_Interp *interp,		/* Used only for getting location info. */
+    Tcl_Obj *objPtr)		/* The bytecode object to disassemble. */
+{
+    Tcl_Obj *bufPtr = DisassembleByteCodeObj(interp, objPtr);
+
+    fprintf(stdout, "\n%s", TclGetString(bufPtr));
+    Tcl_DecrRefCount(bufPtr);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclPrintInstruction --
+ *
+ *	This procedure prints ("disassembles") one instruction from a bytecode
+ *	object to stdout.
+ *
+ * Results:
+ *	Returns the length in bytes of the current instruiction.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclPrintInstruction(
+    ByteCode *codePtr,		/* Bytecode containing the instruction. */
+    const unsigned char *pc)	/* Points to first byte of instruction. */
+{
+    Tcl_Obj *bufferObj;
+    int numBytes;
+
+    TclNewObj(bufferObj);
+    numBytes = FormatInstruction(codePtr, pc, bufferObj);
+    fprintf(stdout, "%s", TclGetString(bufferObj));
+    Tcl_DecrRefCount(bufferObj);
+    return numBytes;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclPrintObject --
+ *
+ *	This procedure prints up to a specified number of characters from the
+ *	argument Tcl object's string representation to a specified file.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Outputs characters to the specified file.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclPrintObject(
+    FILE *outFile,		/* The file to print the source to. */
+    Tcl_Obj *objPtr,		/* Points to the Tcl object whose string
+				 * representation should be printed. */
+    int maxChars)		/* Maximum number of chars to print. */
+{
+    char *bytes;
+    int length;
+
+    bytes = Tcl_GetStringFromObj(objPtr, &length);
+    TclPrintSource(outFile, bytes, TclMin(length, maxChars));
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclPrintSource --
+ *
+ *	This procedure prints up to a specified number of characters from the
+ *	argument string to a specified file. It tries to produce legible
+ *	output by adding backslashes as necessary.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Outputs characters to the specified file.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclPrintSource(
+    FILE *outFile,		/* The file to print the source to. */
+    const char *stringPtr,	/* The string to print. */
+    int maxChars)		/* Maximum number of chars to print. */
+{
+    Tcl_Obj *bufferObj;
+
+    TclNewObj(bufferObj);
+    PrintSourceToObj(bufferObj, stringPtr, maxChars);
+    fprintf(outFile, "%s", TclGetString(bufferObj));
+    Tcl_DecrRefCount(bufferObj);
+}
+#endif /* TCL_COMPILE_DEBUG */
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * DisassembleByteCodeObj --
+ *
+ *	Given an object which is of bytecode type, return a disassembled
+ *	version of the bytecode (in a new refcount 0 object). No guarantees
+ *	are made about the details of the contents of the result.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static Tcl_Obj *
+DisassembleByteCodeObj(
+    Tcl_Interp *interp,
+    Tcl_Obj *objPtr)		/* The bytecode object to disassemble. */
+{
+    ByteCode *codePtr = BYTECODE(objPtr);
+    unsigned char *codeStart, *codeLimit, *pc;
+    unsigned char *codeDeltaNext, *codeLengthNext;
+    unsigned char *srcDeltaNext, *srcLengthNext;
+    int codeOffset, codeLen, srcOffset, srcLen, numCmds, delta, i, line;
+    Interp *iPtr = (Interp *) *codePtr->interpHandle;
+    Tcl_Obj *bufferObj, *fileObj;
+    char ptrBuf1[20], ptrBuf2[20];
+
+    TclNewObj(bufferObj);
+    if (codePtr->refCount <= 0) {
+	return bufferObj;	/* Already freed. */
+    }
+
+    codeStart = codePtr->codeStart;
+    codeLimit = codeStart + codePtr->numCodeBytes;
+    numCmds = codePtr->numCommands;
+
+    /*
+     * Print header lines describing the ByteCode.
+     */
+
+    sprintf(ptrBuf1, "%p", codePtr);
+    sprintf(ptrBuf2, "%p", iPtr);
+    Tcl_AppendPrintfToObj(bufferObj,
+	    "ByteCode 0x%s, refCt %u, epoch %u, interp 0x%s (epoch %u)\n",
+	    ptrBuf1, codePtr->refCount, codePtr->compileEpoch, ptrBuf2,
+	    iPtr->compileEpoch);
+    Tcl_AppendToObj(bufferObj, "  Source ", -1);
+    PrintSourceToObj(bufferObj, codePtr->source,
+	    TclMin(codePtr->numSrcBytes, 55));
+    GetLocationInformation(interp, codePtr->procPtr, &fileObj, &line);
+    if (line > -1 && fileObj != NULL) {
+	Tcl_AppendPrintfToObj(bufferObj, "\n  File \"%s\" Line %d",
+		Tcl_GetString(fileObj), line);
+    }
+    Tcl_AppendPrintfToObj(bufferObj,
+	    "\n  Cmds %d, src %d, inst %d, litObjs %u, aux %d, stkDepth %u, code/src %.2f\n",
+	    numCmds, codePtr->numSrcBytes, codePtr->numCodeBytes,
+	    codePtr->numLitObjects, codePtr->numAuxDataItems,
+	    codePtr->maxStackDepth,
+#ifdef TCL_COMPILE_STATS
+	    codePtr->numSrcBytes?
+		    codePtr->structureSize/(float)codePtr->numSrcBytes :
+#endif
+	    0.0);
+
+#ifdef TCL_COMPILE_STATS
+    Tcl_AppendPrintfToObj(bufferObj,
+	    "  Code %lu = header %lu+inst %d+litObj %lu+exc %lu+aux %lu+cmdMap %d\n",
+	    (unsigned long) codePtr->structureSize,
+	    (unsigned long) (sizeof(ByteCode) - sizeof(size_t) - sizeof(Tcl_Time)),
+	    codePtr->numCodeBytes,
+	    (unsigned long) (codePtr->numLitObjects * sizeof(Tcl_Obj *)),
+	    (unsigned long) (codePtr->numExceptRanges*sizeof(ExceptionRange)),
+	    (unsigned long) (codePtr->numAuxDataItems * sizeof(AuxData)),
+	    codePtr->numCmdLocBytes);
+#endif /* TCL_COMPILE_STATS */
+
+    /*
+     * If the ByteCode is the compiled body of a Tcl procedure, print
+     * information about that procedure. Note that we don't know the
+     * procedure's name since ByteCode's can be shared among procedures.
+     */
+
+    if (codePtr->procPtr != NULL) {
+	Proc *procPtr = codePtr->procPtr;
+	int numCompiledLocals = procPtr->numCompiledLocals;
+
+	sprintf(ptrBuf1, "%p", procPtr);
+	Tcl_AppendPrintfToObj(bufferObj,
+		"  Proc 0x%s, refCt %d, args %d, compiled locals %d\n",
+		ptrBuf1, procPtr->refCount, procPtr->numArgs,
+		numCompiledLocals);
+	if (numCompiledLocals > 0) {
+	    CompiledLocal *localPtr = procPtr->firstLocalPtr;
+
+	    for (i = 0;  i < numCompiledLocals;  i++) {
+		Tcl_AppendPrintfToObj(bufferObj,
+			"      slot %d%s%s%s%s%s%s", i,
+			(localPtr->flags & (VAR_ARRAY|VAR_LINK)) ? "" : ", scalar",
+			(localPtr->flags & VAR_ARRAY) ? ", array" : "",
+			(localPtr->flags & VAR_LINK) ? ", link" : "",
+			(localPtr->flags & VAR_ARGUMENT) ? ", arg" : "",
+			(localPtr->flags & VAR_TEMPORARY) ? ", temp" : "",
+			(localPtr->flags & VAR_RESOLVED) ? ", resolved" : "");
+		if (TclIsVarTemporary(localPtr)) {
+		    Tcl_AppendToObj(bufferObj, "\n", -1);
+		} else {
+		    Tcl_AppendPrintfToObj(bufferObj, ", \"%s\"\n",
+			    localPtr->name);
+		}
+		localPtr = localPtr->nextPtr;
+	    }
+	}
+    }
+
+    /*
+     * Print the ExceptionRange array.
+     */
+
+    if (codePtr->numExceptRanges > 0) {
+	Tcl_AppendPrintfToObj(bufferObj, "  Exception ranges %d, depth %d:\n",
+		codePtr->numExceptRanges, codePtr->maxExceptDepth);
+	for (i = 0;  i < codePtr->numExceptRanges;  i++) {
+	    ExceptionRange *rangePtr = &codePtr->exceptArrayPtr[i];
+
+	    Tcl_AppendPrintfToObj(bufferObj,
+		    "      %d: level %d, %s, pc %d-%d, ",
+		    i, rangePtr->nestingLevel,
+		    (rangePtr->type==LOOP_EXCEPTION_RANGE ? "loop" : "catch"),
+		    rangePtr->codeOffset,
+		    (rangePtr->codeOffset + rangePtr->numCodeBytes - 1));
+	    switch (rangePtr->type) {
+	    case LOOP_EXCEPTION_RANGE:
+		Tcl_AppendPrintfToObj(bufferObj, "continue %d, break %d\n",
+			rangePtr->continueOffset, rangePtr->breakOffset);
+		break;
+	    case CATCH_EXCEPTION_RANGE:
+		Tcl_AppendPrintfToObj(bufferObj, "catch %d\n",
+			rangePtr->catchOffset);
+		break;
+	    default:
+		Tcl_Panic("DisassembleByteCodeObj: bad ExceptionRange type %d",
+			rangePtr->type);
+	    }
+	}
+    }
+
+    /*
+     * If there were no commands (e.g., an expression or an empty string was
+     * compiled), just print all instructions and return.
+     */
+
+    if (numCmds == 0) {
+	pc = codeStart;
+	while (pc < codeLimit) {
+	    Tcl_AppendToObj(bufferObj, "    ", -1);
+	    pc += FormatInstruction(codePtr, pc, bufferObj);
+	}
+	return bufferObj;
+    }
+
+    /*
+     * Print table showing the code offset, source offset, and source length
+     * for each command. These are encoded as a sequence of bytes.
+     */
+
+    Tcl_AppendPrintfToObj(bufferObj, "  Commands %d:", numCmds);
+    codeDeltaNext = codePtr->codeDeltaStart;
+    codeLengthNext = codePtr->codeLengthStart;
+    srcDeltaNext = codePtr->srcDeltaStart;
+    srcLengthNext = codePtr->srcLengthStart;
+    codeOffset = srcOffset = 0;
+    for (i = 0;  i < numCmds;  i++) {
+	if ((unsigned) *codeDeltaNext == (unsigned) 0xFF) {
+	    codeDeltaNext++;
+	    delta = TclGetInt4AtPtr(codeDeltaNext);
+	    codeDeltaNext += 4;
+	} else {
+	    delta = TclGetInt1AtPtr(codeDeltaNext);
+	    codeDeltaNext++;
+	}
+	codeOffset += delta;
+
+	if ((unsigned) *codeLengthNext == (unsigned) 0xFF) {
+	    codeLengthNext++;
+	    codeLen = TclGetInt4AtPtr(codeLengthNext);
+	    codeLengthNext += 4;
+	} else {
+	    codeLen = TclGetInt1AtPtr(codeLengthNext);
+	    codeLengthNext++;
+	}
+
+	if ((unsigned) *srcDeltaNext == (unsigned) 0xFF) {
+	    srcDeltaNext++;
+	    delta = TclGetInt4AtPtr(srcDeltaNext);
+	    srcDeltaNext += 4;
+	} else {
+	    delta = TclGetInt1AtPtr(srcDeltaNext);
+	    srcDeltaNext++;
+	}
+	srcOffset += delta;
+
+	if ((unsigned) *srcLengthNext == (unsigned) 0xFF) {
+	    srcLengthNext++;
+	    srcLen = TclGetInt4AtPtr(srcLengthNext);
+	    srcLengthNext += 4;
+	} else {
+	    srcLen = TclGetInt1AtPtr(srcLengthNext);
+	    srcLengthNext++;
+	}
+
+	Tcl_AppendPrintfToObj(bufferObj, "%s%4d: pc %d-%d, src %d-%d",
+		((i % 2)? "     " : "\n   "),
+		(i+1), codeOffset, (codeOffset + codeLen - 1),
+		srcOffset, (srcOffset + srcLen - 1));
+    }
+    if (numCmds > 0) {
+	Tcl_AppendToObj(bufferObj, "\n", -1);
+    }
+
+    /*
+     * Print each instruction. If the instruction corresponds to the start of
+     * a command, print the command's source. Note that we don't need the code
+     * length here.
+     */
+
+    codeDeltaNext = codePtr->codeDeltaStart;
+    srcDeltaNext = codePtr->srcDeltaStart;
+    srcLengthNext = codePtr->srcLengthStart;
+    codeOffset = srcOffset = 0;
+    pc = codeStart;
+    for (i = 0;  i < numCmds;  i++) {
+	if ((unsigned) *codeDeltaNext == (unsigned) 0xFF) {
+	    codeDeltaNext++;
+	    delta = TclGetInt4AtPtr(codeDeltaNext);
+	    codeDeltaNext += 4;
+	} else {
+	    delta = TclGetInt1AtPtr(codeDeltaNext);
+	    codeDeltaNext++;
+	}
+	codeOffset += delta;
+
+	if ((unsigned) *srcDeltaNext == (unsigned) 0xFF) {
+	    srcDeltaNext++;
+	    delta = TclGetInt4AtPtr(srcDeltaNext);
+	    srcDeltaNext += 4;
+	} else {
+	    delta = TclGetInt1AtPtr(srcDeltaNext);
+	    srcDeltaNext++;
+	}
+	srcOffset += delta;
+
+	if ((unsigned) *srcLengthNext == (unsigned) 0xFF) {
+	    srcLengthNext++;
+	    srcLen = TclGetInt4AtPtr(srcLengthNext);
+	    srcLengthNext += 4;
+	} else {
+	    srcLen = TclGetInt1AtPtr(srcLengthNext);
+	    srcLengthNext++;
+	}
+
+	/*
+	 * Print instructions before command i.
+	 */
+
+	while ((pc-codeStart) < codeOffset) {
+	    Tcl_AppendToObj(bufferObj, "    ", -1);
+	    pc += FormatInstruction(codePtr, pc, bufferObj);
+	}
+
+	Tcl_AppendPrintfToObj(bufferObj, "  Command %d: ", i+1);
+	PrintSourceToObj(bufferObj, (codePtr->source + srcOffset),
+		TclMin(srcLen, 55));
+	Tcl_AppendToObj(bufferObj, "\n", -1);
+    }
+    if (pc < codeLimit) {
+	/*
+	 * Print instructions after the last command.
+	 */
+
+	while (pc < codeLimit) {
+	    Tcl_AppendToObj(bufferObj, "    ", -1);
+	    pc += FormatInstruction(codePtr, pc, bufferObj);
+	}
+    }
+    return bufferObj;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * FormatInstruction --
+ *
+ *	Appends a representation of a bytecode instruction to a Tcl_Obj.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+FormatInstruction(
+    ByteCode *codePtr,		/* Bytecode containing the instruction. */
+    const unsigned char *pc,	/* Points to first byte of instruction. */
+    Tcl_Obj *bufferObj)		/* Object to append instruction info to. */
+{
+    Proc *procPtr = codePtr->procPtr;
+    unsigned char opCode = *pc;
+    register const InstructionDesc *instDesc = &tclInstructionTable[opCode];
+    unsigned char *codeStart = codePtr->codeStart;
+    unsigned pcOffset = pc - codeStart;
+    int opnd = 0, i, j, numBytes = 1;
+    int localCt = procPtr ? procPtr->numCompiledLocals : 0;
+    CompiledLocal *localPtr = procPtr ? procPtr->firstLocalPtr : NULL;
+    char suffixBuffer[128];	/* Additional info to print after main opcode
+				 * and immediates. */
+    char *suffixSrc = NULL;
+    Tcl_Obj *suffixObj = NULL;
+    AuxData *auxPtr = NULL;
+
+    suffixBuffer[0] = '\0';
+    Tcl_AppendPrintfToObj(bufferObj, "(%u) %s ", pcOffset, instDesc->name);
+    for (i = 0;  i < instDesc->numOperands;  i++) {
+	switch (instDesc->opTypes[i]) {
+	case OPERAND_INT1:
+	    opnd = TclGetInt1AtPtr(pc+numBytes); numBytes++;
+	    Tcl_AppendPrintfToObj(bufferObj, "%+d ", opnd);
+	    break;
+	case OPERAND_INT4:
+	    opnd = TclGetInt4AtPtr(pc+numBytes); numBytes += 4;
+	    Tcl_AppendPrintfToObj(bufferObj, "%+d ", opnd);
+	    break;
+	case OPERAND_UINT1:
+	    opnd = TclGetUInt1AtPtr(pc+numBytes); numBytes++;
+	    Tcl_AppendPrintfToObj(bufferObj, "%u ", (unsigned) opnd);
+	    break;
+	case OPERAND_UINT4:
+	    opnd = TclGetUInt4AtPtr(pc+numBytes); numBytes += 4;
+	    if (opCode == INST_START_CMD) {
+		sprintf(suffixBuffer+strlen(suffixBuffer),
+			", %u cmds start here", opnd);
+	    }
+	    Tcl_AppendPrintfToObj(bufferObj, "%u ", (unsigned) opnd);
+	    break;
+	case OPERAND_OFFSET1:
+	    opnd = TclGetInt1AtPtr(pc+numBytes); numBytes++;
+	    sprintf(suffixBuffer, "pc %u", pcOffset+opnd);
+	    Tcl_AppendPrintfToObj(bufferObj, "%+d ", opnd);
+	    break;
+	case OPERAND_OFFSET4:
+	    opnd = TclGetInt4AtPtr(pc+numBytes); numBytes += 4;
+	    if (opCode == INST_START_CMD) {
+		sprintf(suffixBuffer, "next cmd at pc %u", pcOffset+opnd);
+	    } else {
+		sprintf(suffixBuffer, "pc %u", pcOffset+opnd);
+	    }
+	    Tcl_AppendPrintfToObj(bufferObj, "%+d ", opnd);
+	    break;
+	case OPERAND_LIT1:
+	    opnd = TclGetUInt1AtPtr(pc+numBytes); numBytes++;
+	    suffixObj = codePtr->objArrayPtr[opnd];
+	    Tcl_AppendPrintfToObj(bufferObj, "%u ", (unsigned) opnd);
+	    break;
+	case OPERAND_LIT4:
+	    opnd = TclGetUInt4AtPtr(pc+numBytes); numBytes += 4;
+	    suffixObj = codePtr->objArrayPtr[opnd];
+	    Tcl_AppendPrintfToObj(bufferObj, "%u ", (unsigned) opnd);
+	    break;
+	case OPERAND_AUX4:
+	    opnd = TclGetUInt4AtPtr(pc+numBytes); numBytes += 4;
+	    Tcl_AppendPrintfToObj(bufferObj, "%u ", (unsigned) opnd);
+	    auxPtr = &codePtr->auxDataArrayPtr[opnd];
+	    break;
+	case OPERAND_IDX4:
+	    opnd = TclGetInt4AtPtr(pc+numBytes); numBytes += 4;
+	    if (opnd >= -1) {
+		Tcl_AppendPrintfToObj(bufferObj, "%d ", opnd);
+	    } else if (opnd == -2) {
+		Tcl_AppendPrintfToObj(bufferObj, "end ");
+	    } else {
+		Tcl_AppendPrintfToObj(bufferObj, "end-%d ", -2-opnd);
+	    }
+	    break;
+	case OPERAND_LVT1:
+	    opnd = TclGetUInt1AtPtr(pc+numBytes);
+	    numBytes++;
+	    goto printLVTindex;
+	case OPERAND_LVT4:
+	    opnd = TclGetUInt4AtPtr(pc+numBytes);
+	    numBytes += 4;
+	printLVTindex:
+	    if (localPtr != NULL) {
+		if (opnd >= localCt) {
+		    Tcl_Panic("FormatInstruction: bad local var index %u (%u locals)",
+			    (unsigned) opnd, localCt);
+		}
+		for (j = 0;  j < opnd;  j++) {
+		    localPtr = localPtr->nextPtr;
+		}
+		if (TclIsVarTemporary(localPtr)) {
+		    sprintf(suffixBuffer, "temp var %u", (unsigned) opnd);
+		} else {
+		    sprintf(suffixBuffer, "var ");
+		    suffixSrc = localPtr->name;
+		}
+	    }
+	    Tcl_AppendPrintfToObj(bufferObj, "%%v%u ", (unsigned) opnd);
+	    break;
+	case OPERAND_SCLS1:
+	    opnd = TclGetUInt1AtPtr(pc+numBytes); numBytes++;
+	    Tcl_AppendPrintfToObj(bufferObj, "%s ",
+		    tclStringClassTable[opnd].name);
+	    break;
+	case OPERAND_NONE:
+	default:
+	    break;
+	}
+    }
+    if (suffixObj) {
+	const char *bytes;
+	int length;
+
+	Tcl_AppendToObj(bufferObj, "\t# ", -1);
+	bytes = Tcl_GetStringFromObj(codePtr->objArrayPtr[opnd], &length);
+	PrintSourceToObj(bufferObj, bytes, TclMin(length, 40));
+    } else if (suffixBuffer[0]) {
+	Tcl_AppendPrintfToObj(bufferObj, "\t# %s", suffixBuffer);
+	if (suffixSrc) {
+	    PrintSourceToObj(bufferObj, suffixSrc, 40);
+	}
+    }
+    Tcl_AppendToObj(bufferObj, "\n", -1);
+    if (auxPtr && auxPtr->type->printProc) {
+	Tcl_AppendToObj(bufferObj, "\t\t[", -1);
+	auxPtr->type->printProc(auxPtr->clientData, bufferObj, codePtr,
+		pcOffset);
+	Tcl_AppendToObj(bufferObj, "]\n", -1);
+    }
+    return numBytes;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclGetInnerContext --
+ *
+ *	If possible, returns a list capturing the inner context. Otherwise
+ *	return NULL.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_Obj *
+TclGetInnerContext(
+    Tcl_Interp *interp,
+    const unsigned char *pc,
+    Tcl_Obj **tosPtr)
+{
+    int objc = 0, off = 0;
+    Tcl_Obj *result;
+    Interp *iPtr = (Interp *) interp;
+
+    switch (*pc) {
+    case INST_STR_LEN:
+    case INST_LNOT:
+    case INST_BITNOT:
+    case INST_UMINUS:
+    case INST_UPLUS:
+    case INST_TRY_CVT_TO_NUMERIC:
+    case INST_EXPAND_STKTOP:
+    case INST_EXPR_STK:
+        objc = 1;
+        break;
+
+    case INST_LIST_IN:
+    case INST_LIST_NOT_IN:	/* Basic list containment operators. */
+    case INST_STR_EQ:
+    case INST_STR_NEQ:		/* String (in)equality check */
+    case INST_STR_CMP:		/* String compare. */
+    case INST_STR_INDEX:
+    case INST_STR_MATCH:
+    case INST_REGEXP:
+    case INST_EQ:
+    case INST_NEQ:
+    case INST_LT:
+    case INST_GT:
+    case INST_LE:
+    case INST_GE:
+    case INST_MOD:
+    case INST_LSHIFT:
+    case INST_RSHIFT:
+    case INST_BITOR:
+    case INST_BITXOR:
+    case INST_BITAND:
+    case INST_EXPON:
+    case INST_ADD:
+    case INST_SUB:
+    case INST_DIV:
+    case INST_MULT:
+        objc = 2;
+        break;
+
+    case INST_RETURN_STK:
+        /* early pop. TODO: dig out opt dict too :/ */
+        objc = 1;
+        break;
+
+    case INST_SYNTAX:
+    case INST_RETURN_IMM:
+        objc = 2;
+        break;
+
+    case INST_INVOKE_STK4:
+	objc = TclGetUInt4AtPtr(pc+1);
+        break;
+
+    case INST_INVOKE_STK1:
+	objc = TclGetUInt1AtPtr(pc+1);
+	break;
+    }
+
+    result = iPtr->innerContext;
+    if (Tcl_IsShared(result)) {
+        Tcl_DecrRefCount(result);
+        iPtr->innerContext = result = Tcl_NewListObj(objc + 1, NULL);
+        Tcl_IncrRefCount(result);
+    } else {
+        int len;
+
+        /*
+         * Reset while keeping the list intrep as much as possible.
+         */
+
+	Tcl_ListObjLength(interp, result, &len);
+        Tcl_ListObjReplace(interp, result, 0, len, 0, NULL);
+    }
+    Tcl_ListObjAppendElement(NULL, result, TclNewInstNameObj(*pc));
+
+    for (; objc>0 ; objc--) {
+        Tcl_Obj *objPtr;
+
+        objPtr = tosPtr[1 - objc + off];
+        if (!objPtr) {
+            Tcl_Panic("InnerContext: bad tos -- appending null object");
+        }
+        if ((objPtr->refCount<=0)
+#ifdef TCL_MEM_DEBUG
+                || (objPtr->refCount==0x61616161)
+#endif
+        ) {
+            Tcl_Panic("InnerContext: bad tos -- appending freed object %p",
+                    objPtr);
+        }
+        Tcl_ListObjAppendElement(NULL, result, objPtr);
+    }
+
+    return result;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclNewInstNameObj --
+ *
+ *	Creates a new InstName Tcl_Obj based on the given instruction
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_Obj *
+TclNewInstNameObj(
+    unsigned char inst)
+{
+    Tcl_Obj *objPtr = Tcl_NewObj();
+
+    objPtr->typePtr = &tclInstNameType;
+    objPtr->internalRep.longValue = (long) inst;
+    objPtr->bytes = NULL;
+
+    return objPtr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * UpdateStringOfInstName --
+ *
+ *	Update the string representation for an instruction name object.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+UpdateStringOfInstName(
+    Tcl_Obj *objPtr)
+{
+    int inst = objPtr->internalRep.longValue;
+    char *s, buf[20];
+    int len;
+
+    if ((inst < 0) || (inst > LAST_INST_OPCODE)) {
+        sprintf(buf, "inst_%d", inst);
+        s = buf;
+    } else {
+        s = (char *) tclInstructionTable[objPtr->internalRep.longValue].name;
+    }
+    len = strlen(s);
+    objPtr->bytes = ckalloc(len + 1);
+    memcpy(objPtr->bytes, s, len + 1);
+    objPtr->length = len;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * PrintSourceToObj --
+ *
+ *	Appends a quoted representation of a string to a Tcl_Obj.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+PrintSourceToObj(
+    Tcl_Obj *appendObj,		/* The object to print the source to. */
+    const char *stringPtr,	/* The string to print. */
+    int maxChars)		/* Maximum number of chars to print. */
+{
+    register const char *p;
+    register int i = 0, len;
+    Tcl_UniChar ch = 0;
+
+    if (stringPtr == NULL) {
+	Tcl_AppendToObj(appendObj, "\"\"", -1);
+	return;
+    }
+
+    Tcl_AppendToObj(appendObj, "\"", -1);
+    p = stringPtr;
+    for (;  (*p != '\0') && (i < maxChars);  p+=len) {
+
+	len = TclUtfToUniChar(p, &ch);
+	switch (ch) {
+	case '"':
+	    Tcl_AppendToObj(appendObj, "\\\"", -1);
+	    i += 2;
+	    continue;
+	case '\f':
+	    Tcl_AppendToObj(appendObj, "\\f", -1);
+	    i += 2;
+	    continue;
+	case '\n':
+	    Tcl_AppendToObj(appendObj, "\\n", -1);
+	    i += 2;
+	    continue;
+	case '\r':
+	    Tcl_AppendToObj(appendObj, "\\r", -1);
+	    i += 2;
+	    continue;
+	case '\t':
+	    Tcl_AppendToObj(appendObj, "\\t", -1);
+	    i += 2;
+	    continue;
+	case '\v':
+	    Tcl_AppendToObj(appendObj, "\\v", -1);
+	    i += 2;
+	    continue;
+	default:
+#if TCL_UTF_MAX > 4
+	    if (ch > 0xffff) {
+		Tcl_AppendPrintfToObj(appendObj, "\\U%08x", ch);
+		i += 10;
+	    } else
+#elif TCL_UTF_MAX > 3
+	    /* If len == 0, this means we have a char > 0xffff, resulting in
+	     * TclUtfToUniChar producing a surrogate pair. We want to output
+	     * this pair as a single Unicode character.
+	     */
+	    if (len == 0) {
+		int upper = ((ch & 0x3ff) + 1) << 10;
+		len = TclUtfToUniChar(p, &ch);
+		Tcl_AppendPrintfToObj(appendObj, "\\U%08x", upper + (ch & 0x3ff));
+		i += 10;
+	    } else
+#endif
+	    if (ch < 0x20 || ch >= 0x7f) {
+		Tcl_AppendPrintfToObj(appendObj, "\\u%04x", ch);
+		i += 6;
+	    } else {
+		Tcl_AppendPrintfToObj(appendObj, "%c", ch);
+		i++;
+	    }
+	    continue;
+	}
+    }
+    if (*p != '\0') {
+	Tcl_AppendToObj(appendObj, "...", -1);
+    }
+    Tcl_AppendToObj(appendObj, "\"", -1);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * DisassembleByteCodeAsDicts --
+ *
+ *	Given an object which is of bytecode type, return a disassembled
+ *	version of the bytecode (in a new refcount 0 object) in a dictionary.
+ *	No guarantees are made about the details of the contents of the
+ *	result, but it is intended to be more readable than the old output
+ *	format.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static Tcl_Obj *
+DisassembleByteCodeAsDicts(
+    Tcl_Interp *interp,		/* Used for looking up the CmdFrame for the
+				 * procedure, if one exists. */
+    Tcl_Obj *objPtr)		/* The bytecode-holding value to take apart */
+{
+    ByteCode *codePtr = BYTECODE(objPtr);
+    Tcl_Obj *description, *literals, *variables, *instructions, *inst;
+    Tcl_Obj *aux, *exn, *commands, *file;
+    unsigned char *pc, *opnd, *codeOffPtr, *codeLenPtr, *srcOffPtr, *srcLenPtr;
+    int codeOffset, codeLength, sourceOffset, sourceLength;
+    int i, val, line;
+
+    /*
+     * Get the literals from the bytecode.
+     */
+
+    literals = Tcl_NewObj();
+    for (i=0 ; i<codePtr->numLitObjects ; i++) {
+	Tcl_ListObjAppendElement(NULL, literals, codePtr->objArrayPtr[i]);
+    }
+
+    /*
+     * Get the variables from the bytecode.
+     */
+
+    variables = Tcl_NewObj();
+    if (codePtr->procPtr) {
+	int localCount = codePtr->procPtr->numCompiledLocals;
+	CompiledLocal *localPtr = codePtr->procPtr->firstLocalPtr;
+
+	for (i=0 ; i<localCount ; i++,localPtr=localPtr->nextPtr) {
+	    Tcl_Obj *descriptor[2];
+
+	    descriptor[0] = Tcl_NewObj();
+	    if (!(localPtr->flags & (VAR_ARRAY|VAR_LINK))) {
+		Tcl_ListObjAppendElement(NULL, descriptor[0],
+			Tcl_NewStringObj("scalar", -1));
+	    }
+	    if (localPtr->flags & VAR_ARRAY) {
+		Tcl_ListObjAppendElement(NULL, descriptor[0],
+			Tcl_NewStringObj("array", -1));
+	    }
+	    if (localPtr->flags & VAR_LINK) {
+		Tcl_ListObjAppendElement(NULL, descriptor[0],
+			Tcl_NewStringObj("link", -1));
+	    }
+	    if (localPtr->flags & VAR_ARGUMENT) {
+		Tcl_ListObjAppendElement(NULL, descriptor[0],
+			Tcl_NewStringObj("arg", -1));
+	    }
+	    if (localPtr->flags & VAR_TEMPORARY) {
+		Tcl_ListObjAppendElement(NULL, descriptor[0],
+			Tcl_NewStringObj("temp", -1));
+	    }
+	    if (localPtr->flags & VAR_RESOLVED) {
+		Tcl_ListObjAppendElement(NULL, descriptor[0],
+			Tcl_NewStringObj("resolved", -1));
+	    }
+	    if (localPtr->flags & VAR_TEMPORARY) {
+		Tcl_ListObjAppendElement(NULL, variables,
+			Tcl_NewListObj(1, descriptor));
+	    } else {
+		descriptor[1] = Tcl_NewStringObj(localPtr->name, -1);
+		Tcl_ListObjAppendElement(NULL, variables,
+			Tcl_NewListObj(2, descriptor));
+	    }
+	}
+    }
+
+    /*
+     * Get the instructions from the bytecode.
+     */
+
+    instructions = Tcl_NewObj();
+    for (pc=codePtr->codeStart; pc<codePtr->codeStart+codePtr->numCodeBytes;){
+	const InstructionDesc *instDesc = &tclInstructionTable[*pc];
+	int address = pc - codePtr->codeStart;
+
+	inst = Tcl_NewObj();
+	Tcl_ListObjAppendElement(NULL, inst, Tcl_NewStringObj(
+		instDesc->name, -1));
+	opnd = pc + 1;
+	for (i=0 ; i<instDesc->numOperands ; i++) {
+	    switch (instDesc->opTypes[i]) {
+	    case OPERAND_INT1:
+		val = TclGetInt1AtPtr(opnd);
+		opnd += 1;
+		goto formatNumber;
+	    case OPERAND_UINT1:
+		val = TclGetUInt1AtPtr(opnd);
+		opnd += 1;
+		goto formatNumber;
+	    case OPERAND_INT4:
+		val = TclGetInt4AtPtr(opnd);
+		opnd += 4;
+		goto formatNumber;
+	    case OPERAND_UINT4:
+		val = TclGetUInt4AtPtr(opnd);
+		opnd += 4;
+	    formatNumber:
+		Tcl_ListObjAppendElement(NULL, inst, Tcl_NewIntObj(val));
+		break;
+
+	    case OPERAND_OFFSET1:
+		val = TclGetInt1AtPtr(opnd);
+		opnd += 1;
+		goto formatAddress;
+	    case OPERAND_OFFSET4:
+		val = TclGetInt4AtPtr(opnd);
+		opnd += 4;
+	    formatAddress:
+		Tcl_ListObjAppendElement(NULL, inst, Tcl_ObjPrintf(
+			"pc %d", address + val));
+		break;
+
+	    case OPERAND_LIT1:
+		val = TclGetUInt1AtPtr(opnd);
+		opnd += 1;
+		goto formatLiteral;
+	    case OPERAND_LIT4:
+		val = TclGetUInt4AtPtr(opnd);
+		opnd += 4;
+	    formatLiteral:
+		Tcl_ListObjAppendElement(NULL, inst, Tcl_ObjPrintf(
+			"@%d", val));
+		break;
+
+	    case OPERAND_LVT1:
+		val = TclGetUInt1AtPtr(opnd);
+		opnd += 1;
+		goto formatVariable;
+	    case OPERAND_LVT4:
+		val = TclGetUInt4AtPtr(opnd);
+		opnd += 4;
+	    formatVariable:
+		Tcl_ListObjAppendElement(NULL, inst, Tcl_ObjPrintf(
+			"%%%d", val));
+		break;
+	    case OPERAND_IDX4:
+		val = TclGetInt4AtPtr(opnd);
+		opnd += 4;
+		if (val >= -1) {
+		    Tcl_ListObjAppendElement(NULL, inst, Tcl_ObjPrintf(
+			    ".%d", val));
+		} else if (val == -2) {
+		    Tcl_ListObjAppendElement(NULL, inst, Tcl_NewStringObj(
+			    ".end", -1));
+		} else {
+		    Tcl_ListObjAppendElement(NULL, inst, Tcl_ObjPrintf(
+			    ".end-%d", -2-val));
+		}
+		break;
+	    case OPERAND_AUX4:
+		val = TclGetInt4AtPtr(opnd);
+		opnd += 4;
+		Tcl_ListObjAppendElement(NULL, inst, Tcl_ObjPrintf(
+			"?%d", val));
+		break;
+	    case OPERAND_SCLS1:
+		val = TclGetUInt1AtPtr(opnd);
+		opnd++;
+		Tcl_ListObjAppendElement(NULL, inst, Tcl_ObjPrintf(
+			"=%s", tclStringClassTable[val].name));
+		break;
+	    case OPERAND_NONE:
+		Tcl_Panic("opcode %d with more than zero 'no' operands", *pc);
+	    }
+	}
+	Tcl_DictObjPut(NULL, instructions, Tcl_NewIntObj(address), inst);
+	pc += instDesc->numBytes;
+    }
+
+    /*
+     * Get the auxiliary data from the bytecode.
+     */
+
+    aux = Tcl_NewObj();
+    for (i=0 ; i<codePtr->numAuxDataItems ; i++) {
+	AuxData *auxData = &codePtr->auxDataArrayPtr[i];
+	Tcl_Obj *auxDesc = Tcl_NewStringObj(auxData->type->name, -1);
+
+	if (auxData->type->disassembleProc) {
+	    Tcl_Obj *desc = Tcl_NewObj();
+
+	    Tcl_DictObjPut(NULL, desc, Tcl_NewStringObj("name", -1), auxDesc);
+	    auxDesc = desc;
+	    auxData->type->disassembleProc(auxData->clientData, auxDesc,
+		    codePtr, 0);
+	} else if (auxData->type->printProc) {
+	    Tcl_Obj *desc = Tcl_NewObj();
+
+	    auxData->type->printProc(auxData->clientData, desc, codePtr, 0);
+	    Tcl_ListObjAppendElement(NULL, auxDesc, desc);
+	}
+	Tcl_ListObjAppendElement(NULL, aux, auxDesc);
+    }
+
+    /*
+     * Get the exception ranges from the bytecode.
+     */
+
+    exn = Tcl_NewObj();
+    for (i=0 ; i<codePtr->numExceptRanges ; i++) {
+	ExceptionRange *rangePtr = &codePtr->exceptArrayPtr[i];
+
+	switch (rangePtr->type) {
+	case LOOP_EXCEPTION_RANGE:
+	    Tcl_ListObjAppendElement(NULL, exn, Tcl_ObjPrintf(
+		    "type %s level %d from %d to %d break %d continue %d",
+		    "loop", rangePtr->nestingLevel, rangePtr->codeOffset,
+		    rangePtr->codeOffset + rangePtr->numCodeBytes - 1,
+		    rangePtr->breakOffset, rangePtr->continueOffset));
+	    break;
+	case CATCH_EXCEPTION_RANGE:
+	    Tcl_ListObjAppendElement(NULL, exn, Tcl_ObjPrintf(
+		    "type %s level %d from %d to %d catch %d",
+		    "catch", rangePtr->nestingLevel, rangePtr->codeOffset,
+		    rangePtr->codeOffset + rangePtr->numCodeBytes - 1,
+		    rangePtr->catchOffset));
+	    break;
+	}
+    }
+
+    /*
+     * Get the command information from the bytecode.
+     *
+     * The way these are encoded in the bytecode is non-trivial; the Decode
+     * macro (which updates its argument and returns the next decoded value)
+     * handles this so that the rest of the code does not.
+     */
+
+#define Decode(ptr) \
+    ((TclGetUInt1AtPtr(ptr) == 0xFF)			\
+	? ((ptr)+=5 , TclGetInt4AtPtr((ptr)-4))		\
+	: ((ptr)+=1 , TclGetInt1AtPtr((ptr)-1)))
+
+    commands = Tcl_NewObj();
+    codeOffPtr = codePtr->codeDeltaStart;
+    codeLenPtr = codePtr->codeLengthStart;
+    srcOffPtr = codePtr->srcDeltaStart;
+    srcLenPtr = codePtr->srcLengthStart;
+    codeOffset = sourceOffset = 0;
+    for (i=0 ; i<codePtr->numCommands ; i++) {
+	Tcl_Obj *cmd;
+
+	codeOffset += Decode(codeOffPtr);
+	codeLength = Decode(codeLenPtr);
+	sourceOffset += Decode(srcOffPtr);
+	sourceLength = Decode(srcLenPtr);
+	cmd = Tcl_NewObj();
+	Tcl_DictObjPut(NULL, cmd, Tcl_NewStringObj("codefrom", -1),
+		Tcl_NewIntObj(codeOffset));
+	Tcl_DictObjPut(NULL, cmd, Tcl_NewStringObj("codeto", -1),
+		Tcl_NewIntObj(codeOffset + codeLength - 1));
+
+	/*
+	 * Convert byte offsets to character offsets; important if multibyte
+	 * characters are present in the source!
+	 */
+
+	Tcl_DictObjPut(NULL, cmd, Tcl_NewStringObj("scriptfrom", -1),
+		Tcl_NewIntObj(Tcl_NumUtfChars(codePtr->source,
+			sourceOffset)));
+	Tcl_DictObjPut(NULL, cmd, Tcl_NewStringObj("scriptto", -1),
+		Tcl_NewIntObj(Tcl_NumUtfChars(codePtr->source,
+			sourceOffset + sourceLength - 1)));
+	Tcl_DictObjPut(NULL, cmd, Tcl_NewStringObj("script", -1),
+		Tcl_NewStringObj(codePtr->source+sourceOffset, sourceLength));
+	Tcl_ListObjAppendElement(NULL, commands, cmd);
+    }
+
+#undef Decode
+
+    /*
+     * Get the source file and line number information from the CmdFrame
+     * system if it is available.
+     */
+
+    GetLocationInformation(interp, codePtr->procPtr, &file, &line);
+
+    /*
+     * Build the overall result.
+     */
+
+    description = Tcl_NewObj();
+    Tcl_DictObjPut(NULL, description, Tcl_NewStringObj("literals", -1),
+	    literals);
+    Tcl_DictObjPut(NULL, description, Tcl_NewStringObj("variables", -1),
+	    variables);
+    Tcl_DictObjPut(NULL, description, Tcl_NewStringObj("exception", -1), exn);
+    Tcl_DictObjPut(NULL, description, Tcl_NewStringObj("instructions", -1),
+	    instructions);
+    Tcl_DictObjPut(NULL, description, Tcl_NewStringObj("auxiliary", -1), aux);
+    Tcl_DictObjPut(NULL, description, Tcl_NewStringObj("commands", -1),
+	    commands);
+    Tcl_DictObjPut(NULL, description, Tcl_NewStringObj("script", -1),
+	    Tcl_NewStringObj(codePtr->source, codePtr->numSrcBytes));
+    Tcl_DictObjPut(NULL, description, Tcl_NewStringObj("namespace", -1),
+	    Tcl_NewStringObj(codePtr->nsPtr->fullName, -1));
+    Tcl_DictObjPut(NULL, description, Tcl_NewStringObj("stackdepth", -1),
+	    Tcl_NewIntObj(codePtr->maxStackDepth));
+    Tcl_DictObjPut(NULL, description, Tcl_NewStringObj("exceptdepth", -1),
+	    Tcl_NewIntObj(codePtr->maxExceptDepth));
+    if (line > -1) {
+	Tcl_DictObjPut(NULL, description,
+		Tcl_NewStringObj("initiallinenumber", -1),
+		Tcl_NewIntObj(line));
+    }
+    if (file) {
+	Tcl_DictObjPut(NULL, description,
+		Tcl_NewStringObj("sourcefile", -1), file);
+    }
+    return description;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_DisassembleObjCmd --
+ *
+ *	Implementation of the "::tcl::unsupported::disassemble" command. This
+ *	command is not documented, but will disassemble procedures, lambda
+ *	terms and general scripts. Note that will compile terms if necessary
+ *	in order to disassemble them.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_DisassembleObjCmd(
+    ClientData clientData,	/* What type of operation. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    static const char *const types[] = {
+	"constructor", "destructor",
+	"lambda", "method", "objmethod", "proc", "script", NULL
+    };
+    enum Types {
+	DISAS_CLASS_CONSTRUCTOR, DISAS_CLASS_DESTRUCTOR,
+	DISAS_LAMBDA, DISAS_CLASS_METHOD, DISAS_OBJECT_METHOD, DISAS_PROC,
+	DISAS_SCRIPT
+    };
+    int idx, result;
+    Tcl_Obj *codeObjPtr = NULL;
+    Proc *procPtr = NULL;
+    Tcl_HashEntry *hPtr;
+    Object *oPtr;
+    Method *methodPtr;
+
+    if (objc < 2) {
+	Tcl_WrongNumArgs(interp, 1, objv, "type ...");
+	return TCL_ERROR;
+    }
+    if (Tcl_GetIndexFromObj(interp, objv[1], types, "type", 0, &idx)!=TCL_OK){
+	return TCL_ERROR;
+    }
+
+    switch ((enum Types) idx) {
+    case DISAS_LAMBDA: {
+	Command cmd;
+	Tcl_Obj *nsObjPtr;
+	Tcl_Namespace *nsPtr;
+
+	/*
+	 * Compile (if uncompiled) and disassemble a lambda term.
+	 *
+	 * WARNING! Pokes inside the lambda objtype.
+	 */
+
+	if (objc != 3) {
+	    Tcl_WrongNumArgs(interp, 2, objv, "lambdaTerm");
+	    return TCL_ERROR;
+	}
+	if (objv[2]->typePtr == &tclLambdaType) {
+	    procPtr = objv[2]->internalRep.twoPtrValue.ptr1;
+	}
+	if (procPtr == NULL || procPtr->iPtr != (Interp *) interp) {
+	    result = tclLambdaType.setFromAnyProc(interp, objv[2]);
+	    if (result != TCL_OK) {
+		return result;
+	    }
+	    procPtr = objv[2]->internalRep.twoPtrValue.ptr1;
+	}
+
+	memset(&cmd, 0, sizeof(Command));
+	nsObjPtr = objv[2]->internalRep.twoPtrValue.ptr2;
+	result = TclGetNamespaceFromObj(interp, nsObjPtr, &nsPtr);
+	if (result != TCL_OK) {
+	    return result;
+	}
+	cmd.nsPtr = (Namespace *) nsPtr;
+	procPtr->cmdPtr = &cmd;
+	result = TclPushProcCallFrame(procPtr, interp, objc, objv, 1);
+	if (result != TCL_OK) {
+	    return result;
+	}
+	TclPopStackFrame(interp);
+	codeObjPtr = procPtr->bodyPtr;
+	break;
+    }
+    case DISAS_PROC:
+	if (objc != 3) {
+	    Tcl_WrongNumArgs(interp, 2, objv, "procName");
+	    return TCL_ERROR;
+	}
+
+	procPtr = TclFindProc((Interp *) interp, TclGetString(objv[2]));
+	if (procPtr == NULL) {
+	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		    "\"%s\" isn't a procedure", TclGetString(objv[2])));
+	    Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "PROC",
+		    TclGetString(objv[2]), NULL);
+	    return TCL_ERROR;
+	}
+
+	/*
+	 * Compile (if uncompiled) and disassemble a procedure.
+	 */
+
+	result = TclPushProcCallFrame(procPtr, interp, 2, objv+1, 1);
+	if (result != TCL_OK) {
+	    return result;
+	}
+	TclPopStackFrame(interp);
+	codeObjPtr = procPtr->bodyPtr;
+	break;
+    case DISAS_SCRIPT:
+	/*
+	 * Compile and disassemble a script.
+	 */
+
+	if (objc != 3) {
+	    Tcl_WrongNumArgs(interp, 2, objv, "script");
+	    return TCL_ERROR;
+	}
+	if ((objv[2]->typePtr != &tclByteCodeType)
+		&& (TclSetByteCodeFromAny(interp, objv[2], NULL, NULL) != TCL_OK)) {
+	    return TCL_ERROR;
+	}
+	codeObjPtr = objv[2];
+	break;
+
+    case DISAS_CLASS_CONSTRUCTOR:
+	if (objc != 3) {
+	    Tcl_WrongNumArgs(interp, 2, objv, "className");
+	    return TCL_ERROR;
+	}
+
+	/*
+	 * Look up the body of a constructor.
+	 */
+
+	oPtr = (Object *) Tcl_GetObjectFromObj(interp, objv[2]);
+	if (oPtr == NULL) {
+	    return TCL_ERROR;
+	}
+	if (oPtr->classPtr == NULL) {
+	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		    "\"%s\" is not a class", TclGetString(objv[2])));
+	    Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "CLASS",
+		    TclGetString(objv[2]), NULL);
+	    return TCL_ERROR;
+	}
+
+	methodPtr = oPtr->classPtr->constructorPtr;
+	if (methodPtr == NULL) {
+	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		    "\"%s\" has no defined constructor",
+		    TclGetString(objv[2])));
+	    Tcl_SetErrorCode(interp, "TCL", "OPERATION", "DISASSEMBLE",
+		    "CONSRUCTOR", NULL);
+	    return TCL_ERROR;
+	}
+	procPtr = TclOOGetProcFromMethod(methodPtr);
+	if (procPtr == NULL) {
+	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		    "body not available for this kind of constructor", -1));
+	    Tcl_SetErrorCode(interp, "TCL", "OPERATION", "DISASSEMBLE",
+		    "METHODTYPE", NULL);
+	    return TCL_ERROR;
+	}
+
+	/*
+	 * Compile if necessary.
+	 */
+
+	if (procPtr->bodyPtr->typePtr != &tclByteCodeType) {
+	    Command cmd;
+
+	    /*
+	     * Yes, this is ugly, but we need to pass the namespace in to the
+	     * compiler in two places.
+	     */
+
+	    cmd.nsPtr = (Namespace *) oPtr->namespacePtr;
+	    procPtr->cmdPtr = &cmd;
+	    result = TclProcCompileProc(interp, procPtr, procPtr->bodyPtr,
+		    (Namespace *) oPtr->namespacePtr, "body of constructor",
+		    TclGetString(objv[2]));
+	    procPtr->cmdPtr = NULL;
+	    if (result != TCL_OK) {
+		return result;
+	    }
+	}
+	codeObjPtr = procPtr->bodyPtr;
+	break;
+
+    case DISAS_CLASS_DESTRUCTOR:
+	if (objc != 3) {
+	    Tcl_WrongNumArgs(interp, 2, objv, "className");
+	    return TCL_ERROR;
+	}
+
+	/*
+	 * Look up the body of a destructor.
+	 */
+
+	oPtr = (Object *) Tcl_GetObjectFromObj(interp, objv[2]);
+	if (oPtr == NULL) {
+	    return TCL_ERROR;
+	}
+	if (oPtr->classPtr == NULL) {
+	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		    "\"%s\" is not a class", TclGetString(objv[2])));
+	    Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "CLASS",
+		    TclGetString(objv[2]), NULL);
+	    return TCL_ERROR;
+	}
+
+	methodPtr = oPtr->classPtr->destructorPtr;
+	if (methodPtr == NULL) {
+	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		    "\"%s\" has no defined destructor",
+		    TclGetString(objv[2])));
+	    Tcl_SetErrorCode(interp, "TCL", "OPERATION", "DISASSEMBLE",
+		    "DESRUCTOR", NULL);
+	    return TCL_ERROR;
+	}
+	procPtr = TclOOGetProcFromMethod(methodPtr);
+	if (procPtr == NULL) {
+	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		    "body not available for this kind of destructor", -1));
+	    Tcl_SetErrorCode(interp, "TCL", "OPERATION", "DISASSEMBLE",
+		    "METHODTYPE", NULL);
+	    return TCL_ERROR;
+	}
+
+	/*
+	 * Compile if necessary.
+	 */
+
+	if (procPtr->bodyPtr->typePtr != &tclByteCodeType) {
+	    Command cmd;
+
+	    /*
+	     * Yes, this is ugly, but we need to pass the namespace in to the
+	     * compiler in two places.
+	     */
+
+	    cmd.nsPtr = (Namespace *) oPtr->namespacePtr;
+	    procPtr->cmdPtr = &cmd;
+	    result = TclProcCompileProc(interp, procPtr, procPtr->bodyPtr,
+		    (Namespace *) oPtr->namespacePtr, "body of destructor",
+		    TclGetString(objv[2]));
+	    procPtr->cmdPtr = NULL;
+	    if (result != TCL_OK) {
+		return result;
+	    }
+	}
+	codeObjPtr = procPtr->bodyPtr;
+	break;
+
+    case DISAS_CLASS_METHOD:
+	if (objc != 4) {
+	    Tcl_WrongNumArgs(interp, 2, objv, "className methodName");
+	    return TCL_ERROR;
+	}
+
+	/*
+	 * Look up the body of a class method.
+	 */
+
+	oPtr = (Object *) Tcl_GetObjectFromObj(interp, objv[2]);
+	if (oPtr == NULL) {
+	    return TCL_ERROR;
+	}
+	if (oPtr->classPtr == NULL) {
+	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		    "\"%s\" is not a class", TclGetString(objv[2])));
+	    Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "CLASS",
+		    TclGetString(objv[2]), NULL);
+	    return TCL_ERROR;
+	}
+	hPtr = Tcl_FindHashEntry(&oPtr->classPtr->classMethods,
+		(char *) objv[3]);
+	goto methodBody;
+    case DISAS_OBJECT_METHOD:
+	if (objc != 4) {
+	    Tcl_WrongNumArgs(interp, 2, objv, "objectName methodName");
+	    return TCL_ERROR;
+	}
+
+	/*
+	 * Look up the body of an instance method.
+	 */
+
+	oPtr = (Object *) Tcl_GetObjectFromObj(interp, objv[2]);
+	if (oPtr == NULL) {
+	    return TCL_ERROR;
+	}
+	if (oPtr->methodsPtr == NULL) {
+	    goto unknownMethod;
+	}
+	hPtr = Tcl_FindHashEntry(oPtr->methodsPtr, (char *) objv[3]);
+
+	/*
+	 * Compile (if necessary) and disassemble a method body.
+	 */
+
+    methodBody:
+	if (hPtr == NULL) {
+	unknownMethod:
+	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		    "unknown method \"%s\"", TclGetString(objv[3])));
+	    Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "METHOD",
+		    TclGetString(objv[3]), NULL);
+	    return TCL_ERROR;
+	}
+	procPtr = TclOOGetProcFromMethod(Tcl_GetHashValue(hPtr));
+	if (procPtr == NULL) {
+	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		    "body not available for this kind of method", -1));
+	    Tcl_SetErrorCode(interp, "TCL", "OPERATION", "DISASSEMBLE",
+		    "METHODTYPE", NULL);
+	    return TCL_ERROR;
+	}
+	if (procPtr->bodyPtr->typePtr != &tclByteCodeType) {
+	    Command cmd;
+
+	    /*
+	     * Yes, this is ugly, but we need to pass the namespace in to the
+	     * compiler in two places.
+	     */
+
+	    cmd.nsPtr = (Namespace *) oPtr->namespacePtr;
+	    procPtr->cmdPtr = &cmd;
+	    result = TclProcCompileProc(interp, procPtr, procPtr->bodyPtr,
+		    (Namespace *) oPtr->namespacePtr, "body of method",
+		    TclGetString(objv[3]));
+	    procPtr->cmdPtr = NULL;
+	    if (result != TCL_OK) {
+		return result;
+	    }
+	}
+	codeObjPtr = procPtr->bodyPtr;
+	break;
+    default:
+	CLANG_ASSERT(0);
+    }
+
+    /*
+     * Do the actual disassembly.
+     */
+
+    if (BYTECODE(codeObjPtr)->flags & TCL_BYTECODE_PRECOMPILED) {
+	Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		"may not disassemble prebuilt bytecode", -1));
+	Tcl_SetErrorCode(interp, "TCL", "OPERATION", "DISASSEMBLE",
+		"BYTECODE", NULL);
+	return TCL_ERROR;
+    }
+    if (PTR2INT(clientData)) {
+	Tcl_SetObjResult(interp,
+		DisassembleByteCodeAsDicts(interp, codeObjPtr));
+    } else {
+	Tcl_SetObjResult(interp,
+		DisassembleByteCodeObj(interp, codeObjPtr));
+    }
+    return TCL_OK;
+}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * tab-width: 8
+ * End:
+ */
diff --git a/generic/tclEncoding.c b/generic/tclEncoding.c
new file mode 100644
index 0000000..4edebcf
--- /dev/null
+++ b/generic/tclEncoding.c
@@ -0,0 +1,3649 @@
+/*
+ * tclEncoding.c --
+ *
+ *	Contains the implementation of the encoding conversion package.
+ *
+ * Copyright (c) 1996-1998 Sun Microsystems, Inc.
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#include "tclInt.h"
+
+typedef size_t (LengthProc)(const char *src);
+
+/*
+ * The following data structure represents an encoding, which describes how to
+ * convert between various character sets and UTF-8.
+ */
+
+typedef struct Encoding {
+    char *name;			/* Name of encoding. Malloced because (1) hash
+				 * table entry that owns this encoding may be
+				 * freed prior to this encoding being freed,
+				 * (2) string passed in the Tcl_EncodingType
+				 * structure may not be persistent. */
+    Tcl_EncodingConvertProc *toUtfProc;
+				/* Function to convert from external encoding
+				 * into UTF-8. */
+    Tcl_EncodingConvertProc *fromUtfProc;
+				/* Function to convert from UTF-8 into
+				 * external encoding. */
+    Tcl_EncodingFreeProc *freeProc;
+				/* If non-NULL, function to call when this
+				 * encoding is deleted. */
+    int nullSize;		/* Number of 0x00 bytes that signify
+				 * end-of-string in this encoding. This number
+				 * is used to determine the source string
+				 * length when the srcLen argument is
+				 * negative. This number can be 1 or 2. */
+    ClientData clientData;	/* Arbitrary value associated with encoding
+				 * type. Passed to conversion functions. */
+    LengthProc *lengthProc;	/* Function to compute length of
+				 * null-terminated strings in this encoding.
+				 * If nullSize is 1, this is strlen; if
+				 * nullSize is 2, this is a function that
+				 * returns the number of bytes in a 0x0000
+				 * terminated string. */
+    int refCount;		/* Number of uses of this structure. */
+    Tcl_HashEntry *hPtr;	/* Hash table entry that owns this encoding. */
+} Encoding;
+
+/*
+ * The following structure is the clientData for a dynamically-loaded,
+ * table-driven encoding created by LoadTableEncoding(). It maps between
+ * Unicode and a single-byte, double-byte, or multibyte (1 or 2 bytes only)
+ * encoding.
+ */
+
+typedef struct TableEncodingData {
+    int fallback;		/* Character (in this encoding) to substitute
+				 * when this encoding cannot represent a UTF-8
+				 * character. */
+    char prefixBytes[256];	/* If a byte in the input stream is a lead
+				 * byte for a 2-byte sequence, the
+				 * corresponding entry in this array is 1,
+				 * otherwise it is 0. */
+    unsigned short **toUnicode;	/* Two dimensional sparse matrix to map
+				 * characters from the encoding to Unicode.
+				 * Each element of the toUnicode array points
+				 * to an array of 256 shorts. If there is no
+				 * corresponding character in Unicode, the
+				 * value in the matrix is 0x0000.
+				 * malloc'd. */
+    unsigned short **fromUnicode;
+				/* Two dimensional sparse matrix to map
+				 * characters from Unicode to the encoding.
+				 * Each element of the fromUnicode array
+				 * points to an array of 256 shorts. If there
+				 * is no corresponding character the encoding,
+				 * the value in the matrix is 0x0000.
+				 * malloc'd. */
+} TableEncodingData;
+
+/*
+ * The following structures is the clientData for a dynamically-loaded,
+ * escape-driven encoding that is itself comprised of other simpler encodings.
+ * An example is "iso-2022-jp", which uses escape sequences to switch between
+ * ascii, jis0208, jis0212, gb2312, and ksc5601. Note that "escape-driven"
+ * does not necessarily mean that the ESCAPE character is the character used
+ * for switching character sets.
+ */
+
+typedef struct EscapeSubTable {
+    unsigned sequenceLen;	/* Length of following string. */
+    char sequence[16];		/* Escape code that marks this encoding. */
+    char name[32];		/* Name for encoding. */
+    Encoding *encodingPtr;	/* Encoding loaded using above name, or NULL
+				 * if this sub-encoding has not been needed
+				 * yet. */
+} EscapeSubTable;
+
+typedef struct EscapeEncodingData {
+    int fallback;		/* Character (in this encoding) to substitute
+				 * when this encoding cannot represent a UTF-8
+				 * character. */
+    unsigned initLen;		/* Length of following string. */
+    char init[16];		/* String to emit or expect before first char
+				 * in conversion. */
+    unsigned finalLen;		/* Length of following string. */
+    char final[16];		/* String to emit or expect after last char in
+				 * conversion. */
+    char prefixBytes[256];	/* If a byte in the input stream is the first
+				 * character of one of the escape sequences in
+				 * the following array, the corresponding
+				 * entry in this array is 1, otherwise it is
+				 * 0. */
+    int numSubTables;		/* Length of following array. */
+    EscapeSubTable subTables[1];/* Information about each EscapeSubTable used
+				 * by this encoding type. The actual size will
+				 * be as large as necessary to hold all
+				 * EscapeSubTables. */
+} EscapeEncodingData;
+
+/*
+ * Constants used when loading an encoding file to identify the type of the
+ * file.
+ */
+
+#define ENCODING_SINGLEBYTE	0
+#define ENCODING_DOUBLEBYTE	1
+#define ENCODING_MULTIBYTE	2
+#define ENCODING_ESCAPE		3
+
+/*
+ * A list of directories in which Tcl should look for *.enc files. This list
+ * is shared by all threads. Access is governed by a mutex lock.
+ */
+
+static TclInitProcessGlobalValueProc InitializeEncodingSearchPath;
+static ProcessGlobalValue encodingSearchPath = {
+    0, 0, NULL, NULL, InitializeEncodingSearchPath, NULL, NULL
+};
+
+/*
+ * A map from encoding names to the directories in which their data files have
+ * been seen. The string value of the map is shared by all threads. Access to
+ * the shared string is governed by a mutex lock.
+ */
+
+static ProcessGlobalValue encodingFileMap = {
+    0, 0, NULL, NULL, NULL, NULL, NULL
+};
+
+/*
+ * A list of directories making up the "library path". Historically this
+ * search path has served many uses, but the only one remaining is a base for
+ * the encodingSearchPath above. If the application does not explicitly set
+ * the encodingSearchPath, then it will be initialized by appending /encoding
+ * to each directory in this "libraryPath".
+ */
+
+static ProcessGlobalValue libraryPath = {
+    0, 0, NULL, NULL, TclpInitLibraryPath, NULL, NULL
+};
+
+static int encodingsInitialized = 0;
+
+/*
+ * Hash table that keeps track of all loaded Encodings. Keys are the string
+ * names that represent the encoding, values are (Encoding *).
+ */
+
+static Tcl_HashTable encodingTable;
+TCL_DECLARE_MUTEX(encodingMutex)
+
+/*
+ * The following are used to hold the default and current system encodings.
+ * If NULL is passed to one of the conversion routines, the current setting of
+ * the system encoding will be used to perform the conversion.
+ */
+
+static Tcl_Encoding defaultEncoding = NULL;
+static Tcl_Encoding systemEncoding = NULL;
+Tcl_Encoding tclIdentityEncoding = NULL;
+
+/*
+ * The following variable is used in the sparse matrix code for a
+ * TableEncoding to represent a page in the table that has no entries.
+ */
+
+static unsigned short emptyPage[256];
+
+/*
+ * Functions used only in this module.
+ */
+
+static int		BinaryProc(ClientData clientData,
+			    const char *src, int srcLen, int flags,
+			    Tcl_EncodingState *statePtr, char *dst, int dstLen,
+			    int *srcReadPtr, int *dstWrotePtr,
+			    int *dstCharsPtr);
+static void		DupEncodingIntRep(Tcl_Obj *srcPtr, Tcl_Obj *dupPtr);
+static void		EscapeFreeProc(ClientData clientData);
+static int		EscapeFromUtfProc(ClientData clientData,
+			    const char *src, int srcLen, int flags,
+			    Tcl_EncodingState *statePtr, char *dst, int dstLen,
+			    int *srcReadPtr, int *dstWrotePtr,
+			    int *dstCharsPtr);
+static int		EscapeToUtfProc(ClientData clientData,
+			    const char *src, int srcLen, int flags,
+			    Tcl_EncodingState *statePtr, char *dst, int dstLen,
+			    int *srcReadPtr, int *dstWrotePtr,
+			    int *dstCharsPtr);
+static void		FillEncodingFileMap(void);
+static void		FreeEncoding(Tcl_Encoding encoding);
+static void		FreeEncodingIntRep(Tcl_Obj *objPtr);
+static Encoding *	GetTableEncoding(EscapeEncodingData *dataPtr,
+			    int state);
+static Tcl_Encoding	LoadEncodingFile(Tcl_Interp *interp, const char *name);
+static Tcl_Encoding	LoadTableEncoding(const char *name, int type,
+			    Tcl_Channel chan);
+static Tcl_Encoding	LoadEscapeEncoding(const char *name, Tcl_Channel chan);
+static Tcl_Channel	OpenEncodingFileChannel(Tcl_Interp *interp,
+			    const char *name);
+static void		TableFreeProc(ClientData clientData);
+static int		TableFromUtfProc(ClientData clientData,
+			    const char *src, int srcLen, int flags,
+			    Tcl_EncodingState *statePtr, char *dst, int dstLen,
+			    int *srcReadPtr, int *dstWrotePtr,
+			    int *dstCharsPtr);
+static int		TableToUtfProc(ClientData clientData, const char *src,
+			    int srcLen, int flags, Tcl_EncodingState *statePtr,
+			    char *dst, int dstLen, int *srcReadPtr,
+			    int *dstWrotePtr, int *dstCharsPtr);
+static size_t		unilen(const char *src);
+static int		UnicodeToUtfProc(ClientData clientData,
+			    const char *src, int srcLen, int flags,
+			    Tcl_EncodingState *statePtr, char *dst, int dstLen,
+			    int *srcReadPtr, int *dstWrotePtr,
+			    int *dstCharsPtr);
+static int		UtfToUnicodeProc(ClientData clientData,
+			    const char *src, int srcLen, int flags,
+			    Tcl_EncodingState *statePtr, char *dst, int dstLen,
+			    int *srcReadPtr, int *dstWrotePtr,
+			    int *dstCharsPtr);
+static int		UtfToUtfProc(ClientData clientData,
+			    const char *src, int srcLen, int flags,
+			    Tcl_EncodingState *statePtr, char *dst, int dstLen,
+			    int *srcReadPtr, int *dstWrotePtr,
+			    int *dstCharsPtr, int pureNullMode);
+static int		UtfIntToUtfExtProc(ClientData clientData,
+			    const char *src, int srcLen, int flags,
+			    Tcl_EncodingState *statePtr, char *dst, int dstLen,
+			    int *srcReadPtr, int *dstWrotePtr,
+			    int *dstCharsPtr);
+static int		UtfExtToUtfIntProc(ClientData clientData,
+			    const char *src, int srcLen, int flags,
+			    Tcl_EncodingState *statePtr, char *dst, int dstLen,
+			    int *srcReadPtr, int *dstWrotePtr,
+			    int *dstCharsPtr);
+static int		Iso88591FromUtfProc(ClientData clientData,
+			    const char *src, int srcLen, int flags,
+			    Tcl_EncodingState *statePtr, char *dst, int dstLen,
+			    int *srcReadPtr, int *dstWrotePtr,
+			    int *dstCharsPtr);
+static int		Iso88591ToUtfProc(ClientData clientData,
+			    const char *src, int srcLen, int flags,
+			    Tcl_EncodingState *statePtr, char *dst,
+			    int dstLen, int *srcReadPtr, int *dstWrotePtr,
+			    int *dstCharsPtr);
+
+/*
+ * A Tcl_ObjType for holding a cached Tcl_Encoding in the twoPtrValue.ptr1 field
+ * of the intrep. This should help the lifetime of encodings be more useful.
+ * See concerns raised in [Bug 1077262].
+ */
+
+static const Tcl_ObjType encodingType = {
+    "encoding", FreeEncodingIntRep, DupEncodingIntRep, NULL, NULL
+};
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_GetEncodingFromObj --
+ *
+ *	Writes to (*encodingPtr) the Tcl_Encoding value of (*objPtr), if
+ *	possible, and returns TCL_OK. If no such encoding exists, TCL_ERROR is
+ *	returned, and if interp is non-NULL, an error message is written
+ *	there.
+ *
+ * Results:
+ *	Standard Tcl return code.
+ *
+ * Side effects:
+ *	Caches the Tcl_Encoding value as the internal rep of (*objPtr).
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_GetEncodingFromObj(
+    Tcl_Interp *interp,
+    Tcl_Obj *objPtr,
+    Tcl_Encoding *encodingPtr)
+{
+    const char *name = Tcl_GetString(objPtr);
+
+    if (objPtr->typePtr != &encodingType) {
+	Tcl_Encoding encoding = Tcl_GetEncoding(interp, name);
+
+	if (encoding == NULL) {
+	    return TCL_ERROR;
+	}
+	TclFreeIntRep(objPtr);
+	objPtr->internalRep.twoPtrValue.ptr1 = encoding;
+	objPtr->typePtr = &encodingType;
+    }
+    *encodingPtr = Tcl_GetEncoding(NULL, name);
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * FreeEncodingIntRep --
+ *
+ *	The Tcl_FreeInternalRepProc for the "encoding" Tcl_ObjType.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+FreeEncodingIntRep(
+    Tcl_Obj *objPtr)
+{
+    Tcl_FreeEncoding(objPtr->internalRep.twoPtrValue.ptr1);
+    objPtr->typePtr = NULL;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * DupEncodingIntRep --
+ *
+ *	The Tcl_DupInternalRepProc for the "encoding" Tcl_ObjType.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+DupEncodingIntRep(
+    Tcl_Obj *srcPtr,
+    Tcl_Obj *dupPtr)
+{
+    dupPtr->internalRep.twoPtrValue.ptr1 = Tcl_GetEncoding(NULL, srcPtr->bytes);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_GetEncodingSearchPath --
+ *
+ *	Keeps the per-thread copy of the encoding search path current with
+ *	changes to the global copy.
+ *
+ * Results:
+ *	Returns a "list" (Tcl_Obj *) that contains the encoding search path.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_Obj *
+Tcl_GetEncodingSearchPath(void)
+{
+    return TclGetProcessGlobalValue(&encodingSearchPath);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_SetEncodingSearchPath --
+ *
+ *	Keeps the per-thread copy of the encoding search path current with
+ *	changes to the global copy.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_SetEncodingSearchPath(
+    Tcl_Obj *searchPath)
+{
+    int dummy;
+
+    if (TCL_ERROR == Tcl_ListObjLength(NULL, searchPath, &dummy)) {
+	return TCL_ERROR;
+    }
+    TclSetProcessGlobalValue(&encodingSearchPath, searchPath, NULL);
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclGetLibraryPath --
+ *
+ *	Keeps the per-thread copy of the library path current with changes to
+ *	the global copy.
+ *
+ * Results:
+ *	Returns a "list" (Tcl_Obj *) that contains the library path.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_Obj *
+TclGetLibraryPath(void)
+{
+    return TclGetProcessGlobalValue(&libraryPath);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclSetLibraryPath --
+ *
+ *	Keeps the per-thread copy of the library path current with changes to
+ *	the global copy.
+ *
+ *	NOTE: this routine returns void, so there's no way to report the error
+ *	that searchPath is not a valid list. In that case, this routine will
+ *	silently do nothing.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclSetLibraryPath(
+    Tcl_Obj *path)
+{
+    int dummy;
+
+    if (TCL_ERROR == Tcl_ListObjLength(NULL, path, &dummy)) {
+	return;
+    }
+    TclSetProcessGlobalValue(&libraryPath, path, NULL);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * FillEncodingFileMap --
+ *
+ *	Called to bring the encoding file map in sync with the current value
+ *	of the encoding search path.
+ *
+ *	Scan the directories on the encoding search path, find the *.enc
+ *	files, and store the found pathnames in a map associated with the
+ *	encoding name.
+ *
+ *	In particular, if $dir is on the encoding search path, and the file
+ *	$dir/foo.enc is found, then store a "foo" -> $dir entry in the map.
+ *	Later, any need for the "foo" encoding will quickly * be able to
+ *	construct the $dir/foo.enc pathname for reading the encoding data.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Entries are added to the encoding file map.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+static void
+FillEncodingFileMap(void)
+{
+    int i, numDirs = 0;
+    Tcl_Obj *map, *searchPath;
+
+    searchPath = Tcl_GetEncodingSearchPath();
+    Tcl_IncrRefCount(searchPath);
+    Tcl_ListObjLength(NULL, searchPath, &numDirs);
+    map = Tcl_NewDictObj();
+    Tcl_IncrRefCount(map);
+
+    for (i = numDirs-1; i >= 0; i--) {
+	/*
+	 * Iterate backwards through the search path so as we overwrite
+	 * entries found, we favor files earlier on the search path.
+	 */
+
+	int j, numFiles;
+	Tcl_Obj *directory, *matchFileList = Tcl_NewObj();
+	Tcl_Obj **filev;
+	Tcl_GlobTypeData readableFiles = {
+	    TCL_GLOB_TYPE_FILE, TCL_GLOB_PERM_R, NULL, NULL
+	};
+
+	Tcl_ListObjIndex(NULL, searchPath, i, &directory);
+	Tcl_IncrRefCount(directory);
+	Tcl_IncrRefCount(matchFileList);
+	Tcl_FSMatchInDirectory(NULL, matchFileList, directory, "*.enc",
+		&readableFiles);
+
+	Tcl_ListObjGetElements(NULL, matchFileList, &numFiles, &filev);
+	for (j=0; j<numFiles; j++) {
+	    Tcl_Obj *encodingName, *fileObj;
+
+	    fileObj = TclPathPart(NULL, filev[j], TCL_PATH_TAIL);
+	    encodingName = TclPathPart(NULL, fileObj, TCL_PATH_ROOT);
+	    Tcl_DictObjPut(NULL, map, encodingName, directory);
+	    Tcl_DecrRefCount(fileObj);
+	    Tcl_DecrRefCount(encodingName);
+	}
+	Tcl_DecrRefCount(matchFileList);
+	Tcl_DecrRefCount(directory);
+    }
+    Tcl_DecrRefCount(searchPath);
+    TclSetProcessGlobalValue(&encodingFileMap, map, NULL);
+    Tcl_DecrRefCount(map);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * TclInitEncodingSubsystem --
+ *
+ *	Initialize all resources used by this subsystem on a per-process
+ *	basis.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Depends on the memory, object, and IO subsystems.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+void
+TclInitEncodingSubsystem(void)
+{
+    Tcl_EncodingType type;
+    TableEncodingData *dataPtr;
+    unsigned size;
+    unsigned short i;
+
+    if (encodingsInitialized) {
+	return;
+    }
+
+    Tcl_MutexLock(&encodingMutex);
+    Tcl_InitHashTable(&encodingTable, TCL_STRING_KEYS);
+    Tcl_MutexUnlock(&encodingMutex);
+
+    /*
+     * Create a few initial encodings. Note that the UTF-8 to UTF-8
+     * translation is not a no-op, because it will turn a stream of improperly
+     * formed UTF-8 into a properly formed stream.
+     */
+
+    type.encodingName	= "identity";
+    type.toUtfProc	= BinaryProc;
+    type.fromUtfProc	= BinaryProc;
+    type.freeProc	= NULL;
+    type.nullSize	= 1;
+    type.clientData	= NULL;
+    tclIdentityEncoding = Tcl_CreateEncoding(&type);
+
+    type.encodingName	= "utf-8";
+    type.toUtfProc	= UtfExtToUtfIntProc;
+    type.fromUtfProc	= UtfIntToUtfExtProc;
+    type.freeProc	= NULL;
+    type.nullSize	= 1;
+    type.clientData	= NULL;
+    Tcl_CreateEncoding(&type);
+
+    type.encodingName   = "unicode";
+    type.toUtfProc	= UnicodeToUtfProc;
+    type.fromUtfProc    = UtfToUnicodeProc;
+    type.freeProc	= NULL;
+    type.nullSize	= 2;
+    type.clientData	= NULL;
+    Tcl_CreateEncoding(&type);
+
+    /*
+     * Need the iso8859-1 encoding in order to process binary data, so force
+     * it to always be embedded. Note that this encoding *must* be a proper
+     * table encoding or some of the escape encodings crash! Hence the ugly
+     * code to duplicate the structure of a table encoding here.
+     */
+
+    dataPtr = ckalloc(sizeof(TableEncodingData));
+    memset(dataPtr, 0, sizeof(TableEncodingData));
+    dataPtr->fallback = '?';
+
+    size = 256*(sizeof(unsigned short *) + sizeof(unsigned short));
+    dataPtr->toUnicode = ckalloc(size);
+    memset(dataPtr->toUnicode, 0, size);
+    dataPtr->fromUnicode = ckalloc(size);
+    memset(dataPtr->fromUnicode, 0, size);
+
+    dataPtr->toUnicode[0] = (unsigned short *) (dataPtr->toUnicode + 256);
+    dataPtr->fromUnicode[0] = (unsigned short *) (dataPtr->fromUnicode + 256);
+    for (i=1 ; i<256 ; i++) {
+	dataPtr->toUnicode[i] = emptyPage;
+	dataPtr->fromUnicode[i] = emptyPage;
+    }
+
+    for (i=0 ; i<256 ; i++) {
+	dataPtr->toUnicode[0][i] = i;
+	dataPtr->fromUnicode[0][i] = i;
+    }
+
+    type.encodingName	= "iso8859-1";
+    type.toUtfProc	= Iso88591ToUtfProc;
+    type.fromUtfProc	= Iso88591FromUtfProc;
+    type.freeProc	= TableFreeProc;
+    type.nullSize	= 1;
+    type.clientData	= dataPtr;
+    defaultEncoding	= Tcl_CreateEncoding(&type);
+    systemEncoding	= Tcl_GetEncoding(NULL, type.encodingName);
+
+    encodingsInitialized = 1;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclFinalizeEncodingSubsystem --
+ *
+ *	Release the state associated with the encoding subsystem.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Frees all of the encodings.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclFinalizeEncodingSubsystem(void)
+{
+    Tcl_HashSearch search;
+    Tcl_HashEntry *hPtr;
+
+    Tcl_MutexLock(&encodingMutex);
+    encodingsInitialized = 0;
+    FreeEncoding(systemEncoding);
+    systemEncoding = NULL;
+    defaultEncoding = NULL;
+    FreeEncoding(tclIdentityEncoding);
+    tclIdentityEncoding = NULL;
+
+    hPtr = Tcl_FirstHashEntry(&encodingTable, &search);
+    while (hPtr != NULL) {
+	/*
+	 * Call FreeEncoding instead of doing it directly to handle refcounts
+	 * like escape encodings use. [Bug 524674] Make sure to call
+	 * Tcl_FirstHashEntry repeatedly so that all encodings are eventually
+	 * cleaned up.
+	 */
+
+	FreeEncoding(Tcl_GetHashValue(hPtr));
+	hPtr = Tcl_FirstHashEntry(&encodingTable, &search);
+    }
+
+    Tcl_DeleteHashTable(&encodingTable);
+    Tcl_MutexUnlock(&encodingMutex);
+}
+
+/*
+ *-------------------------------------------------------------------------
+ *
+ * Tcl_GetDefaultEncodingDir --
+ *
+ *	Legacy public interface to retrieve first directory in the encoding
+ *	searchPath.
+ *
+ * Results:
+ *	The directory pathname, as a string, or NULL for an empty encoding
+ *	search path.
+ *
+ * Side effects:
+ *	None.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+const char *
+Tcl_GetDefaultEncodingDir(void)
+{
+    int numDirs;
+    Tcl_Obj *first, *searchPath = Tcl_GetEncodingSearchPath();
+
+    Tcl_ListObjLength(NULL, searchPath, &numDirs);
+    if (numDirs == 0) {
+	return NULL;
+    }
+    Tcl_ListObjIndex(NULL, searchPath, 0, &first);
+
+    return Tcl_GetString(first);
+}
+
+/*
+ *-------------------------------------------------------------------------
+ *
+ * Tcl_SetDefaultEncodingDir --
+ *
+ *	Legacy public interface to set the first directory in the encoding
+ *	search path.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Modifies the encoding search path.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+void
+Tcl_SetDefaultEncodingDir(
+    const char *path)
+{
+    Tcl_Obj *searchPath = Tcl_GetEncodingSearchPath();
+    Tcl_Obj *directory = Tcl_NewStringObj(path, -1);
+
+    searchPath = Tcl_DuplicateObj(searchPath);
+    Tcl_ListObjReplace(NULL, searchPath, 0, 0, 1, &directory);
+    Tcl_SetEncodingSearchPath(searchPath);
+}
+
+/*
+ *-------------------------------------------------------------------------
+ *
+ * Tcl_GetEncoding --
+ *
+ *	Given the name of a encoding, find the corresponding Tcl_Encoding
+ *	token. If the encoding did not already exist, Tcl attempts to
+ *	dynamically load an encoding by that name.
+ *
+ * Results:
+ *	Returns a token that represents the encoding. If the name didn't refer
+ *	to any known or loadable encoding, NULL is returned. If NULL was
+ *	returned, an error message is left in interp's result object, unless
+ *	interp was NULL.
+ *
+ * Side effects:
+ *	The new encoding type is entered into a table visible to all
+ *	interpreters, keyed off the encoding's name. For each call to this
+ *	function, there should eventually be a call to Tcl_FreeEncoding, so
+ *	that the database can be cleaned up when encodings aren't needed
+ *	anymore.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+Tcl_Encoding
+Tcl_GetEncoding(
+    Tcl_Interp *interp,		/* Interp for error reporting, if not NULL. */
+    const char *name)		/* The name of the desired encoding. */
+{
+    Tcl_HashEntry *hPtr;
+    Encoding *encodingPtr;
+
+    Tcl_MutexLock(&encodingMutex);
+    if (name == NULL) {
+	encodingPtr = (Encoding *) systemEncoding;
+	encodingPtr->refCount++;
+	Tcl_MutexUnlock(&encodingMutex);
+	return systemEncoding;
+    }
+
+    hPtr = Tcl_FindHashEntry(&encodingTable, name);
+    if (hPtr != NULL) {
+	encodingPtr = Tcl_GetHashValue(hPtr);
+	encodingPtr->refCount++;
+	Tcl_MutexUnlock(&encodingMutex);
+	return (Tcl_Encoding) encodingPtr;
+    }
+    Tcl_MutexUnlock(&encodingMutex);
+
+    return LoadEncodingFile(interp, name);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Tcl_FreeEncoding --
+ *
+ *	This function is called to release an encoding allocated by
+ *	Tcl_CreateEncoding() or Tcl_GetEncoding().
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The reference count associated with the encoding is decremented and
+ *	the encoding may be deleted if nothing is using it anymore.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+void
+Tcl_FreeEncoding(
+    Tcl_Encoding encoding)
+{
+    Tcl_MutexLock(&encodingMutex);
+    FreeEncoding(encoding);
+    Tcl_MutexUnlock(&encodingMutex);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * FreeEncoding --
+ *
+ *	This function is called to release an encoding by functions that
+ *	already have the encodingMutex.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The reference count associated with the encoding is decremented and
+ *	the encoding may be deleted if nothing is using it anymore.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+FreeEncoding(
+    Tcl_Encoding encoding)
+{
+    Encoding *encodingPtr = (Encoding *) encoding;
+
+    if (encodingPtr == NULL) {
+	return;
+    }
+    if (encodingPtr->refCount<=0) {
+	Tcl_Panic("FreeEncoding: refcount problem !!!");
+    }
+    encodingPtr->refCount--;
+    if (encodingPtr->refCount == 0) {
+	if (encodingPtr->freeProc != NULL) {
+	    encodingPtr->freeProc(encodingPtr->clientData);
+	}
+	if (encodingPtr->hPtr != NULL) {
+	    Tcl_DeleteHashEntry(encodingPtr->hPtr);
+	}
+	ckfree(encodingPtr->name);
+	ckfree(encodingPtr);
+    }
+}
+
+/*
+ *-------------------------------------------------------------------------
+ *
+ * Tcl_GetEncodingName --
+ *
+ *	Given an encoding, return the name that was used to constuct the
+ *	encoding.
+ *
+ * Results:
+ *	The name of the encoding.
+ *
+ * Side effects:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+const char *
+Tcl_GetEncodingName(
+    Tcl_Encoding encoding)	/* The encoding whose name to fetch. */
+{
+    if (encoding == NULL) {
+	encoding = systemEncoding;
+    }
+
+    return ((Encoding *) encoding)->name;
+}
+
+/*
+ *-------------------------------------------------------------------------
+ *
+ * Tcl_GetEncodingNames --
+ *
+ *	Get the list of all known encodings, including the ones stored as
+ *	files on disk in the encoding path.
+ *
+ * Results:
+ *	Modifies interp's result object to hold a list of all the available
+ *	encodings.
+ *
+ * Side effects:
+ *	None.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+void
+Tcl_GetEncodingNames(
+    Tcl_Interp *interp)		/* Interp to hold result. */
+{
+    Tcl_HashTable table;
+    Tcl_HashSearch search;
+    Tcl_HashEntry *hPtr;
+    Tcl_Obj *map, *name, *result = Tcl_NewObj();
+    Tcl_DictSearch mapSearch;
+    int dummy, done = 0;
+
+    Tcl_InitObjHashTable(&table);
+
+    /*
+     * Copy encoding names from loaded encoding table to table.
+     */
+
+    Tcl_MutexLock(&encodingMutex);
+    for (hPtr = Tcl_FirstHashEntry(&encodingTable, &search); hPtr != NULL;
+	    hPtr = Tcl_NextHashEntry(&search)) {
+	Encoding *encodingPtr = Tcl_GetHashValue(hPtr);
+
+	Tcl_CreateHashEntry(&table,
+		Tcl_NewStringObj(encodingPtr->name, -1), &dummy);
+    }
+    Tcl_MutexUnlock(&encodingMutex);
+
+    FillEncodingFileMap();
+    map = TclGetProcessGlobalValue(&encodingFileMap);
+
+    /*
+     * Copy encoding names from encoding file map to table.
+     */
+
+    Tcl_DictObjFirst(NULL, map, &mapSearch, &name, NULL, &done);
+    for (; !done; Tcl_DictObjNext(&mapSearch, &name, NULL, &done)) {
+	Tcl_CreateHashEntry(&table, name, &dummy);
+    }
+
+    /*
+     * Pull all encoding names from table into the result list.
+     */
+
+    for (hPtr = Tcl_FirstHashEntry(&table, &search); hPtr != NULL;
+	    hPtr = Tcl_NextHashEntry(&search)) {
+	Tcl_ListObjAppendElement(NULL, result,
+		(Tcl_Obj *) Tcl_GetHashKey(&table, hPtr));
+    }
+    Tcl_SetObjResult(interp, result);
+    Tcl_DeleteHashTable(&table);
+}
+
+/*
+ *------------------------------------------------------------------------
+ *
+ * Tcl_SetSystemEncoding --
+ *
+ *	Sets the default encoding that should be used whenever the user passes
+ *	a NULL value in to one of the conversion routines. If the supplied
+ *	name is NULL, the system encoding is reset to the default system
+ *	encoding.
+ *
+ * Results:
+ *	The return value is TCL_OK if the system encoding was successfully set
+ *	to the encoding specified by name, TCL_ERROR otherwise. If TCL_ERROR
+ *	is returned, an error message is left in interp's result object,
+ *	unless interp was NULL.
+ *
+ * Side effects:
+ *	The reference count of the new system encoding is incremented. The
+ *	reference count of the old system encoding is decremented and it may
+ *	be freed.
+ *
+ *------------------------------------------------------------------------
+ */
+
+int
+Tcl_SetSystemEncoding(
+    Tcl_Interp *interp,		/* Interp for error reporting, if not NULL. */
+    const char *name)		/* The name of the desired encoding, or NULL/""
+				 * to reset to default encoding. */
+{
+    Tcl_Encoding encoding;
+    Encoding *encodingPtr;
+
+    if (!name || !*name) {
+	Tcl_MutexLock(&encodingMutex);
+	encoding = defaultEncoding;
+	encodingPtr = (Encoding *) encoding;
+	encodingPtr->refCount++;
+	Tcl_MutexUnlock(&encodingMutex);
+    } else {
+	encoding = Tcl_GetEncoding(interp, name);
+	if (encoding == NULL) {
+	    return TCL_ERROR;
+	}
+    }
+
+    Tcl_MutexLock(&encodingMutex);
+    FreeEncoding(systemEncoding);
+    systemEncoding = encoding;
+    Tcl_MutexUnlock(&encodingMutex);
+
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Tcl_CreateEncoding --
+ *
+ *	This function is called to define a new encoding and the functions
+ *	that are used to convert between the specified encoding and Unicode.
+ *
+ * Results:
+ *	Returns a token that represents the encoding. If an encoding with the
+ *	same name already existed, the old encoding token remains valid and
+ *	continues to behave as it used to, and will eventually be garbage
+ *	collected when the last reference to it goes away. Any subsequent
+ *	calls to Tcl_GetEncoding with the specified name will retrieve the
+ *	most recent encoding token.
+ *
+ * Side effects:
+ *	The new encoding type is entered into a table visible to all
+ *	interpreters, keyed off the encoding's name. For each call to this
+ *	function, there should eventually be a call to Tcl_FreeEncoding, so
+ *	that the database can be cleaned up when encodings aren't needed
+ *	anymore.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+Tcl_Encoding
+Tcl_CreateEncoding(
+    const Tcl_EncodingType *typePtr)
+				/* The encoding type. */
+{
+    Tcl_HashEntry *hPtr;
+    int isNew;
+    Encoding *encodingPtr;
+    char *name;
+
+    Tcl_MutexLock(&encodingMutex);
+    hPtr = Tcl_CreateHashEntry(&encodingTable, typePtr->encodingName, &isNew);
+    if (isNew == 0) {
+	/*
+	 * Remove old encoding from hash table, but don't delete it until last
+	 * reference goes away.
+	 */
+
+	encodingPtr = Tcl_GetHashValue(hPtr);
+	encodingPtr->hPtr = NULL;
+    }
+
+    name = ckalloc(strlen(typePtr->encodingName) + 1);
+
+    encodingPtr = ckalloc(sizeof(Encoding));
+    encodingPtr->name		= strcpy(name, typePtr->encodingName);
+    encodingPtr->toUtfProc	= typePtr->toUtfProc;
+    encodingPtr->fromUtfProc	= typePtr->fromUtfProc;
+    encodingPtr->freeProc	= typePtr->freeProc;
+    encodingPtr->nullSize	= typePtr->nullSize;
+    encodingPtr->clientData	= typePtr->clientData;
+    if (typePtr->nullSize == 1) {
+	encodingPtr->lengthProc = (LengthProc *) strlen;
+    } else {
+	encodingPtr->lengthProc = (LengthProc *) unilen;
+    }
+    encodingPtr->refCount	= 1;
+    encodingPtr->hPtr		= hPtr;
+    Tcl_SetHashValue(hPtr, encodingPtr);
+
+    Tcl_MutexUnlock(&encodingMutex);
+
+    return (Tcl_Encoding) encodingPtr;
+}
+
+/*
+ *-------------------------------------------------------------------------
+ *
+ * Tcl_ExternalToUtfDString --
+ *
+ *	Convert a source buffer from the specified encoding into UTF-8. If any
+ *	of the bytes in the source buffer are invalid or cannot be represented
+ *	in the target encoding, a default fallback character will be
+ *	substituted.
+ *
+ * Results:
+ *	The converted bytes are stored in the DString, which is then NULL
+ *	terminated. The return value is a pointer to the value stored in the
+ *	DString.
+ *
+ * Side effects:
+ *	None.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+char *
+Tcl_ExternalToUtfDString(
+    Tcl_Encoding encoding,	/* The encoding for the source string, or NULL
+				 * for the default system encoding. */
+    const char *src,		/* Source string in specified encoding. */
+    int srcLen,			/* Source string length in bytes, or < 0 for
+				 * encoding-specific string length. */
+    Tcl_DString *dstPtr)	/* Uninitialized or free DString in which the
+				 * converted string is stored. */
+{
+    char *dst;
+    Tcl_EncodingState state;
+    const Encoding *encodingPtr;
+    int flags, dstLen, result, soFar, srcRead, dstWrote, dstChars;
+
+    Tcl_DStringInit(dstPtr);
+    dst = Tcl_DStringValue(dstPtr);
+    dstLen = dstPtr->spaceAvl - 1;
+
+    if (encoding == NULL) {
+	encoding = systemEncoding;
+    }
+    encodingPtr = (Encoding *) encoding;
+
+    if (src == NULL) {
+	srcLen = 0;
+    } else if (srcLen < 0) {
+	srcLen = encodingPtr->lengthProc(src);
+    }
+
+    flags = TCL_ENCODING_START | TCL_ENCODING_END;
+
+    while (1) {
+	result = encodingPtr->toUtfProc(encodingPtr->clientData, src, srcLen,
+		flags, &state, dst, dstLen, &srcRead, &dstWrote, &dstChars);
+	soFar = dst + dstWrote - Tcl_DStringValue(dstPtr);
+
+	if (result != TCL_CONVERT_NOSPACE) {
+	    Tcl_DStringSetLength(dstPtr, soFar);
+	    return Tcl_DStringValue(dstPtr);
+	}
+
+	flags &= ~TCL_ENCODING_START;
+	src += srcRead;
+	srcLen -= srcRead;
+	if (Tcl_DStringLength(dstPtr) == 0) {
+	    Tcl_DStringSetLength(dstPtr, dstLen);
+	}
+	Tcl_DStringSetLength(dstPtr, 2 * Tcl_DStringLength(dstPtr) + 1);
+	dst = Tcl_DStringValue(dstPtr) + soFar;
+	dstLen = Tcl_DStringLength(dstPtr) - soFar - 1;
+    }
+}
+
+/*
+ *-------------------------------------------------------------------------
+ *
+ * Tcl_ExternalToUtf --
+ *
+ *	Convert a source buffer from the specified encoding into UTF-8.
+ *
+ * Results:
+ *	The return value is one of TCL_OK, TCL_CONVERT_MULTIBYTE,
+ *	TCL_CONVERT_SYNTAX, TCL_CONVERT_UNKNOWN, or TCL_CONVERT_NOSPACE, as
+ *	documented in tcl.h.
+ *
+ * Side effects:
+ *	The converted bytes are stored in the output buffer.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+int
+Tcl_ExternalToUtf(
+    Tcl_Interp *interp,		/* Interp for error return, if not NULL. */
+    Tcl_Encoding encoding,	/* The encoding for the source string, or NULL
+				 * for the default system encoding. */
+    const char *src,		/* Source string in specified encoding. */
+    int srcLen,			/* Source string length in bytes, or < 0 for
+				 * encoding-specific string length. */
+    int flags,			/* Conversion control flags. */
+    Tcl_EncodingState *statePtr,/* Place for conversion routine to store state
+				 * information used during a piecewise
+				 * conversion. Contents of statePtr are
+				 * initialized and/or reset by conversion
+				 * routine under control of flags argument. */
+    char *dst,			/* Output buffer in which converted string is
+				 * stored. */
+    int dstLen,			/* The maximum length of output buffer in
+				 * bytes. */
+    int *srcReadPtr,		/* Filled with the number of bytes from the
+				 * source string that were converted. This may
+				 * be less than the original source length if
+				 * there was a problem converting some source
+				 * characters. */
+    int *dstWrotePtr,		/* Filled with the number of bytes that were
+				 * stored in the output buffer as a result of
+				 * the conversion. */
+    int *dstCharsPtr)		/* Filled with the number of characters that
+				 * correspond to the bytes stored in the
+				 * output buffer. */
+{
+    const Encoding *encodingPtr;
+    int result, srcRead, dstWrote, dstChars = 0;
+    int noTerminate = flags & TCL_ENCODING_NO_TERMINATE;
+    int charLimited = (flags & TCL_ENCODING_CHAR_LIMIT) && dstCharsPtr;
+    int maxChars = INT_MAX;
+    Tcl_EncodingState state;
+
+    if (encoding == NULL) {
+	encoding = systemEncoding;
+    }
+    encodingPtr = (Encoding *) encoding;
+
+    if (src == NULL) {
+	srcLen = 0;
+    } else if (srcLen < 0) {
+	srcLen = encodingPtr->lengthProc(src);
+    }
+    if (statePtr == NULL) {
+	flags |= TCL_ENCODING_START | TCL_ENCODING_END;
+	statePtr = &state;
+    }
+    if (srcReadPtr == NULL) {
+	srcReadPtr = &srcRead;
+    }
+    if (dstWrotePtr == NULL) {
+	dstWrotePtr = &dstWrote;
+    }
+    if (dstCharsPtr == NULL) {
+	dstCharsPtr = &dstChars;
+	flags &= ~TCL_ENCODING_CHAR_LIMIT;
+    } else if (charLimited) {
+	maxChars = *dstCharsPtr;
+    }
+
+    if (!noTerminate) {
+	/*
+	 * If there are any null characters in the middle of the buffer,
+	 * they will converted to the UTF-8 null character (\xC080). To get
+	 * the actual \0 at the end of the destination buffer, we need to
+	 * append it manually.  First make room for it...
+	 */
+
+	dstLen--;
+    }
+    do {
+	int savedFlags = flags;
+	Tcl_EncodingState savedState = *statePtr;
+
+	result = encodingPtr->toUtfProc(encodingPtr->clientData, src, srcLen,
+		flags, statePtr, dst, dstLen, srcReadPtr, dstWrotePtr,
+		dstCharsPtr);
+	if (*dstCharsPtr <= maxChars) {
+	    break;
+	}
+	dstLen = Tcl_UtfAtIndex(dst, maxChars) - 1 - dst + TCL_UTF_MAX;
+	flags = savedFlags;
+	*statePtr = savedState;
+    } while (1);
+    if (!noTerminate) {
+	/* ...and then append it */
+
+	dst[*dstWrotePtr] = '\0';
+    }
+
+    return result;
+}
+
+/*
+ *-------------------------------------------------------------------------
+ *
+ * Tcl_UtfToExternalDString --
+ *
+ *	Convert a source buffer from UTF-8 into the specified encoding. If any
+ *	of the bytes in the source buffer are invalid or cannot be represented
+ *	in the target encoding, a default fallback character will be
+ *	substituted.
+ *
+ * Results:
+ *	The converted bytes are stored in the DString, which is then NULL
+ *	terminated in an encoding-specific manner. The return value is a
+ *	pointer to the value stored in the DString.
+ *
+ * Side effects:
+ *	None.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+char *
+Tcl_UtfToExternalDString(
+    Tcl_Encoding encoding,	/* The encoding for the converted string, or
+				 * NULL for the default system encoding. */
+    const char *src,		/* Source string in UTF-8. */
+    int srcLen,			/* Source string length in bytes, or < 0 for
+				 * strlen(). */
+    Tcl_DString *dstPtr)	/* Uninitialized or free DString in which the
+				 * converted string is stored. */
+{
+    char *dst;
+    Tcl_EncodingState state;
+    const Encoding *encodingPtr;
+    int flags, dstLen, result, soFar, srcRead, dstWrote, dstChars;
+
+    Tcl_DStringInit(dstPtr);
+    dst = Tcl_DStringValue(dstPtr);
+    dstLen = dstPtr->spaceAvl - 1;
+
+    if (encoding == NULL) {
+	encoding = systemEncoding;
+    }
+    encodingPtr = (Encoding *) encoding;
+
+    if (src == NULL) {
+	srcLen = 0;
+    } else if (srcLen < 0) {
+	srcLen = strlen(src);
+    }
+    flags = TCL_ENCODING_START | TCL_ENCODING_END;
+    while (1) {
+	result = encodingPtr->fromUtfProc(encodingPtr->clientData, src,
+		srcLen, flags, &state, dst, dstLen, &srcRead, &dstWrote,
+		&dstChars);
+	soFar = dst + dstWrote - Tcl_DStringValue(dstPtr);
+
+	if (result != TCL_CONVERT_NOSPACE) {
+	    if (encodingPtr->nullSize == 2) {
+		Tcl_DStringSetLength(dstPtr, soFar + 1);
+	    }
+	    Tcl_DStringSetLength(dstPtr, soFar);
+	    return Tcl_DStringValue(dstPtr);
+	}
+
+	flags &= ~TCL_ENCODING_START;
+	src += srcRead;
+	srcLen -= srcRead;
+	if (Tcl_DStringLength(dstPtr) == 0) {
+	    Tcl_DStringSetLength(dstPtr, dstLen);
+	}
+	Tcl_DStringSetLength(dstPtr, 2 * Tcl_DStringLength(dstPtr) + 1);
+	dst = Tcl_DStringValue(dstPtr) + soFar;
+	dstLen = Tcl_DStringLength(dstPtr) - soFar - 1;
+    }
+}
+
+/*
+ *-------------------------------------------------------------------------
+ *
+ * Tcl_UtfToExternal --
+ *
+ *	Convert a buffer from UTF-8 into the specified encoding.
+ *
+ * Results:
+ *	The return value is one of TCL_OK, TCL_CONVERT_MULTIBYTE,
+ *	TCL_CONVERT_SYNTAX, TCL_CONVERT_UNKNOWN, or TCL_CONVERT_NOSPACE, as
+ *	documented in tcl.h.
+ *
+ * Side effects:
+ *	The converted bytes are stored in the output buffer.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+int
+Tcl_UtfToExternal(
+    Tcl_Interp *interp,		/* Interp for error return, if not NULL. */
+    Tcl_Encoding encoding,	/* The encoding for the converted string, or
+				 * NULL for the default system encoding. */
+    const char *src,		/* Source string in UTF-8. */
+    int srcLen,			/* Source string length in bytes, or < 0 for
+				 * strlen(). */
+    int flags,			/* Conversion control flags. */
+    Tcl_EncodingState *statePtr,/* Place for conversion routine to store state
+				 * information used during a piecewise
+				 * conversion. Contents of statePtr are
+				 * initialized and/or reset by conversion
+				 * routine under control of flags argument. */
+    char *dst,			/* Output buffer in which converted string
+				 * is stored. */
+    int dstLen,			/* The maximum length of output buffer in
+				 * bytes. */
+    int *srcReadPtr,		/* Filled with the number of bytes from the
+				 * source string that were converted. This may
+				 * be less than the original source length if
+				 * there was a problem converting some source
+				 * characters. */
+    int *dstWrotePtr,		/* Filled with the number of bytes that were
+				 * stored in the output buffer as a result of
+				 * the conversion. */
+    int *dstCharsPtr)		/* Filled with the number of characters that
+				 * correspond to the bytes stored in the
+				 * output buffer. */
+{
+    const Encoding *encodingPtr;
+    int result, srcRead, dstWrote, dstChars;
+    Tcl_EncodingState state;
+
+    if (encoding == NULL) {
+	encoding = systemEncoding;
+    }
+    encodingPtr = (Encoding *) encoding;
+
+    if (src == NULL) {
+	srcLen = 0;
+    } else if (srcLen < 0) {
+	srcLen = strlen(src);
+    }
+    if (statePtr == NULL) {
+	flags |= TCL_ENCODING_START | TCL_ENCODING_END;
+	statePtr = &state;
+    }
+    if (srcReadPtr == NULL) {
+	srcReadPtr = &srcRead;
+    }
+    if (dstWrotePtr == NULL) {
+	dstWrotePtr = &dstWrote;
+    }
+    if (dstCharsPtr == NULL) {
+	dstCharsPtr = &dstChars;
+    }
+
+    dstLen -= encodingPtr->nullSize;
+    result = encodingPtr->fromUtfProc(encodingPtr->clientData, src, srcLen,
+	    flags, statePtr, dst, dstLen, srcReadPtr, dstWrotePtr,
+	    dstCharsPtr);
+    if (encodingPtr->nullSize == 2) {
+	dst[*dstWrotePtr + 1] = '\0';
+    }
+    dst[*dstWrotePtr] = '\0';
+
+    return result;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Tcl_FindExecutable --
+ *
+ *	This function computes the absolute path name of the current
+ *	application, given its argv[0] value.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The absolute pathname for the application is computed and stored to be
+ *	returned later by [info nameofexecutable].
+ *
+ *---------------------------------------------------------------------------
+ */
+#undef Tcl_FindExecutable
+void
+Tcl_FindExecutable(
+    const char *argv0)		/* The value of the application's argv[0]
+				 * (native). */
+{
+    TclInitSubsystems();
+    TclpSetInitialEncodings();
+    TclpFindExecutable(argv0);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * OpenEncodingFileChannel --
+ *
+ *	Open the file believed to hold data for the encoding, "name".
+ *
+ * Results:
+ *	Returns the readable Tcl_Channel from opening the file, or NULL if the
+ *	file could not be successfully opened. If NULL was returned, an error
+ *	message is left in interp's result object, unless interp was NULL.
+ *
+ * Side effects:
+ *	Channel may be opened. Information about the filesystem may be cached
+ *	to speed later calls.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+static Tcl_Channel
+OpenEncodingFileChannel(
+    Tcl_Interp *interp,		/* Interp for error reporting, if not NULL. */
+    const char *name)		/* The name of the encoding file on disk and
+				 * also the name for new encoding. */
+{
+    Tcl_Obj *nameObj = Tcl_NewStringObj(name, -1);
+    Tcl_Obj *fileNameObj = Tcl_DuplicateObj(nameObj);
+    Tcl_Obj *searchPath = Tcl_DuplicateObj(Tcl_GetEncodingSearchPath());
+    Tcl_Obj *map = TclGetProcessGlobalValue(&encodingFileMap);
+    Tcl_Obj **dir, *path, *directory = NULL;
+    Tcl_Channel chan = NULL;
+    int i, numDirs;
+
+    Tcl_ListObjGetElements(NULL, searchPath, &numDirs, &dir);
+    Tcl_IncrRefCount(nameObj);
+    Tcl_AppendToObj(fileNameObj, ".enc", -1);
+    Tcl_IncrRefCount(fileNameObj);
+    Tcl_DictObjGet(NULL, map, nameObj, &directory);
+
+    /*
+     * Check that any cached directory is still on the encoding search path.
+     */
+
+    if (NULL != directory) {
+	int verified = 0;
+
+	for (i=0; i<numDirs && !verified; i++) {
+	    if (dir[i] == directory) {
+		verified = 1;
+	    }
+	}
+	if (!verified) {
+	    const char *dirString = Tcl_GetString(directory);
+
+	    for (i=0; i<numDirs && !verified; i++) {
+		if (strcmp(dirString, Tcl_GetString(dir[i])) == 0) {
+		    verified = 1;
+		}
+	    }
+	}
+	if (!verified) {
+	    /*
+	     * Directory no longer on the search path. Remove from cache.
+	     */
+
+	    map = Tcl_DuplicateObj(map);
+	    Tcl_DictObjRemove(NULL, map, nameObj);
+	    TclSetProcessGlobalValue(&encodingFileMap, map, NULL);
+	    directory = NULL;
+	}
+    }
+
+    if (NULL != directory) {
+	/*
+	 * Got a directory from the cache. Try to use it first.
+	 */
+
+	Tcl_IncrRefCount(directory);
+	path = Tcl_FSJoinToPath(directory, 1, &fileNameObj);
+	Tcl_IncrRefCount(path);
+	Tcl_DecrRefCount(directory);
+	chan = Tcl_FSOpenFileChannel(NULL, path, "r", 0);
+	Tcl_DecrRefCount(path);
+    }
+
+    /*
+     * Scan the search path until we find it.
+     */
+
+    for (i=0; i<numDirs && (chan == NULL); i++) {
+	path = Tcl_FSJoinToPath(dir[i], 1, &fileNameObj);
+	Tcl_IncrRefCount(path);
+	chan = Tcl_FSOpenFileChannel(NULL, path, "r", 0);
+	Tcl_DecrRefCount(path);
+	if (chan != NULL) {
+	    /*
+	     * Save directory in the cache.
+	     */
+
+	    map = Tcl_DuplicateObj(TclGetProcessGlobalValue(&encodingFileMap));
+	    Tcl_DictObjPut(NULL, map, nameObj, dir[i]);
+	    TclSetProcessGlobalValue(&encodingFileMap, map, NULL);
+	}
+    }
+
+    if ((NULL == chan) && (interp != NULL)) {
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		"unknown encoding \"%s\"", name));
+	Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "ENCODING", name, NULL);
+    }
+    Tcl_DecrRefCount(fileNameObj);
+    Tcl_DecrRefCount(nameObj);
+    Tcl_DecrRefCount(searchPath);
+
+    return chan;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * LoadEncodingFile --
+ *
+ *	Read a file that describes an encoding and create a new Encoding from
+ *	the data.
+ *
+ * Results:
+ *	The return value is the newly loaded Encoding, or NULL if the file
+ *	didn't exist of was in the incorrect format. If NULL was returned, an
+ *	error message is left in interp's result object, unless interp was
+ *	NULL.
+ *
+ * Side effects:
+ *	File read from disk.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+static Tcl_Encoding
+LoadEncodingFile(
+    Tcl_Interp *interp,		/* Interp for error reporting, if not NULL. */
+    const char *name)		/* The name of the encoding file on disk and
+				 * also the name for new encoding. */
+{
+    Tcl_Channel chan = NULL;
+    Tcl_Encoding encoding = NULL;
+    int ch;
+
+    chan = OpenEncodingFileChannel(interp, name);
+    if (chan == NULL) {
+	return NULL;
+    }
+
+    Tcl_SetChannelOption(NULL, chan, "-encoding", "utf-8");
+
+    while (1) {
+	Tcl_DString ds;
+
+	Tcl_DStringInit(&ds);
+	Tcl_Gets(chan, &ds);
+	ch = Tcl_DStringValue(&ds)[0];
+	Tcl_DStringFree(&ds);
+	if (ch != '#') {
+	    break;
+	}
+    }
+
+    switch (ch) {
+    case 'S':
+	encoding = LoadTableEncoding(name, ENCODING_SINGLEBYTE, chan);
+	break;
+    case 'D':
+	encoding = LoadTableEncoding(name, ENCODING_DOUBLEBYTE, chan);
+	break;
+    case 'M':
+	encoding = LoadTableEncoding(name, ENCODING_MULTIBYTE, chan);
+	break;
+    case 'E':
+	encoding = LoadEscapeEncoding(name, chan);
+	break;
+    }
+    if ((encoding == NULL) && (interp != NULL)) {
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		"invalid encoding file \"%s\"", name));
+	Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "ENCODING", name, NULL);
+    }
+    Tcl_Close(NULL, chan);
+
+    return encoding;
+}
+
+/*
+ *-------------------------------------------------------------------------
+ *
+ * LoadTableEncoding --
+ *
+ *	Helper function for LoadEncodingTable(). Loads a table to that
+ *	converts between Unicode and some other encoding and creates an
+ *	encoding (using a TableEncoding structure) from that information.
+ *
+ *	File contains binary data, but begins with a marker to indicate
+ *	byte-ordering, so that same binary file can be read on either endian
+ *	platforms.
+ *
+ * Results:
+ *	The return value is the new encoding, or NULL if the encoding could
+ *	not be created (because the file contained invalid data).
+ *
+ * Side effects:
+ *	None.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+static Tcl_Encoding
+LoadTableEncoding(
+    const char *name,		/* Name for new encoding. */
+    int type,			/* Type of encoding (ENCODING_?????). */
+    Tcl_Channel chan)		/* File containing new encoding. */
+{
+    Tcl_DString lineString;
+    Tcl_Obj *objPtr;
+    char *line;
+    int i, hi, lo, numPages, symbol, fallback, len;
+    unsigned char used[256];
+    unsigned size;
+    TableEncodingData *dataPtr;
+    unsigned short *pageMemPtr, *page;
+    Tcl_EncodingType encType;
+
+    /*
+     * Speed over memory. Use a full 256 character table to decode hex
+     * sequences in the encoding files.
+     */
+
+    static const char staticHex[] = {
+      0,  0,  0,  0,  0,  0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*   0 ...  15 */
+      0,  0,  0,  0,  0,  0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*  16 ...  31 */
+      0,  0,  0,  0,  0,  0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*  32 ...  47 */
+      0,  1,  2,  3,  4,  5,  6, 7, 8, 9, 0, 0, 0, 0, 0, 0, /*  48 ...  63 */
+      0, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*  64 ...  79 */
+      0,  0,  0,  0,  0,  0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*  80 ...  95 */
+      0, 10, 11, 12, 13, 14, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, /*  96 ... 111 */
+      0,  1,  2,  3,  4,  5,  6, 7, 8, 9, 0, 0, 0, 0, 0, 0, /* 112 ... 127 */
+      0,  0,  0,  0,  0,  0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 128 ... 143 */
+      0,  0,  0,  0,  0,  0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 144 ... 159 */
+      0,  0,  0,  0,  0,  0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 160 ... 175 */
+      0,  0,  0,  0,  0,  0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 176 ... 191 */
+      0,  0,  0,  0,  0,  0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 192 ... 207 */
+      0,  0,  0,  0,  0,  0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 208 ... 223 */
+      0,  0,  0,  0,  0,  0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 224 ... 239 */
+      0,  0,  0,  0,  0,  0,  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 240 ... 255 */
+    };
+
+    Tcl_DStringInit(&lineString);
+    Tcl_Gets(chan, &lineString);
+    line = Tcl_DStringValue(&lineString);
+
+    fallback = (int) strtol(line, &line, 16);
+    symbol = (int) strtol(line, &line, 10);
+    numPages = (int) strtol(line, &line, 10);
+    Tcl_DStringFree(&lineString);
+
+    if (numPages < 0) {
+	numPages = 0;
+    } else if (numPages > 256) {
+	numPages = 256;
+    }
+
+    memset(used, 0, sizeof(used));
+
+#undef PAGESIZE
+#define PAGESIZE    (256 * sizeof(unsigned short))
+
+    dataPtr = ckalloc(sizeof(TableEncodingData));
+    memset(dataPtr, 0, sizeof(TableEncodingData));
+
+    dataPtr->fallback = fallback;
+
+    /*
+     * Read the table that maps characters to Unicode. Performs a single
+     * malloc to get the memory for the array and all the pages needed by the
+     * array.
+     */
+
+    size = 256 * sizeof(unsigned short *) + numPages * PAGESIZE;
+    dataPtr->toUnicode = ckalloc(size);
+    memset(dataPtr->toUnicode, 0, size);
+    pageMemPtr = (unsigned short *) (dataPtr->toUnicode + 256);
+
+    TclNewObj(objPtr);
+    Tcl_IncrRefCount(objPtr);
+    for (i = 0; i < numPages; i++) {
+	int ch;
+	const char *p;
+
+	Tcl_ReadChars(chan, objPtr, 3 + 16 * (16 * 4 + 1), 0);
+	p = Tcl_GetString(objPtr);
+	hi = (staticHex[UCHAR(p[0])] << 4) + staticHex[UCHAR(p[1])];
+	dataPtr->toUnicode[hi] = pageMemPtr;
+	p += 2;
+	for (lo = 0; lo < 256; lo++) {
+	    if ((lo & 0x0f) == 0) {
+		p++;
+	    }
+	    ch = (staticHex[UCHAR(p[0])] << 12) + (staticHex[UCHAR(p[1])] << 8)
+		    + (staticHex[UCHAR(p[2])] << 4) + staticHex[UCHAR(p[3])];
+	    if (ch != 0) {
+		used[ch >> 8] = 1;
+	    }
+	    *pageMemPtr = (unsigned short) ch;
+	    pageMemPtr++;
+	    p += 4;
+	}
+    }
+    TclDecrRefCount(objPtr);
+
+    if (type == ENCODING_DOUBLEBYTE) {
+	memset(dataPtr->prefixBytes, 1, sizeof(dataPtr->prefixBytes));
+    } else {
+	for (hi = 1; hi < 256; hi++) {
+	    if (dataPtr->toUnicode[hi] != NULL) {
+		dataPtr->prefixBytes[hi] = 1;
+	    }
+	}
+    }
+
+    /*
+     * Invert toUnicode array to produce the fromUnicode array. Performs a
+     * single malloc to get the memory for the array and all the pages needed
+     * by the array. While reading in the toUnicode array, we remembered what
+     * pages that would be needed for the fromUnicode array.
+     */
+
+    if (symbol) {
+	used[0] = 1;
+    }
+    numPages = 0;
+    for (hi = 0; hi < 256; hi++) {
+	if (used[hi]) {
+	    numPages++;
+	}
+    }
+    size = 256 * sizeof(unsigned short *) + numPages * PAGESIZE;
+    dataPtr->fromUnicode = ckalloc(size);
+    memset(dataPtr->fromUnicode, 0, size);
+    pageMemPtr = (unsigned short *) (dataPtr->fromUnicode + 256);
+
+    for (hi = 0; hi < 256; hi++) {
+	if (dataPtr->toUnicode[hi] == NULL) {
+	    dataPtr->toUnicode[hi] = emptyPage;
+	    continue;
+	}
+	for (lo = 0; lo < 256; lo++) {
+	    int ch = dataPtr->toUnicode[hi][lo];
+
+	    if (ch != 0) {
+		page = dataPtr->fromUnicode[ch >> 8];
+		if (page == NULL) {
+		    page = pageMemPtr;
+		    pageMemPtr += 256;
+		    dataPtr->fromUnicode[ch >> 8] = page;
+		}
+		page[ch & 0xff] = (unsigned short) ((hi << 8) + lo);
+	    }
+	}
+    }
+    if (type == ENCODING_MULTIBYTE) {
+	/*
+	 * If multibyte encodings don't have a backslash character, define
+	 * one. Otherwise, on Windows, native file names won't work because
+	 * the backslash in the file name will map to the unknown character
+	 * (question mark) when converting from UTF-8 to external encoding.
+	 */
+
+	if (dataPtr->fromUnicode[0] != NULL) {
+	    if (dataPtr->fromUnicode[0]['\\'] == '\0') {
+		dataPtr->fromUnicode[0]['\\'] = '\\';
+	    }
+	}
+    }
+    if (symbol) {
+	/*
+	 * Make a special symbol encoding that not only maps the symbol
+	 * characters from their Unicode code points down into page 0, but
+	 * also ensure that the characters on page 0 map to themselves. This
+	 * is so that a symbol font can be used to display a simple string
+	 * like "abcd" and have alpha, beta, chi, delta show up, rather than
+	 * have "unknown" chars show up because strictly speaking the symbol
+	 * font doesn't have glyphs for those low ASCII chars.
+	 */
+
+	page = dataPtr->fromUnicode[0];
+	if (page == NULL) {
+	    page = pageMemPtr;
+	    dataPtr->fromUnicode[0] = page;
+	}
+	for (lo = 0; lo < 256; lo++) {
+	    if (dataPtr->toUnicode[0][lo] != 0) {
+		page[lo] = (unsigned short) lo;
+	    }
+	}
+    }
+    for (hi = 0; hi < 256; hi++) {
+	if (dataPtr->fromUnicode[hi] == NULL) {
+	    dataPtr->fromUnicode[hi] = emptyPage;
+	}
+    }
+
+    /*
+     * For trailing 'R'everse encoding, see [Patch 689341]
+     */
+
+    Tcl_DStringInit(&lineString);
+
+    /*
+     * Skip leading empty lines.
+     */
+
+    while ((len = Tcl_Gets(chan, &lineString)) == 0) {
+	/* empty body */
+    }
+    if (len < 0) {
+	goto doneParse;
+    }
+
+    /*
+     * Require that it starts with an 'R'.
+     */
+
+    line = Tcl_DStringValue(&lineString);
+    if (line[0] != 'R') {
+	goto doneParse;
+    }
+
+    /*
+     * Read lines from the encoding until EOF.
+     */
+
+    for (TclDStringClear(&lineString);
+	    (len = Tcl_Gets(chan, &lineString)) >= 0;
+	    TclDStringClear(&lineString)) {
+	const unsigned char *p;
+	int to, from;
+
+	/*
+	 * Skip short lines.
+	 */
+
+	if (len < 5) {
+	    continue;
+	}
+
+	/*
+	 * Parse the line as a sequence of hex digits.
+	 */
+
+	p = (const unsigned char *) Tcl_DStringValue(&lineString);
+	to = (staticHex[p[0]] << 12) + (staticHex[p[1]] << 8)
+		+ (staticHex[p[2]] << 4) + staticHex[p[3]];
+	if (to == 0) {
+	    continue;
+	}
+	for (p += 5, len -= 5; len >= 0 && *p; p += 5, len -= 5) {
+	    from = (staticHex[p[0]] << 12) + (staticHex[p[1]] << 8)
+		    + (staticHex[p[2]] << 4) + staticHex[p[3]];
+	    if (from == 0) {
+		continue;
+	    }
+	    dataPtr->fromUnicode[from >> 8][from & 0xff] = to;
+	}
+    }
+  doneParse:
+    Tcl_DStringFree(&lineString);
+
+    /*
+     * Package everything into an encoding structure.
+     */
+
+    encType.encodingName    = name;
+    encType.toUtfProc	    = TableToUtfProc;
+    encType.fromUtfProc	    = TableFromUtfProc;
+    encType.freeProc	    = TableFreeProc;
+    encType.nullSize	    = (type == ENCODING_DOUBLEBYTE) ? 2 : 1;
+    encType.clientData	    = dataPtr;
+
+    return Tcl_CreateEncoding(&encType);
+}
+
+/*
+ *-------------------------------------------------------------------------
+ *
+ * LoadEscapeEncoding --
+ *
+ *	Helper function for LoadEncodingTable(). Loads a state machine that
+ *	converts between Unicode and some other encoding.
+ *
+ *	File contains text data that describes the escape sequences that are
+ *	used to choose an encoding and the associated names for the
+ *	sub-encodings.
+ *
+ * Results:
+ *	The return value is the new encoding, or NULL if the encoding could
+ *	not be created (because the file contained invalid data).
+ *
+ * Side effects:
+ *	None.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+static Tcl_Encoding
+LoadEscapeEncoding(
+    const char *name,		/* Name for new encoding. */
+    Tcl_Channel chan)		/* File containing new encoding. */
+{
+    int i;
+    unsigned size;
+    Tcl_DString escapeData;
+    char init[16], final[16];
+    EscapeEncodingData *dataPtr;
+    Tcl_EncodingType type;
+
+    init[0] = '\0';
+    final[0] = '\0';
+    Tcl_DStringInit(&escapeData);
+
+    while (1) {
+	int argc;
+	const char **argv;
+	char *line;
+	Tcl_DString lineString;
+
+	Tcl_DStringInit(&lineString);
+	if (Tcl_Gets(chan, &lineString) < 0) {
+	    break;
+	}
+	line = Tcl_DStringValue(&lineString);
+	if (Tcl_SplitList(NULL, line, &argc, &argv) != TCL_OK) {
+	    Tcl_DStringFree(&lineString);
+	    continue;
+	}
+	if (argc >= 2) {
+	    if (strcmp(argv[0], "name") == 0) {
+		/* do nothing */
+	    } else if (strcmp(argv[0], "init") == 0) {
+		strncpy(init, argv[1], sizeof(init));
+		init[sizeof(init) - 1] = '\0';
+	    } else if (strcmp(argv[0], "final") == 0) {
+		strncpy(final, argv[1], sizeof(final));
+		final[sizeof(final) - 1] = '\0';
+	    } else {
+		EscapeSubTable est;
+		Encoding *e;
+
+		strncpy(est.sequence, argv[1], sizeof(est.sequence));
+		est.sequence[sizeof(est.sequence) - 1] = '\0';
+		est.sequenceLen = strlen(est.sequence);
+
+		strncpy(est.name, argv[0], sizeof(est.name));
+		est.name[sizeof(est.name) - 1] = '\0';
+
+		/*
+		 * To avoid infinite recursion in [encoding system iso2022-*]
+		 */
+
+		e = (Encoding *) Tcl_GetEncoding(NULL, est.name);
+		if ((e != NULL) && (e->toUtfProc != TableToUtfProc)
+			&& (e->toUtfProc != Iso88591ToUtfProc)) {
+		   Tcl_FreeEncoding((Tcl_Encoding) e);
+		   e = NULL;
+		}
+		est.encodingPtr = e;
+		Tcl_DStringAppend(&escapeData, (char *) &est, sizeof(est));
+	    }
+	}
+	ckfree(argv);
+	Tcl_DStringFree(&lineString);
+    }
+
+    size = sizeof(EscapeEncodingData) - sizeof(EscapeSubTable)
+	    + Tcl_DStringLength(&escapeData);
+    dataPtr = ckalloc(size);
+    dataPtr->initLen = strlen(init);
+    memcpy(dataPtr->init, init, (unsigned) dataPtr->initLen + 1);
+    dataPtr->finalLen = strlen(final);
+    memcpy(dataPtr->final, final, (unsigned) dataPtr->finalLen + 1);
+    dataPtr->numSubTables =
+	    Tcl_DStringLength(&escapeData) / sizeof(EscapeSubTable);
+    memcpy(dataPtr->subTables, Tcl_DStringValue(&escapeData),
+	    (size_t) Tcl_DStringLength(&escapeData));
+    Tcl_DStringFree(&escapeData);
+
+    memset(dataPtr->prefixBytes, 0, sizeof(dataPtr->prefixBytes));
+    for (i = 0; i < dataPtr->numSubTables; i++) {
+	dataPtr->prefixBytes[UCHAR(dataPtr->subTables[i].sequence[0])] = 1;
+    }
+    if (dataPtr->init[0] != '\0') {
+	dataPtr->prefixBytes[UCHAR(dataPtr->init[0])] = 1;
+    }
+    if (dataPtr->final[0] != '\0') {
+	dataPtr->prefixBytes[UCHAR(dataPtr->final[0])] = 1;
+    }
+
+    /*
+     * Package everything into an encoding structure.
+     */
+
+    type.encodingName	= name;
+    type.toUtfProc	= EscapeToUtfProc;
+    type.fromUtfProc    = EscapeFromUtfProc;
+    type.freeProc	= EscapeFreeProc;
+    type.nullSize	= 1;
+    type.clientData	= dataPtr;
+
+    return Tcl_CreateEncoding(&type);
+}
+
+/*
+ *-------------------------------------------------------------------------
+ *
+ * BinaryProc --
+ *
+ *	The default conversion when no other conversion is specified. No
+ *	translation is done; source bytes are copied directly to destination
+ *	bytes.
+ *
+ * Results:
+ *	Returns TCL_OK if conversion was successful.
+ *
+ * Side effects:
+ *	None.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+static int
+BinaryProc(
+    ClientData clientData,	/* Not used. */
+    const char *src,		/* Source string (unknown encoding). */
+    int srcLen,			/* Source string length in bytes. */
+    int flags,			/* Conversion control flags. */
+    Tcl_EncodingState *statePtr,/* Place for conversion routine to store state
+				 * information used during a piecewise
+				 * conversion. Contents of statePtr are
+				 * initialized and/or reset by conversion
+				 * routine under control of flags argument. */
+    char *dst,			/* Output buffer in which converted string is
+				 * stored. */
+    int dstLen,			/* The maximum length of output buffer in
+				 * bytes. */
+    int *srcReadPtr,		/* Filled with the number of bytes from the
+				 * source string that were converted. */
+    int *dstWrotePtr,		/* Filled with the number of bytes that were
+				 * stored in the output buffer as a result of
+				 * the conversion. */
+    int *dstCharsPtr)		/* Filled with the number of characters that
+				 * correspond to the bytes stored in the
+				 * output buffer. */
+{
+    int result;
+
+    result = TCL_OK;
+    dstLen -= TCL_UTF_MAX - 1;
+    if (dstLen < 0) {
+	dstLen = 0;
+    }
+    if ((flags & TCL_ENCODING_CHAR_LIMIT) && srcLen > *dstCharsPtr) {
+	srcLen = *dstCharsPtr;
+    }
+    if (srcLen > dstLen) {
+	srcLen = dstLen;
+	result = TCL_CONVERT_NOSPACE;
+    }
+
+    *srcReadPtr = srcLen;
+    *dstWrotePtr = srcLen;
+    *dstCharsPtr = srcLen;
+    memcpy(dst, src, (size_t) srcLen);
+    return result;
+}
+
+/*
+ *-------------------------------------------------------------------------
+ *
+ * UtfExtToUtfIntProc --
+ *
+ *	Convert from UTF-8 to UTF-8. While converting null-bytes from the
+ *	Tcl's internal representation (0xc0, 0x80) to the official
+ *	representation (0x00). See UtfToUtfProc for details.
+ *
+ * Results:
+ *	Returns TCL_OK if conversion was successful.
+ *
+ * Side effects:
+ *	None.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+static int
+UtfIntToUtfExtProc(
+    ClientData clientData,	/* Not used. */
+    const char *src,		/* Source string in UTF-8. */
+    int srcLen,			/* Source string length in bytes. */
+    int flags,			/* Conversion control flags. */
+    Tcl_EncodingState *statePtr,/* Place for conversion routine to store state
+				 * information used during a piecewise
+				 * conversion. Contents of statePtr are
+				 * initialized and/or reset by conversion
+				 * routine under control of flags argument. */
+    char *dst,			/* Output buffer in which converted string
+				 * is stored. */
+    int dstLen,			/* The maximum length of output buffer in
+				 * bytes. */
+    int *srcReadPtr,		/* Filled with the number of bytes from the
+				 * source string that were converted. This may
+				 * be less than the original source length if
+				 * there was a problem converting some source
+				 * characters. */
+    int *dstWrotePtr,		/* Filled with the number of bytes that were
+				 * stored in the output buffer as a result of
+				 * the conversion. */
+    int *dstCharsPtr)		/* Filled with the number of characters that
+				 * correspond to the bytes stored in the
+				 * output buffer. */
+{
+    return UtfToUtfProc(clientData, src, srcLen, flags, statePtr, dst, dstLen,
+	    srcReadPtr, dstWrotePtr, dstCharsPtr, 1);
+}
+
+/*
+ *-------------------------------------------------------------------------
+ *
+ * UtfExtToUtfIntProc --
+ *
+ *	Convert from UTF-8 to UTF-8 while converting null-bytes from the
+ *	official representation (0x00) to Tcl's internal representation (0xc0,
+ *	0x80). See UtfToUtfProc for details.
+ *
+ * Results:
+ *	Returns TCL_OK if conversion was successful.
+ *
+ * Side effects:
+ *	None.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+static int
+UtfExtToUtfIntProc(
+    ClientData clientData,	/* Not used. */
+    const char *src,		/* Source string in UTF-8. */
+    int srcLen,			/* Source string length in bytes. */
+    int flags,			/* Conversion control flags. */
+    Tcl_EncodingState *statePtr,/* Place for conversion routine to store state
+				 * information used during a piecewise
+				 * conversion. Contents of statePtr are
+				 * initialized and/or reset by conversion
+				 * routine under control of flags argument. */
+    char *dst,			/* Output buffer in which converted string is
+				 * stored. */
+    int dstLen,			/* The maximum length of output buffer in
+				 * bytes. */
+    int *srcReadPtr,		/* Filled with the number of bytes from the
+				 * source string that were converted. This may
+				 * be less than the original source length if
+				 * there was a problem converting some source
+				 * characters. */
+    int *dstWrotePtr,		/* Filled with the number of bytes that were
+				 * stored in the output buffer as a result of
+				 * the conversion. */
+    int *dstCharsPtr)		/* Filled with the number of characters that
+				 * correspond to the bytes stored in the
+				 * output buffer. */
+{
+    return UtfToUtfProc(clientData, src, srcLen, flags, statePtr, dst, dstLen,
+	    srcReadPtr, dstWrotePtr, dstCharsPtr, 0);
+}
+
+/*
+ *-------------------------------------------------------------------------
+ *
+ * UtfToUtfProc --
+ *
+ *	Convert from UTF-8 to UTF-8. Note that the UTF-8 to UTF-8 translation
+ *	is not a no-op, because it will turn a stream of improperly formed
+ *	UTF-8 into a properly formed stream.
+ *
+ * Results:
+ *	Returns TCL_OK if conversion was successful.
+ *
+ * Side effects:
+ *	None.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+static int
+UtfToUtfProc(
+    ClientData clientData,	/* Not used. */
+    const char *src,		/* Source string in UTF-8. */
+    int srcLen,			/* Source string length in bytes. */
+    int flags,			/* Conversion control flags. */
+    Tcl_EncodingState *statePtr,/* Place for conversion routine to store state
+				 * information used during a piecewise
+				 * conversion. Contents of statePtr are
+				 * initialized and/or reset by conversion
+				 * routine under control of flags argument. */
+    char *dst,			/* Output buffer in which converted string is
+				 * stored. */
+    int dstLen,			/* The maximum length of output buffer in
+				 * bytes. */
+    int *srcReadPtr,		/* Filled with the number of bytes from the
+				 * source string that were converted. This may
+				 * be less than the original source length if
+				 * there was a problem converting some source
+				 * characters. */
+    int *dstWrotePtr,		/* Filled with the number of bytes that were
+				 * stored in the output buffer as a result of
+				 * the conversion. */
+    int *dstCharsPtr,		/* Filled with the number of characters that
+				 * correspond to the bytes stored in the
+				 * output buffer. */
+    int pureNullMode)		/* Convert embedded nulls from internal
+				 * representation to real null-bytes or vice
+				 * versa. */
+{
+    const char *srcStart, *srcEnd, *srcClose;
+    const char *dstStart, *dstEnd;
+    int result, numChars, charLimit = INT_MAX;
+    Tcl_UniChar ch;
+
+    result = TCL_OK;
+
+    srcStart = src;
+    srcEnd = src + srcLen;
+    srcClose = srcEnd;
+    if ((flags & TCL_ENCODING_END) == 0) {
+	srcClose -= TCL_UTF_MAX;
+    }
+    if (flags & TCL_ENCODING_CHAR_LIMIT) {
+	charLimit = *dstCharsPtr;
+    }
+
+    dstStart = dst;
+    dstEnd = dst + dstLen - TCL_UTF_MAX;
+
+    for (numChars = 0; src < srcEnd && numChars <= charLimit; numChars++) {
+	if ((src > srcClose) && (!Tcl_UtfCharComplete(src, srcEnd - src))) {
+	    /*
+	     * If there is more string to follow, this will ensure that the
+	     * last UTF-8 character in the source buffer hasn't been cut off.
+	     */
+
+	    result = TCL_CONVERT_MULTIBYTE;
+	    break;
+	}
+	if (dst > dstEnd) {
+	    result = TCL_CONVERT_NOSPACE;
+	    break;
+	}
+	if (UCHAR(*src) < 0x80 && !(UCHAR(*src) == 0 && pureNullMode == 0)) {
+	    /*
+	     * Copy 7bit chatacters, but skip null-bytes when we are in input
+	     * mode, so that they get converted to 0xc080.
+	     */
+
+	    *dst++ = *src++;
+	} else if (pureNullMode == 1 && UCHAR(*src) == 0xc0 &&
+		(src + 1 < srcEnd) && UCHAR(*(src+1)) == 0x80) {
+	    /*
+	     * Convert 0xc080 to real nulls when we are in output mode.
+	     */
+
+	    *dst++ = 0;
+	    src += 2;
+	} else if (!Tcl_UtfCharComplete(src, srcEnd - src)) {
+	    /*
+	     * Always check before using Tcl_UtfToUniChar. Not doing can so
+	     * cause it run beyond the endof the buffer! If we happen such an
+	     * incomplete char its byts are made to represent themselves.
+	     */
+
+	    ch = (unsigned char) *src;
+	    src += 1;
+	    dst += Tcl_UniCharToUtf(ch, dst);
+	} else {
+	    src += Tcl_UtfToUniChar(src, &ch);
+	    dst += Tcl_UniCharToUtf(ch, dst);
+	}
+    }
+
+    *srcReadPtr = src - srcStart;
+    *dstWrotePtr = dst - dstStart;
+    *dstCharsPtr = numChars;
+    return result;
+}
+
+/*
+ *-------------------------------------------------------------------------
+ *
+ * UnicodeToUtfProc --
+ *
+ *	Convert from Unicode to UTF-8.
+ *
+ * Results:
+ *	Returns TCL_OK if conversion was successful.
+ *
+ * Side effects:
+ *	None.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+static int
+UnicodeToUtfProc(
+    ClientData clientData,	/* Not used. */
+    const char *src,		/* Source string in Unicode. */
+    int srcLen,			/* Source string length in bytes. */
+    int flags,			/* Conversion control flags. */
+    Tcl_EncodingState *statePtr,/* Place for conversion routine to store state
+				 * information used during a piecewise
+				 * conversion. Contents of statePtr are
+				 * initialized and/or reset by conversion
+				 * routine under control of flags argument. */
+    char *dst,			/* Output buffer in which converted string is
+				 * stored. */
+    int dstLen,			/* The maximum length of output buffer in
+				 * bytes. */
+    int *srcReadPtr,		/* Filled with the number of bytes from the
+				 * source string that were converted. This may
+				 * be less than the original source length if
+				 * there was a problem converting some source
+				 * characters. */
+    int *dstWrotePtr,		/* Filled with the number of bytes that were
+				 * stored in the output buffer as a result of
+				 * the conversion. */
+    int *dstCharsPtr)		/* Filled with the number of characters that
+				 * correspond to the bytes stored in the
+				 * output buffer. */
+{
+    const char *srcStart, *srcEnd;
+    const char *dstEnd, *dstStart;
+    int result, numChars, charLimit = INT_MAX;
+    Tcl_UniChar ch;
+
+    if (flags & TCL_ENCODING_CHAR_LIMIT) {
+	charLimit = *dstCharsPtr;
+    }
+    result = TCL_OK;
+    if ((srcLen % sizeof(Tcl_UniChar)) != 0) {
+	result = TCL_CONVERT_MULTIBYTE;
+	srcLen /= sizeof(Tcl_UniChar);
+	srcLen *= sizeof(Tcl_UniChar);
+    }
+
+    srcStart = src;
+    srcEnd = src + srcLen;
+
+    dstStart = dst;
+    dstEnd = dst + dstLen - TCL_UTF_MAX;
+
+    for (numChars = 0; src < srcEnd && numChars <= charLimit; numChars++) {
+	if (dst > dstEnd) {
+	    result = TCL_CONVERT_NOSPACE;
+	    break;
+	}
+
+	/*
+	 * Special case for 1-byte utf chars for speed. Make sure we work with
+	 * Tcl_UniChar-size data.
+	 */
+
+	ch = *(Tcl_UniChar *)src;
+	if (ch && ch < 0x80) {
+	    *dst++ = (ch & 0xFF);
+	} else {
+	    dst += Tcl_UniCharToUtf(ch, dst);
+	}
+	src += sizeof(Tcl_UniChar);
+    }
+
+    *srcReadPtr = src - srcStart;
+    *dstWrotePtr = dst - dstStart;
+    *dstCharsPtr = numChars;
+    return result;
+}
+
+/*
+ *-------------------------------------------------------------------------
+ *
+ * UtfToUnicodeProc --
+ *
+ *	Convert from UTF-8 to Unicode.
+ *
+ * Results:
+ *	Returns TCL_OK if conversion was successful.
+ *
+ * Side effects:
+ *	None.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+static int
+UtfToUnicodeProc(
+    ClientData clientData,	/* TableEncodingData that specifies
+				 * encoding. */
+    const char *src,		/* Source string in UTF-8. */
+    int srcLen,			/* Source string length in bytes. */
+    int flags,			/* Conversion control flags. */
+    Tcl_EncodingState *statePtr,/* Place for conversion routine to store state
+				 * information used during a piecewise
+				 * conversion. Contents of statePtr are
+				 * initialized and/or reset by conversion
+				 * routine under control of flags argument. */
+    char *dst,			/* Output buffer in which converted string is
+				 * stored. */
+    int dstLen,			/* The maximum length of output buffer in
+				 * bytes. */
+    int *srcReadPtr,		/* Filled with the number of bytes from the
+				 * source string that were converted. This may
+				 * be less than the original source length if
+				 * there was a problem converting some source
+				 * characters. */
+    int *dstWrotePtr,		/* Filled with the number of bytes that were
+				 * stored in the output buffer as a result of
+				 * the conversion. */
+    int *dstCharsPtr)		/* Filled with the number of characters that
+				 * correspond to the bytes stored in the
+				 * output buffer. */
+{
+    const char *srcStart, *srcEnd, *srcClose, *dstStart, *dstEnd;
+    int result, numChars;
+    Tcl_UniChar ch;
+
+    srcStart = src;
+    srcEnd = src + srcLen;
+    srcClose = srcEnd;
+    if ((flags & TCL_ENCODING_END) == 0) {
+	srcClose -= TCL_UTF_MAX;
+    }
+
+    dstStart = dst;
+    dstEnd   = dst + dstLen - sizeof(Tcl_UniChar);
+
+    result = TCL_OK;
+    for (numChars = 0; src < srcEnd; numChars++) {
+	if ((src > srcClose) && (!Tcl_UtfCharComplete(src, srcEnd - src))) {
+	    /*
+	     * If there is more string to follow, this will ensure that the
+	     * last UTF-8 character in the source buffer hasn't been cut off.
+	     */
+
+	    result = TCL_CONVERT_MULTIBYTE;
+	    break;
+	}
+	if (dst > dstEnd) {
+	    result = TCL_CONVERT_NOSPACE;
+	    break;
+	}
+	src += TclUtfToUniChar(src, &ch);
+
+	/*
+	 * Need to handle this in a way that won't cause misalignment by
+	 * casting dst to a Tcl_UniChar. [Bug 1122671]
+	 */
+
+#ifdef WORDS_BIGENDIAN
+#if TCL_UTF_MAX > 4
+	*dst++ = (ch >> 24);
+	*dst++ = ((ch >> 16) & 0xFF);
+	*dst++ = ((ch >> 8) & 0xFF);
+	*dst++ = (ch & 0xFF);
+#else
+	*dst++ = (ch >> 8);
+	*dst++ = (ch & 0xFF);
+#endif
+#else
+#if TCL_UTF_MAX > 4
+	*dst++ = (ch & 0xFF);
+	*dst++ = ((ch >> 8) & 0xFF);
+	*dst++ = ((ch >> 16) & 0xFF);
+	*dst++ = (ch >> 24);
+#else
+	*dst++ = (ch & 0xFF);
+	*dst++ = (ch >> 8);
+#endif
+#endif
+    }
+    *srcReadPtr = src - srcStart;
+    *dstWrotePtr = dst - dstStart;
+    *dstCharsPtr = numChars;
+    return result;
+}
+
+/*
+ *-------------------------------------------------------------------------
+ *
+ * TableToUtfProc --
+ *
+ *	Convert from the encoding specified by the TableEncodingData into
+ *	UTF-8.
+ *
+ * Results:
+ *	Returns TCL_OK if conversion was successful.
+ *
+ * Side effects:
+ *	None.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+static int
+TableToUtfProc(
+    ClientData clientData,	/* TableEncodingData that specifies
+				 * encoding. */
+    const char *src,		/* Source string in specified encoding. */
+    int srcLen,			/* Source string length in bytes. */
+    int flags,			/* Conversion control flags. */
+    Tcl_EncodingState *statePtr,/* Place for conversion routine to store state
+				 * information used during a piecewise
+				 * conversion. Contents of statePtr are
+				 * initialized and/or reset by conversion
+				 * routine under control of flags argument. */
+    char *dst,			/* Output buffer in which converted string is
+				 * stored. */
+    int dstLen,			/* The maximum length of output buffer in
+				 * bytes. */
+    int *srcReadPtr,		/* Filled with the number of bytes from the
+				 * source string that were converted. This may
+				 * be less than the original source length if
+				 * there was a problem converting some source
+				 * characters. */
+    int *dstWrotePtr,		/* Filled with the number of bytes that were
+				 * stored in the output buffer as a result of
+				 * the conversion. */
+    int *dstCharsPtr)		/* Filled with the number of characters that
+				 * correspond to the bytes stored in the
+				 * output buffer. */
+{
+    const char *srcStart, *srcEnd;
+    const char *dstEnd, *dstStart, *prefixBytes;
+    int result, byte, numChars, charLimit = INT_MAX;
+    Tcl_UniChar ch;
+    const unsigned short *const *toUnicode;
+    const unsigned short *pageZero;
+    TableEncodingData *dataPtr = clientData;
+
+    if (flags & TCL_ENCODING_CHAR_LIMIT) {
+	charLimit = *dstCharsPtr;
+    }
+    srcStart = src;
+    srcEnd = src + srcLen;
+
+    dstStart = dst;
+    dstEnd = dst + dstLen - TCL_UTF_MAX;
+
+    toUnicode = (const unsigned short *const *) dataPtr->toUnicode;
+    prefixBytes = dataPtr->prefixBytes;
+    pageZero = toUnicode[0];
+
+    result = TCL_OK;
+    for (numChars = 0; src < srcEnd && numChars <= charLimit; numChars++) {
+	if (dst > dstEnd) {
+	    result = TCL_CONVERT_NOSPACE;
+	    break;
+	}
+	byte = *((unsigned char *) src);
+	if (prefixBytes[byte]) {
+	    src++;
+	    if (src >= srcEnd) {
+		src--;
+		result = TCL_CONVERT_MULTIBYTE;
+		break;
+	    }
+	    ch = toUnicode[byte][*((unsigned char *) src)];
+	} else {
+	    ch = pageZero[byte];
+	}
+	if ((ch == 0) && (byte != 0)) {
+	    if (flags & TCL_ENCODING_STOPONERROR) {
+		result = TCL_CONVERT_SYNTAX;
+		break;
+	    }
+	    if (prefixBytes[byte]) {
+		src--;
+	    }
+	    ch = (Tcl_UniChar) byte;
+	}
+
+	/*
+	 * Special case for 1-byte utf chars for speed.
+	 */
+
+	if (ch && ch < 0x80) {
+	    *dst++ = (char) ch;
+	} else {
+	    dst += Tcl_UniCharToUtf(ch, dst);
+	}
+	src++;
+    }
+
+    *srcReadPtr = src - srcStart;
+    *dstWrotePtr = dst - dstStart;
+    *dstCharsPtr = numChars;
+    return result;
+}
+
+/*
+ *-------------------------------------------------------------------------
+ *
+ * TableFromUtfProc --
+ *
+ *	Convert from UTF-8 into the encoding specified by the
+ *	TableEncodingData.
+ *
+ * Results:
+ *	Returns TCL_OK if conversion was successful.
+ *
+ * Side effects:
+ *	None.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+static int
+TableFromUtfProc(
+    ClientData clientData,	/* TableEncodingData that specifies
+				 * encoding. */
+    const char *src,		/* Source string in UTF-8. */
+    int srcLen,			/* Source string length in bytes. */
+    int flags,			/* Conversion control flags. */
+    Tcl_EncodingState *statePtr,/* Place for conversion routine to store state
+				 * information used during a piecewise
+				 * conversion. Contents of statePtr are
+				 * initialized and/or reset by conversion
+				 * routine under control of flags argument. */
+    char *dst,			/* Output buffer in which converted string is
+				 * stored. */
+    int dstLen,			/* The maximum length of output buffer in
+				 * bytes. */
+    int *srcReadPtr,		/* Filled with the number of bytes from the
+				 * source string that were converted. This may
+				 * be less than the original source length if
+				 * there was a problem converting some source
+				 * characters. */
+    int *dstWrotePtr,		/* Filled with the number of bytes that were
+				 * stored in the output buffer as a result of
+				 * the conversion. */
+    int *dstCharsPtr)		/* Filled with the number of characters that
+				 * correspond to the bytes stored in the
+				 * output buffer. */
+{
+    const char *srcStart, *srcEnd, *srcClose;
+    const char *dstStart, *dstEnd, *prefixBytes;
+    Tcl_UniChar ch;
+    int result, len, word, numChars;
+    TableEncodingData *dataPtr = clientData;
+    const unsigned short *const *fromUnicode;
+
+    result = TCL_OK;
+
+    prefixBytes = dataPtr->prefixBytes;
+    fromUnicode = (const unsigned short *const *) dataPtr->fromUnicode;
+
+    srcStart = src;
+    srcEnd = src + srcLen;
+    srcClose = srcEnd;
+    if ((flags & TCL_ENCODING_END) == 0) {
+	srcClose -= TCL_UTF_MAX;
+    }
+
+    dstStart = dst;
+    dstEnd = dst + dstLen - 1;
+
+    for (numChars = 0; src < srcEnd; numChars++) {
+	if ((src > srcClose) && (!Tcl_UtfCharComplete(src, srcEnd - src))) {
+	    /*
+	     * If there is more string to follow, this will ensure that the
+	     * last UTF-8 character in the source buffer hasn't been cut off.
+	     */
+
+	    result = TCL_CONVERT_MULTIBYTE;
+	    break;
+	}
+	len = TclUtfToUniChar(src, &ch);
+
+#if TCL_UTF_MAX > 3
+	/*
+	 * This prevents a crash condition. More evaluation is required for
+	 * full support of int Tcl_UniChar. [Bug 1004065]
+	 */
+
+	if (ch & 0xffff0000) {
+	    word = 0;
+	} else
+#endif
+	    word = fromUnicode[(ch >> 8)][ch & 0xff];
+
+	if ((word == 0) && (ch != 0)) {
+	    if (flags & TCL_ENCODING_STOPONERROR) {
+		result = TCL_CONVERT_UNKNOWN;
+		break;
+	    }
+	    word = dataPtr->fallback;
+	}
+	if (prefixBytes[(word >> 8)] != 0) {
+	    if (dst + 1 > dstEnd) {
+		result = TCL_CONVERT_NOSPACE;
+		break;
+	    }
+	    dst[0] = (char) (word >> 8);
+	    dst[1] = (char) word;
+	    dst += 2;
+	} else {
+	    if (dst > dstEnd) {
+		result = TCL_CONVERT_NOSPACE;
+		break;
+	    }
+	    dst[0] = (char) word;
+	    dst++;
+	}
+	src += len;
+    }
+
+    *srcReadPtr = src - srcStart;
+    *dstWrotePtr = dst - dstStart;
+    *dstCharsPtr = numChars;
+    return result;
+}
+
+/*
+ *-------------------------------------------------------------------------
+ *
+ * Iso88591ToUtfProc --
+ *
+ *	Convert from the "iso8859-1" encoding into UTF-8.
+ *
+ * Results:
+ *	Returns TCL_OK if conversion was successful.
+ *
+ * Side effects:
+ *	None.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+static int
+Iso88591ToUtfProc(
+    ClientData clientData,	/* Ignored. */
+    const char *src,		/* Source string in specified encoding. */
+    int srcLen,			/* Source string length in bytes. */
+    int flags,			/* Conversion control flags. */
+    Tcl_EncodingState *statePtr,/* Place for conversion routine to store state
+				 * information used during a piecewise
+				 * conversion. Contents of statePtr are
+				 * initialized and/or reset by conversion
+				 * routine under control of flags argument. */
+    char *dst,			/* Output buffer in which converted string is
+				 * stored. */
+    int dstLen,			/* The maximum length of output buffer in
+				 * bytes. */
+    int *srcReadPtr,		/* Filled with the number of bytes from the
+				 * source string that were converted. This may
+				 * be less than the original source length if
+				 * there was a problem converting some source
+				 * characters. */
+    int *dstWrotePtr,		/* Filled with the number of bytes that were
+				 * stored in the output buffer as a result of
+				 * the conversion. */
+    int *dstCharsPtr)		/* Filled with the number of characters that
+				 * correspond to the bytes stored in the
+				 * output buffer. */
+{
+    const char *srcStart, *srcEnd;
+    const char *dstEnd, *dstStart;
+    int result, numChars, charLimit = INT_MAX;
+
+    if (flags & TCL_ENCODING_CHAR_LIMIT) {
+	charLimit = *dstCharsPtr;
+    }
+    srcStart = src;
+    srcEnd = src + srcLen;
+
+    dstStart = dst;
+    dstEnd = dst + dstLen - TCL_UTF_MAX;
+
+    result = TCL_OK;
+    for (numChars = 0; src < srcEnd && numChars <= charLimit; numChars++) {
+	Tcl_UniChar ch;
+
+	if (dst > dstEnd) {
+	    result = TCL_CONVERT_NOSPACE;
+	    break;
+	}
+	ch = (Tcl_UniChar) *((unsigned char *) src);
+
+	/*
+	 * Special case for 1-byte utf chars for speed.
+	 */
+
+	if (ch && ch < 0x80) {
+	    *dst++ = (char) ch;
+	} else {
+	    dst += Tcl_UniCharToUtf(ch, dst);
+	}
+	src++;
+    }
+
+    *srcReadPtr = src - srcStart;
+    *dstWrotePtr = dst - dstStart;
+    *dstCharsPtr = numChars;
+    return result;
+}
+
+/*
+ *-------------------------------------------------------------------------
+ *
+ * Iso88591FromUtfProc --
+ *
+ *	Convert from UTF-8 into the encoding "iso8859-1".
+ *
+ * Results:
+ *	Returns TCL_OK if conversion was successful.
+ *
+ * Side effects:
+ *	None.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+static int
+Iso88591FromUtfProc(
+    ClientData clientData,	/* Ignored. */
+    const char *src,		/* Source string in UTF-8. */
+    int srcLen,			/* Source string length in bytes. */
+    int flags,			/* Conversion control flags. */
+    Tcl_EncodingState *statePtr,/* Place for conversion routine to store state
+				 * information used during a piecewise
+				 * conversion. Contents of statePtr are
+				 * initialized and/or reset by conversion
+				 * routine under control of flags argument. */
+    char *dst,			/* Output buffer in which converted string is
+				 * stored. */
+    int dstLen,			/* The maximum length of output buffer in
+				 * bytes. */
+    int *srcReadPtr,		/* Filled with the number of bytes from the
+				 * source string that were converted. This may
+				 * be less than the original source length if
+				 * there was a problem converting some source
+				 * characters. */
+    int *dstWrotePtr,		/* Filled with the number of bytes that were
+				 * stored in the output buffer as a result of
+				 * the conversion. */
+    int *dstCharsPtr)		/* Filled with the number of characters that
+				 * correspond to the bytes stored in the
+				 * output buffer. */
+{
+    const char *srcStart, *srcEnd, *srcClose;
+    const char *dstStart, *dstEnd;
+    int result, numChars;
+
+    result = TCL_OK;
+
+    srcStart = src;
+    srcEnd = src + srcLen;
+    srcClose = srcEnd;
+    if ((flags & TCL_ENCODING_END) == 0) {
+	srcClose -= TCL_UTF_MAX;
+    }
+
+    dstStart = dst;
+    dstEnd = dst + dstLen - 1;
+
+    for (numChars = 0; src < srcEnd; numChars++) {
+	Tcl_UniChar ch;
+	int len;
+
+	if ((src > srcClose) && (!Tcl_UtfCharComplete(src, srcEnd - src))) {
+	    /*
+	     * If there is more string to follow, this will ensure that the
+	     * last UTF-8 character in the source buffer hasn't been cut off.
+	     */
+
+	    result = TCL_CONVERT_MULTIBYTE;
+	    break;
+	}
+	len = TclUtfToUniChar(src, &ch);
+
+	/*
+	 * Check for illegal characters.
+	 */
+
+	if (ch > 0xff) {
+	    if (flags & TCL_ENCODING_STOPONERROR) {
+		result = TCL_CONVERT_UNKNOWN;
+		break;
+	    }
+
+	    /*
+	     * Plunge on, using '?' as a fallback character.
+	     */
+
+	    ch = (Tcl_UniChar) '?';
+	}
+
+	if (dst > dstEnd) {
+	    result = TCL_CONVERT_NOSPACE;
+	    break;
+	}
+	*(dst++) = (char) ch;
+	src += len;
+    }
+
+    *srcReadPtr = src - srcStart;
+    *dstWrotePtr = dst - dstStart;
+    *dstCharsPtr = numChars;
+    return result;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * TableFreeProc --
+ *
+ *	This function is invoked when an encoding is deleted. It deletes the
+ *	memory used by the TableEncodingData.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Memory freed.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+static void
+TableFreeProc(
+    ClientData clientData)	/* TableEncodingData that specifies
+				 * encoding. */
+{
+    TableEncodingData *dataPtr = clientData;
+
+    /*
+     * Make sure we aren't freeing twice on shutdown. [Bug 219314]
+     */
+
+    ckfree(dataPtr->toUnicode);
+    dataPtr->toUnicode = NULL;
+    ckfree(dataPtr->fromUnicode);
+    dataPtr->fromUnicode = NULL;
+    ckfree(dataPtr);
+}
+
+/*
+ *-------------------------------------------------------------------------
+ *
+ * EscapeToUtfProc --
+ *
+ *	Convert from the encoding specified by the EscapeEncodingData into
+ *	UTF-8.
+ *
+ * Results:
+ *	Returns TCL_OK if conversion was successful.
+ *
+ * Side effects:
+ *	None.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+static int
+EscapeToUtfProc(
+    ClientData clientData,	/* EscapeEncodingData that specifies
+				 * encoding. */
+    const char *src,		/* Source string in specified encoding. */
+    int srcLen,			/* Source string length in bytes. */
+    int flags,			/* Conversion control flags. */
+    Tcl_EncodingState *statePtr,/* Place for conversion routine to store state
+				 * information used during a piecewise
+				 * conversion. Contents of statePtr are
+				 * initialized and/or reset by conversion
+				 * routine under control of flags argument. */
+    char *dst,			/* Output buffer in which converted string is
+				 * stored. */
+    int dstLen,			/* The maximum length of output buffer in
+				 * bytes. */
+    int *srcReadPtr,		/* Filled with the number of bytes from the
+				 * source string that were converted. This may
+				 * be less than the original source length if
+				 * there was a problem converting some source
+				 * characters. */
+    int *dstWrotePtr,		/* Filled with the number of bytes that were
+				 * stored in the output buffer as a result of
+				 * the conversion. */
+    int *dstCharsPtr)		/* Filled with the number of characters that
+				 * correspond to the bytes stored in the
+				 * output buffer. */
+{
+    EscapeEncodingData *dataPtr = clientData;
+    const char *prefixBytes, *tablePrefixBytes, *srcStart, *srcEnd;
+    const unsigned short *const *tableToUnicode;
+    const Encoding *encodingPtr;
+    int state, result, numChars, charLimit = INT_MAX;
+    const char *dstStart, *dstEnd;
+
+    if (flags & TCL_ENCODING_CHAR_LIMIT) {
+	charLimit = *dstCharsPtr;
+    }
+    result = TCL_OK;
+    tablePrefixBytes = NULL;	/* lint. */
+    tableToUnicode = NULL;	/* lint. */
+    prefixBytes = dataPtr->prefixBytes;
+    encodingPtr = NULL;
+
+    srcStart = src;
+    srcEnd = src + srcLen;
+
+    dstStart = dst;
+    dstEnd = dst + dstLen - TCL_UTF_MAX;
+
+    state = PTR2INT(*statePtr);
+    if (flags & TCL_ENCODING_START) {
+	state = 0;
+    }
+
+    for (numChars = 0; src < srcEnd && numChars <= charLimit; ) {
+	int byte, hi, lo, ch;
+
+	if (dst > dstEnd) {
+	    result = TCL_CONVERT_NOSPACE;
+	    break;
+	}
+	byte = *((unsigned char *) src);
+	if (prefixBytes[byte]) {
+	    unsigned left, len, longest;
+	    int checked, i;
+	    const EscapeSubTable *subTablePtr;
+
+	    /*
+	     * Saw the beginning of an escape sequence.
+	     */
+
+	    left = srcEnd - src;
+	    len = dataPtr->initLen;
+	    longest = len;
+	    checked = 0;
+
+	    if (len <= left) {
+		checked++;
+		if ((len > 0) && (memcmp(src, dataPtr->init, len) == 0)) {
+		    /*
+		     * If we see initialization string, skip it, even if we're
+		     * not at the beginning of the buffer.
+		     */
+
+		    src += len;
+		    continue;
+		}
+	    }
+
+	    len = dataPtr->finalLen;
+	    if (len > longest) {
+		longest = len;
+	    }
+
+	    if (len <= left) {
+		checked++;
+		if ((len > 0) && (memcmp(src, dataPtr->final, len) == 0)) {
+		    /*
+		     * If we see finalization string, skip it, even if we're
+		     * not at the end of the buffer.
+		     */
+
+		    src += len;
+		    continue;
+		}
+	    }
+
+	    subTablePtr = dataPtr->subTables;
+	    for (i = 0; i < dataPtr->numSubTables; i++) {
+		len = subTablePtr->sequenceLen;
+		if (len > longest) {
+		    longest = len;
+		}
+		if (len <= left) {
+		    checked++;
+		    if ((len > 0) &&
+			    (memcmp(src, subTablePtr->sequence, len) == 0)) {
+			state = i;
+			encodingPtr = NULL;
+			subTablePtr = NULL;
+			src += len;
+			break;
+		    }
+		}
+		subTablePtr++;
+	    }
+
+	    if (subTablePtr == NULL) {
+		/*
+		 * A match was found, the escape sequence was consumed, and
+		 * the state was updated.
+		 */
+
+		continue;
+	    }
+
+	    /*
+	     * We have a split-up or unrecognized escape sequence. If we
+	     * checked all the sequences, then it's a syntax error, otherwise
+	     * we need more bytes to determine a match.
+	     */
+
+	    if ((checked == dataPtr->numSubTables + 2)
+		    || (flags & TCL_ENCODING_END)) {
+		if ((flags & TCL_ENCODING_STOPONERROR) == 0) {
+		    /*
+		     * Skip the unknown escape sequence.
+		     */
+
+		    src += longest;
+		    continue;
+		}
+		result = TCL_CONVERT_SYNTAX;
+	    } else {
+		result = TCL_CONVERT_MULTIBYTE;
+	    }
+	    break;
+	}
+
+	if (encodingPtr == NULL) {
+	    TableEncodingData *tableDataPtr;
+
+	    encodingPtr = GetTableEncoding(dataPtr, state);
+	    tableDataPtr = encodingPtr->clientData;
+	    tablePrefixBytes = tableDataPtr->prefixBytes;
+	    tableToUnicode = (const unsigned short *const*)
+		    tableDataPtr->toUnicode;
+	}
+
+	if (tablePrefixBytes[byte]) {
+	    src++;
+	    if (src >= srcEnd) {
+		src--;
+		result = TCL_CONVERT_MULTIBYTE;
+		break;
+	    }
+	    hi = byte;
+	    lo = *((unsigned char *) src);
+	} else {
+	    hi = 0;
+	    lo = byte;
+	}
+
+	ch = tableToUnicode[hi][lo];
+	dst += Tcl_UniCharToUtf(ch, dst);
+	src++;
+	numChars++;
+    }
+
+    *statePtr = (Tcl_EncodingState) INT2PTR(state);
+    *srcReadPtr = src - srcStart;
+    *dstWrotePtr = dst - dstStart;
+    *dstCharsPtr = numChars;
+    return result;
+}
+
+/*
+ *-------------------------------------------------------------------------
+ *
+ * EscapeFromUtfProc --
+ *
+ *	Convert from UTF-8 into the encoding specified by the
+ *	EscapeEncodingData.
+ *
+ * Results:
+ *	Returns TCL_OK if conversion was successful.
+ *
+ * Side effects:
+ *	None.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+static int
+EscapeFromUtfProc(
+    ClientData clientData,	/* EscapeEncodingData that specifies
+				 * encoding. */
+    const char *src,		/* Source string in UTF-8. */
+    int srcLen,			/* Source string length in bytes. */
+    int flags,			/* Conversion control flags. */
+    Tcl_EncodingState *statePtr,/* Place for conversion routine to store state
+				 * information used during a piecewise
+				 * conversion. Contents of statePtr are
+				 * initialized and/or reset by conversion
+				 * routine under control of flags argument. */
+    char *dst,			/* Output buffer in which converted string is
+				 * stored. */
+    int dstLen,			/* The maximum length of output buffer in
+				 * bytes. */
+    int *srcReadPtr,		/* Filled with the number of bytes from the
+				 * source string that were converted. This may
+				 * be less than the original source length if
+				 * there was a problem converting some source
+				 * characters. */
+    int *dstWrotePtr,		/* Filled with the number of bytes that were
+				 * stored in the output buffer as a result of
+				 * the conversion. */
+    int *dstCharsPtr)		/* Filled with the number of characters that
+				 * correspond to the bytes stored in the
+				 * output buffer. */
+{
+    EscapeEncodingData *dataPtr = clientData;
+    const Encoding *encodingPtr;
+    const char *srcStart, *srcEnd, *srcClose;
+    const char *dstStart, *dstEnd;
+    int state, result, numChars;
+    const TableEncodingData *tableDataPtr;
+    const char *tablePrefixBytes;
+    const unsigned short *const *tableFromUnicode;
+
+    result = TCL_OK;
+
+    srcStart = src;
+    srcEnd = src + srcLen;
+    srcClose = srcEnd;
+    if ((flags & TCL_ENCODING_END) == 0) {
+	srcClose -= TCL_UTF_MAX;
+    }
+
+    dstStart = dst;
+    dstEnd = dst + dstLen - 1;
+
+    /*
+     * RFC 1468 states that the text starts in ASCII, and switches to Japanese
+     * characters, and that the text must end in ASCII. [Patch 474358]
+     */
+
+    if (flags & TCL_ENCODING_START) {
+	state = 0;
+	if ((dst + dataPtr->initLen) > dstEnd) {
+	    *srcReadPtr = 0;
+	    *dstWrotePtr = 0;
+	    return TCL_CONVERT_NOSPACE;
+	}
+	memcpy(dst, dataPtr->init, (size_t)dataPtr->initLen);
+	dst += dataPtr->initLen;
+    } else {
+	state = PTR2INT(*statePtr);
+    }
+
+    encodingPtr = GetTableEncoding(dataPtr, state);
+    tableDataPtr = encodingPtr->clientData;
+    tablePrefixBytes = tableDataPtr->prefixBytes;
+    tableFromUnicode = (const unsigned short *const *)
+	    tableDataPtr->fromUnicode;
+
+    for (numChars = 0; src < srcEnd; numChars++) {
+	unsigned len;
+	int word;
+	Tcl_UniChar ch;
+
+	if ((src > srcClose) && (!Tcl_UtfCharComplete(src, srcEnd - src))) {
+	    /*
+	     * If there is more string to follow, this will ensure that the
+	     * last UTF-8 character in the source buffer hasn't been cut off.
+	     */
+
+	    result = TCL_CONVERT_MULTIBYTE;
+	    break;
+	}
+	len = TclUtfToUniChar(src, &ch);
+	word = tableFromUnicode[(ch >> 8)][ch & 0xff];
+
+	if ((word == 0) && (ch != 0)) {
+	    int oldState;
+	    const EscapeSubTable *subTablePtr;
+
+	    oldState = state;
+	    for (state = 0; state < dataPtr->numSubTables; state++) {
+		encodingPtr = GetTableEncoding(dataPtr, state);
+		tableDataPtr = encodingPtr->clientData;
+		word = tableDataPtr->fromUnicode[(ch >> 8)][ch & 0xff];
+		if (word != 0) {
+		    break;
+		}
+	    }
+
+	    if (word == 0) {
+		state = oldState;
+		if (flags & TCL_ENCODING_STOPONERROR) {
+		    result = TCL_CONVERT_UNKNOWN;
+		    break;
+		}
+		encodingPtr = GetTableEncoding(dataPtr, state);
+		tableDataPtr = encodingPtr->clientData;
+		word = tableDataPtr->fallback;
+	    }
+
+	    tablePrefixBytes = (const char *) tableDataPtr->prefixBytes;
+	    tableFromUnicode = (const unsigned short *const *)
+		    tableDataPtr->fromUnicode;
+
+	    /*
+	     * The state variable has the value of oldState when word is 0.
+	     * In this case, the escape sequense should not be copied to dst
+	     * because the current character set is not changed.
+	     */
+
+	    if (state != oldState) {
+		subTablePtr = &dataPtr->subTables[state];
+		if ((dst + subTablePtr->sequenceLen) > dstEnd) {
+		    /*
+		     * If there is no space to write the escape sequence, the
+		     * state variable must be changed to the value of oldState
+		     * variable because this escape sequence must be written
+		     * in the next conversion.
+		     */
+
+		    state = oldState;
+		    result = TCL_CONVERT_NOSPACE;
+		    break;
+		}
+		memcpy(dst, subTablePtr->sequence,
+			(size_t) subTablePtr->sequenceLen);
+		dst += subTablePtr->sequenceLen;
+	    }
+	}
+
+	if (tablePrefixBytes[(word >> 8)] != 0) {
+	    if (dst + 1 > dstEnd) {
+		result = TCL_CONVERT_NOSPACE;
+		break;
+	    }
+	    dst[0] = (char) (word >> 8);
+	    dst[1] = (char) word;
+	    dst += 2;
+	} else {
+	    if (dst > dstEnd) {
+		result = TCL_CONVERT_NOSPACE;
+		break;
+	    }
+	    dst[0] = (char) word;
+	    dst++;
+	}
+	src += len;
+    }
+
+    if ((result == TCL_OK) && (flags & TCL_ENCODING_END)) {
+	unsigned len = dataPtr->subTables[0].sequenceLen;
+
+	/*
+	 * Certain encodings like iso2022-jp need to write an escape sequence
+	 * after all characters have been converted. This logic checks that
+	 * enough room is available in the buffer for the escape bytes. The
+	 * TCL_ENCODING_END flag is cleared after a final escape sequence has
+	 * been added to the buffer so that another call to this method does
+	 * not attempt to append escape bytes a second time.
+	 */
+
+	if ((dst + dataPtr->finalLen + (state?len:0)) > dstEnd) {
+	    result = TCL_CONVERT_NOSPACE;
+	} else {
+	    if (state) {
+		memcpy(dst, dataPtr->subTables[0].sequence, len);
+		dst += len;
+	    }
+	    memcpy(dst, dataPtr->final, (size_t) dataPtr->finalLen);
+	    dst += dataPtr->finalLen;
+	    state &= ~TCL_ENCODING_END;
+	}
+    }
+
+    *statePtr = (Tcl_EncodingState) INT2PTR(state);
+    *srcReadPtr = src - srcStart;
+    *dstWrotePtr = dst - dstStart;
+    *dstCharsPtr = numChars;
+    return result;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * EscapeFreeProc --
+ *
+ *	This function is invoked when an EscapeEncodingData encoding is
+ *	deleted. It deletes the memory used by the encoding.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Memory freed.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+static void
+EscapeFreeProc(
+    ClientData clientData)	/* EscapeEncodingData that specifies
+				 * encoding. */
+{
+    EscapeEncodingData *dataPtr = clientData;
+    EscapeSubTable *subTablePtr;
+    int i;
+
+    if (dataPtr == NULL) {
+	return;
+    }
+
+    /*
+     * The subTables should be freed recursively in normal operation but not
+     * during TclFinalizeEncodingSubsystem because they are also present as a
+     * weak reference in the toplevel encodingTable (i.e., they don't have a
+     * +1 refcount for this), and unpredictable nuking order could remove them
+     * from under the following loop's feet. [Bug 2891556]
+     *
+     * The encodingsInitialized flag, being reset on entry to TFES, can serve
+     * as a "not in finalization" test.
+     */
+
+    if (encodingsInitialized) {
+	subTablePtr = dataPtr->subTables;
+	for (i = 0; i < dataPtr->numSubTables; i++) {
+	    FreeEncoding((Tcl_Encoding) subTablePtr->encodingPtr);
+	    subTablePtr->encodingPtr = NULL;
+	    subTablePtr++;
+	}
+    }
+    ckfree(dataPtr);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * GetTableEncoding --
+ *
+ *	Helper function for the EscapeEncodingData conversions. Gets the
+ *	encoding (of type TextEncodingData) that represents the specified
+ *	state.
+ *
+ * Results:
+ *	The return value is the encoding.
+ *
+ * Side effects:
+ *	If the encoding that represents the specified state has not already
+ *	been used by this EscapeEncoding, it will be loaded and cached in the
+ *	dataPtr.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+static Encoding *
+GetTableEncoding(
+    EscapeEncodingData *dataPtr,/* Contains names of encodings. */
+    int state)			/* Index in dataPtr of desired Encoding. */
+{
+    EscapeSubTable *subTablePtr = &dataPtr->subTables[state];
+    Encoding *encodingPtr = subTablePtr->encodingPtr;
+
+    if (encodingPtr == NULL) {
+	encodingPtr = (Encoding *) Tcl_GetEncoding(NULL, subTablePtr->name);
+	if ((encodingPtr == NULL)
+		|| (encodingPtr->toUtfProc != TableToUtfProc
+		&& encodingPtr->toUtfProc != Iso88591ToUtfProc)) {
+	    Tcl_Panic("EscapeToUtfProc: invalid sub table");
+	}
+	subTablePtr->encodingPtr = encodingPtr;
+    }
+
+    return encodingPtr;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * unilen --
+ *
+ *	A helper function for the Tcl_ExternalToUtf functions. This function
+ *	is similar to strlen for double-byte characters: it returns the number
+ *	of bytes in a 0x0000 terminated string.
+ *
+ * Results:
+ *	As above.
+ *
+ * Side effects:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+static size_t
+unilen(
+    const char *src)
+{
+    unsigned short *p;
+
+    p = (unsigned short *) src;
+    while (*p != 0x0000) {
+	p++;
+    }
+    return (char *) p - src;
+}
+
+/*
+ *-------------------------------------------------------------------------
+ *
+ * InitializeEncodingSearchPath	--
+ *
+ *	This is the fallback routine that sets the default value of the
+ *	encoding search path if the application has not set one via a call to
+ *	Tcl_SetEncodingSearchPath() by the first time the search path is needed
+ *	to load encoding data.
+ *
+ *	The default encoding search path is produced by taking each directory
+ *	in the library path, appending a subdirectory named "encoding", and if
+ *	the resulting directory exists, adding it to the encoding search path.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Sets the encoding search path to an initial value.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+static void
+InitializeEncodingSearchPath(
+    char **valuePtr,
+    int *lengthPtr,
+    Tcl_Encoding *encodingPtr)
+{
+    const char *bytes;
+    int i, numDirs, numBytes;
+    Tcl_Obj *libPathObj, *encodingObj, *searchPathObj;
+
+    TclNewLiteralStringObj(encodingObj, "encoding");
+    TclNewObj(searchPathObj);
+    Tcl_IncrRefCount(encodingObj);
+    Tcl_IncrRefCount(searchPathObj);
+    libPathObj = TclGetLibraryPath();
+    Tcl_IncrRefCount(libPathObj);
+    Tcl_ListObjLength(NULL, libPathObj, &numDirs);
+
+    for (i = 0; i < numDirs; i++) {
+	Tcl_Obj *directoryObj, *pathObj;
+	Tcl_StatBuf stat;
+
+	Tcl_ListObjIndex(NULL, libPathObj, i, &directoryObj);
+	pathObj = Tcl_FSJoinToPath(directoryObj, 1, &encodingObj);
+	Tcl_IncrRefCount(pathObj);
+	if ((0 == Tcl_FSStat(pathObj, &stat)) && S_ISDIR(stat.st_mode)) {
+	    Tcl_ListObjAppendElement(NULL, searchPathObj, pathObj);
+	}
+	Tcl_DecrRefCount(pathObj);
+    }
+
+    Tcl_DecrRefCount(libPathObj);
+    Tcl_DecrRefCount(encodingObj);
+    *encodingPtr = libraryPath.encoding;
+    if (*encodingPtr) {
+	((Encoding *)(*encodingPtr))->refCount++;
+    }
+    bytes = Tcl_GetStringFromObj(searchPathObj, &numBytes);
+
+    *lengthPtr = numBytes;
+    *valuePtr = ckalloc(numBytes + 1);
+    memcpy(*valuePtr, bytes, (size_t) numBytes + 1);
+    Tcl_DecrRefCount(searchPathObj);
+}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tclEnsemble.c b/generic/tclEnsemble.c
new file mode 100644
index 0000000..8e5e410
--- /dev/null
+++ b/generic/tclEnsemble.c
@@ -0,0 +1,3665 @@
+/*
+ * tclEnsemble.c --
+ *
+ *	Contains support for ensembles (see TIP#112), which provide simple
+ *	mechanism for creating composite commands on top of namespaces.
+ *
+ * Copyright (c) 2005-2013 Donal K. Fellows.
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#include "tclInt.h"
+#include "tclCompile.h"
+
+/*
+ * Declarations for functions local to this file:
+ */
+
+static inline Tcl_Obj *	NewNsObj(Tcl_Namespace *namespacePtr);
+static inline int	EnsembleUnknownCallback(Tcl_Interp *interp,
+			    EnsembleConfig *ensemblePtr, int objc,
+			    Tcl_Obj *const objv[], Tcl_Obj **prefixObjPtr);
+static int		NsEnsembleImplementationCmd(ClientData clientData,
+			    Tcl_Interp *interp,int objc,Tcl_Obj *const objv[]);
+static int		NsEnsembleImplementationCmdNR(ClientData clientData,
+			    Tcl_Interp *interp,int objc,Tcl_Obj *const objv[]);
+static void		BuildEnsembleConfig(EnsembleConfig *ensemblePtr);
+static int		NsEnsembleStringOrder(const void *strPtr1,
+			    const void *strPtr2);
+static void		DeleteEnsembleConfig(ClientData clientData);
+static void		MakeCachedEnsembleCommand(Tcl_Obj *objPtr,
+			    EnsembleConfig *ensemblePtr, Tcl_HashEntry *hPtr,
+			    Tcl_Obj *fix);
+static void		FreeEnsembleCmdRep(Tcl_Obj *objPtr);
+static void		DupEnsembleCmdRep(Tcl_Obj *objPtr, Tcl_Obj *copyPtr);
+static void		CompileToInvokedCommand(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Tcl_Obj *replacements,
+			    Command *cmdPtr, CompileEnv *envPtr);
+static int		CompileBasicNArgCommand(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    CompileEnv *envPtr);
+
+static Tcl_NRPostProc	FreeER;
+
+/*
+ * The lists of subcommands and options for the [namespace ensemble] command.
+ */
+
+static const char *const ensembleSubcommands[] = {
+    "configure", "create", "exists", NULL
+};
+enum EnsSubcmds {
+    ENS_CONFIG, ENS_CREATE, ENS_EXISTS
+};
+
+static const char *const ensembleCreateOptions[] = {
+    "-command", "-map", "-parameters", "-prefixes", "-subcommands",
+    "-unknown", NULL
+};
+enum EnsCreateOpts {
+    CRT_CMD, CRT_MAP, CRT_PARAM, CRT_PREFIX, CRT_SUBCMDS, CRT_UNKNOWN
+};
+
+static const char *const ensembleConfigOptions[] = {
+    "-map", "-namespace", "-parameters", "-prefixes", "-subcommands",
+    "-unknown", NULL
+};
+enum EnsConfigOpts {
+    CONF_MAP, CONF_NAMESPACE, CONF_PARAM, CONF_PREFIX, CONF_SUBCMDS,
+    CONF_UNKNOWN
+};
+
+/*
+ * This structure defines a Tcl object type that contains a reference to an
+ * ensemble subcommand (e.g. the "length" in [string length ab]). It is used
+ * to cache the mapping between the subcommand itself and the real command
+ * that implements it.
+ */
+
+static const Tcl_ObjType ensembleCmdType = {
+    "ensembleCommand",		/* the type's name */
+    FreeEnsembleCmdRep,		/* freeIntRepProc */
+    DupEnsembleCmdRep,		/* dupIntRepProc */
+    NULL,			/* updateStringProc */
+    NULL			/* setFromAnyProc */
+};
+
+/*
+ * The internal rep for caching ensemble subcommand lookups and
+ * spell corrections.
+ */
+
+typedef struct {
+    int epoch;                  /* Used to confirm when the data in this
+                                 * really structure matches up with the
+                                 * ensemble. */
+    Command *token;             /* Reference to the command for which this
+                                 * structure is a cache of the resolution. */
+    Tcl_Obj *fix;               /* Corrected spelling, if needed. */
+    Tcl_HashEntry *hPtr;        /* Direct link to entry in the subcommand
+                                 * hash table. */
+} EnsembleCmdRep;
+
+
+static inline Tcl_Obj *
+NewNsObj(
+    Tcl_Namespace *namespacePtr)
+{
+    register Namespace *nsPtr = (Namespace *) namespacePtr;
+
+    if (namespacePtr == TclGetGlobalNamespace(nsPtr->interp)) {
+	return Tcl_NewStringObj("::", 2);
+    } else {
+	return Tcl_NewStringObj(nsPtr->fullName, -1);
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclNamespaceEnsembleCmd --
+ *
+ *	Invoked to implement the "namespace ensemble" command that creates and
+ *	manipulates ensembles built on top of namespaces. Handles the
+ *	following syntax:
+ *
+ *	    namespace ensemble name ?dictionary?
+ *
+ * Results:
+ *	Returns TCL_OK if successful, and TCL_ERROR if anything goes wrong.
+ *
+ * Side effects:
+ *	Creates the ensemble for the namespace if one did not previously
+ *	exist. Alternatively, alters the way that the ensemble's subcommand =>
+ *	implementation prefix is configured.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclNamespaceEnsembleCmd(
+    ClientData dummy,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const objv[])
+{
+    Tcl_Namespace *namespacePtr;
+    Namespace *nsPtr = (Namespace *) TclGetCurrentNamespace(interp);
+    Tcl_Command token;
+    Tcl_DictSearch search;
+    Tcl_Obj *listObj;
+    int index, done;
+
+    if (nsPtr == NULL || nsPtr->flags & NS_DYING) {
+	if (!Tcl_InterpDeleted(interp)) {
+	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		    "tried to manipulate ensemble of deleted namespace",
+		    -1));
+	    Tcl_SetErrorCode(interp, "TCL", "ENSEMBLE", "DEAD", NULL);
+	}
+	return TCL_ERROR;
+    }
+
+    if (objc < 2) {
+	Tcl_WrongNumArgs(interp, 1, objv, "subcommand ?arg ...?");
+	return TCL_ERROR;
+    }
+    if (Tcl_GetIndexFromObj(interp, objv[1], ensembleSubcommands,
+	    "subcommand", 0, &index) != TCL_OK) {
+	return TCL_ERROR;
+    }
+
+    switch ((enum EnsSubcmds) index) {
+    case ENS_CREATE: {
+	const char *name;
+	int len, allocatedMapFlag = 0;
+	/*
+	 * Defaults
+	 */
+	Tcl_Obj *subcmdObj = NULL;
+	Tcl_Obj *mapObj = NULL;
+	int permitPrefix = 1;
+	Tcl_Obj *unknownObj = NULL;
+	Tcl_Obj *paramObj = NULL;
+
+	/*
+	 * Check that we've got option-value pairs... [Bug 1558654]
+	 */
+
+	if (objc & 1) {
+	    Tcl_WrongNumArgs(interp, 2, objv, "?option value ...?");
+	    return TCL_ERROR;
+	}
+	objv += 2;
+	objc -= 2;
+
+	/*
+	 * Work out what name to use for the command to create. If supplied,
+	 * it is either fully specified or relative to the current namespace.
+	 * If not supplied, it is exactly the name of the current namespace.
+	 */
+
+	name = nsPtr->fullName;
+
+	/*
+	 * Parse the option list, applying type checks as we go. Note that we
+	 * are not incrementing any reference counts in the objects at this
+	 * stage, so the presence of an option multiple times won't cause any
+	 * memory leaks.
+	 */
+
+	for (; objc>1 ; objc-=2,objv+=2) {
+	    if (Tcl_GetIndexFromObj(interp, objv[0], ensembleCreateOptions,
+		    "option", 0, &index) != TCL_OK) {
+		if (allocatedMapFlag) {
+		    Tcl_DecrRefCount(mapObj);
+		}
+		return TCL_ERROR;
+	    }
+	    switch ((enum EnsCreateOpts) index) {
+	    case CRT_CMD:
+		name = TclGetString(objv[1]);
+		continue;
+	    case CRT_SUBCMDS:
+		if (TclListObjLength(interp, objv[1], &len) != TCL_OK) {
+		    if (allocatedMapFlag) {
+			Tcl_DecrRefCount(mapObj);
+		    }
+		    return TCL_ERROR;
+		}
+		subcmdObj = (len > 0 ? objv[1] : NULL);
+		continue;
+	    case CRT_PARAM:
+		if (TclListObjLength(interp, objv[1], &len) != TCL_OK) {
+		    if (allocatedMapFlag) {
+			Tcl_DecrRefCount(mapObj);
+		    }
+		    return TCL_ERROR;
+		}
+		paramObj = (len > 0 ? objv[1] : NULL);
+		continue;
+	    case CRT_MAP: {
+		Tcl_Obj *patchedDict = NULL, *subcmdWordsObj;
+
+		/*
+		 * Verify that the map is sensible.
+		 */
+
+		if (Tcl_DictObjFirst(interp, objv[1], &search,
+			&subcmdWordsObj, &listObj, &done) != TCL_OK) {
+		    if (allocatedMapFlag) {
+			Tcl_DecrRefCount(mapObj);
+		    }
+		    return TCL_ERROR;
+		}
+		if (done) {
+		    mapObj = NULL;
+		    continue;
+		}
+		do {
+		    Tcl_Obj **listv;
+		    const char *cmd;
+
+		    if (TclListObjGetElements(interp, listObj, &len,
+			    &listv) != TCL_OK) {
+			Tcl_DictObjDone(&search);
+			if (patchedDict) {
+			    Tcl_DecrRefCount(patchedDict);
+			}
+			if (allocatedMapFlag) {
+			    Tcl_DecrRefCount(mapObj);
+			}
+			return TCL_ERROR;
+		    }
+		    if (len < 1) {
+			Tcl_SetObjResult(interp, Tcl_NewStringObj(
+				"ensemble subcommand implementations "
+				"must be non-empty lists", -1));
+			Tcl_SetErrorCode(interp, "TCL", "ENSEMBLE",
+				"EMPTY_TARGET", NULL);
+			Tcl_DictObjDone(&search);
+			if (patchedDict) {
+			    Tcl_DecrRefCount(patchedDict);
+			}
+			if (allocatedMapFlag) {
+			    Tcl_DecrRefCount(mapObj);
+			}
+			return TCL_ERROR;
+		    }
+		    cmd = TclGetString(listv[0]);
+		    if (!(cmd[0] == ':' && cmd[1] == ':')) {
+			Tcl_Obj *newList = Tcl_NewListObj(len, listv);
+			Tcl_Obj *newCmd = NewNsObj((Tcl_Namespace *) nsPtr);
+
+			if (nsPtr->parentPtr) {
+			    Tcl_AppendStringsToObj(newCmd, "::", NULL);
+			}
+			Tcl_AppendObjToObj(newCmd, listv[0]);
+			Tcl_ListObjReplace(NULL, newList, 0, 1, 1, &newCmd);
+			if (patchedDict == NULL) {
+			    patchedDict = Tcl_DuplicateObj(objv[1]);
+			}
+			Tcl_DictObjPut(NULL, patchedDict, subcmdWordsObj,
+				newList);
+		    }
+		    Tcl_DictObjNext(&search, &subcmdWordsObj,&listObj, &done);
+		} while (!done);
+
+		if (allocatedMapFlag) {
+		    Tcl_DecrRefCount(mapObj);
+		}
+		mapObj = (patchedDict ? patchedDict : objv[1]);
+		if (patchedDict) {
+		    allocatedMapFlag = 1;
+		}
+		continue;
+	    }
+	    case CRT_PREFIX:
+		if (Tcl_GetBooleanFromObj(interp, objv[1],
+			&permitPrefix) != TCL_OK) {
+		    if (allocatedMapFlag) {
+			Tcl_DecrRefCount(mapObj);
+		    }
+		    return TCL_ERROR;
+		}
+		continue;
+	    case CRT_UNKNOWN:
+		if (TclListObjLength(interp, objv[1], &len) != TCL_OK) {
+		    if (allocatedMapFlag) {
+			Tcl_DecrRefCount(mapObj);
+		    }
+		    return TCL_ERROR;
+		}
+		unknownObj = (len > 0 ? objv[1] : NULL);
+		continue;
+	    }
+	}
+
+	/*
+	 * Create the ensemble. Note that this might delete another ensemble
+	 * linked to the same namespace, so we must be careful. However, we
+	 * should be OK because we only link the namespace into the list once
+	 * we've created it (and after any deletions have occurred.)
+	 */
+
+	token = Tcl_CreateEnsemble(interp, name, NULL,
+		(permitPrefix ? TCL_ENSEMBLE_PREFIX : 0));
+	Tcl_SetEnsembleSubcommandList(interp, token, subcmdObj);
+	Tcl_SetEnsembleMappingDict(interp, token, mapObj);
+	Tcl_SetEnsembleUnknownHandler(interp, token, unknownObj);
+	Tcl_SetEnsembleParameterList(interp, token, paramObj);
+
+	/*
+	 * Tricky! Must ensure that the result is not shared (command delete
+	 * traces could have corrupted the pristine object that we started
+	 * with). [Snit test rename-1.5]
+	 */
+
+	Tcl_ResetResult(interp);
+	Tcl_GetCommandFullName(interp, token, Tcl_GetObjResult(interp));
+	return TCL_OK;
+    }
+
+    case ENS_EXISTS:
+	if (objc != 3) {
+	    Tcl_WrongNumArgs(interp, 2, objv, "cmdname");
+	    return TCL_ERROR;
+	}
+	Tcl_SetObjResult(interp, Tcl_NewBooleanObj(
+		Tcl_FindEnsemble(interp, objv[2], 0) != NULL));
+	return TCL_OK;
+
+    case ENS_CONFIG:
+	if (objc < 3 || (objc != 4 && !(objc & 1))) {
+	    Tcl_WrongNumArgs(interp, 2, objv,
+		    "cmdname ?-option value ...? ?arg ...?");
+	    return TCL_ERROR;
+	}
+	token = Tcl_FindEnsemble(interp, objv[2], TCL_LEAVE_ERR_MSG);
+	if (token == NULL) {
+	    return TCL_ERROR;
+	}
+
+	if (objc == 4) {
+	    Tcl_Obj *resultObj = NULL;		/* silence gcc 4 warning */
+
+	    if (Tcl_GetIndexFromObj(interp, objv[3], ensembleConfigOptions,
+		    "option", 0, &index) != TCL_OK) {
+		return TCL_ERROR;
+	    }
+	    switch ((enum EnsConfigOpts) index) {
+	    case CONF_SUBCMDS:
+		Tcl_GetEnsembleSubcommandList(NULL, token, &resultObj);
+		if (resultObj != NULL) {
+		    Tcl_SetObjResult(interp, resultObj);
+		}
+		break;
+	    case CONF_PARAM:
+		Tcl_GetEnsembleParameterList(NULL, token, &resultObj);
+		if (resultObj != NULL) {
+		    Tcl_SetObjResult(interp, resultObj);
+		}
+		break;
+	    case CONF_MAP:
+		Tcl_GetEnsembleMappingDict(NULL, token, &resultObj);
+		if (resultObj != NULL) {
+		    Tcl_SetObjResult(interp, resultObj);
+		}
+		break;
+	    case CONF_NAMESPACE:
+		namespacePtr = NULL;		/* silence gcc 4 warning */
+		Tcl_GetEnsembleNamespace(NULL, token, &namespacePtr);
+		Tcl_SetObjResult(interp, NewNsObj(namespacePtr));
+		break;
+	    case CONF_PREFIX: {
+		int flags = 0;			/* silence gcc 4 warning */
+
+		Tcl_GetEnsembleFlags(NULL, token, &flags);
+		Tcl_SetObjResult(interp,
+			Tcl_NewBooleanObj(flags & TCL_ENSEMBLE_PREFIX));
+		break;
+	    }
+	    case CONF_UNKNOWN:
+		Tcl_GetEnsembleUnknownHandler(NULL, token, &resultObj);
+		if (resultObj != NULL) {
+		    Tcl_SetObjResult(interp, resultObj);
+		}
+		break;
+	    }
+	} else if (objc == 3) {
+	    /*
+	     * Produce list of all information.
+	     */
+
+	    Tcl_Obj *resultObj, *tmpObj = NULL;	/* silence gcc 4 warning */
+	    int flags = 0;			/* silence gcc 4 warning */
+
+	    TclNewObj(resultObj);
+
+	    /* -map option */
+	    Tcl_ListObjAppendElement(NULL, resultObj,
+		    Tcl_NewStringObj(ensembleConfigOptions[CONF_MAP], -1));
+	    Tcl_GetEnsembleMappingDict(NULL, token, &tmpObj);
+	    Tcl_ListObjAppendElement(NULL, resultObj,
+		    (tmpObj != NULL) ? tmpObj : Tcl_NewObj());
+
+	    /* -namespace option */
+	    Tcl_ListObjAppendElement(NULL, resultObj,
+		    Tcl_NewStringObj(ensembleConfigOptions[CONF_NAMESPACE],
+			    -1));
+	    namespacePtr = NULL;		/* silence gcc 4 warning */
+	    Tcl_GetEnsembleNamespace(NULL, token, &namespacePtr);
+	    Tcl_ListObjAppendElement(NULL, resultObj, NewNsObj(namespacePtr));
+
+	    /* -parameters option */
+	    Tcl_ListObjAppendElement(NULL, resultObj,
+		    Tcl_NewStringObj(ensembleConfigOptions[CONF_PARAM], -1));
+	    Tcl_GetEnsembleParameterList(NULL, token, &tmpObj);
+	    Tcl_ListObjAppendElement(NULL, resultObj,
+		    (tmpObj != NULL) ? tmpObj : Tcl_NewObj());
+
+	    /* -prefix option */
+	    Tcl_ListObjAppendElement(NULL, resultObj,
+		    Tcl_NewStringObj(ensembleConfigOptions[CONF_PREFIX], -1));
+	    Tcl_GetEnsembleFlags(NULL, token, &flags);
+	    Tcl_ListObjAppendElement(NULL, resultObj,
+		    Tcl_NewBooleanObj(flags & TCL_ENSEMBLE_PREFIX));
+
+	    /* -subcommands option */
+	    Tcl_ListObjAppendElement(NULL, resultObj,
+		    Tcl_NewStringObj(ensembleConfigOptions[CONF_SUBCMDS],-1));
+	    Tcl_GetEnsembleSubcommandList(NULL, token, &tmpObj);
+	    Tcl_ListObjAppendElement(NULL, resultObj,
+		    (tmpObj != NULL) ? tmpObj : Tcl_NewObj());
+
+	    /* -unknown option */
+	    Tcl_ListObjAppendElement(NULL, resultObj,
+		    Tcl_NewStringObj(ensembleConfigOptions[CONF_UNKNOWN],-1));
+	    Tcl_GetEnsembleUnknownHandler(NULL, token, &tmpObj);
+	    Tcl_ListObjAppendElement(NULL, resultObj,
+		    (tmpObj != NULL) ? tmpObj : Tcl_NewObj());
+
+	    Tcl_SetObjResult(interp, resultObj);
+	} else {
+	    int len, allocatedMapFlag = 0;
+	    Tcl_Obj *subcmdObj = NULL, *mapObj = NULL, *paramObj = NULL,
+		    *unknownObj = NULL; /* Defaults, silence gcc 4 warnings */
+	    int permitPrefix, flags = 0;	/* silence gcc 4 warning */
+
+	    Tcl_GetEnsembleSubcommandList(NULL, token, &subcmdObj);
+	    Tcl_GetEnsembleMappingDict(NULL, token, &mapObj);
+	    Tcl_GetEnsembleParameterList(NULL, token, &paramObj);
+	    Tcl_GetEnsembleUnknownHandler(NULL, token, &unknownObj);
+	    Tcl_GetEnsembleFlags(NULL, token, &flags);
+	    permitPrefix = (flags & TCL_ENSEMBLE_PREFIX) != 0;
+
+	    objv += 3;
+	    objc -= 3;
+
+	    /*
+	     * Parse the option list, applying type checks as we go. Note that
+	     * we are not incrementing any reference counts in the objects at
+	     * this stage, so the presence of an option multiple times won't
+	     * cause any memory leaks.
+	     */
+
+	    for (; objc>0 ; objc-=2,objv+=2) {
+		if (Tcl_GetIndexFromObj(interp, objv[0],ensembleConfigOptions,
+			"option", 0, &index) != TCL_OK) {
+		freeMapAndError:
+		    if (allocatedMapFlag) {
+			Tcl_DecrRefCount(mapObj);
+		    }
+		    return TCL_ERROR;
+		}
+		switch ((enum EnsConfigOpts) index) {
+		case CONF_SUBCMDS:
+		    if (TclListObjLength(interp, objv[1], &len) != TCL_OK) {
+			goto freeMapAndError;
+		    }
+		    subcmdObj = (len > 0 ? objv[1] : NULL);
+		    continue;
+		case CONF_PARAM:
+		    if (TclListObjLength(interp, objv[1], &len) != TCL_OK) {
+			goto freeMapAndError;
+		    }
+		    paramObj = (len > 0 ? objv[1] : NULL);
+		    continue;
+		case CONF_MAP: {
+		    Tcl_Obj *patchedDict = NULL, *subcmdWordsObj, **listv;
+		    const char *cmd;
+
+		    /*
+		     * Verify that the map is sensible.
+		     */
+
+		    if (Tcl_DictObjFirst(interp, objv[1], &search,
+			    &subcmdWordsObj, &listObj, &done) != TCL_OK) {
+			goto freeMapAndError;
+		    }
+		    if (done) {
+			mapObj = NULL;
+			continue;
+		    }
+		    do {
+			if (TclListObjGetElements(interp, listObj, &len,
+				&listv) != TCL_OK) {
+			    Tcl_DictObjDone(&search);
+			    if (patchedDict) {
+				Tcl_DecrRefCount(patchedDict);
+			    }
+			    goto freeMapAndError;
+			}
+			if (len < 1) {
+			    Tcl_SetObjResult(interp, Tcl_NewStringObj(
+				    "ensemble subcommand implementations "
+				    "must be non-empty lists", -1));
+			    Tcl_SetErrorCode(interp, "TCL", "ENSEMBLE",
+				    "EMPTY_TARGET", NULL);
+			    Tcl_DictObjDone(&search);
+			    if (patchedDict) {
+				Tcl_DecrRefCount(patchedDict);
+			    }
+			    goto freeMapAndError;
+			}
+			cmd = TclGetString(listv[0]);
+			if (!(cmd[0] == ':' && cmd[1] == ':')) {
+			    Tcl_Obj *newList = Tcl_DuplicateObj(listObj);
+			    Tcl_Obj *newCmd = NewNsObj((Tcl_Namespace*)nsPtr);
+
+			    if (nsPtr->parentPtr) {
+				Tcl_AppendStringsToObj(newCmd, "::", NULL);
+			    }
+			    Tcl_AppendObjToObj(newCmd, listv[0]);
+			    Tcl_ListObjReplace(NULL, newList, 0,1, 1,&newCmd);
+			    if (patchedDict == NULL) {
+				patchedDict = Tcl_DuplicateObj(objv[1]);
+			    }
+			    Tcl_DictObjPut(NULL, patchedDict, subcmdWordsObj,
+				    newList);
+			}
+			Tcl_DictObjNext(&search, &subcmdWordsObj, &listObj,
+				&done);
+		    } while (!done);
+		    if (allocatedMapFlag) {
+			Tcl_DecrRefCount(mapObj);
+		    }
+		    mapObj = (patchedDict ? patchedDict : objv[1]);
+		    if (patchedDict) {
+			allocatedMapFlag = 1;
+		    }
+		    continue;
+		}
+		case CONF_NAMESPACE:
+		    Tcl_SetObjResult(interp, Tcl_NewStringObj(
+			    "option -namespace is read-only", -1));
+		    Tcl_SetErrorCode(interp, "TCL", "ENSEMBLE", "READ_ONLY",
+			    NULL);
+		    goto freeMapAndError;
+		case CONF_PREFIX:
+		    if (Tcl_GetBooleanFromObj(interp, objv[1],
+			    &permitPrefix) != TCL_OK) {
+			goto freeMapAndError;
+		    }
+		    continue;
+		case CONF_UNKNOWN:
+		    if (TclListObjLength(interp, objv[1], &len) != TCL_OK) {
+			goto freeMapAndError;
+		    }
+		    unknownObj = (len > 0 ? objv[1] : NULL);
+		    continue;
+		}
+	    }
+
+	    /*
+	     * Update the namespace now that we've finished the parsing stage.
+	     */
+
+	    flags = (permitPrefix ? flags|TCL_ENSEMBLE_PREFIX
+		    : flags&~TCL_ENSEMBLE_PREFIX);
+	    Tcl_SetEnsembleSubcommandList(interp, token, subcmdObj);
+	    Tcl_SetEnsembleMappingDict(interp, token, mapObj);
+	    Tcl_SetEnsembleParameterList(interp, token, paramObj);
+	    Tcl_SetEnsembleUnknownHandler(interp, token, unknownObj);
+	    Tcl_SetEnsembleFlags(interp, token, flags);
+	}
+	return TCL_OK;
+
+    default:
+	Tcl_Panic("unexpected ensemble command");
+    }
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_CreateEnsemble --
+ *
+ *	Create a simple ensemble attached to the given namespace.
+ *
+ * Results:
+ *	The token for the command created.
+ *
+ * Side effects:
+ *	The ensemble is created and marked for compilation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_Command
+Tcl_CreateEnsemble(
+    Tcl_Interp *interp,
+    const char *name,
+    Tcl_Namespace *namespacePtr,
+    int flags)
+{
+    Namespace *nsPtr = (Namespace *) namespacePtr;
+    EnsembleConfig *ensemblePtr = ckalloc(sizeof(EnsembleConfig));
+    Tcl_Obj *nameObj = NULL;
+
+    if (nsPtr == NULL) {
+	nsPtr = (Namespace *) TclGetCurrentNamespace(interp);
+    }
+
+    /*
+     * Make the name of the ensemble into a fully qualified name. This might
+     * allocate a temporary object.
+     */
+
+    if (!(name[0] == ':' && name[1] == ':')) {
+	nameObj = NewNsObj((Tcl_Namespace *) nsPtr);
+	if (nsPtr->parentPtr == NULL) {
+	    Tcl_AppendStringsToObj(nameObj, name, NULL);
+	} else {
+	    Tcl_AppendStringsToObj(nameObj, "::", name, NULL);
+	}
+	Tcl_IncrRefCount(nameObj);
+	name = TclGetString(nameObj);
+    }
+
+    ensemblePtr->nsPtr = nsPtr;
+    ensemblePtr->epoch = 0;
+    Tcl_InitHashTable(&ensemblePtr->subcommandTable, TCL_STRING_KEYS);
+    ensemblePtr->subcommandArrayPtr = NULL;
+    ensemblePtr->subcmdList = NULL;
+    ensemblePtr->subcommandDict = NULL;
+    ensemblePtr->flags = flags;
+    ensemblePtr->numParameters = 0;
+    ensemblePtr->parameterList = NULL;
+    ensemblePtr->unknownHandler = NULL;
+    ensemblePtr->token = Tcl_NRCreateCommand(interp, name,
+	    NsEnsembleImplementationCmd, NsEnsembleImplementationCmdNR,
+	    ensemblePtr, DeleteEnsembleConfig);
+    ensemblePtr->next = (EnsembleConfig *) nsPtr->ensembles;
+    nsPtr->ensembles = (Tcl_Ensemble *) ensemblePtr;
+
+    /*
+     * Trigger an eventual recomputation of the ensemble command set. Note
+     * that this is slightly tricky, as it means that we are not actually
+     * counting the number of namespace export actions, but it is the simplest
+     * way to go!
+     */
+
+    nsPtr->exportLookupEpoch++;
+
+    if (flags & ENSEMBLE_COMPILE) {
+	((Command *) ensemblePtr->token)->compileProc = TclCompileEnsemble;
+    }
+
+    if (nameObj != NULL) {
+	TclDecrRefCount(nameObj);
+    }
+    return ensemblePtr->token;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_SetEnsembleSubcommandList --
+ *
+ *	Set the subcommand list for a particular ensemble.
+ *
+ * Results:
+ *	Tcl result code (error if command token does not indicate an ensemble
+ *	or the subcommand list - if non-NULL - is not a list).
+ *
+ * Side effects:
+ *	The ensemble is updated and marked for recompilation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_SetEnsembleSubcommandList(
+    Tcl_Interp *interp,
+    Tcl_Command token,
+    Tcl_Obj *subcmdList)
+{
+    Command *cmdPtr = (Command *) token;
+    EnsembleConfig *ensemblePtr;
+    Tcl_Obj *oldList;
+
+    if (cmdPtr->objProc != NsEnsembleImplementationCmd) {
+	Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		"command is not an ensemble", -1));
+	Tcl_SetErrorCode(interp, "TCL", "ENSEMBLE", "NOT_ENSEMBLE", NULL);
+	return TCL_ERROR;
+    }
+    if (subcmdList != NULL) {
+	int length;
+
+	if (TclListObjLength(interp, subcmdList, &length) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	if (length < 1) {
+	    subcmdList = NULL;
+	}
+    }
+
+    ensemblePtr = cmdPtr->objClientData;
+    oldList = ensemblePtr->subcmdList;
+    ensemblePtr->subcmdList = subcmdList;
+    if (subcmdList != NULL) {
+	Tcl_IncrRefCount(subcmdList);
+    }
+    if (oldList != NULL) {
+	TclDecrRefCount(oldList);
+    }
+
+    /*
+     * Trigger an eventual recomputation of the ensemble command set. Note
+     * that this is slightly tricky, as it means that we are not actually
+     * counting the number of namespace export actions, but it is the simplest
+     * way to go!
+     */
+
+    ensemblePtr->nsPtr->exportLookupEpoch++;
+
+    /*
+     * Special hack to make compiling of [info exists] work when the
+     * dictionary is modified.
+     */
+
+    if (cmdPtr->compileProc != NULL) {
+	((Interp *) interp)->compileEpoch++;
+    }
+
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_SetEnsembleParameterList --
+ *
+ *	Set the parameter list for a particular ensemble.
+ *
+ * Results:
+ *	Tcl result code (error if command token does not indicate an ensemble
+ *	or the parameter list - if non-NULL - is not a list).
+ *
+ * Side effects:
+ *	The ensemble is updated and marked for recompilation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_SetEnsembleParameterList(
+    Tcl_Interp *interp,
+    Tcl_Command token,
+    Tcl_Obj *paramList)
+{
+    Command *cmdPtr = (Command *) token;
+    EnsembleConfig *ensemblePtr;
+    Tcl_Obj *oldList;
+    int length;
+
+    if (cmdPtr->objProc != NsEnsembleImplementationCmd) {
+	Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		"command is not an ensemble", -1));
+	Tcl_SetErrorCode(interp, "TCL", "ENSEMBLE", "NOT_ENSEMBLE", NULL);
+	return TCL_ERROR;
+    }
+    if (paramList == NULL) {
+	length = 0;
+    } else {
+	if (TclListObjLength(interp, paramList, &length) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	if (length < 1) {
+	    paramList = NULL;
+	}
+    }
+
+    ensemblePtr = cmdPtr->objClientData;
+    oldList = ensemblePtr->parameterList;
+    ensemblePtr->parameterList = paramList;
+    if (paramList != NULL) {
+	Tcl_IncrRefCount(paramList);
+    }
+    if (oldList != NULL) {
+	TclDecrRefCount(oldList);
+    }
+    ensemblePtr->numParameters = length;
+
+    /*
+     * Trigger an eventual recomputation of the ensemble command set. Note
+     * that this is slightly tricky, as it means that we are not actually
+     * counting the number of namespace export actions, but it is the simplest
+     * way to go!
+     */
+
+    ensemblePtr->nsPtr->exportLookupEpoch++;
+
+    /*
+     * Special hack to make compiling of [info exists] work when the
+     * dictionary is modified.
+     */
+
+    if (cmdPtr->compileProc != NULL) {
+	((Interp *) interp)->compileEpoch++;
+    }
+
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_SetEnsembleMappingDict --
+ *
+ *	Set the mapping dictionary for a particular ensemble.
+ *
+ * Results:
+ *	Tcl result code (error if command token does not indicate an ensemble
+ *	or the mapping - if non-NULL - is not a dict).
+ *
+ * Side effects:
+ *	The ensemble is updated and marked for recompilation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_SetEnsembleMappingDict(
+    Tcl_Interp *interp,
+    Tcl_Command token,
+    Tcl_Obj *mapDict)
+{
+    Command *cmdPtr = (Command *) token;
+    EnsembleConfig *ensemblePtr;
+    Tcl_Obj *oldDict;
+
+    if (cmdPtr->objProc != NsEnsembleImplementationCmd) {
+	Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		"command is not an ensemble", -1));
+	Tcl_SetErrorCode(interp, "TCL", "ENSEMBLE", "NOT_ENSEMBLE", NULL);
+	return TCL_ERROR;
+    }
+    if (mapDict != NULL) {
+	int size, done;
+	Tcl_DictSearch search;
+	Tcl_Obj *valuePtr;
+
+	if (Tcl_DictObjSize(interp, mapDict, &size) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+
+	for (Tcl_DictObjFirst(NULL, mapDict, &search, NULL, &valuePtr, &done);
+		!done; Tcl_DictObjNext(&search, NULL, &valuePtr, &done)) {
+	    Tcl_Obj *cmdObjPtr;
+	    const char *bytes;
+
+	    if (Tcl_ListObjIndex(interp, valuePtr, 0, &cmdObjPtr) != TCL_OK) {
+		Tcl_DictObjDone(&search);
+		return TCL_ERROR;
+	    }
+	    bytes = TclGetString(cmdObjPtr);
+	    if (bytes[0] != ':' || bytes[1] != ':') {
+		Tcl_SetObjResult(interp, Tcl_NewStringObj(
+			"ensemble target is not a fully-qualified command",
+			-1));
+		Tcl_SetErrorCode(interp, "TCL", "ENSEMBLE",
+			"UNQUALIFIED_TARGET", NULL);
+		Tcl_DictObjDone(&search);
+		return TCL_ERROR;
+	    }
+	}
+
+	if (size < 1) {
+	    mapDict = NULL;
+	}
+    }
+
+    ensemblePtr = cmdPtr->objClientData;
+    oldDict = ensemblePtr->subcommandDict;
+    ensemblePtr->subcommandDict = mapDict;
+    if (mapDict != NULL) {
+	Tcl_IncrRefCount(mapDict);
+    }
+    if (oldDict != NULL) {
+	TclDecrRefCount(oldDict);
+    }
+
+    /*
+     * Trigger an eventual recomputation of the ensemble command set. Note
+     * that this is slightly tricky, as it means that we are not actually
+     * counting the number of namespace export actions, but it is the simplest
+     * way to go!
+     */
+
+    ensemblePtr->nsPtr->exportLookupEpoch++;
+
+    /*
+     * Special hack to make compiling of [info exists] work when the
+     * dictionary is modified.
+     */
+
+    if (cmdPtr->compileProc != NULL) {
+	((Interp *) interp)->compileEpoch++;
+    }
+
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_SetEnsembleUnknownHandler --
+ *
+ *	Set the unknown handler for a particular ensemble.
+ *
+ * Results:
+ *	Tcl result code (error if command token does not indicate an ensemble
+ *	or the unknown handler - if non-NULL - is not a list).
+ *
+ * Side effects:
+ *	The ensemble is updated and marked for recompilation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_SetEnsembleUnknownHandler(
+    Tcl_Interp *interp,
+    Tcl_Command token,
+    Tcl_Obj *unknownList)
+{
+    Command *cmdPtr = (Command *) token;
+    EnsembleConfig *ensemblePtr;
+    Tcl_Obj *oldList;
+
+    if (cmdPtr->objProc != NsEnsembleImplementationCmd) {
+	Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		"command is not an ensemble", -1));
+	Tcl_SetErrorCode(interp, "TCL", "ENSEMBLE", "NOT_ENSEMBLE", NULL);
+	return TCL_ERROR;
+    }
+    if (unknownList != NULL) {
+	int length;
+
+	if (TclListObjLength(interp, unknownList, &length) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	if (length < 1) {
+	    unknownList = NULL;
+	}
+    }
+
+    ensemblePtr = cmdPtr->objClientData;
+    oldList = ensemblePtr->unknownHandler;
+    ensemblePtr->unknownHandler = unknownList;
+    if (unknownList != NULL) {
+	Tcl_IncrRefCount(unknownList);
+    }
+    if (oldList != NULL) {
+	TclDecrRefCount(oldList);
+    }
+
+    /*
+     * Trigger an eventual recomputation of the ensemble command set. Note
+     * that this is slightly tricky, as it means that we are not actually
+     * counting the number of namespace export actions, but it is the simplest
+     * way to go!
+     */
+
+    ensemblePtr->nsPtr->exportLookupEpoch++;
+
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_SetEnsembleFlags --
+ *
+ *	Set the flags for a particular ensemble.
+ *
+ * Results:
+ *	Tcl result code (error if command token does not indicate an
+ *	ensemble).
+ *
+ * Side effects:
+ *	The ensemble is updated and marked for recompilation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_SetEnsembleFlags(
+    Tcl_Interp *interp,
+    Tcl_Command token,
+    int flags)
+{
+    Command *cmdPtr = (Command *) token;
+    EnsembleConfig *ensemblePtr;
+    int wasCompiled;
+
+    if (cmdPtr->objProc != NsEnsembleImplementationCmd) {
+	Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		"command is not an ensemble", -1));
+	Tcl_SetErrorCode(interp, "TCL", "ENSEMBLE", "NOT_ENSEMBLE", NULL);
+	return TCL_ERROR;
+    }
+
+    ensemblePtr = cmdPtr->objClientData;
+    wasCompiled = ensemblePtr->flags & ENSEMBLE_COMPILE;
+
+    /*
+     * This API refuses to set the ENSEMBLE_DEAD flag...
+     */
+
+    ensemblePtr->flags &= ENSEMBLE_DEAD;
+    ensemblePtr->flags |= flags & ~ENSEMBLE_DEAD;
+
+    /*
+     * Trigger an eventual recomputation of the ensemble command set. Note
+     * that this is slightly tricky, as it means that we are not actually
+     * counting the number of namespace export actions, but it is the simplest
+     * way to go!
+     */
+
+    ensemblePtr->nsPtr->exportLookupEpoch++;
+
+    /*
+     * If the ENSEMBLE_COMPILE flag status was changed, install or remove the
+     * compiler function and bump the interpreter's compilation epoch so that
+     * bytecode gets regenerated.
+     */
+
+    if (flags & ENSEMBLE_COMPILE) {
+	if (!wasCompiled) {
+	    ((Command*) ensemblePtr->token)->compileProc = TclCompileEnsemble;
+	    ((Interp *) interp)->compileEpoch++;
+	}
+    } else {
+	if (wasCompiled) {
+	    ((Command *) ensemblePtr->token)->compileProc = NULL;
+	    ((Interp *) interp)->compileEpoch++;
+	}
+    }
+
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_GetEnsembleSubcommandList --
+ *
+ *	Get the list of subcommands associated with a particular ensemble.
+ *
+ * Results:
+ *	Tcl result code (error if command token does not indicate an
+ *	ensemble). The list of subcommands is returned by updating the
+ *	variable pointed to by the last parameter (NULL if this is to be
+ *	derived from the mapping dictionary or the associated namespace's
+ *	exported commands).
+ *
+ * Side effects:
+ *	None
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_GetEnsembleSubcommandList(
+    Tcl_Interp *interp,
+    Tcl_Command token,
+    Tcl_Obj **subcmdListPtr)
+{
+    Command *cmdPtr = (Command *) token;
+    EnsembleConfig *ensemblePtr;
+
+    if (cmdPtr->objProc != NsEnsembleImplementationCmd) {
+	if (interp != NULL) {
+	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		    "command is not an ensemble", -1));
+	    Tcl_SetErrorCode(interp, "TCL", "ENSEMBLE", "NOT_ENSEMBLE", NULL);
+	}
+	return TCL_ERROR;
+    }
+
+    ensemblePtr = cmdPtr->objClientData;
+    *subcmdListPtr = ensemblePtr->subcmdList;
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_GetEnsembleParameterList --
+ *
+ *	Get the list of parameters associated with a particular ensemble.
+ *
+ * Results:
+ *	Tcl result code (error if command token does not indicate an
+ *	ensemble). The list of parameters is returned by updating the
+ *	variable pointed to by the last parameter (NULL if there are
+ *	no parameters).
+ *
+ * Side effects:
+ *	None
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_GetEnsembleParameterList(
+    Tcl_Interp *interp,
+    Tcl_Command token,
+    Tcl_Obj **paramListPtr)
+{
+    Command *cmdPtr = (Command *) token;
+    EnsembleConfig *ensemblePtr;
+
+    if (cmdPtr->objProc != NsEnsembleImplementationCmd) {
+	if (interp != NULL) {
+	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		    "command is not an ensemble", -1));
+	    Tcl_SetErrorCode(interp, "TCL", "ENSEMBLE", "NOT_ENSEMBLE", NULL);
+	}
+	return TCL_ERROR;
+    }
+
+    ensemblePtr = cmdPtr->objClientData;
+    *paramListPtr = ensemblePtr->parameterList;
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_GetEnsembleMappingDict --
+ *
+ *	Get the command mapping dictionary associated with a particular
+ *	ensemble.
+ *
+ * Results:
+ *	Tcl result code (error if command token does not indicate an
+ *	ensemble). The mapping dict is returned by updating the variable
+ *	pointed to by the last parameter (NULL if none is installed).
+ *
+ * Side effects:
+ *	None
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_GetEnsembleMappingDict(
+    Tcl_Interp *interp,
+    Tcl_Command token,
+    Tcl_Obj **mapDictPtr)
+{
+    Command *cmdPtr = (Command *) token;
+    EnsembleConfig *ensemblePtr;
+
+    if (cmdPtr->objProc != NsEnsembleImplementationCmd) {
+	if (interp != NULL) {
+	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		    "command is not an ensemble", -1));
+	    Tcl_SetErrorCode(interp, "TCL", "ENSEMBLE", "NOT_ENSEMBLE", NULL);
+	}
+	return TCL_ERROR;
+    }
+
+    ensemblePtr = cmdPtr->objClientData;
+    *mapDictPtr = ensemblePtr->subcommandDict;
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_GetEnsembleUnknownHandler --
+ *
+ *	Get the unknown handler associated with a particular ensemble.
+ *
+ * Results:
+ *	Tcl result code (error if command token does not indicate an
+ *	ensemble). The unknown handler is returned by updating the variable
+ *	pointed to by the last parameter (NULL if no handler is installed).
+ *
+ * Side effects:
+ *	None
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_GetEnsembleUnknownHandler(
+    Tcl_Interp *interp,
+    Tcl_Command token,
+    Tcl_Obj **unknownListPtr)
+{
+    Command *cmdPtr = (Command *) token;
+    EnsembleConfig *ensemblePtr;
+
+    if (cmdPtr->objProc != NsEnsembleImplementationCmd) {
+	if (interp != NULL) {
+	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		    "command is not an ensemble", -1));
+	    Tcl_SetErrorCode(interp, "TCL", "ENSEMBLE", "NOT_ENSEMBLE", NULL);
+	}
+	return TCL_ERROR;
+    }
+
+    ensemblePtr = cmdPtr->objClientData;
+    *unknownListPtr = ensemblePtr->unknownHandler;
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_GetEnsembleFlags --
+ *
+ *	Get the flags for a particular ensemble.
+ *
+ * Results:
+ *	Tcl result code (error if command token does not indicate an
+ *	ensemble). The flags are returned by updating the variable pointed to
+ *	by the last parameter.
+ *
+ * Side effects:
+ *	None
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_GetEnsembleFlags(
+    Tcl_Interp *interp,
+    Tcl_Command token,
+    int *flagsPtr)
+{
+    Command *cmdPtr = (Command *) token;
+    EnsembleConfig *ensemblePtr;
+
+    if (cmdPtr->objProc != NsEnsembleImplementationCmd) {
+	if (interp != NULL) {
+	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		    "command is not an ensemble", -1));
+	    Tcl_SetErrorCode(interp, "TCL", "ENSEMBLE", "NOT_ENSEMBLE", NULL);
+	}
+	return TCL_ERROR;
+    }
+
+    ensemblePtr = cmdPtr->objClientData;
+    *flagsPtr = ensemblePtr->flags;
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_GetEnsembleNamespace --
+ *
+ *	Get the namespace associated with a particular ensemble.
+ *
+ * Results:
+ *	Tcl result code (error if command token does not indicate an
+ *	ensemble). Namespace is returned by updating the variable pointed to
+ *	by the last parameter.
+ *
+ * Side effects:
+ *	None
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_GetEnsembleNamespace(
+    Tcl_Interp *interp,
+    Tcl_Command token,
+    Tcl_Namespace **namespacePtrPtr)
+{
+    Command *cmdPtr = (Command *) token;
+    EnsembleConfig *ensemblePtr;
+
+    if (cmdPtr->objProc != NsEnsembleImplementationCmd) {
+	if (interp != NULL) {
+	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		    "command is not an ensemble", -1));
+	    Tcl_SetErrorCode(interp, "TCL", "ENSEMBLE", "NOT_ENSEMBLE", NULL);
+	}
+	return TCL_ERROR;
+    }
+
+    ensemblePtr = cmdPtr->objClientData;
+    *namespacePtrPtr = (Tcl_Namespace *) ensemblePtr->nsPtr;
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_FindEnsemble --
+ *
+ *	Given a command name, get the ensemble token for it, allowing for
+ *	[namespace import]s. [Bug 1017022]
+ *
+ * Results:
+ *	The token for the ensemble command with the given name, or NULL if the
+ *	command either does not exist or is not an ensemble (when an error
+ *	message will be written into the interp if thats non-NULL).
+ *
+ * Side effects:
+ *	None
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_Command
+Tcl_FindEnsemble(
+    Tcl_Interp *interp,		/* Where to do the lookup, and where to write
+				 * the errors if TCL_LEAVE_ERR_MSG is set in
+				 * the flags. */
+    Tcl_Obj *cmdNameObj,	/* Name of command to look up. */
+    int flags)			/* Either 0 or TCL_LEAVE_ERR_MSG; other flags
+				 * are probably not useful. */
+{
+    Command *cmdPtr;
+
+    cmdPtr = (Command *)
+	    Tcl_FindCommand(interp, TclGetString(cmdNameObj), NULL, flags);
+    if (cmdPtr == NULL) {
+	return NULL;
+    }
+
+    if (cmdPtr->objProc != NsEnsembleImplementationCmd) {
+	/*
+	 * Reuse existing infrastructure for following import link chains
+	 * rather than duplicating it.
+	 */
+
+	cmdPtr = (Command *) TclGetOriginalCommand((Tcl_Command) cmdPtr);
+
+	if (cmdPtr == NULL || cmdPtr->objProc != NsEnsembleImplementationCmd){
+	    if (flags & TCL_LEAVE_ERR_MSG) {
+		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+			"\"%s\" is not an ensemble command",
+			TclGetString(cmdNameObj)));
+		Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "ENSEMBLE",
+			TclGetString(cmdNameObj), NULL);
+	    }
+	    return NULL;
+	}
+    }
+
+    return (Tcl_Command) cmdPtr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_IsEnsemble --
+ *
+ *	Simple test for ensemble-hood that takes into account imported
+ *	ensemble commands as well.
+ *
+ * Results:
+ *	Boolean value
+ *
+ * Side effects:
+ *	None
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_IsEnsemble(
+    Tcl_Command token)
+{
+    Command *cmdPtr = (Command *) token;
+
+    if (cmdPtr->objProc == NsEnsembleImplementationCmd) {
+	return 1;
+    }
+    cmdPtr = (Command *) TclGetOriginalCommand((Tcl_Command) cmdPtr);
+    if (cmdPtr == NULL || cmdPtr->objProc != NsEnsembleImplementationCmd) {
+	return 0;
+    }
+    return 1;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclMakeEnsemble --
+ *
+ *	Create an ensemble from a table of implementation commands. The
+ *	ensemble will be subject to (limited) compilation if any of the
+ *	implementation commands are compilable.
+ *
+ *	The 'name' parameter may be a single command name or a list if
+ *	creating an ensemble subcommand (see the binary implementation).
+ *
+ *	Currently, the TCL_ENSEMBLE_PREFIX ensemble flag is only used on
+ *	top-level ensemble commands.
+ *
+ * Results:
+ *	Handle for the new ensemble, or NULL on failure.
+ *
+ * Side effects:
+ *	May advance the bytecode compilation epoch.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_Command
+TclMakeEnsemble(
+    Tcl_Interp *interp,
+    const char *name,		 /* The ensemble name (as explained above) */
+    const EnsembleImplMap map[]) /* The subcommands to create */
+{
+    Tcl_Command ensemble;
+    Tcl_Namespace *ns;
+    Tcl_DString buf, hiddenBuf;
+    const char **nameParts = NULL;
+    const char *cmdName = NULL;
+    int i, nameCount = 0, ensembleFlags = 0, hiddenLen;
+
+    /*
+     * Construct the path for the ensemble namespace and create it.
+     */
+
+    Tcl_DStringInit(&buf);
+    Tcl_DStringInit(&hiddenBuf);
+    TclDStringAppendLiteral(&hiddenBuf, "tcl:");
+    Tcl_DStringAppend(&hiddenBuf, name, -1);
+    TclDStringAppendLiteral(&hiddenBuf, ":");
+    hiddenLen = Tcl_DStringLength(&hiddenBuf);
+    if (name[0] == ':' && name[1] == ':') {
+	/*
+	 * An absolute name, so use it directly.
+	 */
+
+	cmdName = name;
+	Tcl_DStringAppend(&buf, name, -1);
+	ensembleFlags = TCL_ENSEMBLE_PREFIX;
+    } else {
+	/*
+	 * Not an absolute name, so do munging of it. Note that this treats a
+	 * multi-word list differently to a single word.
+	 */
+
+	TclDStringAppendLiteral(&buf, "::tcl");
+
+	if (Tcl_SplitList(NULL, name, &nameCount, &nameParts) != TCL_OK) {
+	    Tcl_Panic("invalid ensemble name '%s'", name);
+	}
+
+	for (i = 0; i < nameCount; ++i) {
+	    TclDStringAppendLiteral(&buf, "::");
+	    Tcl_DStringAppend(&buf, nameParts[i], -1);
+	}
+    }
+
+    ns = Tcl_FindNamespace(interp, Tcl_DStringValue(&buf), NULL,
+	    TCL_CREATE_NS_IF_UNKNOWN);
+    if (!ns) {
+	Tcl_Panic("unable to find or create %s namespace!",
+		Tcl_DStringValue(&buf));
+    }
+
+    /*
+     * Create the named ensemble in the correct namespace
+     */
+
+    if (cmdName == NULL) {
+	if (nameCount == 1) {
+	    ensembleFlags = TCL_ENSEMBLE_PREFIX;
+	    cmdName = Tcl_DStringValue(&buf) + 5;
+	} else {
+	    ns = ns->parentPtr;
+	    cmdName = nameParts[nameCount - 1];
+	}
+    }
+
+    /*
+     * Switch on compilation always for core ensembles now that we can do
+     * nice bytecode things with them.  Do it now.  Waiting until later will
+     * just cause pointless epoch bumps.
+     */
+
+    ensembleFlags |= ENSEMBLE_COMPILE;
+    ensemble = Tcl_CreateEnsemble(interp, cmdName, ns, ensembleFlags);
+
+    /*
+     * Create the ensemble mapping dictionary and the ensemble command procs.
+     */
+
+    if (ensemble != NULL) {
+	Tcl_Obj *mapDict, *fromObj, *toObj;
+	Command *cmdPtr;
+
+	TclDStringAppendLiteral(&buf, "::");
+	TclNewObj(mapDict);
+	for (i=0 ; map[i].name != NULL ; i++) {
+	    fromObj = Tcl_NewStringObj(map[i].name, -1);
+	    TclNewStringObj(toObj, Tcl_DStringValue(&buf),
+		    Tcl_DStringLength(&buf));
+	    Tcl_AppendToObj(toObj, map[i].name, -1);
+	    Tcl_DictObjPut(NULL, mapDict, fromObj, toObj);
+
+	    if (map[i].proc || map[i].nreProc) {
+		/*
+		 * If the command is unsafe, hide it when we're in a safe
+		 * interpreter. The code to do this is really hokey! It also
+		 * doesn't work properly yet; this function is always
+		 * currently called before the safe-interp flag is set so the
+		 * Tcl_IsSafe check fails.
+		 */
+
+		if (map[i].unsafe && Tcl_IsSafe(interp)) {
+		    cmdPtr = (Command *)
+			    Tcl_NRCreateCommand(interp, "___tmp", map[i].proc,
+			    map[i].nreProc, map[i].clientData, NULL);
+		    Tcl_DStringSetLength(&hiddenBuf, hiddenLen);
+		    if (Tcl_HideCommand(interp, "___tmp",
+			    Tcl_DStringAppend(&hiddenBuf, map[i].name, -1))) {
+			Tcl_Panic("%s", Tcl_GetString(Tcl_GetObjResult(interp)));
+		    }
+		} else {
+		    /*
+		     * Not hidden, so just create it. Yay!
+		     */
+
+		    cmdPtr = (Command *)
+			    Tcl_NRCreateCommand(interp, TclGetString(toObj),
+			    map[i].proc, map[i].nreProc, map[i].clientData,
+			    NULL);
+		}
+		cmdPtr->compileProc = map[i].compileProc;
+	    }
+	}
+	Tcl_SetEnsembleMappingDict(interp, ensemble, mapDict);
+    }
+
+    Tcl_DStringFree(&buf);
+    Tcl_DStringFree(&hiddenBuf);
+    if (nameParts != NULL) {
+	ckfree((char *) nameParts);
+    }
+    return ensemble;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * NsEnsembleImplementationCmd --
+ *
+ *	Implements an ensemble of commands (being those exported by a
+ *	namespace other than the global namespace) as a command with the same
+ *	(short) name as the namespace in the parent namespace.
+ *
+ * Results:
+ *	A standard Tcl result code. Will be TCL_ERROR if the command is not an
+ *	unambiguous prefix of any command exported by the ensemble's
+ *	namespace.
+ *
+ * Side effects:
+ *	Depends on the command within the namespace that gets executed. If the
+ *	ensemble itself returns TCL_ERROR, a descriptive error message will be
+ *	placed in the interpreter's result.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+NsEnsembleImplementationCmd(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const objv[])
+{
+    return Tcl_NRCallObjProc(interp, NsEnsembleImplementationCmdNR,
+	    clientData, objc, objv);
+}
+
+static int
+NsEnsembleImplementationCmdNR(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const objv[])
+{
+    EnsembleConfig *ensemblePtr = clientData;
+				/* The ensemble itself. */
+    Tcl_Obj *prefixObj;		/* An object containing the prefix words of
+				 * the command that implements the
+				 * subcommand. */
+    Tcl_HashEntry *hPtr;	/* Used for efficient lookup of fully
+				 * specified but not yet cached command
+				 * names. */
+    int reparseCount = 0;	/* Number of reparses. */
+    Tcl_Obj *errorObj;		/* Used for building error messages. */
+    Tcl_Obj *subObj;
+    int subIdx;
+
+    /*
+     * Must recheck objc, since numParameters might have changed. Cf. test
+     * namespace-53.9.
+     */
+
+  restartEnsembleParse:
+    subIdx = 1 + ensemblePtr->numParameters;
+    if (objc < subIdx + 1) {
+	/*
+	 * We don't have a subcommand argument. Make error message.
+	 */
+
+	Tcl_DString buf;	/* Message being built */
+
+	Tcl_DStringInit(&buf);
+	if (ensemblePtr->parameterList) {
+	    Tcl_DStringAppend(&buf,
+		    TclGetString(ensemblePtr->parameterList), -1);
+	    TclDStringAppendLiteral(&buf, " ");
+	}
+	TclDStringAppendLiteral(&buf, "subcommand ?arg ...?");
+	Tcl_WrongNumArgs(interp, 1, objv, Tcl_DStringValue(&buf));
+	Tcl_DStringFree(&buf);
+
+	return TCL_ERROR;
+    }
+
+    if (ensemblePtr->nsPtr->flags & NS_DYING) {
+	/*
+	 * Don't know how we got here, but make things give up quickly.
+	 */
+
+	if (!Tcl_InterpDeleted(interp)) {
+	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		    "ensemble activated for deleted namespace", -1));
+	    Tcl_SetErrorCode(interp, "TCL", "ENSEMBLE", "DEAD", NULL);
+	}
+	return TCL_ERROR;
+    }
+
+    /*
+     * Determine if the table of subcommands is right. If so, we can just look
+     * up in there and go straight to dispatch.
+     */
+
+    subObj = objv[subIdx];
+
+    if (ensemblePtr->epoch == ensemblePtr->nsPtr->exportLookupEpoch) {
+	/*
+	 * Table of subcommands is still valid; therefore there might be a
+	 * valid cache of discovered information which we can reuse. Do the
+	 * check here, and if we're still valid, we can jump straight to the
+	 * part where we do the invocation of the subcommand.
+	 */
+
+	if (subObj->typePtr==&ensembleCmdType){
+	    EnsembleCmdRep *ensembleCmd = subObj->internalRep.twoPtrValue.ptr1;
+
+	    if (ensembleCmd->epoch == ensemblePtr->epoch &&
+		    ensembleCmd->token == (Command *)ensemblePtr->token) {
+		prefixObj = Tcl_GetHashValue(ensembleCmd->hPtr);
+		Tcl_IncrRefCount(prefixObj);
+		if (ensembleCmd->fix) {
+		    TclSpellFix(interp, objv, objc, subIdx, subObj, ensembleCmd->fix);
+		}
+		goto runResultingSubcommand;
+	    }
+	}
+    } else {
+	BuildEnsembleConfig(ensemblePtr);
+	ensemblePtr->epoch = ensemblePtr->nsPtr->exportLookupEpoch;
+    }
+
+    /*
+     * Look in the hashtable for the subcommand name; this is the fastest way
+     * of all if there is no cache in operation.
+     */
+
+    hPtr = Tcl_FindHashEntry(&ensemblePtr->subcommandTable,
+	    TclGetString(subObj));
+    if (hPtr != NULL) {
+
+	/*
+	 * Cache for later in the subcommand object.
+	 */
+
+	MakeCachedEnsembleCommand(subObj, ensemblePtr, hPtr, NULL);
+    } else if (!(ensemblePtr->flags & TCL_ENSEMBLE_PREFIX)) {
+	/*
+	 * Could not map, no prefixing, go to unknown/error handling.
+	 */
+
+	goto unknownOrAmbiguousSubcommand;
+    } else {
+	/*
+	 * If we've not already confirmed the command with the hash as part of
+	 * building our export table, we need to scan the sorted array for
+	 * matches.
+	 */
+
+	const char *subcmdName; /* Name of the subcommand, or unique prefix of
+				 * it (will be an error for a non-unique
+				 * prefix). */
+	char *fullName = NULL;	/* Full name of the subcommand. */
+	int stringLength, i;
+	int tableLength = ensemblePtr->subcommandTable.numEntries;
+	Tcl_Obj *fix;
+
+	subcmdName = Tcl_GetStringFromObj(subObj, &stringLength);
+	for (i=0 ; i<tableLength ; i++) {
+	    register int cmp = strncmp(subcmdName,
+		    ensemblePtr->subcommandArrayPtr[i],
+		    (unsigned) stringLength);
+
+	    if (cmp == 0) {
+		if (fullName != NULL) {
+		    /*
+		     * Since there's never the exact-match case to worry about
+		     * (hash search filters this), getting here indicates that
+		     * our subcommand is an ambiguous prefix of (at least) two
+		     * exported subcommands, which is an error case.
+		     */
+
+		    goto unknownOrAmbiguousSubcommand;
+		}
+		fullName = ensemblePtr->subcommandArrayPtr[i];
+	    } else if (cmp < 0) {
+		/*
+		 * Because we are searching a sorted table, we can now stop
+		 * searching because we have gone past anything that could
+		 * possibly match.
+		 */
+
+		break;
+	    }
+	}
+	if (fullName == NULL) {
+	    /*
+	     * The subcommand is not a prefix of anything, so bail out!
+	     */
+
+	    goto unknownOrAmbiguousSubcommand;
+	}
+	hPtr = Tcl_FindHashEntry(&ensemblePtr->subcommandTable, fullName);
+	if (hPtr == NULL) {
+	    Tcl_Panic("full name %s not found in supposedly synchronized hash",
+		    fullName);
+	}
+
+	/*
+	 * Record the spelling correction for usage message.
+	 */
+
+	fix = Tcl_NewStringObj(fullName, -1);
+
+	/*
+	 * Cache for later in the subcommand object.
+	 */
+
+	MakeCachedEnsembleCommand(subObj, ensemblePtr, hPtr, fix);
+	TclSpellFix(interp, objv, objc, subIdx, subObj, fix);
+    }
+
+    prefixObj = Tcl_GetHashValue(hPtr);
+    Tcl_IncrRefCount(prefixObj);
+  runResultingSubcommand:
+
+    /*
+     * Do the real work of execution of the subcommand by building an array of
+     * objects (note that this is potentially not the same length as the
+     * number of arguments to this ensemble command), populating it and then
+     * feeding it back through the main command-lookup engine. In theory, we
+     * could look up the command in the namespace ourselves, as we already
+     * have the namespace in which it is guaranteed to exist,
+     *
+     *   ((Q: That's not true if the -map option is used, is it?))
+     *
+     * but we don't do that (the cacheing of the command object used should
+     * help with that.)
+     */
+
+    {
+	Tcl_Obj *copyPtr;	/* The actual list of words to dispatch to.
+				 * Will be freed by the dispatch engine. */
+	Tcl_Obj **copyObjv;
+	int copyObjc, prefixObjc;
+
+	Tcl_ListObjLength(NULL, prefixObj, &prefixObjc);
+
+	if (objc == 2) {
+	    copyPtr = TclListObjCopy(NULL, prefixObj);
+	} else {
+	    copyPtr = Tcl_NewListObj(objc - 2 + prefixObjc, NULL);
+	    Tcl_ListObjAppendList(NULL, copyPtr, prefixObj);
+	    Tcl_ListObjReplace(NULL, copyPtr, LIST_MAX, 0,
+		    ensemblePtr->numParameters, objv + 1);
+	    Tcl_ListObjReplace(NULL, copyPtr, LIST_MAX, 0,
+		    objc - 2 - ensemblePtr->numParameters,
+		    objv + 2 + ensemblePtr->numParameters);
+	}
+	Tcl_IncrRefCount(copyPtr);
+	TclNRAddCallback(interp, TclNRReleaseValues, copyPtr, NULL, NULL, NULL);
+	TclDecrRefCount(prefixObj);
+
+	/*
+	 * Record what arguments the script sent in so that things like
+	 * Tcl_WrongNumArgs can give the correct error message. Parameters
+	 * count both as inserted and removed arguments.
+	 */
+
+	if (TclInitRewriteEnsemble(interp, 2 + ensemblePtr->numParameters,
+		prefixObjc + ensemblePtr->numParameters, objv)) {
+	    TclNRAddCallback(interp, TclClearRootEnsemble, NULL, NULL, NULL,
+		    NULL);
+	}
+
+	/*
+	 * Hand off to the target command.
+	 */
+
+	TclSkipTailcall(interp);
+	Tcl_ListObjGetElements(NULL, copyPtr, &copyObjc, &copyObjv);
+	return TclNREvalObjv(interp, copyObjc, copyObjv, TCL_EVAL_INVOKE, NULL);
+    }
+
+  unknownOrAmbiguousSubcommand:
+    /*
+     * Have not been able to match the subcommand asked for with a real
+     * subcommand that we export. See whether a handler has been registered
+     * for dealing with this situation. Will only call (at most) once for any
+     * particular ensemble invocation.
+     */
+
+    if (ensemblePtr->unknownHandler != NULL && reparseCount++ < 1) {
+	switch (EnsembleUnknownCallback(interp, ensemblePtr, objc, objv,
+		&prefixObj)) {
+	case TCL_OK:
+	    goto runResultingSubcommand;
+	case TCL_ERROR:
+	    return TCL_ERROR;
+	case TCL_CONTINUE:
+	    goto restartEnsembleParse;
+	}
+    }
+
+    /*
+     * We cannot determine what subcommand to hand off to, so generate a
+     * (standard) failure message. Note the one odd case compared with
+     * standard ensemble-like command, which is where a namespace has no
+     * exported commands at all...
+     */
+
+    Tcl_ResetResult(interp);
+    Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "SUBCOMMAND",
+	    TclGetString(subObj), NULL);
+    if (ensemblePtr->subcommandTable.numEntries == 0) {
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		"unknown subcommand \"%s\": namespace %s does not"
+		" export any commands", TclGetString(subObj),
+		ensemblePtr->nsPtr->fullName));
+	return TCL_ERROR;
+    }
+    errorObj = Tcl_ObjPrintf("unknown%s subcommand \"%s\": must be ",
+	    (ensemblePtr->flags & TCL_ENSEMBLE_PREFIX ? " or ambiguous" : ""),
+	    TclGetString(subObj));
+    if (ensemblePtr->subcommandTable.numEntries == 1) {
+	Tcl_AppendToObj(errorObj, ensemblePtr->subcommandArrayPtr[0], -1);
+    } else {
+	int i;
+
+	for (i=0 ; i<ensemblePtr->subcommandTable.numEntries-1 ; i++) {
+	    Tcl_AppendToObj(errorObj, ensemblePtr->subcommandArrayPtr[i], -1);
+	    Tcl_AppendToObj(errorObj, ", ", 2);
+	}
+	Tcl_AppendPrintfToObj(errorObj, "or %s",
+		ensemblePtr->subcommandArrayPtr[i]);
+    }
+    Tcl_SetObjResult(interp, errorObj);
+    return TCL_ERROR;
+}
+
+int
+TclClearRootEnsemble(
+    ClientData data[],
+    Tcl_Interp *interp,
+    int result)
+{
+    TclResetRewriteEnsemble(interp, 1);
+    return result;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclInitRewriteEnsemble --
+ *
+ *	Applies a rewrite of arguments so that an ensemble subcommand will
+ *	report error messages correctly for the overall command.
+ *
+ * Results:
+ *	Whether this is the first rewrite applied, a value which must be
+ *	passed to TclResetRewriteEnsemble when undoing this command's
+ *	behaviour.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclInitRewriteEnsemble(
+    Tcl_Interp *interp,
+    int numRemoved,
+    int numInserted,
+    Tcl_Obj *const *objv)
+{
+    Interp *iPtr = (Interp *) interp;
+
+    int isRootEnsemble = (iPtr->ensembleRewrite.sourceObjs == NULL);
+
+    if (isRootEnsemble) {
+	iPtr->ensembleRewrite.sourceObjs = objv;
+	iPtr->ensembleRewrite.numRemovedObjs = numRemoved;
+	iPtr->ensembleRewrite.numInsertedObjs = numInserted;
+    } else {
+	int numIns = iPtr->ensembleRewrite.numInsertedObjs;
+
+	if (numIns < numRemoved) {
+	    iPtr->ensembleRewrite.numRemovedObjs += numRemoved - numIns;
+	    iPtr->ensembleRewrite.numInsertedObjs = numInserted;
+	} else {
+	    iPtr->ensembleRewrite.numInsertedObjs += numInserted - numRemoved;
+	}
+    }
+    return isRootEnsemble;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclResetRewriteEnsemble --
+ *
+ *	Removes any rewrites applied to support proper reporting of error
+ *	messages used in ensembles. Should be paired with
+ *	TclInitRewriteEnsemble.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclResetRewriteEnsemble(
+    Tcl_Interp *interp,
+    int isRootEnsemble)
+{
+    Interp *iPtr = (Interp *) interp;
+
+    if (isRootEnsemble) {
+	iPtr->ensembleRewrite.sourceObjs = NULL;
+	iPtr->ensembleRewrite.numRemovedObjs = 0;
+	iPtr->ensembleRewrite.numInsertedObjs = 0;
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclSpellFix --
+ *
+ *	Record a spelling correction that needs making in the
+ *	generation of the WrongNumArgs usage message.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Can create an alternative ensemble rewrite structure.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+FreeER(
+    ClientData data[],
+    Tcl_Interp *interp,
+    int result)
+{
+    Tcl_Obj **tmp = (Tcl_Obj **)data[0];
+
+    ckfree(tmp[2]);
+    ckfree(tmp);
+    return result;
+}
+
+void
+TclSpellFix(
+    Tcl_Interp *interp,
+    Tcl_Obj *const *objv,
+    int objc,
+    int badIdx,
+    Tcl_Obj *bad,
+    Tcl_Obj *fix)
+{
+    Interp *iPtr = (Interp *) interp;
+    Tcl_Obj *const *search;
+    Tcl_Obj **store;
+    int idx;
+    int size;
+
+    if (iPtr->ensembleRewrite.sourceObjs == NULL) {
+	iPtr->ensembleRewrite.sourceObjs = objv;
+	iPtr->ensembleRewrite.numRemovedObjs = 0;
+	iPtr->ensembleRewrite.numInsertedObjs = 0;
+    }
+
+    /* Compute the valid length of the ensemble root */
+
+    size = iPtr->ensembleRewrite.numRemovedObjs + objc
+		- iPtr->ensembleRewrite.numInsertedObjs;
+
+    search = iPtr->ensembleRewrite.sourceObjs;
+    if (search[0] == NULL) {
+	/* Awful casting abuse here */
+	search = (Tcl_Obj *const *) search[1];
+    }
+
+    if (badIdx < iPtr->ensembleRewrite.numInsertedObjs) {
+	/*
+	 * Misspelled value was inserted. We cannot directly jump
+	 * to the bad value, but have to search.
+	 */
+	idx = 1;
+	while (idx < size) {
+	    if (search[idx] == bad) {
+		break;
+	    }
+	    idx++;
+	}
+	if (idx == size) {
+	    return;
+	}
+    } else {
+	/* Jump to the misspelled value. */
+	idx = iPtr->ensembleRewrite.numRemovedObjs + badIdx
+		- iPtr->ensembleRewrite.numInsertedObjs;
+
+	/* Verify */
+	if (search[idx] != bad) {
+	    Tcl_Panic("SpellFix: programming error");
+	}
+    }
+
+    search = iPtr->ensembleRewrite.sourceObjs;
+    if (search[0] == NULL) {
+	store = (Tcl_Obj **)search[2];
+    }  else {
+	Tcl_Obj **tmp = ckalloc(3 * sizeof(Tcl_Obj *));
+	tmp[0] = NULL;
+	tmp[1] = (Tcl_Obj *)iPtr->ensembleRewrite.sourceObjs;
+	tmp[2] = (Tcl_Obj *)ckalloc(size * sizeof(Tcl_Obj *));
+	memcpy(tmp[2], tmp[1], size*sizeof(Tcl_Obj *));
+
+	iPtr->ensembleRewrite.sourceObjs = (Tcl_Obj *const *) tmp;
+	TclNRAddCallback(interp, FreeER, tmp, NULL, NULL, NULL);
+	store = (Tcl_Obj **)tmp[2];
+    }
+
+    store[idx] = fix;
+    Tcl_IncrRefCount(fix);
+    TclNRAddCallback(interp, TclNRReleaseValues, fix, NULL, NULL, NULL);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclFetchEnsembleRoot --
+ *
+ *	Returns the root of ensemble rewriting, if any.
+ *	If no root exists, returns objv instead.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_Obj *const *
+TclFetchEnsembleRoot(
+    Tcl_Interp *interp,
+    Tcl_Obj *const *objv,
+    int objc,
+    int *objcPtr)
+{
+    Interp *iPtr = (Interp *) interp;
+
+    if (iPtr->ensembleRewrite.sourceObjs) {
+	*objcPtr = objc + iPtr->ensembleRewrite.numRemovedObjs
+		- iPtr->ensembleRewrite.numInsertedObjs;
+	return iPtr->ensembleRewrite.sourceObjs;
+    }
+    *objcPtr = objc;
+    return objv;
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * EnsmebleUnknownCallback --
+ *
+ *	Helper for the ensemble engine that handles the procesing of unknown
+ *	callbacks. See the user documentation of the ensemble unknown handler
+ *	for details; this function is only ever called when such a function is
+ *	defined, and is only ever called once per ensemble dispatch (i.e. if a
+ *	reparse still fails, this isn't called again).
+ *
+ * Results:
+ *	TCL_OK -	*prefixObjPtr contains the command words to dispatch
+ *			to.
+ *	TCL_CONTINUE -	Need to reparse (*prefixObjPtr is invalid).
+ *	TCL_ERROR -	Something went wrong! Error message in interpreter.
+ *
+ * Side effects:
+ *	Calls the Tcl interpreter, so arbitrary.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+static inline int
+EnsembleUnknownCallback(
+    Tcl_Interp *interp,
+    EnsembleConfig *ensemblePtr,
+    int objc,
+    Tcl_Obj *const objv[],
+    Tcl_Obj **prefixObjPtr)
+{
+    int paramc, i, result, prefixObjc;
+    Tcl_Obj **paramv, *unknownCmd, *ensObj;
+
+    /*
+     * Create the unknown command callback to determine what to do.
+     */
+
+    unknownCmd = Tcl_DuplicateObj(ensemblePtr->unknownHandler);
+    TclNewObj(ensObj);
+    Tcl_GetCommandFullName(interp, ensemblePtr->token, ensObj);
+    Tcl_ListObjAppendElement(NULL, unknownCmd, ensObj);
+    for (i=1 ; i<objc ; i++) {
+	Tcl_ListObjAppendElement(NULL, unknownCmd, objv[i]);
+    }
+    TclListObjGetElements(NULL, unknownCmd, &paramc, &paramv);
+    Tcl_IncrRefCount(unknownCmd);
+
+    /*
+     * Now call the unknown handler. (We don't bother NRE-enabling this; deep
+     * recursing through unknown handlers is horribly perverse.) Note that it
+     * is always an error for an unknown handler to delete its ensemble; don't
+     * do that!
+     */
+
+    Tcl_Preserve(ensemblePtr);
+    TclSkipTailcall(interp);
+    result = Tcl_EvalObjv(interp, paramc, paramv, 0);
+    if ((result == TCL_OK) && (ensemblePtr->flags & ENSEMBLE_DEAD)) {
+	if (!Tcl_InterpDeleted(interp)) {
+	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		    "unknown subcommand handler deleted its ensemble", -1));
+	    Tcl_SetErrorCode(interp, "TCL", "ENSEMBLE", "UNKNOWN_DELETED",
+		    NULL);
+	}
+	result = TCL_ERROR;
+    }
+    Tcl_Release(ensemblePtr);
+
+    /*
+     * If we succeeded, we should either have a list of words that form the
+     * command to be executed, or an empty list. In the empty-list case, the
+     * ensemble is believed to be updated so we should ask the ensemble engine
+     * to reparse the original command.
+     */
+
+    if (result == TCL_OK) {
+	*prefixObjPtr = Tcl_GetObjResult(interp);
+	Tcl_IncrRefCount(*prefixObjPtr);
+	TclDecrRefCount(unknownCmd);
+	Tcl_ResetResult(interp);
+
+	/*
+	 * Namespace is still there. Check if the result is a valid list. If
+	 * it is, and it is non-empty, that list is what we are using as our
+	 * replacement.
+	 */
+
+	if (TclListObjLength(interp, *prefixObjPtr, &prefixObjc) != TCL_OK) {
+	    TclDecrRefCount(*prefixObjPtr);
+	    Tcl_AddErrorInfo(interp, "\n    while parsing result of "
+		    "ensemble unknown subcommand handler");
+	    return TCL_ERROR;
+	}
+	if (prefixObjc > 0) {
+	    return TCL_OK;
+	}
+
+	/*
+	 * Namespace alive & empty result => reparse.
+	 */
+
+	TclDecrRefCount(*prefixObjPtr);
+	return TCL_CONTINUE;
+    }
+
+    /*
+     * Oh no! An exceptional result. Convert to an error.
+     */
+
+    if (!Tcl_InterpDeleted(interp)) {
+	if (result != TCL_ERROR) {
+	    Tcl_ResetResult(interp);
+	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		    "unknown subcommand handler returned bad code: ", -1));
+	    switch (result) {
+	    case TCL_RETURN:
+		Tcl_AppendToObj(Tcl_GetObjResult(interp), "return", -1);
+		break;
+	    case TCL_BREAK:
+		Tcl_AppendToObj(Tcl_GetObjResult(interp), "break", -1);
+		break;
+	    case TCL_CONTINUE:
+		Tcl_AppendToObj(Tcl_GetObjResult(interp), "continue", -1);
+		break;
+	    default:
+		Tcl_AppendPrintfToObj(Tcl_GetObjResult(interp), "%d", result);
+	    }
+	    Tcl_AddErrorInfo(interp, "\n    result of "
+		    "ensemble unknown subcommand handler: ");
+	    Tcl_AppendObjToErrorInfo(interp, unknownCmd);
+	    Tcl_SetErrorCode(interp, "TCL", "ENSEMBLE", "UNKNOWN_RESULT",
+		    NULL);
+	} else {
+	    Tcl_AddErrorInfo(interp,
+		    "\n    (ensemble unknown subcommand handler)");
+	}
+    }
+    TclDecrRefCount(unknownCmd);
+    return TCL_ERROR;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * MakeCachedEnsembleCommand --
+ *
+ *	Cache what we've computed so far; it's not nice to repeatedly copy
+ *	strings about. Note that to do this, we start by deleting any old
+ *	representation that there was (though if it was an out of date
+ *	ensemble rep, we can skip some of the deallocation process.)
+ *
+ * Results:
+ *	None
+ *
+ * Side effects:
+ *	Alters the internal representation of the first object parameter.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+MakeCachedEnsembleCommand(
+    Tcl_Obj *objPtr,
+    EnsembleConfig *ensemblePtr,
+    Tcl_HashEntry *hPtr,
+    Tcl_Obj *fix)
+{
+    register EnsembleCmdRep *ensembleCmd;
+
+    if (objPtr->typePtr == &ensembleCmdType) {
+	ensembleCmd = objPtr->internalRep.twoPtrValue.ptr1;
+	TclCleanupCommandMacro(ensembleCmd->token);
+	if (ensembleCmd->fix) {
+	    Tcl_DecrRefCount(ensembleCmd->fix);
+	}
+    } else {
+	/*
+	 * Kill the old internal rep, and replace it with a brand new one of
+	 * our own.
+	 */
+
+	TclFreeIntRep(objPtr);
+	ensembleCmd = ckalloc(sizeof(EnsembleCmdRep));
+	objPtr->internalRep.twoPtrValue.ptr1 = ensembleCmd;
+	objPtr->typePtr = &ensembleCmdType;
+    }
+
+    /*
+     * Populate the internal rep.
+     */
+
+    ensembleCmd->epoch = ensemblePtr->epoch;
+    ensembleCmd->token = (Command *) ensemblePtr->token;
+    ensembleCmd->token->refCount++;
+    if (fix) {
+	Tcl_IncrRefCount(fix);
+    }
+    ensembleCmd->fix = fix;
+    ensembleCmd->hPtr = hPtr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * DeleteEnsembleConfig --
+ *
+ *	Destroys the data structure used to represent an ensemble. This is
+ *	called when the ensemble's command is deleted (which happens
+ *	automatically if the ensemble's namespace is deleted.) Maintainers
+ *	should note that ensembles should be deleted by deleting their
+ *	commands.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Memory is (eventually) deallocated.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+DeleteEnsembleConfig(
+    ClientData clientData)
+{
+    EnsembleConfig *ensemblePtr = clientData;
+    Namespace *nsPtr = ensemblePtr->nsPtr;
+    Tcl_HashSearch search;
+    Tcl_HashEntry *hEnt;
+
+    /*
+     * Unlink from the ensemble chain if it has not been marked as having been
+     * done already.
+     */
+
+    if (ensemblePtr->next != ensemblePtr) {
+	EnsembleConfig *ensPtr = (EnsembleConfig *) nsPtr->ensembles;
+
+	if (ensPtr == ensemblePtr) {
+	    nsPtr->ensembles = (Tcl_Ensemble *) ensemblePtr->next;
+	} else {
+	    while (ensPtr != NULL) {
+		if (ensPtr->next == ensemblePtr) {
+		    ensPtr->next = ensemblePtr->next;
+		    break;
+		}
+		ensPtr = ensPtr->next;
+	    }
+	}
+    }
+
+    /*
+     * Mark the namespace as dead so code that uses Tcl_Preserve() can tell
+     * whether disaster happened anyway.
+     */
+
+    ensemblePtr->flags |= ENSEMBLE_DEAD;
+
+    /*
+     * Kill the pointer-containing fields.
+     */
+
+    if (ensemblePtr->subcommandTable.numEntries != 0) {
+	ckfree(ensemblePtr->subcommandArrayPtr);
+    }
+    hEnt = Tcl_FirstHashEntry(&ensemblePtr->subcommandTable, &search);
+    while (hEnt != NULL) {
+	Tcl_Obj *prefixObj = Tcl_GetHashValue(hEnt);
+
+	Tcl_DecrRefCount(prefixObj);
+	hEnt = Tcl_NextHashEntry(&search);
+    }
+    Tcl_DeleteHashTable(&ensemblePtr->subcommandTable);
+    if (ensemblePtr->subcmdList != NULL) {
+	Tcl_DecrRefCount(ensemblePtr->subcmdList);
+    }
+    if (ensemblePtr->parameterList != NULL) {
+	Tcl_DecrRefCount(ensemblePtr->parameterList);
+    }
+    if (ensemblePtr->subcommandDict != NULL) {
+	Tcl_DecrRefCount(ensemblePtr->subcommandDict);
+    }
+    if (ensemblePtr->unknownHandler != NULL) {
+	Tcl_DecrRefCount(ensemblePtr->unknownHandler);
+    }
+
+    /*
+     * Arrange for the structure to be reclaimed. Note that this is complex
+     * because we have to make sure that we can react sensibly when an
+     * ensemble is deleted during the process of initialising the ensemble
+     * (especially the unknown callback.)
+     */
+
+    Tcl_EventuallyFree(ensemblePtr, TCL_DYNAMIC);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * BuildEnsembleConfig --
+ *
+ *	Create the internal data structures that describe how an ensemble
+ *	looks, being a hash mapping from the full command name to the Tcl list
+ *	that describes the implementation prefix words, and a sorted array of
+ *	all the full command names to allow for reasonably efficient
+ *	unambiguous prefix handling.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Reallocates and rebuilds the hash table and array stored at the
+ *	ensemblePtr argument. For large ensembles or large namespaces, this is
+ *	a potentially expensive operation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+BuildEnsembleConfig(
+    EnsembleConfig *ensemblePtr)
+{
+    Tcl_HashSearch search;	/* Used for scanning the set of commands in
+				 * the namespace that backs up this
+				 * ensemble. */
+    int i, j, isNew;
+    Tcl_HashTable *hash = &ensemblePtr->subcommandTable;
+    Tcl_HashEntry *hPtr;
+
+    if (hash->numEntries != 0) {
+	/*
+	 * Remove pre-existing table.
+	 */
+
+	ckfree(ensemblePtr->subcommandArrayPtr);
+	hPtr = Tcl_FirstHashEntry(hash, &search);
+	while (hPtr != NULL) {
+	    Tcl_Obj *prefixObj = Tcl_GetHashValue(hPtr);
+
+	    Tcl_DecrRefCount(prefixObj);
+	    hPtr = Tcl_NextHashEntry(&search);
+	}
+	Tcl_DeleteHashTable(hash);
+	Tcl_InitHashTable(hash, TCL_STRING_KEYS);
+    }
+
+    /*
+     * See if we've got an export list. If so, we will only export exactly
+     * those commands, which may be either implemented by the prefix in the
+     * subcommandDict or mapped directly onto the namespace's commands.
+     */
+
+    if (ensemblePtr->subcmdList != NULL) {
+	Tcl_Obj **subcmdv, *target, *cmdObj, *cmdPrefixObj;
+	int subcmdc;
+
+	TclListObjGetElements(NULL, ensemblePtr->subcmdList, &subcmdc,
+		&subcmdv);
+	for (i=0 ; i<subcmdc ; i++) {
+	    const char *name = TclGetString(subcmdv[i]);
+
+	    hPtr = Tcl_CreateHashEntry(hash, name, &isNew);
+
+	    /*
+	     * Skip non-unique cases.
+	     */
+
+	    if (!isNew) {
+		continue;
+	    }
+
+	    /*
+	     * Look in our dictionary (if present) for the command.
+	     */
+
+	    if (ensemblePtr->subcommandDict != NULL) {
+		Tcl_DictObjGet(NULL, ensemblePtr->subcommandDict, subcmdv[i],
+			&target);
+		if (target != NULL) {
+		    Tcl_SetHashValue(hPtr, target);
+		    Tcl_IncrRefCount(target);
+		    continue;
+		}
+	    }
+
+	    /*
+	     * Not there, so map onto the namespace. Note in this case that we
+	     * do not guarantee that the command is actually there; that is
+	     * the programmer's responsibility (or [::unknown] of course).
+	     */
+
+	    cmdObj = NewNsObj((Tcl_Namespace *) ensemblePtr->nsPtr);
+	    if (ensemblePtr->nsPtr->parentPtr != NULL) {
+		Tcl_AppendStringsToObj(cmdObj, "::", name, NULL);
+	    } else {
+		Tcl_AppendStringsToObj(cmdObj, name, NULL);
+	    }
+	    cmdPrefixObj = Tcl_NewListObj(1, &cmdObj);
+	    Tcl_SetHashValue(hPtr, cmdPrefixObj);
+	    Tcl_IncrRefCount(cmdPrefixObj);
+	}
+    } else if (ensemblePtr->subcommandDict != NULL) {
+	/*
+	 * No subcmd list, but we do have a mapping dictionary so we should
+	 * use the keys of that. Convert the dictionary's contents into the
+	 * form required for the ensemble's internal hashtable.
+	 */
+
+	Tcl_DictSearch dictSearch;
+	Tcl_Obj *keyObj, *valueObj;
+	int done;
+
+	Tcl_DictObjFirst(NULL, ensemblePtr->subcommandDict, &dictSearch,
+		&keyObj, &valueObj, &done);
+	while (!done) {
+	    const char *name = TclGetString(keyObj);
+
+	    hPtr = Tcl_CreateHashEntry(hash, name, &isNew);
+	    Tcl_SetHashValue(hPtr, valueObj);
+	    Tcl_IncrRefCount(valueObj);
+	    Tcl_DictObjNext(&dictSearch, &keyObj, &valueObj, &done);
+	}
+    } else {
+	/*
+	 * Discover what commands are actually exported by the namespace.
+	 * What we have is an array of patterns and a hash table whose keys
+	 * are the command names exported by the namespace (the contents do
+	 * not matter here.) We must find out what commands are actually
+	 * exported by filtering each command in the namespace against each of
+	 * the patterns in the export list. Note that we use an intermediate
+	 * hash table to make memory management easier, and because that makes
+	 * exact matching far easier too.
+	 *
+	 * Suggestion for future enhancement: compute the unique prefixes and
+	 * place them in the hash too, which should make for even faster
+	 * matching.
+	 */
+
+	hPtr = Tcl_FirstHashEntry(&ensemblePtr->nsPtr->cmdTable, &search);
+	for (; hPtr!= NULL ; hPtr=Tcl_NextHashEntry(&search)) {
+	    char *nsCmdName =		/* Name of command in namespace. */
+		    Tcl_GetHashKey(&ensemblePtr->nsPtr->cmdTable, hPtr);
+
+	    for (i=0 ; i<ensemblePtr->nsPtr->numExportPatterns ; i++) {
+		if (Tcl_StringMatch(nsCmdName,
+			ensemblePtr->nsPtr->exportArrayPtr[i])) {
+		    hPtr = Tcl_CreateHashEntry(hash, nsCmdName, &isNew);
+
+		    /*
+		     * Remember, hash entries have a full reference to the
+		     * substituted part of the command (as a list) as their
+		     * content!
+		     */
+
+		    if (isNew) {
+			Tcl_Obj *cmdObj, *cmdPrefixObj;
+
+			TclNewObj(cmdObj);
+			Tcl_AppendStringsToObj(cmdObj,
+				ensemblePtr->nsPtr->fullName,
+				(ensemblePtr->nsPtr->parentPtr ? "::" : ""),
+				nsCmdName, NULL);
+			cmdPrefixObj = Tcl_NewListObj(1, &cmdObj);
+			Tcl_SetHashValue(hPtr, cmdPrefixObj);
+			Tcl_IncrRefCount(cmdPrefixObj);
+		    }
+		    break;
+		}
+	    }
+	}
+    }
+
+    if (hash->numEntries == 0) {
+	ensemblePtr->subcommandArrayPtr = NULL;
+	return;
+    }
+
+    /*
+     * Create a sorted array of all subcommands in the ensemble; hash tables
+     * are all very well for a quick look for an exact match, but they can't
+     * determine things like whether a string is a prefix of another (not
+     * without lots of preparation anyway) and they're no good for when we're
+     * generating the error message either.
+     *
+     * We do this by filling an array with the names (we use the hash keys
+     * directly to save a copy, since any time we change the array we change
+     * the hash too, and vice versa) and running quicksort over the array.
+     */
+
+    ensemblePtr->subcommandArrayPtr =
+	    ckalloc(sizeof(char *) * hash->numEntries);
+
+    /*
+     * Fill array from both ends as this makes us less likely to end up with
+     * performance problems in qsort(), which is good. Note that doing this
+     * makes this code much more opaque, but the naive alternatve:
+     *
+     * for (hPtr=Tcl_FirstHashEntry(hash,&search),i=0 ;
+     *	       hPtr!=NULL ; hPtr=Tcl_NextHashEntry(&search),i++) {
+     *     ensemblePtr->subcommandArrayPtr[i] = Tcl_GetHashKey(hash, &hPtr);
+     * }
+     *
+     * can produce long runs of precisely ordered table entries when the
+     * commands in the namespace are declared in a sorted fashion (an ordering
+     * some people like) and the hashing functions (or the command names
+     * themselves) are fairly unfortunate. By filling from both ends, it
+     * requires active malice (and probably a debugger) to get qsort() to have
+     * awful runtime behaviour.
+     */
+
+    i = 0;
+    j = hash->numEntries;
+    hPtr = Tcl_FirstHashEntry(hash, &search);
+    while (hPtr != NULL) {
+	ensemblePtr->subcommandArrayPtr[i++] = Tcl_GetHashKey(hash, hPtr);
+	hPtr = Tcl_NextHashEntry(&search);
+	if (hPtr == NULL) {
+	    break;
+	}
+	ensemblePtr->subcommandArrayPtr[--j] = Tcl_GetHashKey(hash, hPtr);
+	hPtr = Tcl_NextHashEntry(&search);
+    }
+    if (hash->numEntries > 1) {
+	qsort(ensemblePtr->subcommandArrayPtr, (unsigned) hash->numEntries,
+		sizeof(char *), NsEnsembleStringOrder);
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * NsEnsembleStringOrder --
+ *
+ *	Helper function to compare two pointers to two strings for use with
+ *	qsort().
+ *
+ * Results:
+ *	-1 if the first string is smaller, 1 if the second string is smaller,
+ *	and 0 if they are equal.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+NsEnsembleStringOrder(
+    const void *strPtr1,
+    const void *strPtr2)
+{
+    return strcmp(*(const char **)strPtr1, *(const char **)strPtr2);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * FreeEnsembleCmdRep --
+ *
+ *	Destroys the internal representation of a Tcl_Obj that has been
+ *	holding information about a command in an ensemble.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Memory is deallocated. If this held the last reference to a
+ *	namespace's main structure, that main structure will also be
+ *	destroyed.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+FreeEnsembleCmdRep(
+    Tcl_Obj *objPtr)
+{
+    EnsembleCmdRep *ensembleCmd = objPtr->internalRep.twoPtrValue.ptr1;
+
+    TclCleanupCommandMacro(ensembleCmd->token);
+    if (ensembleCmd->fix) {
+	Tcl_DecrRefCount(ensembleCmd->fix);
+    }
+    ckfree(ensembleCmd);
+    objPtr->typePtr = NULL;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * DupEnsembleCmdRep --
+ *
+ *	Makes one Tcl_Obj into a copy of another that is a subcommand of an
+ *	ensemble.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Memory is allocated, and the namespace that the ensemble is built on
+ *	top of gains another reference.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+DupEnsembleCmdRep(
+    Tcl_Obj *objPtr,
+    Tcl_Obj *copyPtr)
+{
+    EnsembleCmdRep *ensembleCmd = objPtr->internalRep.twoPtrValue.ptr1;
+    EnsembleCmdRep *ensembleCopy = ckalloc(sizeof(EnsembleCmdRep));
+
+    copyPtr->typePtr = &ensembleCmdType;
+    copyPtr->internalRep.twoPtrValue.ptr1 = ensembleCopy;
+    ensembleCopy->epoch = ensembleCmd->epoch;
+    ensembleCopy->token = ensembleCmd->token;
+    ensembleCopy->token->refCount++;
+    ensembleCopy->fix = ensembleCmd->fix;
+    if (ensembleCopy->fix) {
+	Tcl_IncrRefCount(ensembleCopy->fix);
+    }
+    ensembleCopy->hPtr = ensembleCmd->hPtr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclCompileEnsemble --
+ *
+ *	Procedure called to compile an ensemble command. Note that most
+ *	ensembles are not compiled, since modifying a compiled ensemble causes
+ *	a invalidation of all existing bytecode (expensive!) which is not
+ *	normally warranted.
+ *
+ * Results:
+ *	Returns TCL_OK for a successful compile. Returns TCL_ERROR to defer
+ *	evaluation to runtime.
+ *
+ * Side effects:
+ *	Instructions are added to envPtr to execute the subcommands of the
+ *	ensemble at runtime if a compile-time mapping is possible.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclCompileEnsemble(
+    Tcl_Interp *interp,		/* Used for error reporting. */
+    Tcl_Parse *parsePtr,	/* Points to a parse structure for the command
+				 * created by Tcl_ParseCommand. */
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)		/* Holds resulting instructions. */
+{
+    Tcl_Token *tokenPtr = TokenAfter(parsePtr->tokenPtr);
+    Tcl_Obj *mapObj, *subcmdObj, *targetCmdObj, *listObj, **elems;
+    Tcl_Obj *replaced = Tcl_NewObj(), *replacement;
+    Tcl_Command ensemble = (Tcl_Command) cmdPtr;
+    Command *oldCmdPtr = cmdPtr, *newCmdPtr;
+    int len, result, flags = 0, i, depth = 1, invokeAnyway = 0;
+    int ourResult = TCL_ERROR;
+    unsigned numBytes;
+    const char *word;
+    DefineLineInformation;
+
+    Tcl_IncrRefCount(replaced);
+    if (parsePtr->numWords < depth + 1) {
+	goto failed;
+    }
+    if (tokenPtr->type != TCL_TOKEN_SIMPLE_WORD) {
+	/*
+	 * Too hard.
+	 */
+
+	goto failed;
+    }
+
+    /*
+     * This is where we return to if we are parsing multiple nested compiled
+     * ensembles. [info object] is such a beast.
+     */
+
+  checkNextWord:
+    word = tokenPtr[1].start;
+    numBytes = tokenPtr[1].size;
+
+    /*
+     * There's a sporting chance we'll be able to compile this. But now we
+     * must check properly. To do that, check that we're compiling an ensemble
+     * that has a compilable command as its appropriate subcommand.
+     */
+
+    if (Tcl_GetEnsembleMappingDict(NULL, ensemble, &mapObj) != TCL_OK
+	    || mapObj == NULL) {
+	/*
+	 * Either not an ensemble or a mapping isn't installed. Crud. Too hard
+	 * to proceed.
+	 */
+
+	goto failed;
+    }
+
+    /*
+     * Also refuse to compile anything that uses a formal parameter list for
+     * now, on the grounds that it is too complex.
+     */
+
+    if (Tcl_GetEnsembleParameterList(NULL, ensemble, &listObj) != TCL_OK
+	    || listObj != NULL) {
+	/*
+	 * Figuring out how to compile this has become too much. Bail out.
+	 */
+
+	goto failed;
+    }
+
+    /*
+     * Next, get the flags. We need them on several code paths so that we can
+     * know whether we're to do prefix matching.
+     */
+
+    (void) Tcl_GetEnsembleFlags(NULL, ensemble, &flags);
+
+    /*
+     * Check to see if there's also a subcommand list; must check to see if
+     * the subcommand we are calling is in that list if it exists, since that
+     * list filters the entries in the map.
+     */
+
+    (void) Tcl_GetEnsembleSubcommandList(NULL, ensemble, &listObj);
+    if (listObj != NULL) {
+	int sclen;
+	const char *str;
+	Tcl_Obj *matchObj = NULL;
+
+	if (Tcl_ListObjGetElements(NULL, listObj, &len, &elems) != TCL_OK) {
+	    goto failed;
+	}
+	for (i=0 ; i<len ; i++) {
+	    str = Tcl_GetStringFromObj(elems[i], &sclen);
+	    if ((sclen == (int) numBytes) && !memcmp(word, str, numBytes)) {
+		/*
+		 * Exact match! Excellent!
+		 */
+
+		result = Tcl_DictObjGet(NULL, mapObj,elems[i], &targetCmdObj);
+		if (result != TCL_OK || targetCmdObj == NULL) {
+		    goto failed;
+		}
+		replacement = elems[i];
+		goto doneMapLookup;
+	    }
+
+	    /*
+	     * Check to see if we've got a prefix match. A single prefix match
+	     * is fine, and allows us to refine our dictionary lookup, but
+	     * multiple prefix matches is a Bad Thing and will prevent us from
+	     * making progress. Note that we cannot do the lookup immediately
+	     * in the prefix case; might be another entry later in the list
+	     * that causes things to fail.
+	     */
+
+	    if ((flags & TCL_ENSEMBLE_PREFIX)
+		    && strncmp(word, str, numBytes) == 0) {
+		if (matchObj != NULL) {
+		    goto failed;
+		}
+		matchObj = elems[i];
+	    }
+	}
+	if (matchObj == NULL) {
+	    goto failed;
+	}
+	result = Tcl_DictObjGet(NULL, mapObj, matchObj, &targetCmdObj);
+	if (result != TCL_OK || targetCmdObj == NULL) {
+	    goto failed;
+	}
+	replacement = matchObj;
+    } else {
+	Tcl_DictSearch s;
+	int done, matched;
+	Tcl_Obj *tmpObj;
+
+	/*
+	 * No map, so check the dictionary directly.
+	 */
+
+	TclNewStringObj(subcmdObj, word, (int) numBytes);
+	result = Tcl_DictObjGet(NULL, mapObj, subcmdObj, &targetCmdObj);
+	if (result == TCL_OK && targetCmdObj != NULL) {
+	    /*
+	     * Got it. Skip the fiddling around with prefixes.
+	     */
+
+	    replacement = subcmdObj;
+	    goto doneMapLookup;
+	}
+	TclDecrRefCount(subcmdObj);
+
+	/*
+	 * We've not literally got a valid subcommand. But maybe we have a
+	 * prefix. Check if prefix matches are allowed.
+	 */
+
+	if (!(flags & TCL_ENSEMBLE_PREFIX)) {
+	    goto failed;
+	}
+
+	/*
+	 * Iterate over the keys in the dictionary, checking to see if we're a
+	 * prefix.
+	 */
+
+	Tcl_DictObjFirst(NULL, mapObj, &s, &subcmdObj, &tmpObj, &done);
+	matched = 0;
+	replacement = NULL;		/* Silence, fool compiler! */
+	while (!done) {
+	    if (strncmp(TclGetString(subcmdObj), word, numBytes) == 0) {
+		if (matched++) {
+		    /*
+		     * Must have matched twice! Not unique, so no point
+		     * looking further.
+		     */
+
+		    break;
+		}
+		replacement = subcmdObj;
+		targetCmdObj = tmpObj;
+	    }
+	    Tcl_DictObjNext(&s, &subcmdObj, &tmpObj, &done);
+	}
+	Tcl_DictObjDone(&s);
+
+	/*
+	 * If we have anything other than a single match, we've failed the
+	 * unique prefix check.
+	 */
+
+	if (matched != 1) {
+	    invokeAnyway = 1;
+	    goto failed;
+	}
+    }
+
+    /*
+     * OK, we definitely map to something. But what?
+     *
+     * The command we map to is the first word out of the map element. Note
+     * that we also reject dealing with multi-element rewrites if we are in a
+     * safe interpreter, as there is otherwise a (highly gnarly!) way to make
+     * Tcl crash open to exploit.
+     */
+
+  doneMapLookup:
+    Tcl_ListObjAppendElement(NULL, replaced, replacement);
+    if (Tcl_ListObjGetElements(NULL, targetCmdObj, &len, &elems) != TCL_OK) {
+	goto failed;
+    } else if (len != 1) {
+	/*
+	 * Note that at this point we know we can't issue any special
+	 * instruction sequence as the mapping isn't one that we support at
+	 * the compiled level.
+	 */
+
+	goto cleanup;
+    }
+    targetCmdObj = elems[0];
+
+    oldCmdPtr = cmdPtr;
+    Tcl_IncrRefCount(targetCmdObj);
+    newCmdPtr = (Command *) Tcl_GetCommandFromObj(interp, targetCmdObj);
+    TclDecrRefCount(targetCmdObj);
+    if (newCmdPtr == NULL || Tcl_IsSafe(interp)
+	    || newCmdPtr->nsPtr->flags & NS_SUPPRESS_COMPILATION
+	    || newCmdPtr->flags & CMD_HAS_EXEC_TRACES
+	    || ((Interp *)interp)->flags & DONT_COMPILE_CMDS_INLINE) {
+	/*
+	 * Maps to an undefined command or a command without a compiler.
+	 * Cannot compile.
+	 */
+
+	goto cleanup;
+    }
+    cmdPtr = newCmdPtr;
+    depth++;
+
+    /*
+     * See whether we have a nested ensemble. If we do, we can go round the
+     * mulberry bush again, consuming the next word.
+     */
+
+    if (cmdPtr->compileProc == TclCompileEnsemble) {
+	tokenPtr = TokenAfter(tokenPtr);
+	if (parsePtr->numWords < depth + 1
+		|| tokenPtr->type != TCL_TOKEN_SIMPLE_WORD) {
+	    /*
+	     * Too hard because the user has done something unpleasant like
+	     * omitting the sub-ensemble's command name or used a non-constant
+	     * name for a sub-ensemble's command name; we respond by bailing
+	     * out completely (this is a rare case). [Bug 6d2f249a01]
+	     */
+
+	    goto cleanup;
+	}
+	ensemble = (Tcl_Command) cmdPtr;
+	goto checkNextWord;
+    }
+
+    /*
+     * Now we've done the mapping process, can now actually try to compile.
+     * If there is a subcommand compiler and that successfully produces code,
+     * we'll use that. Otherwise, we fall back to generating opcodes to do the
+     * invoke at runtime.
+     */
+
+    invokeAnyway = 1;
+    if (TCL_OK == TclAttemptCompileProc(interp, parsePtr, depth, cmdPtr,
+	    envPtr)) {
+	ourResult = TCL_OK;
+	goto cleanup;
+    }
+
+    /*
+     * Throw out any line information generated by the failed compile attempt.
+     */
+
+    while (mapPtr->nuloc - 1 > eclIndex) {
+        mapPtr->nuloc--;
+        ckfree(mapPtr->loc[mapPtr->nuloc].line);
+        mapPtr->loc[mapPtr->nuloc].line = NULL;
+    }
+
+    /*
+     * Reset the index of next command.  Toss out any from failed nested
+     * partial compiles.
+     */
+
+    envPtr->numCommands = mapPtr->nuloc;
+
+    /*
+     * Failed to do a full compile for some reason. Try to do a direct invoke
+     * instead of going through the ensemble lookup process again.
+     */
+
+  failed:
+    if (depth < 250) {
+	if (depth > 1) {
+	    if (!invokeAnyway) {
+		cmdPtr = oldCmdPtr;
+		depth--;
+	    }
+	}
+	/*
+	 * The length of the "replaced" list must be depth-1.  Trim back
+	 * any extra elements that might have been appended by failing
+	 * pathways above.
+	 */
+	(void) Tcl_ListObjReplace(NULL, replaced, depth-1, INT_MAX, 0, NULL);
+
+	/*
+	 * TODO: Reconsider whether we ought to call CompileToInvokedCommand()
+	 * when depth==1.  In that case we are choosing to emit the
+	 * INST_INVOKE_REPLACE bytecode when there is in fact no replacing
+	 * to be done.  It would be equally functional and presumably more
+	 * performant to fall through to cleanup below, return TCL_ERROR,
+	 * and let the compiler harness emit the INST_INVOKE_STK
+	 * implementation for us.
+	 */
+
+	CompileToInvokedCommand(interp, parsePtr, replaced, cmdPtr, envPtr);
+	ourResult = TCL_OK;
+    }
+
+    /*
+     * Release the memory we allocated. If we've got here, we've either done
+     * something useful or we're in a case that we can't compile at all and
+     * we're just giving up.
+     */
+
+  cleanup:
+    Tcl_DecrRefCount(replaced);
+    return ourResult;
+}
+
+int
+TclAttemptCompileProc(
+    Tcl_Interp *interp,
+    Tcl_Parse *parsePtr,
+    int depth,
+    Command *cmdPtr,
+    CompileEnv *envPtr)		/* Holds resulting instructions. */
+{
+    int result, i;
+    Tcl_Token *saveTokenPtr = parsePtr->tokenPtr;
+    int savedStackDepth = envPtr->currStackDepth;
+    unsigned savedCodeNext = envPtr->codeNext - envPtr->codeStart;
+    int savedAuxDataArrayNext = envPtr->auxDataArrayNext;
+    int savedExceptArrayNext = envPtr->exceptArrayNext;
+#ifdef TCL_COMPILE_DEBUG
+    int savedExceptDepth = envPtr->exceptDepth;
+#endif
+    DefineLineInformation;
+
+    if (cmdPtr->compileProc == NULL) {
+	return TCL_ERROR;
+    }
+
+    /*
+     * Advance parsePtr->tokenPtr so that it points at the last subcommand.
+     * This will be wrong, but it will not matter, and it will put the
+     * tokens for the arguments in the right place without the needed to
+     * allocate a synthetic Tcl_Parse struct, or copy tokens around.
+     */
+
+    for (i = 0; i < depth - 1; i++) {
+	parsePtr->tokenPtr = TokenAfter(parsePtr->tokenPtr);
+    }
+    parsePtr->numWords -= (depth - 1);
+
+    /*
+     * Shift the line information arrays to account for different word
+     * index values.
+     */
+
+    mapPtr->loc[eclIndex].line += (depth - 1);
+    mapPtr->loc[eclIndex].next += (depth - 1);
+
+    /*
+     * Hand off compilation to the subcommand compiler. At last!
+     */
+
+    result = cmdPtr->compileProc(interp, parsePtr, cmdPtr, envPtr);
+
+    /*
+     * Undo the shift.
+     */
+
+    mapPtr->loc[eclIndex].line -= (depth - 1);
+    mapPtr->loc[eclIndex].next -= (depth - 1);
+
+    parsePtr->numWords += (depth - 1);
+    parsePtr->tokenPtr = saveTokenPtr;
+
+    /*
+     * If our target failed to compile, revert any data from failed partial
+     * compiles.  Note that envPtr->numCommands need not be checked because
+     * we avoid compiling subcommands that recursively call TclCompileScript().
+     */
+
+#ifdef TCL_COMPILE_DEBUG
+    if (envPtr->exceptDepth != savedExceptDepth) {
+	Tcl_Panic("ExceptionRange Starts and Ends do not balance");
+    }
+#endif
+
+    if (result != TCL_OK) {
+	ExceptionAux *auxPtr = envPtr->exceptAuxArrayPtr;
+
+	for (i = 0; i < savedExceptArrayNext; i++) {
+	    while (auxPtr->numBreakTargets > 0
+		    && auxPtr->breakTargets[auxPtr->numBreakTargets - 1]
+		    >= savedCodeNext) {
+		auxPtr->numBreakTargets--;
+	    }
+	    while (auxPtr->numContinueTargets > 0
+		    && auxPtr->continueTargets[auxPtr->numContinueTargets - 1]
+		    >= savedCodeNext) {
+		auxPtr->numContinueTargets--;
+	    }
+	    auxPtr++;
+	}
+	envPtr->exceptArrayNext = savedExceptArrayNext;
+
+	if (savedAuxDataArrayNext != envPtr->auxDataArrayNext) {
+	    AuxData *auxDataPtr = envPtr->auxDataArrayPtr;
+	    AuxData *auxDataEnd = auxDataPtr;
+
+	    auxDataPtr += savedAuxDataArrayNext;
+	    auxDataEnd += envPtr->auxDataArrayNext;
+
+	    while (auxDataPtr < auxDataEnd) {
+		if (auxDataPtr->type->freeProc != NULL) {
+		    auxDataPtr->type->freeProc(auxDataPtr->clientData);
+		}
+		auxDataPtr++;
+	    }
+	    envPtr->auxDataArrayNext = savedAuxDataArrayNext;
+	}
+	envPtr->currStackDepth = savedStackDepth;
+	envPtr->codeNext = envPtr->codeStart + savedCodeNext;
+#ifdef TCL_COMPILE_DEBUG
+    } else {
+	/*
+	 * Confirm that the command compiler generated a single value on
+	 * the stack as its result. This is only done in debugging mode,
+	 * as it *should* be correct and normal users have no reasonable
+	 * way to fix it anyway.
+	 */
+
+	int diff = envPtr->currStackDepth - savedStackDepth;
+
+	if (diff != 1) {
+	    Tcl_Panic("bad stack adjustment when compiling"
+		    " %.*s (was %d instead of 1)", parsePtr->tokenPtr->size,
+		    parsePtr->tokenPtr->start, diff);
+	}
+#endif
+    }
+
+    return result;
+}
+
+/*
+ * How to compile a subcommand to a _replacing_ invoke of its implementation
+ * command.
+ */
+
+static void
+CompileToInvokedCommand(
+    Tcl_Interp *interp,
+    Tcl_Parse *parsePtr,
+    Tcl_Obj *replacements,
+    Command *cmdPtr,
+    CompileEnv *envPtr)		/* Holds resulting instructions. */
+{
+    Tcl_Token *tokPtr;
+    Tcl_Obj *objPtr, **words;
+    char *bytes;
+    int length, i, numWords, cmdLit;
+    DefineLineInformation;
+
+    /*
+     * Push the words of the command. Take care; the command words may be
+     * scripts that have backslashes in them, and [info frame 0] can see the
+     * difference. Hence the call to TclContinuationsEnterDerived...
+     */
+
+    Tcl_ListObjGetElements(NULL, replacements, &numWords, &words);
+    for (i = 0, tokPtr = parsePtr->tokenPtr; i < parsePtr->numWords;
+	    i++, tokPtr = TokenAfter(tokPtr)) {
+	if (i > 0 && i < numWords+1) {
+	    bytes = Tcl_GetStringFromObj(words[i-1], &length);
+	    PushLiteral(envPtr, bytes, length);
+	    continue;
+	}
+
+	SetLineInformation(i);
+	if (tokPtr->type == TCL_TOKEN_SIMPLE_WORD) {
+	    int literal = TclRegisterNewLiteral(envPtr,
+		    tokPtr[1].start, tokPtr[1].size);
+
+	    if (envPtr->clNext) {
+		TclContinuationsEnterDerived(
+			TclFetchLiteral(envPtr, literal),
+			tokPtr[1].start - envPtr->source,
+			envPtr->clNext);
+	    }
+	    TclEmitPush(literal, envPtr);
+	} else {
+	    CompileTokens(envPtr, tokPtr, interp);
+	}
+    }
+
+    /*
+     * Push the name of the command we're actually dispatching to as part of
+     * the implementation.
+     */
+
+    objPtr = Tcl_NewObj();
+    Tcl_GetCommandFullName(interp, (Tcl_Command) cmdPtr, objPtr);
+    bytes = Tcl_GetStringFromObj(objPtr, &length);
+    cmdLit = TclRegisterNewCmdLiteral(envPtr, bytes, length);
+    TclSetCmdNameObj(interp, TclFetchLiteral(envPtr, cmdLit), cmdPtr);
+    TclEmitPush(cmdLit, envPtr);
+    TclDecrRefCount(objPtr);
+
+    /*
+     * Do the replacing dispatch.
+     */
+
+    TclEmitInvoke(envPtr, INST_INVOKE_REPLACE, parsePtr->numWords,numWords+1);
+}
+
+/*
+ * Helpers that do issuing of instructions for commands that "don't have
+ * compilers" (well, they do; these). They all work by just generating base
+ * code to invoke the command; they're intended for ensemble subcommands so
+ * that the costs of INST_INVOKE_REPLACE can be avoided where we can work out
+ * that they're not needed.
+ *
+ * Note that these are NOT suitable for commands where there's an argument
+ * that is a script, as an [info level] or [info frame] in the inner context
+ * can see the difference.
+ */
+
+static int
+CompileBasicNArgCommand(
+    Tcl_Interp *interp,		/* Used for error reporting. */
+    Tcl_Parse *parsePtr,	/* Points to a parse structure for the command
+				 * created by Tcl_ParseCommand. */
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)		/* Holds resulting instructions. */
+{
+    Tcl_Obj *objPtr = Tcl_NewObj();
+
+    Tcl_IncrRefCount(objPtr);
+    Tcl_GetCommandFullName(interp, (Tcl_Command) cmdPtr, objPtr);
+    TclCompileInvocation(interp, parsePtr->tokenPtr, objPtr,
+	    parsePtr->numWords, envPtr);
+    Tcl_DecrRefCount(objPtr);
+    return TCL_OK;
+}
+
+int
+TclCompileBasic0ArgCmd(
+    Tcl_Interp *interp,		/* Used for error reporting. */
+    Tcl_Parse *parsePtr,	/* Points to a parse structure for the command
+				 * created by Tcl_ParseCommand. */
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)		/* Holds resulting instructions. */
+{
+    /*
+     * Verify that the number of arguments is correct; that's the only case
+     * that we know will avoid the call to Tcl_WrongNumArgs() at invoke time,
+     * which is the only code that sees the shenanigans of ensemble dispatch.
+     */
+
+    if (parsePtr->numWords != 1) {
+	return TCL_ERROR;
+    }
+
+    return CompileBasicNArgCommand(interp, parsePtr, cmdPtr, envPtr);
+}
+
+int
+TclCompileBasic1ArgCmd(
+    Tcl_Interp *interp,		/* Used for error reporting. */
+    Tcl_Parse *parsePtr,	/* Points to a parse structure for the command
+				 * created by Tcl_ParseCommand. */
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)		/* Holds resulting instructions. */
+{
+    /*
+     * Verify that the number of arguments is correct; that's the only case
+     * that we know will avoid the call to Tcl_WrongNumArgs() at invoke time,
+     * which is the only code that sees the shenanigans of ensemble dispatch.
+     */
+
+    if (parsePtr->numWords != 2) {
+	return TCL_ERROR;
+    }
+
+    return CompileBasicNArgCommand(interp, parsePtr, cmdPtr, envPtr);
+}
+
+int
+TclCompileBasic2ArgCmd(
+    Tcl_Interp *interp,		/* Used for error reporting. */
+    Tcl_Parse *parsePtr,	/* Points to a parse structure for the command
+				 * created by Tcl_ParseCommand. */
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)		/* Holds resulting instructions. */
+{
+    /*
+     * Verify that the number of arguments is correct; that's the only case
+     * that we know will avoid the call to Tcl_WrongNumArgs() at invoke time,
+     * which is the only code that sees the shenanigans of ensemble dispatch.
+     */
+
+    if (parsePtr->numWords != 3) {
+	return TCL_ERROR;
+    }
+
+    return CompileBasicNArgCommand(interp, parsePtr, cmdPtr, envPtr);
+}
+
+int
+TclCompileBasic3ArgCmd(
+    Tcl_Interp *interp,		/* Used for error reporting. */
+    Tcl_Parse *parsePtr,	/* Points to a parse structure for the command
+				 * created by Tcl_ParseCommand. */
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)		/* Holds resulting instructions. */
+{
+    /*
+     * Verify that the number of arguments is correct; that's the only case
+     * that we know will avoid the call to Tcl_WrongNumArgs() at invoke time,
+     * which is the only code that sees the shenanigans of ensemble dispatch.
+     */
+
+    if (parsePtr->numWords != 4) {
+	return TCL_ERROR;
+    }
+
+    return CompileBasicNArgCommand(interp, parsePtr, cmdPtr, envPtr);
+}
+
+int
+TclCompileBasic0Or1ArgCmd(
+    Tcl_Interp *interp,		/* Used for error reporting. */
+    Tcl_Parse *parsePtr,	/* Points to a parse structure for the command
+				 * created by Tcl_ParseCommand. */
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)		/* Holds resulting instructions. */
+{
+    /*
+     * Verify that the number of arguments is correct; that's the only case
+     * that we know will avoid the call to Tcl_WrongNumArgs() at invoke time,
+     * which is the only code that sees the shenanigans of ensemble dispatch.
+     */
+
+    if (parsePtr->numWords != 1 && parsePtr->numWords != 2) {
+	return TCL_ERROR;
+    }
+
+    return CompileBasicNArgCommand(interp, parsePtr, cmdPtr, envPtr);
+}
+
+int
+TclCompileBasic1Or2ArgCmd(
+    Tcl_Interp *interp,		/* Used for error reporting. */
+    Tcl_Parse *parsePtr,	/* Points to a parse structure for the command
+				 * created by Tcl_ParseCommand. */
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)		/* Holds resulting instructions. */
+{
+    /*
+     * Verify that the number of arguments is correct; that's the only case
+     * that we know will avoid the call to Tcl_WrongNumArgs() at invoke time,
+     * which is the only code that sees the shenanigans of ensemble dispatch.
+     */
+
+    if (parsePtr->numWords != 2 && parsePtr->numWords != 3) {
+	return TCL_ERROR;
+    }
+
+    return CompileBasicNArgCommand(interp, parsePtr, cmdPtr, envPtr);
+}
+
+int
+TclCompileBasic2Or3ArgCmd(
+    Tcl_Interp *interp,		/* Used for error reporting. */
+    Tcl_Parse *parsePtr,	/* Points to a parse structure for the command
+				 * created by Tcl_ParseCommand. */
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)		/* Holds resulting instructions. */
+{
+    /*
+     * Verify that the number of arguments is correct; that's the only case
+     * that we know will avoid the call to Tcl_WrongNumArgs() at invoke time,
+     * which is the only code that sees the shenanigans of ensemble dispatch.
+     */
+
+    if (parsePtr->numWords != 3 && parsePtr->numWords != 4) {
+	return TCL_ERROR;
+    }
+
+    return CompileBasicNArgCommand(interp, parsePtr, cmdPtr, envPtr);
+}
+
+int
+TclCompileBasic0To2ArgCmd(
+    Tcl_Interp *interp,		/* Used for error reporting. */
+    Tcl_Parse *parsePtr,	/* Points to a parse structure for the command
+				 * created by Tcl_ParseCommand. */
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)		/* Holds resulting instructions. */
+{
+    /*
+     * Verify that the number of arguments is correct; that's the only case
+     * that we know will avoid the call to Tcl_WrongNumArgs() at invoke time,
+     * which is the only code that sees the shenanigans of ensemble dispatch.
+     */
+
+    if (parsePtr->numWords < 1 || parsePtr->numWords > 3) {
+	return TCL_ERROR;
+    }
+
+    return CompileBasicNArgCommand(interp, parsePtr, cmdPtr, envPtr);
+}
+
+int
+TclCompileBasic1To3ArgCmd(
+    Tcl_Interp *interp,		/* Used for error reporting. */
+    Tcl_Parse *parsePtr,	/* Points to a parse structure for the command
+				 * created by Tcl_ParseCommand. */
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)		/* Holds resulting instructions. */
+{
+    /*
+     * Verify that the number of arguments is correct; that's the only case
+     * that we know will avoid the call to Tcl_WrongNumArgs() at invoke time,
+     * which is the only code that sees the shenanigans of ensemble dispatch.
+     */
+
+    if (parsePtr->numWords < 2 || parsePtr->numWords > 4) {
+	return TCL_ERROR;
+    }
+
+    return CompileBasicNArgCommand(interp, parsePtr, cmdPtr, envPtr);
+}
+
+int
+TclCompileBasicMin0ArgCmd(
+    Tcl_Interp *interp,		/* Used for error reporting. */
+    Tcl_Parse *parsePtr,	/* Points to a parse structure for the command
+				 * created by Tcl_ParseCommand. */
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)		/* Holds resulting instructions. */
+{
+    /*
+     * Verify that the number of arguments is correct; that's the only case
+     * that we know will avoid the call to Tcl_WrongNumArgs() at invoke time,
+     * which is the only code that sees the shenanigans of ensemble dispatch.
+     */
+
+    if (parsePtr->numWords < 1) {
+	return TCL_ERROR;
+    }
+
+    return CompileBasicNArgCommand(interp, parsePtr, cmdPtr, envPtr);
+}
+
+int
+TclCompileBasicMin1ArgCmd(
+    Tcl_Interp *interp,		/* Used for error reporting. */
+    Tcl_Parse *parsePtr,	/* Points to a parse structure for the command
+				 * created by Tcl_ParseCommand. */
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)		/* Holds resulting instructions. */
+{
+    /*
+     * Verify that the number of arguments is correct; that's the only case
+     * that we know will avoid the call to Tcl_WrongNumArgs() at invoke time,
+     * which is the only code that sees the shenanigans of ensemble dispatch.
+     */
+
+    if (parsePtr->numWords < 2) {
+	return TCL_ERROR;
+    }
+
+    return CompileBasicNArgCommand(interp, parsePtr, cmdPtr, envPtr);
+}
+
+int
+TclCompileBasicMin2ArgCmd(
+    Tcl_Interp *interp,		/* Used for error reporting. */
+    Tcl_Parse *parsePtr,	/* Points to a parse structure for the command
+				 * created by Tcl_ParseCommand. */
+    Command *cmdPtr,		/* Points to defintion of command being
+				 * compiled. */
+    CompileEnv *envPtr)		/* Holds resulting instructions. */
+{
+    /*
+     * Verify that the number of arguments is correct; that's the only case
+     * that we know will avoid the call to Tcl_WrongNumArgs() at invoke time,
+     * which is the only code that sees the shenanigans of ensemble dispatch.
+     */
+
+    if (parsePtr->numWords < 3) {
+	return TCL_ERROR;
+    }
+
+    return CompileBasicNArgCommand(interp, parsePtr, cmdPtr, envPtr);
+}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tclEnv.c b/generic/tclEnv.c
new file mode 100644
index 0000000..66ddb57
--- /dev/null
+++ b/generic/tclEnv.c
@@ -0,0 +1,744 @@
+/*
+ * tclEnv.c --
+ *
+ *	Tcl support for environment variables, including a setenv function.
+ *	This file contains the generic portion of the environment module. It
+ *	is primarily responsible for keeping the "env" arrays in sync with the
+ *	system environment variables.
+ *
+ * Copyright (c) 1991-1994 The Regents of the University of California.
+ * Copyright (c) 1994-1998 Sun Microsystems, Inc.
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#include "tclInt.h"
+
+TCL_DECLARE_MUTEX(envMutex)	/* To serialize access to environ. */
+
+static struct {
+    int cacheSize;		/* Number of env strings in cache. */
+    char **cache;		/* Array containing all of the environment
+				 * strings that Tcl has allocated. */
+#ifndef USE_PUTENV
+    char **ourEnviron;		/* Cache of the array that we allocate. We
+				 * need to track this in case another
+				 * subsystem swaps around the environ array
+				 * like we do. */
+    int ourEnvironSize;		/* Non-zero means that the environ array was
+				 * malloced and has this many total entries
+				 * allocated to it (not all may be in use at
+				 * once). Zero means that the environment
+				 * array is in its original static state. */
+#endif
+} env;
+
+/*
+ * Declarations for local functions defined in this file:
+ */
+
+static char *		EnvTraceProc(ClientData clientData, Tcl_Interp *interp,
+			    const char *name1, const char *name2, int flags);
+static void		ReplaceString(const char *oldStr, char *newStr);
+MODULE_SCOPE void	TclSetEnv(const char *name, const char *value);
+MODULE_SCOPE void	TclUnsetEnv(const char *name);
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclSetupEnv --
+ *
+ *	This function is invoked for an interpreter to make environment
+ *	variables accessible from that interpreter via the "env" associative
+ *	array.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The interpreter is added to a list of interpreters managed by us, so
+ *	that its view of envariables can be kept consistent with the view in
+ *	other interpreters. If this is the first call to TclSetupEnv, then
+ *	additional initialization happens, such as copying the environment to
+ *	dynamically-allocated space for ease of management.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclSetupEnv(
+    Tcl_Interp *interp)		/* Interpreter whose "env" array is to be
+				 * managed. */
+{
+    Var *varPtr, *arrayPtr;
+    Tcl_Obj *varNamePtr;
+    Tcl_DString envString;
+    Tcl_HashTable namesHash;
+    Tcl_HashEntry *hPtr;
+    Tcl_HashSearch search;
+
+    /*
+     * Synchronize the values in the environ array with the contents of the
+     * Tcl "env" variable. To do this:
+     *    1) Remove the trace that fires when the "env" var is updated.
+     *    2) Find the existing contents of the "env", storing in a hash table.
+     *    3) Create/update elements for each environ variable, removing
+     *	     elements from the hash table as we go.
+     *    4) Remove the elements for each remaining entry in the hash table,
+     *	     which must have existed before yet have no analog in the environ
+     *	     variable.
+     *    5) Add a trace that synchronizes the "env" array.
+     */
+
+    Tcl_UntraceVar2(interp, "env", NULL,
+	    TCL_GLOBAL_ONLY | TCL_TRACE_WRITES | TCL_TRACE_UNSETS |
+	    TCL_TRACE_READS | TCL_TRACE_ARRAY, EnvTraceProc, NULL);
+
+    /*
+     * Find out what elements are currently in the global env array.
+     */
+
+    TclNewLiteralStringObj(varNamePtr, "env");
+    Tcl_IncrRefCount(varNamePtr);
+    Tcl_InitObjHashTable(&namesHash);
+    varPtr = TclObjLookupVarEx(interp, varNamePtr, NULL, TCL_GLOBAL_ONLY,
+	    /*msg*/ 0, /*createPart1*/ 0, /*createPart2*/ 0, &arrayPtr);
+    TclFindArrayPtrElements(varPtr, &namesHash);
+
+    /*
+     * Go through the environment array and transfer its values into Tcl. At
+     * the same time, remove those elements we add/update from the hash table
+     * of existing elements, so that after this part processes, that table
+     * will hold just the parts to remove.
+     */
+
+    if (environ[0] != NULL) {
+	int i;
+
+	Tcl_MutexLock(&envMutex);
+	for (i = 0; environ[i] != NULL; i++) {
+	    Tcl_Obj *obj1, *obj2;
+	    char *p1, *p2;
+
+	    p1 = Tcl_ExternalToUtfDString(NULL, environ[i], -1, &envString);
+	    p2 = strchr(p1, '=');
+	    if (p2 == NULL) {
+		/*
+		 * This condition seem to happen occasionally under some
+		 * versions of Solaris, or when encoding accidents swallow the
+		 * '='; ignore the entry.
+		 */
+
+		continue;
+	    }
+	    p2++;
+	    p2[-1] = '\0';
+	    obj1 = Tcl_NewStringObj(p1, -1);
+	    obj2 = Tcl_NewStringObj(p2, -1);
+	    Tcl_DStringFree(&envString);
+
+	    Tcl_IncrRefCount(obj1);
+	    Tcl_IncrRefCount(obj2);
+	    Tcl_ObjSetVar2(interp, varNamePtr, obj1, obj2, TCL_GLOBAL_ONLY);
+	    hPtr = Tcl_FindHashEntry(&namesHash, obj1);
+	    if (hPtr != NULL) {
+		Tcl_DeleteHashEntry(hPtr);
+	    }
+	    Tcl_DecrRefCount(obj1);
+	    Tcl_DecrRefCount(obj2);
+	}
+	Tcl_MutexUnlock(&envMutex);
+    }
+
+    /*
+     * Delete those elements that existed in the array but which had no
+     * counterparts in the environment array.
+     */
+
+    for (hPtr=Tcl_FirstHashEntry(&namesHash, &search); hPtr!=NULL;
+	    hPtr=Tcl_NextHashEntry(&search)) {
+	Tcl_Obj *elemName = Tcl_GetHashValue(hPtr);
+
+	TclObjUnsetVar2(interp, varNamePtr, elemName, TCL_GLOBAL_ONLY);
+    }
+    Tcl_DeleteHashTable(&namesHash);
+    Tcl_DecrRefCount(varNamePtr);
+
+    /*
+     * Re-establish the trace.
+     */
+
+    Tcl_TraceVar2(interp, "env", NULL,
+	    TCL_GLOBAL_ONLY | TCL_TRACE_WRITES | TCL_TRACE_UNSETS |
+	    TCL_TRACE_READS | TCL_TRACE_ARRAY, EnvTraceProc, NULL);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclSetEnv --
+ *
+ *	Set an environment variable, replacing an existing value or creating a
+ *	new variable if there doesn't exist a variable by the given name. This
+ *	function is intended to be a stand-in for the UNIX "setenv" function
+ *	so that applications using that function will interface properly to
+ *	Tcl. To make it a stand-in, the Makefile must define "TclSetEnv" to
+ *	"setenv".
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The environ array gets updated.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclSetEnv(
+    const char *name,		/* Name of variable whose value is to be set
+				 * (UTF-8). */
+    const char *value)		/* New value for variable (UTF-8). */
+{
+    Tcl_DString envString;
+    unsigned nameLength, valueLength;
+    int index, length;
+    char *p, *oldValue;
+    const char *p2;
+
+    /*
+     * Figure out where the entry is going to go. If the name doesn't already
+     * exist, enlarge the array if necessary to make room. If the name exists,
+     * free its old entry.
+     */
+
+    Tcl_MutexLock(&envMutex);
+    index = TclpFindVariable(name, &length);
+
+    if (index == -1) {
+#ifndef USE_PUTENV
+	/*
+	 * We need to handle the case where the environment may be changed
+	 * outside our control. ourEnvironSize is only valid if the current
+	 * environment is the one we allocated. [Bug 979640]
+	 */
+
+	if ((env.ourEnviron != environ) || (length+2 > env.ourEnvironSize)) {
+	    char **newEnviron = ckalloc((length + 5) * sizeof(char *));
+
+	    memcpy(newEnviron, environ, length * sizeof(char *));
+	    if ((env.ourEnvironSize != 0) && (env.ourEnviron != NULL)) {
+		ckfree(env.ourEnviron);
+	    }
+	    environ = env.ourEnviron = newEnviron;
+	    env.ourEnvironSize = length + 5;
+	}
+	index = length;
+	environ[index + 1] = NULL;
+#endif /* USE_PUTENV */
+	oldValue = NULL;
+	nameLength = strlen(name);
+    } else {
+	const char *env;
+
+	/*
+	 * Compare the new value to the existing value. If they're the same
+	 * then quit immediately (e.g. don't rewrite the value or propagate it
+	 * to other interpreters). Otherwise, when there are N interpreters
+	 * there will be N! propagations of the same value among the
+	 * interpreters.
+	 */
+
+	env = Tcl_ExternalToUtfDString(NULL, environ[index], -1, &envString);
+	if (strcmp(value, env + (length + 1)) == 0) {
+	    Tcl_DStringFree(&envString);
+	    Tcl_MutexUnlock(&envMutex);
+	    return;
+	}
+	Tcl_DStringFree(&envString);
+
+	oldValue = environ[index];
+	nameLength = (unsigned) length;
+    }
+
+    /*
+     * Create a new entry. Build a complete UTF string that contains a
+     * "name=value" pattern. Then convert the string to the native encoding,
+     * and set the environ array value.
+     */
+
+    valueLength = strlen(value);
+    p = ckalloc(nameLength + valueLength + 2);
+    memcpy(p, name, nameLength);
+    p[nameLength] = '=';
+    memcpy(p+nameLength+1, value, valueLength+1);
+    p2 = Tcl_UtfToExternalDString(NULL, p, -1, &envString);
+
+    /*
+     * Copy the native string to heap memory.
+     */
+
+    p = ckrealloc(p, Tcl_DStringLength(&envString) + 1);
+    memcpy(p, p2, (unsigned) Tcl_DStringLength(&envString) + 1);
+    Tcl_DStringFree(&envString);
+
+#ifdef USE_PUTENV
+    /*
+     * Update the system environment.
+     */
+
+    putenv(p);
+    index = TclpFindVariable(name, &length);
+#else
+    environ[index] = p;
+#endif /* USE_PUTENV */
+
+    /*
+     * Watch out for versions of putenv that copy the string (e.g. VC++). In
+     * this case we need to free the string immediately. Otherwise update the
+     * string in the cache.
+     */
+
+    if ((index != -1) && (environ[index] == p)) {
+	ReplaceString(oldValue, p);
+#ifdef HAVE_PUTENV_THAT_COPIES
+    } else {
+	/*
+	 * This putenv() copies instead of taking ownership.
+	 */
+
+	ckfree(p);
+#endif /* HAVE_PUTENV_THAT_COPIES */
+    }
+
+    Tcl_MutexUnlock(&envMutex);
+
+    if (!strcmp(name, "HOME")) {
+	/*
+	 * If the user's home directory has changed, we must invalidate the
+	 * filesystem cache, because '~' expansions will now be incorrect.
+	 */
+
+	Tcl_FSMountsChanged(NULL);
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_PutEnv --
+ *
+ *	Set an environment variable. Similar to setenv except that the
+ *	information is passed in a single string of the form NAME=value,
+ *	rather than as separate name strings. This function is intended to be
+ *	a stand-in for the UNIX "putenv" function so that applications using
+ *	that function will interface properly to Tcl. To make it a stand-in,
+ *	the Makefile will define "Tcl_PutEnv" to "putenv".
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The environ array gets updated, as do all of the interpreters that we
+ *	manage.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_PutEnv(
+    const char *assignment)	/* Info about environment variable in the form
+				 * NAME=value. (native) */
+{
+    Tcl_DString nameString;
+    const char *name;
+    char *value;
+
+    if (assignment == NULL) {
+	return 0;
+    }
+
+    /*
+     * First convert the native string to UTF. Then separate the string into
+     * name and value parts, and call TclSetEnv to do all of the real work.
+     */
+
+    name = Tcl_ExternalToUtfDString(NULL, assignment, -1, &nameString);
+    value = strchr(name, '=');
+
+    if ((value != NULL) && (value != name)) {
+	value[0] = '\0';
+	TclSetEnv(name, value+1);
+    }
+
+    Tcl_DStringFree(&nameString);
+    return 0;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclUnsetEnv --
+ *
+ *	Remove an environment variable, updating the "env" arrays in all
+ *	interpreters managed by us. This function is intended to replace the
+ *	UNIX "unsetenv" function (but to do this the Makefile must be modified
+ *	to redefine "TclUnsetEnv" to "unsetenv".
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Interpreters are updated, as is environ.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclUnsetEnv(
+    const char *name)		/* Name of variable to remove (UTF-8). */
+{
+    char *oldValue;
+    int length;
+    int index;
+#ifdef USE_PUTENV_FOR_UNSET
+    Tcl_DString envString;
+    char *string;
+#else
+    char **envPtr;
+#endif /* USE_PUTENV_FOR_UNSET */
+
+    Tcl_MutexLock(&envMutex);
+    index = TclpFindVariable(name, &length);
+
+    /*
+     * First make sure that the environment variable exists to avoid doing
+     * needless work and to avoid recursion on the unset.
+     */
+
+    if (index == -1) {
+	Tcl_MutexUnlock(&envMutex);
+	return;
+    }
+
+    /*
+     * Remember the old value so we can free it if Tcl created the string.
+     */
+
+    oldValue = environ[index];
+
+    /*
+     * Update the system environment. This must be done before we update the
+     * interpreters or we will recurse.
+     */
+
+#ifdef USE_PUTENV_FOR_UNSET
+    /*
+     * For those platforms that support putenv to unset, Linux indicates
+     * that no = should be included, and Windows requires it.
+     */
+
+#if defined(_WIN32)
+    string = ckalloc(length + 2);
+    memcpy(string, name, (size_t) length);
+    string[length] = '=';
+    string[length+1] = '\0';
+#else
+    string = ckalloc(length + 1);
+    memcpy(string, name, (size_t) length);
+    string[length] = '\0';
+#endif /* _WIN32 */
+
+    Tcl_UtfToExternalDString(NULL, string, -1, &envString);
+    string = ckrealloc(string, Tcl_DStringLength(&envString) + 1);
+    memcpy(string, Tcl_DStringValue(&envString),
+	    (unsigned) Tcl_DStringLength(&envString)+1);
+    Tcl_DStringFree(&envString);
+
+    putenv(string);
+
+    /*
+     * Watch out for versions of putenv that copy the string (e.g. VC++). In
+     * this case we need to free the string immediately. Otherwise update the
+     * string in the cache.
+     */
+
+    if (environ[index] == string) {
+	ReplaceString(oldValue, string);
+#ifdef HAVE_PUTENV_THAT_COPIES
+    } else {
+	/*
+	 * This putenv() copies instead of taking ownership.
+	 */
+
+	ckfree(string);
+#endif /* HAVE_PUTENV_THAT_COPIES */
+    }
+#else /* !USE_PUTENV_FOR_UNSET */
+    for (envPtr = environ+index+1; ; envPtr++) {
+	envPtr[-1] = *envPtr;
+	if (*envPtr == NULL) {
+	    break;
+	}
+    }
+    ReplaceString(oldValue, NULL);
+#endif /* USE_PUTENV_FOR_UNSET */
+
+    Tcl_MutexUnlock(&envMutex);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * TclGetEnv --
+ *
+ *	Retrieve the value of an environment variable.
+ *
+ * Results:
+ *	The result is a pointer to a string specifying the value of the
+ *	environment variable, or NULL if that environment variable does not
+ *	exist. Storage for the result string is allocated in valuePtr; the
+ *	caller must call Tcl_DStringFree() when the result is no longer
+ *	needed.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+const char *
+TclGetEnv(
+    const char *name,		/* Name of environment variable to find
+				 * (UTF-8). */
+    Tcl_DString *valuePtr)	/* Uninitialized or free DString in which the
+				 * value of the environment variable is
+				 * stored. */
+{
+    int length, index;
+    const char *result;
+
+    Tcl_MutexLock(&envMutex);
+    index = TclpFindVariable(name, &length);
+    result = NULL;
+    if (index != -1) {
+	Tcl_DString envStr;
+
+	result = Tcl_ExternalToUtfDString(NULL, environ[index], -1, &envStr);
+	result += length;
+	if (*result == '=') {
+	    result++;
+	    Tcl_DStringInit(valuePtr);
+	    Tcl_DStringAppend(valuePtr, result, -1);
+	    result = Tcl_DStringValue(valuePtr);
+	} else {
+	    result = NULL;
+	}
+	Tcl_DStringFree(&envStr);
+    }
+    Tcl_MutexUnlock(&envMutex);
+    return result;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * EnvTraceProc --
+ *
+ *	This function is invoked whenever an environment variable is read,
+ *	modified or deleted. It propagates the change to the global "environ"
+ *	array.
+ *
+ * Results:
+ *	Returns NULL to indicate success, or an error-message if the array
+ *	element being handled doesn't exist.
+ *
+ * Side effects:
+ *	Environment variable changes get propagated. If the whole "env" array
+ *	is deleted, then we stop managing things for this interpreter (usually
+ *	this happens because the whole interpreter is being deleted).
+ *
+ *----------------------------------------------------------------------
+ */
+
+	/* ARGSUSED */
+static char *
+EnvTraceProc(
+    ClientData clientData,	/* Not used. */
+    Tcl_Interp *interp,		/* Interpreter whose "env" variable is being
+				 * modified. */
+    const char *name1,		/* Better be "env". */
+    const char *name2,		/* Name of variable being modified, or NULL if
+				 * whole array is being deleted (UTF-8). */
+    int flags)			/* Indicates what's happening. */
+{
+    /*
+     * For array traces, let TclSetupEnv do all the work.
+     */
+
+    if (flags & TCL_TRACE_ARRAY) {
+	TclSetupEnv(interp);
+	return NULL;
+    }
+
+    /*
+     * If name2 is NULL, then return and do nothing.
+     */
+
+    if (name2 == NULL) {
+	return NULL;
+    }
+
+    /*
+     * If a value is being set, call TclSetEnv to do all of the work.
+     */
+
+    if (flags & TCL_TRACE_WRITES) {
+	const char *value;
+
+	value = Tcl_GetVar2(interp, "env", name2, TCL_GLOBAL_ONLY);
+	TclSetEnv(name2, value);
+    }
+
+    /*
+     * If a value is being read, call TclGetEnv to do all of the work.
+     */
+
+    if (flags & TCL_TRACE_READS) {
+	Tcl_DString valueString;
+	const char *value = TclGetEnv(name2, &valueString);
+
+	if (value == NULL) {
+	    return (char *) "no such variable";
+	}
+	Tcl_SetVar2(interp, name1, name2, value, 0);
+	Tcl_DStringFree(&valueString);
+    }
+
+    /*
+     * For unset traces, let TclUnsetEnv do all the work.
+     */
+
+    if (flags & TCL_TRACE_UNSETS) {
+	TclUnsetEnv(name2);
+    }
+    return NULL;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ReplaceString --
+ *
+ *	Replace one string with another in the environment variable cache. The
+ *	cache keeps track of all of the environment variables that Tcl has
+ *	modified so they can be freed later.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	May free the old string.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+ReplaceString(
+    const char *oldStr,		/* Old environment string. */
+    char *newStr)		/* New environment string. */
+{
+    int i;
+
+    /*
+     * Check to see if the old value was allocated by Tcl. If so, it needs to
+     * be deallocated to avoid memory leaks. Note that this algorithm is O(n),
+     * not O(1). This will result in n-squared behavior if lots of environment
+     * changes are being made.
+     */
+
+    for (i = 0; i < env.cacheSize; i++) {
+	if (env.cache[i]==oldStr || env.cache[i]==NULL) {
+	    break;
+	}
+    }
+    if (i < env.cacheSize) {
+	/*
+	 * Replace or delete the old value.
+	 */
+
+	if (env.cache[i]) {
+	    ckfree(env.cache[i]);
+	}
+
+	if (newStr) {
+	    env.cache[i] = newStr;
+	} else {
+	    for (; i < env.cacheSize-1; i++) {
+		env.cache[i] = env.cache[i+1];
+	    }
+	    env.cache[env.cacheSize-1] = NULL;
+	}
+    } else {
+	/*
+	 * We need to grow the cache in order to hold the new string.
+	 */
+
+	const int growth = 5;
+
+	env.cache = ckrealloc(env.cache,
+		(env.cacheSize + growth) * sizeof(char *));
+	env.cache[env.cacheSize] = newStr;
+	(void) memset(env.cache+env.cacheSize+1, 0,
+		(size_t) (growth-1) * sizeof(char *));
+	env.cacheSize += growth;
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclFinalizeEnvironment --
+ *
+ *	This function releases any storage allocated by this module that isn't
+ *	still in use by the global environment. Any strings that are still in
+ *	the environment will be leaked.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	May deallocate storage.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclFinalizeEnvironment(void)
+{
+    /*
+     * For now we just deallocate the cache array and none of the environment
+     * strings. This may leak more memory that strictly necessary, since some
+     * of the strings may no longer be in the environment. However,
+     * determining which ones are ok to delete is n-squared, and is pretty
+     * unlikely, so we don't bother.
+     */
+
+    if (env.cache) {
+	ckfree(env.cache);
+	env.cache = NULL;
+	env.cacheSize = 0;
+#ifndef USE_PUTENV
+	env.ourEnvironSize = 0;
+#endif
+    }
+}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tclEvent.c b/generic/tclEvent.c
new file mode 100644
index 0000000..b0b8188
--- /dev/null
+++ b/generic/tclEvent.c
@@ -0,0 +1,1624 @@
+/*
+ * tclEvent.c --
+ *
+ *	This file implements some general event related interfaces including
+ *	background errors, exit handlers, and the "vwait" and "update" command
+ *	functions.
+ *
+ * Copyright (c) 1990-1994 The Regents of the University of California.
+ * Copyright (c) 1994-1998 Sun Microsystems, Inc.
+ * Copyright (c) 2004 by Zoran Vasiljevic.
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#include "tclInt.h"
+
+/*
+ * The data structure below is used to report background errors. One such
+ * structure is allocated for each error; it holds information about the
+ * interpreter and the error until an idle handler command can be invoked.
+ */
+
+typedef struct BgError {
+    Tcl_Obj *errorMsg;		/* Copy of the error message (the interp's
+				 * result when the error occurred). */
+    Tcl_Obj *returnOpts;	/* Active return options when the error
+				 * occurred */
+    struct BgError *nextPtr;	/* Next in list of all pending error reports
+				 * for this interpreter, or NULL for end of
+				 * list. */
+} BgError;
+
+/*
+ * One of the structures below is associated with the "tclBgError" assoc data
+ * for each interpreter. It keeps track of the head and tail of the list of
+ * pending background errors for the interpreter.
+ */
+
+typedef struct ErrAssocData {
+    Tcl_Interp *interp;		/* Interpreter in which error occurred. */
+    Tcl_Obj *cmdPrefix;		/* First word(s) of the handler command */
+    BgError *firstBgPtr;	/* First in list of all background errors
+				 * waiting to be processed for this
+				 * interpreter (NULL if none). */
+    BgError *lastBgPtr;		/* Last in list of all background errors
+				 * waiting to be processed for this
+				 * interpreter (NULL if none). */
+} ErrAssocData;
+
+/*
+ * For each exit handler created with a call to Tcl_Create(Late)ExitHandler
+ * there is a structure of the following type:
+ */
+
+typedef struct ExitHandler {
+    Tcl_ExitProc *proc;		/* Function to call when process exits. */
+    ClientData clientData;	/* One word of information to pass to proc. */
+    struct ExitHandler *nextPtr;/* Next in list of all exit handlers for this
+				 * application, or NULL for end of list. */
+} ExitHandler;
+
+/*
+ * There is both per-process and per-thread exit handlers. The first list is
+ * controlled by a mutex. The other is in thread local storage.
+ */
+
+static ExitHandler *firstExitPtr = NULL;
+				/* First in list of all exit handlers for
+				 * application. */
+static ExitHandler *firstLateExitPtr = NULL;
+				/* First in list of all late exit handlers for
+				 * application. */
+TCL_DECLARE_MUTEX(exitMutex)
+
+/*
+ * This variable is set to 1 when Tcl_Exit is called. The variable is checked
+ * by TclInExit() to allow different behavior for exit-time processing, e.g.,
+ * in closing of files and pipes.
+ */
+
+static int inExit = 0;
+
+static int subsystemsInitialized = 0;
+
+/*
+ * This variable contains the application wide exit handler. It will be called
+ * by Tcl_Exit instead of the C-runtime exit if this variable is set to a
+ * non-NULL value.
+ */
+
+static TCL_NORETURN1 Tcl_ExitProc *appExitPtr = NULL;
+
+typedef struct ThreadSpecificData {
+    ExitHandler *firstExitPtr;	/* First in list of all exit handlers for this
+				 * thread. */
+    int inExit;			/* True when this thread is exiting. This is
+				 * used as a hack to decide to close the
+				 * standard channels. */
+} ThreadSpecificData;
+static Tcl_ThreadDataKey dataKey;
+
+#ifdef TCL_THREADS
+typedef struct {
+    Tcl_ThreadCreateProc *proc;	/* Main() function of the thread */
+    ClientData clientData;	/* The one argument to Main() */
+} ThreadClientData;
+static Tcl_ThreadCreateType NewThreadProc(ClientData clientData);
+#endif /* TCL_THREADS */
+
+/*
+ * Prototypes for functions referenced only in this file:
+ */
+
+static void		BgErrorDeleteProc(ClientData clientData,
+			    Tcl_Interp *interp);
+static void		HandleBgErrors(ClientData clientData);
+static char *		VwaitVarProc(ClientData clientData,
+			    Tcl_Interp *interp, const char *name1,
+			    const char *name2, int flags);
+static void		InvokeExitHandlers(void);
+static void		FinalizeThread(int quick);
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_BackgroundError --
+ *
+ *	This function is invoked to handle errors that occur in Tcl commands
+ *	that are invoked in "background" (e.g. from event or timer bindings).
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	A handler command is invoked later as an idle handler to process the
+ *	error, passing it the interp result and return options.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_BackgroundError(
+    Tcl_Interp *interp)		/* Interpreter in which an error has
+				 * occurred. */
+{
+    Tcl_BackgroundException(interp, TCL_ERROR);
+}
+
+void
+Tcl_BackgroundException(
+    Tcl_Interp *interp,		/* Interpreter in which an exception has
+				 * occurred. */
+    int code)			/* The exception code value */
+{
+    BgError *errPtr;
+    ErrAssocData *assocPtr;
+
+    if (code == TCL_OK) {
+	return;
+    }
+
+    errPtr = ckalloc(sizeof(BgError));
+    errPtr->errorMsg = Tcl_GetObjResult(interp);
+    Tcl_IncrRefCount(errPtr->errorMsg);
+    errPtr->returnOpts = Tcl_GetReturnOptions(interp, code);
+    Tcl_IncrRefCount(errPtr->returnOpts);
+    errPtr->nextPtr = NULL;
+
+    (void) TclGetBgErrorHandler(interp);
+    assocPtr = Tcl_GetAssocData(interp, "tclBgError", NULL);
+    if (assocPtr->firstBgPtr == NULL) {
+	assocPtr->firstBgPtr = errPtr;
+	Tcl_DoWhenIdle(HandleBgErrors, assocPtr);
+    } else {
+	assocPtr->lastBgPtr->nextPtr = errPtr;
+    }
+    assocPtr->lastBgPtr = errPtr;
+    Tcl_ResetResult(interp);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * HandleBgErrors --
+ *
+ *	This function is invoked as an idle handler to process all of the
+ *	accumulated background errors.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Depends on what actions the handler command takes for the errors.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+HandleBgErrors(
+    ClientData clientData)	/* Pointer to ErrAssocData structure. */
+{
+    ErrAssocData *assocPtr = clientData;
+    Tcl_Interp *interp = assocPtr->interp;
+    BgError *errPtr;
+
+    /*
+     * Not bothering to save/restore the interp state. Assume that any code
+     * that has interp state it needs to keep will make its own
+     * Tcl_SaveInterpState call before calling something like Tcl_DoOneEvent()
+     * that could lead us here.
+     */
+
+    Tcl_Preserve(assocPtr);
+    Tcl_Preserve(interp);
+    while (assocPtr->firstBgPtr != NULL) {
+	int code, prefixObjc;
+	Tcl_Obj **prefixObjv, **tempObjv;
+
+	/*
+	 * Note we copy the handler command prefix each pass through, so we do
+	 * support one handler setting another handler.
+	 */
+
+	Tcl_Obj *copyObj = TclListObjCopy(NULL, assocPtr->cmdPrefix);
+
+	errPtr = assocPtr->firstBgPtr;
+
+	Tcl_ListObjGetElements(NULL, copyObj, &prefixObjc, &prefixObjv);
+	tempObjv = ckalloc((prefixObjc+2) * sizeof(Tcl_Obj *));
+	memcpy(tempObjv, prefixObjv, prefixObjc*sizeof(Tcl_Obj *));
+	tempObjv[prefixObjc] = errPtr->errorMsg;
+	tempObjv[prefixObjc+1] = errPtr->returnOpts;
+	Tcl_AllowExceptions(interp);
+	code = Tcl_EvalObjv(interp, prefixObjc+2, tempObjv, TCL_EVAL_GLOBAL);
+
+	/*
+	 * Discard the command and the information about the error report.
+	 */
+
+	Tcl_DecrRefCount(copyObj);
+	Tcl_DecrRefCount(errPtr->errorMsg);
+	Tcl_DecrRefCount(errPtr->returnOpts);
+	assocPtr->firstBgPtr = errPtr->nextPtr;
+	ckfree(errPtr);
+	ckfree(tempObjv);
+
+	if (code == TCL_BREAK) {
+	    /*
+	     * Break means cancel any remaining error reports for this
+	     * interpreter.
+	     */
+
+	    while (assocPtr->firstBgPtr != NULL) {
+		errPtr = assocPtr->firstBgPtr;
+		assocPtr->firstBgPtr = errPtr->nextPtr;
+		Tcl_DecrRefCount(errPtr->errorMsg);
+		Tcl_DecrRefCount(errPtr->returnOpts);
+		ckfree(errPtr);
+	    }
+	} else if ((code == TCL_ERROR) && !Tcl_IsSafe(interp)) {
+	    Tcl_Channel errChannel = Tcl_GetStdChannel(TCL_STDERR);
+
+	    if (errChannel != NULL) {
+		Tcl_Obj *options = Tcl_GetReturnOptions(interp, code);
+		Tcl_Obj *keyPtr, *valuePtr = NULL;
+
+		TclNewLiteralStringObj(keyPtr, "-errorinfo");
+		Tcl_IncrRefCount(keyPtr);
+		Tcl_DictObjGet(NULL, options, keyPtr, &valuePtr);
+		Tcl_DecrRefCount(keyPtr);
+
+		Tcl_WriteChars(errChannel,
+			"error in background error handler:\n", -1);
+		if (valuePtr) {
+		    Tcl_WriteObj(errChannel, valuePtr);
+		} else {
+		    Tcl_WriteObj(errChannel, Tcl_GetObjResult(interp));
+		}
+		Tcl_WriteChars(errChannel, "\n", 1);
+		Tcl_Flush(errChannel);
+		Tcl_DecrRefCount(options);
+	    }
+	}
+    }
+    assocPtr->lastBgPtr = NULL;
+    Tcl_Release(interp);
+    Tcl_Release(assocPtr);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclDefaultBgErrorHandlerObjCmd --
+ *
+ *	This function is invoked to process the "::tcl::Bgerror" Tcl command.
+ *	It is the default handler command registered with [interp bgerror] for
+ *	the sake of compatibility with older Tcl releases.
+ *
+ * Results:
+ *	A standard Tcl object result.
+ *
+ * Side effects:
+ *	Depends on what actions the "bgerror" command takes for the errors.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclDefaultBgErrorHandlerObjCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    Tcl_Obj *keyPtr, *valuePtr;
+    Tcl_Obj *tempObjv[2];
+    int result, code, level;
+    Tcl_InterpState saved;
+
+    if (objc != 3) {
+	Tcl_WrongNumArgs(interp, 1, objv, "msg options");
+	return TCL_ERROR;
+    }
+
+    /*
+     * Check for a valid return options dictionary.
+     */
+
+    TclNewLiteralStringObj(keyPtr, "-level");
+    Tcl_IncrRefCount(keyPtr);
+    result = Tcl_DictObjGet(NULL, objv[2], keyPtr, &valuePtr);
+    Tcl_DecrRefCount(keyPtr);
+    if (result != TCL_OK || valuePtr == NULL) {
+	Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		"missing return option \"-level\"", -1));
+	Tcl_SetErrorCode(interp, "TCL", "ARGUMENT", "MISSING", NULL);
+	return TCL_ERROR;
+    }
+    if (Tcl_GetIntFromObj(interp, valuePtr, &level) == TCL_ERROR) {
+	return TCL_ERROR;
+    }
+    TclNewLiteralStringObj(keyPtr, "-code");
+    Tcl_IncrRefCount(keyPtr);
+    result = Tcl_DictObjGet(NULL, objv[2], keyPtr, &valuePtr);
+    Tcl_DecrRefCount(keyPtr);
+    if (result != TCL_OK || valuePtr == NULL) {
+	Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		"missing return option \"-code\"", -1));
+	Tcl_SetErrorCode(interp, "TCL", "ARGUMENT", "MISSING", NULL);
+	return TCL_ERROR;
+    }
+    if (Tcl_GetIntFromObj(interp, valuePtr, &code) == TCL_ERROR) {
+	return TCL_ERROR;
+    }
+
+    if (level != 0) {
+	/*
+	 * We're handling a TCL_RETURN exception.
+	 */
+
+	code = TCL_RETURN;
+    }
+    if (code == TCL_OK) {
+	/*
+	 * Somehow we got to exception handling with no exception. (Pass
+	 * TCL_OK to Tcl_BackgroundException()?) Just return without doing
+	 * anything.
+	 */
+
+	return TCL_OK;
+    }
+
+    /*
+     * Construct the bgerror command.
+     */
+
+    TclNewLiteralStringObj(tempObjv[0], "bgerror");
+    Tcl_IncrRefCount(tempObjv[0]);
+
+    /*
+     * Determine error message argument.  Check the return options in case
+     * a non-error exception brought us here.
+     */
+
+    switch (code) {
+    case TCL_ERROR:
+	tempObjv[1] = objv[1];
+	break;
+    case TCL_BREAK:
+	TclNewLiteralStringObj(tempObjv[1],
+		"invoked \"break\" outside of a loop");
+	break;
+    case TCL_CONTINUE:
+	TclNewLiteralStringObj(tempObjv[1],
+		"invoked \"continue\" outside of a loop");
+	break;
+    default:
+	tempObjv[1] = Tcl_ObjPrintf("command returned bad code: %d", code);
+	break;
+    }
+    Tcl_IncrRefCount(tempObjv[1]);
+
+    if (code != TCL_ERROR) {
+	Tcl_SetObjResult(interp, tempObjv[1]);
+    }
+
+    TclNewLiteralStringObj(keyPtr, "-errorcode");
+    Tcl_IncrRefCount(keyPtr);
+    result = Tcl_DictObjGet(NULL, objv[2], keyPtr, &valuePtr);
+    Tcl_DecrRefCount(keyPtr);
+    if (result == TCL_OK && valuePtr != NULL) {
+	Tcl_SetObjErrorCode(interp, valuePtr);
+    }
+
+    TclNewLiteralStringObj(keyPtr, "-errorinfo");
+    Tcl_IncrRefCount(keyPtr);
+    result = Tcl_DictObjGet(NULL, objv[2], keyPtr, &valuePtr);
+    Tcl_DecrRefCount(keyPtr);
+    if (result == TCL_OK && valuePtr != NULL) {
+	Tcl_AppendObjToErrorInfo(interp, valuePtr);
+    }
+
+    if (code == TCL_ERROR) {
+	Tcl_SetObjResult(interp, tempObjv[1]);
+    }
+
+    /*
+     * Save interpreter state so we can restore it if multiple handler
+     * attempts are needed.
+     */
+
+    saved = Tcl_SaveInterpState(interp, code);
+
+    /*
+     * Invoke the bgerror command.
+     */
+
+    Tcl_AllowExceptions(interp);
+    code = Tcl_EvalObjv(interp, 2, tempObjv, TCL_EVAL_GLOBAL);
+    if (code == TCL_ERROR) {
+	/*
+	 * If the interpreter is safe, we look for a hidden command named
+	 * "bgerror" and call that with the error information. Otherwise,
+	 * simply ignore the error. The rationale is that this could be an
+	 * error caused by a malicious applet trying to cause an infinite
+	 * barrage of error messages. The hidden "bgerror" command can be used
+	 * by a security policy to interpose on such attacks and e.g. kill the
+	 * applet after a few attempts.
+	 */
+
+	if (Tcl_IsSafe(interp)) {
+	    Tcl_RestoreInterpState(interp, saved);
+	    TclObjInvoke(interp, 2, tempObjv, TCL_INVOKE_HIDDEN);
+	} else {
+	    Tcl_Channel errChannel = Tcl_GetStdChannel(TCL_STDERR);
+
+	    if (errChannel != NULL) {
+		Tcl_Obj *resultPtr = Tcl_GetObjResult(interp);
+
+		Tcl_IncrRefCount(resultPtr);
+		if (Tcl_FindCommand(interp, "bgerror", NULL,
+			TCL_GLOBAL_ONLY) == NULL) {
+		    Tcl_RestoreInterpState(interp, saved);
+		    Tcl_WriteObj(errChannel, Tcl_GetVar2Ex(interp,
+			    "errorInfo", NULL, TCL_GLOBAL_ONLY));
+		    Tcl_WriteChars(errChannel, "\n", -1);
+		} else {
+		    Tcl_DiscardInterpState(saved);
+		    Tcl_WriteChars(errChannel,
+			    "bgerror failed to handle background error.\n",-1);
+		    Tcl_WriteChars(errChannel, "    Original error: ", -1);
+		    Tcl_WriteObj(errChannel, tempObjv[1]);
+		    Tcl_WriteChars(errChannel, "\n", -1);
+		    Tcl_WriteChars(errChannel, "    Error in bgerror: ", -1);
+		    Tcl_WriteObj(errChannel, resultPtr);
+		    Tcl_WriteChars(errChannel, "\n", -1);
+		}
+		Tcl_DecrRefCount(resultPtr);
+		Tcl_Flush(errChannel);
+	    } else {
+		Tcl_DiscardInterpState(saved);
+	    }
+	}
+	code = TCL_OK;
+    } else {
+	Tcl_DiscardInterpState(saved);
+    }
+
+    Tcl_DecrRefCount(tempObjv[0]);
+    Tcl_DecrRefCount(tempObjv[1]);
+    Tcl_ResetResult(interp);
+    return code;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclSetBgErrorHandler --
+ *
+ *	This function sets the command prefix to be used to handle background
+ *	errors in interp.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Error handler is registered.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclSetBgErrorHandler(
+    Tcl_Interp *interp,
+    Tcl_Obj *cmdPrefix)
+{
+    ErrAssocData *assocPtr = Tcl_GetAssocData(interp, "tclBgError", NULL);
+
+    if (cmdPrefix == NULL) {
+	Tcl_Panic("TclSetBgErrorHandler: NULL cmdPrefix argument");
+    }
+    if (assocPtr == NULL) {
+	/*
+	 * First access: initialize.
+	 */
+
+	assocPtr = ckalloc(sizeof(ErrAssocData));
+	assocPtr->interp = interp;
+	assocPtr->cmdPrefix = NULL;
+	assocPtr->firstBgPtr = NULL;
+	assocPtr->lastBgPtr = NULL;
+	Tcl_SetAssocData(interp, "tclBgError", BgErrorDeleteProc, assocPtr);
+    }
+    if (assocPtr->cmdPrefix) {
+	Tcl_DecrRefCount(assocPtr->cmdPrefix);
+    }
+    assocPtr->cmdPrefix = cmdPrefix;
+    Tcl_IncrRefCount(assocPtr->cmdPrefix);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclGetBgErrorHandler --
+ *
+ *	This function retrieves the command prefix currently used to handle
+ *	background errors in interp.
+ *
+ * Results:
+ *	A (Tcl_Obj *) to a list of words (command prefix).
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_Obj *
+TclGetBgErrorHandler(
+    Tcl_Interp *interp)
+{
+    ErrAssocData *assocPtr = Tcl_GetAssocData(interp, "tclBgError", NULL);
+
+    if (assocPtr == NULL) {
+	Tcl_Obj *bgerrorObj;
+
+	TclNewLiteralStringObj(bgerrorObj, "::tcl::Bgerror");
+	TclSetBgErrorHandler(interp, bgerrorObj);
+	assocPtr = Tcl_GetAssocData(interp, "tclBgError", NULL);
+    }
+    return assocPtr->cmdPrefix;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * BgErrorDeleteProc --
+ *
+ *	This function is associated with the "tclBgError" assoc data for an
+ *	interpreter; it is invoked when the interpreter is deleted in order to
+ *	free the information assoicated with any pending error reports.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Background error information is freed: if there were any pending error
+ *	reports, they are canceled.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+BgErrorDeleteProc(
+    ClientData clientData,	/* Pointer to ErrAssocData structure. */
+    Tcl_Interp *interp)		/* Interpreter being deleted. */
+{
+    ErrAssocData *assocPtr = clientData;
+    BgError *errPtr;
+
+    while (assocPtr->firstBgPtr != NULL) {
+	errPtr = assocPtr->firstBgPtr;
+	assocPtr->firstBgPtr = errPtr->nextPtr;
+	Tcl_DecrRefCount(errPtr->errorMsg);
+	Tcl_DecrRefCount(errPtr->returnOpts);
+	ckfree(errPtr);
+    }
+    Tcl_CancelIdleCall(HandleBgErrors, assocPtr);
+    Tcl_DecrRefCount(assocPtr->cmdPrefix);
+    Tcl_EventuallyFree(assocPtr, TCL_DYNAMIC);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_CreateExitHandler --
+ *
+ *	Arrange for a given function to be invoked just before the application
+ *	exits.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Proc will be invoked with clientData as argument when the application
+ *	exits.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_CreateExitHandler(
+    Tcl_ExitProc *proc,		/* Function to invoke. */
+    ClientData clientData)	/* Arbitrary value to pass to proc. */
+{
+    ExitHandler *exitPtr = ckalloc(sizeof(ExitHandler));
+
+    exitPtr->proc = proc;
+    exitPtr->clientData = clientData;
+    Tcl_MutexLock(&exitMutex);
+    exitPtr->nextPtr = firstExitPtr;
+    firstExitPtr = exitPtr;
+    Tcl_MutexUnlock(&exitMutex);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclCreateLateExitHandler --
+ *
+ *	Arrange for a given function to be invoked after all pre-thread
+ *	cleanups.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Proc will be invoked with clientData as argument when the application
+ *	exits.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclCreateLateExitHandler(
+    Tcl_ExitProc *proc,		/* Function to invoke. */
+    ClientData clientData)	/* Arbitrary value to pass to proc. */
+{
+    ExitHandler *exitPtr = ckalloc(sizeof(ExitHandler));
+
+    exitPtr->proc = proc;
+    exitPtr->clientData = clientData;
+    Tcl_MutexLock(&exitMutex);
+    exitPtr->nextPtr = firstLateExitPtr;
+    firstLateExitPtr = exitPtr;
+    Tcl_MutexUnlock(&exitMutex);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_DeleteExitHandler --
+ *
+ *	This function cancels an existing exit handler matching proc and
+ *	clientData, if such a handler exits.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	If there is an exit handler corresponding to proc and clientData then
+ *	it is canceled; if no such handler exists then nothing happens.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_DeleteExitHandler(
+    Tcl_ExitProc *proc,		/* Function that was previously registered. */
+    ClientData clientData)	/* Arbitrary value to pass to proc. */
+{
+    ExitHandler *exitPtr, *prevPtr;
+
+    Tcl_MutexLock(&exitMutex);
+    for (prevPtr = NULL, exitPtr = firstExitPtr; exitPtr != NULL;
+	    prevPtr = exitPtr, exitPtr = exitPtr->nextPtr) {
+	if ((exitPtr->proc == proc)
+		&& (exitPtr->clientData == clientData)) {
+	    if (prevPtr == NULL) {
+		firstExitPtr = exitPtr->nextPtr;
+	    } else {
+		prevPtr->nextPtr = exitPtr->nextPtr;
+	    }
+	    ckfree(exitPtr);
+	    break;
+	}
+    }
+    Tcl_MutexUnlock(&exitMutex);
+    return;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclDeleteLateExitHandler --
+ *
+ *	This function cancels an existing late exit handler matching proc and
+ *	clientData, if such a handler exits.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	If there is a late exit handler corresponding to proc and clientData
+ *	then it is canceled; if no such handler exists then nothing happens.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclDeleteLateExitHandler(
+    Tcl_ExitProc *proc,		/* Function that was previously registered. */
+    ClientData clientData)	/* Arbitrary value to pass to proc. */
+{
+    ExitHandler *exitPtr, *prevPtr;
+
+    Tcl_MutexLock(&exitMutex);
+    for (prevPtr = NULL, exitPtr = firstLateExitPtr; exitPtr != NULL;
+	    prevPtr = exitPtr, exitPtr = exitPtr->nextPtr) {
+	if ((exitPtr->proc == proc)
+		&& (exitPtr->clientData == clientData)) {
+	    if (prevPtr == NULL) {
+		firstLateExitPtr = exitPtr->nextPtr;
+	    } else {
+		prevPtr->nextPtr = exitPtr->nextPtr;
+	    }
+	    ckfree(exitPtr);
+	    break;
+	}
+    }
+    Tcl_MutexUnlock(&exitMutex);
+    return;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_CreateThreadExitHandler --
+ *
+ *	Arrange for a given function to be invoked just before the current
+ *	thread exits.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Proc will be invoked with clientData as argument when the application
+ *	exits.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_CreateThreadExitHandler(
+    Tcl_ExitProc *proc,		/* Function to invoke. */
+    ClientData clientData)	/* Arbitrary value to pass to proc. */
+{
+    ExitHandler *exitPtr;
+    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+
+    exitPtr = ckalloc(sizeof(ExitHandler));
+    exitPtr->proc = proc;
+    exitPtr->clientData = clientData;
+    exitPtr->nextPtr = tsdPtr->firstExitPtr;
+    tsdPtr->firstExitPtr = exitPtr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_DeleteThreadExitHandler --
+ *
+ *	This function cancels an existing exit handler matching proc and
+ *	clientData, if such a handler exits.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	If there is an exit handler corresponding to proc and clientData then
+ *	it is canceled; if no such handler exists then nothing happens.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_DeleteThreadExitHandler(
+    Tcl_ExitProc *proc,		/* Function that was previously registered. */
+    ClientData clientData)	/* Arbitrary value to pass to proc. */
+{
+    ExitHandler *exitPtr, *prevPtr;
+    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+
+    for (prevPtr = NULL, exitPtr = tsdPtr->firstExitPtr; exitPtr != NULL;
+	    prevPtr = exitPtr, exitPtr = exitPtr->nextPtr) {
+	if ((exitPtr->proc == proc)
+		&& (exitPtr->clientData == clientData)) {
+	    if (prevPtr == NULL) {
+		tsdPtr->firstExitPtr = exitPtr->nextPtr;
+	    } else {
+		prevPtr->nextPtr = exitPtr->nextPtr;
+	    }
+	    ckfree(exitPtr);
+	    return;
+	}
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_SetExitProc --
+ *
+ *	This function sets the application wide exit handler that will be
+ *	called by Tcl_Exit in place of the C-runtime exit. If the application
+ *	wide exit handler is NULL, the C-runtime exit will be used instead.
+ *
+ * Results:
+ *	The previously set application wide exit handler.
+ *
+ * Side effects:
+ *	Sets the application wide exit handler to the specified value.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_ExitProc *
+Tcl_SetExitProc(
+    TCL_NORETURN1 Tcl_ExitProc *proc)		/* New exit handler for app or NULL */
+{
+    Tcl_ExitProc *prevExitProc;
+
+    /*
+     * Swap the old exit proc for the new one, saving the old one for our
+     * return value.
+     */
+
+    Tcl_MutexLock(&exitMutex);
+    prevExitProc = appExitPtr;
+    appExitPtr = proc;
+    Tcl_MutexUnlock(&exitMutex);
+
+    return prevExitProc;
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * InvokeExitHandlers --
+ *
+ *      Call the registered exit handlers.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The exit handlers are invoked, and the ExitHandler struct is
+ *      freed.
+ *
+ *----------------------------------------------------------------------
+ */
+static void
+InvokeExitHandlers(void)
+{
+    ExitHandler *exitPtr;
+
+    Tcl_MutexLock(&exitMutex);
+    inExit = 1;
+
+    for (exitPtr = firstExitPtr; exitPtr != NULL; exitPtr = firstExitPtr) {
+	/*
+	 * Be careful to remove the handler from the list before invoking its
+	 * callback. This protects us against double-freeing if the callback
+	 * should call Tcl_DeleteExitHandler on itself.
+	 */
+
+	firstExitPtr = exitPtr->nextPtr;
+	Tcl_MutexUnlock(&exitMutex);
+	exitPtr->proc(exitPtr->clientData);
+	ckfree(exitPtr);
+	Tcl_MutexLock(&exitMutex);
+    }
+    firstExitPtr = NULL;
+    Tcl_MutexUnlock(&exitMutex);
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_Exit --
+ *
+ *	This function is called to terminate the application.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	All existing exit handlers are invoked, then the application ends.
+ *
+ *----------------------------------------------------------------------
+ */
+
+TCL_NORETURN void
+Tcl_Exit(
+    int status)			/* Exit status for application; typically 0
+				 * for normal return, 1 for error return. */
+{
+    TCL_NORETURN1 Tcl_ExitProc *currentAppExitPtr;
+
+    Tcl_MutexLock(&exitMutex);
+    currentAppExitPtr = appExitPtr;
+    Tcl_MutexUnlock(&exitMutex);
+
+    if (currentAppExitPtr) {
+	/*
+	 * Warning: this code SHOULD NOT return, as there is code that depends
+	 * on Tcl_Exit never returning. In fact, we will Tcl_Panic if anyone
+	 * returns, so critical is this dependcy.
+	 */
+
+	currentAppExitPtr(INT2PTR(status));
+	Tcl_Panic("AppExitProc returned unexpectedly");
+    } else {
+
+	if (TclFullFinalizationRequested()) {
+
+	    /*
+	     * Thorough finalization for Valgrind et al.
+	     */
+
+	    Tcl_Finalize();
+
+	} else {
+
+	    /*
+	     * Fast and deterministic exit (default behavior)
+	     */
+
+	    InvokeExitHandlers();
+
+	    /*
+	     * Ensure the thread-specific data is initialised as it is used in
+	     * Tcl_FinalizeThread()
+	     */
+
+	    (void) TCL_TSD_INIT(&dataKey);
+
+	    /*
+	     * Now finalize the calling thread only (others are not safely
+	     * reachable).  Among other things, this triggers a flush of the
+	     * Tcl_Channels that may have data enqueued.
+	     */
+
+	    FinalizeThread(/* quick */ 1);
+	}
+	TclpExit(status);
+	Tcl_Panic("OS exit failed!");
+    }
+}
+
+/*
+ *-------------------------------------------------------------------------
+ *
+ * TclInitSubsystems --
+ *
+ *	Initialize various subsytems in Tcl. This should be called the first
+ *	time an interp is created, or before any of the subsystems are used.
+ *	This function ensures an order for the initialization of subsystems:
+ *
+ *	1. that cannot be initialized in lazy order because they are mutually
+ *	dependent.
+ *
+ *	2. so that they can be finalized in a known order w/o causing the
+ *	subsequent re-initialization of a subsystem in the act of shutting
+ *	down another.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Varied, see the respective initialization routines.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+void
+TclInitSubsystems(void)
+{
+    if (inExit != 0) {
+	Tcl_Panic("TclInitSubsystems called while exiting");
+    }
+
+    if (subsystemsInitialized == 0) {
+	/*
+	 * Double check inside the mutex. There are definitly calls back into
+	 * this routine from some of the functions below.
+	 */
+
+	TclpInitLock();
+	if (subsystemsInitialized == 0) {
+
+		/*
+	     * Initialize locks used by the memory allocators before anything
+	     * interesting happens so we can use the allocators in the
+	     * implementation of self-initializing locks.
+	     */
+
+	    TclInitThreadStorage();     /* Creates master hash table for
+					 * thread local storage */
+#if USE_TCLALLOC
+	    TclInitAlloc();		/* Process wide mutex init */
+#endif
+#ifdef TCL_MEM_DEBUG
+	    TclInitDbCkalloc();		/* Process wide mutex init */
+#endif
+
+	    TclpInitPlatform();		/* Creates signal handler(s) */
+	    TclInitDoubleConversion();	/* Initializes constants for
+					 * converting to/from double. */
+	    TclInitObjSubsystem();	/* Register obj types, create
+					 * mutexes. */
+	    TclInitIOSubsystem();	/* Inits a tsd key (noop). */
+	    TclInitEncodingSubsystem();	/* Process wide encoding init. */
+	    TclpSetInterfaces();
+	    TclInitNamespaceSubsystem();/* Register ns obj type (mutexed). */
+	    subsystemsInitialized = 1;
+	}
+	TclpInitUnlock();
+    }
+    TclInitNotifier();
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_Finalize --
+ *
+ *	Shut down Tcl. First calls registered exit handlers, then carefully
+ *	shuts down various subsystems.  Should be invoked by user before the
+ *	Tcl shared library is being unloaded in an embedded context.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Varied, see the respective finalization routines.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_Finalize(void)
+{
+    ExitHandler *exitPtr;
+
+    /*
+     * Invoke exit handlers first.
+     */
+
+    InvokeExitHandlers();
+
+    TclpInitLock();
+    if (subsystemsInitialized == 0) {
+	goto alreadyFinalized;
+    }
+    subsystemsInitialized = 0;
+
+    /*
+     * Ensure the thread-specific data is initialised as it is used in
+     * Tcl_FinalizeThread()
+     */
+
+    (void) TCL_TSD_INIT(&dataKey);
+
+    /*
+     * Clean up after the current thread now, after exit handlers. In
+     * particular, the testexithandler command sets up something that writes
+     * to standard output, which gets closed. Note that there is no
+     * thread-local storage or IO subsystem after this call.
+     */
+
+    Tcl_FinalizeThread();
+
+    /*
+     * Now invoke late (process-wide) exit handlers.
+     */
+
+    Tcl_MutexLock(&exitMutex);
+    for (exitPtr = firstLateExitPtr; exitPtr != NULL;
+	    exitPtr = firstLateExitPtr) {
+	/*
+	 * Be careful to remove the handler from the list before invoking its
+	 * callback. This protects us against double-freeing if the callback
+	 * should call Tcl_DeleteLateExitHandler on itself.
+	 */
+
+	firstLateExitPtr = exitPtr->nextPtr;
+	Tcl_MutexUnlock(&exitMutex);
+	exitPtr->proc(exitPtr->clientData);
+	ckfree(exitPtr);
+	Tcl_MutexLock(&exitMutex);
+    }
+    firstLateExitPtr = NULL;
+    Tcl_MutexUnlock(&exitMutex);
+
+    /*
+     * Now finalize the Tcl execution environment. Note that this must be done
+     * after the exit handlers, because there are order dependencies.
+     */
+
+    TclFinalizeEvaluation();
+    TclFinalizeExecution();
+    TclFinalizeEnvironment();
+
+    /*
+     * Finalizing the filesystem must come after anything which might
+     * conceivably interact with the 'Tcl_FS' API.
+     */
+
+    TclFinalizeFilesystem();
+
+    /*
+     * Undo all Tcl_ObjType registrations, and reset the master list of free
+     * Tcl_Obj's. After this returns, no more Tcl_Obj's should be allocated or
+     * freed.
+     *
+     * Note in particular that TclFinalizeObjects() must follow
+     * TclFinalizeFilesystem() because TclFinalizeFilesystem free's the
+     * Tcl_Obj that holds the path of the current working directory.
+     */
+
+    TclFinalizeObjects();
+
+    /*
+     * We must be sure the encoding finalization doesn't need to examine the
+     * filesystem in any way. Since it only needs to clean up internal data
+     * structures, this is fine.
+     */
+
+    TclFinalizeEncodingSubsystem();
+
+    /*
+     * Repeat finalization of the thread local storage once more. Although
+     * this step is already done by the Tcl_FinalizeThread call above, series
+     * of events happening afterwards may re-initialize TSD slots. Those need
+     * to be finalized again, otherwise we're leaking memory chunks. Very
+     * important to note is that things happening afterwards should not
+     * reference anything which may re-initialize TSD's. This includes freeing
+     * Tcl_Objs's, among other things.
+     *
+     * This fixes the Tcl Bug #990552.
+     */
+
+    TclFinalizeThreadData(/* quick */ 0);
+
+    /*
+     * Now we can free constants for conversions to/from double.
+     */
+
+    TclFinalizeDoubleConversion();
+
+    /*
+     * There have been several bugs in the past that cause exit handlers to be
+     * established during Tcl_Finalize processing. Such exit handlers leave
+     * malloc'ed memory, and Tcl_FinalizeMemorySubsystem or
+     * Tcl_FinalizeThreadAlloc will result in a corrupted heap. The result can
+     * be a mysterious crash on process exit. Check here that nobody's done
+     * this.
+     */
+
+    if (firstExitPtr != NULL) {
+	Tcl_Panic("exit handlers were created during Tcl_Finalize");
+    }
+
+    TclFinalizePreserve();
+
+    /*
+     * Free synchronization objects. There really should only be one thread
+     * alive at this moment.
+     */
+
+    TclFinalizeSynchronization();
+
+    /*
+     * Close down the thread-specific object allocator.
+     */
+
+#if defined(TCL_THREADS) && defined(USE_THREAD_ALLOC)
+    TclFinalizeThreadAlloc();
+#endif
+
+    /*
+     * We defer unloading of packages until very late to avoid memory access
+     * issues. Both exit callbacks and synchronization variables may be stored
+     * in packages.
+     *
+     * Note that TclFinalizeLoad unloads packages in the reverse of the order
+     * they were loaded in (i.e. last to be loaded is the first to be
+     * unloaded). This can be important for correct unloading when
+     * dependencies exist.
+     *
+     * Once load has been finalized, we will have deleted any temporary copies
+     * of shared libraries and can therefore reset the filesystem to its
+     * original state.
+     */
+
+    TclFinalizeLoad();
+    TclResetFilesystem();
+
+    /*
+     * At this point, there should no longer be any ckalloc'ed memory.
+     */
+
+    TclFinalizeMemorySubsystem();
+
+  alreadyFinalized:
+    TclFinalizeLock();
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_FinalizeThread --
+ *
+ *	Runs the exit handlers to allow Tcl to clean up its state about a
+ *	particular thread.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Varied, see the respective finalization routines.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_FinalizeThread(void)
+{
+    FinalizeThread(/* quick */ 0);
+}
+
+void
+FinalizeThread(
+    int quick)
+{
+    ExitHandler *exitPtr;
+    ThreadSpecificData *tsdPtr;
+
+    /*
+     * We use TclThreadDataKeyGet here, rather than Tcl_GetThreadData, because
+     * we don't want to initialize the data block if it hasn't been
+     * initialized already.
+     */
+
+    tsdPtr = TclThreadDataKeyGet(&dataKey);
+    if (tsdPtr != NULL) {
+	tsdPtr->inExit = 1;
+
+	for (exitPtr = tsdPtr->firstExitPtr; exitPtr != NULL;
+		exitPtr = tsdPtr->firstExitPtr) {
+	    /*
+	     * Be careful to remove the handler from the list before invoking
+	     * its callback. This protects us against double-freeing if the
+	     * callback should call Tcl_DeleteThreadExitHandler on itself.
+	     */
+
+	    tsdPtr->firstExitPtr = exitPtr->nextPtr;
+	    exitPtr->proc(exitPtr->clientData);
+	    ckfree(exitPtr);
+	}
+	TclFinalizeIOSubsystem();
+	TclFinalizeNotifier();
+	TclFinalizeAsync();
+	TclFinalizeThreadObjects();
+    }
+
+    /*
+     * Blow away all thread local storage blocks.
+     *
+     * Note that Tcl API allows creation of threads which do not use any Tcl
+     * interp or other Tcl subsytems. Those threads might, however, use thread
+     * local storage, so we must unconditionally finalize it.
+     *
+     * Fix [Bug #571002]
+     */
+    TclFinalizeThreadData(quick);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclInExit --
+ *
+ *	Determines if we are in the middle of exit-time cleanup.
+ *
+ * Results:
+ *	If we are in the middle of exiting, 1, otherwise 0.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclInExit(void)
+{
+    return inExit;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclInThreadExit --
+ *
+ *	Determines if we are in the middle of thread exit-time cleanup.
+ *
+ * Results:
+ *	If we are in the middle of exiting this thread, 1, otherwise 0.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclInThreadExit(void)
+{
+    ThreadSpecificData *tsdPtr = TclThreadDataKeyGet(&dataKey);
+
+    if (tsdPtr == NULL) {
+	return 0;
+    }
+    return tsdPtr->inExit;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_VwaitObjCmd --
+ *
+ *	This function is invoked to process the "vwait" Tcl command. See the
+ *	user documentation for details on what it does.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+	/* ARGSUSED */
+int
+Tcl_VwaitObjCmd(
+    ClientData clientData,	/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    int done, foundEvent;
+    const char *nameString;
+
+    if (objc != 2) {
+	Tcl_WrongNumArgs(interp, 1, objv, "name");
+	return TCL_ERROR;
+    }
+    nameString = Tcl_GetString(objv[1]);
+    if (Tcl_TraceVar2(interp, nameString, NULL,
+	    TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
+	    VwaitVarProc, &done) != TCL_OK) {
+	return TCL_ERROR;
+    };
+    done = 0;
+    foundEvent = 1;
+    while (!done && foundEvent) {
+	foundEvent = Tcl_DoOneEvent(TCL_ALL_EVENTS);
+	if (Tcl_Canceled(interp, TCL_LEAVE_ERR_MSG) == TCL_ERROR) {
+	    break;
+	}
+	if (Tcl_LimitExceeded(interp)) {
+	    Tcl_ResetResult(interp);
+	    Tcl_SetObjResult(interp, Tcl_NewStringObj("limit exceeded", -1));
+	    break;
+	}
+    }
+    Tcl_UntraceVar2(interp, nameString, NULL,
+	    TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
+	    VwaitVarProc, &done);
+
+    if (!foundEvent) {
+	Tcl_ResetResult(interp);
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		"can't wait for variable \"%s\": would wait forever",
+		nameString));
+	Tcl_SetErrorCode(interp, "TCL", "EVENT", "NO_SOURCES", NULL);
+	return TCL_ERROR;
+    }
+    if (!done) {
+	/*
+	 * The interpreter's result was already set to the right error message
+	 * prior to exiting the loop above.
+	 */
+
+	return TCL_ERROR;
+    }
+
+    /*
+     * Clear out the interpreter's result, since it may have been set by event
+     * handlers.
+     */
+
+    Tcl_ResetResult(interp);
+    return TCL_OK;
+}
+
+	/* ARGSUSED */
+static char *
+VwaitVarProc(
+    ClientData clientData,	/* Pointer to integer to set to 1. */
+    Tcl_Interp *interp,		/* Interpreter containing variable. */
+    const char *name1,		/* Name of variable. */
+    const char *name2,		/* Second part of variable name. */
+    int flags)			/* Information about what happened. */
+{
+    int *donePtr = clientData;
+
+    *donePtr = 1;
+    Tcl_UntraceVar(interp, name1, TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
+	    VwaitVarProc, clientData);
+    return NULL;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_UpdateObjCmd --
+ *
+ *	This function is invoked to process the "update" Tcl command. See the
+ *	user documentation for details on what it does.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+	/* ARGSUSED */
+int
+Tcl_UpdateObjCmd(
+    ClientData clientData,	/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    int optionIndex;
+    int flags = 0;		/* Initialized to avoid compiler warning. */
+    static const char *const updateOptions[] = {"idletasks", NULL};
+    enum updateOptions {OPT_IDLETASKS};
+
+    if (objc == 1) {
+	flags = TCL_ALL_EVENTS|TCL_DONT_WAIT;
+    } else if (objc == 2) {
+	if (Tcl_GetIndexFromObj(interp, objv[1], updateOptions,
+		"option", 0, &optionIndex) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	switch ((enum updateOptions) optionIndex) {
+	case OPT_IDLETASKS:
+	    flags = TCL_WINDOW_EVENTS|TCL_IDLE_EVENTS|TCL_DONT_WAIT;
+	    break;
+	default:
+	    Tcl_Panic("Tcl_UpdateObjCmd: bad option index to UpdateOptions");
+	}
+    } else {
+	Tcl_WrongNumArgs(interp, 1, objv, "?idletasks?");
+	return TCL_ERROR;
+    }
+
+    while (Tcl_DoOneEvent(flags) != 0) {
+	if (Tcl_Canceled(interp, TCL_LEAVE_ERR_MSG) == TCL_ERROR) {
+	    return TCL_ERROR;
+	}
+	if (Tcl_LimitExceeded(interp)) {
+	    Tcl_ResetResult(interp);
+	    Tcl_SetObjResult(interp, Tcl_NewStringObj("limit exceeded", -1));
+	    return TCL_ERROR;
+	}
+    }
+
+    /*
+     * Must clear the interpreter's result because event handlers could have
+     * executed commands.
+     */
+
+    Tcl_ResetResult(interp);
+    return TCL_OK;
+}
+
+#ifdef TCL_THREADS
+/*
+ *----------------------------------------------------------------------
+ *
+ * NewThreadProc --
+ *
+ *	Bootstrap function of a new Tcl thread.
+ *
+ * Results:
+ *	None.
+ *
+ * Side Effects:
+ *	Initializes Tcl notifier for the current thread.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static Tcl_ThreadCreateType
+NewThreadProc(
+    ClientData clientData)
+{
+    ThreadClientData *cdPtr = clientData;
+    ClientData threadClientData;
+    Tcl_ThreadCreateProc *threadProc;
+
+    threadProc = cdPtr->proc;
+    threadClientData = cdPtr->clientData;
+    ckfree(clientData);		/* Allocated in Tcl_CreateThread() */
+
+    threadProc(threadClientData);
+
+    TCL_THREAD_CREATE_RETURN;
+}
+#endif
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_CreateThread --
+ *
+ *	This function creates a new thread. This actually belongs to the
+ *	tclThread.c file but since we use some private data structures local
+ *	to this file, it is placed here.
+ *
+ * Results:
+ *	TCL_OK if the thread could be created. The thread ID is returned in a
+ *	parameter.
+ *
+ * Side effects:
+ *	A new thread is created.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_CreateThread(
+    Tcl_ThreadId *idPtr,	/* Return, the ID of the thread */
+    Tcl_ThreadCreateProc *proc,	/* Main() function of the thread */
+    ClientData clientData,	/* The one argument to Main() */
+    int stackSize,		/* Size of stack for the new thread */
+    int flags)			/* Flags controlling behaviour of the new
+				 * thread. */
+{
+#ifdef TCL_THREADS
+    ThreadClientData *cdPtr = ckalloc(sizeof(ThreadClientData));
+    int result;
+
+    cdPtr->proc = proc;
+    cdPtr->clientData = clientData;
+    result = TclpThreadCreate(idPtr, NewThreadProc, cdPtr, stackSize, flags);
+    if (result != TCL_OK) {
+	ckfree(cdPtr);
+    }
+    return result;
+#else
+    return TCL_ERROR;
+#endif /* TCL_THREADS */
+}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tclExecute.c b/generic/tclExecute.c
new file mode 100644
index 0000000..e539161
--- /dev/null
+++ b/generic/tclExecute.c
@@ -0,0 +1,10754 @@
+/*
+ * tclExecute.c --
+ *
+ *	This file contains procedures that execute byte-compiled Tcl commands.
+ *
+ * Copyright (c) 1996-1997 Sun Microsystems, Inc.
+ * Copyright (c) 1998-2000 by Scriptics Corporation.
+ * Copyright (c) 2001 by Kevin B. Kenny. All rights reserved.
+ * Copyright (c) 2002-2010 by Miguel Sofer.
+ * Copyright (c) 2005-2007 by Donal K. Fellows.
+ * Copyright (c) 2007 Daniel A. Steffen <das@users.sourceforge.net>
+ * Copyright (c) 2006-2008 by Joe Mistachkin.  All rights reserved.
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#include "tclInt.h"
+#include "tclCompile.h"
+#include "tclOOInt.h"
+#include "tommath.h"
+#include "tclStringRep.h"
+#include <math.h>
+#include <assert.h>
+
+/*
+ * Hack to determine whether we may expect IEEE floating point. The hack is
+ * formally incorrect in that non-IEEE platforms might have the same precision
+ * and range, but VAX, IBM, and Cray do not; are there any other floating
+ * point units that we might care about?
+ */
+
+#if (FLT_RADIX == 2) && (DBL_MANT_DIG == 53) && (DBL_MAX_EXP == 1024)
+#define IEEE_FLOATING_POINT
+#endif
+
+/*
+ * A mask (should be 2**n-1) that is used to work out when the bytecode engine
+ * should call Tcl_AsyncReady() to see whether there is a signal that needs
+ * handling.
+ */
+
+#ifndef ASYNC_CHECK_COUNT_MASK
+#   define ASYNC_CHECK_COUNT_MASK	63
+#endif /* !ASYNC_CHECK_COUNT_MASK */
+
+/*
+ * Boolean flag indicating whether the Tcl bytecode interpreter has been
+ * initialized.
+ */
+
+static int execInitialized = 0;
+TCL_DECLARE_MUTEX(execMutex)
+
+static int cachedInExit = 0;
+
+#ifdef TCL_COMPILE_DEBUG
+/*
+ * Variable that controls whether execution tracing is enabled and, if so,
+ * what level of tracing is desired:
+ *    0: no execution tracing
+ *    1: trace invocations of Tcl procs only
+ *    2: trace invocations of all (not compiled away) commands
+ *    3: display each instruction executed
+ * This variable is linked to the Tcl variable "tcl_traceExec".
+ */
+
+int tclTraceExec = 0;
+#endif
+
+/*
+ * Mapping from expression instruction opcodes to strings; used for error
+ * messages. Note that these entries must match the order and number of the
+ * expression opcodes (e.g., INST_LOR) in tclCompile.h.
+ *
+ * Does not include the string for INST_EXPON (and beyond), as that is
+ * disjoint for backward-compatability reasons.
+ */
+
+static const char *const operatorStrings[] = {
+    "||", "&&", "|", "^", "&", "==", "!=", "<", ">", "<=", ">=", "<<", ">>",
+    "+", "-", "*", "/", "%", "+", "-", "~", "!"
+};
+
+/*
+ * Mapping from Tcl result codes to strings; used for error and debugging
+ * messages.
+ */
+
+#ifdef TCL_COMPILE_DEBUG
+static const char *const resultStrings[] = {
+    "TCL_OK", "TCL_ERROR", "TCL_RETURN", "TCL_BREAK", "TCL_CONTINUE"
+};
+#endif
+
+/*
+ * These are used by evalstats to monitor object usage in Tcl.
+ */
+
+#ifdef TCL_COMPILE_STATS
+long		tclObjsAlloced = 0;
+long		tclObjsFreed = 0;
+long		tclObjsShared[TCL_MAX_SHARED_OBJ_STATS] = { 0, 0, 0, 0, 0 };
+#endif /* TCL_COMPILE_STATS */
+
+/*
+ * Support pre-8.5 bytecodes unless specifically requested otherwise.
+ */
+
+#ifndef TCL_SUPPORT_84_BYTECODE
+#define TCL_SUPPORT_84_BYTECODE 1
+#endif
+
+#if TCL_SUPPORT_84_BYTECODE
+/*
+ * We need to know the tclBuiltinFuncTable to support translation of pre-8.5
+ * math functions to the namespace-based ::tcl::mathfunc::op in 8.5+.
+ */
+
+typedef struct {
+    const char *name;		/* Name of function. */
+    int numArgs;		/* Number of arguments for function. */
+} BuiltinFunc;
+
+/*
+ * Table describing the built-in math functions. Entries in this table are
+ * indexed by the values of the INST_CALL_BUILTIN_FUNC instruction's
+ * operand byte.
+ */
+
+static BuiltinFunc const tclBuiltinFuncTable[] = {
+    {"acos", 1},
+    {"asin", 1},
+    {"atan", 1},
+    {"atan2", 2},
+    {"ceil", 1},
+    {"cos", 1},
+    {"cosh", 1},
+    {"exp", 1},
+    {"floor", 1},
+    {"fmod", 2},
+    {"hypot", 2},
+    {"log", 1},
+    {"log10", 1},
+    {"pow", 2},
+    {"sin", 1},
+    {"sinh", 1},
+    {"sqrt", 1},
+    {"tan", 1},
+    {"tanh", 1},
+    {"abs", 1},
+    {"double", 1},
+    {"int", 1},
+    {"rand", 0},
+    {"round", 1},
+    {"srand", 1},
+    {"wide", 1},
+    {NULL, 0},
+};
+
+#define LAST_BUILTIN_FUNC	25
+#endif
+
+/*
+ * NR_TEBC
+ * Helpers for NR - non-recursive calls to TEBC
+ * Minimal data required to fully reconstruct the execution state.
+ */
+
+typedef struct TEBCdata {
+    ByteCode *codePtr;		/* Constant until the BC returns */
+				/* -----------------------------------------*/
+    ptrdiff_t *catchTop;	/* These fields are used on return TO this */
+    Tcl_Obj *auxObjList;	/* this level: they record the state when a */
+    CmdFrame cmdFrame;		/* new codePtr was received for NR */
+                                /* execution. */
+    void *stack[1];		/* Start of the actual combined catch and obj
+				 * stacks; the struct will be expanded as
+				 * necessary */
+} TEBCdata;
+
+#define TEBC_YIELD() \
+    do {						\
+	esPtr->tosPtr = tosPtr;				\
+	TclNRAddCallback(interp, TEBCresume,		\
+		TD, pc, INT2PTR(cleanup), NULL);	\
+    } while (0)
+
+#define TEBC_DATA_DIG() \
+    do {					\
+	tosPtr = esPtr->tosPtr;			\
+    } while (0)
+
+#define PUSH_TAUX_OBJ(objPtr) \
+    do {							\
+	if (auxObjList) {					\
+	    objPtr->length += auxObjList->length;		\
+	}							\
+	objPtr->internalRep.twoPtrValue.ptr1 = auxObjList;	\
+	auxObjList = objPtr;					\
+    } while (0)
+
+#define POP_TAUX_OBJ() \
+    do {							\
+	tmpPtr = auxObjList;					\
+	auxObjList = tmpPtr->internalRep.twoPtrValue.ptr1;	\
+	Tcl_DecrRefCount(tmpPtr);				\
+    } while (0)
+
+/*
+ * These variable-access macros have to coincide with those in tclVar.c
+ */
+
+#define VarHashGetValue(hPtr) \
+    ((Var *) ((char *)hPtr - TclOffset(VarInHash, entry)))
+
+static inline Var *
+VarHashCreateVar(
+    TclVarHashTable *tablePtr,
+    Tcl_Obj *key,
+    int *newPtr)
+{
+    Tcl_HashEntry *hPtr = Tcl_CreateHashEntry(&tablePtr->table,
+	    key, newPtr);
+
+    if (!hPtr) {
+	return NULL;
+    }
+    return VarHashGetValue(hPtr);
+}
+
+#define VarHashFindVar(tablePtr, key) \
+    VarHashCreateVar((tablePtr), (key), NULL)
+
+/*
+ * The new macro for ending an instruction; note that a reasonable C-optimiser
+ * will resolve all branches at compile time. (result) is always a constant;
+ * the macro NEXT_INST_F handles constant (nCleanup), NEXT_INST_V is resolved
+ * at runtime for variable (nCleanup).
+ *
+ * ARGUMENTS:
+ *    pcAdjustment: how much to increment pc
+ *    nCleanup: how many objects to remove from the stack
+ *    resultHandling: 0 indicates no object should be pushed on the stack;
+ *	otherwise, push objResultPtr. If (result < 0), objResultPtr already
+ *	has the correct reference count.
+ *
+ * We use the new compile-time assertions to check that nCleanup is constant
+ * and within range.
+ */
+
+/* Verify the stack depth, only when no expansion is in progress */
+
+#ifdef TCL_COMPILE_DEBUG
+#define CHECK_STACK()							\
+    do {								\
+	ValidatePcAndStackTop(codePtr, pc, CURR_DEPTH,			\
+		/*checkStack*/ !(starting || auxObjList));		\
+	starting = 0;							\
+    } while (0)
+#else
+#define CHECK_STACK()
+#endif
+
+#define NEXT_INST_F(pcAdjustment, nCleanup, resultHandling)	\
+    do {							\
+	TCL_CT_ASSERT((nCleanup >= 0) && (nCleanup <= 2));	\
+	CHECK_STACK();						\
+	if (nCleanup == 0) {					\
+	    if (resultHandling != 0) {				\
+		if ((resultHandling) > 0) {			\
+		    PUSH_OBJECT(objResultPtr);			\
+		} else {					\
+		    *(++tosPtr) = objResultPtr;			\
+		}						\
+	    }							\
+	    pc += (pcAdjustment);				\
+	    goto cleanup0;					\
+	} else if (resultHandling != 0) {			\
+	    if ((resultHandling) > 0) {				\
+		Tcl_IncrRefCount(objResultPtr);			\
+	    }							\
+	    pc += (pcAdjustment);				\
+	    switch (nCleanup) {					\
+	    case 1: goto cleanup1_pushObjResultPtr;		\
+	    case 2: goto cleanup2_pushObjResultPtr;		\
+	    case 0: break;					\
+	    }							\
+	} else {						\
+	    pc += (pcAdjustment);				\
+	    switch (nCleanup) {					\
+	    case 1: goto cleanup1;				\
+	    case 2: goto cleanup2;				\
+	    case 0: break;					\
+	    }							\
+	}							\
+    } while (0)
+
+#define NEXT_INST_V(pcAdjustment, nCleanup, resultHandling)	\
+    CHECK_STACK();						\
+    do {							\
+	pc += (pcAdjustment);					\
+	cleanup = (nCleanup);					\
+	if (resultHandling) {					\
+	    if ((resultHandling) > 0) {				\
+		Tcl_IncrRefCount(objResultPtr);			\
+	    }							\
+	    goto cleanupV_pushObjResultPtr;			\
+	} else {						\
+	    goto cleanupV;					\
+	}							\
+    } while (0)
+
+#ifndef TCL_COMPILE_DEBUG
+#define JUMP_PEEPHOLE_F(condition, pcAdjustment, cleanup) \
+    do {								\
+	pc += (pcAdjustment);						\
+	switch (*pc) {							\
+	case INST_JUMP_FALSE1:						\
+	    NEXT_INST_F(((condition)? 2 : TclGetInt1AtPtr(pc+1)), (cleanup), 0); \
+	case INST_JUMP_TRUE1:						\
+	    NEXT_INST_F(((condition)? TclGetInt1AtPtr(pc+1) : 2), (cleanup), 0); \
+	case INST_JUMP_FALSE4:						\
+	    NEXT_INST_F(((condition)? 5 : TclGetInt4AtPtr(pc+1)), (cleanup), 0); \
+	case INST_JUMP_TRUE4:						\
+	    NEXT_INST_F(((condition)? TclGetInt4AtPtr(pc+1) : 5), (cleanup), 0); \
+	default:							\
+	    if ((condition) < 0) {					\
+		TclNewIntObj(objResultPtr, -1);				\
+	    } else {							\
+		objResultPtr = TCONST((condition) > 0);			\
+	    }								\
+	    NEXT_INST_F(0, (cleanup), 1);				\
+	}								\
+    } while (0)
+#define JUMP_PEEPHOLE_V(condition, pcAdjustment, cleanup) \
+    do {								\
+	pc += (pcAdjustment);						\
+	switch (*pc) {							\
+	case INST_JUMP_FALSE1:						\
+	    NEXT_INST_V(((condition)? 2 : TclGetInt1AtPtr(pc+1)), (cleanup), 0); \
+	case INST_JUMP_TRUE1:						\
+	    NEXT_INST_V(((condition)? TclGetInt1AtPtr(pc+1) : 2), (cleanup), 0); \
+	case INST_JUMP_FALSE4:						\
+	    NEXT_INST_V(((condition)? 5 : TclGetInt4AtPtr(pc+1)), (cleanup), 0); \
+	case INST_JUMP_TRUE4:						\
+	    NEXT_INST_V(((condition)? TclGetInt4AtPtr(pc+1) : 5), (cleanup), 0); \
+	default:							\
+	    if ((condition) < 0) {					\
+		TclNewIntObj(objResultPtr, -1);				\
+	    } else {							\
+		objResultPtr = TCONST((condition) > 0);			\
+	    }								\
+	    NEXT_INST_V(0, (cleanup), 1);				\
+	}								\
+    } while (0)
+#else /* TCL_COMPILE_DEBUG */
+#define JUMP_PEEPHOLE_F(condition, pcAdjustment, cleanup) \
+    do{									\
+	if ((condition) < 0) {						\
+	    TclNewIntObj(objResultPtr, -1);				\
+	} else {							\
+	    objResultPtr = TCONST((condition) > 0);			\
+	}								\
+	NEXT_INST_F((pcAdjustment), (cleanup), 1);			\
+    } while (0)
+#define JUMP_PEEPHOLE_V(condition, pcAdjustment, cleanup) \
+    do{									\
+	if ((condition) < 0) {						\
+	    TclNewIntObj(objResultPtr, -1);				\
+	} else {							\
+	    objResultPtr = TCONST((condition) > 0);			\
+	}								\
+	NEXT_INST_V((pcAdjustment), (cleanup), 1);			\
+    } while (0)
+#endif
+
+/*
+ * Macros used to cache often-referenced Tcl evaluation stack information
+ * in local variables. Note that a DECACHE_STACK_INFO()-CACHE_STACK_INFO()
+ * pair must surround any call inside TclNRExecuteByteCode (and a few other
+ * procedures that use this scheme) that could result in a recursive call
+ * to TclNRExecuteByteCode.
+ */
+
+#define CACHE_STACK_INFO() \
+    checkInterp = 1
+
+#define DECACHE_STACK_INFO() \
+    esPtr->tosPtr = tosPtr
+
+/*
+ * Macros used to access items on the Tcl evaluation stack. PUSH_OBJECT
+ * increments the object's ref count since it makes the stack have another
+ * reference pointing to the object. However, POP_OBJECT does not decrement
+ * the ref count. This is because the stack may hold the only reference to the
+ * object, so the object would be destroyed if its ref count were decremented
+ * before the caller had a chance to, e.g., store it in a variable. It is the
+ * caller's responsibility to decrement the ref count when it is finished with
+ * an object.
+ *
+ * WARNING! It is essential that objPtr only appear once in the PUSH_OBJECT
+ * macro. The actual parameter might be an expression with side effects, and
+ * this ensures that it will be executed only once.
+ */
+
+#define PUSH_OBJECT(objPtr) \
+    Tcl_IncrRefCount(*(++tosPtr) = (objPtr))
+
+#define POP_OBJECT()	*(tosPtr--)
+
+#define OBJ_AT_TOS	*tosPtr
+
+#define OBJ_UNDER_TOS	*(tosPtr-1)
+
+#define OBJ_AT_DEPTH(n)	*(tosPtr-(n))
+
+#define CURR_DEPTH	((ptrdiff_t) (tosPtr - initTosPtr))
+
+#define STACK_BASE(esPtr) ((esPtr)->stackWords - 1)
+
+/*
+ * Macros used to trace instruction execution. The macros TRACE,
+ * TRACE_WITH_OBJ, and O2S are only used inside TclNRExecuteByteCode. O2S is
+ * only used in TRACE* calls to get a string from an object.
+ */
+
+#ifdef TCL_COMPILE_DEBUG
+#   define TRACE(a) \
+    while (traceInstructions) {					\
+	fprintf(stdout, "%2d: %2d (%u) %s ", iPtr->numLevels,	\
+		(int) CURR_DEPTH,				\
+		(unsigned) (pc - codePtr->codeStart),		\
+		GetOpcodeName(pc));				\
+	printf a;						\
+	break;							\
+    }
+#   define TRACE_APPEND(a) \
+    while (traceInstructions) {		\
+	printf a;			\
+	break;				\
+    }
+#   define TRACE_ERROR(interp) \
+    TRACE_APPEND(("ERROR: %.30s\n", O2S(Tcl_GetObjResult(interp))));
+#   define TRACE_WITH_OBJ(a, objPtr) \
+    while (traceInstructions) {					\
+	fprintf(stdout, "%2d: %2d (%u) %s ", iPtr->numLevels,	\
+		(int) CURR_DEPTH,				\
+		(unsigned) (pc - codePtr->codeStart),		\
+		GetOpcodeName(pc));				\
+	printf a;						\
+	TclPrintObject(stdout, objPtr, 30);			\
+	fprintf(stdout, "\n");					\
+	break;							\
+    }
+#   define O2S(objPtr) \
+    (objPtr ? TclGetString(objPtr) : "")
+#else /* !TCL_COMPILE_DEBUG */
+#   define TRACE(a)
+#   define TRACE_APPEND(a)
+#   define TRACE_ERROR(interp)
+#   define TRACE_WITH_OBJ(a, objPtr)
+#   define O2S(objPtr)
+#endif /* TCL_COMPILE_DEBUG */
+
+/*
+ * DTrace instruction probe macros.
+ */
+
+#define TCL_DTRACE_INST_NEXT() \
+    do {								\
+	if (TCL_DTRACE_INST_DONE_ENABLED()) {				\
+	    if (curInstName) {						\
+		TCL_DTRACE_INST_DONE(curInstName, (int) CURR_DEPTH,	\
+			tosPtr);					\
+	    }								\
+	    curInstName = tclInstructionTable[*pc].name;		\
+	    if (TCL_DTRACE_INST_START_ENABLED()) {			\
+		TCL_DTRACE_INST_START(curInstName, (int) CURR_DEPTH,	\
+			tosPtr);					\
+	    }								\
+	} else if (TCL_DTRACE_INST_START_ENABLED()) {			\
+	    TCL_DTRACE_INST_START(tclInstructionTable[*pc].name,	\
+			(int) CURR_DEPTH, tosPtr);			\
+	}								\
+    } while (0)
+#define TCL_DTRACE_INST_LAST() \
+    do {								\
+	if (TCL_DTRACE_INST_DONE_ENABLED() && curInstName) {		\
+	    TCL_DTRACE_INST_DONE(curInstName, (int) CURR_DEPTH, tosPtr);\
+	}								\
+    } while (0)
+
+/*
+ * Macro used in this file to save a function call for common uses of
+ * TclGetNumberFromObj(). The ANSI C "prototype" is:
+ *
+ * MODULE_SCOPE int GetNumberFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr,
+ *			ClientData *ptrPtr, int *tPtr);
+ */
+
+#ifdef TCL_WIDE_INT_IS_LONG
+#define GetNumberFromObj(interp, objPtr, ptrPtr, tPtr) \
+    (((objPtr)->typePtr == &tclIntType)					\
+	?	(*(tPtr) = TCL_NUMBER_LONG,				\
+		*(ptrPtr) = (ClientData)				\
+		    (&((objPtr)->internalRep.longValue)), TCL_OK) :	\
+    ((objPtr)->typePtr == &tclDoubleType)				\
+	?	(((TclIsNaN((objPtr)->internalRep.doubleValue))		\
+		    ?	(*(tPtr) = TCL_NUMBER_NAN)			\
+		    :	(*(tPtr) = TCL_NUMBER_DOUBLE)),			\
+		*(ptrPtr) = (ClientData)				\
+		    (&((objPtr)->internalRep.doubleValue)), TCL_OK) :	\
+    ((((objPtr)->typePtr == NULL) && ((objPtr)->bytes == NULL)) ||	\
+    (((objPtr)->bytes != NULL) && ((objPtr)->length == 0)))		\
+	? (*(tPtr) = TCL_NUMBER_LONG),TCL_ERROR :			\
+    TclGetNumberFromObj((interp), (objPtr), (ptrPtr), (tPtr)))
+#else /* !TCL_WIDE_INT_IS_LONG */
+#define GetNumberFromObj(interp, objPtr, ptrPtr, tPtr) \
+    (((objPtr)->typePtr == &tclIntType)					\
+	?	(*(tPtr) = TCL_NUMBER_LONG,				\
+		*(ptrPtr) = (ClientData)				\
+		    (&((objPtr)->internalRep.longValue)), TCL_OK) :	\
+    ((objPtr)->typePtr == &tclWideIntType)				\
+	?	(*(tPtr) = TCL_NUMBER_WIDE,				\
+		*(ptrPtr) = (ClientData)				\
+		    (&((objPtr)->internalRep.wideValue)), TCL_OK) :	\
+    ((objPtr)->typePtr == &tclDoubleType)				\
+	?	(((TclIsNaN((objPtr)->internalRep.doubleValue))		\
+		    ?	(*(tPtr) = TCL_NUMBER_NAN)			\
+		    :	(*(tPtr) = TCL_NUMBER_DOUBLE)),			\
+		*(ptrPtr) = (ClientData)				\
+		    (&((objPtr)->internalRep.doubleValue)), TCL_OK) :	\
+    ((((objPtr)->typePtr == NULL) && ((objPtr)->bytes == NULL)) ||	\
+    (((objPtr)->bytes != NULL) && ((objPtr)->length == 0)))		\
+	? (*(tPtr) = TCL_NUMBER_LONG),TCL_ERROR :			\
+    TclGetNumberFromObj((interp), (objPtr), (ptrPtr), (tPtr)))
+#endif /* TCL_WIDE_INT_IS_LONG */
+
+/*
+ * Macro used in this file to save a function call for common uses of
+ * Tcl_GetBooleanFromObj(). The ANSI C "prototype" is:
+ *
+ * MODULE_SCOPE int TclGetBooleanFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr,
+ *			int *boolPtr);
+ */
+
+#define TclGetBooleanFromObj(interp, objPtr, boolPtr) \
+    ((((objPtr)->typePtr == &tclIntType)				\
+	|| ((objPtr)->typePtr == &tclBooleanType))			\
+	? (*(boolPtr) = ((objPtr)->internalRep.longValue!=0), TCL_OK)	\
+	: Tcl_GetBooleanFromObj((interp), (objPtr), (boolPtr)))
+
+/*
+ * Macro used to make the check for type overflow more mnemonic. This works by
+ * comparing sign bits; the rest of the word is irrelevant. The ANSI C
+ * "prototype" (where inttype_t is any integer type) is:
+ *
+ * MODULE_SCOPE int Overflowing(inttype_t a, inttype_t b, inttype_t sum);
+ *
+ * Check first the condition most likely to fail in usual code (at least for
+ * usage in [incr]: do the first summand and the sum have != signs?
+ */
+
+#define Overflowing(a,b,sum) ((((a)^(sum)) < 0) && (((a)^(b)) >= 0))
+
+/*
+ * Macro for checking whether the type is NaN, used when we're thinking about
+ * throwing an error for supplying a non-number number.
+ */
+
+#ifndef ACCEPT_NAN
+#define IsErroringNaNType(type)		((type) == TCL_NUMBER_NAN)
+#else
+#define IsErroringNaNType(type)		0
+#endif
+
+/*
+ * Auxiliary tables used to compute powers of small integers.
+ */
+
+#if (LONG_MAX == 0x7fffffff)
+
+/*
+ * Maximum base that, when raised to powers 2, 3, ... 8, fits in a 32-bit
+ * signed integer.
+ */
+
+static const long MaxBase32[] = {46340, 1290, 215, 73, 35, 21, 14};
+static const size_t MaxBase32Size = sizeof(MaxBase32)/sizeof(long);
+
+/*
+ * Table giving 3, 4, ..., 11, raised to the powers 9, 10, ..., as far as they
+ * fit in a 32-bit signed integer. Exp32Index[i] gives the starting index of
+ * powers of i+3; Exp32Value[i] gives the corresponding powers.
+ */
+
+static const unsigned short Exp32Index[] = {
+    0, 11, 18, 23, 26, 29, 31, 32, 33
+};
+static const size_t Exp32IndexSize =
+    sizeof(Exp32Index) / sizeof(unsigned short);
+static const long Exp32Value[] = {
+    19683, 59049, 177147, 531441, 1594323, 4782969, 14348907, 43046721,
+    129140163, 387420489, 1162261467, 262144, 1048576, 4194304,
+    16777216, 67108864, 268435456, 1073741824, 1953125, 9765625,
+    48828125, 244140625, 1220703125, 10077696, 60466176, 362797056,
+    40353607, 282475249, 1977326743, 134217728, 1073741824, 387420489,
+    1000000000
+};
+static const size_t Exp32ValueSize = sizeof(Exp32Value)/sizeof(long);
+#endif /* LONG_MAX == 0x7fffffff -- 32 bit machine */
+
+#if (LONG_MAX > 0x7fffffff) || !defined(TCL_WIDE_INT_IS_LONG)
+
+/*
+ * Maximum base that, when raised to powers 2, 3, ..., 16, fits in a
+ * Tcl_WideInt.
+ */
+
+static const Tcl_WideInt MaxBase64[] = {
+    (Tcl_WideInt)46340*65536+62259,	/* 3037000499 == isqrt(2**63-1) */
+    (Tcl_WideInt)2097151, (Tcl_WideInt)55108, (Tcl_WideInt)6208,
+    (Tcl_WideInt)1448, (Tcl_WideInt)511, (Tcl_WideInt)234, (Tcl_WideInt)127,
+    (Tcl_WideInt)78, (Tcl_WideInt)52, (Tcl_WideInt)38, (Tcl_WideInt)28,
+    (Tcl_WideInt)22, (Tcl_WideInt)18, (Tcl_WideInt)15
+};
+static const size_t MaxBase64Size = sizeof(MaxBase64)/sizeof(Tcl_WideInt);
+
+/*
+ * Table giving 3, 4, ..., 13 raised to powers greater than 16 when the
+ * results fit in a 64-bit signed integer.
+ */
+
+static const unsigned short Exp64Index[] = {
+    0, 23, 38, 49, 57, 63, 67, 70, 72, 74, 75, 76
+};
+static const size_t Exp64IndexSize =
+    sizeof(Exp64Index) / sizeof(unsigned short);
+static const Tcl_WideInt Exp64Value[] = {
+    (Tcl_WideInt)243*243*243*3*3,
+    (Tcl_WideInt)243*243*243*3*3*3,
+    (Tcl_WideInt)243*243*243*3*3*3*3,
+    (Tcl_WideInt)243*243*243*243,
+    (Tcl_WideInt)243*243*243*243*3,
+    (Tcl_WideInt)243*243*243*243*3*3,
+    (Tcl_WideInt)243*243*243*243*3*3*3,
+    (Tcl_WideInt)243*243*243*243*3*3*3*3,
+    (Tcl_WideInt)243*243*243*243*243,
+    (Tcl_WideInt)243*243*243*243*243*3,
+    (Tcl_WideInt)243*243*243*243*243*3*3,
+    (Tcl_WideInt)243*243*243*243*243*3*3*3,
+    (Tcl_WideInt)243*243*243*243*243*3*3*3*3,
+    (Tcl_WideInt)243*243*243*243*243*243,
+    (Tcl_WideInt)243*243*243*243*243*243*3,
+    (Tcl_WideInt)243*243*243*243*243*243*3*3,
+    (Tcl_WideInt)243*243*243*243*243*243*3*3*3,
+    (Tcl_WideInt)243*243*243*243*243*243*3*3*3*3,
+    (Tcl_WideInt)243*243*243*243*243*243*243,
+    (Tcl_WideInt)243*243*243*243*243*243*243*3,
+    (Tcl_WideInt)243*243*243*243*243*243*243*3*3,
+    (Tcl_WideInt)243*243*243*243*243*243*243*3*3*3,
+    (Tcl_WideInt)243*243*243*243*243*243*243*3*3*3*3,
+    (Tcl_WideInt)1024*1024*1024*4*4,
+    (Tcl_WideInt)1024*1024*1024*4*4*4,
+    (Tcl_WideInt)1024*1024*1024*4*4*4*4,
+    (Tcl_WideInt)1024*1024*1024*1024,
+    (Tcl_WideInt)1024*1024*1024*1024*4,
+    (Tcl_WideInt)1024*1024*1024*1024*4*4,
+    (Tcl_WideInt)1024*1024*1024*1024*4*4*4,
+    (Tcl_WideInt)1024*1024*1024*1024*4*4*4*4,
+    (Tcl_WideInt)1024*1024*1024*1024*1024,
+    (Tcl_WideInt)1024*1024*1024*1024*1024*4,
+    (Tcl_WideInt)1024*1024*1024*1024*1024*4*4,
+    (Tcl_WideInt)1024*1024*1024*1024*1024*4*4*4,
+    (Tcl_WideInt)1024*1024*1024*1024*1024*4*4*4*4,
+    (Tcl_WideInt)1024*1024*1024*1024*1024*1024,
+    (Tcl_WideInt)1024*1024*1024*1024*1024*1024*4,
+    (Tcl_WideInt)3125*3125*3125*5*5,
+    (Tcl_WideInt)3125*3125*3125*5*5*5,
+    (Tcl_WideInt)3125*3125*3125*5*5*5*5,
+    (Tcl_WideInt)3125*3125*3125*3125,
+    (Tcl_WideInt)3125*3125*3125*3125*5,
+    (Tcl_WideInt)3125*3125*3125*3125*5*5,
+    (Tcl_WideInt)3125*3125*3125*3125*5*5*5,
+    (Tcl_WideInt)3125*3125*3125*3125*5*5*5*5,
+    (Tcl_WideInt)3125*3125*3125*3125*3125,
+    (Tcl_WideInt)3125*3125*3125*3125*3125*5,
+    (Tcl_WideInt)3125*3125*3125*3125*3125*5*5,
+    (Tcl_WideInt)7776*7776*7776*6*6,
+    (Tcl_WideInt)7776*7776*7776*6*6*6,
+    (Tcl_WideInt)7776*7776*7776*6*6*6*6,
+    (Tcl_WideInt)7776*7776*7776*7776,
+    (Tcl_WideInt)7776*7776*7776*7776*6,
+    (Tcl_WideInt)7776*7776*7776*7776*6*6,
+    (Tcl_WideInt)7776*7776*7776*7776*6*6*6,
+    (Tcl_WideInt)7776*7776*7776*7776*6*6*6*6,
+    (Tcl_WideInt)16807*16807*16807*7*7,
+    (Tcl_WideInt)16807*16807*16807*7*7*7,
+    (Tcl_WideInt)16807*16807*16807*7*7*7*7,
+    (Tcl_WideInt)16807*16807*16807*16807,
+    (Tcl_WideInt)16807*16807*16807*16807*7,
+    (Tcl_WideInt)16807*16807*16807*16807*7*7,
+    (Tcl_WideInt)32768*32768*32768*8*8,
+    (Tcl_WideInt)32768*32768*32768*8*8*8,
+    (Tcl_WideInt)32768*32768*32768*8*8*8*8,
+    (Tcl_WideInt)32768*32768*32768*32768,
+    (Tcl_WideInt)59049*59049*59049*9*9,
+    (Tcl_WideInt)59049*59049*59049*9*9*9,
+    (Tcl_WideInt)59049*59049*59049*9*9*9*9,
+    (Tcl_WideInt)100000*100000*100000*10*10,
+    (Tcl_WideInt)100000*100000*100000*10*10*10,
+    (Tcl_WideInt)161051*161051*161051*11*11,
+    (Tcl_WideInt)161051*161051*161051*11*11*11,
+    (Tcl_WideInt)248832*248832*248832*12*12,
+    (Tcl_WideInt)371293*371293*371293*13*13
+};
+static const size_t Exp64ValueSize = sizeof(Exp64Value) / sizeof(Tcl_WideInt);
+#endif /* (LONG_MAX > 0x7fffffff) || !defined(TCL_WIDE_INT_IS_LONG) */
+
+/*
+ * Markers for ExecuteExtendedBinaryMathOp.
+ */
+
+#define DIVIDED_BY_ZERO		((Tcl_Obj *) -1)
+#define EXPONENT_OF_ZERO	((Tcl_Obj *) -2)
+#define GENERAL_ARITHMETIC_ERROR ((Tcl_Obj *) -3)
+
+/*
+ * Declarations for local procedures to this file:
+ */
+
+#ifdef TCL_COMPILE_STATS
+static int		EvalStatsCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+#endif /* TCL_COMPILE_STATS */
+#ifdef TCL_COMPILE_DEBUG
+static const char *	GetOpcodeName(const unsigned char *pc);
+static void		PrintByteCodeInfo(ByteCode *codePtr);
+static const char *	StringForResultCode(int result);
+static void		ValidatePcAndStackTop(ByteCode *codePtr,
+			    const unsigned char *pc, int stackTop,
+			    int checkStack);
+#endif /* TCL_COMPILE_DEBUG */
+static ByteCode *	CompileExprObj(Tcl_Interp *interp, Tcl_Obj *objPtr);
+static void		DeleteExecStack(ExecStack *esPtr);
+static void		DupExprCodeInternalRep(Tcl_Obj *srcPtr,
+			    Tcl_Obj *copyPtr);
+MODULE_SCOPE int	TclCompareTwoNumbers(Tcl_Obj *valuePtr,
+			    Tcl_Obj *value2Ptr);
+static Tcl_Obj *	ExecuteExtendedBinaryMathOp(Tcl_Interp *interp,
+			    int opcode, Tcl_Obj **constants,
+			    Tcl_Obj *valuePtr, Tcl_Obj *value2Ptr);
+static Tcl_Obj *	ExecuteExtendedUnaryMathOp(int opcode,
+			    Tcl_Obj *valuePtr);
+static void		FreeExprCodeInternalRep(Tcl_Obj *objPtr);
+static ExceptionRange *	GetExceptRangeForPc(const unsigned char *pc,
+			    int searchMode, ByteCode *codePtr);
+static const char *	GetSrcInfoForPc(const unsigned char *pc,
+			    ByteCode *codePtr, int *lengthPtr,
+			    const unsigned char **pcBeg, int *cmdIdxPtr);
+static Tcl_Obj **	GrowEvaluationStack(ExecEnv *eePtr, int growth,
+			    int move);
+static void		IllegalExprOperandType(Tcl_Interp *interp,
+			    const unsigned char *pc, Tcl_Obj *opndPtr);
+static void		InitByteCodeExecution(Tcl_Interp *interp);
+static inline int	wordSkip(void *ptr);
+static void		ReleaseDictIterator(Tcl_Obj *objPtr);
+/* Useful elsewhere, make available in tclInt.h or stubs? */
+static Tcl_Obj **	StackAllocWords(Tcl_Interp *interp, int numWords);
+static Tcl_Obj **	StackReallocWords(Tcl_Interp *interp, int numWords);
+static Tcl_NRPostProc	CopyCallback;
+static Tcl_NRPostProc	ExprObjCallback;
+static Tcl_NRPostProc	FinalizeOONext;
+static Tcl_NRPostProc	FinalizeOONextFilter;
+static Tcl_NRPostProc   TEBCresume;
+
+/*
+ * The structure below defines a bytecode Tcl object type to hold the
+ * compiled bytecode for Tcl expressions.
+ */
+
+static const Tcl_ObjType exprCodeType = {
+    "exprcode",
+    FreeExprCodeInternalRep,	/* freeIntRepProc */
+    DupExprCodeInternalRep,	/* dupIntRepProc */
+    NULL,			/* updateStringProc */
+    NULL			/* setFromAnyProc */
+};
+
+/*
+ * Custom object type only used in this file; values of its type should never
+ * be seen by user scripts.
+ */
+
+static const Tcl_ObjType dictIteratorType = {
+    "dictIterator",
+    ReleaseDictIterator,
+    NULL, NULL, NULL
+};
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ReleaseDictIterator --
+ *
+ *	This takes apart a dictionary iterator that is stored in the given Tcl
+ *	object.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Deallocates memory, marks the object as being untyped.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+ReleaseDictIterator(
+    Tcl_Obj *objPtr)
+{
+    Tcl_DictSearch *searchPtr;
+    Tcl_Obj *dictPtr;
+
+    /*
+     * First kill the search, and then release the reference to the dictionary
+     * that we were holding.
+     */
+
+    searchPtr = objPtr->internalRep.twoPtrValue.ptr1;
+    Tcl_DictObjDone(searchPtr);
+    ckfree(searchPtr);
+
+    dictPtr = objPtr->internalRep.twoPtrValue.ptr2;
+    TclDecrRefCount(dictPtr);
+
+    objPtr->typePtr = NULL;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * InitByteCodeExecution --
+ *
+ *	This procedure is called once to initialize the Tcl bytecode
+ *	interpreter.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	This procedure initializes the array of instruction names. If
+ *	compiling with the TCL_COMPILE_STATS flag, it initializes the array
+ *	that counts the executions of each instruction and it creates the
+ *	"evalstats" command. It also establishes the link between the Tcl
+ *	"tcl_traceExec" and C "tclTraceExec" variables.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+InitByteCodeExecution(
+    Tcl_Interp *interp)		/* Interpreter for which the Tcl variable
+				 * "tcl_traceExec" is linked to control
+				 * instruction tracing. */
+{
+#ifdef TCL_COMPILE_DEBUG
+    if (Tcl_LinkVar(interp, "tcl_traceExec", (char *) &tclTraceExec,
+	    TCL_LINK_INT) != TCL_OK) {
+	Tcl_Panic("InitByteCodeExecution: can't create link for tcl_traceExec variable");
+    }
+#endif
+#ifdef TCL_COMPILE_STATS
+    Tcl_CreateObjCommand(interp, "evalstats", EvalStatsCmd, NULL, NULL);
+#endif /* TCL_COMPILE_STATS */
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclCreateExecEnv --
+ *
+ *	This procedure creates a new execution environment for Tcl bytecode
+ *	execution. An ExecEnv points to a Tcl evaluation stack. An ExecEnv is
+ *	typically created once for each Tcl interpreter (Interp structure) and
+ *	recursively passed to TclNRExecuteByteCode to execute ByteCode sequences
+ *	for nested commands.
+ *
+ * Results:
+ *	A newly allocated ExecEnv is returned. This points to an empty
+ *	evaluation stack of the standard initial size.
+ *
+ * Side effects:
+ *	The bytecode interpreter is also initialized here, as this procedure
+ *	will be called before any call to TclNRExecuteByteCode.
+ *
+ *----------------------------------------------------------------------
+ */
+
+ExecEnv *
+TclCreateExecEnv(
+    Tcl_Interp *interp,		/* Interpreter for which the execution
+				 * environment is being created. */
+    int size)			/* The initial stack size, in number of words
+				 * [sizeof(Tcl_Obj*)] */
+{
+    ExecEnv *eePtr = ckalloc(sizeof(ExecEnv));
+    ExecStack *esPtr = ckalloc(sizeof(ExecStack)
+	    + (size_t) (size-1) * sizeof(Tcl_Obj *));
+
+    eePtr->execStackPtr = esPtr;
+    TclNewBooleanObj(eePtr->constants[0], 0);
+    Tcl_IncrRefCount(eePtr->constants[0]);
+    TclNewBooleanObj(eePtr->constants[1], 1);
+    Tcl_IncrRefCount(eePtr->constants[1]);
+    eePtr->interp = interp;
+    eePtr->callbackPtr = NULL;
+    eePtr->corPtr = NULL;
+    eePtr->rewind = 0;
+
+    esPtr->prevPtr = NULL;
+    esPtr->nextPtr = NULL;
+    esPtr->markerPtr = NULL;
+    esPtr->endPtr = &esPtr->stackWords[size-1];
+    esPtr->tosPtr = STACK_BASE(esPtr);
+
+    Tcl_MutexLock(&execMutex);
+    if (!execInitialized) {
+	InitByteCodeExecution(interp);
+	execInitialized = 1;
+    }
+    Tcl_MutexUnlock(&execMutex);
+
+    return eePtr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclDeleteExecEnv --
+ *
+ *	Frees the storage for an ExecEnv.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Storage for an ExecEnv and its contained storage (e.g. the evaluation
+ *	stack) is freed.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+DeleteExecStack(
+    ExecStack *esPtr)
+{
+    if (esPtr->markerPtr && !cachedInExit) {
+	Tcl_Panic("freeing an execStack which is still in use");
+    }
+
+    if (esPtr->prevPtr) {
+	esPtr->prevPtr->nextPtr = esPtr->nextPtr;
+    }
+    if (esPtr->nextPtr) {
+	esPtr->nextPtr->prevPtr = esPtr->prevPtr;
+    }
+    ckfree(esPtr);
+}
+
+void
+TclDeleteExecEnv(
+    ExecEnv *eePtr)		/* Execution environment to free. */
+{
+    ExecStack *esPtr = eePtr->execStackPtr, *tmpPtr;
+
+	cachedInExit = TclInExit();
+
+    /*
+     * Delete all stacks in this exec env.
+     */
+
+    while (esPtr->nextPtr) {
+	esPtr = esPtr->nextPtr;
+    }
+    while (esPtr) {
+	tmpPtr = esPtr;
+	esPtr = tmpPtr->prevPtr;
+	DeleteExecStack(tmpPtr);
+    }
+
+    TclDecrRefCount(eePtr->constants[0]);
+    TclDecrRefCount(eePtr->constants[1]);
+    if (eePtr->callbackPtr && !cachedInExit) {
+	Tcl_Panic("Deleting execEnv with pending TEOV callbacks!");
+    }
+    if (eePtr->corPtr && !cachedInExit) {
+	Tcl_Panic("Deleting execEnv with existing coroutine");
+    }
+    ckfree(eePtr);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclFinalizeExecution --
+ *
+ *	Finalizes the execution environment setup so that it can be later
+ *	reinitialized.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	After this call, the next time TclCreateExecEnv will be called it will
+ *	call InitByteCodeExecution.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclFinalizeExecution(void)
+{
+    Tcl_MutexLock(&execMutex);
+    execInitialized = 0;
+    Tcl_MutexUnlock(&execMutex);
+}
+
+/*
+ * Auxiliary code to insure that GrowEvaluationStack always returns correctly
+ * aligned memory.
+ *
+ * WALLOCALIGN represents the alignment reqs in words, just as TCL_ALLOCALIGN
+ * represents the reqs in bytes. This assumes that TCL_ALLOCALIGN is a
+ * multiple of the wordsize 'sizeof(Tcl_Obj *)'.
+ */
+
+#define WALLOCALIGN \
+    (TCL_ALLOCALIGN/sizeof(Tcl_Obj *))
+
+/*
+ * wordSkip computes how many words have to be skipped until the next aligned
+ * word. Note that we are only interested in the low order bits of ptr, so
+ * that any possible information loss in PTR2INT is of no consequence.
+ */
+
+static inline int
+wordSkip(
+    void *ptr)
+{
+    int mask = TCL_ALLOCALIGN-1;
+    int base = PTR2INT(ptr) & mask;
+    return (TCL_ALLOCALIGN - base)/sizeof(Tcl_Obj *);
+}
+
+/*
+ * Given a marker, compute where the following aligned memory starts.
+ */
+
+#define MEMSTART(markerPtr) \
+    ((markerPtr) + wordSkip(markerPtr))
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * GrowEvaluationStack --
+ *
+ *	This procedure grows a Tcl evaluation stack stored in an ExecEnv,
+ *	copying over the words since the last mark if so requested. A mark is
+ *	set at the beginning of the new area when no copying is requested.
+ *
+ * Results:
+ *	Returns a pointer to the first usable word in the (possibly) grown
+ *	stack.
+ *
+ * Side effects:
+ *	The size of the evaluation stack may be grown, a marker is set
+ *
+ *----------------------------------------------------------------------
+ */
+
+static Tcl_Obj **
+GrowEvaluationStack(
+    ExecEnv *eePtr,		/* Points to the ExecEnv with an evaluation
+				 * stack to enlarge. */
+    int growth,			/* How much larger than the current used
+				 * size. */
+    int move)			/* 1 if move words since last marker. */
+{
+    ExecStack *esPtr = eePtr->execStackPtr, *oldPtr = NULL;
+    int newBytes, newElems, currElems;
+    int needed = growth - (esPtr->endPtr - esPtr->tosPtr);
+    Tcl_Obj **markerPtr = esPtr->markerPtr, **memStart;
+    int moveWords = 0;
+
+    if (move) {
+	if (!markerPtr) {
+	    Tcl_Panic("STACK: Reallocating with no previous alloc");
+	}
+	if (needed <= 0) {
+	    return MEMSTART(markerPtr);
+	}
+    } else {
+#ifndef PURIFY
+	Tcl_Obj **tmpMarkerPtr = esPtr->tosPtr + 1;
+	int offset = wordSkip(tmpMarkerPtr);
+
+	if (needed + offset < 0) {
+	    /*
+	     * Put a marker pointing to the previous marker in this stack, and
+	     * store it in esPtr as the current marker. Return a pointer to
+	     * the start of aligned memory.
+	     */
+
+	    esPtr->markerPtr = tmpMarkerPtr;
+	    memStart = tmpMarkerPtr + offset;
+	    esPtr->tosPtr = memStart - 1;
+	    *esPtr->markerPtr = (Tcl_Obj *) markerPtr;
+	    return memStart;
+	}
+#endif
+    }
+
+    /*
+     * Reset move to hold the number of words to be moved to new stack (if
+     * any) and growth to hold the complete stack requirements: add one for
+     * the marker, (WALLOCALIGN-1) for the maximal possible offset.
+     */
+
+    if (move) {
+	moveWords = esPtr->tosPtr - MEMSTART(markerPtr) + 1;
+    }
+    needed = growth + moveWords + WALLOCALIGN;
+
+
+    /*
+     * Check if there is enough room in the next stack (if there is one, it
+     * should be both empty and the last one!)
+     */
+
+    if (esPtr->nextPtr) {
+	oldPtr = esPtr;
+	esPtr = oldPtr->nextPtr;
+	currElems = esPtr->endPtr - STACK_BASE(esPtr);
+	if (esPtr->markerPtr || (esPtr->tosPtr != STACK_BASE(esPtr))) {
+	    Tcl_Panic("STACK: Stack after current is in use");
+	}
+	if (esPtr->nextPtr) {
+	    Tcl_Panic("STACK: Stack after current is not last");
+	}
+	if (needed <= currElems) {
+	    goto newStackReady;
+	}
+	DeleteExecStack(esPtr);
+	esPtr = oldPtr;
+    } else {
+	currElems = esPtr->endPtr - STACK_BASE(esPtr);
+    }
+
+    /*
+     * We need to allocate a new stack! It needs to store 'growth' words,
+     * including the elements to be copied over and the new marker.
+     */
+
+#ifndef PURIFY
+    newElems = 2*currElems;
+    while (needed > newElems) {
+	newElems *= 2;
+    }
+#else
+    newElems = needed;
+#endif
+
+    newBytes = sizeof(ExecStack) + (newElems-1) * sizeof(Tcl_Obj *);
+
+    oldPtr = esPtr;
+    esPtr = ckalloc(newBytes);
+
+    oldPtr->nextPtr = esPtr;
+    esPtr->prevPtr = oldPtr;
+    esPtr->nextPtr = NULL;
+    esPtr->endPtr = &esPtr->stackWords[newElems-1];
+
+  newStackReady:
+    eePtr->execStackPtr = esPtr;
+
+    /*
+     * Store a NULL marker at the beginning of the stack, to indicate that
+     * this is the first marker in this stack and that rewinding to here
+     * should actually be a return to the previous stack.
+     */
+
+    esPtr->stackWords[0] = NULL;
+    esPtr->markerPtr = &esPtr->stackWords[0];
+    memStart = MEMSTART(esPtr->markerPtr);
+    esPtr->tosPtr = memStart - 1;
+
+    if (move) {
+	memcpy(memStart, MEMSTART(markerPtr), moveWords*sizeof(Tcl_Obj *));
+	esPtr->tosPtr += moveWords;
+	oldPtr->markerPtr = (Tcl_Obj **) *markerPtr;
+	oldPtr->tosPtr = markerPtr-1;
+    }
+
+    /*
+     * Free the old stack if it is now unused.
+     */
+
+    if (!oldPtr->markerPtr) {
+	DeleteExecStack(oldPtr);
+    }
+
+    return memStart;
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * TclStackAlloc, TclStackRealloc, TclStackFree --
+ *
+ *	Allocate memory from the execution stack; it has to be returned later
+ *	with a call to TclStackFree.
+ *
+ * Results:
+ *	A pointer to the first byte allocated, or panics if the allocation did
+ *	not succeed.
+ *
+ * Side effects:
+ *	The execution stack may be grown.
+ *
+ *--------------------------------------------------------------
+ */
+
+static Tcl_Obj **
+StackAllocWords(
+    Tcl_Interp *interp,
+    int numWords)
+{
+    /*
+     * Note that GrowEvaluationStack sets a marker in the stack. This marker
+     * is read when rewinding, e.g., by TclStackFree.
+     */
+
+    Interp *iPtr = (Interp *) interp;
+    ExecEnv *eePtr = iPtr->execEnvPtr;
+    Tcl_Obj **resPtr = GrowEvaluationStack(eePtr, numWords, 0);
+
+    eePtr->execStackPtr->tosPtr += numWords;
+    return resPtr;
+}
+
+static Tcl_Obj **
+StackReallocWords(
+    Tcl_Interp *interp,
+    int numWords)
+{
+    Interp *iPtr = (Interp *) interp;
+    ExecEnv *eePtr = iPtr->execEnvPtr;
+    Tcl_Obj **resPtr = GrowEvaluationStack(eePtr, numWords, 1);
+
+    eePtr->execStackPtr->tosPtr += numWords;
+    return resPtr;
+}
+
+void
+TclStackFree(
+    Tcl_Interp *interp,
+    void *freePtr)
+{
+    Interp *iPtr = (Interp *) interp;
+    ExecEnv *eePtr;
+    ExecStack *esPtr;
+    Tcl_Obj **markerPtr, *marker;
+
+    if (iPtr == NULL || iPtr->execEnvPtr == NULL) {
+	ckfree((char *) freePtr);
+	return;
+    }
+
+    /*
+     * Rewind the stack to the previous marker position. The current marker,
+     * as set in the last call to GrowEvaluationStack, contains a pointer to
+     * the previous marker.
+     */
+
+    eePtr = iPtr->execEnvPtr;
+    esPtr = eePtr->execStackPtr;
+    markerPtr = esPtr->markerPtr;
+    marker = *markerPtr;
+
+    if ((freePtr != NULL) && (MEMSTART(markerPtr) != (Tcl_Obj **)freePtr)) {
+	Tcl_Panic("TclStackFree: incorrect freePtr (%p != %p). Call out of sequence?",
+		freePtr, MEMSTART(markerPtr));
+    }
+
+    esPtr->tosPtr = markerPtr - 1;
+    esPtr->markerPtr = (Tcl_Obj **) marker;
+    if (marker) {
+	return;
+    }
+
+    /*
+     * Return to previous active stack. Note that repeated expansions or
+     * reallocs could have generated several unused intervening stacks: free
+     * them too.
+     */
+
+    while (esPtr->nextPtr) {
+	esPtr = esPtr->nextPtr;
+    }
+    esPtr->tosPtr = STACK_BASE(esPtr);
+    while (esPtr->prevPtr) {
+	ExecStack *tmpPtr = esPtr->prevPtr;
+	if (tmpPtr->tosPtr == STACK_BASE(tmpPtr)) {
+	    DeleteExecStack(tmpPtr);
+	} else {
+	    break;
+	}
+    }
+    if (esPtr->prevPtr) {
+	eePtr->execStackPtr = esPtr->prevPtr;
+#ifdef PURIFY
+	eePtr->execStackPtr->nextPtr = NULL;
+	DeleteExecStack(esPtr);
+#endif
+    } else {
+	eePtr->execStackPtr = esPtr;
+    }
+}
+
+void *
+TclStackAlloc(
+    Tcl_Interp *interp,
+    int numBytes)
+{
+    Interp *iPtr = (Interp *) interp;
+    int numWords = (numBytes + (sizeof(Tcl_Obj *) - 1))/sizeof(Tcl_Obj *);
+
+    if (iPtr == NULL || iPtr->execEnvPtr == NULL) {
+	return (void *) ckalloc(numBytes);
+    }
+
+    return (void *) StackAllocWords(interp, numWords);
+}
+
+void *
+TclStackRealloc(
+    Tcl_Interp *interp,
+    void *ptr,
+    int numBytes)
+{
+    Interp *iPtr = (Interp *) interp;
+    ExecEnv *eePtr;
+    ExecStack *esPtr;
+    Tcl_Obj **markerPtr;
+    int numWords;
+
+    if (iPtr == NULL || iPtr->execEnvPtr == NULL) {
+	return (void *) ckrealloc((char *) ptr, numBytes);
+    }
+
+    eePtr = iPtr->execEnvPtr;
+    esPtr = eePtr->execStackPtr;
+    markerPtr = esPtr->markerPtr;
+
+    if (MEMSTART(markerPtr) != (Tcl_Obj **)ptr) {
+	Tcl_Panic("TclStackRealloc: incorrect ptr. Call out of sequence?");
+    }
+
+    numWords = (numBytes + (sizeof(Tcl_Obj *) - 1))/sizeof(Tcl_Obj *);
+    return (void *) StackReallocWords(interp, numWords);
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * Tcl_ExprObj --
+ *
+ *	Evaluate an expression in a Tcl_Obj.
+ *
+ * Results:
+ *	A standard Tcl object result. If the result is other than TCL_OK, then
+ *	the interpreter's result contains an error message. If the result is
+ *	TCL_OK, then a pointer to the expression's result value object is
+ *	stored in resultPtrPtr. In that case, the object's ref count is
+ *	incremented to reflect the reference returned to the caller; the
+ *	caller is then responsible for the resulting object and must, for
+ *	example, decrement the ref count when it is finished with the object.
+ *
+ * Side effects:
+ *	Any side effects caused by subcommands in the expression, if any. The
+ *	interpreter result is not modified unless there is an error.
+ *
+ *--------------------------------------------------------------
+ */
+
+int
+Tcl_ExprObj(
+    Tcl_Interp *interp,		/* Context in which to evaluate the
+				 * expression. */
+    register Tcl_Obj *objPtr,	/* Points to Tcl object containing expression
+				 * to evaluate. */
+    Tcl_Obj **resultPtrPtr)	/* Where the Tcl_Obj* that is the expression
+				 * result is stored if no errors occur. */
+{
+    NRE_callback *rootPtr = TOP_CB(interp);
+    Tcl_Obj *resultPtr;
+
+    TclNewObj(resultPtr);
+    TclNRAddCallback(interp, CopyCallback, resultPtrPtr, resultPtr,
+	    NULL, NULL);
+    Tcl_NRExprObj(interp, objPtr, resultPtr);
+    return TclNRRunCallbacks(interp, TCL_OK, rootPtr);
+}
+
+static int
+CopyCallback(
+    ClientData data[],
+    Tcl_Interp *interp,
+    int result)
+{
+    Tcl_Obj **resultPtrPtr = data[0];
+    Tcl_Obj *resultPtr = data[1];
+
+    if (result == TCL_OK) {
+	*resultPtrPtr = resultPtr;
+	Tcl_IncrRefCount(resultPtr);
+    } else {
+	Tcl_DecrRefCount(resultPtr);
+    }
+    return result;
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * Tcl_NRExprObj --
+ *
+ *	Request evaluation of the expression in a Tcl_Obj by the NR stack.
+ *
+ * Results:
+ *	Returns TCL_OK.
+ *
+ * Side effects:
+ *	Compiles objPtr as a Tcl expression and places callbacks on the
+ *	NR stack to execute the bytecode and store the result in resultPtr.
+ *	If bytecode execution raises an exception, nothing is written
+ *	to resultPtr, and the exceptional return code flows up the NR
+ *	stack.  If the exception is TCL_ERROR, an error message is left
+ *	in the interp result and the interp's return options dictionary
+ *	holds additional error information too.  Execution of the bytecode
+ *	may have other side effects, depending on the expression.
+ *
+ *--------------------------------------------------------------
+ */
+
+int
+Tcl_NRExprObj(
+    Tcl_Interp *interp,
+    Tcl_Obj *objPtr,
+    Tcl_Obj *resultPtr)
+{
+    ByteCode *codePtr;
+    Tcl_InterpState state = Tcl_SaveInterpState(interp, TCL_OK);
+
+    Tcl_ResetResult(interp);
+    codePtr = CompileExprObj(interp, objPtr);
+
+    Tcl_NRAddCallback(interp, ExprObjCallback, state, resultPtr,
+	    NULL, NULL);
+    return TclNRExecuteByteCode(interp, codePtr);
+}
+
+static int
+ExprObjCallback(
+    ClientData data[],
+    Tcl_Interp *interp,
+    int result)
+{
+    Tcl_InterpState state = data[0];
+    Tcl_Obj *resultPtr = data[1];
+
+    if (result == TCL_OK) {
+	TclSetDuplicateObj(resultPtr, Tcl_GetObjResult(interp));
+	(void) Tcl_RestoreInterpState(interp, state);
+    } else {
+	Tcl_DiscardInterpState(state);
+    }
+    return result;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * CompileExprObj --
+ *	Compile a Tcl expression value into ByteCode.
+ *
+ * Results:
+ *	A (ByteCode *) is returned pointing to the resulting ByteCode.
+ *	The caller must manage its refCount and arrange for a call to
+ *	TclCleanupByteCode() when the last reference disappears.
+ *
+ * Side effects:
+ *	The Tcl_ObjType of objPtr is changed to the "bytecode" type,
+ *	and the ByteCode is kept in the internal rep (along with context
+ *	data for checking validity) for faster operations the next time
+ *	CompileExprObj is called on the same value.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static ByteCode *
+CompileExprObj(
+    Tcl_Interp *interp,
+    Tcl_Obj *objPtr)
+{
+    Interp *iPtr = (Interp *) interp;
+    CompileEnv compEnv;		/* Compilation environment structure allocated
+				 * in frame. */
+    register ByteCode *codePtr = NULL;
+				/* Tcl Internal type of bytecode. Initialized
+				 * to avoid compiler warning. */
+
+    /*
+     * Get the expression ByteCode from the object. If it exists, make sure it
+     * is valid in the current context.
+     */
+    if (objPtr->typePtr == &exprCodeType) {
+	Namespace *namespacePtr = iPtr->varFramePtr->nsPtr;
+
+	codePtr = objPtr->internalRep.twoPtrValue.ptr1;
+	if (((Interp *) *codePtr->interpHandle != iPtr)
+		|| (codePtr->compileEpoch != iPtr->compileEpoch)
+		|| (codePtr->nsPtr != namespacePtr)
+		|| (codePtr->nsEpoch != namespacePtr->resolverEpoch)
+		|| (codePtr->localCachePtr != iPtr->varFramePtr->localCachePtr)) {
+	    FreeExprCodeInternalRep(objPtr);
+	}
+    }
+    if (objPtr->typePtr != &exprCodeType) {
+	/*
+	 * TIP #280: No invoker (yet) - Expression compilation.
+	 */
+
+	int length;
+	const char *string = TclGetStringFromObj(objPtr, &length);
+
+	TclInitCompileEnv(interp, &compEnv, string, length, NULL, 0);
+	TclCompileExpr(interp, string, length, &compEnv, 0);
+
+	/*
+	 * Successful compilation. If the expression yielded no instructions,
+	 * push an zero object as the expression's result.
+	 */
+
+	if (compEnv.codeNext == compEnv.codeStart) {
+	    TclEmitPush(TclRegisterNewLiteral(&compEnv, "0", 1),
+		    &compEnv);
+	}
+
+	/*
+	 * Add a "done" instruction as the last instruction and change the
+	 * object into a ByteCode object. Ownership of the literal objects and
+	 * aux data items is given to the ByteCode object.
+	 */
+
+	TclEmitOpcode(INST_DONE, &compEnv);
+	TclInitByteCodeObj(objPtr, &compEnv);
+	objPtr->typePtr = &exprCodeType;
+	TclFreeCompileEnv(&compEnv);
+	codePtr = objPtr->internalRep.twoPtrValue.ptr1;
+	if (iPtr->varFramePtr->localCachePtr) {
+	    codePtr->localCachePtr = iPtr->varFramePtr->localCachePtr;
+	    codePtr->localCachePtr->refCount++;
+	}
+#ifdef TCL_COMPILE_DEBUG
+	if (tclTraceCompile == 2) {
+	    TclPrintByteCodeObj(interp, objPtr);
+	    fflush(stdout);
+	}
+#endif /* TCL_COMPILE_DEBUG */
+    }
+    return codePtr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * DupExprCodeInternalRep --
+ *
+ *	Part of the Tcl object type implementation for Tcl expression
+ *	bytecode. We do not copy the bytecode intrep. Instead, we return
+ *	without setting copyPtr->typePtr, so the copy is a plain string copy
+ *	of the expression value, and if it is to be used as a compiled
+ *	expression, it will just need a recompile.
+ *
+ *	This makes sense, because with Tcl's copy-on-write practices, the
+ *	usual (only?) time Tcl_DuplicateObj() will be called is when the copy
+ *	is about to be modified, which would invalidate any copied bytecode
+ *	anyway. The only reason it might make sense to copy the bytecode is if
+ *	we had some modifying routines that operated directly on the intrep,
+ *	like we do for lists and dicts.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+DupExprCodeInternalRep(
+    Tcl_Obj *srcPtr,
+    Tcl_Obj *copyPtr)
+{
+    return;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * FreeExprCodeInternalRep --
+ *
+ *	Part of the Tcl object type implementation for Tcl expression
+ *	bytecode. Frees the storage allocated to hold the internal rep, unless
+ *	ref counts indicate bytecode execution is still in progress.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	May free allocated memory. Leaves objPtr untyped.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+FreeExprCodeInternalRep(
+    Tcl_Obj *objPtr)
+{
+    ByteCode *codePtr = objPtr->internalRep.twoPtrValue.ptr1;
+
+    objPtr->typePtr = NULL;
+    if (codePtr->refCount-- <= 1) {
+	TclCleanupByteCode(codePtr);
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclCompileObj --
+ *
+ *	This procedure compiles the script contained in a Tcl_Obj.
+ *
+ * Results:
+ *	A pointer to the corresponding ByteCode, never NULL.
+ *
+ * Side effects:
+ *	The object is shimmered to bytecode type.
+ *
+ *----------------------------------------------------------------------
+ */
+
+ByteCode *
+TclCompileObj(
+    Tcl_Interp *interp,
+    Tcl_Obj *objPtr,
+    const CmdFrame *invoker,
+    int word)
+{
+    register Interp *iPtr = (Interp *) interp;
+    register ByteCode *codePtr;	/* Tcl Internal type of bytecode. */
+    Namespace *namespacePtr = iPtr->varFramePtr->nsPtr;
+
+    /*
+     * If the object is not already of tclByteCodeType, compile it (and reset
+     * the compilation flags in the interpreter; this should be done after any
+     * compilation). Otherwise, check that it is "fresh" enough.
+     */
+
+    if (objPtr->typePtr == &tclByteCodeType) {
+	/*
+	 * Make sure the Bytecode hasn't been invalidated by, e.g., someone
+	 * redefining a command with a compile procedure (this might make the
+	 * compiled code wrong). The object needs to be recompiled if it was
+	 * compiled in/for a different interpreter, or for a different
+	 * namespace, or for the same namespace but with different name
+	 * resolution rules. Precompiled objects, however, are immutable and
+	 * therefore they are not recompiled, even if the epoch has changed.
+	 *
+	 * To be pedantically correct, we should also check that the
+	 * originating procPtr is the same as the current context procPtr
+	 * (assuming one exists at all - none for global level). This code is
+	 * #def'ed out because [info body] was changed to never return a
+	 * bytecode type object, which should obviate us from the extra checks
+	 * here.
+	 */
+
+	codePtr = objPtr->internalRep.twoPtrValue.ptr1;
+	if (((Interp *) *codePtr->interpHandle != iPtr)
+		|| (codePtr->compileEpoch != iPtr->compileEpoch)
+		|| (codePtr->nsPtr != namespacePtr)
+		|| (codePtr->nsEpoch != namespacePtr->resolverEpoch)) {
+	    if (!(codePtr->flags & TCL_BYTECODE_PRECOMPILED)) {
+		goto recompileObj;
+	    }
+	    if ((Interp *) *codePtr->interpHandle != iPtr) {
+		Tcl_Panic("Tcl_EvalObj: compiled script jumped interps");
+	    }
+	    codePtr->compileEpoch = iPtr->compileEpoch;
+	}
+
+	/*
+	 * Check that any compiled locals do refer to the current proc
+	 * environment! If not, recompile.
+	 */
+
+	if (!(codePtr->flags & TCL_BYTECODE_PRECOMPILED) &&
+		(codePtr->procPtr == NULL) &&
+		(codePtr->localCachePtr != iPtr->varFramePtr->localCachePtr)){
+	    goto recompileObj;
+	}
+
+	/*
+	 * #280.
+	 * Literal sharing fix. This part of the fix is not required by 8.4
+	 * nor 8.5, because they eval-direct any literals, so just saving the
+	 * argument locations per command in bytecode is enough, embedded
+	 * 'eval' commands, etc. get the correct information.
+	 *
+	 * But in 8.6 all the embedded script are compiled, and the resulting
+	 * bytecode stored in the literal. Now the shared literal has bytecode
+	 * with location data for _one_ particular location this literal is
+	 * found at. If we get executed from a different location the bytecode
+	 * has to be recompiled to get the correct locations. Not doing this
+	 * will execute the saved bytecode with data for a different location,
+	 * causing 'info frame' to point to the wrong place in the sources.
+	 *
+	 * Future optimizations ...
+	 * (1) Save the location data (ExtCmdLoc) keyed by start line. In that
+	 *     case we recompile once per location of the literal, but not
+	 *     continously, because the moment we have all locations we do not
+	 *     need to recompile any longer.
+	 *
+	 * (2) Alternative: Do not recompile, tell the execution engine the
+	 *     offset between saved starting line and actual one. Then modify
+	 *     the users to adjust the locations they have by this offset.
+	 *
+	 * (3) Alternative 2: Do not fully recompile, adjust just the location
+	 *     information.
+	 */
+
+	if (invoker == NULL) {
+	    return codePtr;
+	} else {
+	    Tcl_HashEntry *hePtr =
+		    Tcl_FindHashEntry(iPtr->lineBCPtr, codePtr);
+	    ExtCmdLoc *eclPtr;
+	    CmdFrame *ctxCopyPtr;
+	    int redo;
+
+	    if (!hePtr) {
+		return codePtr;
+	    }
+
+	    eclPtr = Tcl_GetHashValue(hePtr);
+	    redo = 0;
+	    ctxCopyPtr = TclStackAlloc(interp, sizeof(CmdFrame));
+	    *ctxCopyPtr = *invoker;
+
+	    if (invoker->type == TCL_LOCATION_BC) {
+		/*
+		 * Note: Type BC => ctx.data.eval.path    is not used.
+		 *		    ctx.data.tebc.codePtr used instead
+		 */
+
+		TclGetSrcInfoForPc(ctxCopyPtr);
+		if (ctxCopyPtr->type == TCL_LOCATION_SOURCE) {
+		    /*
+		     * The reference made by 'TclGetSrcInfoForPc' is dead.
+		     */
+
+		    Tcl_DecrRefCount(ctxCopyPtr->data.eval.path);
+		    ctxCopyPtr->data.eval.path = NULL;
+		}
+	    }
+
+	    if (word < ctxCopyPtr->nline) {
+		/*
+		 * Note: We do not care if the line[word] is -1. This is a
+		 * difference and requires a recompile (location changed from
+		 * absolute to relative, literal is used fixed and through
+		 * variable)
+		 *
+		 * Example:
+		 * test info-32.0 using literal of info-24.8
+		 *     (dict with ... vs           set body ...).
+		 */
+
+		redo = ((eclPtr->type == TCL_LOCATION_SOURCE)
+			    && (eclPtr->start != ctxCopyPtr->line[word]))
+			|| ((eclPtr->type == TCL_LOCATION_BC)
+			    && (ctxCopyPtr->type == TCL_LOCATION_SOURCE));
+	    }
+
+	    TclStackFree(interp, ctxCopyPtr);
+	    if (!redo) {
+		return codePtr;
+	    }
+	}
+    }
+
+  recompileObj:
+    iPtr->errorLine = 1;
+
+    /*
+     * TIP #280. Remember the invoker for a moment in the interpreter
+     * structures so that the byte code compiler can pick it up when
+     * initializing the compilation environment, i.e. the extended location
+     * information.
+     */
+
+    iPtr->invokeCmdFramePtr = invoker;
+    iPtr->invokeWord = word;
+    TclSetByteCodeFromAny(interp, objPtr, NULL, NULL);
+    iPtr->invokeCmdFramePtr = NULL;
+    codePtr = objPtr->internalRep.twoPtrValue.ptr1;
+    if (iPtr->varFramePtr->localCachePtr) {
+	codePtr->localCachePtr = iPtr->varFramePtr->localCachePtr;
+	codePtr->localCachePtr->refCount++;
+    }
+    return codePtr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclIncrObj --
+ *
+ *	Increment an integeral value in a Tcl_Obj by an integeral value held
+ *	in another Tcl_Obj. Caller is responsible for making sure we can
+ *	update the first object.
+ *
+ * Results:
+ *	TCL_ERROR if either object is non-integer, and TCL_OK otherwise. On
+ *	error, an error message is left in the interpreter (if it is not NULL,
+ *	of course).
+ *
+ * Side effects:
+ *	valuePtr gets the new incrmented value.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclIncrObj(
+    Tcl_Interp *interp,
+    Tcl_Obj *valuePtr,
+    Tcl_Obj *incrPtr)
+{
+    ClientData ptr1, ptr2;
+    int type1, type2;
+    mp_int value, incr;
+
+    if (Tcl_IsShared(valuePtr)) {
+	Tcl_Panic("%s called with shared object", "TclIncrObj");
+    }
+
+    if (GetNumberFromObj(NULL, valuePtr, &ptr1, &type1) != TCL_OK) {
+	/*
+	 * Produce error message (reparse?!)
+	 */
+
+	return TclGetIntFromObj(interp, valuePtr, &type1);
+    }
+    if (GetNumberFromObj(NULL, incrPtr, &ptr2, &type2) != TCL_OK) {
+	/*
+	 * Produce error message (reparse?!)
+	 */
+
+	TclGetIntFromObj(interp, incrPtr, &type1);
+	Tcl_AddErrorInfo(interp, "\n    (reading increment)");
+	return TCL_ERROR;
+    }
+
+    if ((type1 == TCL_NUMBER_LONG) && (type2 == TCL_NUMBER_LONG)) {
+	long augend = *((const long *) ptr1);
+	long addend = *((const long *) ptr2);
+	long sum = augend + addend;
+
+	/*
+	 * Overflow when (augend and sum have different sign) and (augend and
+	 * addend have the same sign). This is encapsulated in the Overflowing
+	 * macro.
+	 */
+
+	if (!Overflowing(augend, addend, sum)) {
+	    TclSetLongObj(valuePtr, sum);
+	    return TCL_OK;
+	}
+#ifndef TCL_WIDE_INT_IS_LONG
+	{
+	    Tcl_WideInt w1 = (Tcl_WideInt) augend;
+	    Tcl_WideInt w2 = (Tcl_WideInt) addend;
+
+	    /*
+	     * We know the sum value is outside the long range, so we use the
+	     * macro form that doesn't range test again.
+	     */
+
+	    TclSetWideIntObj(valuePtr, w1 + w2);
+	    return TCL_OK;
+	}
+#endif
+    }
+
+    if ((type1 == TCL_NUMBER_DOUBLE) || (type1 == TCL_NUMBER_NAN)) {
+	/*
+	 * Produce error message (reparse?!)
+	 */
+
+	return TclGetIntFromObj(interp, valuePtr, &type1);
+    }
+    if ((type2 == TCL_NUMBER_DOUBLE) || (type2 == TCL_NUMBER_NAN)) {
+	/*
+	 * Produce error message (reparse?!)
+	 */
+
+	TclGetIntFromObj(interp, incrPtr, &type1);
+	Tcl_AddErrorInfo(interp, "\n    (reading increment)");
+	return TCL_ERROR;
+    }
+
+#ifndef TCL_WIDE_INT_IS_LONG
+    if ((type1 != TCL_NUMBER_BIG) && (type2 != TCL_NUMBER_BIG)) {
+	Tcl_WideInt w1, w2, sum;
+
+	TclGetWideIntFromObj(NULL, valuePtr, &w1);
+	TclGetWideIntFromObj(NULL, incrPtr, &w2);
+	sum = w1 + w2;
+
+	/*
+	 * Check for overflow.
+	 */
+
+	if (!Overflowing(w1, w2, sum)) {
+	    Tcl_SetWideIntObj(valuePtr, sum);
+	    return TCL_OK;
+	}
+    }
+#endif
+
+    Tcl_TakeBignumFromObj(interp, valuePtr, &value);
+    Tcl_GetBignumFromObj(interp, incrPtr, &incr);
+    mp_add(&value, &incr, &value);
+    mp_clear(&incr);
+    Tcl_SetBignumObj(valuePtr, &value);
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ArgumentBCEnter --
+ *
+ *	This is a helper for TclNRExecuteByteCode/TEBCresume that encapsulates
+ *	a code sequence that is fairly common in the code but *not* commonly
+ *	called.
+ *
+ * Results:
+ *	None
+ *
+ * Side effects:
+ *	May register information about the bytecode in the command frame.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+ArgumentBCEnter(
+    Tcl_Interp *interp,
+    ByteCode *codePtr,
+    TEBCdata *tdPtr,
+    const unsigned char *pc,
+    int objc,
+    Tcl_Obj **objv)
+{
+    int cmd;
+
+    if (GetSrcInfoForPc(pc, codePtr, NULL, NULL, &cmd)) {
+	TclArgumentBCEnter(interp, objv, objc, codePtr, &tdPtr->cmdFrame, cmd,
+		pc - codePtr->codeStart);
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclNRExecuteByteCode --
+ *
+ *	This procedure executes the instructions of a ByteCode structure. It
+ *	returns when a "done" instruction is executed or an error occurs.
+ *
+ * Results:
+ *	The return value is one of the return codes defined in tcl.h (such as
+ *	TCL_OK), and interp->objResultPtr refers to a Tcl object that either
+ *	contains the result of executing the code or an error message.
+ *
+ * Side effects:
+ *	Almost certainly, depending on the ByteCode's instructions.
+ *
+ *----------------------------------------------------------------------
+ */
+#define	bcFramePtr	(&TD->cmdFrame)
+#define	initCatchTop	((ptrdiff_t *) (&TD->stack[-1]))
+#define	initTosPtr	((Tcl_Obj **) (initCatchTop+codePtr->maxExceptDepth))
+#define esPtr		(iPtr->execEnvPtr->execStackPtr)
+
+int
+TclNRExecuteByteCode(
+    Tcl_Interp *interp,		/* Token for command interpreter. */
+    ByteCode *codePtr)		/* The bytecode sequence to interpret. */
+{
+    Interp *iPtr = (Interp *) interp;
+    TEBCdata *TD;
+    int size = sizeof(TEBCdata) - 1
+	    + (codePtr->maxStackDepth + codePtr->maxExceptDepth)
+		* sizeof(void *);
+    int numWords = (size + sizeof(Tcl_Obj *) - 1) / sizeof(Tcl_Obj *);
+
+    codePtr->refCount++;
+
+    /*
+     * Reserve the stack, setup the TEBCdataPtr (TD) and CallFrame
+     *
+     * The execution uses a unified stack: first a TEBCdata, immediately
+     * above it a CmdFrame, then the catch stack, then the execution stack.
+     *
+     * Make sure the catch stack is large enough to hold the maximum number of
+     * catch commands that could ever be executing at the same time (this will
+     * be no more than the exception range array's depth). Make sure the
+     * execution stack is large enough to execute this ByteCode.
+     */
+
+    TD = (TEBCdata *) GrowEvaluationStack(iPtr->execEnvPtr, numWords, 0);
+    esPtr->tosPtr = initTosPtr;
+
+    TD->codePtr     = codePtr;
+    TD->catchTop    = initCatchTop;
+    TD->auxObjList  = NULL;
+
+    /*
+     * TIP #280: Initialize the frame. Do not push it yet: it will be pushed
+     * every time that we call out from this TD, popped when we return to it.
+     */
+
+    bcFramePtr->type = ((codePtr->flags & TCL_BYTECODE_PRECOMPILED)
+	    ? TCL_LOCATION_PREBC : TCL_LOCATION_BC);
+    bcFramePtr->level = (iPtr->cmdFramePtr ? iPtr->cmdFramePtr->level+1 : 1);
+    bcFramePtr->framePtr = iPtr->framePtr;
+    bcFramePtr->nextPtr = iPtr->cmdFramePtr;
+    bcFramePtr->nline = 0;
+    bcFramePtr->line = NULL;
+    bcFramePtr->litarg = NULL;
+    bcFramePtr->data.tebc.codePtr = codePtr;
+    bcFramePtr->data.tebc.pc = NULL;
+    bcFramePtr->cmdObj = NULL;
+    bcFramePtr->cmd = NULL;
+    bcFramePtr->len = 0;
+
+#ifdef TCL_COMPILE_STATS
+    iPtr->stats.numExecutions++;
+#endif
+
+    /*
+     * Test namespace-50.9 demonstrates the need for this call.
+     * Use a --enable-symbols=mem bug to see.
+     */
+
+    TclResetRewriteEnsemble(interp, 1);
+
+    /*
+     * Push the callback for bytecode execution
+     */
+
+    TclNRAddCallback(interp, TEBCresume, TD, /* pc */ NULL,
+	    /* cleanup */ INT2PTR(0), NULL);
+    return TCL_OK;
+}
+
+static int
+TEBCresume(
+    ClientData data[],
+    Tcl_Interp *interp,
+    int result)
+{
+    /*
+     * Compiler cast directive - not a real variable.
+     *	   Interp *iPtr = (Interp *) interp;
+     */
+#define iPtr ((Interp *) interp)
+
+    /*
+     * Check just the read-traced/write-traced bit of a variable.
+     */
+
+#define ReadTraced(varPtr) ((varPtr)->flags & VAR_TRACED_READ)
+#define WriteTraced(varPtr) ((varPtr)->flags & VAR_TRACED_WRITE)
+#define UnsetTraced(varPtr) ((varPtr)->flags & VAR_TRACED_UNSET)
+
+    /*
+     * Bottom of allocated stack holds the NR data
+     */
+
+    /*
+     * Constants: variables that do not change during the execution, used
+     * sporadically: no special need for speed.
+     */
+
+    int instructionCount = 0;	/* Counter that is used to work out when to
+				 * call Tcl_AsyncReady() */
+    const char *curInstName;
+#ifdef TCL_COMPILE_DEBUG
+    int traceInstructions;	/* Whether we are doing instruction-level
+				 * tracing or not. */
+#endif
+
+    Var *compiledLocals = iPtr->varFramePtr->compiledLocals;
+    Tcl_Obj **constants = &iPtr->execEnvPtr->constants[0];
+
+#define LOCAL(i)	(&compiledLocals[(i)])
+#define TCONST(i)	(constants[(i)])
+
+    /*
+     * These macros are just meant to save some global variables that are not
+     * used too frequently
+     */
+
+    TEBCdata *TD = data[0];
+#define auxObjList	(TD->auxObjList)
+#define catchTop	(TD->catchTop)
+#define codePtr		(TD->codePtr)
+
+    /*
+     * Globals: variables that store state, must remain valid at all times.
+     */
+
+    Tcl_Obj **tosPtr;		/* Cached pointer to top of evaluation
+				 * stack. */
+    const unsigned char *pc = data[1];
+                                /* The current program counter. */
+    unsigned char inst;         /* The currently running instruction */
+
+    /*
+     * Transfer variables - needed only between opcodes, but not while
+     * executing an instruction.
+     */
+
+    int cleanup = PTR2INT(data[2]);
+    Tcl_Obj *objResultPtr;
+    int checkInterp;            /* Indicates when a check of interp readyness
+				 * is necessary. Set by CACHE_STACK_INFO() */
+
+    /*
+     * Locals - variables that are used within opcodes or bounded sections of
+     * the file (jumps between opcodes within a family).
+     * NOTE: These are now mostly defined locally where needed.
+     */
+
+    Tcl_Obj *objPtr, *valuePtr, *value2Ptr, *part1Ptr, *part2Ptr, *tmpPtr;
+    Tcl_Obj **objv;
+    int objc = 0;
+    int opnd, length, pcAdjustment;
+    Var *varPtr, *arrayPtr;
+#ifdef TCL_COMPILE_DEBUG
+    char cmdNameBuf[21];
+#endif
+
+#ifdef TCL_COMPILE_DEBUG
+    int starting = 1;
+    traceInstructions = (tclTraceExec == 3);
+#endif
+
+    TEBC_DATA_DIG();
+
+#ifdef TCL_COMPILE_DEBUG
+    if (!pc && (tclTraceExec >= 2)) {
+	PrintByteCodeInfo(codePtr);
+	fprintf(stdout, "  Starting stack top=%d\n", (int) CURR_DEPTH);
+	fflush(stdout);
+    }
+#endif
+
+    if (!pc) {
+	/* bytecode is starting from scratch */
+	checkInterp = 0;
+	pc = codePtr->codeStart;
+	goto cleanup0;
+    } else {
+        /* resume from invocation */
+	CACHE_STACK_INFO();
+
+	NRE_ASSERT(iPtr->cmdFramePtr == bcFramePtr);
+	if (bcFramePtr->cmdObj) {
+	    Tcl_DecrRefCount(bcFramePtr->cmdObj);
+	    bcFramePtr->cmdObj = NULL;
+	    bcFramePtr->cmd = NULL;
+	}
+	iPtr->cmdFramePtr = bcFramePtr->nextPtr;
+	if (iPtr->flags & INTERP_DEBUG_FRAME) {
+	    TclArgumentBCRelease(interp, bcFramePtr);
+	}
+	if (iPtr->execEnvPtr->rewind) {
+	    result = TCL_ERROR;
+	    goto abnormalReturn;
+	}
+	if (codePtr->flags & TCL_BYTECODE_RECOMPILE) {
+	    iPtr->flags |= ERR_ALREADY_LOGGED;
+	    codePtr->flags &= ~TCL_BYTECODE_RECOMPILE;
+	}
+
+	if (result != TCL_OK) {
+	    pc--;
+	    goto processExceptionReturn;
+	}
+
+	/*
+	 * Push the call's object result and continue execution with the next
+	 * instruction.
+	 */
+
+	TRACE_WITH_OBJ(("%u => ... after \"%.20s\": TCL_OK, result=",
+		objc, cmdNameBuf), Tcl_GetObjResult(interp));
+
+	/*
+	 * Reset the interp's result to avoid possible duplications of large
+	 * objects [Bug 781585]. We do not call Tcl_ResetResult to avoid any
+	 * side effects caused by the resetting of errorInfo and errorCode
+	 * [Bug 804681], which are not needed here. We chose instead to
+	 * manipulate the interp's object result directly.
+	 *
+	 * Note that the result object is now in objResultPtr, it keeps the
+	 * refCount it had in its role of iPtr->objResultPtr.
+	 */
+
+	objResultPtr = Tcl_GetObjResult(interp);
+	TclNewObj(objPtr);
+	Tcl_IncrRefCount(objPtr);
+	iPtr->objResultPtr = objPtr;
+#ifndef TCL_COMPILE_DEBUG
+	if (*pc == INST_POP) {
+	    TclDecrRefCount(objResultPtr);
+	    NEXT_INST_V(1, cleanup, 0);
+	}
+#endif
+	NEXT_INST_V(0, cleanup, -1);
+    }
+
+    /*
+     * Targets for standard instruction endings; unrolled for speed in the
+     * most frequent cases (instructions that consume up to two stack
+     * elements).
+     *
+     * This used to be a "for(;;)" loop, with each instruction doing its own
+     * cleanup.
+     */
+
+  cleanupV_pushObjResultPtr:
+    switch (cleanup) {
+    case 0:
+	*(++tosPtr) = (objResultPtr);
+	goto cleanup0;
+    default:
+	cleanup -= 2;
+	while (cleanup--) {
+	    objPtr = POP_OBJECT();
+	    TclDecrRefCount(objPtr);
+	}
+    case 2:
+    cleanup2_pushObjResultPtr:
+	objPtr = POP_OBJECT();
+	TclDecrRefCount(objPtr);
+    case 1:
+    cleanup1_pushObjResultPtr:
+	objPtr = OBJ_AT_TOS;
+	TclDecrRefCount(objPtr);
+    }
+    OBJ_AT_TOS = objResultPtr;
+    goto cleanup0;
+
+  cleanupV:
+    switch (cleanup) {
+    default:
+	cleanup -= 2;
+	while (cleanup--) {
+	    objPtr = POP_OBJECT();
+	    TclDecrRefCount(objPtr);
+	}
+    case 2:
+    cleanup2:
+	objPtr = POP_OBJECT();
+	TclDecrRefCount(objPtr);
+    case 1:
+    cleanup1:
+	objPtr = POP_OBJECT();
+	TclDecrRefCount(objPtr);
+    case 0:
+	/*
+	 * We really want to do nothing now, but this is needed for some
+	 * compilers (SunPro CC).
+	 */
+
+	break;
+    }
+  cleanup0:
+
+    /*
+     * Check for asynchronous handlers [Bug 746722]; we do the check every
+     * ASYNC_CHECK_COUNT_MASK instruction, of the form (2**n-1).
+     */
+
+    if ((instructionCount++ & ASYNC_CHECK_COUNT_MASK) == 0) {
+	DECACHE_STACK_INFO();
+	if (TclAsyncReady(iPtr)) {
+	    result = Tcl_AsyncInvoke(interp, result);
+	    if (result == TCL_ERROR) {
+		CACHE_STACK_INFO();
+		goto gotError;
+	    }
+	}
+
+	if (TclCanceled(iPtr)) {
+	    if (Tcl_Canceled(interp, TCL_LEAVE_ERR_MSG) == TCL_ERROR) {
+		CACHE_STACK_INFO();
+		goto gotError;
+	    }
+	}
+
+	if (TclLimitReady(iPtr->limit)) {
+	    if (Tcl_LimitCheck(interp) == TCL_ERROR) {
+		CACHE_STACK_INFO();
+		goto gotError;
+	    }
+	}
+	CACHE_STACK_INFO();
+    }
+
+    /*
+     * These two instructions account for 26% of all instructions (according
+     * to measurements on tclbench by Ben Vitale
+     * [http://www.cs.toronto.edu/syslab/pubs/tcl2005-vitale-zaleski.pdf]
+     * Resolving them before the switch reduces the cost of branch
+     * mispredictions, seems to improve runtime by 5% to 15%, and (amazingly!)
+     * reduces total obj size.
+     */
+
+    inst = *pc;
+
+    peepholeStart:
+#ifdef TCL_COMPILE_STATS
+    iPtr->stats.instructionCount[*pc]++;
+#endif
+
+#ifdef TCL_COMPILE_DEBUG
+    /*
+     * Skip the stack depth check if an expansion is in progress.
+     */
+
+    CHECK_STACK();
+    if (traceInstructions) {
+	fprintf(stdout, "%2d: %2d ", iPtr->numLevels, (int) CURR_DEPTH);
+	TclPrintInstruction(codePtr, pc);
+	fflush(stdout);
+    }
+#endif /* TCL_COMPILE_DEBUG */
+
+    TCL_DTRACE_INST_NEXT();
+
+    if (inst == INST_LOAD_SCALAR1) {
+	goto instLoadScalar1;
+    } else if (inst == INST_PUSH1) {
+	PUSH_OBJECT(codePtr->objArrayPtr[TclGetUInt1AtPtr(pc+1)]);
+	TRACE_WITH_OBJ(("%u => ", TclGetUInt1AtPtr(pc+1)), OBJ_AT_TOS);
+	inst = *(pc += 2);
+	goto peepholeStart;
+    } else if (inst == INST_START_CMD) {
+	/*
+	 * Peephole: do not run INST_START_CMD, just skip it
+	 */
+
+	iPtr->cmdCount += TclGetUInt4AtPtr(pc+5);
+	if (checkInterp) {
+	    checkInterp = 0;
+	    if (((codePtr->compileEpoch != iPtr->compileEpoch) ||
+		 (codePtr->nsEpoch != iPtr->varFramePtr->nsPtr->resolverEpoch)) &&
+		!(codePtr->flags & TCL_BYTECODE_PRECOMPILED)) {
+		goto instStartCmdFailed;
+	    }
+	}
+	inst = *(pc += 9);
+	goto peepholeStart;
+    } else if (inst == INST_NOP) {
+#ifndef TCL_COMPILE_DEBUG
+	while (inst == INST_NOP)
+#endif
+	{
+	    inst = *++pc;
+	}
+	goto peepholeStart;
+    }
+
+    switch (inst) {
+    case INST_SYNTAX:
+    case INST_RETURN_IMM: {
+	int code = TclGetInt4AtPtr(pc+1);
+	int level = TclGetUInt4AtPtr(pc+5);
+
+	/*
+	 * OBJ_AT_TOS is returnOpts, OBJ_UNDER_TOS is resultObjPtr.
+	 */
+
+	TRACE(("%u %u => ", code, level));
+	result = TclProcessReturn(interp, code, level, OBJ_AT_TOS);
+	if (result == TCL_OK) {
+	    TRACE_APPEND(("continuing to next instruction (result=\"%.30s\")\n",
+		    O2S(objResultPtr)));
+	    NEXT_INST_F(9, 1, 0);
+	}
+	Tcl_SetObjResult(interp, OBJ_UNDER_TOS);
+	if (*pc == INST_SYNTAX) {
+	    iPtr->flags &= ~ERR_ALREADY_LOGGED;
+	}
+	cleanup = 2;
+	TRACE_APPEND(("\n"));
+	goto processExceptionReturn;
+    }
+
+    case INST_RETURN_STK:
+	TRACE(("=> "));
+	objResultPtr = POP_OBJECT();
+	result = Tcl_SetReturnOptions(interp, OBJ_AT_TOS);
+	if (result == TCL_OK) {
+	    Tcl_DecrRefCount(OBJ_AT_TOS);
+	    OBJ_AT_TOS = objResultPtr;
+	    TRACE_APPEND(("continuing to next instruction (result=\"%.30s\")\n",
+		    O2S(objResultPtr)));
+	    NEXT_INST_F(1, 0, 0);
+	} else if (result == TCL_ERROR) {
+	    /*
+	     * BEWARE! Must do this in this order, because an error in the
+	     * option dictionary overrides the result (and can be verified by
+	     * test).
+	     */
+
+	    Tcl_SetObjResult(interp, objResultPtr);
+	    Tcl_SetReturnOptions(interp, OBJ_AT_TOS);
+	    Tcl_DecrRefCount(OBJ_AT_TOS);
+	    OBJ_AT_TOS = objResultPtr;
+	} else {
+	    Tcl_DecrRefCount(OBJ_AT_TOS);
+	    OBJ_AT_TOS = objResultPtr;
+	    Tcl_SetObjResult(interp, objResultPtr);
+	}
+	cleanup = 1;
+	TRACE_APPEND(("\n"));
+	goto processExceptionReturn;
+
+    {
+	CoroutineData *corPtr;
+	int yieldParameter;
+
+    case INST_YIELD:
+	corPtr = iPtr->execEnvPtr->corPtr;
+	TRACE(("%.30s => ", O2S(OBJ_AT_TOS)));
+	if (!corPtr) {
+	    TRACE_APPEND(("ERROR: yield outside coroutine\n"));
+	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		    "yield can only be called in a coroutine", -1));
+	    DECACHE_STACK_INFO();
+	    Tcl_SetErrorCode(interp, "TCL", "COROUTINE", "ILLEGAL_YIELD",
+		    NULL);
+	    CACHE_STACK_INFO();
+	    goto gotError;
+	}
+
+#ifdef TCL_COMPILE_DEBUG
+	if (tclTraceExec >= 2) {
+	    if (traceInstructions) {
+		TRACE_APPEND(("YIELD...\n"));
+	    } else {
+		fprintf(stdout, "%d: (%u) yielding value \"%.30s\"\n",
+			iPtr->numLevels, (unsigned)(pc - codePtr->codeStart),
+			Tcl_GetString(OBJ_AT_TOS));
+	    }
+	    fflush(stdout);
+	}
+#endif
+	yieldParameter = 0;
+	Tcl_SetObjResult(interp, OBJ_AT_TOS);
+	goto doYield;
+
+    case INST_YIELD_TO_INVOKE:
+	corPtr = iPtr->execEnvPtr->corPtr;
+	valuePtr = OBJ_AT_TOS;
+	if (!corPtr) {
+	    TRACE(("[%.30s] => ERROR: yield outside coroutine\n",
+		    O2S(valuePtr)));
+	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		    "yieldto can only be called in a coroutine", -1));
+	    DECACHE_STACK_INFO();
+	    Tcl_SetErrorCode(interp, "TCL", "COROUTINE", "ILLEGAL_YIELD",
+		    NULL);
+	    CACHE_STACK_INFO();
+	    goto gotError;
+	}
+	if (((Namespace *)TclGetCurrentNamespace(interp))->flags & NS_DYING) {
+	    TRACE(("[%.30s] => ERROR: yield in deleted\n",
+		    O2S(valuePtr)));
+	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		    "yieldto called in deleted namespace", -1));
+	    DECACHE_STACK_INFO();
+	    Tcl_SetErrorCode(interp, "TCL", "COROUTINE", "YIELDTO_IN_DELETED",
+		    NULL);
+	    CACHE_STACK_INFO();
+	    goto gotError;
+	}
+
+#ifdef TCL_COMPILE_DEBUG
+	if (tclTraceExec >= 2) {
+	    if (traceInstructions) {
+		TRACE(("[%.30s] => YIELD...\n", O2S(valuePtr)));
+	    } else {
+		/* FIXME: What is the right thing to trace? */
+		fprintf(stdout, "%d: (%u) yielding to [%.30s]\n",
+			iPtr->numLevels, (unsigned)(pc - codePtr->codeStart),
+			Tcl_GetString(valuePtr));
+	    }
+	    fflush(stdout);
+	}
+#endif
+
+	/*
+	 * Install a tailcall record in the caller and continue with the
+	 * yield. The yield is switched into multi-return mode (via the
+	 * 'yieldParameter').
+	 */
+
+	Tcl_IncrRefCount(valuePtr);
+	iPtr->execEnvPtr = corPtr->callerEEPtr;
+	TclSetTailcall(interp, valuePtr);
+	iPtr->execEnvPtr = corPtr->eePtr;
+	yieldParameter = (PTR2INT(NULL)+1);	/*==CORO_ACTIVATE_YIELDM*/
+
+    doYield:
+	/* TIP #280: Record the last piece of info needed by
+	 * 'TclGetSrcInfoForPc', and push the frame.
+	 */
+
+	bcFramePtr->data.tebc.pc = (char *) pc;
+	iPtr->cmdFramePtr = bcFramePtr;
+
+	if (iPtr->flags & INTERP_DEBUG_FRAME) {
+	    ArgumentBCEnter(interp, codePtr, TD, pc, objc, objv);
+	}
+
+	pc++;
+	cleanup = 1;
+	TEBC_YIELD();
+	TclNRAddCallback(interp, TclNRCoroutineActivateCallback, corPtr,
+		INT2PTR(yieldParameter), NULL, NULL);
+	return TCL_OK;
+    }
+
+    case INST_TAILCALL: {
+	Tcl_Obj *listPtr, *nsObjPtr;
+
+	opnd = TclGetUInt1AtPtr(pc+1);
+
+	if (!(iPtr->varFramePtr->isProcCallFrame & 1)) {
+	    TRACE(("%d => ERROR: tailcall in non-proc context\n", opnd));
+	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		    "tailcall can only be called from a proc or lambda", -1));
+	    DECACHE_STACK_INFO();
+	    Tcl_SetErrorCode(interp, "TCL", "TAILCALL", "ILLEGAL", NULL);
+	    CACHE_STACK_INFO();
+	    goto gotError;
+	}
+
+#ifdef TCL_COMPILE_DEBUG
+	/* FIXME: What is the right thing to trace? */
+	{
+	    register int i;
+
+	    TRACE(("%d [", opnd));
+	    for (i=opnd-1 ; i>=0 ; i--) {
+		TRACE_APPEND(("\"%.30s\"", O2S(OBJ_AT_DEPTH(i))));
+		if (i > 0) {
+		    TRACE_APPEND((" "));
+		}
+	    }
+	    TRACE_APPEND(("] => RETURN..."));
+	}
+#endif
+
+	/*
+	 * Push the evaluation of the called command into the NR callback
+	 * stack.
+	 */
+
+	listPtr = Tcl_NewListObj(opnd, &OBJ_AT_DEPTH(opnd-1));
+	nsObjPtr = Tcl_NewStringObj(iPtr->varFramePtr->nsPtr->fullName, -1);
+	TclListObjSetElement(interp, listPtr, 0, nsObjPtr);
+	if (iPtr->varFramePtr->tailcallPtr) {
+	    Tcl_DecrRefCount(iPtr->varFramePtr->tailcallPtr);
+	}
+	iPtr->varFramePtr->tailcallPtr = listPtr;
+
+	result = TCL_RETURN;
+	cleanup = opnd;
+	goto processExceptionReturn;
+    }
+
+    case INST_DONE:
+	if (tosPtr > initTosPtr) {
+	    /*
+	     * Set the interpreter's object result to point to the topmost
+	     * object from the stack, and check for a possible [catch]. The
+	     * stackTop's level and refCount will be handled by "processCatch"
+	     * or "abnormalReturn".
+	     */
+
+	    Tcl_SetObjResult(interp, OBJ_AT_TOS);
+#ifdef TCL_COMPILE_DEBUG
+	    TRACE_WITH_OBJ(("=> return code=%d, result=", result),
+		    iPtr->objResultPtr);
+	    if (traceInstructions) {
+		fprintf(stdout, "\n");
+	    }
+#endif
+	    goto checkForCatch;
+	}
+	(void) POP_OBJECT();
+	goto abnormalReturn;
+
+    case INST_PUSH4:
+	objResultPtr = codePtr->objArrayPtr[TclGetUInt4AtPtr(pc+1)];
+	TRACE_WITH_OBJ(("%u => ", TclGetUInt4AtPtr(pc+1)), objResultPtr);
+	NEXT_INST_F(5, 0, 1);
+
+    case INST_POP:
+	TRACE_WITH_OBJ(("=> discarding "), OBJ_AT_TOS);
+	objPtr = POP_OBJECT();
+	TclDecrRefCount(objPtr);
+	NEXT_INST_F(1, 0, 0);
+
+    case INST_DUP:
+	objResultPtr = OBJ_AT_TOS;
+	TRACE_WITH_OBJ(("=> "), objResultPtr);
+	NEXT_INST_F(1, 0, 1);
+
+    case INST_OVER:
+	opnd = TclGetUInt4AtPtr(pc+1);
+	objResultPtr = OBJ_AT_DEPTH(opnd);
+	TRACE_WITH_OBJ(("%u => ", opnd), objResultPtr);
+	NEXT_INST_F(5, 0, 1);
+
+    case INST_REVERSE: {
+	Tcl_Obj **a, **b;
+
+	opnd = TclGetUInt4AtPtr(pc+1);
+	a = tosPtr-(opnd-1);
+	b = tosPtr;
+	while (a<b) {
+	    tmpPtr = *a;
+	    *a = *b;
+	    *b = tmpPtr;
+	    a++; b--;
+	}
+	TRACE(("%u => OK\n", opnd));
+	NEXT_INST_F(5, 0, 0);
+    }
+
+    case INST_STR_CONCAT1: {
+	int appendLen = 0;
+	char *bytes, *p;
+	Tcl_Obj **currPtr;
+	int onlyb = 1;
+
+	opnd = TclGetUInt1AtPtr(pc+1);
+
+	/*
+	 * Detect only-bytearray-or-null case.
+	 */
+
+	for (currPtr=&OBJ_AT_DEPTH(opnd-1); currPtr<=&OBJ_AT_TOS; currPtr++) {
+	    if (((*currPtr)->typePtr != &tclByteArrayType)
+		    && ((*currPtr)->bytes != tclEmptyStringRep)) {
+		onlyb = 0;
+		break;
+	    } else if (((*currPtr)->typePtr == &tclByteArrayType) &&
+		    ((*currPtr)->bytes != NULL)) {
+		onlyb = 0;
+		break;
+	    }
+	}
+
+	/*
+	 * Compute the length to be appended.
+	 */
+
+	if (onlyb) {
+	    for (currPtr = &OBJ_AT_DEPTH(opnd-2);
+		    appendLen >= 0 && currPtr <= &OBJ_AT_TOS; currPtr++) {
+		if ((*currPtr)->bytes != tclEmptyStringRep) {
+		    Tcl_GetByteArrayFromObj(*currPtr, &length);
+		    appendLen += length;
+		}
+	    }
+	} else {
+	    for (currPtr = &OBJ_AT_DEPTH(opnd-2);
+		    appendLen >= 0 && currPtr <= &OBJ_AT_TOS; currPtr++) {
+		bytes = TclGetStringFromObj(*currPtr, &length);
+		if (bytes != NULL) {
+		    appendLen += length;
+		}
+	    }
+	}
+
+	if (appendLen < 0) {
+	    /* TODO: convert panic to error ? */
+	    Tcl_Panic("max size for a Tcl value (%d bytes) exceeded", INT_MAX);
+	}
+
+	/*
+	 * If nothing is to be appended, just return the first object by
+	 * dropping all the others from the stack; this saves both the
+	 * computation and copy of the string rep of the first object,
+	 * enabling the fast '$x[set x {}]' idiom for 'K $x [set x {}]'.
+	 */
+
+	if (appendLen == 0) {
+	    TRACE_WITH_OBJ(("%u => ", opnd), objResultPtr);
+	    NEXT_INST_V(2, (opnd-1), 0);
+	}
+
+	/*
+	 * If the first object is shared, we need a new obj for the result;
+	 * otherwise, we can reuse the first object. In any case, make sure it
+	 * has enough room to accomodate all the concatenated bytes. Note that
+	 * if it is unshared its bytes are copied by ckrealloc, so that we set
+	 * the loop parameters to avoid copying them again: p points to the
+	 * end of the already copied bytes, currPtr to the second object.
+	 */
+
+	objResultPtr = OBJ_AT_DEPTH(opnd-1);
+	if (!onlyb) {
+	    bytes = TclGetStringFromObj(objResultPtr, &length);
+	    if (length + appendLen < 0) {
+		/* TODO: convert panic to error ? */
+		Tcl_Panic("max size for a Tcl value (%d bytes) exceeded",
+			INT_MAX);
+	    }
+#ifndef TCL_COMPILE_DEBUG
+	    if (bytes != tclEmptyStringRep && !Tcl_IsShared(objResultPtr)) {
+		TclFreeIntRep(objResultPtr);
+		objResultPtr->bytes = ckrealloc(bytes, length+appendLen+1);
+		objResultPtr->length = length + appendLen;
+		p = TclGetString(objResultPtr) + length;
+		currPtr = &OBJ_AT_DEPTH(opnd - 2);
+	    } else
+#endif
+	    {
+		p = ckalloc(length + appendLen + 1);
+		TclNewObj(objResultPtr);
+		objResultPtr->bytes = p;
+		objResultPtr->length = length + appendLen;
+		currPtr = &OBJ_AT_DEPTH(opnd - 1);
+	    }
+
+	    /*
+	     * Append the remaining characters.
+	     */
+
+	    for (; currPtr <= &OBJ_AT_TOS; currPtr++) {
+		bytes = TclGetStringFromObj(*currPtr, &length);
+		if (bytes != NULL) {
+		    memcpy(p, bytes, (size_t) length);
+		    p += length;
+		}
+	    }
+	    *p = '\0';
+	} else {
+	    bytes = (char *) Tcl_GetByteArrayFromObj(objResultPtr, &length);
+	    if (length + appendLen < 0) {
+		/* TODO: convert panic to error ? */
+		Tcl_Panic("max size for a Tcl value (%d bytes) exceeded",
+			INT_MAX);
+	    }
+#ifndef TCL_COMPILE_DEBUG
+	    if (!Tcl_IsShared(objResultPtr)) {
+		bytes = (char *) Tcl_SetByteArrayLength(objResultPtr,
+			length + appendLen);
+		p = bytes + length;
+		currPtr = &OBJ_AT_DEPTH(opnd - 2);
+	    } else
+#endif
+	    {
+		TclNewObj(objResultPtr);
+		bytes = (char *) Tcl_SetByteArrayLength(objResultPtr,
+			length + appendLen);
+		p = bytes;
+		currPtr = &OBJ_AT_DEPTH(opnd - 1);
+	    }
+
+	    /*
+	     * Append the remaining characters.
+	     */
+
+	    for (; currPtr <= &OBJ_AT_TOS; currPtr++) {
+		if ((*currPtr)->bytes != tclEmptyStringRep) {
+		    bytes = (char *) Tcl_GetByteArrayFromObj(*currPtr,&length);
+		    memcpy(p, bytes, (size_t) length);
+		    p += length;
+		}
+	    }
+	}
+
+	TRACE_WITH_OBJ(("%u => ", opnd), objResultPtr);
+	NEXT_INST_V(2, opnd, 1);
+    }
+
+    case INST_CONCAT_STK:
+	/*
+	 * Pop the opnd (objc) top stack elements, run through Tcl_ConcatObj,
+	 * and then decrement their ref counts.
+	 */
+
+	opnd = TclGetUInt4AtPtr(pc+1);
+	objResultPtr = Tcl_ConcatObj(opnd, &OBJ_AT_DEPTH(opnd-1));
+	TRACE_WITH_OBJ(("%u => ", opnd), objResultPtr);
+	NEXT_INST_V(5, opnd, 1);
+
+    case INST_EXPAND_START:
+	/*
+	 * Push an element to the auxObjList. This records the current
+	 * stack depth - i.e., the point in the stack where the expanded
+	 * command starts.
+	 *
+	 * Use a Tcl_Obj as linked list element; slight mem waste, but faster
+	 * allocation than ckalloc. This also abuses the Tcl_Obj structure, as
+	 * we do not define a special tclObjType for it. It is not dangerous
+	 * as the obj is never passed anywhere, so that all manipulations are
+	 * performed here and in INST_INVOKE_EXPANDED (in case of an expansion
+	 * error, also in INST_EXPAND_STKTOP).
+	 */
+
+	TclNewObj(objPtr);
+	objPtr->internalRep.twoPtrValue.ptr2 = INT2PTR(CURR_DEPTH);
+	objPtr->length = 0;
+	PUSH_TAUX_OBJ(objPtr);
+	TRACE(("=> mark depth as %d\n", (int) CURR_DEPTH));
+	NEXT_INST_F(1, 0, 0);
+
+    case INST_EXPAND_DROP:
+	/*
+	 * Drops an element of the auxObjList, popping stack elements to
+	 * restore the stack to the state before the point where the aux
+	 * element was created.
+	 */
+
+	CLANG_ASSERT(auxObjList);
+	objc = CURR_DEPTH - PTR2INT(auxObjList->internalRep.twoPtrValue.ptr2);
+	POP_TAUX_OBJ();
+#ifdef TCL_COMPILE_DEBUG
+	/* Ugly abuse! */
+	starting = 1;
+#endif
+	TRACE(("=> drop %d items\n", objc));
+	NEXT_INST_V(1, objc, 0);
+
+    case INST_EXPAND_STKTOP: {
+	int i;
+	ptrdiff_t moved;
+
+	/*
+	 * Make sure that the element at stackTop is a list; if not, just
+	 * leave with an error. Note that the element from the expand list
+	 * will be removed at checkForCatch.
+	 */
+
+	objPtr = OBJ_AT_TOS;
+	TRACE(("\"%.30s\" => ", O2S(objPtr)));
+	if (TclListObjGetElements(interp, objPtr, &objc, &objv) != TCL_OK) {
+	    TRACE_ERROR(interp);
+	    goto gotError;
+	}
+	(void) POP_OBJECT();
+
+	/*
+	 * Make sure there is enough room in the stack to expand this list
+	 * *and* process the rest of the command (at least up to the next
+	 * argument expansion or command end). The operand is the current
+	 * stack depth, as seen by the compiler.
+	 */
+
+	auxObjList->length += objc - 1;
+	if ((objc > 1) && (auxObjList->length > 0)) {
+	    length = auxObjList->length /* Total expansion room we need */
+		    + codePtr->maxStackDepth /* Beyond the original max */
+		    - CURR_DEPTH;	/* Relative to where we are */
+	    DECACHE_STACK_INFO();
+	    moved = GrowEvaluationStack(iPtr->execEnvPtr, length, 1)
+		    - (Tcl_Obj **) TD;
+	    if (moved) {
+		/*
+		 * Change the global data to point to the new stack: move the
+		 * TEBCdataPtr TD, recompute the position of every other
+		 * stack-allocated parameter, update the stack pointers.
+		 */
+
+		TD = (TEBCdata *) (((Tcl_Obj **)TD) + moved);
+
+		catchTop += moved;
+		tosPtr += moved;
+	    }
+	}
+
+	/*
+	 * Expand the list at stacktop onto the stack; free the list. Knowing
+	 * that it has a freeIntRepProc we use Tcl_DecrRefCount().
+	 */
+
+	for (i = 0; i < objc; i++) {
+	    PUSH_OBJECT(objv[i]);
+	}
+
+	TRACE_APPEND(("OK\n"));
+	Tcl_DecrRefCount(objPtr);
+	NEXT_INST_F(5, 0, 0);
+    }
+
+    case INST_EXPR_STK: {
+	ByteCode *newCodePtr;
+
+	bcFramePtr->data.tebc.pc = (char *) pc;
+	iPtr->cmdFramePtr = bcFramePtr;
+	DECACHE_STACK_INFO();
+	newCodePtr = CompileExprObj(interp, OBJ_AT_TOS);
+	CACHE_STACK_INFO();
+	cleanup = 1;
+	pc++;
+	TEBC_YIELD();
+	return TclNRExecuteByteCode(interp, newCodePtr);
+    }
+
+	/*
+	 * INVOCATION BLOCK
+	 */
+
+    instEvalStk:
+    case INST_EVAL_STK:
+	bcFramePtr->data.tebc.pc = (char *) pc;
+	iPtr->cmdFramePtr = bcFramePtr;
+
+	cleanup = 1;
+	pc += 1;
+	TEBC_YIELD();
+	return TclNREvalObjEx(interp, OBJ_AT_TOS, 0, NULL, 0);
+
+    case INST_INVOKE_EXPANDED:
+	CLANG_ASSERT(auxObjList);
+	objc = CURR_DEPTH - PTR2INT(auxObjList->internalRep.twoPtrValue.ptr2);
+	POP_TAUX_OBJ();
+	if (objc) {
+	    pcAdjustment = 1;
+	    goto doInvocation;
+	}
+
+	/*
+	 * Nothing was expanded, return {}.
+	 */
+
+	TclNewObj(objResultPtr);
+	NEXT_INST_F(1, 0, 1);
+
+    case INST_INVOKE_STK4:
+	objc = TclGetUInt4AtPtr(pc+1);
+	pcAdjustment = 5;
+	goto doInvocation;
+
+    case INST_INVOKE_STK1:
+	objc = TclGetUInt1AtPtr(pc+1);
+	pcAdjustment = 2;
+
+    doInvocation:
+	objv = &OBJ_AT_DEPTH(objc-1);
+	cleanup = objc;
+
+#ifdef TCL_COMPILE_DEBUG
+	if (tclTraceExec >= 2) {
+	    int i;
+
+	    if (traceInstructions) {
+		strncpy(cmdNameBuf, TclGetString(objv[0]), 20);
+		TRACE(("%u => call ", objc));
+	    } else {
+		fprintf(stdout, "%d: (%u) invoking ", iPtr->numLevels,
+			(unsigned)(pc - codePtr->codeStart));
+	    }
+	    for (i = 0;  i < objc;  i++) {
+		TclPrintObject(stdout, objv[i], 15);
+		fprintf(stdout, " ");
+	    }
+	    fprintf(stdout, "\n");
+	    fflush(stdout);
+	}
+#endif /*TCL_COMPILE_DEBUG*/
+
+	/*
+	 * Finally, let TclEvalObjv handle the command.
+	 *
+	 * TIP #280: Record the last piece of info needed by
+	 * 'TclGetSrcInfoForPc', and push the frame.
+	 */
+
+	bcFramePtr->data.tebc.pc = (char *) pc;
+	iPtr->cmdFramePtr = bcFramePtr;
+
+	if (iPtr->flags & INTERP_DEBUG_FRAME) {
+	    ArgumentBCEnter(interp, codePtr, TD, pc, objc, objv);
+	}
+
+	DECACHE_STACK_INFO();
+
+	pc += pcAdjustment;
+	TEBC_YIELD();
+	return TclNREvalObjv(interp, objc, objv,
+		TCL_EVAL_NOERR | TCL_EVAL_SOURCE_IN_FRAME, NULL);
+
+#if TCL_SUPPORT_84_BYTECODE
+    case INST_CALL_BUILTIN_FUNC1:
+	/*
+	 * Call one of the built-in pre-8.5 Tcl math functions. This
+	 * translates to INST_INVOKE_STK1 with the first argument of
+	 * ::tcl::mathfunc::$objv[0]. We need to insert the named math
+	 * function into the stack.
+	 */
+
+	opnd = TclGetUInt1AtPtr(pc+1);
+	if ((opnd < 0) || (opnd > LAST_BUILTIN_FUNC)) {
+	    TRACE(("UNRECOGNIZED BUILTIN FUNC CODE %d\n", opnd));
+	    Tcl_Panic("TclNRExecuteByteCode: unrecognized builtin function code %d", opnd);
+	}
+
+	TclNewLiteralStringObj(objPtr, "::tcl::mathfunc::");
+	Tcl_AppendToObj(objPtr, tclBuiltinFuncTable[opnd].name, -1);
+
+	/*
+	 * Only 0, 1 or 2 args.
+	 */
+
+	{
+	    int numArgs = tclBuiltinFuncTable[opnd].numArgs;
+	    Tcl_Obj *tmpPtr1, *tmpPtr2;
+
+	    if (numArgs == 0) {
+		PUSH_OBJECT(objPtr);
+	    } else if (numArgs == 1) {
+		tmpPtr1 = POP_OBJECT();
+		PUSH_OBJECT(objPtr);
+		PUSH_OBJECT(tmpPtr1);
+		Tcl_DecrRefCount(tmpPtr1);
+	    } else {
+		tmpPtr2 = POP_OBJECT();
+		tmpPtr1 = POP_OBJECT();
+		PUSH_OBJECT(objPtr);
+		PUSH_OBJECT(tmpPtr1);
+		PUSH_OBJECT(tmpPtr2);
+		Tcl_DecrRefCount(tmpPtr1);
+		Tcl_DecrRefCount(tmpPtr2);
+	    }
+	    objc = numArgs + 1;
+	}
+	pcAdjustment = 2;
+	goto doInvocation;
+
+    case INST_CALL_FUNC1:
+	/*
+	 * Call a non-builtin Tcl math function previously registered by a
+	 * call to Tcl_CreateMathFunc pre-8.5. This is essentially
+	 * INST_INVOKE_STK1 converting the first arg to
+	 * ::tcl::mathfunc::$objv[0].
+	 */
+
+	objc = TclGetUInt1AtPtr(pc+1);	/* Number of arguments. The function
+					 * name is the 0-th argument. */
+
+	objPtr = OBJ_AT_DEPTH(objc-1);
+	TclNewLiteralStringObj(tmpPtr, "::tcl::mathfunc::");
+	Tcl_AppendObjToObj(tmpPtr, objPtr);
+	Tcl_DecrRefCount(objPtr);
+
+	/*
+	 * Variation of PUSH_OBJECT.
+	 */
+
+	OBJ_AT_DEPTH(objc-1) = tmpPtr;
+	Tcl_IncrRefCount(tmpPtr);
+
+	pcAdjustment = 2;
+	goto doInvocation;
+#else
+    /*
+     * INST_CALL_BUILTIN_FUNC1 and INST_CALL_FUNC1 were made obsolete by the
+     * changes to add a ::tcl::mathfunc namespace in 8.5. Optional support
+     * remains for existing bytecode precompiled files.
+     */
+
+    case INST_CALL_BUILTIN_FUNC1:
+	Tcl_Panic("TclNRExecuteByteCode: obsolete INST_CALL_BUILTIN_FUNC1 found");
+    case INST_CALL_FUNC1:
+	Tcl_Panic("TclNRExecuteByteCode: obsolete INST_CALL_FUNC1 found");
+#endif
+
+    case INST_INVOKE_REPLACE:
+	objc = TclGetUInt4AtPtr(pc+1);
+	opnd = TclGetUInt1AtPtr(pc+5);
+	objPtr = POP_OBJECT();
+	objv = &OBJ_AT_DEPTH(objc-1);
+	cleanup = objc;
+#ifdef TCL_COMPILE_DEBUG
+	if (tclTraceExec >= 2) {
+	    int i;
+
+	    if (traceInstructions) {
+		strncpy(cmdNameBuf, TclGetString(objv[0]), 20);
+		TRACE(("%u => call (implementation %s) ", objc, O2S(objPtr)));
+	    } else {
+		fprintf(stdout,
+			"%d: (%u) invoking (using implementation %s) ",
+			iPtr->numLevels, (unsigned)(pc - codePtr->codeStart),
+			O2S(objPtr));
+	    }
+	    for (i = 0;  i < objc;  i++) {
+		if (i < opnd) {
+		    fprintf(stdout, "<");
+		    TclPrintObject(stdout, objv[i], 15);
+		    fprintf(stdout, ">");
+		} else {
+		    TclPrintObject(stdout, objv[i], 15);
+		}
+		fprintf(stdout, " ");
+	    }
+	    fprintf(stdout, "\n");
+	    fflush(stdout);
+	}
+#endif /*TCL_COMPILE_DEBUG*/
+
+	bcFramePtr->data.tebc.pc = (char *) pc;
+	iPtr->cmdFramePtr = bcFramePtr;
+	if (iPtr->flags & INTERP_DEBUG_FRAME) {
+	    ArgumentBCEnter(interp, codePtr, TD, pc, objc, objv);
+	}
+
+	TclInitRewriteEnsemble(interp, opnd, 1, objv);
+
+	{
+	    Tcl_Obj *copyPtr = Tcl_NewListObj(objc - opnd + 1, NULL);
+
+	    Tcl_ListObjAppendElement(NULL, copyPtr, objPtr);
+	    Tcl_ListObjReplace(NULL, copyPtr, LIST_MAX, 0, 
+		    objc - opnd, objv + opnd);
+	    Tcl_DecrRefCount(objPtr);
+	    objPtr = copyPtr;
+	}
+
+	DECACHE_STACK_INFO();
+	pc += 6;
+	TEBC_YIELD();
+
+	TclMarkTailcall(interp);
+	TclNRAddCallback(interp, TclClearRootEnsemble, NULL, NULL, NULL, NULL);
+	Tcl_ListObjGetElements(NULL, objPtr, &objc, &objv);
+	TclNRAddCallback(interp, TclNRReleaseValues, objPtr, NULL, NULL, NULL);
+	return TclNREvalObjv(interp, objc, objv, TCL_EVAL_INVOKE, NULL);
+
+    /*
+     * -----------------------------------------------------------------
+     *	   Start of INST_LOAD instructions.
+     *
+     * WARNING: more 'goto' here than your doctor recommended! The different
+     * instructions set the value of some variables and then jump to some
+     * common execution code.
+     */
+
+    case INST_LOAD_SCALAR1:
+    instLoadScalar1:
+	opnd = TclGetUInt1AtPtr(pc+1);
+	varPtr = LOCAL(opnd);
+	while (TclIsVarLink(varPtr)) {
+	    varPtr = varPtr->value.linkPtr;
+	}
+	TRACE(("%u => ", opnd));
+	if (TclIsVarDirectReadable(varPtr)) {
+	    /*
+	     * No errors, no traces: just get the value.
+	     */
+
+	    objResultPtr = varPtr->value.objPtr;
+	    TRACE_APPEND(("%.30s\n", O2S(objResultPtr)));
+	    NEXT_INST_F(2, 0, 1);
+	}
+	pcAdjustment = 2;
+	cleanup = 0;
+	arrayPtr = NULL;
+	part1Ptr = part2Ptr = NULL;
+	goto doCallPtrGetVar;
+
+    case INST_LOAD_SCALAR4:
+	opnd = TclGetUInt4AtPtr(pc+1);
+	varPtr = LOCAL(opnd);
+	while (TclIsVarLink(varPtr)) {
+	    varPtr = varPtr->value.linkPtr;
+	}
+	TRACE(("%u => ", opnd));
+	if (TclIsVarDirectReadable(varPtr)) {
+	    /*
+	     * No errors, no traces: just get the value.
+	     */
+
+	    objResultPtr = varPtr->value.objPtr;
+	    TRACE_APPEND(("%.30s\n", O2S(objResultPtr)));
+	    NEXT_INST_F(5, 0, 1);
+	}
+	pcAdjustment = 5;
+	cleanup = 0;
+	arrayPtr = NULL;
+	part1Ptr = part2Ptr = NULL;
+	goto doCallPtrGetVar;
+
+    case INST_LOAD_ARRAY4:
+	opnd = TclGetUInt4AtPtr(pc+1);
+	pcAdjustment = 5;
+	goto doLoadArray;
+
+    case INST_LOAD_ARRAY1:
+	opnd = TclGetUInt1AtPtr(pc+1);
+	pcAdjustment = 2;
+
+    doLoadArray:
+	part1Ptr = NULL;
+	part2Ptr = OBJ_AT_TOS;
+	arrayPtr = LOCAL(opnd);
+	while (TclIsVarLink(arrayPtr)) {
+	    arrayPtr = arrayPtr->value.linkPtr;
+	}
+	TRACE(("%u \"%.30s\" => ", opnd, O2S(part2Ptr)));
+	if (TclIsVarArray(arrayPtr) && !ReadTraced(arrayPtr)) {
+	    varPtr = VarHashFindVar(arrayPtr->value.tablePtr, part2Ptr);
+	    if (varPtr && TclIsVarDirectReadable(varPtr)) {
+		/*
+		 * No errors, no traces: just get the value.
+		 */
+
+		objResultPtr = varPtr->value.objPtr;
+		TRACE_APPEND(("%.30s\n", O2S(objResultPtr)));
+		NEXT_INST_F(pcAdjustment, 1, 1);
+	    }
+	}
+	varPtr = TclLookupArrayElement(interp, part1Ptr, part2Ptr,
+		TCL_LEAVE_ERR_MSG, "read", 0, 1, arrayPtr, opnd);
+	if (varPtr == NULL) {
+	    TRACE_ERROR(interp);
+	    goto gotError;
+	}
+	cleanup = 1;
+	goto doCallPtrGetVar;
+
+    case INST_LOAD_ARRAY_STK:
+	cleanup = 2;
+	part2Ptr = OBJ_AT_TOS;		/* element name */
+	objPtr = OBJ_UNDER_TOS;		/* array name */
+	TRACE(("\"%.30s(%.30s)\" => ", O2S(objPtr), O2S(part2Ptr)));
+	goto doLoadStk;
+
+    case INST_LOAD_STK:
+    case INST_LOAD_SCALAR_STK:
+	cleanup = 1;
+	part2Ptr = NULL;
+	objPtr = OBJ_AT_TOS;		/* variable name */
+	TRACE(("\"%.30s\" => ", O2S(objPtr)));
+
+    doLoadStk:
+	part1Ptr = objPtr;
+	varPtr = TclObjLookupVarEx(interp, part1Ptr, part2Ptr,
+		TCL_LEAVE_ERR_MSG, "read", /*createPart1*/0, /*createPart2*/1,
+		&arrayPtr);
+	if (!varPtr) {
+	    TRACE_ERROR(interp);
+	    goto gotError;
+	}
+
+	if (TclIsVarDirectReadable2(varPtr, arrayPtr)) {
+	    /*
+	     * No errors, no traces: just get the value.
+	     */
+
+	    objResultPtr = varPtr->value.objPtr;
+	    TRACE_APPEND(("%.30s\n", O2S(objResultPtr)));
+	    NEXT_INST_V(1, cleanup, 1);
+	}
+	pcAdjustment = 1;
+	opnd = -1;
+
+    doCallPtrGetVar:
+	/*
+	 * There are either errors or the variable is traced: call
+	 * TclPtrGetVar to process fully.
+	 */
+
+	DECACHE_STACK_INFO();
+	objResultPtr = TclPtrGetVar(interp, varPtr, arrayPtr,
+		part1Ptr, part2Ptr, TCL_LEAVE_ERR_MSG, opnd);
+	CACHE_STACK_INFO();
+	if (!objResultPtr) {
+	    TRACE_ERROR(interp);
+	    goto gotError;
+	}
+	TRACE_APPEND(("%.30s\n", O2S(objResultPtr)));
+	NEXT_INST_V(pcAdjustment, cleanup, 1);
+
+    /*
+     *	   End of INST_LOAD instructions.
+     * -----------------------------------------------------------------
+     *	   Start of INST_STORE and related instructions.
+     *
+     * WARNING: more 'goto' here than your doctor recommended! The different
+     * instructions set the value of some variables and then jump to somme
+     * common execution code.
+     */
+
+    {
+	int storeFlags, len;
+
+    case INST_STORE_ARRAY4:
+	opnd = TclGetUInt4AtPtr(pc+1);
+	pcAdjustment = 5;
+	goto doStoreArrayDirect;
+
+    case INST_STORE_ARRAY1:
+	opnd = TclGetUInt1AtPtr(pc+1);
+	pcAdjustment = 2;
+
+    doStoreArrayDirect:
+	valuePtr = OBJ_AT_TOS;
+	part2Ptr = OBJ_UNDER_TOS;
+	arrayPtr = LOCAL(opnd);
+	TRACE(("%u \"%.30s\" <- \"%.30s\" => ", opnd, O2S(part2Ptr),
+		O2S(valuePtr)));
+	while (TclIsVarLink(arrayPtr)) {
+	    arrayPtr = arrayPtr->value.linkPtr;
+	}
+	if (TclIsVarArray(arrayPtr) && !WriteTraced(arrayPtr)) {
+	    varPtr = VarHashFindVar(arrayPtr->value.tablePtr, part2Ptr);
+	    if (varPtr && TclIsVarDirectWritable(varPtr)) {
+		tosPtr--;
+		Tcl_DecrRefCount(OBJ_AT_TOS);
+		OBJ_AT_TOS = valuePtr;
+		goto doStoreVarDirect;
+	    }
+	}
+	cleanup = 2;
+	storeFlags = TCL_LEAVE_ERR_MSG;
+	part1Ptr = NULL;
+	goto doStoreArrayDirectFailed;
+
+    case INST_STORE_SCALAR4:
+	opnd = TclGetUInt4AtPtr(pc+1);
+	pcAdjustment = 5;
+	goto doStoreScalarDirect;
+
+    case INST_STORE_SCALAR1:
+	opnd = TclGetUInt1AtPtr(pc+1);
+	pcAdjustment = 2;
+
+    doStoreScalarDirect:
+	valuePtr = OBJ_AT_TOS;
+	varPtr = LOCAL(opnd);
+	TRACE(("%u <- \"%.30s\" => ", opnd, O2S(valuePtr)));
+	while (TclIsVarLink(varPtr)) {
+	    varPtr = varPtr->value.linkPtr;
+	}
+	if (!TclIsVarDirectWritable(varPtr)) {
+	    storeFlags = TCL_LEAVE_ERR_MSG;
+	    part1Ptr = NULL;
+	    goto doStoreScalar;
+	}
+
+	/*
+	 * No traces, no errors, plain 'set': we can safely inline. The value
+	 * *will* be set to what's requested, so that the stack top remains
+	 * pointing to the same Tcl_Obj.
+	 */
+
+    doStoreVarDirect:
+	valuePtr = varPtr->value.objPtr;
+	if (valuePtr != NULL) {
+	    TclDecrRefCount(valuePtr);
+	}
+	objResultPtr = OBJ_AT_TOS;
+	varPtr->value.objPtr = objResultPtr;
+#ifndef TCL_COMPILE_DEBUG
+	if (*(pc+pcAdjustment) == INST_POP) {
+	    tosPtr--;
+	    NEXT_INST_F((pcAdjustment+1), 0, 0);
+	}
+#else
+	TRACE_APPEND(("%.30s\n", O2S(objResultPtr)));
+#endif
+	Tcl_IncrRefCount(objResultPtr);
+	NEXT_INST_F(pcAdjustment, 0, 0);
+
+    case INST_LAPPEND_STK:
+	valuePtr = OBJ_AT_TOS; /* value to append */
+	part2Ptr = NULL;
+	storeFlags = (TCL_LEAVE_ERR_MSG | TCL_APPEND_VALUE
+		| TCL_LIST_ELEMENT);
+	goto doStoreStk;
+
+    case INST_LAPPEND_ARRAY_STK:
+	valuePtr = OBJ_AT_TOS; /* value to append */
+	part2Ptr = OBJ_UNDER_TOS;
+	storeFlags = (TCL_LEAVE_ERR_MSG | TCL_APPEND_VALUE
+		| TCL_LIST_ELEMENT);
+	goto doStoreStk;
+
+    case INST_APPEND_STK:
+	valuePtr = OBJ_AT_TOS; /* value to append */
+	part2Ptr = NULL;
+	storeFlags = (TCL_LEAVE_ERR_MSG | TCL_APPEND_VALUE);
+	goto doStoreStk;
+
+    case INST_APPEND_ARRAY_STK:
+	valuePtr = OBJ_AT_TOS; /* value to append */
+	part2Ptr = OBJ_UNDER_TOS;
+	storeFlags = (TCL_LEAVE_ERR_MSG | TCL_APPEND_VALUE);
+	goto doStoreStk;
+
+    case INST_STORE_ARRAY_STK:
+	valuePtr = OBJ_AT_TOS;
+	part2Ptr = OBJ_UNDER_TOS;
+	storeFlags = TCL_LEAVE_ERR_MSG;
+	goto doStoreStk;
+
+    case INST_STORE_STK:
+    case INST_STORE_SCALAR_STK:
+	valuePtr = OBJ_AT_TOS;
+	part2Ptr = NULL;
+	storeFlags = TCL_LEAVE_ERR_MSG;
+
+    doStoreStk:
+	objPtr = OBJ_AT_DEPTH(1 + (part2Ptr != NULL)); /* variable name */
+	part1Ptr = objPtr;
+#ifdef TCL_COMPILE_DEBUG
+	if (part2Ptr == NULL) {
+	    TRACE(("\"%.30s\" <- \"%.30s\" =>", O2S(part1Ptr),O2S(valuePtr)));
+	} else {
+	    TRACE(("\"%.30s(%.30s)\" <- \"%.30s\" => ",
+		    O2S(part1Ptr), O2S(part2Ptr), O2S(valuePtr)));
+	}
+#endif
+	varPtr = TclObjLookupVarEx(interp, objPtr,part2Ptr, TCL_LEAVE_ERR_MSG,
+		"set", /*createPart1*/ 1, /*createPart2*/ 1, &arrayPtr);
+	if (!varPtr) {
+	    TRACE_ERROR(interp);
+	    goto gotError;
+	}
+	cleanup = ((part2Ptr == NULL)? 2 : 3);
+	pcAdjustment = 1;
+	opnd = -1;
+	goto doCallPtrSetVar;
+
+    case INST_LAPPEND_ARRAY4:
+	opnd = TclGetUInt4AtPtr(pc+1);
+	pcAdjustment = 5;
+	storeFlags = (TCL_LEAVE_ERR_MSG | TCL_APPEND_VALUE
+		| TCL_LIST_ELEMENT);
+	goto doStoreArray;
+
+    case INST_LAPPEND_ARRAY1:
+	opnd = TclGetUInt1AtPtr(pc+1);
+	pcAdjustment = 2;
+	storeFlags = (TCL_LEAVE_ERR_MSG | TCL_APPEND_VALUE
+		| TCL_LIST_ELEMENT);
+	goto doStoreArray;
+
+    case INST_APPEND_ARRAY4:
+	opnd = TclGetUInt4AtPtr(pc+1);
+	pcAdjustment = 5;
+	storeFlags = (TCL_LEAVE_ERR_MSG | TCL_APPEND_VALUE);
+	goto doStoreArray;
+
+    case INST_APPEND_ARRAY1:
+	opnd = TclGetUInt1AtPtr(pc+1);
+	pcAdjustment = 2;
+	storeFlags = (TCL_LEAVE_ERR_MSG | TCL_APPEND_VALUE);
+	goto doStoreArray;
+
+    doStoreArray:
+	valuePtr = OBJ_AT_TOS;
+	part2Ptr = OBJ_UNDER_TOS;
+	arrayPtr = LOCAL(opnd);
+	TRACE(("%u \"%.30s\" <- \"%.30s\" => ", opnd, O2S(part2Ptr),
+		O2S(valuePtr)));
+	while (TclIsVarLink(arrayPtr)) {
+	    arrayPtr = arrayPtr->value.linkPtr;
+	}
+	cleanup = 2;
+	part1Ptr = NULL;
+
+    doStoreArrayDirectFailed:
+	varPtr = TclLookupArrayElement(interp, part1Ptr, part2Ptr,
+		TCL_LEAVE_ERR_MSG, "set", 1, 1, arrayPtr, opnd);
+	if (!varPtr) {
+	    TRACE_ERROR(interp);
+	    goto gotError;
+	}
+	goto doCallPtrSetVar;
+
+    case INST_LAPPEND_SCALAR4:
+	opnd = TclGetUInt4AtPtr(pc+1);
+	pcAdjustment = 5;
+	storeFlags = (TCL_LEAVE_ERR_MSG | TCL_APPEND_VALUE
+		| TCL_LIST_ELEMENT);
+	goto doStoreScalar;
+
+    case INST_LAPPEND_SCALAR1:
+	opnd = TclGetUInt1AtPtr(pc+1);
+	pcAdjustment = 2;
+	storeFlags = (TCL_LEAVE_ERR_MSG | TCL_APPEND_VALUE
+		| TCL_LIST_ELEMENT);
+	goto doStoreScalar;
+
+    case INST_APPEND_SCALAR4:
+	opnd = TclGetUInt4AtPtr(pc+1);
+	pcAdjustment = 5;
+	storeFlags = (TCL_LEAVE_ERR_MSG | TCL_APPEND_VALUE);
+	goto doStoreScalar;
+
+    case INST_APPEND_SCALAR1:
+	opnd = TclGetUInt1AtPtr(pc+1);
+	pcAdjustment = 2;
+	storeFlags = (TCL_LEAVE_ERR_MSG | TCL_APPEND_VALUE);
+	goto doStoreScalar;
+
+    doStoreScalar:
+	valuePtr = OBJ_AT_TOS;
+	varPtr = LOCAL(opnd);
+	TRACE(("%u <- \"%.30s\" => ", opnd, O2S(valuePtr)));
+	while (TclIsVarLink(varPtr)) {
+	    varPtr = varPtr->value.linkPtr;
+	}
+	cleanup = 1;
+	arrayPtr = NULL;
+	part1Ptr = part2Ptr = NULL;
+
+    doCallPtrSetVar:
+	DECACHE_STACK_INFO();
+	objResultPtr = TclPtrSetVar(interp, varPtr, arrayPtr,
+		part1Ptr, part2Ptr, valuePtr, storeFlags, opnd);
+	CACHE_STACK_INFO();
+	if (!objResultPtr) {
+	    TRACE_ERROR(interp);
+	    goto gotError;
+	}
+#ifndef TCL_COMPILE_DEBUG
+	if (*(pc+pcAdjustment) == INST_POP) {
+	    NEXT_INST_V((pcAdjustment+1), cleanup, 0);
+	}
+#endif
+	TRACE_APPEND(("%.30s\n", O2S(objResultPtr)));
+	NEXT_INST_V(pcAdjustment, cleanup, 1);
+
+    case INST_LAPPEND_LIST:
+	opnd = TclGetUInt4AtPtr(pc+1);
+	valuePtr = OBJ_AT_TOS;
+	varPtr = LOCAL(opnd);
+	cleanup = 1;
+	pcAdjustment = 5;
+	while (TclIsVarLink(varPtr)) {
+	    varPtr = varPtr->value.linkPtr;
+	}
+	TRACE(("%u <- \"%.30s\" => ", opnd, O2S(valuePtr)));
+	if (TclListObjGetElements(interp, valuePtr, &objc, &objv)
+		!= TCL_OK) {
+	    TRACE_ERROR(interp);
+	    goto gotError;
+	}
+	if (TclIsVarDirectReadable(varPtr)
+		&& TclIsVarDirectWritable(varPtr)) {
+	    goto lappendListDirect;
+	}
+	arrayPtr = NULL;
+	part1Ptr = part2Ptr = NULL;
+	goto lappendListPtr;
+
+    case INST_LAPPEND_LIST_ARRAY:
+	opnd = TclGetUInt4AtPtr(pc+1);
+	valuePtr = OBJ_AT_TOS;
+	part1Ptr = NULL;
+	part2Ptr = OBJ_UNDER_TOS;
+	arrayPtr = LOCAL(opnd);
+	cleanup = 2;
+	pcAdjustment = 5;
+	while (TclIsVarLink(arrayPtr)) {
+	    arrayPtr = arrayPtr->value.linkPtr;
+	}
+	TRACE(("%u \"%.30s\" \"%.30s\" => ",
+		opnd, O2S(part2Ptr), O2S(valuePtr)));
+	if (TclListObjGetElements(interp, valuePtr, &objc, &objv)
+		!= TCL_OK) {
+	    TRACE_ERROR(interp);
+	    goto gotError;
+	}
+	if (TclIsVarArray(arrayPtr) && !ReadTraced(arrayPtr)
+		&& !WriteTraced(arrayPtr)) {
+	    varPtr = VarHashFindVar(arrayPtr->value.tablePtr, part2Ptr);
+	    if (varPtr && TclIsVarDirectReadable(varPtr)
+		    && TclIsVarDirectWritable(varPtr)) {
+		goto lappendListDirect;
+	    }
+	}
+	varPtr = TclLookupArrayElement(interp, part1Ptr, part2Ptr,
+		TCL_LEAVE_ERR_MSG, "set", 1, 1, arrayPtr, opnd);
+	if (varPtr == NULL) {
+	    TRACE_ERROR(interp);
+	    goto gotError;
+	}
+	goto lappendListPtr;
+
+    case INST_LAPPEND_LIST_ARRAY_STK:
+	pcAdjustment = 1;
+	cleanup = 3;
+	valuePtr = OBJ_AT_TOS;
+	part2Ptr = OBJ_UNDER_TOS;	/* element name */
+	part1Ptr = OBJ_AT_DEPTH(2);	/* array name */
+	TRACE(("\"%.30s(%.30s)\" \"%.30s\" => ",
+		O2S(part1Ptr), O2S(part2Ptr), O2S(valuePtr)));
+	goto lappendList;
+
+    case INST_LAPPEND_LIST_STK:
+	pcAdjustment = 1;
+	cleanup = 2;
+	valuePtr = OBJ_AT_TOS;
+	part2Ptr = NULL;
+	part1Ptr = OBJ_UNDER_TOS;	/* variable name */
+	TRACE(("\"%.30s\" \"%.30s\" => ", O2S(part1Ptr), O2S(valuePtr)));
+	goto lappendList;
+
+    lappendListDirect:
+	objResultPtr = varPtr->value.objPtr;
+	if (TclListObjLength(interp, objResultPtr, &len) != TCL_OK) {
+	    TRACE_ERROR(interp);
+	    goto gotError;
+	}
+	if (Tcl_IsShared(objResultPtr)) {
+	    Tcl_Obj *newValue = Tcl_DuplicateObj(objResultPtr);
+
+	    TclDecrRefCount(objResultPtr);
+	    varPtr->value.objPtr = objResultPtr = newValue;
+	    Tcl_IncrRefCount(newValue);
+	}
+	if (Tcl_ListObjReplace(interp, objResultPtr, len, 0, objc, objv)
+		!= TCL_OK) {
+	    TRACE_ERROR(interp);
+	    goto gotError;
+	}
+	TRACE_APPEND(("%.30s\n", O2S(objResultPtr)));
+	NEXT_INST_V(pcAdjustment, cleanup, 1);
+
+    lappendList:
+	opnd = -1;
+	if (TclListObjGetElements(interp, valuePtr, &objc, &objv)
+		!= TCL_OK) {
+	    TRACE_ERROR(interp);
+	    goto gotError;
+	}
+	DECACHE_STACK_INFO();
+	varPtr = TclObjLookupVarEx(interp, part1Ptr, part2Ptr,
+		TCL_LEAVE_ERR_MSG, "set", 1, 1, &arrayPtr);
+	CACHE_STACK_INFO();
+	if (!varPtr) {
+	    TRACE_ERROR(interp);
+	    goto gotError;
+	}
+
+    lappendListPtr:
+	if (TclIsVarInHash(varPtr)) {
+	    VarHashRefCount(varPtr)++;
+	}
+	if (arrayPtr && TclIsVarInHash(arrayPtr)) {
+	    VarHashRefCount(arrayPtr)++;
+	}
+	DECACHE_STACK_INFO();
+	objResultPtr = TclPtrGetVar(interp, varPtr, arrayPtr,
+		part1Ptr, part2Ptr, TCL_LEAVE_ERR_MSG, opnd);
+	CACHE_STACK_INFO();
+	if (TclIsVarInHash(varPtr)) {
+	    VarHashRefCount(varPtr)--;
+	}
+	if (arrayPtr && TclIsVarInHash(arrayPtr)) {
+	    VarHashRefCount(arrayPtr)--;
+	}
+
+	{
+	    int createdNewObj = 0;
+
+	    if (!objResultPtr) {
+		objResultPtr = valuePtr;
+	    } else if (TclListObjLength(interp, objResultPtr, &len)!=TCL_OK) {
+		TRACE_ERROR(interp);
+		goto gotError;
+	    } else {
+		if (Tcl_IsShared(objResultPtr)) {
+		    objResultPtr = Tcl_DuplicateObj(objResultPtr);
+		    createdNewObj = 1;
+		}
+		if (Tcl_ListObjReplace(interp, objResultPtr, len,0, objc,objv)
+			!= TCL_OK) {
+		    goto errorInLappendListPtr;
+		}
+	    }
+	    DECACHE_STACK_INFO();
+	    objResultPtr = TclPtrSetVar(interp, varPtr, arrayPtr, part1Ptr,
+		    part2Ptr, objResultPtr, TCL_LEAVE_ERR_MSG, opnd);
+	    CACHE_STACK_INFO();
+	    if (!objResultPtr) {
+	    errorInLappendListPtr:
+		if (createdNewObj) {
+		    TclDecrRefCount(objResultPtr);
+		}
+		TRACE_ERROR(interp);
+		goto gotError;
+	    }
+	}
+	TRACE_APPEND(("%.30s\n", O2S(objResultPtr)));
+	NEXT_INST_V(pcAdjustment, cleanup, 1);
+    }
+
+    /*
+     *	   End of INST_STORE and related instructions.
+     * -----------------------------------------------------------------
+     *	   Start of INST_INCR instructions.
+     *
+     * WARNING: more 'goto' here than your doctor recommended! The different
+     * instructions set the value of some variables and then jump to somme
+     * common execution code.
+     */
+
+/*TODO: Consider more untangling here; merge with LOAD and STORE ? */
+
+    {
+	Tcl_Obj *incrPtr;
+#ifndef TCL_WIDE_INT_IS_LONG
+	Tcl_WideInt w;
+#endif
+	long increment;
+
+    case INST_INCR_SCALAR1:
+    case INST_INCR_ARRAY1:
+    case INST_INCR_ARRAY_STK:
+    case INST_INCR_SCALAR_STK:
+    case INST_INCR_STK:
+	opnd = TclGetUInt1AtPtr(pc+1);
+	incrPtr = POP_OBJECT();
+	switch (*pc) {
+	case INST_INCR_SCALAR1:
+	    pcAdjustment = 2;
+	    goto doIncrScalar;
+	case INST_INCR_ARRAY1:
+	    pcAdjustment = 2;
+	    goto doIncrArray;
+	default:
+	    pcAdjustment = 1;
+	    goto doIncrStk;
+	}
+
+    case INST_INCR_ARRAY_STK_IMM:
+    case INST_INCR_SCALAR_STK_IMM:
+    case INST_INCR_STK_IMM:
+	increment = TclGetInt1AtPtr(pc+1);
+	incrPtr = Tcl_NewIntObj(increment);
+	Tcl_IncrRefCount(incrPtr);
+	pcAdjustment = 2;
+
+    doIncrStk:
+	if ((*pc == INST_INCR_ARRAY_STK_IMM)
+		|| (*pc == INST_INCR_ARRAY_STK)) {
+	    part2Ptr = OBJ_AT_TOS;
+	    objPtr = OBJ_UNDER_TOS;
+	    TRACE(("\"%.30s(%.30s)\" (by %ld) => ",
+		    O2S(objPtr), O2S(part2Ptr), increment));
+	} else {
+	    part2Ptr = NULL;
+	    objPtr = OBJ_AT_TOS;
+	    TRACE(("\"%.30s\" (by %ld) => ", O2S(objPtr), increment));
+	}
+	part1Ptr = objPtr;
+	opnd = -1;
+	varPtr = TclObjLookupVarEx(interp, objPtr, part2Ptr,
+		TCL_LEAVE_ERR_MSG, "read", 1, 1, &arrayPtr);
+	if (!varPtr) {
+	    DECACHE_STACK_INFO();
+	    Tcl_AddErrorInfo(interp,
+		    "\n    (reading value of variable to increment)");
+	    CACHE_STACK_INFO();
+	    TRACE_ERROR(interp);
+	    Tcl_DecrRefCount(incrPtr);
+	    goto gotError;
+	}
+	cleanup = ((part2Ptr == NULL)? 1 : 2);
+	goto doIncrVar;
+
+    case INST_INCR_ARRAY1_IMM:
+	opnd = TclGetUInt1AtPtr(pc+1);
+	increment = TclGetInt1AtPtr(pc+2);
+	incrPtr = Tcl_NewIntObj(increment);
+	Tcl_IncrRefCount(incrPtr);
+	pcAdjustment = 3;
+
+    doIncrArray:
+	part1Ptr = NULL;
+	part2Ptr = OBJ_AT_TOS;
+	arrayPtr = LOCAL(opnd);
+	cleanup = 1;
+	while (TclIsVarLink(arrayPtr)) {
+	    arrayPtr = arrayPtr->value.linkPtr;
+	}
+	TRACE(("%u \"%.30s\" (by %ld) => ", opnd, O2S(part2Ptr), increment));
+	varPtr = TclLookupArrayElement(interp, part1Ptr, part2Ptr,
+		TCL_LEAVE_ERR_MSG, "read", 1, 1, arrayPtr, opnd);
+	if (!varPtr) {
+	    TRACE_ERROR(interp);
+	    Tcl_DecrRefCount(incrPtr);
+	    goto gotError;
+	}
+	goto doIncrVar;
+
+    case INST_INCR_SCALAR1_IMM:
+	opnd = TclGetUInt1AtPtr(pc+1);
+	increment = TclGetInt1AtPtr(pc+2);
+	pcAdjustment = 3;
+	cleanup = 0;
+	varPtr = LOCAL(opnd);
+	while (TclIsVarLink(varPtr)) {
+	    varPtr = varPtr->value.linkPtr;
+	}
+
+	if (TclIsVarDirectModifyable(varPtr)) {
+	    ClientData ptr;
+	    int type;
+
+	    objPtr = varPtr->value.objPtr;
+	    if (GetNumberFromObj(NULL, objPtr, &ptr, &type) == TCL_OK) {
+		if (type == TCL_NUMBER_LONG) {
+		    long augend = *((const long *)ptr);
+		    long sum = augend + increment;
+
+		    /*
+		     * Overflow when (augend and sum have different sign) and
+		     * (augend and increment have the same sign). This is
+		     * encapsulated in the Overflowing macro.
+		     */
+
+		    if (!Overflowing(augend, increment, sum)) {
+			TRACE(("%u %ld => ", opnd, increment));
+			if (Tcl_IsShared(objPtr)) {
+			    objPtr->refCount--;	/* We know it's shared. */
+			    TclNewLongObj(objResultPtr, sum);
+			    Tcl_IncrRefCount(objResultPtr);
+			    varPtr->value.objPtr = objResultPtr;
+			} else {
+			    objResultPtr = objPtr;
+			    TclSetLongObj(objPtr, sum);
+			}
+			goto doneIncr;
+		    }
+#ifndef TCL_WIDE_INT_IS_LONG
+		    w = (Tcl_WideInt)augend;
+
+		    TRACE(("%u %ld => ", opnd, increment));
+		    if (Tcl_IsShared(objPtr)) {
+			objPtr->refCount--;	/* We know it's shared. */
+			objResultPtr = Tcl_NewWideIntObj(w+increment);
+			Tcl_IncrRefCount(objResultPtr);
+			varPtr->value.objPtr = objResultPtr;
+		    } else {
+			objResultPtr = objPtr;
+
+			/*
+			 * We know the sum value is outside the long range;
+			 * use macro form that doesn't range test again.
+			 */
+
+			TclSetWideIntObj(objPtr, w+increment);
+		    }
+		    goto doneIncr;
+#endif
+		}	/* end if (type == TCL_NUMBER_LONG) */
+#ifndef TCL_WIDE_INT_IS_LONG
+		if (type == TCL_NUMBER_WIDE) {
+		    Tcl_WideInt sum;
+
+		    w = *((const Tcl_WideInt *) ptr);
+		    sum = w + increment;
+
+		    /*
+		     * Check for overflow.
+		     */
+
+		    if (!Overflowing(w, increment, sum)) {
+			TRACE(("%u %ld => ", opnd, increment));
+			if (Tcl_IsShared(objPtr)) {
+			    objPtr->refCount--;	/* We know it's shared. */
+			    objResultPtr = Tcl_NewWideIntObj(sum);
+			    Tcl_IncrRefCount(objResultPtr);
+			    varPtr->value.objPtr = objResultPtr;
+			} else {
+			    objResultPtr = objPtr;
+
+			    /*
+			     * We *do not* know the sum value is outside the
+			     * long range (wide + long can yield long); use
+			     * the function call that checks range.
+			     */
+
+			    Tcl_SetWideIntObj(objPtr, sum);
+			}
+			goto doneIncr;
+		    }
+		}
+#endif
+	    }
+	    if (Tcl_IsShared(objPtr)) {
+		objPtr->refCount--;	/* We know it's shared */
+		objResultPtr = Tcl_DuplicateObj(objPtr);
+		Tcl_IncrRefCount(objResultPtr);
+		varPtr->value.objPtr = objResultPtr;
+	    } else {
+		objResultPtr = objPtr;
+	    }
+	    TclNewLongObj(incrPtr, increment);
+	    if (TclIncrObj(interp, objResultPtr, incrPtr) != TCL_OK) {
+		Tcl_DecrRefCount(incrPtr);
+		TRACE_ERROR(interp);
+		goto gotError;
+	    }
+	    Tcl_DecrRefCount(incrPtr);
+	    goto doneIncr;
+	}
+
+	/*
+	 * All other cases, flow through to generic handling.
+	 */
+
+	TclNewLongObj(incrPtr, increment);
+	Tcl_IncrRefCount(incrPtr);
+
+    doIncrScalar:
+	varPtr = LOCAL(opnd);
+	while (TclIsVarLink(varPtr)) {
+	    varPtr = varPtr->value.linkPtr;
+	}
+	arrayPtr = NULL;
+	part1Ptr = part2Ptr = NULL;
+	cleanup = 0;
+	TRACE(("%u %s => ", opnd, Tcl_GetString(incrPtr)));
+
+    doIncrVar:
+	if (TclIsVarDirectModifyable2(varPtr, arrayPtr)) {
+	    objPtr = varPtr->value.objPtr;
+	    if (Tcl_IsShared(objPtr)) {
+		objPtr->refCount--;	/* We know it's shared */
+		objResultPtr = Tcl_DuplicateObj(objPtr);
+		Tcl_IncrRefCount(objResultPtr);
+		varPtr->value.objPtr = objResultPtr;
+	    } else {
+		objResultPtr = objPtr;
+	    }
+	    if (TclIncrObj(interp, objResultPtr, incrPtr) != TCL_OK) {
+		Tcl_DecrRefCount(incrPtr);
+		TRACE_ERROR(interp);
+		goto gotError;
+	    }
+	    Tcl_DecrRefCount(incrPtr);
+	} else {
+	    DECACHE_STACK_INFO();
+	    objResultPtr = TclPtrIncrObjVar(interp, varPtr, arrayPtr,
+		    part1Ptr, part2Ptr, incrPtr, TCL_LEAVE_ERR_MSG, opnd);
+	    CACHE_STACK_INFO();
+	    Tcl_DecrRefCount(incrPtr);
+	    if (objResultPtr == NULL) {
+		TRACE_ERROR(interp);
+		goto gotError;
+	    }
+	}
+    doneIncr:
+	TRACE_APPEND(("%.30s\n", O2S(objResultPtr)));
+#ifndef TCL_COMPILE_DEBUG
+	if (*(pc+pcAdjustment) == INST_POP) {
+	    NEXT_INST_V((pcAdjustment+1), cleanup, 0);
+	}
+#endif
+	NEXT_INST_V(pcAdjustment, cleanup, 1);
+    }
+
+    /*
+     *	   End of INST_INCR instructions.
+     * -----------------------------------------------------------------
+     *	   Start of INST_EXIST instructions.
+     */
+
+    case INST_EXIST_SCALAR:
+	cleanup = 0;
+	pcAdjustment = 5;
+	opnd = TclGetUInt4AtPtr(pc+1);
+	varPtr = LOCAL(opnd);
+	while (TclIsVarLink(varPtr)) {
+	    varPtr = varPtr->value.linkPtr;
+	}
+	TRACE(("%u => ", opnd));
+	if (ReadTraced(varPtr)) {
+	    DECACHE_STACK_INFO();
+	    TclObjCallVarTraces(iPtr, NULL, varPtr, NULL, NULL,
+		    TCL_TRACE_READS, 0, opnd);
+	    CACHE_STACK_INFO();
+	    if (TclIsVarUndefined(varPtr)) {
+		TclCleanupVar(varPtr, NULL);
+		varPtr = NULL;
+	    }
+	}
+	goto afterExistsPeephole;
+
+    case INST_EXIST_ARRAY:
+	cleanup = 1;
+	pcAdjustment = 5;
+	opnd = TclGetUInt4AtPtr(pc+1);
+	part2Ptr = OBJ_AT_TOS;
+	arrayPtr = LOCAL(opnd);
+	while (TclIsVarLink(arrayPtr)) {
+	    arrayPtr = arrayPtr->value.linkPtr;
+	}
+	TRACE(("%u \"%.30s\" => ", opnd, O2S(part2Ptr)));
+	if (TclIsVarArray(arrayPtr) && !ReadTraced(arrayPtr)) {
+	    varPtr = VarHashFindVar(arrayPtr->value.tablePtr, part2Ptr);
+	    if (!varPtr || !ReadTraced(varPtr)) {
+		goto afterExistsPeephole;
+	    }
+	}
+	varPtr = TclLookupArrayElement(interp, NULL, part2Ptr, 0, "access",
+		0, 1, arrayPtr, opnd);
+	if (varPtr) {
+	    if (ReadTraced(varPtr) || (arrayPtr && ReadTraced(arrayPtr))) {
+		DECACHE_STACK_INFO();
+		TclObjCallVarTraces(iPtr, arrayPtr, varPtr, NULL, part2Ptr,
+			TCL_TRACE_READS, 0, opnd);
+		CACHE_STACK_INFO();
+	    }
+	    if (TclIsVarUndefined(varPtr)) {
+		TclCleanupVar(varPtr, arrayPtr);
+		varPtr = NULL;
+	    }
+	}
+	goto afterExistsPeephole;
+
+    case INST_EXIST_ARRAY_STK:
+	cleanup = 2;
+	pcAdjustment = 1;
+	part2Ptr = OBJ_AT_TOS;		/* element name */
+	part1Ptr = OBJ_UNDER_TOS;	/* array name */
+	TRACE(("\"%.30s(%.30s)\" => ", O2S(part1Ptr), O2S(part2Ptr)));
+	goto doExistStk;
+
+    case INST_EXIST_STK:
+	cleanup = 1;
+	pcAdjustment = 1;
+	part2Ptr = NULL;
+	part1Ptr = OBJ_AT_TOS;		/* variable name */
+	TRACE(("\"%.30s\" => ", O2S(part1Ptr)));
+
+    doExistStk:
+	varPtr = TclObjLookupVarEx(interp, part1Ptr, part2Ptr, 0, "access",
+		/*createPart1*/0, /*createPart2*/1, &arrayPtr);
+	if (varPtr) {
+	    if (ReadTraced(varPtr) || (arrayPtr && ReadTraced(arrayPtr))) {
+		DECACHE_STACK_INFO();
+		TclObjCallVarTraces(iPtr, arrayPtr, varPtr, part1Ptr,part2Ptr,
+			TCL_TRACE_READS, 0, -1);
+		CACHE_STACK_INFO();
+	    }
+	    if (TclIsVarUndefined(varPtr)) {
+		TclCleanupVar(varPtr, arrayPtr);
+		varPtr = NULL;
+	    }
+	}
+
+	/*
+	 * Peep-hole optimisation: if you're about to jump, do jump from here.
+	 */
+
+    afterExistsPeephole: {
+	int found = (varPtr && !TclIsVarUndefined(varPtr));
+
+	TRACE_APPEND(("%d\n", found ? 1 : 0));
+	JUMP_PEEPHOLE_V(found, pcAdjustment, cleanup);
+    }
+
+    /*
+     *	   End of INST_EXIST instructions.
+     * -----------------------------------------------------------------
+     *	   Start of INST_UNSET instructions.
+     */
+
+    {
+	int flags;
+
+    case INST_UNSET_SCALAR:
+	flags = TclGetUInt1AtPtr(pc+1) ? TCL_LEAVE_ERR_MSG : 0;
+	opnd = TclGetUInt4AtPtr(pc+2);
+	varPtr = LOCAL(opnd);
+	while (TclIsVarLink(varPtr)) {
+	    varPtr = varPtr->value.linkPtr;
+	}
+	TRACE(("%s %u => ", (flags ? "normal" : "noerr"), opnd));
+	if (TclIsVarDirectUnsettable(varPtr) && !TclIsVarInHash(varPtr)) {
+	    /*
+	     * No errors, no traces, no searches: just make the variable cease
+	     * to exist.
+	     */
+
+	    if (!TclIsVarUndefined(varPtr)) {
+		TclDecrRefCount(varPtr->value.objPtr);
+	    } else if (flags & TCL_LEAVE_ERR_MSG) {
+		goto slowUnsetScalar;
+	    }
+	    varPtr->value.objPtr = NULL;
+	    TRACE_APPEND(("OK\n"));
+	    NEXT_INST_F(6, 0, 0);
+	}
+
+    slowUnsetScalar:
+	DECACHE_STACK_INFO();
+	if (TclPtrUnsetVar(interp, varPtr, NULL, NULL, NULL, flags,
+		opnd) != TCL_OK && flags) {
+	    goto errorInUnset;
+	}
+	CACHE_STACK_INFO();
+	NEXT_INST_F(6, 0, 0);
+
+    case INST_UNSET_ARRAY:
+	flags = TclGetUInt1AtPtr(pc+1) ? TCL_LEAVE_ERR_MSG : 0;
+	opnd = TclGetUInt4AtPtr(pc+2);
+	part2Ptr = OBJ_AT_TOS;
+	arrayPtr = LOCAL(opnd);
+	while (TclIsVarLink(arrayPtr)) {
+	    arrayPtr = arrayPtr->value.linkPtr;
+	}
+	TRACE(("%s %u \"%.30s\" => ",
+		(flags ? "normal" : "noerr"), opnd, O2S(part2Ptr)));
+	if (TclIsVarArray(arrayPtr) && !UnsetTraced(arrayPtr)) {
+	    varPtr = VarHashFindVar(arrayPtr->value.tablePtr, part2Ptr);
+	    if (varPtr && TclIsVarDirectUnsettable(varPtr)) {
+		/*
+		 * No nasty traces and element exists, so we can proceed to
+		 * unset it. Might still not exist though...
+		 */
+
+		if (!TclIsVarUndefined(varPtr)) {
+		    TclDecrRefCount(varPtr->value.objPtr);
+		    TclSetVarUndefined(varPtr);
+		    TclClearVarNamespaceVar(varPtr);
+		    TclCleanupVar(varPtr, arrayPtr);
+		} else if (flags & TCL_LEAVE_ERR_MSG) {
+		    goto slowUnsetArray;
+		}
+		TRACE_APPEND(("OK\n"));
+		NEXT_INST_F(6, 1, 0);
+	    } else if (!varPtr && !(flags & TCL_LEAVE_ERR_MSG)) {
+		/*
+		 * Don't need to do anything here.
+		 */
+
+		TRACE_APPEND(("OK\n"));
+		NEXT_INST_F(6, 1, 0);
+	    }
+	}
+    slowUnsetArray:
+	DECACHE_STACK_INFO();
+	varPtr = TclLookupArrayElement(interp, NULL, part2Ptr, flags, "unset",
+		0, 0, arrayPtr, opnd);
+	if (!varPtr) {
+	    if (flags & TCL_LEAVE_ERR_MSG) {
+		goto errorInUnset;
+	    }
+	} else if (TclPtrUnsetVar(interp, varPtr, arrayPtr, NULL, part2Ptr,
+		flags, opnd) != TCL_OK && (flags & TCL_LEAVE_ERR_MSG)) {
+	    goto errorInUnset;
+	}
+	CACHE_STACK_INFO();
+	NEXT_INST_F(6, 1, 0);
+
+    case INST_UNSET_ARRAY_STK:
+	flags = TclGetUInt1AtPtr(pc+1) ? TCL_LEAVE_ERR_MSG : 0;
+	cleanup = 2;
+	part2Ptr = OBJ_AT_TOS;		/* element name */
+	part1Ptr = OBJ_UNDER_TOS;	/* array name */
+	TRACE(("%s \"%.30s(%.30s)\" => ", (flags ? "normal" : "noerr"),
+		O2S(part1Ptr), O2S(part2Ptr)));
+	goto doUnsetStk;
+
+    case INST_UNSET_STK:
+	flags = TclGetUInt1AtPtr(pc+1) ? TCL_LEAVE_ERR_MSG : 0;
+	cleanup = 1;
+	part2Ptr = NULL;
+	part1Ptr = OBJ_AT_TOS;		/* variable name */
+	TRACE(("%s \"%.30s\" => ", (flags ? "normal" : "noerr"),
+		O2S(part1Ptr)));
+
+    doUnsetStk:
+	DECACHE_STACK_INFO();
+	if (TclObjUnsetVar2(interp, part1Ptr, part2Ptr, flags) != TCL_OK
+		&& (flags & TCL_LEAVE_ERR_MSG)) {
+	    goto errorInUnset;
+	}
+	CACHE_STACK_INFO();
+	TRACE_APPEND(("OK\n"));
+	NEXT_INST_V(2, cleanup, 0);
+
+    errorInUnset:
+	CACHE_STACK_INFO();
+	TRACE_ERROR(interp);
+	goto gotError;
+
+	/*
+	 * This is really an unset operation these days. Do not issue.
+	 */
+
+    case INST_DICT_DONE:
+	opnd = TclGetUInt4AtPtr(pc+1);
+	TRACE(("%u => OK\n", opnd));
+	varPtr = LOCAL(opnd);
+	while (TclIsVarLink(varPtr)) {
+	    varPtr = varPtr->value.linkPtr;
+	}
+	if (TclIsVarDirectUnsettable(varPtr) && !TclIsVarInHash(varPtr)) {
+	    if (!TclIsVarUndefined(varPtr)) {
+		TclDecrRefCount(varPtr->value.objPtr);
+	    }
+	    varPtr->value.objPtr = NULL;
+	} else {
+	    DECACHE_STACK_INFO();
+	    TclPtrUnsetVar(interp, varPtr, NULL, NULL, NULL, 0, opnd);
+	    CACHE_STACK_INFO();
+	}
+	NEXT_INST_F(5, 0, 0);
+    }
+
+    /*
+     *	   End of INST_UNSET instructions.
+     * -----------------------------------------------------------------
+     *	   Start of INST_ARRAY instructions.
+     */
+
+    case INST_ARRAY_EXISTS_IMM:
+	opnd = TclGetUInt4AtPtr(pc+1);
+	pcAdjustment = 5;
+	cleanup = 0;
+	part1Ptr = NULL;
+	arrayPtr = NULL;
+	TRACE(("%u => ", opnd));
+	varPtr = LOCAL(opnd);
+	while (TclIsVarLink(varPtr)) {
+	    varPtr = varPtr->value.linkPtr;
+	}
+	goto doArrayExists;
+    case INST_ARRAY_EXISTS_STK:
+	opnd = -1;
+	pcAdjustment = 1;
+	cleanup = 1;
+	part1Ptr = OBJ_AT_TOS;
+	TRACE(("\"%.30s\" => ", O2S(part1Ptr)));
+	varPtr = TclObjLookupVarEx(interp, part1Ptr, NULL, 0, NULL,
+		/*createPart1*/0, /*createPart2*/0, &arrayPtr);
+    doArrayExists:
+	if (varPtr && (varPtr->flags & VAR_TRACED_ARRAY)
+		&& (TclIsVarArray(varPtr) || TclIsVarUndefined(varPtr))) {
+	    DECACHE_STACK_INFO();
+	    result = TclObjCallVarTraces(iPtr, arrayPtr, varPtr, part1Ptr,
+		    NULL, (TCL_LEAVE_ERR_MSG|TCL_NAMESPACE_ONLY|
+		    TCL_GLOBAL_ONLY|TCL_TRACE_ARRAY), 1, opnd);
+	    CACHE_STACK_INFO();
+	    if (result == TCL_ERROR) {
+		TRACE_ERROR(interp);
+		goto gotError;
+	    }
+	}
+	if (varPtr && TclIsVarArray(varPtr) && !TclIsVarUndefined(varPtr)) {
+	    objResultPtr = TCONST(1);
+	} else {
+	    objResultPtr = TCONST(0);
+	}
+	TRACE_APPEND(("%.30s\n", O2S(objResultPtr)));
+	NEXT_INST_V(pcAdjustment, cleanup, 1);
+
+    case INST_ARRAY_MAKE_IMM:
+	opnd = TclGetUInt4AtPtr(pc+1);
+	pcAdjustment = 5;
+	cleanup = 0;
+	part1Ptr = NULL;
+	arrayPtr = NULL;
+	TRACE(("%u => ", opnd));
+	varPtr = LOCAL(opnd);
+	while (TclIsVarLink(varPtr)) {
+	    varPtr = varPtr->value.linkPtr;
+	}
+	goto doArrayMake;
+    case INST_ARRAY_MAKE_STK:
+	opnd = -1;
+	pcAdjustment = 1;
+	cleanup = 1;
+	part1Ptr = OBJ_AT_TOS;
+	TRACE(("\"%.30s\" => ", O2S(part1Ptr)));
+	varPtr = TclObjLookupVarEx(interp, part1Ptr, NULL, TCL_LEAVE_ERR_MSG,
+		"set", /*createPart1*/1, /*createPart2*/0, &arrayPtr);
+	if (varPtr == NULL) {
+	    TRACE_ERROR(interp);
+	    goto gotError;
+	}
+    doArrayMake:
+	if (varPtr && !TclIsVarArray(varPtr)) {
+	    if (TclIsVarArrayElement(varPtr) || !TclIsVarUndefined(varPtr)) {
+		/*
+		 * Either an array element, or a scalar: lose!
+		 */
+
+		TclObjVarErrMsg(interp, part1Ptr, NULL, "array set",
+			"variable isn't array", opnd);
+		DECACHE_STACK_INFO();
+		Tcl_SetErrorCode(interp, "TCL", "WRITE", "ARRAY", NULL);
+		CACHE_STACK_INFO();
+		TRACE_ERROR(interp);
+		goto gotError;
+	    }
+	    TclSetVarArray(varPtr);
+	    varPtr->value.tablePtr = ckalloc(sizeof(TclVarHashTable));
+	    TclInitVarHashTable(varPtr->value.tablePtr,
+		    TclGetVarNsPtr(varPtr));
+#ifdef TCL_COMPILE_DEBUG
+	    TRACE_APPEND(("done\n"));
+	} else {
+	    TRACE_APPEND(("nothing to do\n"));
+#endif
+	}
+	NEXT_INST_V(pcAdjustment, cleanup, 0);
+
+    /*
+     *	   End of INST_ARRAY instructions.
+     * -----------------------------------------------------------------
+     *	   Start of variable linking instructions.
+     */
+
+    {
+	Var *otherPtr;
+	CallFrame *framePtr, *savedFramePtr;
+	Tcl_Namespace *nsPtr;
+	Namespace *savedNsPtr;
+
+    case INST_UPVAR:
+	TRACE(("%d %.30s %.30s => ", TclGetInt4AtPtr(pc+1),
+		O2S(OBJ_UNDER_TOS), O2S(OBJ_AT_TOS)));
+
+	if (TclObjGetFrame(interp, OBJ_UNDER_TOS, &framePtr) == -1) {
+	    TRACE_ERROR(interp);
+	    goto gotError;
+	}
+
+	/*
+	 * Locate the other variable.
+	 */
+
+	savedFramePtr = iPtr->varFramePtr;
+	iPtr->varFramePtr = framePtr;
+	otherPtr = TclObjLookupVarEx(interp, OBJ_AT_TOS, NULL,
+		TCL_LEAVE_ERR_MSG, "access", /*createPart1*/ 1,
+		/*createPart2*/ 1, &varPtr);
+	iPtr->varFramePtr = savedFramePtr;
+	if (!otherPtr) {
+	    TRACE_ERROR(interp);
+	    goto gotError;
+	}
+	goto doLinkVars;
+
+    case INST_NSUPVAR:
+	TRACE(("%d %.30s %.30s => ", TclGetInt4AtPtr(pc+1),
+		O2S(OBJ_UNDER_TOS), O2S(OBJ_AT_TOS)));
+	if (TclGetNamespaceFromObj(interp, OBJ_UNDER_TOS, &nsPtr) != TCL_OK) {
+	    TRACE_ERROR(interp);
+	    goto gotError;
+	}
+
+	/*
+	 * Locate the other variable.
+	 */
+
+	savedNsPtr = iPtr->varFramePtr->nsPtr;
+	iPtr->varFramePtr->nsPtr = (Namespace *) nsPtr;
+	otherPtr = TclObjLookupVarEx(interp, OBJ_AT_TOS, NULL,
+		(TCL_NAMESPACE_ONLY|TCL_LEAVE_ERR_MSG|TCL_AVOID_RESOLVERS),
+		"access", /*createPart1*/ 1, /*createPart2*/ 1, &varPtr);
+	iPtr->varFramePtr->nsPtr = savedNsPtr;
+	if (!otherPtr) {
+	    TRACE_ERROR(interp);
+	    goto gotError;
+	}
+	goto doLinkVars;
+
+    case INST_VARIABLE:
+	TRACE(("%d, %.30s => ", TclGetInt4AtPtr(pc+1), O2S(OBJ_AT_TOS)));
+	otherPtr = TclObjLookupVarEx(interp, OBJ_AT_TOS, NULL,
+		(TCL_NAMESPACE_ONLY | TCL_LEAVE_ERR_MSG), "access",
+		/*createPart1*/ 1, /*createPart2*/ 1, &varPtr);
+	if (!otherPtr) {
+	    TRACE_ERROR(interp);
+	    goto gotError;
+	}
+
+	/*
+	 * Do the [variable] magic.
+	 */
+
+	TclSetVarNamespaceVar(otherPtr);
+
+    doLinkVars:
+
+	/*
+	 * If we are here, the local variable has already been created: do the
+	 * little work of TclPtrMakeUpvar that remains to be done right here
+	 * if there are no errors; otherwise, let it handle the case.
+	 */
+
+	opnd = TclGetInt4AtPtr(pc+1);
+	varPtr = LOCAL(opnd);
+	if ((varPtr != otherPtr) && !TclIsVarTraced(varPtr)
+		&& (TclIsVarUndefined(varPtr) || TclIsVarLink(varPtr))) {
+	    if (!TclIsVarUndefined(varPtr)) {
+		/*
+		 * Then it is a defined link.
+		 */
+
+		Var *linkPtr = varPtr->value.linkPtr;
+
+		if (linkPtr == otherPtr) {
+		    TRACE_APPEND(("already linked\n"));
+		    NEXT_INST_F(5, 1, 0);
+		}
+		if (TclIsVarInHash(linkPtr)) {
+		    VarHashRefCount(linkPtr)--;
+		    if (TclIsVarUndefined(linkPtr)) {
+			TclCleanupVar(linkPtr, NULL);
+		    }
+		}
+	    }
+	    TclSetVarLink(varPtr);
+	    varPtr->value.linkPtr = otherPtr;
+	    if (TclIsVarInHash(otherPtr)) {
+		VarHashRefCount(otherPtr)++;
+	    }
+	} else if (TclPtrObjMakeUpvar(interp, otherPtr, NULL, 0,
+		opnd) != TCL_OK) {
+	    TRACE_ERROR(interp);
+	    goto gotError;
+	}
+
+	/*
+	 * Do not pop the namespace or frame index, it may be needed for other
+	 * variables - and [variable] did not push it at all.
+	 */
+
+	TRACE_APPEND(("link made\n"));
+	NEXT_INST_F(5, 1, 0);
+    }
+
+    /*
+     *	   End of variable linking instructions.
+     * -----------------------------------------------------------------
+     */
+
+    case INST_JUMP1:
+	opnd = TclGetInt1AtPtr(pc+1);
+	TRACE(("%d => new pc %u\n", opnd,
+		(unsigned)(pc + opnd - codePtr->codeStart)));
+	NEXT_INST_F(opnd, 0, 0);
+
+    case INST_JUMP4:
+	opnd = TclGetInt4AtPtr(pc+1);
+	TRACE(("%d => new pc %u\n", opnd,
+		(unsigned)(pc + opnd - codePtr->codeStart)));
+	NEXT_INST_F(opnd, 0, 0);
+
+    {
+	int jmpOffset[2], b;
+
+	/* TODO: consider rewrite so we don't compute the offset we're not
+	 * going to take. */
+    case INST_JUMP_FALSE4:
+	jmpOffset[0] = TclGetInt4AtPtr(pc+1);	/* FALSE offset */
+	jmpOffset[1] = 5;			/* TRUE offset */
+	goto doCondJump;
+
+    case INST_JUMP_TRUE4:
+	jmpOffset[0] = 5;
+	jmpOffset[1] = TclGetInt4AtPtr(pc+1);
+	goto doCondJump;
+
+    case INST_JUMP_FALSE1:
+	jmpOffset[0] = TclGetInt1AtPtr(pc+1);
+	jmpOffset[1] = 2;
+	goto doCondJump;
+
+    case INST_JUMP_TRUE1:
+	jmpOffset[0] = 2;
+	jmpOffset[1] = TclGetInt1AtPtr(pc+1);
+
+    doCondJump:
+	valuePtr = OBJ_AT_TOS;
+	TRACE(("%d => ", jmpOffset[
+		(*pc==INST_JUMP_FALSE1 || *pc==INST_JUMP_FALSE4) ? 0 : 1]));
+
+	/* TODO - check claim that taking address of b harms performance */
+	/* TODO - consider optimization search for constants */
+	if (TclGetBooleanFromObj(interp, valuePtr, &b) != TCL_OK) {
+	    TRACE_ERROR(interp);
+	    goto gotError;
+	}
+
+#ifdef TCL_COMPILE_DEBUG
+	if (b) {
+	    if ((*pc == INST_JUMP_TRUE1) || (*pc == INST_JUMP_TRUE4)) {
+		TRACE_APPEND(("%.20s true, new pc %u\n", O2S(valuePtr),
+			(unsigned)(pc + jmpOffset[1] - codePtr->codeStart)));
+	    } else {
+		TRACE_APPEND(("%.20s true\n", O2S(valuePtr)));
+	    }
+	} else {
+	    if ((*pc == INST_JUMP_TRUE1) || (*pc == INST_JUMP_TRUE4)) {
+		TRACE_APPEND(("%.20s false\n", O2S(valuePtr)));
+	    } else {
+		TRACE_APPEND(("%.20s false, new pc %u\n", O2S(valuePtr),
+			(unsigned)(pc + jmpOffset[0] - codePtr->codeStart)));
+	    }
+	}
+#endif
+	NEXT_INST_F(jmpOffset[b], 1, 0);
+    }
+
+    case INST_JUMP_TABLE: {
+	Tcl_HashEntry *hPtr;
+	JumptableInfo *jtPtr;
+
+	/*
+	 * Jump to location looked up in a hashtable; fall through to next
+	 * instr if lookup fails.
+	 */
+
+	opnd = TclGetInt4AtPtr(pc+1);
+	jtPtr = (JumptableInfo *) codePtr->auxDataArrayPtr[opnd].clientData;
+	TRACE(("%d \"%.20s\" => ", opnd, O2S(OBJ_AT_TOS)));
+	hPtr = Tcl_FindHashEntry(&jtPtr->hashTable, TclGetString(OBJ_AT_TOS));
+	if (hPtr != NULL) {
+	    int jumpOffset = PTR2INT(Tcl_GetHashValue(hPtr));
+
+	    TRACE_APPEND(("found in table, new pc %u\n",
+		    (unsigned)(pc - codePtr->codeStart + jumpOffset)));
+	    NEXT_INST_F(jumpOffset, 1, 0);
+	} else {
+	    TRACE_APPEND(("not found in table\n"));
+	    NEXT_INST_F(5, 1, 0);
+	}
+    }
+
+    /*
+     * These two instructions are now redundant: the complete logic of the LOR
+     * and LAND is now handled by the expression compiler.
+     */
+
+    case INST_LOR:
+    case INST_LAND: {
+	/*
+	 * Operands must be boolean or numeric. No int->double conversions are
+	 * performed.
+	 */
+
+	int i1, i2, iResult;
+
+	value2Ptr = OBJ_AT_TOS;
+	valuePtr = OBJ_UNDER_TOS;
+	if (TclGetBooleanFromObj(NULL, valuePtr, &i1) != TCL_OK) {
+	    TRACE(("\"%.20s\" => ILLEGAL TYPE %s \n", O2S(valuePtr),
+		    (valuePtr->typePtr? valuePtr->typePtr->name : "null")));
+	    DECACHE_STACK_INFO();
+	    IllegalExprOperandType(interp, pc, valuePtr);
+	    CACHE_STACK_INFO();
+	    goto gotError;
+	}
+
+	if (TclGetBooleanFromObj(NULL, value2Ptr, &i2) != TCL_OK) {
+	    TRACE(("\"%.20s\" => ILLEGAL TYPE %s \n", O2S(value2Ptr),
+		    (value2Ptr->typePtr? value2Ptr->typePtr->name : "null")));
+	    DECACHE_STACK_INFO();
+	    IllegalExprOperandType(interp, pc, value2Ptr);
+	    CACHE_STACK_INFO();
+	    goto gotError;
+	}
+
+	if (*pc == INST_LOR) {
+	    iResult = (i1 || i2);
+	} else {
+	    iResult = (i1 && i2);
+	}
+	objResultPtr = TCONST(iResult);
+	TRACE(("%.20s %.20s => %d\n", O2S(valuePtr),O2S(value2Ptr),iResult));
+	NEXT_INST_F(1, 2, 1);
+    }
+
+    /*
+     * -----------------------------------------------------------------
+     *	   Start of general introspector instructions.
+     */
+
+    case INST_NS_CURRENT: {
+	Namespace *currNsPtr = (Namespace *) TclGetCurrentNamespace(interp);
+
+	if (currNsPtr == (Namespace *) TclGetGlobalNamespace(interp)) {
+	    TclNewLiteralStringObj(objResultPtr, "::");
+	} else {
+	    TclNewStringObj(objResultPtr, currNsPtr->fullName,
+		    strlen(currNsPtr->fullName));
+	}
+	TRACE_WITH_OBJ(("=> "), objResultPtr);
+	NEXT_INST_F(1, 0, 1);
+    }
+    case INST_COROUTINE_NAME: {
+	CoroutineData *corPtr = iPtr->execEnvPtr->corPtr;
+
+	TclNewObj(objResultPtr);
+	if (corPtr && !(corPtr->cmdPtr->flags & CMD_IS_DELETED)) {
+	    Tcl_GetCommandFullName(interp, (Tcl_Command) corPtr->cmdPtr,
+		    objResultPtr);
+	}
+	TRACE_WITH_OBJ(("=> "), objResultPtr);
+	NEXT_INST_F(1, 0, 1);
+    }
+    case INST_INFO_LEVEL_NUM:
+	TclNewIntObj(objResultPtr, iPtr->varFramePtr->level);
+	TRACE_WITH_OBJ(("=> "), objResultPtr);
+	NEXT_INST_F(1, 0, 1);
+    case INST_INFO_LEVEL_ARGS: {
+	int level;
+	register CallFrame *framePtr = iPtr->varFramePtr;
+	register CallFrame *rootFramePtr = iPtr->rootFramePtr;
+
+	TRACE(("\"%.30s\" => ", O2S(OBJ_AT_TOS)));
+	if (TclGetIntFromObj(interp, OBJ_AT_TOS, &level) != TCL_OK) {
+	    TRACE_ERROR(interp);
+	    goto gotError;
+	}
+	if (level <= 0) {
+	    level += framePtr->level;
+	}
+	for (; (framePtr->level!=level) && (framePtr!=rootFramePtr) ;
+		framePtr = framePtr->callerVarPtr) {
+	    /* Empty loop body */
+	}
+	if (framePtr == rootFramePtr) {
+	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		    "bad level \"%s\"", TclGetString(OBJ_AT_TOS)));
+	    TRACE_ERROR(interp);
+	    DECACHE_STACK_INFO();
+	    Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "STACK_LEVEL",
+		    TclGetString(OBJ_AT_TOS), NULL);
+	    CACHE_STACK_INFO();
+	    goto gotError;
+	}
+	objResultPtr = Tcl_NewListObj(framePtr->objc, framePtr->objv);
+	TRACE_APPEND(("%.30s\n", O2S(objResultPtr)));
+	NEXT_INST_F(1, 1, 1);
+    }
+    {
+	Tcl_Command cmd, origCmd;
+
+    case INST_RESOLVE_COMMAND:
+	cmd = Tcl_GetCommandFromObj(interp, OBJ_AT_TOS);
+	TclNewObj(objResultPtr);
+	if (cmd != NULL) {
+	    Tcl_GetCommandFullName(interp, cmd, objResultPtr);
+	}
+	TRACE_WITH_OBJ(("\"%.20s\" => ", O2S(OBJ_AT_TOS)), objResultPtr);
+	NEXT_INST_F(1, 1, 1);
+
+    case INST_ORIGIN_COMMAND:
+	TRACE(("\"%.30s\" => ", O2S(OBJ_AT_TOS)));
+	cmd = Tcl_GetCommandFromObj(interp, OBJ_AT_TOS);
+	if (cmd == NULL) {
+	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		    "invalid command name \"%s\"", TclGetString(OBJ_AT_TOS)));
+	    DECACHE_STACK_INFO();
+	    Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "COMMAND",
+		    TclGetString(OBJ_AT_TOS), NULL);
+	    CACHE_STACK_INFO();
+	    TRACE_APPEND(("ERROR: not command\n"));
+	    goto gotError;
+	}
+	origCmd = TclGetOriginalCommand(cmd);
+	if (origCmd == NULL) {
+	    origCmd = cmd;
+	}
+	TclNewObj(objResultPtr);
+	Tcl_GetCommandFullName(interp, origCmd, objResultPtr);
+	TRACE_APPEND(("\"%.30s\"", O2S(OBJ_AT_TOS)));
+	NEXT_INST_F(1, 1, 1);
+    }
+
+    /*
+     * -----------------------------------------------------------------
+     *	   Start of TclOO support instructions.
+     */
+
+    {
+	Object *oPtr;
+	CallFrame *framePtr;
+	CallContext *contextPtr;
+	int skip, newDepth;
+
+    case INST_TCLOO_SELF:
+	framePtr = iPtr->varFramePtr;
+	if (framePtr == NULL ||
+		!(framePtr->isProcCallFrame & FRAME_IS_METHOD)) {
+	    TRACE(("=> ERROR: no TclOO call context\n"));
+	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		    "self may only be called from inside a method",
+		    -1));
+	    DECACHE_STACK_INFO();
+	    Tcl_SetErrorCode(interp, "TCL", "OO", "CONTEXT_REQUIRED", NULL);
+	    CACHE_STACK_INFO();
+	    goto gotError;
+	}
+	contextPtr = framePtr->clientData;
+
+	/*
+	 * Call out to get the name; it's expensive to compute but cached.
+	 */
+
+	objResultPtr = TclOOObjectName(interp, contextPtr->oPtr);
+	TRACE_WITH_OBJ(("=> "), objResultPtr);
+	NEXT_INST_F(1, 0, 1);
+
+    case INST_TCLOO_NEXT_CLASS:
+	opnd = TclGetUInt1AtPtr(pc+1);
+	framePtr = iPtr->varFramePtr;
+	valuePtr = OBJ_AT_DEPTH(opnd - 2);
+	objv = &OBJ_AT_DEPTH(opnd - 1);
+	skip = 2;
+	TRACE(("%d => ", opnd));
+	if (framePtr == NULL ||
+		!(framePtr->isProcCallFrame & FRAME_IS_METHOD)) {
+	    TRACE_APPEND(("ERROR: no TclOO call context\n"));
+	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		    "nextto may only be called from inside a method",
+		    -1));
+	    DECACHE_STACK_INFO();
+	    Tcl_SetErrorCode(interp, "TCL", "OO", "CONTEXT_REQUIRED", NULL);
+	    CACHE_STACK_INFO();
+	    goto gotError;
+	}
+	contextPtr = framePtr->clientData;
+
+	oPtr = (Object *) Tcl_GetObjectFromObj(interp, valuePtr);
+	if (oPtr == NULL) {
+	    TRACE_APPEND(("ERROR: \"%.30s\" not object\n", O2S(valuePtr)));
+	    goto gotError;
+	} else {
+	    Class *classPtr = oPtr->classPtr;
+	    struct MInvoke *miPtr;
+	    int i;
+	    const char *methodType;
+
+	    if (classPtr == NULL) {
+		TRACE_APPEND(("ERROR: \"%.30s\" not class\n", O2S(valuePtr)));
+		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+			"\"%s\" is not a class", TclGetString(valuePtr)));
+		DECACHE_STACK_INFO();
+		Tcl_SetErrorCode(interp, "TCL", "OO", "CLASS_REQUIRED", NULL);
+		CACHE_STACK_INFO();
+		goto gotError;
+	    }
+
+	    for (i=contextPtr->index+1 ; i<contextPtr->callPtr->numChain ; i++) {
+		miPtr = contextPtr->callPtr->chain + i;
+		if (!miPtr->isFilter &&
+			miPtr->mPtr->declaringClassPtr == classPtr) {
+		    newDepth = i;
+#ifdef TCL_COMPILE_DEBUG
+		    if (tclTraceExec >= 2) {
+			if (traceInstructions) {
+			    strncpy(cmdNameBuf, TclGetString(objv[0]), 20);
+			} else {
+			    fprintf(stdout, "%d: (%u) invoking ",
+				    iPtr->numLevels,
+				    (unsigned)(pc - codePtr->codeStart));
+			}
+			for (i = 0;  i < opnd;  i++) {
+			    TclPrintObject(stdout, objv[i], 15);
+			    fprintf(stdout, " ");
+			}
+			fprintf(stdout, "\n");
+			fflush(stdout);
+		    }
+#endif /*TCL_COMPILE_DEBUG*/
+		    goto doInvokeNext;
+		}
+	    }
+
+	    if (contextPtr->callPtr->flags & CONSTRUCTOR) {
+		methodType = "constructor";
+	    } else if (contextPtr->callPtr->flags & DESTRUCTOR) {
+		methodType = "destructor";
+	    } else {
+		methodType = "method";
+	    }
+
+	    TRACE_APPEND(("ERROR: \"%.30s\" not on reachable chain\n",
+		    O2S(valuePtr)));
+	    for (i=contextPtr->index ; i>=0 ; i--) {
+		miPtr = contextPtr->callPtr->chain + i;
+		if (miPtr->isFilter
+			|| miPtr->mPtr->declaringClassPtr != classPtr) {
+		    continue;
+		}
+		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+			"%s implementation by \"%s\" not reachable from here",
+			methodType, TclGetString(valuePtr)));
+		DECACHE_STACK_INFO();
+		Tcl_SetErrorCode(interp, "TCL", "OO", "CLASS_NOT_REACHABLE",
+			NULL);
+		CACHE_STACK_INFO();
+		goto gotError;
+	    }
+	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		    "%s has no non-filter implementation by \"%s\"",
+		    methodType, TclGetString(valuePtr)));
+	    DECACHE_STACK_INFO();
+	    Tcl_SetErrorCode(interp, "TCL", "OO", "CLASS_NOT_THERE", NULL);
+	    CACHE_STACK_INFO();
+	    goto gotError;
+	}
+
+    case INST_TCLOO_NEXT:
+	opnd = TclGetUInt1AtPtr(pc+1);
+	objv = &OBJ_AT_DEPTH(opnd - 1);
+	framePtr = iPtr->varFramePtr;
+	skip = 1;
+	TRACE(("%d => ", opnd));
+	if (framePtr == NULL ||
+		!(framePtr->isProcCallFrame & FRAME_IS_METHOD)) {
+	    TRACE_APPEND(("ERROR: no TclOO call context\n"));
+	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		    "next may only be called from inside a method",
+		    -1));
+	    DECACHE_STACK_INFO();
+	    Tcl_SetErrorCode(interp, "TCL", "OO", "CONTEXT_REQUIRED", NULL);
+	    CACHE_STACK_INFO();
+	    goto gotError;
+	}
+	contextPtr = framePtr->clientData;
+
+	newDepth = contextPtr->index + 1;
+	if (newDepth >= contextPtr->callPtr->numChain) {
+	    /*
+	     * We're at the end of the chain; generate an error message unless
+	     * the interpreter is being torn down, in which case we might be
+	     * getting here because of methods/destructors doing a [next] (or
+	     * equivalent) unexpectedly.
+	     */
+
+	    const char *methodType;
+
+	    if (contextPtr->callPtr->flags & CONSTRUCTOR) {
+		methodType = "constructor";
+	    } else if (contextPtr->callPtr->flags & DESTRUCTOR) {
+		methodType = "destructor";
+	    } else {
+		methodType = "method";
+	    }
+
+	    TRACE_APPEND(("ERROR: no TclOO next impl\n"));
+	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		    "no next %s implementation", methodType));
+	    DECACHE_STACK_INFO();
+	    Tcl_SetErrorCode(interp, "TCL", "OO", "NOTHING_NEXT", NULL);
+	    CACHE_STACK_INFO();
+	    goto gotError;
+#ifdef TCL_COMPILE_DEBUG
+	} else if (tclTraceExec >= 2) {
+	    int i;
+
+	    if (traceInstructions) {
+		strncpy(cmdNameBuf, TclGetString(objv[0]), 20);
+	    } else {
+		fprintf(stdout, "%d: (%u) invoking ",
+			iPtr->numLevels, (unsigned)(pc - codePtr->codeStart));
+	    }
+	    for (i = 0;  i < opnd;  i++) {
+		TclPrintObject(stdout, objv[i], 15);
+		fprintf(stdout, " ");
+	    }
+	    fprintf(stdout, "\n");
+	    fflush(stdout);
+#endif /*TCL_COMPILE_DEBUG*/
+	}
+
+    doInvokeNext:
+	bcFramePtr->data.tebc.pc = (char *) pc;
+	iPtr->cmdFramePtr = bcFramePtr;
+
+	if (iPtr->flags & INTERP_DEBUG_FRAME) {
+	    ArgumentBCEnter(interp, codePtr, TD, pc, opnd, objv);
+	}
+
+	pcAdjustment = 2;
+	cleanup = opnd;
+	DECACHE_STACK_INFO();
+	iPtr->varFramePtr = framePtr->callerVarPtr;
+	pc += pcAdjustment;
+	TEBC_YIELD();
+
+	TclPushTailcallPoint(interp);
+	oPtr = contextPtr->oPtr;
+	if (oPtr->flags & FILTER_HANDLING) {
+	    TclNRAddCallback(interp, FinalizeOONextFilter,
+		    framePtr, contextPtr, INT2PTR(contextPtr->index),
+		    INT2PTR(contextPtr->skip));
+	} else {
+	    TclNRAddCallback(interp, FinalizeOONext,
+		    framePtr, contextPtr, INT2PTR(contextPtr->index),
+		    INT2PTR(contextPtr->skip));
+	}
+	contextPtr->skip = skip;
+	contextPtr->index = newDepth;
+	if (contextPtr->callPtr->chain[newDepth].isFilter
+		|| contextPtr->callPtr->flags & FILTER_HANDLING) {
+	    oPtr->flags |= FILTER_HANDLING;
+	} else {
+	    oPtr->flags &= ~FILTER_HANDLING;
+	}
+
+	{
+	    register Method *const mPtr =
+		    contextPtr->callPtr->chain[newDepth].mPtr;
+
+	    return mPtr->typePtr->callProc(mPtr->clientData, interp,
+		    (Tcl_ObjectContext) contextPtr, opnd, objv);
+	}
+
+    case INST_TCLOO_IS_OBJECT:
+	oPtr = (Object *) Tcl_GetObjectFromObj(interp, OBJ_AT_TOS);
+	objResultPtr = TCONST(oPtr != NULL ? 1 : 0);
+	TRACE_WITH_OBJ(("%.30s => ", O2S(OBJ_AT_TOS)), objResultPtr);
+	NEXT_INST_F(1, 1, 1);
+    case INST_TCLOO_CLASS:
+	oPtr = (Object *) Tcl_GetObjectFromObj(interp, OBJ_AT_TOS);
+	if (oPtr == NULL) {
+	    TRACE(("%.30s => ERROR: not object\n", O2S(OBJ_AT_TOS)));
+	    goto gotError;
+	}
+	objResultPtr = TclOOObjectName(interp, oPtr->selfCls->thisPtr);
+	TRACE_WITH_OBJ(("%.30s => ", O2S(OBJ_AT_TOS)), objResultPtr);
+	NEXT_INST_F(1, 1, 1);
+    case INST_TCLOO_NS:
+	oPtr = (Object *) Tcl_GetObjectFromObj(interp, OBJ_AT_TOS);
+	if (oPtr == NULL) {
+	    TRACE(("%.30s => ERROR: not object\n", O2S(OBJ_AT_TOS)));
+	    goto gotError;
+	}
+
+	/*
+	 * TclOO objects *never* have the global namespace as their NS.
+	 */
+
+	TclNewStringObj(objResultPtr, oPtr->namespacePtr->fullName,
+		strlen(oPtr->namespacePtr->fullName));
+	TRACE_WITH_OBJ(("%.30s => ", O2S(OBJ_AT_TOS)), objResultPtr);
+	NEXT_INST_F(1, 1, 1);
+    }
+
+    /*
+     *     End of TclOO support instructions.
+     * -----------------------------------------------------------------
+     *	   Start of INST_LIST and related instructions.
+     */
+
+    {
+	int index, numIndices, fromIdx, toIdx;
+	int nocase, match, length2, cflags, s1len, s2len;
+	const char *s1, *s2;
+
+    case INST_LIST:
+	/*
+	 * Pop the opnd (objc) top stack elements into a new list obj and then
+	 * decrement their ref counts.
+	 */
+
+	opnd = TclGetUInt4AtPtr(pc+1);
+	objResultPtr = Tcl_NewListObj(opnd, &OBJ_AT_DEPTH(opnd-1));
+	TRACE_WITH_OBJ(("%u => ", opnd), objResultPtr);
+	NEXT_INST_V(5, opnd, 1);
+
+    case INST_LIST_LENGTH:
+	TRACE(("\"%.30s\" => ", O2S(OBJ_AT_TOS)));
+	if (TclListObjLength(interp, OBJ_AT_TOS, &length) != TCL_OK) {
+	    TRACE_ERROR(interp);
+	    goto gotError;
+	}
+	TclNewIntObj(objResultPtr, length);
+	TRACE_APPEND(("%d\n", length));
+	NEXT_INST_F(1, 1, 1);
+
+    case INST_LIST_INDEX:	/* lindex with objc == 3 */
+	value2Ptr = OBJ_AT_TOS;
+	valuePtr = OBJ_UNDER_TOS;
+	TRACE(("\"%.30s\" \"%.30s\" => ", O2S(valuePtr), O2S(value2Ptr)));
+
+	/*
+	 * Extract the desired list element.
+	 */
+
+	if ((TclListObjGetElements(interp, valuePtr, &objc, &objv) == TCL_OK)
+		&& (value2Ptr->typePtr != &tclListType)
+		&& (TclGetIntForIndexM(NULL , value2Ptr, objc-1,
+			&index) == TCL_OK)) {
+	    TclDecrRefCount(value2Ptr);
+	    tosPtr--;
+	    pcAdjustment = 1;
+	    goto lindexFastPath;
+	}
+
+	objResultPtr = TclLindexList(interp, valuePtr, value2Ptr);
+	if (!objResultPtr) {
+	    TRACE_ERROR(interp);
+	    goto gotError;
+	}
+
+	/*
+	 * Stash the list element on the stack.
+	 */
+
+	TRACE_APPEND(("\"%.30s\"\n", O2S(objResultPtr)));
+	NEXT_INST_F(1, 2, -1);	/* Already has the correct refCount */
+
+    case INST_LIST_INDEX_IMM:	/* lindex with objc==3 and index in bytecode
+				 * stream */
+
+	/*
+	 * Pop the list and get the index.
+	 */
+
+	valuePtr = OBJ_AT_TOS;
+	opnd = TclGetInt4AtPtr(pc+1);
+	TRACE(("\"%.30s\" %d => ", O2S(valuePtr), opnd));
+
+	/*
+	 * Get the contents of the list, making sure that it really is a list
+	 * in the process.
+	 */
+
+	if (TclListObjGetElements(interp, valuePtr, &objc, &objv) != TCL_OK) {
+	    TRACE_ERROR(interp);
+	    goto gotError;
+	}
+
+	/*
+	 * Select the list item based on the index. Negative operand means
+	 * end-based indexing.
+	 */
+
+	if (opnd < -1) {
+	    index = opnd+1 + objc;
+	} else {
+	    index = opnd;
+	}
+	pcAdjustment = 5;
+
+    lindexFastPath:
+	if (index >= 0 && index < objc) {
+	    objResultPtr = objv[index];
+	} else {
+	    TclNewObj(objResultPtr);
+	}
+
+	TRACE_APPEND(("\"%.30s\"\n", O2S(objResultPtr)));
+	NEXT_INST_F(pcAdjustment, 1, 1);
+
+    case INST_LIST_INDEX_MULTI:	/* 'lindex' with multiple index args */
+	/*
+	 * Determine the count of index args.
+	 */
+
+	opnd = TclGetUInt4AtPtr(pc+1);
+	numIndices = opnd-1;
+
+	/*
+	 * Do the 'lindex' operation.
+	 */
+
+	TRACE(("%d => ", opnd));
+	objResultPtr = TclLindexFlat(interp, OBJ_AT_DEPTH(numIndices),
+		numIndices, &OBJ_AT_DEPTH(numIndices - 1));
+	if (!objResultPtr) {
+	    TRACE_ERROR(interp);
+	    goto gotError;
+	}
+
+	/*
+	 * Set result.
+	 */
+
+	TRACE_APPEND(("\"%.30s\"\n", O2S(objResultPtr)));
+	NEXT_INST_V(5, opnd, -1);
+
+    case INST_LSET_FLAT:
+	/*
+	 * Lset with 3, 5, or more args. Get the number of index args.
+	 */
+
+	opnd = TclGetUInt4AtPtr(pc + 1);
+	numIndices = opnd - 2;
+	TRACE(("%d => ", opnd));
+
+	/*
+	 * Get the old value of variable, and remove the stack ref. This is
+	 * safe because the variable still references the object; the ref
+	 * count will never go zero here - we can use the smaller macro
+	 * Tcl_DecrRefCount.
+	 */
+
+	valuePtr = POP_OBJECT();
+	Tcl_DecrRefCount(valuePtr); /* This one should be done here */
+
+	/*
+	 * Compute the new variable value.
+	 */
+
+	objResultPtr = TclLsetFlat(interp, valuePtr, numIndices,
+		&OBJ_AT_DEPTH(numIndices), OBJ_AT_TOS);
+	if (!objResultPtr) {
+	    TRACE_ERROR(interp);
+	    goto gotError;
+	}
+
+	/*
+	 * Set result.
+	 */
+
+	TRACE_APPEND(("\"%.30s\"\n", O2S(objResultPtr)));
+	NEXT_INST_V(5, numIndices+1, -1);
+
+    case INST_LSET_LIST:	/* 'lset' with 4 args */
+	/*
+	 * Get the old value of variable, and remove the stack ref. This is
+	 * safe because the variable still references the object; the ref
+	 * count will never go zero here - we can use the smaller macro
+	 * Tcl_DecrRefCount.
+	 */
+
+	objPtr = POP_OBJECT();
+	Tcl_DecrRefCount(objPtr);	/* This one should be done here. */
+
+	/*
+	 * Get the new element value, and the index list.
+	 */
+
+	valuePtr = OBJ_AT_TOS;
+	value2Ptr = OBJ_UNDER_TOS;
+	TRACE(("\"%.30s\" \"%.30s\" \"%.30s\" => ",
+		O2S(value2Ptr), O2S(valuePtr), O2S(objPtr)));
+
+	/*
+	 * Compute the new variable value.
+	 */
+
+	objResultPtr = TclLsetList(interp, objPtr, value2Ptr, valuePtr);
+	if (!objResultPtr) {
+	    TRACE_ERROR(interp);
+	    goto gotError;
+	}
+
+	/*
+	 * Set result.
+	 */
+
+	TRACE_APPEND(("\"%.30s\"\n", O2S(objResultPtr)));
+	NEXT_INST_F(1, 2, -1);
+
+    case INST_LIST_RANGE_IMM:	/* lrange with objc==4 and both indices in
+				 * bytecode stream */
+
+	/*
+	 * Pop the list and get the indices.
+	 */
+
+	valuePtr = OBJ_AT_TOS;
+	fromIdx = TclGetInt4AtPtr(pc+1);
+	toIdx = TclGetInt4AtPtr(pc+5);
+	TRACE(("\"%.30s\" %d %d => ", O2S(valuePtr), TclGetInt4AtPtr(pc+1),
+		TclGetInt4AtPtr(pc+5)));
+
+	/*
+	 * Get the contents of the list, making sure that it really is a list
+	 * in the process.
+	 */
+
+	if (TclListObjGetElements(interp, valuePtr, &objc, &objv) != TCL_OK) {
+	    TRACE_ERROR(interp);
+	    goto gotError;
+	}
+
+	/*
+	 * Skip a lot of work if we're about to throw the result away (common
+	 * with uses of [lassign]).
+	 */
+
+#ifndef TCL_COMPILE_DEBUG
+	if (*(pc+9) == INST_POP) {
+	    NEXT_INST_F(10, 1, 0);
+	}
+#endif
+
+	/*
+	 * Adjust the indices for end-based handling.
+	 */
+
+	if (fromIdx < -1) {
+	    fromIdx += 1+objc;
+	    if (fromIdx < -1) {
+		fromIdx = -1;
+	    }
+	} else if (fromIdx > objc) {
+	    fromIdx = objc;
+	}
+	if (toIdx < -1) {
+	    toIdx += 1 + objc;
+	    if (toIdx < -1) {
+		toIdx = -1;
+	    }
+	} else if (toIdx > objc) {
+	    toIdx = objc;
+	}
+
+	/*
+	 * Check if we are referring to a valid, non-empty list range, and if
+	 * so, build the list of elements in that range.
+	 */
+
+	if (fromIdx<=toIdx && fromIdx<objc && toIdx>=0) {
+	    if (fromIdx < 0) {
+		fromIdx = 0;
+	    }
+	    if (toIdx >= objc) {
+		toIdx = objc-1;
+	    }
+	    if (fromIdx == 0 && toIdx != objc-1 && !Tcl_IsShared(valuePtr)) {
+		/*
+		 * BEWARE! This is looking inside the implementation of the
+		 * list type.
+		 */
+
+		List *listPtr = valuePtr->internalRep.twoPtrValue.ptr1;
+
+		if (listPtr->refCount == 1) {
+		    for (index=toIdx+1; index<objc ; index++) {
+			TclDecrRefCount(objv[index]);
+		    }
+		    listPtr->elemCount = toIdx+1;
+		    listPtr->canonicalFlag = 1;
+		    TclInvalidateStringRep(valuePtr);
+		    TRACE_APPEND(("%.30s\n", O2S(valuePtr)));
+		    NEXT_INST_F(9, 0, 0);
+		}
+	    }
+	    objResultPtr = Tcl_NewListObj(toIdx-fromIdx+1, objv+fromIdx);
+	} else {
+	    TclNewObj(objResultPtr);
+	}
+
+	TRACE_APPEND(("\"%.30s\"", O2S(objResultPtr)));
+	NEXT_INST_F(9, 1, 1);
+
+    case INST_LIST_IN:
+    case INST_LIST_NOT_IN:	/* Basic list containment operators. */
+	value2Ptr = OBJ_AT_TOS;
+	valuePtr = OBJ_UNDER_TOS;
+
+	s1 = TclGetStringFromObj(valuePtr, &s1len);
+	TRACE(("\"%.30s\" \"%.30s\" => ", O2S(valuePtr), O2S(value2Ptr)));
+	if (TclListObjLength(interp, value2Ptr, &length) != TCL_OK) {
+	    TRACE_ERROR(interp);
+	    goto gotError;
+	}
+	match = 0;
+	if (length > 0) {
+	    int i = 0;
+	    Tcl_Obj *o;
+
+	    /*
+	     * An empty list doesn't match anything.
+	     */
+
+	    do {
+		Tcl_ListObjIndex(NULL, value2Ptr, i, &o);
+		if (o != NULL) {
+		    s2 = TclGetStringFromObj(o, &s2len);
+		} else {
+		    s2 = "";
+		    s2len = 0;
+		}
+		if (s1len == s2len) {
+		    match = (memcmp(s1, s2, s1len) == 0);
+		}
+		i++;
+	    } while (i < length && match == 0);
+	}
+
+	if (*pc == INST_LIST_NOT_IN) {
+	    match = !match;
+	}
+
+	TRACE_APPEND(("%d\n", match));
+
+	/*
+	 * Peep-hole optimisation: if you're about to jump, do jump from here.
+	 * We're saving the effort of pushing a boolean value only to pop it
+	 * for branching.
+	 */
+
+	JUMP_PEEPHOLE_F(match, 1, 2);
+
+    case INST_LIST_CONCAT:
+	value2Ptr = OBJ_AT_TOS;
+	valuePtr = OBJ_UNDER_TOS;
+	TRACE(("\"%.30s\" \"%.30s\" => ", O2S(valuePtr), O2S(value2Ptr)));
+	if (Tcl_IsShared(valuePtr)) {
+	    objResultPtr = Tcl_DuplicateObj(valuePtr);
+	    if (Tcl_ListObjAppendList(interp, objResultPtr,
+		    value2Ptr) != TCL_OK) {
+		TRACE_ERROR(interp);
+		TclDecrRefCount(objResultPtr);
+		goto gotError;
+	    }
+	    TRACE_APPEND(("\"%.30s\"\n", O2S(objResultPtr)));
+	    NEXT_INST_F(1, 2, 1);
+	} else {
+	    if (Tcl_ListObjAppendList(interp, valuePtr, value2Ptr) != TCL_OK){
+		TRACE_ERROR(interp);
+		goto gotError;
+	    }
+	    TRACE_APPEND(("\"%.30s\"\n", O2S(valuePtr)));
+	    NEXT_INST_F(1, 1, 0);
+	}
+
+    /*
+     *	   End of INST_LIST and related instructions.
+     * -----------------------------------------------------------------
+     *	   Start of string-related instructions.
+     */
+
+    case INST_STR_EQ:
+    case INST_STR_NEQ:		/* String (in)equality check */
+    case INST_STR_CMP:		/* String compare. */
+    stringCompare:
+	value2Ptr = OBJ_AT_TOS;
+	valuePtr = OBJ_UNDER_TOS;
+
+	if (valuePtr == value2Ptr) {
+	    match = 0;
+	} else {
+	    /*
+	     * We only need to check (in)equality when we have equal length
+	     * strings.  We can use memcmp in all (n)eq cases because we
+	     * don't need to worry about lexical LE/BE variance.
+	     */
+
+	    typedef int (*memCmpFn_t)(const void*, const void*, size_t);
+	    memCmpFn_t memCmpFn;
+	    int checkEq = ((*pc == INST_EQ) || (*pc == INST_NEQ)
+		    || (*pc == INST_STR_EQ) || (*pc == INST_STR_NEQ));
+
+	    if (TclIsPureByteArray(valuePtr)
+		    && TclIsPureByteArray(value2Ptr)) {
+		s1 = (char *) Tcl_GetByteArrayFromObj(valuePtr, &s1len);
+		s2 = (char *) Tcl_GetByteArrayFromObj(value2Ptr, &s2len);
+		memCmpFn = memcmp;
+	    } else if ((valuePtr->typePtr == &tclStringType)
+		    && (value2Ptr->typePtr == &tclStringType)) {
+		/*
+		 * Do a unicode-specific comparison if both of the args are of
+		 * String type. If the char length == byte length, we can do a
+		 * memcmp. In benchmark testing this proved the most efficient
+		 * check between the unicode and string comparison operations.
+		 */
+
+		s1len = Tcl_GetCharLength(valuePtr);
+		s2len = Tcl_GetCharLength(value2Ptr);
+		if ((s1len == valuePtr->length)
+			&& (valuePtr->bytes != NULL)
+			&& (s2len == value2Ptr->length)
+			&& (value2Ptr->bytes != NULL)) {
+		    s1 = valuePtr->bytes;
+		    s2 = value2Ptr->bytes;
+		    memCmpFn = memcmp;
+		} else {
+		    s1 = (char *) Tcl_GetUnicode(valuePtr);
+		    s2 = (char *) Tcl_GetUnicode(value2Ptr);
+		    if (
+#ifdef WORDS_BIGENDIAN
+			1
+#else
+			checkEq
+#endif
+			) {
+			memCmpFn = memcmp;
+			s1len *= sizeof(Tcl_UniChar);
+			s2len *= sizeof(Tcl_UniChar);
+		    } else {
+			memCmpFn = (memCmpFn_t) Tcl_UniCharNcmp;
+		    }
+		}
+	    } else {
+		/*
+		 * strcmp can't do a simple memcmp in order to handle the
+		 * special Tcl \xC0\x80 null encoding for utf-8.
+		 */
+
+		s1 = TclGetStringFromObj(valuePtr, &s1len);
+		s2 = TclGetStringFromObj(value2Ptr, &s2len);
+		if (checkEq) {
+		    memCmpFn = memcmp;
+		} else {
+		    memCmpFn = (memCmpFn_t) TclpUtfNcmp2;
+		}
+	    }
+
+	    if (checkEq && (s1len != s2len)) {
+		match = 1;
+	    } else {
+		/*
+		 * The comparison function should compare up to the minimum
+		 * byte length only.
+		 */
+		match = memCmpFn(s1, s2,
+			(size_t) ((s1len < s2len) ? s1len : s2len));
+		if (match == 0) {
+		    match = s1len - s2len;
+		}
+	    }
+	}
+
+	/*
+	 * Make sure only -1,0,1 is returned
+	 * TODO: consider peephole opt.
+	 */
+
+	if (*pc != INST_STR_CMP) {
+	    /*
+	     * Take care of the opcodes that goto'ed into here.
+	     */
+
+	    switch (*pc) {
+	    case INST_STR_EQ:
+	    case INST_EQ:
+		match = (match == 0);
+		break;
+	    case INST_STR_NEQ:
+	    case INST_NEQ:
+		match = (match != 0);
+		break;
+	    case INST_LT:
+		match = (match < 0);
+		break;
+	    case INST_GT:
+		match = (match > 0);
+		break;
+	    case INST_LE:
+		match = (match <= 0);
+		break;
+	    case INST_GE:
+		match = (match >= 0);
+		break;
+	    }
+	}
+
+	TRACE(("\"%.20s\" \"%.20s\" => %d\n", O2S(valuePtr), O2S(value2Ptr),
+		(match < 0 ? -1 : match > 0 ? 1 : 0)));
+	JUMP_PEEPHOLE_F(match, 1, 2);
+
+    case INST_STR_LEN:
+	valuePtr = OBJ_AT_TOS;
+	length = Tcl_GetCharLength(valuePtr);
+	TclNewIntObj(objResultPtr, length);
+	TRACE(("\"%.20s\" => %d\n", O2S(valuePtr), length));
+	NEXT_INST_F(1, 1, 1);
+
+    case INST_STR_UPPER:
+	valuePtr = OBJ_AT_TOS;
+	TRACE(("\"%.20s\" => ", O2S(valuePtr)));
+	if (Tcl_IsShared(valuePtr)) {
+	    s1 = TclGetStringFromObj(valuePtr, &length);
+	    TclNewStringObj(objResultPtr, s1, length);
+	    length = Tcl_UtfToUpper(TclGetString(objResultPtr));
+	    Tcl_SetObjLength(objResultPtr, length);
+	    TRACE_APPEND(("\"%.20s\"\n", O2S(objResultPtr)));
+	    NEXT_INST_F(1, 1, 1);
+	} else {
+	    length = Tcl_UtfToUpper(TclGetString(valuePtr));
+	    Tcl_SetObjLength(valuePtr, length);
+	    TclFreeIntRep(valuePtr);
+	    TRACE_APPEND(("\"%.20s\"\n", O2S(valuePtr)));
+	    NEXT_INST_F(1, 0, 0);
+	}
+    case INST_STR_LOWER:
+	valuePtr = OBJ_AT_TOS;
+	TRACE(("\"%.20s\" => ", O2S(valuePtr)));
+	if (Tcl_IsShared(valuePtr)) {
+	    s1 = TclGetStringFromObj(valuePtr, &length);
+	    TclNewStringObj(objResultPtr, s1, length);
+	    length = Tcl_UtfToLower(TclGetString(objResultPtr));
+	    Tcl_SetObjLength(objResultPtr, length);
+	    TRACE_APPEND(("\"%.20s\"\n", O2S(objResultPtr)));
+	    NEXT_INST_F(1, 1, 1);
+	} else {
+	    length = Tcl_UtfToLower(TclGetString(valuePtr));
+	    Tcl_SetObjLength(valuePtr, length);
+	    TclFreeIntRep(valuePtr);
+	    TRACE_APPEND(("\"%.20s\"\n", O2S(valuePtr)));
+	    NEXT_INST_F(1, 0, 0);
+	}
+    case INST_STR_TITLE:
+	valuePtr = OBJ_AT_TOS;
+	TRACE(("\"%.20s\" => ", O2S(valuePtr)));
+	if (Tcl_IsShared(valuePtr)) {
+	    s1 = TclGetStringFromObj(valuePtr, &length);
+	    TclNewStringObj(objResultPtr, s1, length);
+	    length = Tcl_UtfToTitle(TclGetString(objResultPtr));
+	    Tcl_SetObjLength(objResultPtr, length);
+	    TRACE_APPEND(("\"%.20s\"\n", O2S(objResultPtr)));
+	    NEXT_INST_F(1, 1, 1);
+	} else {
+	    length = Tcl_UtfToTitle(TclGetString(valuePtr));
+	    Tcl_SetObjLength(valuePtr, length);
+	    TclFreeIntRep(valuePtr);
+	    TRACE_APPEND(("\"%.20s\"\n", O2S(valuePtr)));
+	    NEXT_INST_F(1, 0, 0);
+	}
+
+    case INST_STR_INDEX:
+	value2Ptr = OBJ_AT_TOS;
+	valuePtr = OBJ_UNDER_TOS;
+	TRACE(("\"%.20s\" %.20s => ", O2S(valuePtr), O2S(value2Ptr)));
+
+	/*
+	 * Get char length to calulate what 'end' means.
+	 */
+
+	length = Tcl_GetCharLength(valuePtr);
+	if (TclGetIntForIndexM(interp, value2Ptr, length-1, &index)!=TCL_OK) {
+	    TRACE_ERROR(interp);
+	    goto gotError;
+	}
+
+	if ((index < 0) || (index >= length)) {
+	    TclNewObj(objResultPtr);
+	} else if (TclIsPureByteArray(valuePtr)) {
+	    objResultPtr = Tcl_NewByteArrayObj(
+		    Tcl_GetByteArrayFromObj(valuePtr, NULL)+index, 1);
+	} else if (valuePtr->bytes && length == valuePtr->length) {
+	    objResultPtr = Tcl_NewStringObj((const char *)
+		    valuePtr->bytes+index, 1);
+	} else {
+	    char buf[TCL_UTF_MAX];
+	    Tcl_UniChar ch = Tcl_GetUniChar(valuePtr, index);
+
+	    /*
+	     * This could be: Tcl_NewUnicodeObj((const Tcl_UniChar *)&ch, 1)
+	     * but creating the object as a string seems to be faster in
+	     * practical use.
+	     */
+
+	    length = Tcl_UniCharToUtf(ch, buf);
+	    objResultPtr = Tcl_NewStringObj(buf, length);
+	}
+
+	TRACE_APPEND(("\"%s\"\n", O2S(objResultPtr)));
+	NEXT_INST_F(1, 2, 1);
+
+    case INST_STR_RANGE:
+	TRACE(("\"%.20s\" %.20s %.20s =>",
+		O2S(OBJ_AT_DEPTH(2)), O2S(OBJ_UNDER_TOS), O2S(OBJ_AT_TOS)));
+	length = Tcl_GetCharLength(OBJ_AT_DEPTH(2)) - 1;
+	if (TclGetIntForIndexM(interp, OBJ_UNDER_TOS, length,
+		    &fromIdx) != TCL_OK
+	    || TclGetIntForIndexM(interp, OBJ_AT_TOS, length,
+		    &toIdx) != TCL_OK) {
+	    TRACE_ERROR(interp);
+	    goto gotError;
+	}
+
+	if (fromIdx < 0) {
+	    fromIdx = 0;
+	}
+	if (toIdx >= length) {
+	    toIdx = length;
+	}
+	if (toIdx >= fromIdx) {
+	    objResultPtr = Tcl_GetRange(OBJ_AT_DEPTH(2), fromIdx, toIdx);
+	} else {
+	    TclNewObj(objResultPtr);
+	}
+	TRACE_APPEND(("\"%.30s\"\n", O2S(objResultPtr)));
+	NEXT_INST_V(1, 3, 1);
+
+    case INST_STR_RANGE_IMM:
+	valuePtr = OBJ_AT_TOS;
+	fromIdx = TclGetInt4AtPtr(pc+1);
+	toIdx = TclGetInt4AtPtr(pc+5);
+	length = Tcl_GetCharLength(valuePtr);
+	TRACE(("\"%.20s\" %d %d => ", O2S(valuePtr), fromIdx, toIdx));
+
+	/*
+	 * Adjust indices for end-based indexing.
+	 */
+
+	if (fromIdx < -1) {
+	    fromIdx += 1 + length;
+	    if (fromIdx < 0) {
+		fromIdx = 0;
+	    }
+	} else if (fromIdx >= length) {
+	    fromIdx = length;
+	}
+	if (toIdx < -1) {
+	    toIdx += 1 + length;
+	} else if (toIdx >= length) {
+	    toIdx = length - 1;
+	}
+
+	/*
+	 * Check if we can do a sane substring.
+	 */
+
+	if (fromIdx <= toIdx) {
+	    objResultPtr = Tcl_GetRange(valuePtr, fromIdx, toIdx);
+	} else {
+	    TclNewObj(objResultPtr);
+	}
+	TRACE_APPEND(("%.30s\n", O2S(objResultPtr)));
+	NEXT_INST_F(9, 1, 1);
+
+    {
+	Tcl_UniChar *ustring1, *ustring2, *ustring3, *end, *p;
+	int length3;
+	Tcl_Obj *value3Ptr;
+
+    case INST_STR_REPLACE:
+	value3Ptr = POP_OBJECT();
+	valuePtr = OBJ_AT_DEPTH(2);
+	length = Tcl_GetCharLength(valuePtr) - 1;
+	TRACE(("\"%.20s\" %s %s \"%.20s\" => ", O2S(valuePtr),
+		O2S(OBJ_UNDER_TOS), O2S(OBJ_AT_TOS), O2S(value3Ptr)));
+	if (TclGetIntForIndexM(interp, OBJ_UNDER_TOS, length,
+		    &fromIdx) != TCL_OK
+	    || TclGetIntForIndexM(interp, OBJ_AT_TOS, length,
+		    &toIdx) != TCL_OK) {
+	    TclDecrRefCount(value3Ptr);
+	    TRACE_ERROR(interp);
+	    goto gotError;
+	}
+	TclDecrRefCount(OBJ_AT_TOS);
+	(void) POP_OBJECT();
+	TclDecrRefCount(OBJ_AT_TOS);
+	(void) POP_OBJECT();
+	if (fromIdx < 0) {
+	    fromIdx = 0;
+	}
+
+	if (fromIdx > toIdx || fromIdx > length) {
+	    TRACE_APPEND(("\"%.30s\"\n", O2S(valuePtr)));
+	    TclDecrRefCount(value3Ptr);
+	    NEXT_INST_F(1, 0, 0);
+	}
+
+	if (toIdx > length) {
+	    toIdx = length;
+	}
+
+	if (fromIdx == 0 && toIdx == length) {
+	    TclDecrRefCount(OBJ_AT_TOS);
+	    OBJ_AT_TOS = value3Ptr;
+	    TRACE_APPEND(("\"%.30s\"\n", O2S(value3Ptr)));
+	    NEXT_INST_F(1, 0, 0);
+	}
+
+	length3 = Tcl_GetCharLength(value3Ptr);
+
+	/*
+	 * Remove substring. In-place.
+	 */
+
+	if (length3 == 0 && !Tcl_IsShared(valuePtr) && toIdx == length) {
+	    TclDecrRefCount(value3Ptr);
+	    Tcl_SetObjLength(valuePtr, fromIdx);
+	    TRACE_APPEND(("\"%.30s\"\n", O2S(valuePtr)));
+	    NEXT_INST_F(1, 0, 0);
+	}
+
+	/*
+	 * See if we can splice in place. This happens when the number of
+	 * characters being replaced is the same as the number of characters
+	 * in the string to be inserted.
+	 */
+
+	if (length3 - 1 == toIdx - fromIdx) {
+	    unsigned char *bytes1, *bytes2;
+
+	    /*
+	     * Flush the info in the string internal rep that refers to the
+	     * about-to-be-invalidated UTF-8 rep. This indicates that a new
+	     * buffer needs to be allocated, and assumes that the value is
+	     * already of tclStringTypePtr type, which should be true provided
+	     * we call it after Tcl_GetUnicodeFromObj.
+	     */
+#define MarkStringInternalRepForFlush(objPtr) \
+	    (GET_STRING(objPtr)->allocated = 0)
+
+	    if (Tcl_IsShared(valuePtr)) {
+		objResultPtr = Tcl_DuplicateObj(valuePtr);
+		if (TclIsPureByteArray(objResultPtr)
+			&& TclIsPureByteArray(value3Ptr)) {
+		    bytes1 = Tcl_GetByteArrayFromObj(objResultPtr, NULL);
+		    bytes2 = Tcl_GetByteArrayFromObj(value3Ptr, NULL);
+		    memcpy(bytes1 + fromIdx, bytes2, length3);
+		} else {
+		    ustring1 = Tcl_GetUnicodeFromObj(objResultPtr, NULL);
+		    ustring2 = Tcl_GetUnicodeFromObj(value3Ptr, NULL);
+		    memcpy(ustring1 + fromIdx, ustring2,
+			    length3 * sizeof(Tcl_UniChar));
+		    MarkStringInternalRepForFlush(objResultPtr);
+		}
+		Tcl_InvalidateStringRep(objResultPtr);
+		TclDecrRefCount(value3Ptr);
+		TRACE_APPEND(("\"%.30s\"\n", O2S(objResultPtr)));
+		NEXT_INST_F(1, 1, 1);
+	    } else {
+		if (TclIsPureByteArray(valuePtr)
+			&& TclIsPureByteArray(value3Ptr)) {
+		    bytes1 = Tcl_GetByteArrayFromObj(valuePtr, NULL);
+		    bytes2 = Tcl_GetByteArrayFromObj(value3Ptr, NULL);
+		    memcpy(bytes1 + fromIdx, bytes2, length3);
+		} else {
+		    ustring1 = Tcl_GetUnicodeFromObj(valuePtr, NULL);
+		    ustring2 = Tcl_GetUnicodeFromObj(value3Ptr, NULL);
+		    memcpy(ustring1 + fromIdx, ustring2,
+			    length3 * sizeof(Tcl_UniChar));
+		    MarkStringInternalRepForFlush(valuePtr);
+		}
+		Tcl_InvalidateStringRep(valuePtr);
+		TclDecrRefCount(value3Ptr);
+		TRACE_APPEND(("\"%.30s\"\n", O2S(valuePtr)));
+		NEXT_INST_F(1, 0, 0);
+	    }
+	}
+
+	/*
+	 * Get the unicode representation; this is where we guarantee to lose
+	 * bytearrays.
+	 */
+
+	ustring1 = Tcl_GetUnicodeFromObj(valuePtr, &length);
+	length--;
+
+	/*
+	 * Remove substring using copying.
+	 */
+
+	if (length3 == 0) {
+	    if (fromIdx > 0) {
+		objResultPtr = Tcl_NewUnicodeObj(ustring1, fromIdx);
+		if (toIdx < length) {
+		    Tcl_AppendUnicodeToObj(objResultPtr, ustring1 + toIdx + 1,
+			    length - toIdx);
+		}
+	    } else {
+		objResultPtr = Tcl_NewUnicodeObj(ustring1 + toIdx + 1,
+			length - toIdx);
+	    }
+	    TclDecrRefCount(value3Ptr);
+	    TRACE_APPEND(("\"%.30s\"\n", O2S(objResultPtr)));
+	    NEXT_INST_F(1, 1, 1);
+	}
+
+	/*
+	 * Splice string pieces by full copying.
+	 */
+
+	if (fromIdx > 0) {
+	    objResultPtr = Tcl_NewUnicodeObj(ustring1, fromIdx);
+	    Tcl_AppendObjToObj(objResultPtr, value3Ptr);
+	    if (toIdx < length) {
+		Tcl_AppendUnicodeToObj(objResultPtr, ustring1 + toIdx + 1,
+			length - toIdx);
+	    }
+	} else if (Tcl_IsShared(value3Ptr)) {
+	    objResultPtr = Tcl_DuplicateObj(value3Ptr);
+	    if (toIdx < length) {
+		Tcl_AppendUnicodeToObj(objResultPtr, ustring1 + toIdx + 1,
+			length - toIdx);
+	    }
+	} else {
+	    /*
+	     * Be careful with splicing the stack in this case; we have a
+	     * refCount:1 object in value3Ptr and we want to append to it and
+	     * make it be the refCount:1 object at the top of the stack
+	     * afterwards. [Bug 82e7f67325]
+	     */
+
+	    if (toIdx < length) {
+		Tcl_AppendUnicodeToObj(value3Ptr, ustring1 + toIdx + 1,
+			length - toIdx);
+	    }
+	    TRACE_APPEND(("\"%.30s\"\n", O2S(value3Ptr)));
+	    TclDecrRefCount(valuePtr);
+	    OBJ_AT_TOS = value3Ptr;	/* Tricky! */
+	    NEXT_INST_F(1, 0, 0);
+	}
+	TclDecrRefCount(value3Ptr);
+	TRACE_APPEND(("\"%.30s\"\n", O2S(objResultPtr)));
+	NEXT_INST_F(1, 1, 1);
+
+    case INST_STR_MAP:
+	valuePtr = OBJ_AT_TOS;		/* "Main" string. */
+	value3Ptr = OBJ_UNDER_TOS;	/* "Target" string. */
+	value2Ptr = OBJ_AT_DEPTH(2);	/* "Source" string. */
+	if (value3Ptr == value2Ptr) {
+	    objResultPtr = valuePtr;
+	    goto doneStringMap;
+	} else if (valuePtr == value2Ptr) {
+	    objResultPtr = value3Ptr;
+	    goto doneStringMap;
+	}
+	ustring1 = Tcl_GetUnicodeFromObj(valuePtr, &length);
+	if (length == 0) {
+	    objResultPtr = valuePtr;
+	    goto doneStringMap;
+	}
+	ustring2 = Tcl_GetUnicodeFromObj(value2Ptr, &length2);
+	if (length2 > length || length2 == 0) {
+	    objResultPtr = valuePtr;
+	    goto doneStringMap;
+	} else if (length2 == length) {
+	    if (memcmp(ustring1, ustring2, sizeof(Tcl_UniChar) * length)) {
+		objResultPtr = valuePtr;
+	    } else {
+		objResultPtr = value3Ptr;
+	    }
+	    goto doneStringMap;
+	}
+	ustring3 = Tcl_GetUnicodeFromObj(value3Ptr, &length3);
+
+	objResultPtr = Tcl_NewUnicodeObj(ustring1, 0);
+	p = ustring1;
+	end = ustring1 + length;
+	for (; ustring1 < end; ustring1++) {
+	    if ((*ustring1 == *ustring2) && (length2==1 ||
+		    memcmp(ustring1, ustring2, sizeof(Tcl_UniChar) * length2)
+			    == 0)) {
+		if (p != ustring1) {
+		    Tcl_AppendUnicodeToObj(objResultPtr, p, ustring1-p);
+		    p = ustring1 + length2;
+		} else {
+		    p += length2;
+		}
+		ustring1 = p - 1;
+
+		Tcl_AppendUnicodeToObj(objResultPtr, ustring3, length3);
+	    }
+	}
+	if (p != ustring1) {
+	    /*
+	     * Put the rest of the unmapped chars onto result.
+	     */
+
+	    Tcl_AppendUnicodeToObj(objResultPtr, p, ustring1 - p);
+	}
+    doneStringMap:
+	TRACE_WITH_OBJ(("%.20s %.20s %.20s => ",
+		O2S(value2Ptr), O2S(value3Ptr), O2S(valuePtr)), objResultPtr);
+	NEXT_INST_V(1, 3, 1);
+
+    case INST_STR_FIND:
+	ustring1 = Tcl_GetUnicodeFromObj(OBJ_AT_TOS, &length);	/* Haystack */
+	ustring2 = Tcl_GetUnicodeFromObj(OBJ_UNDER_TOS, &length2);/* Needle */
+
+	match = -1;
+	if (length2 > 0 && length2 <= length) {
+	    end = ustring1 + length - length2 + 1;
+	    for (p=ustring1 ; p<end ; p++) {
+		if ((*p == *ustring2) &&
+			memcmp(ustring2,p,sizeof(Tcl_UniChar)*length2) == 0) {
+		    match = p - ustring1;
+		    break;
+		}
+	    }
+	}
+
+	TRACE(("%.20s %.20s => %d\n",
+		O2S(OBJ_UNDER_TOS), O2S(OBJ_AT_TOS), match));
+	TclNewIntObj(objResultPtr, match);
+	NEXT_INST_F(1, 2, 1);
+
+    case INST_STR_FIND_LAST:
+	ustring1 = Tcl_GetUnicodeFromObj(OBJ_AT_TOS, &length);	/* Haystack */
+	ustring2 = Tcl_GetUnicodeFromObj(OBJ_UNDER_TOS, &length2);/* Needle */
+
+	match = -1;
+	if (length2 > 0 && length2 <= length) {
+	    for (p=ustring1+length-length2 ; p>=ustring1 ; p--) {
+		if ((*p == *ustring2) &&
+			memcmp(ustring2,p,sizeof(Tcl_UniChar)*length2) == 0) {
+		    match = p - ustring1;
+		    break;
+		}
+	    }
+	}
+
+	TRACE(("%.20s %.20s => %d\n",
+		O2S(OBJ_UNDER_TOS), O2S(OBJ_AT_TOS), match));
+
+	TclNewIntObj(objResultPtr, match);
+	NEXT_INST_F(1, 2, 1);
+
+    case INST_STR_CLASS:
+	opnd = TclGetInt1AtPtr(pc+1);
+	valuePtr = OBJ_AT_TOS;
+	TRACE(("%s \"%.30s\" => ", tclStringClassTable[opnd].name,
+		O2S(valuePtr)));
+	ustring1 = Tcl_GetUnicodeFromObj(valuePtr, &length);
+	match = 1;
+	if (length > 0) {
+	    end = ustring1 + length;
+	    for (p=ustring1 ; p<end ; p++) {
+		if (!tclStringClassTable[opnd].comparator(*p)) {
+		    match = 0;
+		    break;
+		}
+	    }
+	}
+	TRACE_APPEND(("%d\n", match));
+	JUMP_PEEPHOLE_F(match, 2, 1);
+    }
+
+    case INST_STR_MATCH:
+	nocase = TclGetInt1AtPtr(pc+1);
+	valuePtr = OBJ_AT_TOS;		/* String */
+	value2Ptr = OBJ_UNDER_TOS;	/* Pattern */
+
+	/*
+	 * Check that at least one of the objects is Unicode before promoting
+	 * both.
+	 */
+
+	if ((valuePtr->typePtr == &tclStringType)
+		|| (value2Ptr->typePtr == &tclStringType)) {
+	    Tcl_UniChar *ustring1, *ustring2;
+
+	    ustring1 = Tcl_GetUnicodeFromObj(valuePtr, &length);
+	    ustring2 = Tcl_GetUnicodeFromObj(value2Ptr, &length2);
+	    match = TclUniCharMatch(ustring1, length, ustring2, length2,
+		    nocase);
+	} else if (TclIsPureByteArray(valuePtr) && !nocase) {
+	    unsigned char *bytes1, *bytes2;
+
+	    bytes1 = Tcl_GetByteArrayFromObj(valuePtr, &length);
+	    bytes2 = Tcl_GetByteArrayFromObj(value2Ptr, &length2);
+	    match = TclByteArrayMatch(bytes1, length, bytes2, length2, 0);
+	} else {
+	    match = Tcl_StringCaseMatch(TclGetString(valuePtr),
+		    TclGetString(value2Ptr), nocase);
+	}
+
+	/*
+	 * Reuse value2Ptr object already on stack if possible. Adjustment is
+	 * 2 due to the nocase byte
+	 */
+
+	TRACE(("%.20s %.20s => %d\n", O2S(valuePtr), O2S(value2Ptr), match));
+
+	/*
+	 * Peep-hole optimisation: if you're about to jump, do jump from here.
+	 */
+
+	JUMP_PEEPHOLE_F(match, 2, 2);
+
+    {
+	const char *string1, *string2;
+	int trim1, trim2;
+
+    case INST_STR_TRIM_LEFT:
+	valuePtr = OBJ_UNDER_TOS;	/* String */
+	value2Ptr = OBJ_AT_TOS;		/* TrimSet */
+	string2 = TclGetStringFromObj(value2Ptr, &length2);
+	string1 = TclGetStringFromObj(valuePtr, &length);
+	trim1 = TclTrimLeft(string1, length, string2, length2);
+	trim2 = 0;
+	goto createTrimmedString;
+    case INST_STR_TRIM_RIGHT:
+	valuePtr = OBJ_UNDER_TOS;	/* String */
+	value2Ptr = OBJ_AT_TOS;		/* TrimSet */
+	string2 = TclGetStringFromObj(value2Ptr, &length2);
+	string1 = TclGetStringFromObj(valuePtr, &length);
+	trim2 = TclTrimRight(string1, length, string2, length2);
+	trim1 = 0;
+	goto createTrimmedString;
+    case INST_STR_TRIM:
+	valuePtr = OBJ_UNDER_TOS;	/* String */
+	value2Ptr = OBJ_AT_TOS;		/* TrimSet */
+	string2 = TclGetStringFromObj(value2Ptr, &length2);
+	string1 = TclGetStringFromObj(valuePtr, &length);
+	trim1 = TclTrimLeft(string1, length, string2, length2);
+	if (trim1 < length) {
+	    trim2 = TclTrimRight(string1, length, string2, length2);
+	} else {
+	    trim2 = 0;
+	}
+    createTrimmedString:
+	/*
+	 * Careful here; trim set often contains non-ASCII characters so we
+	 * take care when printing. [Bug 971cb4f1db]
+	 */
+
+#ifdef TCL_COMPILE_DEBUG
+	if (traceInstructions) {
+	    TRACE(("\"%.30s\" ", O2S(valuePtr)));
+	    TclPrintObject(stdout, value2Ptr, 30);
+	    printf(" => ");
+	}
+#endif
+	if (trim1 == 0 && trim2 == 0) {
+#ifdef TCL_COMPILE_DEBUG
+	    if (traceInstructions) {
+		TclPrintObject(stdout, valuePtr, 30);
+		printf("\n");
+	    }
+#endif
+	    NEXT_INST_F(1, 1, 0);
+	} else {
+	    objResultPtr = Tcl_NewStringObj(string1+trim1, length-trim1-trim2);
+#ifdef TCL_COMPILE_DEBUG
+	    if (traceInstructions) {
+		TclPrintObject(stdout, objResultPtr, 30);
+		printf("\n");
+	    }
+#endif
+	    NEXT_INST_F(1, 2, 1);
+	}
+    }
+
+    case INST_REGEXP:
+	cflags = TclGetInt1AtPtr(pc+1); /* RE compile flages like NOCASE */
+	valuePtr = OBJ_AT_TOS;		/* String */
+	value2Ptr = OBJ_UNDER_TOS;	/* Pattern */
+	TRACE(("\"%.30s\" \"%.30s\" => ", O2S(valuePtr), O2S(value2Ptr)));
+
+	/*
+	 * Compile and match the regular expression.
+	 */
+
+	{
+	    Tcl_RegExp regExpr =
+		    Tcl_GetRegExpFromObj(interp, value2Ptr, cflags);
+
+	    if (regExpr == NULL) {
+		TRACE_ERROR(interp);
+		goto gotError;
+	    }
+	    match = Tcl_RegExpExecObj(interp, regExpr, valuePtr, 0, 0, 0);
+	    if (match < 0) {
+		TRACE_ERROR(interp);
+		goto gotError;
+	    }
+	}
+
+	TRACE_APPEND(("%d\n", match));
+
+	/*
+	 * Peep-hole optimisation: if you're about to jump, do jump from here.
+	 * Adjustment is 2 due to the nocase byte.
+	 */
+
+	JUMP_PEEPHOLE_F(match, 2, 2);
+    }
+
+    /*
+     *	   End of string-related instructions.
+     * -----------------------------------------------------------------
+     *	   Start of numeric operator instructions.
+     */
+
+    {
+	ClientData ptr1, ptr2;
+	int type1, type2;
+	long l1, l2, lResult;
+
+    case INST_NUM_TYPE:
+	if (GetNumberFromObj(NULL, OBJ_AT_TOS, &ptr1, &type1) != TCL_OK) {
+	    type1 = 0;
+	} else if (type1 == TCL_NUMBER_LONG) {
+	    /* value is between LONG_MIN and LONG_MAX */
+	    /* [string is integer] is -UINT_MAX to UINT_MAX range */
+	    int i;
+
+	    if (Tcl_GetIntFromObj(NULL, OBJ_AT_TOS, &i) != TCL_OK) {
+		type1 = TCL_NUMBER_WIDE;
+	    }
+#ifndef TCL_WIDE_INT_IS_LONG
+	} else if (type1 == TCL_NUMBER_WIDE) {
+	    /* value is between WIDE_MIN and WIDE_MAX */
+	    /* [string is wideinteger] is -UWIDE_MAX to UWIDE_MAX range */
+	    int i;
+	    if (Tcl_GetIntFromObj(NULL, OBJ_AT_TOS, &i) == TCL_OK) {
+		type1 = TCL_NUMBER_LONG;
+	    }
+#endif
+	} else if (type1 == TCL_NUMBER_BIG) {
+	    /* value is an integer outside the WIDE_MIN to WIDE_MAX range */
+	    /* [string is wideinteger] is -UWIDE_MAX to UWIDE_MAX range */
+	    Tcl_WideInt w;
+
+	    if (Tcl_GetWideIntFromObj(NULL, OBJ_AT_TOS, &w) == TCL_OK) {
+		type1 = TCL_NUMBER_WIDE;
+	    }
+	}
+	TclNewIntObj(objResultPtr, type1);
+	TRACE(("\"%.20s\" => %d\n", O2S(OBJ_AT_TOS), type1));
+	NEXT_INST_F(1, 1, 1);
+
+    case INST_EQ:
+    case INST_NEQ:
+    case INST_LT:
+    case INST_GT:
+    case INST_LE:
+    case INST_GE: {
+	int iResult = 0, compare = 0;
+
+	value2Ptr = OBJ_AT_TOS;
+	valuePtr = OBJ_UNDER_TOS;
+
+	if (GetNumberFromObj(NULL, valuePtr, &ptr1, &type1) != TCL_OK) {
+	    /*
+	     * At least one non-numeric argument - compare as strings.
+	     */
+
+	    goto stringCompare;
+	}
+	if (type1 == TCL_NUMBER_NAN) {
+	    /*
+	     * NaN first arg: NaN != to everything, other compares are false.
+	     */
+
+	    iResult = (*pc == INST_NEQ);
+	    goto foundResult;
+	}
+	if (valuePtr == value2Ptr) {
+	    compare = MP_EQ;
+	    goto convertComparison;
+	}
+	if (GetNumberFromObj(NULL, value2Ptr, &ptr2, &type2) != TCL_OK) {
+	    /*
+	     * At least one non-numeric argument - compare as strings.
+	     */
+
+	    goto stringCompare;
+	}
+	if (type2 == TCL_NUMBER_NAN) {
+	    /*
+	     * NaN 2nd arg: NaN != to everything, other compares are false.
+	     */
+
+	    iResult = (*pc == INST_NEQ);
+	    goto foundResult;
+	}
+	if ((type1 == TCL_NUMBER_LONG) && (type2 == TCL_NUMBER_LONG)) {
+	    l1 = *((const long *)ptr1);
+	    l2 = *((const long *)ptr2);
+	    compare = (l1 < l2) ? MP_LT : ((l1 > l2) ? MP_GT : MP_EQ);
+	} else {
+	    compare = TclCompareTwoNumbers(valuePtr, value2Ptr);
+	}
+
+	/*
+	 * Turn comparison outcome into appropriate result for opcode.
+	 */
+
+    convertComparison:
+	switch (*pc) {
+	case INST_EQ:
+	    iResult = (compare == MP_EQ);
+	    break;
+	case INST_NEQ:
+	    iResult = (compare != MP_EQ);
+	    break;
+	case INST_LT:
+	    iResult = (compare == MP_LT);
+	    break;
+	case INST_GT:
+	    iResult = (compare == MP_GT);
+	    break;
+	case INST_LE:
+	    iResult = (compare != MP_GT);
+	    break;
+	case INST_GE:
+	    iResult = (compare != MP_LT);
+	    break;
+	}
+
+	/*
+	 * Peep-hole optimisation: if you're about to jump, do jump from here.
+	 */
+
+    foundResult:
+	TRACE(("\"%.20s\" \"%.20s\" => %d\n", O2S(valuePtr), O2S(value2Ptr),
+		iResult));
+	JUMP_PEEPHOLE_F(iResult, 1, 2);
+    }
+
+    case INST_MOD:
+    case INST_LSHIFT:
+    case INST_RSHIFT:
+    case INST_BITOR:
+    case INST_BITXOR:
+    case INST_BITAND:
+	value2Ptr = OBJ_AT_TOS;
+	valuePtr = OBJ_UNDER_TOS;
+
+	if ((GetNumberFromObj(NULL, valuePtr, &ptr1, &type1) != TCL_OK)
+		|| (type1==TCL_NUMBER_DOUBLE) || (type1==TCL_NUMBER_NAN)) {
+	    TRACE(("%.20s %.20s => ILLEGAL 1st TYPE %s\n", O2S(valuePtr),
+		    O2S(value2Ptr), (valuePtr->typePtr?
+		    valuePtr->typePtr->name : "null")));
+	    DECACHE_STACK_INFO();
+	    IllegalExprOperandType(interp, pc, valuePtr);
+	    CACHE_STACK_INFO();
+	    goto gotError;
+	}
+
+	if ((GetNumberFromObj(NULL, value2Ptr, &ptr2, &type2) != TCL_OK)
+		|| (type2==TCL_NUMBER_DOUBLE) || (type2==TCL_NUMBER_NAN)) {
+	    TRACE(("%.20s %.20s => ILLEGAL 2nd TYPE %s\n", O2S(valuePtr),
+		    O2S(value2Ptr), (value2Ptr->typePtr?
+		    value2Ptr->typePtr->name : "null")));
+	    DECACHE_STACK_INFO();
+	    IllegalExprOperandType(interp, pc, value2Ptr);
+	    CACHE_STACK_INFO();
+	    goto gotError;
+	}
+
+	/*
+	 * Check for common, simple case.
+	 */
+
+	if ((type1 == TCL_NUMBER_LONG) && (type2 == TCL_NUMBER_LONG)) {
+	    l1 = *((const long *)ptr1);
+	    l2 = *((const long *)ptr2);
+
+	    switch (*pc) {
+	    case INST_MOD:
+		if (l2 == 0) {
+		    TRACE(("%s %s => DIVIDE BY ZERO\n", O2S(valuePtr),
+			    O2S(value2Ptr)));
+		    goto divideByZero;
+		} else if ((l2 == 1) || (l2 == -1)) {
+		    /*
+		     * Div. by |1| always yields remainder of 0.
+		     */
+
+		    TRACE(("%s %s => ", O2S(valuePtr), O2S(value2Ptr)));
+		    objResultPtr = TCONST(0);
+		    TRACE(("%s\n", O2S(objResultPtr)));
+		    NEXT_INST_F(1, 2, 1);
+		} else if (l1 == 0) {
+		    /*
+		     * 0 % (non-zero) always yields remainder of 0.
+		     */
+
+		    TRACE(("%s %s => ", O2S(valuePtr), O2S(value2Ptr)));
+		    objResultPtr = TCONST(0);
+		    TRACE(("%s\n", O2S(objResultPtr)));
+		    NEXT_INST_F(1, 2, 1);
+		} else {
+		    lResult = l1 / l2;
+
+		    /*
+		     * Force Tcl's integer division rules.
+		     * TODO: examine for logic simplification
+		     */
+
+		    if ((lResult < 0 || (lResult == 0 &&
+			    ((l1 < 0 && l2 > 0) || (l1 > 0 && l2 < 0)))) &&
+			    (lResult * l2 != l1)) {
+			lResult -= 1;
+		    }
+		    lResult = l1 - l2*lResult;
+		    goto longResultOfArithmetic;
+		}
+
+	    case INST_RSHIFT:
+		if (l2 < 0) {
+		    Tcl_SetObjResult(interp, Tcl_NewStringObj(
+			    "negative shift argument", -1));
+#ifdef ERROR_CODE_FOR_EARLY_DETECTED_ARITH_ERROR
+		    DECACHE_STACK_INFO();
+		    Tcl_SetErrorCode(interp, "ARITH", "DOMAIN",
+			    "domain error: argument not in valid range",
+			    NULL);
+		    CACHE_STACK_INFO();
+#endif /* ERROR_CODE_FOR_EARLY_DETECTED_ARITH_ERROR */
+		    goto gotError;
+		} else if (l1 == 0) {
+		    TRACE(("%s %s => ", O2S(valuePtr), O2S(value2Ptr)));
+		    objResultPtr = TCONST(0);
+		    TRACE(("%s\n", O2S(objResultPtr)));
+		    NEXT_INST_F(1, 2, 1);
+		} else {
+		    /*
+		     * Quickly force large right shifts to 0 or -1.
+		     */
+
+		    if (l2 >= (long)(CHAR_BIT*sizeof(long))) {
+			/*
+			 * We assume that INT_MAX is much larger than the
+			 * number of bits in a long. This is a pretty safe
+			 * assumption, given that the former is usually around
+			 * 4e9 and the latter 32 or 64...
+			 */
+
+			TRACE(("%s %s => ", O2S(valuePtr), O2S(value2Ptr)));
+			if (l1 > 0L) {
+			    objResultPtr = TCONST(0);
+			} else {
+			    TclNewIntObj(objResultPtr, -1);
+			}
+			TRACE(("%s\n", O2S(objResultPtr)));
+			NEXT_INST_F(1, 2, 1);
+		    }
+
+		    /*
+		     * Handle shifts within the native long range.
+		     */
+
+		    lResult = l1 >> ((int) l2);
+		    goto longResultOfArithmetic;
+		}
+
+	    case INST_LSHIFT:
+		if (l2 < 0) {
+		    Tcl_SetObjResult(interp, Tcl_NewStringObj(
+			    "negative shift argument", -1));
+#ifdef ERROR_CODE_FOR_EARLY_DETECTED_ARITH_ERROR
+		    DECACHE_STACK_INFO();
+		    Tcl_SetErrorCode(interp, "ARITH", "DOMAIN",
+			    "domain error: argument not in valid range",
+			    NULL);
+		    CACHE_STACK_INFO();
+#endif /* ERROR_CODE_FOR_EARLY_DETECTED_ARITH_ERROR */
+		    goto gotError;
+		} else if (l1 == 0) {
+		    TRACE(("%s %s => ", O2S(valuePtr), O2S(value2Ptr)));
+		    objResultPtr = TCONST(0);
+		    TRACE(("%s\n", O2S(objResultPtr)));
+		    NEXT_INST_F(1, 2, 1);
+		} else if (l2 > (long) INT_MAX) {
+		    /*
+		     * Technically, we could hold the value (1 << (INT_MAX+1))
+		     * in an mp_int, but since we're using mp_mul_2d() to do
+		     * the work, and it takes only an int argument, that's a
+		     * good place to draw the line.
+		     */
+
+		    Tcl_SetObjResult(interp, Tcl_NewStringObj(
+			    "integer value too large to represent", -1));
+#ifdef ERROR_CODE_FOR_EARLY_DETECTED_ARITH_ERROR
+		    DECACHE_STACK_INFO();
+		    Tcl_SetErrorCode(interp, "ARITH", "IOVERFLOW",
+			    "integer value too large to represent", NULL);
+		    CACHE_STACK_INFO();
+#endif /* ERROR_CODE_FOR_EARLY_DETECTED_ARITH_ERROR */
+		    goto gotError;
+		} else {
+		    int shift = (int) l2;
+
+		    /*
+		     * Handle shifts within the native long range.
+		     */
+
+		    if ((size_t) shift < CHAR_BIT*sizeof(long) && (l1 != 0)
+			    && !((l1>0 ? l1 : ~l1) &
+				-(1L<<(CHAR_BIT*sizeof(long) - 1 - shift)))) {
+			lResult = l1 << shift;
+			goto longResultOfArithmetic;
+		    }
+		}
+
+		/*
+		 * Too large; need to use the broken-out function.
+		 */
+
+		TRACE(("%s %s => ", O2S(valuePtr), O2S(value2Ptr)));
+		break;
+
+	    case INST_BITAND:
+		lResult = l1 & l2;
+		goto longResultOfArithmetic;
+	    case INST_BITOR:
+		lResult = l1 | l2;
+		goto longResultOfArithmetic;
+	    case INST_BITXOR:
+		lResult = l1 ^ l2;
+	    longResultOfArithmetic:
+		TRACE(("%s %s => ", O2S(valuePtr), O2S(value2Ptr)));
+		if (Tcl_IsShared(valuePtr)) {
+		    TclNewLongObj(objResultPtr, lResult);
+		    TRACE(("%s\n", O2S(objResultPtr)));
+		    NEXT_INST_F(1, 2, 1);
+		}
+		TclSetLongObj(valuePtr, lResult);
+		TRACE(("%s\n", O2S(valuePtr)));
+		NEXT_INST_F(1, 1, 0);
+	    }
+	}
+
+	/*
+	 * DO NOT MERGE THIS WITH THE EQUIVALENT SECTION LATER! That would
+	 * encourage the compiler to inline ExecuteExtendedBinaryMathOp, which
+	 * is highly undesirable due to the overall impact on size.
+	 */
+
+	TRACE(("%s %s => ", O2S(valuePtr), O2S(value2Ptr)));
+	objResultPtr = ExecuteExtendedBinaryMathOp(interp, *pc, &TCONST(0),
+		valuePtr, value2Ptr);
+	if (objResultPtr == DIVIDED_BY_ZERO) {
+	    TRACE_APPEND(("DIVIDE BY ZERO\n"));
+	    goto divideByZero;
+	} else if (objResultPtr == GENERAL_ARITHMETIC_ERROR) {
+	    TRACE_ERROR(interp);
+	    goto gotError;
+	} else if (objResultPtr == NULL) {
+	    TRACE_APPEND(("%s\n", O2S(valuePtr)));
+	    NEXT_INST_F(1, 1, 0);
+	} else {
+	    TRACE_APPEND(("%s\n", O2S(objResultPtr)));
+	    NEXT_INST_F(1, 2, 1);
+	}
+
+    case INST_EXPON:
+    case INST_ADD:
+    case INST_SUB:
+    case INST_DIV:
+    case INST_MULT:
+	value2Ptr = OBJ_AT_TOS;
+	valuePtr = OBJ_UNDER_TOS;
+
+	if ((GetNumberFromObj(NULL, valuePtr, &ptr1, &type1) != TCL_OK)
+		|| IsErroringNaNType(type1)) {
+	    TRACE(("%.20s %.20s => ILLEGAL 1st TYPE %s\n",
+		    O2S(value2Ptr), O2S(valuePtr),
+		    (valuePtr->typePtr? valuePtr->typePtr->name: "null")));
+	    DECACHE_STACK_INFO();
+	    IllegalExprOperandType(interp, pc, valuePtr);
+	    CACHE_STACK_INFO();
+	    goto gotError;
+	}
+
+#ifdef ACCEPT_NAN
+	if (type1 == TCL_NUMBER_NAN) {
+	    /*
+	     * NaN first argument -> result is also NaN.
+	     */
+
+	    NEXT_INST_F(1, 1, 0);
+	}
+#endif
+
+	if ((GetNumberFromObj(NULL, value2Ptr, &ptr2, &type2) != TCL_OK)
+		|| IsErroringNaNType(type2)) {
+	    TRACE(("%.20s %.20s => ILLEGAL 2nd TYPE %s\n",
+		    O2S(value2Ptr), O2S(valuePtr),
+		    (value2Ptr->typePtr? value2Ptr->typePtr->name: "null")));
+	    DECACHE_STACK_INFO();
+	    IllegalExprOperandType(interp, pc, value2Ptr);
+	    CACHE_STACK_INFO();
+	    goto gotError;
+	}
+
+#ifdef ACCEPT_NAN
+	if (type2 == TCL_NUMBER_NAN) {
+	    /*
+	     * NaN second argument -> result is also NaN.
+	     */
+
+	    objResultPtr = value2Ptr;
+	    NEXT_INST_F(1, 2, 1);
+	}
+#endif
+
+	/*
+	 * Handle (long,long) arithmetic as best we can without going out to
+	 * an external function.
+	 */
+
+	if ((type1 == TCL_NUMBER_LONG) && (type2 == TCL_NUMBER_LONG)) {
+	    Tcl_WideInt w1, w2, wResult;
+
+	    l1 = *((const long *)ptr1);
+	    l2 = *((const long *)ptr2);
+
+	    switch (*pc) {
+	    case INST_ADD:
+		w1 = (Tcl_WideInt) l1;
+		w2 = (Tcl_WideInt) l2;
+		wResult = w1 + w2;
+#ifdef TCL_WIDE_INT_IS_LONG
+		/*
+		 * Check for overflow.
+		 */
+
+		if (Overflowing(w1, w2, wResult)) {
+		    goto overflow;
+		}
+#endif
+		goto wideResultOfArithmetic;
+
+	    case INST_SUB:
+		w1 = (Tcl_WideInt) l1;
+		w2 = (Tcl_WideInt) l2;
+		wResult = w1 - w2;
+#ifdef TCL_WIDE_INT_IS_LONG
+		/*
+		 * Must check for overflow. The macro tests for overflows in
+		 * sums by looking at the sign bits. As we have a subtraction
+		 * here, we are adding -w2. As -w2 could in turn overflow, we
+		 * test with ~w2 instead: it has the opposite sign bit to w2
+		 * so it does the job. Note that the only "bad" case (w2==0)
+		 * is irrelevant for this macro, as in that case w1 and
+		 * wResult have the same sign and there is no overflow anyway.
+		 */
+
+		if (Overflowing(w1, ~w2, wResult)) {
+		    goto overflow;
+		}
+#endif
+	    wideResultOfArithmetic:
+		TRACE(("%s %s => ", O2S(valuePtr), O2S(value2Ptr)));
+		if (Tcl_IsShared(valuePtr)) {
+		    objResultPtr = Tcl_NewWideIntObj(wResult);
+		    TRACE(("%s\n", O2S(objResultPtr)));
+		    NEXT_INST_F(1, 2, 1);
+		}
+		Tcl_SetWideIntObj(valuePtr, wResult);
+		TRACE(("%s\n", O2S(valuePtr)));
+		NEXT_INST_F(1, 1, 0);
+
+	    case INST_DIV:
+		if (l2 == 0) {
+		    TRACE(("%s %s => DIVIDE BY ZERO\n",
+			    O2S(valuePtr), O2S(value2Ptr)));
+		    goto divideByZero;
+		} else if ((l1 == LONG_MIN) && (l2 == -1)) {
+		    /*
+		     * Can't represent (-LONG_MIN) as a long.
+		     */
+
+		    goto overflow;
+		}
+		lResult = l1 / l2;
+
+		/*
+		 * Force Tcl's integer division rules.
+		 * TODO: examine for logic simplification
+		 */
+
+		if (((lResult < 0) || ((lResult == 0) &&
+			((l1 < 0 && l2 > 0) || (l1 > 0 && l2 < 0)))) &&
+			((lResult * l2) != l1)) {
+		    lResult -= 1;
+		}
+		goto longResultOfArithmetic;
+
+	    case INST_MULT:
+		if (((sizeof(long) >= 2*sizeof(int))
+			&& (l1 <= INT_MAX) && (l1 >= INT_MIN)
+			&& (l2 <= INT_MAX) && (l2 >= INT_MIN))
+			|| ((sizeof(long) >= 2*sizeof(short))
+			&& (l1 <= SHRT_MAX) && (l1 >= SHRT_MIN)
+			&& (l2 <= SHRT_MAX) && (l2 >= SHRT_MIN))) {
+		    lResult = l1 * l2;
+		    goto longResultOfArithmetic;
+		}
+	    }
+
+	    /*
+	     * Fall through with INST_EXPON, INST_DIV and large multiplies.
+	     */
+	}
+
+    overflow:
+	TRACE(("%s %s => ", O2S(valuePtr), O2S(value2Ptr)));
+	objResultPtr = ExecuteExtendedBinaryMathOp(interp, *pc, &TCONST(0),
+		valuePtr, value2Ptr);
+	if (objResultPtr == DIVIDED_BY_ZERO) {
+	    TRACE_APPEND(("DIVIDE BY ZERO\n"));
+	    goto divideByZero;
+	} else if (objResultPtr == EXPONENT_OF_ZERO) {
+	    TRACE_APPEND(("EXPONENT OF ZERO\n"));
+	    goto exponOfZero;
+	} else if (objResultPtr == GENERAL_ARITHMETIC_ERROR) {
+	    TRACE_ERROR(interp);
+	    goto gotError;
+	} else if (objResultPtr == NULL) {
+	    TRACE_APPEND(("%s\n", O2S(valuePtr)));
+	    NEXT_INST_F(1, 1, 0);
+	} else {
+	    TRACE_APPEND(("%s\n", O2S(objResultPtr)));
+	    NEXT_INST_F(1, 2, 1);
+	}
+
+    case INST_LNOT: {
+	int b;
+
+	valuePtr = OBJ_AT_TOS;
+
+	/* TODO - check claim that taking address of b harms performance */
+	/* TODO - consider optimization search for constants */
+	if (TclGetBooleanFromObj(NULL, valuePtr, &b) != TCL_OK) {
+	    TRACE(("\"%.20s\" => ERROR: illegal type %s\n", O2S(valuePtr),
+		    (valuePtr->typePtr? valuePtr->typePtr->name : "null")));
+	    DECACHE_STACK_INFO();
+	    IllegalExprOperandType(interp, pc, valuePtr);
+	    CACHE_STACK_INFO();
+	    goto gotError;
+	}
+	/* TODO: Consider peephole opt. */
+	objResultPtr = TCONST(!b);
+	TRACE_WITH_OBJ(("%s => ", O2S(valuePtr)), objResultPtr);
+	NEXT_INST_F(1, 1, 1);
+    }
+
+    case INST_BITNOT:
+	valuePtr = OBJ_AT_TOS;
+	TRACE(("\"%.20s\" => ", O2S(valuePtr)));
+	if ((GetNumberFromObj(NULL, valuePtr, &ptr1, &type1) != TCL_OK)
+		|| (type1==TCL_NUMBER_NAN) || (type1==TCL_NUMBER_DOUBLE)) {
+	    /*
+	     * ... ~$NonInteger => raise an error.
+	     */
+
+	    TRACE_APPEND(("ERROR: illegal type %s\n",
+		    (valuePtr->typePtr? valuePtr->typePtr->name : "null")));
+	    DECACHE_STACK_INFO();
+	    IllegalExprOperandType(interp, pc, valuePtr);
+	    CACHE_STACK_INFO();
+	    goto gotError;
+	}
+	if (type1 == TCL_NUMBER_LONG) {
+	    l1 = *((const long *) ptr1);
+	    if (Tcl_IsShared(valuePtr)) {
+		TclNewLongObj(objResultPtr, ~l1);
+		TRACE_APPEND(("%s\n", O2S(objResultPtr)));
+		NEXT_INST_F(1, 1, 1);
+	    }
+	    TclSetLongObj(valuePtr, ~l1);
+	    TRACE_APPEND(("%s\n", O2S(valuePtr)));
+	    NEXT_INST_F(1, 0, 0);
+	}
+	objResultPtr = ExecuteExtendedUnaryMathOp(*pc, valuePtr);
+	if (objResultPtr != NULL) {
+	    TRACE_APPEND(("%s\n", O2S(objResultPtr)));
+	    NEXT_INST_F(1, 1, 1);
+	} else {
+	    TRACE_APPEND(("%s\n", O2S(valuePtr)));
+	    NEXT_INST_F(1, 0, 0);
+	}
+
+    case INST_UMINUS:
+	valuePtr = OBJ_AT_TOS;
+	TRACE(("\"%.20s\" => ", O2S(valuePtr)));
+	if ((GetNumberFromObj(NULL, valuePtr, &ptr1, &type1) != TCL_OK)
+		|| IsErroringNaNType(type1)) {
+	    TRACE_APPEND(("ERROR: illegal type %s \n",
+		    (valuePtr->typePtr? valuePtr->typePtr->name : "null")));
+	    DECACHE_STACK_INFO();
+	    IllegalExprOperandType(interp, pc, valuePtr);
+	    CACHE_STACK_INFO();
+	    goto gotError;
+	}
+	switch (type1) {
+	case TCL_NUMBER_NAN:
+	    /* -NaN => NaN */
+	    TRACE_APPEND(("%s\n", O2S(valuePtr)));
+	    NEXT_INST_F(1, 0, 0);
+	case TCL_NUMBER_LONG:
+	    l1 = *((const long *) ptr1);
+	    if (l1 != LONG_MIN) {
+		if (Tcl_IsShared(valuePtr)) {
+		    TclNewLongObj(objResultPtr, -l1);
+		    TRACE_APPEND(("%s\n", O2S(objResultPtr)));
+		    NEXT_INST_F(1, 1, 1);
+		}
+		TclSetLongObj(valuePtr, -l1);
+		TRACE_APPEND(("%s\n", O2S(valuePtr)));
+		NEXT_INST_F(1, 0, 0);
+	    }
+	    /* FALLTHROUGH */
+	}
+	objResultPtr = ExecuteExtendedUnaryMathOp(*pc, valuePtr);
+	if (objResultPtr != NULL) {
+	    TRACE_APPEND(("%s\n", O2S(objResultPtr)));
+	    NEXT_INST_F(1, 1, 1);
+	} else {
+	    TRACE_APPEND(("%s\n", O2S(valuePtr)));
+	    NEXT_INST_F(1, 0, 0);
+	}
+
+    case INST_UPLUS:
+    case INST_TRY_CVT_TO_NUMERIC:
+	/*
+	 * Try to convert the topmost stack object to numeric object. This is
+	 * done in order to support [expr]'s policy of interpreting operands
+	 * if at all possible as numbers first, then strings.
+	 */
+
+	valuePtr = OBJ_AT_TOS;
+	TRACE(("\"%.20s\" => ", O2S(valuePtr)));
+
+	if (GetNumberFromObj(NULL, valuePtr, &ptr1, &type1) != TCL_OK) {
+	    if (*pc == INST_UPLUS) {
+		/*
+		 * ... +$NonNumeric => raise an error.
+		 */
+
+		TRACE_APPEND(("ERROR: illegal type %s\n",
+			(valuePtr->typePtr? valuePtr->typePtr->name:"null")));
+		DECACHE_STACK_INFO();
+		IllegalExprOperandType(interp, pc, valuePtr);
+		CACHE_STACK_INFO();
+		goto gotError;
+	    }
+
+	    /* ... TryConvertToNumeric($NonNumeric) is acceptable */
+	    TRACE_APPEND(("not numeric\n"));
+	    NEXT_INST_F(1, 0, 0);
+	}
+	if (IsErroringNaNType(type1)) {
+	    if (*pc == INST_UPLUS) {
+		/*
+		 * ... +$NonNumeric => raise an error.
+		 */
+
+		TRACE_APPEND(("ERROR: illegal type %s\n",
+			(valuePtr->typePtr? valuePtr->typePtr->name:"null")));
+		DECACHE_STACK_INFO();
+		IllegalExprOperandType(interp, pc, valuePtr);
+		CACHE_STACK_INFO();
+	    } else {
+		/*
+		 * Numeric conversion of NaN -> error.
+		 */
+
+		TRACE_APPEND(("ERROR: IEEE floating pt error\n"));
+		DECACHE_STACK_INFO();
+		TclExprFloatError(interp, *((const double *) ptr1));
+		CACHE_STACK_INFO();
+	    }
+	    goto gotError;
+	}
+
+	/*
+	 * Ensure that the numeric value has a string rep the same as the
+	 * formatted version of its internal rep. This is used, e.g., to make
+	 * sure that "expr {0001}" yields "1", not "0001". We implement this
+	 * by _discarding_ the string rep since we know it will be
+	 * regenerated, if needed later, by formatting the internal rep's
+	 * value.
+	 */
+
+	if (valuePtr->bytes == NULL) {
+	    TRACE_APPEND(("numeric, same Tcl_Obj\n"));
+	    NEXT_INST_F(1, 0, 0);
+	}
+	if (Tcl_IsShared(valuePtr)) {
+	    /*
+	     * Here we do some surgery within the Tcl_Obj internals. We want
+	     * to copy the intrep, but not the string, so we temporarily hide
+	     * the string so we do not copy it.
+	     */
+
+	    char *savedString = valuePtr->bytes;
+
+	    valuePtr->bytes = NULL;
+	    objResultPtr = Tcl_DuplicateObj(valuePtr);
+	    valuePtr->bytes = savedString;
+	    TRACE_APPEND(("numeric, new Tcl_Obj\n"));
+	    NEXT_INST_F(1, 1, 1);
+	}
+	TclInvalidateStringRep(valuePtr);
+	TRACE_APPEND(("numeric, same Tcl_Obj\n"));
+	NEXT_INST_F(1, 0, 0);
+    }
+
+    /*
+     *	   End of numeric operator instructions.
+     * -----------------------------------------------------------------
+     */
+
+    case INST_TRY_CVT_TO_BOOLEAN:
+	valuePtr = OBJ_AT_TOS;
+	if (valuePtr->typePtr == &tclBooleanType) {
+	    objResultPtr = TCONST(1);
+	} else {
+	    int result = (TclSetBooleanFromAny(NULL, valuePtr) == TCL_OK);
+	    objResultPtr = TCONST(result);
+	}
+	TRACE_WITH_OBJ(("\"%.30s\" => ", O2S(valuePtr)), objResultPtr);
+	NEXT_INST_F(1, 0, 1);
+
+    case INST_BREAK:
+	/*
+	DECACHE_STACK_INFO();
+	Tcl_ResetResult(interp);
+	CACHE_STACK_INFO();
+	*/
+	result = TCL_BREAK;
+	cleanup = 0;
+	TRACE(("=> BREAK!\n"));
+	goto processExceptionReturn;
+
+    case INST_CONTINUE:
+	/*
+	DECACHE_STACK_INFO();
+	Tcl_ResetResult(interp);
+	CACHE_STACK_INFO();
+	*/
+	result = TCL_CONTINUE;
+	cleanup = 0;
+	TRACE(("=> CONTINUE!\n"));
+	goto processExceptionReturn;
+
+    {
+	ForeachInfo *infoPtr;
+	Var *iterVarPtr, *listVarPtr;
+	Tcl_Obj *oldValuePtr, *listPtr, **elements;
+	ForeachVarList *varListPtr;
+	int numLists, iterNum, listTmpIndex, listLen, numVars;
+	int varIndex, valIndex, continueLoop, j, iterTmpIndex;
+	long i;
+
+    case INST_FOREACH_START4: /* DEPRECATED */
+	/*
+	 * Initialize the temporary local var that holds the count of the
+	 * number of iterations of the loop body to -1.
+	 */
+
+	opnd = TclGetUInt4AtPtr(pc+1);
+	infoPtr = codePtr->auxDataArrayPtr[opnd].clientData;
+	iterTmpIndex = infoPtr->loopCtTemp;
+	iterVarPtr = LOCAL(iterTmpIndex);
+	oldValuePtr = iterVarPtr->value.objPtr;
+
+	if (oldValuePtr == NULL) {
+	    TclNewLongObj(iterVarPtr->value.objPtr, -1);
+	    Tcl_IncrRefCount(iterVarPtr->value.objPtr);
+	} else {
+	    TclSetLongObj(oldValuePtr, -1);
+	}
+	TRACE(("%u => loop iter count temp %d\n", opnd, iterTmpIndex));
+
+#ifndef TCL_COMPILE_DEBUG
+	/*
+	 * Remark that the compiler ALWAYS sets INST_FOREACH_STEP4 immediately
+	 * after INST_FOREACH_START4 - let us just fall through instead of
+	 * jumping back to the top.
+	 */
+
+	pc += 5;
+	TCL_DTRACE_INST_NEXT();
+#else
+	NEXT_INST_F(5, 0, 0);
+#endif
+
+    case INST_FOREACH_STEP4: /* DEPRECATED */
+	/*
+	 * "Step" a foreach loop (i.e., begin its next iteration) by assigning
+	 * the next value list element to each loop var.
+	 */
+
+	opnd = TclGetUInt4AtPtr(pc+1);
+	TRACE(("%u => ", opnd));
+	infoPtr = codePtr->auxDataArrayPtr[opnd].clientData;
+	numLists = infoPtr->numLists;
+
+	/*
+	 * Increment the temp holding the loop iteration number.
+	 */
+
+	iterVarPtr = LOCAL(infoPtr->loopCtTemp);
+	valuePtr = iterVarPtr->value.objPtr;
+	iterNum = valuePtr->internalRep.longValue + 1;
+	TclSetLongObj(valuePtr, iterNum);
+
+	/*
+	 * Check whether all value lists are exhausted and we should stop the
+	 * loop.
+	 */
+
+	continueLoop = 0;
+	listTmpIndex = infoPtr->firstValueTemp;
+	for (i = 0;  i < numLists;  i++) {
+	    varListPtr = infoPtr->varLists[i];
+	    numVars = varListPtr->numVars;
+
+	    listVarPtr = LOCAL(listTmpIndex);
+	    listPtr = listVarPtr->value.objPtr;
+	    if (TclListObjLength(interp, listPtr, &listLen) != TCL_OK) {
+		TRACE_APPEND(("ERROR converting list %ld, \"%.30s\": %s\n",
+			i, O2S(listPtr), O2S(Tcl_GetObjResult(interp))));
+		goto gotError;
+	    }
+	    if (listLen > iterNum * numVars) {
+		continueLoop = 1;
+	    }
+	    listTmpIndex++;
+	}
+
+	/*
+	 * If some var in some var list still has a remaining list element
+	 * iterate one more time. Assign to var the next element from its
+	 * value list. We already checked above that each list temp holds a
+	 * valid list object (by calling Tcl_ListObjLength), but cannot rely
+	 * on that check remaining valid: one list could have been shimmered
+	 * as a side effect of setting a traced variable.
+	 */
+
+	if (continueLoop) {
+	    listTmpIndex = infoPtr->firstValueTemp;
+	    for (i = 0;  i < numLists;  i++) {
+		varListPtr = infoPtr->varLists[i];
+		numVars = varListPtr->numVars;
+
+		listVarPtr = LOCAL(listTmpIndex);
+		listPtr = TclListObjCopy(NULL, listVarPtr->value.objPtr);
+		TclListObjGetElements(interp, listPtr, &listLen, &elements);
+
+		valIndex = (iterNum * numVars);
+		for (j = 0;  j < numVars;  j++) {
+		    if (valIndex >= listLen) {
+			TclNewObj(valuePtr);
+		    } else {
+			valuePtr = elements[valIndex];
+		    }
+
+		    varIndex = varListPtr->varIndexes[j];
+		    varPtr = LOCAL(varIndex);
+		    while (TclIsVarLink(varPtr)) {
+			varPtr = varPtr->value.linkPtr;
+		    }
+		    if (TclIsVarDirectWritable(varPtr)) {
+			value2Ptr = varPtr->value.objPtr;
+			if (valuePtr != value2Ptr) {
+			    if (value2Ptr != NULL) {
+				TclDecrRefCount(value2Ptr);
+			    }
+			    varPtr->value.objPtr = valuePtr;
+			    Tcl_IncrRefCount(valuePtr);
+			}
+		    } else {
+			DECACHE_STACK_INFO();
+			if (TclPtrSetVar(interp, varPtr, NULL, NULL, NULL,
+				valuePtr, TCL_LEAVE_ERR_MSG, varIndex)==NULL){
+			    CACHE_STACK_INFO();
+			    TRACE_APPEND((
+				    "ERROR init. index temp %d: %s\n",
+				    varIndex, O2S(Tcl_GetObjResult(interp))));
+			    TclDecrRefCount(listPtr);
+			    goto gotError;
+			}
+			CACHE_STACK_INFO();
+		    }
+		    valIndex++;
+		}
+		TclDecrRefCount(listPtr);
+		listTmpIndex++;
+	    }
+	}
+	TRACE_APPEND(("%d lists, iter %d, %s loop\n",
+		numLists, iterNum, (continueLoop? "continue" : "exit")));
+
+	/*
+	 * Run-time peep-hole optimisation: the compiler ALWAYS follows
+	 * INST_FOREACH_STEP4 with an INST_JUMP_FALSE. We just skip that
+	 * instruction and jump direct from here.
+	 */
+
+	pc += 5;
+	if (*pc == INST_JUMP_FALSE1) {
+	    NEXT_INST_F((continueLoop? 2 : TclGetInt1AtPtr(pc+1)), 0, 0);
+	} else {
+	    NEXT_INST_F((continueLoop? 5 : TclGetInt4AtPtr(pc+1)), 0, 0);
+	}
+
+    }
+    {
+	ForeachInfo *infoPtr;
+	Tcl_Obj *listPtr, **elements, *tmpPtr;
+	ForeachVarList *varListPtr;
+	int numLists, iterMax, listLen, numVars;
+	int iterTmp, iterNum, listTmpDepth;
+	int varIndex, valIndex, j;
+	long i;
+
+    case INST_FOREACH_START:
+	/*
+	 * Initialize the data for the looping construct, pushing the
+	 * corresponding Tcl_Objs to the stack.
+	 */
+
+	opnd = TclGetUInt4AtPtr(pc+1);
+	infoPtr = codePtr->auxDataArrayPtr[opnd].clientData;
+	numLists = infoPtr->numLists;
+	TRACE(("%u => ", opnd));
+
+	/*
+	 * Compute the number of iterations that will be run: iterMax
+	 */
+
+	iterMax = 0;
+	listTmpDepth = numLists-1;
+	for (i = 0;  i < numLists;  i++) {
+	    varListPtr = infoPtr->varLists[i];
+	    numVars = varListPtr->numVars;
+	    listPtr = OBJ_AT_DEPTH(listTmpDepth);
+	    if (TclListObjLength(interp, listPtr, &listLen) != TCL_OK) {
+		TRACE_APPEND(("ERROR converting list %ld, \"%s\": %s",
+			i, O2S(listPtr), O2S(Tcl_GetObjResult(interp))));
+		goto gotError;
+	    }
+	    if (Tcl_IsShared(listPtr)) {
+		objPtr = TclListObjCopy(NULL, listPtr);
+		Tcl_IncrRefCount(objPtr);
+		Tcl_DecrRefCount(listPtr);
+		OBJ_AT_DEPTH(listTmpDepth) = objPtr;
+	    }
+	    iterTmp = (listLen + (numVars - 1))/numVars;
+	    if (iterTmp > iterMax) {
+		iterMax = iterTmp;
+	    }
+	    listTmpDepth--;
+	}
+
+	/*
+	 * Store the iterNum and iterMax in a single Tcl_Obj; we keep a
+	 * nul-string obj with the pointer stored in the ptrValue so that the
+	 * thing is properly garbage collected. THIS OBJ MAKES NO SENSE, but
+	 * it will never leave this scope and is read-only.
+	 */
+
+	TclNewObj(tmpPtr);
+	tmpPtr->internalRep.twoPtrValue.ptr1 = INT2PTR(0);
+	tmpPtr->internalRep.twoPtrValue.ptr2 = INT2PTR(iterMax);
+	PUSH_OBJECT(tmpPtr); /* iterCounts object */
+
+	/*
+	 * Store a pointer to the ForeachInfo struct; same dirty trick
+	 * as above
+	 */
+
+	TclNewObj(tmpPtr);
+	tmpPtr->internalRep.twoPtrValue.ptr1 = infoPtr;
+	PUSH_OBJECT(tmpPtr); /* infoPtr object */
+	TRACE_APPEND(("jump to loop step\n"));
+
+	/*
+	 * Jump directly to the INST_FOREACH_STEP instruction; the C code just
+	 * falls through.
+	 */
+
+	pc += 5 - infoPtr->loopCtTemp;
+
+    case INST_FOREACH_STEP:
+	/*
+	 * "Step" a foreach loop (i.e., begin its next iteration) by assigning
+	 * the next value list element to each loop var.
+	 */
+
+	tmpPtr = OBJ_AT_TOS;
+	infoPtr = tmpPtr->internalRep.twoPtrValue.ptr1;
+	numLists = infoPtr->numLists;
+	TRACE(("=> "));
+
+	tmpPtr = OBJ_AT_DEPTH(1);
+	iterNum = PTR2INT(tmpPtr->internalRep.twoPtrValue.ptr1);
+	iterMax = PTR2INT(tmpPtr->internalRep.twoPtrValue.ptr2);
+
+	/*
+	 * If some list still has a remaining list element iterate one more
+	 * time. Assign to var the next element from its value list.
+	 */
+
+	if (iterNum < iterMax) {
+	    /*
+	     * Set the variables and jump back to run the body
+	     */
+
+	    tmpPtr->internalRep.twoPtrValue.ptr1 = INT2PTR(iterNum + 1);
+
+	    listTmpDepth = numLists + 1;
+
+	    for (i = 0;  i < numLists;  i++) {
+		varListPtr = infoPtr->varLists[i];
+		numVars = varListPtr->numVars;
+
+		listPtr = OBJ_AT_DEPTH(listTmpDepth);
+		TclListObjGetElements(interp, listPtr, &listLen, &elements);
+
+		valIndex = (iterNum * numVars);
+		for (j = 0;  j < numVars;  j++) {
+		    if (valIndex >= listLen) {
+			TclNewObj(valuePtr);
+		    } else {
+			valuePtr = elements[valIndex];
+		    }
+
+		    varIndex = varListPtr->varIndexes[j];
+		    varPtr = LOCAL(varIndex);
+		    while (TclIsVarLink(varPtr)) {
+			varPtr = varPtr->value.linkPtr;
+		    }
+		    if (TclIsVarDirectWritable(varPtr)) {
+			value2Ptr = varPtr->value.objPtr;
+			if (valuePtr != value2Ptr) {
+			    if (value2Ptr != NULL) {
+				TclDecrRefCount(value2Ptr);
+			    }
+			    varPtr->value.objPtr = valuePtr;
+			    Tcl_IncrRefCount(valuePtr);
+			}
+		    } else {
+			DECACHE_STACK_INFO();
+			if (TclPtrSetVar(interp, varPtr, NULL, NULL, NULL,
+				valuePtr, TCL_LEAVE_ERR_MSG, varIndex)==NULL){
+			    CACHE_STACK_INFO();
+			    TRACE_APPEND(("ERROR init. index temp %d: %.30s",
+				    varIndex, O2S(Tcl_GetObjResult(interp))));
+			    goto gotError;
+			}
+			CACHE_STACK_INFO();
+		    }
+		    valIndex++;
+		}
+		listTmpDepth--;
+	    }
+	    TRACE_APPEND(("jump to loop start\n"));
+	    /* loopCtTemp being 'misused' for storing the jump size */
+	    NEXT_INST_F(infoPtr->loopCtTemp, 0, 0);
+	}
+
+	TRACE_APPEND(("loop has no more iterations\n"));
+#ifdef TCL_COMPILE_DEBUG
+	NEXT_INST_F(1, 0, 0);
+#else
+	/*
+	 * FALL THROUGH
+	 */
+	pc++;
+#endif
+
+    case INST_FOREACH_END:
+	/* THIS INSTRUCTION IS ONLY CALLED AS A BREAK TARGET */
+	tmpPtr = OBJ_AT_TOS;
+	infoPtr = tmpPtr->internalRep.twoPtrValue.ptr1;
+	numLists = infoPtr->numLists;
+	TRACE(("=> loop terminated\n"));
+	NEXT_INST_V(1, numLists+2, 0);
+
+    case INST_LMAP_COLLECT:
+	/*
+	 * This instruction is only issued by lmap. The stack is:
+	 *   - result
+	 *   - infoPtr
+	 *   - loop counters
+	 *   - valLists
+	 *   - collecting obj (unshared)
+	 * The instruction lappends the result to the collecting obj.
+	 */
+
+	tmpPtr = OBJ_AT_DEPTH(1);
+	infoPtr = tmpPtr->internalRep.twoPtrValue.ptr1;
+	numLists = infoPtr->numLists;
+	TRACE_APPEND(("=> appending to list at depth %d\n", 3 + numLists));
+
+	objPtr = OBJ_AT_DEPTH(3 + numLists);
+	Tcl_ListObjAppendElement(NULL, objPtr, OBJ_AT_TOS);
+	NEXT_INST_F(1, 1, 0);
+    }
+
+    case INST_BEGIN_CATCH4:
+	/*
+	 * Record start of the catch command with exception range index equal
+	 * to the operand. Push the current stack depth onto the special catch
+	 * stack.
+	 */
+
+	*(++catchTop) = CURR_DEPTH;
+	TRACE(("%u => catchTop=%d, stackTop=%d\n",
+		TclGetUInt4AtPtr(pc+1), (int) (catchTop - initCatchTop - 1),
+		(int) CURR_DEPTH));
+	NEXT_INST_F(5, 0, 0);
+
+    case INST_END_CATCH:
+	catchTop--;
+	DECACHE_STACK_INFO();
+	Tcl_ResetResult(interp);
+	CACHE_STACK_INFO();
+	result = TCL_OK;
+	TRACE(("=> catchTop=%d\n", (int) (catchTop - initCatchTop - 1)));
+	NEXT_INST_F(1, 0, 0);
+
+    case INST_PUSH_RESULT:
+	objResultPtr = Tcl_GetObjResult(interp);
+	TRACE_WITH_OBJ(("=> "), objResultPtr);
+
+	/*
+	 * See the comments at INST_INVOKE_STK
+	 */
+
+	TclNewObj(objPtr);
+	Tcl_IncrRefCount(objPtr);
+	iPtr->objResultPtr = objPtr;
+	NEXT_INST_F(1, 0, -1);
+
+    case INST_PUSH_RETURN_CODE:
+	TclNewIntObj(objResultPtr, result);
+	TRACE(("=> %u\n", result));
+	NEXT_INST_F(1, 0, 1);
+
+    case INST_PUSH_RETURN_OPTIONS:
+	DECACHE_STACK_INFO();
+	objResultPtr = Tcl_GetReturnOptions(interp, result);
+	CACHE_STACK_INFO();
+	TRACE_WITH_OBJ(("=> "), objResultPtr);
+	NEXT_INST_F(1, 0, 1);
+
+    case INST_RETURN_CODE_BRANCH: {
+	int code;
+
+	if (TclGetIntFromObj(NULL, OBJ_AT_TOS, &code) != TCL_OK) {
+	    Tcl_Panic("INST_RETURN_CODE_BRANCH: TOS not a return code!");
+	}
+	if (code == TCL_OK) {
+	    Tcl_Panic("INST_RETURN_CODE_BRANCH: TOS is TCL_OK!");
+	}
+	if (code < TCL_ERROR || code > TCL_CONTINUE) {
+	    code = TCL_CONTINUE + 1;
+	}
+	TRACE(("\"%s\" => jump offset %d\n", O2S(OBJ_AT_TOS), 2*code-1));
+	NEXT_INST_F(2*code-1, 1, 0);
+    }
+
+    /*
+     * -----------------------------------------------------------------
+     *	   Start of dictionary-related instructions.
+     */
+
+    {
+	int opnd2, allocateDict, done, i, allocdict;
+	Tcl_Obj *dictPtr, *statePtr, *keyPtr, *listPtr, *varNamePtr, *keysPtr;
+	Tcl_Obj *emptyPtr, **keyPtrPtr;
+	Tcl_DictSearch *searchPtr;
+	DictUpdateInfo *duiPtr;
+
+    case INST_DICT_VERIFY:
+	dictPtr = OBJ_AT_TOS;
+	TRACE(("\"%.30s\" => ", O2S(dictPtr)));
+	if (Tcl_DictObjSize(interp, dictPtr, &done) != TCL_OK) {
+	    TRACE_APPEND(("ERROR verifying dictionary nature of \"%.30s\": %s\n",
+		    O2S(dictPtr), O2S(Tcl_GetObjResult(interp))));
+	    goto gotError;
+	}
+	TRACE_APPEND(("OK\n"));
+	NEXT_INST_F(1, 1, 0);
+
+    case INST_DICT_GET:
+    case INST_DICT_EXISTS: {
+	register Tcl_Interp *interp2 = interp;
+	register int found;
+
+	opnd = TclGetUInt4AtPtr(pc+1);
+	TRACE(("%u => ", opnd));
+	dictPtr = OBJ_AT_DEPTH(opnd);
+	if (*pc == INST_DICT_EXISTS) {
+	    interp2 = NULL;
+	}
+	if (opnd > 1) {
+	    dictPtr = TclTraceDictPath(interp2, dictPtr, opnd-1,
+		    &OBJ_AT_DEPTH(opnd-1), DICT_PATH_READ);
+	    if (dictPtr == NULL) {
+		if (*pc == INST_DICT_EXISTS) {
+		    found = 0;
+		    goto afterDictExists;
+		}
+		TRACE_WITH_OBJ((
+			"ERROR tracing dictionary path into \"%.30s\": ",
+			O2S(OBJ_AT_DEPTH(opnd))),
+			Tcl_GetObjResult(interp));
+		goto gotError;
+	    }
+	}
+	if (Tcl_DictObjGet(interp2, dictPtr, OBJ_AT_TOS,
+		&objResultPtr) == TCL_OK) {
+	    if (*pc == INST_DICT_EXISTS) {
+		found = (objResultPtr ? 1 : 0);
+		goto afterDictExists;
+	    }
+	    if (!objResultPtr) {
+		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+			"key \"%s\" not known in dictionary",
+			TclGetString(OBJ_AT_TOS)));
+		DECACHE_STACK_INFO();
+		Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "DICT",
+			TclGetString(OBJ_AT_TOS), NULL);
+		CACHE_STACK_INFO();
+		TRACE_ERROR(interp);
+		goto gotError;
+	    }
+	    TRACE_APPEND(("%.30s\n", O2S(objResultPtr)));
+	    NEXT_INST_V(5, opnd+1, 1);
+	} else if (*pc != INST_DICT_EXISTS) {
+	    TRACE_APPEND(("ERROR reading leaf dictionary key \"%.30s\": %s",
+		    O2S(dictPtr), O2S(Tcl_GetObjResult(interp))));
+	    goto gotError;
+	} else {
+	    found = 0;
+	}
+    afterDictExists:
+	TRACE_APPEND(("%d\n", found));
+
+	/*
+	 * The INST_DICT_EXISTS instruction is usually followed by a
+	 * conditional jump, so we can take advantage of this to do some
+	 * peephole optimization (note that we're careful to not close out
+	 * someone doing something else).
+	 */
+
+	JUMP_PEEPHOLE_V(found, 5, opnd+1);
+    }
+
+    case INST_DICT_SET:
+    case INST_DICT_UNSET:
+    case INST_DICT_INCR_IMM:
+	opnd = TclGetUInt4AtPtr(pc+1);
+	opnd2 = TclGetUInt4AtPtr(pc+5);
+
+	varPtr = LOCAL(opnd2);
+	while (TclIsVarLink(varPtr)) {
+	    varPtr = varPtr->value.linkPtr;
+	}
+	TRACE(("%u %u => ", opnd, opnd2));
+	if (TclIsVarDirectReadable(varPtr)) {
+	    dictPtr = varPtr->value.objPtr;
+	} else {
+	    DECACHE_STACK_INFO();
+	    dictPtr = TclPtrGetVar(interp, varPtr, NULL,NULL,NULL, 0, opnd2);
+	    CACHE_STACK_INFO();
+	}
+	if (dictPtr == NULL) {
+	    TclNewObj(dictPtr);
+	    allocateDict = 1;
+	} else {
+	    allocateDict = Tcl_IsShared(dictPtr);
+	    if (allocateDict) {
+		dictPtr = Tcl_DuplicateObj(dictPtr);
+	    }
+	}
+
+	switch (*pc) {
+	case INST_DICT_SET:
+	    cleanup = opnd + 1;
+	    result = Tcl_DictObjPutKeyList(interp, dictPtr, opnd,
+		    &OBJ_AT_DEPTH(opnd), OBJ_AT_TOS);
+	    break;
+	case INST_DICT_INCR_IMM:
+	    cleanup = 1;
+	    opnd = TclGetInt4AtPtr(pc+1);
+	    result = Tcl_DictObjGet(interp, dictPtr, OBJ_AT_TOS, &valuePtr);
+	    if (result != TCL_OK) {
+		break;
+	    }
+	    if (valuePtr == NULL) {
+		Tcl_DictObjPut(NULL, dictPtr, OBJ_AT_TOS,Tcl_NewIntObj(opnd));
+	    } else {
+		value2Ptr = Tcl_NewIntObj(opnd);
+		Tcl_IncrRefCount(value2Ptr);
+		if (Tcl_IsShared(valuePtr)) {
+		    valuePtr = Tcl_DuplicateObj(valuePtr);
+		    Tcl_DictObjPut(NULL, dictPtr, OBJ_AT_TOS, valuePtr);
+		}
+		result = TclIncrObj(interp, valuePtr, value2Ptr);
+		if (result == TCL_OK) {
+		    TclInvalidateStringRep(dictPtr);
+		}
+		TclDecrRefCount(value2Ptr);
+	    }
+	    break;
+	case INST_DICT_UNSET:
+	    cleanup = opnd;
+	    result = Tcl_DictObjRemoveKeyList(interp, dictPtr, opnd,
+		    &OBJ_AT_DEPTH(opnd-1));
+	    break;
+	default:
+	    cleanup = 0; /* stop compiler warning */
+	    Tcl_Panic("Should not happen!");
+	}
+
+	if (result != TCL_OK) {
+	    if (allocateDict) {
+		TclDecrRefCount(dictPtr);
+	    }
+	    TRACE_APPEND(("ERROR updating dictionary: %s\n",
+		    O2S(Tcl_GetObjResult(interp))));
+	    goto checkForCatch;
+	}
+
+	if (TclIsVarDirectWritable(varPtr)) {
+	    if (allocateDict) {
+		value2Ptr = varPtr->value.objPtr;
+		Tcl_IncrRefCount(dictPtr);
+		if (value2Ptr != NULL) {
+		    TclDecrRefCount(value2Ptr);
+		}
+		varPtr->value.objPtr = dictPtr;
+	    }
+	    objResultPtr = dictPtr;
+	} else {
+	    Tcl_IncrRefCount(dictPtr);
+	    DECACHE_STACK_INFO();
+	    objResultPtr = TclPtrSetVar(interp, varPtr, NULL, NULL, NULL,
+		    dictPtr, TCL_LEAVE_ERR_MSG, opnd2);
+	    CACHE_STACK_INFO();
+	    TclDecrRefCount(dictPtr);
+	    if (objResultPtr == NULL) {
+		TRACE_ERROR(interp);
+		goto gotError;
+	    }
+	}
+#ifndef TCL_COMPILE_DEBUG
+	if (*(pc+9) == INST_POP) {
+	    NEXT_INST_V(10, cleanup, 0);
+	}
+#endif
+	TRACE_APPEND(("\"%.30s\"\n", O2S(objResultPtr)));
+	NEXT_INST_V(9, cleanup, 1);
+
+    case INST_DICT_APPEND:
+    case INST_DICT_LAPPEND:
+	opnd = TclGetUInt4AtPtr(pc+1);
+	varPtr = LOCAL(opnd);
+	while (TclIsVarLink(varPtr)) {
+	    varPtr = varPtr->value.linkPtr;
+	}
+	TRACE(("%u => ", opnd));
+	if (TclIsVarDirectReadable(varPtr)) {
+	    dictPtr = varPtr->value.objPtr;
+	} else {
+	    DECACHE_STACK_INFO();
+	    dictPtr = TclPtrGetVar(interp, varPtr, NULL, NULL, NULL, 0, opnd);
+	    CACHE_STACK_INFO();
+	}
+	if (dictPtr == NULL) {
+	    TclNewObj(dictPtr);
+	    allocateDict = 1;
+	} else {
+	    allocateDict = Tcl_IsShared(dictPtr);
+	    if (allocateDict) {
+		dictPtr = Tcl_DuplicateObj(dictPtr);
+	    }
+	}
+
+	if (Tcl_DictObjGet(interp, dictPtr, OBJ_UNDER_TOS,
+		&valuePtr) != TCL_OK) {
+	    if (allocateDict) {
+		TclDecrRefCount(dictPtr);
+	    }
+	    TRACE_ERROR(interp);
+	    goto gotError;
+	}
+
+	/*
+	 * Note that a non-existent key results in a NULL valuePtr, which is a
+	 * case handled separately below. What we *can* say at this point is
+	 * that the write-back will always succeed.
+	 */
+
+	switch (*pc) {
+	case INST_DICT_APPEND:
+	    if (valuePtr == NULL) {
+		Tcl_DictObjPut(NULL, dictPtr, OBJ_UNDER_TOS, OBJ_AT_TOS);
+	    } else if (Tcl_IsShared(valuePtr)) {
+		valuePtr = Tcl_DuplicateObj(valuePtr);
+		Tcl_AppendObjToObj(valuePtr, OBJ_AT_TOS);
+		Tcl_DictObjPut(NULL, dictPtr, OBJ_UNDER_TOS, valuePtr);
+	    } else {
+		Tcl_AppendObjToObj(valuePtr, OBJ_AT_TOS);
+
+		/*
+		 * Must invalidate the string representation of dictionary
+		 * here because we have directly updated the internal
+		 * representation; if we don't, callers could see the wrong
+		 * string rep despite the internal version of the dictionary
+		 * having the correct value. [Bug 3079830]
+		 */
+
+		TclInvalidateStringRep(dictPtr);
+	    }
+	    break;
+	case INST_DICT_LAPPEND:
+	    /*
+	     * More complex because list-append can fail.
+	     */
+
+	    if (valuePtr == NULL) {
+		Tcl_DictObjPut(NULL, dictPtr, OBJ_UNDER_TOS,
+			Tcl_NewListObj(1, &OBJ_AT_TOS));
+		break;
+	    } else if (Tcl_IsShared(valuePtr)) {
+		valuePtr = Tcl_DuplicateObj(valuePtr);
+		if (Tcl_ListObjAppendElement(interp, valuePtr,
+			OBJ_AT_TOS) != TCL_OK) {
+		    TclDecrRefCount(valuePtr);
+		    if (allocateDict) {
+			TclDecrRefCount(dictPtr);
+		    }
+		    TRACE_ERROR(interp);
+		    goto gotError;
+		}
+		Tcl_DictObjPut(NULL, dictPtr, OBJ_UNDER_TOS, valuePtr);
+	    } else {
+		if (Tcl_ListObjAppendElement(interp, valuePtr,
+			OBJ_AT_TOS) != TCL_OK) {
+		    if (allocateDict) {
+			TclDecrRefCount(dictPtr);
+		    }
+		    TRACE_ERROR(interp);
+		    goto gotError;
+		}
+
+		/*
+		 * Must invalidate the string representation of dictionary
+		 * here because we have directly updated the internal
+		 * representation; if we don't, callers could see the wrong
+		 * string rep despite the internal version of the dictionary
+		 * having the correct value. [Bug 3079830]
+		 */
+
+		TclInvalidateStringRep(dictPtr);
+	    }
+	    break;
+	default:
+	    Tcl_Panic("Should not happen!");
+	}
+
+	if (TclIsVarDirectWritable(varPtr)) {
+	    if (allocateDict) {
+		value2Ptr = varPtr->value.objPtr;
+		Tcl_IncrRefCount(dictPtr);
+		if (value2Ptr != NULL) {
+		    TclDecrRefCount(value2Ptr);
+		}
+		varPtr->value.objPtr = dictPtr;
+	    }
+	    objResultPtr = dictPtr;
+	} else {
+	    Tcl_IncrRefCount(dictPtr);
+	    DECACHE_STACK_INFO();
+	    objResultPtr = TclPtrSetVar(interp, varPtr, NULL, NULL, NULL,
+		    dictPtr, TCL_LEAVE_ERR_MSG, opnd);
+	    CACHE_STACK_INFO();
+	    TclDecrRefCount(dictPtr);
+	    if (objResultPtr == NULL) {
+		TRACE_ERROR(interp);
+		goto gotError;
+	    }
+	}
+#ifndef TCL_COMPILE_DEBUG
+	if (*(pc+5) == INST_POP) {
+	    NEXT_INST_F(6, 2, 0);
+	}
+#endif
+	TRACE_APPEND(("%.30s\n", O2S(objResultPtr)));
+	NEXT_INST_F(5, 2, 1);
+
+    case INST_DICT_FIRST:
+	opnd = TclGetUInt4AtPtr(pc+1);
+	TRACE(("%u => ", opnd));
+	dictPtr = POP_OBJECT();
+	searchPtr = ckalloc(sizeof(Tcl_DictSearch));
+	if (Tcl_DictObjFirst(interp, dictPtr, searchPtr, &keyPtr,
+		&valuePtr, &done) != TCL_OK) {
+
+	    /*
+	     * dictPtr is no longer on the stack, and we're not
+	     * moving it into the intrep of an iterator.  We need
+	     * to drop the refcount [Tcl Bug 9b352768e6].
+	     */
+
+	    Tcl_DecrRefCount(dictPtr);
+	    ckfree(searchPtr);
+	    TRACE_ERROR(interp);
+	    goto gotError;
+	}
+	TclNewObj(statePtr);
+	statePtr->typePtr = &dictIteratorType;
+	statePtr->internalRep.twoPtrValue.ptr1 = searchPtr;
+	statePtr->internalRep.twoPtrValue.ptr2 = dictPtr;
+	varPtr = LOCAL(opnd);
+	if (varPtr->value.objPtr) {
+	    if (varPtr->value.objPtr->typePtr == &dictIteratorType) {
+		Tcl_Panic("mis-issued dictFirst!");
+	    }
+	    TclDecrRefCount(varPtr->value.objPtr);
+	}
+	varPtr->value.objPtr = statePtr;
+	Tcl_IncrRefCount(statePtr);
+	goto pushDictIteratorResult;
+
+    case INST_DICT_NEXT:
+	opnd = TclGetUInt4AtPtr(pc+1);
+	TRACE(("%u => ", opnd));
+	statePtr = (*LOCAL(opnd)).value.objPtr;
+	if (statePtr == NULL || statePtr->typePtr != &dictIteratorType) {
+	    Tcl_Panic("mis-issued dictNext!");
+	}
+	searchPtr = statePtr->internalRep.twoPtrValue.ptr1;
+	Tcl_DictObjNext(searchPtr, &keyPtr, &valuePtr, &done);
+    pushDictIteratorResult:
+	if (done) {
+	    TclNewObj(emptyPtr);
+	    PUSH_OBJECT(emptyPtr);
+	    PUSH_OBJECT(emptyPtr);
+	} else {
+	    PUSH_OBJECT(valuePtr);
+	    PUSH_OBJECT(keyPtr);
+	}
+	TRACE_APPEND(("\"%.30s\" \"%.30s\" %d\n",
+		O2S(OBJ_UNDER_TOS), O2S(OBJ_AT_TOS), done));
+
+	/*
+	 * The INST_DICT_FIRST and INST_DICT_NEXT instructsions are always
+	 * followed by a conditional jump, so we can take advantage of this to
+	 * do some peephole optimization (note that we're careful to not close
+	 * out someone doing something else).
+	 */
+
+	JUMP_PEEPHOLE_F(done, 5, 0);
+
+    case INST_DICT_UPDATE_START:
+	opnd = TclGetUInt4AtPtr(pc+1);
+	opnd2 = TclGetUInt4AtPtr(pc+5);
+	TRACE(("%u => ", opnd));
+	varPtr = LOCAL(opnd);
+	duiPtr = codePtr->auxDataArrayPtr[opnd2].clientData;
+	while (TclIsVarLink(varPtr)) {
+	    varPtr = varPtr->value.linkPtr;
+	}
+	if (TclIsVarDirectReadable(varPtr)) {
+	    dictPtr = varPtr->value.objPtr;
+	} else {
+	    DECACHE_STACK_INFO();
+	    dictPtr = TclPtrGetVar(interp, varPtr, NULL, NULL, NULL,
+		    TCL_LEAVE_ERR_MSG, opnd);
+	    CACHE_STACK_INFO();
+	    if (dictPtr == NULL) {
+		TRACE_ERROR(interp);
+		goto gotError;
+	    }
+	}
+	Tcl_IncrRefCount(dictPtr);
+	if (TclListObjGetElements(interp, OBJ_AT_TOS, &length,
+		&keyPtrPtr) != TCL_OK) {
+	    TRACE_ERROR(interp);
+	    goto gotError;
+	}
+	if (length != duiPtr->length) {
+	    Tcl_Panic("dictUpdateStart argument length mismatch");
+	}
+	for (i=0 ; i<length ; i++) {
+	    if (Tcl_DictObjGet(interp, dictPtr, keyPtrPtr[i],
+		    &valuePtr) != TCL_OK) {
+		TRACE_ERROR(interp);
+		Tcl_DecrRefCount(dictPtr);
+		goto gotError;
+	    }
+	    varPtr = LOCAL(duiPtr->varIndices[i]);
+	    while (TclIsVarLink(varPtr)) {
+		varPtr = varPtr->value.linkPtr;
+	    }
+	    DECACHE_STACK_INFO();
+	    if (valuePtr == NULL) {
+		TclObjUnsetVar2(interp,
+			localName(iPtr->varFramePtr, duiPtr->varIndices[i]),
+			NULL, 0);
+	    } else if (TclPtrSetVar(interp, varPtr, NULL, NULL, NULL,
+		    valuePtr, TCL_LEAVE_ERR_MSG,
+		    duiPtr->varIndices[i]) == NULL) {
+		CACHE_STACK_INFO();
+		TRACE_ERROR(interp);
+		Tcl_DecrRefCount(dictPtr);
+		goto gotError;
+	    }
+	    CACHE_STACK_INFO();
+	}
+	TclDecrRefCount(dictPtr);
+	TRACE_APPEND(("OK\n"));
+	NEXT_INST_F(9, 0, 0);
+
+    case INST_DICT_UPDATE_END:
+	opnd = TclGetUInt4AtPtr(pc+1);
+	opnd2 = TclGetUInt4AtPtr(pc+5);
+	TRACE(("%u => ", opnd));
+	varPtr = LOCAL(opnd);
+	duiPtr = codePtr->auxDataArrayPtr[opnd2].clientData;
+	while (TclIsVarLink(varPtr)) {
+	    varPtr = varPtr->value.linkPtr;
+	}
+	if (TclIsVarDirectReadable(varPtr)) {
+	    dictPtr = varPtr->value.objPtr;
+	} else {
+	    DECACHE_STACK_INFO();
+	    dictPtr = TclPtrGetVar(interp, varPtr, NULL, NULL, NULL, 0, opnd);
+	    CACHE_STACK_INFO();
+	}
+	if (dictPtr == NULL) {
+	    TRACE_APPEND(("storage was unset\n"));
+	    NEXT_INST_F(9, 1, 0);
+	}
+	if (Tcl_DictObjSize(interp, dictPtr, &length) != TCL_OK
+		|| TclListObjGetElements(interp, OBJ_AT_TOS, &length,
+			&keyPtrPtr) != TCL_OK) {
+	    TRACE_ERROR(interp);
+	    goto gotError;
+	}
+	allocdict = Tcl_IsShared(dictPtr);
+	if (allocdict) {
+	    dictPtr = Tcl_DuplicateObj(dictPtr);
+	}
+	if (length > 0) {
+	    TclInvalidateStringRep(dictPtr);
+	}
+	for (i=0 ; i<length ; i++) {
+	    Var *var2Ptr = LOCAL(duiPtr->varIndices[i]);
+
+	    while (TclIsVarLink(var2Ptr)) {
+		var2Ptr = var2Ptr->value.linkPtr;
+	    }
+	    if (TclIsVarDirectReadable(var2Ptr)) {
+		valuePtr = var2Ptr->value.objPtr;
+	    } else {
+		DECACHE_STACK_INFO();
+		valuePtr = TclPtrGetVar(interp, var2Ptr, NULL, NULL, NULL, 0,
+			duiPtr->varIndices[i]);
+		CACHE_STACK_INFO();
+	    }
+	    if (valuePtr == NULL) {
+		Tcl_DictObjRemove(interp, dictPtr, keyPtrPtr[i]);
+	    } else if (dictPtr == valuePtr) {
+		Tcl_DictObjPut(interp, dictPtr, keyPtrPtr[i],
+			Tcl_DuplicateObj(valuePtr));
+	    } else {
+		Tcl_DictObjPut(interp, dictPtr, keyPtrPtr[i], valuePtr);
+	    }
+	}
+	if (TclIsVarDirectWritable(varPtr)) {
+	    Tcl_IncrRefCount(dictPtr);
+	    TclDecrRefCount(varPtr->value.objPtr);
+	    varPtr->value.objPtr = dictPtr;
+	} else {
+	    DECACHE_STACK_INFO();
+	    objResultPtr = TclPtrSetVar(interp, varPtr, NULL, NULL, NULL,
+		    dictPtr, TCL_LEAVE_ERR_MSG, opnd);
+	    CACHE_STACK_INFO();
+	    if (objResultPtr == NULL) {
+		if (allocdict) {
+		    TclDecrRefCount(dictPtr);
+		}
+		TRACE_ERROR(interp);
+		goto gotError;
+	    }
+	}
+	TRACE_APPEND(("written back\n"));
+	NEXT_INST_F(9, 1, 0);
+
+    case INST_DICT_EXPAND:
+	dictPtr = OBJ_UNDER_TOS;
+	listPtr = OBJ_AT_TOS;
+	TRACE(("\"%.30s\" \"%.30s\" =>", O2S(dictPtr), O2S(listPtr)));
+	if (TclListObjGetElements(interp, listPtr, &objc, &objv) != TCL_OK) {
+	    TRACE_ERROR(interp);
+	    goto gotError;
+	}
+	objResultPtr = TclDictWithInit(interp, dictPtr, objc, objv);
+	if (objResultPtr == NULL) {
+	    TRACE_ERROR(interp);
+	    goto gotError;
+	}
+	TRACE_APPEND(("\"%.30s\"\n", O2S(objResultPtr)));
+	NEXT_INST_F(1, 2, 1);
+
+    case INST_DICT_RECOMBINE_STK:
+	keysPtr = POP_OBJECT();
+	varNamePtr = OBJ_UNDER_TOS;
+	listPtr = OBJ_AT_TOS;
+	TRACE(("\"%.30s\" \"%.30s\" \"%.30s\" => ",
+		O2S(varNamePtr), O2S(valuePtr), O2S(keysPtr)));
+	if (TclListObjGetElements(interp, listPtr, &objc, &objv) != TCL_OK) {
+	    TRACE_ERROR(interp);
+	    TclDecrRefCount(keysPtr);
+	    goto gotError;
+	}
+	varPtr = TclObjLookupVarEx(interp, varNamePtr, NULL,
+		TCL_LEAVE_ERR_MSG, "set", 1, 1, &arrayPtr);
+	if (varPtr == NULL) {
+	    TRACE_ERROR(interp);
+	    TclDecrRefCount(keysPtr);
+	    goto gotError;
+	}
+	DECACHE_STACK_INFO();
+	result = TclDictWithFinish(interp, varPtr,arrayPtr,varNamePtr,NULL,-1,
+		objc, objv, keysPtr);
+	CACHE_STACK_INFO();
+	TclDecrRefCount(keysPtr);
+	if (result != TCL_OK) {
+	    TRACE_ERROR(interp);
+	    goto gotError;
+	}
+	TRACE_APPEND(("OK\n"));
+	NEXT_INST_F(1, 2, 0);
+
+    case INST_DICT_RECOMBINE_IMM:
+	opnd = TclGetUInt4AtPtr(pc+1);
+	listPtr = OBJ_UNDER_TOS;
+	keysPtr = OBJ_AT_TOS;
+	varPtr = LOCAL(opnd);
+	TRACE(("%u <- \"%.30s\" \"%.30s\" => ", opnd, O2S(valuePtr),
+		O2S(keysPtr)));
+	if (TclListObjGetElements(interp, listPtr, &objc, &objv) != TCL_OK) {
+	    TRACE_ERROR(interp);
+	    goto gotError;
+	}
+	while (TclIsVarLink(varPtr)) {
+	    varPtr = varPtr->value.linkPtr;
+	}
+	DECACHE_STACK_INFO();
+	result = TclDictWithFinish(interp, varPtr, NULL, NULL, NULL, opnd,
+		objc, objv, keysPtr);
+	CACHE_STACK_INFO();
+	if (result != TCL_OK) {
+	    TRACE_ERROR(interp);
+	    goto gotError;
+	}
+	TRACE_APPEND(("OK\n"));
+	NEXT_INST_F(5, 2, 0);
+    }
+
+    /*
+     *	   End of dictionary-related instructions.
+     * -----------------------------------------------------------------
+     */
+
+    default:
+	Tcl_Panic("TclNRExecuteByteCode: unrecognized opCode %u", *pc);
+    } /* end of switch on opCode */
+
+    /*
+     * Block for variables needed to process exception returns.
+     */
+
+    {
+	ExceptionRange *rangePtr;
+				/* Points to closest loop or catch exception
+				 * range enclosing the pc. Used by various
+				 * instructions and processCatch to process
+				 * break, continue, and errors. */
+	const char *bytes;
+
+	/*
+	 * An external evaluation (INST_INVOKE or INST_EVAL) returned
+	 * something different from TCL_OK, or else INST_BREAK or
+	 * INST_CONTINUE were called.
+	 */
+
+    processExceptionReturn:
+#ifdef TCL_COMPILE_DEBUG
+	switch (*pc) {
+	case INST_INVOKE_STK1:
+	    opnd = TclGetUInt1AtPtr(pc+1);
+	    TRACE(("%u => ... after \"%.20s\": ", opnd, cmdNameBuf));
+	    break;
+	case INST_INVOKE_STK4:
+	    opnd = TclGetUInt4AtPtr(pc+1);
+	    TRACE(("%u => ... after \"%.20s\": ", opnd, cmdNameBuf));
+	    break;
+	case INST_EVAL_STK:
+	    /*
+	     * Note that the object at stacktop has to be used before doing
+	     * the cleanup.
+	     */
+
+	    TRACE(("\"%.30s\" => ", O2S(OBJ_AT_TOS)));
+	    break;
+	default:
+	    TRACE(("=> "));
+	}
+#endif
+	if ((result == TCL_CONTINUE) || (result == TCL_BREAK)) {
+	    rangePtr = GetExceptRangeForPc(pc, result, codePtr);
+	    if (rangePtr == NULL) {
+		TRACE_APPEND(("no encl. loop or catch, returning %s\n",
+			StringForResultCode(result)));
+		goto abnormalReturn;
+	    }
+	    if (rangePtr->type == CATCH_EXCEPTION_RANGE) {
+		TRACE_APPEND(("%s ...\n", StringForResultCode(result)));
+		goto processCatch;
+	    }
+	    while (cleanup--) {
+		valuePtr = POP_OBJECT();
+		TclDecrRefCount(valuePtr);
+	    }
+	    if (result == TCL_BREAK) {
+		result = TCL_OK;
+		pc = (codePtr->codeStart + rangePtr->breakOffset);
+		TRACE_APPEND(("%s, range at %d, new pc %d\n",
+			StringForResultCode(result),
+			rangePtr->codeOffset, rangePtr->breakOffset));
+		NEXT_INST_F(0, 0, 0);
+	    }
+	    if (rangePtr->continueOffset == -1) {
+		TRACE_APPEND(("%s, loop w/o continue, checking for catch\n",
+			StringForResultCode(result)));
+		goto checkForCatch;
+	    }
+	    result = TCL_OK;
+	    pc = (codePtr->codeStart + rangePtr->continueOffset);
+	    TRACE_APPEND(("%s, range at %d, new pc %d\n",
+		    StringForResultCode(result),
+		    rangePtr->codeOffset, rangePtr->continueOffset));
+	    NEXT_INST_F(0, 0, 0);
+	}
+#ifdef TCL_COMPILE_DEBUG
+	if (traceInstructions) {
+	    objPtr = Tcl_GetObjResult(interp);
+	    if ((result != TCL_ERROR) && (result != TCL_RETURN)) {
+		TRACE_APPEND(("OTHER RETURN CODE %d, result=\"%.30s\"\n ",
+			result, O2S(objPtr)));
+	    } else {
+		TRACE_APPEND(("%s, result=\"%.30s\"\n",
+			StringForResultCode(result), O2S(objPtr)));
+	    }
+	}
+#endif
+	goto checkForCatch;
+
+	/*
+	 * Division by zero in an expression. Control only reaches this point
+	 * by "goto divideByZero".
+	 */
+
+    divideByZero:
+	Tcl_SetObjResult(interp, Tcl_NewStringObj("divide by zero", -1));
+	DECACHE_STACK_INFO();
+	Tcl_SetErrorCode(interp, "ARITH", "DIVZERO", "divide by zero", NULL);
+	CACHE_STACK_INFO();
+	goto gotError;
+
+	/*
+	 * Exponentiation of zero by negative number in an expression. Control
+	 * only reaches this point by "goto exponOfZero".
+	 */
+
+    exponOfZero:
+	Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		"exponentiation of zero by negative power", -1));
+	DECACHE_STACK_INFO();
+	Tcl_SetErrorCode(interp, "ARITH", "DOMAIN",
+		"exponentiation of zero by negative power", NULL);
+	CACHE_STACK_INFO();
+
+	/*
+	 * Almost all error paths feed through here rather than assigning to
+	 * result themselves (for a small but consistent saving).
+	 */
+
+    gotError:
+	result = TCL_ERROR;
+
+	/*
+	 * Execution has generated an "exception" such as TCL_ERROR. If the
+	 * exception is an error, record information about what was being
+	 * executed when the error occurred. Find the closest enclosing catch
+	 * range, if any. If no enclosing catch range is found, stop execution
+	 * and return the "exception" code.
+	 */
+
+    checkForCatch:
+	if (iPtr->execEnvPtr->rewind) {
+	    goto abnormalReturn;
+	}
+	if ((result == TCL_ERROR) && !(iPtr->flags & ERR_ALREADY_LOGGED)) {
+	    const unsigned char *pcBeg;
+
+	    bytes = GetSrcInfoForPc(pc, codePtr, &length, &pcBeg, NULL);
+	    DECACHE_STACK_INFO();
+	    TclLogCommandInfo(interp, codePtr->source, bytes,
+		    bytes ? length : 0, pcBeg, tosPtr);
+	    CACHE_STACK_INFO();
+	}
+	iPtr->flags &= ~ERR_ALREADY_LOGGED;
+
+	/*
+	 * Clear all expansions that may have started after the last
+	 * INST_BEGIN_CATCH.
+	 */
+
+	while (auxObjList) {
+	    if ((catchTop != initCatchTop)
+		    && (*catchTop > (ptrdiff_t)
+			auxObjList->internalRep.twoPtrValue.ptr2)) {
+		break;
+	    }
+	    POP_TAUX_OBJ();
+	}
+
+	/*
+	 * We must not catch if the script in progress has been canceled with
+	 * the TCL_CANCEL_UNWIND flag. Instead, it blows outwards until we
+	 * either hit another interpreter (presumably where the script in
+	 * progress has not been canceled) or we get to the top-level. We do
+	 * NOT modify the interpreter result here because we know it will
+	 * already be set prior to vectoring down to this point in the code.
+	 */
+
+	if (TclCanceled(iPtr) && (Tcl_Canceled(interp, 0) == TCL_ERROR)) {
+#ifdef TCL_COMPILE_DEBUG
+	    if (traceInstructions) {
+		fprintf(stdout, "   ... cancel with unwind, returning %s\n",
+			StringForResultCode(result));
+	    }
+#endif
+	    goto abnormalReturn;
+	}
+
+	/*
+	 * We must not catch an exceeded limit. Instead, it blows outwards
+	 * until we either hit another interpreter (presumably where the limit
+	 * is not exceeded) or we get to the top-level.
+	 */
+
+	if (TclLimitExceeded(iPtr->limit)) {
+#ifdef TCL_COMPILE_DEBUG
+	    if (traceInstructions) {
+		fprintf(stdout, "   ... limit exceeded, returning %s\n",
+			StringForResultCode(result));
+	    }
+#endif
+	    goto abnormalReturn;
+	}
+	if (catchTop == initCatchTop) {
+#ifdef TCL_COMPILE_DEBUG
+	    if (traceInstructions) {
+		fprintf(stdout, "   ... no enclosing catch, returning %s\n",
+			StringForResultCode(result));
+	    }
+#endif
+	    goto abnormalReturn;
+	}
+	rangePtr = GetExceptRangeForPc(pc, TCL_ERROR, codePtr);
+	if (rangePtr == NULL) {
+	    /*
+	     * This is only possible when compiling a [catch] that sends its
+	     * script to INST_EVAL. Cannot correct the compiler without
+	     * breaking compat with previous .tbc compiled scripts.
+	     */
+
+#ifdef TCL_COMPILE_DEBUG
+	    if (traceInstructions) {
+		fprintf(stdout, "   ... no enclosing catch, returning %s\n",
+			StringForResultCode(result));
+	    }
+#endif
+	    goto abnormalReturn;
+	}
+
+	/*
+	 * A catch exception range (rangePtr) was found to handle an
+	 * "exception". It was found either by checkForCatch just above or by
+	 * an instruction during break, continue, or error processing. Jump to
+	 * its catchOffset after unwinding the operand stack to the depth it
+	 * had when starting to execute the range's catch command.
+	 */
+
+    processCatch:
+	while (CURR_DEPTH > *catchTop) {
+	    valuePtr = POP_OBJECT();
+	    TclDecrRefCount(valuePtr);
+	}
+#ifdef TCL_COMPILE_DEBUG
+	if (traceInstructions) {
+	    fprintf(stdout, "  ... found catch at %d, catchTop=%d, "
+		    "unwound to %ld, new pc %u\n",
+		    rangePtr->codeOffset, (int) (catchTop - initCatchTop - 1),
+		    (long) *catchTop, (unsigned) rangePtr->catchOffset);
+	}
+#endif
+	pc = (codePtr->codeStart + rangePtr->catchOffset);
+	NEXT_INST_F(0, 0, 0);	/* Restart the execution loop at pc. */
+
+	/*
+	 * end of infinite loop dispatching on instructions.
+	 */
+
+	/*
+	 * Abnormal return code. Restore the stack to state it had when
+	 * starting to execute the ByteCode. Panic if the stack is below the
+	 * initial level.
+	 */
+
+    abnormalReturn:
+	TCL_DTRACE_INST_LAST();
+
+	/*
+	 * Clear all expansions and same-level NR calls.
+	 *
+	 * Note that expansion markers have a NULL type; avoid removing other
+	 * markers.
+	 */
+
+	while (auxObjList) {
+	    POP_TAUX_OBJ();
+	}
+	while (tosPtr > initTosPtr) {
+	    objPtr = POP_OBJECT();
+	    Tcl_DecrRefCount(objPtr);
+	}
+
+	if (tosPtr < initTosPtr) {
+	    fprintf(stderr,
+		    "\nTclNRExecuteByteCode: abnormal return at pc %u: "
+		    "stack top %d < entry stack top %d\n",
+		    (unsigned)(pc - codePtr->codeStart),
+		    (unsigned) CURR_DEPTH, (unsigned) 0);
+	    Tcl_Panic("TclNRExecuteByteCode execution failure: end stack top < start stack top");
+	}
+	CLANG_ASSERT(bcFramePtr);
+    }
+
+    iPtr->cmdFramePtr = bcFramePtr->nextPtr;
+    if (codePtr->refCount-- <= 1) {
+	TclCleanupByteCode(codePtr);
+    }
+    TclStackFree(interp, TD);	/* free my stack */
+
+    return result;
+
+    /*
+     * INST_START_CMD failure case removed where it doesn't bother that much
+     *
+     * Remark that if the interpreter is marked for deletion its
+     * compileEpoch is modified, so that the epoch check also verifies
+     * that the interp is not deleted. If no outside call has been made
+     * since the last check, it is safe to omit the check.
+
+     * case INST_START_CMD:
+     */
+
+	instStartCmdFailed:
+	{
+	    const char *bytes;
+
+	    checkInterp = 1;
+	    length = 0;
+
+	    /*
+	     * We used to switch to direct eval; for NRE-awareness we now
+	     * compile and eval the command so that this evaluation does not
+	     * add a new TEBC instance. [Bug 2910748]
+	     */
+
+	    if (TclInterpReady(interp) == TCL_ERROR) {
+		goto gotError;
+	    }
+
+	    codePtr->flags |= TCL_BYTECODE_RECOMPILE;
+	    bytes = GetSrcInfoForPc(pc, codePtr, &length, NULL, NULL);
+	    opnd = TclGetUInt4AtPtr(pc+1);
+	    pc += (opnd-1);
+	    assert(bytes);
+	    PUSH_OBJECT(Tcl_NewStringObj(bytes, length));
+	    goto instEvalStk;
+	}
+}
+
+#undef codePtr
+#undef iPtr
+#undef bcFramePtr
+#undef initCatchTop
+#undef initTosPtr
+#undef auxObjList
+#undef catchTop
+#undef TCONST
+#undef esPtr
+
+static int
+FinalizeOONext(
+    ClientData data[],
+    Tcl_Interp *interp,
+    int result)
+{
+    Interp *iPtr = (Interp *) interp;
+    CallContext *contextPtr = data[1];
+
+    /*
+     * Reset the variable lookup frame.
+     */
+
+    iPtr->varFramePtr = data[0];
+
+    /*
+     * Restore the call chain context index as we've finished the inner invoke
+     * and want to operate in the outer context again.
+     */
+
+    contextPtr->index = PTR2INT(data[2]);
+    contextPtr->skip = PTR2INT(data[3]);
+    contextPtr->oPtr->flags &= ~FILTER_HANDLING;
+    return result;
+}
+
+static int
+FinalizeOONextFilter(
+    ClientData data[],
+    Tcl_Interp *interp,
+    int result)
+{
+    Interp *iPtr = (Interp *) interp;
+    CallContext *contextPtr = data[1];
+
+    /*
+     * Reset the variable lookup frame.
+     */
+
+    iPtr->varFramePtr = data[0];
+
+    /*
+     * Restore the call chain context index as we've finished the inner invoke
+     * and want to operate in the outer context again.
+     */
+
+    contextPtr->index = PTR2INT(data[2]);
+    contextPtr->skip = PTR2INT(data[3]);
+    contextPtr->oPtr->flags |= FILTER_HANDLING;
+    return result;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ExecuteExtendedBinaryMathOp, ExecuteExtendedUnaryMathOp --
+ *
+ *	These functions do advanced math for binary and unary operators
+ *	respectively, so that the main TEBC code does not bear the cost of
+ *	them.
+ *
+ * Results:
+ *	A Tcl_Obj* result, or a NULL (in which case valuePtr is updated to
+ *	hold the result value), or one of the special flag values
+ *	GENERAL_ARITHMETIC_ERROR, EXPONENT_OF_ZERO or DIVIDED_BY_ZERO. The
+ *	latter two signify a zero value raised to a negative power or a value
+ *	divided by zero, respectively. With GENERAL_ARITHMETIC_ERROR, all
+ *	error information will have already been reported in the interpreter
+ *	result.
+ *
+ * Side effects:
+ *	May update the Tcl_Obj indicated valuePtr if it is unshared. Will
+ *	return a NULL when that happens.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static Tcl_Obj *
+ExecuteExtendedBinaryMathOp(
+    Tcl_Interp *interp,		/* Where to report errors. */
+    int opcode,			/* What operation to perform. */
+    Tcl_Obj **constants,	/* The execution environment's constants. */
+    Tcl_Obj *valuePtr,		/* The first operand on the stack. */
+    Tcl_Obj *value2Ptr)		/* The second operand on the stack. */
+{
+#define LONG_RESULT(l) \
+    if (Tcl_IsShared(valuePtr)) {		\
+	TclNewLongObj(objResultPtr, l);		\
+	return objResultPtr;			\
+    } else {					\
+	Tcl_SetLongObj(valuePtr, l);		\
+	return NULL;				\
+    }
+#define WIDE_RESULT(w) \
+    if (Tcl_IsShared(valuePtr)) {		\
+	return Tcl_NewWideIntObj(w);		\
+    } else {					\
+	Tcl_SetWideIntObj(valuePtr, w);		\
+	return NULL;				\
+    }
+#define BIG_RESULT(b) \
+    if (Tcl_IsShared(valuePtr)) {		\
+	return Tcl_NewBignumObj(b);		\
+    } else {					\
+	Tcl_SetBignumObj(valuePtr, b);		\
+	return NULL;				\
+    }
+#define DOUBLE_RESULT(d) \
+    if (Tcl_IsShared(valuePtr)) {		\
+	TclNewDoubleObj(objResultPtr, (d));	\
+	return objResultPtr;			\
+    } else {					\
+	Tcl_SetDoubleObj(valuePtr, (d));	\
+	return NULL;				\
+    }
+
+    int type1, type2;
+    ClientData ptr1, ptr2;
+    double d1, d2, dResult;
+    long l1, l2, lResult;
+    Tcl_WideInt w1, w2, wResult;
+    mp_int big1, big2, bigResult, bigRemainder;
+    Tcl_Obj *objResultPtr;
+    int invalid, numPos, zero;
+    long shift;
+
+    (void) GetNumberFromObj(NULL, valuePtr, &ptr1, &type1);
+    (void) GetNumberFromObj(NULL, value2Ptr, &ptr2, &type2);
+
+    switch (opcode) {
+    case INST_MOD:
+	/* TODO: Attempts to re-use unshared operands on stack */
+
+	l2 = 0;			/* silence gcc warning */
+	if (type2 == TCL_NUMBER_LONG) {
+	    l2 = *((const long *)ptr2);
+	    if (l2 == 0) {
+		return DIVIDED_BY_ZERO;
+	    }
+	    if ((l2 == 1) || (l2 == -1)) {
+		/*
+		 * Div. by |1| always yields remainder of 0.
+		 */
+
+		return constants[0];
+	    }
+	}
+#ifndef TCL_WIDE_INT_IS_LONG
+	if (type1 == TCL_NUMBER_WIDE) {
+	    w1 = *((const Tcl_WideInt *)ptr1);
+	    if (type2 != TCL_NUMBER_BIG) {
+		Tcl_WideInt wQuotient, wRemainder;
+		Tcl_GetWideIntFromObj(NULL, value2Ptr, &w2);
+		wQuotient = w1 / w2;
+
+		/*
+		 * Force Tcl's integer division rules.
+		 * TODO: examine for logic simplification
+		 */
+
+		if (((wQuotient < (Tcl_WideInt) 0)
+			|| ((wQuotient == (Tcl_WideInt) 0)
+			&& ((w1 < (Tcl_WideInt)0 && w2 > (Tcl_WideInt)0)
+			|| (w1 > (Tcl_WideInt)0 && w2 < (Tcl_WideInt)0))))
+			&& (wQuotient * w2 != w1)) {
+		    wQuotient -= (Tcl_WideInt) 1;
+		}
+		wRemainder = w1 - w2*wQuotient;
+		WIDE_RESULT(wRemainder);
+	    }
+
+	    Tcl_TakeBignumFromObj(NULL, value2Ptr, &big2);
+
+	    /* TODO: internals intrusion */
+	    if ((w1 > ((Tcl_WideInt) 0)) ^ (big2.sign == MP_ZPOS)) {
+		/*
+		 * Arguments are opposite sign; remainder is sum.
+		 */
+
+		TclBNInitBignumFromWideInt(&big1, w1);
+		mp_add(&big2, &big1, &big2);
+		mp_clear(&big1);
+		BIG_RESULT(&big2);
+	    }
+
+	    /*
+	     * Arguments are same sign; remainder is first operand.
+	     */
+
+	    mp_clear(&big2);
+	    return NULL;
+	}
+#endif
+	Tcl_GetBignumFromObj(NULL, valuePtr, &big1);
+	Tcl_GetBignumFromObj(NULL, value2Ptr, &big2);
+	mp_init(&bigResult);
+	mp_init(&bigRemainder);
+	mp_div(&big1, &big2, &bigResult, &bigRemainder);
+	if (!mp_iszero(&bigRemainder) && (bigRemainder.sign != big2.sign)) {
+	    /*
+	     * Convert to Tcl's integer division rules.
+	     */
+
+	    mp_sub_d(&bigResult, 1, &bigResult);
+	    mp_add(&bigRemainder, &big2, &bigRemainder);
+	}
+	mp_copy(&bigRemainder, &bigResult);
+	mp_clear(&bigRemainder);
+	mp_clear(&big1);
+	mp_clear(&big2);
+	BIG_RESULT(&bigResult);
+
+    case INST_LSHIFT:
+    case INST_RSHIFT: {
+	/*
+	 * Reject negative shift argument.
+	 */
+
+	switch (type2) {
+	case TCL_NUMBER_LONG:
+	    invalid = (*((const long *)ptr2) < 0L);
+	    break;
+#ifndef TCL_WIDE_INT_IS_LONG
+	case TCL_NUMBER_WIDE:
+	    invalid = (*((const Tcl_WideInt *)ptr2) < (Tcl_WideInt)0);
+	    break;
+#endif
+	case TCL_NUMBER_BIG:
+	    Tcl_TakeBignumFromObj(NULL, value2Ptr, &big2);
+	    invalid = (mp_cmp_d(&big2, 0) == MP_LT);
+	    mp_clear(&big2);
+	    break;
+	default:
+	    /* Unused, here to silence compiler warning */
+	    invalid = 0;
+	}
+	if (invalid) {
+	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		    "negative shift argument", -1));
+	    return GENERAL_ARITHMETIC_ERROR;
+	}
+
+	/*
+	 * Zero shifted any number of bits is still zero.
+	 */
+
+	if ((type1==TCL_NUMBER_LONG) && (*((const long *)ptr1) == (long)0)) {
+	    return constants[0];
+	}
+
+	if (opcode == INST_LSHIFT) {
+	    /*
+	     * Large left shifts create integer overflow.
+	     *
+	     * BEWARE! Can't use Tcl_GetIntFromObj() here because that
+	     * converts values in the (unsigned) range to their signed int
+	     * counterparts, leading to incorrect results.
+	     */
+
+	    if ((type2 != TCL_NUMBER_LONG)
+		    || (*((const long *)ptr2) > (long) INT_MAX)) {
+		/*
+		 * Technically, we could hold the value (1 << (INT_MAX+1)) in
+		 * an mp_int, but since we're using mp_mul_2d() to do the
+		 * work, and it takes only an int argument, that's a good
+		 * place to draw the line.
+		 */
+
+		Tcl_SetObjResult(interp, Tcl_NewStringObj(
+			"integer value too large to represent", -1));
+		return GENERAL_ARITHMETIC_ERROR;
+	    }
+	    shift = (int)(*((const long *)ptr2));
+
+	    /*
+	     * Handle shifts within the native wide range.
+	     */
+
+	    if ((type1 != TCL_NUMBER_BIG)
+		    && ((size_t)shift < CHAR_BIT*sizeof(Tcl_WideInt))) {
+		TclGetWideIntFromObj(NULL, valuePtr, &w1);
+		if (!((w1>0 ? w1 : ~w1)
+			& -(((Tcl_WideInt)1)
+			<< (CHAR_BIT*sizeof(Tcl_WideInt) - 1 - shift)))) {
+		    WIDE_RESULT(w1 << shift);
+		}
+	    }
+	} else {
+	    /*
+	     * Quickly force large right shifts to 0 or -1.
+	     */
+
+	    if ((type2 != TCL_NUMBER_LONG)
+		    || (*(const long *)ptr2 > INT_MAX)) {
+		/*
+		 * Again, technically, the value to be shifted could be an
+		 * mp_int so huge that a right shift by (INT_MAX+1) bits could
+		 * not take us to the result of 0 or -1, but since we're using
+		 * mp_div_2d to do the work, and it takes only an int
+		 * argument, we draw the line there.
+		 */
+
+		switch (type1) {
+		case TCL_NUMBER_LONG:
+		    zero = (*(const long *)ptr1 > 0L);
+		    break;
+#ifndef TCL_WIDE_INT_IS_LONG
+		case TCL_NUMBER_WIDE:
+		    zero = (*(const Tcl_WideInt *)ptr1 > (Tcl_WideInt)0);
+		    break;
+#endif
+		case TCL_NUMBER_BIG:
+		    Tcl_TakeBignumFromObj(NULL, valuePtr, &big1);
+		    zero = (mp_cmp_d(&big1, 0) == MP_GT);
+		    mp_clear(&big1);
+		    break;
+		default:
+		    /* Unused, here to silence compiler warning. */
+		    zero = 0;
+		}
+		if (zero) {
+		    return constants[0];
+		}
+		LONG_RESULT(-1);
+	    }
+	    shift = (int)(*(const long *)ptr2);
+
+#ifndef TCL_WIDE_INT_IS_LONG
+	    /*
+	     * Handle shifts within the native wide range.
+	     */
+
+	    if (type1 == TCL_NUMBER_WIDE) {
+		w1 = *(const Tcl_WideInt *)ptr1;
+		if ((size_t)shift >= CHAR_BIT*sizeof(Tcl_WideInt)) {
+		    if (w1 >= (Tcl_WideInt)0) {
+			return constants[0];
+		    }
+		    LONG_RESULT(-1);
+		}
+		WIDE_RESULT(w1 >> shift);
+	    }
+#endif
+	}
+
+	Tcl_TakeBignumFromObj(NULL, valuePtr, &big1);
+
+	mp_init(&bigResult);
+	if (opcode == INST_LSHIFT) {
+	    mp_mul_2d(&big1, shift, &bigResult);
+	} else {
+	    mp_init(&bigRemainder);
+	    mp_div_2d(&big1, shift, &bigResult, &bigRemainder);
+	    if (mp_cmp_d(&bigRemainder, 0) == MP_LT) {
+		/*
+		 * Convert to Tcl's integer division rules.
+		 */
+
+		mp_sub_d(&bigResult, 1, &bigResult);
+	    }
+	    mp_clear(&bigRemainder);
+	}
+	mp_clear(&big1);
+	BIG_RESULT(&bigResult);
+    }
+
+    case INST_BITOR:
+    case INST_BITXOR:
+    case INST_BITAND:
+	if ((type1 == TCL_NUMBER_BIG) || (type2 == TCL_NUMBER_BIG)) {
+	    mp_int *First, *Second;
+
+	    Tcl_TakeBignumFromObj(NULL, valuePtr, &big1);
+	    Tcl_TakeBignumFromObj(NULL, value2Ptr, &big2);
+
+	    /*
+	     * Count how many positive arguments we have. If only one of the
+	     * arguments is negative, store it in 'Second'.
+	     */
+
+	    if (mp_cmp_d(&big1, 0) != MP_LT) {
+		numPos = 1 + (mp_cmp_d(&big2, 0) != MP_LT);
+		First = &big1;
+		Second = &big2;
+	    } else {
+		First = &big2;
+		Second = &big1;
+		numPos = (mp_cmp_d(First, 0) != MP_LT);
+	    }
+	    mp_init(&bigResult);
+
+	    switch (opcode) {
+	    case INST_BITAND:
+		switch (numPos) {
+		case 2:
+		    /*
+		     * Both arguments positive, base case.
+		     */
+
+		    mp_and(First, Second, &bigResult);
+		    break;
+		case 1:
+		    /*
+		     * First is positive; second negative:
+		     * P & N = P & ~~N = P&~(-N-1) = P & (P ^ (-N-1))
+		     */
+
+		    mp_neg(Second, Second);
+		    mp_sub_d(Second, 1, Second);
+		    mp_xor(First, Second, &bigResult);
+		    mp_and(First, &bigResult, &bigResult);
+		    break;
+		case 0:
+		    /*
+		     * Both arguments negative:
+		     * a & b = ~ (~a | ~b) = -(-a-1|-b-1)-1
+		     */
+
+		    mp_neg(First, First);
+		    mp_sub_d(First, 1, First);
+		    mp_neg(Second, Second);
+		    mp_sub_d(Second, 1, Second);
+		    mp_or(First, Second, &bigResult);
+		    mp_neg(&bigResult, &bigResult);
+		    mp_sub_d(&bigResult, 1, &bigResult);
+		    break;
+		}
+		break;
+
+	    case INST_BITOR:
+		switch (numPos) {
+		case 2:
+		    /*
+		     * Both arguments positive, base case.
+		     */
+
+		    mp_or(First, Second, &bigResult);
+		    break;
+		case 1:
+		    /*
+		     * First is positive; second negative:
+		     * N|P = ~(~N&~P) = ~((-N-1)&~P) = -((-N-1)&((-N-1)^P))-1
+		     */
+
+		    mp_neg(Second, Second);
+		    mp_sub_d(Second, 1, Second);
+		    mp_xor(First, Second, &bigResult);
+		    mp_and(Second, &bigResult, &bigResult);
+		    mp_neg(&bigResult, &bigResult);
+		    mp_sub_d(&bigResult, 1, &bigResult);
+		    break;
+		case 0:
+		    /*
+		     * Both arguments negative:
+		     * a | b = ~ (~a & ~b) = -(-a-1&-b-1)-1
+		     */
+
+		    mp_neg(First, First);
+		    mp_sub_d(First, 1, First);
+		    mp_neg(Second, Second);
+		    mp_sub_d(Second, 1, Second);
+		    mp_and(First, Second, &bigResult);
+		    mp_neg(&bigResult, &bigResult);
+		    mp_sub_d(&bigResult, 1, &bigResult);
+		    break;
+		}
+		break;
+
+	    case INST_BITXOR:
+		switch (numPos) {
+		case 2:
+		    /*
+		     * Both arguments positive, base case.
+		     */
+
+		    mp_xor(First, Second, &bigResult);
+		    break;
+		case 1:
+		    /*
+		     * First is positive; second negative:
+		     * P^N = ~(P^~N) = -(P^(-N-1))-1
+		     */
+
+		    mp_neg(Second, Second);
+		    mp_sub_d(Second, 1, Second);
+		    mp_xor(First, Second, &bigResult);
+		    mp_neg(&bigResult, &bigResult);
+		    mp_sub_d(&bigResult, 1, &bigResult);
+		    break;
+		case 0:
+		    /*
+		     * Both arguments negative:
+		     * a ^ b = (~a ^ ~b) = (-a-1^-b-1)
+		     */
+
+		    mp_neg(First, First);
+		    mp_sub_d(First, 1, First);
+		    mp_neg(Second, Second);
+		    mp_sub_d(Second, 1, Second);
+		    mp_xor(First, Second, &bigResult);
+		    break;
+		}
+		break;
+	    }
+
+	    mp_clear(&big1);
+	    mp_clear(&big2);
+	    BIG_RESULT(&bigResult);
+	}
+
+#ifndef TCL_WIDE_INT_IS_LONG
+	if ((type1 == TCL_NUMBER_WIDE) || (type2 == TCL_NUMBER_WIDE)) {
+	    TclGetWideIntFromObj(NULL, valuePtr, &w1);
+	    TclGetWideIntFromObj(NULL, value2Ptr, &w2);
+
+	    switch (opcode) {
+	    case INST_BITAND:
+		wResult = w1 & w2;
+		break;
+	    case INST_BITOR:
+		wResult = w1 | w2;
+		break;
+	    case INST_BITXOR:
+		wResult = w1 ^ w2;
+		break;
+	    default:
+		/* Unused, here to silence compiler warning. */
+		wResult = 0;
+	    }
+	    WIDE_RESULT(wResult);
+	}
+#endif
+	l1 = *((const long *)ptr1);
+	l2 = *((const long *)ptr2);
+
+	switch (opcode) {
+	case INST_BITAND:
+	    lResult = l1 & l2;
+	    break;
+	case INST_BITOR:
+	    lResult = l1 | l2;
+	    break;
+	case INST_BITXOR:
+	    lResult = l1 ^ l2;
+	    break;
+	default:
+	    /* Unused, here to silence compiler warning. */
+	    lResult = 0;
+	}
+	LONG_RESULT(lResult);
+
+    case INST_EXPON: {
+	int oddExponent = 0, negativeExponent = 0;
+	unsigned short base;
+
+	if ((type1 == TCL_NUMBER_DOUBLE) || (type2 == TCL_NUMBER_DOUBLE)) {
+	    Tcl_GetDoubleFromObj(NULL, valuePtr, &d1);
+	    Tcl_GetDoubleFromObj(NULL, value2Ptr, &d2);
+
+	    if (d1==0.0 && d2<0.0) {
+		return EXPONENT_OF_ZERO;
+	    }
+	    dResult = pow(d1, d2);
+	    goto doubleResult;
+	}
+	l1 = l2 = 0;
+	if (type2 == TCL_NUMBER_LONG) {
+	    l2 = *((const long *) ptr2);
+	    if (l2 == 0) {
+		/*
+		 * Anything to the zero power is 1.
+		 */
+
+		return constants[1];
+	    } else if (l2 == 1) {
+		/*
+		 * Anything to the first power is itself
+		 */
+
+		return NULL;
+	    }
+	}
+
+	switch (type2) {
+	case TCL_NUMBER_LONG:
+	    negativeExponent = (l2 < 0);
+	    oddExponent = (int) (l2 & 1);
+	    break;
+#ifndef TCL_WIDE_INT_IS_LONG
+	case TCL_NUMBER_WIDE:
+	    w2 = *((const Tcl_WideInt *)ptr2);
+	    negativeExponent = (w2 < 0);
+	    oddExponent = (int) (w2 & (Tcl_WideInt)1);
+	    break;
+#endif
+	case TCL_NUMBER_BIG:
+	    Tcl_TakeBignumFromObj(NULL, value2Ptr, &big2);
+	    negativeExponent = (mp_cmp_d(&big2, 0) == MP_LT);
+	    mp_mod_2d(&big2, 1, &big2);
+	    oddExponent = !mp_iszero(&big2);
+	    mp_clear(&big2);
+	    break;
+	}
+
+	if (type1 == TCL_NUMBER_LONG) {
+	    l1 = *((const long *)ptr1);
+	}
+	if (negativeExponent) {
+	    if (type1 == TCL_NUMBER_LONG) {
+		switch (l1) {
+		case 0:
+		    /*
+		     * Zero to a negative power is div by zero error.
+		     */
+
+		    return EXPONENT_OF_ZERO;
+		case -1:
+		    if (oddExponent) {
+			LONG_RESULT(-1);
+		    }
+		    /* fallthrough */
+		case 1:
+		    /*
+		     * 1 to any power is 1.
+		     */
+
+		    return constants[1];
+		}
+	    }
+
+	    /*
+	     * Integers with magnitude greater than 1 raise to a negative
+	     * power yield the answer zero (see TIP 123).
+	     */
+
+	    return constants[0];
+	}
+
+	if (type1 == TCL_NUMBER_LONG) {
+	    switch (l1) {
+	    case 0:
+		/*
+		 * Zero to a positive power is zero.
+		 */
+
+		return constants[0];
+	    case 1:
+		/*
+		 * 1 to any power is 1.
+		 */
+
+		return constants[1];
+	    case -1:
+		if (!oddExponent) {
+		    return constants[1];
+		}
+		LONG_RESULT(-1);
+	    }
+	}
+
+	/*
+	 * We refuse to accept exponent arguments that exceed one mp_digit
+	 * which means the max exponent value is 2**28-1 = 0x0fffffff =
+	 * 268435455, which fits into a signed 32 bit int which is within the
+	 * range of the long int type. This means any numeric Tcl_Obj value
+	 * not using TCL_NUMBER_LONG type must hold a value larger than we
+	 * accept.
+	 */
+
+	if (type2 != TCL_NUMBER_LONG) {
+	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		    "exponent too large", -1));
+	    return GENERAL_ARITHMETIC_ERROR;
+	}
+
+	if (type1 == TCL_NUMBER_LONG) {
+	    if (l1 == 2) {
+		/*
+		 * Reduce small powers of 2 to shifts.
+		 */
+
+		if ((unsigned long) l2 < CHAR_BIT * sizeof(long) - 1) {
+		    LONG_RESULT(1L << l2);
+		}
+#if !defined(TCL_WIDE_INT_IS_LONG)
+		if ((unsigned long)l2 < CHAR_BIT*sizeof(Tcl_WideInt) - 1) {
+		    WIDE_RESULT(((Tcl_WideInt) 1) << l2);
+		}
+#endif
+		goto overflowExpon;
+	    }
+	    if (l1 == -2) {
+		int signum = oddExponent ? -1 : 1;
+
+		/*
+		 * Reduce small powers of 2 to shifts.
+		 */
+
+		if ((unsigned long) l2 < CHAR_BIT * sizeof(long) - 1) {
+		    LONG_RESULT(signum * (1L << l2));
+		}
+#if !defined(TCL_WIDE_INT_IS_LONG)
+		if ((unsigned long)l2 < CHAR_BIT*sizeof(Tcl_WideInt) - 1){
+		    WIDE_RESULT(signum * (((Tcl_WideInt) 1) << l2));
+		}
+#endif
+		goto overflowExpon;
+	    }
+#if (LONG_MAX == 0x7fffffff)
+	    if (l2 - 2 < (long)MaxBase32Size
+		    && l1 <= MaxBase32[l2 - 2]
+		    && l1 >= -MaxBase32[l2 - 2]) {
+		/*
+		 * Small powers of 32-bit integers.
+		 */
+
+		lResult = l1 * l1;		/* b**2 */
+		switch (l2) {
+		case 2:
+		    break;
+		case 3:
+		    lResult *= l1;		/* b**3 */
+		    break;
+		case 4:
+		    lResult *= lResult;		/* b**4 */
+		    break;
+		case 5:
+		    lResult *= lResult;		/* b**4 */
+		    lResult *= l1;		/* b**5 */
+		    break;
+		case 6:
+		    lResult *= l1;		/* b**3 */
+		    lResult *= lResult;		/* b**6 */
+		    break;
+		case 7:
+		    lResult *= l1;		/* b**3 */
+		    lResult *= lResult;		/* b**6 */
+		    lResult *= l1;		/* b**7 */
+		    break;
+		case 8:
+		    lResult *= lResult;		/* b**4 */
+		    lResult *= lResult;		/* b**8 */
+		    break;
+		}
+		LONG_RESULT(lResult);
+	    }
+
+	    if (l1 - 3 >= 0 && l1 -2 < (long)Exp32IndexSize
+		    && l2 - 2 < (long)(Exp32ValueSize + MaxBase32Size)) {
+		base = Exp32Index[l1 - 3]
+			+ (unsigned short) (l2 - 2 - MaxBase32Size);
+		if (base < Exp32Index[l1 - 2]) {
+		    /*
+		     * 32-bit number raised to intermediate power, done by
+		     * table lookup.
+		     */
+
+		    LONG_RESULT(Exp32Value[base]);
+		}
+	    }
+	    if (-l1 - 3 >= 0 && -l1 - 2 < (long)Exp32IndexSize
+		    && l2 - 2 < (long)(Exp32ValueSize + MaxBase32Size)) {
+		base = Exp32Index[-l1 - 3]
+			+ (unsigned short) (l2 - 2 - MaxBase32Size);
+		if (base < Exp32Index[-l1 - 2]) {
+		    /*
+		     * 32-bit number raised to intermediate power, done by
+		     * table lookup.
+		     */
+
+		    lResult = (oddExponent) ?
+			    -Exp32Value[base] : Exp32Value[base];
+		    LONG_RESULT(lResult);
+		}
+	    }
+#endif
+	}
+#if (LONG_MAX > 0x7fffffff) || !defined(TCL_WIDE_INT_IS_LONG)
+	if (type1 == TCL_NUMBER_LONG) {
+	    w1 = l1;
+#ifndef TCL_WIDE_INT_IS_LONG
+	} else if (type1 == TCL_NUMBER_WIDE) {
+	    w1 = *((const Tcl_WideInt *) ptr1);
+#endif
+	} else {
+	    goto overflowExpon;
+	}
+	if (l2 - 2 < (long)MaxBase64Size
+		&& w1 <=  MaxBase64[l2 - 2]
+		&& w1 >= -MaxBase64[l2 - 2]) {
+	    /*
+	     * Small powers of integers whose result is wide.
+	     */
+
+	    wResult = w1 * w1;		/* b**2 */
+	    switch (l2) {
+	    case 2:
+		break;
+	    case 3:
+		wResult *= l1;		/* b**3 */
+		break;
+	    case 4:
+		wResult *= wResult;	/* b**4 */
+		break;
+	    case 5:
+		wResult *= wResult;	/* b**4 */
+		wResult *= w1;		/* b**5 */
+		break;
+	    case 6:
+		wResult *= w1;		/* b**3 */
+		wResult *= wResult;	/* b**6 */
+		break;
+	    case 7:
+		wResult *= w1;		/* b**3 */
+		wResult *= wResult;	/* b**6 */
+		wResult *= w1;		/* b**7 */
+		break;
+	    case 8:
+		wResult *= wResult;	/* b**4 */
+		wResult *= wResult;	/* b**8 */
+		break;
+	    case 9:
+		wResult *= wResult;	/* b**4 */
+		wResult *= wResult;	/* b**8 */
+		wResult *= w1;		/* b**9 */
+		break;
+	    case 10:
+		wResult *= wResult;	/* b**4 */
+		wResult *= w1;		/* b**5 */
+		wResult *= wResult;	/* b**10 */
+		break;
+	    case 11:
+		wResult *= wResult;	/* b**4 */
+		wResult *= w1;		/* b**5 */
+		wResult *= wResult;	/* b**10 */
+		wResult *= w1;		/* b**11 */
+		break;
+	    case 12:
+		wResult *= w1;		/* b**3 */
+		wResult *= wResult;	/* b**6 */
+		wResult *= wResult;	/* b**12 */
+		break;
+	    case 13:
+		wResult *= w1;		/* b**3 */
+		wResult *= wResult;	/* b**6 */
+		wResult *= wResult;	/* b**12 */
+		wResult *= w1;		/* b**13 */
+		break;
+	    case 14:
+		wResult *= w1;		/* b**3 */
+		wResult *= wResult;	/* b**6 */
+		wResult *= w1;		/* b**7 */
+		wResult *= wResult;	/* b**14 */
+		break;
+	    case 15:
+		wResult *= w1;		/* b**3 */
+		wResult *= wResult;	/* b**6 */
+		wResult *= w1;		/* b**7 */
+		wResult *= wResult;	/* b**14 */
+		wResult *= w1;		/* b**15 */
+		break;
+	    case 16:
+		wResult *= wResult;	/* b**4 */
+		wResult *= wResult;	/* b**8 */
+		wResult *= wResult;	/* b**16 */
+		break;
+	    }
+	    WIDE_RESULT(wResult);
+	}
+
+	/*
+	 * Handle cases of powers > 16 that still fit in a 64-bit word by
+	 * doing table lookup.
+	 */
+
+	if (w1 - 3 >= 0 && w1 - 2 < (long)Exp64IndexSize
+		&& l2 - 2 < (long)(Exp64ValueSize + MaxBase64Size)) {
+	    base = Exp64Index[w1 - 3]
+		    + (unsigned short) (l2 - 2 - MaxBase64Size);
+	    if (base < Exp64Index[w1 - 2]) {
+		/*
+		 * 64-bit number raised to intermediate power, done by
+		 * table lookup.
+		 */
+
+		WIDE_RESULT(Exp64Value[base]);
+	    }
+	}
+
+	if (-w1 - 3 >= 0 && -w1 - 2 < (long)Exp64IndexSize
+		&& l2 - 2 < (long)(Exp64ValueSize + MaxBase64Size)) {
+	    base = Exp64Index[-w1 - 3]
+		    + (unsigned short) (l2 - 2 - MaxBase64Size);
+	    if (base < Exp64Index[-w1 - 2]) {
+		/*
+		 * 64-bit number raised to intermediate power, done by
+		 * table lookup.
+		 */
+
+		wResult = oddExponent ? -Exp64Value[base] : Exp64Value[base];
+		WIDE_RESULT(wResult);
+	    }
+	}
+#endif
+
+    overflowExpon:
+	Tcl_TakeBignumFromObj(NULL, value2Ptr, &big2);
+	if (big2.used > 1) {
+	    mp_clear(&big2);
+	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		    "exponent too large", -1));
+	    return GENERAL_ARITHMETIC_ERROR;
+	}
+	Tcl_TakeBignumFromObj(NULL, valuePtr, &big1);
+	mp_init(&bigResult);
+	mp_expt_d(&big1, big2.dp[0], &bigResult);
+	mp_clear(&big1);
+	mp_clear(&big2);
+	BIG_RESULT(&bigResult);
+    }
+
+    case INST_ADD:
+    case INST_SUB:
+    case INST_MULT:
+    case INST_DIV:
+	if ((type1 == TCL_NUMBER_DOUBLE) || (type2 == TCL_NUMBER_DOUBLE)) {
+	    /*
+	     * At least one of the values is floating-point, so perform
+	     * floating point calculations.
+	     */
+
+	    Tcl_GetDoubleFromObj(NULL, valuePtr, &d1);
+	    Tcl_GetDoubleFromObj(NULL, value2Ptr, &d2);
+
+	    switch (opcode) {
+	    case INST_ADD:
+		dResult = d1 + d2;
+		break;
+	    case INST_SUB:
+		dResult = d1 - d2;
+		break;
+	    case INST_MULT:
+		dResult = d1 * d2;
+		break;
+	    case INST_DIV:
+#ifndef IEEE_FLOATING_POINT
+		if (d2 == 0.0) {
+		    return DIVIDED_BY_ZERO;
+		}
+#endif
+		/*
+		 * We presume that we are running with zero-divide unmasked if
+		 * we're on an IEEE box. Otherwise, this statement might cause
+		 * demons to fly out our noses.
+		 */
+
+		dResult = d1 / d2;
+		break;
+	    default:
+		/* Unused, here to silence compiler warning. */
+		dResult = 0;
+	    }
+
+	doubleResult:
+#ifndef ACCEPT_NAN
+	    /*
+	     * Check now for IEEE floating-point error.
+	     */
+
+	    if (TclIsNaN(dResult)) {
+		TclExprFloatError(interp, dResult);
+		return GENERAL_ARITHMETIC_ERROR;
+	    }
+#endif
+	    DOUBLE_RESULT(dResult);
+	}
+	if ((type1 != TCL_NUMBER_BIG) && (type2 != TCL_NUMBER_BIG)) {
+	    TclGetWideIntFromObj(NULL, valuePtr, &w1);
+	    TclGetWideIntFromObj(NULL, value2Ptr, &w2);
+
+	    switch (opcode) {
+	    case INST_ADD:
+		wResult = w1 + w2;
+#ifndef TCL_WIDE_INT_IS_LONG
+		if ((type1 == TCL_NUMBER_WIDE) || (type2 == TCL_NUMBER_WIDE))
+#endif
+		{
+		    /*
+		     * Check for overflow.
+		     */
+
+		    if (Overflowing(w1, w2, wResult)) {
+			goto overflowBasic;
+		    }
+		}
+		break;
+
+	    case INST_SUB:
+		wResult = w1 - w2;
+#ifndef TCL_WIDE_INT_IS_LONG
+		if ((type1 == TCL_NUMBER_WIDE) || (type2 == TCL_NUMBER_WIDE))
+#endif
+		{
+		    /*
+		     * Must check for overflow. The macro tests for overflows
+		     * in sums by looking at the sign bits. As we have a
+		     * subtraction here, we are adding -w2. As -w2 could in
+		     * turn overflow, we test with ~w2 instead: it has the
+		     * opposite sign bit to w2 so it does the job. Note that
+		     * the only "bad" case (w2==0) is irrelevant for this
+		     * macro, as in that case w1 and wResult have the same
+		     * sign and there is no overflow anyway.
+		     */
+
+		    if (Overflowing(w1, ~w2, wResult)) {
+			goto overflowBasic;
+		    }
+		}
+		break;
+
+	    case INST_MULT:
+		if ((type1 != TCL_NUMBER_LONG) || (type2 != TCL_NUMBER_LONG)
+			|| (sizeof(Tcl_WideInt) < 2*sizeof(long))) {
+		    goto overflowBasic;
+		}
+		wResult = w1 * w2;
+		break;
+
+	    case INST_DIV:
+		if (w2 == 0) {
+		    return DIVIDED_BY_ZERO;
+		}
+
+		/*
+		 * Need a bignum to represent (LLONG_MIN / -1)
+		 */
+
+		if ((w1 == LLONG_MIN) && (w2 == -1)) {
+		    goto overflowBasic;
+		}
+		wResult = w1 / w2;
+
+		/*
+		 * Force Tcl's integer division rules.
+		 * TODO: examine for logic simplification
+		 */
+
+		if (((wResult < 0) || ((wResult == 0) &&
+			((w1 < 0 && w2 > 0) || (w1 > 0 && w2 < 0)))) &&
+			(wResult*w2 != w1)) {
+		    wResult -= 1;
+		}
+		break;
+
+	    default:
+		/*
+		 * Unused, here to silence compiler warning.
+		 */
+
+		wResult = 0;
+	    }
+
+	    WIDE_RESULT(wResult);
+	}
+
+    overflowBasic:
+	Tcl_TakeBignumFromObj(NULL, valuePtr, &big1);
+	Tcl_TakeBignumFromObj(NULL, value2Ptr, &big2);
+	mp_init(&bigResult);
+	switch (opcode) {
+	case INST_ADD:
+	    mp_add(&big1, &big2, &bigResult);
+	    break;
+	case INST_SUB:
+	    mp_sub(&big1, &big2, &bigResult);
+	    break;
+	case INST_MULT:
+	    mp_mul(&big1, &big2, &bigResult);
+	    break;
+	case INST_DIV:
+	    if (mp_iszero(&big2)) {
+		mp_clear(&big1);
+		mp_clear(&big2);
+		mp_clear(&bigResult);
+		return DIVIDED_BY_ZERO;
+	    }
+	    mp_init(&bigRemainder);
+	    mp_div(&big1, &big2, &bigResult, &bigRemainder);
+	    /* TODO: internals intrusion */
+	    if (!mp_iszero(&bigRemainder)
+		    && (bigRemainder.sign != big2.sign)) {
+		/*
+		 * Convert to Tcl's integer division rules.
+		 */
+
+		mp_sub_d(&bigResult, 1, &bigResult);
+		mp_add(&bigRemainder, &big2, &bigRemainder);
+	    }
+	    mp_clear(&bigRemainder);
+	    break;
+	}
+	mp_clear(&big1);
+	mp_clear(&big2);
+	BIG_RESULT(&bigResult);
+    }
+
+    Tcl_Panic("unexpected opcode");
+    return NULL;
+}
+
+static Tcl_Obj *
+ExecuteExtendedUnaryMathOp(
+    int opcode,			/* What operation to perform. */
+    Tcl_Obj *valuePtr)		/* The operand on the stack. */
+{
+    ClientData ptr;
+    int type;
+    Tcl_WideInt w;
+    mp_int big;
+    Tcl_Obj *objResultPtr;
+
+    (void) GetNumberFromObj(NULL, valuePtr, &ptr, &type);
+
+    switch (opcode) {
+    case INST_BITNOT:
+#ifndef TCL_WIDE_INT_IS_LONG
+	if (type == TCL_NUMBER_WIDE) {
+	    w = *((const Tcl_WideInt *) ptr);
+	    WIDE_RESULT(~w);
+	}
+#endif
+	Tcl_TakeBignumFromObj(NULL, valuePtr, &big);
+	/* ~a = - a - 1 */
+	mp_neg(&big, &big);
+	mp_sub_d(&big, 1, &big);
+	BIG_RESULT(&big);
+    case INST_UMINUS:
+	switch (type) {
+	case TCL_NUMBER_DOUBLE:
+	    DOUBLE_RESULT(-(*((const double *) ptr)));
+	case TCL_NUMBER_LONG:
+	    w = (Tcl_WideInt) (*((const long *) ptr));
+	    if (w != LLONG_MIN) {
+		WIDE_RESULT(-w);
+	    }
+	    TclBNInitBignumFromLong(&big, *(const long *) ptr);
+	    break;
+#ifndef TCL_WIDE_INT_IS_LONG
+	case TCL_NUMBER_WIDE:
+	    w = *((const Tcl_WideInt *) ptr);
+	    if (w != LLONG_MIN) {
+		WIDE_RESULT(-w);
+	    }
+	    TclBNInitBignumFromWideInt(&big, w);
+	    break;
+#endif
+	default:
+	    Tcl_TakeBignumFromObj(NULL, valuePtr, &big);
+	}
+	mp_neg(&big, &big);
+	BIG_RESULT(&big);
+    }
+
+    Tcl_Panic("unexpected opcode");
+    return NULL;
+}
+#undef LONG_RESULT
+#undef WIDE_RESULT
+#undef BIG_RESULT
+#undef DOUBLE_RESULT
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * CompareTwoNumbers --
+ *
+ *	This function compares a pair of numbers in Tcl_Objs. Each argument
+ *	must already be known to be numeric and not NaN.
+ *
+ * Results:
+ *	One of MP_LT, MP_EQ or MP_GT, depending on whether valuePtr is less
+ *	than, equal to, or greater than value2Ptr (respectively).
+ *
+ * Side effects:
+ *	None, provided both values are numeric.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclCompareTwoNumbers(
+    Tcl_Obj *valuePtr,
+    Tcl_Obj *value2Ptr)
+{
+    int type1, type2, compare;
+    ClientData ptr1, ptr2;
+    mp_int big1, big2;
+    double d1, d2, tmp;
+    long l1, l2;
+#ifndef TCL_WIDE_INT_IS_LONG
+    Tcl_WideInt w1, w2;
+#endif
+
+    (void) GetNumberFromObj(NULL, valuePtr, &ptr1, &type1);
+    (void) GetNumberFromObj(NULL, value2Ptr, &ptr2, &type2);
+
+    switch (type1) {
+    case TCL_NUMBER_LONG:
+	l1 = *((const long *)ptr1);
+	switch (type2) {
+	case TCL_NUMBER_LONG:
+	    l2 = *((const long *)ptr2);
+	longCompare:
+	    return (l1 < l2) ? MP_LT : ((l1 > l2) ? MP_GT : MP_EQ);
+#ifndef TCL_WIDE_INT_IS_LONG
+	case TCL_NUMBER_WIDE:
+	    w2 = *((const Tcl_WideInt *)ptr2);
+	    w1 = (Tcl_WideInt)l1;
+	    goto wideCompare;
+#endif
+	case TCL_NUMBER_DOUBLE:
+	    d2 = *((const double *)ptr2);
+	    d1 = (double) l1;
+
+	    /*
+	     * If the double has a fractional part, or if the long can be
+	     * converted to double without loss of precision, then compare as
+	     * doubles.
+	     */
+
+	    if (DBL_MANT_DIG > CHAR_BIT*sizeof(long) || l1 == (long) d1
+		    || modf(d2, &tmp) != 0.0) {
+		goto doubleCompare;
+	    }
+
+	    /*
+	     * Otherwise, to make comparision based on full precision, need to
+	     * convert the double to a suitably sized integer.
+	     *
+	     * Need this to get comparsions like
+	     *	  expr 20000000000000003 < 20000000000000004.0
+	     * right. Converting the first argument to double will yield two
+	     * double values that are equivalent within double precision.
+	     * Converting the double to an integer gets done exactly, then
+	     * integer comparison can tell the difference.
+	     */
+
+	    if (d2 < (double)LONG_MIN) {
+		return MP_GT;
+	    }
+	    if (d2 > (double)LONG_MAX) {
+		return MP_LT;
+	    }
+	    l2 = (long) d2;
+	    goto longCompare;
+	case TCL_NUMBER_BIG:
+	    Tcl_TakeBignumFromObj(NULL, value2Ptr, &big2);
+	    if (mp_cmp_d(&big2, 0) == MP_LT) {
+		compare = MP_GT;
+	    } else {
+		compare = MP_LT;
+	    }
+	    mp_clear(&big2);
+	    return compare;
+	}
+
+#ifndef TCL_WIDE_INT_IS_LONG
+    case TCL_NUMBER_WIDE:
+	w1 = *((const Tcl_WideInt *)ptr1);
+	switch (type2) {
+	case TCL_NUMBER_WIDE:
+	    w2 = *((const Tcl_WideInt *)ptr2);
+	wideCompare:
+	    return (w1 < w2) ? MP_LT : ((w1 > w2) ? MP_GT : MP_EQ);
+	case TCL_NUMBER_LONG:
+	    l2 = *((const long *)ptr2);
+	    w2 = (Tcl_WideInt)l2;
+	    goto wideCompare;
+	case TCL_NUMBER_DOUBLE:
+	    d2 = *((const double *)ptr2);
+	    d1 = (double) w1;
+	    if (DBL_MANT_DIG > CHAR_BIT*sizeof(Tcl_WideInt)
+		    || w1 == (Tcl_WideInt) d1 || modf(d2, &tmp) != 0.0) {
+		goto doubleCompare;
+	    }
+	    if (d2 < (double)LLONG_MIN) {
+		return MP_GT;
+	    }
+	    if (d2 > (double)LLONG_MAX) {
+		return MP_LT;
+	    }
+	    w2 = (Tcl_WideInt) d2;
+	    goto wideCompare;
+	case TCL_NUMBER_BIG:
+	    Tcl_TakeBignumFromObj(NULL, value2Ptr, &big2);
+	    if (mp_cmp_d(&big2, 0) == MP_LT) {
+		compare = MP_GT;
+	    } else {
+		compare = MP_LT;
+	    }
+	    mp_clear(&big2);
+	    return compare;
+	}
+#endif
+
+    case TCL_NUMBER_DOUBLE:
+	d1 = *((const double *)ptr1);
+	switch (type2) {
+	case TCL_NUMBER_DOUBLE:
+	    d2 = *((const double *)ptr2);
+	doubleCompare:
+	    return (d1 < d2) ? MP_LT : ((d1 > d2) ? MP_GT : MP_EQ);
+	case TCL_NUMBER_LONG:
+	    l2 = *((const long *)ptr2);
+	    d2 = (double) l2;
+	    if (DBL_MANT_DIG > CHAR_BIT*sizeof(long) || l2 == (long) d2
+		    || modf(d1, &tmp) != 0.0) {
+		goto doubleCompare;
+	    }
+	    if (d1 < (double)LONG_MIN) {
+		return MP_LT;
+	    }
+	    if (d1 > (double)LONG_MAX) {
+		return MP_GT;
+	    }
+	    l1 = (long) d1;
+	    goto longCompare;
+#ifndef TCL_WIDE_INT_IS_LONG
+	case TCL_NUMBER_WIDE:
+	    w2 = *((const Tcl_WideInt *)ptr2);
+	    d2 = (double) w2;
+	    if (DBL_MANT_DIG > CHAR_BIT*sizeof(Tcl_WideInt)
+		    || w2 == (Tcl_WideInt) d2 || modf(d1, &tmp) != 0.0) {
+		goto doubleCompare;
+	    }
+	    if (d1 < (double)LLONG_MIN) {
+		return MP_LT;
+	    }
+	    if (d1 > (double)LLONG_MAX) {
+		return MP_GT;
+	    }
+	    w1 = (Tcl_WideInt) d1;
+	    goto wideCompare;
+#endif
+	case TCL_NUMBER_BIG:
+	    if (TclIsInfinite(d1)) {
+		return (d1 > 0.0) ? MP_GT : MP_LT;
+	    }
+	    Tcl_TakeBignumFromObj(NULL, value2Ptr, &big2);
+	    if ((d1 < (double)LONG_MAX) && (d1 > (double)LONG_MIN)) {
+		if (mp_cmp_d(&big2, 0) == MP_LT) {
+		    compare = MP_GT;
+		} else {
+		    compare = MP_LT;
+		}
+		mp_clear(&big2);
+		return compare;
+	    }
+	    if (DBL_MANT_DIG > CHAR_BIT*sizeof(long)
+		    && modf(d1, &tmp) != 0.0) {
+		d2 = TclBignumToDouble(&big2);
+		mp_clear(&big2);
+		goto doubleCompare;
+	    }
+	    Tcl_InitBignumFromDouble(NULL, d1, &big1);
+	    goto bigCompare;
+	}
+
+    case TCL_NUMBER_BIG:
+	Tcl_TakeBignumFromObj(NULL, valuePtr, &big1);
+	switch (type2) {
+#ifndef TCL_WIDE_INT_IS_LONG
+	case TCL_NUMBER_WIDE:
+#endif
+	case TCL_NUMBER_LONG:
+	    compare = mp_cmp_d(&big1, 0);
+	    mp_clear(&big1);
+	    return compare;
+	case TCL_NUMBER_DOUBLE:
+	    d2 = *((const double *)ptr2);
+	    if (TclIsInfinite(d2)) {
+		compare = (d2 > 0.0) ? MP_LT : MP_GT;
+		mp_clear(&big1);
+		return compare;
+	    }
+	    if ((d2 < (double)LONG_MAX) && (d2 > (double)LONG_MIN)) {
+		compare = mp_cmp_d(&big1, 0);
+		mp_clear(&big1);
+		return compare;
+	    }
+	    if (DBL_MANT_DIG > CHAR_BIT*sizeof(long)
+		    && modf(d2, &tmp) != 0.0) {
+		d1 = TclBignumToDouble(&big1);
+		mp_clear(&big1);
+		goto doubleCompare;
+	    }
+	    Tcl_InitBignumFromDouble(NULL, d2, &big2);
+	    goto bigCompare;
+	case TCL_NUMBER_BIG:
+	    Tcl_TakeBignumFromObj(NULL, value2Ptr, &big2);
+	bigCompare:
+	    compare = mp_cmp(&big1, &big2);
+	    mp_clear(&big1);
+	    mp_clear(&big2);
+	    return compare;
+	}
+    default:
+	Tcl_Panic("unexpected number type");
+	return TCL_ERROR;
+    }
+}
+
+#ifdef TCL_COMPILE_DEBUG
+/*
+ *----------------------------------------------------------------------
+ *
+ * PrintByteCodeInfo --
+ *
+ *	This procedure prints a summary about a bytecode object to stdout. It
+ *	is called by TclNRExecuteByteCode when starting to execute the bytecode
+ *	object if tclTraceExec has the value 2 or more.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+PrintByteCodeInfo(
+    register ByteCode *codePtr)	/* The bytecode whose summary is printed to
+				 * stdout. */
+{
+    Proc *procPtr = codePtr->procPtr;
+    Interp *iPtr = (Interp *) *codePtr->interpHandle;
+
+    fprintf(stdout, "\nExecuting ByteCode 0x%p, refCt %u, epoch %u, interp 0x%p (epoch %u)\n",
+	    codePtr, codePtr->refCount, codePtr->compileEpoch, iPtr,
+	    iPtr->compileEpoch);
+
+    fprintf(stdout, "  Source: ");
+    TclPrintSource(stdout, codePtr->source, 60);
+
+    fprintf(stdout, "\n  Cmds %d, src %d, inst %u, litObjs %u, aux %d, stkDepth %u, code/src %.2f\n",
+	    codePtr->numCommands, codePtr->numSrcBytes,
+	    codePtr->numCodeBytes, codePtr->numLitObjects,
+	    codePtr->numAuxDataItems, codePtr->maxStackDepth,
+#ifdef TCL_COMPILE_STATS
+	    codePtr->numSrcBytes?
+		    ((float)codePtr->structureSize)/codePtr->numSrcBytes :
+#endif
+	    0.0);
+
+#ifdef TCL_COMPILE_STATS
+    fprintf(stdout, "  Code %lu = header %lu+inst %d+litObj %lu+exc %lu+aux %lu+cmdMap %d\n",
+	    (unsigned long) codePtr->structureSize,
+	    (unsigned long) (sizeof(ByteCode)-sizeof(size_t)-sizeof(Tcl_Time)),
+	    codePtr->numCodeBytes,
+	    (unsigned long) (codePtr->numLitObjects * sizeof(Tcl_Obj *)),
+	    (unsigned long) (codePtr->numExceptRanges*sizeof(ExceptionRange)),
+	    (unsigned long) (codePtr->numAuxDataItems * sizeof(AuxData)),
+	    codePtr->numCmdLocBytes);
+#endif /* TCL_COMPILE_STATS */
+    if (procPtr != NULL) {
+	fprintf(stdout,
+		"  Proc 0x%p, refCt %d, args %d, compiled locals %d\n",
+		procPtr, procPtr->refCount, procPtr->numArgs,
+		procPtr->numCompiledLocals);
+    }
+}
+#endif /* TCL_COMPILE_DEBUG */
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ValidatePcAndStackTop --
+ *
+ *	This procedure is called by TclNRExecuteByteCode when debugging to
+ *	verify that the program counter and stack top are valid during
+ *	execution.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Prints a message to stderr and panics if either the pc or stack top
+ *	are invalid.
+ *
+ *----------------------------------------------------------------------
+ */
+
+#ifdef TCL_COMPILE_DEBUG
+static void
+ValidatePcAndStackTop(
+    register ByteCode *codePtr,	/* The bytecode whose summary is printed to
+				 * stdout. */
+    const unsigned char *pc,	/* Points to first byte of a bytecode
+				 * instruction. The program counter. */
+    int stackTop,		/* Current stack top. Must be between
+				 * stackLowerBound and stackUpperBound
+				 * (inclusive). */
+    int checkStack)		/* 0 if the stack depth check should be
+				 * skipped. */
+{
+    int stackUpperBound = codePtr->maxStackDepth;
+				/* Greatest legal value for stackTop. */
+    unsigned relativePc = (unsigned) (pc - codePtr->codeStart);
+    unsigned long codeStart = (unsigned long) codePtr->codeStart;
+    unsigned long codeEnd = (unsigned long)
+	    (codePtr->codeStart + codePtr->numCodeBytes);
+    unsigned char opCode = *pc;
+
+    if (((unsigned long) pc < codeStart) || ((unsigned long) pc > codeEnd)) {
+	fprintf(stderr, "\nBad instruction pc 0x%p in TclNRExecuteByteCode\n",
+		pc);
+	Tcl_Panic("TclNRExecuteByteCode execution failure: bad pc");
+    }
+    if ((unsigned) opCode > LAST_INST_OPCODE) {
+	fprintf(stderr, "\nBad opcode %d at pc %u in TclNRExecuteByteCode\n",
+		(unsigned) opCode, relativePc);
+	Tcl_Panic("TclNRExecuteByteCode execution failure: bad opcode");
+    }
+    if (checkStack &&
+	    ((stackTop < 0) || (stackTop > stackUpperBound))) {
+	int numChars;
+	const char *cmd = GetSrcInfoForPc(pc, codePtr, &numChars, NULL, NULL);
+
+	fprintf(stderr, "\nBad stack top %d at pc %u in TclNRExecuteByteCode (min 0, max %i)",
+		stackTop, relativePc, stackUpperBound);
+	if (cmd != NULL) {
+	    Tcl_Obj *message;
+
+	    TclNewLiteralStringObj(message, "\n executing ");
+	    Tcl_IncrRefCount(message);
+	    Tcl_AppendLimitedToObj(message, cmd, numChars, 100, NULL);
+	    fprintf(stderr,"%s\n", Tcl_GetString(message));
+	    Tcl_DecrRefCount(message);
+	} else {
+	    fprintf(stderr, "\n");
+	}
+	Tcl_Panic("TclNRExecuteByteCode execution failure: bad stack top");
+    }
+}
+#endif /* TCL_COMPILE_DEBUG */
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * IllegalExprOperandType --
+ *
+ *	Used by TclNRExecuteByteCode to append an error message to the interp
+ *	result when an illegal operand type is detected by an expression
+ *	instruction. The argument opndPtr holds the operand object in error.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	An error message is appended to the interp result.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+IllegalExprOperandType(
+    Tcl_Interp *interp,		/* Interpreter to which error information
+				 * pertains. */
+    const unsigned char *pc, /* Points to the instruction being executed
+				 * when the illegal type was found. */
+    Tcl_Obj *opndPtr)		/* Points to the operand holding the value
+				 * with the illegal type. */
+{
+    ClientData ptr;
+    int type;
+    const unsigned char opcode = *pc;
+    const char *description, *operator = "unknown";
+
+    if (opcode == INST_EXPON) {
+	operator = "**";
+    } else if (opcode <= INST_LNOT) {
+	operator = operatorStrings[opcode - INST_LOR];
+    }
+
+    if (GetNumberFromObj(NULL, opndPtr, &ptr, &type) != TCL_OK) {
+	int numBytes;
+	const char *bytes = Tcl_GetStringFromObj(opndPtr, &numBytes);
+
+	if (numBytes == 0) {
+	    description = "empty string";
+	} else if (TclCheckBadOctal(NULL, bytes)) {
+	    description = "invalid octal number";
+	} else {
+	    description = "non-numeric string";
+	}
+    } else if (type == TCL_NUMBER_NAN) {
+	description = "non-numeric floating-point value";
+    } else if (type == TCL_NUMBER_DOUBLE) {
+	description = "floating-point value";
+    } else {
+	/* TODO: No caller needs this. Eliminate? */
+	description = "(big) integer";
+    }
+
+    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+	    "can't use %s as operand of \"%s\"", description, operator));
+    Tcl_SetErrorCode(interp, "ARITH", "DOMAIN", description, NULL);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclGetSrcInfoForPc, GetSrcInfoForPc, TclGetSourceFromFrame --
+ *
+ *	Given a program counter value, finds the closest command in the
+ *	bytecode code unit's CmdLocation array and returns information about
+ *	that command's source: a pointer to its first byte and the number of
+ *	characters.
+ *
+ * Results:
+ *	If a command is found that encloses the program counter value, a
+ *	pointer to the command's source is returned and the length of the
+ *	source is stored at *lengthPtr. If multiple commands resulted in code
+ *	at pc, information about the closest enclosing command is returned. If
+ *	no matching command is found, NULL is returned and *lengthPtr is
+ *	unchanged.
+ *
+ * Side effects:
+ *	The CmdFrame at *cfPtr is updated.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_Obj *
+TclGetSourceFromFrame(
+    CmdFrame *cfPtr,
+    int objc,
+    Tcl_Obj *const objv[])
+{
+    if (cfPtr == NULL) {
+        return Tcl_NewListObj(objc, objv);
+    }
+    if (cfPtr->cmdObj == NULL) {
+        if (cfPtr->cmd == NULL) {
+	    ByteCode *codePtr = (ByteCode *) cfPtr->data.tebc.codePtr;
+
+            cfPtr->cmd = GetSrcInfoForPc((unsigned char *)
+		    cfPtr->data.tebc.pc, codePtr, &cfPtr->len, NULL, NULL);
+        }
+	if (cfPtr->cmd) {
+	    cfPtr->cmdObj = Tcl_NewStringObj(cfPtr->cmd, cfPtr->len);
+	} else {
+	    cfPtr->cmdObj = Tcl_NewListObj(objc, objv);
+	}
+        Tcl_IncrRefCount(cfPtr->cmdObj);
+    }
+    return cfPtr->cmdObj;
+}
+
+void
+TclGetSrcInfoForPc(
+    CmdFrame *cfPtr)
+{
+    ByteCode *codePtr = (ByteCode *) cfPtr->data.tebc.codePtr;
+
+    assert(cfPtr->type == TCL_LOCATION_BC);
+
+    if (cfPtr->cmd == NULL) {
+
+	cfPtr->cmd = GetSrcInfoForPc(
+		(unsigned char *) cfPtr->data.tebc.pc, codePtr,
+		&cfPtr->len, NULL, NULL);
+    }
+
+    if (cfPtr->cmd != NULL) {
+	/*
+	 * We now have the command. We can get the srcOffset back and from
+	 * there find the list of word locations for this command.
+	 */
+
+	ExtCmdLoc *eclPtr;
+	ECL *locPtr = NULL;
+	int srcOffset, i;
+	Interp *iPtr = (Interp *) *codePtr->interpHandle;
+	Tcl_HashEntry *hePtr =
+		Tcl_FindHashEntry(iPtr->lineBCPtr, codePtr);
+
+	if (!hePtr) {
+	    return;
+	}
+
+	srcOffset = cfPtr->cmd - codePtr->source;
+	eclPtr = Tcl_GetHashValue(hePtr);
+
+	for (i=0; i < eclPtr->nuloc; i++) {
+	    if (eclPtr->loc[i].srcOffset == srcOffset) {
+		locPtr = eclPtr->loc+i;
+		break;
+	    }
+	}
+	if (locPtr == NULL) {
+	    Tcl_Panic("LocSearch failure");
+	}
+
+	cfPtr->line = locPtr->line;
+	cfPtr->nline = locPtr->nline;
+	cfPtr->type = eclPtr->type;
+
+	if (eclPtr->type == TCL_LOCATION_SOURCE) {
+	    cfPtr->data.eval.path = eclPtr->path;
+	    Tcl_IncrRefCount(cfPtr->data.eval.path);
+	}
+
+	/*
+	 * Do not set cfPtr->data.eval.path NULL for non-SOURCE. Needed for
+	 * cfPtr->data.tebc.codePtr.
+	 */
+    }
+}
+
+static const char *
+GetSrcInfoForPc(
+    const unsigned char *pc,	/* The program counter value for which to
+				 * return the closest command's source info.
+				 * This points within a bytecode instruction
+				 * in codePtr's code. */
+    ByteCode *codePtr,		/* The bytecode sequence in which to look up
+				 * the command source for the pc. */
+    int *lengthPtr,		/* If non-NULL, the location where the length
+				 * of the command's source should be stored.
+				 * If NULL, no length is stored. */
+    const unsigned char **pcBeg,/* If non-NULL, the bytecode location
+				 * where the current instruction starts.
+				 * If NULL; no pointer is stored. */
+    int *cmdIdxPtr)		/* If non-NULL, the location where the index
+				 * of the command containing the pc should
+				 * be stored. */
+{
+    register int pcOffset = (pc - codePtr->codeStart);
+    int numCmds = codePtr->numCommands;
+    unsigned char *codeDeltaNext, *codeLengthNext;
+    unsigned char *srcDeltaNext, *srcLengthNext;
+    int codeOffset, codeLen, codeEnd, srcOffset, srcLen, delta, i;
+    int bestDist = INT_MAX;	/* Distance of pc to best cmd's start pc. */
+    int bestSrcOffset = -1;	/* Initialized to avoid compiler warning. */
+    int bestSrcLength = -1;	/* Initialized to avoid compiler warning. */
+    int bestCmdIdx = -1;
+
+    /* The pc must point within the bytecode */
+    assert ((pcOffset >= 0) && (pcOffset < codePtr->numCodeBytes));
+
+    /*
+     * Decode the code and source offset and length for each command. The
+     * closest enclosing command is the last one whose code started before
+     * pcOffset.
+     */
+
+    codeDeltaNext = codePtr->codeDeltaStart;
+    codeLengthNext = codePtr->codeLengthStart;
+    srcDeltaNext = codePtr->srcDeltaStart;
+    srcLengthNext = codePtr->srcLengthStart;
+    codeOffset = srcOffset = 0;
+    for (i = 0;  i < numCmds;  i++) {
+	if ((unsigned) *codeDeltaNext == (unsigned) 0xFF) {
+	    codeDeltaNext++;
+	    delta = TclGetInt4AtPtr(codeDeltaNext);
+	    codeDeltaNext += 4;
+	} else {
+	    delta = TclGetInt1AtPtr(codeDeltaNext);
+	    codeDeltaNext++;
+	}
+	codeOffset += delta;
+
+	if ((unsigned) *codeLengthNext == (unsigned) 0xFF) {
+	    codeLengthNext++;
+	    codeLen = TclGetInt4AtPtr(codeLengthNext);
+	    codeLengthNext += 4;
+	} else {
+	    codeLen = TclGetInt1AtPtr(codeLengthNext);
+	    codeLengthNext++;
+	}
+	codeEnd = (codeOffset + codeLen - 1);
+
+	if ((unsigned) *srcDeltaNext == (unsigned) 0xFF) {
+	    srcDeltaNext++;
+	    delta = TclGetInt4AtPtr(srcDeltaNext);
+	    srcDeltaNext += 4;
+	} else {
+	    delta = TclGetInt1AtPtr(srcDeltaNext);
+	    srcDeltaNext++;
+	}
+	srcOffset += delta;
+
+	if ((unsigned) *srcLengthNext == (unsigned) 0xFF) {
+	    srcLengthNext++;
+	    srcLen = TclGetInt4AtPtr(srcLengthNext);
+	    srcLengthNext += 4;
+	} else {
+	    srcLen = TclGetInt1AtPtr(srcLengthNext);
+	    srcLengthNext++;
+	}
+
+	if (codeOffset > pcOffset) {	/* Best cmd already found */
+	    break;
+	}
+	if (pcOffset <= codeEnd) {	/* This cmd's code encloses pc */
+	    int dist = (pcOffset - codeOffset);
+
+	    if (dist <= bestDist) {
+		bestDist = dist;
+		bestSrcOffset = srcOffset;
+		bestSrcLength = srcLen;
+		bestCmdIdx = i;
+	    }
+	}
+    }
+
+    if (pcBeg != NULL) {
+	const unsigned char *curr, *prev;
+
+	/*
+	 * Walk from beginning of command or BC to pc, by complete
+	 * instructions. Stop when crossing pc; keep previous.
+	 */
+
+	curr = ((bestDist == INT_MAX) ? codePtr->codeStart : pc - bestDist);
+	prev = curr;
+	while (curr <= pc) {
+	    prev = curr;
+	    curr += tclInstructionTable[*curr].numBytes;
+	}
+	*pcBeg = prev;
+    }
+
+    if (bestDist == INT_MAX) {
+	return NULL;
+    }
+
+    if (lengthPtr != NULL) {
+	*lengthPtr = bestSrcLength;
+    }
+
+    if (cmdIdxPtr != NULL) {
+	*cmdIdxPtr = bestCmdIdx;
+    }
+
+    return (codePtr->source + bestSrcOffset);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * GetExceptRangeForPc --
+ *
+ *	Given a program counter value, return the closest enclosing
+ *	ExceptionRange.
+ *
+ * Results:
+ *	If the searchMode is TCL_ERROR, this procedure ignores loop exception
+ *	ranges and returns a pointer to the closest catch range. If the
+ *	searchMode is TCL_BREAK, this procedure returns a pointer to the most
+ *	closely enclosing ExceptionRange regardless of whether it is a loop or
+ *	catch exception range. If the searchMode is TCL_CONTINUE, this
+ *	procedure returns a pointer to the most closely enclosing
+ *	ExceptionRange (of any type) skipping only loop exception ranges if
+ *	they don't have a sensible continueOffset defined. If no matching
+ *	ExceptionRange is found that encloses pc, a NULL is returned.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static ExceptionRange *
+GetExceptRangeForPc(
+    const unsigned char *pc,	/* The program counter value for which to
+				 * search for a closest enclosing exception
+				 * range. This points to a bytecode
+				 * instruction in codePtr's code. */
+    int searchMode,		/* If TCL_BREAK, consider either loop or catch
+				 * ExceptionRanges in search. If TCL_ERROR
+				 * consider only catch ranges (and ignore any
+				 * closer loop ranges). If TCL_CONTINUE, look
+				 * for loop ranges that define a continue
+				 * point or a catch range. */
+    ByteCode *codePtr)		/* Points to the ByteCode in which to search
+				 * for the enclosing ExceptionRange. */
+{
+    ExceptionRange *rangeArrayPtr;
+    int numRanges = codePtr->numExceptRanges;
+    register ExceptionRange *rangePtr;
+    int pcOffset = pc - codePtr->codeStart;
+    register int start;
+
+    if (numRanges == 0) {
+	return NULL;
+    }
+
+    /*
+     * This exploits peculiarities of our compiler: nested ranges are always
+     * *after* their containing ranges, so that by scanning backwards we are
+     * sure that the first matching range is indeed the deepest.
+     */
+
+    rangeArrayPtr = codePtr->exceptArrayPtr;
+    rangePtr = rangeArrayPtr + numRanges;
+    while (--rangePtr >= rangeArrayPtr) {
+	start = rangePtr->codeOffset;
+	if ((start <= pcOffset) &&
+		(pcOffset < (start + rangePtr->numCodeBytes))) {
+	    if (rangePtr->type == CATCH_EXCEPTION_RANGE) {
+		return rangePtr;
+	    }
+	    if (searchMode == TCL_BREAK) {
+		return rangePtr;
+	    }
+	    if (searchMode == TCL_CONTINUE && rangePtr->continueOffset != -1){
+		return rangePtr;
+	    }
+	}
+    }
+    return NULL;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * GetOpcodeName --
+ *
+ *	This procedure is called by the TRACE and TRACE_WITH_OBJ macros used
+ *	in TclNRExecuteByteCode when debugging. It returns the name of the
+ *	bytecode instruction at a specified instruction pc.
+ *
+ * Results:
+ *	A character string for the instruction.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+#ifdef TCL_COMPILE_DEBUG
+static const char *
+GetOpcodeName(
+    const unsigned char *pc)	/* Points to the instruction whose name should
+				 * be returned. */
+{
+    unsigned char opCode = *pc;
+
+    return tclInstructionTable[opCode].name;
+}
+#endif /* TCL_COMPILE_DEBUG */
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclExprFloatError --
+ *
+ *	This procedure is called when an error occurs during a floating-point
+ *	operation. It reads errno and sets interp->objResultPtr accordingly.
+ *
+ * Results:
+ *	interp->objResultPtr is set to hold an error message.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclExprFloatError(
+    Tcl_Interp *interp,		/* Where to store error message. */
+    double value)		/* Value returned after error; used to
+				 * distinguish underflows from overflows. */
+{
+    const char *s;
+
+    if ((errno == EDOM) || TclIsNaN(value)) {
+	s = "domain error: argument not in valid range";
+	Tcl_SetObjResult(interp, Tcl_NewStringObj(s, -1));
+	Tcl_SetErrorCode(interp, "ARITH", "DOMAIN", s, NULL);
+    } else if ((errno == ERANGE) || TclIsInfinite(value)) {
+	if (value == 0.0) {
+	    s = "floating-point value too small to represent";
+	    Tcl_SetObjResult(interp, Tcl_NewStringObj(s, -1));
+	    Tcl_SetErrorCode(interp, "ARITH", "UNDERFLOW", s, NULL);
+	} else {
+	    s = "floating-point value too large to represent";
+	    Tcl_SetObjResult(interp, Tcl_NewStringObj(s, -1));
+	    Tcl_SetErrorCode(interp, "ARITH", "OVERFLOW", s, NULL);
+	}
+    } else {
+	Tcl_Obj *objPtr = Tcl_ObjPrintf(
+		"unknown floating-point error, errno = %d", errno);
+
+	Tcl_SetErrorCode(interp, "ARITH", "UNKNOWN",
+		Tcl_GetString(objPtr), NULL);
+	Tcl_SetObjResult(interp, objPtr);
+    }
+}
+
+#ifdef TCL_COMPILE_STATS
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclLog2 --
+ *
+ *	Procedure used while collecting compilation statistics to determine
+ *	the log base 2 of an integer.
+ *
+ * Results:
+ *	Returns the log base 2 of the operand. If the argument is less than or
+ *	equal to zero, a zero is returned.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclLog2(
+    register int value)		/* The integer for which to compute the log
+				 * base 2. */
+{
+    register int n = value;
+    register int result = 0;
+
+    while (n > 1) {
+	n = n >> 1;
+	result++;
+    }
+    return result;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * EvalStatsCmd --
+ *
+ *	Implements the "evalstats" command that prints instruction execution
+ *	counts to stdout.
+ *
+ * Results:
+ *	Standard Tcl results.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+EvalStatsCmd(
+    ClientData unused,		/* Unused. */
+    Tcl_Interp *interp,		/* The current interpreter. */
+    int objc,			/* The number of arguments. */
+    Tcl_Obj *const objv[])	/* The argument strings. */
+{
+    Interp *iPtr = (Interp *) interp;
+    LiteralTable *globalTablePtr = &iPtr->literalTable;
+    ByteCodeStats *statsPtr = &iPtr->stats;
+    double totalCodeBytes, currentCodeBytes;
+    double totalLiteralBytes, currentLiteralBytes;
+    double objBytesIfUnshared, strBytesIfUnshared, sharingBytesSaved;
+    double strBytesSharedMultX, strBytesSharedOnce;
+    double numInstructions, currentHeaderBytes;
+    long numCurrentByteCodes, numByteCodeLits;
+    long refCountSum, literalMgmtBytes, sum;
+    int numSharedMultX, numSharedOnce;
+    int decadeHigh, minSizeDecade, maxSizeDecade, length, i;
+    char *litTableStats;
+    LiteralEntry *entryPtr;
+    Tcl_Obj *objPtr;
+
+#define Percent(a,b) ((a) * 100.0 / (b))
+
+    objPtr = Tcl_NewObj();
+    Tcl_IncrRefCount(objPtr);
+
+    numInstructions = 0.0;
+    for (i = 0;  i < 256;  i++) {
+	if (statsPtr->instructionCount[i] != 0) {
+	    numInstructions += statsPtr->instructionCount[i];
+	}
+    }
+
+    totalLiteralBytes = sizeof(LiteralTable)
+	    + iPtr->literalTable.numBuckets * sizeof(LiteralEntry *)
+	    + (statsPtr->numLiteralsCreated * sizeof(LiteralEntry))
+	    + (statsPtr->numLiteralsCreated * sizeof(Tcl_Obj))
+	    + statsPtr->totalLitStringBytes;
+    totalCodeBytes = statsPtr->totalByteCodeBytes + totalLiteralBytes;
+
+    numCurrentByteCodes =
+	    statsPtr->numCompilations - statsPtr->numByteCodesFreed;
+    currentHeaderBytes = numCurrentByteCodes
+	    * (sizeof(ByteCode) - sizeof(size_t) - sizeof(Tcl_Time));
+    literalMgmtBytes = sizeof(LiteralTable)
+	    + (iPtr->literalTable.numBuckets * sizeof(LiteralEntry *))
+	    + (iPtr->literalTable.numEntries * sizeof(LiteralEntry));
+    currentLiteralBytes = literalMgmtBytes
+	    + iPtr->literalTable.numEntries * sizeof(Tcl_Obj)
+	    + statsPtr->currentLitStringBytes;
+    currentCodeBytes = statsPtr->currentByteCodeBytes + currentLiteralBytes;
+
+    /*
+     * Summary statistics, total and current source and ByteCode sizes.
+     */
+
+    Tcl_AppendPrintfToObj(objPtr, "\n----------------------------------------------------------------\n");
+    Tcl_AppendPrintfToObj(objPtr,
+	    "Compilation and execution statistics for interpreter %#lx\n",
+	    (long int)iPtr);
+
+    Tcl_AppendPrintfToObj(objPtr, "\nNumber ByteCodes executed\t%ld\n",
+	    statsPtr->numExecutions);
+    Tcl_AppendPrintfToObj(objPtr, "Number ByteCodes compiled\t%ld\n",
+	    statsPtr->numCompilations);
+    Tcl_AppendPrintfToObj(objPtr, "  Mean executions/compile\t%.1f\n",
+	    statsPtr->numExecutions / (float)statsPtr->numCompilations);
+
+    Tcl_AppendPrintfToObj(objPtr, "\nInstructions executed\t\t%.0f\n",
+	    numInstructions);
+    Tcl_AppendPrintfToObj(objPtr, "  Mean inst/compile\t\t%.0f\n",
+	    numInstructions / statsPtr->numCompilations);
+    Tcl_AppendPrintfToObj(objPtr, "  Mean inst/execution\t\t%.0f\n",
+	    numInstructions / statsPtr->numExecutions);
+
+    Tcl_AppendPrintfToObj(objPtr, "\nTotal ByteCodes\t\t\t%ld\n",
+	    statsPtr->numCompilations);
+    Tcl_AppendPrintfToObj(objPtr, "  Source bytes\t\t\t%.6g\n",
+	    statsPtr->totalSrcBytes);
+    Tcl_AppendPrintfToObj(objPtr, "  Code bytes\t\t\t%.6g\n",
+	    totalCodeBytes);
+    Tcl_AppendPrintfToObj(objPtr, "    ByteCode bytes\t\t%.6g\n",
+	    statsPtr->totalByteCodeBytes);
+    Tcl_AppendPrintfToObj(objPtr, "    Literal bytes\t\t%.6g\n",
+	    totalLiteralBytes);
+    Tcl_AppendPrintfToObj(objPtr, "      table %lu + bkts %lu + entries %lu + objects %lu + strings %.6g\n",
+	    (unsigned long) sizeof(LiteralTable),
+	    (unsigned long) (iPtr->literalTable.numBuckets * sizeof(LiteralEntry *)),
+	    (unsigned long) (statsPtr->numLiteralsCreated * sizeof(LiteralEntry)),
+	    (unsigned long) (statsPtr->numLiteralsCreated * sizeof(Tcl_Obj)),
+	    statsPtr->totalLitStringBytes);
+    Tcl_AppendPrintfToObj(objPtr, "  Mean code/compile\t\t%.1f\n",
+	    totalCodeBytes / statsPtr->numCompilations);
+    Tcl_AppendPrintfToObj(objPtr, "  Mean code/source\t\t%.1f\n",
+	    totalCodeBytes / statsPtr->totalSrcBytes);
+
+    Tcl_AppendPrintfToObj(objPtr, "\nCurrent (active) ByteCodes\t%ld\n",
+	    numCurrentByteCodes);
+    Tcl_AppendPrintfToObj(objPtr, "  Source bytes\t\t\t%.6g\n",
+	    statsPtr->currentSrcBytes);
+    Tcl_AppendPrintfToObj(objPtr, "  Code bytes\t\t\t%.6g\n",
+	    currentCodeBytes);
+    Tcl_AppendPrintfToObj(objPtr, "    ByteCode bytes\t\t%.6g\n",
+	    statsPtr->currentByteCodeBytes);
+    Tcl_AppendPrintfToObj(objPtr, "    Literal bytes\t\t%.6g\n",
+	    currentLiteralBytes);
+    Tcl_AppendPrintfToObj(objPtr, "      table %lu + bkts %lu + entries %lu + objects %lu + strings %.6g\n",
+	    (unsigned long) sizeof(LiteralTable),
+	    (unsigned long) (iPtr->literalTable.numBuckets * sizeof(LiteralEntry *)),
+	    (unsigned long) (iPtr->literalTable.numEntries * sizeof(LiteralEntry)),
+	    (unsigned long) (iPtr->literalTable.numEntries * sizeof(Tcl_Obj)),
+	    statsPtr->currentLitStringBytes);
+    Tcl_AppendPrintfToObj(objPtr, "  Mean code/source\t\t%.1f\n",
+	    currentCodeBytes / statsPtr->currentSrcBytes);
+    Tcl_AppendPrintfToObj(objPtr, "  Code + source bytes\t\t%.6g (%0.1f mean code/src)\n",
+	    (currentCodeBytes + statsPtr->currentSrcBytes),
+	    (currentCodeBytes / statsPtr->currentSrcBytes) + 1.0);
+
+    /*
+     * Tcl_IsShared statistics check
+     *
+     * This gives the refcount of each obj as Tcl_IsShared was called for it.
+     * Shared objects must be duplicated before they can be modified.
+     */
+
+    numSharedMultX = 0;
+    Tcl_AppendPrintfToObj(objPtr, "\nTcl_IsShared object check (all objects):\n");
+    Tcl_AppendPrintfToObj(objPtr, "  Object had refcount <=1 (not shared)\t%ld\n",
+	    tclObjsShared[1]);
+    for (i = 2;  i < TCL_MAX_SHARED_OBJ_STATS;  i++) {
+	Tcl_AppendPrintfToObj(objPtr, "  refcount ==%d\t\t%ld\n",
+		i, tclObjsShared[i]);
+	numSharedMultX += tclObjsShared[i];
+    }
+    Tcl_AppendPrintfToObj(objPtr, "  refcount >=%d\t\t%ld\n",
+	    i, tclObjsShared[0]);
+    numSharedMultX += tclObjsShared[0];
+    Tcl_AppendPrintfToObj(objPtr, "  Total shared objects\t\t\t%d\n",
+	    numSharedMultX);
+
+    /*
+     * Literal table statistics.
+     */
+
+    numByteCodeLits = 0;
+    refCountSum = 0;
+    numSharedMultX = 0;
+    numSharedOnce = 0;
+    objBytesIfUnshared = 0.0;
+    strBytesIfUnshared = 0.0;
+    strBytesSharedMultX = 0.0;
+    strBytesSharedOnce = 0.0;
+    for (i = 0;  i < globalTablePtr->numBuckets;  i++) {
+	for (entryPtr = globalTablePtr->buckets[i];  entryPtr != NULL;
+		entryPtr = entryPtr->nextPtr) {
+	    if (entryPtr->objPtr->typePtr == &tclByteCodeType) {
+		numByteCodeLits++;
+	    }
+	    (void) Tcl_GetStringFromObj(entryPtr->objPtr, &length);
+	    refCountSum += entryPtr->refCount;
+	    objBytesIfUnshared += (entryPtr->refCount * sizeof(Tcl_Obj));
+	    strBytesIfUnshared += (entryPtr->refCount * (length+1));
+	    if (entryPtr->refCount > 1) {
+		numSharedMultX++;
+		strBytesSharedMultX += (length+1);
+	    } else {
+		numSharedOnce++;
+		strBytesSharedOnce += (length+1);
+	    }
+	}
+    }
+    sharingBytesSaved = (objBytesIfUnshared + strBytesIfUnshared)
+	    - currentLiteralBytes;
+
+    Tcl_AppendPrintfToObj(objPtr, "\nTotal objects (all interps)\t%ld\n",
+	    tclObjsAlloced);
+    Tcl_AppendPrintfToObj(objPtr, "Current objects\t\t\t%ld\n",
+	    (tclObjsAlloced - tclObjsFreed));
+    Tcl_AppendPrintfToObj(objPtr, "Total literal objects\t\t%ld\n",
+	    statsPtr->numLiteralsCreated);
+
+    Tcl_AppendPrintfToObj(objPtr, "\nCurrent literal objects\t\t%d (%0.1f%% of current objects)\n",
+	    globalTablePtr->numEntries,
+	    Percent(globalTablePtr->numEntries, tclObjsAlloced-tclObjsFreed));
+    Tcl_AppendPrintfToObj(objPtr, "  ByteCode literals\t\t%ld (%0.1f%% of current literals)\n",
+	    numByteCodeLits,
+	    Percent(numByteCodeLits, globalTablePtr->numEntries));
+    Tcl_AppendPrintfToObj(objPtr, "  Literals reused > 1x\t\t%d\n",
+	    numSharedMultX);
+    Tcl_AppendPrintfToObj(objPtr, "  Mean reference count\t\t%.2f\n",
+	    ((double) refCountSum) / globalTablePtr->numEntries);
+    Tcl_AppendPrintfToObj(objPtr, "  Mean len, str reused >1x \t%.2f\n",
+	    (numSharedMultX ? strBytesSharedMultX/numSharedMultX : 0.0));
+    Tcl_AppendPrintfToObj(objPtr, "  Mean len, str used 1x\t\t%.2f\n",
+	    (numSharedOnce ? strBytesSharedOnce/numSharedOnce : 0.0));
+    Tcl_AppendPrintfToObj(objPtr, "  Total sharing savings\t\t%.6g (%0.1f%% of bytes if no sharing)\n",
+	    sharingBytesSaved,
+	    Percent(sharingBytesSaved, objBytesIfUnshared+strBytesIfUnshared));
+    Tcl_AppendPrintfToObj(objPtr, "    Bytes with sharing\t\t%.6g\n",
+	    currentLiteralBytes);
+    Tcl_AppendPrintfToObj(objPtr, "      table %lu + bkts %lu + entries %lu + objects %lu + strings %.6g\n",
+	    (unsigned long) sizeof(LiteralTable),
+	    (unsigned long) (iPtr->literalTable.numBuckets * sizeof(LiteralEntry *)),
+	    (unsigned long) (iPtr->literalTable.numEntries * sizeof(LiteralEntry)),
+	    (unsigned long) (iPtr->literalTable.numEntries * sizeof(Tcl_Obj)),
+	    statsPtr->currentLitStringBytes);
+    Tcl_AppendPrintfToObj(objPtr, "    Bytes if no sharing\t\t%.6g = objects %.6g + strings %.6g\n",
+	    (objBytesIfUnshared + strBytesIfUnshared),
+	    objBytesIfUnshared, strBytesIfUnshared);
+    Tcl_AppendPrintfToObj(objPtr, "  String sharing savings \t%.6g = unshared %.6g - shared %.6g\n",
+	    (strBytesIfUnshared - statsPtr->currentLitStringBytes),
+	    strBytesIfUnshared, statsPtr->currentLitStringBytes);
+    Tcl_AppendPrintfToObj(objPtr, "  Literal mgmt overhead\t\t%ld (%0.1f%% of bytes with sharing)\n",
+	    literalMgmtBytes,
+	    Percent(literalMgmtBytes, currentLiteralBytes));
+    Tcl_AppendPrintfToObj(objPtr, "    table %lu + buckets %lu + entries %lu\n",
+	    (unsigned long) sizeof(LiteralTable),
+	    (unsigned long) (iPtr->literalTable.numBuckets * sizeof(LiteralEntry *)),
+	    (unsigned long) (iPtr->literalTable.numEntries * sizeof(LiteralEntry)));
+
+    /*
+     * Breakdown of current ByteCode space requirements.
+     */
+
+    Tcl_AppendPrintfToObj(objPtr, "\nBreakdown of current ByteCode requirements:\n");
+    Tcl_AppendPrintfToObj(objPtr, "                         Bytes      Pct of    Avg per\n");
+    Tcl_AppendPrintfToObj(objPtr, "                                     total    ByteCode\n");
+    Tcl_AppendPrintfToObj(objPtr, "Total             %12.6g     100.00%%   %8.1f\n",
+	    statsPtr->currentByteCodeBytes,
+	    statsPtr->currentByteCodeBytes / numCurrentByteCodes);
+    Tcl_AppendPrintfToObj(objPtr, "Header            %12.6g   %8.1f%%   %8.1f\n",
+	    currentHeaderBytes,
+	    Percent(currentHeaderBytes, statsPtr->currentByteCodeBytes),
+	    currentHeaderBytes / numCurrentByteCodes);
+    Tcl_AppendPrintfToObj(objPtr, "Instructions      %12.6g   %8.1f%%   %8.1f\n",
+	    statsPtr->currentInstBytes,
+	    Percent(statsPtr->currentInstBytes,statsPtr->currentByteCodeBytes),
+	    statsPtr->currentInstBytes / numCurrentByteCodes);
+    Tcl_AppendPrintfToObj(objPtr, "Literal ptr array %12.6g   %8.1f%%   %8.1f\n",
+	    statsPtr->currentLitBytes,
+	    Percent(statsPtr->currentLitBytes,statsPtr->currentByteCodeBytes),
+	    statsPtr->currentLitBytes / numCurrentByteCodes);
+    Tcl_AppendPrintfToObj(objPtr, "Exception table   %12.6g   %8.1f%%   %8.1f\n",
+	    statsPtr->currentExceptBytes,
+	    Percent(statsPtr->currentExceptBytes,statsPtr->currentByteCodeBytes),
+	    statsPtr->currentExceptBytes / numCurrentByteCodes);
+    Tcl_AppendPrintfToObj(objPtr, "Auxiliary data    %12.6g   %8.1f%%   %8.1f\n",
+	    statsPtr->currentAuxBytes,
+	    Percent(statsPtr->currentAuxBytes,statsPtr->currentByteCodeBytes),
+	    statsPtr->currentAuxBytes / numCurrentByteCodes);
+    Tcl_AppendPrintfToObj(objPtr, "Command map       %12.6g   %8.1f%%   %8.1f\n",
+	    statsPtr->currentCmdMapBytes,
+	    Percent(statsPtr->currentCmdMapBytes,statsPtr->currentByteCodeBytes),
+	    statsPtr->currentCmdMapBytes / numCurrentByteCodes);
+
+    /*
+     * Detailed literal statistics.
+     */
+
+    Tcl_AppendPrintfToObj(objPtr, "\nLiteral string sizes:\n");
+    Tcl_AppendPrintfToObj(objPtr, "\t Up to length\t\tPercentage\n");
+    maxSizeDecade = 0;
+    for (i = 31;  i >= 0;  i--) {
+	if (statsPtr->literalCount[i] > 0) {
+	    maxSizeDecade = i;
+	    break;
+	}
+    }
+    sum = 0;
+    for (i = 0;  i <= maxSizeDecade;  i++) {
+	decadeHigh = (1 << (i+1)) - 1;
+	sum += statsPtr->literalCount[i];
+	Tcl_AppendPrintfToObj(objPtr, "\t%10d\t\t%8.0f%%\n",
+		decadeHigh, Percent(sum, statsPtr->numLiteralsCreated));
+    }
+
+    litTableStats = TclLiteralStats(globalTablePtr);
+    Tcl_AppendPrintfToObj(objPtr, "\nCurrent literal table statistics:\n%s\n",
+	    litTableStats);
+    ckfree(litTableStats);
+
+    /*
+     * Source and ByteCode size distributions.
+     */
+
+    Tcl_AppendPrintfToObj(objPtr, "\nSource sizes:\n");
+    Tcl_AppendPrintfToObj(objPtr, "\t Up to size\t\tPercentage\n");
+    minSizeDecade = maxSizeDecade = 0;
+    for (i = 0;  i < 31;  i++) {
+	if (statsPtr->srcCount[i] > 0) {
+	    minSizeDecade = i;
+	    break;
+	}
+    }
+    for (i = 31;  i >= 0;  i--) {
+	if (statsPtr->srcCount[i] > 0) {
+	    maxSizeDecade = i;
+	    break;
+	}
+    }
+    sum = 0;
+    for (i = minSizeDecade;  i <= maxSizeDecade;  i++) {
+	decadeHigh = (1 << (i+1)) - 1;
+	sum += statsPtr->srcCount[i];
+	Tcl_AppendPrintfToObj(objPtr, "\t%10d\t\t%8.0f%%\n",
+		decadeHigh, Percent(sum, statsPtr->numCompilations));
+    }
+
+    Tcl_AppendPrintfToObj(objPtr, "\nByteCode sizes:\n");
+    Tcl_AppendPrintfToObj(objPtr, "\t Up to size\t\tPercentage\n");
+    minSizeDecade = maxSizeDecade = 0;
+    for (i = 0;  i < 31;  i++) {
+	if (statsPtr->byteCodeCount[i] > 0) {
+	    minSizeDecade = i;
+	    break;
+	}
+    }
+    for (i = 31;  i >= 0;  i--) {
+	if (statsPtr->byteCodeCount[i] > 0) {
+	    maxSizeDecade = i;
+	    break;
+	}
+    }
+    sum = 0;
+    for (i = minSizeDecade;  i <= maxSizeDecade;  i++) {
+	decadeHigh = (1 << (i+1)) - 1;
+	sum += statsPtr->byteCodeCount[i];
+	Tcl_AppendPrintfToObj(objPtr, "\t%10d\t\t%8.0f%%\n",
+		decadeHigh, Percent(sum, statsPtr->numCompilations));
+    }
+
+    Tcl_AppendPrintfToObj(objPtr, "\nByteCode longevity (excludes Current ByteCodes):\n");
+    Tcl_AppendPrintfToObj(objPtr, "\t       Up to ms\t\tPercentage\n");
+    minSizeDecade = maxSizeDecade = 0;
+    for (i = 0;  i < 31;  i++) {
+	if (statsPtr->lifetimeCount[i] > 0) {
+	    minSizeDecade = i;
+	    break;
+	}
+    }
+    for (i = 31;  i >= 0;  i--) {
+	if (statsPtr->lifetimeCount[i] > 0) {
+	    maxSizeDecade = i;
+	    break;
+	}
+    }
+    sum = 0;
+    for (i = minSizeDecade;  i <= maxSizeDecade;  i++) {
+	decadeHigh = (1 << (i+1)) - 1;
+	sum += statsPtr->lifetimeCount[i];
+	Tcl_AppendPrintfToObj(objPtr, "\t%12.3f\t\t%8.0f%%\n",
+		decadeHigh/1000.0, Percent(sum, statsPtr->numByteCodesFreed));
+    }
+
+    /*
+     * Instruction counts.
+     */
+
+    Tcl_AppendPrintfToObj(objPtr, "\nInstruction counts:\n");
+    for (i = 0;  i <= LAST_INST_OPCODE;  i++) {
+	Tcl_AppendPrintfToObj(objPtr, "%20s %8ld ",
+		tclInstructionTable[i].name, statsPtr->instructionCount[i]);
+	if (statsPtr->instructionCount[i]) {
+	    Tcl_AppendPrintfToObj(objPtr, "%6.1f%%\n",
+		    Percent(statsPtr->instructionCount[i], numInstructions));
+	} else {
+	    Tcl_AppendPrintfToObj(objPtr, "0\n");
+	}
+    }
+
+#ifdef TCL_MEM_DEBUG
+    Tcl_AppendPrintfToObj(objPtr, "\nHeap Statistics:\n");
+    TclDumpMemoryInfo((ClientData) objPtr, 1);
+#endif
+    Tcl_AppendPrintfToObj(objPtr, "\n----------------------------------------------------------------\n");
+
+    if (objc == 1) {
+	Tcl_SetObjResult(interp, objPtr);
+    } else {
+	Tcl_Channel outChan;
+	char *str = Tcl_GetStringFromObj(objv[1], &length);
+
+	if (length) {
+	    if (strcmp(str, "stdout") == 0) {
+		outChan = Tcl_GetStdChannel(TCL_STDOUT);
+	    } else if (strcmp(str, "stderr") == 0) {
+		outChan = Tcl_GetStdChannel(TCL_STDERR);
+	    } else {
+		outChan = Tcl_OpenFileChannel(NULL, str, "w", 0664);
+	    }
+	} else {
+	    outChan = Tcl_GetStdChannel(TCL_STDOUT);
+	}
+	if (outChan != NULL) {
+	    Tcl_WriteObj(outChan, objPtr);
+	}
+    }
+    Tcl_DecrRefCount(objPtr);
+    return TCL_OK;
+}
+#endif /* TCL_COMPILE_STATS */
+
+#ifdef TCL_COMPILE_DEBUG
+/*
+ *----------------------------------------------------------------------
+ *
+ * StringForResultCode --
+ *
+ *	Procedure that returns a human-readable string representing a Tcl
+ *	result code such as TCL_ERROR.
+ *
+ * Results:
+ *	If the result code is one of the standard Tcl return codes, the result
+ *	is a string representing that code such as "TCL_ERROR". Otherwise, the
+ *	result string is that code formatted as a sequence of decimal digit
+ *	characters. Note that the resulting string must not be modified by the
+ *	caller.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static const char *
+StringForResultCode(
+    int result)			/* The Tcl result code for which to generate a
+				 * string. */
+{
+    static char buf[TCL_INTEGER_SPACE];
+
+    if ((result >= TCL_OK) && (result <= TCL_CONTINUE)) {
+	return resultStrings[result];
+    }
+    TclFormatInt(buf, result);
+    return buf;
+}
+#endif /* TCL_COMPILE_DEBUG */
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tclFCmd.c b/generic/tclFCmd.c
new file mode 100644
index 0000000..bb814ea
--- /dev/null
+++ b/generic/tclFCmd.c
@@ -0,0 +1,1513 @@
+/*
+ * tclFCmd.c
+ *
+ *	This file implements the generic portion of file manipulation
+ *	subcommands of the "file" command.
+ *
+ * Copyright (c) 1996-1998 Sun Microsystems, Inc.
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#include "tclInt.h"
+#include "tclFileSystem.h"
+
+/*
+ * Declarations for local functions defined in this file:
+ */
+
+static int		CopyRenameOneFile(Tcl_Interp *interp,
+			    Tcl_Obj *srcPathPtr, Tcl_Obj *destPathPtr,
+			    int copyFlag, int force);
+static Tcl_Obj *	FileBasename(Tcl_Interp *interp, Tcl_Obj *pathPtr);
+static int		FileCopyRename(Tcl_Interp *interp,
+			    int objc, Tcl_Obj *const objv[], int copyFlag);
+static int		FileForceOption(Tcl_Interp *interp,
+			    int objc, Tcl_Obj *const objv[], int *forcePtr);
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * TclFileRenameCmd
+ *
+ *	This function implements the "rename" subcommand of the "file"
+ *	command. Filename arguments need to be translated to native format
+ *	before being passed to platform-specific code that implements rename
+ *	functionality.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+int
+TclFileRenameCmd(
+    ClientData clientData,	/* Unused */
+    Tcl_Interp *interp,		/* Interp for error reporting or recursive
+				 * calls in the case of a tricky rename. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument strings passed to Tcl_FileCmd. */
+{
+    return FileCopyRename(interp, objc, objv, 0);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * TclFileCopyCmd
+ *
+ *	This function implements the "copy" subcommand of the "file" command.
+ *	Filename arguments need to be translated to native format before being
+ *	passed to platform-specific code that implements copy functionality.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+int
+TclFileCopyCmd(
+    ClientData clientData,	/* Unused */
+    Tcl_Interp *interp,		/* Used for error reporting or recursive calls
+				 * in the case of a tricky copy. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument strings passed to Tcl_FileCmd. */
+{
+    return FileCopyRename(interp, objc, objv, 1);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * FileCopyRename --
+ *
+ *	Performs the work of TclFileRenameCmd and TclFileCopyCmd. See
+ *	comments for those functions.
+ *
+ * Results:
+ *	See above.
+ *
+ * Side effects:
+ *	See above.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+static int
+FileCopyRename(
+    Tcl_Interp *interp,		/* Used for error reporting. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[],	/* Argument strings passed to Tcl_FileCmd. */
+    int copyFlag)		/* If non-zero, copy source(s). Otherwise,
+				 * rename them. */
+{
+    int i, result, force;
+    Tcl_StatBuf statBuf;
+    Tcl_Obj *target;
+
+    i = FileForceOption(interp, objc - 1, objv + 1, &force);
+    if (i < 0) {
+	return TCL_ERROR;
+    }
+    i++;
+    if ((objc - i) < 2) {
+	Tcl_WrongNumArgs(interp, 1, objv,
+		"?-option value ...? source ?source ...? target");
+	return TCL_ERROR;
+    }
+
+    /*
+     * If target doesn't exist or isn't a directory, try the copy/rename. More
+     * than 2 arguments is only valid if the target is an existing directory.
+     */
+
+    target = objv[objc - 1];
+    if (Tcl_FSConvertToPathType(interp, target) != TCL_OK) {
+	return TCL_ERROR;
+    }
+
+    result = TCL_OK;
+
+    /*
+     * Call Tcl_FSStat() so that if target is a symlink that points to a
+     * directory we will put the sources in that directory instead of
+     * overwriting the symlink.
+     */
+
+    if ((Tcl_FSStat(target, &statBuf) != 0) || !S_ISDIR(statBuf.st_mode)) {
+	if ((objc - i) > 2) {
+	    errno = ENOTDIR;
+	    Tcl_PosixError(interp);
+	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		    "error %s: target \"%s\" is not a directory",
+		    (copyFlag?"copying":"renaming"), TclGetString(target)));
+	    result = TCL_ERROR;
+	} else {
+	    /*
+	     * Even though already have target == translated(objv[i+1]), pass
+	     * the original argument down, so if there's an error, the error
+	     * message will reflect the original arguments.
+	     */
+
+	    result = CopyRenameOneFile(interp, objv[i], objv[i + 1], copyFlag,
+		    force);
+	}
+	return result;
+    }
+
+    /*
+     * Move each source file into target directory. Extract the basename from
+     * each source, and append it to the end of the target path.
+     */
+
+    for ( ; i<objc-1 ; i++) {
+	Tcl_Obj *jargv[2];
+	Tcl_Obj *source, *newFileName;
+
+	source = FileBasename(interp, objv[i]);
+	if (source == NULL) {
+	    result = TCL_ERROR;
+	    break;
+	}
+	jargv[0] = objv[objc - 1];
+	jargv[1] = source;
+	newFileName = TclJoinPath(2, jargv);
+	Tcl_IncrRefCount(newFileName);
+	result = CopyRenameOneFile(interp, objv[i], newFileName, copyFlag,
+		force);
+	Tcl_DecrRefCount(newFileName);
+	Tcl_DecrRefCount(source);
+
+	if (result == TCL_ERROR) {
+	    break;
+	}
+    }
+    return result;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * TclFileMakeDirsCmd
+ *
+ *	This function implements the "mkdir" subcommand of the "file" command.
+ *	Filename arguments need to be translated to native format before being
+ *	passed to platform-specific code that implements mkdir functionality.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclFileMakeDirsCmd(
+    ClientData clientData,	/* Unused */
+    Tcl_Interp *interp,		/* Used for error reporting. */
+    int objc,			/* Number of arguments */
+    Tcl_Obj *const objv[])	/* Argument strings passed to Tcl_FileCmd. */
+{
+    Tcl_Obj *errfile = NULL;
+    int result, i, j, pobjc;
+    Tcl_Obj *split = NULL;
+    Tcl_Obj *target = NULL;
+    Tcl_StatBuf statBuf;
+
+    result = TCL_OK;
+    for (i = 1; i < objc; i++) {
+	if (Tcl_FSConvertToPathType(interp, objv[i]) != TCL_OK) {
+	    result = TCL_ERROR;
+	    break;
+	}
+
+	split = Tcl_FSSplitPath(objv[i], &pobjc);
+	Tcl_IncrRefCount(split);
+	if (pobjc == 0) {
+	    errno = ENOENT;
+	    errfile = objv[i];
+	    break;
+	}
+	for (j = 0; j < pobjc; j++) {
+	    target = Tcl_FSJoinPath(split, j + 1);
+	    Tcl_IncrRefCount(target);
+
+	    /*
+	     * Call Tcl_FSStat() so that if target is a symlink that points to
+	     * a directory we will create subdirectories in that directory.
+	     */
+
+	    if (Tcl_FSStat(target, &statBuf) == 0) {
+		if (!S_ISDIR(statBuf.st_mode)) {
+		    errno = EEXIST;
+		    errfile = target;
+		    goto done;
+		}
+	    } else if (errno != ENOENT) {
+		/*
+		 * If Tcl_FSStat() failed and the error is anything other than
+		 * non-existence of the target, throw the error.
+		 */
+
+		errfile = target;
+		goto done;
+	    } else if (Tcl_FSCreateDirectory(target) != TCL_OK) {
+		/*
+		 * Create might have failed because of being in a race
+		 * condition with another process trying to create the same
+		 * subdirectory.
+		 */
+
+		if (errno != EEXIST) {
+		    errfile = target;
+		    goto done;
+		} else if ((Tcl_FSStat(target, &statBuf) == 0)
+			&& S_ISDIR(statBuf.st_mode)) {
+		    /*
+		     * It is a directory that wasn't there before, so keep
+		     * going without error.
+		     */
+
+		    Tcl_ResetResult(interp);
+		} else {
+		    errfile = target;
+		    goto done;
+		}
+	    }
+
+	    /*
+	     * Forget about this sub-path.
+	     */
+
+	    Tcl_DecrRefCount(target);
+	    target = NULL;
+	}
+	Tcl_DecrRefCount(split);
+	split = NULL;
+    }
+
+  done:
+    if (errfile != NULL) {
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		"can't create directory \"%s\": %s",
+		TclGetString(errfile), Tcl_PosixError(interp)));
+	result = TCL_ERROR;
+    }
+    if (split != NULL) {
+	Tcl_DecrRefCount(split);
+    }
+    if (target != NULL) {
+	Tcl_DecrRefCount(target);
+    }
+    return result;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclFileDeleteCmd
+ *
+ *	This function implements the "delete" subcommand of the "file"
+ *	command.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclFileDeleteCmd(
+    ClientData clientData,	/* Unused */
+    Tcl_Interp *interp,		/* Used for error reporting */
+    int objc,			/* Number of arguments */
+    Tcl_Obj *const objv[])	/* Argument strings passed to Tcl_FileCmd. */
+{
+    int i, force, result;
+    Tcl_Obj *errfile;
+    Tcl_Obj *errorBuffer = NULL;
+
+    i = FileForceOption(interp, objc - 1, objv + 1, &force);
+    if (i < 0) {
+	return TCL_ERROR;
+    }
+
+    errfile = NULL;
+    result = TCL_OK;
+
+    for (i++ ; i < objc; i++) {
+	Tcl_StatBuf statBuf;
+
+	errfile = objv[i];
+	if (Tcl_FSConvertToPathType(interp, objv[i]) != TCL_OK) {
+	    result = TCL_ERROR;
+	    goto done;
+	}
+
+	/*
+	 * Call lstat() to get info so can delete symbolic link itself.
+	 */
+
+	if (Tcl_FSLstat(objv[i], &statBuf) != 0) {
+	    /*
+	     * Trying to delete a file that does not exist is not considered
+	     * an error, just a no-op
+	     */
+
+	    if (errno != ENOENT) {
+		result = TCL_ERROR;
+	    }
+	} else if (S_ISDIR(statBuf.st_mode)) {
+	    /*
+	     * We own a reference count on errorBuffer, if it was set as a
+	     * result of this call.
+	     */
+
+	    result = Tcl_FSRemoveDirectory(objv[i], force, &errorBuffer);
+	    if (result != TCL_OK) {
+		if ((force == 0) && (errno == EEXIST)) {
+		    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+			    "error deleting \"%s\": directory not empty",
+			    TclGetString(objv[i])));
+		    Tcl_PosixError(interp);
+		    goto done;
+		}
+
+		/*
+		 * If possible, use the untranslated name for the file.
+		 */
+
+		errfile = errorBuffer;
+
+		/*
+		 * FS supposed to check between translated objv and errfile.
+		 */
+
+		if (Tcl_FSEqualPaths(objv[i], errfile)) {
+		    errfile = objv[i];
+		}
+	    }
+	} else {
+	    result = Tcl_FSDeleteFile(objv[i]);
+	}
+
+	if (result != TCL_OK) {
+	    result = TCL_ERROR;
+
+	    /*
+	     * It is important that we break on error, otherwise we might end
+	     * up owning reference counts on numerous errorBuffers.
+	     */
+
+	    break;
+	}
+    }
+    if (result != TCL_OK) {
+	if (errfile == NULL) {
+	    /*
+	     * We try to accomodate poor error results from our Tcl_FS calls.
+	     */
+
+	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		    "error deleting unknown file: %s",
+		    Tcl_PosixError(interp)));
+	} else {
+	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		    "error deleting \"%s\": %s",
+		    TclGetString(errfile), Tcl_PosixError(interp)));
+	}
+    }
+
+  done:
+    if (errorBuffer != NULL) {
+	Tcl_DecrRefCount(errorBuffer);
+    }
+    return result;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * CopyRenameOneFile
+ *
+ *	Copies or renames specified source file or directory hierarchy to the
+ *	specified target.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	Target is overwritten if the force flag is set. Attempting to
+ *	copy/rename a file onto a directory or a directory onto a file will
+ *	always result in an error.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+CopyRenameOneFile(
+    Tcl_Interp *interp,		/* Used for error reporting. */
+    Tcl_Obj *source,		/* Pathname of file to copy. May need to be
+				 * translated. */
+    Tcl_Obj *target,		/* Pathname of file to create/overwrite. May
+				 * need to be translated. */
+    int copyFlag,		/* If non-zero, copy files. Otherwise, rename
+				 * them. */
+    int force)			/* If non-zero, overwrite target file if it
+				 * exists. Otherwise, error if target already
+				 * exists. */
+{
+    int result;
+    Tcl_Obj *errfile, *errorBuffer;
+    Tcl_Obj *actualSource=NULL;	/* If source is a link, then this is the real
+				 * file/directory. */
+    Tcl_StatBuf sourceStatBuf, targetStatBuf;
+
+    if (Tcl_FSConvertToPathType(interp, source) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    if (Tcl_FSConvertToPathType(interp, target) != TCL_OK) {
+	return TCL_ERROR;
+    }
+
+    errfile = NULL;
+    errorBuffer = NULL;
+    result = TCL_ERROR;
+
+    /*
+     * We want to copy/rename links and not the files they point to, so we use
+     * lstat(). If target is a link, we also want to replace the link and not
+     * the file it points to, so we also use lstat() on the target.
+     */
+
+    if (Tcl_FSLstat(source, &sourceStatBuf) != 0) {
+	errfile = source;
+	goto done;
+    }
+    if (Tcl_FSLstat(target, &targetStatBuf) != 0) {
+	if (errno != ENOENT) {
+	    errfile = target;
+	    goto done;
+	}
+    } else {
+	if (force == 0) {
+	    errno = EEXIST;
+	    errfile = target;
+	    goto done;
+	}
+
+	/*
+	 * Prevent copying or renaming a file onto itself. On Windows since
+	 * 8.5 we do get an inode number, however the unsigned short field is
+	 * insufficient to accept the Win32 API file id so it is truncated to
+	 * 16 bits and we get collisions. See bug #2015723.
+	 */
+
+#if !defined(_WIN32) && !defined(__CYGWIN__)
+	if ((sourceStatBuf.st_ino != 0) && (targetStatBuf.st_ino != 0)) {
+	    if ((sourceStatBuf.st_ino == targetStatBuf.st_ino) &&
+		    (sourceStatBuf.st_dev == targetStatBuf.st_dev)) {
+		result = TCL_OK;
+		goto done;
+	    }
+	}
+#endif
+
+	/*
+	 * Prevent copying/renaming a file onto a directory and vice-versa.
+	 * This is a policy decision based on the fact that existing
+	 * implementations of copy and rename on all platforms also prevent
+	 * this.
+	 */
+
+	if (S_ISDIR(sourceStatBuf.st_mode)
+		&& !S_ISDIR(targetStatBuf.st_mode)) {
+	    errno = EISDIR;
+	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		    "can't overwrite file \"%s\" with directory \"%s\"",
+		    TclGetString(target), TclGetString(source)));
+	    goto done;
+	}
+	if (!S_ISDIR(sourceStatBuf.st_mode)
+		&& S_ISDIR(targetStatBuf.st_mode)) {
+	    errno = EISDIR;
+	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		    "can't overwrite directory \"%s\" with file \"%s\"",
+		    TclGetString(target), TclGetString(source)));
+	    goto done;
+	}
+
+	/*
+	 * The destination exists, but appears to be ok to over-write, and
+	 * -force is given. We now try to adjust permissions to ensure the
+	 * operation succeeds. If we can't adjust permissions, we'll let the
+	 * actual copy/rename return an error later.
+	 */
+
+	{
+	    Tcl_Obj *perm;
+	    int index;
+
+	    TclNewLiteralStringObj(perm, "u+w");
+	    Tcl_IncrRefCount(perm);
+	    if (TclFSFileAttrIndex(target, "-permissions", &index) == TCL_OK) {
+		Tcl_FSFileAttrsSet(NULL, index, target, perm);
+	    }
+	    Tcl_DecrRefCount(perm);
+	}
+    }
+
+    if (copyFlag == 0) {
+	result = Tcl_FSRenameFile(source, target);
+	if (result == TCL_OK) {
+	    goto done;
+	}
+
+	if (errno == EINVAL) {
+	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		    "error renaming \"%s\" to \"%s\": trying to rename a"
+		    " volume or move a directory into itself",
+		    TclGetString(source), TclGetString(target)));
+	    goto done;
+	} else if (errno != EXDEV) {
+	    errfile = target;
+	    goto done;
+	}
+
+	/*
+	 * The rename failed because the move was across file systems. Fall
+	 * through to copy file and then remove original. Note that the
+	 * low-level Tcl_FSRenameFileProc in the filesystem is allowed to
+	 * implement cross-filesystem moves itself, if it desires.
+	 */
+    }
+
+    actualSource = source;
+    Tcl_IncrRefCount(actualSource);
+
+    /*
+     * Activate the following block to copy files instead of links. However
+     * Tcl's semantics currently say we should copy links, so any such change
+     * should be the subject of careful study on the consequences.
+     *
+     * Perhaps there could be an optional flag to 'file copy' to dictate which
+     * approach to use, with the default being _not_ to have this block
+     * active.
+     */
+
+#if 0
+#ifdef S_ISLNK
+    if (copyFlag && S_ISLNK(sourceStatBuf.st_mode)) {
+	/*
+	 * We want to copy files not links. Therefore we must follow the link.
+	 * There are two purposes to this 'stat' call here. First we want to
+	 * know if the linked-file/dir actually exists, and second, in the
+	 * block of code which follows, some 20 lines down, we want to check
+	 * if the thing is a file or directory.
+	 */
+
+	if (Tcl_FSStat(source, &sourceStatBuf) != 0) {
+	    /*
+	     * Actual file doesn't exist.
+	     */
+
+	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		    "error copying \"%s\": the target of this link doesn't"
+		    " exist", TclGetString(source)));
+	    goto done;
+	} else {
+	    int counter = 0;
+
+	    while (1) {
+		Tcl_Obj *path = Tcl_FSLink(actualSource, NULL, 0);
+		if (path == NULL) {
+		    break;
+		}
+
+		/*
+		 * Now we want to check if this is a relative path, and if so,
+		 * to make it absolute.
+		 */
+
+		if (Tcl_FSGetPathType(path) == TCL_PATH_RELATIVE) {
+		    Tcl_Obj *abs = Tcl_FSJoinToPath(actualSource, 1, &path);
+
+		    if (abs == NULL) {
+			break;
+		    }
+		    Tcl_IncrRefCount(abs);
+		    Tcl_DecrRefCount(path);
+		    path = abs;
+		}
+		Tcl_DecrRefCount(actualSource);
+		actualSource = path;
+		counter++;
+
+		/*
+		 * Arbitrary limit of 20 links to follow.
+		 */
+
+		if (counter > 20) {
+		    /*
+		     * Too many links.
+		     */
+
+		    Tcl_SetErrno(EMLINK);
+		    errfile = source;
+		    goto done;
+		}
+	    }
+	    /* Now 'actualSource' is the correct file */
+	}
+    }
+#endif /* S_ISLNK */
+#endif
+
+    if (S_ISDIR(sourceStatBuf.st_mode)) {
+	result = Tcl_FSCopyDirectory(actualSource, target, &errorBuffer);
+	if (result != TCL_OK) {
+	    if (errno == EXDEV) {
+		/*
+		 * The copy failed because we're trying to do a
+		 * cross-filesystem copy. We do this through our Tcl library.
+		 */
+
+		Tcl_Obj *copyCommand, *cmdObj, *opObj;
+
+		TclNewObj(copyCommand);
+		TclNewLiteralStringObj(cmdObj, "::tcl::CopyDirectory");
+		Tcl_ListObjAppendElement(interp, copyCommand, cmdObj);
+		if (copyFlag) {
+		    TclNewLiteralStringObj(opObj, "copying");
+		} else {
+		    TclNewLiteralStringObj(opObj, "renaming");
+		}
+		Tcl_ListObjAppendElement(interp, copyCommand, opObj);
+		Tcl_ListObjAppendElement(interp, copyCommand, source);
+		Tcl_ListObjAppendElement(interp, copyCommand, target);
+		Tcl_IncrRefCount(copyCommand);
+		result = Tcl_EvalObjEx(interp, copyCommand,
+			TCL_EVAL_GLOBAL | TCL_EVAL_DIRECT);
+		Tcl_DecrRefCount(copyCommand);
+		if (result != TCL_OK) {
+		    /*
+		     * There was an error in the Tcl-level copy. We will pass
+		     * on the Tcl error message and can ensure this by setting
+		     * errfile to NULL
+		     */
+
+		    errfile = NULL;
+		}
+	    } else {
+		errfile = errorBuffer;
+		if (Tcl_FSEqualPaths(errfile, source)) {
+		    errfile = source;
+		} else if (Tcl_FSEqualPaths(errfile, target)) {
+		    errfile = target;
+		}
+	    }
+	}
+    } else {
+	result = Tcl_FSCopyFile(actualSource, target);
+	if ((result != TCL_OK) && (errno == EXDEV)) {
+	    result = TclCrossFilesystemCopy(interp, source, target);
+	}
+	if (result != TCL_OK) {
+	    /*
+	     * We could examine 'errno' to double-check if the problem was
+	     * with the target, but we checked the source above, so it should
+	     * be quite clear
+	     */
+
+	    errfile = target;
+	}
+	/*
+	 * We now need to reset the result, because the above call,
+	 * may have left set it.  (Ideally we would prefer not to pass
+	 * an interpreter in above, but the channel IO code used by
+	 * TclCrossFilesystemCopy currently requires one)
+	 */
+	Tcl_ResetResult(interp);
+    }
+    if ((copyFlag == 0) && (result == TCL_OK)) {
+	if (S_ISDIR(sourceStatBuf.st_mode)) {
+	    result = Tcl_FSRemoveDirectory(source, 1, &errorBuffer);
+	    if (result != TCL_OK) {
+		errfile = errorBuffer;
+		if (Tcl_FSEqualPaths(errfile, source) == 0) {
+		    errfile = source;
+		}
+	    }
+	} else {
+	    result = Tcl_FSDeleteFile(source);
+	    if (result != TCL_OK) {
+		errfile = source;
+	    }
+	}
+	if (result != TCL_OK) {
+	    Tcl_SetObjResult(interp, Tcl_ObjPrintf("can't unlink \"%s\": %s",
+		    TclGetString(errfile), Tcl_PosixError(interp)));
+	    errfile = NULL;
+	}
+    }
+
+  done:
+    if (errfile != NULL) {
+	Tcl_Obj *errorMsg = Tcl_ObjPrintf("error %s \"%s\"",
+		(copyFlag ? "copying" : "renaming"), TclGetString(source));
+
+	if (errfile != source) {
+	    Tcl_AppendPrintfToObj(errorMsg, " to \"%s\"",
+		    TclGetString(target));
+	    if (errfile != target) {
+		Tcl_AppendPrintfToObj(errorMsg, ": \"%s\"",
+			TclGetString(errfile));
+	    }
+	}
+	Tcl_AppendPrintfToObj(errorMsg, ": %s", Tcl_PosixError(interp));
+	Tcl_SetObjResult(interp, errorMsg);
+    }
+    if (errorBuffer != NULL) {
+	Tcl_DecrRefCount(errorBuffer);
+    }
+    if (actualSource != NULL) {
+	Tcl_DecrRefCount(actualSource);
+    }
+    return result;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * FileForceOption --
+ *
+ *	Helps parse command line options for file commands that take the
+ *	"-force" and "--" options.
+ *
+ * Results:
+ *	The return value is how many arguments from argv were consumed by this
+ *	function, or -1 if there was an error parsing the options. If an error
+ *	occurred, an error message is left in the interp's result.
+ *
+ * Side effects:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+static int
+FileForceOption(
+    Tcl_Interp *interp,		/* Interp, for error return. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[],	/* Argument strings.  First command line
+				 * option, if it exists, begins at 0. */
+    int *forcePtr)		/* If the "-force" was specified, *forcePtr is
+				 * filled with 1, otherwise with 0. */
+{
+    int force, i, idx;
+    static const char *const options[] = {
+	"-force", "--", NULL
+    };
+
+    force = 0;
+    for (i = 0; i < objc; i++) {
+	if (TclGetString(objv[i])[0] != '-') {
+	    break;
+	}
+	if (Tcl_GetIndexFromObj(interp, objv[i], options, "option", TCL_EXACT,
+		&idx) != TCL_OK) {
+	    return -1;
+	}
+	if (idx == 0 /* -force */) {
+	    force = 1;
+	} else { /* -- */
+	    i++;
+	    break;
+	}
+    }
+    *forcePtr = force;
+    return i;
+}
+/*
+ *---------------------------------------------------------------------------
+ *
+ * FileBasename --
+ *
+ *	Given a path in either tcl format (with / separators), or in the
+ *	platform-specific format for the current platform, return all the
+ *	characters in the path after the last directory separator. But, if
+ *	path is the root directory, returns no characters.
+ *
+ * Results:
+ *	Returns the string object that represents the basename. If there is an
+ *	error, an error message is left in interp, and NULL is returned.
+ *
+ * Side effects:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+static Tcl_Obj *
+FileBasename(
+    Tcl_Interp *interp,		/* Interp, for error return. */
+    Tcl_Obj *pathPtr)		/* Path whose basename to extract. */
+{
+    int objc;
+    Tcl_Obj *splitPtr;
+    Tcl_Obj *resultPtr = NULL;
+
+    splitPtr = Tcl_FSSplitPath(pathPtr, &objc);
+    Tcl_IncrRefCount(splitPtr);
+
+    if (objc != 0) {
+	if ((objc == 1) && (*TclGetString(pathPtr) == '~')) {
+	    Tcl_DecrRefCount(splitPtr);
+	    if (Tcl_FSConvertToPathType(interp, pathPtr) != TCL_OK) {
+		return NULL;
+	    }
+	    splitPtr = Tcl_FSSplitPath(pathPtr, &objc);
+	    Tcl_IncrRefCount(splitPtr);
+	}
+
+	/*
+	 * Return the last component, unless it is the only component, and it
+	 * is the root of an absolute path.
+	 */
+
+	if (objc > 0) {
+	    Tcl_ListObjIndex(NULL, splitPtr, objc-1, &resultPtr);
+	    if ((objc == 1) &&
+		    (Tcl_FSGetPathType(resultPtr) != TCL_PATH_RELATIVE)) {
+		resultPtr = NULL;
+	    }
+	}
+    }
+    if (resultPtr == NULL) {
+	resultPtr = Tcl_NewObj();
+    }
+    Tcl_IncrRefCount(resultPtr);
+    Tcl_DecrRefCount(splitPtr);
+    return resultPtr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclFileAttrsCmd --
+ *
+ *	Sets or gets the platform-specific attributes of a file. The objc-objv
+ *	points to the file name with the rest of the command line following.
+ *	This routine uses platform-specific tables of option strings and
+ *	callbacks. The callback to get the attributes take three parameters:
+ *	    Tcl_Interp *interp;	    The interp to report errors with. Since
+ *				    this is an object-based API, the object
+ *				    form of the result should be used.
+ *	    const char *fileName;   This is extracted using
+ *				    Tcl_TranslateFileName.
+ *	    TclObj **attrObjPtrPtr; A new object to hold the attribute is
+ *				    allocated and put here.
+ *	The first two parameters of the callback used to write out the
+ *	attributes are the same. The third parameter is:
+ *	    const *attrObjPtr;	    A pointer to the object that has the new
+ *				    attribute.
+ *	They both return standard TCL errors; if the routine to get an
+ *	attribute fails, no object is allocated and *attrObjPtrPtr is
+ *	unchanged.
+ *
+ * Results:
+ *	Standard TCL error.
+ *
+ * Side effects:
+ *	May set file attributes for the file name.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclFileAttrsCmd(
+    ClientData clientData,	/* Unused */
+    Tcl_Interp *interp,		/* The interpreter for error reporting. */
+    int objc,			/* Number of command line arguments. */
+    Tcl_Obj *const objv[])	/* The command line objects. */
+{
+    int result;
+    const char *const *attributeStrings;
+    const char **attributeStringsAllocated = NULL;
+    Tcl_Obj *objStrings = NULL;
+    int numObjStrings = -1;
+    Tcl_Obj *filePtr;
+
+    if (objc < 2) {
+	Tcl_WrongNumArgs(interp, 1, objv, "name ?-option value ...?");
+	return TCL_ERROR;
+    }
+
+    filePtr = objv[1];
+    if (Tcl_FSConvertToPathType(interp, filePtr) != TCL_OK) {
+	return TCL_ERROR;
+    }
+
+    objc -= 2;
+    objv += 2;
+    result = TCL_ERROR;
+    Tcl_SetErrno(0);
+
+    /*
+     * Get the set of attribute names from the filesystem.
+     */
+
+    attributeStrings = Tcl_FSFileAttrStrings(filePtr, &objStrings);
+    if (attributeStrings == NULL) {
+	int index;
+	Tcl_Obj *objPtr;
+
+	if (objStrings == NULL) {
+	    if (Tcl_GetErrno() != 0) {
+		/*
+		 * There was an error, probably that the filePtr is not
+		 * accepted by any filesystem
+		 */
+
+		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+			"could not read \"%s\": %s",
+			TclGetString(filePtr), Tcl_PosixError(interp)));
+	    }
+	    return TCL_ERROR;
+	}
+
+	/*
+	 * We own the object now.
+	 */
+
+	Tcl_IncrRefCount(objStrings);
+
+	/*
+	 * Use objStrings as a list object.
+	 */
+
+	if (Tcl_ListObjLength(interp, objStrings, &numObjStrings) != TCL_OK) {
+	    goto end;
+	}
+	attributeStringsAllocated = (const char **)
+		TclStackAlloc(interp, (1+numObjStrings) * sizeof(char *));
+	for (index = 0; index < numObjStrings; index++) {
+	    Tcl_ListObjIndex(interp, objStrings, index, &objPtr);
+	    attributeStringsAllocated[index] = TclGetString(objPtr);
+	}
+	attributeStringsAllocated[index] = NULL;
+	attributeStrings = attributeStringsAllocated;
+    } else if (objStrings != NULL) {
+	Tcl_Panic("must not update objPtrRef's variable and return non-NULL");
+    }
+
+    /*
+     * Process the attributes to produce a list of all of them, the value of a
+     * particular attribute, or to set one or more attributes (depending on
+     * the number of arguments).
+     */
+
+    if (objc == 0) {
+	/*
+	 * Get all attributes.
+	 */
+
+	int index, res = TCL_OK, nbAtts = 0;
+	Tcl_Obj *listPtr;
+
+	listPtr = Tcl_NewListObj(0, NULL);
+	for (index = 0; attributeStrings[index] != NULL; index++) {
+	    Tcl_Obj *objPtrAttr;
+
+	    if (res != TCL_OK) {
+		/*
+		 * Clear the error from the last iteration.
+		 */
+
+		Tcl_ResetResult(interp);
+	    }
+
+	    res = Tcl_FSFileAttrsGet(interp, index, filePtr, &objPtrAttr);
+	    if (res == TCL_OK) {
+		Tcl_Obj *objPtr =
+			Tcl_NewStringObj(attributeStrings[index], -1);
+
+		Tcl_ListObjAppendElement(interp, listPtr, objPtr);
+		Tcl_ListObjAppendElement(interp, listPtr, objPtrAttr);
+		nbAtts++;
+	    }
+	}
+
+	if (index > 0 && nbAtts == 0) {
+	    /*
+	     * Error: no valid attributes found.
+	     */
+
+	    Tcl_DecrRefCount(listPtr);
+	    goto end;
+	}
+
+	Tcl_SetObjResult(interp, listPtr);
+    } else if (objc == 1) {
+	/*
+	 * Get one attribute.
+	 */
+
+	int index;
+	Tcl_Obj *objPtr = NULL;
+
+	if (numObjStrings == 0) {
+	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		    "bad option \"%s\", there are no file attributes in this"
+		    " filesystem", TclGetString(objv[0])));
+	    Tcl_SetErrorCode(interp, "TCL","OPERATION","FATTR","NONE", NULL);
+	    goto end;
+	}
+
+	if (Tcl_GetIndexFromObj(interp, objv[0], attributeStrings,
+		"option", 0, &index) != TCL_OK) {
+	    goto end;
+	}
+	if (attributeStringsAllocated != NULL) {
+	    TclFreeIntRep(objv[0]);
+	}
+	if (Tcl_FSFileAttrsGet(interp, index, filePtr,
+		&objPtr) != TCL_OK) {
+	    goto end;
+	}
+	Tcl_SetObjResult(interp, objPtr);
+    } else {
+	/*
+	 * Set option/value pairs.
+	 */
+
+	int i, index;
+
+	if (numObjStrings == 0) {
+	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		    "bad option \"%s\", there are no file attributes in this"
+		    " filesystem", TclGetString(objv[0])));
+	    Tcl_SetErrorCode(interp, "TCL","OPERATION","FATTR","NONE", NULL);
+	    goto end;
+	}
+
+	for (i = 0; i < objc ; i += 2) {
+	    if (Tcl_GetIndexFromObj(interp, objv[i], attributeStrings,
+		    "option", 0, &index) != TCL_OK) {
+		goto end;
+	    }
+	    if (attributeStringsAllocated != NULL) {
+		TclFreeIntRep(objv[i]);
+	    }
+	    if (i + 1 == objc) {
+		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+			"value for \"%s\" missing", TclGetString(objv[i])));
+		Tcl_SetErrorCode(interp, "TCL", "OPERATION", "FATTR",
+			"NOVALUE", NULL);
+		goto end;
+	    }
+	    if (Tcl_FSFileAttrsSet(interp, index, filePtr,
+		    objv[i + 1]) != TCL_OK) {
+		goto end;
+	    }
+	}
+    }
+    result = TCL_OK;
+
+    /*
+     * Free up the array we allocated and drop our reference to any list of
+     * attribute names issued by the filesystem.
+     */
+
+  end:
+    if (attributeStringsAllocated != NULL) {
+	TclStackFree(interp, (void *) attributeStringsAllocated);
+    }
+    if (objStrings != NULL) {
+	Tcl_DecrRefCount(objStrings);
+    }
+    return result;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclFileLinkCmd --
+ *
+ *	This function is invoked to process the "file link" Tcl command. See
+ *	the user documentation for details on what it does.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	May create a new link.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclFileLinkCmd(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const objv[])
+{
+    Tcl_Obj *contents;
+    int index;
+
+    if (objc < 2 || objc > 4) {
+	Tcl_WrongNumArgs(interp, 1, objv, "?-linktype? linkname ?target?");
+	return TCL_ERROR;
+    }
+
+    /*
+     * Index of the 'source' argument.
+     */
+
+    if (objc == 4) {
+	index = 2;
+    } else {
+	index = 1;
+    }
+
+    if (objc > 2) {
+	int linkAction;
+
+	if (objc == 4) {
+	    /*
+	     * We have a '-linktype' argument.
+	     */
+
+	    static const char *const linkTypes[] = {
+		"-symbolic", "-hard", NULL
+	    };
+	    if (Tcl_GetIndexFromObj(interp, objv[1], linkTypes, "option", 0,
+		    &linkAction) != TCL_OK) {
+		return TCL_ERROR;
+	    }
+	    if (linkAction == 0) {
+		linkAction = TCL_CREATE_SYMBOLIC_LINK;
+	    } else {
+		linkAction = TCL_CREATE_HARD_LINK;
+	    }
+	} else {
+	    linkAction = TCL_CREATE_SYMBOLIC_LINK | TCL_CREATE_HARD_LINK;
+	}
+	if (Tcl_FSConvertToPathType(interp, objv[index]) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+
+	/*
+	 * Create link from source to target.
+	 */
+
+	contents = Tcl_FSLink(objv[index], objv[index+1], linkAction);
+	if (contents == NULL) {
+	    /*
+	     * We handle three common error cases specially, and for all other
+	     * errors, we use the standard posix error message.
+	     */
+
+	    if (errno == EEXIST) {
+		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+			"could not create new link \"%s\": that path already"
+			" exists", TclGetString(objv[index])));
+		Tcl_PosixError(interp);
+	    } else if (errno == ENOENT) {
+		/*
+		 * There are two cases here: either the target doesn't exist,
+		 * or the directory of the src doesn't exist.
+		 */
+
+		int access;
+		Tcl_Obj *dirPtr = TclPathPart(interp, objv[index],
+			TCL_PATH_DIRNAME);
+
+		if (dirPtr == NULL) {
+		    return TCL_ERROR;
+		}
+		access = Tcl_FSAccess(dirPtr, F_OK);
+		Tcl_DecrRefCount(dirPtr);
+		if (access != 0) {
+		    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+			    "could not create new link \"%s\": no such file"
+			    " or directory", TclGetString(objv[index])));
+		    Tcl_PosixError(interp);
+		} else {
+		    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+			    "could not create new link \"%s\": target \"%s\" "
+			    "doesn't exist", TclGetString(objv[index]),
+			    TclGetString(objv[index+1])));
+		    errno = ENOENT;
+		    Tcl_PosixError(interp);
+		}
+	    } else {
+		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+			"could not create new link \"%s\" pointing to \"%s\": %s",
+			TclGetString(objv[index]),
+			TclGetString(objv[index+1]), Tcl_PosixError(interp)));
+	    }
+	    return TCL_ERROR;
+	}
+    } else {
+	if (Tcl_FSConvertToPathType(interp, objv[index]) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+
+	/*
+	 * Read link
+	 */
+
+	contents = Tcl_FSLink(objv[index], NULL, 0);
+	if (contents == NULL) {
+	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		    "could not read link \"%s\": %s",
+		    TclGetString(objv[index]), Tcl_PosixError(interp)));
+	    return TCL_ERROR;
+	}
+    }
+    Tcl_SetObjResult(interp, contents);
+    if (objc == 2) {
+	/*
+	 * If we are reading a link, we need to free this result refCount. If
+	 * we are creating a link, this will just be objv[index+1], and so we
+	 * don't own it.
+	 */
+
+	Tcl_DecrRefCount(contents);
+    }
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclFileReadLinkCmd --
+ *
+ *	This function is invoked to process the "file readlink" Tcl command.
+ *	See the user documentation for details on what it does.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclFileReadLinkCmd(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const objv[])
+{
+    Tcl_Obj *contents;
+
+    if (objc != 2) {
+	Tcl_WrongNumArgs(interp, 1, objv, "name");
+	return TCL_ERROR;
+    }
+
+    if (Tcl_FSConvertToPathType(interp, objv[1]) != TCL_OK) {
+	return TCL_ERROR;
+    }
+
+    contents = Tcl_FSLink(objv[1], NULL, 0);
+
+    if (contents == NULL) {
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		"could not read link \"%s\": %s",
+		TclGetString(objv[1]), Tcl_PosixError(interp)));
+	return TCL_ERROR;
+    }
+    Tcl_SetObjResult(interp, contents);
+    Tcl_DecrRefCount(contents);
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * TclFileTemporaryCmd
+ *
+ *	This function implements the "tempfile" subcommand of the "file"
+ *	command.
+ *
+ * Results:
+ *	Returns a standard Tcl result.
+ *
+ * Side effects:
+ *	Creates a temporary file. Opens a channel to that file and puts the
+ *	name of that channel in the result. *Might* register suitable exit
+ *	handlers to ensure that the temporary file gets deleted. Might write
+ *	to a variable, so reentrancy is a potential issue.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+int
+TclFileTemporaryCmd(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const objv[])
+{
+    Tcl_Obj *nameVarObj = NULL;	/* Variable to store the name of the temporary
+				 * file in. */
+    Tcl_Obj *nameObj = NULL;	/* Object that will contain the filename. */
+    Tcl_Channel chan;		/* The channel opened (RDWR) on the temporary
+				 * file, or NULL if there's an error. */
+    Tcl_Obj *tempDirObj = NULL, *tempBaseObj = NULL, *tempExtObj = NULL;
+				/* Pieces of template. Each piece is NULL if
+				 * it is omitted. The platform temporary file
+				 * engine might ignore some pieces. */
+
+    if (objc < 1 || objc > 3) {
+	Tcl_WrongNumArgs(interp, 1, objv, "?nameVar? ?template?");
+	return TCL_ERROR;
+    }
+
+    if (objc > 1) {
+	nameVarObj = objv[1];
+	TclNewObj(nameObj);
+    }
+    if (objc > 2) {
+	int length;
+	Tcl_Obj *templateObj = objv[2];
+	const char *string = TclGetStringFromObj(templateObj, &length);
+
+	/*
+	 * Treat an empty string as if it wasn't there.
+	 */
+
+	if (length == 0) {
+	    goto makeTemporary;
+	}
+
+	/*
+	 * The template only gives a directory if there is a directory
+	 * separator in it.
+	 */
+
+	if (strchr(string, '/') != NULL
+		|| (tclPlatform == TCL_PLATFORM_WINDOWS
+		    && strchr(string, '\\') != NULL)) {
+	    tempDirObj = TclPathPart(interp, templateObj, TCL_PATH_DIRNAME);
+
+	    /*
+	     * Only allow creation of temporary files in the native filesystem
+	     * since they are frequently used for integration with external
+	     * tools or system libraries. [Bug 2388866]
+	     */
+
+	    if (tempDirObj != NULL && Tcl_FSGetFileSystemForPath(tempDirObj)
+		    != &tclNativeFilesystem) {
+		TclDecrRefCount(tempDirObj);
+		tempDirObj = NULL;
+	    }
+	}
+
+	/*
+	 * The template only gives the filename if the last character isn't a
+	 * directory separator.
+	 */
+
+	if (string[length-1] != '/' && (tclPlatform != TCL_PLATFORM_WINDOWS
+		|| string[length-1] != '\\')) {
+	    Tcl_Obj *tailObj = TclPathPart(interp, templateObj,
+		    TCL_PATH_TAIL);
+
+	    if (tailObj != NULL) {
+		tempBaseObj = TclPathPart(interp, tailObj, TCL_PATH_ROOT);
+		tempExtObj = TclPathPart(interp, tailObj, TCL_PATH_EXTENSION);
+		TclDecrRefCount(tailObj);
+	    }
+	}
+    }
+
+    /*
+     * Convert empty parts of the template into unspecified parts.
+     */
+
+    if (tempDirObj && !TclGetString(tempDirObj)[0]) {
+	TclDecrRefCount(tempDirObj);
+	tempDirObj = NULL;
+    }
+    if (tempBaseObj && !TclGetString(tempBaseObj)[0]) {
+	TclDecrRefCount(tempBaseObj);
+	tempBaseObj = NULL;
+    }
+    if (tempExtObj && !TclGetString(tempExtObj)[0]) {
+	TclDecrRefCount(tempExtObj);
+	tempExtObj = NULL;
+    }
+
+    /*
+     * Create and open the temporary file.
+     */
+
+  makeTemporary:
+    chan = TclpOpenTemporaryFile(tempDirObj,tempBaseObj,tempExtObj, nameObj);
+
+    /*
+     * If we created pieces of template, get rid of them now.
+     */
+
+    if (tempDirObj) {
+	TclDecrRefCount(tempDirObj);
+    }
+    if (tempBaseObj) {
+	TclDecrRefCount(tempBaseObj);
+    }
+    if (tempExtObj) {
+	TclDecrRefCount(tempExtObj);
+    }
+
+    /*
+     * Deal with results.
+     */
+
+    if (chan == NULL) {
+	if (nameVarObj) {
+	    TclDecrRefCount(nameObj);
+	}
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		"can't create temporary file: %s", Tcl_PosixError(interp)));
+	return TCL_ERROR;
+    }
+    Tcl_RegisterChannel(interp, chan);
+    if (nameVarObj != NULL) {
+	if (Tcl_ObjSetVar2(interp, nameVarObj, NULL, nameObj,
+		TCL_LEAVE_ERR_MSG) == NULL) {
+	    Tcl_UnregisterChannel(interp, chan);
+	    return TCL_ERROR;
+	}
+    }
+    Tcl_SetObjResult(interp, Tcl_NewStringObj(Tcl_GetChannelName(chan), -1));
+    return TCL_OK;
+}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tclFileName.c b/generic/tclFileName.c
new file mode 100644
index 0000000..2136883
--- /dev/null
+++ b/generic/tclFileName.c
@@ -0,0 +1,2658 @@
+/*
+ * tclFileName.c --
+ *
+ *	This file contains routines for converting file names betwen native
+ *	and network form.
+ *
+ * Copyright (c) 1995-1998 Sun Microsystems, Inc.
+ * Copyright (c) 1998-1999 by Scriptics Corporation.
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#include "tclInt.h"
+#include "tclRegexp.h"
+#include "tclFileSystem.h" /* For TclGetPathType() */
+
+/*
+ * The following variable is set in the TclPlatformInit call to one of:
+ * TCL_PLATFORM_UNIX or TCL_PLATFORM_WINDOWS.
+ */
+
+TclPlatformType tclPlatform = TCL_PLATFORM_UNIX;
+
+/*
+ * Prototypes for local procedures defined in this file:
+ */
+
+static const char *	DoTildeSubst(Tcl_Interp *interp,
+			    const char *user, Tcl_DString *resultPtr);
+static const char *	ExtractWinRoot(const char *path,
+			    Tcl_DString *resultPtr, int offset,
+			    Tcl_PathType *typePtr);
+static int		SkipToChar(char **stringPtr, int match);
+static Tcl_Obj *	SplitWinPath(const char *path);
+static Tcl_Obj *	SplitUnixPath(const char *path);
+static int		DoGlob(Tcl_Interp *interp, Tcl_Obj *resultPtr,
+			    const char *separators, Tcl_Obj *pathPtr, int flags,
+			    char *pattern, Tcl_GlobTypeData *types);
+
+/*
+ * When there is no support for getting the block size of a file in a stat()
+ * call, use this as a guess. Allow it to be overridden in the platform-
+ * specific files.
+ */
+
+#if (!defined(HAVE_STRUCT_STAT_ST_BLKSIZE) && !defined(GUESSED_BLOCK_SIZE))
+#define GUESSED_BLOCK_SIZE	1024
+#endif
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * SetResultLength --
+ *
+ *	Resets the result DString for ExtractWinRoot to accommodate
+ *	any NT extended path prefixes.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	May modify the Tcl_DString.
+ *----------------------------------------------------------------------
+ */
+
+static void
+SetResultLength(
+    Tcl_DString *resultPtr,
+    int offset,
+    int extended)
+{
+    Tcl_DStringSetLength(resultPtr, offset);
+    if (extended == 2) {
+	TclDStringAppendLiteral(resultPtr, "//?/UNC/");
+    } else if (extended == 1) {
+	TclDStringAppendLiteral(resultPtr, "//?/");
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ExtractWinRoot --
+ *
+ *	Matches the root portion of a Windows path and appends it to the
+ *	specified Tcl_DString.
+ *
+ * Results:
+ *	Returns the position in the path immediately after the root including
+ *	any trailing slashes. Appends a cleaned up version of the root to the
+ *	Tcl_DString at the specified offest.
+ *
+ * Side effects:
+ *	Modifies the specified Tcl_DString.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static const char *
+ExtractWinRoot(
+    const char *path,		/* Path to parse. */
+    Tcl_DString *resultPtr,	/* Buffer to hold result. */
+    int offset,			/* Offset in buffer where result should be
+				 * stored. */
+    Tcl_PathType *typePtr)	/* Where to store pathType result */
+{
+    int extended = 0;
+
+    if (   (path[0] == '/' || path[0] == '\\')
+	&& (path[1] == '/' || path[1] == '\\')
+	&& (path[2] == '?')
+	&& (path[3] == '/' || path[3] == '\\')) {
+	extended = 1;
+	path = path + 4;
+	if (path[0] == 'U' && path[1] == 'N' && path[2] == 'C'
+	    && (path[3] == '/' || path[3] == '\\')) {
+	    extended = 2;
+	    path = path + 4;
+	}
+    }
+
+    if (path[0] == '/' || path[0] == '\\') {
+	/*
+	 * Might be a UNC or Vol-Relative path.
+	 */
+
+	const char *host, *share, *tail;
+	int hlen, slen;
+
+	if (path[1] != '/' && path[1] != '\\') {
+	    SetResultLength(resultPtr, offset, extended);
+	    *typePtr = TCL_PATH_VOLUME_RELATIVE;
+	    TclDStringAppendLiteral(resultPtr, "/");
+	    return &path[1];
+	}
+	host = &path[2];
+
+	/*
+	 * Skip separators.
+	 */
+
+	while (host[0] == '/' || host[0] == '\\') {
+	    host++;
+	}
+
+	for (hlen = 0; host[hlen];hlen++) {
+	    if (host[hlen] == '/' || host[hlen] == '\\') {
+		break;
+	    }
+	}
+	if (host[hlen] == 0 || host[hlen+1] == 0) {
+	    /*
+	     * The path given is simply of the form '/foo', '//foo',
+	     * '/////foo' or the same with backslashes. If there is exactly
+	     * one leading '/' the path is volume relative (see filename man
+	     * page). If there are more than one, we are simply assuming they
+	     * are superfluous and we trim them away. (An alternative
+	     * interpretation would be that it is a host name, but we have
+	     * been documented that that is not the case).
+	     */
+
+	    *typePtr = TCL_PATH_VOLUME_RELATIVE;
+	    TclDStringAppendLiteral(resultPtr, "/");
+	    return &path[2];
+	}
+	SetResultLength(resultPtr, offset, extended);
+	share = &host[hlen];
+
+	/*
+	 * Skip separators.
+	 */
+
+	while (share[0] == '/' || share[0] == '\\') {
+	    share++;
+	}
+
+	for (slen=0; share[slen]; slen++) {
+	    if (share[slen] == '/' || share[slen] == '\\') {
+		break;
+	    }
+	}
+	TclDStringAppendLiteral(resultPtr, "//");
+	Tcl_DStringAppend(resultPtr, host, hlen);
+	TclDStringAppendLiteral(resultPtr, "/");
+	Tcl_DStringAppend(resultPtr, share, slen);
+
+	tail = &share[slen];
+
+	/*
+	 * Skip separators.
+	 */
+
+	while (tail[0] == '/' || tail[0] == '\\') {
+	    tail++;
+	}
+
+	*typePtr = TCL_PATH_ABSOLUTE;
+	return tail;
+    } else if (*path && path[1] == ':') {
+	/*
+	 * Might be a drive separator.
+	 */
+
+	SetResultLength(resultPtr, offset, extended);
+
+	if (path[2] != '/' && path[2] != '\\') {
+	    *typePtr = TCL_PATH_VOLUME_RELATIVE;
+	    Tcl_DStringAppend(resultPtr, path, 2);
+	    return &path[2];
+	} else {
+	    const char *tail = &path[3];
+
+	    /*
+	     * Skip separators.
+	     */
+
+	    while (*tail && (tail[0] == '/' || tail[0] == '\\')) {
+		tail++;
+	    }
+
+	    *typePtr = TCL_PATH_ABSOLUTE;
+	    Tcl_DStringAppend(resultPtr, path, 2);
+	    TclDStringAppendLiteral(resultPtr, "/");
+
+	    return tail;
+	}
+    } else {
+	int abs = 0;
+
+	/*
+	 * Check for Windows devices.
+	 */
+
+	if ((path[0] == 'c' || path[0] == 'C')
+		&& (path[1] == 'o' || path[1] == 'O')) {
+	    if ((path[2] == 'm' || path[2] == 'M')
+		    && path[3] >= '1' && path[3] <= '9') {
+		/*
+		 * May have match for 'com[1-9]:?', which is a serial port.
+		 */
+
+		if (path[4] == '\0') {
+		    abs = 4;
+		} else if (path [4] == ':' && path[5] == '\0') {
+		    abs = 5;
+		}
+
+	    } else if ((path[2] == 'n' || path[2] == 'N') && path[3] == '\0') {
+		/*
+		 * Have match for 'con'.
+		 */
+
+		abs = 3;
+	    }
+
+	} else if ((path[0] == 'l' || path[0] == 'L')
+		&& (path[1] == 'p' || path[1] == 'P')
+		&& (path[2] == 't' || path[2] == 'T')) {
+	    if (path[3] >= '1' && path[3] <= '9') {
+		/*
+		 * May have match for 'lpt[1-9]:?'
+		 */
+
+		if (path[4] == '\0') {
+		    abs = 4;
+		} else if (path [4] == ':' && path[5] == '\0') {
+		    abs = 5;
+		}
+	    }
+
+	} else if ((path[0] == 'p' || path[0] == 'P')
+		&& (path[1] == 'r' || path[1] == 'R')
+		&& (path[2] == 'n' || path[2] == 'N')
+		&& path[3] == '\0') {
+	    /*
+	     * Have match for 'prn'.
+	     */
+	    abs = 3;
+
+	} else if ((path[0] == 'n' || path[0] == 'N')
+		&& (path[1] == 'u' || path[1] == 'U')
+		&& (path[2] == 'l' || path[2] == 'L')
+		&& path[3] == '\0') {
+	    /*
+	     * Have match for 'nul'.
+	     */
+
+	    abs = 3;
+
+	} else if ((path[0] == 'a' || path[0] == 'A')
+		&& (path[1] == 'u' || path[1] == 'U')
+		&& (path[2] == 'x' || path[2] == 'X')
+		&& path[3] == '\0') {
+	    /*
+	     * Have match for 'aux'.
+	     */
+
+	    abs = 3;
+	}
+
+	if (abs != 0) {
+	    *typePtr = TCL_PATH_ABSOLUTE;
+	    SetResultLength(resultPtr, offset, extended);
+	    Tcl_DStringAppend(resultPtr, path, abs);
+	    return path + abs;
+	}
+    }
+
+    /*
+     * Anything else is treated as relative.
+     */
+
+    *typePtr = TCL_PATH_RELATIVE;
+    return path;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_GetPathType --
+ *
+ *	Determines whether a given path is relative to the current directory,
+ *	relative to the current volume, or absolute.
+ *
+ *	The objectified Tcl_FSGetPathType should be used in preference to this
+ *	function (as you can see below, this is just a wrapper around that
+ *	other function).
+ *
+ * Results:
+ *	Returns one of TCL_PATH_ABSOLUTE, TCL_PATH_RELATIVE, or
+ *	TCL_PATH_VOLUME_RELATIVE.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_PathType
+Tcl_GetPathType(
+    const char *path)
+{
+    Tcl_PathType type;
+    Tcl_Obj *tempObj = Tcl_NewStringObj(path,-1);
+
+    Tcl_IncrRefCount(tempObj);
+    type = Tcl_FSGetPathType(tempObj);
+    Tcl_DecrRefCount(tempObj);
+    return type;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclpGetNativePathType --
+ *
+ *	Determines whether a given path is relative to the current directory,
+ *	relative to the current volume, or absolute, but ONLY FOR THE NATIVE
+ *	FILESYSTEM. This function is called from tclIOUtil.c (but needs to be
+ *	here due to its dependence on static variables/functions in this
+ *	file). The exported function Tcl_FSGetPathType should be used by
+ *	extensions.
+ *
+ *	Note that '~' paths are always considered TCL_PATH_ABSOLUTE, even
+ *	though expanding the '~' could lead to any possible path type. This
+ *	function should therefore be considered a low-level, string
+ *	manipulation function only -- it doesn't actually do any expansion in
+ *	making its determination.
+ *
+ * Results:
+ *	Returns one of TCL_PATH_ABSOLUTE, TCL_PATH_RELATIVE, or
+ *	TCL_PATH_VOLUME_RELATIVE.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_PathType
+TclpGetNativePathType(
+    Tcl_Obj *pathPtr,		/* Native path of interest */
+    int *driveNameLengthPtr,	/* Returns length of drive, if non-NULL and
+				 * path was absolute */
+    Tcl_Obj **driveNameRef)
+{
+    Tcl_PathType type = TCL_PATH_ABSOLUTE;
+    int pathLen;
+    const char *path = Tcl_GetStringFromObj(pathPtr, &pathLen);
+
+    if (path[0] == '~') {
+	/*
+	 * This case is common to all platforms. Paths that begin with ~ are
+	 * absolute.
+	 */
+
+	if (driveNameLengthPtr != NULL) {
+	    const char *end = path + 1;
+	    while ((*end != '\0') && (*end != '/')) {
+		end++;
+	    }
+	    *driveNameLengthPtr = end - path;
+	}
+    } else {
+	switch (tclPlatform) {
+	case TCL_PLATFORM_UNIX: {
+	    const char *origPath = path;
+
+	    /*
+	     * Paths that begin with / are absolute.
+	     */
+
+	    if (path[0] == '/') {
+		++path;
+#if defined(__CYGWIN__) || defined(__QNX__)
+		/*
+		 * Check for "//" network path prefix
+		 */
+		if ((*path == '/') && path[1] && (path[1] != '/')) {
+		    path += 2;
+		    while (*path && *path != '/') {
+			++path;
+		    }
+#if defined(__CYGWIN__)
+		    /* UNC paths need to be followed by a share name */
+		    if (*path++ && (*path && *path != '/')) {
+			++path;
+			while (*path && *path != '/') {
+			    ++path;
+			}
+		    } else {
+			path = origPath + 1;
+		    }
+#endif
+		}
+#endif
+		if (driveNameLengthPtr != NULL) {
+		    /*
+		     * We need this addition in case the QNX or Cygwin code was used.
+		     */
+
+		    *driveNameLengthPtr = (path - origPath);
+		}
+	    } else {
+		type = TCL_PATH_RELATIVE;
+	    }
+	    break;
+	}
+	case TCL_PLATFORM_WINDOWS: {
+	    Tcl_DString ds;
+	    const char *rootEnd;
+
+	    Tcl_DStringInit(&ds);
+	    rootEnd = ExtractWinRoot(path, &ds, 0, &type);
+	    if ((rootEnd != path) && (driveNameLengthPtr != NULL)) {
+		*driveNameLengthPtr = rootEnd - path;
+		if (driveNameRef != NULL) {
+		    *driveNameRef = TclDStringToObj(&ds);
+		    Tcl_IncrRefCount(*driveNameRef);
+		}
+	    }
+	    Tcl_DStringFree(&ds);
+	    break;
+	}
+	}
+    }
+    return type;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * TclpNativeSplitPath --
+ *
+ *	This function takes the given Tcl_Obj, which should be a valid path,
+ *	and returns a Tcl List object containing each segment of that path as
+ *	an element.
+ *
+ *	Note this function currently calls the older Split(Plat)Path
+ *	functions, which require more memory allocation than is desirable.
+ *
+ * Results:
+ *	Returns list object with refCount of zero. If the passed in lenPtr is
+ *	non-NULL, we use it to return the number of elements in the returned
+ *	list.
+ *
+ * Side effects:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+Tcl_Obj *
+TclpNativeSplitPath(
+    Tcl_Obj *pathPtr,		/* Path to split. */
+    int *lenPtr)		/* int to store number of path elements. */
+{
+    Tcl_Obj *resultPtr = NULL;	/* Needed only to prevent gcc warnings. */
+
+    /*
+     * Perform platform specific splitting.
+     */
+
+    switch (tclPlatform) {
+    case TCL_PLATFORM_UNIX:
+	resultPtr = SplitUnixPath(Tcl_GetString(pathPtr));
+	break;
+
+    case TCL_PLATFORM_WINDOWS:
+	resultPtr = SplitWinPath(Tcl_GetString(pathPtr));
+	break;
+    }
+
+    /*
+     * Compute the number of elements in the result.
+     */
+
+    if (lenPtr != NULL) {
+	Tcl_ListObjLength(NULL, resultPtr, lenPtr);
+    }
+    return resultPtr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_SplitPath --
+ *
+ *	Split a path into a list of path components. The first element of the
+ *	list will have the same path type as the original path.
+ *
+ * Results:
+ *	Returns a standard Tcl result. The interpreter result contains a list
+ *	of path components. *argvPtr will be filled in with the address of an
+ *	array whose elements point to the elements of path, in order.
+ *	*argcPtr will get filled in with the number of valid elements in the
+ *	array. A single block of memory is dynamically allocated to hold both
+ *	the argv array and a copy of the path elements. The caller must
+ *	eventually free this memory by calling ckfree() on *argvPtr. Note:
+ *	*argvPtr and *argcPtr are only modified if the procedure returns
+ *	normally.
+ *
+ * Side effects:
+ *	Allocates memory.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_SplitPath(
+    const char *path,		/* Pointer to string containing a path. */
+    int *argcPtr,		/* Pointer to location to fill in with the
+				 * number of elements in the path. */
+    const char ***argvPtr)	/* Pointer to place to store pointer to array
+				 * of pointers to path elements. */
+{
+    Tcl_Obj *resultPtr = NULL;	/* Needed only to prevent gcc warnings. */
+    Tcl_Obj *tmpPtr, *eltPtr;
+    int i, size, len;
+    char *p;
+    const char *str;
+
+    /*
+     * Perform the splitting, using objectified, vfs-aware code.
+     */
+
+    tmpPtr = Tcl_NewStringObj(path, -1);
+    Tcl_IncrRefCount(tmpPtr);
+    resultPtr = Tcl_FSSplitPath(tmpPtr, argcPtr);
+    Tcl_IncrRefCount(resultPtr);
+    Tcl_DecrRefCount(tmpPtr);
+
+    /*
+     * Calculate space required for the result.
+     */
+
+    size = 1;
+    for (i = 0; i < *argcPtr; i++) {
+	Tcl_ListObjIndex(NULL, resultPtr, i, &eltPtr);
+	Tcl_GetStringFromObj(eltPtr, &len);
+	size += len + 1;
+    }
+
+    /*
+     * Allocate a buffer large enough to hold the contents of all of the list
+     * plus the argv pointers and the terminating NULL pointer.
+     */
+
+    *argvPtr = ckalloc((((*argcPtr) + 1) * sizeof(char *)) + size);
+
+    /*
+     * Position p after the last argv pointer and copy the contents of the
+     * list in, piece by piece.
+     */
+
+    p = (char *) &(*argvPtr)[(*argcPtr) + 1];
+    for (i = 0; i < *argcPtr; i++) {
+	Tcl_ListObjIndex(NULL, resultPtr, i, &eltPtr);
+	str = Tcl_GetStringFromObj(eltPtr, &len);
+	memcpy(p, str, (size_t) len+1);
+	p += len+1;
+    }
+
+    /*
+     * Now set up the argv pointers.
+     */
+
+    p = (char *) &(*argvPtr)[(*argcPtr) + 1];
+
+    for (i = 0; i < *argcPtr; i++) {
+	(*argvPtr)[i] = p;
+	for (; *(p++)!='\0'; );
+    }
+    (*argvPtr)[i] = NULL;
+
+    /*
+     * Free the result ptr given to us by Tcl_FSSplitPath
+     */
+
+    Tcl_DecrRefCount(resultPtr);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * SplitUnixPath --
+ *
+ *	This routine is used by Tcl_(FS)SplitPath to handle splitting Unix
+ *	paths.
+ *
+ * Results:
+ *	Returns a newly allocated Tcl list object.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static Tcl_Obj *
+SplitUnixPath(
+    const char *path)		/* Pointer to string containing a path. */
+{
+    int length;
+    const char *origPath = path, *elementStart;
+    Tcl_Obj *result = Tcl_NewObj();
+
+    /*
+     * Deal with the root directory as a special case.
+     */
+
+    if (*path == '/') {
+	Tcl_Obj *rootElt;
+	++path;
+#if defined(__CYGWIN__) || defined(__QNX__)
+	/*
+	 * Check for "//" network path prefix
+	 */
+	if ((*path == '/') && path[1] && (path[1] != '/')) {
+	    path += 2;
+	    while (*path && *path != '/') {
+		++path;
+	    }
+#if defined(__CYGWIN__)
+	    /* UNC paths need to be followed by a share name */
+	    if (*path++ && (*path && *path != '/')) {
+		++path;
+		while (*path && *path != '/') {
+		    ++path;
+		}
+	    } else {
+		path = origPath + 1;
+	    }
+#endif
+	}
+#endif
+	rootElt = Tcl_NewStringObj(origPath, path - origPath);
+	Tcl_ListObjAppendElement(NULL, result, rootElt);
+	while (*path == '/') {
+	    ++path;
+	}
+    }
+
+    /*
+     * Split on slashes. Embedded elements that start with tilde will be
+     * prefixed with "./" so they are not affected by tilde substitution.
+     */
+
+    for (;;) {
+	elementStart = path;
+	while ((*path != '\0') && (*path != '/')) {
+	    path++;
+	}
+	length = path - elementStart;
+	if (length > 0) {
+	    Tcl_Obj *nextElt;
+	    if ((elementStart[0] == '~') && (elementStart != origPath)) {
+		TclNewLiteralStringObj(nextElt, "./");
+		Tcl_AppendToObj(nextElt, elementStart, length);
+	    } else {
+		nextElt = Tcl_NewStringObj(elementStart, length);
+	    }
+	    Tcl_ListObjAppendElement(NULL, result, nextElt);
+	}
+	if (*path++ == '\0') {
+	    break;
+	}
+    }
+    return result;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * SplitWinPath --
+ *
+ *	This routine is used by Tcl_(FS)SplitPath to handle splitting Windows
+ *	paths.
+ *
+ * Results:
+ *	Returns a newly allocated Tcl list object.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static Tcl_Obj *
+SplitWinPath(
+    const char *path)		/* Pointer to string containing a path. */
+{
+    int length;
+    const char *p, *elementStart;
+    Tcl_PathType type = TCL_PATH_ABSOLUTE;
+    Tcl_DString buf;
+    Tcl_Obj *result = Tcl_NewObj();
+    Tcl_DStringInit(&buf);
+
+    p = ExtractWinRoot(path, &buf, 0, &type);
+
+    /*
+     * Terminate the root portion, if we matched something.
+     */
+
+    if (p != path) {
+	Tcl_ListObjAppendElement(NULL, result, TclDStringToObj(&buf));
+    }
+    Tcl_DStringFree(&buf);
+
+    /*
+     * Split on slashes. Embedded elements that start with tilde or a drive
+     * letter will be prefixed with "./" so they are not affected by tilde
+     * substitution.
+     */
+
+    do {
+	elementStart = p;
+	while ((*p != '\0') && (*p != '/') && (*p != '\\')) {
+	    p++;
+	}
+	length = p - elementStart;
+	if (length > 0) {
+	    Tcl_Obj *nextElt;
+	    if ((elementStart != path) && ((elementStart[0] == '~')
+		    || (isalpha(UCHAR(elementStart[0]))
+			&& elementStart[1] == ':'))) {
+		TclNewLiteralStringObj(nextElt, "./");
+		Tcl_AppendToObj(nextElt, elementStart, length);
+	    } else {
+		nextElt = Tcl_NewStringObj(elementStart, length);
+	    }
+	    Tcl_ListObjAppendElement(NULL, result, nextElt);
+	}
+    } while (*p++ != '\0');
+
+    return result;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Tcl_FSJoinToPath --
+ *
+ *	This function takes the given object, which should usually be a valid
+ *	path or NULL, and joins onto it the array of paths segments given.
+ *
+ *	The objects in the array given will temporarily have their refCount
+ *	increased by one, and then decreased by one when this function exits
+ *	(which means if they had zero refCount when we were called, they will
+ *	be freed).
+ *
+ * Results:
+ *	Returns object owned by the caller (which should increment its
+ *	refCount) - typically an object with refCount of zero.
+ *
+ * Side effects:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+Tcl_Obj *
+Tcl_FSJoinToPath(
+    Tcl_Obj *pathPtr,		/* Valid path or NULL. */
+    int objc,			/* Number of array elements to join */
+    Tcl_Obj *const objv[])	/* Path elements to join. */
+{
+    if (pathPtr == NULL) {
+	return TclJoinPath(objc, objv);
+    }
+    if (objc == 0) {
+	return TclJoinPath(1, &pathPtr);
+    }
+    if (objc == 1) {
+	Tcl_Obj *pair[2];
+
+	pair[0] = pathPtr;
+	pair[1] = objv[0];
+	return TclJoinPath(2, pair);
+    } else {
+	int elemc = objc + 1;
+	Tcl_Obj *ret, **elemv = ckalloc(elemc*sizeof(Tcl_Obj *));
+
+	elemv[0] = pathPtr;
+	memcpy(elemv+1, objv, objc*sizeof(Tcl_Obj *));
+	ret = TclJoinPath(elemc, elemv);
+	ckfree(elemv);
+	return ret;
+    }
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * TclpNativeJoinPath --
+ *
+ *	'prefix' is absolute, 'joining' is relative to prefix.
+ *
+ * Results:
+ *	modifies prefix
+ *
+ * Side effects:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+void
+TclpNativeJoinPath(
+    Tcl_Obj *prefix,
+    const char *joining)
+{
+    int length, needsSep;
+    char *dest;
+    const char *p;
+    const char *start;
+
+    start = Tcl_GetStringFromObj(prefix, &length);
+
+    /*
+     * Remove the ./ from tilde prefixed elements, and drive-letter prefixed
+     * elements on Windows, unless it is the first component.
+     */
+
+    p = joining;
+
+    if (length != 0) {
+	if ((p[0] == '.') && (p[1] == '/') && ((p[2] == '~')
+		|| (tclPlatform==TCL_PLATFORM_WINDOWS && isalpha(UCHAR(p[2]))
+		&& (p[3] == ':')))) {
+	    p += 2;
+	}
+    }
+    if (*p == '\0') {
+	return;
+    }
+
+    switch (tclPlatform) {
+    case TCL_PLATFORM_UNIX:
+	/*
+	 * Append a separator if needed.
+	 */
+
+	if (length > 0 && (start[length-1] != '/')) {
+	    Tcl_AppendToObj(prefix, "/", 1);
+	    Tcl_GetStringFromObj(prefix, &length);
+	}
+	needsSep = 0;
+
+	/*
+	 * Append the element, eliminating duplicate and trailing slashes.
+	 */
+
+	Tcl_SetObjLength(prefix, length + (int) strlen(p));
+
+	dest = Tcl_GetString(prefix) + length;
+	for (; *p != '\0'; p++) {
+	    if (*p == '/') {
+		while (p[1] == '/') {
+		    p++;
+		}
+		if (p[1] != '\0' && needsSep) {
+		    *dest++ = '/';
+		}
+	    } else {
+		*dest++ = *p;
+		needsSep = 1;
+	    }
+	}
+	length = dest - Tcl_GetString(prefix);
+	Tcl_SetObjLength(prefix, length);
+	break;
+
+    case TCL_PLATFORM_WINDOWS:
+	/*
+	 * Check to see if we need to append a separator.
+	 */
+
+	if ((length > 0) &&
+		(start[length-1] != '/') && (start[length-1] != ':')) {
+	    Tcl_AppendToObj(prefix, "/", 1);
+	    Tcl_GetStringFromObj(prefix, &length);
+	}
+	needsSep = 0;
+
+	/*
+	 * Append the element, eliminating duplicate and trailing slashes.
+	 */
+
+	Tcl_SetObjLength(prefix, length + (int) strlen(p));
+	dest = Tcl_GetString(prefix) + length;
+	for (; *p != '\0'; p++) {
+	    if ((*p == '/') || (*p == '\\')) {
+		while ((p[1] == '/') || (p[1] == '\\')) {
+		    p++;
+		}
+		if ((p[1] != '\0') && needsSep) {
+		    *dest++ = '/';
+		}
+	    } else {
+		*dest++ = *p;
+		needsSep = 1;
+	    }
+	}
+	length = dest - Tcl_GetString(prefix);
+	Tcl_SetObjLength(prefix, length);
+	break;
+    }
+    return;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_JoinPath --
+ *
+ *	Combine a list of paths in a platform specific manner. The function
+ *	'Tcl_FSJoinPath' should be used in preference where possible.
+ *
+ * Results:
+ *	Appends the joined path to the end of the specified Tcl_DString
+ *	returning a pointer to the resulting string. Note that the
+ *	Tcl_DString must already be initialized.
+ *
+ * Side effects:
+ *	Modifies the Tcl_DString.
+ *
+ *----------------------------------------------------------------------
+ */
+
+char *
+Tcl_JoinPath(
+    int argc,
+    const char *const *argv,
+    Tcl_DString *resultPtr)	/* Pointer to previously initialized DString */
+{
+    int i, len;
+    Tcl_Obj *listObj = Tcl_NewObj();
+    Tcl_Obj *resultObj;
+    const char *resultStr;
+
+    /*
+     * Build the list of paths.
+     */
+
+    for (i = 0; i < argc; i++) {
+	Tcl_ListObjAppendElement(NULL, listObj,
+		Tcl_NewStringObj(argv[i], -1));
+    }
+
+    /*
+     * Ask the objectified code to join the paths.
+     */
+
+    Tcl_IncrRefCount(listObj);
+    resultObj = Tcl_FSJoinPath(listObj, argc);
+    Tcl_IncrRefCount(resultObj);
+    Tcl_DecrRefCount(listObj);
+
+    /*
+     * Store the result.
+     */
+
+    resultStr = Tcl_GetStringFromObj(resultObj, &len);
+    Tcl_DStringAppend(resultPtr, resultStr, len);
+    Tcl_DecrRefCount(resultObj);
+
+    /*
+     * Return a pointer to the result.
+     */
+
+    return Tcl_DStringValue(resultPtr);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Tcl_TranslateFileName --
+ *
+ *	Converts a file name into a form usable by the native system
+ *	interfaces. If the name starts with a tilde, it will produce a name
+ *	where the tilde and following characters have been replaced by the
+ *	home directory location for the named user.
+ *
+ * Results:
+ *	The return value is a pointer to a string containing the name after
+ *	tilde substitution. If there was no tilde substitution, the return
+ *	value is a pointer to a copy of the original string. If there was an
+ *	error in processing the name, then an error message is left in the
+ *	interp's result (if interp was not NULL) and the return value is NULL.
+ *	Space for the return value is allocated in bufferPtr; the caller must
+ *	call Tcl_DStringFree() to free the space if the return value was not
+ *	NULL.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+char *
+Tcl_TranslateFileName(
+    Tcl_Interp *interp,		/* Interpreter in which to store error message
+				 * (if necessary). */
+    const char *name,		/* File name, which may begin with "~" (to
+				 * indicate current user's home directory) or
+				 * "~<user>" (to indicate any user's home
+				 * directory). */
+    Tcl_DString *bufferPtr)	/* Uninitialized or free DString filled with
+				 * name after tilde substitution. */
+{
+    Tcl_Obj *path = Tcl_NewStringObj(name, -1);
+    Tcl_Obj *transPtr;
+
+    Tcl_IncrRefCount(path);
+    transPtr = Tcl_FSGetTranslatedPath(interp, path);
+    if (transPtr == NULL) {
+	Tcl_DecrRefCount(path);
+	return NULL;
+    }
+
+    Tcl_DStringInit(bufferPtr);
+    TclDStringAppendObj(bufferPtr, transPtr);
+    Tcl_DecrRefCount(path);
+    Tcl_DecrRefCount(transPtr);
+
+    /*
+     * Convert forward slashes to backslashes in Windows paths because some
+     * system interfaces don't accept forward slashes.
+     */
+
+    if (tclPlatform == TCL_PLATFORM_WINDOWS) {
+	register char *p;
+	for (p = Tcl_DStringValue(bufferPtr); *p != '\0'; p++) {
+	    if (*p == '/') {
+		*p = '\\';
+	    }
+	}
+    }
+
+    return Tcl_DStringValue(bufferPtr);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclGetExtension --
+ *
+ *	This function returns a pointer to the beginning of the extension part
+ *	of a file name.
+ *
+ * Results:
+ *	Returns a pointer into name which indicates where the extension
+ *	starts. If there is no extension, returns NULL.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+const char *
+TclGetExtension(
+    const char *name)		/* File name to parse. */
+{
+    const char *p, *lastSep;
+
+    /*
+     * First find the last directory separator.
+     */
+
+    lastSep = NULL;		/* Needed only to prevent gcc warnings. */
+    switch (tclPlatform) {
+    case TCL_PLATFORM_UNIX:
+	lastSep = strrchr(name, '/');
+	break;
+
+    case TCL_PLATFORM_WINDOWS:
+	lastSep = NULL;
+	for (p = name; *p != '\0'; p++) {
+	    if (strchr("/\\:", *p) != NULL) {
+		lastSep = p;
+	    }
+	}
+	break;
+    }
+    p = strrchr(name, '.');
+    if ((p != NULL) && (lastSep != NULL) && (lastSep > p)) {
+	p = NULL;
+    }
+
+    /*
+     * In earlier versions, we used to back up to the first period in a series
+     * so that "foo..o" would be split into "foo" and "..o". This is a
+     * confusing and usually incorrect behavior, so now we split at the last
+     * period in the name.
+     */
+
+    return p;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * DoTildeSubst --
+ *
+ *	Given a string following a tilde, this routine returns the
+ *	corresponding home directory.
+ *
+ * Results:
+ *	The result is a pointer to a static string containing the home
+ *	directory in native format. If there was an error in processing the
+ *	substitution, then an error message is left in the interp's result and
+ *	the return value is NULL. On success, the results are appended to
+ *	resultPtr, and the contents of resultPtr are returned.
+ *
+ * Side effects:
+ *	Information may be left in resultPtr.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static const char *
+DoTildeSubst(
+    Tcl_Interp *interp,		/* Interpreter in which to store error message
+				 * (if necessary). */
+    const char *user,		/* Name of user whose home directory should be
+				 * substituted, or "" for current user. */
+    Tcl_DString *resultPtr)	/* Initialized DString filled with name after
+				 * tilde substitution. */
+{
+    const char *dir;
+
+    if (*user == '\0') {
+	Tcl_DString dirString;
+
+	dir = TclGetEnv("HOME", &dirString);
+	if (dir == NULL) {
+	    if (interp) {
+		Tcl_SetObjResult(interp, Tcl_NewStringObj(
+			"couldn't find HOME environment "
+			"variable to expand path", -1));
+		Tcl_SetErrorCode(interp, "TCL", "FILENAME", "NO_HOME", NULL);
+	    }
+	    return NULL;
+	}
+	Tcl_JoinPath(1, &dir, resultPtr);
+	Tcl_DStringFree(&dirString);
+    } else if (TclpGetUserHome(user, resultPtr) == NULL) {
+	if (interp) {
+	    Tcl_ResetResult(interp);
+	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		    "user \"%s\" doesn't exist", user));
+	    Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "USER", user, NULL);
+	}
+	return NULL;
+    }
+    return Tcl_DStringValue(resultPtr);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_GlobObjCmd --
+ *
+ *	This procedure is invoked to process the "glob" Tcl command. See the
+ *	user documentation for details on what it does.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+	/* ARGSUSED */
+int
+Tcl_GlobObjCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    int index, i, globFlags, length, join, dir, result;
+    char *string;
+    const char *separators;
+    Tcl_Obj *typePtr, *look;
+    Tcl_Obj *pathOrDir = NULL;
+    Tcl_DString prefix;
+    static const char *const options[] = {
+	"-directory", "-join", "-nocomplain", "-path", "-tails",
+	"-types", "--", NULL
+    };
+    enum options {
+	GLOB_DIR, GLOB_JOIN, GLOB_NOCOMPLAIN, GLOB_PATH, GLOB_TAILS,
+	GLOB_TYPE, GLOB_LAST
+    };
+    enum pathDirOptions {PATH_NONE = -1 , PATH_GENERAL = 0, PATH_DIR = 1};
+    Tcl_GlobTypeData *globTypes = NULL;
+
+    globFlags = 0;
+    join = 0;
+    dir = PATH_NONE;
+    typePtr = NULL;
+    for (i = 1; i < objc; i++) {
+	if (Tcl_GetIndexFromObj(interp, objv[i], options, "option", 0,
+		&index) != TCL_OK) {
+	    string = Tcl_GetStringFromObj(objv[i], &length);
+	    if (string[0] == '-') {
+		/*
+		 * It looks like the command contains an option so signal an
+		 * error.
+		 */
+
+		return TCL_ERROR;
+	    } else {
+		/*
+		 * This clearly isn't an option; assume it's the first glob
+		 * pattern. We must clear the error.
+		 */
+
+		Tcl_ResetResult(interp);
+		break;
+	    }
+	}
+
+	switch (index) {
+	case GLOB_NOCOMPLAIN:			/* -nocomplain */
+	    globFlags |= TCL_GLOBMODE_NO_COMPLAIN;
+	    break;
+	case GLOB_DIR:				/* -dir */
+	    if (i == (objc-1)) {
+		Tcl_SetObjResult(interp, Tcl_NewStringObj(
+			"missing argument to \"-directory\"", -1));
+		Tcl_SetErrorCode(interp, "TCL", "ARGUMENT", "MISSING", NULL);
+		return TCL_ERROR;
+	    }
+	    if (dir != PATH_NONE) {
+		Tcl_SetObjResult(interp, Tcl_NewStringObj(
+			"\"-directory\" cannot be used with \"-path\"", -1));
+		Tcl_SetErrorCode(interp, "TCL", "OPERATION", "GLOB",
+			"BADOPTIONCOMBINATION", NULL);
+		return TCL_ERROR;
+	    }
+	    dir = PATH_DIR;
+	    globFlags |= TCL_GLOBMODE_DIR;
+	    pathOrDir = objv[i+1];
+	    i++;
+	    break;
+	case GLOB_JOIN:				/* -join */
+	    join = 1;
+	    break;
+	case GLOB_TAILS:				/* -tails */
+	    globFlags |= TCL_GLOBMODE_TAILS;
+	    break;
+	case GLOB_PATH:				/* -path */
+	    if (i == (objc-1)) {
+		Tcl_SetObjResult(interp, Tcl_NewStringObj(
+			"missing argument to \"-path\"", -1));
+		Tcl_SetErrorCode(interp, "TCL", "ARGUMENT", "MISSING", NULL);
+		return TCL_ERROR;
+	    }
+	    if (dir != PATH_NONE) {
+		Tcl_SetObjResult(interp, Tcl_NewStringObj(
+			"\"-path\" cannot be used with \"-directory\"", -1));
+		Tcl_SetErrorCode(interp, "TCL", "OPERATION", "GLOB",
+			"BADOPTIONCOMBINATION", NULL);
+		return TCL_ERROR;
+	    }
+	    dir = PATH_GENERAL;
+	    pathOrDir = objv[i+1];
+	    i++;
+	    break;
+	case GLOB_TYPE:				/* -types */
+	    if (i == (objc-1)) {
+		Tcl_SetObjResult(interp, Tcl_NewStringObj(
+			"missing argument to \"-types\"", -1));
+		Tcl_SetErrorCode(interp, "TCL", "ARGUMENT", "MISSING", NULL);
+		return TCL_ERROR;
+	    }
+	    typePtr = objv[i+1];
+	    if (Tcl_ListObjLength(interp, typePtr, &length) != TCL_OK) {
+		return TCL_ERROR;
+	    }
+	    i++;
+	    break;
+	case GLOB_LAST:				/* -- */
+	    i++;
+	    goto endOfForLoop;
+	}
+    }
+
+  endOfForLoop:
+    if ((globFlags & TCL_GLOBMODE_TAILS) && (pathOrDir == NULL)) {
+	Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		"\"-tails\" must be used with either "
+		"\"-directory\" or \"-path\"", -1));
+	Tcl_SetErrorCode(interp, "TCL", "OPERATION", "GLOB",
+		"BADOPTIONCOMBINATION", NULL);
+	return TCL_ERROR;
+    }
+
+    separators = NULL;		/* lint. */
+    switch (tclPlatform) {
+    case TCL_PLATFORM_UNIX:
+	separators = "/";
+	break;
+    case TCL_PLATFORM_WINDOWS:
+	separators = "/\\:";
+	break;
+    }
+
+    if (dir == PATH_GENERAL) {
+	int pathlength;
+	const char *last;
+	const char *first = Tcl_GetStringFromObj(pathOrDir,&pathlength);
+
+	/*
+	 * Find the last path separator in the path
+	 */
+
+	last = first + pathlength;
+	for (; last != first; last--) {
+	    if (strchr(separators, *(last-1)) != NULL) {
+		break;
+	    }
+	}
+
+	if (last == first + pathlength) {
+	    /*
+	     * It's really a directory.
+	     */
+
+	    dir = PATH_DIR;
+
+	} else {
+	    Tcl_DString pref;
+	    char *search, *find;
+	    Tcl_DStringInit(&pref);
+	    if (last == first) {
+		/*
+		 * The whole thing is a prefix. This means we must remove any
+		 * 'tails' flag too, since it is irrelevant now (the same
+		 * effect will happen without it), but in particular its use
+		 * in TclGlob requires a non-NULL pathOrDir.
+		 */
+
+		Tcl_DStringAppend(&pref, first, -1);
+		globFlags &= ~TCL_GLOBMODE_TAILS;
+		pathOrDir = NULL;
+	    } else {
+		/*
+		 * Have to split off the end.
+		 */
+
+		Tcl_DStringAppend(&pref, last, first+pathlength-last);
+		pathOrDir = Tcl_NewStringObj(first, last-first-1);
+
+		/*
+		 * We must ensure that we haven't cut off too much, and turned
+		 * a valid path like '/' or 'C:/' into an incorrect path like
+		 * '' or 'C:'. The way we do this is to add a separator if
+		 * there are none presently in the prefix.
+		 */
+
+		if (strpbrk(Tcl_GetString(pathOrDir), "\\/") == NULL) {
+		    Tcl_AppendToObj(pathOrDir, last-1, 1);
+		}
+	    }
+
+	    /*
+	     * Need to quote 'prefix'.
+	     */
+
+	    Tcl_DStringInit(&prefix);
+	    search = Tcl_DStringValue(&pref);
+	    while ((find = (strpbrk(search, "\\[]*?{}"))) != NULL) {
+		Tcl_DStringAppend(&prefix, search, find-search);
+		TclDStringAppendLiteral(&prefix, "\\");
+		Tcl_DStringAppend(&prefix, find, 1);
+		search = find+1;
+		if (*search == '\0') {
+		    break;
+		}
+	    }
+	    if (*search != '\0') {
+		Tcl_DStringAppend(&prefix, search, -1);
+	    }
+	    Tcl_DStringFree(&pref);
+	}
+    }
+
+    if (pathOrDir != NULL) {
+	Tcl_IncrRefCount(pathOrDir);
+    }
+
+    if (typePtr != NULL) {
+	/*
+	 * The rest of the possible type arguments (except 'd') are platform
+	 * specific. We don't complain when they are used on an incompatible
+	 * platform.
+	 */
+
+	Tcl_ListObjLength(interp, typePtr, &length);
+	if (length <= 0) {
+	    goto skipTypes;
+	}
+	globTypes = TclStackAlloc(interp, sizeof(Tcl_GlobTypeData));
+	globTypes->type = 0;
+	globTypes->perm = 0;
+	globTypes->macType = NULL;
+	globTypes->macCreator = NULL;
+
+	while (--length >= 0) {
+	    int len;
+	    const char *str;
+
+	    Tcl_ListObjIndex(interp, typePtr, length, &look);
+	    str = Tcl_GetStringFromObj(look, &len);
+	    if (strcmp("readonly", str) == 0) {
+		globTypes->perm |= TCL_GLOB_PERM_RONLY;
+	    } else if (strcmp("hidden", str) == 0) {
+		globTypes->perm |= TCL_GLOB_PERM_HIDDEN;
+	    } else if (len == 1) {
+		switch (str[0]) {
+		case 'r':
+		    globTypes->perm |= TCL_GLOB_PERM_R;
+		    break;
+		case 'w':
+		    globTypes->perm |= TCL_GLOB_PERM_W;
+		    break;
+		case 'x':
+		    globTypes->perm |= TCL_GLOB_PERM_X;
+		    break;
+		case 'b':
+		    globTypes->type |= TCL_GLOB_TYPE_BLOCK;
+		    break;
+		case 'c':
+		    globTypes->type |= TCL_GLOB_TYPE_CHAR;
+		    break;
+		case 'd':
+		    globTypes->type |= TCL_GLOB_TYPE_DIR;
+		    break;
+		case 'p':
+		    globTypes->type |= TCL_GLOB_TYPE_PIPE;
+		    break;
+		case 'f':
+		    globTypes->type |= TCL_GLOB_TYPE_FILE;
+		    break;
+		case 'l':
+		    globTypes->type |= TCL_GLOB_TYPE_LINK;
+		    break;
+		case 's':
+		    globTypes->type |= TCL_GLOB_TYPE_SOCK;
+		    break;
+		default:
+		    goto badTypesArg;
+		}
+
+	    } else if (len == 4) {
+		/*
+		 * This is assumed to be a MacOS file type.
+		 */
+
+		if (globTypes->macType != NULL) {
+		    goto badMacTypesArg;
+		}
+		globTypes->macType = look;
+		Tcl_IncrRefCount(look);
+
+	    } else {
+		Tcl_Obj *item;
+
+		if ((Tcl_ListObjLength(NULL, look, &len) == TCL_OK)
+			&& (len == 3)) {
+		    Tcl_ListObjIndex(interp, look, 0, &item);
+		    if (!strcmp("macintosh", Tcl_GetString(item))) {
+			Tcl_ListObjIndex(interp, look, 1, &item);
+			if (!strcmp("type", Tcl_GetString(item))) {
+			    Tcl_ListObjIndex(interp, look, 2, &item);
+			    if (globTypes->macType != NULL) {
+				goto badMacTypesArg;
+			    }
+			    globTypes->macType = item;
+			    Tcl_IncrRefCount(item);
+			    continue;
+			} else if (!strcmp("creator", Tcl_GetString(item))) {
+			    Tcl_ListObjIndex(interp, look, 2, &item);
+			    if (globTypes->macCreator != NULL) {
+				goto badMacTypesArg;
+			    }
+			    globTypes->macCreator = item;
+			    Tcl_IncrRefCount(item);
+			    continue;
+			}
+		    }
+		}
+
+		/*
+		 * Error cases. We reset the 'join' flag to zero, since we
+		 * haven't yet made use of it.
+		 */
+
+	    badTypesArg:
+		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+			"bad argument to \"-types\": %s",
+			Tcl_GetString(look)));
+		Tcl_SetErrorCode(interp, "TCL", "ARGUMENT", "BAD", NULL);
+		result = TCL_ERROR;
+		join = 0;
+		goto endOfGlob;
+
+	    badMacTypesArg:
+		Tcl_SetObjResult(interp, Tcl_NewStringObj(
+			"only one MacOS type or creator argument"
+			" to \"-types\" allowed", -1));
+		result = TCL_ERROR;
+		Tcl_SetErrorCode(interp, "TCL", "ARGUMENT", "BAD", NULL);
+		join = 0;
+		goto endOfGlob;
+	    }
+	}
+    }
+
+  skipTypes:
+    /*
+     * Now we perform the actual glob below. This may involve joining together
+     * the pattern arguments, dealing with particular file types etc. We use a
+     * 'goto' to ensure we free any memory allocated along the way.
+     */
+
+    objc -= i;
+    objv += i;
+    result = TCL_OK;
+
+    if (join) {
+	if (dir != PATH_GENERAL) {
+	    Tcl_DStringInit(&prefix);
+	}
+	for (i = 0; i < objc; i++) {
+	    TclDStringAppendObj(&prefix, objv[i]);
+	    if (i != objc -1) {
+		Tcl_DStringAppend(&prefix, separators, 1);
+	    }
+	}
+	if (TclGlob(interp, Tcl_DStringValue(&prefix), pathOrDir, globFlags,
+		globTypes) != TCL_OK) {
+	    result = TCL_ERROR;
+	    goto endOfGlob;
+	}
+    } else if (dir == PATH_GENERAL) {
+	Tcl_DString str;
+
+	Tcl_DStringInit(&str);
+	for (i = 0; i < objc; i++) {
+	    Tcl_DStringSetLength(&str, 0);
+	    if (dir == PATH_GENERAL) {
+		TclDStringAppendDString(&str, &prefix);
+	    }
+	    TclDStringAppendObj(&str, objv[i]);
+	    if (TclGlob(interp, Tcl_DStringValue(&str), pathOrDir, globFlags,
+		    globTypes) != TCL_OK) {
+		result = TCL_ERROR;
+		Tcl_DStringFree(&str);
+		goto endOfGlob;
+	    }
+	}
+	Tcl_DStringFree(&str);
+    } else {
+	for (i = 0; i < objc; i++) {
+	    string = Tcl_GetString(objv[i]);
+	    if (TclGlob(interp, string, pathOrDir, globFlags,
+		    globTypes) != TCL_OK) {
+		result = TCL_ERROR;
+		goto endOfGlob;
+	    }
+	}
+    }
+
+    if ((globFlags & TCL_GLOBMODE_NO_COMPLAIN) == 0) {
+	if (Tcl_ListObjLength(interp, Tcl_GetObjResult(interp),
+		&length) != TCL_OK) {
+	    /*
+	     * This should never happen. Maybe we should be more dramatic.
+	     */
+
+	    result = TCL_ERROR;
+	    goto endOfGlob;
+	}
+
+	if (length == 0) {
+	    Tcl_Obj *errorMsg =
+		    Tcl_ObjPrintf("no files matched glob pattern%s \"",
+			    (join || (objc == 1)) ? "" : "s");
+
+	    if (join) {
+		Tcl_AppendToObj(errorMsg, Tcl_DStringValue(&prefix), -1);
+	    } else {
+		const char *sep = "";
+
+		for (i = 0; i < objc; i++) {
+		    Tcl_AppendPrintfToObj(errorMsg, "%s%s",
+			    sep, Tcl_GetString(objv[i]));
+		    sep = " ";
+		}
+	    }
+	    Tcl_AppendToObj(errorMsg, "\"", -1);
+	    Tcl_SetObjResult(interp, errorMsg);
+	    Tcl_SetErrorCode(interp, "TCL", "OPERATION", "GLOB", "NOMATCH",
+		    NULL);
+	    result = TCL_ERROR;
+	}
+    }
+
+  endOfGlob:
+    if (join || (dir == PATH_GENERAL)) {
+	Tcl_DStringFree(&prefix);
+    }
+    if (pathOrDir != NULL) {
+	Tcl_DecrRefCount(pathOrDir);
+    }
+    if (globTypes != NULL) {
+	if (globTypes->macType != NULL) {
+	    Tcl_DecrRefCount(globTypes->macType);
+	}
+	if (globTypes->macCreator != NULL) {
+	    Tcl_DecrRefCount(globTypes->macCreator);
+	}
+	TclStackFree(interp, globTypes);
+    }
+    return result;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclGlob --
+ *
+ *	This procedure prepares arguments for the DoGlob call. It sets the
+ *	separator string based on the platform, performs * tilde substitution,
+ *	and calls DoGlob.
+ *
+ *	The interpreter's result, on entry to this function, must be a valid
+ *	Tcl list (e.g. it could be empty), since we will lappend any new
+ *	results to that list. If it is not a valid list, this function will
+ *	fail to do anything very meaningful.
+ *
+ *	Note that if globFlags contains 'TCL_GLOBMODE_TAILS' then pathPrefix
+ *	cannot be NULL (it is only allowed with -dir or -path).
+ *
+ * Results:
+ *	The return value is a standard Tcl result indicating whether an error
+ *	occurred in globbing. After a normal return the result in interp (set
+ *	by DoGlob) holds all of the file names given by the pattern and
+ *	pathPrefix arguments. After an error the result in interp will hold
+ *	an error message.
+ *
+ * Side effects:
+ *	The 'pattern' is written to.
+ *
+ *----------------------------------------------------------------------
+ */
+
+	/* ARGSUSED */
+int
+TclGlob(
+    Tcl_Interp *interp,		/* Interpreter for returning error message or
+				 * appending list of matching file names. */
+    char *pattern,		/* Glob pattern to match. Must not refer to a
+				 * static string. */
+    Tcl_Obj *pathPrefix,	/* Path prefix to glob pattern, if non-null,
+				 * which is considered literally. */
+    int globFlags,		/* Stores or'ed combination of flags */
+    Tcl_GlobTypeData *types)	/* Struct containing acceptable types. May be
+				 * NULL. */
+{
+    const char *separators;
+    const char *head;
+    char *tail, *start;
+    int result;
+    Tcl_Obj *filenamesObj, *savedResultObj;
+
+    separators = NULL;		/* lint. */
+    switch (tclPlatform) {
+    case TCL_PLATFORM_UNIX:
+	separators = "/";
+	break;
+    case TCL_PLATFORM_WINDOWS:
+	separators = "/\\:";
+	break;
+    }
+
+    if (pathPrefix == NULL) {
+	char c;
+	Tcl_DString buffer;
+	Tcl_DStringInit(&buffer);
+
+	start = pattern;
+
+	/*
+	 * Perform tilde substitution, if needed.
+	 */
+
+	if (start[0] == '~') {
+	    /*
+	     * Find the first path separator after the tilde.
+	     */
+
+	    for (tail = start; *tail != '\0'; tail++) {
+		if (*tail == '\\') {
+		    if (strchr(separators, tail[1]) != NULL) {
+			break;
+		    }
+		} else if (strchr(separators, *tail) != NULL) {
+		    break;
+		}
+	    }
+
+	    /*
+	     * Determine the home directory for the specified user.
+	     */
+
+	    c = *tail;
+	    *tail = '\0';
+	    head = DoTildeSubst(interp, start+1, &buffer);
+	    *tail = c;
+	    if (head == NULL) {
+		return TCL_ERROR;
+	    }
+	    if (head != Tcl_DStringValue(&buffer)) {
+		Tcl_DStringAppend(&buffer, head, -1);
+	    }
+	    pathPrefix = TclDStringToObj(&buffer);
+	    Tcl_IncrRefCount(pathPrefix);
+	    globFlags |= TCL_GLOBMODE_DIR;
+	    if (c != '\0') {
+		tail++;
+	    }
+	    Tcl_DStringFree(&buffer);
+	} else {
+	    tail = pattern;
+	}
+    } else {
+	Tcl_IncrRefCount(pathPrefix);
+	tail = pattern;
+    }
+
+    /*
+     * Handling empty path prefixes with glob patterns like 'C:' or
+     * 'c:////////' is a pain on Windows if we leave it too late, since these
+     * aren't really patterns at all! We therefore check the head of the
+     * pattern now for such cases, if we don't have an unquoted prefix yet.
+     *
+     * Similarly on Unix with '/' at the head of the pattern -- it just
+     * indicates the root volume, so we treat it as such.
+     */
+
+    if (tclPlatform == TCL_PLATFORM_WINDOWS) {
+	if (pathPrefix == NULL && tail[0] != '\0' && tail[1] == ':') {
+	    char *p = tail + 1;
+	    pathPrefix = Tcl_NewStringObj(tail, 1);
+	    while (*p != '\0') {
+		char c = p[1];
+		if (*p == '\\') {
+		    if (strchr(separators, c) != NULL) {
+			if (c == '\\') {
+			    c = '/';
+			}
+			Tcl_AppendToObj(pathPrefix, &c, 1);
+			p++;
+		    } else {
+			break;
+		    }
+		} else if (strchr(separators, *p) != NULL) {
+		    Tcl_AppendToObj(pathPrefix, p, 1);
+		} else {
+		    break;
+		}
+		p++;
+	    }
+	    tail = p;
+	    Tcl_IncrRefCount(pathPrefix);
+	} else if (pathPrefix == NULL && (tail[0] == '/'
+		|| (tail[0] == '\\' && tail[1] == '\\'))) {
+	    int driveNameLen;
+	    Tcl_Obj *driveName;
+	    Tcl_Obj *temp = Tcl_NewStringObj(tail, -1);
+	    Tcl_IncrRefCount(temp);
+
+	    switch (TclGetPathType(temp, NULL, &driveNameLen, &driveName)) {
+	    case TCL_PATH_VOLUME_RELATIVE: {
+		/*
+		 * Volume relative path which is equivalent to a path in the
+		 * root of the cwd's volume. We will actually return
+		 * non-volume-relative paths here. i.e. 'glob /foo*' will
+		 * return 'C:/foobar'. This is much the same as globbing for a
+		 * path with '\\' will return one with '/' on Windows.
+		 */
+
+		Tcl_Obj *cwd = Tcl_FSGetCwd(interp);
+
+		if (cwd == NULL) {
+		    Tcl_DecrRefCount(temp);
+		    return TCL_ERROR;
+		}
+		pathPrefix = Tcl_NewStringObj(Tcl_GetString(cwd), 3);
+		Tcl_DecrRefCount(cwd);
+		if (tail[0] == '/') {
+		    tail++;
+		} else {
+		    tail += 2;
+		}
+		Tcl_IncrRefCount(pathPrefix);
+		break;
+	    }
+	    case TCL_PATH_ABSOLUTE:
+		/*
+		 * Absolute, possibly network path //Machine/Share. Use that
+		 * as the path prefix (it already has a refCount).
+		 */
+
+		pathPrefix = driveName;
+		tail += driveNameLen;
+		break;
+	    case TCL_PATH_RELATIVE:
+		/* Do nothing */
+		break;
+	    }
+	    Tcl_DecrRefCount(temp);
+	}
+
+	/*
+	 * ':' no longer needed as a separator. It is only relevant to the
+	 * beginning of the path.
+	 */
+
+	separators = "/\\";
+
+    } else if (tclPlatform == TCL_PLATFORM_UNIX) {
+	if (pathPrefix == NULL && tail[0] == '/') {
+	    pathPrefix = Tcl_NewStringObj(tail, 1);
+	    tail++;
+	    Tcl_IncrRefCount(pathPrefix);
+	}
+    }
+
+    /*
+     * Finally if we still haven't managed to generate a path prefix, check if
+     * the path starts with a current volume.
+     */
+
+    if (pathPrefix == NULL) {
+	int driveNameLen;
+	Tcl_Obj *driveName;
+	if (TclFSNonnativePathType(tail, (int) strlen(tail), NULL,
+		&driveNameLen, &driveName) == TCL_PATH_ABSOLUTE) {
+	    pathPrefix = driveName;
+	    tail += driveNameLen;
+	}
+    }
+
+    /*
+     * To process a [glob] invokation, this function may be called multiple
+     * times. Each time, the previously discovered filenames are in the
+     * interpreter result. We stash that away here so the result is free for
+     * error messsages.
+     */
+
+    savedResultObj = Tcl_GetObjResult(interp);
+    Tcl_IncrRefCount(savedResultObj);
+    Tcl_ResetResult(interp);
+    TclNewObj(filenamesObj);
+    Tcl_IncrRefCount(filenamesObj);
+
+    /*
+     * Now we do the actual globbing, adding filenames as we go to buffer in
+     * filenamesObj
+     */
+
+    if (*tail == '\0' && pathPrefix != NULL) {
+	/*
+	 * An empty pattern. This means 'pathPrefix' is actually a full path
+	 * of a file/directory we want to simply check for existence and type.
+	 */
+
+	if (types == NULL) {
+	    /*
+	     * We just want to check for existence. In this case we make it
+	     * easy on Tcl_FSMatchInDirectory and its sub-implementations by
+	     * not bothering them (even though they should support this
+	     * situation) and we just use the simple existence check with
+	     * Tcl_FSAccess.
+	     */
+
+	    if (Tcl_FSAccess(pathPrefix, F_OK) == 0) {
+		Tcl_ListObjAppendElement(interp, filenamesObj, pathPrefix);
+	    }
+	    result = TCL_OK;
+	} else {
+	    /*
+	     * We want to check for the correct type. Tcl_FSMatchInDirectory
+	     * is documented to do this for us, if we give it a NULL pattern.
+	     */
+
+	    result = Tcl_FSMatchInDirectory(interp, filenamesObj, pathPrefix,
+		    NULL, types);
+	}
+    } else {
+	result = DoGlob(interp, filenamesObj, separators, pathPrefix,
+		globFlags & TCL_GLOBMODE_DIR, tail, types);
+    }
+
+    /*
+     * Check for errors...
+     */
+
+    if (result != TCL_OK) {
+	TclDecrRefCount(filenamesObj);
+	TclDecrRefCount(savedResultObj);
+	if (pathPrefix != NULL) {
+	    Tcl_DecrRefCount(pathPrefix);
+	}
+	return result;
+    }
+
+    /*
+     * If we only want the tails, we must strip off the prefix now. It may
+     * seem more efficient to pass the tails flag down into DoGlob,
+     * Tcl_FSMatchInDirectory, but those functions are continually adjusting
+     * the prefix as the various pieces of the pattern are assimilated, so
+     * that would add a lot of complexity to the code. This way is a little
+     * slower (when the -tails flag is given), but much simpler to code.
+     *
+     * We do it by rewriting the result list in-place.
+     */
+
+    if (globFlags & TCL_GLOBMODE_TAILS) {
+	int objc, i;
+	Tcl_Obj **objv;
+	int prefixLen;
+	const char *pre;
+
+	/*
+	 * If this length has never been set, set it here.
+	 */
+
+	if (pathPrefix == NULL) {
+	    Tcl_Panic("Called TclGlob with TCL_GLOBMODE_TAILS and pathPrefix==NULL");
+	}
+
+	pre = Tcl_GetStringFromObj(pathPrefix, &prefixLen);
+	if (prefixLen > 0
+		&& (strchr(separators, pre[prefixLen-1]) == NULL)) {
+	    /*
+	     * If we're on Windows and the prefix is a volume relative one
+	     * like 'C:', then there won't be a path separator in between, so
+	     * no need to skip it here.
+	     */
+
+	    if ((tclPlatform != TCL_PLATFORM_WINDOWS) || (prefixLen != 2)
+		    || (pre[1] != ':')) {
+		prefixLen++;
+	    }
+	}
+
+	Tcl_ListObjGetElements(NULL, filenamesObj, &objc, &objv);
+	for (i = 0; i< objc; i++) {
+	    int len;
+	    const char *oldStr = Tcl_GetStringFromObj(objv[i], &len);
+	    Tcl_Obj *elem;
+
+	    if (len == prefixLen) {
+		if ((pattern[0] == '\0')
+			|| (strchr(separators, pattern[0]) == NULL)) {
+		    TclNewLiteralStringObj(elem, ".");
+		} else {
+		    TclNewLiteralStringObj(elem, "/");
+		}
+	    } else {
+		elem = Tcl_NewStringObj(oldStr+prefixLen, len-prefixLen);
+	    }
+	    Tcl_ListObjReplace(interp, filenamesObj, i, 1, 1, &elem);
+	}
+    }
+
+    /*
+     * Now we have a list of discovered filenames in filenamesObj and a list
+     * of previously discovered (saved earlier from the interpreter result) in
+     * savedResultObj. Merge them and put them back in the interpreter result.
+     */
+
+    if (Tcl_IsShared(savedResultObj)) {
+	TclDecrRefCount(savedResultObj);
+	savedResultObj = Tcl_DuplicateObj(savedResultObj);
+	Tcl_IncrRefCount(savedResultObj);
+    }
+    if (Tcl_ListObjAppendList(interp, savedResultObj, filenamesObj) != TCL_OK){
+	result = TCL_ERROR;
+    } else {
+	Tcl_SetObjResult(interp, savedResultObj);
+    }
+    TclDecrRefCount(savedResultObj);
+    TclDecrRefCount(filenamesObj);
+    if (pathPrefix != NULL) {
+	Tcl_DecrRefCount(pathPrefix);
+    }
+
+    return result;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * SkipToChar --
+ *
+ *	This function traverses a glob pattern looking for the next unquoted
+ *	occurance of the specified character at the same braces nesting level.
+ *
+ * Results:
+ *	Updates stringPtr to point to the matching character, or to the end of
+ *	the string if nothing matched. The return value is 1 if a match was
+ *	found at the top level, otherwise it is 0.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+SkipToChar(
+    char **stringPtr,		/* Pointer string to check. */
+    int match)			/* Character to find. */
+{
+    int quoted, level;
+    register char *p;
+
+    quoted = 0;
+    level = 0;
+
+    for (p = *stringPtr; *p != '\0'; p++) {
+	if (quoted) {
+	    quoted = 0;
+	    continue;
+	}
+	if ((level == 0) && (*p == match)) {
+	    *stringPtr = p;
+	    return 1;
+	}
+	if (*p == '{') {
+	    level++;
+	} else if (*p == '}') {
+	    level--;
+	} else if (*p == '\\') {
+	    quoted = 1;
+	}
+    }
+    *stringPtr = p;
+    return 0;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * DoGlob --
+ *
+ *	This recursive procedure forms the heart of the globbing code. It
+ *	performs a depth-first traversal of the tree given by the path name to
+ *	be globbed and the pattern. The directory and remainder are assumed to
+ *	be native format paths. The prefix contained in 'pathPtr' is either a
+ *	directory or path from which to start the search (or NULL). If pathPtr
+ *	is NULL, then the pattern must not start with an absolute path
+ *	specification (that case should be handled by moving the absolute path
+ *	prefix into pathPtr before calling DoGlob).
+ *
+ * Results:
+ *	The return value is a standard Tcl result indicating whether an error
+ *	occurred in globbing. After a normal return the result in interp will
+ *	be set to hold all of the file names given by the dir and remaining
+ *	arguments. After an error the result in interp will hold an error
+ *	message.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+DoGlob(
+    Tcl_Interp *interp,		/* Interpreter to use for error reporting
+				 * (e.g. unmatched brace). */
+    Tcl_Obj *matchesObj,	/* Unshared list object in which to place all
+				 * resulting filenames. Caller allocates and
+				 * deallocates; DoGlob must not touch the
+				 * refCount of this object. */
+    const char *separators,	/* String containing separator characters that
+				 * should be used to identify globbing
+				 * boundaries. */
+    Tcl_Obj *pathPtr,		/* Completely expanded prefix. */
+    int flags,			/* If non-zero then pathPtr is a directory */
+    char *pattern,		/* The pattern to match against. Must not be a
+				 * pointer to a static string. */
+    Tcl_GlobTypeData *types)	/* List object containing list of acceptable
+				 * types. May be NULL. */
+{
+    int baseLength, quoted, count;
+    int result = TCL_OK;
+    char *name, *p, *openBrace, *closeBrace, *firstSpecialChar;
+    Tcl_Obj *joinedPtr;
+
+    /*
+     * Consume any leading directory separators, leaving pattern pointing just
+     * past the last initial separator.
+     */
+
+    count = 0;
+    name = pattern;
+    for (; *pattern != '\0'; pattern++) {
+	if (*pattern == '\\') {
+	    /*
+	     * If the first character is escaped, either we have a directory
+	     * separator, or we have any other character. In the latter case
+	     * the rest is a pattern, and we must break from the loop. This
+	     * is particularly important on Windows where '\' is both the
+	     * escaping character and a directory separator.
+	     */
+
+	    if (strchr(separators, pattern[1]) != NULL) {
+		pattern++;
+	    } else {
+		break;
+	    }
+	} else if (strchr(separators, *pattern) == NULL) {
+	    break;
+	}
+	count++;
+    }
+
+    /*
+     * Look for the first matching pair of braces or the first directory
+     * separator that is not inside a pair of braces.
+     */
+
+    openBrace = closeBrace = NULL;
+    quoted = 0;
+    for (p = pattern; *p != '\0'; p++) {
+	if (quoted) {
+	    quoted = 0;
+
+	} else if (*p == '\\') {
+	    quoted = 1;
+	    if (strchr(separators, p[1]) != NULL) {
+		/*
+		 * Quoted directory separator.
+		 */
+		break;
+	    }
+
+	} else if (strchr(separators, *p) != NULL) {
+	    /*
+	     * Unquoted directory separator.
+	     */
+	    break;
+
+	} else if (*p == '{') {
+	    openBrace = p;
+	    p++;
+	    if (SkipToChar(&p, '}')) {
+		/*
+		 * Balanced braces.
+		 */
+
+		closeBrace = p;
+		break;
+	    }
+	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		    "unmatched open-brace in file name", -1));
+	    Tcl_SetErrorCode(interp, "TCL", "OPERATION", "GLOB", "BALANCE",
+		    NULL);
+	    return TCL_ERROR;
+
+	} else if (*p == '}') {
+	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		    "unmatched close-brace in file name", -1));
+	    Tcl_SetErrorCode(interp, "TCL", "OPERATION", "GLOB", "BALANCE",
+		    NULL);
+	    return TCL_ERROR;
+	}
+    }
+
+    /*
+     * Substitute the alternate patterns from the braces and recurse.
+     */
+
+    if (openBrace != NULL) {
+	char *element;
+	Tcl_DString newName;
+
+	Tcl_DStringInit(&newName);
+
+	/*
+	 * For each element within in the outermost pair of braces, append the
+	 * element and the remainder to the fixed portion before the first
+	 * brace and recursively call DoGlob.
+	 */
+
+	Tcl_DStringAppend(&newName, pattern, openBrace-pattern);
+	baseLength = Tcl_DStringLength(&newName);
+	*closeBrace = '\0';
+	for (p = openBrace; p != closeBrace; ) {
+	    p++;
+	    element = p;
+	    SkipToChar(&p, ',');
+	    Tcl_DStringSetLength(&newName, baseLength);
+	    Tcl_DStringAppend(&newName, element, p-element);
+	    Tcl_DStringAppend(&newName, closeBrace+1, -1);
+	    result = DoGlob(interp, matchesObj, separators, pathPtr, flags,
+		    Tcl_DStringValue(&newName), types);
+	    if (result != TCL_OK) {
+		break;
+	    }
+	}
+	*closeBrace = '}';
+	Tcl_DStringFree(&newName);
+	return result;
+    }
+
+    /*
+     * At this point, there are no more brace substitutions to perform on this
+     * path component. The variable p is pointing at a quoted or unquoted
+     * directory separator or the end of the string. So we need to check for
+     * special globbing characters in the current pattern. We avoid modifying
+     * pattern if p is pointing at the end of the string.
+     *
+     * If we find any globbing characters, then we must call
+     * Tcl_FSMatchInDirectory. If we're at the end of the string, then that's
+     * all we need to do. If we're not at the end of the string, then we must
+     * recurse, so we do that below.
+     *
+     * Alternatively, if there are no globbing characters then again there are
+     * two cases. If we're at the end of the string, we just need to check for
+     * the given path's existence and type. If we're not at the end of the
+     * string, we recurse.
+     */
+
+    if (*p != '\0') {
+	char savedChar = *p;
+
+	/*
+	 * Note that we are modifying the string in place. This won't work if
+	 * the string is a static.
+	 */
+
+	*p = '\0';
+	firstSpecialChar = strpbrk(pattern, "*[]?\\");
+	*p = savedChar;
+    } else {
+	firstSpecialChar = strpbrk(pattern, "*[]?\\");
+    }
+
+    if (firstSpecialChar != NULL) {
+	/*
+	 * Look for matching files in the given directory. The implementation
+	 * of this function is filesystem specific. For each file that
+	 * matches, it will add the match onto the resultPtr given.
+	 */
+
+	static Tcl_GlobTypeData dirOnly = {
+	    TCL_GLOB_TYPE_DIR, 0, NULL, NULL
+	};
+	char save = *p;
+	Tcl_Obj *subdirsPtr;
+
+	if (*p == '\0') {
+	    return Tcl_FSMatchInDirectory(interp, matchesObj, pathPtr,
+		    pattern, types);
+	}
+
+	/*
+	 * We do the recursion ourselves. This makes implementing
+	 * Tcl_FSMatchInDirectory for each filesystem much easier.
+	 */
+
+	*p = '\0';
+	TclNewObj(subdirsPtr);
+	Tcl_IncrRefCount(subdirsPtr);
+	result = Tcl_FSMatchInDirectory(interp, subdirsPtr, pathPtr,
+		pattern, &dirOnly);
+	*p = save;
+	if (result == TCL_OK) {
+	    int subdirc, i, repair = -1;
+	    Tcl_Obj **subdirv;
+
+	    result = Tcl_ListObjGetElements(interp, subdirsPtr,
+		    &subdirc, &subdirv);
+	    for (i=0; result==TCL_OK && i<subdirc; i++) {
+		Tcl_Obj *copy = NULL;
+
+		if (pathPtr == NULL && Tcl_GetString(subdirv[i])[0] == '~') {
+		    Tcl_ListObjLength(NULL, matchesObj, &repair);
+		    copy = subdirv[i];
+		    subdirv[i] = Tcl_NewStringObj("./", 2);
+		    Tcl_AppendObjToObj(subdirv[i], copy);
+		    Tcl_IncrRefCount(subdirv[i]);
+		}
+		result = DoGlob(interp, matchesObj, separators, subdirv[i],
+			1, p+1, types);
+		if (copy) {
+		    int end;
+
+		    Tcl_DecrRefCount(subdirv[i]);
+		    subdirv[i] = copy;
+		    Tcl_ListObjLength(NULL, matchesObj, &end);
+		    while (repair < end) {
+			const char *bytes;
+			int numBytes;
+			Tcl_Obj *fixme, *newObj;
+
+			Tcl_ListObjIndex(NULL, matchesObj, repair, &fixme);
+			bytes = Tcl_GetStringFromObj(fixme, &numBytes);
+			newObj = Tcl_NewStringObj(bytes+2, numBytes-2);
+			Tcl_ListObjReplace(NULL, matchesObj, repair, 1,
+				1, &newObj);
+			repair++;
+		    }
+		    repair = -1;
+		}
+	    }
+	}
+	TclDecrRefCount(subdirsPtr);
+	return result;
+    }
+
+    /*
+     * We reach here with no pattern char in current section
+     */
+
+    if (*p == '\0') {
+	int length;
+	Tcl_DString append;
+
+	/*
+	 * This is the code path reached by a command like 'glob foo'.
+	 *
+	 * There are no more wildcards in the pattern and no more unprocessed
+	 * characters in the pattern, so now we can construct the path, and
+	 * pass it to Tcl_FSMatchInDirectory with an empty pattern to verify
+	 * the existence of the file and check it is of the correct type (if a
+	 * 'types' flag it given -- if no such flag was given, we could just
+	 * use 'Tcl_FSLStat', but for simplicity we keep to a common
+	 * approach).
+	 */
+
+	Tcl_DStringInit(&append);
+	Tcl_DStringAppend(&append, pattern, p-pattern);
+
+	if (pathPtr != NULL) {
+	    (void) Tcl_GetStringFromObj(pathPtr, &length);
+	} else {
+	    length = 0;
+	}
+
+	switch (tclPlatform) {
+	case TCL_PLATFORM_WINDOWS:
+	    if (length == 0 && (Tcl_DStringLength(&append) == 0)) {
+		if (((*name == '\\') && (name[1] == '/' ||
+			name[1] == '\\')) || (*name == '/')) {
+		    TclDStringAppendLiteral(&append, "/");
+		} else {
+		    TclDStringAppendLiteral(&append, ".");
+		}
+	    }
+
+	    break;
+
+	case TCL_PLATFORM_UNIX:
+	    if (length == 0 && (Tcl_DStringLength(&append) == 0)) {
+		if ((*name == '\\' && name[1] == '/') || (*name == '/')) {
+		    TclDStringAppendLiteral(&append, "/");
+		} else {
+		    TclDStringAppendLiteral(&append, ".");
+		}
+	    }
+	    break;
+	}
+
+	/*
+	 * Common for all platforms.
+	 */
+
+	if (pathPtr == NULL) {
+	    joinedPtr = TclDStringToObj(&append);
+	} else if (flags) {
+	    joinedPtr = TclNewFSPathObj(pathPtr, Tcl_DStringValue(&append),
+		    Tcl_DStringLength(&append));
+	} else {
+	    joinedPtr = Tcl_DuplicateObj(pathPtr);
+	    if (strchr(separators, Tcl_DStringValue(&append)[0]) == NULL) {
+		/*
+		 * The current prefix must end in a separator.
+		 */
+
+		int len;
+		const char *joined = Tcl_GetStringFromObj(joinedPtr,&len);
+
+		if (strchr(separators, joined[len-1]) == NULL) {
+		    Tcl_AppendToObj(joinedPtr, "/", 1);
+		}
+	    }
+	    Tcl_AppendToObj(joinedPtr, Tcl_DStringValue(&append),
+		    Tcl_DStringLength(&append));
+	}
+	Tcl_IncrRefCount(joinedPtr);
+	Tcl_DStringFree(&append);
+	result = Tcl_FSMatchInDirectory(interp, matchesObj, joinedPtr, NULL,
+		types);
+	Tcl_DecrRefCount(joinedPtr);
+	return result;
+    }
+
+    /*
+     * If it's not the end of the string, we must recurse
+     */
+
+    if (pathPtr == NULL) {
+	joinedPtr = Tcl_NewStringObj(pattern, p-pattern);
+    } else if (flags) {
+	joinedPtr = TclNewFSPathObj(pathPtr, pattern, p-pattern);
+    } else {
+	joinedPtr = Tcl_DuplicateObj(pathPtr);
+	if (strchr(separators, pattern[0]) == NULL) {
+	    /*
+	     * The current prefix must end in a separator, unless this is a
+	     * volume-relative path. In particular globbing in Windows shares,
+	     * when not using -dir or -path, e.g. 'glob [file join
+	     * //machine/share/subdir *]' requires adding a separator here.
+	     * This behaviour is not currently tested for in the test suite.
+	     */
+
+	    int len;
+	    const char *joined = Tcl_GetStringFromObj(joinedPtr,&len);
+
+	    if (strchr(separators, joined[len-1]) == NULL) {
+		if (Tcl_FSGetPathType(pathPtr) != TCL_PATH_VOLUME_RELATIVE) {
+		    Tcl_AppendToObj(joinedPtr, "/", 1);
+		}
+	    }
+	}
+	Tcl_AppendToObj(joinedPtr, pattern, p-pattern);
+    }
+
+    Tcl_IncrRefCount(joinedPtr);
+    result = DoGlob(interp, matchesObj, separators, joinedPtr, 1, p, types);
+    Tcl_DecrRefCount(joinedPtr);
+
+    return result;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Tcl_AllocStatBuf --
+ *
+ *	This procedure allocates a Tcl_StatBuf on the heap. It exists so that
+ *	extensions may be used unchanged on systems where largefile support is
+ *	optional.
+ *
+ * Results:
+ *	A pointer to a Tcl_StatBuf which may be deallocated by being passed to
+ *	ckfree().
+ *
+ * Side effects:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+Tcl_StatBuf *
+Tcl_AllocStatBuf(void)
+{
+    return ckalloc(sizeof(Tcl_StatBuf));
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Access functions for Tcl_StatBuf --
+ *
+ *	These functions provide portable read-only access to the portable
+ *	fields of the Tcl_StatBuf structure (really a 'struct stat', 'struct
+ *	stat64' or something else related). [TIP #316]
+ *
+ * Results:
+ *	The value from the field being retrieved.
+ *
+ * Side effects:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+unsigned
+Tcl_GetFSDeviceFromStat(
+    const Tcl_StatBuf *statPtr)
+{
+    return (unsigned) statPtr->st_dev;
+}
+
+unsigned
+Tcl_GetFSInodeFromStat(
+    const Tcl_StatBuf *statPtr)
+{
+    return (unsigned) statPtr->st_ino;
+}
+
+unsigned
+Tcl_GetModeFromStat(
+    const Tcl_StatBuf *statPtr)
+{
+    return (unsigned) statPtr->st_mode;
+}
+
+int
+Tcl_GetLinkCountFromStat(
+    const Tcl_StatBuf *statPtr)
+{
+    return (int)statPtr->st_nlink;
+}
+
+int
+Tcl_GetUserIdFromStat(
+    const Tcl_StatBuf *statPtr)
+{
+    return (int) statPtr->st_uid;
+}
+
+int
+Tcl_GetGroupIdFromStat(
+    const Tcl_StatBuf *statPtr)
+{
+    return (int) statPtr->st_gid;
+}
+
+int
+Tcl_GetDeviceTypeFromStat(
+    const Tcl_StatBuf *statPtr)
+{
+    return (int) statPtr->st_rdev;
+}
+
+Tcl_WideInt
+Tcl_GetAccessTimeFromStat(
+    const Tcl_StatBuf *statPtr)
+{
+    return (Tcl_WideInt) statPtr->st_atime;
+}
+
+Tcl_WideInt
+Tcl_GetModificationTimeFromStat(
+    const Tcl_StatBuf *statPtr)
+{
+    return (Tcl_WideInt) statPtr->st_mtime;
+}
+
+Tcl_WideInt
+Tcl_GetChangeTimeFromStat(
+    const Tcl_StatBuf *statPtr)
+{
+    return (Tcl_WideInt) statPtr->st_ctime;
+}
+
+Tcl_WideUInt
+Tcl_GetSizeFromStat(
+    const Tcl_StatBuf *statPtr)
+{
+    return (Tcl_WideUInt) statPtr->st_size;
+}
+
+Tcl_WideUInt
+Tcl_GetBlocksFromStat(
+    const Tcl_StatBuf *statPtr)
+{
+#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
+    return (Tcl_WideUInt) statPtr->st_blocks;
+#else
+    register unsigned blksize = Tcl_GetBlockSizeFromStat(statPtr);
+
+    return ((Tcl_WideUInt) statPtr->st_size + blksize - 1) / blksize;
+#endif
+}
+
+unsigned
+Tcl_GetBlockSizeFromStat(
+    const Tcl_StatBuf *statPtr)
+{
+#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
+    return (unsigned) statPtr->st_blksize;
+#else
+    /*
+     * Not a great guess, but will do...
+     */
+
+    return GUESSED_BLOCK_SIZE;
+#endif
+}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tclFileSystem.h b/generic/tclFileSystem.h
new file mode 100644
index 0000000..1eec7ff
--- /dev/null
+++ b/generic/tclFileSystem.h
@@ -0,0 +1,74 @@
+/*
+ * tclFileSystem.h --
+ *
+ *	This file contains the common defintions and prototypes for use by
+ *	Tcl's filesystem and path handling layers.
+ *
+ * Copyright (c) 2003 Vince Darley.
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#ifndef _TCLFILESYSTEM
+#define _TCLFILESYSTEM
+
+#include "tcl.h"
+
+/*
+ * The internal TclFS API provides routines for handling and manipulating
+ * paths efficiently, taking direct advantage of the "path" Tcl_Obj type.
+ *
+ * These functions are not exported at all at present.
+ */
+
+MODULE_SCOPE int	TclFSCwdPointerEquals(Tcl_Obj **pathPtrPtr);
+MODULE_SCOPE int	TclFSNormalizeToUniquePath(Tcl_Interp *interp,
+			    Tcl_Obj *pathPtr, int startAt);
+MODULE_SCOPE Tcl_Obj *	TclFSMakePathRelative(Tcl_Interp *interp,
+			    Tcl_Obj *pathPtr, Tcl_Obj *cwdPtr);
+MODULE_SCOPE int	TclFSEnsureEpochOk(Tcl_Obj *pathPtr,
+			    const Tcl_Filesystem **fsPtrPtr);
+MODULE_SCOPE void	TclFSSetPathDetails(Tcl_Obj *pathPtr,
+			    const Tcl_Filesystem *fsPtr, ClientData clientData);
+MODULE_SCOPE Tcl_Obj *	TclFSNormalizeAbsolutePath(Tcl_Interp *interp,
+			    Tcl_Obj *pathPtr);
+MODULE_SCOPE size_t	TclFSEpoch(void);
+
+/*
+ * Private shared variables for use by tclIOUtil.c and tclPathObj.c
+ */
+
+MODULE_SCOPE const Tcl_Filesystem tclNativeFilesystem;
+
+/*
+ * Private shared functions for use by tclIOUtil.c, tclPathObj.c and
+ * tclFileName.c, and any platform-specific filesystem code.
+ */
+
+MODULE_SCOPE Tcl_PathType TclFSGetPathType(Tcl_Obj *pathPtr,
+			    const Tcl_Filesystem **filesystemPtrPtr,
+			    int *driveNameLengthPtr);
+MODULE_SCOPE Tcl_PathType TclFSNonnativePathType(const char *pathPtr,
+			    int pathLen, const Tcl_Filesystem **filesystemPtrPtr,
+			    int *driveNameLengthPtr, Tcl_Obj **driveNameRef);
+MODULE_SCOPE Tcl_PathType TclGetPathType(Tcl_Obj *pathPtr,
+			    const Tcl_Filesystem **filesystemPtrPtr,
+			    int *driveNameLengthPtr, Tcl_Obj **driveNameRef);
+MODULE_SCOPE int	TclFSEpochOk(size_t filesystemEpoch);
+MODULE_SCOPE int	TclFSCwdIsNative(void);
+MODULE_SCOPE Tcl_Obj *	TclWinVolumeRelativeNormalize(Tcl_Interp *interp,
+			    const char *path, Tcl_Obj **useThisCwdPtr);
+
+MODULE_SCOPE Tcl_FSPathInFilesystemProc TclNativePathInFilesystem;
+MODULE_SCOPE Tcl_FSCreateInternalRepProc TclNativeCreateNativeRep;
+
+#endif /* _TCLFILESYSTEM */
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tclGet.c b/generic/tclGet.c
new file mode 100644
index 0000000..97e8c7b
--- /dev/null
+++ b/generic/tclGet.c
@@ -0,0 +1,156 @@
+/*
+ * tclGet.c --
+ *
+ *	This file contains functions to convert strings into other forms, like
+ *	integers or floating-point numbers or booleans, doing syntax checking
+ *	along the way.
+ *
+ * Copyright (c) 1990-1993 The Regents of the University of California.
+ * Copyright (c) 1994-1997 Sun Microsystems, Inc.
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#include "tclInt.h"
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_GetInt --
+ *
+ *	Given a string, produce the corresponding integer value.
+ *
+ * Results:
+ *	The return value is normally TCL_OK; in this case *intPtr will be set
+ *	to the integer value equivalent to src.  If src is improperly formed
+ *	then TCL_ERROR is returned and an error message will be left in the
+ *	interp's result.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_GetInt(
+    Tcl_Interp *interp,		/* Interpreter to use for error reporting. */
+    const char *src,		/* String containing a (possibly signed)
+				 * integer in a form acceptable to
+				 * Tcl_GetIntFromObj(). */
+    int *intPtr)		/* Place to store converted result. */
+{
+    Tcl_Obj obj;
+    int code;
+
+    obj.refCount = 1;
+    obj.bytes = (char *) src;
+    obj.length = strlen(src);
+    obj.typePtr = NULL;
+
+    code = Tcl_GetIntFromObj(interp, &obj, intPtr);
+    if (obj.refCount > 1) {
+	Tcl_Panic("invalid sharing of Tcl_Obj on C stack");
+    }
+    TclFreeIntRep(&obj);
+    return code;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_GetDouble --
+ *
+ *	Given a string, produce the corresponding double-precision
+ *	floating-point value.
+ *
+ * Results:
+ *	The return value is normally TCL_OK; in this case *doublePtr will be
+ *	set to the double-precision value equivalent to src. If src is
+ *	improperly formed then TCL_ERROR is returned and an error message will
+ *	be left in the interp's result.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_GetDouble(
+    Tcl_Interp *interp,		/* Interpreter used for error reporting. */
+    const char *src,		/* String containing a floating-point number
+				 * in a form acceptable to
+				 * Tcl_GetDoubleFromObj(). */
+    double *doublePtr)		/* Place to store converted result. */
+{
+    Tcl_Obj obj;
+    int code;
+
+    obj.refCount = 1;
+    obj.bytes = (char *) src;
+    obj.length = strlen(src);
+    obj.typePtr = NULL;
+
+    code = Tcl_GetDoubleFromObj(interp, &obj, doublePtr);
+    if (obj.refCount > 1) {
+	Tcl_Panic("invalid sharing of Tcl_Obj on C stack");
+    }
+    TclFreeIntRep(&obj);
+    return code;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_GetBoolean --
+ *
+ *	Given a string, return a 0/1 boolean value corresponding to the
+ *	string.
+ *
+ * Results:
+ *	The return value is normally TCL_OK; in this case *boolPtr will be set
+ *	to the 0/1 value equivalent to src. If src is improperly formed then
+ *	TCL_ERROR is returned and an error message will be left in the
+ *	interp's result.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_GetBoolean(
+    Tcl_Interp *interp,		/* Interpreter used for error reporting. */
+    const char *src,		/* String containing one of the boolean values
+				 * 1, 0, true, false, yes, no, on, off. */
+    int *boolPtr)		/* Place to store converted result, which will
+				 * be 0 or 1. */
+{
+    Tcl_Obj obj;
+    int code;
+
+    obj.refCount = 1;
+    obj.bytes = (char *) src;
+    obj.length = strlen(src);
+    obj.typePtr = NULL;
+
+    code = TclSetBooleanFromAny(interp, &obj);
+    if (obj.refCount > 1) {
+	Tcl_Panic("invalid sharing of Tcl_Obj on C stack");
+    }
+    if (code == TCL_OK) {
+	*boolPtr = obj.internalRep.longValue;
+    }
+    return code;
+}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tclGetDate.y b/generic/tclGetDate.y
new file mode 100644
index 0000000..da4c3fd
--- /dev/null
+++ b/generic/tclGetDate.y
@@ -0,0 +1,1130 @@
+/*
+ * tclGetDate.y --
+ *
+ *	Contains yacc grammar for parsing date and time strings. The output of
+ *	this file should be the file tclDate.c which is used directly in the
+ *	Tcl sources. Note that this file is largely obsolete in Tcl 8.5; it is
+ *	only used when doing free-form date parsing, an ill-defined process
+ *	anyway.
+ *
+ * Copyright (c) 1992-1995 Karl Lehenbauer and Mark Diekhans.
+ * Copyright (c) 1995-1997 Sun Microsystems, Inc.
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+%parse-param {DateInfo* info}
+%lex-param {DateInfo* info}
+%pure-parser
+ /* %error-verbose would be nice, but our token names are meaningless */
+%locations
+
+%{
+/*
+ * tclDate.c --
+ *
+ *	This file is generated from a yacc grammar defined in the file
+ *	tclGetDate.y. It should not be edited directly.
+ *
+ * Copyright (c) 1992-1995 Karl Lehenbauer and Mark Diekhans.
+ * Copyright (c) 1995-1997 Sun Microsystems, Inc.
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ *
+ */
+#include "tclInt.h"
+
+/*
+ * Bison generates several labels that happen to be unused. MS Visual C++
+ * doesn't like that, and complains. Tell it to shut up.
+ */
+
+#ifdef _MSC_VER
+#pragma warning( disable : 4102 )
+#endif /* _MSC_VER */
+
+/*
+ * yyparse will accept a 'struct DateInfo' as its parameter; that's where the
+ * parsed fields will be returned.
+ */
+
+typedef struct DateInfo {
+
+    Tcl_Obj* messages;		/* Error messages */
+    const char* separatrix;	/* String separating messages */
+
+    time_t dateYear;
+    time_t dateMonth;
+    time_t dateDay;
+    int dateHaveDate;
+
+    time_t dateHour;
+    time_t dateMinutes;
+    time_t dateSeconds;
+    int dateMeridian;
+    int dateHaveTime;
+
+    time_t dateTimezone;
+    int dateDSTmode;
+    int dateHaveZone;
+
+    time_t dateRelMonth;
+    time_t dateRelDay;
+    time_t dateRelSeconds;
+    int dateHaveRel;
+
+    time_t dateMonthOrdinal;
+    int dateHaveOrdinalMonth;
+
+    time_t dateDayOrdinal;
+    time_t dateDayNumber;
+    int dateHaveDay;
+
+    const char *dateStart;
+    const char *dateInput;
+    time_t *dateRelPointer;
+
+    int dateDigitCount;
+} DateInfo;
+
+#define YYMALLOC	ckalloc
+#define YYFREE(x)	(ckfree((void*) (x)))
+
+#define yyDSTmode	(info->dateDSTmode)
+#define yyDayOrdinal	(info->dateDayOrdinal)
+#define yyDayNumber	(info->dateDayNumber)
+#define yyMonthOrdinal	(info->dateMonthOrdinal)
+#define yyHaveDate	(info->dateHaveDate)
+#define yyHaveDay	(info->dateHaveDay)
+#define yyHaveOrdinalMonth (info->dateHaveOrdinalMonth)
+#define yyHaveRel	(info->dateHaveRel)
+#define yyHaveTime	(info->dateHaveTime)
+#define yyHaveZone	(info->dateHaveZone)
+#define yyTimezone	(info->dateTimezone)
+#define yyDay		(info->dateDay)
+#define yyMonth		(info->dateMonth)
+#define yyYear		(info->dateYear)
+#define yyHour		(info->dateHour)
+#define yyMinutes	(info->dateMinutes)
+#define yySeconds	(info->dateSeconds)
+#define yyMeridian	(info->dateMeridian)
+#define yyRelMonth	(info->dateRelMonth)
+#define yyRelDay	(info->dateRelDay)
+#define yyRelSeconds	(info->dateRelSeconds)
+#define yyRelPointer	(info->dateRelPointer)
+#define yyInput		(info->dateInput)
+#define yyDigitCount	(info->dateDigitCount)
+
+#define EPOCH		1970
+#define START_OF_TIME	1902
+#define END_OF_TIME	2037
+
+/*
+ * The offset of tm_year of struct tm returned by localtime, gmtime, etc.
+ * Posix requires 1900.
+ */
+
+#define TM_YEAR_BASE	1900
+
+#define HOUR(x)		((int) (60 * x))
+#define SECSPERDAY	(24L * 60L * 60L)
+#define IsLeapYear(x)	((x % 4 == 0) && (x % 100 != 0 || x % 400 == 0))
+
+/*
+ * An entry in the lexical lookup table.
+ */
+
+typedef struct _TABLE {
+    const char *name;
+    int type;
+    time_t value;
+} TABLE;
+
+/*
+ * Daylight-savings mode: on, off, or not yet known.
+ */
+
+typedef enum _DSTMODE {
+    DSTon, DSToff, DSTmaybe
+} DSTMODE;
+
+/*
+ * Meridian: am, pm, or 24-hour style.
+ */
+
+typedef enum _MERIDIAN {
+    MERam, MERpm, MER24
+} MERIDIAN;
+
+%}
+
+%union {
+    time_t Number;
+    enum _MERIDIAN Meridian;
+}
+
+%{
+
+/*
+ * Prototypes of internal functions.
+ */
+
+static int		LookupWord(YYSTYPE* yylvalPtr, char *buff);
+ static void		TclDateerror(YYLTYPE* location,
+				     DateInfo* info, const char *s);
+ static int		TclDatelex(YYSTYPE* yylvalPtr, YYLTYPE* location,
+				   DateInfo* info);
+static time_t		ToSeconds(time_t Hours, time_t Minutes,
+			    time_t Seconds, MERIDIAN Meridian);
+MODULE_SCOPE int	yyparse(DateInfo*);
+
+%}
+
+%token	tAGO
+%token	tDAY
+%token	tDAYZONE
+%token	tID
+%token	tMERIDIAN
+%token	tMONTH
+%token	tMONTH_UNIT
+%token	tSTARDATE
+%token	tSEC_UNIT
+%token	tSNUMBER
+%token	tUNUMBER
+%token	tZONE
+%token	tEPOCH
+%token	tDST
+%token	tISOBASE
+%token	tDAY_UNIT
+%token	tNEXT
+
+%type	<Number>	tDAY
+%type	<Number>	tDAYZONE
+%type	<Number>	tMONTH
+%type	<Number>	tMONTH_UNIT
+%type	<Number>	tDST
+%type	<Number>	tSEC_UNIT
+%type	<Number>	tSNUMBER
+%type	<Number>	tUNUMBER
+%type	<Number>	tZONE
+%type	<Number>	tISOBASE
+%type	<Number>	tDAY_UNIT
+%type	<Number>	unit
+%type	<Number>	sign
+%type	<Number>	tNEXT
+%type	<Number>	tSTARDATE
+%type	<Meridian>	tMERIDIAN
+%type	<Meridian>	o_merid
+
+%%
+
+spec	: /* NULL */
+	| spec item
+	;
+
+item	: time {
+	    yyHaveTime++;
+	}
+	| zone {
+	    yyHaveZone++;
+	}
+	| date {
+	    yyHaveDate++;
+	}
+	| ordMonth {
+	    yyHaveOrdinalMonth++;
+	}
+	| day {
+	    yyHaveDay++;
+	}
+	| relspec {
+	    yyHaveRel++;
+	}
+	| iso {
+	    yyHaveTime++;
+	    yyHaveDate++;
+	}
+	| trek {
+	    yyHaveTime++;
+	    yyHaveDate++;
+	    yyHaveRel++;
+	}
+	| number
+	;
+
+time	: tUNUMBER tMERIDIAN {
+	    yyHour = $1;
+	    yyMinutes = 0;
+	    yySeconds = 0;
+	    yyMeridian = $2;
+	}
+	| tUNUMBER ':' tUNUMBER o_merid {
+	    yyHour = $1;
+	    yyMinutes = $3;
+	    yySeconds = 0;
+	    yyMeridian = $4;
+	}
+	| tUNUMBER ':' tUNUMBER '-' tUNUMBER {
+	    yyHour = $1;
+	    yyMinutes = $3;
+	    yyMeridian = MER24;
+	    yyDSTmode = DSToff;
+	    yyTimezone = ($5 % 100 + ($5 / 100) * 60);
+	    ++yyHaveZone;
+	}
+	| tUNUMBER ':' tUNUMBER ':' tUNUMBER o_merid {
+	    yyHour = $1;
+	    yyMinutes = $3;
+	    yySeconds = $5;
+	    yyMeridian = $6;
+	}
+	| tUNUMBER ':' tUNUMBER ':' tUNUMBER '-' tUNUMBER {
+	    yyHour = $1;
+	    yyMinutes = $3;
+	    yySeconds = $5;
+	    yyMeridian = MER24;
+	    yyDSTmode = DSToff;
+	    yyTimezone = ($7 % 100 + ($7 / 100) * 60);
+	    ++yyHaveZone;
+	}
+	;
+
+zone	: tZONE tDST {
+	    yyTimezone = $1;
+	    yyDSTmode = DSTon;
+	}
+	| tZONE {
+	    yyTimezone = $1;
+	    yyDSTmode = DSToff;
+	}
+	| tDAYZONE {
+	    yyTimezone = $1;
+	    yyDSTmode = DSTon;
+	}
+	;
+
+day	: tDAY {
+	    yyDayOrdinal = 1;
+	    yyDayNumber = $1;
+	}
+	| tDAY ',' {
+	    yyDayOrdinal = 1;
+	    yyDayNumber = $1;
+	}
+	| tUNUMBER tDAY {
+	    yyDayOrdinal = $1;
+	    yyDayNumber = $2;
+	}
+	| sign tUNUMBER tDAY {
+	    yyDayOrdinal = $1 * $2;
+	    yyDayNumber = $3;
+	}
+	| tNEXT tDAY {
+	    yyDayOrdinal = 2;
+	    yyDayNumber = $2;
+	}
+	;
+
+date	: tUNUMBER '/' tUNUMBER {
+	    yyMonth = $1;
+	    yyDay = $3;
+	}
+	| tUNUMBER '/' tUNUMBER '/' tUNUMBER {
+	    yyMonth = $1;
+	    yyDay = $3;
+	    yyYear = $5;
+	}
+	| tISOBASE {
+	    yyYear = $1 / 10000;
+	    yyMonth = ($1 % 10000)/100;
+	    yyDay = $1 % 100;
+	}
+	| tUNUMBER '-' tMONTH '-' tUNUMBER {
+	    yyDay = $1;
+	    yyMonth = $3;
+	    yyYear = $5;
+	}
+	| tUNUMBER '-' tUNUMBER '-' tUNUMBER {
+	    yyMonth = $3;
+	    yyDay = $5;
+	    yyYear = $1;
+	}
+	| tMONTH tUNUMBER {
+	    yyMonth = $1;
+	    yyDay = $2;
+	}
+	| tMONTH tUNUMBER ',' tUNUMBER {
+	    yyMonth = $1;
+	    yyDay = $2;
+	    yyYear = $4;
+	}
+	| tUNUMBER tMONTH {
+	    yyMonth = $2;
+	    yyDay = $1;
+	}
+	| tEPOCH {
+	    yyMonth = 1;
+	    yyDay = 1;
+	    yyYear = EPOCH;
+	}
+	| tUNUMBER tMONTH tUNUMBER {
+	    yyMonth = $2;
+	    yyDay = $1;
+	    yyYear = $3;
+	}
+	;
+
+ordMonth: tNEXT tMONTH {
+	    yyMonthOrdinal = 1;
+	    yyMonth = $2;
+	}
+	| tNEXT tUNUMBER tMONTH {
+	    yyMonthOrdinal = $2;
+	    yyMonth = $3;
+	}
+	;
+
+iso	: tISOBASE tZONE tISOBASE {
+	    if ($2 != HOUR( 7)) YYABORT;
+	    yyYear = $1 / 10000;
+	    yyMonth = ($1 % 10000)/100;
+	    yyDay = $1 % 100;
+	    yyHour = $3 / 10000;
+	    yyMinutes = ($3 % 10000)/100;
+	    yySeconds = $3 % 100;
+	}
+	| tISOBASE tZONE tUNUMBER ':' tUNUMBER ':' tUNUMBER {
+	    if ($2 != HOUR( 7)) YYABORT;
+	    yyYear = $1 / 10000;
+	    yyMonth = ($1 % 10000)/100;
+	    yyDay = $1 % 100;
+	    yyHour = $3;
+	    yyMinutes = $5;
+	    yySeconds = $7;
+	}
+	| tISOBASE tISOBASE {
+	    yyYear = $1 / 10000;
+	    yyMonth = ($1 % 10000)/100;
+	    yyDay = $1 % 100;
+	    yyHour = $2 / 10000;
+	    yyMinutes = ($2 % 10000)/100;
+	    yySeconds = $2 % 100;
+	}
+	;
+
+trek	: tSTARDATE tUNUMBER '.' tUNUMBER {
+	    /*
+	     * Offset computed year by -377 so that the returned years will be
+	     * in a range accessible with a 32 bit clock seconds value.
+	     */
+
+	    yyYear = $2/1000 + 2323 - 377;
+	    yyDay  = 1;
+	    yyMonth = 1;
+	    yyRelDay += (($2%1000)*(365 + IsLeapYear(yyYear)))/1000;
+	    yyRelSeconds += $4 * 144 * 60;
+	}
+	;
+
+relspec : relunits tAGO {
+	    yyRelSeconds *= -1;
+	    yyRelMonth *= -1;
+	    yyRelDay *= -1;
+	}
+	| relunits
+	;
+
+relunits : sign tUNUMBER unit {
+	    *yyRelPointer += $1 * $2 * $3;
+	}
+	| tUNUMBER unit {
+	    *yyRelPointer += $1 * $2;
+	}
+	| tNEXT unit {
+	    *yyRelPointer += $2;
+	}
+	| tNEXT tUNUMBER unit {
+	    *yyRelPointer += $2 * $3;
+	}
+	| unit {
+	    *yyRelPointer += $1;
+	}
+	;
+
+sign	: '-' {
+	    $$ = -1;
+	}
+	| '+' {
+	    $$ =  1;
+	}
+	;
+
+unit	: tSEC_UNIT {
+	    $$ = $1;
+	    yyRelPointer = &yyRelSeconds;
+	}
+	| tDAY_UNIT {
+	    $$ = $1;
+	    yyRelPointer = &yyRelDay;
+	}
+	| tMONTH_UNIT {
+	    $$ = $1;
+	    yyRelPointer = &yyRelMonth;
+	}
+	;
+
+number	: tUNUMBER {
+	    if (yyHaveTime && yyHaveDate && !yyHaveRel) {
+		yyYear = $1;
+	    } else {
+		yyHaveTime++;
+		if (yyDigitCount <= 2) {
+		    yyHour = $1;
+		    yyMinutes = 0;
+		} else {
+		    yyHour = $1 / 100;
+		    yyMinutes = $1 % 100;
+		}
+		yySeconds = 0;
+		yyMeridian = MER24;
+	    }
+	}
+	;
+
+o_merid : /* NULL */ {
+	    $$ = MER24;
+	}
+	| tMERIDIAN {
+	    $$ = $1;
+	}
+	;
+
+%%
+/*
+ * Month and day table.
+ */
+
+static const TABLE MonthDayTable[] = {
+    { "january",	tMONTH,	 1 },
+    { "february",	tMONTH,	 2 },
+    { "march",		tMONTH,	 3 },
+    { "april",		tMONTH,	 4 },
+    { "may",		tMONTH,	 5 },
+    { "june",		tMONTH,	 6 },
+    { "july",		tMONTH,	 7 },
+    { "august",		tMONTH,	 8 },
+    { "september",	tMONTH,	 9 },
+    { "sept",		tMONTH,	 9 },
+    { "october",	tMONTH, 10 },
+    { "november",	tMONTH, 11 },
+    { "december",	tMONTH, 12 },
+    { "sunday",		tDAY, 0 },
+    { "monday",		tDAY, 1 },
+    { "tuesday",	tDAY, 2 },
+    { "tues",		tDAY, 2 },
+    { "wednesday",	tDAY, 3 },
+    { "wednes",		tDAY, 3 },
+    { "thursday",	tDAY, 4 },
+    { "thur",		tDAY, 4 },
+    { "thurs",		tDAY, 4 },
+    { "friday",		tDAY, 5 },
+    { "saturday",	tDAY, 6 },
+    { NULL, 0, 0 }
+};
+
+/*
+ * Time units table.
+ */
+
+static const TABLE UnitsTable[] = {
+    { "year",		tMONTH_UNIT,	12 },
+    { "month",		tMONTH_UNIT,	 1 },
+    { "fortnight",	tDAY_UNIT,	14 },
+    { "week",		tDAY_UNIT,	 7 },
+    { "day",		tDAY_UNIT,	 1 },
+    { "hour",		tSEC_UNIT, 60 * 60 },
+    { "minute",		tSEC_UNIT,	60 },
+    { "min",		tSEC_UNIT,	60 },
+    { "second",		tSEC_UNIT,	 1 },
+    { "sec",		tSEC_UNIT,	 1 },
+    { NULL, 0, 0 }
+};
+
+/*
+ * Assorted relative-time words.
+ */
+
+static const TABLE OtherTable[] = {
+    { "tomorrow",	tDAY_UNIT,	1 },
+    { "yesterday",	tDAY_UNIT,	-1 },
+    { "today",		tDAY_UNIT,	0 },
+    { "now",		tSEC_UNIT,	0 },
+    { "last",		tUNUMBER,	-1 },
+    { "this",		tSEC_UNIT,	0 },
+    { "next",		tNEXT,		1 },
+#if 0
+    { "first",		tUNUMBER,	1 },
+    { "second",		tUNUMBER,	2 },
+    { "third",		tUNUMBER,	3 },
+    { "fourth",		tUNUMBER,	4 },
+    { "fifth",		tUNUMBER,	5 },
+    { "sixth",		tUNUMBER,	6 },
+    { "seventh",	tUNUMBER,	7 },
+    { "eighth",		tUNUMBER,	8 },
+    { "ninth",		tUNUMBER,	9 },
+    { "tenth",		tUNUMBER,	10 },
+    { "eleventh",	tUNUMBER,	11 },
+    { "twelfth",	tUNUMBER,	12 },
+#endif
+    { "ago",		tAGO,		1 },
+    { "epoch",		tEPOCH,		0 },
+    { "stardate",	tSTARDATE,	0 },
+    { NULL, 0, 0 }
+};
+
+/*
+ * The timezone table. (Note: This table was modified to not use any floating
+ * point constants to work around an SGI compiler bug).
+ */
+
+static const TABLE TimezoneTable[] = {
+    { "gmt",	tZONE,	   HOUR( 0) },	    /* Greenwich Mean */
+    { "ut",	tZONE,	   HOUR( 0) },	    /* Universal (Coordinated) */
+    { "utc",	tZONE,	   HOUR( 0) },
+    { "uct",	tZONE,	   HOUR( 0) },	    /* Universal Coordinated Time */
+    { "wet",	tZONE,	   HOUR( 0) },	    /* Western European */
+    { "bst",	tDAYZONE,  HOUR( 0) },	    /* British Summer */
+    { "wat",	tZONE,	   HOUR( 1) },	    /* West Africa */
+    { "at",	tZONE,	   HOUR( 2) },	    /* Azores */
+#if	0
+    /* For completeness.  BST is also British Summer, and GST is
+     * also Guam Standard. */
+    { "bst",	tZONE,	   HOUR( 3) },	    /* Brazil Standard */
+    { "gst",	tZONE,	   HOUR( 3) },	    /* Greenland Standard */
+#endif
+    { "nft",	tZONE,	   HOUR( 7/2) },    /* Newfoundland */
+    { "nst",	tZONE,	   HOUR( 7/2) },    /* Newfoundland Standard */
+    { "ndt",	tDAYZONE,  HOUR( 7/2) },    /* Newfoundland Daylight */
+    { "ast",	tZONE,	   HOUR( 4) },	    /* Atlantic Standard */
+    { "adt",	tDAYZONE,  HOUR( 4) },	    /* Atlantic Daylight */
+    { "est",	tZONE,	   HOUR( 5) },	    /* Eastern Standard */
+    { "edt",	tDAYZONE,  HOUR( 5) },	    /* Eastern Daylight */
+    { "cst",	tZONE,	   HOUR( 6) },	    /* Central Standard */
+    { "cdt",	tDAYZONE,  HOUR( 6) },	    /* Central Daylight */
+    { "mst",	tZONE,	   HOUR( 7) },	    /* Mountain Standard */
+    { "mdt",	tDAYZONE,  HOUR( 7) },	    /* Mountain Daylight */
+    { "pst",	tZONE,	   HOUR( 8) },	    /* Pacific Standard */
+    { "pdt",	tDAYZONE,  HOUR( 8) },	    /* Pacific Daylight */
+    { "yst",	tZONE,	   HOUR( 9) },	    /* Yukon Standard */
+    { "ydt",	tDAYZONE,  HOUR( 9) },	    /* Yukon Daylight */
+    { "hst",	tZONE,	   HOUR(10) },	    /* Hawaii Standard */
+    { "hdt",	tDAYZONE,  HOUR(10) },	    /* Hawaii Daylight */
+    { "cat",	tZONE,	   HOUR(10) },	    /* Central Alaska */
+    { "ahst",	tZONE,	   HOUR(10) },	    /* Alaska-Hawaii Standard */
+    { "nt",	tZONE,	   HOUR(11) },	    /* Nome */
+    { "idlw",	tZONE,	   HOUR(12) },	    /* International Date Line West */
+    { "cet",	tZONE,	  -HOUR( 1) },	    /* Central European */
+    { "cest",	tDAYZONE, -HOUR( 1) },	    /* Central European Summer */
+    { "met",	tZONE,	  -HOUR( 1) },	    /* Middle European */
+    { "mewt",	tZONE,	  -HOUR( 1) },	    /* Middle European Winter */
+    { "mest",	tDAYZONE, -HOUR( 1) },	    /* Middle European Summer */
+    { "swt",	tZONE,	  -HOUR( 1) },	    /* Swedish Winter */
+    { "sst",	tDAYZONE, -HOUR( 1) },	    /* Swedish Summer */
+    { "fwt",	tZONE,	  -HOUR( 1) },	    /* French Winter */
+    { "fst",	tDAYZONE, -HOUR( 1) },	    /* French Summer */
+    { "eet",	tZONE,	  -HOUR( 2) },	    /* Eastern Europe, USSR Zone 1 */
+    { "bt",	tZONE,	  -HOUR( 3) },	    /* Baghdad, USSR Zone 2 */
+    { "it",	tZONE,	  -HOUR( 7/2) },    /* Iran */
+    { "zp4",	tZONE,	  -HOUR( 4) },	    /* USSR Zone 3 */
+    { "zp5",	tZONE,	  -HOUR( 5) },	    /* USSR Zone 4 */
+    { "ist",	tZONE,	  -HOUR(11/2) },    /* Indian Standard */
+    { "zp6",	tZONE,	  -HOUR( 6) },	    /* USSR Zone 5 */
+#if	0
+    /* For completeness.  NST is also Newfoundland Stanard, nad SST is
+     * also Swedish Summer. */
+    { "nst",	tZONE,	  -HOUR(13/2) },    /* North Sumatra */
+    { "sst",	tZONE,	  -HOUR( 7) },	    /* South Sumatra, USSR Zone 6 */
+#endif	/* 0 */
+    { "wast",	tZONE,	  -HOUR( 7) },	    /* West Australian Standard */
+    { "wadt",	tDAYZONE, -HOUR( 7) },	    /* West Australian Daylight */
+    { "jt",	tZONE,	  -HOUR(15/2) },    /* Java (3pm in Cronusland!) */
+    { "cct",	tZONE,	  -HOUR( 8) },	    /* China Coast, USSR Zone 7 */
+    { "jst",	tZONE,	  -HOUR( 9) },	    /* Japan Standard, USSR Zone 8 */
+    { "jdt",	tDAYZONE, -HOUR( 9) },	    /* Japan Daylight */
+    { "kst",	tZONE,	  -HOUR( 9) },	    /* Korea Standard */
+    { "kdt",	tDAYZONE, -HOUR( 9) },	    /* Korea Daylight */
+    { "cast",	tZONE,	  -HOUR(19/2) },    /* Central Australian Standard */
+    { "cadt",	tDAYZONE, -HOUR(19/2) },    /* Central Australian Daylight */
+    { "east",	tZONE,	  -HOUR(10) },	    /* Eastern Australian Standard */
+    { "eadt",	tDAYZONE, -HOUR(10) },	    /* Eastern Australian Daylight */
+    { "gst",	tZONE,	  -HOUR(10) },	    /* Guam Standard, USSR Zone 9 */
+    { "nzt",	tZONE,	  -HOUR(12) },	    /* New Zealand */
+    { "nzst",	tZONE,	  -HOUR(12) },	    /* New Zealand Standard */
+    { "nzdt",	tDAYZONE, -HOUR(12) },	    /* New Zealand Daylight */
+    { "idle",	tZONE,	  -HOUR(12) },	    /* International Date Line East */
+    /* ADDED BY Marco Nijdam */
+    { "dst",	tDST,	  HOUR( 0) },	    /* DST on (hour is ignored) */
+    /* End ADDED */
+    { NULL, 0, 0 }
+};
+
+/*
+ * Military timezone table.
+ */
+
+static const TABLE MilitaryTable[] = {
+    { "a",	tZONE,	-HOUR( 1) },
+    { "b",	tZONE,	-HOUR( 2) },
+    { "c",	tZONE,	-HOUR( 3) },
+    { "d",	tZONE,	-HOUR( 4) },
+    { "e",	tZONE,	-HOUR( 5) },
+    { "f",	tZONE,	-HOUR( 6) },
+    { "g",	tZONE,	-HOUR( 7) },
+    { "h",	tZONE,	-HOUR( 8) },
+    { "i",	tZONE,	-HOUR( 9) },
+    { "k",	tZONE,	-HOUR(10) },
+    { "l",	tZONE,	-HOUR(11) },
+    { "m",	tZONE,	-HOUR(12) },
+    { "n",	tZONE,	HOUR(  1) },
+    { "o",	tZONE,	HOUR(  2) },
+    { "p",	tZONE,	HOUR(  3) },
+    { "q",	tZONE,	HOUR(  4) },
+    { "r",	tZONE,	HOUR(  5) },
+    { "s",	tZONE,	HOUR(  6) },
+    { "t",	tZONE,	HOUR(  7) },
+    { "u",	tZONE,	HOUR(  8) },
+    { "v",	tZONE,	HOUR(  9) },
+    { "w",	tZONE,	HOUR( 10) },
+    { "x",	tZONE,	HOUR( 11) },
+    { "y",	tZONE,	HOUR( 12) },
+    { "z",	tZONE,	HOUR( 0) },
+    { NULL, 0, 0 }
+};
+
+/*
+ * Dump error messages in the bit bucket.
+ */
+
+static void
+TclDateerror(
+    YYLTYPE* location,
+    DateInfo* infoPtr,
+    const char *s)
+{
+    Tcl_Obj* t;
+    Tcl_AppendToObj(infoPtr->messages, infoPtr->separatrix, -1);
+    Tcl_AppendToObj(infoPtr->messages, s, -1);
+    Tcl_AppendToObj(infoPtr->messages, " (characters ", -1);
+    t = Tcl_NewIntObj(location->first_column);
+    Tcl_IncrRefCount(t);
+    Tcl_AppendObjToObj(infoPtr->messages, t);
+    Tcl_DecrRefCount(t);
+    Tcl_AppendToObj(infoPtr->messages, "-", -1);
+    t = Tcl_NewIntObj(location->last_column);
+    Tcl_IncrRefCount(t);
+    Tcl_AppendObjToObj(infoPtr->messages, t);
+    Tcl_DecrRefCount(t);
+    Tcl_AppendToObj(infoPtr->messages, ")", -1);
+    infoPtr->separatrix = "\n";
+}
+
+static time_t
+ToSeconds(
+    time_t Hours,
+    time_t Minutes,
+    time_t Seconds,
+    MERIDIAN Meridian)
+{
+    if (Minutes < 0 || Minutes > 59 || Seconds < 0 || Seconds > 59) {
+	return -1;
+    }
+    switch (Meridian) {
+    case MER24:
+	if (Hours < 0 || Hours > 23) {
+	    return -1;
+	}
+	return (Hours * 60L + Minutes) * 60L + Seconds;
+    case MERam:
+	if (Hours < 1 || Hours > 12) {
+	    return -1;
+	}
+	return ((Hours % 12) * 60L + Minutes) * 60L + Seconds;
+    case MERpm:
+	if (Hours < 1 || Hours > 12) {
+	    return -1;
+	}
+	return (((Hours % 12) + 12) * 60L + Minutes) * 60L + Seconds;
+    }
+    return -1;			/* Should never be reached */
+}
+
+static int
+LookupWord(
+    YYSTYPE* yylvalPtr,
+    char *buff)
+{
+    register char *p;
+    register char *q;
+    register const TABLE *tp;
+    int i, abbrev;
+
+    /*
+     * Make it lowercase.
+     */
+
+    Tcl_UtfToLower(buff);
+
+    if (strcmp(buff, "am") == 0 || strcmp(buff, "a.m.") == 0) {
+	yylvalPtr->Meridian = MERam;
+	return tMERIDIAN;
+    }
+    if (strcmp(buff, "pm") == 0 || strcmp(buff, "p.m.") == 0) {
+	yylvalPtr->Meridian = MERpm;
+	return tMERIDIAN;
+    }
+
+    /*
+     * See if we have an abbreviation for a month.
+     */
+
+    if (strlen(buff) == 3) {
+	abbrev = 1;
+    } else if (strlen(buff) == 4 && buff[3] == '.') {
+	abbrev = 1;
+	buff[3] = '\0';
+    } else {
+	abbrev = 0;
+    }
+
+    for (tp = MonthDayTable; tp->name; tp++) {
+	if (abbrev) {
+	    if (strncmp(buff, tp->name, 3) == 0) {
+		yylvalPtr->Number = tp->value;
+		return tp->type;
+	    }
+	} else if (strcmp(buff, tp->name) == 0) {
+	    yylvalPtr->Number = tp->value;
+	    return tp->type;
+	}
+    }
+
+    for (tp = TimezoneTable; tp->name; tp++) {
+	if (strcmp(buff, tp->name) == 0) {
+	    yylvalPtr->Number = tp->value;
+	    return tp->type;
+	}
+    }
+
+    for (tp = UnitsTable; tp->name; tp++) {
+	if (strcmp(buff, tp->name) == 0) {
+	    yylvalPtr->Number = tp->value;
+	    return tp->type;
+	}
+    }
+
+    /*
+     * Strip off any plural and try the units table again.
+     */
+
+    i = strlen(buff) - 1;
+    if (i > 0 && buff[i] == 's') {
+	buff[i] = '\0';
+	for (tp = UnitsTable; tp->name; tp++) {
+	    if (strcmp(buff, tp->name) == 0) {
+		yylvalPtr->Number = tp->value;
+		return tp->type;
+	    }
+	}
+    }
+
+    for (tp = OtherTable; tp->name; tp++) {
+	if (strcmp(buff, tp->name) == 0) {
+	    yylvalPtr->Number = tp->value;
+	    return tp->type;
+	}
+    }
+
+    /*
+     * Military timezones.
+     */
+
+    if (buff[1] == '\0' && !(*buff & 0x80)
+	    && isalpha(UCHAR(*buff))) {			/* INTL: ISO only */
+	for (tp = MilitaryTable; tp->name; tp++) {
+	    if (strcmp(buff, tp->name) == 0) {
+		yylvalPtr->Number = tp->value;
+		return tp->type;
+	    }
+	}
+    }
+
+    /*
+     * Drop out any periods and try the timezone table again.
+     */
+
+    for (i = 0, p = q = buff; *q; q++) {
+	if (*q != '.') {
+	    *p++ = *q;
+	} else {
+	    i++;
+	}
+    }
+    *p = '\0';
+    if (i) {
+	for (tp = TimezoneTable; tp->name; tp++) {
+	    if (strcmp(buff, tp->name) == 0) {
+		yylvalPtr->Number = tp->value;
+		return tp->type;
+	    }
+	}
+    }
+
+    return tID;
+}
+
+static int
+TclDatelex(
+    YYSTYPE* yylvalPtr,
+    YYLTYPE* location,
+    DateInfo *info)
+{
+    register char c;
+    register char *p;
+    char buff[20];
+    int Count;
+
+    location->first_column = yyInput - info->dateStart;
+    for ( ; ; ) {
+	while (isspace(UCHAR(*yyInput))) {
+	    yyInput++;
+	}
+
+	if (isdigit(UCHAR(c = *yyInput))) { /* INTL: digit */
+	    /*
+	     * Convert the string into a number; count the number of digits.
+	     */
+
+	    Count = 0;
+	    for (yylvalPtr->Number = 0;
+		    isdigit(UCHAR(c = *yyInput++)); ) {	  /* INTL: digit */
+		yylvalPtr->Number = 10 * yylvalPtr->Number + c - '0';
+		Count++;
+	    }
+	    yyInput--;
+	    yyDigitCount = Count;
+
+	    /*
+	     * A number with 6 or more digits is considered an ISO 8601 base.
+	     */
+
+	    if (Count >= 6) {
+		location->last_column = yyInput - info->dateStart - 1;
+		return tISOBASE;
+	    } else {
+		location->last_column = yyInput - info->dateStart - 1;
+		return tUNUMBER;
+	    }
+	}
+	if (!(c & 0x80) && isalpha(UCHAR(c))) {		  /* INTL: ISO only. */
+	    for (p = buff; isalpha(UCHAR(c = *yyInput++)) /* INTL: ISO only. */
+		     || c == '.'; ) {
+		if (p < &buff[sizeof buff - 1]) {
+		    *p++ = c;
+		}
+	    }
+	    *p = '\0';
+	    yyInput--;
+	    location->last_column = yyInput - info->dateStart - 1;
+	    return LookupWord(yylvalPtr, buff);
+	}
+	if (c != '(') {
+	    location->last_column = yyInput - info->dateStart;
+	    return *yyInput++;
+	}
+	Count = 0;
+	do {
+	    c = *yyInput++;
+	    if (c == '\0') {
+		location->last_column = yyInput - info->dateStart - 1;
+		return c;
+	    } else if (c == '(') {
+		Count++;
+	    } else if (c == ')') {
+		Count--;
+	    }
+	} while (Count > 0);
+    }
+}
+
+int
+TclClockOldscanObjCmd(
+    ClientData clientData,	/* Unused */
+    Tcl_Interp *interp,		/* Tcl interpreter */
+    int objc,			/* Count of paraneters */
+    Tcl_Obj *const *objv)	/* Parameters */
+{
+    Tcl_Obj *result, *resultElement;
+    int yr, mo, da;
+    DateInfo dateInfo;
+    DateInfo* info = &dateInfo;
+    int status;
+
+    if (objc != 5) {
+	Tcl_WrongNumArgs(interp, 1, objv,
+		"stringToParse baseYear baseMonth baseDay" );
+	return TCL_ERROR;
+    }
+
+    yyInput = Tcl_GetString( objv[1] );
+    dateInfo.dateStart = yyInput;
+
+    yyHaveDate = 0;
+    if (Tcl_GetIntFromObj(interp, objv[2], &yr) != TCL_OK
+	    || Tcl_GetIntFromObj(interp, objv[3], &mo) != TCL_OK
+	    || Tcl_GetIntFromObj(interp, objv[4], &da) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    yyYear = yr; yyMonth = mo; yyDay = da;
+
+    yyHaveTime = 0;
+    yyHour = 0; yyMinutes = 0; yySeconds = 0; yyMeridian = MER24;
+
+    yyHaveZone = 0;
+    yyTimezone = 0; yyDSTmode = DSTmaybe;
+
+    yyHaveOrdinalMonth = 0;
+    yyMonthOrdinal = 0;
+
+    yyHaveDay = 0;
+    yyDayOrdinal = 0; yyDayNumber = 0;
+
+    yyHaveRel = 0;
+    yyRelMonth = 0; yyRelDay = 0; yyRelSeconds = 0; yyRelPointer = NULL;
+
+    dateInfo.messages = Tcl_NewObj();
+    dateInfo.separatrix = "";
+    Tcl_IncrRefCount(dateInfo.messages);
+
+    status = yyparse(&dateInfo);
+    if (status == 1) {
+	Tcl_SetObjResult(interp, dateInfo.messages);
+	Tcl_DecrRefCount(dateInfo.messages);
+	Tcl_SetErrorCode(interp, "TCL", "VALUE", "DATE", "PARSE", NULL);
+	return TCL_ERROR;
+    } else if (status == 2) {
+	Tcl_SetObjResult(interp, Tcl_NewStringObj("memory exhausted", -1));
+	Tcl_DecrRefCount(dateInfo.messages);
+	Tcl_SetErrorCode(interp, "TCL", "MEMORY", NULL);
+	return TCL_ERROR;
+    } else if (status != 0) {
+	Tcl_SetObjResult(interp, Tcl_NewStringObj("Unknown status returned "
+						  "from date parser. Please "
+						  "report this error as a "
+						  "bug in Tcl.", -1));
+	Tcl_DecrRefCount(dateInfo.messages);
+	Tcl_SetErrorCode(interp, "TCL", "BUG", NULL);
+	return TCL_ERROR;
+    }
+    Tcl_DecrRefCount(dateInfo.messages);
+
+    if (yyHaveDate > 1) {
+	Tcl_SetObjResult(interp,
+		Tcl_NewStringObj("more than one date in string", -1));
+	Tcl_SetErrorCode(interp, "TCL", "VALUE", "DATE", "MULTIPLE", NULL);
+	return TCL_ERROR;
+    }
+    if (yyHaveTime > 1) {
+	Tcl_SetObjResult(interp,
+		Tcl_NewStringObj("more than one time of day in string", -1));
+	Tcl_SetErrorCode(interp, "TCL", "VALUE", "DATE", "MULTIPLE", NULL);
+	return TCL_ERROR;
+    }
+    if (yyHaveZone > 1) {
+	Tcl_SetObjResult(interp,
+		Tcl_NewStringObj("more than one time zone in string", -1));
+	Tcl_SetErrorCode(interp, "TCL", "VALUE", "DATE", "MULTIPLE", NULL);
+	return TCL_ERROR;
+    }
+    if (yyHaveDay > 1) {
+	Tcl_SetObjResult(interp,
+		Tcl_NewStringObj("more than one weekday in string", -1));
+	Tcl_SetErrorCode(interp, "TCL", "VALUE", "DATE", "MULTIPLE", NULL);
+	return TCL_ERROR;
+    }
+    if (yyHaveOrdinalMonth > 1) {
+	Tcl_SetObjResult(interp,
+		Tcl_NewStringObj("more than one ordinal month in string", -1));
+	Tcl_SetErrorCode(interp, "TCL", "VALUE", "DATE", "MULTIPLE", NULL);
+	return TCL_ERROR;
+    }
+
+    result = Tcl_NewObj();
+    resultElement = Tcl_NewObj();
+    if (yyHaveDate) {
+	Tcl_ListObjAppendElement(interp, resultElement,
+		Tcl_NewIntObj((int) yyYear));
+	Tcl_ListObjAppendElement(interp, resultElement,
+		Tcl_NewIntObj((int) yyMonth));
+	Tcl_ListObjAppendElement(interp, resultElement,
+		Tcl_NewIntObj((int) yyDay));
+    }
+    Tcl_ListObjAppendElement(interp, result, resultElement);
+
+    if (yyHaveTime) {
+	Tcl_ListObjAppendElement(interp, result, Tcl_NewIntObj((int)
+		ToSeconds(yyHour, yyMinutes, yySeconds, yyMeridian)));
+    } else {
+	Tcl_ListObjAppendElement(interp, result, Tcl_NewObj());
+    }
+
+    resultElement = Tcl_NewObj();
+    if (yyHaveZone) {
+	Tcl_ListObjAppendElement(interp, resultElement,
+		Tcl_NewIntObj((int) -yyTimezone));
+	Tcl_ListObjAppendElement(interp, resultElement,
+		Tcl_NewIntObj(1 - yyDSTmode));
+    }
+    Tcl_ListObjAppendElement(interp, result, resultElement);
+
+    resultElement = Tcl_NewObj();
+    if (yyHaveRel) {
+	Tcl_ListObjAppendElement(interp, resultElement,
+		Tcl_NewIntObj((int) yyRelMonth));
+	Tcl_ListObjAppendElement(interp, resultElement,
+		Tcl_NewIntObj((int) yyRelDay));
+	Tcl_ListObjAppendElement(interp, resultElement,
+		Tcl_NewIntObj((int) yyRelSeconds));
+    }
+    Tcl_ListObjAppendElement(interp, result, resultElement);
+
+    resultElement = Tcl_NewObj();
+    if (yyHaveDay && !yyHaveDate) {
+	Tcl_ListObjAppendElement(interp, resultElement,
+		Tcl_NewIntObj((int) yyDayOrdinal));
+	Tcl_ListObjAppendElement(interp, resultElement,
+		Tcl_NewIntObj((int) yyDayNumber));
+    }
+    Tcl_ListObjAppendElement(interp, result, resultElement);
+
+    resultElement = Tcl_NewObj();
+    if (yyHaveOrdinalMonth) {
+	Tcl_ListObjAppendElement(interp, resultElement,
+		Tcl_NewIntObj((int) yyMonthOrdinal));
+	Tcl_ListObjAppendElement(interp, resultElement,
+		Tcl_NewIntObj((int) yyMonth));
+    }
+    Tcl_ListObjAppendElement(interp, result, resultElement);
+
+    Tcl_SetObjResult(interp, result);
+    return TCL_OK;
+}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tclHash.c b/generic/tclHash.c
new file mode 100644
index 0000000..1991aea
--- /dev/null
+++ b/generic/tclHash.c
@@ -0,0 +1,1116 @@
+/*
+ * tclHash.c --
+ *
+ *	Implementation of in-memory hash tables for Tcl and Tcl-based
+ *	applications.
+ *
+ * Copyright (c) 1991-1993 The Regents of the University of California.
+ * Copyright (c) 1994 Sun Microsystems, Inc.
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#include "tclInt.h"
+
+/*
+ * Prevent macros from clashing with function definitions.
+ */
+
+#undef Tcl_FindHashEntry
+#undef Tcl_CreateHashEntry
+
+/*
+ * When there are this many entries per bucket, on average, rebuild the hash
+ * table to make it larger.
+ */
+
+#define REBUILD_MULTIPLIER	3
+
+/*
+ * The following macro takes a preliminary integer hash value and produces an
+ * index into a hash tables bucket list. The idea is to make it so that
+ * preliminary values that are arbitrarily similar will end up in different
+ * buckets. The hash function was taken from a random-number generator.
+ */
+
+#define RANDOM_INDEX(tablePtr, i) \
+    ((((i)*1103515245L) >> (tablePtr)->downShift) & (tablePtr)->mask)
+
+/*
+ * Prototypes for the array hash key methods.
+ */
+
+static Tcl_HashEntry *	AllocArrayEntry(Tcl_HashTable *tablePtr, void *keyPtr);
+static int		CompareArrayKeys(void *keyPtr, Tcl_HashEntry *hPtr);
+static unsigned int	HashArrayKey(Tcl_HashTable *tablePtr, void *keyPtr);
+
+/*
+ * Prototypes for the one word hash key methods. Not actually declared because
+ * this is a critical path that is implemented in the core hash table access
+ * function.
+ */
+
+#if 0
+static Tcl_HashEntry *	AllocOneWordEntry(Tcl_HashTable *tablePtr,
+			    void *keyPtr);
+static int		CompareOneWordKeys(void *keyPtr, Tcl_HashEntry *hPtr);
+static unsigned int	HashOneWordKey(Tcl_HashTable *tablePtr, void *keyPtr);
+#endif
+
+/*
+ * Prototypes for the string hash key methods.
+ */
+
+static Tcl_HashEntry *	AllocStringEntry(Tcl_HashTable *tablePtr,
+			    void *keyPtr);
+static int		CompareStringKeys(void *keyPtr, Tcl_HashEntry *hPtr);
+static unsigned int	HashStringKey(Tcl_HashTable *tablePtr, void *keyPtr);
+
+/*
+ * Function prototypes for static functions in this file:
+ */
+
+static Tcl_HashEntry *	BogusFind(Tcl_HashTable *tablePtr, const char *key);
+static Tcl_HashEntry *	BogusCreate(Tcl_HashTable *tablePtr, const char *key,
+			    int *newPtr);
+static Tcl_HashEntry *	CreateHashEntry(Tcl_HashTable *tablePtr, const char *key,
+			    int *newPtr);
+static Tcl_HashEntry *	FindHashEntry(Tcl_HashTable *tablePtr, const char *key);
+static void		RebuildTable(Tcl_HashTable *tablePtr);
+
+const Tcl_HashKeyType tclArrayHashKeyType = {
+    TCL_HASH_KEY_TYPE_VERSION,		/* version */
+    TCL_HASH_KEY_RANDOMIZE_HASH,	/* flags */
+    HashArrayKey,			/* hashKeyProc */
+    CompareArrayKeys,			/* compareKeysProc */
+    AllocArrayEntry,			/* allocEntryProc */
+    NULL				/* freeEntryProc */
+};
+
+const Tcl_HashKeyType tclOneWordHashKeyType = {
+    TCL_HASH_KEY_TYPE_VERSION,		/* version */
+    0,					/* flags */
+    NULL, /* HashOneWordKey, */		/* hashProc */
+    NULL, /* CompareOneWordKey, */	/* compareProc */
+    NULL, /* AllocOneWordKey, */	/* allocEntryProc */
+    NULL  /* FreeOneWordKey, */		/* freeEntryProc */
+};
+
+const Tcl_HashKeyType tclStringHashKeyType = {
+    TCL_HASH_KEY_TYPE_VERSION,		/* version */
+    0,					/* flags */
+    HashStringKey,			/* hashKeyProc */
+    CompareStringKeys,			/* compareKeysProc */
+    AllocStringEntry,			/* allocEntryProc */
+    NULL				/* freeEntryProc */
+};
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_InitHashTable --
+ *
+ *	Given storage for a hash table, set up the fields to prepare the hash
+ *	table for use.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	TablePtr is now ready to be passed to Tcl_FindHashEntry and
+ *	Tcl_CreateHashEntry.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_InitHashTable(
+    register Tcl_HashTable *tablePtr,
+				/* Pointer to table record, which is supplied
+				 * by the caller. */
+    int keyType)		/* Type of keys to use in table:
+				 * TCL_STRING_KEYS, TCL_ONE_WORD_KEYS, or an
+				 * integer >= 2. */
+{
+    /*
+     * Use a special value to inform the extended version that it must not
+     * access any of the new fields in the Tcl_HashTable. If an extension is
+     * rebuilt then any calls to this function will be redirected to the
+     * extended version by a macro.
+     */
+
+    Tcl_InitCustomHashTable(tablePtr, keyType, (const Tcl_HashKeyType *) -1);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_InitCustomHashTable --
+ *
+ *	Given storage for a hash table, set up the fields to prepare the hash
+ *	table for use. This is an extended version of Tcl_InitHashTable which
+ *	supports user defined keys.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	TablePtr is now ready to be passed to Tcl_FindHashEntry and
+ *	Tcl_CreateHashEntry.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_InitCustomHashTable(
+    register Tcl_HashTable *tablePtr,
+				/* Pointer to table record, which is supplied
+				 * by the caller. */
+    int keyType,		/* Type of keys to use in table:
+				 * TCL_STRING_KEYS, TCL_ONE_WORD_KEYS,
+				 * TCL_CUSTOM_TYPE_KEYS, TCL_CUSTOM_PTR_KEYS,
+				 * or an integer >= 2. */
+    const Tcl_HashKeyType *typePtr) /* Pointer to structure which defines the
+				 * behaviour of this table. */
+{
+#if (TCL_SMALL_HASH_TABLE != 4)
+    Tcl_Panic("Tcl_InitCustomHashTable: TCL_SMALL_HASH_TABLE is %d, not 4",
+	    TCL_SMALL_HASH_TABLE);
+#endif
+
+    tablePtr->buckets = tablePtr->staticBuckets;
+    tablePtr->staticBuckets[0] = tablePtr->staticBuckets[1] = 0;
+    tablePtr->staticBuckets[2] = tablePtr->staticBuckets[3] = 0;
+    tablePtr->numBuckets = TCL_SMALL_HASH_TABLE;
+    tablePtr->numEntries = 0;
+    tablePtr->rebuildSize = TCL_SMALL_HASH_TABLE*REBUILD_MULTIPLIER;
+    tablePtr->downShift = 28;
+    tablePtr->mask = 3;
+    tablePtr->keyType = keyType;
+    tablePtr->findProc = FindHashEntry;
+    tablePtr->createProc = CreateHashEntry;
+
+    if (typePtr == NULL) {
+	/*
+	 * The caller has been rebuilt so the hash table is an extended
+	 * version.
+	 */
+    } else if (typePtr != (Tcl_HashKeyType *) -1) {
+	/*
+	 * The caller is requesting a customized hash table so it must be an
+	 * extended version.
+	 */
+
+	tablePtr->typePtr = typePtr;
+    } else {
+	/*
+	 * The caller has not been rebuilt so the hash table is not extended.
+	 */
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_FindHashEntry --
+ *
+ *	Given a hash table find the entry with a matching key.
+ *
+ * Results:
+ *	The return value is a token for the matching entry in the hash table,
+ *	or NULL if there was no matching entry.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_HashEntry *
+Tcl_FindHashEntry(
+    Tcl_HashTable *tablePtr,	/* Table in which to lookup entry. */
+    const void *key)		/* Key to use to find matching entry. */
+{
+    return (*((tablePtr)->findProc))(tablePtr, key);
+}
+
+static Tcl_HashEntry *
+FindHashEntry(
+    Tcl_HashTable *tablePtr,	/* Table in which to lookup entry. */
+    const char *key)		/* Key to use to find matching entry. */
+{
+    return CreateHashEntry(tablePtr, key, NULL);
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_CreateHashEntry --
+ *
+ *	Given a hash table with string keys, and a string key, find the entry
+ *	with a matching key. If there is no matching entry, then create a new
+ *	entry that does match.
+ *
+ * Results:
+ *	The return value is a pointer to the matching entry. If this is a
+ *	newly-created entry, then *newPtr will be set to a non-zero value;
+ *	otherwise *newPtr will be set to 0. If this is a new entry the value
+ *	stored in the entry will initially be 0.
+ *
+ * Side effects:
+ *	A new entry may be added to the hash table.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_HashEntry *
+Tcl_CreateHashEntry(
+    Tcl_HashTable *tablePtr,	/* Table in which to lookup entry. */
+    const void *key,		/* Key to use to find or create matching
+				 * entry. */
+    int *newPtr)		/* Store info here telling whether a new entry
+				 * was created. */
+{
+    return (*((tablePtr)->createProc))(tablePtr, key, newPtr);
+}
+
+static Tcl_HashEntry *
+CreateHashEntry(
+    Tcl_HashTable *tablePtr,	/* Table in which to lookup entry. */
+    const char *key,		/* Key to use to find or create matching
+				 * entry. */
+    int *newPtr)		/* Store info here telling whether a new entry
+				 * was created. */
+{
+    register Tcl_HashEntry *hPtr;
+    const Tcl_HashKeyType *typePtr;
+    unsigned int hash;
+    int index;
+
+    if (tablePtr->keyType == TCL_STRING_KEYS) {
+	typePtr = &tclStringHashKeyType;
+    } else if (tablePtr->keyType == TCL_ONE_WORD_KEYS) {
+	typePtr = &tclOneWordHashKeyType;
+    } else if (tablePtr->keyType == TCL_CUSTOM_TYPE_KEYS
+	    || tablePtr->keyType == TCL_CUSTOM_PTR_KEYS) {
+	typePtr = tablePtr->typePtr;
+    } else {
+	typePtr = &tclArrayHashKeyType;
+    }
+
+    if (typePtr->hashKeyProc) {
+	hash = typePtr->hashKeyProc(tablePtr, (void *) key);
+	if (typePtr->flags & TCL_HASH_KEY_RANDOMIZE_HASH) {
+	    index = RANDOM_INDEX(tablePtr, hash);
+	} else {
+	    index = hash & tablePtr->mask;
+	}
+    } else {
+	hash = PTR2UINT(key);
+	index = RANDOM_INDEX(tablePtr, hash);
+    }
+
+    /*
+     * Search all of the entries in the appropriate bucket.
+     */
+
+    if (typePtr->compareKeysProc) {
+	Tcl_CompareHashKeysProc *compareKeysProc = typePtr->compareKeysProc;
+
+	for (hPtr = tablePtr->buckets[index]; hPtr != NULL;
+		hPtr = hPtr->nextPtr) {
+#if TCL_HASH_KEY_STORE_HASH
+	    if (hash != PTR2UINT(hPtr->hash)) {
+		continue;
+	    }
+#endif
+	    if (((void *) key == hPtr) || compareKeysProc((void *) key, hPtr)) {
+		if (newPtr) {
+		    *newPtr = 0;
+		}
+		return hPtr;
+	    }
+	}
+    } else {
+	for (hPtr = tablePtr->buckets[index]; hPtr != NULL;
+		hPtr = hPtr->nextPtr) {
+#if TCL_HASH_KEY_STORE_HASH
+	    if (hash != PTR2UINT(hPtr->hash)) {
+		continue;
+	    }
+#endif
+	    if (key == hPtr->key.oneWordValue) {
+		if (newPtr) {
+		    *newPtr = 0;
+		}
+		return hPtr;
+	    }
+	}
+    }
+
+    if (!newPtr) {
+	return NULL;
+    }
+
+    /*
+     * Entry not found. Add a new one to the bucket.
+     */
+
+    *newPtr = 1;
+    if (typePtr->allocEntryProc) {
+	hPtr = typePtr->allocEntryProc(tablePtr, (void *) key);
+    } else {
+	hPtr = ckalloc(sizeof(Tcl_HashEntry));
+	hPtr->key.oneWordValue = (char *) key;
+	hPtr->clientData = 0;
+    }
+
+    hPtr->tablePtr = tablePtr;
+#if TCL_HASH_KEY_STORE_HASH
+    hPtr->hash = UINT2PTR(hash);
+    hPtr->nextPtr = tablePtr->buckets[index];
+    tablePtr->buckets[index] = hPtr;
+#else
+    hPtr->bucketPtr = &tablePtr->buckets[index];
+    hPtr->nextPtr = *hPtr->bucketPtr;
+    *hPtr->bucketPtr = hPtr;
+#endif
+    tablePtr->numEntries++;
+
+    /*
+     * If the table has exceeded a decent size, rebuild it with many more
+     * buckets.
+     */
+
+    if (tablePtr->numEntries >= tablePtr->rebuildSize) {
+	RebuildTable(tablePtr);
+    }
+    return hPtr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_DeleteHashEntry --
+ *
+ *	Remove a single entry from a hash table.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The entry given by entryPtr is deleted from its table and should never
+ *	again be used by the caller. It is up to the caller to free the
+ *	clientData field of the entry, if that is relevant.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_DeleteHashEntry(
+    Tcl_HashEntry *entryPtr)
+{
+    register Tcl_HashEntry *prevPtr;
+    const Tcl_HashKeyType *typePtr;
+    Tcl_HashTable *tablePtr;
+    Tcl_HashEntry **bucketPtr;
+#if TCL_HASH_KEY_STORE_HASH
+    int index;
+#endif
+
+    tablePtr = entryPtr->tablePtr;
+
+    if (tablePtr->keyType == TCL_STRING_KEYS) {
+	typePtr = &tclStringHashKeyType;
+    } else if (tablePtr->keyType == TCL_ONE_WORD_KEYS) {
+	typePtr = &tclOneWordHashKeyType;
+    } else if (tablePtr->keyType == TCL_CUSTOM_TYPE_KEYS
+	    || tablePtr->keyType == TCL_CUSTOM_PTR_KEYS) {
+	typePtr = tablePtr->typePtr;
+    } else {
+	typePtr = &tclArrayHashKeyType;
+    }
+
+#if TCL_HASH_KEY_STORE_HASH
+    if (typePtr->hashKeyProc == NULL
+	    || typePtr->flags & TCL_HASH_KEY_RANDOMIZE_HASH) {
+	index = RANDOM_INDEX(tablePtr, PTR2INT(entryPtr->hash));
+    } else {
+	index = PTR2UINT(entryPtr->hash) & tablePtr->mask;
+    }
+
+    bucketPtr = &tablePtr->buckets[index];
+#else
+    bucketPtr = entryPtr->bucketPtr;
+#endif
+
+    if (*bucketPtr == entryPtr) {
+	*bucketPtr = entryPtr->nextPtr;
+    } else {
+	for (prevPtr = *bucketPtr; ; prevPtr = prevPtr->nextPtr) {
+	    if (prevPtr == NULL) {
+		Tcl_Panic("malformed bucket chain in Tcl_DeleteHashEntry");
+	    }
+	    if (prevPtr->nextPtr == entryPtr) {
+		prevPtr->nextPtr = entryPtr->nextPtr;
+		break;
+	    }
+	}
+    }
+
+    tablePtr->numEntries--;
+    if (typePtr->freeEntryProc) {
+	typePtr->freeEntryProc(entryPtr);
+    } else {
+	ckfree(entryPtr);
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_DeleteHashTable --
+ *
+ *	Free up everything associated with a hash table except for the record
+ *	for the table itself.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The hash table is no longer useable.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_DeleteHashTable(
+    register Tcl_HashTable *tablePtr)	/* Table to delete. */
+{
+    register Tcl_HashEntry *hPtr, *nextPtr;
+    const Tcl_HashKeyType *typePtr;
+    int i;
+
+    if (tablePtr->keyType == TCL_STRING_KEYS) {
+	typePtr = &tclStringHashKeyType;
+    } else if (tablePtr->keyType == TCL_ONE_WORD_KEYS) {
+	typePtr = &tclOneWordHashKeyType;
+    } else if (tablePtr->keyType == TCL_CUSTOM_TYPE_KEYS
+	    || tablePtr->keyType == TCL_CUSTOM_PTR_KEYS) {
+	typePtr = tablePtr->typePtr;
+    } else {
+	typePtr = &tclArrayHashKeyType;
+    }
+
+    /*
+     * Free up all the entries in the table.
+     */
+
+    for (i = 0; i < tablePtr->numBuckets; i++) {
+	hPtr = tablePtr->buckets[i];
+	while (hPtr != NULL) {
+	    nextPtr = hPtr->nextPtr;
+	    if (typePtr->freeEntryProc) {
+		typePtr->freeEntryProc(hPtr);
+	    } else {
+		ckfree(hPtr);
+	    }
+	    hPtr = nextPtr;
+	}
+    }
+
+    /*
+     * Free up the bucket array, if it was dynamically allocated.
+     */
+
+    if (tablePtr->buckets != tablePtr->staticBuckets) {
+	if (typePtr->flags & TCL_HASH_KEY_SYSTEM_HASH) {
+	    TclpSysFree((char *) tablePtr->buckets);
+	} else {
+	    ckfree(tablePtr->buckets);
+	}
+    }
+
+    /*
+     * Arrange for panics if the table is used again without
+     * re-initialization.
+     */
+
+    tablePtr->findProc = BogusFind;
+    tablePtr->createProc = BogusCreate;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_FirstHashEntry --
+ *
+ *	Locate the first entry in a hash table and set up a record that can be
+ *	used to step through all the remaining entries of the table.
+ *
+ * Results:
+ *	The return value is a pointer to the first entry in tablePtr, or NULL
+ *	if tablePtr has no entries in it. The memory at *searchPtr is
+ *	initialized so that subsequent calls to Tcl_NextHashEntry will return
+ *	all of the entries in the table, one at a time.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_HashEntry *
+Tcl_FirstHashEntry(
+    Tcl_HashTable *tablePtr,	/* Table to search. */
+    Tcl_HashSearch *searchPtr)	/* Place to store information about progress
+				 * through the table. */
+{
+    searchPtr->tablePtr = tablePtr;
+    searchPtr->nextIndex = 0;
+    searchPtr->nextEntryPtr = NULL;
+    return Tcl_NextHashEntry(searchPtr);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_NextHashEntry --
+ *
+ *	Once a hash table enumeration has been initiated by calling
+ *	Tcl_FirstHashEntry, this function may be called to return successive
+ *	elements of the table.
+ *
+ * Results:
+ *	The return value is the next entry in the hash table being enumerated,
+ *	or NULL if the end of the table is reached.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_HashEntry *
+Tcl_NextHashEntry(
+    register Tcl_HashSearch *searchPtr)
+				/* Place to store information about progress
+				 * through the table. Must have been
+				 * initialized by calling
+				 * Tcl_FirstHashEntry. */
+{
+    Tcl_HashEntry *hPtr;
+    Tcl_HashTable *tablePtr = searchPtr->tablePtr;
+
+    while (searchPtr->nextEntryPtr == NULL) {
+	if (searchPtr->nextIndex >= tablePtr->numBuckets) {
+	    return NULL;
+	}
+	searchPtr->nextEntryPtr =
+		tablePtr->buckets[searchPtr->nextIndex];
+	searchPtr->nextIndex++;
+    }
+    hPtr = searchPtr->nextEntryPtr;
+    searchPtr->nextEntryPtr = hPtr->nextPtr;
+    return hPtr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_HashStats --
+ *
+ *	Return statistics describing the layout of the hash table in its hash
+ *	buckets.
+ *
+ * Results:
+ *	The return value is a malloc-ed string containing information about
+ *	tablePtr. It is the caller's responsibility to free this string.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+char *
+Tcl_HashStats(
+    Tcl_HashTable *tablePtr)	/* Table for which to produce stats. */
+{
+#define NUM_COUNTERS 10
+    int count[NUM_COUNTERS], overflow, i, j;
+    double average, tmp;
+    register Tcl_HashEntry *hPtr;
+    char *result, *p;
+
+    /*
+     * Compute a histogram of bucket usage.
+     */
+
+    for (i = 0; i < NUM_COUNTERS; i++) {
+	count[i] = 0;
+    }
+    overflow = 0;
+    average = 0.0;
+    for (i = 0; i < tablePtr->numBuckets; i++) {
+	j = 0;
+	for (hPtr = tablePtr->buckets[i]; hPtr != NULL; hPtr = hPtr->nextPtr) {
+	    j++;
+	}
+	if (j < NUM_COUNTERS) {
+	    count[j]++;
+	} else {
+	    overflow++;
+	}
+	tmp = j;
+	if (tablePtr->numEntries != 0) {
+	    average += (tmp+1.0)*(tmp/tablePtr->numEntries)/2.0;
+	}
+    }
+
+    /*
+     * Print out the histogram and a few other pieces of information.
+     */
+
+    result = ckalloc((NUM_COUNTERS * 60) + 300);
+    sprintf(result, "%d entries in table, %d buckets\n",
+	    tablePtr->numEntries, tablePtr->numBuckets);
+    p = result + strlen(result);
+    for (i = 0; i < NUM_COUNTERS; i++) {
+	sprintf(p, "number of buckets with %d entries: %d\n",
+		i, count[i]);
+	p += strlen(p);
+    }
+    sprintf(p, "number of buckets with %d or more entries: %d\n",
+	    NUM_COUNTERS, overflow);
+    p += strlen(p);
+    sprintf(p, "average search distance for entry: %.1f", average);
+    return result;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * AllocArrayEntry --
+ *
+ *	Allocate space for a Tcl_HashEntry containing the array key.
+ *
+ * Results:
+ *	The return value is a pointer to the created entry.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static Tcl_HashEntry *
+AllocArrayEntry(
+    Tcl_HashTable *tablePtr,	/* Hash table. */
+    void *keyPtr)		/* Key to store in the hash table entry. */
+{
+    int *array = (int *) keyPtr;
+    register int *iPtr1, *iPtr2;
+    Tcl_HashEntry *hPtr;
+    int count;
+    unsigned int size;
+
+    count = tablePtr->keyType;
+
+    size = sizeof(Tcl_HashEntry) + (count*sizeof(int)) - sizeof(hPtr->key);
+    if (size < sizeof(Tcl_HashEntry)) {
+	size = sizeof(Tcl_HashEntry);
+    }
+    hPtr = ckalloc(size);
+
+    for (iPtr1 = array, iPtr2 = hPtr->key.words;
+	    count > 0; count--, iPtr1++, iPtr2++) {
+	*iPtr2 = *iPtr1;
+    }
+    hPtr->clientData = 0;
+
+    return hPtr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * CompareArrayKeys --
+ *
+ *	Compares two array keys.
+ *
+ * Results:
+ *	The return value is 0 if they are different and 1 if they are the
+ *	same.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+CompareArrayKeys(
+    void *keyPtr,		/* New key to compare. */
+    Tcl_HashEntry *hPtr)	/* Existing key to compare. */
+{
+    register const int *iPtr1 = (const int *) keyPtr;
+    register const int *iPtr2 = (const int *) hPtr->key.words;
+    Tcl_HashTable *tablePtr = hPtr->tablePtr;
+    int count;
+
+    for (count = tablePtr->keyType; ; count--, iPtr1++, iPtr2++) {
+	if (count == 0) {
+	    return 1;
+	}
+	if (*iPtr1 != *iPtr2) {
+	    break;
+	}
+    }
+    return 0;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * HashArrayKey --
+ *
+ *	Compute a one-word summary of an array, which can be used to generate
+ *	a hash index.
+ *
+ * Results:
+ *	The return value is a one-word summary of the information in
+ *	string.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static unsigned int
+HashArrayKey(
+    Tcl_HashTable *tablePtr,	/* Hash table. */
+    void *keyPtr)		/* Key from which to compute hash value. */
+{
+    register const int *array = (const int *) keyPtr;
+    register unsigned int result;
+    int count;
+
+    for (result = 0, count = tablePtr->keyType; count > 0;
+	    count--, array++) {
+	result += *array;
+    }
+    return result;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * AllocStringEntry --
+ *
+ *	Allocate space for a Tcl_HashEntry containing the string key.
+ *
+ * Results:
+ *	The return value is a pointer to the created entry.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static Tcl_HashEntry *
+AllocStringEntry(
+    Tcl_HashTable *tablePtr,	/* Hash table. */
+    void *keyPtr)		/* Key to store in the hash table entry. */
+{
+    const char *string = (const char *) keyPtr;
+    Tcl_HashEntry *hPtr;
+    unsigned int size, allocsize;
+
+    allocsize = size = strlen(string) + 1;
+    if (size < sizeof(hPtr->key)) {
+	allocsize = sizeof(hPtr->key);
+    }
+    hPtr = ckalloc(TclOffset(Tcl_HashEntry, key) + allocsize);
+    memcpy(hPtr->key.string, string, size);
+    hPtr->clientData = 0;
+    return hPtr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * CompareStringKeys --
+ *
+ *	Compares two string keys.
+ *
+ * Results:
+ *	The return value is 0 if they are different and 1 if they are the
+ *	same.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+CompareStringKeys(
+    void *keyPtr,		/* New key to compare. */
+    Tcl_HashEntry *hPtr)	/* Existing key to compare. */
+{
+    register const char *p1 = (const char *) keyPtr;
+    register const char *p2 = (const char *) hPtr->key.string;
+
+    return !strcmp(p1, p2);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * HashStringKey --
+ *
+ *	Compute a one-word summary of a text string, which can be used to
+ *	generate a hash index.
+ *
+ * Results:
+ *	The return value is a one-word summary of the information in string.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static unsigned
+HashStringKey(
+    Tcl_HashTable *tablePtr,	/* Hash table. */
+    void *keyPtr)		/* Key from which to compute hash value. */
+{
+    register const char *string = keyPtr;
+    register unsigned int result;
+    register char c;
+
+    /*
+     * I tried a zillion different hash functions and asked many other people
+     * for advice. Many people had their own favorite functions, all
+     * different, but no-one had much idea why they were good ones. I chose
+     * the one below (multiply by 9 and add new character) because of the
+     * following reasons:
+     *
+     * 1. Multiplying by 10 is perfect for keys that are decimal strings, and
+     *    multiplying by 9 is just about as good.
+     * 2. Times-9 is (shift-left-3) plus (old). This means that each
+     *    character's bits hang around in the low-order bits of the hash value
+     *    for ever, plus they spread fairly rapidly up to the high-order bits
+     *    to fill out the hash value. This seems works well both for decimal
+     *    and non-decimal strings, but isn't strong against maliciously-chosen
+     *    keys.
+     *
+     * Note that this function is very weak against malicious strings; it's
+     * very easy to generate multiple keys that have the same hashcode. On the
+     * other hand, that hardly ever actually occurs and this function *is*
+     * very cheap, even by comparison with industry-standard hashes like FNV.
+     * If real strength of hash is required though, use a custom hash based on
+     * Bob Jenkins's lookup3(), but be aware that it's significantly slower.
+     * Since Tcl command and namespace names are usually reasonably-named (the
+     * main use for string hashes in modern Tcl) speed is far more important
+     * than strength.
+     *
+     * See also HashString in tclLiteral.c.
+     * See also TclObjHashKey in tclObj.c.
+     *
+     * See [tcl-Feature Request #2958832]
+     */
+
+    if ((result = UCHAR(*string)) != 0) {
+	while ((c = *++string) != 0) {
+	    result += (result << 3) + UCHAR(c);
+	}
+    }
+    return result;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * BogusFind --
+ *
+ *	This function is invoked when an Tcl_FindHashEntry is called on a
+ *	table that has been deleted.
+ *
+ * Results:
+ *	If Tcl_Panic returns (which it shouldn't) this function returns NULL.
+ *
+ * Side effects:
+ *	Generates a panic.
+ *
+ *----------------------------------------------------------------------
+ */
+
+	/* ARGSUSED */
+static Tcl_HashEntry *
+BogusFind(
+    Tcl_HashTable *tablePtr,	/* Table in which to lookup entry. */
+    const char *key)		/* Key to use to find matching entry. */
+{
+    Tcl_Panic("called %s on deleted table", "Tcl_FindHashEntry");
+    return NULL;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * BogusCreate --
+ *
+ *	This function is invoked when an Tcl_CreateHashEntry is called on a
+ *	table that has been deleted.
+ *
+ * Results:
+ *	If panic returns (which it shouldn't) this function returns NULL.
+ *
+ * Side effects:
+ *	Generates a panic.
+ *
+ *----------------------------------------------------------------------
+ */
+
+	/* ARGSUSED */
+static Tcl_HashEntry *
+BogusCreate(
+    Tcl_HashTable *tablePtr,	/* Table in which to lookup entry. */
+    const char *key,		/* Key to use to find or create matching
+				 * entry. */
+    int *newPtr)		/* Store info here telling whether a new entry
+				 * was created. */
+{
+    Tcl_Panic("called %s on deleted table", "Tcl_CreateHashEntry");
+    return NULL;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * RebuildTable --
+ *
+ *	This function is invoked when the ratio of entries to hash buckets
+ *	becomes too large. It creates a new table with a larger bucket array
+ *	and moves all of the entries into the new table.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Memory gets reallocated and entries get re-hashed to new buckets.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+RebuildTable(
+    register Tcl_HashTable *tablePtr)	/* Table to enlarge. */
+{
+    int oldSize, count, index;
+    Tcl_HashEntry **oldBuckets;
+    register Tcl_HashEntry **oldChainPtr, **newChainPtr;
+    register Tcl_HashEntry *hPtr;
+    const Tcl_HashKeyType *typePtr;
+
+    if (tablePtr->keyType == TCL_STRING_KEYS) {
+	typePtr = &tclStringHashKeyType;
+    } else if (tablePtr->keyType == TCL_ONE_WORD_KEYS) {
+	typePtr = &tclOneWordHashKeyType;
+    } else if (tablePtr->keyType == TCL_CUSTOM_TYPE_KEYS
+	    || tablePtr->keyType == TCL_CUSTOM_PTR_KEYS) {
+	typePtr = tablePtr->typePtr;
+    } else {
+	typePtr = &tclArrayHashKeyType;
+    }
+
+    oldSize = tablePtr->numBuckets;
+    oldBuckets = tablePtr->buckets;
+
+    /*
+     * Allocate and initialize the new bucket array, and set up hashing
+     * constants for new array size.
+     */
+
+    tablePtr->numBuckets *= 4;
+    if (typePtr->flags & TCL_HASH_KEY_SYSTEM_HASH) {
+	tablePtr->buckets = (Tcl_HashEntry **) TclpSysAlloc((unsigned)
+		(tablePtr->numBuckets * sizeof(Tcl_HashEntry *)), 0);
+    } else {
+	tablePtr->buckets =
+		ckalloc(tablePtr->numBuckets * sizeof(Tcl_HashEntry *));
+    }
+    for (count = tablePtr->numBuckets, newChainPtr = tablePtr->buckets;
+	    count > 0; count--, newChainPtr++) {
+	*newChainPtr = NULL;
+    }
+    tablePtr->rebuildSize *= 4;
+    tablePtr->downShift -= 2;
+    tablePtr->mask = (tablePtr->mask << 2) + 3;
+
+    /*
+     * Rehash all of the existing entries into the new bucket array.
+     */
+
+    for (oldChainPtr = oldBuckets; oldSize > 0; oldSize--, oldChainPtr++) {
+	for (hPtr = *oldChainPtr; hPtr != NULL; hPtr = *oldChainPtr) {
+	    *oldChainPtr = hPtr->nextPtr;
+#if TCL_HASH_KEY_STORE_HASH
+	    if (typePtr->hashKeyProc == NULL
+		    || typePtr->flags & TCL_HASH_KEY_RANDOMIZE_HASH) {
+		index = RANDOM_INDEX(tablePtr, PTR2INT(hPtr->hash));
+	    } else {
+		index = PTR2UINT(hPtr->hash) & tablePtr->mask;
+	    }
+	    hPtr->nextPtr = tablePtr->buckets[index];
+	    tablePtr->buckets[index] = hPtr;
+#else
+	    void *key = Tcl_GetHashKey(tablePtr, hPtr);
+
+	    if (typePtr->hashKeyProc) {
+		unsigned int hash;
+
+		hash = typePtr->hashKeyProc(tablePtr, key);
+		if (typePtr->flags & TCL_HASH_KEY_RANDOMIZE_HASH) {
+		    index = RANDOM_INDEX(tablePtr, hash);
+		} else {
+		    index = hash & tablePtr->mask;
+		}
+	    } else {
+		index = RANDOM_INDEX(tablePtr, key);
+	    }
+
+	    hPtr->bucketPtr = &tablePtr->buckets[index];
+	    hPtr->nextPtr = *hPtr->bucketPtr;
+	    *hPtr->bucketPtr = hPtr;
+#endif
+	}
+    }
+
+    /*
+     * Free up the old bucket array, if it was dynamically allocated.
+     */
+
+    if (oldBuckets != tablePtr->staticBuckets) {
+	if (typePtr->flags & TCL_HASH_KEY_SYSTEM_HASH) {
+	    TclpSysFree((char *) oldBuckets);
+	} else {
+	    ckfree(oldBuckets);
+	}
+    }
+}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tclHistory.c b/generic/tclHistory.c
new file mode 100644
index 0000000..b08e352
--- /dev/null
+++ b/generic/tclHistory.c
@@ -0,0 +1,230 @@
+/*
+ * tclHistory.c --
+ *
+ *	This module and the Tcl library file history.tcl together implement
+ *	Tcl command history. Tcl_RecordAndEval(Obj) can be called to record
+ *	commands ("events") before they are executed. Commands defined in
+ *	history.tcl may be used to perform history substitutions.
+ *
+ * Copyright (c) 1990-1993 The Regents of the University of California.
+ * Copyright (c) 1994-1997 Sun Microsystems, Inc.
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#include "tclInt.h"
+
+/*
+ * Type of the assocData structure used to hold the reference to the [history
+ * add] subcommand, used in Tcl_RecordAndEvalObj.
+ */
+
+typedef struct {
+    Tcl_Obj *historyObj;	/* == "::history" */
+    Tcl_Obj *addObj;		/* == "add" */
+} HistoryObjs;
+
+#define HISTORY_OBJS_KEY	"::tcl::HistoryObjs"
+
+/*
+ * Static functions in this file.
+ */
+
+static Tcl_InterpDeleteProc DeleteHistoryObjs;
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_RecordAndEval --
+ *
+ *	This procedure adds its command argument to the current list of
+ *	recorded events and then executes the command by calling Tcl_Eval.
+ *
+ * Results:
+ *	The return value is a standard Tcl return value, the result of
+ *	executing cmd.
+ *
+ * Side effects:
+ *	The command is recorded and executed.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_RecordAndEval(
+    Tcl_Interp *interp,		/* Token for interpreter in which command will
+				 * be executed. */
+    const char *cmd,		/* Command to record. */
+    int flags)			/* Additional flags. TCL_NO_EVAL means only
+				 * record: don't execute command.
+				 * TCL_EVAL_GLOBAL means use Tcl_GlobalEval
+				 * instead of Tcl_Eval. */
+{
+    register Tcl_Obj *cmdPtr;
+    int length = strlen(cmd);
+    int result;
+
+    if (length > 0) {
+	/*
+	 * Call Tcl_RecordAndEvalObj to do the actual work.
+	 */
+
+	cmdPtr = Tcl_NewStringObj(cmd, length);
+	Tcl_IncrRefCount(cmdPtr);
+	result = Tcl_RecordAndEvalObj(interp, cmdPtr, flags);
+
+	/*
+	 * Move the interpreter's object result to the string result, then
+	 * reset the object result.
+	 */
+
+	(void) Tcl_GetStringResult(interp);
+
+	/*
+	 * Discard the Tcl object created to hold the command.
+	 */
+
+	Tcl_DecrRefCount(cmdPtr);
+    } else {
+	/*
+	 * An empty string. Just reset the interpreter's result.
+	 */
+
+	Tcl_ResetResult(interp);
+	result = TCL_OK;
+    }
+    return result;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_RecordAndEvalObj --
+ *
+ *	This procedure adds the command held in its argument object to the
+ *	current list of recorded events and then executes the command by
+ *	calling Tcl_EvalObj.
+ *
+ * Results:
+ *	The return value is a standard Tcl return value, the result of
+ *	executing the command.
+ *
+ * Side effects:
+ *	The command is recorded and executed.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_RecordAndEvalObj(
+    Tcl_Interp *interp,		/* Token for interpreter in which command will
+				 * be executed. */
+    Tcl_Obj *cmdPtr,		/* Points to object holding the command to
+				 * record and execute. */
+    int flags)			/* Additional flags. TCL_NO_EVAL means record
+				 * only: don't execute the command.
+				 * TCL_EVAL_GLOBAL means evaluate the script
+				 * in global variable context instead of the
+				 * current procedure. */
+{
+    int result, call = 1;
+    Tcl_CmdInfo info;
+    HistoryObjs *histObjsPtr =
+	    Tcl_GetAssocData(interp, HISTORY_OBJS_KEY, NULL);
+
+    /*
+     * Create the references to the [::history add] command if necessary.
+     */
+
+    if (histObjsPtr == NULL) {
+	histObjsPtr = ckalloc(sizeof(HistoryObjs));
+	TclNewLiteralStringObj(histObjsPtr->historyObj, "::history");
+	TclNewLiteralStringObj(histObjsPtr->addObj, "add");
+	Tcl_IncrRefCount(histObjsPtr->historyObj);
+	Tcl_IncrRefCount(histObjsPtr->addObj);
+	Tcl_SetAssocData(interp, HISTORY_OBJS_KEY, DeleteHistoryObjs,
+		histObjsPtr);
+    }
+
+    /*
+     * Do not call [history] if it has been replaced by an empty proc
+     */
+
+    result = Tcl_GetCommandInfo(interp, "::history", &info);
+    if (result && (info.deleteProc == TclProcDeleteProc)) {
+	Proc *procPtr = (Proc *) info.objClientData;
+	call = (procPtr->cmdPtr->compileProc != TclCompileNoOp);
+    }
+
+    if (call) {
+	Tcl_Obj *list[3];
+
+	/*
+	 * Do recording by eval'ing a tcl history command: history add $cmd.
+	 */
+
+	list[0] = histObjsPtr->historyObj;
+	list[1] = histObjsPtr->addObj;
+	list[2] = cmdPtr;
+
+	Tcl_IncrRefCount(cmdPtr);
+	(void) Tcl_EvalObjv(interp, 3, list, TCL_EVAL_GLOBAL);
+	Tcl_DecrRefCount(cmdPtr);
+
+	/*
+	 * One possible failure mode above: exceeding a resource limit.
+	 */
+
+	if (Tcl_LimitExceeded(interp)) {
+	    return TCL_ERROR;
+	}
+    }
+
+    /*
+     * Execute the command.
+     */
+
+    result = TCL_OK;
+    if (!(flags & TCL_NO_EVAL)) {
+	result = Tcl_EvalObjEx(interp, cmdPtr, flags & TCL_EVAL_GLOBAL);
+    }
+    return result;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * DeleteHistoryObjs --
+ *
+ *	Called to delete the references to the constant words used when adding
+ *	to the history.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The constant words may be deleted.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+DeleteHistoryObjs(
+    ClientData clientData,
+    Tcl_Interp *interp)
+{
+    register HistoryObjs *histObjsPtr = clientData;
+
+    TclDecrRefCount(histObjsPtr->historyObj);
+    TclDecrRefCount(histObjsPtr->addObj);
+    ckfree(histObjsPtr);
+}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tclIO.c b/generic/tclIO.c
new file mode 100644
index 0000000..80f6fa4
--- /dev/null
+++ b/generic/tclIO.c
@@ -0,0 +1,11250 @@
+/*
+ * tclIO.c --
+ *
+ *	This file provides the generic portions (those that are the same on
+ *	all platforms and for all channel types) of Tcl's IO facilities.
+ *
+ * Copyright (c) 1998-2000 Ajuba Solutions
+ * Copyright (c) 1995-1997 Sun Microsystems, Inc.
+ * Contributions from Don Porter, NIST, 2014. (not subject to US copyright)
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#include "tclInt.h"
+#include "tclIO.h"
+#include <assert.h>
+
+/*
+ * For each channel handler registered in a call to Tcl_CreateChannelHandler,
+ * there is one record of the following type. All of records for a specific
+ * channel are chained together in a singly linked list which is stored in
+ * the channel structure.
+ */
+
+typedef struct ChannelHandler {
+    Channel *chanPtr;		/* The channel structure for this channel. */
+    int mask;			/* Mask of desired events. */
+    Tcl_ChannelProc *proc;	/* Procedure to call in the type of
+				 * Tcl_CreateChannelHandler. */
+    ClientData clientData;	/* Argument to pass to procedure. */
+    struct ChannelHandler *nextPtr;
+				/* Next one in list of registered handlers. */
+} ChannelHandler;
+
+/*
+ * This structure keeps track of the current ChannelHandler being invoked in
+ * the current invocation of Tcl_NotifyChannel. There is a potential
+ * problem if a ChannelHandler is deleted while it is the current one, since
+ * Tcl_NotifyChannel needs to look at the nextPtr field. To handle this
+ * problem, structures of the type below indicate the next handler to be
+ * processed for any (recursively nested) dispatches in progress. The
+ * nextHandlerPtr field is updated if the handler being pointed to is deleted.
+ * The nestedHandlerPtr field is used to chain together all recursive
+ * invocations, so that Tcl_DeleteChannelHandler can find all the recursively
+ * nested invocations of Tcl_NotifyChannel and compare the handler being
+ * deleted against the NEXT handler to be invoked in that invocation; when it
+ * finds such a situation, Tcl_DeleteChannelHandler updates the nextHandlerPtr
+ * field of the structure to the next handler.
+ */
+
+typedef struct NextChannelHandler {
+    ChannelHandler *nextHandlerPtr;	/* The next handler to be invoked in
+					 * this invocation. */
+    struct NextChannelHandler *nestedHandlerPtr;
+					/* Next nested invocation of
+					 * Tcl_NotifyChannel. */
+} NextChannelHandler;
+
+/*
+ * The following structure is used by Tcl_GetsObj() to encapsulates the
+ * state for a "gets" operation.
+ */
+
+typedef struct GetsState {
+    Tcl_Obj *objPtr;		/* The object to which UTF-8 characters
+				 * will be appended. */
+    char **dstPtr;		/* Pointer into objPtr's string rep where
+				 * next character should be stored. */
+    Tcl_Encoding encoding;	/* The encoding to use to convert raw bytes
+				 * to UTF-8.  */
+    ChannelBuffer *bufPtr;	/* The current buffer of raw bytes being
+				 * emptied. */
+    Tcl_EncodingState state;	/* The encoding state just before the last
+				 * external to UTF-8 conversion in
+				 * FilterInputBytes(). */
+    int rawRead;		/* The number of bytes removed from bufPtr
+				 * in the last call to FilterInputBytes(). */
+    int bytesWrote;		/* The number of bytes of UTF-8 data
+				 * appended to objPtr during the last call to
+				 * FilterInputBytes(). */
+    int charsWrote;		/* The corresponding number of UTF-8
+				 * characters appended to objPtr during the
+				 * last call to FilterInputBytes(). */
+    int totalChars;		/* The total number of UTF-8 characters
+				 * appended to objPtr so far, just before the
+				 * last call to FilterInputBytes(). */
+} GetsState;
+
+/*
+ * The following structure encapsulates the state for a background channel
+ * copy.  Note that the data buffer for the copy will be appended to this
+ * structure.
+ */
+
+typedef struct CopyState {
+    struct Channel *readPtr;	/* Pointer to input channel. */
+    struct Channel *writePtr;	/* Pointer to output channel. */
+    int readFlags;		/* Original read channel flags. */
+    int writeFlags;		/* Original write channel flags. */
+    Tcl_WideInt toRead;		/* Number of bytes to copy, or -1. */
+    Tcl_WideInt total;		/* Total bytes transferred (written). */
+    Tcl_Interp *interp;		/* Interp that started the copy. */
+    Tcl_Obj *cmdPtr;		/* Command to be invoked at completion. */
+    int bufSize;		/* Size of appended buffer. */
+    char buffer[1];		/* Copy buffer, this must be the last
+                                 * field. */
+} CopyState;
+
+/*
+ * All static variables used in this file are collected into a single instance
+ * of the following structure. For multi-threaded implementations, there is
+ * one instance of this structure for each thread.
+ *
+ * Notice that different structures with the same name appear in other files.
+ * The structure defined below is used in this file only.
+ */
+
+typedef struct ThreadSpecificData {
+    NextChannelHandler *nestedHandlerPtr;
+				/* This variable holds the list of nested
+				 * Tcl_NotifyChannel invocations. */
+    ChannelState *firstCSPtr;	/* List of all channels currently open,
+				 * indexed by ChannelState, as only one
+				 * ChannelState exists per set of stacked
+				 * channels. */
+    Tcl_Channel stdinChannel;	/* Static variable for the stdin channel. */
+    int stdinInitialized;
+    Tcl_Channel stdoutChannel;	/* Static variable for the stdout channel. */
+    int stdoutInitialized;
+    Tcl_Channel stderrChannel;	/* Static variable for the stderr channel. */
+    int stderrInitialized;
+    Tcl_Encoding binaryEncoding;
+} ThreadSpecificData;
+
+static Tcl_ThreadDataKey dataKey;
+
+/*
+ * Structure to record a close callback. One such record exists for
+ * each close callback registered for a channel.
+ */
+
+typedef struct CloseCallback {
+    Tcl_CloseProc *proc;		/* The procedure to call. */
+    ClientData clientData;		/* Arbitrary one-word data to pass
+					 * to the callback. */
+    struct CloseCallback *nextPtr;	/* For chaining close callbacks. */
+} CloseCallback;
+
+/*
+ * Static functions in this file:
+ */
+
+static ChannelBuffer *	AllocChannelBuffer(int length);
+static void		PreserveChannelBuffer(ChannelBuffer *bufPtr);
+static void		ReleaseChannelBuffer(ChannelBuffer *bufPtr);
+static int		IsShared(ChannelBuffer *bufPtr);
+static void		ChannelFree(Channel *chanPtr);
+static void		ChannelTimerProc(ClientData clientData);
+static int		ChanRead(Channel *chanPtr, char *dst, int dstSize);
+static int		CheckChannelErrors(ChannelState *statePtr,
+			    int direction);
+static int		CheckForDeadChannel(Tcl_Interp *interp,
+			    ChannelState *statePtr);
+static void		CheckForStdChannelsBeingClosed(Tcl_Channel chan);
+static void		CleanupChannelHandlers(Tcl_Interp *interp,
+			    Channel *chanPtr);
+static int		CloseChannel(Tcl_Interp *interp, Channel *chanPtr,
+			    int errorCode);
+static int		CloseChannelPart(Tcl_Interp *interp, Channel *chanPtr,
+			    int errorCode, int flags);
+static int		CloseWrite(Tcl_Interp *interp, Channel *chanPtr);
+static void		CommonGetsCleanup(Channel *chanPtr);
+static int		CopyData(CopyState *csPtr, int mask);
+static int		MoveBytes(CopyState *csPtr);
+
+static void		MBCallback(CopyState *csPtr, Tcl_Obj *errObj);
+static void		MBError(CopyState *csPtr, int mask, int errorCode);
+static int		MBRead(CopyState *csPtr);
+static int		MBWrite(CopyState *csPtr);
+static void		MBEvent(ClientData clientData, int mask);
+
+static void		CopyEventProc(ClientData clientData, int mask);
+static void		CreateScriptRecord(Tcl_Interp *interp,
+			    Channel *chanPtr, int mask, Tcl_Obj *scriptPtr);
+static void		DeleteChannelTable(ClientData clientData,
+			    Tcl_Interp *interp);
+static void		DeleteScriptRecord(Tcl_Interp *interp,
+			    Channel *chanPtr, int mask);
+static int		DetachChannel(Tcl_Interp *interp, Tcl_Channel chan);
+static void		DiscardInputQueued(ChannelState *statePtr,
+			    int discardSavedBuffers);
+static void		DiscardOutputQueued(ChannelState *chanPtr);
+static int		DoRead(Channel *chanPtr, char *dst, int bytesToRead,
+			    int allowShortReads);
+static int		DoReadChars(Channel *chan, Tcl_Obj *objPtr, int toRead,
+			    int appendFlag);
+static int		FilterInputBytes(Channel *chanPtr,
+			    GetsState *statePtr);
+static int		FlushChannel(Tcl_Interp *interp, Channel *chanPtr,
+			    int calledFromAsyncFlush);
+static int		TclGetsObjBinary(Tcl_Channel chan, Tcl_Obj *objPtr);
+static Tcl_Encoding	GetBinaryEncoding();
+static void		FreeBinaryEncoding(ClientData clientData);
+static Tcl_HashTable *	GetChannelTable(Tcl_Interp *interp);
+static int		GetInput(Channel *chanPtr);
+static int		HaveVersion(const Tcl_ChannelType *typePtr,
+			    Tcl_ChannelTypeVersion minimumVersion);
+static void		PeekAhead(Channel *chanPtr, char **dstEndPtr,
+			    GetsState *gsPtr);
+static int		ReadBytes(ChannelState *statePtr, Tcl_Obj *objPtr,
+			    int charsLeft);
+static int		ReadChars(ChannelState *statePtr, Tcl_Obj *objPtr,
+			    int charsLeft, int *factorPtr);
+static void		RecycleBuffer(ChannelState *statePtr,
+			    ChannelBuffer *bufPtr, int mustDiscard);
+static int		StackSetBlockMode(Channel *chanPtr, int mode);
+static int		SetBlockMode(Tcl_Interp *interp, Channel *chanPtr,
+			    int mode);
+static void		StopCopy(CopyState *csPtr);
+static void		TranslateInputEOL(ChannelState *statePtr, char *dst,
+			    const char *src, int *dstLenPtr, int *srcLenPtr);
+static void		UpdateInterest(Channel *chanPtr);
+static int		Write(Channel *chanPtr, const char *src,
+			    int srcLen, Tcl_Encoding encoding);
+static Tcl_Obj *	FixLevelCode(Tcl_Obj *msg);
+static void		SpliceChannel(Tcl_Channel chan);
+static void		CutChannel(Tcl_Channel chan);
+static int              WillRead(Channel *chanPtr);
+
+#define WriteChars(chanPtr, src, srcLen) \
+			Write(chanPtr, src, srcLen, chanPtr->state->encoding)
+#define WriteBytes(chanPtr, src, srcLen) \
+			Write(chanPtr, src, srcLen, tclIdentityEncoding)
+
+/*
+ * Simplifying helper macros. All may use their argument(s) multiple times.
+ * The ANSI C "prototypes" for the macros are listed below, together with a
+ * short description of what the macro does.
+ *
+ * --------------------------------------------------------------------------
+ * int BytesLeft(ChannelBuffer *bufPtr)
+ *
+ *	Returns the number of bytes of data remaining in the buffer.
+ *
+ * int SpaceLeft(ChannelBuffer *bufPtr)
+ *
+ *	Returns the number of bytes of space remaining at the end of the
+ *	buffer.
+ *
+ * int IsBufferReady(ChannelBuffer *bufPtr)
+ *
+ *	Returns whether a buffer has bytes available within it.
+ *
+ * int IsBufferEmpty(ChannelBuffer *bufPtr)
+ *
+ *	Returns whether a buffer is entirely empty. Note that this is not the
+ *	inverse of the above operation; trying to merge the two seems to lead
+ *	to occasional crashes...
+ *
+ * int IsBufferFull(ChannelBuffer *bufPtr)
+ *
+ *	Returns whether more data can be added to a buffer.
+ *
+ * int IsBufferOverflowing(ChannelBuffer *bufPtr)
+ *
+ *	Returns whether a buffer has more data in it than it should.
+ *
+ * char *InsertPoint(ChannelBuffer *bufPtr)
+ *
+ *	Returns a pointer to where characters should be added to the buffer.
+ *
+ * char *RemovePoint(ChannelBuffer *bufPtr)
+ *
+ *	Returns a pointer to where characters should be removed from the
+ *	buffer.
+ * --------------------------------------------------------------------------
+ */
+
+#define BytesLeft(bufPtr)	((bufPtr)->nextAdded - (bufPtr)->nextRemoved)
+
+#define SpaceLeft(bufPtr)	((bufPtr)->bufLength - (bufPtr)->nextAdded)
+
+#define IsBufferReady(bufPtr)	((bufPtr)->nextAdded > (bufPtr)->nextRemoved)
+
+#define IsBufferEmpty(bufPtr)	((bufPtr)->nextAdded == (bufPtr)->nextRemoved)
+
+#define IsBufferFull(bufPtr)	((bufPtr) && (bufPtr)->nextAdded >= (bufPtr)->bufLength)
+
+#define IsBufferOverflowing(bufPtr) ((bufPtr)->nextAdded>(bufPtr)->bufLength)
+
+#define InsertPoint(bufPtr)	((bufPtr)->buf + (bufPtr)->nextAdded)
+
+#define RemovePoint(bufPtr)	((bufPtr)->buf + (bufPtr)->nextRemoved)
+
+/*
+ * For working with channel state flag bits.
+ */
+
+#define SetFlag(statePtr, flag)		((statePtr)->flags |= (flag))
+#define ResetFlag(statePtr, flag)	((statePtr)->flags &= ~(flag))
+#define GotFlag(statePtr, flag)		((statePtr)->flags & (flag))
+
+/*
+ * Macro for testing whether a string (in optionName, length len) matches a
+ * value (prefix matching rules). Arguments are the minimum length to match
+ * and the value to match against. (Can't use Tcl_GetIndexFromObj as this is
+ * used in a situation where no objects are available.)
+ */
+
+#define HaveOpt(minLength, nameString) \
+	((len > (minLength)) && (optionName[1] == (nameString)[1]) \
+		&& (strncmp(optionName, (nameString), len) == 0))
+
+/*
+ * The ChannelObjType type.  Used to store the result of looking up
+ * a channel name in the context of an interp.  Saves the lookup
+ * result and values needed to check its continued validity.
+ */
+
+typedef struct ResolvedChanName {
+    ChannelState *statePtr;	/* The saved lookup result */
+    Tcl_Interp *interp;		/* The interp in which the lookup was done. */
+    int epoch;			/* The epoch of the channel when the lookup
+				 * was done. Use to verify validity. */
+    int refCount;		/* Share this struct among many Tcl_Obj. */
+} ResolvedChanName;
+
+static void		DupChannelIntRep(Tcl_Obj *objPtr, Tcl_Obj *copyPtr);
+static void		FreeChannelIntRep(Tcl_Obj *objPtr);
+
+static const Tcl_ObjType chanObjType = {
+    "channel",			/* name for this type */
+    FreeChannelIntRep,		/* freeIntRepProc */
+    DupChannelIntRep,		/* dupIntRepProc */
+    NULL,			/* updateStringProc */
+    NULL			/* setFromAnyProc */
+};
+
+#define BUSY_STATE(st, fl) \
+     ((((st)->csPtrR) && ((fl) & TCL_READABLE)) || \
+      (((st)->csPtrW) && ((fl) & TCL_WRITABLE)))
+
+#define MAX_CHANNEL_BUFFER_SIZE (1024*1024)
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * ChanClose, ChanRead, ChanSeek, ChanThreadAction, ChanWatch, ChanWrite --
+ *
+ *	Simplify the access to selected channel driver "methods" that are used
+ *	in multiple places in a stereotypical fashion. These are just thin
+ *	wrappers around the driver functions.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+static inline int
+ChanClose(
+    Channel *chanPtr,
+    Tcl_Interp *interp)
+{
+    if (chanPtr->typePtr->closeProc != TCL_CLOSE2PROC) {
+	return chanPtr->typePtr->closeProc(chanPtr->instanceData, interp);
+    } else {
+	return chanPtr->typePtr->close2Proc(chanPtr->instanceData, interp, 0);
+    }
+}
+
+static inline int
+ChanCloseHalf(
+    Channel *chanPtr,
+    Tcl_Interp *interp,
+    int flags)
+{
+    return chanPtr->typePtr->close2Proc(chanPtr->instanceData, interp, flags);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * ChanRead --
+ *
+ *	Read up to dstSize bytes using the inputProc of chanPtr, store
+ *	them at dst, and return the number of bytes stored.
+ *
+ * Results:
+ *	The return value of the driver inputProc,
+ *	  - number of bytes stored at dst, ot
+ *	  - -1 on error, with a Posix error code available to the
+ *	    caller by calling Tcl_GetErrno().
+ *
+ * Side effects:
+ *	The CHANNEL_BLOCKED and CHANNEL_EOF flags of the channel state are
+ *	set as appropriate.
+ *	On EOF, the inputEncodingFlags are set to perform ending operations
+ *	on decoding.
+ *	TODO - Is this really the right place for that?
+ *
+ *---------------------------------------------------------------------------
+ */
+static int
+ChanRead(
+    Channel *chanPtr,
+    char *dst,
+    int dstSize)
+{
+    int bytesRead, result;
+
+    /*
+     * If the caller asked for zero bytes, we'd force the inputProc
+     * to return zero bytes, and then misinterpret that as EOF.
+     */
+    assert(dstSize > 0);
+
+    /*
+     * Each read op must set the blocked and eof states anew, not let
+     * the effect of prior reads leak through.
+     */
+    if (GotFlag(chanPtr->state, CHANNEL_EOF)) {
+        chanPtr->state->inputEncodingFlags |= TCL_ENCODING_START;
+    }
+    ResetFlag(chanPtr->state, CHANNEL_BLOCKED | CHANNEL_EOF);
+    chanPtr->state->inputEncodingFlags &= ~TCL_ENCODING_END;
+    if (WillRead(chanPtr) < 0) {
+        return -1;
+    }
+
+    bytesRead = chanPtr->typePtr->inputProc(chanPtr->instanceData,
+	    dst, dstSize, &result);
+
+    /* Stop any flag leakage through stacked channel levels */
+    if (GotFlag(chanPtr->state, CHANNEL_EOF)) {
+        chanPtr->state->inputEncodingFlags |= TCL_ENCODING_START;
+    }
+    ResetFlag(chanPtr->state, CHANNEL_BLOCKED | CHANNEL_EOF);
+    chanPtr->state->inputEncodingFlags &= ~TCL_ENCODING_END;
+    if (bytesRead > 0) {
+	/*
+	 * If we get a short read, signal up that we may be BLOCKED.
+	 * We should avoid calling the driver because on some
+	 * platforms we will block in the low level reading code even
+	 * though the channel is set into nonblocking mode.
+	 */
+
+	if (bytesRead < dstSize) {
+	    SetFlag(chanPtr->state, CHANNEL_BLOCKED);
+	}
+    } else if (bytesRead == 0) {
+	SetFlag(chanPtr->state, CHANNEL_EOF);
+	chanPtr->state->inputEncodingFlags |= TCL_ENCODING_END;
+    } else if (bytesRead < 0) {
+	if ((result == EWOULDBLOCK) || (result == EAGAIN)) {
+	    SetFlag(chanPtr->state, CHANNEL_BLOCKED);
+	    result = EAGAIN;
+	}
+	Tcl_SetErrno(result);
+    }
+    return bytesRead;
+}
+
+static inline Tcl_WideInt
+ChanSeek(
+    Channel *chanPtr,
+    Tcl_WideInt offset,
+    int mode,
+    int *errnoPtr)
+{
+    /*
+     * Note that we prefer the wideSeekProc if that field is available in the
+     * type and non-NULL.
+     */
+
+    if (HaveVersion(chanPtr->typePtr, TCL_CHANNEL_VERSION_3) &&
+	    chanPtr->typePtr->wideSeekProc != NULL) {
+	return chanPtr->typePtr->wideSeekProc(chanPtr->instanceData,
+		offset, mode, errnoPtr);
+    }
+
+    if (offset<Tcl_LongAsWide(LONG_MIN) || offset>Tcl_LongAsWide(LONG_MAX)) {
+	*errnoPtr = EOVERFLOW;
+	return Tcl_LongAsWide(-1);
+    }
+
+    return Tcl_LongAsWide(chanPtr->typePtr->seekProc(chanPtr->instanceData,
+	    Tcl_WideAsLong(offset), mode, errnoPtr));
+}
+
+static inline void
+ChanThreadAction(
+    Channel *chanPtr,
+    int action)
+{
+    Tcl_DriverThreadActionProc *threadActionProc =
+	    Tcl_ChannelThreadActionProc(chanPtr->typePtr);
+
+    if (threadActionProc != NULL) {
+	threadActionProc(chanPtr->instanceData, action);
+    }
+}
+
+static inline void
+ChanWatch(
+    Channel *chanPtr,
+    int mask)
+{
+    chanPtr->typePtr->watchProc(chanPtr->instanceData, mask);
+}
+
+static inline int
+ChanWrite(
+    Channel *chanPtr,
+    const char *src,
+    int srcLen,
+    int *errnoPtr)
+{
+    return chanPtr->typePtr->outputProc(chanPtr->instanceData, src, srcLen,
+	    errnoPtr);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * TclInitIOSubsystem --
+ *
+ *	Initialize all resources used by this subsystem on a per-process
+ *	basis.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Depends on the memory subsystems.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+void
+TclInitIOSubsystem(void)
+{
+    /*
+     * By fetching thread local storage we take care of allocating it for each
+     * thread.
+     */
+
+    (void) TCL_TSD_INIT(&dataKey);
+}
+
+/*
+ *-------------------------------------------------------------------------
+ *
+ * TclFinalizeIOSubsystem --
+ *
+ *	Releases all resources used by this subsystem on a per-process basis.
+ *	Closes all extant channels that have not already been closed because
+ *	they were not owned by any interp.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Depends on encoding and memory subsystems.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+	/* ARGSUSED */
+void
+TclFinalizeIOSubsystem(void)
+{
+    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+    Channel *chanPtr = NULL;	/* Iterates over open channels. */
+    ChannelState *statePtr;	/* State of channel stack */
+    int active = 1;		/* Flag == 1 while there's still work to do */
+    int doflushnb;
+
+    /* Fetch the pre-TIP#398 compatibility flag */
+    {
+        const char *s;
+        Tcl_DString ds;
+
+        s = TclGetEnv("TCL_FLUSH_NONBLOCKING_ON_EXIT", &ds);
+        doflushnb = ((s != NULL) && strcmp(s, "0"));
+        if (s != NULL) {
+            Tcl_DStringFree(&ds);
+        }
+    }
+
+    /*
+     * Walk all channel state structures known to this thread and close
+     * corresponding channels.
+     */
+
+    while (active) {
+	/*
+	 * Iterate through the open channel list, and find the first channel
+	 * that isn't dead. We start from the head of the list each time,
+	 * because the close action on one channel can close others.
+	 */
+
+	active = 0;
+	for (statePtr = tsdPtr->firstCSPtr;
+		statePtr != NULL;
+		statePtr = statePtr->nextCSPtr) {
+	    chanPtr = statePtr->topChanPtr;
+            if (GotFlag(statePtr, CHANNEL_DEAD)) {
+                continue;
+            }
+	    if (!GotFlag(statePtr, CHANNEL_INCLOSE | CHANNEL_CLOSED )
+                || GotFlag(statePtr, BG_FLUSH_SCHEDULED)) {
+                ResetFlag(statePtr, BG_FLUSH_SCHEDULED);
+		active = 1;
+		break;
+	    }
+	}
+
+	/*
+	 * We've found a live (or bg-closing) channel. Close it.
+	 */
+
+	if (active) {
+
+	    TclChannelPreserve((Tcl_Channel)chanPtr);
+	    /*
+	     * TIP #398:  by default, we no  longer set the  channel back into
+             * blocking  mode.  To  restore  the old  blocking  behavior,  the
+             * environment variable  TCL_FLUSH_NONBLOCKING_ON_EXIT must be set
+             * and not be "0".
+	     */
+            if (doflushnb) {
+                    /* Set the channel back into blocking mode to ensure that we wait
+                     * for all data to flush out.
+                     */
+
+                (void) Tcl_SetChannelOption(NULL, (Tcl_Channel) chanPtr,
+                                            "-blocking", "on");
+            }
+
+	    if ((chanPtr == (Channel *) tsdPtr->stdinChannel) ||
+		    (chanPtr == (Channel *) tsdPtr->stdoutChannel) ||
+		    (chanPtr == (Channel *) tsdPtr->stderrChannel)) {
+		/*
+		 * Decrement the refcount which was earlier artificially
+		 * bumped up to keep the channel from being closed.
+		 */
+
+		statePtr->refCount--;
+	    }
+
+	    if (statePtr->refCount <= 0) {
+		/*
+		 * Close it only if the refcount indicates that the channel is
+		 * not referenced from any interpreter. If it is, that
+		 * interpreter will close the channel when it gets destroyed.
+		 */
+
+		(void) Tcl_Close(NULL, (Tcl_Channel) chanPtr);
+	    } else {
+		/*
+		 * The refcount is greater than zero, so flush the channel.
+		 */
+
+		Tcl_Flush((Tcl_Channel) chanPtr);
+
+		/*
+		 * Call the device driver to actually close the underlying
+		 * device for this channel.
+		 */
+
+		(void) ChanClose(chanPtr, NULL);
+
+		/*
+		 * Finally, we clean up the fields in the channel data
+		 * structure since all of them have been deleted already. We
+		 * mark the channel with CHANNEL_DEAD to prevent any further
+		 * IO operations on it.
+		 */
+
+		chanPtr->instanceData = NULL;
+		SetFlag(statePtr, CHANNEL_DEAD);
+	    }
+	    TclChannelRelease((Tcl_Channel)chanPtr);
+	}
+    }
+
+    TclpFinalizeSockets();
+    TclpFinalizePipes();
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_SetStdChannel --
+ *
+ *	This function is used to change the channels that are used for
+ *	stdin/stdout/stderr in new interpreters.
+ *
+ * Results:
+ *	None
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_SetStdChannel(
+    Tcl_Channel channel,
+    int type)			/* One of TCL_STDIN, TCL_STDOUT, TCL_STDERR. */
+{
+    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+
+    switch (type) {
+    case TCL_STDIN:
+	tsdPtr->stdinInitialized = 1;
+	tsdPtr->stdinChannel = channel;
+	break;
+    case TCL_STDOUT:
+	tsdPtr->stdoutInitialized = 1;
+	tsdPtr->stdoutChannel = channel;
+	break;
+    case TCL_STDERR:
+	tsdPtr->stderrInitialized = 1;
+	tsdPtr->stderrChannel = channel;
+	break;
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_GetStdChannel --
+ *
+ *	Returns the specified standard channel.
+ *
+ * Results:
+ *	Returns the specified standard channel, or NULL.
+ *
+ * Side effects:
+ *	May cause the creation of a standard channel and the underlying file.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_Channel
+Tcl_GetStdChannel(
+    int type)			/* One of TCL_STDIN, TCL_STDOUT, TCL_STDERR. */
+{
+    Tcl_Channel channel = NULL;
+    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+
+    /*
+     * If the channels were not created yet, create them now and store them in
+     * the static variables.
+     */
+
+    switch (type) {
+    case TCL_STDIN:
+	if (!tsdPtr->stdinInitialized) {
+	    tsdPtr->stdinChannel = TclpGetDefaultStdChannel(TCL_STDIN);
+	    tsdPtr->stdinInitialized = 1;
+
+	    /*
+	     * Artificially bump the refcount to ensure that the channel is
+	     * only closed on exit.
+	     *
+	     * NOTE: Must only do this if stdinChannel is not NULL. It can be
+	     * NULL in situations where Tcl is unable to connect to the
+	     * standard input.
+	     */
+
+	    if (tsdPtr->stdinChannel != NULL) {
+		Tcl_RegisterChannel(NULL, tsdPtr->stdinChannel);
+	    }
+	}
+	channel = tsdPtr->stdinChannel;
+	break;
+    case TCL_STDOUT:
+	if (!tsdPtr->stdoutInitialized) {
+	    tsdPtr->stdoutChannel = TclpGetDefaultStdChannel(TCL_STDOUT);
+	    tsdPtr->stdoutInitialized = 1;
+	    if (tsdPtr->stdoutChannel != NULL) {
+		Tcl_RegisterChannel(NULL, tsdPtr->stdoutChannel);
+	    }
+	}
+	channel = tsdPtr->stdoutChannel;
+	break;
+    case TCL_STDERR:
+	if (!tsdPtr->stderrInitialized) {
+	    tsdPtr->stderrChannel = TclpGetDefaultStdChannel(TCL_STDERR);
+	    tsdPtr->stderrInitialized = 1;
+	    if (tsdPtr->stderrChannel != NULL) {
+		Tcl_RegisterChannel(NULL, tsdPtr->stderrChannel);
+	    }
+	}
+	channel = tsdPtr->stderrChannel;
+	break;
+    }
+    return channel;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_CreateCloseHandler
+ *
+ *	Creates a close callback which will be called when the channel is
+ *	closed.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Causes the callback to be called in the future when the channel will
+ *	be closed.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_CreateCloseHandler(
+    Tcl_Channel chan,		/* The channel for which to create the close
+				 * callback. */
+    Tcl_CloseProc *proc,	/* The callback routine to call when the
+				 * channel will be closed. */
+    ClientData clientData)	/* Arbitrary data to pass to the close
+				 * callback. */
+{
+    ChannelState *statePtr = ((Channel *) chan)->state;
+    CloseCallback *cbPtr;
+
+    cbPtr = ckalloc(sizeof(CloseCallback));
+    cbPtr->proc = proc;
+    cbPtr->clientData = clientData;
+
+    cbPtr->nextPtr = statePtr->closeCbPtr;
+    statePtr->closeCbPtr = cbPtr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_DeleteCloseHandler --
+ *
+ *	Removes a callback that would have been called on closing the channel.
+ *	If there is no matching callback then this function has no effect.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The callback will not be called in the future when the channel is
+ *	eventually closed.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_DeleteCloseHandler(
+    Tcl_Channel chan,		/* The channel for which to cancel the close
+				 * callback. */
+    Tcl_CloseProc *proc,	/* The procedure for the callback to
+				 * remove. */
+    ClientData clientData)	/* The callback data for the callback to
+				 * remove. */
+{
+    ChannelState *statePtr = ((Channel *) chan)->state;
+    CloseCallback *cbPtr, *cbPrevPtr;
+
+    for (cbPtr = statePtr->closeCbPtr, cbPrevPtr = NULL;
+	    cbPtr != NULL; cbPtr = cbPtr->nextPtr) {
+	if ((cbPtr->proc == proc) && (cbPtr->clientData == clientData)) {
+	    if (cbPrevPtr == NULL) {
+		statePtr->closeCbPtr = cbPtr->nextPtr;
+	    } else {
+		cbPrevPtr->nextPtr = cbPtr->nextPtr;
+	    }
+	    ckfree(cbPtr);
+	    break;
+	}
+	cbPrevPtr = cbPtr;
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * GetChannelTable --
+ *
+ *	Gets and potentially initializes the channel table for an interpreter.
+ *	If it is initializing the table it also inserts channels for stdin,
+ *	stdout and stderr if the interpreter is trusted.
+ *
+ * Results:
+ *	A pointer to the hash table created, for use by the caller.
+ *
+ * Side effects:
+ *	Initializes the channel table for an interpreter. May create channels
+ *	for stdin, stdout and stderr.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static Tcl_HashTable *
+GetChannelTable(
+    Tcl_Interp *interp)
+{
+    Tcl_HashTable *hTblPtr;	/* Hash table of channels. */
+    Tcl_Channel stdinChan, stdoutChan, stderrChan;
+
+    hTblPtr = Tcl_GetAssocData(interp, "tclIO", NULL);
+    if (hTblPtr == NULL) {
+	hTblPtr = ckalloc(sizeof(Tcl_HashTable));
+	Tcl_InitHashTable(hTblPtr, TCL_STRING_KEYS);
+	Tcl_SetAssocData(interp, "tclIO",
+		(Tcl_InterpDeleteProc *) DeleteChannelTable, hTblPtr);
+
+	/*
+	 * If the interpreter is trusted (not "safe"), insert channels for
+	 * stdin, stdout and stderr (possibly creating them in the process).
+	 */
+
+	if (Tcl_IsSafe(interp) == 0) {
+	    stdinChan = Tcl_GetStdChannel(TCL_STDIN);
+	    if (stdinChan != NULL) {
+		Tcl_RegisterChannel(interp, stdinChan);
+	    }
+	    stdoutChan = Tcl_GetStdChannel(TCL_STDOUT);
+	    if (stdoutChan != NULL) {
+		Tcl_RegisterChannel(interp, stdoutChan);
+	    }
+	    stderrChan = Tcl_GetStdChannel(TCL_STDERR);
+	    if (stderrChan != NULL) {
+		Tcl_RegisterChannel(interp, stderrChan);
+	    }
+	}
+    }
+    return hTblPtr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * DeleteChannelTable --
+ *
+ *	Deletes the channel table for an interpreter, closing any open
+ *	channels whose refcount reaches zero. This procedure is invoked when
+ *	an interpreter is deleted, via the AssocData cleanup mechanism.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Deletes the hash table of channels. May close channels. May flush
+ *	output on closed channels. Removes any channeEvent handlers that were
+ *	registered in this interpreter.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+DeleteChannelTable(
+    ClientData clientData,	/* The per-interpreter data structure. */
+    Tcl_Interp *interp)		/* The interpreter being deleted. */
+{
+    Tcl_HashTable *hTblPtr;	/* The hash table. */
+    Tcl_HashSearch hSearch;	/* Search variable. */
+    Tcl_HashEntry *hPtr;	/* Search variable. */
+    Channel *chanPtr;		/* Channel being deleted. */
+    ChannelState *statePtr;	/* State of Channel being deleted. */
+    EventScriptRecord *sPtr, *prevPtr, *nextPtr;
+				/* Variables to loop over all channel events
+				 * registered, to delete the ones that refer
+				 * to the interpreter being deleted. */
+
+    /*
+     * Delete all the registered channels - this will close channels whose
+     * refcount reaches zero.
+     */
+
+    hTblPtr = clientData;
+    for (hPtr = Tcl_FirstHashEntry(hTblPtr, &hSearch); hPtr != NULL;
+	    hPtr = Tcl_FirstHashEntry(hTblPtr, &hSearch)) {
+	chanPtr = Tcl_GetHashValue(hPtr);
+	statePtr = chanPtr->state;
+
+	/*
+	 * Remove any fileevents registered in this interpreter.
+	 */
+
+	for (sPtr = statePtr->scriptRecordPtr, prevPtr = NULL;
+		sPtr != NULL; sPtr = nextPtr) {
+	    nextPtr = sPtr->nextPtr;
+	    if (sPtr->interp == interp) {
+		if (prevPtr == NULL) {
+		    statePtr->scriptRecordPtr = nextPtr;
+		} else {
+		    prevPtr->nextPtr = nextPtr;
+		}
+
+		Tcl_DeleteChannelHandler((Tcl_Channel) chanPtr,
+			TclChannelEventScriptInvoker, sPtr);
+
+		TclDecrRefCount(sPtr->scriptPtr);
+		ckfree(sPtr);
+	    } else {
+		prevPtr = sPtr;
+	    }
+	}
+
+	/*
+	 * Cannot call Tcl_UnregisterChannel because that procedure calls
+	 * Tcl_GetAssocData to get the channel table, which might already be
+	 * inaccessible from the interpreter structure. Instead, we emulate
+	 * the behavior of Tcl_UnregisterChannel directly here.
+	 */
+
+	Tcl_DeleteHashEntry(hPtr);
+	statePtr->epoch++;
+	if (statePtr->refCount-- <= 1) {
+	    if (!GotFlag(statePtr, BG_FLUSH_SCHEDULED)) {
+		(void) Tcl_Close(interp, (Tcl_Channel) chanPtr);
+	    }
+	}
+
+    }
+    Tcl_DeleteHashTable(hTblPtr);
+    ckfree(hTblPtr);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * CheckForStdChannelsBeingClosed --
+ *
+ *	Perform special handling for standard channels being closed. When
+ *	given a standard channel, if the refcount is now 1, it means that the
+ *	last reference to the standard channel is being explicitly closed. Now
+ *	bump the refcount artificially down to 0, to ensure the normal
+ *	handling of channels being closed will occur. Also reset the static
+ *	pointer to the channel to NULL, to avoid dangling references.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Manipulates the refcount on standard channels. May smash the global
+ *	static pointer to a standard channel.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+CheckForStdChannelsBeingClosed(
+    Tcl_Channel chan)
+{
+    ChannelState *statePtr = ((Channel *) chan)->state;
+    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+
+    if (tsdPtr->stdinInitialized
+	    && tsdPtr->stdinChannel != NULL
+	    && statePtr == ((Channel *)tsdPtr->stdinChannel)->state) {
+	if (statePtr->refCount < 2) {
+	    statePtr->refCount = 0;
+	    tsdPtr->stdinChannel = NULL;
+	    return;
+	}
+    } else if (tsdPtr->stdoutInitialized
+	    && tsdPtr->stdoutChannel != NULL
+	    && statePtr == ((Channel *)tsdPtr->stdoutChannel)->state) {
+	if (statePtr->refCount < 2) {
+	    statePtr->refCount = 0;
+	    tsdPtr->stdoutChannel = NULL;
+	    return;
+	}
+    } else if (tsdPtr->stderrInitialized
+	    && tsdPtr->stderrChannel != NULL
+	    && statePtr == ((Channel *)tsdPtr->stderrChannel)->state) {
+	if (statePtr->refCount < 2) {
+	    statePtr->refCount = 0;
+	    tsdPtr->stderrChannel = NULL;
+	    return;
+	}
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_IsStandardChannel --
+ *
+ *	Test if the given channel is a standard channel. No attempt is made to
+ *	check if the channel or the standard channels are initialized or
+ *	otherwise valid.
+ *
+ * Results:
+ *	Returns 1 if true, 0 if false.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_IsStandardChannel(
+    Tcl_Channel chan)		/* Channel to check. */
+{
+    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+
+    if ((chan == tsdPtr->stdinChannel)
+	    || (chan == tsdPtr->stdoutChannel)
+	    || (chan == tsdPtr->stderrChannel)) {
+	return 1;
+    } else {
+	return 0;
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_RegisterChannel --
+ *
+ *	Adds an already-open channel to the channel table of an interpreter.
+ *	If the interpreter passed as argument is NULL, it only increments the
+ *	channel refCount.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	May increment the reference count of a channel.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_RegisterChannel(
+    Tcl_Interp *interp,		/* Interpreter in which to add the channel. */
+    Tcl_Channel chan)		/* The channel to add to this interpreter
+				 * channel table. */
+{
+    Tcl_HashTable *hTblPtr;	/* Hash table of channels. */
+    Tcl_HashEntry *hPtr;	/* Search variable. */
+    int isNew;			/* Is the hash entry new or does it exist? */
+    Channel *chanPtr;		/* The actual channel. */
+    ChannelState *statePtr;	/* State of the actual channel. */
+
+    /*
+     * Always (un)register bottom-most channel in the stack. This makes
+     * management of the channel list easier because no manipulation is
+     * necessary during (un)stack operation.
+     */
+
+    chanPtr = ((Channel *) chan)->state->bottomChanPtr;
+    statePtr = chanPtr->state;
+
+    if (statePtr->channelName == NULL) {
+	Tcl_Panic("Tcl_RegisterChannel: channel without name");
+    }
+    if (interp != NULL) {
+	hTblPtr = GetChannelTable(interp);
+	hPtr = Tcl_CreateHashEntry(hTblPtr, statePtr->channelName, &isNew);
+	if (!isNew) {
+	    if (chan == Tcl_GetHashValue(hPtr)) {
+		return;
+	    }
+
+	    Tcl_Panic("Tcl_RegisterChannel: duplicate channel names");
+	}
+	Tcl_SetHashValue(hPtr, chanPtr);
+    }
+    statePtr->refCount++;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_UnregisterChannel --
+ *
+ *	Deletes the hash entry for a channel associated with an interpreter.
+ *	If the interpreter given as argument is NULL, it only decrements the
+ *	reference count. (This all happens in the Tcl_DetachChannel helper
+ *	function).
+ *
+ *	Finally, if the reference count of the channel drops to zero, it is
+ *	deleted.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	Calls Tcl_DetachChannel which deletes the hash entry for a channel
+ *	associated with an interpreter.
+ *
+ *	May delete the channel, which can have a variety of consequences,
+ *	especially if we are forced to close the channel.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_UnregisterChannel(
+    Tcl_Interp *interp,		/* Interpreter in which channel is defined. */
+    Tcl_Channel chan)		/* Channel to delete. */
+{
+    ChannelState *statePtr;	/* State of the real channel. */
+
+    statePtr = ((Channel *) chan)->state->bottomChanPtr->state;
+
+    if (GotFlag(statePtr, CHANNEL_INCLOSE)) {
+	if (interp != NULL) {
+	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
+                    "illegal recursive call to close through close-handler"
+                    " of channel", -1));
+	}
+	return TCL_ERROR;
+    }
+
+    if (DetachChannel(interp, chan) != TCL_OK) {
+	return TCL_OK;
+    }
+
+    statePtr = ((Channel *) chan)->state->bottomChanPtr->state;
+
+    /*
+     * Perform special handling for standard channels being closed. If the
+     * refCount is now 1 it means that the last reference to the standard
+     * channel is being explicitly closed, so bump the refCount down
+     * artificially to 0. This will ensure that the channel is actually
+     * closed, below. Also set the static pointer to NULL for the channel.
+     */
+
+    CheckForStdChannelsBeingClosed(chan);
+
+    /*
+     * If the refCount reached zero, close the actual channel.
+     */
+
+    if (statePtr->refCount <= 0) {
+	Tcl_Preserve(statePtr);
+	if (!GotFlag(statePtr, BG_FLUSH_SCHEDULED)) {
+	    /*
+	     * We don't want to re-enter Tcl_Close().
+	     */
+
+	    if (!GotFlag(statePtr, CHANNEL_CLOSED)) {
+		if (Tcl_Close(interp, chan) != TCL_OK) {
+		    SetFlag(statePtr, CHANNEL_CLOSED);
+		    Tcl_Release(statePtr);
+		    return TCL_ERROR;
+		}
+	    }
+	}
+	SetFlag(statePtr, CHANNEL_CLOSED);
+	Tcl_Release(statePtr);
+    }
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_DetachChannel --
+ *
+ *	Deletes the hash entry for a channel associated with an interpreter.
+ *	If the interpreter given as argument is NULL, it only decrements the
+ *	reference count. Even if the ref count drops to zero, the channel is
+ *	NOT closed or cleaned up. This allows a channel to be detached from an
+ *	interpreter and left in the same state it was in when it was
+ *	originally returned by 'Tcl_OpenFileChannel', for example.
+ *
+ *	This function cannot be used on the standard channels, and will return
+ *	TCL_ERROR if that is attempted.
+ *
+ *	This function should only be necessary for special purposes in which
+ *	you need to generate a pristine channel from one that has already been
+ *	used. All ordinary purposes will almost always want to use
+ *	Tcl_UnregisterChannel instead.
+ *
+ *	Provided the channel is not attached to any other interpreter, it can
+ *	then be closed with Tcl_Close, rather than with Tcl_UnregisterChannel.
+ *
+ * Results:
+ *	A standard Tcl result. If the channel is not currently registered with
+ *	the given interpreter, TCL_ERROR is returned, otherwise TCL_OK.
+ *	However no error messages are left in the interp's result.
+ *
+ * Side effects:
+ *	Deletes the hash entry for a channel associated with an interpreter.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_DetachChannel(
+    Tcl_Interp *interp,		/* Interpreter in which channel is defined. */
+    Tcl_Channel chan)		/* Channel to delete. */
+{
+    if (Tcl_IsStandardChannel(chan)) {
+	return TCL_ERROR;
+    }
+
+    return DetachChannel(interp, chan);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * DetachChannel --
+ *
+ *	Deletes the hash entry for a channel associated with an interpreter.
+ *	If the interpreter given as argument is NULL, it only decrements the
+ *	reference count. Even if the ref count drops to zero, the channel is
+ *	NOT closed or cleaned up. This allows a channel to be detached from an
+ *	interpreter and left in the same state it was in when it was
+ *	originally returned by 'Tcl_OpenFileChannel', for example.
+ *
+ * Results:
+ *	A standard Tcl result. If the channel is not currently registered with
+ *	the given interpreter, TCL_ERROR is returned, otherwise TCL_OK.
+ *	However no error messages are left in the interp's result.
+ *
+ * Side effects:
+ *	Deletes the hash entry for a channel associated with an interpreter.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+DetachChannel(
+    Tcl_Interp *interp,		/* Interpreter in which channel is defined. */
+    Tcl_Channel chan)		/* Channel to delete. */
+{
+    Tcl_HashTable *hTblPtr;	/* Hash table of channels. */
+    Tcl_HashEntry *hPtr;	/* Search variable. */
+    Channel *chanPtr;		/* The real IO channel. */
+    ChannelState *statePtr;	/* State of the real channel. */
+
+    /*
+     * Always (un)register bottom-most channel in the stack. This makes
+     * management of the channel list easier because no manipulation is
+     * necessary during (un)stack operation.
+     */
+
+    chanPtr = ((Channel *) chan)->state->bottomChanPtr;
+    statePtr = chanPtr->state;
+
+    if (interp != NULL) {
+	hTblPtr = Tcl_GetAssocData(interp, "tclIO", NULL);
+	if (hTblPtr == NULL) {
+	    return TCL_ERROR;
+	}
+	hPtr = Tcl_FindHashEntry(hTblPtr, statePtr->channelName);
+	if (hPtr == NULL) {
+	    return TCL_ERROR;
+	}
+	if ((Channel *) Tcl_GetHashValue(hPtr) != chanPtr) {
+	    return TCL_ERROR;
+	}
+	Tcl_DeleteHashEntry(hPtr);
+	statePtr->epoch++;
+
+	/*
+	 * Remove channel handlers that refer to this interpreter, so that
+	 * they will not be present if the actual close is delayed and more
+	 * events happen on the channel. This may occur if the channel is
+	 * shared between several interpreters, or if the channel has async
+	 * flushing active.
+	 */
+
+	CleanupChannelHandlers(interp, chanPtr);
+    }
+
+    statePtr->refCount--;
+
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Tcl_GetChannel --
+ *
+ *	Finds an existing Tcl_Channel structure by name in a given
+ *	interpreter. This function is public because it is used by
+ *	channel-type-specific functions.
+ *
+ * Results:
+ *	A Tcl_Channel or NULL on failure. If failed, interp's result object
+ *	contains an error message. *modePtr is filled with the modes in which
+ *	the channel was opened.
+ *
+ * Side effects:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+Tcl_Channel
+Tcl_GetChannel(
+    Tcl_Interp *interp,		/* Interpreter in which to find or create the
+				 * channel. */
+    const char *chanName,	/* The name of the channel. */
+    int *modePtr)		/* Where to store the mode in which the
+				 * channel was opened? Will contain an ORed
+				 * combination of TCL_READABLE and
+				 * TCL_WRITABLE, if non-NULL. */
+{
+    Channel *chanPtr;		/* The actual channel. */
+    Tcl_HashTable *hTblPtr;	/* Hash table of channels. */
+    Tcl_HashEntry *hPtr;	/* Search variable. */
+    const char *name;		/* Translated name. */
+
+    /*
+     * Substitute "stdin", etc. Note that even though we immediately find the
+     * channel using Tcl_GetStdChannel, we still need to look it up in the
+     * specified interpreter to ensure that it is present in the channel
+     * table. Otherwise, safe interpreters would always have access to the
+     * standard channels.
+     */
+
+    name = chanName;
+    if ((chanName[0] == 's') && (chanName[1] == 't')) {
+	chanPtr = NULL;
+	if (strcmp(chanName, "stdin") == 0) {
+	    chanPtr = (Channel *) Tcl_GetStdChannel(TCL_STDIN);
+	} else if (strcmp(chanName, "stdout") == 0) {
+	    chanPtr = (Channel *) Tcl_GetStdChannel(TCL_STDOUT);
+	} else if (strcmp(chanName, "stderr") == 0) {
+	    chanPtr = (Channel *) Tcl_GetStdChannel(TCL_STDERR);
+	}
+	if (chanPtr != NULL) {
+	    name = chanPtr->state->channelName;
+	}
+    }
+
+    hTblPtr = GetChannelTable(interp);
+    hPtr = Tcl_FindHashEntry(hTblPtr, name);
+    if (hPtr == NULL) {
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+                "can not find channel named \"%s\"", chanName));
+	Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "CHANNEL", chanName, NULL);
+	return NULL;
+    }
+
+    /*
+     * Always return bottom-most channel in the stack. This one lives the
+     * longest - other channels may go away unnoticed. The other APIs
+     * compensate where necessary to retrieve the topmost channel again.
+     */
+
+    chanPtr = Tcl_GetHashValue(hPtr);
+    chanPtr = chanPtr->state->bottomChanPtr;
+    if (modePtr != NULL) {
+	*modePtr = chanPtr->state->flags & (TCL_READABLE|TCL_WRITABLE);
+    }
+
+    return (Tcl_Channel) chanPtr;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * TclGetChannelFromObj --
+ *
+ *	Finds an existing Tcl_Channel structure by name in a given
+ *	interpreter. This function is public because it is used by
+ *	channel-type-specific functions.
+ *
+ * Results:
+ *	A Tcl_Channel or NULL on failure. If failed, interp's result object
+ *	contains an error message. *modePtr is filled with the modes in which
+ *	the channel was opened.
+ *
+ * Side effects:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+int
+TclGetChannelFromObj(
+    Tcl_Interp *interp,		/* Interpreter in which to find or create the
+				 * channel. */
+    Tcl_Obj *objPtr,
+    Tcl_Channel *channelPtr,
+    int *modePtr,		/* Where to store the mode in which the
+				 * channel was opened? Will contain an ORed
+				 * combination of TCL_READABLE and
+				 * TCL_WRITABLE, if non-NULL. */
+    int flags)
+{
+    ChannelState *statePtr;
+    ResolvedChanName *resPtr = NULL;
+    Tcl_Channel chan;
+
+    if (interp == NULL) {
+	return TCL_ERROR;
+    }
+
+    if (objPtr->typePtr == &chanObjType) {
+	/*
+ 	 * Confirm validity of saved lookup results.
+ 	 */
+
+	resPtr = (ResolvedChanName *) objPtr->internalRep.twoPtrValue.ptr1;
+	statePtr = resPtr->statePtr;
+	if ((resPtr->interp == interp)		/* Same interp context */
+			/* No epoch change in channel since lookup */
+		&& (resPtr->epoch == statePtr->epoch)) {
+
+	    /* Have a valid saved lookup. Jump to end to return it. */
+	    goto valid;
+	}
+    }
+
+    chan = Tcl_GetChannel(interp, TclGetString(objPtr), NULL);
+
+    if (chan == NULL) {
+	if (resPtr) {
+	    FreeChannelIntRep(objPtr);
+	}
+	return TCL_ERROR;
+    }
+
+    if (resPtr && resPtr->refCount == 1) {
+	/* Re-use the ResolvedCmdName struct */
+	Tcl_Release((ClientData) resPtr->statePtr);
+
+    } else {
+	TclFreeIntRep(objPtr);
+
+	resPtr = (ResolvedChanName *) ckalloc(sizeof(ResolvedChanName));
+	resPtr->refCount = 1;
+	objPtr->internalRep.twoPtrValue.ptr1 = (ClientData) resPtr;
+	objPtr->typePtr = &chanObjType;
+    }
+    statePtr = ((Channel *)chan)->state;
+    resPtr->statePtr = statePtr;
+    Tcl_Preserve((ClientData) statePtr);
+    resPtr->interp = interp;
+    resPtr->epoch = statePtr->epoch;
+
+  valid:
+    *channelPtr = (Tcl_Channel) statePtr->bottomChanPtr;
+
+    if (modePtr != NULL) {
+	*modePtr = statePtr->flags & (TCL_READABLE|TCL_WRITABLE);
+    }
+
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_CreateChannel --
+ *
+ *	Creates a new entry in the hash table for a Tcl_Channel record.
+ *
+ * Results:
+ *	Returns the new Tcl_Channel.
+ *
+ * Side effects:
+ *	Creates a new Tcl_Channel instance and inserts it into the hash table.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_Channel
+Tcl_CreateChannel(
+    const Tcl_ChannelType *typePtr, /* The channel type record. */
+    const char *chanName,	/* Name of channel to record. */
+    ClientData instanceData,	/* Instance specific data. */
+    int mask)			/* TCL_READABLE & TCL_WRITABLE to indicate if
+				 * the channel is readable, writable. */
+{
+    Channel *chanPtr;		/* The channel structure newly created. */
+    ChannelState *statePtr;	/* The stack-level independent state info for
+				 * the channel. */
+    const char *name;
+    char *tmp;
+    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+
+    /*
+     * With the change of the Tcl_ChannelType structure to use a version in
+     * 8.3.2+, we have to make sure that our assumption that the structure
+     * remains a binary compatible size is true.
+     *
+     * If this assertion fails on some system, then it can be removed only if
+     * the user recompiles code with older channel drivers in the new system
+     * as well.
+     */
+
+    assert(sizeof(Tcl_ChannelTypeVersion) == sizeof(Tcl_DriverBlockModeProc *));
+    assert(typePtr->typeName != NULL);
+    if (NULL == typePtr->closeProc) {
+	Tcl_Panic("channel type %s must define closeProc", typePtr->typeName);
+    }
+    if ((TCL_READABLE & mask) && (NULL == typePtr->inputProc)) {
+	Tcl_Panic("channel type %s must define inputProc when used for reader channel", typePtr->typeName);
+    }
+    if ((TCL_WRITABLE & mask) &&  (NULL == typePtr->outputProc)) {
+	Tcl_Panic("channel type %s must define outputProc when used for writer channel", typePtr->typeName);
+    }
+    if (NULL == typePtr->watchProc) {
+	Tcl_Panic("channel type %s must define watchProc", typePtr->typeName);
+    }
+    if ((NULL!=typePtr->wideSeekProc) && (NULL == typePtr->seekProc)) {
+	Tcl_Panic("channel type %s must define seekProc if defining wideSeekProc", typePtr->typeName);
+    }
+
+    /*
+     * JH: We could subsequently memset these to 0 to avoid the numerous
+     * assignments to 0/NULL below.
+     */
+
+    chanPtr = ckalloc(sizeof(Channel));
+    statePtr = ckalloc(sizeof(ChannelState));
+    chanPtr->state = statePtr;
+
+    chanPtr->instanceData = instanceData;
+    chanPtr->typePtr = typePtr;
+
+    /*
+     * Set all the bits that are part of the stack-independent state
+     * information for the channel.
+     */
+
+    if (chanName != NULL) {
+	unsigned len = strlen(chanName) + 1;
+
+	/*
+         * Make sure we allocate at least 7 bytes, so it fits for "stdout"
+         * later.
+         */
+
+	tmp = ckalloc((len < 7) ? 7 : len);
+	strcpy(tmp, chanName);
+    } else {
+	tmp = ckalloc(7);
+	tmp[0] = '\0';
+    }
+    statePtr->channelName = tmp;
+    statePtr->flags = mask;
+
+    /*
+     * Set the channel to system default encoding.
+     *
+     * Note the strange bit of protection taking place here. If the system
+     * encoding name is reported back as "binary", something weird is
+     * happening. Tcl provides no "binary" encoding, so someone else has
+     * provided one. We ignore it so as not to interfere with the "magic"
+     * interpretation that Tcl_Channels give to the "-encoding binary" option.
+     */
+
+    statePtr->encoding = NULL;
+    name = Tcl_GetEncodingName(NULL);
+    if (strcmp(name, "binary") != 0) {
+	statePtr->encoding = Tcl_GetEncoding(NULL, name);
+    }
+    statePtr->inputEncodingState  = NULL;
+    statePtr->inputEncodingFlags  = TCL_ENCODING_START;
+    statePtr->outputEncodingState = NULL;
+    statePtr->outputEncodingFlags = TCL_ENCODING_START;
+
+    /*
+     * Set the channel up initially in AUTO input translation mode to accept
+     * "\n", "\r" and "\r\n". Output translation mode is set to a platform
+     * specific default value. The eofChar is set to 0 for both input and
+     * output, so that Tcl does not look for an in-file EOF indicator (e.g.
+     * ^Z) and does not append an EOF indicator to files.
+     */
+
+    statePtr->inputTranslation	= TCL_TRANSLATE_AUTO;
+    statePtr->outputTranslation	= TCL_PLATFORM_TRANSLATION;
+    statePtr->inEofChar		= 0;
+    statePtr->outEofChar	= 0;
+
+    statePtr->unreportedError	= 0;
+    statePtr->refCount		= 0;
+    statePtr->closeCbPtr	= NULL;
+    statePtr->curOutPtr		= NULL;
+    statePtr->outQueueHead	= NULL;
+    statePtr->outQueueTail	= NULL;
+    statePtr->saveInBufPtr	= NULL;
+    statePtr->inQueueHead	= NULL;
+    statePtr->inQueueTail	= NULL;
+    statePtr->chPtr		= NULL;
+    statePtr->interestMask	= 0;
+    statePtr->scriptRecordPtr	= NULL;
+    statePtr->bufSize		= CHANNELBUFFER_DEFAULT_SIZE;
+    statePtr->timer		= NULL;
+    statePtr->csPtrR		= NULL;
+    statePtr->csPtrW		= NULL;
+    statePtr->outputStage	= NULL;
+
+    /*
+     * As we are creating the channel, it is obviously the top for now.
+     */
+
+    statePtr->topChanPtr	= chanPtr;
+    statePtr->bottomChanPtr	= chanPtr;
+    chanPtr->downChanPtr	= NULL;
+    chanPtr->upChanPtr		= NULL;
+    chanPtr->inQueueHead	= NULL;
+    chanPtr->inQueueTail	= NULL;
+    chanPtr->refCount		= 0;
+
+    /*
+     * TIP #219, Tcl Channel Reflection API
+     */
+
+    statePtr->chanMsg		= NULL;
+    statePtr->unreportedMsg	= NULL;
+
+    statePtr->epoch		= 0;
+
+    /*
+     * Link the channel into the list of all channels; create an on-exit
+     * handler if there is not one already, to close off all the channels in
+     * the list on exit.
+     *
+     * JH: Could call Tcl_SpliceChannel, but need to avoid NULL check.
+     *
+     * TIP #218.
+     * AK: Just initialize the field to NULL before invoking Tcl_SpliceChannel
+     *	   We need Tcl_SpliceChannel, for the threadAction calls. There is no
+     *	   real reason to duplicate all of this.
+     * NOTE: All drivers using thread actions now have to perform their TSD
+     *	     manipulation only in their thread action proc. Doing it when
+     *	     creating their instance structures will collide with the thread
+     *	     action activity and lead to damaged lists.
+     */
+
+    statePtr->nextCSPtr = NULL;
+    SpliceChannel((Tcl_Channel) chanPtr);
+
+    /*
+     * Install this channel in the first empty standard channel slot, if the
+     * channel was previously closed explicitly.
+     */
+
+    if ((tsdPtr->stdinChannel == NULL) && (tsdPtr->stdinInitialized == 1)) {
+	strcpy(tmp, "stdin");
+	Tcl_SetStdChannel((Tcl_Channel) chanPtr, TCL_STDIN);
+	Tcl_RegisterChannel(NULL, (Tcl_Channel) chanPtr);
+    } else if ((tsdPtr->stdoutChannel == NULL) &&
+	    (tsdPtr->stdoutInitialized == 1)) {
+	strcpy(tmp, "stdout");
+	Tcl_SetStdChannel((Tcl_Channel) chanPtr, TCL_STDOUT);
+	Tcl_RegisterChannel(NULL, (Tcl_Channel) chanPtr);
+    } else if ((tsdPtr->stderrChannel == NULL) &&
+	    (tsdPtr->stderrInitialized == 1)) {
+	strcpy(tmp, "stderr");
+	Tcl_SetStdChannel((Tcl_Channel) chanPtr, TCL_STDERR);
+	Tcl_RegisterChannel(NULL, (Tcl_Channel) chanPtr);
+    }
+    return (Tcl_Channel) chanPtr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_StackChannel --
+ *
+ *	Replaces an entry in the hash table for a Tcl_Channel record. The
+ *	replacement is a new channel with same name, it supercedes the
+ *	replaced channel. Input and output of the superceded channel is now
+ *	going through the newly created channel and allows the arbitrary
+ *	filtering/manipulation of the dataflow.
+ *
+ *	Andreas Kupries <a.kupries@westend.com>, 12/13/1998 "Trf-Patch for
+ *	filtering channels"
+ *
+ * Results:
+ *	Returns the new Tcl_Channel, which actually contains the saved
+ *	information about prevChan.
+ *
+ * Side effects:
+ *	A new channel structure is allocated and linked below the existing
+ *	channel. The channel operations and client data of the existing
+ *	channel are copied down to the newly created channel, and the current
+ *	channel has its operations replaced by the new typePtr.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_Channel
+Tcl_StackChannel(
+    Tcl_Interp *interp,		/* The interpreter we are working in */
+    const Tcl_ChannelType *typePtr,
+				/* The channel type record for the new
+				 * channel. */
+    ClientData instanceData,	/* Instance specific data for the new
+				 * channel. */
+    int mask,			/* TCL_READABLE & TCL_WRITABLE to indicate if
+				 * the channel is readable, writable. */
+    Tcl_Channel prevChan)	/* The channel structure to replace */
+{
+    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+    Channel *chanPtr, *prevChanPtr;
+    ChannelState *statePtr;
+
+    /*
+     * Find the given channel (prevChan) in the list of all channels. If we do
+     * not find it, then it was never registered correctly.
+     *
+     * This operation should occur at the top of a channel stack.
+     */
+
+    statePtr = (ChannelState *) tsdPtr->firstCSPtr;
+    prevChanPtr = ((Channel *) prevChan)->state->topChanPtr;
+
+    while ((statePtr != NULL) && (statePtr->topChanPtr != prevChanPtr)) {
+	statePtr = statePtr->nextCSPtr;
+    }
+
+    if (statePtr == NULL) {
+	if (interp) {
+	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+                    "couldn't find state for channel \"%s\"",
+		    Tcl_GetChannelName(prevChan)));
+	}
+	return NULL;
+    }
+
+    /*
+     * Here we check if the given "mask" matches the "flags" of the already
+     * existing channel.
+     *
+     *	  | - | R | W | RW |
+     *	--+---+---+---+----+	<=>  0 != (chan->mask & prevChan->mask)
+     *	- |   |   |   |    |
+     *	R |   | + |   | +  |	The superceding channel is allowed to restrict
+     *	W |   |   | + | +  |	the capabilities of the superceded one!
+     *	RW|   | + | + | +  |
+     *	--+---+---+---+----+
+     */
+
+    if ((mask & (statePtr->flags & (TCL_READABLE | TCL_WRITABLE))) == 0) {
+	if (interp) {
+	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		    "reading and writing both disallowed for channel \"%s\"",
+		    Tcl_GetChannelName(prevChan)));
+	}
+	return NULL;
+    }
+
+    /*
+     * Flush the buffers. This ensures that any data still in them at this
+     * time is not handled by the new transformation. Restrict this to
+     * writable channels. Take care to hide a possible bg-copy in progress
+     * from Tcl_Flush and the CheckForChannelErrors inside.
+     */
+
+    if ((mask & TCL_WRITABLE) != 0) {
+	CopyState *csPtrR = statePtr->csPtrR;
+	CopyState *csPtrW = statePtr->csPtrW;
+
+	statePtr->csPtrR = NULL;
+	statePtr->csPtrW = NULL;
+
+	/*
+	 * TODO: Examine what can go wrong if Tcl_Flush() call disturbs
+	 * the stacking state of this channel during its operations.
+	 */
+	if (Tcl_Flush((Tcl_Channel) prevChanPtr) != TCL_OK) {
+	    statePtr->csPtrR = csPtrR;
+	    statePtr->csPtrW = csPtrW;
+	    if (interp) {
+		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+                        "could not flush channel \"%s\"",
+			Tcl_GetChannelName(prevChan)));
+	    }
+	    return NULL;
+	}
+
+	statePtr->csPtrR = csPtrR;
+	statePtr->csPtrW = csPtrW;
+    }
+
+    /*
+     * Discard any input in the buffers. They are not yet read by the user of
+     * the channel, so they have to go through the new transformation before
+     * reading. As the buffers contain the untransformed form their contents
+     * are not only useless but actually distorts our view of the system.
+     *
+     * To preserve the information without having to read them again and to
+     * avoid problems with the location in the channel (seeking might be
+     * impossible) we move the buffers from the common state structure into
+     * the channel itself. We use the buffers in the channel below the new
+     * transformation to hold the data. In the future this allows us to write
+     * transformations which pre-read data and push the unused part back when
+     * they are going away.
+     */
+
+    if (((mask & TCL_READABLE) != 0) && (statePtr->inQueueHead != NULL)) {
+
+	/*
+	 * When statePtr->inQueueHead is not NULL, we know
+	 * prevChanPtr->inQueueHead must be NULL.
+	 */
+
+	assert(prevChanPtr->inQueueHead == NULL);
+	assert(prevChanPtr->inQueueTail == NULL);
+
+	prevChanPtr->inQueueHead = statePtr->inQueueHead;
+	prevChanPtr->inQueueTail = statePtr->inQueueTail;
+
+	statePtr->inQueueHead = NULL;
+	statePtr->inQueueTail = NULL;
+    }
+
+    chanPtr = ckalloc(sizeof(Channel));
+
+    /*
+     * Save some of the current state into the new structure, reinitialize the
+     * parts which will stay with the transformation.
+     *
+     * Remarks:
+     */
+
+    chanPtr->state		= statePtr;
+    chanPtr->instanceData	= instanceData;
+    chanPtr->typePtr		= typePtr;
+    chanPtr->downChanPtr	= prevChanPtr;
+    chanPtr->upChanPtr		= NULL;
+    chanPtr->inQueueHead	= NULL;
+    chanPtr->inQueueTail	= NULL;
+    chanPtr->refCount		= 0;
+
+    /*
+     * Place new block at the head of a possibly existing list of previously
+     * stacked channels.
+     */
+
+    prevChanPtr->upChanPtr	= chanPtr;
+    statePtr->topChanPtr	= chanPtr;
+
+    /*
+     * TIP #218, Channel Thread Actions.
+     *
+     * We call the thread actions for the new channel directly. We _cannot_
+     * use SpliceChannel, because the (thread-)global list of all channels
+     * always contains the _ChannelState_ for a stack of channels, not the
+     * individual channels. And SpliceChannel would not only call the thread
+     * actions, but also add the shared ChannelState to this list a second
+     * time, mangling it.
+     */
+
+    ChanThreadAction(chanPtr, TCL_CHANNEL_THREAD_INSERT);
+
+    return (Tcl_Channel) chanPtr;
+}
+
+void
+TclChannelPreserve(
+    Tcl_Channel chan)
+{
+    ((Channel *)chan)->refCount++;
+}
+
+void
+TclChannelRelease(
+    Tcl_Channel chan)
+{
+    Channel *chanPtr = (Channel *) chan;
+
+    if (chanPtr->refCount == 0) {
+	Tcl_Panic("Channel released more than preserved");
+    }
+    if (--chanPtr->refCount) {
+	return;
+    }
+    if (chanPtr->typePtr == NULL) {
+	ckfree(chanPtr);
+    }
+}
+
+static void
+ChannelFree(
+    Channel *chanPtr)
+{
+    if (chanPtr->refCount == 0) {
+	ckfree(chanPtr);
+	return;
+    }
+    chanPtr->typePtr = NULL;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_UnstackChannel --
+ *
+ *	Unstacks an entry in the hash table for a Tcl_Channel record. This is
+ *	the reverse to 'Tcl_StackChannel'.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	If TCL_ERROR is returned, the posix error code will be set with
+ *	Tcl_SetErrno. May leave a message in interp result as well.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_UnstackChannel(
+    Tcl_Interp *interp,		/* The interpreter we are working in */
+    Tcl_Channel chan)		/* The channel to unstack */
+{
+    Channel *chanPtr = (Channel *) chan;
+    ChannelState *statePtr = chanPtr->state;
+    int result = 0;
+
+    /*
+     * This operation should occur at the top of a channel stack.
+     */
+
+    chanPtr = statePtr->topChanPtr;
+
+    if (chanPtr->downChanPtr != NULL) {
+	/*
+	 * Instead of manipulating the per-thread / per-interp list/hashtable
+	 * of registered channels we wind down the state of the
+	 * transformation, and then restore the state of underlying channel
+	 * into the old structure.
+	 */
+
+	/*
+	 * TODO: Figure out how to handle the situation where the chan
+	 * operations called below by this unstacking operation cause
+	 * another unstacking recursively.  In that case the downChanPtr
+	 * value we're holding on to will not be the right thing.
+	 */
+
+	Channel *downChanPtr = chanPtr->downChanPtr;
+
+	/*
+	 * Flush the buffers. This ensures that any data still in them at this
+	 * time _is_ handled by the transformation we are unstacking right
+	 * now. Restrict this to writable channels. Take care to hide a
+	 * possible bg-copy in progress from Tcl_Flush and the
+	 * CheckForChannelErrors inside.
+	 */
+
+	if (GotFlag(statePtr, TCL_WRITABLE)) {
+	    CopyState *csPtrR = statePtr->csPtrR;
+	    CopyState *csPtrW = statePtr->csPtrW;
+
+	    statePtr->csPtrR = NULL;
+	    statePtr->csPtrW = NULL;
+
+	    if (Tcl_Flush((Tcl_Channel) chanPtr) != TCL_OK) {
+		statePtr->csPtrR = csPtrR;
+		statePtr->csPtrW = csPtrW;
+
+		/*
+		 * TIP #219, Tcl Channel Reflection API.
+		 * Move error messages put by the driver into the chan/ip
+		 * bypass area into the regular interpreter result. Fall back
+		 * to the regular message if nothing was found in the
+		 * bypasses.
+		 */
+
+		if (!TclChanCaughtErrorBypass(interp, chan) && interp) {
+		    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+                            "could not flush channel \"%s\"",
+			    Tcl_GetChannelName((Tcl_Channel) chanPtr)));
+		}
+		return TCL_ERROR;
+	    }
+
+	    statePtr->csPtrR  = csPtrR;
+	    statePtr->csPtrW = csPtrW;
+	}
+
+	/*
+	 * Anything in the input queue and the push-back buffers of the
+	 * transformation going away is transformed data, but not yet read. As
+	 * unstacking means that the caller does not want to see transformed
+	 * data any more we have to discard these bytes. To avoid writing an
+	 * analogue to 'DiscardInputQueued' we move the information in the
+	 * push back buffers to the input queue and then call
+	 * 'DiscardInputQueued' on that.
+	 */
+
+	if (GotFlag(statePtr, TCL_READABLE) &&
+		((statePtr->inQueueHead != NULL) ||
+		(chanPtr->inQueueHead != NULL))) {
+	    if ((statePtr->inQueueHead != NULL) &&
+		    (chanPtr->inQueueHead != NULL)) {
+		statePtr->inQueueTail->nextPtr = chanPtr->inQueueHead;
+		statePtr->inQueueTail = chanPtr->inQueueTail;
+		statePtr->inQueueHead = statePtr->inQueueTail;
+	    } else if (chanPtr->inQueueHead != NULL) {
+		statePtr->inQueueHead = chanPtr->inQueueHead;
+		statePtr->inQueueTail = chanPtr->inQueueTail;
+	    }
+
+	    chanPtr->inQueueHead = NULL;
+	    chanPtr->inQueueTail = NULL;
+
+	    DiscardInputQueued(statePtr, 0);
+	}
+
+	/*
+	 * TIP #218, Channel Thread Actions.
+	 *
+	 * We call the thread actions for the new channel directly. We
+	 * _cannot_ use CutChannel, because the (thread-)global list of all
+	 * channels always contains the _ChannelState_ for a stack of
+	 * channels, not the individual channels. And SpliceChannel would not
+	 * only call the thread actions, but also remove the shared
+	 * ChannelState from this list despite there being more channels for
+	 * the state which are still active.
+	 */
+
+	ChanThreadAction(chanPtr, TCL_CHANNEL_THREAD_REMOVE);
+
+	statePtr->topChanPtr = downChanPtr;
+	downChanPtr->upChanPtr = NULL;
+
+	/*
+	 * Leave this link intact for closeproc
+	 *  chanPtr->downChanPtr = NULL;
+	 */
+
+	/*
+	 * Close and free the channel driver state.
+	 */
+
+	result = ChanClose(chanPtr, interp);
+	ChannelFree(chanPtr);
+
+	UpdateInterest(statePtr->topChanPtr);
+
+	if (result != 0) {
+	    Tcl_SetErrno(result);
+
+	    /*
+	     * TIP #219, Tcl Channel Reflection API.
+	     * Move error messages put by the driver into the chan/ip bypass
+	     * area into the regular interpreter result.
+	     */
+
+	    TclChanCaughtErrorBypass(interp, chan);
+	    return TCL_ERROR;
+	}
+    } else {
+	/*
+	 * This channel does not cover another one. Simply do a close, if
+	 * necessary.
+	 */
+
+	if (statePtr->refCount <= 0) {
+	    if (Tcl_Close(interp, chan) != TCL_OK) {
+		/*
+		 * TIP #219, Tcl Channel Reflection API.
+		 * "TclChanCaughtErrorBypass" is not required here, it was
+		 * done already by "Tcl_Close".
+		 */
+
+		return TCL_ERROR;
+	    }
+	}
+
+	/*
+	 * TIP #218, Channel Thread Actions.
+	 * Not required in this branch, this is done by Tcl_Close. If
+	 * Tcl_Close is not called then the ChannelState is still active in
+	 * the thread and no action has to be taken either.
+	 */
+    }
+
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_GetStackedChannel --
+ *
+ *	Determines whether the specified channel is stacked upon another.
+ *
+ * Results:
+ *	NULL if the channel is not stacked upon another one, or a reference to
+ *	the channel it is stacked upon. This reference can be used in queries,
+ *	but modification is not allowed.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_Channel
+Tcl_GetStackedChannel(
+    Tcl_Channel chan)
+{
+    Channel *chanPtr = (Channel *) chan;
+				/* The actual channel. */
+
+    return (Tcl_Channel) chanPtr->downChanPtr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_GetTopChannel --
+ *
+ *	Returns the top channel of a channel stack.
+ *
+ * Results:
+ *	NULL if the channel is not stacked upon another one, or a reference to
+ *	the channel it is stacked upon. This reference can be used in queries,
+ *	but modification is not allowed.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_Channel
+Tcl_GetTopChannel(
+    Tcl_Channel chan)
+{
+    Channel *chanPtr = (Channel *) chan;
+				/* The actual channel. */
+
+    return (Tcl_Channel) chanPtr->state->topChanPtr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_GetChannelInstanceData --
+ *
+ *	Returns the client data associated with a channel.
+ *
+ * Results:
+ *	The client data.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+ClientData
+Tcl_GetChannelInstanceData(
+    Tcl_Channel chan)		/* Channel for which to return client data. */
+{
+    Channel *chanPtr = (Channel *) chan;
+				/* The actual channel. */
+
+    return chanPtr->instanceData;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_GetChannelThread --
+ *
+ *	Given a channel structure, returns the thread managing it. TIP #10
+ *
+ * Results:
+ *	Returns the id of the thread managing the channel.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_ThreadId
+Tcl_GetChannelThread(
+    Tcl_Channel chan)		/* The channel to return the managing thread
+				 * for. */
+{
+    Channel *chanPtr = (Channel *) chan;
+				/* The actual channel. */
+
+    return chanPtr->state->managingThread;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_GetChannelType --
+ *
+ *	Given a channel structure, returns the channel type structure.
+ *
+ * Results:
+ *	Returns a pointer to the channel type structure.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+const Tcl_ChannelType *
+Tcl_GetChannelType(
+    Tcl_Channel chan)		/* The channel to return type for. */
+{
+    Channel *chanPtr = (Channel *) chan;
+				/* The actual channel. */
+
+    return chanPtr->typePtr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_GetChannelMode --
+ *
+ *	Computes a mask indicating whether the channel is open for reading and
+ *	writing.
+ *
+ * Results:
+ *	An OR-ed combination of TCL_READABLE and TCL_WRITABLE.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_GetChannelMode(
+    Tcl_Channel chan)		/* The channel for which the mode is being
+				 * computed. */
+{
+    ChannelState *statePtr = ((Channel *) chan)->state;
+				/* State of actual channel. */
+
+    return (statePtr->flags & (TCL_READABLE | TCL_WRITABLE));
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_GetChannelName --
+ *
+ *	Returns the string identifying the channel name.
+ *
+ * Results:
+ *	The string containing the channel name. This memory is owned by the
+ *	generic layer and should not be modified by the caller.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+const char *
+Tcl_GetChannelName(
+    Tcl_Channel chan)		/* The channel for which to return the name. */
+{
+    ChannelState *statePtr = ((Channel *) chan)->state;
+				/* State of actual channel. */
+
+    return statePtr->channelName;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_GetChannelHandle --
+ *
+ *	Returns an OS handle associated with a channel.
+ *
+ * Results:
+ *	Returns TCL_OK and places the handle in handlePtr, or returns
+ *	TCL_ERROR on failure.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_GetChannelHandle(
+    Tcl_Channel chan,		/* The channel to get file from. */
+    int direction,		/* TCL_WRITABLE or TCL_READABLE. */
+    ClientData *handlePtr)	/* Where to store handle */
+{
+    Channel *chanPtr;		/* The actual channel. */
+    ClientData handle;
+    int result;
+
+    chanPtr = ((Channel *) chan)->state->bottomChanPtr;
+    if (!chanPtr->typePtr->getHandleProc) {
+        Tcl_SetChannelError(chan, Tcl_ObjPrintf(
+                "channel \"%s\" does not support OS handles",
+                Tcl_GetChannelName(chan)));
+	return TCL_ERROR;
+    }
+    result = chanPtr->typePtr->getHandleProc(chanPtr->instanceData, direction,
+	    &handle);
+    if (handlePtr) {
+	*handlePtr = handle;
+    }
+    return result;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * AllocChannelBuffer --
+ *
+ *	A channel buffer has BUFFER_PADDING bytes extra at beginning to hold
+ *	any bytes of a native-encoding character that got split by the end of
+ *	the previous buffer and need to be moved to the beginning of the next
+ *	buffer to make a contiguous string so it can be converted to UTF-8.
+ *
+ *	A channel buffer has BUFFER_PADDING bytes extra at the end to hold any
+ *	bytes of a native-encoding character (generated from a UTF-8
+ *	character) that overflow past the end of the buffer and need to be
+ *	moved to the next buffer.
+ *
+ * Results:
+ *	A newly allocated channel buffer.
+ *
+ * Side effects:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+static ChannelBuffer *
+AllocChannelBuffer(
+    int length)			/* Desired length of channel buffer. */
+{
+    ChannelBuffer *bufPtr;
+    int n;
+
+    n = length + CHANNELBUFFER_HEADER_SIZE + BUFFER_PADDING + BUFFER_PADDING;
+    bufPtr = ckalloc(n);
+    bufPtr->nextAdded	= BUFFER_PADDING;
+    bufPtr->nextRemoved	= BUFFER_PADDING;
+    bufPtr->bufLength	= length + BUFFER_PADDING;
+    bufPtr->nextPtr	= NULL;
+    bufPtr->refCount	= 1;
+    return bufPtr;
+}
+
+static void
+PreserveChannelBuffer(
+    ChannelBuffer *bufPtr)
+{
+    if (bufPtr->refCount == 0) {
+	Tcl_Panic("Reuse of ChannelBuffer! %p", bufPtr);
+    }
+    bufPtr->refCount++;
+}
+
+static void
+ReleaseChannelBuffer(
+    ChannelBuffer *bufPtr)
+{
+    if (--bufPtr->refCount) {
+	return;
+    }
+    ckfree(bufPtr);
+}
+
+static int
+IsShared(
+    ChannelBuffer *bufPtr)
+{
+    return bufPtr->refCount > 1;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * RecycleBuffer --
+ *
+ *	Helper function to recycle input and output buffers. Ensures that two
+ *	input buffers are saved (one in the input queue and another in the
+ *	saveInBufPtr field) and that curOutPtr is set to a buffer. Only if
+ *	these conditions are met is the buffer freed to the OS.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	May free a buffer to the OS.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+RecycleBuffer(
+    ChannelState *statePtr,	/* ChannelState in which to recycle buffers. */
+    ChannelBuffer *bufPtr,	/* The buffer to recycle. */
+    int mustDiscard)		/* If nonzero, free the buffer to the OS,
+				 * always. */
+{
+    /*
+     * Do we have to free the buffer to the OS?
+     */
+    if (IsShared(bufPtr)) {
+	mustDiscard = 1;
+    }
+
+    if (mustDiscard) {
+	ReleaseChannelBuffer(bufPtr);
+	return;
+    }
+
+    /*
+     * Only save buffers which have the requested buffersize for the
+     * channel. This is to honor dynamic changes of the buffersize
+     * made by the user.
+     */
+
+    if ((bufPtr->bufLength - BUFFER_PADDING) != statePtr->bufSize) {
+	ReleaseChannelBuffer(bufPtr);
+	return;
+    }
+
+    /*
+     * Only save buffers for the input queue if the channel is readable.
+     */
+
+    if (GotFlag(statePtr, TCL_READABLE)) {
+	if (statePtr->inQueueHead == NULL) {
+	    statePtr->inQueueHead = bufPtr;
+	    statePtr->inQueueTail = bufPtr;
+	    goto keepBuffer;
+	}
+	if (statePtr->saveInBufPtr == NULL) {
+	    statePtr->saveInBufPtr = bufPtr;
+	    goto keepBuffer;
+	}
+    }
+
+    /*
+     * Only save buffers for the output queue if the channel is writable.
+     */
+
+    if (GotFlag(statePtr, TCL_WRITABLE)) {
+	if (statePtr->curOutPtr == NULL) {
+	    statePtr->curOutPtr = bufPtr;
+	    goto keepBuffer;
+	}
+    }
+
+    /*
+     * If we reached this code we return the buffer to the OS.
+     */
+
+    ReleaseChannelBuffer(bufPtr);
+    return;
+
+  keepBuffer:
+    bufPtr->nextRemoved = BUFFER_PADDING;
+    bufPtr->nextAdded = BUFFER_PADDING;
+    bufPtr->nextPtr = NULL;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * DiscardOutputQueued --
+ *
+ *	Discards all output queued in the output queue of a channel.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Recycles buffers.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+DiscardOutputQueued(
+    ChannelState *statePtr)	/* ChannelState for which to discard output. */
+{
+    ChannelBuffer *bufPtr;
+
+    while (statePtr->outQueueHead != NULL) {
+	bufPtr = statePtr->outQueueHead;
+	statePtr->outQueueHead = bufPtr->nextPtr;
+	RecycleBuffer(statePtr, bufPtr, 0);
+    }
+    statePtr->outQueueHead = NULL;
+    statePtr->outQueueTail = NULL;
+    bufPtr = statePtr->curOutPtr;
+    if (bufPtr && BytesLeft(bufPtr)) {
+	statePtr->curOutPtr = NULL;
+	RecycleBuffer(statePtr, bufPtr, 0);
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * CheckForDeadChannel --
+ *
+ *	This function checks is a given channel is Dead (a channel that has
+ *	been closed but not yet deallocated.)
+ *
+ * Results:
+ *	True (1) if channel is Dead, False (0) if channel is Ok
+ *
+ * Side effects:
+ *	None
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+CheckForDeadChannel(
+    Tcl_Interp *interp,		/* For error reporting (can be NULL) */
+    ChannelState *statePtr)	/* The channel state to check. */
+{
+    if (!GotFlag(statePtr, CHANNEL_DEAD)) {
+	return 0;
+    }
+
+    Tcl_SetErrno(EINVAL);
+    if (interp) {
+	Tcl_SetObjResult(interp, Tcl_NewStringObj(
+                "unable to access channel: invalid channel", -1));
+    }
+    return 1;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * FlushChannel --
+ *
+ *	This function flushes as much of the queued output as is possible now.
+ *	If calledFromAsyncFlush is nonzero, it is being called in an event
+ *	handler to flush channel output asynchronously.
+ *
+ * Results:
+ *	0 if successful, else the error code that was returned by the channel
+ *	type operation. May leave a message in the interp result.
+ *
+ * Side effects:
+ *	May produce output on a channel. May block indefinitely if the channel
+ *	is synchronous. May schedule an async flush on the channel. May
+ *	recycle memory for buffers in the output queue.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+FlushChannel(
+    Tcl_Interp *interp,		/* For error reporting during close. */
+    Channel *chanPtr,		/* The channel to flush on. */
+    int calledFromAsyncFlush)	/* If nonzero then we are being called from an
+				 * asynchronous flush callback. */
+{
+    ChannelState *statePtr = chanPtr->state;
+				/* State of the channel stack. */
+    ChannelBuffer *bufPtr;	/* Iterates over buffered output queue. */
+    int written;		/* Amount of output data actually written in
+				 * current round. */
+    int errorCode = 0;		/* Stores POSIX error codes from channel
+				 * driver operations. */
+    int wroteSome = 0;		/* Set to one if any data was written to the
+				 * driver. */
+
+    /*
+     * Prevent writing on a dead channel -- a channel that has been closed but
+     * not yet deallocated. This can occur if the exit handler for the channel
+     * deallocation runs before all channels are deregistered in all
+     * interpreters.
+     */
+
+    if (CheckForDeadChannel(interp, statePtr)) {
+	return -1;
+    }
+
+    /*
+     * Should we shift the current output buffer over to the output queue?
+     * First check that there are bytes in it.  If so then...
+     * If the output queue is empty, then yes, trusting the caller called
+     * us only when written bytes ought to be flushed.
+     * If the current output buffer is full, then yes, so we can meet
+     * the post-condition that on a successful return to caller we've
+     * left space in the current output buffer for more writing (the flush
+     * call was to make new room).
+     * If the channel is blocking, then yes, so we guarantee that
+     * blocking flushes actually flush all pending data.
+     * Otherwise, no.  Keep the current output buffer where it is so more
+     * can be written to it, possibly filling it, to promote more efficient
+     * buffer usage.
+     */
+
+    bufPtr = statePtr->curOutPtr;
+    if (bufPtr && BytesLeft(bufPtr) && /* Keep empties off queue */
+	    (statePtr->outQueueHead == NULL || IsBufferFull(bufPtr)
+		    || !GotFlag(statePtr, CHANNEL_NONBLOCKING))) {
+	if (statePtr->outQueueHead == NULL) {
+	    statePtr->outQueueHead = bufPtr;
+	} else {
+	    statePtr->outQueueTail->nextPtr = bufPtr;
+	}
+	statePtr->outQueueTail = bufPtr;
+	statePtr->curOutPtr = NULL;
+    }
+
+    assert(!IsBufferFull(statePtr->curOutPtr));
+
+    /*
+     * If we are not being called from an async flush and an async flush
+     * is active, we just return without producing any output.
+     */
+
+    if (!calledFromAsyncFlush && GotFlag(statePtr, BG_FLUSH_SCHEDULED)) {
+	return 0;
+    }
+
+    /*
+     * Loop over the queued buffers and attempt to flush as much as possible
+     * of the queued output to the channel.
+     */
+
+    TclChannelPreserve((Tcl_Channel)chanPtr);
+    while (statePtr->outQueueHead) {
+	bufPtr = statePtr->outQueueHead;
+
+	/*
+	 * Produce the output on the channel.
+	 */
+
+	PreserveChannelBuffer(bufPtr);
+	written = ChanWrite(chanPtr, RemovePoint(bufPtr), BytesLeft(bufPtr),
+		&errorCode);
+
+	/*
+	 * If the write failed completely attempt to start the asynchronous
+	 * flush mechanism and break out of this loop - do not attempt to
+	 * write any more output at this time.
+	 */
+
+	if (written < 0) {
+	    /*
+	     * If the last attempt to write was interrupted, simply retry.
+	     */
+
+	    if (errorCode == EINTR) {
+		errorCode = 0;
+		ReleaseChannelBuffer(bufPtr);
+		continue;
+	    }
+
+	    /*
+	     * If the channel is non-blocking and we would have blocked, start
+	     * a background flushing handler and break out of the loop.
+	     */
+
+	    if ((errorCode == EWOULDBLOCK) || (errorCode == EAGAIN)) {
+		/*
+		 * This used to check for CHANNEL_NONBLOCKING, and panic if
+		 * the channel was blocking. However, it appears that setting
+		 * stdin to -blocking 0 has some effect on the stdout when
+		 * it's a tty channel (dup'ed underneath)
+		 */
+
+		if (!GotFlag(statePtr, BG_FLUSH_SCHEDULED) && !TclInExit()) {
+		    SetFlag(statePtr, BG_FLUSH_SCHEDULED);
+		    UpdateInterest(chanPtr);
+		}
+		errorCode = 0;
+		ReleaseChannelBuffer(bufPtr);
+		break;
+	    }
+
+	    /*
+	     * Decide whether to report the error upwards or defer it.
+	     */
+
+	    if (calledFromAsyncFlush) {
+		/*
+		 * TIP #219, Tcl Channel Reflection API.
+		 * When defering the error copy a message from the bypass into
+		 * the unreported area. Or discard it if the new error is to be
+		 * ignored in favor of an earlier defered error.
+		 */
+
+		Tcl_Obj *msg = statePtr->chanMsg;
+
+		if (statePtr->unreportedError == 0) {
+		    statePtr->unreportedError = errorCode;
+		    statePtr->unreportedMsg = msg;
+		    if (msg != NULL) {
+			Tcl_IncrRefCount(msg);
+		    }
+		} else {
+		    /*
+		     * An old unreported error is kept, and this error thrown
+		     * away.
+		     */
+
+		    statePtr->chanMsg = NULL;
+		    if (msg != NULL) {
+			TclDecrRefCount(msg);
+		    }
+		}
+	    } else {
+		/*
+		 * TIP #219, Tcl Channel Reflection API.
+		 * Move error messages put by the driver into the chan bypass
+		 * area into the regular interpreter result. Fall back to the
+		 * regular message if nothing was found in the bypasses.
+		 */
+
+		Tcl_SetErrno(errorCode);
+		if (interp != NULL && !TclChanCaughtErrorBypass(interp,
+			(Tcl_Channel) chanPtr)) {
+		    Tcl_SetObjResult(interp,
+			    Tcl_NewStringObj(Tcl_PosixError(interp), -1));
+		}
+
+		/*
+		 * An unreportable bypassed message is kept, for the caller of
+		 * Tcl_Seek, Tcl_Write, etc.
+		 */
+	    }
+
+	    /*
+	     * When we get an error we throw away all the output currently
+	     * queued.
+	     */
+
+	    DiscardOutputQueued(statePtr);
+	    ReleaseChannelBuffer(bufPtr);
+	    break;
+	} else {
+	    /* TODO: Consider detecting and reacting to short writes
+	     * on blocking channels.  Ought not happen.  See iocmd-24.2. */
+	    wroteSome = 1;
+	}
+
+	bufPtr->nextRemoved += written;
+
+	/*
+	 * If this buffer is now empty, recycle it.
+	 */
+
+	if (IsBufferEmpty(bufPtr)) {
+	    statePtr->outQueueHead = bufPtr->nextPtr;
+	    if (statePtr->outQueueHead == NULL) {
+		statePtr->outQueueTail = NULL;
+	    }
+	    RecycleBuffer(statePtr, bufPtr, 0);
+	}
+	ReleaseChannelBuffer(bufPtr);
+    }	/* Closes "while". */
+
+    /*
+     * If we wrote some data while flushing in the background, we are done.
+     * We can't finish the background flush until we run out of data and the
+     * channel becomes writable again. This ensures that all of the pending
+     * data has been flushed at the system level.
+     */
+
+    if (GotFlag(statePtr, BG_FLUSH_SCHEDULED)) {
+	if (wroteSome) {
+	    goto done;
+	} else if (statePtr->outQueueHead == NULL) {
+	    ResetFlag(statePtr, BG_FLUSH_SCHEDULED);
+	    ChanWatch(chanPtr, statePtr->interestMask);
+	} else {
+
+	    /*
+	     * When we are calledFromAsyncFlush, that means a writable
+	     * state on the channel triggered the call, so we should be
+	     * able to write something.  Either we did write something
+	     * and wroteSome should be set, or there was nothing left to
+	     * write in this call, and we've completed the BG flush.
+	     * These are the two cases above.  If we get here, that means
+	     * there is some kind failure in the writable event machinery.
+	     *
+	     * The tls extension indeed suffers from flaws in its channel
+	     * event mgmt.  See http://core.tcl.tk/tcl/info/c31ca233ca.
+	     * Until that patch is broadly distributed, disable the
+	     * assertion checking here, so that programs using Tcl and
+	     * tls can be debugged.
+
+	    assert(!calledFromAsyncFlush);
+	     */
+	}
+    }
+
+    /*
+     * If the channel is flagged as closed, delete it when the refCount drops
+     * to zero, the output queue is empty and there is no output in the
+     * current output buffer.
+     */
+
+    if (GotFlag(statePtr, CHANNEL_CLOSED) && (statePtr->refCount <= 0) &&
+	    (statePtr->outQueueHead == NULL) &&
+	    ((statePtr->curOutPtr == NULL) ||
+	    IsBufferEmpty(statePtr->curOutPtr))) {
+	errorCode = CloseChannel(interp, chanPtr, errorCode);
+	goto done;
+    }
+
+    /*
+     * If the write-side of the channel is flagged as closed, delete it when
+     * the output queue is empty and there is no output in the current output
+     * buffer.
+     */
+
+    if (GotFlag(statePtr, CHANNEL_CLOSEDWRITE) &&
+	    (statePtr->outQueueHead == NULL) &&
+	    ((statePtr->curOutPtr == NULL) ||
+	    IsBufferEmpty(statePtr->curOutPtr))) {
+	errorCode = CloseChannelPart(interp, chanPtr, errorCode, TCL_CLOSE_WRITE);
+	goto done;
+    }
+
+  done:
+    TclChannelRelease((Tcl_Channel)chanPtr);
+    return errorCode;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * CloseChannel --
+ *
+ *	Utility procedure to close a channel and free associated resources.
+ *
+ *	If the channel was stacked, then the it will copy the necessary
+ *	elements of the NEXT channel into the TOP channel, in essence
+ *	unstacking the channel. The NEXT channel will then be freed.
+ *
+ *	If the channel was not stacked, then we will free all the bits for the
+ *	TOP channel, including the data structure itself.
+ *
+ * Results:
+ *	Error code from an unreported error or the driver close operation.
+ *
+ * Side effects:
+ *	May close the actual channel, may free memory, may change the value of
+ *	errno.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+CloseChannel(
+    Tcl_Interp *interp,		/* For error reporting. */
+    Channel *chanPtr,		/* The channel to close. */
+    int errorCode)		/* Status of operation so far. */
+{
+    int result = 0;		/* Of calling driver close operation. */
+    ChannelState *statePtr;	/* State of the channel stack. */
+    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+
+    if (chanPtr == NULL) {
+	return result;
+    }
+    statePtr = chanPtr->state;
+
+    /*
+     * No more input can be consumed so discard any leftover input.
+     */
+
+    DiscardInputQueued(statePtr, 1);
+
+    /*
+     * Discard a leftover buffer in the current output buffer field.
+     */
+
+    if (statePtr->curOutPtr != NULL) {
+	ReleaseChannelBuffer(statePtr->curOutPtr);
+	statePtr->curOutPtr = NULL;
+    }
+
+    /*
+     * The caller guarantees that there are no more buffers queued for output.
+     */
+
+    if (statePtr->outQueueHead != NULL) {
+	Tcl_Panic("TclFlush, closed channel: queued output left");
+    }
+
+    /*
+     * If the EOF character is set in the channel, append that to the output
+     * device.
+     */
+
+    if ((statePtr->outEofChar != 0) && GotFlag(statePtr, TCL_WRITABLE)) {
+	int dummy;
+	char c = (char) statePtr->outEofChar;
+
+	(void) ChanWrite(chanPtr, &c, 1, &dummy);
+    }
+
+    /*
+     * TIP #219, Tcl Channel Reflection API.
+     * Move a leftover error message in the channel bypass into the
+     * interpreter bypass. Just clear it if there is no interpreter.
+     */
+
+    if (statePtr->chanMsg != NULL) {
+	if (interp != NULL) {
+	    Tcl_SetChannelErrorInterp(interp, statePtr->chanMsg);
+	}
+	TclDecrRefCount(statePtr->chanMsg);
+	statePtr->chanMsg = NULL;
+    }
+
+    /*
+     * Remove this channel from of the list of all channels.
+     */
+
+    CutChannel((Tcl_Channel) chanPtr);
+
+    /*
+     * Close and free the channel driver state.
+     * This may leave a TIP #219 error message in the interp.
+     */
+
+    result = ChanClose(chanPtr, interp);
+
+    /*
+     * Some resources can be cleared only if the bottom channel in a stack is
+     * closed. All the other channels in the stack are not allowed to remove.
+     */
+
+    if (chanPtr == statePtr->bottomChanPtr) {
+	if (statePtr->channelName != NULL) {
+	    ckfree(statePtr->channelName);
+	    statePtr->channelName = NULL;
+	}
+
+	Tcl_FreeEncoding(statePtr->encoding);
+    }
+
+    /*
+     * If we are being called synchronously, report either any latent error on
+     * the channel or the current error.
+     */
+
+    if (statePtr->unreportedError != 0) {
+	errorCode = statePtr->unreportedError;
+
+	/*
+	 * TIP #219, Tcl Channel Reflection API.
+	 * Move an error message found in the unreported area into the regular
+	 * bypass (interp). This kills any message in the channel bypass area.
+	 */
+
+	if (statePtr->chanMsg != NULL) {
+	    TclDecrRefCount(statePtr->chanMsg);
+	    statePtr->chanMsg = NULL;
+	}
+	if (interp) {
+	    Tcl_SetChannelErrorInterp(interp, statePtr->unreportedMsg);
+	}
+    }
+    if (errorCode == 0) {
+	errorCode = result;
+	if (errorCode != 0) {
+	    Tcl_SetErrno(errorCode);
+	}
+    }
+
+    /*
+     * Cancel any outstanding timer.
+     */
+
+    Tcl_DeleteTimerHandler(statePtr->timer);
+
+    /*
+     * Mark the channel as deleted by clearing the type structure.
+     */
+
+    if (chanPtr->downChanPtr != NULL) {
+	Channel *downChanPtr = chanPtr->downChanPtr;
+
+	statePtr->nextCSPtr = tsdPtr->firstCSPtr;
+	tsdPtr->firstCSPtr = statePtr;
+
+	statePtr->topChanPtr = downChanPtr;
+	downChanPtr->upChanPtr = NULL;
+
+	ChannelFree(chanPtr);
+
+	return Tcl_Close(interp, (Tcl_Channel) downChanPtr);
+    }
+
+    /*
+     * There is only the TOP Channel, so we free the remaining pointers we
+     * have and then ourselves. Since this is the last of the channels in the
+     * stack, make sure to free the ChannelState structure associated with it.
+     */
+
+    ChannelFree(chanPtr);
+
+    Tcl_EventuallyFree(statePtr, TCL_DYNAMIC);
+
+    return errorCode;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_CutChannel --
+ * CutChannel --
+ *
+ *	Removes a channel from the (thread-)global list of all channels (in
+ *	that thread). This is actually the statePtr for the stack of channel.
+ *
+ * Results:
+ *	Nothing.
+ *
+ * Side effects:
+ *	Resets the field 'nextCSPtr' of the specified channel state to NULL.
+ *
+ * NOTE:
+ *	The channel to cut out of the list must not be referenced in any
+ *	interpreter. This is something this procedure cannot check (despite
+ *	the refcount) because the caller usually wants fiddle with the channel
+ *	(like transfering it to a different thread) and thus keeps the
+ *	refcount artifically high to prevent its destruction.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+CutChannel(
+    Tcl_Channel chan)		/* The channel being removed. Must not be
+				 * referenced in any interpreter. */
+{
+    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+    ChannelState *prevCSPtr;	/* Preceding channel state in list of all
+				 * states - used to splice a channel out of
+				 * the list on close. */
+    ChannelState *statePtr = ((Channel *) chan)->state;
+				/* State of the channel stack. */
+
+    /*
+     * Remove this channel from of the list of all channels (in the current
+     * thread).
+     */
+
+    if (tsdPtr->firstCSPtr && (statePtr == tsdPtr->firstCSPtr)) {
+	tsdPtr->firstCSPtr = statePtr->nextCSPtr;
+    } else {
+	for (prevCSPtr = tsdPtr->firstCSPtr;
+		prevCSPtr && (prevCSPtr->nextCSPtr != statePtr);
+		prevCSPtr = prevCSPtr->nextCSPtr) {
+	    /* Empty loop body. */
+	}
+	if (prevCSPtr == NULL) {
+	    Tcl_Panic("FlushChannel: damaged channel list");
+	}
+	prevCSPtr->nextCSPtr = statePtr->nextCSPtr;
+    }
+
+    statePtr->nextCSPtr = NULL;
+
+    /*
+     * TIP #218, Channel Thread Actions
+     */
+
+    ChanThreadAction((Channel *) chan, TCL_CHANNEL_THREAD_REMOVE);
+}
+
+void
+Tcl_CutChannel(
+    Tcl_Channel chan)		/* The channel being added. Must not be
+				 * referenced in any interpreter. */
+{
+    Channel *chanPtr = ((Channel *) chan)->state->bottomChanPtr;
+    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+    ChannelState *prevCSPtr;	/* Preceding channel state in list of all
+				 * states - used to splice a channel out of
+				 * the list on close. */
+    ChannelState *statePtr = chanPtr->state;
+				/* State of the channel stack. */
+
+    /*
+     * Remove this channel from of the list of all channels (in the current
+     * thread).
+     */
+
+    if (tsdPtr->firstCSPtr && (statePtr == tsdPtr->firstCSPtr)) {
+	tsdPtr->firstCSPtr = statePtr->nextCSPtr;
+    } else {
+	for (prevCSPtr = tsdPtr->firstCSPtr;
+		prevCSPtr && (prevCSPtr->nextCSPtr != statePtr);
+		prevCSPtr = prevCSPtr->nextCSPtr) {
+	    /* Empty loop body. */
+	}
+	if (prevCSPtr == NULL) {
+	    Tcl_Panic("FlushChannel: damaged channel list");
+	}
+	prevCSPtr->nextCSPtr = statePtr->nextCSPtr;
+    }
+
+    statePtr->nextCSPtr = NULL;
+
+    /*
+     * TIP #218, Channel Thread Actions
+     * For all transformations and the base channel.
+     */
+
+    for (; chanPtr != NULL ; chanPtr = chanPtr->upChanPtr) {
+	ChanThreadAction(chanPtr, TCL_CHANNEL_THREAD_REMOVE);
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_SpliceChannel --
+ * SpliceChannel --
+ *
+ *	Adds a channel to the (thread-)global list of all channels (in that
+ *	thread). Expects that the field 'nextChanPtr' in the channel is set to
+ *	NULL.
+ *
+ * Results:
+ *	Nothing.
+ *
+ * Side effects:
+ *	Nothing.
+ *
+ * NOTE:
+ *	The channel to splice into the list must not be referenced in any
+ *	interpreter. This is something this procedure cannot check (despite
+ *	the refcount) because the caller usually wants figgle with the channel
+ *	(like transfering it to a different thread) and thus keeps the
+ *	refcount artifically high to prevent its destruction.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+SpliceChannel(
+    Tcl_Channel chan)		/* The channel being added. Must not be
+				 * referenced in any interpreter. */
+{
+    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+    ChannelState *statePtr = ((Channel *) chan)->state;
+
+    if (statePtr->nextCSPtr != NULL) {
+	Tcl_Panic("SpliceChannel: trying to add channel used in different list");
+    }
+
+    statePtr->nextCSPtr = tsdPtr->firstCSPtr;
+    tsdPtr->firstCSPtr = statePtr;
+
+    /*
+     * TIP #10. Mark the current thread as the new one managing this channel.
+     *		Note: 'Tcl_GetCurrentThread' returns sensible values even for
+     *		a non-threaded core.
+     */
+
+    statePtr->managingThread = Tcl_GetCurrentThread();
+
+    /*
+     * TIP #218, Channel Thread Actions
+     */
+
+    ChanThreadAction((Channel *) chan, TCL_CHANNEL_THREAD_INSERT);
+}
+
+void
+Tcl_SpliceChannel(
+    Tcl_Channel chan)		/* The channel being added. Must not be
+				 * referenced in any interpreter. */
+{
+    Channel *chanPtr = ((Channel *) chan)->state->bottomChanPtr;
+    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+    ChannelState *statePtr = chanPtr->state;
+
+    if (statePtr->nextCSPtr != NULL) {
+	Tcl_Panic("SpliceChannel: trying to add channel used in different list");
+    }
+
+    statePtr->nextCSPtr = tsdPtr->firstCSPtr;
+    tsdPtr->firstCSPtr = statePtr;
+
+    /*
+     * TIP #10. Mark the current thread as the new one managing this channel.
+     *		Note: 'Tcl_GetCurrentThread' returns sensible values even for
+     *		a non-threaded core.
+     */
+
+    statePtr->managingThread = Tcl_GetCurrentThread();
+
+    /*
+     * TIP #218, Channel Thread Actions
+     * For all transformations and the base channel.
+     */
+
+    for (; chanPtr != NULL ; chanPtr = chanPtr->upChanPtr) {
+	ChanThreadAction(chanPtr, TCL_CHANNEL_THREAD_INSERT);
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_Close --
+ *
+ *	Closes a channel.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	Closes the channel if this is the last reference.
+ *
+ * NOTE:
+ *	Tcl_Close removes the channel as far as the user is concerned.
+ *	However, it may continue to exist for a while longer if it has a
+ *	background flush scheduled. The device itself is eventually closed and
+ *	the channel record removed, in CloseChannel, above.
+ *
+ *----------------------------------------------------------------------
+ */
+
+	/* ARGSUSED */
+int
+Tcl_Close(
+    Tcl_Interp *interp,		/* Interpreter for errors. */
+    Tcl_Channel chan)		/* The channel being closed. Must not be
+				 * referenced in any interpreter. */
+{
+    CloseCallback *cbPtr;	/* Iterate over close callbacks for this
+				 * channel. */
+    Channel *chanPtr;		/* The real IO channel. */
+    ChannelState *statePtr;	/* State of real IO channel. */
+    int result;			/* Of calling FlushChannel. */
+    int flushcode;
+    int stickyError;
+
+    if (chan == NULL) {
+	return TCL_OK;
+    }
+
+    /*
+     * Perform special handling for standard channels being closed. If the
+     * refCount is now 1 it means that the last reference to the standard
+     * channel is being explicitly closed, so bump the refCount down
+     * artificially to 0. This will ensure that the channel is actually
+     * closed, below. Also set the static pointer to NULL for the channel.
+     */
+
+    CheckForStdChannelsBeingClosed(chan);
+
+    /*
+     * This operation should occur at the top of a channel stack.
+     */
+
+    chanPtr = (Channel *) chan;
+    statePtr = chanPtr->state;
+    chanPtr = statePtr->topChanPtr;
+
+    if (statePtr->refCount > 0) {
+	Tcl_Panic("called Tcl_Close on channel with refCount > 0");
+    }
+
+    if (GotFlag(statePtr, CHANNEL_INCLOSE)) {
+	if (interp) {
+	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
+                    "illegal recursive call to close through close-handler"
+                    " of channel", -1));
+	}
+	return TCL_ERROR;
+    }
+    SetFlag(statePtr, CHANNEL_INCLOSE);
+
+    /*
+     * When the channel has an escape sequence driven encoding such as
+     * iso2022, the terminated escape sequence must write to the buffer.
+     */
+
+    stickyError = 0;
+
+    if (GotFlag(statePtr, TCL_WRITABLE) && (statePtr->encoding != NULL)
+	    && !(statePtr->outputEncodingFlags & TCL_ENCODING_START)) {
+
+	int code = CheckChannelErrors(statePtr, TCL_WRITABLE);
+
+	if (code == 0) {
+	    statePtr->outputEncodingFlags |= TCL_ENCODING_END;
+	    code = WriteChars(chanPtr, "", 0);
+	    statePtr->outputEncodingFlags &= ~TCL_ENCODING_END;
+	    statePtr->outputEncodingFlags |= TCL_ENCODING_START;
+	}
+	if (code < 0) {
+	    stickyError = Tcl_GetErrno();
+	}
+
+	/*
+	 * TIP #219, Tcl Channel Reflection API.
+	 * Move an error message found in the channel bypass into the
+	 * interpreter bypass. Just clear it if there is no interpreter.
+	 */
+
+	if (statePtr->chanMsg != NULL) {
+	    if (interp != NULL) {
+		Tcl_SetChannelErrorInterp(interp, statePtr->chanMsg);
+	    }
+	    TclDecrRefCount(statePtr->chanMsg);
+	    statePtr->chanMsg = NULL;
+	}
+    }
+
+    Tcl_ClearChannelHandlers(chan);
+
+    /*
+     * Invoke the registered close callbacks and delete their records.
+     */
+
+    while (statePtr->closeCbPtr != NULL) {
+	cbPtr = statePtr->closeCbPtr;
+	statePtr->closeCbPtr = cbPtr->nextPtr;
+	cbPtr->proc(cbPtr->clientData);
+	ckfree(cbPtr);
+    }
+
+    ResetFlag(statePtr, CHANNEL_INCLOSE);
+
+    /*
+     * If this channel supports it, close the read side, since we don't need
+     * it anymore and this will help avoid deadlocks on some channel types.
+     */
+
+    if (chanPtr->typePtr->closeProc == TCL_CLOSE2PROC) {
+	result = chanPtr->typePtr->close2Proc(chanPtr->instanceData, interp,
+		TCL_CLOSE_READ);
+    } else {
+	result = 0;
+    }
+
+    /*
+     * The call to FlushChannel will flush any queued output and invoke the
+     * close function of the channel driver, or it will set up the channel to
+     * be flushed and closed asynchronously.
+     */
+
+    SetFlag(statePtr, CHANNEL_CLOSED);
+
+    flushcode = FlushChannel(interp, chanPtr, 0);
+
+    /*
+     * TIP #219.
+     * Capture error messages put by the driver into the bypass area and put
+     * them into the regular interpreter result.
+     *
+     * Notes: Due to the assertion of CHANNEL_CLOSED in the flags
+     * FlushChannel() has called CloseChannel() and thus freed all the channel
+     * structures. We must not try to access "chan" anymore, hence the NULL
+     * argument in the call below. The only place which may still contain a
+     * message is the interpreter itself, and "CloseChannel" made sure to lift
+     * any channel message it generated into it.
+     */
+
+    if (TclChanCaughtErrorBypass(interp, NULL)) {
+	result = EINVAL;
+    }
+
+    if (stickyError != 0) {
+	Tcl_SetErrno(stickyError);
+	if (interp != NULL) {
+	    Tcl_SetObjResult(interp,
+			     Tcl_NewStringObj(Tcl_PosixError(interp), -1));
+	}
+	return TCL_ERROR;
+    }
+    /*
+     * Bug 97069ea11a: set error message if a flush code is set and no error
+     * message set up to now.
+     */
+    if (flushcode != 0 && interp != NULL
+	    && 0 == Tcl_GetCharLength(Tcl_GetObjResult(interp)) ) {
+	Tcl_SetErrno(flushcode);
+	Tcl_SetObjResult(interp,
+		Tcl_NewStringObj(Tcl_PosixError(interp), -1));
+    }
+    if ((flushcode != 0) || (result != 0)) {
+	return TCL_ERROR;
+    }
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_CloseEx --
+ *
+ *	Closes one side of a channel, read or write.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	Closes one direction of the channel.
+ *
+ * NOTE:
+ *	Tcl_CloseEx closes the specified direction of the channel as far as
+ *	the user is concerned. The channel keeps existing however. You cannot
+ *	calls this function to close the last possible direction of the
+ *	channel. Use Tcl_Close for that.
+ *
+ *----------------------------------------------------------------------
+ */
+
+	/* ARGSUSED */
+int
+Tcl_CloseEx(
+    Tcl_Interp *interp,		/* Interpreter for errors. */
+    Tcl_Channel chan,		/* The channel being closed. May still be used
+				 * by some interpreter. */
+    int flags)			/* Flags telling us which side to close. */
+{
+    Channel *chanPtr;		/* The real IO channel. */
+    ChannelState *statePtr;	/* State of real IO channel. */
+
+    if (chan == NULL) {
+	return TCL_OK;
+    }
+
+    /* TODO: assert flags validity ? */
+
+    chanPtr = (Channel *) chan;
+    statePtr = chanPtr->state;
+
+    /*
+     * Does the channel support half-close anyway? Error if not.
+     */
+
+    if (!chanPtr->typePtr->close2Proc) {
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+                "half-close of channels not supported by %ss",
+		chanPtr->typePtr->typeName));
+	return TCL_ERROR;
+    }
+
+    /*
+     * Is the channel unstacked ? If not we fail.
+     */
+
+    if (chanPtr != statePtr->topChanPtr) {
+	Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		"half-close not applicable to stack of transformations", -1));
+	return TCL_ERROR;
+    }
+
+    /*
+     * Check direction against channel mode. It is an error if we try to close
+     * a direction not supported by the channel (already closed, or never
+     * opened for that direction).
+     */
+
+    if (!(statePtr->flags & (TCL_READABLE | TCL_WRITABLE) & flags)) {
+	const char *msg;
+
+	if (flags & TCL_CLOSE_READ) {
+	    msg = "read";
+	} else {
+	    msg = "write";
+	}
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+                "Half-close of %s-side not possible, side not opened or"
+                " already closed", msg));
+	return TCL_ERROR;
+    }
+
+    /*
+     * A user may try to call half-close from within a channel close
+     * handler. That won't do.
+     */
+
+    if (statePtr->flags & CHANNEL_INCLOSE) {
+	if (interp) {
+	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
+                    "illegal recursive call to close through close-handler"
+                    " of channel", -1));
+	}
+	return TCL_ERROR;
+    }
+
+    if (flags & TCL_CLOSE_READ) {
+	/*
+	 * Call the finalization code directly. There are no events to handle,
+	 * there cannot be for the read-side.
+	 */
+
+	return CloseChannelPart(interp, chanPtr, 0, flags);
+    } else if (flags & TCL_CLOSE_WRITE) {
+	Tcl_Preserve(statePtr);
+	if (!GotFlag(statePtr, BG_FLUSH_SCHEDULED)) {
+	    /*
+	     * We don't want to re-enter CloseWrite().
+	     */
+
+	    if (!GotFlag(statePtr, CHANNEL_CLOSEDWRITE)) {
+		if (CloseWrite(interp, chanPtr) != TCL_OK) {
+		    SetFlag(statePtr, CHANNEL_CLOSEDWRITE);
+		    Tcl_Release(statePtr);
+		    return TCL_ERROR;
+		}
+	    }
+	}
+	SetFlag(statePtr, CHANNEL_CLOSEDWRITE);
+	Tcl_Release(statePtr);
+    }
+
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * CloseWrite --
+ *
+ *	Closes the write side a channel.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	Closes the write side of the channel.
+ *
+ * NOTE:
+ *	CloseWrite removes the channel as far as the user is concerned.
+ *	However, the ooutput data structures may continue to exist for a while
+ *	longer if it has a background flush scheduled. The device itself is
+ *	eventually closed and the channel structures modified, in
+ *	CloseChannelPart, below.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+CloseWrite(
+    Tcl_Interp *interp,		/* Interpreter for errors. */
+    Channel *chanPtr)		/* The channel whose write side is being
+                                 * closed. May still be used by some
+                                 * interpreter */
+{
+    /* Notes: clear-channel-handlers - write side only ? or keep around, just
+     * not called. */
+    /* No close cllbacks are run - channel is still open (read side) */
+
+    ChannelState *statePtr = chanPtr->state;
+                                /* State of real IO channel. */
+    int flushcode;
+    int result = 0;
+
+    /*
+     * The call to FlushChannel will flush any queued output and invoke the
+     * close function of the channel driver, or it will set up the channel to
+     * be flushed and closed asynchronously.
+     */
+
+    SetFlag(statePtr, CHANNEL_CLOSEDWRITE);
+
+    flushcode = FlushChannel(interp, chanPtr, 0);
+
+    /*
+     * TIP #219.
+     * Capture error messages put by the driver into the bypass area and put
+     * them into the regular interpreter result.
+     *
+     * Notes: Due to the assertion of CHANNEL_CLOSEDWRITE in the flags
+     * FlushChannel() has called CloseChannelPart(). While we can still access
+     * "chan" (no structures were freed), the only place which may still
+     * contain a message is the interpreter itself, and "CloseChannelPart" made
+     * sure to lift any channel message it generated into it. Hence the NULL
+     * argument in the call below.
+     */
+
+    if (TclChanCaughtErrorBypass(interp, NULL)) {
+	result = EINVAL;
+    }
+
+    if ((flushcode != 0) || (result != 0)) {
+	return TCL_ERROR;
+    }
+
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * CloseChannelPart --
+ *
+ *	Utility procedure to close a channel partially and free associated
+ *	resources. If the channel was stacked it will never be run (The higher
+ *	level forbid this). If the channel was not stacked, then we will free
+ *	all the bits of the chosen side (read, or write) for the TOP channel.
+ *
+ * Results:
+ *	Error code from an unreported error or the driver close2 operation.
+ *
+ * Side effects:
+ *	May free memory, may change the value of errno.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+CloseChannelPart(
+    Tcl_Interp *interp,		/* Interpreter for errors. */
+    Channel *chanPtr,		/* The channel being closed. May still be used
+				 * by some interpreter. */
+    int errorCode,		/* Status of operation so far. */
+    int flags)			/* Flags telling us which side to close. */
+{
+    ChannelState *statePtr;	/* State of real IO channel. */
+    int result;			/* Of calling the close2proc. */
+
+    statePtr = chanPtr->state;
+
+    if (flags & TCL_CLOSE_READ) {
+	/*
+	 * No more input can be consumed so discard any leftover input.
+	 */
+
+	DiscardInputQueued(statePtr, 1);
+    } else if (flags & TCL_CLOSE_WRITE) {
+	/*
+	 * The caller guarantees that there are no more buffers queued for
+	 * output.
+	 */
+
+	if (statePtr->outQueueHead != NULL) {
+	    Tcl_Panic("ClosechanHalf, closed write-side of channel: "
+		    "queued output left");
+	}
+
+	/*
+	 * If the EOF character is set in the channel, append that to the
+	 * output device.
+	 */
+
+	if ((statePtr->outEofChar != 0) && GotFlag(statePtr, TCL_WRITABLE)) {
+	    int dummy;
+	    char c = (char) statePtr->outEofChar;
+
+	    (void) ChanWrite(chanPtr, &c, 1, &dummy);
+	}
+
+	/*
+	 * TIP #219, Tcl Channel Reflection API.
+	 * Move a leftover error message in the channel bypass into the
+	 * interpreter bypass. Just clear it if there is no interpreter.
+	 */
+
+	if (statePtr->chanMsg != NULL) {
+	    if (interp != NULL) {
+		Tcl_SetChannelErrorInterp(interp, statePtr->chanMsg);
+	    }
+	    TclDecrRefCount(statePtr->chanMsg);
+	    statePtr->chanMsg = NULL;
+	}
+    }
+
+    /*
+     * Finally do what is asked of us. Close and free the channel driver state
+     * for the chosen side of the channel. This may leave a TIP #219 error
+     * message in the interp.
+     */
+
+    result = ChanCloseHalf(chanPtr, interp, flags);
+
+    /*
+     * If we are being called synchronously, report either any latent error on
+     * the channel or the current error.
+     */
+
+    if (statePtr->unreportedError != 0) {
+	errorCode = statePtr->unreportedError;
+
+	/*
+	 * TIP #219, Tcl Channel Reflection API.
+	 * Move an error message found in the unreported area into the regular
+	 * bypass (interp). This kills any message in the channel bypass area.
+	 */
+
+	if (statePtr->chanMsg != NULL) {
+	    TclDecrRefCount(statePtr->chanMsg);
+	    statePtr->chanMsg = NULL;
+	}
+	if (interp) {
+	    Tcl_SetChannelErrorInterp(interp, statePtr->unreportedMsg);
+	}
+    }
+    if (errorCode == 0) {
+	errorCode = result;
+	if (errorCode != 0) {
+	    Tcl_SetErrno(errorCode);
+	}
+    }
+
+    /*
+     * TIP #219.
+     * Capture error messages put by the driver into the bypass area and put
+     * them into the regular interpreter result. See also the bottom of
+     * CloseWrite().
+     */
+
+    if (TclChanCaughtErrorBypass(interp, (Tcl_Channel) chanPtr)) {
+	result = EINVAL;
+    }
+
+    if (result != 0) {
+	return TCL_ERROR;
+    }
+
+    /*
+     * Remove the closed side from the channel mode/flags.
+     */
+
+    ResetFlag(statePtr, flags & (TCL_READABLE | TCL_WRITABLE));
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_ClearChannelHandlers --
+ *
+ *	Removes all channel handlers and event scripts from the channel,
+ *	cancels all background copies involving the channel and any interest
+ *	in events.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	See above. Deallocates memory.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_ClearChannelHandlers(
+    Tcl_Channel channel)
+{
+    ChannelHandler *chPtr, *chNext;	/* Iterate over channel handlers. */
+    EventScriptRecord *ePtr, *eNextPtr;	/* Iterate over eventscript records. */
+    Channel *chanPtr;			/* The real IO channel. */
+    ChannelState *statePtr;		/* State of real IO channel. */
+    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+    NextChannelHandler *nhPtr;
+
+    /*
+     * This operation should occur at the top of a channel stack.
+     */
+
+    chanPtr = (Channel *) channel;
+    statePtr = chanPtr->state;
+    chanPtr = statePtr->topChanPtr;
+
+    /*
+     * Cancel any outstanding timer.
+     */
+
+    Tcl_DeleteTimerHandler(statePtr->timer);
+
+    /*
+     * Remove any references to channel handlers for this channel that may be
+     * about to be invoked.
+     */
+
+    for (nhPtr = tsdPtr->nestedHandlerPtr; nhPtr != NULL;
+	    nhPtr = nhPtr->nestedHandlerPtr) {
+	if (nhPtr->nextHandlerPtr &&
+		(nhPtr->nextHandlerPtr->chanPtr == chanPtr)) {
+	    nhPtr->nextHandlerPtr = NULL;
+	}
+    }
+
+    /*
+     * Remove all the channel handler records attached to the channel itself.
+     */
+
+    for (chPtr = statePtr->chPtr; chPtr != NULL; chPtr = chNext) {
+	chNext = chPtr->nextPtr;
+	ckfree(chPtr);
+    }
+    statePtr->chPtr = NULL;
+
+    /*
+     * Cancel any pending copy operation.
+     */
+
+    StopCopy(statePtr->csPtrR);
+    StopCopy(statePtr->csPtrW);
+
+    /*
+     * Must set the interest mask now to 0, otherwise infinite loops
+     * will occur if Tcl_DoOneEvent is called before the channel is
+     * finally deleted in FlushChannel. This can happen if the channel
+     * has a background flush active.
+     */
+
+    statePtr->interestMask = 0;
+
+    /*
+     * Remove any EventScript records for this channel.
+     */
+
+    for (ePtr = statePtr->scriptRecordPtr; ePtr != NULL; ePtr = eNextPtr) {
+	eNextPtr = ePtr->nextPtr;
+	TclDecrRefCount(ePtr->scriptPtr);
+	ckfree(ePtr);
+    }
+    statePtr->scriptRecordPtr = NULL;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_Write --
+ *
+ *	Puts a sequence of bytes into an output buffer, may queue the buffer
+ *	for output if it gets full, and also remembers whether the current
+ *	buffer is ready e.g. if it contains a newline and we are in line
+ *	buffering mode. Compensates stacking, i.e. will redirect the data from
+ *	the specified channel to the topmost channel in a stack.
+ *
+ *	No encoding conversions are applied to the bytes being read.
+ *
+ * Results:
+ *	The number of bytes written or -1 in case of error. If -1,
+ *	Tcl_GetErrno will return the error code.
+ *
+ * Side effects:
+ *	May buffer up output and may cause output to be produced on the
+ *	channel.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_Write(
+    Tcl_Channel chan,		/* The channel to buffer output for. */
+    const char *src,		/* Data to queue in output buffer. */
+    int srcLen)			/* Length of data in bytes, or < 0 for
+				 * strlen(). */
+{
+    /*
+     * Always use the topmost channel of the stack
+     */
+
+    Channel *chanPtr;
+    ChannelState *statePtr;	/* State info for channel */
+
+    statePtr = ((Channel *) chan)->state;
+    chanPtr = statePtr->topChanPtr;
+
+    if (CheckChannelErrors(statePtr, TCL_WRITABLE) != 0) {
+	return -1;
+    }
+
+    if (srcLen < 0) {
+	srcLen = strlen(src);
+    }
+    if (WriteBytes(chanPtr, src, srcLen) < 0) {
+	return -1;
+    }
+    return srcLen;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_WriteRaw --
+ *
+ *	Puts a sequence of bytes into an output buffer, may queue the buffer
+ *	for output if it gets full, and also remembers whether the current
+ *	buffer is ready e.g. if it contains a newline and we are in line
+ *	buffering mode. Writes directly to the driver of the channel, does not
+ *	compensate for stacking.
+ *
+ *	No encoding conversions are applied to the bytes being read.
+ *
+ * Results:
+ *	The number of bytes written or -1 in case of error. If -1,
+ *	Tcl_GetErrno will return the error code.
+ *
+ * Side effects:
+ *	May buffer up output and may cause output to be produced on the
+ *	channel.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_WriteRaw(
+    Tcl_Channel chan,		/* The channel to buffer output for. */
+    const char *src,		/* Data to queue in output buffer. */
+    int srcLen)			/* Length of data in bytes, or < 0 for
+				 * strlen(). */
+{
+    Channel *chanPtr = ((Channel *) chan);
+    ChannelState *statePtr = chanPtr->state;
+				/* State info for channel */
+    int errorCode, written;
+
+    if (CheckChannelErrors(statePtr, TCL_WRITABLE | CHANNEL_RAW_MODE) != 0) {
+	return -1;
+    }
+
+    if (srcLen < 0) {
+	srcLen = strlen(src);
+    }
+
+    /*
+     * Go immediately to the driver, do all the error handling by ourselves.
+     * The code was stolen from 'FlushChannel'.
+     */
+
+    written = ChanWrite(chanPtr, src, srcLen, &errorCode);
+    if (written < 0) {
+	Tcl_SetErrno(errorCode);
+    }
+
+    return written;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Tcl_WriteChars --
+ *
+ *	Takes a sequence of UTF-8 characters and converts them for output
+ *	using the channel's current encoding, may queue the buffer for output
+ *	if it gets full, and also remembers whether the current buffer is
+ *	ready e.g. if it contains a newline and we are in line buffering
+ *	mode. Compensates stacking, i.e. will redirect the data from the
+ *	specified channel to the topmost channel in a stack.
+ *
+ * Results:
+ *	The number of bytes written or -1 in case of error. If -1,
+ *	Tcl_GetErrno will return the error code.
+ *
+ * Side effects:
+ *	May buffer up output and may cause output to be produced on the
+ *	channel.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_WriteChars(
+    Tcl_Channel chan,		/* The channel to buffer output for. */
+    const char *src,		/* UTF-8 characters to queue in output
+				 * buffer. */
+    int len)			/* Length of string in bytes, or < 0 for
+				 * strlen(). */
+{
+    Channel *chanPtr = (Channel *) chan;
+    ChannelState *statePtr = chanPtr->state;	/* State info for channel */
+    int result;
+    Tcl_Obj *objPtr;
+
+    if (CheckChannelErrors(statePtr, TCL_WRITABLE) != 0) {
+	return -1;
+    }
+
+    chanPtr = statePtr->topChanPtr;
+
+    if (len < 0) {
+	len = strlen(src);
+    }
+    if (statePtr->encoding) {
+	return WriteChars(chanPtr, src, len);
+    }
+
+    /*
+     * Inefficient way to convert UTF-8 to byte-array, but the code
+     * parallels the way it is done for objects.  Special case for 1-byte
+     * (used by eg [puts] for the \n) could be extended to more efficient
+     * translation of the src string.
+     */
+
+    if ((len == 1) && (UCHAR(*src) < 0xC0)) {
+	return WriteBytes(chanPtr, src, len);
+    }
+
+    objPtr = Tcl_NewStringObj(src, len);
+    src = (char *) Tcl_GetByteArrayFromObj(objPtr, &len);
+    result = WriteBytes(chanPtr, src, len);
+    TclDecrRefCount(objPtr);
+    return result;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Tcl_WriteObj --
+ *
+ *	Takes the Tcl object and queues its contents for output. If the
+ *	encoding of the channel is NULL, takes the byte-array representation
+ *	of the object and queues those bytes for output. Otherwise, takes the
+ *	characters in the UTF-8 (string) representation of the object and
+ *	converts them for output using the channel's current encoding. May
+ *	flush internal buffers to output if one becomes full or is ready for
+ *	some other reason, e.g. if it contains a newline and the channel is in
+ *	line buffering mode.
+ *
+ * Results:
+ *	The number of bytes written or -1 in case of error. If -1,
+ *	Tcl_GetErrno() will return the error code.
+ *
+ * Side effects:
+ *	May buffer up output and may cause output to be produced on the
+ *	channel.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_WriteObj(
+    Tcl_Channel chan,		/* The channel to buffer output for. */
+    Tcl_Obj *objPtr)		/* The object to write. */
+{
+    /*
+     * Always use the topmost channel of the stack
+     */
+
+    Channel *chanPtr;
+    ChannelState *statePtr;	/* State info for channel */
+    const char *src;
+    int srcLen;
+
+    statePtr = ((Channel *) chan)->state;
+    chanPtr = statePtr->topChanPtr;
+
+    if (CheckChannelErrors(statePtr, TCL_WRITABLE) != 0) {
+	return -1;
+    }
+    if (statePtr->encoding == NULL) {
+	src = (char *) Tcl_GetByteArrayFromObj(objPtr, &srcLen);
+	return WriteBytes(chanPtr, src, srcLen);
+    } else {
+	src = TclGetStringFromObj(objPtr, &srcLen);
+	return WriteChars(chanPtr, src, srcLen);
+    }
+}
+
+static void
+WillWrite(
+    Channel *chanPtr)
+{
+    int inputBuffered;
+
+    if ((chanPtr->typePtr->seekProc != NULL) &&
+            ((inputBuffered = Tcl_InputBuffered((Tcl_Channel) chanPtr)) > 0)){
+        int ignore;
+
+        DiscardInputQueued(chanPtr->state, 0);
+        ChanSeek(chanPtr, -inputBuffered, SEEK_CUR, &ignore);
+    }
+}
+
+static int
+WillRead(
+    Channel *chanPtr)
+{
+    if (chanPtr->typePtr == NULL) {
+	/* Prevent read attempts on a closed channel */
+        DiscardInputQueued(chanPtr->state, 0);
+	Tcl_SetErrno(EINVAL);
+	return -1;
+    }
+    if ((chanPtr->typePtr->seekProc != NULL)
+            && (Tcl_OutputBuffered((Tcl_Channel) chanPtr) > 0)) {
+
+	/*
+	 * CAVEAT - The assumption here is that FlushChannel() will
+	 * push out the bytes of any writes that are in progress.
+	 * Since this is a seekable channel, we assume it is not one
+	 * that can block and force bg flushing.  Channels we know that
+	 * can do that -- sockets, pipes -- are not seekable.  If the
+	 * assumption is wrong, more drastic measures may be required here
+	 * like temporarily setting the channel into blocking mode.
+	 */
+
+        if (FlushChannel(NULL, chanPtr, 0) != 0) {
+            return -1;
+        }
+    }
+    return 0;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Write --
+ *
+ *	Convert srcLen bytes starting at src according to encoding and write
+ *	produced bytes into an output buffer, may queue the buffer for output
+ *	if it gets full, and also remembers whether the current buffer is
+ *	ready e.g. if it contains a newline and we are in line buffering mode.
+ *
+ * Results:
+ *	The number of bytes written or -1 in case of error. If -1,
+ *	Tcl_GetErrno will return the error code.
+ *
+ * Side effects:
+ *	May buffer up output and may cause output to be produced on the
+ *	channel.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+Write(
+    Channel *chanPtr,		/* The channel to buffer output for. */
+    const char *src,		/* UTF-8 string to write. */
+    int srcLen,			/* Length of UTF-8 string in bytes. */
+    Tcl_Encoding encoding)
+{
+    ChannelState *statePtr = chanPtr->state;
+				/* State info for channel */
+    char *nextNewLine = NULL;
+    int endEncoding, saved = 0, total = 0, flushed = 0, needNlFlush = 0;
+
+    if (srcLen) {
+        WillWrite(chanPtr);
+    }
+
+    /*
+     * Write the terminated escape sequence even if srcLen is 0.
+     */
+
+    endEncoding = ((statePtr->outputEncodingFlags & TCL_ENCODING_END) != 0);
+
+    if (GotFlag(statePtr, CHANNEL_LINEBUFFERED)
+	    || (statePtr->outputTranslation != TCL_TRANSLATE_LF)) {
+	nextNewLine = memchr(src, '\n', srcLen);
+    }
+
+    while (srcLen + saved + endEncoding > 0) {
+	ChannelBuffer *bufPtr;
+	char *dst, safe[BUFFER_PADDING];
+	int result, srcRead, dstLen, dstWrote, srcLimit = srcLen;
+
+	if (nextNewLine) {
+	    srcLimit = nextNewLine - src;
+	}
+
+	/* Get space to write into */
+	bufPtr = statePtr->curOutPtr;
+	if (bufPtr == NULL) {
+	    bufPtr = AllocChannelBuffer(statePtr->bufSize);
+	    statePtr->curOutPtr = bufPtr;
+	}
+	if (saved) {
+	    /*
+	     * Here's some translated bytes left over from the last buffer
+	     * that we need to stick at the beginning of this buffer.
+	     */
+
+	    memcpy(InsertPoint(bufPtr), safe, (size_t) saved);
+	    bufPtr->nextAdded += saved;
+	    saved = 0;
+	}
+	PreserveChannelBuffer(bufPtr);
+	dst = InsertPoint(bufPtr);
+	dstLen = SpaceLeft(bufPtr);
+
+	result = Tcl_UtfToExternal(NULL, encoding, src, srcLimit,
+		statePtr->outputEncodingFlags,
+		&statePtr->outputEncodingState, dst,
+		dstLen + BUFFER_PADDING, &srcRead, &dstWrote, NULL);
+
+	/* See chan-io-1.[89]. Tcl Bug 506297. */
+	statePtr->outputEncodingFlags &= ~TCL_ENCODING_START;
+
+	if ((result != TCL_OK) && (srcRead + dstWrote == 0)) {
+	    /* We're reading from invalid/incomplete UTF-8 */
+	    ReleaseChannelBuffer(bufPtr);
+	    if (total == 0) {
+		Tcl_SetErrno(EINVAL);
+		return -1;
+	    }
+	    break;
+	}
+
+	bufPtr->nextAdded += dstWrote;
+	src += srcRead;
+	srcLen -= srcRead;
+	total += dstWrote;
+	dst += dstWrote;
+	dstLen -= dstWrote;
+
+	if (src == nextNewLine && dstLen > 0) {
+	    static char crln[3] = "\r\n";
+	    char *nl = NULL;
+	    int nlLen = 0;
+
+	    switch (statePtr->outputTranslation) {
+	    case TCL_TRANSLATE_LF:
+		nl = crln + 1;
+		nlLen = 1;
+		break;
+	    case TCL_TRANSLATE_CR:
+		nl = crln;
+		nlLen = 1;
+		break;
+	    case TCL_TRANSLATE_CRLF:
+		nl = crln;
+		nlLen = 2;
+		break;
+	    default:
+		Tcl_Panic("unknown output translation requested");
+		break;
+	    }
+
+	    result |= Tcl_UtfToExternal(NULL, encoding, nl, nlLen,
+		statePtr->outputEncodingFlags,
+		&statePtr->outputEncodingState, dst,
+		dstLen + BUFFER_PADDING, &srcRead, &dstWrote, NULL);
+
+	    assert (srcRead == nlLen);
+
+	    bufPtr->nextAdded += dstWrote;
+	    src++;
+	    srcLen--;
+	    total += dstWrote;
+	    dst += dstWrote;
+	    dstLen -= dstWrote;
+	    nextNewLine = memchr(src, '\n', srcLen);
+	    needNlFlush = 1;
+	}
+
+	if (IsBufferOverflowing(bufPtr)) {
+	    /*
+	     * When translating from UTF-8 to external encoding, we
+	     * allowed the translation to produce a character that crossed
+	     * the end of the output buffer, so that we would get a
+	     * completely full buffer before flushing it. The extra bytes
+	     * will be moved to the beginning of the next buffer.
+	     */
+
+	    saved = -SpaceLeft(bufPtr);
+	    memcpy(safe, dst + dstLen, (size_t) saved);
+	    bufPtr->nextAdded = bufPtr->bufLength;
+	}
+
+	if ((srcLen + saved == 0) && (result == TCL_OK)) {
+	    endEncoding = 0;
+	}
+
+	if (IsBufferFull(bufPtr)) {
+	    if (FlushChannel(NULL, chanPtr, 0) != 0) {
+		ReleaseChannelBuffer(bufPtr);
+		return -1;
+	    }
+	    flushed += statePtr->bufSize;
+
+	    /*
+ 	     * We just flushed.  So if we have needNlFlush set to record
+ 	     * that we need to flush because theres a (translated) newline
+ 	     * in the buffer, that's likely not true any more.  But there
+ 	     * is a tricky exception.  If we have saved bytes that did not
+ 	     * really get flushed and those bytes came from a translation
+ 	     * of a newline as the last thing taken from the src array,
+ 	     * then needNlFlush needs to remain set to flag that the
+ 	     * next buffer still needs a newline flush.
+ 	     */
+	    if (needNlFlush && (saved == 0 || src[-1] != '\n')) {
+		needNlFlush = 0;
+	    }
+	}
+	ReleaseChannelBuffer(bufPtr);
+    }
+    if ((flushed < total) && (GotFlag(statePtr, CHANNEL_UNBUFFERED) ||
+	    (needNlFlush && GotFlag(statePtr, CHANNEL_LINEBUFFERED)))) {
+	if (FlushChannel(NULL, chanPtr, 0) != 0) {
+	    return -1;
+	}
+    }
+
+    return total;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Tcl_Gets --
+ *
+ *	Reads a complete line of input from the channel into a Tcl_DString.
+ *
+ * Results:
+ *	Length of line read (in characters) or -1 if error, EOF, or blocked.
+ *	If -1, use Tcl_GetErrno() to retrieve the POSIX error code for the
+ *	error or condition that occurred.
+ *
+ * Side effects:
+ *	May flush output on the channel. May cause input to be consumed from
+ *	the channel.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+int
+Tcl_Gets(
+    Tcl_Channel chan,		/* Channel from which to read. */
+    Tcl_DString *lineRead)	/* The line read will be appended to this
+				 * DString as UTF-8 characters. The caller
+				 * must have initialized it and is responsible
+				 * for managing the storage. */
+{
+    Tcl_Obj *objPtr;
+    int charsStored;
+
+    TclNewObj(objPtr);
+    charsStored = Tcl_GetsObj(chan, objPtr);
+    if (charsStored > 0) {
+	TclDStringAppendObj(lineRead, objPtr);
+    }
+    TclDecrRefCount(objPtr);
+    return charsStored;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Tcl_GetsObj --
+ *
+ *	Accumulate input from the input channel until end-of-line or
+ *	end-of-file has been seen. Bytes read from the input channel are
+ *	converted to UTF-8 using the encoding specified by the channel.
+ *
+ * Results:
+ *	Number of characters accumulated in the object or -1 if error,
+ *	blocked, or EOF. If -1, use Tcl_GetErrno() to retrieve the POSIX error
+ *	code for the error or condition that occurred.
+ *
+ * Side effects:
+ *	Consumes input from the channel.
+ *
+ *	On reading EOF, leave channel pointing at EOF char. On reading EOL,
+ *	leave channel pointing after EOL, but don't return EOL in dst buffer.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+int
+Tcl_GetsObj(
+    Tcl_Channel chan,		/* Channel from which to read. */
+    Tcl_Obj *objPtr)		/* The line read will be appended to this
+				 * object as UTF-8 characters. */
+{
+    GetsState gs;
+    Channel *chanPtr = (Channel *) chan;
+    ChannelState *statePtr = chanPtr->state;
+				/* State info for channel */
+    ChannelBuffer *bufPtr;
+    int inEofChar, skip, copiedTotal, oldLength, oldFlags, oldRemoved;
+    Tcl_Encoding encoding;
+    char *dst, *dstEnd, *eol, *eof;
+    Tcl_EncodingState oldState;
+
+    if (CheckChannelErrors(statePtr, TCL_READABLE) != 0) {
+	return -1;
+    }
+
+    /*
+     * If we're sitting ready to read the eofchar, there's no need to
+     * do it.
+     */
+
+    if (GotFlag(statePtr, CHANNEL_STICKY_EOF)) {
+	SetFlag(statePtr, CHANNEL_EOF);
+	assert( statePtr->inputEncodingFlags & TCL_ENCODING_END );
+	assert( !GotFlag(statePtr, CHANNEL_BLOCKED|INPUT_SAW_CR) );
+
+	/* TODO: Do we need this? */
+	UpdateInterest(chanPtr);
+	return -1;
+    }
+
+    /*
+     * A binary version of Tcl_GetsObj. This could also handle encodings that
+     * are ascii-7 pure (iso8859, utf-8, ...) with a final encoding conversion
+     * done on objPtr.
+     */
+
+    if ((statePtr->encoding == NULL)
+	    && ((statePtr->inputTranslation == TCL_TRANSLATE_LF)
+		    || (statePtr->inputTranslation == TCL_TRANSLATE_CR))) {
+	return TclGetsObjBinary(chan, objPtr);
+    }
+
+    /*
+     * This operation should occur at the top of a channel stack.
+     */
+
+    chanPtr = statePtr->topChanPtr;
+    TclChannelPreserve((Tcl_Channel)chanPtr);
+
+    bufPtr = statePtr->inQueueHead;
+    encoding = statePtr->encoding;
+
+    /*
+     * Preserved so we can restore the channel's state in case we don't find a
+     * newline in the available input.
+     */
+
+    TclGetStringFromObj(objPtr, &oldLength);
+    oldFlags = statePtr->inputEncodingFlags;
+    oldState = statePtr->inputEncodingState;
+    oldRemoved = BUFFER_PADDING;
+    if (bufPtr != NULL) {
+	oldRemoved = bufPtr->nextRemoved;
+    }
+
+    /*
+     * If there is no encoding, use "iso8859-1" -- Tcl_GetsObj() doesn't
+     * produce ByteArray objects.
+     */
+
+    if (encoding == NULL) {
+	encoding = GetBinaryEncoding();
+    }
+
+    /*
+     * Object used by FilterInputBytes to keep track of how much data has been
+     * consumed from the channel buffers.
+     */
+
+    gs.objPtr		= objPtr;
+    gs.dstPtr		= &dst;
+    gs.encoding		= encoding;
+    gs.bufPtr		= bufPtr;
+    gs.state		= oldState;
+    gs.rawRead		= 0;
+    gs.bytesWrote	= 0;
+    gs.charsWrote	= 0;
+    gs.totalChars	= 0;
+
+    dst = objPtr->bytes + oldLength;
+    dstEnd = dst;
+
+    skip = 0;
+    eof = NULL;
+    inEofChar = statePtr->inEofChar;
+
+    ResetFlag(statePtr, CHANNEL_BLOCKED);
+    while (1) {
+	if (dst >= dstEnd) {
+	    if (FilterInputBytes(chanPtr, &gs) != 0) {
+		goto restore;
+	    }
+	    dstEnd = dst + gs.bytesWrote;
+	}
+
+	/*
+	 * Remember if EOF char is seen, then look for EOL anyhow, because the
+	 * EOL might be before the EOF char.
+	 */
+
+	if (inEofChar != '\0') {
+	    for (eol = dst; eol < dstEnd; eol++) {
+		if (*eol == inEofChar) {
+		    dstEnd = eol;
+		    eof = eol;
+		    break;
+		}
+	    }
+	}
+
+	/*
+	 * On EOL, leave current file position pointing after the EOL, but
+	 * don't store the EOL in the output string.
+	 */
+
+	switch (statePtr->inputTranslation) {
+	case TCL_TRANSLATE_LF:
+	    for (eol = dst; eol < dstEnd; eol++) {
+		if (*eol == '\n') {
+		    skip = 1;
+		    goto gotEOL;
+		}
+	    }
+	    break;
+	case TCL_TRANSLATE_CR:
+	    for (eol = dst; eol < dstEnd; eol++) {
+		if (*eol == '\r') {
+		    skip = 1;
+		    goto gotEOL;
+		}
+	    }
+	    break;
+	case TCL_TRANSLATE_CRLF:
+	    for (eol = dst; eol < dstEnd; eol++) {
+		if (*eol == '\r') {
+		    eol++;
+
+		    /*
+		     * If a CR is at the end of the buffer, then check for a
+		     * LF at the begining of the next buffer, unless EOF char
+		     * was found already.
+		     */
+
+		    if (eol >= dstEnd) {
+			int offset;
+
+			if (eol != eof) {
+			    offset = eol - objPtr->bytes;
+			    dst = dstEnd;
+			    if (FilterInputBytes(chanPtr, &gs) != 0) {
+				goto restore;
+			    }
+			    dstEnd = dst + gs.bytesWrote;
+			    eol = objPtr->bytes + offset;
+			}
+			if (eol >= dstEnd) {
+			    skip = 0;
+			    goto gotEOL;
+			}
+		    }
+		    if (*eol == '\n') {
+			eol--;
+			skip = 2;
+			goto gotEOL;
+		    }
+		}
+	    }
+	    break;
+	case TCL_TRANSLATE_AUTO:
+	    eol = dst;
+	    skip = 1;
+	    if (GotFlag(statePtr, INPUT_SAW_CR)) {
+		ResetFlag(statePtr, INPUT_SAW_CR);
+		if ((eol < dstEnd) && (*eol == '\n')) {
+		    /*
+		     * Skip the raw bytes that make up the '\n'.
+		     */
+
+		    char tmp[TCL_UTF_MAX];
+		    int rawRead;
+
+		    bufPtr = gs.bufPtr;
+		    Tcl_ExternalToUtf(NULL, gs.encoding, RemovePoint(bufPtr),
+			    gs.rawRead, statePtr->inputEncodingFlags
+				| TCL_ENCODING_NO_TERMINATE, &gs.state, tmp,
+			    TCL_UTF_MAX, &rawRead, NULL, NULL);
+		    bufPtr->nextRemoved += rawRead;
+		    gs.rawRead -= rawRead;
+		    gs.bytesWrote--;
+		    gs.charsWrote--;
+		    memmove(dst, dst + 1, (size_t) (dstEnd - dst));
+		    dstEnd--;
+		}
+	    }
+	    for (eol = dst; eol < dstEnd; eol++) {
+		if (*eol == '\r') {
+		    eol++;
+		    if (eol == dstEnd) {
+			/*
+			 * If buffer ended on \r, peek ahead to see if a \n is
+			 * available, unless EOF char was found already.
+			 */
+
+			if (eol != eof) {
+			    int offset;
+
+			    offset = eol - objPtr->bytes;
+			    dst = dstEnd;
+			    PeekAhead(chanPtr, &dstEnd, &gs);
+			    eol = objPtr->bytes + offset;
+			}
+
+			if (eol >= dstEnd) {
+			    eol--;
+			    SetFlag(statePtr, INPUT_SAW_CR);
+			    goto gotEOL;
+			}
+		    }
+		    if (*eol == '\n') {
+			skip++;
+		    }
+		    eol--;
+		    goto gotEOL;
+		} else if (*eol == '\n') {
+		    goto gotEOL;
+		}
+	    }
+	}
+	if (eof != NULL) {
+	    /*
+	     * EOF character was seen. On EOF, leave current file position
+	     * pointing at the EOF character, but don't store the EOF
+	     * character in the output string.
+	     */
+
+	    dstEnd = eof;
+	    SetFlag(statePtr, CHANNEL_EOF | CHANNEL_STICKY_EOF);
+	    statePtr->inputEncodingFlags |= TCL_ENCODING_END;
+	    ResetFlag(statePtr, CHANNEL_BLOCKED|INPUT_SAW_CR);
+	}
+	if (GotFlag(statePtr, CHANNEL_EOF)) {
+	    skip = 0;
+	    eol = dstEnd;
+	    if (eol == objPtr->bytes + oldLength) {
+		/*
+		 * If we didn't append any bytes before encountering EOF,
+		 * caller needs to see -1.
+		 */
+
+		Tcl_SetObjLength(objPtr, oldLength);
+		CommonGetsCleanup(chanPtr);
+		copiedTotal = -1;
+		ResetFlag(statePtr, CHANNEL_BLOCKED);
+		goto done;
+	    }
+	    goto gotEOL;
+	}
+	dst = dstEnd;
+    }
+
+    /*
+     * Found EOL or EOF, but the output buffer may now contain too many UTF-8
+     * characters. We need to know how many raw bytes correspond to the number
+     * of UTF-8 characters we want, plus how many raw bytes correspond to the
+     * character(s) making up EOL (if any), so we can remove the correct
+     * number of bytes from the channel buffer.
+     */
+
+  gotEOL:
+    /*
+     * Regenerate the top channel, in case it was changed due to
+     * self-modifying reflected transforms.
+     */
+
+    if (chanPtr != statePtr->topChanPtr) {
+	TclChannelRelease((Tcl_Channel)chanPtr);
+	chanPtr = statePtr->topChanPtr;
+	TclChannelPreserve((Tcl_Channel)chanPtr);
+    }
+
+    bufPtr = gs.bufPtr;
+    if (bufPtr == NULL) {
+	Tcl_Panic("Tcl_GetsObj: gotEOL reached with bufPtr==NULL");
+    }
+    statePtr->inputEncodingState = gs.state;
+    Tcl_ExternalToUtf(NULL, gs.encoding, RemovePoint(bufPtr), gs.rawRead,
+	    statePtr->inputEncodingFlags | TCL_ENCODING_NO_TERMINATE,
+	    &statePtr->inputEncodingState, dst,
+	    eol - dst + skip + TCL_UTF_MAX - 1, &gs.rawRead, NULL,
+	    &gs.charsWrote);
+    bufPtr->nextRemoved += gs.rawRead;
+
+    /*
+     * Recycle all the emptied buffers.
+     */
+
+    Tcl_SetObjLength(objPtr, eol - objPtr->bytes);
+    CommonGetsCleanup(chanPtr);
+    ResetFlag(statePtr, CHANNEL_BLOCKED);
+    copiedTotal = gs.totalChars + gs.charsWrote - skip;
+    goto done;
+
+    /*
+     * Couldn't get a complete line. This only happens if we get a error
+     * reading from the channel or we are non-blocking and there wasn't an EOL
+     * or EOF in the data available.
+     */
+
+  restore:
+    /*
+     * Regenerate the top channel, in case it was changed due to
+     * self-modifying reflected transforms.
+     */
+    if (chanPtr != statePtr->topChanPtr) {
+	TclChannelRelease((Tcl_Channel)chanPtr);
+	chanPtr = statePtr->topChanPtr;
+	TclChannelPreserve((Tcl_Channel)chanPtr);
+    }
+    bufPtr = statePtr->inQueueHead;
+    if (bufPtr != NULL) {
+	bufPtr->nextRemoved = oldRemoved;
+	bufPtr = bufPtr->nextPtr;
+    }
+
+    for ( ; bufPtr != NULL; bufPtr = bufPtr->nextPtr) {
+	bufPtr->nextRemoved = BUFFER_PADDING;
+    }
+    CommonGetsCleanup(chanPtr);
+
+    statePtr->inputEncodingState = oldState;
+    statePtr->inputEncodingFlags = oldFlags;
+    Tcl_SetObjLength(objPtr, oldLength);
+
+    /*
+     * We didn't get a complete line so we need to indicate to UpdateInterest
+     * that the gets blocked. It will wait for more data instead of firing a
+     * timer, avoiding a busy wait. This is where we are assuming that the
+     * next operation is a gets. No more file events will be delivered on this
+     * channel until new data arrives or some operation is performed on the
+     * channel (e.g. gets, read, fconfigure) that changes the blocking state.
+     * Note that this means a file event will not be delivered even though a
+     * read would be able to consume the buffered data.
+     */
+
+    SetFlag(statePtr, CHANNEL_NEED_MORE_DATA);
+    copiedTotal = -1;
+
+    /*
+     * Update the notifier state so we don't block while there is still data
+     * in the buffers.
+     */
+
+  done:
+	assert(!GotFlag(statePtr, CHANNEL_EOF)
+		|| GotFlag(statePtr, CHANNEL_STICKY_EOF)
+		|| Tcl_InputBuffered((Tcl_Channel)chanPtr) == 0);
+
+	assert( !(GotFlag(statePtr, CHANNEL_EOF|CHANNEL_BLOCKED)
+		== (CHANNEL_EOF|CHANNEL_BLOCKED)) );
+
+    /*
+     * Regenerate the top channel, in case it was changed due to
+     * self-modifying reflected transforms.
+     */
+    if (chanPtr != statePtr->topChanPtr) {
+	TclChannelRelease((Tcl_Channel)chanPtr);
+	chanPtr = statePtr->topChanPtr;
+	TclChannelPreserve((Tcl_Channel)chanPtr);
+    }
+    UpdateInterest(chanPtr);
+    TclChannelRelease((Tcl_Channel)chanPtr);
+    return copiedTotal;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * TclGetsObjBinary --
+ *
+ *	A variation of Tcl_GetsObj that works directly on the buffers until
+ *	end-of-line or end-of-file has been seen. Bytes read from the input
+ *	channel return as a ByteArray obj.
+ *
+ *	WARNING!  The notion of "binary" used here is different from
+ *	notions of "binary" used in other places.  In particular, this
+ *	"binary" routine may be called when an -eofchar is set on the
+ * 	channel.
+ *
+ * Results:
+ *	Number of characters accumulated in the object or -1 if error,
+ *	blocked, or EOF. If -1, use Tcl_GetErrno() to retrieve the POSIX error
+ *	code for the error or condition that occurred.
+ *
+ * Side effects:
+ *	Consumes input from the channel.
+ *
+ *	On reading EOF, leave channel pointing at EOF char. On reading EOL,
+ *	leave channel pointing after EOL, but don't return EOL in dst buffer.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+static int
+TclGetsObjBinary(
+    Tcl_Channel chan,		/* Channel from which to read. */
+    Tcl_Obj *objPtr)		/* The line read will be appended to this
+				 * object as UTF-8 characters. */
+{
+    Channel *chanPtr = (Channel *) chan;
+    ChannelState *statePtr = chanPtr->state;
+				/* State info for channel */
+    ChannelBuffer *bufPtr;
+    int inEofChar, skip, copiedTotal, oldLength, oldFlags, oldRemoved;
+    int rawLen, byteLen, eolChar;
+    unsigned char *dst, *dstEnd, *eol, *eof, *byteArray;
+
+    /*
+     * This operation should occur at the top of a channel stack.
+     */
+
+    chanPtr = statePtr->topChanPtr;
+    TclChannelPreserve((Tcl_Channel)chanPtr);
+
+    bufPtr = statePtr->inQueueHead;
+
+    /*
+     * Preserved so we can restore the channel's state in case we don't find a
+     * newline in the available input.
+     */
+
+    byteArray = Tcl_GetByteArrayFromObj(objPtr, &byteLen);
+    oldFlags = statePtr->inputEncodingFlags;
+    oldRemoved = BUFFER_PADDING;
+    oldLength = byteLen;
+    if (bufPtr != NULL) {
+	oldRemoved = bufPtr->nextRemoved;
+    }
+
+    rawLen = 0;
+    skip = 0;
+    eof = NULL;
+    inEofChar = statePtr->inEofChar;
+
+    /*
+     * Only handle TCL_TRANSLATE_LF and TCL_TRANSLATE_CR.
+     */
+
+    eolChar = (statePtr->inputTranslation == TCL_TRANSLATE_LF) ? '\n' : '\r';
+
+    ResetFlag(statePtr, CHANNEL_BLOCKED);
+    while (1) {
+	/*
+	 * Subtract the number of bytes that were removed from channel
+	 * buffer during last call.
+	 */
+
+	if (bufPtr != NULL) {
+	    bufPtr->nextRemoved += rawLen;
+	    if (!IsBufferReady(bufPtr)) {
+		bufPtr = bufPtr->nextPtr;
+	    }
+	}
+
+	if ((bufPtr == NULL) || (bufPtr->nextAdded == BUFFER_PADDING)) {
+	    /*
+	     * All channel buffers were exhausted and the caller still
+	     * hasn't seen EOL. Need to read more bytes from the channel
+	     * device. Side effect is to allocate another channel buffer.
+	     */
+	    if (GetInput(chanPtr) != 0) {
+		goto restore;
+	    }
+	    bufPtr = statePtr->inQueueTail;
+	    if (bufPtr == NULL) {
+		goto restore;
+	    }
+	} else {
+	    /*
+	     * Incoming CHANNEL_STICKY_EOF is filtered out on entry.
+	     * A new CHANNEL_STICKY_EOF set in this routine leads to
+	     * return before coming back here.  When we are not dealing
+	     * with CHANNEL_STICKY_EOF, a CHANNEL_EOF implies an
+	     * empty buffer.  Here the buffer is non-empty so we know
+	     * we're a non-EOF */
+
+	    assert ( !GotFlag(statePtr, CHANNEL_STICKY_EOF) );
+	    assert ( !GotFlag(statePtr, CHANNEL_EOF) );
+	}
+
+	dst = (unsigned char *) RemovePoint(bufPtr);
+	dstEnd = dst + BytesLeft(bufPtr);
+
+	/*
+	 * Remember if EOF char is seen, then look for EOL anyhow, because the
+	 * EOL might be before the EOF char.
+	 * XXX - in the binary case, consider coincident search for eol/eof.
+	 */
+
+	if (inEofChar != '\0') {
+	    for (eol = dst; eol < dstEnd; eol++) {
+		if (*eol == inEofChar) {
+		    dstEnd = eol;
+		    eof = eol;
+		    break;
+		}
+	    }
+	}
+
+	/*
+	 * On EOL, leave current file position pointing after the EOL, but
+	 * don't store the EOL in the output string.
+	 */
+
+	for (eol = dst; eol < dstEnd; eol++) {
+	    if (*eol == eolChar) {
+		skip = 1;
+		goto gotEOL;
+	    }
+	}
+	if (eof != NULL) {
+	    /*
+	     * EOF character was seen. On EOF, leave current file position
+	     * pointing at the EOF character, but don't store the EOF
+	     * character in the output string.
+	     */
+
+	    SetFlag(statePtr, CHANNEL_EOF | CHANNEL_STICKY_EOF);
+	    statePtr->inputEncodingFlags |= TCL_ENCODING_END;
+	    ResetFlag(statePtr, CHANNEL_BLOCKED|INPUT_SAW_CR);
+	}
+	if (GotFlag(statePtr, CHANNEL_EOF)) {
+	    skip = 0;
+	    eol = dstEnd;
+	    if ((dst == dstEnd) && (byteLen == oldLength)) {
+		/*
+		 * If we didn't append any bytes before encountering EOF,
+		 * caller needs to see -1.
+		 */
+
+		byteArray = Tcl_SetByteArrayLength(objPtr, oldLength);
+		CommonGetsCleanup(chanPtr);
+		copiedTotal = -1;
+		ResetFlag(statePtr, CHANNEL_BLOCKED);
+		goto done;
+	    }
+	    goto gotEOL;
+	}
+	if (GotFlag(statePtr, CHANNEL_BLOCKED|CHANNEL_NONBLOCKING)
+		== (CHANNEL_BLOCKED|CHANNEL_NONBLOCKING)) {
+	    goto restore;
+	}
+
+	/*
+	 * Copy bytes from the channel buffer to the ByteArray.
+	 * This may realloc space, so keep track of result.
+	 */
+
+	rawLen = dstEnd - dst;
+	byteArray = Tcl_SetByteArrayLength(objPtr, byteLen + rawLen);
+	memcpy(byteArray + byteLen, dst, (size_t) rawLen);
+	byteLen += rawLen;
+    }
+
+    /*
+     * Found EOL or EOF, but the output buffer may now contain too many bytes.
+     * We need to know how many bytes correspond to the number we want, so we
+     * can remove the correct number of bytes from the channel buffer.
+     */
+
+  gotEOL:
+    if (bufPtr == NULL) {
+	Tcl_Panic("TclGetsObjBinary: gotEOL reached with bufPtr==NULL");
+    }
+
+    rawLen = eol - dst;
+    byteArray = Tcl_SetByteArrayLength(objPtr, byteLen + rawLen);
+    memcpy(byteArray + byteLen, dst, (size_t) rawLen);
+    byteLen += rawLen;
+    bufPtr->nextRemoved += rawLen + skip;
+
+    /*
+     * Convert the buffer if there was an encoding.
+     * XXX - unimplemented.
+     */
+
+    if (statePtr->encoding != NULL) {
+    }
+
+    /*
+     * Recycle all the emptied buffers.
+     */
+
+    CommonGetsCleanup(chanPtr);
+    ResetFlag(statePtr, CHANNEL_BLOCKED);
+    copiedTotal = byteLen;
+    goto done;
+
+    /*
+     * Couldn't get a complete line. This only happens if we get a error
+     * reading from the channel or we are non-blocking and there wasn't an EOL
+     * or EOF in the data available.
+     */
+
+  restore:
+    bufPtr = statePtr->inQueueHead;
+    if (bufPtr) {
+	bufPtr->nextRemoved = oldRemoved;
+	bufPtr = bufPtr->nextPtr;
+    }
+
+    for ( ; bufPtr != NULL; bufPtr = bufPtr->nextPtr) {
+	bufPtr->nextRemoved = BUFFER_PADDING;
+    }
+    CommonGetsCleanup(chanPtr);
+
+    statePtr->inputEncodingFlags = oldFlags;
+    byteArray = Tcl_SetByteArrayLength(objPtr, oldLength);
+
+    /*
+     * We didn't get a complete line so we need to indicate to UpdateInterest
+     * that the gets blocked. It will wait for more data instead of firing a
+     * timer, avoiding a busy wait. This is where we are assuming that the
+     * next operation is a gets. No more file events will be delivered on this
+     * channel until new data arrives or some operation is performed on the
+     * channel (e.g. gets, read, fconfigure) that changes the blocking state.
+     * Note that this means a file event will not be delivered even though a
+     * read would be able to consume the buffered data.
+     */
+
+    SetFlag(statePtr, CHANNEL_NEED_MORE_DATA);
+    copiedTotal = -1;
+
+    /*
+     * Update the notifier state so we don't block while there is still data
+     * in the buffers.
+     */
+
+  done:
+	assert(!GotFlag(statePtr, CHANNEL_EOF)
+		|| GotFlag(statePtr, CHANNEL_STICKY_EOF)
+		|| Tcl_InputBuffered((Tcl_Channel)chanPtr) == 0);
+	assert( !(GotFlag(statePtr, CHANNEL_EOF|CHANNEL_BLOCKED)
+		== (CHANNEL_EOF|CHANNEL_BLOCKED)) );
+    UpdateInterest(chanPtr);
+    TclChannelRelease((Tcl_Channel)chanPtr);
+    return copiedTotal;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * FreeBinaryEncoding --
+ *
+ *	Frees any "iso8859-1" Tcl_Encoding created by [gets] on a binary
+ *	channel in a thread as part of that thread's finalization.
+ *
+ * Results:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+static void
+FreeBinaryEncoding(
+    ClientData dummy)	/* Not used */
+{
+    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+
+    if (tsdPtr->binaryEncoding != NULL) {
+	Tcl_FreeEncoding(tsdPtr->binaryEncoding);
+	tsdPtr->binaryEncoding = NULL;
+    }
+}
+
+static Tcl_Encoding
+GetBinaryEncoding()
+{
+    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+
+    if (tsdPtr->binaryEncoding == NULL) {
+	tsdPtr->binaryEncoding = Tcl_GetEncoding(NULL, "iso8859-1");
+	Tcl_CreateThreadExitHandler(FreeBinaryEncoding, NULL);
+    }
+    if (tsdPtr->binaryEncoding == NULL) {
+	Tcl_Panic("binary encoding is not available");
+    }
+    return tsdPtr->binaryEncoding;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * FilterInputBytes --
+ *
+ *	Helper function for Tcl_GetsObj. Produces UTF-8 characters from raw
+ *	bytes read from the channel.
+ *
+ *	Consumes available bytes from channel buffers. When channel buffers
+ *	are exhausted, reads more bytes from channel device into a new channel
+ *	buffer. It is the caller's responsibility to free the channel buffers
+ *	that have been exhausted.
+ *
+ * Results:
+ *	The return value is -1 if there was an error reading from the channel,
+ *	0 otherwise.
+ *
+ * Side effects:
+ *	Status object keeps track of how much data from channel buffers has
+ *	been consumed and where UTF-8 bytes should be stored.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+static int
+FilterInputBytes(
+    Channel *chanPtr,		/* Channel to read. */
+    GetsState *gsPtr)		/* Current state of gets operation. */
+{
+    ChannelState *statePtr = chanPtr->state;
+				/* State info for channel */
+    ChannelBuffer *bufPtr;
+    char *raw, *dst;
+    int offset, toRead, dstNeeded, spaceLeft, result, rawLen;
+    Tcl_Obj *objPtr;
+#define ENCODING_LINESIZE 20	/* Lower bound on how many bytes to convert at
+				 * a time. Since we don't know a priori how
+				 * many bytes of storage this many source
+				 * bytes will use, we actually need at least
+				 * ENCODING_LINESIZE * TCL_MAX_UTF bytes of
+				 * room. */
+
+    objPtr = gsPtr->objPtr;
+
+    /*
+     * Subtract the number of bytes that were removed from channel buffer
+     * during last call.
+     */
+
+    bufPtr = gsPtr->bufPtr;
+    if (bufPtr != NULL) {
+	bufPtr->nextRemoved += gsPtr->rawRead;
+	if (!IsBufferReady(bufPtr)) {
+	    bufPtr = bufPtr->nextPtr;
+	}
+    }
+    gsPtr->totalChars += gsPtr->charsWrote;
+
+    if ((bufPtr == NULL) || (bufPtr->nextAdded == BUFFER_PADDING)) {
+	/*
+	 * All channel buffers were exhausted and the caller still hasn't seen
+	 * EOL. Need to read more bytes from the channel device. Side effect
+	 * is to allocate another channel buffer.
+	 */
+
+    read:
+	if (GotFlag(statePtr, CHANNEL_NONBLOCKING|CHANNEL_BLOCKED)
+		== (CHANNEL_NONBLOCKING|CHANNEL_BLOCKED)) {
+	    gsPtr->charsWrote = 0;
+	    gsPtr->rawRead = 0;
+	    return -1;
+	}
+	if (GetInput(chanPtr) != 0) {
+	    gsPtr->charsWrote = 0;
+	    gsPtr->rawRead = 0;
+	    return -1;
+	}
+	bufPtr = statePtr->inQueueTail;
+	gsPtr->bufPtr = bufPtr;
+	if (bufPtr == NULL) {
+	    gsPtr->charsWrote = 0;
+	    gsPtr->rawRead = 0;
+	    return -1;
+	}
+    } else {
+	/*
+	 * Incoming CHANNEL_STICKY_EOF is filtered out on entry.
+	 * A new CHANNEL_STICKY_EOF set in this routine leads to
+	 * return before coming back here.  When we are not dealing
+	 * with CHANNEL_STICKY_EOF, a CHANNEL_EOF implies an
+	 * empty buffer.  Here the buffer is non-empty so we know
+	 * we're a non-EOF */
+
+	assert ( !GotFlag(statePtr, CHANNEL_STICKY_EOF) );
+	assert ( !GotFlag(statePtr, CHANNEL_EOF) );
+    }
+
+    /*
+     * Convert some of the bytes from the channel buffer to UTF-8. Space in
+     * objPtr's string rep is used to hold the UTF-8 characters. Grow the
+     * string rep if we need more space.
+     */
+
+    raw = RemovePoint(bufPtr);
+    rawLen = BytesLeft(bufPtr);
+
+    dst = *gsPtr->dstPtr;
+    offset = dst - objPtr->bytes;
+    toRead = ENCODING_LINESIZE;
+    if (toRead > rawLen) {
+	toRead = rawLen;
+    }
+    dstNeeded = toRead * TCL_UTF_MAX;
+    spaceLeft = objPtr->length - offset;
+    if (dstNeeded > spaceLeft) {
+	int length = offset + ((offset < dstNeeded) ? dstNeeded : offset);
+
+	if (Tcl_AttemptSetObjLength(objPtr, length) == 0) {
+	    length = offset + dstNeeded;
+	    if (Tcl_AttemptSetObjLength(objPtr, length) == 0) {
+		dstNeeded = TCL_UTF_MAX - 1 + toRead;
+		length = offset + dstNeeded;
+		Tcl_SetObjLength(objPtr, length);
+	    }
+	}
+	spaceLeft = length - offset;
+	dst = objPtr->bytes + offset;
+	*gsPtr->dstPtr = dst;
+    }
+    gsPtr->state = statePtr->inputEncodingState;
+    result = Tcl_ExternalToUtf(NULL, gsPtr->encoding, raw, rawLen,
+	    statePtr->inputEncodingFlags | TCL_ENCODING_NO_TERMINATE,
+	    &statePtr->inputEncodingState, dst, spaceLeft, &gsPtr->rawRead,
+	    &gsPtr->bytesWrote, &gsPtr->charsWrote);
+
+    /*
+     * Make sure that if we go through 'gets', that we reset the
+     * TCL_ENCODING_START flag still. [Bug #523988]
+     */
+
+    statePtr->inputEncodingFlags &= ~TCL_ENCODING_START;
+
+    if (result == TCL_CONVERT_MULTIBYTE) {
+	/*
+	 * The last few bytes in this channel buffer were the start of a
+	 * multibyte sequence. If this buffer was full, then move them to the
+	 * next buffer so the bytes will be contiguous.
+	 */
+
+	ChannelBuffer *nextPtr;
+	int extra;
+
+	nextPtr = bufPtr->nextPtr;
+	if (!IsBufferFull(bufPtr)) {
+	    if (gsPtr->rawRead > 0) {
+		/*
+		 * Some raw bytes were converted to UTF-8. Fall through,
+		 * returning those UTF-8 characters because a EOL might be
+		 * present in them.
+		 */
+	    } else if (GotFlag(statePtr, CHANNEL_EOF)) {
+		/*
+		 * There was a partial character followed by EOF on the
+		 * device. Fall through, returning that nothing was found.
+		 */
+
+		bufPtr->nextRemoved = bufPtr->nextAdded;
+	    } else {
+		/*
+		 * There are no more cached raw bytes left. See if we can get
+		 * some more, but avoid blocking on a non-blocking channel.
+		 */
+
+		goto read;
+	    }
+	} else {
+	    if (nextPtr == NULL) {
+		nextPtr = AllocChannelBuffer(statePtr->bufSize);
+		bufPtr->nextPtr = nextPtr;
+		statePtr->inQueueTail = nextPtr;
+	    }
+	    extra = rawLen - gsPtr->rawRead;
+	    memcpy(nextPtr->buf + (BUFFER_PADDING - extra),
+		    raw + gsPtr->rawRead, (size_t) extra);
+	    nextPtr->nextRemoved -= extra;
+	    bufPtr->nextAdded -= extra;
+	}
+    }
+
+    gsPtr->bufPtr = bufPtr;
+    return 0;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * PeekAhead --
+ *
+ *	Helper function used by Tcl_GetsObj(). Called when we've seen a \r at
+ *	the end of the UTF-8 string and want to look ahead one character to
+ *	see if it is a \n.
+ *
+ * Results:
+ *	*gsPtr->dstPtr is filled with a pointer to the start of the range of
+ *	UTF-8 characters that were found by peeking and *dstEndPtr is filled
+ *	with a pointer to the bytes just after the end of the range.
+ *
+ * Side effects:
+ *	If no more raw bytes were available in one of the channel buffers,
+ *	tries to perform a non-blocking read to get more bytes from the
+ *	channel device.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+static void
+PeekAhead(
+    Channel *chanPtr,		/* The channel to read. */
+    char **dstEndPtr,		/* Filled with pointer to end of new range of
+				 * UTF-8 characters. */
+    GetsState *gsPtr)		/* Current state of gets operation. */
+{
+    ChannelState *statePtr = chanPtr->state;
+				/* State info for channel */
+    ChannelBuffer *bufPtr;
+    Tcl_DriverBlockModeProc *blockModeProc;
+    int bytesLeft;
+
+    bufPtr = gsPtr->bufPtr;
+
+    /*
+     * If there's any more raw input that's still buffered, we'll peek into
+     * that. Otherwise, only get more data from the channel driver if it looks
+     * like there might actually be more data. The assumption is that if the
+     * channel buffer is filled right up to the end, then there might be more
+     * data to read.
+     */
+
+    blockModeProc = NULL;
+    if (bufPtr->nextPtr == NULL) {
+	bytesLeft = BytesLeft(bufPtr) - gsPtr->rawRead;
+	if (bytesLeft == 0) {
+	    if (!IsBufferFull(bufPtr)) {
+		/*
+		 * Don't peek ahead if last read was short read.
+		 */
+
+		goto cleanup;
+	    }
+	    if (!GotFlag(statePtr, CHANNEL_NONBLOCKING)) {
+		blockModeProc = Tcl_ChannelBlockModeProc(chanPtr->typePtr);
+		if (blockModeProc == NULL) {
+		    /*
+		     * Don't peek ahead if cannot set non-blocking mode.
+		     */
+
+		    goto cleanup;
+		}
+		StackSetBlockMode(chanPtr, TCL_MODE_NONBLOCKING);
+	    }
+	}
+    }
+    if (FilterInputBytes(chanPtr, gsPtr) == 0) {
+	*dstEndPtr = *gsPtr->dstPtr + gsPtr->bytesWrote;
+    }
+    if (blockModeProc != NULL) {
+	StackSetBlockMode(chanPtr, TCL_MODE_BLOCKING);
+    }
+    return;
+
+  cleanup:
+    bufPtr->nextRemoved += gsPtr->rawRead;
+    gsPtr->rawRead = 0;
+    gsPtr->totalChars += gsPtr->charsWrote;
+    gsPtr->bytesWrote = 0;
+    gsPtr->charsWrote = 0;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * CommonGetsCleanup --
+ *
+ *	Helper function for Tcl_GetsObj() to restore the channel after a
+ *	"gets" operation.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Encoding may be freed.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+static void
+CommonGetsCleanup(
+    Channel *chanPtr)
+{
+    ChannelState *statePtr = chanPtr->state;
+				/* State info for channel */
+    ChannelBuffer *bufPtr, *nextPtr;
+
+    bufPtr = statePtr->inQueueHead;
+    for ( ; bufPtr != NULL; bufPtr = nextPtr) {
+	nextPtr = bufPtr->nextPtr;
+	if (IsBufferReady(bufPtr)) {
+	    break;
+	}
+	RecycleBuffer(statePtr, bufPtr, 0);
+    }
+    statePtr->inQueueHead = bufPtr;
+    if (bufPtr == NULL) {
+	statePtr->inQueueTail = NULL;
+    } else {
+	/*
+	 * If any multi-byte characters were split across channel buffer
+	 * boundaries, the split-up bytes were moved to the next channel
+	 * buffer by FilterInputBytes(). Move the bytes back to their original
+	 * buffer because the caller could change the channel's encoding which
+	 * could change the interpretation of whether those bytes really made
+	 * up multi-byte characters after all.
+	 */
+
+	nextPtr = bufPtr->nextPtr;
+	for ( ; nextPtr != NULL; nextPtr = bufPtr->nextPtr) {
+	    int extra;
+
+	    extra = SpaceLeft(bufPtr);
+	    if (extra > 0) {
+		memcpy(InsertPoint(bufPtr),
+			nextPtr->buf + (BUFFER_PADDING - extra),
+			(size_t) extra);
+		bufPtr->nextAdded += extra;
+		nextPtr->nextRemoved = BUFFER_PADDING;
+	    }
+	    bufPtr = nextPtr;
+	}
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_Read --
+ *
+ *	Reads a given number of bytes from a channel. EOL and EOF translation
+ *	is done on the bytes being read, so the number of bytes consumed from
+ *	the channel may not be equal to the number of bytes stored in the
+ *	destination buffer.
+ *
+ *	No encoding conversions are applied to the bytes being read.
+ *
+ * Results:
+ *	The number of bytes read, or -1 on error. Use Tcl_GetErrno() to
+ *	retrieve the error code for the error that occurred.
+ *
+ * Side effects:
+ *	May cause input to be buffered.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_Read(
+    Tcl_Channel chan,		/* The channel from which to read. */
+    char *dst,			/* Where to store input read. */
+    int bytesToRead)		/* Maximum number of bytes to read. */
+{
+    Channel *chanPtr = (Channel *) chan;
+    ChannelState *statePtr = chanPtr->state;
+				/* State info for channel */
+
+    /*
+     * This operation should occur at the top of a channel stack.
+     */
+
+    chanPtr = statePtr->topChanPtr;
+
+    if (CheckChannelErrors(statePtr, TCL_READABLE) != 0) {
+	return -1;
+    }
+
+    return DoRead(chanPtr, dst, bytesToRead, 0);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_ReadRaw --
+ *
+ *	Reads a given number of bytes from a channel. EOL and EOF translation
+ *	is done on the bytes being read, so the number of bytes consumed from
+ *	the channel may not be equal to the number of bytes stored in the
+ *	destination buffer.
+ *
+ *	No encoding conversions are applied to the bytes being read.
+ *
+ * Results:
+ *	The number of bytes read, or -1 on error. Use Tcl_GetErrno() to
+ *	retrieve the error code for the error that occurred.
+ *
+ * Side effects:
+ *	May cause input to be buffered.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_ReadRaw(
+    Tcl_Channel chan,		/* The channel from which to read. */
+    char *readBuf,		/* Where to store input read. */
+    int bytesToRead)		/* Maximum number of bytes to read. */
+{
+    Channel *chanPtr = (Channel *) chan;
+    ChannelState *statePtr = chanPtr->state;
+				/* State info for channel */
+    int copied = 0;
+
+    assert(bytesToRead > 0);
+    if (CheckChannelErrors(statePtr, TCL_READABLE | CHANNEL_RAW_MODE) != 0) {
+	return -1;
+    }
+
+    /* First read bytes from the push-back buffers. */
+
+    while (chanPtr->inQueueHead && bytesToRead > 0) {
+	ChannelBuffer *bufPtr = chanPtr->inQueueHead;
+	int bytesInBuffer = BytesLeft(bufPtr);
+	int toCopy = (bytesInBuffer < bytesToRead) ? bytesInBuffer
+		: bytesToRead;
+
+	/* Copy the current chunk into the read buffer. */
+
+	memcpy(readBuf, RemovePoint(bufPtr), (size_t) toCopy);
+	bufPtr->nextRemoved += toCopy;
+	copied += toCopy;
+	readBuf += toCopy;
+	bytesToRead -= toCopy;
+
+	/* If the current buffer is empty recycle it. */
+
+	if (IsBufferEmpty(bufPtr)) {
+	    chanPtr->inQueueHead = bufPtr->nextPtr;
+	    if (chanPtr->inQueueHead == NULL) {
+		chanPtr->inQueueTail = NULL;
+	    }
+	    RecycleBuffer(chanPtr->state, bufPtr, 0);
+	}
+    }
+
+    /*
+     * Go to the driver only if we got nothing from pushback.
+     * Have to do it this way to avoid EOF mis-timings when we
+     * consider the ability that EOF may not be a permanent
+     * condition in the driver, and in that case we have to
+     * synchronize.
+     */
+
+    if (copied) {
+	return copied;
+    }
+
+    /* This test not needed. */
+    if (bytesToRead > 0) {
+
+	int nread = ChanRead(chanPtr, readBuf, bytesToRead);
+
+	if (nread > 0) {
+	    /* Successful read (short is OK) - add to bytes copied */
+	    copied += nread;
+	} else if (nread < 0) {
+	    /*
+	     * An error signaled.  If CHANNEL_BLOCKED, then the error
+	     * is not real, but an indication of blocked state.  In
+	     * that case, retain the flag and let caller receive the
+	     * short read of copied bytes from the pushback.
+	     * HOWEVER, if copied==0 bytes from pushback then repeat
+	     * signalling the blocked state as an error to caller so
+	     * there is no false report of an EOF.
+	     * When !CHANNEL_BLOCKED, the error is real and passes on
+	     * to caller.
+	     */
+	    if (!GotFlag(statePtr, CHANNEL_BLOCKED) || copied == 0) {
+		copied = -1;
+	    }
+	} else {
+	    /*
+	     * nread == 0.  Driver is at EOF. Let that state filter up.
+	     */
+	}
+    }
+    return copied;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Tcl_ReadChars --
+ *
+ *	Reads from the channel until the requested number of characters have
+ *	been seen, EOF is seen, or the channel would block. EOL and EOF
+ *	translation is done. If reading binary data, the raw bytes are wrapped
+ *	in a Tcl byte array object. Otherwise, the raw bytes are converted to
+ *	UTF-8 using the channel's current encoding and stored in a Tcl string
+ *	object.
+ *
+ * Results:
+ *	The number of characters read, or -1 on error. Use Tcl_GetErrno() to
+ *	retrieve the error code for the error that occurred.
+ *
+ * Side effects:
+ *	May cause input to be buffered.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+int
+Tcl_ReadChars(
+    Tcl_Channel chan,		/* The channel to read. */
+    Tcl_Obj *objPtr,		/* Input data is stored in this object. */
+    int toRead,			/* Maximum number of characters to store, or
+				 * -1 to read all available data (up to EOF or
+				 * when channel blocks). */
+    int appendFlag)		/* If non-zero, data read from the channel
+				 * will be appended to the object. Otherwise,
+				 * the data will replace the existing contents
+				 * of the object. */
+{
+    Channel *chanPtr = (Channel *) chan;
+    ChannelState *statePtr = chanPtr->state;
+				/* State info for channel */
+
+    /*
+     * This operation should occur at the top of a channel stack.
+     */
+
+    chanPtr = statePtr->topChanPtr;
+
+    if (CheckChannelErrors(statePtr, TCL_READABLE) != 0) {
+	/*
+	 * Update the notifier state so we don't block while there is still
+	 * data in the buffers.
+	 */
+
+	UpdateInterest(chanPtr);
+	return -1;
+    }
+
+    return DoReadChars(chanPtr, objPtr, toRead, appendFlag);
+}
+/*
+ *---------------------------------------------------------------------------
+ *
+ * DoReadChars --
+ *
+ *	Reads from the channel until the requested number of characters have
+ *	been seen, EOF is seen, or the channel would block. EOL and EOF
+ *	translation is done. If reading binary data, the raw bytes are wrapped
+ *	in a Tcl byte array object. Otherwise, the raw bytes are converted to
+ *	UTF-8 using the channel's current encoding and stored in a Tcl string
+ *	object.
+ *
+ * Results:
+ *	The number of characters read, or -1 on error. Use Tcl_GetErrno() to
+ *	retrieve the error code for the error that occurred.
+ *
+ * Side effects:
+ *	May cause input to be buffered.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+static int
+DoReadChars(
+    Channel *chanPtr,		/* The channel to read. */
+    Tcl_Obj *objPtr,		/* Input data is stored in this object. */
+    int toRead,			/* Maximum number of characters to store, or
+				 * -1 to read all available data (up to EOF or
+				 * when channel blocks). */
+    int appendFlag)		/* If non-zero, data read from the channel
+				 * will be appended to the object. Otherwise,
+				 * the data will replace the existing contents
+				 * of the object. */
+{
+    ChannelState *statePtr = chanPtr->state;
+				/* State info for channel */
+    ChannelBuffer *bufPtr;
+    int copied, copiedNow, result;
+    Tcl_Encoding encoding = statePtr->encoding;
+    int binaryMode;
+#define UTF_EXPANSION_FACTOR	1024
+    int factor = UTF_EXPANSION_FACTOR;
+
+    binaryMode = (encoding == NULL)
+	    && (statePtr->inputTranslation == TCL_TRANSLATE_LF)
+	    && (statePtr->inEofChar == '\0');
+
+    if (appendFlag == 0) {
+	if (binaryMode) {
+	    Tcl_SetByteArrayLength(objPtr, 0);
+	} else {
+	    Tcl_SetObjLength(objPtr, 0);
+
+	    /*
+	     * We're going to access objPtr->bytes directly, so we must ensure
+	     * that this is actually a string object (otherwise it might have
+	     * been pure Unicode).
+	     *
+	     * Probably not needed anymore.
+	     */
+
+	    TclGetString(objPtr);
+	}
+    }
+
+    /*
+     * Early out when next read will see eofchar.
+     *
+     * NOTE: See DoRead for argument that it's a bug (one we're keeping)
+     * to have this escape before the one for zero-char read request.
+     */
+
+    if (GotFlag(statePtr, CHANNEL_STICKY_EOF)) {
+	SetFlag(statePtr, CHANNEL_EOF);
+	assert( statePtr->inputEncodingFlags & TCL_ENCODING_END );
+	assert( !GotFlag(statePtr, CHANNEL_BLOCKED|INPUT_SAW_CR) );
+
+	/* TODO: We don't need this call? */
+	UpdateInterest(chanPtr);
+	return 0;
+    }
+
+    /* Special handling for zero-char read request. */
+    if (toRead == 0) {
+	if (GotFlag(statePtr, CHANNEL_EOF)) {
+	    statePtr->inputEncodingFlags |= TCL_ENCODING_START;
+	}
+	ResetFlag(statePtr, CHANNEL_BLOCKED|CHANNEL_EOF);
+	statePtr->inputEncodingFlags &= ~TCL_ENCODING_END;
+	/* TODO: We don't need this call? */
+	UpdateInterest(chanPtr);
+	return 0;
+    }
+
+    /*
+     * This operation should occur at the top of a channel stack.
+     */
+
+    chanPtr = statePtr->topChanPtr;
+    TclChannelPreserve((Tcl_Channel)chanPtr);
+
+    /* Must clear the BLOCKED|EOF flags here since we check before reading */
+    if (GotFlag(statePtr, CHANNEL_EOF)) {
+	statePtr->inputEncodingFlags |= TCL_ENCODING_START;
+    }
+    ResetFlag(statePtr, CHANNEL_BLOCKED|CHANNEL_EOF);
+    statePtr->inputEncodingFlags &= ~TCL_ENCODING_END;
+    for (copied = 0; (unsigned) toRead > 0; ) {
+	copiedNow = -1;
+	if (statePtr->inQueueHead != NULL) {
+	    if (binaryMode) {
+		copiedNow = ReadBytes(statePtr, objPtr, toRead);
+	    } else {
+		copiedNow = ReadChars(statePtr, objPtr, toRead, &factor);
+	    }
+
+	    /*
+	     * If the current buffer is empty recycle it.
+	     */
+
+	    bufPtr = statePtr->inQueueHead;
+	    if (IsBufferEmpty(bufPtr)) {
+		ChannelBuffer *nextPtr = bufPtr->nextPtr;
+
+		RecycleBuffer(statePtr, bufPtr, 0);
+		statePtr->inQueueHead = nextPtr;
+		if (nextPtr == NULL) {
+		    statePtr->inQueueTail = NULL;
+		}
+	    }
+	}
+
+	if (copiedNow < 0) {
+	    if (GotFlag(statePtr, CHANNEL_EOF)) {
+		break;
+	    }
+	    if (GotFlag(statePtr, CHANNEL_NONBLOCKING|CHANNEL_BLOCKED)
+		    == (CHANNEL_NONBLOCKING|CHANNEL_BLOCKED)) {
+		break;
+	    }
+	    result = GetInput(chanPtr);
+	    if (chanPtr != statePtr->topChanPtr) {
+		TclChannelRelease((Tcl_Channel)chanPtr);
+		chanPtr = statePtr->topChanPtr;
+		TclChannelPreserve((Tcl_Channel)chanPtr);
+	    }
+	    if (result != 0) {
+		if (!GotFlag(statePtr, CHANNEL_BLOCKED)) {
+		    copied = -1;
+		}
+		break;
+	    }
+	} else {
+	    copied += copiedNow;
+	    toRead -= copiedNow;
+	}
+    }
+
+    /*
+     * Failure to fill a channel buffer may have left channel reporting
+     * a "blocked" state, but so long as we fulfilled the request here,
+     * the caller does not consider us blocked.
+     */
+    if (toRead == 0) {
+	ResetFlag(statePtr, CHANNEL_BLOCKED);
+    }
+
+    /*
+     * Regenerate the top channel, in case it was changed due to
+     * self-modifying reflected transforms.
+     */
+    if (chanPtr != statePtr->topChanPtr) {
+	TclChannelRelease((Tcl_Channel)chanPtr);
+	chanPtr = statePtr->topChanPtr;
+	TclChannelPreserve((Tcl_Channel)chanPtr);
+    }
+
+    /*
+     * Update the notifier state so we don't block while there is still data
+     * in the buffers.
+     */
+	assert(!GotFlag(statePtr, CHANNEL_EOF)
+		|| GotFlag(statePtr, CHANNEL_STICKY_EOF)
+		|| Tcl_InputBuffered((Tcl_Channel)chanPtr) == 0);
+	assert( !(GotFlag(statePtr, CHANNEL_EOF|CHANNEL_BLOCKED)
+		== (CHANNEL_EOF|CHANNEL_BLOCKED)) );
+    UpdateInterest(chanPtr);
+    TclChannelRelease((Tcl_Channel)chanPtr);
+    return copied;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * ReadBytes --
+ *
+ *	Reads from the channel until the requested number of bytes have been
+ *	seen, EOF is seen, or the channel would block. Bytes from the channel
+ *	are stored in objPtr as a ByteArray object. EOL and EOF translation
+ *	are done.
+ *
+ *	'bytesToRead' can safely be a very large number because space is only
+ *	allocated to hold data read from the channel as needed.
+ *
+ * Results:
+ *	The return value is the number of bytes appended to the object, or
+ *	-1 to indicate that zero bytes were read due to an EOF.
+ *
+ * Side effects:
+ *	The storage of bytes in objPtr can cause (re-)allocation of memory.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+static int
+ReadBytes(
+    ChannelState *statePtr,	/* State of the channel to read. */
+    Tcl_Obj *objPtr,		/* Input data is appended to this ByteArray
+				 * object. Its length is how much space has
+				 * been allocated to hold data, not how many
+				 * bytes of data have been stored in the
+				 * object. */
+    int bytesToRead)		/* Maximum number of bytes to store, or < 0 to
+				 * get all available bytes. Bytes are obtained
+				 * from the first buffer in the queue - even
+				 * if this number is larger than the number of
+				 * bytes available in the first buffer, only
+				 * the bytes from the first buffer are
+				 * returned. */
+{
+    ChannelBuffer *bufPtr = statePtr->inQueueHead;
+    int srcLen = BytesLeft(bufPtr);
+    int toRead = bytesToRead>srcLen || bytesToRead<0 ? srcLen : bytesToRead;
+
+    TclAppendBytesToByteArray(objPtr, (unsigned char *) RemovePoint(bufPtr),
+	    toRead);
+    bufPtr->nextRemoved += toRead;
+    return toRead;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * ReadChars --
+ *
+ *	Reads from the channel until the requested number of UTF-8 characters
+ *	have been seen, EOF is seen, or the channel would block. Raw bytes
+ *	from the channel are converted to UTF-8 and stored in objPtr. EOL and
+ *	EOF translation is done.
+ *
+ *	'charsToRead' can safely be a very large number because space is only
+ *	allocated to hold data read from the channel as needed.
+ *
+ *	'charsToRead' may *not* be 0.
+ *
+ * Results:
+ *	The return value is the number of characters appended to the object,
+ *	*offsetPtr is filled with the number of bytes that were appended, and
+ *	*factorPtr is filled with the expansion factor used to guess how many
+ *	bytes of UTF-8 to allocate to hold N source bytes.
+ *
+ * Side effects:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+static int
+ReadChars(
+    ChannelState *statePtr,	/* State of channel to read. */
+    Tcl_Obj *objPtr,		/* Input data is appended to this object.
+				 * objPtr->length is how much space has been
+				 * allocated to hold data, not how many bytes
+				 * of data have been stored in the object. */
+    int charsToRead,		/* Maximum number of characters to store, or
+				 * -1 to get all available characters.
+				 * Characters are obtained from the first
+				 * buffer in the queue -- even if this number
+				 * is larger than the number of characters
+				 * available in the first buffer, only the
+				 * characters from the first buffer are
+				 * returned. The execption is when there is
+				 * not any complete character in the first
+				 * buffer.  In that case, a recursive call
+				 * effectively obtains chars from the
+				 * second buffer. */
+    int *factorPtr)		/* On input, contains a guess of how many
+				 * bytes need to be allocated to hold the
+				 * result of converting N source bytes to
+				 * UTF-8. On output, contains another guess
+				 * based on the data seen so far. */
+{
+    Tcl_Encoding encoding = statePtr->encoding? statePtr->encoding
+	    : GetBinaryEncoding();
+    Tcl_EncodingState savedState = statePtr->inputEncodingState;
+    ChannelBuffer *bufPtr = statePtr->inQueueHead;
+    int savedIEFlags = statePtr->inputEncodingFlags;
+    int savedFlags = statePtr->flags;
+    char *dst, *src = RemovePoint(bufPtr);
+    int numBytes, srcLen = BytesLeft(bufPtr);
+
+    /*
+     * One src byte can yield at most one character.  So when the
+     * number of src bytes we plan to read is less than the limit on
+     * character count to be read, clearly we will remain within that
+     * limit, and we can use the value of "srcLen" as a tighter limit
+     * for sizing receiving buffers.
+     */
+
+    int toRead = ((charsToRead<0)||(charsToRead > srcLen)) ? srcLen : charsToRead;
+
+    /*
+     * 'factor' is how much we guess that the bytes in the source buffer will
+     * expand when converted to UTF-8 chars. This guess comes from analyzing
+     * how many characters were produced by the previous pass.
+     */
+
+    int factor = *factorPtr;
+    int dstLimit = TCL_UTF_MAX - 1 + toRead * factor / UTF_EXPANSION_FACTOR;
+
+    (void) TclGetStringFromObj(objPtr, &numBytes);
+    Tcl_AppendToObj(objPtr, NULL, dstLimit);
+    if (toRead == srcLen) {
+	unsigned int size;
+	dst = TclGetStringStorage(objPtr, &size) + numBytes;
+	dstLimit = size - numBytes;
+    } else {
+	dst = TclGetString(objPtr) + numBytes;
+    }
+
+    /*
+     * This routine is burdened with satisfying several constraints.
+     * It cannot append more than 'charsToRead` chars onto objPtr.
+     * This is measured after encoding and translation transformations
+     * are completed.  There is no precise number of src bytes that can
+     * be associated with the limit.  Yet, when we are done, we must know
+     * precisely the number of src bytes that were consumed to produce
+     * the appended chars, so that all subsequent bytes are left in
+     * the buffers for future read operations.
+     *
+     * The consequence is that we have no choice but to implement a
+     * "trial and error" approach, where in general we may need to
+     * perform transformations and copies multiple times to achieve
+     * a consistent set of results.  This takes the shape of a loop.
+     */
+
+    while (1) {
+	int dstDecoded, dstRead, dstWrote, srcRead, numChars, code;
+	int flags = statePtr->inputEncodingFlags | TCL_ENCODING_NO_TERMINATE;
+
+	if (charsToRead > 0) {
+	    flags |= TCL_ENCODING_CHAR_LIMIT;
+	    numChars = charsToRead;
+	}
+
+	/*
+	 * Perform the encoding transformation.  Read no more than
+	 * srcLen bytes, write no more than dstLimit bytes.
+	 *
+	 * Some trickiness with encoding flags here.  We do not want
+	 * the end of a buffer to be treated as the end of all input
+	 * when the presence of bytes in a next buffer are already
+	 * known to exist.  This is checked with an assert() because
+	 * so far no test case causing the assertion to be false has
+	 * been created.  The normal operations of channel reading
+	 * appear to cause EOF and TCL_ENCODING_END setting to appear
+	 * only in situations where there are no further bytes in
+	 * any buffers.
+	 */
+
+	assert(bufPtr->nextPtr == NULL || BytesLeft(bufPtr->nextPtr) == 0
+		|| (statePtr->inputEncodingFlags & TCL_ENCODING_END) == 0);
+
+	code = Tcl_ExternalToUtf(NULL, encoding, src, srcLen,
+		flags, &statePtr->inputEncodingState,
+		dst, dstLimit, &srcRead, &dstDecoded, &numChars);
+
+	/*
+	 * Perform the translation transformation in place.  Read no more
+	 * than the dstDecoded bytes the encoding transformation actually
+	 * produced.  Capture the number of bytes written in dstWrote.
+	 * Capture the number of bytes actually consumed in dstRead.
+	 */
+
+	dstWrote = dstLimit;
+	dstRead = dstDecoded;
+	TranslateInputEOL(statePtr, dst, dst, &dstWrote, &dstRead);
+
+	if (dstRead < dstDecoded) {
+
+	    /*
+	     * The encoding transformation produced bytes that the
+	     * translation transformation did not consume.  Why did
+	     * this happen?
+	     */
+
+	    if (statePtr->inEofChar && dst[dstRead] == statePtr->inEofChar) {
+		/*
+		 * 1) There's an eof char set on the channel, and
+		 *    we saw it and stopped translating at that point.
+		 *
+		 * NOTE the bizarre spec of TranslateInputEOL in this case.
+		 * Clearly the eof char had to be read in order to account
+		 * for the stopping, but the value of dstRead does not
+		 * include it.
+		 *
+		 * Also rather bizarre, our caller can only notice an
+		 * EOF condition if we return the value -1 as the number
+		 * of chars read.  This forces us to perform a 2-call
+		 * dance where the first call can read all the chars
+		 * up to the eof char, and the second call is solely
+		 * for consuming the encoded eof char then pointed at
+		 * by src so that we can return that magic -1 value.
+		 * This seems really wasteful, especially since
+		 * the first decoding pass of each call is likely to
+		 * decode many bytes beyond that eof char that's all we
+		 * care about.
+		 */
+
+		if (dstRead == 0) {
+		    /*
+		     * Curious choice in the eof char handling.  We leave
+		     * the eof char in the buffer.  So, no need to compute
+		     * a proper srcRead value.  At this point, there
+		     * are no chars before the eof char in the buffer.
+		     */
+		    Tcl_SetObjLength(objPtr, numBytes);
+		    return -1;
+		}
+
+		{
+		    /*
+		     * There are chars leading the buffer before the eof
+		     * char.  Adjust the dstLimit so we go back and read
+		     * only those and do not encounter the eof char this
+		     * time.
+		     */
+
+		    dstLimit = dstRead - 1 + TCL_UTF_MAX;
+		    statePtr->flags = savedFlags;
+		    statePtr->inputEncodingFlags = savedIEFlags;
+		    statePtr->inputEncodingState = savedState;
+		    continue;
+		}
+	    }
+
+	    /*
+	     * 2) The other way to read fewer bytes than are decoded
+	     *    is when the final byte is \r and we're in a CRLF
+	     *    translation mode so we cannot decide whether to
+	     *	  record \r or \n yet.
+	     */
+
+	    assert(dst[dstRead] == '\r');
+	    assert(statePtr->inputTranslation == TCL_TRANSLATE_CRLF);
+
+	    if (dstWrote > 0) {
+		/*
+		 * There are chars we can read before we hit the bare cr.
+		 * Go back with a smaller dstLimit so we get them in the
+		 * next pass, compute a matching srcRead, and don't end
+		 * up back here in this call.
+		 */
+
+		dstLimit = dstRead - 1 + TCL_UTF_MAX;
+		statePtr->flags = savedFlags;
+		statePtr->inputEncodingFlags = savedIEFlags;
+		statePtr->inputEncodingState = savedState;
+		continue;
+	    }
+
+	    assert(dstWrote == 0);
+	    assert(dstRead == 0);
+
+	    /*
+	     * We decoded only the bare cr, and we cannot read a
+	     * translated char from that alone.  We have to know what's
+	     * next.  So why do we only have the one decoded char?
+	     */
+
+	    if (code != TCL_OK) {
+		char buffer[TCL_UTF_MAX + 1];
+		int read, decoded, count;
+
+		/*
+		 * Didn't get everything the buffer could offer
+		 */
+
+		statePtr->flags = savedFlags;
+		statePtr->inputEncodingFlags = savedIEFlags;
+		statePtr->inputEncodingState = savedState;
+
+		assert(bufPtr->nextPtr == NULL
+			|| BytesLeft(bufPtr->nextPtr) == 0 || 0 ==
+			(statePtr->inputEncodingFlags & TCL_ENCODING_END));
+
+		Tcl_ExternalToUtf(NULL, encoding, src, srcLen,
+		(statePtr->inputEncodingFlags | TCL_ENCODING_NO_TERMINATE),
+		&statePtr->inputEncodingState, buffer, TCL_UTF_MAX + 1,
+		&read, &decoded, &count);
+
+		if (count == 2) {
+		    if (buffer[1] == '\n') {
+			/* \r\n translate to \n */
+			dst[0] = '\n';
+			bufPtr->nextRemoved += read;
+		    } else {
+			dst[0] = '\r';
+			bufPtr->nextRemoved += srcRead;
+		    }
+
+		    statePtr->inputEncodingFlags &= ~TCL_ENCODING_START;
+
+		    Tcl_SetObjLength(objPtr, numBytes + 1);
+		    return 1;
+		}
+
+	    } else if (statePtr->flags & CHANNEL_EOF) {
+
+		/*
+		 * The bare \r is the only char and we will never read
+		 * a subsequent char to make the determination.
+		 */
+
+		dst[0] = '\r';
+		bufPtr->nextRemoved = bufPtr->nextAdded;
+		Tcl_SetObjLength(objPtr, numBytes + 1);
+		return 1;
+	    }
+
+	    /*
+	     * Revise the dstRead value so that the numChars calc
+	     * below correctly computes zero characters read.
+	     */
+
+	    dstRead = numChars;
+
+	    /* FALL THROUGH - get more data (dstWrote == 0) */
+	}
+
+	/*
+	 * The translation transformation can only reduce the number
+	 * of chars when it converts \r\n into \n.  The reduction in
+	 * the number of chars is the difference in bytes read and written.
+	 */
+
+	numChars -= (dstRead - dstWrote);
+
+	if (charsToRead > 0 && numChars > charsToRead) {
+
+	    /*
+	     * TODO: This cannot happen anymore.
+	     *
+	     * We read more chars than allowed.  Reset limits to
+	     * prevent that and try again.  Don't forget the extra
+	     * padding of TCL_UTF_MAX bytes demanded by the
+	     * Tcl_ExternalToUtf() call!
+	     */
+
+	    dstLimit = Tcl_UtfAtIndex(dst, charsToRead) - 1 + TCL_UTF_MAX - dst;
+	    statePtr->flags = savedFlags;
+	    statePtr->inputEncodingFlags = savedIEFlags;
+	    statePtr->inputEncodingState = savedState;
+	    continue;
+	}
+
+	if (dstWrote == 0) {
+	    ChannelBuffer *nextPtr;
+
+	    /* We were not able to read any chars. */
+
+	    assert (numChars == 0);
+
+	    /*
+	     * There is one situation where this is the correct final
+	     * result.  If the src buffer contains only a single \n
+	     * byte, and we are in TCL_TRANSLATE_AUTO mode, and
+	     * when the translation pass was made the INPUT_SAW_CR
+	     * flag was set on the channel.  In that case, the
+	     * correct behavior is to consume that \n and produce the
+	     * empty string.
+	     */
+
+	    if (dstRead == 1 && dst[0] == '\n') {
+		assert(statePtr->inputTranslation == TCL_TRANSLATE_AUTO);
+
+		goto consume;
+	    }
+
+	    /* Otherwise, reading zero characters indicates there's
+	     * something incomplete at the end of the src buffer.
+	     * Maybe there were not enough src bytes to decode into
+	     * a char.  Maybe a lone \r could not be translated (crlf
+	     * mode).  Need to combine any unused src bytes we have
+	     * in the first buffer with subsequent bytes to try again.
+	     */
+
+	    nextPtr = bufPtr->nextPtr;
+
+	    if (nextPtr == NULL) {
+		if (srcLen > 0) {
+		    SetFlag(statePtr, CHANNEL_NEED_MORE_DATA);
+		}
+		Tcl_SetObjLength(objPtr, numBytes);
+		return -1;
+	    }
+
+	    /*
+	     * Space is made at the beginning of the buffer to copy the
+	     * previous unused bytes there. Check first if the buffer we
+	     * are using actually has enough space at its beginning for
+	     * the data we are copying.  Because if not we will write over
+	     * the buffer management information, especially the 'nextPtr'.
+	     *
+	     * Note that the BUFFER_PADDING (See AllocChannelBuffer) is
+	     * used to prevent exactly this situation. I.e. it should never
+	     * happen.  Therefore it is ok to panic should it happen despite
+	     * the precautions.
+	     */
+
+	    if (nextPtr->nextRemoved - srcLen < 0) {
+		Tcl_Panic("Buffer Underflow, BUFFER_PADDING not enough");
+	    }
+
+	    nextPtr->nextRemoved -= srcLen;
+	    memcpy(RemovePoint(nextPtr), src, (size_t) srcLen);
+	    RecycleBuffer(statePtr, bufPtr, 0);
+	    statePtr->inQueueHead = nextPtr;
+	    Tcl_SetObjLength(objPtr, numBytes);
+	    return ReadChars(statePtr, objPtr, charsToRead, factorPtr);
+	}
+
+	statePtr->inputEncodingFlags &= ~TCL_ENCODING_START;
+
+    consume:
+	bufPtr->nextRemoved += srcRead;
+	/*
+	 * If this read contained multibyte characters, revise factorPtr
+	 * so the next read will allocate bigger buffers.
+	 */
+	if (numChars && numChars < srcRead) {
+	    *factorPtr = srcRead * UTF_EXPANSION_FACTOR / numChars;
+	}
+	Tcl_SetObjLength(objPtr, numBytes + dstWrote);
+	return numChars;
+    }
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * TranslateInputEOL --
+ *
+ *	Perform input EOL and EOF translation on the source buffer, leaving
+ *	the translated result in the destination buffer.
+ *
+ * Results:
+ *	The return value is 1 if the EOF character was found when copying
+ *	bytes to the destination buffer, 0 otherwise.
+ *
+ * Side effects:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+static void
+TranslateInputEOL(
+    ChannelState *statePtr,	/* Channel being read, for EOL translation and
+				 * EOF character. */
+    char *dstStart,		/* Output buffer filled with chars by applying
+				 * appropriate EOL translation to source
+				 * characters. */
+    const char *srcStart,	/* Source characters. */
+    int *dstLenPtr,		/* On entry, the maximum length of output
+				 * buffer in bytes. On exit, the number of
+				 * bytes actually used in output buffer. */
+    int *srcLenPtr)		/* On entry, the length of source buffer. On
+				 * exit, the number of bytes read from the
+				 * source buffer. */
+{
+    const char *eof = NULL;
+    int dstLen = *dstLenPtr;
+    int srcLen = *srcLenPtr;
+    int inEofChar = statePtr->inEofChar;
+
+    /*
+     * Depending on the translation mode in use, there's no need
+     * to scan more srcLen bytes at srcStart than can possibly transform
+     * to dstLen bytes.  This keeps the scan for eof char below from
+     * being pointlessly long.
+     */
+
+    switch (statePtr->inputTranslation) {
+    case TCL_TRANSLATE_LF:
+    case TCL_TRANSLATE_CR:
+	if (srcLen > dstLen) {
+	/* In these modes, each src byte become a dst byte. */
+	    srcLen = dstLen;
+	}
+	break;
+    default:
+	/* In other modes, at most 2 src bytes become a dst byte. */
+	if (srcLen/2 > dstLen) {
+	    srcLen = 2 * dstLen;
+	}
+	break;
+    }
+
+    if (inEofChar != '\0') {
+	/*
+	 * Make sure we do not read past any logical end of channel input
+	 * created by the presence of the input eof char.
+	 */
+
+	if ((eof = memchr(srcStart, inEofChar, srcLen))) {
+	    srcLen = eof - srcStart;
+	}
+    }
+
+    switch (statePtr->inputTranslation) {
+    case TCL_TRANSLATE_LF:
+    case TCL_TRANSLATE_CR:
+	if (dstStart != srcStart) {
+	    memcpy(dstStart, srcStart, (size_t) srcLen);
+	}
+	if (statePtr->inputTranslation == TCL_TRANSLATE_CR) {
+	    char *dst = dstStart;
+	    char *dstEnd = dstStart + srcLen;
+
+	    while ((dst = memchr(dst, '\r', dstEnd - dst))) {
+		*dst++ = '\n';
+	    }
+	}
+	dstLen = srcLen;
+	break;
+    case TCL_TRANSLATE_CRLF: {
+	const char *crFound, *src = srcStart;
+	char *dst = dstStart;
+	int lesser = (dstLen < srcLen) ? dstLen : srcLen;
+
+	while ((crFound = memchr(src, '\r', lesser))) {
+	    int numBytes = crFound - src;
+	    memmove(dst, src, numBytes);
+
+	    dst += numBytes; dstLen -= numBytes;
+	    src += numBytes; srcLen -= numBytes;
+	    if (srcLen == 1) {
+		/* valid src bytes end in \r */
+		if (eof) {
+		    *dst++ = '\r';
+		    src++; srcLen--;
+		} else {
+		    lesser = 0;
+		    break;
+		}
+	    } else if (src[1] == '\n') {
+		*dst++ = '\n';
+		src += 2; srcLen -= 2;
+	    } else {
+		*dst++ = '\r';
+		src++; srcLen--;
+	    }
+	    dstLen--;
+	    lesser = (dstLen < srcLen) ? dstLen : srcLen;
+	}
+	memmove(dst, src, lesser);
+	srcLen = src + lesser - srcStart;
+	dstLen = dst + lesser - dstStart;
+	break;
+    }
+    case TCL_TRANSLATE_AUTO: {
+	const char *crFound, *src = srcStart;
+	char *dst = dstStart;
+	int lesser;
+
+	if ((statePtr->flags & INPUT_SAW_CR) && srcLen) {
+	    if (*src == '\n') { src++; srcLen--; }
+	    ResetFlag(statePtr, INPUT_SAW_CR);
+	}
+	lesser = (dstLen < srcLen) ? dstLen : srcLen;
+	while ((crFound = memchr(src, '\r', lesser))) {
+	    int numBytes = crFound - src;
+	    memmove(dst, src, numBytes);
+
+	    dst[numBytes] = '\n';
+	    dst += numBytes + 1; dstLen -= numBytes + 1;
+	    src += numBytes + 1; srcLen -= numBytes + 1;
+	    if (srcLen == 0) {
+		SetFlag(statePtr, INPUT_SAW_CR);
+	    } else if (*src == '\n') {
+		src++; srcLen--;
+	    }
+	    lesser = (dstLen < srcLen) ? dstLen : srcLen;
+	}
+	memmove(dst, src, lesser);
+	srcLen = src + lesser - srcStart;
+	dstLen = dst + lesser - dstStart;
+	break;
+    }
+    default:
+	Tcl_Panic("unknown input translation %d", statePtr->inputTranslation);
+    }
+    *dstLenPtr = dstLen;
+    *srcLenPtr = srcLen;
+
+    if (srcStart + srcLen == eof) {
+	/*
+	 * EOF character was seen in EOL translated range. Leave current file
+	 * position pointing at the EOF character, but don't store the EOF
+	 * character in the output string.
+	 */
+
+	SetFlag(statePtr, CHANNEL_EOF | CHANNEL_STICKY_EOF);
+	statePtr->inputEncodingFlags |= TCL_ENCODING_END;
+	ResetFlag(statePtr, CHANNEL_BLOCKED|INPUT_SAW_CR);
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_Ungets --
+ *
+ *	Causes the supplied string to be added to the input queue of the
+ *	channel, at either the head or tail of the queue.
+ *
+ * Results:
+ *	The number of bytes stored in the channel, or -1 on error.
+ *
+ * Side effects:
+ *	Adds input to the input queue of a channel.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_Ungets(
+    Tcl_Channel chan,		/* The channel for which to add the input. */
+    const char *str,		/* The input itself. */
+    int len,			/* The length of the input. */
+    int atEnd)			/* If non-zero, add at end of queue; otherwise
+				 * add at head of queue. */
+{
+    Channel *chanPtr;		/* The real IO channel. */
+    ChannelState *statePtr;	/* State of actual channel. */
+    ChannelBuffer *bufPtr;	/* Buffer to contain the data. */
+    int flags;
+
+    chanPtr = (Channel *) chan;
+    statePtr = chanPtr->state;
+
+    /*
+     * This operation should occur at the top of a channel stack.
+     */
+
+    chanPtr = statePtr->topChanPtr;
+
+    /*
+     * CheckChannelErrors clears too many flag bits in this one case.
+     */
+
+    flags = statePtr->flags;
+    if (CheckChannelErrors(statePtr, TCL_READABLE) != 0) {
+	len = -1;
+	goto done;
+    }
+    statePtr->flags = flags;
+
+    /*
+     * Clear the EOF flags, and clear the BLOCKED bit.
+     */
+
+    if (GotFlag(statePtr, CHANNEL_EOF)) {
+	statePtr->inputEncodingFlags |= TCL_ENCODING_START;
+    }
+    ResetFlag(statePtr,
+	    CHANNEL_BLOCKED | CHANNEL_STICKY_EOF | CHANNEL_EOF | INPUT_SAW_CR);
+    statePtr->inputEncodingFlags &= ~TCL_ENCODING_END;
+
+    bufPtr = AllocChannelBuffer(len);
+    memcpy(InsertPoint(bufPtr), str, (size_t) len);
+    bufPtr->nextAdded += len;
+
+    if (statePtr->inQueueHead == NULL) {
+	bufPtr->nextPtr = NULL;
+	statePtr->inQueueHead = bufPtr;
+	statePtr->inQueueTail = bufPtr;
+    } else if (atEnd) {
+	bufPtr->nextPtr = NULL;
+	statePtr->inQueueTail->nextPtr = bufPtr;
+	statePtr->inQueueTail = bufPtr;
+    } else {
+	bufPtr->nextPtr = statePtr->inQueueHead;
+	statePtr->inQueueHead = bufPtr;
+    }
+
+    /*
+     * Update the notifier state so we don't block while there is still data
+     * in the buffers.
+     */
+
+  done:
+    UpdateInterest(chanPtr);
+    return len;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_Flush --
+ *
+ *	Flushes output data on a channel.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	May flush output queued on this channel.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_Flush(
+    Tcl_Channel chan)		/* The Channel to flush. */
+{
+    int result;			/* Of calling FlushChannel. */
+    Channel *chanPtr = (Channel *) chan;
+				/* The actual channel. */
+    ChannelState *statePtr = chanPtr->state;
+				/* State of actual channel. */
+
+    /*
+     * This operation should occur at the top of a channel stack.
+     */
+
+    chanPtr = statePtr->topChanPtr;
+
+    if (CheckChannelErrors(statePtr, TCL_WRITABLE) != 0) {
+	return -1;
+    }
+
+    result = FlushChannel(NULL, chanPtr, 0);
+    if (result != 0) {
+	return TCL_ERROR;
+    }
+
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * DiscardInputQueued --
+ *
+ *	Discards any input read from the channel but not yet consumed by Tcl
+ *	reading commands.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	May discard input from the channel. If discardLastBuffer is zero,
+ *	leaves one buffer in place for back-filling.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+DiscardInputQueued(
+    ChannelState *statePtr,	/* Channel on which to discard the queued
+				 * input. */
+    int discardSavedBuffers)	/* If non-zero, discard all buffers including
+				 * last one. */
+{
+    ChannelBuffer *bufPtr, *nxtPtr;
+				/* Loop variables. */
+
+    bufPtr = statePtr->inQueueHead;
+    statePtr->inQueueHead = NULL;
+    statePtr->inQueueTail = NULL;
+    for (; bufPtr != NULL; bufPtr = nxtPtr) {
+	nxtPtr = bufPtr->nextPtr;
+	RecycleBuffer(statePtr, bufPtr, discardSavedBuffers);
+    }
+
+    /*
+     * If discardSavedBuffers is nonzero, must also discard any previously
+     * saved buffer in the saveInBufPtr field.
+     */
+
+    if (discardSavedBuffers && statePtr->saveInBufPtr != NULL) {
+	ReleaseChannelBuffer(statePtr->saveInBufPtr);
+	statePtr->saveInBufPtr = NULL;
+    }
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * GetInput --
+ *
+ *	Reads input data from a device into a channel buffer.
+ *
+ *	IMPORTANT!  This routine is only called on a chanPtr argument
+ *	that is the top channel of a stack!
+ *
+ * Results:
+ *	The return value is the Posix error code if an error occurred while
+ *	reading from the file, or 0 otherwise.
+ *
+ * Side effects:
+ *	Reads from the underlying device.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+static int
+GetInput(
+    Channel *chanPtr)		/* Channel to read input from. */
+{
+    int toRead;			/* How much to read? */
+    int result;			/* Of calling driver. */
+    int nread;			/* How much was read from channel? */
+    ChannelBuffer *bufPtr;	/* New buffer to add to input queue. */
+    ChannelState *statePtr = chanPtr->state;
+				/* State info for channel */
+
+    /*
+     * Verify that all callers know better than to call us when
+     * it's recorded that the next char waiting to be read is the
+     * eofchar.
+     */
+
+    assert( !GotFlag(statePtr, CHANNEL_STICKY_EOF) );
+
+    /*
+     * Prevent reading from a dead channel -- a channel that has been closed
+     * but not yet deallocated, which can happen if the exit handler for
+     * channel cleanup has run but the channel is still registered in some
+     * interpreter.
+     */
+
+    if (CheckForDeadChannel(NULL, statePtr)) {
+	return EINVAL;
+    }
+
+    /*
+     * WARNING: There was once a comment here claiming that it was
+     * a bad idea to make another call to the inputproc of a channel
+     * driver when EOF has already been detected on the channel.  Through
+     * much of Tcl's history, this warning was then completely negated
+     * by having all (most?) read paths clear the EOF setting before
+     * reaching here.  So we had a guard that was never triggered.
+     *
+     * Don't be tempted to restore the guard.  Even if EOF is set on
+     * the channel, continue through and call the inputproc again.  This
+     * is the way to enable the ability to [read] again beyond the EOF,
+     * which seems a strange thing to do, but for which use cases exist
+     * [Tcl Bug 5adc350683] and which may even be essential for channels
+     * representing things like ttys or other devices where the stream
+     * might take the logical form of a series of 'files' separated by
+     * an EOF condition.
+     */
+
+    /*
+     * First check for more buffers in the pushback area of the topmost
+     * channel in the stack and use them. They can be the result of a
+     * transformation which went away without reading all the information
+     * placed in the area when it was stacked.
+     */
+
+    if (chanPtr->inQueueHead != NULL) {
+
+	/* TODO: Tests to cover this. */
+	assert(statePtr->inQueueHead == NULL);
+
+	statePtr->inQueueHead = chanPtr->inQueueHead;
+	statePtr->inQueueTail = chanPtr->inQueueTail;
+	chanPtr->inQueueHead = NULL;
+	chanPtr->inQueueTail = NULL;
+	return 0;
+    }
+
+    /*
+     * Nothing in the pushback area, fall back to the usual handling (driver,
+     * etc.)
+     */
+
+    /*
+     * See if we can fill an existing buffer. If we can, read only as much as
+     * will fit in it. Otherwise allocate a new buffer, add it to the input
+     * queue and attempt to fill it to the max.
+     */
+
+    bufPtr = statePtr->inQueueTail;
+
+    if ((bufPtr == NULL) || IsBufferFull(bufPtr)) {
+	bufPtr = statePtr->saveInBufPtr;
+	statePtr->saveInBufPtr = NULL;
+
+	/*
+	 * Check the actual buffersize against the requested buffersize.
+	 * Saved buffers of the wrong size are squashed. This is done
+	 * to honor dynamic changes of the buffersize made by the user.
+	 * TODO: Tests to cover this.
+	 */
+
+	if ((bufPtr != NULL)
+		&& (bufPtr->bufLength - BUFFER_PADDING != statePtr->bufSize)) {
+	    ReleaseChannelBuffer(bufPtr);
+	    bufPtr = NULL;
+	}
+
+	if (bufPtr == NULL) {
+	    bufPtr = AllocChannelBuffer(statePtr->bufSize);
+	}
+	bufPtr->nextPtr = NULL;
+
+	toRead = SpaceLeft(bufPtr);
+	assert(toRead == statePtr->bufSize);
+
+	if (statePtr->inQueueTail == NULL) {
+	    statePtr->inQueueHead = bufPtr;
+	} else {
+	    statePtr->inQueueTail->nextPtr = bufPtr;
+	}
+	statePtr->inQueueTail = bufPtr;
+    } else {
+	toRead = SpaceLeft(bufPtr);
+    }
+
+    PreserveChannelBuffer(bufPtr);
+    nread = ChanRead(chanPtr, InsertPoint(bufPtr), toRead);
+
+    if (nread < 0) {
+	result = Tcl_GetErrno();
+    } else {
+	result = 0;
+	bufPtr->nextAdded += nread;
+    }
+
+    ReleaseChannelBuffer(bufPtr);
+    return result;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_Seek --
+ *
+ *	Implements seeking on Tcl Channels. This is a public function so that
+ *	other C facilities may be implemented on top of it.
+ *
+ * Results:
+ *	The new access point or -1 on error. If error, use Tcl_GetErrno() to
+ *	retrieve the POSIX error code for the error that occurred.
+ *
+ * Side effects:
+ *	May flush output on the channel. May discard queued input.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_WideInt
+Tcl_Seek(
+    Tcl_Channel chan,		/* The channel on which to seek. */
+    Tcl_WideInt offset,		/* Offset to seek to. */
+    int mode)			/* Relative to which location to seek? */
+{
+    Channel *chanPtr = (Channel *) chan;
+				/* The real IO channel. */
+    ChannelState *statePtr = chanPtr->state;
+				/* State info for channel */
+    int inputBuffered, outputBuffered;
+				/* # bytes held in buffers. */
+    int result;			/* Of device driver operations. */
+    Tcl_WideInt curPos;		/* Position on the device. */
+    int wasAsync;		/* Was the channel nonblocking before the seek
+				 * operation? If so, must restore to
+				 * non-blocking mode after the seek. */
+
+    if (CheckChannelErrors(statePtr, TCL_WRITABLE | TCL_READABLE) != 0) {
+	return Tcl_LongAsWide(-1);
+    }
+
+    /*
+     * Disallow seek on dead channels - channels that have been closed but not
+     * yet been deallocated. Such channels can be found if the exit handler
+     * for channel cleanup has run but the channel is still registered in an
+     * interpreter.
+     */
+
+    if (CheckForDeadChannel(NULL, statePtr)) {
+	return Tcl_LongAsWide(-1);
+    }
+
+    /*
+     * This operation should occur at the top of a channel stack.
+     */
+
+    chanPtr = statePtr->topChanPtr;
+
+    /*
+     * Disallow seek on channels whose type does not have a seek procedure
+     * defined. This means that the channel does not support seeking.
+     */
+
+    if (chanPtr->typePtr->seekProc == NULL) {
+	Tcl_SetErrno(EINVAL);
+	return Tcl_LongAsWide(-1);
+    }
+
+    /*
+     * Compute how much input and output is buffered. If both input and output
+     * is buffered, cannot compute the current position.
+     */
+
+    inputBuffered = Tcl_InputBuffered(chan);
+    outputBuffered = Tcl_OutputBuffered(chan);
+
+    if ((inputBuffered != 0) && (outputBuffered != 0)) {
+	Tcl_SetErrno(EFAULT);
+	return Tcl_LongAsWide(-1);
+    }
+
+    /*
+     * If we are seeking relative to the current position, compute the
+     * corrected offset taking into account the amount of unread input.
+     */
+
+    if (mode == SEEK_CUR) {
+	offset -= inputBuffered;
+    }
+
+    /*
+     * Discard any queued input - this input should not be read after the
+     * seek.
+     */
+
+    DiscardInputQueued(statePtr, 0);
+
+    /*
+     * Reset EOF and BLOCKED flags. We invalidate them by moving the access
+     * point. Also clear CR related flags.
+     */
+
+    if (GotFlag(statePtr, CHANNEL_EOF)) {
+	statePtr->inputEncodingFlags |= TCL_ENCODING_START;
+    }
+    ResetFlag(statePtr, CHANNEL_EOF | CHANNEL_STICKY_EOF | CHANNEL_BLOCKED |
+	    INPUT_SAW_CR);
+    statePtr->inputEncodingFlags &= ~TCL_ENCODING_END;
+
+    /*
+     * If the channel is in asynchronous output mode, switch it back to
+     * synchronous mode and cancel any async flush that may be scheduled.
+     * After the flush, the channel will be put back into asynchronous output
+     * mode.
+     */
+
+    wasAsync = 0;
+    if (GotFlag(statePtr, CHANNEL_NONBLOCKING)) {
+	wasAsync = 1;
+	result = StackSetBlockMode(chanPtr, TCL_MODE_BLOCKING);
+	if (result != 0) {
+	    return Tcl_LongAsWide(-1);
+	}
+	ResetFlag(statePtr, CHANNEL_NONBLOCKING);
+	if (GotFlag(statePtr, BG_FLUSH_SCHEDULED)) {
+	    ResetFlag(statePtr, BG_FLUSH_SCHEDULED);
+	}
+    }
+
+    /*
+     * If the flush fails we cannot recover the original position. In that
+     * case the seek is not attempted because we do not know where the access
+     * position is - instead we return the error. FlushChannel has already
+     * called Tcl_SetErrno() to report the error upwards. If the flush
+     * succeeds we do the seek also.
+     */
+
+    if (FlushChannel(NULL, chanPtr, 0) != 0) {
+	curPos = -1;
+    } else {
+	/*
+	 * Now seek to the new position in the channel as requested by the
+	 * caller.
+	 */
+
+	curPos = ChanSeek(chanPtr, offset, mode, &result);
+	if (curPos == Tcl_LongAsWide(-1)) {
+	    Tcl_SetErrno(result);
+	}
+    }
+
+    /*
+     * Restore to nonblocking mode if that was the previous behavior.
+     *
+     * NOTE: Even if there was an async flush active we do not restore it now
+     * because we already flushed all the queued output, above.
+     */
+
+    if (wasAsync) {
+	SetFlag(statePtr, CHANNEL_NONBLOCKING);
+	result = StackSetBlockMode(chanPtr, TCL_MODE_NONBLOCKING);
+	if (result != 0) {
+	    return Tcl_LongAsWide(-1);
+	}
+    }
+
+    return curPos;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_Tell --
+ *
+ *	Returns the position of the next character to be read/written on this
+ *	channel.
+ *
+ * Results:
+ *	A nonnegative integer on success, -1 on failure. If failed, use
+ *	Tcl_GetErrno() to retrieve the POSIX error code for the error that
+ *	occurred.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_WideInt
+Tcl_Tell(
+    Tcl_Channel chan)		/* The channel to return pos for. */
+{
+    Channel *chanPtr = (Channel *) chan;
+				/* The real IO channel. */
+    ChannelState *statePtr = chanPtr->state;
+				/* State info for channel */
+    int inputBuffered, outputBuffered;
+				/* # bytes held in buffers. */
+    int result;			/* Of calling device driver. */
+    Tcl_WideInt curPos;		/* Position on device. */
+
+    if (CheckChannelErrors(statePtr, TCL_WRITABLE | TCL_READABLE) != 0) {
+	return Tcl_LongAsWide(-1);
+    }
+
+    /*
+     * Disallow tell on dead channels -- channels that have been closed but
+     * not yet been deallocated. Such channels can be found if the exit
+     * handler for channel cleanup has run but the channel is still registered
+     * in an interpreter.
+     */
+
+    if (CheckForDeadChannel(NULL, statePtr)) {
+	return Tcl_LongAsWide(-1);
+    }
+
+    /*
+     * This operation should occur at the top of a channel stack.
+     */
+
+    chanPtr = statePtr->topChanPtr;
+
+    /*
+     * Disallow tell on channels whose type does not have a seek procedure
+     * defined. This means that the channel does not support seeking.
+     */
+
+    if (chanPtr->typePtr->seekProc == NULL) {
+	Tcl_SetErrno(EINVAL);
+	return Tcl_LongAsWide(-1);
+    }
+
+    /*
+     * Compute how much input and output is buffered. If both input and output
+     * is buffered, cannot compute the current position.
+     */
+
+    inputBuffered = Tcl_InputBuffered(chan);
+    outputBuffered = Tcl_OutputBuffered(chan);
+
+    /*
+     * Get the current position in the device and compute the position where
+     * the next character will be read or written. Note that we prefer the
+     * wideSeekProc if that is available and non-NULL...
+     */
+
+    curPos = ChanSeek(chanPtr, Tcl_LongAsWide(0), SEEK_CUR, &result);
+    if (curPos == Tcl_LongAsWide(-1)) {
+	Tcl_SetErrno(result);
+	return Tcl_LongAsWide(-1);
+    }
+
+    if (inputBuffered != 0) {
+	return curPos - inputBuffered;
+    }
+    return curPos + outputBuffered;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Tcl_SeekOld, Tcl_TellOld --
+ *
+ *	Backward-compatability versions of the seek/tell interface that do not
+ *	support 64-bit offsets. This interface is not documented or expected
+ *	to be supported indefinitely.
+ *
+ * Results:
+ *	As for Tcl_Seek and Tcl_Tell respectively, except truncated to
+ *	whatever value will fit in an 'int'.
+ *
+ * Side effects:
+ *	As for Tcl_Seek and Tcl_Tell respectively.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+int
+Tcl_SeekOld(
+    Tcl_Channel chan,		/* The channel on which to seek. */
+    int offset,			/* Offset to seek to. */
+    int mode)			/* Relative to which location to seek? */
+{
+    Tcl_WideInt wOffset, wResult;
+
+    wOffset = Tcl_LongAsWide((long) offset);
+    wResult = Tcl_Seek(chan, wOffset, mode);
+    return (int) Tcl_WideAsLong(wResult);
+}
+
+int
+Tcl_TellOld(
+    Tcl_Channel chan)		/* The channel to return pos for. */
+{
+    Tcl_WideInt wResult = Tcl_Tell(chan);
+
+    return (int) Tcl_WideAsLong(wResult);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Tcl_TruncateChannel --
+ *
+ *	Truncate a channel to the given length.
+ *
+ * Results:
+ *	TCL_OK on success, TCL_ERROR if the operation failed (e.g. is not
+ *	supported by the type of channel, or the underlying OS operation
+ *	failed in some way).
+ *
+ * Side effects:
+ *	Seeks the channel to the current location. Sets errno on OS error.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+int
+Tcl_TruncateChannel(
+    Tcl_Channel chan,		/* Channel to truncate. */
+    Tcl_WideInt length)		/* Length to truncate it to. */
+{
+    Channel *chanPtr = (Channel *) chan;
+    Tcl_DriverTruncateProc *truncateProc =
+	    Tcl_ChannelTruncateProc(chanPtr->typePtr);
+    int result;
+
+    if (truncateProc == NULL) {
+	/*
+	 * Feature not supported and it's not emulatable. Pretend it's
+	 * returned an EINVAL, a very generic error!
+	 */
+
+	Tcl_SetErrno(EINVAL);
+	return TCL_ERROR;
+    }
+
+    if (!GotFlag(chanPtr->state, TCL_WRITABLE)) {
+	/*
+	 * We require that the file was opened of writing. Do that check now
+	 * so that we only flush if we think we're going to succeed.
+	 */
+
+	Tcl_SetErrno(EINVAL);
+	return TCL_ERROR;
+    }
+
+    /*
+     * Seek first to force a total flush of all pending buffers and ditch any
+     * pre-read input data.
+     */
+
+    WillWrite(chanPtr);
+
+    if (WillRead(chanPtr) < 0) {
+        return TCL_ERROR;
+    }
+
+    /*
+     * We're all flushed to disk now and we also don't have any unfortunate
+     * input baggage around either; can truncate with impunity.
+     */
+
+    result = truncateProc(chanPtr->instanceData, length);
+    if (result != 0) {
+	Tcl_SetErrno(result);
+	return TCL_ERROR;
+    }
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * CheckChannelErrors --
+ *
+ *	See if the channel is in an ready state and can perform the desired
+ *	operation.
+ *
+ * Results:
+ *	The return value is 0 if the channel is OK, otherwise the return value
+ *	is -1 and errno is set to indicate the error.
+ *
+ * Side effects:
+ *	May clear the EOF and/or BLOCKED bits if reading from channel.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+static int
+CheckChannelErrors(
+    ChannelState *statePtr,	/* Channel to check. */
+    int flags)			/* Test if channel supports desired operation:
+				 * TCL_READABLE, TCL_WRITABLE. Also indicates
+				 * Raw read or write for special close
+				 * processing */
+{
+    int direction = flags & (TCL_READABLE|TCL_WRITABLE);
+
+    /*
+     * Check for unreported error.
+     */
+
+    if (statePtr->unreportedError != 0) {
+	Tcl_SetErrno(statePtr->unreportedError);
+	statePtr->unreportedError = 0;
+
+	/*
+	 * TIP #219, Tcl Channel Reflection API.
+	 * Move a defered error message back into the channel bypass.
+	 */
+
+	if (statePtr->chanMsg != NULL) {
+	    TclDecrRefCount(statePtr->chanMsg);
+	}
+	statePtr->chanMsg = statePtr->unreportedMsg;
+	statePtr->unreportedMsg = NULL;
+	return -1;
+    }
+
+    /*
+     * Only the raw read and write operations are allowed during close in
+     * order to drain data from stacked channels.
+     */
+
+    if (GotFlag(statePtr, CHANNEL_CLOSED) && !(flags & CHANNEL_RAW_MODE)) {
+	Tcl_SetErrno(EACCES);
+	return -1;
+    }
+
+    /*
+     * Fail if the channel is not opened for desired operation.
+     */
+
+    if ((statePtr->flags & direction) == 0) {
+	Tcl_SetErrno(EACCES);
+	return -1;
+    }
+
+    /*
+     * Fail if the channel is in the middle of a background copy.
+     *
+     * Don't do this tests for raw channels here or else the chaining in the
+     * transformation drivers will fail with 'file busy' error instead of
+     * retrieving and transforming the data to copy.
+     */
+
+    if (BUSY_STATE(statePtr, flags) && ((flags & CHANNEL_RAW_MODE) == 0)) {
+	Tcl_SetErrno(EBUSY);
+	return -1;
+    }
+
+    if (direction == TCL_READABLE) {
+	ResetFlag(statePtr, CHANNEL_NEED_MORE_DATA);
+    }
+
+    return 0;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_Eof --
+ *
+ *	Returns 1 if the channel is at EOF, 0 otherwise.
+ *
+ * Results:
+ *	1 or 0, always.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_Eof(
+    Tcl_Channel chan)		/* Does this channel have EOF? */
+{
+    ChannelState *statePtr = ((Channel *) chan)->state;
+				/* State of real channel structure. */
+
+    return GotFlag(statePtr, CHANNEL_EOF) ? 1 : 0;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_InputBlocked --
+ *
+ *	Returns 1 if input is blocked on this channel, 0 otherwise.
+ *
+ * Results:
+ *	0 or 1, always.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_InputBlocked(
+    Tcl_Channel chan)		/* Is this channel blocked? */
+{
+    ChannelState *statePtr = ((Channel *) chan)->state;
+				/* State of real channel structure. */
+
+    return GotFlag(statePtr, CHANNEL_BLOCKED) ? 1 : 0;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_InputBuffered --
+ *
+ *	Returns the number of bytes of input currently buffered in the common
+ *	internal buffer of a channel.
+ *
+ * Results:
+ *	The number of input bytes buffered, or zero if the channel is not open
+ *	for reading.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_InputBuffered(
+    Tcl_Channel chan)		/* The channel to query. */
+{
+    ChannelState *statePtr = ((Channel *) chan)->state;
+				/* State of real channel structure. */
+    ChannelBuffer *bufPtr;
+    int bytesBuffered;
+
+    for (bytesBuffered = 0, bufPtr = statePtr->inQueueHead; bufPtr != NULL;
+	    bufPtr = bufPtr->nextPtr) {
+	bytesBuffered += BytesLeft(bufPtr);
+    }
+
+    /*
+     * Don't forget the bytes in the topmost pushback area.
+     */
+
+    for (bufPtr = statePtr->topChanPtr->inQueueHead; bufPtr != NULL;
+	    bufPtr = bufPtr->nextPtr) {
+	bytesBuffered += BytesLeft(bufPtr);
+    }
+
+    return bytesBuffered;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_OutputBuffered --
+ *
+ *    Returns the number of bytes of output currently buffered in the common
+ *    internal buffer of a channel.
+ *
+ * Results:
+ *    The number of output bytes buffered, or zero if the channel is not open
+ *    for writing.
+ *
+ * Side effects:
+ *    None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_OutputBuffered(
+    Tcl_Channel chan)		/* The channel to query. */
+{
+    ChannelState *statePtr = ((Channel *) chan)->state;
+				/* State of real channel structure. */
+    ChannelBuffer *bufPtr;
+    int bytesBuffered;
+
+    for (bytesBuffered = 0, bufPtr = statePtr->outQueueHead; bufPtr != NULL;
+	    bufPtr = bufPtr->nextPtr) {
+	bytesBuffered += BytesLeft(bufPtr);
+    }
+    if (statePtr->curOutPtr != NULL) {
+	register ChannelBuffer *curOutPtr = statePtr->curOutPtr;
+
+	if (IsBufferReady(curOutPtr)) {
+	    bytesBuffered += BytesLeft(curOutPtr);
+	}
+    }
+
+    return bytesBuffered;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_ChannelBuffered --
+ *
+ *	Returns the number of bytes of input currently buffered in the
+ *	internal buffer (push back area) of a channel.
+ *
+ * Results:
+ *	The number of input bytes buffered, or zero if the channel is not open
+ *	for reading.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_ChannelBuffered(
+    Tcl_Channel chan)		/* The channel to query. */
+{
+    Channel *chanPtr = (Channel *) chan;
+				/* Real channel structure. */
+    ChannelBuffer *bufPtr;
+    int bytesBuffered = 0;
+
+    for (bufPtr = chanPtr->inQueueHead; bufPtr != NULL;
+	    bufPtr = bufPtr->nextPtr) {
+	bytesBuffered += BytesLeft(bufPtr);
+    }
+
+    return bytesBuffered;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_SetChannelBufferSize --
+ *
+ *	Sets the size of buffers to allocate to store input or output in the
+ *	channel. The size must be between 1 byte and 1 MByte.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Sets the size of buffers subsequently allocated for this channel.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_SetChannelBufferSize(
+    Tcl_Channel chan,		/* The channel whose buffer size to set. */
+    int sz)			/* The size to set. */
+{
+    ChannelState *statePtr;	/* State of real channel structure. */
+
+    /*
+     * Clip the buffer size to force it into the [1,1M] range
+     */
+
+    if (sz < 1) {
+	sz = 1;
+    } else if (sz > MAX_CHANNEL_BUFFER_SIZE) {
+	sz = MAX_CHANNEL_BUFFER_SIZE;
+    }
+
+    statePtr = ((Channel *) chan)->state;
+
+    if (statePtr->bufSize == sz) {
+	return;
+    }
+    statePtr->bufSize = sz;
+
+    /*
+     * If bufsize changes, need to get rid of old utility buffer.
+     */
+
+    if (statePtr->saveInBufPtr != NULL) {
+	RecycleBuffer(statePtr, statePtr->saveInBufPtr, 1);
+	statePtr->saveInBufPtr = NULL;
+    }
+    if ((statePtr->inQueueHead != NULL)
+	    && (statePtr->inQueueHead->nextPtr == NULL)
+	    && IsBufferEmpty(statePtr->inQueueHead)) {
+	RecycleBuffer(statePtr, statePtr->inQueueHead, 1);
+	statePtr->inQueueHead = NULL;
+	statePtr->inQueueTail = NULL;
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_GetChannelBufferSize --
+ *
+ *	Retrieves the size of buffers to allocate for this channel.
+ *
+ * Results:
+ *	The size.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_GetChannelBufferSize(
+    Tcl_Channel chan)		/* The channel for which to find the buffer
+				 * size. */
+{
+    ChannelState *statePtr = ((Channel *) chan)->state;
+				/* State of real channel structure. */
+
+    return statePtr->bufSize;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_BadChannelOption --
+ *
+ *	This procedure generates a "bad option" error message in an (optional)
+ *	interpreter. It is used by channel drivers when a invalid Set/Get
+ *	option is requested. Its purpose is to concatenate the generic options
+ *	list to the specific ones and factorize the generic options error
+ *	message string.
+ *
+ * Results:
+ *	TCL_ERROR.
+ *
+ * Side effects:
+
+ *	An error message is generated in interp's result object to indicate
+ *	that a command was invoked with the a bad option. The message has the
+ *	form:
+ *		bad option "blah": should be one of
+ *		<...generic options...>+<...specific options...>
+ *	"blah" is the optionName argument and "<specific options>" is a space
+ *	separated list of specific option words. The function takes good care
+ *	of inserting minus signs before each option, commas after, and an "or"
+ *	before the last option.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_BadChannelOption(
+    Tcl_Interp *interp,		/* Current interpreter (can be NULL).*/
+    const char *optionName,	/* 'bad option' name */
+    const char *optionList)	/* Specific options list to append to the
+				 * standard generic options. Can be NULL for
+				 * generic options only. */
+{
+    if (interp != NULL) {
+	const char *genericopt =
+		"blocking buffering buffersize encoding eofchar translation";
+	const char **argv;
+	int argc, i;
+	Tcl_DString ds;
+        Tcl_Obj *errObj;
+
+	Tcl_DStringInit(&ds);
+	Tcl_DStringAppend(&ds, genericopt, -1);
+	if (optionList && (*optionList)) {
+	    TclDStringAppendLiteral(&ds, " ");
+	    Tcl_DStringAppend(&ds, optionList, -1);
+	}
+	if (Tcl_SplitList(interp, Tcl_DStringValue(&ds),
+		&argc, &argv) != TCL_OK) {
+	    Tcl_Panic("malformed option list in channel driver");
+	}
+	Tcl_ResetResult(interp);
+	errObj = Tcl_ObjPrintf("bad option \"%s\": should be one of ",
+                optionName);
+	argc--;
+	for (i = 0; i < argc; i++) {
+	    Tcl_AppendPrintfToObj(errObj, "-%s, ", argv[i]);
+	}
+	Tcl_AppendPrintfToObj(errObj, "or -%s", argv[i]);
+        Tcl_SetObjResult(interp, errObj);
+	Tcl_DStringFree(&ds);
+	ckfree(argv);
+    }
+    Tcl_SetErrno(EINVAL);
+    return TCL_ERROR;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_GetChannelOption --
+ *
+ *	Gets a mode associated with an IO channel. If the optionName arg is
+ *	non NULL, retrieves the value of that option. If the optionName arg is
+ *	NULL, retrieves a list of alternating option names and values for the
+ *	given channel.
+ *
+ * Results:
+ *	A standard Tcl result. Also sets the supplied DString to the string
+ *	value of the option(s) returned.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_GetChannelOption(
+    Tcl_Interp *interp,		/* For error reporting - can be NULL. */
+    Tcl_Channel chan,		/* Channel on which to get option. */
+    const char *optionName,	/* Option to get. */
+    Tcl_DString *dsPtr)		/* Where to store value(s). */
+{
+    size_t len;			/* Length of optionName string. */
+    char optionVal[128];	/* Buffer for sprintf. */
+    Channel *chanPtr = (Channel *) chan;
+    ChannelState *statePtr = chanPtr->state;
+				/* State info for channel */
+    int flags;
+
+    /*
+     * Disallow options on dead channels -- channels that have been closed but
+     * not yet been deallocated. Such channels can be found if the exit
+     * handler for channel cleanup has run but the channel is still registered
+     * in an interpreter.
+     */
+
+    if (CheckForDeadChannel(interp, statePtr)) {
+	return TCL_ERROR;
+    }
+
+    /*
+     * This operation should occur at the top of a channel stack.
+     */
+
+    chanPtr = statePtr->topChanPtr;
+
+    /*
+     * If we are in the middle of a background copy, use the saved flags.
+     */
+
+    if (statePtr->csPtrR) {
+	flags = statePtr->csPtrR->readFlags;
+    } else if (statePtr->csPtrW) {
+	flags = statePtr->csPtrW->writeFlags;
+    } else {
+	flags = statePtr->flags;
+    }
+
+    /*
+     * If the optionName is NULL it means that we want a list of all options
+     * and values.
+     */
+
+    if (optionName == NULL) {
+	len = 0;
+    } else {
+	len = strlen(optionName);
+    }
+
+    if (len == 0 || HaveOpt(2, "-blocking")) {
+	if (len == 0) {
+	    Tcl_DStringAppendElement(dsPtr, "-blocking");
+	}
+	Tcl_DStringAppendElement(dsPtr,
+		(flags & CHANNEL_NONBLOCKING) ? "0" : "1");
+	if (len > 0) {
+	    return TCL_OK;
+	}
+    }
+    if (len == 0 || HaveOpt(7, "-buffering")) {
+	if (len == 0) {
+	    Tcl_DStringAppendElement(dsPtr, "-buffering");
+	}
+	if (flags & CHANNEL_LINEBUFFERED) {
+	    Tcl_DStringAppendElement(dsPtr, "line");
+	} else if (flags & CHANNEL_UNBUFFERED) {
+	    Tcl_DStringAppendElement(dsPtr, "none");
+	} else {
+	    Tcl_DStringAppendElement(dsPtr, "full");
+	}
+	if (len > 0) {
+	    return TCL_OK;
+	}
+    }
+    if (len == 0 || HaveOpt(7, "-buffersize")) {
+	if (len == 0) {
+	    Tcl_DStringAppendElement(dsPtr, "-buffersize");
+	}
+	TclFormatInt(optionVal, statePtr->bufSize);
+	Tcl_DStringAppendElement(dsPtr, optionVal);
+	if (len > 0) {
+	    return TCL_OK;
+	}
+    }
+    if (len == 0 || HaveOpt(2, "-encoding")) {
+	if (len == 0) {
+	    Tcl_DStringAppendElement(dsPtr, "-encoding");
+	}
+	if (statePtr->encoding == NULL) {
+	    Tcl_DStringAppendElement(dsPtr, "binary");
+	} else {
+	    Tcl_DStringAppendElement(dsPtr,
+		    Tcl_GetEncodingName(statePtr->encoding));
+	}
+	if (len > 0) {
+	    return TCL_OK;
+	}
+    }
+    if (len == 0 || HaveOpt(2, "-eofchar")) {
+	if (len == 0) {
+	    Tcl_DStringAppendElement(dsPtr, "-eofchar");
+	}
+	if (((flags & (TCL_READABLE|TCL_WRITABLE)) ==
+		(TCL_READABLE|TCL_WRITABLE)) && (len == 0)) {
+	    Tcl_DStringStartSublist(dsPtr);
+	}
+	if (flags & TCL_READABLE) {
+	    if (statePtr->inEofChar == 0) {
+		Tcl_DStringAppendElement(dsPtr, "");
+	    } else {
+		char buf[4];
+
+		sprintf(buf, "%c", statePtr->inEofChar);
+		Tcl_DStringAppendElement(dsPtr, buf);
+	    }
+	}
+	if (flags & TCL_WRITABLE) {
+	    if (statePtr->outEofChar == 0) {
+		Tcl_DStringAppendElement(dsPtr, "");
+	    } else {
+		char buf[4];
+
+		sprintf(buf, "%c", statePtr->outEofChar);
+		Tcl_DStringAppendElement(dsPtr, buf);
+	    }
+	}
+	if (!(flags & (TCL_READABLE|TCL_WRITABLE))) {
+	    /*
+	     * Not readable or writable (e.g. server socket)
+	     */
+
+	    Tcl_DStringAppendElement(dsPtr, "");
+	}
+	if (((flags & (TCL_READABLE|TCL_WRITABLE)) ==
+		(TCL_READABLE|TCL_WRITABLE)) && (len == 0)) {
+	    Tcl_DStringEndSublist(dsPtr);
+	}
+	if (len > 0) {
+	    return TCL_OK;
+	}
+    }
+    if (len == 0 || HaveOpt(1, "-translation")) {
+	if (len == 0) {
+	    Tcl_DStringAppendElement(dsPtr, "-translation");
+	}
+	if (((flags & (TCL_READABLE|TCL_WRITABLE)) ==
+		(TCL_READABLE|TCL_WRITABLE)) && (len == 0)) {
+	    Tcl_DStringStartSublist(dsPtr);
+	}
+	if (flags & TCL_READABLE) {
+	    if (statePtr->inputTranslation == TCL_TRANSLATE_AUTO) {
+		Tcl_DStringAppendElement(dsPtr, "auto");
+	    } else if (statePtr->inputTranslation == TCL_TRANSLATE_CR) {
+		Tcl_DStringAppendElement(dsPtr, "cr");
+	    } else if (statePtr->inputTranslation == TCL_TRANSLATE_CRLF) {
+		Tcl_DStringAppendElement(dsPtr, "crlf");
+	    } else {
+		Tcl_DStringAppendElement(dsPtr, "lf");
+	    }
+	}
+	if (flags & TCL_WRITABLE) {
+	    if (statePtr->outputTranslation == TCL_TRANSLATE_AUTO) {
+		Tcl_DStringAppendElement(dsPtr, "auto");
+	    } else if (statePtr->outputTranslation == TCL_TRANSLATE_CR) {
+		Tcl_DStringAppendElement(dsPtr, "cr");
+	    } else if (statePtr->outputTranslation == TCL_TRANSLATE_CRLF) {
+		Tcl_DStringAppendElement(dsPtr, "crlf");
+	    } else {
+		Tcl_DStringAppendElement(dsPtr, "lf");
+	    }
+	}
+	if (!(flags & (TCL_READABLE|TCL_WRITABLE))) {
+	    /*
+	     * Not readable or writable (e.g. server socket)
+	     */
+
+	    Tcl_DStringAppendElement(dsPtr, "auto");
+	}
+	if (((flags & (TCL_READABLE|TCL_WRITABLE)) ==
+		(TCL_READABLE|TCL_WRITABLE)) && (len == 0)) {
+	    Tcl_DStringEndSublist(dsPtr);
+	}
+	if (len > 0) {
+	    return TCL_OK;
+	}
+    }
+
+    if (chanPtr->typePtr->getOptionProc != NULL) {
+	/*
+	 * Let the driver specific handle additional options and result code
+	 * and message.
+	 */
+
+	return chanPtr->typePtr->getOptionProc(chanPtr->instanceData, interp,
+		optionName, dsPtr);
+    } else {
+	/*
+	 * No driver specific options case.
+	 */
+
+	if (len == 0) {
+	    return TCL_OK;
+	}
+	return Tcl_BadChannelOption(interp, optionName, NULL);
+    }
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Tcl_SetChannelOption --
+ *
+ *	Sets an option on a channel.
+ *
+ * Results:
+ *	A standard Tcl result. On error, sets interp's result object if
+ *	interp is not NULL.
+ *
+ * Side effects:
+ *	May modify an option on a device.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+int
+Tcl_SetChannelOption(
+    Tcl_Interp *interp,		/* For error reporting - can be NULL. */
+    Tcl_Channel chan,		/* Channel on which to set mode. */
+    const char *optionName,	/* Which option to set? */
+    const char *newValue)	/* New value for option. */
+{
+    Channel *chanPtr = (Channel *) chan;
+				/* The real IO channel. */
+    ChannelState *statePtr = chanPtr->state;
+				/* State info for channel */
+    size_t len;			/* Length of optionName string. */
+    int argc;
+    const char **argv;
+
+    /*
+     * If the channel is in the middle of a background copy, fail.
+     */
+
+    if (statePtr->csPtrR || statePtr->csPtrW) {
+	if (interp) {
+	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
+                    "unable to set channel options: background copy in"
+                    " progress", -1));
+	}
+	return TCL_ERROR;
+    }
+
+    /*
+     * Disallow options on dead channels -- channels that have been closed but
+     * not yet been deallocated. Such channels can be found if the exit
+     * handler for channel cleanup has run but the channel is still registered
+     * in an interpreter.
+     */
+
+    if (CheckForDeadChannel(NULL, statePtr)) {
+	return TCL_ERROR;
+    }
+
+    /*
+     * This operation should occur at the top of a channel stack.
+     */
+
+    chanPtr = statePtr->topChanPtr;
+
+    len = strlen(optionName);
+
+    if (HaveOpt(2, "-blocking")) {
+	int newMode;
+
+	if (Tcl_GetBoolean(interp, newValue, &newMode) == TCL_ERROR) {
+	    return TCL_ERROR;
+	}
+	if (newMode) {
+	    newMode = TCL_MODE_BLOCKING;
+	} else {
+	    newMode = TCL_MODE_NONBLOCKING;
+	}
+	return SetBlockMode(interp, chanPtr, newMode);
+    } else if (HaveOpt(7, "-buffering")) {
+	len = strlen(newValue);
+	if ((newValue[0] == 'f') && (strncmp(newValue, "full", len) == 0)) {
+	    ResetFlag(statePtr, CHANNEL_UNBUFFERED | CHANNEL_LINEBUFFERED);
+	} else if ((newValue[0] == 'l') &&
+		(strncmp(newValue, "line", len) == 0)) {
+	    ResetFlag(statePtr, CHANNEL_UNBUFFERED);
+	    SetFlag(statePtr, CHANNEL_LINEBUFFERED);
+	} else if ((newValue[0] == 'n') &&
+		(strncmp(newValue, "none", len) == 0)) {
+	    ResetFlag(statePtr, CHANNEL_LINEBUFFERED);
+	    SetFlag(statePtr, CHANNEL_UNBUFFERED);
+	} else if (interp) {
+            Tcl_SetObjResult(interp, Tcl_NewStringObj(
+                    "bad value for -buffering: must be one of"
+                    " full, line, or none", -1));
+            return TCL_ERROR;
+	}
+	return TCL_OK;
+    } else if (HaveOpt(7, "-buffersize")) {
+	int newBufferSize;
+
+	if (Tcl_GetInt(interp, newValue, &newBufferSize) == TCL_ERROR) {
+	    return TCL_ERROR;
+	}
+	Tcl_SetChannelBufferSize(chan, newBufferSize);
+	return TCL_OK;
+    } else if (HaveOpt(2, "-encoding")) {
+	Tcl_Encoding encoding;
+
+	if ((newValue[0] == '\0') || (strcmp(newValue, "binary") == 0)) {
+	    encoding = NULL;
+	} else {
+	    encoding = Tcl_GetEncoding(interp, newValue);
+	    if (encoding == NULL) {
+		return TCL_ERROR;
+	    }
+	}
+
+	/*
+	 * When the channel has an escape sequence driven encoding such as
+	 * iso2022, the terminated escape sequence must write to the buffer.
+	 */
+
+	if ((statePtr->encoding != NULL)
+		&& !(statePtr->outputEncodingFlags & TCL_ENCODING_START)
+		&& (CheckChannelErrors(statePtr, TCL_WRITABLE) == 0)) {
+	    statePtr->outputEncodingFlags |= TCL_ENCODING_END;
+	    WriteChars(chanPtr, "", 0);
+	}
+	Tcl_FreeEncoding(statePtr->encoding);
+	statePtr->encoding = encoding;
+	statePtr->inputEncodingState = NULL;
+	statePtr->inputEncodingFlags = TCL_ENCODING_START;
+	statePtr->outputEncodingState = NULL;
+	statePtr->outputEncodingFlags = TCL_ENCODING_START;
+	ResetFlag(statePtr, CHANNEL_NEED_MORE_DATA);
+	UpdateInterest(chanPtr);
+	return TCL_OK;
+    } else if (HaveOpt(2, "-eofchar")) {
+	if (Tcl_SplitList(interp, newValue, &argc, &argv) == TCL_ERROR) {
+	    return TCL_ERROR;
+	}
+	if (argc == 0) {
+	    statePtr->inEofChar = 0;
+	    statePtr->outEofChar = 0;
+	} else if (argc == 1 || argc == 2) {
+	    int outIndex = (argc - 1);
+	    int inValue = (int) argv[0][0];
+	    int outValue = (int) argv[outIndex][0];
+
+	    if (inValue & 0x80 || outValue & 0x80) {
+		if (interp) {
+		    Tcl_SetObjResult(interp, Tcl_NewStringObj(
+                            "bad value for -eofchar: must be non-NUL ASCII"
+                            " character", -1));
+		}
+		ckfree(argv);
+		return TCL_ERROR;
+	    }
+	    if (GotFlag(statePtr, TCL_READABLE)) {
+		statePtr->inEofChar = inValue;
+	    }
+	    if (GotFlag(statePtr, TCL_WRITABLE)) {
+		statePtr->outEofChar = outValue;
+	    }
+	} else {
+	    if (interp) {
+		Tcl_SetObjResult(interp, Tcl_NewStringObj(
+			"bad value for -eofchar: should be a list of zero,"
+			" one, or two elements", -1));
+	    }
+	    ckfree(argv);
+	    return TCL_ERROR;
+	}
+	if (argv != NULL) {
+	    ckfree(argv);
+	}
+
+	/*
+	 * [Bug 930851] Reset EOF and BLOCKED flags. Changing the character
+	 * which signals eof can transform a current eof condition into a 'go
+	 * ahead'. Ditto for blocked.
+	 */
+
+	if (GotFlag(statePtr, CHANNEL_EOF)) {
+	    statePtr->inputEncodingFlags |= TCL_ENCODING_START;
+	}
+	ResetFlag(statePtr, CHANNEL_EOF|CHANNEL_STICKY_EOF|CHANNEL_BLOCKED);
+	statePtr->inputEncodingFlags &= ~TCL_ENCODING_END;
+	return TCL_OK;
+    } else if (HaveOpt(1, "-translation")) {
+	const char *readMode, *writeMode;
+
+	if (Tcl_SplitList(interp, newValue, &argc, &argv) == TCL_ERROR) {
+	    return TCL_ERROR;
+	}
+
+	if (argc == 1) {
+	    readMode = GotFlag(statePtr, TCL_READABLE) ? argv[0] : NULL;
+	    writeMode = GotFlag(statePtr, TCL_WRITABLE) ? argv[0] : NULL;
+	} else if (argc == 2) {
+	    readMode = GotFlag(statePtr, TCL_READABLE) ? argv[0] : NULL;
+	    writeMode = GotFlag(statePtr, TCL_WRITABLE) ? argv[1] : NULL;
+	} else {
+	    if (interp) {
+		Tcl_SetObjResult(interp, Tcl_NewStringObj(
+			"bad value for -translation: must be a one or two"
+			" element list", -1));
+	    }
+	    ckfree(argv);
+	    return TCL_ERROR;
+	}
+
+	if (readMode) {
+	    TclEolTranslation translation;
+
+	    if (*readMode == '\0') {
+		translation = statePtr->inputTranslation;
+	    } else if (strcmp(readMode, "auto") == 0) {
+		translation = TCL_TRANSLATE_AUTO;
+	    } else if (strcmp(readMode, "binary") == 0) {
+		translation = TCL_TRANSLATE_LF;
+		statePtr->inEofChar = 0;
+		Tcl_FreeEncoding(statePtr->encoding);
+		statePtr->encoding = NULL;
+	    } else if (strcmp(readMode, "lf") == 0) {
+		translation = TCL_TRANSLATE_LF;
+	    } else if (strcmp(readMode, "cr") == 0) {
+		translation = TCL_TRANSLATE_CR;
+	    } else if (strcmp(readMode, "crlf") == 0) {
+		translation = TCL_TRANSLATE_CRLF;
+	    } else if (strcmp(readMode, "platform") == 0) {
+		translation = TCL_PLATFORM_TRANSLATION;
+	    } else {
+		if (interp) {
+		    Tcl_SetObjResult(interp, Tcl_NewStringObj(
+			    "bad value for -translation: must be one of "
+                            "auto, binary, cr, lf, crlf, or platform", -1));
+		}
+		ckfree(argv);
+		return TCL_ERROR;
+	    }
+
+	    /*
+	     * Reset the EOL flags since we need to look at any buffered data
+	     * to see if the new translation mode allows us to complete the
+	     * line.
+	     */
+
+	    if (translation != statePtr->inputTranslation) {
+		statePtr->inputTranslation = translation;
+		ResetFlag(statePtr, INPUT_SAW_CR | CHANNEL_NEED_MORE_DATA);
+		UpdateInterest(chanPtr);
+	    }
+	}
+	if (writeMode) {
+	    if (*writeMode == '\0') {
+		/* Do nothing. */
+	    } else if (strcmp(writeMode, "auto") == 0) {
+		/*
+		 * This is a hack to get TCP sockets to produce output in CRLF
+		 * mode if they are being set into AUTO mode. A better
+		 * solution for achieving this effect will be coded later.
+		 */
+
+		if (strcmp(Tcl_ChannelName(chanPtr->typePtr), "tcp") == 0) {
+		    statePtr->outputTranslation = TCL_TRANSLATE_CRLF;
+		} else {
+		    statePtr->outputTranslation = TCL_PLATFORM_TRANSLATION;
+		}
+	    } else if (strcmp(writeMode, "binary") == 0) {
+		statePtr->outEofChar = 0;
+		statePtr->outputTranslation = TCL_TRANSLATE_LF;
+		Tcl_FreeEncoding(statePtr->encoding);
+		statePtr->encoding = NULL;
+	    } else if (strcmp(writeMode, "lf") == 0) {
+		statePtr->outputTranslation = TCL_TRANSLATE_LF;
+	    } else if (strcmp(writeMode, "cr") == 0) {
+		statePtr->outputTranslation = TCL_TRANSLATE_CR;
+	    } else if (strcmp(writeMode, "crlf") == 0) {
+		statePtr->outputTranslation = TCL_TRANSLATE_CRLF;
+	    } else if (strcmp(writeMode, "platform") == 0) {
+		statePtr->outputTranslation = TCL_PLATFORM_TRANSLATION;
+	    } else {
+		if (interp) {
+		    Tcl_SetObjResult(interp, Tcl_NewStringObj(
+			    "bad value for -translation: must be one of "
+                            "auto, binary, cr, lf, crlf, or platform", -1));
+		}
+		ckfree(argv);
+		return TCL_ERROR;
+	    }
+	}
+	ckfree(argv);
+	return TCL_OK;
+    } else if (chanPtr->typePtr->setOptionProc != NULL) {
+	return chanPtr->typePtr->setOptionProc(chanPtr->instanceData, interp,
+		optionName, newValue);
+    } else {
+	return Tcl_BadChannelOption(interp, optionName, NULL);
+    }
+
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * CleanupChannelHandlers --
+ *
+ *	Removes channel handlers that refer to the supplied interpreter, so
+ *	that if the actual channel is not closed now, these handlers will not
+ *	run on subsequent events on the channel. This would be erroneous,
+ *	because the interpreter no longer has a reference to this channel.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Removes channel handlers.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+CleanupChannelHandlers(
+    Tcl_Interp *interp,
+    Channel *chanPtr)
+{
+    ChannelState *statePtr = chanPtr->state;
+				/* State info for channel */
+    EventScriptRecord *sPtr, *prevPtr, *nextPtr;
+
+    /*
+     * Remove fileevent records on this channel that refer to the given
+     * interpreter.
+     */
+
+    for (sPtr = statePtr->scriptRecordPtr, prevPtr = NULL;
+	    sPtr != NULL; sPtr = nextPtr) {
+	nextPtr = sPtr->nextPtr;
+	if (sPtr->interp == interp) {
+	    if (prevPtr == NULL) {
+		statePtr->scriptRecordPtr = nextPtr;
+	    } else {
+		prevPtr->nextPtr = nextPtr;
+	    }
+
+	    Tcl_DeleteChannelHandler((Tcl_Channel) chanPtr,
+		    TclChannelEventScriptInvoker, sPtr);
+
+	    TclDecrRefCount(sPtr->scriptPtr);
+	    ckfree(sPtr);
+	} else {
+	    prevPtr = sPtr;
+	}
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_NotifyChannel --
+ *
+ *	This procedure is called by a channel driver when a driver detects an
+ *	event on a channel. This procedure is responsible for actually
+ *	handling the event by invoking any channel handler callbacks.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Whatever the channel handler callback procedure does.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_NotifyChannel(
+    Tcl_Channel channel,	/* Channel that detected an event. */
+    int mask)			/* OR'ed combination of TCL_READABLE,
+				 * TCL_WRITABLE, or TCL_EXCEPTION: indicates
+				 * which events were detected. */
+{
+    Channel *chanPtr = (Channel *) channel;
+    ChannelState *statePtr = chanPtr->state;
+				/* State info for channel */
+    ChannelHandler *chPtr;
+    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+    NextChannelHandler nh;
+    Channel *upChanPtr;
+    const Tcl_ChannelType *upTypePtr;
+
+    /*
+     * In contrast to the other API functions this procedure walks towards the
+     * top of a stack and not down from it.
+     *
+     * The channel calling this procedure is the one who generated the event,
+     * and thus does not take part in handling it. IOW, its HandlerProc is not
+     * called, instead we begin with the channel above it.
+     *
+     * This behaviour also allows the transformation channels to generate
+     * their own events and pass them upward.
+     */
+
+    while (mask && (chanPtr->upChanPtr != NULL)) {
+	Tcl_DriverHandlerProc *upHandlerProc;
+
+	upChanPtr = chanPtr->upChanPtr;
+	upTypePtr = upChanPtr->typePtr;
+	upHandlerProc = Tcl_ChannelHandlerProc(upTypePtr);
+	if (upHandlerProc != NULL) {
+	    mask = upHandlerProc(upChanPtr->instanceData, mask);
+	}
+
+	/*
+	 * ELSE: Ignore transformations which are unable to handle the event
+	 * coming from below. Assume that they don't change the mask and pass
+	 * it on.
+	 */
+
+	chanPtr = upChanPtr;
+    }
+
+    channel = (Tcl_Channel) chanPtr;
+
+    /*
+     * Here we have either reached the top of the stack or the mask is empty.
+     * We break out of the procedure if it is the latter.
+     */
+
+    if (!mask) {
+	return;
+    }
+
+    /*
+     * We are now above the topmost channel in a stack and have events left.
+     * Now call the channel handlers as usual.
+     *
+     * Preserve the channel struct in case the script closes it.
+     */
+
+    TclChannelPreserve((Tcl_Channel)channel);
+    Tcl_Preserve(statePtr);
+
+    /*
+     * If we are flushing in the background, be sure to call FlushChannel for
+     * writable events. Note that we have to discard the writable event so we
+     * don't call any write handlers before the flush is complete.
+     */
+
+    if (GotFlag(statePtr, BG_FLUSH_SCHEDULED) && (mask & TCL_WRITABLE)) {
+	if (0 == FlushChannel(NULL, chanPtr, 1)) {
+	    mask &= ~TCL_WRITABLE;
+	}
+    }
+
+    /*
+     * Add this invocation to the list of recursive invocations of
+     * Tcl_NotifyChannel.
+     */
+
+    nh.nextHandlerPtr = NULL;
+    nh.nestedHandlerPtr = tsdPtr->nestedHandlerPtr;
+    tsdPtr->nestedHandlerPtr = &nh;
+
+    for (chPtr = statePtr->chPtr; chPtr != NULL; ) {
+	/*
+	 * If this channel handler is interested in any of the events that
+	 * have occurred on the channel, invoke its procedure.
+	 */
+
+	if ((chPtr->mask & mask) != 0) {
+	    nh.nextHandlerPtr = chPtr->nextPtr;
+	    chPtr->proc(chPtr->clientData, chPtr->mask & mask);
+	    chPtr = nh.nextHandlerPtr;
+	} else {
+	    chPtr = chPtr->nextPtr;
+	}
+    }
+
+    /*
+     * Update the notifier interest, since it may have changed after invoking
+     * event handlers. Skip that if the channel was deleted in the call to the
+     * channel handler.
+     */
+
+    if (chanPtr->typePtr != NULL) {
+	/*
+	 * TODO: This call may not be needed.  If a handler induced a
+	 * change in interest, that handler should have made its own
+	 * UpdateInterest() call, one would think.
+	 */
+	UpdateInterest(chanPtr);
+    }
+
+    Tcl_Release(statePtr);
+    TclChannelRelease(channel);
+
+    tsdPtr->nestedHandlerPtr = nh.nestedHandlerPtr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * UpdateInterest --
+ *
+ *	Arrange for the notifier to call us back at appropriate times based on
+ *	the current state of the channel.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	May schedule a timer or driver handler.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+UpdateInterest(
+    Channel *chanPtr)		/* Channel to update. */
+{
+    ChannelState *statePtr = chanPtr->state;
+				/* State info for channel */
+    int mask = statePtr->interestMask;
+
+    if (chanPtr->typePtr == NULL) {
+	/* Do not update interest on a closed channel */
+	return;
+    }
+
+    /*
+     * If there are flushed buffers waiting to be written, then we need to
+     * watch for the channel to become writable.
+     */
+
+    if (GotFlag(statePtr, BG_FLUSH_SCHEDULED)) {
+	mask |= TCL_WRITABLE;
+    }
+
+    /*
+     * If there is data in the input queue, and we aren't waiting for more
+     * data, then we need to schedule a timer so we don't block in the
+     * notifier. Also, cancel the read interest so we don't get duplicate
+     * events.
+     */
+
+    if (mask & TCL_READABLE) {
+	if (!GotFlag(statePtr, CHANNEL_NEED_MORE_DATA)
+		&& (statePtr->inQueueHead != NULL)
+		&& IsBufferReady(statePtr->inQueueHead)) {
+	    mask &= ~TCL_READABLE;
+
+	    /*
+	     * Andreas Kupries, April 11, 2003
+	     *
+	     * Some operating systems (Solaris 2.6 and higher (but not Solaris
+	     * 2.5, go figure)) generate READABLE and EXCEPTION events when
+	     * select()'ing [*] on a plain file, even if EOF was not yet
+	     * reached. This is a problem in the following situation:
+	     *
+	     * - An extension asks to get both READABLE and EXCEPTION events.
+	     * - It reads data into a buffer smaller than the buffer used by
+	     *	 Tcl itself.
+	     * - It does not process all events in the event queue, but only
+	     *	 one, at least in some situations.
+	     *
+	     * In that case we can get into a situation where
+	     *
+	     * - Tcl drops READABLE here, because it has data in its own
+	     *	 buffers waiting to be read by the extension.
+	     * - A READABLE event is syntesized via timer.
+	     * - The OS still reports the EXCEPTION condition on the file.
+	     * - And the extension gets the EXCPTION event first, and handles
+	     *	 this as EOF.
+	     *
+	     * End result ==> Premature end of reading from a file.
+	     *
+	     * The concrete example is 'Expect', and its [expect] command
+	     * (and at the C-level, deep in the bowels of Expect,
+	     * 'exp_get_next_event'. See marker 'SunOS' for commentary in
+	     * that function too).
+	     *
+	     * [*] As the Tcl notifier does. See also for marker 'SunOS' in
+	     * file 'exp_event.c' of Expect.
+	     *
+	     * Our solution here is to drop the interest in the EXCEPTION
+	     * events too. This compiles on all platforms, and also passes the
+	     * testsuite on all of them.
+	     */
+
+	    mask &= ~TCL_EXCEPTION;
+
+	    if (!statePtr->timer) {
+		statePtr->timer = Tcl_CreateTimerHandler(SYNTHETIC_EVENT_TIME,
+                        ChannelTimerProc, chanPtr);
+	    }
+	}
+    }
+    ChanWatch(chanPtr, mask);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ChannelTimerProc --
+ *
+ *	Timer handler scheduled by UpdateInterest to monitor the channel
+ *	buffers until they are empty.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	May invoke channel handlers.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+ChannelTimerProc(
+    ClientData clientData)
+{
+    Channel *chanPtr = clientData;
+    ChannelState *statePtr = chanPtr->state;
+				/* State info for channel */
+
+    if (!GotFlag(statePtr, CHANNEL_NEED_MORE_DATA)
+	    && (statePtr->interestMask & TCL_READABLE)
+	    && (statePtr->inQueueHead != NULL)
+	    && IsBufferReady(statePtr->inQueueHead)) {
+	/*
+	 * Restart the timer in case a channel handler reenters the event loop
+	 * before UpdateInterest gets called by Tcl_NotifyChannel.
+	 */
+
+	statePtr->timer = Tcl_CreateTimerHandler(SYNTHETIC_EVENT_TIME,
+                ChannelTimerProc,chanPtr);
+	Tcl_Preserve(statePtr);
+	Tcl_NotifyChannel((Tcl_Channel) chanPtr, TCL_READABLE);
+	Tcl_Release(statePtr);
+    } else {
+	statePtr->timer = NULL;
+	UpdateInterest(chanPtr);
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_CreateChannelHandler --
+ *
+ *	Arrange for a given procedure to be invoked whenever the channel
+ *	indicated by the chanPtr arg becomes readable or writable.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	From now on, whenever the I/O channel given by chanPtr becomes ready
+ *	in the way indicated by mask, proc will be invoked. See the manual
+ *	entry for details on the calling sequence to proc. If there is already
+ *	an event handler for chan, proc and clientData, then the mask will be
+ *	updated.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_CreateChannelHandler(
+    Tcl_Channel chan,		/* The channel to create the handler for. */
+    int mask,			/* OR'ed combination of TCL_READABLE,
+				 * TCL_WRITABLE, and TCL_EXCEPTION: indicates
+				 * conditions under which proc should be
+				 * called. Use 0 to disable a registered
+				 * handler. */
+    Tcl_ChannelProc *proc,	/* Procedure to call for each selected
+				 * event. */
+    ClientData clientData)	/* Arbitrary data to pass to proc. */
+{
+    ChannelHandler *chPtr;
+    Channel *chanPtr = (Channel *) chan;
+    ChannelState *statePtr = chanPtr->state;
+				/* State info for channel */
+
+    /*
+     * Check whether this channel handler is not already registered. If it is
+     * not, create a new record, else reuse existing record (smash current
+     * values).
+     */
+
+    for (chPtr = statePtr->chPtr; chPtr != NULL; chPtr = chPtr->nextPtr) {
+	if ((chPtr->chanPtr == chanPtr) && (chPtr->proc == proc) &&
+		(chPtr->clientData == clientData)) {
+	    break;
+	}
+    }
+    if (chPtr == NULL) {
+	chPtr = ckalloc(sizeof(ChannelHandler));
+	chPtr->mask = 0;
+	chPtr->proc = proc;
+	chPtr->clientData = clientData;
+	chPtr->chanPtr = chanPtr;
+	chPtr->nextPtr = statePtr->chPtr;
+	statePtr->chPtr = chPtr;
+    }
+
+    /*
+     * The remainder of the initialization below is done regardless of whether
+     * or not this is a new record or a modification of an old one.
+     */
+
+    chPtr->mask = mask;
+
+    /*
+     * Recompute the interest mask for the channel - this call may actually be
+     * disabling an existing handler.
+     */
+
+    statePtr->interestMask = 0;
+    for (chPtr = statePtr->chPtr; chPtr != NULL; chPtr = chPtr->nextPtr) {
+	statePtr->interestMask |= chPtr->mask;
+    }
+
+    UpdateInterest(statePtr->topChanPtr);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_DeleteChannelHandler --
+ *
+ *	Cancel a previously arranged callback arrangement for an IO channel.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	If a callback was previously registered for this chan, proc and
+ *	clientData, it is removed and the callback will no longer be called
+ *	when the channel becomes ready for IO.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_DeleteChannelHandler(
+    Tcl_Channel chan,		/* The channel for which to remove the
+				 * callback. */
+    Tcl_ChannelProc *proc,	/* The procedure in the callback to delete. */
+    ClientData clientData)	/* The client data in the callback to
+				 * delete. */
+{
+    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+    ChannelHandler *chPtr, *prevChPtr;
+    Channel *chanPtr = (Channel *) chan;
+    ChannelState *statePtr = chanPtr->state;
+				/* State info for channel */
+    NextChannelHandler *nhPtr;
+
+    /*
+     * Find the entry and the previous one in the list.
+     */
+
+    for (prevChPtr = NULL, chPtr = statePtr->chPtr; chPtr != NULL;
+	    chPtr = chPtr->nextPtr) {
+	if ((chPtr->chanPtr == chanPtr) && (chPtr->clientData == clientData)
+		&& (chPtr->proc == proc)) {
+	    break;
+	}
+	prevChPtr = chPtr;
+    }
+
+    /*
+     * If not found, return without doing anything.
+     */
+
+    if (chPtr == NULL) {
+	return;
+    }
+
+    /*
+     * If Tcl_NotifyChannel is about to process this handler, tell it to
+     * process the next one instead - we are going to delete *this* one.
+     */
+
+    for (nhPtr = tsdPtr->nestedHandlerPtr; nhPtr != NULL;
+	    nhPtr = nhPtr->nestedHandlerPtr) {
+	if (nhPtr->nextHandlerPtr == chPtr) {
+	    nhPtr->nextHandlerPtr = chPtr->nextPtr;
+	}
+    }
+
+    /*
+     * Splice it out of the list of channel handlers.
+     */
+
+    if (prevChPtr == NULL) {
+	statePtr->chPtr = chPtr->nextPtr;
+    } else {
+	prevChPtr->nextPtr = chPtr->nextPtr;
+    }
+    ckfree(chPtr);
+
+    /*
+     * Recompute the interest list for the channel, so that infinite loops
+     * will not result if Tcl_DeleteChannelHandler is called inside an event.
+     */
+
+    statePtr->interestMask = 0;
+    for (chPtr = statePtr->chPtr; chPtr != NULL; chPtr = chPtr->nextPtr) {
+	statePtr->interestMask |= chPtr->mask;
+    }
+
+    UpdateInterest(statePtr->topChanPtr);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * DeleteScriptRecord --
+ *
+ *	Delete a script record for this combination of channel, interp and
+ *	mask.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Deletes a script record and cancels a channel event handler.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+DeleteScriptRecord(
+    Tcl_Interp *interp,		/* Interpreter in which script was to be
+				 * executed. */
+    Channel *chanPtr,		/* The channel for which to delete the script
+				 * record (if any). */
+    int mask)			/* Events in mask must exactly match mask of
+				 * script to delete. */
+{
+    ChannelState *statePtr = chanPtr->state;
+				/* State info for channel */
+    EventScriptRecord *esPtr, *prevEsPtr;
+
+    for (esPtr = statePtr->scriptRecordPtr, prevEsPtr = NULL; esPtr != NULL;
+	    prevEsPtr = esPtr, esPtr = esPtr->nextPtr) {
+	if ((esPtr->interp == interp) && (esPtr->mask == mask)) {
+	    if (esPtr == statePtr->scriptRecordPtr) {
+		statePtr->scriptRecordPtr = esPtr->nextPtr;
+	    } else {
+		CLANG_ASSERT(prevEsPtr);
+		prevEsPtr->nextPtr = esPtr->nextPtr;
+	    }
+
+	    Tcl_DeleteChannelHandler((Tcl_Channel) chanPtr,
+		    TclChannelEventScriptInvoker, esPtr);
+
+	    TclDecrRefCount(esPtr->scriptPtr);
+	    ckfree(esPtr);
+
+	    break;
+	}
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * CreateScriptRecord --
+ *
+ *	Creates a record to store a script to be executed when a specific
+ *	event fires on a specific channel.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Causes the script to be stored for later execution.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+CreateScriptRecord(
+    Tcl_Interp *interp,		/* Interpreter in which to execute the stored
+				 * script. */
+    Channel *chanPtr,		/* Channel for which script is to be stored */
+    int mask,			/* Set of events for which script will be
+				 * invoked. */
+    Tcl_Obj *scriptPtr)		/* Pointer to script object. */
+{
+    ChannelState *statePtr = chanPtr->state;
+				/* State info for channel */
+    EventScriptRecord *esPtr;
+    int makeCH;
+
+    for (esPtr=statePtr->scriptRecordPtr; esPtr!=NULL; esPtr=esPtr->nextPtr) {
+	if ((esPtr->interp == interp) && (esPtr->mask == mask)) {
+	    TclDecrRefCount(esPtr->scriptPtr);
+	    esPtr->scriptPtr = NULL;
+	    break;
+	}
+    }
+
+    makeCH = (esPtr == NULL);
+
+    if (makeCH) {
+	esPtr = ckalloc(sizeof(EventScriptRecord));
+    }
+
+    /*
+     * Initialize the structure before calling Tcl_CreateChannelHandler,
+     * because a reflected channel calling 'chan postevent' aka
+     * 'Tcl_NotifyChannel' in its 'watch'Proc will invoke
+     * 'TclChannelEventScriptInvoker' immediately, and we do not wish it to
+     * see uninitialized memory and crash. See [Bug 2918110].
+     */
+
+    esPtr->chanPtr = chanPtr;
+    esPtr->interp = interp;
+    esPtr->mask = mask;
+    Tcl_IncrRefCount(scriptPtr);
+    esPtr->scriptPtr = scriptPtr;
+
+    if (makeCH) {
+	esPtr->nextPtr = statePtr->scriptRecordPtr;
+	statePtr->scriptRecordPtr = esPtr;
+
+	Tcl_CreateChannelHandler((Tcl_Channel) chanPtr, mask,
+		TclChannelEventScriptInvoker, esPtr);
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclChannelEventScriptInvoker --
+ *
+ *	Invokes a script scheduled by "fileevent" for when the channel becomes
+ *	ready for IO. This function is invoked by the channel handler which
+ *	was created by the Tcl "fileevent" command.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Whatever the script does.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclChannelEventScriptInvoker(
+    ClientData clientData,	/* The script+interp record. */
+    int mask)			/* Not used. */
+{
+    Tcl_Interp *interp;		/* Interpreter in which to eval the script. */
+    Channel *chanPtr;		/* The channel for which this handler is
+				 * registered. */
+    EventScriptRecord *esPtr;	/* The event script + interpreter to eval it
+				 * in. */
+    int result;			/* Result of call to eval script. */
+
+    esPtr = clientData;
+    chanPtr = esPtr->chanPtr;
+    mask = esPtr->mask;
+    interp = esPtr->interp;
+
+    /*
+     * We must preserve the interpreter so we can report errors on it later.
+     * Note that we do not need to preserve the channel because that is done
+     * by Tcl_NotifyChannel before calling channel handlers.
+     */
+
+    Tcl_Preserve(interp);
+    TclChannelPreserve((Tcl_Channel)chanPtr);
+    result = Tcl_EvalObjEx(interp, esPtr->scriptPtr, TCL_EVAL_GLOBAL);
+
+    /*
+     * On error, cause a background error and remove the channel handler and
+     * the script record.
+     *
+     * NOTE: Must delete channel handler before causing the background error
+     * because the background error may want to reinstall the handler.
+     */
+
+    if (result != TCL_OK) {
+	if (chanPtr->typePtr != NULL) {
+	    DeleteScriptRecord(interp, chanPtr, mask);
+	}
+	Tcl_BackgroundException(interp, result);
+    }
+    TclChannelRelease((Tcl_Channel)chanPtr);
+    Tcl_Release(interp);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_FileEventObjCmd --
+ *
+ *	This procedure implements the "fileevent" Tcl command. See the user
+ *	documentation for details on what it does. This command is based on
+ *	the Tk command "fileevent" which in turn is based on work contributed
+ *	by Mark Diekhans.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	May create a channel handler for the specified channel.
+ *
+ *----------------------------------------------------------------------
+ */
+
+	/* ARGSUSED */
+int
+Tcl_FileEventObjCmd(
+    ClientData clientData,	/* Not used. */
+    Tcl_Interp *interp,		/* Interpreter in which the channel for which
+				 * to create the handler is found. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    Channel *chanPtr;		/* The channel to create the handler for. */
+    ChannelState *statePtr;	/* State info for channel */
+    Tcl_Channel chan;		/* The opaque type for the channel. */
+    const char *chanName;
+    int modeIndex;		/* Index of mode argument. */
+    int mask;
+    static const char *const modeOptions[] = {"readable", "writable", NULL};
+    static const int maskArray[] = {TCL_READABLE, TCL_WRITABLE};
+
+    if ((objc != 3) && (objc != 4)) {
+	Tcl_WrongNumArgs(interp, 1, objv, "channelId event ?script?");
+	return TCL_ERROR;
+    }
+    if (Tcl_GetIndexFromObj(interp, objv[2], modeOptions, "event name", 0,
+	    &modeIndex) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    mask = maskArray[modeIndex];
+
+    chanName = TclGetString(objv[1]);
+    chan = Tcl_GetChannel(interp, chanName, NULL);
+    if (chan == NULL) {
+	return TCL_ERROR;
+    }
+    chanPtr = (Channel *) chan;
+    statePtr = chanPtr->state;
+    if ((statePtr->flags & mask) == 0) {
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf("channel is not %s",
+		(mask == TCL_READABLE) ? "readable" : "writable"));
+	return TCL_ERROR;
+    }
+
+    /*
+     * If we are supposed to return the script, do so.
+     */
+
+    if (objc == 3) {
+	EventScriptRecord *esPtr;
+
+	for (esPtr = statePtr->scriptRecordPtr; esPtr != NULL;
+		esPtr = esPtr->nextPtr) {
+	    if ((esPtr->interp == interp) && (esPtr->mask == mask)) {
+		Tcl_SetObjResult(interp, esPtr->scriptPtr);
+		break;
+	    }
+	}
+	return TCL_OK;
+    }
+
+    /*
+     * If we are supposed to delete a stored script, do so.
+     */
+
+    if (*(TclGetString(objv[3])) == '\0') {
+	DeleteScriptRecord(interp, chanPtr, mask);
+	return TCL_OK;
+    }
+
+    /*
+     * Make the script record that will link between the event and the script
+     * to invoke. This also creates a channel event handler which will
+     * evaluate the script in the supplied interpreter.
+     */
+
+    CreateScriptRecord(interp, chanPtr, mask, objv[3]);
+
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ZeroTransferTimerProc --
+ *
+ *	Timer handler scheduled by TclCopyChannel so that -command is
+ *	called asynchronously even when -size is 0.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Calls CopyData for -command invocation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+ZeroTransferTimerProc(
+    ClientData clientData)
+{
+    /* calling CopyData with mask==0 still implies immediate invocation of the
+     *  -command callback, and completion of the fcopy.
+     */
+    CopyData(clientData, 0);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclCopyChannel --
+ *
+ *	This routine copies data from one channel to another, either
+ *	synchronously or asynchronously. If a command script is supplied, the
+ *	operation runs in the background. The script is invoked when the copy
+ *	completes. Otherwise the function waits until the copy is completed
+ *	before returning.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	May schedule a background copy operation that causes both channels to
+ *	be marked busy.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclCopyChannelOld(
+    Tcl_Interp *interp,		/* Current interpreter. */
+    Tcl_Channel inChan,		/* Channel to read from. */
+    Tcl_Channel outChan,	/* Channel to write to. */
+    int toRead,			/* Amount of data to copy, or -1 for all. */
+    Tcl_Obj *cmdPtr)		/* Pointer to script to execute or NULL. */
+{
+    return TclCopyChannel(interp, inChan, outChan, (Tcl_WideInt) toRead,
+            cmdPtr);
+}
+
+int
+TclCopyChannel(
+    Tcl_Interp *interp,		/* Current interpreter. */
+    Tcl_Channel inChan,		/* Channel to read from. */
+    Tcl_Channel outChan,	/* Channel to write to. */
+    Tcl_WideInt toRead,		/* Amount of data to copy, or -1 for all. */
+    Tcl_Obj *cmdPtr)		/* Pointer to script to execute or NULL. */
+{
+    Channel *inPtr = (Channel *) inChan;
+    Channel *outPtr = (Channel *) outChan;
+    ChannelState *inStatePtr, *outStatePtr;
+    int readFlags, writeFlags;
+    CopyState *csPtr;
+    int nonBlocking = (cmdPtr) ? CHANNEL_NONBLOCKING : 0;
+    int moveBytes;
+
+    inStatePtr = inPtr->state;
+    outStatePtr = outPtr->state;
+
+    if (BUSY_STATE(inStatePtr, TCL_READABLE)) {
+	if (interp) {
+	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+                    "channel \"%s\" is busy", Tcl_GetChannelName(inChan)));
+	}
+	return TCL_ERROR;
+    }
+    if (BUSY_STATE(outStatePtr, TCL_WRITABLE)) {
+	if (interp) {
+	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+                    "channel \"%s\" is busy", Tcl_GetChannelName(outChan)));
+	}
+	return TCL_ERROR;
+    }
+
+    readFlags = inStatePtr->flags;
+    writeFlags = outStatePtr->flags;
+
+    /*
+     * Set up the blocking mode appropriately. Background copies need
+     * non-blocking channels. Foreground copies need blocking channels. If
+     * there is an error, restore the old blocking mode.
+     */
+
+    if (nonBlocking != (readFlags & CHANNEL_NONBLOCKING)) {
+	if (SetBlockMode(interp, inPtr, nonBlocking ?
+		TCL_MODE_NONBLOCKING : TCL_MODE_BLOCKING) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+    }
+    if ((inPtr!=outPtr) && (nonBlocking!=(writeFlags&CHANNEL_NONBLOCKING)) &&
+	    (SetBlockMode(NULL, outPtr, nonBlocking ?
+		    TCL_MODE_NONBLOCKING : TCL_MODE_BLOCKING) != TCL_OK) &&
+	    (nonBlocking != (readFlags & CHANNEL_NONBLOCKING))) {
+	SetBlockMode(NULL, inPtr, (readFlags & CHANNEL_NONBLOCKING)
+		? TCL_MODE_NONBLOCKING : TCL_MODE_BLOCKING);
+	return TCL_ERROR;
+    }
+
+    /*
+     * Make sure the output side is unbuffered.
+     */
+
+    outStatePtr->flags = (outStatePtr->flags & ~CHANNEL_LINEBUFFERED)
+	    | CHANNEL_UNBUFFERED;
+
+    /*
+     * Test for conditions where we know we can just move bytes from input
+     * channel to output channel with no transformation or even examination
+     * of the bytes themselves.
+     */
+
+    moveBytes = inStatePtr->inEofChar == '\0'	/* No eofChar to stop input */
+	    && inStatePtr->inputTranslation == TCL_TRANSLATE_LF
+	    && outStatePtr->outputTranslation == TCL_TRANSLATE_LF
+	    && inStatePtr->encoding == outStatePtr->encoding;
+
+    /*
+     * Allocate a new CopyState to maintain info about the current copy in
+     * progress. This structure will be deallocated when the copy is
+     * completed.
+     */
+
+    csPtr = ckalloc(sizeof(CopyState) + !moveBytes * inStatePtr->bufSize);
+    csPtr->bufSize = !moveBytes * inStatePtr->bufSize;
+    csPtr->readPtr = inPtr;
+    csPtr->writePtr = outPtr;
+    csPtr->readFlags = readFlags;
+    csPtr->writeFlags = writeFlags;
+    csPtr->toRead = toRead;
+    csPtr->total = (Tcl_WideInt) 0;
+    csPtr->interp = interp;
+    if (cmdPtr) {
+	Tcl_IncrRefCount(cmdPtr);
+    }
+    csPtr->cmdPtr = cmdPtr;
+
+    inStatePtr->csPtrR  = csPtr;
+    outStatePtr->csPtrW = csPtr;
+
+    if (moveBytes) {
+	return MoveBytes(csPtr);
+    }
+
+    /*
+     * Special handling of -size 0 async transfers, so that the -command is
+     * still called asynchronously.
+     */
+
+    if ((nonBlocking == CHANNEL_NONBLOCKING) && (toRead == 0)) {
+        Tcl_CreateTimerHandler(0, ZeroTransferTimerProc, csPtr);
+        return 0;
+    }
+
+    /*
+     * Start copying data between the channels.
+     */
+
+    return CopyData(csPtr, 0);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * CopyData --
+ *
+ *	This function implements the lowest level of the copying mechanism for
+ *	TclCopyChannel.
+ *
+ * Results:
+ *	Returns TCL_OK on success, else TCL_ERROR.
+ *
+ * Side effects:
+ *	Moves data between channels, may create channel handlers.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+MBCallback(
+    CopyState *csPtr,
+    Tcl_Obj *errObj)
+{
+    Tcl_Obj *cmdPtr = Tcl_DuplicateObj(csPtr->cmdPtr);
+    Tcl_WideInt total = csPtr->total;
+    Tcl_Interp *interp = csPtr->interp;
+    int code;
+
+    Tcl_IncrRefCount(cmdPtr);
+    StopCopy(csPtr);
+
+    /* TODO: What if cmdPtr is not a list?! */
+
+    Tcl_ListObjAppendElement(NULL, cmdPtr, Tcl_NewWideIntObj(total));
+    if (errObj) {
+	Tcl_ListObjAppendElement(NULL, cmdPtr, errObj);
+    }
+
+    Tcl_Preserve(interp);
+    code = Tcl_EvalObjEx(interp, cmdPtr, TCL_EVAL_GLOBAL);
+    if (code != TCL_OK) {
+	Tcl_BackgroundException(interp, code);
+    }
+    Tcl_Release(interp);
+    TclDecrRefCount(cmdPtr);
+}
+
+static void
+MBError(
+    CopyState *csPtr,
+    int mask,
+    int errorCode)
+{
+    Tcl_Channel inChan = (Tcl_Channel) csPtr->readPtr;
+    Tcl_Channel outChan = (Tcl_Channel) csPtr->writePtr;
+    Tcl_Obj *errObj;
+
+    Tcl_SetErrno(errorCode);
+
+    errObj = Tcl_ObjPrintf( "error %sing \"%s\": %s",
+	    (mask & TCL_READABLE) ? "read" : "writ",
+	    Tcl_GetChannelName((mask & TCL_READABLE) ? inChan : outChan),
+	    Tcl_PosixError(csPtr->interp));
+
+    if (csPtr->cmdPtr) {
+	MBCallback(csPtr, errObj);
+    } else {
+	Tcl_SetObjResult(csPtr->interp, errObj);
+	StopCopy(csPtr);
+    }
+}
+
+static void
+MBEvent(
+    ClientData clientData,
+    int mask)
+{
+    CopyState *csPtr = (CopyState *) clientData;
+    Tcl_Channel inChan = (Tcl_Channel) csPtr->readPtr;
+    Tcl_Channel outChan = (Tcl_Channel) csPtr->writePtr;
+    ChannelState *inStatePtr = csPtr->readPtr->state;
+
+    if (mask & TCL_WRITABLE) {
+	Tcl_DeleteChannelHandler(inChan, MBEvent, csPtr);
+	Tcl_DeleteChannelHandler(outChan, MBEvent, csPtr);
+	switch (MBWrite(csPtr)) {
+	case TCL_OK:
+	    MBCallback(csPtr, NULL);
+	    break;
+	case TCL_CONTINUE:
+	    Tcl_CreateChannelHandler(inChan, TCL_READABLE, MBEvent, csPtr);
+	    break;
+	}
+    } else if (mask & TCL_READABLE) {
+	if (TCL_OK == MBRead(csPtr)) {
+	    /* When at least one full buffer is present, stop reading. */
+	    if (IsBufferFull(inStatePtr->inQueueHead)
+		    || !Tcl_InputBlocked(inChan)) {
+		Tcl_DeleteChannelHandler(inChan, MBEvent, csPtr);
+	    }
+
+	    /* Successful read -- set up to write the bytes we read */
+	    Tcl_CreateChannelHandler(outChan, TCL_WRITABLE, MBEvent, csPtr);
+	}
+    }
+}
+
+static int
+MBRead(
+    CopyState *csPtr)
+{
+    ChannelState *inStatePtr = csPtr->readPtr->state;
+    ChannelBuffer *bufPtr = inStatePtr->inQueueHead;
+    int code;
+
+    if (bufPtr && BytesLeft(bufPtr) > 0) {
+	return TCL_OK;
+    }
+
+    code = GetInput(inStatePtr->topChanPtr);
+    if (code == 0 || GotFlag(inStatePtr, CHANNEL_BLOCKED)) {
+	return TCL_OK;
+    } else {
+	MBError(csPtr, TCL_READABLE, code);
+	return TCL_ERROR;
+    }
+}
+
+static int
+MBWrite(
+    CopyState *csPtr)
+{
+    ChannelState *inStatePtr = csPtr->readPtr->state;
+    ChannelState *outStatePtr = csPtr->writePtr->state;
+    ChannelBuffer *bufPtr = inStatePtr->inQueueHead;
+    ChannelBuffer *tail = NULL;
+    int code;
+    Tcl_WideInt inBytes = 0;
+
+    /* Count up number of bytes waiting in the input queue */
+    while (bufPtr) {
+	inBytes += BytesLeft(bufPtr);
+	tail = bufPtr;
+	if (csPtr->toRead != -1 && csPtr->toRead < inBytes) {
+	    /* Queue has enough bytes to complete the copy */
+	    break;
+	}
+	bufPtr = bufPtr->nextPtr;
+    }
+
+    if (bufPtr) {
+	/* Split the overflowing buffer in two */
+	int extra = (int) (inBytes - csPtr->toRead);
+        /* Note that going with int for extra assumes that inBytes is not too
+         * much over toRead to require a wide itself. If that gets violated
+         * then the calculations involving extra must be made wide too.
+         *
+         * Noted with Win32/MSVC debug build treating the warning (possible of
+         * data in int64 to int conversion) as error.
+         */
+
+	bufPtr = AllocChannelBuffer(extra);
+
+	tail->nextAdded -= extra;
+	memcpy(InsertPoint(bufPtr), InsertPoint(tail), extra);
+	bufPtr->nextAdded += extra;
+	bufPtr->nextPtr = tail->nextPtr;
+	tail->nextPtr = NULL;
+	inBytes = csPtr->toRead;
+    }
+
+    /* Update the byte counts */
+    if (csPtr->toRead != -1) {
+	csPtr->toRead -= inBytes;
+    }
+    csPtr->total += inBytes;
+
+    /* Move buffers from input to output channels */
+    if (outStatePtr->outQueueTail) {
+	outStatePtr->outQueueTail->nextPtr = inStatePtr->inQueueHead;
+    } else {
+	outStatePtr->outQueueHead = inStatePtr->inQueueHead;
+    }
+    outStatePtr->outQueueTail = tail;
+    inStatePtr->inQueueHead = bufPtr;
+    if (inStatePtr->inQueueTail == tail) {
+	inStatePtr->inQueueTail = bufPtr;
+    }
+    if (bufPtr == NULL) {
+	inStatePtr->inQueueTail = NULL;
+    }
+
+    code = FlushChannel(csPtr->interp, outStatePtr->topChanPtr, 0);
+    if (code) {
+	MBError(csPtr, TCL_WRITABLE, code);
+	return TCL_ERROR;
+    }
+    if (csPtr->toRead == 0 || GotFlag(inStatePtr, CHANNEL_EOF)) {
+	return TCL_OK;
+    }
+    return TCL_CONTINUE;
+}
+
+static int
+MoveBytes(
+    CopyState *csPtr)		/* State of copy operation. */
+{
+    ChannelState *outStatePtr = csPtr->writePtr->state;
+    ChannelBuffer *bufPtr = outStatePtr->curOutPtr;
+    int errorCode;
+
+    if (bufPtr && BytesLeft(bufPtr)) {
+	/* If we start with unflushed bytes in the destination
+	 * channel, flush them out of the way first. */
+
+	errorCode = FlushChannel(csPtr->interp, outStatePtr->topChanPtr, 0);
+	if (errorCode != 0) {
+	    MBError(csPtr, TCL_WRITABLE, errorCode);
+	    return TCL_ERROR;
+	}
+    }
+
+    if (csPtr->cmdPtr) {
+	Tcl_Channel inChan = (Tcl_Channel) csPtr->readPtr;
+	Tcl_CreateChannelHandler(inChan, TCL_READABLE, MBEvent, csPtr);
+	return TCL_OK;
+    }
+
+    while (1) {
+	int code;
+
+	if (TCL_ERROR == MBRead(csPtr)) {
+	    return TCL_ERROR;
+	}
+	code = MBWrite(csPtr);
+	if (code == TCL_OK) {
+	    Tcl_SetObjResult(csPtr->interp, Tcl_NewWideIntObj(csPtr->total));
+	    StopCopy(csPtr);
+	    return TCL_OK;
+	}
+	if (code == TCL_ERROR) {
+	    return TCL_ERROR;
+	}
+	/* code == TCL_CONTINUE --> continue the loop */
+    }
+    return TCL_OK;	/* Silence compiler warnings */
+}
+
+static int
+CopyData(
+    CopyState *csPtr,		/* State of copy operation. */
+    int mask)			/* Current channel event flags. */
+{
+    Tcl_Interp *interp;
+    Tcl_Obj *cmdPtr, *errObj = NULL, *bufObj = NULL, *msg = NULL;
+    Tcl_Channel inChan, outChan;
+    ChannelState *inStatePtr, *outStatePtr;
+    int result = TCL_OK, size, sizeb;
+    Tcl_WideInt total;
+    const char *buffer;
+    int inBinary, outBinary, sameEncoding;
+				/* Encoding control */
+    int underflow;		/* Input underflow */
+
+    inChan	= (Tcl_Channel) csPtr->readPtr;
+    outChan	= (Tcl_Channel) csPtr->writePtr;
+    inStatePtr	= csPtr->readPtr->state;
+    outStatePtr	= csPtr->writePtr->state;
+    interp	= csPtr->interp;
+    cmdPtr	= csPtr->cmdPtr;
+
+    /*
+     * Copy the data the slow way, using the translation mechanism.
+     *
+     * Note: We have make sure that we use the topmost channel in a stack for
+     * the copying. The caller uses Tcl_GetChannel to access it, and thus gets
+     * the bottom of the stack.
+     */
+
+    inBinary = (inStatePtr->encoding == NULL);
+    outBinary = (outStatePtr->encoding == NULL);
+    sameEncoding = (inStatePtr->encoding == outStatePtr->encoding);
+
+    if (!(inBinary || sameEncoding)) {
+	TclNewObj(bufObj);
+	Tcl_IncrRefCount(bufObj);
+    }
+
+    while (csPtr->toRead != (Tcl_WideInt) 0) {
+	/*
+	 * Check for unreported background errors.
+	 */
+
+	Tcl_GetChannelError(inChan, &msg);
+	if ((inStatePtr->unreportedError != 0) || (msg != NULL)) {
+	    Tcl_SetErrno(inStatePtr->unreportedError);
+	    inStatePtr->unreportedError = 0;
+	    goto readError;
+	}
+	Tcl_GetChannelError(outChan, &msg);
+	if ((outStatePtr->unreportedError != 0) || (msg != NULL)) {
+	    Tcl_SetErrno(outStatePtr->unreportedError);
+	    outStatePtr->unreportedError = 0;
+	    goto writeError;
+	}
+
+	if (cmdPtr && (mask == 0)) {
+	    /*
+	     * In async mode, we skip reading synchronously and fake an
+	     * underflow instead to prime the readable fileevent.
+	     */
+
+	    size = 0;
+	    underflow = 1;
+	} else {
+	    /*
+	     * Read up to bufSize bytes.
+	     */
+
+	    if ((csPtr->toRead == (Tcl_WideInt) -1)
+                    || (csPtr->toRead > (Tcl_WideInt) csPtr->bufSize)) {
+		sizeb = csPtr->bufSize;
+	    } else {
+		sizeb = (int) csPtr->toRead;
+	    }
+
+	    if (inBinary || sameEncoding) {
+		size = DoRead(inStatePtr->topChanPtr, csPtr->buffer, sizeb,
+                              !GotFlag(inStatePtr, CHANNEL_NONBLOCKING));
+	    } else {
+		size = DoReadChars(inStatePtr->topChanPtr, bufObj, sizeb,
+			0 /* No append */);
+	    }
+	    underflow = (size >= 0) && (size < sizeb);	/* Input underflow */
+	}
+
+	if (size < 0) {
+	readError:
+	    if (interp) {
+		TclNewObj(errObj);
+		Tcl_AppendStringsToObj(errObj, "error reading \"",
+			Tcl_GetChannelName(inChan), "\": ", NULL);
+		if (msg != NULL) {
+		    Tcl_AppendObjToObj(errObj, msg);
+		} else {
+		    Tcl_AppendStringsToObj(errObj, Tcl_PosixError(interp),
+			    NULL);
+		}
+	    }
+	    if (msg != NULL) {
+		Tcl_DecrRefCount(msg);
+	    }
+	    break;
+	} else if (underflow) {
+	    /*
+	     * We had an underflow on the read side. If we are at EOF, and not
+	     * in the synchronous part of an asynchronous fcopy, then the
+	     * copying is done, otherwise set up a channel handler to detect
+	     * when the channel becomes readable again.
+	     */
+
+	    if ((size == 0) && Tcl_Eof(inChan) && !(cmdPtr && (mask == 0))) {
+		break;
+	    }
+	    if (cmdPtr && (!Tcl_Eof(inChan) || (mask == 0)) &&
+                !(mask & TCL_READABLE)) {
+		if (mask & TCL_WRITABLE) {
+		    Tcl_DeleteChannelHandler(outChan, CopyEventProc, csPtr);
+		}
+		Tcl_CreateChannelHandler(inChan, TCL_READABLE, CopyEventProc,
+			csPtr);
+	    }
+	    if (size == 0) {
+		if (!GotFlag(inStatePtr, CHANNEL_NONBLOCKING)) {
+		    /* We allowed a short read.  Keep trying. */
+		    continue;
+		}
+		if (bufObj != NULL) {
+		    TclDecrRefCount(bufObj);
+		    bufObj = NULL;
+		}
+		return TCL_OK;
+	    }
+	}
+
+	/*
+	 * Now write the buffer out.
+	 */
+
+	if (inBinary || sameEncoding) {
+	    buffer = csPtr->buffer;
+	    sizeb = size;
+	} else {
+	    buffer = TclGetStringFromObj(bufObj, &sizeb);
+	}
+
+	if (outBinary || sameEncoding) {
+	    sizeb = WriteBytes(outStatePtr->topChanPtr, buffer, sizeb);
+	} else {
+	    sizeb = WriteChars(outStatePtr->topChanPtr, buffer, sizeb);
+	}
+
+	/*
+	 * [Bug 2895565]. At this point 'size' still contains the number of
+	 * bytes or characters which have been read. We keep this to later to
+	 * update the totals and toRead information, see marker (UP) below. We
+	 * must not overwrite it with 'sizeb', which is the number of written
+	 * bytes or characters, and both EOL translation and encoding
+	 * conversion may have changed this number unpredictably in relation
+	 * to 'size' (It can be smaller or larger, in the latter case able to
+	 * drive toRead below -1, causing infinite looping). Completely
+	 * unsuitable for updating totals and toRead.
+	 */
+
+	if (sizeb < 0) {
+	writeError:
+	    if (interp) {
+		TclNewObj(errObj);
+		Tcl_AppendStringsToObj(errObj, "error writing \"",
+			Tcl_GetChannelName(outChan), "\": ", NULL);
+		if (msg != NULL) {
+		    Tcl_AppendObjToObj(errObj, msg);
+		} else {
+		    Tcl_AppendStringsToObj(errObj, Tcl_PosixError(interp),
+			    NULL);
+		}
+	    }
+	    if (msg != NULL) {
+		Tcl_DecrRefCount(msg);
+	    }
+	    break;
+	}
+
+	/*
+	 * Update the current byte count. Do it now so the count is valid
+	 * before a return or break takes us out of the loop. The invariant at
+	 * the top of the loop should be that csPtr->toRead holds the number
+	 * of bytes left to copy.
+	 */
+
+	if (csPtr->toRead != -1) {
+	    csPtr->toRead -= size;
+	}
+	csPtr->total += size;
+
+	/*
+	 * Break loop if EOF && (size>0)
+	 */
+
+	if (Tcl_Eof(inChan)) {
+	    break;
+	}
+
+	/*
+	 * Check to see if the write is happening in the background. If so,
+	 * stop copying and wait for the channel to become writable again.
+	 * After input underflow we already installed a readable handler
+	 * therefore we don't need a writable handler.
+	 */
+
+	if (!underflow && GotFlag(outStatePtr, BG_FLUSH_SCHEDULED)) {
+	    if (!(mask & TCL_WRITABLE)) {
+		if (mask & TCL_READABLE) {
+		    Tcl_DeleteChannelHandler(inChan, CopyEventProc, csPtr);
+		}
+		Tcl_CreateChannelHandler(outChan, TCL_WRITABLE,
+			CopyEventProc, csPtr);
+	    }
+	    if (bufObj != NULL) {
+		TclDecrRefCount(bufObj);
+		bufObj = NULL;
+	    }
+	    return TCL_OK;
+	}
+
+	/*
+	 * For background copies, we only do one buffer per invocation so we
+	 * don't starve the rest of the system.
+	 */
+
+	if (cmdPtr && (csPtr->toRead != 0)) {
+	    /*
+	     * The first time we enter this code, there won't be a channel
+	     * handler established yet, so do it here.
+	     */
+
+	    if (mask == 0) {
+		Tcl_CreateChannelHandler(outChan, TCL_WRITABLE, CopyEventProc,
+			csPtr);
+	    }
+	    if (bufObj != NULL) {
+		TclDecrRefCount(bufObj);
+		bufObj = NULL;
+	    }
+	    return TCL_OK;
+	}
+    } /* while */
+
+    if (bufObj != NULL) {
+	TclDecrRefCount(bufObj);
+	bufObj = NULL;
+    }
+
+    /*
+     * Make the callback or return the number of bytes transferred. The local
+     * total is used because StopCopy frees csPtr.
+     */
+
+    total = csPtr->total;
+    if (cmdPtr && interp) {
+	int code;
+
+	/*
+	 * Get a private copy of the command so we can mutate it by adding
+	 * arguments. Note that StopCopy frees our saved reference to the
+	 * original command obj.
+	 */
+
+	cmdPtr = Tcl_DuplicateObj(cmdPtr);
+	Tcl_IncrRefCount(cmdPtr);
+	StopCopy(csPtr);
+	Tcl_Preserve(interp);
+
+	Tcl_ListObjAppendElement(interp, cmdPtr, Tcl_NewWideIntObj(total));
+	if (errObj) {
+	    Tcl_ListObjAppendElement(interp, cmdPtr, errObj);
+	}
+	code = Tcl_EvalObjEx(interp, cmdPtr, TCL_EVAL_GLOBAL);
+	if (code != TCL_OK) {
+	    Tcl_BackgroundException(interp, code);
+	    result = TCL_ERROR;
+	}
+	TclDecrRefCount(cmdPtr);
+	Tcl_Release(interp);
+    } else {
+	StopCopy(csPtr);
+	if (interp) {
+	    if (errObj) {
+		Tcl_SetObjResult(interp, errObj);
+		result = TCL_ERROR;
+	    } else {
+		Tcl_ResetResult(interp);
+		Tcl_SetObjResult(interp, Tcl_NewWideIntObj(total));
+	    }
+	}
+    }
+    return result;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * DoRead --
+ *
+ *	Stores up to "bytesToRead" bytes in memory pointed to by "dst".
+ *	These bytes come from reading the channel "chanPtr" and
+ *	performing the configured translations.  No encoding conversions
+ *	are applied to the bytes being read.
+ *
+ * Results:
+ *	The number of bytes actually stored (<= bytesToRead),
+ * 	or -1 if there is an error in reading the channel.  Use
+ * 	Tcl_GetErrno() to retrieve the error code for the error
+ *	that occurred.
+ *
+ *	The number of bytes stored can be less than the number
+ * 	requested when
+ *	  - EOF is reached on the channel; or
+ *	  - the channel is non-blocking, and we've read all we can
+ *	    without blocking.
+ *	  - a channel reading error occurs (and we return -1)
+ *
+ * Side effects:
+ *	May cause input to be buffered.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+DoRead(
+    Channel *chanPtr,		/* The channel from which to read. */
+    char *dst,			/* Where to store input read. */
+    int bytesToRead,		/* Maximum number of bytes to read. */
+    int allowShortReads)	/* Allow half-blocking (pipes,sockets) */
+{
+    ChannelState *statePtr = chanPtr->state;
+    char *p = dst;
+
+    assert (bytesToRead >= 0);
+
+    /*
+     * Early out when we know a read will get the eofchar.
+     *
+     * NOTE: This seems to be a bug.  The special handling for
+     * a zero-char read request ought to come first.  As coded
+     * the EOF due to eofchar has distinguishing behavior from
+     * the EOF due to reported EOF on the underlying device, and
+     * that seems undesirable.  However recent history indicates
+     * that new inconsistent behavior in a patchlevel has problems
+     * too.  Keep on keeping on for now.
+     */
+
+    if (GotFlag(statePtr, CHANNEL_STICKY_EOF)) {
+	SetFlag(statePtr, CHANNEL_EOF);
+	assert( statePtr->inputEncodingFlags & TCL_ENCODING_END );
+	assert( !GotFlag(statePtr, CHANNEL_BLOCKED|INPUT_SAW_CR) );
+
+	/* TODO: Don't need this call */
+	UpdateInterest(chanPtr);
+	return 0;
+    }
+
+    /* Special handling for zero-char read request. */
+    if (bytesToRead == 0) {
+	if (GotFlag(statePtr, CHANNEL_EOF)) {
+	    statePtr->inputEncodingFlags |= TCL_ENCODING_START;
+	}
+	ResetFlag(statePtr, CHANNEL_BLOCKED|CHANNEL_EOF);
+	statePtr->inputEncodingFlags &= ~TCL_ENCODING_END;
+	/* TODO: Don't need this call */
+	UpdateInterest(chanPtr);
+	return 0;
+    }
+
+    TclChannelPreserve((Tcl_Channel)chanPtr);
+    while (bytesToRead) {
+	/*
+	 * Each pass through the loop is intended to process up to
+	 * one channel buffer.
+	 */
+
+	int bytesRead, bytesWritten;
+	ChannelBuffer *bufPtr = statePtr->inQueueHead;
+
+	/*
+	 * Don't read more data if we have what we need.
+	 */
+
+	while (!bufPtr ||			/* We got no buffer!   OR */
+		(!IsBufferFull(bufPtr) && 	/* Our buffer has room AND */
+		(BytesLeft(bufPtr) < bytesToRead) ) ) {
+						/* Not enough bytes in it
+						 * yet to fill the dst */
+	    int code;
+
+	moreData:
+	    code = GetInput(chanPtr);
+	    bufPtr = statePtr->inQueueHead;
+
+	    assert (bufPtr != NULL);
+
+	    if (GotFlag(statePtr, CHANNEL_EOF|CHANNEL_BLOCKED)) {
+		/* Further reads cannot do any more */
+		break;
+	    }
+
+	    if (code) {
+		/* Read error */
+		UpdateInterest(chanPtr);
+		TclChannelRelease((Tcl_Channel)chanPtr);
+		return -1;
+	    }
+
+	    assert (IsBufferFull(bufPtr));
+	}
+
+	assert (bufPtr != NULL);
+
+	bytesRead = BytesLeft(bufPtr);
+	bytesWritten = bytesToRead;
+
+	TranslateInputEOL(statePtr, p, RemovePoint(bufPtr),
+		&bytesWritten, &bytesRead);
+	bufPtr->nextRemoved += bytesRead;
+	p += bytesWritten;
+	bytesToRead -= bytesWritten;
+
+	if (!IsBufferEmpty(bufPtr)) {
+	    /*
+	     * Buffer is not empty.  How can that be?
+	     *
+	     * 0) We stopped early because we got all the bytes
+	     *    we were seeking.  That's fine.
+	     */
+
+	    if (bytesToRead == 0) {
+		break;
+	    }
+
+	    /*
+	     * 1) We're @EOF because we saw eof char.
+	     */
+
+	    if (GotFlag(statePtr, CHANNEL_STICKY_EOF)) {
+		break;
+	    }
+
+	    /*
+	     * 2) The buffer holds a \r while in CRLF translation,
+	     *    followed by the end of the buffer.
+	     */
+
+	    assert(statePtr->inputTranslation == TCL_TRANSLATE_CRLF);
+	    assert(RemovePoint(bufPtr)[0] == '\r');
+	    assert(BytesLeft(bufPtr) == 1);
+
+	    if (bufPtr->nextPtr == NULL) {
+		/* There's no more buffered data.... */
+
+		if (statePtr->flags & CHANNEL_EOF) {
+		    /* ...and there never will be. */
+
+		    *p++ = '\r';
+		    bytesToRead--;
+		    bufPtr->nextRemoved++;
+		} else if (statePtr->flags & CHANNEL_BLOCKED) {
+		    /* ...and we cannot get more now. */
+		    SetFlag(statePtr, CHANNEL_NEED_MORE_DATA);
+		    break;
+		} else {
+		    /* ... so we need to get some. */
+		    goto moreData;
+		}
+	    }
+
+	    if (bufPtr->nextPtr) {
+		/* There's a next buffer.  Shift orphan \r to it. */
+
+		ChannelBuffer *nextPtr = bufPtr->nextPtr;
+
+		nextPtr->nextRemoved -= 1;
+		RemovePoint(nextPtr)[0] = '\r';
+		bufPtr->nextRemoved++;
+	    }
+	}
+
+	if (IsBufferEmpty(bufPtr)) {
+	    statePtr->inQueueHead = bufPtr->nextPtr;
+	    if (statePtr->inQueueHead == NULL) {
+		statePtr->inQueueTail = NULL;
+	    }
+	    RecycleBuffer(statePtr, bufPtr, 0);
+	    bufPtr = statePtr->inQueueHead;
+	}
+
+	if ((GotFlag(statePtr, CHANNEL_NONBLOCKING) || allowShortReads)
+		&& GotFlag(statePtr, CHANNEL_BLOCKED)) {
+	    break;
+	}
+
+	/*
+	 * When there's no buffered data to read, and we're at EOF,
+	 * escape to the caller.
+	 */
+
+	if (GotFlag(statePtr, CHANNEL_EOF)
+		&& (bufPtr == NULL || IsBufferEmpty(bufPtr))) {
+	    break;
+	}
+    }
+    if (bytesToRead == 0) {
+	ResetFlag(statePtr, CHANNEL_BLOCKED);
+    }
+
+	assert(!GotFlag(statePtr, CHANNEL_EOF)
+		|| GotFlag(statePtr, CHANNEL_STICKY_EOF)
+		|| Tcl_InputBuffered((Tcl_Channel)chanPtr) == 0);
+	assert( !(GotFlag(statePtr, CHANNEL_EOF|CHANNEL_BLOCKED)
+		== (CHANNEL_EOF|CHANNEL_BLOCKED)) );
+    UpdateInterest(chanPtr);
+    TclChannelRelease((Tcl_Channel)chanPtr);
+    return (int)(p - dst);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * CopyEventProc --
+ *
+ *	This routine is invoked as a channel event handler for the background
+ *	copy operation. It is just a trivial wrapper around the CopyData
+ *	routine.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+CopyEventProc(
+    ClientData clientData,
+    int mask)
+{
+    (void) CopyData(clientData, mask);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * StopCopy --
+ *
+ *	This routine halts a copy that is in progress.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Removes any pending channel handlers and restores the blocking and
+ *	buffering modes of the channels. The CopyState is freed.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+StopCopy(
+    CopyState *csPtr)		/* State for bg copy to stop . */
+{
+    ChannelState *inStatePtr, *outStatePtr;
+    Tcl_Channel inChan, outChan;
+
+    int nonBlocking;
+
+    if (!csPtr) {
+	return;
+    }
+
+    inChan = (Tcl_Channel) csPtr->readPtr;
+    outChan = (Tcl_Channel) csPtr->writePtr;
+    inStatePtr = csPtr->readPtr->state;
+    outStatePtr = csPtr->writePtr->state;
+
+    /*
+     * Restore the old blocking mode and output buffering mode.
+     */
+
+    nonBlocking = csPtr->readFlags & CHANNEL_NONBLOCKING;
+    if (nonBlocking != (inStatePtr->flags & CHANNEL_NONBLOCKING)) {
+	SetBlockMode(NULL, csPtr->readPtr,
+		nonBlocking ? TCL_MODE_NONBLOCKING : TCL_MODE_BLOCKING);
+    }
+    if (csPtr->readPtr != csPtr->writePtr) {
+	nonBlocking = csPtr->writeFlags & CHANNEL_NONBLOCKING;
+	if (nonBlocking != (outStatePtr->flags & CHANNEL_NONBLOCKING)) {
+	    SetBlockMode(NULL, csPtr->writePtr,
+		    nonBlocking ? TCL_MODE_NONBLOCKING : TCL_MODE_BLOCKING);
+	}
+    }
+    ResetFlag(outStatePtr, CHANNEL_LINEBUFFERED | CHANNEL_UNBUFFERED);
+    outStatePtr->flags |=
+	    csPtr->writeFlags & (CHANNEL_LINEBUFFERED | CHANNEL_UNBUFFERED);
+
+    if (csPtr->cmdPtr) {
+	Tcl_DeleteChannelHandler(inChan, CopyEventProc, csPtr);
+	if (inChan != outChan) {
+	    Tcl_DeleteChannelHandler(outChan, CopyEventProc, csPtr);
+	}
+	Tcl_DeleteChannelHandler(inChan, MBEvent, csPtr);
+	Tcl_DeleteChannelHandler(outChan, MBEvent, csPtr);
+	TclDecrRefCount(csPtr->cmdPtr);
+    }
+    inStatePtr->csPtrR = NULL;
+    outStatePtr->csPtrW = NULL;
+    ckfree(csPtr);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * StackSetBlockMode --
+ *
+ *	This function sets the blocking mode for a channel, iterating through
+ *	each channel in a stack and updates the state flags.
+ *
+ * Results:
+ *	0 if OK, result code from failed blockModeProc otherwise.
+ *
+ * Side effects:
+ *	Modifies the blocking mode of the channel and possibly generates an
+ *	error.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+StackSetBlockMode(
+    Channel *chanPtr,		/* Channel to modify. */
+    int mode)			/* One of TCL_MODE_BLOCKING or
+				 * TCL_MODE_NONBLOCKING. */
+{
+    int result = 0;
+    Tcl_DriverBlockModeProc *blockModeProc;
+    ChannelState *statePtr = chanPtr->state;
+
+    /*
+     * Start at the top of the channel stack
+     * TODO: Examine what can go wrong when blockModeProc calls
+     * disturb the stacking state of the channel.
+     */
+
+    chanPtr = statePtr->topChanPtr;
+    while (chanPtr != NULL) {
+	blockModeProc = Tcl_ChannelBlockModeProc(chanPtr->typePtr);
+	if (blockModeProc != NULL) {
+	    result = blockModeProc(chanPtr->instanceData, mode);
+	    if (result != 0) {
+		Tcl_SetErrno(result);
+		return result;
+	    }
+	}
+	chanPtr = chanPtr->downChanPtr;
+    }
+    return 0;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * SetBlockMode --
+ *
+ *	This function sets the blocking mode for a channel and updates the
+ *	state flags.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	Modifies the blocking mode of the channel and possibly generates an
+ *	error.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+SetBlockMode(
+    Tcl_Interp *interp,		/* Interp for error reporting. */
+    Channel *chanPtr,		/* Channel to modify. */
+    int mode)			/* One of TCL_MODE_BLOCKING or
+				 * TCL_MODE_NONBLOCKING. */
+{
+    int result = 0;
+    ChannelState *statePtr = chanPtr->state;
+				/* State info for channel */
+
+    result = StackSetBlockMode(chanPtr, mode);
+    if (result != 0) {
+	if (interp != NULL) {
+	    /*
+	     * TIP #219.
+	     * Move error messages put by the driver into the bypass area and
+	     * put them into the regular interpreter result. Fall back to the
+	     * regular message if nothing was found in the bypass.
+	     *
+	     * Note that we cannot have a message in the interpreter bypass
+	     * area, StackSetBlockMode is restricted to the channel bypass.
+	     * We still need the interp as the destination of the move.
+	     */
+
+	    if (!TclChanCaughtErrorBypass(interp, (Tcl_Channel) chanPtr)) {
+		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+                        "error setting blocking mode: %s",
+			Tcl_PosixError(interp)));
+	    }
+	} else {
+	    /*
+	     * TIP #219.
+	     * If we have no interpreter to put a bypass message into we have
+	     * to clear it, to prevent its propagation and use in other places
+	     * unrelated to the actual occurence of the problem.
+	     */
+
+	    Tcl_SetChannelError((Tcl_Channel) chanPtr, NULL);
+	}
+	return TCL_ERROR;
+    }
+    if (mode == TCL_MODE_BLOCKING) {
+	ResetFlag(statePtr, CHANNEL_NONBLOCKING | BG_FLUSH_SCHEDULED);
+    } else {
+	SetFlag(statePtr, CHANNEL_NONBLOCKING);
+    }
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_GetChannelNames --
+ *
+ *	Return the names of all open channels in the interp.
+ *
+ * Results:
+ *	TCL_OK or TCL_ERROR.
+ *
+ * Side effects:
+ *	Interp result modified with list of channel names.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_GetChannelNames(
+    Tcl_Interp *interp)		/* Interp for error reporting. */
+{
+    return Tcl_GetChannelNamesEx(interp, NULL);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_GetChannelNamesEx --
+ *
+ *	Return the names of open channels in the interp filtered filtered
+ *	through a pattern. If pattern is NULL, it returns all the open
+ *	channels.
+ *
+ * Results:
+ *	TCL_OK or TCL_ERROR.
+ *
+ * Side effects:
+ *	Interp result modified with list of channel names.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_GetChannelNamesEx(
+    Tcl_Interp *interp,		/* Interp for error reporting. */
+    const char *pattern)	/* Pattern to filter on. */
+{
+    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+    ChannelState *statePtr;
+    const char *name;		/* Name for channel */
+    Tcl_Obj *resultPtr;		/* Pointer to result object */
+    Tcl_HashTable *hTblPtr;	/* Hash table of channels. */
+    Tcl_HashEntry *hPtr;	/* Search variable. */
+    Tcl_HashSearch hSearch;	/* Search variable. */
+
+    if (interp == NULL) {
+	return TCL_OK;
+    }
+
+    /*
+     * Get the channel table that stores the channels registered for this
+     * interpreter.
+     */
+
+    hTblPtr = GetChannelTable(interp);
+    TclNewObj(resultPtr);
+    if ((pattern != NULL) && TclMatchIsTrivial(pattern)
+	    && !((pattern[0] == 's') && (pattern[1] == 't')
+	    && (pattern[2] == 'd'))) {
+	if ((Tcl_FindHashEntry(hTblPtr, pattern) != NULL)
+		&& (Tcl_ListObjAppendElement(interp, resultPtr,
+		Tcl_NewStringObj(pattern, -1)) != TCL_OK)) {
+	    goto error;
+	}
+	goto done;
+    }
+
+    for (hPtr = Tcl_FirstHashEntry(hTblPtr, &hSearch); hPtr != NULL;
+	    hPtr = Tcl_NextHashEntry(&hSearch)) {
+	statePtr = ((Channel *) Tcl_GetHashValue(hPtr))->state;
+
+	if (statePtr->topChanPtr == (Channel *) tsdPtr->stdinChannel) {
+	    name = "stdin";
+	} else if (statePtr->topChanPtr == (Channel *) tsdPtr->stdoutChannel) {
+	    name = "stdout";
+	} else if (statePtr->topChanPtr == (Channel *) tsdPtr->stderrChannel) {
+	    name = "stderr";
+	} else {
+	    /*
+	     * This is also stored in Tcl_GetHashKey(hTblPtr, hPtr), but it's
+	     * simpler to just grab the name from the statePtr.
+	     */
+
+	    name = statePtr->channelName;
+	}
+
+	if (((pattern == NULL) || Tcl_StringMatch(name, pattern)) &&
+		(Tcl_ListObjAppendElement(interp, resultPtr,
+			Tcl_NewStringObj(name, -1)) != TCL_OK)) {
+	error:
+	    TclDecrRefCount(resultPtr);
+	    return TCL_ERROR;
+	}
+    }
+
+  done:
+    Tcl_SetObjResult(interp, resultPtr);
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_IsChannelRegistered --
+ *
+ *	Checks whether the channel is associated with the interp. See also
+ *	Tcl_RegisterChannel and Tcl_UnregisterChannel.
+ *
+ * Results:
+ *	0 if the channel is not registered in the interpreter, 1 else.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_IsChannelRegistered(
+    Tcl_Interp *interp,		/* The interp to query of the channel */
+    Tcl_Channel chan)		/* The channel to check */
+{
+    Tcl_HashTable *hTblPtr;	/* Hash table of channels. */
+    Tcl_HashEntry *hPtr;	/* Search variable. */
+    Channel *chanPtr;		/* The real IO channel. */
+    ChannelState *statePtr;	/* State of the real channel. */
+
+    /*
+     * Always check bottom-most channel in the stack. This is the one that
+     * gets registered.
+     */
+
+    chanPtr = ((Channel *) chan)->state->bottomChanPtr;
+    statePtr = chanPtr->state;
+
+    hTblPtr = Tcl_GetAssocData(interp, "tclIO", NULL);
+    if (hTblPtr == NULL) {
+	return 0;
+    }
+    hPtr = Tcl_FindHashEntry(hTblPtr, statePtr->channelName);
+    if (hPtr == NULL) {
+	return 0;
+    }
+    if ((Channel *) Tcl_GetHashValue(hPtr) != chanPtr) {
+	return 0;
+    }
+
+    return 1;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_IsChannelShared --
+ *
+ *	Checks whether the channel is shared by multiple interpreters.
+ *
+ * Results:
+ *	A boolean value (0 = Not shared, 1 = Shared).
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_IsChannelShared(
+    Tcl_Channel chan)		/* The channel to query */
+{
+    ChannelState *statePtr = ((Channel *) chan)->state;
+				/* State of real channel structure. */
+
+    return ((statePtr->refCount > 1) ? 1 : 0);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_IsChannelExisting --
+ *
+ *	Checks whether a channel of the given name exists in the
+ *	(thread)-global list of all channels. See Tcl_GetChannelNamesEx for
+ *	function exposed at the Tcl level.
+ *
+ * Results:
+ *	A boolean value (0 = Does not exist, 1 = Does exist).
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_IsChannelExisting(
+    const char *chanName)	/* The name of the channel to look for. */
+{
+    ChannelState *statePtr;
+    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+    const char *name;
+    int chanNameLen;
+
+    chanNameLen = strlen(chanName);
+    for (statePtr = tsdPtr->firstCSPtr; statePtr != NULL;
+	    statePtr = statePtr->nextCSPtr) {
+	if (statePtr->topChanPtr == (Channel *) tsdPtr->stdinChannel) {
+	    name = "stdin";
+	} else if (statePtr->topChanPtr == (Channel *) tsdPtr->stdoutChannel) {
+	    name = "stdout";
+	} else if (statePtr->topChanPtr == (Channel *) tsdPtr->stderrChannel) {
+	    name = "stderr";
+	} else {
+	    name = statePtr->channelName;
+	}
+
+	if ((*chanName == *name) &&
+		(memcmp(name, chanName, (size_t) chanNameLen + 1) == 0)) {
+	    return 1;
+	}
+    }
+
+    return 0;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_ChannelName --
+ *
+ *	Return the name of the channel type.
+ *
+ * Results:
+ *	A pointer the name of the channel type.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+const char *
+Tcl_ChannelName(
+    const Tcl_ChannelType *chanTypePtr) /* Pointer to channel type. */
+{
+    return chanTypePtr->typeName;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_ChannelVersion --
+ *
+ *	Return the of version of the channel type.
+ *
+ * Results:
+ *	One of the TCL_CHANNEL_VERSION_* constants from tcl.h
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_ChannelTypeVersion
+Tcl_ChannelVersion(
+    const Tcl_ChannelType *chanTypePtr)
+				/* Pointer to channel type. */
+{
+    if (chanTypePtr->version == TCL_CHANNEL_VERSION_2) {
+	return TCL_CHANNEL_VERSION_2;
+    } else if (chanTypePtr->version == TCL_CHANNEL_VERSION_3) {
+	return TCL_CHANNEL_VERSION_3;
+    } else if (chanTypePtr->version == TCL_CHANNEL_VERSION_4) {
+	return TCL_CHANNEL_VERSION_4;
+    } else if (chanTypePtr->version == TCL_CHANNEL_VERSION_5) {
+	return TCL_CHANNEL_VERSION_5;
+    } else {
+	/*
+	 * In <v2 channel versions, the version field is occupied by the
+	 * Tcl_DriverBlockModeProc
+	 */
+
+	return TCL_CHANNEL_VERSION_1;
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * HaveVersion --
+ *
+ *	Return whether a channel type is (at least) of a given version.
+ *
+ * Results:
+ *	True if the minimum version is exceeded by the version actually
+ *	present.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+HaveVersion(
+    const Tcl_ChannelType *chanTypePtr,
+    Tcl_ChannelTypeVersion minimumVersion)
+{
+    Tcl_ChannelTypeVersion actualVersion = Tcl_ChannelVersion(chanTypePtr);
+
+    return (PTR2INT(actualVersion)) >= (PTR2INT(minimumVersion));
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_ChannelBlockModeProc --
+ *
+ *	Return the Tcl_DriverBlockModeProc of the channel type.
+ *
+ * Results:
+ *	A pointer to the proc.
+ *
+ * Side effects:
+ *	None.
+ *
+ *---------------------------------------------------------------------- */
+
+Tcl_DriverBlockModeProc *
+Tcl_ChannelBlockModeProc(
+    const Tcl_ChannelType *chanTypePtr)
+				/* Pointer to channel type. */
+{
+    if (HaveVersion(chanTypePtr, TCL_CHANNEL_VERSION_2)) {
+	return chanTypePtr->blockModeProc;
+    }
+
+    /*
+     * The v1 structure had the blockModeProc in a different place.
+     */
+
+    return (Tcl_DriverBlockModeProc *) chanTypePtr->version;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_ChannelCloseProc --
+ *
+ *	Return the Tcl_DriverCloseProc of the channel type.
+ *
+ * Results:
+ *	A pointer to the proc.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_DriverCloseProc *
+Tcl_ChannelCloseProc(
+    const Tcl_ChannelType *chanTypePtr)
+				/* Pointer to channel type. */
+{
+    return chanTypePtr->closeProc;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_ChannelClose2Proc --
+ *
+ *	Return the Tcl_DriverClose2Proc of the channel type.
+ *
+ * Results:
+ *	A pointer to the proc.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_DriverClose2Proc *
+Tcl_ChannelClose2Proc(
+    const Tcl_ChannelType *chanTypePtr)
+				/* Pointer to channel type. */
+{
+    return chanTypePtr->close2Proc;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_ChannelInputProc --
+ *
+ *	Return the Tcl_DriverInputProc of the channel type.
+ *
+ * Results:
+ *	A pointer to the proc.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_DriverInputProc *
+Tcl_ChannelInputProc(
+    const Tcl_ChannelType *chanTypePtr)
+				/* Pointer to channel type. */
+{
+    return chanTypePtr->inputProc;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_ChannelOutputProc --
+ *
+ *	Return the Tcl_DriverOutputProc of the channel type.
+ *
+ * Results:
+ *	A pointer to the proc.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_DriverOutputProc *
+Tcl_ChannelOutputProc(
+    const Tcl_ChannelType *chanTypePtr)
+				/* Pointer to channel type. */
+{
+    return chanTypePtr->outputProc;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_ChannelSeekProc --
+ *
+ *	Return the Tcl_DriverSeekProc of the channel type.
+ *
+ * Results:
+ *	A pointer to the proc.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_DriverSeekProc *
+Tcl_ChannelSeekProc(
+    const Tcl_ChannelType *chanTypePtr)
+				/* Pointer to channel type. */
+{
+    return chanTypePtr->seekProc;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_ChannelSetOptionProc --
+ *
+ *	Return the Tcl_DriverSetOptionProc of the channel type.
+ *
+ * Results:
+ *	A pointer to the proc.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_DriverSetOptionProc *
+Tcl_ChannelSetOptionProc(
+    const Tcl_ChannelType *chanTypePtr)
+				/* Pointer to channel type. */
+{
+    return chanTypePtr->setOptionProc;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_ChannelGetOptionProc --
+ *
+ *	Return the Tcl_DriverGetOptionProc of the channel type.
+ *
+ * Results:
+ *	A pointer to the proc.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_DriverGetOptionProc *
+Tcl_ChannelGetOptionProc(
+    const Tcl_ChannelType *chanTypePtr)
+				/* Pointer to channel type. */
+{
+    return chanTypePtr->getOptionProc;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_ChannelWatchProc --
+ *
+ *	Return the Tcl_DriverWatchProc of the channel type.
+ *
+ * Results:
+ *	A pointer to the proc.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_DriverWatchProc *
+Tcl_ChannelWatchProc(
+    const Tcl_ChannelType *chanTypePtr)
+				/* Pointer to channel type. */
+{
+    return chanTypePtr->watchProc;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_ChannelGetHandleProc --
+ *
+ *	Return the Tcl_DriverGetHandleProc of the channel type.
+ *
+ * Results:
+ *	A pointer to the proc.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_DriverGetHandleProc *
+Tcl_ChannelGetHandleProc(
+    const Tcl_ChannelType *chanTypePtr)
+				/* Pointer to channel type. */
+{
+    return chanTypePtr->getHandleProc;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_ChannelFlushProc --
+ *
+ *	Return the Tcl_DriverFlushProc of the channel type.
+ *
+ * Results:
+ *	A pointer to the proc.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_DriverFlushProc *
+Tcl_ChannelFlushProc(
+    const Tcl_ChannelType *chanTypePtr)
+				/* Pointer to channel type. */
+{
+    if (HaveVersion(chanTypePtr, TCL_CHANNEL_VERSION_2)) {
+	return chanTypePtr->flushProc;
+    }
+    return NULL;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_ChannelHandlerProc --
+ *
+ *	Return the Tcl_DriverHandlerProc of the channel type.
+ *
+ * Results:
+ *	A pointer to the proc.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_DriverHandlerProc *
+Tcl_ChannelHandlerProc(
+    const Tcl_ChannelType *chanTypePtr)
+				/* Pointer to channel type. */
+{
+    if (HaveVersion(chanTypePtr, TCL_CHANNEL_VERSION_2)) {
+	return chanTypePtr->handlerProc;
+    }
+    return NULL;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_ChannelWideSeekProc --
+ *
+ *	Return the Tcl_DriverWideSeekProc of the channel type.
+ *
+ * Results:
+ *	A pointer to the proc.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_DriverWideSeekProc *
+Tcl_ChannelWideSeekProc(
+    const Tcl_ChannelType *chanTypePtr)
+				/* Pointer to channel type. */
+{
+    if (HaveVersion(chanTypePtr, TCL_CHANNEL_VERSION_3)) {
+	return chanTypePtr->wideSeekProc;
+    }
+    return NULL;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_ChannelThreadActionProc --
+ *
+ *	TIP #218, Channel Thread Actions. Return the
+ *	Tcl_DriverThreadActionProc of the channel type.
+ *
+ * Results:
+ *	A pointer to the proc.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_DriverThreadActionProc *
+Tcl_ChannelThreadActionProc(
+    const Tcl_ChannelType *chanTypePtr)
+				/* Pointer to channel type. */
+{
+    if (HaveVersion(chanTypePtr, TCL_CHANNEL_VERSION_4)) {
+	return chanTypePtr->threadActionProc;
+    }
+    return NULL;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_SetChannelErrorInterp --
+ *
+ *	TIP #219, Tcl Channel Reflection API.
+ *	Store an error message for the I/O system.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Discards a previously stored message.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_SetChannelErrorInterp(
+    Tcl_Interp *interp,		/* Interp to store the data into. */
+    Tcl_Obj *msg)		/* Error message to store. */
+{
+    Interp *iPtr = (Interp *) interp;
+
+    if (iPtr->chanMsg != NULL) {
+	TclDecrRefCount(iPtr->chanMsg);
+	iPtr->chanMsg = NULL;
+    }
+
+    if (msg != NULL) {
+	iPtr->chanMsg = FixLevelCode(msg);
+	Tcl_IncrRefCount(iPtr->chanMsg);
+    }
+    return;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_SetChannelError --
+ *
+ *	TIP #219, Tcl Channel Reflection API.
+ *	Store an error message for the I/O system.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Discards a previously stored message.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_SetChannelError(
+    Tcl_Channel chan,		/* Channel to store the data into. */
+    Tcl_Obj *msg)		/* Error message to store. */
+{
+    ChannelState *statePtr = ((Channel *) chan)->state;
+
+    if (statePtr->chanMsg != NULL) {
+	TclDecrRefCount(statePtr->chanMsg);
+	statePtr->chanMsg = NULL;
+    }
+
+    if (msg != NULL) {
+	statePtr->chanMsg = FixLevelCode(msg);
+	Tcl_IncrRefCount(statePtr->chanMsg);
+    }
+    return;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * FixLevelCode --
+ *
+ *	TIP #219, Tcl Channel Reflection API.
+ *	Scans an error message for bad -code / -level directives. Returns a
+ *	modified copy with such directives corrected, and the input if it had
+ *	no problems.
+ *
+ * Results:
+ *	A Tcl_Obj*
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static Tcl_Obj *
+FixLevelCode(
+    Tcl_Obj *msg)
+{
+    int explicitResult, numOptions, lc, lcn;
+    Tcl_Obj **lv, **lvn;
+    int res, i, j, val, lignore, cignore;
+    int newlevel = -1, newcode = -1;
+
+    /* ASSERT msg != NULL */
+
+    /*
+     * Process the caught message.
+     *
+     * Syntax = (option value)... ?message?
+     *
+     * Bad message syntax causes a panic, because the other side uses
+     * Tcl_GetReturnOptions and list construction functions to marshall the
+     * information. Hence an error means that we've got serious breakage.
+     */
+
+    res = Tcl_ListObjGetElements(NULL, msg, &lc, &lv);
+    if (res != TCL_OK) {
+	Tcl_Panic("Tcl_SetChannelError: bad syntax of message");
+    }
+
+    explicitResult = (1 == (lc % 2));
+    numOptions = lc - explicitResult;
+
+    /*
+     * No options, nothing to do.
+     */
+
+    if (numOptions == 0) {
+	return msg;
+    }
+
+    /*
+     * Check for -code x, x != 1|error, and -level x, x != 0
+     */
+
+    for (i = 0; i < numOptions; i += 2) {
+	if (0 == strcmp(TclGetString(lv[i]), "-code")) {
+	    /*
+	     * !"error", !integer, integer != 1 (numeric code for error)
+	     */
+
+	    res = TclGetIntFromObj(NULL, lv[i+1], &val);
+	    if (((res == TCL_OK) && (val != 1)) || ((res != TCL_OK) &&
+		    (0 != strcmp(TclGetString(lv[i+1]), "error")))) {
+		newcode = 1;
+	    }
+	} else if (0 == strcmp(TclGetString(lv[i]), "-level")) {
+	    /*
+	     * !integer, integer != 0
+	     */
+
+	    res = TclGetIntFromObj(NULL, lv [i+1], &val);
+	    if ((res != TCL_OK) || (val != 0)) {
+		newlevel = 0;
+	    }
+	}
+    }
+
+    /*
+     * -code, -level are either not present or ok. Nothing to do.
+     */
+
+    if ((newlevel < 0) && (newcode < 0)) {
+	return msg;
+    }
+
+    lcn = numOptions;
+    if (explicitResult) {
+	lcn ++;
+    }
+    if (newlevel >= 0) {
+	lcn += 2;
+    }
+    if (newcode >= 0) {
+	lcn += 2;
+    }
+
+    lvn = ckalloc(lcn * sizeof(Tcl_Obj *));
+
+    /*
+     * New level/code information is spliced into the first occurence of
+     * -level, -code, further occurences are ignored. The options cannot be
+     * not present, we would not come here. Options which are ok are simply
+     * copied over.
+     */
+
+    lignore = cignore = 0;
+    for (i=0, j=0; i<numOptions; i+=2) {
+	if (0 == strcmp(TclGetString(lv[i]), "-level")) {
+	    if (newlevel >= 0) {
+		lvn[j++] = lv[i];
+		lvn[j++] = Tcl_NewIntObj(newlevel);
+		newlevel = -1;
+		lignore = 1;
+		continue;
+	    } else if (lignore) {
+		continue;
+	    }
+	} else if (0 == strcmp(TclGetString(lv[i]), "-code")) {
+	    if (newcode >= 0) {
+		lvn[j++] = lv[i];
+		lvn[j++] = Tcl_NewIntObj(newcode);
+		newcode = -1;
+		cignore = 1;
+		continue;
+	    } else if (cignore) {
+		continue;
+	    }
+	}
+
+	/*
+	 * Keep everything else, possibly copied down.
+	 */
+
+	lvn[j++] = lv[i];
+	lvn[j++] = lv[i+1];
+    }
+    if (newlevel >= 0) {
+	Tcl_Panic("Defined newlevel not used in rewrite");
+    }
+    if (newcode >= 0) {
+	Tcl_Panic("Defined newcode not used in rewrite");
+    }
+
+    if (explicitResult) {
+	lvn[j++] = lv[i];
+    }
+
+    msg = Tcl_NewListObj(j, lvn);
+
+    ckfree(lvn);
+    return msg;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_GetChannelErrorInterp --
+ *
+ *	TIP #219, Tcl Channel Reflection API.
+ *	Return the message stored by the channel driver.
+ *
+ * Results:
+ *	Tcl error message object.
+ *
+ * Side effects:
+ *	Resets the stored data to NULL.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_GetChannelErrorInterp(
+    Tcl_Interp *interp,		/* Interp to query. */
+    Tcl_Obj **msg)		/* Place for error message. */
+{
+    Interp *iPtr = (Interp *) interp;
+
+    *msg = iPtr->chanMsg;
+    iPtr->chanMsg = NULL;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_GetChannelError --
+ *
+ *	TIP #219, Tcl Channel Reflection API.
+ *	Return the message stored by the channel driver.
+ *
+ * Results:
+ *	Tcl error message object.
+ *
+ * Side effects:
+ *	Resets the stored data to NULL.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_GetChannelError(
+    Tcl_Channel chan,		/* Channel to query. */
+    Tcl_Obj **msg)		/* Place for error message. */
+{
+    ChannelState *statePtr = ((Channel *) chan)->state;
+
+    *msg = statePtr->chanMsg;
+    statePtr->chanMsg = NULL;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_ChannelTruncateProc --
+ *
+ *	TIP #208 (subsection relating to truncation, based on TIP #206).
+ *	Return the Tcl_DriverTruncateProc of the channel type.
+ *
+ * Results:
+ *	A pointer to the proc.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_DriverTruncateProc *
+Tcl_ChannelTruncateProc(
+    const Tcl_ChannelType *chanTypePtr)
+				/* Pointer to channel type. */
+{
+    if (HaveVersion(chanTypePtr, TCL_CHANNEL_VERSION_5)) {
+	return chanTypePtr->truncateProc;
+    }
+    return NULL;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * DupChannelIntRep --
+ *
+ *	Initialize the internal representation of a new Tcl_Obj to a copy of
+ *	the internal representation of an existing string object.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	copyPtr's internal rep is set to a copy of srcPtr's internal
+ *	representation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+DupChannelIntRep(
+    register Tcl_Obj *srcPtr,	/* Object with internal rep to copy. Must have
+				 * an internal rep of type "Channel". */
+    register Tcl_Obj *copyPtr)	/* Object with internal rep to set. Must not
+				 * currently have an internal rep.*/
+{
+    ResolvedChanName *resPtr = srcPtr->internalRep.twoPtrValue.ptr1;
+
+    resPtr->refCount++;
+    copyPtr->internalRep.twoPtrValue.ptr1 = resPtr;
+    copyPtr->typePtr = srcPtr->typePtr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * FreeChannelIntRep --
+ *
+ *	Release statePtr storage.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	May cause state to be freed.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+FreeChannelIntRep(
+    Tcl_Obj *objPtr)		/* Object with internal rep to free. */
+{
+    ResolvedChanName *resPtr = objPtr->internalRep.twoPtrValue.ptr1;
+
+    objPtr->typePtr = NULL;
+    if (--resPtr->refCount) {
+	return;
+    }
+    Tcl_Release(resPtr->statePtr);
+    ckfree(resPtr);
+}
+
+#if 0
+/*
+ * For future debugging work, a simple function to print the flags of a
+ * channel in semi-readable form.
+ */
+
+static int
+DumpFlags(
+    char *str,
+    int flags)
+{
+    char buf[20];
+    int i = 0;
+
+#define ChanFlag(chr, bit)      (buf[i++] = ((flags & (bit)) ? (chr) : '_'))
+
+    ChanFlag('r', TCL_READABLE);
+    ChanFlag('w', TCL_WRITABLE);
+    ChanFlag('n', CHANNEL_NONBLOCKING);
+    ChanFlag('l', CHANNEL_LINEBUFFERED);
+    ChanFlag('u', CHANNEL_UNBUFFERED);
+    ChanFlag('F', BG_FLUSH_SCHEDULED);
+    ChanFlag('c', CHANNEL_CLOSED);
+    ChanFlag('E', CHANNEL_EOF);
+    ChanFlag('S', CHANNEL_STICKY_EOF);
+    ChanFlag('B', CHANNEL_BLOCKED);
+    ChanFlag('/', INPUT_SAW_CR);
+    ChanFlag('D', CHANNEL_DEAD);
+    ChanFlag('R', CHANNEL_RAW_MODE);
+    ChanFlag('x', CHANNEL_INCLOSE);
+
+    buf[i] ='\0';
+
+    fprintf(stderr, "%s: %s\n", str, buf);
+    return 0;
+}
+#endif
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/generic/tclIO.h b/generic/tclIO.h
new file mode 100644
index 0000000..ffbfa31
--- /dev/null
+++ b/generic/tclIO.h
@@ -0,0 +1,297 @@
+/*
+ * tclIO.h --
+ *
+ *	This file provides the generic portions (those that are the same on
+ *	all platforms and for all channel types) of Tcl's IO facilities.
+ *
+ * Copyright (c) 1998-2000 Ajuba Solutions
+ * Copyright (c) 1995-1997 Sun Microsystems, Inc.
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+/*
+ * Make sure that both EAGAIN and EWOULDBLOCK are defined. This does not
+ * compile on systems where neither is defined. We want both defined so that
+ * we can test safely for both. In the code we still have to test for both
+ * because there may be systems on which both are defined and have different
+ * values.
+ */
+
+#if ((!defined(EWOULDBLOCK)) && (defined(EAGAIN)))
+#   define EWOULDBLOCK EAGAIN
+#endif
+#if ((!defined(EAGAIN)) && (defined(EWOULDBLOCK)))
+#   define EAGAIN EWOULDBLOCK
+#endif
+#if ((!defined(EAGAIN)) && (!defined(EWOULDBLOCK)))
+#error one of EWOULDBLOCK or EAGAIN must be defined
+#endif
+
+/*
+ * struct ChannelBuffer:
+ *
+ * Buffers data being sent to or from a channel.
+ */
+
+typedef struct ChannelBuffer {
+    int refCount;		/* Current uses count */
+    int nextAdded;		/* The next position into which a character
+				 * will be put in the buffer. */
+    int nextRemoved;		/* Position of next byte to be removed from
+				 * the buffer. */
+    int bufLength;		/* How big is the buffer? */
+    struct ChannelBuffer *nextPtr;
+    				/* Next buffer in chain. */
+    char buf[1];		/* Placeholder for real buffer. The real
+				 * buffer occuppies this space + bufSize-1
+				 * bytes. This must be the last field in the
+				 * structure. */
+} ChannelBuffer;
+
+#define CHANNELBUFFER_HEADER_SIZE	TclOffset(ChannelBuffer, buf)
+
+/*
+ * How much extra space to allocate in buffer to hold bytes from previous
+ * buffer (when converting to UTF-8) or to hold bytes that will go to next
+ * buffer (when converting from UTF-8).
+ */
+
+#define BUFFER_PADDING		16
+
+/*
+ * The following defines the *default* buffer size for channels.
+ */
+
+#define CHANNELBUFFER_DEFAULT_SIZE	(1024 * 4)
+
+/*
+ * The following structure describes the information saved from a call to
+ * "fileevent". This is used later when the event being waited for to invoke
+ * the saved script in the interpreter designed in this record.
+ */
+
+typedef struct EventScriptRecord {
+    struct Channel *chanPtr;	/* The channel for which this script is
+				 * registered. This is used only when an error
+				 * occurs during evaluation of the script, to
+				 * delete the handler. */
+    Tcl_Obj *scriptPtr;		/* Script to invoke. */
+    Tcl_Interp *interp;		/* In what interpreter to invoke script? */
+    int mask;			/* Events must overlap current mask for the
+				 * stored script to be invoked. */
+    struct EventScriptRecord *nextPtr;
+				/* Next in chain of records. */
+} EventScriptRecord;
+
+/*
+ * struct Channel:
+ *
+ * One of these structures is allocated for each open channel. It contains
+ * data specific to the channel but which belongs to the generic part of the
+ * Tcl channel mechanism, and it points at an instance specific (and type
+ * specific) instance data, and at a channel type structure.
+ */
+
+typedef struct Channel {
+    struct ChannelState *state; /* Split out state information */
+    ClientData instanceData;	/* Instance-specific data provided by creator
+				 * of channel. */
+    const Tcl_ChannelType *typePtr; /* Pointer to channel type structure. */
+    struct Channel *downChanPtr;/* Refers to channel this one was stacked
+				 * upon. This reference is NULL for normal
+				 * channels. See Tcl_StackChannel. */
+    struct Channel *upChanPtr;	/* Refers to the channel above stacked this
+				 * one. NULL for the top most channel. */
+
+    /*
+     * Intermediate buffers to hold pre-read data for consumption by a newly
+     * stacked transformation. See 'Tcl_StackChannel'.
+     */
+
+    ChannelBuffer *inQueueHead;	/* Points at first buffer in input queue. */
+    ChannelBuffer *inQueueTail;	/* Points at last buffer in input queue. */
+
+    int refCount;
+} Channel;
+
+/*
+ * struct ChannelState:
+ *
+ * One of these structures is allocated for each open channel. It contains
+ * data specific to the channel but which belongs to the generic part of the
+ * Tcl channel mechanism, and it points at an instance specific (and type
+ * specific) instance data, and at a channel type structure.
+ */
+
+typedef struct ChannelState {
+    char *channelName;		/* The name of the channel instance in Tcl
+				 * commands. Storage is owned by the generic
+				 * IO code, is dynamically allocated. */
+    int	flags;			/* ORed combination of the flags defined
+				 * below. */
+    Tcl_Encoding encoding;	/* Encoding to apply when reading or writing
+				 * data on this channel. NULL means no
+				 * encoding is applied to data. */
+    Tcl_EncodingState inputEncodingState;
+				/* Current encoding state, used when
+				 * converting input data bytes to UTF-8. */
+    int inputEncodingFlags;	/* Encoding flags to pass to conversion
+				 * routine when converting input data bytes to
+				 * UTF-8. May be TCL_ENCODING_START before
+				 * converting first byte and TCL_ENCODING_END
+				 * when EOF is seen. */
+    Tcl_EncodingState outputEncodingState;
+				/* Current encoding state, used when
+				 * converting UTF-8 to output data bytes. */
+    int outputEncodingFlags;	/* Encoding flags to pass to conversion
+				 * routine when converting UTF-8 to output
+				 * data bytes. May be TCL_ENCODING_START
+				 * before converting first byte and
+				 * TCL_ENCODING_END when EOF is seen. */
+    TclEolTranslation inputTranslation;
+				/* What translation to apply for end of line
+				 * sequences on input? */
+    TclEolTranslation outputTranslation;
+				/* What translation to use for generating end
+				 * of line sequences in output? */
+    int inEofChar;		/* If nonzero, use this as a signal of EOF on
+				 * input. */
+    int outEofChar;		/* If nonzero, append this to the channel when
+				 * it is closed if it is open for writing. */
+    int unreportedError;	/* Non-zero if an error report was deferred
+				 * because it happened in the background. The
+				 * value is the POSIX error code. */
+    int refCount;		/* How many interpreters hold references to
+				 * this IO channel? */
+    struct CloseCallback *closeCbPtr;
+				/* Callbacks registered to be called when the
+				 * channel is closed. */
+    char *outputStage;		/* Temporary staging buffer used when
+				 * translating EOL before converting from
+				 * UTF-8 to external form. */
+    ChannelBuffer *curOutPtr;	/* Current output buffer being filled. */
+    ChannelBuffer *outQueueHead;/* Points at first buffer in output queue. */
+    ChannelBuffer *outQueueTail;/* Points at last buffer in output queue. */
+    ChannelBuffer *saveInBufPtr;/* Buffer saved for input queue - eliminates
+				 * need to allocate a new buffer for "gets"
+				 * that crosses buffer boundaries. */
+    ChannelBuffer *inQueueHead;	/* Points at first buffer in input queue. */
+    ChannelBuffer *inQueueTail;	/* Points at last buffer in input queue. */
+    struct ChannelHandler *chPtr;/* List of channel handlers registered for
+				  * this channel. */
+    int interestMask;		/* Mask of all events this channel has
+				 * handlers for. */
+    EventScriptRecord *scriptRecordPtr;
+				/* Chain of all scripts registered for event
+				 * handlers ("fileevent") on this channel. */
+    int bufSize;		/* What size buffers to allocate? */
+    Tcl_TimerToken timer;	/* Handle to wakeup timer for this channel. */
+    struct CopyState *csPtrR;	/* State of background copy for which channel
+				 * is input, or NULL. */
+    struct CopyState *csPtrW;	/* State of background copy for which channel
+				 * is output, or NULL. */
+    Channel *topChanPtr;	/* Refers to topmost channel in a stack. Never
+				 * NULL. */
+    Channel *bottomChanPtr;	/* Refers to bottommost channel in a stack.
+				 * This channel can be relied on to live as
+				 * long as the channel state. Never NULL. */
+    struct ChannelState *nextCSPtr;
+				/* Next in list of channels currently open. */
+    Tcl_ThreadId managingThread;/* TIP #10: Id of the thread managing this
+				 * stack of channels. */
+
+    /*
+     * TIP #219 ... Info for the I/O system ...
+     * Error message set by channel drivers, for the propagation of arbitrary
+     * Tcl errors. This information, if present (chanMsg not NULL), takes
+     * precedence over a posix error code returned by a channel operation.
+     */
+
+    Tcl_Obj* chanMsg;
+    Tcl_Obj* unreportedMsg;     /* Non-NULL if an error report was deferred
+				 * because it happened in the background. The
+				 * value is the chanMg, if any. #219's
+				 * companion to 'unreportedError'. */
+    int epoch;			/* Used to test validity of stored channelname
+				 * lookup results. */
+} ChannelState;
+
+/*
+ * Values for the flags field in Channel. Any ORed combination of the
+ * following flags can be stored in the field. These flags record various
+ * options and state bits about the channel. In addition to the flags below,
+ * the channel can also have TCL_READABLE (1<<1) and TCL_WRITABLE (1<<2) set.
+ */
+
+#define CHANNEL_NONBLOCKING	(1<<3)	/* Channel is currently in nonblocking
+					 * mode. */
+#define CHANNEL_LINEBUFFERED	(1<<4)	/* Output to the channel must be
+					 * flushed after every newline. */
+#define CHANNEL_UNBUFFERED	(1<<5)	/* Output to the channel must always
+					 * be flushed immediately. */
+#define BG_FLUSH_SCHEDULED	(1<<7)	/* A background flush of the queued
+					 * output buffers has been
+					 * scheduled. */
+#define CHANNEL_CLOSED		(1<<8)	/* Channel has been closed. No further
+					 * Tcl-level IO on the channel is
+					 * allowed. */
+#define CHANNEL_EOF		(1<<9)	/* EOF occurred on this channel. This
+					 * bit is cleared before every input
+					 * operation. */
+#define CHANNEL_STICKY_EOF	(1<<10)	/* EOF occurred on this channel
+					 * because we saw the input
+					 * eofChar. This bit prevents clearing
+					 * of the EOF bit before every input
+					 * operation. */
+#define CHANNEL_BLOCKED		(1<<11)	/* EWOULDBLOCK or EAGAIN occurred on
+					 * this channel. This bit is cleared
+					 * before every input or output
+					 * operation. */
+#define INPUT_SAW_CR		(1<<12)	/* Channel is in CRLF eol input
+					 * translation mode and the last byte
+					 * seen was a "\r". */
+#define CHANNEL_DEAD		(1<<13)	/* The channel has been closed by the
+					 * exit handler (on exit) but not
+					 * deallocated. When any IO operation
+					 * sees this flag on a channel, it
+					 * does not call driver level
+					 * functions to avoid referring to
+					 * deallocated data. */
+#define CHANNEL_NEED_MORE_DATA	(1<<14)	/* The last input operation failed
+					 * because there was not enough data
+					 * to complete the operation. This
+					 * flag is set when gets fails to get
+					 * a complete line or when read fails
+					 * to get a complete character. When
+					 * set, file events will not be
+					 * delivered for buffered data until
+					 * the state of the channel
+					 * changes. */
+#define CHANNEL_RAW_MODE	(1<<16)	/* When set, notes that the Raw API is
+					 * being used. */
+
+#define CHANNEL_INCLOSE		(1<<19)	/* Channel is currently being closed.
+					 * Its structures are still live and
+					 * usable, but it may not be closed
+					 * again from within the close
+					 * handler. */
+#define CHANNEL_CLOSEDWRITE	(1<<21)	/* Channel write side has been closed.
+					 * No further Tcl-level write IO on
+					 * the channel is allowed. */
+
+/*
+ * The length of time to wait between synthetic timer events. Must be zero or
+ * bad things tend to happen.
+ */
+
+#define SYNTHETIC_EVENT_TIME	0
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tclIOCmd.c b/generic/tclIOCmd.c
new file mode 100644
index 0000000..834f225
--- /dev/null
+++ b/generic/tclIOCmd.c
@@ -0,0 +1,2027 @@
+/*
+ * tclIOCmd.c --
+ *
+ *	Contains the definitions of most of the Tcl commands relating to IO.
+ *
+ * Copyright (c) 1995-1997 Sun Microsystems, Inc.
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#include "tclInt.h"
+
+/*
+ * Callback structure for accept callback in a TCP server.
+ */
+
+typedef struct AcceptCallback {
+    char *script;		/* Script to invoke. */
+    Tcl_Interp *interp;		/* Interpreter in which to run it. */
+} AcceptCallback;
+
+/*
+ * Thread local storage used to maintain a per-thread stdout channel obj.
+ * It must be per-thread because of std channel limitations.
+ */
+
+typedef struct ThreadSpecificData {
+    int initialized;		/* Set to 1 when the module is initialized. */
+    Tcl_Obj *stdoutObjPtr;	/* Cached stdout channel Tcl_Obj */
+} ThreadSpecificData;
+
+static Tcl_ThreadDataKey dataKey;
+
+/*
+ * Static functions for this file:
+ */
+
+static void		FinalizeIOCmdTSD(ClientData clientData);
+static void		AcceptCallbackProc(ClientData callbackData,
+			    Tcl_Channel chan, char *address, int port);
+static int		ChanPendingObjCmd(ClientData unused,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+static int		ChanTruncateObjCmd(ClientData dummy,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+static void		RegisterTcpServerInterpCleanup(Tcl_Interp *interp,
+			    AcceptCallback *acceptCallbackPtr);
+static void		TcpAcceptCallbacksDeleteProc(ClientData clientData,
+			    Tcl_Interp *interp);
+static void		TcpServerCloseProc(ClientData callbackData);
+static void		UnregisterTcpServerInterpCleanupProc(
+			    Tcl_Interp *interp,
+			    AcceptCallback *acceptCallbackPtr);
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * FinalizeIOCmdTSD --
+ *
+ *	Release the storage associated with the per-thread cache.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+FinalizeIOCmdTSD(
+    ClientData clientData)	/* Not used. */
+{
+    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+
+    if (tsdPtr->stdoutObjPtr != NULL) {
+	Tcl_DecrRefCount(tsdPtr->stdoutObjPtr);
+	tsdPtr->stdoutObjPtr = NULL;
+    }
+    tsdPtr->initialized = 0;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_PutsObjCmd --
+ *
+ *	This function is invoked to process the "puts" Tcl command. See the
+ *	user documentation for details on what it does.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	Produces output on a channel.
+ *
+ *----------------------------------------------------------------------
+ */
+
+	/* ARGSUSED */
+int
+Tcl_PutsObjCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    Tcl_Channel chan;		/* The channel to puts on. */
+    Tcl_Obj *string;		/* String to write. */
+    Tcl_Obj *chanObjPtr = NULL;	/* channel object. */
+    int newline;		/* Add a newline at end? */
+    int result;			/* Result of puts operation. */
+    int mode;			/* Mode in which channel is opened. */
+    ThreadSpecificData *tsdPtr;
+
+    switch (objc) {
+    case 2:			/* [puts $x] */
+	string = objv[1];
+	newline = 1;
+	break;
+
+    case 3:			/* [puts -nonewline $x] or [puts $chan $x] */
+	if (strcmp(TclGetString(objv[1]), "-nonewline") == 0) {
+	    newline = 0;
+	} else {
+	    newline = 1;
+	    chanObjPtr = objv[1];
+	}
+	string = objv[2];
+	break;
+
+    case 4:			/* [puts -nonewline $chan $x] or
+				 * [puts $chan $x nonewline] */
+	newline = 0;
+	if (strcmp(TclGetString(objv[1]), "-nonewline") == 0) {
+	    chanObjPtr = objv[2];
+	    string = objv[3];
+	    break;
+#if TCL_MAJOR_VERSION < 9
+	} else if (strcmp(TclGetString(objv[3]), "nonewline") == 0) {
+	    /*
+	     * The code below provides backwards compatibility with an old
+	     * form of the command that is no longer recommended or
+	     * documented. See also [Bug #3151675]. Will be removed in Tcl 9,
+	     * maybe even earlier.
+	     */
+
+	    chanObjPtr = objv[1];
+	    string = objv[2];
+	    break;
+#endif
+	}
+	/* Fall through */
+    default:			/* [puts] or
+				 * [puts some bad number of arguments...] */
+	Tcl_WrongNumArgs(interp, 1, objv, "?-nonewline? ?channelId? string");
+	return TCL_ERROR;
+    }
+
+    if (chanObjPtr == NULL) {
+	tsdPtr = TCL_TSD_INIT(&dataKey);
+
+	if (!tsdPtr->initialized) {
+	    tsdPtr->initialized = 1;
+	    TclNewLiteralStringObj(tsdPtr->stdoutObjPtr, "stdout");
+	    Tcl_IncrRefCount(tsdPtr->stdoutObjPtr);
+	    Tcl_CreateThreadExitHandler(FinalizeIOCmdTSD, NULL);
+	}
+	chanObjPtr = tsdPtr->stdoutObjPtr;
+    }
+    if (TclGetChannelFromObj(interp, chanObjPtr, &chan, &mode, 0) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    if (!(mode & TCL_WRITABLE)) {
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		"channel \"%s\" wasn't opened for writing",
+		TclGetString(chanObjPtr)));
+	return TCL_ERROR;
+    }
+
+    TclChannelPreserve(chan);
+    result = Tcl_WriteObj(chan, string);
+    if (result < 0) {
+	goto error;
+    }
+    if (newline != 0) {
+	result = Tcl_WriteChars(chan, "\n", 1);
+	if (result < 0) {
+	    goto error;
+	}
+    }
+    TclChannelRelease(chan);
+    return TCL_OK;
+
+    /*
+     * TIP #219.
+     * Capture error messages put by the driver into the bypass area and put
+     * them into the regular interpreter result. Fall back to the regular
+     * message if nothing was found in the bypass.
+     */
+
+  error:
+    if (!TclChanCaughtErrorBypass(interp, chan)) {
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf("error writing \"%s\": %s",
+		TclGetString(chanObjPtr), Tcl_PosixError(interp)));
+    }
+    TclChannelRelease(chan);
+    return TCL_ERROR;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_FlushObjCmd --
+ *
+ *	This function is called to process the Tcl "flush" command. See the
+ *	user documentation for details on what it does.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	May cause output to appear on the specified channel.
+ *
+ *----------------------------------------------------------------------
+ */
+
+	/* ARGSUSED */
+int
+Tcl_FlushObjCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    Tcl_Obj *chanObjPtr;
+    Tcl_Channel chan;		/* The channel to flush on. */
+    int mode;
+
+    if (objc != 2) {
+	Tcl_WrongNumArgs(interp, 1, objv, "channelId");
+	return TCL_ERROR;
+    }
+    chanObjPtr = objv[1];
+    if (TclGetChannelFromObj(interp, chanObjPtr, &chan, &mode, 0) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    if (!(mode & TCL_WRITABLE)) {
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		"channel \"%s\" wasn't opened for writing",
+		TclGetString(chanObjPtr)));
+	return TCL_ERROR;
+    }
+
+    TclChannelPreserve(chan);
+    if (Tcl_Flush(chan) != TCL_OK) {
+	/*
+	 * TIP #219.
+	 * Capture error messages put by the driver into the bypass area and
+	 * put them into the regular interpreter result. Fall back to the
+	 * regular message if nothing was found in the bypass.
+	 */
+
+	if (!TclChanCaughtErrorBypass(interp, chan)) {
+	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		    "error flushing \"%s\": %s",
+		    TclGetString(chanObjPtr), Tcl_PosixError(interp)));
+	}
+	TclChannelRelease(chan);
+	return TCL_ERROR;
+    }
+    TclChannelRelease(chan);
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_GetsObjCmd --
+ *
+ *	This function is called to process the Tcl "gets" command. See the
+ *	user documentation for details on what it does.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	May consume input from channel.
+ *
+ *----------------------------------------------------------------------
+ */
+
+	/* ARGSUSED */
+int
+Tcl_GetsObjCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    Tcl_Channel chan;		/* The channel to read from. */
+    int lineLen;		/* Length of line just read. */
+    int mode;			/* Mode in which channel is opened. */
+    Tcl_Obj *linePtr, *chanObjPtr;
+    int code = TCL_OK;
+
+    if ((objc != 2) && (objc != 3)) {
+	Tcl_WrongNumArgs(interp, 1, objv, "channelId ?varName?");
+	return TCL_ERROR;
+    }
+    chanObjPtr = objv[1];
+    if (TclGetChannelFromObj(interp, chanObjPtr, &chan, &mode, 0) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    if (!(mode & TCL_READABLE)) {
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		"channel \"%s\" wasn't opened for reading",
+		TclGetString(chanObjPtr)));
+	return TCL_ERROR;
+    }
+
+    TclChannelPreserve(chan);
+    linePtr = Tcl_NewObj();
+    lineLen = Tcl_GetsObj(chan, linePtr);
+    if (lineLen < 0) {
+	if (!Tcl_Eof(chan) && !Tcl_InputBlocked(chan)) {
+	    Tcl_DecrRefCount(linePtr);
+
+	    /*
+	     * TIP #219.
+	     * Capture error messages put by the driver into the bypass area
+	     * and put them into the regular interpreter result. Fall back to
+	     * the regular message if nothing was found in the bypass.
+	     */
+
+	    if (!TclChanCaughtErrorBypass(interp, chan)) {
+		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+			"error reading \"%s\": %s",
+			TclGetString(chanObjPtr), Tcl_PosixError(interp)));
+	    }
+	    code = TCL_ERROR;
+	    goto done;
+	}
+	lineLen = -1;
+    }
+    if (objc == 3) {
+	if (Tcl_ObjSetVar2(interp, objv[2], NULL, linePtr,
+		TCL_LEAVE_ERR_MSG) == NULL) {
+	    code = TCL_ERROR;
+	    goto done;
+	}
+	Tcl_SetObjResult(interp, Tcl_NewIntObj(lineLen));
+    } else {
+	Tcl_SetObjResult(interp, linePtr);
+    }
+  done:
+    TclChannelRelease(chan);
+    return code;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_ReadObjCmd --
+ *
+ *	This function is invoked to process the Tcl "read" command. See the
+ *	user documentation for details on what it does.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	May consume input from channel.
+ *
+ *----------------------------------------------------------------------
+ */
+
+	/* ARGSUSED */
+int
+Tcl_ReadObjCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    Tcl_Channel chan;		/* The channel to read from. */
+    int newline, i;		/* Discard newline at end? */
+    int toRead;			/* How many bytes to read? */
+    int charactersRead;		/* How many characters were read? */
+    int mode;			/* Mode in which channel is opened. */
+    Tcl_Obj *resultPtr, *chanObjPtr;
+
+    if ((objc != 2) && (objc != 3)) {
+	Interp *iPtr;
+
+    argerror:
+	iPtr = (Interp *) interp;
+	Tcl_WrongNumArgs(interp, 1, objv, "channelId ?numChars?");
+
+	/*
+	 * Do not append directly; that makes ensembles using this command as
+	 * a subcommand produce the wrong message.
+	 */
+
+	iPtr->flags |= INTERP_ALTERNATE_WRONG_ARGS;
+	Tcl_WrongNumArgs(interp, 1, objv, "?-nonewline? channelId");
+	return TCL_ERROR;
+    }
+
+    i = 1;
+    newline = 0;
+    if (strcmp(TclGetString(objv[1]), "-nonewline") == 0) {
+	newline = 1;
+	i++;
+    }
+
+    if (i == objc) {
+	goto argerror;
+    }
+
+    chanObjPtr = objv[i];
+    if (TclGetChannelFromObj(interp, chanObjPtr, &chan, &mode, 0) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    if (!(mode & TCL_READABLE)) {
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		"channel \"%s\" wasn't opened for reading",
+		TclGetString(chanObjPtr)));
+	return TCL_ERROR;
+    }
+    i++;			/* Consumed channel name. */
+
+    /*
+     * Compute how many bytes to read.
+     */
+
+    toRead = -1;
+    if (i < objc) {
+	if ((TclGetIntFromObj(interp, objv[i], &toRead) != TCL_OK)
+		|| (toRead < 0)) {
+#if TCL_MAJOR_VERSION < 9
+	    /*
+	     * The code below provides backwards compatibility with an old
+	     * form of the command that is no longer recommended or
+	     * documented. See also [Bug #3151675]. Will be removed in Tcl 9,
+	     * maybe even earlier.
+	     */
+
+	    if (strcmp(TclGetString(objv[i]), "nonewline") != 0) {
+#endif
+		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+			"expected non-negative integer but got \"%s\"",
+			TclGetString(objv[i])));
+		Tcl_SetErrorCode(interp, "TCL", "VALUE", "NUMBER", NULL);
+		return TCL_ERROR;
+#if TCL_MAJOR_VERSION < 9
+	    }
+	    newline = 1;
+#endif
+	}
+    }
+
+    resultPtr = Tcl_NewObj();
+    Tcl_IncrRefCount(resultPtr);
+    TclChannelPreserve(chan);
+    charactersRead = Tcl_ReadChars(chan, resultPtr, toRead, 0);
+    if (charactersRead < 0) {
+	/*
+	 * TIP #219.
+	 * Capture error messages put by the driver into the bypass area and
+	 * put them into the regular interpreter result. Fall back to the
+	 * regular message if nothing was found in the bypass.
+	 */
+
+	if (!TclChanCaughtErrorBypass(interp, chan)) {
+	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		    "error reading \"%s\": %s",
+		    TclGetString(chanObjPtr), Tcl_PosixError(interp)));
+	}
+	TclChannelRelease(chan);
+	Tcl_DecrRefCount(resultPtr);
+	return TCL_ERROR;
+    }
+
+    /*
+     * If requested, remove the last newline in the channel if at EOF.
+     */
+
+    if ((charactersRead > 0) && (newline != 0)) {
+	const char *result;
+	int length;
+
+	result = TclGetStringFromObj(resultPtr, &length);
+	if (result[length - 1] == '\n') {
+	    Tcl_SetObjLength(resultPtr, length - 1);
+	}
+    }
+    Tcl_SetObjResult(interp, resultPtr);
+    TclChannelRelease(chan);
+    Tcl_DecrRefCount(resultPtr);
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_SeekObjCmd --
+ *
+ *	This function is invoked to process the Tcl "seek" command. See the
+ *	user documentation for details on what it does.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	Moves the position of the access point on the specified channel.  May
+ *	flush queued output.
+ *
+ *----------------------------------------------------------------------
+ */
+
+	/* ARGSUSED */
+int
+Tcl_SeekObjCmd(
+    ClientData clientData,	/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    Tcl_Channel chan;		/* The channel to tell on. */
+    Tcl_WideInt offset;		/* Where to seek? */
+    int mode;			/* How to seek? */
+    Tcl_WideInt result;		/* Of calling Tcl_Seek. */
+    int optionIndex;
+    static const char *const originOptions[] = {
+	"start", "current", "end", NULL
+    };
+    static const int modeArray[] = {SEEK_SET, SEEK_CUR, SEEK_END};
+
+    if ((objc != 3) && (objc != 4)) {
+	Tcl_WrongNumArgs(interp, 1, objv, "channelId offset ?origin?");
+	return TCL_ERROR;
+    }
+    if (TclGetChannelFromObj(interp, objv[1], &chan, NULL, 0) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    if (Tcl_GetWideIntFromObj(interp, objv[2], &offset) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    mode = SEEK_SET;
+    if (objc == 4) {
+	if (Tcl_GetIndexFromObj(interp, objv[3], originOptions, "origin", 0,
+		&optionIndex) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	mode = modeArray[optionIndex];
+    }
+
+    TclChannelPreserve(chan);
+    result = Tcl_Seek(chan, offset, mode);
+    if (result == Tcl_LongAsWide(-1)) {
+	/*
+	 * TIP #219.
+	 * Capture error messages put by the driver into the bypass area and
+	 * put them into the regular interpreter result. Fall back to the
+	 * regular message if nothing was found in the bypass.
+	 */
+
+	if (!TclChanCaughtErrorBypass(interp, chan)) {
+	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		    "error during seek on \"%s\": %s",
+		    TclGetString(objv[1]), Tcl_PosixError(interp)));
+	}
+	TclChannelRelease(chan);
+	return TCL_ERROR;
+    }
+    TclChannelRelease(chan);
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_TellObjCmd --
+ *
+ *	This function is invoked to process the Tcl "tell" command. See the
+ *	user documentation for details on what it does.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+	/* ARGSUSED */
+int
+Tcl_TellObjCmd(
+    ClientData clientData,	/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    Tcl_Channel chan;		/* The channel to tell on. */
+    Tcl_WideInt newLoc;
+    int code;
+
+    if (objc != 2) {
+	Tcl_WrongNumArgs(interp, 1, objv, "channelId");
+	return TCL_ERROR;
+    }
+
+    /*
+     * Try to find a channel with the right name and permissions in the IO
+     * channel table of this interpreter.
+     */
+
+    if (TclGetChannelFromObj(interp, objv[1], &chan, NULL, 0) != TCL_OK) {
+	return TCL_ERROR;
+    }
+
+    TclChannelPreserve(chan);
+    newLoc = Tcl_Tell(chan);
+
+    /*
+     * TIP #219.
+     * Capture error messages put by the driver into the bypass area and put
+     * them into the regular interpreter result.
+     */
+
+
+    code  = TclChanCaughtErrorBypass(interp, chan);
+    TclChannelRelease(chan);
+    if (code) {
+	return TCL_ERROR;
+    }
+
+    Tcl_SetObjResult(interp, Tcl_NewWideIntObj(newLoc));
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_CloseObjCmd --
+ *
+ *	This function is invoked to process the Tcl "close" command. See the
+ *	user documentation for details on what it does.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	May discard queued input; may flush queued output.
+ *
+ *----------------------------------------------------------------------
+ */
+
+	/* ARGSUSED */
+int
+Tcl_CloseObjCmd(
+    ClientData clientData,	/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    Tcl_Channel chan;		/* The channel to close. */
+    static const char *const dirOptions[] = {
+	"read", "write", NULL
+    };
+    static const int dirArray[] = {TCL_CLOSE_READ, TCL_CLOSE_WRITE};
+
+    if ((objc != 2) && (objc != 3)) {
+	Tcl_WrongNumArgs(interp, 1, objv, "channelId ?direction?");
+	return TCL_ERROR;
+    }
+
+    if (TclGetChannelFromObj(interp, objv[1], &chan, NULL, 0) != TCL_OK) {
+	return TCL_ERROR;
+    }
+
+    if (objc == 3) {
+	int index, dir;
+
+	/*
+	 * Get direction requested to close, and check syntax.
+	 */
+
+	if (Tcl_GetIndexFromObj(interp, objv[2], dirOptions, "direction", 0,
+		&index) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	dir = dirArray[index];
+
+	/*
+	 * Check direction against channel mode. It is an error if we try to
+	 * close a direction not supported by the channel (already closed, or
+	 * never opened for that direction).
+	 */
+
+	if (!(dir & Tcl_GetChannelMode(chan))) {
+	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		    "Half-close of %s-side not possible, side not opened"
+		    " or already closed", dirOptions[index]));
+	    return TCL_ERROR;
+	}
+
+	/*
+	 * Special handling is needed if and only if the channel mode supports
+	 * more than the direction to close. Because if the close the last
+	 * direction suppported we can and will go through the regular
+	 * process.
+	 */
+
+	if ((Tcl_GetChannelMode(chan) &
+		(TCL_CLOSE_READ|TCL_CLOSE_WRITE)) != dir) {
+	    return Tcl_CloseEx(interp, chan, dir);
+	}
+    }
+
+    if (Tcl_UnregisterChannel(interp, chan) != TCL_OK) {
+	/*
+	 * If there is an error message and it ends with a newline, remove the
+	 * newline. This is done for command pipeline channels where the error
+	 * output from the subprocesses is stored in interp's result.
+	 *
+	 * NOTE: This is likely to not have any effect on regular error
+	 * messages produced by drivers during the closing of a channel,
+	 * because the Tcl convention is that such error messages do not have
+	 * a terminating newline.
+	 */
+
+	Tcl_Obj *resultPtr = Tcl_GetObjResult(interp);
+	const char *string;
+	int len;
+
+	if (Tcl_IsShared(resultPtr)) {
+	    resultPtr = Tcl_DuplicateObj(resultPtr);
+	    Tcl_SetObjResult(interp, resultPtr);
+	}
+	string = TclGetStringFromObj(resultPtr, &len);
+	if ((len > 0) && (string[len - 1] == '\n')) {
+	    Tcl_SetObjLength(resultPtr, len - 1);
+	}
+	return TCL_ERROR;
+    }
+
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_FconfigureObjCmd --
+ *
+ *	This function is invoked to process the Tcl "fconfigure" command. See
+ *	the user documentation for details on what it does.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	May modify the behavior of an IO channel.
+ *
+ *----------------------------------------------------------------------
+ */
+
+	/* ARGSUSED */
+int
+Tcl_FconfigureObjCmd(
+    ClientData clientData,	/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    const char *optionName, *valueName;
+    Tcl_Channel chan;		/* The channel to set a mode on. */
+    int i;			/* Iterate over arg-value pairs. */
+
+    if ((objc < 2) || (((objc % 2) == 1) && (objc != 3))) {
+	Tcl_WrongNumArgs(interp, 1, objv, "channelId ?-option value ...?");
+	return TCL_ERROR;
+    }
+
+    if (TclGetChannelFromObj(interp, objv[1], &chan, NULL, 0) != TCL_OK) {
+	return TCL_ERROR;
+    }
+
+    if (objc == 2) {
+	Tcl_DString ds;		/* DString to hold result of calling
+				 * Tcl_GetChannelOption. */
+
+	Tcl_DStringInit(&ds);
+	if (Tcl_GetChannelOption(interp, chan, NULL, &ds) != TCL_OK) {
+	    Tcl_DStringFree(&ds);
+	    return TCL_ERROR;
+	}
+	Tcl_DStringResult(interp, &ds);
+	return TCL_OK;
+    } else if (objc == 3) {
+	Tcl_DString ds;		/* DString to hold result of calling
+				 * Tcl_GetChannelOption. */
+
+	Tcl_DStringInit(&ds);
+	optionName = TclGetString(objv[2]);
+	if (Tcl_GetChannelOption(interp, chan, optionName, &ds) != TCL_OK) {
+	    Tcl_DStringFree(&ds);
+	    return TCL_ERROR;
+	}
+	Tcl_DStringResult(interp, &ds);
+	return TCL_OK;
+    }
+
+    for (i = 3; i < objc; i += 2) {
+	optionName = TclGetString(objv[i-1]);
+	valueName = TclGetString(objv[i]);
+	if (Tcl_SetChannelOption(interp, chan, optionName, valueName)
+		!= TCL_OK) {
+	    return TCL_ERROR;
+	}
+    }
+
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Tcl_EofObjCmd --
+ *
+ *	This function is invoked to process the Tcl "eof" command. See the
+ *	user documentation for details on what it does.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	Sets interp's result to boolean true or false depending on whether the
+ *	specified channel has an EOF condition.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+	/* ARGSUSED */
+int
+Tcl_EofObjCmd(
+    ClientData unused,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    Tcl_Channel chan;
+
+    if (objc != 2) {
+	Tcl_WrongNumArgs(interp, 1, objv, "channelId");
+	return TCL_ERROR;
+    }
+
+    if (TclGetChannelFromObj(interp, objv[1], &chan, NULL, 0) != TCL_OK) {
+	return TCL_ERROR;
+    }
+
+    Tcl_SetObjResult(interp, Tcl_NewBooleanObj(Tcl_Eof(chan)));
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_ExecObjCmd --
+ *
+ *	This function is invoked to process the "exec" Tcl command. See the
+ *	user documentation for details on what it does.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+	/* ARGSUSED */
+int
+Tcl_ExecObjCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    Tcl_Obj *resultPtr;
+    const char **argv;		/* An array for the string arguments. Stored
+				 * on the _Tcl_ stack. */
+    const char *string;
+    Tcl_Channel chan;
+    int argc, background, i, index, keepNewline, result, skip, length;
+    int ignoreStderr;
+    static const char *const options[] = {
+	"-ignorestderr", "-keepnewline", "--", NULL
+    };
+    enum options {
+	EXEC_IGNORESTDERR, EXEC_KEEPNEWLINE, EXEC_LAST
+    };
+
+    /*
+     * Check for any leading option arguments.
+     */
+
+    keepNewline = 0;
+    ignoreStderr = 0;
+    for (skip = 1; skip < objc; skip++) {
+	string = TclGetString(objv[skip]);
+	if (string[0] != '-') {
+	    break;
+	}
+	if (Tcl_GetIndexFromObj(interp, objv[skip], options, "option",
+		TCL_EXACT, &index) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	if (index == EXEC_KEEPNEWLINE) {
+	    keepNewline = 1;
+	} else if (index == EXEC_IGNORESTDERR) {
+	    ignoreStderr = 1;
+	} else {
+	    skip++;
+	    break;
+	}
+    }
+    if (objc <= skip) {
+	Tcl_WrongNumArgs(interp, 1, objv, "?-option ...? arg ?arg ...?");
+	return TCL_ERROR;
+    }
+
+    /*
+     * See if the command is to be run in background.
+     */
+
+    background = 0;
+    string = TclGetString(objv[objc - 1]);
+    if ((string[0] == '&') && (string[1] == '\0')) {
+	objc--;
+	background = 1;
+    }
+
+    /*
+     * Create the string argument array "argv". Make sure argv is large enough
+     * to hold the argc arguments plus 1 extra for the zero end-of-argv word.
+     */
+
+    argc = objc - skip;
+    argv = TclStackAlloc(interp, (unsigned)(argc + 1) * sizeof(char *));
+
+    /*
+     * Copy the string conversions of each (post option) object into the
+     * argument vector.
+     */
+
+    for (i = 0; i < argc; i++) {
+	argv[i] = TclGetString(objv[i + skip]);
+    }
+    argv[argc] = NULL;
+    chan = Tcl_OpenCommandChannel(interp, argc, argv, (background ? 0 :
+	    ignoreStderr ? TCL_STDOUT : TCL_STDOUT|TCL_STDERR));
+
+    /*
+     * Free the argv array.
+     */
+
+    TclStackFree(interp, (void *) argv);
+
+    if (chan == NULL) {
+	return TCL_ERROR;
+    }
+
+    if (background) {
+	/*
+	 * Store the list of PIDs from the pipeline in interp's result and
+	 * detach the PIDs (instead of waiting for them).
+	 */
+
+	TclGetAndDetachPids(interp, chan);
+	if (Tcl_Close(interp, chan) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	return TCL_OK;
+    }
+
+    resultPtr = Tcl_NewObj();
+    if (Tcl_GetChannelHandle(chan, TCL_READABLE, NULL) == TCL_OK) {
+	if (Tcl_ReadChars(chan, resultPtr, -1, 0) < 0) {
+	    /*
+	     * TIP #219.
+	     * Capture error messages put by the driver into the bypass area
+	     * and put them into the regular interpreter result. Fall back to
+	     * the regular message if nothing was found in the bypass.
+	     */
+
+	    if (!TclChanCaughtErrorBypass(interp, chan)) {
+		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+			"error reading output from command: %s",
+			Tcl_PosixError(interp)));
+		Tcl_DecrRefCount(resultPtr);
+	    }
+	    return TCL_ERROR;
+	}
+    }
+
+    /*
+     * If the process produced anything on stderr, it will have been returned
+     * in the interpreter result. It needs to be appended to the result
+     * string.
+     */
+
+    result = Tcl_Close(interp, chan);
+    Tcl_AppendObjToObj(resultPtr, Tcl_GetObjResult(interp));
+
+    /*
+     * If the last character of the result is a newline, then remove the
+     * newline character.
+     */
+
+    if (keepNewline == 0) {
+	string = TclGetStringFromObj(resultPtr, &length);
+	if ((length > 0) && (string[length - 1] == '\n')) {
+	    Tcl_SetObjLength(resultPtr, length - 1);
+	}
+    }
+    Tcl_SetObjResult(interp, resultPtr);
+
+    return result;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Tcl_FblockedObjCmd --
+ *
+ *	This function is invoked to process the Tcl "fblocked" command. See
+ *	the user documentation for details on what it does.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	Sets interp's result to boolean true or false depending on whether the
+ *	preceeding input operation on the channel would have blocked.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+	/* ARGSUSED */
+int
+Tcl_FblockedObjCmd(
+    ClientData unused,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    Tcl_Channel chan;
+    int mode;
+
+    if (objc != 2) {
+	Tcl_WrongNumArgs(interp, 1, objv, "channelId");
+	return TCL_ERROR;
+    }
+
+    if (TclGetChannelFromObj(interp, objv[1], &chan, &mode, 0) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    if (!(mode & TCL_READABLE)) {
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		"channel \"%s\" wasn't opened for reading",
+		TclGetString(objv[1])));
+	return TCL_ERROR;
+    }
+
+    Tcl_SetObjResult(interp, Tcl_NewBooleanObj(Tcl_InputBlocked(chan)));
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_OpenObjCmd --
+ *
+ *	This function is invoked to process the "open" Tcl command. See the
+ *	user documentation for details on what it does.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+	/* ARGSUSED */
+int
+Tcl_OpenObjCmd(
+    ClientData notUsed,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    int pipeline, prot;
+    const char *modeString, *what;
+    Tcl_Channel chan;
+
+    if ((objc < 2) || (objc > 4)) {
+	Tcl_WrongNumArgs(interp, 1, objv, "fileName ?access? ?permissions?");
+	return TCL_ERROR;
+    }
+    prot = 0666;
+    if (objc == 2) {
+	modeString = "r";
+    } else {
+	modeString = TclGetString(objv[2]);
+	if (objc == 4) {
+	    const char *permString = TclGetString(objv[3]);
+	    int code = TCL_ERROR;
+	    int scanned = TclParseAllWhiteSpace(permString, -1);
+
+	    /*
+	     * Support legacy octal numbers.
+	     */
+
+	    if ((permString[scanned] == '0')
+		    && (permString[scanned+1] >= '0')
+		    && (permString[scanned+1] <= '7')) {
+		Tcl_Obj *permObj;
+
+		TclNewLiteralStringObj(permObj, "0o");
+		Tcl_AppendToObj(permObj, permString+scanned+1, -1);
+		code = TclGetIntFromObj(NULL, permObj, &prot);
+		Tcl_DecrRefCount(permObj);
+	    }
+
+	    if ((code == TCL_ERROR)
+		    && TclGetIntFromObj(interp, objv[3], &prot) != TCL_OK) {
+		return TCL_ERROR;
+	    }
+	}
+    }
+
+    pipeline = 0;
+    what = TclGetString(objv[1]);
+    if (what[0] == '|') {
+	pipeline = 1;
+    }
+
+    /*
+     * Open the file or create a process pipeline.
+     */
+
+    if (!pipeline) {
+	chan = Tcl_FSOpenFileChannel(interp, objv[1], modeString, prot);
+    } else {
+	int mode, seekFlag, cmdObjc, binary;
+	const char **cmdArgv;
+
+	if (Tcl_SplitList(interp, what+1, &cmdObjc, &cmdArgv) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+
+	mode = TclGetOpenModeEx(interp, modeString, &seekFlag, &binary);
+	if (mode == -1) {
+	    chan = NULL;
+	} else {
+	    int flags = TCL_STDERR | TCL_ENFORCE_MODE;
+
+	    switch (mode & (O_RDONLY | O_WRONLY | O_RDWR)) {
+	    case O_RDONLY:
+		flags |= TCL_STDOUT;
+		break;
+	    case O_WRONLY:
+		flags |= TCL_STDIN;
+		break;
+	    case O_RDWR:
+		flags |= (TCL_STDIN | TCL_STDOUT);
+		break;
+	    default:
+		Tcl_Panic("Tcl_OpenCmd: invalid mode value");
+		break;
+	    }
+	    chan = Tcl_OpenCommandChannel(interp, cmdObjc, cmdArgv, flags);
+	    if (binary && chan) {
+		Tcl_SetChannelOption(interp, chan, "-translation", "binary");
+	    }
+	}
+	ckfree(cmdArgv);
+    }
+    if (chan == NULL) {
+	return TCL_ERROR;
+    }
+    Tcl_RegisterChannel(interp, chan);
+    Tcl_SetObjResult(interp, Tcl_NewStringObj(Tcl_GetChannelName(chan), -1));
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TcpAcceptCallbacksDeleteProc --
+ *
+ *	Assocdata cleanup routine called when an interpreter is being deleted
+ *	to set the interp field of all the accept callback records registered
+ *	with the interpreter to NULL. This will prevent the interpreter from
+ *	being used in the future to eval accept scripts.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Deallocates memory and sets the interp field of all the accept
+ *	callback records to NULL to prevent this interpreter from being used
+ *	subsequently to eval accept scripts.
+ *
+ *----------------------------------------------------------------------
+ */
+
+	/* ARGSUSED */
+static void
+TcpAcceptCallbacksDeleteProc(
+    ClientData clientData,	/* Data which was passed when the assocdata
+				 * was registered. */
+    Tcl_Interp *interp)		/* Interpreter being deleted - not used. */
+{
+    Tcl_HashTable *hTblPtr = clientData;
+    Tcl_HashEntry *hPtr;
+    Tcl_HashSearch hSearch;
+
+    for (hPtr = Tcl_FirstHashEntry(hTblPtr, &hSearch);
+	    hPtr != NULL; hPtr = Tcl_NextHashEntry(&hSearch)) {
+	AcceptCallback *acceptCallbackPtr = Tcl_GetHashValue(hPtr);
+
+	acceptCallbackPtr->interp = NULL;
+    }
+    Tcl_DeleteHashTable(hTblPtr);
+    ckfree(hTblPtr);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * RegisterTcpServerInterpCleanup --
+ *
+ *	Registers an accept callback record to have its interp field set to
+ *	NULL when the interpreter is deleted.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	When, in the future, the interpreter is deleted, the interp field of
+ *	the accept callback data structure will be set to NULL. This will
+ *	prevent attempts to eval the accept script in a deleted interpreter.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+RegisterTcpServerInterpCleanup(
+    Tcl_Interp *interp,		/* Interpreter for which we want to be
+				 * informed of deletion. */
+    AcceptCallback *acceptCallbackPtr)
+				/* The accept callback record whose interp
+				 * field we want set to NULL when the
+				 * interpreter is deleted. */
+{
+    Tcl_HashTable *hTblPtr;	/* Hash table for accept callback records to
+				 * smash when the interpreter will be
+				 * deleted. */
+    Tcl_HashEntry *hPtr;	/* Entry for this record. */
+    int isNew;			/* Is the entry new? */
+
+    hTblPtr = Tcl_GetAssocData(interp, "tclTCPAcceptCallbacks", NULL);
+
+    if (hTblPtr == NULL) {
+	hTblPtr = ckalloc(sizeof(Tcl_HashTable));
+	Tcl_InitHashTable(hTblPtr, TCL_ONE_WORD_KEYS);
+	Tcl_SetAssocData(interp, "tclTCPAcceptCallbacks",
+		TcpAcceptCallbacksDeleteProc, hTblPtr);
+    }
+
+    hPtr = Tcl_CreateHashEntry(hTblPtr, acceptCallbackPtr, &isNew);
+    if (!isNew) {
+	Tcl_Panic("RegisterTcpServerCleanup: damaged accept record table");
+    }
+    Tcl_SetHashValue(hPtr, acceptCallbackPtr);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * UnregisterTcpServerInterpCleanupProc --
+ *
+ *	Unregister a previously registered accept callback record. The interp
+ *	field of this record will no longer be set to NULL in the future when
+ *	the interpreter is deleted.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Prevents the interp field of the accept callback record from being set
+ *	to NULL in the future when the interpreter is deleted.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+UnregisterTcpServerInterpCleanupProc(
+    Tcl_Interp *interp,		/* Interpreter in which the accept callback
+				 * record was registered. */
+    AcceptCallback *acceptCallbackPtr)
+				/* The record for which to delete the
+				 * registration. */
+{
+    Tcl_HashTable *hTblPtr;
+    Tcl_HashEntry *hPtr;
+
+    hTblPtr = Tcl_GetAssocData(interp, "tclTCPAcceptCallbacks", NULL);
+    if (hTblPtr == NULL) {
+	return;
+    }
+
+    hPtr = Tcl_FindHashEntry(hTblPtr, (char *) acceptCallbackPtr);
+    if (hPtr != NULL) {
+	Tcl_DeleteHashEntry(hPtr);
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * AcceptCallbackProc --
+ *
+ *	This callback is invoked by the TCP channel driver when it accepts a
+ *	new connection from a client on a server socket.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Whatever the script does.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+AcceptCallbackProc(
+    ClientData callbackData,	/* The data stored when the callback was
+				 * created in the call to
+				 * Tcl_OpenTcpServer. */
+    Tcl_Channel chan,		/* Channel for the newly accepted
+				 * connection. */
+    char *address,		/* Address of client that was accepted. */
+    int port)			/* Port of client that was accepted. */
+{
+    AcceptCallback *acceptCallbackPtr = callbackData;
+
+    /*
+     * Check if the callback is still valid; the interpreter may have gone
+     * away, this is signalled by setting the interp field of the callback
+     * data to NULL.
+     */
+
+    if (acceptCallbackPtr->interp != NULL) {
+	char portBuf[TCL_INTEGER_SPACE];
+	char *script = acceptCallbackPtr->script;
+	Tcl_Interp *interp = acceptCallbackPtr->interp;
+	int result;
+
+	Tcl_Preserve(script);
+	Tcl_Preserve(interp);
+
+	TclFormatInt(portBuf, port);
+	Tcl_RegisterChannel(interp, chan);
+
+	/*
+	 * Artificially bump the refcount to protect the channel from being
+	 * deleted while the script is being evaluated.
+	 */
+
+	Tcl_RegisterChannel(NULL, chan);
+
+	result = Tcl_VarEval(interp, script, " ", Tcl_GetChannelName(chan),
+		" ", address, " ", portBuf, NULL);
+	if (result != TCL_OK) {
+	    Tcl_BackgroundException(interp, result);
+	    Tcl_UnregisterChannel(interp, chan);
+	}
+
+	/*
+	 * Decrement the artificially bumped refcount. After this it is not
+	 * safe anymore to use "chan", because it may now be deleted.
+	 */
+
+	Tcl_UnregisterChannel(NULL, chan);
+
+	Tcl_Release(interp);
+	Tcl_Release(script);
+    } else {
+	/*
+	 * The interpreter has been deleted, so there is no useful way to use
+	 * the client socket - just close it.
+	 */
+
+	Tcl_Close(NULL, chan);
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TcpServerCloseProc --
+ *
+ *	This callback is called when the TCP server channel for which it was
+ *	registered is being closed. It informs the interpreter in which the
+ *	accept script is evaluated (if that interpreter still exists) that
+ *	this channel no longer needs to be informed if the interpreter is
+ *	deleted.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	In the future, if the interpreter is deleted this channel will no
+ *	longer be informed.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+TcpServerCloseProc(
+    ClientData callbackData)	/* The data passed in the call to
+				 * Tcl_CreateCloseHandler. */
+{
+    AcceptCallback *acceptCallbackPtr = callbackData;
+				/* The actual data. */
+
+    if (acceptCallbackPtr->interp != NULL) {
+	UnregisterTcpServerInterpCleanupProc(acceptCallbackPtr->interp,
+		acceptCallbackPtr);
+    }
+    Tcl_EventuallyFree(acceptCallbackPtr->script, TCL_DYNAMIC);
+    ckfree(acceptCallbackPtr);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_SocketObjCmd --
+ *
+ *	This function is invoked to process the "socket" Tcl command. See the
+ *	user documentation for details on what it does.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	Creates a socket based channel.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_SocketObjCmd(
+    ClientData notUsed,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    static const char *const socketOptions[] = {
+	"-async", "-myaddr", "-myport", "-server", NULL
+    };
+    enum socketOptions {
+	SKT_ASYNC, SKT_MYADDR, SKT_MYPORT, SKT_SERVER
+    };
+    int optionIndex, a, server = 0, port, myport = 0, async = 0;
+    const char *host, *script = NULL, *myaddr = NULL;
+    Tcl_Channel chan;
+
+    if (TclpHasSockets(interp) != TCL_OK) {
+	return TCL_ERROR;
+    }
+
+    for (a = 1; a < objc; a++) {
+	const char *arg = Tcl_GetString(objv[a]);
+
+	if (arg[0] != '-') {
+	    break;
+	}
+	if (Tcl_GetIndexFromObj(interp, objv[a], socketOptions, "option",
+		TCL_EXACT, &optionIndex) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	switch ((enum socketOptions) optionIndex) {
+	case SKT_ASYNC:
+	    if (server == 1) {
+		Tcl_SetObjResult(interp, Tcl_NewStringObj(
+			"cannot set -async option for server sockets", -1));
+		return TCL_ERROR;
+	    }
+	    async = 1;
+	    break;
+	case SKT_MYADDR:
+	    a++;
+	    if (a >= objc) {
+		Tcl_SetObjResult(interp, Tcl_NewStringObj(
+			"no argument given for -myaddr option", -1));
+		return TCL_ERROR;
+	    }
+	    myaddr = TclGetString(objv[a]);
+	    break;
+	case SKT_MYPORT: {
+	    const char *myPortName;
+
+	    a++;
+	    if (a >= objc) {
+		Tcl_SetObjResult(interp, Tcl_NewStringObj(
+			"no argument given for -myport option", -1));
+		return TCL_ERROR;
+	    }
+	    myPortName = TclGetString(objv[a]);
+	    if (TclSockGetPort(interp, myPortName, "tcp", &myport) != TCL_OK) {
+		return TCL_ERROR;
+	    }
+	    break;
+	}
+	case SKT_SERVER:
+	    if (async == 1) {
+		Tcl_SetObjResult(interp, Tcl_NewStringObj(
+			"cannot set -async option for server sockets", -1));
+		return TCL_ERROR;
+	    }
+	    server = 1;
+	    a++;
+	    if (a >= objc) {
+		Tcl_SetObjResult(interp, Tcl_NewStringObj(
+			"no argument given for -server option", -1));
+		return TCL_ERROR;
+	    }
+	    script = TclGetString(objv[a]);
+	    break;
+	default:
+	    Tcl_Panic("Tcl_SocketObjCmd: bad option index to SocketOptions");
+	}
+    }
+    if (server) {
+	host = myaddr;		/* NULL implies INADDR_ANY */
+	if (myport != 0) {
+	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		    "option -myport is not valid for servers", -1));
+	    return TCL_ERROR;
+	}
+    } else if (a < objc) {
+	host = TclGetString(objv[a]);
+	a++;
+    } else {
+	Interp *iPtr;
+
+    wrongNumArgs:
+	iPtr = (Interp *) interp;
+	Tcl_WrongNumArgs(interp, 1, objv,
+		"?-myaddr addr? ?-myport myport? ?-async? host port");
+	iPtr->flags |= INTERP_ALTERNATE_WRONG_ARGS;
+	Tcl_WrongNumArgs(interp, 1, objv,
+		"-server command ?-myaddr addr? port");
+	return TCL_ERROR;
+    }
+
+    if (a == objc-1) {
+	if (TclSockGetPort(interp, TclGetString(objv[a]), "tcp",
+		&port) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+    } else {
+	goto wrongNumArgs;
+    }
+
+    if (server) {
+	AcceptCallback *acceptCallbackPtr =
+		ckalloc(sizeof(AcceptCallback));
+	unsigned len = strlen(script) + 1;
+	char *copyScript = ckalloc(len);
+
+	memcpy(copyScript, script, len);
+	acceptCallbackPtr->script = copyScript;
+	acceptCallbackPtr->interp = interp;
+	chan = Tcl_OpenTcpServer(interp, port, host, AcceptCallbackProc,
+		acceptCallbackPtr);
+	if (chan == NULL) {
+	    ckfree(copyScript);
+	    ckfree(acceptCallbackPtr);
+	    return TCL_ERROR;
+	}
+
+	/*
+	 * Register with the interpreter to let us know when the interpreter
+	 * is deleted (by having the callback set the interp field of the
+	 * acceptCallbackPtr's structure to NULL). This is to avoid trying to
+	 * eval the script in a deleted interpreter.
+	 */
+
+	RegisterTcpServerInterpCleanup(interp, acceptCallbackPtr);
+
+	/*
+	 * Register a close callback. This callback will inform the
+	 * interpreter (if it still exists) that this channel does not need to
+	 * be informed when the interpreter is deleted.
+	 */
+
+	Tcl_CreateCloseHandler(chan, TcpServerCloseProc, acceptCallbackPtr);
+    } else {
+	chan = Tcl_OpenTcpClient(interp, port, host, myaddr, myport, async);
+	if (chan == NULL) {
+	    return TCL_ERROR;
+	}
+    }
+
+    Tcl_RegisterChannel(interp, chan);
+    Tcl_SetObjResult(interp, Tcl_NewStringObj(Tcl_GetChannelName(chan), -1));
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_FcopyObjCmd --
+ *
+ *	This function is invoked to process the "fcopy" Tcl command. See the
+ *	user documentation for details on what it does.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	Moves data between two channels and possibly sets up a background copy
+ *	handler.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_FcopyObjCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    Tcl_Channel inChan, outChan;
+    int mode, i, index;
+    Tcl_WideInt toRead;
+    Tcl_Obj *cmdPtr;
+    static const char *const switches[] = { "-size", "-command", NULL };
+    enum { FcopySize, FcopyCommand };
+
+    if ((objc < 3) || (objc > 7) || (objc == 4) || (objc == 6)) {
+	Tcl_WrongNumArgs(interp, 1, objv,
+		"input output ?-size size? ?-command callback?");
+	return TCL_ERROR;
+    }
+
+    /*
+     * Parse the channel arguments and verify that they are readable or
+     * writable, as appropriate.
+     */
+
+    if (TclGetChannelFromObj(interp, objv[1], &inChan, &mode, 0) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    if (!(mode & TCL_READABLE)) {
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		"channel \"%s\" wasn't opened for reading",
+		TclGetString(objv[1])));
+	return TCL_ERROR;
+    }
+    if (TclGetChannelFromObj(interp, objv[2], &outChan, &mode, 0) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    if (!(mode & TCL_WRITABLE)) {
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		"channel \"%s\" wasn't opened for writing",
+		TclGetString(objv[2])));
+	return TCL_ERROR;
+    }
+
+    toRead = -1;
+    cmdPtr = NULL;
+    for (i = 3; i < objc; i += 2) {
+	if (Tcl_GetIndexFromObj(interp, objv[i], switches, "option", 0,
+		&index) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	switch (index) {
+	case FcopySize:
+	    if (Tcl_GetWideIntFromObj(interp, objv[i+1], &toRead) != TCL_OK) {
+		return TCL_ERROR;
+	    }
+	    if (toRead < 0) {
+		/*
+		 * Handle all negative sizes like -1, meaning 'copy all'. By
+		 * resetting toRead we avoid changes in the core copying
+		 * functions (which explicitly check for -1 and crash on any
+		 * other negative value).
+		 */
+
+		toRead = -1;
+	    }
+	    break;
+	case FcopyCommand:
+	    cmdPtr = objv[i+1];
+	    break;
+	}
+    }
+
+    return TclCopyChannel(interp, inChan, outChan, toRead, cmdPtr);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * ChanPendingObjCmd --
+ *
+ *	This function is invoked to process the Tcl "chan pending" command
+ *	(TIP #287). See the user documentation for details on what it does.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	Sets interp's result to the number of bytes of buffered input or
+ *	output (depending on whether the first argument is "input" or
+ *	"output"), or -1 if the channel wasn't opened for that mode.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+	/* ARGSUSED */
+static int
+ChanPendingObjCmd(
+    ClientData unused,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    Tcl_Channel chan;
+    int index, mode;
+    static const char *const options[] = {"input", "output", NULL};
+    enum options {PENDING_INPUT, PENDING_OUTPUT};
+
+    if (objc != 3) {
+	Tcl_WrongNumArgs(interp, 1, objv, "mode channelId");
+	return TCL_ERROR;
+    }
+
+    if (Tcl_GetIndexFromObj(interp, objv[1], options, "mode", 0,
+	    &index) != TCL_OK) {
+	return TCL_ERROR;
+    }
+
+    if (TclGetChannelFromObj(interp, objv[2], &chan, &mode, 0) != TCL_OK) {
+	return TCL_ERROR;
+    }
+
+    switch ((enum options) index) {
+    case PENDING_INPUT:
+	if (!(mode & TCL_READABLE)) {
+	    Tcl_SetObjResult(interp, Tcl_NewIntObj(-1));
+	} else {
+	    Tcl_SetObjResult(interp, Tcl_NewIntObj(Tcl_InputBuffered(chan)));
+	}
+	break;
+    case PENDING_OUTPUT:
+	if (!(mode & TCL_WRITABLE)) {
+	    Tcl_SetObjResult(interp, Tcl_NewIntObj(-1));
+	} else {
+	    Tcl_SetObjResult(interp, Tcl_NewIntObj(Tcl_OutputBuffered(chan)));
+	}
+	break;
+    }
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ChanTruncateObjCmd --
+ *
+ *	This function is invoked to process the "chan truncate" Tcl command.
+ *	See the user documentation for details on what it does.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	Truncates a channel (or rather a file underlying a channel).
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+ChanTruncateObjCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    Tcl_Channel chan;
+    Tcl_WideInt length;
+
+    if ((objc < 2) || (objc > 3)) {
+	Tcl_WrongNumArgs(interp, 1, objv, "channelId ?length?");
+	return TCL_ERROR;
+    }
+    if (TclGetChannelFromObj(interp, objv[1], &chan, NULL, 0) != TCL_OK) {
+	return TCL_ERROR;
+    }
+
+    if (objc == 3) {
+	/*
+	 * User is supplying an explicit length.
+	 */
+
+	if (Tcl_GetWideIntFromObj(interp, objv[2], &length) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	if (length < 0) {
+	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		    "cannot truncate to negative length of file", -1));
+	    return TCL_ERROR;
+	}
+    } else {
+	/*
+	 * User wants to truncate to the current file position.
+	 */
+
+	length = Tcl_Tell(chan);
+	if (length == Tcl_WideAsLong(-1)) {
+	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		    "could not determine current location in \"%s\": %s",
+		    TclGetString(objv[1]), Tcl_PosixError(interp)));
+	    return TCL_ERROR;
+	}
+    }
+
+    if (Tcl_TruncateChannel(chan, length) != TCL_OK) {
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		"error during truncate on \"%s\": %s",
+		TclGetString(objv[1]), Tcl_PosixError(interp)));
+	return TCL_ERROR;
+    }
+
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ChanPipeObjCmd --
+ *
+ *	This function is invoked to process the "chan pipe" Tcl command.
+ *	See the user documentation for details on what it does.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	Creates a pair of Tcl channels wrapping both ends of a new
+ *	anonymous pipe.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+ChanPipeObjCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    Tcl_Channel rchan, wchan;
+    const char *channelNames[2];
+    Tcl_Obj *resultPtr;
+
+    if (objc != 1) {
+	Tcl_WrongNumArgs(interp, 1, objv, "");
+	return TCL_ERROR;
+    }
+
+    if (Tcl_CreatePipe(interp, &rchan, &wchan, 0) != TCL_OK) {
+	return TCL_ERROR;
+    }
+
+    channelNames[0] = Tcl_GetChannelName(rchan);
+    channelNames[1] = Tcl_GetChannelName(wchan);
+
+    resultPtr = Tcl_NewObj();
+    Tcl_ListObjAppendElement(NULL, resultPtr,
+	    Tcl_NewStringObj(channelNames[0], -1));
+    Tcl_ListObjAppendElement(NULL, resultPtr,
+	    Tcl_NewStringObj(channelNames[1], -1));
+    Tcl_SetObjResult(interp, resultPtr);
+
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclChannelNamesCmd --
+ *
+ *	This function is invoked to process the "chan names" and "file
+ *	channels" Tcl commands.  See the user documentation for details on
+ *	what they do.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclChannelNamesCmd(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const objv[])
+{
+    if (objc < 1 || objc > 2) {
+	Tcl_WrongNumArgs(interp, 1, objv, "?pattern?");
+	return TCL_ERROR;
+    }
+    return Tcl_GetChannelNamesEx(interp,
+	    ((objc == 1) ? NULL : TclGetString(objv[1])));
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclInitChanCmd --
+ *
+ *	This function is invoked to create the "chan" Tcl command. See the
+ *	user documentation for details on what it does.
+ *
+ * Results:
+ *	A Tcl command handle.
+ *
+ * Side effects:
+ *	None (since nothing is byte-compiled).
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_Command
+TclInitChanCmd(
+    Tcl_Interp *interp)
+{
+    /*
+     * Most commands are plugged directly together, but some are done via
+     * alias-like rewriting; [chan configure] is this way for security reasons
+     * (want overwriting of [fconfigure] to control that nicely), and [chan
+     * names] because the functionality isn't available as a separate command
+     * function at the moment.
+     */
+    static const EnsembleImplMap initMap[] = {
+	{"blocked",	Tcl_FblockedObjCmd,	TclCompileBasic1ArgCmd, NULL, NULL, 0},
+	{"close",	Tcl_CloseObjCmd,	TclCompileBasic1Or2ArgCmd, NULL, NULL, 0},
+	{"copy",	Tcl_FcopyObjCmd,	NULL, NULL, NULL, 0},
+	{"create",	TclChanCreateObjCmd,	TclCompileBasic2ArgCmd, NULL, NULL, 0},		/* TIP #219 */
+	{"eof",		Tcl_EofObjCmd,		TclCompileBasic1ArgCmd, NULL, NULL, 0},
+	{"event",	Tcl_FileEventObjCmd,	TclCompileBasic2Or3ArgCmd, NULL, NULL, 0},
+	{"flush",	Tcl_FlushObjCmd,	TclCompileBasic1ArgCmd, NULL, NULL, 0},
+	{"gets",	Tcl_GetsObjCmd,		TclCompileBasic1Or2ArgCmd, NULL, NULL, 0},
+	{"names",	TclChannelNamesCmd,	TclCompileBasic0Or1ArgCmd, NULL, NULL, 0},
+	{"pending",	ChanPendingObjCmd,	TclCompileBasic2ArgCmd, NULL, NULL, 0},		/* TIP #287 */
+	{"pipe",	ChanPipeObjCmd,		TclCompileBasic0ArgCmd, NULL, NULL, 0},		/* TIP #304 */
+	{"pop",		TclChanPopObjCmd,	TclCompileBasic1ArgCmd, NULL, NULL, 0},		/* TIP #230 */
+	{"postevent",	TclChanPostEventObjCmd,	TclCompileBasic2ArgCmd, NULL, NULL, 0},	/* TIP #219 */
+	{"push",	TclChanPushObjCmd,	TclCompileBasic2ArgCmd, NULL, NULL, 0},		/* TIP #230 */
+	{"puts",	Tcl_PutsObjCmd,		NULL, NULL, NULL, 0},
+	{"read",	Tcl_ReadObjCmd,		NULL, NULL, NULL, 0},
+	{"seek",	Tcl_SeekObjCmd,		TclCompileBasic2Or3ArgCmd, NULL, NULL, 0},
+	{"tell",	Tcl_TellObjCmd,		TclCompileBasic1ArgCmd, NULL, NULL, 0},
+	{"truncate",	ChanTruncateObjCmd,	TclCompileBasic1Or2ArgCmd, NULL, NULL, 0},		/* TIP #208 */
+	{NULL, NULL, NULL, NULL, NULL, 0}
+    };
+    static const char *const extras[] = {
+	"configure",	"::fconfigure",
+	NULL
+    };
+    Tcl_Command ensemble;
+    Tcl_Obj *mapObj;
+    int i;
+
+    ensemble = TclMakeEnsemble(interp, "chan", initMap);
+    Tcl_GetEnsembleMappingDict(NULL, ensemble, &mapObj);
+    for (i=0 ; extras[i] ; i+=2) {
+	/*
+	 * Can assume that reference counts are all incremented.
+	 */
+
+	Tcl_DictObjPut(NULL, mapObj, Tcl_NewStringObj(extras[i], -1),
+		Tcl_NewStringObj(extras[i+1], -1));
+    }
+    Tcl_SetEnsembleMappingDict(interp, ensemble, mapObj);
+    return ensemble;
+}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tclIOGT.c b/generic/tclIOGT.c
new file mode 100644
index 0000000..7f61def
--- /dev/null
+++ b/generic/tclIOGT.c
@@ -0,0 +1,1441 @@
+/*
+ * tclIOGT.c --
+ *
+ *	Implements a generic transformation exposing the underlying API at the
+ *	script level. Contributed by Andreas Kupries.
+ *
+ * Copyright (c) 2000 Ajuba Solutions
+ * Copyright (c) 1999-2000 Andreas Kupries (a.kupries@westend.com)
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#include "tclInt.h"
+#include "tclIO.h"
+
+/*
+ * Forward declarations of internal procedures. First the driver procedures of
+ * the transformation.
+ */
+
+static int		TransformBlockModeProc(ClientData instanceData,
+			    int mode);
+static int		TransformCloseProc(ClientData instanceData,
+			    Tcl_Interp *interp);
+static int		TransformInputProc(ClientData instanceData, char *buf,
+			    int toRead, int *errorCodePtr);
+static int		TransformOutputProc(ClientData instanceData,
+			    const char *buf, int toWrite, int *errorCodePtr);
+static int		TransformSeekProc(ClientData instanceData, long offset,
+			    int mode, int *errorCodePtr);
+static int		TransformSetOptionProc(ClientData instanceData,
+			    Tcl_Interp *interp, const char *optionName,
+			    const char *value);
+static int		TransformGetOptionProc(ClientData instanceData,
+			    Tcl_Interp *interp, const char *optionName,
+			    Tcl_DString *dsPtr);
+static void		TransformWatchProc(ClientData instanceData, int mask);
+static int		TransformGetFileHandleProc(ClientData instanceData,
+			    int direction, ClientData *handlePtr);
+static int		TransformNotifyProc(ClientData instanceData, int mask);
+static Tcl_WideInt	TransformWideSeekProc(ClientData instanceData,
+			    Tcl_WideInt offset, int mode, int *errorCodePtr);
+
+/*
+ * Forward declarations of internal procedures. Secondly the procedures for
+ * handling and generating fileeevents.
+ */
+
+static void		TransformChannelHandlerTimer(ClientData clientData);
+
+/*
+ * Forward declarations of internal procedures. Third, helper procedures
+ * encapsulating essential tasks.
+ */
+
+typedef struct TransformChannelData TransformChannelData;
+
+static int		ExecuteCallback(TransformChannelData *ctrl,
+			    Tcl_Interp *interp, unsigned char *op,
+			    unsigned char *buf, int bufLen, int transmit,
+			    int preserve);
+
+/*
+ * Action codes to give to 'ExecuteCallback' (argument 'transmit'), telling
+ * the procedure what to do with the result of the script it calls.
+ */
+
+#define TRANSMIT_DONT	0	/* No transfer to do. */
+#define TRANSMIT_DOWN	1	/* Transfer to the underlying channel. */
+#define TRANSMIT_SELF	2	/* Transfer into our channel. */
+#define TRANSMIT_IBUF	3	/* Transfer to internal input buffer. */
+#define TRANSMIT_NUM	4	/* Transfer number to 'maxRead'. */
+
+/*
+ * Codes for 'preserve' of 'ExecuteCallback'.
+ */
+
+#define P_PRESERVE	1
+#define P_NO_PRESERVE	0
+
+/*
+ * Strings for the action codes delivered to the script implementing a
+ * transformation. Argument 'op' of 'ExecuteCallback'.
+ */
+
+#define A_CREATE_WRITE	(UCHARP("create/write"))
+#define A_DELETE_WRITE	(UCHARP("delete/write"))
+#define A_FLUSH_WRITE	(UCHARP("flush/write"))
+#define A_WRITE		(UCHARP("write"))
+
+#define A_CREATE_READ	(UCHARP("create/read"))
+#define A_DELETE_READ	(UCHARP("delete/read"))
+#define A_FLUSH_READ	(UCHARP("flush/read"))
+#define A_READ		(UCHARP("read"))
+
+#define A_QUERY_MAXREAD	(UCHARP("query/maxRead"))
+#define A_CLEAR_READ	(UCHARP("clear/read"))
+
+/*
+ * Management of a simple buffer.
+ */
+
+typedef struct ResultBuffer ResultBuffer;
+
+static inline void	ResultClear(ResultBuffer *r);
+static inline void	ResultInit(ResultBuffer *r);
+static inline int	ResultEmpty(ResultBuffer *r);
+static inline int	ResultCopy(ResultBuffer *r, unsigned char *buf,
+			    size_t toRead);
+static inline void	ResultAdd(ResultBuffer *r, unsigned char *buf,
+			    size_t toWrite);
+
+/*
+ * This structure describes the channel type structure for Tcl-based
+ * transformations.
+ */
+
+static const Tcl_ChannelType transformChannelType = {
+    "transform",		/* Type name. */
+    TCL_CHANNEL_VERSION_5,	/* v5 channel */
+    TransformCloseProc,		/* Close proc. */
+    TransformInputProc,		/* Input proc. */
+    TransformOutputProc,	/* Output proc. */
+    TransformSeekProc,		/* Seek proc. */
+    TransformSetOptionProc,	/* Set option proc. */
+    TransformGetOptionProc,	/* Get option proc. */
+    TransformWatchProc,		/* Initialize notifier. */
+    TransformGetFileHandleProc,	/* Get OS handles out of channel. */
+    NULL,			/* close2proc */
+    TransformBlockModeProc,	/* Set blocking/nonblocking mode.*/
+    NULL,			/* Flush proc. */
+    TransformNotifyProc,	/* Handling of events bubbling up. */
+    TransformWideSeekProc,	/* Wide seek proc. */
+    NULL,			/* Thread action. */
+    NULL			/* Truncate. */
+};
+
+/*
+ * Possible values for 'flags' field in control structure, see below.
+ */
+
+#define CHANNEL_ASYNC (1<<0)	/* Non-blocking mode. */
+
+/*
+ * Definition of the structure containing the information about the internal
+ * input buffer.
+ */
+
+struct ResultBuffer {
+    unsigned char *buf;		/* Reference to the buffer area. */
+    size_t allocated;		/* Allocated size of the buffer area. */
+    size_t used;		/* Number of bytes in the buffer, no more than
+				 * number allocated. */
+};
+
+/*
+ * Additional bytes to allocate during buffer expansion.
+ */
+
+#define INCREMENT	512
+
+/*
+ * Number of milliseconds to wait before firing an event to flush out
+ * information waiting in buffers (fileevent support).
+ */
+
+#define FLUSH_DELAY	5
+
+/*
+ * Convenience macro to make some casts easier to use.
+ */
+
+#define UCHARP(x)	((unsigned char *) (x))
+
+/*
+ * Definition of a structure used by all transformations generated here to
+ * maintain their local state.
+ */
+
+struct TransformChannelData {
+    /*
+     * General section. Data to integrate the transformation into the channel
+     * system.
+     */
+
+    Tcl_Channel self;		/* Our own Channel handle. */
+    int readIsFlushed;		/* Flag to note whether in.flushProc was
+				 * called or not. */
+    int eofPending;		/* Flag: EOF seen down, not raised up */
+    int flags;			/* Currently CHANNEL_ASYNC or zero. */
+    int watchMask;		/* Current watch/event/interest mask. */
+    int mode;			/* Mode of parent channel, OR'ed combination
+				 * of TCL_READABLE, TCL_WRITABLE. */
+    Tcl_TimerToken timer;	/* Timer for automatic flushing of information
+				 * sitting in an internal buffer. Required for
+				 * full fileevent support. */
+
+    /*
+     * Transformation specific data.
+     */
+
+    int maxRead;		/* Maximum allowed number of bytes to read, as
+				 * given to us by the Tcl script implementing
+				 * the transformation. */
+    Tcl_Interp *interp;		/* Reference to the interpreter which created
+				 * the transformation. Used to execute the
+				 * code below. */
+    Tcl_Obj *command;		/* Tcl code to execute for a buffer */
+    ResultBuffer result;	/* Internal buffer used to store the result of
+				 * a transformation of incoming data. Also
+				 * serves as buffer of all data not yet
+				 * consumed by the reader. */
+    int refCount;
+};
+
+static void
+PreserveData(
+    TransformChannelData *dataPtr)
+{
+    dataPtr->refCount++;
+}
+
+static void
+ReleaseData(
+    TransformChannelData *dataPtr)
+{
+    if (--dataPtr->refCount) {
+	return;
+    }
+    ResultClear(&dataPtr->result);
+    Tcl_DecrRefCount(dataPtr->command);
+    ckfree(dataPtr);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclChannelTransform --
+ *
+ *	Implements the Tcl "testchannel transform" debugging command. This is
+ *	part of the testing environment. This sets up a tcl script (cmdObjPtr)
+ *	to be used as a transform on the channel.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+	/* ARGSUSED */
+int
+TclChannelTransform(
+    Tcl_Interp *interp,		/* Interpreter for result. */
+    Tcl_Channel chan,		/* Channel to transform. */
+    Tcl_Obj *cmdObjPtr)		/* Script to use for transform. */
+{
+    Channel *chanPtr;		/* The actual channel. */
+    ChannelState *statePtr;	/* State info for channel. */
+    int mode;			/* Read/write mode of the channel. */
+    int objc;
+    TransformChannelData *dataPtr;
+    Tcl_DString ds;
+
+    if (chan == NULL) {
+	return TCL_ERROR;
+    }
+
+    if (TCL_OK != Tcl_ListObjLength(interp, cmdObjPtr, &objc)) {
+	Tcl_SetObjResult(interp,
+		Tcl_NewStringObj("-command value is not a list", -1));
+	return TCL_ERROR;
+    }
+
+    chanPtr = (Channel *) chan;
+    statePtr = chanPtr->state;
+    chanPtr = statePtr->topChanPtr;
+    chan = (Tcl_Channel) chanPtr;
+    mode = (statePtr->flags & (TCL_READABLE|TCL_WRITABLE));
+
+    /*
+     * Now initialize the transformation state and stack it upon the specified
+     * channel. One of the necessary things to do is to retrieve the blocking
+     * regime of the underlying channel and to use the same for us too.
+     */
+
+    dataPtr = ckalloc(sizeof(TransformChannelData));
+
+    dataPtr->refCount = 1;
+    Tcl_DStringInit(&ds);
+    Tcl_GetChannelOption(interp, chan, "-blocking", &ds);
+    dataPtr->readIsFlushed = 0;
+    dataPtr->eofPending = 0;
+    dataPtr->flags = 0;
+    if (ds.string[0] == '0') {
+	dataPtr->flags |= CHANNEL_ASYNC;
+    }
+    Tcl_DStringFree(&ds);
+
+    dataPtr->watchMask = 0;
+    dataPtr->mode = mode;
+    dataPtr->timer = NULL;
+    dataPtr->maxRead = 4096;	/* Initial value not relevant. */
+    dataPtr->interp = interp;
+    dataPtr->command = cmdObjPtr;
+    Tcl_IncrRefCount(dataPtr->command);
+
+    ResultInit(&dataPtr->result);
+
+    dataPtr->self = Tcl_StackChannel(interp, &transformChannelType, dataPtr,
+	    mode, chan);
+    if (dataPtr->self == NULL) {
+	Tcl_AppendPrintfToObj(Tcl_GetObjResult(interp),
+		"\nfailed to stack channel \"%s\"", Tcl_GetChannelName(chan));
+	ReleaseData(dataPtr);
+	return TCL_ERROR;
+    }
+    Tcl_Preserve(dataPtr->self);
+
+    /*
+     * At last initialize the transformation at the script level.
+     */
+
+    PreserveData(dataPtr);
+    if ((dataPtr->mode & TCL_WRITABLE) && ExecuteCallback(dataPtr, NULL,
+	    A_CREATE_WRITE, NULL, 0, TRANSMIT_DONT, P_NO_PRESERVE) != TCL_OK){
+	Tcl_UnstackChannel(interp, chan);
+	ReleaseData(dataPtr);
+	return TCL_ERROR;
+    }
+
+    if ((dataPtr->mode & TCL_READABLE) && ExecuteCallback(dataPtr, NULL,
+	    A_CREATE_READ, NULL, 0, TRANSMIT_DONT, P_NO_PRESERVE) != TCL_OK) {
+	ExecuteCallback(dataPtr, NULL, A_DELETE_WRITE, NULL, 0, TRANSMIT_DONT,
+		P_NO_PRESERVE);
+	Tcl_UnstackChannel(interp, chan);
+	ReleaseData(dataPtr);
+	return TCL_ERROR;
+    }
+
+    ReleaseData(dataPtr);
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ExecuteCallback --
+ *
+ *	Executes the defined callback for buffer and operation.
+ *
+ * Side effects:
+ *	As of the executed tcl script.
+ *
+ * Result:
+ *	A standard TCL error code. In case of an error a message is left in
+ *	the result area of the specified interpreter.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+ExecuteCallback(
+    TransformChannelData *dataPtr,
+				/* Transformation with the callback. */
+    Tcl_Interp *interp,		/* Current interpreter, possibly NULL. */
+    unsigned char *op,		/* Operation invoking the callback. */
+    unsigned char *buf,		/* Buffer to give to the script. */
+    int bufLen,			/* And its length. */
+    int transmit,		/* Flag, determines whether the result of the
+				 * callback is sent to the underlying channel
+				 * or not. */
+    int preserve)		/* Flag. If true the procedure will preserve
+				 * the result state of all accessed
+				 * interpreters. */
+{
+    Tcl_Obj *resObj;		/* See below, switch (transmit). */
+    int resLen;
+    unsigned char *resBuf;
+    Tcl_InterpState state = NULL;
+    int res = TCL_OK;
+    Tcl_Obj *command = TclListObjCopy(NULL, dataPtr->command);
+    Tcl_Interp *eval = dataPtr->interp;
+
+    Tcl_Preserve(eval);
+
+    /*
+     * Step 1, create the complete command to execute. Do this by appending
+     * operation and buffer to operate upon to a copy of the callback
+     * definition. We *cannot* create a list containing 3 objects and then use
+     * 'Tcl_EvalObjv', because the command may contain additional prefixed
+     * arguments. Feather's curried commands would come in handy here.
+     */
+
+    if (preserve == P_PRESERVE) {
+	state = Tcl_SaveInterpState(eval, res);
+    }
+
+    Tcl_IncrRefCount(command);
+    Tcl_ListObjAppendElement(NULL, command, Tcl_NewStringObj((char *) op, -1));
+
+    /*
+     * Use a byte-array to prevent the misinterpretation of binary data coming
+     * through as UTF while at the tcl level.
+     */
+
+    Tcl_ListObjAppendElement(NULL, command, Tcl_NewByteArrayObj(buf, bufLen));
+
+    /*
+     * Step 2, execute the command at the global level of the interpreter used
+     * to create the transformation. Destroy the command afterward. If an
+     * error occured and the current interpreter is defined and not equal to
+     * the interpreter for the callback, then copy the error message into
+     * current interpreter. Don't copy if in preservation mode.
+     */
+
+    res = Tcl_EvalObjEx(eval, command, TCL_EVAL_GLOBAL);
+    Tcl_DecrRefCount(command);
+    command = NULL;
+
+    if ((res != TCL_OK) && (interp != NULL) && (eval != interp)
+	    && (preserve == P_NO_PRESERVE)) {
+	Tcl_SetObjResult(interp, Tcl_GetObjResult(eval));
+	Tcl_Release(eval);
+	return res;
+    }
+
+    /*
+     * Step 3, transmit a possible conversion result to the underlying
+     * channel, or ourselves.
+     */
+
+    switch (transmit) {
+    case TRANSMIT_DONT:
+	/* nothing to do */
+	break;
+
+    case TRANSMIT_DOWN:
+	if (dataPtr->self == NULL) {
+	    break;
+	}
+	resObj = Tcl_GetObjResult(eval);
+	resBuf = Tcl_GetByteArrayFromObj(resObj, &resLen);
+	Tcl_WriteRaw(Tcl_GetStackedChannel(dataPtr->self), (char *) resBuf,
+		resLen);
+	break;
+
+    case TRANSMIT_SELF:
+	if (dataPtr->self == NULL) {
+	    break;
+	}
+	resObj = Tcl_GetObjResult(eval);
+	resBuf = Tcl_GetByteArrayFromObj(resObj, &resLen);
+	Tcl_WriteRaw(dataPtr->self, (char *) resBuf, resLen);
+	break;
+
+    case TRANSMIT_IBUF:
+	resObj = Tcl_GetObjResult(eval);
+	resBuf = Tcl_GetByteArrayFromObj(resObj, &resLen);
+	ResultAdd(&dataPtr->result, resBuf, resLen);
+	break;
+
+    case TRANSMIT_NUM:
+	/*
+	 * Interpret result as integer number.
+	 */
+
+	resObj = Tcl_GetObjResult(eval);
+	TclGetIntFromObj(eval, resObj, &dataPtr->maxRead);
+	break;
+    }
+
+    Tcl_ResetResult(eval);
+    if (preserve == P_PRESERVE) {
+	(void) Tcl_RestoreInterpState(eval, state);
+    }
+    Tcl_Release(eval);
+    return res;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TransformBlockModeProc --
+ *
+ *	Trap handler. Called by the generic IO system during option processing
+ *	to change the blocking mode of the channel.
+ *
+ * Side effects:
+ *	Forwards the request to the underlying channel.
+ *
+ * Result:
+ *	0 if successful, errno when failed.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+TransformBlockModeProc(
+    ClientData instanceData,	/* State of transformation. */
+    int mode)			/* New blocking mode. */
+{
+    TransformChannelData *dataPtr = instanceData;
+
+    if (mode == TCL_MODE_NONBLOCKING) {
+	dataPtr->flags |= CHANNEL_ASYNC;
+    } else {
+	dataPtr->flags &= ~CHANNEL_ASYNC;
+    }
+    return 0;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TransformCloseProc --
+ *
+ *	Trap handler. Called by the generic IO system during destruction of
+ *	the transformation channel.
+ *
+ * Side effects:
+ *	Releases the memory allocated in 'Tcl_TransformObjCmd'.
+ *
+ * Result:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+TransformCloseProc(
+    ClientData instanceData,
+    Tcl_Interp *interp)
+{
+    TransformChannelData *dataPtr = instanceData;
+
+    /*
+     * Important: In this procedure 'dataPtr->self' already points to the
+     * underlying channel.
+     *
+     * There is no need to cancel an existing channel handler, this is already
+     * done. Either by 'Tcl_UnstackChannel' or by the general cleanup in
+     * 'Tcl_Close'.
+     *
+     * But we have to cancel an active timer to prevent it from firing on the
+     * removed channel.
+     */
+
+    if (dataPtr->timer != NULL) {
+	Tcl_DeleteTimerHandler(dataPtr->timer);
+	dataPtr->timer = NULL;
+    }
+
+    /*
+     * Now flush data waiting in internal buffers to output and input. The
+     * input must be done despite the fact that there is no real receiver for
+     * it anymore. But the scripts might have sideeffects other parts of the
+     * system rely on (f.e. signaling the close to interested parties).
+     */
+
+    PreserveData(dataPtr);
+    if (dataPtr->mode & TCL_WRITABLE) {
+	ExecuteCallback(dataPtr, interp, A_FLUSH_WRITE, NULL, 0,
+		TRANSMIT_DOWN, P_PRESERVE);
+    }
+
+    if ((dataPtr->mode & TCL_READABLE) && !dataPtr->readIsFlushed) {
+	dataPtr->readIsFlushed = 1;
+	ExecuteCallback(dataPtr, interp, A_FLUSH_READ, NULL, 0, TRANSMIT_IBUF,
+		P_PRESERVE);
+    }
+
+    if (dataPtr->mode & TCL_WRITABLE) {
+	ExecuteCallback(dataPtr, interp, A_DELETE_WRITE, NULL, 0,
+		TRANSMIT_DONT, P_PRESERVE);
+    }
+    if (dataPtr->mode & TCL_READABLE) {
+	ExecuteCallback(dataPtr, interp, A_DELETE_READ, NULL, 0,
+		TRANSMIT_DONT, P_PRESERVE);
+    }
+    ReleaseData(dataPtr);
+
+    /*
+     * General cleanup.
+     */
+
+    Tcl_Release(dataPtr->self);
+    dataPtr->self = NULL;
+    ReleaseData(dataPtr);
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TransformInputProc --
+ *
+ *	Called by the generic IO system to convert read data.
+ *
+ * Side effects:
+ *	As defined by the conversion.
+ *
+ * Result:
+ *	A transformed buffer.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+TransformInputProc(
+    ClientData instanceData,
+    char *buf,
+    int toRead,
+    int *errorCodePtr)
+{
+    TransformChannelData *dataPtr = instanceData;
+    int gotBytes, read, copied;
+    Tcl_Channel downChan;
+
+    /*
+     * Should assert(dataPtr->mode & TCL_READABLE);
+     */
+
+    if (toRead == 0 || dataPtr->self == NULL) {
+	/*
+	 * Catch a no-op. TODO: Is this a panic()?
+	 */
+	return 0;
+    }
+
+    gotBytes = 0;
+    downChan = Tcl_GetStackedChannel(dataPtr->self);
+
+    PreserveData(dataPtr);
+    while (toRead > 0) {
+	/*
+	 * Loop until the request is satisfied (or no data is available from
+	 * below, possibly EOF).
+	 */
+
+	copied = ResultCopy(&dataPtr->result, UCHARP(buf), toRead);
+	toRead -= copied;
+	buf += copied;
+	gotBytes += copied;
+
+	if (toRead == 0) {
+	    /*
+	     * The request was completely satisfied from our buffers. We can
+	     * break out of the loop and return to the caller.
+	     */
+
+	    break;
+	}
+
+	/*
+	 * Length (dataPtr->result) == 0, toRead > 0 here. Use the incoming
+	 * 'buf'! as target to store the intermediary information read from
+	 * the underlying channel.
+	 *
+	 * Ask the tcl level how much data it allows us to read from the
+	 * underlying channel. This feature allows the transform to signal EOF
+	 * upstream although there is none downstream. Useful to control an
+	 * unbounded 'fcopy', either through counting bytes, or by pattern
+	 * matching.
+	 */
+
+	ExecuteCallback(dataPtr, NULL, A_QUERY_MAXREAD, NULL, 0,
+		TRANSMIT_NUM /* -> maxRead */, P_PRESERVE);
+
+	if (dataPtr->maxRead >= 0) {
+	    if (dataPtr->maxRead < toRead) {
+		toRead = dataPtr->maxRead;
+	    }
+	} /* else: 'maxRead < 0' == Accept the current value of toRead. */
+	if (toRead <= 0) {
+	    break;
+	}
+	if (dataPtr->eofPending) {
+	    /*
+	     * Already saw EOF from downChan; don't ask again.
+	     * NOTE: Could move this up to avoid the last maxRead
+	     * execution.  Believe this would still be correct behavior,
+	     * but the test suite tests the whole command callback
+	     * sequence, so leave it unchanged for now.
+	     */
+
+	    break;
+	}
+
+	/*
+	 * Get bytes from the underlying channel.
+	 */
+
+	read = Tcl_ReadRaw(downChan, buf, toRead);
+	if (read < 0) {
+	    if (Tcl_InputBlocked(downChan) && (gotBytes > 0)) {
+		/*
+		 * Zero bytes available from downChan because blocked.
+		 * But nonzero bytes already copied, so total is a
+		 * valid blocked short read. Return to caller.
+		 */
+
+		break;
+	    }
+
+	    /*
+	     * Either downChan is not blocked (there's a real error).
+	     * or it is and there are no bytes copied yet.  In either
+	     * case we want to pass the "error" along to the caller,
+	     * either to report an error, or to signal to the caller
+	     * that zero bytes are available because blocked.
+	     */
+
+	    *errorCodePtr = Tcl_GetErrno();
+	    gotBytes = -1;
+	    break;
+	} else if (read == 0) {
+
+	    /*
+	     * Zero returned from Tcl_ReadRaw() always indicates EOF
+	     * on the down channel.
+	     */
+
+	    dataPtr->eofPending = 1;
+	    dataPtr->readIsFlushed = 1;
+	    ExecuteCallback(dataPtr, NULL, A_FLUSH_READ, NULL, 0,
+		    TRANSMIT_IBUF, P_PRESERVE);
+
+	    if (ResultEmpty(&dataPtr->result)) {
+		/*
+		 * We had nothing to flush.
+		 */
+
+		break;
+	    }
+
+	    continue;		/* at: while (toRead > 0) */
+	} /* read == 0 */
+
+	/*
+	 * Transform the read chunk and add the result to our read buffer
+	 * (dataPtr->result).
+	 */
+
+	if (ExecuteCallback(dataPtr, NULL, A_READ, UCHARP(buf), read,
+		TRANSMIT_IBUF, P_PRESERVE) != TCL_OK) {
+	    *errorCodePtr = EINVAL;
+	    gotBytes = -1;
+	    break;
+	}
+    } /* while toRead > 0 */
+
+    if (gotBytes == 0) {
+	dataPtr->eofPending = 0;
+    }
+    ReleaseData(dataPtr);
+    return gotBytes;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TransformOutputProc --
+ *
+ *	Called by the generic IO system to convert data waiting to be written.
+ *
+ * Side effects:
+ *	As defined by the transformation.
+ *
+ * Result:
+ *	A transformed buffer.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+TransformOutputProc(
+    ClientData instanceData,
+    const char *buf,
+    int toWrite,
+    int *errorCodePtr)
+{
+    TransformChannelData *dataPtr = instanceData;
+
+    /*
+     * Should assert(dataPtr->mode & TCL_WRITABLE);
+     */
+
+    if (toWrite == 0) {
+	/*
+	 * Catch a no-op.
+	 */
+
+	return 0;
+    }
+
+    PreserveData(dataPtr);
+    if (ExecuteCallback(dataPtr, NULL, A_WRITE, UCHARP(buf), toWrite,
+	    TRANSMIT_DOWN, P_NO_PRESERVE) != TCL_OK) {
+	*errorCodePtr = EINVAL;
+	toWrite = -1;
+    }
+    ReleaseData(dataPtr);
+
+    return toWrite;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TransformSeekProc --
+ *
+ *	This procedure is called by the generic IO level to move the access
+ *	point in a channel.
+ *
+ * Side effects:
+ *	Moves the location at which the channel will be accessed in future
+ *	operations. Flushes all transformation buffers, then forwards it to
+ *	the underlying channel.
+ *
+ * Result:
+ *	-1 if failed, the new position if successful. An output argument
+ *	contains the POSIX error code if an error occurred, or zero.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+TransformSeekProc(
+    ClientData instanceData,	/* The channel to manipulate. */
+    long offset,		/* Size of movement. */
+    int mode,			/* How to move. */
+    int *errorCodePtr)		/* Location of error flag. */
+{
+    TransformChannelData *dataPtr = instanceData;
+    Tcl_Channel parent = Tcl_GetStackedChannel(dataPtr->self);
+    const Tcl_ChannelType *parentType = Tcl_GetChannelType(parent);
+    Tcl_DriverSeekProc *parentSeekProc = Tcl_ChannelSeekProc(parentType);
+
+    if ((offset == 0) && (mode == SEEK_CUR)) {
+	/*
+	 * This is no seek but a request to tell the caller the current
+	 * location. Simply pass the request down.
+	 */
+
+	return parentSeekProc(Tcl_GetChannelInstanceData(parent), offset,
+		mode, errorCodePtr);
+    }
+
+    /*
+     * It is a real request to change the position. Flush all data waiting for
+     * output and discard everything in the input buffers. Then pass the
+     * request down, unchanged.
+     */
+
+    PreserveData(dataPtr);
+    if (dataPtr->mode & TCL_WRITABLE) {
+	ExecuteCallback(dataPtr, NULL, A_FLUSH_WRITE, NULL, 0, TRANSMIT_DOWN,
+		P_NO_PRESERVE);
+    }
+
+    if (dataPtr->mode & TCL_READABLE) {
+	ExecuteCallback(dataPtr, NULL, A_CLEAR_READ, NULL, 0, TRANSMIT_DONT,
+		P_NO_PRESERVE);
+	ResultClear(&dataPtr->result);
+	dataPtr->readIsFlushed = 0;
+	dataPtr->eofPending = 0;
+    }
+    ReleaseData(dataPtr);
+
+    return parentSeekProc(Tcl_GetChannelInstanceData(parent), offset, mode,
+	    errorCodePtr);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TransformWideSeekProc --
+ *
+ *	This procedure is called by the generic IO level to move the access
+ *	point in a channel, with a (potentially) 64-bit offset.
+ *
+ * Side effects:
+ *	Moves the location at which the channel will be accessed in future
+ *	operations. Flushes all transformation buffers, then forwards it to
+ *	the underlying channel.
+ *
+ * Result:
+ *	-1 if failed, the new position if successful. An output argument
+ *	contains the POSIX error code if an error occurred, or zero.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static Tcl_WideInt
+TransformWideSeekProc(
+    ClientData instanceData,	/* The channel to manipulate. */
+    Tcl_WideInt offset,		/* Size of movement. */
+    int mode,			/* How to move. */
+    int *errorCodePtr)		/* Location of error flag. */
+{
+    TransformChannelData *dataPtr = instanceData;
+    Tcl_Channel parent = Tcl_GetStackedChannel(dataPtr->self);
+    const Tcl_ChannelType *parentType	= Tcl_GetChannelType(parent);
+    Tcl_DriverSeekProc *parentSeekProc = Tcl_ChannelSeekProc(parentType);
+    Tcl_DriverWideSeekProc *parentWideSeekProc =
+	    Tcl_ChannelWideSeekProc(parentType);
+    ClientData parentData = Tcl_GetChannelInstanceData(parent);
+
+    if ((offset == Tcl_LongAsWide(0)) && (mode == SEEK_CUR)) {
+	/*
+	 * This is no seek but a request to tell the caller the current
+	 * location. Simply pass the request down.
+	 */
+
+	if (parentWideSeekProc != NULL) {
+	    return parentWideSeekProc(parentData, offset, mode, errorCodePtr);
+	}
+
+	return Tcl_LongAsWide(parentSeekProc(parentData, 0, mode,
+		errorCodePtr));
+    }
+
+    /*
+     * It is a real request to change the position. Flush all data waiting for
+     * output and discard everything in the input buffers. Then pass the
+     * request down, unchanged.
+     */
+
+    PreserveData(dataPtr);
+    if (dataPtr->mode & TCL_WRITABLE) {
+	ExecuteCallback(dataPtr, NULL, A_FLUSH_WRITE, NULL, 0, TRANSMIT_DOWN,
+		P_NO_PRESERVE);
+    }
+
+    if (dataPtr->mode & TCL_READABLE) {
+	ExecuteCallback(dataPtr, NULL, A_CLEAR_READ, NULL, 0, TRANSMIT_DONT,
+		P_NO_PRESERVE);
+	ResultClear(&dataPtr->result);
+	dataPtr->readIsFlushed = 0;
+	dataPtr->eofPending = 0;
+    }
+    ReleaseData(dataPtr);
+
+    /*
+     * If we have a wide seek capability, we should stick with that.
+     */
+
+    if (parentWideSeekProc != NULL) {
+	return parentWideSeekProc(parentData, offset, mode, errorCodePtr);
+    }
+
+    /*
+     * We're transferring to narrow seeks at this point; this is a bit complex
+     * because we have to check whether the seek is possible first (i.e.
+     * whether we are losing information in truncating the bits of the
+     * offset). Luckily, there's a defined error for what happens when trying
+     * to go out of the representable range.
+     */
+
+    if (offset<Tcl_LongAsWide(LONG_MIN) || offset>Tcl_LongAsWide(LONG_MAX)) {
+	*errorCodePtr = EOVERFLOW;
+	return Tcl_LongAsWide(-1);
+    }
+
+    return Tcl_LongAsWide(parentSeekProc(parentData, Tcl_WideAsLong(offset),
+	    mode, errorCodePtr));
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TransformSetOptionProc --
+ *
+ *	Called by generic layer to handle the reconfiguration of channel
+ *	specific options. As this channel type does not have such, it simply
+ *	passes all requests downstream.
+ *
+ * Side effects:
+ *	As defined by the channel downstream.
+ *
+ * Result:
+ *	A standard TCL error code.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+TransformSetOptionProc(
+    ClientData instanceData,
+    Tcl_Interp *interp,
+    const char *optionName,
+    const char *value)
+{
+    TransformChannelData *dataPtr = instanceData;
+    Tcl_Channel downChan = Tcl_GetStackedChannel(dataPtr->self);
+    Tcl_DriverSetOptionProc *setOptionProc;
+
+    setOptionProc = Tcl_ChannelSetOptionProc(Tcl_GetChannelType(downChan));
+    if (setOptionProc == NULL) {
+	return TCL_ERROR;
+    }
+
+    return setOptionProc(Tcl_GetChannelInstanceData(downChan), interp,
+	    optionName, value);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TransformGetOptionProc --
+ *
+ *	Called by generic layer to handle requests for the values of channel
+ *	specific options. As this channel type does not have such, it simply
+ *	passes all requests downstream.
+ *
+ * Side effects:
+ *	As defined by the channel downstream.
+ *
+ * Result:
+ *	A standard TCL error code.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+TransformGetOptionProc(
+    ClientData instanceData,
+    Tcl_Interp *interp,
+    const char *optionName,
+    Tcl_DString *dsPtr)
+{
+    TransformChannelData *dataPtr = instanceData;
+    Tcl_Channel downChan = Tcl_GetStackedChannel(dataPtr->self);
+    Tcl_DriverGetOptionProc *getOptionProc;
+
+    getOptionProc = Tcl_ChannelGetOptionProc(Tcl_GetChannelType(downChan));
+    if (getOptionProc != NULL) {
+	return getOptionProc(Tcl_GetChannelInstanceData(downChan), interp,
+		optionName, dsPtr);
+    } else if (optionName == NULL) {
+	/*
+	 * Request is query for all options, this is ok.
+	 */
+
+	return TCL_OK;
+    }
+
+    /*
+     * Request for a specific option has to fail, since we don't have any.
+     */
+
+    return TCL_ERROR;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TransformWatchProc --
+ *
+ *	Initialize the notifier to watch for events from this channel.
+ *
+ * Side effects:
+ *	Sets up the notifier so that a future event on the channel will be
+ *	seen by Tcl.
+ *
+ * Result:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+	/* ARGSUSED */
+static void
+TransformWatchProc(
+    ClientData instanceData,	/* Channel to watch. */
+    int mask)			/* Events of interest. */
+{
+    TransformChannelData *dataPtr = instanceData;
+    Tcl_Channel downChan;
+
+    /*
+     * The caller expressed interest in events occuring for this channel. We
+     * are forwarding the call to the underlying channel now.
+     */
+
+    dataPtr->watchMask = mask;
+
+    /*
+     * No channel handlers any more. We will be notified automatically about
+     * events on the channel below via a call to our 'TransformNotifyProc'.
+     * But we have to pass the interest down now. We are allowed to add
+     * additional 'interest' to the mask if we want to. But this
+     * transformation has no such interest. It just passes the request down,
+     * unchanged.
+     */
+
+    if (dataPtr->self == NULL) {
+	return;
+    }
+    downChan = Tcl_GetStackedChannel(dataPtr->self);
+
+    Tcl_GetChannelType(downChan)->watchProc(
+	    Tcl_GetChannelInstanceData(downChan), mask);
+
+    /*
+     * Management of the internal timer.
+     */
+
+    if ((dataPtr->timer != NULL) &&
+	    (!(mask & TCL_READABLE) || ResultEmpty(&dataPtr->result))) {
+	/*
+	 * A pending timer exists, but either is there no (more) interest in
+	 * the events it generates or nothing is available for reading, so
+	 * remove it.
+	 */
+
+	Tcl_DeleteTimerHandler(dataPtr->timer);
+	dataPtr->timer = NULL;
+    }
+
+    if ((dataPtr->timer == NULL) && (mask & TCL_READABLE)
+	    && !ResultEmpty(&dataPtr->result)) {
+	/*
+	 * There is no pending timer, but there is interest in readable events
+	 * and we actually have data waiting, so generate a timer to flush
+	 * that.
+	 */
+
+	dataPtr->timer = Tcl_CreateTimerHandler(FLUSH_DELAY,
+		TransformChannelHandlerTimer, dataPtr);
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TransformGetFileHandleProc --
+ *
+ *	Called from Tcl_GetChannelHandle to retrieve OS specific file handle
+ *	from inside this channel.
+ *
+ * Side effects:
+ *	None.
+ *
+ * Result:
+ *	The appropriate Tcl_File or NULL if not present.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+TransformGetFileHandleProc(
+    ClientData instanceData,	/* Channel to query. */
+    int direction,		/* Direction of interest. */
+    ClientData *handlePtr)	/* Place to store the handle into. */
+{
+    TransformChannelData *dataPtr = instanceData;
+
+    /*
+     * Return the handle belonging to parent channel. IOW, pass the request
+     * down and the result up.
+     */
+
+    return Tcl_GetChannelHandle(Tcl_GetStackedChannel(dataPtr->self),
+	    direction, handlePtr);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TransformNotifyProc --
+ *
+ *	Handler called by Tcl to inform us of activity on the underlying
+ *	channel.
+ *
+ * Side effects:
+ *	May process the incoming event by itself.
+ *
+ * Result:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+TransformNotifyProc(
+    ClientData clientData,	/* The state of the notified
+				 * transformation. */
+    int mask)			/* The mask of occuring events. */
+{
+    TransformChannelData *dataPtr = clientData;
+
+    /*
+     * An event occured in the underlying channel. This transformation doesn't
+     * process such events thus returns the incoming mask unchanged.
+     */
+
+    if (dataPtr->timer != NULL) {
+	/*
+	 * Delete an existing timer. It was not fired, yet we are here, so the
+	 * channel below generated such an event and we don't have to. The
+	 * renewal of the interest after the execution of channel handlers
+	 * will eventually cause us to recreate the timer (in
+	 * TransformWatchProc).
+	 */
+
+	Tcl_DeleteTimerHandler(dataPtr->timer);
+	dataPtr->timer = NULL;
+    }
+    return mask;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TransformChannelHandlerTimer --
+ *
+ *	Called by the notifier (-> timer) to flush out information waiting in
+ *	the input buffer.
+ *
+ * Side effects:
+ *	As of 'Tcl_NotifyChannel'.
+ *
+ * Result:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+TransformChannelHandlerTimer(
+    ClientData clientData)	/* Transformation to query. */
+{
+    TransformChannelData *dataPtr = clientData;
+
+    dataPtr->timer = NULL;
+    if (!(dataPtr->watchMask&TCL_READABLE) || ResultEmpty(&dataPtr->result)) {
+	/*
+	 * The timer fired, but either is there no (more) interest in the
+	 * events it generates or nothing is available for reading, so ignore
+	 * it and don't recreate it.
+	 */
+
+	return;
+    }
+    Tcl_NotifyChannel(dataPtr->self, TCL_READABLE);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ResultClear --
+ *
+ *	Deallocates any memory allocated by 'ResultAdd'.
+ *
+ * Side effects:
+ *	See above.
+ *
+ * Result:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static inline void
+ResultClear(
+    ResultBuffer *r)		/* Reference to the buffer to clear out. */
+{
+    r->used = 0;
+
+    if (r->allocated) {
+	ckfree(r->buf);
+	r->buf = NULL;
+	r->allocated = 0;
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ResultInit --
+ *
+ *	Initializes the specified buffer structure. The structure will contain
+ *	valid information for an emtpy buffer.
+ *
+ * Side effects:
+ *	See above.
+ *
+ * Result:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static inline void
+ResultInit(
+    ResultBuffer *r)		/* Reference to the structure to
+				 * initialize. */
+{
+    r->used = 0;
+    r->allocated = 0;
+    r->buf = NULL;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ResultEmpty --
+ *
+ *	Returns whether the number of bytes stored in the buffer is zero.
+ *
+ * Side effects:
+ *	None.
+ *
+ * Result:
+ *	A boolean.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static inline int
+ResultEmpty(
+    ResultBuffer *r)		/* The structure to query. */
+{
+    return r->used == 0;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ResultCopy --
+ *
+ *	Copies the requested number of bytes from the buffer into the
+ *	specified array and removes them from the buffer afterward. Copies
+ *	less if there is not enough data in the buffer.
+ *
+ * Side effects:
+ *	See above.
+ *
+ * Result:
+ *	The number of actually copied bytes, possibly less than 'toRead'.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static inline int
+ResultCopy(
+    ResultBuffer *r,		/* The buffer to read from. */
+    unsigned char *buf,		/* The buffer to copy into. */
+    size_t toRead)		/* Number of requested bytes. */
+{
+    if (r->used == 0) {
+	/*
+	 * Nothing to copy in the case of an empty buffer.
+	 */
+
+	return 0;
+    } else if (r->used == toRead) {
+	/*
+	 * We have just enough. Copy everything to the caller.
+	 */
+
+	memcpy(buf, r->buf, toRead);
+	r->used = 0;
+    } else if (r->used > toRead) {
+	/*
+	 * The internal buffer contains more than requested. Copy the
+	 * requested subset to the caller, and shift the remaining bytes down.
+	 */
+
+	memcpy(buf, r->buf, toRead);
+	memmove(r->buf, r->buf + toRead, r->used - toRead);
+	r->used -= toRead;
+    } else {
+	/*
+	 * There is not enough in the buffer to satisfy the caller, so take
+	 * everything.
+	 */
+
+	memcpy(buf, r->buf, r->used);
+	toRead = r->used;
+	r->used = 0;
+    }
+    return toRead;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ResultAdd --
+ *
+ *	Adds the bytes in the specified array to the buffer, by appending it.
+ *
+ * Side effects:
+ *	See above.
+ *
+ * Result:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static inline void
+ResultAdd(
+    ResultBuffer *r,		/* The buffer to extend. */
+    unsigned char *buf,		/* The buffer to read from. */
+    size_t toWrite)		/* The number of bytes in 'buf'. */
+{
+    if (r->used + toWrite > r->allocated) {
+	/*
+	 * Extension of the internal buffer is required.
+	 */
+
+	if (r->allocated == 0) {
+	    r->allocated = toWrite + INCREMENT;
+	    r->buf = ckalloc(r->allocated);
+	} else {
+	    r->allocated += toWrite + INCREMENT;
+	    r->buf = ckrealloc(r->buf, r->allocated);
+	}
+    }
+
+    /*
+     * Now we may copy the data.
+     */
+
+    memcpy(r->buf + r->used, buf, toWrite);
+    r->used += toWrite;
+}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tclIORChan.c b/generic/tclIORChan.c
new file mode 100644
index 0000000..f476a1a
--- /dev/null
+++ b/generic/tclIORChan.c
@@ -0,0 +1,3292 @@
+/*
+ * tclIORChan.c --
+ *
+ *	This file contains the implementation of Tcl's generic channel
+ *	reflection code, which allows the implementation of Tcl channels in
+ *	Tcl code.
+ *
+ *	Parts of this file are based on code contributed by Jean-Claude
+ *	Wippler.
+ *
+ *	See TIP #219 for the specification of this functionality.
+ *
+ * Copyright (c) 2004-2005 ActiveState, a divison of Sophos
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#include "tclInt.h"
+#include "tclIO.h"
+#include <assert.h>
+
+#ifndef EINVAL
+#define EINVAL	9
+#endif
+#ifndef EOK
+#define EOK	0
+#endif
+
+/*
+ * Signatures of all functions used in the C layer of the reflection.
+ */
+
+static int		ReflectClose(ClientData clientData,
+			    Tcl_Interp *interp);
+static int		ReflectInput(ClientData clientData, char *buf,
+			    int toRead, int *errorCodePtr);
+static int		ReflectOutput(ClientData clientData, const char *buf,
+			    int toWrite, int *errorCodePtr);
+static void		ReflectWatch(ClientData clientData, int mask);
+static int		ReflectBlock(ClientData clientData, int mode);
+#ifdef TCL_THREADS
+static void		ReflectThread(ClientData clientData, int action);
+#endif
+static Tcl_WideInt	ReflectSeekWide(ClientData clientData,
+			    Tcl_WideInt offset, int mode, int *errorCodePtr);
+static int		ReflectSeek(ClientData clientData, long offset,
+			    int mode, int *errorCodePtr);
+static int		ReflectGetOption(ClientData clientData,
+			    Tcl_Interp *interp, const char *optionName,
+			    Tcl_DString *dsPtr);
+static int		ReflectSetOption(ClientData clientData,
+			    Tcl_Interp *interp, const char *optionName,
+			    const char *newValue);
+
+/*
+ * The C layer channel type/driver definition used by the reflection. This is
+ * a version 3 structure.
+ */
+
+static const Tcl_ChannelType tclRChannelType = {
+    "tclrchannel",	   /* Type name.				  */
+    TCL_CHANNEL_VERSION_5, /* v5 channel */
+    ReflectClose,	   /* Close channel, clean instance data	  */
+    ReflectInput,	   /* Handle read request			  */
+    ReflectOutput,	   /* Handle write request			  */
+    ReflectSeek,	   /* Move location of access point.	NULL'able */
+    ReflectSetOption,	   /* Set options.			NULL'able */
+    ReflectGetOption,	   /* Get options.			NULL'able */
+    ReflectWatch,	   /* Initialize notifier			  */
+    NULL,		   /* Get OS handle from the channel.	NULL'able */
+    NULL,		   /* No close2 support.		NULL'able */
+    ReflectBlock,	   /* Set blocking/nonblocking.		NULL'able */
+    NULL,		   /* Flush channel. Not used by core.	NULL'able */
+    NULL,		   /* Handle events.			NULL'able */
+    ReflectSeekWide,	   /* Move access point (64 bit).	NULL'able */
+#ifdef TCL_THREADS
+    ReflectThread,         /* thread action, tracking owner */
+#else
+    NULL,		   /* thread action */
+#endif
+    NULL		   /* truncate */
+};
+
+/*
+ * Instance data for a reflected channel. ===========================
+ */
+
+typedef struct {
+    Tcl_Channel chan;		/* Back reference to generic channel
+				 * structure. */
+    Tcl_Interp *interp;		/* Reference to the interpreter containing the
+				 * Tcl level part of the channel. NULL here
+				 * signals the channel is dead because the
+				 * interpreter/thread containing its Tcl
+				 * command is gone.
+				 */
+#ifdef TCL_THREADS
+    Tcl_ThreadId thread;	/* Thread the 'interp' belongs to. == Handler thread */
+    Tcl_ThreadId owner;         /* Thread owning the structure.    == Channel thread */
+#endif
+    Tcl_Obj *cmd;		/* Callback command prefix */
+    Tcl_Obj *methods;		/* Methods to append to command prefix */
+    Tcl_Obj *name;		/* Name of the channel as created */
+
+    int mode;			/* Mask of R/W mode */
+    int interest;		/* Mask of events the channel is interested
+				 * in. */
+
+    int dead;			/* Boolean signal that some operations
+				 * should no longer be attempted. */
+
+    /*
+     * Note regarding the usage of timers.
+     *
+     * Most channel implementations need a timer in the C level to ensure that
+     * data in buffers is flushed out through the generation of fake file
+     * events.
+     *
+     * See 'rechan', 'memchan', etc.
+     *
+     * Here this is _not_ required. Interest in events is posted to the Tcl
+     * level via 'watch'. And posting of events is possible from the Tcl level
+     * as well, via 'chan postevent'. This means that the generation of all
+     * events, fake or not, timer based or not, is completely in the hands of
+     * the Tcl level. Therefore no timer here.
+     */
+} ReflectedChannel;
+
+/*
+ * Structure of the table maping from channel handles to reflected
+ * channels. Each interpreter which has the handler command for one or more
+ * reflected channels records them in such a table, so that 'chan postevent'
+ * is able to find them even if the actual channel was moved to a different
+ * interpreter and/or thread.
+ *
+ * The table is reachable via the standard interpreter AssocData, the key is
+ * defined below.
+ */
+
+typedef struct {
+    Tcl_HashTable map;
+} ReflectedChannelMap;
+
+#define RCMKEY "ReflectedChannelMap"
+
+/*
+ * Event literals. ==================================================
+ */
+
+static const char *const eventOptions[] = {
+    "read", "write", NULL
+};
+typedef enum {
+    EVENT_READ, EVENT_WRITE
+} EventOption;
+
+/*
+ * Method literals. ==================================================
+ */
+
+static const char *const methodNames[] = {
+    "blocking",		/* OPT */
+    "cget",		/* OPT \/ Together or none */
+    "cgetall",		/* OPT /\ of these two     */
+    "configure",	/* OPT */
+    "finalize",		/*     */
+    "initialize",	/*     */
+    "read",		/* OPT */
+    "seek",		/* OPT */
+    "watch",		/*     */
+    "write",		/* OPT */
+    NULL
+};
+typedef enum {
+    METH_BLOCKING,
+    METH_CGET,
+    METH_CGETALL,
+    METH_CONFIGURE,
+    METH_FINAL,
+    METH_INIT,
+    METH_READ,
+    METH_SEEK,
+    METH_WATCH,
+    METH_WRITE
+} MethodName;
+
+#define FLAG(m) (1 << (m))
+#define REQUIRED_METHODS \
+	(FLAG(METH_INIT) | FLAG(METH_FINAL) | FLAG(METH_WATCH))
+#define NULLABLE_METHODS \
+	(FLAG(METH_BLOCKING) | FLAG(METH_SEEK) | \
+	FLAG(METH_CONFIGURE) | FLAG(METH_CGET) | FLAG(METH_CGETALL))
+
+#define RANDW \
+	(TCL_READABLE | TCL_WRITABLE)
+
+#define IMPLIES(a,b)	((!(a)) || (b))
+#define NEGIMPL(a,b)
+#define HAS(x,f)	(x & FLAG(f))
+
+#ifdef TCL_THREADS
+/*
+ * Thread specific types and structures.
+ *
+ * We are here essentially creating a very specific implementation of 'thread
+ * send'.
+ */
+
+/*
+ * Enumeration of all operations which can be forwarded.
+ */
+
+typedef enum {
+    ForwardedClose,
+    ForwardedInput,
+    ForwardedOutput,
+    ForwardedSeek,
+    ForwardedWatch,
+    ForwardedBlock,
+    ForwardedSetOpt,
+    ForwardedGetOpt,
+    ForwardedGetOptAll
+} ForwardedOperation;
+
+/*
+ * Event used to forward driver invocations to the thread actually managing
+ * the channel. We cannot construct the command to execute and forward that.
+ * Because then it will contain a mixture of Tcl_Obj's belonging to both the
+ * command handler thread (CT), and the thread managing the channel (MT),
+ * executed in CT. Tcl_Obj's are not allowed to cross thread boundaries. So we
+ * forward an operation code, the argument details, and reference to results.
+ * The command is assembled in the CT and belongs fully to that thread. No
+ * sharing problems.
+ */
+
+typedef struct ForwardParamBase {
+    int code;			/* O: Ok/Fail of the cmd handler */
+    char *msgStr;		/* O: Error message for handler failure */
+    int mustFree;		/* O: True if msgStr is allocated, false if
+				 * otherwise (static). */
+} ForwardParamBase;
+
+/*
+ * Operation specific parameter/result structures. (These are "subtypes" of
+ * ForwardParamBase. Where an operation does not need any special types, it
+ * has no "subtype" and just uses ForwardParamBase, as listed above.)
+ */
+
+struct ForwardParamInput {
+    ForwardParamBase base;	/* "Supertype". MUST COME FIRST. */
+    char *buf;			/* O: Where to store the read bytes */
+    int toRead;			/* I: #bytes to read,
+				 * O: #bytes actually read */
+};
+struct ForwardParamOutput {
+    ForwardParamBase base;	/* "Supertype". MUST COME FIRST. */
+    const char *buf;		/* I: Where the bytes to write come from */
+    int toWrite;		/* I: #bytes to write,
+				 * O: #bytes actually written */
+};
+struct ForwardParamSeek {
+    ForwardParamBase base;	/* "Supertype". MUST COME FIRST. */
+    int seekMode;		/* I: How to seek */
+    Tcl_WideInt offset;		/* I: Where to seek,
+				 * O: New location */
+};
+struct ForwardParamWatch {
+    ForwardParamBase base;	/* "Supertype". MUST COME FIRST. */
+    int mask;			/* I: What events to watch for */
+};
+struct ForwardParamBlock {
+    ForwardParamBase base;	/* "Supertype". MUST COME FIRST. */
+    int nonblocking;		/* I: What mode to activate */
+};
+struct ForwardParamSetOpt {
+    ForwardParamBase base;	/* "Supertype". MUST COME FIRST. */
+    const char *name;		/* Name of option to set */
+    const char *value;		/* Value to set */
+};
+struct ForwardParamGetOpt {
+    ForwardParamBase base;	/* "Supertype". MUST COME FIRST. */
+    const char *name;		/* Name of option to get, maybe NULL */
+    Tcl_DString *value;		/* Result */
+};
+
+/*
+ * Now join all these together in a single union for convenience.
+ */
+
+typedef union ForwardParam {
+    ForwardParamBase base;
+    struct ForwardParamInput input;
+    struct ForwardParamOutput output;
+    struct ForwardParamSeek seek;
+    struct ForwardParamWatch watch;
+    struct ForwardParamBlock block;
+    struct ForwardParamSetOpt setOpt;
+    struct ForwardParamGetOpt getOpt;
+} ForwardParam;
+
+/*
+ * Forward declaration.
+ */
+
+typedef struct ForwardingResult ForwardingResult;
+
+/*
+ * General event structure, with reference to operation specific data.
+ */
+
+typedef struct ForwardingEvent {
+    Tcl_Event event;		/* Basic event data, has to be first item */
+    ForwardingResult *resultPtr;
+    ForwardedOperation op;	/* Forwarded driver operation */
+    ReflectedChannel *rcPtr;	/* Channel instance */
+    ForwardParam *param;	/* Packaged arguments and return values, a
+				 * ForwardParam pointer. */
+} ForwardingEvent;
+
+/*
+ * Structure to manage the result of the forwarding. This is not the result of
+ * the operation itself, but about the success of the forward event itself.
+ * The event can be successful, even if the operation which was forwarded
+ * failed. It is also there to manage the synchronization between the involved
+ * threads.
+ */
+
+struct ForwardingResult {
+    Tcl_ThreadId src;		/* Originating thread. */
+    Tcl_ThreadId dst;		/* Thread the op was forwarded to. */
+    Tcl_Interp *dsti;		/* Interpreter in the thread the op was
+				 * forwarded to. */
+    /*
+     * Note regarding 'dsti' above: Its information is also available via the
+     * chain evPtr->rcPtr->interp, however, as can be seen, two more
+     * indirections are needed to retrieve it. And the evPtr may be gone,
+     * breaking the chain.
+     */
+    Tcl_Condition done;		/* Condition variable the forwarder blocks
+				 * on. */
+    int result;			/* TCL_OK or TCL_ERROR */
+    ForwardingEvent *evPtr;	/* Event the result belongs to. */
+    ForwardingResult *prevPtr, *nextPtr;
+				/* Links into the list of pending forwarded
+				 * results. */
+};
+
+typedef struct ThreadSpecificData {
+    /*
+     * Table of all reflected channels owned by this thread. This is the
+     * per-thread version of the per-interpreter map.
+     */
+
+    ReflectedChannelMap *rcmPtr;
+} ThreadSpecificData;
+
+static Tcl_ThreadDataKey dataKey;
+
+/*
+ * List of forwarded operations which have not completed yet, plus the mutex
+ * to protect the access to this process global list.
+ */
+
+static ForwardingResult *forwardList = NULL;
+TCL_DECLARE_MUTEX(rcForwardMutex)
+
+/*
+ * Function containing the generic code executing a forward, and wrapper
+ * macros for the actual operations we wish to forward. Uses ForwardProc as
+ * the event function executed by the thread receiving a forwarding event
+ * (which executes the appropriate function and collects the result, if any).
+ *
+ * The ExitProc ensures that things do not deadlock when the sending thread
+ * involved in the forwarding exits. It also clean things up so that we don't
+ * leak resources when threads go away.
+ */
+
+static void		ForwardOpToHandlerThread(ReflectedChannel *rcPtr,
+			    ForwardedOperation op, const void *param);
+static int		ForwardProc(Tcl_Event *evPtr, int mask);
+static void		SrcExitProc(ClientData clientData);
+
+#define FreeReceivedError(p) \
+	if ((p)->base.mustFree) {                               \
+	    ckfree((p)->base.msgStr);                           \
+	}
+#define PassReceivedErrorInterp(i,p) \
+	if ((i) != NULL) {                                      \
+	    Tcl_SetChannelErrorInterp((i),                      \
+		    Tcl_NewStringObj((p)->base.msgStr, -1));    \
+	}                                                       \
+	FreeReceivedError(p)
+#define PassReceivedError(c,p) \
+	Tcl_SetChannelError((c), Tcl_NewStringObj((p)->base.msgStr, -1)); \
+	FreeReceivedError(p)
+#define ForwardSetStaticError(p,emsg) \
+	(p)->base.code = TCL_ERROR;                             \
+	(p)->base.mustFree = 0;                                 \
+	(p)->base.msgStr = (char *) (emsg)
+#define ForwardSetDynamicError(p,emsg) \
+	(p)->base.code = TCL_ERROR;                             \
+	(p)->base.mustFree = 1;                                 \
+	(p)->base.msgStr = (char *) (emsg)
+
+static void		ForwardSetObjError(ForwardParam *p, Tcl_Obj *objPtr);
+
+static ReflectedChannelMap *	GetThreadReflectedChannelMap(void);
+static void		DeleteThreadReflectedChannelMap(ClientData clientData);
+
+#endif /* TCL_THREADS */
+
+#define SetChannelErrorStr(c,msgStr) \
+	Tcl_SetChannelError((c), Tcl_NewStringObj((msgStr), -1))
+
+static Tcl_Obj *	MarshallError(Tcl_Interp *interp);
+static void		UnmarshallErrorResult(Tcl_Interp *interp,
+			    Tcl_Obj *msgObj);
+
+/*
+ * Static functions for this file:
+ */
+
+static int		EncodeEventMask(Tcl_Interp *interp,
+			    const char *objName, Tcl_Obj *obj, int *mask);
+static Tcl_Obj *	DecodeEventMask(int mask);
+static ReflectedChannel * NewReflectedChannel(Tcl_Interp *interp,
+			    Tcl_Obj *cmdpfxObj, int mode, Tcl_Obj *handleObj);
+static Tcl_Obj *	NextHandle(void);
+static void		FreeReflectedChannel(ReflectedChannel *rcPtr);
+static int		InvokeTclMethod(ReflectedChannel *rcPtr,
+			    MethodName method, Tcl_Obj *argOneObj,
+			    Tcl_Obj *argTwoObj, Tcl_Obj **resultObjPtr);
+
+static ReflectedChannelMap *	GetReflectedChannelMap(Tcl_Interp *interp);
+static void		DeleteReflectedChannelMap(ClientData clientData,
+			    Tcl_Interp *interp);
+static int		ErrnoReturn(ReflectedChannel *rcPtr, Tcl_Obj *resObj);
+static void		MarkDead(ReflectedChannel *rcPtr);
+
+/*
+ * Global constant strings (messages). ==================
+ * These string are used directly as bypass errors, thus they have to be valid
+ * Tcl lists where the last element is the message itself. Hence the
+ * list-quoting to keep the words of the message together. See also [x].
+ */
+
+static const char *msg_read_toomuch = "{read delivered more than requested}";
+static const char *msg_write_toomuch = "{write wrote more than requested}";
+static const char *msg_write_nothing = "{write wrote nothing}";
+static const char *msg_seek_beforestart = "{Tried to seek before origin}";
+#ifdef TCL_THREADS
+static const char *msg_send_originlost = "{Channel thread lost}";
+#endif /* TCL_THREADS */
+static const char *msg_send_dstlost    = "{Owner lost}";
+static const char *msg_dstlost    = "-code 1 -level 0 -errorcode NONE -errorinfo {} -errorline 1 {Owner lost}";
+
+/*
+ * Main methods to plug into the 'chan' ensemble'. ==================
+ */
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclChanCreateObjCmd --
+ *
+ *	This function is invoked to process the "chan create" Tcl command.
+ *	See the user documentation for details on what it does.
+ *
+ * Results:
+ *	A standard Tcl result. The handle of the new channel is placed in the
+ *	interp result.
+ *
+ * Side effects:
+ *	Creates a new channel.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclChanCreateObjCmd(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const *objv)
+{
+    ReflectedChannel *rcPtr;	/* Instance data of the new channel */
+    Tcl_Obj *rcId;		/* Handle of the new channel */
+    int mode;			/* R/W mode of new channel. Has to match
+				 * abilities of handler commands */
+    Tcl_Obj *cmdObj;		/* Command prefix, list of words */
+    Tcl_Obj *cmdNameObj;	/* Command name */
+    Tcl_Channel chan;		/* Token for the new channel */
+    Tcl_Obj *modeObj;		/* mode in obj form for method call */
+    int listc;			/* Result of 'initialize', and of */
+    Tcl_Obj **listv;		/* its sublist in the 2nd element */
+    int methIndex;		/* Encoded method name */
+    int result;			/* Result code for 'initialize' */
+    Tcl_Obj *resObj;		/* Result data for 'initialize' */
+    int methods;		/* Bitmask for supported methods. */
+    Channel *chanPtr;		/* 'chan' resolved to internal struct. */
+    Tcl_Obj *err;		/* Error message */
+    ReflectedChannelMap *rcmPtr;
+				/* Map of reflected channels with handlers in
+				 * this interp. */
+    Tcl_HashEntry *hPtr;	/* Entry in the above map */
+    int isNew;			/* Placeholder. */
+
+    /*
+     * Syntax:   chan create MODE CMDPREFIX
+     *           [0]  [1]    [2]  [3]
+     *
+     * Actually: rCreate MODE CMDPREFIX
+     *           [0]     [1]  [2]
+     */
+
+#define MODE	(1)
+#define CMD	(2)
+
+    /*
+     * Number of arguments...
+     */
+
+    if (objc != 3) {
+	Tcl_WrongNumArgs(interp, 1, objv, "mode cmdprefix");
+	return TCL_ERROR;
+    }
+
+    /*
+     * First argument is a list of modes. Allowed entries are "read", "write".
+     * Expect at least one list element. Abbreviations are ok.
+     */
+
+    modeObj = objv[MODE];
+    if (EncodeEventMask(interp, "mode", objv[MODE], &mode) != TCL_OK) {
+	return TCL_ERROR;
+    }
+
+    /*
+     * Second argument is command prefix, i.e. list of words, first word is
+     * name of handler command, other words are fixed arguments. Run the
+     * 'initialize' method to get the list of supported methods. Validate
+     * this.
+     */
+
+    cmdObj = objv[CMD];
+
+    /*
+     * Basic check that the command prefix truly is a list.
+     */
+
+    if (Tcl_ListObjIndex(interp, cmdObj, 0, &cmdNameObj) != TCL_OK) {
+	return TCL_ERROR;
+    }
+
+    /*
+     * Now create the channel.
+     */
+
+    rcId = NextHandle();
+    rcPtr = NewReflectedChannel(interp, cmdObj, mode, rcId);
+
+    /*
+     * Invoke 'initialize' and validate that the handler is present and ok.
+     * Squash the channel if not.
+     *
+     * Note: The conversion of 'mode' back into a Tcl_Obj ensures that
+     * 'initialize' is invoked with canonical mode names, and no
+     * abbreviations. Using modeObj directly could feed abbreviations into the
+     * handler, and the handler is not specified to handle such.
+     */
+
+    modeObj = DecodeEventMask(mode);
+    /* assert modeObj.refCount == 1 */
+    result = InvokeTclMethod(rcPtr, METH_INIT, modeObj, NULL, &resObj);
+    Tcl_DecrRefCount(modeObj);
+
+    if (result != TCL_OK) {
+	UnmarshallErrorResult(interp, resObj);
+	Tcl_DecrRefCount(resObj);	/* Remove reference held from invoke */
+	goto error;
+    }
+
+    /*
+     * Verify the result.
+     * - List, of method names. Convert to mask.
+     *   Check for non-optionals through the mask.
+     *   Compare open mode against optional r/w.
+     */
+
+    if (Tcl_ListObjGetElements(NULL, resObj, &listc, &listv) != TCL_OK) {
+        Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+                "chan handler \"%s initialize\" returned non-list: %s",
+                Tcl_GetString(cmdObj), Tcl_GetString(resObj)));
+	Tcl_DecrRefCount(resObj);
+	goto error;
+    }
+
+    methods = 0;
+    while (listc > 0) {
+	if (Tcl_GetIndexFromObj(interp, listv[listc-1], methodNames,
+		"method", TCL_EXACT, &methIndex) != TCL_OK) {
+	    TclNewLiteralStringObj(err, "chan handler \"");
+	    Tcl_AppendObjToObj(err, cmdObj);
+	    Tcl_AppendToObj(err, " initialize\" returned ", -1);
+	    Tcl_AppendObjToObj(err, Tcl_GetObjResult(interp));
+	    Tcl_SetObjResult(interp, err);
+	    Tcl_DecrRefCount(resObj);
+	    goto error;
+	}
+
+	methods |= FLAG(methIndex);
+	listc--;
+    }
+    Tcl_DecrRefCount(resObj);
+
+    if ((REQUIRED_METHODS & methods) != REQUIRED_METHODS) {
+        Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+                "chan handler \"%s\" does not support all required methods",
+                Tcl_GetString(cmdObj)));
+	goto error;
+    }
+
+    if ((mode & TCL_READABLE) && !HAS(methods, METH_READ)) {
+        Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+                "chan handler \"%s\" lacks a \"read\" method",
+                Tcl_GetString(cmdObj)));
+	goto error;
+    }
+
+    if ((mode & TCL_WRITABLE) && !HAS(methods, METH_WRITE)) {
+        Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+                "chan handler \"%s\" lacks a \"write\" method",
+                Tcl_GetString(cmdObj)));
+	goto error;
+    }
+
+    if (!IMPLIES(HAS(methods, METH_CGET), HAS(methods, METH_CGETALL))) {
+        Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+                "chan handler \"%s\" supports \"cget\" but not \"cgetall\"",
+                Tcl_GetString(cmdObj)));
+	goto error;
+    }
+
+    if (!IMPLIES(HAS(methods, METH_CGETALL), HAS(methods, METH_CGET))) {
+        Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+                "chan handler \"%s\" supports \"cgetall\" but not \"cget\"",
+                Tcl_GetString(cmdObj)));
+	goto error;
+    }
+
+    Tcl_ResetResult(interp);
+
+    /*
+     * Everything is fine now.
+     */
+
+    chan = Tcl_CreateChannel(&tclRChannelType, TclGetString(rcId), rcPtr,
+	    mode);
+    rcPtr->chan = chan;
+    TclChannelPreserve(chan);
+    chanPtr = (Channel *) chan;
+
+    if ((methods & NULLABLE_METHODS) != NULLABLE_METHODS) {
+	/*
+	 * Some of the nullable methods are not supported. We clone the
+	 * channel type, null the associated C functions, and use the result
+	 * as the actual channel type.
+	 */
+
+	Tcl_ChannelType *clonePtr = ckalloc(sizeof(Tcl_ChannelType));
+
+	memcpy(clonePtr, &tclRChannelType, sizeof(Tcl_ChannelType));
+
+	if (!(methods & FLAG(METH_CONFIGURE))) {
+	    clonePtr->setOptionProc = NULL;
+	}
+
+	if (!(methods & FLAG(METH_CGET)) && !(methods & FLAG(METH_CGETALL))) {
+	    clonePtr->getOptionProc = NULL;
+	}
+	if (!(methods & FLAG(METH_BLOCKING))) {
+	    clonePtr->blockModeProc = NULL;
+	}
+	if (!(methods & FLAG(METH_SEEK))) {
+	    clonePtr->seekProc = NULL;
+	    clonePtr->wideSeekProc = NULL;
+	}
+
+	chanPtr->typePtr = clonePtr;
+    }
+
+    /*
+     * Register the channel in the I/O system, and in our our map for 'chan
+     * postevent'.
+     */
+
+    Tcl_RegisterChannel(interp, chan);
+
+    rcmPtr = GetReflectedChannelMap(interp);
+    hPtr = Tcl_CreateHashEntry(&rcmPtr->map, chanPtr->state->channelName,
+	    &isNew);
+    if (!isNew && chanPtr != Tcl_GetHashValue(hPtr)) {
+	Tcl_Panic("TclChanCreateObjCmd: duplicate channel names");
+    }
+    Tcl_SetHashValue(hPtr, chan);
+#ifdef TCL_THREADS
+    rcmPtr = GetThreadReflectedChannelMap();
+    hPtr = Tcl_CreateHashEntry(&rcmPtr->map, chanPtr->state->channelName,
+	    &isNew);
+    Tcl_SetHashValue(hPtr, chan);
+#endif
+
+    /*
+     * Return handle as result of command.
+     */
+
+    Tcl_SetObjResult(interp,
+            Tcl_NewStringObj(chanPtr->state->channelName, -1));
+    return TCL_OK;
+
+  error:
+    Tcl_DecrRefCount(rcPtr->name);
+    Tcl_DecrRefCount(rcPtr->methods);
+    Tcl_DecrRefCount(rcPtr->cmd);
+    ckfree((char*) rcPtr);
+    return TCL_ERROR;
+
+#undef MODE
+#undef CMD
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclChanPostEventObjCmd --
+ *
+ *	This function is invoked to process the "chan postevent" Tcl command.
+ *	See the user documentation for details on what it does.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	Posts events to a reflected channel, invokes event handlers. The
+ *	latter implies that arbitrary side effects are possible.
+ *
+ *----------------------------------------------------------------------
+ */
+
+typedef struct ReflectEvent {
+    Tcl_Event header;
+    ReflectedChannel *rcPtr;
+    int events;
+} ReflectEvent;
+
+static int
+ReflectEventRun(
+    Tcl_Event *ev,
+    int flags)
+{
+    /* OWNER thread
+     *
+     * Note: When the channel is closed any pending events of this type are
+     * deleted. See ReflectClose() for the Tcl_DeleteEvents() calls
+     * accomplishing that.
+     */
+
+    ReflectEvent *e = (ReflectEvent *) ev;
+
+    Tcl_NotifyChannel(e->rcPtr->chan, e->events);
+    return 1;
+}
+
+static int
+ReflectEventDelete(
+    Tcl_Event *ev,
+    ClientData cd)
+{
+    /* OWNER thread
+     *
+     * Invoked by DeleteThreadReflectedChannelMap() and ReflectClose(). The
+     * latter ensures that no pending events of this type are run on an
+     * invalid channel.
+     */
+
+    ReflectEvent *e = (ReflectEvent *) ev;
+
+    if ((ev->proc != ReflectEventRun) || ((cd != NULL) && (cd != e->rcPtr))) {
+        return 0;
+    }
+    return 1;
+}
+
+int
+TclChanPostEventObjCmd(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const *objv)
+{
+    /*
+     * Ensure -> HANDLER thread
+     *
+     * Syntax:   chan postevent CHANNEL EVENTSPEC
+     *           [0]  [1]       [2]     [3]
+     *
+     * Actually: rPostevent CHANNEL EVENTSPEC
+     *           [0]        [1]     [2]
+     *
+     * where EVENTSPEC = {read write ...} (Abbreviations allowed as well).
+     */
+
+#define CHAN	(1)
+#define EVENT	(2)
+
+    const char *chanId;		/* Tcl level channel handle */
+    Tcl_Channel chan;		/* Channel associated to the handle */
+    const Tcl_ChannelType *chanTypePtr;
+				/* Its associated driver structure */
+    ReflectedChannel *rcPtr;	/* Associated instance data */
+    int events;			/* Mask of events to post */
+    ReflectedChannelMap *rcmPtr;/* Map of reflected channels with handlers in
+				 * this interp. */
+    Tcl_HashEntry *hPtr;	/* Entry in the above map */
+
+    /*
+     * Number of arguments...
+     */
+
+    if (objc != 3) {
+	Tcl_WrongNumArgs(interp, 1, objv, "channel eventspec");
+	return TCL_ERROR;
+    }
+
+    /*
+     * First argument is a channel, a reflected channel, and the call of this
+     * command is done from the interp defining the channel handler cmd.
+     */
+
+    chanId = TclGetString(objv[CHAN]);
+
+    rcmPtr = GetReflectedChannelMap(interp);
+    hPtr = Tcl_FindHashEntry(&rcmPtr->map, chanId);
+
+    if (hPtr == NULL) {
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+                "can not find reflected channel named \"%s\"", chanId));
+	Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "CHANNEL", chanId, NULL);
+	return TCL_ERROR;
+    }
+
+    /*
+     * Note that the search above subsumes several of the older checks, namely:
+     *
+     * (1) Does the channel handle refer to a reflected channel ?
+     * (2) Is the post event issued from the interpreter holding the handler
+     *     of the reflected channel ?
+     *
+     * A successful search answers yes to both. Because the map holds only
+     * handles of reflected channels, and only of such whose handler is
+     * defined in this interpreter.
+     *
+     * We keep the old checks for both, for paranioa, but abort now instead of
+     * throwing errors, as failure now means that our internal datastructures
+     * have gone seriously haywire.
+     */
+
+    chan = Tcl_GetHashValue(hPtr);
+    chanTypePtr = Tcl_GetChannelType(chan);
+
+    /*
+     * We use a function referenced by the channel type as our cookie to
+     * detect calls to non-reflecting channels. The channel type itself is not
+     * suitable, as it might not be the static definition in this file, but a
+     * clone thereof. And while we have reserved the name of the type nothing
+     * in the core checks against violation, so someone else might have
+     * created a channel type using our name, clashing with ourselves.
+     */
+
+    if (chanTypePtr->watchProc != &ReflectWatch) {
+	Tcl_Panic("TclChanPostEventObjCmd: channel is not a reflected channel");
+    }
+
+    rcPtr = Tcl_GetChannelInstanceData(chan);
+
+    if (rcPtr->interp != interp) {
+	Tcl_Panic("TclChanPostEventObjCmd: postevent accepted for call from outside interpreter");
+    }
+
+    /*
+     * Second argument is a list of events. Allowed entries are "read",
+     * "write". Expect at least one list element. Abbreviations are ok.
+     */
+
+    if (EncodeEventMask(interp, "event", objv[EVENT], &events) != TCL_OK) {
+	return TCL_ERROR;
+    }
+
+    /*
+     * Check that the channel is actually interested in the provided events.
+     */
+
+    if (events & ~rcPtr->interest) {
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+                "tried to post events channel \"%s\" is not interested in",
+                chanId));
+	return TCL_ERROR;
+    }
+
+    /*
+     * We have the channel and the events to post.
+     */
+
+#ifdef TCL_THREADS
+    if (rcPtr->owner == rcPtr->thread) {
+#endif
+        Tcl_NotifyChannel(chan, events);
+#ifdef TCL_THREADS
+    } else {
+        ReflectEvent *ev = ckalloc(sizeof(ReflectEvent));
+
+        ev->header.proc = ReflectEventRun;
+        ev->events = events;
+        ev->rcPtr = rcPtr;
+
+        /*
+         * We are not preserving the structure here. When the channel is
+         * closed any pending events are deleted, see ReflectClose(), and
+         * ReflectEventDelete(). Trying to preserve and later release when the
+         * event is run may generate a situation where the channel structure
+         * is deleted but not our structure, crashing in
+         * FreeReflectedChannel().
+         *
+         * Force creation of the RCM, for proper cleanup on thread teardown.
+         * The teardown of unprocessed events is currently coupled to the
+         * thread reflected channel map
+         */
+
+        (void) GetThreadReflectedChannelMap();
+
+        /* XXX Race condition !!
+         * XXX The destination thread may not exist anymore already.
+         * XXX (Delayed postevent executed after channel got removed).
+         * XXX Can we detect this ? (check the validity of the owner threadid ?)
+         * XXX Actually, in that case the channel should be dead also !
+         */
+
+        Tcl_ThreadQueueEvent(rcPtr->owner, (Tcl_Event *) ev, TCL_QUEUE_TAIL);
+        Tcl_ThreadAlert(rcPtr->owner);
+    }
+#endif
+
+    /*
+     * Squash interp results left by the event script.
+     */
+
+    Tcl_ResetResult(interp);
+    return TCL_OK;
+
+#undef CHAN
+#undef EVENT
+}
+
+/*
+ * Channel error message marshalling utilities.
+ */
+
+static Tcl_Obj *
+MarshallError(
+    Tcl_Interp *interp)
+{
+    /*
+     * Capture the result status of the interpreter into a string. => List of
+     * options and values, followed by the error message. The result has
+     * refCount 0.
+     */
+
+    Tcl_Obj *returnOpt = Tcl_GetReturnOptions(interp, TCL_ERROR);
+
+    /*
+     * => returnOpt.refCount == 0. We can append directly.
+     */
+
+    Tcl_ListObjAppendElement(NULL, returnOpt, Tcl_GetObjResult(interp));
+    return returnOpt;
+}
+
+static void
+UnmarshallErrorResult(
+    Tcl_Interp *interp,
+    Tcl_Obj *msgObj)
+{
+    int lc;
+    Tcl_Obj **lv;
+    int explicitResult;
+    int numOptions;
+
+    /*
+     * Process the caught message.
+     *
+     * Syntax = (option value)... ?message?
+     *
+     * Bad syntax causes a panic. This is OK because the other side uses
+     * Tcl_GetReturnOptions and list construction functions to marshall the
+     * information; if we panic here, something has gone badly wrong already.
+     */
+
+    if (Tcl_ListObjGetElements(interp, msgObj, &lc, &lv) != TCL_OK) {
+	Tcl_Panic("TclChanCaughtErrorBypass: Bad syntax of caught result");
+    }
+    if (interp == NULL) {
+	return;
+    }
+
+    explicitResult = lc & 1;		/* Odd number of values? */
+    numOptions = lc - explicitResult;
+
+    if (explicitResult) {
+	Tcl_SetObjResult(interp, lv[lc-1]);
+    }
+
+    (void) Tcl_SetReturnOptions(interp, Tcl_NewListObj(numOptions, lv));
+    ((Interp *) interp)->flags &= ~ERR_ALREADY_LOGGED;
+}
+
+int
+TclChanCaughtErrorBypass(
+    Tcl_Interp *interp,
+    Tcl_Channel chan)
+{
+    Tcl_Obj *chanMsgObj = NULL;
+    Tcl_Obj *interpMsgObj = NULL;
+    Tcl_Obj *msgObj = NULL;
+
+    /*
+     * Get a bypassed error message from channel and/or interpreter, save the
+     * reference, then kill the returned objects, if there were any. If there
+     * are messages in both the channel has preference.
+     */
+
+    if ((chan == NULL) && (interp == NULL)) {
+	return 0;
+    }
+
+    if (chan != NULL) {
+	Tcl_GetChannelError(chan, &chanMsgObj);
+    }
+    if (interp != NULL) {
+	Tcl_GetChannelErrorInterp(interp, &interpMsgObj);
+    }
+
+    if (chanMsgObj != NULL) {
+	msgObj = chanMsgObj;
+    } else if (interpMsgObj != NULL) {
+	msgObj = interpMsgObj;
+    }
+    if (msgObj != NULL) {
+	Tcl_IncrRefCount(msgObj);
+    }
+
+    if (chanMsgObj != NULL) {
+	Tcl_DecrRefCount(chanMsgObj);
+    }
+    if (interpMsgObj != NULL) {
+	Tcl_DecrRefCount(interpMsgObj);
+    }
+
+    /*
+     * No message returned, nothing caught.
+     */
+
+    if (msgObj == NULL) {
+	return 0;
+    }
+
+    UnmarshallErrorResult(interp, msgObj);
+
+    Tcl_DecrRefCount(msgObj);
+    return 1;
+}
+
+/*
+ * Driver functions. ================================================
+ */
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ReflectClose --
+ *
+ *	This function is invoked when the channel is closed, to delete the
+ *	driver specific instance data.
+ *
+ * Results:
+ *	A posix error.
+ *
+ * Side effects:
+ *	Releases memory. Arbitrary, as it calls upon a script.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+ReflectClose(
+    ClientData clientData,
+    Tcl_Interp *interp)
+{
+    ReflectedChannel *rcPtr = clientData;
+    int result;			/* Result code for 'close' */
+    Tcl_Obj *resObj;		/* Result data for 'close' */
+    ReflectedChannelMap *rcmPtr;/* Map of reflected channels with handlers in
+				 * this interp */
+    Tcl_HashEntry *hPtr;	/* Entry in the above map */
+    const Tcl_ChannelType *tctPtr;
+
+    if (TclInThreadExit()) {
+	/*
+	 * This call comes from TclFinalizeIOSystem. There are no
+	 * interpreters, and therefore we cannot call upon the handler command
+	 * anymore. Threading is irrelevant as well. We simply clean up all
+	 * our C level data structures and leave the Tcl level to the other
+	 * finalization functions.
+	 */
+
+	/*
+	 * THREADED => Forward this to the origin thread
+	 *
+	 * Note: DeleteThreadReflectedChannelMap() is the thread exit handler
+	 * for the origin thread. Use this to clean up the structure? Except
+	 * if lost?
+	 */
+
+#ifdef TCL_THREADS
+	if (rcPtr->thread != Tcl_GetCurrentThread()) {
+	    ForwardParam p;
+
+	    ForwardOpToHandlerThread(rcPtr, ForwardedClose, &p);
+	    result = p.base.code;
+
+            /*
+             * Now squash the pending reflection events for this channel.
+             */
+
+            Tcl_DeleteEvents(ReflectEventDelete, rcPtr);
+
+	    if (result != TCL_OK) {
+		FreeReceivedError(&p);
+	    }
+	}
+#endif
+
+	tctPtr = ((Channel *)rcPtr->chan)->typePtr;
+	if (tctPtr && tctPtr != &tclRChannelType) {
+	    ckfree((char *)tctPtr);
+	    ((Channel *)rcPtr->chan)->typePtr = NULL;
+	}
+        Tcl_EventuallyFree(rcPtr, (Tcl_FreeProc *) FreeReflectedChannel);
+	return EOK;
+    }
+
+    /*
+     * Are we in the correct thread?
+     */
+
+#ifdef TCL_THREADS
+    if (rcPtr->thread != Tcl_GetCurrentThread()) {
+	ForwardParam p;
+
+	ForwardOpToHandlerThread(rcPtr, ForwardedClose, &p);
+	result = p.base.code;
+
+        /*
+         * Now squash the pending reflection events for this channel.
+         */
+
+        Tcl_DeleteEvents(ReflectEventDelete, rcPtr);
+
+	if (result != TCL_OK) {
+	    PassReceivedErrorInterp(interp, &p);
+	}
+    } else {
+#endif
+	result = InvokeTclMethod(rcPtr, METH_FINAL, NULL, NULL, &resObj);
+	if ((result != TCL_OK) && (interp != NULL)) {
+	    Tcl_SetChannelErrorInterp(interp, resObj);
+	}
+
+	Tcl_DecrRefCount(resObj);	/* Remove reference we held from the
+					 * invoke */
+
+	/*
+	 * Remove the channel from the map before releasing the memory, to
+	 * prevent future accesses (like by 'postevent') from finding and
+	 * dereferencing a dangling pointer.
+	 *
+	 * NOTE: The channel may not be in the map. This is ok, that happens
+	 * when the channel was created in a different interpreter and/or
+	 * thread and then was moved here.
+	 *
+	 * NOTE: The channel may have been removed from the map already via
+	 * the per-interp DeleteReflectedChannelMap exit-handler.
+	 */
+
+	if (!rcPtr->dead) {
+	    rcmPtr = GetReflectedChannelMap(rcPtr->interp);
+	    hPtr = Tcl_FindHashEntry(&rcmPtr->map,
+		    Tcl_GetChannelName(rcPtr->chan));
+	    if (hPtr) {
+		Tcl_DeleteHashEntry(hPtr);
+	    }
+	}
+#ifdef TCL_THREADS
+	rcmPtr = GetThreadReflectedChannelMap();
+	hPtr = Tcl_FindHashEntry(&rcmPtr->map,
+		Tcl_GetChannelName(rcPtr->chan));
+	if (hPtr) {
+	    Tcl_DeleteHashEntry(hPtr);
+	}
+    }
+#endif
+    tctPtr = ((Channel *)rcPtr->chan)->typePtr;
+    if (tctPtr && tctPtr != &tclRChannelType) {
+	    ckfree((char *)tctPtr);
+	    ((Channel *)rcPtr->chan)->typePtr = NULL;
+    }
+    Tcl_EventuallyFree(rcPtr, (Tcl_FreeProc *) FreeReflectedChannel);
+    return (result == TCL_OK) ? EOK : EINVAL;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ReflectInput --
+ *
+ *	This function is invoked when more data is requested from the channel.
+ *
+ * Results:
+ *	The number of bytes read.
+ *
+ * Side effects:
+ *	Allocates memory. Arbitrary, as it calls upon a script.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+ReflectInput(
+    ClientData clientData,
+    char *buf,
+    int toRead,
+    int *errorCodePtr)
+{
+    ReflectedChannel *rcPtr = clientData;
+    Tcl_Obj *toReadObj;
+    int bytec;			/* Number of returned bytes */
+    unsigned char *bytev;	/* Array of returned bytes */
+    Tcl_Obj *resObj;		/* Result data for 'read' */
+
+    /*
+     * Are we in the correct thread?
+     */
+
+#ifdef TCL_THREADS
+    if (rcPtr->thread != Tcl_GetCurrentThread()) {
+	ForwardParam p;
+
+	p.input.buf = buf;
+	p.input.toRead = toRead;
+
+	ForwardOpToHandlerThread(rcPtr, ForwardedInput, &p);
+
+	if (p.base.code != TCL_OK) {
+	    if (p.base.code < 0) {
+		/* No error message, this is an errno signal. */
+		*errorCodePtr = -p.base.code;
+	    } else {
+		PassReceivedError(rcPtr->chan, &p);
+		*errorCodePtr = EINVAL;
+	    }
+	    p.input.toRead = -1;
+	} else {
+	    *errorCodePtr = EOK;
+	}
+
+	return p.input.toRead;
+    }
+#endif
+
+    /* ASSERT: rcPtr->method & FLAG(METH_READ) */
+    /* ASSERT: rcPtr->mode & TCL_READABLE */
+
+    Tcl_Preserve(rcPtr);
+
+    toReadObj = Tcl_NewIntObj(toRead);
+    Tcl_IncrRefCount(toReadObj);
+
+    if (InvokeTclMethod(rcPtr, METH_READ, toReadObj, NULL, &resObj)!=TCL_OK) {
+	int code = ErrnoReturn(rcPtr, resObj);
+
+	if (code < 0) {
+	    *errorCodePtr = -code;
+            goto error;
+	}
+
+	Tcl_SetChannelError(rcPtr->chan, resObj);
+        goto invalid;
+    }
+
+    bytev = Tcl_GetByteArrayFromObj(resObj, &bytec);
+
+    if (toRead < bytec) {
+	SetChannelErrorStr(rcPtr->chan, msg_read_toomuch);
+        goto invalid;
+    }
+
+    *errorCodePtr = EOK;
+
+    if (bytec > 0) {
+	memcpy(buf, bytev, (size_t) bytec);
+    }
+
+ stop:
+    Tcl_DecrRefCount(toReadObj);
+    Tcl_DecrRefCount(resObj);		/* Remove reference held from invoke */
+    Tcl_Release(rcPtr);
+    return bytec;
+ invalid:
+    *errorCodePtr = EINVAL;
+ error:
+    bytec = -1;
+    goto stop;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ReflectOutput --
+ *
+ *	This function is invoked when data is writen to the channel.
+ *
+ * Results:
+ *	The number of bytes actually written.
+ *
+ * Side effects:
+ *	Allocates memory. Arbitrary, as it calls upon a script.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+ReflectOutput(
+    ClientData clientData,
+    const char *buf,
+    int toWrite,
+    int *errorCodePtr)
+{
+    ReflectedChannel *rcPtr = clientData;
+    Tcl_Obj *bufObj;
+    Tcl_Obj *resObj;		/* Result data for 'write' */
+    int written;
+
+    /*
+     * Are we in the correct thread?
+     */
+
+#ifdef TCL_THREADS
+    if (rcPtr->thread != Tcl_GetCurrentThread()) {
+	ForwardParam p;
+
+	p.output.buf = buf;
+	p.output.toWrite = toWrite;
+
+	ForwardOpToHandlerThread(rcPtr, ForwardedOutput, &p);
+
+	if (p.base.code != TCL_OK) {
+	    if (p.base.code < 0) {
+		/* No error message, this is an errno signal. */
+		*errorCodePtr = -p.base.code;
+	    } else {
+                PassReceivedError(rcPtr->chan, &p);
+                *errorCodePtr = EINVAL;
+            }
+	    p.output.toWrite = -1;
+	} else {
+	    *errorCodePtr = EOK;
+	}
+
+	return p.output.toWrite;
+    }
+#endif
+
+    /* ASSERT: rcPtr->method & FLAG(METH_WRITE) */
+    /* ASSERT: rcPtr->mode & TCL_WRITABLE */
+
+    Tcl_Preserve(rcPtr);
+    Tcl_Preserve(rcPtr->interp);
+
+    bufObj = Tcl_NewByteArrayObj((unsigned char *) buf, toWrite);
+    Tcl_IncrRefCount(bufObj);
+
+    if (InvokeTclMethod(rcPtr, METH_WRITE, bufObj, NULL, &resObj) != TCL_OK) {
+	int code = ErrnoReturn(rcPtr, resObj);
+
+	if (code < 0) {
+	    *errorCodePtr = -code;
+            goto error;
+	}
+
+	Tcl_SetChannelError(rcPtr->chan, resObj);
+        goto invalid;
+    }
+
+    if (Tcl_InterpDeleted(rcPtr->interp)) {
+	/*
+	 * The interp was destroyed during InvokeTclMethod().
+	 */
+
+	SetChannelErrorStr(rcPtr->chan, msg_send_dstlost);
+        goto invalid;
+    }
+    if (Tcl_GetIntFromObj(rcPtr->interp, resObj, &written) != TCL_OK) {
+	Tcl_SetChannelError(rcPtr->chan, MarshallError(rcPtr->interp));
+        goto invalid;
+    }
+
+    if ((written == 0) && (toWrite > 0)) {
+	/*
+	 * The handler claims to have written nothing of what it was
+	 * given. That is bad.
+	 */
+
+	SetChannelErrorStr(rcPtr->chan, msg_write_nothing);
+        goto invalid;
+    }
+    if (toWrite < written) {
+	/*
+	 * The handler claims to have written more than it was given. That is
+	 * bad. Note that the I/O core would crash if we were to return this
+	 * information, trying to write -nnn bytes in the next iteration.
+	 */
+
+	SetChannelErrorStr(rcPtr->chan, msg_write_toomuch);
+        goto invalid;
+    }
+
+    *errorCodePtr = EOK;
+ stop:
+    Tcl_DecrRefCount(bufObj);
+    Tcl_DecrRefCount(resObj);		/* Remove reference held from invoke */
+    Tcl_Release(rcPtr->interp);
+    Tcl_Release(rcPtr);
+    return written;
+ invalid:
+    *errorCodePtr = EINVAL;
+ error:
+    written = -1;
+    goto stop;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ReflectSeekWide / ReflectSeek --
+ *
+ *	This function is invoked when the user wishes to seek on the channel.
+ *
+ * Results:
+ *	The new location of the access point.
+ *
+ * Side effects:
+ *	Allocates memory. Arbitrary, as it calls upon a script.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static Tcl_WideInt
+ReflectSeekWide(
+    ClientData clientData,
+    Tcl_WideInt offset,
+    int seekMode,
+    int *errorCodePtr)
+{
+    ReflectedChannel *rcPtr = clientData;
+    Tcl_Obj *offObj, *baseObj;
+    Tcl_Obj *resObj;		/* Result for 'seek' */
+    Tcl_WideInt newLoc;
+
+    /*
+     * Are we in the correct thread?
+     */
+
+#ifdef TCL_THREADS
+    if (rcPtr->thread != Tcl_GetCurrentThread()) {
+	ForwardParam p;
+
+	p.seek.seekMode = seekMode;
+	p.seek.offset = offset;
+
+	ForwardOpToHandlerThread(rcPtr, ForwardedSeek, &p);
+
+	if (p.base.code != TCL_OK) {
+	    PassReceivedError(rcPtr->chan, &p);
+	    *errorCodePtr = EINVAL;
+	    p.seek.offset = -1;
+	} else {
+	    *errorCodePtr = EOK;
+	}
+
+	return p.seek.offset;
+    }
+#endif
+
+    /* ASSERT: rcPtr->method & FLAG(METH_SEEK) */
+
+    Tcl_Preserve(rcPtr);
+
+    offObj  = Tcl_NewWideIntObj(offset);
+    baseObj = Tcl_NewStringObj(
+            (seekMode == SEEK_SET) ? "start" :
+            (seekMode == SEEK_CUR) ? "current" : "end", -1);
+    Tcl_IncrRefCount(offObj);
+    Tcl_IncrRefCount(baseObj);
+
+    if (InvokeTclMethod(rcPtr, METH_SEEK, offObj, baseObj, &resObj)!=TCL_OK) {
+	Tcl_SetChannelError(rcPtr->chan, resObj);
+        goto invalid;
+    }
+
+    if (Tcl_GetWideIntFromObj(rcPtr->interp, resObj, &newLoc) != TCL_OK) {
+	Tcl_SetChannelError(rcPtr->chan, MarshallError(rcPtr->interp));
+        goto invalid;
+    }
+
+    if (newLoc < Tcl_LongAsWide(0)) {
+	SetChannelErrorStr(rcPtr->chan, msg_seek_beforestart);
+        goto invalid;
+    }
+
+    *errorCodePtr = EOK;
+ stop:
+    Tcl_DecrRefCount(offObj);
+    Tcl_DecrRefCount(baseObj);
+    Tcl_DecrRefCount(resObj);		/* Remove reference held from invoke */
+    Tcl_Release(rcPtr);
+    return newLoc;
+ invalid:
+    *errorCodePtr = EINVAL;
+    newLoc = -1;
+    goto stop;
+}
+
+static int
+ReflectSeek(
+    ClientData clientData,
+    long offset,
+    int seekMode,
+    int *errorCodePtr)
+{
+    /*
+     * This function can be invoked from a transformation which is based on
+     * standard seeking, i.e. non-wide. Because of this we have to implement
+     * it, a dummy is not enough. We simply delegate the call to the wide
+     * routine.
+     */
+
+    return (int) ReflectSeekWide(clientData, Tcl_LongAsWide(offset), seekMode,
+	    errorCodePtr);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ReflectWatch --
+ *
+ *	This function is invoked to tell the channel what events the I/O
+ *	system is interested in.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Allocates memory. Arbitrary, as it calls upon a script.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+ReflectWatch(
+    ClientData clientData,
+    int mask)
+{
+    ReflectedChannel *rcPtr = clientData;
+    Tcl_Obj *maskObj;
+
+    /*
+     * We restrict the interest to what the channel can support. IOW there
+     * will never be write events for a channel which is not writable.
+     * Analoguously for read events and non-readable channels.
+     */
+
+    mask &= rcPtr->mode;
+
+    if (mask == rcPtr->interest) {
+	/*
+	 * Same old, same old, why should we do something?
+	 */
+
+	return;
+    }
+
+    /*
+     * Are we in the correct thread?
+     */
+
+#ifdef TCL_THREADS
+    if (rcPtr->thread != Tcl_GetCurrentThread()) {
+	ForwardParam p;
+
+	p.watch.mask = mask;
+	ForwardOpToHandlerThread(rcPtr, ForwardedWatch, &p);
+
+	/*
+	 * Any failure from the forward is ignored. We have no place to put
+	 * this.
+	 */
+
+	return;
+    }
+#endif
+
+    Tcl_Preserve(rcPtr);
+
+    rcPtr->interest = mask;
+    maskObj = DecodeEventMask(mask);
+    /* assert maskObj.refCount == 1 */
+    (void) InvokeTclMethod(rcPtr, METH_WATCH, maskObj, NULL, NULL);
+    Tcl_DecrRefCount(maskObj);
+
+    Tcl_Release(rcPtr);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ReflectBlock --
+ *
+ *	This function is invoked to tell the channel which blocking behaviour
+ *	is required of it.
+ *
+ * Results:
+ *	A posix error number.
+ *
+ * Side effects:
+ *	Allocates memory. Arbitrary, as it calls upon a script.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+ReflectBlock(
+    ClientData clientData,
+    int nonblocking)
+{
+    ReflectedChannel *rcPtr = clientData;
+    Tcl_Obj *blockObj;
+    int errorNum;		/* EINVAL or EOK (success). */
+    Tcl_Obj *resObj;		/* Result data for 'blocking' */
+
+    /*
+     * Are we in the correct thread?
+     */
+
+#ifdef TCL_THREADS
+    if (rcPtr->thread != Tcl_GetCurrentThread()) {
+	ForwardParam p;
+
+	p.block.nonblocking = nonblocking;
+
+	ForwardOpToHandlerThread(rcPtr, ForwardedBlock, &p);
+
+	if (p.base.code != TCL_OK) {
+	    PassReceivedError(rcPtr->chan, &p);
+	    return EINVAL;
+	}
+
+	return EOK;
+    }
+#endif
+
+    blockObj = Tcl_NewBooleanObj(!nonblocking);
+    Tcl_IncrRefCount(blockObj);
+
+    Tcl_Preserve(rcPtr);
+
+    if (InvokeTclMethod(rcPtr,METH_BLOCKING,blockObj,NULL,&resObj)!=TCL_OK) {
+	Tcl_SetChannelError(rcPtr->chan, resObj);
+	errorNum = EINVAL;
+    } else {
+	errorNum = EOK;
+    }
+
+    Tcl_DecrRefCount(blockObj);
+    Tcl_DecrRefCount(resObj);		/* Remove reference held from invoke */
+
+    Tcl_Release(rcPtr);
+    return errorNum;
+}
+
+#ifdef TCL_THREADS
+/*
+ *----------------------------------------------------------------------
+ *
+ * ReflectThread --
+ *
+ *	This function is invoked to tell the channel about thread movements.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Allocates memory. Arbitrary, as it calls upon a script.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+ReflectThread(
+    ClientData clientData,
+    int action)
+{
+    ReflectedChannel *rcPtr = clientData;
+
+    switch (action) {
+    case TCL_CHANNEL_THREAD_INSERT:
+        rcPtr->owner = Tcl_GetCurrentThread();
+        break;
+    case TCL_CHANNEL_THREAD_REMOVE:
+        rcPtr->owner = NULL;
+        break;
+    default:
+        Tcl_Panic("Unknown thread action code.");
+        break;
+    }
+}
+
+#endif
+/*
+ *----------------------------------------------------------------------
+ *
+ * ReflectSetOption --
+ *
+ *	This function is invoked to configure a channel option.
+ *
+ * Results:
+ *	A standard Tcl result code.
+ *
+ * Side effects:
+ *	Arbitrary, as it calls upon a Tcl script.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+ReflectSetOption(
+    ClientData clientData,	/* Channel to query */
+    Tcl_Interp *interp,		/* Interpreter to leave error messages in */
+    const char *optionName,	/* Name of requested option */
+    const char *newValue)	/* The new value */
+{
+    ReflectedChannel *rcPtr = clientData;
+    Tcl_Obj *optionObj, *valueObj;
+    int result;			/* Result code for 'configure' */
+    Tcl_Obj *resObj;		/* Result data for 'configure' */
+
+    /*
+     * Are we in the correct thread?
+     */
+
+#ifdef TCL_THREADS
+    if (rcPtr->thread != Tcl_GetCurrentThread()) {
+	ForwardParam p;
+
+	p.setOpt.name = optionName;
+	p.setOpt.value = newValue;
+
+	ForwardOpToHandlerThread(rcPtr, ForwardedSetOpt, &p);
+
+	if (p.base.code != TCL_OK) {
+	    Tcl_Obj *err = Tcl_NewStringObj(p.base.msgStr, -1);
+
+	    UnmarshallErrorResult(interp, err);
+	    Tcl_DecrRefCount(err);
+	    FreeReceivedError(&p);
+	}
+
+	return p.base.code;
+    }
+#endif
+    Tcl_Preserve(rcPtr);
+
+    optionObj = Tcl_NewStringObj(optionName, -1);
+    valueObj = Tcl_NewStringObj(newValue, -1);
+
+    Tcl_IncrRefCount(optionObj);
+    Tcl_IncrRefCount(valueObj);
+
+    result = InvokeTclMethod(rcPtr, METH_CONFIGURE,optionObj,valueObj, &resObj);
+    if (result != TCL_OK) {
+	UnmarshallErrorResult(interp, resObj);
+    }
+
+    Tcl_DecrRefCount(optionObj);
+    Tcl_DecrRefCount(valueObj);
+    Tcl_DecrRefCount(resObj);		/* Remove reference held from invoke */
+    Tcl_Release(rcPtr);
+    return result;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ReflectGetOption --
+ *
+ *	This function is invoked to retrieve all or a channel option.
+ *
+ * Results:
+ *	A standard Tcl result code.
+ *
+ * Side effects:
+ *	Arbitrary, as it calls upon a Tcl script.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+ReflectGetOption(
+    ClientData clientData,	/* Channel to query */
+    Tcl_Interp *interp,		/* Interpreter to leave error messages in */
+    const char *optionName,	/* Name of reuqested option */
+    Tcl_DString *dsPtr)		/* String to place the result into */
+{
+    /*
+     * This code is special. It has regular passing of Tcl result, and errors.
+     * The bypass functions are not required.
+     */
+
+    ReflectedChannel *rcPtr = clientData;
+    Tcl_Obj *optionObj;
+    Tcl_Obj *resObj;		/* Result data for 'configure' */
+    int listc, result = TCL_OK;
+    Tcl_Obj **listv;
+    MethodName method;
+
+    /*
+     * Are we in the correct thread?
+     */
+
+#ifdef TCL_THREADS
+    if (rcPtr->thread != Tcl_GetCurrentThread()) {
+	int opcode;
+	ForwardParam p;
+
+	p.getOpt.name = optionName;
+	p.getOpt.value = dsPtr;
+
+	if (optionName == NULL) {
+	    opcode = ForwardedGetOptAll;
+	} else {
+	    opcode = ForwardedGetOpt;
+	}
+
+	ForwardOpToHandlerThread(rcPtr, opcode, &p);
+
+	if (p.base.code != TCL_OK) {
+	    Tcl_Obj *err = Tcl_NewStringObj(p.base.msgStr, -1);
+
+	    UnmarshallErrorResult(interp, err);
+	    Tcl_DecrRefCount(err);
+	    FreeReceivedError(&p);
+	}
+
+	return p.base.code;
+    }
+#endif
+
+    if (optionName == NULL) {
+	/*
+	 * Retrieve all options.
+	 */
+
+	method = METH_CGETALL;
+	optionObj = NULL;
+    } else {
+	/*
+	 * Retrieve the value of one option.
+	 */
+
+	method = METH_CGET;
+	optionObj = Tcl_NewStringObj(optionName, -1);
+        Tcl_IncrRefCount(optionObj);
+    }
+
+    Tcl_Preserve(rcPtr);
+
+    if (InvokeTclMethod(rcPtr, method, optionObj, NULL, &resObj)!=TCL_OK) {
+	UnmarshallErrorResult(interp, resObj);
+        goto error;
+    }
+
+    /*
+     * The result has to go into the 'dsPtr' for propagation to the caller of
+     * the driver.
+     */
+
+    if (optionObj != NULL) {
+	TclDStringAppendObj(dsPtr, resObj);
+        goto ok;
+    }
+
+    /*
+     * Extract the list and append each item as element.
+     */
+
+    /*
+     * NOTE (4): If we extract the string rep we can assume a properly quoted
+     * string. Together with a separating space this way of simply appending
+     * the whole string rep might be faster. It also doesn't check if the
+     * result is a valid list. Nor that the list has an even number elements.
+     */
+
+    if (Tcl_ListObjGetElements(interp, resObj, &listc, &listv) != TCL_OK) {
+        goto error;
+    }
+
+    if ((listc % 2) == 1) {
+	/*
+	 * Odd number of elements is wrong.
+	 */
+
+	Tcl_ResetResult(interp);
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		"Expected list with even number of "
+		"elements, got %d element%s instead", listc,
+		(listc == 1 ? "" : "s")));
+        goto error;
+    } else {
+	int len;
+	const char *str = Tcl_GetStringFromObj(resObj, &len);
+
+	if (len) {
+	    TclDStringAppendLiteral(dsPtr, " ");
+	    Tcl_DStringAppend(dsPtr, str, len);
+	}
+        goto ok;
+    }
+
+ ok:
+    result = TCL_OK;
+ stop:
+    if (optionObj) {
+        Tcl_DecrRefCount(optionObj);
+    }
+    Tcl_DecrRefCount(resObj);	/* Remove reference held from invoke */
+    Tcl_Release(rcPtr);
+    return result;
+ error:
+    result = TCL_ERROR;
+    goto stop;
+}
+
+/*
+ * Helpers. =========================================================
+ */
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * EncodeEventMask --
+ *
+ *	This function takes a list of event items and constructs the
+ *	equivalent internal bitmask. The list must contain at least one
+ *	element. Elements are "read", "write", or any unique abbreviation of
+ *	them. Note that the bitmask is not changed if problems are
+ *	encountered.
+ *
+ * Results:
+ *	A standard Tcl error code. A bitmask where TCL_READABLE and/or
+ *	TCL_WRITABLE can be set.
+ *
+ * Side effects:
+ *	May shimmer 'obj' to a list representation. May place an error message
+ *	into the interp result.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+EncodeEventMask(
+    Tcl_Interp *interp,
+    const char *objName,
+    Tcl_Obj *obj,
+    int *mask)
+{
+    int events;			/* Mask of events to post */
+    int listc;			/* #elements in eventspec list */
+    Tcl_Obj **listv;		/* Elements of eventspec list */
+    int evIndex;		/* Id of event for an element of the eventspec
+				 * list. */
+
+    if (Tcl_ListObjGetElements(interp, obj, &listc, &listv) != TCL_OK) {
+	return TCL_ERROR;
+    }
+
+    if (listc < 1) {
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+                "bad %s list: is empty", objName));
+	return TCL_ERROR;
+    }
+
+    events = 0;
+    while (listc > 0) {
+	if (Tcl_GetIndexFromObj(interp, listv[listc-1], eventOptions,
+		objName, 0, &evIndex) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	switch (evIndex) {
+	case EVENT_READ:
+	    events |= TCL_READABLE;
+	    break;
+	case EVENT_WRITE:
+	    events |= TCL_WRITABLE;
+	    break;
+	}
+	listc --;
+    }
+
+    *mask = events;
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * DecodeEventMask --
+ *
+ *	This function takes an internal bitmask of events and constructs the
+ *	equivalent list of event items.
+ *
+ * Results, Contract:
+ *	A Tcl_Obj reference. The object will have a refCount of one. The user
+ *	has to decrement it to release the object.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static Tcl_Obj *
+DecodeEventMask(
+    int mask)
+{
+    register const char *eventStr;
+    Tcl_Obj *evObj;
+
+    switch (mask & RANDW) {
+    case RANDW:
+	eventStr = "read write";
+	break;
+    case TCL_READABLE:
+	eventStr = "read";
+	break;
+    case TCL_WRITABLE:
+	eventStr = "write";
+	break;
+    default:
+	eventStr = "";
+	break;
+    }
+
+    evObj = Tcl_NewStringObj(eventStr, -1);
+    Tcl_IncrRefCount(evObj);
+    /* assert evObj.refCount == 1 */
+    return evObj;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * NewReflectedChannel --
+ *
+ *	This function is invoked to allocate and initialize the instance data
+ *	of a new reflected channel.
+ *
+ * Results:
+ *	A heap-allocated channel instance.
+ *
+ * Side effects:
+ *	Allocates memory.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static ReflectedChannel *
+NewReflectedChannel(
+    Tcl_Interp *interp,
+    Tcl_Obj *cmdpfxObj,
+    int mode,
+    Tcl_Obj *handleObj)
+{
+    ReflectedChannel *rcPtr;
+    MethodName mn = METH_BLOCKING;
+
+    rcPtr = ckalloc(sizeof(ReflectedChannel));
+
+    /* rcPtr->chan: Assigned by caller. Dummy data here. */
+
+    rcPtr->chan = NULL;
+    rcPtr->interp = interp;
+    rcPtr->dead = 0;
+#ifdef TCL_THREADS
+    rcPtr->thread = Tcl_GetCurrentThread();
+#endif
+    rcPtr->mode = mode;
+    rcPtr->interest = 0;		/* Initially no interest registered */
+
+    /* ASSERT: cmdpfxObj is a Tcl List */
+    rcPtr->cmd = TclListObjCopy(NULL, cmdpfxObj);
+    Tcl_IncrRefCount(rcPtr->cmd);
+    rcPtr->methods = Tcl_NewListObj(METH_WRITE + 1, NULL);
+    while (mn <= METH_WRITE) {
+	Tcl_ListObjAppendElement(NULL, rcPtr->methods,
+		Tcl_NewStringObj(methodNames[mn++], -1));
+    }
+    Tcl_IncrRefCount(rcPtr->methods);
+    rcPtr->name = handleObj;
+    Tcl_IncrRefCount(rcPtr->name);
+    return rcPtr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * NextHandle --
+ *
+ *	This function is invoked to generate a channel handle for a new
+ *	reflected channel.
+ *
+ * Results:
+ *	A Tcl_Obj containing the string of the new channel handle. The
+ *	refcount of the returned object is -- zero --.
+ *
+ * Side effects:
+ *	May allocate memory. Mutex protected critical section locks out other
+ *	threads for a short time.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static Tcl_Obj *
+NextHandle(void)
+{
+    /*
+     * Count number of generated reflected channels. Used for id generation.
+     * Ids are never reclaimed and there is no dealing with wrap around. On
+     * the other hand, "unsigned long" should be big enough except for
+     * absolute longrunners (generate a 100 ids per second => overflow will
+     * occur in 1 1/3 years).
+     */
+
+    TCL_DECLARE_MUTEX(rcCounterMutex)
+    static unsigned long rcCounter = 0;
+    Tcl_Obj *resObj;
+
+    Tcl_MutexLock(&rcCounterMutex);
+    resObj = Tcl_ObjPrintf("rc%lu", rcCounter);
+    rcCounter++;
+    Tcl_MutexUnlock(&rcCounterMutex);
+
+    return resObj;
+}
+
+static void
+FreeReflectedChannel(
+    ReflectedChannel *rcPtr)
+{
+    Channel *chanPtr = (Channel *) rcPtr->chan;
+
+    TclChannelRelease((Tcl_Channel)chanPtr);
+    if (rcPtr->name) {
+	Tcl_DecrRefCount(rcPtr->name);
+    }
+    if (rcPtr->methods) {
+	Tcl_DecrRefCount(rcPtr->methods);
+    }
+    if (rcPtr->cmd) {
+	Tcl_DecrRefCount(rcPtr->cmd);
+    }
+    ckfree(rcPtr);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * InvokeTclMethod --
+ *
+ *	This function is used to invoke the Tcl level of a reflected channel.
+ *	It handles all the command assembly, invokation, and generic state and
+ *	result mgmt. It does *not* handle thread redirection; that is the
+ *	responsibility of clients of this function.
+ *
+ * Results:
+ *	Result code and data as returned by the method.
+ *
+ * Side effects:
+ *	Arbitrary, as it calls upon a Tcl script.
+ *
+ * Contract:
+ *	argOneObj.refCount >= 1 on entry and exit, if argOneObj != NULL
+ *	argTwoObj.refCount >= 1 on entry and exit, if argTwoObj != NULL
+ *	resObj.refCount in {0, 1, ...}
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+InvokeTclMethod(
+    ReflectedChannel *rcPtr,
+    MethodName method,
+    Tcl_Obj *argOneObj,		/* NULL'able */
+    Tcl_Obj *argTwoObj,		/* NULL'able */
+    Tcl_Obj **resultObjPtr)	/* NULL'able */
+{
+    Tcl_Obj *methObj = NULL;	/* Method name in object form */
+    Tcl_InterpState sr;		/* State of handler interp */
+    int result;			/* Result code of method invokation */
+    Tcl_Obj *resObj = NULL;	/* Result of method invokation. */
+    Tcl_Obj *cmd;
+
+    if (rcPtr->dead) {
+	/*
+	 * The channel is marked as dead. Bail out immediately, with an
+	 * appropriate error.
+	 */
+
+	if (resultObjPtr != NULL) {
+	    resObj = Tcl_NewStringObj(msg_dstlost,-1);
+	    *resultObjPtr = resObj;
+	    Tcl_IncrRefCount(resObj);
+	}
+
+        /*
+         * Not touching argOneObj, argTwoObj, they have not been used.
+         * See the contract as well.
+         */
+
+	return TCL_ERROR;
+    }
+
+    /*
+     * Insert method into the callback command, after the command prefix,
+     * before the channel id.
+     */
+
+    cmd = TclListObjCopy(NULL, rcPtr->cmd);
+
+    Tcl_ListObjIndex(NULL, rcPtr->methods, method, &methObj);
+    Tcl_ListObjAppendElement(NULL, cmd, methObj);
+    Tcl_ListObjAppendElement(NULL, cmd, rcPtr->name);
+
+    /*
+     * Append the additional argument containing method specific details
+     * behind the channel id. If specified.
+     *
+     * Because of the contract there is no need to increment the refcounts.
+     * The objects will survive the Tcl_EvalObjv without change.
+     */
+
+    if (argOneObj) {
+	Tcl_ListObjAppendElement(NULL, cmd, argOneObj);
+	if (argTwoObj) {
+	    Tcl_ListObjAppendElement(NULL, cmd, argTwoObj);
+	}
+    }
+
+    /*
+     * And run the handler... This is done in auch a manner which leaves any
+     * existing state intact.
+     */
+
+    Tcl_IncrRefCount(cmd);
+    sr = Tcl_SaveInterpState(rcPtr->interp, 0 /* Dummy */);
+    Tcl_Preserve(rcPtr->interp);
+    result = Tcl_EvalObjEx(rcPtr->interp, cmd, TCL_EVAL_GLOBAL);
+
+    /*
+     * We do not try to extract the result information if the caller has no
+     * interest in it. I.e. there is no need to put effort into creating
+     * something which is discarded immediately after.
+     */
+
+    if (resultObjPtr) {
+	if (result == TCL_OK) {
+	    /*
+	     * Ok result taken as is, also if the caller requests that there
+	     * is no capture.
+	     */
+
+	    resObj = Tcl_GetObjResult(rcPtr->interp);
+	} else {
+	    /*
+	     * Non-ok result is always treated as an error. We have to capture
+	     * the full state of the result, including additional options.
+	     *
+	     * This is complex and ugly, and would be completely unnecessary
+	     * if we only added support for a TCL_FORBID_EXCEPTIONS flag.
+	     */
+
+	    if (result != TCL_ERROR) {
+		int cmdLen;
+		const char *cmdString = Tcl_GetStringFromObj(cmd, &cmdLen);
+
+		Tcl_IncrRefCount(cmd);
+		Tcl_ResetResult(rcPtr->interp);
+		Tcl_SetObjResult(rcPtr->interp, Tcl_ObjPrintf(
+			"chan handler returned bad code: %d", result));
+		Tcl_LogCommandInfo(rcPtr->interp, cmdString, cmdString,
+			cmdLen);
+		Tcl_DecrRefCount(cmd);
+		result = TCL_ERROR;
+	    }
+	    Tcl_AppendObjToErrorInfo(rcPtr->interp, Tcl_ObjPrintf(
+		    "\n    (chan handler subcommand \"%s\")",
+		    methodNames[method]));
+	    resObj = MarshallError(rcPtr->interp);
+	}
+	Tcl_IncrRefCount(resObj);
+    }
+    Tcl_DecrRefCount(cmd);
+    Tcl_RestoreInterpState(rcPtr->interp, sr);
+    Tcl_Release(rcPtr->interp);
+
+    /*
+     * The resObj has a ref count of 1 at this location. This means that the
+     * caller of InvokeTclMethod has to dispose of it (but only if it was
+     * returned to it).
+     */
+
+    if (resultObjPtr != NULL) {
+	*resultObjPtr = resObj;
+    }
+
+    /*
+     * There no need to handle the case where nothing is returned, because for
+     * that case resObj was not set anyway.
+     */
+
+    return result;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ErrnoReturn --
+ *
+ *	Checks a method error result if it returned an 'errno'.
+ *
+ * Results:
+ *	The negative errno found in the error result, or 0.
+ *
+ * Side effects:
+ *	None.
+ *
+ * Users:
+ *	ReflectInput/Output(), to enable the signaling of EAGAIN
+ *	on 0-sized short reads/writes.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+ErrnoReturn(
+    ReflectedChannel *rcPtr,
+    Tcl_Obj *resObj)
+{
+    int code;
+    Tcl_InterpState sr;		/* State of handler interp */
+
+    if (rcPtr->dead) {
+	return 0;
+    }
+
+    sr = Tcl_SaveInterpState(rcPtr->interp, 0 /* Dummy */);
+    UnmarshallErrorResult(rcPtr->interp, resObj);
+
+    resObj = Tcl_GetObjResult(rcPtr->interp);
+
+    if (((Tcl_GetIntFromObj(rcPtr->interp, resObj, &code) != TCL_OK)
+	    || (code >= 0))) {
+	if (strcmp("EAGAIN", Tcl_GetString(resObj)) == 0) {
+	    code = -EAGAIN;
+	} else {
+	    code = 0;
+	}
+    }
+
+    Tcl_RestoreInterpState(rcPtr->interp, sr);
+    return code;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * GetReflectedChannelMap --
+ *
+ *	Gets and potentially initializes the reflected channel map for an
+ *	interpreter.
+ *
+ * Results:
+ *	A pointer to the map created, for use by the caller.
+ *
+ * Side effects:
+ *	Initializes the reflected channel map for an interpreter.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static ReflectedChannelMap *
+GetReflectedChannelMap(
+    Tcl_Interp *interp)
+{
+    ReflectedChannelMap *rcmPtr = Tcl_GetAssocData(interp, RCMKEY, NULL);
+
+    if (rcmPtr == NULL) {
+	rcmPtr = ckalloc(sizeof(ReflectedChannelMap));
+	Tcl_InitHashTable(&rcmPtr->map, TCL_STRING_KEYS);
+	Tcl_SetAssocData(interp, RCMKEY,
+		(Tcl_InterpDeleteProc *) DeleteReflectedChannelMap, rcmPtr);
+    }
+    return rcmPtr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * DeleteReflectedChannelMap --
+ *
+ *	Deletes the channel table for an interpreter, closing any open
+ *	channels whose refcount reaches zero. This procedure is invoked when
+ *	an interpreter is deleted, via the AssocData cleanup mechanism.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Deletes the hash table of channels. May close channels. May flush
+ *	output on closed channels. Removes any channeEvent handlers that were
+ *	registered in this interpreter.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+MarkDead(
+    ReflectedChannel *rcPtr)
+{
+    if (rcPtr->dead) {
+	return;
+    }
+    if (rcPtr->name) {
+	Tcl_DecrRefCount(rcPtr->name);
+	rcPtr->name = NULL;
+    }
+    if (rcPtr->methods) {
+	Tcl_DecrRefCount(rcPtr->methods);
+	rcPtr->methods = NULL;
+    }
+    if (rcPtr->cmd) {
+	Tcl_DecrRefCount(rcPtr->cmd);
+	rcPtr->cmd = NULL;
+    }
+    rcPtr->dead = 1;
+}
+
+static void
+DeleteReflectedChannelMap(
+    ClientData clientData,	/* The per-interpreter data structure. */
+    Tcl_Interp *interp)		/* The interpreter being deleted. */
+{
+    ReflectedChannelMap *rcmPtr = clientData;
+				/* The map */
+    Tcl_HashSearch hSearch;	 /* Search variable. */
+    Tcl_HashEntry *hPtr;	 /* Search variable. */
+    ReflectedChannel *rcPtr;
+    Tcl_Channel chan;
+#ifdef TCL_THREADS
+    ForwardingResult *resultPtr;
+    ForwardingEvent *evPtr;
+    ForwardParam *paramPtr;
+#endif
+
+    /*
+     * Delete all entries. The channels may have been closed already, or will
+     * be closed later, by the standard IO finalization of an interpreter
+     * under destruction. Except for the channels which were moved to a
+     * different interpreter and/or thread. They do not exist from the IO
+     * systems point of view and will not get closed. Therefore mark all as
+     * dead so that any future access will cause a proper error. For channels
+     * in a different thread we actually do the same as
+     * DeleteThreadReflectedChannelMap(), just restricted to the channels of
+     * this interp.
+     */
+
+    for (hPtr = Tcl_FirstHashEntry(&rcmPtr->map, &hSearch);
+	    hPtr != NULL;
+	    hPtr = Tcl_FirstHashEntry(&rcmPtr->map, &hSearch)) {
+	chan = Tcl_GetHashValue(hPtr);
+	rcPtr = Tcl_GetChannelInstanceData(chan);
+
+	MarkDead(rcPtr);
+	Tcl_DeleteHashEntry(hPtr);
+    }
+    Tcl_DeleteHashTable(&rcmPtr->map);
+    ckfree(&rcmPtr->map);
+
+#ifdef TCL_THREADS
+    /*
+     * The origin interpreter for one or more reflected channels is gone.
+     */
+
+    /*
+     * Go through the list of pending results and cancel all whose events were
+     * destined for this interpreter. While this is in progress we block any
+     * other access to the list of pending results.
+     */
+
+    Tcl_MutexLock(&rcForwardMutex);
+
+    for (resultPtr = forwardList;
+	    resultPtr != NULL;
+	    resultPtr = resultPtr->nextPtr) {
+	if (resultPtr->dsti != interp) {
+	    /*
+	     * Ignore results/events for other interpreters.
+	     */
+
+	    continue;
+	}
+
+	/*
+	 * The receiver for the event exited, before processing the event. We
+	 * detach the result now, wake the originator up and signal failure.
+         *
+         * Attention: Results may have been detached already, by either the
+         * receiver, or this thread, as part of other parts in the thread
+         * teardown. Such results are ignored. See ticket [b47b176adf] for the
+         * identical race condition in Tcl 8.6 IORTrans.
+	 */
+
+	evPtr = resultPtr->evPtr;
+
+	/* Basic crash safety until this routine can get revised [3411310] */
+	if (evPtr == NULL) {
+	    continue;
+	}
+	paramPtr = evPtr->param;
+	if (!evPtr) {
+	    continue;
+	}
+
+	evPtr->resultPtr = NULL;
+	resultPtr->evPtr = NULL;
+	resultPtr->result = TCL_ERROR;
+
+	ForwardSetStaticError(paramPtr, msg_send_dstlost);
+
+	Tcl_ConditionNotify(&resultPtr->done);
+    }
+    Tcl_MutexUnlock(&rcForwardMutex);
+
+    /*
+     * Get the map of all channels handled by the current thread. This is a
+     * ReflectedChannelMap, but on a per-thread basis, not per-interp. Go
+     * through the channels and remove all which were handled by this
+     * interpreter. They have already been marked as dead.
+     */
+
+    rcmPtr = GetThreadReflectedChannelMap();
+    for (hPtr = Tcl_FirstHashEntry(&rcmPtr->map, &hSearch);
+	    hPtr != NULL;
+	    hPtr = Tcl_NextHashEntry(&hSearch)) {
+	chan = Tcl_GetHashValue(hPtr);
+	rcPtr = Tcl_GetChannelInstanceData(chan);
+
+	if (rcPtr->interp != interp) {
+	    /*
+	     * Ignore entries for other interpreters.
+	     */
+
+	    continue;
+	}
+
+	MarkDead(rcPtr);
+	Tcl_DeleteHashEntry(hPtr);
+    }
+#endif
+}
+
+#ifdef TCL_THREADS
+/*
+ *----------------------------------------------------------------------
+ *
+ * GetThreadReflectedChannelMap --
+ *
+ *	Gets and potentially initializes the reflected channel map for a
+ *	thread.
+ *
+ * Results:
+ *	A pointer to the map created, for use by the caller.
+ *
+ * Side effects:
+ *	Initializes the reflected channel map for a thread.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static ReflectedChannelMap *
+GetThreadReflectedChannelMap(void)
+{
+    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+
+    if (!tsdPtr->rcmPtr) {
+	tsdPtr->rcmPtr = ckalloc(sizeof(ReflectedChannelMap));
+	Tcl_InitHashTable(&tsdPtr->rcmPtr->map, TCL_STRING_KEYS);
+	Tcl_CreateThreadExitHandler(DeleteThreadReflectedChannelMap, NULL);
+    }
+
+    return tsdPtr->rcmPtr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * DeleteThreadReflectedChannelMap --
+ *
+ *	Deletes the channel table for a thread. This procedure is invoked when
+ *	a thread is deleted. The channels have already been marked as dead, in
+ *	DeleteReflectedChannelMap().
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Deletes the hash table of channels.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+DeleteThreadReflectedChannelMap(
+    ClientData clientData)	/* The per-thread data structure. */
+{
+    Tcl_HashSearch hSearch;	 /* Search variable. */
+    Tcl_HashEntry *hPtr;	 /* Search variable. */
+    Tcl_ThreadId self = Tcl_GetCurrentThread();
+    ReflectedChannelMap *rcmPtr; /* The map */
+    ForwardingResult *resultPtr;
+
+    /*
+     * The origin thread for one or more reflected channels is gone.
+     * NOTE: If this function is called due to a thread getting killed the
+     *       per-interp DeleteReflectedChannelMap is apparently not called.
+     */
+
+    /*
+     * Go through the list of pending results and cancel all whose events were
+     * destined for this thread. While this is in progress we block any
+     * other access to the list of pending results.
+     */
+
+    Tcl_MutexLock(&rcForwardMutex);
+
+    for (resultPtr = forwardList;
+	    resultPtr != NULL;
+	    resultPtr = resultPtr->nextPtr) {
+	ForwardingEvent *evPtr;
+	ForwardParam *paramPtr;
+
+	if (resultPtr->dst != self) {
+	    /*
+	     * Ignore results/events for other threads.
+	     */
+
+	    continue;
+	}
+
+	/*
+	 * The receiver for the event exited, before processing the event. We
+	 * detach the result now, wake the originator up and signal failure.
+         *
+         * Attention: Results may have been detached already, by either the
+         * receiver, or this thread, as part of other parts in the thread
+         * teardown. Such results are ignored. See ticket [b47b176adf] for the
+         * identical race condition in Tcl 8.6 IORTrans.
+	 */
+
+	evPtr = resultPtr->evPtr;
+
+	/* Basic crash safety until this routine can get revised [3411310] */
+	if (evPtr == NULL ) {
+	    continue;
+	}
+	paramPtr = evPtr->param;
+	if (!evPtr) {
+	    continue;
+	}
+
+	evPtr->resultPtr = NULL;
+	resultPtr->evPtr = NULL;
+	resultPtr->result = TCL_ERROR;
+
+	ForwardSetStaticError(paramPtr, msg_send_dstlost);
+
+	Tcl_ConditionNotify(&resultPtr->done);
+    }
+    Tcl_MutexUnlock(&rcForwardMutex);
+
+    /*
+     * Run over the event queue of this thread and remove all ReflectEvent's
+     * still pending. These are inbound events for reflected channels this
+     * thread owns but doesn't handle. The inverse of the channel map
+     * actually.
+     */
+
+    Tcl_DeleteEvents(ReflectEventDelete, NULL);
+
+    /*
+     * Get the map of all channels handled by the current thread. This is a
+     * ReflectedChannelMap, but on a per-thread basis, not per-interp. Go
+     * through the channels, remove all, mark them as dead.
+     */
+
+    rcmPtr = GetThreadReflectedChannelMap();
+    for (hPtr = Tcl_FirstHashEntry(&rcmPtr->map, &hSearch);
+	    hPtr != NULL;
+	    hPtr = Tcl_FirstHashEntry(&rcmPtr->map, &hSearch)) {
+	Tcl_Channel chan = Tcl_GetHashValue(hPtr);
+	ReflectedChannel *rcPtr = Tcl_GetChannelInstanceData(chan);
+
+	MarkDead(rcPtr);
+	Tcl_DeleteHashEntry(hPtr);
+    }
+    ckfree(rcmPtr);
+}
+
+static void
+ForwardOpToHandlerThread(
+    ReflectedChannel *rcPtr,	/* Channel instance */
+    ForwardedOperation op,	/* Forwarded driver operation */
+    const void *param)		/* Arguments */
+{
+    /*
+     * Core of the communication from OWNER to HANDLER thread.
+     * The receiver is ForwardProc() below.
+     */
+
+    Tcl_ThreadId dst = rcPtr->thread;
+    ForwardingEvent *evPtr;
+    ForwardingResult *resultPtr;
+
+    /*
+     * We gather the lock early. This allows us to check the liveness of the
+     * channel without interference from DeleteThreadReflectedChannelMap().
+     */
+
+    Tcl_MutexLock(&rcForwardMutex);
+
+    if (rcPtr->dead) {
+	/*
+	 * The channel is marked as dead. Bail out immediately, with an
+	 * appropriate error. Do not forget to unlock the mutex on this path.
+	 */
+
+	ForwardSetStaticError((ForwardParam *) param, msg_send_dstlost);
+	Tcl_MutexUnlock(&rcForwardMutex);
+	return;
+    }
+
+    /*
+     * Create and initialize the event and data structures.
+     */
+
+    evPtr = ckalloc(sizeof(ForwardingEvent));
+    resultPtr = ckalloc(sizeof(ForwardingResult));
+
+    evPtr->event.proc = ForwardProc;
+    evPtr->resultPtr = resultPtr;
+    evPtr->op = op;
+    evPtr->rcPtr = rcPtr;
+    evPtr->param = (ForwardParam *) param;
+
+    resultPtr->src = Tcl_GetCurrentThread();
+    resultPtr->dst = dst;
+    resultPtr->dsti = rcPtr->interp;
+    resultPtr->done = NULL;
+    resultPtr->result = -1;
+    resultPtr->evPtr = evPtr;
+
+    /*
+     * Now execute the forward.
+     */
+
+    TclSpliceIn(resultPtr, forwardList);
+    /* Do not unlock here. That is done by the ConditionWait */
+
+    /*
+     * Ensure cleanup of the event if the origin thread exits while this event
+     * is pending or in progress. Exit of the destination thread is handled by
+     * DeleteThreadReflectedChannelMap(), this is set up by
+     * GetThreadReflectedChannelMap(). This is what we use the 'forwardList'
+     * (see above) for.
+     */
+
+    Tcl_CreateThreadExitHandler(SrcExitProc, evPtr);
+
+    /*
+     * Queue the event and poke the other thread's notifier.
+     */
+
+    Tcl_ThreadQueueEvent(dst, (Tcl_Event *) evPtr, TCL_QUEUE_TAIL);
+    Tcl_ThreadAlert(dst);
+
+    /*
+     * (*) Block until the handler thread has either processed the transfer or
+     * rejected it.
+     */
+
+    while (resultPtr->result < 0) {
+	/*
+	 * NOTE (1): Is it possible that the current thread goes away while
+	 * waiting here? IOW Is it possible that "SrcExitProc" is called while
+	 * we are here? See complementary note (2) in "SrcExitProc"
+	 *
+	 * The ConditionWait unlocks the mutex during the wait and relocks it
+	 * immediately after.
+	 */
+
+	Tcl_ConditionWait(&resultPtr->done, &rcForwardMutex, NULL);
+    }
+
+    /*
+     * Unlink result from the forwarder list. No need to lock. Either still
+     * locked, or locked by the ConditionWait
+     */
+
+    TclSpliceOut(resultPtr, forwardList);
+
+    resultPtr->nextPtr = NULL;
+    resultPtr->prevPtr = NULL;
+
+    Tcl_MutexUnlock(&rcForwardMutex);
+    Tcl_ConditionFinalize(&resultPtr->done);
+
+    /*
+     * Kill the cleanup handler now, and the result structure as well, before
+     * returning the success code.
+     *
+     * Note: The event structure has already been deleted.
+     */
+
+    Tcl_DeleteThreadExitHandler(SrcExitProc, evPtr);
+
+    ckfree(resultPtr);
+}
+
+static int
+ForwardProc(
+    Tcl_Event *evGPtr,
+    int mask)
+{
+    /*
+     * HANDLER thread.
+
+     * The receiver part for the operations coming from the OWNER thread.
+     * See ForwardOpToHandlerThread() for the transmitter.
+     *
+     * Notes regarding access to the referenced data.
+     *
+     * In principle the data belongs to the originating thread (see
+     * evPtr->src), however this thread is currently blocked at (*), i.e.
+     * quiescent. Because of this we can treat the data as belonging to us,
+     * without fear of race conditions. I.e. we can read and write as we like.
+     *
+     * The only thing we cannot be sure of is the resultPtr. This can be be
+     * NULLed if the originating thread went away while the event is handled
+     * here now.
+     */
+
+    ForwardingEvent *evPtr = (ForwardingEvent *) evGPtr;
+    ForwardingResult *resultPtr = evPtr->resultPtr;
+    ReflectedChannel *rcPtr = evPtr->rcPtr;
+    Tcl_Interp *interp = rcPtr->interp;
+    ForwardParam *paramPtr = evPtr->param;
+    Tcl_Obj *resObj = NULL;	/* Interp result of InvokeTclMethod */
+    ReflectedChannelMap *rcmPtr;/* Map of reflected channels with handlers in
+                                 * this interp. */
+    Tcl_HashEntry *hPtr;	/* Entry in the above map */
+
+    /*
+     * Ignore the event if no one is waiting for its result anymore.
+     */
+
+    if (!resultPtr) {
+	return 1;
+    }
+
+    paramPtr->base.code = TCL_OK;
+    paramPtr->base.msgStr = NULL;
+    paramPtr->base.mustFree = 0;
+
+    switch (evPtr->op) {
+	/*
+	 * The destination thread for the following operations is
+	 * rcPtr->thread, which contains rcPtr->interp, the interp we have to
+	 * call upon for the driver.
+	 */
+
+    case ForwardedClose: {
+	/*
+	 * No parameters/results.
+	 */
+
+	if (InvokeTclMethod(rcPtr, METH_FINAL, NULL, NULL, &resObj)!=TCL_OK) {
+	    ForwardSetObjError(paramPtr, resObj);
+	}
+
+	/*
+	 * Freeing is done here, in the origin thread, callback command
+	 * objects belong to this thread. Deallocating them in a different
+	 * thread is not allowed
+	 *
+	 * We remove the channel from both interpreter and thread maps before
+	 * releasing the memory, to prevent future accesses (like by
+	 * 'postevent') from finding and dereferencing a dangling pointer.
+	 */
+
+	rcmPtr = GetReflectedChannelMap(interp);
+	hPtr = Tcl_FindHashEntry(&rcmPtr->map,
+                Tcl_GetChannelName(rcPtr->chan));
+	Tcl_DeleteHashEntry(hPtr);
+
+	rcmPtr = GetThreadReflectedChannelMap();
+	hPtr = Tcl_FindHashEntry(&rcmPtr->map,
+                Tcl_GetChannelName(rcPtr->chan));
+	Tcl_DeleteHashEntry(hPtr);
+	MarkDead(rcPtr);
+	break;
+    }
+
+    case ForwardedInput: {
+	Tcl_Obj *toReadObj = Tcl_NewIntObj(paramPtr->input.toRead);
+        Tcl_IncrRefCount(toReadObj);
+
+        Tcl_Preserve(rcPtr);
+	if (InvokeTclMethod(rcPtr, METH_READ, toReadObj, NULL, &resObj)!=TCL_OK){
+	    int code = ErrnoReturn(rcPtr, resObj);
+
+	    if (code < 0) {
+		paramPtr->base.code = code;
+	    } else {
+		ForwardSetObjError(paramPtr, resObj);
+	    }
+	    paramPtr->input.toRead = -1;
+	} else {
+	    /*
+	     * Process a regular result.
+	     */
+
+	    int bytec;			/* Number of returned bytes */
+	    unsigned char *bytev;	/* Array of returned bytes */
+
+	    bytev = Tcl_GetByteArrayFromObj(resObj, &bytec);
+
+	    if (paramPtr->input.toRead < bytec) {
+		ForwardSetStaticError(paramPtr, msg_read_toomuch);
+		paramPtr->input.toRead = -1;
+	    } else {
+		if (bytec > 0) {
+		    memcpy(paramPtr->input.buf, bytev, (size_t) bytec);
+		}
+		paramPtr->input.toRead = bytec;
+	    }
+	}
+        Tcl_Release(rcPtr);
+        Tcl_DecrRefCount(toReadObj);
+	break;
+    }
+
+    case ForwardedOutput: {
+	Tcl_Obj *bufObj = Tcl_NewByteArrayObj((unsigned char *)
+                paramPtr->output.buf, paramPtr->output.toWrite);
+        Tcl_IncrRefCount(bufObj);
+
+        Tcl_Preserve(rcPtr);
+	if (InvokeTclMethod(rcPtr, METH_WRITE, bufObj, NULL, &resObj) != TCL_OK) {
+	    int code = ErrnoReturn(rcPtr, resObj);
+
+	    if (code < 0) {
+		paramPtr->base.code = code;
+	    } else {
+		ForwardSetObjError(paramPtr, resObj);
+	    }
+	    paramPtr->output.toWrite = -1;
+	} else {
+	    /*
+	     * Process a regular result.
+	     */
+
+	    int written;
+
+	    if (Tcl_GetIntFromObj(interp, resObj, &written) != TCL_OK) {
+		Tcl_DecrRefCount(resObj);
+		resObj = MarshallError(interp);
+		ForwardSetObjError(paramPtr, resObj);
+		paramPtr->output.toWrite = -1;
+	    } else if (written==0 || paramPtr->output.toWrite<written) {
+		ForwardSetStaticError(paramPtr, msg_write_toomuch);
+		paramPtr->output.toWrite = -1;
+	    } else {
+		paramPtr->output.toWrite = written;
+	    }
+	}
+        Tcl_Release(rcPtr);
+        Tcl_DecrRefCount(bufObj);
+	break;
+    }
+
+    case ForwardedSeek: {
+	Tcl_Obj *offObj = Tcl_NewWideIntObj(paramPtr->seek.offset);
+	Tcl_Obj *baseObj = Tcl_NewStringObj(
+                (paramPtr->seek.seekMode==SEEK_SET) ? "start" :
+                (paramPtr->seek.seekMode==SEEK_CUR) ? "current" : "end", -1);
+
+        Tcl_IncrRefCount(offObj);
+        Tcl_IncrRefCount(baseObj);
+
+        Tcl_Preserve(rcPtr);
+	if (InvokeTclMethod(rcPtr, METH_SEEK, offObj, baseObj, &resObj)!=TCL_OK){
+	    ForwardSetObjError(paramPtr, resObj);
+	    paramPtr->seek.offset = -1;
+	} else {
+	    /*
+	     * Process a regular result. If the type is wrong this may change
+	     * into an error.
+	     */
+
+	    Tcl_WideInt newLoc;
+
+	    if (Tcl_GetWideIntFromObj(interp, resObj, &newLoc) == TCL_OK) {
+		if (newLoc < Tcl_LongAsWide(0)) {
+		    ForwardSetStaticError(paramPtr, msg_seek_beforestart);
+		    paramPtr->seek.offset = -1;
+		} else {
+		    paramPtr->seek.offset = newLoc;
+		}
+	    } else {
+		Tcl_DecrRefCount(resObj);
+		resObj = MarshallError(interp);
+		ForwardSetObjError(paramPtr, resObj);
+		paramPtr->seek.offset = -1;
+	    }
+	}
+        Tcl_Release(rcPtr);
+        Tcl_DecrRefCount(offObj);
+        Tcl_DecrRefCount(baseObj);
+	break;
+    }
+
+    case ForwardedWatch: {
+	Tcl_Obj *maskObj = DecodeEventMask(paramPtr->watch.mask);
+        /* assert maskObj.refCount == 1 */
+
+        Tcl_Preserve(rcPtr);
+	rcPtr->interest = paramPtr->watch.mask;
+	(void) InvokeTclMethod(rcPtr, METH_WATCH, maskObj, NULL, NULL);
+	Tcl_DecrRefCount(maskObj);
+        Tcl_Release(rcPtr);
+	break;
+    }
+
+    case ForwardedBlock: {
+	Tcl_Obj *blockObj = Tcl_NewBooleanObj(!paramPtr->block.nonblocking);
+
+        Tcl_IncrRefCount(blockObj);
+        Tcl_Preserve(rcPtr);
+	if (InvokeTclMethod(rcPtr, METH_BLOCKING, blockObj, NULL,
+                &resObj) != TCL_OK) {
+	    ForwardSetObjError(paramPtr, resObj);
+	}
+        Tcl_Release(rcPtr);
+        Tcl_DecrRefCount(blockObj);
+	break;
+    }
+
+    case ForwardedSetOpt: {
+	Tcl_Obj *optionObj = Tcl_NewStringObj(paramPtr->setOpt.name, -1);
+	Tcl_Obj *valueObj  = Tcl_NewStringObj(paramPtr->setOpt.value, -1);
+
+        Tcl_IncrRefCount(optionObj);
+        Tcl_IncrRefCount(valueObj);
+        Tcl_Preserve(rcPtr);
+	if (InvokeTclMethod(rcPtr, METH_CONFIGURE, optionObj, valueObj,
+                &resObj) != TCL_OK) {
+	    ForwardSetObjError(paramPtr, resObj);
+	}
+        Tcl_Release(rcPtr);
+        Tcl_DecrRefCount(optionObj);
+        Tcl_DecrRefCount(valueObj);
+	break;
+    }
+
+    case ForwardedGetOpt: {
+	/*
+	 * Retrieve the value of one option.
+	 */
+
+	Tcl_Obj *optionObj = Tcl_NewStringObj(paramPtr->getOpt.name, -1);
+
+        Tcl_IncrRefCount(optionObj);
+        Tcl_Preserve(rcPtr);
+	if (InvokeTclMethod(rcPtr, METH_CGET, optionObj, NULL, &resObj)!=TCL_OK){
+	    ForwardSetObjError(paramPtr, resObj);
+	} else {
+	    TclDStringAppendObj(paramPtr->getOpt.value, resObj);
+	}
+        Tcl_Release(rcPtr);
+        Tcl_DecrRefCount(optionObj);
+	break;
+    }
+
+    case ForwardedGetOptAll:
+	/*
+	 * Retrieve all options.
+	 */
+
+        Tcl_Preserve(rcPtr);
+	if (InvokeTclMethod(rcPtr, METH_CGETALL, NULL, NULL, &resObj) != TCL_OK){
+	    ForwardSetObjError(paramPtr, resObj);
+	} else {
+	    /*
+	     * Extract list, validate that it is a list, and #elements. See
+	     * NOTE (4) as well.
+	     */
+
+	    int listc;
+	    Tcl_Obj **listv;
+
+	    if (Tcl_ListObjGetElements(interp, resObj, &listc,
+                    &listv) != TCL_OK) {
+		Tcl_DecrRefCount(resObj);
+		resObj = MarshallError(interp);
+		ForwardSetObjError(paramPtr, resObj);
+	    } else if ((listc % 2) == 1) {
+		/*
+		 * Odd number of elements is wrong. [x].
+		 */
+
+		char *buf = ckalloc(200);
+		sprintf(buf,
+			"{Expected list with even number of elements, got %d %s instead}",
+			listc, (listc == 1 ? "element" : "elements"));
+
+		ForwardSetDynamicError(paramPtr, buf);
+	    } else {
+		int len;
+		const char *str = Tcl_GetStringFromObj(resObj, &len);
+
+		if (len) {
+		    TclDStringAppendLiteral(paramPtr->getOpt.value, " ");
+		    Tcl_DStringAppend(paramPtr->getOpt.value, str, len);
+		}
+	    }
+	}
+        Tcl_Release(rcPtr);
+	break;
+
+    default:
+	/*
+	 * Bad operation code.
+	 */
+
+	Tcl_Panic("Bad operation code in ForwardProc");
+	break;
+    }
+
+    /*
+     * Remove the reference we held on the result of the invoke, if we had
+     * such.
+     */
+
+    if (resObj != NULL) {
+	Tcl_DecrRefCount(resObj);
+    }
+
+    if (resultPtr) {
+	/*
+	 * Report the forwarding result synchronously to the waiting caller.
+	 * This unblocks (*) as well. This is wrapped into a conditional
+	 * because the caller may have exited in the mean time.
+	 */
+
+	Tcl_MutexLock(&rcForwardMutex);
+	resultPtr->result = TCL_OK;
+	Tcl_ConditionNotify(&resultPtr->done);
+	Tcl_MutexUnlock(&rcForwardMutex);
+    }
+
+    return 1;
+}
+
+static void
+SrcExitProc(
+    ClientData clientData)
+{
+    ForwardingEvent *evPtr = clientData;
+    ForwardingResult *resultPtr;
+    ForwardParam *paramPtr;
+
+    /*
+     * NOTE (2): Can this handler be called with the originator blocked?
+     */
+
+    /*
+     * The originator for the event exited. It is not sure if this can happen,
+     * as the originator should be blocked at (*) while the event is in
+     * transit/pending.
+     *
+     * We make sure that the event cannot refer to the result anymore, remove
+     * it from the list of pending results and free the structure. Locking the
+     * access ensures that we cannot get in conflict with "ForwardProc",
+     * should it already execute the event.
+     */
+
+    Tcl_MutexLock(&rcForwardMutex);
+
+    resultPtr = evPtr->resultPtr;
+    paramPtr = evPtr->param;
+
+    evPtr->resultPtr = NULL;
+    resultPtr->evPtr = NULL;
+    resultPtr->result = TCL_ERROR;
+
+    ForwardSetStaticError(paramPtr, msg_send_originlost);
+
+    /*
+     * See below: TclSpliceOut(resultPtr, forwardList);
+     */
+
+    Tcl_MutexUnlock(&rcForwardMutex);
+
+    /*
+     * This unlocks (*). The structure will be spliced out and freed by
+     * "ForwardProc". Maybe.
+     */
+
+    Tcl_ConditionNotify(&resultPtr->done);
+}
+
+static void
+ForwardSetObjError(
+    ForwardParam *paramPtr,
+    Tcl_Obj *obj)
+{
+    int len;
+    const char *msgStr = Tcl_GetStringFromObj(obj, &len);
+
+    len++;
+    ForwardSetDynamicError(paramPtr, ckalloc(len));
+    memcpy(paramPtr->base.msgStr, msgStr, (unsigned) len);
+}
+#endif
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/generic/tclIORTrans.c b/generic/tclIORTrans.c
new file mode 100644
index 0000000..af86ba5
--- /dev/null
+++ b/generic/tclIORTrans.c
@@ -0,0 +1,3427 @@
+/*
+ * tclIORTrans.c --
+ *
+ *	This file contains the implementation of Tcl's generic transformation
+ *	reflection code, which allows the implementation of Tcl channel
+ *	transformations in Tcl code.
+ *
+ *	Parts of this file are based on code contributed by Jean-Claude
+ *	Wippler.
+ *
+ *	See TIP #230 for the specification of this functionality.
+ *
+ * Copyright (c) 2007-2008 ActiveState.
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#include "tclInt.h"
+#include "tclIO.h"
+#include <assert.h>
+
+#ifndef EINVAL
+#define EINVAL	9
+#endif
+#ifndef EOK
+#define EOK	0
+#endif
+
+/* DUPLICATE of HaveVersion() in tclIO.c // TODO - MODULE_SCOPE */
+static int		HaveVersion(const Tcl_ChannelType *typePtr,
+			    Tcl_ChannelTypeVersion minimumVersion);
+
+/*
+ * Signatures of all functions used in the C layer of the reflection.
+ */
+
+static int		ReflectClose(ClientData clientData,
+			    Tcl_Interp *interp);
+static int		ReflectInput(ClientData clientData, char *buf,
+			    int toRead, int *errorCodePtr);
+static int		ReflectOutput(ClientData clientData, const char *buf,
+			    int toWrite, int *errorCodePtr);
+static void		ReflectWatch(ClientData clientData, int mask);
+static int		ReflectBlock(ClientData clientData, int mode);
+static Tcl_WideInt	ReflectSeekWide(ClientData clientData,
+			    Tcl_WideInt offset, int mode, int *errorCodePtr);
+static int		ReflectSeek(ClientData clientData, long offset,
+			    int mode, int *errorCodePtr);
+static int		ReflectGetOption(ClientData clientData,
+			    Tcl_Interp *interp, const char *optionName,
+			    Tcl_DString *dsPtr);
+static int		ReflectSetOption(ClientData clientData,
+			    Tcl_Interp *interp, const char *optionName,
+			    const char *newValue);
+static int		ReflectHandle(ClientData clientData, int direction,
+			    ClientData *handle);
+static int		ReflectNotify(ClientData clientData, int mask);
+
+/*
+ * The C layer channel type/driver definition used by the reflection.
+ */
+
+static const Tcl_ChannelType tclRTransformType = {
+    "tclrtransform",		/* Type name. */
+    TCL_CHANNEL_VERSION_5,	/* v5 channel. */
+    ReflectClose,		/* Close channel, clean instance data. */
+    ReflectInput,		/* Handle read request. */
+    ReflectOutput,		/* Handle write request. */
+    ReflectSeek,		/* Move location of access point. */
+    ReflectSetOption,		/* Set options. */
+    ReflectGetOption,		/* Get options. */
+    ReflectWatch,		/* Initialize notifier. */
+    ReflectHandle,		/* Get OS handle from the channel. */
+    NULL,			/* No close2 support. NULL'able. */
+    ReflectBlock,		/* Set blocking/nonblocking. */
+    NULL,			/* Flush channel. Not used by core.
+				 * NULL'able. */
+    ReflectNotify,		/* Handle events. */
+    ReflectSeekWide,		/* Move access point (64 bit). */
+    NULL,			/* thread action */
+    NULL			/* truncate */
+};
+
+/*
+ * Structure of the buffer to hold transform results to be consumed by higher
+ * layers upon reading from the channel, plus the functions to manage such.
+ */
+
+typedef struct _ResultBuffer_ {
+    unsigned char *buf;		/* Reference to the buffer area. */
+    int allocated;		/* Allocated size of the buffer area. */
+    int used;			/* Number of bytes in the buffer,
+				 * <= allocated. */
+} ResultBuffer;
+
+#define ResultLength(r) ((r)->used)
+/* static int		ResultLength(ResultBuffer *r); */
+
+static void		ResultClear(ResultBuffer *r);
+static void		ResultInit(ResultBuffer *r);
+static void		ResultAdd(ResultBuffer *r, unsigned char *buf,
+			    int toWrite);
+static int		ResultCopy(ResultBuffer *r, unsigned char *buf,
+			    int toRead);
+
+#define RB_INCREMENT (512)
+
+/*
+ * Convenience macro to make some casts easier to use.
+ */
+
+#define UCHARP(x)	((unsigned char *) (x))
+
+/*
+ * Instance data for a reflected transformation. ===========================
+ */
+
+typedef struct {
+    Tcl_Channel chan;		/* Back reference to the channel of the
+				 * transformation itself. */
+    Tcl_Channel parent;		/* Reference to the channel the transformation
+				 * was pushed on. */
+    Tcl_Interp *interp;		/* Reference to the interpreter containing the
+				 * Tcl level part of the channel. */
+    Tcl_Obj *handle;		/* Reference to transform handle. Also stored
+				 * in the argv, see below. The separate field
+				 * gives us direct access, needed when working
+				 * with the reflection maps. */
+#ifdef TCL_THREADS
+    Tcl_ThreadId thread;	/* Thread the 'interp' belongs to. */
+#endif
+
+    Tcl_TimerToken timer;
+
+    /* See [==] as well.
+     * Storage for the command prefix and the additional words required for
+     * the invocation of methods in the command handler.
+     *
+     * argv [0] ... [.] | [argc-2] [argc-1] | [argc]  [argc+2]
+     *      cmd ... pfx | method   chan     | detail1 detail2
+     *      ~~~~ CT ~~~            ~~ CT ~~
+     *
+     * CT = Belongs to the 'Command handler Thread'.
+     */
+
+    int argc;			/* Number of preallocated words - 2. */
+    Tcl_Obj **argv;		/* Preallocated array for calling the handler.
+				 * args[0] is placeholder for cmd word.
+				 * Followed by the arguments in the prefix,
+				 * plus 4 placeholders for method, channel,
+				 * and at most two varying (method specific)
+				 * words. */
+    int methods;		/* Bitmask of supported methods. */
+
+    /*
+     * NOTE (9): Should we have predefined shared literals for the method
+     * names?
+     */
+
+    int mode;			/* Mask of R/W mode */
+    int nonblocking;		/* Flag: Channel is blocking or not. */
+    int readIsDrained;		/* Flag: Read buffers are flushed. */
+    int eofPending;		/* Flag: EOF seen down, but not raised up */
+    int dead;			/* Boolean signal that some operations
+				 * should no longer be attempted. */
+    ResultBuffer result;
+} ReflectedTransform;
+
+/*
+ * Structure of the table mapping from transform handles to reflected
+ * transform (channels). Each interpreter which has the handler command for
+ * one or more reflected transforms records them in such a table, so that we
+ * are able to find them during interpreter/thread cleanup even if the actual
+ * channel they belong to was moved to a different interpreter and/or thread.
+ *
+ * The table is reachable via the standard interpreter AssocData, the key is
+ * defined below.
+ */
+
+typedef struct {
+    Tcl_HashTable map;
+} ReflectedTransformMap;
+
+#define RTMKEY "ReflectedTransformMap"
+
+/*
+ * Method literals. ==================================================
+ */
+
+static const char *const methodNames[] = {
+    "clear",		/* OPT */
+    "drain",		/* OPT, drain => read */
+    "finalize",		/*     */
+    "flush",		/* OPT, flush => write */
+    "initialize",	/*     */
+    "limit?",		/* OPT */
+    "read",		/* OPT */
+    "write",		/* OPT */
+    NULL
+};
+typedef enum {
+    METH_CLEAR,
+    METH_DRAIN,
+    METH_FINAL,
+    METH_FLUSH,
+    METH_INIT,
+    METH_LIMIT,
+    METH_READ,
+    METH_WRITE
+} MethodName;
+
+#define FLAG(m) (1 << (m))
+#define REQUIRED_METHODS \
+	(FLAG(METH_INIT) | FLAG(METH_FINAL))
+#define RANDW \
+	(TCL_READABLE | TCL_WRITABLE)
+
+#define IMPLIES(a,b)	((!(a)) || (b))
+#define NEGIMPL(a,b)
+#define HAS(x,f)	(x & FLAG(f))
+
+#ifdef TCL_THREADS
+/*
+ * Thread specific types and structures.
+ *
+ * We are here essentially creating a very specific implementation of 'thread
+ * send'.
+ */
+
+/*
+ * Enumeration of all operations which can be forwarded.
+ */
+
+typedef enum {
+    ForwardedClear,
+    ForwardedClose,
+    ForwardedDrain,
+    ForwardedFlush,
+    ForwardedInput,
+    ForwardedLimit,
+    ForwardedOutput
+} ForwardedOperation;
+
+/*
+ * Event used to forward driver invocations to the thread actually managing
+ * the channel. We cannot construct the command to execute and forward that.
+ * Because then it will contain a mixture of Tcl_Obj's belonging to both the
+ * command handler thread (CT), and the thread managing the channel (MT),
+ * executed in CT. Tcl_Obj's are not allowed to cross thread boundaries. So we
+ * forward an operation code, the argument details, and reference to results.
+ * The command is assembled in the CT and belongs fully to that thread. No
+ * sharing problems.
+ */
+
+typedef struct ForwardParamBase {
+    int code;			/* O: Ok/Fail of the cmd handler */
+    char *msgStr;		/* O: Error message for handler failure */
+    int mustFree;		/* O: True if msgStr is allocated, false if
+				 * otherwise (static). */
+} ForwardParamBase;
+
+/*
+ * Operation specific parameter/result structures. (These are "subtypes" of
+ * ForwardParamBase. Where an operation does not need any special types, it
+ * has no "subtype" and just uses ForwardParamBase, as listed above.)
+ */
+
+struct ForwardParamTransform {
+    ForwardParamBase base;	/* "Supertype". MUST COME FIRST. */
+    char *buf;			/* I: Bytes to transform,
+				 * O: Bytes in transform result */
+    int size;			/* I: #bytes to transform,
+				 * O: #bytes in the transform result */
+};
+struct ForwardParamLimit {
+    ForwardParamBase base;	/* "Supertype". MUST COME FIRST. */
+    int max;			/* O: Character read limit */
+};
+
+/*
+ * Now join all these together in a single union for convenience.
+ */
+
+typedef union ForwardParam {
+    ForwardParamBase base;
+    struct ForwardParamTransform transform;
+    struct ForwardParamLimit limit;
+} ForwardParam;
+
+/*
+ * Forward declaration.
+ */
+
+typedef struct ForwardingResult ForwardingResult;
+
+/*
+ * General event structure, with reference to operation specific data.
+ */
+
+typedef struct ForwardingEvent {
+    Tcl_Event event;		/* Basic event data, has to be first item */
+    ForwardingResult *resultPtr;
+    ForwardedOperation op;	/* Forwarded driver operation */
+    ReflectedTransform *rtPtr;	/* Channel instance */
+    ForwardParam *param;	/* Packaged arguments and return values, a
+				 * ForwardParam pointer. */
+} ForwardingEvent;
+
+/*
+ * Structure to manage the result of the forwarding. This is not the result of
+ * the operation itself, but about the success of the forward event itself.
+ * The event can be successful, even if the operation which was forwarded
+ * failed. It is also there to manage the synchronization between the involved
+ * threads.
+ */
+
+struct ForwardingResult {
+    Tcl_ThreadId src;		/* Originating thread. */
+    Tcl_ThreadId dst;		/* Thread the op was forwarded to. */
+    Tcl_Interp *dsti;		/* Interpreter in the thread the op was
+				 * forwarded to. */
+    Tcl_Condition done;		/* Condition variable the forwarder blocks
+				 * on. */
+    int result;			/* TCL_OK or TCL_ERROR */
+    ForwardingEvent *evPtr;	/* Event the result belongs to. */
+    ForwardingResult *prevPtr, *nextPtr;
+				/* Links into the list of pending forwarded
+				 * results. */
+};
+
+typedef struct ThreadSpecificData {
+    /*
+     * Table of all reflected transformations owned by this thread.
+     */
+
+    ReflectedTransformMap *rtmPtr;
+} ThreadSpecificData;
+
+static Tcl_ThreadDataKey dataKey;
+
+/*
+ * List of forwarded operations which have not completed yet, plus the mutex
+ * to protect the access to this process global list.
+ */
+
+static ForwardingResult *forwardList = NULL;
+TCL_DECLARE_MUTEX(rtForwardMutex)
+
+/*
+ * Function containing the generic code executing a forward, and wrapper
+ * macros for the actual operations we wish to forward. Uses ForwardProc as
+ * the event function executed by the thread receiving a forwarding event
+ * (which executes the appropriate function and collects the result, if any).
+ *
+ * The two ExitProcs are handlers so that things do not deadlock when either
+ * thread involved in the forwarding exits. They also clean things up so that
+ * we don't leak resources when threads go away.
+ */
+
+static void		ForwardOpToOwnerThread(ReflectedTransform *rtPtr,
+			    ForwardedOperation op, const void *param);
+static int		ForwardProc(Tcl_Event *evPtr, int mask);
+static void		SrcExitProc(ClientData clientData);
+
+#define FreeReceivedError(p) \
+	do {								\
+	    if ((p)->base.mustFree) {					\
+		ckfree((p)->base.msgStr);				\
+	    }								\
+	} while (0)
+#define PassReceivedErrorInterp(i,p) \
+	do {								\
+	    if ((i) != NULL) {						\
+		Tcl_SetChannelErrorInterp((i),				\
+			Tcl_NewStringObj((p)->base.msgStr, -1));	\
+	    }								\
+	    FreeReceivedError(p);					\
+	} while (0)
+#define PassReceivedError(c,p) \
+	do {								\
+	    Tcl_SetChannelError((c),					\
+		    Tcl_NewStringObj((p)->base.msgStr, -1));		\
+	    FreeReceivedError(p);					\
+	} while (0)
+#define ForwardSetStaticError(p,emsg) \
+	do {								\
+	    (p)->base.code = TCL_ERROR;					\
+	    (p)->base.mustFree = 0;					\
+	    (p)->base.msgStr = (char *) (emsg);				\
+	} while (0)
+#define ForwardSetDynamicError(p,emsg) \
+	do {								\
+	    (p)->base.code = TCL_ERROR;					\
+	    (p)->base.mustFree = 1;					\
+	    (p)->base.msgStr = (char *) (emsg);				\
+	} while (0)
+
+static void		ForwardSetObjError(ForwardParam *p,
+			    Tcl_Obj *objPtr);
+static ReflectedTransformMap *	GetThreadReflectedTransformMap(void);
+static void		DeleteThreadReflectedTransformMap(
+			    ClientData clientData);
+#endif /* TCL_THREADS */
+
+#define SetChannelErrorStr(c,msgStr) \
+	Tcl_SetChannelError((c), Tcl_NewStringObj((msgStr), -1))
+
+static Tcl_Obj *	MarshallError(Tcl_Interp *interp);
+static void		UnmarshallErrorResult(Tcl_Interp *interp,
+			    Tcl_Obj *msgObj);
+
+/*
+ * Static functions for this file:
+ */
+
+static Tcl_Obj *	DecodeEventMask(int mask);
+static ReflectedTransform * NewReflectedTransform(Tcl_Interp *interp,
+			    Tcl_Obj *cmdpfxObj, int mode, Tcl_Obj *handleObj,
+			    Tcl_Channel parentChan);
+static Tcl_Obj *	NextHandle(void);
+static void		FreeReflectedTransform(ReflectedTransform *rtPtr);
+static void		FreeReflectedTransformArgs(ReflectedTransform *rtPtr);
+static int		InvokeTclMethod(ReflectedTransform *rtPtr,
+			    const char *method, Tcl_Obj *argOneObj,
+			    Tcl_Obj *argTwoObj, Tcl_Obj **resultObjPtr);
+
+static ReflectedTransformMap *	GetReflectedTransformMap(Tcl_Interp *interp);
+static void		DeleteReflectedTransformMap(ClientData clientData,
+			    Tcl_Interp *interp);
+
+/*
+ * Global constant strings (messages). ==================
+ * These string are used directly as bypass errors, thus they have to be valid
+ * Tcl lists where the last element is the message itself. Hence the
+ * list-quoting to keep the words of the message together. See also [x].
+ */
+
+static const char *msg_read_unsup = "{read not supported by Tcl driver}";
+static const char *msg_write_unsup = "{write not supported by Tcl driver}";
+#ifdef TCL_THREADS
+static const char *msg_send_originlost = "{Channel thread lost}";
+static const char *msg_send_dstlost = "{Owner lost}";
+#endif /* TCL_THREADS */
+static const char *msg_dstlost =
+    "-code 1 -level 0 -errorcode NONE -errorinfo {} -errorline 1 {Owner lost}";
+
+/*
+ * Timer management (flushing out buffered data via artificial events).
+ */
+
+/*
+ * Helper functions encapsulating some of the thread forwarding to make the
+ * control flow in callers easier.
+ */
+
+static void		TimerKill(ReflectedTransform *rtPtr);
+static void		TimerSetup(ReflectedTransform *rtPtr);
+static void		TimerRun(ClientData clientData);
+static int		TransformRead(ReflectedTransform *rtPtr,
+			    int *errorCodePtr, Tcl_Obj *bufObj);
+static int		TransformWrite(ReflectedTransform *rtPtr,
+			    int *errorCodePtr, unsigned char *buf,
+			    int toWrite);
+static int		TransformDrain(ReflectedTransform *rtPtr,
+			    int *errorCodePtr);
+static int		TransformFlush(ReflectedTransform *rtPtr,
+			    int *errorCodePtr, int op);
+static void		TransformClear(ReflectedTransform *rtPtr);
+static int		TransformLimit(ReflectedTransform *rtPtr,
+			    int *errorCodePtr, int *maxPtr);
+
+/*
+ * Operation codes for TransformFlush().
+ */
+
+#define FLUSH_WRITE	1
+#define FLUSH_DISCARD	0
+
+/*
+ * Main methods to plug into the 'chan' ensemble'. ==================
+ */
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclChanPushObjCmd --
+ *
+ *	This function is invoked to process the "chan push" Tcl command. See
+ *	the user documentation for details on what it does.
+ *
+ * Results:
+ *	A standard Tcl result. The handle of the new channel is placed in the
+ *	interp result.
+ *
+ * Side effects:
+ *	Creates a new channel.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclChanPushObjCmd(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const *objv)
+{
+    ReflectedTransform *rtPtr;	/* Instance data of the new (transform)
+				 * channel. */
+    Tcl_Obj *chanObj;		/* Handle of parent channel */
+    Tcl_Channel parentChan;	/* Token of parent channel */
+    int mode;			/* R/W mode of parent, later the new channel.
+				 * Has to match the abilities of the handler
+				 * commands */
+    Tcl_Obj *cmdObj;		/* Command prefix, list of words */
+    Tcl_Obj *cmdNameObj;	/* Command name */
+    Tcl_Obj *rtId;		/* Handle of the new transform (channel) */
+    Tcl_Obj *modeObj;		/* mode in obj form for method call */
+    int listc;			/* Result of 'initialize', and of */
+    Tcl_Obj **listv;		/* its sublist in the 2nd element */
+    int methIndex;		/* Encoded method name */
+    int result;			/* Result code for 'initialize' */
+    Tcl_Obj *resObj;		/* Result data for 'initialize' */
+    int methods;		/* Bitmask for supported methods. */
+    ReflectedTransformMap *rtmPtr;
+				/* Map of reflected transforms with handlers
+				 * in this interp. */
+    Tcl_HashEntry *hPtr;	/* Entry in the above map */
+    int isNew;			/* Placeholder. */
+
+    /*
+     * Syntax:   chan push CHANNEL CMDPREFIX
+     *           [0]  [1]  [2]     [3]
+     *
+     * Actually: rPush CHANNEL CMDPREFIX
+     *           [0]   [1]     [2]
+     */
+
+#define CHAN	(1)
+#define CMD	(2)
+
+    /*
+     * Number of arguments...
+     */
+
+    if (objc != 3) {
+	Tcl_WrongNumArgs(interp, 1, objv, "channel cmdprefix");
+	return TCL_ERROR;
+    }
+
+    /*
+     * First argument is a channel handle.
+     */
+
+    chanObj = objv[CHAN];
+    parentChan = Tcl_GetChannel(interp, Tcl_GetString(chanObj), &mode);
+    if (parentChan == NULL) {
+	return TCL_ERROR;
+    }
+    parentChan = Tcl_GetTopChannel(parentChan);
+
+    /*
+     * Second argument is command prefix, i.e. list of words, first word is
+     * name of handler command, other words are fixed arguments. Run the
+     * 'initialize' method to get the list of supported methods. Validate
+     * this.
+     */
+
+    cmdObj = objv[CMD];
+
+    /*
+     * Basic check that the command prefix truly is a list.
+     */
+
+    if (Tcl_ListObjIndex(interp, cmdObj, 0, &cmdNameObj) != TCL_OK) {
+	return TCL_ERROR;
+    }
+
+    /*
+     * Now create the transformation (channel).
+     */
+
+    rtId = NextHandle();
+    rtPtr = NewReflectedTransform(interp, cmdObj, mode, rtId, parentChan);
+
+    /*
+     * Invoke 'initialize' and validate that the handler is present and ok.
+     * Squash the transformation if not.
+     */
+
+    modeObj = DecodeEventMask(mode);
+    /* assert modeObj.refCount == 1 */
+    result = InvokeTclMethod(rtPtr, "initialize", modeObj, NULL, &resObj);
+    Tcl_DecrRefCount(modeObj);
+    if (result != TCL_OK) {
+	UnmarshallErrorResult(interp, resObj);
+	Tcl_DecrRefCount(resObj);	/* Remove reference held from invoke */
+	goto error;
+    }
+
+    /*
+     * Verify the result.
+     * - List, of method names. Convert to mask. Check for non-optionals
+     *   through the mask. Compare open mode against optional r/w.
+     */
+
+    if (Tcl_ListObjGetElements(NULL, resObj, &listc, &listv) != TCL_OK) {
+        Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+                "chan handler \"%s initialize\" returned non-list: %s",
+                Tcl_GetString(cmdObj), Tcl_GetString(resObj)));
+	Tcl_DecrRefCount(resObj);
+	goto error;
+    }
+
+    methods = 0;
+    while (listc > 0) {
+	if (Tcl_GetIndexFromObj(interp, listv[listc-1], methodNames,
+		"method", TCL_EXACT, &methIndex) != TCL_OK) {
+	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		    "chan handler \"%s initialize\" returned %s",
+		    Tcl_GetString(cmdObj),
+		    Tcl_GetString(Tcl_GetObjResult(interp))));
+	    Tcl_DecrRefCount(resObj);
+	    goto error;
+	}
+
+	methods |= FLAG(methIndex);
+	listc--;
+    }
+    Tcl_DecrRefCount(resObj);
+
+    if ((REQUIRED_METHODS & methods) != REQUIRED_METHODS) {
+        Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+                "chan handler \"%s\" does not support all required methods",
+                Tcl_GetString(cmdObj)));
+	goto error;
+    }
+
+    /*
+     * Mode tell us what the parent channel supports. The methods tell us what
+     * the handler supports. We remove the non-supported bits from the mode
+     * and check that the channel is not completely inacessible. Afterward the
+     * mode tells us which methods are still required, and these methods will
+     * also be supported by the handler, by design of the check.
+     */
+
+    if (!HAS(methods, METH_READ)) {
+	mode &= ~TCL_READABLE;
+    }
+    if (!HAS(methods, METH_WRITE)) {
+	mode &= ~TCL_WRITABLE;
+    }
+
+    if (!mode) {
+        Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+                "chan handler \"%s\" makes the channel inaccessible",
+                Tcl_GetString(cmdObj)));
+	goto error;
+    }
+
+    /*
+     * The mode and support for it is ok, now check the internal constraints.
+     */
+
+    if (!IMPLIES(HAS(methods, METH_DRAIN), HAS(methods, METH_READ))) {
+        Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+                "chan handler \"%s\" supports \"drain\" but not \"read\"",
+                Tcl_GetString(cmdObj)));
+	goto error;
+    }
+
+    if (!IMPLIES(HAS(methods, METH_FLUSH), HAS(methods, METH_WRITE))) {
+        Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+                "chan handler \"%s\" supports \"flush\" but not \"write\"",
+                Tcl_GetString(cmdObj)));
+	goto error;
+    }
+
+    Tcl_ResetResult(interp);
+
+    /*
+     * Everything is fine now.
+     */
+
+    rtPtr->methods = methods;
+    rtPtr->mode = mode;
+    rtPtr->chan = Tcl_StackChannel(interp, &tclRTransformType, rtPtr, mode,
+	    rtPtr->parent);
+
+    /*
+     * Register the transform in our our map for proper handling of deleted
+     * interpreters and/or threads.
+     */
+
+    rtmPtr = GetReflectedTransformMap(interp);
+    hPtr = Tcl_CreateHashEntry(&rtmPtr->map, Tcl_GetString(rtId), &isNew);
+    if (!isNew && rtPtr != Tcl_GetHashValue(hPtr)) {
+	Tcl_Panic("TclChanPushObjCmd: duplicate transformation handle");
+    }
+    Tcl_SetHashValue(hPtr, rtPtr);
+#ifdef TCL_THREADS
+    rtmPtr = GetThreadReflectedTransformMap();
+    hPtr = Tcl_CreateHashEntry(&rtmPtr->map, Tcl_GetString(rtId), &isNew);
+    Tcl_SetHashValue(hPtr, rtPtr);
+#endif /* TCL_THREADS */
+
+    /*
+     * Return the channel as the result of the command.
+     */
+
+    Tcl_SetObjResult(interp, Tcl_NewStringObj(
+	    Tcl_GetChannelName(rtPtr->chan), -1));
+    return TCL_OK;
+
+  error:
+    /*
+     * We are not going through ReflectClose as we never had a channel
+     * structure.
+     */
+
+    Tcl_EventuallyFree(rtPtr, (Tcl_FreeProc *) FreeReflectedTransform);
+    return TCL_ERROR;
+
+#undef CHAN
+#undef CMD
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclChanPopObjCmd --
+ *
+ *	This function is invoked to process the "chan pop" Tcl command. See
+ *	the user documentation for details on what it does.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	Posts events to a reflected channel, invokes event handlers. The
+ *	latter implies that arbitrary side effects are possible.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclChanPopObjCmd(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const *objv)
+{
+    /*
+     * Syntax:   chan pop CHANNEL
+     *           [0]  [1] [2]
+     *
+     * Actually: rPop CHANNEL
+     *           [0]  [1]
+     */
+
+#define CHAN	(1)
+
+    const char *chanId;		/* Tcl level channel handle */
+    Tcl_Channel chan;		/* Channel associated to the handle */
+    int mode;			/* Channel r/w mode */
+
+    /*
+     * Number of arguments...
+     */
+
+    if (objc != 2) {
+	Tcl_WrongNumArgs(interp, 1, objv, "channel");
+	return TCL_ERROR;
+    }
+
+    /*
+     * First argument is a channel, which may have a (reflected)
+     * transformation.
+     */
+
+    chanId = TclGetString(objv[CHAN]);
+    chan = Tcl_GetChannel(interp, chanId, &mode);
+
+    if (chan == NULL) {
+	return TCL_ERROR;
+    }
+
+    /*
+     * Removing transformations is generic, and not restricted to reflected
+     * transformations.
+     */
+
+    Tcl_UnstackChannel(interp, chan);
+    return TCL_OK;
+
+#undef CHAN
+}
+
+/*
+ * Channel error message marshalling utilities.
+ */
+
+static Tcl_Obj *
+MarshallError(
+    Tcl_Interp *interp)
+{
+    /*
+     * Capture the result status of the interpreter into a string. => List of
+     * options and values, followed by the error message. The result has
+     * refCount 0.
+     */
+
+    Tcl_Obj *returnOpt = Tcl_GetReturnOptions(interp, TCL_ERROR);
+
+    /*
+     * => returnOpt.refCount == 0. We can append directly.
+     */
+
+    Tcl_ListObjAppendElement(NULL, returnOpt, Tcl_GetObjResult(interp));
+    return returnOpt;
+}
+
+static void
+UnmarshallErrorResult(
+    Tcl_Interp *interp,
+    Tcl_Obj *msgObj)
+{
+    int lc;
+    Tcl_Obj **lv;
+    int explicitResult;
+    int numOptions;
+
+    /*
+     * Process the caught message.
+     *
+     * Syntax = (option value)... ?message?
+     *
+     * Bad syntax causes a panic. This is OK because the other side uses
+     * Tcl_GetReturnOptions and list construction functions to marshall the
+     * information; if we panic here, something has gone badly wrong already.
+     */
+
+    if (Tcl_ListObjGetElements(interp, msgObj, &lc, &lv) != TCL_OK) {
+	Tcl_Panic("TclChanCaughtErrorBypass: Bad syntax of caught result");
+    }
+    if (interp == NULL) {
+	return;
+    }
+
+    explicitResult = lc & 1;		/* Odd number of values? */
+    numOptions = lc - explicitResult;
+
+    if (explicitResult) {
+	Tcl_SetObjResult(interp, lv[lc-1]);
+    }
+
+    Tcl_SetReturnOptions(interp, Tcl_NewListObj(numOptions, lv));
+    ((Interp *) interp)->flags &= ~ERR_ALREADY_LOGGED;
+}
+
+/*
+ * Driver functions. ================================================
+ */
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ReflectClose --
+ *
+ *	This function is invoked when the channel is closed, to delete the
+ *	driver specific instance data.
+ *
+ * Results:
+ *	A posix error.
+ *
+ * Side effects:
+ *	Releases memory. Arbitrary, as it calls upon a script.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+ReflectClose(
+    ClientData clientData,
+    Tcl_Interp *interp)
+{
+    ReflectedTransform *rtPtr = clientData;
+    int errorCode, errorCodeSet = 0;
+    int result = TCL_OK;	/* Result code for 'close' */
+    Tcl_Obj *resObj;		/* Result data for 'close' */
+    ReflectedTransformMap *rtmPtr;
+				/* Map of reflected transforms with handlers
+				 * in this interp. */
+    Tcl_HashEntry *hPtr;	/* Entry in the above map */
+
+    if (TclInThreadExit()) {
+	/*
+	 * This call comes from TclFinalizeIOSystem. There are no
+	 * interpreters, and therefore we cannot call upon the handler command
+	 * anymore. Threading is irrelevant as well. We simply clean up all
+	 * our C level data structures and leave the Tcl level to the other
+	 * finalization functions.
+	 */
+
+	/*
+	 * THREADED => Forward this to the origin thread
+	 *
+	 * Note: DeleteThreadReflectedTransformMap() is the thread exit handler
+	 * for the origin thread. Use this to clean up the structure? Except
+	 * if lost?
+	 */
+
+#ifdef TCL_THREADS
+	if (rtPtr->thread != Tcl_GetCurrentThread()) {
+	    ForwardParam p;
+
+	    ForwardOpToOwnerThread(rtPtr, ForwardedClose, &p);
+	    result = p.base.code;
+
+	    if (result != TCL_OK) {
+		FreeReceivedError(&p);
+	    }
+	}
+#endif /* TCL_THREADS */
+
+	Tcl_EventuallyFree(rtPtr, (Tcl_FreeProc *) FreeReflectedTransform);
+	return EOK;
+    }
+
+    /*
+     * In the reflected channel implementation a cleaned method mask here
+     * implies that the channel creation was aborted, and "finalize" must not
+     * be called. for transformations however we are not going through here on
+     * such an abort, but directly through FreeReflectedTransform. So for us
+     * that check is not necessary. We always go through 'finalize'.
+     */
+
+    if (HAS(rtPtr->methods, METH_DRAIN) && !rtPtr->readIsDrained) {
+	if (!TransformDrain(rtPtr, &errorCode)) {
+#ifdef TCL_THREADS
+	    if (rtPtr->thread != Tcl_GetCurrentThread()) {
+		Tcl_EventuallyFree(rtPtr,
+			(Tcl_FreeProc *) FreeReflectedTransform);
+		return errorCode;
+	    }
+#endif /* TCL_THREADS */
+	    errorCodeSet = 1;
+	    goto cleanup;
+	}
+    }
+
+    if (HAS(rtPtr->methods, METH_FLUSH)) {
+	if (!TransformFlush(rtPtr, &errorCode, FLUSH_WRITE)) {
+#ifdef TCL_THREADS
+	    if (rtPtr->thread != Tcl_GetCurrentThread()) {
+		Tcl_EventuallyFree(rtPtr,
+			(Tcl_FreeProc *) FreeReflectedTransform);
+		return errorCode;
+	    }
+#endif /* TCL_THREADS */
+	    errorCodeSet = 1;
+	    goto cleanup;
+	}
+    }
+
+    /*
+     * Are we in the correct thread?
+     */
+
+#ifdef TCL_THREADS
+    if (rtPtr->thread != Tcl_GetCurrentThread()) {
+	ForwardParam p;
+
+	ForwardOpToOwnerThread(rtPtr, ForwardedClose, &p);
+	result = p.base.code;
+
+	Tcl_EventuallyFree(rtPtr, (Tcl_FreeProc *) FreeReflectedTransform);
+
+	if (result != TCL_OK) {
+	    PassReceivedErrorInterp(interp, &p);
+	    return EINVAL;
+	}
+	return EOK;
+    }
+#endif /* TCL_THREADS */
+
+    /*
+     * Do the actual invokation of "finalize" now; we're in the right thread.
+     */
+
+    result = InvokeTclMethod(rtPtr, "finalize", NULL, NULL, &resObj);
+    if ((result != TCL_OK) && (interp != NULL)) {
+	Tcl_SetChannelErrorInterp(interp, resObj);
+    }
+
+    Tcl_DecrRefCount(resObj);	/* Remove reference we held from the
+				 * invoke. */
+
+  cleanup:
+
+    /*
+     * Remove the transform from the map before releasing the memory, to
+     * prevent future accesses from finding and dereferencing a dangling
+     * pointer.
+     *
+     * NOTE: The transform may not be in the map. This is ok, that happens
+     * when the transform was created in a different interpreter and/or thread
+     * and then was moved here.
+     *
+     * NOTE: The channel may have been removed from the map already via
+     * the per-interp DeleteReflectedTransformMap exit-handler.
+     */
+
+    if (!rtPtr->dead) {
+	rtmPtr = GetReflectedTransformMap(rtPtr->interp);
+	hPtr = Tcl_FindHashEntry(&rtmPtr->map, Tcl_GetString(rtPtr->handle));
+	if (hPtr) {
+	    Tcl_DeleteHashEntry(hPtr);
+	}
+
+	/*
+	 * In a threaded interpreter we manage a per-thread map as well,
+	 * to allow us to survive if the script level pulls the rug out
+	 * under a channel by deleting the owning thread.
+	 */
+
+#ifdef TCL_THREADS
+	rtmPtr = GetThreadReflectedTransformMap();
+	hPtr = Tcl_FindHashEntry(&rtmPtr->map, Tcl_GetString(rtPtr->handle));
+	if (hPtr) {
+	    Tcl_DeleteHashEntry(hPtr);
+	}
+#endif /* TCL_THREADS */
+    }
+
+    Tcl_EventuallyFree (rtPtr, (Tcl_FreeProc *) FreeReflectedTransform);
+    return errorCodeSet ? errorCode : ((result == TCL_OK) ? EOK : EINVAL);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ReflectInput --
+ *
+ *	This function is invoked when more data is requested from the channel.
+ *
+ * Results:
+ *	The number of bytes read.
+ *
+ * Side effects:
+ *	Allocates memory. Arbitrary, as it calls upon a script.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+ReflectInput(
+    ClientData clientData,
+    char *buf,
+    int toRead,
+    int *errorCodePtr)
+{
+    ReflectedTransform *rtPtr = clientData;
+    int gotBytes, copied, readBytes;
+    Tcl_Obj *bufObj;
+
+    /*
+     * The following check can be done before thread redirection, because we
+     * are reading from an item which is readonly, i.e. will never change
+     * during the lifetime of the channel.
+     */
+
+    if (!(rtPtr->methods & FLAG(METH_READ))) {
+	SetChannelErrorStr(rtPtr->chan, msg_read_unsup);
+	*errorCodePtr = EINVAL;
+	return -1;
+    }
+
+    Tcl_Preserve(rtPtr);
+
+    /* TODO: Consider a more appropriate buffer size. */
+    bufObj = Tcl_NewByteArrayObj(NULL, toRead);
+    Tcl_IncrRefCount(bufObj);
+    gotBytes = 0;
+    if (rtPtr->eofPending) {
+	goto stop;
+    }
+    rtPtr->readIsDrained = 0;
+    while (toRead > 0) {
+	/*
+	 * Loop until the request is satisfied (or no data available from
+	 * below, possibly EOF).
+	 */
+
+	copied = ResultCopy(&rtPtr->result, UCHARP(buf), toRead);
+	toRead -= copied;
+	buf += copied;
+	gotBytes += copied;
+
+	if (toRead == 0) {
+	    goto stop;
+	}
+
+	if (rtPtr->eofPending) {
+	    goto stop;
+	}
+
+
+	/*
+	 * The buffer is exhausted, but the caller wants even more. We now
+	 * have to go to the underlying channel, get more bytes and then
+	 * transform them for delivery. We may not get what we want (full EOF
+	 * or temporarily out of data).
+	 *
+	 * Length (rtPtr->result) == 0, toRead > 0 here. Use 'buf'! as target
+	 * to store the intermediary information read from the parent channel.
+	 *
+	 * Ask the transform how much data it allows us to read from the
+	 * underlying channel. This feature allows the transform to signal EOF
+	 * upstream although there is none downstream. Useful to control an
+	 * unbounded 'fcopy' for example, either through counting bytes, or by
+	 * pattern matching.
+	 */
+
+	if ((rtPtr->methods & FLAG(METH_LIMIT))) {
+	    int maxRead = -1;
+
+	    if (!TransformLimit(rtPtr, errorCodePtr, &maxRead)) {
+		goto error;
+	    }
+	    if (maxRead == 0) {
+		goto stop;
+	    } else if (maxRead > 0) {
+		if (maxRead < toRead) {
+		    toRead = maxRead;
+		}
+	    } /* else: 'maxRead < 0' == Accept the current value of toRead */
+	}
+
+	if (toRead <= 0) {
+	    goto stop;
+	}
+
+
+	readBytes = Tcl_ReadRaw(rtPtr->parent,
+		(char *) Tcl_SetByteArrayLength(bufObj, toRead), toRead);
+	if (readBytes < 0) {
+	    if (Tcl_InputBlocked(rtPtr->parent) && (gotBytes > 0)) {
+
+		/*
+		 * Down channel is blocked and offers zero additional bytes.
+		 * The nonzero gotBytes already returned makes the total
+		 * operation a valid short read.  Return to caller.
+		 */
+
+		goto stop;
+	    }
+
+	    /*
+	     * Either the down channel is not blocked (a real error)
+	     * or it is and there are gotBytes==0 byte copied so far.
+	     * In either case, pass up the error, so we either report
+	     * any real error, or do not mistakenly signal EOF by
+	     * returning 0 to the caller.
+	     */
+
+	    *errorCodePtr = Tcl_GetErrno();
+	    goto error;
+	}
+
+	if (readBytes == 0) {
+
+	    /*
+	     * Zero returned from Tcl_ReadRaw() always indicates EOF
+	     * on the down channel.
+	     */
+
+	    rtPtr->eofPending = 1;
+
+		/*
+		 * Now this is a bit different. The partial data waiting is
+		 * converted and returned.
+		 */
+
+		if (HAS(rtPtr->methods, METH_DRAIN)) {
+		    if (!TransformDrain(rtPtr, errorCodePtr)) {
+			goto error;
+		    }
+		}
+
+		if (ResultLength(&rtPtr->result) == 0) {
+		    /*
+		     * The drain delivered nothing.
+		     */
+
+		    goto stop;
+		}
+
+		continue; /* at: while (toRead > 0) */
+	} /* readBytes == 0 */
+
+	/*
+	 * Transform the read chunk, which was not empty. Anything we got back
+	 * is a transformation result is put into our buffers, and the next
+	 * iteration will put it into the result.
+	 */
+
+	Tcl_SetByteArrayLength(bufObj, readBytes);
+	if (!TransformRead(rtPtr, errorCodePtr, bufObj)) {
+	    goto error;
+	}
+	if (Tcl_IsShared(bufObj)) {
+	    Tcl_DecrRefCount(bufObj);
+	    bufObj = Tcl_NewObj();
+	    Tcl_IncrRefCount(bufObj);
+	}
+	Tcl_SetByteArrayLength(bufObj, 0);
+    } /* while toRead > 0 */
+
+ stop:
+    if (gotBytes == 0) {
+	rtPtr->eofPending = 0;
+    }
+    Tcl_DecrRefCount(bufObj);
+    Tcl_Release(rtPtr);
+    return gotBytes;
+
+ error:
+    gotBytes = -1;
+    goto stop;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ReflectOutput --
+ *
+ *	This function is invoked when data is written to the channel.
+ *
+ * Results:
+ *	The number of bytes actually written.
+ *
+ * Side effects:
+ *	Allocates memory. Arbitrary, as it calls upon a script.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+ReflectOutput(
+    ClientData clientData,
+    const char *buf,
+    int toWrite,
+    int *errorCodePtr)
+{
+    ReflectedTransform *rtPtr = clientData;
+
+    /*
+     * The following check can be done before thread redirection, because we
+     * are reading from an item which is readonly, i.e. will never change
+     * during the lifetime of the channel.
+     */
+
+    if (!(rtPtr->methods & FLAG(METH_WRITE))) {
+	SetChannelErrorStr(rtPtr->chan, msg_write_unsup);
+	*errorCodePtr = EINVAL;
+	return -1;
+    }
+
+    if (toWrite == 0) {
+	/*
+	 * Nothing came in to write, ignore the call
+	 */
+
+	return 0;
+    }
+
+    /*
+     * Discard partial data in the input buffers, i.e. on the read side. Like
+     * we do when explicitly seeking as well.
+     */
+
+    Tcl_Preserve(rtPtr);
+
+    if ((rtPtr->methods & FLAG(METH_CLEAR))) {
+	TransformClear(rtPtr);
+    }
+
+    /*
+     * Hand the data to the transformation itself. Anything it deigned to
+     * return to us is a (partial) transformation result and written to the
+     * parent channel for further processing.
+     */
+
+    if (!TransformWrite(rtPtr, errorCodePtr, UCHARP(buf), toWrite)) {
+	Tcl_Release(rtPtr);
+	return -1;
+    }
+
+    *errorCodePtr = EOK;
+    Tcl_Release(rtPtr);
+    return toWrite;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ReflectSeekWide / ReflectSeek --
+ *
+ *	This function is invoked when the user wishes to seek on the channel.
+ *
+ * Results:
+ *	The new location of the access point.
+ *
+ * Side effects:
+ *	Allocates memory. Arbitrary, per the parent channel, and the called
+ *	scripts.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static Tcl_WideInt
+ReflectSeekWide(
+    ClientData clientData,
+    Tcl_WideInt offset,
+    int seekMode,
+    int *errorCodePtr)
+{
+    ReflectedTransform *rtPtr = clientData;
+    Channel *parent = (Channel *) rtPtr->parent;
+    Tcl_WideInt curPos;		/* Position on the device. */
+
+    Tcl_DriverSeekProc *seekProc =
+	    Tcl_ChannelSeekProc(Tcl_GetChannelType(rtPtr->parent));
+
+    /*
+     * Fail if the parent channel is not seekable.
+     */
+
+    if (seekProc == NULL) {
+	Tcl_SetErrno(EINVAL);
+	return Tcl_LongAsWide(-1);
+    }
+
+    /*
+     * Check if we can leave out involving the Tcl level, i.e. transformation
+     * handler. This is true for tell requests, and transformations which
+     * support neither flush, nor drain. For these cases we can pass the
+     * request down and the result back up unchanged.
+     */
+
+    Tcl_Preserve(rtPtr);
+
+    if (((seekMode != SEEK_CUR) || (offset != 0))
+	    && (HAS(rtPtr->methods, METH_CLEAR)
+	    || HAS(rtPtr->methods, METH_FLUSH))) {
+	/*
+	 * Neither a tell request, nor clear/flush both not supported. We have
+	 * to go through the Tcl level to clear and/or flush the
+	 * transformation.
+	 */
+
+	if (rtPtr->methods & FLAG(METH_CLEAR)) {
+	    TransformClear(rtPtr);
+	}
+
+	/*
+	 * When flushing the transform for seeking the generated results are
+	 * irrelevant. We cannot put them into the channel, this would move
+	 * the location, throwing it off with regard to where we are and are
+	 * seeking to.
+	 */
+
+	if (HAS(rtPtr->methods, METH_FLUSH)) {
+	    if (!TransformFlush(rtPtr, errorCodePtr, FLUSH_DISCARD)) {
+		Tcl_Release(rtPtr);
+		return -1;
+	    }
+	}
+    }
+
+    /*
+     * Now seek to the new position in the channel as requested by the
+     * caller. Note that we prefer the wideSeekProc if that is available and
+     * non-NULL...
+     */
+
+    if (HaveVersion(parent->typePtr, TCL_CHANNEL_VERSION_3) &&
+	parent->typePtr->wideSeekProc != NULL) {
+	curPos = parent->typePtr->wideSeekProc(parent->instanceData, offset,
+		seekMode, errorCodePtr);
+    } else if (offset < Tcl_LongAsWide(LONG_MIN) ||
+	    offset > Tcl_LongAsWide(LONG_MAX)) {
+	*errorCodePtr = EOVERFLOW;
+	curPos = Tcl_LongAsWide(-1);
+    } else {
+	curPos = Tcl_LongAsWide(parent->typePtr->seekProc(
+		parent->instanceData, Tcl_WideAsLong(offset), seekMode,
+		errorCodePtr));
+    }
+    if (curPos == Tcl_LongAsWide(-1)) {
+	Tcl_SetErrno(*errorCodePtr);
+    }
+
+    *errorCodePtr = EOK;
+    Tcl_Release(rtPtr);
+    return curPos;
+}
+
+static int
+ReflectSeek(
+    ClientData clientData,
+    long offset,
+    int seekMode,
+    int *errorCodePtr)
+{
+    /*
+     * This function can be invoked from a transformation which is based on
+     * standard seeking, i.e. non-wide. Because of this we have to implement
+     * it, a dummy is not enough. We simply delegate the call to the wide
+     * routine.
+     */
+
+    return (int) ReflectSeekWide(clientData, Tcl_LongAsWide(offset), seekMode,
+	    errorCodePtr);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ReflectWatch --
+ *
+ *	This function is invoked to tell the channel what events the I/O
+ *	system is interested in.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Allocates memory. Arbitrary, as it calls upon a script.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+ReflectWatch(
+    ClientData clientData,
+    int mask)
+{
+    ReflectedTransform *rtPtr = clientData;
+    Tcl_DriverWatchProc *watchProc;
+
+    watchProc = Tcl_ChannelWatchProc(Tcl_GetChannelType(rtPtr->parent));
+    watchProc(Tcl_GetChannelInstanceData(rtPtr->parent), mask);
+
+    /*
+     * Management of the internal timer.
+     */
+
+    if (!(mask & TCL_READABLE) || (ResultLength(&rtPtr->result) == 0)) {
+	/*
+	 * A pending timer may exist, but either is there no (more) interest
+	 * in the events it generates or nothing is available for reading.
+	 * Remove it, if existing.
+	 */
+
+	TimerKill(rtPtr);
+    } else {
+	/*
+	 * There might be no pending timer, but there is interest in readable
+	 * events and we actually have data waiting, so generate a timer to
+	 * flush that if it does not exist.
+	 */
+
+	TimerSetup(rtPtr);
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ReflectBlock --
+ *
+ *	This function is invoked to tell the channel which blocking behaviour
+ *	is required of it.
+ *
+ * Results:
+ *	A posix error number.
+ *
+ * Side effects:
+ *	Allocates memory. Arbitrary, as it calls upon a script.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+ReflectBlock(
+    ClientData clientData,
+    int nonblocking)
+{
+    ReflectedTransform *rtPtr = clientData;
+
+    /*
+     * Transformations simply record the blocking mode in their C level
+     * structure for use by --> ReflectInput. The Tcl level doesn't see this
+     * information or change. As such thread forwarding is not required.
+     */
+
+    rtPtr->nonblocking = nonblocking;
+    return EOK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ReflectSetOption --
+ *
+ *	This function is invoked to configure a channel option.
+ *
+ * Results:
+ *	A standard Tcl result code.
+ *
+ * Side effects:
+ *	Arbitrary, per the parent channel.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+ReflectSetOption(
+    ClientData clientData,	/* Channel to query */
+    Tcl_Interp *interp,		/* Interpreter to leave error messages in */
+    const char *optionName,	/* Name of requested option */
+    const char *newValue)	/* The new value */
+{
+    ReflectedTransform *rtPtr = clientData;
+
+    /*
+     * Transformations have no options. Thus the call is passed down unchanged
+     * to the parent channel for processing. Its results are passed back
+     * unchanged as well. This all happens in the thread we are in. As the Tcl
+     * level is not involved there is no need for thread forwarding.
+     */
+
+    Tcl_DriverSetOptionProc *setOptionProc =
+	    Tcl_ChannelSetOptionProc(Tcl_GetChannelType(rtPtr->parent));
+
+    if (setOptionProc == NULL) {
+	return TCL_ERROR;
+    }
+    return setOptionProc(Tcl_GetChannelInstanceData(rtPtr->parent), interp,
+	    optionName, newValue);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ReflectGetOption --
+ *
+ *	This function is invoked to retrieve all or a channel options.
+ *
+ * Results:
+ *	A standard Tcl result code.
+ *
+ * Side effects:
+ *	Arbitrary, per the parent channel.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+ReflectGetOption(
+    ClientData clientData,	/* Channel to query */
+    Tcl_Interp *interp,		/* Interpreter to leave error messages in */
+    const char *optionName,	/* Name of reuqested option */
+    Tcl_DString *dsPtr)		/* String to place the result into */
+{
+    ReflectedTransform *rtPtr = clientData;
+
+    /*
+     * Transformations have no options. Thus the call is passed down unchanged
+     * to the parent channel for processing. Its results are passed back
+     * unchanged as well. This all happens in the thread we are in. As the Tcl
+     * level is not involved there is no need for thread forwarding.
+     *
+     * Note that the parent not having a driver for option retrieval is not an
+     * immediate error. A query for all options is ok. Only a request for a
+     * specific option has to fail.
+     */
+
+    Tcl_DriverGetOptionProc *getOptionProc =
+	    Tcl_ChannelGetOptionProc(Tcl_GetChannelType(rtPtr->parent));
+
+    if (getOptionProc != NULL) {
+	return getOptionProc(Tcl_GetChannelInstanceData(rtPtr->parent),
+		interp, optionName, dsPtr);
+    } else if (optionName == NULL) {
+	return TCL_OK;
+    } else {
+	return TCL_ERROR;
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ReflectHandle --
+ *
+ *	This function is invoked to retrieve the associated file handle.
+ *
+ * Results:
+ *	A standard Tcl result code.
+ *
+ * Side effects:
+ *	Arbitrary, per the parent channel.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+ReflectHandle(
+    ClientData clientData,
+    int direction,
+    ClientData *handlePtr)
+{
+    ReflectedTransform *rtPtr = clientData;
+
+    /*
+     * Transformations have no handle of their own. As such we simply query
+     * the parent channel for it. This way the qery will ripple down through
+     * all transformations until reaches the base channel. Which then returns
+     * its handle, or fails. The former will then ripple up the stack.
+     *
+     * This all happens in the thread we are in. As the Tcl level is not
+     * involved no forwarding is required.
+     */
+
+    return Tcl_GetChannelHandle(rtPtr->parent, direction, handlePtr);
+}
+/*
+ *----------------------------------------------------------------------
+ *
+ * ReflectNotify --
+ *
+ *	This function is invoked to reported incoming events.
+ *
+ * Results:
+ *	A standard Tcl result code.
+ *
+ * Side effects:
+ *	Arbitrary, per the parent channel.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+ReflectNotify(
+    ClientData clientData,
+    int mask)
+{
+    ReflectedTransform *rtPtr = clientData;
+
+    /*
+     * An event occured in the underlying channel.
+     *
+     * We delete our timer. It was not fired, yet we are here, so the channel
+     * below generated such an event and we don't have to. The renewal of the
+     * interest after the execution of channel handlers will eventually cause
+     * us to recreate the timer (in ReflectWatch).
+     */
+
+    TimerKill(rtPtr);
+
+    /*
+     * Pass to higher layers.
+     */
+
+    return mask;
+}
+
+/*
+ * Helpers. =========================================================
+ */
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * DecodeEventMask --
+ *
+ *	This function takes an internal bitmask of events and constructs the
+ *	equivalent list of event items.
+ *
+ * Results:
+ *	A Tcl_Obj reference. The object will have a refCount of one. The user
+ *	has to decrement it to release the object.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ * DUPLICATE of 'DecodeEventMask' in tclIORChan.c
+ */
+
+static Tcl_Obj *
+DecodeEventMask(
+    int mask)
+{
+    register const char *eventStr;
+    Tcl_Obj *evObj;
+
+    switch (mask & RANDW) {
+    case RANDW:
+	eventStr = "read write";
+	break;
+    case TCL_READABLE:
+	eventStr = "read";
+	break;
+    case TCL_WRITABLE:
+	eventStr = "write";
+	break;
+    default:
+	eventStr = "";
+	break;
+    }
+
+    evObj = Tcl_NewStringObj(eventStr, -1);
+    Tcl_IncrRefCount(evObj);
+    return evObj;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * NewReflectedTransform --
+ *
+ *	This function is invoked to allocate and initialize the instance data
+ *	of a new reflected channel.
+ *
+ * Results:
+ *	A heap-allocated channel instance.
+ *
+ * Side effects:
+ *	Allocates memory.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static ReflectedTransform *
+NewReflectedTransform(
+    Tcl_Interp *interp,
+    Tcl_Obj *cmdpfxObj,
+    int mode,
+    Tcl_Obj *handleObj,
+    Tcl_Channel parentChan)
+{
+    ReflectedTransform *rtPtr;
+    int listc;
+    Tcl_Obj **listv;
+    int i;
+
+    rtPtr = ckalloc(sizeof(ReflectedTransform));
+
+    /* rtPtr->chan: Assigned by caller. Dummy data here. */
+    /* rtPtr->methods: Assigned by caller. Dummy data here. */
+
+    rtPtr->chan = NULL;
+    rtPtr->methods = 0;
+#ifdef TCL_THREADS
+    rtPtr->thread = Tcl_GetCurrentThread();
+#endif
+    rtPtr->parent = parentChan;
+    rtPtr->interp = interp;
+    rtPtr->handle = handleObj;
+    Tcl_IncrRefCount(handleObj);
+    rtPtr->timer = NULL;
+    rtPtr->mode = 0;
+    rtPtr->readIsDrained = 0;
+    rtPtr->eofPending = 0;
+    rtPtr->nonblocking =
+	    (((Channel *) parentChan)->state->flags & CHANNEL_NONBLOCKING);
+    rtPtr->dead = 0;
+
+    /*
+     * Query parent for current blocking mode.
+     */
+
+    ResultInit(&rtPtr->result);
+
+    /*
+     * Method placeholder.
+     */
+
+    /* ASSERT: cmdpfxObj is a Tcl List */
+
+    Tcl_ListObjGetElements(interp, cmdpfxObj, &listc, &listv);
+
+    /*
+     * See [==] as well.
+     * Storage for the command prefix and the additional words required for
+     * the invocation of methods in the command handler.
+     *
+     * listv [0] [listc-1] | [listc]  [listc+1] |
+     * argv  [0]   ... [.] | [argc-2] [argc-1]  | [argc]  [argc+2]
+     *       cmd   ... pfx | method   chan      | detail1 detail2
+     */
+
+    rtPtr->argc = listc + 2;
+    rtPtr->argv = ckalloc(sizeof(Tcl_Obj *) * (listc+4));
+
+    /*
+     * Duplicate object references.
+     */
+
+    for (i=0; i<listc ; i++) {
+	Tcl_Obj *word = rtPtr->argv[i] = listv[i];
+
+	Tcl_IncrRefCount(word);
+    }
+
+    i++;				/* Skip placeholder for method */
+
+    /*
+     * See [x] in FreeReflectedTransform for release
+     */
+    rtPtr->argv[i] = handleObj;
+    Tcl_IncrRefCount(handleObj);
+
+    /*
+     * The next two objects are kept empty, varying arguments.
+     */
+
+    /*
+     * Initialization complete.
+     */
+
+    return rtPtr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * NextHandle --
+ *
+ *	This function is invoked to generate a channel handle for a new
+ *	reflected channel.
+ *
+ * Results:
+ *	A Tcl_Obj containing the string of the new channel handle. The
+ *	refcount of the returned object is -- zero --.
+ *
+ * Side effects:
+ *	May allocate memory. Mutex protected critical section locks out other
+ *	threads for a short time.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static Tcl_Obj *
+NextHandle(void)
+{
+    /*
+     * Count number of generated reflected channels. Used for id generation.
+     * Ids are never reclaimed and there is no dealing with wrap around. On
+     * the other hand, "unsigned long" should be big enough except for
+     * absolute longrunners (generate a 100 ids per second => overflow will
+     * occur in 1 1/3 years).
+     */
+
+    TCL_DECLARE_MUTEX(rtCounterMutex)
+    static unsigned long rtCounter = 0;
+    Tcl_Obj *resObj;
+
+    Tcl_MutexLock(&rtCounterMutex);
+    resObj = Tcl_ObjPrintf("rt%lu", rtCounter);
+    rtCounter++;
+    Tcl_MutexUnlock(&rtCounterMutex);
+
+    return resObj;
+}
+
+static void
+FreeReflectedTransformArgs(
+    ReflectedTransform *rtPtr)
+{
+    int i, n = rtPtr->argc - 2;
+
+    if (n < 0) {
+	return;
+    }
+
+    Tcl_DecrRefCount(rtPtr->handle);
+    rtPtr->handle = NULL;
+
+    for (i=0; i<n; i++) {
+	Tcl_DecrRefCount(rtPtr->argv[i]);
+    }
+
+    /*
+     * See [x] in NewReflectedTransform for lock
+     * n+1 = argc-1.
+     */
+    Tcl_DecrRefCount(rtPtr->argv[n+1]);
+
+    rtPtr->argc = 1;
+}
+
+static void
+FreeReflectedTransform(
+    ReflectedTransform *rtPtr)
+{
+    TimerKill(rtPtr);
+    ResultClear(&rtPtr->result);
+
+    FreeReflectedTransformArgs(rtPtr);
+
+    ckfree(rtPtr->argv);
+    ckfree(rtPtr);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * InvokeTclMethod --
+ *
+ *	This function is used to invoke the Tcl level of a reflected channel.
+ *	It handles all the command assembly, invokation, and generic state and
+ *	result mgmt. It does *not* handle thread redirection; that is the
+ *	responsibility of clients of this function.
+ *
+ * Results:
+ *	Result code and data as returned by the method.
+ *
+ * Side effects:
+ *	Arbitrary, as it calls upon a Tcl script.
+ *
+ * Contract:
+ *	argOneObj.refCount >= 1 on entry and exit, if argOneObj != NULL
+ *	argTwoObj.refCount >= 1 on entry and exit, if argTwoObj != NULL
+ *	resObj.refCount in {0, 1, ...}
+ *
+ *----------------------------------------------------------------------
+ * Semi-DUPLICATE of 'InvokeTclMethod' in tclIORChan.c
+ * - Semi because different structures are used.
+ * - Still possible to factor out the commonalities into a separate structure.
+ */
+
+static int
+InvokeTclMethod(
+    ReflectedTransform *rtPtr,
+    const char *method,
+    Tcl_Obj *argOneObj,		/* NULL'able */
+    Tcl_Obj *argTwoObj,		/* NULL'able */
+    Tcl_Obj **resultObjPtr)	/* NULL'able */
+{
+    int cmdc;			/* #words in constructed command */
+    Tcl_Obj *methObj = NULL;	/* Method name in object form */
+    Tcl_InterpState sr;		/* State of handler interp */
+    int result;			/* Result code of method invokation */
+    Tcl_Obj *resObj = NULL;	/* Result of method invokation. */
+
+    if (rtPtr->dead) {
+	/*
+	 * The transform is marked as dead. Bail out immediately, with an
+	 * appropriate error.
+	 */
+
+	if (resultObjPtr != NULL) {
+	    resObj = Tcl_NewStringObj(msg_dstlost,-1);
+	    *resultObjPtr = resObj;
+	    Tcl_IncrRefCount(resObj);
+	}
+	return TCL_ERROR;
+    }
+
+    /*
+     * NOTE (5): Decide impl. issue: Cache objects with method names?
+     * Requires TSD data as reflections can be created in many different
+     * threads.
+     * NO: Caching of command resolutions means storage per channel.
+     */
+
+    /*
+     * Insert method into the pre-allocated area, after the command prefix,
+     * before the channel id.
+     */
+
+    methObj = Tcl_NewStringObj(method, -1);
+    Tcl_IncrRefCount(methObj);
+    rtPtr->argv[rtPtr->argc - 2] = methObj;
+
+    /*
+     * Append the additional argument containing method specific details
+     * behind the channel id. If specified.
+     *
+     * Because of the contract there is no need to increment the refcounts.
+     * The objects will survive the Tcl_EvalObjv without change.
+     */
+
+    cmdc = rtPtr->argc;
+    if (argOneObj) {
+	rtPtr->argv[cmdc] = argOneObj;
+	cmdc++;
+	if (argTwoObj) {
+	    rtPtr->argv[cmdc] = argTwoObj;
+	    cmdc++;
+	}
+    }
+
+    /*
+     * And run the handler... This is done in auch a manner which leaves any
+     * existing state intact.
+     */
+
+    sr = Tcl_SaveInterpState(rtPtr->interp, 0 /* Dummy */);
+    Tcl_Preserve(rtPtr);
+    Tcl_Preserve(rtPtr->interp);
+    result = Tcl_EvalObjv(rtPtr->interp, cmdc, rtPtr->argv, TCL_EVAL_GLOBAL);
+
+    /*
+     * We do not try to extract the result information if the caller has no
+     * interest in it. I.e. there is no need to put effort into creating
+     * something which is discarded immediately after.
+     */
+
+    if (resultObjPtr) {
+	if (result == TCL_OK) {
+	    /*
+	     * Ok result taken as is, also if the caller requests that there
+	     * is no capture.
+	     */
+
+	    resObj = Tcl_GetObjResult(rtPtr->interp);
+	} else {
+	    /*
+	     * Non-ok result is always treated as an error. We have to capture
+	     * the full state of the result, including additional options.
+	     *
+	     * This is complex and ugly, and would be completely unnecessary
+	     * if we only added support for a TCL_FORBID_EXCEPTIONS flag.
+	     */
+	    if (result != TCL_ERROR) {
+		Tcl_Obj *cmd = Tcl_NewListObj(cmdc, rtPtr->argv);
+		int cmdLen;
+		const char *cmdString = Tcl_GetStringFromObj(cmd, &cmdLen);
+
+		Tcl_IncrRefCount(cmd);
+		Tcl_ResetResult(rtPtr->interp);
+		Tcl_SetObjResult(rtPtr->interp, Tcl_ObjPrintf(
+			"chan handler returned bad code: %d", result));
+		Tcl_LogCommandInfo(rtPtr->interp, cmdString, cmdString, cmdLen);
+		Tcl_DecrRefCount(cmd);
+		result = TCL_ERROR;
+	    }
+	    Tcl_AppendObjToErrorInfo(rtPtr->interp, Tcl_ObjPrintf(
+		    "\n    (chan handler subcommand \"%s\")", method));
+	    resObj = MarshallError(rtPtr->interp);
+	}
+	Tcl_IncrRefCount(resObj);
+    }
+    Tcl_RestoreInterpState(rtPtr->interp, sr);
+    Tcl_Release(rtPtr->interp);
+    Tcl_Release(rtPtr);
+
+    /*
+     * Cleanup of the dynamic parts of the command.
+     *
+     * The detail objects survived the Tcl_EvalObjv without change because of
+     * the contract. Therefore there is no need to decrement the refcounts. Only
+     * the internal method object has to be disposed of.
+     */
+
+    Tcl_DecrRefCount(methObj);
+
+    /*
+     * The resObj has a ref count of 1 at this location. This means that the
+     * caller of InvokeTclMethod has to dispose of it (but only if it was
+     * returned to it).
+     */
+
+    if (resultObjPtr != NULL) {
+	*resultObjPtr = resObj;
+    }
+
+    /*
+     * There no need to handle the case where nothing is returned, because for
+     * that case resObj was not set anyway.
+     */
+
+    return result;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * GetReflectedTransformMap --
+ *
+ *	Gets and potentially initializes the reflected channel map for an
+ *	interpreter.
+ *
+ * Results:
+ *	A pointer to the map created, for use by the caller.
+ *
+ * Side effects:
+ *	Initializes the reflected channel map for an interpreter.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static ReflectedTransformMap *
+GetReflectedTransformMap(
+    Tcl_Interp *interp)
+{
+    ReflectedTransformMap *rtmPtr = Tcl_GetAssocData(interp, RTMKEY, NULL);
+
+    if (rtmPtr == NULL) {
+	rtmPtr = ckalloc(sizeof(ReflectedTransformMap));
+	Tcl_InitHashTable(&rtmPtr->map, TCL_STRING_KEYS);
+	Tcl_SetAssocData(interp, RTMKEY,
+		(Tcl_InterpDeleteProc *) DeleteReflectedTransformMap, rtmPtr);
+    }
+    return rtmPtr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * DeleteReflectedTransformMap --
+ *
+ *	Deletes the channel table for an interpreter, closing any open
+ *	channels whose refcount reaches zero. This procedure is invoked when
+ *	an interpreter is deleted, via the AssocData cleanup mechanism.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Deletes the hash table of channels. May close channels. May flush
+ *	output on closed channels. Removes any channeEvent handlers that were
+ *	registered in this interpreter.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+DeleteReflectedTransformMap(
+    ClientData clientData,	/* The per-interpreter data structure. */
+    Tcl_Interp *interp)		/* The interpreter being deleted. */
+{
+    ReflectedTransformMap *rtmPtr; /* The map */
+    Tcl_HashSearch hSearch;	 /* Search variable. */
+    Tcl_HashEntry *hPtr;	 /* Search variable. */
+    ReflectedTransform *rtPtr;
+#ifdef TCL_THREADS
+    ForwardingResult *resultPtr;
+    ForwardingEvent *evPtr;
+    ForwardParam *paramPtr;
+#endif /* TCL_THREADS */
+
+    /*
+     * Delete all entries. The channels may have been closed already, or will
+     * be closed later, by the standard IO finalization of an interpreter
+     * under destruction. Except for the channels which were moved to a
+     * different interpreter and/or thread. They do not exist from the IO
+     * systems point of view and will not get closed. Therefore mark all as
+     * dead so that any future access will cause a proper error. For channels
+     * in a different thread we actually do the same as
+     * DeleteThreadReflectedTransformMap(), just restricted to the channels of
+     * this interp.
+     */
+
+    rtmPtr = clientData;
+    for (hPtr = Tcl_FirstHashEntry(&rtmPtr->map, &hSearch);
+	    hPtr != NULL;
+	    hPtr = Tcl_FirstHashEntry(&rtmPtr->map, &hSearch)) {
+	rtPtr = Tcl_GetHashValue(hPtr);
+
+	rtPtr->dead = 1;
+	Tcl_DeleteHashEntry(hPtr);
+    }
+    Tcl_DeleteHashTable(&rtmPtr->map);
+    ckfree(&rtmPtr->map);
+
+#ifdef TCL_THREADS
+    /*
+     * The origin interpreter for one or more reflected channels is gone.
+     */
+
+    /*
+     * Get the map of all channels handled by the current thread. This is a
+     * ReflectedTransformMap, but on a per-thread basis, not per-interp. Go
+     * through the channels and remove all which were handled by this
+     * interpreter. They have already been marked as dead.
+     */
+
+    rtmPtr = GetThreadReflectedTransformMap();
+    for (hPtr = Tcl_FirstHashEntry(&rtmPtr->map, &hSearch);
+	    hPtr != NULL;
+	    hPtr = Tcl_NextHashEntry(&hSearch)) {
+	rtPtr = Tcl_GetHashValue(hPtr);
+
+	if (rtPtr->interp != interp) {
+	    /*
+	     * Ignore entries for other interpreters.
+	     */
+
+	    continue;
+	}
+
+	rtPtr->dead = 1;
+	FreeReflectedTransformArgs(rtPtr);
+	Tcl_DeleteHashEntry(hPtr);
+    }
+
+    /*
+     * Go through the list of pending results and cancel all whose events were
+     * destined for this interpreter. While this is in progress we block any
+     * other access to the list of pending results.
+     */
+
+    Tcl_MutexLock(&rtForwardMutex);
+
+    for (resultPtr = forwardList; resultPtr != NULL;
+	    resultPtr = resultPtr->nextPtr) {
+	if (resultPtr->dsti != interp) {
+	    /*
+	     * Ignore results/events for other interpreters.
+	     */
+
+	    continue;
+	}
+
+	/*
+	 * The receiver for the event exited, before processing the event. We
+	 * detach the result now, wake the originator up and signal failure.
+	 */
+
+	evPtr = resultPtr->evPtr;
+	if (evPtr == NULL) {
+	    continue;
+	}
+	paramPtr = evPtr->param;
+
+	evPtr->resultPtr = NULL;
+	resultPtr->evPtr = NULL;
+	resultPtr->result = TCL_ERROR;
+
+	ForwardSetStaticError(paramPtr, msg_send_dstlost);
+
+	Tcl_ConditionNotify(&resultPtr->done);
+    }
+    Tcl_MutexUnlock(&rtForwardMutex);
+#endif /* TCL_THREADS */
+}
+
+#ifdef TCL_THREADS
+/*
+ *----------------------------------------------------------------------
+ *
+ * GetThreadReflectedTransformMap --
+ *
+ *	Gets and potentially initializes the reflected channel map for a
+ *	thread.
+ *
+ * Results:
+ *	A pointer to the map created, for use by the caller.
+ *
+ * Side effects:
+ *	Initializes the reflected channel map for a thread.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static ReflectedTransformMap *
+GetThreadReflectedTransformMap(void)
+{
+    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+
+    if (!tsdPtr->rtmPtr) {
+	tsdPtr->rtmPtr = ckalloc(sizeof(ReflectedTransformMap));
+	Tcl_InitHashTable(&tsdPtr->rtmPtr->map, TCL_STRING_KEYS);
+	Tcl_CreateThreadExitHandler(DeleteThreadReflectedTransformMap, NULL);
+    }
+
+    return tsdPtr->rtmPtr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * DeleteThreadReflectedTransformMap --
+ *
+ *	Deletes the channel table for a thread. This procedure is invoked when
+ *	a thread is deleted. The channels have already been marked as dead, in
+ *	DeleteReflectedTransformMap().
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Deletes the hash table of channels.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+DeleteThreadReflectedTransformMap(
+    ClientData clientData)	/* The per-thread data structure. */
+{
+    Tcl_HashSearch hSearch;	 /* Search variable. */
+    Tcl_HashEntry *hPtr;	 /* Search variable. */
+    Tcl_ThreadId self = Tcl_GetCurrentThread();
+    ReflectedTransformMap *rtmPtr; /* The map */
+    ForwardingResult *resultPtr;
+
+    /*
+     * The origin thread for one or more reflected channels is gone.
+     * NOTE: If this function is called due to a thread getting killed the
+     *       per-interp DeleteReflectedTransformMap is apparently not called.
+     */
+
+    /*
+     * Get the map of all channels handled by the current thread. This is a
+     * ReflectedTransformMap, but on a per-thread basis, not per-interp. Go
+     * through the channels, remove all, mark them as dead.
+     */
+
+    rtmPtr = GetThreadReflectedTransformMap();
+    for (hPtr = Tcl_FirstHashEntry(&rtmPtr->map, &hSearch);
+	    hPtr != NULL;
+	    hPtr = Tcl_FirstHashEntry(&rtmPtr->map, &hSearch)) {
+	ReflectedTransform *rtPtr = Tcl_GetHashValue(hPtr);
+
+	rtPtr->dead = 1;
+	FreeReflectedTransformArgs(rtPtr);
+	Tcl_DeleteHashEntry(hPtr);
+    }
+    ckfree(rtmPtr);
+
+    /*
+     * Go through the list of pending results and cancel all whose events were
+     * destined for this thread. While this is in progress we block any
+     * other access to the list of pending results.
+     */
+
+    Tcl_MutexLock(&rtForwardMutex);
+
+    for (resultPtr = forwardList; resultPtr != NULL;
+	    resultPtr = resultPtr->nextPtr) {
+	ForwardingEvent *evPtr;
+	ForwardParam *paramPtr;
+
+	if (resultPtr->dst != self) {
+	    /*
+	     * Ignore results/events for other threads.
+	     */
+
+	    continue;
+	}
+
+	/*
+	 * The receiver for the event exited, before processing the event. We
+	 * detach the result now, wake the originator up and signal failure.
+	 */
+
+	evPtr = resultPtr->evPtr;
+	if (evPtr == NULL) {
+	    continue;
+	}
+	paramPtr = evPtr->param;
+
+	evPtr->resultPtr = NULL;
+	resultPtr->evPtr = NULL;
+	resultPtr->result = TCL_ERROR;
+
+	ForwardSetStaticError(paramPtr, msg_send_dstlost);
+
+	Tcl_ConditionNotify(&resultPtr->done);
+    }
+    Tcl_MutexUnlock(&rtForwardMutex);
+}
+
+static void
+ForwardOpToOwnerThread(
+    ReflectedTransform *rtPtr,	/* Channel instance */
+    ForwardedOperation op,	/* Forwarded driver operation */
+    const void *param)		/* Arguments */
+{
+    Tcl_ThreadId dst = rtPtr->thread;
+    ForwardingEvent *evPtr;
+    ForwardingResult *resultPtr;
+
+    /*
+     * We gather the lock early. This allows us to check the liveness of the
+     * channel without interference from DeleteThreadReflectedTransformMap().
+     */
+
+    Tcl_MutexLock(&rtForwardMutex);
+
+    if (rtPtr->dead) {
+	/*
+	 * The channel is marked as dead. Bail out immediately, with an
+	 * appropriate error. Do not forget to unlock the mutex on this path.
+	 */
+
+	ForwardSetStaticError((ForwardParam *) param, msg_send_dstlost);
+	Tcl_MutexUnlock(&rtForwardMutex);
+	return;
+    }
+
+    /*
+     * Create and initialize the event and data structures.
+     */
+
+    evPtr = ckalloc(sizeof(ForwardingEvent));
+    resultPtr = ckalloc(sizeof(ForwardingResult));
+
+    evPtr->event.proc = ForwardProc;
+    evPtr->resultPtr = resultPtr;
+    evPtr->op = op;
+    evPtr->rtPtr = rtPtr;
+    evPtr->param = (ForwardParam *) param;
+
+    resultPtr->src = Tcl_GetCurrentThread();
+    resultPtr->dst = dst;
+    resultPtr->dsti = rtPtr->interp;
+    resultPtr->done = NULL;
+    resultPtr->result = -1;
+    resultPtr->evPtr = evPtr;
+
+    /*
+     * Now execute the forward.
+     */
+
+    TclSpliceIn(resultPtr, forwardList);
+    /* Do not unlock here. That is done by the ConditionWait */
+
+    /*
+     * Ensure cleanup of the event if the origin thread exits while this event
+     * is pending or in progress. Exit of the destination thread is handled by
+     * DeleteThreadReflectionChannelMap(), this is set up by
+     * GetThreadReflectedTransformMap(). This is what we use the 'forwardList'
+     * (see above) for.
+     */
+
+    Tcl_CreateThreadExitHandler(SrcExitProc, evPtr);
+
+    /*
+     * Queue the event and poke the other thread's notifier.
+     */
+
+    Tcl_ThreadQueueEvent(dst, (Tcl_Event *) evPtr, TCL_QUEUE_TAIL);
+    Tcl_ThreadAlert(dst);
+
+    /*
+     * (*) Block until the other thread has either processed the transfer or
+     * rejected it.
+     */
+
+    while (resultPtr->result < 0) {
+	/*
+	 * NOTE (1): Is it possible that the current thread goes away while
+	 * waiting here? IOW Is it possible that "SrcExitProc" is called
+	 * while we are here? See complementary note (2) in "SrcExitProc"
+	 *
+	 * The ConditionWait unlocks the mutex during the wait and relocks it
+	 * immediately after.
+	 */
+
+	Tcl_ConditionWait(&resultPtr->done, &rtForwardMutex, NULL);
+    }
+
+    /*
+     * Unlink result from the forwarder list. No need to lock. Either still
+     * locked, or locked by the ConditionWait
+     */
+
+    TclSpliceOut(resultPtr, forwardList);
+
+    resultPtr->nextPtr = NULL;
+    resultPtr->prevPtr = NULL;
+
+    Tcl_MutexUnlock(&rtForwardMutex);
+    Tcl_ConditionFinalize(&resultPtr->done);
+
+    /*
+     * Kill the cleanup handler now, and the result structure as well, before
+     * returning the success code.
+     *
+     * Note: The event structure has already been deleted by the destination
+     * notifier, after it serviced the event.
+     */
+
+    Tcl_DeleteThreadExitHandler(SrcExitProc, evPtr);
+
+    ckfree(resultPtr);
+}
+
+static int
+ForwardProc(
+    Tcl_Event *evGPtr,
+    int mask)
+{
+    /*
+     * Notes regarding access to the referenced data.
+     *
+     * In principle the data belongs to the originating thread (see
+     * evPtr->src), however this thread is currently blocked at (*), i.e.
+     * quiescent. Because of this we can treat the data as belonging to us,
+     * without fear of race conditions. I.e. we can read and write as we like.
+     *
+     * The only thing we cannot be sure of is the resultPtr. This can be be
+     * NULLed if the originating thread went away while the event is handled
+     * here now.
+     */
+
+    ForwardingEvent *evPtr = (ForwardingEvent *) evGPtr;
+    ForwardingResult *resultPtr = evPtr->resultPtr;
+    ReflectedTransform *rtPtr = evPtr->rtPtr;
+    Tcl_Interp *interp = rtPtr->interp;
+    ForwardParam *paramPtr = evPtr->param;
+    Tcl_Obj *resObj = NULL;	/* Interp result of InvokeTclMethod */
+    ReflectedTransformMap *rtmPtr;
+				/* Map of reflected channels with handlers in
+				 * this interp. */
+    Tcl_HashEntry *hPtr;	/* Entry in the above map */
+
+    /*
+     * Ignore the event if no one is waiting for its result anymore.
+     */
+
+    if (!resultPtr) {
+	return 1;
+    }
+
+    paramPtr->base.code = TCL_OK;
+    paramPtr->base.msgStr = NULL;
+    paramPtr->base.mustFree = 0;
+
+    switch (evPtr->op) {
+	/*
+	 * The destination thread for the following operations is
+	 * rtPtr->thread, which contains rtPtr->interp, the interp we have to
+	 * call upon for the driver.
+	 */
+
+    case ForwardedClose:
+	/*
+	 * No parameters/results.
+	 */
+
+	if (InvokeTclMethod(rtPtr, "finalize", NULL, NULL,
+		&resObj) != TCL_OK) {
+	    ForwardSetObjError(paramPtr, resObj);
+	}
+
+	/*
+	 * Freeing is done here, in the origin thread, because the argv[]
+	 * objects belong to this thread. Deallocating them in a different
+	 * thread is not allowed
+	 */
+
+	/*
+	 * Remove the channel from the map before releasing the memory, to
+	 * prevent future accesses (like by 'postevent') from finding and
+	 * dereferencing a dangling pointer.
+	 */
+
+	rtmPtr = GetReflectedTransformMap(interp);
+	hPtr = Tcl_FindHashEntry(&rtmPtr->map, Tcl_GetString(rtPtr->handle));
+	Tcl_DeleteHashEntry(hPtr);
+
+	/*
+	 * In a threaded interpreter we manage a per-thread map as well, to
+	 * allow us to survive if the script level pulls the rug out under a
+	 * channel by deleting the owning thread.
+	 */
+
+	rtmPtr = GetThreadReflectedTransformMap();
+	hPtr = Tcl_FindHashEntry(&rtmPtr->map, Tcl_GetString(rtPtr->handle));
+	Tcl_DeleteHashEntry(hPtr);
+
+	FreeReflectedTransformArgs(rtPtr);
+	break;
+
+    case ForwardedInput: {
+	Tcl_Obj *bufObj = Tcl_NewByteArrayObj((unsigned char *)
+		paramPtr->transform.buf, paramPtr->transform.size);
+	Tcl_IncrRefCount(bufObj);
+
+	if (InvokeTclMethod(rtPtr, "read", bufObj, NULL, &resObj) != TCL_OK) {
+	    ForwardSetObjError(paramPtr, resObj);
+	    paramPtr->transform.size = -1;
+	} else {
+	    /*
+	     * Process a regular return. Contains the transformation result.
+	     * Sent it back to the request originator.
+	     */
+
+	    int bytec;		/* Number of returned bytes */
+	    unsigned char *bytev;
+				/* Array of returned bytes */
+
+	    bytev = Tcl_GetByteArrayFromObj(resObj, &bytec);
+
+	    paramPtr->transform.size = bytec;
+
+	    if (bytec > 0) {
+		paramPtr->transform.buf = ckalloc(bytec);
+		memcpy(paramPtr->transform.buf, bytev, (size_t)bytec);
+	    } else {
+		paramPtr->transform.buf = NULL;
+	    }
+	}
+
+	Tcl_DecrRefCount(bufObj);
+	break;
+    }
+
+    case ForwardedOutput: {
+	Tcl_Obj *bufObj = Tcl_NewByteArrayObj((unsigned char *)
+		paramPtr->transform.buf, paramPtr->transform.size);
+	Tcl_IncrRefCount(bufObj);
+
+	if (InvokeTclMethod(rtPtr, "write", bufObj, NULL, &resObj) != TCL_OK) {
+	    ForwardSetObjError(paramPtr, resObj);
+	    paramPtr->transform.size = -1;
+	} else {
+	    /*
+	     * Process a regular return. Contains the transformation result.
+	     * Sent it back to the request originator.
+	     */
+
+	    int bytec;		/* Number of returned bytes */
+	    unsigned char *bytev;
+				/* Array of returned bytes */
+
+	    bytev = Tcl_GetByteArrayFromObj(resObj, &bytec);
+
+	    paramPtr->transform.size = bytec;
+
+	    if (bytec > 0) {
+		paramPtr->transform.buf = ckalloc(bytec);
+		memcpy(paramPtr->transform.buf, bytev, (size_t)bytec);
+	    } else {
+		paramPtr->transform.buf = NULL;
+	    }
+	}
+
+	Tcl_DecrRefCount(bufObj);
+	break;
+    }
+
+    case ForwardedDrain:
+	if (InvokeTclMethod(rtPtr, "drain", NULL, NULL, &resObj) != TCL_OK) {
+	    ForwardSetObjError(paramPtr, resObj);
+	    paramPtr->transform.size = -1;
+	} else {
+	    /*
+	     * Process a regular return. Contains the transformation result.
+	     * Sent it back to the request originator.
+	     */
+
+	    int bytec;		/* Number of returned bytes */
+	    unsigned char *bytev; /* Array of returned bytes */
+
+	    bytev = Tcl_GetByteArrayFromObj(resObj, &bytec);
+
+	    paramPtr->transform.size = bytec;
+
+	    if (bytec > 0) {
+		paramPtr->transform.buf = ckalloc(bytec);
+		memcpy(paramPtr->transform.buf, bytev, (size_t)bytec);
+	    } else {
+		paramPtr->transform.buf = NULL;
+	    }
+	}
+	break;
+
+    case ForwardedFlush:
+	if (InvokeTclMethod(rtPtr, "flush", NULL, NULL, &resObj) != TCL_OK) {
+	    ForwardSetObjError(paramPtr, resObj);
+	    paramPtr->transform.size = -1;
+	} else {
+	    /*
+	     * Process a regular return. Contains the transformation result.
+	     * Sent it back to the request originator.
+	     */
+
+	    int bytec;		/* Number of returned bytes */
+	    unsigned char *bytev;
+				/* Array of returned bytes */
+
+	    bytev = Tcl_GetByteArrayFromObj(resObj, &bytec);
+
+	    paramPtr->transform.size = bytec;
+
+	    if (bytec > 0) {
+		paramPtr->transform.buf = ckalloc(bytec);
+		memcpy(paramPtr->transform.buf, bytev, (size_t)bytec);
+	    } else {
+		paramPtr->transform.buf = NULL;
+	    }
+	}
+	break;
+
+    case ForwardedClear:
+	(void) InvokeTclMethod(rtPtr, "clear", NULL, NULL, NULL);
+	break;
+
+    case ForwardedLimit:
+	if (InvokeTclMethod(rtPtr, "limit?", NULL, NULL, &resObj) != TCL_OK) {
+	    ForwardSetObjError(paramPtr, resObj);
+	    paramPtr->limit.max = -1;
+	} else if (Tcl_GetIntFromObj(interp, resObj,
+		&paramPtr->limit.max) != TCL_OK) {
+	    ForwardSetObjError(paramPtr, MarshallError(interp));
+	    paramPtr->limit.max = -1;
+	}
+	break;
+
+    default:
+	/*
+	 * Bad operation code.
+	 */
+	Tcl_Panic("Bad operation code in ForwardProc");
+	break;
+    }
+
+    /*
+     * Remove the reference we held on the result of the invoke, if we had
+     * such.
+     */
+
+    if (resObj != NULL) {
+	Tcl_DecrRefCount(resObj);
+    }
+
+    if (resultPtr) {
+	/*
+	 * Report the forwarding result synchronously to the waiting caller.
+	 * This unblocks (*) as well. This is wrapped into a conditional
+	 * because the caller may have exited in the mean time.
+	 */
+
+	Tcl_MutexLock(&rtForwardMutex);
+	resultPtr->result = TCL_OK;
+	Tcl_ConditionNotify(&resultPtr->done);
+	Tcl_MutexUnlock(&rtForwardMutex);
+    }
+
+    return 1;
+}
+
+static void
+SrcExitProc(
+    ClientData clientData)
+{
+    ForwardingEvent *evPtr = clientData;
+    ForwardingResult *resultPtr;
+    ForwardParam *paramPtr;
+
+    /*
+     * NOTE (2): Can this handler be called with the originator blocked?
+     */
+
+    /*
+     * The originator for the event exited. It is not sure if this can happen,
+     * as the originator should be blocked at (*) while the event is in
+     * transit/pending.
+     *
+     * We make sure that the event cannot refer to the result anymore, remove
+     * it from the list of pending results and free the structure. Locking the
+     * access ensures that we cannot get in conflict with "ForwardProc",
+     * should it already execute the event.
+     */
+
+    Tcl_MutexLock(&rtForwardMutex);
+
+    resultPtr = evPtr->resultPtr;
+    paramPtr = evPtr->param;
+
+    evPtr->resultPtr = NULL;
+    resultPtr->evPtr = NULL;
+    resultPtr->result = TCL_ERROR;
+
+    ForwardSetStaticError(paramPtr, msg_send_originlost);
+
+    /*
+     * See below: TclSpliceOut(resultPtr, forwardList);
+     */
+
+    Tcl_MutexUnlock(&rtForwardMutex);
+
+    /*
+     * This unlocks (*). The structure will be spliced out and freed by
+     * "ForwardProc". Maybe.
+     */
+
+    Tcl_ConditionNotify(&resultPtr->done);
+}
+
+static void
+ForwardSetObjError(
+    ForwardParam *paramPtr,
+    Tcl_Obj *obj)
+{
+    int len;
+    const char *msgStr = Tcl_GetStringFromObj(obj, &len);
+
+    len++;
+    ForwardSetDynamicError(paramPtr, ckalloc(len));
+    memcpy(paramPtr->base.msgStr, msgStr, (unsigned) len);
+}
+#endif /* TCL_THREADS */
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TimerKill --
+ *
+ *	Timer management. Removes the internal timer if it exists.
+ *
+ * Side effects:
+ *	See above.
+ *
+ * Result:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+TimerKill(
+    ReflectedTransform *rtPtr)
+{
+    if (rtPtr->timer == NULL) {
+	return;
+    }
+
+    /*
+     * Delete an existing flush-out timer, prevent it from firing on a
+     * removed/dead channel.
+     */
+
+    Tcl_DeleteTimerHandler(rtPtr->timer);
+    rtPtr->timer = NULL;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TimerSetup --
+ *
+ *	Timer management. Creates the internal timer if it does not exist.
+ *
+ * Side effects:
+ *	See above.
+ *
+ * Result:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+TimerSetup(
+    ReflectedTransform *rtPtr)
+{
+    if (rtPtr->timer != NULL) {
+	return;
+    }
+
+    rtPtr->timer = Tcl_CreateTimerHandler(SYNTHETIC_EVENT_TIME,
+	    TimerRun, rtPtr);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TimerRun --
+ *
+ *	Called by the notifier (-> timer) to flush out information waiting in
+ *	channel buffers.
+ *
+ * Side effects:
+ *	As of 'Tcl_NotifyChannel'.
+ *
+ * Result:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+TimerRun(
+    ClientData clientData)
+{
+    ReflectedTransform *rtPtr = clientData;
+
+    rtPtr->timer = NULL;
+    Tcl_NotifyChannel(rtPtr->chan, TCL_READABLE);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ResultInit --
+ *
+ *	Initializes the specified buffer structure. The structure will contain
+ *	valid information for an emtpy buffer.
+ *
+ * Side effects:
+ *	See above.
+ *
+ * Result:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+ResultInit(
+    ResultBuffer *rPtr)		/* Reference to the structure to
+				 * initialize. */
+{
+    rPtr->used = 0;
+    rPtr->allocated = 0;
+    rPtr->buf = NULL;
+}
+/*
+ *----------------------------------------------------------------------
+ *
+ * ResultClear --
+ *
+ *	Deallocates any memory allocated by 'ResultAdd'.
+ *
+ * Side effects:
+ *	See above.
+ *
+ * Result:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+ResultClear(
+    ResultBuffer *rPtr)		/* Reference to the buffer to clear out */
+{
+    rPtr->used = 0;
+
+    if (!rPtr->allocated) {
+	return;
+    }
+
+    ckfree((char *) rPtr->buf);
+    rPtr->buf = NULL;
+    rPtr->allocated = 0;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ResultAdd --
+ *
+ *	Adds the bytes in the specified array to the buffer, by appending it.
+ *
+ * Side effects:
+ *	See above.
+ *
+ * Result:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+ResultAdd(
+    ResultBuffer *rPtr,		/* The buffer to extend */
+    unsigned char *buf,		/* The buffer to read from */
+    int toWrite)		/* The number of bytes in 'buf' */
+{
+    if ((rPtr->used + toWrite + 1) > rPtr->allocated) {
+	/*
+	 * Extension of the internal buffer is required.
+	 * NOTE: Currently linear. Should be doubling to amortize.
+	 */
+
+	if (rPtr->allocated == 0) {
+	    rPtr->allocated = toWrite + RB_INCREMENT;
+	    rPtr->buf = UCHARP(ckalloc(rPtr->allocated));
+	} else {
+	    rPtr->allocated += toWrite + RB_INCREMENT;
+	    rPtr->buf = UCHARP(ckrealloc((char *) rPtr->buf,
+		    rPtr->allocated));
+	}
+    }
+
+    /*
+     * Now copy data.
+     */
+
+    memcpy(rPtr->buf + rPtr->used, buf, toWrite);
+    rPtr->used += toWrite;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ResultCopy --
+ *
+ *	Copies the requested number of bytes from the buffer into the
+ *	specified array and removes them from the buffer afterward. Copies
+ *	less if there is not enough data in the buffer.
+ *
+ * Side effects:
+ *	See above.
+ *
+ * Result:
+ *	The number of actually copied bytes, possibly less than 'toRead'.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+ResultCopy(
+    ResultBuffer *rPtr,		/* The buffer to read from */
+    unsigned char *buf,		/* The buffer to copy into */
+    int toRead)			/* Number of requested bytes */
+{
+    int copied;
+
+    if (rPtr->used == 0) {
+	/*
+	 * Nothing to copy in the case of an empty buffer.
+	 */
+
+	copied = 0;
+    } else if (rPtr->used == toRead) {
+	/*
+	 * We have just enough. Copy everything to the caller.
+	 */
+
+	memcpy(buf, rPtr->buf, toRead);
+	rPtr->used = 0;
+	copied = toRead;
+    } else if (rPtr->used > toRead) {
+	/*
+	 * The internal buffer contains more than requested. Copy the
+	 * requested subset to the caller, and shift the remaining bytes down.
+	 */
+
+	memcpy(buf, rPtr->buf, toRead);
+	memmove(rPtr->buf, rPtr->buf + toRead, rPtr->used - toRead);
+
+	rPtr->used -= toRead;
+	copied = toRead;
+    } else {
+	/*
+	 * There is not enough in the buffer to satisfy the caller, so take
+	 * everything.
+	 */
+
+	memcpy(buf, rPtr->buf, rPtr->used);
+	toRead = rPtr->used;
+	rPtr->used = 0;
+	copied = toRead;
+    }
+
+    /* -- common postwork code ------- */
+
+    return copied;
+}
+
+static int
+TransformRead(
+    ReflectedTransform *rtPtr,
+    int *errorCodePtr,
+    Tcl_Obj *bufObj)
+{
+    Tcl_Obj *resObj;
+    int bytec;			/* Number of returned bytes */
+    unsigned char *bytev;	/* Array of returned bytes */
+
+    /*
+     * Are we in the correct thread?
+     */
+
+#ifdef TCL_THREADS
+    if (rtPtr->thread != Tcl_GetCurrentThread()) {
+	ForwardParam p;
+
+	p.transform.buf = (char *) Tcl_GetByteArrayFromObj(bufObj,
+		&(p.transform.size));
+
+	ForwardOpToOwnerThread(rtPtr, ForwardedInput, &p);
+
+	if (p.base.code != TCL_OK) {
+	    PassReceivedError(rtPtr->chan, &p);
+	    *errorCodePtr = EINVAL;
+	    return 0;
+	}
+
+	*errorCodePtr = EOK;
+	ResultAdd(&rtPtr->result, UCHARP(p.transform.buf), p.transform.size);
+	ckfree(p.transform.buf);
+	return 1;
+    }
+#endif /* TCL_THREADS */
+
+    /* ASSERT: rtPtr->method & FLAG(METH_READ) */
+    /* ASSERT: rtPtr->mode & TCL_READABLE */
+
+    if (InvokeTclMethod(rtPtr, "read", bufObj, NULL, &resObj) != TCL_OK) {
+	Tcl_SetChannelError(rtPtr->chan, resObj);
+	Tcl_DecrRefCount(resObj);	/* Remove reference held from invoke */
+	*errorCodePtr = EINVAL;
+	return 0;
+    }
+
+    bytev = Tcl_GetByteArrayFromObj(resObj, &bytec);
+    ResultAdd(&rtPtr->result, bytev, bytec);
+
+    Tcl_DecrRefCount(resObj);		/* Remove reference held from invoke */
+    return 1;
+}
+
+static int
+TransformWrite(
+    ReflectedTransform *rtPtr,
+    int *errorCodePtr,
+    unsigned char *buf,
+    int toWrite)
+{
+    Tcl_Obj *bufObj;
+    Tcl_Obj *resObj;
+    int bytec;			/* Number of returned bytes */
+    unsigned char *bytev;	/* Array of returned bytes */
+    int res;
+
+    /*
+     * Are we in the correct thread?
+     */
+
+#ifdef TCL_THREADS
+    if (rtPtr->thread != Tcl_GetCurrentThread()) {
+	ForwardParam p;
+
+	p.transform.buf = (char *) buf;
+	p.transform.size = toWrite;
+
+	ForwardOpToOwnerThread(rtPtr, ForwardedOutput, &p);
+
+	if (p.base.code != TCL_OK) {
+	    PassReceivedError(rtPtr->chan, &p);
+	    *errorCodePtr = EINVAL;
+	    return 0;
+	}
+
+	*errorCodePtr = EOK;
+	res = Tcl_WriteRaw(rtPtr->parent, (char *) p.transform.buf,
+		p.transform.size);
+	ckfree(p.transform.buf);
+    } else
+#endif /* TCL_THREADS */
+    {
+	/* ASSERT: rtPtr->method & FLAG(METH_WRITE) */
+	/* ASSERT: rtPtr->mode & TCL_WRITABLE */
+
+	bufObj = Tcl_NewByteArrayObj((unsigned char *) buf, toWrite);
+	Tcl_IncrRefCount(bufObj);
+	if (InvokeTclMethod(rtPtr, "write", bufObj, NULL, &resObj) != TCL_OK) {
+	    *errorCodePtr = EINVAL;
+	    Tcl_SetChannelError(rtPtr->chan, resObj);
+
+	    Tcl_DecrRefCount(bufObj);
+	    Tcl_DecrRefCount(resObj);	/* Remove reference held from invoke */
+	    return 0;
+	}
+
+	*errorCodePtr = EOK;
+
+	bytev = Tcl_GetByteArrayFromObj(resObj, &bytec);
+	res = Tcl_WriteRaw(rtPtr->parent, (char *) bytev, bytec);
+
+	Tcl_DecrRefCount(bufObj);
+	Tcl_DecrRefCount(resObj);	/* Remove reference held from invoke */
+    }
+
+    if (res < 0) {
+	*errorCodePtr = Tcl_GetErrno();
+	return 0;
+    }
+
+    return 1;
+}
+
+static int
+TransformDrain(
+    ReflectedTransform *rtPtr,
+    int *errorCodePtr)
+{
+    Tcl_Obj *resObj;
+    int bytec;			/* Number of returned bytes */
+    unsigned char *bytev;	/* Array of returned bytes */
+
+    /*
+     * Are we in the correct thread?
+     */
+
+#ifdef TCL_THREADS
+    if (rtPtr->thread != Tcl_GetCurrentThread()) {
+	ForwardParam p;
+
+	ForwardOpToOwnerThread(rtPtr, ForwardedDrain, &p);
+
+	if (p.base.code != TCL_OK) {
+	    PassReceivedError(rtPtr->chan, &p);
+	    *errorCodePtr = EINVAL;
+	    return 0;
+	}
+
+	*errorCodePtr = EOK;
+	ResultAdd(&rtPtr->result, UCHARP(p.transform.buf), p.transform.size);
+	ckfree(p.transform.buf);
+    } else
+#endif /* TCL_THREADS */
+    {
+	if (InvokeTclMethod(rtPtr, "drain", NULL, NULL, &resObj)!=TCL_OK) {
+	    Tcl_SetChannelError(rtPtr->chan, resObj);
+	    Tcl_DecrRefCount(resObj);	/* Remove reference held from invoke */
+	    *errorCodePtr = EINVAL;
+	    return 0;
+	}
+
+	bytev = Tcl_GetByteArrayFromObj(resObj, &bytec);
+	ResultAdd(&rtPtr->result, bytev, bytec);
+
+	Tcl_DecrRefCount(resObj);	/* Remove reference held from invoke */
+    }
+
+    rtPtr->readIsDrained = 1;
+    return 1;
+}
+
+static int
+TransformFlush(
+    ReflectedTransform *rtPtr,
+    int *errorCodePtr,
+    int op)
+{
+    Tcl_Obj *resObj;
+    int bytec;			/* Number of returned bytes */
+    unsigned char *bytev;	/* Array of returned bytes */
+    int res;
+
+    /*
+     * Are we in the correct thread?
+     */
+
+#ifdef TCL_THREADS
+    if (rtPtr->thread != Tcl_GetCurrentThread()) {
+	ForwardParam p;
+
+	ForwardOpToOwnerThread(rtPtr, ForwardedFlush, &p);
+
+	if (p.base.code != TCL_OK) {
+	    PassReceivedError(rtPtr->chan, &p);
+	    *errorCodePtr = EINVAL;
+	    return 0;
+	}
+
+	*errorCodePtr = EOK;
+	if (op == FLUSH_WRITE) {
+	    res = Tcl_WriteRaw(rtPtr->parent, (char *) p.transform.buf,
+		    p.transform.size);
+	} else {
+	    res = 0;
+	}
+	ckfree(p.transform.buf);
+    } else
+#endif /* TCL_THREADS */
+    {
+	if (InvokeTclMethod(rtPtr, "flush", NULL, NULL, &resObj)!=TCL_OK) {
+	    Tcl_SetChannelError(rtPtr->chan, resObj);
+	    Tcl_DecrRefCount(resObj);	/* Remove reference held from invoke */
+	    *errorCodePtr = EINVAL;
+	    return 0;
+	}
+
+	if (op == FLUSH_WRITE) {
+	    bytev = Tcl_GetByteArrayFromObj(resObj, &bytec);
+	    res = Tcl_WriteRaw(rtPtr->parent, (char *) bytev, bytec);
+	} else {
+	    res = 0;
+	}
+	Tcl_DecrRefCount(resObj);	/* Remove reference held from invoke */
+    }
+
+    if (res < 0) {
+	*errorCodePtr = Tcl_GetErrno();
+	return 0;
+    }
+
+    return 1;
+}
+
+static void
+TransformClear(
+    ReflectedTransform *rtPtr)
+{
+    /*
+     * Are we in the correct thread?
+     */
+
+#ifdef TCL_THREADS
+    if (rtPtr->thread != Tcl_GetCurrentThread()) {
+	ForwardParam p;
+
+	ForwardOpToOwnerThread(rtPtr, ForwardedClear, &p);
+	return;
+    }
+#endif /* TCL_THREADS */
+
+    /* ASSERT: rtPtr->method & FLAG(METH_READ) */
+    /* ASSERT: rtPtr->mode & TCL_READABLE */
+
+    (void) InvokeTclMethod(rtPtr, "clear", NULL, NULL, NULL);
+
+    rtPtr->readIsDrained = 0;
+    rtPtr->eofPending = 0;
+    ResultClear(&rtPtr->result);
+}
+
+static int
+TransformLimit(
+    ReflectedTransform *rtPtr,
+    int *errorCodePtr,
+    int *maxPtr)
+{
+    Tcl_Obj *resObj;
+    Tcl_InterpState sr;		/* State of handler interp */
+
+    /*
+     * Are we in the correct thread?
+     */
+
+#ifdef TCL_THREADS
+    if (rtPtr->thread != Tcl_GetCurrentThread()) {
+	ForwardParam p;
+
+	ForwardOpToOwnerThread(rtPtr, ForwardedLimit, &p);
+
+	if (p.base.code != TCL_OK) {
+	    PassReceivedError(rtPtr->chan, &p);
+	    *errorCodePtr = EINVAL;
+	    return 0;
+	}
+
+	*errorCodePtr = EOK;
+	*maxPtr = p.limit.max;
+	return 1;
+    }
+#endif
+
+    /* ASSERT: rtPtr->method & FLAG(METH_WRITE) */
+    /* ASSERT: rtPtr->mode & TCL_WRITABLE */
+
+    if (InvokeTclMethod(rtPtr, "limit?", NULL, NULL, &resObj) != TCL_OK) {
+	Tcl_SetChannelError(rtPtr->chan, resObj);
+	Tcl_DecrRefCount(resObj);	/* Remove reference held from invoke */
+	*errorCodePtr = EINVAL;
+	return 0;
+    }
+
+    sr = Tcl_SaveInterpState(rtPtr->interp, 0 /* Dummy */);
+
+    if (Tcl_GetIntFromObj(rtPtr->interp, resObj, maxPtr) != TCL_OK) {
+	Tcl_DecrRefCount(resObj);	/* Remove reference held from invoke */
+	Tcl_SetChannelError(rtPtr->chan, MarshallError(rtPtr->interp));
+	*errorCodePtr = EINVAL;
+
+	Tcl_RestoreInterpState(rtPtr->interp, sr);
+	return 0;
+    }
+
+    Tcl_DecrRefCount(resObj);		/* Remove reference held from invoke */
+    Tcl_RestoreInterpState(rtPtr->interp, sr);
+    return 1;
+}
+
+/* DUPLICATE of HaveVersion() in tclIO.c
+ *----------------------------------------------------------------------
+ *
+ * HaveVersion --
+ *
+ *	Return whether a channel type is (at least) of a given version.
+ *
+ * Results:
+ *	True if the minimum version is exceeded by the version actually
+ *	present.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+HaveVersion(
+    const Tcl_ChannelType *chanTypePtr,
+    Tcl_ChannelTypeVersion minimumVersion)
+{
+    Tcl_ChannelTypeVersion actualVersion = Tcl_ChannelVersion(chanTypePtr);
+
+    return PTR2INT(actualVersion) >= PTR2INT(minimumVersion);
+}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tclIOSock.c b/generic/tclIOSock.c
new file mode 100644
index 0000000..c5b7d28
--- /dev/null
+++ b/generic/tclIOSock.c
@@ -0,0 +1,291 @@
+/*
+ * tclIOSock.c --
+ *
+ *	Common routines used by all socket based channel types.
+ *
+ * Copyright (c) 1995-1997 Sun Microsystems, Inc.
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#include "tclInt.h"
+
+#if defined(_WIN32) && defined(UNICODE)
+/* On Windows, we need to do proper Unicode->UTF-8 conversion. */
+
+typedef struct ThreadSpecificData {
+    int initialized;
+    Tcl_DString errorMsg; /* UTF-8 encoded error-message */
+} ThreadSpecificData;
+static Tcl_ThreadDataKey dataKey;
+
+#undef gai_strerror
+static const char *gai_strerror(int code) {
+    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+
+    if (tsdPtr->initialized) {
+	Tcl_DStringFree(&tsdPtr->errorMsg);
+    } else {
+	tsdPtr->initialized = 1;
+    }
+    Tcl_WinTCharToUtf(gai_strerrorW(code), -1, &tsdPtr->errorMsg);
+    return Tcl_DStringValue(&tsdPtr->errorMsg);
+}
+#endif
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * TclSockGetPort --
+ *
+ *	Maps from a string, which could be a service name, to a port. Used by
+ *	socket creation code to get port numbers and resolve registered
+ *	service names to port numbers.
+ *
+ * Results:
+ *	A standard Tcl result. On success, the port number is returned in
+ *	portPtr. On failure, an error message is left in the interp's result.
+ *
+ * Side effects:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+int
+TclSockGetPort(
+    Tcl_Interp *interp,
+    const char *string, /* Integer or service name */
+    const char *proto, /* "tcp" or "udp", typically */
+    int *portPtr)		/* Return port number */
+{
+    struct servent *sp;		/* Protocol info for named services */
+    Tcl_DString ds;
+    const char *native;
+
+    if (Tcl_GetInt(NULL, string, portPtr) != TCL_OK) {
+	/*
+	 * Don't bother translating 'proto' to native.
+	 */
+
+	native = Tcl_UtfToExternalDString(NULL, string, -1, &ds);
+	sp = getservbyname(native, proto);		/* INTL: Native. */
+	Tcl_DStringFree(&ds);
+	if (sp != NULL) {
+	    *portPtr = ntohs((unsigned short) sp->s_port);
+	    return TCL_OK;
+	}
+    }
+    if (Tcl_GetInt(interp, string, portPtr) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    if (*portPtr > 0xFFFF) {
+	Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		"couldn't open socket: port number too high", -1));
+	return TCL_ERROR;
+    }
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclSockMinimumBuffers --
+ *
+ *	Ensure minimum buffer sizes (non zero).
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	Sets SO_SNDBUF and SO_RCVBUF sizes.
+ *
+ *----------------------------------------------------------------------
+ */
+
+#if !defined(_WIN32) && !defined(__CYGWIN__)
+#   define SOCKET int
+#endif
+
+int
+TclSockMinimumBuffers(
+    void *sock,			/* Socket file descriptor */
+    int size)			/* Minimum buffer size */
+{
+    int current;
+    socklen_t len;
+
+    len = sizeof(int);
+    getsockopt((SOCKET)(size_t) sock, SOL_SOCKET, SO_SNDBUF,
+	    (char *) &current, &len);
+    if (current < size) {
+	len = sizeof(int);
+	setsockopt((SOCKET)(size_t) sock, SOL_SOCKET, SO_SNDBUF,
+		(char *) &size, len);
+    }
+    len = sizeof(int);
+    getsockopt((SOCKET)(size_t) sock, SOL_SOCKET, SO_RCVBUF,
+		(char *) &current, &len);
+    if (current < size) {
+	len = sizeof(int);
+	setsockopt((SOCKET)(size_t) sock, SOL_SOCKET, SO_RCVBUF,
+		(char *) &size, len);
+    }
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclCreateSocketAddress --
+ *
+ *	This function initializes a sockaddr structure for a host and port.
+ *
+ * Results:
+ *	1 if the host was valid, 0 if the host could not be converted to an IP
+ *	address.
+ *
+ * Side effects:
+ *	Fills in the *sockaddrPtr structure.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclCreateSocketAddress(
+    Tcl_Interp *interp,                 /* Interpreter for querying
+					 * the desired socket family */
+    struct addrinfo **addrlist,		/* Socket address list */
+    const char *host,			/* Host. NULL implies INADDR_ANY */
+    int port,				/* Port number */
+    int willBind,			/* Is this an address to bind() to or
+					 * to connect() to? */
+    const char **errorMsgPtr)		/* Place to store the error message
+					 * detail, if available. */
+{
+    struct addrinfo hints;
+    struct addrinfo *p;
+    struct addrinfo *v4head = NULL, *v4ptr = NULL;
+    struct addrinfo *v6head = NULL, *v6ptr = NULL;
+    char *native = NULL, portbuf[TCL_INTEGER_SPACE], *portstring;
+    const char *family = NULL;
+    Tcl_DString ds;
+    int result;
+
+    if (host != NULL) {
+	native = Tcl_UtfToExternalDString(NULL, host, -1, &ds);
+    }
+
+    /*
+     * Workaround for OSX's apparent inability to resolve "localhost", "0"
+     * when the loopback device is the only available network interface.
+     */
+    if (host != NULL && port == 0) {
+        portstring = NULL;
+    } else {
+        TclFormatInt(portbuf, port);
+        portstring = portbuf;
+    }
+
+    (void) memset(&hints, 0, sizeof(hints));
+    hints.ai_family = AF_UNSPEC;
+
+    /*
+     * Magic variable to enforce a certain address family - to be superseded
+     * by a TIP that adds explicit switches to [socket]
+     */
+
+    if (interp != NULL) {
+        family = Tcl_GetVar(interp, "::tcl::unsupported::socketAF", 0);
+        if (family != NULL) {
+            if (strcmp(family, "inet") == 0) {
+                hints.ai_family = AF_INET;
+            } else if (strcmp(family, "inet6") == 0) {
+                hints.ai_family = AF_INET6;
+            }
+        }
+    }
+
+    hints.ai_socktype = SOCK_STREAM;
+
+#if 0
+    /*
+     * We found some problems when using AI_ADDRCONFIG, e.g. on systems that
+     * have no networking besides the loopback interface and want to resolve
+     * localhost. See [Bugs 3385024, 3382419, 3382431]. As the advantage of
+     * using AI_ADDRCONFIG in situations where it works, is probably low,
+     * we'll leave it out for now. After all, it is just an optimisation.
+     *
+     * Missing on: OpenBSD, NetBSD.
+     * Causes failure when used on AIX 5.1 and HP-UX
+     */
+
+#if defined(AI_ADDRCONFIG) && !defined(_AIX) && !defined(__hpux)
+    hints.ai_flags |= AI_ADDRCONFIG;
+#endif /* AI_ADDRCONFIG && !_AIX && !__hpux */
+#endif /* 0 */
+
+    if (willBind) {
+	hints.ai_flags |= AI_PASSIVE;
+    }
+
+    result = getaddrinfo(native, portstring, &hints, addrlist);
+
+    if (host != NULL) {
+	Tcl_DStringFree(&ds);
+    }
+
+    if (result != 0) {
+	*errorMsgPtr =
+#ifdef EAI_SYSTEM	/* Doesn't exist on Windows */
+		(result == EAI_SYSTEM) ? Tcl_PosixError(interp) :
+#endif /* EAI_SYSTEM */
+		gai_strerror(result);
+        return 0;
+    }
+
+    /*
+     * Put IPv4 addresses before IPv6 addresses to maximize backwards
+     * compatibility of [fconfigure -sockname] output.
+     *
+     * There might be more elegant/efficient ways to do this.
+     */
+    if (willBind) {
+	for (p = *addrlist; p != NULL; p = p->ai_next) {
+	    if (p->ai_family == AF_INET) {
+		if (v4head == NULL) {
+		    v4head = p;
+		} else {
+		    v4ptr->ai_next = p;
+		}
+		v4ptr = p;
+	    } else {
+		if (v6head == NULL) {
+		    v6head = p;
+		} else {
+		    v6ptr->ai_next = p;
+		}
+		v6ptr = p;
+	    }
+	}
+	*addrlist = NULL;
+	if (v6head != NULL) {
+	    *addrlist = v6head;
+	    v6ptr->ai_next = NULL;
+	}
+	if (v4head != NULL) {
+	    v4ptr->ai_next = *addrlist;
+	    *addrlist = v4head;
+	}
+    }
+    return 1;
+}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tclIOUtil.c b/generic/tclIOUtil.c
new file mode 100644
index 0000000..3aa0ce5
--- /dev/null
+++ b/generic/tclIOUtil.c
@@ -0,0 +1,4874 @@
+/*
+ * tclIOUtil.c --
+ *
+ *	This file contains the implementation of Tcl's generic filesystem
+ *	code, which supports a pluggable filesystem architecture allowing both
+ *	platform specific filesystems and 'virtual filesystems'. All
+ *	filesystem access should go through the functions defined in this
+ *	file. Most of this code was contributed by Vince Darley.
+ *
+ *	Parts of this file are based on code contributed by Karl Lehenbauer,
+ *	Mark Diekhans and Peter da Silva.
+ *
+ * Copyright (c) 1991-1994 The Regents of the University of California.
+ * Copyright (c) 1994-1997 Sun Microsystems, Inc.
+ * Copyright (c) 2001-2004 Vincent Darley.
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#include "tclInt.h"
+#ifdef _WIN32
+#   include "tclWinInt.h"
+#endif
+#include "tclFileSystem.h"
+
+#ifdef TCL_TEMPLOAD_NO_UNLINK
+#ifndef NO_FSTATFS
+#include <sys/statfs.h>
+#endif
+#endif
+
+/*
+ * struct FilesystemRecord --
+ *
+ * A filesystem record is used to keep track of each filesystem currently
+ * registered with the core, in a linked list.
+ */
+
+typedef struct FilesystemRecord {
+    ClientData clientData;	/* Client specific data for the new filesystem
+				 * (can be NULL) */
+    const Tcl_Filesystem *fsPtr;/* Pointer to filesystem dispatch table. */
+    struct FilesystemRecord *nextPtr;
+				/* The next filesystem registered to Tcl, or
+				 * NULL if no more. */
+    struct FilesystemRecord *prevPtr;
+				/* The previous filesystem registered to Tcl,
+				 * or NULL if no more. */
+} FilesystemRecord;
+
+/*
+ * This structure holds per-thread private copy of the current directory
+ * maintained by the global cwdPathPtr. This structure holds per-thread
+ * private copies of some global data. This way we avoid most of the
+ * synchronization calls which boosts performance, at cost of having to update
+ * this information each time the corresponding epoch counter changes.
+ */
+
+typedef struct ThreadSpecificData {
+    int initialized;
+    size_t cwdPathEpoch;
+    size_t filesystemEpoch;
+    Tcl_Obj *cwdPathPtr;
+    ClientData cwdClientData;
+    FilesystemRecord *filesystemList;
+    size_t claims;
+} ThreadSpecificData;
+
+/*
+ * Prototypes for functions defined later in this file.
+ */
+
+static Tcl_NRPostProc	EvalFileCallback;
+static FilesystemRecord*FsGetFirstFilesystem(void);
+static void		FsThrExitProc(ClientData cd);
+static Tcl_Obj *	FsListMounts(Tcl_Obj *pathPtr, const char *pattern);
+static void		FsAddMountsToGlobResult(Tcl_Obj *resultPtr,
+			    Tcl_Obj *pathPtr, const char *pattern,
+			    Tcl_GlobTypeData *types);
+static void		FsUpdateCwd(Tcl_Obj *cwdObj, ClientData clientData);
+static void		FsRecacheFilesystemList(void);
+static void		Claim(void);
+static void		Disclaim(void);
+
+static void *		DivertFindSymbol(Tcl_Interp *interp,
+			    Tcl_LoadHandle loadHandle, const char *symbol);
+static void		DivertUnloadFile(Tcl_LoadHandle loadHandle);
+
+/*
+ * These form part of the native filesystem support. They are needed here
+ * because we have a few native filesystem functions (which are the same for
+ * win/unix) in this file. There is no need to place them in tclInt.h, because
+ * they are not (and should not be) used anywhere else.
+ */
+
+MODULE_SCOPE const char *const		tclpFileAttrStrings[];
+MODULE_SCOPE const TclFileAttrProcs	tclpFileAttrProcs[];
+
+/*
+ * Declare the native filesystem support. These functions should be considered
+ * private to Tcl, and should really not be called directly by any code other
+ * than this file (i.e. neither by Tcl's core nor by extensions). Similarly,
+ * the old string-based Tclp... native filesystem functions should not be
+ * called.
+ *
+ * The correct API to use now is the Tcl_FS... set of functions, which ensure
+ * correct and complete virtual filesystem support.
+ *
+ * We cannot make all of these static, since some of them are implemented in
+ * the platform-specific directories.
+ */
+
+static Tcl_FSFilesystemSeparatorProc NativeFilesystemSeparator;
+static Tcl_FSFreeInternalRepProc NativeFreeInternalRep;
+static Tcl_FSFileAttrStringsProc NativeFileAttrStrings;
+static Tcl_FSFileAttrsGetProc	NativeFileAttrsGet;
+static Tcl_FSFileAttrsSetProc	NativeFileAttrsSet;
+
+/*
+ * The only reason these functions are not static is that they are either
+ * called by code in the native (win/unix) directories or they are actually
+ * implemented in those directories. They should simply not be called by code
+ * outside Tcl's native filesystem core i.e. they should be considered
+ * 'static' to Tcl's filesystem code (if we ever built the native filesystem
+ * support into a separate code library, this could actually be enforced).
+ */
+
+Tcl_FSFilesystemPathTypeProc	TclpFilesystemPathType;
+Tcl_FSInternalToNormalizedProc	TclpNativeToNormalized;
+Tcl_FSStatProc			TclpObjStat;
+Tcl_FSAccessProc		TclpObjAccess;
+Tcl_FSMatchInDirectoryProc	TclpMatchInDirectory;
+Tcl_FSChdirProc			TclpObjChdir;
+Tcl_FSLstatProc			TclpObjLstat;
+Tcl_FSCopyFileProc		TclpObjCopyFile;
+Tcl_FSDeleteFileProc		TclpObjDeleteFile;
+Tcl_FSRenameFileProc		TclpObjRenameFile;
+Tcl_FSCreateDirectoryProc	TclpObjCreateDirectory;
+Tcl_FSCopyDirectoryProc		TclpObjCopyDirectory;
+Tcl_FSRemoveDirectoryProc	TclpObjRemoveDirectory;
+Tcl_FSUnloadFileProc		TclpUnloadFile;
+Tcl_FSLinkProc			TclpObjLink;
+Tcl_FSListVolumesProc		TclpObjListVolumes;
+
+/*
+ * Define the native filesystem dispatch table. If necessary, it is ok to make
+ * this non-static, but it should only be accessed by the functions actually
+ * listed within it (or perhaps other helper functions of them). Anything
+ * which is not part of this 'native filesystem implementation' should not be
+ * delving inside here!
+ */
+
+const Tcl_Filesystem tclNativeFilesystem = {
+    "native",
+    sizeof(Tcl_Filesystem),
+    TCL_FILESYSTEM_VERSION_2,
+    TclNativePathInFilesystem,
+    TclNativeDupInternalRep,
+    NativeFreeInternalRep,
+    TclpNativeToNormalized,
+    TclNativeCreateNativeRep,
+    TclpObjNormalizePath,
+    TclpFilesystemPathType,
+    NativeFilesystemSeparator,
+    TclpObjStat,
+    TclpObjAccess,
+    TclpOpenFileChannel,
+    TclpMatchInDirectory,
+    TclpUtime,
+#ifndef S_IFLNK
+    NULL,
+#else
+    TclpObjLink,
+#endif /* S_IFLNK */
+    TclpObjListVolumes,
+    NativeFileAttrStrings,
+    NativeFileAttrsGet,
+    NativeFileAttrsSet,
+    TclpObjCreateDirectory,
+    TclpObjRemoveDirectory,
+    TclpObjDeleteFile,
+    TclpObjCopyFile,
+    TclpObjRenameFile,
+    TclpObjCopyDirectory,
+    TclpObjLstat,
+    /* Needs casts since we're using version_2. */
+    (Tcl_FSLoadFileProc *) TclpDlopen,
+    (Tcl_FSGetCwdProc *) TclpGetNativeCwd,
+    TclpObjChdir
+};
+
+/*
+ * Define the tail of the linked list. Note that for unconventional uses of
+ * Tcl without a native filesystem, we may in the future wish to modify the
+ * current approach of hard-coding the native filesystem in the lookup list
+ * 'filesystemList' below.
+ *
+ * We initialize the record so that it thinks one file uses it. This means it
+ * will never be freed.
+ */
+
+static FilesystemRecord nativeFilesystemRecord = {
+    NULL,
+    &tclNativeFilesystem,
+    NULL,
+    NULL
+};
+
+/*
+ * This is incremented each time we modify the linked list of filesystems. Any
+ * time it changes, all cached filesystem representations are suspect and must
+ * be freed. For multithreading builds, change of the filesystem epoch will
+ * trigger cache cleanup in all threads.
+ */
+
+static size_t theFilesystemEpoch = 1;
+
+/*
+ * Stores the linked list of filesystems. A 1:1 copy of this list is also
+ * maintained in the TSD for each thread. This is to avoid synchronization
+ * issues.
+ */
+
+static FilesystemRecord *filesystemList = &nativeFilesystemRecord;
+TCL_DECLARE_MUTEX(filesystemMutex)
+
+/*
+ * Used to implement Tcl_FSGetCwd in a file-system independent way.
+ */
+
+static Tcl_Obj *cwdPathPtr = NULL;
+static size_t cwdPathEpoch = 0;
+static ClientData cwdClientData = NULL;
+TCL_DECLARE_MUTEX(cwdMutex)
+
+static Tcl_ThreadDataKey fsDataKey;
+
+/*
+ * One of these structures is used each time we successfully load a file from
+ * a file system by way of making a temporary copy of the file on the native
+ * filesystem. We need to store both the actual unloadProc/clientData
+ * combination which was used, and the original and modified filenames, so
+ * that we can correctly undo the entire operation when we want to unload the
+ * code.
+ */
+
+typedef struct FsDivertLoad {
+    Tcl_LoadHandle loadHandle;
+    Tcl_FSUnloadFileProc *unloadProcPtr;
+    Tcl_Obj *divertedFile;
+    const Tcl_Filesystem *divertedFilesystem;
+    ClientData divertedFileNativeRep;
+} FsDivertLoad;
+
+/*
+ * The following functions are obsolete string based APIs, and should be
+ * removed in a future release (Tcl 9 would be a good time).
+ */
+
+/* Obsolete */
+int
+Tcl_Stat(
+    const char *path,		/* Path of file to stat (in current CP). */
+    struct stat *oldStyleBuf)	/* Filled with results of stat call. */
+{
+    int ret;
+    Tcl_StatBuf buf;
+    Tcl_Obj *pathPtr = Tcl_NewStringObj(path,-1);
+
+    Tcl_IncrRefCount(pathPtr);
+    ret = Tcl_FSStat(pathPtr, &buf);
+    Tcl_DecrRefCount(pathPtr);
+    if (ret != -1) {
+#ifndef TCL_WIDE_INT_IS_LONG
+	Tcl_WideInt tmp1, tmp2, tmp3 = 0;
+
+# define OUT_OF_RANGE(x) \
+	(((Tcl_WideInt)(x)) < Tcl_LongAsWide(LONG_MIN) || \
+	 ((Tcl_WideInt)(x)) > Tcl_LongAsWide(LONG_MAX))
+# define OUT_OF_URANGE(x) \
+	(((Tcl_WideUInt)(x)) > ((Tcl_WideUInt)ULONG_MAX))
+
+	/*
+	 * Perform the result-buffer overflow check manually.
+	 *
+	 * Note that ino_t/ino64_t is unsigned...
+	 *
+	 * Workaround gcc warning of "comparison is always false due to
+	 * limited range of data type" by assigning to tmp var of type
+	 * Tcl_WideInt.
+	 */
+
+	tmp1 = (Tcl_WideInt) buf.st_ino;
+	tmp2 = (Tcl_WideInt) buf.st_size;
+#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
+	tmp3 = (Tcl_WideInt) buf.st_blocks;
+#endif
+
+	if (OUT_OF_URANGE(tmp1) || OUT_OF_RANGE(tmp2) || OUT_OF_RANGE(tmp3)) {
+#if defined(EFBIG)
+	    errno = EFBIG;
+#elif defined(EOVERFLOW)
+	    errno = EOVERFLOW;
+#else
+#error "What status should be returned for file size out of range?"
+#endif
+	    return -1;
+	}
+
+#   undef OUT_OF_RANGE
+#   undef OUT_OF_URANGE
+#endif /* !TCL_WIDE_INT_IS_LONG */
+
+	/*
+	 * Copy across all supported fields, with possible type coercions on
+	 * those fields that change between the normal and lf64 versions of
+	 * the stat structure (on Solaris at least). This is slow when the
+	 * structure sizes coincide, but that's what you get for using an
+	 * obsolete interface.
+	 */
+
+	oldStyleBuf->st_mode	= buf.st_mode;
+	oldStyleBuf->st_ino	= (ino_t) buf.st_ino;
+	oldStyleBuf->st_dev	= buf.st_dev;
+	oldStyleBuf->st_rdev	= buf.st_rdev;
+	oldStyleBuf->st_nlink	= buf.st_nlink;
+	oldStyleBuf->st_uid	= buf.st_uid;
+	oldStyleBuf->st_gid	= buf.st_gid;
+	oldStyleBuf->st_size	= (off_t) buf.st_size;
+	oldStyleBuf->st_atime	= buf.st_atime;
+	oldStyleBuf->st_mtime	= buf.st_mtime;
+	oldStyleBuf->st_ctime	= buf.st_ctime;
+#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
+	oldStyleBuf->st_blksize	= buf.st_blksize;
+#endif
+#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
+#ifdef HAVE_BLKCNT_T
+	oldStyleBuf->st_blocks	= (blkcnt_t) buf.st_blocks;
+#else
+	oldStyleBuf->st_blocks	= (unsigned long) buf.st_blocks;
+#endif
+#endif
+    }
+    return ret;
+}
+
+/* Obsolete */
+int
+Tcl_Access(
+    const char *path,		/* Path of file to access (in current CP). */
+    int mode)			/* Permission setting. */
+{
+    int ret;
+    Tcl_Obj *pathPtr = Tcl_NewStringObj(path,-1);
+
+    Tcl_IncrRefCount(pathPtr);
+    ret = Tcl_FSAccess(pathPtr,mode);
+    Tcl_DecrRefCount(pathPtr);
+
+    return ret;
+}
+
+/* Obsolete */
+Tcl_Channel
+Tcl_OpenFileChannel(
+    Tcl_Interp *interp,		/* Interpreter for error reporting; can be
+				 * NULL. */
+    const char *path,		/* Name of file to open. */
+    const char *modeString,	/* A list of POSIX open modes or a string such
+				 * as "rw". */
+    int permissions)		/* If the open involves creating a file, with
+				 * what modes to create it? */
+{
+    Tcl_Channel ret;
+    Tcl_Obj *pathPtr = Tcl_NewStringObj(path,-1);
+
+    Tcl_IncrRefCount(pathPtr);
+    ret = Tcl_FSOpenFileChannel(interp, pathPtr, modeString, permissions);
+    Tcl_DecrRefCount(pathPtr);
+
+    return ret;
+}
+
+/* Obsolete */
+int
+Tcl_Chdir(
+    const char *dirName)
+{
+    int ret;
+    Tcl_Obj *pathPtr = Tcl_NewStringObj(dirName,-1);
+    Tcl_IncrRefCount(pathPtr);
+    ret = Tcl_FSChdir(pathPtr);
+    Tcl_DecrRefCount(pathPtr);
+    return ret;
+}
+
+/* Obsolete */
+char *
+Tcl_GetCwd(
+    Tcl_Interp *interp,
+    Tcl_DString *cwdPtr)
+{
+    Tcl_Obj *cwd = Tcl_FSGetCwd(interp);
+
+    if (cwd == NULL) {
+	return NULL;
+    }
+    Tcl_DStringInit(cwdPtr);
+    TclDStringAppendObj(cwdPtr, cwd);
+    Tcl_DecrRefCount(cwd);
+    return Tcl_DStringValue(cwdPtr);
+}
+
+/* Obsolete */
+int
+Tcl_EvalFile(
+    Tcl_Interp *interp,		/* Interpreter in which to process file. */
+    const char *fileName)	/* Name of file to process. Tilde-substitution
+				 * will be performed on this name. */
+{
+    int ret;
+    Tcl_Obj *pathPtr = Tcl_NewStringObj(fileName,-1);
+
+    Tcl_IncrRefCount(pathPtr);
+    ret = Tcl_FSEvalFile(interp, pathPtr);
+    Tcl_DecrRefCount(pathPtr);
+    return ret;
+}
+
+/*
+ * Now move on to the basic filesystem implementation.
+ */
+
+static void
+FsThrExitProc(
+    ClientData cd)
+{
+    ThreadSpecificData *tsdPtr = cd;
+    FilesystemRecord *fsRecPtr = NULL, *tmpFsRecPtr = NULL;
+
+    /*
+     * Trash the cwd copy.
+     */
+
+    if (tsdPtr->cwdPathPtr != NULL) {
+	Tcl_DecrRefCount(tsdPtr->cwdPathPtr);
+	tsdPtr->cwdPathPtr = NULL;
+    }
+    if (tsdPtr->cwdClientData != NULL) {
+	NativeFreeInternalRep(tsdPtr->cwdClientData);
+    }
+
+    /*
+     * Trash the filesystems cache.
+     */
+
+    fsRecPtr = tsdPtr->filesystemList;
+    while (fsRecPtr != NULL) {
+	tmpFsRecPtr = fsRecPtr->nextPtr;
+	fsRecPtr->fsPtr = NULL;
+	ckfree(fsRecPtr);
+	fsRecPtr = tmpFsRecPtr;
+    }
+    tsdPtr->filesystemList = NULL;
+    tsdPtr->initialized = 0;
+}
+
+int
+TclFSCwdIsNative(void)
+{
+    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&fsDataKey);
+
+    if (tsdPtr->cwdClientData != NULL) {
+	return 1;
+    } else {
+	return 0;
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclFSCwdPointerEquals --
+ *
+ *	Check whether the current working directory is equal to the path
+ *	given.
+ *
+ * Results:
+ *	1 (equal) or 0 (un-equal) as appropriate.
+ *
+ * Side effects:
+ *	If the paths are equal, but are not the same object, this method will
+ *	modify the given pathPtrPtr to refer to the same object. In this case
+ *	the object pointed to by pathPtrPtr will have its refCount
+ *	decremented, and it will be adjusted to point to the cwd (with a new
+ *	refCount).
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclFSCwdPointerEquals(
+    Tcl_Obj **pathPtrPtr)
+{
+    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&fsDataKey);
+
+    Tcl_MutexLock(&cwdMutex);
+    if (tsdPtr->cwdPathPtr == NULL
+	    || tsdPtr->cwdPathEpoch != cwdPathEpoch) {
+	if (tsdPtr->cwdPathPtr != NULL) {
+	    Tcl_DecrRefCount(tsdPtr->cwdPathPtr);
+	}
+	if (tsdPtr->cwdClientData != NULL) {
+	    NativeFreeInternalRep(tsdPtr->cwdClientData);
+	}
+	if (cwdPathPtr == NULL) {
+	    tsdPtr->cwdPathPtr = NULL;
+	} else {
+	    tsdPtr->cwdPathPtr = Tcl_DuplicateObj(cwdPathPtr);
+	    Tcl_IncrRefCount(tsdPtr->cwdPathPtr);
+	}
+	if (cwdClientData == NULL) {
+	    tsdPtr->cwdClientData = NULL;
+	} else {
+	    tsdPtr->cwdClientData = TclNativeDupInternalRep(cwdClientData);
+	}
+	tsdPtr->cwdPathEpoch = cwdPathEpoch;
+    }
+    Tcl_MutexUnlock(&cwdMutex);
+
+    if (tsdPtr->initialized == 0) {
+	Tcl_CreateThreadExitHandler(FsThrExitProc, tsdPtr);
+	tsdPtr->initialized = 1;
+    }
+
+    if (pathPtrPtr == NULL) {
+	return (tsdPtr->cwdPathPtr == NULL);
+    }
+
+    if (tsdPtr->cwdPathPtr == *pathPtrPtr) {
+	return 1;
+    } else {
+	int len1, len2;
+	const char *str1, *str2;
+
+	str1 = Tcl_GetStringFromObj(tsdPtr->cwdPathPtr, &len1);
+	str2 = Tcl_GetStringFromObj(*pathPtrPtr, &len2);
+	if ((len1 == len2) && !memcmp(str1, str2, len1)) {
+	    /*
+	     * They are equal, but different objects. Update so they will be
+	     * the same object in the future.
+	     */
+
+	    Tcl_DecrRefCount(*pathPtrPtr);
+	    *pathPtrPtr = tsdPtr->cwdPathPtr;
+	    Tcl_IncrRefCount(*pathPtrPtr);
+	    return 1;
+	} else {
+	    return 0;
+	}
+    }
+}
+
+static void
+FsRecacheFilesystemList(void)
+{
+    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&fsDataKey);
+    FilesystemRecord *fsRecPtr, *tmpFsRecPtr = NULL, *toFree = NULL, *list;
+
+    /*
+     * Trash the current cache.
+     */
+
+    fsRecPtr = tsdPtr->filesystemList;
+    while (fsRecPtr != NULL) {
+	tmpFsRecPtr = fsRecPtr->nextPtr;
+	fsRecPtr->nextPtr = toFree;
+	toFree = fsRecPtr;
+	fsRecPtr = tmpFsRecPtr;
+    }
+
+    /*
+     * Locate tail of the global filesystem list.
+     */
+
+    Tcl_MutexLock(&filesystemMutex);
+    fsRecPtr = filesystemList;
+    while (fsRecPtr != NULL) {
+	tmpFsRecPtr = fsRecPtr;
+	fsRecPtr = fsRecPtr->nextPtr;
+    }
+
+    /*
+     * Refill the cache honouring the order.
+     */
+
+    list = NULL;
+    fsRecPtr = tmpFsRecPtr;
+    while (fsRecPtr != NULL) {
+	tmpFsRecPtr = ckalloc(sizeof(FilesystemRecord));
+	*tmpFsRecPtr = *fsRecPtr;
+	tmpFsRecPtr->nextPtr = list;
+	tmpFsRecPtr->prevPtr = NULL;
+	list = tmpFsRecPtr;
+	fsRecPtr = fsRecPtr->prevPtr;
+    }
+    tsdPtr->filesystemList = list;
+    tsdPtr->filesystemEpoch = theFilesystemEpoch;
+    Tcl_MutexUnlock(&filesystemMutex);
+
+    while (toFree) {
+	FilesystemRecord *next = toFree->nextPtr;
+	toFree->fsPtr = NULL;
+	ckfree(toFree);
+	toFree = next;
+    }
+
+    /*
+     * Make sure the above gets released on thread exit.
+     */
+
+    if (tsdPtr->initialized == 0) {
+	Tcl_CreateThreadExitHandler(FsThrExitProc, tsdPtr);
+	tsdPtr->initialized = 1;
+    }
+}
+
+static FilesystemRecord *
+FsGetFirstFilesystem(void)
+{
+    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&fsDataKey);
+    if (tsdPtr->filesystemList == NULL || ((tsdPtr->claims == 0)
+	    && (tsdPtr->filesystemEpoch != theFilesystemEpoch))) {
+	FsRecacheFilesystemList();
+    }
+    return tsdPtr->filesystemList;
+}
+
+/*
+ * The epoch can be changed both by filesystems being added or removed and by
+ * env(HOME) changing.
+ */
+
+int
+TclFSEpochOk(
+    size_t filesystemEpoch)
+{
+    return (filesystemEpoch == 0 || filesystemEpoch == theFilesystemEpoch);
+}
+
+static void
+Claim(void)
+{
+    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&fsDataKey);
+
+    tsdPtr->claims++;
+}
+
+static void
+Disclaim(void)
+{
+    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&fsDataKey);
+
+    tsdPtr->claims--;
+}
+
+size_t
+TclFSEpoch(void)
+{
+    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&fsDataKey);
+
+    return tsdPtr->filesystemEpoch;
+}
+
+
+/*
+ * If non-NULL, clientData is owned by us and must be freed later.
+ */
+
+static void
+FsUpdateCwd(
+    Tcl_Obj *cwdObj,
+    ClientData clientData)
+{
+    int len;
+    const char *str = NULL;
+    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&fsDataKey);
+
+    if (cwdObj != NULL) {
+	str = Tcl_GetStringFromObj(cwdObj, &len);
+    }
+
+    Tcl_MutexLock(&cwdMutex);
+    if (cwdPathPtr != NULL) {
+	Tcl_DecrRefCount(cwdPathPtr);
+    }
+    if (cwdClientData != NULL) {
+	NativeFreeInternalRep(cwdClientData);
+    }
+
+    if (cwdObj == NULL) {
+	cwdPathPtr = NULL;
+	cwdClientData = NULL;
+    } else {
+	/*
+	 * This must be stored as string obj!
+	 */
+
+	cwdPathPtr = Tcl_NewStringObj(str, len);
+	Tcl_IncrRefCount(cwdPathPtr);
+	cwdClientData = TclNativeDupInternalRep(clientData);
+    }
+
+    if (++cwdPathEpoch == 0) {
+	++cwdPathEpoch;
+    }
+    tsdPtr->cwdPathEpoch = cwdPathEpoch;
+    Tcl_MutexUnlock(&cwdMutex);
+
+    if (tsdPtr->cwdPathPtr) {
+	Tcl_DecrRefCount(tsdPtr->cwdPathPtr);
+    }
+    if (tsdPtr->cwdClientData) {
+	NativeFreeInternalRep(tsdPtr->cwdClientData);
+    }
+
+    if (cwdObj == NULL) {
+	tsdPtr->cwdPathPtr = NULL;
+	tsdPtr->cwdClientData = NULL;
+    } else {
+	tsdPtr->cwdPathPtr = Tcl_NewStringObj(str, len);
+	tsdPtr->cwdClientData = clientData;
+	Tcl_IncrRefCount(tsdPtr->cwdPathPtr);
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclFinalizeFilesystem --
+ *
+ *	Clean up the filesystem. After this, calls to all Tcl_FS... functions
+ *	will fail.
+ *
+ *	We will later call TclResetFilesystem to restore the FS to a pristine
+ *	state.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Frees any memory allocated by the filesystem.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclFinalizeFilesystem(void)
+{
+    FilesystemRecord *fsRecPtr;
+
+    /*
+     * Assumption that only one thread is active now. Otherwise we would need
+     * to put various mutexes around this code.
+     */
+
+    if (cwdPathPtr != NULL) {
+	Tcl_DecrRefCount(cwdPathPtr);
+	cwdPathPtr = NULL;
+	cwdPathEpoch = 0;
+    }
+    if (cwdClientData != NULL) {
+	NativeFreeInternalRep(cwdClientData);
+	cwdClientData = NULL;
+    }
+
+    /*
+     * Remove all filesystems, freeing any allocated memory that is no longer
+     * needed.
+     */
+
+    fsRecPtr = filesystemList;
+    while (fsRecPtr != NULL) {
+	FilesystemRecord *tmpFsRecPtr = fsRecPtr->nextPtr;
+
+	/* The native filesystem is static, so we don't free it. */
+
+	if (fsRecPtr != &nativeFilesystemRecord) {
+	    ckfree(fsRecPtr);
+	}
+	fsRecPtr = tmpFsRecPtr;
+    }
+    if (++theFilesystemEpoch == 0) {
+	++theFilesystemEpoch;
+    }
+    filesystemList = NULL;
+
+    /*
+     * Now filesystemList is NULL. This means that any attempt to use the
+     * filesystem is likely to fail.
+     */
+
+#ifdef _WIN32
+    TclWinEncodingsCleanup();
+#endif
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclResetFilesystem --
+ *
+ *	Restore the filesystem to a pristine state.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclResetFilesystem(void)
+{
+    filesystemList = &nativeFilesystemRecord;
+    if (++theFilesystemEpoch == 0) {
+	++theFilesystemEpoch;
+    }
+
+#ifdef _WIN32
+    /*
+     * Cleans up the win32 API filesystem proc lookup table. This must happen
+     * very late in finalization so that deleting of copied dlls can occur.
+     */
+
+    TclWinResetInterfaces();
+#endif
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_FSRegister --
+ *
+ *	Insert the filesystem function table at the head of the list of
+ *	functions which are used during calls to all file-system operations.
+ *	The filesystem will be added even if it is already in the list. (You
+ *	can use Tcl_FSData to check if it is in the list, provided the
+ *	ClientData used was not NULL).
+ *
+ *	Note that the filesystem handling is head-to-tail of the list. Each
+ *	filesystem is asked in turn whether it can handle a particular
+ *	request, until one of them says 'yes'. At that point no further
+ *	filesystems are asked.
+ *
+ *	In particular this means if you want to add a diagnostic filesystem
+ *	(which simply reports all fs activity), it must be at the head of the
+ *	list: i.e. it must be the last registered.
+ *
+ * Results:
+ *	Normally TCL_OK; TCL_ERROR if memory for a new node in the list could
+ *	not be allocated.
+ *
+ * Side effects:
+ *	Memory allocated and modifies the link list for filesystems.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_FSRegister(
+    ClientData clientData,	/* Client specific data for this fs. */
+    const Tcl_Filesystem *fsPtr)/* The filesystem record for the new fs. */
+{
+    FilesystemRecord *newFilesystemPtr;
+
+    if (fsPtr == NULL) {
+	return TCL_ERROR;
+    }
+
+    newFilesystemPtr = ckalloc(sizeof(FilesystemRecord));
+
+    newFilesystemPtr->clientData = clientData;
+    newFilesystemPtr->fsPtr = fsPtr;
+
+    /*
+     * Is this lock and wait strictly speaking necessary? Since any iterators
+     * out there will have grabbed a copy of the head of the list and be
+     * iterating away from that, if we add a new element to the head of the
+     * list, it can't possibly have any effect on any of their loops. In fact
+     * it could be better not to wait, since we are adjusting the filesystem
+     * epoch, any cached representations calculated by existing iterators are
+     * going to have to be thrown away anyway.
+     *
+     * However, since registering and unregistering filesystems is a very rare
+     * action, this is not a very important point.
+     */
+
+    Tcl_MutexLock(&filesystemMutex);
+
+    newFilesystemPtr->nextPtr = filesystemList;
+    newFilesystemPtr->prevPtr = NULL;
+    if (filesystemList) {
+	filesystemList->prevPtr = newFilesystemPtr;
+    }
+    filesystemList = newFilesystemPtr;
+
+    /*
+     * Increment the filesystem epoch counter, since existing paths might
+     * conceivably now belong to different filesystems.
+     */
+
+    if (++theFilesystemEpoch == 0) {
+	++theFilesystemEpoch;
+    }
+    Tcl_MutexUnlock(&filesystemMutex);
+
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_FSUnregister --
+ *
+ *	Remove the passed filesystem from the list of filesystem function
+ *	tables. It also ensures that the built-in (native) filesystem is not
+ *	removable, although we may wish to change that decision in the future
+ *	to allow a smaller Tcl core, in which the native filesystem is not
+ *	used at all (we could, say, initialise Tcl completely over a network
+ *	connection).
+ *
+ * Results:
+ *	TCL_OK if the function pointer was successfully removed, TCL_ERROR
+ *	otherwise.
+ *
+ * Side effects:
+ *	Memory may be deallocated (or will be later, once no "path" objects
+ *	refer to this filesystem), but the list of registered filesystems is
+ *	updated immediately.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_FSUnregister(
+    const Tcl_Filesystem *fsPtr)	/* The filesystem record to remove. */
+{
+    int retVal = TCL_ERROR;
+    FilesystemRecord *fsRecPtr;
+
+    Tcl_MutexLock(&filesystemMutex);
+
+    /*
+     * Traverse the 'filesystemList' looking for the particular node whose
+     * 'fsPtr' member matches 'fsPtr' and remove that one from the list.
+     * Ensure that the "default" node cannot be removed.
+     */
+
+    fsRecPtr = filesystemList;
+    while ((retVal == TCL_ERROR) && (fsRecPtr != &nativeFilesystemRecord)) {
+	if (fsRecPtr->fsPtr == fsPtr) {
+	    if (fsRecPtr->prevPtr) {
+		fsRecPtr->prevPtr->nextPtr = fsRecPtr->nextPtr;
+	    } else {
+		filesystemList = fsRecPtr->nextPtr;
+	    }
+	    if (fsRecPtr->nextPtr) {
+		fsRecPtr->nextPtr->prevPtr = fsRecPtr->prevPtr;
+	    }
+
+	    /*
+	     * Increment the filesystem epoch counter, since existing paths
+	     * might conceivably now belong to different filesystems. This
+	     * should also ensure that paths which have cached the filesystem
+	     * which is about to be deleted do not reference that filesystem
+	     * (which would of course lead to memory exceptions).
+	     */
+
+	    if (++theFilesystemEpoch == 0) {
+		++theFilesystemEpoch;
+	    }
+
+	    ckfree(fsRecPtr);
+
+	    retVal = TCL_OK;
+	} else {
+	    fsRecPtr = fsRecPtr->nextPtr;
+	}
+    }
+
+    Tcl_MutexUnlock(&filesystemMutex);
+    return retVal;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_FSMatchInDirectory --
+ *
+ *	This routine is used by the globbing code to search a directory for
+ *	all files which match a given pattern. The appropriate function for
+ *	the filesystem to which pathPtr belongs will be called. If pathPtr
+ *	does not belong to any filesystem and if it is NULL or the empty
+ *	string, then we assume the pattern is to be matched in the current
+ *	working directory. To avoid have the Tcl_FSMatchInDirectoryProc for
+ *	each filesystem from having to deal with this issue, we create a
+ *	pathPtr on the fly (equal to the cwd), and then remove it from the
+ *	results returned. This makes filesystems easy to write, since they can
+ *	assume the pathPtr passed to them is an ordinary path. In fact this
+ *	means we could remove such special case handling from Tcl's native
+ *	filesystems.
+ *
+ *	If 'pattern' is NULL, then pathPtr is assumed to be a fully specified
+ *	path of a single file/directory which must be checked for existence
+ *	and correct type.
+ *
+ * Results:
+ *
+ *	The return value is a standard Tcl result indicating whether an error
+ *	occurred in globbing. Error messages are placed in interp, but good
+ *	results are placed in the resultPtr given.
+ *
+ *	Recursive searches, e.g.
+ *		glob -dir $dir -join * pkgIndex.tcl
+ *	which must recurse through each directory matching '*' are handled
+ *	internally by Tcl, by passing specific flags in a modified 'types'
+ *	parameter. This means the actual filesystem only ever sees patterns
+ *	which match in a single directory.
+ *
+ * Side effects:
+ *	The interpreter may have an error message inserted into it.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_FSMatchInDirectory(
+    Tcl_Interp *interp,		/* Interpreter to receive error messages, but
+				 * may be NULL. */
+    Tcl_Obj *resultPtr,		/* List object to receive results. */
+    Tcl_Obj *pathPtr,		/* Contains path to directory to search. */
+    const char *pattern,	/* Pattern to match against. */
+    Tcl_GlobTypeData *types)	/* Object containing list of acceptable types.
+				 * May be NULL. In particular the directory
+				 * flag is very important. */
+{
+    const Tcl_Filesystem *fsPtr;
+    Tcl_Obj *cwd, *tmpResultPtr, **elemsPtr;
+    int resLength, i, ret = -1;
+
+    if (types != NULL && (types->type & TCL_GLOB_TYPE_MOUNT)) {
+	/*
+	 * We don't currently allow querying of mounts by external code (a
+	 * valuable future step), so since we're the only function that
+	 * actually knows about mounts, this means we're being called
+	 * recursively by ourself. Return no matches.
+	 */
+
+	return TCL_OK;
+    }
+
+    if (pathPtr != NULL) {
+	fsPtr = Tcl_FSGetFileSystemForPath(pathPtr);
+    } else {
+	fsPtr = NULL;
+    }
+
+    /*
+     * Check if we've successfully mapped the path to a filesystem within
+     * which to search.
+     */
+
+    if (fsPtr != NULL) {
+	if (fsPtr->matchInDirectoryProc == NULL) {
+	    Tcl_SetErrno(ENOENT);
+	    return -1;
+	}
+	ret = fsPtr->matchInDirectoryProc(interp, resultPtr, pathPtr, pattern,
+		types);
+	if (ret == TCL_OK && pattern != NULL) {
+	    FsAddMountsToGlobResult(resultPtr, pathPtr, pattern, types);
+	}
+	return ret;
+    }
+
+    /*
+     * If the path isn't empty, we have no idea how to match files in a
+     * directory which belongs to no known filesystem.
+     */
+
+    if (pathPtr != NULL && TclGetString(pathPtr)[0] != '\0') {
+	Tcl_SetErrno(ENOENT);
+	return -1;
+    }
+
+    /*
+     * We have an empty or NULL path. This is defined to mean we must search
+     * for files within the current 'cwd'. We therefore use that, but then
+     * since the proc we call will return results which include the cwd we
+     * must then trim it off the front of each path in the result. We choose
+     * to deal with this here (in the generic code), since if we don't, every
+     * single filesystem's implementation of Tcl_FSMatchInDirectory will have
+     * to deal with it for us.
+     */
+
+    cwd = Tcl_FSGetCwd(NULL);
+    if (cwd == NULL) {
+	if (interp != NULL) {
+	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		    "glob couldn't determine the current working directory",
+		    -1));
+	}
+	return TCL_ERROR;
+    }
+
+    fsPtr = Tcl_FSGetFileSystemForPath(cwd);
+    if (fsPtr != NULL && fsPtr->matchInDirectoryProc != NULL) {
+	TclNewObj(tmpResultPtr);
+	Tcl_IncrRefCount(tmpResultPtr);
+	ret = fsPtr->matchInDirectoryProc(interp, tmpResultPtr, cwd, pattern,
+		types);
+	if (ret == TCL_OK) {
+	    FsAddMountsToGlobResult(tmpResultPtr, cwd, pattern, types);
+
+	    /*
+	     * Note that we know resultPtr and tmpResultPtr are distinct.
+	     */
+
+	    ret = Tcl_ListObjGetElements(interp, tmpResultPtr,
+		    &resLength, &elemsPtr);
+	    for (i=0 ; ret==TCL_OK && i<resLength ; i++) {
+		ret = Tcl_ListObjAppendElement(interp, resultPtr,
+			TclFSMakePathRelative(interp, elemsPtr[i], cwd));
+	    }
+	}
+	TclDecrRefCount(tmpResultPtr);
+    }
+    Tcl_DecrRefCount(cwd);
+    return ret;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * FsAddMountsToGlobResult --
+ *
+ *	This routine is used by the globbing code to take the results of a
+ *	directory listing and add any mounted paths to that listing. This is
+ *	required so that simple things like 'glob *' merge mounts and listings
+ *	correctly.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Modifies the resultPtr.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+FsAddMountsToGlobResult(
+    Tcl_Obj *resultPtr,		/* The current list of matching paths; must
+				 * not be shared! */
+    Tcl_Obj *pathPtr,		/* The directory in question. */
+    const char *pattern,	/* Pattern to match against. */
+    Tcl_GlobTypeData *types)	/* Object containing list of acceptable types.
+				 * May be NULL. In particular the directory
+				 * flag is very important. */
+{
+    int mLength, gLength, i;
+    int dir = (types == NULL || (types->type & TCL_GLOB_TYPE_DIR));
+    Tcl_Obj *mounts = FsListMounts(pathPtr, pattern);
+
+    if (mounts == NULL) {
+	return;
+    }
+
+    if (Tcl_ListObjLength(NULL, mounts, &mLength) != TCL_OK || mLength == 0) {
+	goto endOfMounts;
+    }
+    if (Tcl_ListObjLength(NULL, resultPtr, &gLength) != TCL_OK) {
+	goto endOfMounts;
+    }
+    for (i=0 ; i<mLength ; i++) {
+	Tcl_Obj *mElt;
+	int j;
+	int found = 0;
+
+	Tcl_ListObjIndex(NULL, mounts, i, &mElt);
+
+	for (j=0 ; j<gLength ; j++) {
+	    Tcl_Obj *gElt;
+
+	    Tcl_ListObjIndex(NULL, resultPtr, j, &gElt);
+	    if (Tcl_FSEqualPaths(mElt, gElt)) {
+		found = 1;
+		if (!dir) {
+		    /*
+		     * We don't want to list this.
+		     */
+
+		    Tcl_ListObjReplace(NULL, resultPtr, j, 1, 0, NULL);
+		    gLength--;
+		}
+		break;		/* Break out of for loop. */
+	    }
+	}
+	if (!found && dir) {
+	    Tcl_Obj *norm;
+	    int len, mlen;
+
+	    /*
+	     * We know mElt is absolute normalized and lies inside pathPtr, so
+	     * now we must add to the result the right representation of mElt,
+	     * i.e. the representation which is relative to pathPtr.
+	     */
+
+	    norm = Tcl_FSGetNormalizedPath(NULL, pathPtr);
+	    if (norm != NULL) {
+		const char *path, *mount;
+
+		mount = Tcl_GetStringFromObj(mElt, &mlen);
+		path = Tcl_GetStringFromObj(norm, &len);
+		if (path[len-1] == '/') {
+		    /*
+		     * Deal with the root of the volume.
+		     */
+
+		    len--;
+		}
+		len++; /* account for '/' in the mElt [Bug 1602539] */
+		mElt = TclNewFSPathObj(pathPtr, mount + len, mlen - len);
+		Tcl_ListObjAppendElement(NULL, resultPtr, mElt);
+	    }
+	    /*
+	     * No need to increment gLength, since we don't want to compare
+	     * mounts against mounts.
+	     */
+	}
+    }
+
+  endOfMounts:
+    Tcl_DecrRefCount(mounts);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_FSMountsChanged --
+ *
+ *	Notify the filesystem that the available mounted filesystems (or
+ *	within any one filesystem type, the number or location of mount
+ *	points) have changed.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The global filesystem variable 'theFilesystemEpoch' is incremented.
+ *	The effect of this is to make all cached path representations invalid.
+ *	Clearly it should only therefore be called when it is really required!
+ *	There are a few circumstances when it should be called:
+ *
+ *	(1) when a new filesystem is registered or unregistered. Strictly
+ *	speaking this is only necessary if the new filesystem accepts file
+ *	paths as is (normally the filesystem itself is really a shell which
+ *	hasn't yet had any mount points established and so its
+ *	'pathInFilesystem' proc will always fail). However, for safety, Tcl
+ *	always calls this for you in these circumstances.
+ *
+ *	(2) when additional mount points are established inside any existing
+ *	filesystem (except the native fs)
+ *
+ *	(3) when any filesystem (except the native fs) changes the list of
+ *	available volumes.
+ *
+ *	(4) when the mapping from a string representation of a file to a full,
+ *	normalized path changes. For example, if 'env(HOME)' is modified, then
+ *	any path containing '~' will map to a different filesystem location.
+ *	Therefore all such paths need to have their internal representation
+ *	invalidated.
+ *
+ *	Tcl has no control over (2) and (3), so any registered filesystem must
+ *	make sure it calls this function when those situations occur.
+ *
+ *	(Note: the reason for the exception in 2,3 for the native filesystem
+ *	is that the native filesystem by default claims all unknown files even
+ *	if it really doesn't understand them or if they don't exist).
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_FSMountsChanged(
+    const Tcl_Filesystem *fsPtr)
+{
+    /*
+     * We currently don't do anything with this parameter. We could in the
+     * future only invalidate files for this filesystem or otherwise take more
+     * advanced action.
+     */
+
+    (void)fsPtr;
+
+    /*
+     * Increment the filesystem epoch counter, since existing paths might now
+     * belong to different filesystems.
+     */
+
+    Tcl_MutexLock(&filesystemMutex);
+    if (++theFilesystemEpoch == 0) {
+	++theFilesystemEpoch;
+    }
+    Tcl_MutexUnlock(&filesystemMutex);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_FSData --
+ *
+ *	Retrieve the clientData field for the filesystem given, or NULL if
+ *	that filesystem is not registered.
+ *
+ * Results:
+ *	A clientData value, or NULL. Note that if the filesystem was
+ *	registered with a NULL clientData field, this function will return
+ *	that NULL value.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+ClientData
+Tcl_FSData(
+    const Tcl_Filesystem *fsPtr) /* The filesystem record to query. */
+{
+    ClientData retVal = NULL;
+    FilesystemRecord *fsRecPtr = FsGetFirstFilesystem();
+
+    /*
+     * Traverse the list of filesystems look for a particular one. If found,
+     * return that filesystem's clientData (originally provided when calling
+     * Tcl_FSRegister).
+     */
+
+    while ((retVal == NULL) && (fsRecPtr != NULL)) {
+	if (fsRecPtr->fsPtr == fsPtr) {
+	    retVal = fsRecPtr->clientData;
+	}
+	fsRecPtr = fsRecPtr->nextPtr;
+    }
+
+    return retVal;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * TclFSNormalizeToUniquePath --
+ *
+ *	Takes a path specification containing no ../, ./ sequences, and
+ *	converts it into a unique path for the given platform. On Unix, this
+ *	means the path must be free of symbolic links/aliases, and on Windows
+ *	it means we want the long form, with that long form's case-dependence
+ *	(which gives us a unique, case-dependent path).
+ *
+ * Results:
+ *	The pathPtr is modified in place. The return value is the last byte
+ *	offset which was recognised in the path string.
+ *
+ * Side effects:
+ *	None (beyond the memory allocation for the result).
+ *
+ * Special notes:
+ *	If the filesystem-specific normalizePathProcs can re-introduce ../, ./
+ *	sequences into the path, then this function will not return the
+ *	correct result. This may be possible with symbolic links on unix.
+ *
+ *	Important assumption: if startAt is non-zero, it must point to a
+ *	directory separator that we know exists and is already normalized (so
+ *	it is important not to point to the char just after the separator).
+ *
+ *---------------------------------------------------------------------------
+ */
+
+int
+TclFSNormalizeToUniquePath(
+    Tcl_Interp *interp,		/* Used for error messages. */
+    Tcl_Obj *pathPtr,		/* The path to normalize in place. */
+    int startAt)		/* Start at this char-offset. */
+{
+    FilesystemRecord *fsRecPtr, *firstFsRecPtr;
+
+    /*
+     * Call each of the "normalise path" functions in succession. This is a
+     * special case, in which if we have a native filesystem handler, we call
+     * it first. This is because the root of Tcl's filesystem is always a
+     * native filesystem (i.e. '/' on unix is native).
+     */
+
+    firstFsRecPtr = FsGetFirstFilesystem();
+
+    Claim();
+    for (fsRecPtr=firstFsRecPtr; fsRecPtr!=NULL; fsRecPtr=fsRecPtr->nextPtr) {
+	if (fsRecPtr->fsPtr != &tclNativeFilesystem) {
+	    continue;
+	}
+
+	/*
+	 * TODO: Assume that we always find the native file system; it should
+	 * always be there...
+	 */
+
+	if (fsRecPtr->fsPtr->normalizePathProc != NULL) {
+	    startAt = fsRecPtr->fsPtr->normalizePathProc(interp, pathPtr,
+		    startAt);
+	}
+	break;
+    }
+
+    for (fsRecPtr=firstFsRecPtr; fsRecPtr!=NULL; fsRecPtr=fsRecPtr->nextPtr) {
+	/*
+	 * Skip the native system next time through.
+	 */
+
+	if (fsRecPtr->fsPtr == &tclNativeFilesystem) {
+	    continue;
+	}
+
+	if (fsRecPtr->fsPtr->normalizePathProc != NULL) {
+	    startAt = fsRecPtr->fsPtr->normalizePathProc(interp, pathPtr,
+		    startAt);
+	}
+
+	/*
+	 * We could add an efficiency check like this:
+	 *		if (retVal == length-of(pathPtr)) {break;}
+	 * but there's not much benefit.
+	 */
+    }
+    Disclaim();
+
+    return startAt;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * TclGetOpenMode --
+ *
+ *	This routine is an obsolete, limited version of TclGetOpenModeEx()
+ *	below. It exists only to satisfy any extensions imprudently using it
+ *	via Tcl's internal stubs table.
+ *
+ * Results:
+ *	Same as TclGetOpenModeEx().
+ *
+ * Side effects:
+ *	Same as TclGetOpenModeEx().
+ *
+ *---------------------------------------------------------------------------
+ */
+
+int
+TclGetOpenMode(
+    Tcl_Interp *interp,		/* Interpreter to use for error reporting -
+				 * may be NULL. */
+    const char *modeString,	/* Mode string, e.g. "r+" or "RDONLY CREAT" */
+    int *seekFlagPtr)		/* Set this to 1 if the caller should seek to
+				 * EOF during the opening of the file. */
+{
+    int binary = 0;
+    return TclGetOpenModeEx(interp, modeString, seekFlagPtr, &binary);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * TclGetOpenModeEx --
+ *
+ *	Computes a POSIX mode mask for opening a file, from a given string,
+ *	and also sets flags to indicate whether the caller should seek to EOF
+ *	after opening the file, and whether the caller should configure the
+ *	channel for binary data.
+ *
+ * Results:
+ *	On success, returns mode to pass to "open". If an error occurs, the
+ *	return value is -1 and if interp is not NULL, sets interp's result
+ *	object to an error message.
+ *
+ * Side effects:
+ *	Sets the integer referenced by seekFlagPtr to 1 to tell the caller to
+ *	seek to EOF after opening the file, or to 0 otherwise. Sets the
+ *	integer referenced by binaryPtr to 1 to tell the caller to seek to
+ *	configure the channel for binary data, or to 0 otherwise.
+ *
+ * Special note:
+ *	This code is based on a prototype implementation contributed by Mark
+ *	Diekhans.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+int
+TclGetOpenModeEx(
+    Tcl_Interp *interp,		/* Interpreter to use for error reporting -
+				 * may be NULL. */
+    const char *modeString,	/* Mode string, e.g. "r+" or "RDONLY CREAT" */
+    int *seekFlagPtr,		/* Set this to 1 if the caller should seek to
+				 * EOF during the opening of the file. */
+    int *binaryPtr)		/* Set this to 1 if the caller should
+				 * configure the opened channel for binary
+				 * operations. */
+{
+    int mode, modeArgc, c, i, gotRW;
+    const char **modeArgv, *flag;
+#define RW_MODES (O_RDONLY|O_WRONLY|O_RDWR)
+
+    /*
+     * Check for the simpler fopen-like access modes (e.g. "r"). They are
+     * distinguished from the POSIX access modes by the presence of a
+     * lower-case first letter.
+     */
+
+    *seekFlagPtr = 0;
+    *binaryPtr = 0;
+    mode = 0;
+
+    /*
+     * Guard against international characters before using byte oriented
+     * routines.
+     */
+
+    if (!(modeString[0] & 0x80)
+	    && islower(UCHAR(modeString[0]))) { /* INTL: ISO only. */
+	switch (modeString[0]) {
+	case 'r':
+	    mode = O_RDONLY;
+	    break;
+	case 'w':
+	    mode = O_WRONLY|O_CREAT|O_TRUNC;
+	    break;
+	case 'a':
+	    /*
+	     * Added O_APPEND for proper automatic seek-to-end-on-write by the
+	     * OS. [Bug 680143]
+	     */
+
+	    mode = O_WRONLY|O_CREAT|O_APPEND;
+	    *seekFlagPtr = 1;
+	    break;
+	default:
+	    goto error;
+	}
+	i = 1;
+	while (i<3 && modeString[i]) {
+	    if (modeString[i] == modeString[i-1]) {
+		goto error;
+	    }
+	    switch (modeString[i++]) {
+	    case '+':
+		/*
+		 * Must remove the O_APPEND flag so that the seek command
+		 * works. [Bug 1773127]
+		 */
+
+		mode &= ~(O_RDONLY|O_WRONLY|O_APPEND);
+		mode |= O_RDWR;
+		break;
+	    case 'b':
+		*binaryPtr = 1;
+		break;
+	    default:
+		goto error;
+	    }
+	}
+	if (modeString[i] != 0) {
+	    goto error;
+	}
+	return mode;
+
+    error:
+	*seekFlagPtr = 0;
+	*binaryPtr = 0;
+	if (interp != NULL) {
+	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		    "illegal access mode \"%s\"", modeString));
+	}
+	return -1;
+    }
+
+    /*
+     * The access modes are specified using a list of POSIX modes such as
+     * O_CREAT.
+     *
+     * IMPORTANT NOTE: We rely on Tcl_SplitList working correctly when a NULL
+     * interpreter is passed in.
+     */
+
+    if (Tcl_SplitList(interp, modeString, &modeArgc, &modeArgv) != TCL_OK) {
+	if (interp != NULL) {
+	    Tcl_AddErrorInfo(interp,
+		    "\n    while processing open access modes \"");
+	    Tcl_AddErrorInfo(interp, modeString);
+	    Tcl_AddErrorInfo(interp, "\"");
+	}
+	return -1;
+    }
+
+    gotRW = 0;
+    for (i = 0; i < modeArgc; i++) {
+	flag = modeArgv[i];
+	c = flag[0];
+	if ((c == 'R') && (strcmp(flag, "RDONLY") == 0)) {
+	    mode = (mode & ~RW_MODES) | O_RDONLY;
+	    gotRW = 1;
+	} else if ((c == 'W') && (strcmp(flag, "WRONLY") == 0)) {
+	    mode = (mode & ~RW_MODES) | O_WRONLY;
+	    gotRW = 1;
+	} else if ((c == 'R') && (strcmp(flag, "RDWR") == 0)) {
+	    mode = (mode & ~RW_MODES) | O_RDWR;
+	    gotRW = 1;
+	} else if ((c == 'A') && (strcmp(flag, "APPEND") == 0)) {
+	    mode |= O_APPEND;
+	    *seekFlagPtr = 1;
+	} else if ((c == 'C') && (strcmp(flag, "CREAT") == 0)) {
+	    mode |= O_CREAT;
+	} else if ((c == 'E') && (strcmp(flag, "EXCL") == 0)) {
+	    mode |= O_EXCL;
+
+	} else if ((c == 'N') && (strcmp(flag, "NOCTTY") == 0)) {
+#ifdef O_NOCTTY
+	    mode |= O_NOCTTY;
+#else
+	    if (interp != NULL) {
+		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+			"access mode \"%s\" not supported by this system",
+			flag));
+	    }
+	    ckfree(modeArgv);
+	    return -1;
+#endif
+
+	} else if ((c == 'N') && (strcmp(flag, "NONBLOCK") == 0)) {
+#ifdef O_NONBLOCK
+	    mode |= O_NONBLOCK;
+#else
+	    if (interp != NULL) {
+		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+			"access mode \"%s\" not supported by this system",
+			flag));
+	    }
+	    ckfree(modeArgv);
+	    return -1;
+#endif
+
+	} else if ((c == 'T') && (strcmp(flag, "TRUNC") == 0)) {
+	    mode |= O_TRUNC;
+	} else if ((c == 'B') && (strcmp(flag, "BINARY") == 0)) {
+	    *binaryPtr = 1;
+	} else {
+
+	    if (interp != NULL) {
+		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+			"invalid access mode \"%s\": must be RDONLY, WRONLY, "
+			"RDWR, APPEND, BINARY, CREAT, EXCL, NOCTTY, NONBLOCK,"
+			" or TRUNC", flag));
+	    }
+	    ckfree(modeArgv);
+	    return -1;
+	}
+    }
+
+    ckfree(modeArgv);
+
+    if (!gotRW) {
+	if (interp != NULL) {
+	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		    "access mode must include either RDONLY, WRONLY, or RDWR",
+		    -1));
+	}
+	return -1;
+    }
+    return mode;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_FSEvalFile, Tcl_FSEvalFileEx, TclNREvalFile --
+ *
+ *	Read in a file and process the entire file as one gigantic Tcl
+ *	command. Tcl_FSEvalFile is Tcl_FSEvalFileEx without encoding argument.
+ *	TclNREvalFile is an NRE-enabled version of Tcl_FSEvalFileEx.
+ *
+ * Results:
+ *	A standard Tcl result, which is either the result of executing the
+ *	file or an error indicating why the file couldn't be read.
+ *
+ * Side effects:
+ *	Depends on the commands in the file. During the evaluation of the
+ *	contents of the file, iPtr->scriptFile is made to point to pathPtr
+ *	(the old value is cached and replaced when this function returns).
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_FSEvalFile(
+    Tcl_Interp *interp,		/* Interpreter in which to process file. */
+    Tcl_Obj *pathPtr)		/* Path of file to process. Tilde-substitution
+				 * will be performed on this name. */
+{
+    return Tcl_FSEvalFileEx(interp, pathPtr, NULL);
+}
+
+int
+Tcl_FSEvalFileEx(
+    Tcl_Interp *interp,		/* Interpreter in which to process file. */
+    Tcl_Obj *pathPtr,		/* Path of file to process. Tilde-substitution
+				 * will be performed on this name. */
+    const char *encodingName)	/* If non-NULL, then use this encoding for the
+				 * file. NULL means use the system encoding. */
+{
+    int length, result = TCL_ERROR;
+    Tcl_StatBuf statBuf;
+    Tcl_Obj *oldScriptFile;
+    Interp *iPtr;
+    const char *string;
+    Tcl_Channel chan;
+    Tcl_Obj *objPtr;
+
+    if (Tcl_FSGetNormalizedPath(interp, pathPtr) == NULL) {
+	return result;
+    }
+
+    if (Tcl_FSStat(pathPtr, &statBuf) == -1) {
+	Tcl_SetErrno(errno);
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		"couldn't read file \"%s\": %s",
+		Tcl_GetString(pathPtr), Tcl_PosixError(interp)));
+	return result;
+    }
+    chan = Tcl_FSOpenFileChannel(interp, pathPtr, "r", 0644);
+    if (chan == NULL) {
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		"couldn't read file \"%s\": %s",
+		Tcl_GetString(pathPtr), Tcl_PosixError(interp)));
+	return result;
+    }
+
+    /*
+     * The eofchar is \32 (^Z). This is the usual on Windows, but we effect
+     * this cross-platform to allow for scripted documents. [Bug: 2040]
+     */
+
+    Tcl_SetChannelOption(interp, chan, "-eofchar", "\32");
+
+    /*
+     * If the encoding is specified, set it for the channel. Else don't touch
+     * it (and use the system encoding) Report error on unknown encoding.
+     */
+
+    if (encodingName != NULL) {
+	if (Tcl_SetChannelOption(interp, chan, "-encoding", encodingName)
+		!= TCL_OK) {
+	    Tcl_Close(interp,chan);
+	    return result;
+	}
+    }
+
+    objPtr = Tcl_NewObj();
+    Tcl_IncrRefCount(objPtr);
+
+    /*
+     * Try to read first character of stream, so we can check for utf-8 BOM to
+     * be handled especially.
+     */
+
+    if (Tcl_ReadChars(chan, objPtr, 1, 0) < 0) {
+	Tcl_Close(interp, chan);
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		"couldn't read file \"%s\": %s",
+		Tcl_GetString(pathPtr), Tcl_PosixError(interp)));
+	goto end;
+    }
+    string = Tcl_GetString(objPtr);
+
+    /*
+     * If first character is not a BOM, append the remaining characters,
+     * otherwise replace them. [Bug 3466099]
+     */
+
+    if (Tcl_ReadChars(chan, objPtr, -1,
+	    memcmp(string, "\xef\xbb\xbf", 3)) < 0) {
+	Tcl_Close(interp, chan);
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		"couldn't read file \"%s\": %s",
+		Tcl_GetString(pathPtr), Tcl_PosixError(interp)));
+	goto end;
+    }
+
+    if (Tcl_Close(interp, chan) != TCL_OK) {
+	goto end;
+    }
+
+    iPtr = (Interp *) interp;
+    oldScriptFile = iPtr->scriptFile;
+    iPtr->scriptFile = pathPtr;
+    Tcl_IncrRefCount(iPtr->scriptFile);
+    string = Tcl_GetStringFromObj(objPtr, &length);
+
+    /*
+     * TIP #280 Force the evaluator to open a frame for a sourced file.
+     */
+
+    iPtr->evalFlags |= TCL_EVAL_FILE;
+    result = TclEvalEx(interp, string, length, 0, 1, NULL, string);
+
+    /*
+     * Now we have to be careful; the script may have changed the
+     * iPtr->scriptFile value, so we must reset it without assuming it still
+     * points to 'pathPtr'.
+     */
+
+    if (iPtr->scriptFile != NULL) {
+	Tcl_DecrRefCount(iPtr->scriptFile);
+    }
+    iPtr->scriptFile = oldScriptFile;
+
+    if (result == TCL_RETURN) {
+	result = TclUpdateReturnInfo(iPtr);
+    } else if (result == TCL_ERROR) {
+	/*
+	 * Record information telling where the error occurred.
+	 */
+
+	const char *pathString = Tcl_GetStringFromObj(pathPtr, &length);
+	int limit = 150;
+	int overflow = (length > limit);
+
+	Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf(
+		"\n    (file \"%.*s%s\" line %d)",
+		(overflow ? limit : length), pathString,
+		(overflow ? "..." : ""), Tcl_GetErrorLine(interp)));
+    }
+
+  end:
+    Tcl_DecrRefCount(objPtr);
+    return result;
+}
+
+int
+TclNREvalFile(
+    Tcl_Interp *interp,		/* Interpreter in which to process file. */
+    Tcl_Obj *pathPtr,		/* Path of file to process. Tilde-substitution
+				 * will be performed on this name. */
+    const char *encodingName)	/* If non-NULL, then use this encoding for the
+				 * file. NULL means use the system encoding. */
+{
+    Tcl_StatBuf statBuf;
+    Tcl_Obj *oldScriptFile, *objPtr;
+    Interp *iPtr;
+    Tcl_Channel chan;
+    const char *string;
+
+    if (Tcl_FSGetNormalizedPath(interp, pathPtr) == NULL) {
+	return TCL_ERROR;
+    }
+
+    if (Tcl_FSStat(pathPtr, &statBuf) == -1) {
+	Tcl_SetErrno(errno);
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		"couldn't read file \"%s\": %s",
+		Tcl_GetString(pathPtr), Tcl_PosixError(interp)));
+	return TCL_ERROR;
+    }
+    chan = Tcl_FSOpenFileChannel(interp, pathPtr, "r", 0644);
+    if (chan == NULL) {
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		"couldn't read file \"%s\": %s",
+		Tcl_GetString(pathPtr), Tcl_PosixError(interp)));
+	return TCL_ERROR;
+    }
+
+    /*
+     * The eofchar is \32 (^Z). This is the usual on Windows, but we effect
+     * this cross-platform to allow for scripted documents. [Bug: 2040]
+     */
+
+    Tcl_SetChannelOption(interp, chan, "-eofchar", "\32");
+
+    /*
+     * If the encoding is specified, set it for the channel. Else don't touch
+     * it (and use the system encoding) Report error on unknown encoding.
+     */
+
+    if (encodingName != NULL) {
+	if (Tcl_SetChannelOption(interp, chan, "-encoding", encodingName)
+		!= TCL_OK) {
+	    Tcl_Close(interp,chan);
+	    return TCL_ERROR;
+	}
+    }
+
+    objPtr = Tcl_NewObj();
+    Tcl_IncrRefCount(objPtr);
+
+    /*
+     * Try to read first character of stream, so we can check for utf-8 BOM to
+     * be handled especially.
+     */
+
+    if (Tcl_ReadChars(chan, objPtr, 1, 0) < 0) {
+	Tcl_Close(interp, chan);
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		"couldn't read file \"%s\": %s",
+		Tcl_GetString(pathPtr), Tcl_PosixError(interp)));
+	Tcl_DecrRefCount(objPtr);
+	return TCL_ERROR;
+    }
+    string = Tcl_GetString(objPtr);
+
+    /*
+     * If first character is not a BOM, append the remaining characters,
+     * otherwise replace them. [Bug 3466099]
+     */
+
+    if (Tcl_ReadChars(chan, objPtr, -1,
+	    memcmp(string, "\xef\xbb\xbf", 3)) < 0) {
+	Tcl_Close(interp, chan);
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		"couldn't read file \"%s\": %s",
+		Tcl_GetString(pathPtr), Tcl_PosixError(interp)));
+	Tcl_DecrRefCount(objPtr);
+	return TCL_ERROR;
+    }
+
+    if (Tcl_Close(interp, chan) != TCL_OK) {
+	Tcl_DecrRefCount(objPtr);
+	return TCL_ERROR;
+    }
+
+    iPtr = (Interp *) interp;
+    oldScriptFile = iPtr->scriptFile;
+    iPtr->scriptFile = pathPtr;
+    Tcl_IncrRefCount(iPtr->scriptFile);
+
+    /*
+     * TIP #280: Force the evaluator to open a frame for a sourced file.
+     */
+
+    iPtr->evalFlags |= TCL_EVAL_FILE;
+    TclNRAddCallback(interp, EvalFileCallback, oldScriptFile, pathPtr, objPtr,
+	    NULL);
+    return TclNREvalObjEx(interp, objPtr, 0, NULL, INT_MIN);
+}
+
+static int
+EvalFileCallback(
+    ClientData data[],
+    Tcl_Interp *interp,
+    int result)
+{
+    Interp *iPtr = (Interp *) interp;
+    Tcl_Obj *oldScriptFile = data[0];
+    Tcl_Obj *pathPtr = data[1];
+    Tcl_Obj *objPtr = data[2];
+
+    /*
+     * Now we have to be careful; the script may have changed the
+     * iPtr->scriptFile value, so we must reset it without assuming it still
+     * points to 'pathPtr'.
+     */
+
+    if (iPtr->scriptFile != NULL) {
+	Tcl_DecrRefCount(iPtr->scriptFile);
+    }
+    iPtr->scriptFile = oldScriptFile;
+
+    if (result == TCL_RETURN) {
+	result = TclUpdateReturnInfo(iPtr);
+    } else if (result == TCL_ERROR) {
+	/*
+	 * Record information telling where the error occurred.
+	 */
+
+	int length;
+	const char *pathString = Tcl_GetStringFromObj(pathPtr, &length);
+	const int limit = 150;
+	int overflow = (length > limit);
+
+	Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf(
+		"\n    (file \"%.*s%s\" line %d)",
+		(overflow ? limit : length), pathString,
+		(overflow ? "..." : ""), Tcl_GetErrorLine(interp)));
+    }
+
+    Tcl_DecrRefCount(objPtr);
+    return result;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_GetErrno --
+ *
+ *	Gets the current value of the Tcl error code variable. This is
+ *	currently the global variable "errno" but could in the future change
+ *	to something else.
+ *
+ * Results:
+ *	The value of the Tcl error code variable.
+ *
+ * Side effects:
+ *	None. Note that the value of the Tcl error code variable is UNDEFINED
+ *	if a call to Tcl_SetErrno did not precede this call.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_GetErrno(void)
+{
+    /*
+     * On some platforms, errno is really a thread local (implemented by the C
+     * library).
+     */
+
+    return errno;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_SetErrno --
+ *
+ *	Sets the Tcl error code variable to the supplied value. On some saner
+ *	platforms this is actually a thread-local (this is implemented in the
+ *	C library) but this is *really* unsafe to assume!
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Modifies the value of the Tcl error code variable.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_SetErrno(
+    int err)			/* The new value. */
+{
+    /*
+     * On some platforms, errno is really a thread local (implemented by the C
+     * library).
+     */
+
+    errno = err;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_PosixError --
+ *
+ *	This function is typically called after UNIX kernel calls return
+ *	errors. It stores machine-readable information about the error in
+ *	errorCode field of interp and returns an information string for the
+ *	caller's use.
+ *
+ * Results:
+ *	The return value is a human-readable string describing the error.
+ *
+ * Side effects:
+ *	The errorCode field of the interp is set.
+ *
+ *----------------------------------------------------------------------
+ */
+
+const char *
+Tcl_PosixError(
+    Tcl_Interp *interp)		/* Interpreter whose errorCode field is to be
+				 * set. */
+{
+    const char *id, *msg;
+
+    msg = Tcl_ErrnoMsg(errno);
+    id = Tcl_ErrnoId();
+    if (interp) {
+	Tcl_SetErrorCode(interp, "POSIX", id, msg, NULL);
+    }
+    return msg;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_FSStat --
+ *
+ *	This function replaces the library version of stat and lsat.
+ *
+ *	The appropriate function for the filesystem to which pathPtr belongs
+ *	will be called.
+ *
+ * Results:
+ *	See stat documentation.
+ *
+ * Side effects:
+ *	See stat documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_FSStat(
+    Tcl_Obj *pathPtr,		/* Path of file to stat (in current CP). */
+    Tcl_StatBuf *buf)		/* Filled with results of stat call. */
+{
+    const Tcl_Filesystem *fsPtr = Tcl_FSGetFileSystemForPath(pathPtr);
+
+    if (fsPtr != NULL && fsPtr->statProc != NULL) {
+	return fsPtr->statProc(pathPtr, buf);
+    }
+    Tcl_SetErrno(ENOENT);
+    return -1;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_FSLstat --
+ *
+ *	This function replaces the library version of lstat. The appropriate
+ *	function for the filesystem to which pathPtr belongs will be called.
+ *	If no 'lstat' function is listed, but a 'stat' function is, then Tcl
+ *	will fall back on the stat function.
+ *
+ * Results:
+ *	See lstat documentation.
+ *
+ * Side effects:
+ *	See lstat documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_FSLstat(
+    Tcl_Obj *pathPtr,		/* Path of file to stat (in current CP). */
+    Tcl_StatBuf *buf)		/* Filled with results of stat call. */
+{
+    const Tcl_Filesystem *fsPtr = Tcl_FSGetFileSystemForPath(pathPtr);
+
+    if (fsPtr != NULL) {
+	if (fsPtr->lstatProc != NULL) {
+	    return fsPtr->lstatProc(pathPtr, buf);
+	}
+	if (fsPtr->statProc != NULL) {
+	    return fsPtr->statProc(pathPtr, buf);
+	}
+    }
+    Tcl_SetErrno(ENOENT);
+    return -1;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_FSAccess --
+ *
+ *	This function replaces the library version of access. The appropriate
+ *	function for the filesystem to which pathPtr belongs will be called.
+ *
+ * Results:
+ *	See access documentation.
+ *
+ * Side effects:
+ *	See access documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_FSAccess(
+    Tcl_Obj *pathPtr,		/* Path of file to access (in current CP). */
+    int mode)			/* Permission setting. */
+{
+    const Tcl_Filesystem *fsPtr = Tcl_FSGetFileSystemForPath(pathPtr);
+
+    if (fsPtr != NULL && fsPtr->accessProc != NULL) {
+	return fsPtr->accessProc(pathPtr, mode);
+    }
+    Tcl_SetErrno(ENOENT);
+    return -1;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_FSOpenFileChannel --
+ *
+ *	The appropriate function for the filesystem to which pathPtr belongs
+ *	will be called.
+ *
+ * Results:
+ *	The new channel or NULL, if the named file could not be opened.
+ *
+ * Side effects:
+ *	May open the channel and may cause creation of a file on the file
+ *	system.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_Channel
+Tcl_FSOpenFileChannel(
+    Tcl_Interp *interp,		/* Interpreter for error reporting; can be
+				 * NULL. */
+    Tcl_Obj *pathPtr,		/* Name of file to open. */
+    const char *modeString,	/* A list of POSIX open modes or a string such
+				 * as "rw". */
+    int permissions)		/* If the open involves creating a file, with
+				 * what modes to create it? */
+{
+    const Tcl_Filesystem *fsPtr;
+    Tcl_Channel retVal = NULL;
+
+    /*
+     * We need this just to ensure we return the correct error messages under
+     * some circumstances.
+     */
+
+    if (Tcl_FSGetNormalizedPath(interp, pathPtr) == NULL) {
+	return NULL;
+    }
+
+    fsPtr = Tcl_FSGetFileSystemForPath(pathPtr);
+    if (fsPtr != NULL && fsPtr->openFileChannelProc != NULL) {
+	int mode, seekFlag, binary;
+
+	/*
+	 * Parse the mode, picking up whether we want to seek to start with
+	 * and/or set the channel automatically into binary mode.
+	 */
+
+	mode = TclGetOpenModeEx(interp, modeString, &seekFlag, &binary);
+	if (mode == -1) {
+	    return NULL;
+	}
+
+	/*
+	 * Do the actual open() call.
+	 */
+
+	retVal = fsPtr->openFileChannelProc(interp, pathPtr, mode,
+		permissions);
+	if (retVal == NULL) {
+	    return NULL;
+	}
+
+	/*
+	 * Apply appropriate flags parsed out above.
+	 */
+
+	if (seekFlag && Tcl_Seek(retVal, (Tcl_WideInt) 0, SEEK_END)
+		< (Tcl_WideInt) 0) {
+	    if (interp != NULL) {
+		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+			"could not seek to end of file while opening \"%s\": %s",
+			Tcl_GetString(pathPtr), Tcl_PosixError(interp)));
+	    }
+	    Tcl_Close(NULL, retVal);
+	    return NULL;
+	}
+	if (binary) {
+	    Tcl_SetChannelOption(interp, retVal, "-translation", "binary");
+	}
+	return retVal;
+    }
+
+    /*
+     * File doesn't belong to any filesystem that can open it.
+     */
+
+    Tcl_SetErrno(ENOENT);
+    if (interp != NULL) {
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		"couldn't open \"%s\": %s",
+		Tcl_GetString(pathPtr), Tcl_PosixError(interp)));
+    }
+    return NULL;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_FSUtime --
+ *
+ *	This function replaces the library version of utime. The appropriate
+ *	function for the filesystem to which pathPtr belongs will be called.
+ *
+ * Results:
+ *	See utime documentation.
+ *
+ * Side effects:
+ *	See utime documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_FSUtime(
+    Tcl_Obj *pathPtr,		/* File to change access/modification
+				 * times. */
+    struct utimbuf *tval)	/* Structure containing access/modification
+				 * times to use. Should not be modified. */
+{
+    const Tcl_Filesystem *fsPtr = Tcl_FSGetFileSystemForPath(pathPtr);
+
+    if (fsPtr != NULL && fsPtr->utimeProc != NULL) {
+	return fsPtr->utimeProc(pathPtr, tval);
+    }
+    /* TODO: set errno here? Tcl_SetErrno(ENOENT); */
+    return -1;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * NativeFileAttrStrings --
+ *
+ *	This function implements the platform dependent 'file attributes'
+ *	subcommand, for the native filesystem, for listing the set of possible
+ *	attribute strings. This function is part of Tcl's native filesystem
+ *	support, and is placed here because it is shared by Unix and Windows
+ *	code.
+ *
+ * Results:
+ *	An array of strings
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static const char *const *
+NativeFileAttrStrings(
+    Tcl_Obj *pathPtr,
+    Tcl_Obj **objPtrRef)
+{
+    return tclpFileAttrStrings;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * NativeFileAttrsGet --
+ *
+ *	This function implements the platform dependent 'file attributes'
+ *	subcommand, for the native filesystem, for 'get' operations. This
+ *	function is part of Tcl's native filesystem support, and is placed
+ *	here because it is shared by Unix and Windows code.
+ *
+ * Results:
+ *	Standard Tcl return code. The object placed in objPtrRef (if TCL_OK
+ *	was returned) is likely to have a refCount of zero. Either way we must
+ *	either store it somewhere (e.g. the Tcl result), or Incr/Decr its
+ *	refCount to ensure it is properly freed.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+NativeFileAttrsGet(
+    Tcl_Interp *interp,		/* The interpreter for error reporting. */
+    int index,			/* index of the attribute command. */
+    Tcl_Obj *pathPtr,		/* path of file we are operating on. */
+    Tcl_Obj **objPtrRef)	/* for output. */
+{
+    return tclpFileAttrProcs[index].getProc(interp, index, pathPtr,objPtrRef);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * NativeFileAttrsSet --
+ *
+ *	This function implements the platform dependent 'file attributes'
+ *	subcommand, for the native filesystem, for 'set' operations. This
+ *	function is part of Tcl's native filesystem support, and is placed
+ *	here because it is shared by Unix and Windows code.
+ *
+ * Results:
+ *	Standard Tcl return code.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+NativeFileAttrsSet(
+    Tcl_Interp *interp,		/* The interpreter for error reporting. */
+    int index,			/* index of the attribute command. */
+    Tcl_Obj *pathPtr,		/* path of file we are operating on. */
+    Tcl_Obj *objPtr)		/* set to this value. */
+{
+    return tclpFileAttrProcs[index].setProc(interp, index, pathPtr, objPtr);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_FSFileAttrStrings --
+ *
+ *	This function implements part of the hookable 'file attributes'
+ *	subcommand. The appropriate function for the filesystem to which
+ *	pathPtr belongs will be called.
+ *
+ * Results:
+ *	The called function may either return an array of strings, or may
+ *	instead return NULL and place a Tcl list into the given objPtrRef.
+ *	Tcl will take that list and first increment its refCount before using
+ *	it. On completion of that use, Tcl will decrement its refCount. Hence
+ *	if the list should be disposed of by Tcl when done, it should have a
+ *	refCount of zero, and if the list should not be disposed of, the
+ *	filesystem should ensure it retains a refCount on the object.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+const char *const *
+Tcl_FSFileAttrStrings(
+    Tcl_Obj *pathPtr,
+    Tcl_Obj **objPtrRef)
+{
+    const Tcl_Filesystem *fsPtr = Tcl_FSGetFileSystemForPath(pathPtr);
+
+    if (fsPtr != NULL && fsPtr->fileAttrStringsProc != NULL) {
+	return fsPtr->fileAttrStringsProc(pathPtr, objPtrRef);
+    }
+    Tcl_SetErrno(ENOENT);
+    return NULL;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclFSFileAttrIndex --
+ *
+ *	Helper function for converting an attribute name to an index into the
+ *	attribute table.
+ *
+ * Results:
+ *	Tcl result code, index written to *indexPtr on result==TCL_OK
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclFSFileAttrIndex(
+    Tcl_Obj *pathPtr,		/* File whose attributes are to be indexed
+				 * into. */
+    const char *attributeName,	/* The attribute being looked for. */
+    int *indexPtr)		/* Where to write the found index. */
+{
+    Tcl_Obj *listObj = NULL;
+    const char *const *attrTable;
+
+    /*
+     * Get the attribute table for the file.
+     */
+
+    attrTable = Tcl_FSFileAttrStrings(pathPtr, &listObj);
+    if (listObj != NULL) {
+	Tcl_IncrRefCount(listObj);
+    }
+
+    if (attrTable != NULL) {
+	/*
+	 * It's a constant attribute table, so use T_GIFO.
+	 */
+
+	Tcl_Obj *tmpObj = Tcl_NewStringObj(attributeName, -1);
+	int result;
+
+	result = Tcl_GetIndexFromObj(NULL, tmpObj, attrTable, NULL, TCL_EXACT,
+		indexPtr);
+	TclDecrRefCount(tmpObj);
+	if (listObj != NULL) {
+	    TclDecrRefCount(listObj);
+	}
+	return result;
+    } else if (listObj != NULL) {
+	/*
+	 * It's a non-constant attribute list, so do a literal search.
+	 */
+
+	int i, objc;
+	Tcl_Obj **objv;
+
+	if (Tcl_ListObjGetElements(NULL, listObj, &objc, &objv) != TCL_OK) {
+	    TclDecrRefCount(listObj);
+	    return TCL_ERROR;
+	}
+	for (i=0 ; i<objc ; i++) {
+	    if (!strcmp(attributeName, TclGetString(objv[i]))) {
+		TclDecrRefCount(listObj);
+		*indexPtr = i;
+		return TCL_OK;
+	    }
+	}
+	TclDecrRefCount(listObj);
+	return TCL_ERROR;
+    } else {
+	return TCL_ERROR;
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_FSFileAttrsGet --
+ *
+ *	This function implements read access for the hookable 'file
+ *	attributes' subcommand. The appropriate function for the filesystem to
+ *	which pathPtr belongs will be called.
+ *
+ * Results:
+ *	Standard Tcl return code. The object placed in objPtrRef (if TCL_OK
+ *	was returned) is likely to have a refCount of zero. Either way we must
+ *	either store it somewhere (e.g. the Tcl result), or Incr/Decr its
+ *	refCount to ensure it is properly freed.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_FSFileAttrsGet(
+    Tcl_Interp *interp,		/* The interpreter for error reporting. */
+    int index,			/* index of the attribute command. */
+    Tcl_Obj *pathPtr,		/* filename we are operating on. */
+    Tcl_Obj **objPtrRef)	/* for output. */
+{
+    const Tcl_Filesystem *fsPtr = Tcl_FSGetFileSystemForPath(pathPtr);
+
+    if (fsPtr != NULL && fsPtr->fileAttrsGetProc != NULL) {
+	return fsPtr->fileAttrsGetProc(interp, index, pathPtr, objPtrRef);
+    }
+    Tcl_SetErrno(ENOENT);
+    return -1;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_FSFileAttrsSet --
+ *
+ *	This function implements write access for the hookable 'file
+ *	attributes' subcommand. The appropriate function for the filesystem to
+ *	which pathPtr belongs will be called.
+ *
+ * Results:
+ *	Standard Tcl return code.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_FSFileAttrsSet(
+    Tcl_Interp *interp,		/* The interpreter for error reporting. */
+    int index,			/* index of the attribute command. */
+    Tcl_Obj *pathPtr,		/* filename we are operating on. */
+    Tcl_Obj *objPtr)		/* Input value. */
+{
+    const Tcl_Filesystem *fsPtr = Tcl_FSGetFileSystemForPath(pathPtr);
+
+    if (fsPtr != NULL && fsPtr->fileAttrsSetProc != NULL) {
+	return fsPtr->fileAttrsSetProc(interp, index, pathPtr, objPtr);
+    }
+    Tcl_SetErrno(ENOENT);
+    return -1;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_FSGetCwd --
+ *
+ *	This function replaces the library version of getcwd().
+ *
+ *	Most VFS's will *not* implement a 'cwdProc'. Tcl now maintains its own
+ *	record (in a Tcl_Obj) of the cwd, and an attempt is made to synch this
+ *	with the cwd's containing filesystem, if that filesystem provides a
+ *	cwdProc (e.g. the native filesystem).
+ *
+ *	Note that if Tcl's cwd is not in the native filesystem, then of course
+ *	Tcl's cwd and the native cwd are different: extensions should
+ *	therefore ensure they only access the cwd through this function to
+ *	avoid confusion.
+ *
+ *	If a global cwdPathPtr already exists, it is cached in the thread's
+ *	private data structures and reference to the cached copy is returned,
+ *	subject to a synchronisation attempt in that cwdPathPtr's fs.
+ *
+ *	Otherwise, the chain of functions that have been "inserted" into the
+ *	filesystem will be called in succession until either a value other
+ *	than NULL is returned, or the entire list is visited.
+ *
+ * Results:
+ *	The result is a pointer to a Tcl_Obj specifying the current directory,
+ *	or NULL if the current directory could not be determined. If NULL is
+ *	returned, an error message is left in the interp's result.
+ *
+ *	The result already has its refCount incremented for the caller. When
+ *	it is no longer needed, that refCount should be decremented.
+ *
+ * Side effects:
+ *	Various objects may be freed and allocated.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_Obj *
+Tcl_FSGetCwd(
+    Tcl_Interp *interp)
+{
+    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&fsDataKey);
+
+    if (TclFSCwdPointerEquals(NULL)) {
+	FilesystemRecord *fsRecPtr;
+	Tcl_Obj *retVal = NULL;
+
+	/*
+	 * We've never been called before, try to find a cwd. Call each of the
+	 * "Tcl_GetCwd" function in succession. A non-NULL return value
+	 * indicates the particular function has succeeded.
+	 */
+
+	fsRecPtr = FsGetFirstFilesystem();
+	Claim();
+	for (; (retVal == NULL) && (fsRecPtr != NULL);
+		fsRecPtr = fsRecPtr->nextPtr) {
+	    ClientData retCd;
+	    TclFSGetCwdProc2 *proc2;
+	    if (fsRecPtr->fsPtr->getCwdProc == NULL) {
+		continue;
+	    }
+
+	    if (fsRecPtr->fsPtr->version == TCL_FILESYSTEM_VERSION_1) {
+		retVal = fsRecPtr->fsPtr->getCwdProc(interp);
+		continue;
+	    }
+
+	    proc2 = (TclFSGetCwdProc2 *) fsRecPtr->fsPtr->getCwdProc;
+	    retCd = proc2(NULL);
+	    if (retCd != NULL) {
+		Tcl_Obj *norm;
+
+		/*
+		 * Looks like a new current directory.
+		 */
+
+		retVal = fsRecPtr->fsPtr->internalToNormalizedProc(retCd);
+		Tcl_IncrRefCount(retVal);
+		norm = TclFSNormalizeAbsolutePath(interp,retVal);
+		if (norm != NULL) {
+		    /*
+		     * We found a cwd, which is now in our global storage. We
+		     * must make a copy. Norm already has a refCount of 1.
+		     *
+		     * Threading issue: note that multiple threads at system
+		     * startup could in principle call this function
+		     * simultaneously. They will therefore each set the
+		     * cwdPathPtr independently. That behaviour is a bit
+		     * peculiar, but should be fine. Once we have a cwd, we'll
+		     * always be in the 'else' branch below which is simpler.
+		     */
+
+		    FsUpdateCwd(norm, retCd);
+		    Tcl_DecrRefCount(norm);
+		} else {
+		    fsRecPtr->fsPtr->freeInternalRepProc(retCd);
+		}
+		Tcl_DecrRefCount(retVal);
+		retVal = NULL;
+		Disclaim();
+		goto cdDidNotChange;
+	    } else if (interp != NULL) {
+		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+			"error getting working directory name: %s",
+			Tcl_PosixError(interp)));
+	    }
+	}
+	Disclaim();
+
+	/*
+	 * Now the 'cwd' may NOT be normalized, at least on some platforms.
+	 * For the sake of efficiency, we want a completely normalized cwd at
+	 * all times.
+	 *
+	 * Finally, if retVal is NULL, we do not have a cwd, which could be
+	 * problematic.
+	 */
+
+	if (retVal != NULL) {
+	    Tcl_Obj *norm = TclFSNormalizeAbsolutePath(interp, retVal);
+
+	    if (norm != NULL) {
+		/*
+		 * We found a cwd, which is now in our global storage. We must
+		 * make a copy. Norm already has a refCount of 1.
+		 *
+		 * Threading issue: note that multiple threads at system
+		 * startup could in principle call this function
+		 * simultaneously. They will therefore each set the cwdPathPtr
+		 * independently. That behaviour is a bit peculiar, but should
+		 * be fine. Once we have a cwd, we'll always be in the 'else'
+		 * branch below which is simpler.
+		 */
+
+		ClientData cd = (ClientData) Tcl_FSGetNativePath(norm);
+
+		FsUpdateCwd(norm, TclNativeDupInternalRep(cd));
+		Tcl_DecrRefCount(norm);
+	    }
+	    Tcl_DecrRefCount(retVal);
+	}
+    } else {
+	/*
+	 * We already have a cwd cached, but we want to give the filesystem it
+	 * is in a chance to check whether that cwd has changed, or is perhaps
+	 * no longer accessible. This allows an error to be thrown if, say,
+	 * the permissions on that directory have changed.
+	 */
+
+	const Tcl_Filesystem *fsPtr =
+		Tcl_FSGetFileSystemForPath(tsdPtr->cwdPathPtr);
+	ClientData retCd = NULL;
+	Tcl_Obj *retVal, *norm;
+
+	/*
+	 * If the filesystem couldn't be found, or if no cwd function exists
+	 * for this filesystem, then we simply assume the cached cwd is ok.
+	 * If we do call a cwd, we must watch for errors (if the cwd returns
+	 * NULL). This ensures that, say, on Unix if the permissions of the
+	 * cwd change, 'pwd' does actually throw the correct error in Tcl.
+	 * (This is tested for in the test suite on unix).
+	 */
+
+	if (fsPtr == NULL || fsPtr->getCwdProc == NULL) {
+	    goto cdDidNotChange;
+	}
+
+	if (fsPtr->version == TCL_FILESYSTEM_VERSION_1) {
+	    retVal = fsPtr->getCwdProc(interp);
+	} else {
+	    /*
+	     * New API.
+	     */
+
+	    TclFSGetCwdProc2 *proc2 = (TclFSGetCwdProc2 *) fsPtr->getCwdProc;
+
+	    retCd = proc2(tsdPtr->cwdClientData);
+	    if (retCd == NULL && interp != NULL) {
+		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+			"error getting working directory name: %s",
+			Tcl_PosixError(interp)));
+	    }
+
+	    if (retCd == tsdPtr->cwdClientData) {
+		goto cdDidNotChange;
+	    }
+
+	    /*
+	     * Looks like a new current directory.
+	     */
+
+	    retVal = fsPtr->internalToNormalizedProc(retCd);
+	    Tcl_IncrRefCount(retVal);
+	}
+
+	/*
+	 * Check if the 'cwd' function returned an error; if so, reset the
+	 * cwd.
+	 */
+
+	if (retVal == NULL) {
+	    FsUpdateCwd(NULL, NULL);
+	    goto cdDidNotChange;
+	}
+
+	/*
+	 * Normalize the path.
+	 */
+
+	norm = TclFSNormalizeAbsolutePath(interp, retVal);
+
+	/*
+	 * Check whether cwd has changed from the value previously stored in
+	 * cwdPathPtr. Really 'norm' shouldn't be NULL, but we are careful.
+	 */
+
+	if (norm == NULL) {
+	    /* Do nothing */
+	    if (retCd != NULL) {
+		fsPtr->freeInternalRepProc(retCd);
+	    }
+	} else if (norm == tsdPtr->cwdPathPtr) {
+	    goto cdEqual;
+	} else {
+	    /*
+	     * Note that both 'norm' and 'tsdPtr->cwdPathPtr' are normalized
+	     * paths. Therefore we can be more efficient than calling
+	     * 'Tcl_FSEqualPaths', and in addition avoid a nasty infinite loop
+	     * bug when trying to normalize tsdPtr->cwdPathPtr.
+	     */
+
+	    int len1, len2;
+	    const char *str1, *str2;
+
+	    str1 = Tcl_GetStringFromObj(tsdPtr->cwdPathPtr, &len1);
+	    str2 = Tcl_GetStringFromObj(norm, &len2);
+	    if ((len1 == len2) && (strcmp(str1, str2) == 0)) {
+		/*
+		 * If the paths were equal, we can be more efficient and
+		 * retain the old path object which will probably already be
+		 * shared. In this case we can simply free the normalized path
+		 * we just calculated.
+		 */
+
+	    cdEqual:
+		Tcl_DecrRefCount(norm);
+		if (retCd != NULL) {
+		    fsPtr->freeInternalRepProc(retCd);
+		}
+	    } else {
+		FsUpdateCwd(norm, retCd);
+		Tcl_DecrRefCount(norm);
+	    }
+	}
+	Tcl_DecrRefCount(retVal);
+    }
+
+  cdDidNotChange:
+    if (tsdPtr->cwdPathPtr != NULL) {
+	Tcl_IncrRefCount(tsdPtr->cwdPathPtr);
+    }
+
+    return tsdPtr->cwdPathPtr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_FSChdir --
+ *
+ *	This function replaces the library version of chdir().
+ *
+ *	The path is normalized and then passed to the filesystem which claims
+ *	it.
+ *
+ * Results:
+ *	See chdir() documentation. If successful, we keep a record of the
+ *	successful path in cwdPathPtr for subsequent calls to getcwd.
+ *
+ * Side effects:
+ *	See chdir() documentation. The global cwdPathPtr may change value.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_FSChdir(
+    Tcl_Obj *pathPtr)
+{
+    const Tcl_Filesystem *fsPtr, *oldFsPtr = NULL;
+    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&fsDataKey);
+    int retVal = -1;
+
+    if (tsdPtr->cwdPathPtr != NULL) {
+	oldFsPtr = Tcl_FSGetFileSystemForPath(tsdPtr->cwdPathPtr);
+    }
+    if (Tcl_FSGetNormalizedPath(NULL, pathPtr) == NULL) {
+	Tcl_SetErrno(ENOENT);
+	return retVal;
+    }
+
+    fsPtr = Tcl_FSGetFileSystemForPath(pathPtr);
+    if (fsPtr != NULL) {
+	if (fsPtr->chdirProc != NULL) {
+	    /*
+	     * If this fails, an appropriate errno will have been stored using
+	     * 'Tcl_SetErrno()'.
+	     */
+
+	    retVal = fsPtr->chdirProc(pathPtr);
+	} else {
+	    /*
+	     * Fallback on stat-based implementation.
+	     */
+
+	    Tcl_StatBuf buf;
+
+	    /*
+	     * If the file can be stat'ed and is a directory and is readable,
+	     * then we can chdir. If any of these actions fail, then
+	     * 'Tcl_SetErrno()' should automatically have been called to set
+	     * an appropriate error code.
+	     */
+
+	    if ((Tcl_FSStat(pathPtr, &buf) == 0) && (S_ISDIR(buf.st_mode))
+		    && (Tcl_FSAccess(pathPtr, R_OK) == 0)) {
+		/*
+		 * We allow the chdir.
+		 */
+
+		retVal = 0;
+	    }
+	}
+    } else {
+	Tcl_SetErrno(ENOENT);
+    }
+
+    /*
+     * The cwd changed, or an error was thrown. If an error was thrown, we can
+     * just continue (and that will report the error to the user). If there
+     * was no error we must assume that the cwd was actually changed to the
+     * normalized value we calculated above, and we must therefore cache that
+     * information.
+     *
+     * If the filesystem in question has a getCwdProc, then the correct logic
+     * which performs the part below is already part of the Tcl_FSGetCwd()
+     * call, so no need to replicate it again. This will have a side effect
+     * though. The private authoritative representation of the current working
+     * directory stored in cwdPathPtr in static memory will be out-of-sync
+     * with the real OS-maintained value. The first call to Tcl_FSGetCwd will
+     * however recalculate the private copy to match the OS-value so
+     * everything will work right.
+     *
+     * However, if there is no getCwdProc, then we _must_ update our private
+     * storage of the cwd, since this is the only opportunity to do that!
+     *
+     * Note: We currently call this block of code irrespective of whether
+     * there was a getCwdProc or not, but the code should all in principle
+     * work if we only call this block if fsPtr->getCwdProc == NULL.
+     */
+
+    if (retVal == 0) {
+	/*
+	 * Note that this normalized path may be different to what we found
+	 * above (or at least a different object), if the filesystem epoch
+	 * changed recently. This can actually happen with scripted documents
+	 * very easily. Therefore we ask for the normalized path again (the
+	 * correct value will have been cached as a result of the
+	 * Tcl_FSGetFileSystemForPath call above anyway).
+	 */
+
+	Tcl_Obj *normDirName = Tcl_FSGetNormalizedPath(NULL, pathPtr);
+
+	if (normDirName == NULL) {
+	    /* Not really true, but what else to do? */
+	    Tcl_SetErrno(ENOENT);
+	    return -1;
+	}
+
+	if (fsPtr == &tclNativeFilesystem) {
+	    /*
+	     * For the native filesystem, we keep a cache of the native
+	     * representation of the cwd. But, we want to do that for the
+	     * exact format that is returned by 'getcwd' (so that we can later
+	     * compare the two representations for equality), which might not
+	     * be exactly the same char-string as the native representation of
+	     * the fully normalized path (e.g. on Windows there's a
+	     * forward-slash vs backslash difference). Hence we ask for this
+	     * again here. On Unix it might actually be true that we always
+	     * have the correct form in the native rep in which case we could
+	     * simply use:
+	     *		cd = Tcl_FSGetNativePath(pathPtr);
+	     * instead. This should be examined by someone on Unix.
+	     */
+
+	    ClientData cd;
+	    ClientData oldcd = tsdPtr->cwdClientData;
+
+	    /*
+	     * Assumption we are using a filesystem version 2.
+	     */
+
+	    TclFSGetCwdProc2 *proc2 = (TclFSGetCwdProc2 *) fsPtr->getCwdProc;
+
+	    cd = proc2(oldcd);
+	    if (cd != oldcd) {
+		FsUpdateCwd(normDirName, cd);
+	    }
+	} else {
+	    FsUpdateCwd(normDirName, NULL);
+	}
+
+	/*
+	 * If the filesystem changed between old and new cwd
+	 * force filesystem refresh on path objects.
+	 */
+	if (oldFsPtr != NULL && fsPtr != oldFsPtr) {
+	    Tcl_FSMountsChanged(NULL);
+	}
+    }
+
+    return retVal;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_FSLoadFile --
+ *
+ *	Dynamically loads a binary code file into memory and returns the
+ *	addresses of two functions within that file, if they are defined. The
+ *	appropriate function for the filesystem to which pathPtr belongs will
+ *	be called.
+ *
+ *	Note that the native filesystem doesn't actually assume 'pathPtr' is a
+ *	path. Rather it assumes pathPtr is either a path or just the name
+ *	(tail) of a file which can be found somewhere in the environment's
+ *	loadable path. This behaviour is not very compatible with virtual
+ *	filesystems (and has other problems documented in the load man-page),
+ *	so it is advised that full paths are always used.
+ *
+ * Results:
+ *	A standard Tcl completion code. If an error occurs, an error message
+ *	is left in the interp's result.
+ *
+ * Side effects:
+ *	New code suddenly appears in memory. This may later be unloaded by
+ *	passing the clientData to the unloadProc.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_FSLoadFile(
+    Tcl_Interp *interp,		/* Used for error reporting. */
+    Tcl_Obj *pathPtr,		/* Name of the file containing the desired
+				 * code. */
+    const char *sym1, const char *sym2,
+				/* Names of two functions to look up in the
+				 * file's symbol table. */
+    Tcl_PackageInitProc **proc1Ptr, Tcl_PackageInitProc **proc2Ptr,
+				/* Where to return the addresses corresponding
+				 * to sym1 and sym2. */
+    Tcl_LoadHandle *handlePtr,	/* Filled with token for dynamically loaded
+				 * file which will be passed back to
+				 * (*unloadProcPtr)() to unload the file. */
+    Tcl_FSUnloadFileProc **unloadProcPtr)
+				/* Filled with address of Tcl_FSUnloadFileProc
+				 * function which should be used for this
+				 * file. */
+{
+    const char *symbols[3];
+    void *procPtrs[2];
+    int res;
+
+    /*
+     * Initialize the arrays.
+     */
+
+    symbols[0] = sym1;
+    symbols[1] = sym2;
+    symbols[2] = NULL;
+
+    /*
+     * Perform the load.
+     */
+
+    res = Tcl_LoadFile(interp, pathPtr, symbols, 0, procPtrs, handlePtr);
+    if (res == TCL_OK) {
+	*proc1Ptr = (Tcl_PackageInitProc *) procPtrs[0];
+	*proc2Ptr = (Tcl_PackageInitProc *) procPtrs[1];
+    } else {
+	*proc1Ptr = *proc2Ptr = NULL;
+    }
+
+    return res;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_LoadFile --
+ *
+ *	Dynamically loads a binary code file into memory and returns the
+ *	addresses of a number of given functions within that file, if they are
+ *	defined. The appropriate function for the filesystem to which pathPtr
+ *	belongs will be called.
+ *
+ *	Note that the native filesystem doesn't actually assume 'pathPtr' is a
+ *	path. Rather it assumes pathPtr is either a path or just the name
+ *	(tail) of a file which can be found somewhere in the environment's
+ *	loadable path. This behaviour is not very compatible with virtual
+ *	filesystems (and has other problems documented in the load man-page),
+ *	so it is advised that full paths are always used.
+ *
+ * Results:
+ *	A standard Tcl completion code. If an error occurs, an error message
+ *	is left in the interp's result.
+ *
+ * Side effects:
+ *	New code suddenly appears in memory. This may later be unloaded by
+ *	calling TclFS_UnloadFile.
+ *
+ *----------------------------------------------------------------------
+ */
+
+/*
+ * Workaround for issue with modern HPUX which do allow the unlink (no ETXTBSY
+ * error) yet somehow trash some internal data structures which prevents the
+ * second and further shared libraries from getting properly loaded. Only the
+ * first is ok. We try to get around the issue by not unlinking,
+ * i.e. emulating the behaviour of the older HPUX which denied removal.
+ *
+ * Doing the unlink is also an issue within docker containers, whose AUFS
+ * bungles this as well, see
+ *     https://github.com/dotcloud/docker/issues/1911
+ *
+ * For these situations the change below makes the execution of the unlink
+ * semi-controllable at runtime.
+ *
+ *     An AUFS filesystem (if it can be detected) will force avoidance of
+ *     unlink. The env variable TCL_TEMPLOAD_NO_UNLINK allows detection of a
+ *     users general request (unlink and not.
+ *
+ * By default the unlink is done (if not in AUFS). However if the variable is
+ * present and set to true (any integer > 0) then the unlink is skipped.
+ */
+
+int
+TclSkipUnlink (Tcl_Obj* shlibFile)
+{
+    /* Order of testing:
+     * 1. On hpux we generally want to skip unlink in general
+     *
+     * Outside of hpux then:
+     * 2. For a general user request   (TCL_TEMPLOAD_NO_UNLINK present, non-empty, => int)
+     * 3. For general AUFS environment (statfs, if available).
+     *
+     * Ad 2: This variable can disable/override the AUFS detection, i.e. for
+     * testing if a newer AUFS does not have the bug any more.
+     *
+     * Ad 3: This is conditionally compiled in. Condition currently must be set manually.
+     *       This part needs proper tests in the configure(.in).
+     */
+
+#ifdef hpux
+    return 1;
+#else
+    char* skipstr;
+
+    skipstr = getenv ("TCL_TEMPLOAD_NO_UNLINK");
+    if (skipstr && (skipstr[0] != '\0')) {
+	return atoi(skipstr);
+    }
+
+#ifdef TCL_TEMPLOAD_NO_UNLINK
+#ifndef NO_FSTATFS
+    {
+	struct statfs fs;
+	/* Have fstatfs. May not have the AUFS super magic ... Indeed our build
+	 * box is too old to have it directly in the headers. Define taken from
+	 *     http://mooon.googlecode.com/svn/trunk/linux_include/linux/aufs_type.h
+	 *     http://aufs.sourceforge.net/
+	 * Better reference will be gladly taken.
+	 */
+#ifndef AUFS_SUPER_MAGIC
+#define AUFS_SUPER_MAGIC ('a' << 24 | 'u' << 16 | 'f' << 8 | 's')
+#endif /* AUFS_SUPER_MAGIC */
+	if ((statfs(Tcl_GetString (shlibFile), &fs) == 0) &&
+	    (fs.f_type == AUFS_SUPER_MAGIC)) {
+	    return 1;
+	}
+    }
+#endif /* ... NO_FSTATFS */
+#endif /* ... TCL_TEMPLOAD_NO_UNLINK */
+
+    /* Fallback: !hpux, no EV override, no AUFS (detection, nor detected):
+     * Don't skip */
+    return 0;
+#endif /* hpux */
+}
+
+int
+Tcl_LoadFile(
+    Tcl_Interp *interp,		/* Used for error reporting. */
+    Tcl_Obj *pathPtr,		/* Name of the file containing the desired
+				 * code. */
+    const char *const symbols[],/* Names of functions to look up in the file's
+				 * symbol table. */
+    int flags,			/* Flags */
+    void *procVPtrs,		/* Where to return the addresses corresponding
+				 * to symbols[]. */
+    Tcl_LoadHandle *handlePtr)	/* Filled with token for shared library
+				 * information which can be used in
+				 * TclpFindSymbol. */
+{
+    void **procPtrs = (void **) procVPtrs;
+    const Tcl_Filesystem *fsPtr = Tcl_FSGetFileSystemForPath(pathPtr);
+    const Tcl_Filesystem *copyFsPtr;
+    Tcl_FSUnloadFileProc *unloadProcPtr;
+    Tcl_Obj *copyToPtr;
+    Tcl_LoadHandle newLoadHandle = NULL;
+    Tcl_LoadHandle divertedLoadHandle = NULL;
+    Tcl_FSUnloadFileProc *newUnloadProcPtr = NULL;
+    FsDivertLoad *tvdlPtr;
+    int retVal;
+    int i;
+
+    if (fsPtr == NULL) {
+	Tcl_SetErrno(ENOENT);
+	return TCL_ERROR;
+    }
+
+    if (fsPtr->loadFileProc != NULL) {
+	int retVal = ((Tcl_FSLoadFileProc2 *)(fsPtr->loadFileProc))
+		(interp, pathPtr, handlePtr, &unloadProcPtr, flags);
+
+	if (retVal == TCL_OK) {
+	    if (*handlePtr == NULL) {
+		return TCL_ERROR;
+	    }
+	    if (interp) {
+		Tcl_ResetResult(interp);
+	    }
+	    goto resolveSymbols;
+	}
+	if (Tcl_GetErrno() != EXDEV) {
+	    return retVal;
+	}
+    }
+
+    /*
+     * The filesystem doesn't support 'load', so we fall back on the following
+     * technique:
+     *
+     * First check if it is readable -- and exists!
+     */
+
+    if (Tcl_FSAccess(pathPtr, R_OK) != 0) {
+	if (interp) {
+	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		    "couldn't load library \"%s\": %s",
+		    Tcl_GetString(pathPtr), Tcl_PosixError(interp)));
+	}
+	return TCL_ERROR;
+    }
+
+#ifdef TCL_LOAD_FROM_MEMORY
+    /*
+     * The platform supports loading code from memory, so ask for a buffer of
+     * the appropriate size, read the file into it and load the code from the
+     * buffer:
+     */
+
+    {
+	int ret, size;
+	void *buffer;
+	Tcl_StatBuf statBuf;
+	Tcl_Channel data;
+
+	ret = Tcl_FSStat(pathPtr, &statBuf);
+	if (ret < 0) {
+	    goto mustCopyToTempAnyway;
+	}
+	size = (int) statBuf.st_size;
+
+	/*
+	 * Tcl_Read takes an int: check that file size isn't wide.
+	 */
+
+	if (size != (Tcl_WideInt) statBuf.st_size) {
+	    goto mustCopyToTempAnyway;
+	}
+	data = Tcl_FSOpenFileChannel(interp, pathPtr, "rb", 0666);
+	if (!data) {
+	    goto mustCopyToTempAnyway;
+	}
+	buffer = TclpLoadMemoryGetBuffer(interp, size);
+	if (!buffer) {
+	    Tcl_Close(interp, data);
+	    goto mustCopyToTempAnyway;
+	}
+	ret = Tcl_Read(data, buffer, size);
+	Tcl_Close(interp, data);
+	ret = TclpLoadMemory(interp, buffer, size, ret, handlePtr,
+		&unloadProcPtr, flags);
+	if (ret == TCL_OK && *handlePtr != NULL) {
+	    goto resolveSymbols;
+	}
+    }
+
+  mustCopyToTempAnyway:
+    if (interp) {
+	Tcl_ResetResult(interp);
+    }
+#endif /* TCL_LOAD_FROM_MEMORY */
+
+    /*
+     * Get a temporary filename to use, first to copy the file into, and then
+     * to load.
+     */
+
+    copyToPtr = TclpTempFileNameForLibrary(interp, pathPtr);
+    if (copyToPtr == NULL) {
+	return TCL_ERROR;
+    }
+    Tcl_IncrRefCount(copyToPtr);
+
+    copyFsPtr = Tcl_FSGetFileSystemForPath(copyToPtr);
+    if ((copyFsPtr == NULL) || (copyFsPtr == fsPtr)) {
+	/*
+	 * We already know we can't use Tcl_FSLoadFile from this filesystem,
+	 * and we must avoid a possible infinite loop. Try to delete the file
+	 * we probably created, and then exit.
+	 */
+
+	Tcl_FSDeleteFile(copyToPtr);
+	Tcl_DecrRefCount(copyToPtr);
+	if (interp) {
+	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		    "couldn't load from current filesystem", -1));
+	}
+	return TCL_ERROR;
+    }
+
+    if (TclCrossFilesystemCopy(interp, pathPtr, copyToPtr) != TCL_OK) {
+	/*
+	 * Cross-platform copy failed.
+	 */
+
+	Tcl_FSDeleteFile(copyToPtr);
+	Tcl_DecrRefCount(copyToPtr);
+	return TCL_ERROR;
+    }
+
+#ifndef _WIN32
+    /*
+     * Do we need to set appropriate permissions on the file? This may be
+     * required on some systems. On Unix we could loop over the file
+     * attributes, and set any that are called "-permissions" to 0700. However
+     * we just do this directly, like this:
+     */
+
+    {
+	int index;
+	Tcl_Obj *perm;
+
+	TclNewLiteralStringObj(perm, "0700");
+	Tcl_IncrRefCount(perm);
+	if (TclFSFileAttrIndex(copyToPtr, "-permissions", &index) == TCL_OK) {
+	    Tcl_FSFileAttrsSet(NULL, index, copyToPtr, perm);
+	}
+	Tcl_DecrRefCount(perm);
+    }
+#endif
+
+    /*
+     * We need to reset the result now, because the cross-filesystem copy may
+     * have stored the number of bytes in the result.
+     */
+
+    if (interp) {
+	Tcl_ResetResult(interp);
+    }
+
+    retVal = Tcl_LoadFile(interp, copyToPtr, symbols, flags, procPtrs,
+	    &newLoadHandle);
+    if (retVal != TCL_OK) {
+	/*
+	 * The file didn't load successfully.
+	 */
+
+	Tcl_FSDeleteFile(copyToPtr);
+	Tcl_DecrRefCount(copyToPtr);
+	return retVal;
+    }
+
+    /*
+     * Try to delete the file immediately - this is possible in some OSes, and
+     * avoids any worries about leaving the copy laying around on exit.
+     */
+
+    if (
+	!TclSkipUnlink (copyToPtr) &&
+	(Tcl_FSDeleteFile(copyToPtr) == TCL_OK)) {
+	Tcl_DecrRefCount(copyToPtr);
+
+	/*
+	 * We tell our caller about the real shared library which was loaded.
+	 * Note that this does mean that the package list maintained by 'load'
+	 * will store the original (vfs) path alongside the temporary load
+	 * handle and unload proc ptr.
+	 */
+
+	*handlePtr = newLoadHandle;
+	if (interp) {
+	    Tcl_ResetResult(interp);
+	}
+	return TCL_OK;
+    }
+
+    /*
+     * When we unload this file, we need to divert the unloading so we can
+     * unload and cleanup the temporary file correctly.
+     */
+
+    tvdlPtr = ckalloc(sizeof(FsDivertLoad));
+
+    /*
+     * Remember three pieces of information. This allows us to cleanup the
+     * diverted load completely, on platforms which allow proper unloading of
+     * code.
+     */
+
+    tvdlPtr->loadHandle = newLoadHandle;
+    tvdlPtr->unloadProcPtr = newUnloadProcPtr;
+
+    if (copyFsPtr != &tclNativeFilesystem) {
+	/*
+	 * copyToPtr is already incremented for this reference.
+	 */
+
+	tvdlPtr->divertedFile = copyToPtr;
+
+	/*
+	 * This is the filesystem we loaded it into. Since we have a reference
+	 * to 'copyToPtr', we already have a refCount on this filesystem, so
+	 * we don't need to worry about it disappearing on us.
+	 */
+
+	tvdlPtr->divertedFilesystem = copyFsPtr;
+	tvdlPtr->divertedFileNativeRep = NULL;
+    } else {
+	/*
+	 * We need the native rep.
+	 */
+
+	tvdlPtr->divertedFileNativeRep = TclNativeDupInternalRep(
+		Tcl_FSGetInternalRep(copyToPtr, copyFsPtr));
+
+	/*
+	 * We don't need or want references to the copied Tcl_Obj or the
+	 * filesystem if it is the native one.
+	 */
+
+	tvdlPtr->divertedFile = NULL;
+	tvdlPtr->divertedFilesystem = NULL;
+	Tcl_DecrRefCount(copyToPtr);
+    }
+
+    copyToPtr = NULL;
+
+    divertedLoadHandle = ckalloc(sizeof(struct Tcl_LoadHandle_));
+    divertedLoadHandle->clientData = tvdlPtr;
+    divertedLoadHandle->findSymbolProcPtr = DivertFindSymbol;
+    divertedLoadHandle->unloadFileProcPtr = DivertUnloadFile;
+    *handlePtr = divertedLoadHandle;
+
+    if (interp) {
+	Tcl_ResetResult(interp);
+    }
+    return retVal;
+
+  resolveSymbols:
+    /*
+     * At this point, *handlePtr is already set up to the handle for the
+     * loaded library. We now try to resolve the symbols.
+     */
+
+    if (symbols != NULL) {
+	for (i=0 ; symbols[i] != NULL; i++) {
+	    procPtrs[i] = Tcl_FindSymbol(interp, *handlePtr, symbols[i]);
+	    if (procPtrs[i] == NULL) {
+		/*
+		 * At least one symbol in the list was not found.  Unload the
+		 * file, and report the problem back to the caller.
+		 * (Tcl_FindSymbol should already have left an appropriate
+		 * error message.)
+		 */
+
+		(*handlePtr)->unloadFileProcPtr(*handlePtr);
+		*handlePtr = NULL;
+		return TCL_ERROR;
+	    }
+	}
+    }
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * DivertFindSymbol --
+ *
+ *	Find a symbol in a shared library loaded by copy-from-VFS.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void *
+DivertFindSymbol(
+    Tcl_Interp *interp, 	/* Tcl interpreter */
+    Tcl_LoadHandle loadHandle,	/* Handle to the diverted module */
+    const char *symbol)		/* Symbol to resolve */
+{
+    FsDivertLoad *tvdlPtr = (FsDivertLoad *) loadHandle->clientData;
+    Tcl_LoadHandle originalHandle = tvdlPtr->loadHandle;
+
+    return originalHandle->findSymbolProcPtr(interp, originalHandle, symbol);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * DivertUnloadFile --
+ *
+ *	Unloads a file that has been loaded by copying from VFS to the native
+ *	filesystem.
+ *
+ * Parameters:
+ *	loadHandle -- Handle of the file to unload
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+DivertUnloadFile(
+    Tcl_LoadHandle loadHandle)
+{
+    FsDivertLoad *tvdlPtr = (FsDivertLoad *) loadHandle->clientData;
+    Tcl_LoadHandle originalHandle;
+
+    /*
+     * This test should never trigger, since we give the client data in the
+     * function above.
+     */
+
+    if (tvdlPtr == NULL) {
+	return;
+    }
+    originalHandle = tvdlPtr->loadHandle;
+
+    /*
+     * Call the real 'unloadfile' proc we actually used. It is very important
+     * that we call this first, so that the shared library is actually
+     * unloaded by the OS. Otherwise, the following 'delete' may well fail
+     * because the shared library is still in use.
+     */
+
+    originalHandle->unloadFileProcPtr(originalHandle);
+
+    /*
+     * What filesystem contains the temp copy of the library?
+     */
+
+    if (tvdlPtr->divertedFilesystem == NULL) {
+	/*
+	 * It was the native filesystem, and we have a special function
+	 * available just for this purpose, which we know works even at this
+	 * late stage.
+	 */
+
+	TclpDeleteFile(tvdlPtr->divertedFileNativeRep);
+	NativeFreeInternalRep(tvdlPtr->divertedFileNativeRep);
+    } else {
+	/*
+	 * Remove the temporary file we created. Note, we may crash here
+	 * because encodings have been taken down already.
+	 */
+
+	if (tvdlPtr->divertedFilesystem->deleteFileProc(tvdlPtr->divertedFile)
+		!= TCL_OK) {
+	    /*
+	     * The above may have failed because the filesystem, or something
+	     * it depends upon (e.g. encodings) have been taken down because
+	     * Tcl is exiting.
+	     *
+	     * We may need to work out how to delete this file more robustly
+	     * (or give the filesystem the information it needs to delete the
+	     * file more robustly).
+	     *
+	     * In particular, one problem might be that the filesystem cannot
+	     * extract the information it needs from the above path object
+	     * because Tcl's entire filesystem apparatus (the code in this
+	     * file) has been finalized, and it refuses to pass the internal
+	     * representation to the filesystem.
+	     */
+	}
+
+	/*
+	 * And free up the allocations. This will also of course remove a
+	 * refCount from the Tcl_Filesystem to which this file belongs, which
+	 * could then free up the filesystem if we are exiting.
+	 */
+
+	Tcl_DecrRefCount(tvdlPtr->divertedFile);
+    }
+
+    ckfree(tvdlPtr);
+    ckfree(loadHandle);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_FindSymbol --
+ *
+ *	Find a symbol in a loaded library
+ *
+ * Results:
+ *	Returns a pointer to the symbol if found. If not found, returns NULL
+ *	and leaves an error message in the interpreter result.
+ *
+ * This function was once filesystem-specific, but has been made portable by
+ * having TclpDlopen return a structure that includes procedure pointers.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void *
+Tcl_FindSymbol(
+    Tcl_Interp *interp,		/* Tcl interpreter */
+    Tcl_LoadHandle loadHandle,	/* Handle to the loaded library */
+    const char *symbol)		/* Name of the symbol to resolve */
+{
+    return loadHandle->findSymbolProcPtr(interp, loadHandle, symbol);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_FSUnloadFile --
+ *
+ *	Unloads a library given its handle. Checks first that the library
+ *	supports unloading.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_FSUnloadFile(
+    Tcl_Interp *interp,		/* Tcl interpreter */
+    Tcl_LoadHandle handle)	/* Handle of the file to unload */
+{
+    if (handle->unloadFileProcPtr == NULL) {
+	if (interp != NULL) {
+	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		    "cannot unload: filesystem does not support unloading",
+		    -1));
+	}
+	return TCL_ERROR;
+    }
+    TclpUnloadFile(handle);
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclpUnloadFile --
+ *
+ *	Unloads a library given its handle
+ *
+ * This function was once filesystem-specific, but has been made portable by
+ * having TclpDlopen return a structure that includes procedure pointers.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclpUnloadFile(
+    Tcl_LoadHandle handle)
+{
+    if (handle->unloadFileProcPtr != NULL) {
+	handle->unloadFileProcPtr(handle);
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclFSUnloadTempFile --
+ *
+ *	This function is called when we loaded a library of code via an
+ *	intermediate temporary file. This function ensures the library is
+ *	correctly unloaded and the temporary file is correctly deleted.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The effects of the 'unload' function called, and of course the
+ *	temporary file will be deleted.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclFSUnloadTempFile(
+    Tcl_LoadHandle loadHandle)	/* loadHandle returned by a previous call to
+				 * Tcl_FSLoadFile(). The loadHandle is a token
+				 * that represents the loaded file. */
+{
+    FsDivertLoad *tvdlPtr = (FsDivertLoad *) loadHandle;
+
+    /*
+     * This test should never trigger, since we give the client data in the
+     * function above.
+     */
+
+    if (tvdlPtr == NULL) {
+	return;
+    }
+
+    /*
+     * Call the real 'unloadfile' proc we actually used. It is very important
+     * that we call this first, so that the shared library is actually
+     * unloaded by the OS. Otherwise, the following 'delete' may well fail
+     * because the shared library is still in use.
+     */
+
+    if (tvdlPtr->unloadProcPtr != NULL) {
+	tvdlPtr->unloadProcPtr(tvdlPtr->loadHandle);
+    }
+
+    if (tvdlPtr->divertedFilesystem == NULL) {
+	/*
+	 * It was the native filesystem, and we have a special function
+	 * available just for this purpose, which we know works even at this
+	 * late stage.
+	 */
+
+	TclpDeleteFile(tvdlPtr->divertedFileNativeRep);
+	NativeFreeInternalRep(tvdlPtr->divertedFileNativeRep);
+    } else {
+	/*
+	 * Remove the temporary file we created. Note, we may crash here
+	 * because encodings have been taken down already.
+	 */
+
+	if (tvdlPtr->divertedFilesystem->deleteFileProc(tvdlPtr->divertedFile)
+		!= TCL_OK) {
+	    /*
+	     * The above may have failed because the filesystem, or something
+	     * it depends upon (e.g. encodings) have been taken down because
+	     * Tcl is exiting.
+	     *
+	     * We may need to work out how to delete this file more robustly
+	     * (or give the filesystem the information it needs to delete the
+	     * file more robustly).
+	     *
+	     * In particular, one problem might be that the filesystem cannot
+	     * extract the information it needs from the above path object
+	     * because Tcl's entire filesystem apparatus (the code in this
+	     * file) has been finalized, and it refuses to pass the internal
+	     * representation to the filesystem.
+	     */
+	}
+
+	/*
+	 * And free up the allocations. This will also of course remove a
+	 * refCount from the Tcl_Filesystem to which this file belongs, which
+	 * could then free up the filesystem if we are exiting.
+	 */
+
+	Tcl_DecrRefCount(tvdlPtr->divertedFile);
+    }
+
+    ckfree(tvdlPtr);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Tcl_FSLink --
+ *
+ *	This function replaces the library version of readlink() and can also
+ *	be used to make links. The appropriate function for the filesystem to
+ *	which pathPtr belongs will be called.
+ *
+ * Results:
+ *	If toPtr is NULL, then the result is a Tcl_Obj specifying the contents
+ *	of the symbolic link given by 'pathPtr', or NULL if the symbolic link
+ *	could not be read. The result is owned by the caller, which should
+ *	call Tcl_DecrRefCount when the result is no longer needed.
+ *
+ *	If toPtr is non-NULL, then the result is toPtr if the link action was
+ *	successful, or NULL if not. In this case the result has no additional
+ *	reference count, and need not be freed. The actual action to perform
+ *	is given by the 'linkAction' flags, which is an or'd combination of:
+ *
+ *		TCL_CREATE_SYMBOLIC_LINK
+ *		TCL_CREATE_HARD_LINK
+ *
+ *	Note that most filesystems will not support linking across to
+ *	different filesystems, so this function will usually fail unless toPtr
+ *	is in the same FS as pathPtr.
+ *
+ * Side effects:
+ *	See readlink() documentation. A new filesystem link object may appear.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+Tcl_Obj *
+Tcl_FSLink(
+    Tcl_Obj *pathPtr,		/* Path of file to readlink or link. */
+    Tcl_Obj *toPtr,		/* NULL or path to be linked to. */
+    int linkAction)		/* Action to perform. */
+{
+    const Tcl_Filesystem *fsPtr = Tcl_FSGetFileSystemForPath(pathPtr);
+
+    if (fsPtr != NULL && fsPtr->linkProc != NULL) {
+	return fsPtr->linkProc(pathPtr, toPtr, linkAction);
+    }
+
+    /*
+     * If S_IFLNK isn't defined it means that the machine doesn't support
+     * symbolic links, so the file can't possibly be a symbolic link. Generate
+     * an EINVAL error, which is what happens on machines that do support
+     * symbolic links when you invoke readlink on a file that isn't a symbolic
+     * link.
+     */
+
+#ifndef S_IFLNK
+    errno = EINVAL; /* TODO: Change to Tcl_SetErrno()? */
+#else
+    Tcl_SetErrno(ENOENT);
+#endif /* S_IFLNK */
+    return NULL;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Tcl_FSListVolumes --
+ *
+ *	Lists the currently mounted volumes. The chain of functions that have
+ *	been "inserted" into the filesystem will be called in succession; each
+ *	may return a list of volumes, all of which are added to the result
+ *	until all mounted file systems are listed.
+ *
+ *	Notice that we assume the lists returned by each filesystem (if non
+ *	NULL) have been given a refCount for us already. However, we are NOT
+ *	allowed to hang on to the list itself (it belongs to the filesystem we
+ *	called). Therefore we quite naturally add its contents to the result
+ *	we are building, and then decrement the refCount.
+ *
+ * Results:
+ *	The list of volumes, in an object which has refCount 0.
+ *
+ * Side effects:
+ *	None
+ *
+ *---------------------------------------------------------------------------
+ */
+
+Tcl_Obj *
+Tcl_FSListVolumes(void)
+{
+    FilesystemRecord *fsRecPtr;
+    Tcl_Obj *resultPtr = Tcl_NewObj();
+
+    /*
+     * Call each of the "listVolumes" function in succession. A non-NULL
+     * return value indicates the particular function has succeeded. We call
+     * all the functions registered, since we want a list of all drives from
+     * all filesystems.
+     */
+
+    fsRecPtr = FsGetFirstFilesystem();
+    Claim();
+    while (fsRecPtr != NULL) {
+	if (fsRecPtr->fsPtr->listVolumesProc != NULL) {
+	    Tcl_Obj *thisFsVolumes = fsRecPtr->fsPtr->listVolumesProc();
+
+	    if (thisFsVolumes != NULL) {
+		Tcl_ListObjAppendList(NULL, resultPtr, thisFsVolumes);
+		Tcl_DecrRefCount(thisFsVolumes);
+	    }
+	}
+	fsRecPtr = fsRecPtr->nextPtr;
+    }
+    Disclaim();
+
+    return resultPtr;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * FsListMounts --
+ *
+ *	List all mounts within the given directory, which match the given
+ *	pattern.
+ *
+ * Results:
+ *	The list of mounts, in a list object which has refCount 0, or NULL if
+ *	we didn't even find any filesystems to try to list mounts.
+ *
+ * Side effects:
+ *	None
+ *
+ *---------------------------------------------------------------------------
+ */
+
+static Tcl_Obj *
+FsListMounts(
+    Tcl_Obj *pathPtr,		/* Contains path to directory to search. */
+    const char *pattern)	/* Pattern to match against. */
+{
+    FilesystemRecord *fsRecPtr;
+    Tcl_GlobTypeData mountsOnly = { TCL_GLOB_TYPE_MOUNT, 0, NULL, NULL };
+    Tcl_Obj *resultPtr = NULL;
+
+    /*
+     * Call each of the "matchInDirectory" functions in succession, with the
+     * specific type information 'mountsOnly'. A non-NULL return value
+     * indicates the particular function has succeeded. We call all the
+     * functions registered, since we want a list from each filesystems.
+     */
+
+    fsRecPtr = FsGetFirstFilesystem();
+    Claim();
+    while (fsRecPtr != NULL) {
+	if (fsRecPtr->fsPtr != &tclNativeFilesystem &&
+		fsRecPtr->fsPtr->matchInDirectoryProc != NULL) {
+	    if (resultPtr == NULL) {
+		resultPtr = Tcl_NewObj();
+	    }
+	    fsRecPtr->fsPtr->matchInDirectoryProc(NULL, resultPtr, pathPtr,
+		    pattern, &mountsOnly);
+	}
+	fsRecPtr = fsRecPtr->nextPtr;
+    }
+    Disclaim();
+
+    return resultPtr;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Tcl_FSSplitPath --
+ *
+ *	This function takes the given Tcl_Obj, which should be a valid path,
+ *	and returns a Tcl List object containing each segment of that path as
+ *	an element.
+ *
+ * Results:
+ *	Returns list object with refCount of zero. If the passed in lenPtr is
+ *	non-NULL, we use it to return the number of elements in the returned
+ *	list.
+ *
+ * Side effects:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+Tcl_Obj *
+Tcl_FSSplitPath(
+    Tcl_Obj *pathPtr,		/* Path to split. */
+    int *lenPtr)		/* int to store number of path elements. */
+{
+    Tcl_Obj *result = NULL;	/* Needed only to prevent gcc warnings. */
+    const Tcl_Filesystem *fsPtr;
+    char separator = '/';
+    int driveNameLength;
+    const char *p;
+
+    /*
+     * Perform platform specific splitting.
+     */
+
+    if (TclFSGetPathType(pathPtr, &fsPtr,
+	    &driveNameLength) == TCL_PATH_ABSOLUTE) {
+	if (fsPtr == &tclNativeFilesystem) {
+	    return TclpNativeSplitPath(pathPtr, lenPtr);
+	}
+    } else {
+	return TclpNativeSplitPath(pathPtr, lenPtr);
+    }
+
+    /*
+     * We assume separators are single characters.
+     */
+
+    if (fsPtr->filesystemSeparatorProc != NULL) {
+	Tcl_Obj *sep = fsPtr->filesystemSeparatorProc(pathPtr);
+
+	if (sep != NULL) {
+	    Tcl_IncrRefCount(sep);
+	    separator = Tcl_GetString(sep)[0];
+	    Tcl_DecrRefCount(sep);
+	}
+    }
+
+    /*
+     * Place the drive name as first element of the result list. The drive
+     * name may contain strange characters, like colons and multiple forward
+     * slashes (for example 'ftp://' is a valid vfs drive name)
+     */
+
+    result = Tcl_NewObj();
+    p = Tcl_GetString(pathPtr);
+    Tcl_ListObjAppendElement(NULL, result,
+	    Tcl_NewStringObj(p, driveNameLength));
+    p += driveNameLength;
+
+    /*
+     * Add the remaining path elements to the list.
+     */
+
+    for (;;) {
+	const char *elementStart = p;
+	int length;
+
+	while ((*p != '\0') && (*p != separator)) {
+	    p++;
+	}
+	length = p - elementStart;
+	if (length > 0) {
+	    Tcl_Obj *nextElt;
+
+	    if (elementStart[0] == '~') {
+		TclNewLiteralStringObj(nextElt, "./");
+		Tcl_AppendToObj(nextElt, elementStart, length);
+	    } else {
+		nextElt = Tcl_NewStringObj(elementStart, length);
+	    }
+	    Tcl_ListObjAppendElement(NULL, result, nextElt);
+	}
+	if (*p++ == '\0') {
+	    break;
+	}
+    }
+
+    /*
+     * Compute the number of elements in the result.
+     */
+
+    if (lenPtr != NULL) {
+	TclListObjLength(NULL, result, lenPtr);
+    }
+    return result;
+}
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclGetPathType --
+ *
+ *	Helper function used by FSGetPathType.
+ *
+ * Results:
+ *	Returns one of TCL_PATH_ABSOLUTE, TCL_PATH_RELATIVE, or
+ *	TCL_PATH_VOLUME_RELATIVE. The filesystem reference will be set if and
+ *	only if it is non-NULL and the function's return value is
+ *	TCL_PATH_ABSOLUTE.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_PathType
+TclGetPathType(
+    Tcl_Obj *pathPtr,		/* Path to determine type for. */
+    const Tcl_Filesystem **filesystemPtrPtr,
+				/* If absolute path and this is not NULL, then
+				 * set to the filesystem which claims this
+				 * path. */
+    int *driveNameLengthPtr,	/* If the path is absolute, and this is
+				 * non-NULL, then set to the length of the
+				 * driveName. */
+    Tcl_Obj **driveNameRef)	/* If the path is absolute, and this is
+				 * non-NULL, then set to the name of the
+				 * drive, network-volume which contains the
+				 * path, already with a refCount for the
+				 * caller. */
+{
+    int pathLen;
+    const char *path = Tcl_GetStringFromObj(pathPtr, &pathLen);
+    Tcl_PathType type;
+
+    type = TclFSNonnativePathType(path, pathLen, filesystemPtrPtr,
+	    driveNameLengthPtr, driveNameRef);
+
+    if (type != TCL_PATH_ABSOLUTE) {
+	type = TclpGetNativePathType(pathPtr, driveNameLengthPtr,
+		driveNameRef);
+	if ((type == TCL_PATH_ABSOLUTE) && (filesystemPtrPtr != NULL)) {
+	    *filesystemPtrPtr = &tclNativeFilesystem;
+	}
+    }
+    return type;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclFSNonnativePathType --
+ *
+ *	Helper function used by TclGetPathType. Its purpose is to check
+ *	whether the given path starts with a string which corresponds to a
+ *	file volume in any registered filesystem except the native one. For
+ *	speed and historical reasons the native filesystem has special
+ *	hard-coded checks dotted here and there in the filesystem code.
+ *
+ * Results:
+ *	Returns one of TCL_PATH_ABSOLUTE or TCL_PATH_RELATIVE. The filesystem
+ *	reference will be set if and only if it is non-NULL and the function's
+ *	return value is TCL_PATH_ABSOLUTE.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_PathType
+TclFSNonnativePathType(
+    const char *path,		/* Path to determine type for. */
+    int pathLen,		/* Length of the path. */
+    const Tcl_Filesystem **filesystemPtrPtr,
+				/* If absolute path and this is not NULL, then
+				 * set to the filesystem which claims this
+				 * path. */
+    int *driveNameLengthPtr,	/* If the path is absolute, and this is
+				 * non-NULL, then set to the length of the
+				 * driveName. */
+    Tcl_Obj **driveNameRef)	/* If the path is absolute, and this is
+				 * non-NULL, then set to the name of the
+				 * drive, network-volume which contains the
+				 * path, already with a refCount for the
+				 * caller. */
+{
+    FilesystemRecord *fsRecPtr;
+    Tcl_PathType type = TCL_PATH_RELATIVE;
+
+    /*
+     * Call each of the "listVolumes" function in succession, checking whether
+     * the given path is an absolute path on any of the volumes returned (this
+     * is done by checking whether the path's prefix matches).
+     */
+
+    fsRecPtr = FsGetFirstFilesystem();
+    Claim();
+    while (fsRecPtr != NULL) {
+	/*
+	 * We want to skip the native filesystem in this loop because
+	 * otherwise we won't necessarily pass all the Tcl testsuite - this is
+	 * because some of the tests artificially change the current platform
+	 * (between win, unix) but the list of volumes we get by calling
+	 * fsRecPtr->fsPtr->listVolumesProc will reflect the current (real)
+	 * platform only and this may cause some tests to fail. In particular,
+	 * on Unix '/' will match the beginning of certain absolute Windows
+	 * paths starting '//' and those tests will go wrong.
+	 *
+	 * Besides these test-suite issues, there is one other reason to skip
+	 * the native filesystem - since the tclFilename.c code has nice fast
+	 * 'absolute path' checkers, we don't want to waste time repeating
+	 * that effort here, and this function is actually called quite often,
+	 * so if we can save the overhead of the native filesystem returning
+	 * us a list of volumes all the time, it is better.
+	 */
+
+	if ((fsRecPtr->fsPtr != &tclNativeFilesystem)
+		&& (fsRecPtr->fsPtr->listVolumesProc != NULL)) {
+	    int numVolumes;
+	    Tcl_Obj *thisFsVolumes = fsRecPtr->fsPtr->listVolumesProc();
+
+	    if (thisFsVolumes != NULL) {
+		if (Tcl_ListObjLength(NULL, thisFsVolumes, &numVolumes)
+			!= TCL_OK) {
+		    /*
+		     * This is VERY bad; the listVolumesProc didn't return a
+		     * valid list. Set numVolumes to -1 so that we skip the
+		     * while loop below and just return with the current value
+		     * of 'type'.
+		     *
+		     * It would be better if we could signal an error here
+		     * (but Tcl_Panic seems a bit excessive).
+		     */
+
+		    numVolumes = -1;
+		}
+		while (numVolumes > 0) {
+		    Tcl_Obj *vol;
+		    int len;
+		    const char *strVol;
+
+		    numVolumes--;
+		    Tcl_ListObjIndex(NULL, thisFsVolumes, numVolumes, &vol);
+		    strVol = Tcl_GetStringFromObj(vol,&len);
+		    if (pathLen < len) {
+			continue;
+		    }
+		    if (strncmp(strVol, path, (size_t) len) == 0) {
+			type = TCL_PATH_ABSOLUTE;
+			if (filesystemPtrPtr != NULL) {
+			    *filesystemPtrPtr = fsRecPtr->fsPtr;
+			}
+			if (driveNameLengthPtr != NULL) {
+			    *driveNameLengthPtr = len;
+			}
+			if (driveNameRef != NULL) {
+			    *driveNameRef = vol;
+			    Tcl_IncrRefCount(vol);
+			}
+			break;
+		    }
+		}
+		Tcl_DecrRefCount(thisFsVolumes);
+		if (type == TCL_PATH_ABSOLUTE) {
+		    /*
+		     * We don't need to examine any more filesystems.
+		     */
+
+		    break;
+		}
+	    }
+	}
+	fsRecPtr = fsRecPtr->nextPtr;
+    }
+    Disclaim();
+    return type;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Tcl_FSRenameFile --
+ *
+ *	If the two paths given belong to the same filesystem, we call that
+ *	filesystems rename function. Otherwise we simply return the POSIX
+ *	error 'EXDEV', and -1.
+ *
+ * Results:
+ *	Standard Tcl error code if a function was called.
+ *
+ * Side effects:
+ *	A file may be renamed.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+int
+Tcl_FSRenameFile(
+    Tcl_Obj *srcPathPtr,	/* Pathname of file or dir to be renamed
+				 * (UTF-8). */
+    Tcl_Obj *destPathPtr)	/* New pathname of file or directory
+				 * (UTF-8). */
+{
+    int retVal = -1;
+    const Tcl_Filesystem *fsPtr, *fsPtr2;
+
+    fsPtr = Tcl_FSGetFileSystemForPath(srcPathPtr);
+    fsPtr2 = Tcl_FSGetFileSystemForPath(destPathPtr);
+
+    if ((fsPtr == fsPtr2) && (fsPtr != NULL)
+	    && (fsPtr->renameFileProc != NULL)) {
+	retVal = fsPtr->renameFileProc(srcPathPtr, destPathPtr);
+    }
+    if (retVal == -1) {
+	Tcl_SetErrno(EXDEV);
+    }
+    return retVal;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Tcl_FSCopyFile --
+ *
+ *	If the two paths given belong to the same filesystem, we call that
+ *	filesystem's copy function. Otherwise we simply return the POSIX error
+ *	'EXDEV', and -1.
+ *
+ *	Note that in the native filesystems, 'copyFileProc' is defined to copy
+ *	soft links (i.e. it copies the links themselves, not the things they
+ *	point to).
+ *
+ * Results:
+ *	Standard Tcl error code if a function was called.
+ *
+ * Side effects:
+ *	A file may be copied.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+int
+Tcl_FSCopyFile(
+    Tcl_Obj *srcPathPtr,	/* Pathname of file to be copied (UTF-8). */
+    Tcl_Obj *destPathPtr)	/* Pathname of file to copy to (UTF-8). */
+{
+    int retVal = -1;
+    const Tcl_Filesystem *fsPtr, *fsPtr2;
+
+    fsPtr = Tcl_FSGetFileSystemForPath(srcPathPtr);
+    fsPtr2 = Tcl_FSGetFileSystemForPath(destPathPtr);
+
+    if (fsPtr == fsPtr2 && fsPtr != NULL && fsPtr->copyFileProc != NULL) {
+	retVal = fsPtr->copyFileProc(srcPathPtr, destPathPtr);
+    }
+    if (retVal == -1) {
+	Tcl_SetErrno(EXDEV);
+    }
+    return retVal;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * TclCrossFilesystemCopy --
+ *
+ *	Helper for above function, and for Tcl_FSLoadFile, to copy files from
+ *	one filesystem to another. This function will overwrite the target
+ *	file if it already exists.
+ *
+ * Results:
+ *	Standard Tcl error code.
+ *
+ * Side effects:
+ *	A file may be created.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+int
+TclCrossFilesystemCopy(
+    Tcl_Interp *interp,		/* For error messages. */
+    Tcl_Obj *source,		/* Pathname of file to be copied (UTF-8). */
+    Tcl_Obj *target)		/* Pathname of file to copy to (UTF-8). */
+{
+    int result = TCL_ERROR;
+    int prot = 0666;
+    Tcl_Channel in, out;
+    Tcl_StatBuf sourceStatBuf;
+    struct utimbuf tval;
+
+    out = Tcl_FSOpenFileChannel(interp, target, "wb", prot);
+    if (out == NULL) {
+	/*
+	 * It looks like we cannot copy it over. Bail out...
+	 */
+	goto done;
+    }
+
+    in = Tcl_FSOpenFileChannel(interp, source, "rb", prot);
+    if (in == NULL) {
+	/*
+	 * This is very strange, caller should have checked this...
+	 */
+
+	Tcl_Close(interp, out);
+	goto done;
+    }
+
+    /*
+     * Copy it synchronously. We might wish to add an asynchronous option to
+     * support vfs's which are slow (e.g. network sockets).
+     */
+
+    if (TclCopyChannel(interp, in, out, -1, NULL) == TCL_OK) {
+	result = TCL_OK;
+    }
+
+    /*
+     * If the copy failed, assume that copy channel left a good error message.
+     */
+
+    Tcl_Close(interp, in);
+    Tcl_Close(interp, out);
+
+    /*
+     * Set modification date of copied file.
+     */
+
+    if (Tcl_FSLstat(source, &sourceStatBuf) == 0) {
+	tval.actime = sourceStatBuf.st_atime;
+	tval.modtime = sourceStatBuf.st_mtime;
+	Tcl_FSUtime(target, &tval);
+    }
+
+  done:
+    return result;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Tcl_FSDeleteFile --
+ *
+ *	The appropriate function for the filesystem to which pathPtr belongs
+ *	will be called.
+ *
+ * Results:
+ *	Standard Tcl error code.
+ *
+ * Side effects:
+ *	A file may be deleted.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+int
+Tcl_FSDeleteFile(
+    Tcl_Obj *pathPtr)		/* Pathname of file to be removed (UTF-8). */
+{
+    const Tcl_Filesystem *fsPtr = Tcl_FSGetFileSystemForPath(pathPtr);
+
+    if (fsPtr != NULL && fsPtr->deleteFileProc != NULL) {
+	return fsPtr->deleteFileProc(pathPtr);
+    }
+    Tcl_SetErrno(ENOENT);
+    return -1;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Tcl_FSCreateDirectory --
+ *
+ *	The appropriate function for the filesystem to which pathPtr belongs
+ *	will be called.
+ *
+ * Results:
+ *	Standard Tcl error code.
+ *
+ * Side effects:
+ *	A directory may be created.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+int
+Tcl_FSCreateDirectory(
+    Tcl_Obj *pathPtr)		/* Pathname of directory to create (UTF-8). */
+{
+    const Tcl_Filesystem *fsPtr = Tcl_FSGetFileSystemForPath(pathPtr);
+
+    if (fsPtr != NULL && fsPtr->createDirectoryProc != NULL) {
+	return fsPtr->createDirectoryProc(pathPtr);
+    }
+    Tcl_SetErrno(ENOENT);
+    return -1;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Tcl_FSCopyDirectory --
+ *
+ *	If the two paths given belong to the same filesystem, we call that
+ *	filesystems copy-directory function. Otherwise we simply return the
+ *	POSIX error 'EXDEV', and -1.
+ *
+ * Results:
+ *	Standard Tcl error code if a function was called.
+ *
+ * Side effects:
+ *	A directory may be copied.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+int
+Tcl_FSCopyDirectory(
+    Tcl_Obj *srcPathPtr,	/* Pathname of directory to be copied
+				 * (UTF-8). */
+    Tcl_Obj *destPathPtr,	/* Pathname of target directory (UTF-8). */
+    Tcl_Obj **errorPtr)		/* If non-NULL, then will be set to a new
+				 * object containing name of file causing
+				 * error, with refCount 1. */
+{
+    int retVal = -1;
+    const Tcl_Filesystem *fsPtr, *fsPtr2;
+
+    fsPtr = Tcl_FSGetFileSystemForPath(srcPathPtr);
+    fsPtr2 = Tcl_FSGetFileSystemForPath(destPathPtr);
+
+    if (fsPtr == fsPtr2 && fsPtr != NULL && fsPtr->copyDirectoryProc != NULL){
+	retVal = fsPtr->copyDirectoryProc(srcPathPtr, destPathPtr, errorPtr);
+    }
+    if (retVal == -1) {
+	Tcl_SetErrno(EXDEV);
+    }
+    return retVal;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Tcl_FSRemoveDirectory --
+ *
+ *	The appropriate function for the filesystem to which pathPtr belongs
+ *	will be called.
+ *
+ * Results:
+ *	Standard Tcl error code.
+ *
+ * Side effects:
+ *	A directory may be deleted.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+int
+Tcl_FSRemoveDirectory(
+    Tcl_Obj *pathPtr,		/* Pathname of directory to be removed
+				 * (UTF-8). */
+    int recursive,		/* If non-zero, removes directories that are
+				 * nonempty. Otherwise, will only remove empty
+				 * directories. */
+    Tcl_Obj **errorPtr)		/* If non-NULL, then will be set to a new
+				 * object containing name of file causing
+				 * error, with refCount 1. */
+{
+    const Tcl_Filesystem *fsPtr = Tcl_FSGetFileSystemForPath(pathPtr);
+
+    if (fsPtr == NULL || fsPtr->removeDirectoryProc == NULL) {
+	Tcl_SetErrno(ENOENT);
+	return -1;
+    }
+
+    /*
+     * When working recursively, we check whether the cwd lies inside this
+     * directory and move it if it does.
+     */
+
+    if (recursive) {
+	Tcl_Obj *cwdPtr = Tcl_FSGetCwd(NULL);
+
+	if (cwdPtr != NULL) {
+	    const char *cwdStr, *normPathStr;
+	    int cwdLen, normLen;
+	    Tcl_Obj *normPath = Tcl_FSGetNormalizedPath(NULL, pathPtr);
+
+	    if (normPath != NULL) {
+		normPathStr = Tcl_GetStringFromObj(normPath, &normLen);
+		cwdStr = Tcl_GetStringFromObj(cwdPtr, &cwdLen);
+		if ((cwdLen >= normLen) && (strncmp(normPathStr, cwdStr,
+			(size_t) normLen) == 0)) {
+		    /*
+		     * The cwd is inside the directory, so we perform a 'cd
+		     * [file dirname $path]'.
+		     */
+
+		    Tcl_Obj *dirPtr = TclPathPart(NULL, pathPtr,
+			    TCL_PATH_DIRNAME);
+
+		    Tcl_FSChdir(dirPtr);
+		    Tcl_DecrRefCount(dirPtr);
+		}
+	    }
+	    Tcl_DecrRefCount(cwdPtr);
+	}
+    }
+    return fsPtr->removeDirectoryProc(pathPtr, recursive, errorPtr);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Tcl_FSGetFileSystemForPath --
+ *
+ *	This function determines which filesystem to use for a particular path
+ *	object, and returns the filesystem which accepts this file. If no
+ *	filesystem will accept this object as a valid file path, then NULL is
+ *	returned.
+ *
+ * Results:
+ *	NULL or a filesystem which will accept this path.
+ *
+ * Side effects:
+ *	The object may be converted to a path type.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+const Tcl_Filesystem *
+Tcl_FSGetFileSystemForPath(
+    Tcl_Obj *pathPtr)
+{
+    FilesystemRecord *fsRecPtr;
+    const Tcl_Filesystem *retVal = NULL;
+
+    if (pathPtr == NULL) {
+	Tcl_Panic("Tcl_FSGetFileSystemForPath called with NULL object");
+	return NULL;
+    }
+
+    /*
+     * If the object has a refCount of zero, we reject it. This is to avoid
+     * possible segfaults or nondeterministic memory leaks (i.e. the user
+     * doesn't know if they should decrement the ref count on return or not).
+     */
+
+    if (pathPtr->refCount == 0) {
+	Tcl_Panic("Tcl_FSGetFileSystemForPath called with object with refCount == 0");
+	return NULL;
+    }
+
+    /*
+     * Check if the filesystem has changed in some way since this object's
+     * internal representation was calculated. Before doing that, assure we
+     * have the most up-to-date copy of the master filesystem. This is
+     * accomplished by the FsGetFirstFilesystem() call.
+     */
+
+    fsRecPtr = FsGetFirstFilesystem();
+    Claim();
+
+    if (TclFSEnsureEpochOk(pathPtr, &retVal) != TCL_OK) {
+	Disclaim();
+	return NULL;
+    } else if (retVal != NULL) {
+	/* TODO: Can this happen? */
+	Disclaim();
+	return retVal;
+    }
+
+    /*
+     * Call each of the "pathInFilesystem" functions in succession. A
+     * non-return value of -1 indicates the particular function has succeeded.
+     */
+
+    for (; fsRecPtr!=NULL ; fsRecPtr=fsRecPtr->nextPtr) {
+	ClientData clientData = NULL;
+
+	if (fsRecPtr->fsPtr->pathInFilesystemProc == NULL) {
+	    continue;
+	}
+
+	if (fsRecPtr->fsPtr->pathInFilesystemProc(pathPtr, &clientData)!=-1) {
+	    /*
+	     * We assume the type of pathPtr hasn't been changed by the above
+	     * call to the pathInFilesystemProc.
+	     */
+
+	    TclFSSetPathDetails(pathPtr, fsRecPtr->fsPtr, clientData);
+	    Disclaim();
+	    return fsRecPtr->fsPtr;
+	}
+    }
+    Disclaim();
+
+    return NULL;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Tcl_FSGetNativePath --
+ *
+ *	This function is for use by the Win/Unix native filesystems, so that
+ *	they can easily retrieve the native (char* or TCHAR*) representation
+ *	of a path. Other filesystems will probably want to implement similar
+ *	functions. They basically act as a safety net around
+ *	Tcl_FSGetInternalRep. Normally your file-system functions will always
+ *	be called with path objects already converted to the correct
+ *	filesystem, but if for some reason they are called directly (i.e. by
+ *	functions not in this file), then one cannot necessarily guarantee
+ *	that the path object pointer is from the correct filesystem.
+ *
+ *	Note: in the future it might be desirable to have separate versions
+ *	of this function with different signatures, for example
+ *	Tcl_FSGetNativeWinPath, Tcl_FSGetNativeUnixPath etc. Right now, since
+ *	native paths are all string based, we use just one function.
+ *
+ * Results:
+ *	NULL or a valid native path.
+ *
+ * Side effects:
+ *	See Tcl_FSGetInternalRep.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+const void *
+Tcl_FSGetNativePath(
+    Tcl_Obj *pathPtr)
+{
+    return Tcl_FSGetInternalRep(pathPtr, &tclNativeFilesystem);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * NativeFreeInternalRep --
+ *
+ *	Free a native internal representation, which will be non-NULL.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Memory is released.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+static void
+NativeFreeInternalRep(
+    ClientData clientData)
+{
+    ckfree(clientData);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Tcl_FSFileSystemInfo --
+ *
+ *	This function returns a list of two elements. The first element is the
+ *	name of the filesystem (e.g. "native" or "vfs"), and the second is the
+ *	particular type of the given path within that filesystem.
+ *
+ * Results:
+ *	A list of two elements.
+ *
+ * Side effects:
+ *	The object may be converted to a path type.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+Tcl_Obj *
+Tcl_FSFileSystemInfo(
+    Tcl_Obj *pathPtr)
+{
+    Tcl_Obj *resPtr;
+    const Tcl_Filesystem *fsPtr = Tcl_FSGetFileSystemForPath(pathPtr);
+
+    if (fsPtr == NULL) {
+	return NULL;
+    }
+
+    resPtr = Tcl_NewListObj(0, NULL);
+    Tcl_ListObjAppendElement(NULL, resPtr,
+	    Tcl_NewStringObj(fsPtr->typeName, -1));
+
+    if (fsPtr->filesystemPathTypeProc != NULL) {
+	Tcl_Obj *typePtr = fsPtr->filesystemPathTypeProc(pathPtr);
+
+	if (typePtr != NULL) {
+	    Tcl_ListObjAppendElement(NULL, resPtr, typePtr);
+	}
+    }
+
+    return resPtr;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Tcl_FSPathSeparator --
+ *
+ *	This function returns the separator to be used for a given path. The
+ *	object returned should have a refCount of zero
+ *
+ * Results:
+ *	A Tcl object, with a refCount of zero. If the caller needs to retain a
+ *	reference to the object, it should call Tcl_IncrRefCount, and should
+ *	otherwise free the object.
+ *
+ * Side effects:
+ *	The path object may be converted to a path type.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+Tcl_Obj *
+Tcl_FSPathSeparator(
+    Tcl_Obj *pathPtr)
+{
+    const Tcl_Filesystem *fsPtr = Tcl_FSGetFileSystemForPath(pathPtr);
+    Tcl_Obj *resultObj;
+
+    if (fsPtr == NULL) {
+	return NULL;
+    }
+
+    if (fsPtr->filesystemSeparatorProc != NULL) {
+	return fsPtr->filesystemSeparatorProc(pathPtr);
+    }
+
+    /*
+     * Allow filesystems not to provide a filesystemSeparatorProc if they wish
+     * to use the standard forward slash.
+     */
+
+    TclNewLiteralStringObj(resultObj, "/");
+    return resultObj;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * NativeFilesystemSeparator --
+ *
+ *	This function is part of the native filesystem support, and returns
+ *	the separator for the given path.
+ *
+ * Results:
+ *	String object containing the separator character.
+ *
+ * Side effects:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+static Tcl_Obj *
+NativeFilesystemSeparator(
+    Tcl_Obj *pathPtr)
+{
+    const char *separator = NULL; /* lint */
+
+    switch (tclPlatform) {
+    case TCL_PLATFORM_UNIX:
+	separator = "/";
+	break;
+    case TCL_PLATFORM_WINDOWS:
+	separator = "\\";
+	break;
+    }
+    return Tcl_NewStringObj(separator,1);
+}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tclIndexObj.c b/generic/tclIndexObj.c
new file mode 100644
index 0000000..0e0ddc9
--- /dev/null
+++ b/generic/tclIndexObj.c
@@ -0,0 +1,1489 @@
+/*
+ * tclIndexObj.c --
+ *
+ *	This file implements objects of type "index". This object type is used
+ *	to lookup a keyword in a table of valid values and cache the index of
+ *	the matching entry. Also provides table-based argv/argc processing.
+ *
+ * Copyright (c) 1990-1994 The Regents of the University of California.
+ * Copyright (c) 1997 Sun Microsystems, Inc.
+ * Copyright (c) 2006 Sam Bromley.
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#include "tclInt.h"
+
+/*
+ * Prototypes for functions defined later in this file:
+ */
+
+static int		GetIndexFromObjList(Tcl_Interp *interp,
+			    Tcl_Obj *objPtr, Tcl_Obj *tableObjPtr,
+			    const char *msg, int flags, int *indexPtr);
+static int		SetIndexFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr);
+static void		UpdateStringOfIndex(Tcl_Obj *objPtr);
+static void		DupIndex(Tcl_Obj *srcPtr, Tcl_Obj *dupPtr);
+static void		FreeIndex(Tcl_Obj *objPtr);
+static int		PrefixAllObjCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+static int		PrefixLongestObjCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+static int		PrefixMatchObjCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+static void		PrintUsage(Tcl_Interp *interp,
+			    const Tcl_ArgvInfo *argTable);
+
+/*
+ * The structure below defines the index Tcl object type by means of functions
+ * that can be invoked by generic object code.
+ */
+
+static const Tcl_ObjType indexType = {
+    "index",			/* name */
+    FreeIndex,			/* freeIntRepProc */
+    DupIndex,			/* dupIntRepProc */
+    UpdateStringOfIndex,	/* updateStringProc */
+    SetIndexFromAny		/* setFromAnyProc */
+};
+
+/*
+ * The definition of the internal representation of the "index" object; The
+ * internalRep.twoPtrValue.ptr1 field of an object of "index" type will be a
+ * pointer to one of these structures.
+ *
+ * Keep this structure declaration in sync with tclTestObj.c
+ */
+
+typedef struct {
+    void *tablePtr;		/* Pointer to the table of strings */
+    int offset;			/* Offset between table entries */
+    int index;			/* Selected index into table. */
+} IndexRep;
+
+/*
+ * The following macros greatly simplify moving through a table...
+ */
+
+#define STRING_AT(table, offset) \
+	(*((const char *const *)(((char *)(table)) + (offset))))
+#define NEXT_ENTRY(table, offset) \
+	(&(STRING_AT(table, offset)))
+#define EXPAND_OF(indexRep) \
+	STRING_AT((indexRep)->tablePtr, (indexRep)->offset*(indexRep)->index)
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_GetIndexFromObj --
+ *
+ *	This function looks up an object's value in a table of strings and
+ *	returns the index of the matching string, if any.
+ *
+ * Results:
+ *	If the value of objPtr is identical to or a unique abbreviation for
+ *	one of the entries in tablePtr, then the return value is TCL_OK and the
+ *	index of the matching entry is stored at *indexPtr. If there isn't a
+ *	proper match, then TCL_ERROR is returned and an error message is left
+ *	in interp's result (unless interp is NULL). The msg argument is used
+ *	in the error message; for example, if msg has the value "option" then
+ *	the error message will say something flag 'bad option "foo": must be
+ *	...'
+ *
+ * Side effects:
+ *	The result of the lookup is cached as the internal rep of objPtr, so
+ *	that repeated lookups can be done quickly.
+ *
+ *----------------------------------------------------------------------
+ */
+
+#undef Tcl_GetIndexFromObj
+int
+Tcl_GetIndexFromObj(
+    Tcl_Interp *interp,		/* Used for error reporting if not NULL. */
+    Tcl_Obj *objPtr,		/* Object containing the string to lookup. */
+    const char *const*tablePtr,	/* Array of strings to compare against the
+				 * value of objPtr; last entry must be NULL
+				 * and there must not be duplicate entries. */
+    const char *msg,		/* Identifying word to use in error
+				 * messages. */
+    int flags,			/* 0 or TCL_EXACT */
+    int *indexPtr)		/* Place to store resulting integer index. */
+{
+
+    /*
+     * See if there is a valid cached result from a previous lookup (doing the
+     * check here saves the overhead of calling Tcl_GetIndexFromObjStruct in
+     * the common case where the result is cached).
+     */
+
+    if (objPtr->typePtr == &indexType) {
+	IndexRep *indexRep = objPtr->internalRep.twoPtrValue.ptr1;
+
+	/*
+	 * Here's hoping we don't get hit by unfortunate packing constraints
+	 * on odd platforms like a Cray PVP...
+	 */
+
+	if (indexRep->tablePtr == (void *) tablePtr
+		&& indexRep->offset == sizeof(char *)) {
+	    *indexPtr = indexRep->index;
+	    return TCL_OK;
+	}
+    }
+    return Tcl_GetIndexFromObjStruct(interp, objPtr, tablePtr, sizeof(char *),
+	    msg, flags, indexPtr);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * GetIndexFromObjList --
+ *
+ *	This procedure looks up an object's value in a table of strings and
+ *	returns the index of the matching string, if any.
+ *
+ * Results:
+ *	If the value of objPtr is identical to or a unique abbreviation for
+ *	one of the entries in tableObjPtr, then the return value is TCL_OK and
+ *	the index of the matching entry is stored at *indexPtr. If there isn't
+ *	a proper match, then TCL_ERROR is returned and an error message is
+ *	left in interp's result (unless interp is NULL). The msg argument is
+ *	used in the error message; for example, if msg has the value "option"
+ *	then the error message will say something flag 'bad option "foo": must
+ *	be ...'
+ *
+ * Side effects:
+ *	Removes any internal representation that the object might have. (TODO:
+ *	find a way to cache the lookup.)
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+GetIndexFromObjList(
+    Tcl_Interp *interp,		/* Used for error reporting if not NULL. */
+    Tcl_Obj *objPtr,		/* Object containing the string to lookup. */
+    Tcl_Obj *tableObjPtr,	/* List of strings to compare against the
+				 * value of objPtr. */
+    const char *msg,		/* Identifying word to use in error
+				 * messages. */
+    int flags,			/* 0 or TCL_EXACT */
+    int *indexPtr)		/* Place to store resulting integer index. */
+{
+
+    int objc, result, t;
+    Tcl_Obj **objv;
+    const char **tablePtr;
+
+    /*
+     * Use Tcl_GetIndexFromObjStruct to do the work to avoid duplicating most
+     * of the code there. This is a bit ineffiecient but simpler.
+     */
+
+    result = Tcl_ListObjGetElements(interp, tableObjPtr, &objc, &objv);
+    if (result != TCL_OK) {
+	return result;
+    }
+
+    /*
+     * Build a string table from the list.
+     */
+
+    tablePtr = ckalloc((objc + 1) * sizeof(char *));
+    for (t = 0; t < objc; t++) {
+	if (objv[t] == objPtr) {
+	    /*
+	     * An exact match is always chosen, so we can stop here.
+	     */
+
+	    ckfree(tablePtr);
+	    *indexPtr = t;
+	    return TCL_OK;
+	}
+
+	tablePtr[t] = Tcl_GetString(objv[t]);
+    }
+    tablePtr[objc] = NULL;
+
+    result = Tcl_GetIndexFromObjStruct(interp, objPtr, tablePtr,
+	    sizeof(char *), msg, flags, indexPtr);
+
+    /*
+     * The internal rep must be cleared since tablePtr will go away.
+     */
+
+    TclFreeIntRep(objPtr);
+    ckfree(tablePtr);
+
+    return result;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_GetIndexFromObjStruct --
+ *
+ *	This function looks up an object's value given a starting string and
+ *	an offset for the amount of space between strings. This is useful when
+ *	the strings are embedded in some other kind of array.
+ *
+ * Results:
+ *	If the value of objPtr is identical to or a unique abbreviation for
+ *	one of the entries in tablePtr, then the return value is TCL_OK and
+ *	the index of the matching entry is stored at *indexPtr. If there isn't
+ *	a proper match, then TCL_ERROR is returned and an error message is
+ *	left in interp's result (unless interp is NULL). The msg argument is
+ *	used in the error message; for example, if msg has the value "option"
+ *	then the error message will say something like 'bad option "foo": must
+ *	be ...'
+ *
+ * Side effects:
+ *	The result of the lookup is cached as the internal rep of objPtr, so
+ *	that repeated lookups can be done quickly.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_GetIndexFromObjStruct(
+    Tcl_Interp *interp,		/* Used for error reporting if not NULL. */
+    Tcl_Obj *objPtr,		/* Object containing the string to lookup. */
+    const void *tablePtr,	/* The first string in the table. The second
+				 * string will be at this address plus the
+				 * offset, the third plus the offset again,
+				 * etc. The last entry must be NULL and there
+				 * must not be duplicate entries. */
+    int offset,			/* The number of bytes between entries */
+    const char *msg,		/* Identifying word to use in error
+				 * messages. */
+    int flags,			/* 0 or TCL_EXACT */
+    int *indexPtr)		/* Place to store resulting integer index. */
+{
+    int index, idx, numAbbrev;
+    const char *key, *p1;
+    const char *p2;
+    const char *const *entryPtr;
+    Tcl_Obj *resultPtr;
+    IndexRep *indexRep;
+
+    /* Protect against invalid values, like -1 or 0. */
+    if (offset < (int)sizeof(char *)) {
+	offset = (int)sizeof(char *);
+    }
+    /*
+     * See if there is a valid cached result from a previous lookup.
+     */
+
+    if (objPtr->typePtr == &indexType) {
+	indexRep = objPtr->internalRep.twoPtrValue.ptr1;
+	if (indexRep->tablePtr==tablePtr && indexRep->offset==offset) {
+	    *indexPtr = indexRep->index;
+	    return TCL_OK;
+	}
+    }
+
+    /*
+     * Lookup the value of the object in the table. Accept unique
+     * abbreviations unless TCL_EXACT is set in flags.
+     */
+
+    key = TclGetString(objPtr);
+    index = -1;
+    numAbbrev = 0;
+
+    /*
+     * Scan the table looking for one of:
+     *  - An exact match (always preferred)
+     *  - A single abbreviation (allowed depending on flags)
+     *  - Several abbreviations (never allowed, but overridden by exact match)
+     */
+
+    for (entryPtr = tablePtr, idx = 0; *entryPtr != NULL;
+	    entryPtr = NEXT_ENTRY(entryPtr, offset), idx++) {
+	for (p1 = key, p2 = *entryPtr; *p1 == *p2; p1++, p2++) {
+	    if (*p1 == '\0') {
+		index = idx;
+		goto done;
+	    }
+	}
+	if (*p1 == '\0') {
+	    /*
+	     * The value is an abbreviation for this entry. Continue checking
+	     * other entries to make sure it's unique. If we get more than one
+	     * unique abbreviation, keep searching to see if there is an exact
+	     * match, but remember the number of unique abbreviations and
+	     * don't allow either.
+	     */
+
+	    numAbbrev++;
+	    index = idx;
+	}
+    }
+
+    /*
+     * Check if we were instructed to disallow abbreviations.
+     */
+
+    if ((flags & TCL_EXACT) || (key[0] == '\0') || (numAbbrev != 1)) {
+	goto error;
+    }
+
+  done:
+    /*
+     * Cache the found representation. Note that we want to avoid allocating a
+     * new internal-rep if at all possible since that is potentially a slow
+     * operation.
+     */
+
+    if (objPtr->typePtr == &indexType) {
+	indexRep = objPtr->internalRep.twoPtrValue.ptr1;
+    } else {
+	TclFreeIntRep(objPtr);
+	indexRep = ckalloc(sizeof(IndexRep));
+	objPtr->internalRep.twoPtrValue.ptr1 = indexRep;
+	objPtr->typePtr = &indexType;
+    }
+    indexRep->tablePtr = (void *) tablePtr;
+    indexRep->offset = offset;
+    indexRep->index = index;
+
+    *indexPtr = index;
+    return TCL_OK;
+
+  error:
+    if (interp != NULL) {
+	/*
+	 * Produce a fancy error message.
+	 */
+
+	int count = 0;
+
+	TclNewObj(resultPtr);
+	entryPtr = tablePtr;
+	while ((*entryPtr != NULL) && !**entryPtr) {
+	    entryPtr = NEXT_ENTRY(entryPtr, offset);
+	}
+	Tcl_AppendStringsToObj(resultPtr,
+		(numAbbrev>1 && !(flags & TCL_EXACT) ? "ambiguous " : "bad "),
+		msg, " \"", key, NULL);
+	if (*entryPtr == NULL) {
+	    Tcl_AppendStringsToObj(resultPtr, "\": no valid options", NULL);
+	} else {
+	    Tcl_AppendStringsToObj(resultPtr, "\": must be ",
+		    *entryPtr, NULL);
+	    entryPtr = NEXT_ENTRY(entryPtr, offset);
+	    while (*entryPtr != NULL) {
+		if (*NEXT_ENTRY(entryPtr, offset) == NULL) {
+		    Tcl_AppendStringsToObj(resultPtr, (count > 0 ? "," : ""),
+			    " or ", *entryPtr, NULL);
+		} else if (**entryPtr) {
+		    Tcl_AppendStringsToObj(resultPtr, ", ", *entryPtr, NULL);
+		    count++;
+		}
+		entryPtr = NEXT_ENTRY(entryPtr, offset);
+	    }
+	}
+	Tcl_SetObjResult(interp, resultPtr);
+	Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "INDEX", msg, key, NULL);
+    }
+    return TCL_ERROR;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * SetIndexFromAny --
+ *
+ *	This function is called to convert a Tcl object to index internal
+ *	form. However, this doesn't make sense (need to have a table of
+ *	keywords in order to do the conversion) so the function always
+ *	generates an error.
+ *
+ * Results:
+ *	The return value is always TCL_ERROR, and an error message is left in
+ *	interp's result if interp isn't NULL.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+SetIndexFromAny(
+    Tcl_Interp *interp,		/* Used for error reporting if not NULL. */
+    register Tcl_Obj *objPtr)	/* The object to convert. */
+{
+    if (interp) {
+	Tcl_SetObjResult(interp, Tcl_NewStringObj(
+	    "can't convert value to index except via Tcl_GetIndexFromObj API",
+	    -1));
+    }
+    return TCL_ERROR;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * UpdateStringOfIndex --
+ *
+ *	This function is called to convert a Tcl object from index internal
+ *	form to its string form. No abbreviation is ever generated.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The string representation of the object is updated.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+UpdateStringOfIndex(
+    Tcl_Obj *objPtr)
+{
+    IndexRep *indexRep = objPtr->internalRep.twoPtrValue.ptr1;
+    register char *buf;
+    register unsigned len;
+    register const char *indexStr = EXPAND_OF(indexRep);
+
+    len = strlen(indexStr);
+    buf = ckalloc(len + 1);
+    memcpy(buf, indexStr, len+1);
+    objPtr->bytes = buf;
+    objPtr->length = len;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * DupIndex --
+ *
+ *	This function is called to copy the internal rep of an index Tcl
+ *	object from to another object.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The internal representation of the target object is updated and the
+ *	type is set.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+DupIndex(
+    Tcl_Obj *srcPtr,
+    Tcl_Obj *dupPtr)
+{
+    IndexRep *srcIndexRep = srcPtr->internalRep.twoPtrValue.ptr1;
+    IndexRep *dupIndexRep = ckalloc(sizeof(IndexRep));
+
+    memcpy(dupIndexRep, srcIndexRep, sizeof(IndexRep));
+    dupPtr->internalRep.twoPtrValue.ptr1 = dupIndexRep;
+    dupPtr->typePtr = &indexType;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * FreeIndex --
+ *
+ *	This function is called to delete the internal rep of an index Tcl
+ *	object.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The internal representation of the target object is deleted.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+FreeIndex(
+    Tcl_Obj *objPtr)
+{
+    ckfree(objPtr->internalRep.twoPtrValue.ptr1);
+    objPtr->typePtr = NULL;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclInitPrefixCmd --
+ *
+ *	This procedure creates the "prefix" Tcl command. See the user
+ *	documentation for details on what it does.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_Command
+TclInitPrefixCmd(
+    Tcl_Interp *interp)		/* Current interpreter. */
+{
+    static const EnsembleImplMap prefixImplMap[] = {
+	{"all",	    PrefixAllObjCmd,	TclCompileBasic2ArgCmd, NULL, NULL, 0},
+	{"longest", PrefixLongestObjCmd,TclCompileBasic2ArgCmd, NULL, NULL, 0},
+	{"match",   PrefixMatchObjCmd,	TclCompileBasicMin2ArgCmd, NULL, NULL, 0},
+	{NULL, NULL, NULL, NULL, NULL, 0}
+    };
+    Tcl_Command prefixCmd;
+
+    prefixCmd = TclMakeEnsemble(interp, "::tcl::prefix", prefixImplMap);
+    Tcl_Export(interp, Tcl_FindNamespace(interp, "::tcl", NULL, 0),
+	    "prefix", 0);
+    return prefixCmd;
+}
+
+/*----------------------------------------------------------------------
+ *
+ * PrefixMatchObjCmd --
+ *
+ *	This function implements the 'prefix match' Tcl command. Refer to the
+ *	user documentation for details on what it does.
+ *
+ * Results:
+ *	Returns a standard Tcl result.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+PrefixMatchObjCmd(
+    ClientData clientData,	/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    int flags = 0, result, index;
+    int dummyLength, i, errorLength;
+    Tcl_Obj *errorPtr = NULL;
+    const char *message = "option";
+    Tcl_Obj *tablePtr, *objPtr, *resultPtr;
+    static const char *const matchOptions[] = {
+	"-error", "-exact", "-message", NULL
+    };
+    enum matchOptions {
+	PRFMATCH_ERROR, PRFMATCH_EXACT, PRFMATCH_MESSAGE
+    };
+
+    if (objc < 3) {
+	Tcl_WrongNumArgs(interp, 1, objv, "?options? table string");
+	return TCL_ERROR;
+    }
+
+    for (i = 1; i < (objc - 2); i++) {
+	if (Tcl_GetIndexFromObj(interp, objv[i], matchOptions, "option", 0,
+		&index) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	switch ((enum matchOptions) index) {
+	case PRFMATCH_EXACT:
+	    flags |= TCL_EXACT;
+	    break;
+	case PRFMATCH_MESSAGE:
+	    if (i > objc-4) {
+		Tcl_SetObjResult(interp, Tcl_NewStringObj(
+			"missing value for -message", -1));
+		Tcl_SetErrorCode(interp, "TCL", "OPERATION", "NOARG", NULL);
+		return TCL_ERROR;
+	    }
+	    i++;
+	    message = Tcl_GetString(objv[i]);
+	    break;
+	case PRFMATCH_ERROR:
+	    if (i > objc-4) {
+		Tcl_SetObjResult(interp, Tcl_NewStringObj(
+			"missing value for -error", -1));
+		Tcl_SetErrorCode(interp, "TCL", "OPERATION", "NOARG", NULL);
+		return TCL_ERROR;
+	    }
+	    i++;
+	    result = Tcl_ListObjLength(interp, objv[i], &errorLength);
+	    if (result != TCL_OK) {
+		return TCL_ERROR;
+	    }
+	    if ((errorLength % 2) != 0) {
+		Tcl_SetObjResult(interp, Tcl_NewStringObj(
+			"error options must have an even number of elements",
+			-1));
+		Tcl_SetErrorCode(interp, "TCL", "VALUE", "DICTIONARY", NULL);
+		return TCL_ERROR;
+	    }
+	    errorPtr = objv[i];
+	    break;
+	}
+    }
+
+    tablePtr = objv[objc - 2];
+    objPtr = objv[objc - 1];
+
+    /*
+     * Check that table is a valid list first, since we want to handle that
+     * error case regardless of level.
+     */
+
+    result = Tcl_ListObjLength(interp, tablePtr, &dummyLength);
+    if (result != TCL_OK) {
+	return result;
+    }
+
+    result = GetIndexFromObjList(interp, objPtr, tablePtr, message, flags,
+	    &index);
+    if (result != TCL_OK) {
+	if (errorPtr != NULL && errorLength == 0) {
+	    Tcl_ResetResult(interp);
+	    return TCL_OK;
+	} else if (errorPtr == NULL) {
+	    return TCL_ERROR;
+	}
+
+	if (Tcl_IsShared(errorPtr)) {
+	    errorPtr = Tcl_DuplicateObj(errorPtr);
+	}
+	Tcl_ListObjAppendElement(interp, errorPtr,
+		Tcl_NewStringObj("-code", 5));
+	Tcl_ListObjAppendElement(interp, errorPtr, Tcl_NewIntObj(result));
+
+	return Tcl_SetReturnOptions(interp, errorPtr);
+    }
+
+    result = Tcl_ListObjIndex(interp, tablePtr, index, &resultPtr);
+    if (result != TCL_OK) {
+	return result;
+    }
+    Tcl_SetObjResult(interp, resultPtr);
+    return TCL_OK;
+}
+
+/*----------------------------------------------------------------------
+ *
+ * PrefixAllObjCmd --
+ *
+ *	This function implements the 'prefix all' Tcl command. Refer to the
+ *	user documentation for details on what it does.
+ *
+ * Results:
+ *	Returns a standard Tcl result.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+PrefixAllObjCmd(
+    ClientData clientData,	/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    int tableObjc, result, t, length, elemLength;
+    const char *string, *elemString;
+    Tcl_Obj **tableObjv, *resultPtr;
+
+    if (objc != 3) {
+	Tcl_WrongNumArgs(interp, 1, objv, "table string");
+	return TCL_ERROR;
+    }
+
+    result = Tcl_ListObjGetElements(interp, objv[1], &tableObjc, &tableObjv);
+    if (result != TCL_OK) {
+	return result;
+    }
+    resultPtr = Tcl_NewListObj(0, NULL);
+    string = Tcl_GetStringFromObj(objv[2], &length);
+
+    for (t = 0; t < tableObjc; t++) {
+	elemString = Tcl_GetStringFromObj(tableObjv[t], &elemLength);
+
+	/*
+	 * A prefix cannot match if it is longest.
+	 */
+
+	if (length <= elemLength) {
+	    if (TclpUtfNcmp2(elemString, string, length) == 0) {
+		Tcl_ListObjAppendElement(interp, resultPtr, tableObjv[t]);
+	    }
+	}
+    }
+
+    Tcl_SetObjResult(interp, resultPtr);
+    return TCL_OK;
+}
+
+/*----------------------------------------------------------------------
+ *
+ * PrefixLongestObjCmd --
+ *
+ *	This function implements the 'prefix longest' Tcl command. Refer to
+ *	the user documentation for details on what it does.
+ *
+ * Results:
+ *	Returns a standard Tcl result.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+PrefixLongestObjCmd(
+    ClientData clientData,	/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    int tableObjc, result, i, t, length, elemLength, resultLength;
+    const char *string, *elemString, *resultString;
+    Tcl_Obj **tableObjv;
+
+    if (objc != 3) {
+	Tcl_WrongNumArgs(interp, 1, objv, "table string");
+	return TCL_ERROR;
+    }
+
+    result = Tcl_ListObjGetElements(interp, objv[1], &tableObjc, &tableObjv);
+    if (result != TCL_OK) {
+	return result;
+    }
+    string = Tcl_GetStringFromObj(objv[2], &length);
+
+    resultString = NULL;
+    resultLength = 0;
+
+    for (t = 0; t < tableObjc; t++) {
+	elemString = Tcl_GetStringFromObj(tableObjv[t], &elemLength);
+
+	/*
+	 * First check if the prefix string matches the element. A prefix
+	 * cannot match if it is longest.
+	 */
+
+	if ((length > elemLength) ||
+		TclpUtfNcmp2(elemString, string, length) != 0) {
+	    continue;
+	}
+
+	if (resultString == NULL) {
+	    /*
+	     * If this is the first match, the longest common substring this
+	     * far is the complete string. The result is part of this string
+	     * so we only need to adjust the length later.
+	     */
+
+	    resultString = elemString;
+	    resultLength = elemLength;
+	} else {
+	    /*
+	     * Longest common substring cannot be longer than shortest string.
+	     */
+
+	    if (elemLength < resultLength) {
+		resultLength = elemLength;
+	    }
+
+	    /*
+	     * Compare strings.
+	     */
+
+	    for (i = 0; i < resultLength; i++) {
+		if (resultString[i] != elemString[i]) {
+		    /*
+		     * Adjust in case we stopped in the middle of a UTF char.
+		     */
+
+		    resultLength = Tcl_UtfPrev(&resultString[i+1],
+			    resultString) - resultString;
+		    break;
+		}
+	    }
+	}
+    }
+    if (resultLength > 0) {
+	Tcl_SetObjResult(interp,
+		Tcl_NewStringObj(resultString, resultLength));
+    }
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_WrongNumArgs --
+ *
+ *	This function generates a "wrong # args" error message in an
+ *	interpreter. It is used as a utility function by many command
+ *	functions, including the function that implements procedures.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	An error message is generated in interp's result object to indicate
+ *	that a command was invoked with the wrong number of arguments. The
+ *	message has the form
+ *		wrong # args: should be "foo bar additional stuff"
+ *	where "foo" and "bar" are the initial objects in objv (objc determines
+ *	how many of these are printed) and "additional stuff" is the contents
+ *	of the message argument.
+ *
+ *	The message printed is modified somewhat if the command is wrapped
+ *	inside an ensemble. In that case, the error message generated is
+ *	rewritten in such a way that it appears to be generated from the
+ *	user-visible command and not how that command is actually implemented,
+ *	giving a better overall user experience.
+ *
+ *	Internally, the Tcl core may set the flag INTERP_ALTERNATE_WRONG_ARGS
+ *	in the interpreter to generate complex multi-part messages by calling
+ *	this function repeatedly. This allows the code that knows how to
+ *	handle ensemble-related error messages to be kept here while still
+ *	generating suitable error messages for commands like [read] and
+ *	[socket]. Ideally, this would be done through an extra flags argument,
+ *	but that wouldn't be source-compatible with the existing API and it's
+ *	a fairly rare requirement anyway.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_WrongNumArgs(
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments to print from objv. */
+    Tcl_Obj *const objv[],	/* Initial argument objects, which should be
+				 * included in the error message. */
+    const char *message)	/* Error message to print after the leading
+				 * objects in objv. The message may be
+				 * NULL. */
+{
+    Tcl_Obj *objPtr;
+    int i, len, elemLen, flags;
+    Interp *iPtr = (Interp *) interp;
+    const char *elementStr;
+
+    /*
+     * [incr Tcl] does something fairly horrific when generating error
+     * messages for its ensembles; it passes the whole set of ensemble
+     * arguments as a list in the first argument. This means that this code
+     * causes a problem in iTcl if it attempts to correctly quote all
+     * arguments, which would be the correct thing to do. We work around this
+     * nasty behaviour for now, and hope that we can remove it all in the
+     * future...
+     */
+
+#ifndef AVOID_HACKS_FOR_ITCL
+    int isFirst = 1;		/* Special flag used to inhibit the treating
+				 * of the first word as a list element so the
+				 * hacky way Itcl generates error messages for
+				 * its ensembles will still work. [Bug
+				 * 1066837] */
+#   define MAY_QUOTE_WORD	(!isFirst)
+#   define AFTER_FIRST_WORD	(isFirst = 0)
+#else /* !AVOID_HACKS_FOR_ITCL */
+#   define MAY_QUOTE_WORD	1
+#   define AFTER_FIRST_WORD	(void) 0
+#endif /* AVOID_HACKS_FOR_ITCL */
+
+    TclNewObj(objPtr);
+    if (iPtr->flags & INTERP_ALTERNATE_WRONG_ARGS) {
+	iPtr->flags &= ~INTERP_ALTERNATE_WRONG_ARGS;
+	Tcl_AppendObjToObj(objPtr, Tcl_GetObjResult(interp));
+	Tcl_AppendToObj(objPtr, " or \"", -1);
+    } else {
+	Tcl_AppendToObj(objPtr, "wrong # args: should be \"", -1);
+    }
+
+    /*
+     * Check to see if we are processing an ensemble implementation, and if so
+     * rewrite the results in terms of how the ensemble was invoked.
+     */
+
+    if (iPtr->ensembleRewrite.sourceObjs != NULL) {
+	int toSkip = iPtr->ensembleRewrite.numInsertedObjs;
+	int toPrint = iPtr->ensembleRewrite.numRemovedObjs;
+	Tcl_Obj *const *origObjv = iPtr->ensembleRewrite.sourceObjs;
+
+	/*
+	 * Check for spelling fixes, and substitute the fixed values.
+	 */
+
+	if (origObjv[0] == NULL) {
+	    origObjv = (Tcl_Obj *const *)origObjv[2];
+	}
+
+	/*
+	 * We only know how to do rewriting if all the replaced objects are
+	 * actually arguments (in objv) to this function. Otherwise it just
+	 * gets too complicated and we'd be better off just giving a slightly
+	 * confusing error message...
+	 */
+
+	if (objc < toSkip) {
+	    goto addNormalArgumentsToMessage;
+	}
+
+	/*
+	 * Strip out the actual arguments that the ensemble inserted.
+	 */
+
+	objv += toSkip;
+	objc -= toSkip;
+
+	/*
+	 * We assume no object is of index type.
+	 */
+
+	for (i=0 ; i<toPrint ; i++) {
+	    /*
+	     * Add the element, quoting it if necessary.
+	     */
+
+	    if (origObjv[i]->typePtr == &indexType) {
+		register IndexRep *indexRep =
+			origObjv[i]->internalRep.twoPtrValue.ptr1;
+
+		elementStr = EXPAND_OF(indexRep);
+		elemLen = strlen(elementStr);
+	    } else {
+		elementStr = TclGetStringFromObj(origObjv[i], &elemLen);
+	    }
+	    flags = 0;
+	    len = TclScanElement(elementStr, elemLen, &flags);
+
+	    if (MAY_QUOTE_WORD && len != elemLen) {
+		char *quotedElementStr = TclStackAlloc(interp,
+			(unsigned)len + 1);
+
+		len = TclConvertElement(elementStr, elemLen,
+			quotedElementStr, flags);
+		Tcl_AppendToObj(objPtr, quotedElementStr, len);
+		TclStackFree(interp, quotedElementStr);
+	    } else {
+		Tcl_AppendToObj(objPtr, elementStr, elemLen);
+	    }
+
+	    AFTER_FIRST_WORD;
+
+	    /*
+	     * Add a space if the word is not the last one (which has a
+	     * moderately complex condition here).
+	     */
+
+	    if (i<toPrint-1 || objc!=0 || message!=NULL) {
+		Tcl_AppendStringsToObj(objPtr, " ", NULL);
+	    }
+	}
+    }
+
+    /*
+     * Now add the arguments (other than those rewritten) that the caller took
+     * from its calling context.
+     */
+
+  addNormalArgumentsToMessage:
+    for (i = 0; i < objc; i++) {
+	/*
+	 * If the object is an index type use the index table which allows for
+	 * the correct error message even if the subcommand was abbreviated.
+	 * Otherwise, just use the string rep.
+	 */
+
+	if (objv[i]->typePtr == &indexType) {
+	    register IndexRep *indexRep = objv[i]->internalRep.twoPtrValue.ptr1;
+
+	    Tcl_AppendStringsToObj(objPtr, EXPAND_OF(indexRep), NULL);
+	} else {
+	    /*
+	     * Quote the argument if it contains spaces (Bug 942757).
+	     */
+
+	    elementStr = TclGetStringFromObj(objv[i], &elemLen);
+	    flags = 0;
+	    len = TclScanElement(elementStr, elemLen, &flags);
+
+	    if (MAY_QUOTE_WORD && len != elemLen) {
+		char *quotedElementStr = TclStackAlloc(interp,
+			(unsigned) len + 1);
+
+		len = TclConvertElement(elementStr, elemLen,
+			quotedElementStr, flags);
+		Tcl_AppendToObj(objPtr, quotedElementStr, len);
+		TclStackFree(interp, quotedElementStr);
+	    } else {
+		Tcl_AppendToObj(objPtr, elementStr, elemLen);
+	    }
+	}
+
+	AFTER_FIRST_WORD;
+
+	/*
+	 * Append a space character (" ") if there is more text to follow
+	 * (either another element from objv, or the message string).
+	 */
+
+	if (i<objc-1 || message!=NULL) {
+	    Tcl_AppendStringsToObj(objPtr, " ", NULL);
+	}
+    }
+
+    /*
+     * Add any trailing message bits and set the resulting string as the
+     * interpreter result. Caller is responsible for reporting this as an
+     * actual error.
+     */
+
+    if (message != NULL) {
+	Tcl_AppendStringsToObj(objPtr, message, NULL);
+    }
+    Tcl_AppendStringsToObj(objPtr, "\"", NULL);
+    Tcl_SetErrorCode(interp, "TCL", "WRONGARGS", NULL);
+    Tcl_SetObjResult(interp, objPtr);
+#undef MAY_QUOTE_WORD
+#undef AFTER_FIRST_WORD
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_ParseArgsObjv --
+ *
+ *	Process an objv array according to a table of expected command-line
+ *	options. See the manual page for more details.
+ *
+ * Results:
+ *	The return value is a standard Tcl return value. If an error occurs
+ *	then an error message is left in the interp's result. Under normal
+ *	conditions, both *objcPtr and *objv are modified to return the
+ *	arguments that couldn't be processed here (they didn't match the
+ *	option table, or followed an TCL_ARGV_REST argument).
+ *
+ * Side effects:
+ *	Variables may be modified, or procedures may be called. It all depends
+ *	on the arguments and their entries in argTable. See the user
+ *	documentation for details.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_ParseArgsObjv(
+    Tcl_Interp *interp,		/* Place to store error message. */
+    const Tcl_ArgvInfo *argTable,
+				/* Array of option descriptions. */
+    int *objcPtr,		/* Number of arguments in objv. Modified to
+				 * hold # args left in objv at end. */
+    Tcl_Obj *const *objv,	/* Array of arguments to be parsed. */
+    Tcl_Obj ***remObjv)		/* Pointer to array of arguments that were not
+				 * processed here. Should be NULL if no return
+				 * of arguments is desired. */
+{
+    Tcl_Obj **leftovers;	/* Array to write back to remObjv on
+				 * successful exit. Will include the name of
+				 * the command. */
+    int nrem;			/* Size of leftovers.*/
+    register const Tcl_ArgvInfo *infoPtr;
+				/* Pointer to the current entry in the table
+				 * of argument descriptions. */
+    const Tcl_ArgvInfo *matchPtr;
+				/* Descriptor that matches current argument */
+    Tcl_Obj *curArg;		/* Current argument */
+    const char *str = NULL;
+    register char c;		/* Second character of current arg (used for
+				 * quick check for matching; use 2nd char.
+				 * because first char. will almost always be
+				 * '-'). */
+    int srcIndex;		/* Location from which to read next argument
+				 * from objv. */
+    int dstIndex;		/* Used to keep track of current arguments
+				 * being processed, primarily for error
+				 * reporting. */
+    int objc;			/* # arguments in objv still to process. */
+    int length;			/* Number of characters in current argument */
+
+    if (remObjv != NULL) {
+	/*
+	 * Then we should copy the name of the command (0th argument). The
+	 * upper bound on the number of elements is known, and (undocumented,
+	 * but historically true) there should be a NULL argument after the
+	 * last result. [Bug 3413857]
+	 */
+
+	nrem = 1;
+	leftovers = ckalloc((1 + *objcPtr) * sizeof(Tcl_Obj *));
+	leftovers[0] = objv[0];
+    } else {
+	nrem = 0;
+	leftovers = NULL;
+    }
+
+    /*
+     * OK, now start processing from the second element (1st argument).
+     */
+
+    srcIndex = dstIndex = 1;
+    objc = *objcPtr-1;
+
+    while (objc > 0) {
+	curArg = objv[srcIndex];
+	srcIndex++;
+	objc--;
+	str = Tcl_GetStringFromObj(curArg, &length);
+	if (length > 0) {
+	    c = str[1];
+	} else {
+	    c = 0;
+	}
+
+	/*
+	 * Loop throught the argument descriptors searching for one with the
+	 * matching key string. If found, leave a pointer to it in matchPtr.
+	 */
+
+	matchPtr = NULL;
+	infoPtr = argTable;
+	for (; infoPtr != NULL && infoPtr->type != TCL_ARGV_END ; infoPtr++) {
+	    if (infoPtr->keyStr == NULL) {
+		continue;
+	    }
+	    if ((infoPtr->keyStr[1] != c)
+		    || (strncmp(infoPtr->keyStr, str, length) != 0)) {
+		continue;
+	    }
+	    if (infoPtr->keyStr[length] == 0) {
+		matchPtr = infoPtr;
+		goto gotMatch;
+	    }
+	    if (matchPtr != NULL) {
+		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+			"ambiguous option \"%s\"", str));
+		goto error;
+	    }
+	    matchPtr = infoPtr;
+	}
+	if (matchPtr == NULL) {
+	    /*
+	     * Unrecognized argument. Just copy it down, unless the caller
+	     * prefers an error to be registered.
+	     */
+
+	    if (remObjv == NULL) {
+		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+			"unrecognized argument \"%s\"", str));
+		goto error;
+	    }
+
+	    dstIndex++;		/* This argument is now handled */
+	    leftovers[nrem++] = curArg;
+	    continue;
+	}
+
+	/*
+	 * Take the appropriate action based on the option type
+	 */
+
+    gotMatch:
+	infoPtr = matchPtr;
+	switch (infoPtr->type) {
+	case TCL_ARGV_CONSTANT:
+	    *((int *) infoPtr->dstPtr) = PTR2INT(infoPtr->srcPtr);
+	    break;
+	case TCL_ARGV_INT:
+	    if (objc == 0) {
+		goto missingArg;
+	    }
+	    if (Tcl_GetIntFromObj(interp, objv[srcIndex],
+		    (int *) infoPtr->dstPtr) == TCL_ERROR) {
+		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+			"expected integer argument for \"%s\" but got \"%s\"",
+			infoPtr->keyStr, Tcl_GetString(objv[srcIndex])));
+		goto error;
+	    }
+	    srcIndex++;
+	    objc--;
+	    break;
+	case TCL_ARGV_STRING:
+	    if (objc == 0) {
+		goto missingArg;
+	    }
+	    *((const char **) infoPtr->dstPtr) =
+		    Tcl_GetString(objv[srcIndex]);
+	    srcIndex++;
+	    objc--;
+	    break;
+	case TCL_ARGV_REST:
+	    /*
+	     * Only store the point where we got to if it's not to be written
+	     * to NULL, so that TCL_ARGV_AUTO_REST works.
+	     */
+
+	    if (infoPtr->dstPtr != NULL) {
+		*((int *) infoPtr->dstPtr) = dstIndex;
+	    }
+	    goto argsDone;
+	case TCL_ARGV_FLOAT:
+	    if (objc == 0) {
+		goto missingArg;
+	    }
+	    if (Tcl_GetDoubleFromObj(interp, objv[srcIndex],
+		    (double *) infoPtr->dstPtr) == TCL_ERROR) {
+		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+			"expected floating-point argument for \"%s\" but got \"%s\"",
+			infoPtr->keyStr, Tcl_GetString(objv[srcIndex])));
+		goto error;
+	    }
+	    srcIndex++;
+	    objc--;
+	    break;
+	case TCL_ARGV_FUNC: {
+	    Tcl_ArgvFuncProc *handlerProc = (Tcl_ArgvFuncProc *)
+		    infoPtr->srcPtr;
+	    Tcl_Obj *argObj;
+
+	    if (objc == 0) {
+		argObj = NULL;
+	    } else {
+		argObj = objv[srcIndex];
+	    }
+	    if (handlerProc(infoPtr->clientData, argObj, infoPtr->dstPtr)) {
+		srcIndex++;
+		objc--;
+	    }
+	    break;
+	}
+	case TCL_ARGV_GENFUNC: {
+	    Tcl_ArgvGenFuncProc *handlerProc = (Tcl_ArgvGenFuncProc *)
+		    infoPtr->srcPtr;
+
+	    objc = handlerProc(infoPtr->clientData, interp, objc,
+		    &objv[srcIndex], infoPtr->dstPtr);
+	    if (objc < 0) {
+		goto error;
+	    }
+	    break;
+	}
+	case TCL_ARGV_HELP:
+	    PrintUsage(interp, argTable);
+	    goto error;
+	default:
+	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		    "bad argument type %d in Tcl_ArgvInfo", infoPtr->type));
+	    goto error;
+	}
+    }
+
+    /*
+     * If we broke out of the loop because of an OPT_REST argument, copy the
+     * remaining arguments down. Note that there is always at least one
+     * argument left over - the command name - so we always have a result if
+     * our caller is willing to receive it. [Bug 3413857]
+     */
+
+  argsDone:
+    if (remObjv == NULL) {
+	/*
+	 * Nothing to do.
+	 */
+
+	return TCL_OK;
+    }
+
+    if (objc > 0) {
+	memcpy(leftovers+nrem, objv+srcIndex, objc*sizeof(Tcl_Obj *));
+	nrem += objc;
+    }
+    leftovers[nrem] = NULL;
+    *objcPtr = nrem++;
+    *remObjv = ckrealloc(leftovers, nrem * sizeof(Tcl_Obj *));
+    return TCL_OK;
+
+    /*
+     * Make sure to handle freeing any temporary space we've allocated on the
+     * way to an error.
+     */
+
+  missingArg:
+    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+	    "\"%s\" option requires an additional argument", str));
+  error:
+    if (leftovers != NULL) {
+	ckfree(leftovers);
+    }
+    return TCL_ERROR;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * PrintUsage --
+ *
+ *	Generate a help string describing command-line options.
+ *
+ * Results:
+ *	The interp's result will be modified to hold a help string describing
+ *	all the options in argTable.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+PrintUsage(
+    Tcl_Interp *interp,		/* Place information in this interp's result
+				 * area. */
+    const Tcl_ArgvInfo *argTable)
+				/* Array of command-specific argument
+				 * descriptions. */
+{
+    register const Tcl_ArgvInfo *infoPtr;
+    int width, numSpaces;
+#define NUM_SPACES 20
+    static const char spaces[] = "                    ";
+    char tmp[TCL_DOUBLE_SPACE];
+    Tcl_Obj *msg;
+
+    /*
+     * First, compute the width of the widest option key, so that we can make
+     * everything line up.
+     */
+
+    width = 4;
+    for (infoPtr = argTable; infoPtr->type != TCL_ARGV_END; infoPtr++) {
+	int length;
+
+	if (infoPtr->keyStr == NULL) {
+	    continue;
+	}
+	length = strlen(infoPtr->keyStr);
+	if (length > width) {
+	    width = length;
+	}
+    }
+
+    /*
+     * Now add the option information, with pretty-printing.
+     */
+
+    msg = Tcl_NewStringObj("Command-specific options:", -1);
+    for (infoPtr = argTable; infoPtr->type != TCL_ARGV_END; infoPtr++) {
+	if ((infoPtr->type == TCL_ARGV_HELP) && (infoPtr->keyStr == NULL)) {
+	    Tcl_AppendPrintfToObj(msg, "\n%s", infoPtr->helpStr);
+	    continue;
+	}
+	Tcl_AppendPrintfToObj(msg, "\n %s:", infoPtr->keyStr);
+	numSpaces = width + 1 - strlen(infoPtr->keyStr);
+	while (numSpaces > 0) {
+	    if (numSpaces >= NUM_SPACES) {
+		Tcl_AppendToObj(msg, spaces, NUM_SPACES);
+	    } else {
+		Tcl_AppendToObj(msg, spaces, numSpaces);
+	    }
+	    numSpaces -= NUM_SPACES;
+	}
+	Tcl_AppendToObj(msg, infoPtr->helpStr, -1);
+	switch (infoPtr->type) {
+	case TCL_ARGV_INT:
+	    Tcl_AppendPrintfToObj(msg, "\n\t\tDefault value: %d",
+		    *((int *) infoPtr->dstPtr));
+	    break;
+	case TCL_ARGV_FLOAT:
+	    Tcl_AppendPrintfToObj(msg, "\n\t\tDefault value: %g",
+		    *((double *) infoPtr->dstPtr));
+	    sprintf(tmp, "%g", *((double *) infoPtr->dstPtr));
+	    break;
+	case TCL_ARGV_STRING: {
+	    char *string = *((char **) infoPtr->dstPtr);
+
+	    if (string != NULL) {
+		Tcl_AppendPrintfToObj(msg, "\n\t\tDefault value: \"%s\"",
+			string);
+	    }
+	    break;
+	}
+	default:
+	    break;
+	}
+    }
+    Tcl_SetObjResult(interp, msg);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclGetCompletionCodeFromObj --
+ *
+ *	Parses Completion code Code
+ *
+ * Results:
+ *	Returns TCL_ERROR if the value is an invalid completion code.
+ *	Otherwise, returns TCL_OK, and writes the completion code to the
+ *	pointer provided.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclGetCompletionCodeFromObj(
+    Tcl_Interp *interp,		/* Current interpreter. */
+    Tcl_Obj *value,
+    int *codePtr)		/* Argument objects. */
+{
+    static const char *const returnCodes[] = {
+	"ok", "error", "return", "break", "continue", NULL
+    };
+
+    if ((value->typePtr != &indexType)
+	    && TclGetIntFromObj(NULL, value, codePtr) == TCL_OK) {
+	return TCL_OK;
+    }
+    if (Tcl_GetIndexFromObj(NULL, value, returnCodes, NULL, TCL_EXACT,
+	    codePtr) == TCL_OK) {
+	return TCL_OK;
+    }
+
+    /*
+     * Value is not a legal completion code.
+     */
+
+    if (interp != NULL) {
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		"bad completion code \"%s\": must be"
+		" ok, error, return, break, continue, or an integer",
+		TclGetString(value)));
+	Tcl_SetErrorCode(interp, "TCL", "RESULT", "ILLEGAL_CODE", NULL);
+    }
+    return TCL_ERROR;
+}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tclInt.decls b/generic/tclInt.decls
new file mode 100644
index 0000000..4e7e422
--- /dev/null
+++ b/generic/tclInt.decls
@@ -0,0 +1,1261 @@
+# tclInt.decls --
+#
+#	This file contains the declarations for all unsupported
+#	functions that are exported by the Tcl library.  This file
+#	is used to generate the tclIntDecls.h, tclIntPlatDecls.h
+#	and tclStubInit.c files
+#
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+# Copyright (c) 2001 by Kevin B. Kenny.  All rights reserved.
+# Copyright (c) 2007 Daniel A. Steffen <das@users.sourceforge.net>
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+library tcl
+
+# Define the unsupported generic interfaces.
+
+interface tclInt
+
+# Declare each of the functions in the unsupported internal Tcl
+# interface.  These interfaces are allowed to changed between versions.
+# Use at your own risk.  Note that the position of functions should not
+# be changed between versions to avoid gratuitous incompatibilities.
+
+# Replaced by Tcl_FSAccess in 8.4:
+#declare 0 {
+#    int TclAccess(const char *path, int mode)
+#}
+#declare 1 {
+#    int TclAccessDeleteProc(TclAccessProc_ *proc)
+#}
+#declare 2 {
+#    int TclAccessInsertProc(TclAccessProc_ *proc)
+#}
+declare 3 {
+    void TclAllocateFreeObjects(void)
+}
+# Replaced by TclpChdir in 8.1:
+#  declare 4 {
+#      int TclChdir(Tcl_Interp *interp, char *dirName)
+#  }
+declare 5 {
+    int TclCleanupChildren(Tcl_Interp *interp, int numPids, Tcl_Pid *pidPtr,
+	    Tcl_Channel errorChan)
+}
+declare 6 {
+    void TclCleanupCommand(Command *cmdPtr)
+}
+declare 7 {
+    int TclCopyAndCollapse(int count, const char *src, char *dst)
+}
+declare 8 {
+    int TclCopyChannelOld(Tcl_Interp *interp, Tcl_Channel inChan,
+	    Tcl_Channel outChan, int toRead, Tcl_Obj *cmdPtr)
+}
+
+# TclCreatePipeline unofficially exported for use by BLT.
+
+declare 9 {
+    int TclCreatePipeline(Tcl_Interp *interp, int argc, const char **argv,
+	    Tcl_Pid **pidArrayPtr, TclFile *inPipePtr, TclFile *outPipePtr,
+	    TclFile *errFilePtr)
+}
+declare 10 {
+    int TclCreateProc(Tcl_Interp *interp, Namespace *nsPtr,
+	    const char *procName,
+	    Tcl_Obj *argsPtr, Tcl_Obj *bodyPtr, Proc **procPtrPtr)
+}
+declare 11 {
+    void TclDeleteCompiledLocalVars(Interp *iPtr, CallFrame *framePtr)
+}
+declare 12 {
+    void TclDeleteVars(Interp *iPtr, TclVarHashTable *tablePtr)
+}
+# Removed in 8.5
+#declare 13 {
+#    int TclDoGlob(Tcl_Interp *interp, char *separators,
+#	    Tcl_DString *headPtr, char *tail, Tcl_GlobTypeData *types)
+#}
+declare 14 {
+    int TclDumpMemoryInfo(ClientData clientData, int flags)
+}
+# Removed in 8.1:
+#  declare 15 {
+#      void TclExpandParseValue(ParseValue *pvPtr, int needed)
+#  }
+declare 16 {
+    void TclExprFloatError(Tcl_Interp *interp, double value)
+}
+# Removed in 8.4
+#declare 17 {
+#    int TclFileAttrsCmd(Tcl_Interp *interp, int objc, Tcl_Obj *const objv[])
+#}
+#declare 18 {
+#    int TclFileCopyCmd(Tcl_Interp *interp, int argc, char **argv)
+#}
+#declare 19 {
+#    int TclFileDeleteCmd(Tcl_Interp *interp, int argc, char **argv)
+#}
+#declare 20 {
+#    int TclFileMakeDirsCmd(Tcl_Interp *interp, int argc, char **argv)
+#}
+#declare 21 {
+#    int TclFileRenameCmd(Tcl_Interp *interp, int argc, char **argv)
+#}
+declare 22 {
+    int TclFindElement(Tcl_Interp *interp, const char *listStr,
+	    int listLength, const char **elementPtr, const char **nextPtr,
+	    int *sizePtr, int *bracePtr)
+}
+declare 23 {
+    Proc *TclFindProc(Interp *iPtr, const char *procName)
+}
+# Replaced with macro (see tclInt.h) in Tcl 8.5.0, restored in 8.5.10
+declare 24 {
+    int TclFormatInt(char *buffer, long n)
+}
+declare 25 {
+    void TclFreePackageInfo(Interp *iPtr)
+}
+# Removed in 8.1:
+#  declare 26 {
+#      char *TclGetCwd(Tcl_Interp *interp)
+#  }
+# Removed in 8.5
+#declare 27 {
+#    int TclGetDate(char *p, unsigned long now, long zone,
+#	    unsigned long *timePtr)
+#}
+declare 28 {
+    Tcl_Channel TclpGetDefaultStdChannel(int type)
+}
+# Removed in 8.4b2:
+#declare 29 {
+#    Tcl_Obj *TclGetElementOfIndexedArray(Tcl_Interp *interp,
+#	    int localIndex, Tcl_Obj *elemPtr, int flags)
+#}
+# Replaced by char *TclGetEnv(const char *name, Tcl_DString *valuePtr) in 8.1:
+#  declare 30 {
+#      char *TclGetEnv(const char *name)
+#  }
+declare 31 {
+    const char *TclGetExtension(const char *name)
+}
+declare 32 {
+    int TclGetFrame(Tcl_Interp *interp, const char *str,
+	    CallFrame **framePtrPtr)
+}
+# Removed in Tcl 8.5
+#declare 33 {
+#    TclCmdProcType TclGetInterpProc(void)
+#}
+declare 34 {
+    int TclGetIntForIndex(Tcl_Interp *interp, Tcl_Obj *objPtr,
+	    int endValue, int *indexPtr)
+}
+# Removed in 8.4b2:
+#declare 35 {
+#    Tcl_Obj *TclGetIndexedScalar(Tcl_Interp *interp, int localIndex,
+#	    int flags)
+#}
+# Removed in 8.6a2
+#declare 36 {
+#    int TclGetLong(Tcl_Interp *interp, const char *str, long *longPtr)
+#}
+declare 37 {
+    int TclGetLoadedPackages(Tcl_Interp *interp, const char *targetName)
+}
+declare 38 {
+    int TclGetNamespaceForQualName(Tcl_Interp *interp, const char *qualName,
+	    Namespace *cxtNsPtr, int flags, Namespace **nsPtrPtr,
+	    Namespace **altNsPtrPtr, Namespace **actualCxtPtrPtr,
+	    const char **simpleNamePtr)
+}
+declare 39 {
+    TclObjCmdProcType TclGetObjInterpProc(void)
+}
+declare 40 {
+    int TclGetOpenMode(Tcl_Interp *interp, const char *str, int *seekFlagPtr)
+}
+declare 41 {
+    Tcl_Command TclGetOriginalCommand(Tcl_Command command)
+}
+declare 42 {
+    CONST86 char *TclpGetUserHome(const char *name, Tcl_DString *bufferPtr)
+}
+# Removed in Tcl 8.5a2
+#declare 43 {
+#    int TclGlobalInvoke(Tcl_Interp *interp, int argc, CONST84 char **argv,
+#	    int flags)
+#}
+declare 44 {
+    int TclGuessPackageName(const char *fileName, Tcl_DString *bufPtr)
+}
+declare 45 {
+    int TclHideUnsafeCommands(Tcl_Interp *interp)
+}
+declare 46 {
+    int TclInExit(void)
+}
+# Removed in 8.4b2:
+#declare 47 {
+#    Tcl_Obj *TclIncrElementOfIndexedArray(Tcl_Interp *interp,
+#	    int localIndex, Tcl_Obj *elemPtr, long incrAmount)
+#}
+# Removed in 8.4b2:
+#declare 48 {
+#    Tcl_Obj *TclIncrIndexedScalar(Tcl_Interp *interp, int localIndex,
+#	    long incrAmount)
+#}
+#declare 49 {
+#    Tcl_Obj *TclIncrVar2(Tcl_Interp *interp, Tcl_Obj *part1Ptr,
+#	    Tcl_Obj *part2Ptr, long incrAmount, int part1NotParsed)
+#}
+declare 50 {
+    void TclInitCompiledLocals(Tcl_Interp *interp, CallFrame *framePtr,
+	    Namespace *nsPtr)
+}
+declare 51 {
+    int TclInterpInit(Tcl_Interp *interp)
+}
+# Removed in Tcl 8.5a2
+#declare 52 {
+#    int TclInvoke(Tcl_Interp *interp, int argc, CONST84 char **argv,
+#	    int flags)
+#}
+declare 53 {
+    int TclInvokeObjectCommand(ClientData clientData, Tcl_Interp *interp,
+	    int argc, CONST84 char **argv)
+}
+declare 54 {
+    int TclInvokeStringCommand(ClientData clientData, Tcl_Interp *interp,
+	    int objc, Tcl_Obj *const objv[])
+}
+declare 55 {
+    Proc *TclIsProc(Command *cmdPtr)
+}
+# Replaced with TclpLoadFile in 8.1:
+#  declare 56 {
+#      int TclLoadFile(Tcl_Interp *interp, char *fileName, char *sym1,
+#  	    char *sym2, Tcl_PackageInitProc **proc1Ptr,
+#  	    Tcl_PackageInitProc **proc2Ptr)
+#  }
+# Signature changed to take a length in 8.1:
+#  declare 57 {
+#      int TclLooksLikeInt(char *p)
+#  }
+declare 58 {
+    Var *TclLookupVar(Tcl_Interp *interp, const char *part1, const char *part2,
+	    int flags, const char *msg, int createPart1, int createPart2,
+	    Var **arrayPtrPtr)
+}
+# Replaced by Tcl_FSMatchInDirectory in 8.4
+#declare 59 {
+#    int TclpMatchFiles(Tcl_Interp *interp, char *separators,
+#	    Tcl_DString *dirPtr, char *pattern, char *tail)
+#}
+declare 60 {
+    int TclNeedSpace(const char *start, const char *end)
+}
+declare 61 {
+    Tcl_Obj *TclNewProcBodyObj(Proc *procPtr)
+}
+declare 62 {
+    int TclObjCommandComplete(Tcl_Obj *cmdPtr)
+}
+declare 63 {
+    int TclObjInterpProc(ClientData clientData, Tcl_Interp *interp,
+	    int objc, Tcl_Obj *const objv[])
+}
+declare 64 {
+    int TclObjInvoke(Tcl_Interp *interp, int objc, Tcl_Obj *const objv[],
+	    int flags)
+}
+# Removed in Tcl 8.5a2
+#declare 65 {
+#    int TclObjInvokeGlobal(Tcl_Interp *interp, int objc,
+#	    Tcl_Obj *const objv[], int flags)
+#}
+#declare 66 {
+#    int TclOpenFileChannelDeleteProc(TclOpenFileChannelProc_ *proc)
+#}
+#declare 67 {
+#    int TclOpenFileChannelInsertProc(TclOpenFileChannelProc_ *proc)
+#}
+# Replaced by Tcl_FSAccess in 8.4:
+#declare 68 {
+#    int TclpAccess(const char *path, int mode)
+#}
+declare 69 {
+    char *TclpAlloc(unsigned int size)
+}
+#declare 70 {
+#    int TclpCopyFile(const char *source, const char *dest)
+#}
+#declare 71 {
+#    int TclpCopyDirectory(const char *source, const char *dest,
+#	    Tcl_DString *errorPtr)
+#}
+#declare 72 {
+#    int TclpCreateDirectory(const char *path)
+#}
+#declare 73 {
+#    int TclpDeleteFile(const char *path)
+#}
+declare 74 {
+    void TclpFree(char *ptr)
+}
+declare 75 {
+    unsigned long TclpGetClicks(void)
+}
+declare 76 {
+    unsigned long TclpGetSeconds(void)
+}
+
+# deprecated
+declare 77 {
+    void TclpGetTime(Tcl_Time *time)
+}
+# Removed in 8.6:
+#declare 78 {
+#    int TclpGetTimeZone(unsigned long time)
+#}
+# Replaced by Tcl_FSListVolumes in 8.4:
+#declare 79 {
+#    int TclpListVolumes(Tcl_Interp *interp)
+#}
+# Replaced by Tcl_FSOpenFileChannel in 8.4:
+#declare 80 {
+#    Tcl_Channel TclpOpenFileChannel(Tcl_Interp *interp, char *fileName,
+#	    char *modeString, int permissions)
+#}
+declare 81 {
+    char *TclpRealloc(char *ptr, unsigned int size)
+}
+#declare 82 {
+#    int TclpRemoveDirectory(const char *path, int recursive,
+#	    Tcl_DString *errorPtr)
+#}
+#declare 83 {
+#    int TclpRenameFile(const char *source, const char *dest)
+#}
+# Removed in 8.1:
+#  declare 84 {
+#      int TclParseBraces(Tcl_Interp *interp, char *str, char **termPtr,
+#  	    ParseValue *pvPtr)
+#  }
+#  declare 85 {
+#      int TclParseNestedCmd(Tcl_Interp *interp, char *str, int flags,
+#  	    char **termPtr, ParseValue *pvPtr)
+#  }
+#  declare 86 {
+#      int TclParseQuotes(Tcl_Interp *interp, char *str, int termChar,
+#  	    int flags, char **termPtr, ParseValue *pvPtr)
+#  }
+#  declare 87 {
+#      void TclPlatformInit(Tcl_Interp *interp)
+#  }
+declare 88 {
+    char *TclPrecTraceProc(ClientData clientData, Tcl_Interp *interp,
+	    const char *name1, const char *name2, int flags)
+}
+declare 89 {
+    int TclPreventAliasLoop(Tcl_Interp *interp, Tcl_Interp *cmdInterp,
+	    Tcl_Command cmd)
+}
+# Removed in 8.1 (only available if compiled with TCL_COMPILE_DEBUG):
+#  declare 90 {
+#      void TclPrintByteCodeObj(Tcl_Interp *interp, Tcl_Obj *objPtr)
+#  }
+declare 91 {
+    void TclProcCleanupProc(Proc *procPtr)
+}
+declare 92 {
+    int TclProcCompileProc(Tcl_Interp *interp, Proc *procPtr,
+	    Tcl_Obj *bodyPtr, Namespace *nsPtr, const char *description,
+	    const char *procName)
+}
+declare 93 {
+    void TclProcDeleteProc(ClientData clientData)
+}
+# Removed in Tcl 8.5:
+#declare 94 {
+#    int TclProcInterpProc(ClientData clientData, Tcl_Interp *interp,
+#	    int argc, const char **argv)
+#}
+# Replaced by Tcl_FSStat in 8.4:
+#declare 95 {
+#    int TclpStat(const char *path, Tcl_StatBuf *buf)
+#}
+declare 96 {
+    int TclRenameCommand(Tcl_Interp *interp, const char *oldName,
+            const char *newName)
+}
+declare 97 {
+    void TclResetShadowedCmdRefs(Tcl_Interp *interp, Command *newCmdPtr)
+}
+declare 98 {
+    int TclServiceIdle(void)
+}
+# Removed in 8.4b2:
+#declare 99 {
+#    Tcl_Obj *TclSetElementOfIndexedArray(Tcl_Interp *interp, int localIndex,
+#	    Tcl_Obj *elemPtr, Tcl_Obj *objPtr, int flags)
+#}
+# Removed in 8.4b2:
+#declare 100 {
+#    Tcl_Obj *TclSetIndexedScalar(Tcl_Interp *interp, int localIndex,
+#	    Tcl_Obj *objPtr, int flags)
+#}
+declare 101 {
+    CONST86 char *TclSetPreInitScript(const char *string)
+}
+declare 102 {
+    void TclSetupEnv(Tcl_Interp *interp)
+}
+declare 103 {
+    int TclSockGetPort(Tcl_Interp *interp, const char *str, const char *proto,
+	    int *portPtr)
+}
+declare 104 {
+    int TclSockMinimumBuffersOld(int sock, int size)
+}
+# Replaced by Tcl_FSStat in 8.4:
+#declare 105 {
+#    int TclStat(const char *path, Tcl_StatBuf *buf)
+#}
+#declare 106 {
+#    int TclStatDeleteProc(TclStatProc_ *proc)
+#}
+#declare 107 {
+#    int TclStatInsertProc(TclStatProc_ *proc)
+#}
+declare 108 {
+    void TclTeardownNamespace(Namespace *nsPtr)
+}
+declare 109 {
+    int TclUpdateReturnInfo(Interp *iPtr)
+}
+declare 110 {
+    int TclSockMinimumBuffers(void *sock, int size)
+}
+# Removed in 8.1:
+#  declare 110 {
+#      char *TclWordEnd(char *start, char *lastChar, int nested, int *semiPtr)
+#  }
+
+# Procedures used in conjunction with Tcl namespaces. They are
+# defined here instead of in tcl.decls since they are not stable yet.
+
+declare 111 {
+    void Tcl_AddInterpResolvers(Tcl_Interp *interp, const char *name,
+	    Tcl_ResolveCmdProc *cmdProc, Tcl_ResolveVarProc *varProc,
+	    Tcl_ResolveCompiledVarProc *compiledVarProc)
+}
+declare 112 {
+    int Tcl_AppendExportList(Tcl_Interp *interp, Tcl_Namespace *nsPtr,
+	    Tcl_Obj *objPtr)
+}
+declare 113 {
+    Tcl_Namespace *Tcl_CreateNamespace(Tcl_Interp *interp, const char *name,
+	    ClientData clientData, Tcl_NamespaceDeleteProc *deleteProc)
+}
+declare 114 {
+    void Tcl_DeleteNamespace(Tcl_Namespace *nsPtr)
+}
+declare 115 {
+    int Tcl_Export(Tcl_Interp *interp, Tcl_Namespace *nsPtr,
+	    const char *pattern, int resetListFirst)
+}
+declare 116 {
+    Tcl_Command Tcl_FindCommand(Tcl_Interp *interp, const char *name,
+	    Tcl_Namespace *contextNsPtr, int flags)
+}
+declare 117 {
+    Tcl_Namespace *Tcl_FindNamespace(Tcl_Interp *interp, const char *name,
+	    Tcl_Namespace *contextNsPtr, int flags)
+}
+declare 118 {
+    int Tcl_GetInterpResolvers(Tcl_Interp *interp, const char *name,
+	    Tcl_ResolverInfo *resInfo)
+}
+declare 119 {
+    int Tcl_GetNamespaceResolvers(Tcl_Namespace *namespacePtr,
+	    Tcl_ResolverInfo *resInfo)
+}
+declare 120 {
+    Tcl_Var Tcl_FindNamespaceVar(Tcl_Interp *interp, const char *name,
+	    Tcl_Namespace *contextNsPtr, int flags)
+}
+declare 121 {
+    int Tcl_ForgetImport(Tcl_Interp *interp, Tcl_Namespace *nsPtr,
+	    const char *pattern)
+}
+declare 122 {
+    Tcl_Command Tcl_GetCommandFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr)
+}
+declare 123 {
+    void Tcl_GetCommandFullName(Tcl_Interp *interp, Tcl_Command command,
+	    Tcl_Obj *objPtr)
+}
+declare 124 {
+    Tcl_Namespace *Tcl_GetCurrentNamespace(Tcl_Interp *interp)
+}
+declare 125 {
+    Tcl_Namespace *Tcl_GetGlobalNamespace(Tcl_Interp *interp)
+}
+declare 126 {
+    void Tcl_GetVariableFullName(Tcl_Interp *interp, Tcl_Var variable,
+	    Tcl_Obj *objPtr)
+}
+declare 127 {
+    int Tcl_Import(Tcl_Interp *interp, Tcl_Namespace *nsPtr,
+	    const char *pattern, int allowOverwrite)
+}
+declare 128 {
+    void Tcl_PopCallFrame(Tcl_Interp *interp)
+}
+declare 129 {
+    int Tcl_PushCallFrame(Tcl_Interp *interp, Tcl_CallFrame *framePtr,
+	    Tcl_Namespace *nsPtr, int isProcCallFrame)
+}
+declare 130 {
+    int Tcl_RemoveInterpResolvers(Tcl_Interp *interp, const char *name)
+}
+declare 131 {
+    void Tcl_SetNamespaceResolvers(Tcl_Namespace *namespacePtr,
+	    Tcl_ResolveCmdProc *cmdProc, Tcl_ResolveVarProc *varProc,
+	    Tcl_ResolveCompiledVarProc *compiledVarProc)
+}
+declare 132 {
+    int TclpHasSockets(Tcl_Interp *interp)
+}
+declare 133 {
+    struct tm *TclpGetDate(const time_t *time, int useGMT)
+}
+# Removed in 8.5
+#declare 134 {
+#    size_t TclpStrftime(char *s, size_t maxsize, const char *format,
+#	    const struct tm *t, int useGMT)
+#}
+#declare 135 {
+#    int TclpCheckStackSpace(void)
+#}
+
+# Added in 8.1:
+
+#declare 137 {
+#   int TclpChdir(const char *dirName)
+#}
+declare 138 {
+    CONST84_RETURN char *TclGetEnv(const char *name, Tcl_DString *valuePtr)
+}
+#declare 139 {
+#    int TclpLoadFile(Tcl_Interp *interp, char *fileName, char *sym1,
+#	    char *sym2, Tcl_PackageInitProc **proc1Ptr,
+#	    Tcl_PackageInitProc **proc2Ptr, ClientData *clientDataPtr)
+#}
+#declare 140 {
+#    int TclLooksLikeInt(const char *bytes, int length)
+#}
+# This is used by TclX, but should otherwise be considered private
+declare 141 {
+    CONST84_RETURN char *TclpGetCwd(Tcl_Interp *interp, Tcl_DString *cwdPtr)
+}
+declare 142 {
+    int TclSetByteCodeFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr,
+	    CompileHookProc *hookProc, ClientData clientData)
+}
+declare 143 {
+    int TclAddLiteralObj(struct CompileEnv *envPtr, Tcl_Obj *objPtr,
+	    LiteralEntry **litPtrPtr)
+}
+declare 144 {
+    void TclHideLiteral(Tcl_Interp *interp, struct CompileEnv *envPtr,
+	    int index)
+}
+declare 145 {
+    const struct AuxDataType *TclGetAuxDataType(const char *typeName)
+}
+declare 146 {
+    TclHandle TclHandleCreate(void *ptr)
+}
+declare 147 {
+    void TclHandleFree(TclHandle handle)
+}
+declare 148 {
+    TclHandle TclHandlePreserve(TclHandle handle)
+}
+declare 149 {
+    void TclHandleRelease(TclHandle handle)
+}
+
+# Added for Tcl 8.2
+
+declare 150 {
+    int TclRegAbout(Tcl_Interp *interp, Tcl_RegExp re)
+}
+declare 151 {
+    void TclRegExpRangeUniChar(Tcl_RegExp re, int index, int *startPtr,
+	    int *endPtr)
+}
+declare 152 {
+    void TclSetLibraryPath(Tcl_Obj *pathPtr)
+}
+declare 153 {
+    Tcl_Obj *TclGetLibraryPath(void)
+}
+
+# moved to tclTest.c (static) in 8.3.2/8.4a2
+#declare 154 {
+#    int TclTestChannelCmd(ClientData clientData,
+#    Tcl_Interp *interp, int argc, char **argv)
+#}
+#declare 155 {
+#    int TclTestChannelEventCmd(ClientData clientData,
+#	     Tcl_Interp *interp, int argc, char **argv)
+#}
+
+declare 156 {
+    void TclRegError(Tcl_Interp *interp, const char *msg,
+	    int status)
+}
+declare 157 {
+    Var *TclVarTraceExists(Tcl_Interp *interp, const char *varName)
+}
+# REMOVED (except from stub table) - use public Tcl_SetStartupScript()
+declare 158 {
+    void TclSetStartupScriptFileName(const char *filename)
+}
+# REMOVED (except from stub table) - use public Tcl_GetStartupScript()
+declare 159 {
+    const char *TclGetStartupScriptFileName(void)
+}
+#declare 160 {
+#    int TclpMatchFilesTypes(Tcl_Interp *interp, char *separators,
+#	    Tcl_DString *dirPtr, char *pattern, char *tail,
+#	    GlobTypeData *types)
+#}
+
+# new in 8.3.2/8.4a2
+declare 161 {
+    int TclChannelTransform(Tcl_Interp *interp, Tcl_Channel chan,
+	    Tcl_Obj *cmdObjPtr)
+}
+declare 162 {
+    void TclChannelEventScriptInvoker(ClientData clientData, int flags)
+}
+
+# ALERT: The result of 'TclGetInstructionTable' is actually a
+# "const InstructionDesc*" but we do not want to describe this structure in
+# "tclInt.h". It is described in "tclCompile.h". Use a cast to the
+# correct type when calling this procedure.
+
+declare 163 {
+    const void *TclGetInstructionTable(void)
+}
+
+# ALERT: The argument of 'TclExpandCodeArray' is actually a
+# "CompileEnv*" but we do not want to describe this structure in
+# "tclInt.h". It is described in "tclCompile.h".
+
+declare 164 {
+    void TclExpandCodeArray(void *envPtr)
+}
+
+# These functions are vfs aware, but are generally only useful internally.
+declare 165 {
+    void TclpSetInitialEncodings(void)
+}
+
+# New function due to TIP #33
+declare 166 {
+    int TclListObjSetElement(Tcl_Interp *interp, Tcl_Obj *listPtr,
+	    int index, Tcl_Obj *valuePtr)
+}
+
+# VFS-aware versions of Tcl*StartupScriptFileName (158 and 159 above)
+# REMOVED (except from stub table) - use public Tcl_SetStartupScript()
+declare 167 {
+    void TclSetStartupScriptPath(Tcl_Obj *pathPtr)
+}
+# REMOVED (except from stub table) - use public Tcl_GetStartupScript()
+declare 168 {
+    Tcl_Obj *TclGetStartupScriptPath(void)
+}
+# variant of Tcl_UtfNCmp that takes n as bytes, not chars
+declare 169 {
+    int TclpUtfNcmp2(const char *s1, const char *s2, unsigned long n)
+}
+declare 170 {
+    int TclCheckInterpTraces(Tcl_Interp *interp, const char *command,
+	    int numChars, Command *cmdPtr, int result, int traceFlags,
+	    int objc, Tcl_Obj *const objv[])
+}
+declare 171 {
+    int TclCheckExecutionTraces(Tcl_Interp *interp, const char *command,
+	    int numChars, Command *cmdPtr, int result, int traceFlags,
+	    int objc, Tcl_Obj *const objv[])
+}
+declare 172 {
+    int TclInThreadExit(void)
+}
+
+# added for 8.4.2
+
+declare 173 {
+    int TclUniCharMatch(const Tcl_UniChar *string, int strLen,
+	    const Tcl_UniChar *pattern, int ptnLen, int flags)
+}
+
+# added for 8.4.3
+
+#declare 174 {
+#    Tcl_Obj *TclIncrWideVar2(Tcl_Interp *interp, Tcl_Obj *part1Ptr,
+#	    Tcl_Obj *part2Ptr, Tcl_WideInt wideIncrAmount, int part1NotParsed)
+#}
+
+# Factoring out of trace code
+
+declare 175 {
+    int TclCallVarTraces(Interp *iPtr, Var *arrayPtr, Var *varPtr,
+	    const char *part1, const char *part2, int flags, int leaveErrMsg)
+}
+declare 176 {
+    void TclCleanupVar(Var *varPtr, Var *arrayPtr)
+}
+declare 177 {
+    void TclVarErrMsg(Tcl_Interp *interp, const char *part1, const char *part2,
+	    const char *operation, const char *reason)
+}
+# TIP 338 made these public - now declared in tcl.h too
+declare 178 {
+    void Tcl_SetStartupScript(Tcl_Obj *pathPtr, const char *encodingName)
+}
+declare 179 {
+    Tcl_Obj *Tcl_GetStartupScript(const char **encodingNamePtr)
+}
+
+# REMOVED
+# Allocate lists without copying arrays
+# declare 180 {
+#    Tcl_Obj *TclNewListObjDirect(int objc, Tcl_Obj **objv)
+# }
+#declare 181 {
+#    Tcl_Obj *TclDbNewListObjDirect(int objc, Tcl_Obj **objv,
+#	    const char *file, int line)
+#}
+
+# TclpGmtime and TclpLocaltime promoted to the generic interface from unix
+
+declare 182 {
+     struct tm *TclpLocaltime(const time_t *clock)
+}
+declare 183 {
+     struct tm *TclpGmtime(const time_t *clock)
+}
+
+# For the new "Thread Storage" subsystem.
+
+### REMOVED on grounds it should never have been exposed. All these
+### functions are now either static in tclThreadStorage.c or
+### MODULE_SCOPE.
+# declare 184 {
+#      void TclThreadStorageLockInit(void)
+# }
+# declare 185 {
+#      void TclThreadStorageLock(void)
+# }
+# declare 186 {
+#      void TclThreadStorageUnlock(void)
+# }
+# declare 187 {
+#      void TclThreadStoragePrint(FILE *outFile, int flags)
+# }
+# declare 188 {
+#      Tcl_HashTable *TclThreadStorageGetHashTable(Tcl_ThreadId id)
+# }
+# declare 189 {
+#      Tcl_HashTable *TclThreadStorageInit(Tcl_ThreadId id, void *reserved)
+# }
+# declare 190 {
+#      void TclThreadStorageDataKeyInit(Tcl_ThreadDataKey *keyPtr)
+# }
+# declare 191 {
+#      void *TclThreadStorageDataKeyGet(Tcl_ThreadDataKey *keyPtr)
+# }
+# declare 192 {
+#      void TclThreadStorageDataKeySet(Tcl_ThreadDataKey *keyPtr, void *data)
+# }
+# declare 193 {
+#      void TclFinalizeThreadStorageThread(Tcl_ThreadId id)
+# }
+# declare 194 {
+#      void TclFinalizeThreadStorage(void)
+# }
+# declare 195 {
+#      void TclFinalizeThreadStorageData(Tcl_ThreadDataKey *keyPtr)
+# }
+# declare 196 {
+#      void TclFinalizeThreadStorageDataKey(Tcl_ThreadDataKey *keyPtr)
+# }
+
+#
+# Added in tcl8.5a5 for compiler/executor experimentation.
+# Disabled in Tcl 8.5.1; experiments terminated. :/
+#
+#declare 197 {
+#    int TclCompEvalObj(Tcl_Interp *interp, Tcl_Obj *objPtr,
+#		        const CmdFrame *invoker, int word)
+#}
+declare 198 {
+    int TclObjGetFrame(Tcl_Interp *interp, Tcl_Obj *objPtr,
+	    CallFrame **framePtrPtr)
+}
+
+#declare 199 {
+#    int TclMatchIsTrivial(const char *pattern)
+#}
+
+# 200-208 exported for use by the test suite [Bug 1054748]
+declare 200 {
+    int TclpObjRemoveDirectory(Tcl_Obj *pathPtr, int recursive,
+	Tcl_Obj **errorPtr)
+}
+declare 201 {
+    int TclpObjCopyDirectory(Tcl_Obj *srcPathPtr, Tcl_Obj *destPathPtr,
+	Tcl_Obj **errorPtr)
+}
+declare 202 {
+    int TclpObjCreateDirectory(Tcl_Obj *pathPtr)
+}
+declare 203 {
+    int TclpObjDeleteFile(Tcl_Obj *pathPtr)
+}
+declare 204 {
+    int TclpObjCopyFile(Tcl_Obj *srcPathPtr, Tcl_Obj *destPathPtr)
+}
+declare 205 {
+    int TclpObjRenameFile(Tcl_Obj *srcPathPtr, Tcl_Obj *destPathPtr)
+}
+declare 206 {
+    int TclpObjStat(Tcl_Obj *pathPtr, Tcl_StatBuf *buf)
+}
+declare 207 {
+    int TclpObjAccess(Tcl_Obj *pathPtr, int mode)
+}
+declare 208 {
+    Tcl_Channel TclpOpenFileChannel(Tcl_Interp *interp,
+	    Tcl_Obj *pathPtr, int mode, int permissions)
+}
+# Made public by TIP 258
+#declare 209 {
+#    Tcl_Obj *TclGetEncodingSearchPath(void)
+#}
+#declare 210 {
+#    int TclSetEncodingSearchPath(Tcl_Obj *searchPath)
+#}
+#declare 211 {
+#    const char *TclpGetEncodingNameFromEnvironment(Tcl_DString *bufPtr)
+#}
+declare 212 {
+    void TclpFindExecutable(const char *argv0)
+}
+declare 213 {
+    Tcl_Obj *TclGetObjNameOfExecutable(void)
+}
+declare 214 {
+    void TclSetObjNameOfExecutable(Tcl_Obj *name, Tcl_Encoding encoding)
+}
+declare 215 {
+    void *TclStackAlloc(Tcl_Interp *interp, int numBytes)
+}
+declare 216 {
+    void TclStackFree(Tcl_Interp *interp, void *freePtr)
+}
+declare 217 {
+    int TclPushStackFrame(Tcl_Interp *interp, Tcl_CallFrame **framePtrPtr,
+            Tcl_Namespace *namespacePtr, int isProcCallFrame)
+}
+declare 218 {
+    void TclPopStackFrame(Tcl_Interp *interp)
+}
+
+# for use in tclTest.c
+declare 224 {
+    TclPlatformType *TclGetPlatform(void)
+}
+
+#
+declare 225 {
+    Tcl_Obj *TclTraceDictPath(Tcl_Interp *interp, Tcl_Obj *rootPtr,
+	    int keyc, Tcl_Obj *const keyv[], int flags)
+}
+declare 226 {
+    int TclObjBeingDeleted(Tcl_Obj *objPtr)
+}
+declare 227 {
+    void TclSetNsPath(Namespace *nsPtr, int pathLength,
+            Tcl_Namespace *pathAry[])
+}
+#  Used to be needed for TclOO-extension; unneeded now that TclOO is in the
+#  core and NRE-enabled
+#  declare 228 {
+#      int TclObjInterpProcCore(register Tcl_Interp *interp, Tcl_Obj *procNameObj,
+#             int skip, ProcErrorProc *errorProc)
+#  }
+declare 229 {
+    int	TclPtrMakeUpvar(Tcl_Interp *interp, Var *otherP1Ptr,
+	    const char *myName, int myFlags, int index)
+}
+declare 230 {
+    Var *TclObjLookupVar(Tcl_Interp *interp, Tcl_Obj *part1Ptr,
+	    const char *part2, int flags, const char *msg,
+	    const int createPart1, const int createPart2, Var **arrayPtrPtr)
+}
+declare 231 {
+    int	TclGetNamespaceFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr,
+	    Tcl_Namespace **nsPtrPtr)
+}
+
+# Bits and pieces of TIP#280's guts
+declare 232 {
+    int TclEvalObjEx(Tcl_Interp *interp, Tcl_Obj *objPtr, int flags,
+	    const CmdFrame *invoker, int word)
+}
+declare 233 {
+    void TclGetSrcInfoForPc(CmdFrame *contextPtr)
+}
+
+# Exports for VarReform compat: Itcl, XOTcl like to peek into our varTables :(
+declare 234 {
+    Var *TclVarHashCreateVar(TclVarHashTable *tablePtr, const char *key,
+             int *newPtr)
+}
+declare 235 {
+    void TclInitVarHashTable(TclVarHashTable *tablePtr, Namespace *nsPtr)
+}
+
+
+# TIP 337 made this one public
+declare 236 {
+    void TclBackgroundException(Tcl_Interp *interp, int code)
+}
+
+# TIP #285: Script cancellation support.
+declare 237 {
+    int TclResetCancellation(Tcl_Interp *interp, int force)
+}
+
+# NRE functions for "rogue" extensions to exploit NRE; they will need to
+# include NRE.h too.
+declare 238 {
+    int TclNRInterpProc(ClientData clientData, Tcl_Interp *interp,
+	    int objc, Tcl_Obj *const objv[])
+}
+declare 239 {
+    int TclNRInterpProcCore(Tcl_Interp *interp, Tcl_Obj *procNameObj,
+			    int skip, ProcErrorProc *errorProc)
+}
+declare 240 {
+    int TclNRRunCallbacks(Tcl_Interp *interp, int result,
+	      struct NRE_callback *rootPtr)
+}
+declare 241 {
+    int TclNREvalObjEx(Tcl_Interp *interp, Tcl_Obj *objPtr, int flags,
+	    const CmdFrame *invoker, int word)
+}
+declare 242 {
+    int TclNREvalObjv(Tcl_Interp *interp, int objc,
+	      Tcl_Obj *const objv[], int flags, Command *cmdPtr)
+}
+
+# Tcl_Obj leak detection support.
+declare 243 {
+    void TclDbDumpActiveObjects(FILE *outFile)
+}
+
+# Functions to make things better for itcl
+declare 244 {
+    Tcl_HashTable *TclGetNamespaceChildTable(Tcl_Namespace *nsPtr)
+}
+declare 245 {
+    Tcl_HashTable *TclGetNamespaceCommandTable(Tcl_Namespace *nsPtr)
+}
+declare 246 {
+    int TclInitRewriteEnsemble(Tcl_Interp *interp, int numRemoved,
+	    int numInserted, Tcl_Obj *const *objv)
+}
+declare 247 {
+    void TclResetRewriteEnsemble(Tcl_Interp *interp, int isRootEnsemble)
+}
+
+declare 248 {
+    int TclCopyChannel(Tcl_Interp *interp, Tcl_Channel inChan,
+	    Tcl_Channel outChan, Tcl_WideInt toRead, Tcl_Obj *cmdPtr)
+}
+
+declare 249 {
+    char *TclDoubleDigits(double dv, int ndigits, int flags,
+			  int *decpt, int *signum, char **endPtr)
+}
+# TIP #285: Script cancellation support.
+declare 250 {
+    void TclSetSlaveCancelFlags(Tcl_Interp *interp, int flags, int force)
+}
+
+# Allow extensions for optimization
+declare 251 {
+    int TclRegisterLiteral(void *envPtr,
+	    char *bytes, int length, int flags)
+}
+
+##############################################################################
+
+# Define the platform specific internal Tcl interface. These functions are
+# only available on the designated platform.
+
+interface tclIntPlat
+
+################################
+# Windows specific functions
+
+declare 0 win {
+    void TclWinConvertError(DWORD errCode)
+}
+declare 1 win {
+    void TclWinConvertWSAError(DWORD errCode)
+}
+declare 2 win {
+    struct servent *TclWinGetServByName(const char *nm,
+	    const char *proto)
+}
+declare 3 win {
+    int TclWinGetSockOpt(SOCKET s, int level, int optname,
+	    char *optval, int *optlen)
+}
+declare 4 win {
+    HINSTANCE TclWinGetTclInstance(void)
+}
+# new for 8.4.20+/8.5.12+ Cygwin only
+declare 5 win {
+    int TclUnixWaitForFile(int fd, int mask, int timeout)
+}
+# Removed in 8.1:
+#  declare 5 win {
+#      HINSTANCE TclWinLoadLibrary(char *name)
+#  }
+declare 6 win {
+    unsigned short TclWinNToHS(unsigned short ns)
+}
+declare 7 win {
+    int TclWinSetSockOpt(SOCKET s, int level, int optname,
+	    const char *optval, int optlen)
+}
+declare 8 win {
+    int TclpGetPid(Tcl_Pid pid)
+}
+declare 9 win {
+    int TclWinGetPlatformId(void)
+}
+# new for 8.4.20+/8.5.12+ Cygwin only
+declare 10 win {
+    Tcl_DirEntry *TclpReaddir(DIR *dir)
+}
+# Removed in 8.3.1 (for Win32s only)
+#declare 10 win {
+#    int TclWinSynchSpawn(void *args, int type, void **trans, Tcl_Pid *pidPtr)
+#}
+
+# Pipe channel functions
+
+declare 11 win {
+    void TclGetAndDetachPids(Tcl_Interp *interp, Tcl_Channel chan)
+}
+declare 12 win {
+    int TclpCloseFile(TclFile file)
+}
+declare 13 win {
+    Tcl_Channel TclpCreateCommandChannel(TclFile readFile,
+	    TclFile writeFile, TclFile errorFile, int numPids, Tcl_Pid *pidPtr)
+}
+declare 14 win {
+    int TclpCreatePipe(TclFile *readPipe, TclFile *writePipe)
+}
+declare 15 win {
+    int TclpCreateProcess(Tcl_Interp *interp, int argc,
+	    const char **argv, TclFile inputFile, TclFile outputFile,
+	    TclFile errorFile, Tcl_Pid *pidPtr)
+}
+# new for 8.4.20+/8.5.12+ Cygwin only
+declare 16 win {
+    int TclpIsAtty(int fd)
+}
+# Signature changed in 8.1:
+#  declare 16 win {
+#      TclFile TclpCreateTempFile(char *contents, Tcl_DString *namePtr)
+#  }
+#  declare 17 win {
+#      char *TclpGetTZName(void)
+#  }
+# new for 8.5.12+ Cygwin only
+declare 17 win {
+    int TclUnixCopyFile(const char *src, const char *dst,
+	    const Tcl_StatBuf *statBufPtr, int dontCopyAtts)
+}
+declare 18 win {
+    TclFile TclpMakeFile(Tcl_Channel channel, int direction)
+}
+declare 19 win {
+    TclFile TclpOpenFile(const char *fname, int mode)
+}
+declare 20 win {
+    void TclWinAddProcess(HANDLE hProcess, DWORD id)
+}
+# new for 8.4.20+/8.5.12+
+declare 21 win {
+    char *TclpInetNtoa(struct in_addr addr)
+}
+# removed permanently for 8.4
+#declare 21 win {
+#    void TclpAsyncMark(Tcl_AsyncHandler async)
+#}
+
+# Added in 8.1:
+declare 22 win {
+    TclFile TclpCreateTempFile(const char *contents)
+}
+# Removed in 8.6:
+#declare 23 win {
+#    char *TclpGetTZName(int isdst)
+#}
+declare 24 win {
+    char *TclWinNoBackslash(char *path)
+}
+# replaced by generic TclGetPlatform
+#declare 25 win {
+#    TclPlatformType *TclWinGetPlatform(void)
+#}
+declare 26 win {
+    void TclWinSetInterfaces(int wide)
+}
+
+# Added in Tcl 8.3.3 / 8.4
+
+declare 27 win {
+    void TclWinFlushDirtyChannels(void)
+}
+
+# Added in 8.4.2
+
+declare 28 win {
+    void TclWinResetInterfaces(void)
+}
+
+################################
+# Unix specific functions
+
+# Pipe channel functions
+
+declare 0 unix {
+    void TclGetAndDetachPids(Tcl_Interp *interp, Tcl_Channel chan)
+}
+declare 1 unix {
+    int TclpCloseFile(TclFile file)
+}
+declare 2 unix {
+    Tcl_Channel TclpCreateCommandChannel(TclFile readFile,
+	    TclFile writeFile, TclFile errorFile, int numPids, Tcl_Pid *pidPtr)
+}
+declare 3 unix {
+    int TclpCreatePipe(TclFile *readPipe, TclFile *writePipe)
+}
+declare 4 unix {
+    int TclpCreateProcess(Tcl_Interp *interp, int argc,
+	    const char **argv, TclFile inputFile, TclFile outputFile,
+	    TclFile errorFile, Tcl_Pid *pidPtr)
+}
+# Signature changed in 8.1:
+#  declare 5 unix {
+#      TclFile TclpCreateTempFile(char *contents, Tcl_DString *namePtr)
+#  }
+declare 6 unix {
+    TclFile TclpMakeFile(Tcl_Channel channel, int direction)
+}
+declare 7 unix {
+    TclFile TclpOpenFile(const char *fname, int mode)
+}
+declare 8 unix {
+    int TclUnixWaitForFile(int fd, int mask, int timeout)
+}
+
+# Added in 8.1:
+
+declare 9 unix {
+    TclFile TclpCreateTempFile(const char *contents)
+}
+
+# Added in 8.4:
+
+declare 10 unix {
+    Tcl_DirEntry *TclpReaddir(DIR *dir)
+}
+# Slots 11 and 12 are forwarders for functions that were promoted to
+# generic Stubs
+declare 11 unix {
+    struct tm *TclpLocaltime_unix(const time_t *clock)
+}
+declare 12 unix {
+    struct tm *TclpGmtime_unix(const time_t *clock)
+}
+declare 13 unix {
+    char *TclpInetNtoa(struct in_addr addr)
+}
+
+# Added in 8.5:
+
+declare 14 unix {
+    int TclUnixCopyFile(const char *src, const char *dst,
+	    const Tcl_StatBuf *statBufPtr, int dontCopyAtts)
+}
+
+################################
+# Mac OS X specific functions
+
+declare 15 macosx {
+    int TclMacOSXGetFileAttribute(Tcl_Interp *interp, int objIndex,
+	    Tcl_Obj *fileName, Tcl_Obj **attributePtrPtr)
+}
+declare 16 macosx {
+    int TclMacOSXSetFileAttribute(Tcl_Interp *interp, int objIndex,
+	    Tcl_Obj *fileName, Tcl_Obj *attributePtr)
+}
+declare 17 macosx {
+    int TclMacOSXCopyFileAttributes(const char *src, const char *dst,
+	    const Tcl_StatBuf *statBufPtr)
+}
+declare 18 macosx {
+    int TclMacOSXMatchType(Tcl_Interp *interp, const char *pathName,
+	    const char *fileName, Tcl_StatBuf *statBufPtr,
+	    Tcl_GlobTypeData *types)
+}
+declare 19 macosx {
+    void TclMacOSXNotifierAddRunLoopMode(const void *runLoopMode)
+}
+
+declare 29 {win unix} {
+    int TclWinCPUID(unsigned int index, unsigned int *regs)
+}
+# Added in 8.6; core of TclpOpenTemporaryFile
+declare 30 {win unix} {
+    int TclUnixOpenTemporaryFile(Tcl_Obj *dirObj, Tcl_Obj *basenameObj,
+	    Tcl_Obj *extensionObj, Tcl_Obj *resultingNameObj)
+}
+
+
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/generic/tclInt.h b/generic/tclInt.h
new file mode 100644
index 0000000..4f7ea6e
--- /dev/null
+++ b/generic/tclInt.h
@@ -0,0 +1,4862 @@
+/*
+ * tclInt.h --
+ *
+ *	Declarations of things used internally by the Tcl interpreter.
+ *
+ * Copyright (c) 1987-1993 The Regents of the University of California.
+ * Copyright (c) 1993-1997 Lucent Technologies.
+ * Copyright (c) 1994-1998 Sun Microsystems, Inc.
+ * Copyright (c) 1998-1999 by Scriptics Corporation.
+ * Copyright (c) 2001, 2002 by Kevin B. Kenny.  All rights reserved.
+ * Copyright (c) 2007 Daniel A. Steffen <das@users.sourceforge.net>
+ * Copyright (c) 2006-2008 by Joe Mistachkin.  All rights reserved.
+ * Copyright (c) 2008 by Miguel Sofer. All rights reserved.
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#ifndef _TCLINT
+#define _TCLINT
+
+/*
+ * Some numerics configuration options.
+ */
+
+#undef ACCEPT_NAN
+
+/*
+ * Common include files needed by most of the Tcl source files are included
+ * here, so that system-dependent personalizations for the include files only
+ * have to be made in once place. This results in a few extra includes, but
+ * greater modularity. The order of the three groups of #includes is
+ * important. For example, stdio.h is needed by tcl.h.
+ */
+
+#include "tclPort.h"
+
+#include <stdio.h>
+
+#include <ctype.h>
+#ifdef NO_STDLIB_H
+#   include "../compat/stdlib.h"
+#else
+#   include <stdlib.h>
+#endif
+#ifdef NO_STRING_H
+#include "../compat/string.h"
+#else
+#include <string.h>
+#endif
+#if defined(STDC_HEADERS) || defined(__STDC__) || defined(__C99__FUNC__) \
+     || defined(__cplusplus) || defined(_MSC_VER)
+#include <stddef.h>
+#else
+typedef int ptrdiff_t;
+#endif
+
+/*
+ * Ensure WORDS_BIGENDIAN is defined correctly:
+ * Needs to happen here in addition to configure to work with fat compiles on
+ * Darwin (where configure runs only once for multiple architectures).
+ */
+
+#ifdef HAVE_SYS_TYPES_H
+#    include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_PARAM_H
+#    include <sys/param.h>
+#endif
+#ifdef BYTE_ORDER
+#    ifdef BIG_ENDIAN
+#	 if BYTE_ORDER == BIG_ENDIAN
+#	     undef WORDS_BIGENDIAN
+#	     define WORDS_BIGENDIAN 1
+#	 endif
+#    endif
+#    ifdef LITTLE_ENDIAN
+#	 if BYTE_ORDER == LITTLE_ENDIAN
+#	     undef WORDS_BIGENDIAN
+#	 endif
+#    endif
+#endif
+
+/*
+ * Used to tag functions that are only to be visible within the module being
+ * built and not outside it (where this is supported by the linker).
+ */
+
+#ifndef MODULE_SCOPE
+#   ifdef __cplusplus
+#	define MODULE_SCOPE extern "C"
+#   else
+#	define MODULE_SCOPE extern
+#   endif
+#endif
+
+/*
+ * Macros used to cast between pointers and integers (e.g. when storing an int
+ * in ClientData), on 64-bit architectures they avoid gcc warning about "cast
+ * to/from pointer from/to integer of different size".
+ */
+
+#if !defined(INT2PTR) && !defined(PTR2INT)
+#   if defined(HAVE_INTPTR_T) || defined(intptr_t)
+#	define INT2PTR(p) ((void *)(intptr_t)(p))
+#	define PTR2INT(p) ((int)(intptr_t)(p))
+#   else
+#	define INT2PTR(p) ((void *)(p))
+#	define PTR2INT(p) ((int)(p))
+#   endif
+#endif
+#if !defined(UINT2PTR) && !defined(PTR2UINT)
+#   if defined(HAVE_UINTPTR_T) || defined(uintptr_t)
+#	define UINT2PTR(p) ((void *)(uintptr_t)(p))
+#	define PTR2UINT(p) ((unsigned int)(uintptr_t)(p))
+#   else
+#	define UINT2PTR(p) ((void *)(p))
+#	define PTR2UINT(p) ((unsigned int)(p))
+#   endif
+#endif
+
+#if defined(_WIN32) && defined(_MSC_VER)
+#   define vsnprintf _vsnprintf
+#endif
+
+/*
+ * The following procedures allow namespaces to be customized to support
+ * special name resolution rules for commands/variables.
+ */
+
+struct Tcl_ResolvedVarInfo;
+
+typedef Tcl_Var (Tcl_ResolveRuntimeVarProc)(Tcl_Interp *interp,
+	struct Tcl_ResolvedVarInfo *vinfoPtr);
+
+typedef void (Tcl_ResolveVarDeleteProc)(struct Tcl_ResolvedVarInfo *vinfoPtr);
+
+/*
+ * The following structure encapsulates the routines needed to resolve a
+ * variable reference at runtime. Any variable specific state will typically
+ * be appended to this structure.
+ */
+
+typedef struct Tcl_ResolvedVarInfo {
+    Tcl_ResolveRuntimeVarProc *fetchProc;
+    Tcl_ResolveVarDeleteProc *deleteProc;
+} Tcl_ResolvedVarInfo;
+
+typedef int (Tcl_ResolveCompiledVarProc)(Tcl_Interp *interp,
+	CONST84 char *name, int length, Tcl_Namespace *context,
+	Tcl_ResolvedVarInfo **rPtr);
+
+typedef int (Tcl_ResolveVarProc)(Tcl_Interp *interp, CONST84 char *name,
+	Tcl_Namespace *context, int flags, Tcl_Var *rPtr);
+
+typedef int (Tcl_ResolveCmdProc)(Tcl_Interp *interp, CONST84 char *name,
+	Tcl_Namespace *context, int flags, Tcl_Command *rPtr);
+
+typedef struct Tcl_ResolverInfo {
+    Tcl_ResolveCmdProc *cmdResProc;
+				/* Procedure handling command name
+				 * resolution. */
+    Tcl_ResolveVarProc *varResProc;
+				/* Procedure handling variable name resolution
+				 * for variables that can only be handled at
+				 * runtime. */
+    Tcl_ResolveCompiledVarProc *compiledVarResProc;
+				/* Procedure handling variable name resolution
+				 * at compile time. */
+} Tcl_ResolverInfo;
+
+/*
+ * This flag bit should not interfere with TCL_GLOBAL_ONLY,
+ * TCL_NAMESPACE_ONLY, or TCL_LEAVE_ERR_MSG; it signals that the variable
+ * lookup is performed for upvar (or similar) purposes, with slightly
+ * different rules:
+ *    - Bug #696893 - variable is either proc-local or in the current
+ *	namespace; never follow the second (global) resolution path
+ *    - Bug #631741 - do not use special namespace or interp resolvers
+ *
+ * It should also not collide with the (deprecated) TCL_PARSE_PART1 flag
+ * (Bug #835020)
+ */
+
+#define TCL_AVOID_RESOLVERS 0x40000
+
+/*
+ *----------------------------------------------------------------
+ * Data structures related to namespaces.
+ *----------------------------------------------------------------
+ */
+
+typedef struct Tcl_Ensemble Tcl_Ensemble;
+typedef struct NamespacePathEntry NamespacePathEntry;
+
+/*
+ * Special hashtable for variables: this is just a Tcl_HashTable with an nsPtr
+ * field added at the end: in this way variables can find their namespace
+ * without having to copy a pointer in their struct: they can access it via
+ * their hPtr->tablePtr.
+ */
+
+typedef struct TclVarHashTable {
+    Tcl_HashTable table;
+    struct Namespace *nsPtr;
+} TclVarHashTable;
+
+/*
+ * This is for itcl - it likes to search our varTables directly :(
+ */
+
+#define TclVarHashFindVar(tablePtr, key) \
+    TclVarHashCreateVar((tablePtr), (key), NULL)
+
+/*
+ * Define this to reduce the amount of space that the average namespace
+ * consumes by only allocating the table of child namespaces when necessary.
+ * Defining it breaks compatibility for Tcl extensions (e.g., itcl) which
+ * reach directly into the Namespace structure.
+ */
+
+#undef BREAK_NAMESPACE_COMPAT
+
+/*
+ * The structure below defines a namespace.
+ * Note: the first five fields must match exactly the fields in a
+ * Tcl_Namespace structure (see tcl.h). If you change one, be sure to change
+ * the other.
+ */
+
+typedef struct Namespace {
+    char *name;			/* The namespace's simple (unqualified) name.
+				 * This contains no ::'s. The name of the
+				 * global namespace is "" although "::" is an
+				 * synonym. */
+    char *fullName;		/* The namespace's fully qualified name. This
+				 * starts with ::. */
+    ClientData clientData;	/* An arbitrary value associated with this
+				 * namespace. */
+    Tcl_NamespaceDeleteProc *deleteProc;
+				/* Procedure invoked when deleting the
+				 * namespace to, e.g., free clientData. */
+    struct Namespace *parentPtr;/* Points to the namespace that contains this
+				 * one. NULL if this is the global
+				 * namespace. */
+#ifndef BREAK_NAMESPACE_COMPAT
+    Tcl_HashTable childTable;	/* Contains any child namespaces. Indexed by
+				 * strings; values have type (Namespace *). */
+#else
+    Tcl_HashTable *childTablePtr;
+				/* Contains any child namespaces. Indexed by
+				 * strings; values have type (Namespace *). If
+				 * NULL, there are no children. */
+#endif
+    long nsId;			/* Unique id for the namespace. */
+    Tcl_Interp *interp;		/* The interpreter containing this
+				 * namespace. */
+    int flags;			/* OR-ed combination of the namespace status
+				 * flags NS_DYING and NS_DEAD listed below. */
+    int activationCount;	/* Number of "activations" or active call
+				 * frames for this namespace that are on the
+				 * Tcl call stack. The namespace won't be
+				 * freed until activationCount becomes zero. */
+    int refCount;		/* Count of references by namespaceName
+				 * objects. The namespace can't be freed until
+				 * refCount becomes zero. */
+    Tcl_HashTable cmdTable;	/* Contains all the commands currently
+				 * registered in the namespace. Indexed by
+				 * strings; values have type (Command *).
+				 * Commands imported by Tcl_Import have
+				 * Command structures that point (via an
+				 * ImportedCmdRef structure) to the Command
+				 * structure in the source namespace's command
+				 * table. */
+    TclVarHashTable varTable;	/* Contains all the (global) variables
+				 * currently in this namespace. Indexed by
+				 * strings; values have type (Var *). */
+    char **exportArrayPtr;	/* Points to an array of string patterns
+				 * specifying which commands are exported. A
+				 * pattern may include "string match" style
+				 * wildcard characters to specify multiple
+				 * commands; however, no namespace qualifiers
+				 * are allowed. NULL if no export patterns are
+				 * registered. */
+    int numExportPatterns;	/* Number of export patterns currently
+				 * registered using "namespace export". */
+    int maxExportPatterns;	/* Mumber of export patterns for which space
+				 * is currently allocated. */
+    int cmdRefEpoch;		/* Incremented if a newly added command
+				 * shadows a command for which this namespace
+				 * has already cached a Command* pointer; this
+				 * causes all its cached Command* pointers to
+				 * be invalidated. */
+    int resolverEpoch;		/* Incremented whenever (a) the name
+				 * resolution rules change for this namespace
+				 * or (b) a newly added command shadows a
+				 * command that is compiled to bytecodes. This
+				 * invalidates all byte codes compiled in the
+				 * namespace, causing the code to be
+				 * recompiled under the new rules.*/
+    Tcl_ResolveCmdProc *cmdResProc;
+				/* If non-null, this procedure overrides the
+				 * usual command resolution mechanism in Tcl.
+				 * This procedure is invoked within
+				 * Tcl_FindCommand to resolve all command
+				 * references within the namespace. */
+    Tcl_ResolveVarProc *varResProc;
+				/* If non-null, this procedure overrides the
+				 * usual variable resolution mechanism in Tcl.
+				 * This procedure is invoked within
+				 * Tcl_FindNamespaceVar to resolve all
+				 * variable references within the namespace at
+				 * runtime. */
+    Tcl_ResolveCompiledVarProc *compiledVarResProc;
+				/* If non-null, this procedure overrides the
+				 * usual variable resolution mechanism in Tcl.
+				 * This procedure is invoked within
+				 * LookupCompiledLocal to resolve variable
+				 * references within the namespace at compile
+				 * time. */
+    int exportLookupEpoch;	/* Incremented whenever a command is added to
+				 * a namespace, removed from a namespace or
+				 * the exports of a namespace are changed.
+				 * Allows TIP#112-driven command lists to be
+				 * validated efficiently. */
+    Tcl_Ensemble *ensembles;	/* List of structures that contain the details
+				 * of the ensembles that are implemented on
+				 * top of this namespace. */
+    Tcl_Obj *unknownHandlerPtr;	/* A script fragment to be used when command
+				 * resolution in this namespace fails. TIP
+				 * 181. */
+    int commandPathLength;	/* The length of the explicit path. */
+    NamespacePathEntry *commandPathArray;
+				/* The explicit path of the namespace as an
+				 * array. */
+    NamespacePathEntry *commandPathSourceList;
+				/* Linked list of path entries that point to
+				 * this namespace. */
+    Tcl_NamespaceDeleteProc *earlyDeleteProc;
+				/* Just like the deleteProc field (and called
+				 * with the same clientData) but called at the
+				 * start of the deletion process, so there is
+				 * a chance for code to do stuff inside the
+				 * namespace before deletion completes. */
+} Namespace;
+
+/*
+ * An entry on a namespace's command resolution path.
+ */
+
+struct NamespacePathEntry {
+    Namespace *nsPtr;		/* What does this path entry point to? If it
+				 * is NULL, this path entry points is
+				 * redundant and should be skipped. */
+    Namespace *creatorNsPtr;	/* Where does this path entry point from? This
+				 * allows for efficient invalidation of
+				 * references when the path entry's target
+				 * updates its current list of defined
+				 * commands. */
+    NamespacePathEntry *prevPtr, *nextPtr;
+				/* Linked list pointers or NULL at either end
+				 * of the list that hangs off Namespace's
+				 * commandPathSourceList field. */
+};
+
+/*
+ * Flags used to represent the status of a namespace:
+ *
+ * NS_DYING -	1 means Tcl_DeleteNamespace has been called to delete the
+ *		namespace but there are still active call frames on the Tcl
+ *		stack that refer to the namespace. When the last call frame
+ *		referring to it has been popped, it's variables and command
+ *		will be destroyed and it will be marked "dead" (NS_DEAD). The
+ *		namespace can no longer be looked up by name.
+ * NS_DEAD -	1 means Tcl_DeleteNamespace has been called to delete the
+ *		namespace and no call frames still refer to it. Its variables
+ *		and command have already been destroyed. This bit allows the
+ *		namespace resolution code to recognize that the namespace is
+ *		"deleted". When the last namespaceName object in any byte code
+ *		unit that refers to the namespace has been freed (i.e., when
+ *		the namespace's refCount is 0), the namespace's storage will
+ *		be freed.
+ * NS_KILLED -	1 means that TclTeardownNamespace has already been called on
+ *		this namespace and it should not be called again [Bug 1355942]
+ * NS_SUPPRESS_COMPILATION -
+ *		Marks the commands in this namespace for not being compiled,
+ *		forcing them to be looked up every time.
+ */
+
+#define NS_DYING	0x01
+#define NS_DEAD		0x02
+#define NS_KILLED	0x04
+#define NS_SUPPRESS_COMPILATION	0x08
+
+/*
+ * Flags passed to TclGetNamespaceForQualName:
+ *
+ * TCL_GLOBAL_ONLY		- (see tcl.h) Look only in the global ns.
+ * TCL_NAMESPACE_ONLY		- (see tcl.h) Look only in the context ns.
+ * TCL_CREATE_NS_IF_UNKNOWN	- Create unknown namespaces.
+ * TCL_FIND_ONLY_NS		- The name sought is a namespace name.
+ */
+
+#define TCL_CREATE_NS_IF_UNKNOWN	0x800
+#define TCL_FIND_ONLY_NS		0x1000
+
+/*
+ * The client data for an ensemble command. This consists of the table of
+ * commands that are actually exported by the namespace, and an epoch counter
+ * that, combined with the exportLookupEpoch field of the namespace structure,
+ * defines whether the table contains valid data or will need to be recomputed
+ * next time the ensemble command is called.
+ */
+
+typedef struct EnsembleConfig {
+    Namespace *nsPtr;		/* The namspace backing this ensemble up. */
+    Tcl_Command token;		/* The token for the command that provides
+				 * ensemble support for the namespace, or NULL
+				 * if the command has been deleted (or never
+				 * existed; the global namespace never has an
+				 * ensemble command.) */
+    int epoch;			/* The epoch at which this ensemble's table of
+				 * exported commands is valid. */
+    char **subcommandArrayPtr;	/* Array of ensemble subcommand names. At all
+				 * consistent points, this will have the same
+				 * number of entries as there are entries in
+				 * the subcommandTable hash. */
+    Tcl_HashTable subcommandTable;
+				/* Hash table of ensemble subcommand names,
+				 * which are its keys so this also provides
+				 * the storage management for those subcommand
+				 * names. The contents of the entry values are
+				 * object version the prefix lists to use when
+				 * substituting for the command/subcommand to
+				 * build the ensemble implementation command.
+				 * Has to be stored here as well as in
+				 * subcommandDict because that field is NULL
+				 * when we are deriving the ensemble from the
+				 * namespace exports list. FUTURE WORK: use
+				 * object hash table here. */
+    struct EnsembleConfig *next;/* The next ensemble in the linked list of
+				 * ensembles associated with a namespace. If
+				 * this field points to this ensemble, the
+				 * structure has already been unlinked from
+				 * all lists, and cannot be found by scanning
+				 * the list from the namespace's ensemble
+				 * field. */
+    int flags;			/* ORed combo of TCL_ENSEMBLE_PREFIX,
+				 * ENSEMBLE_DEAD and ENSEMBLE_COMPILE. */
+
+    /* OBJECT FIELDS FOR ENSEMBLE CONFIGURATION */
+
+    Tcl_Obj *subcommandDict;	/* Dictionary providing mapping from
+				 * subcommands to their implementing command
+				 * prefixes, or NULL if we are to build the
+				 * map automatically from the namespace
+				 * exports. */
+    Tcl_Obj *subcmdList;	/* List of commands that this ensemble
+				 * actually provides, and whose implementation
+				 * will be built using the subcommandDict (if
+				 * present and defined) and by simple mapping
+				 * to the namespace otherwise. If NULL,
+				 * indicates that we are using the (dynamic)
+				 * list of currently exported commands. */
+    Tcl_Obj *unknownHandler;	/* Script prefix used to handle the case when
+				 * no match is found (according to the rule
+				 * defined by flag bit TCL_ENSEMBLE_PREFIX) or
+				 * NULL to use the default error-generating
+				 * behaviour. The script execution gets all
+				 * the arguments to the ensemble command
+				 * (including objv[0]) and will have the
+				 * results passed directly back to the caller
+				 * (including the error code) unless the code
+				 * is TCL_CONTINUE in which case the
+				 * subcommand will be reparsed by the ensemble
+				 * core, presumably because the ensemble
+				 * itself has been updated. */
+    Tcl_Obj *parameterList;	/* List of ensemble parameter names. */
+    int numParameters;		/* Cached number of parameters. This is either
+				 * 0 (if the parameterList field is NULL) or
+				 * the length of the list in the parameterList
+				 * field. */
+} EnsembleConfig;
+
+/*
+ * Various bits for the EnsembleConfig.flags field.
+ */
+
+#define ENSEMBLE_DEAD	0x1	/* Flag value to say that the ensemble is dead
+				 * and on its way out. */
+#define ENSEMBLE_COMPILE 0x4	/* Flag to enable bytecode compilation of an
+				 * ensemble. */
+
+/*
+ *----------------------------------------------------------------
+ * Data structures related to variables. These are used primarily in tclVar.c
+ *----------------------------------------------------------------
+ */
+
+/*
+ * The following structure defines a variable trace, which is used to invoke a
+ * specific C procedure whenever certain operations are performed on a
+ * variable.
+ */
+
+typedef struct VarTrace {
+    Tcl_VarTraceProc *traceProc;/* Procedure to call when operations given by
+				 * flags are performed on variable. */
+    ClientData clientData;	/* Argument to pass to proc. */
+    int flags;			/* What events the trace procedure is
+				 * interested in: OR-ed combination of
+				 * TCL_TRACE_READS, TCL_TRACE_WRITES,
+				 * TCL_TRACE_UNSETS and TCL_TRACE_ARRAY. */
+    struct VarTrace *nextPtr;	/* Next in list of traces associated with a
+				 * particular variable. */
+} VarTrace;
+
+/*
+ * The following structure defines a command trace, which is used to invoke a
+ * specific C procedure whenever certain operations are performed on a
+ * command.
+ */
+
+typedef struct CommandTrace {
+    Tcl_CommandTraceProc *traceProc;
+				/* Procedure to call when operations given by
+				 * flags are performed on command. */
+    ClientData clientData;	/* Argument to pass to proc. */
+    int flags;			/* What events the trace procedure is
+				 * interested in: OR-ed combination of
+				 * TCL_TRACE_RENAME, TCL_TRACE_DELETE. */
+    struct CommandTrace *nextPtr;
+				/* Next in list of traces associated with a
+				 * particular command. */
+    int refCount;		/* Used to ensure this structure is not
+				 * deleted too early. Keeps track of how many
+				 * pieces of code have a pointer to this
+				 * structure. */
+} CommandTrace;
+
+/*
+ * When a command trace is active (i.e. its associated procedure is executing)
+ * one of the following structures is linked into a list associated with the
+ * command's interpreter. The information in the structure is needed in order
+ * for Tcl to behave reasonably if traces are deleted while traces are active.
+ */
+
+typedef struct ActiveCommandTrace {
+    struct Command *cmdPtr;	/* Command that's being traced. */
+    struct ActiveCommandTrace *nextPtr;
+				/* Next in list of all active command traces
+				 * for the interpreter, or NULL if no more. */
+    CommandTrace *nextTracePtr;	/* Next trace to check after current trace
+				 * procedure returns; if this trace gets
+				 * deleted, must update pointer to avoid using
+				 * free'd memory. */
+    int reverseScan;		/* Boolean set true when traces are scanning
+				 * in reverse order. */
+} ActiveCommandTrace;
+
+/*
+ * When a variable trace is active (i.e. its associated procedure is
+ * executing) one of the following structures is linked into a list associated
+ * with the variable's interpreter. The information in the structure is needed
+ * in order for Tcl to behave reasonably if traces are deleted while traces
+ * are active.
+ */
+
+typedef struct ActiveVarTrace {
+    struct Var *varPtr;		/* Variable that's being traced. */
+    struct ActiveVarTrace *nextPtr;
+				/* Next in list of all active variable traces
+				 * for the interpreter, or NULL if no more. */
+    VarTrace *nextTracePtr;	/* Next trace to check after current trace
+				 * procedure returns; if this trace gets
+				 * deleted, must update pointer to avoid using
+				 * free'd memory. */
+} ActiveVarTrace;
+
+/*
+ * The structure below defines a variable, which associates a string name with
+ * a Tcl_Obj value. These structures are kept in procedure call frames (for
+ * local variables recognized by the compiler) or in the heap (for global
+ * variables and any variable not known to the compiler). For each Var
+ * structure in the heap, a hash table entry holds the variable name and a
+ * pointer to the Var structure.
+ */
+
+typedef struct Var {
+    int flags;			/* Miscellaneous bits of information about
+				 * variable. See below for definitions. */
+    union {
+	Tcl_Obj *objPtr;	/* The variable's object value. Used for
+				 * scalar variables and array elements. */
+	TclVarHashTable *tablePtr;/* For array variables, this points to
+				 * information about the hash table used to
+				 * implement the associative array. Points to
+				 * ckalloc-ed data. */
+	struct Var *linkPtr;	/* If this is a global variable being referred
+				 * to in a procedure, or a variable created by
+				 * "upvar", this field points to the
+				 * referenced variable's Var struct. */
+    } value;
+} Var;
+
+typedef struct VarInHash {
+    Var var;
+    int refCount;		/* Counts number of active uses of this
+				 * variable: 1 for the entry in the hash
+				 * table, 1 for each additional variable whose
+				 * linkPtr points here, 1 for each nested
+				 * trace active on variable, and 1 if the
+				 * variable is a namespace variable. This
+				 * record can't be deleted until refCount
+				 * becomes 0. */
+    Tcl_HashEntry entry;	/* The hash table entry that refers to this
+				 * variable. This is used to find the name of
+				 * the variable and to delete it from its
+				 * hashtable if it is no longer needed. It
+				 * also holds the variable's name. */
+} VarInHash;
+
+/*
+ * Flag bits for variables. The first two (VAR_ARRAY and VAR_LINK) are
+ * mutually exclusive and give the "type" of the variable. If none is set,
+ * this is a scalar variable.
+ *
+ * VAR_ARRAY -			1 means this is an array variable rather than
+ *				a scalar variable or link. The "tablePtr"
+ *				field points to the array's hashtable for its
+ *				elements.
+ * VAR_LINK -			1 means this Var structure contains a pointer
+ *				to another Var structure that either has the
+ *				real value or is itself another VAR_LINK
+ *				pointer. Variables like this come about
+ *				through "upvar" and "global" commands, or
+ *				through references to variables in enclosing
+ *				namespaces.
+ *
+ * Flags that indicate the type and status of storage; none is set for
+ * compiled local variables (Var structs).
+ *
+ * VAR_IN_HASHTABLE -		1 means this variable is in a hashtable and
+ *				the Var structure is malloced. 0 if it is a
+ *				local variable that was assigned a slot in a
+ *				procedure frame by the compiler so the Var
+ *				storage is part of the call frame.
+ * VAR_DEAD_HASH		1 means that this var's entry in the hashtable
+ *				has already been deleted.
+ * VAR_ARRAY_ELEMENT -		1 means that this variable is an array
+ *				element, so it is not legal for it to be an
+ *				array itself (the VAR_ARRAY flag had better
+ *				not be set).
+ * VAR_NAMESPACE_VAR -		1 means that this variable was declared as a
+ *				namespace variable. This flag ensures it
+ *				persists until its namespace is destroyed or
+ *				until the variable is unset; it will persist
+ *				even if it has not been initialized and is
+ *				marked undefined. The variable's refCount is
+ *				incremented to reflect the "reference" from
+ *				its namespace.
+ *
+ * Flag values relating to the variable's trace and search status.
+ *
+ * VAR_TRACED_READ
+ * VAR_TRACED_WRITE
+ * VAR_TRACED_UNSET
+ * VAR_TRACED_ARRAY
+ * VAR_TRACE_ACTIVE -		1 means that trace processing is currently
+ *				underway for a read or write access, so new
+ *				read or write accesses should not cause trace
+ *				procedures to be called and the variable can't
+ *				be deleted.
+ * VAR_SEARCH_ACTIVE
+ *
+ * The following additional flags are used with the CompiledLocal type defined
+ * below:
+ *
+ * VAR_ARGUMENT -		1 means that this variable holds a procedure
+ *				argument.
+ * VAR_TEMPORARY -		1 if the local variable is an anonymous
+ *				temporary variable. Temporaries have a NULL
+ *				name.
+ * VAR_RESOLVED -		1 if name resolution has been done for this
+ *				variable.
+ * VAR_IS_ARGS			1 if this variable is the last argument and is
+ *				named "args".
+ */
+
+/*
+ * FLAGS RENUMBERED: everything breaks already, make things simpler.
+ *
+ * IMPORTANT: skip the values 0x10, 0x20, 0x40, 0x800 corresponding to
+ * TCL_TRACE_(READS/WRITES/UNSETS/ARRAY): makes code simpler in tclTrace.c
+ *
+ * Keep the flag values for VAR_ARGUMENT and VAR_TEMPORARY so that old values
+ * in precompiled scripts keep working.
+ */
+
+/* Type of value (0 is scalar) */
+#define VAR_ARRAY		0x1
+#define VAR_LINK		0x2
+
+/* Type of storage (0 is compiled local) */
+#define VAR_IN_HASHTABLE	0x4
+#define VAR_DEAD_HASH		0x8
+#define VAR_ARRAY_ELEMENT	0x1000
+#define VAR_NAMESPACE_VAR	0x80	/* KEEP OLD VALUE for Itcl */
+
+#define VAR_ALL_HASH \
+	(VAR_IN_HASHTABLE|VAR_DEAD_HASH|VAR_NAMESPACE_VAR|VAR_ARRAY_ELEMENT)
+
+/* Trace and search state. */
+
+#define VAR_TRACED_READ		0x10	/* TCL_TRACE_READS */
+#define VAR_TRACED_WRITE	0x20	/* TCL_TRACE_WRITES */
+#define VAR_TRACED_UNSET	0x40	/* TCL_TRACE_UNSETS */
+#define VAR_TRACED_ARRAY	0x800	/* TCL_TRACE_ARRAY */
+#define VAR_TRACE_ACTIVE	0x2000
+#define VAR_SEARCH_ACTIVE	0x4000
+#define VAR_ALL_TRACES \
+	(VAR_TRACED_READ|VAR_TRACED_WRITE|VAR_TRACED_ARRAY|VAR_TRACED_UNSET)
+
+/* Special handling on initialisation (only CompiledLocal). */
+#define VAR_ARGUMENT		0x100	/* KEEP OLD VALUE! See tclProc.c */
+#define VAR_TEMPORARY		0x200	/* KEEP OLD VALUE! See tclProc.c */
+#define VAR_IS_ARGS		0x400
+#define VAR_RESOLVED		0x8000
+
+/*
+ * Macros to ensure that various flag bits are set properly for variables.
+ * The ANSI C "prototypes" for these macros are:
+ *
+ * MODULE_SCOPE void	TclSetVarScalar(Var *varPtr);
+ * MODULE_SCOPE void	TclSetVarArray(Var *varPtr);
+ * MODULE_SCOPE void	TclSetVarLink(Var *varPtr);
+ * MODULE_SCOPE void	TclSetVarArrayElement(Var *varPtr);
+ * MODULE_SCOPE void	TclSetVarUndefined(Var *varPtr);
+ * MODULE_SCOPE void	TclClearVarUndefined(Var *varPtr);
+ */
+
+#define TclSetVarScalar(varPtr) \
+    (varPtr)->flags &= ~(VAR_ARRAY|VAR_LINK)
+
+#define TclSetVarArray(varPtr) \
+    (varPtr)->flags = ((varPtr)->flags & ~VAR_LINK) | VAR_ARRAY
+
+#define TclSetVarLink(varPtr) \
+    (varPtr)->flags = ((varPtr)->flags & ~VAR_ARRAY) | VAR_LINK
+
+#define TclSetVarArrayElement(varPtr) \
+    (varPtr)->flags = ((varPtr)->flags & ~VAR_ARRAY) | VAR_ARRAY_ELEMENT
+
+#define TclSetVarUndefined(varPtr) \
+    (varPtr)->flags &= ~(VAR_ARRAY|VAR_LINK);\
+    (varPtr)->value.objPtr = NULL
+
+#define TclClearVarUndefined(varPtr)
+
+#define TclSetVarTraceActive(varPtr) \
+    (varPtr)->flags |= VAR_TRACE_ACTIVE
+
+#define TclClearVarTraceActive(varPtr) \
+    (varPtr)->flags &= ~VAR_TRACE_ACTIVE
+
+#define TclSetVarNamespaceVar(varPtr) \
+    if (!TclIsVarNamespaceVar(varPtr)) {\
+	(varPtr)->flags |= VAR_NAMESPACE_VAR;\
+	if (TclIsVarInHash(varPtr)) {\
+	    ((VarInHash *)(varPtr))->refCount++;\
+	}\
+    }
+
+#define TclClearVarNamespaceVar(varPtr) \
+    if (TclIsVarNamespaceVar(varPtr)) {\
+	(varPtr)->flags &= ~VAR_NAMESPACE_VAR;\
+	if (TclIsVarInHash(varPtr)) {\
+	    ((VarInHash *)(varPtr))->refCount--;\
+	}\
+    }
+
+/*
+ * Macros to read various flag bits of variables.
+ * The ANSI C "prototypes" for these macros are:
+ *
+ * MODULE_SCOPE int	TclIsVarScalar(Var *varPtr);
+ * MODULE_SCOPE int	TclIsVarLink(Var *varPtr);
+ * MODULE_SCOPE int	TclIsVarArray(Var *varPtr);
+ * MODULE_SCOPE int	TclIsVarUndefined(Var *varPtr);
+ * MODULE_SCOPE int	TclIsVarArrayElement(Var *varPtr);
+ * MODULE_SCOPE int	TclIsVarTemporary(Var *varPtr);
+ * MODULE_SCOPE int	TclIsVarArgument(Var *varPtr);
+ * MODULE_SCOPE int	TclIsVarResolved(Var *varPtr);
+ */
+
+#define TclIsVarScalar(varPtr) \
+    !((varPtr)->flags & (VAR_ARRAY|VAR_LINK))
+
+#define TclIsVarLink(varPtr) \
+    ((varPtr)->flags & VAR_LINK)
+
+#define TclIsVarArray(varPtr) \
+    ((varPtr)->flags & VAR_ARRAY)
+
+#define TclIsVarUndefined(varPtr) \
+    ((varPtr)->value.objPtr == NULL)
+
+#define TclIsVarArrayElement(varPtr) \
+    ((varPtr)->flags & VAR_ARRAY_ELEMENT)
+
+#define TclIsVarNamespaceVar(varPtr) \
+    ((varPtr)->flags & VAR_NAMESPACE_VAR)
+
+#define TclIsVarTemporary(varPtr) \
+    ((varPtr)->flags & VAR_TEMPORARY)
+
+#define TclIsVarArgument(varPtr) \
+    ((varPtr)->flags & VAR_ARGUMENT)
+
+#define TclIsVarResolved(varPtr) \
+    ((varPtr)->flags & VAR_RESOLVED)
+
+#define TclIsVarTraceActive(varPtr) \
+    ((varPtr)->flags & VAR_TRACE_ACTIVE)
+
+#define TclIsVarTraced(varPtr) \
+    ((varPtr)->flags & VAR_ALL_TRACES)
+
+#define TclIsVarInHash(varPtr) \
+    ((varPtr)->flags & VAR_IN_HASHTABLE)
+
+#define TclIsVarDeadHash(varPtr) \
+    ((varPtr)->flags & VAR_DEAD_HASH)
+
+#define TclGetVarNsPtr(varPtr) \
+    (TclIsVarInHash(varPtr) \
+	? ((TclVarHashTable *) ((((VarInHash *) (varPtr))->entry.tablePtr)))->nsPtr \
+	: NULL)
+
+#define VarHashRefCount(varPtr) \
+    ((VarInHash *) (varPtr))->refCount
+
+/*
+ * Macros for direct variable access by TEBC.
+ */
+
+#define TclIsVarDirectReadable(varPtr) \
+    (   !((varPtr)->flags & (VAR_ARRAY|VAR_LINK|VAR_TRACED_READ)) \
+    &&  (varPtr)->value.objPtr)
+
+#define TclIsVarDirectWritable(varPtr) \
+    !((varPtr)->flags & (VAR_ARRAY|VAR_LINK|VAR_TRACED_WRITE|VAR_DEAD_HASH))
+
+#define TclIsVarDirectUnsettable(varPtr) \
+    !((varPtr)->flags & (VAR_ARRAY|VAR_LINK|VAR_TRACED_READ|VAR_TRACED_WRITE|VAR_TRACED_UNSET|VAR_DEAD_HASH))
+
+#define TclIsVarDirectModifyable(varPtr) \
+    (   !((varPtr)->flags & (VAR_ARRAY|VAR_LINK|VAR_TRACED_READ|VAR_TRACED_WRITE)) \
+    &&  (varPtr)->value.objPtr)
+
+#define TclIsVarDirectReadable2(varPtr, arrayPtr) \
+    (TclIsVarDirectReadable(varPtr) &&\
+	(!(arrayPtr) || !((arrayPtr)->flags & VAR_TRACED_READ)))
+
+#define TclIsVarDirectWritable2(varPtr, arrayPtr) \
+    (TclIsVarDirectWritable(varPtr) &&\
+	(!(arrayPtr) || !((arrayPtr)->flags & VAR_TRACED_WRITE)))
+
+#define TclIsVarDirectModifyable2(varPtr, arrayPtr) \
+    (TclIsVarDirectModifyable(varPtr) &&\
+	(!(arrayPtr) || !((arrayPtr)->flags & (VAR_TRACED_READ|VAR_TRACED_WRITE))))
+
+/*
+ *----------------------------------------------------------------
+ * Data structures related to procedures. These are used primarily in
+ * tclProc.c, tclCompile.c, and tclExecute.c.
+ *----------------------------------------------------------------
+ */
+
+/*
+ * Forward declaration to prevent an error when the forward reference to
+ * Command is encountered in the Proc and ImportRef types declared below.
+ */
+
+struct Command;
+
+/*
+ * The variable-length structure below describes a local variable of a
+ * procedure that was recognized by the compiler. These variables have a name,
+ * an element in the array of compiler-assigned local variables in the
+ * procedure's call frame, and various other items of information. If the
+ * local variable is a formal argument, it may also have a default value. The
+ * compiler can't recognize local variables whose names are expressions (these
+ * names are only known at runtime when the expressions are evaluated) or
+ * local variables that are created as a result of an "upvar" or "uplevel"
+ * command. These other local variables are kept separately in a hash table in
+ * the call frame.
+ */
+
+typedef struct CompiledLocal {
+    struct CompiledLocal *nextPtr;
+				/* Next compiler-recognized local variable for
+				 * this procedure, or NULL if this is the last
+				 * local. */
+    int nameLength;		/* The number of characters in local
+				 * variable's name. Used to speed up variable
+				 * lookups. */
+    int frameIndex;		/* Index in the array of compiler-assigned
+				 * variables in the procedure call frame. */
+    int flags;			/* Flag bits for the local variable. Same as
+				 * the flags for the Var structure above,
+				 * although only VAR_ARGUMENT, VAR_TEMPORARY,
+				 * and VAR_RESOLVED make sense. */
+    Tcl_Obj *defValuePtr;	/* Pointer to the default value of an
+				 * argument, if any. NULL if not an argument
+				 * or, if an argument, no default value. */
+    Tcl_ResolvedVarInfo *resolveInfo;
+				/* Customized variable resolution info
+				 * supplied by the Tcl_ResolveCompiledVarProc
+				 * associated with a namespace. Each variable
+				 * is marked by a unique ClientData tag during
+				 * compilation, and that same tag is used to
+				 * find the variable at runtime. */
+    char name[1];		/* Name of the local variable starts here. If
+				 * the name is NULL, this will just be '\0'.
+				 * The actual size of this field will be large
+				 * enough to hold the name. MUST BE THE LAST
+				 * FIELD IN THE STRUCTURE! */
+} CompiledLocal;
+
+/*
+ * The structure below defines a command procedure, which consists of a
+ * collection of Tcl commands plus information about arguments and other local
+ * variables recognized at compile time.
+ */
+
+typedef struct Proc {
+    struct Interp *iPtr;	/* Interpreter for which this command is
+				 * defined. */
+    int refCount;		/* Reference count: 1 if still present in
+				 * command table plus 1 for each call to the
+				 * procedure that is currently active. This
+				 * structure can be freed when refCount
+				 * becomes zero. */
+    struct Command *cmdPtr;	/* Points to the Command structure for this
+				 * procedure. This is used to get the
+				 * namespace in which to execute the
+				 * procedure. */
+    Tcl_Obj *bodyPtr;		/* Points to the ByteCode object for
+				 * procedure's body command. */
+    int numArgs;		/* Number of formal parameters. */
+    int numCompiledLocals;	/* Count of local variables recognized by the
+				 * compiler including arguments and
+				 * temporaries. */
+    CompiledLocal *firstLocalPtr;
+				/* Pointer to first of the procedure's
+				 * compiler-allocated local variables, or NULL
+				 * if none. The first numArgs entries in this
+				 * list describe the procedure's formal
+				 * arguments. */
+    CompiledLocal *lastLocalPtr;/* Pointer to the last allocated local
+				 * variable or NULL if none. This has frame
+				 * index (numCompiledLocals-1). */
+} Proc;
+
+/*
+ * The type of functions called to process errors found during the execution
+ * of a procedure (or lambda term or ...).
+ */
+
+typedef void (ProcErrorProc)(Tcl_Interp *interp, Tcl_Obj *procNameObj);
+
+/*
+ * The structure below defines a command trace. This is used to allow Tcl
+ * clients to find out whenever a command is about to be executed.
+ */
+
+typedef struct Trace {
+    int level;			/* Only trace commands at nesting level less
+				 * than or equal to this. */
+    Tcl_CmdObjTraceProc *proc;	/* Procedure to call to trace command. */
+    ClientData clientData;	/* Arbitrary value to pass to proc. */
+    struct Trace *nextPtr;	/* Next in list of traces for this interp. */
+    int flags;			/* Flags governing the trace - see
+				 * Tcl_CreateObjTrace for details. */
+    Tcl_CmdObjTraceDeleteProc *delProc;
+				/* Procedure to call when trace is deleted. */
+} Trace;
+
+/*
+ * When an interpreter trace is active (i.e. its associated procedure is
+ * executing), one of the following structures is linked into a list
+ * associated with the interpreter. The information in the structure is needed
+ * in order for Tcl to behave reasonably if traces are deleted while traces
+ * are active.
+ */
+
+typedef struct ActiveInterpTrace {
+    struct ActiveInterpTrace *nextPtr;
+				/* Next in list of all active command traces
+				 * for the interpreter, or NULL if no more. */
+    Trace *nextTracePtr;	/* Next trace to check after current trace
+				 * procedure returns; if this trace gets
+				 * deleted, must update pointer to avoid using
+				 * free'd memory. */
+    int reverseScan;		/* Boolean set true when traces are scanning
+				 * in reverse order. */
+} ActiveInterpTrace;
+
+/*
+ * Flag values designating types of execution traces. See tclTrace.c for
+ * related flag values.
+ *
+ * TCL_TRACE_ENTER_EXEC		- triggers enter/enterstep traces.
+ * 				- passed to Tcl_CreateObjTrace to set up
+ *				  "enterstep" traces.
+ * TCL_TRACE_LEAVE_EXEC		- triggers leave/leavestep traces.
+ * 				- passed to Tcl_CreateObjTrace to set up
+ *				  "leavestep" traces.
+ */
+
+#define TCL_TRACE_ENTER_EXEC	1
+#define TCL_TRACE_LEAVE_EXEC	2
+
+/*
+ * The structure below defines an entry in the assocData hash table which is
+ * associated with an interpreter. The entry contains a pointer to a function
+ * to call when the interpreter is deleted, and a pointer to a user-defined
+ * piece of data.
+ */
+
+typedef struct AssocData {
+    Tcl_InterpDeleteProc *proc;	/* Proc to call when deleting. */
+    ClientData clientData;	/* Value to pass to proc. */
+} AssocData;
+
+/*
+ * The structure below defines a call frame. A call frame defines a naming
+ * context for a procedure call: its local naming scope (for local variables)
+ * and its global naming scope (a namespace, perhaps the global :: namespace).
+ * A call frame can also define the naming context for a namespace eval or
+ * namespace inscope command: the namespace in which the command's code should
+ * execute. The Tcl_CallFrame structures exist only while procedures or
+ * namespace eval/inscope's are being executed, and provide a kind of Tcl call
+ * stack.
+ *
+ * WARNING!! The structure definition must be kept consistent with the
+ * Tcl_CallFrame structure in tcl.h. If you change one, change the other.
+ */
+
+/*
+ * Will be grown to contain: pointers to the varnames (allocated at the end),
+ * plus the init values for each variable (suitable to be memcopied on init)
+ */
+
+typedef struct LocalCache {
+    int refCount;
+    int numVars;
+    Tcl_Obj *varName0;
+} LocalCache;
+
+#define localName(framePtr, i) \
+    ((&((framePtr)->localCachePtr->varName0))[(i)])
+
+MODULE_SCOPE void	TclFreeLocalCache(Tcl_Interp *interp,
+			    LocalCache *localCachePtr);
+
+typedef struct CallFrame {
+    Namespace *nsPtr;		/* Points to the namespace used to resolve
+				 * commands and global variables. */
+    int isProcCallFrame;	/* If 0, the frame was pushed to execute a
+				 * namespace command and var references are
+				 * treated as references to namespace vars;
+				 * varTablePtr and compiledLocals are ignored.
+				 * If FRAME_IS_PROC is set, the frame was
+				 * pushed to execute a Tcl procedure and may
+				 * have local vars. */
+    int objc;			/* This and objv below describe the arguments
+				 * for this procedure call. */
+    Tcl_Obj *const *objv;	/* Array of argument objects. */
+    struct CallFrame *callerPtr;
+				/* Value of interp->framePtr when this
+				 * procedure was invoked (i.e. next higher in
+				 * stack of all active procedures). */
+    struct CallFrame *callerVarPtr;
+				/* Value of interp->varFramePtr when this
+				 * procedure was invoked (i.e. determines
+				 * variable scoping within caller). Same as
+				 * callerPtr unless an "uplevel" command or
+				 * something equivalent was active in the
+				 * caller). */
+    int level;			/* Level of this procedure, for "uplevel"
+				 * purposes (i.e. corresponds to nesting of
+				 * callerVarPtr's, not callerPtr's). 1 for
+				 * outermost procedure, 0 for top-level. */
+    Proc *procPtr;		/* Points to the structure defining the called
+				 * procedure. Used to get information such as
+				 * the number of compiled local variables
+				 * (local variables assigned entries ["slots"]
+				 * in the compiledLocals array below). */
+    TclVarHashTable *varTablePtr;
+				/* Hash table containing local variables not
+				 * recognized by the compiler, or created at
+				 * execution time through, e.g., upvar.
+				 * Initially NULL and created if needed. */
+    int numCompiledLocals;	/* Count of local variables recognized by the
+				 * compiler including arguments. */
+    Var *compiledLocals;	/* Points to the array of local variables
+				 * recognized by the compiler. The compiler
+				 * emits code that refers to these variables
+				 * using an index into this array. */
+    ClientData clientData;	/* Pointer to some context that is used by
+				 * object systems. The meaning of the contents
+				 * of this field is defined by the code that
+				 * sets it, and it should only ever be set by
+				 * the code that is pushing the frame. In that
+				 * case, the code that sets it should also
+				 * have some means of discovering what the
+				 * meaning of the value is, which we do not
+				 * specify. */
+    LocalCache *localCachePtr;
+    Tcl_Obj    *tailcallPtr;
+				/* NULL if no tailcall is scheduled */
+} CallFrame;
+
+#define FRAME_IS_PROC	0x1
+#define FRAME_IS_LAMBDA 0x2
+#define FRAME_IS_METHOD	0x4	/* The frame is a method body, and the frame's
+				 * clientData field contains a CallContext
+				 * reference. Part of TIP#257. */
+#define FRAME_IS_OO_DEFINE 0x8	/* The frame is part of the inside workings of
+				 * the [oo::define] command; the clientData
+				 * field contains an Object reference that has
+				 * been confirmed to refer to a class. Part of
+				 * TIP#257. */
+
+/*
+ * TIP #280
+ * The structure below defines a command frame. A command frame provides
+ * location information for all commands executing a tcl script (source, eval,
+ * uplevel, procedure bodies, ...). The runtime structure essentially contains
+ * the stack trace as it would be if the currently executing command were to
+ * throw an error.
+ *
+ * For commands where it makes sense it refers to the associated CallFrame as
+ * well.
+ *
+ * The structures are chained in a single list, with the top of the stack
+ * anchored in the Interp structure.
+ *
+ * Instances can be allocated on the C stack, or the heap, the former making
+ * cleanup a bit simpler.
+ */
+
+typedef struct CmdFrame {
+    /*
+     * General data. Always available.
+     */
+
+    int type;			/* Values see below. */
+    int level;			/* Number of frames in stack, prevent O(n)
+				 * scan of list. */
+    int *line;			/* Lines the words of the command start on. */
+    int nline;
+    CallFrame *framePtr;	/* Procedure activation record, may be
+				 * NULL. */
+    struct CmdFrame *nextPtr;	/* Link to calling frame. */
+    /*
+     * Data needed for Eval vs TEBC
+     *
+     * EXECUTION CONTEXTS and usage of CmdFrame
+     *
+     * Field	  TEBC		  EvalEx
+     * =======	  ====		  ======
+     * level	  yes		  yes
+     * type	  BC/PREBC	  SRC/EVAL
+     * line0	  yes		  yes
+     * framePtr	  yes		  yes
+     * =======	  ====		  ======
+     *
+     * =======	  ====		  ========= union data
+     * line1	  -		  yes
+     * line3	  -		  yes
+     * path	  -		  yes
+     * -------	  ----		  ------
+     * codePtr	  yes		  -
+     * pc	  yes		  -
+     * =======	  ====		  ======
+     *
+     * =======	  ====		  ========= union cmd
+     * str.cmd	  yes		  yes
+     * str.len	  yes		  yes
+     * -------	  ----		  ------
+     */
+
+    union {
+	struct {
+	    Tcl_Obj *path;	/* Path of the sourced file the command is
+				 * in. */
+	} eval;
+	struct {
+	    const void *codePtr;/* Byte code currently executed... */
+	    const char *pc;	/* ... and instruction pointer. */
+	} tebc;
+    } data;
+    Tcl_Obj *cmdObj;
+    const char *cmd;		/* The executed command, if possible... */
+    int len;			/* ... and its length. */
+    const struct CFWordBC *litarg;
+				/* Link to set of literal arguments which have
+				 * ben pushed on the lineLABCPtr stack by
+				 * TclArgumentBCEnter(). These will be removed
+				 * by TclArgumentBCRelease. */
+} CmdFrame;
+
+typedef struct CFWord {
+    CmdFrame *framePtr;		/* CmdFrame to access. */
+    int word;			/* Index of the word in the command. */
+    int refCount;		/* Number of times the word is on the
+				 * stack. */
+} CFWord;
+
+typedef struct CFWordBC {
+    CmdFrame *framePtr;		/* CmdFrame to access. */
+    int pc;			/* Instruction pointer of a command in
+				 * ExtCmdLoc.loc[.] */
+    int word;			/* Index of word in
+				 * ExtCmdLoc.loc[cmd]->line[.] */
+    struct CFWordBC *prevPtr;	/* Previous entry in stack for same Tcl_Obj. */
+    struct CFWordBC *nextPtr;	/* Next entry for same command call. See
+				 * CmdFrame litarg field for the list start. */
+    Tcl_Obj *obj;		/* Back reference to hashtable key */
+} CFWordBC;
+
+/*
+ * Structure to record the locations of invisible continuation lines in
+ * literal scripts, as character offset from the beginning of the script. Both
+ * compiler and direct evaluator use this information to adjust their line
+ * counters when tracking through the script, because when it is invoked the
+ * continuation line marker as a whole has been removed already, meaning that
+ * the \n which was part of it is gone as well, breaking regular line
+ * tracking.
+ *
+ * These structures are allocated and filled by both the function
+ * TclSubstTokens() in the file "tclParse.c" and its caller TclEvalEx() in the
+ * file "tclBasic.c", and stored in the thread-global hashtable "lineCLPtr" in
+ * file "tclObj.c". They are used by the functions TclSetByteCodeFromAny() and
+ * TclCompileScript(), both found in the file "tclCompile.c". Their memory is
+ * released by the function TclFreeObj(), in the file "tclObj.c", and also by
+ * the function TclThreadFinalizeObjects(), in the same file.
+ */
+
+#define CLL_END		(-1)
+
+typedef struct ContLineLoc {
+    int num;			/* Number of entries in loc, not counting the
+				 * final -1 marker entry. */
+    int loc[1];			/* Table of locations, as character offsets.
+				 * The table is allocated as part of the
+				 * structure, extending behind the nominal end
+				 * of the structure. An entry containing the
+				 * value -1 is put after the last location, as
+				 * end-marker/sentinel. */
+} ContLineLoc;
+
+/*
+ * The following macros define the allowed values for the type field of the
+ * CmdFrame structure above. Some of the values occur only in the extended
+ * location data referenced via the 'baseLocPtr'.
+ *
+ * TCL_LOCATION_EVAL	  : Frame is for a script evaluated by EvalEx.
+ * TCL_LOCATION_BC	  : Frame is for bytecode.
+ * TCL_LOCATION_PREBC	  : Frame is for precompiled bytecode.
+ * TCL_LOCATION_SOURCE	  : Frame is for a script evaluated by EvalEx, from a
+ *			    sourced file.
+ * TCL_LOCATION_PROC	  : Frame is for bytecode of a procedure.
+ *
+ * A TCL_LOCATION_BC type in a frame can be overridden by _SOURCE and _PROC
+ * types, per the context of the byte code in execution.
+ */
+
+#define TCL_LOCATION_EVAL	(0) /* Location in a dynamic eval script. */
+#define TCL_LOCATION_BC		(2) /* Location in byte code. */
+#define TCL_LOCATION_PREBC	(3) /* Location in precompiled byte code, no
+				     * location. */
+#define TCL_LOCATION_SOURCE	(4) /* Location in a file. */
+#define TCL_LOCATION_PROC	(5) /* Location in a dynamic proc. */
+#define TCL_LOCATION_LAST	(6) /* Number of values in the enum. */
+
+/*
+ * Structure passed to describe procedure-like "procedures" that are not
+ * procedures (e.g. a lambda) so that their details can be reported correctly
+ * by [info frame]. Contains a sub-structure for each extra field.
+ */
+
+typedef Tcl_Obj * (GetFrameInfoValueProc)(ClientData clientData);
+typedef struct {
+    const char *name;		/* Name of this field. */
+    GetFrameInfoValueProc *proc;	/* Function to generate a Tcl_Obj* from the
+				 * clientData, or just use the clientData
+				 * directly (after casting) if NULL. */
+    ClientData clientData;	/* Context for above function, or Tcl_Obj* if
+				 * proc field is NULL. */
+} ExtraFrameInfoField;
+typedef struct {
+    int length;			/* Length of array. */
+    ExtraFrameInfoField fields[2];
+				/* Really as long as necessary, but this is
+				 * long enough for nearly anything. */
+} ExtraFrameInfo;
+
+/*
+ *----------------------------------------------------------------
+ * Data structures and procedures related to TclHandles, which are a very
+ * lightweight method of preserving enough information to determine if an
+ * arbitrary malloc'd block has been deleted.
+ *----------------------------------------------------------------
+ */
+
+typedef void **TclHandle;
+
+/*
+ *----------------------------------------------------------------
+ * Experimental flag value passed to Tcl_GetRegExpFromObj. Intended for use
+ * only by Expect. It will probably go away in a later release.
+ *----------------------------------------------------------------
+ */
+
+#define TCL_REG_BOSONLY 002000	/* Prepend \A to pattern so it only matches at
+				 * the beginning of the string. */
+
+/*
+ * These are a thin layer over TclpThreadKeyDataGet and TclpThreadKeyDataSet
+ * when threads are used, or an emulation if there are no threads. These are
+ * really internal and Tcl clients should use Tcl_GetThreadData.
+ */
+
+MODULE_SCOPE void *	TclThreadDataKeyGet(Tcl_ThreadDataKey *keyPtr);
+MODULE_SCOPE void	TclThreadDataKeySet(Tcl_ThreadDataKey *keyPtr,
+			    void *data);
+
+/*
+ * This is a convenience macro used to initialize a thread local storage ptr.
+ */
+
+#define TCL_TSD_INIT(keyPtr) \
+  (ThreadSpecificData *)Tcl_GetThreadData((keyPtr), sizeof(ThreadSpecificData))
+
+/*
+ *----------------------------------------------------------------
+ * Data structures related to bytecode compilation and execution. These are
+ * used primarily in tclCompile.c, tclExecute.c, and tclBasic.c.
+ *----------------------------------------------------------------
+ */
+
+/*
+ * Forward declaration to prevent errors when the forward references to
+ * Tcl_Parse and CompileEnv are encountered in the procedure type CompileProc
+ * declared below.
+ */
+
+struct CompileEnv;
+
+/*
+ * The type of procedures called by the Tcl bytecode compiler to compile
+ * commands. Pointers to these procedures are kept in the Command structure
+ * describing each command. The integer value returned by a CompileProc must
+ * be one of the following:
+ *
+ * TCL_OK		Compilation completed normally.
+ * TCL_ERROR 		Compilation could not be completed. This can be just a
+ * 			judgment by the CompileProc that the command is too
+ * 			complex to compile effectively, or it can indicate
+ * 			that in the current state of the interp, the command
+ * 			would raise an error. The bytecode compiler will not
+ * 			do any error reporting at compiler time. Error
+ * 			reporting is deferred until the actual runtime,
+ * 			because by then changes in the interp state may allow
+ * 			the command to be successfully evaluated.
+ * TCL_OUT_LINE_COMPILE	A source-compatible alias for TCL_ERROR, kept for the
+ * 			sake of old code only.
+ */
+
+#define TCL_OUT_LINE_COMPILE	TCL_ERROR
+
+typedef int (CompileProc)(Tcl_Interp *interp, Tcl_Parse *parsePtr,
+	struct Command *cmdPtr, struct CompileEnv *compEnvPtr);
+
+/*
+ * The type of procedure called from the compilation hook point in
+ * SetByteCodeFromAny.
+ */
+
+typedef int (CompileHookProc)(Tcl_Interp *interp,
+	struct CompileEnv *compEnvPtr, ClientData clientData);
+
+/*
+ * The data structure for a (linked list of) execution stacks.
+ */
+
+typedef struct ExecStack {
+    struct ExecStack *prevPtr;
+    struct ExecStack *nextPtr;
+    Tcl_Obj **markerPtr;
+    Tcl_Obj **endPtr;
+    Tcl_Obj **tosPtr;
+    Tcl_Obj *stackWords[1];
+} ExecStack;
+
+/*
+ * The data structure defining the execution environment for ByteCode's.
+ * There is one ExecEnv structure per Tcl interpreter. It holds the evaluation
+ * stack that holds command operands and results. The stack grows towards
+ * increasing addresses. The member stackPtr points to the stackItems of the
+ * currently active execution stack.
+ */
+
+typedef struct CorContext {
+    struct CallFrame *framePtr;
+    struct CallFrame *varFramePtr;
+    struct CmdFrame *cmdFramePtr;  /* See Interp.cmdFramePtr */
+    Tcl_HashTable *lineLABCPtr;    /* See Interp.lineLABCPtr */
+} CorContext;
+
+typedef struct CoroutineData {
+    struct Command *cmdPtr;	/* The command handle for the coroutine. */
+    struct ExecEnv *eePtr;	/* The special execution environment (stacks,
+				 * etc.) for the coroutine. */
+    struct ExecEnv *callerEEPtr;/* The execution environment for the caller of
+				 * the coroutine, which might be the
+				 * interpreter global environment or another
+				 * coroutine. */
+    CorContext caller;
+    CorContext running;
+    Tcl_HashTable *lineLABCPtr;    /* See Interp.lineLABCPtr */
+    void *stackLevel;
+    int auxNumLevels;		/* While the coroutine is running the
+				 * numLevels of the create/resume command is
+				 * stored here; for suspended coroutines it
+				 * holds the nesting numLevels at yield. */
+    int nargs;                  /* Number of args required for resuming this
+				 * coroutine; -2 means "0 or 1" (default), -1
+				 * means "any" */
+} CoroutineData;
+
+typedef struct ExecEnv {
+    ExecStack *execStackPtr;	/* Points to the first item in the evaluation
+				 * stack on the heap. */
+    Tcl_Obj *constants[2];	/* Pointers to constant "0" and "1" objs. */
+    struct Tcl_Interp *interp;
+    struct NRE_callback *callbackPtr;
+				/* Top callback in NRE's stack. */
+    struct CoroutineData *corPtr;
+    int rewind;
+} ExecEnv;
+
+#define COR_IS_SUSPENDED(corPtr) \
+    ((corPtr)->stackLevel == NULL)
+
+/*
+ * The definitions for the LiteralTable and LiteralEntry structures. Each
+ * interpreter contains a LiteralTable. It is used to reduce the storage
+ * needed for all the Tcl objects that hold the literals of scripts compiled
+ * by the interpreter. A literal's object is shared by all the ByteCodes that
+ * refer to the literal. Each distinct literal has one LiteralEntry entry in
+ * the LiteralTable. A literal table is a specialized hash table that is
+ * indexed by the literal's string representation, which may contain null
+ * characters.
+ *
+ * Note that we reduce the space needed for literals by sharing literal
+ * objects both within a ByteCode (each ByteCode contains a local
+ * LiteralTable) and across all an interpreter's ByteCodes (with the
+ * interpreter's global LiteralTable).
+ */
+
+typedef struct LiteralEntry {
+    struct LiteralEntry *nextPtr;
+				/* Points to next entry in this hash bucket or
+				 * NULL if end of chain. */
+    Tcl_Obj *objPtr;		/* Points to Tcl object that holds the
+				 * literal's bytes and length. */
+    int refCount;		/* If in an interpreter's global literal
+				 * table, the number of ByteCode structures
+				 * that share the literal object; the literal
+				 * entry can be freed when refCount drops to
+				 * 0. If in a local literal table, -1. */
+    Namespace *nsPtr;		/* Namespace in which this literal is used. We
+				 * try to avoid sharing literal non-FQ command
+				 * names among different namespaces to reduce
+				 * shimmering. */
+} LiteralEntry;
+
+typedef struct LiteralTable {
+    LiteralEntry **buckets;	/* Pointer to bucket array. Each element
+				 * points to first entry in bucket's hash
+				 * chain, or NULL. */
+    LiteralEntry *staticBuckets[TCL_SMALL_HASH_TABLE];
+				/* Bucket array used for small tables to avoid
+				 * mallocs and frees. */
+    int numBuckets;		/* Total number of buckets allocated at
+				 * **buckets. */
+    int numEntries;		/* Total number of entries present in
+				 * table. */
+    int rebuildSize;		/* Enlarge table when numEntries gets to be
+				 * this large. */
+    int mask;			/* Mask value used in hashing function. */
+} LiteralTable;
+
+/*
+ * The following structure defines for each Tcl interpreter various
+ * statistics-related information about the bytecode compiler and
+ * interpreter's operation in that interpreter.
+ */
+
+#ifdef TCL_COMPILE_STATS
+typedef struct ByteCodeStats {
+    long numExecutions;		/* Number of ByteCodes executed. */
+    long numCompilations;	/* Number of ByteCodes created. */
+    long numByteCodesFreed;	/* Number of ByteCodes destroyed. */
+    long instructionCount[256];	/* Number of times each instruction was
+				 * executed. */
+
+    double totalSrcBytes;	/* Total source bytes ever compiled. */
+    double totalByteCodeBytes;	/* Total bytes for all ByteCodes. */
+    double currentSrcBytes;	/* Src bytes for all current ByteCodes. */
+    double currentByteCodeBytes;/* Code bytes in all current ByteCodes. */
+
+    long srcCount[32];		/* Source size distribution: # of srcs of
+				 * size [2**(n-1)..2**n), n in [0..32). */
+    long byteCodeCount[32];	/* ByteCode size distribution. */
+    long lifetimeCount[32];	/* ByteCode lifetime distribution (ms). */
+
+    double currentInstBytes;	/* Instruction bytes-current ByteCodes. */
+    double currentLitBytes;	/* Current literal bytes. */
+    double currentExceptBytes;	/* Current exception table bytes. */
+    double currentAuxBytes;	/* Current auxiliary information bytes. */
+    double currentCmdMapBytes;	/* Current src<->code map bytes. */
+
+    long numLiteralsCreated;	/* Total literal objects ever compiled. */
+    double totalLitStringBytes;	/* Total string bytes in all literals. */
+    double currentLitStringBytes;
+				/* String bytes in current literals. */
+    long literalCount[32];	/* Distribution of literal string sizes. */
+} ByteCodeStats;
+#endif /* TCL_COMPILE_STATS */
+
+/*
+ * Structure used in implementation of those core ensembles which are
+ * partially compiled. Used as an array of these, with a terminating field
+ * whose 'name' is NULL.
+ */
+
+typedef struct {
+    const char *name;		/* The name of the subcommand. */
+    Tcl_ObjCmdProc *proc;	/* The implementation of the subcommand. */
+    CompileProc *compileProc;	/* The compiler for the subcommand. */
+    Tcl_ObjCmdProc *nreProc;	/* NRE implementation of this command. */
+    ClientData clientData;	/* Any clientData to give the command. */
+    int unsafe;			/* Whether this command is to be hidden by
+				 * default in a safe interpreter. */
+} EnsembleImplMap;
+
+/*
+ *----------------------------------------------------------------
+ * Data structures related to commands.
+ *----------------------------------------------------------------
+ */
+
+/*
+ * An imported command is created in an namespace when it imports a "real"
+ * command from another namespace. An imported command has a Command structure
+ * that points (via its ClientData value) to the "real" Command structure in
+ * the source namespace's command table. The real command records all the
+ * imported commands that refer to it in a list of ImportRef structures so
+ * that they can be deleted when the real command is deleted.
+ */
+
+typedef struct ImportRef {
+    struct Command *importedCmdPtr;
+				/* Points to the imported command created in
+				 * an importing namespace; this command
+				 * redirects its invocations to the "real"
+				 * command. */
+    struct ImportRef *nextPtr;	/* Next element on the linked list of imported
+				 * commands that refer to the "real" command.
+				 * The real command deletes these imported
+				 * commands on this list when it is
+				 * deleted. */
+} ImportRef;
+
+/*
+ * Data structure used as the ClientData of imported commands: commands
+ * created in an namespace when it imports a "real" command from another
+ * namespace.
+ */
+
+typedef struct ImportedCmdData {
+    struct Command *realCmdPtr;	/* "Real" command that this imported command
+				 * refers to. */
+    struct Command *selfPtr;	/* Pointer to this imported command. Needed
+				 * only when deleting it in order to remove it
+				 * from the real command's linked list of
+				 * imported commands that refer to it. */
+} ImportedCmdData;
+
+/*
+ * A Command structure exists for each command in a namespace. The Tcl_Command
+ * opaque type actually refers to these structures.
+ */
+
+typedef struct Command {
+    Tcl_HashEntry *hPtr;	/* Pointer to the hash table entry that refers
+				 * to this command. The hash table is either a
+				 * namespace's command table or an
+				 * interpreter's hidden command table. This
+				 * pointer is used to get a command's name
+				 * from its Tcl_Command handle. NULL means
+				 * that the hash table entry has been removed
+				 * already (this can happen if deleteProc
+				 * causes the command to be deleted or
+				 * recreated). */
+    Namespace *nsPtr;		/* Points to the namespace containing this
+				 * command. */
+    int refCount;		/* 1 if in command hashtable plus 1 for each
+				 * reference from a CmdName Tcl object
+				 * representing a command's name in a ByteCode
+				 * instruction sequence. This structure can be
+				 * freed when refCount becomes zero. */
+    int cmdEpoch;		/* Incremented to invalidate any references
+				 * that point to this command when it is
+				 * renamed, deleted, hidden, or exposed. */
+    CompileProc *compileProc;	/* Procedure called to compile command. NULL
+				 * if no compile proc exists for command. */
+    Tcl_ObjCmdProc *objProc;	/* Object-based command procedure. */
+    ClientData objClientData;	/* Arbitrary value passed to object proc. */
+    Tcl_CmdProc *proc;		/* String-based command procedure. */
+    ClientData clientData;	/* Arbitrary value passed to string proc. */
+    Tcl_CmdDeleteProc *deleteProc;
+				/* Procedure invoked when deleting command to,
+				 * e.g., free all client data. */
+    ClientData deleteData;	/* Arbitrary value passed to deleteProc. */
+    int flags;			/* Miscellaneous bits of information about
+				 * command. See below for definitions. */
+    ImportRef *importRefPtr;	/* List of each imported Command created in
+				 * another namespace when this command is
+				 * imported. These imported commands redirect
+				 * invocations back to this command. The list
+				 * is used to remove all those imported
+				 * commands when deleting this "real"
+				 * command. */
+    CommandTrace *tracePtr;	/* First in list of all traces set for this
+				 * command. */
+    Tcl_ObjCmdProc *nreProc;	/* NRE implementation of this command. */
+} Command;
+
+/*
+ * Flag bits for commands.
+ *
+ * CMD_IS_DELETED -		Means that the command is in the process of
+ *				being deleted (its deleteProc is currently
+ *				executing). Other attempts to delete the
+ *				command should be ignored.
+ * CMD_TRACE_ACTIVE -		1 means that trace processing is currently
+ *				underway for a rename/delete change. See the
+ *				two flags below for which is currently being
+ *				processed.
+ * CMD_HAS_EXEC_TRACES -	1 means that this command has at least one
+ *				execution trace (as opposed to simple
+ *				delete/rename traces) in its tracePtr list.
+ * CMD_COMPILES_EXPANDED -	1 means that this command has a compiler that
+ *				can handle expansion (provided it is not the
+ *				first word).
+ * TCL_TRACE_RENAME -		A rename trace is in progress. Further
+ *				recursive renames will not be traced.
+ * TCL_TRACE_DELETE -		A delete trace is in progress. Further
+ *				recursive deletes will not be traced.
+ * (these last two flags are defined in tcl.h)
+ */
+
+#define CMD_IS_DELETED		    0x1
+#define CMD_TRACE_ACTIVE	    0x2
+#define CMD_HAS_EXEC_TRACES	    0x4
+#define CMD_COMPILES_EXPANDED	    0x8
+#define CMD_REDEF_IN_PROGRESS	    0x10
+
+/*
+ *----------------------------------------------------------------
+ * Data structures related to name resolution procedures.
+ *----------------------------------------------------------------
+ */
+
+/*
+ * The interpreter keeps a linked list of name resolution schemes. The scheme
+ * for a namespace is consulted first, followed by the list of schemes in an
+ * interpreter, followed by the default name resolution in Tcl. Schemes are
+ * added/removed from the interpreter's list by calling Tcl_AddInterpResolver
+ * and Tcl_RemoveInterpResolver.
+ */
+
+typedef struct ResolverScheme {
+    char *name;			/* Name identifying this scheme. */
+    Tcl_ResolveCmdProc *cmdResProc;
+				/* Procedure handling command name
+				 * resolution. */
+    Tcl_ResolveVarProc *varResProc;
+				/* Procedure handling variable name resolution
+				 * for variables that can only be handled at
+				 * runtime. */
+    Tcl_ResolveCompiledVarProc *compiledVarResProc;
+				/* Procedure handling variable name resolution
+				 * at compile time. */
+
+    struct ResolverScheme *nextPtr;
+				/* Pointer to next record in linked list. */
+} ResolverScheme;
+
+/*
+ * Forward declaration of the TIP#143 limit handler structure.
+ */
+
+typedef struct LimitHandler LimitHandler;
+
+/*
+ * TIP #268.
+ * Values for the selection mode, i.e the package require preferences.
+ */
+
+enum PkgPreferOptions {
+    PKG_PREFER_LATEST, PKG_PREFER_STABLE
+};
+
+/*
+ *----------------------------------------------------------------
+ * This structure shadows the first few fields of the memory cache for the
+ * allocator defined in tclThreadAlloc.c; it has to be kept in sync with the
+ * definition there.
+ * Some macros require knowledge of some fields in the struct in order to
+ * avoid hitting the TSD unnecessarily. In order to facilitate this, a pointer
+ * to the relevant fields is kept in the allocCache field in struct Interp.
+ *----------------------------------------------------------------
+ */
+
+typedef struct AllocCache {
+    struct Cache *nextPtr;	/* Linked list of cache entries. */
+    Tcl_ThreadId owner;		/* Which thread's cache is this? */
+    Tcl_Obj *firstObjPtr;	/* List of free objects for thread. */
+    int numObjects;		/* Number of objects for thread. */
+} AllocCache;
+
+/*
+ *----------------------------------------------------------------
+ * This structure defines an interpreter, which is a collection of commands
+ * plus other state information related to interpreting commands, such as
+ * variable storage. Primary responsibility for this data structure is in
+ * tclBasic.c, but almost every Tcl source file uses something in here.
+ *----------------------------------------------------------------
+ */
+
+typedef struct Interp {
+    /*
+     * Note: the first three fields must match exactly the fields in a
+     * Tcl_Interp struct (see tcl.h). If you change one, be sure to change the
+     * other.
+     *
+     * The interpreter's result is held in both the string and the
+     * objResultPtr fields. These fields hold, respectively, the result's
+     * string or object value. The interpreter's result is always in the
+     * result field if that is non-empty, otherwise it is in objResultPtr.
+     * The two fields are kept consistent unless some C code sets
+     * interp->result directly. Programs should not access result and
+     * objResultPtr directly; instead, they should always get and set the
+     * result using procedures such as Tcl_SetObjResult, Tcl_GetObjResult, and
+     * Tcl_GetStringResult. See the SetResult man page for details.
+     */
+
+    char *result;		/* If the last command returned a string
+				 * result, this points to it. Should not be
+				 * accessed directly; see comment above. */
+    Tcl_FreeProc *freeProc;	/* Zero means a string result is statically
+				 * allocated. TCL_DYNAMIC means string result
+				 * was allocated with ckalloc and should be
+				 * freed with ckfree. Other values give
+				 * address of procedure to invoke to free the
+				 * string result. Tcl_Eval must free it before
+				 * executing next command. */
+    int errorLine;		/* When TCL_ERROR is returned, this gives the
+				 * line number in the command where the error
+				 * occurred (1 means first line). */
+    const struct TclStubs *stubTable;
+				/* Pointer to the exported Tcl stub table. On
+				 * previous versions of Tcl this is a pointer
+				 * to the objResultPtr or a pointer to a
+				 * buckets array in a hash table. We therefore
+				 * have to do some careful checking before we
+				 * can use this. */
+
+    TclHandle handle;		/* Handle used to keep track of when this
+				 * interp is deleted. */
+
+    Namespace *globalNsPtr;	/* The interpreter's global namespace. */
+    Tcl_HashTable *hiddenCmdTablePtr;
+				/* Hash table used by tclBasic.c to keep track
+				 * of hidden commands on a per-interp
+				 * basis. */
+    ClientData interpInfo;	/* Information used by tclInterp.c to keep
+				 * track of master/slave interps on a
+				 * per-interp basis. */
+    union {
+	void (*optimizer)(void *envPtr);
+	Tcl_HashTable unused2;	/* No longer used (was mathFuncTable). The
+				 * unused space in interp was repurposed for
+				 * pluggable bytecode optimizers. The core
+				 * contains one optimizer, which can be
+				 * selectively overriden by extensions. */
+    } extra;
+
+    /*
+     * Information related to procedures and variables. See tclProc.c and
+     * tclVar.c for usage.
+     */
+
+    int numLevels;		/* Keeps track of how many nested calls to
+				 * Tcl_Eval are in progress for this
+				 * interpreter. It's used to delay deletion of
+				 * the table until all Tcl_Eval invocations
+				 * are completed. */
+    int maxNestingDepth;	/* If numLevels exceeds this value then Tcl
+				 * assumes that infinite recursion has
+				 * occurred and it generates an error. */
+    CallFrame *framePtr;	/* Points to top-most in stack of all nested
+				 * procedure invocations. */
+    CallFrame *varFramePtr;	/* Points to the call frame whose variables
+				 * are currently in use (same as framePtr
+				 * unless an "uplevel" command is
+				 * executing). */
+    ActiveVarTrace *activeVarTracePtr;
+				/* First in list of active traces for interp,
+				 * or NULL if no active traces. */
+    int returnCode;		/* [return -code] parameter. */
+    CallFrame *rootFramePtr;	/* Global frame pointer for this
+				 * interpreter. */
+    Namespace *lookupNsPtr;	/* Namespace to use ONLY on the next
+				 * TCL_EVAL_INVOKE call to Tcl_EvalObjv. */
+
+    /*
+     * Information used by Tcl_AppendResult to keep track of partial results.
+     * See Tcl_AppendResult code for details.
+     */
+
+    char *appendResult;		/* Storage space for results generated by
+				 * Tcl_AppendResult. Ckalloc-ed. NULL means
+				 * not yet allocated. */
+    int appendAvl;		/* Total amount of space available at
+				 * partialResult. */
+    int appendUsed;		/* Number of non-null bytes currently stored
+				 * at partialResult. */
+
+    /*
+     * Information about packages. Used only in tclPkg.c.
+     */
+
+    Tcl_HashTable packageTable;	/* Describes all of the packages loaded in or
+				 * available to this interpreter. Keys are
+				 * package names, values are (Package *)
+				 * pointers. */
+    char *packageUnknown;	/* Command to invoke during "package require"
+				 * commands for packages that aren't described
+				 * in packageTable. Ckalloc'ed, may be
+				 * NULL. */
+    /*
+     * Miscellaneous information:
+     */
+
+    int cmdCount;		/* Total number of times a command procedure
+				 * has been called for this interpreter. */
+    int evalFlags;		/* Flags to control next call to Tcl_Eval.
+				 * Normally zero, but may be set before
+				 * calling Tcl_Eval. See below for valid
+				 * values. */
+    int unused1;		/* No longer used (was termOffset) */
+    LiteralTable literalTable;	/* Contains LiteralEntry's describing all Tcl
+				 * objects holding literals of scripts
+				 * compiled by the interpreter. Indexed by the
+				 * string representations of literals. Used to
+				 * avoid creating duplicate objects. */
+    int compileEpoch;		/* Holds the current "compilation epoch" for
+				 * this interpreter. This is incremented to
+				 * invalidate existing ByteCodes when, e.g., a
+				 * command with a compile procedure is
+				 * redefined. */
+    Proc *compiledProcPtr;	/* If a procedure is being compiled, a pointer
+				 * to its Proc structure; otherwise, this is
+				 * NULL. Set by ObjInterpProc in tclProc.c and
+				 * used by tclCompile.c to process local
+				 * variables appropriately. */
+    ResolverScheme *resolverPtr;
+				/* Linked list of name resolution schemes
+				 * added to this interpreter. Schemes are
+				 * added and removed by calling
+				 * Tcl_AddInterpResolvers and
+				 * Tcl_RemoveInterpResolver respectively. */
+    Tcl_Obj *scriptFile;	/* NULL means there is no nested source
+				 * command active; otherwise this points to
+				 * pathPtr of the file being sourced. */
+    int flags;			/* Various flag bits. See below. */
+    long randSeed;		/* Seed used for rand() function. */
+    Trace *tracePtr;		/* List of traces for this interpreter. */
+    Tcl_HashTable *assocData;	/* Hash table for associating data with this
+				 * interpreter. Cleaned up when this
+				 * interpreter is deleted. */
+    struct ExecEnv *execEnvPtr;	/* Execution environment for Tcl bytecode
+				 * execution. Contains a pointer to the Tcl
+				 * evaluation stack. */
+    Tcl_Obj *emptyObjPtr;	/* Points to an object holding an empty
+				 * string. Returned by Tcl_ObjSetVar2 when
+				 * variable traces change a variable in a
+				 * gross way. */
+    char resultSpace[TCL_RESULT_SIZE+1];
+				/* Static space holding small results. */
+    Tcl_Obj *objResultPtr;	/* If the last command returned an object
+				 * result, this points to it. Should not be
+				 * accessed directly; see comment above. */
+    Tcl_ThreadId threadId;	/* ID of thread that owns the interpreter. */
+
+    ActiveCommandTrace *activeCmdTracePtr;
+				/* First in list of active command traces for
+				 * interp, or NULL if no active traces. */
+    ActiveInterpTrace *activeInterpTracePtr;
+				/* First in list of active traces for interp,
+				 * or NULL if no active traces. */
+
+    int tracesForbiddingInline;	/* Count of traces (in the list headed by
+				 * tracePtr) that forbid inline bytecode
+				 * compilation. */
+
+    /*
+     * Fields used to manage extensible return options (TIP 90).
+     */
+
+    Tcl_Obj *returnOpts;	/* A dictionary holding the options to the
+				 * last [return] command. */
+
+    Tcl_Obj *errorInfo;		/* errorInfo value (now as a Tcl_Obj). */
+    Tcl_Obj *eiVar;		/* cached ref to ::errorInfo variable. */
+    Tcl_Obj *errorCode;		/* errorCode value (now as a Tcl_Obj). */
+    Tcl_Obj *ecVar;		/* cached ref to ::errorInfo variable. */
+    int returnLevel;		/* [return -level] parameter. */
+
+    /*
+     * Resource limiting framework support (TIP#143).
+     */
+
+    struct {
+	int active;		/* Flag values defining which limits have been
+				 * set. */
+	int granularityTicker;	/* Counter used to determine how often to
+				 * check the limits. */
+	int exceeded;		/* Which limits have been exceeded, described
+				 * as flag values the same as the 'active'
+				 * field. */
+
+	int cmdCount;		/* Limit for how many commands to execute in
+				 * the interpreter. */
+	LimitHandler *cmdHandlers;
+				/* Handlers to execute when the limit is
+				 * reached. */
+	int cmdGranularity;	/* Mod factor used to determine how often to
+				 * evaluate the limit check. */
+
+	Tcl_Time time;		/* Time limit for execution within the
+				 * interpreter. */
+	LimitHandler *timeHandlers;
+				/* Handlers to execute when the limit is
+				 * reached. */
+	int timeGranularity;	/* Mod factor used to determine how often to
+				 * evaluate the limit check. */
+	Tcl_TimerToken timeEvent;
+				/* Handle for a timer callback that will occur
+				 * when the time-limit is exceeded. */
+
+	Tcl_HashTable callbacks;/* Mapping from (interp,type) pair to data
+				 * used to install a limit handler callback to
+				 * run in _this_ interp when the limit is
+				 * exceeded. */
+    } limit;
+
+    /*
+     * Information for improved default error generation from ensembles
+     * (TIP#112).
+     */
+
+    struct {
+	Tcl_Obj *const *sourceObjs;
+				/* What arguments were actually input into the
+				 * *root* ensemble command? (Nested ensembles
+				 * don't rewrite this.) NULL if we're not
+				 * processing an ensemble. */
+	int numRemovedObjs;	/* How many arguments have been stripped off
+				 * because of ensemble processing. */
+	int numInsertedObjs;	/* How many of the current arguments were
+				 * inserted by an ensemble. */
+    } ensembleRewrite;
+
+    /*
+     * TIP #219: Global info for the I/O system.
+     */
+
+    Tcl_Obj *chanMsg;		/* Error message set by channel drivers, for
+				 * the propagation of arbitrary Tcl errors.
+				 * This information, if present (chanMsg not
+				 * NULL), takes precedence over a POSIX error
+				 * code returned by a channel operation. */
+
+    /*
+     * Source code origin information (TIP #280).
+     */
+
+    CmdFrame *cmdFramePtr;	/* Points to the command frame containing the
+				 * location information for the current
+				 * command. */
+    const CmdFrame *invokeCmdFramePtr;
+				/* Points to the command frame which is the
+				 * invoking context of the bytecode compiler.
+				 * NULL when the byte code compiler is not
+				 * active. */
+    int invokeWord;		/* Index of the word in the command which
+				 * is getting compiled. */
+    Tcl_HashTable *linePBodyPtr;/* This table remembers for each statically
+				 * defined procedure the location information
+				 * for its body. It is keyed by the address of
+				 * the Proc structure for a procedure. The
+				 * values are "struct CmdFrame*". */
+    Tcl_HashTable *lineBCPtr;	/* This table remembers for each ByteCode
+				 * object the location information for its
+				 * body. It is keyed by the address of the
+				 * Proc structure for a procedure. The values
+				 * are "struct ExtCmdLoc*". (See
+				 * tclCompile.h) */
+    Tcl_HashTable *lineLABCPtr;
+    Tcl_HashTable *lineLAPtr;	/* This table remembers for each argument of a
+				 * command on the execution stack the index of
+				 * the argument in the command, and the
+				 * location data of the command. It is keyed
+				 * by the address of the Tcl_Obj containing
+				 * the argument. The values are "struct
+				 * CFWord*" (See tclBasic.c). This allows
+				 * commands like uplevel, eval, etc. to find
+				 * location information for their arguments,
+				 * if they are a proper literal argument to an
+				 * invoking command. Alt view: An index to the
+				 * CmdFrame stack keyed by command argument
+				 * holders. */
+    ContLineLoc *scriptCLLocPtr;/* This table points to the location data for
+				 * invisible continuation lines in the script,
+				 * if any. This pointer is set by the function
+				 * TclEvalObjEx() in file "tclBasic.c", and
+				 * used by function ...() in the same file.
+				 * It does for the eval/direct path of script
+				 * execution what CompileEnv.clLoc does for
+				 * the bytecode compiler.
+				 */
+    /*
+     * TIP #268. The currently active selection mode, i.e. the package require
+     * preferences.
+     */
+
+    int packagePrefer;		/* Current package selection mode. */
+
+    /*
+     * Hashtables for variable traces and searches.
+     */
+
+    Tcl_HashTable varTraces;	/* Hashtable holding the start of a variable's
+				 * active trace list; varPtr is the key. */
+    Tcl_HashTable varSearches;	/* Hashtable holding the start of a variable's
+				 * active searches list; varPtr is the key. */
+    /*
+     * The thread-specific data ekeko: cache pointers or values that
+     *  (a) do not change during the thread's lifetime
+     *  (b) require access to TSD to determine at runtime
+     *  (c) are accessed very often (e.g., at each command call)
+     *
+     * Note that these are the same for all interps in the same thread. They
+     * just have to be initialised for the thread's master interp, slaves
+     * inherit the value.
+     *
+     * They are used by the macros defined below.
+     */
+
+    AllocCache *allocCache;
+    void *pendingObjDataPtr;	/* Pointer to the Cache and PendingObjData
+				 * structs for this interp's thread; see
+				 * tclObj.c and tclThreadAlloc.c */
+    int *asyncReadyPtr;		/* Pointer to the asyncReady indicator for
+				 * this interp's thread; see tclAsync.c */
+    /*
+     * The pointer to the object system root ekeko. c.f. TIP #257.
+     */
+    void *objectFoundation;	/* Pointer to the Foundation structure of the
+				 * object system, which contains things like
+				 * references to key namespaces. See
+				 * tclOOInt.h and tclOO.c for real definition
+				 * and setup. */
+
+    struct NRE_callback *deferredCallbacks;
+				/* Callbacks that are set previous to a call
+				 * to some Eval function but that actually
+				 * belong to the command that is about to be
+				 * called - i.e., they should be run *before*
+				 * any tailcall is invoked. */
+
+    /*
+     * TIP #285, Script cancellation support.
+     */
+
+    Tcl_AsyncHandler asyncCancel;
+				/* Async handler token for Tcl_CancelEval. */
+    Tcl_Obj *asyncCancelMsg;	/* Error message set by async cancel handler
+				 * for the propagation of arbitrary Tcl
+				 * errors. This information, if present
+				 * (asyncCancelMsg not NULL), takes precedence
+				 * over the default error messages returned by
+				 * a script cancellation operation. */
+
+	/*
+	 * TIP #348 IMPLEMENTATION  -  Substituted error stack
+	 */
+    Tcl_Obj *errorStack;	/* [info errorstack] value (as a Tcl_Obj). */
+    Tcl_Obj *upLiteral;		/* "UP" literal for [info errorstack] */
+    Tcl_Obj *callLiteral;	/* "CALL" literal for [info errorstack] */
+    Tcl_Obj *innerLiteral;	/* "INNER" literal for [info errorstack] */
+    Tcl_Obj *innerContext;	/* cached list for fast reallocation */
+    int resetErrorStack;        /* controls cleaning up of ::errorStack */
+
+#ifdef TCL_COMPILE_STATS
+    /*
+     * Statistical information about the bytecode compiler and interpreter's
+     * operation. This should be the last field of Interp.
+     */
+
+    ByteCodeStats stats;	/* Holds compilation and execution statistics
+				 * for this interpreter. */
+#endif /* TCL_COMPILE_STATS */
+} Interp;
+
+/*
+ * Macros that use the TSD-ekeko.
+ */
+
+#define TclAsyncReady(iPtr) \
+    *((iPtr)->asyncReadyPtr)
+
+/*
+ * Macros for script cancellation support (TIP #285).
+ */
+
+#define TclCanceled(iPtr) \
+    (((iPtr)->flags & CANCELED) || ((iPtr)->flags & TCL_CANCEL_UNWIND))
+
+#define TclSetCancelFlags(iPtr, cancelFlags)   \
+    (iPtr)->flags |= CANCELED;                 \
+    if ((cancelFlags) & TCL_CANCEL_UNWIND) {   \
+        (iPtr)->flags |= TCL_CANCEL_UNWIND;    \
+    }
+
+#define TclUnsetCancelFlags(iPtr) \
+    (iPtr)->flags &= (~(CANCELED | TCL_CANCEL_UNWIND))
+
+/*
+ * Macros for splicing into and out of doubly linked lists. They assume
+ * existence of struct items 'prevPtr' and 'nextPtr'.
+ *
+ * a = element to add or remove.
+ * b = list head.
+ *
+ * TclSpliceIn adds to the head of the list.
+ */
+
+#define TclSpliceIn(a,b)			\
+    (a)->nextPtr = (b);				\
+    if ((b) != NULL) {				\
+	(b)->prevPtr = (a);			\
+    }						\
+    (a)->prevPtr = NULL, (b) = (a);
+
+#define TclSpliceOut(a,b)			\
+    if ((a)->prevPtr != NULL) {			\
+	(a)->prevPtr->nextPtr = (a)->nextPtr;	\
+    } else {					\
+	(b) = (a)->nextPtr;			\
+    }						\
+    if ((a)->nextPtr != NULL) {			\
+	(a)->nextPtr->prevPtr = (a)->prevPtr;	\
+    }
+
+/*
+ * EvalFlag bits for Interp structures:
+ *
+ * TCL_ALLOW_EXCEPTIONS	1 means it's OK for the script to terminate with a
+ *			code other than TCL_OK or TCL_ERROR; 0 means codes
+ *			other than these should be turned into errors.
+ */
+
+#define TCL_ALLOW_EXCEPTIONS		0x04
+#define TCL_EVAL_FILE			0x02
+#define TCL_EVAL_SOURCE_IN_FRAME	0x10
+#define TCL_EVAL_NORESOLVE		0x20
+
+/*
+ * Flag bits for Interp structures:
+ *
+ * DELETED:		Non-zero means the interpreter has been deleted:
+ *			don't process any more commands for it, and destroy
+ *			the structure as soon as all nested invocations of
+ *			Tcl_Eval are done.
+ * ERR_ALREADY_LOGGED:	Non-zero means information has already been logged in
+ *			iPtr->errorInfo for the current Tcl_Eval instance, so
+ *			Tcl_Eval needn't log it (used to implement the "error
+ *			message log" command).
+ * DONT_COMPILE_CMDS_INLINE: Non-zero means that the bytecode compiler should
+ *			not compile any commands into an inline sequence of
+ *			instructions. This is set 1, for example, when command
+ *			traces are requested.
+ * RAND_SEED_INITIALIZED: Non-zero means that the randSeed value of the interp
+ *			has not be initialized. This is set 1 when we first
+ *			use the rand() or srand() functions.
+ * SAFE_INTERP:		Non zero means that the current interp is a safe
+ *			interp (i.e. it has only the safe commands installed,
+ *			less priviledge than a regular interp).
+ * INTERP_DEBUG_FRAME:	Used for switching on various extra interpreter
+ *			debug/info mechanisms (e.g. info frame eval/uplevel
+ *			tracing) which are performance intensive.
+ * INTERP_TRACE_IN_PROGRESS: Non-zero means that an interp trace is currently
+ *			active; so no further trace callbacks should be
+ *			invoked.
+ * INTERP_ALTERNATE_WRONG_ARGS: Used for listing second and subsequent forms
+ *			of the wrong-num-args string in Tcl_WrongNumArgs.
+ *			Makes it append instead of replacing and uses
+ *			different intermediate text.
+ * CANCELED:		Non-zero means that the script in progress should be
+ *			canceled as soon as possible. This can be checked by
+ *			extensions (and the core itself) by calling
+ *			Tcl_Canceled and checking if TCL_ERROR is returned.
+ *			This is a one-shot flag that is reset immediately upon
+ *			being detected; however, if the TCL_CANCEL_UNWIND flag
+ *			is set Tcl_Canceled will continue to report that the
+ *			script in progress has been canceled thereby allowing
+ *			the evaluation stack for the interp to be fully
+ *			unwound.
+ *
+ * WARNING: For the sake of some extensions that have made use of former
+ * internal values, do not re-use the flag values 2 (formerly ERR_IN_PROGRESS)
+ * or 8 (formerly ERROR_CODE_SET).
+ */
+
+#define DELETED				     1
+#define ERR_ALREADY_LOGGED		     4
+#define INTERP_DEBUG_FRAME		  0x10
+#define DONT_COMPILE_CMDS_INLINE	  0x20
+#define RAND_SEED_INITIALIZED		  0x40
+#define SAFE_INTERP			  0x80
+#define INTERP_TRACE_IN_PROGRESS	 0x200
+#define INTERP_ALTERNATE_WRONG_ARGS	 0x400
+#define ERR_LEGACY_COPY			 0x800
+#define CANCELED			0x1000
+
+/*
+ * Maximum number of levels of nesting permitted in Tcl commands (used to
+ * catch infinite recursion).
+ */
+
+#define MAX_NESTING_DEPTH	1000
+
+/*
+ * The macro below is used to modify a "char" value (e.g. by casting it to an
+ * unsigned character) so that it can be used safely with macros such as
+ * isspace.
+ */
+
+#define UCHAR(c) ((unsigned char) (c))
+
+/*
+ * This macro is used to properly align the memory allocated by Tcl, giving
+ * the same alignment as the native malloc.
+ */
+
+#if defined(__APPLE__)
+#define TCL_ALLOCALIGN	16
+#else
+#define TCL_ALLOCALIGN	(2*sizeof(void *))
+#endif
+
+/*
+ * This macro is used to determine the offset needed to safely allocate any
+ * data structure in memory. Given a starting offset or size, it "rounds up"
+ * or "aligns" the offset to the next 8-byte boundary so that any data
+ * structure can be placed at the resulting offset without fear of an
+ * alignment error.
+ *
+ * WARNING!! DO NOT USE THIS MACRO TO ALIGN POINTERS: it will produce the
+ * wrong result on platforms that allocate addresses that are divisible by 4
+ * or 2. Only use it for offsets or sizes.
+ *
+ * This macro is only used by tclCompile.c in the core (Bug 926445). It
+ * however not be made file static, as extensions that touch bytecodes
+ * (notably tbcload) require it.
+ */
+
+#define TCL_ALIGN(x) (((int)(x) + 7) & ~7)
+
+/*
+ * The following enum values are used to specify the runtime platform setting
+ * of the tclPlatform variable.
+ */
+
+typedef enum {
+    TCL_PLATFORM_UNIX = 0,	/* Any Unix-like OS. */
+    TCL_PLATFORM_WINDOWS = 2	/* Any Microsoft Windows OS. */
+} TclPlatformType;
+
+/*
+ * The following enum values are used to indicate the translation of a Tcl
+ * channel. Declared here so that each platform can define
+ * TCL_PLATFORM_TRANSLATION to the native translation on that platform.
+ */
+
+typedef enum TclEolTranslation {
+    TCL_TRANSLATE_AUTO,		/* Eol == \r, \n and \r\n. */
+    TCL_TRANSLATE_CR,		/* Eol == \r. */
+    TCL_TRANSLATE_LF,		/* Eol == \n. */
+    TCL_TRANSLATE_CRLF		/* Eol == \r\n. */
+} TclEolTranslation;
+
+/*
+ * Flags for TclInvoke:
+ *
+ * TCL_INVOKE_HIDDEN		Invoke a hidden command; if not set, invokes
+ *				an exposed command.
+ * TCL_INVOKE_NO_UNKNOWN	If set, "unknown" is not invoked if the
+ *				command to be invoked is not found. Only has
+ *				an effect if invoking an exposed command,
+ *				i.e. if TCL_INVOKE_HIDDEN is not also set.
+ * TCL_INVOKE_NO_TRACEBACK	Does not record traceback information if the
+ *				invoked command returns an error. Used if the
+ *				caller plans on recording its own traceback
+ *				information.
+ */
+
+#define	TCL_INVOKE_HIDDEN	(1<<0)
+#define TCL_INVOKE_NO_UNKNOWN	(1<<1)
+#define TCL_INVOKE_NO_TRACEBACK	(1<<2)
+
+/*
+ * The structure used as the internal representation of Tcl list objects. This
+ * struct is grown (reallocated and copied) as necessary to hold all the
+ * list's element pointers. The struct might contain more slots than currently
+ * used to hold all element pointers. This is done to make append operations
+ * faster.
+ */
+
+typedef struct List {
+    int refCount;
+    int maxElemCount;		/* Total number of element array slots. */
+    int elemCount;		/* Current number of list elements. */
+    int canonicalFlag;		/* Set if the string representation was
+				 * derived from the list representation. May
+				 * be ignored if there is no string rep at
+				 * all.*/
+    Tcl_Obj *elements;		/* First list element; the struct is grown to
+				 * accomodate all elements. */
+} List;
+
+#define LIST_MAX \
+	(1 + (int)(((size_t)UINT_MAX - sizeof(List))/sizeof(Tcl_Obj *)))
+#define LIST_SIZE(numElems) \
+	(unsigned)(sizeof(List) + (((numElems) - 1) * sizeof(Tcl_Obj *)))
+
+/*
+ * Macro used to get the elements of a list object.
+ */
+
+#define ListRepPtr(listPtr) \
+    ((List *) (listPtr)->internalRep.twoPtrValue.ptr1)
+
+#define ListSetIntRep(objPtr, listRepPtr) \
+    (objPtr)->internalRep.twoPtrValue.ptr1 = (void *)(listRepPtr), \
+    (objPtr)->internalRep.twoPtrValue.ptr2 = NULL, \
+    (listRepPtr)->refCount++, \
+    (objPtr)->typePtr = &tclListType
+
+#define ListObjGetElements(listPtr, objc, objv) \
+    ((objv) = &(ListRepPtr(listPtr)->elements), \
+     (objc) = ListRepPtr(listPtr)->elemCount)
+
+#define ListObjLength(listPtr, len) \
+    ((len) = ListRepPtr(listPtr)->elemCount)
+
+#define ListObjIsCanonical(listPtr) \
+    (((listPtr)->bytes == NULL) || ListRepPtr(listPtr)->canonicalFlag)
+
+#define TclListObjGetElements(interp, listPtr, objcPtr, objvPtr) \
+    (((listPtr)->typePtr == &tclListType) \
+	    ? ((ListObjGetElements((listPtr), *(objcPtr), *(objvPtr))), TCL_OK)\
+	    : Tcl_ListObjGetElements((interp), (listPtr), (objcPtr), (objvPtr)))
+
+#define TclListObjLength(interp, listPtr, lenPtr) \
+    (((listPtr)->typePtr == &tclListType) \
+	    ? ((ListObjLength((listPtr), *(lenPtr))), TCL_OK)\
+	    : Tcl_ListObjLength((interp), (listPtr), (lenPtr)))
+
+#define TclListObjIsCanonical(listPtr) \
+    (((listPtr)->typePtr == &tclListType) ? ListObjIsCanonical((listPtr)) : 0)
+
+/*
+ * Modes for collecting (or not) in the implementations of TclNRForeachCmd,
+ * TclNRLmapCmd and their compilations.
+ */
+
+#define TCL_EACH_KEEP_NONE  0	/* Discard iteration result like [foreach] */
+#define TCL_EACH_COLLECT    1	/* Collect iteration result like [lmap] */
+
+/*
+ * Macros providing a faster path to integers: Tcl_GetLongFromObj everywhere,
+ * Tcl_GetIntFromObj and TclGetIntForIndex on platforms where longs are ints.
+ *
+ * WARNING: these macros eval their args more than once.
+ */
+
+#define TclGetLongFromObj(interp, objPtr, longPtr) \
+    (((objPtr)->typePtr == &tclIntType)	\
+	    ? ((*(longPtr) = (objPtr)->internalRep.longValue), TCL_OK) \
+	    : Tcl_GetLongFromObj((interp), (objPtr), (longPtr)))
+
+#if (LONG_MAX == INT_MAX)
+#define TclGetIntFromObj(interp, objPtr, intPtr) \
+    (((objPtr)->typePtr == &tclIntType)	\
+	    ? ((*(intPtr) = (objPtr)->internalRep.longValue), TCL_OK) \
+	    : Tcl_GetIntFromObj((interp), (objPtr), (intPtr)))
+#define TclGetIntForIndexM(interp, objPtr, endValue, idxPtr) \
+    (((objPtr)->typePtr == &tclIntType)	\
+	    ? ((*(idxPtr) = (objPtr)->internalRep.longValue), TCL_OK) \
+	    : TclGetIntForIndex((interp), (objPtr), (endValue), (idxPtr)))
+#else
+#define TclGetIntFromObj(interp, objPtr, intPtr) \
+    Tcl_GetIntFromObj((interp), (objPtr), (intPtr))
+#define TclGetIntForIndexM(interp, objPtr, ignore, idxPtr)	\
+    TclGetIntForIndex(interp, objPtr, ignore, idxPtr)
+#endif
+
+/*
+ * Macro used to save a function call for common uses of
+ * Tcl_GetWideIntFromObj(). The ANSI C "prototype" is:
+ *
+ * MODULE_SCOPE int TclGetWideIntFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr,
+ *			Tcl_WideInt *wideIntPtr);
+ */
+
+#ifdef TCL_WIDE_INT_IS_LONG
+#define TclGetWideIntFromObj(interp, objPtr, wideIntPtr) \
+    (((objPtr)->typePtr == &tclIntType)					\
+	? (*(wideIntPtr) = (Tcl_WideInt)				\
+		((objPtr)->internalRep.longValue), TCL_OK) :		\
+	Tcl_GetWideIntFromObj((interp), (objPtr), (wideIntPtr)))
+#else /* !TCL_WIDE_INT_IS_LONG */
+#define TclGetWideIntFromObj(interp, objPtr, wideIntPtr)		\
+    (((objPtr)->typePtr == &tclWideIntType)				\
+	? (*(wideIntPtr) = (objPtr)->internalRep.wideValue, TCL_OK) :	\
+    ((objPtr)->typePtr == &tclIntType)					\
+	? (*(wideIntPtr) = (Tcl_WideInt)				\
+		((objPtr)->internalRep.longValue), TCL_OK) :		\
+	Tcl_GetWideIntFromObj((interp), (objPtr), (wideIntPtr)))
+#endif /* TCL_WIDE_INT_IS_LONG */
+
+/*
+ * Flag values for TclTraceDictPath().
+ *
+ * DICT_PATH_READ indicates that all entries on the path must exist but no
+ * updates will be needed.
+ *
+ * DICT_PATH_UPDATE indicates that we are going to be doing an update at the
+ * tip of the path, so duplication of shared objects should be done along the
+ * way.
+ *
+ * DICT_PATH_EXISTS indicates that we are performing an existance test and a
+ * lookup failure should therefore not be an error. If (and only if) this flag
+ * is set, TclTraceDictPath() will return the special value
+ * DICT_PATH_NON_EXISTENT if the path is not traceable.
+ *
+ * DICT_PATH_CREATE (which also requires the DICT_PATH_UPDATE bit to be set)
+ * indicates that we are to create non-existant dictionaries on the path.
+ */
+
+#define DICT_PATH_READ		0
+#define DICT_PATH_UPDATE	1
+#define DICT_PATH_EXISTS	2
+#define DICT_PATH_CREATE	5
+
+#define DICT_PATH_NON_EXISTENT	((Tcl_Obj *) (void *) 1)
+
+/*
+ *----------------------------------------------------------------
+ * Data structures related to the filesystem internals
+ *----------------------------------------------------------------
+ */
+
+/*
+ * The version_2 filesystem is private to Tcl. As and when these changes have
+ * been thoroughly tested and investigated a new public filesystem interface
+ * will be released. The aim is more versatile virtual filesystem interfaces,
+ * more efficiency in 'path' manipulation and usage, and cleaner filesystem
+ * code internally.
+ */
+
+#define TCL_FILESYSTEM_VERSION_2	((Tcl_FSVersion) 0x2)
+typedef ClientData (TclFSGetCwdProc2)(ClientData clientData);
+typedef int (Tcl_FSLoadFileProc2) (Tcl_Interp *interp, Tcl_Obj *pathPtr,
+	Tcl_LoadHandle *handlePtr, Tcl_FSUnloadFileProc **unloadProcPtr, int flags);
+
+/*
+ * The following types are used for getting and storing platform-specific file
+ * attributes in tclFCmd.c and the various platform-versions of that file.
+ * This is done to have as much common code as possible in the file attributes
+ * code. For more information about the callbacks, see TclFileAttrsCmd in
+ * tclFCmd.c.
+ */
+
+typedef int (TclGetFileAttrProc)(Tcl_Interp *interp, int objIndex,
+	Tcl_Obj *fileName, Tcl_Obj **attrObjPtrPtr);
+typedef int (TclSetFileAttrProc)(Tcl_Interp *interp, int objIndex,
+	Tcl_Obj *fileName, Tcl_Obj *attrObjPtr);
+
+typedef struct TclFileAttrProcs {
+    TclGetFileAttrProc *getProc;/* The procedure for getting attrs. */
+    TclSetFileAttrProc *setProc;/* The procedure for setting attrs. */
+} TclFileAttrProcs;
+
+/*
+ * Opaque handle used in pipeline routines to encapsulate platform-dependent
+ * state.
+ */
+
+typedef struct TclFile_ *TclFile;
+
+/*
+ * The "globParameters" argument of the function TclGlob is an or'ed
+ * combination of the following values:
+ */
+
+#define TCL_GLOBMODE_NO_COMPLAIN	1
+#define TCL_GLOBMODE_JOIN		2
+#define TCL_GLOBMODE_DIR		4
+#define TCL_GLOBMODE_TAILS		8
+
+typedef enum Tcl_PathPart {
+    TCL_PATH_DIRNAME,
+    TCL_PATH_TAIL,
+    TCL_PATH_EXTENSION,
+    TCL_PATH_ROOT
+} Tcl_PathPart;
+
+/*
+ *----------------------------------------------------------------
+ * Data structures related to obsolete filesystem hooks
+ *----------------------------------------------------------------
+ */
+
+typedef int (TclStatProc_)(const char *path, struct stat *buf);
+typedef int (TclAccessProc_)(const char *path, int mode);
+typedef Tcl_Channel (TclOpenFileChannelProc_)(Tcl_Interp *interp,
+	const char *fileName, const char *modeString, int permissions);
+
+/*
+ *----------------------------------------------------------------
+ * Data structures related to procedures
+ *----------------------------------------------------------------
+ */
+
+typedef Tcl_CmdProc *TclCmdProcType;
+typedef Tcl_ObjCmdProc *TclObjCmdProcType;
+
+/*
+ *----------------------------------------------------------------
+ * Data structures for process-global values.
+ *----------------------------------------------------------------
+ */
+
+typedef void (TclInitProcessGlobalValueProc)(char **valuePtr, int *lengthPtr,
+	Tcl_Encoding *encodingPtr);
+
+/*
+ * A ProcessGlobalValue struct exists for each internal value in Tcl that is
+ * to be shared among several threads. Each thread sees a (Tcl_Obj) copy of
+ * the value, and the master is kept as a counted string, with epoch and mutex
+ * control. Each ProcessGlobalValue struct should be a static variable in some
+ * file.
+ */
+
+typedef struct ProcessGlobalValue {
+    int epoch;			/* Epoch counter to detect changes in the
+				 * master value. */
+    int numBytes;		/* Length of the master string. */
+    char *value;		/* The master string value. */
+    Tcl_Encoding encoding;	/* system encoding when master string was
+				 * initialized. */
+    TclInitProcessGlobalValueProc *proc;
+    				/* A procedure to initialize the master string
+				 * copy when a "get" request comes in before
+				 * any "set" request has been received. */
+    Tcl_Mutex mutex;		/* Enforce orderly access from multiple
+				 * threads. */
+    Tcl_ThreadDataKey key;	/* Key for per-thread data holding the
+				 * (Tcl_Obj) copy for each thread. */
+} ProcessGlobalValue;
+
+/*
+ *----------------------------------------------------------------------
+ * Flags for TclParseNumber
+ *----------------------------------------------------------------------
+ */
+
+#define TCL_PARSE_DECIMAL_ONLY		1
+				/* Leading zero doesn't denote octal or
+				 * hex. */
+#define TCL_PARSE_OCTAL_ONLY		2
+				/* Parse octal even without prefix. */
+#define TCL_PARSE_HEXADECIMAL_ONLY	4
+				/* Parse hexadecimal even without prefix. */
+#define TCL_PARSE_INTEGER_ONLY		8
+				/* Disable floating point parsing. */
+#define TCL_PARSE_SCAN_PREFIXES		16
+				/* Use [scan] rules dealing with 0?
+				 * prefixes. */
+#define TCL_PARSE_NO_WHITESPACE		32
+				/* Reject leading/trailing whitespace. */
+#define TCL_PARSE_BINARY_ONLY	64
+				/* Parse binary even without prefix. */
+
+/*
+ *----------------------------------------------------------------------
+ * Type values TclGetNumberFromObj
+ *----------------------------------------------------------------------
+ */
+
+#define TCL_NUMBER_LONG		1
+#define TCL_NUMBER_WIDE		2
+#define TCL_NUMBER_BIG		3
+#define TCL_NUMBER_DOUBLE	4
+#define TCL_NUMBER_NAN		5
+
+/*
+ *----------------------------------------------------------------
+ * Variables shared among Tcl modules but not used by the outside world.
+ *----------------------------------------------------------------
+ */
+
+MODULE_SCOPE char *tclNativeExecutableName;
+MODULE_SCOPE int tclFindExecutableSearchDone;
+MODULE_SCOPE char *tclMemDumpFileName;
+MODULE_SCOPE TclPlatformType tclPlatform;
+MODULE_SCOPE Tcl_NotifierProcs tclNotifierHooks;
+
+MODULE_SCOPE Tcl_Encoding tclIdentityEncoding;
+
+/*
+ * TIP #233 (Virtualized Time)
+ * Data for the time hooks, if any.
+ */
+
+MODULE_SCOPE Tcl_GetTimeProc *tclGetTimeProcPtr;
+MODULE_SCOPE Tcl_ScaleTimeProc *tclScaleTimeProcPtr;
+MODULE_SCOPE ClientData tclTimeClientData;
+
+/*
+ * Variables denoting the Tcl object types defined in the core.
+ */
+
+MODULE_SCOPE const Tcl_ObjType tclBignumType;
+MODULE_SCOPE const Tcl_ObjType tclBooleanType;
+MODULE_SCOPE const Tcl_ObjType tclByteArrayType;
+MODULE_SCOPE const Tcl_ObjType tclByteCodeType;
+MODULE_SCOPE const Tcl_ObjType tclDoubleType;
+MODULE_SCOPE const Tcl_ObjType tclEndOffsetType;
+MODULE_SCOPE const Tcl_ObjType tclIntType;
+MODULE_SCOPE const Tcl_ObjType tclListType;
+MODULE_SCOPE const Tcl_ObjType tclDictType;
+MODULE_SCOPE const Tcl_ObjType tclProcBodyType;
+MODULE_SCOPE const Tcl_ObjType tclStringType;
+MODULE_SCOPE const Tcl_ObjType tclArraySearchType;
+MODULE_SCOPE const Tcl_ObjType tclEnsembleCmdType;
+#ifndef TCL_WIDE_INT_IS_LONG
+MODULE_SCOPE const Tcl_ObjType tclWideIntType;
+#endif
+MODULE_SCOPE const Tcl_ObjType tclRegexpType;
+MODULE_SCOPE Tcl_ObjType tclCmdNameType;
+
+/*
+ * Variables denoting the hash key types defined in the core.
+ */
+
+MODULE_SCOPE const Tcl_HashKeyType tclArrayHashKeyType;
+MODULE_SCOPE const Tcl_HashKeyType tclOneWordHashKeyType;
+MODULE_SCOPE const Tcl_HashKeyType tclStringHashKeyType;
+MODULE_SCOPE const Tcl_HashKeyType tclObjHashKeyType;
+
+/*
+ * The head of the list of free Tcl objects, and the total number of Tcl
+ * objects ever allocated and freed.
+ */
+
+MODULE_SCOPE Tcl_Obj *	tclFreeObjList;
+
+#ifdef TCL_COMPILE_STATS
+MODULE_SCOPE long	tclObjsAlloced;
+MODULE_SCOPE long	tclObjsFreed;
+#define TCL_MAX_SHARED_OBJ_STATS 5
+MODULE_SCOPE long	tclObjsShared[TCL_MAX_SHARED_OBJ_STATS];
+#endif /* TCL_COMPILE_STATS */
+
+/*
+ * Pointer to a heap-allocated string of length zero that the Tcl core uses as
+ * the value of an empty string representation for an object. This value is
+ * shared by all new objects allocated by Tcl_NewObj.
+ */
+
+MODULE_SCOPE char *	tclEmptyStringRep;
+MODULE_SCOPE char	tclEmptyString;
+
+/*
+ *----------------------------------------------------------------
+ * Procedures shared among Tcl modules but not used by the outside world,
+ * introduced by/for NRE.
+ *----------------------------------------------------------------
+ */
+
+MODULE_SCOPE Tcl_ObjCmdProc TclNRApplyObjCmd;
+MODULE_SCOPE Tcl_ObjCmdProc TclNREvalObjCmd;
+MODULE_SCOPE Tcl_ObjCmdProc TclNRCatchObjCmd;
+MODULE_SCOPE Tcl_ObjCmdProc TclNRExprObjCmd;
+MODULE_SCOPE Tcl_ObjCmdProc TclNRForObjCmd;
+MODULE_SCOPE Tcl_ObjCmdProc TclNRForeachCmd;
+MODULE_SCOPE Tcl_ObjCmdProc TclNRIfObjCmd;
+MODULE_SCOPE Tcl_ObjCmdProc TclNRLmapCmd;
+MODULE_SCOPE Tcl_ObjCmdProc TclNRSourceObjCmd;
+MODULE_SCOPE Tcl_ObjCmdProc TclNRSubstObjCmd;
+MODULE_SCOPE Tcl_ObjCmdProc TclNRSwitchObjCmd;
+MODULE_SCOPE Tcl_ObjCmdProc TclNRTryObjCmd;
+MODULE_SCOPE Tcl_ObjCmdProc TclNRUplevelObjCmd;
+MODULE_SCOPE Tcl_ObjCmdProc TclNRWhileObjCmd;
+
+MODULE_SCOPE Tcl_NRPostProc TclNRForIterCallback;
+MODULE_SCOPE Tcl_NRPostProc TclNRCoroutineActivateCallback;
+MODULE_SCOPE Tcl_ObjCmdProc TclNRTailcallObjCmd;
+MODULE_SCOPE Tcl_NRPostProc TclNRTailcallEval;
+MODULE_SCOPE Tcl_ObjCmdProc TclNRCoroutineObjCmd;
+MODULE_SCOPE Tcl_ObjCmdProc TclNRYieldObjCmd;
+MODULE_SCOPE Tcl_ObjCmdProc TclNRYieldmObjCmd;
+MODULE_SCOPE Tcl_ObjCmdProc TclNRYieldToObjCmd;
+MODULE_SCOPE Tcl_ObjCmdProc TclNRInvoke;
+MODULE_SCOPE Tcl_NRPostProc TclNRReleaseValues;
+
+MODULE_SCOPE void  TclSetTailcall(Tcl_Interp *interp, Tcl_Obj *tailcallPtr);
+MODULE_SCOPE void  TclPushTailcallPoint(Tcl_Interp *interp);
+
+/* These two can be considered for the public api */
+MODULE_SCOPE void  TclMarkTailcall(Tcl_Interp *interp);
+MODULE_SCOPE void  TclSkipTailcall(Tcl_Interp *interp);
+
+/*
+ * This structure holds the data for the various iteration callbacks used to
+ * NRE the 'for' and 'while' commands. We need a separate structure because we
+ * have more than the 4 client data entries we can provide directly thorugh
+ * the callback API. It is the 'word' information which puts us over the
+ * limit. It is needed because the loop body is argument 4 of 'for' and
+ * argument 2 of 'while'. Not providing the correct index confuses the #280
+ * code. We TclSmallAlloc/Free this.
+ */
+
+typedef struct ForIterData {
+    Tcl_Obj *cond;		/* Loop condition expression. */
+    Tcl_Obj *body;		/* Loop body. */
+    Tcl_Obj *next;		/* Loop step script, NULL for 'while'. */
+    const char *msg;		/* Error message part. */
+    int word;			/* Index of the body script in the command */
+} ForIterData;
+
+/* TIP #357 - Structure doing the bookkeeping of handles for Tcl_LoadFile
+ *            and Tcl_FindSymbol. This structure corresponds to an opaque
+ *            typedef in tcl.h */
+
+typedef void* TclFindSymbolProc(Tcl_Interp* interp, Tcl_LoadHandle loadHandle,
+				const char* symbol);
+struct Tcl_LoadHandle_ {
+    ClientData clientData;	/* Client data is the load handle in the
+				 * native filesystem if a module was loaded
+				 * there, or an opaque pointer to a structure
+				 * for further bookkeeping on load-from-VFS
+				 * and load-from-memory */
+    TclFindSymbolProc* findSymbolProcPtr;
+				/* Procedure that resolves symbols in a
+				 * loaded module */
+    Tcl_FSUnloadFileProc* unloadFileProcPtr;
+				/* Procedure that unloads a loaded module */
+};
+
+/* Flags for conversion of doubles to digit strings */
+
+#define TCL_DD_SHORTEST 		0x4
+				/* Use the shortest possible string */
+#define TCL_DD_STEELE   		0x5
+				/* Use the original Steele&White algorithm */
+#define TCL_DD_E_FORMAT 		0x2
+				/* Use a fixed-length string of digits,
+				 * suitable for E format*/
+#define TCL_DD_F_FORMAT 		0x3
+				/* Use a fixed number of digits after the
+				 * decimal point, suitable for F format */
+
+#define TCL_DD_SHORTEN_FLAG 		0x4
+				/* Allow return of a shorter digit string
+				 * if it converts losslessly */
+#define TCL_DD_NO_QUICK 		0x8
+				/* Debug flag: forbid quick FP conversion */
+
+#define TCL_DD_CONVERSION_TYPE_MASK	0x3
+				/* Mask to isolate the conversion type */
+#define TCL_DD_STEELE0 			0x1
+				/* 'Steele&White' after masking */
+#define TCL_DD_SHORTEST0		0x0
+				/* 'Shortest possible' after masking */
+
+/*
+ *----------------------------------------------------------------
+ * Procedures shared among Tcl modules but not used by the outside world:
+ *----------------------------------------------------------------
+ */
+
+MODULE_SCOPE void	TclAppendBytesToByteArray(Tcl_Obj *objPtr,
+			    const unsigned char *bytes, int len);
+MODULE_SCOPE int	TclNREvalCmd(Tcl_Interp *interp, Tcl_Obj *objPtr,
+			    int flags);
+MODULE_SCOPE void	TclAdvanceContinuations(int *line, int **next,
+			    int loc);
+MODULE_SCOPE void	TclAdvanceLines(int *line, const char *start,
+			    const char *end);
+MODULE_SCOPE void	TclArgumentEnter(Tcl_Interp *interp,
+			    Tcl_Obj *objv[], int objc, CmdFrame *cf);
+MODULE_SCOPE void	TclArgumentRelease(Tcl_Interp *interp,
+			    Tcl_Obj *objv[], int objc);
+MODULE_SCOPE void	TclArgumentBCEnter(Tcl_Interp *interp,
+			    Tcl_Obj *objv[], int objc,
+			    void *codePtr, CmdFrame *cfPtr, int cmd, int pc);
+MODULE_SCOPE void	TclArgumentBCRelease(Tcl_Interp *interp,
+			    CmdFrame *cfPtr);
+MODULE_SCOPE void	TclArgumentGet(Tcl_Interp *interp, Tcl_Obj *obj,
+			    CmdFrame **cfPtrPtr, int *wordPtr);
+MODULE_SCOPE int	TclArraySet(Tcl_Interp *interp,
+			    Tcl_Obj *arrayNameObj, Tcl_Obj *arrayElemObj);
+MODULE_SCOPE double	TclBignumToDouble(const mp_int *bignum);
+MODULE_SCOPE int	TclByteArrayMatch(const unsigned char *string,
+			    int strLen, const unsigned char *pattern,
+			    int ptnLen, int flags);
+MODULE_SCOPE double	TclCeil(const mp_int *a);
+MODULE_SCOPE void	TclChannelPreserve(Tcl_Channel chan);
+MODULE_SCOPE void	TclChannelRelease(Tcl_Channel chan);
+MODULE_SCOPE int	TclCheckBadOctal(Tcl_Interp *interp,
+			    const char *value);
+MODULE_SCOPE int	TclChanCaughtErrorBypass(Tcl_Interp *interp,
+			    Tcl_Channel chan);
+MODULE_SCOPE Tcl_ObjCmdProc TclChannelNamesCmd;
+MODULE_SCOPE Tcl_NRPostProc TclClearRootEnsemble;
+MODULE_SCOPE ContLineLoc *TclContinuationsEnter(Tcl_Obj *objPtr, int num,
+			    int *loc);
+MODULE_SCOPE void	TclContinuationsEnterDerived(Tcl_Obj *objPtr,
+			    int start, int *clNext);
+MODULE_SCOPE ContLineLoc *TclContinuationsGet(Tcl_Obj *objPtr);
+MODULE_SCOPE void	TclContinuationsCopy(Tcl_Obj *objPtr,
+			    Tcl_Obj *originObjPtr);
+MODULE_SCOPE int	TclConvertElement(const char *src, int length,
+			    char *dst, int flags);
+MODULE_SCOPE void	TclDeleteNamespaceVars(Namespace *nsPtr);
+MODULE_SCOPE int	TclFindDictElement(Tcl_Interp *interp,
+			    const char *dict, int dictLength,
+			    const char **elementPtr, const char **nextPtr,
+			    int *sizePtr, int *literalPtr);
+/* TIP #280 - Modified token based evulation, with line information. */
+MODULE_SCOPE int	TclEvalEx(Tcl_Interp *interp, const char *script,
+			    int numBytes, int flags, int line,
+			    int *clNextOuter, const char *outerScript);
+MODULE_SCOPE Tcl_ObjCmdProc TclFileAttrsCmd;
+MODULE_SCOPE Tcl_ObjCmdProc TclFileCopyCmd;
+MODULE_SCOPE Tcl_ObjCmdProc TclFileDeleteCmd;
+MODULE_SCOPE Tcl_ObjCmdProc TclFileLinkCmd;
+MODULE_SCOPE Tcl_ObjCmdProc TclFileMakeDirsCmd;
+MODULE_SCOPE Tcl_ObjCmdProc TclFileReadLinkCmd;
+MODULE_SCOPE Tcl_ObjCmdProc TclFileRenameCmd;
+MODULE_SCOPE Tcl_ObjCmdProc TclFileTemporaryCmd;
+MODULE_SCOPE void	TclCreateLateExitHandler(Tcl_ExitProc *proc,
+			    ClientData clientData);
+MODULE_SCOPE void	TclDeleteLateExitHandler(Tcl_ExitProc *proc,
+			    ClientData clientData);
+MODULE_SCOPE char *	TclDStringAppendObj(Tcl_DString *dsPtr,
+			    Tcl_Obj *objPtr);
+MODULE_SCOPE char *	TclDStringAppendDString(Tcl_DString *dsPtr,
+			    Tcl_DString *toAppendPtr);
+MODULE_SCOPE Tcl_Obj *	TclDStringToObj(Tcl_DString *dsPtr);
+MODULE_SCOPE Tcl_Obj *const *	TclFetchEnsembleRoot(Tcl_Interp *interp,
+			    Tcl_Obj *const *objv, int objc, int *objcPtr);
+MODULE_SCOPE void	TclFinalizeAllocSubsystem(void);
+MODULE_SCOPE void	TclFinalizeAsync(void);
+MODULE_SCOPE void	TclFinalizeDoubleConversion(void);
+MODULE_SCOPE void	TclFinalizeEncodingSubsystem(void);
+MODULE_SCOPE void	TclFinalizeEnvironment(void);
+MODULE_SCOPE void	TclFinalizeEvaluation(void);
+MODULE_SCOPE void	TclFinalizeExecution(void);
+MODULE_SCOPE void	TclFinalizeIOSubsystem(void);
+MODULE_SCOPE void	TclFinalizeFilesystem(void);
+MODULE_SCOPE void	TclResetFilesystem(void);
+MODULE_SCOPE void	TclFinalizeLoad(void);
+MODULE_SCOPE void	TclFinalizeLock(void);
+MODULE_SCOPE void	TclFinalizeMemorySubsystem(void);
+MODULE_SCOPE void	TclFinalizeNotifier(void);
+MODULE_SCOPE void	TclFinalizeObjects(void);
+MODULE_SCOPE void	TclFinalizePreserve(void);
+MODULE_SCOPE void	TclFinalizeSynchronization(void);
+MODULE_SCOPE void	TclFinalizeThreadAlloc(void);
+MODULE_SCOPE void	TclFinalizeThreadAllocThread(void);
+MODULE_SCOPE void	TclFinalizeThreadData(int quick);
+MODULE_SCOPE void	TclFinalizeThreadObjects(void);
+MODULE_SCOPE double	TclFloor(const mp_int *a);
+MODULE_SCOPE void	TclFormatNaN(double value, char *buffer);
+MODULE_SCOPE int	TclFSFileAttrIndex(Tcl_Obj *pathPtr,
+			    const char *attributeName, int *indexPtr);
+MODULE_SCOPE int	TclNREvalFile(Tcl_Interp *interp, Tcl_Obj *pathPtr,
+			    const char *encodingName);
+MODULE_SCOPE void	TclFSUnloadTempFile(Tcl_LoadHandle loadHandle);
+MODULE_SCOPE int *	TclGetAsyncReadyPtr(void);
+MODULE_SCOPE Tcl_Obj *	TclGetBgErrorHandler(Tcl_Interp *interp);
+MODULE_SCOPE int	TclGetChannelFromObj(Tcl_Interp *interp,
+			    Tcl_Obj *objPtr, Tcl_Channel *chanPtr,
+			    int *modePtr, int flags);
+MODULE_SCOPE int TclGetCompletionCodeFromObj(Tcl_Interp *interp,
+			    Tcl_Obj *value, int *code);
+MODULE_SCOPE int	TclGetNumberFromObj(Tcl_Interp *interp,
+			    Tcl_Obj *objPtr, ClientData *clientDataPtr,
+			    int *typePtr);
+MODULE_SCOPE int	TclGetOpenModeEx(Tcl_Interp *interp,
+			    const char *modeString, int *seekFlagPtr,
+			    int *binaryPtr);
+MODULE_SCOPE Tcl_Obj *	TclGetProcessGlobalValue(ProcessGlobalValue *pgvPtr);
+MODULE_SCOPE Tcl_Obj *	TclGetSourceFromFrame(CmdFrame *cfPtr, int objc,
+			    Tcl_Obj *const objv[]);
+MODULE_SCOPE char *	TclGetStringStorage(Tcl_Obj *objPtr,
+			    unsigned int *sizePtr);
+MODULE_SCOPE int	TclGlob(Tcl_Interp *interp, char *pattern,
+			    Tcl_Obj *unquotedPrefix, int globFlags,
+			    Tcl_GlobTypeData *types);
+MODULE_SCOPE int	TclIncrObj(Tcl_Interp *interp, Tcl_Obj *valuePtr,
+			    Tcl_Obj *incrPtr);
+MODULE_SCOPE Tcl_Obj *	TclIncrObjVar2(Tcl_Interp *interp, Tcl_Obj *part1Ptr,
+			    Tcl_Obj *part2Ptr, Tcl_Obj *incrPtr, int flags);
+MODULE_SCOPE int	TclInfoExistsCmd(ClientData dummy, Tcl_Interp *interp,
+			    int objc, Tcl_Obj *const objv[]);
+MODULE_SCOPE int	TclInfoCoroutineCmd(ClientData dummy, Tcl_Interp *interp,
+			    int objc, Tcl_Obj *const objv[]);
+MODULE_SCOPE Tcl_Obj *	TclInfoFrame(Tcl_Interp *interp, CmdFrame *framePtr);
+MODULE_SCOPE int	TclInfoGlobalsCmd(ClientData dummy, Tcl_Interp *interp,
+			    int objc, Tcl_Obj *const objv[]);
+MODULE_SCOPE int	TclInfoLocalsCmd(ClientData dummy, Tcl_Interp *interp,
+			    int objc, Tcl_Obj *const objv[]);
+MODULE_SCOPE int	TclInfoVarsCmd(ClientData dummy, Tcl_Interp *interp,
+			    int objc, Tcl_Obj *const objv[]);
+MODULE_SCOPE void	TclInitAlloc(void);
+MODULE_SCOPE void	TclInitDbCkalloc(void);
+MODULE_SCOPE void	TclInitDoubleConversion(void);
+MODULE_SCOPE void	TclInitEmbeddedConfigurationInformation(
+			    Tcl_Interp *interp);
+MODULE_SCOPE void	TclInitEncodingSubsystem(void);
+MODULE_SCOPE void	TclInitIOSubsystem(void);
+MODULE_SCOPE void	TclInitLimitSupport(Tcl_Interp *interp);
+MODULE_SCOPE void	TclInitNamespaceSubsystem(void);
+MODULE_SCOPE void	TclInitNotifier(void);
+MODULE_SCOPE void	TclInitObjSubsystem(void);
+MODULE_SCOPE void	TclInitSubsystems(void);
+MODULE_SCOPE int	TclInterpReady(Tcl_Interp *interp);
+MODULE_SCOPE int	TclIsSpaceProc(char byte);
+MODULE_SCOPE int	TclIsBareword(char byte);
+MODULE_SCOPE Tcl_Obj *	TclJoinPath(int elements, Tcl_Obj * const objv[]);
+MODULE_SCOPE int	TclJoinThread(Tcl_ThreadId id, int *result);
+MODULE_SCOPE void	TclLimitRemoveAllHandlers(Tcl_Interp *interp);
+MODULE_SCOPE Tcl_Obj *	TclLindexList(Tcl_Interp *interp,
+			    Tcl_Obj *listPtr, Tcl_Obj *argPtr);
+MODULE_SCOPE Tcl_Obj *	TclLindexFlat(Tcl_Interp *interp, Tcl_Obj *listPtr,
+			    int indexCount, Tcl_Obj *const indexArray[]);
+/* TIP #280 */
+MODULE_SCOPE void	TclListLines(Tcl_Obj *listObj, int line, int n,
+			    int *lines, Tcl_Obj *const *elems);
+MODULE_SCOPE Tcl_Obj *	TclListObjCopy(Tcl_Interp *interp, Tcl_Obj *listPtr);
+MODULE_SCOPE Tcl_Obj *	TclLsetList(Tcl_Interp *interp, Tcl_Obj *listPtr,
+			    Tcl_Obj *indexPtr, Tcl_Obj *valuePtr);
+MODULE_SCOPE Tcl_Obj *	TclLsetFlat(Tcl_Interp *interp, Tcl_Obj *listPtr,
+			    int indexCount, Tcl_Obj *const indexArray[],
+			    Tcl_Obj *valuePtr);
+MODULE_SCOPE Tcl_Command TclMakeEnsemble(Tcl_Interp *interp, const char *name,
+			    const EnsembleImplMap map[]);
+MODULE_SCOPE int	TclMaxListLength(const char *bytes, int numBytes,
+			    const char **endPtr);
+MODULE_SCOPE int	TclMergeReturnOptions(Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[], Tcl_Obj **optionsPtrPtr,
+			    int *codePtr, int *levelPtr);
+MODULE_SCOPE Tcl_Obj *  TclNoErrorStack(Tcl_Interp *interp, Tcl_Obj *options);
+MODULE_SCOPE int	TclNokia770Doubles(void);
+MODULE_SCOPE void	TclNsDecrRefCount(Namespace *nsPtr);
+MODULE_SCOPE void	TclObjVarErrMsg(Tcl_Interp *interp, Tcl_Obj *part1Ptr,
+			    Tcl_Obj *part2Ptr, const char *operation,
+			    const char *reason, int index);
+MODULE_SCOPE int	TclObjInvokeNamespace(Tcl_Interp *interp,
+			    int objc, Tcl_Obj *const objv[],
+			    Tcl_Namespace *nsPtr, int flags);
+MODULE_SCOPE int	TclObjUnsetVar2(Tcl_Interp *interp,
+			    Tcl_Obj *part1Ptr, Tcl_Obj *part2Ptr, int flags);
+MODULE_SCOPE int	TclParseBackslash(const char *src,
+			    int numBytes, int *readPtr, char *dst);
+MODULE_SCOPE int	TclParseHex(const char *src, int numBytes,
+			    int *resultPtr);
+MODULE_SCOPE int	TclParseNumber(Tcl_Interp *interp, Tcl_Obj *objPtr,
+			    const char *expected, const char *bytes,
+			    int numBytes, const char **endPtrPtr, int flags);
+MODULE_SCOPE void	TclParseInit(Tcl_Interp *interp, const char *string,
+			    int numBytes, Tcl_Parse *parsePtr);
+MODULE_SCOPE int	TclParseAllWhiteSpace(const char *src, int numBytes);
+MODULE_SCOPE int	TclProcessReturn(Tcl_Interp *interp,
+			    int code, int level, Tcl_Obj *returnOpts);
+MODULE_SCOPE int	TclpObjLstat(Tcl_Obj *pathPtr, Tcl_StatBuf *buf);
+MODULE_SCOPE Tcl_Obj *	TclpTempFileName(void);
+MODULE_SCOPE Tcl_Obj *  TclpTempFileNameForLibrary(Tcl_Interp *interp, Tcl_Obj* pathPtr);
+MODULE_SCOPE Tcl_Obj *	TclNewFSPathObj(Tcl_Obj *dirPtr, const char *addStrRep,
+			    int len);
+MODULE_SCOPE int	TclpDeleteFile(const void *path);
+MODULE_SCOPE void	TclpFinalizeCondition(Tcl_Condition *condPtr);
+MODULE_SCOPE void	TclpFinalizeMutex(Tcl_Mutex *mutexPtr);
+MODULE_SCOPE void	TclpFinalizePipes(void);
+MODULE_SCOPE void	TclpFinalizeSockets(void);
+MODULE_SCOPE int	TclCreateSocketAddress(Tcl_Interp *interp,
+			    struct addrinfo **addrlist,
+			    const char *host, int port, int willBind,
+			    const char **errorMsgPtr);
+MODULE_SCOPE int	TclpThreadCreate(Tcl_ThreadId *idPtr,
+			    Tcl_ThreadCreateProc *proc, ClientData clientData,
+			    int stackSize, int flags);
+MODULE_SCOPE int	TclpFindVariable(const char *name, int *lengthPtr);
+MODULE_SCOPE void	TclpInitLibraryPath(char **valuePtr,
+			    int *lengthPtr, Tcl_Encoding *encodingPtr);
+MODULE_SCOPE void	TclpInitLock(void);
+MODULE_SCOPE void	TclpInitPlatform(void);
+MODULE_SCOPE void	TclpInitUnlock(void);
+MODULE_SCOPE Tcl_Obj *	TclpObjListVolumes(void);
+MODULE_SCOPE void	TclpMasterLock(void);
+MODULE_SCOPE void	TclpMasterUnlock(void);
+MODULE_SCOPE int	TclpMatchFiles(Tcl_Interp *interp, char *separators,
+			    Tcl_DString *dirPtr, char *pattern, char *tail);
+MODULE_SCOPE int	TclpObjNormalizePath(Tcl_Interp *interp,
+			    Tcl_Obj *pathPtr, int nextCheckpoint);
+MODULE_SCOPE void	TclpNativeJoinPath(Tcl_Obj *prefix, const char *joining);
+MODULE_SCOPE Tcl_Obj *	TclpNativeSplitPath(Tcl_Obj *pathPtr, int *lenPtr);
+MODULE_SCOPE Tcl_PathType TclpGetNativePathType(Tcl_Obj *pathPtr,
+			    int *driveNameLengthPtr, Tcl_Obj **driveNameRef);
+MODULE_SCOPE int	TclCrossFilesystemCopy(Tcl_Interp *interp,
+			    Tcl_Obj *source, Tcl_Obj *target);
+MODULE_SCOPE int	TclpMatchInDirectory(Tcl_Interp *interp,
+			    Tcl_Obj *resultPtr, Tcl_Obj *pathPtr,
+			    const char *pattern, Tcl_GlobTypeData *types);
+MODULE_SCOPE ClientData	TclpGetNativeCwd(ClientData clientData);
+MODULE_SCOPE Tcl_FSDupInternalRepProc TclNativeDupInternalRep;
+MODULE_SCOPE Tcl_Obj *	TclpObjLink(Tcl_Obj *pathPtr, Tcl_Obj *toPtr,
+			    int linkType);
+MODULE_SCOPE int	TclpObjChdir(Tcl_Obj *pathPtr);
+MODULE_SCOPE Tcl_Channel TclpOpenTemporaryFile(Tcl_Obj *dirObj,
+			    Tcl_Obj *basenameObj, Tcl_Obj *extensionObj,
+			    Tcl_Obj *resultingNameObj);
+MODULE_SCOPE Tcl_Obj *	TclPathPart(Tcl_Interp *interp, Tcl_Obj *pathPtr,
+			    Tcl_PathPart portion);
+MODULE_SCOPE char *	TclpReadlink(const char *fileName,
+			    Tcl_DString *linkPtr);
+MODULE_SCOPE void	TclpSetInterfaces(void);
+MODULE_SCOPE void	TclpSetVariables(Tcl_Interp *interp);
+MODULE_SCOPE void *	TclThreadStorageKeyGet(Tcl_ThreadDataKey *keyPtr);
+MODULE_SCOPE void	TclThreadStorageKeySet(Tcl_ThreadDataKey *keyPtr,
+			    void *data);
+MODULE_SCOPE void	TclpThreadExit(int status);
+MODULE_SCOPE void	TclRememberCondition(Tcl_Condition *mutex);
+MODULE_SCOPE void	TclRememberJoinableThread(Tcl_ThreadId id);
+MODULE_SCOPE void	TclRememberMutex(Tcl_Mutex *mutex);
+MODULE_SCOPE void	TclRemoveScriptLimitCallbacks(Tcl_Interp *interp);
+MODULE_SCOPE int	TclReToGlob(Tcl_Interp *interp, const char *reStr,
+			    int reStrLen, Tcl_DString *dsPtr, int *flagsPtr,
+			    int *quantifiersFoundPtr);
+MODULE_SCOPE int	TclScanElement(const char *string, int length,
+			    int *flagPtr);
+MODULE_SCOPE void	TclSetBgErrorHandler(Tcl_Interp *interp,
+			    Tcl_Obj *cmdPrefix);
+MODULE_SCOPE void	TclSetBignumIntRep(Tcl_Obj *objPtr,
+			    mp_int *bignumValue);
+MODULE_SCOPE int	TclSetBooleanFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr);
+MODULE_SCOPE void	TclSetCmdNameObj(Tcl_Interp *interp, Tcl_Obj *objPtr,
+			    Command *cmdPtr);
+MODULE_SCOPE void	TclSetDuplicateObj(Tcl_Obj *dupPtr, Tcl_Obj *objPtr);
+MODULE_SCOPE void	TclSetProcessGlobalValue(ProcessGlobalValue *pgvPtr,
+			    Tcl_Obj *newValue, Tcl_Encoding encoding);
+MODULE_SCOPE void	TclSignalExitThread(Tcl_ThreadId id, int result);
+MODULE_SCOPE void	TclSpellFix(Tcl_Interp *interp,
+			    Tcl_Obj *const *objv, int objc, int subIdx,
+			    Tcl_Obj *bad, Tcl_Obj *fix);
+MODULE_SCOPE void *	TclStackRealloc(Tcl_Interp *interp, void *ptr,
+			    int numBytes);
+MODULE_SCOPE int	TclStringMatch(const char *str, int strLen,
+			    const char *pattern, int ptnLen, int flags);
+MODULE_SCOPE int	TclStringMatchObj(Tcl_Obj *stringObj,
+			    Tcl_Obj *patternObj, int flags);
+MODULE_SCOPE Tcl_Obj *	TclStringObjReverse(Tcl_Obj *objPtr);
+MODULE_SCOPE void	TclSubstCompile(Tcl_Interp *interp, const char *bytes,
+			    int numBytes, int flags, int line,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclSubstOptions(Tcl_Interp *interp, int numOpts,
+			    Tcl_Obj *const opts[], int *flagPtr);
+MODULE_SCOPE void	TclSubstParse(Tcl_Interp *interp, const char *bytes,
+			    int numBytes, int flags, Tcl_Parse *parsePtr,
+			    Tcl_InterpState *statePtr);
+MODULE_SCOPE int	TclSubstTokens(Tcl_Interp *interp, Tcl_Token *tokenPtr,
+			    int count, int *tokensLeftPtr, int line,
+			    int *clNextOuter, const char *outerScript);
+MODULE_SCOPE int	TclTrimLeft(const char *bytes, int numBytes,
+			    const char *trim, int numTrim);
+MODULE_SCOPE int	TclTrimRight(const char *bytes, int numBytes,
+			    const char *trim, int numTrim);
+MODULE_SCOPE int	TclUtfCasecmp(const char *cs, const char *ct);
+MODULE_SCOPE Tcl_Obj *	TclpNativeToNormalized(ClientData clientData);
+MODULE_SCOPE Tcl_Obj *	TclpFilesystemPathType(Tcl_Obj *pathPtr);
+MODULE_SCOPE int	TclpDlopen(Tcl_Interp *interp, Tcl_Obj *pathPtr,
+			    Tcl_LoadHandle *loadHandle,
+			    Tcl_FSUnloadFileProc **unloadProcPtr, int flags);
+MODULE_SCOPE int	TclpUtime(Tcl_Obj *pathPtr, struct utimbuf *tval);
+#ifdef TCL_LOAD_FROM_MEMORY
+MODULE_SCOPE void *	TclpLoadMemoryGetBuffer(Tcl_Interp *interp, int size);
+MODULE_SCOPE int	TclpLoadMemory(Tcl_Interp *interp, void *buffer,
+			    int size, int codeSize, Tcl_LoadHandle *loadHandle,
+			    Tcl_FSUnloadFileProc **unloadProcPtr, int flags);
+#endif
+MODULE_SCOPE void	TclInitThreadStorage(void);
+MODULE_SCOPE void	TclFinalizeThreadDataThread(void);
+MODULE_SCOPE void	TclFinalizeThreadStorage(void);
+#ifdef TCL_WIDE_CLICKS
+MODULE_SCOPE Tcl_WideInt TclpGetWideClicks(void);
+MODULE_SCOPE double	TclpWideClicksToNanoseconds(Tcl_WideInt clicks);
+#endif
+MODULE_SCOPE int	TclZlibInit(Tcl_Interp *interp);
+MODULE_SCOPE void *	TclpThreadCreateKey(void);
+MODULE_SCOPE void	TclpThreadDeleteKey(void *keyPtr);
+MODULE_SCOPE void	TclpThreadSetMasterTSD(void *tsdKeyPtr, void *ptr);
+MODULE_SCOPE void *	TclpThreadGetMasterTSD(void *tsdKeyPtr);
+
+MODULE_SCOPE void	TclErrorStackResetIf(Tcl_Interp *interp, const char *msg, int length);
+
+/*
+ *----------------------------------------------------------------
+ * Command procedures in the generic core:
+ *----------------------------------------------------------------
+ */
+
+MODULE_SCOPE int	Tcl_AfterObjCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+MODULE_SCOPE int	Tcl_AppendObjCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+MODULE_SCOPE int	Tcl_ApplyObjCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+MODULE_SCOPE Tcl_Command TclInitArrayCmd(Tcl_Interp *interp);
+MODULE_SCOPE Tcl_Command TclInitBinaryCmd(Tcl_Interp *interp);
+MODULE_SCOPE int	Tcl_BreakObjCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+MODULE_SCOPE int	Tcl_CaseObjCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+MODULE_SCOPE int	Tcl_CatchObjCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+MODULE_SCOPE int	Tcl_CdObjCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+MODULE_SCOPE Tcl_Command TclInitChanCmd(Tcl_Interp *interp);
+MODULE_SCOPE int	TclChanCreateObjCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+MODULE_SCOPE int	TclChanPostEventObjCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+MODULE_SCOPE int	TclChanPopObjCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]);
+MODULE_SCOPE int	TclChanPushObjCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]);
+MODULE_SCOPE void	TclClockInit(Tcl_Interp *interp);
+MODULE_SCOPE int	TclClockOldscanObjCmd(
+			    ClientData clientData, Tcl_Interp *interp,
+			    int objc, Tcl_Obj *const objv[]);
+MODULE_SCOPE int	Tcl_CloseObjCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+MODULE_SCOPE int	Tcl_ConcatObjCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+MODULE_SCOPE int	Tcl_ContinueObjCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+MODULE_SCOPE Tcl_TimerToken TclCreateAbsoluteTimerHandler(
+			    Tcl_Time *timePtr, Tcl_TimerProc *proc,
+			    ClientData clientData);
+MODULE_SCOPE int	TclDefaultBgErrorHandlerObjCmd(
+			    ClientData clientData, Tcl_Interp *interp,
+			    int objc, Tcl_Obj *const objv[]);
+MODULE_SCOPE Tcl_Command TclInitDictCmd(Tcl_Interp *interp);
+MODULE_SCOPE int	TclDictWithFinish(Tcl_Interp *interp, Var *varPtr,
+			    Var *arrayPtr, Tcl_Obj *part1Ptr,
+			    Tcl_Obj *part2Ptr, int index, int pathc,
+			    Tcl_Obj *const pathv[], Tcl_Obj *keysPtr);
+MODULE_SCOPE Tcl_Obj *	TclDictWithInit(Tcl_Interp *interp, Tcl_Obj *dictPtr,
+			    int pathc, Tcl_Obj *const pathv[]);
+MODULE_SCOPE int	Tcl_DisassembleObjCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+
+/* Assemble command function */
+MODULE_SCOPE int	Tcl_AssembleObjCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+MODULE_SCOPE int	TclNRAssembleObjCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+
+MODULE_SCOPE int	Tcl_EncodingObjCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+MODULE_SCOPE int	Tcl_EofObjCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+MODULE_SCOPE int	Tcl_ErrorObjCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+MODULE_SCOPE int	Tcl_EvalObjCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+MODULE_SCOPE int	Tcl_ExecObjCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+MODULE_SCOPE int	Tcl_ExitObjCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+MODULE_SCOPE int	Tcl_ExprObjCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+MODULE_SCOPE int	Tcl_FblockedObjCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+MODULE_SCOPE int	Tcl_FconfigureObjCmd(
+			    ClientData clientData, Tcl_Interp *interp,
+			    int objc, Tcl_Obj *const objv[]);
+MODULE_SCOPE int	Tcl_FcopyObjCmd(ClientData dummy,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+MODULE_SCOPE Tcl_Command TclInitFileCmd(Tcl_Interp *interp);
+MODULE_SCOPE int	TclMakeFileCommandSafe(Tcl_Interp *interp);
+MODULE_SCOPE int	Tcl_FileEventObjCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+MODULE_SCOPE int	Tcl_FlushObjCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+MODULE_SCOPE int	Tcl_ForObjCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+MODULE_SCOPE int	Tcl_ForeachObjCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+MODULE_SCOPE int	Tcl_FormatObjCmd(ClientData dummy,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+MODULE_SCOPE int	Tcl_GetsObjCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+MODULE_SCOPE int	Tcl_GlobalObjCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+MODULE_SCOPE int	Tcl_GlobObjCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+MODULE_SCOPE int	Tcl_IfObjCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+MODULE_SCOPE int	Tcl_IncrObjCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+MODULE_SCOPE Tcl_Command TclInitInfoCmd(Tcl_Interp *interp);
+MODULE_SCOPE int	Tcl_InterpObjCmd(ClientData clientData,
+			    Tcl_Interp *interp, int argc,
+			    Tcl_Obj *const objv[]);
+MODULE_SCOPE int	Tcl_JoinObjCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+MODULE_SCOPE int	Tcl_LappendObjCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+MODULE_SCOPE int	Tcl_LassignObjCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+MODULE_SCOPE int	Tcl_LindexObjCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+MODULE_SCOPE int	Tcl_LinsertObjCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+MODULE_SCOPE int	Tcl_LlengthObjCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+MODULE_SCOPE int	Tcl_ListObjCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+MODULE_SCOPE int	Tcl_LmapObjCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+MODULE_SCOPE int	Tcl_LoadObjCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+MODULE_SCOPE int	Tcl_LrangeObjCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+MODULE_SCOPE int	Tcl_LrepeatObjCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+MODULE_SCOPE int	Tcl_LreplaceObjCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+MODULE_SCOPE int	Tcl_LreverseObjCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+MODULE_SCOPE int	Tcl_LsearchObjCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+MODULE_SCOPE int	Tcl_LsetObjCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+MODULE_SCOPE int	Tcl_LsortObjCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+MODULE_SCOPE Tcl_Command TclInitNamespaceCmd(Tcl_Interp *interp);
+MODULE_SCOPE int	TclNamespaceEnsembleCmd(ClientData dummy,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+MODULE_SCOPE int	Tcl_OpenObjCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+MODULE_SCOPE int	Tcl_PackageObjCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+MODULE_SCOPE int	Tcl_PidObjCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+MODULE_SCOPE Tcl_Command TclInitPrefixCmd(Tcl_Interp *interp);
+MODULE_SCOPE int	Tcl_PutsObjCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+MODULE_SCOPE int	Tcl_PwdObjCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+MODULE_SCOPE int	Tcl_ReadObjCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+MODULE_SCOPE int	Tcl_RegexpObjCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+MODULE_SCOPE int	Tcl_RegsubObjCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+MODULE_SCOPE int	Tcl_RenameObjCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+MODULE_SCOPE int	Tcl_RepresentationCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+MODULE_SCOPE int	Tcl_ReturnObjCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+MODULE_SCOPE int	Tcl_ScanObjCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+MODULE_SCOPE int	Tcl_SeekObjCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+MODULE_SCOPE int	Tcl_SetObjCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+MODULE_SCOPE int	Tcl_SplitObjCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+MODULE_SCOPE int	Tcl_SocketObjCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+MODULE_SCOPE int	Tcl_SourceObjCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+MODULE_SCOPE Tcl_Command TclInitStringCmd(Tcl_Interp *interp);
+MODULE_SCOPE int	Tcl_SubstObjCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+MODULE_SCOPE int	Tcl_SwitchObjCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+MODULE_SCOPE int	Tcl_TellObjCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+MODULE_SCOPE int	Tcl_ThrowObjCmd(ClientData dummy, Tcl_Interp *interp,
+			    int objc, Tcl_Obj *const objv[]);
+MODULE_SCOPE int	Tcl_TimeObjCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+MODULE_SCOPE int	Tcl_TraceObjCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+MODULE_SCOPE int	Tcl_TryObjCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+MODULE_SCOPE int	Tcl_UnloadObjCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+MODULE_SCOPE int	Tcl_UnsetObjCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+MODULE_SCOPE int	Tcl_UpdateObjCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+MODULE_SCOPE int	Tcl_UplevelObjCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+MODULE_SCOPE int	Tcl_UpvarObjCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+MODULE_SCOPE int	Tcl_VariableObjCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+MODULE_SCOPE int	Tcl_VwaitObjCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+MODULE_SCOPE int	Tcl_WhileObjCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+
+/*
+ *----------------------------------------------------------------
+ * Compilation procedures for commands in the generic core:
+ *----------------------------------------------------------------
+ */
+
+MODULE_SCOPE int	TclCompileAppendCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclCompileArrayExistsCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclCompileArraySetCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclCompileArrayUnsetCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclCompileBreakCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclCompileCatchCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclCompileConcatCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclCompileContinueCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclCompileDictAppendCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclCompileDictCreateCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclCompileDictExistsCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclCompileDictForCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclCompileDictGetCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclCompileDictIncrCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclCompileDictLappendCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclCompileDictMapCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclCompileDictMergeCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclCompileDictSetCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclCompileDictUnsetCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclCompileDictUpdateCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclCompileDictWithCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclCompileEnsemble(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclCompileErrorCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclCompileExprCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclCompileForCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclCompileForeachCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclCompileFormatCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclCompileGlobalCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclCompileIfCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclCompileInfoCommandsCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclCompileInfoCoroutineCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclCompileInfoExistsCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclCompileInfoLevelCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclCompileInfoObjectClassCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclCompileInfoObjectIsACmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclCompileInfoObjectNamespaceCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclCompileIncrCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclCompileLappendCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclCompileLassignCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclCompileLindexCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclCompileLinsertCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclCompileListCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclCompileLlengthCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclCompileLmapCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclCompileLrangeCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclCompileLreplaceCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclCompileLsetCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclCompileNamespaceCodeCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclCompileNamespaceCurrentCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclCompileNamespaceOriginCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclCompileNamespaceQualifiersCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclCompileNamespaceTailCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclCompileNamespaceUpvarCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclCompileNamespaceWhichCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclCompileNoOp(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclCompileObjectNextCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclCompileObjectNextToCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclCompileObjectSelfCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclCompileRegexpCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclCompileRegsubCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclCompileReturnCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclCompileSetCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclCompileStringCatCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclCompileStringCmpCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclCompileStringEqualCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclCompileStringFirstCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclCompileStringIndexCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclCompileStringIsCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclCompileStringLastCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclCompileStringLenCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclCompileStringMapCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclCompileStringMatchCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclCompileStringRangeCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclCompileStringReplaceCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclCompileStringToLowerCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclCompileStringToTitleCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclCompileStringToUpperCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclCompileStringTrimCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclCompileStringTrimLCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclCompileStringTrimRCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclCompileSubstCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclCompileSwitchCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclCompileTailcallCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclCompileThrowCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclCompileTryCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclCompileUnsetCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclCompileUpvarCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclCompileVariableCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclCompileWhileCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclCompileYieldCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclCompileYieldToCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclCompileBasic0ArgCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclCompileBasic1ArgCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclCompileBasic2ArgCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclCompileBasic3ArgCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclCompileBasic0Or1ArgCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclCompileBasic1Or2ArgCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclCompileBasic2Or3ArgCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclCompileBasic0To2ArgCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclCompileBasic1To3ArgCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclCompileBasicMin0ArgCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclCompileBasicMin1ArgCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclCompileBasicMin2ArgCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+
+MODULE_SCOPE int	TclInvertOpCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+MODULE_SCOPE int	TclCompileInvertOpCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclNotOpCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+MODULE_SCOPE int	TclCompileNotOpCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclAddOpCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+MODULE_SCOPE int	TclCompileAddOpCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclMulOpCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+MODULE_SCOPE int	TclCompileMulOpCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclAndOpCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+MODULE_SCOPE int	TclCompileAndOpCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclOrOpCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+MODULE_SCOPE int	TclCompileOrOpCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclXorOpCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+MODULE_SCOPE int	TclCompileXorOpCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclPowOpCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+MODULE_SCOPE int	TclCompilePowOpCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclLshiftOpCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+MODULE_SCOPE int	TclCompileLshiftOpCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclRshiftOpCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+MODULE_SCOPE int	TclCompileRshiftOpCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclModOpCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+MODULE_SCOPE int	TclCompileModOpCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclNeqOpCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+MODULE_SCOPE int	TclCompileNeqOpCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclStrneqOpCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+MODULE_SCOPE int	TclCompileStrneqOpCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclInOpCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+MODULE_SCOPE int	TclCompileInOpCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclNiOpCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+MODULE_SCOPE int	TclCompileNiOpCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclMinusOpCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+MODULE_SCOPE int	TclCompileMinusOpCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclDivOpCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+MODULE_SCOPE int	TclCompileDivOpCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclLessOpCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+MODULE_SCOPE int	TclCompileLessOpCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclLeqOpCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+MODULE_SCOPE int	TclCompileLeqOpCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclGreaterOpCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+MODULE_SCOPE int	TclCompileGreaterOpCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclGeqOpCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+MODULE_SCOPE int	TclCompileGeqOpCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclEqOpCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+MODULE_SCOPE int	TclCompileEqOpCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+MODULE_SCOPE int	TclStreqOpCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+MODULE_SCOPE int	TclCompileStreqOpCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+
+MODULE_SCOPE int	TclCompileAssembleCmd(Tcl_Interp *interp,
+			    Tcl_Parse *parsePtr, Command *cmdPtr,
+			    struct CompileEnv *envPtr);
+
+/*
+ * Functions defined in generic/tclVar.c and currenttly exported only for use
+ * by the bytecode compiler and engine. Some of these could later be placed in
+ * the public interface.
+ */
+
+MODULE_SCOPE Var *	TclObjLookupVarEx(Tcl_Interp * interp,
+			    Tcl_Obj *part1Ptr, Tcl_Obj *part2Ptr, int flags,
+			    const char *msg, const int createPart1,
+			    const int createPart2, Var **arrayPtrPtr);
+MODULE_SCOPE Var *	TclLookupArrayElement(Tcl_Interp *interp,
+			    Tcl_Obj *arrayNamePtr, Tcl_Obj *elNamePtr,
+			    const int flags, const char *msg,
+			    const int createPart1, const int createPart2,
+			    Var *arrayPtr, int index);
+MODULE_SCOPE Tcl_Obj *	TclPtrGetVar(Tcl_Interp *interp,
+			    Var *varPtr, Var *arrayPtr, Tcl_Obj *part1Ptr,
+			    Tcl_Obj *part2Ptr, const int flags, int index);
+MODULE_SCOPE Tcl_Obj *	TclPtrSetVar(Tcl_Interp *interp,
+			    Var *varPtr, Var *arrayPtr, Tcl_Obj *part1Ptr,
+			    Tcl_Obj *part2Ptr, Tcl_Obj *newValuePtr,
+			    const int flags, int index);
+MODULE_SCOPE Tcl_Obj *	TclPtrIncrObjVar(Tcl_Interp *interp,
+			    Var *varPtr, Var *arrayPtr, Tcl_Obj *part1Ptr,
+			    Tcl_Obj *part2Ptr, Tcl_Obj *incrPtr,
+			    const int flags, int index);
+MODULE_SCOPE int	TclPtrObjMakeUpvar(Tcl_Interp *interp, Var *otherPtr,
+			    Tcl_Obj *myNamePtr, int myFlags, int index);
+MODULE_SCOPE int	TclPtrUnsetVar(Tcl_Interp *interp, Var *varPtr,
+			    Var *arrayPtr, Tcl_Obj *part1Ptr,
+			    Tcl_Obj *part2Ptr, const int flags,
+			    int index);
+MODULE_SCOPE void	TclInvalidateNsPath(Namespace *nsPtr);
+MODULE_SCOPE void	TclFindArrayPtrElements(Var *arrayPtr,
+			    Tcl_HashTable *tablePtr);
+
+/*
+ * The new extended interface to the variable traces.
+ */
+
+MODULE_SCOPE int	TclObjCallVarTraces(Interp *iPtr, Var *arrayPtr,
+			    Var *varPtr, Tcl_Obj *part1Ptr, Tcl_Obj *part2Ptr,
+			    int flags, int leaveErrMsg, int index);
+
+/*
+ * So tclObj.c and tclDictObj.c can share these implementations.
+ */
+
+MODULE_SCOPE int	TclCompareObjKeys(void *keyPtr, Tcl_HashEntry *hPtr);
+MODULE_SCOPE void	TclFreeObjEntry(Tcl_HashEntry *hPtr);
+MODULE_SCOPE unsigned	TclHashObjKey(Tcl_HashTable *tablePtr, void *keyPtr);
+
+MODULE_SCOPE int	TclFullFinalizationRequested(void);
+
+/*
+ *----------------------------------------------------------------
+ * Macros used by the Tcl core to create and release Tcl objects.
+ * TclNewObj(objPtr) creates a new object denoting an empty string.
+ * TclDecrRefCount(objPtr) decrements the object's reference count, and frees
+ * the object if its reference count is zero. These macros are inline versions
+ * of Tcl_NewObj() and Tcl_DecrRefCount(). Notice that the names differ in not
+ * having a "_" after the "Tcl". Notice also that these macros reference their
+ * argument more than once, so you should avoid calling them with an
+ * expression that is expensive to compute or has side effects. The ANSI C
+ * "prototypes" for these macros are:
+ *
+ * MODULE_SCOPE void	TclNewObj(Tcl_Obj *objPtr);
+ * MODULE_SCOPE void	TclDecrRefCount(Tcl_Obj *objPtr);
+ *
+ * These macros are defined in terms of two macros that depend on memory
+ * allocator in use: TclAllocObjStorage, TclFreeObjStorage. They are defined
+ * below.
+ *----------------------------------------------------------------
+ */
+
+/*
+ * DTrace object allocation probe macros.
+ */
+
+#ifdef USE_DTRACE
+#ifndef _TCLDTRACE_H
+typedef const char *TclDTraceStr;
+#include "tclDTrace.h"
+#endif
+#define	TCL_DTRACE_OBJ_CREATE(objPtr)	TCL_OBJ_CREATE(objPtr)
+#define	TCL_DTRACE_OBJ_FREE(objPtr)	TCL_OBJ_FREE(objPtr)
+#else /* USE_DTRACE */
+#define	TCL_DTRACE_OBJ_CREATE(objPtr)	{}
+#define	TCL_DTRACE_OBJ_FREE(objPtr)	{}
+#endif /* USE_DTRACE */
+
+#ifdef TCL_COMPILE_STATS
+#  define TclIncrObjsAllocated() \
+    tclObjsAlloced++
+#  define TclIncrObjsFreed() \
+    tclObjsFreed++
+#else
+#  define TclIncrObjsAllocated()
+#  define TclIncrObjsFreed()
+#endif /* TCL_COMPILE_STATS */
+
+#  define TclAllocObjStorage(objPtr)		\
+	TclAllocObjStorageEx(NULL, (objPtr))
+
+#  define TclFreeObjStorage(objPtr)		\
+	TclFreeObjStorageEx(NULL, (objPtr))
+
+#ifndef TCL_MEM_DEBUG
+# define TclNewObj(objPtr) \
+    TclIncrObjsAllocated(); \
+    TclAllocObjStorage(objPtr); \
+    (objPtr)->refCount = 0; \
+    (objPtr)->bytes    = tclEmptyStringRep; \
+    (objPtr)->length   = 0; \
+    (objPtr)->typePtr  = NULL; \
+    TCL_DTRACE_OBJ_CREATE(objPtr)
+
+/*
+ * Invalidate the string rep first so we can use the bytes value for our
+ * pointer chain, and signal an obj deletion (as opposed to shimmering) with
+ * 'length == -1'.
+ * Use empty 'if ; else' to handle use in unbraced outer if/else conditions.
+ */
+
+# define TclDecrRefCount(objPtr) \
+    if ((objPtr)->refCount-- > 1) ; else { \
+	if (!(objPtr)->typePtr || !(objPtr)->typePtr->freeIntRepProc) { \
+	    TCL_DTRACE_OBJ_FREE(objPtr); \
+	    if ((objPtr)->bytes \
+		    && ((objPtr)->bytes != tclEmptyStringRep)) { \
+		ckfree((char *) (objPtr)->bytes); \
+	    } \
+	    (objPtr)->length = -1; \
+	    TclFreeObjStorage(objPtr); \
+	    TclIncrObjsFreed(); \
+	} else { \
+	    TclFreeObj(objPtr); \
+	} \
+    }
+
+#if defined(PURIFY)
+
+/*
+ * The PURIFY mode is like the regular mode, but instead of doing block
+ * Tcl_Obj allocation and keeping a freed list for efficiency, it always
+ * allocates and frees a single Tcl_Obj so that tools like Purify can better
+ * track memory leaks.
+ */
+
+#  define TclAllocObjStorageEx(interp, objPtr) \
+	(objPtr) = (Tcl_Obj *) ckalloc(sizeof(Tcl_Obj))
+
+#  define TclFreeObjStorageEx(interp, objPtr) \
+	ckfree((char *) (objPtr))
+
+#undef USE_THREAD_ALLOC
+#undef USE_TCLALLOC
+#elif defined(TCL_THREADS) && defined(USE_THREAD_ALLOC)
+
+/*
+ * The TCL_THREADS mode is like the regular mode but allocates Tcl_Obj's from
+ * per-thread caches.
+ */
+
+MODULE_SCOPE Tcl_Obj *	TclThreadAllocObj(void);
+MODULE_SCOPE void	TclThreadFreeObj(Tcl_Obj *);
+MODULE_SCOPE Tcl_Mutex *TclpNewAllocMutex(void);
+MODULE_SCOPE void	TclFreeAllocCache(void *);
+MODULE_SCOPE void *	TclpGetAllocCache(void);
+MODULE_SCOPE void	TclpSetAllocCache(void *);
+MODULE_SCOPE void	TclpFreeAllocMutex(Tcl_Mutex *mutex);
+MODULE_SCOPE void	TclpFreeAllocCache(void *);
+
+/*
+ * These macros need to be kept in sync with the code of TclThreadAllocObj()
+ * and TclThreadFreeObj().
+ *
+ * Note that the optimiser should resolve the case (interp==NULL) at compile
+ * time.
+ */
+
+#  define ALLOC_NOBJHIGH 1200
+
+#  define TclAllocObjStorageEx(interp, objPtr)				\
+    do {								\
+	AllocCache *cachePtr;						\
+	if (((interp) == NULL) ||					\
+		((cachePtr = ((Interp *)(interp))->allocCache),		\
+			(cachePtr->numObjects == 0))) {			\
+	    (objPtr) = TclThreadAllocObj();				\
+	} else {							\
+	    (objPtr) = cachePtr->firstObjPtr;				\
+	    cachePtr->firstObjPtr = (objPtr)->internalRep.twoPtrValue.ptr1; \
+	    --cachePtr->numObjects;					\
+	}								\
+    } while (0)
+
+#  define TclFreeObjStorageEx(interp, objPtr)				\
+    do {								\
+	AllocCache *cachePtr;						\
+	if (((interp) == NULL) ||					\
+		((cachePtr = ((Interp *)(interp))->allocCache),		\
+			((cachePtr->numObjects == 0) ||			\
+			(cachePtr->numObjects >= ALLOC_NOBJHIGH)))) {	\
+	    TclThreadFreeObj(objPtr);					\
+	} else {							\
+	    (objPtr)->internalRep.twoPtrValue.ptr1 = cachePtr->firstObjPtr; \
+	    cachePtr->firstObjPtr = objPtr;				\
+	    ++cachePtr->numObjects;					\
+	}								\
+    } while (0)
+
+#else /* not PURIFY or USE_THREAD_ALLOC */
+
+#if defined(USE_TCLALLOC) && USE_TCLALLOC
+    MODULE_SCOPE void TclFinalizeAllocSubsystem();
+    MODULE_SCOPE void TclInitAlloc();
+#else
+#   define USE_TCLALLOC 0
+#endif
+
+#ifdef TCL_THREADS
+/* declared in tclObj.c */
+MODULE_SCOPE Tcl_Mutex	tclObjMutex;
+#endif
+
+#  define TclAllocObjStorageEx(interp, objPtr) \
+    do {								\
+	Tcl_MutexLock(&tclObjMutex);					\
+	if (tclFreeObjList == NULL) {					\
+	    TclAllocateFreeObjects();					\
+	}								\
+	(objPtr) = tclFreeObjList;					\
+	tclFreeObjList = (Tcl_Obj *)					\
+		tclFreeObjList->internalRep.twoPtrValue.ptr1;		\
+	Tcl_MutexUnlock(&tclObjMutex);					\
+    } while (0)
+
+#  define TclFreeObjStorageEx(interp, objPtr) \
+    do {							       \
+	Tcl_MutexLock(&tclObjMutex);				       \
+	(objPtr)->internalRep.twoPtrValue.ptr1 = (void *) tclFreeObjList; \
+	tclFreeObjList = (objPtr);				       \
+	Tcl_MutexUnlock(&tclObjMutex);				       \
+    } while (0)
+#endif
+
+#else /* TCL_MEM_DEBUG */
+MODULE_SCOPE void	TclDbInitNewObj(Tcl_Obj *objPtr, const char *file,
+			    int line);
+
+# define TclDbNewObj(objPtr, file, line) \
+    do { \
+	TclIncrObjsAllocated();						\
+	(objPtr) = (Tcl_Obj *)						\
+		Tcl_DbCkalloc(sizeof(Tcl_Obj), (file), (line));		\
+	TclDbInitNewObj((objPtr), (file), (line));			\
+	TCL_DTRACE_OBJ_CREATE(objPtr);					\
+    } while (0)
+
+# define TclNewObj(objPtr) \
+    TclDbNewObj(objPtr, __FILE__, __LINE__);
+
+# define TclDecrRefCount(objPtr) \
+    Tcl_DbDecrRefCount(objPtr, __FILE__, __LINE__)
+
+# define TclNewListObjDirect(objc, objv) \
+    TclDbNewListObjDirect(objc, objv, __FILE__, __LINE__)
+
+#undef USE_THREAD_ALLOC
+#endif /* TCL_MEM_DEBUG */
+
+/*
+ *----------------------------------------------------------------
+ * Macro used by the Tcl core to set a Tcl_Obj's string representation to a
+ * copy of the "len" bytes starting at "bytePtr". This code works even if the
+ * byte array contains NULLs as long as the length is correct. Because "len"
+ * is referenced multiple times, it should be as simple an expression as
+ * possible. The ANSI C "prototype" for this macro is:
+ *
+ * MODULE_SCOPE void TclInitStringRep(Tcl_Obj *objPtr, char *bytePtr, int len);
+ *
+ * This macro should only be called on an unshared objPtr where
+ *  objPtr->typePtr->freeIntRepProc == NULL
+ *----------------------------------------------------------------
+ */
+
+#define TclInitStringRep(objPtr, bytePtr, len) \
+    if ((len) == 0) { \
+	(objPtr)->bytes	 = tclEmptyStringRep; \
+	(objPtr)->length = 0; \
+    } else { \
+	(objPtr)->bytes = (char *) ckalloc((unsigned) ((len) + 1)); \
+	memcpy((objPtr)->bytes, (bytePtr), (unsigned) (len)); \
+	(objPtr)->bytes[len] = '\0'; \
+	(objPtr)->length = (len); \
+    }
+
+/*
+ *----------------------------------------------------------------
+ * Macro used by the Tcl core to get the string representation's byte array
+ * pointer from a Tcl_Obj. This is an inline version of Tcl_GetString(). The
+ * macro's expression result is the string rep's byte pointer which might be
+ * NULL. The bytes referenced by this pointer must not be modified by the
+ * caller. The ANSI C "prototype" for this macro is:
+ *
+ * MODULE_SCOPE char *	TclGetString(Tcl_Obj *objPtr);
+ *----------------------------------------------------------------
+ */
+
+#define TclGetString(objPtr) \
+    ((objPtr)->bytes? (objPtr)->bytes : Tcl_GetString((objPtr)))
+
+#define TclGetStringFromObj(objPtr, lenPtr) \
+    ((objPtr)->bytes \
+	    ? (*(lenPtr) = (objPtr)->length, (objPtr)->bytes)	\
+	    : Tcl_GetStringFromObj((objPtr), (lenPtr)))
+
+/*
+ *----------------------------------------------------------------
+ * Macro used by the Tcl core to clean out an object's internal
+ * representation. Does not actually reset the rep's bytes. The ANSI C
+ * "prototype" for this macro is:
+ *
+ * MODULE_SCOPE void	TclFreeIntRep(Tcl_Obj *objPtr);
+ *----------------------------------------------------------------
+ */
+
+#define TclFreeIntRep(objPtr) \
+    if ((objPtr)->typePtr != NULL) { \
+	if ((objPtr)->typePtr->freeIntRepProc != NULL) { \
+	    (objPtr)->typePtr->freeIntRepProc(objPtr); \
+	} \
+	(objPtr)->typePtr = NULL; \
+    }
+
+/*
+ *----------------------------------------------------------------
+ * Macro used by the Tcl core to clean out an object's string representation.
+ * The ANSI C "prototype" for this macro is:
+ *
+ * MODULE_SCOPE void	TclInvalidateStringRep(Tcl_Obj *objPtr);
+ *----------------------------------------------------------------
+ */
+
+#define TclInvalidateStringRep(objPtr) \
+    if (objPtr->bytes != NULL) { \
+	if (objPtr->bytes != tclEmptyStringRep) { \
+	    ckfree((char *) objPtr->bytes); \
+	} \
+	objPtr->bytes = NULL; \
+    }
+
+/*
+ *----------------------------------------------------------------
+ * Macros used by the Tcl core to grow Tcl_Token arrays. They use the same
+ * growth algorithm as used in tclStringObj.c for growing strings. The ANSI C
+ * "prototype" for this macro is:
+ *
+ * MODULE_SCOPE void	TclGrowTokenArray(Tcl_Token *tokenPtr, int used,
+ *				int available, int append,
+ *				Tcl_Token *staticPtr);
+ * MODULE_SCOPE void	TclGrowParseTokenArray(Tcl_Parse *parsePtr,
+ *				int append);
+ *----------------------------------------------------------------
+ */
+
+/* General tuning for minimum growth in Tcl growth algorithms */
+#ifndef TCL_MIN_GROWTH
+#  ifdef TCL_GROWTH_MIN_ALLOC
+     /* Support for any legacy tuners */
+#    define TCL_MIN_GROWTH TCL_GROWTH_MIN_ALLOC
+#  else
+#    define TCL_MIN_GROWTH 1024
+#  endif
+#endif
+
+/* Token growth tuning, default to the general value. */
+#ifndef TCL_MIN_TOKEN_GROWTH
+#define TCL_MIN_TOKEN_GROWTH TCL_MIN_GROWTH/sizeof(Tcl_Token)
+#endif
+
+#define TCL_MAX_TOKENS (int)(UINT_MAX / sizeof(Tcl_Token))
+#define TclGrowTokenArray(tokenPtr, used, available, append, staticPtr)	\
+    do {								\
+	int needed = (used) + (append);					\
+	if (needed > TCL_MAX_TOKENS) {					\
+	    Tcl_Panic("max # of tokens for a Tcl parse (%d) exceeded",	\
+		    TCL_MAX_TOKENS);					\
+	}								\
+	if (needed > (available)) {					\
+	    int allocated = 2 * needed;					\
+	    Tcl_Token *oldPtr = (tokenPtr);				\
+	    Tcl_Token *newPtr;						\
+	    if (oldPtr == (staticPtr)) {				\
+		oldPtr = NULL;						\
+	    }								\
+	    if (allocated > TCL_MAX_TOKENS) {				\
+		allocated = TCL_MAX_TOKENS;				\
+	    }								\
+	    newPtr = (Tcl_Token *) attemptckrealloc((char *) oldPtr,	\
+		    (unsigned int) (allocated * sizeof(Tcl_Token)));	\
+	    if (newPtr == NULL) {					\
+		allocated = needed + (append) + TCL_MIN_TOKEN_GROWTH;	\
+		if (allocated > TCL_MAX_TOKENS) {			\
+		    allocated = TCL_MAX_TOKENS;				\
+		}							\
+		newPtr = (Tcl_Token *) ckrealloc((char *) oldPtr,	\
+			(unsigned int) (allocated * sizeof(Tcl_Token))); \
+	    }								\
+	    (available) = allocated;					\
+	    if (oldPtr == NULL) {					\
+		memcpy(newPtr, staticPtr,				\
+			(size_t) ((used) * sizeof(Tcl_Token)));		\
+	    }								\
+	    (tokenPtr) = newPtr;					\
+	}								\
+    } while (0)
+
+#define TclGrowParseTokenArray(parsePtr, append)			\
+    TclGrowTokenArray((parsePtr)->tokenPtr, (parsePtr)->numTokens,	\
+	    (parsePtr)->tokensAvailable, (append),			\
+	    (parsePtr)->staticTokens)
+
+/*
+ *----------------------------------------------------------------
+ * Macro used by the Tcl core get a unicode char from a utf string. It checks
+ * to see if we have a one-byte utf char before calling the real
+ * Tcl_UtfToUniChar, as this will save a lot of time for primarily ASCII
+ * string handling. The macro's expression result is 1 for the 1-byte case or
+ * the result of Tcl_UtfToUniChar. The ANSI C "prototype" for this macro is:
+ *
+ * MODULE_SCOPE int	TclUtfToUniChar(const char *string, Tcl_UniChar *ch);
+ *----------------------------------------------------------------
+ */
+
+#define TclUtfToUniChar(str, chPtr) \
+	((((unsigned char) *(str)) < 0xC0) ?		\
+	    ((*(chPtr) = (Tcl_UniChar) *(str)), 1)	\
+	    : Tcl_UtfToUniChar(str, chPtr))
+
+/*
+ *----------------------------------------------------------------
+ * Macro counterpart of the Tcl_NumUtfChars() function. To be used in speed-
+ * -sensitive points where it pays to avoid a function call in the common case
+ * of counting along a string of all one-byte characters.  The ANSI C
+ * "prototype" for this macro is:
+ *
+ * MODULE_SCOPE void	TclNumUtfChars(int numChars, const char *bytes,
+ *				int numBytes);
+ *----------------------------------------------------------------
+ */
+
+#define TclNumUtfChars(numChars, bytes, numBytes) \
+    do { \
+	int count, i = (numBytes); \
+	unsigned char *str = (unsigned char *) (bytes); \
+	while (i && (*str < 0xC0)) { i--; str++; } \
+	count = (numBytes) - i; \
+	if (i) { \
+	    count += Tcl_NumUtfChars((bytes) + count, i); \
+	} \
+	(numChars) = count; \
+    } while (0);
+
+/*
+ *----------------------------------------------------------------
+ * Macro that encapsulates the logic that determines when it is safe to
+ * interpret a string as a byte array directly. In summary, the object must be
+ * a byte array and must not have a string representation (as the operations
+ * that it is used in are defined on strings, not byte arrays). Theoretically
+ * it is possible to also be efficient in the case where the object's bytes
+ * field is filled by generation from the byte array (c.f. list canonicality)
+ * but we don't do that at the moment since this is purely about efficiency.
+ * The ANSI C "prototype" for this macro is:
+ *
+ * MODULE_SCOPE int	TclIsPureByteArray(Tcl_Obj *objPtr);
+ *----------------------------------------------------------------
+ */
+
+#define TclIsPureByteArray(objPtr) \
+	(((objPtr)->typePtr==&tclByteArrayType) && ((objPtr)->bytes==NULL))
+
+/*
+ *----------------------------------------------------------------
+ * Macro used by the Tcl core to compare Unicode strings. On big-endian
+ * systems we can use the more efficient memcmp, but this would not be
+ * lexically correct on little-endian systems. The ANSI C "prototype" for
+ * this macro is:
+ *
+ * MODULE_SCOPE int	TclUniCharNcmp(const Tcl_UniChar *cs,
+ *			    const Tcl_UniChar *ct, unsigned long n);
+ *----------------------------------------------------------------
+ */
+
+#ifdef WORDS_BIGENDIAN
+#   define TclUniCharNcmp(cs,ct,n) memcmp((cs),(ct),(n)*sizeof(Tcl_UniChar))
+#else /* !WORDS_BIGENDIAN */
+#   define TclUniCharNcmp Tcl_UniCharNcmp
+#endif /* WORDS_BIGENDIAN */
+
+/*
+ *----------------------------------------------------------------
+ * Macro used by the Tcl core to increment a namespace's export export epoch
+ * counter. The ANSI C "prototype" for this macro is:
+ *
+ * MODULE_SCOPE void	TclInvalidateNsCmdLookup(Namespace *nsPtr);
+ *----------------------------------------------------------------
+ */
+
+#define TclInvalidateNsCmdLookup(nsPtr) \
+    if ((nsPtr)->numExportPatterns) {		\
+	(nsPtr)->exportLookupEpoch++;		\
+    }						\
+    if ((nsPtr)->commandPathLength) {		\
+	(nsPtr)->cmdRefEpoch++;			\
+    }
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Core procedure added to libtommath for bignum manipulation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+MODULE_SCOPE Tcl_PackageInitProc TclTommath_Init;
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * External (platform specific) initialization routine, these declarations
+ * explicitly don't use EXTERN since this code does not get compiled into the
+ * library:
+ *
+ *----------------------------------------------------------------------
+ */
+
+MODULE_SCOPE Tcl_PackageInitProc TclplatformtestInit;
+MODULE_SCOPE Tcl_PackageInitProc TclObjTest_Init;
+MODULE_SCOPE Tcl_PackageInitProc TclThread_Init;
+MODULE_SCOPE Tcl_PackageInitProc Procbodytest_Init;
+MODULE_SCOPE Tcl_PackageInitProc Procbodytest_SafeInit;
+
+/*
+ *----------------------------------------------------------------
+ * Macro used by the Tcl core to check whether a pattern has any characters
+ * special to [string match]. The ANSI C "prototype" for this macro is:
+ *
+ * MODULE_SCOPE int	TclMatchIsTrivial(const char *pattern);
+ *----------------------------------------------------------------
+ */
+
+#define TclMatchIsTrivial(pattern) \
+    (strpbrk((pattern), "*[?\\") == NULL)
+
+/*
+ *----------------------------------------------------------------
+ * Macros used by the Tcl core to set a Tcl_Obj's numeric representation
+ * avoiding the corresponding function calls in time critical parts of the
+ * core. They should only be called on unshared objects. The ANSI C
+ * "prototypes" for these macros are:
+ *
+ * MODULE_SCOPE void	TclSetIntObj(Tcl_Obj *objPtr, int intValue);
+ * MODULE_SCOPE void	TclSetLongObj(Tcl_Obj *objPtr, long longValue);
+ * MODULE_SCOPE void	TclSetBooleanObj(Tcl_Obj *objPtr, long boolValue);
+ * MODULE_SCOPE void	TclSetWideIntObj(Tcl_Obj *objPtr, Tcl_WideInt w);
+ * MODULE_SCOPE void	TclSetDoubleObj(Tcl_Obj *objPtr, double d);
+ *----------------------------------------------------------------
+ */
+
+#define TclSetLongObj(objPtr, i) \
+    do {						\
+	TclInvalidateStringRep(objPtr);			\
+	TclFreeIntRep(objPtr);				\
+	(objPtr)->internalRep.longValue = (long)(i);	\
+	(objPtr)->typePtr = &tclIntType;		\
+    } while (0)
+
+#define TclSetIntObj(objPtr, l) \
+    TclSetLongObj(objPtr, l)
+
+/*
+ * NOTE: There is to be no such thing as a "pure" boolean. Boolean values set
+ * programmatically go straight to being "int" Tcl_Obj's, with value 0 or 1.
+ * The only "boolean" Tcl_Obj's shall be those holding the cached boolean
+ * value of strings like: "yes", "no", "true", "false", "on", "off".
+ */
+
+#define TclSetBooleanObj(objPtr, b) \
+    TclSetLongObj(objPtr, (b)!=0);
+
+#ifndef TCL_WIDE_INT_IS_LONG
+#define TclSetWideIntObj(objPtr, w) \
+    do {							\
+	TclInvalidateStringRep(objPtr);				\
+	TclFreeIntRep(objPtr);					\
+	(objPtr)->internalRep.wideValue = (Tcl_WideInt)(w);	\
+	(objPtr)->typePtr = &tclWideIntType;			\
+    } while (0)
+#endif
+
+#define TclSetDoubleObj(objPtr, d) \
+    do {							\
+	TclInvalidateStringRep(objPtr);				\
+	TclFreeIntRep(objPtr);					\
+	(objPtr)->internalRep.doubleValue = (double)(d);	\
+	(objPtr)->typePtr = &tclDoubleType;			\
+    } while (0)
+
+/*
+ *----------------------------------------------------------------
+ * Macros used by the Tcl core to create and initialise objects of standard
+ * types, avoiding the corresponding function calls in time critical parts of
+ * the core. The ANSI C "prototypes" for these macros are:
+ *
+ * MODULE_SCOPE void	TclNewIntObj(Tcl_Obj *objPtr, int i);
+ * MODULE_SCOPE void	TclNewLongObj(Tcl_Obj *objPtr, long l);
+ * MODULE_SCOPE void	TclNewBooleanObj(Tcl_Obj *objPtr, int b);
+ * MODULE_SCOPE void	TclNewWideObj(Tcl_Obj *objPtr, Tcl_WideInt w);
+ * MODULE_SCOPE void	TclNewDoubleObj(Tcl_Obj *objPtr, double d);
+ * MODULE_SCOPE void	TclNewStringObj(Tcl_Obj *objPtr, char *s, int len);
+ * MODULE_SCOPE void	TclNewLiteralStringObj(Tcl_Obj*objPtr, char*sLiteral);
+ *
+ *----------------------------------------------------------------
+ */
+
+#ifndef TCL_MEM_DEBUG
+#define TclNewLongObj(objPtr, i) \
+    do {						\
+	TclIncrObjsAllocated();				\
+	TclAllocObjStorage(objPtr);			\
+	(objPtr)->refCount = 0;				\
+	(objPtr)->bytes = NULL;				\
+	(objPtr)->internalRep.longValue = (long)(i);	\
+	(objPtr)->typePtr = &tclIntType;		\
+	TCL_DTRACE_OBJ_CREATE(objPtr);			\
+    } while (0)
+
+#define TclNewIntObj(objPtr, l) \
+    TclNewLongObj(objPtr, l)
+
+/*
+ * NOTE: There is to be no such thing as a "pure" boolean.
+ * See comment above TclSetBooleanObj macro above.
+ */
+#define TclNewBooleanObj(objPtr, b) \
+    TclNewLongObj((objPtr), (b)!=0)
+
+#define TclNewDoubleObj(objPtr, d) \
+    do {							\
+	TclIncrObjsAllocated();					\
+	TclAllocObjStorage(objPtr);				\
+	(objPtr)->refCount = 0;					\
+	(objPtr)->bytes = NULL;					\
+	(objPtr)->internalRep.doubleValue = (double)(d);	\
+	(objPtr)->typePtr = &tclDoubleType;			\
+	TCL_DTRACE_OBJ_CREATE(objPtr);				\
+    } while (0)
+
+#define TclNewStringObj(objPtr, s, len) \
+    do {							\
+	TclIncrObjsAllocated();					\
+	TclAllocObjStorage(objPtr);				\
+	(objPtr)->refCount = 0;					\
+	TclInitStringRep((objPtr), (s), (len));			\
+	(objPtr)->typePtr = NULL;				\
+	TCL_DTRACE_OBJ_CREATE(objPtr);				\
+    } while (0)
+
+#else /* TCL_MEM_DEBUG */
+#define TclNewIntObj(objPtr, i) \
+    (objPtr) = Tcl_NewIntObj(i)
+
+#define TclNewLongObj(objPtr, l) \
+    (objPtr) = Tcl_NewLongObj(l)
+
+#define TclNewBooleanObj(objPtr, b) \
+    (objPtr) = Tcl_NewBooleanObj(b)
+
+#define TclNewDoubleObj(objPtr, d) \
+    (objPtr) = Tcl_NewDoubleObj(d)
+
+#define TclNewStringObj(objPtr, s, len) \
+    (objPtr) = Tcl_NewStringObj((s), (len))
+#endif /* TCL_MEM_DEBUG */
+
+/*
+ * The sLiteral argument *must* be a string literal; the incantation with
+ * sizeof(sLiteral "") will fail to compile otherwise.
+ */
+#define TclNewLiteralStringObj(objPtr, sLiteral) \
+    TclNewStringObj((objPtr), (sLiteral), (int) (sizeof(sLiteral "") - 1))
+
+/*
+ *----------------------------------------------------------------
+ * Convenience macros for DStrings.
+ * The ANSI C "prototypes" for these macros are:
+ *
+ * MODULE_SCOPE char * TclDStringAppendLiteral(Tcl_DString *dsPtr,
+ *			const char *sLiteral);
+ * MODULE_SCOPE void   TclDStringClear(Tcl_DString *dsPtr);
+ */
+
+#define TclDStringAppendLiteral(dsPtr, sLiteral) \
+    Tcl_DStringAppend((dsPtr), (sLiteral), (int) (sizeof(sLiteral "") - 1))
+#define TclDStringClear(dsPtr) \
+    Tcl_DStringSetLength((dsPtr), 0)
+
+/*
+ *----------------------------------------------------------------
+ * Macros used by the Tcl core to test for some special double values.
+ * The ANSI C "prototypes" for these macros are:
+ *
+ * MODULE_SCOPE int	TclIsInfinite(double d);
+ * MODULE_SCOPE int	TclIsNaN(double d);
+ */
+
+#ifdef _MSC_VER
+#    define TclIsInfinite(d)	(!(_finite((d))))
+#    define TclIsNaN(d)		(_isnan((d)))
+#else
+#    define TclIsInfinite(d)	((d) > DBL_MAX || (d) < -DBL_MAX)
+#    ifdef NO_ISNAN
+#	 define TclIsNaN(d)	((d) != (d))
+#    else
+#	 define TclIsNaN(d)	(isnan(d))
+#    endif
+#endif
+
+/*
+ * ----------------------------------------------------------------------
+ * Macro to use to find the offset of a field in a structure. Computes number
+ * of bytes from beginning of structure to a given field.
+ */
+
+#ifdef offsetof
+#define TclOffset(type, field) ((int) offsetof(type, field))
+#else
+#define TclOffset(type, field) ((int) ((char *) &((type *) 0)->field))
+#endif
+
+/*
+ *----------------------------------------------------------------
+ * Inline version of Tcl_GetCurrentNamespace and Tcl_GetGlobalNamespace.
+ */
+
+#define TclGetCurrentNamespace(interp) \
+    (Tcl_Namespace *) ((Interp *)(interp))->varFramePtr->nsPtr
+
+#define TclGetGlobalNamespace(interp) \
+    (Tcl_Namespace *) ((Interp *)(interp))->globalNsPtr
+
+/*
+ *----------------------------------------------------------------
+ * Inline version of TclCleanupCommand; still need the function as it is in
+ * the internal stubs, but the core can use the macro instead.
+ */
+
+#define TclCleanupCommandMacro(cmdPtr) \
+    if ((cmdPtr)->refCount-- <= 1) { \
+	ckfree((char *) (cmdPtr));\
+    }
+
+/*
+ *----------------------------------------------------------------
+ * Inline versions of Tcl_LimitReady() and Tcl_LimitExceeded to limit number
+ * of calls out of the critical path. Note that this code isn't particularly
+ * readable; the non-inline version (in tclInterp.c) is much easier to
+ * understand. Note also that these macros takes different args (iPtr->limit)
+ * to the non-inline version.
+ */
+
+#define TclLimitExceeded(limit) ((limit).exceeded != 0)
+
+#define TclLimitReady(limit)						\
+    (((limit).active == 0) ? 0 :					\
+    (++(limit).granularityTicker,					\
+    ((((limit).active & TCL_LIMIT_COMMANDS) &&				\
+	    (((limit).cmdGranularity == 1) ||				\
+	    ((limit).granularityTicker % (limit).cmdGranularity == 0)))	\
+	    ? 1 :							\
+    (((limit).active & TCL_LIMIT_TIME) &&				\
+	    (((limit).timeGranularity == 1) ||				\
+	    ((limit).granularityTicker % (limit).timeGranularity == 0)))\
+	    ? 1 : 0)))
+
+/*
+ * Compile-time assertions: these produce a compile time error if the
+ * expression is not known to be true at compile time. If the assertion is
+ * known to be false, the compiler (or optimizer?) will error out with
+ * "division by zero". If the assertion cannot be evaluated at compile time,
+ * the compiler will error out with "non-static initializer".
+ *
+ * Adapted with permission from
+ * http://www.pixelbeat.org/programming/gcc/static_assert.html
+ */
+
+#define TCL_CT_ASSERT(e) \
+    {enum { ct_assert_value = 1/(!!(e)) };}
+
+/*
+ *----------------------------------------------------------------
+ * Allocator for small structs (<=sizeof(Tcl_Obj)) using the Tcl_Obj pool.
+ * Only checked at compile time.
+ *
+ * ONLY USE FOR CONSTANT nBytes.
+ *
+ * DO NOT LET THEM CROSS THREAD BOUNDARIES
+ *----------------------------------------------------------------
+ */
+
+#define TclSmallAlloc(nbytes, memPtr) \
+    TclSmallAllocEx(NULL, (nbytes), (memPtr))
+
+#define TclSmallFree(memPtr) \
+    TclSmallFreeEx(NULL, (memPtr))
+
+#ifndef TCL_MEM_DEBUG
+#define TclSmallAllocEx(interp, nbytes, memPtr) \
+    do {								\
+	Tcl_Obj *objPtr;						\
+	TCL_CT_ASSERT((nbytes)<=sizeof(Tcl_Obj));			\
+	TclIncrObjsAllocated();						\
+	TclAllocObjStorageEx((interp), (objPtr));			\
+	memPtr = (ClientData) (objPtr);					\
+    } while (0)
+
+#define TclSmallFreeEx(interp, memPtr) \
+    do {								\
+	TclFreeObjStorageEx((interp), (Tcl_Obj *) (memPtr));		\
+	TclIncrObjsFreed();						\
+    } while (0)
+
+#else    /* TCL_MEM_DEBUG */
+#define TclSmallAllocEx(interp, nbytes, memPtr) \
+    do {								\
+	Tcl_Obj *objPtr;						\
+	TCL_CT_ASSERT((nbytes)<=sizeof(Tcl_Obj));			\
+	TclNewObj(objPtr);						\
+	memPtr = (ClientData) objPtr;					\
+    } while (0)
+
+#define TclSmallFreeEx(interp, memPtr) \
+    do {								\
+	Tcl_Obj *objPtr = (Tcl_Obj *) memPtr;				\
+	objPtr->bytes = NULL;						\
+	objPtr->typePtr = NULL;						\
+	objPtr->refCount = 1;						\
+	TclDecrRefCount(objPtr);					\
+    } while (0)
+#endif   /* TCL_MEM_DEBUG */
+
+/*
+ * Support for Clang Static Analyzer <http://clang-analyzer.llvm.org>
+ */
+
+#if defined(PURIFY) && defined(__clang__)
+#if __has_feature(attribute_analyzer_noreturn) && \
+	!defined(Tcl_Panic) && defined(Tcl_Panic_TCL_DECLARED)
+void Tcl_Panic(const char *, ...) __attribute__((analyzer_noreturn));
+#endif
+#if !defined(CLANG_ASSERT)
+#include <assert.h>
+#define CLANG_ASSERT(x) assert(x)
+#endif
+#elif !defined(CLANG_ASSERT)
+#define CLANG_ASSERT(x)
+#endif /* PURIFY && __clang__ */
+
+/*
+ *----------------------------------------------------------------
+ * Parameters, structs and macros for the non-recursive engine (NRE)
+ *----------------------------------------------------------------
+ */
+
+#define NRE_USE_SMALL_ALLOC	1  /* Only turn off for debugging purposes. */
+#ifndef NRE_ENABLE_ASSERTS
+#define NRE_ENABLE_ASSERTS	0
+#endif
+
+/*
+ * This is the main data struct for representing NR commands. It is designed
+ * to fit in sizeof(Tcl_Obj) in order to exploit the fastest memory allocator
+ * available.
+ */
+
+typedef struct NRE_callback {
+    Tcl_NRPostProc *procPtr;
+    ClientData data[4];
+    struct NRE_callback *nextPtr;
+} NRE_callback;
+
+#define TOP_CB(iPtr) (((Interp *)(iPtr))->execEnvPtr->callbackPtr)
+
+/*
+ * Inline version of Tcl_NRAddCallback.
+ */
+
+#define TclNRAddCallback(interp,postProcPtr,data0,data1,data2,data3) \
+    do {								\
+	NRE_callback *callbackPtr;					\
+	TCLNR_ALLOC((interp), (callbackPtr));				\
+	callbackPtr->procPtr = (postProcPtr);				\
+	callbackPtr->data[0] = (ClientData)(data0);			\
+	callbackPtr->data[1] = (ClientData)(data1);			\
+	callbackPtr->data[2] = (ClientData)(data2);			\
+	callbackPtr->data[3] = (ClientData)(data3);			\
+	callbackPtr->nextPtr = TOP_CB(interp);				\
+	TOP_CB(interp) = callbackPtr;					\
+    } while (0)
+
+#if NRE_USE_SMALL_ALLOC
+#define TCLNR_ALLOC(interp, ptr) \
+    TclSmallAllocEx(interp, sizeof(NRE_callback), (ptr))
+#define TCLNR_FREE(interp, ptr)  TclSmallFreeEx((interp), (ptr))
+#else
+#define TCLNR_ALLOC(interp, ptr) \
+    (ptr = ((ClientData) ckalloc(sizeof(NRE_callback))))
+#define TCLNR_FREE(interp, ptr)  ckfree((char *) (ptr))
+#endif
+
+#if NRE_ENABLE_ASSERTS
+#define NRE_ASSERT(expr) assert((expr))
+#else
+#define NRE_ASSERT(expr)
+#endif
+
+#include "tclIntDecls.h"
+#include "tclIntPlatDecls.h"
+#include "tclTomMathDecls.h"
+
+#if !defined(USE_TCL_STUBS) && !defined(TCL_MEM_DEBUG)
+#define Tcl_AttemptAlloc(size)        TclpAlloc(size)
+#define Tcl_AttemptRealloc(ptr, size) TclpRealloc((ptr), (size))
+#define Tcl_Free(ptr)                 TclpFree(ptr)
+#endif
+
+#endif /* _TCLINT */
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tclIntDecls.h b/generic/tclIntDecls.h
new file mode 100644
index 0000000..f95f999
--- /dev/null
+++ b/generic/tclIntDecls.h
@@ -0,0 +1,1370 @@
+/*
+ * tclIntDecls.h --
+ *
+ *	This file contains the declarations for all unsupported
+ *	functions that are exported by the Tcl library.  These
+ *	interfaces are not guaranteed to remain the same between
+ *	versions.  Use at your own risk.
+ *
+ * Copyright (c) 1998-1999 by Scriptics Corporation.
+ *
+ * See the file "license.terms" for information on usage and redistribution
+ * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#ifndef _TCLINTDECLS
+#define _TCLINTDECLS
+
+#include "tclPort.h"
+
+#undef TCL_STORAGE_CLASS
+#ifdef BUILD_tcl
+#   define TCL_STORAGE_CLASS DLLEXPORT
+#else
+#   ifdef USE_TCL_STUBS
+#      define TCL_STORAGE_CLASS
+#   else
+#      define TCL_STORAGE_CLASS DLLIMPORT
+#   endif
+#endif
+
+/* [Bug #803489] Tcl_FindNamespace problem in the Stubs table */
+#undef Tcl_CreateNamespace
+#undef Tcl_DeleteNamespace
+#undef Tcl_AppendExportList
+#undef Tcl_Export
+#undef Tcl_Import
+#undef Tcl_ForgetImport
+#undef Tcl_GetCurrentNamespace
+#undef Tcl_GetGlobalNamespace
+#undef Tcl_FindNamespace
+#undef Tcl_FindCommand
+#undef Tcl_GetCommandFromObj
+#undef Tcl_GetCommandFullName
+#undef Tcl_SetStartupScript
+#undef Tcl_GetStartupScript
+
+/*
+ * WARNING: This file is automatically generated by the tools/genStubs.tcl
+ * script.  Any modifications to the function declarations below should be made
+ * in the generic/tclInt.decls script.
+ */
+
+/* !BEGIN!: Do not edit below this line. */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Exported function declarations:
+ */
+
+/* Slot 0 is reserved */
+/* Slot 1 is reserved */
+/* Slot 2 is reserved */
+/* 3 */
+EXTERN void		TclAllocateFreeObjects(void);
+/* Slot 4 is reserved */
+/* 5 */
+EXTERN int		TclCleanupChildren(Tcl_Interp *interp, int numPids,
+				Tcl_Pid *pidPtr, Tcl_Channel errorChan);
+/* 6 */
+EXTERN void		TclCleanupCommand(Command *cmdPtr);
+/* 7 */
+EXTERN int		TclCopyAndCollapse(int count, const char *src,
+				char *dst);
+/* 8 */
+EXTERN int		TclCopyChannelOld(Tcl_Interp *interp,
+				Tcl_Channel inChan, Tcl_Channel outChan,
+				int toRead, Tcl_Obj *cmdPtr);
+/* 9 */
+EXTERN int		TclCreatePipeline(Tcl_Interp *interp, int argc,
+				const char **argv, Tcl_Pid **pidArrayPtr,
+				TclFile *inPipePtr, TclFile *outPipePtr,
+				TclFile *errFilePtr);
+/* 10 */
+EXTERN int		TclCreateProc(Tcl_Interp *interp, Namespace *nsPtr,
+				const char *procName, Tcl_Obj *argsPtr,
+				Tcl_Obj *bodyPtr, Proc **procPtrPtr);
+/* 11 */
+EXTERN void		TclDeleteCompiledLocalVars(Interp *iPtr,
+				CallFrame *framePtr);
+/* 12 */
+EXTERN void		TclDeleteVars(Interp *iPtr,
+				TclVarHashTable *tablePtr);
+/* Slot 13 is reserved */
+/* 14 */
+EXTERN int		TclDumpMemoryInfo(ClientData clientData, int flags);
+/* Slot 15 is reserved */
+/* 16 */
+EXTERN void		TclExprFloatError(Tcl_Interp *interp, double value);
+/* Slot 17 is reserved */
+/* Slot 18 is reserved */
+/* Slot 19 is reserved */
+/* Slot 20 is reserved */
+/* Slot 21 is reserved */
+/* 22 */
+EXTERN int		TclFindElement(Tcl_Interp *interp,
+				const char *listStr, int listLength,
+				const char **elementPtr,
+				const char **nextPtr, int *sizePtr,
+				int *bracePtr);
+/* 23 */
+EXTERN Proc *		TclFindProc(Interp *iPtr, const char *procName);
+/* 24 */
+EXTERN int		TclFormatInt(char *buffer, long n);
+/* 25 */
+EXTERN void		TclFreePackageInfo(Interp *iPtr);
+/* Slot 26 is reserved */
+/* Slot 27 is reserved */
+/* 28 */
+EXTERN Tcl_Channel	TclpGetDefaultStdChannel(int type);
+/* Slot 29 is reserved */
+/* Slot 30 is reserved */
+/* 31 */
+EXTERN const char *	TclGetExtension(const char *name);
+/* 32 */
+EXTERN int		TclGetFrame(Tcl_Interp *interp, const char *str,
+				CallFrame **framePtrPtr);
+/* Slot 33 is reserved */
+/* 34 */
+EXTERN int		TclGetIntForIndex(Tcl_Interp *interp,
+				Tcl_Obj *objPtr, int endValue, int *indexPtr);
+/* Slot 35 is reserved */
+/* Slot 36 is reserved */
+/* 37 */
+EXTERN int		TclGetLoadedPackages(Tcl_Interp *interp,
+				const char *targetName);
+/* 38 */
+EXTERN int		TclGetNamespaceForQualName(Tcl_Interp *interp,
+				const char *qualName, Namespace *cxtNsPtr,
+				int flags, Namespace **nsPtrPtr,
+				Namespace **altNsPtrPtr,
+				Namespace **actualCxtPtrPtr,
+				const char **simpleNamePtr);
+/* 39 */
+EXTERN TclObjCmdProcType TclGetObjInterpProc(void);
+/* 40 */
+EXTERN int		TclGetOpenMode(Tcl_Interp *interp, const char *str,
+				int *seekFlagPtr);
+/* 41 */
+EXTERN Tcl_Command	TclGetOriginalCommand(Tcl_Command command);
+/* 42 */
+EXTERN CONST86 char *	TclpGetUserHome(const char *name,
+				Tcl_DString *bufferPtr);
+/* Slot 43 is reserved */
+/* 44 */
+EXTERN int		TclGuessPackageName(const char *fileName,
+				Tcl_DString *bufPtr);
+/* 45 */
+EXTERN int		TclHideUnsafeCommands(Tcl_Interp *interp);
+/* 46 */
+EXTERN int		TclInExit(void);
+/* Slot 47 is reserved */
+/* Slot 48 is reserved */
+/* Slot 49 is reserved */
+/* 50 */
+EXTERN void		TclInitCompiledLocals(Tcl_Interp *interp,
+				CallFrame *framePtr, Namespace *nsPtr);
+/* 51 */
+EXTERN int		TclInterpInit(Tcl_Interp *interp);
+/* Slot 52 is reserved */
+/* 53 */
+EXTERN int		TclInvokeObjectCommand(ClientData clientData,
+				Tcl_Interp *interp, int argc,
+				CONST84 char **argv);
+/* 54 */
+EXTERN int		TclInvokeStringCommand(ClientData clientData,
+				Tcl_Interp *interp, int objc,
+				Tcl_Obj *const objv[]);
+/* 55 */
+EXTERN Proc *		TclIsProc(Command *cmdPtr);
+/* Slot 56 is reserved */
+/* Slot 57 is reserved */
+/* 58 */
+EXTERN Var *		TclLookupVar(Tcl_Interp *interp, const char *part1,
+				const char *part2, int flags,
+				const char *msg, int createPart1,
+				int createPart2, Var **arrayPtrPtr);
+/* Slot 59 is reserved */
+/* 60 */
+EXTERN int		TclNeedSpace(const char *start, const char *end);
+/* 61 */
+EXTERN Tcl_Obj *	TclNewProcBodyObj(Proc *procPtr);
+/* 62 */
+EXTERN int		TclObjCommandComplete(Tcl_Obj *cmdPtr);
+/* 63 */
+EXTERN int		TclObjInterpProc(ClientData clientData,
+				Tcl_Interp *interp, int objc,
+				Tcl_Obj *const objv[]);
+/* 64 */
+EXTERN int		TclObjInvoke(Tcl_Interp *interp, int objc,
+				Tcl_Obj *const objv[], int flags);
+/* Slot 65 is reserved */
+/* Slot 66 is reserved */
+/* Slot 67 is reserved */
+/* Slot 68 is reserved */
+/* 69 */
+EXTERN char *		TclpAlloc(unsigned int size);
+/* Slot 70 is reserved */
+/* Slot 71 is reserved */
+/* Slot 72 is reserved */
+/* Slot 73 is reserved */
+/* 74 */
+EXTERN void		TclpFree(char *ptr);
+/* 75 */
+EXTERN unsigned long	TclpGetClicks(void);
+/* 76 */
+EXTERN unsigned long	TclpGetSeconds(void);
+/* 77 */
+EXTERN void		TclpGetTime(Tcl_Time *time);
+/* Slot 78 is reserved */
+/* Slot 79 is reserved */
+/* Slot 80 is reserved */
+/* 81 */
+EXTERN char *		TclpRealloc(char *ptr, unsigned int size);
+/* Slot 82 is reserved */
+/* Slot 83 is reserved */
+/* Slot 84 is reserved */
+/* Slot 85 is reserved */
+/* Slot 86 is reserved */
+/* Slot 87 is reserved */
+/* 88 */
+EXTERN char *		TclPrecTraceProc(ClientData clientData,
+				Tcl_Interp *interp, const char *name1,
+				const char *name2, int flags);
+/* 89 */
+EXTERN int		TclPreventAliasLoop(Tcl_Interp *interp,
+				Tcl_Interp *cmdInterp, Tcl_Command cmd);
+/* Slot 90 is reserved */
+/* 91 */
+EXTERN void		TclProcCleanupProc(Proc *procPtr);
+/* 92 */
+EXTERN int		TclProcCompileProc(Tcl_Interp *interp, Proc *procPtr,
+				Tcl_Obj *bodyPtr, Namespace *nsPtr,
+				const char *description,
+				const char *procName);
+/* 93 */
+EXTERN void		TclProcDeleteProc(ClientData clientData);
+/* Slot 94 is reserved */
+/* Slot 95 is reserved */
+/* 96 */
+EXTERN int		TclRenameCommand(Tcl_Interp *interp,
+				const char *oldName, const char *newName);
+/* 97 */
+EXTERN void		TclResetShadowedCmdRefs(Tcl_Interp *interp,
+				Command *newCmdPtr);
+/* 98 */
+EXTERN int		TclServiceIdle(void);
+/* Slot 99 is reserved */
+/* Slot 100 is reserved */
+/* 101 */
+EXTERN CONST86 char *	TclSetPreInitScript(const char *string);
+/* 102 */
+EXTERN void		TclSetupEnv(Tcl_Interp *interp);
+/* 103 */
+EXTERN int		TclSockGetPort(Tcl_Interp *interp, const char *str,
+				const char *proto, int *portPtr);
+/* 104 */
+EXTERN int		TclSockMinimumBuffersOld(int sock, int size);
+/* Slot 105 is reserved */
+/* Slot 106 is reserved */
+/* Slot 107 is reserved */
+/* 108 */
+EXTERN void		TclTeardownNamespace(Namespace *nsPtr);
+/* 109 */
+EXTERN int		TclUpdateReturnInfo(Interp *iPtr);
+/* 110 */
+EXTERN int		TclSockMinimumBuffers(void *sock, int size);
+/* 111 */
+EXTERN void		Tcl_AddInterpResolvers(Tcl_Interp *interp,
+				const char *name,
+				Tcl_ResolveCmdProc *cmdProc,
+				Tcl_ResolveVarProc *varProc,
+				Tcl_ResolveCompiledVarProc *compiledVarProc);
+/* 112 */
+EXTERN int		Tcl_AppendExportList(Tcl_Interp *interp,
+				Tcl_Namespace *nsPtr, Tcl_Obj *objPtr);
+/* 113 */
+EXTERN Tcl_Namespace *	Tcl_CreateNamespace(Tcl_Interp *interp,
+				const char *name, ClientData clientData,
+				Tcl_NamespaceDeleteProc *deleteProc);
+/* 114 */
+EXTERN void		Tcl_DeleteNamespace(Tcl_Namespace *nsPtr);
+/* 115 */
+EXTERN int		Tcl_Export(Tcl_Interp *interp, Tcl_Namespace *nsPtr,
+				const char *pattern, int resetListFirst);
+/* 116 */
+EXTERN Tcl_Command	Tcl_FindCommand(Tcl_Interp *interp, const char *name,
+				Tcl_Namespace *contextNsPtr, int flags);
+/* 117 */
+EXTERN Tcl_Namespace *	Tcl_FindNamespace(Tcl_Interp *interp,
+				const char *name,
+				Tcl_Namespace *contextNsPtr, int flags);
+/* 118 */
+EXTERN int		Tcl_GetInterpResolvers(Tcl_Interp *interp,
+				const char *name, Tcl_ResolverInfo *resInfo);
+/* 119 */
+EXTERN int		Tcl_GetNamespaceResolvers(
+				Tcl_Namespace *namespacePtr,
+				Tcl_ResolverInfo *resInfo);
+/* 120 */
+EXTERN Tcl_Var		Tcl_FindNamespaceVar(Tcl_Interp *interp,
+				const char *name,
+				Tcl_Namespace *contextNsPtr, int flags);
+/* 121 */
+EXTERN int		Tcl_ForgetImport(Tcl_Interp *interp,
+				Tcl_Namespace *nsPtr, const char *pattern);
+/* 122 */
+EXTERN Tcl_Command	Tcl_GetCommandFromObj(Tcl_Interp *interp,
+				Tcl_Obj *objPtr);
+/* 123 */
+EXTERN void		Tcl_GetCommandFullName(Tcl_Interp *interp,
+				Tcl_Command command, Tcl_Obj *objPtr);
+/* 124 */
+EXTERN Tcl_Namespace *	Tcl_GetCurrentNamespace(Tcl_Interp *interp);
+/* 125 */
+EXTERN Tcl_Namespace *	Tcl_GetGlobalNamespace(Tcl_Interp *interp);
+/* 126 */
+EXTERN void		Tcl_GetVariableFullName(Tcl_Interp *interp,
+				Tcl_Var variable, Tcl_Obj *objPtr);
+/* 127 */
+EXTERN int		Tcl_Import(Tcl_Interp *interp, Tcl_Namespace *nsPtr,
+				const char *pattern, int allowOverwrite);
+/* 128 */
+EXTERN void		Tcl_PopCallFrame(Tcl_Interp *interp);
+/* 129 */
+EXTERN int		Tcl_PushCallFrame(Tcl_Interp *interp,
+				Tcl_CallFrame *framePtr,
+				Tcl_Namespace *nsPtr, int isProcCallFrame);
+/* 130 */
+EXTERN int		Tcl_RemoveInterpResolvers(Tcl_Interp *interp,
+				const char *name);
+/* 131 */
+EXTERN void		Tcl_SetNamespaceResolvers(
+				Tcl_Namespace *namespacePtr,
+				Tcl_ResolveCmdProc *cmdProc,
+				Tcl_ResolveVarProc *varProc,
+				Tcl_ResolveCompiledVarProc *compiledVarProc);
+/* 132 */
+EXTERN int		TclpHasSockets(Tcl_Interp *interp);
+/* 133 */
+EXTERN struct tm *	TclpGetDate(const time_t *time, int useGMT);
+/* Slot 134 is reserved */
+/* Slot 135 is reserved */
+/* Slot 136 is reserved */
+/* Slot 137 is reserved */
+/* 138 */
+EXTERN CONST84_RETURN char * TclGetEnv(const char *name,
+				Tcl_DString *valuePtr);
+/* Slot 139 is reserved */
+/* Slot 140 is reserved */
+/* 141 */
+EXTERN CONST84_RETURN char * TclpGetCwd(Tcl_Interp *interp,
+				Tcl_DString *cwdPtr);
+/* 142 */
+EXTERN int		TclSetByteCodeFromAny(Tcl_Interp *interp,
+				Tcl_Obj *objPtr, CompileHookProc *hookProc,
+				ClientData clientData);
+/* 143 */
+EXTERN int		TclAddLiteralObj(struct CompileEnv *envPtr,
+				Tcl_Obj *objPtr, LiteralEntry **litPtrPtr);
+/* 144 */
+EXTERN void		TclHideLiteral(Tcl_Interp *interp,
+				struct CompileEnv *envPtr, int index);
+/* 145 */
+EXTERN const struct AuxDataType * TclGetAuxDataType(const char *typeName);
+/* 146 */
+EXTERN TclHandle	TclHandleCreate(void *ptr);
+/* 147 */
+EXTERN void		TclHandleFree(TclHandle handle);
+/* 148 */
+EXTERN TclHandle	TclHandlePreserve(TclHandle handle);
+/* 149 */
+EXTERN void		TclHandleRelease(TclHandle handle);
+/* 150 */
+EXTERN int		TclRegAbout(Tcl_Interp *interp, Tcl_RegExp re);
+/* 151 */
+EXTERN void		TclRegExpRangeUniChar(Tcl_RegExp re, int index,
+				int *startPtr, int *endPtr);
+/* 152 */
+EXTERN void		TclSetLibraryPath(Tcl_Obj *pathPtr);
+/* 153 */
+EXTERN Tcl_Obj *	TclGetLibraryPath(void);
+/* Slot 154 is reserved */
+/* Slot 155 is reserved */
+/* 156 */
+EXTERN void		TclRegError(Tcl_Interp *interp, const char *msg,
+				int status);
+/* 157 */
+EXTERN Var *		TclVarTraceExists(Tcl_Interp *interp,
+				const char *varName);
+/* 158 */
+EXTERN void		TclSetStartupScriptFileName(const char *filename);
+/* 159 */
+EXTERN const char *	TclGetStartupScriptFileName(void);
+/* Slot 160 is reserved */
+/* 161 */
+EXTERN int		TclChannelTransform(Tcl_Interp *interp,
+				Tcl_Channel chan, Tcl_Obj *cmdObjPtr);
+/* 162 */
+EXTERN void		TclChannelEventScriptInvoker(ClientData clientData,
+				int flags);
+/* 163 */
+EXTERN const void *	TclGetInstructionTable(void);
+/* 164 */
+EXTERN void		TclExpandCodeArray(void *envPtr);
+/* 165 */
+EXTERN void		TclpSetInitialEncodings(void);
+/* 166 */
+EXTERN int		TclListObjSetElement(Tcl_Interp *interp,
+				Tcl_Obj *listPtr, int index,
+				Tcl_Obj *valuePtr);
+/* 167 */
+EXTERN void		TclSetStartupScriptPath(Tcl_Obj *pathPtr);
+/* 168 */
+EXTERN Tcl_Obj *	TclGetStartupScriptPath(void);
+/* 169 */
+EXTERN int		TclpUtfNcmp2(const char *s1, const char *s2,
+				unsigned long n);
+/* 170 */
+EXTERN int		TclCheckInterpTraces(Tcl_Interp *interp,
+				const char *command, int numChars,
+				Command *cmdPtr, int result, int traceFlags,
+				int objc, Tcl_Obj *const objv[]);
+/* 171 */
+EXTERN int		TclCheckExecutionTraces(Tcl_Interp *interp,
+				const char *command, int numChars,
+				Command *cmdPtr, int result, int traceFlags,
+				int objc, Tcl_Obj *const objv[]);
+/* 172 */
+EXTERN int		TclInThreadExit(void);
+/* 173 */
+EXTERN int		TclUniCharMatch(const Tcl_UniChar *string,
+				int strLen, const Tcl_UniChar *pattern,
+				int ptnLen, int flags);
+/* Slot 174 is reserved */
+/* 175 */
+EXTERN int		TclCallVarTraces(Interp *iPtr, Var *arrayPtr,
+				Var *varPtr, const char *part1,
+				const char *part2, int flags,
+				int leaveErrMsg);
+/* 176 */
+EXTERN void		TclCleanupVar(Var *varPtr, Var *arrayPtr);
+/* 177 */
+EXTERN void		TclVarErrMsg(Tcl_Interp *interp, const char *part1,
+				const char *part2, const char *operation,
+				const char *reason);
+/* 178 */
+EXTERN void		Tcl_SetStartupScript(Tcl_Obj *pathPtr,
+				const char *encodingName);
+/* 179 */
+EXTERN Tcl_Obj *	Tcl_GetStartupScript(const char **encodingNamePtr);
+/* Slot 180 is reserved */
+/* Slot 181 is reserved */
+/* 182 */
+EXTERN struct tm *	TclpLocaltime(const time_t *clock);
+/* 183 */
+EXTERN struct tm *	TclpGmtime(const time_t *clock);
+/* Slot 184 is reserved */
+/* Slot 185 is reserved */
+/* Slot 186 is reserved */
+/* Slot 187 is reserved */
+/* Slot 188 is reserved */
+/* Slot 189 is reserved */
+/* Slot 190 is reserved */
+/* Slot 191 is reserved */
+/* Slot 192 is reserved */
+/* Slot 193 is reserved */
+/* Slot 194 is reserved */
+/* Slot 195 is reserved */
+/* Slot 196 is reserved */
+/* Slot 197 is reserved */
+/* 198 */
+EXTERN int		TclObjGetFrame(Tcl_Interp *interp, Tcl_Obj *objPtr,
+				CallFrame **framePtrPtr);
+/* Slot 199 is reserved */
+/* 200 */
+EXTERN int		TclpObjRemoveDirectory(Tcl_Obj *pathPtr,
+				int recursive, Tcl_Obj **errorPtr);
+/* 201 */
+EXTERN int		TclpObjCopyDirectory(Tcl_Obj *srcPathPtr,
+				Tcl_Obj *destPathPtr, Tcl_Obj **errorPtr);
+/* 202 */
+EXTERN int		TclpObjCreateDirectory(Tcl_Obj *pathPtr);
+/* 203 */
+EXTERN int		TclpObjDeleteFile(Tcl_Obj *pathPtr);
+/* 204 */
+EXTERN int		TclpObjCopyFile(Tcl_Obj *srcPathPtr,
+				Tcl_Obj *destPathPtr);
+/* 205 */
+EXTERN int		TclpObjRenameFile(Tcl_Obj *srcPathPtr,
+				Tcl_Obj *destPathPtr);
+/* 206 */
+EXTERN int		TclpObjStat(Tcl_Obj *pathPtr, Tcl_StatBuf *buf);
+/* 207 */
+EXTERN int		TclpObjAccess(Tcl_Obj *pathPtr, int mode);
+/* 208 */
+EXTERN Tcl_Channel	TclpOpenFileChannel(Tcl_Interp *interp,
+				Tcl_Obj *pathPtr, int mode, int permissions);
+/* Slot 209 is reserved */
+/* Slot 210 is reserved */
+/* Slot 211 is reserved */
+/* 212 */
+EXTERN void		TclpFindExecutable(const char *argv0);
+/* 213 */
+EXTERN Tcl_Obj *	TclGetObjNameOfExecutable(void);
+/* 214 */
+EXTERN void		TclSetObjNameOfExecutable(Tcl_Obj *name,
+				Tcl_Encoding encoding);
+/* 215 */
+EXTERN void *		TclStackAlloc(Tcl_Interp *interp, int numBytes);
+/* 216 */
+EXTERN void		TclStackFree(Tcl_Interp *interp, void *freePtr);
+/* 217 */
+EXTERN int		TclPushStackFrame(Tcl_Interp *interp,
+				Tcl_CallFrame **framePtrPtr,
+				Tcl_Namespace *namespacePtr,
+				int isProcCallFrame);
+/* 218 */
+EXTERN void		TclPopStackFrame(Tcl_Interp *interp);
+/* Slot 219 is reserved */
+/* Slot 220 is reserved */
+/* Slot 221 is reserved */
+/* Slot 222 is reserved */
+/* Slot 223 is reserved */
+/* 224 */
+EXTERN TclPlatformType * TclGetPlatform(void);
+/* 225 */
+EXTERN Tcl_Obj *	TclTraceDictPath(Tcl_Interp *interp,
+				Tcl_Obj *rootPtr, int keyc,
+				Tcl_Obj *const keyv[], int flags);
+/* 226 */
+EXTERN int		TclObjBeingDeleted(Tcl_Obj *objPtr);
+/* 227 */
+EXTERN void		TclSetNsPath(Namespace *nsPtr, int pathLength,
+				Tcl_Namespace *pathAry[]);
+/* Slot 228 is reserved */
+/* 229 */
+EXTERN int		TclPtrMakeUpvar(Tcl_Interp *interp, Var *otherP1Ptr,
+				const char *myName, int myFlags, int index);
+/* 230 */
+EXTERN Var *		TclObjLookupVar(Tcl_Interp *interp,
+				Tcl_Obj *part1Ptr, const char *part2,
+				int flags, const char *msg,
+				const int createPart1, const int createPart2,
+				Var **arrayPtrPtr);
+/* 231 */
+EXTERN int		TclGetNamespaceFromObj(Tcl_Interp *interp,
+				Tcl_Obj *objPtr, Tcl_Namespace **nsPtrPtr);
+/* 232 */
+EXTERN int		TclEvalObjEx(Tcl_Interp *interp, Tcl_Obj *objPtr,
+				int flags, const CmdFrame *invoker, int word);
+/* 233 */
+EXTERN void		TclGetSrcInfoForPc(CmdFrame *contextPtr);
+/* 234 */
+EXTERN Var *		TclVarHashCreateVar(TclVarHashTable *tablePtr,
+				const char *key, int *newPtr);
+/* 235 */
+EXTERN void		TclInitVarHashTable(TclVarHashTable *tablePtr,
+				Namespace *nsPtr);
+/* 236 */
+EXTERN void		TclBackgroundException(Tcl_Interp *interp, int code);
+/* 237 */
+EXTERN int		TclResetCancellation(Tcl_Interp *interp, int force);
+/* 238 */
+EXTERN int		TclNRInterpProc(ClientData clientData,
+				Tcl_Interp *interp, int objc,
+				Tcl_Obj *const objv[]);
+/* 239 */
+EXTERN int		TclNRInterpProcCore(Tcl_Interp *interp,
+				Tcl_Obj *procNameObj, int skip,
+				ProcErrorProc *errorProc);
+/* 240 */
+EXTERN int		TclNRRunCallbacks(Tcl_Interp *interp, int result,
+				struct NRE_callback *rootPtr);
+/* 241 */
+EXTERN int		TclNREvalObjEx(Tcl_Interp *interp, Tcl_Obj *objPtr,
+				int flags, const CmdFrame *invoker, int word);
+/* 242 */
+EXTERN int		TclNREvalObjv(Tcl_Interp *interp, int objc,
+				Tcl_Obj *const objv[], int flags,
+				Command *cmdPtr);
+/* 243 */
+EXTERN void		TclDbDumpActiveObjects(FILE *outFile);
+/* 244 */
+EXTERN Tcl_HashTable *	TclGetNamespaceChildTable(Tcl_Namespace *nsPtr);
+/* 245 */
+EXTERN Tcl_HashTable *	TclGetNamespaceCommandTable(Tcl_Namespace *nsPtr);
+/* 246 */
+EXTERN int		TclInitRewriteEnsemble(Tcl_Interp *interp,
+				int numRemoved, int numInserted,
+				Tcl_Obj *const *objv);
+/* 247 */
+EXTERN void		TclResetRewriteEnsemble(Tcl_Interp *interp,
+				int isRootEnsemble);
+/* 248 */
+EXTERN int		TclCopyChannel(Tcl_Interp *interp,
+				Tcl_Channel inChan, Tcl_Channel outChan,
+				Tcl_WideInt toRead, Tcl_Obj *cmdPtr);
+/* 249 */
+EXTERN char *		TclDoubleDigits(double dv, int ndigits, int flags,
+				int *decpt, int *signum, char **endPtr);
+/* 250 */
+EXTERN void		TclSetSlaveCancelFlags(Tcl_Interp *interp, int flags,
+				int force);
+/* 251 */
+EXTERN int		TclRegisterLiteral(void *envPtr, char *bytes,
+				int length, int flags);
+
+typedef struct TclIntStubs {
+    int magic;
+    void *hooks;
+
+    void (*reserved0)(void);
+    void (*reserved1)(void);
+    void (*reserved2)(void);
+    void (*tclAllocateFreeObjects) (void); /* 3 */
+    void (*reserved4)(void);
+    int (*tclCleanupChildren) (Tcl_Interp *interp, int numPids, Tcl_Pid *pidPtr, Tcl_Channel errorChan); /* 5 */
+    void (*tclCleanupCommand) (Command *cmdPtr); /* 6 */
+    int (*tclCopyAndCollapse) (int count, const char *src, char *dst); /* 7 */
+    int (*tclCopyChannelOld) (Tcl_Interp *interp, Tcl_Channel inChan, Tcl_Channel outChan, int toRead, Tcl_Obj *cmdPtr); /* 8 */
+    int (*tclCreatePipeline) (Tcl_Interp *interp, int argc, const char **argv, Tcl_Pid **pidArrayPtr, TclFile *inPipePtr, TclFile *outPipePtr, TclFile *errFilePtr); /* 9 */
+    int (*tclCreateProc) (Tcl_Interp *interp, Namespace *nsPtr, const char *procName, Tcl_Obj *argsPtr, Tcl_Obj *bodyPtr, Proc **procPtrPtr); /* 10 */
+    void (*tclDeleteCompiledLocalVars) (Interp *iPtr, CallFrame *framePtr); /* 11 */
+    void (*tclDeleteVars) (Interp *iPtr, TclVarHashTable *tablePtr); /* 12 */
+    void (*reserved13)(void);
+    int (*tclDumpMemoryInfo) (ClientData clientData, int flags); /* 14 */
+    void (*reserved15)(void);
+    void (*tclExprFloatError) (Tcl_Interp *interp, double value); /* 16 */
+    void (*reserved17)(void);
+    void (*reserved18)(void);
+    void (*reserved19)(void);
+    void (*reserved20)(void);
+    void (*reserved21)(void);
+    int (*tclFindElement) (Tcl_Interp *interp, const char *listStr, int listLength, const char **elementPtr, const char **nextPtr, int *sizePtr, int *bracePtr); /* 22 */
+    Proc * (*tclFindProc) (Interp *iPtr, const char *procName); /* 23 */
+    int (*tclFormatInt) (char *buffer, long n); /* 24 */
+    void (*tclFreePackageInfo) (Interp *iPtr); /* 25 */
+    void (*reserved26)(void);
+    void (*reserved27)(void);
+    Tcl_Channel (*tclpGetDefaultStdChannel) (int type); /* 28 */
+    void (*reserved29)(void);
+    void (*reserved30)(void);
+    const char * (*tclGetExtension) (const char *name); /* 31 */
+    int (*tclGetFrame) (Tcl_Interp *interp, const char *str, CallFrame **framePtrPtr); /* 32 */
+    void (*reserved33)(void);
+    int (*tclGetIntForIndex) (Tcl_Interp *interp, Tcl_Obj *objPtr, int endValue, int *indexPtr); /* 34 */
+    void (*reserved35)(void);
+    void (*reserved36)(void);
+    int (*tclGetLoadedPackages) (Tcl_Interp *interp, const char *targetName); /* 37 */
+    int (*tclGetNamespaceForQualName) (Tcl_Interp *interp, const char *qualName, Namespace *cxtNsPtr, int flags, Namespace **nsPtrPtr, Namespace **altNsPtrPtr, Namespace **actualCxtPtrPtr, const char **simpleNamePtr); /* 38 */
+    TclObjCmdProcType (*tclGetObjInterpProc) (void); /* 39 */
+    int (*tclGetOpenMode) (Tcl_Interp *interp, const char *str, int *seekFlagPtr); /* 40 */
+    Tcl_Command (*tclGetOriginalCommand) (Tcl_Command command); /* 41 */
+    CONST86 char * (*tclpGetUserHome) (const char *name, Tcl_DString *bufferPtr); /* 42 */
+    void (*reserved43)(void);
+    int (*tclGuessPackageName) (const char *fileName, Tcl_DString *bufPtr); /* 44 */
+    int (*tclHideUnsafeCommands) (Tcl_Interp *interp); /* 45 */
+    int (*tclInExit) (void); /* 46 */
+    void (*reserved47)(void);
+    void (*reserved48)(void);
+    void (*reserved49)(void);
+    void (*tclInitCompiledLocals) (Tcl_Interp *interp, CallFrame *framePtr, Namespace *nsPtr); /* 50 */
+    int (*tclInterpInit) (Tcl_Interp *interp); /* 51 */
+    void (*reserved52)(void);
+    int (*tclInvokeObjectCommand) (ClientData clientData, Tcl_Interp *interp, int argc, CONST84 char **argv); /* 53 */
+    int (*tclInvokeStringCommand) (ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); /* 54 */
+    Proc * (*tclIsProc) (Command *cmdPtr); /* 55 */
+    void (*reserved56)(void);
+    void (*reserved57)(void);
+    Var * (*tclLookupVar) (Tcl_Interp *interp, const char *part1, const char *part2, int flags, const char *msg, int createPart1, int createPart2, Var **arrayPtrPtr); /* 58 */
+    void (*reserved59)(void);
+    int (*tclNeedSpace) (const char *start, const char *end); /* 60 */
+    Tcl_Obj * (*tclNewProcBodyObj) (Proc *procPtr); /* 61 */
+    int (*tclObjCommandComplete) (Tcl_Obj *cmdPtr); /* 62 */
+    int (*tclObjInterpProc) (ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); /* 63 */
+    int (*tclObjInvoke) (Tcl_Interp *interp, int objc, Tcl_Obj *const objv[], int flags); /* 64 */
+    void (*reserved65)(void);
+    void (*reserved66)(void);
+    void (*reserved67)(void);
+    void (*reserved68)(void);
+    char * (*tclpAlloc) (unsigned int size); /* 69 */
+    void (*reserved70)(void);
+    void (*reserved71)(void);
+    void (*reserved72)(void);
+    void (*reserved73)(void);
+    void (*tclpFree) (char *ptr); /* 74 */
+    unsigned long (*tclpGetClicks) (void); /* 75 */
+    unsigned long (*tclpGetSeconds) (void); /* 76 */
+    void (*tclpGetTime) (Tcl_Time *time); /* 77 */
+    void (*reserved78)(void);
+    void (*reserved79)(void);
+    void (*reserved80)(void);
+    char * (*tclpRealloc) (char *ptr, unsigned int size); /* 81 */
+    void (*reserved82)(void);
+    void (*reserved83)(void);
+    void (*reserved84)(void);
+    void (*reserved85)(void);
+    void (*reserved86)(void);
+    void (*reserved87)(void);
+    char * (*tclPrecTraceProc) (ClientData clientData, Tcl_Interp *interp, const char *name1, const char *name2, int flags); /* 88 */
+    int (*tclPreventAliasLoop) (Tcl_Interp *interp, Tcl_Interp *cmdInterp, Tcl_Command cmd); /* 89 */
+    void (*reserved90)(void);
+    void (*tclProcCleanupProc) (Proc *procPtr); /* 91 */
+    int (*tclProcCompileProc) (Tcl_Interp *interp, Proc *procPtr, Tcl_Obj *bodyPtr, Namespace *nsPtr, const char *description, const char *procName); /* 92 */
+    void (*tclProcDeleteProc) (ClientData clientData); /* 93 */
+    void (*reserved94)(void);
+    void (*reserved95)(void);
+    int (*tclRenameCommand) (Tcl_Interp *interp, const char *oldName, const char *newName); /* 96 */
+    void (*tclResetShadowedCmdRefs) (Tcl_Interp *interp, Command *newCmdPtr); /* 97 */
+    int (*tclServiceIdle) (void); /* 98 */
+    void (*reserved99)(void);
+    void (*reserved100)(void);
+    CONST86 char * (*tclSetPreInitScript) (const char *string); /* 101 */
+    void (*tclSetupEnv) (Tcl_Interp *interp); /* 102 */
+    int (*tclSockGetPort) (Tcl_Interp *interp, const char *str, const char *proto, int *portPtr); /* 103 */
+    int (*tclSockMinimumBuffersOld) (int sock, int size); /* 104 */
+    void (*reserved105)(void);
+    void (*reserved106)(void);
+    void (*reserved107)(void);
+    void (*tclTeardownNamespace) (Namespace *nsPtr); /* 108 */
+    int (*tclUpdateReturnInfo) (Interp *iPtr); /* 109 */
+    int (*tclSockMinimumBuffers) (void *sock, int size); /* 110 */
+    void (*tcl_AddInterpResolvers) (Tcl_Interp *interp, const char *name, Tcl_ResolveCmdProc *cmdProc, Tcl_ResolveVarProc *varProc, Tcl_ResolveCompiledVarProc *compiledVarProc); /* 111 */
+    int (*tcl_AppendExportList) (Tcl_Interp *interp, Tcl_Namespace *nsPtr, Tcl_Obj *objPtr); /* 112 */
+    Tcl_Namespace * (*tcl_CreateNamespace) (Tcl_Interp *interp, const char *name, ClientData clientData, Tcl_NamespaceDeleteProc *deleteProc); /* 113 */
+    void (*tcl_DeleteNamespace) (Tcl_Namespace *nsPtr); /* 114 */
+    int (*tcl_Export) (Tcl_Interp *interp, Tcl_Namespace *nsPtr, const char *pattern, int resetListFirst); /* 115 */
+    Tcl_Command (*tcl_FindCommand) (Tcl_Interp *interp, const char *name, Tcl_Namespace *contextNsPtr, int flags); /* 116 */
+    Tcl_Namespace * (*tcl_FindNamespace) (Tcl_Interp *interp, const char *name, Tcl_Namespace *contextNsPtr, int flags); /* 117 */
+    int (*tcl_GetInterpResolvers) (Tcl_Interp *interp, const char *name, Tcl_ResolverInfo *resInfo); /* 118 */
+    int (*tcl_GetNamespaceResolvers) (Tcl_Namespace *namespacePtr, Tcl_ResolverInfo *resInfo); /* 119 */
+    Tcl_Var (*tcl_FindNamespaceVar) (Tcl_Interp *interp, const char *name, Tcl_Namespace *contextNsPtr, int flags); /* 120 */
+    int (*tcl_ForgetImport) (Tcl_Interp *interp, Tcl_Namespace *nsPtr, const char *pattern); /* 121 */
+    Tcl_Command (*tcl_GetCommandFromObj) (Tcl_Interp *interp, Tcl_Obj *objPtr); /* 122 */
+    void (*tcl_GetCommandFullName) (Tcl_Interp *interp, Tcl_Command command, Tcl_Obj *objPtr); /* 123 */
+    Tcl_Namespace * (*tcl_GetCurrentNamespace) (Tcl_Interp *interp); /* 124 */
+    Tcl_Namespace * (*tcl_GetGlobalNamespace) (Tcl_Interp *interp); /* 125 */
+    void (*tcl_GetVariableFullName) (Tcl_Interp *interp, Tcl_Var variable, Tcl_Obj *objPtr); /* 126 */
+    int (*tcl_Import) (Tcl_Interp *interp, Tcl_Namespace *nsPtr, const char *pattern, int allowOverwrite); /* 127 */
+    void (*tcl_PopCallFrame) (Tcl_Interp *interp); /* 128 */
+    int (*tcl_PushCallFrame) (Tcl_Interp *interp, Tcl_CallFrame *framePtr, Tcl_Namespace *nsPtr, int isProcCallFrame); /* 129 */
+    int (*tcl_RemoveInterpResolvers) (Tcl_Interp *interp, const char *name); /* 130 */
+    void (*tcl_SetNamespaceResolvers) (Tcl_Namespace *namespacePtr, Tcl_ResolveCmdProc *cmdProc, Tcl_ResolveVarProc *varProc, Tcl_ResolveCompiledVarProc *compiledVarProc); /* 131 */
+    int (*tclpHasSockets) (Tcl_Interp *interp); /* 132 */
+    struct tm * (*tclpGetDate) (const time_t *time, int useGMT); /* 133 */
+    void (*reserved134)(void);
+    void (*reserved135)(void);
+    void (*reserved136)(void);
+    void (*reserved137)(void);
+    CONST84_RETURN char * (*tclGetEnv) (const char *name, Tcl_DString *valuePtr); /* 138 */
+    void (*reserved139)(void);
+    void (*reserved140)(void);
+    CONST84_RETURN char * (*tclpGetCwd) (Tcl_Interp *interp, Tcl_DString *cwdPtr); /* 141 */
+    int (*tclSetByteCodeFromAny) (Tcl_Interp *interp, Tcl_Obj *objPtr, CompileHookProc *hookProc, ClientData clientData); /* 142 */
+    int (*tclAddLiteralObj) (struct CompileEnv *envPtr, Tcl_Obj *objPtr, LiteralEntry **litPtrPtr); /* 143 */
+    void (*tclHideLiteral) (Tcl_Interp *interp, struct CompileEnv *envPtr, int index); /* 144 */
+    const struct AuxDataType * (*tclGetAuxDataType) (const char *typeName); /* 145 */
+    TclHandle (*tclHandleCreate) (void *ptr); /* 146 */
+    void (*tclHandleFree) (TclHandle handle); /* 147 */
+    TclHandle (*tclHandlePreserve) (TclHandle handle); /* 148 */
+    void (*tclHandleRelease) (TclHandle handle); /* 149 */
+    int (*tclRegAbout) (Tcl_Interp *interp, Tcl_RegExp re); /* 150 */
+    void (*tclRegExpRangeUniChar) (Tcl_RegExp re, int index, int *startPtr, int *endPtr); /* 151 */
+    void (*tclSetLibraryPath) (Tcl_Obj *pathPtr); /* 152 */
+    Tcl_Obj * (*tclGetLibraryPath) (void); /* 153 */
+    void (*reserved154)(void);
+    void (*reserved155)(void);
+    void (*tclRegError) (Tcl_Interp *interp, const char *msg, int status); /* 156 */
+    Var * (*tclVarTraceExists) (Tcl_Interp *interp, const char *varName); /* 157 */
+    void (*tclSetStartupScriptFileName) (const char *filename); /* 158 */
+    const char * (*tclGetStartupScriptFileName) (void); /* 159 */
+    void (*reserved160)(void);
+    int (*tclChannelTransform) (Tcl_Interp *interp, Tcl_Channel chan, Tcl_Obj *cmdObjPtr); /* 161 */
+    void (*tclChannelEventScriptInvoker) (ClientData clientData, int flags); /* 162 */
+    const void * (*tclGetInstructionTable) (void); /* 163 */
+    void (*tclExpandCodeArray) (void *envPtr); /* 164 */
+    void (*tclpSetInitialEncodings) (void); /* 165 */
+    int (*tclListObjSetElement) (Tcl_Interp *interp, Tcl_Obj *listPtr, int index, Tcl_Obj *valuePtr); /* 166 */
+    void (*tclSetStartupScriptPath) (Tcl_Obj *pathPtr); /* 167 */
+    Tcl_Obj * (*tclGetStartupScriptPath) (void); /* 168 */
+    int (*tclpUtfNcmp2) (const char *s1, const char *s2, unsigned long n); /* 169 */
+    int (*tclCheckInterpTraces) (Tcl_Interp *interp, const char *command, int numChars, Command *cmdPtr, int result, int traceFlags, int objc, Tcl_Obj *const objv[]); /* 170 */
+    int (*tclCheckExecutionTraces) (Tcl_Interp *interp, const char *command, int numChars, Command *cmdPtr, int result, int traceFlags, int objc, Tcl_Obj *const objv[]); /* 171 */
+    int (*tclInThreadExit) (void); /* 172 */
+    int (*tclUniCharMatch) (const Tcl_UniChar *string, int strLen, const Tcl_UniChar *pattern, int ptnLen, int flags); /* 173 */
+    void (*reserved174)(void);
+    int (*tclCallVarTraces) (Interp *iPtr, Var *arrayPtr, Var *varPtr, const char *part1, const char *part2, int flags, int leaveErrMsg); /* 175 */
+    void (*tclCleanupVar) (Var *varPtr, Var *arrayPtr); /* 176 */
+    void (*tclVarErrMsg) (Tcl_Interp *interp, const char *part1, const char *part2, const char *operation, const char *reason); /* 177 */
+    void (*tcl_SetStartupScript) (Tcl_Obj *pathPtr, const char *encodingName); /* 178 */
+    Tcl_Obj * (*tcl_GetStartupScript) (const char **encodingNamePtr); /* 179 */
+    void (*reserved180)(void);
+    void (*reserved181)(void);
+    struct tm * (*tclpLocaltime) (const time_t *clock); /* 182 */
+    struct tm * (*tclpGmtime) (const time_t *clock); /* 183 */
+    void (*reserved184)(void);
+    void (*reserved185)(void);
+    void (*reserved186)(void);
+    void (*reserved187)(void);
+    void (*reserved188)(void);
+    void (*reserved189)(void);
+    void (*reserved190)(void);
+    void (*reserved191)(void);
+    void (*reserved192)(void);
+    void (*reserved193)(void);
+    void (*reserved194)(void);
+    void (*reserved195)(void);
+    void (*reserved196)(void);
+    void (*reserved197)(void);
+    int (*tclObjGetFrame) (Tcl_Interp *interp, Tcl_Obj *objPtr, CallFrame **framePtrPtr); /* 198 */
+    void (*reserved199)(void);
+    int (*tclpObjRemoveDirectory) (Tcl_Obj *pathPtr, int recursive, Tcl_Obj **errorPtr); /* 200 */
+    int (*tclpObjCopyDirectory) (Tcl_Obj *srcPathPtr, Tcl_Obj *destPathPtr, Tcl_Obj **errorPtr); /* 201 */
+    int (*tclpObjCreateDirectory) (Tcl_Obj *pathPtr); /* 202 */
+    int (*tclpObjDeleteFile) (Tcl_Obj *pathPtr); /* 203 */
+    int (*tclpObjCopyFile) (Tcl_Obj *srcPathPtr, Tcl_Obj *destPathPtr); /* 204 */
+    int (*tclpObjRenameFile) (Tcl_Obj *srcPathPtr, Tcl_Obj *destPathPtr); /* 205 */
+    int (*tclpObjStat) (Tcl_Obj *pathPtr, Tcl_StatBuf *buf); /* 206 */
+    int (*tclpObjAccess) (Tcl_Obj *pathPtr, int mode); /* 207 */
+    Tcl_Channel (*tclpOpenFileChannel) (Tcl_Interp *interp, Tcl_Obj *pathPtr, int mode, int permissions); /* 208 */
+    void (*reserved209)(void);
+    void (*reserved210)(void);
+    void (*reserved211)(void);
+    void (*tclpFindExecutable) (const char *argv0); /* 212 */
+    Tcl_Obj * (*tclGetObjNameOfExecutable) (void); /* 213 */
+    void (*tclSetObjNameOfExecutable) (Tcl_Obj *name, Tcl_Encoding encoding); /* 214 */
+    void * (*tclStackAlloc) (Tcl_Interp *interp, int numBytes); /* 215 */
+    void (*tclStackFree) (Tcl_Interp *interp, void *freePtr); /* 216 */
+    int (*tclPushStackFrame) (Tcl_Interp *interp, Tcl_CallFrame **framePtrPtr, Tcl_Namespace *namespacePtr, int isProcCallFrame); /* 217 */
+    void (*tclPopStackFrame) (Tcl_Interp *interp); /* 218 */
+    void (*reserved219)(void);
+    void (*reserved220)(void);
+    void (*reserved221)(void);
+    void (*reserved222)(void);
+    void (*reserved223)(void);
+    TclPlatformType * (*tclGetPlatform) (void); /* 224 */
+    Tcl_Obj * (*tclTraceDictPath) (Tcl_Interp *interp, Tcl_Obj *rootPtr, int keyc, Tcl_Obj *const keyv[], int flags); /* 225 */
+    int (*tclObjBeingDeleted) (Tcl_Obj *objPtr); /* 226 */
+    void (*tclSetNsPath) (Namespace *nsPtr, int pathLength, Tcl_Namespace *pathAry[]); /* 227 */
+    void (*reserved228)(void);
+    int (*tclPtrMakeUpvar) (Tcl_Interp *interp, Var *otherP1Ptr, const char *myName, int myFlags, int index); /* 229 */
+    Var * (*tclObjLookupVar) (Tcl_Interp *interp, Tcl_Obj *part1Ptr, const char *part2, int flags, const char *msg, const int createPart1, const int createPart2, Var **arrayPtrPtr); /* 230 */
+    int (*tclGetNamespaceFromObj) (Tcl_Interp *interp, Tcl_Obj *objPtr, Tcl_Namespace **nsPtrPtr); /* 231 */
+    int (*tclEvalObjEx) (Tcl_Interp *interp, Tcl_Obj *objPtr, int flags, const CmdFrame *invoker, int word); /* 232 */
+    void (*tclGetSrcInfoForPc) (CmdFrame *contextPtr); /* 233 */
+    Var * (*tclVarHashCreateVar) (TclVarHashTable *tablePtr, const char *key, int *newPtr); /* 234 */
+    void (*tclInitVarHashTable) (TclVarHashTable *tablePtr, Namespace *nsPtr); /* 235 */
+    void (*tclBackgroundException) (Tcl_Interp *interp, int code); /* 236 */
+    int (*tclResetCancellation) (Tcl_Interp *interp, int force); /* 237 */
+    int (*tclNRInterpProc) (ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); /* 238 */
+    int (*tclNRInterpProcCore) (Tcl_Interp *interp, Tcl_Obj *procNameObj, int skip, ProcErrorProc *errorProc); /* 239 */
+    int (*tclNRRunCallbacks) (Tcl_Interp *interp, int result, struct NRE_callback *rootPtr); /* 240 */
+    int (*tclNREvalObjEx) (Tcl_Interp *interp, Tcl_Obj *objPtr, int flags, const CmdFrame *invoker, int word); /* 241 */
+    int (*tclNREvalObjv) (Tcl_Interp *interp, int objc, Tcl_Obj *const objv[], int flags, Command *cmdPtr); /* 242 */
+    void (*tclDbDumpActiveObjects) (FILE *outFile); /* 243 */
+    Tcl_HashTable * (*tclGetNamespaceChildTable) (Tcl_Namespace *nsPtr); /* 244 */
+    Tcl_HashTable * (*tclGetNamespaceCommandTable) (Tcl_Namespace *nsPtr); /* 245 */
+    int (*tclInitRewriteEnsemble) (Tcl_Interp *interp, int numRemoved, int numInserted, Tcl_Obj *const *objv); /* 246 */
+    void (*tclResetRewriteEnsemble) (Tcl_Interp *interp, int isRootEnsemble); /* 247 */
+    int (*tclCopyChannel) (Tcl_Interp *interp, Tcl_Channel inChan, Tcl_Channel outChan, Tcl_WideInt toRead, Tcl_Obj *cmdPtr); /* 248 */
+    char * (*tclDoubleDigits) (double dv, int ndigits, int flags, int *decpt, int *signum, char **endPtr); /* 249 */
+    void (*tclSetSlaveCancelFlags) (Tcl_Interp *interp, int flags, int force); /* 250 */
+    int (*tclRegisterLiteral) (void *envPtr, char *bytes, int length, int flags); /* 251 */
+} TclIntStubs;
+
+extern const TclIntStubs *tclIntStubsPtr;
+
+#ifdef __cplusplus
+}
+#endif
+
+#if defined(USE_TCL_STUBS)
+
+/*
+ * Inline function declarations:
+ */
+
+/* Slot 0 is reserved */
+/* Slot 1 is reserved */
+/* Slot 2 is reserved */
+#define TclAllocateFreeObjects \
+	(tclIntStubsPtr->tclAllocateFreeObjects) /* 3 */
+/* Slot 4 is reserved */
+#define TclCleanupChildren \
+	(tclIntStubsPtr->tclCleanupChildren) /* 5 */
+#define TclCleanupCommand \
+	(tclIntStubsPtr->tclCleanupCommand) /* 6 */
+#define TclCopyAndCollapse \
+	(tclIntStubsPtr->tclCopyAndCollapse) /* 7 */
+#define TclCopyChannelOld \
+	(tclIntStubsPtr->tclCopyChannelOld) /* 8 */
+#define TclCreatePipeline \
+	(tclIntStubsPtr->tclCreatePipeline) /* 9 */
+#define TclCreateProc \
+	(tclIntStubsPtr->tclCreateProc) /* 10 */
+#define TclDeleteCompiledLocalVars \
+	(tclIntStubsPtr->tclDeleteCompiledLocalVars) /* 11 */
+#define TclDeleteVars \
+	(tclIntStubsPtr->tclDeleteVars) /* 12 */
+/* Slot 13 is reserved */
+#define TclDumpMemoryInfo \
+	(tclIntStubsPtr->tclDumpMemoryInfo) /* 14 */
+/* Slot 15 is reserved */
+#define TclExprFloatError \
+	(tclIntStubsPtr->tclExprFloatError) /* 16 */
+/* Slot 17 is reserved */
+/* Slot 18 is reserved */
+/* Slot 19 is reserved */
+/* Slot 20 is reserved */
+/* Slot 21 is reserved */
+#define TclFindElement \
+	(tclIntStubsPtr->tclFindElement) /* 22 */
+#define TclFindProc \
+	(tclIntStubsPtr->tclFindProc) /* 23 */
+#define TclFormatInt \
+	(tclIntStubsPtr->tclFormatInt) /* 24 */
+#define TclFreePackageInfo \
+	(tclIntStubsPtr->tclFreePackageInfo) /* 25 */
+/* Slot 26 is reserved */
+/* Slot 27 is reserved */
+#define TclpGetDefaultStdChannel \
+	(tclIntStubsPtr->tclpGetDefaultStdChannel) /* 28 */
+/* Slot 29 is reserved */
+/* Slot 30 is reserved */
+#define TclGetExtension \
+	(tclIntStubsPtr->tclGetExtension) /* 31 */
+#define TclGetFrame \
+	(tclIntStubsPtr->tclGetFrame) /* 32 */
+/* Slot 33 is reserved */
+#define TclGetIntForIndex \
+	(tclIntStubsPtr->tclGetIntForIndex) /* 34 */
+/* Slot 35 is reserved */
+/* Slot 36 is reserved */
+#define TclGetLoadedPackages \
+	(tclIntStubsPtr->tclGetLoadedPackages) /* 37 */
+#define TclGetNamespaceForQualName \
+	(tclIntStubsPtr->tclGetNamespaceForQualName) /* 38 */
+#define TclGetObjInterpProc \
+	(tclIntStubsPtr->tclGetObjInterpProc) /* 39 */
+#define TclGetOpenMode \
+	(tclIntStubsPtr->tclGetOpenMode) /* 40 */
+#define TclGetOriginalCommand \
+	(tclIntStubsPtr->tclGetOriginalCommand) /* 41 */
+#define TclpGetUserHome \
+	(tclIntStubsPtr->tclpGetUserHome) /* 42 */
+/* Slot 43 is reserved */
+#define TclGuessPackageName \
+	(tclIntStubsPtr->tclGuessPackageName) /* 44 */
+#define TclHideUnsafeCommands \
+	(tclIntStubsPtr->tclHideUnsafeCommands) /* 45 */
+#define TclInExit \
+	(tclIntStubsPtr->tclInExit) /* 46 */
+/* Slot 47 is reserved */
+/* Slot 48 is reserved */
+/* Slot 49 is reserved */
+#define TclInitCompiledLocals \
+	(tclIntStubsPtr->tclInitCompiledLocals) /* 50 */
+#define TclInterpInit \
+	(tclIntStubsPtr->tclInterpInit) /* 51 */
+/* Slot 52 is reserved */
+#define TclInvokeObjectCommand \
+	(tclIntStubsPtr->tclInvokeObjectCommand) /* 53 */
+#define TclInvokeStringCommand \
+	(tclIntStubsPtr->tclInvokeStringCommand) /* 54 */
+#define TclIsProc \
+	(tclIntStubsPtr->tclIsProc) /* 55 */
+/* Slot 56 is reserved */
+/* Slot 57 is reserved */
+#define TclLookupVar \
+	(tclIntStubsPtr->tclLookupVar) /* 58 */
+/* Slot 59 is reserved */
+#define TclNeedSpace \
+	(tclIntStubsPtr->tclNeedSpace) /* 60 */
+#define TclNewProcBodyObj \
+	(tclIntStubsPtr->tclNewProcBodyObj) /* 61 */
+#define TclObjCommandComplete \
+	(tclIntStubsPtr->tclObjCommandComplete) /* 62 */
+#define TclObjInterpProc \
+	(tclIntStubsPtr->tclObjInterpProc) /* 63 */
+#define TclObjInvoke \
+	(tclIntStubsPtr->tclObjInvoke) /* 64 */
+/* Slot 65 is reserved */
+/* Slot 66 is reserved */
+/* Slot 67 is reserved */
+/* Slot 68 is reserved */
+#define TclpAlloc \
+	(tclIntStubsPtr->tclpAlloc) /* 69 */
+/* Slot 70 is reserved */
+/* Slot 71 is reserved */
+/* Slot 72 is reserved */
+/* Slot 73 is reserved */
+#define TclpFree \
+	(tclIntStubsPtr->tclpFree) /* 74 */
+#define TclpGetClicks \
+	(tclIntStubsPtr->tclpGetClicks) /* 75 */
+#define TclpGetSeconds \
+	(tclIntStubsPtr->tclpGetSeconds) /* 76 */
+#define TclpGetTime \
+	(tclIntStubsPtr->tclpGetTime) /* 77 */
+/* Slot 78 is reserved */
+/* Slot 79 is reserved */
+/* Slot 80 is reserved */
+#define TclpRealloc \
+	(tclIntStubsPtr->tclpRealloc) /* 81 */
+/* Slot 82 is reserved */
+/* Slot 83 is reserved */
+/* Slot 84 is reserved */
+/* Slot 85 is reserved */
+/* Slot 86 is reserved */
+/* Slot 87 is reserved */
+#define TclPrecTraceProc \
+	(tclIntStubsPtr->tclPrecTraceProc) /* 88 */
+#define TclPreventAliasLoop \
+	(tclIntStubsPtr->tclPreventAliasLoop) /* 89 */
+/* Slot 90 is reserved */
+#define TclProcCleanupProc \
+	(tclIntStubsPtr->tclProcCleanupProc) /* 91 */
+#define TclProcCompileProc \
+	(tclIntStubsPtr->tclProcCompileProc) /* 92 */
+#define TclProcDeleteProc \
+	(tclIntStubsPtr->tclProcDeleteProc) /* 93 */
+/* Slot 94 is reserved */
+/* Slot 95 is reserved */
+#define TclRenameCommand \
+	(tclIntStubsPtr->tclRenameCommand) /* 96 */
+#define TclResetShadowedCmdRefs \
+	(tclIntStubsPtr->tclResetShadowedCmdRefs) /* 97 */
+#define TclServiceIdle \
+	(tclIntStubsPtr->tclServiceIdle) /* 98 */
+/* Slot 99 is reserved */
+/* Slot 100 is reserved */
+#define TclSetPreInitScript \
+	(tclIntStubsPtr->tclSetPreInitScript) /* 101 */
+#define TclSetupEnv \
+	(tclIntStubsPtr->tclSetupEnv) /* 102 */
+#define TclSockGetPort \
+	(tclIntStubsPtr->tclSockGetPort) /* 103 */
+#define TclSockMinimumBuffersOld \
+	(tclIntStubsPtr->tclSockMinimumBuffersOld) /* 104 */
+/* Slot 105 is reserved */
+/* Slot 106 is reserved */
+/* Slot 107 is reserved */
+#define TclTeardownNamespace \
+	(tclIntStubsPtr->tclTeardownNamespace) /* 108 */
+#define TclUpdateReturnInfo \
+	(tclIntStubsPtr->tclUpdateReturnInfo) /* 109 */
+#define TclSockMinimumBuffers \
+	(tclIntStubsPtr->tclSockMinimumBuffers) /* 110 */
+#define Tcl_AddInterpResolvers \
+	(tclIntStubsPtr->tcl_AddInterpResolvers) /* 111 */
+#define Tcl_AppendExportList \
+	(tclIntStubsPtr->tcl_AppendExportList) /* 112 */
+#define Tcl_CreateNamespace \
+	(tclIntStubsPtr->tcl_CreateNamespace) /* 113 */
+#define Tcl_DeleteNamespace \
+	(tclIntStubsPtr->tcl_DeleteNamespace) /* 114 */
+#define Tcl_Export \
+	(tclIntStubsPtr->tcl_Export) /* 115 */
+#define Tcl_FindCommand \
+	(tclIntStubsPtr->tcl_FindCommand) /* 116 */
+#define Tcl_FindNamespace \
+	(tclIntStubsPtr->tcl_FindNamespace) /* 117 */
+#define Tcl_GetInterpResolvers \
+	(tclIntStubsPtr->tcl_GetInterpResolvers) /* 118 */
+#define Tcl_GetNamespaceResolvers \
+	(tclIntStubsPtr->tcl_GetNamespaceResolvers) /* 119 */
+#define Tcl_FindNamespaceVar \
+	(tclIntStubsPtr->tcl_FindNamespaceVar) /* 120 */
+#define Tcl_ForgetImport \
+	(tclIntStubsPtr->tcl_ForgetImport) /* 121 */
+#define Tcl_GetCommandFromObj \
+	(tclIntStubsPtr->tcl_GetCommandFromObj) /* 122 */
+#define Tcl_GetCommandFullName \
+	(tclIntStubsPtr->tcl_GetCommandFullName) /* 123 */
+#define Tcl_GetCurrentNamespace \
+	(tclIntStubsPtr->tcl_GetCurrentNamespace) /* 124 */
+#define Tcl_GetGlobalNamespace \
+	(tclIntStubsPtr->tcl_GetGlobalNamespace) /* 125 */
+#define Tcl_GetVariableFullName \
+	(tclIntStubsPtr->tcl_GetVariableFullName) /* 126 */
+#define Tcl_Import \
+	(tclIntStubsPtr->tcl_Import) /* 127 */
+#define Tcl_PopCallFrame \
+	(tclIntStubsPtr->tcl_PopCallFrame) /* 128 */
+#define Tcl_PushCallFrame \
+	(tclIntStubsPtr->tcl_PushCallFrame) /* 129 */
+#define Tcl_RemoveInterpResolvers \
+	(tclIntStubsPtr->tcl_RemoveInterpResolvers) /* 130 */
+#define Tcl_SetNamespaceResolvers \
+	(tclIntStubsPtr->tcl_SetNamespaceResolvers) /* 131 */
+#define TclpHasSockets \
+	(tclIntStubsPtr->tclpHasSockets) /* 132 */
+#define TclpGetDate \
+	(tclIntStubsPtr->tclpGetDate) /* 133 */
+/* Slot 134 is reserved */
+/* Slot 135 is reserved */
+/* Slot 136 is reserved */
+/* Slot 137 is reserved */
+#define TclGetEnv \
+	(tclIntStubsPtr->tclGetEnv) /* 138 */
+/* Slot 139 is reserved */
+/* Slot 140 is reserved */
+#define TclpGetCwd \
+	(tclIntStubsPtr->tclpGetCwd) /* 141 */
+#define TclSetByteCodeFromAny \
+	(tclIntStubsPtr->tclSetByteCodeFromAny) /* 142 */
+#define TclAddLiteralObj \
+	(tclIntStubsPtr->tclAddLiteralObj) /* 143 */
+#define TclHideLiteral \
+	(tclIntStubsPtr->tclHideLiteral) /* 144 */
+#define TclGetAuxDataType \
+	(tclIntStubsPtr->tclGetAuxDataType) /* 145 */
+#define TclHandleCreate \
+	(tclIntStubsPtr->tclHandleCreate) /* 146 */
+#define TclHandleFree \
+	(tclIntStubsPtr->tclHandleFree) /* 147 */
+#define TclHandlePreserve \
+	(tclIntStubsPtr->tclHandlePreserve) /* 148 */
+#define TclHandleRelease \
+	(tclIntStubsPtr->tclHandleRelease) /* 149 */
+#define TclRegAbout \
+	(tclIntStubsPtr->tclRegAbout) /* 150 */
+#define TclRegExpRangeUniChar \
+	(tclIntStubsPtr->tclRegExpRangeUniChar) /* 151 */
+#define TclSetLibraryPath \
+	(tclIntStubsPtr->tclSetLibraryPath) /* 152 */
+#define TclGetLibraryPath \
+	(tclIntStubsPtr->tclGetLibraryPath) /* 153 */
+/* Slot 154 is reserved */
+/* Slot 155 is reserved */
+#define TclRegError \
+	(tclIntStubsPtr->tclRegError) /* 156 */
+#define TclVarTraceExists \
+	(tclIntStubsPtr->tclVarTraceExists) /* 157 */
+#define TclSetStartupScriptFileName \
+	(tclIntStubsPtr->tclSetStartupScriptFileName) /* 158 */
+#define TclGetStartupScriptFileName \
+	(tclIntStubsPtr->tclGetStartupScriptFileName) /* 159 */
+/* Slot 160 is reserved */
+#define TclChannelTransform \
+	(tclIntStubsPtr->tclChannelTransform) /* 161 */
+#define TclChannelEventScriptInvoker \
+	(tclIntStubsPtr->tclChannelEventScriptInvoker) /* 162 */
+#define TclGetInstructionTable \
+	(tclIntStubsPtr->tclGetInstructionTable) /* 163 */
+#define TclExpandCodeArray \
+	(tclIntStubsPtr->tclExpandCodeArray) /* 164 */
+#define TclpSetInitialEncodings \
+	(tclIntStubsPtr->tclpSetInitialEncodings) /* 165 */
+#define TclListObjSetElement \
+	(tclIntStubsPtr->tclListObjSetElement) /* 166 */
+#define TclSetStartupScriptPath \
+	(tclIntStubsPtr->tclSetStartupScriptPath) /* 167 */
+#define TclGetStartupScriptPath \
+	(tclIntStubsPtr->tclGetStartupScriptPath) /* 168 */
+#define TclpUtfNcmp2 \
+	(tclIntStubsPtr->tclpUtfNcmp2) /* 169 */
+#define TclCheckInterpTraces \
+	(tclIntStubsPtr->tclCheckInterpTraces) /* 170 */
+#define TclCheckExecutionTraces \
+	(tclIntStubsPtr->tclCheckExecutionTraces) /* 171 */
+#define TclInThreadExit \
+	(tclIntStubsPtr->tclInThreadExit) /* 172 */
+#define TclUniCharMatch \
+	(tclIntStubsPtr->tclUniCharMatch) /* 173 */
+/* Slot 174 is reserved */
+#define TclCallVarTraces \
+	(tclIntStubsPtr->tclCallVarTraces) /* 175 */
+#define TclCleanupVar \
+	(tclIntStubsPtr->tclCleanupVar) /* 176 */
+#define TclVarErrMsg \
+	(tclIntStubsPtr->tclVarErrMsg) /* 177 */
+#define Tcl_SetStartupScript \
+	(tclIntStubsPtr->tcl_SetStartupScript) /* 178 */
+#define Tcl_GetStartupScript \
+	(tclIntStubsPtr->tcl_GetStartupScript) /* 179 */
+/* Slot 180 is reserved */
+/* Slot 181 is reserved */
+#define TclpLocaltime \
+	(tclIntStubsPtr->tclpLocaltime) /* 182 */
+#define TclpGmtime \
+	(tclIntStubsPtr->tclpGmtime) /* 183 */
+/* Slot 184 is reserved */
+/* Slot 185 is reserved */
+/* Slot 186 is reserved */
+/* Slot 187 is reserved */
+/* Slot 188 is reserved */
+/* Slot 189 is reserved */
+/* Slot 190 is reserved */
+/* Slot 191 is reserved */
+/* Slot 192 is reserved */
+/* Slot 193 is reserved */
+/* Slot 194 is reserved */
+/* Slot 195 is reserved */
+/* Slot 196 is reserved */
+/* Slot 197 is reserved */
+#define TclObjGetFrame \
+	(tclIntStubsPtr->tclObjGetFrame) /* 198 */
+/* Slot 199 is reserved */
+#define TclpObjRemoveDirectory \
+	(tclIntStubsPtr->tclpObjRemoveDirectory) /* 200 */
+#define TclpObjCopyDirectory \
+	(tclIntStubsPtr->tclpObjCopyDirectory) /* 201 */
+#define TclpObjCreateDirectory \
+	(tclIntStubsPtr->tclpObjCreateDirectory) /* 202 */
+#define TclpObjDeleteFile \
+	(tclIntStubsPtr->tclpObjDeleteFile) /* 203 */
+#define TclpObjCopyFile \
+	(tclIntStubsPtr->tclpObjCopyFile) /* 204 */
+#define TclpObjRenameFile \
+	(tclIntStubsPtr->tclpObjRenameFile) /* 205 */
+#define TclpObjStat \
+	(tclIntStubsPtr->tclpObjStat) /* 206 */
+#define TclpObjAccess \
+	(tclIntStubsPtr->tclpObjAccess) /* 207 */
+#define TclpOpenFileChannel \
+	(tclIntStubsPtr->tclpOpenFileChannel) /* 208 */
+/* Slot 209 is reserved */
+/* Slot 210 is reserved */
+/* Slot 211 is reserved */
+#define TclpFindExecutable \
+	(tclIntStubsPtr->tclpFindExecutable) /* 212 */
+#define TclGetObjNameOfExecutable \
+	(tclIntStubsPtr->tclGetObjNameOfExecutable) /* 213 */
+#define TclSetObjNameOfExecutable \
+	(tclIntStubsPtr->tclSetObjNameOfExecutable) /* 214 */
+#define TclStackAlloc \
+	(tclIntStubsPtr->tclStackAlloc) /* 215 */
+#define TclStackFree \
+	(tclIntStubsPtr->tclStackFree) /* 216 */
+#define TclPushStackFrame \
+	(tclIntStubsPtr->tclPushStackFrame) /* 217 */
+#define TclPopStackFrame \
+	(tclIntStubsPtr->tclPopStackFrame) /* 218 */
+/* Slot 219 is reserved */
+/* Slot 220 is reserved */
+/* Slot 221 is reserved */
+/* Slot 222 is reserved */
+/* Slot 223 is reserved */
+#define TclGetPlatform \
+	(tclIntStubsPtr->tclGetPlatform) /* 224 */
+#define TclTraceDictPath \
+	(tclIntStubsPtr->tclTraceDictPath) /* 225 */
+#define TclObjBeingDeleted \
+	(tclIntStubsPtr->tclObjBeingDeleted) /* 226 */
+#define TclSetNsPath \
+	(tclIntStubsPtr->tclSetNsPath) /* 227 */
+/* Slot 228 is reserved */
+#define TclPtrMakeUpvar \
+	(tclIntStubsPtr->tclPtrMakeUpvar) /* 229 */
+#define TclObjLookupVar \
+	(tclIntStubsPtr->tclObjLookupVar) /* 230 */
+#define TclGetNamespaceFromObj \
+	(tclIntStubsPtr->tclGetNamespaceFromObj) /* 231 */
+#define TclEvalObjEx \
+	(tclIntStubsPtr->tclEvalObjEx) /* 232 */
+#define TclGetSrcInfoForPc \
+	(tclIntStubsPtr->tclGetSrcInfoForPc) /* 233 */
+#define TclVarHashCreateVar \
+	(tclIntStubsPtr->tclVarHashCreateVar) /* 234 */
+#define TclInitVarHashTable \
+	(tclIntStubsPtr->tclInitVarHashTable) /* 235 */
+#define TclBackgroundException \
+	(tclIntStubsPtr->tclBackgroundException) /* 236 */
+#define TclResetCancellation \
+	(tclIntStubsPtr->tclResetCancellation) /* 237 */
+#define TclNRInterpProc \
+	(tclIntStubsPtr->tclNRInterpProc) /* 238 */
+#define TclNRInterpProcCore \
+	(tclIntStubsPtr->tclNRInterpProcCore) /* 239 */
+#define TclNRRunCallbacks \
+	(tclIntStubsPtr->tclNRRunCallbacks) /* 240 */
+#define TclNREvalObjEx \
+	(tclIntStubsPtr->tclNREvalObjEx) /* 241 */
+#define TclNREvalObjv \
+	(tclIntStubsPtr->tclNREvalObjv) /* 242 */
+#define TclDbDumpActiveObjects \
+	(tclIntStubsPtr->tclDbDumpActiveObjects) /* 243 */
+#define TclGetNamespaceChildTable \
+	(tclIntStubsPtr->tclGetNamespaceChildTable) /* 244 */
+#define TclGetNamespaceCommandTable \
+	(tclIntStubsPtr->tclGetNamespaceCommandTable) /* 245 */
+#define TclInitRewriteEnsemble \
+	(tclIntStubsPtr->tclInitRewriteEnsemble) /* 246 */
+#define TclResetRewriteEnsemble \
+	(tclIntStubsPtr->tclResetRewriteEnsemble) /* 247 */
+#define TclCopyChannel \
+	(tclIntStubsPtr->tclCopyChannel) /* 248 */
+#define TclDoubleDigits \
+	(tclIntStubsPtr->tclDoubleDigits) /* 249 */
+#define TclSetSlaveCancelFlags \
+	(tclIntStubsPtr->tclSetSlaveCancelFlags) /* 250 */
+#define TclRegisterLiteral \
+	(tclIntStubsPtr->tclRegisterLiteral) /* 251 */
+
+#endif /* defined(USE_TCL_STUBS) */
+
+/* !END!: Do not edit above this line. */
+
+#undef TCL_STORAGE_CLASS
+#define TCL_STORAGE_CLASS DLLIMPORT
+
+#undef TclGetStartupScriptFileName
+#undef TclSetStartupScriptFileName
+#undef TclGetStartupScriptPath
+#undef TclSetStartupScriptPath
+#undef TclBackgroundException
+
+#if defined(USE_TCL_STUBS) && defined(TCL_NO_DEPRECATED)
+#   undef Tcl_SetStartupScript
+#   define Tcl_SetStartupScript \
+	    (tclStubsPtr->tcl_SetStartupScript) /* 622 */
+#   undef Tcl_GetStartupScript
+#   define Tcl_GetStartupScript \
+	    (tclStubsPtr->tcl_GetStartupScript) /* 623 */
+#   undef Tcl_CreateNamespace
+#   define Tcl_CreateNamespace \
+	   (tclStubsPtr->tcl_CreateNamespace) /* 506 */
+#   undef Tcl_DeleteNamespace
+#   define Tcl_DeleteNamespace \
+	   (tclStubsPtr->tcl_DeleteNamespace) /* 507 */
+#   undef Tcl_AppendExportList
+#   define Tcl_AppendExportList \
+	   (tclStubsPtr->tcl_AppendExportList) /* 508 */
+#   undef Tcl_Export
+#   define Tcl_Export \
+	   (tclStubsPtr->tcl_Export) /* 509 */
+#   undef Tcl_Import
+#   define Tcl_Import \
+	   (tclStubsPtr->tcl_Import) /* 510 */
+#   undef Tcl_ForgetImport
+#   define Tcl_ForgetImport \
+	   (tclStubsPtr->tcl_ForgetImport) /* 511 */
+#   undef Tcl_GetCurrentNamespace
+#   define Tcl_GetCurrentNamespace \
+	   (tclStubsPtr->tcl_GetCurrentNamespace) /* 512 */
+#   undef Tcl_GetGlobalNamespace
+#   define Tcl_GetGlobalNamespace \
+	   (tclStubsPtr->tcl_GetGlobalNamespace) /* 513 */
+#   undef Tcl_FindNamespace
+#   define Tcl_FindNamespace \
+	   (tclStubsPtr->tcl_FindNamespace) /* 514 */
+#   undef Tcl_FindCommand
+#   define Tcl_FindCommand \
+	   (tclStubsPtr->tcl_FindCommand) /* 515 */
+#   undef Tcl_GetCommandFromObj
+#   define Tcl_GetCommandFromObj \
+	   (tclStubsPtr->tcl_GetCommandFromObj) /* 516 */
+#   undef Tcl_GetCommandFullName
+#   define Tcl_GetCommandFullName \
+	   (tclStubsPtr->tcl_GetCommandFullName) /* 517 */
+#endif
+
+#undef TclCopyChannelOld
+#undef TclSockMinimumBuffersOld
+
+#endif /* _TCLINTDECLS */
diff --git a/generic/tclIntPlatDecls.h b/generic/tclIntPlatDecls.h
new file mode 100644
index 0000000..ac06787
--- /dev/null
+++ b/generic/tclIntPlatDecls.h
@@ -0,0 +1,567 @@
+/*
+ * tclIntPlatDecls.h --
+ *
+ *	This file contains the declarations for all platform dependent
+ *	unsupported functions that are exported by the Tcl library.  These
+ *	interfaces are not guaranteed to remain the same between
+ *	versions.  Use at your own risk.
+ *
+ * Copyright (c) 1998-1999 by Scriptics Corporation.
+ * All rights reserved.
+ */
+
+#ifndef _TCLINTPLATDECLS
+#define _TCLINTPLATDECLS
+
+#ifdef _WIN32
+#   define Tcl_DirEntry void
+#   define DIR void
+#endif
+
+#undef TCL_STORAGE_CLASS
+#ifdef BUILD_tcl
+#   define TCL_STORAGE_CLASS DLLEXPORT
+#else
+#   ifdef USE_TCL_STUBS
+#      define TCL_STORAGE_CLASS
+#   else
+#      define TCL_STORAGE_CLASS DLLIMPORT
+#   endif
+#endif
+
+/*
+ * WARNING: This file is automatically generated by the tools/genStubs.tcl
+ * script.  Any modifications to the function declarations below should be made
+ * in the generic/tclInt.decls script.
+ */
+
+/* !BEGIN!: Do not edit below this line. */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Exported function declarations:
+ */
+
+#if !defined(_WIN32) && !defined(__CYGWIN__) && !defined(MAC_OSX_TCL) /* UNIX */
+/* 0 */
+EXTERN void		TclGetAndDetachPids(Tcl_Interp *interp,
+				Tcl_Channel chan);
+/* 1 */
+EXTERN int		TclpCloseFile(TclFile file);
+/* 2 */
+EXTERN Tcl_Channel	TclpCreateCommandChannel(TclFile readFile,
+				TclFile writeFile, TclFile errorFile,
+				int numPids, Tcl_Pid *pidPtr);
+/* 3 */
+EXTERN int		TclpCreatePipe(TclFile *readPipe, TclFile *writePipe);
+/* 4 */
+EXTERN int		TclpCreateProcess(Tcl_Interp *interp, int argc,
+				const char **argv, TclFile inputFile,
+				TclFile outputFile, TclFile errorFile,
+				Tcl_Pid *pidPtr);
+/* Slot 5 is reserved */
+/* 6 */
+EXTERN TclFile		TclpMakeFile(Tcl_Channel channel, int direction);
+/* 7 */
+EXTERN TclFile		TclpOpenFile(const char *fname, int mode);
+/* 8 */
+EXTERN int		TclUnixWaitForFile(int fd, int mask, int timeout);
+/* 9 */
+EXTERN TclFile		TclpCreateTempFile(const char *contents);
+/* 10 */
+EXTERN Tcl_DirEntry *	TclpReaddir(DIR *dir);
+/* 11 */
+EXTERN struct tm *	TclpLocaltime_unix(const time_t *clock);
+/* 12 */
+EXTERN struct tm *	TclpGmtime_unix(const time_t *clock);
+/* 13 */
+EXTERN char *		TclpInetNtoa(struct in_addr addr);
+/* 14 */
+EXTERN int		TclUnixCopyFile(const char *src, const char *dst,
+				const Tcl_StatBuf *statBufPtr,
+				int dontCopyAtts);
+/* Slot 15 is reserved */
+/* Slot 16 is reserved */
+/* Slot 17 is reserved */
+/* Slot 18 is reserved */
+/* Slot 19 is reserved */
+/* Slot 20 is reserved */
+/* Slot 21 is reserved */
+/* Slot 22 is reserved */
+/* Slot 23 is reserved */
+/* Slot 24 is reserved */
+/* Slot 25 is reserved */
+/* Slot 26 is reserved */
+/* Slot 27 is reserved */
+/* Slot 28 is reserved */
+/* 29 */
+EXTERN int		TclWinCPUID(unsigned int index, unsigned int *regs);
+/* 30 */
+EXTERN int		TclUnixOpenTemporaryFile(Tcl_Obj *dirObj,
+				Tcl_Obj *basenameObj, Tcl_Obj *extensionObj,
+				Tcl_Obj *resultingNameObj);
+#endif /* UNIX */
+#if defined(_WIN32) || defined(__CYGWIN__) /* WIN */
+/* 0 */
+EXTERN void		TclWinConvertError(DWORD errCode);
+/* 1 */
+EXTERN void		TclWinConvertWSAError(DWORD errCode);
+/* 2 */
+EXTERN struct servent *	 TclWinGetServByName(const char *nm,
+				const char *proto);
+/* 3 */
+EXTERN int		TclWinGetSockOpt(SOCKET s, int level, int optname,
+				char *optval, int *optlen);
+/* 4 */
+EXTERN HINSTANCE	TclWinGetTclInstance(void);
+/* 5 */
+EXTERN int		TclUnixWaitForFile(int fd, int mask, int timeout);
+/* 6 */
+EXTERN unsigned short	TclWinNToHS(unsigned short ns);
+/* 7 */
+EXTERN int		TclWinSetSockOpt(SOCKET s, int level, int optname,
+				const char *optval, int optlen);
+/* 8 */
+EXTERN int		TclpGetPid(Tcl_Pid pid);
+/* 9 */
+EXTERN int		TclWinGetPlatformId(void);
+/* 10 */
+EXTERN Tcl_DirEntry *	TclpReaddir(DIR *dir);
+/* 11 */
+EXTERN void		TclGetAndDetachPids(Tcl_Interp *interp,
+				Tcl_Channel chan);
+/* 12 */
+EXTERN int		TclpCloseFile(TclFile file);
+/* 13 */
+EXTERN Tcl_Channel	TclpCreateCommandChannel(TclFile readFile,
+				TclFile writeFile, TclFile errorFile,
+				int numPids, Tcl_Pid *pidPtr);
+/* 14 */
+EXTERN int		TclpCreatePipe(TclFile *readPipe, TclFile *writePipe);
+/* 15 */
+EXTERN int		TclpCreateProcess(Tcl_Interp *interp, int argc,
+				const char **argv, TclFile inputFile,
+				TclFile outputFile, TclFile errorFile,
+				Tcl_Pid *pidPtr);
+/* 16 */
+EXTERN int		TclpIsAtty(int fd);
+/* 17 */
+EXTERN int		TclUnixCopyFile(const char *src, const char *dst,
+				const Tcl_StatBuf *statBufPtr,
+				int dontCopyAtts);
+/* 18 */
+EXTERN TclFile		TclpMakeFile(Tcl_Channel channel, int direction);
+/* 19 */
+EXTERN TclFile		TclpOpenFile(const char *fname, int mode);
+/* 20 */
+EXTERN void		TclWinAddProcess(HANDLE hProcess, DWORD id);
+/* 21 */
+EXTERN char *		TclpInetNtoa(struct in_addr addr);
+/* 22 */
+EXTERN TclFile		TclpCreateTempFile(const char *contents);
+/* Slot 23 is reserved */
+/* 24 */
+EXTERN char *		TclWinNoBackslash(char *path);
+/* Slot 25 is reserved */
+/* 26 */
+EXTERN void		TclWinSetInterfaces(int wide);
+/* 27 */
+EXTERN void		TclWinFlushDirtyChannels(void);
+/* 28 */
+EXTERN void		TclWinResetInterfaces(void);
+/* 29 */
+EXTERN int		TclWinCPUID(unsigned int index, unsigned int *regs);
+/* 30 */
+EXTERN int		TclUnixOpenTemporaryFile(Tcl_Obj *dirObj,
+				Tcl_Obj *basenameObj, Tcl_Obj *extensionObj,
+				Tcl_Obj *resultingNameObj);
+#endif /* WIN */
+#ifdef MAC_OSX_TCL /* MACOSX */
+/* 0 */
+EXTERN void		TclGetAndDetachPids(Tcl_Interp *interp,
+				Tcl_Channel chan);
+/* 1 */
+EXTERN int		TclpCloseFile(TclFile file);
+/* 2 */
+EXTERN Tcl_Channel	TclpCreateCommandChannel(TclFile readFile,
+				TclFile writeFile, TclFile errorFile,
+				int numPids, Tcl_Pid *pidPtr);
+/* 3 */
+EXTERN int		TclpCreatePipe(TclFile *readPipe, TclFile *writePipe);
+/* 4 */
+EXTERN int		TclpCreateProcess(Tcl_Interp *interp, int argc,
+				const char **argv, TclFile inputFile,
+				TclFile outputFile, TclFile errorFile,
+				Tcl_Pid *pidPtr);
+/* Slot 5 is reserved */
+/* 6 */
+EXTERN TclFile		TclpMakeFile(Tcl_Channel channel, int direction);
+/* 7 */
+EXTERN TclFile		TclpOpenFile(const char *fname, int mode);
+/* 8 */
+EXTERN int		TclUnixWaitForFile(int fd, int mask, int timeout);
+/* 9 */
+EXTERN TclFile		TclpCreateTempFile(const char *contents);
+/* 10 */
+EXTERN Tcl_DirEntry *	TclpReaddir(DIR *dir);
+/* 11 */
+EXTERN struct tm *	TclpLocaltime_unix(const time_t *clock);
+/* 12 */
+EXTERN struct tm *	TclpGmtime_unix(const time_t *clock);
+/* 13 */
+EXTERN char *		TclpInetNtoa(struct in_addr addr);
+/* 14 */
+EXTERN int		TclUnixCopyFile(const char *src, const char *dst,
+				const Tcl_StatBuf *statBufPtr,
+				int dontCopyAtts);
+/* 15 */
+EXTERN int		TclMacOSXGetFileAttribute(Tcl_Interp *interp,
+				int objIndex, Tcl_Obj *fileName,
+				Tcl_Obj **attributePtrPtr);
+/* 16 */
+EXTERN int		TclMacOSXSetFileAttribute(Tcl_Interp *interp,
+				int objIndex, Tcl_Obj *fileName,
+				Tcl_Obj *attributePtr);
+/* 17 */
+EXTERN int		TclMacOSXCopyFileAttributes(const char *src,
+				const char *dst,
+				const Tcl_StatBuf *statBufPtr);
+/* 18 */
+EXTERN int		TclMacOSXMatchType(Tcl_Interp *interp,
+				const char *pathName, const char *fileName,
+				Tcl_StatBuf *statBufPtr,
+				Tcl_GlobTypeData *types);
+/* 19 */
+EXTERN void		TclMacOSXNotifierAddRunLoopMode(
+				const void *runLoopMode);
+/* Slot 20 is reserved */
+/* Slot 21 is reserved */
+/* Slot 22 is reserved */
+/* Slot 23 is reserved */
+/* Slot 24 is reserved */
+/* Slot 25 is reserved */
+/* Slot 26 is reserved */
+/* Slot 27 is reserved */
+/* Slot 28 is reserved */
+/* 29 */
+EXTERN int		TclWinCPUID(unsigned int index, unsigned int *regs);
+/* 30 */
+EXTERN int		TclUnixOpenTemporaryFile(Tcl_Obj *dirObj,
+				Tcl_Obj *basenameObj, Tcl_Obj *extensionObj,
+				Tcl_Obj *resultingNameObj);
+#endif /* MACOSX */
+
+typedef struct TclIntPlatStubs {
+    int magic;
+    void *hooks;
+
+#if !defined(_WIN32) && !defined(__CYGWIN__) && !defined(MAC_OSX_TCL) /* UNIX */
+    void (*tclGetAndDetachPids) (Tcl_Interp *interp, Tcl_Channel chan); /* 0 */
+    int (*tclpCloseFile) (TclFile file); /* 1 */
+    Tcl_Channel (*tclpCreateCommandChannel) (TclFile readFile, TclFile writeFile, TclFile errorFile, int numPids, Tcl_Pid *pidPtr); /* 2 */
+    int (*tclpCreatePipe) (TclFile *readPipe, TclFile *writePipe); /* 3 */
+    int (*tclpCreateProcess) (Tcl_Interp *interp, int argc, const char **argv, TclFile inputFile, TclFile outputFile, TclFile errorFile, Tcl_Pid *pidPtr); /* 4 */
+    void (*reserved5)(void);
+    TclFile (*tclpMakeFile) (Tcl_Channel channel, int direction); /* 6 */
+    TclFile (*tclpOpenFile) (const char *fname, int mode); /* 7 */
+    int (*tclUnixWaitForFile) (int fd, int mask, int timeout); /* 8 */
+    TclFile (*tclpCreateTempFile) (const char *contents); /* 9 */
+    Tcl_DirEntry * (*tclpReaddir) (DIR *dir); /* 10 */
+    struct tm * (*tclpLocaltime_unix) (const time_t *clock); /* 11 */
+    struct tm * (*tclpGmtime_unix) (const time_t *clock); /* 12 */
+    char * (*tclpInetNtoa) (struct in_addr addr); /* 13 */
+    int (*tclUnixCopyFile) (const char *src, const char *dst, const Tcl_StatBuf *statBufPtr, int dontCopyAtts); /* 14 */
+    void (*reserved15)(void);
+    void (*reserved16)(void);
+    void (*reserved17)(void);
+    void (*reserved18)(void);
+    void (*reserved19)(void);
+    void (*reserved20)(void);
+    void (*reserved21)(void);
+    void (*reserved22)(void);
+    void (*reserved23)(void);
+    void (*reserved24)(void);
+    void (*reserved25)(void);
+    void (*reserved26)(void);
+    void (*reserved27)(void);
+    void (*reserved28)(void);
+    int (*tclWinCPUID) (unsigned int index, unsigned int *regs); /* 29 */
+    int (*tclUnixOpenTemporaryFile) (Tcl_Obj *dirObj, Tcl_Obj *basenameObj, Tcl_Obj *extensionObj, Tcl_Obj *resultingNameObj); /* 30 */
+#endif /* UNIX */
+#if defined(_WIN32) || defined(__CYGWIN__) /* WIN */
+    void (*tclWinConvertError) (DWORD errCode); /* 0 */
+    void (*tclWinConvertWSAError) (DWORD errCode); /* 1 */
+    struct servent * (*tclWinGetServByName) (const char *nm, const char *proto); /* 2 */
+    int (*tclWinGetSockOpt) (SOCKET s, int level, int optname, char *optval, int *optlen); /* 3 */
+    HINSTANCE (*tclWinGetTclInstance) (void); /* 4 */
+    int (*tclUnixWaitForFile) (int fd, int mask, int timeout); /* 5 */
+    unsigned short (*tclWinNToHS) (unsigned short ns); /* 6 */
+    int (*tclWinSetSockOpt) (SOCKET s, int level, int optname, const char *optval, int optlen); /* 7 */
+    int (*tclpGetPid) (Tcl_Pid pid); /* 8 */
+    int (*tclWinGetPlatformId) (void); /* 9 */
+    Tcl_DirEntry * (*tclpReaddir) (DIR *dir); /* 10 */
+    void (*tclGetAndDetachPids) (Tcl_Interp *interp, Tcl_Channel chan); /* 11 */
+    int (*tclpCloseFile) (TclFile file); /* 12 */
+    Tcl_Channel (*tclpCreateCommandChannel) (TclFile readFile, TclFile writeFile, TclFile errorFile, int numPids, Tcl_Pid *pidPtr); /* 13 */
+    int (*tclpCreatePipe) (TclFile *readPipe, TclFile *writePipe); /* 14 */
+    int (*tclpCreateProcess) (Tcl_Interp *interp, int argc, const char **argv, TclFile inputFile, TclFile outputFile, TclFile errorFile, Tcl_Pid *pidPtr); /* 15 */
+    int (*tclpIsAtty) (int fd); /* 16 */
+    int (*tclUnixCopyFile) (const char *src, const char *dst, const Tcl_StatBuf *statBufPtr, int dontCopyAtts); /* 17 */
+    TclFile (*tclpMakeFile) (Tcl_Channel channel, int direction); /* 18 */
+    TclFile (*tclpOpenFile) (const char *fname, int mode); /* 19 */
+    void (*tclWinAddProcess) (HANDLE hProcess, DWORD id); /* 20 */
+    char * (*tclpInetNtoa) (struct in_addr addr); /* 21 */
+    TclFile (*tclpCreateTempFile) (const char *contents); /* 22 */
+    void (*reserved23)(void);
+    char * (*tclWinNoBackslash) (char *path); /* 24 */
+    void (*reserved25)(void);
+    void (*tclWinSetInterfaces) (int wide); /* 26 */
+    void (*tclWinFlushDirtyChannels) (void); /* 27 */
+    void (*tclWinResetInterfaces) (void); /* 28 */
+    int (*tclWinCPUID) (unsigned int index, unsigned int *regs); /* 29 */
+    int (*tclUnixOpenTemporaryFile) (Tcl_Obj *dirObj, Tcl_Obj *basenameObj, Tcl_Obj *extensionObj, Tcl_Obj *resultingNameObj); /* 30 */
+#endif /* WIN */
+#ifdef MAC_OSX_TCL /* MACOSX */
+    void (*tclGetAndDetachPids) (Tcl_Interp *interp, Tcl_Channel chan); /* 0 */
+    int (*tclpCloseFile) (TclFile file); /* 1 */
+    Tcl_Channel (*tclpCreateCommandChannel) (TclFile readFile, TclFile writeFile, TclFile errorFile, int numPids, Tcl_Pid *pidPtr); /* 2 */
+    int (*tclpCreatePipe) (TclFile *readPipe, TclFile *writePipe); /* 3 */
+    int (*tclpCreateProcess) (Tcl_Interp *interp, int argc, const char **argv, TclFile inputFile, TclFile outputFile, TclFile errorFile, Tcl_Pid *pidPtr); /* 4 */
+    void (*reserved5)(void);
+    TclFile (*tclpMakeFile) (Tcl_Channel channel, int direction); /* 6 */
+    TclFile (*tclpOpenFile) (const char *fname, int mode); /* 7 */
+    int (*tclUnixWaitForFile) (int fd, int mask, int timeout); /* 8 */
+    TclFile (*tclpCreateTempFile) (const char *contents); /* 9 */
+    Tcl_DirEntry * (*tclpReaddir) (DIR *dir); /* 10 */
+    struct tm * (*tclpLocaltime_unix) (const time_t *clock); /* 11 */
+    struct tm * (*tclpGmtime_unix) (const time_t *clock); /* 12 */
+    char * (*tclpInetNtoa) (struct in_addr addr); /* 13 */
+    int (*tclUnixCopyFile) (const char *src, const char *dst, const Tcl_StatBuf *statBufPtr, int dontCopyAtts); /* 14 */
+    int (*tclMacOSXGetFileAttribute) (Tcl_Interp *interp, int objIndex, Tcl_Obj *fileName, Tcl_Obj **attributePtrPtr); /* 15 */
+    int (*tclMacOSXSetFileAttribute) (Tcl_Interp *interp, int objIndex, Tcl_Obj *fileName, Tcl_Obj *attributePtr); /* 16 */
+    int (*tclMacOSXCopyFileAttributes) (const char *src, const char *dst, const Tcl_StatBuf *statBufPtr); /* 17 */
+    int (*tclMacOSXMatchType) (Tcl_Interp *interp, const char *pathName, const char *fileName, Tcl_StatBuf *statBufPtr, Tcl_GlobTypeData *types); /* 18 */
+    void (*tclMacOSXNotifierAddRunLoopMode) (const void *runLoopMode); /* 19 */
+    void (*reserved20)(void);
+    void (*reserved21)(void);
+    void (*reserved22)(void);
+    void (*reserved23)(void);
+    void (*reserved24)(void);
+    void (*reserved25)(void);
+    void (*reserved26)(void);
+    void (*reserved27)(void);
+    void (*reserved28)(void);
+    int (*tclWinCPUID) (unsigned int index, unsigned int *regs); /* 29 */
+    int (*tclUnixOpenTemporaryFile) (Tcl_Obj *dirObj, Tcl_Obj *basenameObj, Tcl_Obj *extensionObj, Tcl_Obj *resultingNameObj); /* 30 */
+#endif /* MACOSX */
+} TclIntPlatStubs;
+
+extern const TclIntPlatStubs *tclIntPlatStubsPtr;
+
+#ifdef __cplusplus
+}
+#endif
+
+#if defined(USE_TCL_STUBS)
+
+/*
+ * Inline function declarations:
+ */
+
+#if !defined(_WIN32) && !defined(__CYGWIN__) && !defined(MAC_OSX_TCL) /* UNIX */
+#define TclGetAndDetachPids \
+	(tclIntPlatStubsPtr->tclGetAndDetachPids) /* 0 */
+#define TclpCloseFile \
+	(tclIntPlatStubsPtr->tclpCloseFile) /* 1 */
+#define TclpCreateCommandChannel \
+	(tclIntPlatStubsPtr->tclpCreateCommandChannel) /* 2 */
+#define TclpCreatePipe \
+	(tclIntPlatStubsPtr->tclpCreatePipe) /* 3 */
+#define TclpCreateProcess \
+	(tclIntPlatStubsPtr->tclpCreateProcess) /* 4 */
+/* Slot 5 is reserved */
+#define TclpMakeFile \
+	(tclIntPlatStubsPtr->tclpMakeFile) /* 6 */
+#define TclpOpenFile \
+	(tclIntPlatStubsPtr->tclpOpenFile) /* 7 */
+#define TclUnixWaitForFile \
+	(tclIntPlatStubsPtr->tclUnixWaitForFile) /* 8 */
+#define TclpCreateTempFile \
+	(tclIntPlatStubsPtr->tclpCreateTempFile) /* 9 */
+#define TclpReaddir \
+	(tclIntPlatStubsPtr->tclpReaddir) /* 10 */
+#define TclpLocaltime_unix \
+	(tclIntPlatStubsPtr->tclpLocaltime_unix) /* 11 */
+#define TclpGmtime_unix \
+	(tclIntPlatStubsPtr->tclpGmtime_unix) /* 12 */
+#define TclpInetNtoa \
+	(tclIntPlatStubsPtr->tclpInetNtoa) /* 13 */
+#define TclUnixCopyFile \
+	(tclIntPlatStubsPtr->tclUnixCopyFile) /* 14 */
+/* Slot 15 is reserved */
+/* Slot 16 is reserved */
+/* Slot 17 is reserved */
+/* Slot 18 is reserved */
+/* Slot 19 is reserved */
+/* Slot 20 is reserved */
+/* Slot 21 is reserved */
+/* Slot 22 is reserved */
+/* Slot 23 is reserved */
+/* Slot 24 is reserved */
+/* Slot 25 is reserved */
+/* Slot 26 is reserved */
+/* Slot 27 is reserved */
+/* Slot 28 is reserved */
+#define TclWinCPUID \
+	(tclIntPlatStubsPtr->tclWinCPUID) /* 29 */
+#define TclUnixOpenTemporaryFile \
+	(tclIntPlatStubsPtr->tclUnixOpenTemporaryFile) /* 30 */
+#endif /* UNIX */
+#if defined(_WIN32) || defined(__CYGWIN__) /* WIN */
+#define TclWinConvertError \
+	(tclIntPlatStubsPtr->tclWinConvertError) /* 0 */
+#define TclWinConvertWSAError \
+	(tclIntPlatStubsPtr->tclWinConvertWSAError) /* 1 */
+#define TclWinGetServByName \
+	(tclIntPlatStubsPtr->tclWinGetServByName) /* 2 */
+#define TclWinGetSockOpt \
+	(tclIntPlatStubsPtr->tclWinGetSockOpt) /* 3 */
+#define TclWinGetTclInstance \
+	(tclIntPlatStubsPtr->tclWinGetTclInstance) /* 4 */
+#define TclUnixWaitForFile \
+	(tclIntPlatStubsPtr->tclUnixWaitForFile) /* 5 */
+#define TclWinNToHS \
+	(tclIntPlatStubsPtr->tclWinNToHS) /* 6 */
+#define TclWinSetSockOpt \
+	(tclIntPlatStubsPtr->tclWinSetSockOpt) /* 7 */
+#define TclpGetPid \
+	(tclIntPlatStubsPtr->tclpGetPid) /* 8 */
+#define TclWinGetPlatformId \
+	(tclIntPlatStubsPtr->tclWinGetPlatformId) /* 9 */
+#define TclpReaddir \
+	(tclIntPlatStubsPtr->tclpReaddir) /* 10 */
+#define TclGetAndDetachPids \
+	(tclIntPlatStubsPtr->tclGetAndDetachPids) /* 11 */
+#define TclpCloseFile \
+	(tclIntPlatStubsPtr->tclpCloseFile) /* 12 */
+#define TclpCreateCommandChannel \
+	(tclIntPlatStubsPtr->tclpCreateCommandChannel) /* 13 */
+#define TclpCreatePipe \
+	(tclIntPlatStubsPtr->tclpCreatePipe) /* 14 */
+#define TclpCreateProcess \
+	(tclIntPlatStubsPtr->tclpCreateProcess) /* 15 */
+#define TclpIsAtty \
+	(tclIntPlatStubsPtr->tclpIsAtty) /* 16 */
+#define TclUnixCopyFile \
+	(tclIntPlatStubsPtr->tclUnixCopyFile) /* 17 */
+#define TclpMakeFile \
+	(tclIntPlatStubsPtr->tclpMakeFile) /* 18 */
+#define TclpOpenFile \
+	(tclIntPlatStubsPtr->tclpOpenFile) /* 19 */
+#define TclWinAddProcess \
+	(tclIntPlatStubsPtr->tclWinAddProcess) /* 20 */
+#define TclpInetNtoa \
+	(tclIntPlatStubsPtr->tclpInetNtoa) /* 21 */
+#define TclpCreateTempFile \
+	(tclIntPlatStubsPtr->tclpCreateTempFile) /* 22 */
+/* Slot 23 is reserved */
+#define TclWinNoBackslash \
+	(tclIntPlatStubsPtr->tclWinNoBackslash) /* 24 */
+/* Slot 25 is reserved */
+#define TclWinSetInterfaces \
+	(tclIntPlatStubsPtr->tclWinSetInterfaces) /* 26 */
+#define TclWinFlushDirtyChannels \
+	(tclIntPlatStubsPtr->tclWinFlushDirtyChannels) /* 27 */
+#define TclWinResetInterfaces \
+	(tclIntPlatStubsPtr->tclWinResetInterfaces) /* 28 */
+#define TclWinCPUID \
+	(tclIntPlatStubsPtr->tclWinCPUID) /* 29 */
+#define TclUnixOpenTemporaryFile \
+	(tclIntPlatStubsPtr->tclUnixOpenTemporaryFile) /* 30 */
+#endif /* WIN */
+#ifdef MAC_OSX_TCL /* MACOSX */
+#define TclGetAndDetachPids \
+	(tclIntPlatStubsPtr->tclGetAndDetachPids) /* 0 */
+#define TclpCloseFile \
+	(tclIntPlatStubsPtr->tclpCloseFile) /* 1 */
+#define TclpCreateCommandChannel \
+	(tclIntPlatStubsPtr->tclpCreateCommandChannel) /* 2 */
+#define TclpCreatePipe \
+	(tclIntPlatStubsPtr->tclpCreatePipe) /* 3 */
+#define TclpCreateProcess \
+	(tclIntPlatStubsPtr->tclpCreateProcess) /* 4 */
+/* Slot 5 is reserved */
+#define TclpMakeFile \
+	(tclIntPlatStubsPtr->tclpMakeFile) /* 6 */
+#define TclpOpenFile \
+	(tclIntPlatStubsPtr->tclpOpenFile) /* 7 */
+#define TclUnixWaitForFile \
+	(tclIntPlatStubsPtr->tclUnixWaitForFile) /* 8 */
+#define TclpCreateTempFile \
+	(tclIntPlatStubsPtr->tclpCreateTempFile) /* 9 */
+#define TclpReaddir \
+	(tclIntPlatStubsPtr->tclpReaddir) /* 10 */
+#define TclpLocaltime_unix \
+	(tclIntPlatStubsPtr->tclpLocaltime_unix) /* 11 */
+#define TclpGmtime_unix \
+	(tclIntPlatStubsPtr->tclpGmtime_unix) /* 12 */
+#define TclpInetNtoa \
+	(tclIntPlatStubsPtr->tclpInetNtoa) /* 13 */
+#define TclUnixCopyFile \
+	(tclIntPlatStubsPtr->tclUnixCopyFile) /* 14 */
+#define TclMacOSXGetFileAttribute \
+	(tclIntPlatStubsPtr->tclMacOSXGetFileAttribute) /* 15 */
+#define TclMacOSXSetFileAttribute \
+	(tclIntPlatStubsPtr->tclMacOSXSetFileAttribute) /* 16 */
+#define TclMacOSXCopyFileAttributes \
+	(tclIntPlatStubsPtr->tclMacOSXCopyFileAttributes) /* 17 */
+#define TclMacOSXMatchType \
+	(tclIntPlatStubsPtr->tclMacOSXMatchType) /* 18 */
+#define TclMacOSXNotifierAddRunLoopMode \
+	(tclIntPlatStubsPtr->tclMacOSXNotifierAddRunLoopMode) /* 19 */
+/* Slot 20 is reserved */
+/* Slot 21 is reserved */
+/* Slot 22 is reserved */
+/* Slot 23 is reserved */
+/* Slot 24 is reserved */
+/* Slot 25 is reserved */
+/* Slot 26 is reserved */
+/* Slot 27 is reserved */
+/* Slot 28 is reserved */
+#define TclWinCPUID \
+	(tclIntPlatStubsPtr->tclWinCPUID) /* 29 */
+#define TclUnixOpenTemporaryFile \
+	(tclIntPlatStubsPtr->tclUnixOpenTemporaryFile) /* 30 */
+#endif /* MACOSX */
+
+#endif /* defined(USE_TCL_STUBS) */
+
+/* !END!: Do not edit above this line. */
+
+#undef TCL_STORAGE_CLASS
+#define TCL_STORAGE_CLASS DLLIMPORT
+#undef TclpLocaltime_unix
+#undef TclpGmtime_unix
+#undef TclWinConvertWSAError
+#define TclWinConvertWSAError TclWinConvertError
+#undef TclpInetNtoa
+#define TclpInetNtoa inet_ntoa
+
+#if defined(_WIN32)
+#   undef TclWinNToHS
+#   undef TclWinGetServByName
+#   undef TclWinGetSockOpt
+#   undef TclWinSetSockOpt
+#   define TclWinNToHS ntohs
+#   define TclWinGetServByName getservbyname
+#   define TclWinGetSockOpt getsockopt
+#   define TclWinSetSockOpt setsockopt
+#else
+#   undef TclpGetPid
+#   define TclpGetPid(pid) ((unsigned long) (pid))
+#endif
+
+#endif /* _TCLINTPLATDECLS */
diff --git a/generic/tclInterp.c b/generic/tclInterp.c
new file mode 100644
index 0000000..66ce1e0
--- /dev/null
+++ b/generic/tclInterp.c
@@ -0,0 +1,4825 @@
+/*
+ * tclInterp.c --
+ *
+ *	This file implements the "interp" command which allows creation and
+ *	manipulation of Tcl interpreters from within Tcl scripts.
+ *
+ * Copyright (c) 1995-1997 Sun Microsystems, Inc.
+ * Copyright (c) 2004 Donal K. Fellows
+ *
+ * See the file "license.terms" for information on usage and redistribution
+ * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#include "tclInt.h"
+
+/*
+ * A pointer to a string that holds an initialization script that if non-NULL
+ * is evaluated in Tcl_Init() prior to the built-in initialization script
+ * above. This variable can be modified by the function below.
+ */
+
+static const char *tclPreInitScript = NULL;
+
+/* Forward declaration */
+struct Target;
+
+/*
+ * struct Alias:
+ *
+ * Stores information about an alias. Is stored in the slave interpreter and
+ * used by the source command to find the target command in the master when
+ * the source command is invoked.
+ */
+
+typedef struct Alias {
+    Tcl_Obj *token;		/* Token for the alias command in the slave
+				 * interp. This used to be the command name in
+				 * the slave when the alias was first
+				 * created. */
+    Tcl_Interp *targetInterp;	/* Interp in which target command will be
+				 * invoked. */
+    Tcl_Command slaveCmd;	/* Source command in slave interpreter, bound
+				 * to command that invokes the target command
+				 * in the target interpreter. */
+    Tcl_HashEntry *aliasEntryPtr;
+				/* Entry for the alias hash table in slave.
+				 * This is used by alias deletion to remove
+				 * the alias from the slave interpreter alias
+				 * table. */
+    struct Target *targetPtr;	/* Entry for target command in master. This is
+				 * used in the master interpreter to map back
+				 * from the target command to aliases
+				 * redirecting to it. */
+    int objc;			/* Count of Tcl_Obj in the prefix of the
+				 * target command to be invoked in the target
+				 * interpreter. Additional arguments specified
+				 * when calling the alias in the slave interp
+				 * will be appended to the prefix before the
+				 * command is invoked. */
+    Tcl_Obj *objPtr;		/* The first actual prefix object - the target
+				 * command name; this has to be at the end of
+				 * the structure, which will be extended to
+				 * accomodate the remaining objects in the
+				 * prefix. */
+} Alias;
+
+/*
+ *
+ * struct Slave:
+ *
+ * Used by the "interp" command to record and find information about slave
+ * interpreters. Maps from a command name in the master to information about a
+ * slave interpreter, e.g. what aliases are defined in it.
+ */
+
+typedef struct Slave {
+    Tcl_Interp *masterInterp;	/* Master interpreter for this slave. */
+    Tcl_HashEntry *slaveEntryPtr;
+				/* Hash entry in masters slave table for this
+				 * slave interpreter. Used to find this
+				 * record, and used when deleting the slave
+				 * interpreter to delete it from the master's
+				 * table. */
+    Tcl_Interp	*slaveInterp;	/* The slave interpreter. */
+    Tcl_Command interpCmd;	/* Interpreter object command. */
+    Tcl_HashTable aliasTable;	/* Table which maps from names of commands in
+				 * slave interpreter to struct Alias defined
+				 * below. */
+} Slave;
+
+/*
+ * struct Target:
+ *
+ * Maps from master interpreter commands back to the source commands in slave
+ * interpreters. This is needed because aliases can be created between sibling
+ * interpreters and must be deleted when the target interpreter is deleted. In
+ * case they would not be deleted the source interpreter would be left with a
+ * "dangling pointer". One such record is stored in the Master record of the
+ * master interpreter with the master for each alias which directs to a
+ * command in the master. These records are used to remove the source command
+ * for an from a slave if/when the master is deleted. They are organized in a
+ * doubly-linked list attached to the master interpreter.
+ */
+
+typedef struct Target {
+    Tcl_Command	slaveCmd;	/* Command for alias in slave interp. */
+    Tcl_Interp *slaveInterp;	/* Slave Interpreter. */
+    struct Target *nextPtr;	/* Next in list of target records, or NULL if
+				 * at the end of the list of targets. */
+    struct Target *prevPtr;	/* Previous in list of target records, or NULL
+				 * if at the start of the list of targets. */
+} Target;
+
+/*
+ * struct Master:
+ *
+ * This record is used for two purposes: First, slaveTable (a hashtable) maps
+ * from names of commands to slave interpreters. This hashtable is used to
+ * store information about slave interpreters of this interpreter, to map over
+ * all slaves, etc. The second purpose is to store information about all
+ * aliases in slaves (or siblings) which direct to target commands in this
+ * interpreter (using the targetsPtr doubly-linked list).
+ *
+ * NB: the flags field in the interp structure, used with SAFE_INTERP mask
+ * denotes whether the interpreter is safe or not. Safe interpreters have
+ * restricted functionality, can only create safe slave interpreters and can
+ * only load safe extensions.
+ */
+
+typedef struct Master {
+    Tcl_HashTable slaveTable;	/* Hash table for slave interpreters. Maps
+				 * from command names to Slave records. */
+    Target *targetsPtr;		/* The head of a doubly-linked list of all the
+				 * target records which denote aliases from
+				 * slaves or sibling interpreters that direct
+				 * to commands in this interpreter. This list
+				 * is used to remove dangling pointers from
+				 * the slave (or sibling) interpreters when
+				 * this interpreter is deleted. */
+} Master;
+
+/*
+ * The following structure keeps track of all the Master and Slave information
+ * on a per-interp basis.
+ */
+
+typedef struct InterpInfo {
+    Master master;		/* Keeps track of all interps for which this
+				 * interp is the Master. */
+    Slave slave;		/* Information necessary for this interp to
+				 * function as a slave. */
+} InterpInfo;
+
+/*
+ * Limit callbacks handled by scripts are modelled as structures which are
+ * stored in hashes indexed by a two-word key. Note that the type of the
+ * 'type' field in the key is not int; this is to make sure that things are
+ * likely to work properly on 64-bit architectures.
+ */
+
+typedef struct ScriptLimitCallback {
+    Tcl_Interp *interp;		/* The interpreter in which to execute the
+				 * callback. */
+    Tcl_Obj *scriptObj;		/* The script to execute to perform the
+				 * user-defined part of the callback. */
+    int type;			/* What kind of callback is this. */
+    Tcl_HashEntry *entryPtr;	/* The entry in the hash table maintained by
+				 * the target interpreter that refers to this
+				 * callback record, or NULL if the entry has
+				 * already been deleted from that hash
+				 * table. */
+} ScriptLimitCallback;
+
+typedef struct ScriptLimitCallbackKey {
+    Tcl_Interp *interp;		/* The interpreter that the limit callback was
+				 * attached to. This is not the interpreter
+				 * that the callback runs in! */
+    long type;			/* The type of callback that this is. */
+} ScriptLimitCallbackKey;
+
+/*
+ * TIP#143 limit handler internal representation.
+ */
+
+struct LimitHandler {
+    int flags;			/* The state of this particular handler. */
+    Tcl_LimitHandlerProc *handlerProc;
+				/* The handler callback. */
+    ClientData clientData;	/* Opaque argument to the handler callback. */
+    Tcl_LimitHandlerDeleteProc *deleteProc;
+				/* How to delete the clientData. */
+    LimitHandler *prevPtr;	/* Previous item in linked list of
+				 * handlers. */
+    LimitHandler *nextPtr;	/* Next item in linked list of handlers. */
+};
+
+/*
+ * Values for the LimitHandler flags field.
+ *      LIMIT_HANDLER_ACTIVE - Whether the handler is currently being
+ *              processed; handlers are never to be entered reentrantly.
+ *      LIMIT_HANDLER_DELETED - Whether the handler has been deleted. This
+ *              should not normally be observed because when a handler is
+ *              deleted it is also spliced out of the list of handlers, but
+ *              even so we will be careful.
+ */
+
+#define LIMIT_HANDLER_ACTIVE    0x01
+#define LIMIT_HANDLER_DELETED   0x02
+
+
+
+/*
+ * Prototypes for local static functions:
+ */
+
+static int		AliasCreate(Tcl_Interp *interp,
+			    Tcl_Interp *slaveInterp, Tcl_Interp *masterInterp,
+			    Tcl_Obj *namePtr, Tcl_Obj *targetPtr, int objc,
+			    Tcl_Obj *const objv[]);
+static int		AliasDelete(Tcl_Interp *interp,
+			    Tcl_Interp *slaveInterp, Tcl_Obj *namePtr);
+static int		AliasDescribe(Tcl_Interp *interp,
+			    Tcl_Interp *slaveInterp, Tcl_Obj *objPtr);
+static int		AliasList(Tcl_Interp *interp, Tcl_Interp *slaveInterp);
+static int		AliasObjCmd(ClientData dummy,
+			    Tcl_Interp *currentInterp, int objc,
+			    Tcl_Obj *const objv[]);
+static int		AliasNRCmd(ClientData dummy,
+			    Tcl_Interp *currentInterp, int objc,
+			    Tcl_Obj *const objv[]);
+static void		AliasObjCmdDeleteProc(ClientData clientData);
+static Tcl_Interp *	GetInterp(Tcl_Interp *interp, Tcl_Obj *pathPtr);
+static Tcl_Interp *	GetInterp2(Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+static void		InterpInfoDeleteProc(ClientData clientData,
+			    Tcl_Interp *interp);
+static int		SlaveBgerror(Tcl_Interp *interp,
+			    Tcl_Interp *slaveInterp, int objc,
+			    Tcl_Obj *const objv[]);
+static Tcl_Interp *	SlaveCreate(Tcl_Interp *interp, Tcl_Obj *pathPtr,
+			    int safe);
+static int		SlaveDebugCmd(Tcl_Interp *interp,
+			    Tcl_Interp *slaveInterp,
+			    int objc, Tcl_Obj *const objv[]);
+static int		SlaveEval(Tcl_Interp *interp, Tcl_Interp *slaveInterp,
+			    int objc, Tcl_Obj *const objv[]);
+static int		SlaveExpose(Tcl_Interp *interp,
+			    Tcl_Interp *slaveInterp, int objc,
+			    Tcl_Obj *const objv[]);
+static int		SlaveHide(Tcl_Interp *interp, Tcl_Interp *slaveInterp,
+			    int objc, Tcl_Obj *const objv[]);
+static int		SlaveHidden(Tcl_Interp *interp,
+			    Tcl_Interp *slaveInterp);
+static int		SlaveInvokeHidden(Tcl_Interp *interp,
+			    Tcl_Interp *slaveInterp,
+			    const char *namespaceName,
+			    int objc, Tcl_Obj *const objv[]);
+static int		SlaveMarkTrusted(Tcl_Interp *interp,
+			    Tcl_Interp *slaveInterp);
+static int		SlaveObjCmd(ClientData dummy, Tcl_Interp *interp,
+			    int objc, Tcl_Obj *const objv[]);
+static void		SlaveObjCmdDeleteProc(ClientData clientData);
+static int		SlaveRecursionLimit(Tcl_Interp *interp,
+			    Tcl_Interp *slaveInterp, int objc,
+			    Tcl_Obj *const objv[]);
+static int		SlaveCommandLimitCmd(Tcl_Interp *interp,
+			    Tcl_Interp *slaveInterp, int consumedObjc,
+			    int objc, Tcl_Obj *const objv[]);
+static int		SlaveTimeLimitCmd(Tcl_Interp *interp,
+			    Tcl_Interp *slaveInterp, int consumedObjc,
+			    int objc, Tcl_Obj *const objv[]);
+static void		InheritLimitsFromMaster(Tcl_Interp *slaveInterp,
+			    Tcl_Interp *masterInterp);
+static void		SetScriptLimitCallback(Tcl_Interp *interp, int type,
+			    Tcl_Interp *targetInterp, Tcl_Obj *scriptObj);
+static void		CallScriptLimitCallback(ClientData clientData,
+			    Tcl_Interp *interp);
+static void		DeleteScriptLimitCallback(ClientData clientData);
+static void		RunLimitHandlers(LimitHandler *handlerPtr,
+			    Tcl_Interp *interp);
+static void		TimeLimitCallback(ClientData clientData);
+
+/* NRE enabling */
+static Tcl_NRPostProc	NRPostInvokeHidden;
+static Tcl_ObjCmdProc	NRInterpCmd;
+static Tcl_ObjCmdProc	NRSlaveCmd;
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclSetPreInitScript --
+ *
+ *	This routine is used to change the value of the internal variable,
+ *	tclPreInitScript.
+ *
+ * Results:
+ *	Returns the current value of tclPreInitScript.
+ *
+ * Side effects:
+ *	Changes the way Tcl_Init() routine behaves.
+ *
+ *----------------------------------------------------------------------
+ */
+
+const char *
+TclSetPreInitScript(
+    const char *string)		/* Pointer to a script. */
+{
+    const char *prevString = tclPreInitScript;
+    tclPreInitScript = string;
+    return(prevString);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_Init --
+ *
+ *	This function is typically invoked by Tcl_AppInit functions to find
+ *	and source the "init.tcl" script, which should exist somewhere on the
+ *	Tcl library path.
+ *
+ * Results:
+ *	Returns a standard Tcl completion code and sets the interp's result if
+ *	there is an error.
+ *
+ * Side effects:
+ *	Depends on what's in the init.tcl script.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_Init(
+    Tcl_Interp *interp)		/* Interpreter to initialize. */
+{
+    if (tclPreInitScript != NULL) {
+	if (Tcl_Eval(interp, tclPreInitScript) == TCL_ERROR) {
+	    return TCL_ERROR;
+	}
+    }
+
+    /*
+     * In order to find init.tcl during initialization, the following script
+     * is invoked by Tcl_Init(). It looks in several different directories:
+     *
+     *	$tcl_library		- can specify a primary location, if set, no
+     *				  other locations will be checked. This is the
+     *				  recommended way for a program that embeds
+     *				  Tcl to specifically tell Tcl where to find
+     *				  an init.tcl file.
+     *
+     *	$env(TCL_LIBRARY)	- highest priority so user can always override
+     *				  the search path unless the application has
+     *				  specified an exact directory above
+     *
+     *	$tclDefaultLibrary	- INTERNAL: This variable is set by Tcl on
+     *				  those platforms where it can determine at
+     *				  runtime the directory where it expects the
+     *				  init.tcl file to be. After [tclInit] reads
+     *				  and uses this value, it [unset]s it.
+     *				  External users of Tcl should not make use of
+     *				  the variable to customize [tclInit].
+     *
+     *	$tcl_libPath		- OBSOLETE: This variable is no longer set by
+     *				  Tcl itself, but [tclInit] examines it in
+     *				  case some program that embeds Tcl is
+     *				  customizing [tclInit] by setting this
+     *				  variable to a list of directories in which
+     *				  to search.
+     *
+     *	[tcl::pkgconfig get scriptdir,runtime]
+     *				- the directory determined by configure to be
+     *				  the place where Tcl's script library is to
+     *				  be installed.
+     *
+     * The first directory on this path that contains a valid init.tcl script
+     * will be set as the value of tcl_library.
+     *
+     * Note that this entire search mechanism can be bypassed by defining an
+     * alternate tclInit command before calling Tcl_Init().
+     */
+
+    return Tcl_Eval(interp,
+"if {[namespace which -command tclInit] eq \"\"} {\n"
+"  proc tclInit {} {\n"
+"    global tcl_libPath tcl_library env tclDefaultLibrary\n"
+"    rename tclInit {}\n"
+"    if {[info exists tcl_library]} {\n"
+"	set scripts {{set tcl_library}}\n"
+"    } else {\n"
+"	set scripts {}\n"
+"	if {[info exists env(TCL_LIBRARY)] && ($env(TCL_LIBRARY) ne {})} {\n"
+"	    lappend scripts {set env(TCL_LIBRARY)}\n"
+"	    lappend scripts {\n"
+"if {[regexp ^tcl(.*)$ [file tail $env(TCL_LIBRARY)] -> tail] == 0} continue\n"
+"if {$tail eq [info tclversion]} continue\n"
+"file join [file dirname $env(TCL_LIBRARY)] tcl[info tclversion]}\n"
+"	}\n"
+"	if {[info exists tclDefaultLibrary]} {\n"
+"	    lappend scripts {set tclDefaultLibrary}\n"
+"	} else {\n"
+"	    lappend scripts {::tcl::pkgconfig get scriptdir,runtime}\n"
+"	}\n"
+"	lappend scripts {\n"
+"set parentDir [file dirname [file dirname [info nameofexecutable]]]\n"
+"set grandParentDir [file dirname $parentDir]\n"
+"file join $parentDir lib tcl[info tclversion]} \\\n"
+"	{file join $grandParentDir lib tcl[info tclversion]} \\\n"
+"	{file join $parentDir library} \\\n"
+"	{file join $grandParentDir library} \\\n"
+"	{file join $grandParentDir tcl[info patchlevel] library} \\\n"
+"	{\n"
+"file join [file dirname $grandParentDir] tcl[info patchlevel] library}\n"
+"	if {[info exists tcl_libPath]\n"
+"		&& [catch {llength $tcl_libPath} len] == 0} {\n"
+"	    for {set i 0} {$i < $len} {incr i} {\n"
+"		lappend scripts [list lindex \\$tcl_libPath $i]\n"
+"	    }\n"
+"	}\n"
+"    }\n"
+"    set dirs {}\n"
+"    set errors {}\n"
+"    foreach script $scripts {\n"
+"	lappend dirs [eval $script]\n"
+"	set tcl_library [lindex $dirs end]\n"
+"	set tclfile [file join $tcl_library init.tcl]\n"
+"	if {[file exists $tclfile]} {\n"
+"	    if {[catch {uplevel #0 [list source $tclfile]} msg opts]} {\n"
+"		append errors \"$tclfile: $msg\n\"\n"
+"		append errors \"[dict get $opts -errorinfo]\n\"\n"
+"		continue\n"
+"	    }\n"
+"	    unset -nocomplain tclDefaultLibrary\n"
+"	    return\n"
+"	}\n"
+"    }\n"
+"    unset -nocomplain tclDefaultLibrary\n"
+"    set msg \"Can't find a usable init.tcl in the following directories: \n\"\n"
+"    append msg \"    $dirs\n\n\"\n"
+"    append msg \"$errors\n\n\"\n"
+"    append msg \"This probably means that Tcl wasn't installed properly.\n\"\n"
+"    error $msg\n"
+"  }\n"
+"}\n"
+"tclInit");
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * TclInterpInit --
+ *
+ *	Initializes the invoking interpreter for using the master, slave and
+ *	safe interp facilities. This is called from inside Tcl_CreateInterp().
+ *
+ * Results:
+ *	Always returns TCL_OK for backwards compatibility.
+ *
+ * Side effects:
+ *	Adds the "interp" command to an interpreter and initializes the
+ *	interpInfoPtr field of the invoking interpreter.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+int
+TclInterpInit(
+    Tcl_Interp *interp)		/* Interpreter to initialize. */
+{
+    InterpInfo *interpInfoPtr;
+    Master *masterPtr;
+    Slave *slavePtr;
+
+    interpInfoPtr = ckalloc(sizeof(InterpInfo));
+    ((Interp *) interp)->interpInfo = interpInfoPtr;
+
+    masterPtr = &interpInfoPtr->master;
+    Tcl_InitHashTable(&masterPtr->slaveTable, TCL_STRING_KEYS);
+    masterPtr->targetsPtr = NULL;
+
+    slavePtr = &interpInfoPtr->slave;
+    slavePtr->masterInterp	= NULL;
+    slavePtr->slaveEntryPtr	= NULL;
+    slavePtr->slaveInterp	= interp;
+    slavePtr->interpCmd		= NULL;
+    Tcl_InitHashTable(&slavePtr->aliasTable, TCL_STRING_KEYS);
+
+    Tcl_NRCreateCommand(interp, "interp", Tcl_InterpObjCmd, NRInterpCmd,
+	    NULL, NULL);
+
+    Tcl_CallWhenDeleted(interp, InterpInfoDeleteProc, NULL);
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * InterpInfoDeleteProc --
+ *
+ *	Invoked when an interpreter is being deleted. It releases all storage
+ *	used by the master/slave/safe interpreter facilities.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Cleans up storage. Sets the interpInfoPtr field of the interp to NULL.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+static void
+InterpInfoDeleteProc(
+    ClientData clientData,	/* Ignored. */
+    Tcl_Interp *interp)		/* Interp being deleted. All commands for
+				 * slave interps should already be deleted. */
+{
+    InterpInfo *interpInfoPtr;
+    Slave *slavePtr;
+    Master *masterPtr;
+    Target *targetPtr;
+
+    interpInfoPtr = (InterpInfo *) ((Interp *) interp)->interpInfo;
+
+    /*
+     * There shouldn't be any commands left.
+     */
+
+    masterPtr = &interpInfoPtr->master;
+    if (masterPtr->slaveTable.numEntries != 0) {
+	Tcl_Panic("InterpInfoDeleteProc: still exist commands");
+    }
+    Tcl_DeleteHashTable(&masterPtr->slaveTable);
+
+    /*
+     * Tell any interps that have aliases to this interp that they should
+     * delete those aliases. If the other interp was already dead, it would
+     * have removed the target record already.
+     */
+
+    for (targetPtr = masterPtr->targetsPtr; targetPtr != NULL; ) {
+	Target *tmpPtr = targetPtr->nextPtr;
+	Tcl_DeleteCommandFromToken(targetPtr->slaveInterp,
+		targetPtr->slaveCmd);
+	targetPtr = tmpPtr;
+    }
+
+    slavePtr = &interpInfoPtr->slave;
+    if (slavePtr->interpCmd != NULL) {
+	/*
+	 * Tcl_DeleteInterp() was called on this interpreter, rather "interp
+	 * delete" or the equivalent deletion of the command in the master.
+	 * First ensure that the cleanup callback doesn't try to delete the
+	 * interp again.
+	 */
+
+	slavePtr->slaveInterp = NULL;
+	Tcl_DeleteCommandFromToken(slavePtr->masterInterp,
+		slavePtr->interpCmd);
+    }
+
+    /*
+     * There shouldn't be any aliases left.
+     */
+
+    if (slavePtr->aliasTable.numEntries != 0) {
+	Tcl_Panic("InterpInfoDeleteProc: still exist aliases");
+    }
+    Tcl_DeleteHashTable(&slavePtr->aliasTable);
+
+    ckfree(interpInfoPtr);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_InterpObjCmd --
+ *
+ *	This function is invoked to process the "interp" Tcl command. See the
+ *	user documentation for details on what it does.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+	/* ARGSUSED */
+int
+Tcl_InterpObjCmd(
+    ClientData clientData,		/* Unused. */
+    Tcl_Interp *interp,			/* Current interpreter. */
+    int objc,				/* Number of arguments. */
+    Tcl_Obj *const objv[])		/* Argument objects. */
+{
+    return Tcl_NRCallObjProc(interp, NRInterpCmd, clientData, objc, objv);
+}
+
+static int
+NRInterpCmd(
+    ClientData clientData,		/* Unused. */
+    Tcl_Interp *interp,			/* Current interpreter. */
+    int objc,				/* Number of arguments. */
+    Tcl_Obj *const objv[])		/* Argument objects. */
+{
+    Tcl_Interp *slaveInterp;
+    int index;
+    static const char *const options[] = {
+	"alias",	"aliases",	"bgerror",	"cancel",
+	"create",	"debug",	"delete",
+	"eval",		"exists",	"expose",
+	"hide",		"hidden",	"issafe",
+	"invokehidden",	"limit",	"marktrusted",	"recursionlimit",
+	"slaves",	"share",	"target",	"transfer",
+	NULL
+    };
+    enum option {
+	OPT_ALIAS,	OPT_ALIASES,	OPT_BGERROR,	OPT_CANCEL,
+	OPT_CREATE,	OPT_DEBUG,	OPT_DELETE,
+	OPT_EVAL,	OPT_EXISTS,	OPT_EXPOSE,
+	OPT_HIDE,	OPT_HIDDEN,	OPT_ISSAFE,
+	OPT_INVOKEHID,	OPT_LIMIT,	OPT_MARKTRUSTED,OPT_RECLIMIT,
+	OPT_SLAVES,	OPT_SHARE,	OPT_TARGET,	OPT_TRANSFER
+    };
+
+    if (objc < 2) {
+	Tcl_WrongNumArgs(interp, 1, objv, "cmd ?arg ...?");
+	return TCL_ERROR;
+    }
+    if (Tcl_GetIndexFromObj(interp, objv[1], options, "option", 0,
+	    &index) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    switch ((enum option) index) {
+    case OPT_ALIAS: {
+	Tcl_Interp *masterInterp;
+
+	if (objc < 4) {
+	aliasArgs:
+	    Tcl_WrongNumArgs(interp, 2, objv,
+		    "slavePath slaveCmd ?masterPath masterCmd? ?arg ...?");
+	    return TCL_ERROR;
+	}
+	slaveInterp = GetInterp(interp, objv[2]);
+	if (slaveInterp == NULL) {
+	    return TCL_ERROR;
+	}
+	if (objc == 4) {
+	    return AliasDescribe(interp, slaveInterp, objv[3]);
+	}
+	if ((objc == 5) && (TclGetString(objv[4])[0] == '\0')) {
+	    return AliasDelete(interp, slaveInterp, objv[3]);
+	}
+	if (objc > 5) {
+	    masterInterp = GetInterp(interp, objv[4]);
+	    if (masterInterp == NULL) {
+		return TCL_ERROR;
+	    }
+	    if (TclGetString(objv[5])[0] == '\0') {
+		if (objc == 6) {
+		    return AliasDelete(interp, slaveInterp, objv[3]);
+		}
+	    } else {
+		return AliasCreate(interp, slaveInterp, masterInterp, objv[3],
+			objv[5], objc - 6, objv + 6);
+	    }
+	}
+	goto aliasArgs;
+    }
+    case OPT_ALIASES:
+	slaveInterp = GetInterp2(interp, objc, objv);
+	if (slaveInterp == NULL) {
+	    return TCL_ERROR;
+	}
+	return AliasList(interp, slaveInterp);
+    case OPT_BGERROR:
+	if (objc != 3 && objc != 4) {
+	    Tcl_WrongNumArgs(interp, 2, objv, "path ?cmdPrefix?");
+	    return TCL_ERROR;
+	}
+	slaveInterp = GetInterp(interp, objv[2]);
+	if (slaveInterp == NULL) {
+	    return TCL_ERROR;
+	}
+	return SlaveBgerror(interp, slaveInterp, objc - 3, objv + 3);
+    case OPT_CANCEL: {
+	int i, flags;
+	Tcl_Obj *resultObjPtr;
+	static const char *const cancelOptions[] = {
+	    "-unwind",	"--",	NULL
+	};
+	enum option {
+	    OPT_UNWIND,	OPT_LAST
+	};
+
+	flags = 0;
+
+	for (i = 2; i < objc; i++) {
+	    if (TclGetString(objv[i])[0] != '-') {
+		break;
+	    }
+	    if (Tcl_GetIndexFromObj(interp, objv[i], cancelOptions, "option",
+		    0, &index) != TCL_OK) {
+		return TCL_ERROR;
+	    }
+
+	    switch ((enum option) index) {
+	    case OPT_UNWIND:
+		/*
+		 * The evaluation stack in the target interp is to be unwound.
+		 */
+
+		flags |= TCL_CANCEL_UNWIND;
+		break;
+	    case OPT_LAST:
+		i++;
+		goto endOfForLoop;
+	    }
+	}
+
+    endOfForLoop:
+	if (i < objc - 2) {
+	    Tcl_WrongNumArgs(interp, 2, objv,
+		    "?-unwind? ?--? ?path? ?result?");
+	    return TCL_ERROR;
+	}
+
+	/*
+	 * Did they specify a slave interp to cancel the script in progress
+	 * in?  If not, use the current interp.
+	 */
+
+	if (i < objc) {
+	    slaveInterp = GetInterp(interp, objv[i]);
+	    if (slaveInterp == NULL) {
+		return TCL_ERROR;
+	    }
+	    i++;
+	} else {
+	    slaveInterp = interp;
+	}
+
+	if (i < objc) {
+	    resultObjPtr = objv[i];
+
+	    /*
+	     * Tcl_CancelEval removes this reference.
+	     */
+
+	    Tcl_IncrRefCount(resultObjPtr);
+	    i++;
+	} else {
+	    resultObjPtr = NULL;
+	}
+
+	return Tcl_CancelEval(slaveInterp, resultObjPtr, 0, flags);
+    }
+    case OPT_CREATE: {
+	int i, last, safe;
+	Tcl_Obj *slavePtr;
+	char buf[16 + TCL_INTEGER_SPACE];
+	static const char *const createOptions[] = {
+	    "-safe",	"--", NULL
+	};
+	enum option {
+	    OPT_SAFE,	OPT_LAST
+	};
+
+	safe = Tcl_IsSafe(interp);
+
+	/*
+	 * Weird historical rules: "-safe" is accepted at the end, too.
+	 */
+
+	slavePtr = NULL;
+	last = 0;
+	for (i = 2; i < objc; i++) {
+	    if ((last == 0) && (Tcl_GetString(objv[i])[0] == '-')) {
+		if (Tcl_GetIndexFromObj(interp, objv[i], createOptions,
+			"option", 0, &index) != TCL_OK) {
+		    return TCL_ERROR;
+		}
+		if (index == OPT_SAFE) {
+		    safe = 1;
+		    continue;
+		}
+		i++;
+		last = 1;
+	    }
+	    if (slavePtr != NULL) {
+		Tcl_WrongNumArgs(interp, 2, objv, "?-safe? ?--? ?path?");
+		return TCL_ERROR;
+	    }
+	    if (i < objc) {
+		slavePtr = objv[i];
+	    }
+	}
+	buf[0] = '\0';
+	if (slavePtr == NULL) {
+	    /*
+	     * Create an anonymous interpreter -- we choose its name and the
+	     * name of the command. We check that the command name that we use
+	     * for the interpreter does not collide with an existing command
+	     * in the master interpreter.
+	     */
+
+	    for (i = 0; ; i++) {
+		Tcl_CmdInfo cmdInfo;
+
+		sprintf(buf, "interp%d", i);
+		if (Tcl_GetCommandInfo(interp, buf, &cmdInfo) == 0) {
+		    break;
+		}
+	    }
+	    slavePtr = Tcl_NewStringObj(buf, -1);
+	}
+	if (SlaveCreate(interp, slavePtr, safe) == NULL) {
+	    if (buf[0] != '\0') {
+		Tcl_DecrRefCount(slavePtr);
+	    }
+	    return TCL_ERROR;
+	}
+	Tcl_SetObjResult(interp, slavePtr);
+	return TCL_OK;
+    }
+    case OPT_DEBUG:		/* TIP #378 */
+	/*
+	 * Currently only -frame supported, otherwise ?-option ?value??
+	 */
+
+	if (objc < 3 || objc > 5) {
+	    Tcl_WrongNumArgs(interp, 2, objv, "path ?-frame ?bool??");
+	    return TCL_ERROR;
+	}
+	slaveInterp = GetInterp(interp, objv[2]);
+	if (slaveInterp == NULL) {
+	    return TCL_ERROR;
+	}
+	return SlaveDebugCmd(interp, slaveInterp, objc - 3, objv + 3);
+    case OPT_DELETE: {
+	int i;
+	InterpInfo *iiPtr;
+
+	for (i = 2; i < objc; i++) {
+	    slaveInterp = GetInterp(interp, objv[i]);
+	    if (slaveInterp == NULL) {
+		return TCL_ERROR;
+	    } else if (slaveInterp == interp) {
+		Tcl_SetObjResult(interp, Tcl_NewStringObj(
+			"cannot delete the current interpreter", -1));
+		Tcl_SetErrorCode(interp, "TCL", "OPERATION", "INTERP",
+			"DELETESELF", NULL);
+		return TCL_ERROR;
+	    }
+	    iiPtr = (InterpInfo *) ((Interp *) slaveInterp)->interpInfo;
+	    Tcl_DeleteCommandFromToken(iiPtr->slave.masterInterp,
+		    iiPtr->slave.interpCmd);
+	}
+	return TCL_OK;
+    }
+    case OPT_EVAL:
+	if (objc < 4) {
+	    Tcl_WrongNumArgs(interp, 2, objv, "path arg ?arg ...?");
+	    return TCL_ERROR;
+	}
+	slaveInterp = GetInterp(interp, objv[2]);
+	if (slaveInterp == NULL) {
+	    return TCL_ERROR;
+	}
+	return SlaveEval(interp, slaveInterp, objc - 3, objv + 3);
+    case OPT_EXISTS: {
+	int exists = 1;
+
+	slaveInterp = GetInterp2(interp, objc, objv);
+	if (slaveInterp == NULL) {
+	    if (objc > 3) {
+		return TCL_ERROR;
+	    }
+	    Tcl_ResetResult(interp);
+	    exists = 0;
+	}
+	Tcl_SetObjResult(interp, Tcl_NewBooleanObj(exists));
+	return TCL_OK;
+    }
+    case OPT_EXPOSE:
+	if ((objc < 4) || (objc > 5)) {
+	    Tcl_WrongNumArgs(interp, 2, objv, "path hiddenCmdName ?cmdName?");
+	    return TCL_ERROR;
+	}
+	slaveInterp = GetInterp(interp, objv[2]);
+	if (slaveInterp == NULL) {
+	    return TCL_ERROR;
+	}
+	return SlaveExpose(interp, slaveInterp, objc - 3, objv + 3);
+    case OPT_HIDE:
+	if ((objc < 4) || (objc > 5)) {
+	    Tcl_WrongNumArgs(interp, 2, objv, "path cmdName ?hiddenCmdName?");
+	    return TCL_ERROR;
+	}
+	slaveInterp = GetInterp(interp, objv[2]);
+	if (slaveInterp == NULL) {
+	    return TCL_ERROR;
+	}
+	return SlaveHide(interp, slaveInterp, objc - 3, objv + 3);
+    case OPT_HIDDEN:
+	slaveInterp = GetInterp2(interp, objc, objv);
+	if (slaveInterp == NULL) {
+	    return TCL_ERROR;
+	}
+	return SlaveHidden(interp, slaveInterp);
+    case OPT_ISSAFE:
+	slaveInterp = GetInterp2(interp, objc, objv);
+	if (slaveInterp == NULL) {
+	    return TCL_ERROR;
+	}
+	Tcl_SetObjResult(interp, Tcl_NewBooleanObj(Tcl_IsSafe(slaveInterp)));
+	return TCL_OK;
+    case OPT_INVOKEHID: {
+	int i;
+	const char *namespaceName;
+	static const char *const hiddenOptions[] = {
+	    "-global",	"-namespace",	"--", NULL
+	};
+	enum hiddenOption {
+	    OPT_GLOBAL,	OPT_NAMESPACE,	OPT_LAST
+	};
+
+	namespaceName = NULL;
+	for (i = 3; i < objc; i++) {
+	    if (TclGetString(objv[i])[0] != '-') {
+		break;
+	    }
+	    if (Tcl_GetIndexFromObj(interp, objv[i], hiddenOptions, "option",
+		    0, &index) != TCL_OK) {
+		return TCL_ERROR;
+	    }
+	    if (index == OPT_GLOBAL) {
+		namespaceName = "::";
+	    } else if (index == OPT_NAMESPACE) {
+		if (++i == objc) { /* There must be more arguments. */
+		    break;
+		} else {
+		    namespaceName = TclGetString(objv[i]);
+		}
+	    } else {
+		i++;
+		break;
+	    }
+	}
+	if (objc - i < 1) {
+	    Tcl_WrongNumArgs(interp, 2, objv,
+		    "path ?-namespace ns? ?-global? ?--? cmd ?arg ..?");
+	    return TCL_ERROR;
+	}
+	slaveInterp = GetInterp(interp, objv[2]);
+	if (slaveInterp == NULL) {
+	    return TCL_ERROR;
+	}
+	return SlaveInvokeHidden(interp, slaveInterp, namespaceName, objc - i,
+		objv + i);
+    }
+    case OPT_LIMIT: {
+	static const char *const limitTypes[] = {
+	    "commands", "time", NULL
+	};
+	enum LimitTypes {
+	    LIMIT_TYPE_COMMANDS, LIMIT_TYPE_TIME
+	};
+	int limitType;
+
+	if (objc < 4) {
+	    Tcl_WrongNumArgs(interp, 2, objv,
+		    "path limitType ?-option value ...?");
+	    return TCL_ERROR;
+	}
+	slaveInterp = GetInterp(interp, objv[2]);
+	if (slaveInterp == NULL) {
+	    return TCL_ERROR;
+	}
+	if (Tcl_GetIndexFromObj(interp, objv[3], limitTypes, "limit type", 0,
+		&limitType) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	switch ((enum LimitTypes) limitType) {
+	case LIMIT_TYPE_COMMANDS:
+	    return SlaveCommandLimitCmd(interp, slaveInterp, 4, objc,objv);
+	case LIMIT_TYPE_TIME:
+	    return SlaveTimeLimitCmd(interp, slaveInterp, 4, objc, objv);
+	}
+    }
+    case OPT_MARKTRUSTED:
+	if (objc != 3) {
+	    Tcl_WrongNumArgs(interp, 2, objv, "path");
+	    return TCL_ERROR;
+	}
+	slaveInterp = GetInterp(interp, objv[2]);
+	if (slaveInterp == NULL) {
+	    return TCL_ERROR;
+	}
+	return SlaveMarkTrusted(interp, slaveInterp);
+    case OPT_RECLIMIT:
+	if (objc != 3 && objc != 4) {
+	    Tcl_WrongNumArgs(interp, 2, objv, "path ?newlimit?");
+	    return TCL_ERROR;
+	}
+	slaveInterp = GetInterp(interp, objv[2]);
+	if (slaveInterp == NULL) {
+	    return TCL_ERROR;
+	}
+	return SlaveRecursionLimit(interp, slaveInterp, objc - 3, objv + 3);
+    case OPT_SLAVES: {
+	InterpInfo *iiPtr;
+	Tcl_Obj *resultPtr;
+	Tcl_HashEntry *hPtr;
+	Tcl_HashSearch hashSearch;
+	char *string;
+
+	slaveInterp = GetInterp2(interp, objc, objv);
+	if (slaveInterp == NULL) {
+	    return TCL_ERROR;
+	}
+	iiPtr = (InterpInfo *) ((Interp *) slaveInterp)->interpInfo;
+	resultPtr = Tcl_NewObj();
+	hPtr = Tcl_FirstHashEntry(&iiPtr->master.slaveTable, &hashSearch);
+	for ( ; hPtr != NULL; hPtr = Tcl_NextHashEntry(&hashSearch)) {
+	    string = Tcl_GetHashKey(&iiPtr->master.slaveTable, hPtr);
+	    Tcl_ListObjAppendElement(NULL, resultPtr,
+		    Tcl_NewStringObj(string, -1));
+	}
+	Tcl_SetObjResult(interp, resultPtr);
+	return TCL_OK;
+    }
+    case OPT_TRANSFER:
+    case OPT_SHARE: {
+	Tcl_Interp *masterInterp;	/* The master of the slave. */
+	Tcl_Channel chan;
+
+	if (objc != 5) {
+	    Tcl_WrongNumArgs(interp, 2, objv, "srcPath channelId destPath");
+	    return TCL_ERROR;
+	}
+	masterInterp = GetInterp(interp, objv[2]);
+	if (masterInterp == NULL) {
+	    return TCL_ERROR;
+	}
+	chan = Tcl_GetChannel(masterInterp, TclGetString(objv[3]), NULL);
+	if (chan == NULL) {
+	    Tcl_TransferResult(masterInterp, TCL_OK, interp);
+	    return TCL_ERROR;
+	}
+	slaveInterp = GetInterp(interp, objv[4]);
+	if (slaveInterp == NULL) {
+	    return TCL_ERROR;
+	}
+	Tcl_RegisterChannel(slaveInterp, chan);
+	if (index == OPT_TRANSFER) {
+	    /*
+	     * When transferring, as opposed to sharing, we must unhitch the
+	     * channel from the interpreter where it started.
+	     */
+
+	    if (Tcl_UnregisterChannel(masterInterp, chan) != TCL_OK) {
+		Tcl_TransferResult(masterInterp, TCL_OK, interp);
+		return TCL_ERROR;
+	    }
+	}
+	return TCL_OK;
+    }
+    case OPT_TARGET: {
+	InterpInfo *iiPtr;
+	Tcl_HashEntry *hPtr;
+	Alias *aliasPtr;
+	const char *aliasName;
+
+	if (objc != 4) {
+	    Tcl_WrongNumArgs(interp, 2, objv, "path alias");
+	    return TCL_ERROR;
+	}
+
+	slaveInterp = GetInterp(interp, objv[2]);
+	if (slaveInterp == NULL) {
+	    return TCL_ERROR;
+	}
+
+	aliasName = TclGetString(objv[3]);
+
+	iiPtr = (InterpInfo *) ((Interp *) slaveInterp)->interpInfo;
+	hPtr = Tcl_FindHashEntry(&iiPtr->slave.aliasTable, aliasName);
+	if (hPtr == NULL) {
+	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		    "alias \"%s\" in path \"%s\" not found",
+		    aliasName, Tcl_GetString(objv[2])));
+	    Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "ALIAS", aliasName,
+		    NULL);
+	    return TCL_ERROR;
+	}
+	aliasPtr = Tcl_GetHashValue(hPtr);
+	if (Tcl_GetInterpPath(interp, aliasPtr->targetInterp) != TCL_OK) {
+	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		    "target interpreter for alias \"%s\" in path \"%s\" is "
+		    "not my descendant", aliasName, Tcl_GetString(objv[2])));
+	    Tcl_SetErrorCode(interp, "TCL", "OPERATION", "INTERP",
+		    "TARGETSHROUDED", NULL);
+	    return TCL_ERROR;
+	}
+	return TCL_OK;
+    }
+    }
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * GetInterp2 --
+ *
+ *	Helper function for Tcl_InterpObjCmd() to convert the interp name
+ *	potentially specified on the command line to an Tcl_Interp.
+ *
+ * Results:
+ *	The return value is the interp specified on the command line, or the
+ *	interp argument itself if no interp was specified on the command line.
+ *	If the interp could not be found or the wrong number of arguments was
+ *	specified on the command line, the return value is NULL and an error
+ *	message is left in the interp's result.
+ *
+ * Side effects:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+static Tcl_Interp *
+GetInterp2(
+    Tcl_Interp *interp,		/* Default interp if no interp was specified
+				 * on the command line. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    if (objc == 2) {
+	return interp;
+    } else if (objc == 3) {
+	return GetInterp(interp, objv[2]);
+    } else {
+	Tcl_WrongNumArgs(interp, 2, objv, "?path?");
+	return NULL;
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_CreateAlias --
+ *
+ *	Creates an alias between two interpreters.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	Creates a new alias, manipulates the result field of slaveInterp.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_CreateAlias(
+    Tcl_Interp *slaveInterp,	/* Interpreter for source command. */
+    const char *slaveCmd,	/* Command to install in slave. */
+    Tcl_Interp *targetInterp,	/* Interpreter for target command. */
+    const char *targetCmd,	/* Name of target command. */
+    int argc,			/* How many additional arguments? */
+    const char *const *argv)	/* These are the additional args. */
+{
+    Tcl_Obj *slaveObjPtr, *targetObjPtr;
+    Tcl_Obj **objv;
+    int i;
+    int result;
+
+    objv = TclStackAlloc(slaveInterp, (unsigned) sizeof(Tcl_Obj *) * argc);
+    for (i = 0; i < argc; i++) {
+	objv[i] = Tcl_NewStringObj(argv[i], -1);
+	Tcl_IncrRefCount(objv[i]);
+    }
+
+    slaveObjPtr = Tcl_NewStringObj(slaveCmd, -1);
+    Tcl_IncrRefCount(slaveObjPtr);
+
+    targetObjPtr = Tcl_NewStringObj(targetCmd, -1);
+    Tcl_IncrRefCount(targetObjPtr);
+
+    result = AliasCreate(slaveInterp, slaveInterp, targetInterp, slaveObjPtr,
+	    targetObjPtr, argc, objv);
+
+    for (i = 0; i < argc; i++) {
+	Tcl_DecrRefCount(objv[i]);
+    }
+    TclStackFree(slaveInterp, objv);
+    Tcl_DecrRefCount(targetObjPtr);
+    Tcl_DecrRefCount(slaveObjPtr);
+
+    return result;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_CreateAliasObj --
+ *
+ *	Object version: Creates an alias between two interpreters.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	Creates a new alias.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_CreateAliasObj(
+    Tcl_Interp *slaveInterp,	/* Interpreter for source command. */
+    const char *slaveCmd,	/* Command to install in slave. */
+    Tcl_Interp *targetInterp,	/* Interpreter for target command. */
+    const char *targetCmd,	/* Name of target command. */
+    int objc,			/* How many additional arguments? */
+    Tcl_Obj *const objv[])	/* Argument vector. */
+{
+    Tcl_Obj *slaveObjPtr, *targetObjPtr;
+    int result;
+
+    slaveObjPtr = Tcl_NewStringObj(slaveCmd, -1);
+    Tcl_IncrRefCount(slaveObjPtr);
+
+    targetObjPtr = Tcl_NewStringObj(targetCmd, -1);
+    Tcl_IncrRefCount(targetObjPtr);
+
+    result = AliasCreate(slaveInterp, slaveInterp, targetInterp, slaveObjPtr,
+	    targetObjPtr, objc, objv);
+
+    Tcl_DecrRefCount(slaveObjPtr);
+    Tcl_DecrRefCount(targetObjPtr);
+    return result;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_GetAlias --
+ *
+ *	Gets information about an alias.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_GetAlias(
+    Tcl_Interp *interp,		/* Interp to start search from. */
+    const char *aliasName,	/* Name of alias to find. */
+    Tcl_Interp **targetInterpPtr,
+				/* (Return) target interpreter. */
+    const char **targetNamePtr,	/* (Return) name of target command. */
+    int *argcPtr,		/* (Return) count of addnl args. */
+    const char ***argvPtr)	/* (Return) additional arguments. */
+{
+    InterpInfo *iiPtr = (InterpInfo *) ((Interp *) interp)->interpInfo;
+    Tcl_HashEntry *hPtr;
+    Alias *aliasPtr;
+    int i, objc;
+    Tcl_Obj **objv;
+
+    hPtr = Tcl_FindHashEntry(&iiPtr->slave.aliasTable, aliasName);
+    if (hPtr == NULL) {
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		"alias \"%s\" not found", aliasName));
+	Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "ALIAS", aliasName, NULL);
+	return TCL_ERROR;
+    }
+    aliasPtr = Tcl_GetHashValue(hPtr);
+    objc = aliasPtr->objc;
+    objv = &aliasPtr->objPtr;
+
+    if (targetInterpPtr != NULL) {
+	*targetInterpPtr = aliasPtr->targetInterp;
+    }
+    if (targetNamePtr != NULL) {
+	*targetNamePtr = TclGetString(objv[0]);
+    }
+    if (argcPtr != NULL) {
+	*argcPtr = objc - 1;
+    }
+    if (argvPtr != NULL) {
+	*argvPtr = (const char **)
+		ckalloc(sizeof(const char *) * (objc - 1));
+	for (i = 1; i < objc; i++) {
+	    (*argvPtr)[i - 1] = TclGetString(objv[i]);
+	}
+    }
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_GetAliasObj --
+ *
+ *	Object version: Gets information about an alias.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_GetAliasObj(
+    Tcl_Interp *interp,		/* Interp to start search from. */
+    const char *aliasName,	/* Name of alias to find. */
+    Tcl_Interp **targetInterpPtr,
+				/* (Return) target interpreter. */
+    const char **targetNamePtr,	/* (Return) name of target command. */
+    int *objcPtr,		/* (Return) count of addnl args. */
+    Tcl_Obj ***objvPtr)		/* (Return) additional args. */
+{
+    InterpInfo *iiPtr = (InterpInfo *) ((Interp *) interp)->interpInfo;
+    Tcl_HashEntry *hPtr;
+    Alias *aliasPtr;
+    int objc;
+    Tcl_Obj **objv;
+
+    hPtr = Tcl_FindHashEntry(&iiPtr->slave.aliasTable, aliasName);
+    if (hPtr == NULL) {
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		"alias \"%s\" not found", aliasName));
+	Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "ALIAS", aliasName, NULL);
+	return TCL_ERROR;
+    }
+    aliasPtr = Tcl_GetHashValue(hPtr);
+    objc = aliasPtr->objc;
+    objv = &aliasPtr->objPtr;
+
+    if (targetInterpPtr != NULL) {
+	*targetInterpPtr = aliasPtr->targetInterp;
+    }
+    if (targetNamePtr != NULL) {
+	*targetNamePtr = TclGetString(objv[0]);
+    }
+    if (objcPtr != NULL) {
+	*objcPtr = objc - 1;
+    }
+    if (objvPtr != NULL) {
+	*objvPtr = objv + 1;
+    }
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclPreventAliasLoop --
+ *
+ *	When defining an alias or renaming a command, prevent an alias loop
+ *	from being formed.
+ *
+ * Results:
+ *	A standard Tcl object result.
+ *
+ * Side effects:
+ *	If TCL_ERROR is returned, the function also stores an error message in
+ *	the interpreter's result object.
+ *
+ * NOTE:
+ *	This function is public internal (instead of being static to this
+ *	file) because it is also used from TclRenameCommand.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclPreventAliasLoop(
+    Tcl_Interp *interp,		/* Interp in which to report errors. */
+    Tcl_Interp *cmdInterp,	/* Interp in which the command is being
+				 * defined. */
+    Tcl_Command cmd)		/* Tcl command we are attempting to define. */
+{
+    Command *cmdPtr = (Command *) cmd;
+    Alias *aliasPtr, *nextAliasPtr;
+    Tcl_Command aliasCmd;
+    Command *aliasCmdPtr;
+
+    /*
+     * If we are not creating or renaming an alias, then it is always OK to
+     * create or rename the command.
+     */
+
+    if (cmdPtr->objProc != AliasObjCmd) {
+	return TCL_OK;
+    }
+
+    /*
+     * OK, we are dealing with an alias, so traverse the chain of aliases. If
+     * we encounter the alias we are defining (or renaming to) any in the
+     * chain then we have a loop.
+     */
+
+    aliasPtr = cmdPtr->objClientData;
+    nextAliasPtr = aliasPtr;
+    while (1) {
+	Tcl_Obj *cmdNamePtr;
+
+	/*
+	 * If the target of the next alias in the chain is the same as the
+	 * source alias, we have a loop.
+	 */
+
+	if (Tcl_InterpDeleted(nextAliasPtr->targetInterp)) {
+	    /*
+	     * The slave interpreter can be deleted while creating the alias.
+	     * [Bug #641195]
+	     */
+
+	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		    "cannot define or rename alias \"%s\": interpreter deleted",
+		    Tcl_GetCommandName(cmdInterp, cmd)));
+	    return TCL_ERROR;
+	}
+	cmdNamePtr = nextAliasPtr->objPtr;
+	aliasCmd = Tcl_FindCommand(nextAliasPtr->targetInterp,
+		TclGetString(cmdNamePtr),
+		Tcl_GetGlobalNamespace(nextAliasPtr->targetInterp),
+		/*flags*/ 0);
+	if (aliasCmd == NULL) {
+	    return TCL_OK;
+	}
+	aliasCmdPtr = (Command *) aliasCmd;
+	if (aliasCmdPtr == cmdPtr) {
+	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		    "cannot define or rename alias \"%s\": would create a loop",
+		    Tcl_GetCommandName(cmdInterp, cmd)));
+	    Tcl_SetErrorCode(interp, "TCL", "OPERATION", "INTERP",
+		    "ALIASLOOP", NULL);
+	    return TCL_ERROR;
+	}
+
+	/*
+	 * Otherwise, follow the chain one step further. See if the target
+	 * command is an alias - if so, follow the loop to its target command.
+	 * Otherwise we do not have a loop.
+	 */
+
+	if (aliasCmdPtr->objProc != AliasObjCmd) {
+	    return TCL_OK;
+	}
+	nextAliasPtr = aliasCmdPtr->objClientData;
+    }
+
+    /* NOTREACHED */
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * AliasCreate --
+ *
+ *	Helper function to do the work to actually create an alias.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	An alias command is created and entered into the alias table for the
+ *	slave interpreter.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+AliasCreate(
+    Tcl_Interp *interp,		/* Interp for error reporting. */
+    Tcl_Interp *slaveInterp,	/* Interp where alias cmd will live or from
+				 * which alias will be deleted. */
+    Tcl_Interp *masterInterp,	/* Interp in which target command will be
+				 * invoked. */
+    Tcl_Obj *namePtr,		/* Name of alias cmd. */
+    Tcl_Obj *targetNamePtr,	/* Name of target cmd. */
+    int objc,			/* Additional arguments to store */
+    Tcl_Obj *const objv[])	/* with alias. */
+{
+    Alias *aliasPtr;
+    Tcl_HashEntry *hPtr;
+    Target *targetPtr;
+    Slave *slavePtr;
+    Master *masterPtr;
+    Tcl_Obj **prefv;
+    int isNew, i;
+
+    aliasPtr = ckalloc(sizeof(Alias) + objc * sizeof(Tcl_Obj *));
+    aliasPtr->token = namePtr;
+    Tcl_IncrRefCount(aliasPtr->token);
+    aliasPtr->targetInterp = masterInterp;
+
+    aliasPtr->objc = objc + 1;
+    prefv = &aliasPtr->objPtr;
+
+    *prefv = targetNamePtr;
+    Tcl_IncrRefCount(targetNamePtr);
+    for (i = 0; i < objc; i++) {
+	*(++prefv) = objv[i];
+	Tcl_IncrRefCount(objv[i]);
+    }
+
+    Tcl_Preserve(slaveInterp);
+    Tcl_Preserve(masterInterp);
+
+    if (slaveInterp == masterInterp) {
+	aliasPtr->slaveCmd = Tcl_NRCreateCommand(slaveInterp,
+		TclGetString(namePtr), AliasObjCmd, AliasNRCmd, aliasPtr,
+		AliasObjCmdDeleteProc);
+    } else {
+    aliasPtr->slaveCmd = Tcl_CreateObjCommand(slaveInterp,
+	    TclGetString(namePtr), AliasObjCmd, aliasPtr,
+	    AliasObjCmdDeleteProc);
+    }
+
+    if (TclPreventAliasLoop(interp, slaveInterp,
+	    aliasPtr->slaveCmd) != TCL_OK) {
+	/*
+	 * Found an alias loop! The last call to Tcl_CreateObjCommand made the
+	 * alias point to itself. Delete the command and its alias record. Be
+	 * careful to wipe out its client data first, so the command doesn't
+	 * try to delete itself.
+	 */
+
+	Command *cmdPtr;
+
+	Tcl_DecrRefCount(aliasPtr->token);
+	Tcl_DecrRefCount(targetNamePtr);
+	for (i = 0; i < objc; i++) {
+	    Tcl_DecrRefCount(objv[i]);
+	}
+
+	cmdPtr = (Command *) aliasPtr->slaveCmd;
+	cmdPtr->clientData = NULL;
+	cmdPtr->deleteProc = NULL;
+	cmdPtr->deleteData = NULL;
+	Tcl_DeleteCommandFromToken(slaveInterp, aliasPtr->slaveCmd);
+
+	ckfree(aliasPtr);
+
+	/*
+	 * The result was already set by TclPreventAliasLoop.
+	 */
+
+	Tcl_Release(slaveInterp);
+	Tcl_Release(masterInterp);
+	return TCL_ERROR;
+    }
+
+    /*
+     * Make an entry in the alias table. If it already exists, retry.
+     */
+
+    slavePtr = &((InterpInfo *) ((Interp *) slaveInterp)->interpInfo)->slave;
+    while (1) {
+	Tcl_Obj *newToken;
+	const char *string;
+
+	string = TclGetString(aliasPtr->token);
+	hPtr = Tcl_CreateHashEntry(&slavePtr->aliasTable, string, &isNew);
+	if (isNew != 0) {
+	    break;
+	}
+
+	/*
+	 * The alias name cannot be used as unique token, it is already taken.
+	 * We can produce a unique token by prepending "::" repeatedly. This
+	 * algorithm is a stop-gap to try to maintain the command name as
+	 * token for most use cases, fearful of possible backwards compat
+	 * problems. A better algorithm would produce unique tokens that need
+	 * not be related to the command name.
+	 *
+	 * ATTENTION: the tests in interp.test and possibly safe.test depend
+	 * on the precise definition of these tokens.
+	 */
+
+	TclNewLiteralStringObj(newToken, "::");
+	Tcl_AppendObjToObj(newToken, aliasPtr->token);
+	Tcl_DecrRefCount(aliasPtr->token);
+	aliasPtr->token = newToken;
+	Tcl_IncrRefCount(aliasPtr->token);
+    }
+
+    aliasPtr->aliasEntryPtr = hPtr;
+    Tcl_SetHashValue(hPtr, aliasPtr);
+
+    /*
+     * Create the new command. We must do it after deleting any old command,
+     * because the alias may be pointing at a renamed alias, as in:
+     *
+     * interp alias {} foo {} bar		# Create an alias "foo"
+     * rename foo zop				# Now rename the alias
+     * interp alias {} foo {} zop		# Now recreate "foo"...
+     */
+
+    targetPtr = ckalloc(sizeof(Target));
+    targetPtr->slaveCmd = aliasPtr->slaveCmd;
+    targetPtr->slaveInterp = slaveInterp;
+
+    masterPtr = &((InterpInfo*) ((Interp*) masterInterp)->interpInfo)->master;
+    targetPtr->nextPtr = masterPtr->targetsPtr;
+    targetPtr->prevPtr = NULL;
+    if (masterPtr->targetsPtr != NULL) {
+	masterPtr->targetsPtr->prevPtr = targetPtr;
+    }
+    masterPtr->targetsPtr = targetPtr;
+    aliasPtr->targetPtr = targetPtr;
+
+    Tcl_SetObjResult(interp, aliasPtr->token);
+
+    Tcl_Release(slaveInterp);
+    Tcl_Release(masterInterp);
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * AliasDelete --
+ *
+ *	Deletes the given alias from the slave interpreter given.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	Deletes the alias from the slave interpreter.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+AliasDelete(
+    Tcl_Interp *interp,		/* Interpreter for result & errors. */
+    Tcl_Interp *slaveInterp,	/* Interpreter containing alias. */
+    Tcl_Obj *namePtr)		/* Name of alias to delete. */
+{
+    Slave *slavePtr;
+    Alias *aliasPtr;
+    Tcl_HashEntry *hPtr;
+
+    /*
+     * If the alias has been renamed in the slave, the master can still use
+     * the original name (with which it was created) to find the alias to
+     * delete it.
+     */
+
+    slavePtr = &((InterpInfo *) ((Interp *) slaveInterp)->interpInfo)->slave;
+    hPtr = Tcl_FindHashEntry(&slavePtr->aliasTable, TclGetString(namePtr));
+    if (hPtr == NULL) {
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		"alias \"%s\" not found", TclGetString(namePtr)));
+	Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "ALIAS",
+		TclGetString(namePtr), NULL);
+	return TCL_ERROR;
+    }
+    aliasPtr = Tcl_GetHashValue(hPtr);
+    Tcl_DeleteCommandFromToken(slaveInterp, aliasPtr->slaveCmd);
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * AliasDescribe --
+ *
+ *	Sets the interpreter's result object to a Tcl list describing the
+ *	given alias in the given interpreter: its target command and the
+ *	additional arguments to prepend to any invocation of the alias.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+AliasDescribe(
+    Tcl_Interp *interp,		/* Interpreter for result & errors. */
+    Tcl_Interp *slaveInterp,	/* Interpreter containing alias. */
+    Tcl_Obj *namePtr)		/* Name of alias to describe. */
+{
+    Slave *slavePtr;
+    Tcl_HashEntry *hPtr;
+    Alias *aliasPtr;
+    Tcl_Obj *prefixPtr;
+
+    /*
+     * If the alias has been renamed in the slave, the master can still use
+     * the original name (with which it was created) to find the alias to
+     * describe it.
+     */
+
+    slavePtr = &((InterpInfo *) ((Interp *) slaveInterp)->interpInfo)->slave;
+    hPtr = Tcl_FindHashEntry(&slavePtr->aliasTable, Tcl_GetString(namePtr));
+    if (hPtr == NULL) {
+	return TCL_OK;
+    }
+    aliasPtr = Tcl_GetHashValue(hPtr);
+    prefixPtr = Tcl_NewListObj(aliasPtr->objc, &aliasPtr->objPtr);
+    Tcl_SetObjResult(interp, prefixPtr);
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * AliasList --
+ *
+ *	Computes a list of aliases defined in a slave interpreter.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+AliasList(
+    Tcl_Interp *interp,		/* Interp for data return. */
+    Tcl_Interp *slaveInterp)	/* Interp whose aliases to compute. */
+{
+    Tcl_HashEntry *entryPtr;
+    Tcl_HashSearch hashSearch;
+    Tcl_Obj *resultPtr = Tcl_NewObj();
+    Alias *aliasPtr;
+    Slave *slavePtr;
+
+    slavePtr = &((InterpInfo *) ((Interp *) slaveInterp)->interpInfo)->slave;
+
+    entryPtr = Tcl_FirstHashEntry(&slavePtr->aliasTable, &hashSearch);
+    for ( ; entryPtr != NULL; entryPtr = Tcl_NextHashEntry(&hashSearch)) {
+	aliasPtr = Tcl_GetHashValue(entryPtr);
+	Tcl_ListObjAppendElement(NULL, resultPtr, aliasPtr->token);
+    }
+    Tcl_SetObjResult(interp, resultPtr);
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * AliasObjCmd --
+ *
+ *	This is the function that services invocations of aliases in a slave
+ *	interpreter. One such command exists for each alias. When invoked,
+ *	this function redirects the invocation to the target command in the
+ *	master interpreter as designated by the Alias record associated with
+ *	this command.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	Causes forwarding of the invocation; all possible side effects may
+ *	occur as a result of invoking the command to which the invocation is
+ *	forwarded.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+AliasNRCmd(
+    ClientData clientData,	/* Alias record. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument vector. */
+{
+    Alias *aliasPtr = clientData;
+    int prefc, cmdc, i;
+    Tcl_Obj **prefv, **cmdv;
+    Tcl_Obj *listPtr;
+    List *listRep;
+    int flags = TCL_EVAL_INVOKE;
+
+    /*
+     * Append the arguments to the command prefix and invoke the command in
+     * the target interp's global namespace.
+     */
+
+    prefc = aliasPtr->objc;
+    prefv = &aliasPtr->objPtr;
+    cmdc = prefc + objc - 1;
+
+    listPtr = Tcl_NewListObj(cmdc, NULL);
+    listRep = listPtr->internalRep.twoPtrValue.ptr1;
+    listRep->elemCount = cmdc;
+    cmdv = &listRep->elements;
+
+    prefv = &aliasPtr->objPtr;
+    memcpy(cmdv, prefv, (size_t) (prefc * sizeof(Tcl_Obj *)));
+    memcpy(cmdv+prefc, objv+1, (size_t) ((objc-1) * sizeof(Tcl_Obj *)));
+
+    for (i=0; i<cmdc; i++) {
+	Tcl_IncrRefCount(cmdv[i]);
+    }
+
+    /*
+     * Use the ensemble rewriting machinery to ensure correct error messages:
+     * only the source command should show, not the full target prefix.
+     */
+
+    if (TclInitRewriteEnsemble(interp, 1, prefc, objv)) {
+	TclNRAddCallback(interp, TclClearRootEnsemble, NULL, NULL, NULL, NULL);
+    }
+    TclSkipTailcall(interp);
+    return Tcl_NREvalObj(interp, listPtr, flags);
+}
+
+static int
+AliasObjCmd(
+    ClientData clientData,	/* Alias record. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument vector. */
+{
+#define ALIAS_CMDV_PREALLOC 10
+    Alias *aliasPtr = clientData;
+    Tcl_Interp *targetInterp = aliasPtr->targetInterp;
+    int result, prefc, cmdc, i;
+    Tcl_Obj **prefv, **cmdv;
+    Tcl_Obj *cmdArr[ALIAS_CMDV_PREALLOC];
+    Interp *tPtr = (Interp *) targetInterp;
+    int isRootEnsemble;
+
+    /*
+     * Append the arguments to the command prefix and invoke the command in
+     * the target interp's global namespace.
+     */
+
+    prefc = aliasPtr->objc;
+    prefv = &aliasPtr->objPtr;
+    cmdc = prefc + objc - 1;
+    if (cmdc <= ALIAS_CMDV_PREALLOC) {
+	cmdv = cmdArr;
+    } else {
+	cmdv = TclStackAlloc(interp, cmdc * sizeof(Tcl_Obj *));
+    }
+
+    memcpy(cmdv, prefv, (size_t) (prefc * sizeof(Tcl_Obj *)));
+    memcpy(cmdv+prefc, objv+1, (size_t) ((objc-1) * sizeof(Tcl_Obj *)));
+
+    Tcl_ResetResult(targetInterp);
+
+    for (i=0; i<cmdc; i++) {
+	Tcl_IncrRefCount(cmdv[i]);
+    }
+
+    /*
+     * Use the ensemble rewriting machinery to ensure correct error messages:
+     * only the source command should show, not the full target prefix.
+     */
+
+    isRootEnsemble = TclInitRewriteEnsemble((Tcl_Interp *)tPtr, 1, prefc, objv);
+
+    /*
+     * Protect the target interpreter if it isn't the same as the source
+     * interpreter so that we can continue to work with it after the target
+     * command completes.
+     */
+
+    if (targetInterp != interp) {
+	Tcl_Preserve(targetInterp);
+    }
+
+    /*
+     * Execute the target command in the target interpreter.
+     */
+
+    result = Tcl_EvalObjv(targetInterp, cmdc, cmdv, TCL_EVAL_INVOKE);
+
+    /*
+     * Clean up the ensemble rewrite info if we set it in the first place.
+     */
+
+    if (isRootEnsemble) {
+	TclResetRewriteEnsemble((Tcl_Interp *)tPtr, 1);
+    }
+
+    /*
+     * If it was a cross-interpreter alias, we need to transfer the result
+     * back to the source interpreter and release the lock we previously set
+     * on the target interpreter.
+     */
+
+    if (targetInterp != interp) {
+	Tcl_TransferResult(targetInterp, result, interp);
+	Tcl_Release(targetInterp);
+    }
+
+    for (i=0; i<cmdc; i++) {
+	Tcl_DecrRefCount(cmdv[i]);
+    }
+    if (cmdv != cmdArr) {
+	TclStackFree(interp, cmdv);
+    }
+    return result;
+#undef ALIAS_CMDV_PREALLOC
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * AliasObjCmdDeleteProc --
+ *
+ *	Is invoked when an alias command is deleted in a slave. Cleans up all
+ *	storage associated with this alias.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Deletes the alias record and its entry in the alias table for the
+ *	interpreter.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+AliasObjCmdDeleteProc(
+    ClientData clientData)	/* The alias record for this alias. */
+{
+    Alias *aliasPtr = clientData;
+    Target *targetPtr;
+    int i;
+    Tcl_Obj **objv;
+
+    Tcl_DecrRefCount(aliasPtr->token);
+    objv = &aliasPtr->objPtr;
+    for (i = 0; i < aliasPtr->objc; i++) {
+	Tcl_DecrRefCount(objv[i]);
+    }
+    Tcl_DeleteHashEntry(aliasPtr->aliasEntryPtr);
+
+    /*
+     * Splice the target record out of the target interpreter's master list.
+     */
+
+    targetPtr = aliasPtr->targetPtr;
+    if (targetPtr->prevPtr != NULL) {
+	targetPtr->prevPtr->nextPtr = targetPtr->nextPtr;
+    } else {
+	Master *masterPtr = &((InterpInfo *) ((Interp *)
+		aliasPtr->targetInterp)->interpInfo)->master;
+
+	masterPtr->targetsPtr = targetPtr->nextPtr;
+    }
+    if (targetPtr->nextPtr != NULL) {
+	targetPtr->nextPtr->prevPtr = targetPtr->prevPtr;
+    }
+
+    ckfree(targetPtr);
+    ckfree(aliasPtr);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_CreateSlave --
+ *
+ *	Creates a slave interpreter. The slavePath argument denotes the name
+ *	of the new slave relative to the current interpreter; the slave is a
+ *	direct descendant of the one-before-last component of the path,
+ *	e.g. it is a descendant of the current interpreter if the slavePath
+ *	argument contains only one component. Optionally makes the slave
+ *	interpreter safe.
+ *
+ * Results:
+ *	Returns the interpreter structure created, or NULL if an error
+ *	occurred.
+ *
+ * Side effects:
+ *	Creates a new interpreter and a new interpreter object command in the
+ *	interpreter indicated by the slavePath argument.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_Interp *
+Tcl_CreateSlave(
+    Tcl_Interp *interp,		/* Interpreter to start search at. */
+    const char *slavePath,	/* Name of slave to create. */
+    int isSafe)			/* Should new slave be "safe" ? */
+{
+    Tcl_Obj *pathPtr;
+    Tcl_Interp *slaveInterp;
+
+    pathPtr = Tcl_NewStringObj(slavePath, -1);
+    slaveInterp = SlaveCreate(interp, pathPtr, isSafe);
+    Tcl_DecrRefCount(pathPtr);
+
+    return slaveInterp;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_GetSlave --
+ *
+ *	Finds a slave interpreter by its path name.
+ *
+ * Results:
+ *	Returns a Tcl_Interp * for the named interpreter or NULL if not found.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_Interp *
+Tcl_GetSlave(
+    Tcl_Interp *interp,		/* Interpreter to start search from. */
+    const char *slavePath)	/* Path of slave to find. */
+{
+    Tcl_Obj *pathPtr;
+    Tcl_Interp *slaveInterp;
+
+    pathPtr = Tcl_NewStringObj(slavePath, -1);
+    slaveInterp = GetInterp(interp, pathPtr);
+    Tcl_DecrRefCount(pathPtr);
+
+    return slaveInterp;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_GetMaster --
+ *
+ *	Finds the master interpreter of a slave interpreter.
+ *
+ * Results:
+ *	Returns a Tcl_Interp * for the master interpreter or NULL if none.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_Interp *
+Tcl_GetMaster(
+    Tcl_Interp *interp)		/* Get the master of this interpreter. */
+{
+    Slave *slavePtr;		/* Slave record of this interpreter. */
+
+    if (interp == NULL) {
+	return NULL;
+    }
+    slavePtr = &((InterpInfo *) ((Interp *) interp)->interpInfo)->slave;
+    return slavePtr->masterInterp;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclSetSlaveCancelFlags --
+ *
+ *	This function marks all slave interpreters belonging to a given
+ *	interpreter as being canceled or not canceled, depending on the
+ *	provided flags.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclSetSlaveCancelFlags(
+    Tcl_Interp *interp,		/* Set cancel flags of this interpreter. */
+    int flags,			/* Collection of OR-ed bits that control
+				 * the cancellation of the script. Only
+				 * TCL_CANCEL_UNWIND is currently
+				 * supported. */
+    int force)			/* Non-zero to ignore numLevels for the purpose
+				 * of resetting the cancellation flags. */
+{
+    Master *masterPtr;		/* Master record of given interpreter. */
+    Tcl_HashEntry *hPtr;	/* Search element. */
+    Tcl_HashSearch hashSearch;	/* Search variable. */
+    Slave *slavePtr;		/* Slave record of interpreter. */
+    Interp *iPtr;
+
+    if (interp == NULL) {
+	return;
+    }
+
+    flags &= (CANCELED | TCL_CANCEL_UNWIND);
+
+    masterPtr = &((InterpInfo *) ((Interp *) interp)->interpInfo)->master;
+
+    hPtr = Tcl_FirstHashEntry(&masterPtr->slaveTable, &hashSearch);
+    for ( ; hPtr != NULL; hPtr = Tcl_NextHashEntry(&hashSearch)) {
+	slavePtr = Tcl_GetHashValue(hPtr);
+	iPtr = (Interp *) slavePtr->slaveInterp;
+
+	if (iPtr == NULL) {
+	    continue;
+	}
+
+	if (flags == 0) {
+	    TclResetCancellation((Tcl_Interp *) iPtr, force);
+	} else {
+	    TclSetCancelFlags(iPtr, flags);
+	}
+
+	/*
+	 * Now, recursively handle this for the slaves of this slave
+	 * interpreter.
+	 */
+
+	TclSetSlaveCancelFlags((Tcl_Interp *) iPtr, flags, force);
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_GetInterpPath --
+ *
+ *	Sets the result of the asking interpreter to a proper Tcl list
+ *	containing the names of interpreters between the asking and target
+ *	interpreters. The target interpreter must be either the same as the
+ *	asking interpreter or one of its slaves (including recursively).
+ *
+ * Results:
+ *	TCL_OK if the target interpreter is the same as, or a descendant of,
+ *	the asking interpreter; TCL_ERROR else. This way one can distinguish
+ *	between the case where the asking and target interps are the same (an
+ *	empty list is the result, and TCL_OK is returned) and when the target
+ *	is not a descendant of the asking interpreter (in which case the Tcl
+ *	result is an error message and the function returns TCL_ERROR).
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_GetInterpPath(
+    Tcl_Interp *askingInterp,	/* Interpreter to start search from. */
+    Tcl_Interp *targetInterp)	/* Interpreter to find. */
+{
+    InterpInfo *iiPtr;
+
+    if (targetInterp == askingInterp) {
+	Tcl_SetObjResult(askingInterp, Tcl_NewObj());
+	return TCL_OK;
+    }
+    if (targetInterp == NULL) {
+	return TCL_ERROR;
+    }
+    iiPtr = (InterpInfo *) ((Interp *) targetInterp)->interpInfo;
+    if (Tcl_GetInterpPath(askingInterp, iiPtr->slave.masterInterp) != TCL_OK){
+	return TCL_ERROR;
+    }
+    Tcl_ListObjAppendElement(NULL, Tcl_GetObjResult(askingInterp),
+	    Tcl_NewStringObj(Tcl_GetHashKey(&iiPtr->master.slaveTable,
+		    iiPtr->slave.slaveEntryPtr), -1));
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * GetInterp --
+ *
+ *	Helper function to find a slave interpreter given a pathname.
+ *
+ * Results:
+ *	Returns the slave interpreter known by that name in the calling
+ *	interpreter, or NULL if no interpreter known by that name exists.
+ *
+ * Side effects:
+ *	Assigns to the pointer variable passed in, if not NULL.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static Tcl_Interp *
+GetInterp(
+    Tcl_Interp *interp,		/* Interp. to start search from. */
+    Tcl_Obj *pathPtr)		/* List object containing name of interp. to
+				 * be found. */
+{
+    Tcl_HashEntry *hPtr;	/* Search element. */
+    Slave *slavePtr;		/* Interim slave record. */
+    Tcl_Obj **objv;
+    int objc, i;
+    Tcl_Interp *searchInterp;	/* Interim storage for interp. to find. */
+    InterpInfo *masterInfoPtr;
+
+    if (TclListObjGetElements(interp, pathPtr, &objc, &objv) != TCL_OK) {
+	return NULL;
+    }
+
+    searchInterp = interp;
+    for (i = 0; i < objc; i++) {
+	masterInfoPtr = (InterpInfo *) ((Interp *) searchInterp)->interpInfo;
+	hPtr = Tcl_FindHashEntry(&masterInfoPtr->master.slaveTable,
+		TclGetString(objv[i]));
+	if (hPtr == NULL) {
+	    searchInterp = NULL;
+	    break;
+	}
+	slavePtr = Tcl_GetHashValue(hPtr);
+	searchInterp = slavePtr->slaveInterp;
+	if (searchInterp == NULL) {
+	    break;
+	}
+    }
+    if (searchInterp == NULL) {
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		"could not find interpreter \"%s\"", TclGetString(pathPtr)));
+	Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "INTERP",
+		TclGetString(pathPtr), NULL);
+    }
+    return searchInterp;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * SlaveBgerror --
+ *
+ *	Helper function to set/query the background error handling command
+ *	prefix of an interp
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	When (objc == 1), slaveInterp will be set to a new background handler
+ *	of objv[0].
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+SlaveBgerror(
+    Tcl_Interp *interp,		/* Interp for error return. */
+    Tcl_Interp *slaveInterp,	/* Interp in which limit is set/queried. */
+    int objc,			/* Set or Query. */
+    Tcl_Obj *const objv[])	/* Argument strings. */
+{
+    if (objc) {
+	int length;
+
+	if (TCL_ERROR == TclListObjLength(NULL, objv[0], &length)
+		|| (length < 1)) {
+	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		    "cmdPrefix must be list of length >= 1", -1));
+	    Tcl_SetErrorCode(interp, "TCL", "OPERATION", "INTERP",
+		    "BGERRORFORMAT", NULL);
+	    return TCL_ERROR;
+	}
+	TclSetBgErrorHandler(slaveInterp, objv[0]);
+    }
+    Tcl_SetObjResult(interp, TclGetBgErrorHandler(slaveInterp));
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * SlaveCreate --
+ *
+ *	Helper function to do the actual work of creating a slave interp and
+ *	new object command. Also optionally makes the new slave interpreter
+ *	"safe".
+ *
+ * Results:
+ *	Returns the new Tcl_Interp * if successful or NULL if not. If failed,
+ *	the result of the invoking interpreter contains an error message.
+ *
+ * Side effects:
+ *	Creates a new slave interpreter and a new object command.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static Tcl_Interp *
+SlaveCreate(
+    Tcl_Interp *interp,		/* Interp. to start search from. */
+    Tcl_Obj *pathPtr,		/* Path (name) of slave to create. */
+    int safe)			/* Should we make it "safe"? */
+{
+    Tcl_Interp *masterInterp, *slaveInterp;
+    Slave *slavePtr;
+    InterpInfo *masterInfoPtr;
+    Tcl_HashEntry *hPtr;
+    const char *path;
+    int isNew, objc;
+    Tcl_Obj **objv;
+
+    if (Tcl_ListObjGetElements(interp, pathPtr, &objc, &objv) != TCL_OK) {
+	return NULL;
+    }
+    if (objc < 2) {
+	masterInterp = interp;
+	path = TclGetString(pathPtr);
+    } else {
+	Tcl_Obj *objPtr;
+
+	objPtr = Tcl_NewListObj(objc - 1, objv);
+	masterInterp = GetInterp(interp, objPtr);
+	Tcl_DecrRefCount(objPtr);
+	if (masterInterp == NULL) {
+	    return NULL;
+	}
+	path = TclGetString(objv[objc - 1]);
+    }
+    if (safe == 0) {
+	safe = Tcl_IsSafe(masterInterp);
+    }
+
+    masterInfoPtr = (InterpInfo *) ((Interp *) masterInterp)->interpInfo;
+    hPtr = Tcl_CreateHashEntry(&masterInfoPtr->master.slaveTable, path,
+	    &isNew);
+    if (isNew == 0) {
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		"interpreter named \"%s\" already exists, cannot create",
+		path));
+	return NULL;
+    }
+
+    slaveInterp = Tcl_CreateInterp();
+    slavePtr = &((InterpInfo *) ((Interp *) slaveInterp)->interpInfo)->slave;
+    slavePtr->masterInterp = masterInterp;
+    slavePtr->slaveEntryPtr = hPtr;
+    slavePtr->slaveInterp = slaveInterp;
+    slavePtr->interpCmd = Tcl_NRCreateCommand(masterInterp, path,
+	    SlaveObjCmd, NRSlaveCmd, slaveInterp, SlaveObjCmdDeleteProc);
+    Tcl_InitHashTable(&slavePtr->aliasTable, TCL_STRING_KEYS);
+    Tcl_SetHashValue(hPtr, slavePtr);
+    Tcl_SetVar(slaveInterp, "tcl_interactive", "0", TCL_GLOBAL_ONLY);
+
+    /*
+     * Inherit the recursion limit.
+     */
+
+    ((Interp *) slaveInterp)->maxNestingDepth =
+	    ((Interp *) masterInterp)->maxNestingDepth;
+
+    if (safe) {
+	if (Tcl_MakeSafe(slaveInterp) == TCL_ERROR) {
+	    goto error;
+	}
+    } else {
+	if (Tcl_Init(slaveInterp) == TCL_ERROR) {
+	    goto error;
+	}
+
+	/*
+	 * This will create the "memory" command in slave interpreters if we
+	 * compiled with TCL_MEM_DEBUG, otherwise it does nothing.
+	 */
+
+	Tcl_InitMemory(slaveInterp);
+    }
+
+    /*
+     * Inherit the TIP#143 limits.
+     */
+
+    InheritLimitsFromMaster(slaveInterp, masterInterp);
+
+    /*
+     * The [clock] command presents a safe API, but uses unsafe features in
+     * its implementation. This means it has to be implemented in safe interps
+     * as an alias to a version in the (trusted) master.
+     */
+
+    if (safe) {
+	Tcl_Obj *clockObj;
+	int status;
+
+	TclNewLiteralStringObj(clockObj, "clock");
+	Tcl_IncrRefCount(clockObj);
+	status = AliasCreate(interp, slaveInterp, masterInterp, clockObj,
+		clockObj, 0, NULL);
+	Tcl_DecrRefCount(clockObj);
+	if (status != TCL_OK) {
+	    goto error2;
+	}
+    }
+
+    return slaveInterp;
+
+  error:
+    Tcl_TransferResult(slaveInterp, TCL_ERROR, interp);
+  error2:
+    Tcl_DeleteInterp(slaveInterp);
+
+    return NULL;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * SlaveObjCmd --
+ *
+ *	Command to manipulate an interpreter, e.g. to send commands to it to
+ *	be evaluated. One such command exists for each slave interpreter.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	See user documentation for details.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+SlaveObjCmd(
+    ClientData clientData,	/* Slave interpreter. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    return Tcl_NRCallObjProc(interp, NRSlaveCmd, clientData, objc, objv);
+}
+
+static int
+NRSlaveCmd(
+    ClientData clientData,	/* Slave interpreter. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    Tcl_Interp *slaveInterp = clientData;
+    int index;
+    static const char *const options[] = {
+	"alias",	"aliases",	"bgerror",	"debug",
+	"eval",		"expose",	"hide",		"hidden",
+	"issafe",	"invokehidden",	"limit",	"marktrusted",
+	"recursionlimit", NULL
+    };
+    enum options {
+	OPT_ALIAS,	OPT_ALIASES,	OPT_BGERROR,	OPT_DEBUG,
+	OPT_EVAL,	OPT_EXPOSE,	OPT_HIDE,	OPT_HIDDEN,
+	OPT_ISSAFE,	OPT_INVOKEHIDDEN, OPT_LIMIT,	OPT_MARKTRUSTED,
+	OPT_RECLIMIT
+    };
+
+    if (slaveInterp == NULL) {
+	Tcl_Panic("SlaveObjCmd: interpreter has been deleted");
+    }
+
+    if (objc < 2) {
+	Tcl_WrongNumArgs(interp, 1, objv, "cmd ?arg ...?");
+	return TCL_ERROR;
+    }
+    if (Tcl_GetIndexFromObj(interp, objv[1], options, "option", 0,
+	    &index) != TCL_OK) {
+	return TCL_ERROR;
+    }
+
+    switch ((enum options) index) {
+    case OPT_ALIAS:
+	if (objc > 2) {
+	    if (objc == 3) {
+		return AliasDescribe(interp, slaveInterp, objv[2]);
+	    }
+	    if (TclGetString(objv[3])[0] == '\0') {
+		if (objc == 4) {
+		    return AliasDelete(interp, slaveInterp, objv[2]);
+		}
+	    } else {
+		return AliasCreate(interp, slaveInterp, interp, objv[2],
+			objv[3], objc - 4, objv + 4);
+	    }
+	}
+	Tcl_WrongNumArgs(interp, 2, objv, "aliasName ?targetName? ?arg ...?");
+	return TCL_ERROR;
+    case OPT_ALIASES:
+	if (objc != 2) {
+	    Tcl_WrongNumArgs(interp, 2, objv, NULL);
+	    return TCL_ERROR;
+	}
+	return AliasList(interp, slaveInterp);
+    case OPT_BGERROR:
+	if (objc != 2 && objc != 3) {
+	    Tcl_WrongNumArgs(interp, 2, objv, "?cmdPrefix?");
+	    return TCL_ERROR;
+	}
+	return SlaveBgerror(interp, slaveInterp, objc - 2, objv + 2);
+    case OPT_DEBUG:
+	/*
+	 * TIP #378
+	 * Currently only -frame supported, otherwise ?-option ?value? ...?
+	 */
+	if (objc > 4) {
+	    Tcl_WrongNumArgs(interp, 2, objv, "?-frame ?bool??");
+	    return TCL_ERROR;
+	}
+	return SlaveDebugCmd(interp, slaveInterp, objc - 2, objv + 2);
+    case OPT_EVAL:
+	if (objc < 3) {
+	    Tcl_WrongNumArgs(interp, 2, objv, "arg ?arg ...?");
+	    return TCL_ERROR;
+	}
+	return SlaveEval(interp, slaveInterp, objc - 2, objv + 2);
+    case OPT_EXPOSE:
+	if ((objc < 3) || (objc > 4)) {
+	    Tcl_WrongNumArgs(interp, 2, objv, "hiddenCmdName ?cmdName?");
+	    return TCL_ERROR;
+	}
+	return SlaveExpose(interp, slaveInterp, objc - 2, objv + 2);
+    case OPT_HIDE:
+	if ((objc < 3) || (objc > 4)) {
+	    Tcl_WrongNumArgs(interp, 2, objv, "cmdName ?hiddenCmdName?");
+	    return TCL_ERROR;
+	}
+	return SlaveHide(interp, slaveInterp, objc - 2, objv + 2);
+    case OPT_HIDDEN:
+	if (objc != 2) {
+	    Tcl_WrongNumArgs(interp, 2, objv, NULL);
+	    return TCL_ERROR;
+	}
+	return SlaveHidden(interp, slaveInterp);
+    case OPT_ISSAFE:
+	if (objc != 2) {
+	    Tcl_WrongNumArgs(interp, 2, objv, NULL);
+	    return TCL_ERROR;
+	}
+	Tcl_SetObjResult(interp, Tcl_NewBooleanObj(Tcl_IsSafe(slaveInterp)));
+	return TCL_OK;
+    case OPT_INVOKEHIDDEN: {
+	int i;
+	const char *namespaceName;
+	static const char *const hiddenOptions[] = {
+	    "-global",	"-namespace",	"--", NULL
+	};
+	enum hiddenOption {
+	    OPT_GLOBAL,	OPT_NAMESPACE,	OPT_LAST
+	};
+
+	namespaceName = NULL;
+	for (i = 2; i < objc; i++) {
+	    if (TclGetString(objv[i])[0] != '-') {
+		break;
+	    }
+	    if (Tcl_GetIndexFromObj(interp, objv[i], hiddenOptions, "option",
+		    0, &index) != TCL_OK) {
+		return TCL_ERROR;
+	    }
+	    if (index == OPT_GLOBAL) {
+		namespaceName = "::";
+	    } else if (index == OPT_NAMESPACE) {
+		if (++i == objc) { /* There must be more arguments. */
+		    break;
+		} else {
+		    namespaceName = TclGetString(objv[i]);
+		}
+	    } else {
+		i++;
+		break;
+	    }
+	}
+	if (objc - i < 1) {
+	    Tcl_WrongNumArgs(interp, 2, objv,
+		    "?-namespace ns? ?-global? ?--? cmd ?arg ..?");
+	    return TCL_ERROR;
+	}
+	return SlaveInvokeHidden(interp, slaveInterp, namespaceName,
+		objc - i, objv + i);
+    }
+    case OPT_LIMIT: {
+	static const char *const limitTypes[] = {
+	    "commands", "time", NULL
+	};
+	enum LimitTypes {
+	    LIMIT_TYPE_COMMANDS, LIMIT_TYPE_TIME
+	};
+	int limitType;
+
+	if (objc < 3) {
+	    Tcl_WrongNumArgs(interp, 2, objv, "limitType ?-option value ...?");
+	    return TCL_ERROR;
+	}
+	if (Tcl_GetIndexFromObj(interp, objv[2], limitTypes, "limit type", 0,
+		&limitType) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	switch ((enum LimitTypes) limitType) {
+	case LIMIT_TYPE_COMMANDS:
+	    return SlaveCommandLimitCmd(interp, slaveInterp, 3, objc,objv);
+	case LIMIT_TYPE_TIME:
+	    return SlaveTimeLimitCmd(interp, slaveInterp, 3, objc, objv);
+	}
+    }
+    case OPT_MARKTRUSTED:
+	if (objc != 2) {
+	    Tcl_WrongNumArgs(interp, 2, objv, NULL);
+	    return TCL_ERROR;
+	}
+	return SlaveMarkTrusted(interp, slaveInterp);
+    case OPT_RECLIMIT:
+	if (objc != 2 && objc != 3) {
+	    Tcl_WrongNumArgs(interp, 2, objv, "?newlimit?");
+	    return TCL_ERROR;
+	}
+	return SlaveRecursionLimit(interp, slaveInterp, objc - 2, objv + 2);
+    }
+
+    return TCL_ERROR;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * SlaveObjCmdDeleteProc --
+ *
+ *	Invoked when an object command for a slave interpreter is deleted;
+ *	cleans up all state associated with the slave interpreter and destroys
+ *	the slave interpreter.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Cleans up all state associated with the slave interpreter and destroys
+ *	the slave interpreter.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+SlaveObjCmdDeleteProc(
+    ClientData clientData)	/* The SlaveRecord for the command. */
+{
+    Slave *slavePtr;		/* Interim storage for Slave record. */
+    Tcl_Interp *slaveInterp = clientData;
+				/* And for a slave interp. */
+
+    slavePtr = &((InterpInfo *) ((Interp *) slaveInterp)->interpInfo)->slave;
+
+    /*
+     * Unlink the slave from its master interpreter.
+     */
+
+    Tcl_DeleteHashEntry(slavePtr->slaveEntryPtr);
+
+    /*
+     * Set to NULL so that when the InterpInfo is cleaned up in the slave it
+     * does not try to delete the command causing all sorts of grief. See
+     * SlaveRecordDeleteProc().
+     */
+
+    slavePtr->interpCmd = NULL;
+
+    if (slavePtr->slaveInterp != NULL) {
+	Tcl_DeleteInterp(slavePtr->slaveInterp);
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * SlaveDebugCmd -- TIP #378
+ *
+ *	Helper function to handle 'debug' command in a slave interpreter.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	May modify INTERP_DEBUG_FRAME flag in the slave.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+SlaveDebugCmd(
+    Tcl_Interp *interp,		/* Interp for error return. */
+    Tcl_Interp *slaveInterp,	/* The slave interpreter in which command
+				 * will be evaluated. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    static const char *const debugTypes[] = {
+	"-frame", NULL
+    };
+    enum DebugTypes {
+	DEBUG_TYPE_FRAME
+    };
+    int debugType;
+    Interp *iPtr;
+    Tcl_Obj *resultPtr;
+
+    iPtr = (Interp *) slaveInterp;
+    if (objc == 0) {
+	resultPtr = Tcl_NewObj();
+	Tcl_ListObjAppendElement(NULL, resultPtr,
+		Tcl_NewStringObj("-frame", -1));
+	Tcl_ListObjAppendElement(NULL, resultPtr,
+		Tcl_NewBooleanObj(iPtr->flags & INTERP_DEBUG_FRAME));
+	Tcl_SetObjResult(interp, resultPtr);
+    } else {
+	if (Tcl_GetIndexFromObj(interp, objv[0], debugTypes, "debug option",
+		0, &debugType) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	if (debugType == DEBUG_TYPE_FRAME) {
+	    if (objc == 2) { /* set */
+		if (Tcl_GetBooleanFromObj(interp, objv[1], &debugType)
+			!= TCL_OK) {
+		    return TCL_ERROR;
+		}
+
+		/*
+		 * Quietly ignore attempts to disable interp debugging.  This
+		 * is a one-way switch as frame debug info is maintained in a
+		 * stack that must be consistent once turned on.
+		 */
+
+		if (debugType) {
+		    iPtr->flags |= INTERP_DEBUG_FRAME;
+		}
+	    }
+	    Tcl_SetObjResult(interp,
+		    Tcl_NewBooleanObj(iPtr->flags & INTERP_DEBUG_FRAME));
+	}
+    }
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * SlaveEval --
+ *
+ *	Helper function to evaluate a command in a slave interpreter.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	Whatever the command does.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+SlaveEval(
+    Tcl_Interp *interp,		/* Interp for error return. */
+    Tcl_Interp *slaveInterp,	/* The slave interpreter in which command
+				 * will be evaluated. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    int result;
+
+    /*
+     * TIP #285: If necessary, reset the cancellation flags for the slave
+     * interpreter now; otherwise, canceling a script in a master interpreter
+     * can result in a situation where a slave interpreter can no longer
+     * evaluate any scripts unless somebody calls the TclResetCancellation
+     * function for that particular Tcl_Interp.
+     */
+
+    TclSetSlaveCancelFlags(slaveInterp, 0, 0);
+
+    Tcl_Preserve(slaveInterp);
+    Tcl_AllowExceptions(slaveInterp);
+
+    if (objc == 1) {
+	/*
+	 * TIP #280: Make actual argument location available to eval'd script.
+	 */
+
+	Interp *iPtr = (Interp *) interp;
+	CmdFrame *invoker = iPtr->cmdFramePtr;
+	int word = 0;
+
+	TclArgumentGet(interp, objv[0], &invoker, &word);
+
+	result = TclEvalObjEx(slaveInterp, objv[0], 0, invoker, word);
+    } else {
+	Tcl_Obj *objPtr = Tcl_ConcatObj(objc, objv);
+	Tcl_IncrRefCount(objPtr);
+	result = Tcl_EvalObjEx(slaveInterp, objPtr, 0);
+	Tcl_DecrRefCount(objPtr);
+    }
+    Tcl_TransferResult(slaveInterp, result, interp);
+
+    Tcl_Release(slaveInterp);
+    return result;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * SlaveExpose --
+ *
+ *	Helper function to expose a command in a slave interpreter.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	After this call scripts in the slave will be able to invoke the newly
+ *	exposed command.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+SlaveExpose(
+    Tcl_Interp *interp,		/* Interp for error return. */
+    Tcl_Interp *slaveInterp,	/* Interp in which command will be exposed. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument strings. */
+{
+    const char *name;
+
+    if (Tcl_IsSafe(interp)) {
+	Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		"permission denied: safe interpreter cannot expose commands",
+		-1));
+	Tcl_SetErrorCode(interp, "TCL", "OPERATION", "INTERP", "UNSAFE",
+		NULL);
+	return TCL_ERROR;
+    }
+
+    name = TclGetString(objv[(objc == 1) ? 0 : 1]);
+    if (Tcl_ExposeCommand(slaveInterp, TclGetString(objv[0]),
+	    name) != TCL_OK) {
+	Tcl_TransferResult(slaveInterp, TCL_ERROR, interp);
+	return TCL_ERROR;
+    }
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * SlaveRecursionLimit --
+ *
+ *	Helper function to set/query the Recursion limit of an interp
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	When (objc == 1), slaveInterp will be set to a new recursion limit of
+ *	objv[0].
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+SlaveRecursionLimit(
+    Tcl_Interp *interp,		/* Interp for error return. */
+    Tcl_Interp *slaveInterp,	/* Interp in which limit is set/queried. */
+    int objc,			/* Set or Query. */
+    Tcl_Obj *const objv[])	/* Argument strings. */
+{
+    Interp *iPtr;
+    int limit;
+
+    if (objc) {
+	if (Tcl_IsSafe(interp)) {
+	    Tcl_SetObjResult(interp, Tcl_NewStringObj("permission denied: "
+		    "safe interpreters cannot change recursion limit", -1));
+	    Tcl_SetErrorCode(interp, "TCL", "OPERATION", "INTERP", "UNSAFE",
+		    NULL);
+	    return TCL_ERROR;
+	}
+	if (TclGetIntFromObj(interp, objv[0], &limit) == TCL_ERROR) {
+	    return TCL_ERROR;
+	}
+	if (limit <= 0) {
+	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		    "recursion limit must be > 0", -1));
+	    Tcl_SetErrorCode(interp, "TCL", "OPERATION", "INTERP", "BADLIMIT",
+		    NULL);
+	    return TCL_ERROR;
+	}
+	Tcl_SetRecursionLimit(slaveInterp, limit);
+	iPtr = (Interp *) slaveInterp;
+	if (interp == slaveInterp && iPtr->numLevels > limit) {
+	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		    "falling back due to new recursion limit", -1));
+	    Tcl_SetErrorCode(interp, "TCL", "RECURSION", NULL);
+	    return TCL_ERROR;
+	}
+	Tcl_SetObjResult(interp, objv[0]);
+	return TCL_OK;
+    } else {
+	limit = Tcl_SetRecursionLimit(slaveInterp, 0);
+	Tcl_SetObjResult(interp, Tcl_NewIntObj(limit));
+	return TCL_OK;
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * SlaveHide --
+ *
+ *	Helper function to hide a command in a slave interpreter.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	After this call scripts in the slave will no longer be able to invoke
+ *	the named command.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+SlaveHide(
+    Tcl_Interp *interp,		/* Interp for error return. */
+    Tcl_Interp *slaveInterp,	/* Interp in which command will be exposed. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument strings. */
+{
+    const char *name;
+
+    if (Tcl_IsSafe(interp)) {
+	Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		"permission denied: safe interpreter cannot hide commands",
+		-1));
+	Tcl_SetErrorCode(interp, "TCL", "OPERATION", "INTERP", "UNSAFE",
+		NULL);
+	return TCL_ERROR;
+    }
+
+    name = TclGetString(objv[(objc == 1) ? 0 : 1]);
+    if (Tcl_HideCommand(slaveInterp, TclGetString(objv[0]), name) != TCL_OK) {
+	Tcl_TransferResult(slaveInterp, TCL_ERROR, interp);
+	return TCL_ERROR;
+    }
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * SlaveHidden --
+ *
+ *	Helper function to compute list of hidden commands in a slave
+ *	interpreter.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+SlaveHidden(
+    Tcl_Interp *interp,		/* Interp for data return. */
+    Tcl_Interp *slaveInterp)	/* Interp whose hidden commands to query. */
+{
+    Tcl_Obj *listObjPtr = Tcl_NewObj();	/* Local object pointer. */
+    Tcl_HashTable *hTblPtr;		/* For local searches. */
+    Tcl_HashEntry *hPtr;		/* For local searches. */
+    Tcl_HashSearch hSearch;		/* For local searches. */
+
+    hTblPtr = ((Interp *) slaveInterp)->hiddenCmdTablePtr;
+    if (hTblPtr != NULL) {
+	for (hPtr = Tcl_FirstHashEntry(hTblPtr, &hSearch);
+		hPtr != NULL;
+		hPtr = Tcl_NextHashEntry(&hSearch)) {
+	    Tcl_ListObjAppendElement(NULL, listObjPtr,
+		    Tcl_NewStringObj(Tcl_GetHashKey(hTblPtr, hPtr), -1));
+	}
+    }
+    Tcl_SetObjResult(interp, listObjPtr);
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * SlaveInvokeHidden --
+ *
+ *	Helper function to invoke a hidden command in a slave interpreter.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	Whatever the hidden command does.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+SlaveInvokeHidden(
+    Tcl_Interp *interp,		/* Interp for error return. */
+    Tcl_Interp *slaveInterp,	/* The slave interpreter in which command will
+				 * be invoked. */
+    const char *namespaceName,	/* The namespace to use, if any. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    int result;
+
+    if (Tcl_IsSafe(interp)) {
+	Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		"not allowed to invoke hidden commands from safe interpreter",
+		-1));
+	Tcl_SetErrorCode(interp, "TCL", "OPERATION", "INTERP", "UNSAFE",
+		NULL);
+	return TCL_ERROR;
+    }
+
+    Tcl_Preserve(slaveInterp);
+    Tcl_AllowExceptions(slaveInterp);
+
+    if (namespaceName == NULL) {
+	NRE_callback *rootPtr = TOP_CB(slaveInterp);
+
+	Tcl_NRAddCallback(interp, NRPostInvokeHidden, slaveInterp,
+		rootPtr, NULL, NULL);
+	return TclNRInvoke(NULL, slaveInterp, objc, objv);
+    } else {
+	Namespace *nsPtr, *dummy1, *dummy2;
+	const char *tail;
+
+	result = TclGetNamespaceForQualName(slaveInterp, namespaceName, NULL,
+		TCL_FIND_ONLY_NS | TCL_GLOBAL_ONLY | TCL_LEAVE_ERR_MSG
+		| TCL_CREATE_NS_IF_UNKNOWN, &nsPtr, &dummy1, &dummy2, &tail);
+	if (result == TCL_OK) {
+	    result = TclObjInvokeNamespace(slaveInterp, objc, objv,
+		    (Tcl_Namespace *) nsPtr, TCL_INVOKE_HIDDEN);
+	}
+    }
+
+    Tcl_TransferResult(slaveInterp, result, interp);
+
+    Tcl_Release(slaveInterp);
+    return result;
+}
+
+static int
+NRPostInvokeHidden(
+    ClientData data[],
+    Tcl_Interp *interp,
+    int result)
+{
+    Tcl_Interp *slaveInterp = (Tcl_Interp *)data[0];
+    NRE_callback *rootPtr = (NRE_callback *)data[1];
+
+    if (interp != slaveInterp) {
+	result = TclNRRunCallbacks(slaveInterp, result, rootPtr);
+	Tcl_TransferResult(slaveInterp, result, interp);
+    }
+    Tcl_Release(slaveInterp);
+    return result;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * SlaveMarkTrusted --
+ *
+ *	Helper function to mark a slave interpreter as trusted (unsafe).
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	After this call the hard-wired security checks in the core no longer
+ *	prevent the slave from performing certain operations.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+SlaveMarkTrusted(
+    Tcl_Interp *interp,		/* Interp for error return. */
+    Tcl_Interp *slaveInterp)	/* The slave interpreter which will be marked
+				 * trusted. */
+{
+    if (Tcl_IsSafe(interp)) {
+	Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		"permission denied: safe interpreter cannot mark trusted",
+		-1));
+	Tcl_SetErrorCode(interp, "TCL", "OPERATION", "INTERP", "UNSAFE",
+		NULL);
+	return TCL_ERROR;
+    }
+    ((Interp *) slaveInterp)->flags &= ~SAFE_INTERP;
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_IsSafe --
+ *
+ *	Determines whether an interpreter is safe
+ *
+ * Results:
+ *	1 if it is safe, 0 if it is not.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_IsSafe(
+    Tcl_Interp *interp)		/* Is this interpreter "safe" ? */
+{
+    Interp *iPtr = (Interp *) interp;
+
+    if (iPtr == NULL) {
+	return 0;
+    }
+    return (iPtr->flags & SAFE_INTERP) ? 1 : 0;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_MakeSafe --
+ *
+ *	Makes its argument interpreter contain only functionality that is
+ *	defined to be part of Safe Tcl. Unsafe commands are hidden, the env
+ *	array is unset, and the standard channels are removed.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Hides commands in its argument interpreter, and removes settings and
+ *	channels.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_MakeSafe(
+    Tcl_Interp *interp)		/* Interpreter to be made safe. */
+{
+    Tcl_Channel chan;		/* Channel to remove from safe interpreter. */
+    Interp *iPtr = (Interp *) interp;
+    Tcl_Interp *master = ((InterpInfo*) iPtr->interpInfo)->slave.masterInterp;
+
+    TclHideUnsafeCommands(interp);
+
+    if (master != NULL) {
+	/*
+	 * Alias these function implementations in the slave to those in the
+	 * master; the overall implementations are safe, but they're normally
+	 * defined by init.tcl which is not sourced by safe interpreters.
+	 * Assume these functions all work. [Bug 2895741]
+	 */
+
+	(void) Tcl_Eval(interp,
+		"namespace eval ::tcl {namespace eval mathfunc {}}");
+	(void) Tcl_CreateAlias(interp, "::tcl::mathfunc::min", master,
+		"::tcl::mathfunc::min", 0, NULL);
+	(void) Tcl_CreateAlias(interp, "::tcl::mathfunc::max", master,
+		"::tcl::mathfunc::max", 0, NULL);
+    }
+
+    iPtr->flags |= SAFE_INTERP;
+
+    /*
+     * Unsetting variables : (which should not have been set in the first
+     * place, but...)
+     */
+
+    /*
+     * No env array in a safe slave.
+     */
+
+    Tcl_UnsetVar(interp, "env", TCL_GLOBAL_ONLY);
+
+    /*
+     * Remove unsafe parts of tcl_platform
+     */
+
+    Tcl_UnsetVar2(interp, "tcl_platform", "os", TCL_GLOBAL_ONLY);
+    Tcl_UnsetVar2(interp, "tcl_platform", "osVersion", TCL_GLOBAL_ONLY);
+    Tcl_UnsetVar2(interp, "tcl_platform", "machine", TCL_GLOBAL_ONLY);
+    Tcl_UnsetVar2(interp, "tcl_platform", "user", TCL_GLOBAL_ONLY);
+
+    /*
+     * Unset path informations variables (the only one remaining is [info
+     * nameofexecutable])
+     */
+
+    Tcl_UnsetVar(interp, "tclDefaultLibrary", TCL_GLOBAL_ONLY);
+    Tcl_UnsetVar(interp, "tcl_library", TCL_GLOBAL_ONLY);
+    Tcl_UnsetVar(interp, "tcl_pkgPath", TCL_GLOBAL_ONLY);
+
+    /*
+     * Remove the standard channels from the interpreter; safe interpreters do
+     * not ordinarily have access to stdin, stdout and stderr.
+     *
+     * NOTE: These channels are not added to the interpreter by the
+     * Tcl_CreateInterp call, but may be added later, by another I/O
+     * operation. We want to ensure that the interpreter does not have these
+     * channels even if it is being made safe after being used for some time..
+     */
+
+    chan = Tcl_GetStdChannel(TCL_STDIN);
+    if (chan != NULL) {
+	Tcl_UnregisterChannel(interp, chan);
+    }
+    chan = Tcl_GetStdChannel(TCL_STDOUT);
+    if (chan != NULL) {
+	Tcl_UnregisterChannel(interp, chan);
+    }
+    chan = Tcl_GetStdChannel(TCL_STDERR);
+    if (chan != NULL) {
+	Tcl_UnregisterChannel(interp, chan);
+    }
+
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_LimitExceeded --
+ *
+ *	Tests whether any limit has been exceeded in the given interpreter
+ *	(i.e. whether the interpreter is currently unable to process further
+ *	scripts).
+ *
+ * Results:
+ *	A boolean value.
+ *
+ * Side effects:
+ *	None.
+ *
+ * Notes:
+ *	If you change this function, you MUST also update TclLimitExceeded() in
+ *	tclInt.h.
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_LimitExceeded(
+    Tcl_Interp *interp)
+{
+    register Interp *iPtr = (Interp *) interp;
+
+    return iPtr->limit.exceeded != 0;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_LimitReady --
+ *
+ *	Find out whether any limit has been set on the interpreter, and if so
+ *	check whether the granularity of that limit is such that the full
+ *	limit check should be carried out.
+ *
+ * Results:
+ *	A boolean value that indicates whether to call Tcl_LimitCheck.
+ *
+ * Side effects:
+ *	Increments the limit granularity counter.
+ *
+ * Notes:
+ *	If you change this function, you MUST also update TclLimitReady() in
+ *	tclInt.h.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_LimitReady(
+    Tcl_Interp *interp)
+{
+    register Interp *iPtr = (Interp *) interp;
+
+    if (iPtr->limit.active != 0) {
+	register int ticker = ++iPtr->limit.granularityTicker;
+
+	if ((iPtr->limit.active & TCL_LIMIT_COMMANDS) &&
+		((iPtr->limit.cmdGranularity == 1) ||
+		    (ticker % iPtr->limit.cmdGranularity == 0))) {
+	    return 1;
+	}
+	if ((iPtr->limit.active & TCL_LIMIT_TIME) &&
+		((iPtr->limit.timeGranularity == 1) ||
+		    (ticker % iPtr->limit.timeGranularity == 0))) {
+	    return 1;
+	}
+    }
+    return 0;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_LimitCheck --
+ *
+ *	Check all currently set limits in the interpreter (where permitted by
+ *	granularity). If a limit is exceeded, call its callbacks and, if the
+ *	limit is still exceeded after the callbacks have run, make the
+ *	interpreter generate an error that cannot be caught within the limited
+ *	interpreter.
+ *
+ * Results:
+ *	A Tcl result value (TCL_OK if no limit is exceeded, and TCL_ERROR if a
+ *	limit has been exceeded).
+ *
+ * Side effects:
+ *	May invoke system calls. May invoke other interpreters. May be
+ *	reentrant. May put the interpreter into a state where it can no longer
+ *	execute commands without outside intervention.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_LimitCheck(
+    Tcl_Interp *interp)
+{
+    Interp *iPtr = (Interp *) interp;
+    register int ticker = iPtr->limit.granularityTicker;
+
+    if (Tcl_InterpDeleted(interp)) {
+	return TCL_OK;
+    }
+
+    if ((iPtr->limit.active & TCL_LIMIT_COMMANDS) &&
+	    ((iPtr->limit.cmdGranularity == 1) ||
+		    (ticker % iPtr->limit.cmdGranularity == 0)) &&
+	    (iPtr->limit.cmdCount < iPtr->cmdCount)) {
+	iPtr->limit.exceeded |= TCL_LIMIT_COMMANDS;
+	Tcl_Preserve(interp);
+	RunLimitHandlers(iPtr->limit.cmdHandlers, interp);
+	if (iPtr->limit.cmdCount >= iPtr->cmdCount) {
+	    iPtr->limit.exceeded &= ~TCL_LIMIT_COMMANDS;
+	} else if (iPtr->limit.exceeded & TCL_LIMIT_COMMANDS) {
+	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		    "command count limit exceeded", -1));
+	    Tcl_SetErrorCode(interp, "TCL", "LIMIT", "COMMANDS", NULL);
+	    Tcl_Release(interp);
+	    return TCL_ERROR;
+	}
+	Tcl_Release(interp);
+    }
+
+    if ((iPtr->limit.active & TCL_LIMIT_TIME) &&
+	    ((iPtr->limit.timeGranularity == 1) ||
+		(ticker % iPtr->limit.timeGranularity == 0))) {
+	Tcl_Time now;
+
+	Tcl_GetTime(&now);
+	if (iPtr->limit.time.sec < now.sec ||
+		(iPtr->limit.time.sec == now.sec &&
+		iPtr->limit.time.usec < now.usec)) {
+	    iPtr->limit.exceeded |= TCL_LIMIT_TIME;
+	    Tcl_Preserve(interp);
+	    RunLimitHandlers(iPtr->limit.timeHandlers, interp);
+	    if (iPtr->limit.time.sec > now.sec ||
+		    (iPtr->limit.time.sec == now.sec &&
+		    iPtr->limit.time.usec >= now.usec)) {
+		iPtr->limit.exceeded &= ~TCL_LIMIT_TIME;
+	    } else if (iPtr->limit.exceeded & TCL_LIMIT_TIME) {
+		Tcl_SetObjResult(interp, Tcl_NewStringObj(
+			"time limit exceeded", -1));
+		Tcl_SetErrorCode(interp, "TCL", "LIMIT", "TIME", NULL);
+		Tcl_Release(interp);
+		return TCL_ERROR;
+	    }
+	    Tcl_Release(interp);
+	}
+    }
+
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * RunLimitHandlers --
+ *
+ *	Invoke all the limit handlers in a list (for a particular limit).
+ *	Note that no particular limit handler callback will be invoked
+ *	reentrantly.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Depends on the limit handlers.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+RunLimitHandlers(
+    LimitHandler *handlerPtr,
+    Tcl_Interp *interp)
+{
+    LimitHandler *nextPtr;
+    for (; handlerPtr!=NULL ; handlerPtr=nextPtr) {
+	if (handlerPtr->flags & (LIMIT_HANDLER_DELETED|LIMIT_HANDLER_ACTIVE)) {
+	    /*
+	     * Reentrant call or something seriously strange in the delete
+	     * code.
+	     */
+
+	    nextPtr = handlerPtr->nextPtr;
+	    continue;
+	}
+
+	/*
+	 * Set the ACTIVE flag while running the limit handler itself so we
+	 * cannot reentrantly call this handler and know to use the alternate
+	 * method of deletion if necessary.
+	 */
+
+	handlerPtr->flags |= LIMIT_HANDLER_ACTIVE;
+	handlerPtr->handlerProc(handlerPtr->clientData, interp);
+	handlerPtr->flags &= ~LIMIT_HANDLER_ACTIVE;
+
+	/*
+	 * Rediscover this value; it might have changed during the processing
+	 * of a limit handler. We have to record it here because we might
+	 * delete the structure below, and reading a value out of a deleted
+	 * structure is unsafe (even if actually legal with some
+	 * malloc()/free() implementations.)
+	 */
+
+	nextPtr = handlerPtr->nextPtr;
+
+	/*
+	 * If we deleted the current handler while we were executing it, we
+	 * will have spliced it out of the list and set the
+	 * LIMIT_HANDLER_DELETED flag.
+	 */
+
+	if (handlerPtr->flags & LIMIT_HANDLER_DELETED) {
+	    if (handlerPtr->deleteProc != NULL) {
+		handlerPtr->deleteProc(handlerPtr->clientData);
+	    }
+	    ckfree(handlerPtr);
+	}
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_LimitAddHandler --
+ *
+ *	Add a callback handler for a particular resource limit.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Extends the internal linked list of handlers for a limit.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_LimitAddHandler(
+    Tcl_Interp *interp,
+    int type,
+    Tcl_LimitHandlerProc *handlerProc,
+    ClientData clientData,
+    Tcl_LimitHandlerDeleteProc *deleteProc)
+{
+    Interp *iPtr = (Interp *) interp;
+    LimitHandler *handlerPtr;
+
+    /*
+     * Convert everything into a real deletion callback.
+     */
+
+    if (deleteProc == (Tcl_LimitHandlerDeleteProc *) TCL_DYNAMIC) {
+	deleteProc = (Tcl_LimitHandlerDeleteProc *) Tcl_Free;
+    }
+    if (deleteProc == (Tcl_LimitHandlerDeleteProc *) TCL_STATIC) {
+	deleteProc = NULL;
+    }
+
+    /*
+     * Allocate a handler record.
+     */
+
+    handlerPtr = ckalloc(sizeof(LimitHandler));
+    handlerPtr->flags = 0;
+    handlerPtr->handlerProc = handlerProc;
+    handlerPtr->clientData = clientData;
+    handlerPtr->deleteProc = deleteProc;
+    handlerPtr->prevPtr = NULL;
+
+    /*
+     * Prepend onto the front of the correct linked list.
+     */
+
+    switch (type) {
+    case TCL_LIMIT_COMMANDS:
+	handlerPtr->nextPtr = iPtr->limit.cmdHandlers;
+	if (handlerPtr->nextPtr != NULL) {
+	    handlerPtr->nextPtr->prevPtr = handlerPtr;
+	}
+	iPtr->limit.cmdHandlers = handlerPtr;
+	return;
+
+    case TCL_LIMIT_TIME:
+	handlerPtr->nextPtr = iPtr->limit.timeHandlers;
+	if (handlerPtr->nextPtr != NULL) {
+	    handlerPtr->nextPtr->prevPtr = handlerPtr;
+	}
+	iPtr->limit.timeHandlers = handlerPtr;
+	return;
+    }
+
+    Tcl_Panic("unknown type of resource limit");
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_LimitRemoveHandler --
+ *
+ *	Remove a callback handler for a particular resource limit.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The handler is spliced out of the internal linked list for the limit,
+ *	and if not currently being invoked, deleted. Otherwise it is just
+ *	marked for deletion and removed when the limit handler has finished
+ *	executing.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_LimitRemoveHandler(
+    Tcl_Interp *interp,
+    int type,
+    Tcl_LimitHandlerProc *handlerProc,
+    ClientData clientData)
+{
+    Interp *iPtr = (Interp *) interp;
+    LimitHandler *handlerPtr;
+
+    switch (type) {
+    case TCL_LIMIT_COMMANDS:
+	handlerPtr = iPtr->limit.cmdHandlers;
+	break;
+    case TCL_LIMIT_TIME:
+	handlerPtr = iPtr->limit.timeHandlers;
+	break;
+    default:
+	Tcl_Panic("unknown type of resource limit");
+	return;
+    }
+
+    for (; handlerPtr!=NULL ; handlerPtr=handlerPtr->nextPtr) {
+	if ((handlerPtr->handlerProc != handlerProc) ||
+		(handlerPtr->clientData != clientData)) {
+	    continue;
+	}
+
+	/*
+	 * We've found the handler to delete; mark it as doomed if not already
+	 * so marked (which shouldn't actually happen).
+	 */
+
+	if (handlerPtr->flags & LIMIT_HANDLER_DELETED) {
+	    return;
+	}
+	handlerPtr->flags |= LIMIT_HANDLER_DELETED;
+
+	/*
+	 * Splice the handler out of the doubly-linked list.
+	 */
+
+	if (handlerPtr->prevPtr == NULL) {
+	    switch (type) {
+	    case TCL_LIMIT_COMMANDS:
+		iPtr->limit.cmdHandlers = handlerPtr->nextPtr;
+		break;
+	    case TCL_LIMIT_TIME:
+		iPtr->limit.timeHandlers = handlerPtr->nextPtr;
+		break;
+	    }
+	} else {
+	    handlerPtr->prevPtr->nextPtr = handlerPtr->nextPtr;
+	}
+	if (handlerPtr->nextPtr != NULL) {
+	    handlerPtr->nextPtr->prevPtr = handlerPtr->prevPtr;
+	}
+
+	/*
+	 * If nothing is currently executing the handler, delete its client
+	 * data and the overall handler structure now. Otherwise it will all
+	 * go away when the handler returns.
+	 */
+
+	if (!(handlerPtr->flags & LIMIT_HANDLER_ACTIVE)) {
+	    if (handlerPtr->deleteProc != NULL) {
+		handlerPtr->deleteProc(handlerPtr->clientData);
+	    }
+	    ckfree(handlerPtr);
+	}
+	return;
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclLimitRemoveAllHandlers --
+ *
+ *	Remove all limit callback handlers for an interpreter. This is invoked
+ *	as part of deleting the interpreter.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Limit handlers are deleted or marked for deletion (as with
+ *	Tcl_LimitRemoveHandler).
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclLimitRemoveAllHandlers(
+    Tcl_Interp *interp)
+{
+    Interp *iPtr = (Interp *) interp;
+    LimitHandler *handlerPtr, *nextHandlerPtr;
+
+    /*
+     * Delete all command-limit handlers.
+     */
+
+    for (handlerPtr=iPtr->limit.cmdHandlers, iPtr->limit.cmdHandlers=NULL;
+	    handlerPtr!=NULL; handlerPtr=nextHandlerPtr) {
+	nextHandlerPtr = handlerPtr->nextPtr;
+
+	/*
+	 * Do not delete here if it has already been marked for deletion.
+	 */
+
+	if (handlerPtr->flags & LIMIT_HANDLER_DELETED) {
+	    continue;
+	}
+	handlerPtr->flags |= LIMIT_HANDLER_DELETED;
+	handlerPtr->prevPtr = NULL;
+	handlerPtr->nextPtr = NULL;
+
+	/*
+	 * If nothing is currently executing the handler, delete its client
+	 * data and the overall handler structure now. Otherwise it will all
+	 * go away when the handler returns.
+	 */
+
+	if (!(handlerPtr->flags & LIMIT_HANDLER_ACTIVE)) {
+	    if (handlerPtr->deleteProc != NULL) {
+		handlerPtr->deleteProc(handlerPtr->clientData);
+	    }
+	    ckfree(handlerPtr);
+	}
+    }
+
+    /*
+     * Delete all time-limit handlers.
+     */
+
+    for (handlerPtr=iPtr->limit.timeHandlers, iPtr->limit.timeHandlers=NULL;
+	    handlerPtr!=NULL; handlerPtr=nextHandlerPtr) {
+	nextHandlerPtr = handlerPtr->nextPtr;
+
+	/*
+	 * Do not delete here if it has already been marked for deletion.
+	 */
+
+	if (handlerPtr->flags & LIMIT_HANDLER_DELETED) {
+	    continue;
+	}
+	handlerPtr->flags |= LIMIT_HANDLER_DELETED;
+	handlerPtr->prevPtr = NULL;
+	handlerPtr->nextPtr = NULL;
+
+	/*
+	 * If nothing is currently executing the handler, delete its client
+	 * data and the overall handler structure now. Otherwise it will all
+	 * go away when the handler returns.
+	 */
+
+	if (!(handlerPtr->flags & LIMIT_HANDLER_ACTIVE)) {
+	    if (handlerPtr->deleteProc != NULL) {
+		handlerPtr->deleteProc(handlerPtr->clientData);
+	    }
+	    ckfree(handlerPtr);
+	}
+    }
+
+    /*
+     * Delete the timer callback that is used to trap limits that occur in
+     * [vwait]s...
+     */
+
+    if (iPtr->limit.timeEvent != NULL) {
+	Tcl_DeleteTimerHandler(iPtr->limit.timeEvent);
+	iPtr->limit.timeEvent = NULL;
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_LimitTypeEnabled --
+ *
+ *	Check whether a particular limit has been enabled for an interpreter.
+ *
+ * Results:
+ *	A boolean value.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_LimitTypeEnabled(
+    Tcl_Interp *interp,
+    int type)
+{
+    Interp *iPtr = (Interp *) interp;
+
+    return (iPtr->limit.active & type) != 0;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_LimitTypeExceeded --
+ *
+ *	Check whether a particular limit has been exceeded for an interpreter.
+ *
+ * Results:
+ *	A boolean value (note that Tcl_LimitExceeded will always return
+ *	non-zero when this function returns non-zero).
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_LimitTypeExceeded(
+    Tcl_Interp *interp,
+    int type)
+{
+    Interp *iPtr = (Interp *) interp;
+
+    return (iPtr->limit.exceeded & type) != 0;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_LimitTypeSet --
+ *
+ *	Enable a particular limit for an interpreter.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The limit is turned on and will be checked in future at an interval
+ *	determined by the frequency of calling of Tcl_LimitReady and the
+ *	granularity of the limit in question.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_LimitTypeSet(
+    Tcl_Interp *interp,
+    int type)
+{
+    Interp *iPtr = (Interp *) interp;
+
+    iPtr->limit.active |= type;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_LimitTypeReset --
+ *
+ *	Disable a particular limit for an interpreter.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The limit is disabled. If the limit was exceeded when this function
+ *	was called, the limit will no longer be exceeded afterwards and the
+ *	interpreter will be free to execute further scripts (assuming it isn't
+ *	also deleted, of course).
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_LimitTypeReset(
+    Tcl_Interp *interp,
+    int type)
+{
+    Interp *iPtr = (Interp *) interp;
+
+    iPtr->limit.active &= ~type;
+    iPtr->limit.exceeded &= ~type;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_LimitSetCommands --
+ *
+ *	Set the command limit for an interpreter.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Also resets whether the command limit was exceeded. This might permit
+ *	a small amount of further execution in the interpreter even if the
+ *	limit itself is theoretically exceeded.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_LimitSetCommands(
+    Tcl_Interp *interp,
+    int commandLimit)
+{
+    Interp *iPtr = (Interp *) interp;
+
+    iPtr->limit.cmdCount = commandLimit;
+    iPtr->limit.exceeded &= ~TCL_LIMIT_COMMANDS;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_LimitGetCommands --
+ *
+ *	Get the number of commands that may be executed in the interpreter
+ *	before the command-limit is reached.
+ *
+ * Results:
+ *	An upper bound on the number of commands.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_LimitGetCommands(
+    Tcl_Interp *interp)
+{
+    Interp *iPtr = (Interp *) interp;
+
+    return iPtr->limit.cmdCount;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_LimitSetTime --
+ *
+ *	Set the time limit for an interpreter by copying it from the value
+ *	pointed to by the timeLimitPtr argument.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Also resets whether the time limit was exceeded. This might permit a
+ *	small amount of further execution in the interpreter even if the limit
+ *	itself is theoretically exceeded.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_LimitSetTime(
+    Tcl_Interp *interp,
+    Tcl_Time *timeLimitPtr)
+{
+    Interp *iPtr = (Interp *) interp;
+    Tcl_Time nextMoment;
+
+    memcpy(&iPtr->limit.time, timeLimitPtr, sizeof(Tcl_Time));
+    if (iPtr->limit.timeEvent != NULL) {
+	Tcl_DeleteTimerHandler(iPtr->limit.timeEvent);
+    }
+    nextMoment.sec = timeLimitPtr->sec;
+    nextMoment.usec = timeLimitPtr->usec+10;
+    if (nextMoment.usec >= 1000000) {
+	nextMoment.sec++;
+	nextMoment.usec -= 1000000;
+    }
+    iPtr->limit.timeEvent = TclCreateAbsoluteTimerHandler(&nextMoment,
+	    TimeLimitCallback, interp);
+    iPtr->limit.exceeded &= ~TCL_LIMIT_TIME;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TimeLimitCallback --
+ *
+ *	Callback that allows time limits to be enforced even when doing a
+ *	blocking wait for events.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	May put the interpreter into a state where it can no longer execute
+ *	commands. May make callbacks into other interpreters.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+TimeLimitCallback(
+    ClientData clientData)
+{
+    Tcl_Interp *interp = clientData;
+    Interp *iPtr = clientData;
+    int code;
+
+    Tcl_Preserve(interp);
+    iPtr->limit.timeEvent = NULL;
+
+    /*
+     * Must reset the granularity ticker here to force an immediate full
+     * check. This is OK because we're swallowing the cost in the overall cost
+     * of the event loop. [Bug 2891362]
+     */
+
+    iPtr->limit.granularityTicker = 0;
+
+    code = Tcl_LimitCheck(interp);
+    if (code != TCL_OK) {
+	Tcl_AddErrorInfo(interp, "\n    (while waiting for event)");
+	Tcl_BackgroundException(interp, code);
+    }
+    Tcl_Release(interp);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_LimitGetTime --
+ *
+ *	Get the current time limit.
+ *
+ * Results:
+ *	The time limit (by it being copied into the variable pointed to by the
+ *	timeLimitPtr).
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_LimitGetTime(
+    Tcl_Interp *interp,
+    Tcl_Time *timeLimitPtr)
+{
+    Interp *iPtr = (Interp *) interp;
+
+    memcpy(timeLimitPtr, &iPtr->limit.time, sizeof(Tcl_Time));
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_LimitSetGranularity --
+ *
+ *	Set the granularity divisor (which must be positive) for a particular
+ *	limit.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The granularity is updated.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_LimitSetGranularity(
+    Tcl_Interp *interp,
+    int type,
+    int granularity)
+{
+    Interp *iPtr = (Interp *) interp;
+    if (granularity < 1) {
+	Tcl_Panic("limit granularity must be positive");
+    }
+
+    switch (type) {
+    case TCL_LIMIT_COMMANDS:
+	iPtr->limit.cmdGranularity = granularity;
+	return;
+    case TCL_LIMIT_TIME:
+	iPtr->limit.timeGranularity = granularity;
+	return;
+    }
+    Tcl_Panic("unknown type of resource limit");
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_LimitGetGranularity --
+ *
+ *	Get the granularity divisor for a particular limit.
+ *
+ * Results:
+ *	The granularity divisor for the given limit.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_LimitGetGranularity(
+    Tcl_Interp *interp,
+    int type)
+{
+    Interp *iPtr = (Interp *) interp;
+
+    switch (type) {
+    case TCL_LIMIT_COMMANDS:
+	return iPtr->limit.cmdGranularity;
+    case TCL_LIMIT_TIME:
+	return iPtr->limit.timeGranularity;
+    }
+    Tcl_Panic("unknown type of resource limit");
+    return -1; /* NOT REACHED */
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * DeleteScriptLimitCallback --
+ *
+ *	Callback for when a script limit (a limit callback implemented as a
+ *	Tcl script in a master interpreter, as set up from Tcl) is deleted.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The reference to the script callback from the controlling interpreter
+ *	is removed.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+DeleteScriptLimitCallback(
+    ClientData clientData)
+{
+    ScriptLimitCallback *limitCBPtr = clientData;
+
+    Tcl_DecrRefCount(limitCBPtr->scriptObj);
+    if (limitCBPtr->entryPtr != NULL) {
+	Tcl_DeleteHashEntry(limitCBPtr->entryPtr);
+    }
+    ckfree(limitCBPtr);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * CallScriptLimitCallback --
+ *
+ *	Invoke a script limit callback. Used to implement limit callbacks set
+ *	at the Tcl level on child interpreters.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Depends on the callback script. Errors are reported as background
+ *	errors.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+CallScriptLimitCallback(
+    ClientData clientData,
+    Tcl_Interp *interp)		/* Interpreter which failed the limit */
+{
+    ScriptLimitCallback *limitCBPtr = clientData;
+    int code;
+
+    if (Tcl_InterpDeleted(limitCBPtr->interp)) {
+	return;
+    }
+    Tcl_Preserve(limitCBPtr->interp);
+    code = Tcl_EvalObjEx(limitCBPtr->interp, limitCBPtr->scriptObj,
+	    TCL_EVAL_GLOBAL);
+    if (code != TCL_OK && !Tcl_InterpDeleted(limitCBPtr->interp)) {
+	Tcl_BackgroundException(limitCBPtr->interp, code);
+    }
+    Tcl_Release(limitCBPtr->interp);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * SetScriptLimitCallback --
+ *
+ *	Install (or remove, if scriptObj is NULL) a limit callback script that
+ *	is called when the target interpreter exceeds the type of limit
+ *	specified. Each interpreter may only have one callback set on another
+ *	interpreter through this mechanism (though as many interpreters may be
+ *	limited as the programmer chooses overall).
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	A limit callback implemented as an invokation of a Tcl script in
+ *	another interpreter is either installed or removed.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+SetScriptLimitCallback(
+    Tcl_Interp *interp,
+    int type,
+    Tcl_Interp *targetInterp,
+    Tcl_Obj *scriptObj)
+{
+    ScriptLimitCallback *limitCBPtr;
+    Tcl_HashEntry *hashPtr;
+    int isNew;
+    ScriptLimitCallbackKey key;
+    Interp *iPtr = (Interp *) interp;
+
+    if (interp == targetInterp) {
+	Tcl_Panic("installing limit callback to the limited interpreter");
+    }
+
+    key.interp = targetInterp;
+    key.type = type;
+
+    if (scriptObj == NULL) {
+	hashPtr = Tcl_FindHashEntry(&iPtr->limit.callbacks, (char *) &key);
+	if (hashPtr != NULL) {
+	    Tcl_LimitRemoveHandler(targetInterp, type, CallScriptLimitCallback,
+		    Tcl_GetHashValue(hashPtr));
+	}
+	return;
+    }
+
+    hashPtr = Tcl_CreateHashEntry(&iPtr->limit.callbacks, &key,
+	    &isNew);
+    if (!isNew) {
+	limitCBPtr = Tcl_GetHashValue(hashPtr);
+	limitCBPtr->entryPtr = NULL;
+	Tcl_LimitRemoveHandler(targetInterp, type, CallScriptLimitCallback,
+		limitCBPtr);
+    }
+
+    limitCBPtr = ckalloc(sizeof(ScriptLimitCallback));
+    limitCBPtr->interp = interp;
+    limitCBPtr->scriptObj = scriptObj;
+    limitCBPtr->entryPtr = hashPtr;
+    limitCBPtr->type = type;
+    Tcl_IncrRefCount(scriptObj);
+
+    Tcl_LimitAddHandler(targetInterp, type, CallScriptLimitCallback,
+	    limitCBPtr, DeleteScriptLimitCallback);
+    Tcl_SetHashValue(hashPtr, limitCBPtr);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclRemoveScriptLimitCallbacks --
+ *
+ *	Remove all script-implemented limit callbacks that make calls back
+ *	into the given interpreter. This invoked as part of deleting an
+ *	interpreter.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The script limit callbacks are removed or marked for later removal.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclRemoveScriptLimitCallbacks(
+    Tcl_Interp *interp)
+{
+    Interp *iPtr = (Interp *) interp;
+    Tcl_HashEntry *hashPtr;
+    Tcl_HashSearch search;
+    ScriptLimitCallbackKey *keyPtr;
+
+    hashPtr = Tcl_FirstHashEntry(&iPtr->limit.callbacks, &search);
+    while (hashPtr != NULL) {
+	keyPtr = (ScriptLimitCallbackKey *)
+		Tcl_GetHashKey(&iPtr->limit.callbacks, hashPtr);
+	Tcl_LimitRemoveHandler(keyPtr->interp, keyPtr->type,
+		CallScriptLimitCallback, Tcl_GetHashValue(hashPtr));
+	hashPtr = Tcl_NextHashEntry(&search);
+    }
+    Tcl_DeleteHashTable(&iPtr->limit.callbacks);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclInitLimitSupport --
+ *
+ *	Initialise all the parts of the interpreter relating to resource limit
+ *	management. This allows an interpreter to both have limits set upon
+ *	itself and set limits upon other interpreters.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The resource limit subsystem is initialised for the interpreter.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclInitLimitSupport(
+    Tcl_Interp *interp)
+{
+    Interp *iPtr = (Interp *) interp;
+
+    iPtr->limit.active = 0;
+    iPtr->limit.granularityTicker = 0;
+    iPtr->limit.exceeded = 0;
+    iPtr->limit.cmdCount = 0;
+    iPtr->limit.cmdHandlers = NULL;
+    iPtr->limit.cmdGranularity = 1;
+    memset(&iPtr->limit.time, 0, sizeof(Tcl_Time));
+    iPtr->limit.timeHandlers = NULL;
+    iPtr->limit.timeEvent = NULL;
+    iPtr->limit.timeGranularity = 10;
+    Tcl_InitHashTable(&iPtr->limit.callbacks,
+	    sizeof(ScriptLimitCallbackKey)/sizeof(int));
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * InheritLimitsFromMaster --
+ *
+ *	Derive the interpreter limit configuration for a slave interpreter
+ *	from the limit config for the master.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The slave interpreter limits are set so that if the master has a
+ *	limit, it may not exceed it by handing off work to slave interpreters.
+ *	Note that this does not transfer limit callbacks from the master to
+ *	the slave.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+InheritLimitsFromMaster(
+    Tcl_Interp *slaveInterp,
+    Tcl_Interp *masterInterp)
+{
+    Interp *slavePtr = (Interp *) slaveInterp;
+    Interp *masterPtr = (Interp *) masterInterp;
+
+    if (masterPtr->limit.active & TCL_LIMIT_COMMANDS) {
+	slavePtr->limit.active |= TCL_LIMIT_COMMANDS;
+	slavePtr->limit.cmdCount = 0;
+	slavePtr->limit.cmdGranularity = masterPtr->limit.cmdGranularity;
+    }
+    if (masterPtr->limit.active & TCL_LIMIT_TIME) {
+	slavePtr->limit.active |= TCL_LIMIT_TIME;
+	memcpy(&slavePtr->limit.time, &masterPtr->limit.time,
+		sizeof(Tcl_Time));
+	slavePtr->limit.timeGranularity = masterPtr->limit.timeGranularity;
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * SlaveCommandLimitCmd --
+ *
+ *	Implementation of the [interp limit $i commands] and [$i limit
+ *	commands] subcommands. See the interp manual page for a full
+ *	description.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	Depends on the arguments.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+SlaveCommandLimitCmd(
+    Tcl_Interp *interp,		/* Current interpreter. */
+    Tcl_Interp *slaveInterp,	/* Interpreter being adjusted. */
+    int consumedObjc,		/* Number of args already parsed. */
+    int objc,			/* Total number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    static const char *const options[] = {
+	"-command", "-granularity", "-value", NULL
+    };
+    enum Options {
+	OPT_CMD, OPT_GRAN, OPT_VAL
+    };
+    Interp *iPtr = (Interp *) interp;
+    int index;
+    ScriptLimitCallbackKey key;
+    ScriptLimitCallback *limitCBPtr;
+    Tcl_HashEntry *hPtr;
+
+    /*
+     * First, ensure that we are not reading or writing the calling
+     * interpreter's limits; it may only manipulate its children. Note that
+     * the low level API enforces this with Tcl_Panic, which we want to
+     * avoid. [Bug 3398794]
+     */
+
+    if (interp == slaveInterp) {
+	Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		"limits on current interpreter inaccessible", -1));
+	Tcl_SetErrorCode(interp, "TCL", "OPERATION", "INTERP", "SELF", NULL);
+	return TCL_ERROR;
+    }
+
+    if (objc == consumedObjc) {
+	Tcl_Obj *dictPtr;
+
+	TclNewObj(dictPtr);
+	key.interp = slaveInterp;
+	key.type = TCL_LIMIT_COMMANDS;
+	hPtr = Tcl_FindHashEntry(&iPtr->limit.callbacks, (char *) &key);
+	if (hPtr != NULL) {
+	    limitCBPtr = Tcl_GetHashValue(hPtr);
+	    if (limitCBPtr != NULL && limitCBPtr->scriptObj != NULL) {
+		Tcl_DictObjPut(NULL, dictPtr, Tcl_NewStringObj(options[0], -1),
+			limitCBPtr->scriptObj);
+	    } else {
+		goto putEmptyCommandInDict;
+	    }
+	} else {
+	    Tcl_Obj *empty;
+
+	putEmptyCommandInDict:
+	    TclNewObj(empty);
+	    Tcl_DictObjPut(NULL, dictPtr,
+		    Tcl_NewStringObj(options[0], -1), empty);
+	}
+	Tcl_DictObjPut(NULL, dictPtr, Tcl_NewStringObj(options[1], -1),
+		Tcl_NewIntObj(Tcl_LimitGetGranularity(slaveInterp,
+		TCL_LIMIT_COMMANDS)));
+
+	if (Tcl_LimitTypeEnabled(slaveInterp, TCL_LIMIT_COMMANDS)) {
+	    Tcl_DictObjPut(NULL, dictPtr, Tcl_NewStringObj(options[2], -1),
+		    Tcl_NewIntObj(Tcl_LimitGetCommands(slaveInterp)));
+	} else {
+	    Tcl_Obj *empty;
+
+	    TclNewObj(empty);
+	    Tcl_DictObjPut(NULL, dictPtr,
+		    Tcl_NewStringObj(options[2], -1), empty);
+	}
+	Tcl_SetObjResult(interp, dictPtr);
+	return TCL_OK;
+    } else if (objc == consumedObjc+1) {
+	if (Tcl_GetIndexFromObj(interp, objv[consumedObjc], options, "option",
+		0, &index) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	switch ((enum Options) index) {
+	case OPT_CMD:
+	    key.interp = slaveInterp;
+	    key.type = TCL_LIMIT_COMMANDS;
+	    hPtr = Tcl_FindHashEntry(&iPtr->limit.callbacks, (char *) &key);
+	    if (hPtr != NULL) {
+		limitCBPtr = Tcl_GetHashValue(hPtr);
+		if (limitCBPtr != NULL && limitCBPtr->scriptObj != NULL) {
+		    Tcl_SetObjResult(interp, limitCBPtr->scriptObj);
+		}
+	    }
+	    break;
+	case OPT_GRAN:
+	    Tcl_SetObjResult(interp, Tcl_NewIntObj(
+		    Tcl_LimitGetGranularity(slaveInterp, TCL_LIMIT_COMMANDS)));
+	    break;
+	case OPT_VAL:
+	    if (Tcl_LimitTypeEnabled(slaveInterp, TCL_LIMIT_COMMANDS)) {
+		Tcl_SetObjResult(interp,
+			Tcl_NewIntObj(Tcl_LimitGetCommands(slaveInterp)));
+	    }
+	    break;
+	}
+	return TCL_OK;
+    } else if ((objc-consumedObjc) & 1 /* isOdd(objc-consumedObjc) */) {
+	Tcl_WrongNumArgs(interp, consumedObjc, objv, "?-option value ...?");
+	return TCL_ERROR;
+    } else {
+	int i, scriptLen = 0, limitLen = 0;
+	Tcl_Obj *scriptObj = NULL, *granObj = NULL, *limitObj = NULL;
+	int gran = 0, limit = 0;
+
+	for (i=consumedObjc ; i<objc ; i+=2) {
+	    if (Tcl_GetIndexFromObj(interp, objv[i], options, "option", 0,
+		    &index) != TCL_OK) {
+		return TCL_ERROR;
+	    }
+	    switch ((enum Options) index) {
+	    case OPT_CMD:
+		scriptObj = objv[i+1];
+		(void) Tcl_GetStringFromObj(objv[i+1], &scriptLen);
+		break;
+	    case OPT_GRAN:
+		granObj = objv[i+1];
+		if (TclGetIntFromObj(interp, objv[i+1], &gran) != TCL_OK) {
+		    return TCL_ERROR;
+		}
+		if (gran < 1) {
+		    Tcl_SetObjResult(interp, Tcl_NewStringObj(
+			    "granularity must be at least 1", -1));
+		    Tcl_SetErrorCode(interp, "TCL", "OPERATION", "INTERP",
+			    "BADVALUE", NULL);
+		    return TCL_ERROR;
+		}
+		break;
+	    case OPT_VAL:
+		limitObj = objv[i+1];
+		(void) Tcl_GetStringFromObj(objv[i+1], &limitLen);
+		if (limitLen == 0) {
+		    break;
+		}
+		if (TclGetIntFromObj(interp, objv[i+1], &limit) != TCL_OK) {
+		    return TCL_ERROR;
+		}
+		if (limit < 0) {
+		    Tcl_SetObjResult(interp, Tcl_NewStringObj(
+			    "command limit value must be at least 0", -1));
+		    Tcl_SetErrorCode(interp, "TCL", "OPERATION", "INTERP",
+			    "BADVALUE", NULL);
+		    return TCL_ERROR;
+		}
+		break;
+	    }
+	}
+	if (scriptObj != NULL) {
+	    SetScriptLimitCallback(interp, TCL_LIMIT_COMMANDS, slaveInterp,
+		    (scriptLen > 0 ? scriptObj : NULL));
+	}
+	if (granObj != NULL) {
+	    Tcl_LimitSetGranularity(slaveInterp, TCL_LIMIT_COMMANDS, gran);
+	}
+	if (limitObj != NULL) {
+	    if (limitLen > 0) {
+		Tcl_LimitSetCommands(slaveInterp, limit);
+		Tcl_LimitTypeSet(slaveInterp, TCL_LIMIT_COMMANDS);
+	    } else {
+		Tcl_LimitTypeReset(slaveInterp, TCL_LIMIT_COMMANDS);
+	    }
+	}
+	return TCL_OK;
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * SlaveTimeLimitCmd --
+ *
+ *	Implementation of the [interp limit $i time] and [$i limit time]
+ *	subcommands. See the interp manual page for a full description.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	Depends on the arguments.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+SlaveTimeLimitCmd(
+    Tcl_Interp *interp,			/* Current interpreter. */
+    Tcl_Interp *slaveInterp,		/* Interpreter being adjusted. */
+    int consumedObjc,			/* Number of args already parsed. */
+    int objc,				/* Total number of arguments. */
+    Tcl_Obj *const objv[])		/* Argument objects. */
+{
+    static const char *const options[] = {
+	"-command", "-granularity", "-milliseconds", "-seconds", NULL
+    };
+    enum Options {
+	OPT_CMD, OPT_GRAN, OPT_MILLI, OPT_SEC
+    };
+    Interp *iPtr = (Interp *) interp;
+    int index;
+    ScriptLimitCallbackKey key;
+    ScriptLimitCallback *limitCBPtr;
+    Tcl_HashEntry *hPtr;
+
+    /*
+     * First, ensure that we are not reading or writing the calling
+     * interpreter's limits; it may only manipulate its children. Note that
+     * the low level API enforces this with Tcl_Panic, which we want to
+     * avoid. [Bug 3398794]
+     */
+
+    if (interp == slaveInterp) {
+	Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		"limits on current interpreter inaccessible", -1));
+	Tcl_SetErrorCode(interp, "TCL", "OPERATION", "INTERP", "SELF", NULL);
+	return TCL_ERROR;
+    }
+
+    if (objc == consumedObjc) {
+	Tcl_Obj *dictPtr;
+
+	TclNewObj(dictPtr);
+	key.interp = slaveInterp;
+	key.type = TCL_LIMIT_TIME;
+	hPtr = Tcl_FindHashEntry(&iPtr->limit.callbacks, (char *) &key);
+	if (hPtr != NULL) {
+	    limitCBPtr = Tcl_GetHashValue(hPtr);
+	    if (limitCBPtr != NULL && limitCBPtr->scriptObj != NULL) {
+		Tcl_DictObjPut(NULL, dictPtr, Tcl_NewStringObj(options[0], -1),
+			limitCBPtr->scriptObj);
+	    } else {
+		goto putEmptyCommandInDict;
+	    }
+	} else {
+	    Tcl_Obj *empty;
+	putEmptyCommandInDict:
+	    TclNewObj(empty);
+	    Tcl_DictObjPut(NULL, dictPtr,
+		    Tcl_NewStringObj(options[0], -1), empty);
+	}
+	Tcl_DictObjPut(NULL, dictPtr, Tcl_NewStringObj(options[1], -1),
+		Tcl_NewIntObj(Tcl_LimitGetGranularity(slaveInterp,
+		TCL_LIMIT_TIME)));
+
+	if (Tcl_LimitTypeEnabled(slaveInterp, TCL_LIMIT_TIME)) {
+	    Tcl_Time limitMoment;
+
+	    Tcl_LimitGetTime(slaveInterp, &limitMoment);
+	    Tcl_DictObjPut(NULL, dictPtr, Tcl_NewStringObj(options[2], -1),
+		    Tcl_NewLongObj(limitMoment.usec/1000));
+	    Tcl_DictObjPut(NULL, dictPtr, Tcl_NewStringObj(options[3], -1),
+		    Tcl_NewLongObj(limitMoment.sec));
+	} else {
+	    Tcl_Obj *empty;
+
+	    TclNewObj(empty);
+	    Tcl_DictObjPut(NULL, dictPtr,
+		    Tcl_NewStringObj(options[2], -1), empty);
+	    Tcl_DictObjPut(NULL, dictPtr,
+		    Tcl_NewStringObj(options[3], -1), empty);
+	}
+	Tcl_SetObjResult(interp, dictPtr);
+	return TCL_OK;
+    } else if (objc == consumedObjc+1) {
+	if (Tcl_GetIndexFromObj(interp, objv[consumedObjc], options, "option",
+		0, &index) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	switch ((enum Options) index) {
+	case OPT_CMD:
+	    key.interp = slaveInterp;
+	    key.type = TCL_LIMIT_TIME;
+	    hPtr = Tcl_FindHashEntry(&iPtr->limit.callbacks, (char *) &key);
+	    if (hPtr != NULL) {
+		limitCBPtr = Tcl_GetHashValue(hPtr);
+		if (limitCBPtr != NULL && limitCBPtr->scriptObj != NULL) {
+		    Tcl_SetObjResult(interp, limitCBPtr->scriptObj);
+		}
+	    }
+	    break;
+	case OPT_GRAN:
+	    Tcl_SetObjResult(interp, Tcl_NewIntObj(
+		    Tcl_LimitGetGranularity(slaveInterp, TCL_LIMIT_TIME)));
+	    break;
+	case OPT_MILLI:
+	    if (Tcl_LimitTypeEnabled(slaveInterp, TCL_LIMIT_TIME)) {
+		Tcl_Time limitMoment;
+
+		Tcl_LimitGetTime(slaveInterp, &limitMoment);
+		Tcl_SetObjResult(interp,
+			Tcl_NewLongObj(limitMoment.usec/1000));
+	    }
+	    break;
+	case OPT_SEC:
+	    if (Tcl_LimitTypeEnabled(slaveInterp, TCL_LIMIT_TIME)) {
+		Tcl_Time limitMoment;
+
+		Tcl_LimitGetTime(slaveInterp, &limitMoment);
+		Tcl_SetObjResult(interp, Tcl_NewLongObj(limitMoment.sec));
+	    }
+	    break;
+	}
+	return TCL_OK;
+    } else if ((objc-consumedObjc) & 1 /* isOdd(objc-consumedObjc) */) {
+	Tcl_WrongNumArgs(interp, consumedObjc, objv, "?-option value ...?");
+	return TCL_ERROR;
+    } else {
+	int i, scriptLen = 0, milliLen = 0, secLen = 0;
+	Tcl_Obj *scriptObj = NULL, *granObj = NULL;
+	Tcl_Obj *milliObj = NULL, *secObj = NULL;
+	int gran = 0;
+	Tcl_Time limitMoment;
+	int tmp;
+
+	Tcl_LimitGetTime(slaveInterp, &limitMoment);
+	for (i=consumedObjc ; i<objc ; i+=2) {
+	    if (Tcl_GetIndexFromObj(interp, objv[i], options, "option", 0,
+		    &index) != TCL_OK) {
+		return TCL_ERROR;
+	    }
+	    switch ((enum Options) index) {
+	    case OPT_CMD:
+		scriptObj = objv[i+1];
+		(void) Tcl_GetStringFromObj(objv[i+1], &scriptLen);
+		break;
+	    case OPT_GRAN:
+		granObj = objv[i+1];
+		if (TclGetIntFromObj(interp, objv[i+1], &gran) != TCL_OK) {
+		    return TCL_ERROR;
+		}
+		if (gran < 1) {
+		    Tcl_SetObjResult(interp, Tcl_NewStringObj(
+			    "granularity must be at least 1", -1));
+		    Tcl_SetErrorCode(interp, "TCL", "OPERATION", "INTERP",
+			    "BADVALUE", NULL);
+		    return TCL_ERROR;
+		}
+		break;
+	    case OPT_MILLI:
+		milliObj = objv[i+1];
+		(void) Tcl_GetStringFromObj(objv[i+1], &milliLen);
+		if (milliLen == 0) {
+		    break;
+		}
+		if (TclGetIntFromObj(interp, objv[i+1], &tmp) != TCL_OK) {
+		    return TCL_ERROR;
+		}
+		if (tmp < 0) {
+		    Tcl_SetObjResult(interp, Tcl_NewStringObj(
+			    "milliseconds must be at least 0", -1));
+		    Tcl_SetErrorCode(interp, "TCL", "OPERATION", "INTERP",
+			    "BADVALUE", NULL);
+		    return TCL_ERROR;
+		}
+		limitMoment.usec = ((long) tmp)*1000;
+		break;
+	    case OPT_SEC:
+		secObj = objv[i+1];
+		(void) Tcl_GetStringFromObj(objv[i+1], &secLen);
+		if (secLen == 0) {
+		    break;
+		}
+		if (TclGetIntFromObj(interp, objv[i+1], &tmp) != TCL_OK) {
+		    return TCL_ERROR;
+		}
+		if (tmp < 0) {
+		    Tcl_SetObjResult(interp, Tcl_NewStringObj(
+			    "seconds must be at least 0", -1));
+		    Tcl_SetErrorCode(interp, "TCL", "OPERATION", "INTERP",
+			    "BADVALUE", NULL);
+		    return TCL_ERROR;
+		}
+		limitMoment.sec = tmp;
+		break;
+	    }
+	}
+	if (milliObj != NULL || secObj != NULL) {
+	    if (milliObj != NULL) {
+		/*
+		 * Setting -milliseconds but clearing -seconds, or resetting
+		 * -milliseconds but not resetting -seconds? Bad voodoo!
+		 */
+
+		if (secObj != NULL && secLen == 0 && milliLen > 0) {
+		    Tcl_SetObjResult(interp, Tcl_NewStringObj(
+			    "may only set -milliseconds if -seconds is not "
+			    "also being reset", -1));
+		    Tcl_SetErrorCode(interp, "TCL", "OPERATION", "INTERP",
+			    "BADUSAGE", NULL);
+		    return TCL_ERROR;
+		}
+		if (milliLen == 0 && (secObj == NULL || secLen > 0)) {
+		    Tcl_SetObjResult(interp, Tcl_NewStringObj(
+			    "may only reset -milliseconds if -seconds is "
+			    "also being reset", -1));
+		    Tcl_SetErrorCode(interp, "TCL", "OPERATION", "INTERP",
+			    "BADUSAGE", NULL);
+		    return TCL_ERROR;
+		}
+	    }
+
+	    if (milliLen > 0 || secLen > 0) {
+		/*
+		 * Force usec to be in range [0..1000000), possibly
+		 * incrementing sec in the process. This makes it much easier
+		 * for people to write scripts that do small time increments.
+		 */
+
+		limitMoment.sec += limitMoment.usec / 1000000;
+		limitMoment.usec %= 1000000;
+
+		Tcl_LimitSetTime(slaveInterp, &limitMoment);
+		Tcl_LimitTypeSet(slaveInterp, TCL_LIMIT_TIME);
+	    } else {
+		Tcl_LimitTypeReset(slaveInterp, TCL_LIMIT_TIME);
+	    }
+	}
+	if (scriptObj != NULL) {
+	    SetScriptLimitCallback(interp, TCL_LIMIT_TIME, slaveInterp,
+		    (scriptLen > 0 ? scriptObj : NULL));
+	}
+	if (granObj != NULL) {
+	    Tcl_LimitSetGranularity(slaveInterp, TCL_LIMIT_TIME, gran);
+	}
+	return TCL_OK;
+    }
+}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tclLink.c b/generic/tclLink.c
new file mode 100644
index 0000000..2735256
--- /dev/null
+++ b/generic/tclLink.c
@@ -0,0 +1,636 @@
+/*
+ * tclLink.c --
+ *
+ *	This file implements linked variables (a C variable that is tied to a
+ *	Tcl variable). The idea of linked variables was first suggested by
+ *	Andreas Stolcke and this implementation is based heavily on a
+ *	prototype implementation provided by him.
+ *
+ * Copyright (c) 1993 The Regents of the University of California.
+ * Copyright (c) 1994-1997 Sun Microsystems, Inc.
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#include "tclInt.h"
+
+/*
+ * For each linked variable there is a data structure of the following type,
+ * which describes the link and is the clientData for the trace set on the Tcl
+ * variable.
+ */
+
+typedef struct Link {
+    Tcl_Interp *interp;		/* Interpreter containing Tcl variable. */
+    Tcl_Obj *varName;		/* Name of variable (must be global). This is
+				 * needed during trace callbacks, since the
+				 * actual variable may be aliased at that time
+				 * via upvar. */
+    char *addr;			/* Location of C variable. */
+    int type;			/* Type of link (TCL_LINK_INT, etc.). */
+    union {
+	char c;
+	unsigned char uc;
+	int i;
+	unsigned int ui;
+	short s;
+	unsigned short us;
+	long l;
+	unsigned long ul;
+	Tcl_WideInt w;
+	Tcl_WideUInt uw;
+	float f;
+	double d;
+    } lastValue;		/* Last known value of C variable; used to
+				 * avoid string conversions. */
+    int flags;			/* Miscellaneous one-bit values; see below for
+				 * definitions. */
+} Link;
+
+/*
+ * Definitions for flag bits:
+ * LINK_READ_ONLY -		1 means errors should be generated if Tcl
+ *				script attempts to write variable.
+ * LINK_BEING_UPDATED -		1 means that a call to Tcl_UpdateLinkedVar is
+ *				in progress for this variable, so trace
+ *				callbacks on the variable should be ignored.
+ */
+
+#define LINK_READ_ONLY		1
+#define LINK_BEING_UPDATED	2
+
+/*
+ * Forward references to functions defined later in this file:
+ */
+
+static char *		LinkTraceProc(ClientData clientData,Tcl_Interp *interp,
+			    const char *name1, const char *name2, int flags);
+static Tcl_Obj *	ObjValue(Link *linkPtr);
+
+/*
+ * Convenience macro for accessing the value of the C variable pointed to by a
+ * link. Note that this macro produces something that may be regarded as an
+ * lvalue or rvalue; it may be assigned to as well as read. Also note that
+ * this macro assumes the name of the variable being accessed (linkPtr); this
+ * is not strictly a good thing, but it keeps the code much shorter and
+ * cleaner.
+ */
+
+#define LinkedVar(type) (*(type *) linkPtr->addr)
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_LinkVar --
+ *
+ *	Link a C variable to a Tcl variable so that changes to either one
+ *	causes the other to change.
+ *
+ * Results:
+ *	The return value is TCL_OK if everything went well or TCL_ERROR if an
+ *	error occurred (the interp's result is also set after errors).
+ *
+ * Side effects:
+ *	The value at *addr is linked to the Tcl variable "varName", using
+ *	"type" to convert between string values for Tcl and binary values for
+ *	*addr.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_LinkVar(
+    Tcl_Interp *interp,		/* Interpreter in which varName exists. */
+    const char *varName,	/* Name of a global variable in interp. */
+    char *addr,			/* Address of a C variable to be linked to
+				 * varName. */
+    int type)			/* Type of C variable: TCL_LINK_INT, etc. Also
+				 * may have TCL_LINK_READ_ONLY OR'ed in. */
+{
+    Tcl_Obj *objPtr;
+    Link *linkPtr;
+    int code;
+
+    linkPtr = (Link *) Tcl_VarTraceInfo2(interp, varName, NULL,
+	    TCL_GLOBAL_ONLY, LinkTraceProc, (ClientData) NULL);
+    if (linkPtr != NULL) {
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		"variable '%s' is already linked", varName));
+	return TCL_ERROR;
+    }
+
+    linkPtr = ckalloc(sizeof(Link));
+    linkPtr->interp = interp;
+    linkPtr->varName = Tcl_NewStringObj(varName, -1);
+    Tcl_IncrRefCount(linkPtr->varName);
+    linkPtr->addr = addr;
+    linkPtr->type = type & ~TCL_LINK_READ_ONLY;
+    if (type & TCL_LINK_READ_ONLY) {
+	linkPtr->flags = LINK_READ_ONLY;
+    } else {
+	linkPtr->flags = 0;
+    }
+    objPtr = ObjValue(linkPtr);
+    if (Tcl_ObjSetVar2(interp, linkPtr->varName, NULL, objPtr,
+	    TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG) == NULL) {
+	Tcl_DecrRefCount(linkPtr->varName);
+	ckfree(linkPtr);
+	return TCL_ERROR;
+    }
+    code = Tcl_TraceVar2(interp, varName, NULL,
+	    TCL_GLOBAL_ONLY|TCL_TRACE_READS|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
+	    LinkTraceProc, linkPtr);
+    if (code != TCL_OK) {
+	Tcl_DecrRefCount(linkPtr->varName);
+	ckfree(linkPtr);
+    }
+    return code;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_UnlinkVar --
+ *
+ *	Destroy the link between a Tcl variable and a C variable.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	If "varName" was previously linked to a C variable, the link is broken
+ *	to make the variable independent. If there was no previous link for
+ *	"varName" then nothing happens.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_UnlinkVar(
+    Tcl_Interp *interp,		/* Interpreter containing variable to unlink */
+    const char *varName)	/* Global variable in interp to unlink. */
+{
+    Link *linkPtr = (Link *) Tcl_VarTraceInfo2(interp, varName, NULL,
+	    TCL_GLOBAL_ONLY, LinkTraceProc, NULL);
+
+    if (linkPtr == NULL) {
+	return;
+    }
+    Tcl_UntraceVar2(interp, varName, NULL,
+	    TCL_GLOBAL_ONLY|TCL_TRACE_READS|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
+	    LinkTraceProc, linkPtr);
+    Tcl_DecrRefCount(linkPtr->varName);
+    ckfree(linkPtr);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_UpdateLinkedVar --
+ *
+ *	This function is invoked after a linked variable has been changed by C
+ *	code. It updates the Tcl variable so that traces on the variable will
+ *	trigger.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The Tcl variable "varName" is updated from its C value, causing traces
+ *	on the variable to trigger.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_UpdateLinkedVar(
+    Tcl_Interp *interp,		/* Interpreter containing variable. */
+    const char *varName)	/* Name of global variable that is linked. */
+{
+    Link *linkPtr = (Link *) Tcl_VarTraceInfo2(interp, varName, NULL,
+	    TCL_GLOBAL_ONLY, LinkTraceProc, NULL);
+    int savedFlag;
+
+    if (linkPtr == NULL) {
+	return;
+    }
+    savedFlag = linkPtr->flags & LINK_BEING_UPDATED;
+    linkPtr->flags |= LINK_BEING_UPDATED;
+    Tcl_ObjSetVar2(interp, linkPtr->varName, NULL, ObjValue(linkPtr),
+	    TCL_GLOBAL_ONLY);
+    /*
+     * Callback may have unlinked the variable. [Bug 1740631]
+     */
+    linkPtr = (Link *) Tcl_VarTraceInfo2(interp, varName, NULL,
+	    TCL_GLOBAL_ONLY, LinkTraceProc, NULL);
+    if (linkPtr != NULL) {
+	linkPtr->flags = (linkPtr->flags & ~LINK_BEING_UPDATED) | savedFlag;
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * LinkTraceProc --
+ *
+ *	This function is invoked when a linked Tcl variable is read, written,
+ *	or unset from Tcl. It's responsible for keeping the C variable in sync
+ *	with the Tcl variable.
+ *
+ * Results:
+ *	If all goes well, NULL is returned; otherwise an error message is
+ *	returned.
+ *
+ * Side effects:
+ *	The C variable may be updated to make it consistent with the Tcl
+ *	variable, or the Tcl variable may be overwritten to reject a
+ *	modification.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static char *
+LinkTraceProc(
+    ClientData clientData,	/* Contains information about the link. */
+    Tcl_Interp *interp,		/* Interpreter containing Tcl variable. */
+    const char *name1,		/* First part of variable name. */
+    const char *name2,		/* Second part of variable name. */
+    int flags)			/* Miscellaneous additional information. */
+{
+    Link *linkPtr = clientData;
+    int changed, valueLength;
+    const char *value;
+    char **pp;
+    Tcl_Obj *valueObj;
+    int valueInt;
+    Tcl_WideInt valueWide;
+    double valueDouble;
+
+    /*
+     * If the variable is being unset, then just re-create it (with a trace)
+     * unless the whole interpreter is going away.
+     */
+
+    if (flags & TCL_TRACE_UNSETS) {
+	if (Tcl_InterpDeleted(interp)) {
+	    Tcl_DecrRefCount(linkPtr->varName);
+	    ckfree(linkPtr);
+	} else if (flags & TCL_TRACE_DESTROYED) {
+	    Tcl_ObjSetVar2(interp, linkPtr->varName, NULL, ObjValue(linkPtr),
+		    TCL_GLOBAL_ONLY);
+	    Tcl_TraceVar2(interp, Tcl_GetString(linkPtr->varName), NULL,
+		    TCL_GLOBAL_ONLY|TCL_TRACE_READS|TCL_TRACE_WRITES
+		    |TCL_TRACE_UNSETS, LinkTraceProc, linkPtr);
+	}
+	return NULL;
+    }
+
+    /*
+     * If we were invoked because of a call to Tcl_UpdateLinkedVar, then don't
+     * do anything at all. In particular, we don't want to get upset that the
+     * variable is being modified, even if it is supposed to be read-only.
+     */
+
+    if (linkPtr->flags & LINK_BEING_UPDATED) {
+	return NULL;
+    }
+
+    /*
+     * For read accesses, update the Tcl variable if the C variable has
+     * changed since the last time we updated the Tcl variable.
+     */
+
+    if (flags & TCL_TRACE_READS) {
+	switch (linkPtr->type) {
+	case TCL_LINK_INT:
+	case TCL_LINK_BOOLEAN:
+	    changed = (LinkedVar(int) != linkPtr->lastValue.i);
+	    break;
+	case TCL_LINK_DOUBLE:
+	    changed = (LinkedVar(double) != linkPtr->lastValue.d);
+	    break;
+	case TCL_LINK_WIDE_INT:
+	    changed = (LinkedVar(Tcl_WideInt) != linkPtr->lastValue.w);
+	    break;
+	case TCL_LINK_WIDE_UINT:
+	    changed = (LinkedVar(Tcl_WideUInt) != linkPtr->lastValue.uw);
+	    break;
+	case TCL_LINK_CHAR:
+	    changed = (LinkedVar(char) != linkPtr->lastValue.c);
+	    break;
+	case TCL_LINK_UCHAR:
+	    changed = (LinkedVar(unsigned char) != linkPtr->lastValue.uc);
+	    break;
+	case TCL_LINK_SHORT:
+	    changed = (LinkedVar(short) != linkPtr->lastValue.s);
+	    break;
+	case TCL_LINK_USHORT:
+	    changed = (LinkedVar(unsigned short) != linkPtr->lastValue.us);
+	    break;
+	case TCL_LINK_UINT:
+	    changed = (LinkedVar(unsigned int) != linkPtr->lastValue.ui);
+	    break;
+	case TCL_LINK_LONG:
+	    changed = (LinkedVar(long) != linkPtr->lastValue.l);
+	    break;
+	case TCL_LINK_ULONG:
+	    changed = (LinkedVar(unsigned long) != linkPtr->lastValue.ul);
+	    break;
+	case TCL_LINK_FLOAT:
+	    changed = (LinkedVar(float) != linkPtr->lastValue.f);
+	    break;
+	case TCL_LINK_STRING:
+	    changed = 1;
+	    break;
+	default:
+	    return (char *) "internal error: bad linked variable type";
+	}
+	if (changed) {
+	    Tcl_ObjSetVar2(interp, linkPtr->varName, NULL, ObjValue(linkPtr),
+		    TCL_GLOBAL_ONLY);
+	}
+	return NULL;
+    }
+
+    /*
+     * For writes, first make sure that the variable is writable. Then convert
+     * the Tcl value to C if possible. If the variable isn't writable or can't
+     * be converted, then restore the varaible's old value and return an
+     * error. Another tricky thing: we have to save and restore the interp's
+     * result, since the variable access could occur when the result has been
+     * partially set.
+     */
+
+    if (linkPtr->flags & LINK_READ_ONLY) {
+	Tcl_ObjSetVar2(interp, linkPtr->varName, NULL, ObjValue(linkPtr),
+		TCL_GLOBAL_ONLY);
+	return (char *) "linked variable is read-only";
+    }
+    valueObj = Tcl_ObjGetVar2(interp, linkPtr->varName,NULL, TCL_GLOBAL_ONLY);
+    if (valueObj == NULL) {
+	/*
+	 * This shouldn't ever happen.
+	 */
+
+	return (char *) "internal error: linked variable couldn't be read";
+    }
+
+    switch (linkPtr->type) {
+    case TCL_LINK_INT:
+	if (Tcl_GetIntFromObj(NULL, valueObj, &linkPtr->lastValue.i)
+		!= TCL_OK) {
+	    Tcl_ObjSetVar2(interp, linkPtr->varName, NULL, ObjValue(linkPtr),
+		    TCL_GLOBAL_ONLY);
+	    return (char *) "variable must have integer value";
+	}
+	LinkedVar(int) = linkPtr->lastValue.i;
+	break;
+
+    case TCL_LINK_WIDE_INT:
+	if (Tcl_GetWideIntFromObj(NULL, valueObj, &linkPtr->lastValue.w)
+		!= TCL_OK) {
+	    Tcl_ObjSetVar2(interp, linkPtr->varName, NULL, ObjValue(linkPtr),
+		    TCL_GLOBAL_ONLY);
+	    return (char *) "variable must have integer value";
+	}
+	LinkedVar(Tcl_WideInt) = linkPtr->lastValue.w;
+	break;
+
+    case TCL_LINK_DOUBLE:
+	if (Tcl_GetDoubleFromObj(NULL, valueObj, &linkPtr->lastValue.d)
+		!= TCL_OK) {
+#ifdef ACCEPT_NAN
+	    if (valueObj->typePtr != &tclDoubleType) {
+#endif
+		Tcl_ObjSetVar2(interp, linkPtr->varName, NULL,
+			ObjValue(linkPtr), TCL_GLOBAL_ONLY);
+		return (char *) "variable must have real value";
+#ifdef ACCEPT_NAN
+	    }
+	    linkPtr->lastValue.d = valueObj->internalRep.doubleValue;
+#endif
+	}
+	LinkedVar(double) = linkPtr->lastValue.d;
+	break;
+
+    case TCL_LINK_BOOLEAN:
+	if (Tcl_GetBooleanFromObj(NULL, valueObj, &linkPtr->lastValue.i)
+		!= TCL_OK) {
+	    Tcl_ObjSetVar2(interp, linkPtr->varName, NULL, ObjValue(linkPtr),
+		    TCL_GLOBAL_ONLY);
+	    return (char *) "variable must have boolean value";
+	}
+	LinkedVar(int) = linkPtr->lastValue.i;
+	break;
+
+    case TCL_LINK_CHAR:
+	if (Tcl_GetIntFromObj(interp, valueObj, &valueInt) != TCL_OK
+		|| valueInt < SCHAR_MIN || valueInt > SCHAR_MAX) {
+	    Tcl_ObjSetVar2(interp, linkPtr->varName, NULL, ObjValue(linkPtr),
+		    TCL_GLOBAL_ONLY);
+	    return (char *) "variable must have char value";
+	}
+	linkPtr->lastValue.c = (char)valueInt;
+	LinkedVar(char) = linkPtr->lastValue.c;
+	break;
+
+    case TCL_LINK_UCHAR:
+	if (Tcl_GetIntFromObj(interp, valueObj, &valueInt) != TCL_OK
+		|| valueInt < 0 || valueInt > UCHAR_MAX) {
+	    Tcl_ObjSetVar2(interp, linkPtr->varName, NULL, ObjValue(linkPtr),
+		    TCL_GLOBAL_ONLY);
+	    return (char *) "variable must have unsigned char value";
+	}
+	linkPtr->lastValue.uc = (unsigned char) valueInt;
+	LinkedVar(unsigned char) = linkPtr->lastValue.uc;
+	break;
+
+    case TCL_LINK_SHORT:
+	if (Tcl_GetIntFromObj(interp, valueObj, &valueInt) != TCL_OK
+		|| valueInt < SHRT_MIN || valueInt > SHRT_MAX) {
+	    Tcl_ObjSetVar2(interp, linkPtr->varName, NULL, ObjValue(linkPtr),
+		    TCL_GLOBAL_ONLY);
+	    return (char *) "variable must have short value";
+	}
+	linkPtr->lastValue.s = (short)valueInt;
+	LinkedVar(short) = linkPtr->lastValue.s;
+	break;
+
+    case TCL_LINK_USHORT:
+	if (Tcl_GetIntFromObj(interp, valueObj, &valueInt) != TCL_OK
+		|| valueInt < 0 || valueInt > USHRT_MAX) {
+	    Tcl_ObjSetVar2(interp, linkPtr->varName, NULL, ObjValue(linkPtr),
+		    TCL_GLOBAL_ONLY);
+	    return (char *) "variable must have unsigned short value";
+	}
+	linkPtr->lastValue.us = (unsigned short)valueInt;
+	LinkedVar(unsigned short) = linkPtr->lastValue.us;
+	break;
+
+    case TCL_LINK_UINT:
+	if (Tcl_GetWideIntFromObj(interp, valueObj, &valueWide) != TCL_OK
+		|| valueWide < 0 || valueWide > UINT_MAX) {
+	    Tcl_ObjSetVar2(interp, linkPtr->varName, NULL, ObjValue(linkPtr),
+		    TCL_GLOBAL_ONLY);
+	    return (char *) "variable must have unsigned int value";
+	}
+	linkPtr->lastValue.ui = (unsigned int)valueWide;
+	LinkedVar(unsigned int) = linkPtr->lastValue.ui;
+	break;
+
+    case TCL_LINK_LONG:
+	if (Tcl_GetWideIntFromObj(interp, valueObj, &valueWide) != TCL_OK
+		|| valueWide < LONG_MIN || valueWide > LONG_MAX) {
+	    Tcl_ObjSetVar2(interp, linkPtr->varName, NULL, ObjValue(linkPtr),
+		    TCL_GLOBAL_ONLY);
+	    return (char *) "variable must have long value";
+	}
+	linkPtr->lastValue.l = (long)valueWide;
+	LinkedVar(long) = linkPtr->lastValue.l;
+	break;
+
+    case TCL_LINK_ULONG:
+	if (Tcl_GetWideIntFromObj(interp, valueObj, &valueWide) != TCL_OK
+		|| valueWide < 0 || (Tcl_WideUInt) valueWide > ULONG_MAX) {
+	    Tcl_ObjSetVar2(interp, linkPtr->varName, NULL, ObjValue(linkPtr),
+		    TCL_GLOBAL_ONLY);
+	    return (char *) "variable must have unsigned long value";
+	}
+	linkPtr->lastValue.ul = (unsigned long)valueWide;
+	LinkedVar(unsigned long) = linkPtr->lastValue.ul;
+	break;
+
+    case TCL_LINK_WIDE_UINT:
+	/*
+	 * FIXME: represent as a bignum.
+	 */
+	if (Tcl_GetWideIntFromObj(interp, valueObj, &valueWide) != TCL_OK) {
+	    Tcl_ObjSetVar2(interp, linkPtr->varName, NULL, ObjValue(linkPtr),
+		    TCL_GLOBAL_ONLY);
+	    return (char *) "variable must have unsigned wide int value";
+	}
+	linkPtr->lastValue.uw = (Tcl_WideUInt)valueWide;
+	LinkedVar(Tcl_WideUInt) = linkPtr->lastValue.uw;
+	break;
+
+    case TCL_LINK_FLOAT:
+	if (Tcl_GetDoubleFromObj(interp, valueObj, &valueDouble) != TCL_OK
+		|| valueDouble < -FLT_MAX || valueDouble > FLT_MAX) {
+	    Tcl_ObjSetVar2(interp, linkPtr->varName, NULL, ObjValue(linkPtr),
+		    TCL_GLOBAL_ONLY);
+	    return (char *) "variable must have float value";
+	}
+	linkPtr->lastValue.f = (float)valueDouble;
+	LinkedVar(float) = linkPtr->lastValue.f;
+	break;
+
+    case TCL_LINK_STRING:
+	value = Tcl_GetStringFromObj(valueObj, &valueLength);
+	valueLength++;
+	pp = (char **) linkPtr->addr;
+
+	*pp = ckrealloc(*pp, valueLength);
+	memcpy(*pp, value, (unsigned) valueLength);
+	break;
+
+    default:
+	return (char *) "internal error: bad linked variable type";
+    }
+    return NULL;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ObjValue --
+ *
+ *	Converts the value of a C variable to a Tcl_Obj* for use in a Tcl
+ *	variable to which it is linked.
+ *
+ * Results:
+ *	The return value is a pointer to a Tcl_Obj that represents the value
+ *	of the C variable given by linkPtr.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static Tcl_Obj *
+ObjValue(
+    Link *linkPtr)		/* Structure describing linked variable. */
+{
+    char *p;
+    Tcl_Obj *resultObj;
+
+    switch (linkPtr->type) {
+    case TCL_LINK_INT:
+	linkPtr->lastValue.i = LinkedVar(int);
+	return Tcl_NewIntObj(linkPtr->lastValue.i);
+    case TCL_LINK_WIDE_INT:
+	linkPtr->lastValue.w = LinkedVar(Tcl_WideInt);
+	return Tcl_NewWideIntObj(linkPtr->lastValue.w);
+    case TCL_LINK_DOUBLE:
+	linkPtr->lastValue.d = LinkedVar(double);
+	return Tcl_NewDoubleObj(linkPtr->lastValue.d);
+    case TCL_LINK_BOOLEAN:
+	linkPtr->lastValue.i = LinkedVar(int);
+	return Tcl_NewBooleanObj(linkPtr->lastValue.i != 0);
+    case TCL_LINK_CHAR:
+	linkPtr->lastValue.c = LinkedVar(char);
+	return Tcl_NewIntObj(linkPtr->lastValue.c);
+    case TCL_LINK_UCHAR:
+	linkPtr->lastValue.uc = LinkedVar(unsigned char);
+	return Tcl_NewIntObj(linkPtr->lastValue.uc);
+    case TCL_LINK_SHORT:
+	linkPtr->lastValue.s = LinkedVar(short);
+	return Tcl_NewIntObj(linkPtr->lastValue.s);
+    case TCL_LINK_USHORT:
+	linkPtr->lastValue.us = LinkedVar(unsigned short);
+	return Tcl_NewIntObj(linkPtr->lastValue.us);
+    case TCL_LINK_UINT:
+	linkPtr->lastValue.ui = LinkedVar(unsigned int);
+	return Tcl_NewWideIntObj((Tcl_WideInt) linkPtr->lastValue.ui);
+    case TCL_LINK_LONG:
+	linkPtr->lastValue.l = LinkedVar(long);
+	return Tcl_NewWideIntObj((Tcl_WideInt) linkPtr->lastValue.l);
+    case TCL_LINK_ULONG:
+	linkPtr->lastValue.ul = LinkedVar(unsigned long);
+	return Tcl_NewWideIntObj((Tcl_WideInt) linkPtr->lastValue.ul);
+    case TCL_LINK_FLOAT:
+	linkPtr->lastValue.f = LinkedVar(float);
+	return Tcl_NewDoubleObj(linkPtr->lastValue.f);
+    case TCL_LINK_WIDE_UINT:
+	linkPtr->lastValue.uw = LinkedVar(Tcl_WideUInt);
+	/*
+	 * FIXME: represent as a bignum.
+	 */
+	return Tcl_NewWideIntObj((Tcl_WideInt) linkPtr->lastValue.uw);
+    case TCL_LINK_STRING:
+	p = LinkedVar(char *);
+	if (p == NULL) {
+	    TclNewLiteralStringObj(resultObj, "NULL");
+	    return resultObj;
+	}
+	return Tcl_NewStringObj(p, -1);
+
+    /*
+     * This code only gets executed if the link type is unknown (shouldn't
+     * ever happen).
+     */
+
+    default:
+	TclNewLiteralStringObj(resultObj, "??");
+	return resultObj;
+    }
+}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tclListObj.c b/generic/tclListObj.c
new file mode 100644
index 0000000..14b8a14
--- /dev/null
+++ b/generic/tclListObj.c
@@ -0,0 +1,2040 @@
+/*
+ * tclListObj.c --
+ *
+ *	This file contains functions that implement the Tcl list object type.
+ *
+ * Copyright (c) 1995-1997 Sun Microsystems, Inc.
+ * Copyright (c) 1998 by Scriptics Corporation.
+ * Copyright (c) 2001 by Kevin B. Kenny.  All rights reserved.
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#include "tclInt.h"
+
+/*
+ * Prototypes for functions defined later in this file:
+ */
+
+static List *		AttemptNewList(Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+static List *		NewListIntRep(int objc, Tcl_Obj *const objv[], int p);
+static void		DupListInternalRep(Tcl_Obj *srcPtr, Tcl_Obj *copyPtr);
+static void		FreeListInternalRep(Tcl_Obj *listPtr);
+static int		SetListFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr);
+static void		UpdateStringOfList(Tcl_Obj *listPtr);
+
+/*
+ * The structure below defines the list Tcl object type by means of functions
+ * that can be invoked by generic object code.
+ *
+ * The internal representation of a list object is a two-pointer
+ * representation. The first pointer designates a List structure that contains
+ * an array of pointers to the element objects, together with integers that
+ * represent the current element count and the allocated size of the array.
+ * The second pointer is normally NULL; during execution of functions in this
+ * file that operate on nested sublists, it is occasionally used as working
+ * storage to avoid an auxiliary stack.
+ */
+
+const Tcl_ObjType tclListType = {
+    "list",			/* name */
+    FreeListInternalRep,	/* freeIntRepProc */
+    DupListInternalRep,		/* dupIntRepProc */
+    UpdateStringOfList,		/* updateStringProc */
+    SetListFromAny		/* setFromAnyProc */
+};
+
+#ifndef TCL_MIN_ELEMENT_GROWTH
+#define TCL_MIN_ELEMENT_GROWTH TCL_MIN_GROWTH/sizeof(Tcl_Obj *)
+#endif
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * NewListIntRep --
+ *
+ *	Creates a list internal rep with space for objc elements.  objc
+ *	must be > 0.  If objv!=NULL, initializes with the first objc values
+ *	in that array.  If objv==NULL, initalize list internal rep to have
+ *	0 elements, with space to add objc more.  Flag value "p" indicates
+ *	how to behave on failure.
+ *
+ * Results:
+ *	A new List struct with refCount 0 is returned. If some failure
+ *	prevents this then if p=0, NULL is returned and otherwise the
+ *	routine panics.
+ *
+ * Side effects:
+ *	The ref counts of the elements in objv are incremented since the
+ *	resulting list now refers to them.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static List *
+NewListIntRep(
+    int objc,
+    Tcl_Obj *const objv[],
+    int p)
+{
+    List *listRepPtr;
+
+    if (objc <= 0) {
+	Tcl_Panic("NewListIntRep: expects postive element count");
+    }
+
+    /*
+     * First check to see if we'd overflow and try to allocate an object
+     * larger than our memory allocator allows. Note that this is actually a
+     * fairly small value when you're on a serious 64-bit machine, but that
+     * requires API changes to fix. See [Bug 219196] for a discussion.
+     */
+
+    if ((size_t)objc > LIST_MAX) {
+	if (p) {
+	    Tcl_Panic("max length of a Tcl list (%d elements) exceeded",
+		    LIST_MAX);
+	}
+	return NULL;
+    }
+
+    listRepPtr = attemptckalloc(LIST_SIZE(objc));
+    if (listRepPtr == NULL) {
+	if (p) {
+	    Tcl_Panic("list creation failed: unable to alloc %u bytes",
+		    LIST_SIZE(objc));
+	}
+	return NULL;
+    }
+
+    listRepPtr->canonicalFlag = 0;
+    listRepPtr->refCount = 0;
+    listRepPtr->maxElemCount = objc;
+
+    if (objv) {
+	Tcl_Obj **elemPtrs;
+	int i;
+
+	listRepPtr->elemCount = objc;
+	elemPtrs = &listRepPtr->elements;
+	for (i = 0;  i < objc;  i++) {
+	    elemPtrs[i] = objv[i];
+	    Tcl_IncrRefCount(elemPtrs[i]);
+	}
+    } else {
+	listRepPtr->elemCount = 0;
+    }
+    return listRepPtr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * AttemptNewList --
+ *
+ *	Creates a list internal rep with space for objc elements.  objc
+ *	must be > 0.  If objv!=NULL, initializes with the first objc values
+ *	in that array.  If objv==NULL, initalize list internal rep to have
+ *	0 elements, with space to add objc more.
+ *
+ * Results:
+ *	A new List struct with refCount 0 is returned. If some failure
+ *	prevents this then NULL is returned, and an error message is left
+ *	in the interp result, unless interp is NULL.
+ *
+ * Side effects:
+ *	The ref counts of the elements in objv are incremented since the
+ *	resulting list now refers to them.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static List *
+AttemptNewList(
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const objv[])
+{
+    List *listRepPtr = NewListIntRep(objc, objv, 0);
+
+    if (interp != NULL && listRepPtr == NULL) {
+	if (objc > LIST_MAX) {
+	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		    "max length of a Tcl list (%d elements) exceeded",
+		    LIST_MAX));
+	} else {
+	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		    "list creation failed: unable to alloc %u bytes",
+		    LIST_SIZE(objc)));
+	}
+	Tcl_SetErrorCode(interp, "TCL", "MEMORY", NULL);
+    }
+    return listRepPtr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_NewListObj --
+ *
+ *	This function is normally called when not debugging: i.e., when
+ *	TCL_MEM_DEBUG is not defined. It creates a new list object from an
+ *	(objc,objv) array: that is, each of the objc elements of the array
+ *	referenced by objv is inserted as an element into a new Tcl object.
+ *
+ *	When TCL_MEM_DEBUG is defined, this function just returns the result
+ *	of calling the debugging version Tcl_DbNewListObj.
+ *
+ * Results:
+ *	A new list object is returned that is initialized from the object
+ *	pointers in objv. If objc is less than or equal to zero, an empty
+ *	object is returned. The new object's string representation is left
+ *	NULL. The resulting new list object has ref count 0.
+ *
+ * Side effects:
+ *	The ref counts of the elements in objv are incremented since the
+ *	resulting list now refers to them.
+ *
+ *----------------------------------------------------------------------
+ */
+
+#ifdef TCL_MEM_DEBUG
+#undef Tcl_NewListObj
+
+Tcl_Obj *
+Tcl_NewListObj(
+    int objc,			/* Count of objects referenced by objv. */
+    Tcl_Obj *const objv[])	/* An array of pointers to Tcl objects. */
+{
+    return Tcl_DbNewListObj(objc, objv, "unknown", 0);
+}
+
+#else /* if not TCL_MEM_DEBUG */
+
+Tcl_Obj *
+Tcl_NewListObj(
+    int objc,			/* Count of objects referenced by objv. */
+    Tcl_Obj *const objv[])	/* An array of pointers to Tcl objects. */
+{
+    List *listRepPtr;
+    Tcl_Obj *listPtr;
+
+    TclNewObj(listPtr);
+
+    if (objc <= 0) {
+	return listPtr;
+    }
+
+    /*
+     * Create the internal rep.
+     */
+
+    listRepPtr = NewListIntRep(objc, objv, 1);
+
+    /*
+     * Now create the object.
+     */
+
+    TclInvalidateStringRep(listPtr);
+    ListSetIntRep(listPtr, listRepPtr);
+    return listPtr;
+}
+#endif /* if TCL_MEM_DEBUG */
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_DbNewListObj --
+ *
+ *	This function is normally called when debugging: i.e., when
+ *	TCL_MEM_DEBUG is defined. It creates new list objects. It is the same
+ *	as the Tcl_NewListObj function above except that it calls
+ *	Tcl_DbCkalloc directly with the file name and line number from its
+ *	caller. This simplifies debugging since then the [memory active]
+ *	command will report the correct file name and line number when
+ *	reporting objects that haven't been freed.
+ *
+ *	When TCL_MEM_DEBUG is not defined, this function just returns the
+ *	result of calling Tcl_NewListObj.
+ *
+ * Results:
+ *	A new list object is returned that is initialized from the object
+ *	pointers in objv. If objc is less than or equal to zero, an empty
+ *	object is returned. The new object's string representation is left
+ *	NULL. The new list object has ref count 0.
+ *
+ * Side effects:
+ *	The ref counts of the elements in objv are incremented since the
+ *	resulting list now refers to them.
+ *
+ *----------------------------------------------------------------------
+ */
+
+#ifdef TCL_MEM_DEBUG
+
+Tcl_Obj *
+Tcl_DbNewListObj(
+    int objc,			/* Count of objects referenced by objv. */
+    Tcl_Obj *const objv[],	/* An array of pointers to Tcl objects. */
+    const char *file,		/* The name of the source file calling this
+				 * function; used for debugging. */
+    int line)			/* Line number in the source file; used for
+				 * debugging. */
+{
+    Tcl_Obj *listPtr;
+    List *listRepPtr;
+
+    TclDbNewObj(listPtr, file, line);
+
+    if (objc <= 0) {
+	return listPtr;
+    }
+
+    /*
+     * Create the internal rep.
+     */
+
+    listRepPtr = NewListIntRep(objc, objv, 1);
+
+    /*
+     * Now create the object.
+     */
+
+    TclInvalidateStringRep(listPtr);
+    ListSetIntRep(listPtr, listRepPtr);
+
+    return listPtr;
+}
+
+#else /* if not TCL_MEM_DEBUG */
+
+Tcl_Obj *
+Tcl_DbNewListObj(
+    int objc,			/* Count of objects referenced by objv. */
+    Tcl_Obj *const objv[],	/* An array of pointers to Tcl objects. */
+    const char *file,		/* The name of the source file calling this
+				 * function; used for debugging. */
+    int line)			/* Line number in the source file; used for
+				 * debugging. */
+{
+    return Tcl_NewListObj(objc, objv);
+}
+#endif /* TCL_MEM_DEBUG */
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_SetListObj --
+ *
+ *	Modify an object to be a list containing each of the objc elements of
+ *	the object array referenced by objv.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The object is made a list object and is initialized from the object
+ *	pointers in objv. If objc is less than or equal to zero, an empty
+ *	object is returned. The new object's string representation is left
+ *	NULL. The ref counts of the elements in objv are incremented since the
+ *	list now refers to them. The object's old string and internal
+ *	representations are freed and its type is set NULL.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_SetListObj(
+    Tcl_Obj *objPtr,		/* Object whose internal rep to init. */
+    int objc,			/* Count of objects referenced by objv. */
+    Tcl_Obj *const objv[])	/* An array of pointers to Tcl objects. */
+{
+    List *listRepPtr;
+
+    if (Tcl_IsShared(objPtr)) {
+	Tcl_Panic("%s called with shared object", "Tcl_SetListObj");
+    }
+
+    /*
+     * Free any old string rep and any internal rep for the old type.
+     */
+
+    TclFreeIntRep(objPtr);
+    TclInvalidateStringRep(objPtr);
+
+    /*
+     * Set the object's type to "list" and initialize the internal rep.
+     * However, if there are no elements to put in the list, just give the
+     * object an empty string rep and a NULL type.
+     */
+
+    if (objc > 0) {
+	listRepPtr = NewListIntRep(objc, objv, 1);
+	ListSetIntRep(objPtr, listRepPtr);
+    } else {
+	objPtr->bytes = tclEmptyStringRep;
+	objPtr->length = 0;
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclListObjCopy --
+ *
+ *	Makes a "pure list" copy of a list value. This provides for the C
+ *	level a counterpart of the [lrange $list 0 end] command, while using
+ *	internals details to be as efficient as possible.
+ *
+ * Results:
+ *	Normally returns a pointer to a new Tcl_Obj, that contains the same
+ *	list value as *listPtr does. The returned Tcl_Obj has a refCount of
+ *	zero. If *listPtr does not hold a list, NULL is returned, and if
+ *	interp is non-NULL, an error message is recorded there.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_Obj *
+TclListObjCopy(
+    Tcl_Interp *interp,		/* Used to report errors if not NULL. */
+    Tcl_Obj *listPtr)		/* List object for which an element array is
+				 * to be returned. */
+{
+    Tcl_Obj *copyPtr;
+
+    if (listPtr->typePtr != &tclListType) {
+	if (SetListFromAny(interp, listPtr) != TCL_OK) {
+	    return NULL;
+	}
+    }
+
+    TclNewObj(copyPtr);
+    TclInvalidateStringRep(copyPtr);
+    DupListInternalRep(listPtr, copyPtr);
+    return copyPtr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_ListObjGetElements --
+ *
+ *	This function returns an (objc,objv) array of the elements in a list
+ *	object.
+ *
+ * Results:
+ *	The return value is normally TCL_OK; in this case *objcPtr is set to
+ *	the count of list elements and *objvPtr is set to a pointer to an
+ *	array of (*objcPtr) pointers to each list element. If listPtr does not
+ *	refer to a list object and the object can not be converted to one,
+ *	TCL_ERROR is returned and an error message will be left in the
+ *	interpreter's result if interp is not NULL.
+ *
+ *	The objects referenced by the returned array should be treated as
+ *	readonly and their ref counts are _not_ incremented; the caller must
+ *	do that if it holds on to a reference. Furthermore, the pointer and
+ *	length returned by this function may change as soon as any function is
+ *	called on the list object; be careful about retaining the pointer in a
+ *	local data structure.
+ *
+ * Side effects:
+ *	The possible conversion of the object referenced by listPtr
+ *	to a list object.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_ListObjGetElements(
+    Tcl_Interp *interp,		/* Used to report errors if not NULL. */
+    register Tcl_Obj *listPtr,	/* List object for which an element array is
+				 * to be returned. */
+    int *objcPtr,		/* Where to store the count of objects
+				 * referenced by objv. */
+    Tcl_Obj ***objvPtr)		/* Where to store the pointer to an array of
+				 * pointers to the list's objects. */
+{
+    register List *listRepPtr;
+
+    if (listPtr->typePtr != &tclListType) {
+	int result;
+
+	if (listPtr->bytes == tclEmptyStringRep) {
+	    *objcPtr = 0;
+	    *objvPtr = NULL;
+	    return TCL_OK;
+	}
+	result = SetListFromAny(interp, listPtr);
+	if (result != TCL_OK) {
+	    return result;
+	}
+    }
+    listRepPtr = ListRepPtr(listPtr);
+    *objcPtr = listRepPtr->elemCount;
+    *objvPtr = &listRepPtr->elements;
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_ListObjAppendList --
+ *
+ *	This function appends the elements in the list value referenced by
+ *	elemListPtr to the list value referenced by listPtr.
+ *
+ * Results:
+ *	The return value is normally TCL_OK. If listPtr or elemListPtr do not
+ *	refer to list values, TCL_ERROR is returned and an error message is
+ *	left in the interpreter's result if interp is not NULL.
+ *
+ * Side effects:
+ *	The reference counts of the elements in elemListPtr are incremented
+ *	since the list now refers to them. listPtr and elemListPtr are
+ *	converted, if necessary, to list objects. Also, appending the new
+ *	elements may cause listObj's array of element pointers to grow.
+ *	listPtr's old string representation, if any, is invalidated.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_ListObjAppendList(
+    Tcl_Interp *interp,		/* Used to report errors if not NULL. */
+    register Tcl_Obj *listPtr,	/* List object to append elements to. */
+    Tcl_Obj *elemListPtr)	/* List obj with elements to append. */
+{
+    int objc;
+    Tcl_Obj **objv;
+
+    if (Tcl_IsShared(listPtr)) {
+	Tcl_Panic("%s called with shared object", "Tcl_ListObjAppendList");
+    }
+
+    /*
+     * Pull the elements to append from elemListPtr.
+     */
+
+    if (TCL_OK != TclListObjGetElements(interp, elemListPtr, &objc, &objv)) {
+	return TCL_ERROR;
+    }
+
+    /*
+     * Insert the new elements starting after the lists's last element.
+     * Delete zero existing elements.
+     */
+
+    return Tcl_ListObjReplace(interp, listPtr, LIST_MAX, 0, objc, objv);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_ListObjAppendElement --
+ *
+ *	This function is a special purpose version of Tcl_ListObjAppendList:
+ *	it appends a single object referenced by objPtr to the list object
+ *	referenced by listPtr. If listPtr is not already a list object, an
+ *	attempt will be made to convert it to one.
+ *
+ * Results:
+ *	The return value is normally TCL_OK; in this case objPtr is added to
+ *	the end of listPtr's list. If listPtr does not refer to a list object
+ *	and the object can not be converted to one, TCL_ERROR is returned and
+ *	an error message will be left in the interpreter's result if interp is
+ *	not NULL.
+ *
+ * Side effects:
+ *	The ref count of objPtr is incremented since the list now refers to
+ *	it. listPtr will be converted, if necessary, to a list object. Also,
+ *	appending the new element may cause listObj's array of element
+ *	pointers to grow. listPtr's old string representation, if any, is
+ *	invalidated.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_ListObjAppendElement(
+    Tcl_Interp *interp,		/* Used to report errors if not NULL. */
+    Tcl_Obj *listPtr,		/* List object to append objPtr to. */
+    Tcl_Obj *objPtr)		/* Object to append to listPtr's list. */
+{
+    register List *listRepPtr, *newPtr = NULL;
+    int numElems, numRequired, needGrow, isShared, attempt;
+
+    if (Tcl_IsShared(listPtr)) {
+	Tcl_Panic("%s called with shared object", "Tcl_ListObjAppendElement");
+    }
+    if (listPtr->typePtr != &tclListType) {
+	int result;
+
+	if (listPtr->bytes == tclEmptyStringRep) {
+	    Tcl_SetListObj(listPtr, 1, &objPtr);
+	    return TCL_OK;
+	}
+	result = SetListFromAny(interp, listPtr);
+	if (result != TCL_OK) {
+	    return result;
+	}
+    }
+
+    listRepPtr = ListRepPtr(listPtr);
+    numElems = listRepPtr->elemCount;
+    numRequired = numElems + 1 ;
+    needGrow = (numRequired > listRepPtr->maxElemCount);
+    isShared = (listRepPtr->refCount > 1);
+
+    if (numRequired > LIST_MAX) {
+	if (interp != NULL) {
+	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		    "max length of a Tcl list (%d elements) exceeded",
+		    LIST_MAX));
+	    Tcl_SetErrorCode(interp, "TCL", "MEMORY", NULL);
+	}
+	return TCL_ERROR;
+    }
+
+    if (needGrow && !isShared) {
+	/*
+	 * Need to grow + unshared intrep => try to realloc
+	 */
+
+	attempt = 2 * numRequired;
+	if (attempt <= LIST_MAX) {
+	    newPtr = attemptckrealloc(listRepPtr, LIST_SIZE(attempt));
+	}
+	if (newPtr == NULL) {
+	    attempt = numRequired + 1 + TCL_MIN_ELEMENT_GROWTH;
+	    if (attempt > LIST_MAX) {
+		attempt = LIST_MAX;
+	    }
+	    newPtr = attemptckrealloc(listRepPtr, LIST_SIZE(attempt));
+	}
+	if (newPtr == NULL) {
+	    attempt = numRequired;
+	    newPtr = attemptckrealloc(listRepPtr, LIST_SIZE(attempt));
+	}
+	if (newPtr) {
+	    listRepPtr = newPtr;
+	    listRepPtr->maxElemCount = attempt;
+	    needGrow = 0;
+	}
+    }
+    if (isShared || needGrow) {
+	Tcl_Obj **dst, **src = &listRepPtr->elements;
+
+	/*
+	 * Either we have a shared intrep and we must copy to write, or we
+	 * need to grow and realloc attempts failed.  Attempt intrep copy.
+	 */
+
+	attempt = 2 * numRequired;
+	newPtr = AttemptNewList(NULL, attempt, NULL);
+	if (newPtr == NULL) {
+	    attempt = numRequired + 1 + TCL_MIN_ELEMENT_GROWTH;
+	    if (attempt > LIST_MAX) {
+		attempt = LIST_MAX;
+	    }
+	    newPtr = AttemptNewList(NULL, attempt, NULL);
+	}
+	if (newPtr == NULL) {
+	    attempt = numRequired;
+	    newPtr = AttemptNewList(interp, attempt, NULL);
+	}
+	if (newPtr == NULL) {
+	    /*
+	     * All growth attempts failed; throw the error.
+	     */
+
+	    return TCL_ERROR;
+	}
+
+	dst = &newPtr->elements;
+	newPtr->refCount++;
+	newPtr->canonicalFlag = listRepPtr->canonicalFlag;
+	newPtr->elemCount = listRepPtr->elemCount;
+
+	if (isShared) {
+	    /*
+	     * The original intrep must remain undisturbed.  Copy into the new
+	     * one and bump refcounts
+	     */
+	    while (numElems--) {
+		*dst = *src++;
+		Tcl_IncrRefCount(*dst++);
+	    }
+	    listRepPtr->refCount--;
+	} else {
+	    /*
+	     * Old intrep to be freed, re-use refCounts.
+	     */
+
+	    memcpy(dst, src, (size_t) numElems * sizeof(Tcl_Obj *));
+	    ckfree(listRepPtr);
+	}
+	listRepPtr = newPtr;
+    }
+    listPtr->internalRep.twoPtrValue.ptr1 = listRepPtr;
+
+    /*
+     * Add objPtr to the end of listPtr's array of element pointers. Increment
+     * the ref count for the (now shared) objPtr.
+     */
+
+    *(&listRepPtr->elements + listRepPtr->elemCount) = objPtr;
+    Tcl_IncrRefCount(objPtr);
+    listRepPtr->elemCount++;
+
+    /*
+     * Invalidate any old string representation since the list's internal
+     * representation has changed.
+     */
+
+    TclInvalidateStringRep(listPtr);
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_ListObjIndex --
+ *
+ *	This function returns a pointer to the index'th object from the list
+ *	referenced by listPtr. The first element has index 0. If index is
+ *	negative or greater than or equal to the number of elements in the
+ *	list, a NULL is returned. If listPtr is not a list object, an attempt
+ *	will be made to convert it to a list.
+ *
+ * Results:
+ *	The return value is normally TCL_OK; in this case objPtrPtr is set to
+ *	the Tcl_Obj pointer for the index'th list element or NULL if index is
+ *	out of range. This object should be treated as readonly and its ref
+ *	count is _not_ incremented; the caller must do that if it holds on to
+ *	the reference. If listPtr does not refer to a list and can't be
+ *	converted to one, TCL_ERROR is returned and an error message is left
+ *	in the interpreter's result if interp is not NULL.
+ *
+ * Side effects:
+ *	listPtr will be converted, if necessary, to a list object.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_ListObjIndex(
+    Tcl_Interp *interp,		/* Used to report errors if not NULL. */
+    register Tcl_Obj *listPtr,	/* List object to index into. */
+    register int index,		/* Index of element to return. */
+    Tcl_Obj **objPtrPtr)	/* The resulting Tcl_Obj* is stored here. */
+{
+    register List *listRepPtr;
+
+    if (listPtr->typePtr != &tclListType) {
+	int result;
+
+	if (listPtr->bytes == tclEmptyStringRep) {
+	    *objPtrPtr = NULL;
+	    return TCL_OK;
+	}
+	result = SetListFromAny(interp, listPtr);
+	if (result != TCL_OK) {
+	    return result;
+	}
+    }
+
+    listRepPtr = ListRepPtr(listPtr);
+    if ((index < 0) || (index >= listRepPtr->elemCount)) {
+	*objPtrPtr = NULL;
+    } else {
+	*objPtrPtr = (&listRepPtr->elements)[index];
+    }
+
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_ListObjLength --
+ *
+ *	This function returns the number of elements in a list object. If the
+ *	object is not already a list object, an attempt will be made to
+ *	convert it to one.
+ *
+ * Results:
+ *	The return value is normally TCL_OK; in this case *intPtr will be set
+ *	to the integer count of list elements. If listPtr does not refer to a
+ *	list object and the object can not be converted to one, TCL_ERROR is
+ *	returned and an error message will be left in the interpreter's result
+ *	if interp is not NULL.
+ *
+ * Side effects:
+ *	The possible conversion of the argument object to a list object.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_ListObjLength(
+    Tcl_Interp *interp,		/* Used to report errors if not NULL. */
+    register Tcl_Obj *listPtr,	/* List object whose #elements to return. */
+    register int *intPtr)	/* The resulting int is stored here. */
+{
+    register List *listRepPtr;
+
+    if (listPtr->typePtr != &tclListType) {
+	int result;
+
+	if (listPtr->bytes == tclEmptyStringRep) {
+	    *intPtr = 0;
+	    return TCL_OK;
+	}
+	result = SetListFromAny(interp, listPtr);
+	if (result != TCL_OK) {
+	    return result;
+	}
+    }
+
+    listRepPtr = ListRepPtr(listPtr);
+    *intPtr = listRepPtr->elemCount;
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_ListObjReplace --
+ *
+ *	This function replaces zero or more elements of the list referenced by
+ *	listPtr with the objects from an (objc,objv) array. The objc elements
+ *	of the array referenced by objv replace the count elements in listPtr
+ *	starting at first.
+ *
+ *	If the argument first is zero or negative, it refers to the first
+ *	element. If first is greater than or equal to the number of elements
+ *	in the list, then no elements are deleted; the new elements are
+ *	appended to the list. Count gives the number of elements to replace.
+ *	If count is zero or negative then no elements are deleted; the new
+ *	elements are simply inserted before first.
+ *
+ *	The argument objv refers to an array of objc pointers to the new
+ *	elements to be added to listPtr in place of those that were deleted.
+ *	If objv is NULL, no new elements are added. If listPtr is not a list
+ *	object, an attempt will be made to convert it to one.
+ *
+ * Results:
+ *	The return value is normally TCL_OK. If listPtr does not refer to a
+ *	list object and can not be converted to one, TCL_ERROR is returned and
+ *	an error message will be left in the interpreter's result if interp is
+ *	not NULL.
+ *
+ * Side effects:
+ *	The ref counts of the objc elements in objv are incremented since the
+ *	resulting list now refers to them. Similarly, the ref counts for
+ *	replaced objects are decremented. listPtr is converted, if necessary,
+ *	to a list object. listPtr's old string representation, if any, is
+ *	freed.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_ListObjReplace(
+    Tcl_Interp *interp,		/* Used for error reporting if not NULL. */
+    Tcl_Obj *listPtr,		/* List object whose elements to replace. */
+    int first,			/* Index of first element to replace. */
+    int count,			/* Number of elements to replace. */
+    int objc,			/* Number of objects to insert. */
+    Tcl_Obj *const objv[])	/* An array of objc pointers to Tcl objects to
+				 * insert. */
+{
+    List *listRepPtr;
+    register Tcl_Obj **elemPtrs;
+    int needGrow, numElems, numRequired, numAfterLast, start, i, j, isShared;
+
+    if (Tcl_IsShared(listPtr)) {
+	Tcl_Panic("%s called with shared object", "Tcl_ListObjReplace");
+    }
+    if (listPtr->typePtr != &tclListType) {
+	if (listPtr->bytes == tclEmptyStringRep) {
+	    if (!objc) {
+		return TCL_OK;
+	    }
+	    Tcl_SetListObj(listPtr, objc, NULL);
+	} else {
+	    int result = SetListFromAny(interp, listPtr);
+
+	    if (result != TCL_OK) {
+		return result;
+	    }
+	}
+    }
+
+    /*
+     * Note that when count == 0 and objc == 0, this routine is logically a
+     * no-op, removing and adding no elements to the list. However, by flowing
+     * through this routine anyway, we get the important side effect that the
+     * resulting listPtr is a list in canoncial form. This is important.
+     * Resist any temptation to optimize this case.
+     */
+
+    listRepPtr = ListRepPtr(listPtr);
+    elemPtrs = &listRepPtr->elements;
+    numElems = listRepPtr->elemCount;
+
+    if (first < 0) {
+	first = 0;
+    }
+    if (first >= numElems) {
+	first = numElems;	/* So we'll insert after last element. */
+    }
+    if (count < 0) {
+	count = 0;
+    } else if (numElems < first+count || first+count < 0) {
+	/*
+	 * The 'first+count < 0' condition here guards agains integer
+	 * overflow in determining 'first+count'.
+	 */
+
+	count = numElems - first;
+    }
+
+    if (objc > LIST_MAX - (numElems - count)) {
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		"max length of a Tcl list (%d elements) exceeded", LIST_MAX));
+	return TCL_ERROR;
+    }
+    isShared = (listRepPtr->refCount > 1);
+    numRequired = numElems - count + objc; /* Known <= LIST_MAX */
+    needGrow = numRequired > listRepPtr->maxElemCount;
+
+    for (i = 0;  i < objc;  i++) {
+	Tcl_IncrRefCount(objv[i]);
+    }
+
+    if (needGrow && !isShared) {
+	/* Try to use realloc */
+	List *newPtr = NULL;
+	int attempt = 2 * numRequired;
+	if (attempt <= LIST_MAX) {
+	    newPtr = attemptckrealloc(listRepPtr, LIST_SIZE(attempt));
+	}
+	if (newPtr == NULL) {
+	    attempt = numRequired + 1 + TCL_MIN_ELEMENT_GROWTH;
+	    if (attempt > LIST_MAX) {
+		attempt = LIST_MAX;
+	    }
+	    newPtr = attemptckrealloc(listRepPtr, LIST_SIZE(attempt));
+	}
+	if (newPtr == NULL) {
+	    attempt = numRequired;
+	    newPtr = attemptckrealloc(listRepPtr, LIST_SIZE(attempt));
+	}
+	if (newPtr) {
+	    listRepPtr = newPtr;
+	    listPtr->internalRep.twoPtrValue.ptr1 = listRepPtr;
+	    elemPtrs = &listRepPtr->elements;
+	    listRepPtr->maxElemCount = attempt;
+	    needGrow = numRequired > listRepPtr->maxElemCount;
+	}
+    }
+    if (!needGrow && !isShared) {
+	int shift;
+
+	/*
+	 * Can use the current List struct. First "delete" count elements
+	 * starting at first.
+	 */
+
+	for (j = first;  j < first + count;  j++) {
+	    Tcl_Obj *victimPtr = elemPtrs[j];
+
+	    TclDecrRefCount(victimPtr);
+	}
+
+	/*
+	 * Shift the elements after the last one removed to their new
+	 * locations.
+	 */
+
+	start = first + count;
+	numAfterLast = numElems - start;
+	shift = objc - count;	/* numNewElems - numDeleted */
+	if ((numAfterLast > 0) && (shift != 0)) {
+	    Tcl_Obj **src = elemPtrs + start;
+
+	    memmove(src+shift, src, (size_t) numAfterLast * sizeof(Tcl_Obj*));
+	}
+    } else {
+	/*
+	 * Cannot use the current List struct; it is shared, too small, or
+	 * both. Allocate a new struct and insert elements into it.
+	 */
+
+	List *oldListRepPtr = listRepPtr;
+	Tcl_Obj **oldPtrs = elemPtrs;
+	int newMax;
+
+	if (needGrow){
+	    newMax = 2 * numRequired;
+	} else {
+	    newMax = listRepPtr->maxElemCount;
+	}
+
+	listRepPtr = AttemptNewList(NULL, newMax, NULL);
+	if (listRepPtr == NULL) {
+	    unsigned int limit = LIST_MAX - numRequired;
+	    unsigned int extra = numRequired - numElems
+		    + TCL_MIN_ELEMENT_GROWTH;
+	    int growth = (int) ((extra > limit) ? limit : extra);
+
+	    listRepPtr = AttemptNewList(NULL, numRequired + growth, NULL);
+	    if (listRepPtr == NULL) {
+		listRepPtr = AttemptNewList(interp, numRequired, NULL);
+		if (listRepPtr == NULL) {
+		    for (i = 0;  i < objc;  i++) {
+			/* See bug 3598580 */
+#if TCL_MAJOR_VERSION > 8
+			Tcl_DecrRefCount(objv[i]);
+#else
+			objv[i]->refCount--;
+#endif
+		    }
+		    return TCL_ERROR;
+		}
+	    }
+	}
+
+	listPtr->internalRep.twoPtrValue.ptr1 = listRepPtr;
+	listRepPtr->refCount++;
+
+	elemPtrs = &listRepPtr->elements;
+
+	if (isShared) {
+	    /*
+	     * The old struct will remain in place; need new refCounts for the
+	     * new List struct references. Copy over only the surviving
+	     * elements.
+	     */
+
+	    for (i=0; i < first; i++) {
+		elemPtrs[i] = oldPtrs[i];
+		Tcl_IncrRefCount(elemPtrs[i]);
+	    }
+	    for (i = first + count, j = first + objc;
+		    j < numRequired; i++, j++) {
+		elemPtrs[j] = oldPtrs[i];
+		Tcl_IncrRefCount(elemPtrs[j]);
+	    }
+
+	    oldListRepPtr->refCount--;
+	} else {
+	    /*
+	     * The old struct will be removed; use its inherited refCounts.
+	     */
+
+	    if (first > 0) {
+		memcpy(elemPtrs, oldPtrs, (size_t) first * sizeof(Tcl_Obj *));
+	    }
+
+	    /*
+	     * "Delete" count elements starting at first.
+	     */
+
+	    for (j = first;  j < first + count;  j++) {
+		Tcl_Obj *victimPtr = oldPtrs[j];
+
+		TclDecrRefCount(victimPtr);
+	    }
+
+	    /*
+	     * Copy the elements after the last one removed, shifted to their
+	     * new locations.
+	     */
+
+	    start = first + count;
+	    numAfterLast = numElems - start;
+	    if (numAfterLast > 0) {
+		memcpy(elemPtrs + first + objc, oldPtrs + start,
+			(size_t) numAfterLast * sizeof(Tcl_Obj *));
+	    }
+
+	    ckfree(oldListRepPtr);
+	}
+    }
+
+    /*
+     * Insert the new elements into elemPtrs before "first".
+     */
+
+    for (i=0,j=first ; i<objc ; i++,j++) {
+	elemPtrs[j] = objv[i];
+    }
+
+    /*
+     * Update the count of elements.
+     */
+
+    listRepPtr->elemCount = numRequired;
+
+    /*
+     * Invalidate and free any old string representation since it no longer
+     * reflects the list's internal representation.
+     */
+
+    TclInvalidateStringRep(listPtr);
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclLindexList --
+ *
+ *	This procedure handles the 'lindex' command when objc==3.
+ *
+ * Results:
+ *	Returns a pointer to the object extracted, or NULL if an error
+ *	occurred. The returned object already includes one reference count for
+ *	the pointer returned.
+ *
+ * Side effects:
+ *	None.
+ *
+ * Notes:
+ *	This procedure is implemented entirely as a wrapper around
+ *	TclLindexFlat. All it does is reconfigure the argument format into the
+ *	form required by TclLindexFlat, while taking care to manage shimmering
+ *	in such a way that we tend to keep the most useful intreps and/or
+ *	avoid the most expensive conversions.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_Obj *
+TclLindexList(
+    Tcl_Interp *interp,		/* Tcl interpreter. */
+    Tcl_Obj *listPtr,		/* List being unpacked. */
+    Tcl_Obj *argPtr)		/* Index or index list. */
+{
+
+    int index;			/* Index into the list. */
+    Tcl_Obj *indexListCopy;
+
+    /*
+     * Determine whether argPtr designates a list or a single index. We have
+     * to be careful about the order of the checks to avoid repeated
+     * shimmering; see TIP#22 and TIP#33 for the details.
+     */
+
+    if (argPtr->typePtr != &tclListType
+	    && TclGetIntForIndexM(NULL , argPtr, 0, &index) == TCL_OK) {
+	/*
+	 * argPtr designates a single index.
+	 */
+
+	return TclLindexFlat(interp, listPtr, 1, &argPtr);
+    }
+
+    /*
+     * Here we make a private copy of the index list argument to avoid any
+     * shimmering issues that might invalidate the indices array below while
+     * we are still using it. This is probably unnecessary. It does not appear
+     * that any damaging shimmering is possible, and no test has been devised
+     * to show any error when this private copy is not made. But it's cheap,
+     * and it offers some future-proofing insurance in case the TclLindexFlat
+     * implementation changes in some unexpected way, or some new form of
+     * trace or callback permits things to happen that the current
+     * implementation does not.
+     */
+
+    indexListCopy = TclListObjCopy(NULL, argPtr);
+    if (indexListCopy == NULL) {
+	/*
+	 * argPtr designates something that is neither an index nor a
+	 * well-formed list. Report the error via TclLindexFlat.
+	 */
+
+	return TclLindexFlat(interp, listPtr, 1, &argPtr);
+    }
+
+    if (indexListCopy->typePtr == &tclListType) {
+	List *listRepPtr = ListRepPtr(indexListCopy);
+
+	listPtr = TclLindexFlat(interp, listPtr, listRepPtr->elemCount,
+		&listRepPtr->elements);
+    } else {
+	int indexCount = -1;	/* Size of the array of list indices. */
+	Tcl_Obj **indices = NULL;
+				/* Array of list indices. */
+
+	Tcl_ListObjGetElements(NULL, indexListCopy, &indexCount, &indices);
+	listPtr = TclLindexFlat(interp, listPtr, indexCount, indices);
+    }
+    Tcl_DecrRefCount(indexListCopy);
+    return listPtr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclLindexFlat --
+ *
+ *	This procedure is the core of the 'lindex' command, with all index
+ *	arguments presented as a flat list.
+ *
+ * Results:
+ *	Returns a pointer to the object extracted, or NULL if an error
+ *	occurred. The returned object already includes one reference count for
+ *	the pointer returned.
+ *
+ * Side effects:
+ *	None.
+ *
+ * Notes:
+ *	The reference count of the returned object includes one reference
+ *	corresponding to the pointer returned. Thus, the calling code will
+ *	usually do something like:
+ *		Tcl_SetObjResult(interp, result);
+ *		Tcl_DecrRefCount(result);
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_Obj *
+TclLindexFlat(
+    Tcl_Interp *interp,		/* Tcl interpreter. */
+    Tcl_Obj *listPtr,		/* Tcl object representing the list. */
+    int indexCount,		/* Count of indices. */
+    Tcl_Obj *const indexArray[])/* Array of pointers to Tcl objects that
+				 * represent the indices in the list. */
+{
+    int i;
+
+    Tcl_IncrRefCount(listPtr);
+
+    for (i=0 ; i<indexCount && listPtr ; i++) {
+	int index, listLen = 0;
+	Tcl_Obj **elemPtrs = NULL, *sublistCopy;
+
+	/*
+	 * Here we make a private copy of the current sublist, so we avoid any
+	 * shimmering issues that might invalidate the elemPtr array below
+	 * while we are still using it. See test lindex-8.4.
+	 */
+
+	sublistCopy = TclListObjCopy(interp, listPtr);
+	Tcl_DecrRefCount(listPtr);
+	listPtr = NULL;
+
+	if (sublistCopy == NULL) {
+	    /*
+	     * The sublist is not a list at all => error.
+	     */
+
+	    break;
+	}
+	TclListObjGetElements(NULL, sublistCopy, &listLen, &elemPtrs);
+
+	if (TclGetIntForIndexM(interp, indexArray[i], /*endValue*/ listLen-1,
+		&index) == TCL_OK) {
+	    if (index<0 || index>=listLen) {
+		/*
+		 * Index is out of range. Break out of loop with empty result.
+		 * First check remaining indices for validity
+		 */
+
+		while (++i < indexCount) {
+		    if (TclGetIntForIndexM(interp, indexArray[i], -1, &index)
+			!= TCL_OK) {
+			Tcl_DecrRefCount(sublistCopy);
+			return NULL;
+		    }
+		}
+		listPtr = Tcl_NewObj();
+	    } else {
+		/*
+		 * Extract the pointer to the appropriate element.
+		 */
+
+		listPtr = elemPtrs[index];
+	    }
+	    Tcl_IncrRefCount(listPtr);
+	}
+	Tcl_DecrRefCount(sublistCopy);
+    }
+
+    return listPtr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclLsetList --
+ *
+ *	Core of the 'lset' command when objc == 4. Objv[2] may be either a
+ *	scalar index or a list of indices.
+ *
+ * Results:
+ *	Returns the new value of the list variable, or NULL if there was an
+ *	error. The returned object includes one reference count for the
+ *	pointer returned.
+ *
+ * Side effects:
+ *	None.
+ *
+ * Notes:
+ *	This procedure is implemented entirely as a wrapper around
+ *	TclLsetFlat. All it does is reconfigure the argument format into the
+ *	form required by TclLsetFlat, while taking care to manage shimmering
+ *	in such a way that we tend to keep the most useful intreps and/or
+ *	avoid the most expensive conversions.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_Obj *
+TclLsetList(
+    Tcl_Interp *interp,		/* Tcl interpreter. */
+    Tcl_Obj *listPtr,		/* Pointer to the list being modified. */
+    Tcl_Obj *indexArgPtr,	/* Index or index-list arg to 'lset'. */
+    Tcl_Obj *valuePtr)		/* Value arg to 'lset'. */
+{
+    int indexCount = 0;		/* Number of indices in the index list. */
+    Tcl_Obj **indices = NULL;	/* Vector of indices in the index list. */
+    Tcl_Obj *retValuePtr;	/* Pointer to the list to be returned. */
+    int index;			/* Current index in the list - discarded. */
+    Tcl_Obj *indexListCopy;
+
+    /*
+     * Determine whether the index arg designates a list or a single index.
+     * We have to be careful about the order of the checks to avoid repeated
+     * shimmering; see TIP #22 and #23 for details.
+     */
+
+    if (indexArgPtr->typePtr != &tclListType
+	    && TclGetIntForIndexM(NULL, indexArgPtr, 0, &index) == TCL_OK) {
+	/*
+	 * indexArgPtr designates a single index.
+	 */
+
+	return TclLsetFlat(interp, listPtr, 1, &indexArgPtr, valuePtr);
+
+    }
+
+    indexListCopy = TclListObjCopy(NULL, indexArgPtr);
+    if (indexListCopy == NULL) {
+	/*
+	 * indexArgPtr designates something that is neither an index nor a
+	 * well formed list. Report the error via TclLsetFlat.
+	 */
+
+	return TclLsetFlat(interp, listPtr, 1, &indexArgPtr, valuePtr);
+    }
+    TclListObjGetElements(NULL, indexArgPtr, &indexCount, &indices);
+
+    /*
+     * Let TclLsetFlat handle the actual lset'ting.
+     */
+
+    retValuePtr = TclLsetFlat(interp, listPtr, indexCount, indices, valuePtr);
+
+    Tcl_DecrRefCount(indexListCopy);
+    return retValuePtr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclLsetFlat --
+ *
+ *	Core engine of the 'lset' command.
+ *
+ * Results:
+ *	Returns the new value of the list variable, or NULL if an error
+ *	occurred. The returned object includes one reference count for the
+ *	pointer returned.
+ *
+ * Side effects:
+ *	On entry, the reference count of the variable value does not reflect
+ *	any references held on the stack. The first action of this function is
+ *	to determine whether the object is shared, and to duplicate it if it
+ *	is. The reference count of the duplicate is incremented. At this
+ *	point, the reference count will be 1 for either case, so that the
+ *	object will appear to be unshared.
+ *
+ *	If an error occurs, and the object has been duplicated, the reference
+ *	count on the duplicate is decremented so that it is now 0: this
+ *	dismisses any memory that was allocated by this function.
+ *
+ *	If no error occurs, the reference count of the original object is
+ *	incremented if the object has not been duplicated, and nothing is done
+ *	to a reference count of the duplicate. Now the reference count of an
+ *	unduplicated object is 2 (the returned pointer, plus the one stored in
+ *	the variable). The reference count of a duplicate object is 1,
+ *	reflecting that the returned pointer is the only active reference. The
+ *	caller is expected to store the returned value back in the variable
+ *	and decrement its reference count. (INST_STORE_* does exactly this.)
+ *
+ *	Surgery is performed on the unshared list value to produce the result.
+ *	TclLsetFlat maintains a linked list of Tcl_Obj's whose string
+ *	representations must be spoilt by threading via 'ptr2' of the
+ *	two-pointer internal representation. On entry to TclLsetFlat, the
+ *	values of 'ptr2' are immaterial; on exit, the 'ptr2' field of any
+ *	Tcl_Obj that has been modified is set to NULL.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_Obj *
+TclLsetFlat(
+    Tcl_Interp *interp,		/* Tcl interpreter. */
+    Tcl_Obj *listPtr,		/* Pointer to the list being modified. */
+    int indexCount,		/* Number of index args. */
+    Tcl_Obj *const indexArray[],
+				/* Index args. */
+    Tcl_Obj *valuePtr)		/* Value arg to 'lset'. */
+{
+    int index, result, len;
+    Tcl_Obj *subListPtr, *retValuePtr, *chainPtr;
+
+    /*
+     * If there are no indices, simply return the new value.  (Without
+     * indices, [lset] is a synonym for [set].
+     */
+
+    if (indexCount == 0) {
+	Tcl_IncrRefCount(valuePtr);
+	return valuePtr;
+    }
+
+    /*
+     * If the list is shared, make a copy we can modify (copy-on-write).  We
+     * use Tcl_DuplicateObj() instead of TclListObjCopy() for a few reasons:
+     * 1) we have not yet confirmed listPtr is actually a list; 2) We make a
+     * verbatim copy of any existing string rep, and when we combine that with
+     * the delayed invalidation of string reps of modified Tcl_Obj's
+     * implemented below, the outcome is that any error condition that causes
+     * this routine to return NULL, will leave the string rep of listPtr and
+     * all elements to be unchanged.
+     */
+
+    subListPtr = Tcl_IsShared(listPtr) ? Tcl_DuplicateObj(listPtr) : listPtr;
+
+    /*
+     * Anchor the linked list of Tcl_Obj's whose string reps must be
+     * invalidated if the operation succeeds.
+     */
+
+    retValuePtr = subListPtr;
+    chainPtr = NULL;
+    result = TCL_OK;
+
+    /*
+     * Loop through all the index arguments, and for each one dive into the
+     * appropriate sublist.
+     */
+
+    do {
+	int elemCount;
+	Tcl_Obj *parentList, **elemPtrs;
+
+	/*
+	 * Check for the possible error conditions...
+	 */
+
+	if (TclListObjGetElements(interp, subListPtr, &elemCount, &elemPtrs)
+		!= TCL_OK) {
+	    /* ...the sublist we're indexing into isn't a list at all. */
+	    result = TCL_ERROR;
+	    break;
+	}
+
+	/*
+	 * WARNING: the macro TclGetIntForIndexM is not safe for
+	 * post-increments, avoid '*indexArray++' here.
+	 */
+
+	if (TclGetIntForIndexM(interp, *indexArray, elemCount - 1, &index)
+		!= TCL_OK)  {
+	    /* ...the index we're trying to use isn't an index at all. */
+	    result = TCL_ERROR;
+	    indexArray++;
+	    break;
+	}
+	indexArray++;
+
+	if (index < 0 || index > elemCount) {
+	    /* ...the index points outside the sublist. */
+	    if (interp != NULL) {
+		Tcl_SetObjResult(interp,
+			Tcl_NewStringObj("list index out of range", -1));
+		Tcl_SetErrorCode(interp, "TCL", "OPERATION", "LSET",
+			"BADINDEX", NULL);
+	    }
+	    result = TCL_ERROR;
+	    break;
+	}
+
+	/*
+	 * No error conditions.  As long as we're not yet on the last index,
+	 * determine the next sublist for the next pass through the loop, and
+	 * take steps to make sure it is an unshared copy, as we intend to
+	 * modify it.
+	 */
+
+	if (--indexCount) {
+	    parentList = subListPtr;
+	    if (index == elemCount) {
+		subListPtr = Tcl_NewObj();
+	    } else {
+		subListPtr = elemPtrs[index];
+	    }
+	    if (Tcl_IsShared(subListPtr)) {
+		subListPtr = Tcl_DuplicateObj(subListPtr);
+	    }
+
+	    /*
+	     * Replace the original elemPtr[index] in parentList with a copy
+	     * we know to be unshared.  This call will also deal with the
+	     * situation where parentList shares its intrep with other
+	     * Tcl_Obj's.  Dealing with the shared intrep case can cause
+	     * subListPtr to become shared again, so detect that case and make
+	     * and store another copy.
+	     */
+
+	    if (index == elemCount) {
+		Tcl_ListObjAppendElement(NULL, parentList, subListPtr);
+	    } else {
+		TclListObjSetElement(NULL, parentList, index, subListPtr);
+	    }
+	    if (Tcl_IsShared(subListPtr)) {
+		subListPtr = Tcl_DuplicateObj(subListPtr);
+		TclListObjSetElement(NULL, parentList, index, subListPtr);
+	    }
+
+	    /*
+	     * The TclListObjSetElement() calls do not spoil the string rep of
+	     * parentList, and that's fine for now, since all we've done so
+	     * far is replace a list element with an unshared copy.  The list
+	     * value remains the same, so the string rep. is still valid, and
+	     * unchanged, which is good because if this whole routine returns
+	     * NULL, we'd like to leave no change to the value of the lset
+	     * variable.  Later on, when we set valuePtr in its proper place,
+	     * then all containing lists will have their values changed, and
+	     * will need their string reps spoiled.  We maintain a list of all
+	     * those Tcl_Obj's (via a little intrep surgery) so we can spoil
+	     * them at that time.
+	     */
+
+	    parentList->internalRep.twoPtrValue.ptr2 = chainPtr;
+	    chainPtr = parentList;
+	}
+    } while (indexCount > 0);
+
+    /*
+     * Either we've detected and error condition, and exited the loop with
+     * result == TCL_ERROR, or we've successfully reached the last index, and
+     * we're ready to store valuePtr.  In either case, we need to clean up our
+     * string spoiling list of Tcl_Obj's.
+     */
+
+    while (chainPtr) {
+	Tcl_Obj *objPtr = chainPtr;
+
+	if (result == TCL_OK) {
+	    /*
+	     * We're going to store valuePtr, so spoil string reps of all
+	     * containing lists.
+	     */
+
+	    TclInvalidateStringRep(objPtr);
+	}
+
+	/*
+	 * Clear away our intrep surgery mess.
+	 */
+
+	chainPtr = objPtr->internalRep.twoPtrValue.ptr2;
+	objPtr->internalRep.twoPtrValue.ptr2 = NULL;
+    }
+
+    if (result != TCL_OK) {
+	/*
+	 * Error return; message is already in interp. Clean up any excess
+	 * memory.
+	 */
+
+	if (retValuePtr != listPtr) {
+	    Tcl_DecrRefCount(retValuePtr);
+	}
+	return NULL;
+    }
+
+    /*
+     * Store valuePtr in proper sublist and return. The -1 is to avoid a
+     * compiler warning (not a problem because we checked that we have a
+     * proper list - or something convertible to one - above).
+     */
+
+    len = -1;
+    TclListObjLength(NULL, subListPtr, &len);
+    if (index == len) {
+	Tcl_ListObjAppendElement(NULL, subListPtr, valuePtr);
+    } else {
+	TclListObjSetElement(NULL, subListPtr, index, valuePtr);
+    }
+    TclInvalidateStringRep(subListPtr);
+    Tcl_IncrRefCount(retValuePtr);
+    return retValuePtr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclListObjSetElement --
+ *
+ *	Set a single element of a list to a specified value
+ *
+ * Results:
+ *	The return value is normally TCL_OK. If listPtr does not refer to a
+ *	list object and cannot be converted to one, TCL_ERROR is returned and
+ *	an error message will be left in the interpreter result if interp is
+ *	not NULL. Similarly, if index designates an element outside the range
+ *	[0..listLength-1], where listLength is the count of elements in the
+ *	list object designated by listPtr, TCL_ERROR is returned and an error
+ *	message is left in the interpreter result.
+ *
+ * Side effects:
+ *	Tcl_Panic if listPtr designates a shared object. Otherwise, attempts
+ *	to convert it to a list with a non-shared internal rep. Decrements the
+ *	ref count of the object at the specified index within the list,
+ *	replaces with the object designated by valuePtr, and increments the
+ *	ref count of the replacement object.
+ *
+ *	It is the caller's responsibility to invalidate the string
+ *	representation of the object.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclListObjSetElement(
+    Tcl_Interp *interp,		/* Tcl interpreter; used for error reporting
+				 * if not NULL. */
+    Tcl_Obj *listPtr,		/* List object in which element should be
+				 * stored. */
+    int index,			/* Index of element to store. */
+    Tcl_Obj *valuePtr)		/* Tcl object to store in the designated list
+				 * element. */
+{
+    List *listRepPtr;		/* Internal representation of the list being
+				 * modified. */
+    Tcl_Obj **elemPtrs;		/* Pointers to elements of the list. */
+    int elemCount;		/* Number of elements in the list. */
+
+    /*
+     * Ensure that the listPtr parameter designates an unshared list.
+     */
+
+    if (Tcl_IsShared(listPtr)) {
+	Tcl_Panic("%s called with shared object", "TclListObjSetElement");
+    }
+    if (listPtr->typePtr != &tclListType) {
+	int result;
+
+	if (listPtr->bytes == tclEmptyStringRep) {
+	    if (interp != NULL) {
+		Tcl_SetObjResult(interp,
+			Tcl_NewStringObj("list index out of range", -1));
+		Tcl_SetErrorCode(interp, "TCL", "OPERATION", "LSET",
+			"BADINDEX", NULL);
+	    }
+	    return TCL_ERROR;
+	}
+	result = SetListFromAny(interp, listPtr);
+	if (result != TCL_OK) {
+	    return result;
+	}
+    }
+
+    listRepPtr = ListRepPtr(listPtr);
+    elemCount = listRepPtr->elemCount;
+
+    /*
+     * Ensure that the index is in bounds.
+     */
+
+    if (index<0 || index>=elemCount) {
+	if (interp != NULL) {
+	    Tcl_SetObjResult(interp,
+		    Tcl_NewStringObj("list index out of range", -1));
+	    Tcl_SetErrorCode(interp, "TCL", "OPERATION", "LSET", "BADINDEX",
+		    NULL);
+	}
+	return TCL_ERROR;
+    }
+
+    /*
+     * If the internal rep is shared, replace it with an unshared copy.
+     */
+
+    if (listRepPtr->refCount > 1) {
+	Tcl_Obj **dst, **src = &listRepPtr->elements;
+	List *newPtr = AttemptNewList(NULL, listRepPtr->maxElemCount, NULL);
+
+	if (newPtr == NULL) {
+	    newPtr = AttemptNewList(interp, elemCount, NULL);
+	    if (newPtr == NULL) {
+		return TCL_ERROR;
+	    }
+	}
+	newPtr->refCount++;
+	newPtr->elemCount = elemCount;
+	newPtr->canonicalFlag = listRepPtr->canonicalFlag;
+
+	dst = &newPtr->elements;
+	while (elemCount--) {
+	    *dst = *src++;
+	    Tcl_IncrRefCount(*dst++);
+	}
+
+	listRepPtr->refCount--;
+
+	listPtr->internalRep.twoPtrValue.ptr1 = listRepPtr = newPtr;
+    }
+    elemPtrs = &listRepPtr->elements;
+
+    /*
+     * Add a reference to the new list element.
+     */
+
+    Tcl_IncrRefCount(valuePtr);
+
+    /*
+     * Remove a reference from the old list element.
+     */
+
+    Tcl_DecrRefCount(elemPtrs[index]);
+
+    /*
+     * Stash the new object in the list.
+     */
+
+    elemPtrs[index] = valuePtr;
+
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * FreeListInternalRep --
+ *
+ *	Deallocate the storage associated with a list object's internal
+ *	representation.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Frees listPtr's List* internal representation and sets listPtr's
+ *	internalRep.twoPtrValue.ptr1 to NULL. Decrements the ref counts of all
+ *	element objects, which may free them.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+FreeListInternalRep(
+    Tcl_Obj *listPtr)		/* List object with internal rep to free. */
+{
+    List *listRepPtr = ListRepPtr(listPtr);
+
+    if (listRepPtr->refCount-- <= 1) {
+	Tcl_Obj **elemPtrs = &listRepPtr->elements;
+	int i, numElems = listRepPtr->elemCount;
+
+	for (i = 0;  i < numElems;  i++) {
+	    Tcl_DecrRefCount(elemPtrs[i]);
+	}
+	ckfree(listRepPtr);
+    }
+
+    listPtr->typePtr = NULL;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * DupListInternalRep --
+ *
+ *	Initialize the internal representation of a list Tcl_Obj to share the
+ *	internal representation of an existing list object.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The reference count of the List internal rep is incremented.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+DupListInternalRep(
+    Tcl_Obj *srcPtr,		/* Object with internal rep to copy. */
+    Tcl_Obj *copyPtr)		/* Object with internal rep to set. */
+{
+    List *listRepPtr = ListRepPtr(srcPtr);
+
+    ListSetIntRep(copyPtr, listRepPtr);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * SetListFromAny --
+ *
+ *	Attempt to generate a list internal form for the Tcl object "objPtr".
+ *
+ * Results:
+ *	The return value is TCL_OK or TCL_ERROR. If an error occurs during
+ *	conversion, an error message is left in the interpreter's result
+ *	unless "interp" is NULL.
+ *
+ * Side effects:
+ *	If no error occurs, a list is stored as "objPtr"s internal
+ *	representation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+SetListFromAny(
+    Tcl_Interp *interp,		/* Used for error reporting if not NULL. */
+    Tcl_Obj *objPtr)		/* The object to convert. */
+{
+    List *listRepPtr;
+    Tcl_Obj **elemPtrs;
+
+    /*
+     * Dictionaries are a special case; they have a string representation such
+     * that *all* valid dictionaries are valid lists. Hence we can convert
+     * more directly. Only do this when there's no existing string rep; if
+     * there is, it is the string rep that's authoritative (because it could
+     * describe duplicate keys).
+     */
+
+    if (objPtr->typePtr == &tclDictType && !objPtr->bytes) {
+	Tcl_Obj *keyPtr, *valuePtr;
+	Tcl_DictSearch search;
+	int done, size;
+
+	/*
+	 * Create the new list representation. Note that we do not need to do
+	 * anything with the string representation as the transformation (and
+	 * the reverse back to a dictionary) are both order-preserving. Also
+	 * note that since we know we've got a valid dictionary (by
+	 * representation) we also know that fetching the size of the
+	 * dictionary or iterating over it will not fail.
+	 */
+
+	Tcl_DictObjSize(NULL, objPtr, &size);
+	listRepPtr = AttemptNewList(interp, size > 0 ? 2*size : 1, NULL);
+	if (!listRepPtr) {
+	    return TCL_ERROR;
+	}
+	listRepPtr->elemCount = 2 * size;
+
+	/*
+	 * Populate the list representation.
+	 */
+
+	elemPtrs = &listRepPtr->elements;
+	Tcl_DictObjFirst(NULL, objPtr, &search, &keyPtr, &valuePtr, &done);
+	while (!done) {
+	    *elemPtrs++ = keyPtr;
+	    *elemPtrs++ = valuePtr;
+	    Tcl_IncrRefCount(keyPtr);
+	    Tcl_IncrRefCount(valuePtr);
+	    Tcl_DictObjNext(&search, &keyPtr, &valuePtr, &done);
+	}
+    } else {
+	int estCount, length;
+	const char *limit, *nextElem = TclGetStringFromObj(objPtr, &length);
+
+	/*
+	 * Allocate enough space to hold a (Tcl_Obj *) for each
+	 * (possible) list element.
+	 */
+
+	estCount = TclMaxListLength(nextElem, length, &limit);
+	estCount += (estCount == 0);	/* Smallest list struct holds 1
+					 * element. */
+	listRepPtr = AttemptNewList(interp, estCount, NULL);
+	if (listRepPtr == NULL) {
+	    return TCL_ERROR;
+	}
+	elemPtrs = &listRepPtr->elements;
+
+	/*
+	 * Each iteration, parse and store a list element.
+	 */
+
+	while (nextElem < limit) {
+	    const char *elemStart;
+	    int elemSize, literal;
+
+	    if (TCL_OK != TclFindElement(interp, nextElem, limit - nextElem,
+		    &elemStart, &nextElem, &elemSize, &literal)) {
+		while (--elemPtrs >= &listRepPtr->elements) {
+		    Tcl_DecrRefCount(*elemPtrs);
+		}
+		ckfree((char *) listRepPtr);
+		return TCL_ERROR;
+	    }
+	    if (elemStart == limit) {
+		break;
+	    }
+
+	    /* TODO: replace panic with error on alloc failure? */
+	    if (literal) {
+		TclNewStringObj(*elemPtrs, elemStart, elemSize);
+	    } else {
+		TclNewObj(*elemPtrs);
+		(*elemPtrs)->bytes = ckalloc((unsigned) elemSize + 1);
+		(*elemPtrs)->length = TclCopyAndCollapse(elemSize, elemStart,
+			(*elemPtrs)->bytes);
+	    }
+
+	    Tcl_IncrRefCount(*elemPtrs++);/* Since list now holds ref to it. */
+	}
+
+ 	listRepPtr->elemCount = elemPtrs - &listRepPtr->elements;
+    }
+
+    /*
+     * Free the old internalRep before setting the new one. We do this as late
+     * as possible to allow the conversion code, in particular
+     * Tcl_GetStringFromObj, to use that old internalRep.
+     */
+
+    TclFreeIntRep(objPtr);
+    ListSetIntRep(objPtr, listRepPtr);
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * UpdateStringOfList --
+ *
+ *	Update the string representation for a list object. Note: This
+ *	function does not invalidate an existing old string rep so storage
+ *	will be lost if this has not already been done.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The object's string is set to a valid string that results from the
+ *	list-to-string conversion. This string will be empty if the list has
+ *	no elements. The list internal representation should not be NULL and
+ *	we assume it is not NULL.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+UpdateStringOfList(
+    Tcl_Obj *listPtr)		/* List object with string rep to update. */
+{
+#   define LOCAL_SIZE 20
+    int localFlags[LOCAL_SIZE], *flagPtr = NULL;
+    List *listRepPtr = ListRepPtr(listPtr);
+    int numElems = listRepPtr->elemCount;
+    int i, length, bytesNeeded = 0;
+    const char *elem;
+    char *dst;
+    Tcl_Obj **elemPtrs;
+
+    /*
+     * Mark the list as being canonical; although it will now have a string
+     * rep, it is one we derived through proper "canonical" quoting and so
+     * it's known to be free from nasties relating to [concat] and [eval].
+     */
+
+    listRepPtr->canonicalFlag = 1;
+
+    /*
+     * Handle empty list case first, so rest of the routine is simpler.
+     */
+
+    if (numElems == 0) {
+	listPtr->bytes = tclEmptyStringRep;
+	listPtr->length = 0;
+	return;
+    }
+
+    /*
+     * Pass 1: estimate space, gather flags.
+     */
+
+    if (numElems <= LOCAL_SIZE) {
+	flagPtr = localFlags;
+    } else {
+	/*
+	 * We know numElems <= LIST_MAX, so this is safe.
+	 */
+
+	flagPtr = ckalloc(numElems * sizeof(int));
+    }
+    elemPtrs = &listRepPtr->elements;
+    for (i = 0; i < numElems; i++) {
+	flagPtr[i] = (i ? TCL_DONT_QUOTE_HASH : 0);
+	elem = TclGetStringFromObj(elemPtrs[i], &length);
+	bytesNeeded += TclScanElement(elem, length, flagPtr+i);
+	if (bytesNeeded < 0) {
+	    Tcl_Panic("max size for a Tcl value (%d bytes) exceeded", INT_MAX);
+	}
+    }
+    if (bytesNeeded > INT_MAX - numElems + 1) {
+	Tcl_Panic("max size for a Tcl value (%d bytes) exceeded", INT_MAX);
+    }
+    bytesNeeded += numElems;
+
+    /*
+     * Pass 2: copy into string rep buffer.
+     */
+
+    listPtr->length = bytesNeeded - 1;
+    listPtr->bytes = ckalloc(bytesNeeded);
+    dst = listPtr->bytes;
+    for (i = 0; i < numElems; i++) {
+	flagPtr[i] |= (i ? TCL_DONT_QUOTE_HASH : 0);
+	elem = TclGetStringFromObj(elemPtrs[i], &length);
+	dst += TclConvertElement(elem, length, dst, flagPtr[i]);
+	*dst++ = ' ';
+    }
+    listPtr->bytes[listPtr->length] = '\0';
+
+    if (flagPtr != localFlags) {
+	ckfree(flagPtr);
+    }
+}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tclLiteral.c b/generic/tclLiteral.c
new file mode 100644
index 0000000..03200ca
--- /dev/null
+++ b/generic/tclLiteral.c
@@ -0,0 +1,1233 @@
+/*
+ * tclLiteral.c --
+ *
+ *	Implementation of the global and ByteCode-local literal tables used to
+ *	manage the Tcl objects created for literal values during compilation
+ *	of Tcl scripts. This implementation borrows heavily from the more
+ *	general hashtable implementation of Tcl hash tables that appears in
+ *	tclHash.c.
+ *
+ * Copyright (c) 1997-1998 Sun Microsystems, Inc.
+ * Copyright (c) 2004 by Kevin B. Kenny.  All rights reserved.
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#include "tclInt.h"
+#include "tclCompile.h"
+
+/*
+ * When there are this many entries per bucket, on average, rebuild a
+ * literal's hash table to make it larger.
+ */
+
+#define REBUILD_MULTIPLIER	3
+
+/*
+ * Function prototypes for static functions in this file:
+ */
+
+static int		AddLocalLiteralEntry(CompileEnv *envPtr,
+			    Tcl_Obj *objPtr, int localHash);
+static void		ExpandLocalLiteralArray(CompileEnv *envPtr);
+static unsigned		HashString(const char *string, int length);
+#ifdef TCL_COMPILE_DEBUG
+static LiteralEntry *	LookupLiteralEntry(Tcl_Interp *interp,
+			    Tcl_Obj *objPtr);
+#endif
+static void		RebuildLiteralTable(LiteralTable *tablePtr);
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclInitLiteralTable --
+ *
+ *	This function is called to initialize the fields of a literal table
+ *	structure for either an interpreter or a compilation's CompileEnv
+ *	structure.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The literal table is made ready for use.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclInitLiteralTable(
+    register LiteralTable *tablePtr)
+				/* Pointer to table structure, which is
+				 * supplied by the caller. */
+{
+#if (TCL_SMALL_HASH_TABLE != 4)
+    Tcl_Panic("%s: TCL_SMALL_HASH_TABLE is %d, not 4", "TclInitLiteralTable",
+	    TCL_SMALL_HASH_TABLE);
+#endif
+
+    tablePtr->buckets = tablePtr->staticBuckets;
+    tablePtr->staticBuckets[0] = tablePtr->staticBuckets[1] = 0;
+    tablePtr->staticBuckets[2] = tablePtr->staticBuckets[3] = 0;
+    tablePtr->numBuckets = TCL_SMALL_HASH_TABLE;
+    tablePtr->numEntries = 0;
+    tablePtr->rebuildSize = TCL_SMALL_HASH_TABLE * REBUILD_MULTIPLIER;
+    tablePtr->mask = 3;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclDeleteLiteralTable --
+ *
+ *	This function frees up everything associated with a literal table
+ *	except for the table's structure itself. It is called when the
+ *	interpreter is deleted.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Each literal in the table is released: i.e., its reference count in
+ *	the global literal table is decremented and, if it becomes zero, the
+ *	literal is freed. In addition, the table's bucket array is freed.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclDeleteLiteralTable(
+    Tcl_Interp *interp,		/* Interpreter containing shared literals
+				 * referenced by the table to delete. */
+    LiteralTable *tablePtr)	/* Points to the literal table to delete. */
+{
+    LiteralEntry *entryPtr, *nextPtr;
+    Tcl_Obj *objPtr;
+    int i;
+
+    /*
+     * Release remaining literals in the table. Note that releasing a literal
+     * might release other literals, modifying the table, so we restart the
+     * search from the bucket chain we last found an entry.
+     */
+
+#ifdef TCL_COMPILE_DEBUG
+    TclVerifyGlobalLiteralTable((Interp *) interp);
+#endif /*TCL_COMPILE_DEBUG*/
+
+    /*
+     * We used to call TclReleaseLiteral for each literal in the table, which
+     * is rather inefficient as it causes one lookup-by-hash for each
+     * reference to the literal. We now rely at interp-deletion on each
+     * bytecode object to release its references to the literal Tcl_Obj
+     * without requiring that it updates the global table itself, and deal
+     * here only with the table.
+     */
+
+    for (i=0 ; i<tablePtr->numBuckets ; i++) {
+	entryPtr = tablePtr->buckets[i];
+	while (entryPtr != NULL) {
+	    objPtr = entryPtr->objPtr;
+	    TclDecrRefCount(objPtr);
+	    nextPtr = entryPtr->nextPtr;
+	    ckfree(entryPtr);
+	    entryPtr = nextPtr;
+	}
+    }
+
+    /*
+     * Free up the table's bucket array if it was dynamically allocated.
+     */
+
+    if (tablePtr->buckets != tablePtr->staticBuckets) {
+	ckfree(tablePtr->buckets);
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclCreateLiteral --
+ *
+ *	Find, or if necessary create, an object in the interpreter's literal
+ *	table that has a string representation matching the argument
+ *	string. If nsPtr!=NULL then only literals stored for the namespace are
+ *	considered.
+ *
+ * Results:
+ *	The literal object. If it was created in this call *newPtr is set to
+ *	1, else 0. NULL is returned if newPtr==NULL and no literal is found.
+ *
+ * Side effects:
+ *	Increments the ref count of the global LiteralEntry since the caller
+ *	now holds a reference. If LITERAL_ON_HEAP is set in flags, this
+ *	function is given ownership of the string: if an object is created
+ *	then its string representation is set directly from string, otherwise
+ *	the string is freed. Typically, a caller sets LITERAL_ON_HEAP if
+ *	"string" is an already heap-allocated buffer holding the result of
+ *	backslash substitutions.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_Obj *
+TclCreateLiteral(
+    Interp *iPtr,
+    char *bytes,		/* The start of the string. Note that this is
+				 * not a NUL-terminated string. */
+    int length,			/* Number of bytes in the string. */
+    unsigned hash,		/* The string's hash. If -1, it will be
+				 * computed here. */
+    int *newPtr,
+    Namespace *nsPtr,
+    int flags,
+    LiteralEntry **globalPtrPtr)
+{
+    LiteralTable *globalTablePtr = &iPtr->literalTable;
+    LiteralEntry *globalPtr;
+    int globalHash;
+    Tcl_Obj *objPtr;
+
+    /*
+     * Is it in the interpreter's global literal table?
+     */
+
+    if (hash == (unsigned) -1) {
+	hash = HashString(bytes, length);
+    }
+    globalHash = (hash & globalTablePtr->mask);
+    for (globalPtr=globalTablePtr->buckets[globalHash] ; globalPtr!=NULL;
+	    globalPtr = globalPtr->nextPtr) {
+	objPtr = globalPtr->objPtr;
+	if ((globalPtr->nsPtr == nsPtr)
+		&& (objPtr->length == length) && ((length == 0)
+		|| ((objPtr->bytes[0] == bytes[0])
+		&& (memcmp(objPtr->bytes, bytes, (unsigned) length) == 0)))) {
+	    /*
+	     * A literal was found: return it
+	     */
+
+	    if (newPtr) {
+		*newPtr = 0;
+	    }
+	    if (globalPtrPtr) {
+		*globalPtrPtr = globalPtr;
+	    }
+	    if (flags & LITERAL_ON_HEAP) {
+		ckfree(bytes);
+	    }
+	    globalPtr->refCount++;
+	    return objPtr;
+	}
+    }
+    if (!newPtr) {
+	if (flags & LITERAL_ON_HEAP) {
+	    ckfree(bytes);
+	}
+	return NULL;
+    }
+
+    /*
+     * The literal is new to the interpreter. Add it to the global literal
+     * table.
+     */
+
+    TclNewObj(objPtr);
+    Tcl_IncrRefCount(objPtr);
+    if (flags & LITERAL_ON_HEAP) {
+	objPtr->bytes = bytes;
+	objPtr->length = length;
+    } else {
+	TclInitStringRep(objPtr, bytes, length);
+    }
+
+#ifdef TCL_COMPILE_DEBUG
+    if (LookupLiteralEntry((Tcl_Interp *) iPtr, objPtr) != NULL) {
+	Tcl_Panic("%s: literal \"%.*s\" found globally but shouldn't be",
+		"TclRegisterLiteral", (length>60? 60 : length), bytes);
+    }
+#endif
+
+    globalPtr = ckalloc(sizeof(LiteralEntry));
+    globalPtr->objPtr = objPtr;
+    globalPtr->refCount = 1;
+    globalPtr->nsPtr = nsPtr;
+    globalPtr->nextPtr = globalTablePtr->buckets[globalHash];
+    globalTablePtr->buckets[globalHash] = globalPtr;
+    globalTablePtr->numEntries++;
+
+    /*
+     * If the global literal table has exceeded a decent size, rebuild it with
+     * more buckets.
+     */
+
+    if (globalTablePtr->numEntries >= globalTablePtr->rebuildSize) {
+	RebuildLiteralTable(globalTablePtr);
+    }
+
+#ifdef TCL_COMPILE_DEBUG
+    TclVerifyGlobalLiteralTable(iPtr);
+    {
+	LiteralEntry *entryPtr;
+	int found, i;
+
+	found = 0;
+	for (i=0 ; i<globalTablePtr->numBuckets ; i++) {
+	    for (entryPtr=globalTablePtr->buckets[i]; entryPtr!=NULL ;
+		    entryPtr=entryPtr->nextPtr) {
+		if ((entryPtr == globalPtr) && (entryPtr->objPtr == objPtr)) {
+		    found = 1;
+		}
+	    }
+	}
+	if (!found) {
+	    Tcl_Panic("%s: literal \"%.*s\" wasn't global",
+		    "TclRegisterLiteral", (length>60? 60 : length), bytes);
+	}
+    }
+#endif /*TCL_COMPILE_DEBUG*/
+
+#ifdef TCL_COMPILE_STATS
+    iPtr->stats.numLiteralsCreated++;
+    iPtr->stats.totalLitStringBytes += (double) (length + 1);
+    iPtr->stats.currentLitStringBytes += (double) (length + 1);
+    iPtr->stats.literalCount[TclLog2(length)]++;
+#endif /*TCL_COMPILE_STATS*/
+
+    if (globalPtrPtr) {
+	*globalPtrPtr = globalPtr;
+    }
+    *newPtr = 1;
+    return objPtr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclFetchLiteral --
+ *
+ *	Fetch from a CompileEnv the literal value identified by an index
+ *	value, as returned by a prior call to TclRegisterLiteral().
+ *
+ * Results:
+ *	The literal value, or NULL if the index is out of range.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_Obj *
+TclFetchLiteral(
+    CompileEnv *envPtr,		/* Points to the CompileEnv from which to
+				 * fetch the registered literal value. */
+    unsigned int index)		/* Index of the desired literal, as returned
+				 * by prior call to TclRegisterLiteral() */
+{
+    if (index >= (unsigned int) envPtr->literalArrayNext) {
+	return NULL;
+    }
+    return envPtr->literalArrayPtr[index].objPtr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclRegisterLiteral --
+ *
+ *	Find, or if necessary create, an object in a CompileEnv literal array
+ *	that has a string representation matching the argument string.
+ *
+ * Results:
+ *	The index in the CompileEnv's literal array that references a shared
+ *	literal matching the string. The object is created if necessary.
+ *
+ * Side effects:
+ *	To maximize sharing, we look up the string in the interpreter's global
+ *	literal table. If not found, we create a new shared literal in the
+ *	global table. We then add a reference to the shared literal in the
+ *	CompileEnv's literal array.
+ *
+ *	If LITERAL_ON_HEAP is set in flags, this function is given ownership
+ *	of the string: if an object is created then its string representation
+ *	is set directly from string, otherwise the string is freed. Typically,
+ *	a caller sets LITERAL_ON_HEAP if "string" is an already heap-allocated
+ *	buffer holding the result of backslash substitutions.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclRegisterLiteral(
+    void *ePtr,		/* Points to the CompileEnv in whose object
+				 * array an object is found or created. */
+    register char *bytes,	/* Points to string for which to find or
+				 * create an object in CompileEnv's object
+				 * array. */
+    int length,			/* Number of bytes in the string. If < 0, the
+				 * string consists of all bytes up to the
+				 * first null character. */
+    int flags)			/* If LITERAL_ON_HEAP then the caller already
+				 * malloc'd bytes and ownership is passed to
+				 * this function. If LITERAL_CMD_NAME then
+				 * the literal should not be shared accross
+				 * namespaces. */
+{
+    CompileEnv *envPtr = ePtr;
+    Interp *iPtr = envPtr->iPtr;
+    LiteralTable *localTablePtr = &envPtr->localLitTable;
+    LiteralEntry *globalPtr, *localPtr;
+    Tcl_Obj *objPtr;
+    unsigned hash;
+    int localHash, objIndex, new;
+    Namespace *nsPtr;
+
+    if (length < 0) {
+	length = (bytes ? strlen(bytes) : 0);
+    }
+    hash = HashString(bytes, length);
+
+    /*
+     * Is the literal already in the CompileEnv's local literal array? If so,
+     * just return its index.
+     */
+
+    localHash = (hash & localTablePtr->mask);
+    for (localPtr=localTablePtr->buckets[localHash] ; localPtr!=NULL;
+	    localPtr = localPtr->nextPtr) {
+	objPtr = localPtr->objPtr;
+	if ((objPtr->length == length) && ((length == 0)
+		|| ((objPtr->bytes[0] == bytes[0])
+		&& (memcmp(objPtr->bytes, bytes, (unsigned) length) == 0)))) {
+	    if (flags & LITERAL_ON_HEAP) {
+		ckfree(bytes);
+	    }
+	    objIndex = (localPtr - envPtr->literalArrayPtr);
+#ifdef TCL_COMPILE_DEBUG
+	    TclVerifyLocalLiteralTable(envPtr);
+#endif /*TCL_COMPILE_DEBUG*/
+
+	    return objIndex;
+	}
+    }
+
+    /*
+     * The literal is new to this CompileEnv. If it is a command name, avoid
+     * sharing it accross namespaces, and try not to share it with non-cmd
+     * literals. Note that FQ command names can be shared, so that we register
+     * the namespace as the interp's global NS.
+     */
+
+    if (flags & LITERAL_CMD_NAME) {
+	if ((length >= 2) && (bytes[0] == ':') && (bytes[1] == ':')) {
+	    nsPtr = iPtr->globalNsPtr;
+	} else {
+	    nsPtr = iPtr->varFramePtr->nsPtr;
+	}
+    } else {
+	nsPtr = NULL;
+    }
+
+    /*
+     * Is it in the interpreter's global literal table? If not, create it.
+     */
+
+    objPtr = TclCreateLiteral(iPtr, bytes, length, hash, &new, nsPtr, flags,
+	    &globalPtr);
+    objIndex = AddLocalLiteralEntry(envPtr, objPtr, localHash);
+
+#ifdef TCL_COMPILE_DEBUG
+    if (globalPtr->refCount < 1) {
+	Tcl_Panic("%s: global literal \"%.*s\" had bad refCount %d",
+		"TclRegisterLiteral", (length>60? 60 : length), bytes,
+		globalPtr->refCount);
+    }
+    TclVerifyLocalLiteralTable(envPtr);
+#endif /*TCL_COMPILE_DEBUG*/
+    return objIndex;
+}
+
+#ifdef TCL_COMPILE_DEBUG
+/*
+ *----------------------------------------------------------------------
+ *
+ * LookupLiteralEntry --
+ *
+ *	Finds the LiteralEntry that corresponds to a literal Tcl object
+ *	holding a literal.
+ *
+ * Results:
+ *	Returns the matching LiteralEntry if found, otherwise NULL.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static LiteralEntry *
+LookupLiteralEntry(
+    Tcl_Interp *interp,		/* Interpreter for which objPtr was created to
+				 * hold a literal. */
+    register Tcl_Obj *objPtr)	/* Points to a Tcl object holding a literal
+				 * that was previously created by a call to
+				 * TclRegisterLiteral. */
+{
+    Interp *iPtr = (Interp *) interp;
+    LiteralTable *globalTablePtr = &iPtr->literalTable;
+    register LiteralEntry *entryPtr;
+    const char *bytes;
+    int length, globalHash;
+
+    bytes = TclGetStringFromObj(objPtr, &length);
+    globalHash = (HashString(bytes, length) & globalTablePtr->mask);
+    for (entryPtr=globalTablePtr->buckets[globalHash] ; entryPtr!=NULL;
+	    entryPtr=entryPtr->nextPtr) {
+	if (entryPtr->objPtr == objPtr) {
+	    return entryPtr;
+	}
+    }
+    return NULL;
+}
+
+#endif
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclHideLiteral --
+ *
+ *	Remove a literal entry from the literal hash tables, leaving it in the
+ *	literal array so existing references continue to function. This makes
+ *	it possible to turn a shared literal into a private literal that
+ *	cannot be shared.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Removes the literal from the local hash table and decrements the
+ *	global hash entry's reference count.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclHideLiteral(
+    Tcl_Interp *interp,		/* Interpreter for which objPtr was created to
+				 * hold a literal. */
+    register CompileEnv *envPtr,/* Points to CompileEnv whose literal array
+				 * contains the entry being hidden. */
+    int index)			/* The index of the entry in the literal
+				 * array. */
+{
+    LiteralEntry **nextPtrPtr, *entryPtr, *lPtr;
+    LiteralTable *localTablePtr = &envPtr->localLitTable;
+    int localHash, length;
+    const char *bytes;
+    Tcl_Obj *newObjPtr;
+
+    lPtr = &envPtr->literalArrayPtr[index];
+
+    /*
+     * To avoid unwanted sharing we need to copy the object and remove it from
+     * the local and global literal tables. It still has a slot in the literal
+     * array so it can be referred to by byte codes, but it will not be
+     * matched by literal searches.
+     */
+
+    newObjPtr = Tcl_DuplicateObj(lPtr->objPtr);
+    Tcl_IncrRefCount(newObjPtr);
+    TclReleaseLiteral(interp, lPtr->objPtr);
+    lPtr->objPtr = newObjPtr;
+
+    bytes = TclGetStringFromObj(newObjPtr, &length);
+    localHash = (HashString(bytes, length) & localTablePtr->mask);
+    nextPtrPtr = &localTablePtr->buckets[localHash];
+
+    for (entryPtr=*nextPtrPtr ; entryPtr!=NULL ; entryPtr=*nextPtrPtr) {
+	if (entryPtr == lPtr) {
+	    *nextPtrPtr = lPtr->nextPtr;
+	    lPtr->nextPtr = NULL;
+	    localTablePtr->numEntries--;
+	    break;
+	}
+	nextPtrPtr = &entryPtr->nextPtr;
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclAddLiteralObj --
+ *
+ *	Add a single literal object to the literal array. This function does
+ *	not add the literal to the local or global literal tables. The caller
+ *	is expected to add the entry to whatever tables are appropriate.
+ *
+ * Results:
+ *	The index in the CompileEnv's literal array that references the
+ *	literal. Stores the pointer to the new literal entry in the location
+ *	referenced by the localPtrPtr argument.
+ *
+ * Side effects:
+ *	Expands the literal array if necessary. Increments the refcount on the
+ *	literal object.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclAddLiteralObj(
+    register CompileEnv *envPtr,/* Points to CompileEnv in whose literal array
+				 * the object is to be inserted. */
+    Tcl_Obj *objPtr,		/* The object to insert into the array. */
+    LiteralEntry **litPtrPtr)	/* The location where the pointer to the new
+				 * literal entry should be stored. May be
+				 * NULL. */
+{
+    register LiteralEntry *lPtr;
+    int objIndex;
+
+    if (envPtr->literalArrayNext >= envPtr->literalArrayEnd) {
+	ExpandLocalLiteralArray(envPtr);
+    }
+    objIndex = envPtr->literalArrayNext;
+    envPtr->literalArrayNext++;
+
+    lPtr = &envPtr->literalArrayPtr[objIndex];
+    lPtr->objPtr = objPtr;
+    Tcl_IncrRefCount(objPtr);
+    lPtr->refCount = -1;	/* i.e., unused */
+    lPtr->nextPtr = NULL;
+
+    if (litPtrPtr) {
+	*litPtrPtr = lPtr;
+    }
+
+    return objIndex;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * AddLocalLiteralEntry --
+ *
+ *	Insert a new literal into a CompileEnv's local literal array.
+ *
+ * Results:
+ *	The index in the CompileEnv's literal array that references the
+ *	literal.
+ *
+ * Side effects:
+ *	Expands the literal array if necessary. May rebuild the hash bucket
+ *	array of the CompileEnv's literal array if it becomes too large.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+AddLocalLiteralEntry(
+    register CompileEnv *envPtr,/* Points to CompileEnv in whose literal array
+				 * the object is to be inserted. */
+    Tcl_Obj *objPtr,		/* The literal to add to the CompileEnv. */
+    int localHash)		/* Hash value for the literal's string. */
+{
+    register LiteralTable *localTablePtr = &envPtr->localLitTable;
+    LiteralEntry *localPtr;
+    int objIndex;
+
+    objIndex = TclAddLiteralObj(envPtr, objPtr, &localPtr);
+
+    /*
+     * Add the literal to the local table.
+     */
+
+    localPtr->nextPtr = localTablePtr->buckets[localHash];
+    localTablePtr->buckets[localHash] = localPtr;
+    localTablePtr->numEntries++;
+
+    /*
+     * If the CompileEnv's local literal table has exceeded a decent size,
+     * rebuild it with more buckets.
+     */
+
+    if (localTablePtr->numEntries >= localTablePtr->rebuildSize) {
+	RebuildLiteralTable(localTablePtr);
+    }
+
+#ifdef TCL_COMPILE_DEBUG
+    TclVerifyLocalLiteralTable(envPtr);
+    {
+	char *bytes;
+	int length, found, i;
+
+	found = 0;
+	for (i=0 ; i<localTablePtr->numBuckets ; i++) {
+	    for (localPtr=localTablePtr->buckets[i] ; localPtr!=NULL ;
+		    localPtr=localPtr->nextPtr) {
+		if (localPtr->objPtr == objPtr) {
+		    found = 1;
+		}
+	    }
+	}
+
+	if (!found) {
+	    bytes = Tcl_GetStringFromObj(objPtr, &length);
+	    Tcl_Panic("%s: literal \"%.*s\" wasn't found locally",
+		    "AddLocalLiteralEntry", (length>60? 60 : length), bytes);
+	}
+    }
+#endif /*TCL_COMPILE_DEBUG*/
+
+    return objIndex;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ExpandLocalLiteralArray --
+ *
+ *	Function that uses malloc to allocate more storage for a CompileEnv's
+ *	local literal array.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The literal array in *envPtr is reallocated to a new array of double
+ *	the size, and if envPtr->mallocedLiteralArray is non-zero the old
+ *	array is freed. Entries are copied from the old array to the new one.
+ *	The local literal table is updated to refer to the new entries.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+ExpandLocalLiteralArray(
+    register CompileEnv *envPtr)/* Points to the CompileEnv whose object array
+				 * must be enlarged. */
+{
+    /*
+     * The current allocated local literal entries are stored between elements
+     * 0 and (envPtr->literalArrayNext - 1) [inclusive].
+     */
+
+    LiteralTable *localTablePtr = &envPtr->localLitTable;
+    int currElems = envPtr->literalArrayNext;
+    size_t currBytes = (currElems * sizeof(LiteralEntry));
+    LiteralEntry *currArrayPtr = envPtr->literalArrayPtr;
+    LiteralEntry *newArrayPtr;
+    int i;
+    unsigned int newSize = (currBytes <= UINT_MAX / 2) ? 2*currBytes : UINT_MAX;
+
+    if (currBytes == newSize) {
+	Tcl_Panic("max size of Tcl literal array (%d literals) exceeded",
+		currElems);
+    }
+
+    if (envPtr->mallocedLiteralArray) {
+	newArrayPtr = ckrealloc(currArrayPtr, newSize);
+    } else {
+	/*
+	 * envPtr->literalArrayPtr isn't a ckalloc'd pointer, so we must
+	 * code a ckrealloc equivalent for ourselves.
+	 */
+
+	newArrayPtr = ckalloc(newSize);
+	memcpy(newArrayPtr, currArrayPtr, currBytes);
+	envPtr->mallocedLiteralArray = 1;
+    }
+
+    /*
+     * Update the local literal table's bucket array.
+     */
+
+    if (currArrayPtr != newArrayPtr) {
+	for (i=0 ; i<currElems ; i++) {
+	    if (newArrayPtr[i].nextPtr != NULL) {
+		newArrayPtr[i].nextPtr = newArrayPtr
+			+ (newArrayPtr[i].nextPtr - currArrayPtr);
+	    }
+	}
+	for (i=0 ; i<localTablePtr->numBuckets ; i++) {
+	    if (localTablePtr->buckets[i] != NULL) {
+		localTablePtr->buckets[i] = newArrayPtr
+			+ (localTablePtr->buckets[i] - currArrayPtr);
+	    }
+	}
+    }
+
+    envPtr->literalArrayPtr = newArrayPtr;
+    envPtr->literalArrayEnd = newSize / sizeof(LiteralEntry);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclReleaseLiteral --
+ *
+ *	This function releases a reference to one of the shared Tcl objects
+ *	that hold literals. It is called to release the literals referenced by
+ *	a ByteCode that is being destroyed, and it is also called by
+ *	TclDeleteLiteralTable.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The reference count for the global LiteralTable entry that corresponds
+ *	to the literal is decremented. If no other reference to a global
+ *	literal object remains, it is freed.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclReleaseLiteral(
+    Tcl_Interp *interp,		/* Interpreter for which objPtr was created to
+				 * hold a literal. */
+    register Tcl_Obj *objPtr)	/* Points to a literal object that was
+				 * previously created by a call to
+				 * TclRegisterLiteral. */
+{
+    Interp *iPtr = (Interp *) interp;
+    LiteralTable *globalTablePtr;
+    register LiteralEntry *entryPtr, *prevPtr;
+    const char *bytes;
+    int length, index;
+
+    if (iPtr == NULL) {
+	goto done;
+    }
+
+    globalTablePtr = &iPtr->literalTable;
+    bytes = TclGetStringFromObj(objPtr, &length);
+    index = (HashString(bytes, length) & globalTablePtr->mask);
+
+    /*
+     * Check to see if the object is in the global literal table and remove
+     * this reference. The object may not be in the table if it is a hidden
+     * local literal.
+     */
+
+    for (prevPtr=NULL, entryPtr=globalTablePtr->buckets[index];
+	    entryPtr!=NULL ; prevPtr=entryPtr, entryPtr=entryPtr->nextPtr) {
+	if (entryPtr->objPtr == objPtr) {
+	    entryPtr->refCount--;
+
+	    /*
+	     * If the literal is no longer being used by any ByteCode, delete
+	     * the entry then remove the reference corresponding to the global
+	     * literal table entry (decrement the ref count of the object).
+	     */
+
+	    if (entryPtr->refCount == 0) {
+		if (prevPtr == NULL) {
+		    globalTablePtr->buckets[index] = entryPtr->nextPtr;
+		} else {
+		    prevPtr->nextPtr = entryPtr->nextPtr;
+		}
+		ckfree(entryPtr);
+		globalTablePtr->numEntries--;
+
+		TclDecrRefCount(objPtr);
+
+#ifdef TCL_COMPILE_STATS
+		iPtr->stats.currentLitStringBytes -= (double) (length + 1);
+#endif /*TCL_COMPILE_STATS*/
+	    }
+	    break;
+	}
+    }
+
+    /*
+     * Remove the reference corresponding to the local literal table entry.
+     */
+
+    done:
+    Tcl_DecrRefCount(objPtr);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * HashString --
+ *
+ *	Compute a one-word summary of a text string, which can be used to
+ *	generate a hash index.
+ *
+ * Results:
+ *	The return value is a one-word summary of the information in string.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static unsigned
+HashString(
+    register const char *string,	/* String for which to compute hash value. */
+    int length)			/* Number of bytes in the string. */
+{
+    register unsigned int result = 0;
+
+    /*
+     * I tried a zillion different hash functions and asked many other people
+     * for advice. Many people had their own favorite functions, all
+     * different, but no-one had much idea why they were good ones. I chose
+     * the one below (multiply by 9 and add new character) because of the
+     * following reasons:
+     *
+     * 1. Multiplying by 10 is perfect for keys that are decimal strings, and
+     *    multiplying by 9 is just about as good.
+     * 2. Times-9 is (shift-left-3) plus (old). This means that each
+     *    character's bits hang around in the low-order bits of the hash value
+     *    for ever, plus they spread fairly rapidly up to the high-order bits
+     *    to fill out the hash value. This seems works well both for decimal
+     *    and non-decimal strings.
+     *
+     * Note that this function is very weak against malicious strings; it's
+     * very easy to generate multiple keys that have the same hashcode. On the
+     * other hand, that hardly ever actually occurs and this function *is*
+     * very cheap, even by comparison with industry-standard hashes like FNV.
+     * If real strength of hash is required though, use a custom hash based on
+     * Bob Jenkins's lookup3(), but be aware that it's significantly slower.
+     * Tcl scripts tend to not have a big issue in this area, and literals
+     * mostly aren't looked up by name anyway.
+     *
+     * See also HashStringKey in tclHash.c.
+     * See also TclObjHashKey in tclObj.c.
+     *
+     * See [tcl-Feature Request #2958832]
+     */
+
+    if (length > 0) {
+	result = UCHAR(*string);
+	while (--length) {
+	    result += (result << 3) + UCHAR(*++string);
+	}
+    }
+    return result;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * RebuildLiteralTable --
+ *
+ *	This function is invoked when the ratio of entries to hash buckets
+ *	becomes too large in a local or global literal table. It allocates a
+ *	larger bucket array and moves the entries into the new buckets.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Memory gets reallocated and entries get rehashed into new buckets.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+RebuildLiteralTable(
+    register LiteralTable *tablePtr)
+				/* Local or global table to enlarge. */
+{
+    LiteralEntry **oldBuckets;
+    register LiteralEntry **oldChainPtr, **newChainPtr;
+    register LiteralEntry *entryPtr;
+    LiteralEntry **bucketPtr;
+    const char *bytes;
+    unsigned int oldSize;
+    int count, index, length;
+
+    oldSize = tablePtr->numBuckets;
+    oldBuckets = tablePtr->buckets;
+
+    /*
+     * Allocate and initialize the new bucket array, and set up hashing
+     * constants for new array size.
+     */
+
+    if (oldSize > UINT_MAX/(4 * sizeof(LiteralEntry *))) {
+	/*
+	 * Memory allocator limitations will not let us create the
+	 * next larger table size.  Best option is to limp along
+	 * with what we have.
+	 */
+
+	return;
+    }
+
+    tablePtr->numBuckets *= 4;
+    tablePtr->buckets = ckalloc(tablePtr->numBuckets * sizeof(LiteralEntry*));
+    for (count=tablePtr->numBuckets, newChainPtr=tablePtr->buckets;
+	    count>0 ; count--, newChainPtr++) {
+	*newChainPtr = NULL;
+    }
+    tablePtr->rebuildSize *= 4;
+    tablePtr->mask = (tablePtr->mask << 2) + 3;
+
+    /*
+     * Rehash all of the existing entries into the new bucket array.
+     */
+
+    for (oldChainPtr=oldBuckets ; oldSize>0 ; oldSize--,oldChainPtr++) {
+	for (entryPtr=*oldChainPtr ; entryPtr!=NULL ; entryPtr=*oldChainPtr) {
+	    bytes = TclGetStringFromObj(entryPtr->objPtr, &length);
+	    index = (HashString(bytes, length) & tablePtr->mask);
+
+	    *oldChainPtr = entryPtr->nextPtr;
+	    bucketPtr = &tablePtr->buckets[index];
+	    entryPtr->nextPtr = *bucketPtr;
+	    *bucketPtr = entryPtr;
+	}
+    }
+
+    /*
+     * Free up the old bucket array, if it was dynamically allocated.
+     */
+
+    if (oldBuckets != tablePtr->staticBuckets) {
+	ckfree(oldBuckets);
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclInvalidateCmdLiteral --
+ *
+ *	Invalidate a command literal entry, if present in the literal hash
+ *	tables, by resetting its internal representation. This invalidation
+ *	leaves it in the literal tables and in existing literal arrays. As a
+ *	result, existing references continue to work but we force a fresh
+ *	command look-up upon the next use (see, in particular,
+ *	TclSetCmdNameObj()).
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Resets the internal representation of the CmdName Tcl_Obj
+ *	using TclFreeIntRep().
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclInvalidateCmdLiteral(
+    Tcl_Interp *interp,		/* Interpreter for which to invalidate a
+				 * command literal. */
+    const char *name,		/* Points to the start of the cmd literal
+				 * name. */
+    Namespace *nsPtr)		/* The namespace for which to lookup and
+				 * invalidate a cmd literal. */
+{
+    Interp *iPtr = (Interp *) interp;
+    Tcl_Obj *literalObjPtr = TclCreateLiteral(iPtr, (char *) name,
+	    strlen(name), -1, NULL, nsPtr, 0, NULL);
+
+    if (literalObjPtr != NULL) {
+	if (literalObjPtr->typePtr == &tclCmdNameType) {
+	    TclFreeIntRep(literalObjPtr);
+	}
+	/* Balance the refcount effects of TclCreateLiteral() above */
+	Tcl_IncrRefCount(literalObjPtr);
+	TclReleaseLiteral(interp, literalObjPtr);
+    }
+}
+
+#ifdef TCL_COMPILE_STATS
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclLiteralStats --
+ *
+ *	Return statistics describing the layout of the hash table in its hash
+ *	buckets.
+ *
+ * Results:
+ *	The return value is a malloc-ed string containing information about
+ *	tablePtr. It is the caller's responsibility to free this string.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+char *
+TclLiteralStats(
+    LiteralTable *tablePtr)	/* Table for which to produce stats. */
+{
+#define NUM_COUNTERS 10
+    int count[NUM_COUNTERS], overflow, i, j;
+    double average, tmp;
+    register LiteralEntry *entryPtr;
+    char *result, *p;
+
+    /*
+     * Compute a histogram of bucket usage. For each bucket chain i, j is the
+     * number of entries in the chain.
+     */
+
+    for (i=0 ; i<NUM_COUNTERS ; i++) {
+	count[i] = 0;
+    }
+    overflow = 0;
+    average = 0.0;
+    for (i=0 ; i<tablePtr->numBuckets ; i++) {
+	j = 0;
+	for (entryPtr=tablePtr->buckets[i] ; entryPtr!=NULL;
+		entryPtr=entryPtr->nextPtr) {
+	    j++;
+	}
+	if (j < NUM_COUNTERS) {
+	    count[j]++;
+	} else {
+	    overflow++;
+	}
+	tmp = j;
+	average += (tmp+1.0)*(tmp/tablePtr->numEntries)/2.0;
+    }
+
+    /*
+     * Print out the histogram and a few other pieces of information.
+     */
+
+    result = ckalloc(NUM_COUNTERS*60 + 300);
+    sprintf(result, "%d entries in table, %d buckets\n",
+	    tablePtr->numEntries, tablePtr->numBuckets);
+    p = result + strlen(result);
+    for (i=0 ; i<NUM_COUNTERS ; i++) {
+	sprintf(p, "number of buckets with %d entries: %d\n",
+		i, count[i]);
+	p += strlen(p);
+    }
+    sprintf(p, "number of buckets with %d or more entries: %d\n",
+	    NUM_COUNTERS, overflow);
+    p += strlen(p);
+    sprintf(p, "average search distance for entry: %.1f", average);
+    return result;
+}
+#endif /*TCL_COMPILE_STATS*/
+
+#ifdef TCL_COMPILE_DEBUG
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclVerifyLocalLiteralTable --
+ *
+ *	Check a CompileEnv's local literal table for consistency.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Tcl_Panic if problems are found.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclVerifyLocalLiteralTable(
+    CompileEnv *envPtr)		/* Points to CompileEnv whose literal table is
+				 * to be validated. */
+{
+    register LiteralTable *localTablePtr = &envPtr->localLitTable;
+    register LiteralEntry *localPtr;
+    char *bytes;
+    register int i;
+    int length, count;
+
+    count = 0;
+    for (i=0 ; i<localTablePtr->numBuckets ; i++) {
+	for (localPtr=localTablePtr->buckets[i] ; localPtr!=NULL;
+		localPtr=localPtr->nextPtr) {
+	    count++;
+	    if (localPtr->refCount != -1) {
+		bytes = Tcl_GetStringFromObj(localPtr->objPtr, &length);
+		Tcl_Panic("%s: local literal \"%.*s\" had bad refCount %d",
+			"TclVerifyLocalLiteralTable",
+			(length>60? 60 : length), bytes, localPtr->refCount);
+	    }
+	    if (LookupLiteralEntry((Tcl_Interp *) envPtr->iPtr,
+		    localPtr->objPtr) == NULL) {
+		bytes = Tcl_GetStringFromObj(localPtr->objPtr, &length);
+		Tcl_Panic("%s: local literal \"%.*s\" is not global",
+			"TclVerifyLocalLiteralTable",
+			(length>60? 60 : length), bytes);
+	    }
+	    if (localPtr->objPtr->bytes == NULL) {
+		Tcl_Panic("%s: literal has NULL string rep",
+			"TclVerifyLocalLiteralTable");
+	    }
+	}
+    }
+    if (count != localTablePtr->numEntries) {
+	Tcl_Panic("%s: local literal table had %d entries, should be %d",
+		"TclVerifyLocalLiteralTable", count,
+		localTablePtr->numEntries);
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclVerifyGlobalLiteralTable --
+ *
+ *	Check an interpreter's global literal table literal for consistency.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Tcl_Panic if problems are found.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclVerifyGlobalLiteralTable(
+    Interp *iPtr)		/* Points to interpreter whose global literal
+				 * table is to be validated. */
+{
+    register LiteralTable *globalTablePtr = &iPtr->literalTable;
+    register LiteralEntry *globalPtr;
+    char *bytes;
+    register int i;
+    int length, count;
+
+    count = 0;
+    for (i=0 ; i<globalTablePtr->numBuckets ; i++) {
+	for (globalPtr=globalTablePtr->buckets[i] ; globalPtr!=NULL;
+		globalPtr=globalPtr->nextPtr) {
+	    count++;
+	    if (globalPtr->refCount < 1) {
+		bytes = Tcl_GetStringFromObj(globalPtr->objPtr, &length);
+		Tcl_Panic("%s: global literal \"%.*s\" had bad refCount %d",
+			"TclVerifyGlobalLiteralTable",
+			(length>60? 60 : length), bytes, globalPtr->refCount);
+	    }
+	    if (globalPtr->objPtr->bytes == NULL) {
+		Tcl_Panic("%s: literal has NULL string rep",
+			"TclVerifyGlobalLiteralTable");
+	    }
+	}
+    }
+    if (count != globalTablePtr->numEntries) {
+	Tcl_Panic("%s: global literal table had %d entries, should be %d",
+		"TclVerifyGlobalLiteralTable", count,
+		globalTablePtr->numEntries);
+    }
+}
+#endif /*TCL_COMPILE_DEBUG*/
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tclLoad.c b/generic/tclLoad.c
new file mode 100644
index 0000000..7c70e03
--- /dev/null
+++ b/generic/tclLoad.c
@@ -0,0 +1,1179 @@
+/*
+ * tclLoad.c --
+ *
+ *	This file provides the generic portion (those that are the same on all
+ *	platforms) of Tcl's dynamic loading facilities.
+ *
+ * Copyright (c) 1995-1997 Sun Microsystems, Inc.
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#include "tclInt.h"
+
+/*
+ * The following structure describes a package that has been loaded either
+ * dynamically (with the "load" command) or statically (as indicated by a call
+ * to TclGetLoadedPackages). All such packages are linked together into a
+ * single list for the process. Packages are never unloaded, until the
+ * application exits, when TclFinalizeLoad is called, and these structures are
+ * freed.
+ */
+
+typedef struct LoadedPackage {
+    char *fileName;		/* Name of the file from which the package was
+				 * loaded. An empty string means the package
+				 * is loaded statically. Malloc-ed. */
+    char *packageName;		/* Name of package prefix for the package,
+				 * properly capitalized (first letter UC,
+				 * others LC), no "_", as in "Net".
+				 * Malloc-ed. */
+    Tcl_LoadHandle loadHandle;	/* Token for the loaded file which should be
+				 * passed to (*unLoadProcPtr)() when the file
+				 * is no longer needed. If fileName is NULL,
+				 * then this field is irrelevant. */
+    Tcl_PackageInitProc *initProc;
+				/* Initialization function to call to
+				 * incorporate this package into a trusted
+				 * interpreter. */
+    Tcl_PackageInitProc *safeInitProc;
+				/* Initialization function to call to
+				 * incorporate this package into a safe
+				 * interpreter (one that will execute
+				 * untrusted scripts). NULL means the package
+				 * can't be used in unsafe interpreters. */
+    Tcl_PackageUnloadProc *unloadProc;
+				/* Finalisation function to unload a package
+				 * from a trusted interpreter. NULL means that
+				 * the package cannot be unloaded. */
+    Tcl_PackageUnloadProc *safeUnloadProc;
+				/* Finalisation function to unload a package
+				 * from a safe interpreter. NULL means that
+				 * the package cannot be unloaded. */
+    int interpRefCount;		/* How many times the package has been loaded
+				 * in trusted interpreters. */
+    int safeInterpRefCount;	/* How many times the package has been loaded
+				 * in safe interpreters. */
+    struct LoadedPackage *nextPtr;
+				/* Next in list of all packages loaded into
+				 * this application process. NULL means end of
+				 * list. */
+} LoadedPackage;
+
+/*
+ * TCL_THREADS
+ * There is a global list of packages that is anchored at firstPackagePtr.
+ * Access to this list is governed by a mutex.
+ */
+
+static LoadedPackage *firstPackagePtr = NULL;
+				/* First in list of all packages loaded into
+				 * this process. */
+
+TCL_DECLARE_MUTEX(packageMutex)
+
+/*
+ * The following structure represents a particular package that has been
+ * incorporated into a particular interpreter (by calling its initialization
+ * function). There is a list of these structures for each interpreter, with
+ * an AssocData value (key "load") for the interpreter that points to the
+ * first package (if any).
+ */
+
+typedef struct InterpPackage {
+    LoadedPackage *pkgPtr;	/* Points to detailed information about
+				 * package. */
+    struct InterpPackage *nextPtr;
+				/* Next package in this interpreter, or NULL
+				 * for end of list. */
+} InterpPackage;
+
+/*
+ * Prototypes for functions that are private to this file:
+ */
+
+static void		LoadCleanupProc(ClientData clientData,
+			    Tcl_Interp *interp);
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_LoadObjCmd --
+ *
+ *	This function is invoked to process the "load" Tcl command. See the
+ *	user documentation for details on what it does.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_LoadObjCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    Tcl_Interp *target;
+    LoadedPackage *pkgPtr, *defaultPtr;
+    Tcl_DString pkgName, tmp, initName, safeInitName;
+    Tcl_DString unloadName, safeUnloadName;
+    InterpPackage *ipFirstPtr, *ipPtr;
+    int code, namesMatch, filesMatch, offset;
+    const char *symbols[2];
+    Tcl_PackageInitProc *initProc;
+    const char *p, *fullFileName, *packageName;
+    Tcl_LoadHandle loadHandle;
+    Tcl_UniChar ch;
+    unsigned len;
+    int index, flags = 0;
+    Tcl_Obj *const *savedobjv = objv;
+    static const char *const options[] = {
+	"-global",		"-lazy",		"--",	NULL
+    };
+    enum options {
+	LOAD_GLOBAL,	LOAD_LAZY,	LOAD_LAST
+    };
+
+    while (objc > 2) {
+	if (TclGetString(objv[1])[0] != '-') {
+	    break;
+	}
+	if (Tcl_GetIndexFromObj(interp, objv[1], options, "option", 0,
+		&index) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	++objv; --objc;
+	if (LOAD_GLOBAL == (enum options) index) {
+	    flags |= TCL_LOAD_GLOBAL;
+	} else if (LOAD_LAZY == (enum options) index) {
+	    flags |= TCL_LOAD_LAZY;
+	} else {
+		break;
+	}
+    }
+    if ((objc < 2) || (objc > 4)) {
+	Tcl_WrongNumArgs(interp, 1, savedobjv, "?-global? ?-lazy? ?--? fileName ?packageName? ?interp?");
+	return TCL_ERROR;
+    }
+    if (Tcl_FSConvertToPathType(interp, objv[1]) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    fullFileName = Tcl_GetString(objv[1]);
+
+    Tcl_DStringInit(&pkgName);
+    Tcl_DStringInit(&initName);
+    Tcl_DStringInit(&safeInitName);
+    Tcl_DStringInit(&unloadName);
+    Tcl_DStringInit(&safeUnloadName);
+    Tcl_DStringInit(&tmp);
+
+    packageName = NULL;
+    if (objc >= 3) {
+	packageName = Tcl_GetString(objv[2]);
+	if (packageName[0] == '\0') {
+	    packageName = NULL;
+	}
+    }
+    if ((fullFileName[0] == 0) && (packageName == NULL)) {
+	Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		"must specify either file name or package name", -1));
+	Tcl_SetErrorCode(interp, "TCL", "OPERATION", "LOAD", "NOLIBRARY",
+		NULL);
+	code = TCL_ERROR;
+	goto done;
+    }
+
+    /*
+     * Figure out which interpreter we're going to load the package into.
+     */
+
+    target = interp;
+    if (objc == 4) {
+	const char *slaveIntName = Tcl_GetString(objv[3]);
+
+	target = Tcl_GetSlave(interp, slaveIntName);
+	if (target == NULL) {
+	    code = TCL_ERROR;
+	    goto done;
+	}
+    }
+
+    /*
+     * Scan through the packages that are currently loaded to see if the
+     * package we want is already loaded. We'll use a loaded package if it
+     * meets any of the following conditions:
+     *  - Its name and file match the once we're looking for.
+     *  - Its file matches, and we weren't given a name.
+     *  - Its name matches, the file name was specified as empty, and there is
+     *	  only no statically loaded package with the same name.
+     */
+
+    Tcl_MutexLock(&packageMutex);
+
+    defaultPtr = NULL;
+    for (pkgPtr = firstPackagePtr; pkgPtr != NULL; pkgPtr = pkgPtr->nextPtr) {
+	if (packageName == NULL) {
+	    namesMatch = 0;
+	} else {
+	    TclDStringClear(&pkgName);
+	    Tcl_DStringAppend(&pkgName, packageName, -1);
+	    TclDStringClear(&tmp);
+	    Tcl_DStringAppend(&tmp, pkgPtr->packageName, -1);
+	    Tcl_UtfToLower(Tcl_DStringValue(&pkgName));
+	    Tcl_UtfToLower(Tcl_DStringValue(&tmp));
+	    if (strcmp(Tcl_DStringValue(&tmp),
+		    Tcl_DStringValue(&pkgName)) == 0) {
+		namesMatch = 1;
+	    } else {
+		namesMatch = 0;
+	    }
+	}
+	TclDStringClear(&pkgName);
+
+	filesMatch = (strcmp(pkgPtr->fileName, fullFileName) == 0);
+	if (filesMatch && (namesMatch || (packageName == NULL))) {
+	    break;
+	}
+	if (namesMatch && (fullFileName[0] == 0)) {
+	    defaultPtr = pkgPtr;
+	}
+	if (filesMatch && !namesMatch && (fullFileName[0] != 0)) {
+	    /*
+	     * Can't have two different packages loaded from the same file.
+	     */
+
+	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		    "file \"%s\" is already loaded for package \"%s\"",
+		    fullFileName, pkgPtr->packageName));
+	    Tcl_SetErrorCode(interp, "TCL", "OPERATION", "LOAD",
+		    "SPLITPERSONALITY", NULL);
+	    code = TCL_ERROR;
+	    Tcl_MutexUnlock(&packageMutex);
+	    goto done;
+	}
+    }
+    Tcl_MutexUnlock(&packageMutex);
+    if (pkgPtr == NULL) {
+	pkgPtr = defaultPtr;
+    }
+
+    /*
+     * Scan through the list of packages already loaded in the target
+     * interpreter. If the package we want is already loaded there, then
+     * there's nothing for us to do.
+     */
+
+    if (pkgPtr != NULL) {
+	ipFirstPtr = Tcl_GetAssocData(target, "tclLoad", NULL);
+	for (ipPtr = ipFirstPtr; ipPtr != NULL; ipPtr = ipPtr->nextPtr) {
+	    if (ipPtr->pkgPtr == pkgPtr) {
+		code = TCL_OK;
+		goto done;
+	    }
+	}
+    }
+
+    if (pkgPtr == NULL) {
+	/*
+	 * The desired file isn't currently loaded, so load it. It's an error
+	 * if the desired package is a static one.
+	 */
+
+	if (fullFileName[0] == 0) {
+	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		    "package \"%s\" isn't loaded statically", packageName));
+	    Tcl_SetErrorCode(interp, "TCL", "OPERATION", "LOAD", "NOTSTATIC",
+		    NULL);
+	    code = TCL_ERROR;
+	    goto done;
+	}
+
+	/*
+	 * Figure out the module name if it wasn't provided explicitly.
+	 */
+
+	if (packageName != NULL) {
+	    Tcl_DStringAppend(&pkgName, packageName, -1);
+	} else {
+	    int retc;
+
+	    /*
+	     * Threading note - this call used to be protected by a mutex.
+	     */
+
+	    retc = TclGuessPackageName(fullFileName, &pkgName);
+	    if (!retc) {
+		Tcl_Obj *splitPtr, *pkgGuessPtr;
+		int pElements;
+		const char *pkgGuess;
+
+		/*
+		 * The platform-specific code couldn't figure out the module
+		 * name. Make a guess by taking the last element of the file
+		 * name, stripping off any leading "lib", and then using all
+		 * of the alphabetic and underline characters that follow
+		 * that.
+		 */
+
+		splitPtr = Tcl_FSSplitPath(objv[1], &pElements);
+		Tcl_ListObjIndex(NULL, splitPtr, pElements -1, &pkgGuessPtr);
+		pkgGuess = Tcl_GetString(pkgGuessPtr);
+		if ((pkgGuess[0] == 'l') && (pkgGuess[1] == 'i')
+			&& (pkgGuess[2] == 'b')) {
+		    pkgGuess += 3;
+		}
+#ifdef __CYGWIN__
+		if ((pkgGuess[0] == 'c') && (pkgGuess[1] == 'y')
+			&& (pkgGuess[2] == 'g')) {
+		    pkgGuess += 3;
+		}
+#endif /* __CYGWIN__ */
+		for (p = pkgGuess; *p != 0; p += offset) {
+		    offset = Tcl_UtfToUniChar(p, &ch);
+		    if ((ch > 0x100)
+			    || !(isalpha(UCHAR(ch)) /* INTL: ISO only */
+				    || (UCHAR(ch) == '_'))) {
+			break;
+		    }
+		}
+		if (p == pkgGuess) {
+		    Tcl_DecrRefCount(splitPtr);
+		    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+			    "couldn't figure out package name for %s",
+			    fullFileName));
+		    Tcl_SetErrorCode(interp, "TCL", "OPERATION", "LOAD",
+			    "WHATPACKAGE", NULL);
+		    code = TCL_ERROR;
+		    goto done;
+		}
+		Tcl_DStringAppend(&pkgName, pkgGuess, p - pkgGuess);
+		Tcl_DecrRefCount(splitPtr);
+	    }
+	}
+
+	/*
+	 * Fix the capitalization in the package name so that the first
+	 * character is in caps (or title case) but the others are all
+	 * lower-case.
+	 */
+
+	Tcl_DStringSetLength(&pkgName,
+		Tcl_UtfToTitle(Tcl_DStringValue(&pkgName)));
+
+	/*
+	 * Compute the names of the two initialization functions, based on the
+	 * package name.
+	 */
+
+	TclDStringAppendDString(&initName, &pkgName);
+	TclDStringAppendLiteral(&initName, "_Init");
+	TclDStringAppendDString(&safeInitName, &pkgName);
+	TclDStringAppendLiteral(&safeInitName, "_SafeInit");
+	TclDStringAppendDString(&unloadName, &pkgName);
+	TclDStringAppendLiteral(&unloadName, "_Unload");
+	TclDStringAppendDString(&safeUnloadName, &pkgName);
+	TclDStringAppendLiteral(&safeUnloadName, "_SafeUnload");
+
+	/*
+	 * Call platform-specific code to load the package and find the two
+	 * initialization functions.
+	 */
+
+	symbols[0] = Tcl_DStringValue(&initName);
+	symbols[1] = NULL;
+
+	Tcl_MutexLock(&packageMutex);
+	code = Tcl_LoadFile(interp, objv[1], symbols, flags, &initProc,
+		&loadHandle);
+	Tcl_MutexUnlock(&packageMutex);
+	if (code != TCL_OK) {
+	    goto done;
+	}
+
+	/*
+	 * Create a new record to describe this package.
+	 */
+
+	pkgPtr = ckalloc(sizeof(LoadedPackage));
+	len = strlen(fullFileName) + 1;
+	pkgPtr->fileName	   = ckalloc(len);
+	memcpy(pkgPtr->fileName, fullFileName, len);
+	len = (unsigned) Tcl_DStringLength(&pkgName) + 1;
+	pkgPtr->packageName	   = ckalloc(len);
+	memcpy(pkgPtr->packageName, Tcl_DStringValue(&pkgName), len);
+	pkgPtr->loadHandle	   = loadHandle;
+	pkgPtr->initProc	   = initProc;
+	pkgPtr->safeInitProc	   = (Tcl_PackageInitProc *)
+		Tcl_FindSymbol(interp, loadHandle,
+			Tcl_DStringValue(&safeInitName));
+	pkgPtr->unloadProc	   = (Tcl_PackageUnloadProc *)
+		Tcl_FindSymbol(interp, loadHandle,
+			Tcl_DStringValue(&unloadName));
+	pkgPtr->safeUnloadProc	   = (Tcl_PackageUnloadProc *)
+		Tcl_FindSymbol(interp, loadHandle,
+			Tcl_DStringValue(&safeUnloadName));
+	pkgPtr->interpRefCount	   = 0;
+	pkgPtr->safeInterpRefCount = 0;
+
+	Tcl_MutexLock(&packageMutex);
+	pkgPtr->nextPtr		   = firstPackagePtr;
+	firstPackagePtr		   = pkgPtr;
+	Tcl_MutexUnlock(&packageMutex);
+
+	/*
+	 * The Tcl_FindSymbol calls may have left a spurious error message in
+	 * the interpreter result.
+	 */
+
+	Tcl_ResetResult(interp);
+    }
+
+    /*
+     * Invoke the package's initialization function (either the normal one or
+     * the safe one, depending on whether or not the interpreter is safe).
+     */
+
+    if (Tcl_IsSafe(target)) {
+	if (pkgPtr->safeInitProc == NULL) {
+	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		    "can't use package in a safe interpreter: no"
+		    " %s_SafeInit procedure", pkgPtr->packageName));
+	    Tcl_SetErrorCode(interp, "TCL", "OPERATION", "LOAD", "UNSAFE",
+		    NULL);
+	    code = TCL_ERROR;
+	    goto done;
+	}
+	code = pkgPtr->safeInitProc(target);
+    } else {
+	if (pkgPtr->initProc == NULL) {
+	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		    "can't attach package to interpreter: no %s_Init procedure",
+		    pkgPtr->packageName));
+	    Tcl_SetErrorCode(interp, "TCL", "OPERATION", "LOAD", "ENTRYPOINT",
+		    NULL);
+	    code = TCL_ERROR;
+	    goto done;
+	}
+	code = pkgPtr->initProc(target);
+    }
+
+    /*
+     * Test for whether the initialization failed. If so, transfer the error
+     * from the target interpreter to the originating one.
+     */
+
+    if (code != TCL_OK) {
+	Tcl_TransferResult(target, code, interp);
+	goto done;
+    }
+
+    /*
+     * Record the fact that the package has been loaded in the target
+     * interpreter.
+     *
+     * Update the proper reference count.
+     */
+
+    Tcl_MutexLock(&packageMutex);
+    if (Tcl_IsSafe(target)) {
+	pkgPtr->safeInterpRefCount++;
+    } else {
+	pkgPtr->interpRefCount++;
+    }
+    Tcl_MutexUnlock(&packageMutex);
+
+    /*
+     * Refetch ipFirstPtr: loading the package may have introduced additional
+     * static packages at the head of the linked list!
+     */
+
+    ipFirstPtr = Tcl_GetAssocData(target, "tclLoad", NULL);
+    ipPtr = ckalloc(sizeof(InterpPackage));
+    ipPtr->pkgPtr = pkgPtr;
+    ipPtr->nextPtr = ipFirstPtr;
+    Tcl_SetAssocData(target, "tclLoad", LoadCleanupProc, ipPtr);
+
+  done:
+    Tcl_DStringFree(&pkgName);
+    Tcl_DStringFree(&initName);
+    Tcl_DStringFree(&safeInitName);
+    Tcl_DStringFree(&unloadName);
+    Tcl_DStringFree(&safeUnloadName);
+    Tcl_DStringFree(&tmp);
+    return code;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_UnloadObjCmd --
+ *
+ *	This function is invoked to process the "unload" Tcl command. See the
+ *	user documentation for details on what it does.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_UnloadObjCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    Tcl_Interp *target;		/* Which interpreter to unload from. */
+    LoadedPackage *pkgPtr, *defaultPtr;
+    Tcl_DString pkgName, tmp;
+    Tcl_PackageUnloadProc *unloadProc;
+    InterpPackage *ipFirstPtr, *ipPtr;
+    int i, index, code, complain = 1, keepLibrary = 0;
+    int trustedRefCount = -1, safeRefCount = -1;
+    const char *fullFileName = "";
+    const char *packageName;
+    static const char *const options[] = {
+	"-nocomplain", "-keeplibrary", "--", NULL
+    };
+    enum options {
+	UNLOAD_NOCOMPLAIN, UNLOAD_KEEPLIB, UNLOAD_LAST
+    };
+
+    for (i = 1; i < objc; i++) {
+	if (Tcl_GetIndexFromObj(interp, objv[i], options, "option", 0,
+		&index) != TCL_OK) {
+	    fullFileName = Tcl_GetString(objv[i]);
+	    if (fullFileName[0] == '-') {
+		/*
+		 * It looks like the command contains an option so signal an
+		 * error
+		 */
+
+		return TCL_ERROR;
+	    } else {
+		/*
+		 * This clearly isn't an option; assume it's the filename. We
+		 * must clear the error.
+		 */
+
+		Tcl_ResetResult(interp);
+		break;
+	    }
+	}
+	switch (index) {
+	case UNLOAD_NOCOMPLAIN:		/* -nocomplain */
+	    complain = 0;
+	    break;
+	case UNLOAD_KEEPLIB:		/* -keeplibrary */
+	    keepLibrary = 1;
+	    break;
+	case UNLOAD_LAST:		/* -- */
+	    i++;
+	    goto endOfForLoop;
+	}
+    }
+  endOfForLoop:
+    if ((objc-i < 1) || (objc-i > 3)) {
+	Tcl_WrongNumArgs(interp, 1, objv,
+		"?-switch ...? fileName ?packageName? ?interp?");
+	return TCL_ERROR;
+    }
+    if (Tcl_FSConvertToPathType(interp, objv[i]) != TCL_OK) {
+	return TCL_ERROR;
+    }
+
+    fullFileName = Tcl_GetString(objv[i]);
+    Tcl_DStringInit(&pkgName);
+    Tcl_DStringInit(&tmp);
+
+    packageName = NULL;
+    if (objc - i >= 2) {
+	packageName = Tcl_GetString(objv[i+1]);
+	if (packageName[0] == '\0') {
+	    packageName = NULL;
+	}
+    }
+    if ((fullFileName[0] == 0) && (packageName == NULL)) {
+	Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		"must specify either file name or package name", -1));
+	Tcl_SetErrorCode(interp, "TCL", "OPERATION", "UNLOAD", "NOLIBRARY",
+		NULL);
+	code = TCL_ERROR;
+	goto done;
+    }
+
+    /*
+     * Figure out which interpreter we're going to load the package into.
+     */
+
+    target = interp;
+    if (objc - i == 3) {
+	const char *slaveIntName = Tcl_GetString(objv[i + 2]);
+
+	target = Tcl_GetSlave(interp, slaveIntName);
+	if (target == NULL) {
+	    return TCL_ERROR;
+	}
+    }
+
+    /*
+     * Scan through the packages that are currently loaded to see if the
+     * package we want is already loaded. We'll use a loaded package if it
+     * meets any of the following conditions:
+     *  - Its name and file match the once we're looking for.
+     *  - Its file matches, and we weren't given a name.
+     *  - Its name matches, the file name was specified as empty, and there is
+     *	  only no statically loaded package with the same name.
+     */
+
+    Tcl_MutexLock(&packageMutex);
+
+    defaultPtr = NULL;
+    for (pkgPtr = firstPackagePtr; pkgPtr != NULL; pkgPtr = pkgPtr->nextPtr) {
+	int namesMatch, filesMatch;
+
+	if (packageName == NULL) {
+	    namesMatch = 0;
+	} else {
+	    TclDStringClear(&pkgName);
+	    Tcl_DStringAppend(&pkgName, packageName, -1);
+	    TclDStringClear(&tmp);
+	    Tcl_DStringAppend(&tmp, pkgPtr->packageName, -1);
+	    Tcl_UtfToLower(Tcl_DStringValue(&pkgName));
+	    Tcl_UtfToLower(Tcl_DStringValue(&tmp));
+	    if (strcmp(Tcl_DStringValue(&tmp),
+		    Tcl_DStringValue(&pkgName)) == 0) {
+		namesMatch = 1;
+	    } else {
+		namesMatch = 0;
+	    }
+	}
+	TclDStringClear(&pkgName);
+
+	filesMatch = (strcmp(pkgPtr->fileName, fullFileName) == 0);
+	if (filesMatch && (namesMatch || (packageName == NULL))) {
+	    break;
+	}
+	if (namesMatch && (fullFileName[0] == 0)) {
+	    defaultPtr = pkgPtr;
+	}
+	if (filesMatch && !namesMatch && (fullFileName[0] != 0)) {
+	    break;
+	}
+    }
+    Tcl_MutexUnlock(&packageMutex);
+    if (fullFileName[0] == 0) {
+	/*
+	 * It's an error to try unload a static package.
+	 */
+
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		"package \"%s\" is loaded statically and cannot be unloaded",
+		packageName));
+	Tcl_SetErrorCode(interp, "TCL", "OPERATION", "UNLOAD", "STATIC",
+		NULL);
+	code = TCL_ERROR;
+	goto done;
+    }
+    if (pkgPtr == NULL) {
+	/*
+	 * The DLL pointed by the provided filename has never been loaded.
+	 */
+
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		"file \"%s\" has never been loaded", fullFileName));
+	Tcl_SetErrorCode(interp, "TCL", "OPERATION", "UNLOAD", "NEVERLOADED",
+		NULL);
+	code = TCL_ERROR;
+	goto done;
+    }
+
+    /*
+     * Scan through the list of packages already loaded in the target
+     * interpreter. If the package we want is already loaded there, then we
+     * should proceed with unloading.
+     */
+
+    code = TCL_ERROR;
+    if (pkgPtr != NULL) {
+	ipFirstPtr = Tcl_GetAssocData(target, "tclLoad", NULL);
+	for (ipPtr = ipFirstPtr; ipPtr != NULL; ipPtr = ipPtr->nextPtr) {
+	    if (ipPtr->pkgPtr == pkgPtr) {
+		code = TCL_OK;
+		break;
+	    }
+	}
+    }
+    if (code != TCL_OK) {
+	/*
+	 * The package has not been loaded in this interpreter.
+	 */
+
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		"file \"%s\" has never been loaded in this interpreter",
+		fullFileName));
+	Tcl_SetErrorCode(interp, "TCL", "OPERATION", "UNLOAD", "NEVERLOADED",
+		NULL);
+	code = TCL_ERROR;
+	goto done;
+    }
+
+    /*
+     * Ensure that the DLL can be unloaded. If it is a trusted interpreter,
+     * pkgPtr->unloadProc must not be NULL for the DLL to be unloadable. If
+     * the interpreter is a safe one, pkgPtr->safeUnloadProc must be non-NULL.
+     */
+
+    if (Tcl_IsSafe(target)) {
+	if (pkgPtr->safeUnloadProc == NULL) {
+	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		    "file \"%s\" cannot be unloaded under a safe interpreter",
+		    fullFileName));
+	    Tcl_SetErrorCode(interp, "TCL", "OPERATION", "UNLOAD", "CANNOT",
+		    NULL);
+	    code = TCL_ERROR;
+	    goto done;
+	}
+	unloadProc = pkgPtr->safeUnloadProc;
+    } else {
+	if (pkgPtr->unloadProc == NULL) {
+	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		    "file \"%s\" cannot be unloaded under a trusted interpreter",
+		    fullFileName));
+	    Tcl_SetErrorCode(interp, "TCL", "OPERATION", "UNLOAD", "CANNOT",
+		    NULL);
+	    code = TCL_ERROR;
+	    goto done;
+	}
+	unloadProc = pkgPtr->unloadProc;
+    }
+
+    /*
+     * We are ready to unload the package. First, evaluate the unload
+     * function. If this fails, we cannot proceed with unload. Also, we must
+     * specify the proper flag to pass to the unload callback.
+     * TCL_UNLOAD_DETACH_FROM_INTERPRETER is defined when the callback should
+     * only remove itself from the interpreter; the library will be unloaded
+     * in a future call of unload. In case the library will be unloaded just
+     * after the callback returns, TCL_UNLOAD_DETACH_FROM_PROCESS is passed.
+     */
+
+    code = TCL_UNLOAD_DETACH_FROM_INTERPRETER;
+    if (!keepLibrary) {
+	Tcl_MutexLock(&packageMutex);
+	trustedRefCount = pkgPtr->interpRefCount;
+	safeRefCount = pkgPtr->safeInterpRefCount;
+	Tcl_MutexUnlock(&packageMutex);
+
+	if (Tcl_IsSafe(target)) {
+	    safeRefCount--;
+	} else {
+	    trustedRefCount--;
+	}
+
+	if (safeRefCount <= 0 && trustedRefCount <= 0) {
+	    code = TCL_UNLOAD_DETACH_FROM_PROCESS;
+	}
+    }
+    code = unloadProc(target, code);
+    if (code != TCL_OK) {
+	Tcl_TransferResult(target, code, interp);
+	goto done;
+    }
+
+    /*
+     * The unload function executed fine. Examine the reference count to see
+     * if we unload the DLL.
+     */
+
+    Tcl_MutexLock(&packageMutex);
+    if (Tcl_IsSafe(target)) {
+	pkgPtr->safeInterpRefCount--;
+
+	/*
+	 * Do not let counter get negative.
+	 */
+
+	if (pkgPtr->safeInterpRefCount < 0) {
+	    pkgPtr->safeInterpRefCount = 0;
+	}
+    } else {
+	pkgPtr->interpRefCount--;
+
+	/*
+	 * Do not let counter get negative.
+	 */
+
+	if (pkgPtr->interpRefCount < 0) {
+	    pkgPtr->interpRefCount = 0;
+	}
+    }
+    trustedRefCount = pkgPtr->interpRefCount;
+    safeRefCount = pkgPtr->safeInterpRefCount;
+    Tcl_MutexUnlock(&packageMutex);
+
+    code = TCL_OK;
+    if (pkgPtr->safeInterpRefCount <= 0 && pkgPtr->interpRefCount <= 0
+	    && !keepLibrary) {
+	/*
+	 * Unload the shared library from the application memory...
+	 */
+
+#if defined(TCL_UNLOAD_DLLS) || defined(_WIN32)
+	/*
+	 * Some Unix dlls are poorly behaved - registering things like atexit
+	 * calls that can't be unregistered. If you unload such dlls, you get
+	 * a core on exit because it wants to call a function in the dll after
+	 * it's been unloaded.
+	 */
+
+	if (pkgPtr->fileName[0] != '\0') {
+	    Tcl_MutexLock(&packageMutex);
+	    if (Tcl_FSUnloadFile(interp, pkgPtr->loadHandle) == TCL_OK) {
+		/*
+		 * Remove this library from the loaded library cache.
+		 */
+
+		defaultPtr = pkgPtr;
+		if (defaultPtr == firstPackagePtr) {
+		    firstPackagePtr = pkgPtr->nextPtr;
+		} else {
+		    for (pkgPtr = firstPackagePtr; pkgPtr != NULL;
+			    pkgPtr = pkgPtr->nextPtr) {
+			if (pkgPtr->nextPtr == defaultPtr) {
+			    pkgPtr->nextPtr = defaultPtr->nextPtr;
+			    break;
+			}
+		    }
+		}
+
+		/*
+		 * Remove this library from the interpreter's library cache.
+		 */
+
+		ipFirstPtr = Tcl_GetAssocData(target, "tclLoad", NULL);
+		ipPtr = ipFirstPtr;
+		if (ipPtr->pkgPtr == defaultPtr) {
+		    ipFirstPtr = ipFirstPtr->nextPtr;
+		} else {
+		    InterpPackage *ipPrevPtr;
+
+		    for (ipPrevPtr = ipPtr; ipPtr != NULL;
+			    ipPrevPtr = ipPtr, ipPtr = ipPtr->nextPtr) {
+			if (ipPtr->pkgPtr == pkgPtr) {
+			    ipPrevPtr->nextPtr = ipPtr->nextPtr;
+			    break;
+			}
+		    }
+		}
+		Tcl_SetAssocData(target, "tclLoad", LoadCleanupProc,
+			ipFirstPtr);
+		ckfree(defaultPtr->fileName);
+		ckfree(defaultPtr->packageName);
+		ckfree(defaultPtr);
+		ckfree(ipPtr);
+		Tcl_MutexUnlock(&packageMutex);
+	    } else {
+		code = TCL_ERROR;
+	    }
+	}
+#else
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		"file \"%s\" cannot be unloaded: unloading disabled",
+		fullFileName));
+	Tcl_SetErrorCode(interp, "TCL", "OPERATION", "UNLOAD", "DISABLED",
+		NULL);
+	code = TCL_ERROR;
+#endif
+    }
+
+  done:
+    Tcl_DStringFree(&pkgName);
+    Tcl_DStringFree(&tmp);
+    if (!complain && (code != TCL_OK)) {
+	code = TCL_OK;
+	Tcl_ResetResult(interp);
+    }
+    return code;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_StaticPackage --
+ *
+ *	This function is invoked to indicate that a particular package has
+ *	been linked statically with an application.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Once this function completes, the package becomes loadable via the
+ *	"load" command with an empty file name.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_StaticPackage(
+    Tcl_Interp *interp,		/* If not NULL, it means that the package has
+				 * already been loaded into the given
+				 * interpreter by calling the appropriate init
+				 * proc. */
+    const char *pkgName,	/* Name of package (must be properly
+				 * capitalized: first letter upper case,
+				 * others lower case). */
+    Tcl_PackageInitProc *initProc,
+				/* Function to call to incorporate this
+				 * package into a trusted interpreter. */
+    Tcl_PackageInitProc *safeInitProc)
+				/* Function to call to incorporate this
+				 * package into a safe interpreter (one that
+				 * will execute untrusted scripts). NULL means
+				 * the package can't be used in safe
+				 * interpreters. */
+{
+    LoadedPackage *pkgPtr;
+    InterpPackage *ipPtr, *ipFirstPtr;
+
+    /*
+     * Check to see if someone else has already reported this package as
+     * statically loaded in the process.
+     */
+
+    Tcl_MutexLock(&packageMutex);
+    for (pkgPtr = firstPackagePtr; pkgPtr != NULL; pkgPtr = pkgPtr->nextPtr) {
+	if ((pkgPtr->initProc == initProc)
+		&& (pkgPtr->safeInitProc == safeInitProc)
+		&& (strcmp(pkgPtr->packageName, pkgName) == 0)) {
+	    break;
+	}
+    }
+    Tcl_MutexUnlock(&packageMutex);
+
+    /*
+     * If the package is not yet recorded as being loaded statically, add it
+     * to the list now.
+     */
+
+    if (pkgPtr == NULL) {
+	pkgPtr = ckalloc(sizeof(LoadedPackage));
+	pkgPtr->fileName	= ckalloc(1);
+	pkgPtr->fileName[0]	= 0;
+	pkgPtr->packageName	= ckalloc(strlen(pkgName) + 1);
+	strcpy(pkgPtr->packageName, pkgName);
+	pkgPtr->loadHandle	= NULL;
+	pkgPtr->initProc	= initProc;
+	pkgPtr->safeInitProc	= safeInitProc;
+	Tcl_MutexLock(&packageMutex);
+	pkgPtr->nextPtr		= firstPackagePtr;
+	firstPackagePtr		= pkgPtr;
+	Tcl_MutexUnlock(&packageMutex);
+    }
+
+    if (interp != NULL) {
+
+	/*
+	 * If we're loading the package into an interpreter, determine whether
+	 * it's already loaded.
+	 */
+
+	ipFirstPtr = Tcl_GetAssocData(interp, "tclLoad", NULL);
+	for (ipPtr = ipFirstPtr; ipPtr != NULL; ipPtr = ipPtr->nextPtr) {
+	    if (ipPtr->pkgPtr == pkgPtr) {
+		return;
+	    }
+	}
+
+	/*
+	 * Package isn't loade in the current interp yet. Mark it as now being
+	 * loaded.
+	 */
+
+	ipPtr = ckalloc(sizeof(InterpPackage));
+	ipPtr->pkgPtr = pkgPtr;
+	ipPtr->nextPtr = ipFirstPtr;
+	Tcl_SetAssocData(interp, "tclLoad", LoadCleanupProc, ipPtr);
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclGetLoadedPackages --
+ *
+ *	This function returns information about all of the files that are
+ *	loaded (either in a particular intepreter, or for all interpreters).
+ *
+ * Results:
+ *	The return value is a standard Tcl completion code. If successful, a
+ *	list of lists is placed in the interp's result. Each sublist
+ *	corresponds to one loaded file; its first element is the name of the
+ *	file (or an empty string for something that's statically loaded) and
+ *	the second element is the name of the package in that file.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclGetLoadedPackages(
+    Tcl_Interp *interp,		/* Interpreter in which to return information
+				 * or error message. */
+    const char *targetName)	/* Name of target interpreter or NULL. If
+				 * NULL, return info about all interps;
+				 * otherwise, just return info about this
+				 * interpreter. */
+{
+    Tcl_Interp *target;
+    LoadedPackage *pkgPtr;
+    InterpPackage *ipPtr;
+    Tcl_Obj *resultObj, *pkgDesc[2];
+
+    if (targetName == NULL) {
+	/*
+	 * Return information about all of the available packages.
+	 */
+
+	resultObj = Tcl_NewObj();
+	Tcl_MutexLock(&packageMutex);
+	for (pkgPtr = firstPackagePtr; pkgPtr != NULL;
+		pkgPtr = pkgPtr->nextPtr) {
+	    pkgDesc[0] = Tcl_NewStringObj(pkgPtr->fileName, -1);
+	    pkgDesc[1] = Tcl_NewStringObj(pkgPtr->packageName, -1);
+	    Tcl_ListObjAppendElement(NULL, resultObj,
+		    Tcl_NewListObj(2, pkgDesc));
+	}
+	Tcl_MutexUnlock(&packageMutex);
+	Tcl_SetObjResult(interp, resultObj);
+	return TCL_OK;
+    }
+
+    /*
+     * Return information about only the packages that are loaded in a given
+     * interpreter.
+     */
+
+    target = Tcl_GetSlave(interp, targetName);
+    if (target == NULL) {
+	return TCL_ERROR;
+    }
+    ipPtr = Tcl_GetAssocData(target, "tclLoad", NULL);
+    resultObj = Tcl_NewObj();
+    for (; ipPtr != NULL; ipPtr = ipPtr->nextPtr) {
+	pkgPtr = ipPtr->pkgPtr;
+	pkgDesc[0] = Tcl_NewStringObj(pkgPtr->fileName, -1);
+	pkgDesc[1] = Tcl_NewStringObj(pkgPtr->packageName, -1);
+	Tcl_ListObjAppendElement(NULL, resultObj, Tcl_NewListObj(2, pkgDesc));
+    }
+    Tcl_SetObjResult(interp, resultObj);
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * LoadCleanupProc --
+ *
+ *	This function is called to delete all of the InterpPackage structures
+ *	for an interpreter when the interpreter is deleted. It gets invoked
+ *	via the Tcl AssocData mechanism.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Storage for all of the InterpPackage functions for interp get deleted.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+LoadCleanupProc(
+    ClientData clientData,	/* Pointer to first InterpPackage structure
+				 * for interp. */
+    Tcl_Interp *interp)		/* Interpreter that is being deleted. */
+{
+    InterpPackage *ipPtr, *nextPtr;
+
+    ipPtr = clientData;
+    while (ipPtr != NULL) {
+	nextPtr = ipPtr->nextPtr;
+	ckfree(ipPtr);
+	ipPtr = nextPtr;
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclFinalizeLoad --
+ *
+ *	This function is invoked just before the application exits. It frees
+ *	all of the LoadedPackage structures.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Memory is freed.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclFinalizeLoad(void)
+{
+    LoadedPackage *pkgPtr;
+
+    /*
+     * No synchronization here because there should just be one thread alive
+     * at this point. Logically, packageMutex should be grabbed at this point,
+     * but the Mutexes get finalized before the call to this routine. The only
+     * subsystem left alive at this point is the memory allocator.
+     */
+
+    while (firstPackagePtr != NULL) {
+	pkgPtr = firstPackagePtr;
+	firstPackagePtr = pkgPtr->nextPtr;
+
+#if defined(TCL_UNLOAD_DLLS) || defined(_WIN32)
+	/*
+	 * Some Unix dlls are poorly behaved - registering things like atexit
+	 * calls that can't be unregistered. If you unload such dlls, you get
+	 * a core on exit because it wants to call a function in the dll after
+	 * it has been unloaded.
+	 */
+
+	if (pkgPtr->fileName[0] != '\0') {
+	    Tcl_FSUnloadFile(NULL, pkgPtr->loadHandle);
+	}
+#endif
+
+	ckfree(pkgPtr->fileName);
+	ckfree(pkgPtr->packageName);
+	ckfree(pkgPtr);
+    }
+}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tclLoadNone.c b/generic/tclLoadNone.c
new file mode 100644
index 0000000..6af5c4f
--- /dev/null
+++ b/generic/tclLoadNone.c
@@ -0,0 +1,129 @@
+/*
+ * tclLoadNone.c --
+ *
+ *	This procedure provides a version of the TclpDlopen for use in
+ *	systems that don't support dynamic loading; it just returns an error.
+ *
+ * Copyright (c) 1995-1997 Sun Microsystems, Inc.
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#include "tclInt.h"
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclpDlopen --
+ *
+ *	This procedure is called to carry out dynamic loading of binary code;
+ *	it is intended for use only on systems that don't support dynamic
+ *	loading (it returns an error).
+ *
+ * Results:
+ *	The result is TCL_ERROR, and an error message is left in the interp's
+ *	result.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclpDlopen(
+    Tcl_Interp *interp,		/* Used for error reporting. */
+    Tcl_Obj *pathPtr,		/* Name of the file containing the desired
+				 * code (UTF-8). */
+    Tcl_LoadHandle *loadHandle,	/* Filled with token for dynamically loaded
+				 * file which will be passed back to
+				 * (*unloadProcPtr)() to unload the file. */
+    Tcl_FSUnloadFileProc **unloadProcPtr,
+				/* Filled with address of Tcl_FSUnloadFileProc
+				 * function which should be used for this
+				 * file. */
+    int flags)
+{
+    if (interp) {
+	Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		"dynamic loading is not currently available on this system",
+		-1));
+    }
+    return TCL_ERROR;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclGuessPackageName --
+ *
+ *	If the "load" command is invoked without providing a package name,
+ *	this procedure is invoked to try to figure it out.
+ *
+ * Results:
+ *	Always returns 0 to indicate that we couldn't figure out a package
+ *	name; generic code will then try to guess the package from the file
+ *	name. A return value of 1 would have meant that we figured out the
+ *	package name and put it in bufPtr.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclGuessPackageName(
+    const char *fileName,	/* Name of file containing package (already
+				 * translated to local form if needed). */
+    Tcl_DString *bufPtr)	/* Initialized empty dstring. Append package
+				 * name to this if possible. */
+{
+    return 0;
+}
+
+/*
+ * These functions are fallbacks if we somehow determine that the platform can
+ * do loading from memory but the user wishes to disable it. They just report
+ * (gracefully) that they fail.
+ */
+
+#ifdef TCL_LOAD_FROM_MEMORY
+
+MODULE_SCOPE void *
+TclpLoadMemoryGetBuffer(
+    Tcl_Interp *interp,		/* Dummy: unused by this implementation */
+    int size)			/* Dummy: unused by this implementation */
+{
+    return NULL;
+}
+
+MODULE_SCOPE int
+TclpLoadMemory(
+    Tcl_Interp *interp,		/* Used for error reporting. */
+    void *buffer,		/* Dummy: unused by this implementation */
+    int size,			/* Dummy: unused by this implementation */
+    int codeSize,		/* Dummy: unused by this implementation */
+    Tcl_LoadHandle *loadHandle,	/* Dummy: unused by this implementation */
+    Tcl_FSUnloadFileProc **unloadProcPtr,
+				/* Dummy: unused by this implementation */
+    int flags)
+				/* Dummy: unused by this implementation */
+{
+    if (interp) {
+	Tcl_SetObjResult(interp, Tcl_NewStringObj("dynamic loading from memory "
+		"is not available on this system", -1));
+    }
+    return TCL_ERROR;
+}
+
+#endif /* TCL_LOAD_FROM_MEMORY */
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tclMain.c b/generic/tclMain.c
new file mode 100644
index 0000000..927de7e
--- /dev/null
+++ b/generic/tclMain.c
@@ -0,0 +1,961 @@
+/*
+ * tclMain.c --
+ *
+ *	Main program for Tcl shells and other Tcl-based applications.
+ *	This file contains a generic main program for Tcl shells and other
+ *	Tcl-based applications. It can be used as-is for many applications,
+ *	just by supplying a different appInitProc function for each specific
+ *	application. Or, it can be used as a template for creating new main
+ *	programs for Tcl applications.
+ *
+ * Copyright (c) 1988-1994 The Regents of the University of California.
+ * Copyright (c) 1994-1997 Sun Microsystems, Inc.
+ * Copyright (c) 2000 Ajuba Solutions.
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+/*
+ * On Windows, this file needs to be compiled twice, once with TCL_ASCII_MAIN
+ * defined. This way both Tcl_Main and Tcl_MainExW can be implemented, sharing
+ * the same source code.
+ */
+
+#if defined(TCL_ASCII_MAIN)
+#   ifdef UNICODE
+#	undef UNICODE
+#	undef _UNICODE
+#   else
+#	define UNICODE
+#	define _UNICODE
+#   endif
+#endif
+
+#include "tclInt.h"
+
+/*
+ * The default prompt used when the user has not overridden it.
+ */
+
+#define DEFAULT_PRIMARY_PROMPT	"% "
+
+/*
+ * This file can be compiled on Windows in UNICODE mode, as well as on all
+ * other platforms using the native encoding. This is done by using the normal
+ * Windows functions like _tcscmp, but on platforms which don't have <tchar.h>
+ * we have to translate that to strcmp here.
+ */
+
+#ifndef _WIN32
+#   define TCHAR char
+#   define TEXT(arg) arg
+#   define _tcscmp strcmp
+#endif
+
+/*
+ * Further on, in UNICODE mode we just use Tcl_NewUnicodeObj, otherwise
+ * NewNativeObj is needed (which provides proper conversion from native
+ * encoding to UTF-8).
+ */
+
+#ifdef UNICODE
+#   define NewNativeObj Tcl_NewUnicodeObj
+#else /* !UNICODE */
+static inline Tcl_Obj *
+NewNativeObj(
+    char *string,
+    int length)
+{
+    Tcl_DString ds;
+
+    Tcl_ExternalToUtfDString(NULL, string, length, &ds);
+    return TclDStringToObj(&ds);
+}
+#endif /* !UNICODE */
+
+/*
+ * Declarations for various library functions and variables (don't want to
+ * include tclPort.h here, because people might copy this file out of the Tcl
+ * source directory to make their own modified versions).
+ */
+
+#if defined _MSC_VER && _MSC_VER < 1900
+/* isatty is always defined on MSVC 14.0, but not necessarily as CRTIMPORT. */
+extern CRTIMPORT int	isatty(int fd);
+#endif
+
+/*
+ * The thread-local variables for this file's functions.
+ */
+
+typedef struct {
+    Tcl_Obj *path;		/* The filename of the script for *_Main()
+				 * routines to [source] as a startup script,
+				 * or NULL for none set, meaning enter
+				 * interactive mode. */
+    Tcl_Obj *encoding;		/* The encoding of the startup script file. */
+    Tcl_MainLoopProc *mainLoopProc;
+				/* Any installed main loop handler. The main
+				 * extension that installs these is Tk. */
+} ThreadSpecificData;
+
+/*
+ * Structure definition for information used to keep the state of an
+ * interactive command processor that reads lines from standard input and
+ * writes prompts and results to standard output.
+ */
+
+typedef enum {
+    PROMPT_NONE,		/* Print no prompt */
+    PROMPT_START,		/* Print prompt for command start */
+    PROMPT_CONTINUE		/* Print prompt for command continuation */
+} PromptType;
+
+typedef struct InteractiveState {
+    Tcl_Channel input;		/* The standard input channel from which lines
+				 * are read. */
+    int tty;			/* Non-zero means standard input is a
+				 * terminal-like device. Zero means it's a
+				 * file. */
+    Tcl_Obj *commandPtr;	/* Used to assemble lines of input into Tcl
+				 * commands. */
+    PromptType prompt;		/* Next prompt to print */
+    Tcl_Interp *interp;		/* Interpreter that evaluates interactive
+				 * commands. */
+} InteractiveState;
+
+/*
+ * Forward declarations for functions defined later in this file.
+ */
+
+MODULE_SCOPE Tcl_MainLoopProc *TclGetMainLoop(void);
+static void		Prompt(Tcl_Interp *interp, InteractiveState *isPtr);
+static void		StdinProc(ClientData clientData, int mask);
+static void		FreeMainInterp(ClientData clientData);
+
+#ifndef TCL_ASCII_MAIN
+static Tcl_ThreadDataKey dataKey;
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_SetStartupScript --
+ *
+ *	Sets the path and encoding of the startup script to be evaluated by
+ *	Tcl_Main, used to override the command line processing.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_SetStartupScript(
+    Tcl_Obj *path,		/* Filesystem path of startup script file */
+    const char *encoding)	/* Encoding of the data in that file */
+{
+    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+    Tcl_Obj *newEncoding = NULL;
+
+    if (encoding != NULL) {
+	newEncoding = Tcl_NewStringObj(encoding, -1);
+    }
+
+    if (tsdPtr->path != NULL) {
+	Tcl_DecrRefCount(tsdPtr->path);
+    }
+    tsdPtr->path = path;
+    if (tsdPtr->path != NULL) {
+	Tcl_IncrRefCount(tsdPtr->path);
+    }
+
+    if (tsdPtr->encoding != NULL) {
+	Tcl_DecrRefCount(tsdPtr->encoding);
+    }
+    tsdPtr->encoding = newEncoding;
+    if (tsdPtr->encoding != NULL) {
+	Tcl_IncrRefCount(tsdPtr->encoding);
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_GetStartupScript --
+ *
+ *	Gets the path and encoding of the startup script to be evaluated by
+ *	Tcl_Main.
+ *
+ * Results:
+ *	The path of the startup script; NULL if none has been set.
+ *
+ * Side effects:
+ *	If encodingPtr is not NULL, stores a (const char *) in it pointing to
+ *	the encoding name registered for the startup script. Tcl retains
+ *	ownership of the string, and may free it. Caller should make a copy
+ *	for long-term use.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_Obj *
+Tcl_GetStartupScript(
+    const char **encodingPtr)	/* When not NULL, points to storage for the
+				 * (const char *) that points to the
+				 * registered encoding name for the startup
+				 * script. */
+{
+    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+
+    if (encodingPtr != NULL) {
+	if (tsdPtr->encoding == NULL) {
+	    *encodingPtr = NULL;
+	} else {
+	    *encodingPtr = Tcl_GetString(tsdPtr->encoding);
+	}
+    }
+    return tsdPtr->path;
+}
+
+/*----------------------------------------------------------------------
+ *
+ * Tcl_SourceRCFile --
+ *
+ *	This function is typically invoked by Tcl_Main of Tk_Main function to
+ *	source an application specific rc file into the interpreter at startup
+ *	time.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Depends on what's in the rc script.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_SourceRCFile(
+    Tcl_Interp *interp)		/* Interpreter to source rc file into. */
+{
+    Tcl_DString temp;
+    const char *fileName;
+    Tcl_Channel chan;
+
+    fileName = Tcl_GetVar(interp, "tcl_rcFileName", TCL_GLOBAL_ONLY);
+    if (fileName != NULL) {
+	Tcl_Channel c;
+	const char *fullName;
+
+	Tcl_DStringInit(&temp);
+	fullName = Tcl_TranslateFileName(interp, fileName, &temp);
+	if (fullName == NULL) {
+	    /*
+	     * Couldn't translate the file name (e.g. it referred to a bogus
+	     * user or there was no HOME environment variable). Just do
+	     * nothing.
+	     */
+	} else {
+	    /*
+	     * Test for the existence of the rc file before trying to read it.
+	     */
+
+	    c = Tcl_OpenFileChannel(NULL, fullName, "r", 0);
+	    if (c != NULL) {
+		Tcl_Close(NULL, c);
+		if (Tcl_EvalFile(interp, fullName) != TCL_OK) {
+		    chan = Tcl_GetStdChannel(TCL_STDERR);
+		    if (chan) {
+			Tcl_WriteObj(chan, Tcl_GetObjResult(interp));
+			Tcl_WriteChars(chan, "\n", 1);
+		    }
+		}
+	    }
+	}
+	Tcl_DStringFree(&temp);
+    }
+}
+#endif /* !TCL_ASCII_MAIN */
+
+/*----------------------------------------------------------------------
+ *
+ * Tcl_Main, Tcl_MainEx --
+ *
+ *	Main program for tclsh and most other Tcl-based applications.
+ *
+ * Results:
+ *	None. This function never returns (it exits the process when it's
+ *	done).
+ *
+ * Side effects:
+ *	This function initializes the Tcl world and then starts interpreting
+ *	commands; almost anything could happen, depending on the script being
+ *	interpreted.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_MainEx(
+    int argc,			/* Number of arguments. */
+    TCHAR **argv,		/* Array of argument strings. */
+    Tcl_AppInitProc *appInitProc,
+				/* Application-specific initialization
+				 * function to call after most initialization
+				 * but before starting to execute commands. */
+    Tcl_Interp *interp)
+{
+    Tcl_Obj *path, *resultPtr, *argvPtr, *appName;
+    const char *encodingName = NULL;
+    int code, exitCode = 0;
+    Tcl_MainLoopProc *mainLoopProc;
+    Tcl_Channel chan;
+    InteractiveState is;
+
+    TclpSetInitialEncodings();
+    TclpFindExecutable((const char *)argv[0]);
+
+    Tcl_InitMemory(interp);
+
+    is.interp = interp;
+    is.prompt = PROMPT_START;
+    is.commandPtr = Tcl_NewObj();
+
+    /*
+     * If the application has not already set a startup script, parse the
+     * first few command line arguments to determine the script path and
+     * encoding.
+     */
+
+    if (NULL == Tcl_GetStartupScript(NULL)) {
+	/*
+	 * Check whether first 3 args (argv[1] - argv[3]) look like
+	 *  -encoding ENCODING FILENAME
+	 * or like
+	 *  FILENAME
+	 */
+
+	if ((argc > 3) && (0 == _tcscmp(TEXT("-encoding"), argv[1]))
+		&& ('-' != argv[3][0])) {
+	    Tcl_Obj *value = NewNativeObj(argv[2], -1);
+	    Tcl_SetStartupScript(NewNativeObj(argv[3], -1),
+		    Tcl_GetString(value));
+	    Tcl_DecrRefCount(value);
+	    argc -= 3;
+	    argv += 3;
+	} else if ((argc > 1) && ('-' != argv[1][0])) {
+	    Tcl_SetStartupScript(NewNativeObj(argv[1], -1), NULL);
+	    argc--;
+	    argv++;
+	}
+    }
+
+    path = Tcl_GetStartupScript(&encodingName);
+    if (path == NULL) {
+	appName = NewNativeObj(argv[0], -1);
+    } else {
+	appName = path;
+    }
+    Tcl_SetVar2Ex(interp, "argv0", NULL, appName, TCL_GLOBAL_ONLY);
+    argc--;
+    argv++;
+
+    Tcl_SetVar2Ex(interp, "argc", NULL, Tcl_NewIntObj(argc), TCL_GLOBAL_ONLY);
+
+    argvPtr = Tcl_NewListObj(0, NULL);
+    while (argc--) {
+	Tcl_ListObjAppendElement(NULL, argvPtr, NewNativeObj(*argv++, -1));
+    }
+    Tcl_SetVar2Ex(interp, "argv", NULL, argvPtr, TCL_GLOBAL_ONLY);
+
+    /*
+     * Set the "tcl_interactive" variable.
+     */
+
+    is.tty = isatty(0);
+    Tcl_SetVar2Ex(interp, "tcl_interactive", NULL,
+	    Tcl_NewIntObj(!path && is.tty), TCL_GLOBAL_ONLY);
+
+    /*
+     * Invoke application-specific initialization.
+     */
+
+    Tcl_Preserve(interp);
+    if (appInitProc(interp) != TCL_OK) {
+	chan = Tcl_GetStdChannel(TCL_STDERR);
+	if (chan) {
+	    Tcl_WriteChars(chan,
+		    "application-specific initialization failed: ", -1);
+	    Tcl_WriteObj(chan, Tcl_GetObjResult(interp));
+	    Tcl_WriteChars(chan, "\n", 1);
+	}
+    }
+    if (Tcl_InterpDeleted(interp)) {
+	goto done;
+    }
+    if (Tcl_LimitExceeded(interp)) {
+	goto done;
+    }
+    if (TclFullFinalizationRequested()) {
+	/*
+	 * Arrange for final deletion of the main interp
+	 */
+
+	/* ARGH Munchhausen effect */
+	Tcl_CreateExitHandler(FreeMainInterp, interp);
+    }
+
+    /*
+     * Invoke the script specified on the command line, if any. Must fetch it
+     * again, as the appInitProc might have reset it.
+     */
+
+    path = Tcl_GetStartupScript(&encodingName);
+    if (path != NULL) {
+	Tcl_ResetResult(interp);
+	code = Tcl_FSEvalFileEx(interp, path, encodingName);
+	if (code != TCL_OK) {
+	    chan = Tcl_GetStdChannel(TCL_STDERR);
+	    if (chan) {
+		Tcl_Obj *options = Tcl_GetReturnOptions(interp, code);
+		Tcl_Obj *keyPtr, *valuePtr;
+
+		TclNewLiteralStringObj(keyPtr, "-errorinfo");
+		Tcl_IncrRefCount(keyPtr);
+		Tcl_DictObjGet(NULL, options, keyPtr, &valuePtr);
+		Tcl_DecrRefCount(keyPtr);
+
+		if (valuePtr) {
+		    Tcl_WriteObj(chan, valuePtr);
+		}
+		Tcl_WriteChars(chan, "\n", 1);
+		Tcl_DecrRefCount(options);
+	    }
+	    exitCode = 1;
+	}
+	goto done;
+    }
+
+    /*
+     * We're running interactively. Source a user-specific startup file if the
+     * application specified one and if the file exists.
+     */
+
+    Tcl_SourceRCFile(interp);
+    if (Tcl_LimitExceeded(interp)) {
+	goto done;
+    }
+
+    /*
+     * Process commands from stdin until there's an end-of-file. Note that we
+     * need to fetch the standard channels again after every eval, since they
+     * may have been changed.
+     */
+
+    Tcl_IncrRefCount(is.commandPtr);
+
+    /*
+     * Get a new value for tty if anyone writes to ::tcl_interactive
+     */
+
+    Tcl_LinkVar(interp, "tcl_interactive", (char *) &is.tty, TCL_LINK_BOOLEAN);
+    is.input = Tcl_GetStdChannel(TCL_STDIN);
+    while ((is.input != NULL) && !Tcl_InterpDeleted(interp)) {
+	mainLoopProc = TclGetMainLoop();
+	if (mainLoopProc == NULL) {
+	    int length;
+
+	    if (is.tty) {
+		Prompt(interp, &is);
+		if (Tcl_InterpDeleted(interp)) {
+		    break;
+		}
+		if (Tcl_LimitExceeded(interp)) {
+		    break;
+		}
+		is.input = Tcl_GetStdChannel(TCL_STDIN);
+		if (is.input == NULL) {
+		    break;
+		}
+	    }
+	    if (Tcl_IsShared(is.commandPtr)) {
+		Tcl_DecrRefCount(is.commandPtr);
+		is.commandPtr = Tcl_DuplicateObj(is.commandPtr);
+		Tcl_IncrRefCount(is.commandPtr);
+	    }
+	    length = Tcl_GetsObj(is.input, is.commandPtr);
+	    if (length < 0) {
+		if (Tcl_InputBlocked(is.input)) {
+		    /*
+		     * This can only happen if stdin has been set to
+		     * non-blocking. In that case cycle back and try again.
+		     * This sets up a tight polling loop (since we have no
+		     * event loop running). If this causes bad CPU hogging, we
+		     * might try toggling the blocking on stdin instead.
+		     */
+
+		    continue;
+		}
+
+		/*
+		 * Either EOF, or an error on stdin; we're done
+		 */
+
+		break;
+	    }
+
+	    /*
+	     * Add the newline removed by Tcl_GetsObj back to the string. Have
+	     * to add it back before testing completeness, because it can make
+	     * a difference. [Bug 1775878]
+	     */
+
+	    if (Tcl_IsShared(is.commandPtr)) {
+		Tcl_DecrRefCount(is.commandPtr);
+		is.commandPtr = Tcl_DuplicateObj(is.commandPtr);
+		Tcl_IncrRefCount(is.commandPtr);
+	    }
+	    Tcl_AppendToObj(is.commandPtr, "\n", 1);
+	    if (!TclObjCommandComplete(is.commandPtr)) {
+		is.prompt = PROMPT_CONTINUE;
+		continue;
+	    }
+
+	    is.prompt = PROMPT_START;
+
+	    /*
+	     * The final newline is syntactically redundant, and causes some
+	     * error messages troubles deeper in, so lop it back off.
+	     */
+
+	    Tcl_GetStringFromObj(is.commandPtr, &length);
+	    Tcl_SetObjLength(is.commandPtr, --length);
+	    code = Tcl_RecordAndEvalObj(interp, is.commandPtr,
+		    TCL_EVAL_GLOBAL);
+	    is.input = Tcl_GetStdChannel(TCL_STDIN);
+	    Tcl_DecrRefCount(is.commandPtr);
+	    is.commandPtr = Tcl_NewObj();
+	    Tcl_IncrRefCount(is.commandPtr);
+	    if (code != TCL_OK) {
+		chan = Tcl_GetStdChannel(TCL_STDERR);
+		if (chan) {
+		    Tcl_WriteObj(chan, Tcl_GetObjResult(interp));
+		    Tcl_WriteChars(chan, "\n", 1);
+		}
+	    } else if (is.tty) {
+		resultPtr = Tcl_GetObjResult(interp);
+		Tcl_IncrRefCount(resultPtr);
+		Tcl_GetStringFromObj(resultPtr, &length);
+		chan = Tcl_GetStdChannel(TCL_STDOUT);
+		if ((length > 0) && chan) {
+		    Tcl_WriteObj(chan, resultPtr);
+		    Tcl_WriteChars(chan, "\n", 1);
+		}
+		Tcl_DecrRefCount(resultPtr);
+	    }
+	} else {	/* (mainLoopProc != NULL) */
+	    /*
+	     * If a main loop has been defined while running interactively, we
+	     * want to start a fileevent based prompt by establishing a
+	     * channel handler for stdin.
+	     */
+
+	    if (is.input) {
+		if (is.tty) {
+		    Prompt(interp, &is);
+		}
+
+		Tcl_CreateChannelHandler(is.input, TCL_READABLE,
+			StdinProc, &is);
+	    }
+
+	    mainLoopProc();
+	    Tcl_SetMainLoop(NULL);
+
+	    if (is.input) {
+		Tcl_DeleteChannelHandler(is.input, StdinProc, &is);
+	    }
+	    is.input = Tcl_GetStdChannel(TCL_STDIN);
+	}
+
+	/*
+	 * This code here only for the (unsupported and deprecated) [checkmem]
+	 * command.
+	 */
+
+#ifdef TCL_MEM_DEBUG
+	if (tclMemDumpFileName != NULL) {
+	    Tcl_SetMainLoop(NULL);
+	    Tcl_DeleteInterp(interp);
+	}
+#endif /* TCL_MEM_DEBUG */
+    }
+
+  done:
+    mainLoopProc = TclGetMainLoop();
+    if ((exitCode == 0) && mainLoopProc && !Tcl_LimitExceeded(interp)) {
+	/*
+	 * If everything has gone OK so far, call the main loop proc, if it
+	 * exists. Packages (like Tk) can set it to start processing events at
+	 * this point.
+	 */
+
+	mainLoopProc();
+	Tcl_SetMainLoop(NULL);
+    }
+    if (is.commandPtr != NULL) {
+	Tcl_DecrRefCount(is.commandPtr);
+    }
+
+    /*
+     * Rather than calling exit, invoke the "exit" command so that users can
+     * replace "exit" with some other command to do additional cleanup on
+     * exit. The Tcl_EvalObjEx call should never return.
+     */
+
+    if (!Tcl_InterpDeleted(interp) && !Tcl_LimitExceeded(interp)) {
+	Tcl_Obj *cmd = Tcl_ObjPrintf("exit %d", exitCode);
+
+	Tcl_IncrRefCount(cmd);
+	Tcl_EvalObjEx(interp, cmd, TCL_EVAL_GLOBAL);
+	Tcl_DecrRefCount(cmd);
+    }
+
+    /*
+     * If Tcl_EvalObjEx returns, trying to eval [exit], something unusual is
+     * happening. Maybe interp has been deleted; maybe [exit] was redefined,
+     * maybe we've blown up because of an exceeded limit. We still want to
+     * cleanup and exit.
+     */
+
+    Tcl_Exit(exitCode);
+}
+
+#if (TCL_MAJOR_VERSION == 8) && !defined(UNICODE)
+#undef Tcl_Main
+extern DLLEXPORT void
+Tcl_Main(
+    int argc,			/* Number of arguments. */
+    char **argv,		/* Array of argument strings. */
+    Tcl_AppInitProc *appInitProc)
+				/* Application-specific initialization
+				 * function to call after most initialization
+				 * but before starting to execute commands. */
+{
+    Tcl_MainEx(argc, argv, appInitProc, Tcl_CreateInterp());
+}
+#endif /* TCL_MAJOR_VERSION == 8 && !UNICODE */
+
+#ifndef TCL_ASCII_MAIN
+
+/*
+ *---------------------------------------------------------------
+ *
+ * Tcl_SetMainLoop --
+ *
+ *	Sets an alternative main loop function.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	This function will be called before Tcl exits, allowing for the
+ *	creation of an event loop.
+ *
+ *---------------------------------------------------------------
+ */
+
+void
+Tcl_SetMainLoop(
+    Tcl_MainLoopProc *proc)
+{
+    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+
+    tsdPtr->mainLoopProc = proc;
+}
+
+/*
+ *---------------------------------------------------------------
+ *
+ * TclGetMainLoop --
+ *
+ *	Returns the current alternative main loop function.
+ *
+ * Results:
+ *	Returns the previously defined main loop function, or NULL to indicate
+ *	that no such function has been installed and standard tclsh behaviour
+ *	(i.e., exit once the script is evaluated if not interactive) is
+ *	requested..
+ *
+ * Side effects:
+ *	None (other than possible creation of this file's TSD block).
+ *
+ *---------------------------------------------------------------
+ */
+
+Tcl_MainLoopProc *
+TclGetMainLoop(void)
+{
+    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+
+    return tsdPtr->mainLoopProc;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclFullFinalizationRequested --
+ *
+ *	This function returns true when either -DPURIFY is specified, or the
+ *	environment variable TCL_FINALIZE_ON_EXIT is set and not "0". This
+ *	predicate is called at places affecting the exit sequence, so that the
+ *	default behavior is a fast and deadlock-free exit, and the modified
+ *	behavior is a more thorough finalization for debugging purposes (leak
+ *	hunting etc).
+ *
+ * Results:
+ *	A boolean.
+ *
+ *----------------------------------------------------------------------
+ */
+
+MODULE_SCOPE int
+TclFullFinalizationRequested(void)
+{
+#ifdef PURIFY
+    return 1;
+#else
+    const char *fin;
+    Tcl_DString ds;
+    int finalize = 0;
+
+    fin = TclGetEnv("TCL_FINALIZE_ON_EXIT", &ds);
+    finalize = ((fin != NULL) && strcmp(fin, "0"));
+    if (fin != NULL) {
+	Tcl_DStringFree(&ds);
+    }
+    return finalize;
+#endif /* PURIFY */
+}
+#endif /* !TCL_ASCII_MAIN */
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * StdinProc --
+ *
+ *	This function is invoked by the event dispatcher whenever standard
+ *	input becomes readable. It grabs the next line of input characters,
+ *	adds them to a command being assembled, and executes the command if
+ *	it's complete.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Could be almost arbitrary, depending on the command that's typed.
+ *
+ *----------------------------------------------------------------------
+ */
+
+    /* ARGSUSED */
+static void
+StdinProc(
+    ClientData clientData,	/* The state of interactive cmd line */
+    int mask)			/* Not used. */
+{
+    int code, length;
+    InteractiveState *isPtr = clientData;
+    Tcl_Channel chan = isPtr->input;
+    Tcl_Obj *commandPtr = isPtr->commandPtr;
+    Tcl_Interp *interp = isPtr->interp;
+
+    if (Tcl_IsShared(commandPtr)) {
+	Tcl_DecrRefCount(commandPtr);
+	commandPtr = Tcl_DuplicateObj(commandPtr);
+	Tcl_IncrRefCount(commandPtr);
+    }
+    length = Tcl_GetsObj(chan, commandPtr);
+    if (length < 0) {
+	if (Tcl_InputBlocked(chan)) {
+	    return;
+	}
+	if (isPtr->tty) {
+	    /*
+	     * Would be better to find a way to exit the mainLoop? Or perhaps
+	     * evaluate [exit]? Leaving as is for now due to compatibility
+	     * concerns.
+	     */
+
+	    Tcl_Exit(0);
+	}
+	Tcl_DeleteChannelHandler(chan, StdinProc, isPtr);
+	return;
+    }
+
+    if (Tcl_IsShared(commandPtr)) {
+	Tcl_DecrRefCount(commandPtr);
+	commandPtr = Tcl_DuplicateObj(commandPtr);
+	Tcl_IncrRefCount(commandPtr);
+    }
+    Tcl_AppendToObj(commandPtr, "\n", 1);
+    if (!TclObjCommandComplete(commandPtr)) {
+	isPtr->prompt = PROMPT_CONTINUE;
+	goto prompt;
+    }
+    isPtr->prompt = PROMPT_START;
+    Tcl_GetStringFromObj(commandPtr, &length);
+    Tcl_SetObjLength(commandPtr, --length);
+
+    /*
+     * Disable the stdin channel handler while evaluating the command;
+     * otherwise if the command re-enters the event loop we might process
+     * commands from stdin before the current command is finished. Among other
+     * things, this will trash the text of the command being evaluated.
+     */
+
+    Tcl_CreateChannelHandler(chan, 0, StdinProc, isPtr);
+    code = Tcl_RecordAndEvalObj(interp, commandPtr, TCL_EVAL_GLOBAL);
+    isPtr->input = chan = Tcl_GetStdChannel(TCL_STDIN);
+    Tcl_DecrRefCount(commandPtr);
+    isPtr->commandPtr = commandPtr = Tcl_NewObj();
+    Tcl_IncrRefCount(commandPtr);
+    if (chan != NULL) {
+	Tcl_CreateChannelHandler(chan, TCL_READABLE, StdinProc, isPtr);
+    }
+    if (code != TCL_OK) {
+	chan = Tcl_GetStdChannel(TCL_STDERR);
+
+	if (chan != NULL) {
+	    Tcl_WriteObj(chan, Tcl_GetObjResult(interp));
+	    Tcl_WriteChars(chan, "\n", 1);
+	}
+    } else if (isPtr->tty) {
+	Tcl_Obj *resultPtr = Tcl_GetObjResult(interp);
+	chan = Tcl_GetStdChannel(TCL_STDOUT);
+
+	Tcl_IncrRefCount(resultPtr);
+	Tcl_GetStringFromObj(resultPtr, &length);
+	if ((length > 0) && (chan != NULL)) {
+	    Tcl_WriteObj(chan, resultPtr);
+	    Tcl_WriteChars(chan, "\n", 1);
+	}
+	Tcl_DecrRefCount(resultPtr);
+    }
+
+    /*
+     * If a tty stdin is still around, output a prompt.
+     */
+
+  prompt:
+    if (isPtr->tty && (isPtr->input != NULL)) {
+	Prompt(interp, isPtr);
+	isPtr->input = Tcl_GetStdChannel(TCL_STDIN);
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Prompt --
+ *
+ *	Issue a prompt on standard output, or invoke a script to issue the
+ *	prompt.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	A prompt gets output, and a Tcl script may be evaluated in interp.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+Prompt(
+    Tcl_Interp *interp,		/* Interpreter to use for prompting. */
+    InteractiveState *isPtr)	/* InteractiveState. Filled with PROMPT_NONE
+				 * after a prompt is printed. */
+{
+    Tcl_Obj *promptCmdPtr;
+    int code;
+    Tcl_Channel chan;
+
+    if (isPtr->prompt == PROMPT_NONE) {
+	return;
+    }
+
+    promptCmdPtr = Tcl_GetVar2Ex(interp,
+	    (isPtr->prompt==PROMPT_CONTINUE ? "tcl_prompt2" : "tcl_prompt1"),
+	    NULL, TCL_GLOBAL_ONLY);
+
+    if (Tcl_InterpDeleted(interp)) {
+	return;
+    }
+    if (promptCmdPtr == NULL) {
+    defaultPrompt:
+	if (isPtr->prompt == PROMPT_START) {
+	    chan = Tcl_GetStdChannel(TCL_STDOUT);
+	    if (chan != NULL) {
+		Tcl_WriteChars(chan, DEFAULT_PRIMARY_PROMPT,
+			strlen(DEFAULT_PRIMARY_PROMPT));
+	    }
+	}
+    } else {
+	code = Tcl_EvalObjEx(interp, promptCmdPtr, TCL_EVAL_GLOBAL);
+	if (code != TCL_OK) {
+	    Tcl_AddErrorInfo(interp,
+		    "\n    (script that generates prompt)");
+	    chan = Tcl_GetStdChannel(TCL_STDERR);
+	    if (chan != NULL) {
+		Tcl_WriteObj(chan, Tcl_GetObjResult(interp));
+		Tcl_WriteChars(chan, "\n", 1);
+	    }
+	    goto defaultPrompt;
+	}
+    }
+
+    chan = Tcl_GetStdChannel(TCL_STDOUT);
+    if (chan != NULL) {
+	Tcl_Flush(chan);
+    }
+    isPtr->prompt = PROMPT_NONE;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * FreeMainInterp --
+ *
+ *	Exit handler used to cleanup the main interpreter and ancillary
+ *	startup script storage at exit.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+FreeMainInterp(
+    ClientData clientData)
+{
+    Tcl_Interp *interp = clientData;
+
+    /*if (TclInExit()) return;*/
+
+    if (!Tcl_InterpDeleted(interp)) {
+	Tcl_DeleteInterp(interp);
+    }
+    Tcl_SetStartupScript(NULL, NULL);
+    Tcl_Release(interp);
+}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tclNamesp.c b/generic/tclNamesp.c
new file mode 100644
index 0000000..5930859
--- /dev/null
+++ b/generic/tclNamesp.c
@@ -0,0 +1,5101 @@
+/*
+ * tclNamesp.c --
+ *
+ *	Contains support for namespaces, which provide a separate context of
+ *	commands and global variables. The global :: namespace is the
+ *	traditional Tcl "global" scope. Other namespaces are created as
+ *	children of the global namespace. These other namespaces contain
+ *	special-purpose commands and variables for packages.
+ *
+ * Copyright (c) 1993-1997 Lucent Technologies.
+ * Copyright (c) 1997 Sun Microsystems, Inc.
+ * Copyright (c) 1998-1999 by Scriptics Corporation.
+ * Copyright (c) 2002-2005 Donal K. Fellows.
+ * Copyright (c) 2006 Neil Madden.
+ * Contributions from Don Porter, NIST, 2007. (not subject to US copyright)
+ *
+ * Originally implemented by
+ *   Michael J. McLennan
+ *   Bell Labs Innovations for Lucent Technologies
+ *   mmclennan@lucent.com
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#include "tclInt.h"
+#include "tclCompile.h" /* for TclLogCommandInfo visibility */
+
+/*
+ * Thread-local storage used to avoid having a global lock on data that is not
+ * limited to a single interpreter.
+ */
+
+typedef struct ThreadSpecificData {
+    long numNsCreated;		/* Count of the number of namespaces created
+				 * within the thread. This value is used as a
+				 * unique id for each namespace. Cannot be
+				 * per-interp because the nsId is used to
+				 * distinguish objects which can be passed
+				 * around between interps in the same thread,
+				 * but does not need to be global because
+				 * object internal reps are always per-thread
+				 * anyway. */
+} ThreadSpecificData;
+
+static Tcl_ThreadDataKey dataKey;
+
+/*
+ * This structure contains a cached pointer to a namespace that is the result
+ * of resolving the namespace's name in some other namespace. It is the
+ * internal representation for a nsName object. It contains the pointer along
+ * with some information that is used to check the cached pointer's validity.
+ */
+
+typedef struct ResolvedNsName {
+    Namespace *nsPtr;		/* A cached pointer to the Namespace that the
+				 * name resolved to. */
+    Namespace *refNsPtr;	/* Points to the namespace context in which
+				 * the name was resolved. NULL if the name is
+				 * fully qualified and thus the resolution
+				 * does not depend on the context. */
+    int refCount;		/* Reference count: 1 for each nsName object
+				 * that has a pointer to this ResolvedNsName
+				 * structure as its internal rep. This
+				 * structure can be freed when refCount
+				 * becomes zero. */
+} ResolvedNsName;
+
+/*
+ * Declarations for functions local to this file:
+ */
+
+static void		DeleteImportedCmd(ClientData clientData);
+static int		DoImport(Tcl_Interp *interp,
+			    Namespace *nsPtr, Tcl_HashEntry *hPtr,
+			    const char *cmdName, const char *pattern,
+			    Namespace *importNsPtr, int allowOverwrite);
+static void		DupNsNameInternalRep(Tcl_Obj *objPtr,Tcl_Obj *copyPtr);
+static char *		ErrorCodeRead(ClientData clientData,Tcl_Interp *interp,
+			    const char *name1, const char *name2, int flags);
+static char *		ErrorInfoRead(ClientData clientData,Tcl_Interp *interp,
+			    const char *name1, const char *name2, int flags);
+static char *		EstablishErrorCodeTraces(ClientData clientData,
+			    Tcl_Interp *interp, const char *name1,
+			    const char *name2, int flags);
+static char *		EstablishErrorInfoTraces(ClientData clientData,
+			    Tcl_Interp *interp, const char *name1,
+			    const char *name2, int flags);
+static void		FreeNsNameInternalRep(Tcl_Obj *objPtr);
+static int		GetNamespaceFromObj(Tcl_Interp *interp,
+			    Tcl_Obj *objPtr, Tcl_Namespace **nsPtrPtr);
+static int		InvokeImportedCmd(ClientData clientData,
+			    Tcl_Interp *interp,int objc,Tcl_Obj *const objv[]);
+static int		InvokeImportedNRCmd(ClientData clientData,
+			    Tcl_Interp *interp,int objc,Tcl_Obj *const objv[]);
+static int		NamespaceChildrenCmd(ClientData dummy,
+			    Tcl_Interp *interp,int objc,Tcl_Obj *const objv[]);
+static int		NamespaceCodeCmd(ClientData dummy, Tcl_Interp *interp,
+			    int objc, Tcl_Obj *const objv[]);
+static int		NamespaceCurrentCmd(ClientData dummy,
+			    Tcl_Interp *interp,int objc,Tcl_Obj *const objv[]);
+static int		NamespaceDeleteCmd(ClientData dummy,Tcl_Interp *interp,
+			    int objc, Tcl_Obj *const objv[]);
+static int		NamespaceEvalCmd(ClientData dummy, Tcl_Interp *interp,
+			    int objc, Tcl_Obj *const objv[]);
+static int		NRNamespaceEvalCmd(ClientData dummy,
+			    Tcl_Interp *interp,int objc,Tcl_Obj *const objv[]);
+static int		NamespaceExistsCmd(ClientData dummy,Tcl_Interp *interp,
+			    int objc, Tcl_Obj *const objv[]);
+static int		NamespaceExportCmd(ClientData dummy,Tcl_Interp *interp,
+			    int objc, Tcl_Obj *const objv[]);
+static int		NamespaceForgetCmd(ClientData dummy,Tcl_Interp *interp,
+			    int objc, Tcl_Obj *const objv[]);
+static void		NamespaceFree(Namespace *nsPtr);
+static int		NamespaceImportCmd(ClientData dummy,Tcl_Interp *interp,
+			    int objc, Tcl_Obj *const objv[]);
+static int		NamespaceInscopeCmd(ClientData dummy,
+			    Tcl_Interp *interp,int objc,Tcl_Obj *const objv[]);
+static int		NRNamespaceInscopeCmd(ClientData dummy,
+			    Tcl_Interp *interp,int objc,Tcl_Obj *const objv[]);
+static int		NamespaceOriginCmd(ClientData dummy,Tcl_Interp *interp,
+			    int objc, Tcl_Obj *const objv[]);
+static int		NamespaceParentCmd(ClientData dummy,Tcl_Interp *interp,
+			    int objc, Tcl_Obj *const objv[]);
+static int		NamespacePathCmd(ClientData dummy, Tcl_Interp *interp,
+			    int objc, Tcl_Obj *const objv[]);
+static int		NamespaceQualifiersCmd(ClientData dummy,
+			    Tcl_Interp *interp,int objc,Tcl_Obj *const objv[]);
+static int		NamespaceTailCmd(ClientData dummy, Tcl_Interp *interp,
+			    int objc, Tcl_Obj *const objv[]);
+static int		NamespaceUpvarCmd(ClientData dummy, Tcl_Interp *interp,
+			    int objc, Tcl_Obj *const objv[]);
+static int		NamespaceUnknownCmd(ClientData dummy,
+			    Tcl_Interp *interp,int objc,Tcl_Obj *const objv[]);
+static int		NamespaceWhichCmd(ClientData dummy, Tcl_Interp *interp,
+			    int objc, Tcl_Obj *const objv[]);
+static int		SetNsNameFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr);
+static void		UnlinkNsPath(Namespace *nsPtr);
+
+static Tcl_NRPostProc NsEval_Callback;
+
+/*
+ * This structure defines a Tcl object type that contains a namespace
+ * reference. It is used in commands that take the name of a namespace as an
+ * argument. The namespace reference is resolved, and the result in cached in
+ * the object.
+ */
+
+static const Tcl_ObjType nsNameType = {
+    "nsName",			/* the type's name */
+    FreeNsNameInternalRep,	/* freeIntRepProc */
+    DupNsNameInternalRep,	/* dupIntRepProc */
+    NULL,			/* updateStringProc */
+    SetNsNameFromAny		/* setFromAnyProc */
+};
+
+/*
+ * Array of values describing how to implement each standard subcommand of the
+ * "namespace" command.
+ */
+
+static const EnsembleImplMap defaultNamespaceMap[] = {
+    {"children",   NamespaceChildrenCmd, TclCompileBasic0To2ArgCmd, NULL, NULL, 0},
+    {"code",	   NamespaceCodeCmd,	TclCompileNamespaceCodeCmd, NULL, NULL, 0},
+    {"current",	   NamespaceCurrentCmd,	TclCompileNamespaceCurrentCmd, NULL, NULL, 0},
+    {"delete",	   NamespaceDeleteCmd,	TclCompileBasicMin0ArgCmd, NULL, NULL, 0},
+    {"ensemble",   TclNamespaceEnsembleCmd, NULL, NULL, NULL, 0},
+    {"eval",	   NamespaceEvalCmd,	NULL, NRNamespaceEvalCmd, NULL, 0},
+    {"exists",	   NamespaceExistsCmd,	TclCompileBasic1ArgCmd, NULL, NULL, 0},
+    {"export",	   NamespaceExportCmd,	TclCompileBasicMin0ArgCmd, NULL, NULL, 0},
+    {"forget",	   NamespaceForgetCmd,	TclCompileBasicMin0ArgCmd, NULL, NULL, 0},
+    {"import",	   NamespaceImportCmd,	TclCompileBasicMin0ArgCmd, NULL, NULL, 0},
+    {"inscope",	   NamespaceInscopeCmd,	NULL, NRNamespaceInscopeCmd, NULL, 0},
+    {"origin",	   NamespaceOriginCmd,	TclCompileNamespaceOriginCmd, NULL, NULL, 0},
+    {"parent",	   NamespaceParentCmd,	TclCompileBasic0Or1ArgCmd, NULL, NULL, 0},
+    {"path",	   NamespacePathCmd,	TclCompileBasic0Or1ArgCmd, NULL, NULL, 0},
+    {"qualifiers", NamespaceQualifiersCmd, TclCompileNamespaceQualifiersCmd, NULL, NULL, 0},
+    {"tail",	   NamespaceTailCmd,	TclCompileNamespaceTailCmd, NULL, NULL, 0},
+    {"unknown",	   NamespaceUnknownCmd, TclCompileBasic0Or1ArgCmd, NULL, NULL, 0},
+    {"upvar",	   NamespaceUpvarCmd,	TclCompileNamespaceUpvarCmd, NULL, NULL, 0},
+    {"which",	   NamespaceWhichCmd,	TclCompileNamespaceWhichCmd, NULL, NULL, 0},
+    {NULL, NULL, NULL, NULL, NULL, 0}
+};
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclInitNamespaceSubsystem --
+ *
+ *	This function is called to initialize all the structures that are used
+ *	by namespaces on a per-process basis.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclInitNamespaceSubsystem(void)
+{
+    /*
+     * Does nothing for now.
+     */
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_GetCurrentNamespace --
+ *
+ *	Returns a pointer to an interpreter's currently active namespace.
+ *
+ * Results:
+ *	Returns a pointer to the interpreter's current namespace.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_Namespace *
+Tcl_GetCurrentNamespace(
+    register Tcl_Interp *interp)/* Interpreter whose current namespace is
+				 * being queried. */
+{
+    return TclGetCurrentNamespace(interp);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_GetGlobalNamespace --
+ *
+ *	Returns a pointer to an interpreter's global :: namespace.
+ *
+ * Results:
+ *	Returns a pointer to the specified interpreter's global namespace.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_Namespace *
+Tcl_GetGlobalNamespace(
+    register Tcl_Interp *interp)/* Interpreter whose global namespace should
+				 * be returned. */
+{
+    return TclGetGlobalNamespace(interp);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_PushCallFrame --
+ *
+ *	Pushes a new call frame onto the interpreter's Tcl call stack. Called
+ *	when executing a Tcl procedure or a "namespace eval" or "namespace
+ *	inscope" command.
+ *
+ * Results:
+ *	Returns TCL_OK if successful, or TCL_ERROR (along with an error
+ *	message in the interpreter's result object) if something goes wrong.
+ *
+ * Side effects:
+ *	Modifies the interpreter's Tcl call stack.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_PushCallFrame(
+    Tcl_Interp *interp,		/* Interpreter in which the new call frame is
+				 * to be pushed. */
+    Tcl_CallFrame *callFramePtr,/* Points to a call frame structure to push.
+				 * Storage for this has already been allocated
+				 * by the caller; typically this is the
+				 * address of a CallFrame structure allocated
+				 * on the caller's C stack. The call frame
+				 * will be initialized by this function. The
+				 * caller can pop the frame later with
+				 * Tcl_PopCallFrame, and it is responsible for
+				 * freeing the frame's storage. */
+    Tcl_Namespace *namespacePtr,/* Points to the namespace in which the frame
+				 * will execute. If NULL, the interpreter's
+				 * current namespace will be used. */
+    int isProcCallFrame)	/* If nonzero, the frame represents a called
+				 * Tcl procedure and may have local vars. Vars
+				 * will ordinarily be looked up in the frame.
+				 * If new variables are created, they will be
+				 * created in the frame. If 0, the frame is
+				 * for a "namespace eval" or "namespace
+				 * inscope" command and var references are
+				 * treated as references to namespace
+				 * variables. */
+{
+    Interp *iPtr = (Interp *) interp;
+    register CallFrame *framePtr = (CallFrame *) callFramePtr;
+    register Namespace *nsPtr;
+
+    if (namespacePtr == NULL) {
+	nsPtr = (Namespace *) TclGetCurrentNamespace(interp);
+    } else {
+	nsPtr = (Namespace *) namespacePtr;
+
+	/*
+	 * TODO: Examine whether it would be better to guard based on NS_DYING
+	 * or NS_KILLED. It appears that these are not tested because they can
+	 * be set in a global interp that has been [namespace delete]d, but
+	 * which never really completely goes away because of lingering global
+	 * things like ::errorInfo and [::unknown] and hidden commands.
+	 * Review of those designs might permit stricter checking here.
+	 */
+
+	if (nsPtr->flags & NS_DEAD) {
+	    Tcl_Panic("Trying to push call frame for dead namespace");
+	    /*NOTREACHED*/
+	}
+    }
+
+    nsPtr->activationCount++;
+    framePtr->nsPtr = nsPtr;
+    framePtr->isProcCallFrame = isProcCallFrame;
+    framePtr->objc = 0;
+    framePtr->objv = NULL;
+    framePtr->callerPtr = iPtr->framePtr;
+    framePtr->callerVarPtr = iPtr->varFramePtr;
+    if (iPtr->varFramePtr != NULL) {
+	framePtr->level = (iPtr->varFramePtr->level + 1);
+    } else {
+	framePtr->level = 0;
+    }
+    framePtr->procPtr = NULL;		/* no called procedure */
+    framePtr->varTablePtr = NULL;	/* and no local variables */
+    framePtr->numCompiledLocals = 0;
+    framePtr->compiledLocals = NULL;
+    framePtr->clientData = NULL;
+    framePtr->localCachePtr = NULL;
+    framePtr->tailcallPtr = NULL;
+
+    /*
+     * Push the new call frame onto the interpreter's stack of procedure call
+     * frames making it the current frame.
+     */
+
+    iPtr->framePtr = framePtr;
+    iPtr->varFramePtr = framePtr;
+
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_PopCallFrame --
+ *
+ *	Removes a call frame from the Tcl call stack for the interpreter.
+ *	Called to remove a frame previously pushed by Tcl_PushCallFrame.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Modifies the call stack of the interpreter. Resets various fields of
+ *	the popped call frame. If a namespace has been deleted and has no more
+ *	activations on the call stack, the namespace is destroyed.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_PopCallFrame(
+    Tcl_Interp *interp)		/* Interpreter with call frame to pop. */
+{
+    register Interp *iPtr = (Interp *) interp;
+    register CallFrame *framePtr = iPtr->framePtr;
+    Namespace *nsPtr;
+
+    /*
+     * It's important to remove the call frame from the interpreter's stack of
+     * call frames before deleting local variables, so that traces invoked by
+     * the variable deletion don't see the partially-deleted frame.
+     */
+
+    if (framePtr->callerPtr) {
+	iPtr->framePtr = framePtr->callerPtr;
+	iPtr->varFramePtr = framePtr->callerVarPtr;
+    } else {
+	/* Tcl_PopCallFrame: trying to pop rootCallFrame! */
+    }
+
+    if (framePtr->varTablePtr != NULL) {
+	TclDeleteVars(iPtr, framePtr->varTablePtr);
+	ckfree(framePtr->varTablePtr);
+	framePtr->varTablePtr = NULL;
+    }
+    if (framePtr->numCompiledLocals > 0) {
+	TclDeleteCompiledLocalVars(iPtr, framePtr);
+	if (--framePtr->localCachePtr->refCount == 0) {
+	    TclFreeLocalCache(interp, framePtr->localCachePtr);
+	}
+	framePtr->localCachePtr = NULL;
+    }
+
+    /*
+     * Decrement the namespace's count of active call frames. If the namespace
+     * is "dying" and there are no more active call frames, call
+     * Tcl_DeleteNamespace to destroy it.
+     */
+
+    nsPtr = framePtr->nsPtr;
+    nsPtr->activationCount--;
+    if ((nsPtr->flags & NS_DYING)
+	    && (nsPtr->activationCount - (nsPtr == iPtr->globalNsPtr) == 0)) {
+	Tcl_DeleteNamespace((Tcl_Namespace *) nsPtr);
+    }
+    framePtr->nsPtr = NULL;
+
+    if (framePtr->tailcallPtr) {
+	TclSetTailcall(interp, framePtr->tailcallPtr);
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclPushStackFrame --
+ *
+ *	Allocates a new call frame in the interpreter's execution stack, then
+ *	pushes it onto the interpreter's Tcl call stack. Called when executing
+ *	a Tcl procedure or a "namespace eval" or "namespace inscope" command.
+ *
+ * Results:
+ *	Returns TCL_OK if successful, or TCL_ERROR (along with an error
+ *	message in the interpreter's result object) if something goes wrong.
+ *
+ * Side effects:
+ *	Modifies the interpreter's Tcl call stack.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclPushStackFrame(
+    Tcl_Interp *interp,		/* Interpreter in which the new call frame is
+				 * to be pushed. */
+    Tcl_CallFrame **framePtrPtr,/* Place to store a pointer to the stack
+				 * allocated call frame. */
+    Tcl_Namespace *namespacePtr,/* Points to the namespace in which the frame
+				 * will execute. If NULL, the interpreter's
+				 * current namespace will be used. */
+    int isProcCallFrame)	/* If nonzero, the frame represents a called
+				 * Tcl procedure and may have local vars. Vars
+				 * will ordinarily be looked up in the frame.
+				 * If new variables are created, they will be
+				 * created in the frame. If 0, the frame is
+				 * for a "namespace eval" or "namespace
+				 * inscope" command and var references are
+				 * treated as references to namespace
+				 * variables. */
+{
+    *framePtrPtr = TclStackAlloc(interp, sizeof(CallFrame));
+    return Tcl_PushCallFrame(interp, *framePtrPtr, namespacePtr,
+	    isProcCallFrame);
+}
+
+void
+TclPopStackFrame(
+    Tcl_Interp *interp)		/* Interpreter with call frame to pop. */
+{
+    CallFrame *freePtr = ((Interp *) interp)->framePtr;
+
+    Tcl_PopCallFrame(interp);
+    TclStackFree(interp, freePtr);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * EstablishErrorCodeTraces --
+ *
+ *	Creates traces on the ::errorCode variable to keep its value
+ *	consistent with the expectations of legacy code.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Read and unset traces are established on ::errorCode.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static char *
+EstablishErrorCodeTraces(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    const char *name1,
+    const char *name2,
+    int flags)
+{
+    Tcl_TraceVar2(interp, "errorCode", NULL, TCL_GLOBAL_ONLY|TCL_TRACE_READS,
+	    ErrorCodeRead, NULL);
+    Tcl_TraceVar2(interp, "errorCode", NULL, TCL_GLOBAL_ONLY|TCL_TRACE_UNSETS,
+	    EstablishErrorCodeTraces, NULL);
+    return NULL;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ErrorCodeRead --
+ *
+ *	Called when the ::errorCode variable is read. Copies the current value
+ *	of the interp's errorCode field into ::errorCode.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static char *
+ErrorCodeRead(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    const char *name1,
+    const char *name2,
+    int flags)
+{
+    Interp *iPtr = (Interp *) interp;
+
+    if (Tcl_InterpDeleted(interp) || !(iPtr->flags & ERR_LEGACY_COPY)) {
+	return NULL;
+    }
+    if (iPtr->errorCode) {
+	Tcl_ObjSetVar2(interp, iPtr->ecVar, NULL,
+		iPtr->errorCode, TCL_GLOBAL_ONLY);
+	return NULL;
+    }
+    if (NULL == Tcl_ObjGetVar2(interp, iPtr->ecVar, NULL, TCL_GLOBAL_ONLY)) {
+	Tcl_ObjSetVar2(interp, iPtr->ecVar, NULL,
+		Tcl_NewObj(), TCL_GLOBAL_ONLY);
+    }
+    return NULL;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * EstablishErrorInfoTraces --
+ *
+ *	Creates traces on the ::errorInfo variable to keep its value
+ *	consistent with the expectations of legacy code.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Read and unset traces are established on ::errorInfo.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static char *
+EstablishErrorInfoTraces(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    const char *name1,
+    const char *name2,
+    int flags)
+{
+    Tcl_TraceVar2(interp, "errorInfo", NULL, TCL_GLOBAL_ONLY|TCL_TRACE_READS,
+	    ErrorInfoRead, NULL);
+    Tcl_TraceVar2(interp, "errorInfo", NULL, TCL_GLOBAL_ONLY|TCL_TRACE_UNSETS,
+	    EstablishErrorInfoTraces, NULL);
+    return NULL;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ErrorInfoRead --
+ *
+ *	Called when the ::errorInfo variable is read. Copies the current value
+ *	of the interp's errorInfo field into ::errorInfo.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static char *
+ErrorInfoRead(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    const char *name1,
+    const char *name2,
+    int flags)
+{
+    Interp *iPtr = (Interp *) interp;
+
+    if (Tcl_InterpDeleted(interp) || !(iPtr->flags & ERR_LEGACY_COPY)) {
+	return NULL;
+    }
+    if (iPtr->errorInfo) {
+	Tcl_ObjSetVar2(interp, iPtr->eiVar, NULL,
+		iPtr->errorInfo, TCL_GLOBAL_ONLY);
+	return NULL;
+    }
+    if (NULL == Tcl_ObjGetVar2(interp, iPtr->eiVar, NULL, TCL_GLOBAL_ONLY)) {
+	Tcl_ObjSetVar2(interp, iPtr->eiVar, NULL,
+		Tcl_NewObj(), TCL_GLOBAL_ONLY);
+    }
+    return NULL;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_CreateNamespace --
+ *
+ *	Creates a new namespace with the given name. If there is no active
+ *	namespace (i.e., the interpreter is being initialized), the global ::
+ *	namespace is created and returned.
+ *
+ * Results:
+ *	Returns a pointer to the new namespace if successful. If the namespace
+ *	already exists or if another error occurs, this routine returns NULL,
+ *	along with an error message in the interpreter's result object.
+ *
+ * Side effects:
+ *	If the name contains "::" qualifiers and a parent namespace does not
+ *	already exist, it is automatically created.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_Namespace *
+Tcl_CreateNamespace(
+    Tcl_Interp *interp,		/* Interpreter in which a new namespace is
+				 * being created. Also used for error
+				 * reporting. */
+    const char *name,		/* Name for the new namespace. May be a
+				 * qualified name with names of ancestor
+				 * namespaces separated by "::"s. */
+    ClientData clientData,	/* One-word value to store with namespace. */
+    Tcl_NamespaceDeleteProc *deleteProc)
+				/* Function called to delete client data when
+				 * the namespace is deleted. NULL if no
+				 * function should be called. */
+{
+    Interp *iPtr = (Interp *) interp;
+    register Namespace *nsPtr, *ancestorPtr;
+    Namespace *parentPtr, *dummy1Ptr, *dummy2Ptr;
+    Namespace *globalNsPtr = iPtr->globalNsPtr;
+    const char *simpleName;
+    Tcl_HashEntry *entryPtr;
+    Tcl_DString buffer1, buffer2;
+    Tcl_DString *namePtr, *buffPtr;
+    int newEntry, nameLen;
+    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+    const char *nameStr;
+    Tcl_DString tmpBuffer;
+
+    Tcl_DStringInit(&tmpBuffer);
+
+    /*
+     * If there is no active namespace, the interpreter is being initialized.
+     */
+
+    if ((globalNsPtr == NULL) && (iPtr->varFramePtr == NULL)) {
+	/*
+	 * Treat this namespace as the global namespace, and avoid looking for
+	 * a parent.
+	 */
+
+	parentPtr = NULL;
+	simpleName = "";
+	goto doCreate;
+    }
+
+    /*
+     * Ensure that there are no trailing colons as that causes chaos when a
+     * deleteProc is specified. [Bug d614d63989]
+     */
+
+    if (deleteProc != NULL) {
+	nameStr = name + strlen(name) - 2;
+	if (nameStr >= name && nameStr[1] == ':' && nameStr[0] == ':') {
+	    Tcl_DStringAppend(&tmpBuffer, name, -1);
+	    while ((nameLen = Tcl_DStringLength(&tmpBuffer)) > 0
+		    && Tcl_DStringValue(&tmpBuffer)[nameLen-1] == ':') {
+		Tcl_DStringSetLength(&tmpBuffer, nameLen-1);
+	    }
+	    name = Tcl_DStringValue(&tmpBuffer);
+	}
+    }
+
+    /*
+     * If we've ended up with an empty string now, we're attempting to create
+     * the global namespace despite the global namespace existing. That's
+     * naughty!
+     */
+
+    if (*name == '\0') {
+	Tcl_SetObjResult(interp, Tcl_NewStringObj("can't create namespace"
+                " \"\": only global namespace can have empty name", -1));
+	Tcl_SetErrorCode(interp, "TCL", "OPERATION", "NAMESPACE",
+		"CREATEGLOBAL", NULL);
+	Tcl_DStringFree(&tmpBuffer);
+	return NULL;
+    }
+
+    /*
+     * Find the parent for the new namespace.
+     */
+
+    TclGetNamespaceForQualName(interp, name, NULL, TCL_CREATE_NS_IF_UNKNOWN,
+	    &parentPtr, &dummy1Ptr, &dummy2Ptr, &simpleName);
+
+    /*
+     * If the unqualified name at the end is empty, there were trailing "::"s
+     * after the namespace's name which we ignore. The new namespace was
+     * already (recursively) created and is pointed to by parentPtr.
+     */
+
+    if (*simpleName == '\0') {
+	Tcl_DStringFree(&tmpBuffer);
+	return (Tcl_Namespace *) parentPtr;
+    }
+
+    /*
+     * Check for a bad namespace name and make sure that the name does not
+     * already exist in the parent namespace.
+     */
+
+    if (
+#ifndef BREAK_NAMESPACE_COMPAT
+	Tcl_FindHashEntry(&parentPtr->childTable, simpleName) != NULL
+#else
+	parentPtr->childTablePtr != NULL &&
+	Tcl_FindHashEntry(parentPtr->childTablePtr, simpleName) != NULL
+#endif
+    ) {
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		"can't create namespace \"%s\": already exists", name));
+	Tcl_SetErrorCode(interp, "TCL", "OPERATION", "NAMESPACE",
+		"CREATEEXISTING", NULL);
+	Tcl_DStringFree(&tmpBuffer);
+	return NULL;
+    }
+
+    /*
+     * Create the new namespace and root it in its parent. Increment the count
+     * of namespaces created.
+     */
+
+  doCreate:
+    nsPtr = ckalloc(sizeof(Namespace));
+    nameLen = strlen(simpleName) + 1;
+    nsPtr->name = ckalloc(nameLen);
+    memcpy(nsPtr->name, simpleName, nameLen);
+    nsPtr->fullName = NULL;		/* Set below. */
+    nsPtr->clientData = clientData;
+    nsPtr->deleteProc = deleteProc;
+    nsPtr->parentPtr = parentPtr;
+#ifndef BREAK_NAMESPACE_COMPAT
+    Tcl_InitHashTable(&nsPtr->childTable, TCL_STRING_KEYS);
+#else
+    nsPtr->childTablePtr = NULL;
+#endif
+    nsPtr->nsId = ++(tsdPtr->numNsCreated);
+    nsPtr->interp = interp;
+    nsPtr->flags = 0;
+    nsPtr->activationCount = 0;
+    nsPtr->refCount = 0;
+    Tcl_InitHashTable(&nsPtr->cmdTable, TCL_STRING_KEYS);
+    TclInitVarHashTable(&nsPtr->varTable, nsPtr);
+    nsPtr->exportArrayPtr = NULL;
+    nsPtr->numExportPatterns = 0;
+    nsPtr->maxExportPatterns = 0;
+    nsPtr->cmdRefEpoch = 0;
+    nsPtr->resolverEpoch = 0;
+    nsPtr->cmdResProc = NULL;
+    nsPtr->varResProc = NULL;
+    nsPtr->compiledVarResProc = NULL;
+    nsPtr->exportLookupEpoch = 0;
+    nsPtr->ensembles = NULL;
+    nsPtr->unknownHandlerPtr = NULL;
+    nsPtr->commandPathLength = 0;
+    nsPtr->commandPathArray = NULL;
+    nsPtr->commandPathSourceList = NULL;
+    nsPtr->earlyDeleteProc = NULL;
+
+    if (parentPtr != NULL) {
+	entryPtr = Tcl_CreateHashEntry(
+		TclGetNamespaceChildTable((Tcl_Namespace *) parentPtr),
+		simpleName, &newEntry);
+	Tcl_SetHashValue(entryPtr, nsPtr);
+    } else {
+	/*
+	 * In the global namespace create traces to maintain the ::errorInfo
+	 * and ::errorCode variables.
+	 */
+
+	iPtr->globalNsPtr = nsPtr;
+	EstablishErrorInfoTraces(NULL, interp, NULL, NULL, 0);
+	EstablishErrorCodeTraces(NULL, interp, NULL, NULL, 0);
+    }
+
+    /*
+     * Build the fully qualified name for this namespace.
+     */
+
+    Tcl_DStringInit(&buffer1);
+    Tcl_DStringInit(&buffer2);
+    namePtr = &buffer1;
+    buffPtr = &buffer2;
+    for (ancestorPtr = nsPtr; ancestorPtr != NULL;
+	    ancestorPtr = ancestorPtr->parentPtr) {
+	if (ancestorPtr != globalNsPtr) {
+	    register Tcl_DString *tempPtr = namePtr;
+
+	    TclDStringAppendLiteral(buffPtr, "::");
+	    Tcl_DStringAppend(buffPtr, ancestorPtr->name, -1);
+	    TclDStringAppendDString(buffPtr, namePtr);
+
+	    /*
+	     * Clear the unwanted buffer or we end up appending to previous
+	     * results, making the namespace fullNames of nested namespaces
+	     * very wrong (and strange).
+	     */
+
+	    TclDStringClear(namePtr);
+
+	    /*
+	     * Now swap the buffer pointers so that we build in the other
+	     * buffer. This is faster than repeated copying back and forth
+	     * between buffers.
+	     */
+
+	    namePtr = buffPtr;
+	    buffPtr = tempPtr;
+	}
+    }
+
+    name = Tcl_DStringValue(namePtr);
+    nameLen = Tcl_DStringLength(namePtr);
+    nsPtr->fullName = ckalloc(nameLen + 1);
+    memcpy(nsPtr->fullName, name, (unsigned) nameLen + 1);
+
+    Tcl_DStringFree(&buffer1);
+    Tcl_DStringFree(&buffer2);
+    Tcl_DStringFree(&tmpBuffer);
+
+    /*
+     * If compilation of commands originating from the parent NS is
+     * suppressed, suppress it for commands originating in this one too.
+     */
+
+    if (nsPtr->parentPtr != NULL &&
+	    nsPtr->parentPtr->flags & NS_SUPPRESS_COMPILATION) {
+	nsPtr->flags |= NS_SUPPRESS_COMPILATION;
+    }
+
+    /*
+     * Return a pointer to the new namespace.
+     */
+
+    return (Tcl_Namespace *) nsPtr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_DeleteNamespace --
+ *
+ *	Deletes a namespace and all of the commands, variables, and other
+ *	namespaces within it.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	When a namespace is deleted, it is automatically removed as a child of
+ *	its parent namespace. Also, all its commands, variables and child
+ *	namespaces are deleted.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_DeleteNamespace(
+    Tcl_Namespace *namespacePtr)/* Points to the namespace to delete. */
+{
+    register Namespace *nsPtr = (Namespace *) namespacePtr;
+    Interp *iPtr = (Interp *) nsPtr->interp;
+    Namespace *globalNsPtr = (Namespace *)
+	    TclGetGlobalNamespace((Tcl_Interp *) iPtr);
+    Tcl_HashEntry *entryPtr;
+    Tcl_HashSearch search;
+    Command *cmdPtr;
+
+    /*
+     * Give anyone interested - notably TclOO - a chance to use this namespace
+     * normally despite the fact that the namespace is going to go. Allows the
+     * calling of destructors. Will only be called once (unless re-established
+     * by the called function). [Bug 2950259]
+     *
+     * Note that setting this field requires access to the internal definition
+     * of namespaces, so it should only be accessed by code that knows about
+     * being careful with reentrancy.
+     */
+
+    if (nsPtr->earlyDeleteProc != NULL) {
+	Tcl_NamespaceDeleteProc *earlyDeleteProc = nsPtr->earlyDeleteProc;
+
+	nsPtr->earlyDeleteProc = NULL;
+	nsPtr->activationCount++;
+	earlyDeleteProc(nsPtr->clientData);
+	nsPtr->activationCount--;
+    }
+
+    /*
+     * Delete all coroutine commands now: break the circular ref cycle between
+     * the namespace and the coroutine command [Bug 2724403]. This code is
+     * essentially duplicated in TclTeardownNamespace() for all other
+     * commands. Don't optimize to Tcl_NextHashEntry() because of traces.
+     *
+     * NOTE: we could avoid traversing the ns's command list by keeping a
+     * separate list of coros.
+     */
+
+    for (entryPtr = Tcl_FirstHashEntry(&nsPtr->cmdTable, &search);
+	    entryPtr != NULL;) {
+	cmdPtr = Tcl_GetHashValue(entryPtr);
+	if (cmdPtr->nreProc == TclNRInterpCoroutine) {
+	    Tcl_DeleteCommandFromToken((Tcl_Interp *) iPtr,
+		    (Tcl_Command) cmdPtr);
+	    entryPtr = Tcl_FirstHashEntry(&nsPtr->cmdTable, &search);
+	} else {
+	    entryPtr = Tcl_NextHashEntry(&search);
+	}
+    }
+
+    /*
+     * If the namespace has associated ensemble commands, delete them first.
+     * This leaves the actual contents of the namespace alone (unless they are
+     * linked ensemble commands, of course). Note that this code is actually
+     * reentrant so command delete traces won't purturb things badly.
+     */
+
+    while (nsPtr->ensembles != NULL) {
+	EnsembleConfig *ensemblePtr = (EnsembleConfig *) nsPtr->ensembles;
+
+	/*
+	 * Splice out and link to indicate that we've already been killed.
+	 */
+
+	nsPtr->ensembles = (Tcl_Ensemble *) ensemblePtr->next;
+	ensemblePtr->next = ensemblePtr;
+	Tcl_DeleteCommandFromToken(nsPtr->interp, ensemblePtr->token);
+    }
+
+    /*
+     * If the namespace has a registered unknown handler (TIP 181), then free
+     * it here.
+     */
+
+    if (nsPtr->unknownHandlerPtr != NULL) {
+	Tcl_DecrRefCount(nsPtr->unknownHandlerPtr);
+	nsPtr->unknownHandlerPtr = NULL;
+    }
+
+    /*
+     * If the namespace is on the call frame stack, it is marked as "dying"
+     * (NS_DYING is OR'd into its flags): the namespace can't be looked up by
+     * name but its commands and variables are still usable by those active
+     * call frames. When all active call frames referring to the namespace
+     * have been popped from the Tcl stack, Tcl_PopCallFrame will call this
+     * function again to delete everything in the namespace. If no nsName
+     * objects refer to the namespace (i.e., if its refCount is zero), its
+     * commands and variables are deleted and the storage for its namespace
+     * structure is freed. Otherwise, if its refCount is nonzero, the
+     * namespace's commands and variables are deleted but the structure isn't
+     * freed. Instead, NS_DEAD is OR'd into the structure's flags to allow the
+     * namespace resolution code to recognize that the namespace is "deleted".
+     * The structure's storage is freed by FreeNsNameInternalRep when its
+     * refCount reaches 0.
+     */
+
+    if (nsPtr->activationCount - (nsPtr == globalNsPtr) > 0) {
+	nsPtr->flags |= NS_DYING;
+	if (nsPtr->parentPtr != NULL) {
+	    entryPtr = Tcl_FindHashEntry(
+		    TclGetNamespaceChildTable((Tcl_Namespace *)
+			    nsPtr->parentPtr), nsPtr->name);
+	    if (entryPtr != NULL) {
+		Tcl_DeleteHashEntry(entryPtr);
+	    }
+	}
+	nsPtr->parentPtr = NULL;
+    } else if (!(nsPtr->flags & NS_KILLED)) {
+	/*
+	 * Delete the namespace and everything in it. If this is the global
+	 * namespace, then clear it but don't free its storage unless the
+	 * interpreter is being torn down. Set the NS_KILLED flag to avoid
+	 * recursive calls here - if the namespace is really in the process of
+	 * being deleted, ignore any second call.
+	 */
+
+	nsPtr->flags |= (NS_DYING|NS_KILLED);
+
+	TclTeardownNamespace(nsPtr);
+
+	if ((nsPtr != globalNsPtr) || (iPtr->flags & DELETED)) {
+	    /*
+	     * If this is the global namespace, then it may have residual
+	     * "errorInfo" and "errorCode" variables for errors that occurred
+	     * while it was being torn down. Try to clear the variable list
+	     * one last time.
+	     */
+
+	    TclDeleteNamespaceVars(nsPtr);
+
+#ifndef BREAK_NAMESPACE_COMPAT
+	    Tcl_DeleteHashTable(&nsPtr->childTable);
+#else
+	    if (nsPtr->childTablePtr != NULL) {
+		Tcl_DeleteHashTable(nsPtr->childTablePtr);
+		ckfree(nsPtr->childTablePtr);
+	    }
+#endif
+	    Tcl_DeleteHashTable(&nsPtr->cmdTable);
+
+	    /*
+	     * If the reference count is 0, then discard the namespace.
+	     * Otherwise, mark it as "dead" so that it can't be used.
+	     */
+
+	    if (nsPtr->refCount == 0) {
+		NamespaceFree(nsPtr);
+	    } else {
+		nsPtr->flags |= NS_DEAD;
+	    }
+	} else {
+	    /*
+	     * Restore the ::errorInfo and ::errorCode traces.
+	     */
+
+	    EstablishErrorInfoTraces(NULL, nsPtr->interp, NULL, NULL, 0);
+	    EstablishErrorCodeTraces(NULL, nsPtr->interp, NULL, NULL, 0);
+
+	    /*
+	     * We didn't really kill it, so remove the KILLED marks, so it can
+	     * get killed later, avoiding mem leaks.
+	     */
+
+	    nsPtr->flags &= ~(NS_DYING|NS_KILLED);
+	}
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclTeardownNamespace --
+ *
+ *	Used internally to dismantle and unlink a namespace when it is
+ *	deleted. Divorces the namespace from its parent, and deletes all
+ *	commands, variables, and child namespaces.
+ *
+ *	This is kept separate from Tcl_DeleteNamespace so that the global
+ *	namespace can be handled specially.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Removes this namespace from its parent's child namespace hashtable.
+ *	Deletes all commands, variables and namespaces in this namespace.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclTeardownNamespace(
+    register Namespace *nsPtr)	/* Points to the namespace to be dismantled
+				 * and unlinked from its parent. */
+{
+    Interp *iPtr = (Interp *) nsPtr->interp;
+    register Tcl_HashEntry *entryPtr;
+    Tcl_HashSearch search;
+    int i;
+
+    /*
+     * Start by destroying the namespace's variable table, since variables
+     * might trigger traces. Variable table should be cleared but not freed!
+     * TclDeleteNamespaceVars frees it, so we reinitialize it afterwards.
+     */
+
+    TclDeleteNamespaceVars(nsPtr);
+    TclInitVarHashTable(&nsPtr->varTable, nsPtr);
+
+    /*
+     * Delete all commands in this namespace. Be careful when traversing the
+     * hash table: when each command is deleted, it removes itself from the
+     * command table. Because of traces (and the desire to avoid the quadratic
+     * problems of just using Tcl_FirstHashEntry over and over, [Bug
+     * f97d4ee020]) we copy to a temporary array and then delete all those
+     * commands.
+     */
+
+    while (nsPtr->cmdTable.numEntries > 0) {
+	int length = nsPtr->cmdTable.numEntries;
+	Command **cmds = TclStackAlloc((Tcl_Interp *) iPtr,
+		sizeof(Command *) * length);
+
+	i = 0;
+	for (entryPtr = Tcl_FirstHashEntry(&nsPtr->cmdTable, &search);
+		entryPtr != NULL;
+		entryPtr = Tcl_NextHashEntry(&search)) {
+	    cmds[i] = Tcl_GetHashValue(entryPtr);
+	    cmds[i]->refCount++;
+	    i++;
+	}
+	for (i = 0 ; i < length ; i++) {
+	    Tcl_DeleteCommandFromToken((Tcl_Interp *) iPtr,
+		    (Tcl_Command) cmds[i]);
+	    TclCleanupCommandMacro(cmds[i]);
+	}
+	TclStackFree((Tcl_Interp *) iPtr, cmds);
+    }
+    Tcl_DeleteHashTable(&nsPtr->cmdTable);
+    Tcl_InitHashTable(&nsPtr->cmdTable, TCL_STRING_KEYS);
+
+    /*
+     * Remove the namespace from its parent's child hashtable.
+     */
+
+    if (nsPtr->parentPtr != NULL) {
+	entryPtr = Tcl_FindHashEntry(
+		TclGetNamespaceChildTable((Tcl_Namespace *)
+			nsPtr->parentPtr), nsPtr->name);
+	if (entryPtr != NULL) {
+	    Tcl_DeleteHashEntry(entryPtr);
+	}
+    }
+    nsPtr->parentPtr = NULL;
+
+    /*
+     * Delete the namespace path if one is installed.
+     */
+
+    if (nsPtr->commandPathLength != 0) {
+	UnlinkNsPath(nsPtr);
+	nsPtr->commandPathLength = 0;
+    }
+    if (nsPtr->commandPathSourceList != NULL) {
+	NamespacePathEntry *nsPathPtr = nsPtr->commandPathSourceList;
+
+	do {
+	    if (nsPathPtr->nsPtr != NULL && nsPathPtr->creatorNsPtr != NULL) {
+		nsPathPtr->creatorNsPtr->cmdRefEpoch++;
+	    }
+	    nsPathPtr->nsPtr = NULL;
+	    nsPathPtr = nsPathPtr->nextPtr;
+	} while (nsPathPtr != NULL);
+	nsPtr->commandPathSourceList = NULL;
+    }
+
+    /*
+     * Delete all the child namespaces.
+     *
+     * BE CAREFUL: When each child is deleted, it will divorce itself from its
+     * parent. You can't traverse a hash table properly if its elements are
+     * being deleted.  Because of traces (and the desire to avoid the
+     * quadratic problems of just using Tcl_FirstHashEntry over and over, [Bug
+     * f97d4ee020]) we copy to a temporary array and then delete all those
+     * namespaces.
+     *
+     * Important: leave the hash table itself still live.
+     */
+
+#ifndef BREAK_NAMESPACE_COMPAT
+    while (nsPtr->childTable.numEntries > 0) {
+	int length = nsPtr->childTable.numEntries;
+	Namespace **children = TclStackAlloc((Tcl_Interp *) iPtr,
+		sizeof(Namespace *) * length);
+
+	i = 0;
+	for (entryPtr = Tcl_FirstHashEntry(&nsPtr->childTable, &search);
+		entryPtr != NULL;
+		entryPtr = Tcl_NextHashEntry(&search)) {
+	    children[i] = Tcl_GetHashValue(entryPtr);
+	    children[i]->refCount++;
+	    i++;
+	}
+	for (i = 0 ; i < length ; i++) {
+	    Tcl_DeleteNamespace((Tcl_Namespace *) children[i]);
+	    TclNsDecrRefCount(children[i]);
+	}
+	TclStackFree((Tcl_Interp *) iPtr, children);
+    }
+#else
+    if (nsPtr->childTablePtr != NULL) {
+	while (nsPtr->childTablePtr->numEntries > 0) {
+	    int length = nsPtr->childTablePtr->numEntries;
+	    Namespace **children = TclStackAlloc((Tcl_Interp *) iPtr,
+		    sizeof(Namespace *) * length);
+
+	    i = 0;
+	    for (entryPtr = Tcl_FirstHashEntry(nsPtr->childTablePtr, &search);
+		    entryPtr != NULL;
+		    entryPtr = Tcl_NextHashEntry(&search)) {
+		children[i] = Tcl_GetHashValue(entryPtr);
+		children[i]->refCount++;
+		i++;
+	    }
+	    for (i = 0 ; i < length ; i++) {
+		Tcl_DeleteNamespace((Tcl_Namespace *) children[i]);
+		TclNsDecrRefCount(children[i]);
+	    }
+	    TclStackFree((Tcl_Interp *) iPtr, children);
+	}
+    }
+#endif
+
+    /*
+     * Free the namespace's export pattern array.
+     */
+
+    if (nsPtr->exportArrayPtr != NULL) {
+	for (i = 0;  i < nsPtr->numExportPatterns;  i++) {
+	    ckfree(nsPtr->exportArrayPtr[i]);
+	}
+	ckfree(nsPtr->exportArrayPtr);
+	nsPtr->exportArrayPtr = NULL;
+	nsPtr->numExportPatterns = 0;
+	nsPtr->maxExportPatterns = 0;
+    }
+
+    /*
+     * Free any client data associated with the namespace.
+     */
+
+    if (nsPtr->deleteProc != NULL) {
+	nsPtr->deleteProc(nsPtr->clientData);
+    }
+    nsPtr->deleteProc = NULL;
+    nsPtr->clientData = NULL;
+
+    /*
+     * Reset the namespace's id field to ensure that this namespace won't be
+     * interpreted as valid by, e.g., the cache validation code for cached
+     * command references in Tcl_GetCommandFromObj.
+     */
+
+    nsPtr->nsId = 0;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * NamespaceFree --
+ *
+ *	Called after a namespace has been deleted, when its reference count
+ *	reaches 0. Frees the data structure representing the namespace.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+NamespaceFree(
+    register Namespace *nsPtr)	/* Points to the namespace to free. */
+{
+    /*
+     * Most of the namespace's contents are freed when the namespace is
+     * deleted by Tcl_DeleteNamespace. All that remains is to free its names
+     * (for error messages), and the structure itself.
+     */
+
+    ckfree(nsPtr->name);
+    ckfree(nsPtr->fullName);
+    ckfree(nsPtr);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclNsDecrRefCount --
+ *
+ *	Drops a reference to a namespace and frees it if the namespace has
+ *	been deleted and the last reference has just been dropped.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclNsDecrRefCount(
+    Namespace *nsPtr)
+{
+    nsPtr->refCount--;
+    if ((nsPtr->refCount == 0) && (nsPtr->flags & NS_DEAD)) {
+	NamespaceFree(nsPtr);
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_Export --
+ *
+ *	Makes all the commands matching a pattern available to later be
+ *	imported from the namespace specified by namespacePtr (or the current
+ *	namespace if namespacePtr is NULL). The specified pattern is appended
+ *	onto the namespace's export pattern list, which is optionally cleared
+ *	beforehand.
+ *
+ * Results:
+ *	Returns TCL_OK if successful, or TCL_ERROR (along with an error
+ *	message in the interpreter's result) if something goes wrong.
+ *
+ * Side effects:
+ *	Appends the export pattern onto the namespace's export list.
+ *	Optionally reset the namespace's export pattern list.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_Export(
+    Tcl_Interp *interp,		/* Current interpreter. */
+    Tcl_Namespace *namespacePtr,/* Points to the namespace from which commands
+				 * are to be exported. NULL for the current
+				 * namespace. */
+    const char *pattern,	/* String pattern indicating which commands to
+				 * export. This pattern may not include any
+				 * namespace qualifiers; only commands in the
+				 * specified namespace may be exported. */
+    int resetListFirst)		/* If nonzero, resets the namespace's export
+				 * list before appending. */
+{
+#define INIT_EXPORT_PATTERNS 5
+    Namespace *nsPtr, *exportNsPtr, *dummyPtr;
+    Namespace *currNsPtr = (Namespace *) TclGetCurrentNamespace(interp);
+    const char *simplePattern;
+    char *patternCpy;
+    int neededElems, len, i;
+
+    /*
+     * If the specified namespace is NULL, use the current namespace.
+     */
+
+    if (namespacePtr == NULL) {
+	nsPtr = (Namespace *) currNsPtr;
+    } else {
+	nsPtr = (Namespace *) namespacePtr;
+    }
+
+    /*
+     * If resetListFirst is true (nonzero), clear the namespace's export
+     * pattern list.
+     */
+
+    if (resetListFirst) {
+	if (nsPtr->exportArrayPtr != NULL) {
+	    for (i = 0;  i < nsPtr->numExportPatterns;  i++) {
+		ckfree(nsPtr->exportArrayPtr[i]);
+	    }
+	    ckfree(nsPtr->exportArrayPtr);
+	    nsPtr->exportArrayPtr = NULL;
+	    TclInvalidateNsCmdLookup(nsPtr);
+	    nsPtr->numExportPatterns = 0;
+	    nsPtr->maxExportPatterns = 0;
+	}
+    }
+
+    /*
+     * Check that the pattern doesn't have namespace qualifiers.
+     */
+
+    TclGetNamespaceForQualName(interp, pattern, nsPtr, TCL_NAMESPACE_ONLY,
+	    &exportNsPtr, &dummyPtr, &dummyPtr, &simplePattern);
+
+    if ((exportNsPtr != nsPtr) || (strcmp(pattern, simplePattern) != 0)) {
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf("invalid export pattern"
+                " \"%s\": pattern can't specify a namespace", pattern));
+	Tcl_SetErrorCode(interp, "TCL", "EXPORT", "INVALID", NULL);
+	return TCL_ERROR;
+    }
+
+    /*
+     * Make sure that we don't already have the pattern in the array
+     */
+
+    if (nsPtr->exportArrayPtr != NULL) {
+	for (i = 0;  i < nsPtr->numExportPatterns;  i++) {
+	    if (strcmp(pattern, nsPtr->exportArrayPtr[i]) == 0) {
+		/*
+		 * The pattern already exists in the list.
+		 */
+
+		return TCL_OK;
+	    }
+	}
+    }
+
+    /*
+     * Make sure there is room in the namespace's pattern array for the new
+     * pattern.
+     */
+
+    neededElems = nsPtr->numExportPatterns + 1;
+    if (neededElems > nsPtr->maxExportPatterns) {
+	nsPtr->maxExportPatterns = nsPtr->maxExportPatterns ?
+		2 * nsPtr->maxExportPatterns : INIT_EXPORT_PATTERNS;
+	nsPtr->exportArrayPtr = ckrealloc(nsPtr->exportArrayPtr,
+		sizeof(char *) * nsPtr->maxExportPatterns);
+    }
+
+    /*
+     * Add the pattern to the namespace's array of export patterns.
+     */
+
+    len = strlen(pattern);
+    patternCpy = ckalloc(len + 1);
+    memcpy(patternCpy, pattern, (unsigned) len + 1);
+
+    nsPtr->exportArrayPtr[nsPtr->numExportPatterns] = patternCpy;
+    nsPtr->numExportPatterns++;
+
+    /*
+     * The list of commands actually exported from the namespace might have
+     * changed (probably will have!) However, we do not need to recompute this
+     * just yet; next time we need the info will be soon enough.
+     */
+
+    TclInvalidateNsCmdLookup(nsPtr);
+
+    return TCL_OK;
+#undef INIT_EXPORT_PATTERNS
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_AppendExportList --
+ *
+ *	Appends onto the argument object the list of export patterns for the
+ *	specified namespace.
+ *
+ * Results:
+ *	The return value is normally TCL_OK; in this case the object
+ *	referenced by objPtr has each export pattern appended to it. If an
+ *	error occurs, TCL_ERROR is returned and the interpreter's result holds
+ *	an error message.
+ *
+ * Side effects:
+ *	If necessary, the object referenced by objPtr is converted into a list
+ *	object.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_AppendExportList(
+    Tcl_Interp *interp,		/* Interpreter used for error reporting. */
+    Tcl_Namespace *namespacePtr,/* Points to the namespace whose export
+				 * pattern list is appended onto objPtr. NULL
+				 * for the current namespace. */
+    Tcl_Obj *objPtr)		/* Points to the Tcl object onto which the
+				 * export pattern list is appended. */
+{
+    Namespace *nsPtr;
+    int i, result;
+
+    /*
+     * If the specified namespace is NULL, use the current namespace.
+     */
+
+    if (namespacePtr == NULL) {
+	nsPtr = (Namespace *) TclGetCurrentNamespace(interp);
+    } else {
+	nsPtr = (Namespace *) namespacePtr;
+    }
+
+    /*
+     * Append the export pattern list onto objPtr.
+     */
+
+    for (i = 0;  i < nsPtr->numExportPatterns;  i++) {
+	result = Tcl_ListObjAppendElement(interp, objPtr,
+		Tcl_NewStringObj(nsPtr->exportArrayPtr[i], -1));
+	if (result != TCL_OK) {
+	    return result;
+	}
+    }
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_Import --
+ *
+ *	Imports all of the commands matching a pattern into the namespace
+ *	specified by namespacePtr (or the current namespace if contextNsPtr is
+ *	NULL). This is done by creating a new command (the "imported command")
+ *	that points to the real command in its original namespace.
+ *
+ *	If matching commands are on the autoload path but haven't been loaded
+ *	yet, this command forces them to be loaded, then creates the links to
+ *	them.
+ *
+ * Results:
+ *	Returns TCL_OK if successful, or TCL_ERROR (along with an error
+ *	message in the interpreter's result) if something goes wrong.
+ *
+ * Side effects:
+ *	Creates new commands in the importing namespace. These indirect calls
+ *	back to the real command and are deleted if the real commands are
+ *	deleted.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_Import(
+    Tcl_Interp *interp,		/* Current interpreter. */
+    Tcl_Namespace *namespacePtr,/* Points to the namespace into which the
+				 * commands are to be imported. NULL for the
+				 * current namespace. */
+    const char *pattern,	/* String pattern indicating which commands to
+				 * import. This pattern should be qualified by
+				 * the name of the namespace from which to
+				 * import the command(s). */
+    int allowOverwrite)		/* If nonzero, allow existing commands to be
+				 * overwritten by imported commands. If 0,
+				 * return an error if an imported cmd
+				 * conflicts with an existing one. */
+{
+    Namespace *nsPtr, *importNsPtr, *dummyPtr;
+    const char *simplePattern;
+    register Tcl_HashEntry *hPtr;
+    Tcl_HashSearch search;
+
+    /*
+     * If the specified namespace is NULL, use the current namespace.
+     */
+
+    if (namespacePtr == NULL) {
+	nsPtr = (Namespace *) TclGetCurrentNamespace(interp);
+    } else {
+	nsPtr = (Namespace *) namespacePtr;
+    }
+
+    /*
+     * First, invoke the "auto_import" command with the pattern being
+     * imported. This command is part of the Tcl library. It looks for
+     * imported commands in autoloaded libraries and loads them in. That way,
+     * they will be found when we try to create links below.
+     *
+     * Note that we don't just call Tcl_EvalObjv() directly because we do not
+     * want absence of the command to be a failure case.
+     */
+
+    if (Tcl_FindCommand(interp,"auto_import",NULL,TCL_GLOBAL_ONLY) != NULL) {
+	Tcl_Obj *objv[2];
+	int result;
+
+	TclNewLiteralStringObj(objv[0], "auto_import");
+	objv[1] = Tcl_NewStringObj(pattern, -1);
+
+	Tcl_IncrRefCount(objv[0]);
+	Tcl_IncrRefCount(objv[1]);
+	result = Tcl_EvalObjv(interp, 2, objv, TCL_GLOBAL_ONLY);
+	Tcl_DecrRefCount(objv[0]);
+	Tcl_DecrRefCount(objv[1]);
+
+	if (result != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	Tcl_ResetResult(interp);
+    }
+
+    /*
+     * From the pattern, find the namespace from which we are importing and
+     * get the simple pattern (no namespace qualifiers or ::'s) at the end.
+     */
+
+    if (strlen(pattern) == 0) {
+	Tcl_SetObjResult(interp, Tcl_NewStringObj("empty import pattern",-1));
+	Tcl_SetErrorCode(interp, "TCL", "IMPORT", "EMPTY", NULL);
+	return TCL_ERROR;
+    }
+    TclGetNamespaceForQualName(interp, pattern, nsPtr, TCL_NAMESPACE_ONLY,
+	    &importNsPtr, &dummyPtr, &dummyPtr, &simplePattern);
+
+    if (importNsPtr == NULL) {
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+                "unknown namespace in import pattern \"%s\"", pattern));
+	Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "NAMESPACE", pattern, NULL);
+	return TCL_ERROR;
+    }
+    if (importNsPtr == nsPtr) {
+	if (pattern == simplePattern) {
+	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		    "no namespace specified in import pattern \"%s\"",
+                    pattern));
+	    Tcl_SetErrorCode(interp, "TCL", "IMPORT", "ORIGIN", NULL);
+	} else {
+	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+                    "import pattern \"%s\" tries to import from namespace"
+                    " \"%s\" into itself", pattern, importNsPtr->name));
+	    Tcl_SetErrorCode(interp, "TCL", "IMPORT", "SELF", NULL);
+	}
+	return TCL_ERROR;
+    }
+
+    /*
+     * Scan through the command table in the source namespace and look for
+     * exported commands that match the string pattern. Create an "imported
+     * command" in the current namespace for each imported command; these
+     * commands redirect their invocations to the "real" command.
+     */
+
+    if ((simplePattern != NULL) && TclMatchIsTrivial(simplePattern)) {
+	hPtr = Tcl_FindHashEntry(&importNsPtr->cmdTable, simplePattern);
+	if (hPtr == NULL) {
+	    return TCL_OK;
+	}
+	return DoImport(interp, nsPtr, hPtr, simplePattern, pattern,
+		importNsPtr, allowOverwrite);
+    }
+    for (hPtr = Tcl_FirstHashEntry(&importNsPtr->cmdTable, &search);
+	    (hPtr != NULL); hPtr = Tcl_NextHashEntry(&search)) {
+	char *cmdName = Tcl_GetHashKey(&importNsPtr->cmdTable, hPtr);
+
+	if (Tcl_StringMatch(cmdName, simplePattern) &&
+		DoImport(interp, nsPtr, hPtr, cmdName, pattern, importNsPtr,
+		allowOverwrite) == TCL_ERROR) {
+	    return TCL_ERROR;
+	}
+    }
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * DoImport --
+ *
+ *	Import a particular command from one namespace into another. Helper
+ *	for Tcl_Import().
+ *
+ * Results:
+ *	Standard Tcl result code. If TCL_ERROR, appends an error message to
+ *	the interpreter result.
+ *
+ * Side effects:
+ *	A new command is created in the target namespace unless this is a
+ *	reimport of exactly the same command as before.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+DoImport(
+    Tcl_Interp *interp,
+    Namespace *nsPtr,
+    Tcl_HashEntry *hPtr,
+    const char *cmdName,
+    const char *pattern,
+    Namespace *importNsPtr,
+    int allowOverwrite)
+{
+    int i = 0, exported = 0;
+    Tcl_HashEntry *found;
+
+    /*
+     * The command cmdName in the source namespace matches the pattern. Check
+     * whether it was exported. If it wasn't, we ignore it.
+     */
+
+    while (!exported && (i < importNsPtr->numExportPatterns)) {
+	exported |= Tcl_StringMatch(cmdName,
+		importNsPtr->exportArrayPtr[i++]);
+    }
+    if (!exported) {
+	return TCL_OK;
+    }
+
+    /*
+     * Unless there is a name clash, create an imported command in the current
+     * namespace that refers to cmdPtr.
+     */
+
+    found = Tcl_FindHashEntry(&nsPtr->cmdTable, cmdName);
+    if ((found == NULL) || allowOverwrite) {
+	/*
+	 * Create the imported command and its client data. To create the new
+	 * command in the current namespace, generate a fully qualified name
+	 * for it.
+	 */
+
+	Tcl_DString ds;
+	Tcl_Command importedCmd;
+	ImportedCmdData *dataPtr;
+	Command *cmdPtr;
+	ImportRef *refPtr;
+
+	Tcl_DStringInit(&ds);
+	Tcl_DStringAppend(&ds, nsPtr->fullName, -1);
+	if (nsPtr != ((Interp *) interp)->globalNsPtr) {
+	    TclDStringAppendLiteral(&ds, "::");
+	}
+	Tcl_DStringAppend(&ds, cmdName, -1);
+
+	/*
+	 * Check whether creating the new imported command in the current
+	 * namespace would create a cycle of imported command references.
+	 */
+
+	cmdPtr = Tcl_GetHashValue(hPtr);
+	if (found != NULL && cmdPtr->deleteProc == DeleteImportedCmd) {
+	    Command *overwrite = Tcl_GetHashValue(found);
+	    Command *linkCmd = cmdPtr;
+
+	    while (linkCmd->deleteProc == DeleteImportedCmd) {
+		dataPtr = linkCmd->objClientData;
+		linkCmd = dataPtr->realCmdPtr;
+		if (overwrite == linkCmd) {
+		    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+                            "import pattern \"%s\" would create a loop"
+                            " containing command \"%s\"",
+                            pattern, Tcl_DStringValue(&ds)));
+		    Tcl_DStringFree(&ds);
+		    Tcl_SetErrorCode(interp, "TCL", "IMPORT", "LOOP", NULL);
+		    return TCL_ERROR;
+		}
+	    }
+	}
+
+	dataPtr = ckalloc(sizeof(ImportedCmdData));
+	importedCmd = Tcl_NRCreateCommand(interp, Tcl_DStringValue(&ds),
+		InvokeImportedCmd, InvokeImportedNRCmd, dataPtr,
+		DeleteImportedCmd);
+	dataPtr->realCmdPtr = cmdPtr;
+	dataPtr->selfPtr = (Command *) importedCmd;
+	dataPtr->selfPtr->compileProc = cmdPtr->compileProc;
+	Tcl_DStringFree(&ds);
+
+	/*
+	 * Create an ImportRef structure describing this new import command
+	 * and add it to the import ref list in the "real" command.
+	 */
+
+	refPtr = ckalloc(sizeof(ImportRef));
+	refPtr->importedCmdPtr = (Command *) importedCmd;
+	refPtr->nextPtr = cmdPtr->importRefPtr;
+	cmdPtr->importRefPtr = refPtr;
+    } else {
+	Command *overwrite = Tcl_GetHashValue(found);
+
+	if (overwrite->deleteProc == DeleteImportedCmd) {
+	    ImportedCmdData *dataPtr = overwrite->objClientData;
+
+	    if (dataPtr->realCmdPtr == Tcl_GetHashValue(hPtr)) {
+		/*
+		 * Repeated import of same command is acceptable.
+		 */
+
+		return TCL_OK;
+	    }
+	}
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+                "can't import command \"%s\": already exists", cmdName));
+	Tcl_SetErrorCode(interp, "TCL", "IMPORT", "OVERWRITE", NULL);
+	return TCL_ERROR;
+    }
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_ForgetImport --
+ *
+ *	Deletes commands previously imported into the namespace indicated.
+ *	The by namespacePtr, or the current namespace of interp, when
+ *	namespacePtr is NULL. The pattern controls which imported commands are
+ *	deleted. A simple pattern, one without namespace separators, matches
+ *	the current command names of imported commands in the namespace.
+ *	Matching imported commands are deleted. A qualified pattern is
+ *	interpreted as deletion selection on the basis of where the command is
+ *	imported from. The original command and "first link" command for each
+ *	imported command are determined, and they are matched against the
+ *	pattern. A match leads to deletion of the imported command.
+ *
+ * Results:
+ *	Returns TCL_ERROR and records an error message in the interp result if
+ *	a namespace qualified pattern refers to a namespace that does not
+ *	exist. Otherwise, returns TCL_OK.
+ *
+ * Side effects:
+ *	May delete commands.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_ForgetImport(
+    Tcl_Interp *interp,		/* Current interpreter. */
+    Tcl_Namespace *namespacePtr,/* Points to the namespace from which
+				 * previously imported commands should be
+				 * removed. NULL for current namespace. */
+    const char *pattern)	/* String pattern indicating which imported
+				 * commands to remove. */
+{
+    Namespace *nsPtr, *sourceNsPtr, *dummyPtr;
+    const char *simplePattern;
+    char *cmdName;
+    register Tcl_HashEntry *hPtr;
+    Tcl_HashSearch search;
+
+    /*
+     * If the specified namespace is NULL, use the current namespace.
+     */
+
+    if (namespacePtr == NULL) {
+	nsPtr = (Namespace *) TclGetCurrentNamespace(interp);
+    } else {
+	nsPtr = (Namespace *) namespacePtr;
+    }
+
+    /*
+     * Parse the pattern into its namespace-qualification (if any) and the
+     * simple pattern.
+     */
+
+    TclGetNamespaceForQualName(interp, pattern, nsPtr, TCL_NAMESPACE_ONLY,
+	    &sourceNsPtr, &dummyPtr, &dummyPtr, &simplePattern);
+
+    if (sourceNsPtr == NULL) {
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		"unknown namespace in namespace forget pattern \"%s\"",
+		pattern));
+	Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "NAMESPACE", pattern, NULL);
+	return TCL_ERROR;
+    }
+
+    if (strcmp(pattern, simplePattern) == 0) {
+	/*
+	 * The pattern is simple. Delete any imported commands that match it.
+	 */
+
+	if (TclMatchIsTrivial(simplePattern)) {
+	    hPtr = Tcl_FindHashEntry(&nsPtr->cmdTable, simplePattern);
+	    if (hPtr != NULL) {
+		Command *cmdPtr = Tcl_GetHashValue(hPtr);
+
+		if (cmdPtr && (cmdPtr->deleteProc == DeleteImportedCmd)) {
+		    Tcl_DeleteCommandFromToken(interp, (Tcl_Command) cmdPtr);
+		}
+	    }
+	    return TCL_OK;
+	}
+	for (hPtr = Tcl_FirstHashEntry(&nsPtr->cmdTable, &search);
+		(hPtr != NULL); hPtr = Tcl_NextHashEntry(&search)) {
+	    Command *cmdPtr = Tcl_GetHashValue(hPtr);
+
+	    if (cmdPtr->deleteProc != DeleteImportedCmd) {
+		continue;
+	    }
+	    cmdName = Tcl_GetHashKey(&nsPtr->cmdTable, hPtr);
+	    if (Tcl_StringMatch(cmdName, simplePattern)) {
+		Tcl_DeleteCommandFromToken(interp, (Tcl_Command) cmdPtr);
+	    }
+	}
+	return TCL_OK;
+    }
+
+    /*
+     * The pattern was namespace-qualified.
+     */
+
+    for (hPtr = Tcl_FirstHashEntry(&nsPtr->cmdTable, &search); (hPtr != NULL);
+	    hPtr = Tcl_NextHashEntry(&search)) {
+	Tcl_CmdInfo info;
+	Tcl_Command token = Tcl_GetHashValue(hPtr);
+	Tcl_Command origin = TclGetOriginalCommand(token);
+
+	if (Tcl_GetCommandInfoFromToken(origin, &info) == 0) {
+	    continue;			/* Not an imported command. */
+	}
+	if (info.namespacePtr != (Tcl_Namespace *) sourceNsPtr) {
+	    /*
+	     * Original not in namespace we're matching. Check the first link
+	     * in the import chain.
+	     */
+
+	    Command *cmdPtr = (Command *) token;
+	    ImportedCmdData *dataPtr = cmdPtr->objClientData;
+	    Tcl_Command firstToken = (Tcl_Command) dataPtr->realCmdPtr;
+
+	    if (firstToken == origin) {
+		continue;
+	    }
+	    Tcl_GetCommandInfoFromToken(firstToken, &info);
+	    if (info.namespacePtr != (Tcl_Namespace *) sourceNsPtr) {
+		continue;
+	    }
+	    origin = firstToken;
+	}
+	if (Tcl_StringMatch(Tcl_GetCommandName(NULL, origin), simplePattern)){
+	    Tcl_DeleteCommandFromToken(interp, token);
+	}
+    }
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclGetOriginalCommand --
+ *
+ *	An imported command is created in an namespace when a "real" command
+ *	is imported from another namespace. If the specified command is an
+ *	imported command, this function returns the original command it refers
+ *	to.
+ *
+ * Results:
+ *	If the command was imported into a sequence of namespaces a, b,...,n
+ *	where each successive namespace just imports the command from the
+ *	previous namespace, this function returns the Tcl_Command token in the
+ *	first namespace, a. Otherwise, if the specified command is not an
+ *	imported command, the function returns NULL.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_Command
+TclGetOriginalCommand(
+    Tcl_Command command)	/* The imported command for which the original
+				 * command should be returned. */
+{
+    register Command *cmdPtr = (Command *) command;
+    ImportedCmdData *dataPtr;
+
+    if (cmdPtr->deleteProc != DeleteImportedCmd) {
+	return NULL;
+    }
+
+    while (cmdPtr->deleteProc == DeleteImportedCmd) {
+	dataPtr = cmdPtr->objClientData;
+	cmdPtr = dataPtr->realCmdPtr;
+    }
+    return (Tcl_Command) cmdPtr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * InvokeImportedCmd --
+ *
+ *	Invoked by Tcl whenever the user calls an imported command that was
+ *	created by Tcl_Import. Finds the "real" command (in another
+ *	namespace), and passes control to it.
+ *
+ * Results:
+ *	Returns TCL_OK if successful, and TCL_ERROR if anything goes wrong.
+ *
+ * Side effects:
+ *	Returns a result in the interpreter's result object. If anything goes
+ *	wrong, the result object is set to an error message.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+InvokeImportedNRCmd(
+    ClientData clientData,	/* Points to the imported command's
+				 * ImportedCmdData structure. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* The argument objects. */
+{
+    ImportedCmdData *dataPtr = clientData;
+    Command *realCmdPtr = dataPtr->realCmdPtr;
+
+    TclSkipTailcall(interp);
+    return TclNREvalObjv(interp, objc, objv, TCL_EVAL_NOERR, realCmdPtr);
+}
+
+static int
+InvokeImportedCmd(
+    ClientData clientData,	/* Points to the imported command's
+				 * ImportedCmdData structure. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* The argument objects. */
+{
+    return Tcl_NRCallObjProc(interp, InvokeImportedNRCmd, clientData,
+	    objc, objv);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * DeleteImportedCmd --
+ *
+ *	Invoked by Tcl whenever an imported command is deleted. The "real"
+ *	command keeps a list of all the imported commands that refer to it, so
+ *	those imported commands can be deleted when the real command is
+ *	deleted. This function removes the imported command reference from the
+ *	real command's list, and frees up the memory associated with the
+ *	imported command.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Removes the imported command from the real command's import list.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+DeleteImportedCmd(
+    ClientData clientData)	/* Points to the imported command's
+				 * ImportedCmdData structure. */
+{
+    ImportedCmdData *dataPtr = clientData;
+    Command *realCmdPtr = dataPtr->realCmdPtr;
+    Command *selfPtr = dataPtr->selfPtr;
+    register ImportRef *refPtr, *prevPtr;
+
+    prevPtr = NULL;
+    for (refPtr = realCmdPtr->importRefPtr; refPtr != NULL;
+	    refPtr = refPtr->nextPtr) {
+	if (refPtr->importedCmdPtr == selfPtr) {
+	    /*
+	     * Remove *refPtr from real command's list of imported commands
+	     * that refer to it.
+	     */
+
+	    if (prevPtr == NULL) { /* refPtr is first in list. */
+		realCmdPtr->importRefPtr = refPtr->nextPtr;
+	    } else {
+		prevPtr->nextPtr = refPtr->nextPtr;
+	    }
+	    ckfree(refPtr);
+	    ckfree(dataPtr);
+	    return;
+	}
+	prevPtr = refPtr;
+    }
+
+    Tcl_Panic("DeleteImportedCmd: did not find cmd in real cmd's list of import references");
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclGetNamespaceForQualName --
+ *
+ *	Given a qualified name specifying a command, variable, or namespace,
+ *	and a namespace in which to resolve the name, this function returns a
+ *	pointer to the namespace that contains the item. A qualified name
+ *	consists of the "simple" name of an item qualified by the names of an
+ *	arbitrary number of containing namespace separated by "::"s. If the
+ *	qualified name starts with "::", it is interpreted absolutely from the
+ *	global namespace. Otherwise, it is interpreted relative to the
+ *	namespace specified by cxtNsPtr if it is non-NULL. If cxtNsPtr is
+ *	NULL, the name is interpreted relative to the current namespace.
+ *
+ *	A relative name like "foo::bar::x" can be found starting in either the
+ *	current namespace or in the global namespace. So each search usually
+ *	follows two tracks, and two possible namespaces are returned. If the
+ *	function sets either *nsPtrPtr or *altNsPtrPtr to NULL, then that path
+ *	failed.
+ *
+ *	If "flags" contains TCL_GLOBAL_ONLY, the relative qualified name is
+ *	sought only in the global :: namespace. The alternate search (also)
+ *	starting from the global namespace is ignored and *altNsPtrPtr is set
+ *	NULL.
+ *
+ *	If "flags" contains TCL_NAMESPACE_ONLY, the relative qualified name is
+ *	sought only in the namespace specified by cxtNsPtr. The alternate
+ *	search starting from the global namespace is ignored and *altNsPtrPtr
+ *	is set NULL. If both TCL_GLOBAL_ONLY and TCL_NAMESPACE_ONLY are
+ *	specified, TCL_GLOBAL_ONLY is ignored and the search starts from the
+ *	namespace specified by cxtNsPtr.
+ *
+ *	If "flags" contains TCL_CREATE_NS_IF_UNKNOWN, all namespace components
+ *	of the qualified name that cannot be found are automatically created
+ *	within their specified parent. This makes sure that functions like
+ *	Tcl_CreateCommand always succeed. There is no alternate search path,
+ *	so *altNsPtrPtr is set NULL.
+ *
+ *	If "flags" contains TCL_FIND_ONLY_NS, the qualified name is treated as
+ *	a reference to a namespace, and the entire qualified name is followed.
+ *	If the name is relative, the namespace is looked up only in the
+ *	current namespace. A pointer to the namespace is stored in *nsPtrPtr
+ *	and NULL is stored in *simpleNamePtr. Otherwise, if TCL_FIND_ONLY_NS
+ *	is not specified, only the leading components are treated as namespace
+ *	names, and a pointer to the simple name of the final component is
+ *	stored in *simpleNamePtr.
+ *
+ * Results:
+ *	It sets *nsPtrPtr and *altNsPtrPtr to point to the two possible
+ *	namespaces which represent the last (containing) namespace in the
+ *	qualified name. If the function sets either *nsPtrPtr or *altNsPtrPtr
+ *	to NULL, then the search along that path failed. The function also
+ *	stores a pointer to the simple name of the final component in
+ *	*simpleNamePtr. If the qualified name is "::" or was treated as a
+ *	namespace reference (TCL_FIND_ONLY_NS), the function stores a pointer
+ *	to the namespace in *nsPtrPtr, NULL in *altNsPtrPtr, and sets
+ *	*simpleNamePtr to point to an empty string.
+ *
+ *	If there is an error, this function returns TCL_ERROR. If "flags"
+ *	contains TCL_LEAVE_ERR_MSG, an error message is returned in the
+ *	interpreter's result object. Otherwise, the interpreter's result
+ *	object is left unchanged.
+ *
+ *	*actualCxtPtrPtr is set to the actual context namespace. It is set to
+ *	the input context namespace pointer in cxtNsPtr. If cxtNsPtr is NULL,
+ *	it is set to the current namespace context.
+ *
+ *	For backwards compatibility with the TclPro byte code loader, this
+ *	function always returns TCL_OK.
+ *
+ * Side effects:
+ *	If "flags" contains TCL_CREATE_NS_IF_UNKNOWN, new namespaces may be
+ *	created.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclGetNamespaceForQualName(
+    Tcl_Interp *interp,		/* Interpreter in which to find the namespace
+				 * containing qualName. */
+    const char *qualName,	/* A namespace-qualified name of an command,
+				 * variable, or namespace. */
+    Namespace *cxtNsPtr,	/* The namespace in which to start the search
+				 * for qualName's namespace. If NULL start
+				 * from the current namespace. Ignored if
+				 * TCL_GLOBAL_ONLY is set. */
+    int flags,			/* Flags controlling the search: an OR'd
+				 * combination of TCL_GLOBAL_ONLY,
+				 * TCL_NAMESPACE_ONLY, TCL_FIND_ONLY_NS, and
+				 * TCL_CREATE_NS_IF_UNKNOWN. */
+    Namespace **nsPtrPtr,	/* Address where function stores a pointer to
+				 * containing namespace if qualName is found
+				 * starting from *cxtNsPtr or, if
+				 * TCL_GLOBAL_ONLY is set, if qualName is
+				 * found in the global :: namespace. NULL is
+				 * stored otherwise. */
+    Namespace **altNsPtrPtr,	/* Address where function stores a pointer to
+				 * containing namespace if qualName is found
+				 * starting from the global :: namespace.
+				 * NULL is stored if qualName isn't found
+				 * starting from :: or if the TCL_GLOBAL_ONLY,
+				 * TCL_NAMESPACE_ONLY, TCL_FIND_ONLY_NS,
+				 * TCL_CREATE_NS_IF_UNKNOWN flag is set. */
+    Namespace **actualCxtPtrPtr,/* Address where function stores a pointer to
+				 * the actual namespace from which the search
+				 * started. This is either cxtNsPtr, the ::
+				 * namespace if TCL_GLOBAL_ONLY was specified,
+				 * or the current namespace if cxtNsPtr was
+				 * NULL. */
+    const char **simpleNamePtr) /* Address where function stores the simple
+				 * name at end of the qualName, or NULL if
+				 * qualName is "::" or the flag
+				 * TCL_FIND_ONLY_NS was specified. */
+{
+    Interp *iPtr = (Interp *) interp;
+    Namespace *nsPtr = cxtNsPtr;
+    Namespace *altNsPtr;
+    Namespace *globalNsPtr = iPtr->globalNsPtr;
+    const char *start, *end;
+    const char *nsName;
+    Tcl_HashEntry *entryPtr;
+    Tcl_DString buffer;
+    int len;
+
+    /*
+     * Determine the context namespace nsPtr in which to start the primary
+     * search. If the qualName name starts with a "::" or TCL_GLOBAL_ONLY was
+     * specified, search from the global namespace. Otherwise, use the
+     * namespace given in cxtNsPtr, or if that is NULL, use the current
+     * namespace context. Note that we always treat two or more adjacent ":"s
+     * as a namespace separator.
+     */
+
+    if (flags & TCL_GLOBAL_ONLY) {
+	nsPtr = globalNsPtr;
+    } else if (nsPtr == NULL) {
+	nsPtr = iPtr->varFramePtr->nsPtr;
+    }
+
+    start = qualName;			/* Points to start of qualifying
+					 * namespace. */
+    if ((*qualName == ':') && (*(qualName+1) == ':')) {
+	start = qualName+2;		/* Skip over the initial :: */
+	while (*start == ':') {
+	    start++;			/* Skip over a subsequent : */
+	}
+	nsPtr = globalNsPtr;
+	if (*start == '\0') {		/* qualName is just two or more
+					 * ":"s. */
+	    *nsPtrPtr = globalNsPtr;
+	    *altNsPtrPtr = NULL;
+	    *actualCxtPtrPtr = globalNsPtr;
+	    *simpleNamePtr = start;	/* Points to empty string. */
+	    return TCL_OK;
+	}
+    }
+    *actualCxtPtrPtr = nsPtr;
+
+    /*
+     * Start an alternate search path starting with the global namespace.
+     * However, if the starting context is the global namespace, or if the
+     * flag is set to search only the namespace *cxtNsPtr, ignore the
+     * alternate search path.
+     */
+
+    altNsPtr = globalNsPtr;
+    if ((nsPtr == globalNsPtr)
+	    || (flags & (TCL_NAMESPACE_ONLY | TCL_FIND_ONLY_NS))) {
+	altNsPtr = NULL;
+    }
+
+    /*
+     * Loop to resolve each namespace qualifier in qualName.
+     */
+
+    Tcl_DStringInit(&buffer);
+    end = start;
+    while (*start != '\0') {
+	/*
+	 * Find the next namespace qualifier (i.e., a name ending in "::") or
+	 * the end of the qualified name (i.e., a name ending in "\0"). Set
+	 * len to the number of characters, starting from start, in the name;
+	 * set end to point after the "::"s or at the "\0".
+	 */
+
+	len = 0;
+	for (end = start;  *end != '\0';  end++) {
+	    if ((*end == ':') && (*(end+1) == ':')) {
+		end += 2;		/* Skip over the initial :: */
+		while (*end == ':') {
+		    end++;		/* Skip over the subsequent : */
+		}
+		break;			/* Exit for loop; end is after ::'s */
+	    }
+	    len++;
+	}
+
+	if (*end=='\0' && !(end-start>=2 && *(end-1)==':' && *(end-2)==':')) {
+	    /*
+	     * qualName ended with a simple name at start. If TCL_FIND_ONLY_NS
+	     * was specified, look this up as a namespace. Otherwise, start is
+	     * the name of a cmd or var and we are done.
+	     */
+
+	    if (flags & TCL_FIND_ONLY_NS) {
+		nsName = start;
+	    } else {
+		*nsPtrPtr = nsPtr;
+		*altNsPtrPtr = altNsPtr;
+		*simpleNamePtr = start;
+		Tcl_DStringFree(&buffer);
+		return TCL_OK;
+	    }
+	} else {
+	    /*
+	     * start points to the beginning of a namespace qualifier ending
+	     * in "::". end points to the start of a name in that namespace
+	     * that might be empty. Copy the namespace qualifier to a buffer
+	     * so it can be null terminated. We can't modify the incoming
+	     * qualName since it may be a string constant.
+	     */
+
+	    TclDStringClear(&buffer);
+	    Tcl_DStringAppend(&buffer, start, len);
+	    nsName = Tcl_DStringValue(&buffer);
+	}
+
+	/*
+	 * Look up the namespace qualifier nsName in the current namespace
+	 * context. If it isn't found but TCL_CREATE_NS_IF_UNKNOWN is set,
+	 * create that qualifying namespace. This is needed for functions like
+	 * Tcl_CreateCommand that cannot fail.
+	 */
+
+	if (nsPtr != NULL) {
+#ifndef BREAK_NAMESPACE_COMPAT
+	    entryPtr = Tcl_FindHashEntry(&nsPtr->childTable, nsName);
+#else
+	    if (nsPtr->childTablePtr == NULL) {
+		entryPtr = NULL;
+	    } else {
+		entryPtr = Tcl_FindHashEntry(nsPtr->childTablePtr, nsName);
+	    }
+#endif
+	    if (entryPtr != NULL) {
+		nsPtr = Tcl_GetHashValue(entryPtr);
+	    } else if (flags & TCL_CREATE_NS_IF_UNKNOWN) {
+		Tcl_CallFrame *framePtr;
+
+		(void) TclPushStackFrame(interp, &framePtr,
+			(Tcl_Namespace *) nsPtr, /*isProcCallFrame*/ 0);
+
+		nsPtr = (Namespace *)
+			Tcl_CreateNamespace(interp, nsName, NULL, NULL);
+		TclPopStackFrame(interp);
+
+		if (nsPtr == NULL) {
+		    Tcl_Panic("Could not create namespace '%s'", nsName);
+		}
+	    } else {			/* Namespace not found and was not
+					 * created. */
+		nsPtr = NULL;
+	    }
+	}
+
+	/*
+	 * Look up the namespace qualifier in the alternate search path too.
+	 */
+
+	if (altNsPtr != NULL) {
+#ifndef BREAK_NAMESPACE_COMPAT
+	    entryPtr = Tcl_FindHashEntry(&altNsPtr->childTable, nsName);
+#else
+	    if (altNsPtr->childTablePtr != NULL) {
+		entryPtr = Tcl_FindHashEntry(altNsPtr->childTablePtr, nsName);
+	    } else {
+		entryPtr = NULL;
+	    }
+#endif
+	    if (entryPtr != NULL) {
+		altNsPtr = Tcl_GetHashValue(entryPtr);
+	    } else {
+		altNsPtr = NULL;
+	    }
+	}
+
+	/*
+	 * If both search paths have failed, return NULL results.
+	 */
+
+	if ((nsPtr == NULL) && (altNsPtr == NULL)) {
+	    *nsPtrPtr = NULL;
+	    *altNsPtrPtr = NULL;
+	    *simpleNamePtr = NULL;
+	    Tcl_DStringFree(&buffer);
+	    return TCL_OK;
+	}
+
+	start = end;
+    }
+
+    /*
+     * We ignore trailing "::"s in a namespace name, but in a command or
+     * variable name, trailing "::"s refer to the cmd or var named {}.
+     */
+
+    if ((flags & TCL_FIND_ONLY_NS) || (end>start && *(end-1)!=':')) {
+	*simpleNamePtr = NULL;		/* Found namespace name. */
+    } else {
+	*simpleNamePtr = end;		/* Found cmd/var: points to empty
+					 * string. */
+    }
+
+    /*
+     * As a special case, if we are looking for a namespace and qualName is ""
+     * and the current active namespace (nsPtr) is not the global namespace,
+     * return NULL (no namespace was found). This is because namespaces can
+     * not have empty names except for the global namespace.
+     */
+
+    if ((flags & TCL_FIND_ONLY_NS) && (*qualName == '\0')
+	    && (nsPtr != globalNsPtr)) {
+	nsPtr = NULL;
+    }
+
+    *nsPtrPtr = nsPtr;
+    *altNsPtrPtr = altNsPtr;
+    Tcl_DStringFree(&buffer);
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_FindNamespace --
+ *
+ *	Searches for a namespace.
+ *
+ * Results:
+ *	Returns a pointer to the namespace if it is found. Otherwise, returns
+ *	NULL and leaves an error message in the interpreter's result object if
+ *	"flags" contains TCL_LEAVE_ERR_MSG.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_Namespace *
+Tcl_FindNamespace(
+    Tcl_Interp *interp,		/* The interpreter in which to find the
+				 * namespace. */
+    const char *name,		/* Namespace name. If it starts with "::",
+				 * will be looked up in global namespace.
+				 * Else, looked up first in contextNsPtr
+				 * (current namespace if contextNsPtr is
+				 * NULL), then in global namespace. */
+    Tcl_Namespace *contextNsPtr,/* Ignored if TCL_GLOBAL_ONLY flag is set or
+				 * if the name starts with "::". Otherwise,
+				 * points to namespace in which to resolve
+				 * name; if NULL, look up name in the current
+				 * namespace. */
+    register int flags)		/* Flags controlling namespace lookup: an OR'd
+				 * combination of TCL_GLOBAL_ONLY and
+				 * TCL_LEAVE_ERR_MSG flags. */
+{
+    Namespace *nsPtr, *dummy1Ptr, *dummy2Ptr;
+    const char *dummy;
+
+    /*
+     * Find the namespace(s) that contain the specified namespace name. Add
+     * the TCL_FIND_ONLY_NS flag to resolve the name all the way down to its
+     * last component, a namespace.
+     */
+
+    TclGetNamespaceForQualName(interp, name, (Namespace *) contextNsPtr,
+	    flags|TCL_FIND_ONLY_NS, &nsPtr, &dummy1Ptr, &dummy2Ptr, &dummy);
+
+    if (nsPtr != NULL) {
+	return (Tcl_Namespace *) nsPtr;
+    }
+
+    if (flags & TCL_LEAVE_ERR_MSG) {
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+                "unknown namespace \"%s\"", name));
+	Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "NAMESPACE", name, NULL);
+    }
+    return NULL;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_FindCommand --
+ *
+ *	Searches for a command.
+ *
+ * Results:
+ *	Returns a token for the command if it is found. Otherwise, if it can't
+ *	be found or there is an error, returns NULL and leaves an error
+ *	message in the interpreter's result object if "flags" contains
+ *	TCL_LEAVE_ERR_MSG.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_Command
+Tcl_FindCommand(
+    Tcl_Interp *interp,		/* The interpreter in which to find the
+				 * command and to report errors. */
+    const char *name,		/* Command's name. If it starts with "::",
+				 * will be looked up in global namespace.
+				 * Else, looked up first in contextNsPtr
+				 * (current namespace if contextNsPtr is
+				 * NULL), then in global namespace. */
+    Tcl_Namespace *contextNsPtr,/* Ignored if TCL_GLOBAL_ONLY flag set.
+				 * Otherwise, points to namespace in which to
+				 * resolve name. If NULL, look up name in the
+				 * current namespace. */
+    int flags)			/* An OR'd combination of flags:
+				 * TCL_GLOBAL_ONLY (look up name only in
+				 * global namespace), TCL_NAMESPACE_ONLY (look
+				 * up only in contextNsPtr, or the current
+				 * namespace if contextNsPtr is NULL), and
+				 * TCL_LEAVE_ERR_MSG. If both TCL_GLOBAL_ONLY
+				 * and TCL_NAMESPACE_ONLY are given,
+				 * TCL_GLOBAL_ONLY is ignored. */
+{
+    Interp *iPtr = (Interp *) interp;
+    Namespace *cxtNsPtr;
+    register Tcl_HashEntry *entryPtr;
+    register Command *cmdPtr;
+    const char *simpleName;
+    int result;
+
+    /*
+     * If this namespace has a command resolver, then give it first crack at
+     * the command resolution. If the interpreter has any command resolvers,
+     * consult them next. The command resolver functions may return a
+     * Tcl_Command value, they may signal to continue onward, or they may
+     * signal an error.
+     */
+
+    if ((flags & TCL_GLOBAL_ONLY) || !strncmp(name, "::", 2)) {
+	cxtNsPtr = (Namespace *) TclGetGlobalNamespace(interp);
+    } else if (contextNsPtr != NULL) {
+	cxtNsPtr = (Namespace *) contextNsPtr;
+    } else {
+	cxtNsPtr = (Namespace *) TclGetCurrentNamespace(interp);
+    }
+
+    if (cxtNsPtr->cmdResProc != NULL || iPtr->resolverPtr != NULL) {
+	ResolverScheme *resPtr = iPtr->resolverPtr;
+	Tcl_Command cmd;
+
+	if (cxtNsPtr->cmdResProc) {
+	    result = cxtNsPtr->cmdResProc(interp, name,
+		    (Tcl_Namespace *) cxtNsPtr, flags, &cmd);
+	} else {
+	    result = TCL_CONTINUE;
+	}
+
+	while (result == TCL_CONTINUE && resPtr) {
+	    if (resPtr->cmdResProc) {
+		result = resPtr->cmdResProc(interp, name,
+			(Tcl_Namespace *) cxtNsPtr, flags, &cmd);
+	    }
+	    resPtr = resPtr->nextPtr;
+	}
+
+	if (result == TCL_OK) {
+	    return cmd;
+	} else if (result != TCL_CONTINUE) {
+	    return NULL;
+	}
+    }
+
+    /*
+     * Find the namespace(s) that contain the command.
+     */
+
+    cmdPtr = NULL;
+    if (cxtNsPtr->commandPathLength!=0 && strncmp(name, "::", 2)
+	    && !(flags & TCL_NAMESPACE_ONLY)) {
+	int i;
+	Namespace *pathNsPtr, *realNsPtr, *dummyNsPtr;
+
+	(void) TclGetNamespaceForQualName(interp, name, cxtNsPtr,
+		TCL_NAMESPACE_ONLY, &realNsPtr, &dummyNsPtr, &dummyNsPtr,
+		&simpleName);
+	if ((realNsPtr != NULL) && (simpleName != NULL)) {
+	    if ((cxtNsPtr == realNsPtr)
+		    || !(realNsPtr->flags & NS_DYING)) {
+		entryPtr = Tcl_FindHashEntry(&realNsPtr->cmdTable, simpleName);
+		if (entryPtr != NULL) {
+		    cmdPtr = Tcl_GetHashValue(entryPtr);
+		}
+	    }
+	}
+
+	/*
+	 * Next, check along the path.
+	 */
+
+	for (i=0 ; i<cxtNsPtr->commandPathLength && cmdPtr==NULL ; i++) {
+	    pathNsPtr = cxtNsPtr->commandPathArray[i].nsPtr;
+	    if (pathNsPtr == NULL) {
+		continue;
+	    }
+	    (void) TclGetNamespaceForQualName(interp, name, pathNsPtr,
+		    TCL_NAMESPACE_ONLY, &realNsPtr, &dummyNsPtr, &dummyNsPtr,
+		    &simpleName);
+	    if ((realNsPtr != NULL) && (simpleName != NULL)
+		    && !(realNsPtr->flags & NS_DYING)) {
+		entryPtr = Tcl_FindHashEntry(&realNsPtr->cmdTable, simpleName);
+		if (entryPtr != NULL) {
+		    cmdPtr = Tcl_GetHashValue(entryPtr);
+		}
+	    }
+	}
+
+	/*
+	 * If we've still not found the command, look in the global namespace
+	 * as a last resort.
+	 */
+
+	if (cmdPtr == NULL) {
+	    (void) TclGetNamespaceForQualName(interp, name, NULL,
+		    TCL_GLOBAL_ONLY, &realNsPtr, &dummyNsPtr, &dummyNsPtr,
+		    &simpleName);
+	    if ((realNsPtr != NULL) && (simpleName != NULL)
+		    && !(realNsPtr->flags & NS_DYING)) {
+		entryPtr = Tcl_FindHashEntry(&realNsPtr->cmdTable, simpleName);
+		if (entryPtr != NULL) {
+		    cmdPtr = Tcl_GetHashValue(entryPtr);
+		}
+	    }
+	}
+    } else {
+	Namespace *nsPtr[2];
+	register int search;
+
+	TclGetNamespaceForQualName(interp, name, (Namespace *) contextNsPtr,
+		flags, &nsPtr[0], &nsPtr[1], &cxtNsPtr, &simpleName);
+
+	/*
+	 * Look for the command in the command table of its namespace. Be sure
+	 * to check both possible search paths: from the specified namespace
+	 * context and from the global namespace.
+	 */
+
+	for (search = 0;  (search < 2) && (cmdPtr == NULL);  search++) {
+	    if ((nsPtr[search] != NULL) && (simpleName != NULL)) {
+		entryPtr = Tcl_FindHashEntry(&nsPtr[search]->cmdTable,
+			simpleName);
+		if (entryPtr != NULL) {
+		    cmdPtr = Tcl_GetHashValue(entryPtr);
+		}
+	    }
+	}
+    }
+
+    if (cmdPtr != NULL) {
+	return (Tcl_Command) cmdPtr;
+    }
+
+    if (flags & TCL_LEAVE_ERR_MSG) {
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+                "unknown command \"%s\"", name));
+	Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "COMMAND", name, NULL);
+    }
+    return NULL;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclResetShadowedCmdRefs --
+ *
+ *	Called when a command is added to a namespace to check for existing
+ *	command references that the new command may invalidate. Consider the
+ *	following cases that could happen when you add a command "foo" to a
+ *	namespace "b":
+ *	   1. It could shadow a command named "foo" at the global scope. If
+ *	      it does, all command references in the namespace "b" are
+ *	      suspect.
+ *	   2. Suppose the namespace "b" resides in a namespace "a". Then to
+ *	      "a" the new command "b::foo" could shadow another command
+ *	      "b::foo" in the global namespace. If so, then all command
+ *	      references in "a" * are suspect.
+ *	The same checks are applied to all parent namespaces, until we reach
+ *	the global :: namespace.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	If the new command shadows an existing command, the cmdRefEpoch
+ *	counter is incremented in each namespace that sees the shadow. This
+ *	invalidates all command references that were previously cached in that
+ *	namespace. The next time the commands are used, they are resolved from
+ *	scratch.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclResetShadowedCmdRefs(
+    Tcl_Interp *interp,		/* Interpreter containing the new command. */
+    Command *newCmdPtr)		/* Points to the new command. */
+{
+    char *cmdName;
+    Tcl_HashEntry *hPtr;
+    register Namespace *nsPtr;
+    Namespace *trailNsPtr, *shadowNsPtr;
+    Namespace *globalNsPtr = (Namespace *) TclGetGlobalNamespace(interp);
+    int found, i;
+    int trailFront = -1;
+    int trailSize = 5;		/* Formerly NUM_TRAIL_ELEMS. */
+    Namespace **trailPtr = TclStackAlloc(interp,
+	    trailSize * sizeof(Namespace *));
+
+    /*
+     * Start at the namespace containing the new command, and work up through
+     * the list of parents. Stop just before the global namespace, since the
+     * global namespace can't "shadow" its own entries.
+     *
+     * The namespace "trail" list we build consists of the names of each
+     * namespace that encloses the new command, in order from outermost to
+     * innermost: for example, "a" then "b". Each iteration of this loop
+     * eventually extends the trail upwards by one namespace, nsPtr. We use
+     * this trail list to see if nsPtr (e.g. "a" in 2. above) could have
+     * now-invalid cached command references. This will happen if nsPtr
+     * (e.g. "a") contains a sequence of child namespaces (e.g. "b") such that
+     * there is a identically-named sequence of child namespaces starting from
+     * :: (e.g. "::b") whose tail namespace contains a command also named
+     * cmdName.
+     */
+
+    cmdName = Tcl_GetHashKey(newCmdPtr->hPtr->tablePtr, newCmdPtr->hPtr);
+    for (nsPtr=newCmdPtr->nsPtr ; (nsPtr!=NULL) && (nsPtr!=globalNsPtr) ;
+	    nsPtr=nsPtr->parentPtr) {
+	/*
+	 * Find the maximal sequence of child namespaces contained in nsPtr
+	 * such that there is a identically-named sequence of child namespaces
+	 * starting from ::. shadowNsPtr will be the tail of this sequence, or
+	 * the deepest namespace under :: that might contain a command now
+	 * shadowed by cmdName. We check below if shadowNsPtr actually
+	 * contains a command cmdName.
+	 */
+
+	found = 1;
+	shadowNsPtr = globalNsPtr;
+
+	for (i = trailFront;  i >= 0;  i--) {
+	    trailNsPtr = trailPtr[i];
+#ifndef BREAK_NAMESPACE_COMPAT
+	    hPtr = Tcl_FindHashEntry(&shadowNsPtr->childTable,
+		    trailNsPtr->name);
+#else
+	    if (shadowNsPtr->childTablePtr != NULL) {
+		hPtr = Tcl_FindHashEntry(shadowNsPtr->childTablePtr,
+			trailNsPtr->name);
+	    } else {
+		hPtr = NULL;
+	    }
+#endif
+	    if (hPtr != NULL) {
+		shadowNsPtr = Tcl_GetHashValue(hPtr);
+	    } else {
+		found = 0;
+		break;
+	    }
+	}
+
+	/*
+	 * If shadowNsPtr contains a command named cmdName, we invalidate all
+	 * of the command refs cached in nsPtr. As a boundary case,
+	 * shadowNsPtr is initially :: and we check for case 1. above.
+	 */
+
+	if (found) {
+	    hPtr = Tcl_FindHashEntry(&shadowNsPtr->cmdTable, cmdName);
+	    if (hPtr != NULL) {
+		nsPtr->cmdRefEpoch++;
+		TclInvalidateNsPath(nsPtr);
+
+		/*
+		 * If the shadowed command was compiled to bytecodes, we
+		 * invalidate all the bytecodes in nsPtr, to force a new
+		 * compilation. We use the resolverEpoch to signal the need
+		 * for a fresh compilation of every bytecode.
+		 */
+
+		if (((Command *)Tcl_GetHashValue(hPtr))->compileProc != NULL){
+		    nsPtr->resolverEpoch++;
+		}
+	    }
+	}
+
+	/*
+	 * Insert nsPtr at the front of the trail list: i.e., at the end of
+	 * the trailPtr array.
+	 */
+
+	trailFront++;
+	if (trailFront == trailSize) {
+	    int newSize = 2 * trailSize;
+
+	    trailPtr = TclStackRealloc(interp, trailPtr,
+		    newSize * sizeof(Namespace *));
+	    trailSize = newSize;
+	}
+	trailPtr[trailFront] = nsPtr;
+    }
+    TclStackFree(interp, trailPtr);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclGetNamespaceFromObj, GetNamespaceFromObj --
+ *
+ *	Gets the namespace specified by the name in a Tcl_Obj.
+ *
+ * Results:
+ *	Returns TCL_OK if the namespace was resolved successfully, and stores
+ *	a pointer to the namespace in the location specified by nsPtrPtr. If
+ *	the namespace can't be found, or anything else goes wrong, this
+ *	function returns TCL_ERROR and writes an error message to interp,
+ *	if non-NULL.
+ *
+ * Side effects:
+ *	May update the internal representation for the object, caching the
+ *	namespace reference. The next time this function is called, the
+ *	namespace value can be found quickly.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclGetNamespaceFromObj(
+    Tcl_Interp *interp,		/* The current interpreter. */
+    Tcl_Obj *objPtr,		/* The object to be resolved as the name of a
+				 * namespace. */
+    Tcl_Namespace **nsPtrPtr)	/* Result namespace pointer goes here. */
+{
+    if (GetNamespaceFromObj(interp, objPtr, nsPtrPtr) == TCL_ERROR) {
+	const char *name = TclGetString(objPtr);
+
+	if ((name[0] == ':') && (name[1] == ':')) {
+	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		    "namespace \"%s\" not found", name));
+	} else {
+	    /*
+	     * Get the current namespace name.
+	     */
+
+	    NamespaceCurrentCmd(NULL, interp, 1, NULL);
+	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		    "namespace \"%s\" not found in \"%s\"", name,
+		    Tcl_GetStringResult(interp)));
+	}
+	Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "NAMESPACE", name, NULL);
+	return TCL_ERROR;
+    }
+    return TCL_OK;
+}
+
+static int
+GetNamespaceFromObj(
+    Tcl_Interp *interp,		/* The current interpreter. */
+    Tcl_Obj *objPtr,		/* The object to be resolved as the name of a
+				 * namespace. */
+    Tcl_Namespace **nsPtrPtr)	/* Result namespace pointer goes here. */
+{
+    ResolvedNsName *resNamePtr;
+    Namespace *nsPtr, *refNsPtr;
+
+    if (objPtr->typePtr == &nsNameType) {
+	/*
+	 * Check that the ResolvedNsName is still valid; avoid letting the ref
+	 * cross interps.
+	 */
+
+	resNamePtr = objPtr->internalRep.twoPtrValue.ptr1;
+	nsPtr = resNamePtr->nsPtr;
+	refNsPtr = resNamePtr->refNsPtr;
+	if (!(nsPtr->flags & NS_DYING) && (interp == nsPtr->interp) &&
+		(!refNsPtr || ((interp == refNsPtr->interp) &&
+		(refNsPtr== (Namespace *) Tcl_GetCurrentNamespace(interp))))){
+	    *nsPtrPtr = (Tcl_Namespace *) nsPtr;
+	    return TCL_OK;
+	}
+    }
+    if (SetNsNameFromAny(interp, objPtr) == TCL_OK) {
+	resNamePtr = objPtr->internalRep.twoPtrValue.ptr1;
+	*nsPtrPtr = (Tcl_Namespace *) resNamePtr->nsPtr;
+	return TCL_OK;
+    }
+    return TCL_ERROR;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclInitNamespaceCmd --
+ *
+ *	This function is called to create the "namespace" Tcl command. See the
+ *	user documentation for details on what it does.
+ *
+ * Results:
+ *	Handle for the namespace command, or NULL on failure.
+ *
+ * Side effects:
+ *	none
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_Command
+TclInitNamespaceCmd(
+    Tcl_Interp *interp)		/* Current interpreter. */
+{
+    return TclMakeEnsemble(interp, "namespace", defaultNamespaceMap);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * NamespaceChildrenCmd --
+ *
+ *	Invoked to implement the "namespace children" command that returns a
+ *	list containing the fully-qualified names of the child namespaces of a
+ *	given namespace. Handles the following syntax:
+ *
+ *	    namespace children ?name? ?pattern?
+ *
+ * Results:
+ *	Returns TCL_OK if successful, and TCL_ERROR if anything goes wrong.
+ *
+ * Side effects:
+ *	Returns a result in the interpreter's result object. If anything goes
+ *	wrong, the result is an error message.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+NamespaceChildrenCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    Tcl_Namespace *namespacePtr;
+    Namespace *nsPtr, *childNsPtr;
+    Namespace *globalNsPtr = (Namespace *) TclGetGlobalNamespace(interp);
+    const char *pattern = NULL;
+    Tcl_DString buffer;
+    register Tcl_HashEntry *entryPtr;
+    Tcl_HashSearch search;
+    Tcl_Obj *listPtr, *elemPtr;
+
+    /*
+     * Get a pointer to the specified namespace, or the current namespace.
+     */
+
+    if (objc == 1) {
+	nsPtr = (Namespace *) TclGetCurrentNamespace(interp);
+    } else if ((objc == 2) || (objc == 3)) {
+	if (TclGetNamespaceFromObj(interp, objv[1], &namespacePtr) != TCL_OK){
+	    return TCL_ERROR;
+	}
+	nsPtr = (Namespace *) namespacePtr;
+    } else {
+	Tcl_WrongNumArgs(interp, 1, objv, "?name? ?pattern?");
+	return TCL_ERROR;
+    }
+
+    /*
+     * Get the glob-style pattern, if any, used to narrow the search.
+     */
+
+    Tcl_DStringInit(&buffer);
+    if (objc == 3) {
+	const char *name = TclGetString(objv[2]);
+
+	if ((*name == ':') && (*(name+1) == ':')) {
+	    pattern = name;
+	} else {
+	    Tcl_DStringAppend(&buffer, nsPtr->fullName, -1);
+	    if (nsPtr != globalNsPtr) {
+		TclDStringAppendLiteral(&buffer, "::");
+	    }
+	    Tcl_DStringAppend(&buffer, name, -1);
+	    pattern = Tcl_DStringValue(&buffer);
+	}
+    }
+
+    /*
+     * Create a list containing the full names of all child namespaces whose
+     * names match the specified pattern, if any.
+     */
+
+    listPtr = Tcl_NewListObj(0, NULL);
+    if ((pattern != NULL) && TclMatchIsTrivial(pattern)) {
+	unsigned int length = strlen(nsPtr->fullName);
+
+	if (strncmp(pattern, nsPtr->fullName, length) != 0) {
+	    goto searchDone;
+	}
+	if (
+#ifndef BREAK_NAMESPACE_COMPAT
+	    Tcl_FindHashEntry(&nsPtr->childTable, pattern+length) != NULL
+#else
+	    nsPtr->childTablePtr != NULL &&
+	    Tcl_FindHashEntry(nsPtr->childTablePtr, pattern+length) != NULL
+#endif
+	) {
+	    Tcl_ListObjAppendElement(interp, listPtr,
+		    Tcl_NewStringObj(pattern, -1));
+	}
+	goto searchDone;
+    }
+#ifndef BREAK_NAMESPACE_COMPAT
+    entryPtr = Tcl_FirstHashEntry(&nsPtr->childTable, &search);
+#else
+    if (nsPtr->childTablePtr == NULL) {
+	goto searchDone;
+    }
+    entryPtr = Tcl_FirstHashEntry(nsPtr->childTablePtr, &search);
+#endif
+    while (entryPtr != NULL) {
+	childNsPtr = Tcl_GetHashValue(entryPtr);
+	if ((pattern == NULL)
+		|| Tcl_StringMatch(childNsPtr->fullName, pattern)) {
+	    elemPtr = Tcl_NewStringObj(childNsPtr->fullName, -1);
+	    Tcl_ListObjAppendElement(interp, listPtr, elemPtr);
+	}
+	entryPtr = Tcl_NextHashEntry(&search);
+    }
+
+  searchDone:
+    Tcl_SetObjResult(interp, listPtr);
+    Tcl_DStringFree(&buffer);
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * NamespaceCodeCmd --
+ *
+ *	Invoked to implement the "namespace code" command to capture the
+ *	namespace context of a command. Handles the following syntax:
+ *
+ *	    namespace code arg
+ *
+ *	Here "arg" can be a list. "namespace code arg" produces a result
+ *	equivalent to that produced by the command
+ *
+ *	    list ::namespace inscope [namespace current] $arg
+ *
+ *	However, if "arg" is itself a scoped value starting with "::namespace
+ *	inscope", then the result is just "arg".
+ *
+ * Results:
+ *	Returns TCL_OK if successful, and TCL_ERROR if anything goes wrong.
+ *
+ * Side effects:
+ *	If anything goes wrong, this function returns an error message as the
+ *	result in the interpreter's result object.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+NamespaceCodeCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    Namespace *currNsPtr;
+    Tcl_Obj *listPtr, *objPtr;
+    register const char *arg;
+    int length;
+
+    if (objc != 2) {
+	Tcl_WrongNumArgs(interp, 1, objv, "arg");
+	return TCL_ERROR;
+    }
+
+    /*
+     * If "arg" is already a scoped value, then return it directly.
+     * Take care to only check for scoping in precisely the style that
+     * [::namespace code] generates it.  Anything more forgiving can have
+     * the effect of failing in namespaces that contain their own custom
+     " "namespace" command.  [Bug 3202171].
+     */
+
+    arg = TclGetStringFromObj(objv[1], &length);
+    if (*arg==':' && length > 20
+	    && strncmp(arg, "::namespace inscope ", 20) == 0) {
+	Tcl_SetObjResult(interp, objv[1]);
+	return TCL_OK;
+    }
+
+    /*
+     * Otherwise, construct a scoped command by building a list with
+     * "namespace inscope", the full name of the current namespace, and the
+     * argument "arg". By constructing a list, we ensure that scoped commands
+     * are interpreted properly when they are executed later, by the
+     * "namespace inscope" command.
+     */
+
+    TclNewObj(listPtr);
+    TclNewLiteralStringObj(objPtr, "::namespace");
+    Tcl_ListObjAppendElement(interp, listPtr, objPtr);
+    TclNewLiteralStringObj(objPtr, "inscope");
+    Tcl_ListObjAppendElement(interp, listPtr, objPtr);
+
+    currNsPtr = (Namespace *) TclGetCurrentNamespace(interp);
+    if (currNsPtr == (Namespace *) TclGetGlobalNamespace(interp)) {
+	TclNewLiteralStringObj(objPtr, "::");
+    } else {
+	objPtr = Tcl_NewStringObj(currNsPtr->fullName, -1);
+    }
+    Tcl_ListObjAppendElement(interp, listPtr, objPtr);
+
+    Tcl_ListObjAppendElement(interp, listPtr, objv[1]);
+
+    Tcl_SetObjResult(interp, listPtr);
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * NamespaceCurrentCmd --
+ *
+ *	Invoked to implement the "namespace current" command which returns the
+ *	fully-qualified name of the current namespace. Handles the following
+ *	syntax:
+ *
+ *	    namespace current
+ *
+ * Results:
+ *	Returns TCL_OK if successful, and TCL_ERROR if anything goes wrong.
+ *
+ * Side effects:
+ *	Returns a result in the interpreter's result object. If anything goes
+ *	wrong, the result is an error message.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+NamespaceCurrentCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    register Namespace *currNsPtr;
+
+    if (objc != 1) {
+	Tcl_WrongNumArgs(interp, 1, objv, NULL);
+	return TCL_ERROR;
+    }
+
+    /*
+     * The "real" name of the global namespace ("::") is the null string, but
+     * we return "::" for it as a convenience to programmers. Note that "" and
+     * "::" are treated as synonyms by the namespace code so that it is still
+     * easy to do things like:
+     *
+     *    namespace [namespace current]::bar { ... }
+     */
+
+    currNsPtr = (Namespace *) TclGetCurrentNamespace(interp);
+    if (currNsPtr == (Namespace *) TclGetGlobalNamespace(interp)) {
+	Tcl_SetObjResult(interp, Tcl_NewStringObj("::", 2));
+    } else {
+	Tcl_SetObjResult(interp, Tcl_NewStringObj(currNsPtr->fullName, -1));
+    }
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * NamespaceDeleteCmd --
+ *
+ *	Invoked to implement the "namespace delete" command to delete
+ *	namespace(s). Handles the following syntax:
+ *
+ *	    namespace delete ?name name...?
+ *
+ *	Each name identifies a namespace. It may include a sequence of
+ *	namespace qualifiers separated by "::"s. If a namespace is found, it
+ *	is deleted: all variables and procedures contained in that namespace
+ *	are deleted. If that namespace is being used on the call stack, it is
+ *	kept alive (but logically deleted) until it is removed from the call
+ *	stack: that is, it can no longer be referenced by name but any
+ *	currently executing procedure that refers to it is allowed to do so
+ *	until the procedure returns. If the namespace can't be found, this
+ *	function returns an error. If no namespaces are specified, this
+ *	command does nothing.
+ *
+ * Results:
+ *	Returns TCL_OK if successful, and TCL_ERROR if anything goes wrong.
+ *
+ * Side effects:
+ *	Deletes the specified namespaces. If anything goes wrong, this
+ *	function returns an error message in the interpreter's result object.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+NamespaceDeleteCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    Tcl_Namespace *namespacePtr;
+    const char *name;
+    register int i;
+
+    if (objc < 1) {
+	Tcl_WrongNumArgs(interp, 1, objv, "?name name...?");
+	return TCL_ERROR;
+    }
+
+    /*
+     * Destroying one namespace may cause another to be destroyed. Break this
+     * into two passes: first check to make sure that all namespaces on the
+     * command line are valid, and report any errors.
+     */
+
+    for (i = 1;  i < objc;  i++) {
+	name = TclGetString(objv[i]);
+	namespacePtr = Tcl_FindNamespace(interp, name, NULL, /*flags*/ 0);
+	if ((namespacePtr == NULL)
+		|| (((Namespace *) namespacePtr)->flags & NS_KILLED)) {
+	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+                    "unknown namespace \"%s\" in namespace delete command",
+		    TclGetString(objv[i])));
+	    Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "NAMESPACE",
+		    TclGetString(objv[i]), NULL);
+	    return TCL_ERROR;
+	}
+    }
+
+    /*
+     * Okay, now delete each namespace.
+     */
+
+    for (i = 1;  i < objc;  i++) {
+	name = TclGetString(objv[i]);
+	namespacePtr = Tcl_FindNamespace(interp, name, NULL, /* flags */ 0);
+	if (namespacePtr) {
+	    Tcl_DeleteNamespace(namespacePtr);
+	}
+    }
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * NamespaceEvalCmd --
+ *
+ *	Invoked to implement the "namespace eval" command. Executes commands
+ *	in a namespace. If the namespace does not already exist, it is
+ *	created. Handles the following syntax:
+ *
+ *	    namespace eval name arg ?arg...?
+ *
+ *	If more than one arg argument is specified, the command that is
+ *	executed is the result of concatenating the arguments together with a
+ *	space between each argument.
+ *
+ * Results:
+ *	Returns TCL_OK if the namespace is found and the commands are executed
+ *	successfully. Returns TCL_ERROR if anything goes wrong.
+ *
+ * Side effects:
+ *	Returns the result of the command in the interpreter's result object.
+ *	If anything goes wrong, this function returns an error message as the
+ *	result.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+NamespaceEvalCmd(
+    ClientData clientData,	/* Arbitrary value passed to cmd. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    return Tcl_NRCallObjProc(interp, NRNamespaceEvalCmd, clientData, objc,
+	    objv);
+}
+
+static int
+NRNamespaceEvalCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    Interp *iPtr = (Interp *) interp;
+    CmdFrame *invoker;
+    int word;
+    Tcl_Namespace *namespacePtr;
+    CallFrame *framePtr, **framePtrPtr;
+    Tcl_Obj *objPtr;
+    int result;
+
+    if (objc < 3) {
+	Tcl_WrongNumArgs(interp, 1, objv, "name arg ?arg...?");
+	return TCL_ERROR;
+    }
+
+    /*
+     * Try to resolve the namespace reference, caching the result in the
+     * namespace object along the way.
+     */
+
+    result = GetNamespaceFromObj(interp, objv[1], &namespacePtr);
+
+    /*
+     * If the namespace wasn't found, try to create it.
+     */
+
+    if (result == TCL_ERROR) {
+	const char *name = TclGetString(objv[1]);
+
+	namespacePtr = Tcl_CreateNamespace(interp, name, NULL, NULL);
+	if (namespacePtr == NULL) {
+	    return TCL_ERROR;
+	}
+    }
+
+    /*
+     * Make the specified namespace the current namespace and evaluate the
+     * command(s).
+     */
+
+    /* This is needed to satisfy GCC 3.3's strict aliasing rules */
+    framePtrPtr = &framePtr;
+    (void) TclPushStackFrame(interp, (Tcl_CallFrame **) framePtrPtr,
+	    namespacePtr, /*isProcCallFrame*/ 0);
+
+    framePtr->objv = TclFetchEnsembleRoot(interp, objv, objc, &framePtr->objc);
+
+    if (objc == 3) {
+	/*
+	 * TIP #280: Make actual argument location available to eval'd script.
+	 */
+
+	objPtr = objv[2];
+	invoker = iPtr->cmdFramePtr;
+	word = 3;
+	TclArgumentGet(interp, objPtr, &invoker, &word);
+    } else {
+	/*
+	 * More than one argument: concatenate them together with spaces
+	 * between, then evaluate the result. Tcl_EvalObjEx will delete the
+	 * object when it decrements its refcount after eval'ing it.
+	 */
+
+	objPtr = Tcl_ConcatObj(objc-2, objv+2);
+	invoker = NULL;
+	word = 0;
+    }
+
+    /*
+     * TIP #280: Make invoking context available to eval'd script.
+     */
+
+    TclNRAddCallback(interp, NsEval_Callback, namespacePtr, "eval",
+	    NULL, NULL);
+    return TclNREvalObjEx(interp, objPtr, 0, invoker, word);
+}
+
+static int
+NsEval_Callback(
+    ClientData data[],
+    Tcl_Interp *interp,
+    int result)
+{
+    Tcl_Namespace *namespacePtr = data[0];
+
+    if (result == TCL_ERROR) {
+	int length = strlen(namespacePtr->fullName);
+	int limit = 200;
+	int overflow = (length > limit);
+	char *cmd = data[1];
+
+	Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf(
+		"\n    (in namespace %s \"%.*s%s\" script line %d)",
+		cmd,
+		(overflow ? limit : length), namespacePtr->fullName,
+		(overflow ? "..." : ""), Tcl_GetErrorLine(interp)));
+    }
+
+    /*
+     * Restore the previous "current" namespace.
+     */
+
+    TclPopStackFrame(interp);
+    return result;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * NamespaceExistsCmd --
+ *
+ *	Invoked to implement the "namespace exists" command that returns true
+ *	if the given namespace currently exists, and false otherwise. Handles
+ *	the following syntax:
+ *
+ *	    namespace exists name
+ *
+ * Results:
+ *	Returns TCL_OK if successful, and TCL_ERROR if anything goes wrong.
+ *
+ * Side effects:
+ *	Returns a result in the interpreter's result object. If anything goes
+ *	wrong, the result is an error message.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+NamespaceExistsCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    Tcl_Namespace *namespacePtr;
+
+    if (objc != 2) {
+	Tcl_WrongNumArgs(interp, 1, objv, "name");
+	return TCL_ERROR;
+    }
+
+    Tcl_SetObjResult(interp, Tcl_NewBooleanObj(
+	    GetNamespaceFromObj(interp, objv[1], &namespacePtr) == TCL_OK));
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * NamespaceExportCmd --
+ *
+ *	Invoked to implement the "namespace export" command that specifies
+ *	which commands are exported from a namespace. The exported commands
+ *	are those that can be imported into another namespace using "namespace
+ *	import". Both commands defined in a namespace and commands the
+ *	namespace has imported can be exported by a namespace. This command
+ *	has the following syntax:
+ *
+ *	    namespace export ?-clear? ?pattern pattern...?
+ *
+ *	Each pattern may contain "string match"-style pattern matching special
+ *	characters, but the pattern may not include any namespace qualifiers:
+ *	that is, the pattern must specify commands in the current (exporting)
+ *	namespace. The specified patterns are appended onto the namespace's
+ *	list of export patterns.
+ *
+ *	To reset the namespace's export pattern list, specify the "-clear"
+ *	flag.
+ *
+ *	If there are no export patterns and the "-clear" flag isn't given,
+ *	this command returns the namespace's current export list.
+ *
+ * Results:
+ *	Returns TCL_OK if successful, and TCL_ERROR if anything goes wrong.
+ *
+ * Side effects:
+ *	Returns a result in the interpreter's result object. If anything goes
+ *	wrong, the result is an error message.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+NamespaceExportCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    int firstArg, i;
+
+    if (objc < 1) {
+	Tcl_WrongNumArgs(interp, 1, objv, "?-clear? ?pattern pattern...?");
+	return TCL_ERROR;
+    }
+
+    /*
+     * If no pattern arguments are given, and "-clear" isn't specified, return
+     * the namespace's current export pattern list.
+     */
+
+    if (objc == 1) {
+	Tcl_Obj *listPtr = Tcl_NewObj();
+
+	(void) Tcl_AppendExportList(interp, NULL, listPtr);
+	Tcl_SetObjResult(interp, listPtr);
+	return TCL_OK;
+    }
+
+    /*
+     * Process the optional "-clear" argument.
+     */
+
+    firstArg = 1;
+    if (strcmp("-clear", Tcl_GetString(objv[firstArg])) == 0) {
+	Tcl_Export(interp, NULL, "::", 1);
+	Tcl_ResetResult(interp);
+	firstArg++;
+    }
+
+    /*
+     * Add each pattern to the namespace's export pattern list.
+     */
+
+    for (i = firstArg;  i < objc;  i++) {
+	int result = Tcl_Export(interp, NULL, Tcl_GetString(objv[i]), 0);
+	if (result != TCL_OK) {
+	    return result;
+	}
+    }
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * NamespaceForgetCmd --
+ *
+ *	Invoked to implement the "namespace forget" command to remove imported
+ *	commands from a namespace. Handles the following syntax:
+ *
+ *	    namespace forget ?pattern pattern...?
+ *
+ *	Each pattern is a name like "foo::*" or "a::b::x*". That is, the
+ *	pattern may include the special pattern matching characters recognized
+ *	by the "string match" command, but only in the command name at the end
+ *	of the qualified name; the special pattern characters may not appear
+ *	in a namespace name. All of the commands that match that pattern are
+ *	checked to see if they have an imported command in the current
+ *	namespace that refers to the matched command. If there is an alias, it
+ *	is removed.
+ *
+ * Results:
+ *	Returns TCL_OK if successful, and TCL_ERROR if anything goes wrong.
+ *
+ * Side effects:
+ *	Imported commands are removed from the current namespace. If anything
+ *	goes wrong, this function returns an error message in the
+ *	interpreter's result object.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+NamespaceForgetCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    const char *pattern;
+    register int i, result;
+
+    if (objc < 1) {
+	Tcl_WrongNumArgs(interp, 1, objv, "?pattern pattern...?");
+	return TCL_ERROR;
+    }
+
+    for (i = 1;  i < objc;  i++) {
+	pattern = TclGetString(objv[i]);
+	result = Tcl_ForgetImport(interp, NULL, pattern);
+	if (result != TCL_OK) {
+	    return result;
+	}
+    }
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * NamespaceImportCmd --
+ *
+ *	Invoked to implement the "namespace import" command that imports
+ *	commands into a namespace. Handles the following syntax:
+ *
+ *	    namespace import ?-force? ?pattern pattern...?
+ *
+ *	Each pattern is a namespace-qualified name like "foo::*", "a::b::x*",
+ *	or "bar::p". That is, the pattern may include the special pattern
+ *	matching characters recognized by the "string match" command, but only
+ *	in the command name at the end of the qualified name; the special
+ *	pattern characters may not appear in a namespace name. All of the
+ *	commands that match the pattern and which are exported from their
+ *	namespace are made accessible from the current namespace context. This
+ *	is done by creating a new "imported command" in the current namespace
+ *	that points to the real command in its original namespace; when the
+ *	imported command is called, it invokes the real command.
+ *
+ *	If an imported command conflicts with an existing command, it is
+ *	treated as an error. But if the "-force" option is included, then
+ *	existing commands are overwritten by the imported commands.
+ *
+ *	If there are no pattern arguments and the "-force" flag isn't given,
+ *	this command returns the list of commands currently imported in
+ *	the current namespace.
+ *
+ * Results:
+ *	Returns TCL_OK if successful, and TCL_ERROR if anything goes wrong.
+ *
+ * Side effects:
+ *	Adds imported commands to the current namespace. If anything goes
+ *	wrong, this function returns an error message in the interpreter's
+ *	result object.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+NamespaceImportCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    int allowOverwrite = 0;
+    const char *string, *pattern;
+    register int i, result;
+    int firstArg;
+
+    if (objc < 1) {
+	Tcl_WrongNumArgs(interp, 1, objv, "?-force? ?pattern pattern...?");
+	return TCL_ERROR;
+    }
+
+    /*
+     * Skip over the optional "-force" as the first argument.
+     */
+
+    firstArg = 1;
+    if (firstArg < objc) {
+	string = TclGetString(objv[firstArg]);
+	if ((*string == '-') && (strcmp(string, "-force") == 0)) {
+	    allowOverwrite = 1;
+	    firstArg++;
+	}
+    } else {
+	/*
+	 * When objc == 1, command is just [namespace import]. Introspection
+	 * form to return list of imported commands.
+	 */
+
+	Tcl_HashEntry *hPtr;
+	Tcl_HashSearch search;
+	Namespace *nsPtr = (Namespace *) TclGetCurrentNamespace(interp);
+	Tcl_Obj *listPtr;
+
+	TclNewObj(listPtr);
+	for (hPtr = Tcl_FirstHashEntry(&nsPtr->cmdTable, &search);
+		hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) {
+	    Command *cmdPtr = Tcl_GetHashValue(hPtr);
+
+	    if (cmdPtr->deleteProc == DeleteImportedCmd) {
+		Tcl_ListObjAppendElement(NULL, listPtr, Tcl_NewStringObj(
+			Tcl_GetHashKey(&nsPtr->cmdTable, hPtr) ,-1));
+	    }
+	}
+	Tcl_SetObjResult(interp, listPtr);
+	return TCL_OK;
+    }
+
+    /*
+     * Handle the imports for each of the patterns.
+     */
+
+    for (i = firstArg;  i < objc;  i++) {
+	pattern = TclGetString(objv[i]);
+	result = Tcl_Import(interp, NULL, pattern, allowOverwrite);
+	if (result != TCL_OK) {
+	    return result;
+	}
+    }
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * NamespaceInscopeCmd --
+ *
+ *	Invoked to implement the "namespace inscope" command that executes a
+ *	script in the context of a particular namespace. This command is not
+ *	expected to be used directly by programmers; calls to it are generated
+ *	implicitly when programs use "namespace code" commands to register
+ *	callback scripts. Handles the following syntax:
+ *
+ *	    namespace inscope name arg ?arg...?
+ *
+ *	The "namespace inscope" command is much like the "namespace eval"
+ *	command except that it has lappend semantics and the namespace must
+ *	already exist. It treats the first argument as a list, and appends any
+ *	arguments after the first onto the end as proper list elements. For
+ *	example,
+ *
+ *	    namespace inscope ::foo {a b} c d e
+ *
+ *	is equivalent to
+ *
+ *	    namespace eval ::foo [concat {a b} [list c d e]]
+ *
+ *	This lappend semantics is important because many callback scripts are
+ *	actually prefixes.
+ *
+ * Results:
+ *	Returns TCL_OK to indicate success, or TCL_ERROR to indicate failure.
+ *
+ * Side effects:
+ *	Returns a result in the Tcl interpreter's result object.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+NamespaceInscopeCmd(
+    ClientData clientData,	/* Arbitrary value passed to cmd. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    return Tcl_NRCallObjProc(interp, NRNamespaceInscopeCmd, clientData, objc,
+	    objv);
+}
+
+static int
+NRNamespaceInscopeCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    Tcl_Namespace *namespacePtr;
+    CallFrame *framePtr, **framePtrPtr;
+    int i;
+    Tcl_Obj *cmdObjPtr;
+
+    if (objc < 3) {
+	Tcl_WrongNumArgs(interp, 1, objv, "name arg ?arg...?");
+	return TCL_ERROR;
+    }
+
+    /*
+     * Resolve the namespace reference.
+     */
+
+    if (TclGetNamespaceFromObj(interp, objv[1], &namespacePtr) != TCL_OK) {
+	return TCL_ERROR;
+    }
+
+    /*
+     * Make the specified namespace the current namespace.
+     */
+
+    framePtrPtr = &framePtr;		/* This is needed to satisfy GCC's
+					 * strict aliasing rules. */
+    (void) TclPushStackFrame(interp, (Tcl_CallFrame **) framePtrPtr,
+	    namespacePtr, /*isProcCallFrame*/ 0);
+
+    framePtr->objv = TclFetchEnsembleRoot(interp, objv, objc, &framePtr->objc);
+
+    /*
+     * Execute the command. If there is just one argument, just treat it as a
+     * script and evaluate it. Otherwise, create a list from the arguments
+     * after the first one, then concatenate the first argument and the list
+     * of extra arguments to form the command to evaluate.
+     */
+
+    if (objc == 3) {
+	cmdObjPtr = objv[2];
+    } else {
+	Tcl_Obj *concatObjv[2];
+	register Tcl_Obj *listPtr;
+
+	listPtr = Tcl_NewListObj(0, NULL);
+	for (i = 3;  i < objc;  i++) {
+	    if (Tcl_ListObjAppendElement(interp, listPtr, objv[i]) != TCL_OK){
+		Tcl_DecrRefCount(listPtr);	/* Free unneeded obj. */
+		return TCL_ERROR;
+	    }
+	}
+
+	concatObjv[0] = objv[2];
+	concatObjv[1] = listPtr;
+	cmdObjPtr = Tcl_ConcatObj(2, concatObjv);
+	Tcl_DecrRefCount(listPtr);    /* We're done with the list object. */
+    }
+
+    TclNRAddCallback(interp, NsEval_Callback, namespacePtr, "inscope",
+	    NULL, NULL);
+    return TclNREvalObjEx(interp, cmdObjPtr, 0, NULL, 0);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * NamespaceOriginCmd --
+ *
+ *	Invoked to implement the "namespace origin" command to return the
+ *	fully-qualified name of the "real" command to which the specified
+ *	"imported command" refers. Handles the following syntax:
+ *
+ *	    namespace origin name
+ *
+ * Results:
+ *	An imported command is created in an namespace when that namespace
+ *	imports a command from another namespace. If a command is imported
+ *	into a sequence of namespaces a, b,...,n where each successive
+ *	namespace just imports the command from the previous namespace, this
+ *	command returns the fully-qualified name of the original command in
+ *	the first namespace, a. If "name" does not refer to an alias, its
+ *	fully-qualified name is returned. The returned name is stored in the
+ *	interpreter's result object. This function returns TCL_OK if
+ *	successful, and TCL_ERROR if anything goes wrong.
+ *
+ * Side effects:
+ *	If anything goes wrong, this function returns an error message in the
+ *	interpreter's result object.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+NamespaceOriginCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    Tcl_Command command, origCommand;
+    Tcl_Obj *resultPtr;
+
+    if (objc != 2) {
+	Tcl_WrongNumArgs(interp, 1, objv, "name");
+	return TCL_ERROR;
+    }
+
+    command = Tcl_GetCommandFromObj(interp, objv[1]);
+    if (command == NULL) {
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+                "invalid command name \"%s\"", TclGetString(objv[1])));
+	Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "COMMAND",
+		TclGetString(objv[1]), NULL);
+	return TCL_ERROR;
+    }
+    origCommand = TclGetOriginalCommand(command);
+    TclNewObj(resultPtr);
+    if (origCommand == NULL) {
+	/*
+	 * The specified command isn't an imported command. Return the
+	 * command's name qualified by the full name of the namespace it was
+	 * defined in.
+	 */
+
+	Tcl_GetCommandFullName(interp, command, resultPtr);
+    } else {
+	Tcl_GetCommandFullName(interp, origCommand, resultPtr);
+    }
+    Tcl_SetObjResult(interp, resultPtr);
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * NamespaceParentCmd --
+ *
+ *	Invoked to implement the "namespace parent" command that returns the
+ *	fully-qualified name of the parent namespace for a specified
+ *	namespace. Handles the following syntax:
+ *
+ *	    namespace parent ?name?
+ *
+ * Results:
+ *	Returns TCL_OK if successful, and TCL_ERROR if anything goes wrong.
+ *
+ * Side effects:
+ *	Returns a result in the interpreter's result object. If anything goes
+ *	wrong, the result is an error message.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+NamespaceParentCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    Tcl_Namespace *nsPtr;
+
+    if (objc == 1) {
+	nsPtr = TclGetCurrentNamespace(interp);
+    } else if (objc == 2) {
+	if (TclGetNamespaceFromObj(interp, objv[1], &nsPtr) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+    } else {
+	Tcl_WrongNumArgs(interp, 1, objv, "?name?");
+	return TCL_ERROR;
+    }
+
+    /*
+     * Report the parent of the specified namespace.
+     */
+
+    if (nsPtr->parentPtr != NULL) {
+	Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		nsPtr->parentPtr->fullName, -1));
+    }
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * NamespacePathCmd --
+ *
+ *	Invoked to implement the "namespace path" command that reads and
+ *	writes the current namespace's command resolution path. Has one
+ *	optional argument: if present, it is a list of named namespaces to set
+ *	the path to, and if absent, the current path should be returned.
+ *	Handles the following syntax:
+ *
+ *	    namespace path ?nsList?
+ *
+ * Results:
+ *	Returns TCL_OK if successful, and TCL_ERROR if anything goes wrong
+ *	(most notably if the namespace list contains the name of something
+ *	other than a namespace). In the successful-exit case, may set the
+ *	interpreter result to the list of names of the namespaces on the
+ *	current namespace's path.
+ *
+ * Side effects:
+ *	May update the namespace path (triggering a recomputing of all command
+ *	names that depend on the namespace for resolution).
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+NamespacePathCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    Namespace *nsPtr = (Namespace *) TclGetCurrentNamespace(interp);
+    int i, nsObjc, result = TCL_ERROR;
+    Tcl_Obj **nsObjv;
+    Tcl_Namespace **namespaceList = NULL;
+
+    if (objc > 2) {
+	Tcl_WrongNumArgs(interp, 1, objv, "?pathList?");
+	return TCL_ERROR;
+    }
+
+    /*
+     * If no path is given, return the current path.
+     */
+
+    if (objc == 1) {
+	Tcl_Obj *resultObj = Tcl_NewObj();
+
+	for (i=0 ; i<nsPtr->commandPathLength ; i++) {
+	    if (nsPtr->commandPathArray[i].nsPtr != NULL) {
+		Tcl_ListObjAppendElement(NULL, resultObj, Tcl_NewStringObj(
+			nsPtr->commandPathArray[i].nsPtr->fullName, -1));
+	    }
+	}
+	Tcl_SetObjResult(interp, resultObj);
+	return TCL_OK;
+    }
+
+    /*
+     * There is a path given, so parse it into an array of namespace pointers.
+     */
+
+    if (TclListObjGetElements(interp, objv[1], &nsObjc, &nsObjv) != TCL_OK) {
+	goto badNamespace;
+    }
+    if (nsObjc != 0) {
+	namespaceList = TclStackAlloc(interp,
+		sizeof(Tcl_Namespace *) * nsObjc);
+
+	for (i=0 ; i<nsObjc ; i++) {
+	    if (TclGetNamespaceFromObj(interp, nsObjv[i],
+		    &namespaceList[i]) != TCL_OK) {
+		goto badNamespace;
+	    }
+	}
+    }
+
+    /*
+     * Now we have the list of valid namespaces, install it as the path.
+     */
+
+    TclSetNsPath(nsPtr, nsObjc, namespaceList);
+
+    result = TCL_OK;
+  badNamespace:
+    if (namespaceList != NULL) {
+	TclStackFree(interp, namespaceList);
+    }
+    return result;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclSetNsPath --
+ *
+ *	Sets the namespace command name resolution path to the given list of
+ *	namespaces. If the list is empty (of zero length) the path is set to
+ *	empty and the default old-style behaviour of command name resolution
+ *	is used.
+ *
+ * Results:
+ *	nothing
+ *
+ * Side effects:
+ *	Invalidates the command name resolution caches for any command
+ *	resolved in the given namespace.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclSetNsPath(
+    Namespace *nsPtr,		/* Namespace whose path is to be set. */
+    int pathLength,		/* Length of pathAry. */
+    Tcl_Namespace *pathAry[])	/* Array of namespaces that are the path. */
+{
+    if (pathLength != 0) {
+	NamespacePathEntry *tmpPathArray =
+		ckalloc(sizeof(NamespacePathEntry) * pathLength);
+	int i;
+
+	for (i=0 ; i<pathLength ; i++) {
+	    tmpPathArray[i].nsPtr = (Namespace *) pathAry[i];
+	    tmpPathArray[i].creatorNsPtr = nsPtr;
+	    tmpPathArray[i].prevPtr = NULL;
+	    tmpPathArray[i].nextPtr =
+		    tmpPathArray[i].nsPtr->commandPathSourceList;
+	    if (tmpPathArray[i].nextPtr != NULL) {
+		tmpPathArray[i].nextPtr->prevPtr = &tmpPathArray[i];
+	    }
+	    tmpPathArray[i].nsPtr->commandPathSourceList = &tmpPathArray[i];
+	}
+	if (nsPtr->commandPathLength != 0) {
+	    UnlinkNsPath(nsPtr);
+	}
+	nsPtr->commandPathArray = tmpPathArray;
+    } else {
+	if (nsPtr->commandPathLength != 0) {
+	    UnlinkNsPath(nsPtr);
+	}
+    }
+
+    nsPtr->commandPathLength = pathLength;
+    nsPtr->cmdRefEpoch++;
+    nsPtr->resolverEpoch++;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * UnlinkNsPath --
+ *
+ *	Delete the given namespace's command name resolution path. Only call
+ *	if the path is non-empty. Caller must reset the counter containing the
+ *	path size.
+ *
+ * Results:
+ *	nothing
+ *
+ * Side effects:
+ *	Deletes the array of path entries and unlinks those path entries from
+ *	the target namespace's list of interested namespaces.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+UnlinkNsPath(
+    Namespace *nsPtr)
+{
+    int i;
+    for (i=0 ; i<nsPtr->commandPathLength ; i++) {
+	NamespacePathEntry *nsPathPtr = &nsPtr->commandPathArray[i];
+
+	if (nsPathPtr->prevPtr != NULL) {
+	    nsPathPtr->prevPtr->nextPtr = nsPathPtr->nextPtr;
+	}
+	if (nsPathPtr->nextPtr != NULL) {
+	    nsPathPtr->nextPtr->prevPtr = nsPathPtr->prevPtr;
+	}
+	if (nsPathPtr->nsPtr != NULL) {
+	    if (nsPathPtr->nsPtr->commandPathSourceList == nsPathPtr) {
+		nsPathPtr->nsPtr->commandPathSourceList = nsPathPtr->nextPtr;
+	    }
+	}
+    }
+    ckfree(nsPtr->commandPathArray);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclInvalidateNsPath --
+ *
+ *	Invalidate the name resolution caches for all names looked up in
+ *	namespaces whose name path includes the given namespace.
+ *
+ * Results:
+ *	nothing
+ *
+ * Side effects:
+ *	Increments the command reference epoch in each namespace whose path
+ *	includes the given namespace. This causes any cached resolved names
+ *	whose root cacheing context starts at that namespace to be recomputed
+ *	the next time they are used.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclInvalidateNsPath(
+    Namespace *nsPtr)
+{
+    NamespacePathEntry *nsPathPtr = nsPtr->commandPathSourceList;
+
+    while (nsPathPtr != NULL) {
+	if (nsPathPtr->nsPtr != NULL) {
+	    nsPathPtr->creatorNsPtr->cmdRefEpoch++;
+	}
+	nsPathPtr = nsPathPtr->nextPtr;
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * NamespaceQualifiersCmd --
+ *
+ *	Invoked to implement the "namespace qualifiers" command that returns
+ *	any leading namespace qualifiers in a string. These qualifiers are
+ *	namespace names separated by "::"s. For example, for "::foo::p" this
+ *	command returns "::foo", and for "::" it returns "". This command is
+ *	the complement of the "namespace tail" command. Note that this command
+ *	does not check whether the "namespace" names are, in fact, the names
+ *	of currently defined namespaces. Handles the following syntax:
+ *
+ *	    namespace qualifiers string
+ *
+ * Results:
+ *	Returns TCL_OK if successful, and TCL_ERROR if anything goes wrong.
+ *
+ * Side effects:
+ *	Returns a result in the interpreter's result object. If anything goes
+ *	wrong, the result is an error message.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+NamespaceQualifiersCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    register const char *name, *p;
+    int length;
+
+    if (objc != 2) {
+	Tcl_WrongNumArgs(interp, 1, objv, "string");
+	return TCL_ERROR;
+    }
+
+    /*
+     * Find the end of the string, then work backward and find the start of
+     * the last "::" qualifier.
+     */
+
+    name = TclGetString(objv[1]);
+    for (p = name;  *p != '\0';  p++) {
+	/* empty body */
+    }
+    while (--p >= name) {
+	if ((*p == ':') && (p > name) && (*(p-1) == ':')) {
+	    p -= 2;			/* Back up over the :: */
+	    while ((p >= name) && (*p == ':')) {
+		p--;			/* Back up over the preceeding : */
+	    }
+	    break;
+	}
+    }
+
+    if (p >= name) {
+	length = p-name+1;
+	Tcl_SetObjResult(interp, Tcl_NewStringObj(name, length));
+    }
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * NamespaceUnknownCmd --
+ *
+ *	Invoked to implement the "namespace unknown" command (TIP 181) that
+ *	sets or queries a per-namespace unknown command handler. This handler
+ *	is called when command lookup fails (current and global ns). The
+ *	default handler for the global namespace is ::unknown. The default
+ *	handler for other namespaces is to call the global namespace unknown
+ *	handler. Passing an empty list results in resetting the handler to its
+ *	default.
+ *
+ *	    namespace unknown ?handler?
+ *
+ * Results:
+ *	Returns TCL_OK if successful, and TCL_ERROR if anything goes wrong.
+ *
+ * Side effects:
+ *	If no handler is specified, returns a result in the interpreter's
+ *	result object, otherwise it sets the unknown handler pointer in the
+ *	current namespace to the script fragment provided. If anything goes
+ *	wrong, the result is an error message.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+NamespaceUnknownCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    Tcl_Namespace *currNsPtr;
+    Tcl_Obj *resultPtr;
+    int rc;
+
+    if (objc > 2) {
+	Tcl_WrongNumArgs(interp, 1, objv, "?script?");
+	return TCL_ERROR;
+    }
+
+    currNsPtr = TclGetCurrentNamespace(interp);
+
+    if (objc == 1) {
+	/*
+	 * Introspection - return the current namespace handler.
+	 */
+
+	resultPtr = Tcl_GetNamespaceUnknownHandler(interp, currNsPtr);
+	if (resultPtr == NULL) {
+	    TclNewObj(resultPtr);
+	}
+	Tcl_SetObjResult(interp, resultPtr);
+    } else {
+	rc = Tcl_SetNamespaceUnknownHandler(interp, currNsPtr, objv[1]);
+	if (rc == TCL_OK) {
+	    Tcl_SetObjResult(interp, objv[1]);
+	}
+	return rc;
+    }
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_GetNamespaceUnknownHandler --
+ *
+ *	Returns the unknown command handler registered for the given
+ *	namespace.
+ *
+ * Results:
+ *	Returns the current unknown command handler, or NULL if none exists
+ *	for the namespace.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_Obj *
+Tcl_GetNamespaceUnknownHandler(
+    Tcl_Interp *interp,		/* The interpreter in which the namespace
+				 * exists. */
+    Tcl_Namespace *nsPtr)	/* The namespace. */
+{
+    Namespace *currNsPtr = (Namespace *) nsPtr;
+
+    if (currNsPtr->unknownHandlerPtr == NULL &&
+	    currNsPtr == ((Interp *) interp)->globalNsPtr) {
+	/*
+	 * Default handler for global namespace is "::unknown". For all other
+	 * namespaces, it is NULL (which falls back on the global unknown
+	 * handler).
+	 */
+
+	TclNewLiteralStringObj(currNsPtr->unknownHandlerPtr, "::unknown");
+	Tcl_IncrRefCount(currNsPtr->unknownHandlerPtr);
+    }
+    return currNsPtr->unknownHandlerPtr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_SetNamespaceUnknownHandler --
+ *
+ *	Sets the unknown command handler for the given namespace to the
+ *	command prefix passed.
+ *
+ * Results:
+ *	Returns TCL_OK if successful, and TCL_ERROR if anything goes wrong.
+ *
+ * Side effects:
+ *	Sets the namespace unknown command handler. If the passed in handler
+ *	is NULL or an empty list, then the handler is reset to its default. If
+ *	an error occurs, then an error message is left in the interpreter
+ *	result.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_SetNamespaceUnknownHandler(
+    Tcl_Interp *interp,		/* Interpreter in which the namespace
+				 * exists. */
+    Tcl_Namespace *nsPtr,	/* Namespace which is being updated. */
+    Tcl_Obj *handlerPtr)	/* The new handler, or NULL to reset. */
+{
+    int lstlen = 0;
+    Namespace *currNsPtr = (Namespace *) nsPtr;
+
+    /*
+     * Ensure that we check for errors *first* before we change anything.
+     */
+
+    if (handlerPtr != NULL) {
+	if (TclListObjLength(interp, handlerPtr, &lstlen) != TCL_OK) {
+	    /*
+	     * Not a list.
+	     */
+
+	    return TCL_ERROR;
+	}
+	if (lstlen > 0) {
+	    /*
+	     * We are going to be saving this handler. Increment the reference
+	     * count before decrementing the refcount on the previous handler,
+	     * so that nothing strange can happen if we are told to set the
+	     * handler to the previous value.
+	     */
+
+	    Tcl_IncrRefCount(handlerPtr);
+	}
+    }
+
+    /*
+     * Remove old handler next.
+     */
+
+    if (currNsPtr->unknownHandlerPtr != NULL) {
+	Tcl_DecrRefCount(currNsPtr->unknownHandlerPtr);
+    }
+
+    /*
+     * Install the new handler.
+     */
+
+    if (lstlen > 0) {
+	/*
+	 * Just store the handler. It already has the correct reference count.
+	 */
+
+	currNsPtr->unknownHandlerPtr = handlerPtr;
+    } else {
+	/*
+	 * If NULL or an empty list is passed, this resets to the default
+	 * handler.
+	 */
+
+	currNsPtr->unknownHandlerPtr = NULL;
+    }
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * NamespaceTailCmd --
+ *
+ *	Invoked to implement the "namespace tail" command that returns the
+ *	trailing name at the end of a string with "::" namespace qualifiers.
+ *	These qualifiers are namespace names separated by "::"s. For example,
+ *	for "::foo::p" this command returns "p", and for "::" it returns "".
+ *	This command is the complement of the "namespace qualifiers" command.
+ *	Note that this command does not check whether the "namespace" names
+ *	are, in fact, the names of currently defined namespaces. Handles the
+ *	following syntax:
+ *
+ *	    namespace tail string
+ *
+ * Results:
+ *	Returns TCL_OK if successful, and TCL_ERROR if anything goes wrong.
+ *
+ * Side effects:
+ *	Returns a result in the interpreter's result object. If anything goes
+ *	wrong, the result is an error message.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+NamespaceTailCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    register const char *name, *p;
+
+    if (objc != 2) {
+	Tcl_WrongNumArgs(interp, 1, objv, "string");
+	return TCL_ERROR;
+    }
+
+    /*
+     * Find the end of the string, then work backward and find the last "::"
+     * qualifier.
+     */
+
+    name = TclGetString(objv[1]);
+    for (p = name;  *p != '\0';  p++) {
+	/* empty body */
+    }
+    while (--p > name) {
+	if ((*p == ':') && (*(p-1) == ':')) {
+	    p++;			/* Just after the last "::" */
+	    break;
+	}
+    }
+
+    if (p >= name) {
+	Tcl_SetObjResult(interp, Tcl_NewStringObj(p, -1));
+    }
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * NamespaceUpvarCmd --
+ *
+ *	Invoked to implement the "namespace upvar" command, that creates
+ *	variables in the current scope linked to variables in another
+ *	namespace. Handles the following syntax:
+ *
+ *	    namespace upvar ns otherVar myVar ?otherVar myVar ...?
+ *
+ * Results:
+ *	Returns TCL_OK if successful, and TCL_ERROR if anything goes wrong.
+ *
+ * Side effects:
+ *	Creates new variables in the current scope, linked to the
+ *	corresponding variables in the stipulated nmamespace. If anything goes
+ *	wrong, the result is an error message.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+NamespaceUpvarCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    Interp *iPtr = (Interp *) interp;
+    Tcl_Namespace *nsPtr, *savedNsPtr;
+    Var *otherPtr, *arrayPtr;
+    const char *myName;
+
+    if (objc < 2 || (objc & 1)) {
+	Tcl_WrongNumArgs(interp, 1, objv, "ns ?otherVar myVar ...?");
+	return TCL_ERROR;
+    }
+
+    if (TclGetNamespaceFromObj(interp, objv[1], &nsPtr) != TCL_OK) {
+	return TCL_ERROR;
+    }
+
+    objc -= 2;
+    objv += 2;
+
+    for (; objc>0 ; objc-=2, objv+=2) {
+	/*
+	 * Locate the other variable.
+	 */
+
+	savedNsPtr = (Tcl_Namespace *) iPtr->varFramePtr->nsPtr;
+	iPtr->varFramePtr->nsPtr = (Namespace *) nsPtr;
+	otherPtr = TclObjLookupVarEx(interp, objv[0], NULL,
+		(TCL_NAMESPACE_ONLY|TCL_LEAVE_ERR_MSG|TCL_AVOID_RESOLVERS),
+		"access", /*createPart1*/ 1, /*createPart2*/ 1, &arrayPtr);
+	iPtr->varFramePtr->nsPtr = (Namespace *) savedNsPtr;
+	if (otherPtr == NULL) {
+	    return TCL_ERROR;
+	}
+
+	/*
+	 * Create the new variable and link it to otherPtr.
+	 */
+
+	myName = TclGetString(objv[1]);
+	if (TclPtrMakeUpvar(interp, otherPtr, myName, 0, -1) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+    }
+
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * NamespaceWhichCmd --
+ *
+ *	Invoked to implement the "namespace which" command that returns the
+ *	fully-qualified name of a command or variable. If the specified
+ *	command or variable does not exist, it returns "". Handles the
+ *	following syntax:
+ *
+ *	    namespace which ?-command? ?-variable? name
+ *
+ * Results:
+ *	Returns TCL_OK if successful, and TCL_ERROR if anything goes wrong.
+ *
+ * Side effects:
+ *	Returns a result in the interpreter's result object. If anything goes
+ *	wrong, the result is an error message.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+NamespaceWhichCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    static const char *const opts[] = {
+	"-command", "-variable", NULL
+    };
+    int lookupType = 0;
+    Tcl_Obj *resultPtr;
+
+    if (objc < 2 || objc > 3) {
+    badArgs:
+	Tcl_WrongNumArgs(interp, 1, objv, "?-command? ?-variable? name");
+	return TCL_ERROR;
+    } else if (objc == 3) {
+	/*
+	 * Look for a flag controlling the lookup.
+	 */
+
+	if (Tcl_GetIndexFromObj(interp, objv[1], opts, "option", 0,
+		&lookupType) != TCL_OK) {
+	    /*
+	     * Preserve old style of error message!
+	     */
+
+	    Tcl_ResetResult(interp);
+	    goto badArgs;
+	}
+    }
+
+    TclNewObj(resultPtr);
+    switch (lookupType) {
+    case 0: {				/* -command */
+	Tcl_Command cmd = Tcl_GetCommandFromObj(interp, objv[objc-1]);
+
+	if (cmd != NULL) {
+	    Tcl_GetCommandFullName(interp, cmd, resultPtr);
+	}
+	break;
+    }
+    case 1: {				/* -variable */
+	Tcl_Var var = Tcl_FindNamespaceVar(interp,
+		TclGetString(objv[objc-1]), NULL, /*flags*/ 0);
+
+	if (var != NULL) {
+	    Tcl_GetVariableFullName(interp, var, resultPtr);
+	}
+	break;
+    }
+    }
+    Tcl_SetObjResult(interp, resultPtr);
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * FreeNsNameInternalRep --
+ *
+ *	Frees the resources associated with a nsName object's internal
+ *	representation.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Decrements the ref count of any Namespace structure pointed to by the
+ *	nsName's internal representation. If there are no more references to
+ *	the namespace, it's structure will be freed.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+FreeNsNameInternalRep(
+    register Tcl_Obj *objPtr)	/* nsName object with internal representation
+				 * to free. */
+{
+    ResolvedNsName *resNamePtr = objPtr->internalRep.twoPtrValue.ptr1;
+
+    /*
+     * Decrement the reference count of the namespace. If there are no more
+     * references, free it up.
+     */
+
+    resNamePtr->refCount--;
+    if (resNamePtr->refCount == 0) {
+	/*
+	 * Decrement the reference count for the cached namespace. If the
+	 * namespace is dead, and there are no more references to it, free
+	 * it.
+	 */
+
+	TclNsDecrRefCount(resNamePtr->nsPtr);
+	ckfree(resNamePtr);
+    }
+    objPtr->typePtr = NULL;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * DupNsNameInternalRep --
+ *
+ *	Initializes the internal representation of a nsName object to a copy
+ *	of the internal representation of another nsName object.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	copyPtr's internal rep is set to refer to the same namespace
+ *	referenced by srcPtr's internal rep. Increments the ref count of the
+ *	ResolvedNsName structure used to hold the namespace reference.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+DupNsNameInternalRep(
+    Tcl_Obj *srcPtr,		/* Object with internal rep to copy. */
+    register Tcl_Obj *copyPtr)	/* Object with internal rep to set. */
+{
+    ResolvedNsName *resNamePtr = srcPtr->internalRep.twoPtrValue.ptr1;
+
+    copyPtr->internalRep.twoPtrValue.ptr1 = resNamePtr;
+    resNamePtr->refCount++;
+    copyPtr->typePtr = &nsNameType;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * SetNsNameFromAny --
+ *
+ *	Attempt to generate a nsName internal representation for a Tcl object.
+ *
+ * Results:
+ *	Returns TCL_OK if the value could be converted to a proper namespace
+ *	reference. Otherwise, it returns TCL_ERROR, along with an error
+ *	message in the interpreter's result object.
+ *
+ * Side effects:
+ *	If successful, the object is made a nsName object. Its internal rep is
+ *	set to point to a ResolvedNsName, which contains a cached pointer to
+ *	the Namespace. Reference counts are kept on both the ResolvedNsName
+ *	and the Namespace, so we can keep track of their usage and free them
+ *	when appropriate.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+SetNsNameFromAny(
+    Tcl_Interp *interp,		/* Points to the namespace in which to resolve
+				 * name. Also used for error reporting if not
+				 * NULL. */
+    register Tcl_Obj *objPtr)	/* The object to convert. */
+{
+    const char *dummy;
+    Namespace *nsPtr, *dummy1Ptr, *dummy2Ptr;
+    register ResolvedNsName *resNamePtr;
+    const char *name;
+
+    if (interp == NULL) {
+	return TCL_ERROR;
+    }
+
+    name = TclGetString(objPtr);
+    TclGetNamespaceForQualName(interp, name, NULL, TCL_FIND_ONLY_NS,
+	     &nsPtr, &dummy1Ptr, &dummy2Ptr, &dummy);
+
+    /*
+     * If we found a namespace, then create a new ResolvedNsName structure
+     * that holds a reference to it.
+     */
+
+    if ((nsPtr == NULL) || (nsPtr->flags & NS_DYING)) {
+	/*
+	 * Our failed lookup proves any previously cached nsName intrep is no
+	 * longer valid. Get rid of it so we no longer waste memory storing
+	 * it, nor time determining its invalidity again and again.
+	 */
+
+	if (objPtr->typePtr == &nsNameType) {
+	    TclFreeIntRep(objPtr);
+	}
+	return TCL_ERROR;
+    }
+
+    nsPtr->refCount++;
+    resNamePtr = ckalloc(sizeof(ResolvedNsName));
+    resNamePtr->nsPtr = nsPtr;
+    if ((name[0] == ':') && (name[1] == ':')) {
+	resNamePtr->refNsPtr = NULL;
+    } else {
+	resNamePtr->refNsPtr = (Namespace *) Tcl_GetCurrentNamespace(interp);
+    }
+    resNamePtr->refCount = 1;
+    TclFreeIntRep(objPtr);
+    objPtr->internalRep.twoPtrValue.ptr1 = resNamePtr;
+    objPtr->typePtr = &nsNameType;
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclGetNamespaceCommandTable --
+ *
+ *	Returns the hash table of commands.
+ *
+ * Results:
+ *	Pointer to the hash table.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_HashTable *
+TclGetNamespaceCommandTable(
+    Tcl_Namespace *nsPtr)
+{
+    return &((Namespace *) nsPtr)->cmdTable;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclGetNamespaceChildTable --
+ *
+ *	Returns the hash table of child namespaces.
+ *
+ * Results:
+ *	Pointer to the hash table.
+ *
+ * Side effects:
+ *	Might allocate memory.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_HashTable *
+TclGetNamespaceChildTable(
+    Tcl_Namespace *nsPtr)
+{
+    Namespace *nPtr = (Namespace *) nsPtr;
+#ifndef BREAK_NAMESPACE_COMPAT
+    return &nPtr->childTable;
+#else
+    if (nPtr->childTablePtr == NULL) {
+	nPtr->childTablePtr = ckalloc(sizeof(Tcl_HashTable));
+	Tcl_InitHashTable(nPtr->childTablePtr, TCL_STRING_KEYS);
+    }
+    return nPtr->childTablePtr;
+#endif
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclLogCommandInfo --
+ *
+ *	This function is invoked after an error occurs in an interpreter. It
+ *	adds information to iPtr->errorInfo/errorStack fields to describe the
+ *	command that was being executed when the error occurred. When pc and
+ *	tosPtr are non-NULL, conveying a bytecode execution "inner context",
+ *	and the offending instruction is suitable, that inner context is
+ *	recorded in errorStack.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Information about the command is added to errorInfo/errorStack and the
+ *	line number stored internally in the interpreter is set.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclLogCommandInfo(
+    Tcl_Interp *interp,		/* Interpreter in which to log information. */
+    const char *script,		/* First character in script containing
+				 * command (must be <= command). */
+    const char *command,	/* First character in command that generated
+				 * the error. */
+    int length,			/* Number of bytes in command (-1 means use
+				 * all bytes up to first null byte). */
+    const unsigned char *pc,    /* Current pc of bytecode execution context */
+    Tcl_Obj **tosPtr)		/* Current stack of bytecode execution
+				 * context */
+{
+    register const char *p;
+    Interp *iPtr = (Interp *) interp;
+    int overflow, limit = 150;
+    Var *varPtr, *arrayPtr;
+
+    if (iPtr->flags & ERR_ALREADY_LOGGED) {
+	/*
+	 * Someone else has already logged error information for this command;
+	 * we shouldn't add anything more.
+	 */
+
+	return;
+    }
+
+    if (command != NULL) {
+	/*
+	 * Compute the line number where the error occurred.
+	 */
+
+	iPtr->errorLine = 1;
+	for (p = script; p != command; p++) {
+	    if (*p == '\n') {
+		iPtr->errorLine++;
+	    }
+	}
+
+	if (length < 0) {
+	    length = strlen(command);
+	}
+	overflow = (length > limit);
+	Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf(
+		"\n    %s\n\"%.*s%s\"", ((iPtr->errorInfo == NULL)
+		? "while executing" : "invoked from within"),
+		(overflow ? limit : length), command,
+		(overflow ? "..." : "")));
+
+	varPtr = TclObjLookupVarEx(interp, iPtr->eiVar, NULL, TCL_GLOBAL_ONLY,
+		NULL, 0, 0, &arrayPtr);
+	if ((varPtr == NULL) || !TclIsVarTraced(varPtr)) {
+	    /*
+	     * Should not happen.
+	     */
+
+	    return;
+	} else {
+	    Tcl_HashEntry *hPtr
+		    = Tcl_FindHashEntry(&iPtr->varTraces, (char *) varPtr);
+	    VarTrace *tracePtr = Tcl_GetHashValue(hPtr);
+
+	    if (tracePtr->traceProc != EstablishErrorInfoTraces) {
+		/*
+		 * The most recent trace set on ::errorInfo is not the one the
+		 * core itself puts on last. This means some other code is
+		 * tracing the variable, and the additional trace(s) might be
+		 * write traces that expect the timing of writes to
+		 * ::errorInfo that existed Tcl releases before 8.5. To
+		 * satisfy that compatibility need, we write the current
+		 * -errorinfo value to the ::errorInfo variable.
+		 */
+
+		Tcl_ObjSetVar2(interp, iPtr->eiVar, NULL, iPtr->errorInfo,
+			TCL_GLOBAL_ONLY);
+	    }
+	}
+    }
+
+    /*
+     * TIP #348
+     */
+
+    if (Tcl_IsShared(iPtr->errorStack)) {
+	Tcl_Obj *newObj;
+
+	newObj = Tcl_DuplicateObj(iPtr->errorStack);
+	Tcl_DecrRefCount(iPtr->errorStack);
+	Tcl_IncrRefCount(newObj);
+	iPtr->errorStack = newObj;
+    }
+    if (iPtr->resetErrorStack) {
+	int len;
+
+	iPtr->resetErrorStack = 0;
+	Tcl_ListObjLength(interp, iPtr->errorStack, &len);
+
+	/*
+	 * Reset while keeping the list intrep as much as possible.
+	 */
+
+	Tcl_ListObjReplace(interp, iPtr->errorStack, 0, len, 0, NULL);
+	if (pc != NULL) {
+	    Tcl_Obj *innerContext;
+
+	    innerContext = TclGetInnerContext(interp, pc, tosPtr);
+	    if (innerContext != NULL) {
+		Tcl_ListObjAppendElement(NULL, iPtr->errorStack,
+			iPtr->innerLiteral);
+		Tcl_ListObjAppendElement(NULL, iPtr->errorStack, innerContext);
+	    }
+	} else if (command != NULL) {
+	    Tcl_ListObjAppendElement(NULL, iPtr->errorStack,
+		    iPtr->innerLiteral);
+	    Tcl_ListObjAppendElement(NULL, iPtr->errorStack,
+		    Tcl_NewStringObj(command, length));
+	}
+    }
+
+    if (!iPtr->framePtr->objc) {
+	/*
+	 * Special frame, nothing to report.
+	 */
+    } else if (iPtr->varFramePtr != iPtr->framePtr) {
+	/*
+	 * uplevel case, [lappend errorstack UP $relativelevel]
+	 */
+
+	Tcl_ListObjAppendElement(NULL, iPtr->errorStack, iPtr->upLiteral);
+	Tcl_ListObjAppendElement(NULL, iPtr->errorStack, Tcl_NewIntObj(
+		iPtr->framePtr->level - iPtr->varFramePtr->level));
+    } else if (iPtr->framePtr != iPtr->rootFramePtr) {
+	/*
+	 * normal case, [lappend errorstack CALL [info level 0]]
+	 */
+
+	Tcl_ListObjAppendElement(NULL, iPtr->errorStack, iPtr->callLiteral);
+	Tcl_ListObjAppendElement(NULL, iPtr->errorStack, Tcl_NewListObj(
+		iPtr->framePtr->objc, iPtr->framePtr->objv));
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclErrorStackResetIf --
+ *
+ *	The TIP 348 reset/no-bc part of TLCI, for specific use by
+ *	TclCompileSyntaxError.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Reset errorstack if it needs be, and in that case remember the
+ *	passed-in error message as inner context.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclErrorStackResetIf(
+    Tcl_Interp *interp,
+    const char *msg,
+    int length)
+{
+    Interp *iPtr = (Interp *) interp;
+
+    if (Tcl_IsShared(iPtr->errorStack)) {
+	Tcl_Obj *newObj;
+
+	newObj = Tcl_DuplicateObj(iPtr->errorStack);
+	Tcl_DecrRefCount(iPtr->errorStack);
+	Tcl_IncrRefCount(newObj);
+	iPtr->errorStack = newObj;
+    }
+    if (iPtr->resetErrorStack) {
+	int len;
+
+	iPtr->resetErrorStack = 0;
+	Tcl_ListObjLength(interp, iPtr->errorStack, &len);
+
+	/*
+	 * Reset while keeping the list intrep as much as possible.
+	 */
+
+	Tcl_ListObjReplace(interp, iPtr->errorStack, 0, len, 0, NULL);
+	Tcl_ListObjAppendElement(NULL, iPtr->errorStack, iPtr->innerLiteral);
+	Tcl_ListObjAppendElement(NULL, iPtr->errorStack,
+		Tcl_NewStringObj(msg, length));
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_LogCommandInfo --
+ *
+ *	This function is invoked after an error occurs in an interpreter. It
+ *	adds information to iPtr->errorInfo/errorStack fields to describe the
+ *	command that was being executed when the error occurred.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Information about the command is added to errorInfo/errorStack and the
+ *	line number stored internally in the interpreter is set.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_LogCommandInfo(
+    Tcl_Interp *interp,		/* Interpreter in which to log information. */
+    const char *script,		/* First character in script containing
+				 * command (must be <= command). */
+    const char *command,	/* First character in command that generated
+				 * the error. */
+    int length)			/* Number of bytes in command (-1 means use
+				 * all bytes up to first null byte). */
+{
+    TclLogCommandInfo(interp, script, command, length, NULL, NULL);
+}
+
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * tab-width: 8
+ * End:
+ */
diff --git a/generic/tclNotify.c b/generic/tclNotify.c
new file mode 100644
index 0000000..e76bca8
--- /dev/null
+++ b/generic/tclNotify.c
@@ -0,0 +1,1141 @@
+/*
+ * tclNotify.c --
+ *
+ *	This file implements the generic portion of the Tcl notifier. The
+ *	notifier is lowest-level part of the event system. It manages an event
+ *	queue that holds Tcl_Event structures. The platform specific portion
+ *	of the notifier is defined in the tcl*Notify.c files in each platform
+ *	directory.
+ *
+ * Copyright (c) 1995-1997 Sun Microsystems, Inc.
+ * Copyright (c) 1998 by Scriptics Corporation.
+ * Copyright (c) 2003 by Kevin B. Kenny.  All rights reserved.
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#include "tclInt.h"
+
+/*
+ * Module-scope struct of notifier hooks that are checked in the default
+ * notifier functions (for overriding via Tcl_SetNotifier).
+ */
+
+Tcl_NotifierProcs tclNotifierHooks = {
+    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
+};
+
+/*
+ * For each event source (created with Tcl_CreateEventSource) there is a
+ * structure of the following type:
+ */
+
+typedef struct EventSource {
+    Tcl_EventSetupProc *setupProc;
+    Tcl_EventCheckProc *checkProc;
+    ClientData clientData;
+    struct EventSource *nextPtr;
+} EventSource;
+
+/*
+ * The following structure keeps track of the state of the notifier on a
+ * per-thread basis. The first three elements keep track of the event queue.
+ * In addition to the first (next to be serviced) and last events in the
+ * queue, we keep track of a "marker" event. This provides a simple priority
+ * mechanism whereby events can be inserted at the front of the queue but
+ * behind all other high-priority events already in the queue (this is used
+ * for things like a sequence of Enter and Leave events generated during a
+ * grab in Tk). These elements are protected by the queueMutex so that any
+ * thread can queue an event on any notifier. Note that all of the values in
+ * this structure will be initialized to 0.
+ */
+
+typedef struct ThreadSpecificData {
+    Tcl_Event *firstEventPtr;	/* First pending event, or NULL if none. */
+    Tcl_Event *lastEventPtr;	/* Last pending event, or NULL if none. */
+    Tcl_Event *markerEventPtr;	/* Last high-priority event in queue, or NULL
+				 * if none. */
+    Tcl_Mutex queueMutex;	/* Mutex to protect access to the previous
+				 * three fields. */
+    int serviceMode;		/* One of TCL_SERVICE_NONE or
+				 * TCL_SERVICE_ALL. */
+    int blockTimeSet;		/* 0 means there is no maximum block time:
+				 * block forever. */
+    Tcl_Time blockTime;		/* If blockTimeSet is 1, gives the maximum
+				 * elapsed time for the next block. */
+    int inTraversal;		/* 1 if Tcl_SetMaxBlockTime is being called
+				 * during an event source traversal. */
+    EventSource *firstEventSourcePtr;
+				/* Pointer to first event source in list of
+				 * event sources for this thread. */
+    Tcl_ThreadId threadId;	/* Thread that owns this notifier instance. */
+    ClientData clientData;	/* Opaque handle for platform specific
+				 * notifier. */
+    int initialized;		/* 1 if notifier has been initialized. */
+    struct ThreadSpecificData *nextPtr;
+				/* Next notifier in global list of notifiers.
+				 * Access is controlled by the listLock global
+				 * mutex. */
+} ThreadSpecificData;
+
+static Tcl_ThreadDataKey dataKey;
+
+/*
+ * Global list of notifiers. Access to this list is controlled by the listLock
+ * mutex. If this becomes a performance bottleneck, this could be replaced
+ * with a hashtable.
+ */
+
+static ThreadSpecificData *firstNotifierPtr = NULL;
+TCL_DECLARE_MUTEX(listLock)
+
+/*
+ * Declarations for routines used only in this file.
+ */
+
+static void		QueueEvent(ThreadSpecificData *tsdPtr,
+			    Tcl_Event *evPtr, Tcl_QueuePosition position);
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclInitNotifier --
+ *
+ *	Initialize the thread local data structures for the notifier
+ *	subsystem.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Adds the current thread to the global list of notifiers.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclInitNotifier(void)
+{
+    ThreadSpecificData *tsdPtr;
+    Tcl_ThreadId threadId = Tcl_GetCurrentThread();
+
+    Tcl_MutexLock(&listLock);
+    for (tsdPtr = firstNotifierPtr; tsdPtr && tsdPtr->threadId != threadId;
+	    tsdPtr = tsdPtr->nextPtr) {
+	/* Empty loop body. */
+    }
+
+    if (NULL == tsdPtr) {
+	/*
+	 * Notifier not yet initialized in this thread.
+	 */
+
+	tsdPtr = TCL_TSD_INIT(&dataKey);
+	tsdPtr->threadId = threadId;
+	tsdPtr->clientData = Tcl_InitNotifier();
+	tsdPtr->initialized = 1;
+	tsdPtr->nextPtr = firstNotifierPtr;
+	firstNotifierPtr = tsdPtr;
+    }
+    Tcl_MutexUnlock(&listLock);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclFinalizeNotifier --
+ *
+ *	Finalize the thread local data structures for the notifier subsystem.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Removes the notifier associated with the current thread from the
+ *	global notifier list. This is done only if the notifier was
+ *	initialized for this thread by call to TclInitNotifier(). This is
+ *	always true for threads which have been seeded with an Tcl
+ *	interpreter, since the call to Tcl_CreateInterp will, among other
+ *	things, call TclInitializeSubsystems() and this one will, in turn,
+ *	call the TclInitNotifier() for the thread. For threads created without
+ *	the Tcl interpreter, though, nobody is explicitly nor implicitly
+ *	calling the TclInitNotifier hence, TclFinalizeNotifier should not be
+ *	performed at all.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclFinalizeNotifier(void)
+{
+    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+    ThreadSpecificData **prevPtrPtr;
+    Tcl_Event *evPtr, *hold;
+
+    if (!tsdPtr->initialized) {
+	return;		/* Notifier not initialized for the current thread */
+    }
+
+    Tcl_MutexLock(&(tsdPtr->queueMutex));
+    for (evPtr = tsdPtr->firstEventPtr; evPtr != NULL; ) {
+	hold = evPtr;
+	evPtr = evPtr->nextPtr;
+	ckfree(hold);
+    }
+    tsdPtr->firstEventPtr = NULL;
+    tsdPtr->lastEventPtr = NULL;
+    Tcl_MutexUnlock(&(tsdPtr->queueMutex));
+
+    Tcl_MutexLock(&listLock);
+
+    Tcl_FinalizeNotifier(tsdPtr->clientData);
+    Tcl_MutexFinalize(&(tsdPtr->queueMutex));
+    for (prevPtrPtr = &firstNotifierPtr; *prevPtrPtr != NULL;
+	    prevPtrPtr = &((*prevPtrPtr)->nextPtr)) {
+	if (*prevPtrPtr == tsdPtr) {
+	    *prevPtrPtr = tsdPtr->nextPtr;
+	    break;
+	}
+    }
+    tsdPtr->initialized = 0;
+
+    Tcl_MutexUnlock(&listLock);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_SetNotifier --
+ *
+ *	Install a set of alternate functions for use with the notifier. In
+ *	particular, this can be used to install the Xt-based notifier for use
+ *	with the Browser plugin.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Set the tclNotifierHooks global, which is checked in the default
+ *	notifier functions.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_SetNotifier(
+    Tcl_NotifierProcs *notifierProcPtr)
+{
+    tclNotifierHooks = *notifierProcPtr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_CreateEventSource --
+ *
+ *	This function is invoked to create a new source of events. The source
+ *	is identified by a function that gets invoked during Tcl_DoOneEvent to
+ *	check for events on that source and queue them.
+ *
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	SetupProc and checkProc will be invoked each time that Tcl_DoOneEvent
+ *	runs out of things to do. SetupProc will be invoked before
+ *	Tcl_DoOneEvent calls select or whatever else it uses to wait for
+ *	events. SetupProc typically calls functions like Tcl_SetMaxBlockTime
+ *	to indicate what to wait for.
+ *
+ *	CheckProc is called after select or whatever operation was actually
+ *	used to wait. It figures out whether anything interesting actually
+ *	happened (e.g. by calling Tcl_AsyncReady), and then calls
+ *	Tcl_QueueEvent to queue any events that are ready.
+ *
+ *	Each of these functions is passed two arguments, e.g.
+ *		(*checkProc)(ClientData clientData, int flags));
+ *	ClientData is the same as the clientData argument here, and flags is a
+ *	combination of things like TCL_FILE_EVENTS that indicates what events
+ *	are of interest: setupProc and checkProc use flags to figure out
+ *	whether their events are relevant or not.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_CreateEventSource(
+    Tcl_EventSetupProc *setupProc,
+				/* Function to invoke to figure out what to
+				 * wait for. */
+    Tcl_EventCheckProc *checkProc,
+				/* Function to call after waiting to see what
+				 * happened. */
+    ClientData clientData)	/* One-word argument to pass to setupProc and
+				 * checkProc. */
+{
+    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+    EventSource *sourcePtr = ckalloc(sizeof(EventSource));
+
+    sourcePtr->setupProc = setupProc;
+    sourcePtr->checkProc = checkProc;
+    sourcePtr->clientData = clientData;
+    sourcePtr->nextPtr = tsdPtr->firstEventSourcePtr;
+    tsdPtr->firstEventSourcePtr = sourcePtr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_DeleteEventSource --
+ *
+ *	This function is invoked to delete the source of events given by proc
+ *	and clientData.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The given event source is canceled, so its function will never again
+ *	be called. If no such source exists, nothing happens.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_DeleteEventSource(
+    Tcl_EventSetupProc *setupProc,
+				/* Function to invoke to figure out what to
+				 * wait for. */
+    Tcl_EventCheckProc *checkProc,
+				/* Function to call after waiting to see what
+				 * happened. */
+    ClientData clientData)	/* One-word argument to pass to setupProc and
+				 * checkProc. */
+{
+    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+    EventSource *sourcePtr, *prevPtr;
+
+    for (sourcePtr = tsdPtr->firstEventSourcePtr, prevPtr = NULL;
+	    sourcePtr != NULL;
+	    prevPtr = sourcePtr, sourcePtr = sourcePtr->nextPtr) {
+	if ((sourcePtr->setupProc != setupProc)
+		|| (sourcePtr->checkProc != checkProc)
+		|| (sourcePtr->clientData != clientData)) {
+	    continue;
+	}
+	if (prevPtr == NULL) {
+	    tsdPtr->firstEventSourcePtr = sourcePtr->nextPtr;
+	} else {
+	    prevPtr->nextPtr = sourcePtr->nextPtr;
+	}
+	ckfree(sourcePtr);
+	return;
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_QueueEvent --
+ *
+ *	Queue an event on the event queue associated with the current thread.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_QueueEvent(
+    Tcl_Event *evPtr,		/* Event to add to queue. The storage space
+				 * must have been allocated the caller with
+				 * malloc (ckalloc), and it becomes the
+				 * property of the event queue. It will be
+				 * freed after the event has been handled. */
+    Tcl_QueuePosition position)	/* One of TCL_QUEUE_TAIL, TCL_QUEUE_HEAD,
+				 * TCL_QUEUE_MARK. */
+{
+    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+
+    QueueEvent(tsdPtr, evPtr, position);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_ThreadQueueEvent --
+ *
+ *	Queue an event on the specified thread's event queue.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_ThreadQueueEvent(
+    Tcl_ThreadId threadId,	/* Identifier for thread to use. */
+    Tcl_Event *evPtr,		/* Event to add to queue. The storage space
+				 * must have been allocated the caller with
+				 * malloc (ckalloc), and it becomes the
+				 * property of the event queue. It will be
+				 * freed after the event has been handled. */
+    Tcl_QueuePosition position)	/* One of TCL_QUEUE_TAIL, TCL_QUEUE_HEAD,
+				 * TCL_QUEUE_MARK. */
+{
+    ThreadSpecificData *tsdPtr;
+
+    /*
+     * Find the notifier associated with the specified thread.
+     */
+
+    Tcl_MutexLock(&listLock);
+    for (tsdPtr = firstNotifierPtr; tsdPtr && tsdPtr->threadId != threadId;
+	    tsdPtr = tsdPtr->nextPtr) {
+	/* Empty loop body. */
+    }
+
+    /*
+     * Queue the event if there was a notifier associated with the thread.
+     */
+
+    if (tsdPtr) {
+	QueueEvent(tsdPtr, evPtr, position);
+    } else {
+	ckfree(evPtr);
+    }
+    Tcl_MutexUnlock(&listLock);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * QueueEvent --
+ *
+ *	Insert an event into the specified thread's event queue at one of
+ *	three positions: the head, the tail, or before a floating marker.
+ *	Events inserted before the marker will be processed in first-in-
+ *	first-out order, but before any events inserted at the tail of the
+ *	queue. Events inserted at the head of the queue will be processed in
+ *	last-in-first-out order.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+QueueEvent(
+    ThreadSpecificData *tsdPtr,	/* Handle to thread local data that indicates
+				 * which event queue to use. */
+    Tcl_Event *evPtr,		/* Event to add to queue.  The storage space
+				 * must have been allocated the caller with
+				 * malloc (ckalloc), and it becomes the
+				 * property of the event queue. It will be
+				 * freed after the event has been handled. */
+    Tcl_QueuePosition position)	/* One of TCL_QUEUE_TAIL, TCL_QUEUE_HEAD,
+				 * TCL_QUEUE_MARK. */
+{
+    Tcl_MutexLock(&(tsdPtr->queueMutex));
+    if (position == TCL_QUEUE_TAIL) {
+	/*
+	 * Append the event on the end of the queue.
+	 */
+
+	evPtr->nextPtr = NULL;
+	if (tsdPtr->firstEventPtr == NULL) {
+	    tsdPtr->firstEventPtr = evPtr;
+	} else {
+	    tsdPtr->lastEventPtr->nextPtr = evPtr;
+	}
+	tsdPtr->lastEventPtr = evPtr;
+    } else if (position == TCL_QUEUE_HEAD) {
+	/*
+	 * Push the event on the head of the queue.
+	 */
+
+	evPtr->nextPtr = tsdPtr->firstEventPtr;
+	if (tsdPtr->firstEventPtr == NULL) {
+	    tsdPtr->lastEventPtr = evPtr;
+	}
+	tsdPtr->firstEventPtr = evPtr;
+    } else if (position == TCL_QUEUE_MARK) {
+	/*
+	 * Insert the event after the current marker event and advance the
+	 * marker to the new event.
+	 */
+
+	if (tsdPtr->markerEventPtr == NULL) {
+	    evPtr->nextPtr = tsdPtr->firstEventPtr;
+	    tsdPtr->firstEventPtr = evPtr;
+	} else {
+	    evPtr->nextPtr = tsdPtr->markerEventPtr->nextPtr;
+	    tsdPtr->markerEventPtr->nextPtr = evPtr;
+	}
+	tsdPtr->markerEventPtr = evPtr;
+	if (evPtr->nextPtr == NULL) {
+	    tsdPtr->lastEventPtr = evPtr;
+	}
+    }
+    Tcl_MutexUnlock(&(tsdPtr->queueMutex));
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_DeleteEvents --
+ *
+ *	Calls a function for each event in the queue and deletes those for
+ *	which the function returns 1. Events for which the function returns 0
+ *	are left in the queue. Operates on the queue associated with the
+ *	current thread.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Potentially removes one or more events from the event queue.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_DeleteEvents(
+    Tcl_EventDeleteProc *proc,	/* The function to call. */
+    ClientData clientData)	/* The type-specific data. */
+{
+    Tcl_Event *evPtr;		/* Pointer to the event being examined */
+    Tcl_Event *prevPtr;		/* Pointer to evPtr's predecessor, or NULL if
+				 * evPtr designates the first event in the
+				 * queue for the thread. */
+    Tcl_Event *hold;
+    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+
+    Tcl_MutexLock(&(tsdPtr->queueMutex));
+
+    /*
+     * Walk the queue of events for the thread, applying 'proc' to each to
+     * decide whether to eliminate the event.
+     */
+
+    prevPtr = NULL;
+    evPtr = tsdPtr->firstEventPtr;
+    while (evPtr != NULL) {
+	if (proc(evPtr, clientData) == 1) {
+	    /*
+	     * This event should be deleted. Unlink it.
+	     */
+
+	    if (prevPtr == NULL) {
+		tsdPtr->firstEventPtr = evPtr->nextPtr;
+	    } else {
+		prevPtr->nextPtr = evPtr->nextPtr;
+	    }
+
+	    /*
+	     * Update 'last' and 'marker' events if either has been deleted.
+	     */
+
+	    if (evPtr->nextPtr == NULL) {
+		tsdPtr->lastEventPtr = prevPtr;
+	    }
+	    if (tsdPtr->markerEventPtr == evPtr) {
+		tsdPtr->markerEventPtr = prevPtr;
+	    }
+
+	    /*
+	     * Delete the event data structure.
+	     */
+
+	    hold = evPtr;
+	    evPtr = evPtr->nextPtr;
+	    ckfree(hold);
+	} else {
+	    /*
+	     * Event is to be retained.
+	     */
+
+	    prevPtr = evPtr;
+	    evPtr = evPtr->nextPtr;
+	}
+    }
+    Tcl_MutexUnlock(&(tsdPtr->queueMutex));
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_ServiceEvent --
+ *
+ *	Process one event from the event queue, or invoke an asynchronous
+ *	event handler. Operates on event queue for current thread.
+ *
+ * Results:
+ *	The return value is 1 if the function actually found an event to
+ *	process. If no processing occurred, then 0 is returned.
+ *
+ * Side effects:
+ *	Invokes all of the event handlers for the highest priority event in
+ *	the event queue. May collapse some events into a single event or
+ *	discard stale events.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_ServiceEvent(
+    int flags)			/* Indicates what events should be processed.
+				 * May be any combination of TCL_WINDOW_EVENTS
+				 * TCL_FILE_EVENTS, TCL_TIMER_EVENTS, or other
+				 * flags defined elsewhere. Events not
+				 * matching this will be skipped for
+				 * processing later. */
+{
+    Tcl_Event *evPtr, *prevPtr;
+    Tcl_EventProc *proc;
+    int result;
+    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+
+    /*
+     * Asynchronous event handlers are considered to be the highest priority
+     * events, and so must be invoked before we process events on the event
+     * queue.
+     */
+
+    if (Tcl_AsyncReady()) {
+	(void) Tcl_AsyncInvoke(NULL, 0);
+	return 1;
+    }
+
+    /*
+     * No event flags is equivalent to TCL_ALL_EVENTS.
+     */
+
+    if ((flags & TCL_ALL_EVENTS) == 0) {
+	flags |= TCL_ALL_EVENTS;
+    }
+
+    /*
+     * Loop through all the events in the queue until we find one that can
+     * actually be handled.
+     */
+
+    Tcl_MutexLock(&(tsdPtr->queueMutex));
+    for (evPtr = tsdPtr->firstEventPtr; evPtr != NULL;
+	    evPtr = evPtr->nextPtr) {
+	/*
+	 * Call the handler for the event. If it actually handles the event
+	 * then free the storage for the event. There are two tricky things
+	 * here, both stemming from the fact that the event code may be
+	 * re-entered while servicing the event:
+	 *
+	 * 1. Set the "proc" field to NULL.  This is a signal to ourselves
+	 *    that we shouldn't reexecute the handler if the event loop is
+	 *    re-entered.
+	 * 2. When freeing the event, must search the queue again from the
+	 *    front to find it. This is because the event queue could change
+	 *    almost arbitrarily while handling the event, so we can't depend
+	 *    on pointers found now still being valid when the handler
+	 *    returns.
+	 */
+
+	proc = evPtr->proc;
+	if (proc == NULL) {
+	    continue;
+	}
+	evPtr->proc = NULL;
+
+	/*
+	 * Release the lock before calling the event function. This allows
+	 * other threads to post events if we enter a recursive event loop in
+	 * this thread. Note that we are making the assumption that if the
+	 * proc returns 0, the event is still in the list.
+	 */
+
+	Tcl_MutexUnlock(&(tsdPtr->queueMutex));
+	result = proc(evPtr, flags);
+	Tcl_MutexLock(&(tsdPtr->queueMutex));
+
+	if (result) {
+	    /*
+	     * The event was processed, so remove it from the queue.
+	     */
+
+	    if (tsdPtr->firstEventPtr == evPtr) {
+		tsdPtr->firstEventPtr = evPtr->nextPtr;
+		if (evPtr->nextPtr == NULL) {
+		    tsdPtr->lastEventPtr = NULL;
+		}
+		if (tsdPtr->markerEventPtr == evPtr) {
+		    tsdPtr->markerEventPtr = NULL;
+		}
+	    } else {
+		for (prevPtr = tsdPtr->firstEventPtr;
+			prevPtr && prevPtr->nextPtr != evPtr;
+			prevPtr = prevPtr->nextPtr) {
+		    /* Empty loop body. */
+		}
+		if (prevPtr) {
+		    prevPtr->nextPtr = evPtr->nextPtr;
+		    if (evPtr->nextPtr == NULL) {
+			tsdPtr->lastEventPtr = prevPtr;
+		    }
+		    if (tsdPtr->markerEventPtr == evPtr) {
+			tsdPtr->markerEventPtr = prevPtr;
+		    }
+		} else {
+		    evPtr = NULL;
+		}
+	    }
+	    if (evPtr) {
+		ckfree(evPtr);
+	    }
+	    Tcl_MutexUnlock(&(tsdPtr->queueMutex));
+	    return 1;
+	} else {
+	    /*
+	     * The event wasn't actually handled, so we have to restore the
+	     * proc field to allow the event to be attempted again.
+	     */
+
+	    evPtr->proc = proc;
+	}
+    }
+    Tcl_MutexUnlock(&(tsdPtr->queueMutex));
+    return 0;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_GetServiceMode --
+ *
+ *	This routine returns the current service mode of the notifier.
+ *
+ * Results:
+ *	Returns either TCL_SERVICE_ALL or TCL_SERVICE_NONE.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_GetServiceMode(void)
+{
+    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+
+    return tsdPtr->serviceMode;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_SetServiceMode --
+ *
+ *	This routine sets the current service mode of the tsdPtr->
+ *
+ * Results:
+ *	Returns the previous service mode.
+ *
+ * Side effects:
+ *	Invokes the notifier service mode hook function.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_SetServiceMode(
+    int mode)			/* New service mode: TCL_SERVICE_ALL or
+				 * TCL_SERVICE_NONE */
+{
+    int oldMode;
+    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+
+    oldMode = tsdPtr->serviceMode;
+    tsdPtr->serviceMode = mode;
+    Tcl_ServiceModeHook(mode);
+    return oldMode;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_SetMaxBlockTime --
+ *
+ *	This function is invoked by event sources to tell the notifier how
+ *	long it may block the next time it blocks. The timePtr argument gives
+ *	a maximum time; the actual time may be less if some other event source
+ *	requested a smaller time.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	May reduce the length of the next sleep in the tsdPtr->
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_SetMaxBlockTime(
+    const Tcl_Time *timePtr)		/* Specifies a maximum elapsed time for the
+				 * next blocking operation in the event
+				 * tsdPtr-> */
+{
+    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+
+    if (!tsdPtr->blockTimeSet || (timePtr->sec < tsdPtr->blockTime.sec)
+	    || ((timePtr->sec == tsdPtr->blockTime.sec)
+	    && (timePtr->usec < tsdPtr->blockTime.usec))) {
+	tsdPtr->blockTime = *timePtr;
+	tsdPtr->blockTimeSet = 1;
+    }
+
+    /*
+     * If we are called outside an event source traversal, set the timeout
+     * immediately.
+     */
+
+    if (!tsdPtr->inTraversal) {
+	Tcl_SetTimer(&tsdPtr->blockTime);
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_DoOneEvent --
+ *
+ *	Process a single event of some sort. If there's no work to do, wait
+ *	for an event to occur, then process it.
+ *
+ * Results:
+ *	The return value is 1 if the function actually found an event to
+ *	process. If no processing occurred, then 0 is returned (this can
+ *	happen if the TCL_DONT_WAIT flag is set or if there are no event
+ *	handlers to wait for in the set specified by flags).
+ *
+ * Side effects:
+ *	May delay execution of process while waiting for an event, unless
+ *	TCL_DONT_WAIT is set in the flags argument. Event sources are invoked
+ *	to check for and queue events. Event handlers may produce arbitrary
+ *	side effects.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_DoOneEvent(
+    int flags)			/* Miscellaneous flag values: may be any
+				 * combination of TCL_DONT_WAIT,
+				 * TCL_WINDOW_EVENTS, TCL_FILE_EVENTS,
+				 * TCL_TIMER_EVENTS, TCL_IDLE_EVENTS, or
+				 * others defined by event sources. */
+{
+    int result = 0, oldMode;
+    EventSource *sourcePtr;
+    Tcl_Time *timePtr;
+    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+
+    /*
+     * The first thing we do is to service any asynchronous event handlers.
+     */
+
+    if (Tcl_AsyncReady()) {
+	(void) Tcl_AsyncInvoke(NULL, 0);
+	return 1;
+    }
+
+    /*
+     * No event flags is equivalent to TCL_ALL_EVENTS.
+     */
+
+    if ((flags & TCL_ALL_EVENTS) == 0) {
+	flags |= TCL_ALL_EVENTS;
+    }
+
+    /*
+     * Set the service mode to none so notifier event routines won't try to
+     * service events recursively.
+     */
+
+    oldMode = tsdPtr->serviceMode;
+    tsdPtr->serviceMode = TCL_SERVICE_NONE;
+
+    /*
+     * The core of this function is an infinite loop, even though we only
+     * service one event. The reason for this is that we may be processing
+     * events that don't do anything inside of Tcl.
+     */
+
+    while (1) {
+	/*
+	 * If idle events are the only things to service, skip the main part
+	 * of the loop and go directly to handle idle events (i.e. don't wait
+	 * even if TCL_DONT_WAIT isn't set).
+	 */
+
+	if ((flags & TCL_ALL_EVENTS) == TCL_IDLE_EVENTS) {
+	    flags = TCL_IDLE_EVENTS | TCL_DONT_WAIT;
+	    goto idleEvents;
+	}
+
+	/*
+	 * Ask Tcl to service a queued event, if there are any.
+	 */
+
+	if (Tcl_ServiceEvent(flags)) {
+	    result = 1;
+	    break;
+	}
+
+	/*
+	 * If TCL_DONT_WAIT is set, be sure to poll rather than blocking,
+	 * otherwise reset the block time to infinity.
+	 */
+
+	if (flags & TCL_DONT_WAIT) {
+	    tsdPtr->blockTime.sec = 0;
+	    tsdPtr->blockTime.usec = 0;
+	    tsdPtr->blockTimeSet = 1;
+	} else {
+	    tsdPtr->blockTimeSet = 0;
+	}
+
+	/*
+	 * Set up all the event sources for new events. This will cause the
+	 * block time to be updated if necessary.
+	 */
+
+	tsdPtr->inTraversal = 1;
+	for (sourcePtr = tsdPtr->firstEventSourcePtr; sourcePtr != NULL;
+		sourcePtr = sourcePtr->nextPtr) {
+	    if (sourcePtr->setupProc) {
+		sourcePtr->setupProc(sourcePtr->clientData, flags);
+	    }
+	}
+	tsdPtr->inTraversal = 0;
+
+	if ((flags & TCL_DONT_WAIT) || tsdPtr->blockTimeSet) {
+	    timePtr = &tsdPtr->blockTime;
+	} else {
+	    timePtr = NULL;
+	}
+
+	/*
+	 * Wait for a new event or a timeout. If Tcl_WaitForEvent returns -1,
+	 * we should abort Tcl_DoOneEvent.
+	 */
+
+	result = Tcl_WaitForEvent(timePtr);
+	if (result < 0) {
+	    result = 0;
+	    break;
+	}
+
+	/*
+	 * Check all the event sources for new events.
+	 */
+
+	for (sourcePtr = tsdPtr->firstEventSourcePtr; sourcePtr != NULL;
+		sourcePtr = sourcePtr->nextPtr) {
+	    if (sourcePtr->checkProc) {
+		sourcePtr->checkProc(sourcePtr->clientData, flags);
+	    }
+	}
+
+	/*
+	 * Check for events queued by the notifier or event sources.
+	 */
+
+	if (Tcl_ServiceEvent(flags)) {
+	    result = 1;
+	    break;
+	}
+
+	/*
+	 * We've tried everything at this point, but nobody we know about had
+	 * anything to do. Check for idle events. If none, either quit or go
+	 * back to the top and try again.
+	 */
+
+    idleEvents:
+	if (flags & TCL_IDLE_EVENTS) {
+	    if (TclServiceIdle()) {
+		result = 1;
+		break;
+	    }
+	}
+	if (flags & TCL_DONT_WAIT) {
+	    break;
+	}
+
+	/*
+	 * If Tcl_WaitForEvent has returned 1, indicating that one system
+	 * event has been dispatched (and thus that some Tcl code might have
+	 * been indirectly executed), we break out of the loop. We do this to
+	 * give VwaitCmd for instance a chance to check if that system event
+	 * had the side effect of changing the variable (so the vwait can
+	 * return and unwind properly).
+	 *
+	 * NB: We will process idle events if any first, because otherwise we
+	 *     might never do the idle events if the notifier always gets
+	 *     system events.
+	 */
+
+	if (result) {
+	    break;
+	}
+    }
+
+    tsdPtr->serviceMode = oldMode;
+    return result;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_ServiceAll --
+ *
+ *	This routine checks all of the event sources, processes events that
+ *	are on the Tcl event queue, and then calls the any idle handlers.
+ *	Platform specific notifier callbacks that generate events should call
+ *	this routine before returning to the system in order to ensure that
+ *	Tcl gets a chance to process the new events.
+ *
+ * Results:
+ *	Returns 1 if an event or idle handler was invoked, else 0.
+ *
+ * Side effects:
+ *	Anything that an event or idle handler may do.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_ServiceAll(void)
+{
+    int result = 0;
+    EventSource *sourcePtr;
+    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+
+    if (tsdPtr->serviceMode == TCL_SERVICE_NONE) {
+	return result;
+    }
+
+    /*
+     * We need to turn off event servicing like we to in Tcl_DoOneEvent, to
+     * avoid recursive calls.
+     */
+
+    tsdPtr->serviceMode = TCL_SERVICE_NONE;
+
+    /*
+     * Check async handlers first.
+     */
+
+    if (Tcl_AsyncReady()) {
+	(void) Tcl_AsyncInvoke(NULL, 0);
+    }
+
+    /*
+     * Make a single pass through all event sources, queued events, and idle
+     * handlers. Note that we wait to update the notifier timer until the end
+     * so we can avoid multiple changes.
+     */
+
+    tsdPtr->inTraversal = 1;
+    tsdPtr->blockTimeSet = 0;
+
+    for (sourcePtr = tsdPtr->firstEventSourcePtr; sourcePtr != NULL;
+	    sourcePtr = sourcePtr->nextPtr) {
+	if (sourcePtr->setupProc) {
+	    sourcePtr->setupProc(sourcePtr->clientData, TCL_ALL_EVENTS);
+	}
+    }
+    for (sourcePtr = tsdPtr->firstEventSourcePtr; sourcePtr != NULL;
+	    sourcePtr = sourcePtr->nextPtr) {
+	if (sourcePtr->checkProc) {
+	    sourcePtr->checkProc(sourcePtr->clientData, TCL_ALL_EVENTS);
+	}
+    }
+
+    while (Tcl_ServiceEvent(0)) {
+	result = 1;
+    }
+    if (TclServiceIdle()) {
+	result = 1;
+    }
+
+    if (!tsdPtr->blockTimeSet) {
+	Tcl_SetTimer(NULL);
+    } else {
+	Tcl_SetTimer(&tsdPtr->blockTime);
+    }
+    tsdPtr->inTraversal = 0;
+    tsdPtr->serviceMode = TCL_SERVICE_ALL;
+    return result;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_ThreadAlert --
+ *
+ *	This function wakes up the notifier associated with the specified
+ *	thread (if there is one).
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_ThreadAlert(
+    Tcl_ThreadId threadId)	/* Identifier for thread to use. */
+{
+    ThreadSpecificData *tsdPtr;
+
+    /*
+     * Find the notifier associated with the specified thread. Note that we
+     * need to hold the listLock while calling Tcl_AlertNotifier to avoid a
+     * race condition where the specified thread might destroy its notifier.
+     */
+
+    Tcl_MutexLock(&listLock);
+    for (tsdPtr = firstNotifierPtr; tsdPtr; tsdPtr = tsdPtr->nextPtr) {
+	if (tsdPtr->threadId == threadId) {
+	    Tcl_AlertNotifier(tsdPtr->clientData);
+	    break;
+	}
+    }
+    Tcl_MutexUnlock(&listLock);
+}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tclOO.c b/generic/tclOO.c
new file mode 100644
index 0000000..ec666ee
--- /dev/null
+++ b/generic/tclOO.c
@@ -0,0 +1,3037 @@
+/*
+ * tclOO.c --
+ *
+ *	This file contains the object-system core (NB: not Tcl_Obj, but ::oo)
+ *
+ * Copyright (c) 2005-2012 by Donal K. Fellows
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include "tclInt.h"
+#include "tclOOInt.h"
+
+/*
+ * Commands in oo::define.
+ */
+
+static const struct {
+    const char *name;
+    Tcl_ObjCmdProc *objProc;
+    int flag;
+} defineCmds[] = {
+    {"constructor", TclOODefineConstructorObjCmd, 0},
+    {"deletemethod", TclOODefineDeleteMethodObjCmd, 0},
+    {"destructor", TclOODefineDestructorObjCmd, 0},
+    {"export", TclOODefineExportObjCmd, 0},
+    {"forward", TclOODefineForwardObjCmd, 0},
+    {"method", TclOODefineMethodObjCmd, 0},
+    {"renamemethod", TclOODefineRenameMethodObjCmd, 0},
+    {"self", TclOODefineSelfObjCmd, 0},
+    {"unexport", TclOODefineUnexportObjCmd, 0},
+    {NULL, NULL, 0}
+}, objdefCmds[] = {
+    {"class", TclOODefineClassObjCmd, 1},
+    {"deletemethod", TclOODefineDeleteMethodObjCmd, 1},
+    {"export", TclOODefineExportObjCmd, 1},
+    {"forward", TclOODefineForwardObjCmd, 1},
+    {"method", TclOODefineMethodObjCmd, 1},
+    {"renamemethod", TclOODefineRenameMethodObjCmd, 1},
+    {"unexport", TclOODefineUnexportObjCmd, 1},
+    {NULL, NULL, 0}
+};
+
+/*
+ * What sort of size of things we like to allocate.
+ */
+
+#define ALLOC_CHUNK 8
+
+/*
+ * Function declarations for things defined in this file.
+ */
+
+static Class *		AllocClass(Tcl_Interp *interp, Object *useThisObj);
+static Object *		AllocObject(Tcl_Interp *interp, const char *nameStr,
+			    const char *nsNameStr);
+static void		ClearMixins(Class *clsPtr);
+static void		ClearSuperclasses(Class *clsPtr);
+static int		CloneClassMethod(Tcl_Interp *interp, Class *clsPtr,
+			    Method *mPtr, Tcl_Obj *namePtr,
+			    Method **newMPtrPtr);
+static int		CloneObjectMethod(Tcl_Interp *interp, Object *oPtr,
+			    Method *mPtr, Tcl_Obj *namePtr);
+static void		DeletedDefineNamespace(ClientData clientData);
+static void		DeletedObjdefNamespace(ClientData clientData);
+static void		DeletedHelpersNamespace(ClientData clientData);
+static Tcl_NRPostProc	FinalizeAlloc;
+static Tcl_NRPostProc	FinalizeNext;
+static Tcl_NRPostProc	FinalizeObjectCall;
+static int		InitFoundation(Tcl_Interp *interp);
+static void		KillFoundation(ClientData clientData,
+			    Tcl_Interp *interp);
+static void		MyDeleted(ClientData clientData);
+static void		ObjectNamespaceDeleted(ClientData clientData);
+static void		ObjectRenamedTrace(ClientData clientData,
+			    Tcl_Interp *interp, const char *oldName,
+			    const char *newName, int flags);
+static void		ReleaseClassContents(Tcl_Interp *interp,Object *oPtr);
+static inline void	SquelchCachedName(Object *oPtr);
+static void		SquelchedNsFirst(ClientData clientData);
+
+static int		PublicObjectCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const *objv);
+static int		PublicNRObjectCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const *objv);
+static int		PrivateObjectCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const *objv);
+static int		PrivateNRObjectCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const *objv);
+
+/*
+ * Methods in the oo::object and oo::class classes. First, we define a helper
+ * macro that makes building the method type declaration structure a lot
+ * easier. No point in making life harder than it has to be!
+ *
+ * Note that the core methods don't need clone or free proc callbacks.
+ */
+
+#define DCM(name,visibility,proc) \
+    {name,visibility,\
+	{TCL_OO_METHOD_VERSION_CURRENT,"core method: "#name,proc,NULL,NULL}}
+
+static const DeclaredClassMethod objMethods[] = {
+    DCM("destroy", 1,	TclOO_Object_Destroy),
+    DCM("eval", 0,	TclOO_Object_Eval),
+    DCM("unknown", 0,	TclOO_Object_Unknown),
+    DCM("variable", 0,	TclOO_Object_LinkVar),
+    DCM("varname", 0,	TclOO_Object_VarName),
+    {NULL, 0, {0, NULL, NULL, NULL, NULL}}
+}, clsMethods[] = {
+    DCM("create", 1,	TclOO_Class_Create),
+    DCM("new", 1,	TclOO_Class_New),
+    DCM("createWithNamespace", 0, TclOO_Class_CreateNs),
+    {NULL, 0, {0, NULL, NULL, NULL, NULL}}
+};
+
+/*
+ * And for the oo::class constructor...
+ */
+
+static const Tcl_MethodType classConstructor = {
+    TCL_OO_METHOD_VERSION_CURRENT,
+    "oo::class constructor",
+    TclOO_Class_Constructor, NULL, NULL
+};
+
+/*
+ * Scripted parts of TclOO. First, the master script (cannot be outside this
+ * file).
+ */
+
+static const char *initScript =
+"package ifneeded TclOO " TCLOO_PATCHLEVEL " {# Already present, OK?};"
+"namespace eval ::oo { variable version " TCLOO_VERSION " };"
+"namespace eval ::oo { variable patchlevel " TCLOO_PATCHLEVEL " };";
+/* "tcl_findLibrary tcloo $oo::version $oo::version" */
+/* " tcloo.tcl OO_LIBRARY oo::library;"; */
+
+/*
+ * The scripted part of the definitions of slots.
+ */
+
+static const char *slotScript =
+"::oo::define ::oo::Slot {\n"
+"    method Get {} {error unimplemented}\n"
+"    method Set list {error unimplemented}\n"
+"    method -set args {\n"
+"        uplevel 1 [list [namespace which my] Set $args]\n"
+"    }\n"
+"    method -append args {\n"
+"        uplevel 1 [list [namespace which my] Set [list"
+"                {*}[uplevel 1 [list [namespace which my] Get]] {*}$args]]\n"
+"    }\n"
+"    method -clear {} {uplevel 1 [list [namespace which my] Set {}]}\n"
+"    forward --default-operation my -append\n"
+"    method unknown {args} {\n"
+"        set def --default-operation\n"
+"        if {[llength $args] == 0} {\n"
+"            return [uplevel 1 [list [namespace which my] $def]]\n"
+"        } elseif {![string match -* [lindex $args 0]]} {\n"
+"            return [uplevel 1 [list [namespace which my] $def {*}$args]]\n"
+"        }\n"
+"        next {*}$args\n"
+"    }\n"
+"    export -set -append -clear\n"
+"    unexport unknown destroy\n"
+"}\n"
+"::oo::objdefine ::oo::define::superclass forward --default-operation my -set\n"
+"::oo::objdefine ::oo::define::mixin forward --default-operation my -set\n"
+"::oo::objdefine ::oo::objdefine::mixin forward --default-operation my -set\n";
+
+/*
+ * The body of the <cloned> method of oo::object.
+ */
+
+static const char *clonedBody =
+"foreach p [info procs [info object namespace $originObject]::*] {"
+"    set args [info args $p];"
+"    set idx -1;"
+"    foreach a $args {"
+"        lset args [incr idx] "
+"            [if {[info default $p $a d]} {list $a $d} {list $a}]"
+"    };"
+"    set b [info body $p];"
+"    set p [namespace tail $p];"
+"    proc $p $args $b;"
+"};"
+"foreach v [info vars [info object namespace $originObject]::*] {"
+"    upvar 0 $v vOrigin;"
+"    namespace upvar [namespace current] [namespace tail $v] vNew;"
+"    if {[info exists vOrigin]} {"
+"        if {[array exists vOrigin]} {"
+"            array set vNew [array get vOrigin];"
+"        } else {"
+"            set vNew $vOrigin;"
+"        }"
+"    }"
+"}";
+
+/*
+ * The actual definition of the variable holding the TclOO stub table.
+ */
+
+MODULE_SCOPE const TclOOStubs tclOOStubs;
+
+/*
+ * Convenience macro for getting the foundation from an interpreter.
+ */
+
+#define GetFoundation(interp) \
+	((Foundation *)((Interp *)(interp))->objectFoundation)
+
+/*
+ * Macros to make inspecting into the guts of an object cleaner.
+ *
+ * The ocPtr parameter (only in these macros) is assumed to work fine with
+ * either an oPtr or a classPtr. Note that the roots oo::object and oo::class
+ * have _both_ their object and class flags tagged with ROOT_OBJECT and
+ * ROOT_CLASS respectively.
+ */
+
+#define Deleted(oPtr)		(((Object *)(oPtr))->command == NULL)
+#define IsRootObject(ocPtr)	((ocPtr)->flags & ROOT_OBJECT)
+#define IsRootClass(ocPtr)	((ocPtr)->flags & ROOT_CLASS)
+#define IsRoot(ocPtr)		((ocPtr)->flags & (ROOT_OBJECT|ROOT_CLASS))
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * TclOOInit --
+ *
+ *	Called to initialise the OO system within an interpreter.
+ *
+ * Result:
+ *	TCL_OK if the setup succeeded. Currently assumed to always work.
+ *
+ * Side effects:
+ *	Creates namespaces, commands, several classes and a number of
+ *	callbacks. Upon return, the OO system is ready for use.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+int
+TclOOInit(
+    Tcl_Interp *interp)		/* The interpreter to install into. */
+{
+    /*
+     * Build the core of the OO system.
+     */
+
+    if (InitFoundation(interp) != TCL_OK) {
+	return TCL_ERROR;
+    }
+
+    /*
+     * Run our initialization script and, if that works, declare the package
+     * to be fully provided.
+     */
+
+    if (Tcl_Eval(interp, initScript) != TCL_OK) {
+	return TCL_ERROR;
+    }
+
+    return Tcl_PkgProvideEx(interp, "TclOO", TCLOO_PATCHLEVEL,
+	    (ClientData) &tclOOStubs);
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * TclOOGetFoundation --
+ *
+ *	Get a reference to the OO core class system.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+Foundation *
+TclOOGetFoundation(
+    Tcl_Interp *interp)
+{
+    return GetFoundation(interp);
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * InitFoundation --
+ *
+ *	Set up the core of the OO core class system. This is a structure
+ *	holding references to the magical bits that need to be known about in
+ *	other places, plus the oo::object and oo::class classes.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+static int
+InitFoundation(
+    Tcl_Interp *interp)
+{
+    static Tcl_ThreadDataKey tsdKey;
+    ThreadLocalData *tsdPtr =
+	    Tcl_GetThreadData(&tsdKey, sizeof(ThreadLocalData));
+    Foundation *fPtr = ckalloc(sizeof(Foundation));
+    Tcl_Obj *namePtr, *argsPtr, *bodyPtr;
+    Tcl_DString buffer;
+    Command *cmdPtr;
+    int i;
+
+    /*
+     * Initialize the structure that holds the OO system core. This is
+     * attached to the interpreter via an assocData entry; not very efficient,
+     * but the best we can do without hacking the core more.
+     */
+
+    memset(fPtr, 0, sizeof(Foundation));
+    ((Interp *) interp)->objectFoundation = fPtr;
+    fPtr->interp = interp;
+    fPtr->ooNs = Tcl_CreateNamespace(interp, "::oo", fPtr, NULL);
+    Tcl_Export(interp, fPtr->ooNs, "[a-z]*", 1);
+    fPtr->defineNs = Tcl_CreateNamespace(interp, "::oo::define", fPtr,
+	    DeletedDefineNamespace);
+    fPtr->objdefNs = Tcl_CreateNamespace(interp, "::oo::objdefine", fPtr,
+	    DeletedObjdefNamespace);
+    fPtr->helpersNs = Tcl_CreateNamespace(interp, "::oo::Helpers", fPtr,
+	    DeletedHelpersNamespace);
+    fPtr->epoch = 0;
+    fPtr->tsdPtr = tsdPtr;
+    TclNewLiteralStringObj(fPtr->unknownMethodNameObj, "unknown");
+    TclNewLiteralStringObj(fPtr->constructorName, "<constructor>");
+    TclNewLiteralStringObj(fPtr->destructorName, "<destructor>");
+    TclNewLiteralStringObj(fPtr->clonedName, "<cloned>");
+    TclNewLiteralStringObj(fPtr->defineName, "::oo::define");
+    Tcl_IncrRefCount(fPtr->unknownMethodNameObj);
+    Tcl_IncrRefCount(fPtr->constructorName);
+    Tcl_IncrRefCount(fPtr->destructorName);
+    Tcl_IncrRefCount(fPtr->clonedName);
+    Tcl_IncrRefCount(fPtr->defineName);
+    Tcl_CreateObjCommand(interp, "::oo::UnknownDefinition",
+	    TclOOUnknownDefinition, NULL, NULL);
+    TclNewLiteralStringObj(namePtr, "::oo::UnknownDefinition");
+    Tcl_SetNamespaceUnknownHandler(interp, fPtr->defineNs, namePtr);
+    Tcl_SetNamespaceUnknownHandler(interp, fPtr->objdefNs, namePtr);
+
+    /*
+     * Create the subcommands in the oo::define and oo::objdefine spaces.
+     */
+
+    Tcl_DStringInit(&buffer);
+    for (i=0 ; defineCmds[i].name ; i++) {
+	TclDStringAppendLiteral(&buffer, "::oo::define::");
+	Tcl_DStringAppend(&buffer, defineCmds[i].name, -1);
+	Tcl_CreateObjCommand(interp, Tcl_DStringValue(&buffer),
+		defineCmds[i].objProc, INT2PTR(defineCmds[i].flag), NULL);
+	Tcl_DStringFree(&buffer);
+    }
+    for (i=0 ; objdefCmds[i].name ; i++) {
+	TclDStringAppendLiteral(&buffer, "::oo::objdefine::");
+	Tcl_DStringAppend(&buffer, objdefCmds[i].name, -1);
+	Tcl_CreateObjCommand(interp, Tcl_DStringValue(&buffer),
+		objdefCmds[i].objProc, INT2PTR(objdefCmds[i].flag), NULL);
+	Tcl_DStringFree(&buffer);
+    }
+
+    Tcl_CallWhenDeleted(interp, KillFoundation, NULL);
+
+    /*
+     * Create the objects at the core of the object system. These need to be
+     * spliced manually.
+     */
+
+    fPtr->objectCls = AllocClass(interp,
+	    AllocObject(interp, "::oo::object", NULL));
+    fPtr->classCls = AllocClass(interp,
+	    AllocObject(interp, "::oo::class", NULL));
+    fPtr->objectCls->thisPtr->selfCls = fPtr->classCls;
+    fPtr->objectCls->thisPtr->flags |= ROOT_OBJECT;
+    fPtr->objectCls->flags |= ROOT_OBJECT;
+    fPtr->objectCls->superclasses.num = 0;
+    ckfree(fPtr->objectCls->superclasses.list);
+    fPtr->objectCls->superclasses.list = NULL;
+    fPtr->classCls->thisPtr->selfCls = fPtr->classCls;
+    fPtr->classCls->thisPtr->flags |= ROOT_CLASS;
+    fPtr->classCls->flags |= ROOT_CLASS;
+    TclOOAddToInstances(fPtr->objectCls->thisPtr, fPtr->classCls);
+    TclOOAddToInstances(fPtr->classCls->thisPtr, fPtr->classCls);
+    TclOOAddToSubclasses(fPtr->classCls, fPtr->objectCls);
+    AddRef(fPtr->objectCls->thisPtr);
+    AddRef(fPtr->objectCls);
+
+    /*
+     * Basic method declarations for the core classes.
+     */
+
+    for (i=0 ; objMethods[i].name ; i++) {
+	TclOONewBasicMethod(interp, fPtr->objectCls, &objMethods[i]);
+    }
+    for (i=0 ; clsMethods[i].name ; i++) {
+	TclOONewBasicMethod(interp, fPtr->classCls, &clsMethods[i]);
+    }
+
+    /*
+     * Create the default <cloned> method implementation, used when 'oo::copy'
+     * is called to finish the copying of one object to another.
+     */
+
+    TclNewLiteralStringObj(argsPtr, "originObject");
+    Tcl_IncrRefCount(argsPtr);
+    bodyPtr = Tcl_NewStringObj(clonedBody, -1);
+    TclOONewProcMethod(interp, fPtr->objectCls, 0, fPtr->clonedName, argsPtr,
+	    bodyPtr, NULL);
+    TclDecrRefCount(argsPtr);
+
+    /*
+     * Finish setting up the class of classes by marking the 'new' method as
+     * private; classes, unlike general objects, must have explicit names. We
+     * also need to create the constructor for classes.
+     */
+
+    TclNewLiteralStringObj(namePtr, "new");
+    Tcl_NewInstanceMethod(interp, (Tcl_Object) fPtr->classCls->thisPtr,
+	    namePtr /* keeps ref */, 0 /* ==private */, NULL, NULL);
+    fPtr->classCls->constructorPtr = (Method *) Tcl_NewMethod(interp,
+	    (Tcl_Class) fPtr->classCls, NULL, 0, &classConstructor, NULL);
+
+    /*
+     * Create non-object commands and plug ourselves into the Tcl [info]
+     * ensemble.
+     */
+
+    cmdPtr = (Command *) Tcl_NRCreateCommand(interp, "::oo::Helpers::next",
+	    NULL, TclOONextObjCmd, NULL, NULL);
+    cmdPtr->compileProc = TclCompileObjectNextCmd;
+    cmdPtr = (Command *) Tcl_NRCreateCommand(interp, "::oo::Helpers::nextto",
+	    NULL, TclOONextToObjCmd, NULL, NULL);
+    cmdPtr->compileProc = TclCompileObjectNextToCmd;
+    cmdPtr = (Command *) Tcl_CreateObjCommand(interp, "::oo::Helpers::self",
+	    TclOOSelfObjCmd, NULL, NULL);
+    cmdPtr->compileProc = TclCompileObjectSelfCmd;
+    Tcl_CreateObjCommand(interp, "::oo::define", TclOODefineObjCmd, NULL,
+	    NULL);
+    Tcl_CreateObjCommand(interp, "::oo::objdefine", TclOOObjDefObjCmd, NULL,
+	    NULL);
+    Tcl_CreateObjCommand(interp, "::oo::copy", TclOOCopyObjectCmd, NULL,NULL);
+    TclOOInitInfo(interp);
+
+    /*
+     * Now make the class of slots.
+     */
+
+    if (TclOODefineSlots(fPtr) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    return Tcl_Eval(interp, slotScript);
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * DeletedDefineNamespace, DeletedObjdefNamespace, DeletedHelpersNamespace --
+ *
+ *	Simple helpers used to clear fields of the foundation when they no
+ *	longer hold useful information.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+static void
+DeletedDefineNamespace(
+    ClientData clientData)
+{
+    Foundation *fPtr = clientData;
+
+    fPtr->defineNs = NULL;
+}
+
+static void
+DeletedObjdefNamespace(
+    ClientData clientData)
+{
+    Foundation *fPtr = clientData;
+
+    fPtr->objdefNs = NULL;
+}
+
+static void
+DeletedHelpersNamespace(
+    ClientData clientData)
+{
+    Foundation *fPtr = clientData;
+
+    fPtr->helpersNs = NULL;
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * KillFoundation --
+ *
+ *	Delete those parts of the OO core that are not deleted automatically
+ *	when the objects and classes themselves are destroyed.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+static void
+KillFoundation(
+    ClientData clientData,	/* Pointer to the OO system foundation
+				 * structure. */
+    Tcl_Interp *interp)		/* The interpreter containing the OO system
+				 * foundation. */
+{
+    Foundation *fPtr = GetFoundation(interp);
+
+    DelRef(fPtr->objectCls->thisPtr);
+    DelRef(fPtr->objectCls);
+    TclDecrRefCount(fPtr->unknownMethodNameObj);
+    TclDecrRefCount(fPtr->constructorName);
+    TclDecrRefCount(fPtr->destructorName);
+    TclDecrRefCount(fPtr->clonedName);
+    TclDecrRefCount(fPtr->defineName);
+    ckfree(fPtr);
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * AllocObject --
+ *
+ *	Allocate an object of basic type. Does not splice the object into its
+ *	class's instance list.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+static Object *
+AllocObject(
+    Tcl_Interp *interp,		/* Interpreter within which to create the
+				 * object. */
+    const char *nameStr,	/* The name of the object to create, or NULL
+				 * if the OO system should pick the object
+				 * name itself (equal to the namespace
+				 * name). */
+    const char *nsNameStr)	/* The name of the namespace to create, or
+				 * NULL if the OO system should pick a unique
+				 * name itself. If this is non-NULL but names
+				 * a namespace that already exists, the effect
+				 * will be the same as if this was NULL. */
+{
+    Foundation *fPtr = GetFoundation(interp);
+    Object *oPtr;
+    Command *cmdPtr;
+    CommandTrace *tracePtr;
+    int creationEpoch, ignored;
+
+    oPtr = ckalloc(sizeof(Object));
+    memset(oPtr, 0, sizeof(Object));
+
+    /*
+     * Every object has a namespace; make one. Note that this also normally
+     * computes the creation epoch value for the object, a sequence number
+     * that is unique to the object (and which allows us to manage method
+     * caching without comparing pointers).
+     *
+     * When creating a namespace, we first check to see if the caller
+     * specified the name for the namespace. If not, we generate namespace
+     * names using the epoch until such time as a new namespace is actually
+     * created.
+     */
+
+    if (nsNameStr != NULL) {
+	oPtr->namespacePtr = Tcl_CreateNamespace(interp, nsNameStr, oPtr,
+		ObjectNamespaceDeleted);
+	if (oPtr->namespacePtr != NULL) {
+	    creationEpoch = ++fPtr->tsdPtr->nsCount;
+	    goto configNamespace;
+	}
+	Tcl_ResetResult(interp);
+    }
+
+    while (1) {
+	char objName[10 + TCL_INTEGER_SPACE];
+
+	sprintf(objName, "::oo::Obj%d", ++fPtr->tsdPtr->nsCount);
+	oPtr->namespacePtr = Tcl_CreateNamespace(interp, objName, oPtr,
+		ObjectNamespaceDeleted);
+	if (oPtr->namespacePtr != NULL) {
+	    creationEpoch = fPtr->tsdPtr->nsCount;
+	    break;
+	}
+
+	/*
+	 * Could not make that namespace, so we make another. But first we
+	 * have to get rid of the error message from Tcl_CreateNamespace,
+	 * since that's something that should not be exposed to the user.
+	 */
+
+	Tcl_ResetResult(interp);
+    }
+
+    /*
+     * Make the namespace know about the helper commands. This grants access
+     * to the [self] and [next] commands.
+     */
+
+  configNamespace:
+    if (fPtr->helpersNs != NULL) {
+	TclSetNsPath((Namespace *) oPtr->namespacePtr, 1, &fPtr->helpersNs);
+    }
+    TclOOSetupVariableResolver(oPtr->namespacePtr);
+
+    /*
+     * Suppress use of compiled versions of the commands in this object's
+     * namespace and its children; causes wrong behaviour without expensive
+     * recompilation. [Bug 2037727]
+     */
+
+    ((Namespace *) oPtr->namespacePtr)->flags |= NS_SUPPRESS_COMPILATION;
+
+    /*
+     * Set up a callback to get notification of the deletion of a namespace
+     * when enough of the namespace still remains to execute commands and
+     * access variables in it. [Bug 2950259]
+     */
+
+    ((Namespace *) oPtr->namespacePtr)->earlyDeleteProc = SquelchedNsFirst;
+
+    /*
+     * Fill in the rest of the non-zero/NULL parts of the structure.
+     */
+
+    oPtr->fPtr = fPtr;
+    oPtr->selfCls = fPtr->objectCls;
+    oPtr->creationEpoch = creationEpoch;
+    oPtr->refCount = 1;
+    oPtr->flags = USE_CLASS_CACHE;
+
+    /*
+     * Finally, create the object commands and initialize the trace on the
+     * public command (so that the object structures are deleted when the
+     * command is deleted).
+     */
+
+    if (!nameStr) {
+	oPtr->command = Tcl_CreateObjCommand(interp,
+		oPtr->namespacePtr->fullName, PublicObjectCmd, oPtr, NULL);
+    } else if (nameStr[0] == ':' && nameStr[1] == ':') {
+	oPtr->command = Tcl_CreateObjCommand(interp, nameStr,
+		PublicObjectCmd, oPtr, NULL);
+    } else {
+	Tcl_DString buffer;
+
+	Tcl_DStringInit(&buffer);
+	Tcl_DStringAppend(&buffer,
+		Tcl_GetCurrentNamespace(interp)->fullName, -1);
+	TclDStringAppendLiteral(&buffer, "::");
+	Tcl_DStringAppend(&buffer, nameStr, -1);
+	oPtr->command = Tcl_CreateObjCommand(interp,
+		Tcl_DStringValue(&buffer), PublicObjectCmd, oPtr, NULL);
+	Tcl_DStringFree(&buffer);
+    }
+
+    /*
+     * Add the NRE command and trace directly. While this breaks a number of
+     * abstractions, it is faster and we're inside Tcl here so we're allowed.
+     */
+
+    cmdPtr = (Command *) oPtr->command;
+    cmdPtr->nreProc = PublicNRObjectCmd;
+    cmdPtr->tracePtr = tracePtr = ckalloc(sizeof(CommandTrace));
+    tracePtr->traceProc = ObjectRenamedTrace;
+    tracePtr->clientData = oPtr;
+    tracePtr->flags = TCL_TRACE_RENAME|TCL_TRACE_DELETE;
+    tracePtr->nextPtr = NULL;
+    tracePtr->refCount = 1;
+
+    /*
+     * Access the namespace command table directly when creating "my" to avoid
+     * a bottleneck in string manipulation. Another abstraction-buster.
+     */
+
+    cmdPtr = ckalloc(sizeof(Command));
+    memset(cmdPtr, 0, sizeof(Command));
+    cmdPtr->nsPtr = (Namespace *) oPtr->namespacePtr;
+    cmdPtr->hPtr = Tcl_CreateHashEntry(&cmdPtr->nsPtr->cmdTable, "my",
+	    &ignored);
+    cmdPtr->refCount = 1;
+    cmdPtr->objProc = PrivateObjectCmd;
+    cmdPtr->deleteProc = MyDeleted;
+    cmdPtr->objClientData = cmdPtr->deleteData = oPtr;
+    cmdPtr->proc = TclInvokeObjectCommand;
+    cmdPtr->clientData = cmdPtr;
+    cmdPtr->nreProc = PrivateNRObjectCmd;
+    Tcl_SetHashValue(cmdPtr->hPtr, cmdPtr);
+    oPtr->myCommand = (Tcl_Command) cmdPtr;
+
+    return oPtr;
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * SquelchCachedName --
+ *
+ *	Encapsulates how to throw away a cached object name. Called from
+ *	object rename traces and at object destruction.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+static inline void
+SquelchCachedName(
+    Object *oPtr)
+{
+    if (oPtr->cachedNameObj) {
+	Tcl_DecrRefCount(oPtr->cachedNameObj);
+	oPtr->cachedNameObj = NULL;
+    }
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * MyDeleted --
+ *
+ *	This callback is triggered when the object's [my] command is deleted
+ *	by any mechanism. It just marks the object as not having a [my]
+ *	command, and so prevents cleanup of that when the object itself is
+ *	deleted.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+static void
+MyDeleted(
+    ClientData clientData)	/* Reference to the object whose [my] has been
+				 * squelched. */
+{
+    register Object *oPtr = clientData;
+
+    oPtr->myCommand = NULL;
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * SquelchedNsFirst --
+ *
+ *	This callback is triggered when the object's namespace is deleted by
+ *	any mechanism. It deletes the object's public command if it has not
+ *	already been deleted, so ensuring that destructors get run at an
+ *	appropriate time. [Bug 2950259]
+ *
+ * ----------------------------------------------------------------------
+ */
+
+static void
+SquelchedNsFirst(
+    ClientData clientData)
+{
+    Object *oPtr = clientData;
+
+    if (oPtr->command) {
+	Tcl_DeleteCommandFromToken(oPtr->fPtr->interp, oPtr->command);
+    }
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * ObjectRenamedTrace --
+ *
+ *	This callback is triggered when the object is deleted by any
+ *	mechanism. It runs the destructors and arranges for the actual cleanup
+ *	of the object's namespace, which in turn triggers cleansing of the
+ *	object data structures.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+static void
+ObjectRenamedTrace(
+    ClientData clientData,	/* The object being deleted. */
+    Tcl_Interp *interp,		/* The interpreter containing the object. */
+    const char *oldName,	/* What the object was (last) called. */
+    const char *newName,	/* What it's getting renamed to. (unused) */
+    int flags)			/* Why was the object deleted? */
+{
+    Object *oPtr = clientData;
+    Foundation *fPtr = oPtr->fPtr;
+
+    /*
+     * If this is a rename and not a delete of the object, we just flush the
+     * cache of the object name.
+     */
+
+    if (flags & TCL_TRACE_RENAME) {
+	SquelchCachedName(oPtr);
+	return;
+    }
+
+    /*
+     * Oh dear, the object really is being deleted. Handle this by running the
+     * destructors and deleting the object's namespace, which in turn causes
+     * the real object structures to be deleted.
+     *
+     * Note that it is possible for the namespace to be deleted before the
+     * command. Because of that case, we must take care here to mark the
+     * command as being deleted so that if we return here we don't run into
+     * reentrancy problems.
+     *
+     * We also do not run destructors on the core class objects when the
+     * interpreter is being deleted; their incestuous nature causes problems
+     * in that case when the destructor is partially deleted before the uses
+     * of it have gone. [Bug 2949397]
+     */
+
+    AddRef(oPtr);
+    AddRef(fPtr->classCls);
+    AddRef(fPtr->objectCls);
+    AddRef(fPtr->classCls->thisPtr);
+    AddRef(fPtr->objectCls->thisPtr);
+    oPtr->command = NULL;
+
+    if (!(oPtr->flags & DESTRUCTOR_CALLED) && !Tcl_InterpDeleted(interp)) {
+	CallContext *contextPtr =
+		TclOOGetCallContext(oPtr, NULL, DESTRUCTOR, NULL);
+	int result;
+	Tcl_InterpState state;
+
+	oPtr->flags |= DESTRUCTOR_CALLED;
+	if (contextPtr != NULL) {
+	    contextPtr->callPtr->flags |= DESTRUCTOR;
+	    contextPtr->skip = 0;
+	    state = Tcl_SaveInterpState(interp, TCL_OK);
+	    result = Tcl_NRCallObjProc(interp, TclOOInvokeContext,
+		    contextPtr, 0, NULL);
+	    if (result != TCL_OK) {
+		Tcl_BackgroundException(interp, result);
+	    }
+	    Tcl_RestoreInterpState(interp, state);
+	    TclOODeleteContext(contextPtr);
+	}
+    }
+
+    /*
+     * OK, the destructor's been run. Time to splat the class data (if any)
+     * and nuke the namespace (which triggers the final crushing of the object
+     * structure itself).
+     *
+     * The class of objects needs some special care; if it is deleted (and
+     * we're not killing the whole interpreter) we force the delete of the
+     * class of classes now as well. Due to the incestuous nature of those two
+     * classes, if one goes the other must too and yet the tangle can
+     * sometimes not go away automatically; we force it here. [Bug 2962664]
+     */
+
+    if (!Tcl_InterpDeleted(interp) && IsRootObject(oPtr)
+	    && !Deleted(fPtr->classCls->thisPtr)) {
+	Tcl_DeleteCommandFromToken(interp, fPtr->classCls->thisPtr->command);
+    }
+
+    if (oPtr->classPtr != NULL) {
+	AddRef(oPtr->classPtr);
+	ReleaseClassContents(interp, oPtr);
+    }
+
+    /*
+     * The namespace is only deleted if it hasn't already been deleted. [Bug
+     * 2950259]
+     */
+
+    if (((Namespace *) oPtr->namespacePtr)->earlyDeleteProc != NULL) {
+	Tcl_DeleteNamespace(oPtr->namespacePtr);
+    }
+    if (oPtr->classPtr) {
+	DelRef(oPtr->classPtr);
+    }
+    DelRef(fPtr->classCls->thisPtr);
+    DelRef(fPtr->objectCls->thisPtr);
+    DelRef(fPtr->classCls);
+    DelRef(fPtr->objectCls);
+    DelRef(oPtr);
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * ClearMixins, ClearSuperclasses --
+ *
+ *	Utility functions for correctly clearing the list of mixins or
+ *	superclasses of a class. Will ckfree() the list storage.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+static void
+ClearMixins(
+    Class *clsPtr)
+{
+    int i;
+    Class *mixinPtr;
+
+    if (clsPtr->mixins.num == 0) {
+	return;
+    }
+
+    FOREACH(mixinPtr, clsPtr->mixins) {
+	TclOORemoveFromMixinSubs(clsPtr, mixinPtr);
+    }
+    ckfree(clsPtr->mixins.list);
+    clsPtr->mixins.list = NULL;
+    clsPtr->mixins.num = 0;
+}
+
+static void
+ClearSuperclasses(
+    Class *clsPtr)
+{
+    int i;
+    Class *superPtr;
+
+    if (clsPtr->superclasses.num == 0) {
+	return;
+    }
+
+    FOREACH(superPtr, clsPtr->superclasses) {
+	TclOORemoveFromSubclasses(clsPtr, superPtr);
+    }
+    ckfree(clsPtr->superclasses.list);
+    clsPtr->superclasses.list = NULL;
+    clsPtr->superclasses.num = 0;
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * ReleaseClassContents --
+ *
+ *	Tear down the special class data structure, including deleting all
+ *	dependent classes and objects.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+static void
+ReleaseClassContents(
+    Tcl_Interp *interp,		/* The interpreter containing the class. */
+    Object *oPtr)		/* The object representing the class. */
+{
+    FOREACH_HASH_DECLS;
+    int i;
+    Class *clsPtr = oPtr->classPtr, *mixinSubclassPtr, *subclassPtr;
+    Object *instancePtr;
+    Foundation *fPtr = oPtr->fPtr;
+
+    /*
+     * Sanity check!
+     */
+
+    if (!Deleted(oPtr)) {
+	if (IsRootClass(oPtr)) {
+	    Tcl_Panic("deleting class structure for non-deleted %s",
+		    "::oo::class");
+	} else if (IsRootObject(oPtr)) {
+	    Tcl_Panic("deleting class structure for non-deleted %s",
+		    "::oo::object");
+	} else {
+	    Tcl_Panic("deleting class structure for non-deleted %s",
+		    "general object");
+	}
+    }
+
+    /*
+     * Lock a number of dependent objects until we've stopped putting our
+     * fingers in them.
+     */
+
+    FOREACH(mixinSubclassPtr, clsPtr->mixinSubs) {
+	if (mixinSubclassPtr != NULL) {
+	    AddRef(mixinSubclassPtr);
+	    AddRef(mixinSubclassPtr->thisPtr);
+	}
+    }
+    FOREACH(subclassPtr, clsPtr->subclasses) {
+	if (subclassPtr != NULL && !IsRoot(subclassPtr)) {
+	    AddRef(subclassPtr);
+	    AddRef(subclassPtr->thisPtr);
+	}
+    }
+    if (!IsRootClass(oPtr)) {
+	FOREACH(instancePtr, clsPtr->instances) {
+	    int j;
+	    if (instancePtr->selfCls == clsPtr) {
+		instancePtr->flags |= CLASS_GONE;
+	    }
+	    for(j=0 ; j<instancePtr->mixins.num ; j++) {
+		Class *mixin = instancePtr->mixins.list[j];
+		if (mixin == clsPtr) {
+		    instancePtr->mixins.list[j] = NULL;
+		}
+	    }
+	    if (instancePtr != NULL && !IsRoot(instancePtr)) {
+		AddRef(instancePtr);
+	    }
+	}
+    }
+
+    /*
+     * Squelch classes that this class has been mixed into.
+     */
+
+    FOREACH(mixinSubclassPtr, clsPtr->mixinSubs) {
+	if (!Deleted(mixinSubclassPtr->thisPtr)) {
+	    Tcl_DeleteCommandFromToken(interp,
+		    mixinSubclassPtr->thisPtr->command);
+	}
+	ClearMixins(mixinSubclassPtr);
+	DelRef(mixinSubclassPtr->thisPtr);
+	DelRef(mixinSubclassPtr);
+    }
+    if (clsPtr->mixinSubs.list != NULL) {
+	ckfree(clsPtr->mixinSubs.list);
+	clsPtr->mixinSubs.list = NULL;
+	clsPtr->mixinSubs.num = 0;
+    }
+
+    /*
+     * Squelch subclasses of this class.
+     */
+
+    FOREACH(subclassPtr, clsPtr->subclasses) {
+	if (IsRoot(subclassPtr)) {
+	    continue;
+	}
+	if (!Deleted(subclassPtr->thisPtr)) {
+	    Tcl_DeleteCommandFromToken(interp, subclassPtr->thisPtr->command);
+	}
+	ClearSuperclasses(subclassPtr);
+	DelRef(subclassPtr->thisPtr);
+	DelRef(subclassPtr);
+    }
+    if (clsPtr->subclasses.list != NULL) {
+	ckfree(clsPtr->subclasses.list);
+	clsPtr->subclasses.list = NULL;
+	clsPtr->subclasses.num = 0;
+    }
+
+    /*
+     * Squelch instances of this class (includes objects we're mixed into).
+     */
+
+    if (!IsRootClass(oPtr)) {
+	FOREACH(instancePtr, clsPtr->instances) {
+	    if (instancePtr == NULL || IsRoot(instancePtr)) {
+		continue;
+	    }
+	    if (!Deleted(instancePtr)) {
+		Tcl_DeleteCommandFromToken(interp, instancePtr->command);
+		/*
+		 * Tcl_DeleteCommandFromToken() may have done to whole
+		 * job for us.  Roll back and check again.
+		 */
+		i--;
+		continue;
+	    }
+	    DelRef(instancePtr);
+	}
+    }
+    if (clsPtr->instances.list != NULL) {
+	ckfree(clsPtr->instances.list);
+	clsPtr->instances.list = NULL;
+	clsPtr->instances.num = 0;
+    }
+
+    /*
+     * Special: We delete these after everything else.
+     */
+
+    if (IsRootClass(oPtr) && !Deleted(fPtr->objectCls->thisPtr)) {
+	Tcl_DeleteCommandFromToken(interp, fPtr->objectCls->thisPtr->command);
+    }
+
+    /*
+     * Squelch method implementation chain caches.
+     */
+
+    if (clsPtr->constructorChainPtr) {
+	TclOODeleteChain(clsPtr->constructorChainPtr);
+	clsPtr->constructorChainPtr = NULL;
+    }
+    if (clsPtr->destructorChainPtr) {
+	TclOODeleteChain(clsPtr->destructorChainPtr);
+	clsPtr->destructorChainPtr = NULL;
+    }
+    if (clsPtr->classChainCache) {
+	CallChain *callPtr;
+
+	FOREACH_HASH_VALUE(callPtr, clsPtr->classChainCache) {
+	    TclOODeleteChain(callPtr);
+	}
+	Tcl_DeleteHashTable(clsPtr->classChainCache);
+	ckfree(clsPtr->classChainCache);
+	clsPtr->classChainCache = NULL;
+    }
+
+    /*
+     * Squelch our filter list.
+     */
+
+    if (clsPtr->filters.num) {
+	Tcl_Obj *filterObj;
+
+	FOREACH(filterObj, clsPtr->filters) {
+	    TclDecrRefCount(filterObj);
+	}
+	ckfree(clsPtr->filters.list);
+	clsPtr->filters.num = 0;
+    }
+
+    /*
+     * Squelch our metadata.
+     */
+
+    if (clsPtr->metadataPtr != NULL) {
+	Tcl_ObjectMetadataType *metadataTypePtr;
+	ClientData value;
+
+	FOREACH_HASH(metadataTypePtr, value, clsPtr->metadataPtr) {
+	    metadataTypePtr->deleteProc(value);
+	}
+	Tcl_DeleteHashTable(clsPtr->metadataPtr);
+	ckfree(clsPtr->metadataPtr);
+	clsPtr->metadataPtr = NULL;
+    }
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * ObjectNamespaceDeleted --
+ *
+ *	Callback when the object's namespace is deleted. Used to clean up the
+ *	data structures associated with the object. The complicated bit is
+ *	that this can sometimes happen before the object's command is deleted
+ *	(interpreter teardown is complex!)
+ *
+ * ----------------------------------------------------------------------
+ */
+
+static void
+ObjectNamespaceDeleted(
+    ClientData clientData)	/* Pointer to the class whose namespace is
+				 * being deleted. */
+{
+    Object *oPtr = clientData;
+    FOREACH_HASH_DECLS;
+    Class *clsPtr = oPtr->classPtr, *mixinPtr;
+    Method *mPtr;
+    Tcl_Obj *filterObj, *variableObj;
+    int i;
+
+    /*
+     * Instruct everyone to no longer use any allocated fields of the object.
+     * Also delete the commands that refer to the object at this point (if
+     * they still exist) because otherwise their references to the object
+     * point into freed memory, allowing crashes.
+     */
+
+    if (oPtr->command) {
+	Tcl_DeleteCommandFromToken(oPtr->fPtr->interp, oPtr->command);
+    }
+    if (oPtr->myCommand) {
+	Tcl_DeleteCommandFromToken(oPtr->fPtr->interp, oPtr->myCommand);
+    }
+
+    /*
+     * Splice the object out of its context. After this, we must *not* call
+     * methods on the object.
+     */
+
+    if (!IsRootObject(oPtr) && !(oPtr->flags & CLASS_GONE)) {
+	TclOORemoveFromInstances(oPtr, oPtr->selfCls);
+    }
+
+    FOREACH(mixinPtr, oPtr->mixins) {
+	if (mixinPtr) {
+	    TclOORemoveFromInstances(oPtr, mixinPtr);
+	}
+    }
+    if (i) {
+	ckfree(oPtr->mixins.list);
+    }
+
+    FOREACH(filterObj, oPtr->filters) {
+	TclDecrRefCount(filterObj);
+    }
+    if (i) {
+	ckfree(oPtr->filters.list);
+    }
+
+    if (oPtr->methodsPtr) {
+	FOREACH_HASH_VALUE(mPtr, oPtr->methodsPtr) {
+	    TclOODelMethodRef(mPtr);
+	}
+	Tcl_DeleteHashTable(oPtr->methodsPtr);
+	ckfree(oPtr->methodsPtr);
+    }
+
+    FOREACH(variableObj, oPtr->variables) {
+	TclDecrRefCount(variableObj);
+    }
+    if (i) {
+	ckfree(oPtr->variables.list);
+    }
+
+    if (oPtr->chainCache) {
+	TclOODeleteChainCache(oPtr->chainCache);
+    }
+
+    SquelchCachedName(oPtr);
+
+    if (oPtr->metadataPtr != NULL) {
+	Tcl_ObjectMetadataType *metadataTypePtr;
+	ClientData value;
+
+	FOREACH_HASH(metadataTypePtr, value, oPtr->metadataPtr) {
+	    metadataTypePtr->deleteProc(value);
+	}
+	Tcl_DeleteHashTable(oPtr->metadataPtr);
+	ckfree(oPtr->metadataPtr);
+	oPtr->metadataPtr = NULL;
+    }
+
+    /*
+     * If this was a class, there's additional deletion work to do.
+     */
+
+    if (clsPtr != NULL) {
+	Tcl_ObjectMetadataType *metadataTypePtr;
+	ClientData value;
+
+	if (clsPtr->metadataPtr != NULL) {
+	    FOREACH_HASH(metadataTypePtr, value, clsPtr->metadataPtr) {
+		metadataTypePtr->deleteProc(value);
+	    }
+	    Tcl_DeleteHashTable(clsPtr->metadataPtr);
+	    ckfree(clsPtr->metadataPtr);
+	    clsPtr->metadataPtr = NULL;
+	}
+
+	FOREACH(filterObj, clsPtr->filters) {
+	    TclDecrRefCount(filterObj);
+	}
+	if (i) {
+	    ckfree(clsPtr->filters.list);
+	    clsPtr->filters.num = 0;
+	}
+
+	ClearMixins(clsPtr);
+
+	ClearSuperclasses(clsPtr);
+
+	if (clsPtr->subclasses.list) {
+	    ckfree(clsPtr->subclasses.list);
+	    clsPtr->subclasses.num = 0;
+	}
+	if (clsPtr->instances.list) {
+	    ckfree(clsPtr->instances.list);
+	    clsPtr->instances.num = 0;
+	}
+	if (clsPtr->mixinSubs.list) {
+	    ckfree(clsPtr->mixinSubs.list);
+	    clsPtr->mixinSubs.num = 0;
+	}
+
+	FOREACH_HASH_VALUE(mPtr, &clsPtr->classMethods) {
+	    TclOODelMethodRef(mPtr);
+	}
+	Tcl_DeleteHashTable(&clsPtr->classMethods);
+	TclOODelMethodRef(clsPtr->constructorPtr);
+	TclOODelMethodRef(clsPtr->destructorPtr);
+
+	FOREACH(variableObj, clsPtr->variables) {
+	    TclDecrRefCount(variableObj);
+	}
+	if (i) {
+	    ckfree(clsPtr->variables.list);
+	}
+
+	DelRef(clsPtr);
+    }
+
+    /*
+     * Delete the object structure itself.
+     */
+
+    DelRef(oPtr);
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * TclOORemoveFromInstances --
+ *
+ *	Utility function to remove an object from the list of instances within
+ *	a class.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+void
+TclOORemoveFromInstances(
+    Object *oPtr,		/* The instance to remove. */
+    Class *clsPtr)		/* The class (possibly) containing the
+				 * reference to the instance. */
+{
+    int i;
+    Object *instPtr;
+
+    FOREACH(instPtr, clsPtr->instances) {
+	if (oPtr == instPtr) {
+	    goto removeInstance;
+	}
+    }
+    return;
+
+  removeInstance:
+    if (Deleted(clsPtr->thisPtr)) {
+	if (!IsRootClass(clsPtr)) {
+	    DelRef(clsPtr->instances.list[i]);
+	}
+	clsPtr->instances.list[i] = NULL;
+    } else {
+	clsPtr->instances.num--;
+	if (i < clsPtr->instances.num) {
+	    clsPtr->instances.list[i] =
+		    clsPtr->instances.list[clsPtr->instances.num];
+	}
+	clsPtr->instances.list[clsPtr->instances.num] = NULL;
+    }
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * TclOOAddToInstances --
+ *
+ *	Utility function to add an object to the list of instances within a
+ *	class.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+void
+TclOOAddToInstances(
+    Object *oPtr,		/* The instance to add. */
+    Class *clsPtr)		/* The class to add the instance to. It is
+				 * assumed that the class is not already
+				 * present as an instance in the class. */
+{
+    if (Deleted(clsPtr->thisPtr)) {
+	return;
+    }
+    if (clsPtr->instances.num >= clsPtr->instances.size) {
+	clsPtr->instances.size += ALLOC_CHUNK;
+	if (clsPtr->instances.size == ALLOC_CHUNK) {
+	    clsPtr->instances.list = ckalloc(sizeof(Object *) * ALLOC_CHUNK);
+	} else {
+	    clsPtr->instances.list = ckrealloc(clsPtr->instances.list,
+		    sizeof(Object *) * clsPtr->instances.size);
+	}
+    }
+    clsPtr->instances.list[clsPtr->instances.num++] = oPtr;
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * TclOORemoveFromSubclasses --
+ *
+ *	Utility function to remove a class from the list of subclasses within
+ *	another class.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+void
+TclOORemoveFromSubclasses(
+    Class *subPtr,		/* The subclass to remove. */
+    Class *superPtr)		/* The superclass to (possibly) remove the
+				 * subclass reference from. */
+{
+    int i;
+    Class *subclsPtr;
+
+    FOREACH(subclsPtr, superPtr->subclasses) {
+	if (subPtr == subclsPtr) {
+	    goto removeSubclass;
+	}
+    }
+    return;
+
+  removeSubclass:
+    if (!Deleted(superPtr->thisPtr)) {
+	superPtr->subclasses.num--;
+	if (i < superPtr->subclasses.num) {
+	    superPtr->subclasses.list[i] =
+		    superPtr->subclasses.list[superPtr->subclasses.num];
+	}
+	superPtr->subclasses.list[superPtr->subclasses.num] = NULL;
+    }
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * TclOOAddToSubclasses --
+ *
+ *	Utility function to add a class to the list of subclasses within
+ *	another class.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+void
+TclOOAddToSubclasses(
+    Class *subPtr,		/* The subclass to add. */
+    Class *superPtr)		/* The superclass to add the subclass to. It
+				 * is assumed that the class is not already
+				 * present as a subclass in the superclass. */
+{
+    if (Deleted(superPtr->thisPtr)) {
+	return;
+    }
+    if (superPtr->subclasses.num >= superPtr->subclasses.size) {
+	superPtr->subclasses.size += ALLOC_CHUNK;
+	if (superPtr->subclasses.size == ALLOC_CHUNK) {
+	    superPtr->subclasses.list = ckalloc(sizeof(Class*) * ALLOC_CHUNK);
+	} else {
+	    superPtr->subclasses.list = ckrealloc(superPtr->subclasses.list,
+		    sizeof(Class *) * superPtr->subclasses.size);
+	}
+    }
+    superPtr->subclasses.list[superPtr->subclasses.num++] = subPtr;
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * TclOORemoveFromMixinSubs --
+ *
+ *	Utility function to remove a class from the list of mixinSubs within
+ *	another class.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+void
+TclOORemoveFromMixinSubs(
+    Class *subPtr,		/* The subclass to remove. */
+    Class *superPtr)		/* The superclass to (possibly) remove the
+				 * subclass reference from. */
+{
+    int i;
+    Class *subclsPtr;
+
+    FOREACH(subclsPtr, superPtr->mixinSubs) {
+	if (subPtr == subclsPtr) {
+	    goto removeSubclass;
+	}
+    }
+    return;
+
+  removeSubclass:
+    if (!Deleted(superPtr->thisPtr)) {
+	superPtr->mixinSubs.num--;
+	if (i < superPtr->mixinSubs.num) {
+	    superPtr->mixinSubs.list[i] =
+		    superPtr->mixinSubs.list[superPtr->mixinSubs.num];
+	}
+	superPtr->mixinSubs.list[superPtr->mixinSubs.num] = NULL;
+    }
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * TclOOAddToMixinSubs --
+ *
+ *	Utility function to add a class to the list of mixinSubs within
+ *	another class.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+void
+TclOOAddToMixinSubs(
+    Class *subPtr,		/* The subclass to add. */
+    Class *superPtr)		/* The superclass to add the subclass to. It
+				 * is assumed that the class is not already
+				 * present as a subclass in the superclass. */
+{
+    if (Deleted(superPtr->thisPtr)) {
+	return;
+    }
+    if (superPtr->mixinSubs.num >= superPtr->mixinSubs.size) {
+	superPtr->mixinSubs.size += ALLOC_CHUNK;
+	if (superPtr->mixinSubs.size == ALLOC_CHUNK) {
+	    superPtr->mixinSubs.list = ckalloc(sizeof(Class *) * ALLOC_CHUNK);
+	} else {
+	    superPtr->mixinSubs.list = ckrealloc(superPtr->mixinSubs.list,
+		    sizeof(Class *) * superPtr->mixinSubs.size);
+	}
+    }
+    superPtr->mixinSubs.list[superPtr->mixinSubs.num++] = subPtr;
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * AllocClass --
+ *
+ *	Allocate a basic class. Does not splice the class object into its
+ *	class's instance list.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+static Class *
+AllocClass(
+    Tcl_Interp *interp,		/* Interpreter within which to allocate the
+				 * class. */
+    Object *useThisObj)		/* Object that is to act as the class
+				 * representation, or NULL if a new object
+				 * (with automatic name) is to be used. */
+{
+    Foundation *fPtr = GetFoundation(interp);
+    Class *clsPtr = ckalloc(sizeof(Class));
+
+    /*
+     * Make an object if we haven't been given one.
+     */
+
+    memset(clsPtr, 0, sizeof(Class));
+    if (useThisObj == NULL) {
+	clsPtr->thisPtr = AllocObject(interp, NULL, NULL);
+    } else {
+	clsPtr->thisPtr = useThisObj;
+    }
+
+    /*
+     * Configure the namespace path for the class's object.
+     */
+
+    if (fPtr->helpersNs != NULL) {
+	Tcl_Namespace *path[2];
+
+	path[0] = fPtr->helpersNs;
+	path[1] = fPtr->ooNs;
+	TclSetNsPath((Namespace *) clsPtr->thisPtr->namespacePtr, 2, path);
+    } else {
+	TclSetNsPath((Namespace *) clsPtr->thisPtr->namespacePtr, 1,
+		&fPtr->ooNs);
+    }
+
+    /*
+     * Class objects inherit from the class of classes unless they inherit
+     * from some subclass of it. Enforce this right now.
+     */
+
+    clsPtr->thisPtr->selfCls = fPtr->classCls;
+
+    /*
+     * Classes are subclasses of oo::object, i.e. the objects they create are
+     * objects.
+     */
+
+    clsPtr->superclasses.num = 1;
+    clsPtr->superclasses.list = ckalloc(sizeof(Class *));
+    clsPtr->superclasses.list[0] = fPtr->objectCls;
+
+    /*
+     * Finish connecting the class structure to the object structure.
+     */
+
+    clsPtr->thisPtr->classPtr = clsPtr;
+
+    /*
+     * That's the complicated bit. Now fill in the rest of the non-zero/NULL
+     * fields.
+     */
+
+    clsPtr->refCount = 1;
+    Tcl_InitObjHashTable(&clsPtr->classMethods);
+    return clsPtr;
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * Tcl_NewObjectInstance --
+ *
+ *	Allocate a new instance of an object.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+Tcl_Object
+Tcl_NewObjectInstance(
+    Tcl_Interp *interp,		/* Interpreter context. */
+    Tcl_Class cls,		/* Class to create an instance of. */
+    const char *nameStr,	/* Name of object to create, or NULL to ask
+				 * the code to pick its own unique name. */
+    const char *nsNameStr,	/* Name of namespace to create inside object,
+				 * or NULL to ask the code to pick its own
+				 * unique name. */
+    int objc,			/* Number of arguments. Negative value means
+				 * do not call constructor. */
+    Tcl_Obj *const *objv,	/* Argument list. */
+    int skip)			/* Number of arguments to _not_ pass to the
+				 * constructor. */
+{
+    register Class *classPtr = (Class *) cls;
+    Foundation *fPtr = GetFoundation(interp);
+    Object *oPtr;
+
+    /*
+     * Check if we're going to create an object over an existing command;
+     * that's not allowed.
+     */
+
+    if (nameStr && Tcl_FindCommand(interp, nameStr, NULL,
+	    TCL_NAMESPACE_ONLY)) {
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		"can't create object \"%s\": command already exists with"
+		" that name", nameStr));
+	Tcl_SetErrorCode(interp, "TCL", "OO", "OVERWRITE_OBJECT", NULL);
+	return NULL;
+    }
+
+    /*
+     * Create the object.
+     */
+
+    oPtr = AllocObject(interp, nameStr, nsNameStr);
+    oPtr->selfCls = classPtr;
+    TclOOAddToInstances(oPtr, classPtr);
+
+    /*
+     * Check to see if we're really creating a class. If so, allocate the
+     * class structure as well.
+     */
+
+    if (TclOOIsReachable(fPtr->classCls, classPtr)) {
+	/*
+	 * Is a class, so attach a class structure. Note that the AllocClass
+	 * function splices the structure into the object, so we don't have
+	 * to. Once that's done, we need to repatch the object to have the
+	 * right class since AllocClass interferes with that.
+	 */
+
+	AllocClass(interp, oPtr);
+	oPtr->selfCls = classPtr;
+	TclOOAddToSubclasses(oPtr->classPtr, fPtr->objectCls);
+    }
+
+    /*
+     * Run constructors, except when objc < 0 (a special flag case used for
+     * object cloning only).
+     */
+
+    if (objc >= 0) {
+	CallContext *contextPtr =
+		TclOOGetCallContext(oPtr, NULL, CONSTRUCTOR, NULL);
+
+	if (contextPtr != NULL) {
+	    int isRoot, result;
+	    Tcl_InterpState state;
+
+	    state = Tcl_SaveInterpState(interp, TCL_OK);
+	    contextPtr->callPtr->flags |= CONSTRUCTOR;
+	    contextPtr->skip = skip;
+
+	    /*
+	     * Adjust the ensmble tracking record if necessary. [Bug 3514761]
+	     */
+
+	    isRoot = TclInitRewriteEnsemble(interp, skip, skip, objv);
+	    result = Tcl_NRCallObjProc(interp, TclOOInvokeContext, contextPtr,
+		    objc, objv);
+
+	    if (isRoot) {
+		TclResetRewriteEnsemble(interp, 1);
+	    }
+
+	    /*
+	     * It's an error if the object was whacked in the constructor.
+	     * Force this if it isn't already an error (don't want to lose
+	     * errors by accident...) [Bug 2903011]
+	     */
+
+	    if (result != TCL_ERROR && Deleted(oPtr)) {
+		Tcl_SetObjResult(interp, Tcl_NewStringObj(
+			"object deleted in constructor", -1));
+		Tcl_SetErrorCode(interp, "TCL", "OO", "STILLBORN", NULL);
+		result = TCL_ERROR;
+	    }
+	    TclOODeleteContext(contextPtr);
+	    if (result != TCL_OK) {
+		Tcl_DiscardInterpState(state);
+
+		/*
+		 * Take care to not delete a deleted object; that would be
+		 * bad. [Bug 2903011] Also take care to make sure that we have
+		 * the name of the command before we delete it. [Bug
+		 * 9dd1bd7a74]
+		 */
+
+		if (!Deleted(oPtr)) {
+		    (void) TclOOObjectName(interp, oPtr);
+		    Tcl_DeleteCommandFromToken(interp, oPtr->command);
+		}
+		return NULL;
+	    }
+	    Tcl_RestoreInterpState(interp, state);
+	}
+    }
+
+    return (Tcl_Object) oPtr;
+}
+
+int
+TclNRNewObjectInstance(
+    Tcl_Interp *interp,		/* Interpreter context. */
+    Tcl_Class cls,		/* Class to create an instance of. */
+    const char *nameStr,	/* Name of object to create, or NULL to ask
+				 * the code to pick its own unique name. */
+    const char *nsNameStr,	/* Name of namespace to create inside object,
+				 * or NULL to ask the code to pick its own
+				 * unique name. */
+    int objc,			/* Number of arguments. Negative value means
+				 * do not call constructor. */
+    Tcl_Obj *const *objv,	/* Argument list. */
+    int skip,			/* Number of arguments to _not_ pass to the
+				 * constructor. */
+    Tcl_Object *objectPtr)	/* Place to write the object reference upon
+				 * successful allocation. */
+{
+    register Class *classPtr = (Class *) cls;
+    Foundation *fPtr = GetFoundation(interp);
+    CallContext *contextPtr;
+    Tcl_InterpState state;
+    Object *oPtr;
+
+    /*
+     * Check if we're going to create an object over an existing command;
+     * that's not allowed.
+     */
+
+    if (nameStr && Tcl_FindCommand(interp, nameStr, NULL,
+	    TCL_NAMESPACE_ONLY)) {
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		"can't create object \"%s\": command already exists with"
+		" that name", nameStr));
+	Tcl_SetErrorCode(interp, "TCL", "OO", "OVERWRITE_OBJECT", NULL);
+	return TCL_ERROR;
+    }
+
+    /*
+     * Create the object.
+     */
+
+    oPtr = AllocObject(interp, nameStr, nsNameStr);
+    oPtr->selfCls = classPtr;
+    TclOOAddToInstances(oPtr, classPtr);
+
+    /*
+     * Check to see if we're really creating a class. If so, allocate the
+     * class structure as well.
+     */
+
+    if (TclOOIsReachable(fPtr->classCls, classPtr)) {
+	/*
+	 * Is a class, so attach a class structure. Note that the AllocClass
+	 * function splices the structure into the object, so we don't have
+	 * to. Once that's done, we need to repatch the object to have the
+	 * right class since AllocClass interferes with that.
+	 */
+
+	AllocClass(interp, oPtr);
+	oPtr->selfCls = classPtr;
+	TclOOAddToSubclasses(oPtr->classPtr, fPtr->objectCls);
+    }
+
+    /*
+     * Run constructors, except when objc < 0 (a special flag case used for
+     * object cloning only). If there aren't any constructors, we do nothing.
+     */
+
+    if (objc < 0) {
+	*objectPtr = (Tcl_Object) oPtr;
+	return TCL_OK;
+    }
+    contextPtr = TclOOGetCallContext(oPtr, NULL, CONSTRUCTOR, NULL);
+    if (contextPtr == NULL) {
+	*objectPtr = (Tcl_Object) oPtr;
+	return TCL_OK;
+    }
+
+    state = Tcl_SaveInterpState(interp, TCL_OK);
+    contextPtr->callPtr->flags |= CONSTRUCTOR;
+    contextPtr->skip = skip;
+
+    /*
+     * Adjust the ensmble tracking record if necessary. [Bug 3514761]
+     */
+
+    if (TclInitRewriteEnsemble(interp, skip, skip, objv)) {
+	TclNRAddCallback(interp, TclClearRootEnsemble, NULL, NULL, NULL, NULL);
+    }
+
+    /*
+     * Fire off the constructors non-recursively.
+     */
+
+    AddRef(oPtr);
+    TclNRAddCallback(interp, FinalizeAlloc, contextPtr, oPtr, state,
+	    objectPtr);
+    TclPushTailcallPoint(interp);
+    return TclOOInvokeContext(contextPtr, interp, objc, objv);
+}
+
+static int
+FinalizeAlloc(
+    ClientData data[],
+    Tcl_Interp *interp,
+    int result)
+{
+    CallContext *contextPtr = data[0];
+    Object *oPtr = data[1];
+    Tcl_InterpState state = data[2];
+    Tcl_Object *objectPtr = data[3];
+
+    /*
+     * It's an error if the object was whacked in the constructor. Force this
+     * if it isn't already an error (don't want to lose errors by accident...)
+     * [Bug 2903011]
+     */
+
+    if (result != TCL_ERROR && Deleted(oPtr)) {
+	Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		"object deleted in constructor", -1));
+	Tcl_SetErrorCode(interp, "TCL", "OO", "STILLBORN", NULL);
+	result = TCL_ERROR;
+    }
+    TclOODeleteContext(contextPtr);
+    if (result != TCL_OK) {
+	Tcl_DiscardInterpState(state);
+
+	/*
+	 * Take care to not delete a deleted object; that would be bad. [Bug
+	 * 2903011] Also take care to make sure that we have the name of the
+	 * command before we delete it. [Bug 9dd1bd7a74]
+	 */
+
+	if (!Deleted(oPtr)) {
+	    (void) TclOOObjectName(interp, oPtr);
+	    Tcl_DeleteCommandFromToken(interp, oPtr->command);
+	}
+	DelRef(oPtr);
+	return TCL_ERROR;
+    }
+    Tcl_RestoreInterpState(interp, state);
+    *objectPtr = (Tcl_Object) oPtr;
+    DelRef(oPtr);
+    return TCL_OK;
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * Tcl_CopyObjectInstance --
+ *
+ *	Creates a copy of an object. Does not copy the backing namespace,
+ *	since the correct way to do that (e.g., shallow/deep) depends on the
+ *	object/class's own policies.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+Tcl_Object
+Tcl_CopyObjectInstance(
+    Tcl_Interp *interp,
+    Tcl_Object sourceObject,
+    const char *targetName,
+    const char *targetNamespaceName)
+{
+    Object *oPtr = (Object *) sourceObject, *o2Ptr;
+    FOREACH_HASH_DECLS;
+    Method *mPtr;
+    Class *mixinPtr;
+    CallContext *contextPtr;
+    Tcl_Obj *keyPtr, *filterObj, *variableObj, *args[3];
+    int i, result;
+
+    /*
+     * Sanity check.
+     */
+
+    if (IsRootClass(oPtr)) {
+	Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		"may not clone the class of classes", -1));
+	Tcl_SetErrorCode(interp, "TCL", "OO", "CLONING_CLASS", NULL);
+	return NULL;
+    }
+
+    /*
+     * Build the instance. Note that this does not run any constructors.
+     */
+
+    o2Ptr = (Object *) Tcl_NewObjectInstance(interp,
+	    (Tcl_Class) oPtr->selfCls, targetName, targetNamespaceName, -1,
+	    NULL, -1);
+    if (o2Ptr == NULL) {
+	return NULL;
+    }
+
+    /*
+     * Copy the object-local methods to the new object.
+     */
+
+    if (oPtr->methodsPtr) {
+	FOREACH_HASH(keyPtr, mPtr, oPtr->methodsPtr) {
+	    if (CloneObjectMethod(interp, o2Ptr, mPtr, keyPtr) != TCL_OK) {
+		Tcl_DeleteCommandFromToken(interp, o2Ptr->command);
+		return NULL;
+	    }
+	}
+    }
+
+    /*
+     * Copy the object's mixin references to the new object.
+     */
+
+    FOREACH(mixinPtr, o2Ptr->mixins) {
+	if (mixinPtr && mixinPtr != o2Ptr->selfCls) {
+	    TclOORemoveFromInstances(o2Ptr, mixinPtr);
+	}
+    }
+    DUPLICATE(o2Ptr->mixins, oPtr->mixins, Class *);
+    FOREACH(mixinPtr, o2Ptr->mixins) {
+	if (mixinPtr && mixinPtr != o2Ptr->selfCls) {
+	    TclOOAddToInstances(o2Ptr, mixinPtr);
+	}
+    }
+
+    /*
+     * Copy the object's filter list to the new object.
+     */
+
+    DUPLICATE(o2Ptr->filters, oPtr->filters, Tcl_Obj *);
+    FOREACH(filterObj, o2Ptr->filters) {
+	Tcl_IncrRefCount(filterObj);
+    }
+
+    /*
+     * Copy the object's variable resolution list to the new object.
+     */
+
+    DUPLICATE(o2Ptr->variables, oPtr->variables, Tcl_Obj *);
+    FOREACH(variableObj, o2Ptr->variables) {
+	Tcl_IncrRefCount(variableObj);
+    }
+
+    /*
+     * Copy the object's flags to the new object, clearing those that must be
+     * kept object-local. The duplicate is never deleted at this point, nor is
+     * it the root of the object system or in the midst of processing a filter
+     * call.
+     */
+
+    o2Ptr->flags = oPtr->flags & ~(
+	    OBJECT_DELETED | ROOT_OBJECT | ROOT_CLASS | FILTER_HANDLING);
+
+    /*
+     * Copy the object's metadata.
+     */
+
+    if (oPtr->metadataPtr != NULL) {
+	Tcl_ObjectMetadataType *metadataTypePtr;
+	ClientData value, duplicate;
+
+	FOREACH_HASH(metadataTypePtr, value, oPtr->metadataPtr) {
+	    if (metadataTypePtr->cloneProc == NULL) {
+		duplicate = value;
+	    } else {
+		if (metadataTypePtr->cloneProc(interp, value,
+			&duplicate) != TCL_OK) {
+		    Tcl_DeleteCommandFromToken(interp, o2Ptr->command);
+		    return NULL;
+		}
+	    }
+	    if (duplicate != NULL) {
+		Tcl_ObjectSetMetadata((Tcl_Object) o2Ptr, metadataTypePtr,
+			duplicate);
+	    }
+	}
+    }
+
+    /*
+     * Copy the class, if present. Note that if there is a class present in
+     * the source object, there must also be one in the copy.
+     */
+
+    if (oPtr->classPtr != NULL) {
+	Class *clsPtr = oPtr->classPtr;
+	Class *cls2Ptr = o2Ptr->classPtr;
+	Class *superPtr;
+
+	/*
+	 * Copy the class flags across.
+	 */
+
+	cls2Ptr->flags = clsPtr->flags;
+
+	/*
+	 * Ensure that the new class's superclass structure is the same as the
+	 * old class's.
+	 */
+
+	FOREACH(superPtr, cls2Ptr->superclasses) {
+	    TclOORemoveFromSubclasses(cls2Ptr, superPtr);
+	}
+	if (cls2Ptr->superclasses.num) {
+	    cls2Ptr->superclasses.list = ckrealloc(cls2Ptr->superclasses.list,
+		    sizeof(Class *) * clsPtr->superclasses.num);
+	} else {
+	    cls2Ptr->superclasses.list =
+		    ckalloc(sizeof(Class *) * clsPtr->superclasses.num);
+	}
+	memcpy(cls2Ptr->superclasses.list, clsPtr->superclasses.list,
+		sizeof(Class *) * clsPtr->superclasses.num);
+	cls2Ptr->superclasses.num = clsPtr->superclasses.num;
+	FOREACH(superPtr, cls2Ptr->superclasses) {
+	    TclOOAddToSubclasses(cls2Ptr, superPtr);
+	}
+
+	/*
+	 * Duplicate the source class's filters.
+	 */
+
+	DUPLICATE(cls2Ptr->filters, clsPtr->filters, Tcl_Obj *);
+	FOREACH(filterObj, cls2Ptr->filters) {
+	    Tcl_IncrRefCount(filterObj);
+	}
+
+	/*
+	 * Copy the source class's variable resolution list.
+	 */
+
+	DUPLICATE(cls2Ptr->variables, clsPtr->variables, Tcl_Obj *);
+	FOREACH(variableObj, cls2Ptr->variables) {
+	    Tcl_IncrRefCount(variableObj);
+	}
+
+	/*
+	 * Duplicate the source class's mixins (which cannot be circular
+	 * references to the duplicate).
+	 */
+
+	FOREACH(mixinPtr, cls2Ptr->mixins) {
+	    TclOORemoveFromMixinSubs(cls2Ptr, mixinPtr);
+	}
+	if (cls2Ptr->mixins.num != 0) {
+	    ckfree(clsPtr->mixins.list);
+	}
+	DUPLICATE(cls2Ptr->mixins, clsPtr->mixins, Class *);
+	FOREACH(mixinPtr, cls2Ptr->mixins) {
+	    TclOOAddToMixinSubs(cls2Ptr, mixinPtr);
+	}
+
+	/*
+	 * Duplicate the source class's methods, constructor and destructor.
+	 */
+
+	FOREACH_HASH(keyPtr, mPtr, &clsPtr->classMethods) {
+	    if (CloneClassMethod(interp, cls2Ptr, mPtr, keyPtr,
+		    NULL) != TCL_OK) {
+		Tcl_DeleteCommandFromToken(interp, o2Ptr->command);
+		return NULL;
+	    }
+	}
+	if (clsPtr->constructorPtr) {
+	    if (CloneClassMethod(interp, cls2Ptr, clsPtr->constructorPtr,
+		    NULL, &cls2Ptr->constructorPtr) != TCL_OK) {
+		Tcl_DeleteCommandFromToken(interp, o2Ptr->command);
+		return NULL;
+	    }
+	}
+	if (clsPtr->destructorPtr) {
+	    if (CloneClassMethod(interp, cls2Ptr, clsPtr->destructorPtr, NULL,
+		    &cls2Ptr->destructorPtr) != TCL_OK) {
+		Tcl_DeleteCommandFromToken(interp, o2Ptr->command);
+		return NULL;
+	    }
+	}
+
+	/*
+	 * Duplicate the class's metadata.
+	 */
+
+	if (clsPtr->metadataPtr != NULL) {
+	    Tcl_ObjectMetadataType *metadataTypePtr;
+	    ClientData value, duplicate;
+
+	    FOREACH_HASH(metadataTypePtr, value, clsPtr->metadataPtr) {
+		if (metadataTypePtr->cloneProc == NULL) {
+		    duplicate = value;
+		} else {
+		    if (metadataTypePtr->cloneProc(interp, value,
+			    &duplicate) != TCL_OK) {
+			Tcl_DeleteCommandFromToken(interp, o2Ptr->command);
+			return NULL;
+		    }
+		}
+		if (duplicate != NULL) {
+		    Tcl_ClassSetMetadata((Tcl_Class) cls2Ptr, metadataTypePtr,
+			    duplicate);
+		}
+	    }
+	}
+    }
+
+    TclResetRewriteEnsemble(interp, 1);
+    contextPtr = TclOOGetCallContext(o2Ptr, oPtr->fPtr->clonedName, 0, NULL);
+    if (contextPtr) {
+	args[0] = TclOOObjectName(interp, o2Ptr);
+	args[1] = oPtr->fPtr->clonedName;
+	args[2] = TclOOObjectName(interp, oPtr);
+	Tcl_IncrRefCount(args[0]);
+	Tcl_IncrRefCount(args[1]);
+	Tcl_IncrRefCount(args[2]);
+	result = Tcl_NRCallObjProc(interp, TclOOInvokeContext, contextPtr, 3,
+		args);
+	TclDecrRefCount(args[0]);
+	TclDecrRefCount(args[1]);
+	TclDecrRefCount(args[2]);
+	TclOODeleteContext(contextPtr);
+	if (result == TCL_ERROR) {
+	    Tcl_AddErrorInfo(interp,
+		    "\n    (while performing post-copy callback)");
+	}
+	if (result != TCL_OK) {
+	    Tcl_DeleteCommandFromToken(interp, o2Ptr->command);
+	    return NULL;
+	}
+    }
+
+    return (Tcl_Object) o2Ptr;
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * CloneObjectMethod, CloneClassMethod --
+ *
+ *	Helper functions used for cloning methods. They work identically to
+ *	each other, except for the difference between them in how they
+ *	register the cloned method on a successful clone.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+static int
+CloneObjectMethod(
+    Tcl_Interp *interp,
+    Object *oPtr,
+    Method *mPtr,
+    Tcl_Obj *namePtr)
+{
+    if (mPtr->typePtr == NULL) {
+	Tcl_NewInstanceMethod(interp, (Tcl_Object) oPtr, namePtr,
+		mPtr->flags & PUBLIC_METHOD, NULL, NULL);
+    } else if (mPtr->typePtr->cloneProc) {
+	ClientData newClientData;
+
+	if (mPtr->typePtr->cloneProc(interp, mPtr->clientData,
+		&newClientData) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	Tcl_NewInstanceMethod(interp, (Tcl_Object) oPtr, namePtr,
+		mPtr->flags & PUBLIC_METHOD, mPtr->typePtr, newClientData);
+    } else {
+	Tcl_NewInstanceMethod(interp, (Tcl_Object) oPtr, namePtr,
+		mPtr->flags & PUBLIC_METHOD, mPtr->typePtr, mPtr->clientData);
+    }
+    return TCL_OK;
+}
+
+static int
+CloneClassMethod(
+    Tcl_Interp *interp,
+    Class *clsPtr,
+    Method *mPtr,
+    Tcl_Obj *namePtr,
+    Method **m2PtrPtr)
+{
+    Method *m2Ptr;
+
+    if (mPtr->typePtr == NULL) {
+	m2Ptr = (Method *) Tcl_NewMethod(interp, (Tcl_Class) clsPtr,
+		namePtr, mPtr->flags & PUBLIC_METHOD, NULL, NULL);
+    } else if (mPtr->typePtr->cloneProc) {
+	ClientData newClientData;
+
+	if (mPtr->typePtr->cloneProc(interp, mPtr->clientData,
+		&newClientData) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	m2Ptr = (Method *) Tcl_NewMethod(interp, (Tcl_Class) clsPtr,
+		namePtr, mPtr->flags & PUBLIC_METHOD, mPtr->typePtr,
+		newClientData);
+    } else {
+	m2Ptr = (Method *) Tcl_NewMethod(interp, (Tcl_Class) clsPtr,
+		namePtr, mPtr->flags & PUBLIC_METHOD, mPtr->typePtr,
+		mPtr->clientData);
+    }
+    if (m2PtrPtr != NULL) {
+	*m2PtrPtr = m2Ptr;
+    }
+    return TCL_OK;
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * Tcl_ClassGetMetadata, Tcl_ClassSetMetadata, Tcl_ObjectGetMetadata,
+ * Tcl_ObjectSetMetadata --
+ *
+ *	Metadata management API. The metadata system allows code in extensions
+ *	to attach arbitrary non-NULL pointers to objects and classes without
+ *	the different things that might be interested being able to interfere
+ *	with each other. Apart from non-NULL-ness, these routines attach no
+ *	interpretation to the meaning of the metadata pointers.
+ *
+ *	The Tcl_*GetMetadata routines get the metadata pointer attached that
+ *	has been related with a particular type, or NULL if no metadata
+ *	associated with the given type has been attached.
+ *
+ *	The Tcl_*SetMetadata routines set or delete the metadata pointer that
+ *	is related to a particular type. The value associated with the type is
+ *	deleted (if present; no-op otherwise) if the value is NULL, and
+ *	attached (replacing the previous value, which is deleted if present)
+ *	otherwise. This means it is impossible to attach a NULL value for any
+ *	metadata type.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+ClientData
+Tcl_ClassGetMetadata(
+    Tcl_Class clazz,
+    const Tcl_ObjectMetadataType *typePtr)
+{
+    Class *clsPtr = (Class *) clazz;
+    Tcl_HashEntry *hPtr;
+
+    /*
+     * If there's no metadata store attached, the type in question has
+     * definitely not been attached either!
+     */
+
+    if (clsPtr->metadataPtr == NULL) {
+	return NULL;
+    }
+
+    /*
+     * There is a metadata store, so look in it for the given type.
+     */
+
+    hPtr = Tcl_FindHashEntry(clsPtr->metadataPtr, (char *) typePtr);
+
+    /*
+     * Return the metadata value if we found it, otherwise NULL.
+     */
+
+    if (hPtr == NULL) {
+	return NULL;
+    }
+    return Tcl_GetHashValue(hPtr);
+}
+
+void
+Tcl_ClassSetMetadata(
+    Tcl_Class clazz,
+    const Tcl_ObjectMetadataType *typePtr,
+    ClientData metadata)
+{
+    Class *clsPtr = (Class *) clazz;
+    Tcl_HashEntry *hPtr;
+    int isNew;
+
+    /*
+     * Attach the metadata store if not done already.
+     */
+
+    if (clsPtr->metadataPtr == NULL) {
+	if (metadata == NULL) {
+	    return;
+	}
+	clsPtr->metadataPtr = ckalloc(sizeof(Tcl_HashTable));
+	Tcl_InitHashTable(clsPtr->metadataPtr, TCL_ONE_WORD_KEYS);
+    }
+
+    /*
+     * If the metadata is NULL, we're deleting the metadata for the type.
+     */
+
+    if (metadata == NULL) {
+	hPtr = Tcl_FindHashEntry(clsPtr->metadataPtr, (char *) typePtr);
+	if (hPtr != NULL) {
+	    typePtr->deleteProc(Tcl_GetHashValue(hPtr));
+	    Tcl_DeleteHashEntry(hPtr);
+	}
+	return;
+    }
+
+    /*
+     * Otherwise we're attaching the metadata. Note that if there was already
+     * some metadata attached of this type, we delete that first.
+     */
+
+    hPtr = Tcl_CreateHashEntry(clsPtr->metadataPtr, (char *) typePtr, &isNew);
+    if (!isNew) {
+	typePtr->deleteProc(Tcl_GetHashValue(hPtr));
+    }
+    Tcl_SetHashValue(hPtr, metadata);
+}
+
+ClientData
+Tcl_ObjectGetMetadata(
+    Tcl_Object object,
+    const Tcl_ObjectMetadataType *typePtr)
+{
+    Object *oPtr = (Object *) object;
+    Tcl_HashEntry *hPtr;
+
+    /*
+     * If there's no metadata store attached, the type in question has
+     * definitely not been attached either!
+     */
+
+    if (oPtr->metadataPtr == NULL) {
+	return NULL;
+    }
+
+    /*
+     * There is a metadata store, so look in it for the given type.
+     */
+
+    hPtr = Tcl_FindHashEntry(oPtr->metadataPtr, (char *) typePtr);
+
+    /*
+     * Return the metadata value if we found it, otherwise NULL.
+     */
+
+    if (hPtr == NULL) {
+	return NULL;
+    }
+    return Tcl_GetHashValue(hPtr);
+}
+
+void
+Tcl_ObjectSetMetadata(
+    Tcl_Object object,
+    const Tcl_ObjectMetadataType *typePtr,
+    ClientData metadata)
+{
+    Object *oPtr = (Object *) object;
+    Tcl_HashEntry *hPtr;
+    int isNew;
+
+    /*
+     * Attach the metadata store if not done already.
+     */
+
+    if (oPtr->metadataPtr == NULL) {
+	if (metadata == NULL) {
+	    return;
+	}
+	oPtr->metadataPtr = ckalloc(sizeof(Tcl_HashTable));
+	Tcl_InitHashTable(oPtr->metadataPtr, TCL_ONE_WORD_KEYS);
+    }
+
+    /*
+     * If the metadata is NULL, we're deleting the metadata for the type.
+     */
+
+    if (metadata == NULL) {
+	hPtr = Tcl_FindHashEntry(oPtr->metadataPtr, (char *) typePtr);
+	if (hPtr != NULL) {
+	    typePtr->deleteProc(Tcl_GetHashValue(hPtr));
+	    Tcl_DeleteHashEntry(hPtr);
+	}
+	return;
+    }
+
+    /*
+     * Otherwise we're attaching the metadata. Note that if there was already
+     * some metadata attached of this type, we delete that first.
+     */
+
+    hPtr = Tcl_CreateHashEntry(oPtr->metadataPtr, (char *) typePtr, &isNew);
+    if (!isNew) {
+	typePtr->deleteProc(Tcl_GetHashValue(hPtr));
+    }
+    Tcl_SetHashValue(hPtr, metadata);
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * PublicObjectCmd, PrivateObjectCmd, TclOOInvokeObject --
+ *
+ *	Main entry point for object invokations. The Public* and Private*
+ *	wrapper functions (implementations of both object instance commands
+ *	and [my]) are just thin wrappers round the main TclOOObjectCmdCore
+ *	function. Note that the core is function is NRE-aware.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+static int
+PublicObjectCmd(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const *objv)
+{
+    return Tcl_NRCallObjProc(interp, PublicNRObjectCmd, clientData,objc,objv);
+}
+
+static int
+PublicNRObjectCmd(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const *objv)
+{
+    return TclOOObjectCmdCore(clientData, interp, objc, objv, PUBLIC_METHOD,
+	    NULL);
+}
+
+static int
+PrivateObjectCmd(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const *objv)
+{
+    return Tcl_NRCallObjProc(interp, PrivateNRObjectCmd,clientData,objc,objv);
+}
+
+static int
+PrivateNRObjectCmd(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const *objv)
+{
+    return TclOOObjectCmdCore(clientData, interp, objc, objv, 0, NULL);
+}
+
+int
+TclOOInvokeObject(
+    Tcl_Interp *interp,		/* Interpreter for commands, variables,
+				 * results, error reporting, etc. */
+    Tcl_Object object,		/* The object to invoke. */
+    Tcl_Class startCls,		/* Where in the class chain to start the
+				 * invoke from, or NULL to traverse the whole
+				 * chain including filters. */
+    int publicPrivate,		/* Whether this is an invoke from a public
+				 * context (PUBLIC_METHOD), a private context
+				 * (PRIVATE_METHOD), or a *really* private
+				 * context (any other value; conventionally
+				 * 0). */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const *objv)	/* Array of argument objects. It is assumed
+				 * that the name of the method to invoke will
+				 * be at index 1. */
+{
+    switch (publicPrivate) {
+    case PUBLIC_METHOD:
+	return TclOOObjectCmdCore((Object *) object, interp, objc, objv,
+		PUBLIC_METHOD, (Class *) startCls);
+    case PRIVATE_METHOD:
+	return TclOOObjectCmdCore((Object *) object, interp, objc, objv,
+		PRIVATE_METHOD, (Class *) startCls);
+    default:
+	return TclOOObjectCmdCore((Object *) object, interp, objc, objv, 0,
+		(Class *) startCls);
+    }
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * TclOOObjectCmdCore, FinalizeObjectCall --
+ *
+ *	Main function for object invokations. Does call chain creation,
+ *	management and invokation. The function FinalizeObjectCall exists to
+ *	clean up after the non-recursive processing of TclOOObjectCmdCore.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+int
+TclOOObjectCmdCore(
+    Object *oPtr,		/* The object being invoked. */
+    Tcl_Interp *interp,		/* The interpreter containing the object. */
+    int objc,			/* How many arguments are being passed in. */
+    Tcl_Obj *const *objv,	/* The array of arguments. */
+    int flags,			/* Whether this is an invokation through the
+				 * public or the private command interface. */
+    Class *startCls)		/* Where to start in the call chain, or NULL
+				 * if we are to start at the front with
+				 * filters and the object's methods (which is
+				 * the normal case). */
+{
+    CallContext *contextPtr;
+    Tcl_Obj *methodNamePtr;
+    int result;
+
+    /*
+     * If we've no method name, throw this directly into the unknown
+     * processing.
+     */
+
+    if (objc < 2) {
+	flags |= FORCE_UNKNOWN;
+	methodNamePtr = NULL;
+	goto noMapping;
+    }
+
+    /*
+     * Give plugged in code a chance to remap the method name.
+     */
+
+    methodNamePtr = objv[1];
+    if (oPtr->mapMethodNameProc != NULL) {
+	register Class **startClsPtr = &startCls;
+	Tcl_Obj *mappedMethodName = Tcl_DuplicateObj(methodNamePtr);
+
+	result = oPtr->mapMethodNameProc(interp, (Tcl_Object) oPtr,
+		(Tcl_Class *) startClsPtr, mappedMethodName);
+	if (result != TCL_OK) {
+	    TclDecrRefCount(mappedMethodName);
+	    if (result == TCL_BREAK) {
+		goto noMapping;
+	    } else if (result == TCL_ERROR) {
+		Tcl_AddErrorInfo(interp, "\n    (while mapping method name)");
+	    }
+	    return result;
+	}
+
+	/*
+	 * Get the call chain for the remapped name.
+	 */
+
+	Tcl_IncrRefCount(mappedMethodName);
+	contextPtr = TclOOGetCallContext(oPtr, mappedMethodName,
+		flags | (oPtr->flags & FILTER_HANDLING), methodNamePtr);
+	TclDecrRefCount(mappedMethodName);
+	if (contextPtr == NULL) {
+	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		    "impossible to invoke method \"%s\": no defined method or"
+		    " unknown method", TclGetString(methodNamePtr)));
+	    Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "METHOD_MAPPED",
+		    TclGetString(methodNamePtr), NULL);
+	    return TCL_ERROR;
+	}
+    } else {
+	/*
+	 * Get the call chain.
+	 */
+
+    noMapping:
+	contextPtr = TclOOGetCallContext(oPtr, methodNamePtr,
+		flags | (oPtr->flags & FILTER_HANDLING), NULL);
+	if (contextPtr == NULL) {
+	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		    "impossible to invoke method \"%s\": no defined method or"
+		    " unknown method", TclGetString(methodNamePtr)));
+	    Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "METHOD",
+		    TclGetString(methodNamePtr), NULL);
+	    return TCL_ERROR;
+	}
+    }
+
+    /*
+     * Check to see if we need to apply magical tricks to start part way
+     * through the call chain.
+     */
+
+    if (startCls != NULL) {
+	for (; contextPtr->index < contextPtr->callPtr->numChain;
+		contextPtr->index++) {
+	    register struct MInvoke *miPtr =
+		    &contextPtr->callPtr->chain[contextPtr->index];
+
+	    if (miPtr->isFilter) {
+		continue;
+	    }
+	    if (miPtr->mPtr->declaringClassPtr == startCls) {
+		break;
+	    }
+	}
+	if (contextPtr->index >= contextPtr->callPtr->numChain) {
+	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		    "no valid method implementation", -1));
+	    Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "METHOD",
+		    TclGetString(methodNamePtr), NULL);
+	    TclOODeleteContext(contextPtr);
+	    return TCL_ERROR;
+	}
+    }
+
+    /*
+     * Invoke the call chain, locking the object structure against deletion
+     * for the duration.
+     */
+
+    TclNRAddCallback(interp, FinalizeObjectCall, contextPtr, NULL,NULL,NULL);
+    return TclOOInvokeContext(contextPtr, interp, objc, objv);
+}
+
+static int
+FinalizeObjectCall(
+    ClientData data[],
+    Tcl_Interp *interp,
+    int result)
+{
+    /*
+     * Dispose of the call chain, which drops the lock on the object's
+     * structure.
+     */
+
+    TclOODeleteContext(data[0]);
+    return result;
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * Tcl_ObjectContextInvokeNext, TclNRObjectContextInvokeNext, FinalizeNext --
+ *
+ *	Invokes the next stage of the call chain described in an object
+ *	context. This is the core of the implementation of the [next] command.
+ *	Does not do management of the call-frame stack. Available in public
+ *	(standard API) and private (NRE-aware) forms. FinalizeNext is a
+ *	private function used to clean up in the NRE case.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+int
+Tcl_ObjectContextInvokeNext(
+    Tcl_Interp *interp,
+    Tcl_ObjectContext context,
+    int objc,
+    Tcl_Obj *const *objv,
+    int skip)
+{
+    CallContext *contextPtr = (CallContext *) context;
+    int savedIndex = contextPtr->index;
+    int savedSkip = contextPtr->skip;
+    int result;
+
+    if (contextPtr->index+1 >= contextPtr->callPtr->numChain) {
+	/*
+	 * We're at the end of the chain; generate an error message unless the
+	 * interpreter is being torn down, in which case we might be getting
+	 * here because of methods/destructors doing a [next] (or equivalent)
+	 * unexpectedly.
+	 */
+
+	const char *methodType;
+
+	if (Tcl_InterpDeleted(interp)) {
+	    return TCL_OK;
+	}
+
+	if (contextPtr->callPtr->flags & CONSTRUCTOR) {
+	    methodType = "constructor";
+	} else if (contextPtr->callPtr->flags & DESTRUCTOR) {
+	    methodType = "destructor";
+	} else {
+	    methodType = "method";
+	}
+
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		"no next %s implementation", methodType));
+	Tcl_SetErrorCode(interp, "TCL", "OO", "NOTHING_NEXT", NULL);
+	return TCL_ERROR;
+    }
+
+    /*
+     * Advance to the next method implementation in the chain in the method
+     * call context while we process the body. However, need to adjust the
+     * argument-skip control because we're guaranteed to have a single prefix
+     * arg (i.e., 'next') and not the variable amount that can happen because
+     * method invokations (i.e., '$obj meth' and 'my meth'), constructors
+     * (i.e., '$cls new' and '$cls create obj') and destructors (no args at
+     * all) come through the same code.
+     */
+
+    contextPtr->index++;
+    contextPtr->skip = skip;
+
+    /*
+     * Invoke the (advanced) method call context in the caller context.
+     */
+
+    result = Tcl_NRCallObjProc(interp, TclOOInvokeContext, contextPtr, objc,
+	    objv);
+
+    /*
+     * Restore the call chain context index as we've finished the inner invoke
+     * and want to operate in the outer context again.
+     */
+
+    contextPtr->index = savedIndex;
+    contextPtr->skip = savedSkip;
+
+    return result;
+}
+
+int
+TclNRObjectContextInvokeNext(
+    Tcl_Interp *interp,
+    Tcl_ObjectContext context,
+    int objc,
+    Tcl_Obj *const *objv,
+    int skip)
+{
+    register CallContext *contextPtr = (CallContext *) context;
+
+    if (contextPtr->index+1 >= contextPtr->callPtr->numChain) {
+	/*
+	 * We're at the end of the chain; generate an error message unless the
+	 * interpreter is being torn down, in which case we might be getting
+	 * here because of methods/destructors doing a [next] (or equivalent)
+	 * unexpectedly.
+	 */
+
+	const char *methodType;
+
+	if (Tcl_InterpDeleted(interp)) {
+	    return TCL_OK;
+	}
+
+	if (contextPtr->callPtr->flags & CONSTRUCTOR) {
+	    methodType = "constructor";
+	} else if (contextPtr->callPtr->flags & DESTRUCTOR) {
+	    methodType = "destructor";
+	} else {
+	    methodType = "method";
+	}
+
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		"no next %s implementation", methodType));
+	Tcl_SetErrorCode(interp, "TCL", "OO", "NOTHING_NEXT", NULL);
+	return TCL_ERROR;
+    }
+
+    /*
+     * Advance to the next method implementation in the chain in the method
+     * call context while we process the body. However, need to adjust the
+     * argument-skip control because we're guaranteed to have a single prefix
+     * arg (i.e., 'next') and not the variable amount that can happen because
+     * method invokations (i.e., '$obj meth' and 'my meth'), constructors
+     * (i.e., '$cls new' and '$cls create obj') and destructors (no args at
+     * all) come through the same code.
+     */
+
+    TclNRAddCallback(interp, FinalizeNext, contextPtr,
+	    INT2PTR(contextPtr->index), INT2PTR(contextPtr->skip), NULL);
+    contextPtr->index++;
+    contextPtr->skip = skip;
+
+    /*
+     * Invoke the (advanced) method call context in the caller context.
+     */
+
+    return TclOOInvokeContext(contextPtr, interp, objc, objv);
+}
+
+static int
+FinalizeNext(
+    ClientData data[],
+    Tcl_Interp *interp,
+    int result)
+{
+    CallContext *contextPtr = data[0];
+
+    /*
+     * Restore the call chain context index as we've finished the inner invoke
+     * and want to operate in the outer context again.
+     */
+
+    contextPtr->index = PTR2INT(data[1]);
+    contextPtr->skip = PTR2INT(data[2]);
+    return result;
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * Tcl_GetObjectFromObj --
+ *
+ *	Utility function to get an object from a Tcl_Obj containing its name.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+Tcl_Object
+Tcl_GetObjectFromObj(
+    Tcl_Interp *interp,		/* Interpreter in which to locate the object.
+				 * Will have an error message placed in it if
+				 * the name does not refer to an object. */
+    Tcl_Obj *objPtr)		/* The name of the object to look up, which is
+				 * exactly the name of its public command. */
+{
+    Command *cmdPtr = (Command *) Tcl_GetCommandFromObj(interp, objPtr);
+
+    if (cmdPtr == NULL) {
+	goto notAnObject;
+    }
+    if (cmdPtr->objProc != PublicObjectCmd) {
+	cmdPtr = (Command *) TclGetOriginalCommand((Tcl_Command) cmdPtr);
+	if (cmdPtr == NULL || cmdPtr->objProc != PublicObjectCmd) {
+	    goto notAnObject;
+	}
+    }
+    return cmdPtr->objClientData;
+
+  notAnObject:
+    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+	    "%s does not refer to an object", TclGetString(objPtr)));
+    Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "OBJECT", TclGetString(objPtr),
+	    NULL);
+    return NULL;
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * TclOOIsReachable --
+ *
+ *	Utility function that tests whether a class is a subclass (whether
+ *	directly or indirectly) of another class.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+int
+TclOOIsReachable(
+    Class *targetPtr,
+    Class *startPtr)
+{
+    int i;
+    Class *superPtr;
+
+  tailRecurse:
+    if (startPtr == targetPtr) {
+	return 1;
+    }
+    if (startPtr->superclasses.num == 1 && startPtr->mixins.num == 0) {
+	startPtr = startPtr->superclasses.list[0];
+	goto tailRecurse;
+    }
+    FOREACH(superPtr, startPtr->superclasses) {
+	if (TclOOIsReachable(targetPtr, superPtr)) {
+	    return 1;
+	}
+    }
+    FOREACH(superPtr, startPtr->mixins) {
+	if (TclOOIsReachable(targetPtr, superPtr)) {
+	    return 1;
+	}
+    }
+    return 0;
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * TclOOObjectName, Tcl_GetObjectName --
+ *
+ *	Utility function that returns the name of the object. Note that this
+ *	simplifies cache management by keeping the code to do it in one place
+ *	and not sprayed all over. The value returned always has a reference
+ *	count of at least one.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+Tcl_Obj *
+TclOOObjectName(
+    Tcl_Interp *interp,
+    Object *oPtr)
+{
+    Tcl_Obj *namePtr;
+
+    if (oPtr->cachedNameObj) {
+	return oPtr->cachedNameObj;
+    }
+    namePtr = Tcl_NewObj();
+    Tcl_GetCommandFullName(interp, oPtr->command, namePtr);
+    Tcl_IncrRefCount(namePtr);
+    oPtr->cachedNameObj = namePtr;
+    return namePtr;
+}
+
+Tcl_Obj *
+Tcl_GetObjectName(
+    Tcl_Interp *interp,
+    Tcl_Object object)
+{
+    return TclOOObjectName(interp, (Object *) object);
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * assorted trivial 'getter' functions
+ *
+ * ----------------------------------------------------------------------
+ */
+
+Tcl_Method
+Tcl_ObjectContextMethod(
+    Tcl_ObjectContext context)
+{
+    CallContext *contextPtr = (CallContext *) context;
+    return (Tcl_Method) contextPtr->callPtr->chain[contextPtr->index].mPtr;
+}
+
+int
+Tcl_ObjectContextIsFiltering(
+    Tcl_ObjectContext context)
+{
+    CallContext *contextPtr = (CallContext *) context;
+    return contextPtr->callPtr->chain[contextPtr->index].isFilter;
+}
+
+Tcl_Object
+Tcl_ObjectContextObject(
+    Tcl_ObjectContext context)
+{
+    return (Tcl_Object) ((CallContext *)context)->oPtr;
+}
+
+int
+Tcl_ObjectContextSkippedArgs(
+    Tcl_ObjectContext context)
+{
+    return ((CallContext *)context)->skip;
+}
+
+Tcl_Namespace *
+Tcl_GetObjectNamespace(
+    Tcl_Object object)
+{
+    return ((Object *)object)->namespacePtr;
+}
+
+Tcl_Command
+Tcl_GetObjectCommand(
+    Tcl_Object object)
+{
+    return ((Object *)object)->command;
+}
+
+Tcl_Class
+Tcl_GetObjectAsClass(
+    Tcl_Object object)
+{
+    return (Tcl_Class) ((Object *)object)->classPtr;
+}
+
+int
+Tcl_ObjectDeleted(
+    Tcl_Object object)
+{
+    return Deleted(object) ? 1 : 0;
+}
+
+Tcl_Object
+Tcl_GetClassAsObject(
+    Tcl_Class clazz)
+{
+    return (Tcl_Object) ((Class *)clazz)->thisPtr;
+}
+
+Tcl_ObjectMapMethodNameProc *
+Tcl_ObjectGetMethodNameMapper(
+    Tcl_Object object)
+{
+    return ((Object *) object)->mapMethodNameProc;
+}
+
+void
+Tcl_ObjectSetMethodNameMapper(
+    Tcl_Object object,
+    Tcl_ObjectMapMethodNameProc *mapMethodNameProc)
+{
+    ((Object *) object)->mapMethodNameProc = mapMethodNameProc;
+}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tclOO.decls b/generic/tclOO.decls
new file mode 100644
index 0000000..265ba88
--- /dev/null
+++ b/generic/tclOO.decls
@@ -0,0 +1,218 @@
+# tclOO.decls --
+#
+#	This file contains the declarations for all supported public functions
+#	that are exported by the TclOO package that is embedded within the Tcl
+#	library via the stubs table.  This file is used to generate the
+#	tclOODecls.h, tclOOIntDecls.h and tclOOStubInit.c files.
+#
+# Copyright (c) 2008-2013 by Donal K. Fellows.
+#
+# See the file "license.terms" for information on usage and redistribution of
+# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+library tclOO
+
+######################################################################
+# Public API, exposed for general users of TclOO.
+#
+
+interface tclOO
+hooks tclOOInt
+scspec TCLAPI
+
+declare 0 {
+    Tcl_Object Tcl_CopyObjectInstance(Tcl_Interp *interp,
+	    Tcl_Object sourceObject, const char *targetName,
+	    const char *targetNamespaceName)
+}
+declare 1 {
+    Tcl_Object Tcl_GetClassAsObject(Tcl_Class clazz)
+}
+declare 2 {
+    Tcl_Class Tcl_GetObjectAsClass(Tcl_Object object)
+}
+declare 3 {
+    Tcl_Command Tcl_GetObjectCommand(Tcl_Object object)
+}
+declare 4 {
+    Tcl_Object Tcl_GetObjectFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr)
+}
+declare 5 {
+    Tcl_Namespace *Tcl_GetObjectNamespace(Tcl_Object object)
+}
+declare 6 {
+    Tcl_Class Tcl_MethodDeclarerClass(Tcl_Method method)
+}
+declare 7 {
+    Tcl_Object Tcl_MethodDeclarerObject(Tcl_Method method)
+}
+declare 8 {
+    int Tcl_MethodIsPublic(Tcl_Method method)
+}
+declare 9 {
+    int Tcl_MethodIsType(Tcl_Method method, const Tcl_MethodType *typePtr,
+	    ClientData *clientDataPtr)
+}
+declare 10 {
+    Tcl_Obj *Tcl_MethodName(Tcl_Method method)
+}
+declare 11 {
+    Tcl_Method Tcl_NewInstanceMethod(Tcl_Interp *interp, Tcl_Object object,
+	    Tcl_Obj *nameObj, int isPublic, const Tcl_MethodType *typePtr,
+	    ClientData clientData)
+}
+declare 12 {
+    Tcl_Method Tcl_NewMethod(Tcl_Interp *interp, Tcl_Class cls,
+	    Tcl_Obj *nameObj, int isPublic, const Tcl_MethodType *typePtr,
+	    ClientData clientData)
+}
+declare 13 {
+    Tcl_Object Tcl_NewObjectInstance(Tcl_Interp *interp, Tcl_Class cls,
+	    const char *nameStr, const char *nsNameStr, int objc,
+	    Tcl_Obj *const *objv, int skip)
+}
+declare 14 {
+    int Tcl_ObjectDeleted(Tcl_Object object)
+}
+declare 15 {
+    int Tcl_ObjectContextIsFiltering(Tcl_ObjectContext context)
+}
+declare 16 {
+    Tcl_Method Tcl_ObjectContextMethod(Tcl_ObjectContext context)
+}
+declare 17 {
+    Tcl_Object Tcl_ObjectContextObject(Tcl_ObjectContext context)
+}
+declare 18 {
+    int Tcl_ObjectContextSkippedArgs(Tcl_ObjectContext context)
+}
+declare 19 {
+    ClientData Tcl_ClassGetMetadata(Tcl_Class clazz,
+	    const Tcl_ObjectMetadataType *typePtr)
+}
+declare 20 {
+    void Tcl_ClassSetMetadata(Tcl_Class clazz,
+	    const Tcl_ObjectMetadataType *typePtr, ClientData metadata)
+}
+declare 21 {
+    ClientData Tcl_ObjectGetMetadata(Tcl_Object object,
+	    const Tcl_ObjectMetadataType *typePtr)
+}
+declare 22 {
+    void Tcl_ObjectSetMetadata(Tcl_Object object,
+	    const Tcl_ObjectMetadataType *typePtr, ClientData metadata)
+}
+declare 23 {
+    int Tcl_ObjectContextInvokeNext(Tcl_Interp *interp,
+	    Tcl_ObjectContext context, int objc, Tcl_Obj *const *objv,
+	    int skip)
+}
+declare 24 {
+    Tcl_ObjectMapMethodNameProc *Tcl_ObjectGetMethodNameMapper(
+	    Tcl_Object object)
+}
+declare 25 {
+    void Tcl_ObjectSetMethodNameMapper(Tcl_Object object,
+	    Tcl_ObjectMapMethodNameProc *mapMethodNameProc)
+}
+declare 26 {
+    void Tcl_ClassSetConstructor(Tcl_Interp *interp, Tcl_Class clazz,
+	    Tcl_Method method)
+}
+declare 27 {
+    void Tcl_ClassSetDestructor(Tcl_Interp *interp, Tcl_Class clazz,
+	    Tcl_Method method)
+}
+declare 28 {
+    Tcl_Obj *Tcl_GetObjectName(Tcl_Interp *interp, Tcl_Object object)
+}
+
+######################################################################
+# Private API, exposed to support advanced OO systems that plug in on top of
+# TclOO; not intended for general use and does not have any commitment to
+# long-term support.
+#
+
+interface tclOOInt
+
+declare 0 {
+    Tcl_Object TclOOGetDefineCmdContext(Tcl_Interp *interp)
+}
+declare 1 {
+    Tcl_Method TclOOMakeProcInstanceMethod(Tcl_Interp *interp, Object *oPtr,
+	    int flags, Tcl_Obj *nameObj, Tcl_Obj *argsObj, Tcl_Obj *bodyObj,
+	    const Tcl_MethodType *typePtr, ClientData clientData,
+	    Proc **procPtrPtr)
+}
+declare 2 {
+    Tcl_Method TclOOMakeProcMethod(Tcl_Interp *interp, Class *clsPtr,
+	    int flags, Tcl_Obj *nameObj, const char *namePtr,
+	    Tcl_Obj *argsObj, Tcl_Obj *bodyObj, const Tcl_MethodType *typePtr,
+	    ClientData clientData, Proc **procPtrPtr)
+}
+declare 3 {
+    Method *TclOONewProcInstanceMethod(Tcl_Interp *interp, Object *oPtr,
+	    int flags, Tcl_Obj *nameObj, Tcl_Obj *argsObj, Tcl_Obj *bodyObj,
+	    ProcedureMethod **pmPtrPtr)
+}
+declare 4 {
+    Method *TclOONewProcMethod(Tcl_Interp *interp, Class *clsPtr,
+	    int flags, Tcl_Obj *nameObj, Tcl_Obj *argsObj, Tcl_Obj *bodyObj,
+	    ProcedureMethod **pmPtrPtr)
+}
+declare 5 {
+    int TclOOObjectCmdCore(Object *oPtr, Tcl_Interp *interp, int objc,
+	    Tcl_Obj *const *objv, int publicOnly, Class *startCls)
+}
+declare 6 {
+    int TclOOIsReachable(Class *targetPtr, Class *startPtr)
+}
+declare 7 {
+    Method *TclOONewForwardMethod(Tcl_Interp *interp, Class *clsPtr,
+	    int isPublic, Tcl_Obj *nameObj, Tcl_Obj *prefixObj)
+}
+declare 8 {
+    Method *TclOONewForwardInstanceMethod(Tcl_Interp *interp, Object *oPtr,
+	    int isPublic, Tcl_Obj *nameObj, Tcl_Obj *prefixObj)
+}
+declare 9 {
+    Tcl_Method TclOONewProcInstanceMethodEx(Tcl_Interp *interp,
+	    Tcl_Object oPtr, TclOO_PreCallProc *preCallPtr,
+	    TclOO_PostCallProc *postCallPtr, ProcErrorProc *errProc,
+	    ClientData clientData, Tcl_Obj *nameObj, Tcl_Obj *argsObj,
+	    Tcl_Obj *bodyObj, int flags, void **internalTokenPtr)
+}
+declare 10 {
+    Tcl_Method TclOONewProcMethodEx(Tcl_Interp *interp, Tcl_Class clsPtr,
+	    TclOO_PreCallProc *preCallPtr, TclOO_PostCallProc *postCallPtr,
+	    ProcErrorProc *errProc, ClientData clientData, Tcl_Obj *nameObj,
+	    Tcl_Obj *argsObj, Tcl_Obj *bodyObj, int flags,
+	    void **internalTokenPtr)
+}
+declare 11 {
+    int TclOOInvokeObject(Tcl_Interp *interp, Tcl_Object object,
+	    Tcl_Class startCls, int publicPrivate, int objc,
+	    Tcl_Obj *const *objv)
+}
+declare 12 {
+    void TclOOObjectSetFilters(Object *oPtr, int numFilters,
+	    Tcl_Obj *const *filters)
+}
+declare 13 {
+    void TclOOClassSetFilters(Tcl_Interp *interp, Class *classPtr,
+	    int numFilters, Tcl_Obj *const *filters)
+}
+declare 14 {
+    void TclOOObjectSetMixins(Object *oPtr, int numMixins,
+	    Class *const *mixins)
+}
+declare 15 {
+    void TclOOClassSetMixins(Tcl_Interp *interp, Class *classPtr,
+	    int numMixins, Class *const *mixins)
+}
+
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/generic/tclOO.h b/generic/tclOO.h
new file mode 100644
index 0000000..46f01fb
--- /dev/null
+++ b/generic/tclOO.h
@@ -0,0 +1,147 @@
+/*
+ * tclOO.h --
+ *
+ *	This file contains the public API definitions and some of the function
+ *	declarations for the object-system (NB: not Tcl_Obj, but ::oo).
+ *
+ * Copyright (c) 2006-2010 by Donal K. Fellows
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#ifndef TCLOO_H_INCLUDED
+#define TCLOO_H_INCLUDED
+
+/*
+ * Be careful when it comes to versioning; need to make sure that the
+ * standalone TclOO version matches. Also make sure that this matches the
+ * version in the files:
+ *
+ * tests/oo.test
+ * tests/ooNext2.test
+ * unix/tclooConfig.sh
+ * win/tclooConfig.sh
+ */
+
+#define TCLOO_VERSION "1.0.5"
+#define TCLOO_PATCHLEVEL TCLOO_VERSION
+
+#include "tcl.h"
+
+/*
+ * For C++ compilers, use extern "C"
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern const char *TclOOInitializeStubs(
+	Tcl_Interp *, const char *version);
+#define Tcl_OOInitStubs(interp) \
+    TclOOInitializeStubs((interp), TCLOO_VERSION)
+#ifndef USE_TCL_STUBS
+#   define TclOOInitializeStubs(interp, version) (TCLOO_PATCHLEVEL)
+#endif
+
+/*
+ * These are opaque types.
+ */
+
+typedef struct Tcl_Class_ *Tcl_Class;
+typedef struct Tcl_Method_ *Tcl_Method;
+typedef struct Tcl_Object_ *Tcl_Object;
+typedef struct Tcl_ObjectContext_ *Tcl_ObjectContext;
+
+/*
+ * Public datatypes for callbacks and structures used in the TIP#257 (OO)
+ * implementation. These are used to implement custom types of method calls
+ * and to allow the attachment of arbitrary data to objects and classes.
+ */
+
+typedef int (Tcl_MethodCallProc)(ClientData clientData, Tcl_Interp *interp,
+	Tcl_ObjectContext objectContext, int objc, Tcl_Obj *const *objv);
+typedef void (Tcl_MethodDeleteProc)(ClientData clientData);
+typedef int (Tcl_CloneProc)(Tcl_Interp *interp, ClientData oldClientData,
+	ClientData *newClientData);
+typedef void (Tcl_ObjectMetadataDeleteProc)(ClientData clientData);
+typedef int (Tcl_ObjectMapMethodNameProc)(Tcl_Interp *interp,
+	Tcl_Object object, Tcl_Class *startClsPtr, Tcl_Obj *methodNameObj);
+
+/*
+ * The type of a method implementation. This describes how to call the method
+ * implementation, how to delete it (when the object or class is deleted) and
+ * how to create a clone of it (when the object or class is copied).
+ */
+
+typedef struct {
+    int version;		/* Structure version field. Always to be equal
+				 * to TCL_OO_METHOD_VERSION_CURRENT in
+				 * declarations. */
+    const char *name;		/* Name of this type of method, mostly for
+				 * debugging purposes. */
+    Tcl_MethodCallProc *callProc;
+				/* How to invoke this method. */
+    Tcl_MethodDeleteProc *deleteProc;
+				/* How to delete this method's type-specific
+				 * data, or NULL if the type-specific data
+				 * does not need deleting. */
+    Tcl_CloneProc *cloneProc;	/* How to copy this method's type-specific
+				 * data, or NULL if the type-specific data can
+				 * be copied directly. */
+} Tcl_MethodType;
+
+/*
+ * The correct value for the version field of the Tcl_MethodType structure.
+ * This allows new versions of the structure to be introduced without breaking
+ * binary compatability.
+ */
+
+#define TCL_OO_METHOD_VERSION_CURRENT 1
+
+/*
+ * The type of some object (or class) metadata. This describes how to delete
+ * the metadata (when the object or class is deleted) and how to create a
+ * clone of it (when the object or class is copied).
+ */
+
+typedef struct {
+    int version;		/* Structure version field. Always to be equal
+				 * to TCL_OO_METADATA_VERSION_CURRENT in
+				 * declarations. */
+    const char *name;
+    Tcl_ObjectMetadataDeleteProc *deleteProc;
+				/* How to delete the metadata. This must not
+				 * be NULL. */
+    Tcl_CloneProc *cloneProc;	/* How to copy the metadata, or NULL if the
+				 * type-specific data can be copied
+				 * directly. */
+} Tcl_ObjectMetadataType;
+
+/*
+ * The correct value for the version field of the Tcl_ObjectMetadataType
+ * structure. This allows new versions of the structure to be introduced
+ * without breaking binary compatability.
+ */
+
+#define TCL_OO_METADATA_VERSION_CURRENT 1
+
+/*
+ * Include all the public API, generated from tclOO.decls.
+ */
+
+#include "tclOODecls.h"
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tclOOBasic.c b/generic/tclOOBasic.c
new file mode 100644
index 0000000..8cb80e5
--- /dev/null
+++ b/generic/tclOOBasic.c
@@ -0,0 +1,1245 @@
+/*
+ * tclOOBasic.c --
+ *
+ *	This file contains implementations of the "simple" commands and
+ *	methods from the object-system core.
+ *
+ * Copyright (c) 2005-2013 by Donal K. Fellows
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include "tclInt.h"
+#include "tclOOInt.h"
+
+static inline Tcl_Object *AddConstructionFinalizer(Tcl_Interp *interp);
+static Tcl_NRPostProc	AfterNRDestructor;
+static Tcl_NRPostProc	DecrRefsPostClassConstructor;
+static Tcl_NRPostProc	FinalizeConstruction;
+static Tcl_NRPostProc	FinalizeEval;
+static Tcl_NRPostProc	NextRestoreFrame;
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * AddCreateCallback, FinalizeConstruction --
+ *
+ *	Special version of TclNRAddCallback that allows the caller to splice
+ *	the object created later on. Always calls FinalizeConstruction, which
+ *	converts the object into its name and stores that in the interpreter
+ *	result. This is shared by all the construction methods (create,
+ *	createWithNamespace, new).
+ *
+ *	Note that this is the only code in this file (or, indeed, the whole of
+ *	TclOO) that uses NRE internals; it is the only code that does
+ *	non-standard poking in the NRE guts.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+static inline Tcl_Object *
+AddConstructionFinalizer(
+    Tcl_Interp *interp)
+{
+    TclNRAddCallback(interp, FinalizeConstruction, NULL, NULL, NULL, NULL);
+    return (Tcl_Object *) &(TOP_CB(interp)->data[0]);
+}
+
+static int
+FinalizeConstruction(
+    ClientData data[],
+    Tcl_Interp *interp,
+    int result)
+{
+    Object *oPtr = data[0];
+
+    if (result != TCL_OK) {
+	return result;
+    }
+    Tcl_SetObjResult(interp, TclOOObjectName(interp, oPtr));
+    return TCL_OK;
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * TclOO_Class_Constructor --
+ *
+ *	Implementation for oo::class constructor.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+int
+TclOO_Class_Constructor(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    Tcl_ObjectContext context,
+    int objc,
+    Tcl_Obj *const *objv)
+{
+    Object *oPtr = (Object *) Tcl_ObjectContextObject(context);
+    Tcl_Obj **invoke;
+
+    if (objc-1 > Tcl_ObjectContextSkippedArgs(context)) {
+	Tcl_WrongNumArgs(interp, Tcl_ObjectContextSkippedArgs(context), objv,
+		"?definitionScript?");
+	return TCL_ERROR;
+    } else if (objc == Tcl_ObjectContextSkippedArgs(context)) {
+	return TCL_OK;
+    }
+
+    /*
+     * Delegate to [oo::define] to do the work.
+     */
+
+    invoke = ckalloc(3 * sizeof(Tcl_Obj *));
+    invoke[0] = oPtr->fPtr->defineName;
+    invoke[1] = TclOOObjectName(interp, oPtr);
+    invoke[2] = objv[objc-1];
+
+    /*
+     * Must add references or errors in configuration script will cause
+     * trouble.
+     */
+
+    Tcl_IncrRefCount(invoke[0]);
+    Tcl_IncrRefCount(invoke[1]);
+    Tcl_IncrRefCount(invoke[2]);
+    TclNRAddCallback(interp, DecrRefsPostClassConstructor,
+	    invoke, NULL, NULL, NULL);
+
+    /*
+     * Tricky point: do not want the extra reported level in the Tcl stack
+     * trace, so use TCL_EVAL_NOERR.
+     */
+
+    return TclNREvalObjv(interp, 3, invoke, TCL_EVAL_NOERR, NULL);
+}
+
+static int
+DecrRefsPostClassConstructor(
+    ClientData data[],
+    Tcl_Interp *interp,
+    int result)
+{
+    Tcl_Obj **invoke = data[0];
+
+    TclDecrRefCount(invoke[0]);
+    TclDecrRefCount(invoke[1]);
+    TclDecrRefCount(invoke[2]);
+    ckfree(invoke);
+    return result;
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * TclOO_Class_Create --
+ *
+ *	Implementation for oo::class->create method.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+int
+TclOO_Class_Create(
+    ClientData clientData,	/* Ignored. */
+    Tcl_Interp *interp,		/* Interpreter in which to create the object;
+				 * also used for error reporting. */
+    Tcl_ObjectContext context,	/* The object/call context. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const *objv)	/* The actual arguments. */
+{
+    Object *oPtr = (Object *) Tcl_ObjectContextObject(context);
+    const char *objName;
+    int len;
+
+    /*
+     * Sanity check; should not be possible to invoke this method on a
+     * non-class.
+     */
+
+    if (oPtr->classPtr == NULL) {
+	Tcl_Obj *cmdnameObj = TclOOObjectName(interp, oPtr);
+
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		"object \"%s\" is not a class", TclGetString(cmdnameObj)));
+	Tcl_SetErrorCode(interp, "TCL", "OO", "INSTANTIATE_NONCLASS", NULL);
+	return TCL_ERROR;
+    }
+
+    /*
+     * Check we have the right number of (sensible) arguments.
+     */
+
+    if (objc - Tcl_ObjectContextSkippedArgs(context) < 1) {
+	Tcl_WrongNumArgs(interp, Tcl_ObjectContextSkippedArgs(context), objv,
+		"objectName ?arg ...?");
+	return TCL_ERROR;
+    }
+    objName = Tcl_GetStringFromObj(
+	    objv[Tcl_ObjectContextSkippedArgs(context)], &len);
+    if (len == 0) {
+	Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		"object name must not be empty", -1));
+	Tcl_SetErrorCode(interp, "TCL", "OO", "EMPTY_NAME", NULL);
+	return TCL_ERROR;
+    }
+
+    /*
+     * Make the object and return its name.
+     */
+
+    return TclNRNewObjectInstance(interp, (Tcl_Class) oPtr->classPtr,
+	    objName, NULL, objc, objv,
+	    Tcl_ObjectContextSkippedArgs(context)+1,
+	    AddConstructionFinalizer(interp));
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * TclOO_Class_CreateNs --
+ *
+ *	Implementation for oo::class->createWithNamespace method.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+int
+TclOO_Class_CreateNs(
+    ClientData clientData,	/* Ignored. */
+    Tcl_Interp *interp,		/* Interpreter in which to create the object;
+				 * also used for error reporting. */
+    Tcl_ObjectContext context,	/* The object/call context. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const *objv)	/* The actual arguments. */
+{
+    Object *oPtr = (Object *) Tcl_ObjectContextObject(context);
+    const char *objName, *nsName;
+    int len;
+
+    /*
+     * Sanity check; should not be possible to invoke this method on a
+     * non-class.
+     */
+
+    if (oPtr->classPtr == NULL) {
+	Tcl_Obj *cmdnameObj = TclOOObjectName(interp, oPtr);
+
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		"object \"%s\" is not a class", TclGetString(cmdnameObj)));
+	Tcl_SetErrorCode(interp, "TCL", "OO", "INSTANTIATE_NONCLASS", NULL);
+	return TCL_ERROR;
+    }
+
+    /*
+     * Check we have the right number of (sensible) arguments.
+     */
+
+    if (objc - Tcl_ObjectContextSkippedArgs(context) < 2) {
+	Tcl_WrongNumArgs(interp, Tcl_ObjectContextSkippedArgs(context), objv,
+		"objectName namespaceName ?arg ...?");
+	return TCL_ERROR;
+    }
+    objName = Tcl_GetStringFromObj(
+	    objv[Tcl_ObjectContextSkippedArgs(context)], &len);
+    if (len == 0) {
+	Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		"object name must not be empty", -1));
+	Tcl_SetErrorCode(interp, "TCL", "OO", "EMPTY_NAME", NULL);
+	return TCL_ERROR;
+    }
+    nsName = Tcl_GetStringFromObj(
+	    objv[Tcl_ObjectContextSkippedArgs(context)+1], &len);
+    if (len == 0) {
+	Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		"namespace name must not be empty", -1));
+	Tcl_SetErrorCode(interp, "TCL", "OO", "EMPTY_NAME", NULL);
+	return TCL_ERROR;
+    }
+
+    /*
+     * Make the object and return its name.
+     */
+
+    return TclNRNewObjectInstance(interp, (Tcl_Class) oPtr->classPtr,
+	    objName, nsName, objc, objv,
+	    Tcl_ObjectContextSkippedArgs(context)+2,
+	    AddConstructionFinalizer(interp));
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * TclOO_Class_New --
+ *
+ *	Implementation for oo::class->new method.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+int
+TclOO_Class_New(
+    ClientData clientData,	/* Ignored. */
+    Tcl_Interp *interp,		/* Interpreter in which to create the object;
+				 * also used for error reporting. */
+    Tcl_ObjectContext context,	/* The object/call context. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const *objv)	/* The actual arguments. */
+{
+    Object *oPtr = (Object *) Tcl_ObjectContextObject(context);
+
+    /*
+     * Sanity check; should not be possible to invoke this method on a
+     * non-class.
+     */
+
+    if (oPtr->classPtr == NULL) {
+	Tcl_Obj *cmdnameObj = TclOOObjectName(interp, oPtr);
+
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		"object \"%s\" is not a class", TclGetString(cmdnameObj)));
+	Tcl_SetErrorCode(interp, "TCL", "OO", "INSTANTIATE_NONCLASS", NULL);
+	return TCL_ERROR;
+    }
+
+    /*
+     * Make the object and return its name.
+     */
+
+    return TclNRNewObjectInstance(interp, (Tcl_Class) oPtr->classPtr,
+	    NULL, NULL, objc, objv, Tcl_ObjectContextSkippedArgs(context),
+	    AddConstructionFinalizer(interp));
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * TclOO_Object_Destroy --
+ *
+ *	Implementation for oo::object->destroy method.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+int
+TclOO_Object_Destroy(
+    ClientData clientData,	/* Ignored. */
+    Tcl_Interp *interp,		/* Interpreter in which to create the object;
+				 * also used for error reporting. */
+    Tcl_ObjectContext context,	/* The object/call context. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const *objv)	/* The actual arguments. */
+{
+    Object *oPtr = (Object *) Tcl_ObjectContextObject(context);
+    CallContext *contextPtr;
+
+    if (objc != Tcl_ObjectContextSkippedArgs(context)) {
+	Tcl_WrongNumArgs(interp, Tcl_ObjectContextSkippedArgs(context), objv,
+		NULL);
+	return TCL_ERROR;
+    }
+    if (!(oPtr->flags & DESTRUCTOR_CALLED)) {
+	oPtr->flags |= DESTRUCTOR_CALLED;
+	contextPtr = TclOOGetCallContext(oPtr, NULL, DESTRUCTOR, NULL);
+	if (contextPtr != NULL) {
+	    contextPtr->callPtr->flags |= DESTRUCTOR;
+	    contextPtr->skip = 0;
+	    TclNRAddCallback(interp, AfterNRDestructor, contextPtr,
+		    NULL, NULL, NULL);
+	    TclPushTailcallPoint(interp);
+	    return TclOOInvokeContext(contextPtr, interp, 0, NULL);
+	}
+    }
+    if (oPtr->command) {
+	Tcl_DeleteCommandFromToken(interp, oPtr->command);
+    }
+    return TCL_OK;
+}
+
+static int
+AfterNRDestructor(
+    ClientData data[],
+    Tcl_Interp *interp,
+    int result)
+{
+    CallContext *contextPtr = data[0];
+
+    if (contextPtr->oPtr->command) {
+	Tcl_DeleteCommandFromToken(interp, contextPtr->oPtr->command);
+    }
+    TclOODeleteContext(contextPtr);
+    return result;
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * TclOO_Object_Eval --
+ *
+ *	Implementation for oo::object->eval method.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+int
+TclOO_Object_Eval(
+    ClientData clientData,	/* Ignored. */
+    Tcl_Interp *interp,		/* Interpreter in which to create the object;
+				 * also used for error reporting. */
+    Tcl_ObjectContext context,	/* The object/call context. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const *objv)	/* The actual arguments. */
+{
+    CallContext *contextPtr = (CallContext *) context;
+    Tcl_Object object = Tcl_ObjectContextObject(context);
+    register const int skip = Tcl_ObjectContextSkippedArgs(context);
+    CallFrame *framePtr, **framePtrPtr = &framePtr;
+    Tcl_Obj *scriptPtr;
+    CmdFrame *invoker;
+
+    if (objc-1 < skip) {
+	Tcl_WrongNumArgs(interp, skip, objv, "arg ?arg ...?");
+	return TCL_ERROR;
+    }
+
+    /*
+     * Make the object's namespace the current namespace and evaluate the
+     * command(s).
+     */
+
+    (void) TclPushStackFrame(interp, (Tcl_CallFrame **) framePtrPtr,
+	    Tcl_GetObjectNamespace(object), 0);
+    framePtr->objc = objc;
+    framePtr->objv = objv;	/* Reference counts do not need to be
+				 * incremented here. */
+
+    if (!(contextPtr->callPtr->flags & PUBLIC_METHOD)) {
+	object = NULL;		/* Now just for error mesage printing. */
+    }
+
+    /*
+     * Work out what script we are actually going to evaluate.
+     *
+     * When there's more than one argument, we concatenate them together with
+     * spaces between, then evaluate the result. Tcl_EvalObjEx will delete the
+     * object when it decrements its refcount after eval'ing it.
+     */
+
+    if (objc != skip+1) {
+	scriptPtr = Tcl_ConcatObj(objc-skip, objv+skip);
+	invoker = NULL;
+    } else {
+	scriptPtr = objv[skip];
+	invoker = ((Interp *) interp)->cmdFramePtr;
+    }
+
+    /*
+     * Evaluate the script now, with FinalizeEval to do the processing after
+     * the script completes.
+     */
+
+    TclNRAddCallback(interp, FinalizeEval, object, NULL, NULL, NULL);
+    return TclNREvalObjEx(interp, scriptPtr, 0, invoker, skip);
+}
+
+static int
+FinalizeEval(
+    ClientData data[],
+    Tcl_Interp *interp,
+    int result)
+{
+    if (result == TCL_ERROR) {
+	Object *oPtr = data[0];
+	const char *namePtr;
+
+	if (oPtr) {
+	    namePtr = TclGetString(TclOOObjectName(interp, oPtr));
+	} else {
+	    namePtr = "my";
+	}
+
+	Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf(
+		"\n    (in \"%s eval\" script line %d)",
+		namePtr, Tcl_GetErrorLine(interp)));
+    }
+
+    /*
+     * Restore the previous "current" namespace.
+     */
+
+    TclPopStackFrame(interp);
+    return result;
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * TclOO_Object_Unknown --
+ *
+ *	Default unknown method handler method (defined in oo::object). This
+ *	just creates a suitable error message.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+int
+TclOO_Object_Unknown(
+    ClientData clientData,	/* Ignored. */
+    Tcl_Interp *interp,		/* Interpreter in which to create the object;
+				 * also used for error reporting. */
+    Tcl_ObjectContext context,	/* The object/call context. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const *objv)	/* The actual arguments. */
+{
+    CallContext *contextPtr = (CallContext *) context;
+    Object *oPtr = contextPtr->oPtr;
+    const char **methodNames;
+    int numMethodNames, i, skip = Tcl_ObjectContextSkippedArgs(context);
+    Tcl_Obj *errorMsg;
+
+    /*
+     * If no method name, generate an error asking for a method name. (Only by
+     * overriding *this* method can an object handle the absence of a method
+     * name without an error).
+     */
+
+    if (objc < skip+1) {
+	Tcl_WrongNumArgs(interp, skip, objv, "method ?arg ...?");
+	return TCL_ERROR;
+    }
+
+    /*
+     * Get the list of methods that we want to know about.
+     */
+
+    numMethodNames = TclOOGetSortedMethodList(oPtr,
+	    contextPtr->callPtr->flags & PUBLIC_METHOD, &methodNames);
+
+    /*
+     * Special message when there are no visible methods at all.
+     */
+
+    if (numMethodNames == 0) {
+	Tcl_Obj *tmpBuf = TclOOObjectName(interp, oPtr);
+	const char *piece;
+
+	if (contextPtr->callPtr->flags & PUBLIC_METHOD) {
+	    piece = "visible methods";
+	} else {
+	    piece = "methods";
+	}
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		"object \"%s\" has no %s", TclGetString(tmpBuf), piece));
+	Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "METHOD",
+		TclGetString(objv[skip]), NULL);
+	return TCL_ERROR;
+    }
+
+    errorMsg = Tcl_ObjPrintf("unknown method \"%s\": must be ",
+	    TclGetString(objv[skip]));
+    for (i=0 ; i<numMethodNames-1 ; i++) {
+	if (i) {
+	    Tcl_AppendToObj(errorMsg, ", ", -1);
+	}
+	Tcl_AppendToObj(errorMsg, methodNames[i], -1);
+    }
+    if (i) {
+	Tcl_AppendToObj(errorMsg, " or ", -1);
+    }
+    Tcl_AppendToObj(errorMsg, methodNames[i], -1);
+    ckfree(methodNames);
+    Tcl_SetObjResult(interp, errorMsg);
+    Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "METHOD",
+	    TclGetString(objv[skip]), NULL);
+    return TCL_ERROR;
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * TclOO_Object_LinkVar --
+ *
+ *	Implementation of oo::object->variable method.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+int
+TclOO_Object_LinkVar(
+    ClientData clientData,	/* Ignored. */
+    Tcl_Interp *interp,		/* Interpreter in which to create the object;
+				 * also used for error reporting. */
+    Tcl_ObjectContext context,	/* The object/call context. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const *objv)	/* The actual arguments. */
+{
+    Interp *iPtr = (Interp *) interp;
+    Tcl_Object object = Tcl_ObjectContextObject(context);
+    Namespace *savedNsPtr;
+    int i;
+
+    if (objc-Tcl_ObjectContextSkippedArgs(context) < 0) {
+	Tcl_WrongNumArgs(interp, Tcl_ObjectContextSkippedArgs(context), objv,
+		"?varName ...?");
+	return TCL_ERROR;
+    }
+
+    /*
+     * A sanity check. Shouldn't ever happen. (This is all that remains of a
+     * more complex check inherited from [global] after we have applied the
+     * fix for [Bug 2903811]; note that the fix involved *removing* code.)
+     */
+
+    if (iPtr->varFramePtr == NULL) {
+	return TCL_OK;
+    }
+
+    for (i=Tcl_ObjectContextSkippedArgs(context) ; i<objc ; i++) {
+	Var *varPtr, *aryPtr;
+	const char *varName = TclGetString(objv[i]);
+
+	/*
+	 * The variable name must not contain a '::' since that's illegal in
+	 * local names.
+	 */
+
+	if (strstr(varName, "::") != NULL) {
+	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		    "variable name \"%s\" illegal: must not contain namespace"
+		    " separator", varName));
+	    Tcl_SetErrorCode(interp, "TCL", "UPVAR", "INVERTED", NULL);
+	    return TCL_ERROR;
+	}
+
+	/*
+	 * Switch to the object's namespace for the duration of this call.
+	 * Like this, the variable is looked up in the namespace of the
+	 * object, and not in the namespace of the caller. Otherwise this
+	 * would only work if the caller was a method of the object itself,
+	 * which might not be true if the method was exported. This is a bit
+	 * of a hack, but the simplest way to do this (pushing a stack frame
+	 * would be horribly expensive by comparison).
+	 */
+
+	savedNsPtr = iPtr->varFramePtr->nsPtr;
+	iPtr->varFramePtr->nsPtr = (Namespace *)
+		Tcl_GetObjectNamespace(object);
+	varPtr = TclObjLookupVar(interp, objv[i], NULL, TCL_NAMESPACE_ONLY,
+		"define", 1, 0, &aryPtr);
+	iPtr->varFramePtr->nsPtr = savedNsPtr;
+
+	if (varPtr == NULL || aryPtr != NULL) {
+	    /*
+	     * Variable cannot be an element in an array. If aryPtr is not
+	     * NULL, it is an element, so throw up an error and return.
+	     */
+
+	    TclVarErrMsg(interp, varName, NULL, "define",
+		    "name refers to an element in an array");
+	    Tcl_SetErrorCode(interp, "TCL", "UPVAR", "LOCAL_ELEMENT", NULL);
+	    return TCL_ERROR;
+	}
+
+	/*
+	 * Arrange for the lifetime of the variable to be correctly managed.
+	 * This is copied out of Tcl_VariableObjCmd...
+	 */
+
+	if (!TclIsVarNamespaceVar(varPtr)) {
+	    TclSetVarNamespaceVar(varPtr);
+	}
+
+	if (TclPtrMakeUpvar(interp, varPtr, varName, 0, -1) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+    }
+    return TCL_OK;
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * TclOO_Object_VarName --
+ *
+ *	Implementation of the oo::object->varname method.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+int
+TclOO_Object_VarName(
+    ClientData clientData,	/* Ignored. */
+    Tcl_Interp *interp,		/* Interpreter in which to create the object;
+				 * also used for error reporting. */
+    Tcl_ObjectContext context,	/* The object/call context. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const *objv)	/* The actual arguments. */
+{
+    Var *varPtr, *aryVar;
+    Tcl_Obj *varNamePtr, *argPtr;
+    const char *arg;
+
+    if (Tcl_ObjectContextSkippedArgs(context)+1 != objc) {
+	Tcl_WrongNumArgs(interp, Tcl_ObjectContextSkippedArgs(context), objv,
+		"varName");
+	return TCL_ERROR;
+    }
+    argPtr = objv[objc-1];
+    arg = Tcl_GetString(argPtr);
+
+    /*
+     * Convert the variable name to fully-qualified form if it wasn't already.
+     * This has to be done prior to lookup because we can run into problems
+     * with resolvers otherwise. [Bug 3603695]
+     *
+     * We still need to do the lookup; the variable could be linked to another
+     * variable and we want the target's name.
+     */
+
+    if (arg[0] == ':' && arg[1] == ':') {
+	varNamePtr = argPtr;
+    } else {
+	Tcl_Namespace *namespacePtr =
+		Tcl_GetObjectNamespace(Tcl_ObjectContextObject(context));
+
+	varNamePtr = Tcl_NewStringObj(namespacePtr->fullName, -1);
+	Tcl_AppendToObj(varNamePtr, "::", 2);
+	Tcl_AppendObjToObj(varNamePtr, argPtr);
+    }
+    Tcl_IncrRefCount(varNamePtr);
+    varPtr = TclObjLookupVar(interp, varNamePtr, NULL,
+	    TCL_NAMESPACE_ONLY|TCL_LEAVE_ERR_MSG, "refer to", 1, 1, &aryVar);
+    Tcl_DecrRefCount(varNamePtr);
+    if (varPtr == NULL) {
+	Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "VARIABLE", arg, NULL);
+	return TCL_ERROR;
+    }
+
+    /*
+     * Now that we've pinned down what variable we're really talking about
+     * (including traversing variable links), convert back to a name.
+     */
+
+    varNamePtr = Tcl_NewObj();
+    if (aryVar != NULL) {
+	Tcl_HashEntry *hPtr;
+	Tcl_HashSearch search;
+
+	Tcl_GetVariableFullName(interp, (Tcl_Var) aryVar, varNamePtr);
+
+	/*
+	 * WARNING! This code pokes inside the implementation of hash tables!
+	 */
+
+	hPtr = Tcl_FirstHashEntry((Tcl_HashTable *) aryVar->value.tablePtr,
+		&search);
+	while (hPtr != NULL) {
+	    if (varPtr == Tcl_GetHashValue(hPtr)) {
+		Tcl_AppendToObj(varNamePtr, "(", -1);
+		Tcl_AppendObjToObj(varNamePtr, hPtr->key.objPtr);
+		Tcl_AppendToObj(varNamePtr, ")", -1);
+		break;
+	    }
+	    hPtr = Tcl_NextHashEntry(&search);
+	}
+    } else {
+	Tcl_GetVariableFullName(interp, (Tcl_Var) varPtr, varNamePtr);
+    }
+    Tcl_SetObjResult(interp, varNamePtr);
+    return TCL_OK;
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * TclOONextObjCmd, TclOONextToObjCmd --
+ *
+ *	Implementation of the [next] and [nextto] commands. Note that these
+ *	commands are only ever to be used inside the body of a procedure-like
+ *	method.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+int
+TclOONextObjCmd(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const *objv)
+{
+    Interp *iPtr = (Interp *) interp;
+    CallFrame *framePtr = iPtr->varFramePtr;
+    Tcl_ObjectContext context;
+
+    /*
+     * Start with sanity checks on the calling context to make sure that we
+     * are invoked from a suitable method context. If so, we can safely
+     * retrieve the handle to the object call context.
+     */
+
+    if (framePtr == NULL || !(framePtr->isProcCallFrame & FRAME_IS_METHOD)) {
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		"%s may only be called from inside a method",
+		TclGetString(objv[0])));
+	Tcl_SetErrorCode(interp, "TCL", "OO", "CONTEXT_REQUIRED", NULL);
+	return TCL_ERROR;
+    }
+    context = framePtr->clientData;
+
+    /*
+     * Invoke the (advanced) method call context in the caller context. Note
+     * that this is like [uplevel 1] and not [eval].
+     */
+
+    TclNRAddCallback(interp, NextRestoreFrame, framePtr, NULL,NULL,NULL);
+    iPtr->varFramePtr = framePtr->callerVarPtr;
+    return TclNRObjectContextInvokeNext(interp, context, objc, objv, 1);
+}
+
+int
+TclOONextToObjCmd(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const *objv)
+{
+    Interp *iPtr = (Interp *) interp;
+    CallFrame *framePtr = iPtr->varFramePtr;
+    Class *classPtr;
+    CallContext *contextPtr;
+    int i;
+    Tcl_Object object;
+    const char *methodType;
+
+    /*
+     * Start with sanity checks on the calling context to make sure that we
+     * are invoked from a suitable method context. If so, we can safely
+     * retrieve the handle to the object call context.
+     */
+
+    if (framePtr == NULL || !(framePtr->isProcCallFrame & FRAME_IS_METHOD)) {
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		"%s may only be called from inside a method",
+		TclGetString(objv[0])));
+	Tcl_SetErrorCode(interp, "TCL", "OO", "CONTEXT_REQUIRED", NULL);
+	return TCL_ERROR;
+    }
+    contextPtr = framePtr->clientData;
+
+    /*
+     * Sanity check the arguments; we need the first one to refer to a class.
+     */
+
+    if (objc < 2) {
+	Tcl_WrongNumArgs(interp, 1, objv, "class ?arg...?");
+	return TCL_ERROR;
+    }
+    object = Tcl_GetObjectFromObj(interp, objv[1]);
+    if (object == NULL) {
+	return TCL_ERROR;
+    }
+    classPtr = ((Object *)object)->classPtr;
+    if (classPtr == NULL) {
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		"\"%s\" is not a class", TclGetString(objv[1])));
+	Tcl_SetErrorCode(interp, "TCL", "OO", "CLASS_REQUIRED", NULL);
+	return TCL_ERROR;
+    }
+
+    /*
+     * Search for an implementation of a method associated with the current
+     * call on the call chain past the point where we currently are. Do not
+     * allow jumping backwards!
+     */
+
+    for (i=contextPtr->index+1 ; i<contextPtr->callPtr->numChain ; i++) {
+	struct MInvoke *miPtr = contextPtr->callPtr->chain + i;
+
+	if (!miPtr->isFilter && miPtr->mPtr->declaringClassPtr == classPtr) {
+	    /*
+	     * Invoke the (advanced) method call context in the caller
+	     * context. Note that this is like [uplevel 1] and not [eval].
+	     */
+
+	    TclNRAddCallback(interp, NextRestoreFrame, framePtr,
+		    contextPtr, INT2PTR(contextPtr->index), NULL);
+	    contextPtr->index = i-1;
+	    iPtr->varFramePtr = framePtr->callerVarPtr;
+	    return TclNRObjectContextInvokeNext(interp,
+		    (Tcl_ObjectContext) contextPtr, objc, objv, 2);
+	}
+    }
+
+    /*
+     * Generate an appropriate error message, depending on whether the value
+     * is on the chain but unreachable, or not on the chain at all.
+     */
+
+    if (contextPtr->callPtr->flags & CONSTRUCTOR) {
+	methodType = "constructor";
+    } else if (contextPtr->callPtr->flags & DESTRUCTOR) {
+	methodType = "destructor";
+    } else {
+	methodType = "method";
+    }
+
+    for (i=contextPtr->index ; i>=0 ; i--) {
+	struct MInvoke *miPtr = contextPtr->callPtr->chain + i;
+
+	if (!miPtr->isFilter && miPtr->mPtr->declaringClassPtr == classPtr) {
+	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		    "%s implementation by \"%s\" not reachable from here",
+		    methodType, TclGetString(objv[1])));
+	    Tcl_SetErrorCode(interp, "TCL", "OO", "CLASS_NOT_REACHABLE",
+		    NULL);
+	    return TCL_ERROR;
+	}
+    }
+    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+	    "%s has no non-filter implementation by \"%s\"",
+	    methodType, TclGetString(objv[1])));
+    Tcl_SetErrorCode(interp, "TCL", "OO", "CLASS_NOT_THERE", NULL);
+    return TCL_ERROR;
+}
+
+static int
+NextRestoreFrame(
+    ClientData data[],
+    Tcl_Interp *interp,
+    int result)
+{
+    Interp *iPtr = (Interp *) interp;
+    CallContext *contextPtr = data[1];
+
+    iPtr->varFramePtr = data[0];
+    if (contextPtr != NULL) {
+	contextPtr->index = PTR2INT(data[2]);
+    }
+    return result;
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * TclOOSelfObjCmd --
+ *
+ *	Implementation of the [self] command, which provides introspection of
+ *	the call context.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+int
+TclOOSelfObjCmd(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const *objv)
+{
+    static const char *const subcmds[] = {
+	"call", "caller", "class", "filter", "method", "namespace", "next",
+	"object", "target", NULL
+    };
+    enum SelfCmds {
+	SELF_CALL, SELF_CALLER, SELF_CLASS, SELF_FILTER, SELF_METHOD, SELF_NS,
+	SELF_NEXT, SELF_OBJECT, SELF_TARGET
+    };
+    Interp *iPtr = (Interp *) interp;
+    CallFrame *framePtr = iPtr->varFramePtr;
+    CallContext *contextPtr;
+    Tcl_Obj *result[3];
+    int index;
+
+#define CurrentlyInvoked(contextPtr) \
+    ((contextPtr)->callPtr->chain[(contextPtr)->index])
+
+    /*
+     * Start with sanity checks on the calling context and the method context.
+     */
+
+    if (framePtr == NULL || !(framePtr->isProcCallFrame & FRAME_IS_METHOD)) {
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		"%s may only be called from inside a method",
+		TclGetString(objv[0])));
+	Tcl_SetErrorCode(interp, "TCL", "OO", "CONTEXT_REQUIRED", NULL);
+	return TCL_ERROR;
+    }
+
+    contextPtr = framePtr->clientData;
+
+    /*
+     * Now we do "conventional" argument parsing for a while. Note that no
+     * subcommand takes arguments.
+     */
+
+    if (objc > 2) {
+	Tcl_WrongNumArgs(interp, 1, objv, "subcommand");
+	return TCL_ERROR;
+    } else if (objc == 1) {
+	index = SELF_OBJECT;
+    } else if (Tcl_GetIndexFromObj(interp, objv[1], subcmds, "subcommand", 0,
+	    &index) != TCL_OK) {
+	return TCL_ERROR;
+    }
+
+    switch ((enum SelfCmds) index) {
+    case SELF_OBJECT:
+	Tcl_SetObjResult(interp, TclOOObjectName(interp, contextPtr->oPtr));
+	return TCL_OK;
+    case SELF_NS:
+	Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		contextPtr->oPtr->namespacePtr->fullName,-1));
+	return TCL_OK;
+    case SELF_CLASS: {
+	Class *clsPtr = CurrentlyInvoked(contextPtr).mPtr->declaringClassPtr;
+
+	if (clsPtr == NULL) {
+	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		    "method not defined by a class", -1));
+	    Tcl_SetErrorCode(interp, "TCL", "OO", "UNMATCHED_CONTEXT", NULL);
+	    return TCL_ERROR;
+	}
+
+	Tcl_SetObjResult(interp, TclOOObjectName(interp, clsPtr->thisPtr));
+	return TCL_OK;
+    }
+    case SELF_METHOD:
+	if (contextPtr->callPtr->flags & CONSTRUCTOR) {
+	    Tcl_SetObjResult(interp, contextPtr->oPtr->fPtr->constructorName);
+	} else if (contextPtr->callPtr->flags & DESTRUCTOR) {
+	    Tcl_SetObjResult(interp, contextPtr->oPtr->fPtr->destructorName);
+	} else {
+	    Tcl_SetObjResult(interp,
+		    CurrentlyInvoked(contextPtr).mPtr->namePtr);
+	}
+	return TCL_OK;
+    case SELF_FILTER:
+	if (!CurrentlyInvoked(contextPtr).isFilter) {
+	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		    "not inside a filtering context", -1));
+	    Tcl_SetErrorCode(interp, "TCL", "OO", "UNMATCHED_CONTEXT", NULL);
+	    return TCL_ERROR;
+	} else {
+	    register struct MInvoke *miPtr = &CurrentlyInvoked(contextPtr);
+	    Object *oPtr;
+	    const char *type;
+
+	    if (miPtr->filterDeclarer != NULL) {
+		oPtr = miPtr->filterDeclarer->thisPtr;
+		type = "class";
+	    } else {
+		oPtr = contextPtr->oPtr;
+		type = "object";
+	    }
+
+	    result[0] = TclOOObjectName(interp, oPtr);
+	    result[1] = Tcl_NewStringObj(type, -1);
+	    result[2] = miPtr->mPtr->namePtr;
+	    Tcl_SetObjResult(interp, Tcl_NewListObj(3, result));
+	    return TCL_OK;
+	}
+    case SELF_CALLER:
+	if ((framePtr->callerVarPtr == NULL) ||
+		!(framePtr->callerVarPtr->isProcCallFrame & FRAME_IS_METHOD)){
+	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		    "caller is not an object", -1));
+	    Tcl_SetErrorCode(interp, "TCL", "OO", "CONTEXT_REQUIRED", NULL);
+	    return TCL_ERROR;
+	} else {
+	    CallContext *callerPtr = framePtr->callerVarPtr->clientData;
+	    Method *mPtr = callerPtr->callPtr->chain[callerPtr->index].mPtr;
+	    Object *declarerPtr;
+
+	    if (mPtr->declaringClassPtr != NULL) {
+		declarerPtr = mPtr->declaringClassPtr->thisPtr;
+	    } else if (mPtr->declaringObjectPtr != NULL) {
+		declarerPtr = mPtr->declaringObjectPtr;
+	    } else {
+		/*
+		 * This should be unreachable code.
+		 */
+
+		Tcl_SetObjResult(interp, Tcl_NewStringObj(
+			"method without declarer!", -1));
+		return TCL_ERROR;
+	    }
+
+	    result[0] = TclOOObjectName(interp, declarerPtr);
+	    result[1] = TclOOObjectName(interp, callerPtr->oPtr);
+	    if (callerPtr->callPtr->flags & CONSTRUCTOR) {
+		result[2] = declarerPtr->fPtr->constructorName;
+	    } else if (callerPtr->callPtr->flags & DESTRUCTOR) {
+		result[2] = declarerPtr->fPtr->destructorName;
+	    } else {
+		result[2] = mPtr->namePtr;
+	    }
+	    Tcl_SetObjResult(interp, Tcl_NewListObj(3, result));
+	    return TCL_OK;
+	}
+    case SELF_NEXT:
+	if (contextPtr->index < contextPtr->callPtr->numChain-1) {
+	    Method *mPtr =
+		    contextPtr->callPtr->chain[contextPtr->index+1].mPtr;
+	    Object *declarerPtr;
+
+	    if (mPtr->declaringClassPtr != NULL) {
+		declarerPtr = mPtr->declaringClassPtr->thisPtr;
+	    } else if (mPtr->declaringObjectPtr != NULL) {
+		declarerPtr = mPtr->declaringObjectPtr;
+	    } else {
+		/*
+		 * This should be unreachable code.
+		 */
+
+		Tcl_SetObjResult(interp, Tcl_NewStringObj(
+			"method without declarer!", -1));
+		return TCL_ERROR;
+	    }
+
+	    result[0] = TclOOObjectName(interp, declarerPtr);
+	    if (contextPtr->callPtr->flags & CONSTRUCTOR) {
+		result[1] = declarerPtr->fPtr->constructorName;
+	    } else if (contextPtr->callPtr->flags & DESTRUCTOR) {
+		result[1] = declarerPtr->fPtr->destructorName;
+	    } else {
+		result[1] = mPtr->namePtr;
+	    }
+	    Tcl_SetObjResult(interp, Tcl_NewListObj(2, result));
+	}
+	return TCL_OK;
+    case SELF_TARGET:
+	if (!CurrentlyInvoked(contextPtr).isFilter) {
+	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		    "not inside a filtering context", -1));
+	    Tcl_SetErrorCode(interp, "TCL", "OO", "UNMATCHED_CONTEXT", NULL);
+	    return TCL_ERROR;
+	} else {
+	    Method *mPtr;
+	    Object *declarerPtr;
+	    int i;
+
+	    for (i=contextPtr->index ; i<contextPtr->callPtr->numChain ; i++){
+		if (!contextPtr->callPtr->chain[i].isFilter) {
+		    break;
+		}
+	    }
+	    if (i == contextPtr->callPtr->numChain) {
+		Tcl_Panic("filtering call chain without terminal non-filter");
+	    }
+	    mPtr = contextPtr->callPtr->chain[i].mPtr;
+	    if (mPtr->declaringClassPtr != NULL) {
+		declarerPtr = mPtr->declaringClassPtr->thisPtr;
+	    } else if (mPtr->declaringObjectPtr != NULL) {
+		declarerPtr = mPtr->declaringObjectPtr;
+	    } else {
+		/*
+		 * This should be unreachable code.
+		 */
+
+		Tcl_SetObjResult(interp, Tcl_NewStringObj(
+			"method without declarer!", -1));
+		return TCL_ERROR;
+	    }
+	    result[0] = TclOOObjectName(interp, declarerPtr);
+	    result[1] = mPtr->namePtr;
+	    Tcl_SetObjResult(interp, Tcl_NewListObj(2, result));
+	    return TCL_OK;
+	}
+    case SELF_CALL:
+	result[0] = TclOORenderCallChain(interp, contextPtr->callPtr);
+	result[1] = Tcl_NewIntObj(contextPtr->index);
+	Tcl_SetObjResult(interp, Tcl_NewListObj(2, result));
+	return TCL_OK;
+    }
+    return TCL_ERROR;
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * CopyObjectCmd --
+ *
+ *	Implementation of the [oo::copy] command, which clones an object (but
+ *	not its namespace). Note that no constructors are called during this
+ *	process.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+int
+TclOOCopyObjectCmd(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const *objv)
+{
+    Tcl_Object oPtr, o2Ptr;
+
+    if (objc < 2 || objc > 3) {
+	Tcl_WrongNumArgs(interp, 1, objv, "sourceName ?targetName?");
+	return TCL_ERROR;
+    }
+
+    oPtr = Tcl_GetObjectFromObj(interp, objv[1]);
+    if (oPtr == NULL) {
+	return TCL_ERROR;
+    }
+
+    /*
+     * Create a cloned object of the correct class. Note that constructors are
+     * not called. Also note that we must resolve the object name ourselves
+     * because we do not want to create the object in the current namespace,
+     * but rather in the context of the namespace of the caller of the overall
+     * [oo::define] command.
+     */
+
+    if (objc == 2) {
+	o2Ptr = Tcl_CopyObjectInstance(interp, oPtr, NULL, NULL);
+    } else {
+	const char *name;
+	Tcl_DString buffer;
+
+	name = TclGetString(objv[2]);
+	Tcl_DStringInit(&buffer);
+	if (name[0]!=':' || name[1]!=':') {
+	    Interp *iPtr = (Interp *) interp;
+
+	    if (iPtr->varFramePtr != NULL) {
+		Tcl_DStringAppend(&buffer,
+			iPtr->varFramePtr->nsPtr->fullName, -1);
+	    }
+	    TclDStringAppendLiteral(&buffer, "::");
+	    Tcl_DStringAppend(&buffer, name, -1);
+	    name = Tcl_DStringValue(&buffer);
+	}
+	o2Ptr = Tcl_CopyObjectInstance(interp, oPtr, name, NULL);
+	Tcl_DStringFree(&buffer);
+    }
+
+    if (o2Ptr == NULL) {
+	return TCL_ERROR;
+    }
+
+    /*
+     * Return the name of the cloned object.
+     */
+
+    Tcl_SetObjResult(interp, TclOOObjectName(interp, (Object *) o2Ptr));
+    return TCL_OK;
+}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tclOOCall.c b/generic/tclOOCall.c
new file mode 100644
index 0000000..1797760
--- /dev/null
+++ b/generic/tclOOCall.c
@@ -0,0 +1,1537 @@
+/*
+ * tclOOCall.c --
+ *
+ *	This file contains the method call chain management code for the
+ *	object-system core.
+ *
+ * Copyright (c) 2005-2012 by Donal K. Fellows
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include "tclInt.h"
+#include "tclOOInt.h"
+
+/*
+ * Structure containing a CallContext and any other values needed only during
+ * the construction of the CallContext.
+ */
+
+struct ChainBuilder {
+    CallChain *callChainPtr;	/* The call chain being built. */
+    int filterLength;		/* Number of entries in the call chain that
+				 * are due to processing filters and not the
+				 * main call chain. */
+    Object *oPtr;		/* The object that we are building the chain
+				 * for. */
+};
+
+/*
+ * Extra flags used for call chain management.
+ */
+
+#define DEFINITE_PROTECTED 0x100000
+#define DEFINITE_PUBLIC    0x200000
+#define KNOWN_STATE	   (DEFINITE_PROTECTED | DEFINITE_PUBLIC)
+#define SPECIAL		   (CONSTRUCTOR | DESTRUCTOR | FORCE_UNKNOWN)
+#define BUILDING_MIXINS	   0x400000
+#define TRAVERSED_MIXIN	   0x800000
+#define OBJECT_MIXIN	   0x1000000
+#define MIXIN_CONSISTENT(flags) \
+    (((flags) & OBJECT_MIXIN) ||					\
+	!((flags) & BUILDING_MIXINS) == !((flags) & TRAVERSED_MIXIN))
+
+/*
+ * Function declarations for things defined in this file.
+ */
+
+static void		AddClassFiltersToCallContext(Object *const oPtr,
+			    Class *clsPtr, struct ChainBuilder *const cbPtr,
+			    Tcl_HashTable *const doneFilters, int flags);
+static void		AddClassMethodNames(Class *clsPtr, const int flags,
+			    Tcl_HashTable *const namesPtr);
+static inline void	AddMethodToCallChain(Method *const mPtr,
+			    struct ChainBuilder *const cbPtr,
+			    Tcl_HashTable *const doneFilters,
+			    Class *const filterDecl, int flags);
+static inline void	AddSimpleChainToCallContext(Object *const oPtr,
+			    Tcl_Obj *const methodNameObj,
+			    struct ChainBuilder *const cbPtr,
+			    Tcl_HashTable *const doneFilters, int flags,
+			    Class *const filterDecl);
+static void		AddSimpleClassChainToCallContext(Class *classPtr,
+			    Tcl_Obj *const methodNameObj,
+			    struct ChainBuilder *const cbPtr,
+			    Tcl_HashTable *const doneFilters, int flags,
+			    Class *const filterDecl);
+static int		CmpStr(const void *ptr1, const void *ptr2);
+static void		DupMethodNameRep(Tcl_Obj *srcPtr, Tcl_Obj *dstPtr);
+static Tcl_NRPostProc	FinalizeMethodRefs;
+static void		FreeMethodNameRep(Tcl_Obj *objPtr);
+static inline int	IsStillValid(CallChain *callPtr, Object *oPtr,
+			    int flags, int reuseMask);
+static Tcl_NRPostProc	ResetFilterFlags;
+static Tcl_NRPostProc	SetFilterFlags;
+static inline void	StashCallChain(Tcl_Obj *objPtr, CallChain *callPtr);
+
+/*
+ * Object type used to manage type caches attached to method names.
+ */
+
+static const Tcl_ObjType methodNameType = {
+    "TclOO method name",
+    FreeMethodNameRep,
+    DupMethodNameRep,
+    NULL,
+    NULL
+};
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * TclOODeleteContext --
+ *
+ *	Destroys a method call-chain context, which should not be in use.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+void
+TclOODeleteContext(
+    CallContext *contextPtr)
+{
+    register Object *oPtr = contextPtr->oPtr;
+
+    TclOODeleteChain(contextPtr->callPtr);
+    if (oPtr != NULL) {
+	TclStackFree(oPtr->fPtr->interp, contextPtr);
+	DelRef(oPtr);
+    }
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * TclOODeleteChainCache --
+ *
+ *	Destroy the cache of method call-chains.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+void
+TclOODeleteChainCache(
+    Tcl_HashTable *tablePtr)
+{
+    FOREACH_HASH_DECLS;
+    CallChain *callPtr;
+
+    FOREACH_HASH_VALUE(callPtr, tablePtr) {
+	if (callPtr) {
+	    TclOODeleteChain(callPtr);
+	}
+    }
+    Tcl_DeleteHashTable(tablePtr);
+    ckfree(tablePtr);
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * TclOODeleteChain --
+ *
+ *	Destroys a method call-chain.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+void
+TclOODeleteChain(
+    CallChain *callPtr)
+{
+    if (callPtr == NULL || callPtr->refCount-- > 1) {
+	return;
+    }
+    if (callPtr->chain != callPtr->staticChain) {
+	ckfree(callPtr->chain);
+    }
+    ckfree(callPtr);
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * TclOOStashContext --
+ *
+ *	Saves a reference to a method call context in a Tcl_Obj's internal
+ *	representation.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+static inline void
+StashCallChain(
+    Tcl_Obj *objPtr,
+    CallChain *callPtr)
+{
+    callPtr->refCount++;
+    TclFreeIntRep(objPtr);
+    objPtr->typePtr = &methodNameType;
+    objPtr->internalRep.twoPtrValue.ptr1 = callPtr;
+}
+
+void
+TclOOStashContext(
+    Tcl_Obj *objPtr,
+    CallContext *contextPtr)
+{
+    StashCallChain(objPtr, contextPtr->callPtr);
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * DupMethodNameRep, FreeMethodNameRep --
+ *
+ *	Functions to implement the required parts of the Tcl_Obj guts needed
+ *	for caching of method contexts in Tcl_Objs.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+static void
+DupMethodNameRep(
+    Tcl_Obj *srcPtr,
+    Tcl_Obj *dstPtr)
+{
+    register CallChain *callPtr = srcPtr->internalRep.twoPtrValue.ptr1;
+
+    dstPtr->typePtr = &methodNameType;
+    dstPtr->internalRep.twoPtrValue.ptr1 = callPtr;
+    callPtr->refCount++;
+}
+
+static void
+FreeMethodNameRep(
+    Tcl_Obj *objPtr)
+{
+    register CallChain *callPtr = objPtr->internalRep.twoPtrValue.ptr1;
+
+    TclOODeleteChain(callPtr);
+    objPtr->typePtr = NULL;
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * TclOOInvokeContext --
+ *
+ *	Invokes a single step along a method call-chain context. Note that the
+ *	invokation of a step along the chain can cause further steps along the
+ *	chain to be invoked. Note that this function is written to be as light
+ *	in stack usage as possible.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+int
+TclOOInvokeContext(
+    ClientData clientData,	/* The method call context. */
+    Tcl_Interp *interp,		/* Interpreter for error reporting, and many
+				 * other sorts of context handling (e.g.,
+				 * commands, variables) depending on method
+				 * implementation. */
+    int objc,			/* The number of arguments. */
+    Tcl_Obj *const objv[])	/* The arguments as actually seen. */
+{
+    register CallContext *const contextPtr = clientData;
+    Method *const mPtr = contextPtr->callPtr->chain[contextPtr->index].mPtr;
+    const int isFilter =
+	    contextPtr->callPtr->chain[contextPtr->index].isFilter;
+
+    /*
+     * If this is the first step along the chain, we preserve the method
+     * entries in the chain so that they do not get deleted out from under our
+     * feet.
+     */
+
+    if (contextPtr->index == 0) {
+	int i;
+
+	for (i=0 ; i<contextPtr->callPtr->numChain ; i++) {
+	    AddRef(contextPtr->callPtr->chain[i].mPtr);
+	}
+
+	/*
+	 * Ensure that the method name itself is part of the arguments when
+	 * we're doing unknown processing.
+	 */
+
+	if (contextPtr->callPtr->flags & OO_UNKNOWN_METHOD) {
+	    contextPtr->skip--;
+	}
+
+	/*
+	 * Add a callback to ensure that method references are dropped once
+	 * this call is finished.
+	 */
+
+	TclNRAddCallback(interp, FinalizeMethodRefs, contextPtr, NULL, NULL,
+		NULL);
+    }
+
+    /*
+     * Save whether we were in a filter and set up whether we are now.
+     */
+
+    if (contextPtr->oPtr->flags & FILTER_HANDLING) {
+	TclNRAddCallback(interp, SetFilterFlags, contextPtr, NULL,NULL,NULL);
+    } else {
+	TclNRAddCallback(interp, ResetFilterFlags,contextPtr,NULL,NULL,NULL);
+    }
+    if (isFilter || contextPtr->callPtr->flags & FILTER_HANDLING) {
+	contextPtr->oPtr->flags |= FILTER_HANDLING;
+    } else {
+	contextPtr->oPtr->flags &= ~FILTER_HANDLING;
+    }
+
+    /*
+     * Run the method implementation.
+     */
+
+    return mPtr->typePtr->callProc(mPtr->clientData, interp,
+	    (Tcl_ObjectContext) contextPtr, objc, objv);
+}
+
+static int
+SetFilterFlags(
+    ClientData data[],
+    Tcl_Interp *interp,
+    int result)
+{
+    CallContext *contextPtr = data[0];
+
+    contextPtr->oPtr->flags |= FILTER_HANDLING;
+    return result;
+}
+
+static int
+ResetFilterFlags(
+    ClientData data[],
+    Tcl_Interp *interp,
+    int result)
+{
+    CallContext *contextPtr = data[0];
+
+    contextPtr->oPtr->flags &= ~FILTER_HANDLING;
+    return result;
+}
+
+static int
+FinalizeMethodRefs(
+    ClientData data[],
+    Tcl_Interp *interp,
+    int result)
+{
+    CallContext *contextPtr = data[0];
+    int i;
+
+    for (i=0 ; i<contextPtr->callPtr->numChain ; i++) {
+	TclOODelMethodRef(contextPtr->callPtr->chain[i].mPtr);
+    }
+    return result;
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * TclOOGetSortedMethodList, TclOOGetSortedClassMethodList --
+ *
+ *	Discovers the list of method names supported by an object or class.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+int
+TclOOGetSortedMethodList(
+    Object *oPtr,		/* The object to get the method names for. */
+    int flags,			/* Whether we just want the public method
+				 * names. */
+    const char ***stringsPtr)	/* Where to write a pointer to the array of
+				 * strings to. */
+{
+    Tcl_HashTable names;	/* Tcl_Obj* method name to "wanted in list"
+				 * mapping. */
+    FOREACH_HASH_DECLS;
+    int i;
+    Class *mixinPtr;
+    Tcl_Obj *namePtr;
+    Method *mPtr;
+    int isWantedIn;
+    void *isWanted;
+
+    Tcl_InitObjHashTable(&names);
+
+    /*
+     * Name the bits used in the names table values.
+     */
+#define IN_LIST 1
+#define NO_IMPLEMENTATION 2
+
+    /*
+     * Process method names due to the object.
+     */
+
+    if (oPtr->methodsPtr) {
+	FOREACH_HASH(namePtr, mPtr, oPtr->methodsPtr) {
+	    int isNew;
+
+	    if ((mPtr->flags & PRIVATE_METHOD) && !(flags & PRIVATE_METHOD)) {
+		continue;
+	    }
+	    hPtr = Tcl_CreateHashEntry(&names, (char *) namePtr, &isNew);
+	    if (isNew) {
+		isWantedIn = ((!(flags & PUBLIC_METHOD)
+			|| mPtr->flags & PUBLIC_METHOD) ? IN_LIST : 0);
+		isWantedIn |= (mPtr->typePtr == NULL ? NO_IMPLEMENTATION : 0);
+		Tcl_SetHashValue(hPtr, INT2PTR(isWantedIn));
+	    }
+	}
+    }
+
+    /*
+     * Process method names due to private methods on the object's class.
+     */
+
+    if (flags & PRIVATE_METHOD) {
+	FOREACH_HASH(namePtr, mPtr, &oPtr->selfCls->classMethods) {
+	    if (mPtr->flags & PRIVATE_METHOD) {
+		int isNew;
+
+		hPtr = Tcl_CreateHashEntry(&names, (char *) namePtr, &isNew);
+		if (isNew) {
+		    isWantedIn = IN_LIST;
+		    if (mPtr->typePtr == NULL) {
+			isWantedIn |= NO_IMPLEMENTATION;
+		    }
+		    Tcl_SetHashValue(hPtr, INT2PTR(isWantedIn));
+		} else if (mPtr->typePtr != NULL) {
+		    isWantedIn = PTR2INT(Tcl_GetHashValue(hPtr));
+		    if (isWantedIn & NO_IMPLEMENTATION) {
+			isWantedIn &= ~NO_IMPLEMENTATION;
+			Tcl_SetHashValue(hPtr, INT2PTR(isWantedIn));
+		    }
+		}
+	    }
+	}
+    }
+
+    /*
+     * Process (normal) method names from the class hierarchy and the mixin
+     * hierarchy.
+     */
+
+    AddClassMethodNames(oPtr->selfCls, flags, &names);
+    FOREACH(mixinPtr, oPtr->mixins) {
+	AddClassMethodNames(mixinPtr, flags|TRAVERSED_MIXIN, &names);
+    }
+
+    /*
+     * See how many (visible) method names there are. If none, we do not (and
+     * should not) try to sort the list of them.
+     */
+
+    i = 0;
+    if (names.numEntries != 0) {
+	const char **strings;
+
+	/*
+	 * We need to build the list of methods to sort. We will be using
+	 * qsort() for this, because it is very unlikely that the list will be
+	 * heavily sorted when it is long enough to matter.
+	 */
+
+	strings = ckalloc(sizeof(char *) * names.numEntries);
+	FOREACH_HASH(namePtr, isWanted, &names) {
+	    if (!(flags & PUBLIC_METHOD) || (PTR2INT(isWanted) & IN_LIST)) {
+		if (PTR2INT(isWanted) & NO_IMPLEMENTATION) {
+		    continue;
+		}
+		strings[i++] = TclGetString(namePtr);
+	    }
+	}
+
+	/*
+	 * Note that 'i' may well be less than names.numEntries when we are
+	 * dealing with public method names.
+	 */
+
+	if (i > 0) {
+	    if (i > 1) {
+		qsort((void *) strings, (unsigned) i, sizeof(char *), CmpStr);
+	    }
+	    *stringsPtr = strings;
+	} else {
+	    ckfree(strings);
+	}
+    }
+
+    Tcl_DeleteHashTable(&names);
+    return i;
+}
+
+int
+TclOOGetSortedClassMethodList(
+    Class *clsPtr,		/* The class to get the method names for. */
+    int flags,			/* Whether we just want the public method
+				 * names. */
+    const char ***stringsPtr)	/* Where to write a pointer to the array of
+				 * strings to. */
+{
+    Tcl_HashTable names;	/* Tcl_Obj* method name to "wanted in list"
+				 * mapping. */
+    FOREACH_HASH_DECLS;
+    int i;
+    Tcl_Obj *namePtr;
+    void *isWanted;
+
+    Tcl_InitObjHashTable(&names);
+
+    /*
+     * Process method names from the class hierarchy and the mixin hierarchy.
+     */
+
+    AddClassMethodNames(clsPtr, flags, &names);
+
+    /*
+     * See how many (visible) method names there are. If none, we do not (and
+     * should not) try to sort the list of them.
+     */
+
+    i = 0;
+    if (names.numEntries != 0) {
+	const char **strings;
+
+	/*
+	 * We need to build the list of methods to sort. We will be using
+	 * qsort() for this, because it is very unlikely that the list will be
+	 * heavily sorted when it is long enough to matter.
+	 */
+
+	strings = ckalloc(sizeof(char *) * names.numEntries);
+	FOREACH_HASH(namePtr, isWanted, &names) {
+	    if (!(flags & PUBLIC_METHOD) || (PTR2INT(isWanted) & IN_LIST)) {
+		if (PTR2INT(isWanted) & NO_IMPLEMENTATION) {
+		    continue;
+		}
+		strings[i++] = TclGetString(namePtr);
+	    }
+	}
+
+	/*
+	 * Note that 'i' may well be less than names.numEntries when we are
+	 * dealing with public method names.
+	 */
+
+	if (i > 0) {
+	    if (i > 1) {
+		qsort((void *) strings, (unsigned) i, sizeof(char *), CmpStr);
+	    }
+	    *stringsPtr = strings;
+	} else {
+	    ckfree(strings);
+	}
+    }
+
+    Tcl_DeleteHashTable(&names);
+    return i;
+}
+
+/* Comparator for GetSortedMethodList */
+static int
+CmpStr(
+    const void *ptr1,
+    const void *ptr2)
+{
+    const char **strPtr1 = (const char **) ptr1;
+    const char **strPtr2 = (const char **) ptr2;
+
+    return TclpUtfNcmp2(*strPtr1, *strPtr2, strlen(*strPtr1)+1);
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * AddClassMethodNames --
+ *
+ *	Adds the method names defined by a class (or its superclasses) to the
+ *	collection being built. The collection is built in a hash table to
+ *	ensure that duplicates are excluded. Helper for GetSortedMethodList().
+ *
+ * ----------------------------------------------------------------------
+ */
+
+static void
+AddClassMethodNames(
+    Class *clsPtr,		/* Class to get method names from. */
+    const int flags,		/* Whether we are interested in just the
+				 * public method names. */
+    Tcl_HashTable *const namesPtr)
+				/* Reference to the hash table to put the
+				 * information in. The hash table maps the
+				 * Tcl_Obj * method name to an integral value
+				 * describing whether the method is wanted.
+				 * This ensures that public/private override
+				 * semantics are handled correctly.*/
+{
+    /*
+     * Scope all declarations so that the compiler can stand a good chance of
+     * making the recursive step highly efficient. We also hand-implement the
+     * tail-recursive case using a while loop; C compilers typically cannot do
+     * tail-recursion optimization usefully.
+     */
+
+    if (clsPtr->mixins.num != 0) {
+	Class *mixinPtr;
+	int i;
+
+	/* TODO: Beware of infinite loops! */
+	FOREACH(mixinPtr, clsPtr->mixins) {
+	    AddClassMethodNames(mixinPtr, flags|TRAVERSED_MIXIN, namesPtr);
+	}
+    }
+
+    while (1) {
+	FOREACH_HASH_DECLS;
+	Tcl_Obj *namePtr;
+	Method *mPtr;
+
+	FOREACH_HASH(namePtr, mPtr, &clsPtr->classMethods) {
+	    int isNew;
+
+	    hPtr = Tcl_CreateHashEntry(namesPtr, (char *) namePtr, &isNew);
+	    if (isNew) {
+		int isWanted = (!(flags & PUBLIC_METHOD)
+			|| (mPtr->flags & PUBLIC_METHOD)) ? IN_LIST : 0;
+
+		Tcl_SetHashValue(hPtr, INT2PTR(isWanted));
+	    } else if ((PTR2INT(Tcl_GetHashValue(hPtr)) & NO_IMPLEMENTATION)
+		    && mPtr->typePtr != NULL) {
+		int isWanted = PTR2INT(Tcl_GetHashValue(hPtr));
+
+		isWanted &= ~NO_IMPLEMENTATION;
+		Tcl_SetHashValue(hPtr, INT2PTR(isWanted));
+	    }
+	}
+
+	if (clsPtr->superclasses.num != 1) {
+	    break;
+	}
+	clsPtr = clsPtr->superclasses.list[0];
+    }
+    if (clsPtr->superclasses.num != 0) {
+	Class *superPtr;
+	int i;
+
+	FOREACH(superPtr, clsPtr->superclasses) {
+	    AddClassMethodNames(superPtr, flags, namesPtr);
+	}
+    }
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * AddSimpleChainToCallContext --
+ *
+ *	The core of the call-chain construction engine, this handles calling a
+ *	particular method on a particular object. Note that filters and
+ *	unknown handling are already handled by the logic that uses this
+ *	function.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+static inline void
+AddSimpleChainToCallContext(
+    Object *const oPtr,		/* Object to add call chain entries for. */
+    Tcl_Obj *const methodNameObj,
+				/* Name of method to add the call chain
+				 * entries for. */
+    struct ChainBuilder *const cbPtr,
+				/* Where to add the call chain entries. */
+    Tcl_HashTable *const doneFilters,
+				/* Where to record what call chain entries
+				 * have been processed. */
+    int flags,			/* What sort of call chain are we building. */
+    Class *const filterDecl)	/* The class that declared the filter. If
+				 * NULL, either the filter was declared by the
+				 * object or this isn't a filter. */
+{
+    int i;
+
+    if (!(flags & (KNOWN_STATE | SPECIAL)) && oPtr->methodsPtr) {
+	Tcl_HashEntry *hPtr = Tcl_FindHashEntry(oPtr->methodsPtr,
+		(char *) methodNameObj);
+
+	if (hPtr != NULL) {
+	    Method *mPtr = Tcl_GetHashValue(hPtr);
+
+	    if (flags & PUBLIC_METHOD) {
+		if (!(mPtr->flags & PUBLIC_METHOD)) {
+		    return;
+		} else {
+		    flags |= DEFINITE_PUBLIC;
+		}
+	    } else {
+		flags |= DEFINITE_PROTECTED;
+	    }
+	}
+    }
+    if (!(flags & SPECIAL)) {
+	Tcl_HashEntry *hPtr;
+	Class *mixinPtr;
+
+	FOREACH(mixinPtr, oPtr->mixins) {
+	    AddSimpleClassChainToCallContext(mixinPtr, methodNameObj, cbPtr,
+		    doneFilters, flags|TRAVERSED_MIXIN, filterDecl);
+	}
+	if (oPtr->methodsPtr) {
+	    hPtr = Tcl_FindHashEntry(oPtr->methodsPtr, (char*) methodNameObj);
+	    if (hPtr != NULL) {
+		AddMethodToCallChain(Tcl_GetHashValue(hPtr), cbPtr,
+			doneFilters, filterDecl, flags);
+	    }
+	}
+    }
+    AddSimpleClassChainToCallContext(oPtr->selfCls, methodNameObj, cbPtr,
+	    doneFilters, flags, filterDecl);
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * AddMethodToCallChain --
+ *
+ *	Utility method that manages the adding of a particular method
+ *	implementation to a call-chain.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+static inline void
+AddMethodToCallChain(
+    Method *const mPtr,		/* Actual method implementation to add to call
+				 * chain (or NULL, a no-op). */
+    struct ChainBuilder *const cbPtr,
+				/* The call chain to add the method
+				 * implementation to. */
+    Tcl_HashTable *const doneFilters,
+				/* Where to record what filters have been
+				 * processed. If NULL, not processing filters.
+				 * Note that this function does not update
+				 * this hashtable. */
+    Class *const filterDecl,	/* The class that declared the filter. If
+				 * NULL, either the filter was declared by the
+				 * object or this isn't a filter. */
+    int flags)			/* Used to check if we're mixin-consistent
+				 * only. Mixin-consistent means that either
+				 * we're looking to add things from a mixin
+				 * and we have passed a mixin, or we're not
+				 * looking to add things from a mixin and have
+				 * not passed a mixin. */
+{
+    register CallChain *callPtr = cbPtr->callChainPtr;
+    int i;
+
+    /*
+     * Return if this is just an entry used to record whether this is a public
+     * method. If so, there's nothing real to call and so nothing to add to
+     * the call chain.
+     *
+     * This is also where we enforce mixin-consistency.
+     */
+
+    if (mPtr == NULL || mPtr->typePtr == NULL || !MIXIN_CONSISTENT(flags)) {
+	return;
+    }
+
+    /*
+     * Enforce real private method handling here. We will skip adding this
+     * method IF
+     *  1) we are not allowing private methods, AND
+     *  2) this is a private method, AND
+     *  3) this is a class method, AND
+     *  4) this method was not declared by the class of the current object.
+     *
+     * This does mean that only classes really handle private methods. This
+     * should be sufficient for [incr Tcl] support though.
+     */
+
+    if (!(callPtr->flags & PRIVATE_METHOD)
+	    && (mPtr->flags & PRIVATE_METHOD)
+	    && (mPtr->declaringClassPtr != NULL)
+	    && (mPtr->declaringClassPtr != cbPtr->oPtr->selfCls)) {
+	return;
+    }
+
+    /*
+     * First test whether the method is already in the call chain. Skip over
+     * any leading filters.
+     */
+
+    for (i=cbPtr->filterLength ; i<callPtr->numChain ; i++) {
+	if (callPtr->chain[i].mPtr == mPtr &&
+		callPtr->chain[i].isFilter == (doneFilters != NULL)) {
+	    /*
+	     * Call chain semantics states that methods come as *late* in the
+	     * call chain as possible. This is done by copying down the
+	     * following methods. Note that this does not change the number of
+	     * method invokations in the call chain; it just rearranges them.
+	     */
+
+	    Class *declCls = callPtr->chain[i].filterDeclarer;
+
+	    for (; i+1<callPtr->numChain ; i++) {
+		callPtr->chain[i] = callPtr->chain[i+1];
+	    }
+	    callPtr->chain[i].mPtr = mPtr;
+	    callPtr->chain[i].isFilter = (doneFilters != NULL);
+	    callPtr->chain[i].filterDeclarer = declCls;
+	    return;
+	}
+    }
+
+    /*
+     * Need to really add the method. This is made a bit more complex by the
+     * fact that we are using some "static" space initially, and only start
+     * realloc-ing if the chain gets long.
+     */
+
+    if (callPtr->numChain == CALL_CHAIN_STATIC_SIZE) {
+	callPtr->chain =
+		ckalloc(sizeof(struct MInvoke) * (callPtr->numChain+1));
+	memcpy(callPtr->chain, callPtr->staticChain,
+		sizeof(struct MInvoke) * callPtr->numChain);
+    } else if (callPtr->numChain > CALL_CHAIN_STATIC_SIZE) {
+	callPtr->chain = ckrealloc(callPtr->chain,
+		sizeof(struct MInvoke) * (callPtr->numChain + 1));
+    }
+    callPtr->chain[i].mPtr = mPtr;
+    callPtr->chain[i].isFilter = (doneFilters != NULL);
+    callPtr->chain[i].filterDeclarer = filterDecl;
+    callPtr->numChain++;
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * InitCallChain --
+ *	Encoding of the policy of how to set up a call chain. Doesn't populate
+ *	the chain with the method implementation data.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+static inline void
+InitCallChain(
+    CallChain *callPtr,
+    Object *oPtr,
+    int flags)
+{
+    callPtr->flags = flags &
+	    (PUBLIC_METHOD | PRIVATE_METHOD | SPECIAL | FILTER_HANDLING);
+    if (oPtr->flags & USE_CLASS_CACHE) {
+	oPtr = oPtr->selfCls->thisPtr;
+	callPtr->flags |= USE_CLASS_CACHE;
+    }
+    callPtr->epoch = oPtr->fPtr->epoch;
+    callPtr->objectCreationEpoch = oPtr->creationEpoch;
+    callPtr->objectEpoch = oPtr->epoch;
+    callPtr->refCount = 1;
+    callPtr->numChain = 0;
+    callPtr->chain = callPtr->staticChain;
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * IsStillValid --
+ *	Calculates whether the given call chain can be used for executing a
+ *	method for the given object. The condition on a chain from a cached
+ *	location being reusable is:
+ *	- Refers to the same object (same creation epoch), and
+ *	- Still across the same class structure (same global epoch), and
+ *	- Still across the same object strucutre (same local epoch), and
+ *	- No public/private/filter magic leakage (same flags, modulo the fact
+ *	  that a public chain will satisfy a non-public call).
+ *
+ * ----------------------------------------------------------------------
+ */
+
+static inline int
+IsStillValid(
+    CallChain *callPtr,
+    Object *oPtr,
+    int flags,
+    int mask)
+{
+    if ((oPtr->flags & USE_CLASS_CACHE)) {
+	oPtr = oPtr->selfCls->thisPtr;
+	flags |= USE_CLASS_CACHE;
+    }
+    return ((callPtr->objectCreationEpoch == oPtr->creationEpoch)
+	    && (callPtr->epoch == oPtr->fPtr->epoch)
+	    && (callPtr->objectEpoch == oPtr->epoch)
+	    && ((callPtr->flags & mask) == (flags & mask)));
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * TclOOGetCallContext --
+ *
+ *	Responsible for constructing the call context, an ordered list of all
+ *	method implementations to be called as part of a method invokation.
+ *	This method is central to the whole operation of the OO system.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+CallContext *
+TclOOGetCallContext(
+    Object *oPtr,		/* The object to get the context for. */
+    Tcl_Obj *methodNameObj,	/* The name of the method to get the context
+				 * for. NULL when getting a constructor or
+				 * destructor chain. */
+    int flags,			/* What sort of context are we looking for.
+				 * Only the bits PUBLIC_METHOD, CONSTRUCTOR,
+				 * PRIVATE_METHOD, DESTRUCTOR and
+				 * FILTER_HANDLING are useful. */
+    Tcl_Obj *cacheInThisObj)	/* What object to cache in, or NULL if it is
+				 * to be in the same object as the
+				 * methodNameObj. */
+{
+    CallContext *contextPtr;
+    CallChain *callPtr;
+    struct ChainBuilder cb;
+    int i, count, doFilters;
+    Tcl_HashEntry *hPtr;
+    Tcl_HashTable doneFilters;
+
+    if (cacheInThisObj == NULL) {
+	cacheInThisObj = methodNameObj;
+    }
+    if (flags&(SPECIAL|FILTER_HANDLING) || (oPtr->flags&FILTER_HANDLING)) {
+	hPtr = NULL;
+	doFilters = 0;
+
+	/*
+	 * Check if we have a cached valid constructor or destructor.
+	 */
+
+	if (flags & CONSTRUCTOR) {
+	    callPtr = oPtr->selfCls->constructorChainPtr;
+	    if ((callPtr != NULL)
+		    && (callPtr->objectEpoch == oPtr->selfCls->thisPtr->epoch)
+		    && (callPtr->epoch == oPtr->fPtr->epoch)) {
+		callPtr->refCount++;
+		goto returnContext;
+	    }
+	} else if (flags & DESTRUCTOR) {
+	    callPtr = oPtr->selfCls->destructorChainPtr;
+	    if ((oPtr->mixins.num == 0) && (callPtr != NULL)
+		    && (callPtr->objectEpoch == oPtr->selfCls->thisPtr->epoch)
+		    && (callPtr->epoch == oPtr->fPtr->epoch)) {
+		callPtr->refCount++;
+		goto returnContext;
+	    }
+	}
+    } else {
+	/*
+	 * Check if we can get the chain out of the Tcl_Obj method name or out
+	 * of the cache. This is made a bit more complex by the fact that
+	 * there are multiple different layers of cache (in the Tcl_Obj, in
+	 * the object, and in the class).
+	 */
+
+	const int reuseMask = ((flags & PUBLIC_METHOD) ? ~0 : ~PUBLIC_METHOD);
+
+	if (cacheInThisObj->typePtr == &methodNameType) {
+	    callPtr = cacheInThisObj->internalRep.twoPtrValue.ptr1;
+	    if (IsStillValid(callPtr, oPtr, flags, reuseMask)) {
+		callPtr->refCount++;
+		goto returnContext;
+	    }
+	    FreeMethodNameRep(cacheInThisObj);
+	}
+
+	if (oPtr->flags & USE_CLASS_CACHE) {
+	    if (oPtr->selfCls->classChainCache != NULL) {
+		hPtr = Tcl_FindHashEntry(oPtr->selfCls->classChainCache,
+			(char *) methodNameObj);
+	    } else {
+		hPtr = NULL;
+	    }
+	} else {
+	    if (oPtr->chainCache != NULL) {
+		hPtr = Tcl_FindHashEntry(oPtr->chainCache,
+			(char *) methodNameObj);
+	    } else {
+		hPtr = NULL;
+	    }
+	}
+
+	if (hPtr != NULL && Tcl_GetHashValue(hPtr) != NULL) {
+	    callPtr = Tcl_GetHashValue(hPtr);
+	    if (IsStillValid(callPtr, oPtr, flags, reuseMask)) {
+		callPtr->refCount++;
+		goto returnContext;
+	    }
+	    Tcl_SetHashValue(hPtr, NULL);
+	    TclOODeleteChain(callPtr);
+	}
+
+	doFilters = 1;
+    }
+
+    callPtr = ckalloc(sizeof(CallChain));
+    InitCallChain(callPtr, oPtr, flags);
+
+    cb.callChainPtr = callPtr;
+    cb.filterLength = 0;
+    cb.oPtr = oPtr;
+
+    /*
+     * If we're working with a forced use of unknown, do that now.
+     */
+
+    if (flags & FORCE_UNKNOWN) {
+	AddSimpleChainToCallContext(oPtr, oPtr->fPtr->unknownMethodNameObj,
+		&cb, NULL, BUILDING_MIXINS, NULL);
+	AddSimpleChainToCallContext(oPtr, oPtr->fPtr->unknownMethodNameObj,
+		&cb, NULL, 0, NULL);
+	callPtr->flags |= OO_UNKNOWN_METHOD;
+	callPtr->epoch = -1;
+	if (callPtr->numChain == 0) {
+	    TclOODeleteChain(callPtr);
+	    return NULL;
+	}
+	goto returnContext;
+    }
+
+    /*
+     * Add all defined filters (if any, and if we're going to be processing
+     * them; they're not processed for constructors, destructors or when we're
+     * in the middle of processing a filter).
+     */
+
+    if (doFilters) {
+	Tcl_Obj *filterObj;
+	Class *mixinPtr;
+
+	doFilters = 1;
+	Tcl_InitObjHashTable(&doneFilters);
+	FOREACH(mixinPtr, oPtr->mixins) {
+	    AddClassFiltersToCallContext(oPtr, mixinPtr, &cb, &doneFilters,
+		    TRAVERSED_MIXIN|BUILDING_MIXINS|OBJECT_MIXIN);
+	    AddClassFiltersToCallContext(oPtr, mixinPtr, &cb, &doneFilters,
+		    OBJECT_MIXIN);
+	}
+	FOREACH(filterObj, oPtr->filters) {
+	    AddSimpleChainToCallContext(oPtr, filterObj, &cb, &doneFilters,
+		    BUILDING_MIXINS, NULL);
+	    AddSimpleChainToCallContext(oPtr, filterObj, &cb, &doneFilters, 0,
+		    NULL);
+	}
+	AddClassFiltersToCallContext(oPtr, oPtr->selfCls, &cb, &doneFilters,
+		BUILDING_MIXINS);
+	AddClassFiltersToCallContext(oPtr, oPtr->selfCls, &cb, &doneFilters,
+		0);
+	Tcl_DeleteHashTable(&doneFilters);
+    }
+    count = cb.filterLength = callPtr->numChain;
+
+    /*
+     * Add the actual method implementations. We have to do this twice to
+     * handle class mixins right.
+     */
+
+    AddSimpleChainToCallContext(oPtr, methodNameObj, &cb, NULL,
+	    flags|BUILDING_MIXINS, NULL);
+    AddSimpleChainToCallContext(oPtr, methodNameObj, &cb, NULL, flags, NULL);
+
+    /*
+     * Check to see if the method has no implementation. If so, we probably
+     * need to add in a call to the unknown method. Otherwise, set up the
+     * cacheing of the method implementation (if relevant).
+     */
+
+    if (count == callPtr->numChain) {
+	/*
+	 * Method does not actually exist. If we're dealing with constructors
+	 * or destructors, this isn't a problem.
+	 */
+
+	if (flags & SPECIAL) {
+	    TclOODeleteChain(callPtr);
+	    return NULL;
+	}
+	AddSimpleChainToCallContext(oPtr, oPtr->fPtr->unknownMethodNameObj,
+		&cb, NULL, BUILDING_MIXINS, NULL);
+	AddSimpleChainToCallContext(oPtr, oPtr->fPtr->unknownMethodNameObj,
+		&cb, NULL, 0, NULL);
+	callPtr->flags |= OO_UNKNOWN_METHOD;
+	callPtr->epoch = -1;
+	if (count == callPtr->numChain) {
+	    TclOODeleteChain(callPtr);
+	    return NULL;
+	}
+    } else if (doFilters) {
+	if (hPtr == NULL) {
+	    if (oPtr->flags & USE_CLASS_CACHE) {
+		if (oPtr->selfCls->classChainCache == NULL) {
+		    oPtr->selfCls->classChainCache =
+			    ckalloc(sizeof(Tcl_HashTable));
+
+		    Tcl_InitObjHashTable(oPtr->selfCls->classChainCache);
+		}
+		hPtr = Tcl_CreateHashEntry(oPtr->selfCls->classChainCache,
+			(char *) methodNameObj, &i);
+	    } else {
+		if (oPtr->chainCache == NULL) {
+		    oPtr->chainCache = ckalloc(sizeof(Tcl_HashTable));
+
+		    Tcl_InitObjHashTable(oPtr->chainCache);
+		}
+		hPtr = Tcl_CreateHashEntry(oPtr->chainCache,
+			(char *) methodNameObj, &i);
+	    }
+	}
+	callPtr->refCount++;
+	Tcl_SetHashValue(hPtr, callPtr);
+	StashCallChain(cacheInThisObj, callPtr);
+    } else if (flags & CONSTRUCTOR) {
+	if (oPtr->selfCls->constructorChainPtr) {
+	    TclOODeleteChain(oPtr->selfCls->constructorChainPtr);
+	}
+	oPtr->selfCls->constructorChainPtr = callPtr;
+	callPtr->refCount++;
+    } else if ((flags & DESTRUCTOR) && oPtr->mixins.num == 0) {
+	if (oPtr->selfCls->destructorChainPtr) {
+	    TclOODeleteChain(oPtr->selfCls->destructorChainPtr);
+	}
+	oPtr->selfCls->destructorChainPtr = callPtr;
+	callPtr->refCount++;
+    }
+
+  returnContext:
+    contextPtr = TclStackAlloc(oPtr->fPtr->interp, sizeof(CallContext));
+    contextPtr->oPtr = oPtr;
+    AddRef(oPtr);
+    contextPtr->callPtr = callPtr;
+    contextPtr->skip = 2;
+    contextPtr->index = 0;
+    return contextPtr;
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * TclOOGetStereotypeCallChain --
+ *
+ *	Construct a call-chain for a method that would be used by a
+ *	stereotypical instance of the given class (i.e., where the object has
+ *	no definitions special to itself).
+ *
+ * ----------------------------------------------------------------------
+ */
+
+CallChain *
+TclOOGetStereotypeCallChain(
+    Class *clsPtr,		/* The object to get the context for. */
+    Tcl_Obj *methodNameObj,	/* The name of the method to get the context
+				 * for. NULL when getting a constructor or
+				 * destructor chain. */
+    int flags)			/* What sort of context are we looking for.
+				 * Only the bits PUBLIC_METHOD, CONSTRUCTOR,
+				 * PRIVATE_METHOD, DESTRUCTOR and
+				 * FILTER_HANDLING are useful. */
+{
+    CallChain *callPtr;
+    struct ChainBuilder cb;
+    int i, count;
+    Foundation *fPtr = clsPtr->thisPtr->fPtr;
+    Tcl_HashEntry *hPtr;
+    Tcl_HashTable doneFilters;
+    Object obj;
+
+    /*
+     * Synthesize a temporary stereotypical object so that we can use existing
+     * machinery to produce the stereotypical call chain.
+     */
+
+    memset(&obj, 0, sizeof(Object));
+    obj.fPtr = fPtr;
+    obj.selfCls = clsPtr;
+    obj.refCount = 1;
+    obj.flags = USE_CLASS_CACHE;
+
+    /*
+     * Check if we can get the chain out of the Tcl_Obj method name or out of
+     * the cache. This is made a bit more complex by the fact that there are
+     * multiple different layers of cache (in the Tcl_Obj, in the object, and
+     * in the class).
+     */
+
+    if (clsPtr->classChainCache != NULL) {
+	hPtr = Tcl_FindHashEntry(clsPtr->classChainCache,
+		(char *) methodNameObj);
+	if (hPtr != NULL && Tcl_GetHashValue(hPtr) != NULL) {
+	    const int reuseMask =
+		    ((flags & PUBLIC_METHOD) ? ~0 : ~PUBLIC_METHOD);
+
+	    callPtr = Tcl_GetHashValue(hPtr);
+	    if (IsStillValid(callPtr, &obj, flags, reuseMask)) {
+		callPtr->refCount++;
+		return callPtr;
+	    }
+	    Tcl_SetHashValue(hPtr, NULL);
+	    TclOODeleteChain(callPtr);
+	}
+    } else {
+	hPtr = NULL;
+    }
+
+    callPtr = ckalloc(sizeof(CallChain));
+    memset(callPtr, 0, sizeof(CallChain));
+    callPtr->flags = flags & (PUBLIC_METHOD|PRIVATE_METHOD|FILTER_HANDLING);
+    callPtr->epoch = fPtr->epoch;
+    callPtr->objectCreationEpoch = fPtr->tsdPtr->nsCount;
+    callPtr->objectEpoch = clsPtr->thisPtr->epoch;
+    callPtr->refCount = 1;
+    callPtr->chain = callPtr->staticChain;
+
+    cb.callChainPtr = callPtr;
+    cb.filterLength = 0;
+    cb.oPtr = &obj;
+
+    /*
+     * Add all defined filters (if any, and if we're going to be processing
+     * them; they're not processed for constructors, destructors or when we're
+     * in the middle of processing a filter).
+     */
+
+    Tcl_InitObjHashTable(&doneFilters);
+    AddClassFiltersToCallContext(&obj, clsPtr, &cb, &doneFilters,
+	    BUILDING_MIXINS);
+    AddClassFiltersToCallContext(&obj, clsPtr, &cb, &doneFilters, 0);
+    Tcl_DeleteHashTable(&doneFilters);
+    count = cb.filterLength = callPtr->numChain;
+
+    /*
+     * Add the actual method implementations.
+     */
+
+    AddSimpleChainToCallContext(&obj, methodNameObj, &cb, NULL,
+	    flags|BUILDING_MIXINS, NULL);
+    AddSimpleChainToCallContext(&obj, methodNameObj, &cb, NULL, flags, NULL);
+
+    /*
+     * Check to see if the method has no implementation. If so, we probably
+     * need to add in a call to the unknown method. Otherwise, set up the
+     * cacheing of the method implementation (if relevant).
+     */
+
+    if (count == callPtr->numChain) {
+	AddSimpleChainToCallContext(&obj, fPtr->unknownMethodNameObj, &cb,
+		NULL, BUILDING_MIXINS, NULL);
+	AddSimpleChainToCallContext(&obj, fPtr->unknownMethodNameObj, &cb,
+		NULL, 0, NULL);
+	callPtr->flags |= OO_UNKNOWN_METHOD;
+	callPtr->epoch = -1;
+	if (count == callPtr->numChain) {
+	    TclOODeleteChain(callPtr);
+	    return NULL;
+	}
+    } else {
+	if (hPtr == NULL) {
+	    if (clsPtr->classChainCache == NULL) {
+		clsPtr->classChainCache = ckalloc(sizeof(Tcl_HashTable));
+		Tcl_InitObjHashTable(clsPtr->classChainCache);
+	    }
+	    hPtr = Tcl_CreateHashEntry(clsPtr->classChainCache,
+		    (char *) methodNameObj, &i);
+	}
+	callPtr->refCount++;
+	Tcl_SetHashValue(hPtr, callPtr);
+	StashCallChain(methodNameObj, callPtr);
+    }
+    return callPtr;
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * AddClassFiltersToCallContext --
+ *
+ *	Logic to make extracting all the filters from the class context much
+ *	easier.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+static void
+AddClassFiltersToCallContext(
+    Object *const oPtr,		/* Object that the filters operate on. */
+    Class *clsPtr,		/* Class to get the filters from. */
+    struct ChainBuilder *const cbPtr,
+				/* Context to fill with call chain entries. */
+    Tcl_HashTable *const doneFilters,
+				/* Where to record what filters have been
+				 * processed. Keys are objects, values are
+				 * ignored. */
+    int flags)			/* Whether we've gone along a mixin link
+				 * yet. */
+{
+    int i, clearedFlags =
+	    flags & ~(TRAVERSED_MIXIN|OBJECT_MIXIN|BUILDING_MIXINS);
+    Class *superPtr, *mixinPtr;
+    Tcl_Obj *filterObj;
+
+  tailRecurse:
+    if (clsPtr == NULL) {
+	return;
+    }
+
+    /*
+     * Add all the filters defined by classes mixed into the main class
+     * hierarchy.
+     */
+
+    FOREACH(mixinPtr, clsPtr->mixins) {
+	AddClassFiltersToCallContext(oPtr, mixinPtr, cbPtr, doneFilters,
+		flags|TRAVERSED_MIXIN);
+    }
+
+    /*
+     * Add all the class filters from the current class. Note that the filters
+     * are added starting at the object root, as this allows the object to
+     * override how filters work to extend their behaviour.
+     */
+
+    if (MIXIN_CONSISTENT(flags)) {
+	FOREACH(filterObj, clsPtr->filters) {
+	    int isNew;
+
+	    (void) Tcl_CreateHashEntry(doneFilters, (char *) filterObj,
+		    &isNew);
+	    if (isNew) {
+		AddSimpleChainToCallContext(oPtr, filterObj, cbPtr,
+			doneFilters, clearedFlags|BUILDING_MIXINS, clsPtr);
+		AddSimpleChainToCallContext(oPtr, filterObj, cbPtr,
+			doneFilters, clearedFlags, clsPtr);
+	    }
+	}
+    }
+
+    /*
+     * Now process the recursive case. Notice the tail-call optimization.
+     */
+
+    switch (clsPtr->superclasses.num) {
+    case 1:
+	clsPtr = clsPtr->superclasses.list[0];
+	goto tailRecurse;
+    default:
+	FOREACH(superPtr, clsPtr->superclasses) {
+	    AddClassFiltersToCallContext(oPtr, superPtr, cbPtr, doneFilters,
+		    flags);
+	}
+    case 0:
+	return;
+    }
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * AddSimpleClassChainToCallContext --
+ *
+ *	Construct a call-chain from a class hierarchy.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+static void
+AddSimpleClassChainToCallContext(
+    Class *classPtr,		/* Class to add the call chain entries for. */
+    Tcl_Obj *const methodNameObj,
+				/* Name of method to add the call chain
+				 * entries for. */
+    struct ChainBuilder *const cbPtr,
+				/* Where to add the call chain entries. */
+    Tcl_HashTable *const doneFilters,
+				/* Where to record what call chain entries
+				 * have been processed. */
+    int flags,			/* What sort of call chain are we building. */
+    Class *const filterDecl)	/* The class that declared the filter. If
+				 * NULL, either the filter was declared by the
+				 * object or this isn't a filter. */
+{
+    int i;
+    Class *superPtr;
+
+    /*
+     * We hard-code the tail-recursive form. It's by far the most common case
+     * *and* it is much more gentle on the stack.
+     *
+     * Note that mixins must be processed before the main class hierarchy.
+     * [Bug 1998221]
+     */
+
+  tailRecurse:
+    FOREACH(superPtr, classPtr->mixins) {
+	AddSimpleClassChainToCallContext(superPtr, methodNameObj, cbPtr,
+		doneFilters, flags|TRAVERSED_MIXIN, filterDecl);
+    }
+
+    if (flags & CONSTRUCTOR) {
+	AddMethodToCallChain(classPtr->constructorPtr, cbPtr, doneFilters,
+		filterDecl, flags);
+
+    } else if (flags & DESTRUCTOR) {
+	AddMethodToCallChain(classPtr->destructorPtr, cbPtr, doneFilters,
+		filterDecl, flags);
+    } else {
+	Tcl_HashEntry *hPtr = Tcl_FindHashEntry(&classPtr->classMethods,
+		(char *) methodNameObj);
+
+	if (hPtr != NULL) {
+	    register Method *mPtr = Tcl_GetHashValue(hPtr);
+
+	    if (!(flags & KNOWN_STATE)) {
+		if (flags & PUBLIC_METHOD) {
+		    if (mPtr->flags & PUBLIC_METHOD) {
+			flags |= DEFINITE_PUBLIC;
+		    } else {
+			return;
+		    }
+		} else {
+		    flags |= DEFINITE_PROTECTED;
+		}
+	    }
+	    AddMethodToCallChain(mPtr, cbPtr, doneFilters, filterDecl, flags);
+	}
+    }
+
+    switch (classPtr->superclasses.num) {
+    case 1:
+	classPtr = classPtr->superclasses.list[0];
+	goto tailRecurse;
+    default:
+	FOREACH(superPtr, classPtr->superclasses) {
+	    AddSimpleClassChainToCallContext(superPtr, methodNameObj, cbPtr,
+		    doneFilters, flags, filterDecl);
+	}
+    case 0:
+	return;
+    }
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * TclOORenderCallChain --
+ *
+ *	Create a description of a call chain. Used in [info object call],
+ *	[info class call], and [self call].
+ *
+ * ----------------------------------------------------------------------
+ */
+
+Tcl_Obj *
+TclOORenderCallChain(
+    Tcl_Interp *interp,
+    CallChain *callPtr)
+{
+    Tcl_Obj *filterLiteral, *methodLiteral, *objectLiteral;
+    Tcl_Obj *resultObj, *descObjs[4], **objv;
+    Foundation *fPtr = TclOOGetFoundation(interp);
+    int i;
+
+    /*
+     * Allocate the literals (potentially) used in our description.
+     */
+
+    filterLiteral = Tcl_NewStringObj("filter", -1);
+    Tcl_IncrRefCount(filterLiteral);
+    methodLiteral = Tcl_NewStringObj("method", -1);
+    Tcl_IncrRefCount(methodLiteral);
+    objectLiteral = Tcl_NewStringObj("object", -1);
+    Tcl_IncrRefCount(objectLiteral);
+
+    /*
+     * Do the actual construction of the descriptions. They consist of a list
+     * of triples that describe the details of how a method is understood. For
+     * each triple, the first word is the type of invokation ("method" is
+     * normal, "unknown" is special because it adds the method name as an
+     * extra argument when handled by some method types, and "filter" is
+     * special because it's a filter method). The second word is the name of
+     * the method in question (which differs for "unknown" and "filter" types)
+     * and the third word is the full name of the class that declares the
+     * method (or "object" if it is declared on the instance).
+     */
+
+    objv = TclStackAlloc(interp, callPtr->numChain * sizeof(Tcl_Obj *));
+    for (i=0 ; i<callPtr->numChain ; i++) {
+	struct MInvoke *miPtr = &callPtr->chain[i];
+
+	descObjs[0] = miPtr->isFilter
+		? filterLiteral
+		: callPtr->flags & OO_UNKNOWN_METHOD
+			? fPtr->unknownMethodNameObj
+			: methodLiteral;
+	descObjs[1] = callPtr->flags & CONSTRUCTOR
+		? fPtr->constructorName
+		: callPtr->flags & DESTRUCTOR
+			? fPtr->destructorName
+			: miPtr->mPtr->namePtr;
+	descObjs[2] = miPtr->mPtr->declaringClassPtr
+		? Tcl_GetObjectName(interp,
+			(Tcl_Object) miPtr->mPtr->declaringClassPtr->thisPtr)
+		: objectLiteral;
+	descObjs[3] = Tcl_NewStringObj(miPtr->mPtr->typePtr->name, -1);
+
+	objv[i] = Tcl_NewListObj(4, descObjs);
+    }
+
+    /*
+     * Drop the local references to the literals; if they're actually used,
+     * they'll live on the description itself.
+     */
+
+    Tcl_DecrRefCount(filterLiteral);
+    Tcl_DecrRefCount(methodLiteral);
+    Tcl_DecrRefCount(objectLiteral);
+
+    /*
+     * Finish building the description and return it.
+     */
+
+    resultObj = Tcl_NewListObj(callPtr->numChain, objv);
+    TclStackFree(interp, objv);
+    return resultObj;
+}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tclOODecls.h b/generic/tclOODecls.h
new file mode 100644
index 0000000..9fd62ec
--- /dev/null
+++ b/generic/tclOODecls.h
@@ -0,0 +1,234 @@
+/*
+ * This file is (mostly) automatically generated from tclOO.decls.
+ */
+
+#ifndef _TCLOODECLS
+#define _TCLOODECLS
+
+#ifndef TCLAPI
+#   ifdef BUILD_tcl
+#	define TCLAPI extern DLLEXPORT
+#   else
+#	define TCLAPI extern DLLIMPORT
+#   endif
+#endif
+
+#ifdef USE_TCL_STUBS
+#   undef USE_TCLOO_STUBS
+#   define USE_TCLOO_STUBS
+#endif
+
+/* !BEGIN!: Do not edit below this line. */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Exported function declarations:
+ */
+
+/* 0 */
+TCLAPI Tcl_Object	Tcl_CopyObjectInstance(Tcl_Interp *interp,
+				Tcl_Object sourceObject,
+				const char *targetName,
+				const char *targetNamespaceName);
+/* 1 */
+TCLAPI Tcl_Object	Tcl_GetClassAsObject(Tcl_Class clazz);
+/* 2 */
+TCLAPI Tcl_Class	Tcl_GetObjectAsClass(Tcl_Object object);
+/* 3 */
+TCLAPI Tcl_Command	Tcl_GetObjectCommand(Tcl_Object object);
+/* 4 */
+TCLAPI Tcl_Object	Tcl_GetObjectFromObj(Tcl_Interp *interp,
+				Tcl_Obj *objPtr);
+/* 5 */
+TCLAPI Tcl_Namespace *	Tcl_GetObjectNamespace(Tcl_Object object);
+/* 6 */
+TCLAPI Tcl_Class	Tcl_MethodDeclarerClass(Tcl_Method method);
+/* 7 */
+TCLAPI Tcl_Object	Tcl_MethodDeclarerObject(Tcl_Method method);
+/* 8 */
+TCLAPI int		Tcl_MethodIsPublic(Tcl_Method method);
+/* 9 */
+TCLAPI int		Tcl_MethodIsType(Tcl_Method method,
+				const Tcl_MethodType *typePtr,
+				ClientData *clientDataPtr);
+/* 10 */
+TCLAPI Tcl_Obj *	Tcl_MethodName(Tcl_Method method);
+/* 11 */
+TCLAPI Tcl_Method	Tcl_NewInstanceMethod(Tcl_Interp *interp,
+				Tcl_Object object, Tcl_Obj *nameObj,
+				int isPublic, const Tcl_MethodType *typePtr,
+				ClientData clientData);
+/* 12 */
+TCLAPI Tcl_Method	Tcl_NewMethod(Tcl_Interp *interp, Tcl_Class cls,
+				Tcl_Obj *nameObj, int isPublic,
+				const Tcl_MethodType *typePtr,
+				ClientData clientData);
+/* 13 */
+TCLAPI Tcl_Object	Tcl_NewObjectInstance(Tcl_Interp *interp,
+				Tcl_Class cls, const char *nameStr,
+				const char *nsNameStr, int objc,
+				Tcl_Obj *const *objv, int skip);
+/* 14 */
+TCLAPI int		Tcl_ObjectDeleted(Tcl_Object object);
+/* 15 */
+TCLAPI int		Tcl_ObjectContextIsFiltering(
+				Tcl_ObjectContext context);
+/* 16 */
+TCLAPI Tcl_Method	Tcl_ObjectContextMethod(Tcl_ObjectContext context);
+/* 17 */
+TCLAPI Tcl_Object	Tcl_ObjectContextObject(Tcl_ObjectContext context);
+/* 18 */
+TCLAPI int		Tcl_ObjectContextSkippedArgs(
+				Tcl_ObjectContext context);
+/* 19 */
+TCLAPI ClientData	Tcl_ClassGetMetadata(Tcl_Class clazz,
+				const Tcl_ObjectMetadataType *typePtr);
+/* 20 */
+TCLAPI void		Tcl_ClassSetMetadata(Tcl_Class clazz,
+				const Tcl_ObjectMetadataType *typePtr,
+				ClientData metadata);
+/* 21 */
+TCLAPI ClientData	Tcl_ObjectGetMetadata(Tcl_Object object,
+				const Tcl_ObjectMetadataType *typePtr);
+/* 22 */
+TCLAPI void		Tcl_ObjectSetMetadata(Tcl_Object object,
+				const Tcl_ObjectMetadataType *typePtr,
+				ClientData metadata);
+/* 23 */
+TCLAPI int		Tcl_ObjectContextInvokeNext(Tcl_Interp *interp,
+				Tcl_ObjectContext context, int objc,
+				Tcl_Obj *const *objv, int skip);
+/* 24 */
+TCLAPI Tcl_ObjectMapMethodNameProc * Tcl_ObjectGetMethodNameMapper(
+				Tcl_Object object);
+/* 25 */
+TCLAPI void		Tcl_ObjectSetMethodNameMapper(Tcl_Object object,
+				Tcl_ObjectMapMethodNameProc *mapMethodNameProc);
+/* 26 */
+TCLAPI void		Tcl_ClassSetConstructor(Tcl_Interp *interp,
+				Tcl_Class clazz, Tcl_Method method);
+/* 27 */
+TCLAPI void		Tcl_ClassSetDestructor(Tcl_Interp *interp,
+				Tcl_Class clazz, Tcl_Method method);
+/* 28 */
+TCLAPI Tcl_Obj *	Tcl_GetObjectName(Tcl_Interp *interp,
+				Tcl_Object object);
+
+typedef struct {
+    const struct TclOOIntStubs *tclOOIntStubs;
+} TclOOStubHooks;
+
+typedef struct TclOOStubs {
+    int magic;
+    const TclOOStubHooks *hooks;
+
+    Tcl_Object (*tcl_CopyObjectInstance) (Tcl_Interp *interp, Tcl_Object sourceObject, const char *targetName, const char *targetNamespaceName); /* 0 */
+    Tcl_Object (*tcl_GetClassAsObject) (Tcl_Class clazz); /* 1 */
+    Tcl_Class (*tcl_GetObjectAsClass) (Tcl_Object object); /* 2 */
+    Tcl_Command (*tcl_GetObjectCommand) (Tcl_Object object); /* 3 */
+    Tcl_Object (*tcl_GetObjectFromObj) (Tcl_Interp *interp, Tcl_Obj *objPtr); /* 4 */
+    Tcl_Namespace * (*tcl_GetObjectNamespace) (Tcl_Object object); /* 5 */
+    Tcl_Class (*tcl_MethodDeclarerClass) (Tcl_Method method); /* 6 */
+    Tcl_Object (*tcl_MethodDeclarerObject) (Tcl_Method method); /* 7 */
+    int (*tcl_MethodIsPublic) (Tcl_Method method); /* 8 */
+    int (*tcl_MethodIsType) (Tcl_Method method, const Tcl_MethodType *typePtr, ClientData *clientDataPtr); /* 9 */
+    Tcl_Obj * (*tcl_MethodName) (Tcl_Method method); /* 10 */
+    Tcl_Method (*tcl_NewInstanceMethod) (Tcl_Interp *interp, Tcl_Object object, Tcl_Obj *nameObj, int isPublic, const Tcl_MethodType *typePtr, ClientData clientData); /* 11 */
+    Tcl_Method (*tcl_NewMethod) (Tcl_Interp *interp, Tcl_Class cls, Tcl_Obj *nameObj, int isPublic, const Tcl_MethodType *typePtr, ClientData clientData); /* 12 */
+    Tcl_Object (*tcl_NewObjectInstance) (Tcl_Interp *interp, Tcl_Class cls, const char *nameStr, const char *nsNameStr, int objc, Tcl_Obj *const *objv, int skip); /* 13 */
+    int (*tcl_ObjectDeleted) (Tcl_Object object); /* 14 */
+    int (*tcl_ObjectContextIsFiltering) (Tcl_ObjectContext context); /* 15 */
+    Tcl_Method (*tcl_ObjectContextMethod) (Tcl_ObjectContext context); /* 16 */
+    Tcl_Object (*tcl_ObjectContextObject) (Tcl_ObjectContext context); /* 17 */
+    int (*tcl_ObjectContextSkippedArgs) (Tcl_ObjectContext context); /* 18 */
+    ClientData (*tcl_ClassGetMetadata) (Tcl_Class clazz, const Tcl_ObjectMetadataType *typePtr); /* 19 */
+    void (*tcl_ClassSetMetadata) (Tcl_Class clazz, const Tcl_ObjectMetadataType *typePtr, ClientData metadata); /* 20 */
+    ClientData (*tcl_ObjectGetMetadata) (Tcl_Object object, const Tcl_ObjectMetadataType *typePtr); /* 21 */
+    void (*tcl_ObjectSetMetadata) (Tcl_Object object, const Tcl_ObjectMetadataType *typePtr, ClientData metadata); /* 22 */
+    int (*tcl_ObjectContextInvokeNext) (Tcl_Interp *interp, Tcl_ObjectContext context, int objc, Tcl_Obj *const *objv, int skip); /* 23 */
+    Tcl_ObjectMapMethodNameProc * (*tcl_ObjectGetMethodNameMapper) (Tcl_Object object); /* 24 */
+    void (*tcl_ObjectSetMethodNameMapper) (Tcl_Object object, Tcl_ObjectMapMethodNameProc *mapMethodNameProc); /* 25 */
+    void (*tcl_ClassSetConstructor) (Tcl_Interp *interp, Tcl_Class clazz, Tcl_Method method); /* 26 */
+    void (*tcl_ClassSetDestructor) (Tcl_Interp *interp, Tcl_Class clazz, Tcl_Method method); /* 27 */
+    Tcl_Obj * (*tcl_GetObjectName) (Tcl_Interp *interp, Tcl_Object object); /* 28 */
+} TclOOStubs;
+
+extern const TclOOStubs *tclOOStubsPtr;
+
+#ifdef __cplusplus
+}
+#endif
+
+#if defined(USE_TCLOO_STUBS)
+
+/*
+ * Inline function declarations:
+ */
+
+#define Tcl_CopyObjectInstance \
+	(tclOOStubsPtr->tcl_CopyObjectInstance) /* 0 */
+#define Tcl_GetClassAsObject \
+	(tclOOStubsPtr->tcl_GetClassAsObject) /* 1 */
+#define Tcl_GetObjectAsClass \
+	(tclOOStubsPtr->tcl_GetObjectAsClass) /* 2 */
+#define Tcl_GetObjectCommand \
+	(tclOOStubsPtr->tcl_GetObjectCommand) /* 3 */
+#define Tcl_GetObjectFromObj \
+	(tclOOStubsPtr->tcl_GetObjectFromObj) /* 4 */
+#define Tcl_GetObjectNamespace \
+	(tclOOStubsPtr->tcl_GetObjectNamespace) /* 5 */
+#define Tcl_MethodDeclarerClass \
+	(tclOOStubsPtr->tcl_MethodDeclarerClass) /* 6 */
+#define Tcl_MethodDeclarerObject \
+	(tclOOStubsPtr->tcl_MethodDeclarerObject) /* 7 */
+#define Tcl_MethodIsPublic \
+	(tclOOStubsPtr->tcl_MethodIsPublic) /* 8 */
+#define Tcl_MethodIsType \
+	(tclOOStubsPtr->tcl_MethodIsType) /* 9 */
+#define Tcl_MethodName \
+	(tclOOStubsPtr->tcl_MethodName) /* 10 */
+#define Tcl_NewInstanceMethod \
+	(tclOOStubsPtr->tcl_NewInstanceMethod) /* 11 */
+#define Tcl_NewMethod \
+	(tclOOStubsPtr->tcl_NewMethod) /* 12 */
+#define Tcl_NewObjectInstance \
+	(tclOOStubsPtr->tcl_NewObjectInstance) /* 13 */
+#define Tcl_ObjectDeleted \
+	(tclOOStubsPtr->tcl_ObjectDeleted) /* 14 */
+#define Tcl_ObjectContextIsFiltering \
+	(tclOOStubsPtr->tcl_ObjectContextIsFiltering) /* 15 */
+#define Tcl_ObjectContextMethod \
+	(tclOOStubsPtr->tcl_ObjectContextMethod) /* 16 */
+#define Tcl_ObjectContextObject \
+	(tclOOStubsPtr->tcl_ObjectContextObject) /* 17 */
+#define Tcl_ObjectContextSkippedArgs \
+	(tclOOStubsPtr->tcl_ObjectContextSkippedArgs) /* 18 */
+#define Tcl_ClassGetMetadata \
+	(tclOOStubsPtr->tcl_ClassGetMetadata) /* 19 */
+#define Tcl_ClassSetMetadata \
+	(tclOOStubsPtr->tcl_ClassSetMetadata) /* 20 */
+#define Tcl_ObjectGetMetadata \
+	(tclOOStubsPtr->tcl_ObjectGetMetadata) /* 21 */
+#define Tcl_ObjectSetMetadata \
+	(tclOOStubsPtr->tcl_ObjectSetMetadata) /* 22 */
+#define Tcl_ObjectContextInvokeNext \
+	(tclOOStubsPtr->tcl_ObjectContextInvokeNext) /* 23 */
+#define Tcl_ObjectGetMethodNameMapper \
+	(tclOOStubsPtr->tcl_ObjectGetMethodNameMapper) /* 24 */
+#define Tcl_ObjectSetMethodNameMapper \
+	(tclOOStubsPtr->tcl_ObjectSetMethodNameMapper) /* 25 */
+#define Tcl_ClassSetConstructor \
+	(tclOOStubsPtr->tcl_ClassSetConstructor) /* 26 */
+#define Tcl_ClassSetDestructor \
+	(tclOOStubsPtr->tcl_ClassSetDestructor) /* 27 */
+#define Tcl_GetObjectName \
+	(tclOOStubsPtr->tcl_GetObjectName) /* 28 */
+
+#endif /* defined(USE_TCLOO_STUBS) */
+
+/* !END!: Do not edit above this line. */
+
+#endif /* _TCLOODECLS */
diff --git a/generic/tclOODefineCmds.c b/generic/tclOODefineCmds.c
new file mode 100644
index 0000000..8747ff5
--- /dev/null
+++ b/generic/tclOODefineCmds.c
@@ -0,0 +1,2677 @@
+/*
+ * tclOODefineCmds.c --
+ *
+ *	This file contains the implementation of the ::oo::define command,
+ *	part of the object-system core (NB: not Tcl_Obj, but ::oo).
+ *
+ * Copyright (c) 2006-2013 by Donal K. Fellows
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include "tclInt.h"
+#include "tclOOInt.h"
+
+/*
+ * The maximum length of fully-qualified object name to use in an errorinfo
+ * message. Longer than this will be curtailed.
+ */
+
+#define OBJNAME_LENGTH_IN_ERRORINFO_LIMIT 30
+
+/*
+ * Some things that make it easier to declare a slot.
+ */
+
+struct DeclaredSlot {
+    const char *name;
+    const Tcl_MethodType getterType;
+    const Tcl_MethodType setterType;
+};
+
+#define SLOT(name,getter,setter)					\
+    {"::oo::" name,							\
+	    {TCL_OO_METHOD_VERSION_CURRENT, "core method: " name " Getter", \
+		    getter, NULL, NULL},				\
+	    {TCL_OO_METHOD_VERSION_CURRENT, "core method: " name " Setter", \
+		    setter, NULL, NULL}}
+
+/*
+ * Forward declarations.
+ */
+
+static inline void	BumpGlobalEpoch(Tcl_Interp *interp, Class *classPtr);
+static Tcl_Command	FindCommand(Tcl_Interp *interp, Tcl_Obj *stringObj,
+			    Tcl_Namespace *const namespacePtr);
+static void		GenerateErrorInfo(Tcl_Interp *interp, Object *oPtr,
+			    Tcl_Obj *savedNameObj, const char *typeOfSubject);
+static inline Class *	GetClassInOuterContext(Tcl_Interp *interp,
+			    Tcl_Obj *className, const char *errMsg);
+static inline int	InitDefineContext(Tcl_Interp *interp,
+			    Tcl_Namespace *namespacePtr, Object *oPtr,
+			    int objc, Tcl_Obj *const objv[]);
+static inline void	RecomputeClassCacheFlag(Object *oPtr);
+static int		RenameDeleteMethod(Tcl_Interp *interp, Object *oPtr,
+			    int useClass, Tcl_Obj *const fromPtr,
+			    Tcl_Obj *const toPtr);
+static int		ClassFilterGet(ClientData clientData,
+			    Tcl_Interp *interp, Tcl_ObjectContext context,
+			    int objc, Tcl_Obj *const *objv);
+static int		ClassFilterSet(ClientData clientData,
+			    Tcl_Interp *interp, Tcl_ObjectContext context,
+			    int objc, Tcl_Obj *const *objv);
+static int		ClassMixinGet(ClientData clientData,
+			    Tcl_Interp *interp, Tcl_ObjectContext context,
+			    int objc, Tcl_Obj *const *objv);
+static int		ClassMixinSet(ClientData clientData,
+			    Tcl_Interp *interp, Tcl_ObjectContext context,
+			    int objc, Tcl_Obj *const *objv);
+static int		ClassSuperGet(ClientData clientData,
+			    Tcl_Interp *interp, Tcl_ObjectContext context,
+			    int objc, Tcl_Obj *const *objv);
+static int		ClassSuperSet(ClientData clientData,
+			    Tcl_Interp *interp, Tcl_ObjectContext context,
+			    int objc, Tcl_Obj *const *objv);
+static int		ClassVarsGet(ClientData clientData,
+			    Tcl_Interp *interp, Tcl_ObjectContext context,
+			    int objc, Tcl_Obj *const *objv);
+static int		ClassVarsSet(ClientData clientData,
+			    Tcl_Interp *interp, Tcl_ObjectContext context,
+			    int objc, Tcl_Obj *const *objv);
+static int		ObjFilterGet(ClientData clientData,
+			    Tcl_Interp *interp, Tcl_ObjectContext context,
+			    int objc, Tcl_Obj *const *objv);
+static int		ObjFilterSet(ClientData clientData,
+			    Tcl_Interp *interp, Tcl_ObjectContext context,
+			    int objc, Tcl_Obj *const *objv);
+static int		ObjMixinGet(ClientData clientData,
+			    Tcl_Interp *interp, Tcl_ObjectContext context,
+			    int objc, Tcl_Obj *const *objv);
+static int		ObjMixinSet(ClientData clientData,
+			    Tcl_Interp *interp, Tcl_ObjectContext context,
+			    int objc, Tcl_Obj *const *objv);
+static int		ObjVarsGet(ClientData clientData,
+			    Tcl_Interp *interp, Tcl_ObjectContext context,
+			    int objc, Tcl_Obj *const *objv);
+static int		ObjVarsSet(ClientData clientData,
+			    Tcl_Interp *interp, Tcl_ObjectContext context,
+			    int objc, Tcl_Obj *const *objv);
+
+/*
+ * Now define the slots used in declarations.
+ */
+
+static const struct DeclaredSlot slots[] = {
+    SLOT("define::filter",      ClassFilterGet, ClassFilterSet),
+    SLOT("define::mixin",       ClassMixinGet,  ClassMixinSet),
+    SLOT("define::superclass",  ClassSuperGet,  ClassSuperSet),
+    SLOT("define::variable",    ClassVarsGet,   ClassVarsSet),
+    SLOT("objdefine::filter",   ObjFilterGet,   ObjFilterSet),
+    SLOT("objdefine::mixin",    ObjMixinGet,    ObjMixinSet),
+    SLOT("objdefine::variable", ObjVarsGet,     ObjVarsSet),
+    {NULL, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}}
+};
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * BumpGlobalEpoch --
+ *	Utility that ensures that call chains that are invalid will get thrown
+ *	away at an appropriate time. Note that exactly which epoch gets
+ *	advanced will depend on exactly what the class is tangled up in; in
+ *	the worst case, the simplest option is to advance the global epoch,
+ *	causing *everything* to be thrown away on next usage.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+static inline void
+BumpGlobalEpoch(
+    Tcl_Interp *interp,
+    Class *classPtr)
+{
+    if (classPtr != NULL
+	    && classPtr->subclasses.num == 0
+	    && classPtr->instances.num == 0
+	    && classPtr->mixinSubs.num == 0) {
+	/*
+	 * If a class has no subclasses or instances, and is not mixed into
+	 * anything, a change to its structure does not require us to
+	 * invalidate any call chains. Note that we still bump our object's
+	 * epoch if it has any mixins; the relation between a class and its
+	 * representative object is special. But it won't hurt.
+	 */
+
+	if (classPtr->thisPtr->mixins.num > 0) {
+	    classPtr->thisPtr->epoch++;
+	}
+	return;
+    }
+
+    /*
+     * Either there's no class (?!) or we're reconfiguring something that is
+     * in use. Force regeneration of call chains.
+     */
+
+    TclOOGetFoundation(interp)->epoch++;
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * RecomputeClassCacheFlag --
+ *	Determine whether the object is prototypical of its class, and hence
+ *	able to use the class's method chain cache.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+static inline void
+RecomputeClassCacheFlag(
+    Object *oPtr)
+{
+    if ((oPtr->methodsPtr == NULL || oPtr->methodsPtr->numEntries == 0)
+	    && (oPtr->mixins.num == 0) && (oPtr->filters.num == 0)) {
+	oPtr->flags |= USE_CLASS_CACHE;
+    } else {
+	oPtr->flags &= ~USE_CLASS_CACHE;
+    }
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * TclOOObjectSetFilters --
+ *	Install a list of filter method names into an object.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+void
+TclOOObjectSetFilters(
+    Object *oPtr,
+    int numFilters,
+    Tcl_Obj *const *filters)
+{
+    int i;
+
+    if (oPtr->filters.num) {
+	Tcl_Obj *filterObj;
+
+	FOREACH(filterObj, oPtr->filters) {
+	    Tcl_DecrRefCount(filterObj);
+	}
+    }
+
+    if (numFilters == 0) {
+	/*
+	 * No list of filters was supplied, so we're deleting filters.
+	 */
+
+	ckfree(oPtr->filters.list);
+	oPtr->filters.list = NULL;
+	oPtr->filters.num = 0;
+	RecomputeClassCacheFlag(oPtr);
+    } else {
+	/*
+	 * We've got a list of filters, so we're creating filters.
+	 */
+
+	Tcl_Obj **filtersList;
+	int size = sizeof(Tcl_Obj *) * numFilters;	/* should be size_t */
+
+	if (oPtr->filters.num == 0) {
+	    filtersList = ckalloc(size);
+	} else {
+	    filtersList = ckrealloc(oPtr->filters.list, size);
+	}
+	for (i=0 ; i<numFilters ; i++) {
+	    filtersList[i] = filters[i];
+	    Tcl_IncrRefCount(filters[i]);
+	}
+	oPtr->filters.list = filtersList;
+	oPtr->filters.num = numFilters;
+	oPtr->flags &= ~USE_CLASS_CACHE;
+    }
+    oPtr->epoch++;		/* Only this object can be affected. */
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * TclOOClassSetFilters --
+ *	Install a list of filter method names into a class.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+void
+TclOOClassSetFilters(
+    Tcl_Interp *interp,
+    Class *classPtr,
+    int numFilters,
+    Tcl_Obj *const *filters)
+{
+    int i;
+
+    if (classPtr->filters.num) {
+	Tcl_Obj *filterObj;
+
+	FOREACH(filterObj, classPtr->filters) {
+	    Tcl_DecrRefCount(filterObj);
+	}
+    }
+
+    if (numFilters == 0) {
+	/*
+	 * No list of filters was supplied, so we're deleting filters.
+	 */
+
+	ckfree(classPtr->filters.list);
+	classPtr->filters.list = NULL;
+	classPtr->filters.num = 0;
+    } else {
+	/*
+	 * We've got a list of filters, so we're creating filters.
+	 */
+
+	Tcl_Obj **filtersList;
+	int size = sizeof(Tcl_Obj *) * numFilters;	/* should be size_t */
+
+	if (classPtr->filters.num == 0) {
+	    filtersList = ckalloc(size);
+	} else {
+	    filtersList = ckrealloc(classPtr->filters.list, size);
+	}
+	for (i=0 ; i<numFilters ; i++) {
+	    filtersList[i] = filters[i];
+	    Tcl_IncrRefCount(filters[i]);
+	}
+	classPtr->filters.list = filtersList;
+	classPtr->filters.num = numFilters;
+    }
+
+    /*
+     * There may be many objects affected, so bump the global epoch.
+     */
+
+    BumpGlobalEpoch(interp, classPtr);
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * TclOOObjectSetMixins --
+ *	Install a list of mixin classes into an object.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+void
+TclOOObjectSetMixins(
+    Object *oPtr,
+    int numMixins,
+    Class *const *mixins)
+{
+    Class *mixinPtr;
+    int i;
+
+    if (numMixins == 0) {
+	if (oPtr->mixins.num != 0) {
+	    FOREACH(mixinPtr, oPtr->mixins) {
+		if (mixinPtr) {
+		    TclOORemoveFromInstances(oPtr, mixinPtr);
+		}
+	    }
+	    ckfree(oPtr->mixins.list);
+	    oPtr->mixins.num = 0;
+	}
+	RecomputeClassCacheFlag(oPtr);
+    } else {
+	if (oPtr->mixins.num != 0) {
+	    FOREACH(mixinPtr, oPtr->mixins) {
+		if (mixinPtr && mixinPtr != oPtr->selfCls) {
+		    TclOORemoveFromInstances(oPtr, mixinPtr);
+		}
+	    }
+	    oPtr->mixins.list = ckrealloc(oPtr->mixins.list,
+		    sizeof(Class *) * numMixins);
+	} else {
+	    oPtr->mixins.list = ckalloc(sizeof(Class *) * numMixins);
+	    oPtr->flags &= ~USE_CLASS_CACHE;
+	}
+	oPtr->mixins.num = numMixins;
+	memcpy(oPtr->mixins.list, mixins, sizeof(Class *) * numMixins);
+	FOREACH(mixinPtr, oPtr->mixins) {
+	    if (mixinPtr != oPtr->selfCls) {
+		TclOOAddToInstances(oPtr, mixinPtr);
+	    }
+	}
+    }
+    oPtr->epoch++;
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * TclOOClassSetMixins --
+ *	Install a list of mixin classes into a class.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+void
+TclOOClassSetMixins(
+    Tcl_Interp *interp,
+    Class *classPtr,
+    int numMixins,
+    Class *const *mixins)
+{
+    Class *mixinPtr;
+    int i;
+
+    if (numMixins == 0) {
+	if (classPtr->mixins.num != 0) {
+	    FOREACH(mixinPtr, classPtr->mixins) {
+		TclOORemoveFromMixinSubs(classPtr, mixinPtr);
+	    }
+	    ckfree(classPtr->mixins.list);
+	    classPtr->mixins.num = 0;
+	}
+    } else {
+	if (classPtr->mixins.num != 0) {
+	    FOREACH(mixinPtr, classPtr->mixins) {
+		TclOORemoveFromMixinSubs(classPtr, mixinPtr);
+	    }
+	    classPtr->mixins.list = ckrealloc(classPtr->mixins.list,
+		    sizeof(Class *) * numMixins);
+	} else {
+	    classPtr->mixins.list = ckalloc(sizeof(Class *) * numMixins);
+	}
+	classPtr->mixins.num = numMixins;
+	memcpy(classPtr->mixins.list, mixins, sizeof(Class *) * numMixins);
+	FOREACH(mixinPtr, classPtr->mixins) {
+	    TclOOAddToMixinSubs(classPtr, mixinPtr);
+	}
+    }
+    BumpGlobalEpoch(interp, classPtr);
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * RenameDeleteMethod --
+ *	Core of the code to rename and delete methods.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+static int
+RenameDeleteMethod(
+    Tcl_Interp *interp,
+    Object *oPtr,
+    int useClass,
+    Tcl_Obj *const fromPtr,
+    Tcl_Obj *const toPtr)
+{
+    Tcl_HashEntry *hPtr, *newHPtr = NULL;
+    Method *mPtr;
+    int isNew;
+
+    if (!useClass) {
+	if (!oPtr->methodsPtr) {
+	noSuchMethod:
+	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		    "method %s does not exist", TclGetString(fromPtr)));
+	    Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "METHOD",
+		    TclGetString(fromPtr), NULL);
+	    return TCL_ERROR;
+	}
+	hPtr = Tcl_FindHashEntry(oPtr->methodsPtr, (char *) fromPtr);
+	if (hPtr == NULL) {
+	    goto noSuchMethod;
+	}
+	if (toPtr) {
+	    newHPtr = Tcl_CreateHashEntry(oPtr->methodsPtr, (char *) toPtr,
+		    &isNew);
+	    if (hPtr == newHPtr) {
+	    renameToSelf:
+		Tcl_SetObjResult(interp, Tcl_NewStringObj(
+			"cannot rename method to itself", -1));
+		Tcl_SetErrorCode(interp, "TCL", "OO", "RENAME_TO_SELF", NULL);
+		return TCL_ERROR;
+	    } else if (!isNew) {
+	    renameToExisting:
+		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+			"method called %s already exists",
+			TclGetString(toPtr)));
+		Tcl_SetErrorCode(interp, "TCL", "OO", "RENAME_OVER", NULL);
+		return TCL_ERROR;
+	    }
+	}
+    } else {
+	hPtr = Tcl_FindHashEntry(&oPtr->classPtr->classMethods,
+		(char *) fromPtr);
+	if (hPtr == NULL) {
+	    goto noSuchMethod;
+	}
+	if (toPtr) {
+	    newHPtr = Tcl_CreateHashEntry(&oPtr->classPtr->classMethods,
+		    (char *) toPtr, &isNew);
+	    if (hPtr == newHPtr) {
+		goto renameToSelf;
+	    } else if (!isNew) {
+		goto renameToExisting;
+	    }
+	}
+    }
+
+    /*
+     * Complete the splicing by changing the method's name.
+     */
+
+    mPtr = Tcl_GetHashValue(hPtr);
+    if (toPtr) {
+	Tcl_IncrRefCount(toPtr);
+	Tcl_DecrRefCount(mPtr->namePtr);
+	mPtr->namePtr = toPtr;
+	Tcl_SetHashValue(newHPtr, mPtr);
+    } else {
+	if (!useClass) {
+	    RecomputeClassCacheFlag(oPtr);
+	}
+	TclOODelMethodRef(mPtr);
+    }
+    Tcl_DeleteHashEntry(hPtr);
+    return TCL_OK;
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * TclOOUnknownDefinition --
+ *	Handles what happens when an unknown command is encountered during the
+ *	processing of a definition script. Works by finding a command in the
+ *	operating definition namespace that the requested command is a unique
+ *	prefix of.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+int
+TclOOUnknownDefinition(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const *objv)
+{
+    Namespace *nsPtr = (Namespace *) Tcl_GetCurrentNamespace(interp);
+    Tcl_HashSearch search;
+    Tcl_HashEntry *hPtr;
+    int soughtLen;
+    const char *soughtStr, *matchedStr = NULL;
+
+    if (objc < 2) {
+	Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		"bad call of unknown handler", -1));
+	Tcl_SetErrorCode(interp, "TCL", "OO", "BAD_UNKNOWN", NULL);
+	return TCL_ERROR;
+    }
+    if (TclOOGetDefineCmdContext(interp) == NULL) {
+	return TCL_ERROR;
+    }
+
+    soughtStr = Tcl_GetStringFromObj(objv[1], &soughtLen);
+    if (soughtLen == 0) {
+	goto noMatch;
+    }
+    hPtr = Tcl_FirstHashEntry(&nsPtr->cmdTable, &search);
+    while (hPtr != NULL) {
+	const char *nameStr = Tcl_GetHashKey(&nsPtr->cmdTable, hPtr);
+
+	if (strncmp(soughtStr, nameStr, soughtLen) == 0) {
+	    if (matchedStr != NULL) {
+		goto noMatch;
+	    }
+	    matchedStr = nameStr;
+	}
+	hPtr = Tcl_NextHashEntry(&search);
+    }
+
+    if (matchedStr != NULL) {
+	/*
+	 * Got one match, and only one match!
+	 */
+
+	Tcl_Obj **newObjv = TclStackAlloc(interp, sizeof(Tcl_Obj*)*(objc-1));
+	int result;
+
+	newObjv[0] = Tcl_NewStringObj(matchedStr, -1);
+	Tcl_IncrRefCount(newObjv[0]);
+	if (objc > 2) {
+	    memcpy(newObjv+1, objv+2, sizeof(Tcl_Obj *) * (objc-2));
+	}
+	result = Tcl_EvalObjv(interp, objc-1, newObjv, 0);
+	Tcl_DecrRefCount(newObjv[0]);
+	TclStackFree(interp, newObjv);
+	return result;
+    }
+
+  noMatch:
+    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+	    "invalid command name \"%s\"", soughtStr));
+    Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "COMMAND", soughtStr, NULL);
+    return TCL_ERROR;
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * FindCommand --
+ *	Specialized version of Tcl_FindCommand that handles command prefixes
+ *	and disallows namespace magic.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+static Tcl_Command
+FindCommand(
+    Tcl_Interp *interp,
+    Tcl_Obj *stringObj,
+    Tcl_Namespace *const namespacePtr)
+{
+    int length;
+    const char *nameStr, *string = Tcl_GetStringFromObj(stringObj, &length);
+    register Namespace *const nsPtr = (Namespace *) namespacePtr;
+    FOREACH_HASH_DECLS;
+    Tcl_Command cmd, cmd2;
+
+    /*
+     * If someone is playing games, we stop playing right now.
+     */
+
+    if (string[0] == '\0' || strstr(string, "::") != NULL) {
+	return NULL;
+    }
+
+    /*
+     * Do the exact lookup first.
+     */
+
+    cmd = Tcl_FindCommand(interp, string, namespacePtr, TCL_NAMESPACE_ONLY);
+    if (cmd != NULL) {
+	return cmd;
+    }
+
+    /*
+     * Bother, need to perform an approximate match. Iterate across the hash
+     * table of commands in the namespace.
+     */
+
+    FOREACH_HASH(nameStr, cmd2, &nsPtr->cmdTable) {
+	if (strncmp(string, nameStr, length) == 0) {
+	    if (cmd != NULL) {
+		return NULL;
+	    }
+	    cmd = cmd2;
+	}
+    }
+
+    /*
+     * Either we found one thing or we found nothing. Either way, return it.
+     */
+
+    return cmd;
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * InitDefineContext --
+ *	Does the magic incantations necessary to push the special stack frame
+ *	used when processing object definitions. It is up to the caller to
+ *	dispose of the frame (with TclPopStackFrame) when finished.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+static inline int
+InitDefineContext(
+    Tcl_Interp *interp,
+    Tcl_Namespace *namespacePtr,
+    Object *oPtr,
+    int objc,
+    Tcl_Obj *const objv[])
+{
+    CallFrame *framePtr, **framePtrPtr = &framePtr;
+
+    if (namespacePtr == NULL) {
+	Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		"cannot process definitions; support namespace deleted",
+		-1));
+	Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", NULL);
+	return TCL_ERROR;
+    }
+
+    /* framePtrPtr is needed to satisfy GCC 3.3's strict aliasing rules */
+
+    (void) TclPushStackFrame(interp, (Tcl_CallFrame **) framePtrPtr,
+	    namespacePtr, FRAME_IS_OO_DEFINE);
+    framePtr->clientData = oPtr;
+    framePtr->objc = objc;
+    framePtr->objv = objv;	/* Reference counts do not need to be
+				 * incremented here. */
+    return TCL_OK;
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * TclOOGetDefineCmdContext --
+ *	Extracts the magic token from the current stack frame, or returns NULL
+ *	(and leaves an error message) otherwise.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+Tcl_Object
+TclOOGetDefineCmdContext(
+    Tcl_Interp *interp)
+{
+    Interp *iPtr = (Interp *) interp;
+    Tcl_Object object;
+
+    if ((iPtr->varFramePtr == NULL)
+	    || (iPtr->varFramePtr->isProcCallFrame != FRAME_IS_OO_DEFINE)) {
+	Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		"this command may only be called from within the context of"
+		" an ::oo::define or ::oo::objdefine command", -1));
+	Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", NULL);
+	return NULL;
+    }
+    object = iPtr->varFramePtr->clientData;
+    if (Tcl_ObjectDeleted(object)) {
+	Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		"this command cannot be called when the object has been"
+		" deleted", -1));
+	Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", NULL);
+	return NULL;
+    }
+    return object;
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * GetClassInOuterContext --
+ *	Wrapper round Tcl_GetObjectFromObj to perform the lookup in the
+ *	context that called oo::define (or equivalent). Note that this may
+ *	have to go up multiple levels to get the level that we started doing
+ *	definitions at.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+static inline Class *
+GetClassInOuterContext(
+    Tcl_Interp *interp,
+    Tcl_Obj *className,
+    const char *errMsg)
+{
+    Interp *iPtr = (Interp *) interp;
+    Object *oPtr;
+    CallFrame *savedFramePtr = iPtr->varFramePtr;
+
+    while (iPtr->varFramePtr->isProcCallFrame == FRAME_IS_OO_DEFINE) {
+	if (iPtr->varFramePtr->callerVarPtr == NULL) {
+	    Tcl_Panic("getting outer context when already in global context");
+	}
+	iPtr->varFramePtr = iPtr->varFramePtr->callerVarPtr;
+    }
+    oPtr = (Object *) Tcl_GetObjectFromObj(interp, className);
+    iPtr->varFramePtr = savedFramePtr;
+    if (oPtr == NULL) {
+	return NULL;
+    }
+    if (oPtr->classPtr == NULL) {
+	Tcl_SetObjResult(interp, Tcl_NewStringObj(errMsg, -1));
+	Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "CLASS",
+		TclGetString(className), NULL);
+	return NULL;
+    }
+    return oPtr->classPtr;
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * GenerateErrorInfo --
+ *	Factored out code to generate part of the error trace messages.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+static void
+GenerateErrorInfo(
+    Tcl_Interp *interp,		/* Where to store the error info trace. */
+    Object *oPtr,		/* What object (or class) was being configured
+				 * when the error occurred? */
+    Tcl_Obj *savedNameObj,	/* Name of object saved from before script was
+				 * evaluated, which is needed if the object
+				 * goes away part way through execution. OTOH,
+				 * if the object isn't deleted then its
+				 * current name (post-execution) has to be
+				 * used. This matters, because the object
+				 * could have been renamed... */
+    const char *typeOfSubject)	/* Part of the message, saying whether it was
+				 * an object, class or class-as-object that
+				 * was being configured. */
+{
+    int length;
+    Tcl_Obj *realNameObj = Tcl_ObjectDeleted((Tcl_Object) oPtr)
+	    ? savedNameObj : TclOOObjectName(interp, oPtr);
+    const char *objName = Tcl_GetStringFromObj(realNameObj, &length);
+    int limit = OBJNAME_LENGTH_IN_ERRORINFO_LIMIT;
+    int overflow = (length > limit);
+
+    Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf(
+	    "\n    (in definition script for %s \"%.*s%s\" line %d)",
+	    typeOfSubject, (overflow ? limit : length), objName,
+	    (overflow ? "..." : ""), Tcl_GetErrorLine(interp)));
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * TclOODefineObjCmd --
+ *	Implementation of the "oo::define" command. Works by effectively doing
+ *	the same as 'namespace eval', but with extra magic applied so that the
+ *	object to be modified is known to the commands in the target
+ *	namespace. Also does ensemble-like tricks with dispatch so that error
+ *	messages are clearer.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+int
+TclOODefineObjCmd(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const *objv)
+{
+    Foundation *fPtr = TclOOGetFoundation(interp);
+    int result;
+    Object *oPtr;
+
+    if (objc < 3) {
+	Tcl_WrongNumArgs(interp, 1, objv, "className arg ?arg ...?");
+	return TCL_ERROR;
+    }
+
+    oPtr = (Object *) Tcl_GetObjectFromObj(interp, objv[1]);
+    if (oPtr == NULL) {
+	return TCL_ERROR;
+    }
+    if (oPtr->classPtr == NULL) {
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		"%s does not refer to a class",TclGetString(objv[1])));
+	Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "CLASS",
+		TclGetString(objv[1]), NULL);
+	return TCL_ERROR;
+    }
+
+    /*
+     * Make the oo::define namespace the current namespace and evaluate the
+     * command(s).
+     */
+
+    if (InitDefineContext(interp, fPtr->defineNs, oPtr, objc,objv) != TCL_OK){
+	return TCL_ERROR;
+    }
+
+    AddRef(oPtr);
+    if (objc == 3) {
+	Tcl_Obj *objNameObj = TclOOObjectName(interp, oPtr);
+
+	Tcl_IncrRefCount(objNameObj);
+	result = TclEvalObjEx(interp, objv[2], 0,
+		((Interp *)interp)->cmdFramePtr, 2);
+	if (result == TCL_ERROR) {
+	    GenerateErrorInfo(interp, oPtr, objNameObj, "class");
+	}
+	TclDecrRefCount(objNameObj);
+    } else {
+	Tcl_Obj *objPtr, *obj2Ptr, **objs;
+	Tcl_Command cmd;
+	int isRoot, dummy;
+
+	/*
+	 * More than one argument: fire them through the ensemble processing
+	 * engine so that everything appears to be good and proper in error
+	 * messages. Note that we cannot just concatenate and send through
+	 * Tcl_EvalObjEx, as that doesn't do ensemble processing, and we
+	 * cannot go through Tcl_EvalObjv without the extra work to pre-find
+	 * the command, as that finds command names in the wrong namespace at
+	 * the moment. Ugly!
+	 */
+
+	isRoot = TclInitRewriteEnsemble(interp, 3, 1, objv);
+
+	/*
+	 * Build the list of arguments using a Tcl_Obj as a workspace. See
+	 * comments above for why these contortions are necessary.
+	 */
+
+	objPtr = Tcl_NewObj();
+	obj2Ptr = Tcl_NewObj();
+	cmd = FindCommand(interp, objv[2], fPtr->defineNs);
+	if (cmd == NULL) {
+	    /* punt this case! */
+	    Tcl_AppendObjToObj(obj2Ptr, objv[2]);
+	} else {
+	    Tcl_GetCommandFullName(interp, cmd, obj2Ptr);
+	}
+	Tcl_ListObjAppendElement(NULL, objPtr, obj2Ptr);
+	/* TODO: overflow? */
+	Tcl_ListObjReplace(NULL, objPtr, 1, 0, objc-3, objv+3);
+	Tcl_ListObjGetElements(NULL, objPtr, &dummy, &objs);
+
+	result = Tcl_EvalObjv(interp, objc-2, objs, TCL_EVAL_INVOKE);
+	if (isRoot) {
+	    TclResetRewriteEnsemble(interp, 1);
+	}
+	Tcl_DecrRefCount(objPtr);
+    }
+    DelRef(oPtr);
+
+    /*
+     * Restore the previous "current" namespace.
+     */
+
+    TclPopStackFrame(interp);
+    return result;
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * TclOOObjDefObjCmd --
+ *	Implementation of the "oo::objdefine" command. Works by effectively
+ *	doing the same as 'namespace eval', but with extra magic applied so
+ *	that the object to be modified is known to the commands in the target
+ *	namespace. Also does ensemble-like tricks with dispatch so that error
+ *	messages are clearer.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+int
+TclOOObjDefObjCmd(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const *objv)
+{
+    Foundation *fPtr = TclOOGetFoundation(interp);
+    int isRoot, result;
+    Object *oPtr;
+
+    if (objc < 3) {
+	Tcl_WrongNumArgs(interp, 1, objv, "objectName arg ?arg ...?");
+	return TCL_ERROR;
+    }
+
+    oPtr = (Object *) Tcl_GetObjectFromObj(interp, objv[1]);
+    if (oPtr == NULL) {
+	return TCL_ERROR;
+    }
+
+    /*
+     * Make the oo::objdefine namespace the current namespace and evaluate the
+     * command(s).
+     */
+
+    if (InitDefineContext(interp, fPtr->objdefNs, oPtr, objc,objv) != TCL_OK){
+	return TCL_ERROR;
+    }
+
+    AddRef(oPtr);
+    if (objc == 3) {
+	Tcl_Obj *objNameObj = TclOOObjectName(interp, oPtr);
+
+	Tcl_IncrRefCount(objNameObj);
+	result = TclEvalObjEx(interp, objv[2], 0,
+		((Interp *)interp)->cmdFramePtr, 2);
+	if (result == TCL_ERROR) {
+	    GenerateErrorInfo(interp, oPtr, objNameObj, "object");
+	}
+	TclDecrRefCount(objNameObj);
+    } else {
+	Tcl_Obj *objPtr, *obj2Ptr, **objs;
+	Tcl_Command cmd;
+	int dummy;
+
+	/*
+	 * More than one argument: fire them through the ensemble processing
+	 * engine so that everything appears to be good and proper in error
+	 * messages. Note that we cannot just concatenate and send through
+	 * Tcl_EvalObjEx, as that doesn't do ensemble processing, and we
+	 * cannot go through Tcl_EvalObjv without the extra work to pre-find
+	 * the command, as that finds command names in the wrong namespace at
+	 * the moment. Ugly!
+	 */
+
+	isRoot = TclInitRewriteEnsemble(interp, 3, 1, objv);
+
+	/*
+	 * Build the list of arguments using a Tcl_Obj as a workspace. See
+	 * comments above for why these contortions are necessary.
+	 */
+
+	objPtr = Tcl_NewObj();
+	obj2Ptr = Tcl_NewObj();
+	cmd = FindCommand(interp, objv[2], fPtr->objdefNs);
+	if (cmd == NULL) {
+	    /* punt this case! */
+	    Tcl_AppendObjToObj(obj2Ptr, objv[2]);
+	} else {
+	    Tcl_GetCommandFullName(interp, cmd, obj2Ptr);
+	}
+	Tcl_ListObjAppendElement(NULL, objPtr, obj2Ptr);
+	/* TODO: overflow? */
+	Tcl_ListObjReplace(NULL, objPtr, 1, 0, objc-3, objv+3);
+	Tcl_ListObjGetElements(NULL, objPtr, &dummy, &objs);
+
+	result = Tcl_EvalObjv(interp, objc-2, objs, TCL_EVAL_INVOKE);
+
+	if (isRoot) {
+	    TclResetRewriteEnsemble(interp, 1);
+	}
+	Tcl_DecrRefCount(objPtr);
+    }
+    DelRef(oPtr);
+
+    /*
+     * Restore the previous "current" namespace.
+     */
+
+    TclPopStackFrame(interp);
+    return result;
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * TclOODefineSelfObjCmd --
+ *	Implementation of the "self" subcommand of the "oo::define" command.
+ *	Works by effectively doing the same as 'namespace eval', but with
+ *	extra magic applied so that the object to be modified is known to the
+ *	commands in the target namespace. Also does ensemble-like tricks with
+ *	dispatch so that error messages are clearer.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+int
+TclOODefineSelfObjCmd(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const *objv)
+{
+    Foundation *fPtr = TclOOGetFoundation(interp);
+    int result;
+    Object *oPtr;
+
+    if (objc < 2) {
+	Tcl_WrongNumArgs(interp, 1, objv, "arg ?arg ...?");
+	return TCL_ERROR;
+    }
+
+    oPtr = (Object *) TclOOGetDefineCmdContext(interp);
+    if (oPtr == NULL) {
+	return TCL_ERROR;
+    }
+
+    /*
+     * Make the oo::objdefine namespace the current namespace and evaluate the
+     * command(s).
+     */
+
+    if (InitDefineContext(interp, fPtr->objdefNs, oPtr, objc,objv) != TCL_OK){
+	return TCL_ERROR;
+    }
+
+    AddRef(oPtr);
+    if (objc == 2) {
+	Tcl_Obj *objNameObj = TclOOObjectName(interp, oPtr);
+
+	Tcl_IncrRefCount(objNameObj);
+	result = TclEvalObjEx(interp, objv[1], 0,
+		((Interp *)interp)->cmdFramePtr, 2);
+	if (result == TCL_ERROR) {
+	    GenerateErrorInfo(interp, oPtr, objNameObj, "class object");
+	}
+	TclDecrRefCount(objNameObj);
+    } else {
+	Tcl_Obj *objPtr, *obj2Ptr, **objs;
+	Tcl_Command cmd;
+	int isRoot, dummy;
+
+	/*
+	 * More than one argument: fire them through the ensemble processing
+	 * engine so that everything appears to be good and proper in error
+	 * messages. Note that we cannot just concatenate and send through
+	 * Tcl_EvalObjEx, as that doesn't do ensemble processing, and we
+	 * cannot go through Tcl_EvalObjv without the extra work to pre-find
+	 * the command, as that finds command names in the wrong namespace at
+	 * the moment. Ugly!
+	 */
+
+	isRoot = TclInitRewriteEnsemble(interp, 2, 1, objv);
+
+	/*
+	 * Build the list of arguments using a Tcl_Obj as a workspace. See
+	 * comments above for why these contortions are necessary.
+	 */
+
+	objPtr = Tcl_NewObj();
+	obj2Ptr = Tcl_NewObj();
+	cmd = FindCommand(interp, objv[1], fPtr->objdefNs);
+	if (cmd == NULL) {
+	    /* punt this case! */
+	    Tcl_AppendObjToObj(obj2Ptr, objv[1]);
+	} else {
+	    Tcl_GetCommandFullName(interp, cmd, obj2Ptr);
+	}
+	Tcl_ListObjAppendElement(NULL, objPtr, obj2Ptr);
+	/* TODO: overflow? */
+	Tcl_ListObjReplace(NULL, objPtr, 1, 0, objc-2, objv+2);
+	Tcl_ListObjGetElements(NULL, objPtr, &dummy, &objs);
+
+	result = Tcl_EvalObjv(interp, objc-1, objs, TCL_EVAL_INVOKE);
+	if (isRoot) {
+	    TclResetRewriteEnsemble(interp, 1);
+	}
+	Tcl_DecrRefCount(objPtr);
+    }
+    DelRef(oPtr);
+
+    /*
+     * Restore the previous "current" namespace.
+     */
+
+    TclPopStackFrame(interp);
+    return result;
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * TclOODefineClassObjCmd --
+ *	Implementation of the "class" subcommand of the "oo::objdefine"
+ *	command.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+int
+TclOODefineClassObjCmd(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const *objv)
+{
+    Object *oPtr;
+    Class *clsPtr;
+    Foundation *fPtr = TclOOGetFoundation(interp);
+
+    /*
+     * Parse the context to get the object to operate on.
+     */
+
+    oPtr = (Object *) TclOOGetDefineCmdContext(interp);
+    if (oPtr == NULL) {
+	return TCL_ERROR;
+    }
+    if (oPtr->flags & ROOT_OBJECT) {
+	Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		"may not modify the class of the root object class", -1));
+	Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", NULL);
+	return TCL_ERROR;
+    }
+    if (oPtr->flags & ROOT_CLASS) {
+	Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		"may not modify the class of the class of classes", -1));
+	Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", NULL);
+	return TCL_ERROR;
+    }
+
+    /*
+     * Parse the argument to get the class to set the object's class to.
+     */
+
+    if (objc != 2) {
+	Tcl_WrongNumArgs(interp, 1, objv, "className");
+	return TCL_ERROR;
+    }
+    clsPtr = GetClassInOuterContext(interp, objv[1],
+	    "the class of an object must be a class");
+    if (clsPtr == NULL) {
+	return TCL_ERROR;
+    }
+
+    /*
+     * Apply semantic checks. In particular, classes and non-classes are not
+     * interchangable (too complicated to do the conversion!) so we must
+     * produce an error if any attempt is made to swap from one to the other.
+     */
+
+    if ((oPtr->classPtr==NULL) == TclOOIsReachable(fPtr->classCls, clsPtr)) {
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		"may not change a %sclass object into a %sclass object",
+		(oPtr->classPtr==NULL ? "non-" : ""),
+		(oPtr->classPtr==NULL ? "" : "non-")));
+	Tcl_SetErrorCode(interp, "TCL", "OO", "TRANSMUTATION", NULL);
+	return TCL_ERROR;
+    }
+
+    /*
+     * Set the object's class.
+     */
+
+    if (oPtr->selfCls != clsPtr) {
+	TclOORemoveFromInstances(oPtr, oPtr->selfCls);
+	oPtr->selfCls = clsPtr;
+	TclOOAddToInstances(oPtr, oPtr->selfCls);
+	if (!(clsPtr->thisPtr->flags & OBJECT_DELETED)) {
+	    oPtr->flags &= ~CLASS_GONE;
+	}
+	if (oPtr->classPtr != NULL) {
+	    BumpGlobalEpoch(interp, oPtr->classPtr);
+	} else {
+	    oPtr->epoch++;
+	}
+    }
+    return TCL_OK;
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * TclOODefineConstructorObjCmd --
+ *	Implementation of the "constructor" subcommand of the "oo::define"
+ *	command.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+int
+TclOODefineConstructorObjCmd(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const *objv)
+{
+    Object *oPtr;
+    Class *clsPtr;
+    Tcl_Method method;
+    int bodyLength;
+
+    if (objc != 3) {
+	Tcl_WrongNumArgs(interp, 1, objv, "arguments body");
+	return TCL_ERROR;
+    }
+
+    /*
+     * Extract and validate the context, which is the class that we wish to
+     * modify.
+     */
+
+    oPtr = (Object *) TclOOGetDefineCmdContext(interp);
+    if (oPtr == NULL) {
+	return TCL_ERROR;
+    }
+    clsPtr = oPtr->classPtr;
+
+    Tcl_GetStringFromObj(objv[2], &bodyLength);
+    if (bodyLength > 0) {
+	/*
+	 * Create the method structure.
+	 */
+
+	method = (Tcl_Method) TclOONewProcMethod(interp, clsPtr,
+		PUBLIC_METHOD, NULL, objv[1], objv[2], NULL);
+	if (method == NULL) {
+	    return TCL_ERROR;
+	}
+    } else {
+	/*
+	 * Delete the constructor method record and set the field in the
+	 * class record to NULL.
+	 */
+
+	method = NULL;
+    }
+
+    /*
+     * Place the method structure in the class record. Note that we might not
+     * immediately delete the constructor as this might be being done during
+     * execution of the constructor itself.
+     */
+
+    Tcl_ClassSetConstructor(interp, (Tcl_Class) clsPtr, method);
+    return TCL_OK;
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * TclOODefineDeleteMethodObjCmd --
+ *	Implementation of the "deletemethod" subcommand of the "oo::define"
+ *	and "oo::objdefine" commands.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+int
+TclOODefineDeleteMethodObjCmd(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const *objv)
+{
+    int isInstanceDeleteMethod = (clientData != NULL);
+    Object *oPtr;
+    int i;
+
+    if (objc < 2) {
+	Tcl_WrongNumArgs(interp, 1, objv, "name ?name ...?");
+	return TCL_ERROR;
+    }
+
+    oPtr = (Object *) TclOOGetDefineCmdContext(interp);
+    if (oPtr == NULL) {
+	return TCL_ERROR;
+    }
+    if (!isInstanceDeleteMethod && !oPtr->classPtr) {
+	Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		"attempt to misuse API", -1));
+	Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", NULL);
+	return TCL_ERROR;
+    }
+
+    for (i=1 ; i<objc ; i++) {
+	/*
+	 * Delete the method structure from the appropriate hash table.
+	 */
+
+	if (RenameDeleteMethod(interp, oPtr, !isInstanceDeleteMethod,
+		objv[i], NULL) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+    }
+
+    if (isInstanceDeleteMethod) {
+	oPtr->epoch++;
+    } else {
+	BumpGlobalEpoch(interp, oPtr->classPtr);
+    }
+    return TCL_OK;
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * TclOODefineDestructorObjCmd --
+ *	Implementation of the "destructor" subcommand of the "oo::define"
+ *	command.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+int
+TclOODefineDestructorObjCmd(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const *objv)
+{
+    Object *oPtr;
+    Class *clsPtr;
+    Tcl_Method method;
+    int bodyLength;
+
+    if (objc != 2) {
+	Tcl_WrongNumArgs(interp, 1, objv, "body");
+	return TCL_ERROR;
+    }
+
+    oPtr = (Object *) TclOOGetDefineCmdContext(interp);
+    if (oPtr == NULL) {
+	return TCL_ERROR;
+    }
+    clsPtr = oPtr->classPtr;
+
+    Tcl_GetStringFromObj(objv[1], &bodyLength);
+    if (bodyLength > 0) {
+	/*
+	 * Create the method structure.
+	 */
+
+	method = (Tcl_Method) TclOONewProcMethod(interp, clsPtr,
+		PUBLIC_METHOD, NULL, NULL, objv[1], NULL);
+	if (method == NULL) {
+	    return TCL_ERROR;
+	}
+    } else {
+	/*
+	 * Delete the destructor method record and set the field in the class
+	 * record to NULL.
+	 */
+
+	method = NULL;
+    }
+
+    /*
+     * Place the method structure in the class record. Note that we might not
+     * immediately delete the destructor as this might be being done during
+     * execution of the destructor itself. Also note that setting a
+     * destructor during a destructor is fairly dumb anyway.
+     */
+
+    Tcl_ClassSetDestructor(interp, (Tcl_Class) clsPtr, method);
+    return TCL_OK;
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * TclOODefineExportObjCmd --
+ *	Implementation of the "export" subcommand of the "oo::define" and
+ *	"oo::objdefine" commands.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+int
+TclOODefineExportObjCmd(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const *objv)
+{
+    int isInstanceExport = (clientData != NULL);
+    Object *oPtr;
+    Method *mPtr;
+    Tcl_HashEntry *hPtr;
+    Class *clsPtr;
+    int i, isNew, changed = 0;
+
+    if (objc < 2) {
+	Tcl_WrongNumArgs(interp, 1, objv, "name ?name ...?");
+	return TCL_ERROR;
+    }
+
+    oPtr = (Object *) TclOOGetDefineCmdContext(interp);
+    if (oPtr == NULL) {
+	return TCL_ERROR;
+    }
+    clsPtr = oPtr->classPtr;
+    if (!isInstanceExport && !clsPtr) {
+	Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		"attempt to misuse API", -1));
+	Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", NULL);
+	return TCL_ERROR;
+    }
+
+    for (i=1 ; i<objc ; i++) {
+	/*
+	 * Exporting is done by adding the PUBLIC_METHOD flag to the method
+	 * record. If there is no such method in this object or class (i.e.
+	 * the method comes from something inherited from or that we're an
+	 * instance of) then we put in a blank record with that flag; such
+	 * records are skipped over by the call chain engine *except* for
+	 * their flags member.
+	 */
+
+	if (isInstanceExport) {
+	    if (!oPtr->methodsPtr) {
+		oPtr->methodsPtr = ckalloc(sizeof(Tcl_HashTable));
+		Tcl_InitObjHashTable(oPtr->methodsPtr);
+		oPtr->flags &= ~USE_CLASS_CACHE;
+	    }
+	    hPtr = Tcl_CreateHashEntry(oPtr->methodsPtr, (char *) objv[i],
+		    &isNew);
+	} else {
+	    hPtr = Tcl_CreateHashEntry(&clsPtr->classMethods, (char*) objv[i],
+		    &isNew);
+	}
+
+	if (isNew) {
+	    mPtr = ckalloc(sizeof(Method));
+	    memset(mPtr, 0, sizeof(Method));
+	    mPtr->refCount = 1;
+	    mPtr->namePtr = objv[i];
+	    Tcl_IncrRefCount(objv[i]);
+	    Tcl_SetHashValue(hPtr, mPtr);
+	} else {
+	    mPtr = Tcl_GetHashValue(hPtr);
+	}
+	if (isNew || !(mPtr->flags & PUBLIC_METHOD)) {
+	    mPtr->flags |= PUBLIC_METHOD;
+	    changed = 1;
+	}
+    }
+
+    /*
+     * Bump the right epoch if we actually changed anything.
+     */
+
+    if (changed) {
+	if (isInstanceExport) {
+	    oPtr->epoch++;
+	} else {
+	    BumpGlobalEpoch(interp, clsPtr);
+	}
+    }
+    return TCL_OK;
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * TclOODefineForwardObjCmd --
+ *	Implementation of the "forward" subcommand of the "oo::define" and
+ *	"oo::objdefine" commands.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+int
+TclOODefineForwardObjCmd(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const *objv)
+{
+    int isInstanceForward = (clientData != NULL);
+    Object *oPtr;
+    Method *mPtr;
+    int isPublic;
+    Tcl_Obj *prefixObj;
+
+    if (objc < 3) {
+	Tcl_WrongNumArgs(interp, 1, objv, "name cmdName ?arg ...?");
+	return TCL_ERROR;
+    }
+
+    oPtr = (Object *) TclOOGetDefineCmdContext(interp);
+    if (oPtr == NULL) {
+	return TCL_ERROR;
+    }
+    if (!isInstanceForward && !oPtr->classPtr) {
+	Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		"attempt to misuse API", -1));
+	Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", NULL);
+	return TCL_ERROR;
+    }
+    isPublic = Tcl_StringMatch(TclGetString(objv[1]), "[a-z]*")
+	    ? PUBLIC_METHOD : 0;
+
+    /*
+     * Create the method structure.
+     */
+
+    prefixObj = Tcl_NewListObj(objc-2, objv+2);
+    if (isInstanceForward) {
+	mPtr = TclOONewForwardInstanceMethod(interp, oPtr, isPublic, objv[1],
+		prefixObj);
+    } else {
+	mPtr = TclOONewForwardMethod(interp, oPtr->classPtr, isPublic,
+		objv[1], prefixObj);
+    }
+    if (mPtr == NULL) {
+	Tcl_DecrRefCount(prefixObj);
+	return TCL_ERROR;
+    }
+    return TCL_OK;
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * TclOODefineMethodObjCmd --
+ *	Implementation of the "method" subcommand of the "oo::define" and
+ *	"oo::objdefine" commands.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+int
+TclOODefineMethodObjCmd(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const *objv)
+{
+    int isInstanceMethod = (clientData != NULL);
+    Object *oPtr;
+    int isPublic;
+
+    if (objc != 4) {
+	Tcl_WrongNumArgs(interp, 1, objv, "name args body");
+	return TCL_ERROR;
+    }
+
+    oPtr = (Object *) TclOOGetDefineCmdContext(interp);
+    if (oPtr == NULL) {
+	return TCL_ERROR;
+    }
+    if (!isInstanceMethod && !oPtr->classPtr) {
+	Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		"attempt to misuse API", -1));
+	Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", NULL);
+	return TCL_ERROR;
+    }
+    isPublic = Tcl_StringMatch(TclGetString(objv[1]), "[a-z]*")
+	    ? PUBLIC_METHOD : 0;
+
+    /*
+     * Create the method by using the right back-end API.
+     */
+
+    if (isInstanceMethod) {
+	if (TclOONewProcInstanceMethod(interp, oPtr, isPublic, objv[1],
+		objv[2], objv[3], NULL) == NULL) {
+	    return TCL_ERROR;
+	}
+    } else {
+	if (TclOONewProcMethod(interp, oPtr->classPtr, isPublic, objv[1],
+		objv[2], objv[3], NULL) == NULL) {
+	    return TCL_ERROR;
+	}
+    }
+    return TCL_OK;
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * TclOODefineMixinObjCmd --
+ *	Implementation of the "mixin" subcommand of the "oo::define" and
+ *	"oo::objdefine" commands.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+int
+TclOODefineMixinObjCmd(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    const int objc,
+    Tcl_Obj *const *objv)
+{
+    int isInstanceMixin = (clientData != NULL);
+    Object *oPtr = (Object *) TclOOGetDefineCmdContext(interp);
+    Class **mixins;
+    int i;
+
+    if (oPtr == NULL) {
+	return TCL_ERROR;
+    }
+    if (!isInstanceMixin && !oPtr->classPtr) {
+	Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		"attempt to misuse API", -1));
+	Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", NULL);
+	return TCL_ERROR;
+    }
+    mixins = TclStackAlloc(interp, sizeof(Class *) * (objc-1));
+
+    for (i=1 ; i<objc ; i++) {
+	Class *clsPtr = GetClassInOuterContext(interp, objv[i],
+		"may only mix in classes");
+
+	if (clsPtr == NULL) {
+	    goto freeAndError;
+	}
+	if (!isInstanceMixin && TclOOIsReachable(oPtr->classPtr, clsPtr)) {
+	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		    "may not mix a class into itself", -1));
+	    Tcl_SetErrorCode(interp, "TCL", "OO", "SELF_MIXIN", NULL);
+	    goto freeAndError;
+	}
+	mixins[i-1] = clsPtr;
+    }
+
+    if (isInstanceMixin) {
+	TclOOObjectSetMixins(oPtr, objc-1, mixins);
+    } else {
+	TclOOClassSetMixins(interp, oPtr->classPtr, objc-1, mixins);
+    }
+
+    TclStackFree(interp, mixins);
+    return TCL_OK;
+
+  freeAndError:
+    TclStackFree(interp, mixins);
+    return TCL_ERROR;
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * TclOODefineRenameMethodObjCmd --
+ *	Implementation of the "renamemethod" subcommand of the "oo::define"
+ *	and "oo::objdefine" commands.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+int
+TclOODefineRenameMethodObjCmd(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const *objv)
+{
+    int isInstanceRenameMethod = (clientData != NULL);
+    Object *oPtr;
+
+    if (objc != 3) {
+	Tcl_WrongNumArgs(interp, 1, objv, "oldName newName");
+	return TCL_ERROR;
+    }
+
+    oPtr = (Object *) TclOOGetDefineCmdContext(interp);
+    if (oPtr == NULL) {
+	return TCL_ERROR;
+    }
+    if (!isInstanceRenameMethod && !oPtr->classPtr) {
+	Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		"attempt to misuse API", -1));
+	Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", NULL);
+	return TCL_ERROR;
+    }
+
+    /*
+     * Delete the method entry from the appropriate hash table, and transfer
+     * the thing it points to to its new entry. To do this, we first need to
+     * get the entries from the appropriate hash tables (this can generate a
+     * range of errors...)
+     */
+
+    if (RenameDeleteMethod(interp, oPtr, !isInstanceRenameMethod,
+	    objv[1], objv[2]) != TCL_OK) {
+	return TCL_ERROR;
+    }
+
+    if (isInstanceRenameMethod) {
+	oPtr->epoch++;
+    } else {
+	BumpGlobalEpoch(interp, oPtr->classPtr);
+    }
+    return TCL_OK;
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * TclOODefineUnexportObjCmd --
+ *	Implementation of the "unexport" subcommand of the "oo::define" and
+ *	"oo::objdefine" commands.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+int
+TclOODefineUnexportObjCmd(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const *objv)
+{
+    int isInstanceUnexport = (clientData != NULL);
+    Object *oPtr;
+    Method *mPtr;
+    Tcl_HashEntry *hPtr;
+    Class *clsPtr;
+    int i, isNew, changed = 0;
+
+    if (objc < 2) {
+	Tcl_WrongNumArgs(interp, 1, objv, "name ?name ...?");
+	return TCL_ERROR;
+    }
+
+    oPtr = (Object *) TclOOGetDefineCmdContext(interp);
+    if (oPtr == NULL) {
+	return TCL_ERROR;
+    }
+    clsPtr = oPtr->classPtr;
+    if (!isInstanceUnexport && !clsPtr) {
+	Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		"attempt to misuse API", -1));
+	Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", NULL);
+	return TCL_ERROR;
+    }
+
+    for (i=1 ; i<objc ; i++) {
+	/*
+	 * Unexporting is done by removing the PUBLIC_METHOD flag from the
+	 * method record. If there is no such method in this object or class
+	 * (i.e. the method comes from something inherited from or that we're
+	 * an instance of) then we put in a blank record without that flag;
+	 * such records are skipped over by the call chain engine *except* for
+	 * their flags member.
+	 */
+
+	if (isInstanceUnexport) {
+	    if (!oPtr->methodsPtr) {
+		oPtr->methodsPtr = ckalloc(sizeof(Tcl_HashTable));
+		Tcl_InitObjHashTable(oPtr->methodsPtr);
+		oPtr->flags &= ~USE_CLASS_CACHE;
+	    }
+	    hPtr = Tcl_CreateHashEntry(oPtr->methodsPtr, (char *) objv[i],
+		    &isNew);
+	} else {
+	    hPtr = Tcl_CreateHashEntry(&clsPtr->classMethods, (char*) objv[i],
+		    &isNew);
+	}
+
+	if (isNew) {
+	    mPtr = ckalloc(sizeof(Method));
+	    memset(mPtr, 0, sizeof(Method));
+	    mPtr->refCount = 1;
+	    mPtr->namePtr = objv[i];
+	    Tcl_IncrRefCount(objv[i]);
+	    Tcl_SetHashValue(hPtr, mPtr);
+	} else {
+	    mPtr = Tcl_GetHashValue(hPtr);
+	}
+	if (isNew || mPtr->flags & PUBLIC_METHOD) {
+	    mPtr->flags &= ~PUBLIC_METHOD;
+	    changed = 1;
+	}
+    }
+
+    /*
+     * Bump the right epoch if we actually changed anything.
+     */
+
+    if (changed) {
+	if (isInstanceUnexport) {
+	    oPtr->epoch++;
+	} else {
+	    BumpGlobalEpoch(interp, clsPtr);
+	}
+    }
+    return TCL_OK;
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * Tcl_ClassSetConstructor, Tcl_ClassSetDestructor --
+ *	How to install a constructor or destructor into a class; API to call
+ *	from C.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+void
+Tcl_ClassSetConstructor(
+    Tcl_Interp *interp,
+    Tcl_Class clazz,
+    Tcl_Method method)
+{
+    Class *clsPtr = (Class *) clazz;
+
+    if (method != (Tcl_Method) clsPtr->constructorPtr) {
+	TclOODelMethodRef(clsPtr->constructorPtr);
+	clsPtr->constructorPtr = (Method *) method;
+
+	/*
+	 * Remember to invalidate the cached constructor chain for this class.
+	 * [Bug 2531577]
+	 */
+
+	if (clsPtr->constructorChainPtr) {
+	    TclOODeleteChain(clsPtr->constructorChainPtr);
+	    clsPtr->constructorChainPtr = NULL;
+	}
+	BumpGlobalEpoch(interp, clsPtr);
+    }
+}
+
+void
+Tcl_ClassSetDestructor(
+    Tcl_Interp *interp,
+    Tcl_Class clazz,
+    Tcl_Method method)
+{
+    Class *clsPtr = (Class *) clazz;
+
+    if (method != (Tcl_Method) clsPtr->destructorPtr) {
+	TclOODelMethodRef(clsPtr->destructorPtr);
+	clsPtr->destructorPtr = (Method *) method;
+	if (clsPtr->destructorChainPtr) {
+	    TclOODeleteChain(clsPtr->destructorChainPtr);
+	    clsPtr->destructorChainPtr = NULL;
+	}
+	BumpGlobalEpoch(interp, clsPtr);
+    }
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * TclOODefineSlots --
+ *	Create the "::oo::Slot" class and its standard instances. Class
+ *	definition is empty at the stage (added by scripting).
+ *
+ * ----------------------------------------------------------------------
+ */
+
+int
+TclOODefineSlots(
+    Foundation *fPtr)
+{
+    const struct DeclaredSlot *slotInfoPtr;
+    Tcl_Obj *getName = Tcl_NewStringObj("Get", -1);
+    Tcl_Obj *setName = Tcl_NewStringObj("Set", -1);
+    Class *slotCls;
+
+    slotCls = ((Object *) Tcl_NewObjectInstance(fPtr->interp, (Tcl_Class)
+	    fPtr->classCls, "::oo::Slot", NULL, -1, NULL, 0))->classPtr;
+    if (slotCls == NULL) {
+	return TCL_ERROR;
+    }
+    Tcl_IncrRefCount(getName);
+    Tcl_IncrRefCount(setName);
+    for (slotInfoPtr = slots ; slotInfoPtr->name ; slotInfoPtr++) {
+	Tcl_Object slotObject = Tcl_NewObjectInstance(fPtr->interp,
+		(Tcl_Class) slotCls, slotInfoPtr->name, NULL,-1,NULL,0);
+
+	if (slotObject == NULL) {
+	    continue;
+	}
+	Tcl_NewInstanceMethod(fPtr->interp, slotObject, getName, 0,
+		&slotInfoPtr->getterType, NULL);
+	Tcl_NewInstanceMethod(fPtr->interp, slotObject, setName, 0,
+		&slotInfoPtr->setterType, NULL);
+    }
+    Tcl_DecrRefCount(getName);
+    Tcl_DecrRefCount(setName);
+    return TCL_OK;
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * ClassFilterGet, ClassFilterSet --
+ *	Implementation of the "filter" slot accessors of the "oo::define"
+ *	command.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+static int
+ClassFilterGet(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    Tcl_ObjectContext context,
+    int objc,
+    Tcl_Obj *const *objv)
+{
+    Object *oPtr = (Object *) TclOOGetDefineCmdContext(interp);
+    Tcl_Obj *resultObj, *filterObj;
+    int i;
+
+    if (Tcl_ObjectContextSkippedArgs(context) != objc) {
+	Tcl_WrongNumArgs(interp, Tcl_ObjectContextSkippedArgs(context), objv,
+		NULL);
+	return TCL_ERROR;
+    }
+    if (oPtr == NULL) {
+	return TCL_ERROR;
+    } else if (!oPtr->classPtr) {
+	Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		"attempt to misuse API", -1));
+	Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", NULL);
+	return TCL_ERROR;
+    }
+
+    resultObj = Tcl_NewObj();
+    FOREACH(filterObj, oPtr->classPtr->filters) {
+	Tcl_ListObjAppendElement(NULL, resultObj, filterObj);
+    }
+    Tcl_SetObjResult(interp, resultObj);
+    return TCL_OK;
+}
+
+static int
+ClassFilterSet(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    Tcl_ObjectContext context,
+    int objc,
+    Tcl_Obj *const *objv)
+{
+    Object *oPtr = (Object *) TclOOGetDefineCmdContext(interp);
+    int filterc;
+    Tcl_Obj **filterv;
+
+    if (Tcl_ObjectContextSkippedArgs(context)+1 != objc) {
+	Tcl_WrongNumArgs(interp, Tcl_ObjectContextSkippedArgs(context), objv,
+		"filterList");
+	return TCL_ERROR;
+    }
+    objv += Tcl_ObjectContextSkippedArgs(context);
+
+    if (oPtr == NULL) {
+	return TCL_ERROR;
+    } else if (!oPtr->classPtr) {
+	Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		"attempt to misuse API", -1));
+	Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", NULL);
+	return TCL_ERROR;
+    } else if (Tcl_ListObjGetElements(interp, objv[0], &filterc,
+	    &filterv) != TCL_OK) {
+	return TCL_ERROR;
+    }
+
+    TclOOClassSetFilters(interp, oPtr->classPtr, filterc, filterv);
+    return TCL_OK;
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * ClassMixinGet, ClassMixinSet --
+ *	Implementation of the "mixin" slot accessors of the "oo::define"
+ *	command.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+static int
+ClassMixinGet(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    Tcl_ObjectContext context,
+    int objc,
+    Tcl_Obj *const *objv)
+{
+    Object *oPtr = (Object *) TclOOGetDefineCmdContext(interp);
+    Tcl_Obj *resultObj;
+    Class *mixinPtr;
+    int i;
+
+    if (Tcl_ObjectContextSkippedArgs(context) != objc) {
+	Tcl_WrongNumArgs(interp, Tcl_ObjectContextSkippedArgs(context), objv,
+		NULL);
+	return TCL_ERROR;
+    }
+    if (oPtr == NULL) {
+	return TCL_ERROR;
+    } else if (!oPtr->classPtr) {
+	Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		"attempt to misuse API", -1));
+	Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", NULL);
+	return TCL_ERROR;
+    }
+
+    resultObj = Tcl_NewObj();
+    FOREACH(mixinPtr, oPtr->classPtr->mixins) {
+	Tcl_ListObjAppendElement(NULL, resultObj,
+		TclOOObjectName(interp, mixinPtr->thisPtr));
+    }
+    Tcl_SetObjResult(interp, resultObj);
+    return TCL_OK;
+
+}
+
+static int
+ClassMixinSet(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    Tcl_ObjectContext context,
+    int objc,
+    Tcl_Obj *const *objv)
+{
+    Object *oPtr = (Object *) TclOOGetDefineCmdContext(interp);
+    int mixinc, i;
+    Tcl_Obj **mixinv;
+    Class **mixins;
+
+    if (Tcl_ObjectContextSkippedArgs(context)+1 != objc) {
+	Tcl_WrongNumArgs(interp, Tcl_ObjectContextSkippedArgs(context), objv,
+		"mixinList");
+	return TCL_ERROR;
+    }
+    objv += Tcl_ObjectContextSkippedArgs(context);
+
+    if (oPtr == NULL) {
+	return TCL_ERROR;
+    } else if (!oPtr->classPtr) {
+	Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		"attempt to misuse API", -1));
+	Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", NULL);
+	return TCL_ERROR;
+    } else if (Tcl_ListObjGetElements(interp, objv[0], &mixinc,
+	    &mixinv) != TCL_OK) {
+	return TCL_ERROR;
+    }
+
+    mixins = TclStackAlloc(interp, sizeof(Class *) * mixinc);
+
+    for (i=0 ; i<mixinc ; i++) {
+	mixins[i] = GetClassInOuterContext(interp, mixinv[i],
+		"may only mix in classes");
+	if (mixins[i] == NULL) {
+	    goto freeAndError;
+	}
+	if (TclOOIsReachable(oPtr->classPtr, mixins[i])) {
+	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		    "may not mix a class into itself", -1));
+	    Tcl_SetErrorCode(interp, "TCL", "OO", "SELF_MIXIN", NULL);
+	    goto freeAndError;
+	}
+    }
+
+    TclOOClassSetMixins(interp, oPtr->classPtr, mixinc, mixins);
+    TclStackFree(interp, mixins);
+    return TCL_OK;
+
+  freeAndError:
+    TclStackFree(interp, mixins);
+    return TCL_ERROR;
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * ClassSuperGet, ClassSuperSet --
+ *	Implementation of the "superclass" slot accessors of the "oo::define"
+ *	command.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+static int
+ClassSuperGet(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    Tcl_ObjectContext context,
+    int objc,
+    Tcl_Obj *const *objv)
+{
+    Object *oPtr = (Object *) TclOOGetDefineCmdContext(interp);
+    Tcl_Obj *resultObj;
+    Class *superPtr;
+    int i;
+
+    if (Tcl_ObjectContextSkippedArgs(context) != objc) {
+	Tcl_WrongNumArgs(interp, Tcl_ObjectContextSkippedArgs(context), objv,
+		NULL);
+	return TCL_ERROR;
+    }
+    if (oPtr == NULL) {
+	return TCL_ERROR;
+    } else if (!oPtr->classPtr) {
+	Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		"attempt to misuse API", -1));
+	Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", NULL);
+	return TCL_ERROR;
+    }
+
+    resultObj = Tcl_NewObj();
+    FOREACH(superPtr, oPtr->classPtr->superclasses) {
+	Tcl_ListObjAppendElement(NULL, resultObj,
+		TclOOObjectName(interp, superPtr->thisPtr));
+    }
+    Tcl_SetObjResult(interp, resultObj);
+    return TCL_OK;
+}
+
+static int
+ClassSuperSet(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    Tcl_ObjectContext context,
+    int objc,
+    Tcl_Obj *const *objv)
+{
+    Object *oPtr = (Object *) TclOOGetDefineCmdContext(interp);
+    int superc, i, j;
+    Tcl_Obj **superv;
+    Class **superclasses, *superPtr;
+
+    if (Tcl_ObjectContextSkippedArgs(context)+1 != objc) {
+	Tcl_WrongNumArgs(interp, Tcl_ObjectContextSkippedArgs(context), objv,
+		"superclassList");
+	return TCL_ERROR;
+    }
+    objv += Tcl_ObjectContextSkippedArgs(context);
+
+    if (oPtr == NULL) {
+	return TCL_ERROR;
+    } else if (!oPtr->classPtr) {
+	Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		"attempt to misuse API", -1));
+	Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", NULL);
+	return TCL_ERROR;
+    } else if (oPtr == oPtr->fPtr->objectCls->thisPtr) {
+	Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		"may not modify the superclass of the root object", -1));
+	Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", NULL);
+	return TCL_ERROR;
+    } else if (Tcl_ListObjGetElements(interp, objv[0], &superc,
+	    &superv) != TCL_OK) {
+	return TCL_ERROR;
+    }
+
+    /*
+     * Allocate some working space.
+     */
+
+    superclasses = (Class **) ckalloc(sizeof(Class *) * superc);
+
+    /*
+     * Parse the arguments to get the class to use as superclasses.
+     *
+     * Note that zero classes is special, as it is equivalent to just the
+     * class of objects. [Bug 9d61624b3d]
+     */
+
+    if (superc == 0) {
+	superclasses = ckrealloc(superclasses, sizeof(Class *));
+	superclasses[0] = oPtr->fPtr->objectCls;
+	superc = 1;
+	if (TclOOIsReachable(oPtr->fPtr->classCls, oPtr->classPtr)) {
+	    superclasses[0] = oPtr->fPtr->classCls;
+	}
+    } else {
+	for (i=0 ; i<superc ; i++) {
+	    superclasses[i] = GetClassInOuterContext(interp, superv[i],
+		    "only a class can be a superclass");
+	    if (superclasses[i] == NULL) {
+		goto failedAfterAlloc;
+	    }
+	    for (j=0 ; j<i ; j++) {
+		if (superclasses[j] == superclasses[i]) {
+		    Tcl_SetObjResult(interp, Tcl_NewStringObj(
+			    "class should only be a direct superclass once",
+			    -1));
+		    Tcl_SetErrorCode(interp, "TCL", "OO", "REPETITIOUS",NULL);
+		    goto failedAfterAlloc;
+		}
+	    }
+	    if (TclOOIsReachable(oPtr->classPtr, superclasses[i])) {
+		Tcl_SetObjResult(interp, Tcl_NewStringObj(
+			"attempt to form circular dependency graph", -1));
+		Tcl_SetErrorCode(interp, "TCL", "OO", "CIRCULARITY", NULL);
+	    failedAfterAlloc:
+		ckfree((char *) superclasses);
+		return TCL_ERROR;
+	    }
+	}
+    }
+
+    /*
+     * Install the list of superclasses into the class. Note that this also
+     * involves splicing the class out of the superclasses' subclass list that
+     * it used to be a member of and splicing it into the new superclasses'
+     * subclass list.
+     */
+
+    if (oPtr->classPtr->superclasses.num != 0) {
+	FOREACH(superPtr, oPtr->classPtr->superclasses) {
+	    TclOORemoveFromSubclasses(oPtr->classPtr, superPtr);
+	}
+	ckfree((char *) oPtr->classPtr->superclasses.list);
+    }
+    oPtr->classPtr->superclasses.list = superclasses;
+    oPtr->classPtr->superclasses.num = superc;
+    FOREACH(superPtr, oPtr->classPtr->superclasses) {
+	TclOOAddToSubclasses(oPtr->classPtr, superPtr);
+    }
+    BumpGlobalEpoch(interp, oPtr->classPtr);
+
+    return TCL_OK;
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * ClassVarsGet, ClassVarsSet --
+ *	Implementation of the "variable" slot accessors of the "oo::define"
+ *	command.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+static int
+ClassVarsGet(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    Tcl_ObjectContext context,
+    int objc,
+    Tcl_Obj *const *objv)
+{
+    Object *oPtr = (Object *) TclOOGetDefineCmdContext(interp);
+    Tcl_Obj *resultObj, *variableObj;
+    int i;
+
+    if (Tcl_ObjectContextSkippedArgs(context) != objc) {
+	Tcl_WrongNumArgs(interp, Tcl_ObjectContextSkippedArgs(context), objv,
+		NULL);
+	return TCL_ERROR;
+    }
+    if (oPtr == NULL) {
+	return TCL_ERROR;
+    } else if (!oPtr->classPtr) {
+	Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		"attempt to misuse API", -1));
+	Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", NULL);
+	return TCL_ERROR;
+    }
+
+    resultObj = Tcl_NewObj();
+    FOREACH(variableObj, oPtr->classPtr->variables) {
+	Tcl_ListObjAppendElement(NULL, resultObj, variableObj);
+    }
+    Tcl_SetObjResult(interp, resultObj);
+    return TCL_OK;
+}
+
+static int
+ClassVarsSet(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    Tcl_ObjectContext context,
+    int objc,
+    Tcl_Obj *const *objv)
+{
+    Object *oPtr = (Object *) TclOOGetDefineCmdContext(interp);
+    int varc;
+    Tcl_Obj **varv, *variableObj;
+    int i;
+
+    if (Tcl_ObjectContextSkippedArgs(context)+1 != objc) {
+	Tcl_WrongNumArgs(interp, Tcl_ObjectContextSkippedArgs(context), objv,
+		"filterList");
+	return TCL_ERROR;
+    }
+    objv += Tcl_ObjectContextSkippedArgs(context);
+
+    if (oPtr == NULL) {
+	return TCL_ERROR;
+    } else if (!oPtr->classPtr) {
+	Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		"attempt to misuse API", -1));
+	Tcl_SetErrorCode(interp, "TCL", "OO", "MONKEY_BUSINESS", NULL);
+	return TCL_ERROR;
+    } else if (Tcl_ListObjGetElements(interp, objv[0], &varc,
+	    &varv) != TCL_OK) {
+	return TCL_ERROR;
+    }
+
+    for (i=0 ; i<varc ; i++) {
+	const char *varName = Tcl_GetString(varv[i]);
+
+	if (strstr(varName, "::") != NULL) {
+	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		    "invalid declared variable name \"%s\": must not %s",
+		    varName, "contain namespace separators"));
+	    Tcl_SetErrorCode(interp, "TCL", "OO", "BAD_DECLVAR", NULL);
+	    return TCL_ERROR;
+	}
+	if (Tcl_StringMatch(varName, "*(*)")) {
+	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		    "invalid declared variable name \"%s\": must not %s",
+		    varName, "refer to an array element"));
+	    Tcl_SetErrorCode(interp, "TCL", "OO", "BAD_DECLVAR", NULL);
+	    return TCL_ERROR;
+	}
+    }
+
+    for (i=0 ; i<varc ; i++) {
+	Tcl_IncrRefCount(varv[i]);
+    }
+    FOREACH(variableObj, oPtr->classPtr->variables) {
+	Tcl_DecrRefCount(variableObj);
+    }
+    if (i != varc) {
+	if (varc == 0) {
+	    ckfree((char *) oPtr->classPtr->variables.list);
+	} else if (i) {
+	    oPtr->classPtr->variables.list = (Tcl_Obj **)
+		    ckrealloc((char *) oPtr->classPtr->variables.list,
+		    sizeof(Tcl_Obj *) * varc);
+	} else {
+	    oPtr->classPtr->variables.list = (Tcl_Obj **)
+		    ckalloc(sizeof(Tcl_Obj *) * varc);
+	}
+    }
+
+    oPtr->classPtr->variables.num = 0;
+    if (varc > 0) {
+	int created, n;
+	Tcl_HashTable uniqueTable;
+
+	Tcl_InitObjHashTable(&uniqueTable);
+	for (i=n=0 ; i<varc ; i++) {
+	    Tcl_CreateHashEntry(&uniqueTable, varv[i], &created);
+	    if (created) {
+		oPtr->classPtr->variables.list[n++] = varv[i];
+	    } else {
+		Tcl_DecrRefCount(varv[i]);
+	    }
+	}
+	oPtr->classPtr->variables.num = n;
+
+	/*
+	 * Shouldn't be necessary, but maintain num/list invariant.
+	 */
+
+	oPtr->classPtr->variables.list = (Tcl_Obj **)
+		ckrealloc((char *) oPtr->classPtr->variables.list,
+		sizeof(Tcl_Obj *) * n);
+	Tcl_DeleteHashTable(&uniqueTable);
+    }
+    return TCL_OK;
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * ObjectFilterGet, ObjectFilterSet --
+ *	Implementation of the "filter" slot accessors of the "oo::objdefine"
+ *	command.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+static int
+ObjFilterGet(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    Tcl_ObjectContext context,
+    int objc,
+    Tcl_Obj *const *objv)
+{
+    Object *oPtr = (Object *) TclOOGetDefineCmdContext(interp);
+    Tcl_Obj *resultObj, *filterObj;
+    int i;
+
+    if (Tcl_ObjectContextSkippedArgs(context) != objc) {
+	Tcl_WrongNumArgs(interp, Tcl_ObjectContextSkippedArgs(context), objv,
+		NULL);
+	return TCL_ERROR;
+    } else if (oPtr == NULL) {
+	return TCL_ERROR;
+    }
+
+    resultObj = Tcl_NewObj();
+    FOREACH(filterObj, oPtr->filters) {
+	Tcl_ListObjAppendElement(NULL, resultObj, filterObj);
+    }
+    Tcl_SetObjResult(interp, resultObj);
+    return TCL_OK;
+}
+
+static int
+ObjFilterSet(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    Tcl_ObjectContext context,
+    int objc,
+    Tcl_Obj *const *objv)
+{
+    Object *oPtr = (Object *) TclOOGetDefineCmdContext(interp);
+    int filterc;
+    Tcl_Obj **filterv;
+
+    if (Tcl_ObjectContextSkippedArgs(context)+1 != objc) {
+	Tcl_WrongNumArgs(interp, Tcl_ObjectContextSkippedArgs(context), objv,
+		"filterList");
+	return TCL_ERROR;
+    } else if (oPtr == NULL) {
+	return TCL_ERROR;
+    }
+    objv += Tcl_ObjectContextSkippedArgs(context);
+    if (Tcl_ListObjGetElements(interp, objv[0], &filterc,
+	    &filterv) != TCL_OK) {
+	return TCL_ERROR;
+    }
+
+    TclOOObjectSetFilters(oPtr, filterc, filterv);
+    return TCL_OK;
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * ObjectMixinGet, ObjectMixinSet --
+ *	Implementation of the "mixin" slot accessors of the "oo::objdefine"
+ *	command.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+static int
+ObjMixinGet(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    Tcl_ObjectContext context,
+    int objc,
+    Tcl_Obj *const *objv)
+{
+    Object *oPtr = (Object *) TclOOGetDefineCmdContext(interp);
+    Tcl_Obj *resultObj;
+    Class *mixinPtr;
+    int i;
+
+    if (Tcl_ObjectContextSkippedArgs(context) != objc) {
+	Tcl_WrongNumArgs(interp, Tcl_ObjectContextSkippedArgs(context), objv,
+		NULL);
+	return TCL_ERROR;
+    } else if (oPtr == NULL) {
+	return TCL_ERROR;
+    }
+
+    resultObj = Tcl_NewObj();
+    FOREACH(mixinPtr, oPtr->mixins) {
+	if (mixinPtr) {
+	    Tcl_ListObjAppendElement(NULL, resultObj,
+		    TclOOObjectName(interp, mixinPtr->thisPtr));
+	}
+    }
+    Tcl_SetObjResult(interp, resultObj);
+    return TCL_OK;
+}
+
+static int
+ObjMixinSet(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    Tcl_ObjectContext context,
+    int objc,
+    Tcl_Obj *const *objv)
+{
+    Object *oPtr = (Object *) TclOOGetDefineCmdContext(interp);
+    int mixinc;
+    Tcl_Obj **mixinv;
+    Class **mixins;
+    int i;
+
+    if (Tcl_ObjectContextSkippedArgs(context)+1 != objc) {
+	Tcl_WrongNumArgs(interp, Tcl_ObjectContextSkippedArgs(context), objv,
+		"mixinList");
+	return TCL_ERROR;
+    } else if (oPtr == NULL) {
+	return TCL_ERROR;
+    }
+    objv += Tcl_ObjectContextSkippedArgs(context);
+    if (Tcl_ListObjGetElements(interp, objv[0], &mixinc,
+	    &mixinv) != TCL_OK) {
+	return TCL_ERROR;
+    }
+
+    mixins = TclStackAlloc(interp, sizeof(Class *) * mixinc);
+
+    for (i=0 ; i<mixinc ; i++) {
+	mixins[i] = GetClassInOuterContext(interp, mixinv[i],
+		"may only mix in classes");
+	if (mixins[i] == NULL) {
+	    TclStackFree(interp, mixins);
+	    return TCL_ERROR;
+	}
+    }
+
+    TclOOObjectSetMixins(oPtr, mixinc, mixins);
+    TclStackFree(interp, mixins);
+    return TCL_OK;
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * ObjectVarsGet, ObjectVarsSet --
+ *	Implementation of the "variable" slot accessors of the "oo::objdefine"
+ *	command.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+static int
+ObjVarsGet(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    Tcl_ObjectContext context,
+    int objc,
+    Tcl_Obj *const *objv)
+{
+    Object *oPtr = (Object *) TclOOGetDefineCmdContext(interp);
+    Tcl_Obj *resultObj, *variableObj;
+    int i;
+
+    if (Tcl_ObjectContextSkippedArgs(context) != objc) {
+	Tcl_WrongNumArgs(interp, Tcl_ObjectContextSkippedArgs(context), objv,
+		NULL);
+	return TCL_ERROR;
+    } else if (oPtr == NULL) {
+	return TCL_ERROR;
+    }
+
+    resultObj = Tcl_NewObj();
+    FOREACH(variableObj, oPtr->variables) {
+	Tcl_ListObjAppendElement(NULL, resultObj, variableObj);
+    }
+    Tcl_SetObjResult(interp, resultObj);
+    return TCL_OK;
+}
+
+static int
+ObjVarsSet(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    Tcl_ObjectContext context,
+    int objc,
+    Tcl_Obj *const *objv)
+{
+    Object *oPtr = (Object *) TclOOGetDefineCmdContext(interp);
+    int varc, i;
+    Tcl_Obj **varv, *variableObj;
+
+    if (Tcl_ObjectContextSkippedArgs(context)+1 != objc) {
+	Tcl_WrongNumArgs(interp, Tcl_ObjectContextSkippedArgs(context), objv,
+		"variableList");
+	return TCL_ERROR;
+    } else if (oPtr == NULL) {
+	return TCL_ERROR;
+    }
+    objv += Tcl_ObjectContextSkippedArgs(context);
+    if (Tcl_ListObjGetElements(interp, objv[0], &varc,
+	    &varv) != TCL_OK) {
+	return TCL_ERROR;
+    }
+
+    for (i=0 ; i<varc ; i++) {
+	const char *varName = Tcl_GetString(varv[i]);
+
+	if (strstr(varName, "::") != NULL) {
+	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		    "invalid declared variable name \"%s\": must not %s",
+		    varName, "contain namespace separators"));
+	    Tcl_SetErrorCode(interp, "TCL", "OO", "BAD_DECLVAR", NULL);
+	    return TCL_ERROR;
+	}
+	if (Tcl_StringMatch(varName, "*(*)")) {
+	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		    "invalid declared variable name \"%s\": must not %s",
+		    varName, "refer to an array element"));
+	    Tcl_SetErrorCode(interp, "TCL", "OO", "BAD_DECLVAR", NULL);
+	    return TCL_ERROR;
+	}
+    }
+    for (i=0 ; i<varc ; i++) {
+	Tcl_IncrRefCount(varv[i]);
+    }
+
+    FOREACH(variableObj, oPtr->variables) {
+	Tcl_DecrRefCount(variableObj);
+    }
+    if (i != varc) {
+	if (varc == 0) {
+	    ckfree((char *) oPtr->variables.list);
+	} else if (i) {
+	    oPtr->variables.list = (Tcl_Obj **)
+		    ckrealloc((char *) oPtr->variables.list,
+		    sizeof(Tcl_Obj *) * varc);
+	} else {
+	    oPtr->variables.list = (Tcl_Obj **)
+		    ckalloc(sizeof(Tcl_Obj *) * varc);
+	}
+    }
+    oPtr->variables.num = 0;
+    if (varc > 0) {
+	int created, n;
+	Tcl_HashTable uniqueTable;
+
+	Tcl_InitObjHashTable(&uniqueTable);
+	for (i=n=0 ; i<varc ; i++) {
+	    Tcl_CreateHashEntry(&uniqueTable, varv[i], &created);
+	    if (created) {
+		oPtr->variables.list[n++] = varv[i];
+	    } else {
+		Tcl_DecrRefCount(varv[i]);
+	    }
+	}
+	oPtr->variables.num = n;
+
+	/*
+	 * Shouldn't be necessary, but maintain num/list invariant.
+	 */
+
+	oPtr->variables.list = (Tcl_Obj **)
+		ckrealloc((char *) oPtr->variables.list,
+		sizeof(Tcl_Obj *) * n);
+	Tcl_DeleteHashTable(&uniqueTable);
+    }
+    return TCL_OK;
+}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tclOOInfo.c b/generic/tclOOInfo.c
new file mode 100644
index 0000000..76eaef5
--- /dev/null
+++ b/generic/tclOOInfo.c
@@ -0,0 +1,1530 @@
+/*
+ * tclOODefineCmds.c --
+ *
+ *	This file contains the implementation of the ::oo-related [info]
+ *	subcommands.
+ *
+ * Copyright (c) 2006-2011 by Donal K. Fellows
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include "tclInt.h"
+#include "tclOOInt.h"
+
+static inline Class *	GetClassFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr);
+static Tcl_ObjCmdProc InfoObjectCallCmd;
+static Tcl_ObjCmdProc InfoObjectClassCmd;
+static Tcl_ObjCmdProc InfoObjectDefnCmd;
+static Tcl_ObjCmdProc InfoObjectFiltersCmd;
+static Tcl_ObjCmdProc InfoObjectForwardCmd;
+static Tcl_ObjCmdProc InfoObjectIsACmd;
+static Tcl_ObjCmdProc InfoObjectMethodsCmd;
+static Tcl_ObjCmdProc InfoObjectMethodTypeCmd;
+static Tcl_ObjCmdProc InfoObjectMixinsCmd;
+static Tcl_ObjCmdProc InfoObjectNsCmd;
+static Tcl_ObjCmdProc InfoObjectVarsCmd;
+static Tcl_ObjCmdProc InfoObjectVariablesCmd;
+static Tcl_ObjCmdProc InfoClassCallCmd;
+static Tcl_ObjCmdProc InfoClassConstrCmd;
+static Tcl_ObjCmdProc InfoClassDefnCmd;
+static Tcl_ObjCmdProc InfoClassDestrCmd;
+static Tcl_ObjCmdProc InfoClassFiltersCmd;
+static Tcl_ObjCmdProc InfoClassForwardCmd;
+static Tcl_ObjCmdProc InfoClassInstancesCmd;
+static Tcl_ObjCmdProc InfoClassMethodsCmd;
+static Tcl_ObjCmdProc InfoClassMethodTypeCmd;
+static Tcl_ObjCmdProc InfoClassMixinsCmd;
+static Tcl_ObjCmdProc InfoClassSubsCmd;
+static Tcl_ObjCmdProc InfoClassSupersCmd;
+static Tcl_ObjCmdProc InfoClassVariablesCmd;
+
+/*
+ * List of commands that are used to implement the [info object] subcommands.
+ */
+
+static const EnsembleImplMap infoObjectCmds[] = {
+    {"call",	   InfoObjectCallCmd,	    TclCompileBasic2ArgCmd, NULL, NULL, 0},
+    {"class",	   InfoObjectClassCmd,	    TclCompileInfoObjectClassCmd, NULL, NULL, 0},
+    {"definition", InfoObjectDefnCmd,	    TclCompileBasic2ArgCmd, NULL, NULL, 0},
+    {"filters",	   InfoObjectFiltersCmd,    TclCompileBasic1ArgCmd, NULL, NULL, 0},
+    {"forward",	   InfoObjectForwardCmd,    TclCompileBasic2ArgCmd, NULL, NULL, 0},
+    {"isa",	   InfoObjectIsACmd,	    TclCompileInfoObjectIsACmd, NULL, NULL, 0},
+    {"methods",	   InfoObjectMethodsCmd,    TclCompileBasicMin1ArgCmd, NULL, NULL, 0},
+    {"methodtype", InfoObjectMethodTypeCmd, TclCompileBasic2ArgCmd, NULL, NULL, 0},
+    {"mixins",	   InfoObjectMixinsCmd,	    TclCompileBasic1ArgCmd, NULL, NULL, 0},
+    {"namespace",  InfoObjectNsCmd,	    TclCompileInfoObjectNamespaceCmd, NULL, NULL, 0},
+    {"variables",  InfoObjectVariablesCmd,  TclCompileBasic1ArgCmd, NULL, NULL, 0},
+    {"vars",	   InfoObjectVarsCmd,	    TclCompileBasic1Or2ArgCmd, NULL, NULL, 0},
+    {NULL, NULL, NULL, NULL, NULL, 0}
+};
+
+/*
+ * List of commands that are used to implement the [info class] subcommands.
+ */
+
+static const EnsembleImplMap infoClassCmds[] = {
+    {"call",	     InfoClassCallCmd,		TclCompileBasic2ArgCmd, NULL, NULL, 0},
+    {"constructor",  InfoClassConstrCmd,	TclCompileBasic1ArgCmd, NULL, NULL, 0},
+    {"definition",   InfoClassDefnCmd,		TclCompileBasic2ArgCmd, NULL, NULL, 0},
+    {"destructor",   InfoClassDestrCmd,		TclCompileBasic1ArgCmd, NULL, NULL, 0},
+    {"filters",	     InfoClassFiltersCmd,	TclCompileBasic1ArgCmd, NULL, NULL, 0},
+    {"forward",	     InfoClassForwardCmd,	TclCompileBasic2ArgCmd, NULL, NULL, 0},
+    {"instances",    InfoClassInstancesCmd,	TclCompileBasic1Or2ArgCmd, NULL, NULL, 0},
+    {"methods",	     InfoClassMethodsCmd,	TclCompileBasicMin1ArgCmd, NULL, NULL, 0},
+    {"methodtype",   InfoClassMethodTypeCmd,	TclCompileBasic2ArgCmd, NULL, NULL, 0},
+    {"mixins",	     InfoClassMixinsCmd,	TclCompileBasic1ArgCmd, NULL, NULL, 0},
+    {"subclasses",   InfoClassSubsCmd,		TclCompileBasic1Or2ArgCmd, NULL, NULL, 0},
+    {"superclasses", InfoClassSupersCmd,	TclCompileBasic1ArgCmd, NULL, NULL, 0},
+    {"variables",    InfoClassVariablesCmd,	TclCompileBasic1ArgCmd, NULL, NULL, 0},
+    {NULL, NULL, NULL, NULL, NULL, 0}
+};
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * TclOOInitInfo --
+ *
+ *	Adjusts the Tcl core [info] command to contain subcommands ("object"
+ *	and "class") for introspection of objects and classes.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+void
+TclOOInitInfo(
+    Tcl_Interp *interp)
+{
+    Tcl_Command infoCmd;
+    Tcl_Obj *mapDict;
+
+    /*
+     * Build the ensembles used to implement [info object] and [info class].
+     */
+
+    TclMakeEnsemble(interp, "::oo::InfoObject", infoObjectCmds);
+    TclMakeEnsemble(interp, "::oo::InfoClass", infoClassCmds);
+
+    /*
+     * Install into the master [info] ensemble.
+     */
+
+    infoCmd = Tcl_FindCommand(interp, "info", NULL, TCL_GLOBAL_ONLY);
+    Tcl_GetEnsembleMappingDict(NULL, infoCmd, &mapDict);
+    Tcl_DictObjPut(NULL, mapDict, Tcl_NewStringObj("object", -1),
+	    Tcl_NewStringObj("::oo::InfoObject", -1));
+    Tcl_DictObjPut(NULL, mapDict, Tcl_NewStringObj("class", -1),
+	    Tcl_NewStringObj("::oo::InfoClass", -1));
+    Tcl_SetEnsembleMappingDict(interp, infoCmd, mapDict);
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * GetClassFromObj --
+ *
+ *	How to correctly get a class from a Tcl_Obj. Just a wrapper round
+ *	Tcl_GetObjectFromObj, but this is an idiom that was used heavily.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+static inline Class *
+GetClassFromObj(
+    Tcl_Interp *interp,
+    Tcl_Obj *objPtr)
+{
+    Object *oPtr = (Object *) Tcl_GetObjectFromObj(interp, objPtr);
+
+    if (oPtr == NULL) {
+	return NULL;
+    }
+    if (oPtr->classPtr == NULL) {
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		"\"%s\" is not a class", TclGetString(objPtr)));
+	Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "CLASS",
+		TclGetString(objPtr), NULL);
+	return NULL;
+    }
+    return oPtr->classPtr;
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * InfoObjectClassCmd --
+ *
+ *	Implements [info object class $objName ?$className?]
+ *
+ * ----------------------------------------------------------------------
+ */
+
+static int
+InfoObjectClassCmd(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const objv[])
+{
+    Object *oPtr;
+
+    if (objc != 2 && objc != 3) {
+	Tcl_WrongNumArgs(interp, 1, objv, "objName ?className?");
+	return TCL_ERROR;
+    }
+
+    oPtr = (Object *) Tcl_GetObjectFromObj(interp, objv[1]);
+    if (oPtr == NULL) {
+	return TCL_ERROR;
+    }
+
+    if (objc == 2) {
+	Tcl_SetObjResult(interp,
+		TclOOObjectName(interp, oPtr->selfCls->thisPtr));
+	return TCL_OK;
+    } else {
+	Class *mixinPtr, *o2clsPtr;
+	int i;
+
+	o2clsPtr = GetClassFromObj(interp, objv[2]);
+	if (o2clsPtr == NULL) {
+	    return TCL_ERROR;
+	}
+
+	FOREACH(mixinPtr, oPtr->mixins) {
+	    if (!mixinPtr) {
+		continue;
+	    }
+	    if (TclOOIsReachable(o2clsPtr, mixinPtr)) {
+		Tcl_SetObjResult(interp, Tcl_NewIntObj(1));
+		return TCL_OK;
+	    }
+	}
+	Tcl_SetObjResult(interp, Tcl_NewIntObj(
+		TclOOIsReachable(o2clsPtr, oPtr->selfCls)));
+	return TCL_OK;
+    }
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * InfoObjectDefnCmd --
+ *
+ *	Implements [info object definition $objName $methodName]
+ *
+ * ----------------------------------------------------------------------
+ */
+
+static int
+InfoObjectDefnCmd(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const objv[])
+{
+    Object *oPtr;
+    Tcl_HashEntry *hPtr;
+    Proc *procPtr;
+    CompiledLocal *localPtr;
+    Tcl_Obj *resultObjs[2];
+
+    if (objc != 3) {
+	Tcl_WrongNumArgs(interp, 1, objv, "objName methodName");
+	return TCL_ERROR;
+    }
+
+    oPtr = (Object *) Tcl_GetObjectFromObj(interp, objv[1]);
+    if (oPtr == NULL) {
+	return TCL_ERROR;
+    }
+
+    if (!oPtr->methodsPtr) {
+	goto unknownMethod;
+    }
+    hPtr = Tcl_FindHashEntry(oPtr->methodsPtr, (char *) objv[2]);
+    if (hPtr == NULL) {
+    unknownMethod:
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		"unknown method \"%s\"", TclGetString(objv[2])));
+	Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "METHOD",
+		TclGetString(objv[2]), NULL);
+	return TCL_ERROR;
+    }
+    procPtr = TclOOGetProcFromMethod(Tcl_GetHashValue(hPtr));
+    if (procPtr == NULL) {
+	Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		"definition not available for this kind of method", -1));
+	Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "METHOD",
+		TclGetString(objv[2]), NULL);
+	return TCL_ERROR;
+    }
+
+    resultObjs[0] = Tcl_NewObj();
+    for (localPtr=procPtr->firstLocalPtr; localPtr!=NULL;
+	    localPtr=localPtr->nextPtr) {
+	if (TclIsVarArgument(localPtr)) {
+	    Tcl_Obj *argObj;
+
+	    argObj = Tcl_NewObj();
+	    Tcl_ListObjAppendElement(NULL, argObj,
+		    Tcl_NewStringObj(localPtr->name, -1));
+	    if (localPtr->defValuePtr != NULL) {
+		Tcl_ListObjAppendElement(NULL, argObj, localPtr->defValuePtr);
+	    }
+	    Tcl_ListObjAppendElement(NULL, resultObjs[0], argObj);
+	}
+    }
+    resultObjs[1] = TclOOGetMethodBody(Tcl_GetHashValue(hPtr));
+    Tcl_SetObjResult(interp, Tcl_NewListObj(2, resultObjs));
+    return TCL_OK;
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * InfoObjectFiltersCmd --
+ *
+ *	Implements [info object filters $objName]
+ *
+ * ----------------------------------------------------------------------
+ */
+
+static int
+InfoObjectFiltersCmd(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const objv[])
+{
+    int i;
+    Tcl_Obj *filterObj, *resultObj;
+    Object *oPtr;
+
+    if (objc != 2) {
+	Tcl_WrongNumArgs(interp, 1, objv, "objName");
+	return TCL_ERROR;
+    }
+
+    oPtr = (Object *) Tcl_GetObjectFromObj(interp, objv[1]);
+    if (oPtr == NULL) {
+	return TCL_ERROR;
+    }
+    resultObj = Tcl_NewObj();
+
+    FOREACH(filterObj, oPtr->filters) {
+	Tcl_ListObjAppendElement(NULL, resultObj, filterObj);
+    }
+    Tcl_SetObjResult(interp, resultObj);
+    return TCL_OK;
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * InfoObjectForwardCmd --
+ *
+ *	Implements [info object forward $objName $methodName]
+ *
+ * ----------------------------------------------------------------------
+ */
+
+static int
+InfoObjectForwardCmd(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const objv[])
+{
+    Object *oPtr;
+    Tcl_HashEntry *hPtr;
+    Tcl_Obj *prefixObj;
+
+    if (objc != 3) {
+	Tcl_WrongNumArgs(interp, 1, objv, "objName methodName");
+	return TCL_ERROR;
+    }
+
+    oPtr = (Object *) Tcl_GetObjectFromObj(interp, objv[1]);
+    if (oPtr == NULL) {
+	return TCL_ERROR;
+    }
+
+    if (!oPtr->methodsPtr) {
+	goto unknownMethod;
+    }
+    hPtr = Tcl_FindHashEntry(oPtr->methodsPtr, (char *) objv[2]);
+    if (hPtr == NULL) {
+    unknownMethod:
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		"unknown method \"%s\"", TclGetString(objv[2])));
+	Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "METHOD",
+		TclGetString(objv[2]), NULL);
+	return TCL_ERROR;
+    }
+    prefixObj = TclOOGetFwdFromMethod(Tcl_GetHashValue(hPtr));
+    if (prefixObj == NULL) {
+	Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		"prefix argument list not available for this kind of method",
+		-1));
+	Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "METHOD",
+		TclGetString(objv[2]), NULL);
+	return TCL_ERROR;
+    }
+
+    Tcl_SetObjResult(interp, prefixObj);
+    return TCL_OK;
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * InfoObjectIsACmd --
+ *
+ *	Implements [info object isa $category $objName ...]
+ *
+ * ----------------------------------------------------------------------
+ */
+
+static int
+InfoObjectIsACmd(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const objv[])
+{
+    static const char *const categories[] = {
+	"class", "metaclass", "mixin", "object", "typeof", NULL
+    };
+    enum IsACats {
+	IsClass, IsMetaclass, IsMixin, IsObject, IsType
+    };
+    Object *oPtr, *o2Ptr;
+    int idx, i, result = 0;
+
+    if (objc < 3) {
+	Tcl_WrongNumArgs(interp, 1, objv, "category objName ?arg ...?");
+	return TCL_ERROR;
+    }
+    if (Tcl_GetIndexFromObj(interp, objv[1], categories, "category", 0,
+	    &idx) != TCL_OK) {
+	return TCL_ERROR;
+    }
+
+    /*
+     * Now we know what test we are doing, we can check we've got the right
+     * number of arguments.
+     */
+
+    switch ((enum IsACats) idx) {
+    case IsObject:
+    case IsClass:
+    case IsMetaclass:
+	if (objc != 3) {
+	    Tcl_WrongNumArgs(interp, 2, objv, "objName");
+	    return TCL_ERROR;
+	}
+	break;
+    case IsMixin:
+    case IsType:
+	if (objc != 4) {
+	    Tcl_WrongNumArgs(interp, 2, objv, "objName className");
+	    return TCL_ERROR;
+	}
+	break;
+    }
+
+    /*
+     * Perform the check. Note that we can guarantee that we will not fail
+     * from here on; "failures" result in a false-TCL_OK result.
+     */
+
+    oPtr = (Object *) Tcl_GetObjectFromObj(interp, objv[2]);
+    if (oPtr == NULL) {
+	goto failPrecondition;
+    }
+
+    switch ((enum IsACats) idx) {
+    case IsObject:
+	result = 1;
+	break;
+    case IsClass:
+	result = (oPtr->classPtr != NULL);
+	break;
+    case IsMetaclass:
+	if (oPtr->classPtr != NULL) {
+	    result = TclOOIsReachable(TclOOGetFoundation(interp)->classCls,
+		    oPtr->classPtr);
+	}
+	break;
+    case IsMixin:
+	o2Ptr = (Object *) Tcl_GetObjectFromObj(interp, objv[3]);
+	if (o2Ptr == NULL) {
+	    goto failPrecondition;
+	}
+	if (o2Ptr->classPtr != NULL) {
+	    Class *mixinPtr;
+
+	    FOREACH(mixinPtr, oPtr->mixins) {
+		if (!mixinPtr) {
+		    continue;
+		}
+		if (TclOOIsReachable(o2Ptr->classPtr, mixinPtr)) {
+		    result = 1;
+		    break;
+		}
+	    }
+	}
+	break;
+    case IsType:
+	o2Ptr = (Object *) Tcl_GetObjectFromObj(interp, objv[3]);
+	if (o2Ptr == NULL) {
+	    goto failPrecondition;
+	}
+	if (o2Ptr->classPtr != NULL) {
+	    result = TclOOIsReachable(o2Ptr->classPtr, oPtr->selfCls);
+	}
+	break;
+    }
+    Tcl_SetObjResult(interp, Tcl_NewBooleanObj(result));
+    return TCL_OK;
+
+  failPrecondition:
+    Tcl_ResetResult(interp);
+    Tcl_SetObjResult(interp, Tcl_NewBooleanObj(0));
+    return TCL_OK;
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * InfoObjectMethodsCmd --
+ *
+ *	Implements [info object methods $objName ?$option ...?]
+ *
+ * ----------------------------------------------------------------------
+ */
+
+static int
+InfoObjectMethodsCmd(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const objv[])
+{
+    Object *oPtr;
+    int flag = PUBLIC_METHOD, recurse = 0;
+    FOREACH_HASH_DECLS;
+    Tcl_Obj *namePtr, *resultObj;
+    Method *mPtr;
+    static const char *const options[] = {
+	"-all", "-localprivate", "-private", NULL
+    };
+    enum Options {
+	OPT_ALL, OPT_LOCALPRIVATE, OPT_PRIVATE
+    };
+
+    if (objc < 2) {
+	Tcl_WrongNumArgs(interp, 1, objv, "objName ?-option value ...?");
+	return TCL_ERROR;
+    }
+    oPtr = (Object *) Tcl_GetObjectFromObj(interp, objv[1]);
+    if (oPtr == NULL) {
+	return TCL_ERROR;
+    }
+    if (objc != 2) {
+	int i, idx;
+
+	for (i=2 ; i<objc ; i++) {
+	    if (Tcl_GetIndexFromObj(interp, objv[i], options, "option", 0,
+		    &idx) != TCL_OK) {
+		return TCL_ERROR;
+	    }
+	    switch ((enum Options) idx) {
+	    case OPT_ALL:
+		recurse = 1;
+		break;
+	    case OPT_LOCALPRIVATE:
+		flag = PRIVATE_METHOD;
+		break;
+	    case OPT_PRIVATE:
+		flag = 0;
+		break;
+	    }
+	}
+    }
+
+    resultObj = Tcl_NewObj();
+    if (recurse) {
+	const char **names;
+	int i, numNames = TclOOGetSortedMethodList(oPtr, flag, &names);
+
+	for (i=0 ; i<numNames ; i++) {
+	    Tcl_ListObjAppendElement(NULL, resultObj,
+		    Tcl_NewStringObj(names[i], -1));
+	}
+	if (numNames > 0) {
+	    ckfree(names);
+	}
+    } else if (oPtr->methodsPtr) {
+	FOREACH_HASH(namePtr, mPtr, oPtr->methodsPtr) {
+	    if (mPtr->typePtr != NULL && (mPtr->flags & flag) == flag) {
+		Tcl_ListObjAppendElement(NULL, resultObj, namePtr);
+	    }
+	}
+    }
+    Tcl_SetObjResult(interp, resultObj);
+    return TCL_OK;
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * InfoObjectMethodTypeCmd --
+ *
+ *	Implements [info object methodtype $objName $methodName]
+ *
+ * ----------------------------------------------------------------------
+ */
+
+static int
+InfoObjectMethodTypeCmd(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const objv[])
+{
+    Object *oPtr;
+    Tcl_HashEntry *hPtr;
+    Method *mPtr;
+
+    if (objc != 3) {
+	Tcl_WrongNumArgs(interp, 1, objv, "objName methodName");
+	return TCL_ERROR;
+    }
+
+    oPtr = (Object *) Tcl_GetObjectFromObj(interp, objv[1]);
+    if (oPtr == NULL) {
+	return TCL_ERROR;
+    }
+
+    if (!oPtr->methodsPtr) {
+	goto unknownMethod;
+    }
+    hPtr = Tcl_FindHashEntry(oPtr->methodsPtr, (char *) objv[2]);
+    if (hPtr == NULL) {
+    unknownMethod:
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		"unknown method \"%s\"", TclGetString(objv[2])));
+	Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "METHOD",
+		TclGetString(objv[2]), NULL);
+	return TCL_ERROR;
+    }
+    mPtr = Tcl_GetHashValue(hPtr);
+    if (mPtr->typePtr == NULL) {
+	/*
+	 * Special entry for visibility control: pretend the method doesnt
+	 * exist.
+	 */
+
+	goto unknownMethod;
+    }
+
+    Tcl_SetObjResult(interp, Tcl_NewStringObj(mPtr->typePtr->name, -1));
+    return TCL_OK;
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * InfoObjectMixinsCmd --
+ *
+ *	Implements [info object mixins $objName]
+ *
+ * ----------------------------------------------------------------------
+ */
+
+static int
+InfoObjectMixinsCmd(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const objv[])
+{
+    Class *mixinPtr;
+    Object *oPtr;
+    Tcl_Obj *resultObj;
+    int i;
+
+    if (objc != 2) {
+	Tcl_WrongNumArgs(interp, 1, objv, "objName");
+	return TCL_ERROR;
+    }
+    oPtr = (Object *) Tcl_GetObjectFromObj(interp, objv[1]);
+    if (oPtr == NULL) {
+	return TCL_ERROR;
+    }
+
+    resultObj = Tcl_NewObj();
+    FOREACH(mixinPtr, oPtr->mixins) {
+	if (!mixinPtr) {
+	    continue;
+	}
+	Tcl_ListObjAppendElement(NULL, resultObj,
+		TclOOObjectName(interp, mixinPtr->thisPtr));
+    }
+    Tcl_SetObjResult(interp, resultObj);
+    return TCL_OK;
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * InfoObjectNsCmd --
+ *
+ *	Implements [info object namespace $objName]
+ *
+ * ----------------------------------------------------------------------
+ */
+
+static int
+InfoObjectNsCmd(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const objv[])
+{
+    Object *oPtr;
+
+    if (objc != 2) {
+	Tcl_WrongNumArgs(interp, 1, objv, "objName");
+	return TCL_ERROR;
+    }
+    oPtr = (Object *) Tcl_GetObjectFromObj(interp, objv[1]);
+    if (oPtr == NULL) {
+	return TCL_ERROR;
+    }
+
+    Tcl_SetObjResult(interp,
+	    Tcl_NewStringObj(oPtr->namespacePtr->fullName, -1));
+    return TCL_OK;
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * InfoObjectVariablesCmd --
+ *
+ *	Implements [info object variables $objName]
+ *
+ * ----------------------------------------------------------------------
+ */
+
+static int
+InfoObjectVariablesCmd(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const objv[])
+{
+    Object *oPtr;
+    Tcl_Obj *variableObj, *resultObj;
+    int i;
+
+    if (objc != 2) {
+	Tcl_WrongNumArgs(interp, 1, objv, "objName");
+	return TCL_ERROR;
+    }
+    oPtr = (Object *) Tcl_GetObjectFromObj(interp, objv[1]);
+    if (oPtr == NULL) {
+	return TCL_ERROR;
+    }
+
+    resultObj = Tcl_NewObj();
+    FOREACH(variableObj, oPtr->variables) {
+	Tcl_ListObjAppendElement(NULL, resultObj, variableObj);
+    }
+    Tcl_SetObjResult(interp, resultObj);
+    return TCL_OK;
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * InfoObjectVarsCmd --
+ *
+ *	Implements [info object vars $objName ?$pattern?]
+ *
+ * ----------------------------------------------------------------------
+ */
+
+static int
+InfoObjectVarsCmd(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const objv[])
+{
+    Object *oPtr;
+    const char *pattern = NULL;
+    FOREACH_HASH_DECLS;
+    VarInHash *vihPtr;
+    Tcl_Obj *nameObj, *resultObj;
+
+    if (objc != 2 && objc != 3) {
+	Tcl_WrongNumArgs(interp, 1, objv, "objName ?pattern?");
+	return TCL_ERROR;
+    }
+    oPtr = (Object *) Tcl_GetObjectFromObj(interp, objv[1]);
+    if (oPtr == NULL) {
+	return TCL_ERROR;
+    }
+    if (objc == 3) {
+	pattern = TclGetString(objv[2]);
+    }
+    resultObj = Tcl_NewObj();
+
+    /*
+     * Extract the information we need from the object's namespace's table of
+     * variables. Note that this involves horrific knowledge of the guts of
+     * tclVar.c, so we can't leverage our hash-iteration macros properly.
+     */
+
+    FOREACH_HASH_VALUE(vihPtr,
+	    &((Namespace *) oPtr->namespacePtr)->varTable.table) {
+	nameObj = vihPtr->entry.key.objPtr;
+
+	if (TclIsVarUndefined(&vihPtr->var)
+		|| !TclIsVarNamespaceVar(&vihPtr->var)) {
+	    continue;
+	}
+	if (pattern != NULL
+		&& !Tcl_StringMatch(TclGetString(nameObj), pattern)) {
+	    continue;
+	}
+	Tcl_ListObjAppendElement(NULL, resultObj, nameObj);
+    }
+
+    Tcl_SetObjResult(interp, resultObj);
+    return TCL_OK;
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * InfoClassConstrCmd --
+ *
+ *	Implements [info class constructor $clsName]
+ *
+ * ----------------------------------------------------------------------
+ */
+
+static int
+InfoClassConstrCmd(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const objv[])
+{
+    Proc *procPtr;
+    CompiledLocal *localPtr;
+    Tcl_Obj *resultObjs[2];
+    Class *clsPtr;
+
+    if (objc != 2) {
+	Tcl_WrongNumArgs(interp, 1, objv, "className");
+	return TCL_ERROR;
+    }
+    clsPtr = GetClassFromObj(interp, objv[1]);
+    if (clsPtr == NULL) {
+	return TCL_ERROR;
+    }
+    if (clsPtr->constructorPtr == NULL) {
+	return TCL_OK;
+    }
+    procPtr = TclOOGetProcFromMethod(clsPtr->constructorPtr);
+    if (procPtr == NULL) {
+	Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		"definition not available for this kind of method", -1));
+	Tcl_SetErrorCode(interp, "TCL", "OO", "METHOD_TYPE", NULL);
+	return TCL_ERROR;
+    }
+
+    resultObjs[0] = Tcl_NewObj();
+    for (localPtr=procPtr->firstLocalPtr; localPtr!=NULL;
+	    localPtr=localPtr->nextPtr) {
+	if (TclIsVarArgument(localPtr)) {
+	    Tcl_Obj *argObj;
+
+	    argObj = Tcl_NewObj();
+	    Tcl_ListObjAppendElement(NULL, argObj,
+		    Tcl_NewStringObj(localPtr->name, -1));
+	    if (localPtr->defValuePtr != NULL) {
+		Tcl_ListObjAppendElement(NULL, argObj, localPtr->defValuePtr);
+	    }
+	    Tcl_ListObjAppendElement(NULL, resultObjs[0], argObj);
+	}
+    }
+    resultObjs[1] = TclOOGetMethodBody(clsPtr->constructorPtr);
+    Tcl_SetObjResult(interp, Tcl_NewListObj(2, resultObjs));
+    return TCL_OK;
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * InfoClassDefnCmd --
+ *
+ *	Implements [info class definition $clsName $methodName]
+ *
+ * ----------------------------------------------------------------------
+ */
+
+static int
+InfoClassDefnCmd(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const objv[])
+{
+    Tcl_HashEntry *hPtr;
+    Proc *procPtr;
+    CompiledLocal *localPtr;
+    Tcl_Obj *resultObjs[2];
+    Class *clsPtr;
+
+    if (objc != 3) {
+	Tcl_WrongNumArgs(interp, 1, objv, "className methodName");
+	return TCL_ERROR;
+    }
+    clsPtr = GetClassFromObj(interp, objv[1]);
+    if (clsPtr == NULL) {
+	return TCL_ERROR;
+    }
+    hPtr = Tcl_FindHashEntry(&clsPtr->classMethods, (char *) objv[2]);
+    if (hPtr == NULL) {
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		"unknown method \"%s\"", TclGetString(objv[2])));
+	Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "METHOD",
+		TclGetString(objv[2]), NULL);
+	return TCL_ERROR;
+    }
+    procPtr = TclOOGetProcFromMethod(Tcl_GetHashValue(hPtr));
+    if (procPtr == NULL) {
+	Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		"definition not available for this kind of method", -1));
+	Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "METHOD",
+		TclGetString(objv[2]), NULL);
+	return TCL_ERROR;
+    }
+
+    resultObjs[0] = Tcl_NewObj();
+    for (localPtr=procPtr->firstLocalPtr; localPtr!=NULL;
+	    localPtr=localPtr->nextPtr) {
+	if (TclIsVarArgument(localPtr)) {
+	    Tcl_Obj *argObj;
+
+	    argObj = Tcl_NewObj();
+	    Tcl_ListObjAppendElement(NULL, argObj,
+		    Tcl_NewStringObj(localPtr->name, -1));
+	    if (localPtr->defValuePtr != NULL) {
+		Tcl_ListObjAppendElement(NULL, argObj, localPtr->defValuePtr);
+	    }
+	    Tcl_ListObjAppendElement(NULL, resultObjs[0], argObj);
+	}
+    }
+    resultObjs[1] = TclOOGetMethodBody(Tcl_GetHashValue(hPtr));
+    Tcl_SetObjResult(interp, Tcl_NewListObj(2, resultObjs));
+    return TCL_OK;
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * InfoClassDestrCmd --
+ *
+ *	Implements [info class destructor $clsName]
+ *
+ * ----------------------------------------------------------------------
+ */
+
+static int
+InfoClassDestrCmd(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const objv[])
+{
+    Proc *procPtr;
+    Class *clsPtr;
+
+    if (objc != 2) {
+	Tcl_WrongNumArgs(interp, 1, objv, "className");
+	return TCL_ERROR;
+    }
+    clsPtr = GetClassFromObj(interp, objv[1]);
+    if (clsPtr == NULL) {
+	return TCL_ERROR;
+    }
+
+    if (clsPtr->destructorPtr == NULL) {
+	return TCL_OK;
+    }
+    procPtr = TclOOGetProcFromMethod(clsPtr->destructorPtr);
+    if (procPtr == NULL) {
+	Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		"definition not available for this kind of method", -1));
+	Tcl_SetErrorCode(interp, "TCL", "OO", "METHOD_TYPE", NULL);
+	return TCL_ERROR;
+    }
+
+    Tcl_SetObjResult(interp, TclOOGetMethodBody(clsPtr->destructorPtr));
+    return TCL_OK;
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * InfoClassFiltersCmd --
+ *
+ *	Implements [info class filters $clsName]
+ *
+ * ----------------------------------------------------------------------
+ */
+
+static int
+InfoClassFiltersCmd(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const objv[])
+{
+    int i;
+    Tcl_Obj *filterObj, *resultObj;
+    Class *clsPtr;
+
+    if (objc != 2) {
+	Tcl_WrongNumArgs(interp, 1, objv, "className");
+	return TCL_ERROR;
+    }
+    clsPtr = GetClassFromObj(interp, objv[1]);
+    if (clsPtr == NULL) {
+	return TCL_ERROR;
+    }
+
+    resultObj = Tcl_NewObj();
+    FOREACH(filterObj, clsPtr->filters) {
+	Tcl_ListObjAppendElement(NULL, resultObj, filterObj);
+    }
+    Tcl_SetObjResult(interp, resultObj);
+    return TCL_OK;
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * InfoClassForwardCmd --
+ *
+ *	Implements [info class forward $clsName $methodName]
+ *
+ * ----------------------------------------------------------------------
+ */
+
+static int
+InfoClassForwardCmd(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const objv[])
+{
+    Tcl_HashEntry *hPtr;
+    Tcl_Obj *prefixObj;
+    Class *clsPtr;
+
+    if (objc != 3) {
+	Tcl_WrongNumArgs(interp, 1, objv, "className methodName");
+	return TCL_ERROR;
+    }
+    clsPtr = GetClassFromObj(interp, objv[1]);
+    if (clsPtr == NULL) {
+	return TCL_ERROR;
+    }
+    hPtr = Tcl_FindHashEntry(&clsPtr->classMethods, (char *) objv[2]);
+    if (hPtr == NULL) {
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		"unknown method \"%s\"", TclGetString(objv[2])));
+	Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "METHOD",
+		TclGetString(objv[2]), NULL);
+	return TCL_ERROR;
+    }
+    prefixObj = TclOOGetFwdFromMethod(Tcl_GetHashValue(hPtr));
+    if (prefixObj == NULL) {
+	Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		"prefix argument list not available for this kind of method",
+		-1));
+	Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "METHOD",
+		TclGetString(objv[2]), NULL);
+	return TCL_ERROR;
+    }
+
+    Tcl_SetObjResult(interp, prefixObj);
+    return TCL_OK;
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * InfoClassInstancesCmd --
+ *
+ *	Implements [info class instances $clsName ?$pattern?]
+ *
+ * ----------------------------------------------------------------------
+ */
+
+static int
+InfoClassInstancesCmd(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const objv[])
+{
+    Object *oPtr;
+    Class *clsPtr;
+    int i;
+    const char *pattern = NULL;
+    Tcl_Obj *resultObj;
+
+    if (objc != 2 && objc != 3) {
+	Tcl_WrongNumArgs(interp, 1, objv, "className ?pattern?");
+	return TCL_ERROR;
+    }
+    clsPtr = GetClassFromObj(interp, objv[1]);
+    if (clsPtr == NULL) {
+	return TCL_ERROR;
+    }
+    if (objc == 3) {
+	pattern = TclGetString(objv[2]);
+    }
+
+    resultObj = Tcl_NewObj();
+    FOREACH(oPtr, clsPtr->instances) {
+	Tcl_Obj *tmpObj = TclOOObjectName(interp, oPtr);
+
+	if (pattern && !Tcl_StringMatch(TclGetString(tmpObj), pattern)) {
+	    continue;
+	}
+	Tcl_ListObjAppendElement(NULL, resultObj, tmpObj);
+    }
+    Tcl_SetObjResult(interp, resultObj);
+    return TCL_OK;
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * InfoClassMethodsCmd --
+ *
+ *	Implements [info class methods $clsName ?-private?]
+ *
+ * ----------------------------------------------------------------------
+ */
+
+static int
+InfoClassMethodsCmd(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const objv[])
+{
+    int flag = PUBLIC_METHOD, recurse = 0;
+    Tcl_Obj *namePtr, *resultObj;
+    Method *mPtr;
+    Class *clsPtr;
+    static const char *const options[] = {
+	"-all", "-localprivate", "-private", NULL
+    };
+    enum Options {
+	OPT_ALL, OPT_LOCALPRIVATE, OPT_PRIVATE
+    };
+
+    if (objc < 2) {
+	Tcl_WrongNumArgs(interp, 1, objv, "className ?-option value ...?");
+	return TCL_ERROR;
+    }
+    clsPtr = GetClassFromObj(interp, objv[1]);
+    if (clsPtr == NULL) {
+	return TCL_ERROR;
+    }
+    if (objc != 2) {
+	int i, idx;
+
+	for (i=2 ; i<objc ; i++) {
+	    if (Tcl_GetIndexFromObj(interp, objv[i], options, "option", 0,
+		    &idx) != TCL_OK) {
+		return TCL_ERROR;
+	    }
+	    switch ((enum Options) idx) {
+	    case OPT_ALL:
+		recurse = 1;
+		break;
+	    case OPT_LOCALPRIVATE:
+		flag = PRIVATE_METHOD;
+		break;
+	    case OPT_PRIVATE:
+		flag = 0;
+		break;
+	    }
+	}
+    }
+
+    resultObj = Tcl_NewObj();
+    if (recurse) {
+	const char **names;
+	int i, numNames = TclOOGetSortedClassMethodList(clsPtr, flag, &names);
+
+	for (i=0 ; i<numNames ; i++) {
+	    Tcl_ListObjAppendElement(NULL, resultObj,
+		    Tcl_NewStringObj(names[i], -1));
+	}
+	if (numNames > 0) {
+	    ckfree(names);
+	}
+    } else {
+	FOREACH_HASH_DECLS;
+
+	FOREACH_HASH(namePtr, mPtr, &clsPtr->classMethods) {
+	    if (mPtr->typePtr != NULL && (mPtr->flags & flag) == flag) {
+		Tcl_ListObjAppendElement(NULL, resultObj, namePtr);
+	    }
+	}
+    }
+    Tcl_SetObjResult(interp, resultObj);
+    return TCL_OK;
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * InfoClassMethodTypeCmd --
+ *
+ *	Implements [info class methodtype $clsName $methodName]
+ *
+ * ----------------------------------------------------------------------
+ */
+
+static int
+InfoClassMethodTypeCmd(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const objv[])
+{
+    Tcl_HashEntry *hPtr;
+    Method *mPtr;
+    Class *clsPtr;
+
+    if (objc != 3) {
+	Tcl_WrongNumArgs(interp, 1, objv, "className methodName");
+	return TCL_ERROR;
+    }
+    clsPtr = GetClassFromObj(interp, objv[1]);
+    if (clsPtr == NULL) {
+	return TCL_ERROR;
+    }
+
+    hPtr = Tcl_FindHashEntry(&clsPtr->classMethods, (char *) objv[2]);
+    if (hPtr == NULL) {
+    unknownMethod:
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		"unknown method \"%s\"", TclGetString(objv[2])));
+	Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "METHOD",
+		TclGetString(objv[2]), NULL);
+	return TCL_ERROR;
+    }
+    mPtr = Tcl_GetHashValue(hPtr);
+    if (mPtr->typePtr == NULL) {
+	/*
+	 * Special entry for visibility control: pretend the method doesnt
+	 * exist.
+	 */
+
+	goto unknownMethod;
+    }
+    Tcl_SetObjResult(interp, Tcl_NewStringObj(mPtr->typePtr->name, -1));
+    return TCL_OK;
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * InfoClassMixinsCmd --
+ *
+ *	Implements [info class mixins $clsName]
+ *
+ * ----------------------------------------------------------------------
+ */
+
+static int
+InfoClassMixinsCmd(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const objv[])
+{
+    Class *clsPtr, *mixinPtr;
+    Tcl_Obj *resultObj;
+    int i;
+
+    if (objc != 2) {
+	Tcl_WrongNumArgs(interp, 1, objv, "className");
+	return TCL_ERROR;
+    }
+    clsPtr = GetClassFromObj(interp, objv[1]);
+    if (clsPtr == NULL) {
+	return TCL_ERROR;
+    }
+
+    resultObj = Tcl_NewObj();
+    FOREACH(mixinPtr, clsPtr->mixins) {
+	if (!mixinPtr) {
+	    continue;
+	}
+	Tcl_ListObjAppendElement(NULL, resultObj,
+		TclOOObjectName(interp, mixinPtr->thisPtr));
+    }
+    Tcl_SetObjResult(interp, resultObj);
+    return TCL_OK;
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * InfoClassSubsCmd --
+ *
+ *	Implements [info class subclasses $clsName ?$pattern?]
+ *
+ * ----------------------------------------------------------------------
+ */
+
+static int
+InfoClassSubsCmd(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const objv[])
+{
+    Class *clsPtr, *subclassPtr;
+    Tcl_Obj *resultObj;
+    int i;
+    const char *pattern = NULL;
+
+    if (objc != 2 && objc != 3) {
+	Tcl_WrongNumArgs(interp, 1, objv, "className ?pattern?");
+	return TCL_ERROR;
+    }
+    clsPtr = GetClassFromObj(interp, objv[1]);
+    if (clsPtr == NULL) {
+	return TCL_ERROR;
+    }
+    if (objc == 3) {
+	pattern = TclGetString(objv[2]);
+    }
+
+    resultObj = Tcl_NewObj();
+    FOREACH(subclassPtr, clsPtr->subclasses) {
+	Tcl_Obj *tmpObj = TclOOObjectName(interp, subclassPtr->thisPtr);
+
+	if (pattern && !Tcl_StringMatch(TclGetString(tmpObj), pattern)) {
+	    continue;
+	}
+	Tcl_ListObjAppendElement(NULL, resultObj, tmpObj);
+    }
+    FOREACH(subclassPtr, clsPtr->mixinSubs) {
+	Tcl_Obj *tmpObj = TclOOObjectName(interp, subclassPtr->thisPtr);
+
+	if (pattern && !Tcl_StringMatch(TclGetString(tmpObj), pattern)) {
+	    continue;
+	}
+	Tcl_ListObjAppendElement(NULL, resultObj, tmpObj);
+    }
+    Tcl_SetObjResult(interp, resultObj);
+    return TCL_OK;
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * InfoClassSupersCmd --
+ *
+ *	Implements [info class superclasses $clsName]
+ *
+ * ----------------------------------------------------------------------
+ */
+
+static int
+InfoClassSupersCmd(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const objv[])
+{
+    Class *clsPtr, *superPtr;
+    Tcl_Obj *resultObj;
+    int i;
+
+    if (objc != 2) {
+	Tcl_WrongNumArgs(interp, 1, objv, "className");
+	return TCL_ERROR;
+    }
+    clsPtr = GetClassFromObj(interp, objv[1]);
+    if (clsPtr == NULL) {
+	return TCL_ERROR;
+    }
+
+    resultObj = Tcl_NewObj();
+    FOREACH(superPtr, clsPtr->superclasses) {
+	Tcl_ListObjAppendElement(NULL, resultObj,
+		TclOOObjectName(interp, superPtr->thisPtr));
+    }
+    Tcl_SetObjResult(interp, resultObj);
+    return TCL_OK;
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * InfoClassVariablesCmd --
+ *
+ *	Implements [info class variables $clsName]
+ *
+ * ----------------------------------------------------------------------
+ */
+
+static int
+InfoClassVariablesCmd(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const objv[])
+{
+    Class *clsPtr;
+    Tcl_Obj *variableObj, *resultObj;
+    int i;
+
+    if (objc != 2) {
+	Tcl_WrongNumArgs(interp, 1, objv, "className");
+	return TCL_ERROR;
+    }
+    clsPtr = GetClassFromObj(interp, objv[1]);
+    if (clsPtr == NULL) {
+	return TCL_ERROR;
+    }
+
+    resultObj = Tcl_NewObj();
+    FOREACH(variableObj, clsPtr->variables) {
+	Tcl_ListObjAppendElement(NULL, resultObj, variableObj);
+    }
+    Tcl_SetObjResult(interp, resultObj);
+    return TCL_OK;
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * InfoObjectCallCmd --
+ *
+ *	Implements [info object call $objName $methodName]
+ *
+ * ----------------------------------------------------------------------
+ */
+
+static int
+InfoObjectCallCmd(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const objv[])
+{
+    Object *oPtr;
+    CallContext *contextPtr;
+
+    if (objc != 3) {
+	Tcl_WrongNumArgs(interp, 1, objv, "objName methodName");
+	return TCL_ERROR;
+    }
+    oPtr = (Object *) Tcl_GetObjectFromObj(interp, objv[1]);
+    if (oPtr == NULL) {
+	return TCL_ERROR;
+    }
+
+    /*
+     * Get the call context and render its call chain.
+     */
+
+    contextPtr = TclOOGetCallContext(oPtr, objv[2], PUBLIC_METHOD, NULL);
+    if (contextPtr == NULL) {
+	Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		"cannot construct any call chain", -1));
+	return TCL_ERROR;
+    }
+    Tcl_SetObjResult(interp,
+	    TclOORenderCallChain(interp, contextPtr->callPtr));
+    TclOODeleteContext(contextPtr);
+    return TCL_OK;
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * InfoClassCallCmd --
+ *
+ *	Implements [info class call $clsName $methodName]
+ *
+ * ----------------------------------------------------------------------
+ */
+
+static int
+InfoClassCallCmd(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const objv[])
+{
+    Class *clsPtr;
+    CallChain *callPtr;
+
+    if (objc != 3) {
+	Tcl_WrongNumArgs(interp, 1, objv, "className methodName");
+	return TCL_ERROR;
+    }
+    clsPtr = GetClassFromObj(interp, objv[1]);
+    if (clsPtr == NULL) {
+	return TCL_ERROR;
+    }
+
+    /*
+     * Get an render the stereotypical call chain.
+     */
+
+    callPtr = TclOOGetStereotypeCallChain(clsPtr, objv[2], PUBLIC_METHOD);
+    if (callPtr == NULL) {
+	Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		"cannot construct any call chain", -1));
+	return TCL_ERROR;
+    }
+    Tcl_SetObjResult(interp, TclOORenderCallChain(interp, callPtr));
+    TclOODeleteChain(callPtr);
+    return TCL_OK;
+}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tclOOInt.h b/generic/tclOOInt.h
new file mode 100644
index 0000000..b75ffdb
--- /dev/null
+++ b/generic/tclOOInt.h
@@ -0,0 +1,607 @@
+/*
+ * tclOOInt.h --
+ *
+ *	This file contains the structure definitions and some of the function
+ *	declarations for the object-system (NB: not Tcl_Obj, but ::oo).
+ *
+ * Copyright (c) 2006-2012 by Donal K. Fellows
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#ifndef TCL_OO_INTERNAL_H
+#define TCL_OO_INTERNAL_H 1
+
+#include "tclInt.h"
+#include "tclOO.h"
+
+/*
+ * Hack to make things work with Objective C. Note that ObjC isn't really
+ * supported, but we don't want to to be actively hostile to it. [Bug 2163447]
+ */
+
+#ifdef __OBJC__
+#define Class	TclOOClass
+#define Object	TclOOObject
+#endif /* __OBJC__ */
+
+/*
+ * Forward declarations.
+ */
+
+struct CallChain;
+struct Class;
+struct Foundation;
+struct Object;
+
+/*
+ * The data that needs to be stored per method. This record is used to collect
+ * information about all sorts of methods, including forwards, constructors
+ * and destructors.
+ */
+
+typedef struct Method {
+    const Tcl_MethodType *typePtr;
+				/* The type of method. If NULL, this is a
+				 * special flag record which is just used for
+				 * the setting of the flags field. */
+    int refCount;
+    ClientData clientData;	/* Type-specific data. */
+    Tcl_Obj *namePtr;		/* Name of the method. */
+    struct Object *declaringObjectPtr;
+				/* The object that declares this method, or
+				 * NULL if it was declared by a class. */
+    struct Class *declaringClassPtr;
+				/* The class that declares this method, or
+				 * NULL if it was declared directly on an
+				 * object. */
+    int flags;			/* Assorted flags. Includes whether this
+				 * method is public/exported or not. */
+} Method;
+
+/*
+ * Pre- and post-call callbacks, to allow procedure-like methods to be fine
+ * tuned in their behaviour.
+ */
+
+typedef int (TclOO_PreCallProc)(ClientData clientData, Tcl_Interp *interp,
+	Tcl_ObjectContext context, Tcl_CallFrame *framePtr, int *isFinished);
+typedef int (TclOO_PostCallProc)(ClientData clientData, Tcl_Interp *interp,
+	Tcl_ObjectContext context, Tcl_Namespace *namespacePtr, int result);
+typedef void (TclOO_PmCDDeleteProc)(ClientData clientData);
+typedef ClientData (TclOO_PmCDCloneProc)(ClientData clientData);
+
+/*
+ * Procedure-like methods have the following extra information.
+ */
+
+typedef struct ProcedureMethod {
+    int version;		/* Version of this structure. Currently must
+				 * be 0. */
+    Proc *procPtr;		/* Core of the implementation of the method;
+				 * includes the argument definition and the
+				 * body bytecodes. */
+    int flags;			/* Flags to control features. */
+    int refCount;
+    ClientData clientData;
+    TclOO_PmCDDeleteProc *deleteClientdataProc;
+    TclOO_PmCDCloneProc *cloneClientdataProc;
+    ProcErrorProc *errProc;	/* Replacement error handler. */
+    TclOO_PreCallProc *preCallProc;
+				/* Callback to allow for additional setup
+				 * before the method executes. */
+    TclOO_PostCallProc *postCallProc;
+				/* Callback to allow for additional cleanup
+				 * after the method executes. */
+    GetFrameInfoValueProc *gfivProc;
+				/* Callback to allow for fine tuning of how
+				 * the method reports itself. */
+} ProcedureMethod;
+
+#define TCLOO_PROCEDURE_METHOD_VERSION 0
+
+/*
+ * Flags for use in a ProcedureMethod.
+ *
+ * When the USE_DECLARER_NS flag is set, the method will use the namespace of
+ * the object or class that declared it (or the clone of it, if it was from
+ * such that the implementation of the method came to the particular use)
+ * instead of the namespace of the object on which the method was invoked.
+ * This flag must be distinct from all others that are associated with
+ * methods.
+ */
+
+#define USE_DECLARER_NS		0x80
+
+/*
+ * Forwarded methods have the following extra information.
+ */
+
+typedef struct ForwardMethod {
+    Tcl_Obj *prefixObj;		/* The list of values to use to replace the
+				 * object and method name with. Will be a
+				 * non-empty list. */
+} ForwardMethod;
+
+/*
+ * Helper definitions that declare a "list" array. The two varieties are
+ * either optimized for simplicity (in the case that the whole array is
+ * typically assigned at once) or efficiency (in the case that the array is
+ * expected to be expanded over time). These lists are designed to be iterated
+ * over with the help of the FOREACH macro (see later in this file).
+ *
+ * The "num" field always counts the number of listType_t elements used in the
+ * "list" field. When a "size" field exists, it describes how many elements
+ * are present in the list; when absent, exactly "num" elements are present.
+ */
+
+#define LIST_STATIC(listType_t) \
+    struct { int num; listType_t *list; }
+#define LIST_DYNAMIC(listType_t) \
+    struct { int num, size; listType_t *list; }
+
+/*
+ * Now, the definition of what an object actually is.
+ */
+
+typedef struct Object {
+    struct Foundation *fPtr;	/* The basis for the object system. Putting
+				 * this here allows the avoidance of quite a
+				 * lot of hash lookups on the critical path
+				 * for object invokation and creation. */
+    Tcl_Namespace *namespacePtr;/* This object's tame namespace. */
+    Tcl_Command command;	/* Reference to this object's public
+				 * command. */
+    Tcl_Command myCommand;	/* Reference to this object's internal
+				 * command. */
+    struct Class *selfCls;	/* This object's class. */
+    Tcl_HashTable *methodsPtr;	/* Object-local Tcl_Obj (method name) to
+				 * Method* mapping. */
+    LIST_STATIC(struct Class *) mixins;
+				/* Classes mixed into this object. */
+    LIST_STATIC(Tcl_Obj *) filters;
+				/* List of filter names. */
+    struct Class *classPtr;	/* All classes have this non-NULL; it points
+				 * to the class structure. Everything else has
+				 * this NULL. */
+    int refCount;		/* Number of strong references to this object.
+				 * Note that there may be many more weak
+				 * references; this mechanism is there to
+				 * avoid Tcl_Preserve. */
+    int flags;
+    int creationEpoch;		/* Unique value to make comparisons of objects
+				 * easier. */
+    int epoch;			/* Per-object epoch, incremented when the way
+				 * an object should resolve call chains is
+				 * changed. */
+    Tcl_HashTable *metadataPtr;	/* Mapping from pointers to metadata type to
+				 * the ClientData values that are the values
+				 * of each piece of attached metadata. This
+				 * field starts out as NULL and is only
+				 * allocated if metadata is attached. */
+    Tcl_Obj *cachedNameObj;	/* Cache of the name of the object. */
+    Tcl_HashTable *chainCache;	/* Place to keep unused contexts. This table
+				 * is indexed by method name as Tcl_Obj. */
+    Tcl_ObjectMapMethodNameProc *mapMethodNameProc;
+				/* Function to allow remapping of method
+				 * names. For itcl-ng. */
+    LIST_STATIC(Tcl_Obj *) variables;
+} Object;
+
+#define OBJECT_DELETED	1	/* Flag to say that an object has been
+				 * destroyed. */
+#define DESTRUCTOR_CALLED 2	/* Flag to say that the destructor has been
+				 * called. */
+#define CLASS_GONE	4	/* Indicates that the class of this object has
+				 * been deleted, and so the object should not
+				 * attempt to remove itself from its class. */
+#define ROOT_OBJECT 0x1000	/* Flag to say that this object is the root of
+				 * the class hierarchy and should be treated
+				 * specially during teardown. */
+#define FILTER_HANDLING 0x2000	/* Flag set when the object is processing a
+				 * filter; when set, filters are *not*
+				 * processed on the object, preventing nasty
+				 * recursive filtering problems. */
+#define USE_CLASS_CACHE 0x4000	/* Flag set to say that the object is a pure
+				 * instance of the class, and has had nothing
+				 * added that changes the dispatch chain (i.e.
+				 * no methods, mixins, or filters. */
+#define ROOT_CLASS 0x8000	/* Flag to say that this object is the root
+				 * class of classes, and should be treated
+				 * specially during teardown (and in a few
+				 * other spots). */
+#define FORCE_UNKNOWN 0x10000	/* States that we are *really* looking up the
+				 * unknown method handler at that point. */
+
+/*
+ * And the definition of a class. Note that every class also has an associated
+ * object, through which it is manipulated.
+ */
+
+typedef struct Class {
+    Object *thisPtr;		/* Reference to the object associated with
+				 * this class. */
+    int refCount;		/* Number of strong references to this class.
+				 * Weak references are not counted; the
+				 * purpose of this is to avoid Tcl_Preserve as
+				 * that is quite slow. */
+    int flags;			/* Assorted flags. */
+    LIST_STATIC(struct Class *) superclasses;
+				/* List of superclasses, used for generation
+				 * of method call chains. */
+    LIST_DYNAMIC(struct Class *) subclasses;
+				/* List of subclasses, used to ensure deletion
+				 * of dependent entities happens properly when
+				 * the class itself is deleted. */
+    LIST_DYNAMIC(Object *) instances;
+				/* List of instances, used to ensure deletion
+				 * of dependent entities happens properly when
+				 * the class itself is deleted. */
+    LIST_STATIC(Tcl_Obj *) filters;
+				/* List of filter names, used for generation
+				 * of method call chains. */
+    LIST_STATIC(struct Class *) mixins;
+				/* List of mixin classes, used for generation
+				 * of method call chains. */
+    LIST_DYNAMIC(struct Class *) mixinSubs;
+				/* List of classes that this class is mixed
+				 * into, used to ensure deletion of dependent
+				 * entities happens properly when the class
+				 * itself is deleted. */
+    Tcl_HashTable classMethods;	/* Hash table of all methods. Hash maps from
+				 * the (Tcl_Obj*) method name to the (Method*)
+				 * method record. */
+    Method *constructorPtr;	/* Method record of the class constructor (if
+				 * any). */
+    Method *destructorPtr;	/* Method record of the class destructor (if
+				 * any). */
+    Tcl_HashTable *metadataPtr;	/* Mapping from pointers to metadata type to
+				 * the ClientData values that are the values
+				 * of each piece of attached metadata. This
+				 * field starts out as NULL and is only
+				 * allocated if metadata is attached. */
+    struct CallChain *constructorChainPtr;
+    struct CallChain *destructorChainPtr;
+    Tcl_HashTable *classChainCache;
+				/* Places where call chains are stored. For
+				 * constructors, the class chain is always
+				 * used. For destructors and ordinary methods,
+				 * the class chain is only used when the
+				 * object doesn't override with its own mixins
+				 * (and filters and method implementations for
+				 * when getting method chains). */
+    LIST_STATIC(Tcl_Obj *) variables;
+} Class;
+
+/*
+ * The foundation of the object system within an interpreter contains
+ * references to the key classes and namespaces, together with a few other
+ * useful bits and pieces. Probably ought to eventually go in the Interp
+ * structure itself.
+ */
+
+typedef struct ThreadLocalData {
+    int nsCount;		/* Master epoch counter is used for keeping
+				 * the values used in Tcl_Obj internal
+				 * representations sane. Must be thread-local
+				 * because Tcl_Objs can cross interpreter
+				 * boundaries within a thread (objects don't
+				 * generally cross threads). */
+} ThreadLocalData;
+
+typedef struct Foundation {
+    Tcl_Interp *interp;
+    Class *objectCls;		/* The root of the object system. */
+    Class *classCls;		/* The class of all classes. */
+    Tcl_Namespace *ooNs;	/* Master ::oo namespace. */
+    Tcl_Namespace *defineNs;	/* Namespace containing special commands for
+				 * manipulating objects and classes. The
+				 * "oo::define" command acts as a special kind
+				 * of ensemble for this namespace. */
+    Tcl_Namespace *objdefNs;	/* Namespace containing special commands for
+				 * manipulating objects and classes. The
+				 * "oo::objdefine" command acts as a special
+				 * kind of ensemble for this namespace. */
+    Tcl_Namespace *helpersNs;	/* Namespace containing the commands that are
+				 * only valid when executing inside a
+				 * procedural method. */
+    int epoch;			/* Used to invalidate method chains when the
+				 * class structure changes. */
+    ThreadLocalData *tsdPtr;	/* Counter so we can allocate a unique
+				 * namespace to each object. */
+    Tcl_Obj *unknownMethodNameObj;
+				/* Shared object containing the name of the
+				 * unknown method handler method. */
+    Tcl_Obj *constructorName;	/* Shared object containing the "name" of a
+				 * constructor. */
+    Tcl_Obj *destructorName;	/* Shared object containing the "name" of a
+				 * destructor. */
+    Tcl_Obj *clonedName;	/* Shared object containing the name of a
+				 * "<cloned>" pseudo-constructor. */
+    Tcl_Obj *defineName;	/* Fully qualified name of oo::define. */
+} Foundation;
+
+/*
+ * A call context structure is built when a method is called. They contain the
+ * chain of method implementations that are to be invoked by a particular
+ * call, and the process of calling walks the chain, with the [next] command
+ * proceeding to the next entry in the chain.
+ */
+
+#define CALL_CHAIN_STATIC_SIZE 4
+
+struct MInvoke {
+    Method *mPtr;		/* Reference to the method implementation
+				 * record. */
+    int isFilter;		/* Whether this is a filter invokation. */
+    Class *filterDeclarer;	/* What class decided to add the filter; if
+				 * NULL, it was added by the object. */
+};
+
+typedef struct CallChain {
+    int objectCreationEpoch;	/* The object's creation epoch. Note that the
+				 * object reference is not stored in the call
+				 * chain; it is in the call context. */
+    int objectEpoch;		/* Local (object structure) epoch counter
+				 * snapshot. */
+    int epoch;			/* Global (class structure) epoch counter
+				 * snapshot. */
+    int flags;			/* Assorted flags, see below. */
+    int refCount;		/* Reference count. */
+    int numChain;		/* Size of the call chain. */
+    struct MInvoke *chain;	/* Array of call chain entries. May point to
+				 * staticChain if the number of entries is
+				 * small. */
+    struct MInvoke staticChain[CALL_CHAIN_STATIC_SIZE];
+} CallChain;
+
+typedef struct CallContext {
+    Object *oPtr;		/* The object associated with this call. */
+    int index;			/* Index into the call chain of the currently
+				 * executing method implementation. */
+    int skip;			/* Current number of arguments to skip; can
+				 * vary depending on whether it is a direct
+				 * method call or a continuation via the
+				 * [next] command. */
+    CallChain *callPtr;		/* The actual call chain. */
+} CallContext;
+
+/*
+ * Bits for the 'flags' field of the call chain.
+ */
+
+#define PUBLIC_METHOD     0x01	/* This is a public (exported) method. */
+#define PRIVATE_METHOD    0x02	/* This is a private (class's direct instances
+				 * only) method. */
+#define OO_UNKNOWN_METHOD 0x04	/* This is an unknown method. */
+#define CONSTRUCTOR	  0x08	/* This is a constructor. */
+#define DESTRUCTOR	  0x10	/* This is a destructor. */
+
+/*
+ * Structure containing definition information about basic class methods.
+ */
+
+typedef struct {
+    const char *name;		/* Name of the method in question. */
+    int isPublic;		/* Whether the method is public by default. */
+    Tcl_MethodType definition;	/* How to call the method. */
+} DeclaredClassMethod;
+
+/*
+ *----------------------------------------------------------------
+ * Commands relating to OO support.
+ *----------------------------------------------------------------
+ */
+
+MODULE_SCOPE int	TclOOInit(Tcl_Interp *interp);
+MODULE_SCOPE int	TclOODefineObjCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const *objv);
+MODULE_SCOPE int	TclOOObjDefObjCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const *objv);
+MODULE_SCOPE int	TclOODefineConstructorObjCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const *objv);
+MODULE_SCOPE int	TclOODefineDeleteMethodObjCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const *objv);
+MODULE_SCOPE int	TclOODefineDestructorObjCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const *objv);
+MODULE_SCOPE int	TclOODefineExportObjCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const *objv);
+MODULE_SCOPE int	TclOODefineForwardObjCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const *objv);
+MODULE_SCOPE int	TclOODefineMethodObjCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const *objv);
+MODULE_SCOPE int	TclOODefineRenameMethodObjCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const *objv);
+MODULE_SCOPE int	TclOODefineUnexportObjCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const *objv);
+MODULE_SCOPE int	TclOODefineClassObjCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const *objv);
+MODULE_SCOPE int	TclOODefineSelfObjCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const *objv);
+MODULE_SCOPE int	TclOOUnknownDefinition(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const *objv);
+MODULE_SCOPE int	TclOOCopyObjectCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const *objv);
+MODULE_SCOPE int	TclOONextObjCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const *objv);
+MODULE_SCOPE int	TclOONextToObjCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const *objv);
+MODULE_SCOPE int	TclOOSelfObjCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const *objv);
+
+/*
+ * Method implementations (in tclOOBasic.c).
+ */
+
+MODULE_SCOPE int	TclOO_Class_Constructor(ClientData clientData,
+			    Tcl_Interp *interp, Tcl_ObjectContext context,
+			    int objc, Tcl_Obj *const *objv);
+MODULE_SCOPE int	TclOO_Class_Create(ClientData clientData,
+			    Tcl_Interp *interp, Tcl_ObjectContext context,
+			    int objc, Tcl_Obj *const *objv);
+MODULE_SCOPE int	TclOO_Class_CreateNs(ClientData clientData,
+			    Tcl_Interp *interp, Tcl_ObjectContext context,
+			    int objc, Tcl_Obj *const *objv);
+MODULE_SCOPE int	TclOO_Class_New(ClientData clientData,
+			    Tcl_Interp *interp, Tcl_ObjectContext context,
+			    int objc, Tcl_Obj *const *objv);
+MODULE_SCOPE int	TclOO_Object_Destroy(ClientData clientData,
+			    Tcl_Interp *interp, Tcl_ObjectContext context,
+			    int objc, Tcl_Obj *const *objv);
+MODULE_SCOPE int	TclOO_Object_Eval(ClientData clientData,
+			    Tcl_Interp *interp, Tcl_ObjectContext context,
+			    int objc, Tcl_Obj *const *objv);
+MODULE_SCOPE int	TclOO_Object_LinkVar(ClientData clientData,
+			    Tcl_Interp *interp, Tcl_ObjectContext context,
+			    int objc, Tcl_Obj *const *objv);
+MODULE_SCOPE int	TclOO_Object_Unknown(ClientData clientData,
+			    Tcl_Interp *interp, Tcl_ObjectContext context,
+			    int objc, Tcl_Obj *const *objv);
+MODULE_SCOPE int	TclOO_Object_VarName(ClientData clientData,
+			    Tcl_Interp *interp, Tcl_ObjectContext context,
+			    int objc, Tcl_Obj *const *objv);
+
+/*
+ * Private definitions, some of which perhaps ought to be exposed properly or
+ * maybe just put in the internal stubs table.
+ */
+
+MODULE_SCOPE void	TclOOAddToInstances(Object *oPtr, Class *clsPtr);
+MODULE_SCOPE void	TclOOAddToMixinSubs(Class *subPtr, Class *mixinPtr);
+MODULE_SCOPE void	TclOOAddToSubclasses(Class *subPtr, Class *superPtr);
+MODULE_SCOPE int	TclNRNewObjectInstance(Tcl_Interp *interp,
+			    Tcl_Class cls, const char *nameStr,
+			    const char *nsNameStr, int objc,
+			    Tcl_Obj *const *objv, int skip,
+			    Tcl_Object *objectPtr);
+MODULE_SCOPE int	TclOODefineSlots(Foundation *fPtr);
+MODULE_SCOPE void	TclOODeleteChain(CallChain *callPtr);
+MODULE_SCOPE void	TclOODeleteChainCache(Tcl_HashTable *tablePtr);
+MODULE_SCOPE void	TclOODeleteContext(CallContext *contextPtr);
+MODULE_SCOPE void	TclOODelMethodRef(Method *method);
+MODULE_SCOPE CallContext *TclOOGetCallContext(Object *oPtr,
+			    Tcl_Obj *methodNameObj, int flags,
+			    Tcl_Obj *cacheInThisObj);
+MODULE_SCOPE CallChain *TclOOGetStereotypeCallChain(Class *clsPtr,
+			    Tcl_Obj *methodNameObj, int flags);
+MODULE_SCOPE Foundation	*TclOOGetFoundation(Tcl_Interp *interp);
+MODULE_SCOPE Tcl_Obj *	TclOOGetFwdFromMethod(Method *mPtr);
+MODULE_SCOPE Proc *	TclOOGetProcFromMethod(Method *mPtr);
+MODULE_SCOPE Tcl_Obj *	TclOOGetMethodBody(Method *mPtr);
+MODULE_SCOPE int	TclOOGetSortedClassMethodList(Class *clsPtr,
+			    int flags, const char ***stringsPtr);
+MODULE_SCOPE int	TclOOGetSortedMethodList(Object *oPtr, int flags,
+			    const char ***stringsPtr);
+MODULE_SCOPE int	TclOOInit(Tcl_Interp *interp);
+MODULE_SCOPE void	TclOOInitInfo(Tcl_Interp *interp);
+MODULE_SCOPE int	TclOOInvokeContext(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+MODULE_SCOPE int	TclNRObjectContextInvokeNext(Tcl_Interp *interp,
+			    Tcl_ObjectContext context, int objc,
+			    Tcl_Obj *const *objv, int skip);
+MODULE_SCOPE void	TclOONewBasicMethod(Tcl_Interp *interp, Class *clsPtr,
+			    const DeclaredClassMethod *dcm);
+MODULE_SCOPE Tcl_Obj *	TclOOObjectName(Tcl_Interp *interp, Object *oPtr);
+MODULE_SCOPE void	TclOORemoveFromInstances(Object *oPtr, Class *clsPtr);
+MODULE_SCOPE void	TclOORemoveFromMixinSubs(Class *subPtr,
+			    Class *mixinPtr);
+MODULE_SCOPE void	TclOORemoveFromSubclasses(Class *subPtr,
+			    Class *superPtr);
+MODULE_SCOPE Tcl_Obj *	TclOORenderCallChain(Tcl_Interp *interp,
+			    CallChain *callPtr);
+MODULE_SCOPE void	TclOOStashContext(Tcl_Obj *objPtr,
+			    CallContext *contextPtr);
+MODULE_SCOPE void	TclOOSetupVariableResolver(Tcl_Namespace *nsPtr);
+
+/*
+ * Include all the private API, generated from tclOO.decls.
+ */
+
+#include "tclOOIntDecls.h"
+
+/*
+ * A convenience macro for iterating through the lists used in the internal
+ * memory management of objects. This is a bit gnarly because we want to do
+ * the assignment of the picked-out value only when the body test succeeds,
+ * but we cannot rely on the assigned value being useful, forcing us to do
+ * some nasty stuff with the comma operator. The compiler's optimizer should
+ * be able to sort it all out!
+ *
+ * REQUIRES DECLARATION: int i;
+ */
+
+#define FOREACH(var,ary) \
+	for(i=0 ; (i<(ary).num?((var=(ary).list[i]),1):0) ; i++)
+
+/*
+ * Convenience macros for iterating through hash tables. FOREACH_HASH_DECLS
+ * sets up the declarations needed for the main macro, FOREACH_HASH, which
+ * does the actual iteration. FOREACH_HASH_VALUE is a restricted version that
+ * only iterates over values.
+ */
+
+#define FOREACH_HASH_DECLS \
+    Tcl_HashEntry *hPtr;Tcl_HashSearch search
+#define FOREACH_HASH(key,val,tablePtr) \
+    for(hPtr=Tcl_FirstHashEntry((tablePtr),&search); hPtr!=NULL ? \
+	    ((key)=(void *)Tcl_GetHashKey((tablePtr),hPtr),\
+	    (val)=Tcl_GetHashValue(hPtr),1):0; hPtr=Tcl_NextHashEntry(&search))
+#define FOREACH_HASH_VALUE(val,tablePtr) \
+    for(hPtr=Tcl_FirstHashEntry((tablePtr),&search); hPtr!=NULL ? \
+	    ((val)=Tcl_GetHashValue(hPtr),1):0;hPtr=Tcl_NextHashEntry(&search))
+
+/*
+ * Convenience macro for duplicating a list. Needs no external declaration,
+ * but all arguments are used multiple times and so must have no side effects.
+ */
+
+#undef DUPLICATE /* prevent possible conflict with definition in WINAPI nb30.h */
+#define DUPLICATE(target,source,type) \
+    do { \
+	register unsigned len = sizeof(type) * ((target).num=(source).num);\
+	if (len != 0) { \
+	    memcpy(((target).list=(type*)ckalloc(len)), (source).list, len); \
+	} else { \
+	    (target).list = NULL; \
+	} \
+    } while(0)
+
+/*
+ * Alternatives to Tcl_Preserve/Tcl_EventuallyFree/Tcl_Release.
+ */
+
+#define AddRef(ptr) ((ptr)->refCount++)
+#define DelRef(ptr) do {			\
+	if ((ptr)->refCount-- <= 1) {		\
+	    ckfree((char *) (ptr));		\
+	}					\
+    } while(0)
+
+#endif /* TCL_OO_INTERNAL_H */
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tclOOIntDecls.h b/generic/tclOOIntDecls.h
new file mode 100644
index 0000000..74a8d81
--- /dev/null
+++ b/generic/tclOOIntDecls.h
@@ -0,0 +1,166 @@
+/*
+ * This file is (mostly) automatically generated from tclOO.decls.
+ */
+
+#ifndef _TCLOOINTDECLS
+#define _TCLOOINTDECLS
+
+/* !BEGIN!: Do not edit below this line. */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Exported function declarations:
+ */
+
+/* 0 */
+TCLAPI Tcl_Object	TclOOGetDefineCmdContext(Tcl_Interp *interp);
+/* 1 */
+TCLAPI Tcl_Method	TclOOMakeProcInstanceMethod(Tcl_Interp *interp,
+				Object *oPtr, int flags, Tcl_Obj *nameObj,
+				Tcl_Obj *argsObj, Tcl_Obj *bodyObj,
+				const Tcl_MethodType *typePtr,
+				ClientData clientData, Proc **procPtrPtr);
+/* 2 */
+TCLAPI Tcl_Method	TclOOMakeProcMethod(Tcl_Interp *interp,
+				Class *clsPtr, int flags, Tcl_Obj *nameObj,
+				const char *namePtr, Tcl_Obj *argsObj,
+				Tcl_Obj *bodyObj,
+				const Tcl_MethodType *typePtr,
+				ClientData clientData, Proc **procPtrPtr);
+/* 3 */
+TCLAPI Method *		TclOONewProcInstanceMethod(Tcl_Interp *interp,
+				Object *oPtr, int flags, Tcl_Obj *nameObj,
+				Tcl_Obj *argsObj, Tcl_Obj *bodyObj,
+				ProcedureMethod **pmPtrPtr);
+/* 4 */
+TCLAPI Method *		TclOONewProcMethod(Tcl_Interp *interp, Class *clsPtr,
+				int flags, Tcl_Obj *nameObj,
+				Tcl_Obj *argsObj, Tcl_Obj *bodyObj,
+				ProcedureMethod **pmPtrPtr);
+/* 5 */
+TCLAPI int		TclOOObjectCmdCore(Object *oPtr, Tcl_Interp *interp,
+				int objc, Tcl_Obj *const *objv,
+				int publicOnly, Class *startCls);
+/* 6 */
+TCLAPI int		TclOOIsReachable(Class *targetPtr, Class *startPtr);
+/* 7 */
+TCLAPI Method *		TclOONewForwardMethod(Tcl_Interp *interp,
+				Class *clsPtr, int isPublic,
+				Tcl_Obj *nameObj, Tcl_Obj *prefixObj);
+/* 8 */
+TCLAPI Method *		TclOONewForwardInstanceMethod(Tcl_Interp *interp,
+				Object *oPtr, int isPublic, Tcl_Obj *nameObj,
+				Tcl_Obj *prefixObj);
+/* 9 */
+TCLAPI Tcl_Method	TclOONewProcInstanceMethodEx(Tcl_Interp *interp,
+				Tcl_Object oPtr,
+				TclOO_PreCallProc *preCallPtr,
+				TclOO_PostCallProc *postCallPtr,
+				ProcErrorProc *errProc,
+				ClientData clientData, Tcl_Obj *nameObj,
+				Tcl_Obj *argsObj, Tcl_Obj *bodyObj,
+				int flags, void **internalTokenPtr);
+/* 10 */
+TCLAPI Tcl_Method	TclOONewProcMethodEx(Tcl_Interp *interp,
+				Tcl_Class clsPtr,
+				TclOO_PreCallProc *preCallPtr,
+				TclOO_PostCallProc *postCallPtr,
+				ProcErrorProc *errProc,
+				ClientData clientData, Tcl_Obj *nameObj,
+				Tcl_Obj *argsObj, Tcl_Obj *bodyObj,
+				int flags, void **internalTokenPtr);
+/* 11 */
+TCLAPI int		TclOOInvokeObject(Tcl_Interp *interp,
+				Tcl_Object object, Tcl_Class startCls,
+				int publicPrivate, int objc,
+				Tcl_Obj *const *objv);
+/* 12 */
+TCLAPI void		TclOOObjectSetFilters(Object *oPtr, int numFilters,
+				Tcl_Obj *const *filters);
+/* 13 */
+TCLAPI void		TclOOClassSetFilters(Tcl_Interp *interp,
+				Class *classPtr, int numFilters,
+				Tcl_Obj *const *filters);
+/* 14 */
+TCLAPI void		TclOOObjectSetMixins(Object *oPtr, int numMixins,
+				Class *const *mixins);
+/* 15 */
+TCLAPI void		TclOOClassSetMixins(Tcl_Interp *interp,
+				Class *classPtr, int numMixins,
+				Class *const *mixins);
+
+typedef struct TclOOIntStubs {
+    int magic;
+    void *hooks;
+
+    Tcl_Object (*tclOOGetDefineCmdContext) (Tcl_Interp *interp); /* 0 */
+    Tcl_Method (*tclOOMakeProcInstanceMethod) (Tcl_Interp *interp, Object *oPtr, int flags, Tcl_Obj *nameObj, Tcl_Obj *argsObj, Tcl_Obj *bodyObj, const Tcl_MethodType *typePtr, ClientData clientData, Proc **procPtrPtr); /* 1 */
+    Tcl_Method (*tclOOMakeProcMethod) (Tcl_Interp *interp, Class *clsPtr, int flags, Tcl_Obj *nameObj, const char *namePtr, Tcl_Obj *argsObj, Tcl_Obj *bodyObj, const Tcl_MethodType *typePtr, ClientData clientData, Proc **procPtrPtr); /* 2 */
+    Method * (*tclOONewProcInstanceMethod) (Tcl_Interp *interp, Object *oPtr, int flags, Tcl_Obj *nameObj, Tcl_Obj *argsObj, Tcl_Obj *bodyObj, ProcedureMethod **pmPtrPtr); /* 3 */
+    Method * (*tclOONewProcMethod) (Tcl_Interp *interp, Class *clsPtr, int flags, Tcl_Obj *nameObj, Tcl_Obj *argsObj, Tcl_Obj *bodyObj, ProcedureMethod **pmPtrPtr); /* 4 */
+    int (*tclOOObjectCmdCore) (Object *oPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const *objv, int publicOnly, Class *startCls); /* 5 */
+    int (*tclOOIsReachable) (Class *targetPtr, Class *startPtr); /* 6 */
+    Method * (*tclOONewForwardMethod) (Tcl_Interp *interp, Class *clsPtr, int isPublic, Tcl_Obj *nameObj, Tcl_Obj *prefixObj); /* 7 */
+    Method * (*tclOONewForwardInstanceMethod) (Tcl_Interp *interp, Object *oPtr, int isPublic, Tcl_Obj *nameObj, Tcl_Obj *prefixObj); /* 8 */
+    Tcl_Method (*tclOONewProcInstanceMethodEx) (Tcl_Interp *interp, Tcl_Object oPtr, TclOO_PreCallProc *preCallPtr, TclOO_PostCallProc *postCallPtr, ProcErrorProc *errProc, ClientData clientData, Tcl_Obj *nameObj, Tcl_Obj *argsObj, Tcl_Obj *bodyObj, int flags, void **internalTokenPtr); /* 9 */
+    Tcl_Method (*tclOONewProcMethodEx) (Tcl_Interp *interp, Tcl_Class clsPtr, TclOO_PreCallProc *preCallPtr, TclOO_PostCallProc *postCallPtr, ProcErrorProc *errProc, ClientData clientData, Tcl_Obj *nameObj, Tcl_Obj *argsObj, Tcl_Obj *bodyObj, int flags, void **internalTokenPtr); /* 10 */
+    int (*tclOOInvokeObject) (Tcl_Interp *interp, Tcl_Object object, Tcl_Class startCls, int publicPrivate, int objc, Tcl_Obj *const *objv); /* 11 */
+    void (*tclOOObjectSetFilters) (Object *oPtr, int numFilters, Tcl_Obj *const *filters); /* 12 */
+    void (*tclOOClassSetFilters) (Tcl_Interp *interp, Class *classPtr, int numFilters, Tcl_Obj *const *filters); /* 13 */
+    void (*tclOOObjectSetMixins) (Object *oPtr, int numMixins, Class *const *mixins); /* 14 */
+    void (*tclOOClassSetMixins) (Tcl_Interp *interp, Class *classPtr, int numMixins, Class *const *mixins); /* 15 */
+} TclOOIntStubs;
+
+extern const TclOOIntStubs *tclOOIntStubsPtr;
+
+#ifdef __cplusplus
+}
+#endif
+
+#if defined(USE_TCLOO_STUBS)
+
+/*
+ * Inline function declarations:
+ */
+
+#define TclOOGetDefineCmdContext \
+	(tclOOIntStubsPtr->tclOOGetDefineCmdContext) /* 0 */
+#define TclOOMakeProcInstanceMethod \
+	(tclOOIntStubsPtr->tclOOMakeProcInstanceMethod) /* 1 */
+#define TclOOMakeProcMethod \
+	(tclOOIntStubsPtr->tclOOMakeProcMethod) /* 2 */
+#define TclOONewProcInstanceMethod \
+	(tclOOIntStubsPtr->tclOONewProcInstanceMethod) /* 3 */
+#define TclOONewProcMethod \
+	(tclOOIntStubsPtr->tclOONewProcMethod) /* 4 */
+#define TclOOObjectCmdCore \
+	(tclOOIntStubsPtr->tclOOObjectCmdCore) /* 5 */
+#define TclOOIsReachable \
+	(tclOOIntStubsPtr->tclOOIsReachable) /* 6 */
+#define TclOONewForwardMethod \
+	(tclOOIntStubsPtr->tclOONewForwardMethod) /* 7 */
+#define TclOONewForwardInstanceMethod \
+	(tclOOIntStubsPtr->tclOONewForwardInstanceMethod) /* 8 */
+#define TclOONewProcInstanceMethodEx \
+	(tclOOIntStubsPtr->tclOONewProcInstanceMethodEx) /* 9 */
+#define TclOONewProcMethodEx \
+	(tclOOIntStubsPtr->tclOONewProcMethodEx) /* 10 */
+#define TclOOInvokeObject \
+	(tclOOIntStubsPtr->tclOOInvokeObject) /* 11 */
+#define TclOOObjectSetFilters \
+	(tclOOIntStubsPtr->tclOOObjectSetFilters) /* 12 */
+#define TclOOClassSetFilters \
+	(tclOOIntStubsPtr->tclOOClassSetFilters) /* 13 */
+#define TclOOObjectSetMixins \
+	(tclOOIntStubsPtr->tclOOObjectSetMixins) /* 14 */
+#define TclOOClassSetMixins \
+	(tclOOIntStubsPtr->tclOOClassSetMixins) /* 15 */
+
+#endif /* defined(USE_TCLOO_STUBS) */
+
+/* !END!: Do not edit above this line. */
+
+#endif /* _TCLOOINTDECLS */
diff --git a/generic/tclOOMethod.c b/generic/tclOOMethod.c
new file mode 100644
index 0000000..99a8bfc
--- /dev/null
+++ b/generic/tclOOMethod.c
@@ -0,0 +1,1763 @@
+/*
+ * tclOOMethod.c --
+ *
+ *	This file contains code to create and manage methods.
+ *
+ * Copyright (c) 2005-2011 by Donal K. Fellows
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include "tclInt.h"
+#include "tclOOInt.h"
+#include "tclCompile.h"
+
+/*
+ * Structure used to help delay computing names of objects or classes for
+ * [info frame] until needed, making invokation faster in the normal case.
+ */
+
+struct PNI {
+    Tcl_Interp *interp;		/* Interpreter in which to compute the name of
+				 * a method. */
+    Tcl_Method method;		/* Method to compute the name of. */
+};
+
+/*
+ * Structure used to contain all the information needed about a call frame
+ * used in a procedure-like method.
+ */
+
+typedef struct {
+    CallFrame *framePtr;	/* Reference to the call frame itself (it's
+				 * actually allocated on the Tcl stack). */
+    ProcErrorProc *errProc;	/* The error handler for the body. */
+    Tcl_Obj *nameObj;		/* The "name" of the command. */
+    Command cmd;		/* The command structure. Mostly bogus. */
+    ExtraFrameInfo efi;		/* Extra information used for [info frame]. */
+    Command *oldCmdPtr;		/* Saved cmdPtr so that we can be safe after a
+				 * recursive call returns. */
+    struct PNI pni;		/* Specialist information used in the efi
+				 * field for this type of call. */
+} PMFrameData;
+
+/*
+ * Structure used to pass information about variable resolution to the
+ * on-the-ground resolvers used when working with resolved compiled variables.
+ */
+
+typedef struct {
+    Tcl_ResolvedVarInfo info;	/* "Type" information so that the compiled
+				 * variable can be linked to the namespace
+				 * variable at the right time. */
+    Tcl_Obj *variableObj;	/* The name of the variable. */
+    Tcl_Var cachedObjectVar;	/* TODO: When to flush this cache? Can class
+				 * variables be cached? */
+} OOResVarInfo;
+
+/*
+ * Function declarations for things defined in this file.
+ */
+
+static Tcl_Obj **	InitEnsembleRewrite(Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const *objv, int toRewrite,
+			    int rewriteLength, Tcl_Obj *const *rewriteObjs,
+			    int *lengthPtr);
+static int		InvokeProcedureMethod(ClientData clientData,
+			    Tcl_Interp *interp, Tcl_ObjectContext context,
+			    int objc, Tcl_Obj *const *objv);
+static Tcl_NRPostProc	FinalizeForwardCall;
+static Tcl_NRPostProc	FinalizePMCall;
+static int		PushMethodCallFrame(Tcl_Interp *interp,
+			    CallContext *contextPtr, ProcedureMethod *pmPtr,
+			    int objc, Tcl_Obj *const *objv,
+			    PMFrameData *fdPtr);
+static void		DeleteProcedureMethodRecord(ProcedureMethod *pmPtr);
+static void		DeleteProcedureMethod(ClientData clientData);
+static int		CloneProcedureMethod(Tcl_Interp *interp,
+			    ClientData clientData, ClientData *newClientData);
+static void		MethodErrorHandler(Tcl_Interp *interp,
+			    Tcl_Obj *procNameObj);
+static void		ConstructorErrorHandler(Tcl_Interp *interp,
+			    Tcl_Obj *procNameObj);
+static void		DestructorErrorHandler(Tcl_Interp *interp,
+			    Tcl_Obj *procNameObj);
+static Tcl_Obj *	RenderDeclarerName(ClientData clientData);
+static int		InvokeForwardMethod(ClientData clientData,
+			    Tcl_Interp *interp, Tcl_ObjectContext context,
+			    int objc, Tcl_Obj *const *objv);
+static void		DeleteForwardMethod(ClientData clientData);
+static int		CloneForwardMethod(Tcl_Interp *interp,
+			    ClientData clientData, ClientData *newClientData);
+static int		ProcedureMethodVarResolver(Tcl_Interp *interp,
+			    const char *varName, Tcl_Namespace *contextNs,
+			    int flags, Tcl_Var *varPtr);
+static int		ProcedureMethodCompiledVarResolver(Tcl_Interp *interp,
+			    const char *varName, int length,
+			    Tcl_Namespace *contextNs,
+			    Tcl_ResolvedVarInfo **rPtrPtr);
+
+/*
+ * The types of methods defined by the core OO system.
+ */
+
+static const Tcl_MethodType procMethodType = {
+    TCL_OO_METHOD_VERSION_CURRENT, "method",
+    InvokeProcedureMethod, DeleteProcedureMethod, CloneProcedureMethod
+};
+static const Tcl_MethodType fwdMethodType = {
+    TCL_OO_METHOD_VERSION_CURRENT, "forward",
+    InvokeForwardMethod, DeleteForwardMethod, CloneForwardMethod
+};
+
+/*
+ * Helper macros (derived from things private to tclVar.c)
+ */
+
+#define TclVarTable(contextNs) \
+    ((Tcl_HashTable *) (&((Namespace *) (contextNs))->varTable))
+#define TclVarHashGetValue(hPtr) \
+    ((Tcl_Var) ((char *)hPtr - TclOffset(VarInHash, entry)))
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * Tcl_NewInstanceMethod --
+ *
+ *	Attach a method to an object instance.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+Tcl_Method
+Tcl_NewInstanceMethod(
+    Tcl_Interp *interp,		/* Unused? */
+    Tcl_Object object,		/* The object that has the method attached to
+				 * it. */
+    Tcl_Obj *nameObj,		/* The name of the method. May be NULL; if so,
+				 * up to caller to manage storage (e.g., when
+				 * it is a constructor or destructor). */
+    int flags,			/* Whether this is a public method. */
+    const Tcl_MethodType *typePtr,
+				/* The type of method this is, which defines
+				 * how to invoke, delete and clone the
+				 * method. */
+    ClientData clientData)	/* Some data associated with the particular
+				 * method to be created. */
+{
+    register Object *oPtr = (Object *) object;
+    register Method *mPtr;
+    Tcl_HashEntry *hPtr;
+    int isNew;
+
+    if (nameObj == NULL) {
+	mPtr = ckalloc(sizeof(Method));
+	mPtr->namePtr = NULL;
+	mPtr->refCount = 1;
+	goto populate;
+    }
+    if (!oPtr->methodsPtr) {
+	oPtr->methodsPtr = ckalloc(sizeof(Tcl_HashTable));
+	Tcl_InitObjHashTable(oPtr->methodsPtr);
+	oPtr->flags &= ~USE_CLASS_CACHE;
+    }
+    hPtr = Tcl_CreateHashEntry(oPtr->methodsPtr, (char *) nameObj, &isNew);
+    if (isNew) {
+	mPtr = ckalloc(sizeof(Method));
+	mPtr->namePtr = nameObj;
+	mPtr->refCount = 1;
+	Tcl_IncrRefCount(nameObj);
+	Tcl_SetHashValue(hPtr, mPtr);
+    } else {
+	mPtr = Tcl_GetHashValue(hPtr);
+	if (mPtr->typePtr != NULL && mPtr->typePtr->deleteProc != NULL) {
+	    mPtr->typePtr->deleteProc(mPtr->clientData);
+	}
+    }
+
+  populate:
+    mPtr->typePtr = typePtr;
+    mPtr->clientData = clientData;
+    mPtr->flags = 0;
+    mPtr->declaringObjectPtr = oPtr;
+    mPtr->declaringClassPtr = NULL;
+    if (flags) {
+	mPtr->flags |= flags & (PUBLIC_METHOD | PRIVATE_METHOD);
+    }
+    oPtr->epoch++;
+    return (Tcl_Method) mPtr;
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * Tcl_NewMethod --
+ *
+ *	Attach a method to a class.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+Tcl_Method
+Tcl_NewMethod(
+    Tcl_Interp *interp,		/* The interpreter containing the class. */
+    Tcl_Class cls,		/* The class to attach the method to. */
+    Tcl_Obj *nameObj,		/* The name of the object. May be NULL (e.g.,
+				 * for constructors or destructors); if so, up
+				 * to caller to manage storage. */
+    int flags,			/* Whether this is a public method. */
+    const Tcl_MethodType *typePtr,
+				/* The type of method this is, which defines
+				 * how to invoke, delete and clone the
+				 * method. */
+    ClientData clientData)	/* Some data associated with the particular
+				 * method to be created. */
+{
+    register Class *clsPtr = (Class *) cls;
+    register Method *mPtr;
+    Tcl_HashEntry *hPtr;
+    int isNew;
+
+    if (nameObj == NULL) {
+	mPtr = ckalloc(sizeof(Method));
+	mPtr->namePtr = NULL;
+	mPtr->refCount = 1;
+	goto populate;
+    }
+    hPtr = Tcl_CreateHashEntry(&clsPtr->classMethods, (char *)nameObj,&isNew);
+    if (isNew) {
+	mPtr = ckalloc(sizeof(Method));
+	mPtr->refCount = 1;
+	mPtr->namePtr = nameObj;
+	Tcl_IncrRefCount(nameObj);
+	Tcl_SetHashValue(hPtr, mPtr);
+    } else {
+	mPtr = Tcl_GetHashValue(hPtr);
+	if (mPtr->typePtr != NULL && mPtr->typePtr->deleteProc != NULL) {
+	    mPtr->typePtr->deleteProc(mPtr->clientData);
+	}
+    }
+
+  populate:
+    clsPtr->thisPtr->fPtr->epoch++;
+    mPtr->typePtr = typePtr;
+    mPtr->clientData = clientData;
+    mPtr->flags = 0;
+    mPtr->declaringObjectPtr = NULL;
+    mPtr->declaringClassPtr = clsPtr;
+    if (flags) {
+	mPtr->flags |= flags & (PUBLIC_METHOD | PRIVATE_METHOD);
+    }
+
+    return (Tcl_Method) mPtr;
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * TclOODelMethodRef --
+ *
+ *	How to delete a method.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+void
+TclOODelMethodRef(
+    Method *mPtr)
+{
+    if ((mPtr != NULL) && (mPtr->refCount-- <= 1)) {
+	if (mPtr->typePtr != NULL && mPtr->typePtr->deleteProc != NULL) {
+	    mPtr->typePtr->deleteProc(mPtr->clientData);
+	}
+	if (mPtr->namePtr != NULL) {
+	    Tcl_DecrRefCount(mPtr->namePtr);
+	}
+
+	ckfree(mPtr);
+    }
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * TclOONewBasicMethod --
+ *
+ *	Helper that makes it cleaner to create very simple methods during
+ *	basic system initialization. Not suitable for general use.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+void
+TclOONewBasicMethod(
+    Tcl_Interp *interp,
+    Class *clsPtr,		/* Class to attach the method to. */
+    const DeclaredClassMethod *dcm)
+				/* Name of the method, whether it is public,
+				 * and the function to implement it. */
+{
+    Tcl_Obj *namePtr = Tcl_NewStringObj(dcm->name, -1);
+
+    Tcl_IncrRefCount(namePtr);
+    Tcl_NewMethod(interp, (Tcl_Class) clsPtr, namePtr,
+	    (dcm->isPublic ? PUBLIC_METHOD : 0), &dcm->definition, NULL);
+    Tcl_DecrRefCount(namePtr);
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * TclOONewProcInstanceMethod --
+ *
+ *	Create a new procedure-like method for an object.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+Method *
+TclOONewProcInstanceMethod(
+    Tcl_Interp *interp,		/* The interpreter containing the object. */
+    Object *oPtr,		/* The object to modify. */
+    int flags,			/* Whether this is a public method. */
+    Tcl_Obj *nameObj,		/* The name of the method, which must not be
+				 * NULL. */
+    Tcl_Obj *argsObj,		/* The formal argument list for the method,
+				 * which must not be NULL. */
+    Tcl_Obj *bodyObj,		/* The body of the method, which must not be
+				 * NULL. */
+    ProcedureMethod **pmPtrPtr)	/* Place to write pointer to procedure method
+				 * structure to allow for deeper tuning of the
+				 * structure's contents. NULL if caller is not
+				 * interested. */
+{
+    int argsLen;
+    register ProcedureMethod *pmPtr;
+    Tcl_Method method;
+
+    if (Tcl_ListObjLength(interp, argsObj, &argsLen) != TCL_OK) {
+	return NULL;
+    }
+    pmPtr = ckalloc(sizeof(ProcedureMethod));
+    memset(pmPtr, 0, sizeof(ProcedureMethod));
+    pmPtr->version = TCLOO_PROCEDURE_METHOD_VERSION;
+    pmPtr->flags = flags & USE_DECLARER_NS;
+    pmPtr->refCount = 1;
+
+    method = TclOOMakeProcInstanceMethod(interp, oPtr, flags, nameObj,
+	    argsObj, bodyObj, &procMethodType, pmPtr, &pmPtr->procPtr);
+    if (method == NULL) {
+	ckfree(pmPtr);
+    } else if (pmPtrPtr != NULL) {
+	*pmPtrPtr = pmPtr;
+    }
+    return (Method *) method;
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * TclOONewProcMethod --
+ *
+ *	Create a new procedure-like method for a class.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+Method *
+TclOONewProcMethod(
+    Tcl_Interp *interp,		/* The interpreter containing the class. */
+    Class *clsPtr,		/* The class to modify. */
+    int flags,			/* Whether this is a public method. */
+    Tcl_Obj *nameObj,		/* The name of the method, which may be NULL;
+				 * if so, up to caller to manage storage
+				 * (e.g., because it is a constructor or
+				 * destructor). */
+    Tcl_Obj *argsObj,		/* The formal argument list for the method,
+				 * which may be NULL; if so, it is equivalent
+				 * to an empty list. */
+    Tcl_Obj *bodyObj,		/* The body of the method, which must not be
+				 * NULL. */
+    ProcedureMethod **pmPtrPtr)	/* Place to write pointer to procedure method
+				 * structure to allow for deeper tuning of the
+				 * structure's contents. NULL if caller is not
+				 * interested. */
+{
+    int argsLen;		/* -1 => delete argsObj before exit */
+    register ProcedureMethod *pmPtr;
+    const char *procName;
+    Tcl_Method method;
+
+    if (argsObj == NULL) {
+	argsLen = -1;
+	argsObj = Tcl_NewObj();
+	Tcl_IncrRefCount(argsObj);
+	procName = "<destructor>";
+    } else if (Tcl_ListObjLength(interp, argsObj, &argsLen) != TCL_OK) {
+	return NULL;
+    } else {
+	procName = (nameObj==NULL ? "<constructor>" : TclGetString(nameObj));
+    }
+
+    pmPtr = ckalloc(sizeof(ProcedureMethod));
+    memset(pmPtr, 0, sizeof(ProcedureMethod));
+    pmPtr->version = TCLOO_PROCEDURE_METHOD_VERSION;
+    pmPtr->flags = flags & USE_DECLARER_NS;
+    pmPtr->refCount = 1;
+
+    method = TclOOMakeProcMethod(interp, clsPtr, flags, nameObj, procName,
+	    argsObj, bodyObj, &procMethodType, pmPtr, &pmPtr->procPtr);
+
+    if (argsLen == -1) {
+	Tcl_DecrRefCount(argsObj);
+    }
+    if (method == NULL) {
+	ckfree(pmPtr);
+    } else if (pmPtrPtr != NULL) {
+	*pmPtrPtr = pmPtr;
+    }
+
+    return (Method *) method;
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * TclOOMakeProcInstanceMethod --
+ *
+ *	The guts of the code to make a procedure-like method for an object.
+ *	Split apart so that it is easier for other extensions to reuse (in
+ *	particular, it frees them from having to pry so deeply into Tcl's
+ *	guts).
+ *
+ * ----------------------------------------------------------------------
+ */
+
+Tcl_Method
+TclOOMakeProcInstanceMethod(
+    Tcl_Interp *interp,		/* The interpreter containing the object. */
+    Object *oPtr,		/* The object to modify. */
+    int flags,			/* Whether this is a public method. */
+    Tcl_Obj *nameObj,		/* The name of the method, which _must not_ be
+				 * NULL. */
+    Tcl_Obj *argsObj,		/* The formal argument list for the method,
+				 * which _must not_ be NULL. */
+    Tcl_Obj *bodyObj,		/* The body of the method, which _must not_ be
+				 * NULL. */
+    const Tcl_MethodType *typePtr,
+				/* The type of the method to create. */
+    ClientData clientData,	/* The per-method type-specific data. */
+    Proc **procPtrPtr)		/* A pointer to the variable in which to write
+				 * the procedure record reference. Presumably
+				 * inside the structure indicated by the
+				 * pointer in clientData. */
+{
+    Interp *iPtr = (Interp *) interp;
+    Proc *procPtr;
+
+    if (TclCreateProc(interp, NULL, TclGetString(nameObj), argsObj, bodyObj,
+	    procPtrPtr) != TCL_OK) {
+	return NULL;
+    }
+    procPtr = *procPtrPtr;
+    procPtr->cmdPtr = NULL;
+
+    if (iPtr->cmdFramePtr) {
+	CmdFrame context = *iPtr->cmdFramePtr;
+
+	if (context.type == TCL_LOCATION_BC) {
+	    /*
+	     * Retrieve source information from the bytecode, if possible. If
+	     * the information is retrieved successfully, context.type will be
+	     * TCL_LOCATION_SOURCE and the reference held by
+	     * context.data.eval.path will be counted.
+	     */
+
+	    TclGetSrcInfoForPc(&context);
+	} else if (context.type == TCL_LOCATION_SOURCE) {
+	    /*
+	     * The copy into 'context' up above has created another reference
+	     * to 'context.data.eval.path'; account for it.
+	     */
+
+	    Tcl_IncrRefCount(context.data.eval.path);
+	}
+
+	if (context.type == TCL_LOCATION_SOURCE) {
+	    /*
+	     * We can account for source location within a proc only if the
+	     * proc body was not created by substitution.
+	     * (FIXME: check that this is sane and correct!)
+	     */
+
+	    if (context.line
+		    && (context.nline >= 4) && (context.line[3] >= 0)) {
+		int isNew;
+		CmdFrame *cfPtr = ckalloc(sizeof(CmdFrame));
+		Tcl_HashEntry *hPtr;
+
+		cfPtr->level = -1;
+		cfPtr->type = context.type;
+		cfPtr->line = ckalloc(sizeof(int));
+		cfPtr->line[0] = context.line[3];
+		cfPtr->nline = 1;
+		cfPtr->framePtr = NULL;
+		cfPtr->nextPtr = NULL;
+
+		cfPtr->data.eval.path = context.data.eval.path;
+		Tcl_IncrRefCount(cfPtr->data.eval.path);
+
+		cfPtr->cmd = NULL;
+		cfPtr->len = 0;
+
+		hPtr = Tcl_CreateHashEntry(iPtr->linePBodyPtr,
+			(char *) procPtr, &isNew);
+		Tcl_SetHashValue(hPtr, cfPtr);
+	    }
+
+	    /*
+	     * 'context' is going out of scope; account for the reference that
+	     * it's holding to the path name.
+	     */
+
+	    Tcl_DecrRefCount(context.data.eval.path);
+	    context.data.eval.path = NULL;
+	}
+    }
+
+    return Tcl_NewInstanceMethod(interp, (Tcl_Object) oPtr, nameObj, flags,
+	    typePtr, clientData);
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * TclOOMakeProcMethod --
+ *
+ *	The guts of the code to make a procedure-like method for a class.
+ *	Split apart so that it is easier for other extensions to reuse (in
+ *	particular, it frees them from having to pry so deeply into Tcl's
+ *	guts).
+ *
+ * ----------------------------------------------------------------------
+ */
+
+Tcl_Method
+TclOOMakeProcMethod(
+    Tcl_Interp *interp,		/* The interpreter containing the class. */
+    Class *clsPtr,		/* The class to modify. */
+    int flags,			/* Whether this is a public method. */
+    Tcl_Obj *nameObj,		/* The name of the method, which may be NULL;
+				 * if so, up to caller to manage storage
+				 * (e.g., because it is a constructor or
+				 * destructor). */
+    const char *namePtr,	/* The name of the method as a string, which
+				 * _must not_ be NULL. */
+    Tcl_Obj *argsObj,		/* The formal argument list for the method,
+				 * which _must not_ be NULL. */
+    Tcl_Obj *bodyObj,		/* The body of the method, which _must not_ be
+				 * NULL. */
+    const Tcl_MethodType *typePtr,
+				/* The type of the method to create. */
+    ClientData clientData,	/* The per-method type-specific data. */
+    Proc **procPtrPtr)		/* A pointer to the variable in which to write
+				 * the procedure record reference. Presumably
+				 * inside the structure indicated by the
+				 * pointer in clientData. */
+{
+    Interp *iPtr = (Interp *) interp;
+    Proc *procPtr;
+
+    if (TclCreateProc(interp, NULL, namePtr, argsObj, bodyObj,
+	    procPtrPtr) != TCL_OK) {
+	return NULL;
+    }
+    procPtr = *procPtrPtr;
+    procPtr->cmdPtr = NULL;
+
+    if (iPtr->cmdFramePtr) {
+	CmdFrame context = *iPtr->cmdFramePtr;
+
+	if (context.type == TCL_LOCATION_BC) {
+	    /*
+	     * Retrieve source information from the bytecode, if possible. If
+	     * the information is retrieved successfully, context.type will be
+	     * TCL_LOCATION_SOURCE and the reference held by
+	     * context.data.eval.path will be counted.
+	     */
+
+	    TclGetSrcInfoForPc(&context);
+	} else if (context.type == TCL_LOCATION_SOURCE) {
+	    /*
+	     * The copy into 'context' up above has created another reference
+	     * to 'context.data.eval.path'; account for it.
+	     */
+
+	    Tcl_IncrRefCount(context.data.eval.path);
+	}
+
+	if (context.type == TCL_LOCATION_SOURCE) {
+	    /*
+	     * We can account for source location within a proc only if the
+	     * proc body was not created by substitution.
+	     * (FIXME: check that this is sane and correct!)
+	     */
+
+	    if (context.line
+		    && (context.nline >= 4) && (context.line[3] >= 0)) {
+		int isNew;
+		CmdFrame *cfPtr = ckalloc(sizeof(CmdFrame));
+		Tcl_HashEntry *hPtr;
+
+		cfPtr->level = -1;
+		cfPtr->type = context.type;
+		cfPtr->line = ckalloc(sizeof(int));
+		cfPtr->line[0] = context.line[3];
+		cfPtr->nline = 1;
+		cfPtr->framePtr = NULL;
+		cfPtr->nextPtr = NULL;
+
+		cfPtr->data.eval.path = context.data.eval.path;
+		Tcl_IncrRefCount(cfPtr->data.eval.path);
+
+		cfPtr->cmd = NULL;
+		cfPtr->len = 0;
+
+		hPtr = Tcl_CreateHashEntry(iPtr->linePBodyPtr,
+			(char *) procPtr, &isNew);
+		Tcl_SetHashValue(hPtr, cfPtr);
+	    }
+
+	    /*
+	     * 'context' is going out of scope; account for the reference that
+	     * it's holding to the path name.
+	     */
+
+	    Tcl_DecrRefCount(context.data.eval.path);
+	    context.data.eval.path = NULL;
+	}
+    }
+
+    return Tcl_NewMethod(interp, (Tcl_Class) clsPtr, nameObj, flags, typePtr,
+	    clientData);
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * InvokeProcedureMethod, PushMethodCallFrame --
+ *
+ *	How to invoke a procedure-like method.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+static int
+InvokeProcedureMethod(
+    ClientData clientData,	/* Pointer to some per-method context. */
+    Tcl_Interp *interp,
+    Tcl_ObjectContext context,	/* The method calling context. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const *objv)	/* Arguments as actually seen. */
+{
+    ProcedureMethod *pmPtr = clientData;
+    int result;
+    PMFrameData *fdPtr;		/* Important data that has to have a lifetime
+				 * matched by this function (or rather, by the
+				 * call frame's lifetime). */
+
+    /*
+     * If the interpreter was deleted, we just skip to the next thing in the
+     * chain.
+     */
+
+    if (Tcl_InterpDeleted(interp)) {
+	return TclNRObjectContextInvokeNext(interp, context, objc, objv,
+		Tcl_ObjectContextSkippedArgs(context));
+    }
+
+    /*
+     * Allocate the special frame data.
+     */
+
+    fdPtr = TclStackAlloc(interp, sizeof(PMFrameData));
+
+    /*
+     * Create a call frame for this method.
+     */
+
+    result = PushMethodCallFrame(interp, (CallContext *) context, pmPtr,
+	    objc, objv, fdPtr);
+    if (result != TCL_OK) {
+	TclStackFree(interp, fdPtr);
+	return result;
+    }
+    pmPtr->refCount++;
+
+    /*
+     * Give the pre-call callback a chance to do some setup and, possibly,
+     * veto the call.
+     */
+
+    if (pmPtr->preCallProc != NULL) {
+	int isFinished;
+
+	result = pmPtr->preCallProc(pmPtr->clientData, interp, context,
+		(Tcl_CallFrame *) fdPtr->framePtr, &isFinished);
+	if (isFinished || result != TCL_OK) {
+	    /*
+	     * Restore the old cmdPtr so that a subsequent use of [info frame]
+	     * won't crash on us. [Bug 3001438]
+	     */
+
+	    pmPtr->procPtr->cmdPtr = fdPtr->oldCmdPtr;
+
+	    Tcl_PopCallFrame(interp);
+	    TclStackFree(interp, fdPtr->framePtr);
+	    if (pmPtr->refCount-- <= 1) {
+		DeleteProcedureMethodRecord(pmPtr);
+	    }
+	    TclStackFree(interp, fdPtr);
+	    return result;
+	}
+    }
+
+    /*
+     * Now invoke the body of the method.
+     */
+
+    TclNRAddCallback(interp, FinalizePMCall, pmPtr, context, fdPtr, NULL);
+    return TclNRInterpProcCore(interp, fdPtr->nameObj,
+	    Tcl_ObjectContextSkippedArgs(context), fdPtr->errProc);
+}
+
+static int
+FinalizePMCall(
+    ClientData data[],
+    Tcl_Interp *interp,
+    int result)
+{
+    ProcedureMethod *pmPtr = data[0];
+    Tcl_ObjectContext context = data[1];
+    PMFrameData *fdPtr = data[2];
+
+    /*
+     * Give the post-call callback a chance to do some cleanup. Note that at
+     * this point the call frame itself is invalid; it's already been popped.
+     */
+
+    if (pmPtr->postCallProc) {
+	result = pmPtr->postCallProc(pmPtr->clientData, interp, context,
+		Tcl_GetObjectNamespace(Tcl_ObjectContextObject(context)),
+		result);
+    }
+
+    /*
+     * Restore the old cmdPtr so that a subsequent use of [info frame] won't
+     * crash on us. [Bug 3001438]
+     */
+
+    pmPtr->procPtr->cmdPtr = fdPtr->oldCmdPtr;
+
+    /*
+     * Scrap the special frame data now that we're done with it. Note that we
+     * are inlining DeleteProcedureMethod() here; this location is highly
+     * sensitive when it comes to performance!
+     */
+
+    if (pmPtr->refCount-- <= 1) {
+	DeleteProcedureMethodRecord(pmPtr);
+    }
+    TclStackFree(interp, fdPtr);
+    return result;
+}
+
+static int
+PushMethodCallFrame(
+    Tcl_Interp *interp,		/* Current interpreter. */
+    CallContext *contextPtr,	/* Current method call context. */
+    ProcedureMethod *pmPtr,	/* Information about this procedure-like
+				 * method. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const *objv,	/* Array of arguments. */
+    PMFrameData *fdPtr)		/* Place to store information about the call
+				 * frame. */
+{
+    Namespace *nsPtr = (Namespace *) contextPtr->oPtr->namespacePtr;
+    register int result;
+    const char *namePtr;
+    CallFrame **framePtrPtr = &fdPtr->framePtr;
+
+    /*
+     * Compute basic information on the basis of the type of method it is.
+     */
+
+    if (contextPtr->callPtr->flags & CONSTRUCTOR) {
+	namePtr = "<constructor>";
+	fdPtr->nameObj = contextPtr->oPtr->fPtr->constructorName;
+	fdPtr->errProc = ConstructorErrorHandler;
+    } else if (contextPtr->callPtr->flags & DESTRUCTOR) {
+	namePtr = "<destructor>";
+	fdPtr->nameObj = contextPtr->oPtr->fPtr->destructorName;
+	fdPtr->errProc = DestructorErrorHandler;
+    } else {
+	fdPtr->nameObj = Tcl_MethodName(
+		Tcl_ObjectContextMethod((Tcl_ObjectContext) contextPtr));
+	namePtr = TclGetString(fdPtr->nameObj);
+	fdPtr->errProc = MethodErrorHandler;
+    }
+    if (pmPtr->errProc != NULL) {
+	fdPtr->errProc = pmPtr->errProc;
+    }
+
+    /*
+     * Magic to enable things like [incr Tcl], which wants methods to run in
+     * their class's namespace.
+     */
+
+    if (pmPtr->flags & USE_DECLARER_NS) {
+	register Method *mPtr =
+		contextPtr->callPtr->chain[contextPtr->index].mPtr;
+
+	if (mPtr->declaringClassPtr != NULL) {
+	    nsPtr = (Namespace *)
+		    mPtr->declaringClassPtr->thisPtr->namespacePtr;
+	} else {
+	    nsPtr = (Namespace *) mPtr->declaringObjectPtr->namespacePtr;
+	}
+    }
+
+    /*
+     * Save the old cmdPtr so that when this recursive call returns, we can
+     * restore it. To do otherwise causes crashes in [info frame] after we
+     * return from a recursive call. [Bug 3001438]
+     */
+
+    fdPtr->oldCmdPtr = pmPtr->procPtr->cmdPtr;
+
+    /*
+     * Compile the body. This operation may fail.
+     */
+
+    fdPtr->efi.length = 2;
+    memset(&fdPtr->cmd, 0, sizeof(Command));
+    fdPtr->cmd.nsPtr = nsPtr;
+    fdPtr->cmd.clientData = &fdPtr->efi;
+    pmPtr->procPtr->cmdPtr = &fdPtr->cmd;
+
+    /*
+     * [Bug 2037727] Always call TclProcCompileProc so that we check not only
+     * that we have bytecode, but also that it remains valid. Note that we set
+     * the namespace of the code here directly; this is a hack, but the
+     * alternative is *so* slow...
+     */
+
+    if (pmPtr->procPtr->bodyPtr->typePtr == &tclByteCodeType) {
+	ByteCode *codePtr =
+		pmPtr->procPtr->bodyPtr->internalRep.twoPtrValue.ptr1;
+
+	codePtr->nsPtr = nsPtr;
+    }
+    result = TclProcCompileProc(interp, pmPtr->procPtr,
+	    pmPtr->procPtr->bodyPtr, nsPtr, "body of method", namePtr);
+    if (result != TCL_OK) {
+	goto failureReturn;
+    }
+
+    /*
+     * Make the stack frame and fill it out with information about this call.
+     * This operation may fail.
+     */
+
+    (void) TclPushStackFrame(interp, (Tcl_CallFrame **) framePtrPtr,
+	    (Tcl_Namespace *) nsPtr, FRAME_IS_PROC|FRAME_IS_METHOD);
+
+    fdPtr->framePtr->clientData = contextPtr;
+    fdPtr->framePtr->objc = objc;
+    fdPtr->framePtr->objv = objv;
+    fdPtr->framePtr->procPtr = pmPtr->procPtr;
+
+    /*
+     * Finish filling out the extra frame info so that [info frame] works.
+     */
+
+    fdPtr->efi.fields[0].name = "method";
+    fdPtr->efi.fields[0].proc = NULL;
+    fdPtr->efi.fields[0].clientData = fdPtr->nameObj;
+    if (pmPtr->gfivProc != NULL) {
+	fdPtr->efi.fields[1].name = "";
+	fdPtr->efi.fields[1].proc = pmPtr->gfivProc;
+	fdPtr->efi.fields[1].clientData = pmPtr;
+    } else {
+	register Tcl_Method method =
+		Tcl_ObjectContextMethod((Tcl_ObjectContext) contextPtr);
+
+	if (Tcl_MethodDeclarerObject(method) != NULL) {
+	    fdPtr->efi.fields[1].name = "object";
+	} else {
+	    fdPtr->efi.fields[1].name = "class";
+	}
+	fdPtr->efi.fields[1].proc = RenderDeclarerName;
+	fdPtr->efi.fields[1].clientData = &fdPtr->pni;
+	fdPtr->pni.interp = interp;
+	fdPtr->pni.method = method;
+    }
+
+    return TCL_OK;
+
+    /*
+     * Restore the old cmdPtr so that a subsequent use of [info frame] won't
+     * crash on us. [Bug 3001438]
+     */
+
+  failureReturn:
+    pmPtr->procPtr->cmdPtr = fdPtr->oldCmdPtr;
+    return result;
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * TclOOSetupVariableResolver, etc. --
+ *
+ *	Variable resolution engine used to connect declared variables to local
+ *	variables used in methods. The compiled variable resolver is more
+ *	important, but both are needed as it is possible to have a variable
+ *	that is only referred to in ways that aren't compilable and we can't
+ *	force LVT presence. [TIP #320]
+ *
+ * ----------------------------------------------------------------------
+ */
+
+void
+TclOOSetupVariableResolver(
+    Tcl_Namespace *nsPtr)
+{
+    Tcl_ResolverInfo info;
+
+    Tcl_GetNamespaceResolvers(nsPtr, &info);
+    if (info.compiledVarResProc == NULL) {
+	Tcl_SetNamespaceResolvers(nsPtr, NULL, ProcedureMethodVarResolver,
+		ProcedureMethodCompiledVarResolver);
+    }
+}
+
+static int
+ProcedureMethodVarResolver(
+    Tcl_Interp *interp,
+    const char *varName,
+    Tcl_Namespace *contextNs,
+    int flags,
+    Tcl_Var *varPtr)
+{
+    int result;
+    Tcl_ResolvedVarInfo *rPtr = NULL;
+
+    result = ProcedureMethodCompiledVarResolver(interp, varName,
+	    strlen(varName), contextNs, &rPtr);
+
+    if (result != TCL_OK) {
+	return result;
+    }
+
+    *varPtr = rPtr->fetchProc(interp, rPtr);
+
+    /*
+     * Must not retain reference to resolved information. [Bug 3105999]
+     */
+
+    if (rPtr != NULL) {
+	rPtr->deleteProc(rPtr);
+    }
+    return (*varPtr? TCL_OK : TCL_CONTINUE);
+}
+
+static Tcl_Var
+ProcedureMethodCompiledVarConnect(
+    Tcl_Interp *interp,
+    Tcl_ResolvedVarInfo *rPtr)
+{
+    OOResVarInfo *infoPtr = (OOResVarInfo *) rPtr;
+    Interp *iPtr = (Interp *) interp;
+    CallFrame *framePtr = iPtr->varFramePtr;
+    CallContext *contextPtr;
+    Tcl_Obj *variableObj;
+    Tcl_HashEntry *hPtr;
+    int i, isNew, cacheIt, varLen, len;
+    const char *match, *varName;
+
+    /*
+     * Check that the variable is being requested in a context that is also a
+     * method call; if not (i.e. we're evaluating in the object's namespace or
+     * in a procedure of that namespace) then we do nothing.
+     */
+
+    if (framePtr == NULL || !(framePtr->isProcCallFrame & FRAME_IS_METHOD)) {
+	return NULL;
+    }
+    contextPtr = framePtr->clientData;
+
+    /*
+     * If we've done the work before (in a comparable context) then reuse that
+     * rather than performing resolution ourselves.
+     */
+
+    if (infoPtr->cachedObjectVar) {
+	return infoPtr->cachedObjectVar;
+    }
+
+    /*
+     * Check if the variable is one we want to resolve at all (i.e. whether it
+     * is in the list provided by the user). If not, we mustn't do anything
+     * either.
+     */
+
+    varName = TclGetStringFromObj(infoPtr->variableObj, &varLen);
+    if (contextPtr->callPtr->chain[contextPtr->index]
+	    .mPtr->declaringClassPtr != NULL) {
+	FOREACH(variableObj, contextPtr->callPtr->chain[contextPtr->index]
+		.mPtr->declaringClassPtr->variables) {
+	    match = TclGetStringFromObj(variableObj, &len);
+	    if ((len == varLen) && !memcmp(match, varName, len)) {
+		cacheIt = 0;
+		goto gotMatch;
+	    }
+	}
+    } else {
+	FOREACH(variableObj, contextPtr->oPtr->variables) {
+	    match = TclGetStringFromObj(variableObj, &len);
+	    if ((len == varLen) && !memcmp(match, varName, len)) {
+		cacheIt = 1;
+		goto gotMatch;
+	    }
+	}
+    }
+    return NULL;
+
+    /*
+     * It is a variable we want to resolve, so resolve it.
+     */
+
+  gotMatch:
+    hPtr = Tcl_CreateHashEntry(TclVarTable(contextPtr->oPtr->namespacePtr),
+	    (char *) variableObj, &isNew);
+    if (isNew) {
+	TclSetVarNamespaceVar((Var *) TclVarHashGetValue(hPtr));
+    }
+    if (cacheIt) {
+	infoPtr->cachedObjectVar = TclVarHashGetValue(hPtr);
+
+	/*
+	 * We must keep a reference to the variable so everything will
+	 * continue to work correctly even if it is unset; being unset does
+	 * not end the life of the variable at this level. [Bug 3185009]
+	 */
+
+	VarHashRefCount(infoPtr->cachedObjectVar)++;
+    }
+    return TclVarHashGetValue(hPtr);
+}
+
+static void
+ProcedureMethodCompiledVarDelete(
+    Tcl_ResolvedVarInfo *rPtr)
+{
+    OOResVarInfo *infoPtr = (OOResVarInfo *) rPtr;
+
+    /*
+     * Release the reference to the variable if we were holding it.
+     */
+
+    if (infoPtr->cachedObjectVar) {
+	VarHashRefCount(infoPtr->cachedObjectVar)--;
+	TclCleanupVar((Var *) infoPtr->cachedObjectVar, NULL);
+    }
+    Tcl_DecrRefCount(infoPtr->variableObj);
+    ckfree(infoPtr);
+}
+
+static int
+ProcedureMethodCompiledVarResolver(
+    Tcl_Interp *interp,
+    const char *varName,
+    int length,
+    Tcl_Namespace *contextNs,
+    Tcl_ResolvedVarInfo **rPtrPtr)
+{
+    OOResVarInfo *infoPtr;
+    Tcl_Obj *variableObj = Tcl_NewStringObj(varName, length);
+
+    /*
+     * Do not create resolvers for cases that contain namespace separators or
+     * which look like array accesses. Both will lead us astray.
+     */
+
+    if (strstr(Tcl_GetString(variableObj), "::") != NULL ||
+	    Tcl_StringMatch(Tcl_GetString(variableObj), "*(*)")) {
+	Tcl_DecrRefCount(variableObj);
+	return TCL_CONTINUE;
+    }
+
+    infoPtr = ckalloc(sizeof(OOResVarInfo));
+    infoPtr->info.fetchProc = ProcedureMethodCompiledVarConnect;
+    infoPtr->info.deleteProc = ProcedureMethodCompiledVarDelete;
+    infoPtr->cachedObjectVar = NULL;
+    infoPtr->variableObj = variableObj;
+    Tcl_IncrRefCount(variableObj);
+    *rPtrPtr = &infoPtr->info;
+    return TCL_OK;
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * RenderDeclarerName --
+ *
+ *	Returns the name of the entity (object or class) which declared a
+ *	method. Used for producing information for [info frame] in such a way
+ *	that the expensive part of this (generating the object or class name
+ *	itself) isn't done until it is needed.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+static Tcl_Obj *
+RenderDeclarerName(
+    ClientData clientData)
+{
+    struct PNI *pni = clientData;
+    Tcl_Object object = Tcl_MethodDeclarerObject(pni->method);
+
+    if (object == NULL) {
+	object = Tcl_GetClassAsObject(Tcl_MethodDeclarerClass(pni->method));
+    }
+    return TclOOObjectName(pni->interp, (Object *) object);
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * MethodErrorHandler, ConstructorErrorHandler, DestructorErrorHandler --
+ *
+ *	How to fill in the stack trace correctly upon error in various forms
+ *	of procedure-like methods. LIMIT is how long the inserted strings in
+ *	the error traces should get before being converted to have ellipses,
+ *	and ELLIPSIFY is a macro to do the conversion (with the help of a
+ *	%.*s%s format field). Note that ELLIPSIFY is only safe for use in
+ *	suitable formatting contexts.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+#define LIMIT 60
+#define ELLIPSIFY(str,len) \
+	((len) > LIMIT ? LIMIT : (len)), (str), ((len) > LIMIT ? "..." : "")
+
+static void
+MethodErrorHandler(
+    Tcl_Interp *interp,
+    Tcl_Obj *methodNameObj)
+{
+    int nameLen, objectNameLen;
+    CallContext *contextPtr = ((Interp *) interp)->varFramePtr->clientData;
+    Method *mPtr = contextPtr->callPtr->chain[contextPtr->index].mPtr;
+    const char *objectName, *kindName, *methodName =
+	    Tcl_GetStringFromObj(mPtr->namePtr, &nameLen);
+    Object *declarerPtr;
+
+    if (mPtr->declaringObjectPtr != NULL) {
+	declarerPtr = mPtr->declaringObjectPtr;
+	kindName = "object";
+    } else {
+	if (mPtr->declaringClassPtr == NULL) {
+	    Tcl_Panic("method not declared in class or object");
+	}
+	declarerPtr = mPtr->declaringClassPtr->thisPtr;
+	kindName = "class";
+    }
+
+    objectName = Tcl_GetStringFromObj(TclOOObjectName(interp, declarerPtr),
+	    &objectNameLen);
+    Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf(
+	    "\n    (%s \"%.*s%s\" method \"%.*s%s\" line %d)",
+	    kindName, ELLIPSIFY(objectName, objectNameLen),
+	    ELLIPSIFY(methodName, nameLen), Tcl_GetErrorLine(interp)));
+}
+
+static void
+ConstructorErrorHandler(
+    Tcl_Interp *interp,
+    Tcl_Obj *methodNameObj)
+{
+    CallContext *contextPtr = ((Interp *) interp)->varFramePtr->clientData;
+    Method *mPtr = contextPtr->callPtr->chain[contextPtr->index].mPtr;
+    Object *declarerPtr;
+    const char *objectName, *kindName;
+    int objectNameLen;
+
+    if (mPtr->declaringObjectPtr != NULL) {
+	declarerPtr = mPtr->declaringObjectPtr;
+	kindName = "object";
+    } else {
+	if (mPtr->declaringClassPtr == NULL) {
+	    Tcl_Panic("method not declared in class or object");
+	}
+	declarerPtr = mPtr->declaringClassPtr->thisPtr;
+	kindName = "class";
+    }
+
+    objectName = Tcl_GetStringFromObj(TclOOObjectName(interp, declarerPtr),
+	    &objectNameLen);
+    Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf(
+	    "\n    (%s \"%.*s%s\" constructor line %d)", kindName,
+	    ELLIPSIFY(objectName, objectNameLen), Tcl_GetErrorLine(interp)));
+}
+
+static void
+DestructorErrorHandler(
+    Tcl_Interp *interp,
+    Tcl_Obj *methodNameObj)
+{
+    CallContext *contextPtr = ((Interp *) interp)->varFramePtr->clientData;
+    Method *mPtr = contextPtr->callPtr->chain[contextPtr->index].mPtr;
+    Object *declarerPtr;
+    const char *objectName, *kindName;
+    int objectNameLen;
+
+    if (mPtr->declaringObjectPtr != NULL) {
+	declarerPtr = mPtr->declaringObjectPtr;
+	kindName = "object";
+    } else {
+	if (mPtr->declaringClassPtr == NULL) {
+	    Tcl_Panic("method not declared in class or object");
+	}
+	declarerPtr = mPtr->declaringClassPtr->thisPtr;
+	kindName = "class";
+    }
+
+    objectName = Tcl_GetStringFromObj(TclOOObjectName(interp, declarerPtr),
+	    &objectNameLen);
+    Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf(
+	    "\n    (%s \"%.*s%s\" destructor line %d)", kindName,
+	    ELLIPSIFY(objectName, objectNameLen), Tcl_GetErrorLine(interp)));
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * DeleteProcedureMethod, CloneProcedureMethod --
+ *
+ *	How to delete and clone procedure-like methods.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+static void
+DeleteProcedureMethodRecord(
+    ProcedureMethod *pmPtr)
+{
+    TclProcDeleteProc(pmPtr->procPtr);
+    if (pmPtr->deleteClientdataProc) {
+	pmPtr->deleteClientdataProc(pmPtr->clientData);
+    }
+    ckfree(pmPtr);
+}
+
+static void
+DeleteProcedureMethod(
+    ClientData clientData)
+{
+    register ProcedureMethod *pmPtr = clientData;
+
+    if (pmPtr->refCount-- <= 1) {
+	DeleteProcedureMethodRecord(pmPtr);
+    }
+}
+
+static int
+CloneProcedureMethod(
+    Tcl_Interp *interp,
+    ClientData clientData,
+    ClientData *newClientData)
+{
+    ProcedureMethod *pmPtr = clientData;
+    ProcedureMethod *pm2Ptr;
+    Tcl_Obj *bodyObj, *argsObj;
+    CompiledLocal *localPtr;
+
+    /*
+     * Copy the argument list.
+     */
+
+    argsObj = Tcl_NewObj();
+    for (localPtr=pmPtr->procPtr->firstLocalPtr; localPtr!=NULL;
+	    localPtr=localPtr->nextPtr) {
+	if (TclIsVarArgument(localPtr)) {
+	    Tcl_Obj *argObj = Tcl_NewObj();
+
+	    Tcl_ListObjAppendElement(NULL, argObj,
+		    Tcl_NewStringObj(localPtr->name, -1));
+	    if (localPtr->defValuePtr != NULL) {
+		Tcl_ListObjAppendElement(NULL, argObj, localPtr->defValuePtr);
+	    }
+	    Tcl_ListObjAppendElement(NULL, argsObj, argObj);
+	}
+    }
+
+    /*
+     * Must strip the internal representation in order to ensure that any
+     * bound references to instance variables are removed. [Bug 3609693]
+     */
+
+    bodyObj = Tcl_DuplicateObj(pmPtr->procPtr->bodyPtr);
+    TclFreeIntRep(bodyObj);
+
+    /*
+     * Create the actual copy of the method record, manufacturing a new proc
+     * record.
+     */
+
+    pm2Ptr = ckalloc(sizeof(ProcedureMethod));
+    memcpy(pm2Ptr, pmPtr, sizeof(ProcedureMethod));
+    pm2Ptr->refCount = 1;
+    Tcl_IncrRefCount(argsObj);
+    Tcl_IncrRefCount(bodyObj);
+    if (TclCreateProc(interp, NULL, "", argsObj, bodyObj,
+	    &pm2Ptr->procPtr) != TCL_OK) {
+	Tcl_DecrRefCount(argsObj);
+	Tcl_DecrRefCount(bodyObj);
+	ckfree(pm2Ptr);
+	return TCL_ERROR;
+    }
+    Tcl_DecrRefCount(argsObj);
+    Tcl_DecrRefCount(bodyObj);
+
+    if (pmPtr->cloneClientdataProc) {
+	pm2Ptr->clientData = pmPtr->cloneClientdataProc(pmPtr->clientData);
+    }
+    *newClientData = pm2Ptr;
+    return TCL_OK;
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * TclOONewForwardInstanceMethod --
+ *
+ *	Create a forwarded method for an object.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+Method *
+TclOONewForwardInstanceMethod(
+    Tcl_Interp *interp,		/* Interpreter for error reporting. */
+    Object *oPtr,		/* The object to attach the method to. */
+    int flags,			/* Whether the method is public or not. */
+    Tcl_Obj *nameObj,		/* The name of the method. */
+    Tcl_Obj *prefixObj)		/* List of arguments that form the command
+				 * prefix to forward to. */
+{
+    int prefixLen;
+    register ForwardMethod *fmPtr;
+
+    if (Tcl_ListObjLength(interp, prefixObj, &prefixLen) != TCL_OK) {
+	return NULL;
+    }
+    if (prefixLen < 1) {
+	Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		"method forward prefix must be non-empty", -1));
+	Tcl_SetErrorCode(interp, "TCL", "OO", "BAD_FORWARD", NULL);
+	return NULL;
+    }
+
+    fmPtr = ckalloc(sizeof(ForwardMethod));
+    fmPtr->prefixObj = prefixObj;
+    Tcl_IncrRefCount(prefixObj);
+    return (Method *) Tcl_NewInstanceMethod(interp, (Tcl_Object) oPtr,
+	    nameObj, flags, &fwdMethodType, fmPtr);
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * TclOONewForwardMethod --
+ *
+ *	Create a new forwarded method for a class.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+Method *
+TclOONewForwardMethod(
+    Tcl_Interp *interp,		/* Interpreter for error reporting. */
+    Class *clsPtr,		/* The class to attach the method to. */
+    int flags,			/* Whether the method is public or not. */
+    Tcl_Obj *nameObj,		/* The name of the method. */
+    Tcl_Obj *prefixObj)		/* List of arguments that form the command
+				 * prefix to forward to. */
+{
+    int prefixLen;
+    register ForwardMethod *fmPtr;
+
+    if (Tcl_ListObjLength(interp, prefixObj, &prefixLen) != TCL_OK) {
+	return NULL;
+    }
+    if (prefixLen < 1) {
+	Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		"method forward prefix must be non-empty", -1));
+	Tcl_SetErrorCode(interp, "TCL", "OO", "BAD_FORWARD", NULL);
+	return NULL;
+    }
+
+    fmPtr = ckalloc(sizeof(ForwardMethod));
+    fmPtr->prefixObj = prefixObj;
+    Tcl_IncrRefCount(prefixObj);
+    return (Method *) Tcl_NewMethod(interp, (Tcl_Class) clsPtr, nameObj,
+	    flags, &fwdMethodType, fmPtr);
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * InvokeForwardMethod --
+ *
+ *	How to invoke a forwarded method. Works by doing some ensemble-like
+ *	command rearranging and then invokes some other Tcl command.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+static int
+InvokeForwardMethod(
+    ClientData clientData,	/* Pointer to some per-method context. */
+    Tcl_Interp *interp,
+    Tcl_ObjectContext context,	/* The method calling context. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const *objv)	/* Arguments as actually seen. */
+{
+    CallContext *contextPtr = (CallContext *) context;
+    ForwardMethod *fmPtr = clientData;
+    Tcl_Obj **argObjs, **prefixObjs;
+    int numPrefixes, len, skip = contextPtr->skip;
+
+    /*
+     * Build the real list of arguments to use. Note that we know that the
+     * prefixObj field of the ForwardMethod structure holds a reference to a
+     * non-empty list, so there's a whole class of failures ("not a list") we
+     * can ignore here.
+     */
+
+    Tcl_ListObjGetElements(NULL, fmPtr->prefixObj, &numPrefixes, &prefixObjs);
+    argObjs = InitEnsembleRewrite(interp, objc, objv, skip,
+	    numPrefixes, prefixObjs, &len);
+    Tcl_NRAddCallback(interp, FinalizeForwardCall, argObjs, NULL, NULL, NULL);
+    /*
+     * NOTE: The combination of direct set of iPtr->lookupNsPtr and the use
+     * of the TCL_EVAL_NOERR flag results in an evaluation configuration
+     * very much like TCL_EVAL_INVOKE.
+     */
+    ((Interp *)interp)->lookupNsPtr
+	    = (Namespace *) contextPtr->oPtr->namespacePtr;
+    return TclNREvalObjv(interp, len, argObjs, TCL_EVAL_NOERR, NULL);
+}
+
+static int
+FinalizeForwardCall(
+    ClientData data[],
+    Tcl_Interp *interp,
+    int result)
+{
+    Tcl_Obj **argObjs = data[0];
+
+    TclStackFree(interp, argObjs);
+    return result;
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * DeleteForwardMethod, CloneForwardMethod --
+ *
+ *	How to delete and clone forwarded methods.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+static void
+DeleteForwardMethod(
+    ClientData clientData)
+{
+    ForwardMethod *fmPtr = clientData;
+
+    Tcl_DecrRefCount(fmPtr->prefixObj);
+    ckfree(fmPtr);
+}
+
+static int
+CloneForwardMethod(
+    Tcl_Interp *interp,
+    ClientData clientData,
+    ClientData *newClientData)
+{
+    ForwardMethod *fmPtr = clientData;
+    ForwardMethod *fm2Ptr = ckalloc(sizeof(ForwardMethod));
+
+    fm2Ptr->prefixObj = fmPtr->prefixObj;
+    Tcl_IncrRefCount(fm2Ptr->prefixObj);
+    *newClientData = fm2Ptr;
+    return TCL_OK;
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * TclOOGetProcFromMethod, TclOOGetFwdFromMethod --
+ *
+ *	Utility functions used for procedure-like and forwarding method
+ *	introspection.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+Proc *
+TclOOGetProcFromMethod(
+    Method *mPtr)
+{
+    if (mPtr->typePtr == &procMethodType) {
+	ProcedureMethod *pmPtr = mPtr->clientData;
+
+	return pmPtr->procPtr;
+    }
+    return NULL;
+}
+
+Tcl_Obj *
+TclOOGetMethodBody(
+    Method *mPtr)
+{
+    if (mPtr->typePtr == &procMethodType) {
+	ProcedureMethod *pmPtr = mPtr->clientData;
+
+	if (pmPtr->procPtr->bodyPtr->bytes == NULL) {
+	    (void) Tcl_GetString(pmPtr->procPtr->bodyPtr);
+	}
+	return pmPtr->procPtr->bodyPtr;
+    }
+    return NULL;
+}
+
+Tcl_Obj *
+TclOOGetFwdFromMethod(
+    Method *mPtr)
+{
+    if (mPtr->typePtr == &fwdMethodType) {
+	ForwardMethod *fwPtr = mPtr->clientData;
+
+	return fwPtr->prefixObj;
+    }
+    return NULL;
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * InitEnsembleRewrite --
+ *
+ *	Utility function that wraps up a lot of the complexity involved in
+ *	doing ensemble-like command forwarding. Here is a picture of memory
+ *	management plan:
+ *
+ *                    <-----------------objc---------------------->
+ *      objv:        |=============|===============================|
+ *                    <-toRewrite->           |
+ *                                             \
+ *                    <-rewriteLength->         \
+ *      rewriteObjs: |=================|         \
+ *                           |                    |
+ *                           V                    V
+ *      argObjs:     |=================|===============================|
+ *                    <------------------*lengthPtr------------------->
+ *
+ * ----------------------------------------------------------------------
+ */
+
+static Tcl_Obj **
+InitEnsembleRewrite(
+    Tcl_Interp *interp,		/* Place to log the rewrite info. */
+    int objc,			/* Number of real arguments. */
+    Tcl_Obj *const *objv,	/* The real arguments. */
+    int toRewrite,		/* Number of real arguments to replace. */
+    int rewriteLength,		/* Number of arguments to insert instead. */
+    Tcl_Obj *const *rewriteObjs,/* Arguments to insert instead. */
+    int *lengthPtr)		/* Where to write the resulting length of the
+				 * array of rewritten arguments. */
+{
+    unsigned len = rewriteLength + objc - toRewrite;
+    Tcl_Obj **argObjs = TclStackAlloc(interp, sizeof(Tcl_Obj *) * len);
+
+    memcpy(argObjs, rewriteObjs, rewriteLength * sizeof(Tcl_Obj *));
+    memcpy(argObjs + rewriteLength, objv + toRewrite,
+	    sizeof(Tcl_Obj *) * (objc - toRewrite));
+
+    /*
+     * Now plumb this into the core ensemble rewrite logging system so that
+     * Tcl_WrongNumArgs() can rewrite its result appropriately. The rules for
+     * how to store the rewrite rules get complex solely because of the case
+     * where an ensemble rewrites itself out of the picture; when that
+     * happens, the quality of the error message rewrite falls drastically
+     * (and unavoidably).
+     */
+
+    if (TclInitRewriteEnsemble(interp, toRewrite, rewriteLength, objv)) {
+	TclNRAddCallback(interp, TclClearRootEnsemble, NULL, NULL, NULL, NULL);
+    }
+    *lengthPtr = len;
+    return argObjs;
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * assorted trivial 'getter' functions
+ *
+ * ----------------------------------------------------------------------
+ */
+
+Tcl_Object
+Tcl_MethodDeclarerObject(
+    Tcl_Method method)
+{
+    return (Tcl_Object) ((Method *) method)->declaringObjectPtr;
+}
+
+Tcl_Class
+Tcl_MethodDeclarerClass(
+    Tcl_Method method)
+{
+    return (Tcl_Class) ((Method *) method)->declaringClassPtr;
+}
+
+Tcl_Obj *
+Tcl_MethodName(
+    Tcl_Method method)
+{
+    return ((Method *) method)->namePtr;
+}
+
+int
+Tcl_MethodIsType(
+    Tcl_Method method,
+    const Tcl_MethodType *typePtr,
+    ClientData *clientDataPtr)
+{
+    Method *mPtr = (Method *) method;
+
+    if (mPtr->typePtr == typePtr) {
+	if (clientDataPtr != NULL) {
+	    *clientDataPtr = mPtr->clientData;
+	}
+	return 1;
+    }
+    return 0;
+}
+
+int
+Tcl_MethodIsPublic(
+    Tcl_Method method)
+{
+    return (((Method *)method)->flags & PUBLIC_METHOD) ? 1 : 0;
+}
+
+/*
+ * Extended method construction for itcl-ng.
+ */
+
+Tcl_Method
+TclOONewProcInstanceMethodEx(
+    Tcl_Interp *interp,		/* The interpreter containing the object. */
+    Tcl_Object oPtr,		/* The object to modify. */
+    TclOO_PreCallProc *preCallPtr,
+    TclOO_PostCallProc *postCallPtr,
+    ProcErrorProc *errProc,
+    ClientData clientData,
+    Tcl_Obj *nameObj,		/* The name of the method, which must not be
+				 * NULL. */
+    Tcl_Obj *argsObj,		/* The formal argument list for the method,
+				 * which must not be NULL. */
+    Tcl_Obj *bodyObj,		/* The body of the method, which must not be
+				 * NULL. */
+    int flags,			/* Whether this is a public method. */
+    void **internalTokenPtr)	/* If non-NULL, points to a variable that gets
+				 * the reference to the ProcedureMethod
+				 * structure. */
+{
+    ProcedureMethod *pmPtr;
+    Tcl_Method method = (Tcl_Method) TclOONewProcInstanceMethod(interp,
+	    (Object *) oPtr, flags, nameObj, argsObj, bodyObj, &pmPtr);
+
+    if (method == NULL) {
+	return NULL;
+    }
+    pmPtr->flags = flags & USE_DECLARER_NS;
+    pmPtr->preCallProc = preCallPtr;
+    pmPtr->postCallProc = postCallPtr;
+    pmPtr->errProc = errProc;
+    pmPtr->clientData = clientData;
+    if (internalTokenPtr != NULL) {
+	*internalTokenPtr = pmPtr;
+    }
+    return method;
+}
+
+Tcl_Method
+TclOONewProcMethodEx(
+    Tcl_Interp *interp,		/* The interpreter containing the class. */
+    Tcl_Class clsPtr,		/* The class to modify. */
+    TclOO_PreCallProc *preCallPtr,
+    TclOO_PostCallProc *postCallPtr,
+    ProcErrorProc *errProc,
+    ClientData clientData,
+    Tcl_Obj *nameObj,		/* The name of the method, which may be NULL;
+				 * if so, up to caller to manage storage
+				 * (e.g., because it is a constructor or
+				 * destructor). */
+    Tcl_Obj *argsObj,		/* The formal argument list for the method,
+				 * which may be NULL; if so, it is equivalent
+				 * to an empty list. */
+    Tcl_Obj *bodyObj,		/* The body of the method, which must not be
+				 * NULL. */
+    int flags,			/* Whether this is a public method. */
+    void **internalTokenPtr)	/* If non-NULL, points to a variable that gets
+				 * the reference to the ProcedureMethod
+				 * structure. */
+{
+    ProcedureMethod *pmPtr;
+    Tcl_Method method = (Tcl_Method) TclOONewProcMethod(interp,
+	    (Class *) clsPtr, flags, nameObj, argsObj, bodyObj, &pmPtr);
+
+    if (method == NULL) {
+	return NULL;
+    }
+    pmPtr->flags = flags & USE_DECLARER_NS;
+    pmPtr->preCallProc = preCallPtr;
+    pmPtr->postCallProc = postCallPtr;
+    pmPtr->errProc = errProc;
+    pmPtr->clientData = clientData;
+    if (internalTokenPtr != NULL) {
+	*internalTokenPtr = pmPtr;
+    }
+    return method;
+}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tclOOStubInit.c b/generic/tclOOStubInit.c
new file mode 100644
index 0000000..900ab22
--- /dev/null
+++ b/generic/tclOOStubInit.c
@@ -0,0 +1,78 @@
+/*
+ * This file is (mostly) automatically generated from tclOO.decls.
+ * It is compiled and linked in with the tclOO package proper.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include "tclOOInt.h"
+
+MODULE_SCOPE const TclOOStubs tclOOStubs;
+
+#ifdef __GNUC__
+#pragma GCC dependency "tclOO.decls"
+#endif
+
+/* !BEGIN!: Do not edit below this line. */
+
+static const TclOOIntStubs tclOOIntStubs = {
+    TCL_STUB_MAGIC,
+    0,
+    TclOOGetDefineCmdContext, /* 0 */
+    TclOOMakeProcInstanceMethod, /* 1 */
+    TclOOMakeProcMethod, /* 2 */
+    TclOONewProcInstanceMethod, /* 3 */
+    TclOONewProcMethod, /* 4 */
+    TclOOObjectCmdCore, /* 5 */
+    TclOOIsReachable, /* 6 */
+    TclOONewForwardMethod, /* 7 */
+    TclOONewForwardInstanceMethod, /* 8 */
+    TclOONewProcInstanceMethodEx, /* 9 */
+    TclOONewProcMethodEx, /* 10 */
+    TclOOInvokeObject, /* 11 */
+    TclOOObjectSetFilters, /* 12 */
+    TclOOClassSetFilters, /* 13 */
+    TclOOObjectSetMixins, /* 14 */
+    TclOOClassSetMixins, /* 15 */
+};
+
+static const TclOOStubHooks tclOOStubHooks = {
+    &tclOOIntStubs
+};
+
+const TclOOStubs tclOOStubs = {
+    TCL_STUB_MAGIC,
+    &tclOOStubHooks,
+    Tcl_CopyObjectInstance, /* 0 */
+    Tcl_GetClassAsObject, /* 1 */
+    Tcl_GetObjectAsClass, /* 2 */
+    Tcl_GetObjectCommand, /* 3 */
+    Tcl_GetObjectFromObj, /* 4 */
+    Tcl_GetObjectNamespace, /* 5 */
+    Tcl_MethodDeclarerClass, /* 6 */
+    Tcl_MethodDeclarerObject, /* 7 */
+    Tcl_MethodIsPublic, /* 8 */
+    Tcl_MethodIsType, /* 9 */
+    Tcl_MethodName, /* 10 */
+    Tcl_NewInstanceMethod, /* 11 */
+    Tcl_NewMethod, /* 12 */
+    Tcl_NewObjectInstance, /* 13 */
+    Tcl_ObjectDeleted, /* 14 */
+    Tcl_ObjectContextIsFiltering, /* 15 */
+    Tcl_ObjectContextMethod, /* 16 */
+    Tcl_ObjectContextObject, /* 17 */
+    Tcl_ObjectContextSkippedArgs, /* 18 */
+    Tcl_ClassGetMetadata, /* 19 */
+    Tcl_ClassSetMetadata, /* 20 */
+    Tcl_ObjectGetMetadata, /* 21 */
+    Tcl_ObjectSetMetadata, /* 22 */
+    Tcl_ObjectContextInvokeNext, /* 23 */
+    Tcl_ObjectGetMethodNameMapper, /* 24 */
+    Tcl_ObjectSetMethodNameMapper, /* 25 */
+    Tcl_ClassSetConstructor, /* 26 */
+    Tcl_ClassSetDestructor, /* 27 */
+    Tcl_GetObjectName, /* 28 */
+};
+
+/* !END!: Do not edit above this line. */
diff --git a/generic/tclOOStubLib.c b/generic/tclOOStubLib.c
new file mode 100644
index 0000000..a9fa212
--- /dev/null
+++ b/generic/tclOOStubLib.c
@@ -0,0 +1,71 @@
+/*
+ * ORIGINAL SOURCE: tk/generic/tkStubLib.c, version 1.9 2004/03/17
+ */
+
+#include "tclOOInt.h"
+
+MODULE_SCOPE const TclOOStubs *tclOOStubsPtr;
+MODULE_SCOPE const TclOOIntStubs *tclOOIntStubsPtr;
+
+const TclOOStubs *tclOOStubsPtr = NULL;
+const TclOOIntStubs *tclOOIntStubsPtr = NULL;
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclOOInitializeStubs --
+ *	Load the tclOO package, initialize stub table pointer. Do not call
+ *	this function directly, use Tcl_OOInitStubs() macro instead.
+ *
+ * Results:
+ *	The actual version of the package that satisfies the request, or NULL
+ *	to indicate that an error occurred.
+ *
+ * Side effects:
+ *	Sets the stub table pointers.
+ *
+ *----------------------------------------------------------------------
+ */
+
+#undef TclOOInitializeStubs
+
+MODULE_SCOPE const char *
+TclOOInitializeStubs(
+    Tcl_Interp *interp,
+    const char *version)
+{
+    int exact = 0;
+    const char *packageName = "TclOO";
+    const char *errMsg = NULL;
+    TclOOStubs *stubsPtr = NULL;
+    const char *actualVersion = tclStubsPtr->tcl_PkgRequireEx(interp,
+	    packageName, version, exact, &stubsPtr);
+
+    if (actualVersion == NULL) {
+	return NULL;
+    }
+    if (stubsPtr == NULL) {
+	errMsg = "missing stub table pointer";
+    } else {
+	tclOOStubsPtr = stubsPtr;
+	if (stubsPtr->hooks) {
+	    tclOOIntStubsPtr = stubsPtr->hooks->tclOOIntStubs;
+	} else {
+	    tclOOIntStubsPtr = NULL;
+	}
+	return actualVersion;
+    }
+    tclStubsPtr->tcl_ResetResult(interp);
+    tclStubsPtr->tcl_AppendResult(interp, "Error loading ", packageName,
+	    " (requested version ", version, ", actual version ",
+	    actualVersion, "): ", errMsg, NULL);
+    return NULL;
+}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tclObj.c b/generic/tclObj.c
new file mode 100644
index 0000000..628c3a7
--- /dev/null
+++ b/generic/tclObj.c
@@ -0,0 +1,4519 @@
+/*
+ * tclObj.c --
+ *
+ *	This file contains Tcl object-related functions that are used by many
+ *	Tcl commands.
+ *
+ * Copyright (c) 1995-1997 Sun Microsystems, Inc.
+ * Copyright (c) 1999 by Scriptics Corporation.
+ * Copyright (c) 2001 by ActiveState Corporation.
+ * Copyright (c) 2005 by Kevin B. Kenny.  All rights reserved.
+ * Copyright (c) 2007 Daniel A. Steffen <das@users.sourceforge.net>
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#include "tclInt.h"
+#include "tommath.h"
+#include <math.h>
+
+/*
+ * Table of all object types.
+ */
+
+static Tcl_HashTable typeTable;
+static int typeTableInitialized = 0;	/* 0 means not yet initialized. */
+TCL_DECLARE_MUTEX(tableMutex)
+
+/*
+ * Head of the list of free Tcl_Obj structs we maintain.
+ */
+
+Tcl_Obj *tclFreeObjList = NULL;
+
+/*
+ * The object allocator is single threaded. This mutex is referenced by the
+ * TclNewObj macro, however, so must be visible.
+ */
+
+#ifdef TCL_THREADS
+MODULE_SCOPE Tcl_Mutex tclObjMutex;
+Tcl_Mutex tclObjMutex;
+#endif
+
+/*
+ * Pointer to a heap-allocated string of length zero that the Tcl core uses as
+ * the value of an empty string representation for an object. This value is
+ * shared by all new objects allocated by Tcl_NewObj.
+ */
+
+char tclEmptyString = '\0';
+char *tclEmptyStringRep = &tclEmptyString;
+
+#if defined(TCL_MEM_DEBUG) && defined(TCL_THREADS)
+/*
+ * Structure for tracking the source file and line number where a given
+ * Tcl_Obj was allocated.  We also track the pointer to the Tcl_Obj itself,
+ * for sanity checking purposes.
+ */
+
+typedef struct ObjData {
+    Tcl_Obj *objPtr;		/* The pointer to the allocated Tcl_Obj. */
+    const char *file;		/* The name of the source file calling this
+				 * function; used for debugging. */
+    int line;			/* Line number in the source file; used for
+				 * debugging. */
+} ObjData;
+#endif /* TCL_MEM_DEBUG && TCL_THREADS */
+
+/*
+ * All static variables used in this file are collected into a single instance
+ * of the following structure.  For multi-threaded implementations, there is
+ * one instance of this structure for each thread.
+ *
+ * Notice that different structures with the same name appear in other files.
+ * The structure defined below is used in this file only.
+ */
+
+typedef struct ThreadSpecificData {
+    Tcl_HashTable *lineCLPtr;   /* This table remembers for each Tcl_Obj
+                                 * generated by a call to the function
+                                 * TclSubstTokens() from a literal text
+                                 * where bs+nl sequences occured in it, if
+                                 * any. I.e. this table keeps track of
+                                 * invisible and stripped continuation lines.
+                                 * Its keys are Tcl_Obj pointers, the values
+                                 * are ContLineLoc pointers. See the file
+                                 * tclCompile.h for the definition of this
+                                 * structure, and for references to all
+                                 * related places in the core. */
+#if defined(TCL_MEM_DEBUG) && defined(TCL_THREADS)
+    Tcl_HashTable *objThreadMap;/* Thread local table that is used to check
+                                 * that a Tcl_Obj was not allocated by some
+                                 * other thread. */
+#endif /* TCL_MEM_DEBUG && TCL_THREADS */
+} ThreadSpecificData;
+
+static Tcl_ThreadDataKey dataKey;
+
+static void             TclThreadFinalizeContLines(ClientData clientData);
+static ThreadSpecificData *TclGetContLineTable(void);
+
+/*
+ * Nested Tcl_Obj deletion management support
+ *
+ * All context references used in the object freeing code are pointers to this
+ * structure; every thread will have its own structure instance. The purpose
+ * of this structure is to allow deeply nested collections of Tcl_Objs to be
+ * freed without taking a vast depth of C stack (which could cause all sorts
+ * of breakage.)
+ */
+
+typedef struct PendingObjData {
+    int deletionCount;		/* Count of the number of invokations of
+				 * TclFreeObj() are on the stack (at least
+				 * conceptually; many are actually expanded
+				 * macros). */
+    Tcl_Obj *deletionStack;	/* Stack of objects that have had TclFreeObj()
+				 * invoked upon them but which can't be
+				 * deleted yet because they are in a nested
+				 * invokation of TclFreeObj(). By postponing
+				 * this way, we limit the maximum overall C
+				 * stack depth when deleting a complex object.
+				 * The down-side is that we alter the overall
+				 * behaviour by altering the order in which
+				 * objects are deleted, and we change the
+				 * order in which the string rep and the
+				 * internal rep of an object are deleted. Note
+				 * that code which assumes the previous
+				 * behaviour in either of these respects is
+				 * unsafe anyway; it was never documented as
+				 * to exactly what would happen in these
+				 * cases, and the overall contract of a
+				 * user-level Tcl_DecrRefCount() is still
+				 * preserved (assuming that a particular T_DRC
+				 * would delete an object is not very
+				 * safe). */
+} PendingObjData;
+
+/*
+ * These are separated out so that some semantic content is attached
+ * to them.
+ */
+#define ObjDeletionLock(contextPtr)	((contextPtr)->deletionCount++)
+#define ObjDeletionUnlock(contextPtr)	((contextPtr)->deletionCount--)
+#define ObjDeletePending(contextPtr)	((contextPtr)->deletionCount > 0)
+#define ObjOnStack(contextPtr)		((contextPtr)->deletionStack != NULL)
+#define PushObjToDelete(contextPtr,objPtr) \
+    /* The string rep is already invalidated so we can use the bytes value \
+     * for our pointer chain: push onto the head of the stack. */       \
+    (objPtr)->bytes = (char *) ((contextPtr)->deletionStack);           \
+    (contextPtr)->deletionStack = (objPtr)
+#define PopObjToDelete(contextPtr,objPtrVar) \
+    (objPtrVar) = (contextPtr)->deletionStack;                          \
+    (contextPtr)->deletionStack = (Tcl_Obj *) (objPtrVar)->bytes
+
+/*
+ * Macro to set up the local reference to the deletion context.
+ */
+#ifndef TCL_THREADS
+static PendingObjData pendingObjData;
+#define ObjInitDeletionContext(contextPtr) \
+    PendingObjData *const contextPtr = &pendingObjData
+#elif HAVE_FAST_TSD
+static __thread PendingObjData pendingObjData;
+#define ObjInitDeletionContext(contextPtr) \
+    PendingObjData *const contextPtr = &pendingObjData
+#else
+static Tcl_ThreadDataKey pendingObjDataKey;
+#define ObjInitDeletionContext(contextPtr) \
+    PendingObjData *const contextPtr =                                  \
+	    Tcl_GetThreadData(&pendingObjDataKey, sizeof(PendingObjData))
+#endif
+
+/*
+ * Macros to pack/unpack a bignum's fields in a Tcl_Obj internal rep
+ */
+
+#define PACK_BIGNUM(bignum, objPtr) \
+    if ((bignum).used > 0x7fff) {                                       \
+	mp_int *temp = (void *) ckalloc((unsigned) sizeof(mp_int));     \
+	*temp = bignum;                                                 \
+	(objPtr)->internalRep.twoPtrValue.ptr1 = temp;                 \
+	(objPtr)->internalRep.twoPtrValue.ptr2 = INT2PTR(-1); \
+    } else {                                                            \
+	if ((bignum).alloc > 0x7fff) {                                  \
+	    mp_shrink(&(bignum));                                       \
+	}                                                               \
+	(objPtr)->internalRep.twoPtrValue.ptr1 = (void *) (bignum).dp; \
+	(objPtr)->internalRep.twoPtrValue.ptr2 = INT2PTR( ((bignum).sign << 30) \
+		| ((bignum).alloc << 15) | ((bignum).used));            \
+    }
+
+#define UNPACK_BIGNUM(objPtr, bignum) \
+    if ((objPtr)->internalRep.twoPtrValue.ptr2 == INT2PTR(-1)) { \
+	(bignum) = *((mp_int *) ((objPtr)->internalRep.twoPtrValue.ptr1)); \
+    } else {                                                            \
+	(bignum).dp = (objPtr)->internalRep.twoPtrValue.ptr1;          \
+	(bignum).sign = PTR2INT((objPtr)->internalRep.twoPtrValue.ptr2) >> 30; \
+	(bignum).alloc =                                                \
+		(PTR2INT((objPtr)->internalRep.twoPtrValue.ptr2) >> 15) & 0x7fff; \
+	(bignum).used = PTR2INT((objPtr)->internalRep.twoPtrValue.ptr2) & 0x7fff; \
+    }
+
+/*
+ * Prototypes for functions defined later in this file:
+ */
+
+static int		ParseBoolean(Tcl_Obj *objPtr);
+static int		SetDoubleFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr);
+static int		SetIntFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr);
+static void		UpdateStringOfDouble(Tcl_Obj *objPtr);
+static void		UpdateStringOfInt(Tcl_Obj *objPtr);
+#ifndef TCL_WIDE_INT_IS_LONG
+static void		UpdateStringOfWideInt(Tcl_Obj *objPtr);
+static int		SetWideIntFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr);
+#endif
+static void		FreeBignum(Tcl_Obj *objPtr);
+static void		DupBignum(Tcl_Obj *objPtr, Tcl_Obj *copyPtr);
+static void		UpdateStringOfBignum(Tcl_Obj *objPtr);
+static int		GetBignumFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr,
+			    int copy, mp_int *bignumValue);
+
+/*
+ * Prototypes for the array hash key methods.
+ */
+
+static Tcl_HashEntry *	AllocObjEntry(Tcl_HashTable *tablePtr, void *keyPtr);
+
+/*
+ * Prototypes for the CommandName object type.
+ */
+
+static void		DupCmdNameInternalRep(Tcl_Obj *objPtr,
+			    Tcl_Obj *copyPtr);
+static void		FreeCmdNameInternalRep(Tcl_Obj *objPtr);
+static int		SetCmdNameFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr);
+
+/*
+ * The structures below defines the Tcl object types defined in this file by
+ * means of functions that can be invoked by generic object code. See also
+ * tclStringObj.c, tclListObj.c, tclByteCode.c for other type manager
+ * implementations.
+ */
+
+static const Tcl_ObjType oldBooleanType = {
+    "boolean",			/* name */
+    NULL,			/* freeIntRepProc */
+    NULL,			/* dupIntRepProc */
+    NULL,			/* updateStringProc */
+    TclSetBooleanFromAny		/* setFromAnyProc */
+};
+const Tcl_ObjType tclBooleanType = {
+    "booleanString",		/* name */
+    NULL,			/* freeIntRepProc */
+    NULL,			/* dupIntRepProc */
+    NULL,			/* updateStringProc */
+    TclSetBooleanFromAny		/* setFromAnyProc */
+};
+const Tcl_ObjType tclDoubleType = {
+    "double",			/* name */
+    NULL,			/* freeIntRepProc */
+    NULL,			/* dupIntRepProc */
+    UpdateStringOfDouble,	/* updateStringProc */
+    SetDoubleFromAny		/* setFromAnyProc */
+};
+const Tcl_ObjType tclIntType = {
+    "int",			/* name */
+    NULL,			/* freeIntRepProc */
+    NULL,			/* dupIntRepProc */
+    UpdateStringOfInt,		/* updateStringProc */
+    SetIntFromAny		/* setFromAnyProc */
+};
+#ifndef TCL_WIDE_INT_IS_LONG
+const Tcl_ObjType tclWideIntType = {
+    "wideInt",			/* name */
+    NULL,			/* freeIntRepProc */
+    NULL,			/* dupIntRepProc */
+    UpdateStringOfWideInt,	/* updateStringProc */
+    SetWideIntFromAny		/* setFromAnyProc */
+};
+#endif
+const Tcl_ObjType tclBignumType = {
+    "bignum",			/* name */
+    FreeBignum,			/* freeIntRepProc */
+    DupBignum,			/* dupIntRepProc */
+    UpdateStringOfBignum,	/* updateStringProc */
+    NULL			/* setFromAnyProc */
+};
+
+/*
+ * The structure below defines the Tcl obj hash key type.
+ */
+
+const Tcl_HashKeyType tclObjHashKeyType = {
+    TCL_HASH_KEY_TYPE_VERSION,	/* version */
+    0,				/* flags */
+    TclHashObjKey,		/* hashKeyProc */
+    TclCompareObjKeys,		/* compareKeysProc */
+    AllocObjEntry,		/* allocEntryProc */
+    TclFreeObjEntry		/* freeEntryProc */
+};
+
+/*
+ * The structure below defines the command name Tcl object type by means of
+ * functions that can be invoked by generic object code. Objects of this type
+ * cache the Command pointer that results from looking up command names in the
+ * command hashtable. Such objects appear as the zeroth ("command name")
+ * argument in a Tcl command.
+ *
+ * NOTE: the ResolvedCmdName that gets cached is stored in the
+ * twoPtrValue.ptr1 field, and the twoPtrValue.ptr2 field is unused. You might
+ * think you could use the simpler otherValuePtr field to store the single
+ * ResolvedCmdName pointer, but DO NOT DO THIS. It seems that some extensions
+ * use the second internal pointer field of the twoPtrValue field for their
+ * own purposes.
+ *
+ * TRICKY POINT! Some extensions update this structure! (Notably, these
+ * include TclBlend and TCom). This is highly ill-advised on their part, but
+ * does allow them to delete a command when references to it are gone, which
+ * is fragile but useful given their somewhat-OO style. Because of this, this
+ * structure MUST NOT be const so that the C compiler puts the data in
+ * writable memory. [Bug 2558422] [Bug 07d13d99b0a9]
+ * TODO: Provide a better API for those extensions so that they can coexist...
+ */
+
+Tcl_ObjType tclCmdNameType = {
+    "cmdName",			/* name */
+    FreeCmdNameInternalRep,	/* freeIntRepProc */
+    DupCmdNameInternalRep,	/* dupIntRepProc */
+    NULL,			/* updateStringProc */
+    SetCmdNameFromAny		/* setFromAnyProc */
+};
+
+/*
+ * Structure containing a cached pointer to a command that is the result of
+ * resolving the command's name in some namespace. It is the internal
+ * representation for a cmdName object. It contains the pointer along with
+ * some information that is used to check the pointer's validity.
+ */
+
+typedef struct ResolvedCmdName {
+    Command *cmdPtr;		/* A cached Command pointer. */
+    Namespace *refNsPtr;	/* Points to the namespace containing the
+				 * reference (not the namespace that contains
+				 * the referenced command). NULL if the name
+				 * is fully qualified.*/
+    long refNsId;		/* refNsPtr's unique namespace id. Used to
+				 * verify that refNsPtr is still valid (e.g.,
+				 * it's possible that the cmd's containing
+				 * namespace was deleted and a new one created
+				 * at the same address). */
+    int refNsCmdEpoch;		/* Value of the referencing namespace's
+				 * cmdRefEpoch when the pointer was cached.
+				 * Before using the cached pointer, we check
+				 * if the namespace's epoch was incremented;
+				 * if so, this cached pointer is invalid. */
+    int cmdEpoch;		/* Value of the command's cmdEpoch when this
+				 * pointer was cached. Before using the cached
+				 * pointer, we check if the cmd's epoch was
+				 * incremented; if so, the cmd was renamed,
+				 * deleted, hidden, or exposed, and so the
+				 * pointer is invalid. */
+    int refCount;		/* Reference count: 1 for each cmdName object
+				 * that has a pointer to this ResolvedCmdName
+				 * structure as its internal rep. This
+				 * structure can be freed when refCount
+				 * becomes zero. */
+} ResolvedCmdName;
+
+/*
+ *-------------------------------------------------------------------------
+ *
+ * TclInitObjectSubsystem --
+ *
+ *	This function is invoked to perform once-only initialization of the
+ *	type table. It also registers the object types defined in this file.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Initializes the table of defined object types "typeTable" with builtin
+ *	object types defined in this file.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+void
+TclInitObjSubsystem(void)
+{
+    Tcl_MutexLock(&tableMutex);
+    typeTableInitialized = 1;
+    Tcl_InitHashTable(&typeTable, TCL_STRING_KEYS);
+    Tcl_MutexUnlock(&tableMutex);
+
+    Tcl_RegisterObjType(&tclByteArrayType);
+    Tcl_RegisterObjType(&tclDoubleType);
+    Tcl_RegisterObjType(&tclEndOffsetType);
+    Tcl_RegisterObjType(&tclIntType);
+    Tcl_RegisterObjType(&tclStringType);
+    Tcl_RegisterObjType(&tclListType);
+    Tcl_RegisterObjType(&tclDictType);
+    Tcl_RegisterObjType(&tclByteCodeType);
+    Tcl_RegisterObjType(&tclArraySearchType);
+    Tcl_RegisterObjType(&tclCmdNameType);
+    Tcl_RegisterObjType(&tclRegexpType);
+    Tcl_RegisterObjType(&tclProcBodyType);
+
+    /* For backward compatibility only ... */
+    Tcl_RegisterObjType(&oldBooleanType);
+#ifndef TCL_WIDE_INT_IS_LONG
+    Tcl_RegisterObjType(&tclWideIntType);
+#endif
+
+#ifdef TCL_COMPILE_STATS
+    Tcl_MutexLock(&tclObjMutex);
+    tclObjsAlloced = 0;
+    tclObjsFreed = 0;
+    {
+	int i;
+
+	for (i=0 ; i<TCL_MAX_SHARED_OBJ_STATS ; i++) {
+	    tclObjsShared[i] = 0;
+	}
+    }
+    Tcl_MutexUnlock(&tclObjMutex);
+#endif
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclFinalizeThreadObjects --
+ *
+ *	This function is called by Tcl_FinalizeThread to clean up thread
+ *	specific Tcl_Obj information.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclFinalizeThreadObjects(void)
+{
+#if defined(TCL_MEM_DEBUG) && defined(TCL_THREADS)
+    Tcl_HashEntry *hPtr;
+    Tcl_HashSearch hSearch;
+    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+    Tcl_HashTable *tablePtr = tsdPtr->objThreadMap;
+
+    if (tablePtr != NULL) {
+	for (hPtr = Tcl_FirstHashEntry(tablePtr, &hSearch);
+		hPtr != NULL; hPtr = Tcl_NextHashEntry(&hSearch)) {
+	    ObjData *objData = Tcl_GetHashValue(hPtr);
+
+	    if (objData != NULL) {
+		ckfree(objData);
+	    }
+	}
+
+	Tcl_DeleteHashTable(tablePtr);
+	ckfree(tablePtr);
+	tsdPtr->objThreadMap = NULL;
+    }
+#endif
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclFinalizeObjects --
+ *
+ *	This function is called by Tcl_Finalize to clean up all registered
+ *	Tcl_ObjType's and to reset the tclFreeObjList.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclFinalizeObjects(void)
+{
+    Tcl_MutexLock(&tableMutex);
+    if (typeTableInitialized) {
+	Tcl_DeleteHashTable(&typeTable);
+	typeTableInitialized = 0;
+    }
+    Tcl_MutexUnlock(&tableMutex);
+
+    /*
+     * All we do here is reset the head pointer of the linked list of free
+     * Tcl_Obj's to NULL; the memory finalization will take care of releasing
+     * memory for us.
+     */
+    Tcl_MutexLock(&tclObjMutex);
+    tclFreeObjList = NULL;
+    Tcl_MutexUnlock(&tclObjMutex);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclGetContLineTable --
+ *
+ *	This procedure is a helper which returns the thread-specific
+ *	hash-table used to track continuation line information associated with
+ *	Tcl_Obj*, and the objThreadMap, etc.
+ *
+ * Results:
+ *	A reference to the thread-data.
+ *
+ * Side effects:
+ *	May allocate memory for the thread-data.
+ *
+ * TIP #280
+ *----------------------------------------------------------------------
+ */
+
+static ThreadSpecificData *
+TclGetContLineTable(void)
+{
+    /*
+     * Initialize the hashtable tracking invisible continuation lines.  For
+     * the release we use a thread exit handler to ensure that this is done
+     * before TSD blocks are made invalid. The TclFinalizeObjects() which
+     * would be the natural place for this is invoked afterwards, meaning that
+     * we try to operate on a data structure already gone.
+     */
+
+    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+
+    if (!tsdPtr->lineCLPtr) {
+	tsdPtr->lineCLPtr = ckalloc(sizeof(Tcl_HashTable));
+	Tcl_InitHashTable(tsdPtr->lineCLPtr, TCL_ONE_WORD_KEYS);
+	Tcl_CreateThreadExitHandler(TclThreadFinalizeContLines,NULL);
+    }
+    return tsdPtr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclContinuationsEnter --
+ *
+ *	This procedure is a helper which saves the continuation line
+ *	information associated with a Tcl_Obj*.
+ *
+ * Results:
+ *	A reference to the newly created continuation line location table.
+ *
+ * Side effects:
+ *	Allocates memory for the table of continuation line locations.
+ *
+ * TIP #280
+ *----------------------------------------------------------------------
+ */
+
+ContLineLoc *
+TclContinuationsEnter(
+    Tcl_Obj *objPtr,
+    int num,
+    int *loc)
+{
+    int newEntry;
+    ThreadSpecificData *tsdPtr = TclGetContLineTable();
+    Tcl_HashEntry *hPtr =
+	    Tcl_CreateHashEntry(tsdPtr->lineCLPtr, objPtr, &newEntry);
+    ContLineLoc *clLocPtr = ckalloc(sizeof(ContLineLoc) + num*sizeof(int));
+
+    if (!newEntry) {
+	/*
+	 * We're entering ContLineLoc data for the same value more than one
+	 * time. Taking care not to leak the old entry.
+	 *
+	 * This can happen when literals in a proc body are shared. See for
+	 * example test info-30.19 where the action (code) for all branches of
+	 * the switch command is identical, mapping them all to the same
+	 * literal. An interesting result of this is that the number and
+	 * locations (offset) of invisible continuation lines in the literal
+	 * are the same for all occurences.
+	 *
+	 * Note that while reusing the existing entry is possible it requires
+	 * the same actions as for a new entry because we have to copy the
+	 * incoming num/loc data even so. Because we are called from
+	 * TclContinuationsEnterDerived for this case, which modified the
+	 * stored locations (Rebased to the proper relative offset). Just
+	 * returning the stored entry would rebase them a second time, or
+	 * more, hosing the data. It is easier to simply replace, as we are
+	 * doing.
+	 */
+
+	ckfree(Tcl_GetHashValue(hPtr));
+    }
+
+    clLocPtr->num = num;
+    memcpy(&clLocPtr->loc, loc, num*sizeof(int));
+    clLocPtr->loc[num] = CLL_END;       /* Sentinel */
+    Tcl_SetHashValue(hPtr, clLocPtr);
+
+    return clLocPtr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclContinuationsEnterDerived --
+ *
+ *	This procedure is a helper which computes the continuation line
+ *	information associated with a Tcl_Obj* cut from the middle of a
+ *	script.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Allocates memory for the table of continuation line locations.
+ *
+ * TIP #280
+ *----------------------------------------------------------------------
+ */
+
+void
+TclContinuationsEnterDerived(
+    Tcl_Obj *objPtr,
+    int start,
+    int *clNext)
+{
+    int length, end, num;
+    int *wordCLLast = clNext;
+
+    /*
+     * We have to handle invisible continuations lines here as well, despite
+     * the code we have in TclSubstTokens (TST) for that. Why ?  Nesting. If
+     * our script is the sole argument to an 'eval' command, for example, the
+     * scriptCLLocPtr we are using was generated by a previous call to TST,
+     * and while the words we have here may contain continuation lines they
+     * are invisible already, and the inner call to TST had no bs+nl sequences
+     * to trigger its code.
+     *
+     * Luckily for us, the table we have to create here for the current word
+     * has to be a slice of the table currently in use, with the locations
+     * suitably modified to be relative to the start of the word instead of
+     * relative to the script.
+     *
+     * That is what we are doing now. Determine the slice we need, and if not
+     * empty, wrap it into a new table, and save the result into our
+     * thread-global hashtable, as usual.
+     */
+
+    /*
+     * First compute the range of the word within the script. (Is there a
+     * better way which doesn't shimmer?)
+     */
+
+    Tcl_GetStringFromObj(objPtr, &length);
+    end = start + length;       /* First char after the word */
+
+    /*
+     * Then compute the table slice covering the range of the word.
+     */
+
+    while (*wordCLLast >= 0 && *wordCLLast < end) {
+	wordCLLast++;
+    }
+
+    /*
+     * And generate the table from the slice, if it was not empty.
+     */
+
+    num = wordCLLast - clNext;
+    if (num) {
+	int i;
+	ContLineLoc *clLocPtr = TclContinuationsEnter(objPtr, num, clNext);
+
+	/*
+	 * Re-base the locations.
+	 */
+
+	for (i=0 ; i<num ; i++) {
+	    clLocPtr->loc[i] -= start;
+
+	    /*
+	     * Continuation lines coming before the string and affecting us
+	     * should not happen, due to the proper maintenance of clNext
+	     * during compilation.
+	     */
+
+	    if (clLocPtr->loc[i] < 0) {
+		Tcl_Panic("Derived ICL data for object using offsets from before the script");
+	    }
+	}
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclContinuationsCopy --
+ *
+ *	This procedure is a helper which copies the continuation line
+ *	information associated with a Tcl_Obj* to another Tcl_Obj*. It is
+ *	assumed that both contain the same string/script. Use this when a
+ *	script is duplicated because it was shared.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Allocates memory for the table of continuation line locations.
+ *
+ * TIP #280
+ *----------------------------------------------------------------------
+ */
+
+void
+TclContinuationsCopy(
+    Tcl_Obj *objPtr,
+    Tcl_Obj *originObjPtr)
+{
+    ThreadSpecificData *tsdPtr = TclGetContLineTable();
+    Tcl_HashEntry *hPtr =
+            Tcl_FindHashEntry(tsdPtr->lineCLPtr, originObjPtr);
+
+    if (hPtr) {
+	ContLineLoc *clLocPtr = Tcl_GetHashValue(hPtr);
+
+	TclContinuationsEnter(objPtr, clLocPtr->num, clLocPtr->loc);
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclContinuationsGet --
+ *
+ *	This procedure is a helper which retrieves the continuation line
+ *	information associated with a Tcl_Obj*, if it has any.
+ *
+ * Results:
+ *	A reference to the continuation line location table, or NULL if the
+ *	Tcl_Obj* has no such information associated with it.
+ *
+ * Side effects:
+ *	None.
+ *
+ * TIP #280
+ *----------------------------------------------------------------------
+ */
+
+ContLineLoc *
+TclContinuationsGet(
+    Tcl_Obj *objPtr)
+{
+    ThreadSpecificData *tsdPtr = TclGetContLineTable();
+    Tcl_HashEntry *hPtr =
+            Tcl_FindHashEntry(tsdPtr->lineCLPtr, objPtr);
+
+    if (!hPtr) {
+        return NULL;
+    }
+    return Tcl_GetHashValue(hPtr);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclThreadFinalizeContLines --
+ *
+ *	This procedure is a helper which releases all continuation line
+ *	information currently known. It is run as a thread exit handler.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Releases memory.
+ *
+ * TIP #280
+ *----------------------------------------------------------------------
+ */
+
+static void
+TclThreadFinalizeContLines(
+    ClientData clientData)
+{
+    /*
+     * Release the hashtable tracking invisible continuation lines.
+     */
+
+    ThreadSpecificData *tsdPtr = TclGetContLineTable();
+    Tcl_HashEntry *hPtr;
+    Tcl_HashSearch hSearch;
+
+    for (hPtr = Tcl_FirstHashEntry(tsdPtr->lineCLPtr, &hSearch);
+	    hPtr != NULL; hPtr = Tcl_NextHashEntry(&hSearch)) {
+	ckfree(Tcl_GetHashValue(hPtr));
+	Tcl_DeleteHashEntry(hPtr);
+    }
+    Tcl_DeleteHashTable(tsdPtr->lineCLPtr);
+    ckfree(tsdPtr->lineCLPtr);
+    tsdPtr->lineCLPtr = NULL;
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * Tcl_RegisterObjType --
+ *
+ *	This function is called to register a new Tcl object type in the table
+ *	of all object types supported by Tcl.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The type is registered in the Tcl type table. If there was already a
+ *	type with the same name as in typePtr, it is replaced with the new
+ *	type.
+ *
+ *--------------------------------------------------------------
+ */
+
+void
+Tcl_RegisterObjType(
+    const Tcl_ObjType *typePtr)	/* Information about object type; storage must
+				 * be statically allocated (must live
+				 * forever). */
+{
+    int isNew;
+
+    Tcl_MutexLock(&tableMutex);
+    Tcl_SetHashValue(
+	    Tcl_CreateHashEntry(&typeTable, typePtr->name, &isNew), typePtr);
+    Tcl_MutexUnlock(&tableMutex);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_AppendAllObjTypes --
+ *
+ *	This function appends onto the argument object the name of each object
+ *	type as a list element. This includes the builtin object types (e.g.
+ *	int, list) as well as those added using Tcl_NewObj. These names can be
+ *	used, for example, with Tcl_GetObjType to get pointers to the
+ *	corresponding Tcl_ObjType structures.
+ *
+ * Results:
+ *	The return value is normally TCL_OK; in this case the object
+ *	referenced by objPtr has each type name appended to it. If an error
+ *	occurs, TCL_ERROR is returned and the interpreter's result holds an
+ *	error message.
+ *
+ * Side effects:
+ *	If necessary, the object referenced by objPtr is converted into a list
+ *	object.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_AppendAllObjTypes(
+    Tcl_Interp *interp,		/* Interpreter used for error reporting. */
+    Tcl_Obj *objPtr)		/* Points to the Tcl object onto which the
+				 * name of each registered type is appended as
+				 * a list element. */
+{
+    register Tcl_HashEntry *hPtr;
+    Tcl_HashSearch search;
+    int numElems;
+
+    /*
+     * Get the test for a valid list out of the way first.
+     */
+
+    if (TclListObjLength(interp, objPtr, &numElems) != TCL_OK) {
+	return TCL_ERROR;
+    }
+
+    /*
+     * Type names are NUL-terminated, not counted strings. This code relies on
+     * that.
+     */
+
+    Tcl_MutexLock(&tableMutex);
+    for (hPtr = Tcl_FirstHashEntry(&typeTable, &search);
+	    hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) {
+	Tcl_ListObjAppendElement(NULL, objPtr,
+		Tcl_NewStringObj(Tcl_GetHashKey(&typeTable, hPtr), -1));
+    }
+    Tcl_MutexUnlock(&tableMutex);
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_GetObjType --
+ *
+ *	This function looks up an object type by name.
+ *
+ * Results:
+ *	If an object type with name matching "typeName" is found, a pointer to
+ *	its Tcl_ObjType structure is returned; otherwise, NULL is returned.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+const Tcl_ObjType *
+Tcl_GetObjType(
+    const char *typeName)	/* Name of Tcl object type to look up. */
+{
+    register Tcl_HashEntry *hPtr;
+    const Tcl_ObjType *typePtr = NULL;
+
+    Tcl_MutexLock(&tableMutex);
+    hPtr = Tcl_FindHashEntry(&typeTable, typeName);
+    if (hPtr != NULL) {
+	typePtr = Tcl_GetHashValue(hPtr);
+    }
+    Tcl_MutexUnlock(&tableMutex);
+    return typePtr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_ConvertToType --
+ *
+ *	Convert the Tcl object "objPtr" to have type "typePtr" if possible.
+ *
+ * Results:
+ *	The return value is TCL_OK on success and TCL_ERROR on failure. If
+ *	TCL_ERROR is returned, then the interpreter's result contains an error
+ *	message unless "interp" is NULL. Passing a NULL "interp" allows this
+ *	function to be used as a test whether the conversion could be done
+ *	(and in fact was done).
+ *
+ * Side effects:
+ *	Any internal representation for the old type is freed.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_ConvertToType(
+    Tcl_Interp *interp,		/* Used for error reporting if not NULL. */
+    Tcl_Obj *objPtr,		/* The object to convert. */
+    const Tcl_ObjType *typePtr)	/* The target type. */
+{
+    if (objPtr->typePtr == typePtr) {
+	return TCL_OK;
+    }
+
+    /*
+     * Use the target type's Tcl_SetFromAnyProc to set "objPtr"s internal form
+     * as appropriate for the target type. This frees the old internal
+     * representation.
+     */
+
+    if (typePtr->setFromAnyProc == NULL) {
+	if (interp) {
+	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		    "can't convert value to type %s", typePtr->name));
+	    Tcl_SetErrorCode(interp, "TCL", "API_ABUSE", NULL);
+	}
+	return TCL_ERROR;
+    }
+
+    return typePtr->setFromAnyProc(interp, objPtr);
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * TclDbDumpActiveObjects --
+ *
+ *	This function is called to dump all of the active Tcl_Obj structs this
+ *	allocator knows about.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	None.
+ *
+ *--------------------------------------------------------------
+ */
+
+void
+TclDbDumpActiveObjects(
+    FILE *outFile)
+{
+#if defined(TCL_MEM_DEBUG) && defined(TCL_THREADS)
+    Tcl_HashSearch hSearch;
+    Tcl_HashEntry *hPtr;
+    Tcl_HashTable *tablePtr;
+    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+
+    tablePtr = tsdPtr->objThreadMap;
+
+    if (tablePtr != NULL) {
+	fprintf(outFile, "total objects: %d\n", tablePtr->numEntries);
+	for (hPtr = Tcl_FirstHashEntry(tablePtr, &hSearch); hPtr != NULL;
+		hPtr = Tcl_NextHashEntry(&hSearch)) {
+	    ObjData *objData = Tcl_GetHashValue(hPtr);
+
+	    if (objData != NULL) {
+		fprintf(outFile,
+			"key = 0x%p, objPtr = 0x%p, file = %s, line = %d\n",
+			Tcl_GetHashKey(tablePtr, hPtr), objData->objPtr,
+			objData->file, objData->line);
+	    } else {
+		fprintf(outFile, "key = 0x%p\n",
+			Tcl_GetHashKey(tablePtr, hPtr));
+	    }
+	}
+    }
+#endif
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclDbInitNewObj --
+ *
+ *	Called via the TclNewObj or TclDbNewObj macros when TCL_MEM_DEBUG is
+ *	enabled. This function will initialize the members of a Tcl_Obj
+ *	struct. Initilization would be done inline via the TclNewObj macro
+ *	when compiling without TCL_MEM_DEBUG.
+ *
+ * Results:
+ *	The Tcl_Obj struct members are initialized.
+ *
+ * Side effects:
+ *	None.
+ *----------------------------------------------------------------------
+ */
+
+#ifdef TCL_MEM_DEBUG
+void
+TclDbInitNewObj(
+    register Tcl_Obj *objPtr,
+    register const char *file,	/* The name of the source file calling this
+				 * function; used for debugging. */
+    register int line)		/* Line number in the source file; used for
+				 * debugging. */
+{
+    objPtr->refCount = 0;
+    objPtr->bytes = tclEmptyStringRep;
+    objPtr->length = 0;
+    objPtr->typePtr = NULL;
+
+#ifdef TCL_THREADS
+    /*
+     * Add entry to a thread local map used to check if a Tcl_Obj was
+     * allocated by the currently executing thread.
+     */
+
+    if (!TclInExit()) {
+	Tcl_HashEntry *hPtr;
+	Tcl_HashTable *tablePtr;
+	int isNew;
+	ObjData *objData;
+	ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+
+	if (tsdPtr->objThreadMap == NULL) {
+	    tsdPtr->objThreadMap = ckalloc(sizeof(Tcl_HashTable));
+	    Tcl_InitHashTable(tsdPtr->objThreadMap, TCL_ONE_WORD_KEYS);
+	}
+	tablePtr = tsdPtr->objThreadMap;
+	hPtr = Tcl_CreateHashEntry(tablePtr, objPtr, &isNew);
+	if (!isNew) {
+	    Tcl_Panic("expected to create new entry for object map");
+	}
+
+	/*
+	 * Record the debugging information.
+	 */
+
+	objData = ckalloc(sizeof(ObjData));
+	objData->objPtr = objPtr;
+	objData->file = file;
+	objData->line = line;
+	Tcl_SetHashValue(hPtr, objData);
+    }
+#endif /* TCL_THREADS */
+}
+#endif /* TCL_MEM_DEBUG */
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_NewObj --
+ *
+ *	This function is normally called when not debugging: i.e., when
+ *	TCL_MEM_DEBUG is not defined. It creates new Tcl objects that denote
+ *	the empty string. These objects have a NULL object type and NULL
+ *	string representation byte pointer. Type managers call this routine to
+ *	allocate new objects that they further initialize.
+ *
+ *	When TCL_MEM_DEBUG is defined, this function just returns the result
+ *	of calling the debugging version Tcl_DbNewObj.
+ *
+ * Results:
+ *	The result is a newly allocated object that represents the empty
+ *	string. The new object's typePtr is set NULL and its ref count is set
+ *	to 0.
+ *
+ * Side effects:
+ *	If compiling with TCL_COMPILE_STATS, this function increments the
+ *	global count of allocated objects (tclObjsAlloced).
+ *
+ *----------------------------------------------------------------------
+ */
+
+#ifdef TCL_MEM_DEBUG
+#undef Tcl_NewObj
+
+Tcl_Obj *
+Tcl_NewObj(void)
+{
+    return Tcl_DbNewObj("unknown", 0);
+}
+
+#else /* if not TCL_MEM_DEBUG */
+
+Tcl_Obj *
+Tcl_NewObj(void)
+{
+    register Tcl_Obj *objPtr;
+
+    /*
+     * Use the macro defined in tclInt.h - it will use the correct allocator.
+     */
+
+    TclNewObj(objPtr);
+    return objPtr;
+}
+#endif /* TCL_MEM_DEBUG */
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_DbNewObj --
+ *
+ *	This function is normally called when debugging: i.e., when
+ *	TCL_MEM_DEBUG is defined. It creates new Tcl objects that denote the
+ *	empty string. It is the same as the Tcl_NewObj function above except
+ *	that it calls Tcl_DbCkalloc directly with the file name and line
+ *	number from its caller. This simplifies debugging since then the
+ *	[memory active] command will report the correct file name and line
+ *	number when reporting objects that haven't been freed.
+ *
+ *	When TCL_MEM_DEBUG is not defined, this function just returns the
+ *	result of calling Tcl_NewObj.
+ *
+ * Results:
+ *	The result is a newly allocated that represents the empty string. The
+ *	new object's typePtr is set NULL and its ref count is set to 0.
+ *
+ * Side effects:
+ *	If compiling with TCL_COMPILE_STATS, this function increments the
+ *	global count of allocated objects (tclObjsAlloced).
+ *
+ *----------------------------------------------------------------------
+ */
+
+#ifdef TCL_MEM_DEBUG
+
+Tcl_Obj *
+Tcl_DbNewObj(
+    register const char *file,	/* The name of the source file calling this
+				 * function; used for debugging. */
+    register int line)		/* Line number in the source file; used for
+				 * debugging. */
+{
+    register Tcl_Obj *objPtr;
+
+    /*
+     * Use the macro defined in tclInt.h - it will use the correct allocator.
+     */
+
+    TclDbNewObj(objPtr, file, line);
+    return objPtr;
+}
+#else /* if not TCL_MEM_DEBUG */
+
+Tcl_Obj *
+Tcl_DbNewObj(
+    const char *file,		/* The name of the source file calling this
+				 * function; used for debugging. */
+    int line)			/* Line number in the source file; used for
+				 * debugging. */
+{
+    return Tcl_NewObj();
+}
+#endif /* TCL_MEM_DEBUG */
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclAllocateFreeObjects --
+ *
+ *	Function to allocate a number of free Tcl_Objs. This is done using a
+ *	single ckalloc to reduce the overhead for Tcl_Obj allocation.
+ *
+ *	Assumes mutex is held.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	tclFreeObjList, the head of the list of free Tcl_Objs, is set to the
+ *	first of a number of free Tcl_Obj's linked together by their
+ *	internalRep.twoPtrValue.ptr1's.
+ *
+ *----------------------------------------------------------------------
+ */
+
+#define OBJS_TO_ALLOC_EACH_TIME 100
+
+void
+TclAllocateFreeObjects(void)
+{
+    size_t bytesToAlloc = (OBJS_TO_ALLOC_EACH_TIME * sizeof(Tcl_Obj));
+    char *basePtr;
+    register Tcl_Obj *prevPtr, *objPtr;
+    register int i;
+
+    /*
+     * This has been noted by Purify to be a potential leak. The problem is
+     * that Tcl, when not TCL_MEM_DEBUG compiled, keeps around all allocated
+     * Tcl_Obj's, pointed to by tclFreeObjList, when freed instead of actually
+     * freeing the memory. TclFinalizeObjects() does not ckfree() this memory,
+     * but leaves it to Tcl's memory subsystem finalization to release it.
+     * Purify apparently can't figure that out, and fires a false alarm.
+     */
+
+    basePtr = ckalloc(bytesToAlloc);
+
+    prevPtr = NULL;
+    objPtr = (Tcl_Obj *) basePtr;
+    for (i = 0; i < OBJS_TO_ALLOC_EACH_TIME; i++) {
+	objPtr->internalRep.twoPtrValue.ptr1 = prevPtr;
+	prevPtr = objPtr;
+	objPtr++;
+    }
+    tclFreeObjList = prevPtr;
+}
+#undef OBJS_TO_ALLOC_EACH_TIME
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclFreeObj --
+ *
+ *	This function frees the memory associated with the argument object.
+ *	It is called by the tcl.h macro Tcl_DecrRefCount when an object's ref
+ *	count is zero. It is only "public" since it must be callable by that
+ *	macro wherever the macro is used. It should not be directly called by
+ *	clients.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Deallocates the storage for the object's Tcl_Obj structure after
+ *	deallocating the string representation and calling the type-specific
+ *	Tcl_FreeInternalRepProc to deallocate the object's internal
+ *	representation. If compiling with TCL_COMPILE_STATS, this function
+ *	increments the global count of freed objects (tclObjsFreed).
+ *
+ *----------------------------------------------------------------------
+ */
+
+#ifdef TCL_MEM_DEBUG
+void
+TclFreeObj(
+    register Tcl_Obj *objPtr)	/* The object to be freed. */
+{
+    register const Tcl_ObjType *typePtr = objPtr->typePtr;
+
+    /*
+     * This macro declares a variable, so must come here...
+     */
+
+    ObjInitDeletionContext(context);
+
+# ifdef TCL_THREADS
+    /*
+     * Check to make sure that the Tcl_Obj was allocated by the current
+     * thread. Don't do this check when shutting down since thread local
+     * storage can be finalized before the last Tcl_Obj is freed.
+     */
+
+    if (!TclInExit()) {
+	Tcl_HashTable *tablePtr;
+	Tcl_HashEntry *hPtr;
+	ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+
+	tablePtr = tsdPtr->objThreadMap;
+	if (!tablePtr) {
+	    Tcl_Panic("TclFreeObj: object table not initialized");
+	}
+	hPtr = Tcl_FindHashEntry(tablePtr, (char *) objPtr);
+	if (hPtr) {
+	    /*
+	     * As the Tcl_Obj is going to be deleted we remove the entry.
+	     */
+
+	    ObjData *objData = Tcl_GetHashValue(hPtr);
+
+	    if (objData != NULL) {
+		ckfree(objData);
+	    }
+
+	    Tcl_DeleteHashEntry(hPtr);
+	}
+    }
+# endif
+
+    /*
+     * Check for a double free of the same value.  This is slightly tricky
+     * because it is customary to free a Tcl_Obj when its refcount falls
+     * either from 1 to 0, or from 0 to -1.  Falling from -1 to -2, though,
+     * and so on, is always a sign of a botch in the caller.
+     */
+    if (objPtr->refCount < -1) {
+	Tcl_Panic("Reference count for %p was negative", objPtr);
+    }
+    /*
+     * Now, in case we just approved drop from 1 to 0 as acceptable, make
+     * sure we do not accept a second free when falling from 0 to -1.
+     * Skip that possibility so any double free will trigger the panic.
+     */
+    objPtr->refCount = -1;
+
+    /*
+     * Invalidate the string rep first so we can use the bytes value for our
+     * pointer chain, and signal an obj deletion (as opposed to shimmering)
+     * with 'length == -1'.
+     */
+
+    TclInvalidateStringRep(objPtr);
+    objPtr->length = -1;
+
+    if (ObjDeletePending(context)) {
+	PushObjToDelete(context, objPtr);
+    } else {
+	TCL_DTRACE_OBJ_FREE(objPtr);
+	if ((typePtr != NULL) && (typePtr->freeIntRepProc != NULL)) {
+	    ObjDeletionLock(context);
+	    typePtr->freeIntRepProc(objPtr);
+	    ObjDeletionUnlock(context);
+	}
+
+	Tcl_MutexLock(&tclObjMutex);
+	ckfree(objPtr);
+	Tcl_MutexUnlock(&tclObjMutex);
+	TclIncrObjsFreed();
+	ObjDeletionLock(context);
+	while (ObjOnStack(context)) {
+	    Tcl_Obj *objToFree;
+
+	    PopObjToDelete(context, objToFree);
+	    TCL_DTRACE_OBJ_FREE(objToFree);
+	    TclFreeIntRep(objToFree);
+
+	    Tcl_MutexLock(&tclObjMutex);
+	    ckfree(objToFree);
+	    Tcl_MutexUnlock(&tclObjMutex);
+	    TclIncrObjsFreed();
+	}
+	ObjDeletionUnlock(context);
+    }
+
+    /*
+     * We cannot use TclGetContinuationTable() here, because that may
+     * re-initialize the thread-data for calls coming after the finalization.
+     * We have to access it using the low-level call and then check for
+     * validity. This function can be called after TclFinalizeThreadData() has
+     * already killed the thread-global data structures. Performing
+     * TCL_TSD_INIT will leave us with an un-initialized memory block upon
+     * which we crash (if we where to access the uninitialized hashtable).
+     */
+
+    {
+	ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+        Tcl_HashEntry *hPtr;
+
+	if (tsdPtr->lineCLPtr) {
+            hPtr = Tcl_FindHashEntry(tsdPtr->lineCLPtr, objPtr);
+	    if (hPtr) {
+		ckfree(Tcl_GetHashValue(hPtr));
+		Tcl_DeleteHashEntry(hPtr);
+	    }
+	}
+    }
+}
+#else /* TCL_MEM_DEBUG */
+
+void
+TclFreeObj(
+    register Tcl_Obj *objPtr)	/* The object to be freed. */
+{
+    /*
+     * Invalidate the string rep first so we can use the bytes value for our
+     * pointer chain, and signal an obj deletion (as opposed to shimmering)
+     * with 'length == -1'.
+     */
+
+    TclInvalidateStringRep(objPtr);
+    objPtr->length = -1;
+
+    if (!objPtr->typePtr || !objPtr->typePtr->freeIntRepProc) {
+	/*
+	 * objPtr can be freed safely, as it will not attempt to free any
+	 * other objects: it will not cause recursive calls to this function.
+	 */
+
+	TCL_DTRACE_OBJ_FREE(objPtr);
+	TclFreeObjStorage(objPtr);
+	TclIncrObjsFreed();
+    } else {
+	/*
+	 * This macro declares a variable, so must come here...
+	 */
+
+	ObjInitDeletionContext(context);
+
+	if (ObjDeletePending(context)) {
+	    PushObjToDelete(context, objPtr);
+	} else {
+	    /*
+	     * Note that the contents of the while loop assume that the string
+	     * rep has already been freed and we don't want to do anything
+	     * fancy with adding to the queue inside ourselves. Must take care
+	     * to unstack the object first since freeing the internal rep can
+	     * add further objects to the stack. The code assumes that it is
+	     * the first thing in a block; all current usages in the core
+	     * satisfy this.
+	     */
+
+	    TCL_DTRACE_OBJ_FREE(objPtr);
+	    ObjDeletionLock(context);
+	    objPtr->typePtr->freeIntRepProc(objPtr);
+	    ObjDeletionUnlock(context);
+
+	    TclFreeObjStorage(objPtr);
+	    TclIncrObjsFreed();
+	    ObjDeletionLock(context);
+	    while (ObjOnStack(context)) {
+		Tcl_Obj *objToFree;
+
+		PopObjToDelete(context, objToFree);
+		TCL_DTRACE_OBJ_FREE(objToFree);
+		if ((objToFree->typePtr != NULL)
+			&& (objToFree->typePtr->freeIntRepProc != NULL)) {
+		    objToFree->typePtr->freeIntRepProc(objToFree);
+		}
+		TclFreeObjStorage(objToFree);
+		TclIncrObjsFreed();
+	    }
+	    ObjDeletionUnlock(context);
+	}
+    }
+
+    /*
+     * We cannot use TclGetContinuationTable() here, because that may
+     * re-initialize the thread-data for calls coming after the finalization.
+     * We have to access it using the low-level call and then check for
+     * validity. This function can be called after TclFinalizeThreadData() has
+     * already killed the thread-global data structures. Performing
+     * TCL_TSD_INIT will leave us with an un-initialized memory block upon
+     * which we crash (if we where to access the uninitialized hashtable).
+     */
+
+    {
+	ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+        Tcl_HashEntry *hPtr;
+
+	if (tsdPtr->lineCLPtr) {
+            hPtr = Tcl_FindHashEntry(tsdPtr->lineCLPtr, objPtr);
+	    if (hPtr) {
+		ckfree(Tcl_GetHashValue(hPtr));
+		Tcl_DeleteHashEntry(hPtr);
+	    }
+	}
+    }
+}
+#endif /* TCL_MEM_DEBUG */
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclObjBeingDeleted --
+ *
+ *	This function returns 1 when the Tcl_Obj is being deleted. It is
+ *	provided for the rare cases where the reason for the loss of an
+ *	internal rep might be relevant. [FR 1512138]
+ *
+ * Results:
+ *	1 if being deleted, 0 otherwise.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclObjBeingDeleted(
+    Tcl_Obj *objPtr)
+{
+    return (objPtr->length == -1);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_DuplicateObj --
+ *
+ *	Create and return a new object that is a duplicate of the argument
+ *	object.
+ *
+ * Results:
+ *	The return value is a pointer to a newly created Tcl_Obj. This object
+ *	has reference count 0 and the same type, if any, as the source object
+ *	objPtr. Also:
+ *	  1) If the source object has a valid string rep, we copy it;
+ *	     otherwise, the duplicate's string rep is set NULL to mark it
+ *	     invalid.
+ *	  2) If the source object has an internal representation (i.e. its
+ *	     typePtr is non-NULL), the new object's internal rep is set to a
+ *	     copy; otherwise the new internal rep is marked invalid.
+ *
+ * Side effects:
+ *	What constitutes "copying" the internal representation depends on the
+ *	type. For example, if the argument object is a list, the element
+ *	objects it points to will not actually be copied but will be shared
+ *	with the duplicate list. That is, the ref counts of the element
+ *	objects will be incremented.
+ *
+ *----------------------------------------------------------------------
+ */
+
+#define SetDuplicateObj(dupPtr, objPtr)					\
+    {									\
+	const Tcl_ObjType *typePtr = (objPtr)->typePtr;			\
+	const char *bytes = (objPtr)->bytes;				\
+	if (bytes) {							\
+	    TclInitStringRep((dupPtr), bytes, (objPtr)->length);	\
+	} else {							\
+	    (dupPtr)->bytes = NULL;					\
+	}								\
+	if (typePtr) {							\
+	    if (typePtr->dupIntRepProc) {				\
+		typePtr->dupIntRepProc((objPtr), (dupPtr));		\
+	    } else {							\
+		(dupPtr)->internalRep = (objPtr)->internalRep;		\
+		(dupPtr)->typePtr = typePtr;				\
+	    }								\
+	}								\
+    }
+
+Tcl_Obj *
+Tcl_DuplicateObj(
+    Tcl_Obj *objPtr)		/* The object to duplicate. */
+{
+    Tcl_Obj *dupPtr;
+
+    TclNewObj(dupPtr);
+    SetDuplicateObj(dupPtr, objPtr);
+    return dupPtr;
+}
+
+void
+TclSetDuplicateObj(
+    Tcl_Obj *dupPtr,
+    Tcl_Obj *objPtr)
+{
+    if (Tcl_IsShared(dupPtr)) {
+	Tcl_Panic("%s called with shared object", "TclSetDuplicateObj");
+    }
+    TclInvalidateStringRep(dupPtr);
+    TclFreeIntRep(dupPtr);
+    SetDuplicateObj(dupPtr, objPtr);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_GetString --
+ *
+ *	Returns the string representation byte array pointer for an object.
+ *
+ * Results:
+ *	Returns a pointer to the string representation of objPtr. The byte
+ *	array referenced by the returned pointer must not be modified by the
+ *	caller. Furthermore, the caller must copy the bytes if they need to
+ *	retain them since the object's string rep can change as a result of
+ *	other operations.
+ *
+ * Side effects:
+ *	May call the object's updateStringProc to update the string
+ *	representation from the internal representation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+char *
+Tcl_GetString(
+    register Tcl_Obj *objPtr)	/* Object whose string rep byte pointer should
+				 * be returned. */
+{
+    if (objPtr->bytes != NULL) {
+	return objPtr->bytes;
+    }
+
+    /*
+     * Note we do not check for objPtr->typePtr == NULL.  An invariant of
+     * a properly maintained Tcl_Obj is that at least  one of objPtr->bytes
+     * and objPtr->typePtr must not be NULL.  If broken extensions fail to
+     * maintain that invariant, we can crash here.
+     */
+
+    if (objPtr->typePtr->updateStringProc == NULL) {
+	/*
+	 * Those Tcl_ObjTypes which choose not to define an updateStringProc
+	 * must be written in such a way that (objPtr->bytes) never becomes
+	 * NULL.  This panic was added in Tcl 8.1.
+	 */
+
+	Tcl_Panic("UpdateStringProc should not be invoked for type %s",
+		objPtr->typePtr->name);
+    }
+    objPtr->typePtr->updateStringProc(objPtr);
+    if (objPtr->bytes == NULL || objPtr->length < 0
+	    || objPtr->bytes[objPtr->length] != '\0') {
+	Tcl_Panic("UpdateStringProc for type '%s' "
+		"failed to create a valid string rep", objPtr->typePtr->name);
+    }
+    return objPtr->bytes;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_GetStringFromObj --
+ *
+ *	Returns the string representation's byte array pointer and length for
+ *	an object.
+ *
+ * Results:
+ *	Returns a pointer to the string representation of objPtr. If lengthPtr
+ *	isn't NULL, the length of the string representation is stored at
+ *	*lengthPtr. The byte array referenced by the returned pointer must not
+ *	be modified by the caller. Furthermore, the caller must copy the bytes
+ *	if they need to retain them since the object's string rep can change
+ *	as a result of other operations.
+ *
+ * Side effects:
+ *	May call the object's updateStringProc to update the string
+ *	representation from the internal representation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+char *
+Tcl_GetStringFromObj(
+    register Tcl_Obj *objPtr,	/* Object whose string rep byte pointer should
+				 * be returned. */
+    register int *lengthPtr)	/* If non-NULL, the location where the string
+				 * rep's byte array length should * be stored.
+				 * If NULL, no length is stored. */
+{
+    (void) TclGetString(objPtr);
+
+    if (lengthPtr != NULL) {
+	*lengthPtr = objPtr->length;
+    }
+    return objPtr->bytes;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_InvalidateStringRep --
+ *
+ *	This function is called to invalidate an object's string
+ *	representation.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Deallocates the storage for any old string representation, then sets
+ *	the string representation NULL to mark it invalid.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_InvalidateStringRep(
+    register Tcl_Obj *objPtr)	/* Object whose string rep byte pointer should
+				 * be freed. */
+{
+    TclInvalidateStringRep(objPtr);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_NewBooleanObj --
+ *
+ *	This function is normally called when not debugging: i.e., when
+ *	TCL_MEM_DEBUG is not defined. It creates a new Tcl_Obj and
+ *	initializes it from the argument boolean value. A nonzero "boolValue"
+ *	is coerced to 1.
+ *
+ *	When TCL_MEM_DEBUG is defined, this function just returns the result
+ *	of calling the debugging version Tcl_DbNewBooleanObj.
+ *
+ * Results:
+ *	The newly created object is returned. This object will have an invalid
+ *	string representation. The returned object has ref count 0.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+#undef Tcl_NewBooleanObj
+#ifdef TCL_MEM_DEBUG
+
+Tcl_Obj *
+Tcl_NewBooleanObj(
+    register int boolValue)	/* Boolean used to initialize new object. */
+{
+    return Tcl_DbNewBooleanObj(boolValue, "unknown", 0);
+}
+
+#else /* if not TCL_MEM_DEBUG */
+
+Tcl_Obj *
+Tcl_NewBooleanObj(
+    register int boolValue)	/* Boolean used to initialize new object. */
+{
+    register Tcl_Obj *objPtr;
+
+    TclNewBooleanObj(objPtr, boolValue);
+    return objPtr;
+}
+#endif /* TCL_MEM_DEBUG */
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_DbNewBooleanObj --
+ *
+ *	This function is normally called when debugging: i.e., when
+ *	TCL_MEM_DEBUG is defined. It creates new boolean objects. It is the
+ *	same as the Tcl_NewBooleanObj function above except that it calls
+ *	Tcl_DbCkalloc directly with the file name and line number from its
+ *	caller. This simplifies debugging since then the [memory active]
+ *	command will report the correct file name and line number when
+ *	reporting objects that haven't been freed.
+ *
+ *	When TCL_MEM_DEBUG is not defined, this function just returns the
+ *	result of calling Tcl_NewBooleanObj.
+ *
+ * Results:
+ *	The newly created object is returned. This object will have an invalid
+ *	string representation. The returned object has ref count 0.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+#undef Tcl_DbNewBooleanObj
+#ifdef TCL_MEM_DEBUG
+
+Tcl_Obj *
+Tcl_DbNewBooleanObj(
+    register int boolValue,	/* Boolean used to initialize new object. */
+    const char *file,		/* The name of the source file calling this
+				 * function; used for debugging. */
+    int line)			/* Line number in the source file; used for
+				 * debugging. */
+{
+    register Tcl_Obj *objPtr;
+
+    TclDbNewObj(objPtr, file, line);
+    objPtr->bytes = NULL;
+
+    objPtr->internalRep.longValue = (boolValue? 1 : 0);
+    objPtr->typePtr = &tclIntType;
+    return objPtr;
+}
+
+#else /* if not TCL_MEM_DEBUG */
+
+Tcl_Obj *
+Tcl_DbNewBooleanObj(
+    register int boolValue,	/* Boolean used to initialize new object. */
+    const char *file,		/* The name of the source file calling this
+				 * function; used for debugging. */
+    int line)			/* Line number in the source file; used for
+				 * debugging. */
+{
+    return Tcl_NewBooleanObj(boolValue);
+}
+#endif /* TCL_MEM_DEBUG */
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_SetBooleanObj --
+ *
+ *	Modify an object to be a boolean object and to have the specified
+ *	boolean value. A nonzero "boolValue" is coerced to 1.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The object's old string rep, if any, is freed. Also, any old internal
+ *	rep is freed.
+ *
+ *----------------------------------------------------------------------
+ */
+
+#undef Tcl_SetBooleanObj
+void
+Tcl_SetBooleanObj(
+    register Tcl_Obj *objPtr,	/* Object whose internal rep to init. */
+    register int boolValue)	/* Boolean used to set object's value. */
+{
+    if (Tcl_IsShared(objPtr)) {
+	Tcl_Panic("%s called with shared object", "Tcl_SetBooleanObj");
+    }
+
+    TclSetBooleanObj(objPtr, boolValue);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_GetBooleanFromObj --
+ *
+ *	Attempt to return a boolean from the Tcl object "objPtr". This
+ *	includes conversion from any of Tcl's numeric types.
+ *
+ * Results:
+ *	The return value is a standard Tcl object result. If an error occurs
+ *	during conversion, an error message is left in the interpreter's
+ *	result unless "interp" is NULL.
+ *
+ * Side effects:
+ *	The intrep of *objPtr may be changed.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_GetBooleanFromObj(
+    Tcl_Interp *interp,         /* Used for error reporting if not NULL. */
+    register Tcl_Obj *objPtr,	/* The object from which to get boolean. */
+    register int *boolPtr)	/* Place to store resulting boolean. */
+{
+    do {
+	if (objPtr->typePtr == &tclIntType) {
+	    *boolPtr = (objPtr->internalRep.longValue != 0);
+	    return TCL_OK;
+	}
+	if (objPtr->typePtr == &tclBooleanType) {
+	    *boolPtr = (int) objPtr->internalRep.longValue;
+	    return TCL_OK;
+	}
+	if (objPtr->typePtr == &tclDoubleType) {
+	    /*
+	     * Caution: Don't be tempted to check directly for the "double"
+	     * Tcl_ObjType and then compare the intrep to 0.0. This isn't
+	     * reliable because a "double" Tcl_ObjType can hold the NaN value.
+	     * Use the API Tcl_GetDoubleFromObj, which does the checking and
+	     * sets the proper error message for us.
+	     */
+
+	    double d;
+
+	    if (Tcl_GetDoubleFromObj(interp, objPtr, &d) != TCL_OK) {
+		return TCL_ERROR;
+	    }
+	    *boolPtr = (d != 0.0);
+	    return TCL_OK;
+	}
+	if (objPtr->typePtr == &tclBignumType) {
+	    *boolPtr = 1;
+	    return TCL_OK;
+	}
+#ifndef TCL_WIDE_INT_IS_LONG
+	if (objPtr->typePtr == &tclWideIntType) {
+	    *boolPtr = (objPtr->internalRep.wideValue != 0);
+	    return TCL_OK;
+	}
+#endif
+    } while ((ParseBoolean(objPtr) == TCL_OK) || (TCL_OK ==
+	    TclParseNumber(interp, objPtr, "boolean value", NULL,-1,NULL,0)));
+    return TCL_ERROR;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclSetBooleanFromAny --
+ *
+ *	Attempt to generate a boolean internal form for the Tcl object
+ *	"objPtr".
+ *
+ * Results:
+ *	The return value is a standard Tcl result. If an error occurs during
+ *	conversion, an error message is left in the interpreter's result
+ *	unless "interp" is NULL.
+ *
+ * Side effects:
+ *	If no error occurs, an integer 1 or 0 is stored as "objPtr"s internal
+ *	representation and the type of "objPtr" is set to boolean.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclSetBooleanFromAny(
+    Tcl_Interp *interp,		/* Used for error reporting if not NULL. */
+    register Tcl_Obj *objPtr)	/* The object to convert. */
+{
+    /*
+     * For some "pure" numeric Tcl_ObjTypes (no string rep), we can determine
+     * whether a boolean conversion is possible without generating the string
+     * rep.
+     */
+
+    if (objPtr->bytes == NULL) {
+	if (objPtr->typePtr == &tclIntType) {
+	    switch (objPtr->internalRep.longValue) {
+	    case 0L: case 1L:
+		return TCL_OK;
+	    }
+	    goto badBoolean;
+	}
+
+	if (objPtr->typePtr == &tclBignumType) {
+	    goto badBoolean;
+	}
+
+#ifndef TCL_WIDE_INT_IS_LONG
+	if (objPtr->typePtr == &tclWideIntType) {
+	    goto badBoolean;
+	}
+#endif
+
+	if (objPtr->typePtr == &tclDoubleType) {
+	    goto badBoolean;
+	}
+    }
+
+    if (ParseBoolean(objPtr) == TCL_OK) {
+	return TCL_OK;
+    }
+
+  badBoolean:
+    if (interp != NULL) {
+	int length;
+	const char *str = Tcl_GetStringFromObj(objPtr, &length);
+	Tcl_Obj *msg;
+
+	TclNewLiteralStringObj(msg, "expected boolean value but got \"");
+	Tcl_AppendLimitedToObj(msg, str, length, 50, "");
+	Tcl_AppendToObj(msg, "\"", -1);
+	Tcl_SetObjResult(interp, msg);
+	Tcl_SetErrorCode(interp, "TCL", "VALUE", "BOOLEAN", NULL);
+    }
+    return TCL_ERROR;
+}
+
+static int
+ParseBoolean(
+    register Tcl_Obj *objPtr)	/* The object to parse/convert. */
+{
+    int i, length, newBool;
+    char lowerCase[6];
+    const char *str = TclGetStringFromObj(objPtr, &length);
+
+    if ((length == 0) || (length > 5)) {
+	/*
+         * Longest valid boolean string rep. is "false".
+         */
+
+	return TCL_ERROR;
+    }
+
+    switch (str[0]) {
+    case '0':
+	if (length == 1) {
+	    newBool = 0;
+	    goto numericBoolean;
+	}
+	return TCL_ERROR;
+    case '1':
+	if (length == 1) {
+	    newBool = 1;
+	    goto numericBoolean;
+	}
+	return TCL_ERROR;
+    }
+
+    /*
+     * Force to lower case for case-insensitive detection. Filter out known
+     * invalid characters at the same time.
+     */
+
+    for (i=0; i < length; i++) {
+	char c = str[i];
+
+	switch (c) {
+	case 'A': case 'E': case 'F': case 'L': case 'N':
+	case 'O': case 'R': case 'S': case 'T': case 'U': case 'Y':
+	    lowerCase[i] = c + (char) ('a' - 'A');
+	    break;
+	case 'a': case 'e': case 'f': case 'l': case 'n':
+	case 'o': case 'r': case 's': case 't': case 'u': case 'y':
+	    lowerCase[i] = c;
+	    break;
+	default:
+	    return TCL_ERROR;
+	}
+    }
+    lowerCase[length] = 0;
+    switch (lowerCase[0]) {
+    case 'y':
+	/*
+	 * Checking the 'y' is redundant, but makes the code clearer.
+	 */
+	if (strncmp(lowerCase, "yes", (size_t) length) == 0) {
+	    newBool = 1;
+	    goto goodBoolean;
+	}
+	return TCL_ERROR;
+    case 'n':
+	if (strncmp(lowerCase, "no", (size_t) length) == 0) {
+	    newBool = 0;
+	    goto goodBoolean;
+	}
+	return TCL_ERROR;
+    case 't':
+	if (strncmp(lowerCase, "true", (size_t) length) == 0) {
+	    newBool = 1;
+	    goto goodBoolean;
+	}
+	return TCL_ERROR;
+    case 'f':
+	if (strncmp(lowerCase, "false", (size_t) length) == 0) {
+	    newBool = 0;
+	    goto goodBoolean;
+	}
+	return TCL_ERROR;
+    case 'o':
+	if (length < 2) {
+	    return TCL_ERROR;
+	}
+	if (strncmp(lowerCase, "on", (size_t) length) == 0) {
+	    newBool = 1;
+	    goto goodBoolean;
+	} else if (strncmp(lowerCase, "off", (size_t) length) == 0) {
+	    newBool = 0;
+	    goto goodBoolean;
+	}
+	return TCL_ERROR;
+    default:
+	return TCL_ERROR;
+    }
+
+    /*
+     * Free the old internalRep before setting the new one. We do this as late
+     * as possible to allow the conversion code, in particular
+     * Tcl_GetStringFromObj, to use that old internalRep.
+     */
+
+  goodBoolean:
+    TclFreeIntRep(objPtr);
+    objPtr->internalRep.longValue = newBool;
+    objPtr->typePtr = &tclBooleanType;
+    return TCL_OK;
+
+  numericBoolean:
+    TclFreeIntRep(objPtr);
+    objPtr->internalRep.longValue = newBool;
+    objPtr->typePtr = &tclIntType;
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_NewDoubleObj --
+ *
+ *	This function is normally called when not debugging: i.e., when
+ *	TCL_MEM_DEBUG is not defined. It creates a new double object and
+ *	initializes it from the argument double value.
+ *
+ *	When TCL_MEM_DEBUG is defined, this function just returns the result
+ *	of calling the debugging version Tcl_DbNewDoubleObj.
+ *
+ * Results:
+ *	The newly created object is returned. This object will have an
+ *	invalid string representation. The returned object has ref count 0.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+#ifdef TCL_MEM_DEBUG
+#undef Tcl_NewDoubleObj
+
+Tcl_Obj *
+Tcl_NewDoubleObj(
+    register double dblValue)	/* Double used to initialize the object. */
+{
+    return Tcl_DbNewDoubleObj(dblValue, "unknown", 0);
+}
+
+#else /* if not TCL_MEM_DEBUG */
+
+Tcl_Obj *
+Tcl_NewDoubleObj(
+    register double dblValue)	/* Double used to initialize the object. */
+{
+    register Tcl_Obj *objPtr;
+
+    TclNewDoubleObj(objPtr, dblValue);
+    return objPtr;
+}
+#endif /* if TCL_MEM_DEBUG */
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_DbNewDoubleObj --
+ *
+ *	This function is normally called when debugging: i.e., when
+ *	TCL_MEM_DEBUG is defined. It creates new double objects. It is the
+ *	same as the Tcl_NewDoubleObj function above except that it calls
+ *	Tcl_DbCkalloc directly with the file name and line number from its
+ *	caller. This simplifies debugging since then the [memory active]
+ *	command will report the correct file name and line number when
+ *	reporting objects that haven't been freed.
+ *
+ *	When TCL_MEM_DEBUG is not defined, this function just returns the
+ *	result of calling Tcl_NewDoubleObj.
+ *
+ * Results:
+ *	The newly created object is returned. This object will have an invalid
+ *	string representation. The returned object has ref count 0.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+#ifdef TCL_MEM_DEBUG
+
+Tcl_Obj *
+Tcl_DbNewDoubleObj(
+    register double dblValue,	/* Double used to initialize the object. */
+    const char *file,		/* The name of the source file calling this
+				 * function; used for debugging. */
+    int line)			/* Line number in the source file; used for
+				 * debugging. */
+{
+    register Tcl_Obj *objPtr;
+
+    TclDbNewObj(objPtr, file, line);
+    objPtr->bytes = NULL;
+
+    objPtr->internalRep.doubleValue = dblValue;
+    objPtr->typePtr = &tclDoubleType;
+    return objPtr;
+}
+
+#else /* if not TCL_MEM_DEBUG */
+
+Tcl_Obj *
+Tcl_DbNewDoubleObj(
+    register double dblValue,	/* Double used to initialize the object. */
+    const char *file,		/* The name of the source file calling this
+				 * function; used for debugging. */
+    int line)			/* Line number in the source file; used for
+				 * debugging. */
+{
+    return Tcl_NewDoubleObj(dblValue);
+}
+#endif /* TCL_MEM_DEBUG */
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_SetDoubleObj --
+ *
+ *	Modify an object to be a double object and to have the specified
+ *	double value.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The object's old string rep, if any, is freed. Also, any old internal
+ *	rep is freed.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_SetDoubleObj(
+    register Tcl_Obj *objPtr,	/* Object whose internal rep to init. */
+    register double dblValue)	/* Double used to set the object's value. */
+{
+    if (Tcl_IsShared(objPtr)) {
+	Tcl_Panic("%s called with shared object", "Tcl_SetDoubleObj");
+    }
+
+    TclSetDoubleObj(objPtr, dblValue);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_GetDoubleFromObj --
+ *
+ *	Attempt to return a double from the Tcl object "objPtr". If the object
+ *	is not already a double, an attempt will be made to convert it to one.
+ *
+ * Results:
+ *	The return value is a standard Tcl object result. If an error occurs
+ *	during conversion, an error message is left in the interpreter's
+ *	result unless "interp" is NULL.
+ *
+ * Side effects:
+ *	If the object is not already a double, the conversion will free any
+ *	old internal representation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_GetDoubleFromObj(
+    Tcl_Interp *interp,         /* Used for error reporting if not NULL. */
+    register Tcl_Obj *objPtr,	/* The object from which to get a double. */
+    register double *dblPtr)	/* Place to store resulting double. */
+{
+    do {
+	if (objPtr->typePtr == &tclDoubleType) {
+	    if (TclIsNaN(objPtr->internalRep.doubleValue)) {
+		if (interp != NULL) {
+		    Tcl_SetObjResult(interp, Tcl_NewStringObj(
+			    "floating point value is Not a Number", -1));
+                    Tcl_SetErrorCode(interp, "TCL", "VALUE", "DOUBLE", "NAN",
+                            NULL);
+		}
+		return TCL_ERROR;
+	    }
+	    *dblPtr = (double) objPtr->internalRep.doubleValue;
+	    return TCL_OK;
+	}
+	if (objPtr->typePtr == &tclIntType) {
+	    *dblPtr = objPtr->internalRep.longValue;
+	    return TCL_OK;
+	}
+	if (objPtr->typePtr == &tclBignumType) {
+	    mp_int big;
+
+	    UNPACK_BIGNUM(objPtr, big);
+	    *dblPtr = TclBignumToDouble(&big);
+	    return TCL_OK;
+	}
+#ifndef TCL_WIDE_INT_IS_LONG
+	if (objPtr->typePtr == &tclWideIntType) {
+	    *dblPtr = (double) objPtr->internalRep.wideValue;
+	    return TCL_OK;
+	}
+#endif
+    } while (SetDoubleFromAny(interp, objPtr) == TCL_OK);
+    return TCL_ERROR;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * SetDoubleFromAny --
+ *
+ *	Attempt to generate an double-precision floating point internal form
+ *	for the Tcl object "objPtr".
+ *
+ * Results:
+ *	The return value is a standard Tcl object result. If an error occurs
+ *	during conversion, an error message is left in the interpreter's
+ *	result unless "interp" is NULL.
+ *
+ * Side effects:
+ *	If no error occurs, a double is stored as "objPtr"s internal
+ *	representation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+SetDoubleFromAny(
+    Tcl_Interp *interp,		/* Used for error reporting if not NULL. */
+    register Tcl_Obj *objPtr)	/* The object to convert. */
+{
+    return TclParseNumber(interp, objPtr, "floating-point number", NULL, -1,
+	    NULL, 0);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * UpdateStringOfDouble --
+ *
+ *	Update the string representation for a double-precision floating point
+ *	object. This must obey the current tcl_precision value for
+ *	double-to-string conversions. Note: This function does not free an
+ *	existing old string rep so storage will be lost if this has not
+ *	already been done.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The object's string is set to a valid string that results from the
+ *	double-to-string conversion.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+UpdateStringOfDouble(
+    register Tcl_Obj *objPtr)	/* Double obj with string rep to update. */
+{
+    char buffer[TCL_DOUBLE_SPACE];
+    register int len;
+
+    Tcl_PrintDouble(NULL, objPtr->internalRep.doubleValue, buffer);
+    len = strlen(buffer);
+
+    objPtr->bytes = ckalloc(len + 1);
+    memcpy(objPtr->bytes, buffer, (unsigned) len + 1);
+    objPtr->length = len;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_NewIntObj --
+ *
+ *	If a client is compiled with TCL_MEM_DEBUG defined, calls to
+ *	Tcl_NewIntObj to create a new integer object end up calling the
+ *	debugging function Tcl_DbNewLongObj instead.
+ *
+ *	Otherwise, if the client is compiled without TCL_MEM_DEBUG defined,
+ *	calls to Tcl_NewIntObj result in a call to one of the two
+ *	Tcl_NewIntObj implementations below. We provide two implementations so
+ *	that the Tcl core can be compiled to do memory debugging of the core
+ *	even if a client does not request it for itself.
+ *
+ *	Integer and long integer objects share the same "integer" type
+ *	implementation. We store all integers as longs and Tcl_GetIntFromObj
+ *	checks whether the current value of the long can be represented by an
+ *	int.
+ *
+ * Results:
+ *	The newly created object is returned. This object will have an invalid
+ *	string representation. The returned object has ref count 0.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+#undef Tcl_NewIntObj
+#ifdef TCL_MEM_DEBUG
+
+Tcl_Obj *
+Tcl_NewIntObj(
+    register int intValue)	/* Int used to initialize the new object. */
+{
+    return Tcl_DbNewLongObj((long)intValue, "unknown", 0);
+}
+
+#else /* if not TCL_MEM_DEBUG */
+
+Tcl_Obj *
+Tcl_NewIntObj(
+    register int intValue)	/* Int used to initialize the new object. */
+{
+    register Tcl_Obj *objPtr;
+
+    TclNewIntObj(objPtr, intValue);
+    return objPtr;
+}
+#endif /* if TCL_MEM_DEBUG */
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_SetIntObj --
+ *
+ *	Modify an object to be an integer and to have the specified integer
+ *	value.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The object's old string rep, if any, is freed. Also, any old internal
+ *	rep is freed.
+ *
+ *----------------------------------------------------------------------
+ */
+
+#undef Tcl_SetIntObj
+void
+Tcl_SetIntObj(
+    register Tcl_Obj *objPtr,	/* Object whose internal rep to init. */
+    register int intValue)	/* Integer used to set object's value. */
+{
+    if (Tcl_IsShared(objPtr)) {
+	Tcl_Panic("%s called with shared object", "Tcl_SetIntObj");
+    }
+
+    TclSetIntObj(objPtr, intValue);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_GetIntFromObj --
+ *
+ *	Attempt to return an int from the Tcl object "objPtr". If the object
+ *	is not already an int, an attempt will be made to convert it to one.
+ *
+ *	Integer and long integer objects share the same "integer" type
+ *	implementation. We store all integers as longs and Tcl_GetIntFromObj
+ *	checks whether the current value of the long can be represented by an
+ *	int.
+ *
+ * Results:
+ *	The return value is a standard Tcl object result. If an error occurs
+ *	during conversion or if the long integer held by the object can not be
+ *	represented by an int, an error message is left in the interpreter's
+ *	result unless "interp" is NULL.
+ *
+ * Side effects:
+ *	If the object is not already an int, the conversion will free any old
+ *	internal representation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_GetIntFromObj(
+    Tcl_Interp *interp,         /* Used for error reporting if not NULL. */
+    register Tcl_Obj *objPtr,	/* The object from which to get a int. */
+    register int *intPtr)	/* Place to store resulting int. */
+{
+#if (LONG_MAX == INT_MAX)
+    return TclGetLongFromObj(interp, objPtr, (long *) intPtr);
+#else
+    long l;
+
+    if (TclGetLongFromObj(interp, objPtr, &l) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    if ((ULONG_MAX > UINT_MAX) && ((l > UINT_MAX) || (l < -(long)UINT_MAX))) {
+	if (interp != NULL) {
+	    const char *s =
+		    "integer value too large to represent as non-long integer";
+	    Tcl_SetObjResult(interp, Tcl_NewStringObj(s, -1));
+	    Tcl_SetErrorCode(interp, "ARITH", "IOVERFLOW", s, NULL);
+	}
+	return TCL_ERROR;
+    }
+    *intPtr = (int) l;
+    return TCL_OK;
+#endif
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * SetIntFromAny --
+ *
+ *	Attempts to force the internal representation for a Tcl object to
+ *	tclIntType, specifically.
+ *
+ * Results:
+ *	The return value is a standard object Tcl result. If an error occurs
+ *	during conversion, an error message is left in the interpreter's
+ *	result unless "interp" is NULL.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+SetIntFromAny(
+    Tcl_Interp *interp,		/* Tcl interpreter */
+    Tcl_Obj *objPtr)		/* Pointer to the object to convert */
+{
+    long l;
+
+    return TclGetLongFromObj(interp, objPtr, &l);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * UpdateStringOfInt --
+ *
+ *	Update the string representation for an integer object. Note: This
+ *	function does not free an existing old string rep so storage will be
+ *	lost if this has not already been done.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The object's string is set to a valid string that results from the
+ *	int-to-string conversion.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+UpdateStringOfInt(
+    register Tcl_Obj *objPtr)	/* Int object whose string rep to update. */
+{
+    char buffer[TCL_INTEGER_SPACE];
+    register int len;
+
+    len = TclFormatInt(buffer, objPtr->internalRep.longValue);
+
+    objPtr->bytes = ckalloc(len + 1);
+    memcpy(objPtr->bytes, buffer, (unsigned) len + 1);
+    objPtr->length = len;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_NewLongObj --
+ *
+ *	If a client is compiled with TCL_MEM_DEBUG defined, calls to
+ *	Tcl_NewLongObj to create a new long integer object end up calling the
+ *	debugging function Tcl_DbNewLongObj instead.
+ *
+ *	Otherwise, if the client is compiled without TCL_MEM_DEBUG defined,
+ *	calls to Tcl_NewLongObj result in a call to one of the two
+ *	Tcl_NewLongObj implementations below. We provide two implementations
+ *	so that the Tcl core can be compiled to do memory debugging of the
+ *	core even if a client does not request it for itself.
+ *
+ *	Integer and long integer objects share the same "integer" type
+ *	implementation. We store all integers as longs and Tcl_GetIntFromObj
+ *	checks whether the current value of the long can be represented by an
+ *	int.
+ *
+ * Results:
+ *	The newly created object is returned. This object will have an invalid
+ *	string representation. The returned object has ref count 0.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+#ifdef TCL_MEM_DEBUG
+#undef Tcl_NewLongObj
+
+Tcl_Obj *
+Tcl_NewLongObj(
+    register long longValue)	/* Long integer used to initialize the
+				 * new object. */
+{
+    return Tcl_DbNewLongObj(longValue, "unknown", 0);
+}
+
+#else /* if not TCL_MEM_DEBUG */
+
+Tcl_Obj *
+Tcl_NewLongObj(
+    register long longValue)	/* Long integer used to initialize the
+				 * new object. */
+{
+    register Tcl_Obj *objPtr;
+
+    TclNewLongObj(objPtr, longValue);
+    return objPtr;
+}
+#endif /* if TCL_MEM_DEBUG */
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_DbNewLongObj --
+ *
+ *	If a client is compiled with TCL_MEM_DEBUG defined, calls to
+ *	Tcl_NewIntObj and Tcl_NewLongObj to create new integer or long integer
+ *	objects end up calling the debugging function Tcl_DbNewLongObj
+ *	instead. We provide two implementations of Tcl_DbNewLongObj so that
+ *	whether the Tcl core is compiled to do memory debugging of the core is
+ *	independent of whether a client requests debugging for itself.
+ *
+ *	When the core is compiled with TCL_MEM_DEBUG defined, Tcl_DbNewLongObj
+ *	calls Tcl_DbCkalloc directly with the file name and line number from
+ *	its caller. This simplifies debugging since then the [memory active]
+ *	command will report the caller's file name and line number when
+ *	reporting objects that haven't been freed.
+ *
+ *	Otherwise, when the core is compiled without TCL_MEM_DEBUG defined,
+ *	this function just returns the result of calling Tcl_NewLongObj.
+ *
+ * Results:
+ *	The newly created long integer object is returned. This object will
+ *	have an invalid string representation. The returned object has ref
+ *	count 0.
+ *
+ * Side effects:
+ *	Allocates memory.
+ *
+ *----------------------------------------------------------------------
+ */
+
+#ifdef TCL_MEM_DEBUG
+
+Tcl_Obj *
+Tcl_DbNewLongObj(
+    register long longValue,	/* Long integer used to initialize the new
+				 * object. */
+    const char *file,		/* The name of the source file calling this
+				 * function; used for debugging. */
+    int line)			/* Line number in the source file; used for
+				 * debugging. */
+{
+    register Tcl_Obj *objPtr;
+
+    TclDbNewObj(objPtr, file, line);
+    objPtr->bytes = NULL;
+
+    objPtr->internalRep.longValue = longValue;
+    objPtr->typePtr = &tclIntType;
+    return objPtr;
+}
+
+#else /* if not TCL_MEM_DEBUG */
+
+Tcl_Obj *
+Tcl_DbNewLongObj(
+    register long longValue,	/* Long integer used to initialize the new
+				 * object. */
+    const char *file,		/* The name of the source file calling this
+				 * function; used for debugging. */
+    int line)			/* Line number in the source file; used for
+				 * debugging. */
+{
+    return Tcl_NewLongObj(longValue);
+}
+#endif /* TCL_MEM_DEBUG */
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_SetLongObj --
+ *
+ *	Modify an object to be an integer object and to have the specified
+ *	long integer value.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The object's old string rep, if any, is freed. Also, any old internal
+ *	rep is freed.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_SetLongObj(
+    register Tcl_Obj *objPtr,	/* Object whose internal rep to init. */
+    register long longValue)	/* Long integer used to initialize the
+				 * object's value. */
+{
+    if (Tcl_IsShared(objPtr)) {
+	Tcl_Panic("%s called with shared object", "Tcl_SetLongObj");
+    }
+
+    TclSetLongObj(objPtr, longValue);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_GetLongFromObj --
+ *
+ *	Attempt to return an long integer from the Tcl object "objPtr". If the
+ *	object is not already an int object, an attempt will be made to
+ *	convert it to one.
+ *
+ * Results:
+ *	The return value is a standard Tcl object result. If an error occurs
+ *	during conversion, an error message is left in the interpreter's
+ *	result unless "interp" is NULL.
+ *
+ * Side effects:
+ *	If the object is not already an int object, the conversion will free
+ *	any old internal representation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_GetLongFromObj(
+    Tcl_Interp *interp,         /* Used for error reporting if not NULL. */
+    register Tcl_Obj *objPtr,	/* The object from which to get a long. */
+    register long *longPtr)	/* Place to store resulting long. */
+{
+    do {
+	if (objPtr->typePtr == &tclIntType) {
+	    *longPtr = objPtr->internalRep.longValue;
+	    return TCL_OK;
+	}
+#ifndef TCL_WIDE_INT_IS_LONG
+	if (objPtr->typePtr == &tclWideIntType) {
+	    /*
+	     * We return any integer in the range -ULONG_MAX to ULONG_MAX
+	     * converted to a long, ignoring overflow. The rule preserves
+	     * existing semantics for conversion of integers on input, but
+	     * avoids inadvertent demotion of wide integers to 32-bit ones in
+	     * the internal rep.
+	     */
+
+	    Tcl_WideInt w = objPtr->internalRep.wideValue;
+
+	    if (w >= -(Tcl_WideInt)(ULONG_MAX)
+		    && w <= (Tcl_WideInt)(ULONG_MAX)) {
+		*longPtr = Tcl_WideAsLong(w);
+		return TCL_OK;
+	    }
+	    goto tooLarge;
+	}
+#endif
+	if (objPtr->typePtr == &tclDoubleType) {
+	    if (interp != NULL) {
+                Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+                        "expected integer but got \"%s\"",
+                        Tcl_GetString(objPtr)));
+		Tcl_SetErrorCode(interp, "TCL", "VALUE", "INTEGER", NULL);
+	    }
+	    return TCL_ERROR;
+	}
+	if (objPtr->typePtr == &tclBignumType) {
+	    /*
+	     * Must check for those bignum values that can fit in a long, even
+	     * when auto-narrowing is enabled. Only those values in the signed
+	     * long range get auto-narrowed to tclIntType, while all the
+	     * values in the unsigned long range will fit in a long.
+	     */
+
+	    mp_int big;
+
+	    UNPACK_BIGNUM(objPtr, big);
+	    if ((size_t) big.used <= (CHAR_BIT * sizeof(long) + DIGIT_BIT - 1)
+		    / DIGIT_BIT) {
+		unsigned long value = 0, numBytes = sizeof(long);
+		long scratch;
+		unsigned char *bytes = (unsigned char *) &scratch;
+
+		if (mp_to_unsigned_bin_n(&big, bytes, &numBytes) == MP_OKAY) {
+		    while (numBytes-- > 0) {
+			value = (value << CHAR_BIT) | *bytes++;
+		    }
+		    if (big.sign) {
+			*longPtr = - (long) value;
+		    } else {
+			*longPtr = (long) value;
+		    }
+		    return TCL_OK;
+		}
+	    }
+#ifndef TCL_WIDE_INT_IS_LONG
+	tooLarge:
+#endif
+	    if (interp != NULL) {
+		const char *s = "integer value too large to represent";
+		Tcl_Obj *msg = Tcl_NewStringObj(s, -1);
+
+		Tcl_SetObjResult(interp, msg);
+		Tcl_SetErrorCode(interp, "ARITH", "IOVERFLOW", s, NULL);
+	    }
+	    return TCL_ERROR;
+	}
+    } while (TclParseNumber(interp, objPtr, "integer", NULL, -1, NULL,
+	    TCL_PARSE_INTEGER_ONLY)==TCL_OK);
+    return TCL_ERROR;
+}
+#ifndef TCL_WIDE_INT_IS_LONG
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * UpdateStringOfWideInt --
+ *
+ *	Update the string representation for a wide integer object. Note: this
+ *	function does not free an existing old string rep so storage will be
+ *	lost if this has not already been done.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The object's string is set to a valid string that results from the
+ *	wideInt-to-string conversion.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+UpdateStringOfWideInt(
+    register Tcl_Obj *objPtr)	/* Int object whose string rep to update. */
+{
+    char buffer[TCL_INTEGER_SPACE+2];
+    register unsigned len;
+    register Tcl_WideInt wideVal = objPtr->internalRep.wideValue;
+
+    /*
+     * Note that sprintf will generate a compiler warning under Mingw claiming
+     * %I64 is an unknown format specifier. Just ignore this warning. We can't
+     * use %L as the format specifier since that gets printed as a 32 bit
+     * value.
+     */
+
+    sprintf(buffer, "%" TCL_LL_MODIFIER "d", wideVal);
+    len = strlen(buffer);
+    objPtr->bytes = ckalloc(len + 1);
+    memcpy(objPtr->bytes, buffer, len + 1);
+    objPtr->length = len;
+}
+#endif /* !TCL_WIDE_INT_IS_LONG */
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_NewWideIntObj --
+ *
+ *	If a client is compiled with TCL_MEM_DEBUG defined, calls to
+ *	Tcl_NewWideIntObj to create a new 64-bit integer object end up calling
+ *	the debugging function Tcl_DbNewWideIntObj instead.
+ *
+ *	Otherwise, if the client is compiled without TCL_MEM_DEBUG defined,
+ *	calls to Tcl_NewWideIntObj result in a call to one of the two
+ *	Tcl_NewWideIntObj implementations below. We provide two
+ *	implementations so that the Tcl core can be compiled to do memory
+ *	debugging of the core even if a client does not request it for itself.
+ *
+ * Results:
+ *	The newly created object is returned. This object will have an invalid
+ *	string representation. The returned object has ref count 0.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+#ifdef TCL_MEM_DEBUG
+#undef Tcl_NewWideIntObj
+
+Tcl_Obj *
+Tcl_NewWideIntObj(
+    register Tcl_WideInt wideValue)
+				/* Wide integer used to initialize the new
+				 * object. */
+{
+    return Tcl_DbNewWideIntObj(wideValue, "unknown", 0);
+}
+
+#else /* if not TCL_MEM_DEBUG */
+
+Tcl_Obj *
+Tcl_NewWideIntObj(
+    register Tcl_WideInt wideValue)
+				/* Wide integer used to initialize the new
+				 * object. */
+{
+    register Tcl_Obj *objPtr;
+
+    TclNewObj(objPtr);
+    Tcl_SetWideIntObj(objPtr, wideValue);
+    return objPtr;
+}
+#endif /* if TCL_MEM_DEBUG */
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_DbNewWideIntObj --
+ *
+ *	If a client is compiled with TCL_MEM_DEBUG defined, calls to
+ *	Tcl_NewWideIntObj to create new wide integer end up calling the
+ *	debugging function Tcl_DbNewWideIntObj instead. We provide two
+ *	implementations of Tcl_DbNewWideIntObj so that whether the Tcl core is
+ *	compiled to do memory debugging of the core is independent of whether
+ *	a client requests debugging for itself.
+ *
+ *	When the core is compiled with TCL_MEM_DEBUG defined,
+ *	Tcl_DbNewWideIntObj calls Tcl_DbCkalloc directly with the file name
+ *	and line number from its caller. This simplifies debugging since then
+ *	the checkmem command will report the caller's file name and line
+ *	number when reporting objects that haven't been freed.
+ *
+ *	Otherwise, when the core is compiled without TCL_MEM_DEBUG defined,
+ *	this function just returns the result of calling Tcl_NewWideIntObj.
+ *
+ * Results:
+ *	The newly created wide integer object is returned. This object will
+ *	have an invalid string representation. The returned object has ref
+ *	count 0.
+ *
+ * Side effects:
+ *	Allocates memory.
+ *
+ *----------------------------------------------------------------------
+ */
+
+#ifdef TCL_MEM_DEBUG
+
+Tcl_Obj *
+Tcl_DbNewWideIntObj(
+    register Tcl_WideInt wideValue,
+				/* Wide integer used to initialize the new
+				 * object. */
+    const char *file,		/* The name of the source file calling this
+				 * function; used for debugging. */
+    int line)			/* Line number in the source file; used for
+				 * debugging. */
+{
+    register Tcl_Obj *objPtr;
+
+    TclDbNewObj(objPtr, file, line);
+    Tcl_SetWideIntObj(objPtr, wideValue);
+    return objPtr;
+}
+
+#else /* if not TCL_MEM_DEBUG */
+
+Tcl_Obj *
+Tcl_DbNewWideIntObj(
+    register Tcl_WideInt wideValue,
+				/* Long integer used to initialize the new
+				 * object. */
+    const char *file,		/* The name of the source file calling this
+				 * function; used for debugging. */
+    int line)			/* Line number in the source file; used for
+				 * debugging. */
+{
+    return Tcl_NewWideIntObj(wideValue);
+}
+#endif /* TCL_MEM_DEBUG */
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_SetWideIntObj --
+ *
+ *	Modify an object to be a wide integer object and to have the specified
+ *	wide integer value.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The object's old string rep, if any, is freed. Also, any old internal
+ *	rep is freed.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_SetWideIntObj(
+    register Tcl_Obj *objPtr,	/* Object w. internal rep to init. */
+    register Tcl_WideInt wideValue)
+				/* Wide integer used to initialize the
+				 * object's value. */
+{
+    if (Tcl_IsShared(objPtr)) {
+	Tcl_Panic("%s called with shared object", "Tcl_SetWideIntObj");
+    }
+
+    if ((wideValue >= (Tcl_WideInt) LONG_MIN)
+	    && (wideValue <= (Tcl_WideInt) LONG_MAX)) {
+	TclSetLongObj(objPtr, (long) wideValue);
+    } else {
+#ifndef TCL_WIDE_INT_IS_LONG
+	TclSetWideIntObj(objPtr, wideValue);
+#else
+	mp_int big;
+
+	TclBNInitBignumFromWideInt(&big, wideValue);
+	Tcl_SetBignumObj(objPtr, &big);
+#endif
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_GetWideIntFromObj --
+ *
+ *	Attempt to return a wide integer from the Tcl object "objPtr". If the
+ *	object is not already a wide int object, an attempt will be made to
+ *	convert it to one.
+ *
+ * Results:
+ *	The return value is a standard Tcl object result. If an error occurs
+ *	during conversion, an error message is left in the interpreter's
+ *	result unless "interp" is NULL.
+ *
+ * Side effects:
+ *	If the object is not already an int object, the conversion will free
+ *	any old internal representation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_GetWideIntFromObj(
+    Tcl_Interp *interp,         /* Used for error reporting if not NULL. */
+    register Tcl_Obj *objPtr,	/* Object from which to get a wide int. */
+    register Tcl_WideInt *wideIntPtr)
+				/* Place to store resulting long. */
+{
+    do {
+#ifndef TCL_WIDE_INT_IS_LONG
+	if (objPtr->typePtr == &tclWideIntType) {
+	    *wideIntPtr = objPtr->internalRep.wideValue;
+	    return TCL_OK;
+	}
+#endif
+	if (objPtr->typePtr == &tclIntType) {
+	    *wideIntPtr = (Tcl_WideInt) objPtr->internalRep.longValue;
+	    return TCL_OK;
+	}
+	if (objPtr->typePtr == &tclDoubleType) {
+	    if (interp != NULL) {
+                Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+                        "expected integer but got \"%s\"",
+                        Tcl_GetString(objPtr)));
+		Tcl_SetErrorCode(interp, "TCL", "VALUE", "INTEGER", NULL);
+	    }
+	    return TCL_ERROR;
+	}
+	if (objPtr->typePtr == &tclBignumType) {
+	    /*
+	     * Must check for those bignum values that can fit in a
+	     * Tcl_WideInt, even when auto-narrowing is enabled.
+	     */
+
+	    mp_int big;
+
+	    UNPACK_BIGNUM(objPtr, big);
+	    if ((size_t) big.used <= (CHAR_BIT * sizeof(Tcl_WideInt)
+		     + DIGIT_BIT - 1) / DIGIT_BIT) {
+		Tcl_WideUInt value = 0;
+		unsigned long numBytes = sizeof(Tcl_WideInt);
+		Tcl_WideInt scratch;
+		unsigned char *bytes = (unsigned char *) &scratch;
+
+		if (mp_to_unsigned_bin_n(&big, bytes, &numBytes) == MP_OKAY) {
+		    while (numBytes-- > 0) {
+			value = (value << CHAR_BIT) | *bytes++;
+		    }
+		    if (big.sign) {
+			*wideIntPtr = - (Tcl_WideInt) value;
+		    } else {
+			*wideIntPtr = (Tcl_WideInt) value;
+		    }
+		    return TCL_OK;
+		}
+	    }
+	    if (interp != NULL) {
+		const char *s = "integer value too large to represent";
+		Tcl_Obj *msg = Tcl_NewStringObj(s, -1);
+
+		Tcl_SetObjResult(interp, msg);
+		Tcl_SetErrorCode(interp, "ARITH", "IOVERFLOW", s, NULL);
+	    }
+	    return TCL_ERROR;
+	}
+    } while (TclParseNumber(interp, objPtr, "integer", NULL, -1, NULL,
+	    TCL_PARSE_INTEGER_ONLY)==TCL_OK);
+    return TCL_ERROR;
+}
+#ifndef TCL_WIDE_INT_IS_LONG
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * SetWideIntFromAny --
+ *
+ *	Attempts to force the internal representation for a Tcl object to
+ *	tclWideIntType, specifically.
+ *
+ * Results:
+ *	The return value is a standard object Tcl result. If an error occurs
+ *	during conversion, an error message is left in the interpreter's
+ *	result unless "interp" is NULL.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+SetWideIntFromAny(
+    Tcl_Interp *interp,		/* Tcl interpreter */
+    Tcl_Obj *objPtr)		/* Pointer to the object to convert */
+{
+    Tcl_WideInt w;
+    return Tcl_GetWideIntFromObj(interp, objPtr, &w);
+}
+#endif /* !TCL_WIDE_INT_IS_LONG */
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * FreeBignum --
+ *
+ *	This function frees the internal rep of a bignum.
+ *
+ * Results:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+FreeBignum(
+    Tcl_Obj *objPtr)
+{
+    mp_int toFree;		/* Bignum to free */
+
+    UNPACK_BIGNUM(objPtr, toFree);
+    mp_clear(&toFree);
+    if (PTR2INT(objPtr->internalRep.twoPtrValue.ptr2) < 0) {
+	ckfree(objPtr->internalRep.twoPtrValue.ptr1);
+    }
+    objPtr->typePtr = NULL;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * DupBignum --
+ *
+ *	This function duplicates the internal rep of a bignum.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The destination object receies a copy of the source object
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+DupBignum(
+    Tcl_Obj *srcPtr,
+    Tcl_Obj *copyPtr)
+{
+    mp_int bignumVal;
+    mp_int bignumCopy;
+
+    copyPtr->typePtr = &tclBignumType;
+    UNPACK_BIGNUM(srcPtr, bignumVal);
+    if (mp_init_copy(&bignumCopy, &bignumVal) != MP_OKAY) {
+	Tcl_Panic("initialization failure in DupBignum");
+    }
+    PACK_BIGNUM(bignumCopy, copyPtr);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * UpdateStringOfBignum --
+ *
+ *	This function updates the string representation of a bignum object.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The object's string is set to whatever results from the bignum-
+ *	to-string conversion.
+ *
+ * The object's existing string representation is NOT freed; memory will leak
+ * if the string rep is still valid at the time this function is called.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+UpdateStringOfBignum(
+    Tcl_Obj *objPtr)
+{
+    mp_int bignumVal;
+    int size;
+    int status;
+    char *stringVal;
+
+    UNPACK_BIGNUM(objPtr, bignumVal);
+    status = mp_radix_size(&bignumVal, 10, &size);
+    if (status != MP_OKAY) {
+	Tcl_Panic("radix size failure in UpdateStringOfBignum");
+    }
+    if (size == 3) {
+	/*
+	 * mp_radix_size() returns 3 when more than INT_MAX bytes would be
+	 * needed to hold the string rep (because mp_radix_size ignores
+	 * integer overflow issues). When we know the string rep will be more
+	 * than 3, we can conclude the string rep would overflow our string
+	 * length limits.
+	 *
+	 * Note that so long as we enforce our bignums to the size that fits
+	 * in a packed bignum, this branch will never be taken.
+	 */
+
+	Tcl_Panic("UpdateStringOfBignum: string length limit exceeded");
+    }
+    stringVal = ckalloc(size);
+    status = mp_toradix_n(&bignumVal, stringVal, 10, size);
+    if (status != MP_OKAY) {
+	Tcl_Panic("conversion failure in UpdateStringOfBignum");
+    }
+    objPtr->bytes = stringVal;
+    objPtr->length = size - 1;	/* size includes a trailing NUL byte. */
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_NewBignumObj --
+ *
+ *	Creates an initializes a bignum object.
+ *
+ * Results:
+ *	Returns the newly created object.
+ *
+ * Side effects:
+ *	The bignum value is cleared, since ownership has transferred to Tcl.
+ *
+ *----------------------------------------------------------------------
+ */
+
+#ifdef TCL_MEM_DEBUG
+#undef Tcl_NewBignumObj
+
+Tcl_Obj *
+Tcl_NewBignumObj(
+    mp_int *bignumValue)
+{
+    return Tcl_DbNewBignumObj(bignumValue, "unknown", 0);
+}
+#else
+Tcl_Obj *
+Tcl_NewBignumObj(
+    mp_int *bignumValue)
+{
+    Tcl_Obj *objPtr;
+
+    TclNewObj(objPtr);
+    Tcl_SetBignumObj(objPtr, bignumValue);
+    return objPtr;
+}
+#endif
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_DbNewBignumObj --
+ *
+ *	This function is normally called when debugging: that is, when
+ *	TCL_MEM_DEBUG is defined. It constructs a bignum object, recording the
+ *	creation point so that [memory active] can report it.
+ *
+ * Results:
+ *	Returns the newly created object.
+ *
+ * Side effects:
+ *	The bignum value is cleared, since ownership has transferred to Tcl.
+ *
+ *----------------------------------------------------------------------
+ */
+
+#ifdef TCL_MEM_DEBUG
+Tcl_Obj *
+Tcl_DbNewBignumObj(
+    mp_int *bignumValue,
+    const char *file,
+    int line)
+{
+    Tcl_Obj *objPtr;
+
+    TclDbNewObj(objPtr, file, line);
+    Tcl_SetBignumObj(objPtr, bignumValue);
+    return objPtr;
+}
+#else
+Tcl_Obj *
+Tcl_DbNewBignumObj(
+    mp_int *bignumValue,
+    const char *file,
+    int line)
+{
+    return Tcl_NewBignumObj(bignumValue);
+}
+#endif
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * GetBignumFromObj --
+ *
+ *	This function retrieves a 'bignum' value from a Tcl object, converting
+ *	the object if necessary. Either copies or transfers the mp_int value
+ *	depending on the copy flag value passed in.
+ *
+ * Results:
+ *	Returns TCL_OK if the conversion is successful, TCL_ERROR otherwise.
+ *
+ * Side effects:
+ *	A copy of bignum is stored in *bignumValue, which is expected to be
+ *	uninitialized or cleared. If conversion fails, and the 'interp'
+ *	argument is not NULL, an error message is stored in the interpreter
+ *	result.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+GetBignumFromObj(
+    Tcl_Interp *interp,		/* Tcl interpreter for error reporting */
+    Tcl_Obj *objPtr,		/* Object to read */
+    int copy,			/* Whether to copy the returned bignum value */
+    mp_int *bignumValue)	/* Returned bignum value. */
+{
+    do {
+	if (objPtr->typePtr == &tclBignumType) {
+	    if (copy || Tcl_IsShared(objPtr)) {
+		mp_int temp;
+
+		UNPACK_BIGNUM(objPtr, temp);
+		mp_init_copy(bignumValue, &temp);
+	    } else {
+		UNPACK_BIGNUM(objPtr, *bignumValue);
+		objPtr->internalRep.twoPtrValue.ptr1 = NULL;
+		objPtr->internalRep.twoPtrValue.ptr2 = NULL;
+		objPtr->typePtr = NULL;
+		if (objPtr->bytes == NULL) {
+		    TclInitStringRep(objPtr, tclEmptyStringRep, 0);
+		}
+	    }
+	    return TCL_OK;
+	}
+	if (objPtr->typePtr == &tclIntType) {
+	    TclBNInitBignumFromLong(bignumValue, objPtr->internalRep.longValue);
+	    return TCL_OK;
+	}
+#ifndef TCL_WIDE_INT_IS_LONG
+	if (objPtr->typePtr == &tclWideIntType) {
+	    TclBNInitBignumFromWideInt(bignumValue,
+		    objPtr->internalRep.wideValue);
+	    return TCL_OK;
+	}
+#endif
+	if (objPtr->typePtr == &tclDoubleType) {
+	    if (interp != NULL) {
+                Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+                        "expected integer but got \"%s\"",
+                        Tcl_GetString(objPtr)));
+		Tcl_SetErrorCode(interp, "TCL", "VALUE", "INTEGER", NULL);
+	    }
+	    return TCL_ERROR;
+	}
+    } while (TclParseNumber(interp, objPtr, "integer", NULL, -1, NULL,
+	    TCL_PARSE_INTEGER_ONLY)==TCL_OK);
+    return TCL_ERROR;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_GetBignumFromObj --
+ *
+ *	This function retrieves a 'bignum' value from a Tcl object, converting
+ *	the object if necessary.
+ *
+ * Results:
+ *	Returns TCL_OK if the conversion is successful, TCL_ERROR otherwise.
+ *
+ * Side effects:
+ *	A copy of bignum is stored in *bignumValue, which is expected to be
+ *	uninitialized or cleared. If conversion fails, an the 'interp'
+ *	argument is not NULL, an error message is stored in the interpreter
+ *	result.
+ *
+ *	It is expected that the caller will NOT have invoked mp_init on the
+ *	bignum value before passing it in. Tcl will initialize the mp_int as
+ *	it sets the value. The value is a copy of the value in objPtr, so it
+ *	becomes the responsibility of the caller to call mp_clear on it.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_GetBignumFromObj(
+    Tcl_Interp *interp,		/* Tcl interpreter for error reporting */
+    Tcl_Obj *objPtr,		/* Object to read */
+    mp_int *bignumValue)	/* Returned bignum value. */
+{
+    return GetBignumFromObj(interp, objPtr, 1, bignumValue);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_TakeBignumFromObj --
+ *
+ *	This function retrieves a 'bignum' value from a Tcl object, converting
+ *	the object if necessary.
+ *
+ * Results:
+ *	Returns TCL_OK if the conversion is successful, TCL_ERROR otherwise.
+ *
+ * Side effects:
+ *	A copy of bignum is stored in *bignumValue, which is expected to be
+ *	uninitialized or cleared. If conversion fails, an the 'interp'
+ *	argument is not NULL, an error message is stored in the interpreter
+ *	result.
+ *
+ *	It is expected that the caller will NOT have invoked mp_init on the
+ *	bignum value before passing it in. Tcl will initialize the mp_int as
+ *	it sets the value. The value is transferred from the internals of
+ *	objPtr to the caller, passing responsibility of the caller to call
+ *	mp_clear on it. The objPtr is cleared to hold an empty value.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_TakeBignumFromObj(
+    Tcl_Interp *interp,		/* Tcl interpreter for error reporting */
+    Tcl_Obj *objPtr,		/* Object to read */
+    mp_int *bignumValue)	/* Returned bignum value. */
+{
+    return GetBignumFromObj(interp, objPtr, 0, bignumValue);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_SetBignumObj --
+ *
+ *	This function sets the value of a Tcl_Obj to a large integer.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Object value is stored. The bignum value is cleared, since ownership
+ *	has transferred to Tcl.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_SetBignumObj(
+    Tcl_Obj *objPtr,		/* Object to set */
+    mp_int *bignumValue)	/* Value to store */
+{
+    if (Tcl_IsShared(objPtr)) {
+	Tcl_Panic("%s called with shared object", "Tcl_SetBignumObj");
+    }
+    if ((size_t) bignumValue->used
+	    <= (CHAR_BIT * sizeof(long) + DIGIT_BIT - 1) / DIGIT_BIT) {
+	unsigned long value = 0, numBytes = sizeof(long);
+	long scratch;
+	unsigned char *bytes = (unsigned char *) &scratch;
+
+	if (mp_to_unsigned_bin_n(bignumValue, bytes, &numBytes) != MP_OKAY) {
+	    goto tooLargeForLong;
+	}
+	while (numBytes-- > 0) {
+	    value = (value << CHAR_BIT) | *bytes++;
+	}
+	if (value > (((~(unsigned long)0) >> 1) + bignumValue->sign)) {
+	    goto tooLargeForLong;
+	}
+	if (bignumValue->sign) {
+	    TclSetLongObj(objPtr, -(long)value);
+	} else {
+	    TclSetLongObj(objPtr, (long)value);
+	}
+	mp_clear(bignumValue);
+	return;
+    }
+  tooLargeForLong:
+#ifndef TCL_WIDE_INT_IS_LONG
+    if ((size_t) bignumValue->used
+	    <= (CHAR_BIT * sizeof(Tcl_WideInt) + DIGIT_BIT - 1) / DIGIT_BIT) {
+	Tcl_WideUInt value = 0;
+	unsigned long numBytes = sizeof(Tcl_WideInt);
+	Tcl_WideInt scratch;
+	unsigned char *bytes = (unsigned char *)&scratch;
+
+	if (mp_to_unsigned_bin_n(bignumValue, bytes, &numBytes) != MP_OKAY) {
+	    goto tooLargeForWide;
+	}
+	while (numBytes-- > 0) {
+	    value = (value << CHAR_BIT) | *bytes++;
+	}
+	if (value > (((~(Tcl_WideUInt)0) >> 1) + bignumValue->sign)) {
+	    goto tooLargeForWide;
+	}
+	if (bignumValue->sign) {
+	    TclSetWideIntObj(objPtr, -(Tcl_WideInt)value);
+	} else {
+	    TclSetWideIntObj(objPtr, (Tcl_WideInt)value);
+	}
+	mp_clear(bignumValue);
+	return;
+    }
+  tooLargeForWide:
+#endif
+    TclInvalidateStringRep(objPtr);
+    TclFreeIntRep(objPtr);
+    TclSetBignumIntRep(objPtr, bignumValue);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclSetBignumIntRep --
+ *
+ *	Install a bignum into the internal representation of an object.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Object internal representation is updated and object type is set. The
+ *	bignum value is cleared, since ownership has transferred to the
+ *	object.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclSetBignumIntRep(
+    Tcl_Obj *objPtr,
+    mp_int *bignumValue)
+{
+    objPtr->typePtr = &tclBignumType;
+    PACK_BIGNUM(*bignumValue, objPtr);
+
+    /*
+     * Clear the mp_int value.
+     *
+     * Don't call mp_clear() because it would free the digit array we just
+     * packed into the Tcl_Obj.
+     */
+
+    bignumValue->dp = NULL;
+    bignumValue->alloc = bignumValue->used = 0;
+    bignumValue->sign = MP_NEG;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclGetNumberFromObj --
+ *
+ *      Extracts a number (of any possible numeric type) from an object.
+ *
+ * Results:
+ *      Whether the extraction worked. The type is stored in the variable
+ *      referred to by the typePtr argument, and a pointer to the
+ *      representation is stored in the variable referred to by the
+ *      clientDataPtr.
+ *
+ * Side effects:
+ *      Can allocate thread-specific data for handling the copy-out space for
+ *      bignums; this space is shared within a thread.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclGetNumberFromObj(
+    Tcl_Interp *interp,
+    Tcl_Obj *objPtr,
+    ClientData *clientDataPtr,
+    int *typePtr)
+{
+    do {
+	if (objPtr->typePtr == &tclDoubleType) {
+	    if (TclIsNaN(objPtr->internalRep.doubleValue)) {
+		*typePtr = TCL_NUMBER_NAN;
+	    } else {
+		*typePtr = TCL_NUMBER_DOUBLE;
+	    }
+	    *clientDataPtr = &objPtr->internalRep.doubleValue;
+	    return TCL_OK;
+	}
+	if (objPtr->typePtr == &tclIntType) {
+	    *typePtr = TCL_NUMBER_LONG;
+	    *clientDataPtr = &objPtr->internalRep.longValue;
+	    return TCL_OK;
+	}
+#ifndef TCL_WIDE_INT_IS_LONG
+	if (objPtr->typePtr == &tclWideIntType) {
+	    *typePtr = TCL_NUMBER_WIDE;
+	    *clientDataPtr = &objPtr->internalRep.wideValue;
+	    return TCL_OK;
+	}
+#endif
+	if (objPtr->typePtr == &tclBignumType) {
+	    static Tcl_ThreadDataKey bignumKey;
+	    mp_int *bigPtr = Tcl_GetThreadData(&bignumKey,
+		    (int) sizeof(mp_int));
+
+	    UNPACK_BIGNUM(objPtr, *bigPtr);
+	    *typePtr = TCL_NUMBER_BIG;
+	    *clientDataPtr = bigPtr;
+	    return TCL_OK;
+	}
+    } while (TCL_OK ==
+	    TclParseNumber(interp, objPtr, "number", NULL, -1, NULL, 0));
+    return TCL_ERROR;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_DbIncrRefCount --
+ *
+ *	This function is normally called when debugging: i.e., when
+ *	TCL_MEM_DEBUG is defined. This checks to see whether or not the memory
+ *	has been freed before incrementing the ref count.
+ *
+ *	When TCL_MEM_DEBUG is not defined, this function just increments the
+ *	reference count of the object.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The object's ref count is incremented.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_DbIncrRefCount(
+    register Tcl_Obj *objPtr,	/* The object we are registering a reference
+				 * to. */
+    const char *file,		/* The name of the source file calling this
+				 * function; used for debugging. */
+    int line)			/* Line number in the source file; used for
+				 * debugging. */
+{
+#ifdef TCL_MEM_DEBUG
+    if (objPtr->refCount == 0x61616161) {
+	fprintf(stderr, "file = %s, line = %d\n", file, line);
+	fflush(stderr);
+	Tcl_Panic("incrementing refCount of previously disposed object");
+    }
+
+# ifdef TCL_THREADS
+    /*
+     * Check to make sure that the Tcl_Obj was allocated by the current
+     * thread. Don't do this check when shutting down since thread local
+     * storage can be finalized before the last Tcl_Obj is freed.
+     */
+
+    if (!TclInExit()) {
+	ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+	Tcl_HashTable *tablePtr = tsdPtr->objThreadMap;
+	Tcl_HashEntry *hPtr;
+
+	if (!tablePtr) {
+	    Tcl_Panic("object table not initialized");
+	}
+	hPtr = Tcl_FindHashEntry(tablePtr, objPtr);
+	if (!hPtr) {
+	    Tcl_Panic("Trying to %s of Tcl_Obj allocated in another thread",
+                    "incr ref count");
+	}
+    }
+# endif /* TCL_THREADS */
+#endif /* TCL_MEM_DEBUG */
+    ++(objPtr)->refCount;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_DbDecrRefCount --
+ *
+ *	This function is normally called when debugging: i.e., when
+ *	TCL_MEM_DEBUG is defined. This checks to see whether or not the memory
+ *	has been freed before decrementing the ref count.
+ *
+ *	When TCL_MEM_DEBUG is not defined, this function just decrements the
+ *	reference count of the object.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The object's ref count is incremented.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_DbDecrRefCount(
+    register Tcl_Obj *objPtr,	/* The object we are releasing a reference
+				 * to. */
+    const char *file,		/* The name of the source file calling this
+				 * function; used for debugging. */
+    int line)			/* Line number in the source file; used for
+				 * debugging. */
+{
+#ifdef TCL_MEM_DEBUG
+    if (objPtr->refCount == 0x61616161) {
+	fprintf(stderr, "file = %s, line = %d\n", file, line);
+	fflush(stderr);
+	Tcl_Panic("decrementing refCount of previously disposed object");
+    }
+
+# ifdef TCL_THREADS
+    /*
+     * Check to make sure that the Tcl_Obj was allocated by the current
+     * thread. Don't do this check when shutting down since thread local
+     * storage can be finalized before the last Tcl_Obj is freed.
+     */
+
+    if (!TclInExit()) {
+	ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+	Tcl_HashTable *tablePtr = tsdPtr->objThreadMap;
+	Tcl_HashEntry *hPtr;
+
+	if (!tablePtr) {
+	    Tcl_Panic("object table not initialized");
+	}
+	hPtr = Tcl_FindHashEntry(tablePtr, objPtr);
+	if (!hPtr) {
+	    Tcl_Panic("Trying to %s of Tcl_Obj allocated in another thread",
+                    "decr ref count");
+	}
+    }
+# endif /* TCL_THREADS */
+#endif /* TCL_MEM_DEBUG */
+
+    if (objPtr->refCount-- <= 1) {
+	TclFreeObj(objPtr);
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_DbIsShared --
+ *
+ *	This function is normally called when debugging: i.e., when
+ *	TCL_MEM_DEBUG is defined. It tests whether the object has a ref count
+ *	greater than one.
+ *
+ *	When TCL_MEM_DEBUG is not defined, this function just tests if the
+ *	object has a ref count greater than one.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_DbIsShared(
+    register Tcl_Obj *objPtr,	/* The object to test for being shared. */
+    const char *file,		/* The name of the source file calling this
+				 * function; used for debugging. */
+    int line)			/* Line number in the source file; used for
+				 * debugging. */
+{
+#ifdef TCL_MEM_DEBUG
+    if (objPtr->refCount == 0x61616161) {
+	fprintf(stderr, "file = %s, line = %d\n", file, line);
+	fflush(stderr);
+	Tcl_Panic("checking whether previously disposed object is shared");
+    }
+
+# ifdef TCL_THREADS
+    /*
+     * Check to make sure that the Tcl_Obj was allocated by the current
+     * thread. Don't do this check when shutting down since thread local
+     * storage can be finalized before the last Tcl_Obj is freed.
+     */
+
+    if (!TclInExit()) {
+	ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+	Tcl_HashTable *tablePtr = tsdPtr->objThreadMap;
+	Tcl_HashEntry *hPtr;
+
+	if (!tablePtr) {
+	    Tcl_Panic("object table not initialized");
+	}
+	hPtr = Tcl_FindHashEntry(tablePtr, objPtr);
+	if (!hPtr) {
+	    Tcl_Panic("Trying to %s of Tcl_Obj allocated in another thread",
+                    "check shared status");
+	}
+    }
+# endif /* TCL_THREADS */
+#endif /* TCL_MEM_DEBUG */
+
+#ifdef TCL_COMPILE_STATS
+    Tcl_MutexLock(&tclObjMutex);
+    if ((objPtr)->refCount <= 1) {
+	tclObjsShared[1]++;
+    } else if ((objPtr)->refCount < TCL_MAX_SHARED_OBJ_STATS) {
+	tclObjsShared[(objPtr)->refCount]++;
+    } else {
+	tclObjsShared[0]++;
+    }
+    Tcl_MutexUnlock(&tclObjMutex);
+#endif /* TCL_COMPILE_STATS */
+
+    return ((objPtr)->refCount > 1);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_InitObjHashTable --
+ *
+ *	Given storage for a hash table, set up the fields to prepare the hash
+ *	table for use, the keys are Tcl_Obj *.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	TablePtr is now ready to be passed to Tcl_FindHashEntry and
+ *	Tcl_CreateHashEntry.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_InitObjHashTable(
+    register Tcl_HashTable *tablePtr)
+				/* Pointer to table record, which is supplied
+				 * by the caller. */
+{
+    Tcl_InitCustomHashTable(tablePtr, TCL_CUSTOM_PTR_KEYS,
+	    &tclObjHashKeyType);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * AllocObjEntry --
+ *
+ *	Allocate space for a Tcl_HashEntry containing the Tcl_Obj * key.
+ *
+ * Results:
+ *	The return value is a pointer to the created entry.
+ *
+ * Side effects:
+ *	Increments the reference count on the object.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static Tcl_HashEntry *
+AllocObjEntry(
+    Tcl_HashTable *tablePtr,	/* Hash table. */
+    void *keyPtr)		/* Key to store in the hash table entry. */
+{
+    Tcl_Obj *objPtr = keyPtr;
+    Tcl_HashEntry *hPtr = ckalloc(sizeof(Tcl_HashEntry));
+
+    hPtr->key.objPtr = objPtr;
+    Tcl_IncrRefCount(objPtr);
+    hPtr->clientData = NULL;
+
+    return hPtr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclCompareObjKeys --
+ *
+ *	Compares two Tcl_Obj * keys.
+ *
+ * Results:
+ *	The return value is 0 if they are different and 1 if they are the
+ *	same.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclCompareObjKeys(
+    void *keyPtr,		/* New key to compare. */
+    Tcl_HashEntry *hPtr)	/* Existing key to compare. */
+{
+    Tcl_Obj *objPtr1 = keyPtr;
+    Tcl_Obj *objPtr2 = (Tcl_Obj *) hPtr->key.oneWordValue;
+    register const char *p1, *p2;
+    register int l1, l2;
+
+    /*
+     * If the object pointers are the same then they match.
+     * OPT: this comparison was moved to the caller
+
+       if (objPtr1 == objPtr2) return 1;
+    */
+
+    /*
+     * Don't use Tcl_GetStringFromObj as it would prevent l1 and l2 being
+     * in a register.
+     */
+
+    p1 = TclGetString(objPtr1);
+    l1 = objPtr1->length;
+    p2 = TclGetString(objPtr2);
+    l2 = objPtr2->length;
+
+    /*
+     * Only compare if the string representations are of the same length.
+     */
+
+    if (l1 == l2) {
+	for (;; p1++, p2++, l1--) {
+	    if (*p1 != *p2) {
+		break;
+	    }
+	    if (l1 == 0) {
+		return 1;
+	    }
+	}
+    }
+
+    return 0;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclFreeObjEntry --
+ *
+ *	Frees space for a Tcl_HashEntry containing the Tcl_Obj * key.
+ *
+ * Results:
+ *	The return value is a pointer to the created entry.
+ *
+ * Side effects:
+ *	Decrements the reference count of the object.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclFreeObjEntry(
+    Tcl_HashEntry *hPtr)	/* Hash entry to free. */
+{
+    Tcl_Obj *objPtr = (Tcl_Obj *) hPtr->key.oneWordValue;
+
+    Tcl_DecrRefCount(objPtr);
+    ckfree(hPtr);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclHashObjKey --
+ *
+ *	Compute a one-word summary of the string representation of the
+ *	Tcl_Obj, which can be used to generate a hash index.
+ *
+ * Results:
+ *	The return value is a one-word summary of the information in the
+ *	string representation of the Tcl_Obj.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+unsigned int
+TclHashObjKey(
+    Tcl_HashTable *tablePtr,	/* Hash table. */
+    void *keyPtr)		/* Key from which to compute hash value. */
+{
+    Tcl_Obj *objPtr = keyPtr;
+    int length;
+    const char *string = TclGetStringFromObj(objPtr, &length);
+    unsigned int result = 0;
+
+    /*
+     * I tried a zillion different hash functions and asked many other people
+     * for advice. Many people had their own favorite functions, all
+     * different, but no-one had much idea why they were good ones. I chose
+     * the one below (multiply by 9 and add new character) because of the
+     * following reasons:
+     *
+     * 1. Multiplying by 10 is perfect for keys that are decimal strings, and
+     *    multiplying by 9 is just about as good.
+     * 2. Times-9 is (shift-left-3) plus (old). This means that each
+     *    character's bits hang around in the low-order bits of the hash value
+     *    for ever, plus they spread fairly rapidly up to the high-order bits
+     *    to fill out the hash value. This seems works well both for decimal
+     *    and non-decimal strings.
+     *
+     * Note that this function is very weak against malicious strings; it's
+     * very easy to generate multiple keys that have the same hashcode. On the
+     * other hand, that hardly ever actually occurs and this function *is*
+     * very cheap, even by comparison with industry-standard hashes like FNV.
+     * If real strength of hash is required though, use a custom hash based on
+     * Bob Jenkins's lookup3(), but be aware that it's significantly slower.
+     * Tcl does not use that level of strength because it typically does not
+     * need it (and some of the aspects of that strength are genuinely
+     * unnecessary given the rest of Tcl's hash machinery, and the fact that
+     * we do not either transfer hashes to another machine, use them as a true
+     * substitute for equality, or attempt to minimize work in rebuilding the
+     * hash table).
+     *
+     * See also HashStringKey in tclHash.c.
+     * See also HashString in tclLiteral.c.
+     *
+     * See [tcl-Feature Request #2958832]
+     */
+
+    if (length > 0) {
+	result = UCHAR(*string);
+	while (--length) {
+	    result += (result << 3) + UCHAR(*++string);
+	}
+    }
+    return result;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_GetCommandFromObj --
+ *
+ *	Returns the command specified by the name in a Tcl_Obj.
+ *
+ * Results:
+ *	Returns a token for the command if it is found. Otherwise, if it can't
+ *	be found or there is an error, returns NULL.
+ *
+ * Side effects:
+ *	May update the internal representation for the object, caching the
+ *	command reference so that the next time this function is called with
+ *	the same object, the command can be found quickly.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_Command
+Tcl_GetCommandFromObj(
+    Tcl_Interp *interp,		/* The interpreter in which to resolve the
+				 * command and to report errors. */
+    register Tcl_Obj *objPtr)	/* The object containing the command's name.
+				 * If the name starts with "::", will be
+				 * looked up in global namespace. Else, looked
+				 * up first in the current namespace, then in
+				 * global namespace. */
+{
+    register ResolvedCmdName *resPtr;
+
+    /*
+     * Get the internal representation, converting to a command type if
+     * needed. The internal representation is a ResolvedCmdName that points to
+     * the actual command.
+     *
+     * Check the context namespace and the namespace epoch of the resolved
+     * symbol to make sure that it is fresh. Note that we verify that the
+     * namespace id of the context namespace is the same as the one we cached;
+     * this insures that the namespace wasn't deleted and a new one created at
+     * the same address with the same command epoch. Note that fully qualified
+     * names have a NULL refNsPtr, these checks needn't be made.
+     *
+     * Check also that the command's epoch is up to date, and that the command
+     * is not deleted.
+     *
+     * If any check fails, then force another conversion to the command type,
+     * to discard the old rep and create a new one.
+     */
+
+    resPtr = objPtr->internalRep.twoPtrValue.ptr1;
+    if ((objPtr->typePtr == &tclCmdNameType) && (resPtr != NULL)) {
+        register Command *cmdPtr = resPtr->cmdPtr;
+
+        if ((cmdPtr->cmdEpoch == resPtr->cmdEpoch)
+                && !(cmdPtr->flags & CMD_IS_DELETED)
+                && (interp == cmdPtr->nsPtr->interp)
+                && !(cmdPtr->nsPtr->flags & NS_DYING)) {
+            register Namespace *refNsPtr = (Namespace *)
+                    TclGetCurrentNamespace(interp);
+
+            if ((resPtr->refNsPtr == NULL)
+                || ((refNsPtr == resPtr->refNsPtr)
+                    && (resPtr->refNsId == refNsPtr->nsId)
+                    && (resPtr->refNsCmdEpoch == refNsPtr->cmdRefEpoch))) {
+                return (Tcl_Command) cmdPtr;
+            }
+        }
+    }
+
+    /*
+     * OK, must create a new internal representation (or fail) as any cache we
+     * had is invalid one way or another.
+     */
+
+    /* See [] why we cannot call SetCmdNameFromAny() directly here. */
+    if (tclCmdNameType.setFromAnyProc(interp, objPtr) != TCL_OK) {
+        return NULL;
+    }
+    resPtr = objPtr->internalRep.twoPtrValue.ptr1;
+    return (Tcl_Command) (resPtr ? resPtr->cmdPtr : NULL);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclSetCmdNameObj --
+ *
+ *	Modify an object to be an CmdName object that refers to the argument
+ *	Command structure.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The object's old internal rep is freed. It's string rep is not
+ *	changed. The refcount in the Command structure is incremented to keep
+ *	it from being freed if the command is later deleted until
+ *	TclNRExecuteByteCode has a chance to recognize that it was deleted.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclSetCmdNameObj(
+    Tcl_Interp *interp,		/* Points to interpreter containing command
+				 * that should be cached in objPtr. */
+    register Tcl_Obj *objPtr,	/* Points to Tcl object to be changed to a
+				 * CmdName object. */
+    Command *cmdPtr)		/* Points to Command structure that the
+				 * CmdName object should refer to. */
+{
+    Interp *iPtr = (Interp *) interp;
+    register ResolvedCmdName *resPtr;
+    register Namespace *currNsPtr;
+    const char *name;
+
+    if (objPtr->typePtr == &tclCmdNameType) {
+	return;
+    }
+
+    cmdPtr->refCount++;
+    resPtr = ckalloc(sizeof(ResolvedCmdName));
+    resPtr->cmdPtr = cmdPtr;
+    resPtr->cmdEpoch = cmdPtr->cmdEpoch;
+    resPtr->refCount = 1;
+
+    name = TclGetString(objPtr);
+    if ((*name++ == ':') && (*name == ':')) {
+	/*
+	 * The name is fully qualified: set the referring namespace to
+	 * NULL.
+	 */
+
+	resPtr->refNsPtr = NULL;
+    } else {
+	/*
+	 * Get the current namespace.
+	 */
+
+	currNsPtr = iPtr->varFramePtr->nsPtr;
+
+	resPtr->refNsPtr = currNsPtr;
+	resPtr->refNsId = currNsPtr->nsId;
+	resPtr->refNsCmdEpoch = currNsPtr->cmdRefEpoch;
+    }
+
+    TclFreeIntRep(objPtr);
+    objPtr->internalRep.twoPtrValue.ptr1 = resPtr;
+    objPtr->internalRep.twoPtrValue.ptr2 = NULL;
+    objPtr->typePtr = &tclCmdNameType;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * FreeCmdNameInternalRep --
+ *
+ *	Frees the resources associated with a cmdName object's internal
+ *	representation.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Decrements the ref count of any cached ResolvedCmdName structure
+ *	pointed to by the cmdName's internal representation. If this is the
+ *	last use of the ResolvedCmdName, it is freed. This in turn decrements
+ *	the ref count of the Command structure pointed to by the
+ *	ResolvedSymbol, which may free the Command structure.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+FreeCmdNameInternalRep(
+    register Tcl_Obj *objPtr)	/* CmdName object with internal
+				 * representation to free. */
+{
+    register ResolvedCmdName *resPtr = objPtr->internalRep.twoPtrValue.ptr1;
+
+    if (resPtr != NULL) {
+	/*
+	 * Decrement the reference count of the ResolvedCmdName structure. If
+	 * there are no more uses, free the ResolvedCmdName structure.
+	 */
+
+	if (resPtr->refCount-- == 1) {
+	    /*
+	     * Now free the cached command, unless it is still in its hash
+	     * table or if there are other references to it from other cmdName
+	     * objects.
+	     */
+
+	    Command *cmdPtr = resPtr->cmdPtr;
+
+	    TclCleanupCommandMacro(cmdPtr);
+	    ckfree(resPtr);
+	}
+    }
+    objPtr->typePtr = NULL;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * DupCmdNameInternalRep --
+ *
+ *	Initialize the internal representation of an cmdName Tcl_Obj to a copy
+ *	of the internal representation of an existing cmdName object.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	"copyPtr"s internal rep is set to point to the ResolvedCmdName
+ *	structure corresponding to "srcPtr"s internal rep. Increments the ref
+ *	count of the ResolvedCmdName structure pointed to by the cmdName's
+ *	internal representation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+DupCmdNameInternalRep(
+    Tcl_Obj *srcPtr,		/* Object with internal rep to copy. */
+    register Tcl_Obj *copyPtr)	/* Object with internal rep to set. */
+{
+    register ResolvedCmdName *resPtr = srcPtr->internalRep.twoPtrValue.ptr1;
+
+    copyPtr->internalRep.twoPtrValue.ptr1 = resPtr;
+    copyPtr->internalRep.twoPtrValue.ptr2 = NULL;
+    if (resPtr != NULL) {
+	resPtr->refCount++;
+    }
+    copyPtr->typePtr = &tclCmdNameType;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * SetCmdNameFromAny --
+ *
+ *	Generate an cmdName internal form for the Tcl object "objPtr".
+ *
+ * Results:
+ *	The return value is a standard Tcl result. The conversion always
+ *	succeeds and TCL_OK is returned.
+ *
+ * Side effects:
+ *	A pointer to a ResolvedCmdName structure that holds a cached pointer
+ *	to the command with a name that matches objPtr's string rep is stored
+ *	as objPtr's internal representation. This ResolvedCmdName pointer will
+ *	be NULL if no matching command was found. The ref count of the cached
+ *	Command's structure (if any) is also incremented.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+SetCmdNameFromAny(
+    Tcl_Interp *interp,		/* Used for error reporting if not NULL. */
+    register Tcl_Obj *objPtr)	/* The object to convert. */
+{
+    Interp *iPtr = (Interp *) interp;
+    const char *name;
+    register Command *cmdPtr;
+    Namespace *currNsPtr;
+    register ResolvedCmdName *resPtr;
+
+    if (interp == NULL) {
+	return TCL_ERROR;
+    }
+
+    /*
+     * Find the Command structure, if any, that describes the command called
+     * "name". Build a ResolvedCmdName that holds a cached pointer to this
+     * Command, and bump the reference count in the referenced Command
+     * structure. A Command structure will not be deleted as long as it is
+     * referenced from a CmdName object.
+     */
+
+    name = TclGetString(objPtr);
+    cmdPtr = (Command *)
+	    Tcl_FindCommand(interp, name, /*ns*/ NULL, /*flags*/ 0);
+
+    /*
+     * Free the old internalRep before setting the new one. Do this after
+     * getting the string rep to allow the conversion code (in particular,
+     * Tcl_GetStringFromObj) to use that old internalRep.
+     */
+
+    if (cmdPtr) {
+	cmdPtr->refCount++;
+	resPtr = objPtr->internalRep.twoPtrValue.ptr1;
+	if ((objPtr->typePtr == &tclCmdNameType)
+		&& resPtr && (resPtr->refCount == 1)) {
+	    /*
+	     * Reuse the old ResolvedCmdName struct instead of freeing it
+	     */
+
+	    Command *oldCmdPtr = resPtr->cmdPtr;
+
+	    if (--oldCmdPtr->refCount == 0) {
+		TclCleanupCommandMacro(oldCmdPtr);
+	    }
+	} else {
+	    TclFreeIntRep(objPtr);
+	    resPtr = ckalloc(sizeof(ResolvedCmdName));
+	    resPtr->refCount = 1;
+	    objPtr->internalRep.twoPtrValue.ptr1 = resPtr;
+	    objPtr->internalRep.twoPtrValue.ptr2 = NULL;
+	    objPtr->typePtr = &tclCmdNameType;
+	}
+	resPtr->cmdPtr = cmdPtr;
+	resPtr->cmdEpoch = cmdPtr->cmdEpoch;
+	if ((*name++ == ':') && (*name == ':')) {
+	    /*
+	     * The name is fully qualified: set the referring namespace to
+	     * NULL.
+	     */
+
+	    resPtr->refNsPtr = NULL;
+	} else {
+	    /*
+	     * Get the current namespace.
+	     */
+
+	    currNsPtr = iPtr->varFramePtr->nsPtr;
+
+	    resPtr->refNsPtr = currNsPtr;
+	    resPtr->refNsId = currNsPtr->nsId;
+	    resPtr->refNsCmdEpoch = currNsPtr->cmdRefEpoch;
+	}
+    } else {
+	TclFreeIntRep(objPtr);
+	objPtr->internalRep.twoPtrValue.ptr1 = NULL;
+	objPtr->internalRep.twoPtrValue.ptr2 = NULL;
+	objPtr->typePtr = &tclCmdNameType;
+    }
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_RepresentationCmd --
+ *
+ *	Implementation of the "tcl::unsupported::representation" command.
+ *
+ * Results:
+ *	Reports the current representation (Tcl_Obj type) of its argument.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_RepresentationCmd(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const objv[])
+{
+    char ptrBuffer[2*TCL_INTEGER_SPACE+6];
+    Tcl_Obj *descObj;
+
+    if (objc != 2) {
+	Tcl_WrongNumArgs(interp, 1, objv, "value");
+	return TCL_ERROR;
+    }
+
+    /*
+     * Value is a bignum with a refcount of 14, object pointer at 0x12345678,
+     * internal representation 0x45671234:0x98765432, string representation
+     * "1872361827361287"
+     */
+
+    sprintf(ptrBuffer, "%p", (void *) objv[1]);
+    descObj = Tcl_ObjPrintf("value is a %s with a refcount of %d,"
+            " object pointer at %s",
+            objv[1]->typePtr ? objv[1]->typePtr->name : "pure string",
+	    objv[1]->refCount, ptrBuffer);
+
+    if (objv[1]->typePtr) {
+	sprintf(ptrBuffer, "%p:%p",
+		(void *) objv[1]->internalRep.twoPtrValue.ptr1,
+		(void *) objv[1]->internalRep.twoPtrValue.ptr2);
+	Tcl_AppendPrintfToObj(descObj, ", internal representation %s",
+		ptrBuffer);
+    }
+
+    if (objv[1]->bytes) {
+        Tcl_AppendToObj(descObj, ", string representation \"", -1);
+	Tcl_AppendLimitedToObj(descObj, objv[1]->bytes, objv[1]->length,
+                16, "...");
+	Tcl_AppendToObj(descObj, "\"", -1);
+    } else {
+	Tcl_AppendToObj(descObj, ", no string representation", -1);
+    }
+
+    Tcl_SetObjResult(interp, descObj);
+    return TCL_OK;
+}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/generic/tclOptimize.c b/generic/tclOptimize.c
new file mode 100644
index 0000000..827d89d
--- /dev/null
+++ b/generic/tclOptimize.c
@@ -0,0 +1,444 @@
+/*
+ * tclOptimize.c --
+ *
+ *	This file contains the bytecode optimizer.
+ *
+ * Copyright (c) 2013 by Donal Fellows.
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#include "tclInt.h"
+#include "tclCompile.h"
+#include <assert.h>
+
+/*
+ * Forward declarations.
+ */
+
+static void		AdvanceJumps(CompileEnv *envPtr);
+static void		ConvertZeroEffectToNOP(CompileEnv *envPtr);
+static void		LocateTargetAddresses(CompileEnv *envPtr,
+			    Tcl_HashTable *tablePtr);
+static void		TrimUnreachable(CompileEnv *envPtr);
+
+/*
+ * Helper macros.
+ */
+
+#define DefineTargetAddress(tablePtr, address) \
+    ((void) Tcl_CreateHashEntry((tablePtr), (void *) (address), &isNew))
+#define IsTargetAddress(tablePtr, address) \
+    (Tcl_FindHashEntry((tablePtr), (void *) (address)) != NULL)
+#define AddrLength(address) \
+    (tclInstructionTable[*(unsigned char *)(address)].numBytes)
+#define InstLength(instruction) \
+    (tclInstructionTable[(unsigned char)(instruction)].numBytes)
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * LocateTargetAddresses --
+ *
+ *	Populate a hash table with places that we need to be careful around
+ *	because they're the targets of various kinds of jumps and other
+ *	non-local behavior.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+static void
+LocateTargetAddresses(
+    CompileEnv *envPtr,
+    Tcl_HashTable *tablePtr)
+{
+    unsigned char *currentInstPtr, *targetInstPtr;
+    int isNew, i;
+    Tcl_HashEntry *hPtr;
+    Tcl_HashSearch hSearch;
+
+    Tcl_InitHashTable(tablePtr, TCL_ONE_WORD_KEYS);
+
+    /*
+     * The starts of commands represent target addresses.
+     */
+
+    for (i=0 ; i<envPtr->numCommands ; i++) {
+	DefineTargetAddress(tablePtr,
+		envPtr->codeStart + envPtr->cmdMapPtr[i].codeOffset);
+    }
+
+    /*
+     * Find places where we should be careful about replacing instructions
+     * because they are the targets of various types of jumps.
+     */
+
+    for (currentInstPtr = envPtr->codeStart ;
+	    currentInstPtr < envPtr->codeNext ;
+	    currentInstPtr += AddrLength(currentInstPtr)) {
+	switch (*currentInstPtr) {
+	case INST_JUMP1:
+	case INST_JUMP_TRUE1:
+	case INST_JUMP_FALSE1:
+	    targetInstPtr = currentInstPtr+TclGetInt1AtPtr(currentInstPtr+1);
+	    goto storeTarget;
+	case INST_JUMP4:
+	case INST_JUMP_TRUE4:
+	case INST_JUMP_FALSE4:
+	case INST_START_CMD:
+	    targetInstPtr = currentInstPtr+TclGetInt4AtPtr(currentInstPtr+1);
+	    goto storeTarget;
+	case INST_BEGIN_CATCH4:
+	    targetInstPtr = envPtr->codeStart + envPtr->exceptArrayPtr[
+		    TclGetUInt4AtPtr(currentInstPtr+1)].codeOffset;
+	storeTarget:
+	    DefineTargetAddress(tablePtr, targetInstPtr);
+	    break;
+	case INST_JUMP_TABLE:
+	    hPtr = Tcl_FirstHashEntry(
+		    &JUMPTABLEINFO(envPtr, currentInstPtr+1)->hashTable,
+		    &hSearch);
+	    for (; hPtr ; hPtr = Tcl_NextHashEntry(&hSearch)) {
+		targetInstPtr = currentInstPtr +
+			PTR2INT(Tcl_GetHashValue(hPtr));
+		DefineTargetAddress(tablePtr, targetInstPtr);
+	    }
+	    break;
+	case INST_RETURN_CODE_BRANCH:
+	    for (i=TCL_ERROR ; i<TCL_CONTINUE+1 ; i++) {
+		DefineTargetAddress(tablePtr, currentInstPtr + 2*i - 1);
+	    }
+	    break;
+	}
+    }
+
+    /*
+     * Add a marker *after* the last bytecode instruction. WARNING: points to
+     * one past the end!
+     */
+
+    DefineTargetAddress(tablePtr, currentInstPtr);
+
+    /*
+     * Enter in the targets of exception ranges.
+     */
+
+    for (i=0 ; i<envPtr->exceptArrayNext ; i++) {
+	ExceptionRange *rangePtr = &envPtr->exceptArrayPtr[i];
+
+	if (rangePtr->type == CATCH_EXCEPTION_RANGE) {
+	    targetInstPtr = envPtr->codeStart + rangePtr->catchOffset;
+	    DefineTargetAddress(tablePtr, targetInstPtr);
+	} else {
+	    targetInstPtr = envPtr->codeStart + rangePtr->breakOffset;
+	    DefineTargetAddress(tablePtr, targetInstPtr);
+	    if (rangePtr->continueOffset >= 0) {
+		targetInstPtr = envPtr->codeStart + rangePtr->continueOffset;
+		DefineTargetAddress(tablePtr, targetInstPtr);
+	    }
+	}
+    }
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * TrimUnreachable --
+ *
+ *	Converts code that provably can't be executed into NOPs and reduces
+ *	the overall reported length of the bytecode where that is possible.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+static void
+TrimUnreachable(
+    CompileEnv *envPtr)
+{
+    unsigned char *currentInstPtr;
+    Tcl_HashTable targets;
+
+    LocateTargetAddresses(envPtr, &targets);
+
+    for (currentInstPtr = envPtr->codeStart ;
+	    currentInstPtr < envPtr->codeNext-1 ;
+	    currentInstPtr += AddrLength(currentInstPtr)) {
+	int clear = 0;
+
+	if (*currentInstPtr != INST_DONE) {
+	    continue;
+	}
+
+	while (!IsTargetAddress(&targets, currentInstPtr + 1 + clear)) {
+	    clear += AddrLength(currentInstPtr + 1 + clear);
+	}
+	if (currentInstPtr + 1 + clear == envPtr->codeNext) {
+	    envPtr->codeNext -= clear;
+	} else {
+	    while (clear --> 0) {
+		*(currentInstPtr + 1 + clear) = INST_NOP;
+	    }
+	}
+    }
+
+    Tcl_DeleteHashTable(&targets);
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * ConvertZeroEffectToNOP --
+ *
+ *	Replace PUSH/POP sequences (when non-hazardous) with NOPs. Also
+ *	replace PUSH empty/STR_CONCAT and TRY_CVT_NUMERIC (when followed by an
+ *	operation that guarantees the check for arithmeticity) and eliminate
+ *	LNOT when we can invert the following JUMP condition.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+static void
+ConvertZeroEffectToNOP(
+    CompileEnv *envPtr)
+{
+    unsigned char *currentInstPtr;
+    int size;
+    Tcl_HashTable targets;
+
+    LocateTargetAddresses(envPtr, &targets);
+    for (currentInstPtr = envPtr->codeStart ;
+	    currentInstPtr < envPtr->codeNext ; currentInstPtr += size) {
+	int blank = 0, i, nextInst;
+
+	size = AddrLength(currentInstPtr);
+	while ((currentInstPtr + size < envPtr->codeNext)
+		&& *(currentInstPtr+size) == INST_NOP) {
+	    if (IsTargetAddress(&targets, currentInstPtr + size)) {
+		break;
+	    }
+	    size += InstLength(INST_NOP);
+	}
+	if (IsTargetAddress(&targets, currentInstPtr + size)) {
+	    continue;
+	}
+	nextInst = *(currentInstPtr + size);
+	switch (*currentInstPtr) {
+	case INST_PUSH1:
+	    if (nextInst == INST_POP) {
+		blank = size + InstLength(nextInst);
+	    } else if (nextInst == INST_STR_CONCAT1
+		    && TclGetUInt1AtPtr(currentInstPtr + size + 1) == 2) {
+		Tcl_Obj *litPtr = TclFetchLiteral(envPtr,
+			TclGetUInt1AtPtr(currentInstPtr + 1));
+		int numBytes;
+
+		(void) Tcl_GetStringFromObj(litPtr, &numBytes);
+		if (numBytes == 0) {
+		    blank = size + InstLength(nextInst);
+		}
+	    }
+	    break;
+	case INST_PUSH4:
+	    if (nextInst == INST_POP) {
+		blank = size + 1;
+	    } else if (nextInst == INST_STR_CONCAT1
+		    && TclGetUInt1AtPtr(currentInstPtr + size + 1) == 2) {
+		Tcl_Obj *litPtr = TclFetchLiteral(envPtr,
+			TclGetUInt4AtPtr(currentInstPtr + 1));
+		int numBytes;
+
+		(void) Tcl_GetStringFromObj(litPtr, &numBytes);
+		if (numBytes == 0) {
+		    blank = size + InstLength(nextInst);
+		}
+	    }
+	    break;
+
+	case INST_LNOT:
+	    switch (nextInst) {
+	    case INST_JUMP_TRUE1:
+		blank = size;
+		*(currentInstPtr + size) = INST_JUMP_FALSE1;
+		break;
+	    case INST_JUMP_FALSE1:
+		blank = size;
+		*(currentInstPtr + size) = INST_JUMP_TRUE1;
+		break;
+	    case INST_JUMP_TRUE4:
+		blank = size;
+		*(currentInstPtr + size) = INST_JUMP_FALSE4;
+		break;
+	    case INST_JUMP_FALSE4:
+		blank = size;
+		*(currentInstPtr + size) = INST_JUMP_TRUE4;
+		break;
+	    }
+	    break;
+
+	case INST_TRY_CVT_TO_NUMERIC:
+	    switch (nextInst) {
+	    case INST_JUMP_TRUE1:
+	    case INST_JUMP_TRUE4:
+	    case INST_JUMP_FALSE1:
+	    case INST_JUMP_FALSE4:
+	    case INST_INCR_SCALAR1:
+	    case INST_INCR_ARRAY1:
+	    case INST_INCR_ARRAY_STK:
+	    case INST_INCR_SCALAR_STK:
+	    case INST_INCR_STK:
+	    case INST_LOR:
+	    case INST_LAND:
+	    case INST_EQ:
+	    case INST_NEQ:
+	    case INST_LT:
+	    case INST_LE:
+	    case INST_GT:
+	    case INST_GE:
+	    case INST_MOD:
+	    case INST_LSHIFT:
+	    case INST_RSHIFT:
+	    case INST_BITOR:
+	    case INST_BITXOR:
+	    case INST_BITAND:
+	    case INST_EXPON:
+	    case INST_ADD:
+	    case INST_SUB:
+	    case INST_DIV:
+	    case INST_MULT:
+	    case INST_LNOT:
+	    case INST_BITNOT:
+	    case INST_UMINUS:
+	    case INST_UPLUS:
+	    case INST_TRY_CVT_TO_NUMERIC:
+		blank = size;
+		break;
+	    }
+	    break;
+	}
+
+	if (blank > 0) {
+	    for (i=0 ; i<blank ; i++) {
+		*(currentInstPtr + i) = INST_NOP;
+	    }
+	    size = blank;
+	}
+    }
+    Tcl_DeleteHashTable(&targets);
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * AdvanceJumps --
+ *
+ *	Advance jumps past NOPs and chained JUMPs. After this runs, the only
+ *	JUMPs that jump to a NOP or a JUMP will be length-1 ones that run out
+ *	of room in their opcode to be targeted to where they really belong.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+static void
+AdvanceJumps(
+    CompileEnv *envPtr)
+{
+    unsigned char *currentInstPtr;
+    Tcl_HashTable jumps;
+
+    for (currentInstPtr = envPtr->codeStart ;
+	    currentInstPtr < envPtr->codeNext-1 ;
+	    currentInstPtr += AddrLength(currentInstPtr)) {
+	int offset, delta, isNew;
+
+	switch (*currentInstPtr) {
+	case INST_JUMP1:
+	case INST_JUMP_TRUE1:
+	case INST_JUMP_FALSE1:
+	    offset = TclGetInt1AtPtr(currentInstPtr + 1);
+	    Tcl_InitHashTable(&jumps, TCL_ONE_WORD_KEYS);
+	    for (delta=0 ; offset+delta != 0 ;) {
+		if (offset + delta < -128 || offset + delta > 127) {
+		    break;
+		}
+		Tcl_CreateHashEntry(&jumps, INT2PTR(offset), &isNew);
+		if (!isNew) {
+		    offset = TclGetInt1AtPtr(currentInstPtr + 1);
+		    break;
+		}
+		offset += delta;
+		switch (*(currentInstPtr + offset)) {
+		case INST_NOP:
+		    delta = InstLength(INST_NOP);
+		    continue;
+		case INST_JUMP1:
+		    delta = TclGetInt1AtPtr(currentInstPtr + offset + 1);
+		    continue;
+		case INST_JUMP4:
+		    delta = TclGetInt4AtPtr(currentInstPtr + offset + 1);
+		    continue;
+		}
+		break;
+	    }
+	    Tcl_DeleteHashTable(&jumps);
+	    TclStoreInt1AtPtr(offset, currentInstPtr + 1);
+	    continue;
+
+	case INST_JUMP4:
+	case INST_JUMP_TRUE4:
+	case INST_JUMP_FALSE4:
+	    Tcl_InitHashTable(&jumps, TCL_ONE_WORD_KEYS);
+	    Tcl_CreateHashEntry(&jumps, INT2PTR(0), &isNew);
+	    for (offset = TclGetInt4AtPtr(currentInstPtr + 1); offset!=0 ;) {
+		Tcl_CreateHashEntry(&jumps, INT2PTR(offset), &isNew);
+		if (!isNew) {
+		    offset = TclGetInt4AtPtr(currentInstPtr + 1);
+		    break;
+		}
+		switch (*(currentInstPtr + offset)) {
+		case INST_NOP:
+		    offset += InstLength(INST_NOP);
+		    continue;
+		case INST_JUMP1:
+		    offset += TclGetInt1AtPtr(currentInstPtr + offset + 1);
+		    continue;
+		case INST_JUMP4:
+		    offset += TclGetInt4AtPtr(currentInstPtr + offset + 1);
+		    continue;
+		}
+		break;
+	    }
+	    Tcl_DeleteHashTable(&jumps);
+	    TclStoreInt4AtPtr(offset, currentInstPtr + 1);
+	    continue;
+	}
+    }
+}
+
+/*
+ * ----------------------------------------------------------------------
+ *
+ * TclOptimizeBytecode --
+ *
+ *	A very simple peephole optimizer for bytecode.
+ *
+ * ----------------------------------------------------------------------
+ */
+
+void
+TclOptimizeBytecode(
+    void *envPtr)
+{
+    ConvertZeroEffectToNOP(envPtr);
+    AdvanceJumps(envPtr);
+    TrimUnreachable(envPtr);
+}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * tab-width: 8
+ * End:
+ */
diff --git a/generic/tclPanic.c b/generic/tclPanic.c
new file mode 100644
index 0000000..b032449
--- /dev/null
+++ b/generic/tclPanic.c
@@ -0,0 +1,170 @@
+/*
+ * tclPanic.c --
+ *
+ *	Source code for the "Tcl_Panic" library procedure for Tcl; individual
+ *	applications will probably call Tcl_SetPanicProc() to set an
+ *	application-specific panic procedure.
+ *
+ * Copyright (c) 1988-1993 The Regents of the University of California.
+ * Copyright (c) 1994 Sun Microsystems, Inc.
+ * Copyright (c) 1998-1999 by Scriptics Corporation.
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#include "tclInt.h"
+#if defined(_WIN32) || defined(__CYGWIN__)
+    MODULE_SCOPE TCL_NORETURN void tclWinDebugPanic(const char *format, ...);
+#endif
+
+/*
+ * The panicProc variable contains a pointer to an application specific panic
+ * procedure.
+ */
+
+#if defined(__CYGWIN__)
+static TCL_NORETURN Tcl_PanicProc *panicProc = tclWinDebugPanic;
+#else
+static TCL_NORETURN1 Tcl_PanicProc *panicProc = NULL;
+#endif
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_SetPanicProc --
+ *
+ *	Replace the default panic behavior with the specified function.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Sets the panicProc variable.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_SetPanicProc(
+    TCL_NORETURN1 Tcl_PanicProc *proc)
+{
+#if defined(_WIN32)
+    /* tclWinDebugPanic only installs if there is no panicProc yet. */
+    if ((proc != tclWinDebugPanic) || (panicProc == NULL))
+#elif defined(__CYGWIN__)
+    if (proc == NULL)
+	panicProc = tclWinDebugPanic;
+    else
+#endif
+    panicProc = proc;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_PanicVA --
+ *
+ *	Print an error message and kill the process.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The process dies, entering the debugger if possible.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_PanicVA(
+    const char *format,		/* Format string, suitable for passing to
+				 * fprintf. */
+    va_list argList)		/* Variable argument list. */
+{
+    char *arg1, *arg2, *arg3;	/* Additional arguments (variable in number)
+				 * to pass to fprintf. */
+    char *arg4, *arg5, *arg6, *arg7, *arg8;
+
+    arg1 = va_arg(argList, char *);
+    arg2 = va_arg(argList, char *);
+    arg3 = va_arg(argList, char *);
+    arg4 = va_arg(argList, char *);
+    arg5 = va_arg(argList, char *);
+    arg6 = va_arg(argList, char *);
+    arg7 = va_arg(argList, char *);
+    arg8 = va_arg(argList, char *);
+
+    if (panicProc != NULL) {
+	panicProc(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8);
+#ifdef _WIN32
+    } else if (IsDebuggerPresent()) {
+	tclWinDebugPanic(format, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8);
+#endif
+    } else {
+	fprintf(stderr, format, arg1, arg2, arg3, arg4, arg5, arg6, arg7,
+		arg8);
+	fprintf(stderr, "\n");
+	fflush(stderr);
+#if defined(_WIN32) || defined(__CYGWIN__)
+#   if defined(__GNUC__)
+	__builtin_trap();
+#   elif defined(_WIN64)
+	__debugbreak();
+#   elif defined(_MSC_VER)
+	_asm {int 3}
+#   else
+	DebugBreak();
+#   endif
+#endif
+#if defined(_WIN32)
+	ExitProcess(1);
+#else
+	abort();
+#endif
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_Panic --
+ *
+ *	Print an error message and kill the process.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The process dies, entering the debugger if possible.
+ *
+ *----------------------------------------------------------------------
+ */
+
+/* ARGSUSED */
+
+/*
+ * The following comment is here so that Coverity's static analizer knows that
+ * a Tcl_Panic() call can never return and avoids lots of false positives.
+ */
+
+/* coverity[+kill] */
+void
+Tcl_Panic(
+    const char *format,
+    ...)
+{
+    va_list argList;
+
+    va_start(argList, format);
+    Tcl_PanicVA(format, argList);
+    va_end (argList);
+}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tclParse.c b/generic/tclParse.c
new file mode 100644
index 0000000..95abc45
--- /dev/null
+++ b/generic/tclParse.c
@@ -0,0 +1,2534 @@
+/*
+ * tclParse.c --
+ *
+ *	This file contains functions that parse Tcl scripts. They do so in a
+ *	general-purpose fashion that can be used for many different purposes,
+ *	including compilation, direct execution, code analysis, etc.
+ *
+ * Copyright (c) 1997 Sun Microsystems, Inc.
+ * Copyright (c) 1998-2000 Ajuba Solutions.
+ * Contributions from Don Porter, NIST, 2002. (not subject to US copyright)
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#include "tclInt.h"
+#include "tclParse.h"
+#include <assert.h>
+
+/*
+ * The following table provides parsing information about each possible 8-bit
+ * character. The table is designed to be referenced with either signed or
+ * unsigned characters, so it has 384 entries. The first 128 entries
+ * correspond to negative character values, the next 256 correspond to
+ * positive character values. The last 128 entries are identical to the first
+ * 128. The table is always indexed with a 128-byte offset (the 128th entry
+ * corresponds to a character value of 0).
+ *
+ * The macro CHAR_TYPE is used to index into the table and return information
+ * about its character argument. The following return values are defined.
+ *
+ * TYPE_NORMAL -	All characters that don't have special significance to
+ *			the Tcl parser.
+ * TYPE_SPACE -		The character is a whitespace character other than
+ *			newline.
+ * TYPE_COMMAND_END -	Character is newline or semicolon.
+ * TYPE_SUBS -		Character begins a substitution or has other special
+ *			meaning in ParseTokens: backslash, dollar sign, or
+ *			open bracket.
+ * TYPE_QUOTE -		Character is a double quote.
+ * TYPE_CLOSE_PAREN -	Character is a right parenthesis.
+ * TYPE_CLOSE_BRACK -	Character is a right square bracket.
+ * TYPE_BRACE -		Character is a curly brace (either left or right).
+ */
+
+const char tclCharTypeTable[] = {
+    /*
+     * Negative character values, from -128 to -1:
+     */
+
+    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
+    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
+    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
+    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
+    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
+    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
+    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
+    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
+    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
+    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
+    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
+    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
+    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
+    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
+    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
+    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
+    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
+    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
+    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
+    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
+    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
+    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
+    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
+    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
+    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
+    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
+    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
+    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
+    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
+    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
+    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
+    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
+
+    /*
+     * Positive character values, from 0-127:
+     */
+
+    TYPE_SUBS,        TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
+    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
+    TYPE_NORMAL,      TYPE_SPACE,       TYPE_COMMAND_END, TYPE_SPACE,
+    TYPE_SPACE,       TYPE_SPACE,       TYPE_NORMAL,      TYPE_NORMAL,
+    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
+    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
+    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
+    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
+    TYPE_SPACE,       TYPE_NORMAL,      TYPE_QUOTE,       TYPE_NORMAL,
+    TYPE_SUBS,        TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
+    TYPE_NORMAL,      TYPE_CLOSE_PAREN, TYPE_NORMAL,      TYPE_NORMAL,
+    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
+    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
+    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
+    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_COMMAND_END,
+    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
+    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
+    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
+    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
+    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
+    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
+    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
+    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_SUBS,
+    TYPE_SUBS,        TYPE_CLOSE_BRACK, TYPE_NORMAL,      TYPE_NORMAL,
+    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
+    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
+    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
+    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
+    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
+    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
+    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_BRACE,
+    TYPE_NORMAL,      TYPE_BRACE,       TYPE_NORMAL,      TYPE_NORMAL,
+
+    /*
+     * Large unsigned character values, from 128-255:
+     */
+
+    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
+    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
+    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
+    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
+    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
+    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
+    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
+    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
+    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
+    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
+    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
+    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
+    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
+    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
+    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
+    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
+    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
+    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
+    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
+    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
+    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
+    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
+    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
+    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
+    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
+    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
+    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
+    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
+    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
+    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
+    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
+    TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,      TYPE_NORMAL,
+};
+
+/*
+ * Prototypes for local functions defined in this file:
+ */
+
+static inline int	CommandComplete(const char *script, int numBytes);
+static int		ParseComment(const char *src, int numBytes,
+			    Tcl_Parse *parsePtr);
+static int		ParseTokens(const char *src, int numBytes, int mask,
+			    int flags, Tcl_Parse *parsePtr);
+static int		ParseWhiteSpace(const char *src, int numBytes,
+			    int *incompletePtr, char *typePtr);
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclParseInit --
+ *
+ *	Initialize the fields of a Tcl_Parse struct.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The Tcl_Parse struct pointed to by parsePtr gets initialized.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclParseInit(
+    Tcl_Interp *interp,		/* Interpreter to use for error reporting */
+    const char *start,		/* Start of string to be parsed. */
+    int numBytes,		/* Total number of bytes in string. If < 0,
+				 * the script consists of all bytes up to the
+				 * first null character. */
+    Tcl_Parse *parsePtr)	/* Points to struct to initialize */
+{
+    parsePtr->numWords = 0;
+    parsePtr->tokenPtr = parsePtr->staticTokens;
+    parsePtr->numTokens = 0;
+    parsePtr->tokensAvailable = NUM_STATIC_TOKENS;
+    parsePtr->string = start;
+    parsePtr->end = start + numBytes;
+    parsePtr->term = parsePtr->end;
+    parsePtr->interp = interp;
+    parsePtr->incomplete = 0;
+    parsePtr->errorType = TCL_PARSE_SUCCESS;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_ParseCommand --
+ *
+ *	Given a string, this function parses the first Tcl command in the
+ *	string and returns information about the structure of the command.
+ *
+ * Results:
+ *	The return value is TCL_OK if the command was parsed successfully and
+ *	TCL_ERROR otherwise. If an error occurs and interp isn't NULL then an
+ *	error message is left in its result. On a successful return, parsePtr
+ *	is filled in with information about the command that was parsed.
+ *
+ * Side effects:
+ *	If there is insufficient space in parsePtr to hold all the information
+ *	about the command, then additional space is malloc-ed. If the function
+ *	returns TCL_OK then the caller must eventually invoke Tcl_FreeParse to
+ *	release any additional space that was allocated.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_ParseCommand(
+    Tcl_Interp *interp,		/* Interpreter to use for error reporting; if
+				 * NULL, then no error message is provided. */
+    const char *start,		/* First character of string containing one or
+				 * more Tcl commands. */
+    register int numBytes,	/* Total number of bytes in string. If < 0,
+				 * the script consists of all bytes up to the
+				 * first null character. */
+    int nested,			/* Non-zero means this is a nested command:
+				 * close bracket should be considered a
+				 * command terminator. If zero, then close
+				 * bracket has no special meaning. */
+    register Tcl_Parse *parsePtr)
+				/* Structure to fill in with information about
+				 * the parsed command; any previous
+				 * information in the structure is ignored. */
+{
+    register const char *src;	/* Points to current character in the
+				 * command. */
+    char type;			/* Result returned by CHAR_TYPE(*src). */
+    Tcl_Token *tokenPtr;	/* Pointer to token being filled in. */
+    int wordIndex;		/* Index of word token for current word. */
+    int terminators;		/* CHAR_TYPE bits that indicate the end of a
+				 * command. */
+    const char *termPtr;	/* Set by Tcl_ParseBraces/QuotedString to
+				 * point to char after terminating one. */
+    int scanned;
+
+    if ((start == NULL) && (numBytes != 0)) {
+	if (interp != NULL) {
+	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		    "can't parse a NULL pointer", -1));
+	}
+	return TCL_ERROR;
+    }
+    if (numBytes < 0) {
+	numBytes = strlen(start);
+    }
+    TclParseInit(interp, start, numBytes, parsePtr);
+    parsePtr->commentStart = NULL;
+    parsePtr->commentSize = 0;
+    parsePtr->commandStart = NULL;
+    parsePtr->commandSize = 0;
+    if (nested != 0) {
+	terminators = TYPE_COMMAND_END | TYPE_CLOSE_BRACK;
+    } else {
+	terminators = TYPE_COMMAND_END;
+    }
+
+    /*
+     * Parse any leading space and comments before the first word of the
+     * command.
+     */
+
+    scanned = ParseComment(start, numBytes, parsePtr);
+    src = (start + scanned);
+    numBytes -= scanned;
+    if (numBytes == 0) {
+	if (nested) {
+	    parsePtr->incomplete = nested;
+	}
+    }
+
+    /*
+     * The following loop parses the words of the command, one word in each
+     * iteration through the loop.
+     */
+
+    parsePtr->commandStart = src;
+    while (1) {
+	int expandWord = 0;
+
+	/*
+	 * Create the token for the word.
+	 */
+
+	TclGrowParseTokenArray(parsePtr, 1);
+	wordIndex = parsePtr->numTokens;
+	tokenPtr = &parsePtr->tokenPtr[wordIndex];
+	tokenPtr->type = TCL_TOKEN_WORD;
+
+	/*
+	 * Skip white space before the word. Also skip a backslash-newline
+	 * sequence: it should be treated just like white space.
+	 */
+
+	scanned = ParseWhiteSpace(src,numBytes, &parsePtr->incomplete, &type);
+	src += scanned;
+	numBytes -= scanned;
+	if (numBytes == 0) {
+	    parsePtr->term = src;
+	    break;
+	}
+	if ((type & terminators) != 0) {
+	    parsePtr->term = src;
+	    src++;
+	    break;
+	}
+	tokenPtr->start = src;
+	parsePtr->numTokens++;
+	parsePtr->numWords++;
+
+	/*
+	 * At this point the word can have one of four forms: something
+	 * enclosed in quotes, something enclosed in braces, and expanding
+	 * word, or an unquoted word (anything else).
+	 */
+
+    parseWord:
+	if (*src == '"') {
+	    if (Tcl_ParseQuotedString(interp, src, numBytes, parsePtr, 1,
+		    &termPtr) != TCL_OK) {
+		goto error;
+	    }
+	    src = termPtr;
+	    numBytes = parsePtr->end - src;
+	} else if (*src == '{') {
+	    int expIdx = wordIndex + 1;
+	    Tcl_Token *expPtr;
+
+	    if (Tcl_ParseBraces(interp, src, numBytes, parsePtr, 1,
+		    &termPtr) != TCL_OK) {
+		goto error;
+	    }
+	    src = termPtr;
+	    numBytes = parsePtr->end - src;
+
+	    /*
+	     * Check whether the braces contained the word expansion prefix
+	     * {*}
+	     */
+
+	    expPtr = &parsePtr->tokenPtr[expIdx];
+	    if ((0 == expandWord)
+		    /* Haven't seen prefix already */
+		    && (1 == parsePtr->numTokens - expIdx)
+		    /* Only one token */
+		    && (((1 == (size_t) expPtr->size)
+			    /* Same length as prefix */
+			    && (expPtr->start[0] == '*')))
+			    /* Is the prefix */
+		    && (numBytes > 0) && (0 == ParseWhiteSpace(termPtr,
+			    numBytes, &parsePtr->incomplete, &type))
+		    && (type != TYPE_COMMAND_END)
+		    /* Non-whitespace follows */) {
+		expandWord = 1;
+		parsePtr->numTokens--;
+		goto parseWord;
+	    }
+	} else {
+	    /*
+	     * This is an unquoted word. Call ParseTokens and let it do all of
+	     * the work.
+	     */
+
+	    if (ParseTokens(src, numBytes, TYPE_SPACE|terminators,
+		    TCL_SUBST_ALL, parsePtr) != TCL_OK) {
+		goto error;
+	    }
+	    src = parsePtr->term;
+	    numBytes = parsePtr->end - src;
+	}
+
+	/*
+	 * Finish filling in the token for the word and check for the special
+	 * case of a word consisting of a single range of literal text.
+	 */
+
+	tokenPtr = &parsePtr->tokenPtr[wordIndex];
+	tokenPtr->size = src - tokenPtr->start;
+	tokenPtr->numComponents = parsePtr->numTokens - (wordIndex + 1);
+	if (expandWord) {
+	    int i, isLiteral = 1;
+
+	    /*
+	     * When a command includes a word that is an expanded literal; for
+	     * example, {*}{1 2 3}, the parser performs that expansion
+	     * immediately, generating several TCL_TOKEN_SIMPLE_WORDs instead
+	     * of a single TCL_TOKEN_EXPAND_WORD that the Tcl_ParseCommand()
+	     * caller might have to expand. This notably makes it simpler for
+	     * those callers that wish to track line endings, such as those
+	     * that implement key parts of TIP 280.
+	     *
+	     * First check whether the thing to be expanded is a literal,
+	     * in the sense of being composed entirely of TCL_TOKEN_TEXT
+	     * tokens.
+	     */
+
+	    for (i = 1; i <= tokenPtr->numComponents; i++) {
+		if (tokenPtr[i].type != TCL_TOKEN_TEXT) {
+		    isLiteral = 0;
+		    break;
+		}
+	    }
+
+	    if (isLiteral) {
+		int elemCount = 0, code = TCL_OK, literal = 1;
+		const char *nextElem, *listEnd, *elemStart;
+
+		/*
+		 * The word to be expanded is a literal, so determine the
+		 * boundaries of the literal string to be treated as a list
+		 * and expanded. That literal string starts at
+		 * tokenPtr[1].start, and includes all bytes up to, but not
+		 * including (tokenPtr[tokenPtr->numComponents].start +
+		 * tokenPtr[tokenPtr->numComponents].size)
+		 */
+
+		listEnd = (tokenPtr[tokenPtr->numComponents].start +
+			tokenPtr[tokenPtr->numComponents].size);
+		nextElem = tokenPtr[1].start;
+
+		/*
+		 * Step through the literal string, parsing and counting list
+		 * elements.
+		 */
+
+		while (nextElem < listEnd) {
+		    int size;
+
+		    code = TclFindElement(NULL, nextElem, listEnd - nextElem,
+			    &elemStart, &nextElem, &size, &literal);
+		    if ((code != TCL_OK) || !literal) {
+			break;
+		    }
+		    if (elemStart < listEnd) {
+			elemCount++;
+		    }
+		}
+
+		if ((code != TCL_OK) || !literal) {
+		    /*
+		     * Some list element could not be parsed, or is not
+		     * present as a literal substring of the script.  The
+		     * compiler cannot handle list elements that get generated
+		     * by a call to TclCopyAndCollapse(). Defer  the
+		     * handling of  this to  compile/eval time, where  code is
+		     * already  in place to  report the  "attempt to  expand a
+		     * non-list" error or expand lists that require
+		     * substitution.
+		     */
+
+		    tokenPtr->type = TCL_TOKEN_EXPAND_WORD;
+		} else if (elemCount == 0) {
+		    /*
+		     * We are expanding a literal empty list. This means that
+		     * the expanding word completely disappears, leaving no
+		     * word generated this pass through the loop. Adjust
+		     * accounting appropriately.
+		     */
+
+		    parsePtr->numWords--;
+		    parsePtr->numTokens = wordIndex;
+		} else {
+		    /*
+		     * Recalculate the number of Tcl_Tokens needed to store
+		     * tokens representing the expanded list.
+		     */
+
+		    const char *listStart;
+		    int growthNeeded = wordIndex + 2*elemCount
+			    - parsePtr->numTokens;
+
+		    parsePtr->numWords += elemCount - 1;
+		    if (growthNeeded > 0) {
+			TclGrowParseTokenArray(parsePtr, growthNeeded);
+			tokenPtr = &parsePtr->tokenPtr[wordIndex];
+		    }
+		    parsePtr->numTokens = wordIndex + 2*elemCount;
+
+		    /*
+		     * Generate a TCL_TOKEN_SIMPLE_WORD token sequence for
+		     * each element of the literal list we are expanding in
+		     * place. Take care with the start and size fields of each
+		     * token so they point to the right literal characters in
+		     * the original script to represent the right expanded
+		     * word value.
+		     */
+
+		    listStart = nextElem = tokenPtr[1].start;
+		    while (nextElem < listEnd) {
+			int quoted;
+
+			tokenPtr->type = TCL_TOKEN_SIMPLE_WORD;
+			tokenPtr->numComponents = 1;
+
+			tokenPtr++;
+			tokenPtr->type = TCL_TOKEN_TEXT;
+			tokenPtr->numComponents = 0;
+			TclFindElement(NULL, nextElem, listEnd - nextElem,
+				&(tokenPtr->start), &nextElem,
+				&(tokenPtr->size), NULL);
+
+			quoted = (tokenPtr->start[-1] == '{'
+				|| tokenPtr->start[-1] == '"')
+				&& tokenPtr->start > listStart;
+			tokenPtr[-1].start = tokenPtr->start - quoted;
+			tokenPtr[-1].size = tokenPtr->start + tokenPtr->size
+				- tokenPtr[-1].start + quoted;
+
+			tokenPtr++;
+		    }
+		}
+	    } else {
+		/*
+		 * The word to be expanded is not a literal, so defer
+		 * expansion to compile/eval time by marking with a
+		 * TCL_TOKEN_EXPAND_WORD token.
+		 */
+
+		tokenPtr->type = TCL_TOKEN_EXPAND_WORD;
+	    }
+	} else if ((tokenPtr->numComponents == 1)
+		&& (tokenPtr[1].type == TCL_TOKEN_TEXT)) {
+	    tokenPtr->type = TCL_TOKEN_SIMPLE_WORD;
+	}
+
+	/*
+	 * Do two additional checks: (a) make sure we're really at the end of
+	 * a word (there might have been garbage left after a quoted or braced
+	 * word), and (b) check for the end of the command.
+	 */
+
+	scanned = ParseWhiteSpace(src,numBytes, &parsePtr->incomplete, &type);
+	if (scanned) {
+	    src += scanned;
+	    numBytes -= scanned;
+	    continue;
+	}
+
+	if (numBytes == 0) {
+	    parsePtr->term = src;
+	    break;
+	}
+	if ((type & terminators) != 0) {
+	    parsePtr->term = src;
+	    src++;
+	    break;
+	}
+	if (src[-1] == '"') {
+	    if (interp != NULL) {
+		Tcl_SetObjResult(interp, Tcl_NewStringObj(
+			"extra characters after close-quote", -1));
+	    }
+	    parsePtr->errorType = TCL_PARSE_QUOTE_EXTRA;
+	} else {
+	    if (interp != NULL) {
+		Tcl_SetObjResult(interp, Tcl_NewStringObj(
+			"extra characters after close-brace", -1));
+	    }
+	    parsePtr->errorType = TCL_PARSE_BRACE_EXTRA;
+	}
+	parsePtr->term = src;
+	goto error;
+    }
+
+    parsePtr->commandSize = src - parsePtr->commandStart;
+    return TCL_OK;
+
+  error:
+    Tcl_FreeParse(parsePtr);
+    parsePtr->commandSize = parsePtr->end - parsePtr->commandStart;
+    return TCL_ERROR;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclIsSpaceProc --
+ *
+ *	Report whether byte is in the set of whitespace characters used by
+ *	Tcl to separate words in scripts or elements in lists.
+ *
+ * Results:
+ *	Returns 1, if byte is in the set, 0 otherwise.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclIsSpaceProc(
+    char byte)
+{
+    return CHAR_TYPE(byte) & (TYPE_SPACE) || byte == '\n';
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclIsBareword--
+ *
+ *	Report whether byte is one that can be part of a "bareword".
+ *	This concept is named in expression parsing, where it determines
+ *	what can be a legal function name, but is the same definition used
+ *	in determining what variable names can be parsed as variable
+ *	substitutions without the benefit of enclosing braces.  The set of
+ *	ASCII chars that are accepted are the numeric chars ('0'-'9'),
+ *	the alphabetic chars ('a'-'z', 'A'-'Z')	and underscore ('_').
+ *
+ * Results:
+ *	Returns 1, if byte is in the accepted set of chars, 0 otherwise.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclIsBareword(
+    char byte)
+{
+    if (byte < '0' || byte > 'z') {
+	return 0;
+    }
+    if (byte <= '9' || byte >= 'a') {
+	return 1;
+    }
+    if (byte == '_') {
+	return 1;
+    }
+    if (byte < 'A' || byte > 'Z') {
+	return 0;
+    }
+    return 1;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ParseWhiteSpace --
+ *
+ *	Scans up to numBytes bytes starting at src, consuming white space
+ *	between words as defined by Tcl's parsing rules.
+ *
+ * Results:
+ *	Returns the number of bytes recognized as white space. Records at
+ *	parsePtr, information about the parse. Records at typePtr the
+ *	character type of the non-whitespace character that terminated the
+ *	scan.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+ParseWhiteSpace(
+    const char *src,		/* First character to parse. */
+    register int numBytes,	/* Max number of bytes to scan. */
+    int *incompletePtr,		/* Set this boolean memory to true if parsing
+				 * indicates an incomplete command. */
+    char *typePtr)		/* Points to location to store character type
+				 * of character that ends run of whitespace */
+{
+    register char type = TYPE_NORMAL;
+    register const char *p = src;
+
+    while (1) {
+	while (numBytes && ((type = CHAR_TYPE(*p)) & TYPE_SPACE)) {
+	    numBytes--;
+	    p++;
+	}
+	if (numBytes && (type & TYPE_SUBS)) {
+	    if (*p != '\\') {
+		break;
+	    }
+	    if (--numBytes == 0) {
+		break;
+	    }
+	    if (p[1] != '\n') {
+		break;
+	    }
+	    p += 2;
+	    if (--numBytes == 0) {
+		*incompletePtr = 1;
+		break;
+	    }
+	    continue;
+	}
+	break;
+    }
+    *typePtr = type;
+    return (p - src);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclParseAllWhiteSpace --
+ *
+ *	Scans up to numBytes bytes starting at src, consuming all white space
+ *	including the command-terminating newline characters.
+ *
+ * Results:
+ *	Returns the number of bytes recognized as white space.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclParseAllWhiteSpace(
+    const char *src,		/* First character to parse. */
+    int numBytes)		/* Max number of byes to scan */
+{
+    int dummy;
+    char type;
+    const char *p = src;
+
+    do {
+	int scanned = ParseWhiteSpace(p, numBytes, &dummy, &type);
+
+	p += scanned;
+	numBytes -= scanned;
+    } while (numBytes && (*p == '\n') && (p++, --numBytes));
+    return (p-src);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclParseHex --
+ *
+ *	Scans a hexadecimal number as a Tcl_UniChar value (e.g., for parsing
+ *	\x and \u escape sequences). At most numBytes bytes are scanned.
+ *
+ * Results:
+ *	The numeric value is stored in *resultPtr. Returns the number of bytes
+ *	consumed.
+ *
+ * Notes:
+ *	Relies on the following properties of the ASCII character set, with
+ *	which UTF-8 is compatible:
+ *
+ *	The digits '0' .. '9' and the letters 'A' .. 'Z' and 'a' .. 'z' occupy
+ *	consecutive code points, and '0' < 'A' < 'a'.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclParseHex(
+    const char *src,		/* First character to parse. */
+    int numBytes,		/* Max number of byes to scan */
+    int *resultPtr)	/* Points to storage provided by caller where
+				 * the character resulting from the
+				 * conversion is to be written. */
+{
+    int result = 0;
+    register const char *p = src;
+
+    while (numBytes--) {
+	unsigned char digit = UCHAR(*p);
+
+	if (!isxdigit(digit) || (result > 0x10fff)) {
+	    break;
+	}
+
+	p++;
+	result <<= 4;
+
+	if (digit >= 'a') {
+	    result |= (10 + digit - 'a');
+	} else if (digit >= 'A') {
+	    result |= (10 + digit - 'A');
+	} else {
+	    result |= (digit - '0');
+	}
+    }
+
+    *resultPtr = result;
+    return (p - src);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclParseBackslash --
+ *
+ *	Scans up to numBytes bytes starting at src, consuming a backslash
+ *	sequence as defined by Tcl's parsing rules.
+ *
+ * Results:
+ *	Records at readPtr the number of bytes making up the backslash
+ *	sequence. Records at dst the UTF-8 encoded equivalent of that
+ *	backslash sequence. Returns the number of bytes written to dst, at
+ *	most TCL_UTF_MAX. Either readPtr or dst may be NULL, if the results
+ *	are not needed, but the return value is the same either way.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclParseBackslash(
+    const char *src,		/* Points to the backslash character of a a
+				 * backslash sequence. */
+    int numBytes,		/* Max number of bytes to scan. */
+    int *readPtr,		/* NULL, or points to storage where the number
+				 * of bytes scanned should be written. */
+    char *dst)			/* NULL, or points to buffer where the UTF-8
+				 * encoding of the backslash sequence is to be
+				 * written. At most TCL_UTF_MAX bytes will be
+				 * written there. */
+{
+    register const char *p = src+1;
+    Tcl_UniChar unichar;
+    int result;
+    int count;
+    char buf[TCL_UTF_MAX];
+
+    if (numBytes == 0) {
+	if (readPtr != NULL) {
+	    *readPtr = 0;
+	}
+	return 0;
+    }
+
+    if (dst == NULL) {
+	dst = buf;
+    }
+
+    if (numBytes == 1) {
+	/*
+	 * Can only scan the backslash, so return it.
+	 */
+
+	result = '\\';
+	count = 1;
+	goto done;
+    }
+
+    count = 2;
+    switch (*p) {
+	/*
+	 * Note: in the conversions below, use absolute values (e.g., 0xa)
+	 * rather than symbolic values (e.g. \n) that get converted by the
+	 * compiler. It's possible that compilers on some platforms will do
+	 * the symbolic conversions differently, which could result in
+	 * non-portable Tcl scripts.
+	 */
+
+    case 'a':
+	result = 0x7;
+	break;
+    case 'b':
+	result = 0x8;
+	break;
+    case 'f':
+	result = 0xc;
+	break;
+    case 'n':
+	result = 0xa;
+	break;
+    case 'r':
+	result = 0xd;
+	break;
+    case 't':
+	result = 0x9;
+	break;
+    case 'v':
+	result = 0xb;
+	break;
+    case 'x':
+	count += TclParseHex(p+1, (numBytes > 3) ? 2 : numBytes-2, &result);
+	if (count == 2) {
+	    /*
+	     * No hexadigits -> This is just "x".
+	     */
+
+	    result = 'x';
+	} else {
+	    /*
+	     * Keep only the last byte (2 hex digits).
+	     */
+	    result = (unsigned char) result;
+	}
+	break;
+    case 'u':
+	count += TclParseHex(p+1, (numBytes > 5) ? 4 : numBytes-2, &result);
+	if (count == 2) {
+	    /*
+	     * No hexadigits -> This is just "u".
+	     */
+	    result = 'u';
+	}
+	break;
+    case 'U':
+	count += TclParseHex(p+1, (numBytes > 9) ? 8 : numBytes-2, &result);
+	if (count == 2) {
+	    /*
+	     * No hexadigits -> This is just "U".
+	     */
+	    result = 'U';
+	}
+	break;
+    case '\n':
+	count--;
+	do {
+	    p++;
+	    count++;
+	} while ((count < numBytes) && ((*p == ' ') || (*p == '\t')));
+	result = ' ';
+	break;
+    case 0:
+	result = '\\';
+	count = 1;
+	break;
+    default:
+	/*
+	 * Check for an octal number \oo?o?
+	 */
+
+	if (isdigit(UCHAR(*p)) && (UCHAR(*p) < '8')) {	/* INTL: digit */
+	    result = *p - '0';
+	    p++;
+	    if ((numBytes == 2) || !isdigit(UCHAR(*p))	/* INTL: digit */
+		    || (UCHAR(*p) >= '8')) {
+		break;
+	    }
+	    count = 3;
+	    result = (result << 3) + (*p - '0');
+	    p++;
+	    if ((numBytes == 3) || !isdigit(UCHAR(*p))	/* INTL: digit */
+		    || (UCHAR(*p) >= '8') || (result >= 0x20)) {
+		break;
+	    }
+	    count = 4;
+	    result = UCHAR((result << 3) + (*p - '0'));
+	    break;
+	}
+
+	/*
+	 * We have to convert here in case the user has put a backslash in
+	 * front of a multi-byte utf-8 character. While this means nothing
+	 * special, we shouldn't break up a correct utf-8 character. [Bug
+	 * #217987] test subst-3.2
+	 */
+
+	if (Tcl_UtfCharComplete(p, numBytes - 1)) {
+	    count = Tcl_UtfToUniChar(p, &unichar) + 1;	/* +1 for '\' */
+	} else {
+	    char utfBytes[TCL_UTF_MAX];
+
+	    memcpy(utfBytes, p, (size_t) (numBytes - 1));
+	    utfBytes[numBytes - 1] = '\0';
+	    count = Tcl_UtfToUniChar(utfBytes, &unichar) + 1;
+	}
+	result = unichar;
+	break;
+    }
+
+  done:
+    if (readPtr != NULL) {
+	*readPtr = count;
+    }
+    return Tcl_UniCharToUtf(result, dst);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ParseComment --
+ *
+ *	Scans up to numBytes bytes starting at src, consuming a Tcl comment as
+ *	defined by Tcl's parsing rules.
+ *
+ * Results:
+ *	Records in parsePtr information about the parse. Returns the number of
+ *	bytes consumed.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+ParseComment(
+    const char *src,		/* First character to parse. */
+    register int numBytes,	/* Max number of bytes to scan. */
+    Tcl_Parse *parsePtr)	/* Information about parse in progress.
+				 * Updated if parsing indicates an incomplete
+				 * command. */
+{
+    register const char *p = src;
+
+    while (numBytes) {
+	char type;
+	int scanned;
+
+	do {
+	    scanned = ParseWhiteSpace(p, numBytes,
+		    &parsePtr->incomplete, &type);
+	    p += scanned;
+	    numBytes -= scanned;
+	} while (numBytes && (*p == '\n') && (p++,numBytes--));
+
+	if ((numBytes == 0) || (*p != '#')) {
+	    break;
+	}
+	if (parsePtr->commentStart == NULL) {
+	    parsePtr->commentStart = p;
+	}
+
+	while (numBytes) {
+	    if (*p == '\\') {
+		scanned = ParseWhiteSpace(p, numBytes, &parsePtr->incomplete,
+			&type);
+		if (scanned) {
+		    p += scanned;
+		    numBytes -= scanned;
+		} else {
+		    /*
+		     * General backslash substitution in comments isn't part
+		     * of the formal spec, but test parse-15.47 and history
+		     * indicate that it has been the de facto rule. Don't
+		     * change it now.
+		     */
+
+		    TclParseBackslash(p, numBytes, &scanned, NULL);
+		    p += scanned;
+		    numBytes -= scanned;
+		}
+	    } else {
+		p++;
+		numBytes--;
+		if (p[-1] == '\n') {
+		    break;
+		}
+	    }
+	}
+	parsePtr->commentSize = p - parsePtr->commentStart;
+    }
+    return (p - src);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ParseTokens --
+ *
+ *	This function forms the heart of the Tcl parser. It parses one or more
+ *	tokens from a string, up to a termination point specified by the
+ *	caller. This function is used to parse unquoted command words (those
+ *	not in quotes or braces), words in quotes, and array indices for
+ *	variables. No more than numBytes bytes will be scanned.
+ *
+ * Results:
+ *	Tokens are added to parsePtr and parsePtr->term is filled in with the
+ *	address of the character that terminated the parse (the first one
+ *	whose CHAR_TYPE matched mask or the character at parsePtr->end). The
+ *	return value is TCL_OK if the parse completed successfully and
+ *	TCL_ERROR otherwise. If a parse error occurs and parsePtr->interp is
+ *	not NULL, then an error message is left in the interpreter's result.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+ParseTokens(
+    register const char *src,	/* First character to parse. */
+    register int numBytes,	/* Max number of bytes to scan. */
+    int mask,			/* Specifies when to stop parsing. The parse
+				 * stops at the first unquoted character whose
+				 * CHAR_TYPE contains any of the bits in
+				 * mask. */
+    int flags,			/* OR-ed bits indicating what substitutions to
+				 * perform: TCL_SUBST_COMMANDS,
+				 * TCL_SUBST_VARIABLES, and
+				 * TCL_SUBST_BACKSLASHES */
+    Tcl_Parse *parsePtr)	/* Information about parse in progress.
+				 * Updated with additional tokens and
+				 * termination information. */
+{
+    char type;
+    int originalTokens;
+    int noSubstCmds = !(flags & TCL_SUBST_COMMANDS);
+    int noSubstVars = !(flags & TCL_SUBST_VARIABLES);
+    int noSubstBS = !(flags & TCL_SUBST_BACKSLASHES);
+    Tcl_Token *tokenPtr;
+
+    /*
+     * Each iteration through the following loop adds one token of type
+     * TCL_TOKEN_TEXT, TCL_TOKEN_BS, TCL_TOKEN_COMMAND, or TCL_TOKEN_VARIABLE
+     * to parsePtr. For TCL_TOKEN_VARIABLE tokens, additional tokens are added
+     * for the parsed variable name.
+     */
+
+    originalTokens = parsePtr->numTokens;
+    while (numBytes && !((type = CHAR_TYPE(*src)) & mask)) {
+	TclGrowParseTokenArray(parsePtr, 1);
+	tokenPtr = &parsePtr->tokenPtr[parsePtr->numTokens];
+	tokenPtr->start = src;
+	tokenPtr->numComponents = 0;
+
+	if ((type & TYPE_SUBS) == 0) {
+	    /*
+	     * This is a simple range of characters. Scan to find the end of
+	     * the range.
+	     */
+
+	    while ((++src, --numBytes)
+		    && !(CHAR_TYPE(*src) & (mask | TYPE_SUBS))) {
+		/* empty loop */
+	    }
+	    tokenPtr->type = TCL_TOKEN_TEXT;
+	    tokenPtr->size = src - tokenPtr->start;
+	    parsePtr->numTokens++;
+	} else if (*src == '$') {
+	    int varToken;
+
+	    if (noSubstVars) {
+		tokenPtr->type = TCL_TOKEN_TEXT;
+		tokenPtr->size = 1;
+		parsePtr->numTokens++;
+		src++;
+		numBytes--;
+		continue;
+	    }
+
+	    /*
+	     * This is a variable reference. Call Tcl_ParseVarName to do all
+	     * the dirty work of parsing the name.
+	     */
+
+	    varToken = parsePtr->numTokens;
+	    if (Tcl_ParseVarName(parsePtr->interp, src, numBytes, parsePtr,
+		    1) != TCL_OK) {
+		return TCL_ERROR;
+	    }
+	    src += parsePtr->tokenPtr[varToken].size;
+	    numBytes -= parsePtr->tokenPtr[varToken].size;
+	} else if (*src == '[') {
+	    Tcl_Parse *nestedPtr;
+
+	    if (noSubstCmds) {
+		tokenPtr->type = TCL_TOKEN_TEXT;
+		tokenPtr->size = 1;
+		parsePtr->numTokens++;
+		src++;
+		numBytes--;
+		continue;
+	    }
+
+	    /*
+	     * Command substitution. Call Tcl_ParseCommand recursively (and
+	     * repeatedly) to parse the nested command(s), then throw away the
+	     * parse information.
+	     */
+
+	    src++;
+	    numBytes--;
+	    nestedPtr = TclStackAlloc(parsePtr->interp, sizeof(Tcl_Parse));
+	    while (1) {
+		if (Tcl_ParseCommand(parsePtr->interp, src, numBytes, 1,
+			nestedPtr) != TCL_OK) {
+		    parsePtr->errorType = nestedPtr->errorType;
+		    parsePtr->term = nestedPtr->term;
+		    parsePtr->incomplete = nestedPtr->incomplete;
+		    TclStackFree(parsePtr->interp, nestedPtr);
+		    return TCL_ERROR;
+		}
+		src = nestedPtr->commandStart + nestedPtr->commandSize;
+		numBytes = parsePtr->end - src;
+		Tcl_FreeParse(nestedPtr);
+
+		/*
+		 * Check for the closing ']' that ends the command
+		 * substitution. It must have been the last character of the
+		 * parsed command.
+		 */
+
+		if ((nestedPtr->term < parsePtr->end)
+			&& (*(nestedPtr->term) == ']')
+			&& !(nestedPtr->incomplete)) {
+		    break;
+		}
+		if (numBytes == 0) {
+		    if (parsePtr->interp != NULL) {
+			Tcl_SetObjResult(parsePtr->interp, Tcl_NewStringObj(
+				"missing close-bracket", -1));
+		    }
+		    parsePtr->errorType = TCL_PARSE_MISSING_BRACKET;
+		    parsePtr->term = tokenPtr->start;
+		    parsePtr->incomplete = 1;
+		    TclStackFree(parsePtr->interp, nestedPtr);
+		    return TCL_ERROR;
+		}
+	    }
+	    TclStackFree(parsePtr->interp, nestedPtr);
+	    tokenPtr->type = TCL_TOKEN_COMMAND;
+	    tokenPtr->size = src - tokenPtr->start;
+	    parsePtr->numTokens++;
+	} else if (*src == '\\') {
+	    if (noSubstBS) {
+		tokenPtr->type = TCL_TOKEN_TEXT;
+		tokenPtr->size = 1;
+		parsePtr->numTokens++;
+		src++;
+		numBytes--;
+		continue;
+	    }
+
+	    /*
+	     * Backslash substitution.
+	     */
+
+	    TclParseBackslash(src, numBytes, &tokenPtr->size, NULL);
+
+	    if (tokenPtr->size == 1) {
+		/*
+		 * Just a backslash, due to end of string.
+		 */
+
+		tokenPtr->type = TCL_TOKEN_TEXT;
+		parsePtr->numTokens++;
+		src++;
+		numBytes--;
+		continue;
+	    }
+
+	    if (src[1] == '\n') {
+		if (numBytes == 2) {
+		    parsePtr->incomplete = 1;
+		}
+
+		/*
+		 * Note: backslash-newline is special in that it is treated
+		 * the same as a space character would be. This means that it
+		 * could terminate the token.
+		 */
+
+		if (mask & TYPE_SPACE) {
+		    if (parsePtr->numTokens == originalTokens) {
+			goto finishToken;
+		    }
+		    break;
+		}
+	    }
+
+	    tokenPtr->type = TCL_TOKEN_BS;
+	    parsePtr->numTokens++;
+	    src += tokenPtr->size;
+	    numBytes -= tokenPtr->size;
+	} else if (*src == 0) {
+	    tokenPtr->type = TCL_TOKEN_TEXT;
+	    tokenPtr->size = 1;
+	    parsePtr->numTokens++;
+	    src++;
+	    numBytes--;
+	} else {
+	    Tcl_Panic("ParseTokens encountered unknown character");
+	}
+    }
+    if (parsePtr->numTokens == originalTokens) {
+	/*
+	 * There was nothing in this range of text. Add an empty token for the
+	 * empty range, so that there is always at least one token added.
+	 */
+
+	TclGrowParseTokenArray(parsePtr, 1);
+	tokenPtr = &parsePtr->tokenPtr[parsePtr->numTokens];
+	tokenPtr->start = src;
+	tokenPtr->numComponents = 0;
+
+    finishToken:
+	tokenPtr->type = TCL_TOKEN_TEXT;
+	tokenPtr->size = 0;
+	parsePtr->numTokens++;
+    }
+    parsePtr->term = src;
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_FreeParse --
+ *
+ *	This function is invoked to free any dynamic storage that may have
+ *	been allocated by a previous call to Tcl_ParseCommand.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	If there is any dynamically allocated memory in *parsePtr, it is
+ *	freed.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_FreeParse(
+    Tcl_Parse *parsePtr)	/* Structure that was filled in by a previous
+				 * call to Tcl_ParseCommand. */
+{
+    if (parsePtr->tokenPtr != parsePtr->staticTokens) {
+	ckfree(parsePtr->tokenPtr);
+	parsePtr->tokenPtr = parsePtr->staticTokens;
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_ParseVarName --
+ *
+ *	Given a string starting with a $ sign, parse off a variable name and
+ *	return information about the parse. No more than numBytes bytes will
+ *	be scanned.
+ *
+ * Results:
+ *	The return value is TCL_OK if the command was parsed successfully and
+ *	TCL_ERROR otherwise. If an error occurs and interp isn't NULL then an
+ *	error message is left in its result. On a successful return, tokenPtr
+ *	and numTokens fields of parsePtr are filled in with information about
+ *	the variable name that was parsed. The "size" field of the first new
+ *	token gives the total number of bytes in the variable name. Other
+ *	fields in parsePtr are undefined.
+ *
+ * Side effects:
+ *	If there is insufficient space in parsePtr to hold all the information
+ *	about the command, then additional space is malloc-ed. If the function
+ *	returns TCL_OK then the caller must eventually invoke Tcl_FreeParse to
+ *	release any additional space that was allocated.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_ParseVarName(
+    Tcl_Interp *interp,		/* Interpreter to use for error reporting; if
+				 * NULL, then no error message is provided. */
+    const char *start,		/* Start of variable substitution string.
+				 * First character must be "$". */
+    register int numBytes,	/* Total number of bytes in string. If < 0,
+				 * the string consists of all bytes up to the
+				 * first null character. */
+    Tcl_Parse *parsePtr,	/* Structure to fill in with information about
+				 * the variable name. */
+    int append)			/* Non-zero means append tokens to existing
+				 * information in parsePtr; zero means ignore
+				 * existing tokens in parsePtr and
+				 * reinitialize it. */
+{
+    Tcl_Token *tokenPtr;
+    register const char *src;
+    int varIndex;
+    unsigned array;
+
+    if ((numBytes == 0) || (start == NULL)) {
+	return TCL_ERROR;
+    }
+    if (numBytes < 0) {
+	numBytes = strlen(start);
+    }
+
+    if (!append) {
+	TclParseInit(interp, start, numBytes, parsePtr);
+    }
+
+    /*
+     * Generate one token for the variable, an additional token for the name,
+     * plus any number of additional tokens for the index, if there is one.
+     */
+
+    src = start;
+    TclGrowParseTokenArray(parsePtr, 2);
+    tokenPtr = &parsePtr->tokenPtr[parsePtr->numTokens];
+    tokenPtr->type = TCL_TOKEN_VARIABLE;
+    tokenPtr->start = src;
+    varIndex = parsePtr->numTokens;
+    parsePtr->numTokens++;
+    tokenPtr++;
+    src++;
+    numBytes--;
+    if (numBytes == 0) {
+	goto justADollarSign;
+    }
+    tokenPtr->type = TCL_TOKEN_TEXT;
+    tokenPtr->start = src;
+    tokenPtr->numComponents = 0;
+
+    /*
+     * The name of the variable can have three forms:
+     * 1. The $ sign is followed by an open curly brace. Then the variable
+     *	  name is everything up to the next close curly brace, and the
+     *	  variable is a scalar variable.
+     * 2. The $ sign is not followed by an open curly brace. Then the variable
+     *	  name is everything up to the next character that isn't a letter,
+     *	  digit, or underscore. :: sequences are also considered part of the
+     *	  variable name, in order to support namespaces. If the following
+     *	  character is an open parenthesis, then the information between
+     *	  parentheses is the array element name.
+     * 3. The $ sign is followed by something that isn't a letter, digit, or
+     *	  underscore: in this case, there is no variable name and the token is
+     *	  just "$".
+     */
+
+    if (*src == '{') {
+	src++;
+	numBytes--;
+	tokenPtr->type = TCL_TOKEN_TEXT;
+	tokenPtr->start = src;
+	tokenPtr->numComponents = 0;
+
+	while (numBytes && (*src != '}')) {
+	    numBytes--;
+	    src++;
+	}
+	if (numBytes == 0) {
+	    if (parsePtr->interp != NULL) {
+		Tcl_SetObjResult(parsePtr->interp, Tcl_NewStringObj(
+			"missing close-brace for variable name", -1));
+	    }
+	    parsePtr->errorType = TCL_PARSE_MISSING_VAR_BRACE;
+	    parsePtr->term = tokenPtr->start-1;
+	    parsePtr->incomplete = 1;
+	    goto error;
+	}
+	tokenPtr->size = src - tokenPtr->start;
+	tokenPtr[-1].size = src - tokenPtr[-1].start;
+	parsePtr->numTokens++;
+	src++;
+    } else {
+	tokenPtr->type = TCL_TOKEN_TEXT;
+	tokenPtr->start = src;
+	tokenPtr->numComponents = 0;
+
+	while (numBytes) {
+	    if (TclIsBareword(*src)) {
+		src += 1;
+		numBytes -= 1;
+		continue;
+	    }
+	    if ((src[0] == ':') && (numBytes != 1) && (src[1] == ':')) {
+		src += 2;
+		numBytes -= 2;
+		while (numBytes && (*src == ':')) {
+		    src++;
+		    numBytes--;
+		}
+		continue;
+	    }
+	    break;
+	}
+
+	/*
+	 * Support for empty array names here.
+	 */
+
+	array = (numBytes && (*src == '('));
+	tokenPtr->size = src - tokenPtr->start;
+	if ((tokenPtr->size == 0) && !array) {
+	    goto justADollarSign;
+	}
+	parsePtr->numTokens++;
+	if (array) {
+	    /*
+	     * This is a reference to an array element. Call ParseTokens
+	     * recursively to parse the element name, since it could contain
+	     * any number of substitutions.
+	     */
+
+	    if (TCL_OK != ParseTokens(src+1, numBytes-1, TYPE_CLOSE_PAREN,
+		    TCL_SUBST_ALL, parsePtr)) {
+		goto error;
+	    }
+	    if ((parsePtr->term == src+numBytes) || (*parsePtr->term != ')')){
+		if (parsePtr->interp != NULL) {
+		    Tcl_SetObjResult(parsePtr->interp, Tcl_NewStringObj(
+			    "missing )", -1));
+		}
+		parsePtr->errorType = TCL_PARSE_MISSING_PAREN;
+		parsePtr->term = src;
+		parsePtr->incomplete = 1;
+		goto error;
+	    }
+	    src = parsePtr->term + 1;
+	}
+    }
+    tokenPtr = &parsePtr->tokenPtr[varIndex];
+    tokenPtr->size = src - tokenPtr->start;
+    tokenPtr->numComponents = parsePtr->numTokens - (varIndex + 1);
+    return TCL_OK;
+
+    /*
+     * The dollar sign isn't followed by a variable name. Replace the
+     * TCL_TOKEN_VARIABLE token with a TCL_TOKEN_TEXT token for the dollar
+     * sign.
+     */
+
+  justADollarSign:
+    tokenPtr = &parsePtr->tokenPtr[varIndex];
+    tokenPtr->type = TCL_TOKEN_TEXT;
+    tokenPtr->size = 1;
+    tokenPtr->numComponents = 0;
+    return TCL_OK;
+
+  error:
+    Tcl_FreeParse(parsePtr);
+    return TCL_ERROR;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_ParseVar --
+ *
+ *	Given a string starting with a $ sign, parse off a variable name and
+ *	return its value.
+ *
+ * Results:
+ *	The return value is the contents of the variable given by the leading
+ *	characters of string. If termPtr isn't NULL, *termPtr gets filled in
+ *	with the address of the character just after the last one in the
+ *	variable specifier. If the variable doesn't exist, then the return
+ *	value is NULL and an error message will be left in interp's result.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+const char *
+Tcl_ParseVar(
+    Tcl_Interp *interp,		/* Context for looking up variable. */
+    register const char *start,	/* Start of variable substitution. First
+				 * character must be "$". */
+    const char **termPtr)	/* If non-NULL, points to word to fill in with
+				 * character just after last one in the
+				 * variable specifier. */
+{
+    register Tcl_Obj *objPtr;
+    int code;
+    Tcl_Parse *parsePtr = TclStackAlloc(interp, sizeof(Tcl_Parse));
+
+    if (Tcl_ParseVarName(interp, start, -1, parsePtr, 0) != TCL_OK) {
+	TclStackFree(interp, parsePtr);
+	return NULL;
+    }
+
+    if (termPtr != NULL) {
+	*termPtr = start + parsePtr->tokenPtr->size;
+    }
+    if (parsePtr->numTokens == 1) {
+	/*
+	 * There isn't a variable name after all: the $ is just a $.
+	 */
+
+	TclStackFree(interp, parsePtr);
+	return "$";
+    }
+
+    code = TclSubstTokens(interp, parsePtr->tokenPtr, parsePtr->numTokens,
+	    NULL, 1, NULL, NULL);
+    Tcl_FreeParse(parsePtr);
+    TclStackFree(interp, parsePtr);
+    if (code != TCL_OK) {
+	return NULL;
+    }
+    objPtr = Tcl_GetObjResult(interp);
+
+    /*
+     * At this point we should have an object containing the value of a
+     * variable. Just return the string from that object.
+     *
+     * Since TclSubstTokens above returned TCL_OK, we know that objPtr
+     * is shared.  It is in both the interp result and the value of the
+     * variable.  Returning the string relies on that to be true.
+     */
+
+    assert( Tcl_IsShared(objPtr) );
+
+    Tcl_ResetResult(interp);
+    return TclGetString(objPtr);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_ParseBraces --
+ *
+ *	Given a string in braces such as a Tcl command argument or a string
+ *	value in a Tcl expression, this function parses the string and returns
+ *	information about the parse. No more than numBytes bytes will be
+ *	scanned.
+ *
+ * Results:
+ *	The return value is TCL_OK if the string was parsed successfully and
+ *	TCL_ERROR otherwise. If an error occurs and interp isn't NULL then an
+ *	error message is left in its result. On a successful return, tokenPtr
+ *	and numTokens fields of parsePtr are filled in with information about
+ *	the string that was parsed. Other fields in parsePtr are undefined.
+ *	termPtr is set to point to the character just after the last one in
+ *	the braced string.
+ *
+ * Side effects:
+ *	If there is insufficient space in parsePtr to hold all the information
+ *	about the command, then additional space is malloc-ed. If the function
+ *	returns TCL_OK then the caller must eventually invoke Tcl_FreeParse to
+ *	release any additional space that was allocated.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_ParseBraces(
+    Tcl_Interp *interp,		/* Interpreter to use for error reporting; if
+				 * NULL, then no error message is provided. */
+    const char *start,		/* Start of string enclosed in braces. The
+				 * first character must be {'. */
+    register int numBytes,	/* Total number of bytes in string. If < 0,
+				 * the string consists of all bytes up to the
+				 * first null character. */
+    register Tcl_Parse *parsePtr,
+				/* Structure to fill in with information about
+				 * the string. */
+    int append,			/* Non-zero means append tokens to existing
+				 * information in parsePtr; zero means ignore
+				 * existing tokens in parsePtr and
+				 * reinitialize it. */
+    const char **termPtr)	/* If non-NULL, points to word in which to
+				 * store a pointer to the character just after
+				 * the terminating '}' if the parse was
+				 * successful. */
+{
+    Tcl_Token *tokenPtr;
+    register const char *src;
+    int startIndex, level, length;
+
+    if ((numBytes == 0) || (start == NULL)) {
+	return TCL_ERROR;
+    }
+    if (numBytes < 0) {
+	numBytes = strlen(start);
+    }
+
+    if (!append) {
+	TclParseInit(interp, start, numBytes, parsePtr);
+    }
+
+    src = start;
+    startIndex = parsePtr->numTokens;
+
+    TclGrowParseTokenArray(parsePtr, 1);
+    tokenPtr = &parsePtr->tokenPtr[startIndex];
+    tokenPtr->type = TCL_TOKEN_TEXT;
+    tokenPtr->start = src+1;
+    tokenPtr->numComponents = 0;
+    level = 1;
+    while (1) {
+	while (++src, --numBytes) {
+	    if (CHAR_TYPE(*src) != TYPE_NORMAL) {
+		break;
+	    }
+	}
+	if (numBytes == 0) {
+	    goto missingBraceError;
+	}
+
+	switch (*src) {
+	case '{':
+	    level++;
+	    break;
+	case '}':
+	    if (--level == 0) {
+		/*
+		 * Decide if we need to finish emitting a partially-finished
+		 * token. There are 3 cases:
+		 *     {abc \newline xyz} or {xyz}
+		 *		- finish emitting "xyz" token
+		 *     {abc \newline}
+		 *		- don't emit token after \newline
+		 *     {}	- finish emitting zero-sized token
+		 *
+		 * The last case ensures that there is a token (even if empty)
+		 * that describes the braced string.
+		 */
+
+		if ((src != tokenPtr->start)
+			|| (parsePtr->numTokens == startIndex)) {
+		    tokenPtr->size = (src - tokenPtr->start);
+		    parsePtr->numTokens++;
+		}
+		if (termPtr != NULL) {
+		    *termPtr = src+1;
+		}
+		return TCL_OK;
+	    }
+	    break;
+	case '\\':
+	    TclParseBackslash(src, numBytes, &length, NULL);
+	    if ((length > 1) && (src[1] == '\n')) {
+		/*
+		 * A backslash-newline sequence must be collapsed, even inside
+		 * braces, so we have to split the word into multiple tokens
+		 * so that the backslash-newline can be represented
+		 * explicitly.
+		 */
+
+		if (numBytes == 2) {
+		    parsePtr->incomplete = 1;
+		}
+		tokenPtr->size = (src - tokenPtr->start);
+		if (tokenPtr->size != 0) {
+		    parsePtr->numTokens++;
+		}
+		TclGrowParseTokenArray(parsePtr, 2);
+		tokenPtr = &parsePtr->tokenPtr[parsePtr->numTokens];
+		tokenPtr->type = TCL_TOKEN_BS;
+		tokenPtr->start = src;
+		tokenPtr->size = length;
+		tokenPtr->numComponents = 0;
+		parsePtr->numTokens++;
+
+		src += length - 1;
+		numBytes -= length - 1;
+		tokenPtr++;
+		tokenPtr->type = TCL_TOKEN_TEXT;
+		tokenPtr->start = src + 1;
+		tokenPtr->numComponents = 0;
+	    } else {
+		src += length - 1;
+		numBytes -= length - 1;
+	    }
+	    break;
+	}
+    }
+
+  missingBraceError:
+    parsePtr->errorType = TCL_PARSE_MISSING_BRACE;
+    parsePtr->term = start;
+    parsePtr->incomplete = 1;
+    if (parsePtr->interp == NULL) {
+	/*
+	 * Skip straight to the exit code since we have no interpreter to put
+	 * error message in.
+	 */
+
+	goto error;
+    }
+
+    Tcl_SetObjResult(parsePtr->interp, Tcl_NewStringObj(
+	    "missing close-brace", -1));
+
+    /*
+     * Guess if the problem is due to comments by searching the source string
+     * for a possible open brace within the context of a comment. Since we
+     * aren't performing a full Tcl parse, just look for an open brace
+     * preceded by a '<whitespace>#' on the same line.
+     */
+
+    {
+	register int openBrace = 0;
+
+	while (--src > start) {
+	    switch (*src) {
+	    case '{':
+		openBrace = 1;
+		break;
+	    case '\n':
+		openBrace = 0;
+		break;
+	    case '#' :
+		if (openBrace && TclIsSpaceProc(src[-1])) {
+		    Tcl_AppendToObj(Tcl_GetObjResult(parsePtr->interp),
+			    ": possible unbalanced brace in comment", -1);
+		    goto error;
+		}
+		break;
+	    }
+	}
+    }
+
+  error:
+    Tcl_FreeParse(parsePtr);
+    return TCL_ERROR;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_ParseQuotedString --
+ *
+ *	Given a double-quoted string such as a quoted Tcl command argument or
+ *	a quoted value in a Tcl expression, this function parses the string
+ *	and returns information about the parse. No more than numBytes bytes
+ *	will be scanned.
+ *
+ * Results:
+ *	The return value is TCL_OK if the string was parsed successfully and
+ *	TCL_ERROR otherwise. If an error occurs and interp isn't NULL then an
+ *	error message is left in its result. On a successful return, tokenPtr
+ *	and numTokens fields of parsePtr are filled in with information about
+ *	the string that was parsed. Other fields in parsePtr are undefined.
+ *	termPtr is set to point to the character just after the quoted
+ *	string's terminating close-quote.
+ *
+ * Side effects:
+ *	If there is insufficient space in parsePtr to hold all the information
+ *	about the command, then additional space is malloc-ed. If the function
+ *	returns TCL_OK then the caller must eventually invoke Tcl_FreeParse to
+ *	release any additional space that was allocated.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_ParseQuotedString(
+    Tcl_Interp *interp,		/* Interpreter to use for error reporting; if
+				 * NULL, then no error message is provided. */
+    const char *start,		/* Start of the quoted string. The first
+				 * character must be '"'. */
+    register int numBytes,	/* Total number of bytes in string. If < 0,
+				 * the string consists of all bytes up to the
+				 * first null character. */
+    register Tcl_Parse *parsePtr,
+				/* Structure to fill in with information about
+				 * the string. */
+    int append,			/* Non-zero means append tokens to existing
+				 * information in parsePtr; zero means ignore
+				 * existing tokens in parsePtr and
+				 * reinitialize it. */
+    const char **termPtr)	/* If non-NULL, points to word in which to
+				 * store a pointer to the character just after
+				 * the quoted string's terminating close-quote
+				 * if the parse succeeds. */
+{
+    if ((numBytes == 0) || (start == NULL)) {
+	return TCL_ERROR;
+    }
+    if (numBytes < 0) {
+	numBytes = strlen(start);
+    }
+
+    if (!append) {
+	TclParseInit(interp, start, numBytes, parsePtr);
+    }
+
+    if (TCL_OK != ParseTokens(start+1, numBytes-1, TYPE_QUOTE, TCL_SUBST_ALL,
+	    parsePtr)) {
+	goto error;
+    }
+    if (*parsePtr->term != '"') {
+	if (parsePtr->interp != NULL) {
+	    Tcl_SetObjResult(parsePtr->interp, Tcl_NewStringObj(
+		    "missing \"", -1));
+	}
+	parsePtr->errorType = TCL_PARSE_MISSING_QUOTE;
+	parsePtr->term = start;
+	parsePtr->incomplete = 1;
+	goto error;
+    }
+    if (termPtr != NULL) {
+	*termPtr = (parsePtr->term + 1);
+    }
+    return TCL_OK;
+
+  error:
+    Tcl_FreeParse(parsePtr);
+    return TCL_ERROR;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclSubstParse --
+ *
+ *	Token parser used by the [subst] command. Parses the string made up of
+ *	'numBytes' bytes starting at 'bytes'. Parsing is controlled by the
+ *	flags argument to provide support for the -nobackslashes, -nocommands,
+ *	and -novariables options, as represented by the flag values
+ *	TCL_SUBST_BACKSLASHES, TCL_SUBST_COMMANDS, TCL_SUBST_VARIABLES.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The Tcl_Parse struct '*parsePtr' is filled with parse results.
+ *	The caller is expected to eventually call Tcl_FreeParse() to properly
+ *	cleanup the value written there.
+ *
+ *	If a parse error occurs, the Tcl_InterpState value '*statePtr' is
+ *	filled with the state created by that error. When *statePtr is written
+ *	to, the caller is expected to make the required calls to either
+ *	Tcl_RestoreInterpState() or Tcl_DiscardInterpState() to dispose of the
+ *	value written there.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclSubstParse(
+    Tcl_Interp *interp,
+    const char *bytes,
+    int numBytes,
+    int flags,
+    Tcl_Parse *parsePtr,
+    Tcl_InterpState *statePtr)
+{
+    int length = numBytes;
+    const char *p = bytes;
+
+    TclParseInit(interp, p, length, parsePtr);
+
+    /*
+     * First parse the string rep of objPtr, as if it were enclosed as a
+     * "-quoted word in a normal Tcl command. Honor flags that selectively
+     * inhibit types of substitution.
+     */
+
+    if (TCL_OK != ParseTokens(p, length, /* mask */ 0, flags, parsePtr)) {
+	/*
+	 * There was a parse error. Save the interpreter state for possible
+	 * error reporting later.
+	 */
+
+	*statePtr = Tcl_SaveInterpState(interp, TCL_ERROR);
+
+	/*
+	 * We need to re-parse to get the portion of the string we can [subst]
+	 * before the parse error. Sadly, all the Tcl_Token's created by the
+	 * first parse attempt are gone, freed according to the public spec
+	 * for the Tcl_Parse* routines. The only clue we have is parse.term,
+	 * which points to either the unmatched opener, or to characters that
+	 * follow a close brace or close quote.
+	 *
+	 * Call ParseTokens again, working on the string up to parse.term.
+	 * Keep repeating until we get a good parse on a prefix.
+	 */
+
+	do {
+	    parsePtr->numTokens = 0;
+	    parsePtr->tokensAvailable = NUM_STATIC_TOKENS;
+	    parsePtr->end = parsePtr->term;
+	    parsePtr->incomplete = 0;
+	    parsePtr->errorType = TCL_PARSE_SUCCESS;
+	} while (TCL_OK !=
+		ParseTokens(p, parsePtr->end - p, 0, flags, parsePtr));
+
+	/*
+	 * The good parse will have to be followed by {, (, or [.
+	 */
+
+	switch (*(parsePtr->term)) {
+	case '{':
+	    /*
+	     * Parse error was a missing } in a ${varname} variable
+	     * substitution at the toplevel. We will subst everything up to
+	     * that broken variable substitution before reporting the parse
+	     * error. Substituting the leftover '$' will have no side-effects,
+	     * so the current token stream is fine.
+	     */
+	    break;
+
+	case '(':
+	    /*
+	     * Parse error was during the parsing of the index part of an
+	     * array variable substitution at the toplevel.
+	     */
+
+	    if (*(parsePtr->term - 1) == '$') {
+		/*
+		 * Special case where removing the array index left us with
+		 * just a dollar sign (array variable with name the empty
+		 * string as its name), instead of with a scalar variable
+		 * reference.
+		 *
+		 * As in the previous case, existing token stream is OK.
+		 */
+	    } else {
+		/*
+		 * The current parse includes a successful parse of a scalar
+		 * variable substitution where there should have been an array
+		 * variable substitution. We remove that mistaken part of the
+		 * parse before moving on. A scalar variable substitution is
+		 * two tokens.
+		 */
+
+		Tcl_Token *varTokenPtr =
+			parsePtr->tokenPtr + parsePtr->numTokens - 2;
+
+		if (varTokenPtr->type != TCL_TOKEN_VARIABLE) {
+		    Tcl_Panic("TclSubstParse: programming error");
+		}
+		if (varTokenPtr[1].type != TCL_TOKEN_TEXT) {
+		    Tcl_Panic("TclSubstParse: programming error");
+		}
+		parsePtr->numTokens -= 2;
+	    }
+	    break;
+	case '[':
+	    /*
+	     * Parse error occurred during parsing of a toplevel command
+	     * substitution.
+	     */
+
+	    parsePtr->end = p + length;
+	    p = parsePtr->term + 1;
+	    length = parsePtr->end - p;
+	    if (length == 0) {
+		/*
+		 * No commands, just an unmatched [. As in previous cases,
+		 * existing token stream is OK.
+		 */
+	    } else {
+		/*
+		 * We want to add the parsing of as many commands as we can
+		 * within that substitution until we reach the actual parse
+		 * error. We'll do additional parsing to determine what length
+		 * to claim for the final TCL_TOKEN_COMMAND token.
+		 */
+
+		Tcl_Token *tokenPtr;
+		const char *lastTerm = parsePtr->term;
+		Tcl_Parse *nestedPtr =
+			TclStackAlloc(interp, sizeof(Tcl_Parse));
+
+		while (TCL_OK ==
+			Tcl_ParseCommand(NULL, p, length, 0, nestedPtr)) {
+		    Tcl_FreeParse(nestedPtr);
+		    p = nestedPtr->term + (nestedPtr->term < nestedPtr->end);
+		    length = nestedPtr->end - p;
+		    if ((length == 0) && (nestedPtr->term == nestedPtr->end)) {
+			/*
+			 * If we run out of string, blame the missing close
+			 * bracket on the last command, and do not evaluate it
+			 * during substitution.
+			 */
+
+			break;
+		    }
+		    lastTerm = nestedPtr->term;
+		}
+		TclStackFree(interp, nestedPtr);
+
+		if (lastTerm == parsePtr->term) {
+		    /*
+		     * Parse error in first command. No commands to subst, add
+		     * no more tokens.
+		     */
+		    break;
+		}
+
+		/*
+		 * Create a command substitution token for whatever commands
+		 * got parsed.
+		 */
+
+		TclGrowParseTokenArray(parsePtr, 1);
+		tokenPtr = &(parsePtr->tokenPtr[parsePtr->numTokens]);
+		tokenPtr->start = parsePtr->term;
+		tokenPtr->numComponents = 0;
+		tokenPtr->type = TCL_TOKEN_COMMAND;
+		tokenPtr->size = lastTerm - tokenPtr->start + 1;
+		parsePtr->numTokens++;
+	    }
+	    break;
+
+	default:
+	    Tcl_Panic("bad parse in TclSubstParse: %c", p[length]);
+	}
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclSubstTokens --
+ *
+ *	Accepts an array of count Tcl_Token's, and creates a result value in
+ *	the interp from concatenating the results of performing Tcl
+ *	substitution on each Tcl_Token. Substitution is interrupted if any
+ *	non-TCL_OK completion code arises.
+ *
+ * Results:
+ *	The return value is a standard Tcl completion code. The result in
+ *	interp is the substituted value, or an error message if TCL_ERROR is
+ *	returned. If tokensLeftPtr is not NULL, then it points to an int where
+ *	the number of tokens remaining to be processed is written.
+ *
+ * Side effects:
+ *	Can be anything, depending on the types of substitution done.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclSubstTokens(
+    Tcl_Interp *interp,		/* Interpreter in which to lookup variables,
+				 * execute nested commands, and report
+				 * errors. */
+    Tcl_Token *tokenPtr,	/* Pointer to first in an array of tokens to
+				 * evaluate and concatenate. */
+    int count,			/* Number of tokens to consider at tokenPtr.
+				 * Must be at least 1. */
+    int *tokensLeftPtr,		/* If not NULL, points to memory where an
+				 * integer representing the number of tokens
+				 * left to be substituted will be written */
+    int line,			/* The line the script starts on. */
+    int *clNextOuter,		/* Information about an outer context for */
+    const char *outerScript)	/* continuation line data. This is set by
+				 * EvalEx() to properly handle [...]-nested
+				 * commands. The 'outerScript' refers to the
+				 * most-outer script containing the embedded
+				 * command, which is refered to by 'script'.
+				 * The 'clNextOuter' refers to the current
+				 * entry in the table of continuation lines in
+				 * this "master script", and the character
+				 * offsets are relative to the 'outerScript'
+				 * as well.
+				 *
+				 * If outerScript == script, then this call is
+				 * for words in the outer-most script or
+				 * command. See Tcl_EvalEx and TclEvalObjEx
+				 * for the places generating arguments for
+				 * which this is true. */
+{
+    Tcl_Obj *result;
+    int code = TCL_OK;
+#define NUM_STATIC_POS 20
+    int isLiteral, maxNumCL, numCL, i, adjust;
+    int *clPosition = NULL;
+    Interp *iPtr = (Interp *) interp;
+    int inFile = iPtr->evalFlags & TCL_EVAL_FILE;
+
+    /*
+     * Each pass through this loop will substitute one token, and its
+     * components, if any. The only thing tricky here is that we go to some
+     * effort to pass Tcl_Obj's through untouched, to avoid string copying and
+     * Tcl_Obj creation if possible, to aid performance and limit shimmering.
+     *
+     * Further optimization opportunities might be to check for the equivalent
+     * of Tcl_SetObjResult(interp, Tcl_GetObjResult(interp)) and omit them.
+     */
+
+    /*
+     * For the handling of continuation lines in literals we first check if
+     * this is actually a literal. For if not we can forego the additional
+     * processing. Otherwise we pre-allocate a small table to store the
+     * locations of all continuation lines we find in this literal, if any.
+     * The table is extended if needed.
+     */
+
+    numCL = 0;
+    maxNumCL = 0;
+    isLiteral = 1;
+    for (i=0 ; i < count; i++) {
+	if ((tokenPtr[i].type != TCL_TOKEN_TEXT)
+		&& (tokenPtr[i].type != TCL_TOKEN_BS)) {
+	    isLiteral = 0;
+	    break;
+	}
+    }
+
+    if (isLiteral) {
+	maxNumCL = NUM_STATIC_POS;
+	clPosition = ckalloc(maxNumCL * sizeof(int));
+    }
+
+    adjust = 0;
+    result = NULL;
+    for (; count>0 && code==TCL_OK ; count--, tokenPtr++) {
+	Tcl_Obj *appendObj = NULL;
+	const char *append = NULL;
+	int appendByteLength = 0;
+	char utfCharBytes[TCL_UTF_MAX];
+
+	switch (tokenPtr->type) {
+	case TCL_TOKEN_TEXT:
+	    append = tokenPtr->start;
+	    appendByteLength = tokenPtr->size;
+	    break;
+
+	case TCL_TOKEN_BS:
+	    appendByteLength = TclParseBackslash(tokenPtr->start,
+		    tokenPtr->size, NULL, utfCharBytes);
+	    append = utfCharBytes;
+
+	    /*
+	     * If the backslash sequence we found is in a literal, and
+	     * represented a continuation line, we compute and store its
+	     * location (as char offset to the beginning of the _result_
+	     * script). We may have to extend the table of locations.
+	     *
+	     * Note that the continuation line information is relevant even if
+	     * the word we are processing is not a literal, as it can affect
+	     * nested commands. See the branch for TCL_TOKEN_COMMAND below,
+	     * where the adjustment we are tracking here is taken into
+	     * account. The good thing is that we do not need a table of
+	     * everything, just the number of lines we have to add as
+	     * correction.
+	     */
+
+	    if ((appendByteLength == 1) && (utfCharBytes[0] == ' ')
+		    && (tokenPtr->start[1] == '\n')) {
+		if (isLiteral) {
+		    int clPos;
+
+		    if (result == 0) {
+			clPos = 0;
+		    } else {
+			Tcl_GetStringFromObj(result, &clPos);
+		    }
+
+		    if (numCL >= maxNumCL) {
+			maxNumCL *= 2;
+			clPosition = ckrealloc(clPosition,
+				maxNumCL * sizeof(int));
+		    }
+		    clPosition[numCL] = clPos;
+		    numCL++;
+		}
+		adjust++;
+	    }
+	    break;
+
+	case TCL_TOKEN_COMMAND: {
+	    /* TIP #280: Transfer line information to nested command */
+	    iPtr->numLevels++;
+	    code = TclInterpReady(interp);
+	    if (code == TCL_OK) {
+		/*
+		 * Test cases: info-30.{6,8,9}
+		 */
+
+		int theline;
+
+		TclAdvanceContinuations(&line, &clNextOuter,
+			tokenPtr->start - outerScript);
+		theline = line + adjust;
+		code = TclEvalEx(interp, tokenPtr->start+1, tokenPtr->size-2,
+			0, theline, clNextOuter, outerScript);
+
+		TclAdvanceLines(&line, tokenPtr->start+1,
+			tokenPtr->start + tokenPtr->size - 1);
+
+		/*
+		 * Restore flag reset by nested eval for future bracketed
+		 * commands and their cmdframe setup
+		 */
+
+		if (inFile) {
+		    iPtr->evalFlags |= TCL_EVAL_FILE;
+		}
+	    }
+	    iPtr->numLevels--;
+	    TclResetCancellation(interp, 0);
+	    appendObj = Tcl_GetObjResult(interp);
+	    break;
+	}
+
+	case TCL_TOKEN_VARIABLE: {
+	    Tcl_Obj *arrayIndex = NULL;
+	    Tcl_Obj *varName = NULL;
+
+	    if (tokenPtr->numComponents > 1) {
+		/*
+		 * Subst the index part of an array variable reference.
+		 */
+
+		code = TclSubstTokens(interp, tokenPtr+2,
+			tokenPtr->numComponents - 1, NULL, line, NULL, NULL);
+		arrayIndex = Tcl_GetObjResult(interp);
+		Tcl_IncrRefCount(arrayIndex);
+	    }
+
+	    if (code == TCL_OK) {
+		varName = Tcl_NewStringObj(tokenPtr[1].start,
+			tokenPtr[1].size);
+		appendObj = Tcl_ObjGetVar2(interp, varName, arrayIndex,
+			TCL_LEAVE_ERR_MSG);
+		Tcl_DecrRefCount(varName);
+		if (appendObj == NULL) {
+		    code = TCL_ERROR;
+		}
+	    }
+
+	    switch (code) {
+	    case TCL_OK:	/* Got value */
+	    case TCL_ERROR:	/* Already have error message */
+	    case TCL_BREAK:	/* Will not substitute anyway */
+	    case TCL_CONTINUE:	/* Will not substitute anyway */
+		break;
+	    default:
+		/*
+		 * All other return codes, we will subst the result from the
+		 * code-throwing evaluation.
+		 */
+
+		appendObj = Tcl_GetObjResult(interp);
+	    }
+
+	    if (arrayIndex != NULL) {
+		Tcl_DecrRefCount(arrayIndex);
+	    }
+	    count -= tokenPtr->numComponents;
+	    tokenPtr += tokenPtr->numComponents;
+	    break;
+	}
+
+	default:
+	    Tcl_Panic("unexpected token type in TclSubstTokens: %d",
+		    tokenPtr->type);
+	}
+
+	if ((code == TCL_BREAK) || (code == TCL_CONTINUE)) {
+	    /*
+	     * Inhibit substitution.
+	     */
+	    continue;
+	}
+
+	if (result == NULL) {
+	    /*
+	     * First pass through. If we have a Tcl_Obj, just use it. If not,
+	     * create one from our string.
+	     */
+
+	    if (appendObj != NULL) {
+		result = appendObj;
+	    } else {
+		result = Tcl_NewStringObj(append, appendByteLength);
+	    }
+	    Tcl_IncrRefCount(result);
+	} else {
+	    /*
+	     * Subsequent passes. Append to result.
+	     */
+
+	    if (Tcl_IsShared(result)) {
+		Tcl_DecrRefCount(result);
+		result = Tcl_DuplicateObj(result);
+		Tcl_IncrRefCount(result);
+	    }
+	    if (appendObj != NULL) {
+		Tcl_AppendObjToObj(result, appendObj);
+	    } else {
+		Tcl_AppendToObj(result, append, appendByteLength);
+	    }
+	}
+    }
+
+    if (code != TCL_ERROR) {		/* Keep error message in result! */
+	if (result != NULL) {
+	    Tcl_SetObjResult(interp, result);
+
+	    /*
+	     * If the code found continuation lines (which implies that this
+	     * word is a literal), then we store the accumulated table of
+	     * locations in the thread-global data structure for the bytecode
+	     * compiler to find later, assuming that the literal is a script
+	     * which will be compiled.
+	     */
+
+	    if (numCL) {
+		TclContinuationsEnter(result, numCL, clPosition);
+	    }
+
+	    /*
+	     * Release the temp table we used to collect the locations of
+	     * continuation lines, if any.
+	     */
+
+	    if (maxNumCL) {
+		ckfree(clPosition);
+	    }
+	} else {
+	    Tcl_ResetResult(interp);
+	}
+    }
+    if (tokensLeftPtr != NULL) {
+	*tokensLeftPtr = count;
+    }
+    if (result != NULL) {
+	Tcl_DecrRefCount(result);
+    }
+    return code;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * CommandComplete --
+ *
+ *	This function is shared by TclCommandComplete and
+ *	Tcl_ObjCommandComplete; it does all the real work of seeing whether a
+ *	script is complete
+ *
+ * Results:
+ *	1 is returned if the script is complete, 0 if there are open
+ *	delimiters such as " or (. 1 is also returned if there is a parse
+ *	error in the script other than unmatched delimiters.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static inline int
+CommandComplete(
+    const char *script,		/* Script to check. */
+    int numBytes)		/* Number of bytes in script. */
+{
+    Tcl_Parse parse;
+    const char *p, *end;
+    int result;
+
+    p = script;
+    end = p + numBytes;
+    while (Tcl_ParseCommand(NULL, p, end - p, 0, &parse) == TCL_OK) {
+	p = parse.commandStart + parse.commandSize;
+	if (p >= end) {
+	    break;
+	}
+	Tcl_FreeParse(&parse);
+    }
+    if (parse.incomplete) {
+	result = 0;
+    } else {
+	result = 1;
+    }
+    Tcl_FreeParse(&parse);
+    return result;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_CommandComplete --
+ *
+ *	Given a partial or complete Tcl script, this function determines
+ *	whether the script is complete in the sense of having matched braces
+ *	and quotes and brackets.
+ *
+ * Results:
+ *	1 is returned if the script is complete, 0 otherwise. 1 is also
+ *	returned if there is a parse error in the script other than unmatched
+ *	delimiters.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_CommandComplete(
+    const char *script)		/* Script to check. */
+{
+    return CommandComplete(script, (int) strlen(script));
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclObjCommandComplete --
+ *
+ *	Given a partial or complete Tcl command in a Tcl object, this function
+ *	determines whether the command is complete in the sense of having
+ *	matched braces and quotes and brackets.
+ *
+ * Results:
+ *	1 is returned if the command is complete, 0 otherwise.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclObjCommandComplete(
+    Tcl_Obj *objPtr)		/* Points to object holding script to
+				 * check. */
+{
+    int length;
+    const char *script = Tcl_GetStringFromObj(objPtr, &length);
+
+    return CommandComplete(script, length);
+}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tclParse.h b/generic/tclParse.h
new file mode 100644
index 0000000..20c609c
--- /dev/null
+++ b/generic/tclParse.h
@@ -0,0 +1,17 @@
+/*
+ * Minimal set of shared macro definitions and declarations so that multiple
+ * source files can make use of the parsing table in tclParse.c
+ */
+
+#define TYPE_NORMAL		0
+#define TYPE_SPACE		0x1
+#define TYPE_COMMAND_END	0x2
+#define TYPE_SUBS		0x4
+#define TYPE_QUOTE		0x8
+#define TYPE_CLOSE_PAREN	0x10
+#define TYPE_CLOSE_BRACK	0x20
+#define TYPE_BRACE		0x40
+
+#define CHAR_TYPE(c) (tclCharTypeTable+128)[(int)(c)]
+
+MODULE_SCOPE const char tclCharTypeTable[];
diff --git a/generic/tclPathObj.c b/generic/tclPathObj.c
new file mode 100644
index 0000000..c2643bf
--- /dev/null
+++ b/generic/tclPathObj.c
@@ -0,0 +1,2693 @@
+/*
+ * tclPathObj.c --
+ *
+ *	This file contains the implementation of Tcl's "path" object type used
+ *	to represent and manipulate a general (virtual) filesystem entity in
+ *	an efficient manner.
+ *
+ * Copyright (c) 2003 Vince Darley.
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#include "tclInt.h"
+#include "tclFileSystem.h"
+
+/*
+ * Prototypes for functions defined later in this file.
+ */
+
+static Tcl_Obj *	AppendPath(Tcl_Obj *head, Tcl_Obj *tail);
+static void		DupFsPathInternalRep(Tcl_Obj *srcPtr,
+			    Tcl_Obj *copyPtr);
+static void		FreeFsPathInternalRep(Tcl_Obj *pathPtr);
+static void		UpdateStringOfFsPath(Tcl_Obj *pathPtr);
+static int		SetFsPathFromAny(Tcl_Interp *interp, Tcl_Obj *pathPtr);
+static int		FindSplitPos(const char *path, int separator);
+static int		IsSeparatorOrNull(int ch);
+static Tcl_Obj *	GetExtension(Tcl_Obj *pathPtr);
+static int		MakePathFromNormalized(Tcl_Interp *interp,
+			    Tcl_Obj *pathPtr);
+
+/*
+ * Define the 'path' object type, which Tcl uses to represent file paths
+ * internally.
+ */
+
+static const Tcl_ObjType tclFsPathType = {
+    "path",				/* name */
+    FreeFsPathInternalRep,		/* freeIntRepProc */
+    DupFsPathInternalRep,		/* dupIntRepProc */
+    UpdateStringOfFsPath,		/* updateStringProc */
+    SetFsPathFromAny			/* setFromAnyProc */
+};
+
+/*
+ * struct FsPath --
+ *
+ * Internal representation of a Tcl_Obj of "path" type. This can be used to
+ * represent relative or absolute paths, and has certain optimisations when
+ * used to represent paths which are already normalized and absolute.
+ *
+ * Note that both 'translatedPathPtr' and 'normPathPtr' can be a circular
+ * reference to the container Tcl_Obj of this FsPath.
+ *
+ * There are two cases, with the first being the most common:
+ *
+ * (i) flags == 0, => Ordinary path.
+ *
+ * translatedPathPtr contains the translated path (which may be a circular
+ * reference to the object itself). If it is NULL then the path is pure
+ * normalized (and the normPathPtr will be a circular reference). cwdPtr is
+ * null for an absolute path, and non-null for a relative path (unless the cwd
+ * has never been set, in which case the cwdPtr may also be null for a
+ * relative path).
+ *
+ * (ii) flags != 0, => Special path, see TclNewFSPathObj
+ *
+ * Now, this is a path like 'file join $dir $tail' where, cwdPtr is the $dir
+ * and normPathPtr is the $tail.
+ *
+ */
+
+typedef struct FsPath {
+    Tcl_Obj *translatedPathPtr; /* Name without any ~user sequences. If this
+				 * is NULL, then this is a pure normalized,
+				 * absolute path object, in which the parent
+				 * Tcl_Obj's string rep is already both
+				 * translated and normalized. */
+    Tcl_Obj *normPathPtr;	/* Normalized absolute path, without ., .. or
+				 * ~user sequences. If the Tcl_Obj containing
+				 * this FsPath is already normalized, this may
+				 * be a circular reference back to the
+				 * container. If that is NOT the case, we have
+				 * a refCount on the object. */
+    Tcl_Obj *cwdPtr;		/* If null, path is absolute, else this points
+				 * to the cwd object used for this path. We
+				 * have a refCount on the object. */
+    int flags;			/* Flags to describe interpretation - see
+				 * below. */
+    ClientData nativePathPtr;	/* Native representation of this path, which
+				 * is filesystem dependent. */
+    int filesystemEpoch;	/* Used to ensure the path representation was
+				 * generated during the correct filesystem
+				 * epoch. The epoch changes when
+				 * filesystem-mounts are changed. */
+    const Tcl_Filesystem *fsPtr;/* The Tcl_Filesystem that claims this path */
+} FsPath;
+
+/*
+ * Flag values for FsPath->flags.
+ */
+
+#define TCLPATH_APPENDED 1
+#define TCLPATH_NEEDNORM 4
+
+/*
+ * Define some macros to give us convenient access to path-object specific
+ * fields.
+ */
+
+#define PATHOBJ(pathPtr) ((FsPath *) (pathPtr)->internalRep.twoPtrValue.ptr1)
+#define SETPATHOBJ(pathPtr,fsPathPtr) \
+	((pathPtr)->internalRep.twoPtrValue.ptr1 = (void *) (fsPathPtr))
+#define PATHFLAGS(pathPtr) (PATHOBJ(pathPtr)->flags)
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * TclFSNormalizeAbsolutePath --
+ *
+ *	Takes an absolute path specification and computes a 'normalized' path
+ *	from it.
+ *
+ *	A normalized path is one which has all '../', './' removed. Also it is
+ *	one which is in the 'standard' format for the native platform. On
+ *	Unix, this means the path must be free of symbolic links/aliases, and
+ *	on Windows it means we want the long form, with that long form's
+ *	case-dependence (which gives us a unique, case-dependent path).
+ *
+ *	The behaviour of this function if passed a non-absolute path is NOT
+ *	defined.
+ *
+ *	pathPtr may have a refCount of zero, or may be a shared object.
+ *
+ * Results:
+ *	The result is returned in a Tcl_Obj with a refCount of 1, which is
+ *	therefore owned by the caller. It must be freed (with
+ *	Tcl_DecrRefCount) by the caller when no longer needed.
+ *
+ * Side effects:
+ *	None (beyond the memory allocation for the result).
+ *
+ * Special note:
+ *	This code was originally based on code from Matt Newman and
+ *	Jean-Claude Wippler, but has since been totally rewritten by Vince
+ *	Darley to deal with symbolic links.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+Tcl_Obj *
+TclFSNormalizeAbsolutePath(
+    Tcl_Interp *interp,		/* Interpreter to use */
+    Tcl_Obj *pathPtr)		/* Absolute path to normalize */
+{
+    const char *dirSep, *oldDirSep;
+    int first = 1;		/* Set to zero once we've passed the first
+				 * directory separator - we can't use '..' to
+				 * remove the volume in a path. */
+    Tcl_Obj *retVal = NULL;
+    dirSep = TclGetString(pathPtr);
+
+    if (tclPlatform == TCL_PLATFORM_WINDOWS) {
+	if (   (dirSep[0] == '/' || dirSep[0] == '\\')
+	    && (dirSep[1] == '/' || dirSep[1] == '\\')
+	    && (dirSep[2] == '?')
+	    && (dirSep[3] == '/' || dirSep[3] == '\\')) {
+	    /* NT extended path */
+	    dirSep += 4;
+
+	    if (   (dirSep[0] == 'U' || dirSep[0] == 'u')
+		&& (dirSep[1] == 'N' || dirSep[1] == 'n')
+		&& (dirSep[2] == 'C' || dirSep[2] == 'c')
+		&& (dirSep[3] == '/' || dirSep[3] == '\\')) {
+		/* NT extended UNC path */
+		dirSep += 4;
+	    }
+	}
+	if (dirSep[0] != 0 && dirSep[1] == ':' &&
+		(dirSep[2] == '/' || dirSep[2] == '\\')) {
+	    /* Do nothing */
+	} else if ((dirSep[0] == '/' || dirSep[0] == '\\')
+		&& (dirSep[1] == '/' || dirSep[1] == '\\')) {
+	    /*
+	     * UNC style path, where we must skip over the first separator,
+	     * since the first two segments are actually inseparable.
+	     */
+
+	    dirSep += 2;
+	    dirSep += FindSplitPos(dirSep, '/');
+	    if (*dirSep != 0) {
+		dirSep++;
+	    }
+	}
+    }
+
+    /*
+     * Scan forward from one directory separator to the next, checking for
+     * '..' and '.' sequences which must be handled specially. In particular
+     * handling of '..' can be complicated if the directory before is a link,
+     * since we will have to expand the link to be able to back up one level.
+     */
+
+    while (*dirSep != 0) {
+	oldDirSep = dirSep;
+	if (!first) {
+	    dirSep++;
+	}
+	dirSep += FindSplitPos(dirSep, '/');
+	if (dirSep[0] == 0 || dirSep[1] == 0) {
+	    if (retVal != NULL) {
+		Tcl_AppendToObj(retVal, oldDirSep, dirSep - oldDirSep);
+	    }
+	    break;
+	}
+	if (dirSep[1] == '.') {
+	    if (retVal != NULL) {
+		Tcl_AppendToObj(retVal, oldDirSep, dirSep - oldDirSep);
+		oldDirSep = dirSep;
+	    }
+	again:
+	    if (IsSeparatorOrNull(dirSep[2])) {
+		/*
+		 * Need to skip '.' in the path.
+		 */
+		int curLen;
+
+		if (retVal == NULL) {
+		    const char *path = TclGetString(pathPtr);
+		    retVal = Tcl_NewStringObj(path, dirSep - path);
+		    Tcl_IncrRefCount(retVal);
+		}
+		Tcl_GetStringFromObj(retVal, &curLen);
+		if (curLen == 0) {
+		    Tcl_AppendToObj(retVal, dirSep, 1);
+		}
+		dirSep += 2;
+		oldDirSep = dirSep;
+		if (dirSep[0] != 0 && dirSep[1] == '.') {
+		    goto again;
+		}
+		continue;
+	    }
+	    if (dirSep[2] == '.' && IsSeparatorOrNull(dirSep[3])) {
+		Tcl_Obj *linkObj;
+		int curLen;
+		char *linkStr;
+
+		/*
+		 * Have '..' so need to skip previous directory.
+		 */
+
+		if (retVal == NULL) {
+		    const char *path = TclGetString(pathPtr);
+
+		    retVal = Tcl_NewStringObj(path, dirSep - path);
+		    Tcl_IncrRefCount(retVal);
+		}
+		Tcl_GetStringFromObj(retVal, &curLen);
+		if (curLen == 0) {
+		    Tcl_AppendToObj(retVal, dirSep, 1);
+		}
+		if (!first || (tclPlatform == TCL_PLATFORM_UNIX)) {
+		    linkObj = Tcl_FSLink(retVal, NULL, 0);
+
+		    /* Safety check in case driver caused sharing */
+		    if (Tcl_IsShared(retVal)) {
+			TclDecrRefCount(retVal);
+			retVal = Tcl_DuplicateObj(retVal);
+			Tcl_IncrRefCount(retVal);
+		    }
+
+		    if (linkObj != NULL) {
+			/*
+			 * Got a link. Need to check if the link is relative
+			 * or absolute, for those platforms where relative
+			 * links exist.
+			 */
+
+			if (tclPlatform != TCL_PLATFORM_WINDOWS
+				&& Tcl_FSGetPathType(linkObj)
+					== TCL_PATH_RELATIVE) {
+			    /*
+			     * We need to follow this link which is relative
+			     * to retVal's directory. This means concatenating
+			     * the link onto the directory of the path so far.
+			     */
+
+			    const char *path =
+				    Tcl_GetStringFromObj(retVal, &curLen);
+
+			    while (--curLen >= 0) {
+				if (IsSeparatorOrNull(path[curLen])) {
+				    break;
+				}
+			    }
+
+			    /*
+			     * We want the trailing slash.
+			     */
+
+			    Tcl_SetObjLength(retVal, curLen+1);
+			    Tcl_AppendObjToObj(retVal, linkObj);
+			    TclDecrRefCount(linkObj);
+			    linkStr = Tcl_GetStringFromObj(retVal, &curLen);
+			} else {
+			    /*
+			     * Absolute link.
+			     */
+
+			    TclDecrRefCount(retVal);
+			    if (Tcl_IsShared(linkObj)) {
+				retVal = Tcl_DuplicateObj(linkObj);
+				TclDecrRefCount(linkObj);
+			    } else {
+				retVal = linkObj;
+			    }
+			    linkStr = Tcl_GetStringFromObj(retVal, &curLen);
+
+			    /*
+			     * Convert to forward-slashes on windows.
+			     */
+
+			    if (tclPlatform == TCL_PLATFORM_WINDOWS) {
+				int i;
+
+				for (i = 0; i < curLen; i++) {
+				    if (linkStr[i] == '\\') {
+					linkStr[i] = '/';
+				    }
+				}
+			    }
+			}
+		    } else {
+			linkStr = Tcl_GetStringFromObj(retVal, &curLen);
+		    }
+
+		    /*
+		     * Either way, we now remove the last path element (but
+		     * not the first character of the path).
+		     */
+
+		    while (--curLen >= 0) {
+			if (IsSeparatorOrNull(linkStr[curLen])) {
+			    if (curLen) {
+				Tcl_SetObjLength(retVal, curLen);
+			    } else {
+				Tcl_SetObjLength(retVal, 1);
+			    }
+			    break;
+			}
+		    }
+		}
+		dirSep += 3;
+		oldDirSep = dirSep;
+
+		if ((curLen == 0) && (dirSep[0] != 0)) {
+		    Tcl_SetObjLength(retVal, 0);
+		}
+
+		if (dirSep[0] != 0 && dirSep[1] == '.') {
+		    goto again;
+		}
+		continue;
+	    }
+	}
+	first = 0;
+	if (retVal != NULL) {
+	    Tcl_AppendToObj(retVal, oldDirSep, dirSep - oldDirSep);
+	}
+    }
+
+    /*
+     * If we didn't make any changes, just use the input path.
+     */
+
+    if (retVal == NULL) {
+	retVal = pathPtr;
+	Tcl_IncrRefCount(retVal);
+
+	if (Tcl_IsShared(retVal)) {
+	    /*
+	     * Unfortunately, the platform-specific normalization code which
+	     * will be called below has no way of dealing with the case where
+	     * an object is shared. It is expecting to modify an object in
+	     * place. So, we must duplicate this here to ensure an object with
+	     * a single ref-count.
+	     *
+	     * If that changes in the future (e.g. the normalize proc is given
+	     * one object and is able to return a different one), then we
+	     * could remove this code.
+	     */
+
+	    TclDecrRefCount(retVal);
+	    retVal = Tcl_DuplicateObj(pathPtr);
+	    Tcl_IncrRefCount(retVal);
+	}
+    }
+
+    /*
+     * Ensure a windows drive like C:/ has a trailing separator.
+     */
+
+    if (tclPlatform == TCL_PLATFORM_WINDOWS) {
+	int len;
+	const char *path = Tcl_GetStringFromObj(retVal, &len);
+
+	if (len == 2 && path[0] != 0 && path[1] == ':') {
+	    if (Tcl_IsShared(retVal)) {
+		TclDecrRefCount(retVal);
+		retVal = Tcl_DuplicateObj(retVal);
+		Tcl_IncrRefCount(retVal);
+	    }
+	    Tcl_AppendToObj(retVal, "/", 1);
+	}
+    }
+
+    /*
+     * Now we have an absolute path, with no '..', '.' sequences, but it still
+     * may not be in 'unique' form, depending on the platform. For instance,
+     * Unix is case-sensitive, so the path is ok. Windows is case-insensitive,
+     * and also has the weird 'longname/shortname' thing (e.g. C:/Program
+     * Files/ and C:/Progra~1/ are equivalent).
+     *
+     * Virtual file systems which may be registered may have other criteria
+     * for normalizing a path.
+     */
+
+    TclFSNormalizeToUniquePath(interp, retVal, 0);
+
+    /*
+     * Since we know it is a normalized path, we can actually convert this
+     * object into an FsPath for greater efficiency
+     */
+
+    MakePathFromNormalized(interp, retVal);
+
+    /*
+     * This has a refCount of 1 for the caller, unlike many Tcl_Obj APIs.
+     */
+
+    return retVal;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_FSGetPathType --
+ *
+ *	Determines whether a given path is relative to the current directory,
+ *	relative to the current volume, or absolute.
+ *
+ * Results:
+ *	Returns one of TCL_PATH_ABSOLUTE, TCL_PATH_RELATIVE, or
+ *	TCL_PATH_VOLUME_RELATIVE.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_PathType
+Tcl_FSGetPathType(
+    Tcl_Obj *pathPtr)
+{
+    return TclFSGetPathType(pathPtr, NULL, NULL);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclFSGetPathType --
+ *
+ *	Determines whether a given path is relative to the current directory,
+ *	relative to the current volume, or absolute. If the caller wishes to
+ *	know which filesystem claimed the path (in the case for which the path
+ *	is absolute), then a reference to a filesystem pointer can be passed
+ *	in (but passing NULL is acceptable).
+ *
+ * Results:
+ *	Returns one of TCL_PATH_ABSOLUTE, TCL_PATH_RELATIVE, or
+ *	TCL_PATH_VOLUME_RELATIVE. The filesystem reference will be set if and
+ *	only if it is non-NULL and the function's return value is
+ *	TCL_PATH_ABSOLUTE.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_PathType
+TclFSGetPathType(
+    Tcl_Obj *pathPtr,
+    const Tcl_Filesystem **filesystemPtrPtr,
+    int *driveNameLengthPtr)
+{
+    FsPath *fsPathPtr;
+
+    if (Tcl_FSConvertToPathType(NULL, pathPtr) != TCL_OK) {
+	return TclGetPathType(pathPtr, filesystemPtrPtr, driveNameLengthPtr,
+		NULL);
+    }
+
+    fsPathPtr = PATHOBJ(pathPtr);
+    if (fsPathPtr->cwdPtr == NULL) {
+	return TclGetPathType(pathPtr, filesystemPtrPtr, driveNameLengthPtr,
+		NULL);
+    }
+
+    if (PATHFLAGS(pathPtr) == 0) {
+	/* The path is not absolute... */
+#ifdef _WIN32
+	/* ... on Windows we must make another call to determine whether
+	 * it's relative or volumerelative [Bug 2571597]. */
+	return TclGetPathType(pathPtr, filesystemPtrPtr, driveNameLengthPtr,
+		NULL);
+#else
+	/* On other systems, quickly deduce !absolute -> relative */
+	return TCL_PATH_RELATIVE;
+#endif
+    }
+    return TclFSGetPathType(fsPathPtr->cwdPtr, filesystemPtrPtr,
+	    driveNameLengthPtr);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * TclPathPart
+ *
+ *	This function calculates the requested part of the given path, which
+ *	can be:
+ *
+ *	- the directory above ('file dirname')
+ *	- the tail            ('file tail')
+ *	- the extension       ('file extension')
+ *	- the root            ('file root')
+ *
+ *	The 'portion' parameter dictates which of these to calculate. There
+ *	are a number of special cases both to be more efficient, and because
+ *	the behaviour when given a path with only a single element is defined
+ *	to require the expansion of that single element, where possible.
+ *
+ *	Should look into integrating 'FileBasename' in tclFCmd.c into this
+ *	function.
+ *
+ * Results:
+ *	NULL if an error occurred, otherwise a Tcl_Obj owned by the caller
+ *	(i.e. most likely with refCount 1).
+ *
+ * Side effects:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+Tcl_Obj *
+TclPathPart(
+    Tcl_Interp *interp,		/* Used for error reporting */
+    Tcl_Obj *pathPtr,		/* Path to take dirname of */
+    Tcl_PathPart portion)	/* Requested portion of name */
+{
+    if (pathPtr->typePtr == &tclFsPathType) {
+	FsPath *fsPathPtr = PATHOBJ(pathPtr);
+
+	if (PATHFLAGS(pathPtr) != 0) {
+	    switch (portion) {
+	    case TCL_PATH_DIRNAME: {
+		/*
+		 * Check if the joined-on bit has any directory delimiters in
+		 * it. If so, the 'dirname' would be a joining of the main
+		 * part with the dirname of the joined-on bit. We could handle
+		 * that special case here, but we don't, and instead just use
+		 * the standardPath code.
+		 */
+
+		int numBytes;
+		const char *rest =
+			Tcl_GetStringFromObj(fsPathPtr->normPathPtr, &numBytes);
+
+		if (strchr(rest, '/') != NULL) {
+		    goto standardPath;
+		}
+		/*
+		 * If the joined-on bit is empty, then [file dirname] is
+		 * documented to return all but the last non-empty element
+		 * of the path, so we need to split apart the main part to
+		 * get the right answer.  We could do that here, but it's
+		 * simpler to fall back to the standardPath code.
+		 * [Bug 2710920]
+		 */
+		if (numBytes == 0) {
+		    goto standardPath;
+		}
+		if (tclPlatform == TCL_PLATFORM_WINDOWS
+			&& strchr(rest, '\\') != NULL) {
+		    goto standardPath;
+		}
+
+		/*
+		 * The joined-on path is simple, so we can just return here.
+		 */
+
+		Tcl_IncrRefCount(fsPathPtr->cwdPtr);
+		return fsPathPtr->cwdPtr;
+	    }
+	    case TCL_PATH_TAIL: {
+		/*
+		 * Check if the joined-on bit has any directory delimiters in
+		 * it. If so, the 'tail' would be only the part following the
+		 * last delimiter. We could handle that special case here, but
+		 * we don't, and instead just use the standardPath code.
+		 */
+
+		int numBytes;
+		const char *rest =
+			Tcl_GetStringFromObj(fsPathPtr->normPathPtr, &numBytes);
+
+		if (strchr(rest, '/') != NULL) {
+		    goto standardPath;
+		}
+		/*
+		 * If the joined-on bit is empty, then [file tail] is
+		 * documented to return the last non-empty element
+		 * of the path, so we need to split off the last element
+		 * of the main part to get the right answer.  We could do
+		 * that here, but it's simpler to fall back to the
+		 * standardPath code.  [Bug 2710920]
+		 */
+		if (numBytes == 0) {
+		    goto standardPath;
+		}
+		if (tclPlatform == TCL_PLATFORM_WINDOWS
+			&& strchr(rest, '\\') != NULL) {
+		    goto standardPath;
+		}
+		Tcl_IncrRefCount(fsPathPtr->normPathPtr);
+		return fsPathPtr->normPathPtr;
+	    }
+	    case TCL_PATH_EXTENSION:
+		return GetExtension(fsPathPtr->normPathPtr);
+	    case TCL_PATH_ROOT: {
+		const char *fileName, *extension;
+		int length;
+
+		fileName = Tcl_GetStringFromObj(fsPathPtr->normPathPtr,
+			&length);
+		extension = TclGetExtension(fileName);
+		if (extension == NULL) {
+		    /*
+		     * There is no extension so the root is the same as the
+		     * path we were given.
+		     */
+
+		    Tcl_IncrRefCount(pathPtr);
+		    return pathPtr;
+		} else {
+		    /*
+		     * Need to return the whole path with the extension
+		     * suffix removed.  Do that by joining our "head" to
+		     * our "tail" with the extension suffix removed from
+		     * the tail.
+		     */
+
+		    Tcl_Obj *resultPtr =
+			    TclNewFSPathObj(fsPathPtr->cwdPtr, fileName,
+			    (int)(length - strlen(extension)));
+
+		    Tcl_IncrRefCount(resultPtr);
+		    return resultPtr;
+		}
+	    }
+	    default:
+		/* We should never get here */
+		Tcl_Panic("Bad portion to TclPathPart");
+		/* For less clever compilers */
+		return NULL;
+	    }
+	} else if (fsPathPtr->cwdPtr != NULL) {
+	    /* Relative path */
+	    goto standardPath;
+	} else {
+	    /* Absolute path */
+	    goto standardPath;
+	}
+    } else {
+	int splitElements;
+	Tcl_Obj *splitPtr, *resultPtr;
+
+    standardPath:
+	resultPtr = NULL;
+	if (portion == TCL_PATH_EXTENSION) {
+	    return GetExtension(pathPtr);
+	} else if (portion == TCL_PATH_ROOT) {
+	    int length;
+	    const char *fileName, *extension;
+
+	    fileName = Tcl_GetStringFromObj(pathPtr, &length);
+	    extension = TclGetExtension(fileName);
+	    if (extension == NULL) {
+		Tcl_IncrRefCount(pathPtr);
+		return pathPtr;
+	    } else {
+		Tcl_Obj *root = Tcl_NewStringObj(fileName,
+			(int) (length - strlen(extension)));
+
+		Tcl_IncrRefCount(root);
+		return root;
+	    }
+	}
+
+	/*
+	 * The behaviour we want here is slightly different to the standard
+	 * Tcl_FSSplitPath in the handling of home directories;
+	 * Tcl_FSSplitPath preserves the "~" while this code computes the
+	 * actual full path name, if we had just a single component.
+	 */
+
+	splitPtr = Tcl_FSSplitPath(pathPtr, &splitElements);
+	Tcl_IncrRefCount(splitPtr);
+	if (splitElements == 1  &&  TclGetString(pathPtr)[0] == '~') {
+	    Tcl_Obj *norm;
+
+	    TclDecrRefCount(splitPtr);
+	    norm = Tcl_FSGetNormalizedPath(interp, pathPtr);
+	    if (norm == NULL) {
+		return NULL;
+	    }
+	    splitPtr = Tcl_FSSplitPath(norm, &splitElements);
+	    Tcl_IncrRefCount(splitPtr);
+	}
+	if (portion == TCL_PATH_TAIL) {
+	    /*
+	     * Return the last component, unless it is the only component, and
+	     * it is the root of an absolute path.
+	     */
+
+	    if ((splitElements > 0) && ((splitElements > 1) ||
+		    (Tcl_FSGetPathType(pathPtr) == TCL_PATH_RELATIVE))) {
+		Tcl_ListObjIndex(NULL, splitPtr, splitElements-1, &resultPtr);
+	    } else {
+		resultPtr = Tcl_NewObj();
+	    }
+	} else {
+	    /*
+	     * Return all but the last component. If there is only one
+	     * component, return it if the path was non-relative, otherwise
+	     * return the current directory.
+	     */
+
+	    if (splitElements > 1) {
+		resultPtr = Tcl_FSJoinPath(splitPtr, splitElements - 1);
+	    } else if (splitElements == 0 ||
+		    (Tcl_FSGetPathType(pathPtr) == TCL_PATH_RELATIVE)) {
+		TclNewLiteralStringObj(resultPtr, ".");
+	    } else {
+		Tcl_ListObjIndex(NULL, splitPtr, 0, &resultPtr);
+	    }
+	}
+	Tcl_IncrRefCount(resultPtr);
+	TclDecrRefCount(splitPtr);
+	return resultPtr;
+    }
+}
+
+/*
+ * Simple helper function
+ */
+
+static Tcl_Obj *
+GetExtension(
+    Tcl_Obj *pathPtr)
+{
+    const char *tail, *extension;
+    Tcl_Obj *ret;
+
+    tail = TclGetString(pathPtr);
+    extension = TclGetExtension(tail);
+    if (extension == NULL) {
+	ret = Tcl_NewObj();
+    } else {
+	ret = Tcl_NewStringObj(extension, -1);
+    }
+    Tcl_IncrRefCount(ret);
+    return ret;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Tcl_FSJoinPath --
+ *
+ *	This function takes the given Tcl_Obj, which should be a valid list,
+ *	and returns the path object given by considering the first 'elements'
+ *	elements as valid path segments (each path segment may be a complete
+ *	path, a partial path or just a single possible directory or file
+ *	name). If any path segment is actually an absolute path, then all
+ *	prior path segments are discarded.
+ *
+ *	If elements < 0, we use the entire list that was given.
+ *
+ *	It is possible that the returned object is actually an element of the
+ *	given list, so the caller should be careful to store a refCount to it
+ *	before freeing the list.
+ *
+ * Results:
+ *	Returns object with refCount of zero, (or if non-zero, it has
+ *	references elsewhere in Tcl). Either way, the caller must increment
+ *	its refCount before use. Note that in the case where the caller has
+ *	asked to join zero elements of the list, the return value will be an
+ *	empty-string Tcl_Obj.
+ *
+ *	If the given listObj was invalid, then the calling routine has a bug,
+ *	and this function will just return NULL.
+ *
+ * Side effects:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+Tcl_Obj *
+Tcl_FSJoinPath(
+    Tcl_Obj *listObj,		/* Path elements to join, may have a zero
+				 * reference count. */
+    int elements)		/* Number of elements to use (-1 = all) */
+{
+    Tcl_Obj *copy, *res;
+    int objc;
+    Tcl_Obj **objv;
+
+    if (Tcl_ListObjLength(NULL, listObj, &objc) != TCL_OK) {
+	return NULL;
+    }
+
+    elements = ((elements >= 0) && (elements <= objc)) ? elements : objc;
+    copy = TclListObjCopy(NULL, listObj);
+    Tcl_ListObjGetElements(NULL, listObj, &objc, &objv);
+    res = TclJoinPath(elements, objv);
+    Tcl_DecrRefCount(copy);
+    return res;
+}
+
+Tcl_Obj *
+TclJoinPath(
+    int elements,
+    Tcl_Obj * const objv[])
+{
+    Tcl_Obj *res;
+    int i;
+    const Tcl_Filesystem *fsPtr = NULL;
+
+    res = NULL;
+
+    for (i = 0; i < elements; i++) {
+	int driveNameLength, strEltLen, length;
+	Tcl_PathType type;
+	char *strElt, *ptr;
+	Tcl_Obj *driveName = NULL;
+	Tcl_Obj *elt = objv[i];
+
+	/*
+	 * This is a special case where we can be much more efficient, where
+	 * we are joining a single relative path onto an object that is
+	 * already of path type. The 'TclNewFSPathObj' call below creates an
+	 * object which can be normalized more efficiently. Currently we only
+	 * use the special case when we have exactly two elements, but we
+	 * could expand that in the future.
+         *
+         * Bugfix [a47641a0]. TclNewFSPathObj requires first argument
+         * to be an absolute path. Added a check for that elt is absolute.
+	 */
+
+	if ((i == (elements-2)) && (i == 0)
+                && (elt->typePtr == &tclFsPathType)
+		&& !((elt->bytes != NULL) && (elt->bytes[0] == '\0'))
+                && TclGetPathType(elt, NULL, NULL, NULL) == TCL_PATH_ABSOLUTE) {
+            Tcl_Obj *tailObj = objv[i+1];
+
+	    type = TclGetPathType(tailObj, NULL, NULL, NULL);
+	    if (type == TCL_PATH_RELATIVE) {
+		const char *str;
+		int len;
+
+		str = Tcl_GetStringFromObj(tailObj, &len);
+		if (len == 0) {
+		    /*
+		     * This happens if we try to handle the root volume '/'.
+		     * There's no need to return a special path object, when
+		     * the base itself is just fine!
+		     */
+
+		    if (res != NULL) {
+			TclDecrRefCount(res);
+		    }
+		    return elt;
+		}
+
+		/*
+		 * If it doesn't begin with '.' and is a unix path or it a
+		 * windows path without backslashes, then we can be very
+		 * efficient here. (In fact even a windows path with
+		 * backslashes can be joined efficiently, but the path object
+		 * would not have forward slashes only, and this would
+		 * therefore contradict our 'file join' documentation).
+		 */
+
+		if (str[0] != '.' && ((tclPlatform != TCL_PLATFORM_WINDOWS)
+			|| (strchr(str, '\\') == NULL))) {
+		    /*
+		     * Finally, on Windows, 'file join' is defined to convert
+		     * all backslashes to forward slashes, so the base part
+		     * cannot have backslashes either.
+		     */
+
+		    if ((tclPlatform != TCL_PLATFORM_WINDOWS)
+			    || (strchr(Tcl_GetString(elt), '\\') == NULL)) {
+			if (res != NULL) {
+			    TclDecrRefCount(res);
+			}
+			return TclNewFSPathObj(elt, str, len);
+		    }
+		}
+
+		/*
+		 * Otherwise we don't have an easy join, and we must let the
+		 * more general code below handle things.
+		 */
+	    } else if (tclPlatform == TCL_PLATFORM_UNIX) {
+		if (res != NULL) {
+		    TclDecrRefCount(res);
+		}
+		return tailObj;
+	    } else {
+		const char *str = TclGetString(tailObj);
+
+		if (tclPlatform == TCL_PLATFORM_WINDOWS) {
+		    if (strchr(str, '\\') == NULL) {
+			if (res != NULL) {
+			    TclDecrRefCount(res);
+			}
+			return tailObj;
+		    }
+		}
+	    }
+	}
+	strElt = Tcl_GetStringFromObj(elt, &strEltLen);
+	type = TclGetPathType(elt, &fsPtr, &driveNameLength, &driveName);
+	if (type != TCL_PATH_RELATIVE) {
+	    /*
+	     * Zero out the current result.
+	     */
+
+	    if (res != NULL) {
+		TclDecrRefCount(res);
+	    }
+
+	    if (driveName != NULL) {
+		/*
+		 * We've been given a separate drive-name object, because the
+		 * prefix in 'elt' is not in a suitable format for us (e.g. it
+		 * may contain irrelevant multiple separators, like
+		 * C://///foo).
+		 */
+
+		res = Tcl_DuplicateObj(driveName);
+		TclDecrRefCount(driveName);
+
+		/*
+		 * Do not set driveName to NULL, because we will check its
+		 * value below (but we won't access the contents, since those
+		 * have been cleaned-up).
+		 */
+	    } else {
+		res = Tcl_NewStringObj(strElt, driveNameLength);
+	    }
+	    strElt += driveNameLength;
+	} else if (driveName != NULL) {
+	    Tcl_DecrRefCount(driveName);
+	}
+
+	/*
+	 * Optimisation block: if this is the last element to be examined, and
+	 * it is absolute or the only element, and the drive-prefix was ok (if
+	 * there is one), it might be that the path is already in a suitable
+	 * form to be returned. Then we can short-cut the rest of this
+	 * function.
+	 */
+
+	if ((driveName == NULL) && (i == (elements - 1))
+		&& (type != TCL_PATH_RELATIVE || res == NULL)) {
+	    /*
+	     * It's the last path segment. Perform a quick check if the path
+	     * is already in a suitable form.
+	     */
+
+	    if (tclPlatform == TCL_PLATFORM_WINDOWS) {
+		if (strchr(strElt, '\\') != NULL) {
+		    goto noQuickReturn;
+		}
+	    }
+	    ptr = strElt;
+	    while (*ptr != '\0') {
+		if (*ptr == '/' && (ptr[1] == '/' || ptr[1] == '\0')) {
+		    /*
+		     * We have a repeated file separator, which means the path
+		     * is not in normalized form
+		     */
+
+		    goto noQuickReturn;
+		}
+		ptr++;
+	    }
+	    if (res != NULL) {
+		TclDecrRefCount(res);
+	    }
+
+	    /*
+	     * This element is just what we want to return already; no further
+	     * manipulation is requred.
+	     */
+
+	    return elt;
+	}
+
+	/*
+	 * The path element was not of a suitable form to be returned as is.
+	 * We need to perform a more complex operation here.
+	 */
+
+    noQuickReturn:
+	if (res == NULL) {
+	    res = Tcl_NewObj();
+	    ptr = Tcl_GetStringFromObj(res, &length);
+	} else {
+	    ptr = Tcl_GetStringFromObj(res, &length);
+	}
+
+	/*
+	 * Strip off any './' before a tilde, unless this is the beginning of
+	 * the path.
+	 */
+
+	if (length > 0 && strEltLen > 0 && (strElt[0] == '.') &&
+		(strElt[1] == '/') && (strElt[2] == '~')) {
+	    strElt += 2;
+	}
+
+	/*
+	 * A NULL value for fsPtr at this stage basically means we're trying
+	 * to join a relative path onto something which is also relative (or
+	 * empty). There's nothing particularly wrong with that.
+	 */
+
+	if (*strElt == '\0') {
+	    continue;
+	}
+
+	if (fsPtr == &tclNativeFilesystem || fsPtr == NULL) {
+	    TclpNativeJoinPath(res, strElt);
+	} else {
+	    char separator = '/';
+	    int needsSep = 0;
+
+	    if (fsPtr->filesystemSeparatorProc != NULL) {
+		Tcl_Obj *sep = fsPtr->filesystemSeparatorProc(res);
+
+		if (sep != NULL) {
+		    separator = TclGetString(sep)[0];
+		}
+		/* Safety check in case the VFS driver caused sharing */
+		if (Tcl_IsShared(res)) {
+		    TclDecrRefCount(res);
+		    res = Tcl_DuplicateObj(res);
+		    Tcl_IncrRefCount(res);
+		}
+	    }
+
+	    if (length > 0 && ptr[length -1] != '/') {
+		Tcl_AppendToObj(res, &separator, 1);
+		Tcl_GetStringFromObj(res, &length);
+	    }
+	    Tcl_SetObjLength(res, length + (int) strlen(strElt));
+
+	    ptr = TclGetString(res) + length;
+	    for (; *strElt != '\0'; strElt++) {
+		if (*strElt == separator) {
+		    while (strElt[1] == separator) {
+			strElt++;
+		    }
+		    if (strElt[1] != '\0') {
+			if (needsSep) {
+			    *ptr++ = separator;
+			}
+		    }
+		} else {
+		    *ptr++ = *strElt;
+		    needsSep = 1;
+		}
+	    }
+	    length = ptr - TclGetString(res);
+	    Tcl_SetObjLength(res, length);
+	}
+    }
+    if (res == NULL) {
+	res = Tcl_NewObj();
+    }
+    return res;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Tcl_FSConvertToPathType --
+ *
+ *	This function tries to convert the given Tcl_Obj to a valid Tcl path
+ *	type, taking account of the fact that the cwd may have changed even if
+ *	this object is already supposedly of the correct type.
+ *
+ *	The filename may begin with "~" (to indicate current user's home
+ *	directory) or "~<user>" (to indicate any user's home directory).
+ *
+ * Results:
+ *	Standard Tcl error code.
+ *
+ * Side effects:
+ *	The old representation may be freed, and new memory allocated.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+int
+Tcl_FSConvertToPathType(
+    Tcl_Interp *interp,		/* Interpreter in which to store error message
+				 * (if necessary). */
+    Tcl_Obj *pathPtr)		/* Object to convert to a valid, current path
+				 * type. */
+{
+    /*
+     * While it is bad practice to examine an object's type directly, this is
+     * actually the best thing to do here. The reason is that if we are
+     * converting this object to FsPath type for the first time, we don't need
+     * to worry whether the 'cwd' has changed. On the other hand, if this
+     * object is already of FsPath type, and is a relative path, we do have to
+     * worry about the cwd. If the cwd has changed, we must recompute the
+     * path.
+     */
+
+    if (pathPtr->typePtr == &tclFsPathType) {
+	if (TclFSEpochOk(PATHOBJ(pathPtr)->filesystemEpoch)) {
+	    return TCL_OK;
+	}
+
+	if (pathPtr->bytes == NULL) {
+	    UpdateStringOfFsPath(pathPtr);
+	}
+	FreeFsPathInternalRep(pathPtr);
+    }
+
+    return SetFsPathFromAny(interp, pathPtr);
+
+    /*
+     * We used to have more complex code here:
+     *
+     * FsPath *fsPathPtr = PATHOBJ(pathPtr);
+     * if (fsPathPtr->cwdPtr == NULL || PATHFLAGS(pathPtr) != 0) {
+     *     return TCL_OK;
+     * } else {
+     *     if (TclFSCwdPointerEquals(&fsPathPtr->cwdPtr)) {
+     *         return TCL_OK;
+     *     } else {
+     *         if (pathPtr->bytes == NULL) {
+     *             UpdateStringOfFsPath(pathPtr);
+     *         }
+     *         FreeFsPathInternalRep(pathPtr);
+     *         return Tcl_ConvertToType(interp, pathPtr, &tclFsPathType);
+     *     }
+     * }
+     *
+     * But we no longer believe this is necessary.
+     */
+}
+
+/*
+ * Helper function for normalization.
+ */
+
+static int
+IsSeparatorOrNull(
+    int ch)
+{
+    if (ch == 0) {
+	return 1;
+    }
+    switch (tclPlatform) {
+    case TCL_PLATFORM_UNIX:
+	return (ch == '/' ? 1 : 0);
+    case TCL_PLATFORM_WINDOWS:
+	return ((ch == '/' || ch == '\\') ? 1 : 0);
+    }
+    return 0;
+}
+
+/*
+ * Helper function for SetFsPathFromAny. Returns position of first directory
+ * delimiter in the path. If no separator is found, then returns the position
+ * of the end of the string.
+ */
+
+static int
+FindSplitPos(
+    const char *path,
+    int separator)
+{
+    int count = 0;
+    switch (tclPlatform) {
+    case TCL_PLATFORM_UNIX:
+	while (path[count] != 0) {
+	    if (path[count] == separator) {
+		return count;
+	    }
+	    count++;
+	}
+	break;
+
+    case TCL_PLATFORM_WINDOWS:
+	while (path[count] != 0) {
+	    if (path[count] == separator || path[count] == '\\') {
+		return count;
+	    }
+	    count++;
+	}
+	break;
+    }
+    return count;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * TclNewFSPathObj --
+ *
+ *	Creates a path object whose string representation is '[file join
+ *	dirPtr addStrRep]', but does so in a way that allows for more
+ *	efficient creation and caching of normalized paths, and more efficient
+ *	'file dirname', 'file tail', etc.
+ *
+ * Assumptions:
+ *	'dirPtr' must be an absolute path. 'len' may not be zero.
+ *
+ * Results:
+ *	The new Tcl object, with refCount zero.
+ *
+ * Side effects:
+ *	Memory is allocated. 'dirPtr' gets an additional refCount.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+Tcl_Obj *
+TclNewFSPathObj(
+    Tcl_Obj *dirPtr,
+    const char *addStrRep,
+    int len)
+{
+    FsPath *fsPathPtr;
+    Tcl_Obj *pathPtr;
+    const char *p;
+    int state = 0, count = 0;
+
+    /* [Bug 2806250] - this is only a partial solution of the problem.
+     * The PATHFLAGS != 0 representation assumes in many places that
+     * the "tail" part stored in the normPathPtr field is itself a
+     * relative path.  Strings that begin with "~" are not relative paths,
+     * so we must prevent their storage in the normPathPtr field.
+     *
+     * More generally we ought to be testing "addStrRep" for any value
+     * that is not a relative path, but in an unconstrained VFS world
+     * that could be just about anything, and testing could be expensive.
+     * Since this routine plays a big role in [glob], anything that slows
+     * it down would be unwelcome.  For now, continue the risk of further
+     * bugs when some Tcl_Filesystem uses otherwise relative path strings
+     * as absolute path strings.  Sensible Tcl_Filesystems will avoid
+     * that by mounting on path prefixes like foo:// which cannot be the
+     * name of a file or directory read from a native [glob] operation.
+     */
+    if (addStrRep[0] == '~') {
+	Tcl_Obj *tail = Tcl_NewStringObj(addStrRep, len);
+
+	pathPtr = AppendPath(dirPtr, tail);
+	Tcl_DecrRefCount(tail);
+	return pathPtr;
+    }
+
+    pathPtr = Tcl_NewObj();
+    fsPathPtr = ckalloc(sizeof(FsPath));
+
+    /*
+     * Set up the path.
+     */
+
+    fsPathPtr->translatedPathPtr = NULL;
+    fsPathPtr->normPathPtr = Tcl_NewStringObj(addStrRep, len);
+    Tcl_IncrRefCount(fsPathPtr->normPathPtr);
+    fsPathPtr->cwdPtr = dirPtr;
+    Tcl_IncrRefCount(dirPtr);
+    fsPathPtr->nativePathPtr = NULL;
+    fsPathPtr->fsPtr = NULL;
+    fsPathPtr->filesystemEpoch = 0;
+
+    SETPATHOBJ(pathPtr, fsPathPtr);
+    PATHFLAGS(pathPtr) = TCLPATH_APPENDED;
+    pathPtr->typePtr = &tclFsPathType;
+    pathPtr->bytes = NULL;
+    pathPtr->length = 0;
+
+    /*
+     * Look for path components made up of only "."
+     * This is overly conservative analysis to keep simple. It may mark some
+     * things as needing more aggressive normalization that don't actually
+     * need it. No harm done.
+     */
+    for (p = addStrRep; len > 0; p++, len--) {
+	switch (state) {
+	case 0:		/* So far only "." since last dirsep or start */
+	    switch (*p) {
+	    case '.':
+		count++;
+		break;
+	    case '/':
+	    case '\\':
+	    case ':':
+		if (count) {
+		    PATHFLAGS(pathPtr) |= TCLPATH_NEEDNORM;
+		    len = 0;
+		}
+		break;
+	    default:
+		count = 0;
+		state = 1;
+	    }
+	case 1:		/* Scanning for next dirsep */
+	    switch (*p) {
+	    case '/':
+	    case '\\':
+	    case ':':
+		state = 0;
+		break;
+	    }
+	}
+    }
+    if (len == 0 && count) {
+	PATHFLAGS(pathPtr) |= TCLPATH_NEEDNORM;
+    }
+
+    return pathPtr;
+}
+
+static Tcl_Obj *
+AppendPath(
+    Tcl_Obj *head,
+    Tcl_Obj *tail)
+{
+    int numBytes;
+    const char *bytes;
+    Tcl_Obj *copy = Tcl_DuplicateObj(head);
+
+    /*
+     * This is likely buggy when dealing with virtual filesystem drivers
+     * that use some character other than "/" as a path separator.  I know
+     * of no evidence that such a foolish thing exists.  This solution was
+     * chosen so that "JoinPath" operations that pass through either path
+     * intrep produce the same results; that is, bugward compatibility.  If
+     * we need to fix that bug here, it needs fixing in TclJoinPath() too.
+     */
+    bytes = Tcl_GetStringFromObj(tail, &numBytes);
+    if (numBytes == 0) {
+	Tcl_AppendToObj(copy, "/", 1);
+    } else {
+	TclpNativeJoinPath(copy, bytes);
+    }
+    return copy;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * TclFSMakePathRelative --
+ *
+ *	Only for internal use.
+ *
+ *	Takes a path and a directory, where we _assume_ both path and
+ *	directory are absolute, normalized and that the path lies inside the
+ *	directory. Returns a Tcl_Obj representing filename of the path
+ *	relative to the directory.
+ *
+ * Results:
+ *	NULL on error, otherwise a valid object, typically with refCount of
+ *	zero, which it is assumed the caller will increment.
+ *
+ * Side effects:
+ *	The old representation may be freed, and new memory allocated.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+Tcl_Obj *
+TclFSMakePathRelative(
+    Tcl_Interp *interp,		/* Used for error reporting if not NULL. */
+    Tcl_Obj *pathPtr,		/* The path we have. */
+    Tcl_Obj *cwdPtr)		/* Make it relative to this. */
+{
+    int cwdLen, len;
+    const char *tempStr;
+
+    if (pathPtr->typePtr == &tclFsPathType) {
+	FsPath *fsPathPtr = PATHOBJ(pathPtr);
+
+	if (PATHFLAGS(pathPtr) != 0 && fsPathPtr->cwdPtr == cwdPtr) {
+	    return fsPathPtr->normPathPtr;
+	}
+    }
+
+    /*
+     * We know the cwd is a normalised object which does not end in a
+     * directory delimiter, unless the cwd is the name of a volume, in which
+     * case it will end in a delimiter! We handle this situation here. A
+     * better test than the '!= sep' might be to simply check if 'cwd' is a
+     * root volume.
+     *
+     * Note that if we get this wrong, we will strip off either too much or
+     * too little below, leading to wrong answers returned by glob.
+     */
+
+    tempStr = Tcl_GetStringFromObj(cwdPtr, &cwdLen);
+
+    /*
+     * Should we perhaps use 'Tcl_FSPathSeparator'? But then what about the
+     * Windows special case? Perhaps we should just check if cwd is a root
+     * volume.
+     */
+
+    switch (tclPlatform) {
+    case TCL_PLATFORM_UNIX:
+	if (tempStr[cwdLen-1] != '/') {
+	    cwdLen++;
+	}
+	break;
+    case TCL_PLATFORM_WINDOWS:
+	if (tempStr[cwdLen-1] != '/' && tempStr[cwdLen-1] != '\\') {
+	    cwdLen++;
+	}
+	break;
+    }
+    tempStr = Tcl_GetStringFromObj(pathPtr, &len);
+
+    return Tcl_NewStringObj(tempStr + cwdLen, len - cwdLen);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * MakePathFromNormalized --
+ *
+ *	Like SetFsPathFromAny, but assumes the given object is an absolute
+ *	normalized path. Only for internal use.
+ *
+ * Results:
+ *	Standard Tcl error code.
+ *
+ * Side effects:
+ *	The old representation may be freed, and new memory allocated.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+static int
+MakePathFromNormalized(
+    Tcl_Interp *interp,		/* Used for error reporting if not NULL. */
+    Tcl_Obj *pathPtr)		/* The object to convert. */
+{
+    FsPath *fsPathPtr;
+
+    if (pathPtr->typePtr == &tclFsPathType) {
+	return TCL_OK;
+    }
+
+    /*
+     * Free old representation
+     */
+
+    if (pathPtr->typePtr != NULL) {
+	if (pathPtr->bytes == NULL) {
+	    if (pathPtr->typePtr->updateStringProc == NULL) {
+		if (interp != NULL) {
+		    Tcl_SetObjResult(interp, Tcl_NewStringObj(
+			    "can't find object string representation", -1));
+		    Tcl_SetErrorCode(interp, "TCL", "VALUE", "PATH", "WTF",
+			    NULL);
+		}
+		return TCL_ERROR;
+	    }
+	    pathPtr->typePtr->updateStringProc(pathPtr);
+	}
+	TclFreeIntRep(pathPtr);
+    }
+
+    fsPathPtr = ckalloc(sizeof(FsPath));
+
+    /*
+     * It's a pure normalized absolute path.
+     */
+
+    fsPathPtr->translatedPathPtr = NULL;
+
+    /*
+     * Circular reference by design.
+     */
+
+    fsPathPtr->normPathPtr = pathPtr;
+    fsPathPtr->cwdPtr = NULL;
+    fsPathPtr->nativePathPtr = NULL;
+    fsPathPtr->fsPtr = NULL;
+    /* Remember the epoch under which we decided pathPtr was normalized */
+    fsPathPtr->filesystemEpoch = TclFSEpoch();
+
+    SETPATHOBJ(pathPtr, fsPathPtr);
+    PATHFLAGS(pathPtr) = 0;
+    pathPtr->typePtr = &tclFsPathType;
+
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Tcl_FSNewNativePath --
+ *
+ *	This function performs the something like the reverse of the usual
+ *	obj->path->nativerep conversions. If some code retrieves a path in
+ *	native form (from, e.g. readlink or a native dialog), and that path is
+ *	to be used at the Tcl level, then calling this function is an
+ *	efficient way of creating the appropriate path object type.
+ *
+ *	Any memory which is allocated for 'clientData' should be retained
+ *	until clientData is passed to the filesystem's freeInternalRepProc
+ *	when it can be freed. The built in platform-specific filesystems use
+ *	'ckalloc' to allocate clientData, and ckfree to free it.
+ *
+ * Results:
+ *	NULL or a valid path object pointer, with refCount zero.
+ *
+ * Side effects:
+ *	New memory may be allocated.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+Tcl_Obj *
+Tcl_FSNewNativePath(
+    const Tcl_Filesystem *fromFilesystem,
+    ClientData clientData)
+{
+    Tcl_Obj *pathPtr = NULL;
+    FsPath *fsPathPtr;
+
+
+    if (fromFilesystem->internalToNormalizedProc != NULL) {
+	pathPtr = (*fromFilesystem->internalToNormalizedProc)(clientData);
+    }
+    if (pathPtr == NULL) {
+	return NULL;
+    }
+
+    /*
+     * Free old representation; shouldn't normally be any, but best to be
+     * safe.
+     */
+
+    if (pathPtr->typePtr != NULL) {
+	if (pathPtr->bytes == NULL) {
+	    if (pathPtr->typePtr->updateStringProc == NULL) {
+		return NULL;
+	    }
+	    pathPtr->typePtr->updateStringProc(pathPtr);
+	}
+	TclFreeIntRep(pathPtr);
+    }
+
+    fsPathPtr = ckalloc(sizeof(FsPath));
+
+    fsPathPtr->translatedPathPtr = NULL;
+
+    /*
+     * Circular reference, by design.
+     */
+
+    fsPathPtr->normPathPtr = pathPtr;
+    fsPathPtr->cwdPtr = NULL;
+    fsPathPtr->nativePathPtr = clientData;
+    fsPathPtr->fsPtr = fromFilesystem;
+    fsPathPtr->filesystemEpoch = TclFSEpoch();
+
+    SETPATHOBJ(pathPtr, fsPathPtr);
+    PATHFLAGS(pathPtr) = 0;
+    pathPtr->typePtr = &tclFsPathType;
+
+    return pathPtr;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Tcl_FSGetTranslatedPath --
+ *
+ *	This function attempts to extract the translated path from the given
+ *	Tcl_Obj. If the translation succeeds (i.e. the object is a valid
+ *	path), then it is returned. Otherwise NULL will be returned, and an
+ *	error message may be left in the interpreter (if it is non-NULL)
+ *
+ * Results:
+ *	NULL or a valid Tcl_Obj pointer.
+ *
+ * Side effects:
+ *	Only those of 'Tcl_FSConvertToPathType'
+ *
+ *---------------------------------------------------------------------------
+ */
+
+Tcl_Obj *
+Tcl_FSGetTranslatedPath(
+    Tcl_Interp *interp,
+    Tcl_Obj *pathPtr)
+{
+    Tcl_Obj *retObj = NULL;
+    FsPath *srcFsPathPtr;
+
+    if (Tcl_FSConvertToPathType(interp, pathPtr) != TCL_OK) {
+	return NULL;
+    }
+    srcFsPathPtr = PATHOBJ(pathPtr);
+    if (srcFsPathPtr->translatedPathPtr == NULL) {
+	if (PATHFLAGS(pathPtr) != 0) {
+	    /*
+	     * We lack a translated path result, but we have a directory
+	     * (cwdPtr) and a tail (normPathPtr), and if we join the
+	     * translated version of cwdPtr to normPathPtr, we'll get the
+	     * translated result we need, and can store it for future use.
+	     */
+
+	    Tcl_Obj *translatedCwdPtr = Tcl_FSGetTranslatedPath(interp,
+		    srcFsPathPtr->cwdPtr);
+	    if (translatedCwdPtr == NULL) {
+		return NULL;
+	    }
+
+	    retObj = Tcl_FSJoinToPath(translatedCwdPtr, 1,
+		    &srcFsPathPtr->normPathPtr);
+	    srcFsPathPtr->translatedPathPtr = retObj;
+	    if (translatedCwdPtr->typePtr == &tclFsPathType) {
+		srcFsPathPtr->filesystemEpoch
+			= PATHOBJ(translatedCwdPtr)->filesystemEpoch;
+	    } else {
+		srcFsPathPtr->filesystemEpoch = 0;
+	    }
+	    Tcl_IncrRefCount(retObj);
+	    Tcl_DecrRefCount(translatedCwdPtr);
+	} else {
+	    /*
+	     * It is a pure absolute, normalized path object. This is
+	     * something like being a 'pure list'. The object's string,
+	     * translatedPath and normalizedPath are all identical.
+	     */
+
+	    retObj = srcFsPathPtr->normPathPtr;
+	}
+    } else {
+	/*
+	 * It is an ordinary path object.
+	 */
+
+	retObj = srcFsPathPtr->translatedPathPtr;
+    }
+
+    if (retObj != NULL) {
+	Tcl_IncrRefCount(retObj);
+    }
+    return retObj;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Tcl_FSGetTranslatedStringPath --
+ *
+ *	This function attempts to extract the translated path from the given
+ *	Tcl_Obj. If the translation succeeds (i.e. the object is a valid
+ *	path), then the path is returned. Otherwise NULL will be returned, and
+ *	an error message may be left in the interpreter (if it is non-NULL)
+ *
+ * Results:
+ *	NULL or a valid string.
+ *
+ * Side effects:
+ *	Only those of 'Tcl_FSConvertToPathType'
+ *
+ *---------------------------------------------------------------------------
+ */
+
+const char *
+Tcl_FSGetTranslatedStringPath(
+    Tcl_Interp *interp,
+    Tcl_Obj *pathPtr)
+{
+    Tcl_Obj *transPtr = Tcl_FSGetTranslatedPath(interp, pathPtr);
+
+    if (transPtr != NULL) {
+	int len;
+	const char *orig = Tcl_GetStringFromObj(transPtr, &len);
+	char *result = ckalloc(len+1);
+
+	memcpy(result, orig, (size_t) len+1);
+	TclDecrRefCount(transPtr);
+	return result;
+    }
+
+    return NULL;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Tcl_FSGetNormalizedPath --
+ *
+ *	This important function attempts to extract from the given Tcl_Obj a
+ *	unique normalised path representation, whose string value can be used
+ *	as a unique identifier for the file.
+ *
+ * Results:
+ *	NULL or a valid path object pointer.
+ *
+ * Side effects:
+ *	New memory may be allocated. The Tcl 'errno' may be modified in the
+ *	process of trying to examine various path possibilities.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+Tcl_Obj *
+Tcl_FSGetNormalizedPath(
+    Tcl_Interp *interp,
+    Tcl_Obj *pathPtr)
+{
+    FsPath *fsPathPtr;
+
+    if (Tcl_FSConvertToPathType(interp, pathPtr) != TCL_OK) {
+	return NULL;
+    }
+    fsPathPtr = PATHOBJ(pathPtr);
+
+    if (PATHFLAGS(pathPtr) != 0) {
+	/*
+	 * This is a special path object which is the result of something like
+	 * 'file join'
+	 */
+
+	Tcl_Obj *dir, *copy;
+	int tailLen, cwdLen, pathType;
+
+	pathType = Tcl_FSGetPathType(fsPathPtr->cwdPtr);
+	dir = Tcl_FSGetNormalizedPath(interp, fsPathPtr->cwdPtr);
+	if (dir == NULL) {
+	    return NULL;
+	}
+	/* TODO: Figure out why this is needed. */
+	if (pathPtr->bytes == NULL) {
+	    UpdateStringOfFsPath(pathPtr);
+	}
+
+	Tcl_GetStringFromObj(fsPathPtr->normPathPtr, &tailLen);
+	if (tailLen) {
+	    copy = AppendPath(dir, fsPathPtr->normPathPtr);
+	} else {
+	    copy = Tcl_DuplicateObj(dir);
+	}
+	Tcl_IncrRefCount(dir);
+	Tcl_IncrRefCount(copy);
+
+	/*
+	 * We now own a reference on both 'dir' and 'copy'
+	 */
+
+	(void) Tcl_GetStringFromObj(dir, &cwdLen);
+	cwdLen += (Tcl_GetString(copy)[cwdLen] == '/');
+
+	/* Normalize the combined string. */
+
+	if (PATHFLAGS(pathPtr) & TCLPATH_NEEDNORM) {
+	    /*
+	     * If the "tail" part has components (like /../) that cause the
+	     * combined path to need more complete normalizing, call on the
+	     * more powerful routine to accomplish that so we avoid [Bug
+	     * 2385549] ...
+	     */
+
+	    Tcl_Obj *newCopy = TclFSNormalizeAbsolutePath(interp, copy);
+
+	    Tcl_DecrRefCount(copy);
+	    copy = newCopy;
+	} else {
+	    /*
+	     * ... but in most cases where we join a trouble free tail to a
+	     * normalized head, we can more efficiently normalize the combined
+	     * path by passing over only the unnormalized tail portion. When
+	     * this is sufficient, prior developers claim this should be much
+	     * faster. We use 'cwdLen-1' so that we are already pointing at
+	     * the dir-separator that we know about. The normalization code
+	     * will actually start off directly after that separator.
+	     */
+
+	    TclFSNormalizeToUniquePath(interp, copy, cwdLen-1);
+	}
+
+	/* Now we need to construct the new path object. */
+
+	if (pathType == TCL_PATH_RELATIVE) {
+	    Tcl_Obj *origDir = fsPathPtr->cwdPtr;
+
+	    /*
+	     * NOTE: here we are (dangerously?) assuming that origDir points
+	     * to a Tcl_Obj with Tcl_ObjType == &tclFsPathType. The
+	     *     pathType = Tcl_FSGetPathType(fsPathPtr->cwdPtr);
+	     * above that set the pathType value should have established that,
+	     * but it's far less clear on what basis we know there's been no
+	     * shimmering since then.
+	     */
+
+	    FsPath *origDirFsPathPtr = PATHOBJ(origDir);
+
+	    fsPathPtr->cwdPtr = origDirFsPathPtr->cwdPtr;
+	    Tcl_IncrRefCount(fsPathPtr->cwdPtr);
+
+	    TclDecrRefCount(fsPathPtr->normPathPtr);
+	    fsPathPtr->normPathPtr = copy;
+
+	    /*
+	     * That's our reference to copy used.
+	     */
+
+	    TclDecrRefCount(dir);
+	    TclDecrRefCount(origDir);
+	} else {
+	    TclDecrRefCount(fsPathPtr->cwdPtr);
+	    fsPathPtr->cwdPtr = NULL;
+	    TclDecrRefCount(fsPathPtr->normPathPtr);
+	    fsPathPtr->normPathPtr = copy;
+
+	    /*
+	     * That's our reference to copy used.
+	     */
+
+	    TclDecrRefCount(dir);
+	}
+	PATHFLAGS(pathPtr) = 0;
+    }
+
+    /*
+     * Ensure cwd hasn't changed.
+     */
+
+    if (fsPathPtr->cwdPtr != NULL) {
+	if (!TclFSCwdPointerEquals(&fsPathPtr->cwdPtr)) {
+	    if (pathPtr->bytes == NULL) {
+		UpdateStringOfFsPath(pathPtr);
+	    }
+	    FreeFsPathInternalRep(pathPtr);
+	    if (SetFsPathFromAny(interp, pathPtr) != TCL_OK) {
+		return NULL;
+	    }
+	    fsPathPtr = PATHOBJ(pathPtr);
+	} else if (fsPathPtr->normPathPtr == NULL) {
+	    int cwdLen;
+	    Tcl_Obj *copy;
+
+	    copy = AppendPath(fsPathPtr->cwdPtr, pathPtr);
+
+	    (void) Tcl_GetStringFromObj(fsPathPtr->cwdPtr, &cwdLen);
+	    cwdLen += (Tcl_GetString(copy)[cwdLen] == '/');
+
+	    /*
+	     * Normalize the combined string, but only starting after the end
+	     * of the previously normalized 'dir'. This should be much faster!
+	     */
+
+	    TclFSNormalizeToUniquePath(interp, copy, cwdLen-1);
+	    fsPathPtr->normPathPtr = copy;
+	    Tcl_IncrRefCount(fsPathPtr->normPathPtr);
+	}
+    }
+    if (fsPathPtr->normPathPtr == NULL) {
+	Tcl_Obj *useThisCwd = NULL;
+	int pureNormalized = 1;
+
+	/*
+	 * Since normPathPtr is NULL, but this is a valid path object, we know
+	 * that the translatedPathPtr cannot be NULL.
+	 */
+
+	Tcl_Obj *absolutePath = fsPathPtr->translatedPathPtr;
+	const char *path = TclGetString(absolutePath);
+
+	Tcl_IncrRefCount(absolutePath);
+
+	/*
+	 * We have to be a little bit careful here to avoid infinite loops
+	 * we're asking Tcl_FSGetPathType to return the path's type, but that
+	 * call can actually result in a lot of other filesystem action, which
+	 * might loop back through here.
+	 */
+
+	if (path[0] == '\0') {
+	    /*
+	     * Special handling for the empty string value. This one is very
+	     * weird with [file normalize {}] => {}. (The reasoning supporting
+	     * this is unknown to DGP, but he fears changing it.) Attempt here
+	     * to keep the expectations of other parts of Tcl_Filesystem code
+	     * about state of the FsPath fields satisfied.
+	     *
+	     * In particular, capture the cwd value and save so it can be
+	     * stored in the cwdPtr field below.
+	     */
+
+	    useThisCwd = Tcl_FSGetCwd(interp);
+	} else {
+	    /*
+	     * We don't ask for the type of 'pathPtr' here, because that is
+	     * not correct for our purposes when we have a path like '~'. Tcl
+	     * has a bit of a contradiction in that '~' paths are defined as
+	     * 'absolute', but in reality can be just about anything,
+	     * depending on how env(HOME) is set.
+	     */
+
+	    Tcl_PathType type = Tcl_FSGetPathType(absolutePath);
+
+	    if (type == TCL_PATH_RELATIVE) {
+		useThisCwd = Tcl_FSGetCwd(interp);
+
+		if (useThisCwd == NULL) {
+		    return NULL;
+		}
+
+		pureNormalized = 0;
+		Tcl_DecrRefCount(absolutePath);
+		absolutePath = Tcl_FSJoinToPath(useThisCwd, 1, &absolutePath);
+		Tcl_IncrRefCount(absolutePath);
+
+		/*
+		 * We have a refCount on the cwd.
+		 */
+#ifdef _WIN32
+	    } else if (type == TCL_PATH_VOLUME_RELATIVE) {
+		/*
+		 * Only Windows has volume-relative paths.
+		 */
+
+		Tcl_DecrRefCount(absolutePath);
+		absolutePath = TclWinVolumeRelativeNormalize(interp,
+			path, &useThisCwd);
+		if (absolutePath == NULL) {
+		    return NULL;
+		}
+		pureNormalized = 0;
+#endif /* _WIN32 */
+	    }
+	}
+
+	/*
+	 * Already has refCount incremented.
+	 */
+
+	fsPathPtr->normPathPtr = TclFSNormalizeAbsolutePath(interp,
+		absolutePath);
+
+	/*
+	 * Check if path is pure normalized (this can only be the case if it
+	 * is an absolute path).
+	 */
+
+	if (pureNormalized) {
+	    int normPathLen, pathLen;
+	    const char *normPath;
+
+	    path = TclGetStringFromObj(pathPtr, &pathLen);
+	    normPath = TclGetStringFromObj(fsPathPtr->normPathPtr, &normPathLen);
+	    if ((pathLen == normPathLen) && !memcmp(path, normPath, pathLen)) {
+		/*
+		 * The path was already normalized. Get rid of the duplicate.
+		 */
+
+		TclDecrRefCount(fsPathPtr->normPathPtr);
+
+		/*
+		 * We do *not* increment the refCount for this circular
+		 * reference.
+		 */
+
+		fsPathPtr->normPathPtr = pathPtr;
+	    }
+	}
+	if (useThisCwd != NULL) {
+	    /*
+	     * We just need to free an object we allocated above for relative
+	     * paths (this was returned by Tcl_FSJoinToPath above), and then
+	     * of course store the cwd.
+	     */
+
+	    fsPathPtr->cwdPtr = useThisCwd;
+	}
+	TclDecrRefCount(absolutePath);
+    }
+
+    return fsPathPtr->normPathPtr;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Tcl_FSGetInternalRep --
+ *
+ *	Extract the internal representation of a given path object, in the
+ *	given filesystem. If the path object belongs to a different
+ *	filesystem, we return NULL.
+ *
+ *	If the internal representation is currently NULL, we attempt to
+ *	generate it, by calling the filesystem's
+ *	'Tcl_FSCreateInternalRepProc'.
+ *
+ * Results:
+ *	NULL or a valid internal representation.
+ *
+ * Side effects:
+ *	An attempt may be made to convert the object.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+ClientData
+Tcl_FSGetInternalRep(
+    Tcl_Obj *pathPtr,
+    const Tcl_Filesystem *fsPtr)
+{
+    FsPath *srcFsPathPtr;
+
+    if (Tcl_FSConvertToPathType(NULL, pathPtr) != TCL_OK) {
+	return NULL;
+    }
+    srcFsPathPtr = PATHOBJ(pathPtr);
+
+    /*
+     * We will only return the native representation for the caller's
+     * filesystem. Otherwise we will simply return NULL. This means that there
+     * must be a unique bi-directional mapping between paths and filesystems,
+     * and that this mapping will not allow 'remapped' files -- files which
+     * are in one filesystem but mapped into another. Another way of putting
+     * this is that 'stacked' filesystems are not allowed. We recognise that
+     * this is a potentially useful feature for the future.
+     *
+     * Even something simple like a 'pass through' filesystem which logs all
+     * activity and passes the calls onto the native system would be nice, but
+     * not easily achievable with the current implementation.
+     */
+
+    if (srcFsPathPtr->fsPtr == NULL) {
+	/*
+	 * This only usually happens in wrappers like TclpStat which create a
+	 * string object and pass it to TclpObjStat. Code which calls the
+	 * Tcl_FS.. functions should always have a filesystem already set.
+	 * Whether this code path is legal or not depends on whether we decide
+	 * to allow external code to call the native filesystem directly. It
+	 * is at least safer to allow this sub-optimal routing.
+	 */
+
+	Tcl_FSGetFileSystemForPath(pathPtr);
+
+	/*
+	 * If we fail through here, then the path is probably not a valid path
+	 * in the filesystsem, and is most likely to be a use of the empty
+	 * path "" via a direct call to one of the objectified interfaces
+	 * (e.g. from the Tcl testsuite).
+	 */
+
+	srcFsPathPtr = PATHOBJ(pathPtr);
+	if (srcFsPathPtr->fsPtr == NULL) {
+	    return NULL;
+	}
+    }
+
+    /*
+     * There is still one possibility we should consider; if the file belongs
+     * to a different filesystem, perhaps it is actually linked through to a
+     * file in our own filesystem which we do care about. The way we can check
+     * for this is we ask what filesystem this path belongs to.
+     */
+
+    if (fsPtr != srcFsPathPtr->fsPtr) {
+	const Tcl_Filesystem *actualFs = Tcl_FSGetFileSystemForPath(pathPtr);
+
+	if (actualFs == fsPtr) {
+	    return Tcl_FSGetInternalRep(pathPtr, fsPtr);
+	}
+	return NULL;
+    }
+
+    if (srcFsPathPtr->nativePathPtr == NULL) {
+	Tcl_FSCreateInternalRepProc *proc;
+	char *nativePathPtr;
+
+	proc = srcFsPathPtr->fsPtr->createInternalRepProc;
+	if (proc == NULL) {
+	    return NULL;
+	}
+
+	nativePathPtr = proc(pathPtr);
+	srcFsPathPtr = PATHOBJ(pathPtr);
+	srcFsPathPtr->nativePathPtr = nativePathPtr;
+    }
+
+    return srcFsPathPtr->nativePathPtr;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * TclFSEnsureEpochOk --
+ *
+ *	This will ensure the pathPtr is up to date and can be converted into a
+ *	"path" type, and that we are able to generate a complete normalized
+ *	path which is used to determine the filesystem match.
+ *
+ * Results:
+ *	Standard Tcl return code.
+ *
+ * Side effects:
+ *	An attempt may be made to convert the object.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+int
+TclFSEnsureEpochOk(
+    Tcl_Obj *pathPtr,
+    const Tcl_Filesystem **fsPtrPtr)
+{
+    FsPath *srcFsPathPtr;
+
+    if (pathPtr->typePtr != &tclFsPathType) {
+	return TCL_OK;
+    }
+
+    srcFsPathPtr = PATHOBJ(pathPtr);
+
+    /*
+     * Check if the filesystem has changed in some way since this object's
+     * internal representation was calculated.
+     */
+
+    if (!TclFSEpochOk(srcFsPathPtr->filesystemEpoch)) {
+	/*
+	 * We have to discard the stale representation and recalculate it.
+	 */
+
+	if (pathPtr->bytes == NULL) {
+	    UpdateStringOfFsPath(pathPtr);
+	}
+	FreeFsPathInternalRep(pathPtr);
+	if (SetFsPathFromAny(NULL, pathPtr) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	srcFsPathPtr = PATHOBJ(pathPtr);
+    }
+
+    /*
+     * Check whether the object is already assigned to a fs.
+     */
+
+    if (srcFsPathPtr->fsPtr != NULL) {
+	*fsPtrPtr = srcFsPathPtr->fsPtr;
+    }
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * TclFSSetPathDetails --
+ *
+ *	???
+ *
+ * Results:
+ *	None
+ *
+ * Side effects:
+ *	???
+ *
+ *---------------------------------------------------------------------------
+ */
+
+void
+TclFSSetPathDetails(
+    Tcl_Obj *pathPtr,
+    const Tcl_Filesystem *fsPtr,
+    ClientData clientData)
+{
+    FsPath *srcFsPathPtr;
+
+    /*
+     * Make sure pathPtr is of the correct type.
+     */
+
+    if (pathPtr->typePtr != &tclFsPathType) {
+	if (SetFsPathFromAny(NULL, pathPtr) != TCL_OK) {
+	    return;
+	}
+    }
+
+    srcFsPathPtr = PATHOBJ(pathPtr);
+    srcFsPathPtr->fsPtr = fsPtr;
+    srcFsPathPtr->nativePathPtr = clientData;
+    srcFsPathPtr->filesystemEpoch = TclFSEpoch();
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Tcl_FSEqualPaths --
+ *
+ *	This function tests whether the two paths given are equal path
+ *	objects. If either or both is NULL, 0 is always returned.
+ *
+ * Results:
+ *	1 or 0.
+ *
+ * Side effects:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+int
+Tcl_FSEqualPaths(
+    Tcl_Obj *firstPtr,
+    Tcl_Obj *secondPtr)
+{
+    const char *firstStr, *secondStr;
+    int firstLen, secondLen, tempErrno;
+
+    if (firstPtr == secondPtr) {
+	return 1;
+    }
+
+    if (firstPtr == NULL || secondPtr == NULL) {
+	return 0;
+    }
+    firstStr = TclGetStringFromObj(firstPtr, &firstLen);
+    secondStr = TclGetStringFromObj(secondPtr, &secondLen);
+    if ((firstLen == secondLen) && !memcmp(firstStr, secondStr, firstLen)) {
+	return 1;
+    }
+
+    /*
+     * Try the most thorough, correct method of comparing fully normalized
+     * paths.
+     */
+
+    tempErrno = Tcl_GetErrno();
+    firstPtr = Tcl_FSGetNormalizedPath(NULL, firstPtr);
+    secondPtr = Tcl_FSGetNormalizedPath(NULL, secondPtr);
+    Tcl_SetErrno(tempErrno);
+
+    if (firstPtr == NULL || secondPtr == NULL) {
+	return 0;
+    }
+
+    firstStr = TclGetStringFromObj(firstPtr, &firstLen);
+    secondStr = TclGetStringFromObj(secondPtr, &secondLen);
+    return ((firstLen == secondLen) && !memcmp(firstStr, secondStr, firstLen));
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * SetFsPathFromAny --
+ *
+ *	This function tries to convert the given Tcl_Obj to a valid Tcl path
+ *	type.
+ *
+ *	The filename may begin with "~" (to indicate current user's home
+ *	directory) or "~<user>" (to indicate any user's home directory).
+ *
+ * Results:
+ *	Standard Tcl error code.
+ *
+ * Side effects:
+ *	The old representation may be freed, and new memory allocated.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+static int
+SetFsPathFromAny(
+    Tcl_Interp *interp,		/* Used for error reporting if not NULL. */
+    Tcl_Obj *pathPtr)		/* The object to convert. */
+{
+    int len;
+    FsPath *fsPathPtr;
+    Tcl_Obj *transPtr;
+    char *name;
+
+    if (pathPtr->typePtr == &tclFsPathType) {
+	return TCL_OK;
+    }
+
+    /*
+     * First step is to translate the filename. This is similar to
+     * Tcl_TranslateFilename, but shouldn't convert everything to windows
+     * backslashes on that platform. The current implementation of this piece
+     * is a slightly optimised version of the various Tilde/Split/Join stuff
+     * to avoid multiple split/join operations.
+     *
+     * We remove any trailing directory separator.
+     *
+     * However, the split/join routines are quite complex, and one has to make
+     * sure not to break anything on Unix or Win (fCmd.test, fileName.test and
+     * cmdAH.test exercise most of the code).
+     */
+
+    name = Tcl_GetStringFromObj(pathPtr, &len);
+
+    /*
+     * Handle tilde substitutions, if needed.
+     */
+
+    if (name[0] == '~') {
+	Tcl_DString temp;
+	int split;
+	char separator = '/';
+
+	split = FindSplitPos(name, separator);
+	if (split != len) {
+	    /*
+	     * We have multiple pieces '~user/foo/bar...'
+	     */
+
+	    name[split] = '\0';
+	}
+
+	/*
+	 * Do some tilde substitution.
+	 */
+
+	if (name[1] == '\0') {
+	    /*
+	     * We have just '~'
+	     */
+
+	    const char *dir;
+	    Tcl_DString dirString;
+
+	    if (split != len) {
+		name[split] = separator;
+	    }
+
+	    dir = TclGetEnv("HOME", &dirString);
+	    if (dir == NULL) {
+		if (interp) {
+		    Tcl_SetObjResult(interp, Tcl_NewStringObj(
+			    "couldn't find HOME environment variable to"
+			    " expand path", -1));
+		    Tcl_SetErrorCode(interp, "TCL", "VALUE", "PATH",
+			    "HOMELESS", NULL);
+		}
+		return TCL_ERROR;
+	    }
+	    Tcl_DStringInit(&temp);
+	    Tcl_JoinPath(1, &dir, &temp);
+	    Tcl_DStringFree(&dirString);
+	} else {
+	    /*
+	     * We have a user name '~user'
+	     */
+
+	    Tcl_DStringInit(&temp);
+	    if (TclpGetUserHome(name+1, &temp) == NULL) {
+		if (interp != NULL) {
+		    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+			    "user \"%s\" doesn't exist", name+1));
+		    Tcl_SetErrorCode(interp, "TCL", "VALUE", "PATH", "NOUSER",
+			    NULL);
+		}
+		Tcl_DStringFree(&temp);
+		if (split != len) {
+		    name[split] = separator;
+		}
+		return TCL_ERROR;
+	    }
+	    if (split != len) {
+		name[split] = separator;
+	    }
+	}
+
+	transPtr = TclDStringToObj(&temp);
+
+	if (split != len) {
+	    /*
+	     * Join up the tilde substitution with the rest.
+	     */
+
+	    if (name[split+1] == separator) {
+		/*
+		 * Somewhat tricky case like ~//foo/bar. Make use of
+		 * Split/Join machinery to get it right. Assumes all paths
+		 * beginning with ~ are part of the native filesystem.
+		 */
+
+		int objc;
+		Tcl_Obj **objv;
+		Tcl_Obj *parts = TclpNativeSplitPath(pathPtr, NULL);
+
+		Tcl_ListObjGetElements(NULL, parts, &objc, &objv);
+
+		/*
+		 * Skip '~'. It's replaced by its expansion.
+		 */
+
+		objc--; objv++;
+		while (objc--) {
+		    TclpNativeJoinPath(transPtr, Tcl_GetString(*objv++));
+		}
+		TclDecrRefCount(parts);
+	    } else {
+		Tcl_Obj *pair[2];
+
+		pair[0] = transPtr;
+		pair[1] = Tcl_NewStringObj(name+split+1, -1);
+		transPtr = TclJoinPath(2, pair);
+		Tcl_DecrRefCount(pair[0]);
+		Tcl_DecrRefCount(pair[1]);
+	    }
+	}
+    } else {
+	transPtr = TclJoinPath(1, &pathPtr);
+    }
+
+    /*
+     * Now we have a translated filename in 'transPtr'. This will have forward
+     * slashes on Windows, and will not contain any ~user sequences.
+     */
+
+    fsPathPtr = ckalloc(sizeof(FsPath));
+
+    fsPathPtr->translatedPathPtr = transPtr;
+    if (transPtr != pathPtr) {
+	Tcl_IncrRefCount(fsPathPtr->translatedPathPtr);
+	/* Redo translation when $env(HOME) changes */
+	fsPathPtr->filesystemEpoch = TclFSEpoch();
+    } else {
+	fsPathPtr->filesystemEpoch = 0;
+    }
+    fsPathPtr->normPathPtr = NULL;
+    fsPathPtr->cwdPtr = NULL;
+    fsPathPtr->nativePathPtr = NULL;
+    fsPathPtr->fsPtr = NULL;
+
+    /*
+     * Free old representation before installing our new one.
+     */
+
+    TclFreeIntRep(pathPtr);
+    SETPATHOBJ(pathPtr, fsPathPtr);
+    PATHFLAGS(pathPtr) = 0;
+    pathPtr->typePtr = &tclFsPathType;
+    return TCL_OK;
+}
+
+static void
+FreeFsPathInternalRep(
+    Tcl_Obj *pathPtr)		/* Path object with internal rep to free. */
+{
+    FsPath *fsPathPtr = PATHOBJ(pathPtr);
+
+    if (fsPathPtr->translatedPathPtr != NULL) {
+	if (fsPathPtr->translatedPathPtr != pathPtr) {
+	    TclDecrRefCount(fsPathPtr->translatedPathPtr);
+	}
+    }
+    if (fsPathPtr->normPathPtr != NULL) {
+	if (fsPathPtr->normPathPtr != pathPtr) {
+	    TclDecrRefCount(fsPathPtr->normPathPtr);
+	}
+	fsPathPtr->normPathPtr = NULL;
+    }
+    if (fsPathPtr->cwdPtr != NULL) {
+	TclDecrRefCount(fsPathPtr->cwdPtr);
+    }
+    if (fsPathPtr->nativePathPtr != NULL && fsPathPtr->fsPtr != NULL) {
+	Tcl_FSFreeInternalRepProc *freeProc =
+		fsPathPtr->fsPtr->freeInternalRepProc;
+
+	if (freeProc != NULL) {
+	    freeProc(fsPathPtr->nativePathPtr);
+	    fsPathPtr->nativePathPtr = NULL;
+	}
+    }
+
+    ckfree(fsPathPtr);
+    pathPtr->typePtr = NULL;
+}
+
+static void
+DupFsPathInternalRep(
+    Tcl_Obj *srcPtr,		/* Path obj with internal rep to copy. */
+    Tcl_Obj *copyPtr)		/* Path obj with internal rep to set. */
+{
+    FsPath *srcFsPathPtr = PATHOBJ(srcPtr);
+    FsPath *copyFsPathPtr = ckalloc(sizeof(FsPath));
+
+    SETPATHOBJ(copyPtr, copyFsPathPtr);
+
+    if (srcFsPathPtr->translatedPathPtr == srcPtr) {
+	/* Cycle in src -> make cycle in copy. */
+	copyFsPathPtr->translatedPathPtr = copyPtr;
+    } else {
+	copyFsPathPtr->translatedPathPtr = srcFsPathPtr->translatedPathPtr;
+	if (copyFsPathPtr->translatedPathPtr != NULL) {
+	    Tcl_IncrRefCount(copyFsPathPtr->translatedPathPtr);
+	}
+    }
+
+    if (srcFsPathPtr->normPathPtr == srcPtr) {
+	/* Cycle in src -> make cycle in copy. */
+	copyFsPathPtr->normPathPtr = copyPtr;
+    } else {
+	copyFsPathPtr->normPathPtr = srcFsPathPtr->normPathPtr;
+	if (copyFsPathPtr->normPathPtr != NULL) {
+	    Tcl_IncrRefCount(copyFsPathPtr->normPathPtr);
+	}
+    }
+
+    copyFsPathPtr->cwdPtr = srcFsPathPtr->cwdPtr;
+    if (copyFsPathPtr->cwdPtr != NULL) {
+	Tcl_IncrRefCount(copyFsPathPtr->cwdPtr);
+    }
+
+    copyFsPathPtr->flags = srcFsPathPtr->flags;
+
+    if (srcFsPathPtr->fsPtr != NULL
+	    && srcFsPathPtr->nativePathPtr != NULL) {
+	Tcl_FSDupInternalRepProc *dupProc =
+		srcFsPathPtr->fsPtr->dupInternalRepProc;
+
+	if (dupProc != NULL) {
+	    copyFsPathPtr->nativePathPtr =
+		    dupProc(srcFsPathPtr->nativePathPtr);
+	} else {
+	    copyFsPathPtr->nativePathPtr = NULL;
+	}
+    } else {
+	copyFsPathPtr->nativePathPtr = NULL;
+    }
+    copyFsPathPtr->fsPtr = srcFsPathPtr->fsPtr;
+    copyFsPathPtr->filesystemEpoch = srcFsPathPtr->filesystemEpoch;
+
+    copyPtr->typePtr = &tclFsPathType;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * UpdateStringOfFsPath --
+ *
+ *	Gives an object a valid string rep.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Memory may be allocated.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+static void
+UpdateStringOfFsPath(
+    register Tcl_Obj *pathPtr)	/* path obj with string rep to update. */
+{
+    FsPath *fsPathPtr = PATHOBJ(pathPtr);
+    int cwdLen;
+    Tcl_Obj *copy;
+
+    if (PATHFLAGS(pathPtr) == 0 || fsPathPtr->cwdPtr == NULL) {
+	Tcl_Panic("Called UpdateStringOfFsPath with invalid object");
+    }
+
+    copy = AppendPath(fsPathPtr->cwdPtr, fsPathPtr->normPathPtr);
+
+    pathPtr->bytes = Tcl_GetStringFromObj(copy, &cwdLen);
+    pathPtr->length = cwdLen;
+    copy->bytes = tclEmptyStringRep;
+    copy->length = 0;
+    TclDecrRefCount(copy);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * TclNativePathInFilesystem --
+ *
+ *	Any path object is acceptable to the native filesystem, by default (we
+ *	will throw errors when illegal paths are actually tried to be used).
+ *
+ *	However, this behavior means the native filesystem must be the last
+ *	filesystem in the lookup list (otherwise it will claim all files
+ *	belong to it, and other filesystems will never get a look in).
+ *
+ * Results:
+ *	TCL_OK, to indicate 'yes', -1 to indicate no.
+ *
+ * Side effects:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+int
+TclNativePathInFilesystem(
+    Tcl_Obj *pathPtr,
+    ClientData *clientDataPtr)
+{
+    /*
+     * A special case is required to handle the empty path "". This is a valid
+     * path (i.e. the user should be able to do 'file exists ""' without
+     * throwing an error), but equally the path doesn't exist. Those are the
+     * semantics of Tcl (at present anyway), so we have to abide by them here.
+     */
+
+    if (pathPtr->typePtr == &tclFsPathType) {
+	if (pathPtr->bytes != NULL && pathPtr->bytes[0] == '\0') {
+	    /*
+	     * We reject the empty path "".
+	     */
+
+	    return -1;
+	}
+
+	/*
+	 * Otherwise there is no way this path can be empty.
+	 */
+    } else {
+	/*
+	 * It is somewhat unusual to reach this code path without the object
+	 * being of tclFsPathType. However, we do our best to deal with the
+	 * situation.
+	 */
+
+	int len;
+
+	(void) Tcl_GetStringFromObj(pathPtr, &len);
+	if (len == 0) {
+	    /*
+	     * We reject the empty path "".
+	     */
+
+	    return -1;
+	}
+    }
+
+    /*
+     * Path is of correct type, or is of non-zero length, so we accept it.
+     */
+
+    return TCL_OK;
+}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tclPipe.c b/generic/tclPipe.c
new file mode 100644
index 0000000..83fb818
--- /dev/null
+++ b/generic/tclPipe.c
@@ -0,0 +1,1135 @@
+/*
+ * tclPipe.c --
+ *
+ *	This file contains the generic portion of the command channel driver
+ *	as well as various utility routines used in managing subprocesses.
+ *
+ * Copyright (c) 1997 by Sun Microsystems, Inc.
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#include "tclInt.h"
+
+/*
+ * A linked list of the following structures is used to keep track of child
+ * processes that have been detached but haven't exited yet, so we can make
+ * sure that they're properly "reaped" (officially waited for) and don't lie
+ * around as zombies cluttering the system.
+ */
+
+typedef struct Detached {
+    Tcl_Pid pid;		/* Id of process that's been detached but
+				 * isn't known to have exited. */
+    struct Detached *nextPtr;	/* Next in list of all detached processes. */
+} Detached;
+
+static Detached *detList = NULL;/* List of all detached proceses. */
+TCL_DECLARE_MUTEX(pipeMutex)	/* Guard access to detList. */
+
+/*
+ * Declarations for local functions defined in this file:
+ */
+
+static TclFile		FileForRedirect(Tcl_Interp *interp, const char *spec,
+			    int atOk, const char *arg, const char *nextArg,
+			    int flags, int *skipPtr, int *closePtr,
+			    int *releasePtr);
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * FileForRedirect --
+ *
+ *	This function does much of the work of parsing redirection operators.
+ *	It handles "@" if specified and allowed, and a file name, and opens
+ *	the file if necessary.
+ *
+ * Results:
+ *	The return value is the descriptor number for the file. If an error
+ *	occurs then NULL is returned and an error message is left in the
+ *	interp's result. Several arguments are side-effected; see the argument
+ *	list below for details.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static TclFile
+FileForRedirect(
+    Tcl_Interp *interp,		/* Intepreter to use for error reporting. */
+    const char *spec,		/* Points to character just after redirection
+				 * character. */
+    int atOK,			/* Non-zero means that '@' notation can be
+				 * used to specify a channel, zero means that
+				 * it isn't. */
+    const char *arg,		/* Pointer to entire argument containing spec:
+				 * used for error reporting. */
+    const char *nextArg,	/* Next argument in argc/argv array, if needed
+				 * for file name or channel name. May be
+				 * NULL. */
+    int flags,			/* Flags to use for opening file or to specify
+				 * mode for channel. */
+    int *skipPtr,		/* Filled with 1 if redirection target was in
+				 * spec, 2 if it was in nextArg. */
+    int *closePtr,		/* Filled with one if the caller should close
+				 * the file when done with it, zero
+				 * otherwise. */
+    int *releasePtr)
+{
+    int writing = (flags & O_WRONLY);
+    Tcl_Channel chan;
+    TclFile file;
+
+    *skipPtr = 1;
+    if ((atOK != 0) && (*spec == '@')) {
+	spec++;
+	if (*spec == '\0') {
+	    spec = nextArg;
+	    if (spec == NULL) {
+		goto badLastArg;
+	    }
+	    *skipPtr = 2;
+	}
+	chan = Tcl_GetChannel(interp, spec, NULL);
+	if (chan == (Tcl_Channel) NULL) {
+	    return NULL;
+	}
+	file = TclpMakeFile(chan, writing ? TCL_WRITABLE : TCL_READABLE);
+	if (file == NULL) {
+	    Tcl_Obj *msg;
+
+	    Tcl_GetChannelError(chan, &msg);
+	    if (msg) {
+		Tcl_SetObjResult(interp, msg);
+	    } else {
+		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+			"channel \"%s\" wasn't opened for %s",
+			Tcl_GetChannelName(chan),
+			((writing) ? "writing" : "reading")));
+		Tcl_SetErrorCode(interp, "TCL", "OPERATION", "EXEC",
+			"BADCHAN", NULL);
+	    }
+	    return NULL;
+	}
+	*releasePtr = 1;
+	if (writing) {
+	    /*
+	     * Be sure to flush output to the file, so that anything written
+	     * by the child appears after stuff we've already written.
+	     */
+
+	    Tcl_Flush(chan);
+	}
+    } else {
+	const char *name;
+	Tcl_DString nameString;
+
+	if (*spec == '\0') {
+	    spec = nextArg;
+	    if (spec == NULL) {
+		goto badLastArg;
+	    }
+	    *skipPtr = 2;
+	}
+	name = Tcl_TranslateFileName(interp, spec, &nameString);
+	if (name == NULL) {
+	    return NULL;
+	}
+	file = TclpOpenFile(name, flags);
+	Tcl_DStringFree(&nameString);
+	if (file == NULL) {
+	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		    "couldn't %s file \"%s\": %s",
+		    (writing ? "write" : "read"), spec,
+		    Tcl_PosixError(interp)));
+	    return NULL;
+	}
+	*closePtr = 1;
+    }
+    return file;
+
+  badLastArg:
+    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+	    "can't specify \"%s\" as last word in command", arg));
+    Tcl_SetErrorCode(interp, "TCL", "OPERATION", "EXEC", "SYNTAX", NULL);
+    return NULL;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_DetachPids --
+ *
+ *	This function is called to indicate that one or more child processes
+ *	have been placed in background and will never be waited for; they
+ *	should eventually be reaped by Tcl_ReapDetachedProcs.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_DetachPids(
+    int numPids,		/* Number of pids to detach: gives size of
+				 * array pointed to by pidPtr. */
+    Tcl_Pid *pidPtr)		/* Array of pids to detach. */
+{
+    register Detached *detPtr;
+    int i;
+
+    Tcl_MutexLock(&pipeMutex);
+    for (i = 0; i < numPids; i++) {
+	detPtr = ckalloc(sizeof(Detached));
+	detPtr->pid = pidPtr[i];
+	detPtr->nextPtr = detList;
+	detList = detPtr;
+    }
+    Tcl_MutexUnlock(&pipeMutex);
+
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_ReapDetachedProcs --
+ *
+ *	This function checks to see if any detached processes have exited and,
+ *	if so, it "reaps" them by officially waiting on them. It should be
+ *	called "occasionally" to make sure that all detached processes are
+ *	eventually reaped.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Processes are waited on, so that they can be reaped by the system.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_ReapDetachedProcs(void)
+{
+    register Detached *detPtr;
+    Detached *nextPtr, *prevPtr;
+    int status;
+    Tcl_Pid pid;
+
+    Tcl_MutexLock(&pipeMutex);
+    for (detPtr = detList, prevPtr = NULL; detPtr != NULL; ) {
+	pid = Tcl_WaitPid(detPtr->pid, &status, WNOHANG);
+	if ((pid == 0) || ((pid == (Tcl_Pid) -1) && (errno != ECHILD))) {
+	    prevPtr = detPtr;
+	    detPtr = detPtr->nextPtr;
+	    continue;
+	}
+	nextPtr = detPtr->nextPtr;
+	if (prevPtr == NULL) {
+	    detList = detPtr->nextPtr;
+	} else {
+	    prevPtr->nextPtr = detPtr->nextPtr;
+	}
+	ckfree(detPtr);
+	detPtr = nextPtr;
+    }
+    Tcl_MutexUnlock(&pipeMutex);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclCleanupChildren --
+ *
+ *	This is a utility function used to wait for child processes to exit,
+ *	record information about abnormal exits, and then collect any stderr
+ *	output generated by them.
+ *
+ * Results:
+ *	The return value is a standard Tcl result. If anything at weird
+ *	happened with the child processes, TCL_ERROR is returned and a message
+ *	is left in the interp's result.
+ *
+ * Side effects:
+ *	If the last character of the interp's result is a newline, then it is
+ *	removed unless keepNewline is non-zero. File errorId gets closed, and
+ *	pidPtr is freed back to the storage allocator.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclCleanupChildren(
+    Tcl_Interp *interp,		/* Used for error messages. */
+    int numPids,		/* Number of entries in pidPtr array. */
+    Tcl_Pid *pidPtr,		/* Array of process ids of children. */
+    Tcl_Channel errorChan)	/* Channel for file containing stderr output
+				 * from pipeline. NULL means there isn't any
+				 * stderr output. */
+{
+    int result = TCL_OK;
+    int i, abnormalExit, anyErrorInfo;
+    Tcl_Pid pid;
+    int waitStatus;
+    const char *msg;
+    unsigned long resolvedPid;
+
+    abnormalExit = 0;
+    for (i = 0; i < numPids; i++) {
+	/*
+	 * We need to get the resolved pid before we wait on it as the windows
+	 * implementation of Tcl_WaitPid deletes the information such that any
+	 * following calls to TclpGetPid fail.
+	 */
+
+	resolvedPid = TclpGetPid(pidPtr[i]);
+	pid = Tcl_WaitPid(pidPtr[i], &waitStatus, 0);
+	if (pid == (Tcl_Pid) -1) {
+	    result = TCL_ERROR;
+	    if (interp != NULL) {
+		msg = Tcl_PosixError(interp);
+		if (errno == ECHILD) {
+		    /*
+		     * This changeup in message suggested by Mark Diekhans to
+		     * remind people that ECHILD errors can occur on some
+		     * systems if SIGCHLD isn't in its default state.
+		     */
+
+		    msg =
+			"child process lost (is SIGCHLD ignored or trapped?)";
+		}
+		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+			"error waiting for process to exit: %s", msg));
+	    }
+	    continue;
+	}
+
+	/*
+	 * Create error messages for unusual process exits. An extra newline
+	 * gets appended to each error message, but it gets removed below (in
+	 * the same fashion that an extra newline in the command's output is
+	 * removed).
+	 */
+
+	if (!WIFEXITED(waitStatus) || (WEXITSTATUS(waitStatus) != 0)) {
+	    char msg1[TCL_INTEGER_SPACE], msg2[TCL_INTEGER_SPACE];
+
+	    result = TCL_ERROR;
+	    sprintf(msg1, "%lu", resolvedPid);
+	    if (WIFEXITED(waitStatus)) {
+		if (interp != NULL) {
+		    sprintf(msg2, "%u", WEXITSTATUS(waitStatus));
+		    Tcl_SetErrorCode(interp, "CHILDSTATUS", msg1, msg2, NULL);
+		}
+		abnormalExit = 1;
+	    } else if (interp != NULL) {
+		const char *p;
+
+		if (WIFSIGNALED(waitStatus)) {
+		    p = Tcl_SignalMsg(WTERMSIG(waitStatus));
+		    Tcl_SetErrorCode(interp, "CHILDKILLED", msg1,
+			    Tcl_SignalId(WTERMSIG(waitStatus)), p, NULL);
+		    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+			    "child killed: %s\n", p));
+		} else if (WIFSTOPPED(waitStatus)) {
+		    p = Tcl_SignalMsg(WSTOPSIG(waitStatus));
+		    Tcl_SetErrorCode(interp, "CHILDSUSP", msg1,
+			    Tcl_SignalId(WSTOPSIG(waitStatus)), p, NULL);
+		    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+			    "child suspended: %s\n", p));
+		} else {
+		    Tcl_SetObjResult(interp, Tcl_NewStringObj(
+			    "child wait status didn't make sense\n", -1));
+		    Tcl_SetErrorCode(interp, "TCL", "OPERATION", "EXEC",
+			    "ODDWAITRESULT", msg1, NULL);
+		}
+	    }
+	}
+    }
+
+    /*
+     * Read the standard error file. If there's anything there, then return an
+     * error and add the file's contents to the result string.
+     */
+
+    anyErrorInfo = 0;
+    if (errorChan != NULL) {
+	/*
+	 * Make sure we start at the beginning of the file.
+	 */
+
+	if (interp != NULL) {
+	    int count;
+	    Tcl_Obj *objPtr;
+
+	    Tcl_Seek(errorChan, (Tcl_WideInt)0, SEEK_SET);
+	    objPtr = Tcl_NewObj();
+	    count = Tcl_ReadChars(errorChan, objPtr, -1, 0);
+	    if (count < 0) {
+		result = TCL_ERROR;
+		Tcl_DecrRefCount(objPtr);
+		Tcl_ResetResult(interp);
+		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+			"error reading stderr output file: %s",
+			Tcl_PosixError(interp)));
+	    } else if (count > 0) {
+		anyErrorInfo = 1;
+		Tcl_SetObjResult(interp, objPtr);
+		result = TCL_ERROR;
+	    } else {
+		Tcl_DecrRefCount(objPtr);
+	    }
+	}
+	Tcl_Close(NULL, errorChan);
+    }
+
+    /*
+     * If a child exited abnormally but didn't output any error information at
+     * all, generate an error message here.
+     */
+
+    if ((abnormalExit != 0) && (anyErrorInfo == 0) && (interp != NULL)) {
+	Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		"child process exited abnormally", -1));
+    }
+    return result;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclCreatePipeline --
+ *
+ *	Given an argc/argv array, instantiate a pipeline of processes as
+ *	described by the argv.
+ *
+ *	This function is unofficially exported for use by BLT.
+ *
+ * Results:
+ *	The return value is a count of the number of new processes created, or
+ *	-1 if an error occurred while creating the pipeline. *pidArrayPtr is
+ *	filled in with the address of a dynamically allocated array giving the
+ *	ids of all of the processes. It is up to the caller to free this array
+ *	when it isn't needed anymore. If inPipePtr is non-NULL, *inPipePtr is
+ *	filled in with the file id for the input pipe for the pipeline (if
+ *	any): the caller must eventually close this file. If outPipePtr isn't
+ *	NULL, then *outPipePtr is filled in with the file id for the output
+ *	pipe from the pipeline: the caller must close this file. If errFilePtr
+ *	isn't NULL, then *errFilePtr is filled with a file id that may be used
+ *	to read error output after the pipeline completes.
+ *
+ * Side effects:
+ *	Processes and pipes are created.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclCreatePipeline(
+    Tcl_Interp *interp,		/* Interpreter to use for error reporting. */
+    int argc,			/* Number of entries in argv. */
+    const char **argv,		/* Array of strings describing commands in
+				 * pipeline plus I/O redirection with <, <<,
+				 * >, etc. Argv[argc] must be NULL. */
+    Tcl_Pid **pidArrayPtr,	/* Word at *pidArrayPtr gets filled in with
+				 * address of array of pids for processes in
+				 * pipeline (first pid is first process in
+				 * pipeline). */
+    TclFile *inPipePtr,		/* If non-NULL, input to the pipeline comes
+				 * from a pipe (unless overridden by
+				 * redirection in the command). The file id
+				 * with which to write to this pipe is stored
+				 * at *inPipePtr. NULL means command specified
+				 * its own input source. */
+    TclFile *outPipePtr,	/* If non-NULL, output to the pipeline goes to
+				 * a pipe, unless overriden by redirection in
+				 * the command. The file id with which to read
+				 * frome this pipe is stored at *outPipePtr.
+				 * NULL means command specified its own output
+				 * sink. */
+    TclFile *errFilePtr)	/* If non-NULL, all stderr output from the
+				 * pipeline will go to a temporary file
+				 * created here, and a descriptor to read the
+				 * file will be left at *errFilePtr. The file
+				 * will be removed already, so closing this
+				 * descriptor will be the end of the file. If
+				 * this is NULL, then all stderr output goes
+				 * to our stderr. If the pipeline specifies
+				 * redirection then the file will still be
+				 * created but it will never get any data. */
+{
+    Tcl_Pid *pidPtr = NULL;	/* Points to malloc-ed array holding all the
+				 * pids of child processes. */
+    int numPids;		/* Actual number of processes that exist at
+				 * *pidPtr right now. */
+    int cmdCount;		/* Count of number of distinct commands found
+				 * in argc/argv. */
+    const char *inputLiteral = NULL;
+				/* If non-null, then this points to a string
+				 * containing input data (specified via <<) to
+				 * be piped to the first process in the
+				 * pipeline. */
+    TclFile inputFile = NULL;	/* If != NULL, gives file to use as input for
+				 * first process in pipeline (specified via <
+				 * or <@). */
+    int inputClose = 0;		/* If non-zero, then inputFile should be
+				 * closed when cleaning up. */
+    int inputRelease = 0;
+    TclFile outputFile = NULL;	/* Writable file for output from last command
+				 * in pipeline (could be file or pipe). NULL
+				 * means use stdout. */
+    int outputClose = 0;	/* If non-zero, then outputFile should be
+				 * closed when cleaning up. */
+    int outputRelease = 0;
+    TclFile errorFile = NULL;	/* Writable file for error output from all
+				 * commands in pipeline. NULL means use
+				 * stderr. */
+    int errorClose = 0;		/* If non-zero, then errorFile should be
+				 * closed when cleaning up. */
+    int errorRelease = 0;
+    const char *p;
+    const char *nextArg;
+    int skip, lastBar, lastArg, i, j, atOK, flags, needCmd, errorToOutput = 0;
+    Tcl_DString execBuffer;
+    TclFile pipeIn;
+    TclFile curInFile, curOutFile, curErrFile;
+    Tcl_Channel channel;
+
+    if (inPipePtr != NULL) {
+	*inPipePtr = NULL;
+    }
+    if (outPipePtr != NULL) {
+	*outPipePtr = NULL;
+    }
+    if (errFilePtr != NULL) {
+	*errFilePtr = NULL;
+    }
+
+    Tcl_DStringInit(&execBuffer);
+
+    pipeIn = NULL;
+    curInFile = NULL;
+    curOutFile = NULL;
+    numPids = 0;
+
+    /*
+     * First, scan through all the arguments to figure out the structure of
+     * the pipeline. Process all of the input and output redirection arguments
+     * and remove them from the argument list in the pipeline. Count the
+     * number of distinct processes (it's the number of "|" arguments plus
+     * one) but don't remove the "|" arguments because they'll be used in the
+     * second pass to seperate the individual child processes. Cannot start
+     * the child processes in this pass because the redirection symbols may
+     * appear anywhere in the command line - e.g., the '<' that specifies the
+     * input to the entire pipe may appear at the very end of the argument
+     * list.
+     */
+
+    lastBar = -1;
+    cmdCount = 1;
+    needCmd = 1;
+    for (i = 0; i < argc; i++) {
+	errorToOutput = 0;
+	skip = 0;
+	p = argv[i];
+	switch (*p++) {
+	case '|':
+	    if (*p == '&') {
+		p++;
+	    }
+	    if (*p == '\0') {
+		if ((i == (lastBar + 1)) || (i == (argc - 1))) {
+		    Tcl_SetObjResult(interp, Tcl_NewStringObj(
+			    "illegal use of | or |& in command", -1));
+		    Tcl_SetErrorCode(interp, "TCL", "OPERATION", "EXEC",
+			    "PIPESYNTAX", NULL);
+		    goto error;
+		}
+	    }
+	    lastBar = i;
+	    cmdCount++;
+	    needCmd = 1;
+	    break;
+
+	case '<':
+	    if (inputClose != 0) {
+		inputClose = 0;
+		TclpCloseFile(inputFile);
+	    }
+	    if (inputRelease != 0) {
+		inputRelease = 0;
+		TclpReleaseFile(inputFile);
+	    }
+	    if (*p == '<') {
+		inputFile = NULL;
+		inputLiteral = p + 1;
+		skip = 1;
+		if (*inputLiteral == '\0') {
+		    inputLiteral = ((i + 1) == argc) ? NULL : argv[i + 1];
+		    if (inputLiteral == NULL) {
+			Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+				"can't specify \"%s\" as last word in command",
+				argv[i]));
+			Tcl_SetErrorCode(interp, "TCL", "OPERATION", "EXEC",
+				"PIPESYNTAX", NULL);
+			goto error;
+		    }
+		    skip = 2;
+		}
+	    } else {
+		nextArg = ((i + 1) == argc) ? NULL : argv[i + 1];
+		inputLiteral = NULL;
+		inputFile = FileForRedirect(interp, p, 1, argv[i], nextArg,
+			O_RDONLY, &skip, &inputClose, &inputRelease);
+		if (inputFile == NULL) {
+		    goto error;
+		}
+	    }
+	    break;
+
+	case '>':
+	    atOK = 1;
+	    flags = O_WRONLY | O_CREAT | O_TRUNC;
+	    if (*p == '>') {
+		p++;
+		atOK = 0;
+
+		/*
+		 * Note that the O_APPEND flag only has an effect on POSIX
+		 * platforms. On Windows, we just have to carry on regardless.
+		 */
+
+		flags = O_WRONLY | O_CREAT | O_APPEND;
+	    }
+	    if (*p == '&') {
+		if (errorClose != 0) {
+		    errorClose = 0;
+		    TclpCloseFile(errorFile);
+		}
+		errorToOutput = 1;
+		p++;
+	    }
+
+	    /*
+	     * Close the old output file, but only if the error file is not
+	     * also using it.
+	     */
+
+	    if (outputClose != 0) {
+		outputClose = 0;
+		if (errorFile == outputFile) {
+		    errorClose = 1;
+		} else {
+		    TclpCloseFile(outputFile);
+		}
+	    }
+	    if (outputRelease != 0) {
+		outputRelease = 0;
+		if (errorFile == outputFile) {
+		    errorRelease = 1;
+		} else {
+		    TclpReleaseFile(outputFile);
+		}
+	    }
+	    nextArg = ((i + 1) == argc) ? NULL : argv[i + 1];
+	    outputFile = FileForRedirect(interp, p, atOK, argv[i], nextArg,
+		    flags, &skip, &outputClose, &outputRelease);
+	    if (outputFile == NULL) {
+		goto error;
+	    }
+	    if (errorToOutput) {
+		if (errorClose != 0) {
+		    errorClose = 0;
+		    TclpCloseFile(errorFile);
+		}
+		if (errorRelease != 0) {
+		    errorRelease = 0;
+		    TclpReleaseFile(errorFile);
+		}
+		errorFile = outputFile;
+	    }
+	    break;
+
+	case '2':
+	    if (*p != '>') {
+		break;
+	    }
+	    p++;
+	    atOK = 1;
+	    flags = O_WRONLY | O_CREAT | O_TRUNC;
+	    if (*p == '>') {
+		p++;
+		atOK = 0;
+		flags = O_WRONLY | O_CREAT;
+	    }
+	    if (errorClose != 0) {
+		errorClose = 0;
+		TclpCloseFile(errorFile);
+	    }
+	    if (errorRelease != 0) {
+		errorRelease = 0;
+		TclpReleaseFile(errorFile);
+	    }
+	    if (atOK && p[0] == '@' && p[1] == '1' && p[2] == '\0') {
+		/*
+		 * Special case handling of 2>@1 to redirect stderr to the
+		 * exec/open output pipe as well. This is meant for the end of
+		 * the command string, otherwise use |& between commands.
+		 */
+
+		if (i != argc-1) {
+		    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+			    "must specify \"%s\" as last word in command",
+			    argv[i]));
+		    Tcl_SetErrorCode(interp, "TCL", "OPERATION", "EXEC",
+			    "PIPESYNTAX", NULL);
+		    goto error;
+		}
+		errorFile = outputFile;
+		errorToOutput = 2;
+		skip = 1;
+	    } else {
+		nextArg = ((i + 1) == argc) ? NULL : argv[i + 1];
+		errorFile = FileForRedirect(interp, p, atOK, argv[i],
+			nextArg, flags, &skip, &errorClose, &errorRelease);
+		if (errorFile == NULL) {
+		    goto error;
+		}
+	    }
+	    break;
+
+	default:
+	    /*
+	     * Got a command word, not a redirection.
+	     */
+
+	    needCmd = 0;
+	    break;
+	}
+
+	if (skip != 0) {
+	    for (j = i + skip; j < argc; j++) {
+		argv[j - skip] = argv[j];
+	    }
+	    argc -= skip;
+	    i -= 1;
+	}
+    }
+
+    if (needCmd) {
+	/*
+	 * We had a bar followed only by redirections.
+	 */
+
+	Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		"illegal use of | or |& in command", -1));
+	Tcl_SetErrorCode(interp, "TCL", "OPERATION", "EXEC", "PIPESYNTAX",
+		NULL);
+	goto error;
+    }
+
+    if (inputFile == NULL) {
+	if (inputLiteral != NULL) {
+	    /*
+	     * The input for the first process is immediate data coming from
+	     * Tcl. Create a temporary file for it and put the data into the
+	     * file.
+	     */
+
+	    inputFile = TclpCreateTempFile(inputLiteral);
+	    if (inputFile == NULL) {
+		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+			"couldn't create input file for command: %s",
+			Tcl_PosixError(interp)));
+		goto error;
+	    }
+	    inputClose = 1;
+	} else if (inPipePtr != NULL) {
+	    /*
+	     * The input for the first process in the pipeline is to come from
+	     * a pipe that can be written from by the caller.
+	     */
+
+	    if (TclpCreatePipe(&inputFile, inPipePtr) == 0) {
+		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+			"couldn't create input pipe for command: %s",
+			Tcl_PosixError(interp)));
+		goto error;
+	    }
+	    inputClose = 1;
+	} else {
+	    /*
+	     * The input for the first process comes from stdin.
+	     */
+
+	    channel = Tcl_GetStdChannel(TCL_STDIN);
+	    if (channel != NULL) {
+		inputFile = TclpMakeFile(channel, TCL_READABLE);
+		if (inputFile != NULL) {
+		    inputRelease = 1;
+		}
+	    }
+	}
+    }
+
+    if (outputFile == NULL) {
+	if (outPipePtr != NULL) {
+	    /*
+	     * Output from the last process in the pipeline is to go to a pipe
+	     * that can be read by the caller.
+	     */
+
+	    if (TclpCreatePipe(outPipePtr, &outputFile) == 0) {
+		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+			"couldn't create output pipe for command: %s",
+			Tcl_PosixError(interp)));
+		goto error;
+	    }
+	    outputClose = 1;
+	} else {
+	    /*
+	     * The output for the last process goes to stdout.
+	     */
+
+	    channel = Tcl_GetStdChannel(TCL_STDOUT);
+	    if (channel) {
+		outputFile = TclpMakeFile(channel, TCL_WRITABLE);
+		if (outputFile != NULL) {
+		    outputRelease = 1;
+		}
+	    }
+	}
+    }
+
+    if (errorFile == NULL) {
+	if (errorToOutput == 2) {
+	    /*
+	     * Handle 2>@1 special case at end of cmd line.
+	     */
+
+	    errorFile = outputFile;
+	} else if (errFilePtr != NULL) {
+	    /*
+	     * Set up the standard error output sink for the pipeline, if
+	     * requested. Use a temporary file which is opened, then deleted.
+	     * Could potentially just use pipe, but if it filled up it could
+	     * cause the pipeline to deadlock: we'd be waiting for processes
+	     * to complete before reading stderr, and processes couldn't
+	     * complete because stderr was backed up.
+	     */
+
+	    errorFile = TclpCreateTempFile(NULL);
+	    if (errorFile == NULL) {
+		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+			"couldn't create error file for command: %s",
+			Tcl_PosixError(interp)));
+		goto error;
+	    }
+	    *errFilePtr = errorFile;
+	} else {
+	    /*
+	     * Errors from the pipeline go to stderr.
+	     */
+
+	    channel = Tcl_GetStdChannel(TCL_STDERR);
+	    if (channel) {
+		errorFile = TclpMakeFile(channel, TCL_WRITABLE);
+		if (errorFile != NULL) {
+		    errorRelease = 1;
+		}
+	    }
+	}
+    }
+
+    /*
+     * Scan through the argc array, creating a process for each group of
+     * arguments between the "|" characters.
+     */
+
+    Tcl_ReapDetachedProcs();
+    pidPtr = ckalloc(cmdCount * sizeof(Tcl_Pid));
+
+    curInFile = inputFile;
+
+    for (i = 0; i < argc; i = lastArg + 1) {
+	int result, joinThisError;
+	Tcl_Pid pid;
+	const char *oldName;
+
+	/*
+	 * Convert the program name into native form.
+	 */
+
+	if (Tcl_TranslateFileName(interp, argv[i], &execBuffer) == NULL) {
+	    goto error;
+	}
+
+	/*
+	 * Find the end of the current segment of the pipeline.
+	 */
+
+	joinThisError = 0;
+	for (lastArg = i; lastArg < argc; lastArg++) {
+	    if (argv[lastArg][0] != '|') {
+		continue;
+	    }
+	    if (argv[lastArg][1] == '\0') {
+		break;
+	    }
+	    if ((argv[lastArg][1] == '&') && (argv[lastArg][2] == '\0')) {
+		joinThisError = 1;
+		break;
+	    }
+	}
+
+	/*
+	 * If this is the last segment, use the specified outputFile.
+	 * Otherwise create an intermediate pipe. pipeIn will become the
+	 * curInFile for the next segment of the pipe.
+	 */
+
+	if (lastArg == argc) {
+	    curOutFile = outputFile;
+	} else {
+	    argv[lastArg] = NULL;
+	    if (TclpCreatePipe(&pipeIn, &curOutFile) == 0) {
+		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+			"couldn't create pipe: %s", Tcl_PosixError(interp)));
+		goto error;
+	    }
+	}
+
+	if (joinThisError != 0) {
+	    curErrFile = curOutFile;
+	} else {
+	    curErrFile = errorFile;
+	}
+
+	/*
+	 * Restore argv[i], since a caller wouldn't expect the contents of
+	 * argv to be modified.
+	 */
+
+	oldName = argv[i];
+	argv[i] = Tcl_DStringValue(&execBuffer);
+	result = TclpCreateProcess(interp, lastArg - i, argv + i,
+		curInFile, curOutFile, curErrFile, &pid);
+	argv[i] = oldName;
+	if (result != TCL_OK) {
+	    goto error;
+	}
+	Tcl_DStringFree(&execBuffer);
+
+	pidPtr[numPids] = pid;
+	numPids++;
+
+	/*
+	 * Close off our copies of file descriptors that were set up for this
+	 * child, then set up the input for the next child.
+	 */
+
+	if ((curInFile != NULL) && (curInFile != inputFile)) {
+	    TclpCloseFile(curInFile);
+	}
+	curInFile = pipeIn;
+	pipeIn = NULL;
+
+	if ((curOutFile != NULL) && (curOutFile != outputFile)) {
+	    TclpCloseFile(curOutFile);
+	}
+	curOutFile = NULL;
+    }
+
+    *pidArrayPtr = pidPtr;
+
+    /*
+     * All done. Cleanup open files lying around and then return.
+     */
+
+  cleanup:
+    Tcl_DStringFree(&execBuffer);
+
+    if (inputClose) {
+	TclpCloseFile(inputFile);
+    } else if (inputRelease) {
+	TclpReleaseFile(inputFile);
+    }
+    if (outputClose) {
+	TclpCloseFile(outputFile);
+    } else if (outputRelease) {
+	TclpReleaseFile(outputFile);
+    }
+    if (errorClose) {
+	TclpCloseFile(errorFile);
+    } else if (errorRelease) {
+	TclpReleaseFile(errorFile);
+    }
+    return numPids;
+
+    /*
+     * An error occurred. There could have been extra files open, such as
+     * pipes between children. Clean them all up. Detach any child processes
+     * that have been created.
+     */
+
+  error:
+    if (pipeIn != NULL) {
+	TclpCloseFile(pipeIn);
+    }
+    if ((curOutFile != NULL) && (curOutFile != outputFile)) {
+	TclpCloseFile(curOutFile);
+    }
+    if ((curInFile != NULL) && (curInFile != inputFile)) {
+	TclpCloseFile(curInFile);
+    }
+    if ((inPipePtr != NULL) && (*inPipePtr != NULL)) {
+	TclpCloseFile(*inPipePtr);
+	*inPipePtr = NULL;
+    }
+    if ((outPipePtr != NULL) && (*outPipePtr != NULL)) {
+	TclpCloseFile(*outPipePtr);
+	*outPipePtr = NULL;
+    }
+    if ((errFilePtr != NULL) && (*errFilePtr != NULL)) {
+	TclpCloseFile(*errFilePtr);
+	*errFilePtr = NULL;
+    }
+    if (pidPtr != NULL) {
+	for (i = 0; i < numPids; i++) {
+	    if (pidPtr[i] != (Tcl_Pid) -1) {
+		Tcl_DetachPids(1, &pidPtr[i]);
+	    }
+	}
+	ckfree(pidPtr);
+    }
+    numPids = -1;
+    goto cleanup;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_OpenCommandChannel --
+ *
+ *	Opens an I/O channel to one or more subprocesses specified by argc and
+ *	argv. The flags argument determines the disposition of the stdio
+ *	handles. If the TCL_STDIN flag is set then the standard input for the
+ *	first subprocess will be tied to the channel: writing to the channel
+ *	will provide input to the subprocess. If TCL_STDIN is not set, then
+ *	standard input for the first subprocess will be the same as this
+ *	application's standard input. If TCL_STDOUT is set then standard
+ *	output from the last subprocess can be read from the channel;
+ *	otherwise it goes to this application's standard output. If TCL_STDERR
+ *	is set, standard error output for all subprocesses is returned to the
+ *	channel and results in an error when the channel is closed; otherwise
+ *	it goes to this application's standard error. If TCL_ENFORCE_MODE is
+ *	not set, then argc and argv can redirect the stdio handles to override
+ *	TCL_STDIN, TCL_STDOUT, and TCL_STDERR; if it is set, then it is an
+ *	error for argc and argv to override stdio channels for which
+ *	TCL_STDIN, TCL_STDOUT, and TCL_STDERR have been set.
+ *
+ * Results:
+ *	A new command channel, or NULL on failure with an error message left
+ *	in interp.
+ *
+ * Side effects:
+ *	Creates processes, opens pipes.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_Channel
+Tcl_OpenCommandChannel(
+    Tcl_Interp *interp,		/* Interpreter for error reporting. Can NOT be
+				 * NULL. */
+    int argc,			/* How many arguments. */
+    const char **argv,		/* Array of arguments for command pipe. */
+    int flags)			/* Or'ed combination of TCL_STDIN, TCL_STDOUT,
+				 * TCL_STDERR, and TCL_ENFORCE_MODE. */
+{
+    TclFile *inPipePtr, *outPipePtr, *errFilePtr;
+    TclFile inPipe, outPipe, errFile;
+    int numPids;
+    Tcl_Pid *pidPtr;
+    Tcl_Channel channel;
+
+    inPipe = outPipe = errFile = NULL;
+
+    inPipePtr = (flags & TCL_STDIN) ? &inPipe : NULL;
+    outPipePtr = (flags & TCL_STDOUT) ? &outPipe : NULL;
+    errFilePtr = (flags & TCL_STDERR) ? &errFile : NULL;
+
+    numPids = TclCreatePipeline(interp, argc, argv, &pidPtr, inPipePtr,
+	    outPipePtr, errFilePtr);
+
+    if (numPids < 0) {
+	goto error;
+    }
+
+    /*
+     * Verify that the pipes that were created satisfy the readable/writable
+     * constraints.
+     */
+
+    if (flags & TCL_ENFORCE_MODE) {
+	if ((flags & TCL_STDOUT) && (outPipe == NULL)) {
+	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		    "can't read output from command:"
+		    " standard output was redirected", -1));
+	    Tcl_SetErrorCode(interp, "TCL", "OPERATION", "EXEC",
+		    "BADREDIRECT", NULL);
+	    goto error;
+	}
+	if ((flags & TCL_STDIN) && (inPipe == NULL)) {
+	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		    "can't write input to command:"
+		    " standard input was redirected", -1));
+	    Tcl_SetErrorCode(interp, "TCL", "OPERATION", "EXEC",
+		    "BADREDIRECT", NULL);
+	    goto error;
+	}
+    }
+
+    channel = TclpCreateCommandChannel(outPipe, inPipe, errFile,
+	    numPids, pidPtr);
+
+    if (channel == NULL) {
+	Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		"pipe for command could not be created", -1));
+	Tcl_SetErrorCode(interp, "TCL", "OPERATION", "EXEC", "NOPIPE", NULL);
+	goto error;
+    }
+    return channel;
+
+  error:
+    if (numPids > 0) {
+	Tcl_DetachPids(numPids, pidPtr);
+	ckfree(pidPtr);
+    }
+    if (inPipe != NULL) {
+	TclpCloseFile(inPipe);
+    }
+    if (outPipe != NULL) {
+	TclpCloseFile(outPipe);
+    }
+    if (errFile != NULL) {
+	TclpCloseFile(errFile);
+    }
+    return NULL;
+}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tclPkg.c b/generic/tclPkg.c
new file mode 100644
index 0000000..f6e8b20
--- /dev/null
+++ b/generic/tclPkg.c
@@ -0,0 +1,1923 @@
+/*
+ * tclPkg.c --
+ *
+ *	This file implements package and version control for Tcl via the
+ *	"package" command and a few C APIs.
+ *
+ * Copyright (c) 1996 Sun Microsystems, Inc.
+ * Copyright (c) 2006 Andreas Kupries <andreas_kupries@users.sourceforge.net>
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ *
+ * TIP #268.
+ * Heavily rewritten to handle the extend version numbers, and extended
+ * package requirements.
+ */
+
+#include "tclInt.h"
+
+/*
+ * Each invocation of the "package ifneeded" command creates a structure of
+ * the following type, which is used to load the package into the interpreter
+ * if it is requested with a "package require" command.
+ */
+
+typedef struct PkgAvail {
+    char *version;		/* Version string; malloc'ed. */
+    char *script;		/* Script to invoke to provide this version of
+				 * the package. Malloc'ed and protected by
+				 * Tcl_Preserve and Tcl_Release. */
+    struct PkgAvail *nextPtr;	/* Next in list of available versions of the
+				 * same package. */
+} PkgAvail;
+
+/*
+ * For each package that is known in any way to an interpreter, there is one
+ * record of the following type. These records are stored in the
+ * "packageTable" hash table in the interpreter, keyed by package name such as
+ * "Tk" (no version number).
+ */
+
+typedef struct Package {
+    char *version;		/* Version that has been supplied in this
+				 * interpreter via "package provide"
+				 * (malloc'ed). NULL means the package doesn't
+				 * exist in this interpreter yet. */
+    PkgAvail *availPtr;		/* First in list of all available versions of
+				 * this package. */
+    const void *clientData;	/* Client data. */
+} Package;
+
+/*
+ * Prototypes for functions defined in this file:
+ */
+
+static int		CheckVersionAndConvert(Tcl_Interp *interp,
+			    const char *string, char **internal, int *stable);
+static int		CompareVersions(char *v1i, char *v2i,
+			    int *isMajorPtr);
+static int		CheckRequirement(Tcl_Interp *interp,
+			    const char *string);
+static int		CheckAllRequirements(Tcl_Interp *interp, int reqc,
+			    Tcl_Obj *const reqv[]);
+static int		RequirementSatisfied(char *havei, const char *req);
+static int		SomeRequirementSatisfied(char *havei, int reqc,
+			    Tcl_Obj *const reqv[]);
+static void		AddRequirementsToResult(Tcl_Interp *interp, int reqc,
+			    Tcl_Obj *const reqv[]);
+static void		AddRequirementsToDString(Tcl_DString *dstring,
+			    int reqc, Tcl_Obj *const reqv[]);
+static Package *	FindPackage(Tcl_Interp *interp, const char *name);
+static const char *	PkgRequireCore(Tcl_Interp *interp, const char *name,
+			    int reqc, Tcl_Obj *const reqv[],
+			    void *clientDataPtr);
+
+/*
+ * Helper macros.
+ */
+
+#define DupBlock(v,s,len) \
+    ((v) = ckalloc(len), memcpy((v),(s),(len)))
+#define DupString(v,s) \
+    do { \
+	unsigned local__len = (unsigned) (strlen(s) + 1); \
+	DupBlock((v),(s),local__len); \
+    } while (0)
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_PkgProvide / Tcl_PkgProvideEx --
+ *
+ *	This function is invoked to declare that a particular version of a
+ *	particular package is now present in an interpreter. There must not be
+ *	any other version of this package already provided in the interpreter.
+ *
+ * Results:
+ *	Normally returns TCL_OK; if there is already another version of the
+ *	package loaded then TCL_ERROR is returned and an error message is left
+ *	in the interp's result.
+ *
+ * Side effects:
+ *	The interpreter remembers that this package is available, so that no
+ *	other version of the package may be provided for the interpreter.
+ *
+ *----------------------------------------------------------------------
+ */
+
+#undef Tcl_PkgProvide
+int
+Tcl_PkgProvide(
+    Tcl_Interp *interp,		/* Interpreter in which package is now
+				 * available. */
+    const char *name,		/* Name of package. */
+    const char *version)	/* Version string for package. */
+{
+    return Tcl_PkgProvideEx(interp, name, version, NULL);
+}
+
+int
+Tcl_PkgProvideEx(
+    Tcl_Interp *interp,		/* Interpreter in which package is now
+				 * available. */
+    const char *name,		/* Name of package. */
+    const char *version,	/* Version string for package. */
+    const void *clientData)	/* clientdata for this package (normally used
+				 * for C callback function table) */
+{
+    Package *pkgPtr;
+    char *pvi, *vi;
+    int res;
+
+    pkgPtr = FindPackage(interp, name);
+    if (pkgPtr->version == NULL) {
+	DupString(pkgPtr->version, version);
+	pkgPtr->clientData = clientData;
+	return TCL_OK;
+    }
+
+    if (CheckVersionAndConvert(interp, pkgPtr->version, &pvi,
+	    NULL) != TCL_OK) {
+	return TCL_ERROR;
+    } else if (CheckVersionAndConvert(interp, version, &vi, NULL) != TCL_OK) {
+	ckfree(pvi);
+	return TCL_ERROR;
+    }
+
+    res = CompareVersions(pvi, vi, NULL);
+    ckfree(pvi);
+    ckfree(vi);
+
+    if (res == 0) {
+	if (clientData != NULL) {
+	    pkgPtr->clientData = clientData;
+	}
+	return TCL_OK;
+    }
+    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+	    "conflicting versions provided for package \"%s\": %s, then %s",
+	    name, pkgPtr->version, version));
+    Tcl_SetErrorCode(interp, "TCL", "PACKAGE", "VERSIONCONFLICT", NULL);
+    return TCL_ERROR;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_PkgRequire / Tcl_PkgRequireEx / Tcl_PkgRequireProc --
+ *
+ *	This function is called by code that depends on a particular version
+ *	of a particular package. If the package is not already provided in the
+ *	interpreter, this function invokes a Tcl script to provide it. If the
+ *	package is already provided, this function makes sure that the
+ *	caller's needs don't conflict with the version that is present.
+ *
+ * Results:
+ *	If successful, returns the version string for the currently provided
+ *	version of the package, which may be different from the "version"
+ *	argument. If the caller's requirements cannot be met (e.g. the version
+ *	requested conflicts with a currently provided version, or the required
+ *	version cannot be found, or the script to provide the required version
+ *	generates an error), NULL is returned and an error message is left in
+ *	the interp's result.
+ *
+ * Side effects:
+ *	The script from some previous "package ifneeded" command may be
+ *	invoked to provide the package.
+ *
+ *----------------------------------------------------------------------
+ */
+
+#undef Tcl_PkgRequire
+const char *
+Tcl_PkgRequire(
+    Tcl_Interp *interp,		/* Interpreter in which package is now
+				 * available. */
+    const char *name,		/* Name of desired package. */
+    const char *version,	/* Version string for desired version; NULL
+				 * means use the latest version available. */
+    int exact)			/* Non-zero means that only the particular
+				 * version given is acceptable. Zero means use
+				 * the latest compatible version. */
+{
+    return Tcl_PkgRequireEx(interp, name, version, exact, NULL);
+}
+
+const char *
+Tcl_PkgRequireEx(
+    Tcl_Interp *interp,		/* Interpreter in which package is now
+				 * available. */
+    const char *name,		/* Name of desired package. */
+    const char *version,	/* Version string for desired version; NULL
+				 * means use the latest version available. */
+    int exact,			/* Non-zero means that only the particular
+				 * version given is acceptable. Zero means use
+				 * the latest compatible version. */
+    void *clientDataPtr)	/* Used to return the client data for this
+				 * package. If it is NULL then the client data
+				 * is not returned. This is unchanged if this
+				 * call fails for any reason. */
+{
+    Tcl_Obj *ov;
+    const char *result = NULL;
+
+    /*
+     * If an attempt is being made to load this into a standalone executable
+     * on a platform where backlinking is not supported then this must be a
+     * shared version of Tcl (Otherwise the load would have failed). Detect
+     * this situation by checking that this library has been correctly
+     * initialised. If it has not been then return immediately as nothing will
+     * work.
+     */
+
+    if (tclEmptyStringRep == NULL) {
+	/*
+	 * OK, so what's going on here?
+	 *
+	 * First, what are we doing? We are performing a check on behalf of
+	 * one particular caller, Tcl_InitStubs(). When a package is stub-
+	 * enabled, it is statically linked to libtclstub.a, which contains a
+	 * copy of Tcl_InitStubs(). When a stub-enabled package is loaded, its
+	 * *_Init() function is supposed to call Tcl_InitStubs() before
+	 * calling any other functions in the Tcl library. The first Tcl
+	 * function called by Tcl_InitStubs() through the stub table is
+	 * Tcl_PkgRequireEx(), so this code right here is the first code that
+	 * is part of the original Tcl library in the executable that gets
+	 * executed on behalf of a newly loaded stub-enabled package.
+	 *
+	 * One easy error for the developer/builder of a stub-enabled package
+	 * to make is to forget to define USE_TCL_STUBS when compiling the
+	 * package. When that happens, the package will contain symbols that
+	 * are references to the Tcl library, rather than function pointers
+	 * referencing the stub table. On platforms that lack backlinking,
+	 * those unresolved references may cause the loading of the package to
+	 * also load a second copy of the Tcl library, leading to all kinds of
+	 * trouble. We would like to catch that error and report a useful
+	 * message back to the user. That's what we're doing.
+	 *
+	 * Second, how does this work? If we reach this point, then the global
+	 * variable tclEmptyStringRep has the value NULL. Compare that with
+	 * the definition of tclEmptyStringRep near the top of the file
+	 * generic/tclObj.c. It clearly should not have the value NULL; it
+	 * should point to the char tclEmptyString. If we see it having the
+	 * value NULL, then somehow we are seeing a Tcl library that isn't
+	 * completely initialized, and that's an indicator for the error
+	 * condition described above. (Further explanation is welcome.)
+	 *
+	 * Third, so what do we do about it? This situation indicates the
+	 * package we just loaded wasn't properly compiled to be stub-enabled,
+	 * yet it thinks it is stub-enabled (it called Tcl_InitStubs()). We
+	 * want to report that the package just loaded is broken, so we want
+	 * to place an error message in the interpreter result and return NULL
+	 * to indicate failure to Tcl_InitStubs() so that it will also fail.
+	 * (Further explanation why we don't want to Tcl_Panic() is welcome.
+	 * After all, two Tcl libraries can't be a good thing!)
+	 *
+	 * Trouble is that's going to be tricky. We're now using a Tcl library
+	 * that's not fully initialized. In particular, it doesn't have a
+	 * proper value for tclEmptyStringRep. The Tcl_Obj system heavily
+	 * depends on the value of tclEmptyStringRep and all of Tcl depends
+	 * (increasingly) on the Tcl_Obj system, we need to correct that flaw
+	 * before making the calls to set the interpreter result to the error
+	 * message. That's the only flaw corrected; other problems with
+	 * initialization of the Tcl library are not remedied, so be very
+	 * careful about adding any other calls here without checking how they
+	 * behave when initialization is incomplete.
+	 */
+
+	tclEmptyStringRep = &tclEmptyString;
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		"Cannot load package \"%s\" in standalone executable:"
+		" This package is not compiled with stub support", name));
+	Tcl_SetErrorCode(interp, "TCL", "PACKAGE", "UNSTUBBED", NULL);
+	return NULL;
+    }
+
+    /*
+     * Translate between old and new API, and defer to the new function.
+     */
+
+    if (version == NULL) {
+	result = PkgRequireCore(interp, name, 0, NULL, clientDataPtr);
+    } else {
+	if (exact && TCL_OK
+		!= CheckVersionAndConvert(interp, version, NULL, NULL)) {
+	    return NULL;
+	}
+	ov = Tcl_NewStringObj(version, -1);
+	if (exact) {
+	    Tcl_AppendStringsToObj(ov, "-", version, NULL);
+	}
+	Tcl_IncrRefCount(ov);
+	result = PkgRequireCore(interp, name, 1, &ov, clientDataPtr);
+	TclDecrRefCount(ov);
+    }
+
+    return result;
+}
+
+int
+Tcl_PkgRequireProc(
+    Tcl_Interp *interp,		/* Interpreter in which package is now
+				 * available. */
+    const char *name,		/* Name of desired package. */
+    int reqc,			/* Requirements constraining the desired
+				 * version. */
+    Tcl_Obj *const reqv[],	/* 0 means to use the latest version
+				 * available. */
+    void *clientDataPtr)
+{
+    const char *result =
+	    PkgRequireCore(interp, name, reqc, reqv, clientDataPtr);
+
+    if (result == NULL) {
+	return TCL_ERROR;
+    }
+    Tcl_SetObjResult(interp, Tcl_NewStringObj(result, -1));
+    return TCL_OK;
+}
+
+static const char *
+PkgRequireCore(
+    Tcl_Interp *interp,		/* Interpreter in which package is now
+				 * available. */
+    const char *name,		/* Name of desired package. */
+    int reqc,			/* Requirements constraining the desired
+				 * version. */
+    Tcl_Obj *const reqv[],	/* 0 means to use the latest version
+				 * available. */
+    void *clientDataPtr)
+{
+    Interp *iPtr = (Interp *) interp;
+    Package *pkgPtr;
+    PkgAvail *availPtr, *bestPtr, *bestStablePtr;
+    char *availVersion, *bestVersion;
+				/* Internal rep. of versions */
+    int availStable, code, satisfies, pass;
+    char *script, *pkgVersionI;
+    Tcl_DString command;
+
+    if (TCL_OK != CheckAllRequirements(interp, reqc, reqv)) {
+	return NULL;
+    }
+
+    /*
+     * It can take up to three passes to find the package: one pass to run the
+     * "package unknown" script, one to run the "package ifneeded" script for
+     * a specific version, and a final pass to lookup the package loaded by
+     * the "package ifneeded" script.
+     */
+
+    for (pass=1 ;; pass++) {
+	pkgPtr = FindPackage(interp, name);
+	if (pkgPtr->version != NULL) {
+	    break;
+	}
+
+	/*
+	 * Check whether we're already attempting to load some version of this
+	 * package (circular dependency detection).
+	 */
+
+	if (pkgPtr->clientData != NULL) {
+	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		    "circular package dependency:"
+		    " attempt to provide %s %s requires %s",
+		    name, (char *) pkgPtr->clientData, name));
+	    AddRequirementsToResult(interp, reqc, reqv);
+	    Tcl_SetErrorCode(interp, "TCL", "PACKAGE", "CIRCULARITY", NULL);
+	    return NULL;
+	}
+
+	/*
+	 * The package isn't yet present. Search the list of available
+	 * versions and invoke the script for the best available version. We
+	 * are actually locating the best, and the best stable version. One of
+	 * them is then chosen based on the selection mode.
+	 */
+
+	bestPtr = NULL;
+	bestStablePtr = NULL;
+	bestVersion = NULL;
+
+	for (availPtr = pkgPtr->availPtr; availPtr != NULL;
+		availPtr = availPtr->nextPtr) {
+	    if (CheckVersionAndConvert(interp, availPtr->version,
+		    &availVersion, &availStable) != TCL_OK) {
+		/*
+		 * The provided version number has invalid syntax. This
+		 * should not happen. This should have been caught by the
+		 * 'package ifneeded' registering the package.
+		 */
+
+		continue;
+	    }
+
+	    if (bestPtr != NULL) {
+		int res = CompareVersions(availVersion, bestVersion, NULL);
+
+		/*
+		 * Note: Use internal reps!
+		 */
+
+		if (res <= 0) {
+		    /*
+		     * The version of the package sought is not as good as the
+		     * currently selected version. Ignore it.
+		     */
+
+		    ckfree(availVersion);
+		    availVersion = NULL;
+		    continue;
+		}
+	    }
+
+	    /*
+	     * We have found a version which is better than our max.
+	     */
+
+	    if (reqc > 0) {
+		/* Check satisfaction of requirements. */
+
+		satisfies = SomeRequirementSatisfied(availVersion, reqc, reqv);
+		if (!satisfies) {
+		    ckfree(availVersion);
+		    availVersion = NULL;
+		    continue;
+		}
+	    }
+
+	    bestPtr = availPtr;
+
+	    if (bestVersion != NULL) {
+		ckfree(bestVersion);
+	    }
+	    bestVersion = availVersion;
+
+	    /*
+	     * If this new best version is stable then it also has to be
+	     * better than the max stable version found so far.
+	     */
+
+	    if (availStable) {
+		bestStablePtr = availPtr;
+	    }
+	}
+
+	if (bestVersion != NULL) {
+	    ckfree(bestVersion);
+	}
+
+	/*
+	 * Now choose a version among the two best. For 'latest' we simply
+	 * take (actually keep) the best. For 'stable' we take the best
+	 * stable, if there is any, or the best if there is nothing stable.
+	 */
+
+	if ((iPtr->packagePrefer == PKG_PREFER_STABLE)
+		&& (bestStablePtr != NULL)) {
+	    bestPtr = bestStablePtr;
+	}
+
+	if (bestPtr != NULL) {
+	    /*
+	     * We found an ifneeded script for the package. Be careful while
+	     * executing it: this could cause reentrancy, so (a) protect the
+	     * script itself from deletion and (b) don't assume that bestPtr
+	     * will still exist when the script completes.
+	     */
+
+	    char *versionToProvide = bestPtr->version;
+	    script = bestPtr->script;
+
+	    pkgPtr->clientData = versionToProvide;
+	    Tcl_Preserve(script);
+	    Tcl_Preserve(versionToProvide);
+	    code = Tcl_EvalEx(interp, script, -1, TCL_EVAL_GLOBAL);
+	    Tcl_Release(script);
+
+	    pkgPtr = FindPackage(interp, name);
+	    if (code == TCL_OK) {
+		Tcl_ResetResult(interp);
+		if (pkgPtr->version == NULL) {
+		    code = TCL_ERROR;
+		    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+			    "attempt to provide package %s %s failed:"
+			    " no version of package %s provided",
+			    name, versionToProvide, name));
+		    Tcl_SetErrorCode(interp, "TCL", "PACKAGE", "UNPROVIDED",
+			    NULL);
+		} else {
+		    char *pvi, *vi;
+
+		    if (CheckVersionAndConvert(interp, pkgPtr->version, &pvi,
+			    NULL) != TCL_OK) {
+			code = TCL_ERROR;
+		    } else if (CheckVersionAndConvert(interp,
+			    versionToProvide, &vi, NULL) != TCL_OK) {
+			ckfree(pvi);
+			code = TCL_ERROR;
+		    } else {
+			int res = CompareVersions(pvi, vi, NULL);
+
+			ckfree(pvi);
+			ckfree(vi);
+			if (res != 0) {
+			    code = TCL_ERROR;
+			    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+				    "attempt to provide package %s %s failed:"
+				    " package %s %s provided instead",
+				    name, versionToProvide,
+				    name, pkgPtr->version));
+			    Tcl_SetErrorCode(interp, "TCL", "PACKAGE",
+				    "WRONGPROVIDE", NULL);
+			}
+		    }
+		}
+	    } else if (code != TCL_ERROR) {
+		Tcl_Obj *codePtr = Tcl_NewIntObj(code);
+
+		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+			"attempt to provide package %s %s failed:"
+			" bad return code: %s",
+			name, versionToProvide, TclGetString(codePtr)));
+		Tcl_SetErrorCode(interp, "TCL", "PACKAGE", "BADRESULT", NULL);
+		TclDecrRefCount(codePtr);
+		code = TCL_ERROR;
+	    }
+
+	    if (code == TCL_ERROR) {
+		Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf(
+			"\n    (\"package ifneeded %s %s\" script)",
+			name, versionToProvide));
+	    }
+	    Tcl_Release(versionToProvide);
+
+	    if (code != TCL_OK) {
+		/*
+		 * Take a non-TCL_OK code from the script as an indication the
+		 * package wasn't loaded properly, so the package system
+		 * should not remember an improper load.
+		 *
+		 * This is consistent with our returning NULL. If we're not
+		 * willing to tell our caller we got a particular version, we
+		 * shouldn't store that version for telling future callers
+		 * either.
+		 */
+
+		if (pkgPtr->version != NULL) {
+		    ckfree(pkgPtr->version);
+		    pkgPtr->version = NULL;
+		}
+		pkgPtr->clientData = NULL;
+		return NULL;
+	    }
+
+	    break;
+	}
+
+	/*
+	 * The package is not in the database. If there is a "package unknown"
+	 * command, invoke it (but only on the first pass; after that, we
+	 * should not get here in the first place).
+	 */
+
+	if (pass > 1) {
+	    break;
+	}
+
+	script = ((Interp *) interp)->packageUnknown;
+	if (script != NULL) {
+	    Tcl_DStringInit(&command);
+	    Tcl_DStringAppend(&command, script, -1);
+	    Tcl_DStringAppendElement(&command, name);
+	    AddRequirementsToDString(&command, reqc, reqv);
+
+	    code = Tcl_EvalEx(interp, Tcl_DStringValue(&command),
+		    Tcl_DStringLength(&command), TCL_EVAL_GLOBAL);
+	    Tcl_DStringFree(&command);
+
+	    if ((code != TCL_OK) && (code != TCL_ERROR)) {
+		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+			"bad return code: %d", code));
+		Tcl_SetErrorCode(interp, "TCL", "PACKAGE", "BADRESULT", NULL);
+		code = TCL_ERROR;
+	    }
+	    if (code == TCL_ERROR) {
+		Tcl_AddErrorInfo(interp,
+			"\n    (\"package unknown\" script)");
+		return NULL;
+	    }
+	    Tcl_ResetResult(interp);
+	}
+    }
+
+    if (pkgPtr->version == NULL) {
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		"can't find package %s", name));
+	Tcl_SetErrorCode(interp, "TCL", "PACKAGE", "UNFOUND", NULL);
+	AddRequirementsToResult(interp, reqc, reqv);
+	return NULL;
+    }
+
+    /*
+     * At this point we know that the package is present. Make sure that the
+     * provided version meets the current requirements.
+     */
+
+    if (reqc != 0) {
+	CheckVersionAndConvert(interp, pkgPtr->version, &pkgVersionI, NULL);
+	satisfies = SomeRequirementSatisfied(pkgVersionI, reqc, reqv);
+
+	ckfree(pkgVersionI);
+
+	if (!satisfies) {
+	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		    "version conflict for package \"%s\": have %s, need",
+		    name, pkgPtr->version));
+	    Tcl_SetErrorCode(interp, "TCL", "PACKAGE", "VERSIONCONFLICT",
+		    NULL);
+	    AddRequirementsToResult(interp, reqc, reqv);
+	    return NULL;
+	}
+    }
+
+    if (clientDataPtr) {
+	const void **ptr = (const void **) clientDataPtr;
+
+	*ptr = pkgPtr->clientData;
+    }
+    return pkgPtr->version;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_PkgPresent / Tcl_PkgPresentEx --
+ *
+ *	Checks to see whether the specified package is present. If it is not
+ *	then no additional action is taken.
+ *
+ * Results:
+ *	If successful, returns the version string for the currently provided
+ *	version of the package, which may be different from the "version"
+ *	argument. If the caller's requirements cannot be met (e.g. the version
+ *	requested conflicts with a currently provided version), NULL is
+ *	returned and an error message is left in interp->result.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+#undef Tcl_PkgPresent
+const char *
+Tcl_PkgPresent(
+    Tcl_Interp *interp,		/* Interpreter in which package is now
+				 * available. */
+    const char *name,		/* Name of desired package. */
+    const char *version,	/* Version string for desired version; NULL
+				 * means use the latest version available. */
+    int exact)			/* Non-zero means that only the particular
+				 * version given is acceptable. Zero means use
+				 * the latest compatible version. */
+{
+    return Tcl_PkgPresentEx(interp, name, version, exact, NULL);
+}
+
+const char *
+Tcl_PkgPresentEx(
+    Tcl_Interp *interp,		/* Interpreter in which package is now
+				 * available. */
+    const char *name,		/* Name of desired package. */
+    const char *version,	/* Version string for desired version; NULL
+				 * means use the latest version available. */
+    int exact,			/* Non-zero means that only the particular
+				 * version given is acceptable. Zero means use
+				 * the latest compatible version. */
+    void *clientDataPtr)	/* Used to return the client data for this
+				 * package. If it is NULL then the client data
+				 * is not returned. This is unchanged if this
+				 * call fails for any reason. */
+{
+    Interp *iPtr = (Interp *) interp;
+    Tcl_HashEntry *hPtr;
+    Package *pkgPtr;
+
+    hPtr = Tcl_FindHashEntry(&iPtr->packageTable, name);
+    if (hPtr) {
+	pkgPtr = Tcl_GetHashValue(hPtr);
+	if (pkgPtr->version != NULL) {
+	    /*
+	     * At this point we know that the package is present. Make sure
+	     * that the provided version meets the current requirement by
+	     * calling Tcl_PkgRequireEx() to check for us.
+	     */
+
+	    const char *foundVersion = Tcl_PkgRequireEx(interp, name, version,
+		    exact, clientDataPtr);
+
+	    if (foundVersion == NULL) {
+		Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "PACKAGE", name,
+			NULL);
+	    }
+	    return foundVersion;
+	}
+    }
+
+    if (version != NULL) {
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		"package %s %s is not present", name, version));
+    } else {
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		"package %s is not present", name));
+    }
+    Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "PACKAGE", name, NULL);
+    return NULL;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_PackageObjCmd --
+ *
+ *	This function is invoked to process the "package" Tcl command. See the
+ *	user documentation for details on what it does.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+	/* ARGSUSED */
+int
+Tcl_PackageObjCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    static const char *const pkgOptions[] = {
+	"forget",  "ifneeded", "names",   "prefer",   "present",
+	"provide", "require",  "unknown", "vcompare", "versions",
+	"vsatisfies", NULL
+    };
+    enum pkgOptions {
+	PKG_FORGET,  PKG_IFNEEDED, PKG_NAMES,   PKG_PREFER,   PKG_PRESENT,
+	PKG_PROVIDE, PKG_REQUIRE,  PKG_UNKNOWN, PKG_VCOMPARE, PKG_VERSIONS,
+	PKG_VSATISFIES
+    };
+    Interp *iPtr = (Interp *) interp;
+    int optionIndex, exact, i, satisfies;
+    PkgAvail *availPtr, *prevPtr;
+    Package *pkgPtr;
+    Tcl_HashEntry *hPtr;
+    Tcl_HashSearch search;
+    Tcl_HashTable *tablePtr;
+    const char *version;
+    const char *argv2, *argv3, *argv4;
+    char *iva = NULL, *ivb = NULL;
+
+    if (objc < 2) {
+	Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?");
+	return TCL_ERROR;
+    }
+
+    if (Tcl_GetIndexFromObj(interp, objv[1], pkgOptions, "option", 0,
+	    &optionIndex) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    switch ((enum pkgOptions) optionIndex) {
+    case PKG_FORGET: {
+	const char *keyString;
+
+	for (i = 2; i < objc; i++) {
+	    keyString = TclGetString(objv[i]);
+	    hPtr = Tcl_FindHashEntry(&iPtr->packageTable, keyString);
+	    if (hPtr == NULL) {
+		continue;
+	    }
+	    pkgPtr = Tcl_GetHashValue(hPtr);
+	    Tcl_DeleteHashEntry(hPtr);
+	    if (pkgPtr->version != NULL) {
+		ckfree(pkgPtr->version);
+	    }
+	    while (pkgPtr->availPtr != NULL) {
+		availPtr = pkgPtr->availPtr;
+		pkgPtr->availPtr = availPtr->nextPtr;
+		Tcl_EventuallyFree(availPtr->version, TCL_DYNAMIC);
+		Tcl_EventuallyFree(availPtr->script, TCL_DYNAMIC);
+		ckfree(availPtr);
+	    }
+	    ckfree(pkgPtr);
+	}
+	break;
+    }
+    case PKG_IFNEEDED: {
+	int length, res;
+	char *argv3i, *avi;
+
+	if ((objc != 4) && (objc != 5)) {
+	    Tcl_WrongNumArgs(interp, 2, objv, "package version ?script?");
+	    return TCL_ERROR;
+	}
+	argv3 = TclGetString(objv[3]);
+	if (CheckVersionAndConvert(interp, argv3, &argv3i, NULL) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	argv2 = TclGetString(objv[2]);
+	if (objc == 4) {
+	    hPtr = Tcl_FindHashEntry(&iPtr->packageTable, argv2);
+	    if (hPtr == NULL) {
+		ckfree(argv3i);
+		return TCL_OK;
+	    }
+	    pkgPtr = Tcl_GetHashValue(hPtr);
+	} else {
+	    pkgPtr = FindPackage(interp, argv2);
+	}
+	argv3 = Tcl_GetStringFromObj(objv[3], &length);
+
+	for (availPtr = pkgPtr->availPtr, prevPtr = NULL; availPtr != NULL;
+		prevPtr = availPtr, availPtr = availPtr->nextPtr) {
+	    if (CheckVersionAndConvert(interp, availPtr->version, &avi,
+		    NULL) != TCL_OK) {
+		ckfree(argv3i);
+		return TCL_ERROR;
+	    }
+
+	    res = CompareVersions(avi, argv3i, NULL);
+	    ckfree(avi);
+
+	    if (res == 0){
+		if (objc == 4) {
+		    ckfree(argv3i);
+		    Tcl_SetObjResult(interp,
+			    Tcl_NewStringObj(availPtr->script, -1));
+		    return TCL_OK;
+		}
+		Tcl_EventuallyFree(availPtr->script, TCL_DYNAMIC);
+		break;
+	    }
+	}
+	ckfree(argv3i);
+
+	if (objc == 4) {
+	    return TCL_OK;
+	}
+	if (availPtr == NULL) {
+	    availPtr = ckalloc(sizeof(PkgAvail));
+	    DupBlock(availPtr->version, argv3, (unsigned) length + 1);
+
+	    if (prevPtr == NULL) {
+		availPtr->nextPtr = pkgPtr->availPtr;
+		pkgPtr->availPtr = availPtr;
+	    } else {
+		availPtr->nextPtr = prevPtr->nextPtr;
+		prevPtr->nextPtr = availPtr;
+	    }
+	}
+	argv4 = Tcl_GetStringFromObj(objv[4], &length);
+	DupBlock(availPtr->script, argv4, (unsigned) length + 1);
+	break;
+    }
+    case PKG_NAMES:
+	if (objc != 2) {
+	    Tcl_WrongNumArgs(interp, 2, objv, NULL);
+	    return TCL_ERROR;
+	} else {
+	    Tcl_Obj *resultObj;
+
+	    resultObj = Tcl_NewObj();
+	    tablePtr = &iPtr->packageTable;
+	    for (hPtr = Tcl_FirstHashEntry(tablePtr, &search); hPtr != NULL;
+		    hPtr = Tcl_NextHashEntry(&search)) {
+		pkgPtr = Tcl_GetHashValue(hPtr);
+		if ((pkgPtr->version != NULL) || (pkgPtr->availPtr != NULL)) {
+		    Tcl_ListObjAppendElement(NULL,resultObj, Tcl_NewStringObj(
+			    Tcl_GetHashKey(tablePtr, hPtr), -1));
+		}
+	    }
+	    Tcl_SetObjResult(interp, resultObj);
+	}
+	break;
+    case PKG_PRESENT: {
+	const char *name;
+
+	if (objc < 3) {
+	    goto require;
+	}
+	argv2 = TclGetString(objv[2]);
+	if ((argv2[0] == '-') && (strcmp(argv2, "-exact") == 0)) {
+	    if (objc != 5) {
+		goto requireSyntax;
+	    }
+	    exact = 1;
+	    name = TclGetString(objv[3]);
+	} else {
+	    exact = 0;
+	    name = argv2;
+	}
+
+	hPtr = Tcl_FindHashEntry(&iPtr->packageTable, name);
+	if (hPtr != NULL) {
+	    pkgPtr = Tcl_GetHashValue(hPtr);
+	    if (pkgPtr->version != NULL) {
+		goto require;
+	    }
+	}
+
+	version = NULL;
+	if (exact) {
+	    version = TclGetString(objv[4]);
+	    if (CheckVersionAndConvert(interp, version, NULL,
+		    NULL) != TCL_OK) {
+		return TCL_ERROR;
+	    }
+	} else {
+	    if (CheckAllRequirements(interp, objc-3, objv+3) != TCL_OK) {
+		return TCL_ERROR;
+	    }
+	    if ((objc > 3) && (CheckVersionAndConvert(interp,
+		    TclGetString(objv[3]), NULL, NULL) == TCL_OK)) {
+		version = TclGetString(objv[3]);
+	    }
+	}
+	Tcl_PkgPresentEx(interp, name, version, exact, NULL);
+	return TCL_ERROR;
+	break;
+    }
+    case PKG_PROVIDE:
+	if ((objc != 3) && (objc != 4)) {
+	    Tcl_WrongNumArgs(interp, 2, objv, "package ?version?");
+	    return TCL_ERROR;
+	}
+	argv2 = TclGetString(objv[2]);
+	if (objc == 3) {
+	    hPtr = Tcl_FindHashEntry(&iPtr->packageTable, argv2);
+	    if (hPtr != NULL) {
+		pkgPtr = Tcl_GetHashValue(hPtr);
+		if (pkgPtr->version != NULL) {
+		    Tcl_SetObjResult(interp,
+			    Tcl_NewStringObj(pkgPtr->version, -1));
+		}
+	    }
+	    return TCL_OK;
+	}
+	argv3 = TclGetString(objv[3]);
+	if (CheckVersionAndConvert(interp, argv3, NULL, NULL) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	return Tcl_PkgProvideEx(interp, argv2, argv3, NULL);
+    case PKG_REQUIRE:
+    require:
+	if (objc < 3) {
+	requireSyntax:
+	    Tcl_WrongNumArgs(interp, 2, objv,
+		    "?-exact? package ?requirement ...?");
+	    return TCL_ERROR;
+	}
+
+	version = NULL;
+
+	argv2 = TclGetString(objv[2]);
+	if ((argv2[0] == '-') && (strcmp(argv2, "-exact") == 0)) {
+	    Tcl_Obj *ov;
+	    int res;
+
+	    if (objc != 5) {
+		goto requireSyntax;
+	    }
+
+	    version = TclGetString(objv[4]);
+	    if (CheckVersionAndConvert(interp, version, NULL,
+		    NULL) != TCL_OK) {
+		return TCL_ERROR;
+	    }
+
+	    /*
+	     * Create a new-style requirement for the exact version.
+	     */
+
+	    ov = Tcl_NewStringObj(version, -1);
+	    Tcl_AppendStringsToObj(ov, "-", version, NULL);
+	    version = NULL;
+	    argv3 = TclGetString(objv[3]);
+
+	    Tcl_IncrRefCount(ov);
+	    res = Tcl_PkgRequireProc(interp, argv3, 1, &ov, NULL);
+	    TclDecrRefCount(ov);
+	    return res;
+	} else {
+	    if (CheckAllRequirements(interp, objc-3, objv+3) != TCL_OK) {
+		return TCL_ERROR;
+	    }
+
+	    return Tcl_PkgRequireProc(interp, argv2, objc-3, objv+3, NULL);
+	}
+	break;
+    case PKG_UNKNOWN: {
+	int length;
+
+	if (objc == 2) {
+	    if (iPtr->packageUnknown != NULL) {
+		Tcl_SetObjResult(interp,
+			Tcl_NewStringObj(iPtr->packageUnknown, -1));
+	    }
+	} else if (objc == 3) {
+	    if (iPtr->packageUnknown != NULL) {
+		ckfree(iPtr->packageUnknown);
+	    }
+	    argv2 = Tcl_GetStringFromObj(objv[2], &length);
+	    if (argv2[0] == 0) {
+		iPtr->packageUnknown = NULL;
+	    } else {
+		DupBlock(iPtr->packageUnknown, argv2, (unsigned) length+1);
+	    }
+	} else {
+	    Tcl_WrongNumArgs(interp, 2, objv, "?command?");
+	    return TCL_ERROR;
+	}
+	break;
+    }
+    case PKG_PREFER: {
+	static const char *const pkgPreferOptions[] = {
+	    "latest", "stable", NULL
+	};
+
+	/*
+	 * See tclInt.h for the enum, just before Interp.
+	 */
+
+	if (objc > 3) {
+	    Tcl_WrongNumArgs(interp, 2, objv, "?latest|stable?");
+	    return TCL_ERROR;
+	} else if (objc == 3) {
+	    /*
+	     * Seting the value.
+	     */
+
+	    int newPref;
+
+	    if (Tcl_GetIndexFromObj(interp, objv[2], pkgPreferOptions,
+		    "preference", 0, &newPref) != TCL_OK) {
+		return TCL_ERROR;
+	    }
+
+	    if (newPref < iPtr->packagePrefer) {
+		iPtr->packagePrefer = newPref;
+	    }
+	}
+
+	/*
+	 * Always return current value.
+	 */
+
+	Tcl_SetObjResult(interp,
+		Tcl_NewStringObj(pkgPreferOptions[iPtr->packagePrefer], -1));
+	break;
+    }
+    case PKG_VCOMPARE:
+	if (objc != 4) {
+	    Tcl_WrongNumArgs(interp, 2, objv, "version1 version2");
+	    return TCL_ERROR;
+	}
+	argv3 = TclGetString(objv[3]);
+	argv2 = TclGetString(objv[2]);
+	if (CheckVersionAndConvert(interp, argv2, &iva, NULL) != TCL_OK ||
+		CheckVersionAndConvert(interp, argv3, &ivb, NULL) != TCL_OK) {
+	    if (iva != NULL) {
+		ckfree(iva);
+	    }
+
+	    /*
+	     * ivb cannot be set in this branch.
+	     */
+
+	    return TCL_ERROR;
+	}
+
+	/*
+	 * Comparison is done on the internal representation.
+	 */
+
+	Tcl_SetObjResult(interp,
+		Tcl_NewIntObj(CompareVersions(iva, ivb, NULL)));
+	ckfree(iva);
+	ckfree(ivb);
+	break;
+    case PKG_VERSIONS:
+	if (objc != 3) {
+	    Tcl_WrongNumArgs(interp, 2, objv, "package");
+	    return TCL_ERROR;
+	} else {
+	    Tcl_Obj *resultObj = Tcl_NewObj();
+
+	    argv2 = TclGetString(objv[2]);
+	    hPtr = Tcl_FindHashEntry(&iPtr->packageTable, argv2);
+	    if (hPtr != NULL) {
+		pkgPtr = Tcl_GetHashValue(hPtr);
+		for (availPtr = pkgPtr->availPtr; availPtr != NULL;
+			availPtr = availPtr->nextPtr) {
+		    Tcl_ListObjAppendElement(NULL, resultObj,
+			    Tcl_NewStringObj(availPtr->version, -1));
+		}
+	    }
+	    Tcl_SetObjResult(interp, resultObj);
+	}
+	break;
+    case PKG_VSATISFIES: {
+	char *argv2i = NULL;
+
+	if (objc < 4) {
+	    Tcl_WrongNumArgs(interp, 2, objv, "version ?requirement ...?");
+	    return TCL_ERROR;
+	}
+
+	argv2 = TclGetString(objv[2]);
+	if (CheckVersionAndConvert(interp, argv2, &argv2i, NULL) != TCL_OK) {
+	    return TCL_ERROR;
+	} else if (CheckAllRequirements(interp, objc-3, objv+3) != TCL_OK) {
+	    ckfree(argv2i);
+	    return TCL_ERROR;
+	}
+
+	satisfies = SomeRequirementSatisfied(argv2i, objc-3, objv+3);
+	ckfree(argv2i);
+
+	Tcl_SetObjResult(interp, Tcl_NewBooleanObj(satisfies));
+	break;
+    }
+    default:
+	Tcl_Panic("Tcl_PackageObjCmd: bad option index to pkgOptions");
+    }
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * FindPackage --
+ *
+ *	This function finds the Package record for a particular package in a
+ *	particular interpreter, creating a record if one doesn't already
+ *	exist.
+ *
+ * Results:
+ *	The return value is a pointer to the Package record for the package.
+ *
+ * Side effects:
+ *	A new Package record may be created.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static Package *
+FindPackage(
+    Tcl_Interp *interp,		/* Interpreter to use for package lookup. */
+    const char *name)		/* Name of package to fine. */
+{
+    Interp *iPtr = (Interp *) interp;
+    Tcl_HashEntry *hPtr;
+    int isNew;
+    Package *pkgPtr;
+
+    hPtr = Tcl_CreateHashEntry(&iPtr->packageTable, name, &isNew);
+    if (isNew) {
+	pkgPtr = ckalloc(sizeof(Package));
+	pkgPtr->version = NULL;
+	pkgPtr->availPtr = NULL;
+	pkgPtr->clientData = NULL;
+	Tcl_SetHashValue(hPtr, pkgPtr);
+    } else {
+	pkgPtr = Tcl_GetHashValue(hPtr);
+    }
+    return pkgPtr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclFreePackageInfo --
+ *
+ *	This function is called during interpreter deletion to free all of the
+ *	package-related information for the interpreter.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Memory is freed.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclFreePackageInfo(
+    Interp *iPtr)		/* Interpereter that is being deleted. */
+{
+    Package *pkgPtr;
+    Tcl_HashSearch search;
+    Tcl_HashEntry *hPtr;
+    PkgAvail *availPtr;
+
+    for (hPtr = Tcl_FirstHashEntry(&iPtr->packageTable, &search);
+	    hPtr != NULL; hPtr = Tcl_NextHashEntry(&search)) {
+	pkgPtr = Tcl_GetHashValue(hPtr);
+	if (pkgPtr->version != NULL) {
+	    ckfree(pkgPtr->version);
+	}
+	while (pkgPtr->availPtr != NULL) {
+	    availPtr = pkgPtr->availPtr;
+	    pkgPtr->availPtr = availPtr->nextPtr;
+	    Tcl_EventuallyFree(availPtr->version, TCL_DYNAMIC);
+	    Tcl_EventuallyFree(availPtr->script, TCL_DYNAMIC);
+	    ckfree(availPtr);
+	}
+	ckfree(pkgPtr);
+    }
+    Tcl_DeleteHashTable(&iPtr->packageTable);
+    if (iPtr->packageUnknown != NULL) {
+	ckfree(iPtr->packageUnknown);
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * CheckVersionAndConvert --
+ *
+ *	This function checks to see whether a version number has valid syntax.
+ *	It also generates a semi-internal representation (string rep of a list
+ *	of numbers).
+ *
+ * Results:
+ *	If string is a properly formed version number the TCL_OK is returned.
+ *	Otherwise TCL_ERROR is returned and an error message is left in the
+ *	interp's result.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+CheckVersionAndConvert(
+    Tcl_Interp *interp,		/* Used for error reporting. */
+    const char *string,		/* Supposedly a version number, which is
+				 * groups of decimal digits separated by
+				 * dots. */
+    char **internal,		/* Internal normalized representation */
+    int *stable)		/* Flag: Version is (un)stable. */
+{
+    const char *p = string;
+    char prevChar;
+    int hasunstable = 0;
+    /*
+     * 4* assuming that each char is a separator (a,b become ' -x ').
+     * 4+ to have spce for an additional -2 at the end
+     */
+    char *ibuf = ckalloc(4 + 4*strlen(string));
+    char *ip = ibuf;
+
+    /*
+     * Basic rules
+     * (1) First character has to be a digit.
+     * (2) All other characters have to be a digit or '.'
+     * (3) Two '.'s may not follow each other.
+     *
+     * TIP 268, Modified rules
+     * (1) s.a.
+     * (2) All other characters have to be a digit, 'a', 'b', or '.'
+     * (3) s.a.
+     * (4) Only one of 'a' or 'b' may occur.
+     * (5) Neither 'a', nor 'b' may occur before or after a '.'
+     */
+
+    if (!isdigit(UCHAR(*p))) {				/* INTL: digit */
+	goto error;
+    }
+
+    *ip++ = *p;
+
+    for (prevChar = *p, p++; *p != 0; p++) {
+	if (!isdigit(UCHAR(*p)) &&			/* INTL: digit */
+		((*p!='.' && *p!='a' && *p!='b') ||
+		((hasunstable && (*p=='a' || *p=='b')) ||
+		((prevChar=='a' || prevChar=='b' || prevChar=='.')
+			&& (*p=='.')) ||
+		((*p=='a' || *p=='b' || *p=='.') && prevChar=='.')))) {
+	    goto error;
+	}
+
+	if (*p == 'a' || *p == 'b') {
+	    hasunstable = 1;
+	}
+
+	/*
+	 * Translation to the internal rep. Regular version chars are copied
+	 * as is. The separators are translated to numerics. The new separator
+	 * for all parts is space.
+	 */
+
+	if (*p == '.') {
+	    *ip++ = ' ';
+	    *ip++ = '0';
+	    *ip++ = ' ';
+	} else if (*p == 'a') {
+	    *ip++ = ' ';
+	    *ip++ = '-';
+	    *ip++ = '2';
+	    *ip++ = ' ';
+	} else if (*p == 'b') {
+	    *ip++ = ' ';
+	    *ip++ = '-';
+	    *ip++ = '1';
+	    *ip++ = ' ';
+	} else {
+	    *ip++ = *p;
+	}
+
+	prevChar = *p;
+    }
+    if (prevChar!='.' && prevChar!='a' && prevChar!='b') {
+	*ip = '\0';
+	if (internal != NULL) {
+	    *internal = ibuf;
+	} else {
+	    ckfree(ibuf);
+	}
+	if (stable != NULL) {
+	    *stable = !hasunstable;
+	}
+	return TCL_OK;
+    }
+
+  error:
+    ckfree(ibuf);
+    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+	    "expected version number but got \"%s\"", string));
+    Tcl_SetErrorCode(interp, "TCL", "VALUE", "VERSION", NULL);
+    return TCL_ERROR;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * CompareVersions --
+ *
+ *	This function compares two version numbers (in internal rep).
+ *
+ * Results:
+ *	The return value is -1 if v1 is less than v2, 0 if the two version
+ *	numbers are the same, and 1 if v1 is greater than v2. If *satPtr is
+ *	non-NULL, the word it points to is filled in with 1 if v2 >= v1 and
+ *	both numbers have the same major number or 0 otherwise.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+CompareVersions(
+    char *v1, char *v2,		/* Versions strings, of form 2.1.3 (any number
+				 * of version numbers). */
+    int *isMajorPtr)		/* If non-null, the word pointed to is filled
+				 * in with a 0/1 value. 1 means that the
+				 * difference occured in the first element. */
+{
+    int thisIsMajor, res, flip;
+    char *s1, *e1, *s2, *e2, o1, o2;
+
+    /*
+     * Each iteration of the following loop processes one number from each
+     * string, terminated by a " " (space). If those numbers don't match then
+     * the comparison is over; otherwise, we loop back for the next number.
+     *
+     * TIP 268.
+     * This is identical the function 'ComparePkgVersion', but using the new
+     * space separator as used by the internal rep of version numbers. The
+     * special separators 'a' and 'b' have already been dealt with in
+     * 'CheckVersionAndConvert', they were translated into numbers as well.
+     * This keeps the comparison sane. Otherwise we would have to compare
+     * numerics, the separators, and also deal with the special case of
+     * end-of-string compared to separators. The semi-list rep we get here is
+     * much easier to handle, as it is still regular.
+     *
+     * Rewritten to not compute a numeric value for the extracted version
+     * number, but do string comparison. Skip any leading zeros for that to
+     * work. This change breaks through the 32bit-limit on version numbers.
+     */
+
+    thisIsMajor = 1;
+    s1 = v1;
+    s2 = v2;
+
+    while (1) {
+	/*
+	 * Parse one decimal number from the front of each string. Skip
+	 * leading zeros. Terminate found number for upcoming string-wise
+	 * comparison, if needed.
+	 */
+
+	while ((*s1 != 0) && (*s1 == '0')) {
+	    s1++;
+	}
+	while ((*s2 != 0) && (*s2 == '0')) {
+	    s2++;
+	}
+
+	/*
+	 * s1, s2 now point to the beginnings of the numbers to compare. Test
+	 * for their signs first, as shortcut to the result (different signs),
+	 * or determines if result has to be flipped (both negative). If there
+	 * is no shortcut we have to insert terminators later to limit the
+	 * strcmp.
+	 */
+
+	if ((*s1 == '-') && (*s2 != '-')) {
+	    /* s1 < 0, s2 >= 0 => s1 < s2 */
+	    res = -1;
+	    break;
+	}
+	if ((*s1 != '-') && (*s2 == '-')) {
+	    /* s1 >= 0, s2 < 0 => s1 > s2 */
+	    res = 1;
+	    break;
+	}
+
+	if ((*s1 == '-') && (*s2 == '-')) {
+	    /* a < b => -a > -b, etc. */
+	    s1++;
+	    s2++;
+	    flip = 1;
+	} else {
+	    flip = 0;
+	}
+
+	/*
+	 * The string comparison is needed, so now we determine where the
+	 * numbers end.
+	 */
+
+	e1 = s1;
+	while ((*e1 != 0) && (*e1 != ' ')) {
+	    e1++;
+	}
+	e2 = s2;
+	while ((*e2 != 0) && (*e2 != ' ')) {
+	    e2++;
+	}
+
+	/*
+	 * s1 .. e1 and s2 .. e2 now bracket the numbers to compare. Insert
+	 * terminators, compare, and restore actual contents. First however
+	 * another shortcut. Compare lengths. Shorter string is smaller
+	 * number! Thus we strcmp only strings of identical length.
+	 */
+
+	if ((e1-s1) < (e2-s2)) {
+	    res = -1;
+	} else if ((e2-s2) < (e1-s1)) {
+	    res = 1;
+	} else {
+	    o1 = *e1;
+	    *e1 = '\0';
+	    o2 = *e2;
+	    *e2 = '\0';
+
+	    res = strcmp(s1, s2);
+	    res = (res < 0) ? -1 : (res ? 1 : 0);
+
+	    *e1 = o1;
+	    *e2 = o2;
+	}
+
+	/*
+	 * Stop comparing segments when a difference has been found. Here we
+	 * may have to flip the result to account for signs.
+	 */
+
+	if (res != 0) {
+	    if (flip) {
+		res = -res;
+	    }
+	    break;
+	}
+
+	/*
+	 * Go on to the next version number if the current numbers match.
+	 * However stop processing if the end of both numbers has been
+	 * reached.
+	 */
+
+	s1 = e1;
+	s2 = e2;
+
+	if (*s1 != 0) {
+	    s1++;
+	} else if (*s2 == 0) {
+	    /*
+	     * s1, s2 both at the end => identical
+	     */
+
+	    res = 0;
+	    break;
+	}
+	if (*s2 != 0) {
+	    s2++;
+	}
+	thisIsMajor = 0;
+    }
+
+    if (isMajorPtr != NULL) {
+	*isMajorPtr = thisIsMajor;
+    }
+
+    return res;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * CheckAllRequirements --
+ *
+ *	This function checks to see whether all requirements in a set have
+ *	valid syntax.
+ *
+ * Results:
+ *	TCL_OK is returned if all requirements are valid. Otherwise TCL_ERROR
+ *	is returned and an error message is left in the interp's result.
+ *
+ * Side effects:
+ *	May modify the interpreter result.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+CheckAllRequirements(
+    Tcl_Interp *interp,
+    int reqc,			/* Requirements to check. */
+    Tcl_Obj *const reqv[])
+{
+    int i;
+
+    for (i = 0; i < reqc; i++) {
+	if ((CheckRequirement(interp, TclGetString(reqv[i])) != TCL_OK)) {
+	    return TCL_ERROR;
+	}
+    }
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * CheckRequirement --
+ *
+ *	This function checks to see whether a requirement has valid syntax.
+ *
+ * Results:
+ *	If string is a properly formed requirement then TCL_OK is returned.
+ *	Otherwise TCL_ERROR is returned and an error message is left in the
+ *	interp's result.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+CheckRequirement(
+    Tcl_Interp *interp,		/* Used for error reporting. */
+    const char *string)		/* Supposedly a requirement. */
+{
+    /*
+     * Syntax of requirement = version
+     *			     = version-version
+     *			     = version-
+     */
+
+    char *dash = NULL, *buf;
+
+    dash = strchr(string, '-');
+    if (dash == NULL) {
+	/*
+	 * No dash found, has to be a simple version.
+	 */
+
+	return CheckVersionAndConvert(interp, string, NULL, NULL);
+    }
+
+    if (strchr(dash+1, '-') != NULL) {
+	/*
+	 * More dashes found after the first. This is wrong.
+	 */
+
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		"expected versionMin-versionMax but got \"%s\"", string));
+	Tcl_SetErrorCode(interp, "TCL", "VALUE", "VERSIONRANGE", NULL);
+	return TCL_ERROR;
+    }
+
+    /*
+     * Exactly one dash is present. Copy the string, split at the location of
+     * dash and check that both parts are versions. Note that the max part can
+     * be empty. Also note that the string allocated with strdup() must be
+     * freed with free() and not ckfree().
+     */
+
+    DupString(buf, string);
+    dash = buf + (dash - string);
+    *dash = '\0';		/* buf now <=> min part */
+    dash++;			/* dash now <=> max part */
+
+    if ((CheckVersionAndConvert(interp, buf, NULL, NULL) != TCL_OK) ||
+	    ((*dash != '\0') &&
+	    (CheckVersionAndConvert(interp, dash, NULL, NULL) != TCL_OK))) {
+	ckfree(buf);
+	return TCL_ERROR;
+    }
+
+    ckfree(buf);
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * AddRequirementsToResult --
+ *
+ *	This function accumulates requirements in the interpreter result.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The interpreter result is extended.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+AddRequirementsToResult(
+    Tcl_Interp *interp,
+    int reqc,			/* Requirements constraining the desired
+				 * version. */
+    Tcl_Obj *const reqv[])	/* 0 means to use the latest version
+				 * available. */
+{
+    Tcl_Obj *result = Tcl_GetObjResult(interp);
+    int i, length;
+
+    for (i = 0; i < reqc; i++) {
+	const char *v = Tcl_GetStringFromObj(reqv[i], &length);
+
+	if ((length & 0x1) && (v[length/2] == '-')
+		&& (strncmp(v, v+((length+1)/2), length/2) == 0)) {
+	    Tcl_AppendPrintfToObj(result, " exactly %s", v+((length+1)/2));
+	} else {
+	    Tcl_AppendPrintfToObj(result, " %s", v);
+	}
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * AddRequirementsToDString --
+ *
+ *	This function accumulates requirements in a DString.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The DString argument is extended.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+AddRequirementsToDString(
+    Tcl_DString *dsPtr,
+    int reqc,			/* Requirements constraining the desired
+				 * version. */
+    Tcl_Obj *const reqv[])	/* 0 means to use the latest version
+				 * available. */
+{
+    int i;
+
+    if (reqc > 0) {
+	for (i = 0; i < reqc; i++) {
+	    TclDStringAppendLiteral(dsPtr, " ");
+	    TclDStringAppendObj(dsPtr, reqv[i]);
+	}
+    } else {
+	TclDStringAppendLiteral(dsPtr, " 0-");
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * SomeRequirementSatisfied --
+ *
+ *	This function checks to see whether a version satisfies at least one
+ *	of a set of requirements.
+ *
+ * Results:
+ *	If the requirements are satisfied 1 is returned. Otherwise 0 is
+ *	returned. The function assumes that all pieces have valid syntax. And
+ *	is allowed to make that assumption.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+SomeRequirementSatisfied(
+    char *availVersionI,	/* Candidate version to check against the
+				 * requirements. */
+    int reqc,			/* Requirements constraining the desired
+				 * version. */
+    Tcl_Obj *const reqv[])	/* 0 means to use the latest version
+				 * available. */
+{
+    int i;
+
+    for (i = 0; i < reqc; i++) {
+	if (RequirementSatisfied(availVersionI, TclGetString(reqv[i]))) {
+	    return 1;
+	}
+    }
+    return 0;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * RequirementSatisfied --
+ *
+ *	This function checks to see whether a version satisfies a requirement.
+ *
+ * Results:
+ *	If the requirement is satisfied 1 is returned. Otherwise 0 is
+ *	returned. The function assumes that all pieces have valid syntax, and
+ *	is allowed to make that assumption.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+RequirementSatisfied(
+    char *havei,		/* Version string, of candidate package we
+				 * have. */
+    const char *req)		/* Requirement string the candidate has to
+				 * satisfy. */
+{
+    /*
+     * The have candidate is already in internal rep.
+     */
+
+    int satisfied, res;
+    char *dash = NULL, *buf, *min, *max;
+
+    dash = strchr(req, '-');
+    if (dash == NULL) {
+	/*
+	 * No dash found, is a simple version, fallback to regular check. The
+	 * 'CheckVersionAndConvert' cannot fail. We pad the requirement with
+	 * 'a0', i.e '-2' before doing the comparison to properly accept
+	 * unstables as well.
+	 */
+
+	char *reqi = NULL;
+	int thisIsMajor;
+
+	CheckVersionAndConvert(NULL, req, &reqi, NULL);
+	strcat(reqi, " -2");
+	res = CompareVersions(havei, reqi, &thisIsMajor);
+	satisfied = (res == 0) || ((res == 1) && !thisIsMajor);
+	ckfree(reqi);
+	return satisfied;
+    }
+
+    /*
+     * Exactly one dash is present (Assumption of valid syntax). Copy the req,
+     * split at the location of dash and check that both parts are versions.
+     * Note that the max part can be empty.
+     */
+
+    DupString(buf, req);
+    dash = buf + (dash - req);
+    *dash = '\0';		/* buf now <=> min part */
+    dash++;			/* dash now <=> max part */
+
+    if (*dash == '\0') {
+	/*
+	 * We have a min, but no max. For the comparison we generate the
+	 * internal rep, padded with 'a0' i.e. '-2'.
+	 */
+
+	CheckVersionAndConvert(NULL, buf, &min, NULL);
+	strcat(min, " -2");
+	satisfied = (CompareVersions(havei, min, NULL) >= 0);
+	ckfree(min);
+	ckfree(buf);
+	return satisfied;
+    }
+
+    /*
+     * We have both min and max, and generate their internal reps. When
+     * identical we compare as is, otherwise we pad with 'a0' to ove the range
+     * a bit.
+     */
+
+    CheckVersionAndConvert(NULL, buf, &min, NULL);
+    CheckVersionAndConvert(NULL, dash, &max, NULL);
+
+    if (CompareVersions(min, max, NULL) == 0) {
+	satisfied = (CompareVersions(min, havei, NULL) == 0);
+    } else {
+	strcat(min, " -2");
+	strcat(max, " -2");
+	satisfied = ((CompareVersions(min, havei, NULL) <= 0) &&
+		(CompareVersions(havei, max, NULL) < 0));
+    }
+
+    ckfree(min);
+    ckfree(max);
+    ckfree(buf);
+    return satisfied;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_PkgInitStubsCheck --
+ *
+ *	This is a replacement routine for Tcl_InitStubs() that is called
+ *	from code where -DUSE_TCL_STUBS has not been enabled.
+ *
+ * Results:
+ *	Returns the version of a conforming stubs table, or NULL, if
+ *	the table version doesn't satisfy the requested requirements,
+ *	according to historical practice.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+const char *
+Tcl_PkgInitStubsCheck(
+    Tcl_Interp *interp,
+    const char * version,
+    int exact)
+{
+    const char *actualVersion = Tcl_PkgPresent(interp, "Tcl", version, 0);
+
+    if (exact && actualVersion) {
+	const char *p = version;
+	int count = 0;
+
+	while (*p) {
+	    count += !isdigit(UCHAR(*p++));
+	}
+	if (count == 1) {
+	    if (0 != strncmp(version, actualVersion, strlen(version))) {
+		/* Construct error message */
+		Tcl_PkgPresent(interp, "Tcl", version, 1);
+		return NULL;
+	    }
+	} else {
+	    return Tcl_PkgPresent(interp, "Tcl", version, 1);
+	}
+    }
+    return actualVersion;
+}
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tclPkgConfig.c b/generic/tclPkgConfig.c
new file mode 100644
index 0000000..466d535
--- /dev/null
+++ b/generic/tclPkgConfig.c
@@ -0,0 +1,135 @@
+/*
+ * tclPkgConfig.c --
+ *
+ *	This file contains the configuration information to embed into the tcl
+ *	binary library.
+ *
+ * Copyright (c) 2002 Andreas Kupries <andreas_kupries@users.sourceforge.net>
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+/* Note, the definitions in this module are influenced by the following C
+ * preprocessor macros:
+ *
+ * OSCMa  = shortcut for "old style configuration macro activates"
+ * NSCMdt = shortcut for "new style configuration macro declares that"
+ *
+ * - TCL_THREADS		OSCMa compilation as threaded core.
+ * - TCL_MEM_DEBUG		OSCMa memory debugging.
+ * - TCL_COMPILE_DEBUG		OSCMa debugging of bytecode compiler.
+ * - TCL_COMPILE_STATS		OSCMa bytecode compiler statistics.
+ *
+ * - TCL_CFG_DO64BIT		NSCMdt tcl is compiled for a 64bit system.
+ * - NDEBUG		NSCMdt tcl is compiled with symbol info off.
+ * - TCL_CFG_OPTIMIZED		NSCMdt tcl is compiled with cc optimizations on
+ * - TCL_CFG_PROFILED		NSCMdt tcl is compiled with profiling info.
+ *
+ * - CFG_RUNTIME_*		Paths to various stuff at runtime.
+ * - CFG_INSTALL_*		Paths to various stuff at installation time.
+ *
+ * - TCL_CFGVAL_ENCODING	string containing the encoding used for the
+ *				configuration values.
+ */
+
+#include "tclInt.h"
+
+/*
+ * Use C preprocessor statements to define the various values for the embedded
+ * configuration information.
+ */
+
+#ifdef TCL_THREADS
+#  define  CFG_THREADED		"1"
+#else
+#  define  CFG_THREADED		"0"
+#endif
+
+#ifdef TCL_MEM_DEBUG
+#  define CFG_MEMDEBUG		"1"
+#else
+#  define CFG_MEMDEBUG		"0"
+#endif
+
+#ifdef TCL_COMPILE_DEBUG
+#  define CFG_COMPILE_DEBUG	"1"
+#else
+#  define CFG_COMPILE_DEBUG	"0"
+#endif
+
+#ifdef TCL_COMPILE_STATS
+#  define CFG_COMPILE_STATS	"1"
+#else
+#  define CFG_COMPILE_STATS	"0"
+#endif
+
+#ifdef TCL_CFG_DO64BIT
+#  define CFG_64		"1"
+#else
+#  define CFG_64		"0"
+#endif
+
+#ifndef NDEBUG
+#  define CFG_DEBUG		"1"
+#else
+#  define CFG_DEBUG		"0"
+#endif
+
+#ifdef TCL_CFG_OPTIMIZED
+#  define CFG_OPTIMIZED		"1"
+#else
+#  define CFG_OPTIMIZED		"0"
+#endif
+
+#ifdef TCL_CFG_PROFILED
+#  define CFG_PROFILED		"1"
+#else
+#  define CFG_PROFILED		"0"
+#endif
+
+static Tcl_Config const cfg[] = {
+    {"debug",			CFG_DEBUG},
+    {"threaded",		CFG_THREADED},
+    {"profiled",		CFG_PROFILED},
+    {"64bit",			CFG_64},
+    {"optimized",		CFG_OPTIMIZED},
+    {"mem_debug",		CFG_MEMDEBUG},
+    {"compile_debug",		CFG_COMPILE_DEBUG},
+    {"compile_stats",		CFG_COMPILE_STATS},
+
+    /* Runtime paths to various stuff */
+
+    {"libdir,runtime",		CFG_RUNTIME_LIBDIR},
+    {"bindir,runtime",		CFG_RUNTIME_BINDIR},
+    {"scriptdir,runtime",	CFG_RUNTIME_SCRDIR},
+    {"includedir,runtime",	CFG_RUNTIME_INCDIR},
+    {"docdir,runtime",		CFG_RUNTIME_DOCDIR},
+
+    /* Installation paths to various stuff */
+
+    {"libdir,install",		CFG_INSTALL_LIBDIR},
+    {"bindir,install",		CFG_INSTALL_BINDIR},
+    {"scriptdir,install",	CFG_INSTALL_SCRDIR},
+    {"includedir,install",	CFG_INSTALL_INCDIR},
+    {"docdir,install",		CFG_INSTALL_DOCDIR},
+
+    /* Last entry, closes the array */
+    {NULL, NULL}
+};
+
+void
+TclInitEmbeddedConfigurationInformation(
+    Tcl_Interp *interp)		/* Interpreter the configuration command is
+				 * registered in. */
+{
+    Tcl_RegisterConfig(interp, "tcl", cfg, TCL_CFGVAL_ENCODING);
+}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tclPlatDecls.h b/generic/tclPlatDecls.h
new file mode 100644
index 0000000..abc8ee8
--- /dev/null
+++ b/generic/tclPlatDecls.h
@@ -0,0 +1,122 @@
+/*
+ * tclPlatDecls.h --
+ *
+ *	Declarations of platform specific Tcl APIs.
+ *
+ * Copyright (c) 1998-1999 by Scriptics Corporation.
+ * All rights reserved.
+ */
+
+#ifndef _TCLPLATDECLS
+#define _TCLPLATDECLS
+
+#undef TCL_STORAGE_CLASS
+#ifdef BUILD_tcl
+#   define TCL_STORAGE_CLASS DLLEXPORT
+#else
+#   ifdef USE_TCL_STUBS
+#      define TCL_STORAGE_CLASS
+#   else
+#      define TCL_STORAGE_CLASS DLLIMPORT
+#   endif
+#endif
+
+/*
+ * WARNING: This file is automatically generated by the tools/genStubs.tcl
+ * script.  Any modifications to the function declarations below should be made
+ * in the generic/tcl.decls script.
+ */
+
+/*
+ * TCHAR is needed here for win32, so if it is not defined yet do it here.
+ * This way, we don't need to include <tchar.h> just for one define.
+ */
+#if (defined(_WIN32) || defined(__CYGWIN__)) && !defined(_TCHAR_DEFINED)
+#   if defined(_UNICODE)
+	typedef wchar_t TCHAR;
+#   else
+	typedef char TCHAR;
+#   endif
+#   define _TCHAR_DEFINED
+#endif
+
+/* !BEGIN!: Do not edit below this line. */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Exported function declarations:
+ */
+
+#if defined(_WIN32) || defined(__CYGWIN__) /* WIN */
+/* 0 */
+EXTERN TCHAR *		Tcl_WinUtfToTChar(const char *str, int len,
+				Tcl_DString *dsPtr);
+/* 1 */
+EXTERN char *		Tcl_WinTCharToUtf(const TCHAR *str, int len,
+				Tcl_DString *dsPtr);
+#endif /* WIN */
+#ifdef MAC_OSX_TCL /* MACOSX */
+/* 0 */
+EXTERN int		Tcl_MacOSXOpenBundleResources(Tcl_Interp *interp,
+				const char *bundleName, int hasResourceFile,
+				int maxPathLen, char *libraryPath);
+/* 1 */
+EXTERN int		Tcl_MacOSXOpenVersionedBundleResources(
+				Tcl_Interp *interp, const char *bundleName,
+				const char *bundleVersion,
+				int hasResourceFile, int maxPathLen,
+				char *libraryPath);
+#endif /* MACOSX */
+
+typedef struct TclPlatStubs {
+    int magic;
+    void *hooks;
+
+#if defined(_WIN32) || defined(__CYGWIN__) /* WIN */
+    TCHAR * (*tcl_WinUtfToTChar) (const char *str, int len, Tcl_DString *dsPtr); /* 0 */
+    char * (*tcl_WinTCharToUtf) (const TCHAR *str, int len, Tcl_DString *dsPtr); /* 1 */
+#endif /* WIN */
+#ifdef MAC_OSX_TCL /* MACOSX */
+    int (*tcl_MacOSXOpenBundleResources) (Tcl_Interp *interp, const char *bundleName, int hasResourceFile, int maxPathLen, char *libraryPath); /* 0 */
+    int (*tcl_MacOSXOpenVersionedBundleResources) (Tcl_Interp *interp, const char *bundleName, const char *bundleVersion, int hasResourceFile, int maxPathLen, char *libraryPath); /* 1 */
+#endif /* MACOSX */
+} TclPlatStubs;
+
+extern const TclPlatStubs *tclPlatStubsPtr;
+
+#ifdef __cplusplus
+}
+#endif
+
+#if defined(USE_TCL_STUBS)
+
+/*
+ * Inline function declarations:
+ */
+
+#if defined(_WIN32) || defined(__CYGWIN__) /* WIN */
+#define Tcl_WinUtfToTChar \
+	(tclPlatStubsPtr->tcl_WinUtfToTChar) /* 0 */
+#define Tcl_WinTCharToUtf \
+	(tclPlatStubsPtr->tcl_WinTCharToUtf) /* 1 */
+#endif /* WIN */
+#ifdef MAC_OSX_TCL /* MACOSX */
+#define Tcl_MacOSXOpenBundleResources \
+	(tclPlatStubsPtr->tcl_MacOSXOpenBundleResources) /* 0 */
+#define Tcl_MacOSXOpenVersionedBundleResources \
+	(tclPlatStubsPtr->tcl_MacOSXOpenVersionedBundleResources) /* 1 */
+#endif /* MACOSX */
+
+#endif /* defined(USE_TCL_STUBS) */
+
+/* !END!: Do not edit above this line. */
+
+#undef TCL_STORAGE_CLASS
+#define TCL_STORAGE_CLASS DLLIMPORT
+
+#endif /* _TCLPLATDECLS */
+
+
diff --git a/generic/tclPort.h b/generic/tclPort.h
new file mode 100644
index 0000000..12a60db
--- /dev/null
+++ b/generic/tclPort.h
@@ -0,0 +1,43 @@
+/*
+ * tclPort.h --
+ *
+ *	This header file handles porting issues that occur because
+ *	of differences between systems.  It reads in platform specific
+ *	portability files.
+ *
+ * Copyright (c) 1994-1995 Sun Microsystems, Inc.
+ *
+ * See the file "license.terms" for information on usage and redistribution
+ * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#ifndef _TCLPORT
+#define _TCLPORT
+
+#ifdef HAVE_TCL_CONFIG_H
+#include "tclConfig.h"
+#endif
+#if defined(_WIN32)
+#   include "tclWinPort.h"
+#else
+#   include "tclUnixPort.h"
+#endif
+#include "tcl.h"
+
+#if !defined(LLONG_MIN)
+#   ifdef TCL_WIDE_INT_IS_LONG
+#      define LLONG_MIN LONG_MIN
+#   else
+#      ifdef LLONG_BIT
+#         define LLONG_MIN ((Tcl_WideInt)(Tcl_LongAsWide(1)<<(LLONG_BIT-1)))
+#      else
+/* Assume we're on a system with a 64-bit 'long long' type */
+#         define LLONG_MIN ((Tcl_WideInt)(Tcl_LongAsWide(1)<<63))
+#      endif
+#   endif
+/* Assume that if LLONG_MIN is undefined, then so is LLONG_MAX */
+#   define LLONG_MAX (~LLONG_MIN)
+#endif
+
+
+#endif /* _TCLPORT */
diff --git a/generic/tclPosixStr.c b/generic/tclPosixStr.c
new file mode 100644
index 0000000..411eb27
--- /dev/null
+++ b/generic/tclPosixStr.c
@@ -0,0 +1,1211 @@
+/*
+ * tclPosixStr.c --
+ *
+ *	This file contains procedures that generate strings corresponding to
+ *	various POSIX-related codes, such as errno and signals.
+ *
+ * Copyright (c) 1991-1994 The Regents of the University of California.
+ * Copyright (c) 1994-1996 Sun Microsystems, Inc.
+ *
+ * See the file "license.terms" for information on usage and redistribution
+ * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#include "tclInt.h"
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_ErrnoId --
+ *
+ *	Return a textual identifier for the current errno value.
+ *
+ * Results:
+ *	This procedure returns a machine-readable textual identifier that
+ *	corresponds to the current errno value (e.g. "EPERM"). The identifier
+ *	is the same as the #define name in errno.h.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+const char *
+Tcl_ErrnoId(void)
+{
+    switch (errno) {
+#if defined(E2BIG) && (!defined(EOVERFLOW) || (E2BIG != EOVERFLOW))
+    case E2BIG: return "E2BIG";
+#endif
+#ifdef EACCES
+    case EACCES: return "EACCES";
+#endif
+#ifdef EADDRINUSE
+    case EADDRINUSE: return "EADDRINUSE";
+#endif
+#ifdef EADDRNOTAVAIL
+    case EADDRNOTAVAIL: return "EADDRNOTAVAIL";
+#endif
+#ifdef EADV
+    case EADV: return "EADV";
+#endif
+#ifdef EAFNOSUPPORT
+    case EAFNOSUPPORT: return "EAFNOSUPPORT";
+#endif
+#ifdef EAGAIN
+    case EAGAIN: return "EAGAIN";
+#endif
+#ifdef EALIGN
+    case EALIGN: return "EALIGN";
+#endif
+#if defined(EALREADY) && (!defined(EBUSY) || (EALREADY != EBUSY))
+    case EALREADY: return "EALREADY";
+#endif
+#ifdef EBADE
+    case EBADE: return "EBADE";
+#endif
+#ifdef EBADF
+    case EBADF: return "EBADF";
+#endif
+#ifdef EBADFD
+    case EBADFD: return "EBADFD";
+#endif
+#ifdef EBADMSG
+    case EBADMSG: return "EBADMSG";
+#endif
+#ifdef ECANCELED
+    case ECANCELED: return "ECANCELED";
+#endif
+#ifdef EBADR
+    case EBADR: return "EBADR";
+#endif
+#ifdef EBADRPC
+    case EBADRPC: return "EBADRPC";
+#endif
+#ifdef EBADRQC
+    case EBADRQC: return "EBADRQC";
+#endif
+#ifdef EBADSLT
+    case EBADSLT: return "EBADSLT";
+#endif
+#ifdef EBFONT
+    case EBFONT: return "EBFONT";
+#endif
+#ifdef EBUSY
+    case EBUSY: return "EBUSY";
+#endif
+#ifdef ECHILD
+    case ECHILD: return "ECHILD";
+#endif
+#ifdef ECHRNG
+    case ECHRNG: return "ECHRNG";
+#endif
+#ifdef ECOMM
+    case ECOMM: return "ECOMM";
+#endif
+#ifdef ECONNABORTED
+    case ECONNABORTED: return "ECONNABORTED";
+#endif
+#ifdef ECONNREFUSED
+    case ECONNREFUSED: return "ECONNREFUSED";
+#endif
+#ifdef ECONNRESET
+    case ECONNRESET: return "ECONNRESET";
+#endif
+#if defined(EDEADLK) && (!defined(EWOULDBLOCK) || (EDEADLK != EWOULDBLOCK))
+    case EDEADLK: return "EDEADLK";
+#endif
+#if defined(EDEADLOCK) && (!defined(EDEADLK) || (EDEADLOCK != EDEADLK))
+    case EDEADLOCK: return "EDEADLOCK";
+#endif
+#ifdef EDESTADDRREQ
+    case EDESTADDRREQ: return "EDESTADDRREQ";
+#endif
+#ifdef EDIRTY
+    case EDIRTY: return "EDIRTY";
+#endif
+#ifdef EDOM
+    case EDOM: return "EDOM";
+#endif
+#ifdef EDOTDOT
+    case EDOTDOT: return "EDOTDOT";
+#endif
+#ifdef EDQUOT
+    case EDQUOT: return "EDQUOT";
+#endif
+#ifdef EDUPPKG
+    case EDUPPKG: return "EDUPPKG";
+#endif
+#ifdef EEXIST
+    case EEXIST: return "EEXIST";
+#endif
+#ifdef EFAULT
+    case EFAULT: return "EFAULT";
+#endif
+#ifdef EFBIG
+    case EFBIG: return "EFBIG";
+#endif
+#ifdef EHOSTDOWN
+    case EHOSTDOWN: return "EHOSTDOWN";
+#endif
+#ifdef EHOSTUNREACH
+    case EHOSTUNREACH: return "EHOSTUNREACH";
+#endif
+#if defined(EIDRM) && (!defined(EINPROGRESS) || (EIDRM != EINPROGRESS))
+    case EIDRM: return "EIDRM";
+#endif
+#ifdef EINIT
+    case EINIT: return "EINIT";
+#endif
+#ifdef EINPROGRESS
+    case EINPROGRESS: return "EINPROGRESS";
+#endif
+#ifdef EINTR
+    case EINTR: return "EINTR";
+#endif
+#ifdef EINVAL
+    case EINVAL: return "EINVAL";
+#endif
+#ifdef EIO
+    case EIO: return "EIO";
+#endif
+#ifdef EISCONN
+    case EISCONN: return "EISCONN";
+#endif
+#ifdef EISDIR
+    case EISDIR: return "EISDIR";
+#endif
+#ifdef EISNAME
+    case EISNAM: return "EISNAM";
+#endif
+#ifdef ELBIN
+    case ELBIN: return "ELBIN";
+#endif
+#ifdef EL2HLT
+    case EL2HLT: return "EL2HLT";
+#endif
+#ifdef EL2NSYNC
+    case EL2NSYNC: return "EL2NSYNC";
+#endif
+#ifdef EL3HLT
+    case EL3HLT: return "EL3HLT";
+#endif
+#ifdef EL3RST
+    case EL3RST: return "EL3RST";
+#endif
+#ifdef ELIBACC
+    case ELIBACC: return "ELIBACC";
+#endif
+#ifdef ELIBBAD
+    case ELIBBAD: return "ELIBBAD";
+#endif
+#ifdef ELIBEXEC
+    case ELIBEXEC: return "ELIBEXEC";
+#endif
+#if defined(ELIBMAX) && (!defined(ECANCELED) || (ELIBMAX != ECANCELED))
+    case ELIBMAX: return "ELIBMAX";
+#endif
+#ifdef ELIBSCN
+    case ELIBSCN: return "ELIBSCN";
+#endif
+#ifdef ELNRNG
+    case ELNRNG: return "ELNRNG";
+#endif
+#if defined(ELOOP) && (!defined(ENOENT) || (ELOOP != ENOENT))
+    case ELOOP: return "ELOOP";
+#endif
+#ifdef EMFILE
+    case EMFILE: return "EMFILE";
+#endif
+#ifdef EMLINK
+    case EMLINK: return "EMLINK";
+#endif
+#ifdef EMSGSIZE
+    case EMSGSIZE: return "EMSGSIZE";
+#endif
+#ifdef EMULTIHOP
+    case EMULTIHOP: return "EMULTIHOP";
+#endif
+#ifdef ENAMETOOLONG
+    case ENAMETOOLONG: return "ENAMETOOLONG";
+#endif
+#ifdef ENAVAIL
+    case ENAVAIL: return "ENAVAIL";
+#endif
+#ifdef ENET
+    case ENET: return "ENET";
+#endif
+#ifdef ENETDOWN
+    case ENETDOWN: return "ENETDOWN";
+#endif
+#ifdef ENETRESET
+    case ENETRESET: return "ENETRESET";
+#endif
+#ifdef ENETUNREACH
+    case ENETUNREACH: return "ENETUNREACH";
+#endif
+#ifdef ENFILE
+    case ENFILE: return "ENFILE";
+#endif
+#ifdef ENOANO
+    case ENOANO: return "ENOANO";
+#endif
+#if defined(ENOBUFS) && (!defined(ENOSR) || (ENOBUFS != ENOSR))
+    case ENOBUFS: return "ENOBUFS";
+#endif
+#ifdef ENOCSI
+    case ENOCSI: return "ENOCSI";
+#endif
+#if defined(ENODATA) && (!defined(ECONNREFUSED) || (ENODATA != ECONNREFUSED))
+    case ENODATA: return "ENODATA";
+#endif
+#ifdef ENODEV
+    case ENODEV: return "ENODEV";
+#endif
+#ifdef ENOENT
+    case ENOENT: return "ENOENT";
+#endif
+#ifdef ENOEXEC
+    case ENOEXEC: return "ENOEXEC";
+#endif
+#ifdef ENOLCK
+    case ENOLCK: return "ENOLCK";
+#endif
+#ifdef ENOLINK
+    case ENOLINK: return "ENOLINK";
+#endif
+#ifdef ENOMEM
+    case ENOMEM: return "ENOMEM";
+#endif
+#ifdef ENOMSG
+    case ENOMSG: return "ENOMSG";
+#endif
+#ifdef ENONET
+    case ENONET: return "ENONET";
+#endif
+#ifdef ENOPKG
+    case ENOPKG: return "ENOPKG";
+#endif
+#ifdef ENOPROTOOPT
+    case ENOPROTOOPT: return "ENOPROTOOPT";
+#endif
+#ifdef ENOSPC
+    case ENOSPC: return "ENOSPC";
+#endif
+#if defined(ENOSR) && (!defined(ENAMETOOLONG) || (ENAMETOOLONG != ENOSR))
+    case ENOSR: return "ENOSR";
+#endif
+#if defined(ENOSTR) && (!defined(ENOTTY) || (ENOTTY != ENOSTR))
+    case ENOSTR: return "ENOSTR";
+#endif
+#ifdef ENOSYM
+    case ENOSYM: return "ENOSYM";
+#endif
+#ifdef ENOSYS
+    case ENOSYS: return "ENOSYS";
+#endif
+#ifdef ENOTBLK
+    case ENOTBLK: return "ENOTBLK";
+#endif
+#ifdef ENOTCONN
+    case ENOTCONN: return "ENOTCONN";
+#endif
+#ifdef ENOTRECOVERABLE
+    case ENOTRECOVERABLE: return "ENOTRECOVERABLE";
+#endif
+#ifdef ENOTDIR
+    case ENOTDIR: return "ENOTDIR";
+#endif
+#if defined(ENOTEMPTY) && (!defined(EEXIST) || (ENOTEMPTY != EEXIST))
+    case ENOTEMPTY: return "ENOTEMPTY";
+#endif
+#ifdef ENOTNAM
+    case ENOTNAM: return "ENOTNAM";
+#endif
+#ifdef ENOTSOCK
+    case ENOTSOCK: return "ENOTSOCK";
+#endif
+#ifdef ENOTSUP
+    case ENOTSUP: return "ENOTSUP";
+#endif
+#ifdef ENOTTY
+    case ENOTTY: return "ENOTTY";
+#endif
+#ifdef ENOTUNIQ
+    case ENOTUNIQ: return "ENOTUNIQ";
+#endif
+#ifdef ENXIO
+    case ENXIO: return "ENXIO";
+#endif
+#if defined(EOPNOTSUPP) &&  (!defined(ENOTSUP) || (ENOTSUP != EOPNOTSUPP))
+    case EOPNOTSUPP: return "EOPNOTSUPP";
+#endif
+#ifdef EOTHER
+    case EOTHER: return "EOTHER";
+#endif
+#if defined(EOVERFLOW) && (!defined(EFBIG) || (EOVERFLOW != EFBIG)) && (!defined(EINVAL) || (EOVERFLOW != EINVAL))
+    case EOVERFLOW: return "EOVERFLOW";
+#endif
+#ifdef EOWNERDEAD
+    case EOWNERDEAD: return "EOWNERDEAD";
+#endif
+#ifdef EPERM
+    case EPERM: return "EPERM";
+#endif
+#if defined(EPFNOSUPPORT) && (!defined(ENOLCK) || (ENOLCK != EPFNOSUPPORT))
+    case EPFNOSUPPORT: return "EPFNOSUPPORT";
+#endif
+#ifdef EPIPE
+    case EPIPE: return "EPIPE";
+#endif
+#ifdef EPROCLIM
+    case EPROCLIM: return "EPROCLIM";
+#endif
+#ifdef EPROCUNAVAIL
+    case EPROCUNAVAIL: return "EPROCUNAVAIL";
+#endif
+#ifdef EPROGMISMATCH
+    case EPROGMISMATCH: return "EPROGMISMATCH";
+#endif
+#ifdef EPROGUNAVAIL
+    case EPROGUNAVAIL: return "EPROGUNAVAIL";
+#endif
+#ifdef EPROTO
+    case EPROTO: return "EPROTO";
+#endif
+#ifdef EPROTONOSUPPORT
+    case EPROTONOSUPPORT: return "EPROTONOSUPPORT";
+#endif
+#ifdef EPROTOTYPE
+    case EPROTOTYPE: return "EPROTOTYPE";
+#endif
+#ifdef ERANGE
+    case ERANGE: return "ERANGE";
+#endif
+#if defined(EREFUSED) && (!defined(ECONNREFUSED) || (EREFUSED != ECONNREFUSED))
+    case EREFUSED: return "EREFUSED";
+#endif
+#ifdef EREMCHG
+    case EREMCHG: return "EREMCHG";
+#endif
+#ifdef EREMDEV
+    case EREMDEV: return "EREMDEV";
+#endif
+#ifdef EREMOTE
+    case EREMOTE: return "EREMOTE";
+#endif
+#ifdef EREMOTEIO
+    case EREMOTEIO: return "EREMOTEIO";
+#endif
+#ifdef EREMOTERELEASE
+    case EREMOTERELEASE: return "EREMOTERELEASE";
+#endif
+#ifdef EROFS
+    case EROFS: return "EROFS";
+#endif
+#ifdef ERPCMISMATCH
+    case ERPCMISMATCH: return "ERPCMISMATCH";
+#endif
+#ifdef ERREMOTE
+    case ERREMOTE: return "ERREMOTE";
+#endif
+#ifdef ESHUTDOWN
+    case ESHUTDOWN: return "ESHUTDOWN";
+#endif
+#ifdef ESOCKTNOSUPPORT
+    case ESOCKTNOSUPPORT: return "ESOCKTNOSUPPORT";
+#endif
+#ifdef ESPIPE
+    case ESPIPE: return "ESPIPE";
+#endif
+#ifdef ESRCH
+    case ESRCH: return "ESRCH";
+#endif
+#ifdef ESRMNT
+    case ESRMNT: return "ESRMNT";
+#endif
+#ifdef ESTALE
+    case ESTALE: return "ESTALE";
+#endif
+#ifdef ESUCCESS
+    case ESUCCESS: return "ESUCCESS";
+#endif
+#if defined(ETIME) && (!defined(ELOOP) || (ETIME != ELOOP))
+    case ETIME: return "ETIME";
+#endif
+#if defined(ETIMEDOUT) && (!defined(ENOSTR) || (ETIMEDOUT != ENOSTR))
+    case ETIMEDOUT: return "ETIMEDOUT";
+#endif
+#ifdef ETOOMANYREFS
+    case ETOOMANYREFS: return "ETOOMANYREFS";
+#endif
+#ifdef ETXTBSY
+    case ETXTBSY: return "ETXTBSY";
+#endif
+#ifdef EUCLEAN
+    case EUCLEAN: return "EUCLEAN";
+#endif
+#ifdef EUNATCH
+    case EUNATCH: return "EUNATCH";
+#endif
+#ifdef EUSERS
+    case EUSERS: return "EUSERS";
+#endif
+#ifdef EVERSION
+    case EVERSION: return "EVERSION";
+#endif
+#if defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN))
+    case EWOULDBLOCK: return "EWOULDBLOCK";
+#endif
+#ifdef EXDEV
+    case EXDEV: return "EXDEV";
+#endif
+#ifdef EXFULL
+    case EXFULL: return "EXFULL";
+#endif
+    }
+    return "unknown error";
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_ErrnoMsg --
+ *
+ *	Return a human-readable message corresponding to a given errno value.
+ *
+ * Results:
+ *	The return value is the standard POSIX error message for errno.  This
+ *	procedure is used instead of strerror because strerror returns
+ *	slightly different values on different machines (e.g. different
+ *	capitalizations), which cause problems for things such as regression
+ *	tests. This procedure provides messages for most standard errors, then
+ *	it calls strerror for things it doesn't understand.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+const char *
+Tcl_ErrnoMsg(
+     int err)			/* Error number (such as in errno variable). */
+{
+    switch (err) {
+#if defined(E2BIG) && (!defined(EOVERFLOW) || (E2BIG != EOVERFLOW))
+    case E2BIG: return "argument list too long";
+#endif
+#ifdef EACCES
+    case EACCES: return "permission denied";
+#endif
+#ifdef EADDRINUSE
+    case EADDRINUSE: return "address already in use";
+#endif
+#ifdef EADDRNOTAVAIL
+    case EADDRNOTAVAIL: return "cannot assign requested address";
+#endif
+#ifdef EADV
+    case EADV: return "advertise error";
+#endif
+#ifdef EAFNOSUPPORT
+    case EAFNOSUPPORT: return "address family not supported by protocol";
+#endif
+#ifdef EAGAIN
+    case EAGAIN: return "resource temporarily unavailable";
+#endif
+#ifdef EALIGN
+    case EALIGN: return "EALIGN";
+#endif
+#if defined(EALREADY) && (!defined(EBUSY) || (EALREADY != EBUSY))
+    case EALREADY: return "operation already in progress";
+#endif
+#ifdef EBADE
+    case EBADE: return "bad exchange descriptor";
+#endif
+#ifdef EBADF
+    case EBADF: return "bad file number";
+#endif
+#ifdef EBADFD
+    case EBADFD: return "file descriptor in bad state";
+#endif
+#ifdef EBADMSG
+    case EBADMSG: return "not a data message";
+#endif
+#ifdef ECANCELED
+    case ECANCELED: return "operation canceled";
+#endif
+#ifdef EBADR
+    case EBADR: return "bad request descriptor";
+#endif
+#ifdef EBADRPC
+    case EBADRPC: return "RPC structure is bad";
+#endif
+#ifdef EBADRQC
+    case EBADRQC: return "bad request code";
+#endif
+#ifdef EBADSLT
+    case EBADSLT: return "invalid slot";
+#endif
+#ifdef EBFONT
+    case EBFONT: return "bad font file format";
+#endif
+#ifdef EBUSY
+    case EBUSY: return "file busy";
+#endif
+#ifdef ECHILD
+    case ECHILD: return "no children";
+#endif
+#ifdef ECHRNG
+    case ECHRNG: return "channel number out of range";
+#endif
+#ifdef ECOMM
+    case ECOMM: return "communication error on send";
+#endif
+#ifdef ECONNABORTED
+    case ECONNABORTED: return "software caused connection abort";
+#endif
+#ifdef ECONNREFUSED
+    case ECONNREFUSED: return "connection refused";
+#endif
+#ifdef ECONNRESET
+    case ECONNRESET: return "connection reset by peer";
+#endif
+#if defined(EDEADLK) && (!defined(EWOULDBLOCK) || (EDEADLK != EWOULDBLOCK))
+    case EDEADLK: return "resource deadlock avoided";
+#endif
+#if defined(EDEADLOCK) && (!defined(EDEADLK) || (EDEADLOCK != EDEADLK))
+    case EDEADLOCK: return "resource deadlock avoided";
+#endif
+#ifdef EDESTADDRREQ
+    case EDESTADDRREQ: return "destination address required";
+#endif
+#ifdef EDIRTY
+    case EDIRTY: return "mounting a dirty fs w/o force";
+#endif
+#ifdef EDOM
+    case EDOM: return "math argument out of range";
+#endif
+#ifdef EDOTDOT
+    case EDOTDOT: return "cross mount point";
+#endif
+#ifdef EDQUOT
+    case EDQUOT: return "disk quota exceeded";
+#endif
+#ifdef EDUPPKG
+    case EDUPPKG: return "duplicate package name";
+#endif
+#ifdef EEXIST
+    case EEXIST: return "file already exists";
+#endif
+#ifdef EFAULT
+    case EFAULT: return "bad address in system call argument";
+#endif
+#ifdef EFBIG
+    case EFBIG: return "file too large";
+#endif
+#ifdef EHOSTDOWN
+    case EHOSTDOWN: return "host is down";
+#endif
+#ifdef EHOSTUNREACH
+    case EHOSTUNREACH: return "host is unreachable";
+#endif
+#if defined(EIDRM) && (!defined(EINPROGRESS) || (EIDRM != EINPROGRESS))
+    case EIDRM: return "identifier removed";
+#endif
+#ifdef EINIT
+    case EINIT: return "initialization error";
+#endif
+#ifdef EINPROGRESS
+    case EINPROGRESS: return "operation now in progress";
+#endif
+#ifdef EINTR
+    case EINTR: return "interrupted system call";
+#endif
+#ifdef EINVAL
+    case EINVAL: return "invalid argument";
+#endif
+#ifdef EIO
+    case EIO: return "I/O error";
+#endif
+#ifdef EISCONN
+    case EISCONN: return "socket is already connected";
+#endif
+#ifdef EISDIR
+    case EISDIR: return "illegal operation on a directory";
+#endif
+#ifdef EISNAME
+    case EISNAM: return "is a name file";
+#endif
+#ifdef ELBIN
+    case ELBIN: return "ELBIN";
+#endif
+#ifdef EL2HLT
+    case EL2HLT: return "level 2 halted";
+#endif
+#ifdef EL2NSYNC
+    case EL2NSYNC: return "level 2 not synchronized";
+#endif
+#ifdef EL3HLT
+    case EL3HLT: return "level 3 halted";
+#endif
+#ifdef EL3RST
+    case EL3RST: return "level 3 reset";
+#endif
+#ifdef ELIBACC
+    case ELIBACC: return "cannot access a needed shared library";
+#endif
+#ifdef ELIBBAD
+    case ELIBBAD: return "accessing a corrupted shared library";
+#endif
+#ifdef ELIBEXEC
+    case ELIBEXEC: return "cannot exec a shared library directly";
+#endif
+#if defined(ELIBMAX) && (!defined(ECANCELED) || (ELIBMAX != ECANCELED))
+    case ELIBMAX: return
+	    "attempting to link in more shared libraries than system limit";
+#endif
+#ifdef ELIBSCN
+    case ELIBSCN: return ".lib section in a.out corrupted";
+#endif
+#ifdef ELNRNG
+    case ELNRNG: return "link number out of range";
+#endif
+#if defined(ELOOP) && (!defined(ENOENT) || (ELOOP != ENOENT))
+    case ELOOP: return "too many levels of symbolic links";
+#endif
+#ifdef EMFILE
+    case EMFILE: return "too many open files";
+#endif
+#ifdef EMLINK
+    case EMLINK: return "too many links";
+#endif
+#ifdef EMSGSIZE
+    case EMSGSIZE: return "message too long";
+#endif
+#ifdef EMULTIHOP
+    case EMULTIHOP: return "multihop attempted";
+#endif
+#ifdef ENAMETOOLONG
+    case ENAMETOOLONG: return "file name too long";
+#endif
+#ifdef ENAVAIL
+    case ENAVAIL: return "not available";
+#endif
+#ifdef ENET
+    case ENET: return "ENET";
+#endif
+#ifdef ENETDOWN
+    case ENETDOWN: return "network is down";
+#endif
+#ifdef ENETRESET
+    case ENETRESET: return "network dropped connection on reset";
+#endif
+#ifdef ENETUNREACH
+    case ENETUNREACH: return "network is unreachable";
+#endif
+#ifdef ENFILE
+    case ENFILE: return "file table overflow";
+#endif
+#ifdef ENOANO
+    case ENOANO: return "anode table overflow";
+#endif
+#if defined(ENOBUFS) && (!defined(ENOSR) || (ENOBUFS != ENOSR))
+    case ENOBUFS: return "no buffer space available";
+#endif
+#ifdef ENOCSI
+    case ENOCSI: return "no CSI structure available";
+#endif
+#if defined(ENODATA) && (!defined(ECONNREFUSED) || (ENODATA != ECONNREFUSED))
+    case ENODATA: return "no data available";
+#endif
+#ifdef ENODEV
+    case ENODEV: return "no such device";
+#endif
+#ifdef ENOENT
+    case ENOENT: return "no such file or directory";
+#endif
+#ifdef ENOEXEC
+    case ENOEXEC: return "exec format error";
+#endif
+#ifdef ENOLCK
+    case ENOLCK: return "no locks available";
+#endif
+#ifdef ENOLINK
+    case ENOLINK: return "link has been severed";
+#endif
+#ifdef ENOMEM
+    case ENOMEM: return "not enough memory";
+#endif
+#ifdef ENOMSG
+    case ENOMSG: return "no message of desired type";
+#endif
+#ifdef ENONET
+    case ENONET: return "machine is not on the network";
+#endif
+#ifdef ENOPKG
+    case ENOPKG: return "package not installed";
+#endif
+#ifdef ENOPROTOOPT
+    case ENOPROTOOPT: return "bad protocol option";
+#endif
+#ifdef ENOSPC
+    case ENOSPC: return "no space left on device";
+#endif
+#if defined(ENOSR) && (!defined(ENAMETOOLONG) || (ENAMETOOLONG != ENOSR))
+    case ENOSR: return "out of stream resources";
+#endif
+#if defined(ENOSTR) && (!defined(ENOTTY) || (ENOTTY != ENOSTR))
+    case ENOSTR: return "not a stream device";
+#endif
+#ifdef ENOSYM
+    case ENOSYM: return "unresolved symbol name";
+#endif
+#ifdef ENOSYS
+    case ENOSYS: return "function not implemented";
+#endif
+#ifdef ENOTBLK
+    case ENOTBLK: return "block device required";
+#endif
+#ifdef ENOTCONN
+    case ENOTCONN: return "socket is not connected";
+#endif
+#ifdef ENOTRECOVERABLE
+    case ENOTRECOVERABLE: return "state not recoverable";
+#endif
+#ifdef ENOTDIR
+    case ENOTDIR: return "not a directory";
+#endif
+#if defined(ENOTEMPTY) && (!defined(EEXIST) || (ENOTEMPTY != EEXIST))
+    case ENOTEMPTY: return "directory not empty";
+#endif
+#ifdef ENOTNAM
+    case ENOTNAM: return "not a name file";
+#endif
+#ifdef ENOTSOCK
+    case ENOTSOCK: return "socket operation on non-socket";
+#endif
+#ifdef ENOTSUP
+    case ENOTSUP: return "operation not supported";
+#endif
+#ifdef ENOTTY
+    case ENOTTY: return "inappropriate device for ioctl";
+#endif
+#ifdef ENOTUNIQ
+    case ENOTUNIQ: return "name not unique on network";
+#endif
+#ifdef ENXIO
+    case ENXIO: return "no such device or address";
+#endif
+#if defined(EOPNOTSUPP) &&  (!defined(ENOTSUP) || (ENOTSUP != EOPNOTSUPP))
+    case EOPNOTSUPP: return "operation not supported on socket";
+#endif
+#ifdef EOTHER
+    case EOTHER: return "other error";
+#endif
+#if defined(EOVERFLOW) && (!defined(EFBIG) || (EOVERFLOW != EFBIG)) && (!defined(EINVAL) || (EOVERFLOW != EINVAL))
+    case EOVERFLOW: return "file too big";
+#endif
+#ifdef EOWNERDEAD
+    case EOWNERDEAD: return "owner died";
+#endif
+#ifdef EPERM
+    case EPERM: return "not owner";
+#endif
+#if defined(EPFNOSUPPORT) && (!defined(ENOLCK) || (ENOLCK != EPFNOSUPPORT))
+    case EPFNOSUPPORT: return "protocol family not supported";
+#endif
+#ifdef EPIPE
+    case EPIPE: return "broken pipe";
+#endif
+#ifdef EPROCLIM
+    case EPROCLIM: return "too many processes";
+#endif
+#ifdef EPROCUNAVAIL
+    case EPROCUNAVAIL: return "bad procedure for program";
+#endif
+#ifdef EPROGMISMATCH
+    case EPROGMISMATCH: return "program version wrong";
+#endif
+#ifdef EPROGUNAVAIL
+    case EPROGUNAVAIL: return "RPC program not available";
+#endif
+#ifdef EPROTO
+    case EPROTO: return "protocol error";
+#endif
+#ifdef EPROTONOSUPPORT
+    case EPROTONOSUPPORT: return "protocol not supported";
+#endif
+#ifdef EPROTOTYPE
+    case EPROTOTYPE: return "protocol wrong type for socket";
+#endif
+#ifdef ERANGE
+    case ERANGE: return "math result unrepresentable";
+#endif
+#if defined(EREFUSED) && (!defined(ECONNREFUSED) || (EREFUSED != ECONNREFUSED))
+    case EREFUSED: return "EREFUSED";
+#endif
+#ifdef EREMCHG
+    case EREMCHG: return "remote address changed";
+#endif
+#ifdef EREMDEV
+    case EREMDEV: return "remote device";
+#endif
+#ifdef EREMOTE
+    case EREMOTE: return "pathname hit remote file system";
+#endif
+#ifdef EREMOTEIO
+    case EREMOTEIO: return "remote i/o error";
+#endif
+#ifdef EREMOTERELEASE
+    case EREMOTERELEASE: return "EREMOTERELEASE";
+#endif
+#ifdef EROFS
+    case EROFS: return "read-only file system";
+#endif
+#ifdef ERPCMISMATCH
+    case ERPCMISMATCH: return "RPC version is wrong";
+#endif
+#ifdef ERREMOTE
+    case ERREMOTE: return "object is remote";
+#endif
+#ifdef ESHUTDOWN
+    case ESHUTDOWN: return "cannot send after socket shutdown";
+#endif
+#ifdef ESOCKTNOSUPPORT
+    case ESOCKTNOSUPPORT: return "socket type not supported";
+#endif
+#ifdef ESPIPE
+    case ESPIPE: return "invalid seek";
+#endif
+#ifdef ESRCH
+    case ESRCH: return "no such process";
+#endif
+#ifdef ESRMNT
+    case ESRMNT: return "srmount error";
+#endif
+#ifdef ESTALE
+    case ESTALE: return "stale remote file handle";
+#endif
+#ifdef ESUCCESS
+    case ESUCCESS: return "Error 0";
+#endif
+#if defined(ETIME) && (!defined(ELOOP) || (ETIME != ELOOP))
+    case ETIME: return "timer expired";
+#endif
+#if defined(ETIMEDOUT) && (!defined(ENOSTR) || (ETIMEDOUT != ENOSTR))
+    case ETIMEDOUT: return "connection timed out";
+#endif
+#ifdef ETOOMANYREFS
+    case ETOOMANYREFS: return "too many references: cannot splice";
+#endif
+#ifdef ETXTBSY
+    case ETXTBSY: return "text file or pseudo-device busy";
+#endif
+#ifdef EUCLEAN
+    case EUCLEAN: return "structure needs cleaning";
+#endif
+#ifdef EUNATCH
+    case EUNATCH: return "protocol driver not attached";
+#endif
+#ifdef EUSERS
+    case EUSERS: return "too many users";
+#endif
+#ifdef EVERSION
+    case EVERSION: return "version mismatch";
+#endif
+#if defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN))
+    case EWOULDBLOCK: return "operation would block";
+#endif
+#ifdef EXDEV
+    case EXDEV: return "cross-domain link";
+#endif
+#ifdef EXFULL
+    case EXFULL: return "message tables full";
+#endif
+    default:
+#ifdef NO_STRERROR
+	return "unknown POSIX error";
+#else
+	return strerror(err);
+#endif
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_SignalId --
+ *
+ *	Return a textual identifier for a signal number.
+ *
+ * Results:
+ *	This procedure returns a machine-readable textual identifier that
+ *	corresponds to sig.  The identifier is the same as the #define name in
+ *	signal.h.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+const char *
+Tcl_SignalId(
+     int sig)			/* Number of signal. */
+{
+    switch (sig) {
+#ifdef SIGABRT
+    case SIGABRT: return "SIGABRT";
+#endif
+#ifdef SIGALRM
+    case SIGALRM: return "SIGALRM";
+#endif
+#ifdef SIGBUS
+    case SIGBUS: return "SIGBUS";
+#endif
+#ifdef SIGCHLD
+    case SIGCHLD: return "SIGCHLD";
+#endif
+#if defined(SIGCLD) && (!defined(SIGCHLD) || (SIGCLD != SIGCHLD))
+    case SIGCLD: return "SIGCLD";
+#endif
+#ifdef SIGCONT
+    case SIGCONT: return "SIGCONT";
+#endif
+#if defined(SIGEMT) && (!defined(SIGXCPU) || (SIGEMT != SIGXCPU))
+    case SIGEMT: return "SIGEMT";
+#endif
+#ifdef SIGFPE
+    case SIGFPE: return "SIGFPE";
+#endif
+#ifdef SIGHUP
+    case SIGHUP: return "SIGHUP";
+#endif
+#ifdef SIGILL
+    case SIGILL: return "SIGILL";
+#endif
+#ifdef SIGINT
+    case SIGINT: return "SIGINT";
+#endif
+#ifdef SIGIO
+    case SIGIO: return "SIGIO";
+#endif
+#if defined(SIGIOT) && (!defined(SIGABRT) || (SIGIOT != SIGABRT))
+    case SIGIOT: return "SIGIOT";
+#endif
+#ifdef SIGKILL
+    case SIGKILL: return "SIGKILL";
+#endif
+#if defined(SIGLOST) && (!defined(SIGIOT) || (SIGLOST != SIGIOT)) && (!defined(SIGURG) || (SIGLOST != SIGURG)) && (!defined(SIGPROF) || (SIGLOST != SIGPROF)) && (!defined(SIGIO) || (SIGLOST != SIGIO))
+    case SIGLOST: return "SIGLOST";
+#endif
+#ifdef SIGPIPE
+    case SIGPIPE: return "SIGPIPE";
+#endif
+#if defined(SIGPOLL) && (!defined(SIGIO) || (SIGPOLL != SIGIO))
+    case SIGPOLL: return "SIGPOLL";
+#endif
+#ifdef SIGPROF
+    case SIGPROF: return "SIGPROF";
+#endif
+#if defined(SIGPWR) && (!defined(SIGXFSZ) || (SIGPWR != SIGXFSZ)) && (!defined(SIGLOST) || (SIGPWR != SIGLOST))
+    case SIGPWR: return "SIGPWR";
+#endif
+#ifdef SIGQUIT
+    case SIGQUIT: return "SIGQUIT";
+#endif
+#if defined(SIGSEGV) && (!defined(SIGBUS) || (SIGSEGV != SIGBUS))
+    case SIGSEGV: return "SIGSEGV";
+#endif
+#ifdef SIGSTOP
+    case SIGSTOP: return "SIGSTOP";
+#endif
+#ifdef SIGSYS
+    case SIGSYS: return "SIGSYS";
+#endif
+#ifdef SIGTERM
+    case SIGTERM: return "SIGTERM";
+#endif
+#ifdef SIGTRAP
+    case SIGTRAP: return "SIGTRAP";
+#endif
+#ifdef SIGTSTP
+    case SIGTSTP: return "SIGTSTP";
+#endif
+#ifdef SIGTTIN
+    case SIGTTIN: return "SIGTTIN";
+#endif
+#ifdef SIGTTOU
+    case SIGTTOU: return "SIGTTOU";
+#endif
+#if defined(SIGURG) && (!defined(SIGIO) || (SIGURG != SIGIO))
+    case SIGURG: return "SIGURG";
+#endif
+#if defined(SIGUSR1) && (!defined(SIGIO) || (SIGUSR1 != SIGIO))
+    case SIGUSR1: return "SIGUSR1";
+#endif
+#if defined(SIGUSR2) && (!defined(SIGURG) || (SIGUSR2 != SIGURG))
+    case SIGUSR2: return "SIGUSR2";
+#endif
+#ifdef SIGVTALRM
+    case SIGVTALRM: return "SIGVTALRM";
+#endif
+#ifdef SIGWINCH
+    case SIGWINCH: return "SIGWINCH";
+#endif
+#ifdef SIGXCPU
+    case SIGXCPU: return "SIGXCPU";
+#endif
+#ifdef SIGXFSZ
+    case SIGXFSZ: return "SIGXFSZ";
+#endif
+#if defined(SIGINFO) && (!defined(SIGPWR) || (SIGINFO != SIGPWR))
+    case SIGINFO: return "SIGINFO";
+#endif
+    }
+    return "unknown signal";
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_SignalMsg --
+ *
+ *	Return a human-readable message describing a signal.
+ *
+ * Results:
+ *	This procedure returns a string describing sig that should make sense
+ *	to a human.  It may not be easy for a machine to parse.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+const char *
+Tcl_SignalMsg(
+     int sig)			/* Number of signal. */
+{
+    switch (sig) {
+#ifdef SIGABRT
+    case SIGABRT: return "SIGABRT";
+#endif
+#ifdef SIGALRM
+    case SIGALRM: return "alarm clock";
+#endif
+#ifdef SIGBUS
+    case SIGBUS: return "bus error";
+#endif
+#ifdef SIGCHLD
+    case SIGCHLD: return "child status changed";
+#endif
+#if defined(SIGCLD) && (!defined(SIGCHLD) || (SIGCLD != SIGCHLD))
+    case SIGCLD: return "child status changed";
+#endif
+#ifdef SIGCONT
+    case SIGCONT: return "continue after stop";
+#endif
+#if defined(SIGEMT) && (!defined(SIGXCPU) || (SIGEMT != SIGXCPU))
+    case SIGEMT: return "EMT instruction";
+#endif
+#ifdef SIGFPE
+    case SIGFPE: return "floating-point exception";
+#endif
+#ifdef SIGHUP
+    case SIGHUP: return "hangup";
+#endif
+#ifdef SIGILL
+    case SIGILL: return "illegal instruction";
+#endif
+#ifdef SIGINT
+    case SIGINT: return "interrupt";
+#endif
+#ifdef SIGIO
+    case SIGIO: return "input/output possible on file";
+#endif
+#if defined(SIGIOT) && (!defined(SIGABRT) || (SIGABRT != SIGIOT))
+    case SIGIOT: return "IOT instruction";
+#endif
+#ifdef SIGKILL
+    case SIGKILL: return "kill signal";
+#endif
+#if defined(SIGLOST) && (!defined(SIGIOT) || (SIGLOST != SIGIOT)) && (!defined(SIGURG) || (SIGLOST != SIGURG)) && (!defined(SIGPROF) || (SIGLOST != SIGPROF)) && (!defined(SIGIO) || (SIGLOST != SIGIO))
+    case SIGLOST: return "resource lost";
+#endif
+#ifdef SIGPIPE
+    case SIGPIPE: return "write on pipe with no readers";
+#endif
+#if defined(SIGPOLL) && (!defined(SIGIO) || (SIGPOLL != SIGIO))
+    case SIGPOLL: return "input/output possible on file";
+#endif
+#ifdef SIGPROF
+    case SIGPROF: return "profiling alarm";
+#endif
+#if defined(SIGPWR) && (!defined(SIGXFSZ) || (SIGPWR != SIGXFSZ)) && (!defined(SIGLOST) || (SIGPWR != SIGLOST))
+    case SIGPWR: return "power-fail restart";
+#endif
+#ifdef SIGQUIT
+    case SIGQUIT: return "quit signal";
+#endif
+#if defined(SIGSEGV) && (!defined(SIGBUS) || (SIGSEGV != SIGBUS))
+    case SIGSEGV: return "segmentation violation";
+#endif
+#ifdef SIGSTOP
+    case SIGSTOP: return "stop";
+#endif
+#ifdef SIGSYS
+    case SIGSYS: return "bad argument to system call";
+#endif
+#ifdef SIGTERM
+    case SIGTERM: return "software termination signal";
+#endif
+#ifdef SIGTRAP
+    case SIGTRAP: return "trace trap";
+#endif
+#ifdef SIGTSTP
+    case SIGTSTP: return "stop signal from tty";
+#endif
+#ifdef SIGTTIN
+    case SIGTTIN: return "background tty read";
+#endif
+#ifdef SIGTTOU
+    case SIGTTOU: return "background tty write";
+#endif
+#if defined(SIGURG) && (!defined(SIGIO) || (SIGURG != SIGIO))
+    case SIGURG: return "urgent I/O condition";
+#endif
+#if defined(SIGUSR1) && (!defined(SIGIO) || (SIGUSR1 != SIGIO))
+    case SIGUSR1: return "user-defined signal 1";
+#endif
+#if defined(SIGUSR2) && (!defined(SIGURG) || (SIGUSR2 != SIGURG))
+    case SIGUSR2: return "user-defined signal 2";
+#endif
+#ifdef SIGVTALRM
+    case SIGVTALRM: return "virtual time alarm";
+#endif
+#ifdef SIGWINCH
+    case SIGWINCH: return "window changed";
+#endif
+#ifdef SIGXCPU
+    case SIGXCPU: return "exceeded CPU time limit";
+#endif
+#ifdef SIGXFSZ
+    case SIGXFSZ: return "exceeded file size limit";
+#endif
+#if defined(SIGINFO) && (!defined(SIGPWR) || (SIGINFO != SIGPWR))
+    case SIGINFO: return "information request";
+#endif
+    }
+    return "unknown signal";
+}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tclPreserve.c b/generic/tclPreserve.c
new file mode 100644
index 0000000..cca13e8
--- /dev/null
+++ b/generic/tclPreserve.c
@@ -0,0 +1,473 @@
+/*
+ * tclPreserve.c --
+ *
+ *	This file contains a collection of functions that are used to make
+ *	sure that widget records and other data structures aren't reallocated
+ *	when there are nested functions that depend on their existence.
+ *
+ * Copyright (c) 1991-1994 The Regents of the University of California.
+ * Copyright (c) 1994-1998 Sun Microsystems, Inc.
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#include "tclInt.h"
+
+/*
+ * The following data structure is used to keep track of all the Tcl_Preserve
+ * calls that are still in effect. It grows as needed to accommodate any
+ * number of calls in effect.
+ */
+
+typedef struct {
+    ClientData clientData;	/* Address of preserved block. */
+    int refCount;		/* Number of Tcl_Preserve calls in effect for
+				 * block. */
+    int mustFree;		/* Non-zero means Tcl_EventuallyFree was
+				 * called while a Tcl_Preserve call was in
+				 * effect, so the structure must be freed when
+				 * refCount becomes zero. */
+    Tcl_FreeProc *freeProc;	/* Function to call to free. */
+} Reference;
+
+/*
+ * Global data structures used to hold the list of preserved data references.
+ * These variables are protected by "preserveMutex".
+ */
+
+static Reference *refArray = NULL;	/* First in array of references. */
+static int spaceAvl = 0;	/* Total number of structures available at
+				 * *firstRefPtr. */
+static int inUse = 0;		/* Count of structures currently in use in
+				 * refArray. */
+TCL_DECLARE_MUTEX(preserveMutex)/* To protect the above statics */
+
+#define INITIAL_SIZE	2	/* Initial number of reference slots to make */
+
+/*
+ * The following data structure is used to keep track of whether an arbitrary
+ * block of memory has been deleted. This is used by the TclHandle code to
+ * avoid the more time-expensive algorithm of Tcl_Preserve(). This mechanism
+ * is mainly used when we have lots of references to a few big, expensive
+ * objects that we don't want to live any longer than necessary.
+ */
+
+typedef struct HandleStruct {
+    void *ptr;			/* Pointer to the memory block being tracked.
+				 * This field will become NULL when the memory
+				 * block is deleted. This field must be the
+				 * first in the structure. */
+#ifdef TCL_MEM_DEBUG
+    void *ptr2;			/* Backup copy of the above pointer used to
+				 * ensure that the contents of the handle are
+				 * not changed by anyone else. */
+#endif
+    int refCount;		/* Number of TclHandlePreserve() calls in
+				 * effect on this handle. */
+} HandleStruct;
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclFinalizePreserve --
+ *
+ *	Called during exit processing to clean up the reference array.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Frees the storage of the reference array.
+ *
+ *----------------------------------------------------------------------
+ */
+
+	/* ARGSUSED */
+void
+TclFinalizePreserve(void)
+{
+    Tcl_MutexLock(&preserveMutex);
+    if (spaceAvl != 0) {
+	ckfree(refArray);
+	refArray = NULL;
+	inUse = 0;
+	spaceAvl = 0;
+    }
+    Tcl_MutexUnlock(&preserveMutex);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_Preserve --
+ *
+ *	This function is used by a function to declare its interest in a
+ *	particular block of memory, so that the block will not be reallocated
+ *	until a matching call to Tcl_Release has been made.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Information is retained so that the block of memory will not be freed
+ *	until at least the matching call to Tcl_Release.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_Preserve(
+    ClientData clientData)	/* Pointer to malloc'ed block of memory. */
+{
+    Reference *refPtr;
+    int i;
+
+    /*
+     * See if there is already a reference for this pointer. If so, just
+     * increment its reference count.
+     */
+
+    Tcl_MutexLock(&preserveMutex);
+    for (i=0, refPtr=refArray ; i<inUse ; i++, refPtr++) {
+	if (refPtr->clientData == clientData) {
+	    refPtr->refCount++;
+	    Tcl_MutexUnlock(&preserveMutex);
+	    return;
+	}
+    }
+
+    /*
+     * Make a reference array if it doesn't already exist, or make it bigger
+     * if it is full.
+     */
+
+    if (inUse == spaceAvl) {
+	spaceAvl = spaceAvl ? 2*spaceAvl : INITIAL_SIZE;
+	refArray = ckrealloc(refArray, spaceAvl * sizeof(Reference));
+    }
+
+    /*
+     * Make a new entry for the new reference.
+     */
+
+    refPtr = &refArray[inUse];
+    refPtr->clientData = clientData;
+    refPtr->refCount = 1;
+    refPtr->mustFree = 0;
+    refPtr->freeProc = TCL_STATIC;
+    inUse += 1;
+    Tcl_MutexUnlock(&preserveMutex);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_Release --
+ *
+ *	This function is called to cancel a previous call to Tcl_Preserve,
+ *	thereby allowing a block of memory to be freed (if no one else cares
+ *	about it).
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	If Tcl_EventuallyFree has been called for clientData, and if no other
+ *	call to Tcl_Preserve is still in effect, the block of memory is freed.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_Release(
+    ClientData clientData)	/* Pointer to malloc'ed block of memory. */
+{
+    Reference *refPtr;
+    int i;
+
+    Tcl_MutexLock(&preserveMutex);
+    for (i=0, refPtr=refArray ; i<inUse ; i++, refPtr++) {
+	int mustFree;
+	Tcl_FreeProc *freeProc;
+
+	if (refPtr->clientData != clientData) {
+	    continue;
+	}
+
+	if (--refPtr->refCount != 0) {
+	    Tcl_MutexUnlock(&preserveMutex);
+	    return;
+	}
+
+	/*
+	 * Must remove information from the slot before calling freeProc to
+	 * avoid reentrancy problems if the freeProc calls Tcl_Preserve on the
+	 * same clientData. Copy down the last reference in the array to
+	 * overwrite the current slot.
+	 */
+
+	freeProc = refPtr->freeProc;
+	mustFree = refPtr->mustFree;
+	inUse--;
+	if (i < inUse) {
+	    refArray[i] = refArray[inUse];
+	}
+
+	/*
+	 * Now committed to disposing the data. But first, we've patched up
+	 * all the global data structures so we should release the mutex now.
+	 * Only then should we dabble around with potentially-slow memory
+	 * managers...
+	 */
+
+	Tcl_MutexUnlock(&preserveMutex);
+	if (mustFree) {
+	    if (freeProc == TCL_DYNAMIC) {
+		ckfree(clientData);
+	    } else {
+		freeProc(clientData);
+	    }
+	}
+	return;
+    }
+    Tcl_MutexUnlock(&preserveMutex);
+
+    /*
+     * Reference not found. This is a bug in the caller.
+     */
+
+    Tcl_Panic("Tcl_Release couldn't find reference for %p", clientData);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_EventuallyFree --
+ *
+ *	Free up a block of memory, unless a call to Tcl_Preserve is in effect
+ *	for that block. In this case, defer the free until all calls to
+ *	Tcl_Preserve have been undone by matching calls to Tcl_Release.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Ptr may be released by calling free().
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_EventuallyFree(
+    ClientData clientData,	/* Pointer to malloc'ed block of memory. */
+    Tcl_FreeProc *freeProc)	/* Function to actually do free. */
+{
+    Reference *refPtr;
+    int i;
+
+    /*
+     * See if there is a reference for this pointer. If so, set its "mustFree"
+     * flag (the flag had better not be set already!).
+     */
+
+    Tcl_MutexLock(&preserveMutex);
+    for (i = 0, refPtr = refArray; i < inUse; i++, refPtr++) {
+	if (refPtr->clientData != clientData) {
+	    continue;
+	}
+	if (refPtr->mustFree) {
+	    Tcl_Panic("Tcl_EventuallyFree called twice for %p", clientData);
+	}
+	refPtr->mustFree = 1;
+	refPtr->freeProc = freeProc;
+	Tcl_MutexUnlock(&preserveMutex);
+	return;
+    }
+    Tcl_MutexUnlock(&preserveMutex);
+
+    /*
+     * No reference for this block.  Free it now.
+     */
+
+    if (freeProc == TCL_DYNAMIC) {
+	ckfree(clientData);
+    } else {
+	freeProc(clientData);
+    }
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * TclHandleCreate --
+ *
+ *	Allocate a handle that contains enough information to determine if an
+ *	arbitrary malloc'd block has been deleted. This is used to avoid the
+ *	more time-expensive algorithm of Tcl_Preserve().
+ *
+ * Results:
+ *	The return value is a TclHandle that refers to the given malloc'd
+ *	block. Doubly dereferencing the returned handle will give back the
+ *	pointer to the block, or will give NULL if the block has been deleted.
+ *
+ * Side effects:
+ *	The caller must keep track of this handle (generally by storing it in
+ *	a field in the malloc'd block) and call TclHandleFree() on this handle
+ *	when the block is deleted. Everything else that wishes to keep track
+ *	of whether the malloc'd block has been deleted should use calls to
+ *	TclHandlePreserve() and TclHandleRelease() on the associated handle.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+TclHandle
+TclHandleCreate(
+    void *ptr)			/* Pointer to an arbitrary block of memory to
+				 * be tracked for deletion. Must not be
+				 * NULL. */
+{
+    HandleStruct *handlePtr = ckalloc(sizeof(HandleStruct));
+
+    handlePtr->ptr = ptr;
+#ifdef TCL_MEM_DEBUG
+    handlePtr->ptr2 = ptr;
+#endif
+    handlePtr->refCount = 0;
+    return (TclHandle) handlePtr;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * TclHandleFree --
+ *
+ *	Called when the arbitrary malloc'd block associated with the handle is
+ *	being deleted. Modifies the handle so that doubly dereferencing it
+ *	will give NULL. This informs any user of the handle that the block of
+ *	memory formerly referenced by the handle has been freed.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	If nothing is referring to the handle, the handle will be reclaimed.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+void
+TclHandleFree(
+    TclHandle handle)		/* Previously created handle associated with a
+				 * malloc'd block that is being deleted. The
+				 * handle is modified so that doubly
+				 * dereferencing it will give NULL. */
+{
+    HandleStruct *handlePtr;
+
+    handlePtr = (HandleStruct *) handle;
+#ifdef TCL_MEM_DEBUG
+    if (handlePtr->refCount == 0x61616161) {
+	Tcl_Panic("using previously disposed TclHandle %p", handlePtr);
+    }
+    if (handlePtr->ptr2 != handlePtr->ptr) {
+	Tcl_Panic("someone has changed the block referenced by the handle %p\nfrom %p to %p",
+		handlePtr, handlePtr->ptr2, handlePtr->ptr);
+    }
+#endif
+    handlePtr->ptr = NULL;
+    if (handlePtr->refCount == 0) {
+	ckfree(handlePtr);
+    }
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * TclHandlePreserve --
+ *
+ *	Declare an interest in the arbitrary malloc'd block associated with
+ *	the handle.
+ *
+ * Results:
+ *	The return value is the handle argument, with its ref count
+ *	incremented.
+ *
+ * Side effects:
+ *	For each call to TclHandlePreserve(), there should be a matching call
+ *	to TclHandleRelease() when the caller is no longer interested in the
+ *	malloc'd block associated with the handle.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+TclHandle
+TclHandlePreserve(
+    TclHandle handle)		/* Declare an interest in the block of memory
+				 * referenced by this handle. */
+{
+    HandleStruct *handlePtr;
+
+    handlePtr = (HandleStruct *) handle;
+#ifdef TCL_MEM_DEBUG
+    if (handlePtr->refCount == 0x61616161) {
+	Tcl_Panic("using previously disposed TclHandle %p", handlePtr);
+    }
+    if ((handlePtr->ptr != NULL) && (handlePtr->ptr != handlePtr->ptr2)) {
+	Tcl_Panic("someone has changed the block referenced by the handle %p\nfrom %p to %p",
+		handlePtr, handlePtr->ptr2, handlePtr->ptr);
+    }
+#endif
+    handlePtr->refCount++;
+
+    return handle;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * TclHandleRelease --
+ *
+ *	This function is called to release an interest in the malloc'd block
+ *	associated with the handle.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The ref count of the handle is decremented. If the malloc'd block has
+ *	been freed and if no one is using the handle any more, the handle will
+ *	be reclaimed.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+void
+TclHandleRelease(
+    TclHandle handle)		/* Unregister interest in the block of memory
+				 * referenced by this handle. */
+{
+    HandleStruct *handlePtr;
+
+    handlePtr = (HandleStruct *) handle;
+#ifdef TCL_MEM_DEBUG
+    if (handlePtr->refCount == 0x61616161) {
+	Tcl_Panic("using previously disposed TclHandle %p", handlePtr);
+    }
+    if ((handlePtr->ptr != NULL) && (handlePtr->ptr != handlePtr->ptr2)) {
+	Tcl_Panic("someone has changed the block referenced by the handle %p\nfrom %p to %p",
+		handlePtr, handlePtr->ptr2, handlePtr->ptr);
+    }
+#endif
+    if ((--handlePtr->refCount == 0) && (handlePtr->ptr == NULL)) {
+	ckfree(handlePtr);
+    }
+}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tclProc.c b/generic/tclProc.c
new file mode 100644
index 0000000..ae9e7cd
--- /dev/null
+++ b/generic/tclProc.c
@@ -0,0 +1,2782 @@
+/*
+ * tclProc.c --
+ *
+ *	This file contains routines that implement Tcl procedures, including
+ *	the "proc" and "uplevel" commands.
+ *
+ * Copyright (c) 1987-1993 The Regents of the University of California.
+ * Copyright (c) 1994-1998 Sun Microsystems, Inc.
+ * Copyright (c) 2004-2006 Miguel Sofer
+ * Copyright (c) 2007 Daniel A. Steffen <das@users.sourceforge.net>
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#include "tclInt.h"
+#include "tclCompile.h"
+
+/*
+ * Variables that are part of the [apply] command implementation and which
+ * have to be passed to the other side of the NRE call.
+ */
+
+typedef struct {
+    Command cmd;
+    ExtraFrameInfo efi;
+} ApplyExtraData;
+
+/*
+ * Prototypes for static functions in this file
+ */
+
+static void		DupLambdaInternalRep(Tcl_Obj *objPtr,
+			    Tcl_Obj *copyPtr);
+static void		FreeLambdaInternalRep(Tcl_Obj *objPtr);
+static int		InitArgsAndLocals(Tcl_Interp *interp,
+			    Tcl_Obj *procNameObj, int skip);
+static void		InitResolvedLocals(Tcl_Interp *interp,
+			    ByteCode *codePtr, Var *defPtr,
+			    Namespace *nsPtr);
+static void		InitLocalCache(Proc *procPtr);
+static void		ProcBodyDup(Tcl_Obj *srcPtr, Tcl_Obj *dupPtr);
+static void		ProcBodyFree(Tcl_Obj *objPtr);
+static int		ProcWrongNumArgs(Tcl_Interp *interp, int skip);
+static void		MakeProcError(Tcl_Interp *interp,
+			    Tcl_Obj *procNameObj);
+static void		MakeLambdaError(Tcl_Interp *interp,
+			    Tcl_Obj *procNameObj);
+static int		SetLambdaFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr);
+
+static Tcl_NRPostProc ApplyNR2;
+static Tcl_NRPostProc InterpProcNR2;
+static Tcl_NRPostProc Uplevel_Callback;
+
+/*
+ * The ProcBodyObjType type
+ */
+
+const Tcl_ObjType tclProcBodyType = {
+    "procbody",			/* name for this type */
+    ProcBodyFree,		/* FreeInternalRep function */
+    ProcBodyDup,		/* DupInternalRep function */
+    NULL,			/* UpdateString function; Tcl_GetString and
+				 * Tcl_GetStringFromObj should panic
+				 * instead. */
+    NULL			/* SetFromAny function; Tcl_ConvertToType
+				 * should panic instead. */
+};
+
+/*
+ * The [upvar]/[uplevel] level reference type. Uses the longValue field
+ * to remember the integer value of a parsed #<integer> format.
+ *
+ * Uses the default behaviour throughout, and never disposes of the string
+ * rep; it's just a cache type.
+ */
+
+static const Tcl_ObjType levelReferenceType = {
+    "levelReference",
+    NULL, NULL, NULL, NULL
+};
+
+/*
+ * The type of lambdas. Note that every lambda will *always* have a string
+ * representation.
+ *
+ * Internally, ptr1 is a pointer to a Proc instance that is not bound to a
+ * command name, and ptr2 is a pointer to the namespace that the Proc instance
+ * will execute within. IF YOU CHANGE THIS, CHECK IN tclDisassemble.c TOO.
+ */
+
+const Tcl_ObjType tclLambdaType = {
+    "lambdaExpr",		/* name */
+    FreeLambdaInternalRep,	/* freeIntRepProc */
+    DupLambdaInternalRep,	/* dupIntRepProc */
+    NULL,			/* updateStringProc */
+    SetLambdaFromAny		/* setFromAnyProc */
+};
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_ProcObjCmd --
+ *
+ *	This object-based function is invoked to process the "proc" Tcl
+ *	command. See the user documentation for details on what it does.
+ *
+ * Results:
+ *	A standard Tcl object result value.
+ *
+ * Side effects:
+ *	A new procedure gets created.
+ *
+ *----------------------------------------------------------------------
+ */
+
+	/* ARGSUSED */
+int
+Tcl_ProcObjCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    register Interp *iPtr = (Interp *) interp;
+    Proc *procPtr;
+    const char *fullName;
+    const char *procName, *procArgs, *procBody;
+    Namespace *nsPtr, *altNsPtr, *cxtNsPtr;
+    Tcl_Command cmd;
+    Tcl_DString ds;
+
+    if (objc != 4) {
+	Tcl_WrongNumArgs(interp, 1, objv, "name args body");
+	return TCL_ERROR;
+    }
+
+    /*
+     * Determine the namespace where the procedure should reside. Unless the
+     * command name includes namespace qualifiers, this will be the current
+     * namespace.
+     */
+
+    fullName = TclGetString(objv[1]);
+    TclGetNamespaceForQualName(interp, fullName, NULL, 0,
+	    &nsPtr, &altNsPtr, &cxtNsPtr, &procName);
+
+    if (nsPtr == NULL) {
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		"can't create procedure \"%s\": unknown namespace",
+		fullName));
+	Tcl_SetErrorCode(interp, "TCL", "VALUE", "COMMAND", NULL);
+	return TCL_ERROR;
+    }
+    if (procName == NULL) {
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		"can't create procedure \"%s\": bad procedure name",
+		fullName));
+	Tcl_SetErrorCode(interp, "TCL", "VALUE", "COMMAND", NULL);
+	return TCL_ERROR;
+    }
+    if ((nsPtr != iPtr->globalNsPtr)
+	    && (procName != NULL) && (procName[0] == ':')) {
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		"can't create procedure \"%s\" in non-global namespace with"
+		" name starting with \":\"", procName));
+	Tcl_SetErrorCode(interp, "TCL", "VALUE", "COMMAND", NULL);
+	return TCL_ERROR;
+    }
+
+    /*
+     * Create the data structure to represent the procedure.
+     */
+
+    if (TclCreateProc(interp, nsPtr, procName, objv[2], objv[3],
+	    &procPtr) != TCL_OK) {
+	Tcl_AddErrorInfo(interp, "\n    (creating proc \"");
+	Tcl_AddErrorInfo(interp, procName);
+	Tcl_AddErrorInfo(interp, "\")");
+	return TCL_ERROR;
+    }
+
+    /*
+     * Now create a command for the procedure. This will initially be in the
+     * current namespace unless the procedure's name included namespace
+     * qualifiers. To create the new command in the right namespace, we
+     * generate a fully qualified name for it.
+     */
+
+    Tcl_DStringInit(&ds);
+    if (nsPtr != iPtr->globalNsPtr) {
+	Tcl_DStringAppend(&ds, nsPtr->fullName, -1);
+	TclDStringAppendLiteral(&ds, "::");
+    }
+    Tcl_DStringAppend(&ds, procName, -1);
+
+    cmd = Tcl_NRCreateCommand(interp, Tcl_DStringValue(&ds), TclObjInterpProc,
+	    TclNRInterpProc, procPtr, TclProcDeleteProc);
+    Tcl_DStringFree(&ds);
+
+    /*
+     * Now initialize the new procedure's cmdPtr field. This will be used
+     * later when the procedure is called to determine what namespace the
+     * procedure will run in. This will be different than the current
+     * namespace if the proc was renamed into a different namespace.
+     */
+
+    procPtr->cmdPtr = (Command *) cmd;
+
+    /*
+     * TIP #280: Remember the line the procedure body is starting on. In a
+     * bytecode context we ask the engine to provide us with the necessary
+     * information. This is for the initialization of the byte code compiler
+     * when the body is used for the first time.
+     *
+     * This code is nearly identical to the #280 code in SetLambdaFromAny, see
+     * this file. The differences are the different index of the body in the
+     * line array of the context, and the lambda code requires some special
+     * processing. Find a way to factor the common elements into a single
+     * function.
+     */
+
+    if (iPtr->cmdFramePtr) {
+	CmdFrame *contextPtr = TclStackAlloc(interp, sizeof(CmdFrame));
+
+	*contextPtr = *iPtr->cmdFramePtr;
+	if (contextPtr->type == TCL_LOCATION_BC) {
+	    /*
+	     * Retrieve source information from the bytecode, if possible. If
+	     * the information is retrieved successfully, context.type will be
+	     * TCL_LOCATION_SOURCE and the reference held by
+	     * context.data.eval.path will be counted.
+	     */
+
+	    TclGetSrcInfoForPc(contextPtr);
+	} else if (contextPtr->type == TCL_LOCATION_SOURCE) {
+	    /*
+	     * The copy into 'context' up above has created another reference
+	     * to 'context.data.eval.path'; account for it.
+	     */
+
+	    Tcl_IncrRefCount(contextPtr->data.eval.path);
+	}
+
+	if (contextPtr->type == TCL_LOCATION_SOURCE) {
+	    /*
+	     * We can account for source location within a proc only if the
+	     * proc body was not created by substitution.
+	     */
+
+	    if (contextPtr->line
+		    && (contextPtr->nline >= 4) && (contextPtr->line[3] >= 0)) {
+		int isNew;
+		Tcl_HashEntry *hePtr;
+		CmdFrame *cfPtr = ckalloc(sizeof(CmdFrame));
+
+		cfPtr->level = -1;
+		cfPtr->type = contextPtr->type;
+		cfPtr->line = ckalloc(sizeof(int));
+		cfPtr->line[0] = contextPtr->line[3];
+		cfPtr->nline = 1;
+		cfPtr->framePtr = NULL;
+		cfPtr->nextPtr = NULL;
+
+		cfPtr->data.eval.path = contextPtr->data.eval.path;
+		Tcl_IncrRefCount(cfPtr->data.eval.path);
+
+		cfPtr->cmd = NULL;
+		cfPtr->len = 0;
+
+		hePtr = Tcl_CreateHashEntry(iPtr->linePBodyPtr,
+			procPtr, &isNew);
+		if (!isNew) {
+		    /*
+		     * Get the old command frame and release it. See also
+		     * TclProcCleanupProc in this file. Currently it seems as
+		     * if only the procbodytest::proc command of the testsuite
+		     * is able to trigger this situation.
+		     */
+
+		    CmdFrame *cfOldPtr = Tcl_GetHashValue(hePtr);
+
+		    if (cfOldPtr->type == TCL_LOCATION_SOURCE) {
+			Tcl_DecrRefCount(cfOldPtr->data.eval.path);
+			cfOldPtr->data.eval.path = NULL;
+		    }
+		    ckfree(cfOldPtr->line);
+		    cfOldPtr->line = NULL;
+		    ckfree(cfOldPtr);
+		}
+		Tcl_SetHashValue(hePtr, cfPtr);
+	    }
+
+	    /*
+	     * 'contextPtr' is going out of scope; account for the reference
+	     * that it's holding to the path name.
+	     */
+
+	    Tcl_DecrRefCount(contextPtr->data.eval.path);
+	    contextPtr->data.eval.path = NULL;
+	}
+	TclStackFree(interp, contextPtr);
+    }
+
+    /*
+     * Optimize for no-op procs: if the body is not precompiled (like a TclPro
+     * procbody), and the argument list is just "args" and the body is empty,
+     * define a compileProc to compile a no-op.
+     *
+     * Notes:
+     *	 - cannot be done for any argument list without having different
+     *	   compiled/not-compiled behaviour in the "wrong argument #" case, or
+     *	   making this code much more complicated. In any case, it doesn't
+     *	   seem to make a lot of sense to verify the number of arguments we
+     *	   are about to ignore ...
+     *	 - could be enhanced to handle also non-empty bodies that contain only
+     *	   comments; however, parsing the body will slow down the compilation
+     *	   of all procs whose argument list is just _args_
+     */
+
+    if (objv[3]->typePtr == &tclProcBodyType) {
+	goto done;
+    }
+
+    procArgs = TclGetString(objv[2]);
+
+    while (*procArgs == ' ') {
+	procArgs++;
+    }
+
+    if ((procArgs[0] == 'a') && (strncmp(procArgs, "args", 4) == 0)) {
+	int numBytes;
+
+	procArgs +=4;
+	while (*procArgs != '\0') {
+	    if (*procArgs != ' ') {
+		goto done;
+	    }
+	    procArgs++;
+	}
+
+	/*
+	 * The argument list is just "args"; check the body
+	 */
+
+	procBody = Tcl_GetStringFromObj(objv[3], &numBytes);
+	if (TclParseAllWhiteSpace(procBody, numBytes) < numBytes) {
+	    goto done;
+	}
+
+	/*
+	 * The body is just spaces: link the compileProc
+	 */
+
+	((Command *) cmd)->compileProc = TclCompileNoOp;
+    }
+
+  done:
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclCreateProc --
+ *
+ *	Creates the data associated with a Tcl procedure definition. This
+ *	function knows how to handle two types of body objects: strings and
+ *	procbody. Strings are the traditional (and common) value for bodies,
+ *	procbody are values created by extensions that have loaded a
+ *	previously compiled script.
+ *
+ * Results:
+ *	Returns TCL_OK on success, along with a pointer to a Tcl procedure
+ *	definition in procPtrPtr where the cmdPtr field is not initialised.
+ *	This definition should be freed by calling TclProcCleanupProc() when
+ *	it is no longer needed. Returns TCL_ERROR if anything goes wrong.
+ *
+ * Side effects:
+ *	If anything goes wrong, this function returns an error message in the
+ *	interpreter.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclCreateProc(
+    Tcl_Interp *interp,		/* Interpreter containing proc. */
+    Namespace *nsPtr,		/* Namespace containing this proc. */
+    const char *procName,	/* Unqualified name of this proc. */
+    Tcl_Obj *argsPtr,		/* Description of arguments. */
+    Tcl_Obj *bodyPtr,		/* Command body. */
+    Proc **procPtrPtr)		/* Returns: pointer to proc data. */
+{
+    Interp *iPtr = (Interp *) interp;
+    const char **argArray = NULL;
+
+    register Proc *procPtr;
+    int i, length, result, numArgs;
+    const char *args, *bytes, *p;
+    register CompiledLocal *localPtr = NULL;
+    Tcl_Obj *defPtr;
+    int precompiled = 0;
+
+    if (bodyPtr->typePtr == &tclProcBodyType) {
+	/*
+	 * Because the body is a TclProProcBody, the actual body is already
+	 * compiled, and it is not shared with anyone else, so it's OK not to
+	 * unshare it (as a matter of fact, it is bad to unshare it, because
+	 * there may be no source code).
+	 *
+	 * We don't create and initialize a Proc structure for the procedure;
+	 * rather, we use what is in the body object. We increment the ref
+	 * count of the Proc struct since the command (soon to be created)
+	 * will be holding a reference to it.
+	 */
+
+	procPtr = bodyPtr->internalRep.twoPtrValue.ptr1;
+	procPtr->iPtr = iPtr;
+	procPtr->refCount++;
+	precompiled = 1;
+    } else {
+	/*
+	 * If the procedure's body object is shared because its string value
+	 * is identical to, e.g., the body of another procedure, we must
+	 * create a private copy for this procedure to use. Such sharing of
+	 * procedure bodies is rare but can cause problems. A procedure body
+	 * is compiled in a context that includes the number of "slots"
+	 * allocated by the compiler for local variables. There is a local
+	 * variable slot for each formal parameter (the
+	 * "procPtr->numCompiledLocals = numArgs" assignment below). This
+	 * means that the same code can not be shared by two procedures that
+	 * have a different number of arguments, even if their bodies are
+	 * identical. Note that we don't use Tcl_DuplicateObj since we would
+	 * not want any bytecode internal representation.
+	 */
+
+	if (Tcl_IsShared(bodyPtr)) {
+	    Tcl_Obj *sharedBodyPtr = bodyPtr;
+
+	    bytes = TclGetStringFromObj(bodyPtr, &length);
+	    bodyPtr = Tcl_NewStringObj(bytes, length);
+
+	    /*
+	     * TIP #280.
+	     * Ensure that the continuation line data for the original body is
+	     * not lost and applies to the new body as well.
+	     */
+
+	    TclContinuationsCopy(bodyPtr, sharedBodyPtr);
+	}
+
+	/*
+	 * Create and initialize a Proc structure for the procedure. We
+	 * increment the ref count of the procedure's body object since there
+	 * will be a reference to it in the Proc structure.
+	 */
+
+	Tcl_IncrRefCount(bodyPtr);
+
+	procPtr = ckalloc(sizeof(Proc));
+	procPtr->iPtr = iPtr;
+	procPtr->refCount = 1;
+	procPtr->bodyPtr = bodyPtr;
+	procPtr->numArgs = 0;	/* Actual argument count is set below. */
+	procPtr->numCompiledLocals = 0;
+	procPtr->firstLocalPtr = NULL;
+	procPtr->lastLocalPtr = NULL;
+    }
+
+    /*
+     * Break up the argument list into argument specifiers, then process each
+     * argument specifier. If the body is precompiled, processing is limited
+     * to checking that the parsed argument is consistent with the one stored
+     * in the Proc.
+     *
+     * THIS FAILS IF THE ARG LIST OBJECT'S STRING REP CONTAINS NULS.
+     */
+
+    args = TclGetStringFromObj(argsPtr, &length);
+    result = Tcl_SplitList(interp, args, &numArgs, &argArray);
+    if (result != TCL_OK) {
+	goto procError;
+    }
+
+    if (precompiled) {
+	if (numArgs > procPtr->numArgs) {
+	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		    "procedure \"%s\": arg list contains %d entries, "
+		    "precompiled header expects %d", procName, numArgs,
+		    procPtr->numArgs));
+	    Tcl_SetErrorCode(interp, "TCL", "OPERATION", "PROC",
+		    "BYTECODELIES", NULL);
+	    goto procError;
+	}
+	localPtr = procPtr->firstLocalPtr;
+    } else {
+	procPtr->numArgs = numArgs;
+	procPtr->numCompiledLocals = numArgs;
+    }
+
+    for (i = 0; i < numArgs; i++) {
+	int fieldCount, nameLength, valueLength;
+	const char **fieldValues;
+
+	/*
+	 * Now divide the specifier up into name and default.
+	 */
+
+	result = Tcl_SplitList(interp, argArray[i], &fieldCount,
+		&fieldValues);
+	if (result != TCL_OK) {
+	    goto procError;
+	}
+	if (fieldCount > 2) {
+	    ckfree(fieldValues);
+	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		    "too many fields in argument specifier \"%s\"",
+		    argArray[i]));
+	    Tcl_SetErrorCode(interp, "TCL", "OPERATION", "PROC",
+		    "FORMALARGUMENTFORMAT", NULL);
+	    goto procError;
+	}
+	if ((fieldCount == 0) || (*fieldValues[0] == 0)) {
+	    ckfree(fieldValues);
+	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		    "argument with no name", -1));
+	    Tcl_SetErrorCode(interp, "TCL", "OPERATION", "PROC",
+		    "FORMALARGUMENTFORMAT", NULL);
+	    goto procError;
+	}
+
+	nameLength = strlen(fieldValues[0]);
+	if (fieldCount == 2) {
+	    valueLength = strlen(fieldValues[1]);
+	} else {
+	    valueLength = 0;
+	}
+
+	/*
+	 * Check that the formal parameter name is a scalar.
+	 */
+
+	p = fieldValues[0];
+	while (*p != '\0') {
+	    if (*p == '(') {
+		const char *q = p;
+		do {
+		    q++;
+		} while (*q != '\0');
+		q--;
+		if (*q == ')') {	/* We have an array element. */
+		    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+			    "formal parameter \"%s\" is an array element",
+			    fieldValues[0]));
+		    ckfree(fieldValues);
+		    Tcl_SetErrorCode(interp, "TCL", "OPERATION", "PROC",
+			    "FORMALARGUMENTFORMAT", NULL);
+		    goto procError;
+		}
+	    } else if ((*p == ':') && (*(p+1) == ':')) {
+		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+			"formal parameter \"%s\" is not a simple name",
+			fieldValues[0]));
+		ckfree(fieldValues);
+		Tcl_SetErrorCode(interp, "TCL", "OPERATION", "PROC",
+			"FORMALARGUMENTFORMAT", NULL);
+		goto procError;
+	    }
+	    p++;
+	}
+
+	if (precompiled) {
+	    /*
+	     * Compare the parsed argument with the stored one. Note that the
+	     * only flag value that makes sense at this point is VAR_ARGUMENT
+	     * (its value was kept the same as pre VarReform to simplify
+	     * tbcload's processing of older byetcodes).
+	     *
+	     * The only other flag vlaue that is important to retrieve from
+	     * precompiled procs is VAR_TEMPORARY (also unchanged). It is
+	     * needed later when retrieving the variable names.
+	     */
+
+	    if ((localPtr->nameLength != nameLength)
+		    || (strcmp(localPtr->name, fieldValues[0]))
+		    || (localPtr->frameIndex != i)
+		    || !(localPtr->flags & VAR_ARGUMENT)
+		    || (localPtr->defValuePtr == NULL && fieldCount == 2)
+		    || (localPtr->defValuePtr != NULL && fieldCount != 2)) {
+		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+			"procedure \"%s\": formal parameter %d is "
+			"inconsistent with precompiled body", procName, i));
+		ckfree(fieldValues);
+		Tcl_SetErrorCode(interp, "TCL", "OPERATION", "PROC",
+			"BYTECODELIES", NULL);
+		goto procError;
+	    }
+
+	    /*
+	     * Compare the default value if any.
+	     */
+
+	    if (localPtr->defValuePtr != NULL) {
+		int tmpLength;
+		const char *tmpPtr = TclGetStringFromObj(localPtr->defValuePtr,
+			&tmpLength);
+
+		if ((valueLength != tmpLength) ||
+			strncmp(fieldValues[1], tmpPtr, (size_t) tmpLength)) {
+		    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+			    "procedure \"%s\": formal parameter \"%s\" has "
+			    "default value inconsistent with precompiled body",
+			    procName, fieldValues[0]));
+		    ckfree(fieldValues);
+		    Tcl_SetErrorCode(interp, "TCL", "OPERATION", "PROC",
+			    "BYTECODELIES", NULL);
+		    goto procError;
+		}
+	    }
+	    if ((i == numArgs - 1)
+		    && (localPtr->nameLength == 4)
+		    && (localPtr->name[0] == 'a')
+		    && (strcmp(localPtr->name, "args") == 0)) {
+		localPtr->flags |= VAR_IS_ARGS;
+	    }
+
+	    localPtr = localPtr->nextPtr;
+	} else {
+	    /*
+	     * Allocate an entry in the runtime procedure frame's array of
+	     * local variables for the argument.
+	     */
+
+	    localPtr = ckalloc(TclOffset(CompiledLocal, name) + nameLength+1);
+	    if (procPtr->firstLocalPtr == NULL) {
+		procPtr->firstLocalPtr = procPtr->lastLocalPtr = localPtr;
+	    } else {
+		procPtr->lastLocalPtr->nextPtr = localPtr;
+		procPtr->lastLocalPtr = localPtr;
+	    }
+	    localPtr->nextPtr = NULL;
+	    localPtr->nameLength = nameLength;
+	    localPtr->frameIndex = i;
+	    localPtr->flags = VAR_ARGUMENT;
+	    localPtr->resolveInfo = NULL;
+
+	    if (fieldCount == 2) {
+		localPtr->defValuePtr =
+			Tcl_NewStringObj(fieldValues[1], valueLength);
+		Tcl_IncrRefCount(localPtr->defValuePtr);
+	    } else {
+		localPtr->defValuePtr = NULL;
+	    }
+	    memcpy(localPtr->name, fieldValues[0], nameLength + 1);
+	    if ((i == numArgs - 1)
+		    && (localPtr->nameLength == 4)
+		    && (localPtr->name[0] == 'a')
+		    && (strcmp(localPtr->name, "args") == 0)) {
+		localPtr->flags |= VAR_IS_ARGS;
+	    }
+	}
+
+	ckfree(fieldValues);
+    }
+
+    *procPtrPtr = procPtr;
+    ckfree(argArray);
+    return TCL_OK;
+
+  procError:
+    if (precompiled) {
+	procPtr->refCount--;
+    } else {
+	Tcl_DecrRefCount(bodyPtr);
+	while (procPtr->firstLocalPtr != NULL) {
+	    localPtr = procPtr->firstLocalPtr;
+	    procPtr->firstLocalPtr = localPtr->nextPtr;
+
+	    defPtr = localPtr->defValuePtr;
+	    if (defPtr != NULL) {
+		Tcl_DecrRefCount(defPtr);
+	    }
+
+	    ckfree(localPtr);
+	}
+	ckfree(procPtr);
+    }
+    if (argArray != NULL) {
+	ckfree(argArray);
+    }
+    return TCL_ERROR;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclGetFrame --
+ *
+ *	Given a description of a procedure frame, such as the first argument
+ *	to an "uplevel" or "upvar" command, locate the call frame for the
+ *	appropriate level of procedure.
+ *
+ * Results:
+ *	The return value is -1 if an error occurred in finding the frame (in
+ *	this case an error message is left in the interp's result). 1 is
+ *	returned if string was either a number or a number preceded by "#" and
+ *	it specified a valid frame. 0 is returned if string isn't one of the
+ *	two things above (in this case, the lookup acts as if string were
+ *	"1"). The variable pointed to by framePtrPtr is filled in with the
+ *	address of the desired frame (unless an error occurs, in which case it
+ *	isn't modified).
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclGetFrame(
+    Tcl_Interp *interp,		/* Interpreter in which to find frame. */
+    const char *name,		/* String describing frame. */
+    CallFrame **framePtrPtr)	/* Store pointer to frame here (or NULL if
+				 * global frame indicated). */
+{
+    register Interp *iPtr = (Interp *) interp;
+    int curLevel, level, result;
+    CallFrame *framePtr;
+
+    /*
+     * Parse string to figure out which level number to go to.
+     */
+
+    result = 1;
+    curLevel = iPtr->varFramePtr->level;
+    if (*name== '#') {
+	if (Tcl_GetInt(interp, name+1, &level) != TCL_OK || level < 0) {
+	    goto levelError;
+	}
+    } else if (isdigit(UCHAR(*name))) { /* INTL: digit */
+	if (Tcl_GetInt(interp, name, &level) != TCL_OK) {
+	    goto levelError;
+	}
+	level = curLevel - level;
+    } else {
+	level = curLevel - 1;
+	result = 0;
+    }
+
+    /*
+     * Figure out which frame to use, and return it to the caller.
+     */
+
+    for (framePtr = iPtr->varFramePtr; framePtr != NULL;
+	    framePtr = framePtr->callerVarPtr) {
+	if (framePtr->level == level) {
+	    break;
+	}
+    }
+    if (framePtr == NULL) {
+	goto levelError;
+    }
+
+    *framePtrPtr = framePtr;
+    return result;
+
+  levelError:
+    Tcl_SetObjResult(interp, Tcl_ObjPrintf("bad level \"%s\"", name));
+    Tcl_SetErrorCode(interp, "TCL", "VALUE", "STACKLEVEL", NULL);
+    return -1;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclObjGetFrame --
+ *
+ *	Given a description of a procedure frame, such as the first argument
+ *	to an "uplevel" or "upvar" command, locate the call frame for the
+ *	appropriate level of procedure.
+ *
+ * Results:
+ *	The return value is -1 if an error occurred in finding the frame (in
+ *	this case an error message is left in the interp's result). 1 is
+ *	returned if objPtr was either an int or an int preceded by "#" and
+ *	it specified a valid frame. 0 is returned if objPtr isn't one of the
+ *	two things above (in this case, the lookup acts as if objPtr were
+ *	"1"). The variable pointed to by framePtrPtr is filled in with the
+ *	address of the desired frame (unless an error occurs, in which case it
+ *	isn't modified).
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclObjGetFrame(
+    Tcl_Interp *interp,		/* Interpreter in which to find frame. */
+    Tcl_Obj *objPtr,		/* Object describing frame. */
+    CallFrame **framePtrPtr)	/* Store pointer to frame here (or NULL if
+				 * global frame indicated). */
+{
+    register Interp *iPtr = (Interp *) interp;
+    int curLevel, level, result;
+    const char *name = NULL;
+
+    /*
+     * Parse object to figure out which level number to go to.
+     */
+
+    result = 0;
+    curLevel = iPtr->varFramePtr->level;
+
+    /*
+     * Check for integer first, since that has potential to spare us
+     * a generation of a stringrep.
+     */
+
+    if (objPtr == NULL) {
+	/* Do nothing */
+    } else if (TCL_OK == Tcl_GetIntFromObj(NULL, objPtr, &level)
+	    && (level >= 0)) {
+	level = curLevel - level;
+	result = 1;
+    } else if (objPtr->typePtr == &levelReferenceType) {
+	level = (int) objPtr->internalRep.longValue;
+	result = 1;
+    } else {
+	name = TclGetString(objPtr);
+	if (name[0] == '#') {
+	    if (TCL_OK == Tcl_GetInt(NULL, name+1, &level) && level >= 0) {
+		TclFreeIntRep(objPtr);
+		objPtr->typePtr = &levelReferenceType;
+		objPtr->internalRep.longValue = level;
+		result = 1;
+	    } else {
+		result = -1;
+	    }
+	} else if (isdigit(UCHAR(name[0]))) { /* INTL: digit */
+	    /*
+	     * If this were an integer, we'd have succeeded already.
+	     * Docs say we have to treat this as a 'bad level'  error.
+	     */
+	    result = -1;
+	}
+    }
+
+    if (result == 0) {
+	level = curLevel - 1;
+	name = "1";
+    }
+    if (result != -1) {
+	if (level >= 0) {
+	    CallFrame *framePtr;
+	    for (framePtr = iPtr->varFramePtr; framePtr != NULL;
+		    framePtr = framePtr->callerVarPtr) {
+		if (framePtr->level == level) {
+		    *framePtrPtr = framePtr;
+		    return result;
+		}
+	    }
+	}
+	if (name == NULL) {
+	    name = TclGetString(objPtr);
+	}
+    }
+
+    Tcl_SetObjResult(interp, Tcl_ObjPrintf("bad level \"%s\"", name));
+    Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "LEVEL", name, NULL);
+    return -1;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_UplevelObjCmd --
+ *
+ *	This object function is invoked to process the "uplevel" Tcl command.
+ *	See the user documentation for details on what it does.
+ *
+ * Results:
+ *	A standard Tcl object result value.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+Uplevel_Callback(
+    ClientData data[],
+    Tcl_Interp *interp,
+    int result)
+{
+    CallFrame *savedVarFramePtr = data[0];
+
+    if (result == TCL_ERROR) {
+	Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf(
+		"\n    (\"uplevel\" body line %d)", Tcl_GetErrorLine(interp)));
+    }
+
+    /*
+     * Restore the variable frame, and return.
+     */
+
+    ((Interp *)interp)->varFramePtr = savedVarFramePtr;
+    return result;
+}
+
+	/* ARGSUSED */
+int
+Tcl_UplevelObjCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    return Tcl_NRCallObjProc(interp, TclNRUplevelObjCmd, dummy, objc, objv);
+}
+
+int
+TclNRUplevelObjCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+
+    register Interp *iPtr = (Interp *) interp;
+    CmdFrame *invoker = NULL;
+    int word = 0;
+    int result;
+    CallFrame *savedVarFramePtr, *framePtr;
+    Tcl_Obj *objPtr;
+
+    if (objc < 2) {
+    uplevelSyntax:
+	Tcl_WrongNumArgs(interp, 1, objv, "?level? command ?arg ...?");
+	return TCL_ERROR;
+    }
+
+    /*
+     * Find the level to use for executing the command.
+     */
+
+    result = TclObjGetFrame(interp, objv[1], &framePtr);
+    if (result == -1) {
+	return TCL_ERROR;
+    }
+    objc -= result + 1;
+    if (objc == 0) {
+	goto uplevelSyntax;
+    }
+    objv += result + 1;
+
+    /*
+     * Modify the interpreter state to execute in the given frame.
+     */
+
+    savedVarFramePtr = iPtr->varFramePtr;
+    iPtr->varFramePtr = framePtr;
+
+    /*
+     * Execute the residual arguments as a command.
+     */
+
+    if (objc == 1) {
+	/*
+	 * TIP #280. Make actual argument location available to eval'd script
+	 */
+
+	TclArgumentGet(interp, objv[0], &invoker, &word);
+	objPtr = objv[0];
+
+    } else {
+	/*
+	 * More than one argument: concatenate them together with spaces
+	 * between, then evaluate the result. Tcl_EvalObjEx will delete the
+	 * object when it decrements its refcount after eval'ing it.
+	 */
+
+	objPtr = Tcl_ConcatObj(objc, objv);
+    }
+
+    TclNRAddCallback(interp, Uplevel_Callback, savedVarFramePtr, NULL, NULL,
+	    NULL);
+    return TclNREvalObjEx(interp, objPtr, 0, invoker, word);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclFindProc --
+ *
+ *	Given the name of a procedure, return a pointer to the record
+ *	describing the procedure. The procedure will be looked up using the
+ *	usual rules: first in the current namespace and then in the global
+ *	namespace.
+ *
+ * Results:
+ *	NULL is returned if the name doesn't correspond to any procedure.
+ *	Otherwise, the return value is a pointer to the procedure's record. If
+ *	the name is found but refers to an imported command that points to a
+ *	"real" procedure defined in another namespace, a pointer to that
+ *	"real" procedure's structure is returned.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Proc *
+TclFindProc(
+    Interp *iPtr,		/* Interpreter in which to look. */
+    const char *procName)	/* Name of desired procedure. */
+{
+    Tcl_Command cmd;
+    Command *cmdPtr;
+
+    cmd = Tcl_FindCommand((Tcl_Interp *) iPtr, procName, NULL, /*flags*/ 0);
+    if (cmd == (Tcl_Command) NULL) {
+	return NULL;
+    }
+    cmdPtr = (Command *) cmd;
+
+    return TclIsProc(cmdPtr);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclIsProc --
+ *
+ *	Tells whether a command is a Tcl procedure or not.
+ *
+ * Results:
+ *	If the given command is actually a Tcl procedure, the return value is
+ *	the address of the record describing the procedure. Otherwise the
+ *	return value is 0.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Proc *
+TclIsProc(
+    Command *cmdPtr)		/* Command to test. */
+{
+    Tcl_Command origCmd = TclGetOriginalCommand((Tcl_Command) cmdPtr);
+
+    if (origCmd != NULL) {
+	cmdPtr = (Command *) origCmd;
+    }
+    if (cmdPtr->deleteProc == TclProcDeleteProc) {
+	return cmdPtr->objClientData;
+    }
+    return NULL;
+}
+
+static int
+ProcWrongNumArgs(
+    Tcl_Interp *interp,
+    int skip)
+{
+    CallFrame *framePtr = ((Interp *)interp)->varFramePtr;
+    register Proc *procPtr = framePtr->procPtr;
+    register Var *defPtr;
+    int localCt = procPtr->numCompiledLocals, numArgs, i;
+    Tcl_Obj **desiredObjs;
+    const char *final = NULL;
+
+    /*
+     * Build up desired argument list for Tcl_WrongNumArgs
+     */
+
+    numArgs = framePtr->procPtr->numArgs;
+    desiredObjs = TclStackAlloc(interp,
+	    (int) sizeof(Tcl_Obj *) * (numArgs+1));
+
+    if (framePtr->isProcCallFrame & FRAME_IS_LAMBDA) {
+	desiredObjs[0] = Tcl_NewStringObj("lambdaExpr", -1);
+    } else {
+#ifdef AVOID_HACKS_FOR_ITCL
+	desiredObjs[0] = framePtr->objv[skip-1];
+#else
+	desiredObjs[0] = Tcl_NewListObj(1, framePtr->objv + skip - 1);
+#endif /* AVOID_HACKS_FOR_ITCL */
+    }
+    Tcl_IncrRefCount(desiredObjs[0]);
+
+    defPtr = (Var *) (&framePtr->localCachePtr->varName0 + localCt);
+    for (i=1 ; i<=numArgs ; i++, defPtr++) {
+	Tcl_Obj *argObj;
+	Tcl_Obj *namePtr = localName(framePtr, i-1);
+
+	if (defPtr->value.objPtr != NULL) {
+	    TclNewObj(argObj);
+	    Tcl_AppendStringsToObj(argObj, "?", TclGetString(namePtr), "?", NULL);
+	} else if (defPtr->flags & VAR_IS_ARGS) {
+	    numArgs--;
+	    final = "?arg ...?";
+	    break;
+	} else {
+	    argObj = namePtr;
+	    Tcl_IncrRefCount(namePtr);
+	}
+	desiredObjs[i] = argObj;
+    }
+
+    Tcl_ResetResult(interp);
+    Tcl_WrongNumArgs(interp, numArgs+1, desiredObjs, final);
+
+    for (i=0 ; i<=numArgs ; i++) {
+	Tcl_DecrRefCount(desiredObjs[i]);
+    }
+    TclStackFree(interp, desiredObjs);
+    return TCL_ERROR;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclInitCompiledLocals --
+ *
+ *	This routine is invoked in order to initialize the compiled locals
+ *	table for a new call frame.
+ *
+ *	DEPRECATED: functionality has been inlined elsewhere; this function
+ *	remains to insure binary compatibility with Itcl.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	May invoke various name resolvers in order to determine which
+ *	variables are being referenced at runtime.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclInitCompiledLocals(
+    Tcl_Interp *interp,		/* Current interpreter. */
+    CallFrame *framePtr,	/* Call frame to initialize. */
+    Namespace *nsPtr)		/* Pointer to current namespace. */
+{
+    Var *varPtr = framePtr->compiledLocals;
+    Tcl_Obj *bodyPtr;
+    ByteCode *codePtr;
+
+    bodyPtr = framePtr->procPtr->bodyPtr;
+    if (bodyPtr->typePtr != &tclByteCodeType) {
+	Tcl_Panic("body object for proc attached to frame is not a byte code type");
+    }
+    codePtr = bodyPtr->internalRep.twoPtrValue.ptr1;
+
+    if (framePtr->numCompiledLocals) {
+	if (!codePtr->localCachePtr) {
+	    InitLocalCache(framePtr->procPtr) ;
+	}
+	framePtr->localCachePtr = codePtr->localCachePtr;
+	framePtr->localCachePtr->refCount++;
+    }
+
+    InitResolvedLocals(interp, codePtr, varPtr, nsPtr);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * InitResolvedLocals --
+ *
+ *	This routine is invoked in order to initialize the compiled locals
+ *	table for a new call frame.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	May invoke various name resolvers in order to determine which
+ *	variables are being referenced at runtime.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+InitResolvedLocals(
+    Tcl_Interp *interp,		/* Current interpreter. */
+    ByteCode *codePtr,
+    Var *varPtr,
+    Namespace *nsPtr)		/* Pointer to current namespace. */
+{
+    Interp *iPtr = (Interp *) interp;
+    int haveResolvers = (nsPtr->compiledVarResProc || iPtr->resolverPtr);
+    CompiledLocal *firstLocalPtr, *localPtr;
+    int varNum;
+    Tcl_ResolvedVarInfo *resVarInfo;
+
+    /*
+     * Find the localPtr corresponding to varPtr
+     */
+
+    varNum = varPtr - iPtr->framePtr->compiledLocals;
+    localPtr = iPtr->framePtr->procPtr->firstLocalPtr;
+    while (varNum--) {
+	localPtr = localPtr->nextPtr;
+    }
+
+    if (!(haveResolvers && (codePtr->flags & TCL_BYTECODE_RESOLVE_VARS))) {
+	goto doInitResolvedLocals;
+    }
+
+    /*
+     * This is the first run after a recompile, or else the resolver epoch
+     * has changed: update the resolver cache.
+     */
+
+    firstLocalPtr = localPtr;
+    for (; localPtr != NULL; localPtr = localPtr->nextPtr) {
+	if (localPtr->resolveInfo) {
+	    if (localPtr->resolveInfo->deleteProc) {
+		localPtr->resolveInfo->deleteProc(localPtr->resolveInfo);
+	    } else {
+		ckfree(localPtr->resolveInfo);
+	    }
+	    localPtr->resolveInfo = NULL;
+	}
+	localPtr->flags &= ~VAR_RESOLVED;
+
+	if (haveResolvers &&
+		!(localPtr->flags & (VAR_ARGUMENT|VAR_TEMPORARY))) {
+	    ResolverScheme *resPtr = iPtr->resolverPtr;
+	    Tcl_ResolvedVarInfo *vinfo;
+	    int result;
+
+	    if (nsPtr->compiledVarResProc) {
+		result = nsPtr->compiledVarResProc(nsPtr->interp,
+			localPtr->name, localPtr->nameLength,
+			(Tcl_Namespace *) nsPtr, &vinfo);
+	    } else {
+		result = TCL_CONTINUE;
+	    }
+
+	    while ((result == TCL_CONTINUE) && resPtr) {
+		if (resPtr->compiledVarResProc) {
+		    result = resPtr->compiledVarResProc(nsPtr->interp,
+			    localPtr->name, localPtr->nameLength,
+			    (Tcl_Namespace *) nsPtr, &vinfo);
+		}
+		resPtr = resPtr->nextPtr;
+	    }
+	    if (result == TCL_OK) {
+		localPtr->resolveInfo = vinfo;
+		localPtr->flags |= VAR_RESOLVED;
+	    }
+	}
+    }
+    localPtr = firstLocalPtr;
+    codePtr->flags &= ~TCL_BYTECODE_RESOLVE_VARS;
+
+    /*
+     * Initialize the array of local variables stored in the call frame. Some
+     * variables may have special resolution rules. In that case, we call
+     * their "resolver" procs to get our hands on the variable, and we make
+     * the compiled local a link to the real variable.
+     */
+
+  doInitResolvedLocals:
+    for (; localPtr != NULL; varPtr++, localPtr = localPtr->nextPtr) {
+	varPtr->flags = 0;
+	varPtr->value.objPtr = NULL;
+
+	/*
+	 * Now invoke the resolvers to determine the exact variables that
+	 * should be used.
+	 */
+
+	resVarInfo = localPtr->resolveInfo;
+	if (resVarInfo && resVarInfo->fetchProc) {
+	    register Var *resolvedVarPtr = (Var *)
+		    resVarInfo->fetchProc(interp, resVarInfo);
+
+	    if (resolvedVarPtr) {
+		if (TclIsVarInHash(resolvedVarPtr)) {
+		    VarHashRefCount(resolvedVarPtr)++;
+		}
+		varPtr->flags = VAR_LINK;
+		varPtr->value.linkPtr = resolvedVarPtr;
+	    }
+	}
+    }
+}
+
+void
+TclFreeLocalCache(
+    Tcl_Interp *interp,
+    LocalCache *localCachePtr)
+{
+    int i;
+    Tcl_Obj **namePtrPtr = &localCachePtr->varName0;
+
+    for (i = 0; i < localCachePtr->numVars; i++, namePtrPtr++) {
+	register Tcl_Obj *objPtr = *namePtrPtr;
+
+	if (objPtr) {
+	    /* TclReleaseLiteral calls Tcl_DecrRefCount for us */
+	    TclReleaseLiteral(interp, objPtr);
+	}
+    }
+    ckfree(localCachePtr);
+}
+
+static void
+InitLocalCache(
+    Proc *procPtr)
+{
+    Interp *iPtr = procPtr->iPtr;
+    ByteCode *codePtr = procPtr->bodyPtr->internalRep.twoPtrValue.ptr1;
+    int localCt = procPtr->numCompiledLocals;
+    int numArgs = procPtr->numArgs, i = 0;
+
+    Tcl_Obj **namePtr;
+    Var *varPtr;
+    LocalCache *localCachePtr;
+    CompiledLocal *localPtr;
+    int new;
+
+    /*
+     * Cache the names and initial values of local variables; store the
+     * cache in both the framePtr for this execution and in the codePtr
+     * for future calls.
+     */
+
+    localCachePtr = ckalloc(sizeof(LocalCache)
+	    + (localCt - 1) * sizeof(Tcl_Obj *)
+	    + numArgs * sizeof(Var));
+
+    namePtr = &localCachePtr->varName0;
+    varPtr = (Var *) (namePtr + localCt);
+    localPtr = procPtr->firstLocalPtr;
+    while (localPtr) {
+	if (TclIsVarTemporary(localPtr)) {
+	    *namePtr = NULL;
+	} else {
+	    *namePtr = TclCreateLiteral(iPtr, localPtr->name,
+		    localPtr->nameLength, /* hash */ (unsigned int) -1,
+		    &new, /* nsPtr */ NULL, 0, NULL);
+	    Tcl_IncrRefCount(*namePtr);
+	}
+
+	if (i < numArgs) {
+	    varPtr->flags = (localPtr->flags & VAR_IS_ARGS);
+	    varPtr->value.objPtr = localPtr->defValuePtr;
+	    varPtr++;
+	    i++;
+	}
+	namePtr++;
+	localPtr = localPtr->nextPtr;
+    }
+    codePtr->localCachePtr = localCachePtr;
+    localCachePtr->refCount = 1;
+    localCachePtr->numVars = localCt;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * InitArgsAndLocals --
+ *
+ *	This routine is invoked in order to initialize the arguments and other
+ *	compiled locals table for a new call frame.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	Allocates memory on the stack for the compiled local variables, the
+ *	caller is responsible for freeing them. Initialises all variables. May
+ *	invoke various name resolvers in order to determine which variables
+ *	are being referenced at runtime.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+InitArgsAndLocals(
+    register Tcl_Interp *interp,/* Interpreter in which procedure was
+				 * invoked. */
+    Tcl_Obj *procNameObj,	/* Procedure name for error reporting. */
+    int skip)			/* Number of initial arguments to be skipped,
+				 * i.e., words in the "command name". */
+{
+    CallFrame *framePtr = ((Interp *)interp)->varFramePtr;
+    register Proc *procPtr = framePtr->procPtr;
+    ByteCode *codePtr = procPtr->bodyPtr->internalRep.twoPtrValue.ptr1;
+    register Var *varPtr, *defPtr;
+    int localCt = procPtr->numCompiledLocals, numArgs, argCt, i, imax;
+    Tcl_Obj *const *argObjs;
+
+    /*
+     * Make sure that the local cache of variable names and initial values has
+     * been initialised properly .
+     */
+
+    if (localCt) {
+	if (!codePtr->localCachePtr) {
+	    InitLocalCache(procPtr) ;
+	}
+	framePtr->localCachePtr = codePtr->localCachePtr;
+	framePtr->localCachePtr->refCount++;
+	defPtr = (Var *) (&framePtr->localCachePtr->varName0 + localCt);
+    } else {
+	defPtr = NULL;
+    }
+
+    /*
+     * Create the "compiledLocals" array. Make sure it is large enough to hold
+     * all the procedure's compiled local variables, including its formal
+     * parameters.
+     */
+
+    varPtr = TclStackAlloc(interp, (int)(localCt * sizeof(Var)));
+    framePtr->compiledLocals = varPtr;
+    framePtr->numCompiledLocals = localCt;
+
+    /*
+     * Match and assign the call's actual parameters to the procedure's formal
+     * arguments. The formal arguments are described by the first numArgs
+     * entries in both the Proc structure's local variable list and the call
+     * frame's local variable array.
+     */
+
+    numArgs = procPtr->numArgs;
+    argCt = framePtr->objc - skip;	/* Set it to the number of args to the
+					 * procedure. */
+    argObjs = framePtr->objv + skip;
+    if (numArgs == 0) {
+	if (argCt) {
+	    goto incorrectArgs;
+	} else {
+	    goto correctArgs;
+	}
+    }
+    imax = ((argCt < numArgs-1) ? argCt : numArgs-1);
+    for (i = 0; i < imax; i++, varPtr++, defPtr ? defPtr++ : defPtr) {
+	/*
+	 * "Normal" arguments; last formal is special, depends on it being
+	 * 'args'.
+	 */
+
+	Tcl_Obj *objPtr = argObjs[i];
+
+	varPtr->flags = 0;
+	varPtr->value.objPtr = objPtr;
+	Tcl_IncrRefCount(objPtr);	/* Local var is a reference. */
+    }
+    for (; i < numArgs-1; i++, varPtr++, defPtr ? defPtr++ : defPtr) {
+	/*
+	 * This loop is entered if argCt < (numArgs-1). Set default values;
+	 * last formal is special.
+	 */
+
+	Tcl_Obj *objPtr = defPtr ? defPtr->value.objPtr : NULL;
+
+	if (!objPtr) {
+	    goto incorrectArgs;
+	}
+	varPtr->flags = 0;
+	varPtr->value.objPtr = objPtr;
+	Tcl_IncrRefCount(objPtr);	/* Local var reference. */
+    }
+
+    /*
+     * When we get here, the last formal argument remains to be defined:
+     * defPtr and varPtr point to the last argument to be initialized.
+     */
+
+    varPtr->flags = 0;
+    if (defPtr && defPtr->flags & VAR_IS_ARGS) {
+	Tcl_Obj *listPtr = Tcl_NewListObj(argCt-i, argObjs+i);
+
+	varPtr->value.objPtr = listPtr;
+	Tcl_IncrRefCount(listPtr);	/* Local var is a reference. */
+    } else if (argCt == numArgs) {
+	Tcl_Obj *objPtr = argObjs[i];
+
+	varPtr->value.objPtr = objPtr;
+	Tcl_IncrRefCount(objPtr);	/* Local var is a reference. */
+    } else if ((argCt < numArgs) && defPtr && defPtr->value.objPtr) {
+	Tcl_Obj *objPtr = defPtr->value.objPtr;
+
+	varPtr->value.objPtr = objPtr;
+	Tcl_IncrRefCount(objPtr);	/* Local var is a reference. */
+    } else {
+	goto incorrectArgs;
+    }
+    varPtr++;
+
+    /*
+     * Initialise and resolve the remaining compiledLocals. In the absence of
+     * resolvers, they are undefined local vars: (flags=0, value=NULL).
+     */
+
+  correctArgs:
+    if (numArgs < localCt) {
+	if (!framePtr->nsPtr->compiledVarResProc
+		&& !((Interp *)interp)->resolverPtr) {
+	    memset(varPtr, 0, (localCt - numArgs)*sizeof(Var));
+	} else {
+	    InitResolvedLocals(interp, codePtr, varPtr, framePtr->nsPtr);
+	}
+    }
+
+    return TCL_OK;
+
+    /*
+     * Initialise all compiled locals to avoid problems at DeleteLocalVars.
+     */
+
+  incorrectArgs:
+    if ((skip != 1) &&
+	    TclInitRewriteEnsemble(interp, skip-1, 0, framePtr->objv)) {
+	TclNRAddCallback(interp, TclClearRootEnsemble, NULL, NULL, NULL, NULL);
+    }
+    memset(varPtr, 0,
+	    ((framePtr->compiledLocals + localCt)-varPtr) * sizeof(Var));
+    return ProcWrongNumArgs(interp, skip);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclPushProcCallFrame --
+ *
+ *	Compiles a proc body if necessary, then pushes a CallFrame suitable
+ *	for executing it.
+ *
+ * Results:
+ *	A standard Tcl object result value.
+ *
+ * Side effects:
+ *	The proc's body may be recompiled. A CallFrame is pushed, it will have
+ *	to be popped by the caller.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclPushProcCallFrame(
+    ClientData clientData,	/* Record describing procedure to be
+				 * interpreted. */
+    register Tcl_Interp *interp,/* Interpreter in which procedure was
+				 * invoked. */
+    int objc,			/* Count of number of arguments to this
+				 * procedure. */
+    Tcl_Obj *const objv[],	/* Argument value objects. */
+    int isLambda)		/* 1 if this is a call by ApplyObjCmd: it
+				 * needs special rules for error msg */
+{
+    Proc *procPtr = clientData;
+    Namespace *nsPtr = procPtr->cmdPtr->nsPtr;
+    CallFrame *framePtr, **framePtrPtr;
+    int result;
+    ByteCode *codePtr;
+
+    /*
+     * If necessary (i.e. if we haven't got a suitable compilation already
+     * cached) compile the procedure's body. The compiler will allocate frame
+     * slots for the procedure's non-argument local variables. Note that
+     * compiling the body might increase procPtr->numCompiledLocals if new
+     * local variables are found while compiling.
+     */
+
+    if (procPtr->bodyPtr->typePtr == &tclByteCodeType) {
+	Interp *iPtr = (Interp *) interp;
+
+	/*
+	 * When we've got bytecode, this is the check for validity. That is,
+	 * the bytecode must be for the right interpreter (no cross-leaks!),
+	 * the code must be from the current epoch (so subcommand compilation
+	 * is up-to-date), the namespace must match (so variable handling
+	 * is right) and the resolverEpoch must match (so that new shadowed
+	 * commands and/or resolver changes are considered).
+	 */
+
+	codePtr = procPtr->bodyPtr->internalRep.twoPtrValue.ptr1;
+	if (((Interp *) *codePtr->interpHandle != iPtr)
+		|| (codePtr->compileEpoch != iPtr->compileEpoch)
+		|| (codePtr->nsPtr != nsPtr)
+		|| (codePtr->nsEpoch != nsPtr->resolverEpoch)) {
+	    goto doCompilation;
+	}
+    } else {
+    doCompilation:
+	result = TclProcCompileProc(interp, procPtr, procPtr->bodyPtr, nsPtr,
+		(isLambda ? "body of lambda term" : "body of proc"),
+		TclGetString(objv[isLambda]));
+	if (result != TCL_OK) {
+	    return result;
+	}
+    }
+
+    /*
+     * Set up and push a new call frame for the new procedure invocation.
+     * This call frame will execute in the proc's namespace, which might be
+     * different than the current namespace. The proc's namespace is that of
+     * its command, which can change if the command is renamed from one
+     * namespace to another.
+     */
+
+    framePtrPtr = &framePtr;
+    (void) TclPushStackFrame(interp, (Tcl_CallFrame **) framePtrPtr,
+	    (Tcl_Namespace *) nsPtr,
+	    (isLambda? (FRAME_IS_PROC|FRAME_IS_LAMBDA) : FRAME_IS_PROC));
+
+    framePtr->objc = objc;
+    framePtr->objv = objv;
+    framePtr->procPtr = procPtr;
+
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclObjInterpProc --
+ *
+ *	When a Tcl procedure gets invoked during bytecode evaluation, this
+ *	object-based routine gets invoked to interpret the procedure.
+ *
+ * Results:
+ *	A standard Tcl object result value.
+ *
+ * Side effects:
+ *	Depends on the commands in the procedure.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclObjInterpProc(
+    ClientData clientData,	/* Record describing procedure to be
+				 * interpreted. */
+    register Tcl_Interp *interp,/* Interpreter in which procedure was
+				 * invoked. */
+    int objc,			/* Count of number of arguments to this
+				 * procedure. */
+    Tcl_Obj *const objv[])	/* Argument value objects. */
+{
+    /*
+     * Not used much in the core; external interface for iTcl
+     */
+
+    return Tcl_NRCallObjProc(interp, TclNRInterpProc, clientData, objc, objv);
+}
+
+int
+TclNRInterpProc(
+    ClientData clientData,	/* Record describing procedure to be
+				 * interpreted. */
+    register Tcl_Interp *interp,/* Interpreter in which procedure was
+				 * invoked. */
+    int objc,			/* Count of number of arguments to this
+				 * procedure. */
+    Tcl_Obj *const objv[])	/* Argument value objects. */
+{
+    int result = TclPushProcCallFrame(clientData, interp, objc, objv,
+	    /*isLambda*/ 0);
+
+    if (result != TCL_OK) {
+	return TCL_ERROR;
+    }
+    return TclNRInterpProcCore(interp, objv[0], 1, &MakeProcError);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclNRInterpProcCore --
+ *
+ *	When a Tcl procedure, lambda term or anything else that works like a
+ *	procedure gets invoked during bytecode evaluation, this object-based
+ *	routine gets invoked to interpret the body.
+ *
+ * Results:
+ *	A standard Tcl object result value.
+ *
+ * Side effects:
+ *	Nearly anything; depends on the commands in the procedure body.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclNRInterpProcCore(
+    register Tcl_Interp *interp,/* Interpreter in which procedure was
+				 * invoked. */
+    Tcl_Obj *procNameObj,	/* Procedure name for error reporting. */
+    int skip,			/* Number of initial arguments to be skipped,
+				 * i.e., words in the "command name". */
+    ProcErrorProc *errorProc)	/* How to convert results from the script into
+				 * results of the overall procedure. */
+{
+    Interp *iPtr = (Interp *) interp;
+    register Proc *procPtr = iPtr->varFramePtr->procPtr;
+    int result;
+    CallFrame *freePtr;
+    ByteCode *codePtr;
+
+    result = InitArgsAndLocals(interp, procNameObj, skip);
+    if (result != TCL_OK) {
+	freePtr = iPtr->framePtr;
+	Tcl_PopCallFrame(interp);	/* Pop but do not free. */
+	TclStackFree(interp, freePtr->compiledLocals);
+					/* Free compiledLocals. */
+	TclStackFree(interp, freePtr);	/* Free CallFrame. */
+	return TCL_ERROR;
+    }
+
+#if defined(TCL_COMPILE_DEBUG)
+    if (tclTraceExec >= 1) {
+	register CallFrame *framePtr = iPtr->varFramePtr;
+	register int i;
+
+	if (framePtr->isProcCallFrame & FRAME_IS_LAMBDA) {
+	    fprintf(stdout, "Calling lambda ");
+	} else {
+	    fprintf(stdout, "Calling proc ");
+	}
+	for (i = 0; i < framePtr->objc; i++) {
+	    TclPrintObject(stdout, framePtr->objv[i], 15);
+	    fprintf(stdout, " ");
+	}
+	fprintf(stdout, "\n");
+	fflush(stdout);
+    }
+#endif /*TCL_COMPILE_DEBUG*/
+
+#ifdef USE_DTRACE
+    if (TCL_DTRACE_PROC_ARGS_ENABLED()) {
+	int l = iPtr->varFramePtr->isProcCallFrame & FRAME_IS_LAMBDA ? 1 : 0;
+	const char *a[10];
+	int i;
+
+	for (i = 0 ; i < 10 ; i++) {
+	    a[i] = (l < iPtr->varFramePtr->objc ?
+		    TclGetString(iPtr->varFramePtr->objv[l]) : NULL);
+	    l++;
+	}
+	TCL_DTRACE_PROC_ARGS(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7],
+		a[8], a[9]);
+    }
+    if (TCL_DTRACE_PROC_INFO_ENABLED() && iPtr->cmdFramePtr) {
+	Tcl_Obj *info = TclInfoFrame(interp, iPtr->cmdFramePtr);
+	const char *a[6]; int i[2];
+
+	TclDTraceInfo(info, a, i);
+	TCL_DTRACE_PROC_INFO(a[0], a[1], a[2], a[3], i[0], i[1], a[4], a[5]);
+	TclDecrRefCount(info);
+    }
+    if (TCL_DTRACE_PROC_ENTRY_ENABLED()) {
+	int l = iPtr->varFramePtr->isProcCallFrame & FRAME_IS_LAMBDA ? 1 : 0;
+
+	TCL_DTRACE_PROC_ENTRY(l < iPtr->varFramePtr->objc ?
+		TclGetString(iPtr->varFramePtr->objv[l]) : NULL,
+		iPtr->varFramePtr->objc - l - 1,
+		(Tcl_Obj **)(iPtr->varFramePtr->objv + l + 1));
+    }
+    if (TCL_DTRACE_PROC_ENTRY_ENABLED()) {
+	int l = iPtr->varFramePtr->isProcCallFrame & FRAME_IS_LAMBDA ? 1 : 0;
+
+	TCL_DTRACE_PROC_ENTRY(l < iPtr->varFramePtr->objc ?
+		TclGetString(iPtr->varFramePtr->objv[l]) : NULL,
+		iPtr->varFramePtr->objc - l - 1,
+		(Tcl_Obj **)(iPtr->varFramePtr->objv + l + 1));
+    }
+#endif /* USE_DTRACE */
+
+    /*
+     * Invoke the commands in the procedure's body.
+     */
+
+    procPtr->refCount++;
+    codePtr = procPtr->bodyPtr->internalRep.twoPtrValue.ptr1;
+
+    TclNRAddCallback(interp, InterpProcNR2, procNameObj, errorProc,
+	    NULL, NULL);
+    return TclNRExecuteByteCode(interp, codePtr);
+}
+
+static int
+InterpProcNR2(
+    ClientData data[],
+    Tcl_Interp *interp,
+    int result)
+{
+    Interp *iPtr = (Interp *) interp;
+    Proc *procPtr = iPtr->varFramePtr->procPtr;
+    CallFrame *freePtr;
+    Tcl_Obj *procNameObj = data[0];
+    ProcErrorProc *errorProc = (ProcErrorProc *)data[1];
+
+    if (TCL_DTRACE_PROC_RETURN_ENABLED()) {
+	int l = iPtr->varFramePtr->isProcCallFrame & FRAME_IS_LAMBDA ? 1 : 0;
+
+	TCL_DTRACE_PROC_RETURN(l < iPtr->varFramePtr->objc ?
+		TclGetString(iPtr->varFramePtr->objv[l]) : NULL, result);
+    }
+    if (procPtr->refCount-- <= 1) {
+	TclProcCleanupProc(procPtr);
+    }
+
+    /*
+     * Free the stack-allocated compiled locals and CallFrame. It is important
+     * to pop the call frame without freeing it first: the compiledLocals
+     * cannot be freed before the frame is popped, as the local variables must
+     * be deleted. But the compiledLocals must be freed first, as they were
+     * allocated later on the stack.
+     */
+
+    if (result != TCL_OK) {
+	goto process;
+    }
+
+    done:
+    if (TCL_DTRACE_PROC_RESULT_ENABLED()) {
+	int l = iPtr->varFramePtr->isProcCallFrame & FRAME_IS_LAMBDA ? 1 : 0;
+	Tcl_Obj *r = Tcl_GetObjResult(interp);
+
+	TCL_DTRACE_PROC_RESULT(l < iPtr->varFramePtr->objc ?
+		TclGetString(iPtr->varFramePtr->objv[l]) : NULL, result,
+		TclGetString(r), r);
+    }
+
+    freePtr = iPtr->framePtr;
+    Tcl_PopCallFrame(interp);		/* Pop but do not free. */
+    TclStackFree(interp, freePtr->compiledLocals);
+					/* Free compiledLocals. */
+    TclStackFree(interp, freePtr);	/* Free CallFrame. */
+    return result;
+
+    /*
+     * Process any non-TCL_OK result code.
+     */
+
+    process:
+    switch (result) {
+    case TCL_RETURN:
+	/*
+	 * If it is a 'return', do the TIP#90 processing now.
+	 */
+
+	result = TclUpdateReturnInfo((Interp *) interp);
+	break;
+
+    case TCL_CONTINUE:
+    case TCL_BREAK:
+	/*
+	 * It's an error to get to this point from a 'break' or 'continue', so
+	 * transform to an error now.
+	 */
+
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		"invoked \"%s\" outside of a loop",
+		((result == TCL_BREAK) ? "break" : "continue")));
+	Tcl_SetErrorCode(interp, "TCL", "RESULT", "UNEXPECTED", NULL);
+	result = TCL_ERROR;
+
+	/*
+	 * Fall through to the TCL_ERROR handling code.
+	 */
+
+    case TCL_ERROR:
+	/*
+	 * Now it _must_ be an error, so we need to log it as such. This means
+	 * filling out the error trace. Luckily, we just hand this off to the
+	 * function handed to us as an argument.
+	 */
+
+	errorProc(interp, procNameObj);
+    }
+    goto done;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclProcCompileProc --
+ *
+ *	Called just before a procedure is executed to compile the body to byte
+ *	codes. If the type of the body is not "byte code" or if the compile
+ *	conditions have changed (namespace context, epoch counters, etc.) then
+ *	the body is recompiled. Otherwise, this function does nothing.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	May change the internal representation of the body object to compiled
+ *	code.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclProcCompileProc(
+    Tcl_Interp *interp,		/* Interpreter containing procedure. */
+    Proc *procPtr,		/* Data associated with procedure. */
+    Tcl_Obj *bodyPtr,		/* Body of proc. (Usually procPtr->bodyPtr,
+				 * but could be any code fragment compiled in
+				 * the context of this procedure.) */
+    Namespace *nsPtr,		/* Namespace containing procedure. */
+    const char *description,	/* string describing this body of code. */
+    const char *procName)	/* Name of this procedure. */
+{
+    Interp *iPtr = (Interp *) interp;
+    Tcl_CallFrame *framePtr;
+    ByteCode *codePtr = bodyPtr->internalRep.twoPtrValue.ptr1;
+
+    /*
+     * If necessary, compile the procedure's body. The compiler will allocate
+     * frame slots for the procedure's non-argument local variables. If the
+     * ByteCode already exists, make sure it hasn't been invalidated by
+     * someone redefining a core command (this might make the compiled code
+     * wrong). Also, if the code was compiled in/for a different interpreter,
+     * we recompile it. Note that compiling the body might increase
+     * procPtr->numCompiledLocals if new local variables are found while
+     * compiling.
+     *
+     * Precompiled procedure bodies, however, are immutable and therefore they
+     * are not recompiled, even if things have changed.
+     */
+
+    if (bodyPtr->typePtr == &tclByteCodeType) {
+	if (((Interp *) *codePtr->interpHandle == iPtr)
+		&& (codePtr->compileEpoch == iPtr->compileEpoch)
+		&& (codePtr->nsPtr == nsPtr)
+		&& (codePtr->nsEpoch == nsPtr->resolverEpoch)) {
+	    return TCL_OK;
+	}
+
+	if (codePtr->flags & TCL_BYTECODE_PRECOMPILED) {
+	    if ((Interp *) *codePtr->interpHandle != iPtr) {
+		Tcl_SetObjResult(interp, Tcl_NewStringObj(
+			"a precompiled script jumped interps", -1));
+		Tcl_SetErrorCode(interp, "TCL", "OPERATION", "PROC",
+			"CROSSINTERPBYTECODE", NULL);
+		return TCL_ERROR;
+	    }
+	    codePtr->compileEpoch = iPtr->compileEpoch;
+	    codePtr->nsPtr = nsPtr;
+	} else {
+	    TclFreeIntRep(bodyPtr);
+	}
+    }
+
+    if (bodyPtr->typePtr != &tclByteCodeType) {
+	Tcl_HashEntry *hePtr;
+
+#ifdef TCL_COMPILE_DEBUG
+	if (tclTraceCompile >= 1) {
+	    /*
+	     * Display a line summarizing the top level command we are about
+	     * to compile.
+	     */
+
+	    Tcl_Obj *message;
+
+	    TclNewLiteralStringObj(message, "Compiling ");
+	    Tcl_IncrRefCount(message);
+	    Tcl_AppendStringsToObj(message, description, " \"", NULL);
+	    Tcl_AppendLimitedToObj(message, procName, -1, 50, NULL);
+	    fprintf(stdout, "%s\"\n", TclGetString(message));
+	    Tcl_DecrRefCount(message);
+	}
+#endif
+
+	/*
+	 * Plug the current procPtr into the interpreter and coerce the code
+	 * body to byte codes. The interpreter needs to know which proc it's
+	 * compiling so that it can access its list of compiled locals.
+	 *
+	 * TRICKY NOTE: Be careful to push a call frame with the proper
+	 *   namespace context, so that the byte codes are compiled in the
+	 *   appropriate class context.
+	 */
+
+	iPtr->compiledProcPtr = procPtr;
+
+	if (procPtr->numCompiledLocals > procPtr->numArgs) {
+	    CompiledLocal *clPtr = procPtr->firstLocalPtr;
+	    CompiledLocal *lastPtr = NULL;
+	    int i, numArgs = procPtr->numArgs;
+
+	    for (i = 0; i < numArgs; i++) {
+		lastPtr = clPtr;
+		clPtr = clPtr->nextPtr;
+	    }
+
+	    if (lastPtr) {
+		lastPtr->nextPtr = NULL;
+	    } else {
+		procPtr->firstLocalPtr = NULL;
+	    }
+	    procPtr->lastLocalPtr = lastPtr;
+	    while (clPtr) {
+		CompiledLocal *toFree = clPtr;
+
+		clPtr = clPtr->nextPtr;
+		if (toFree->resolveInfo) {
+		    if (toFree->resolveInfo->deleteProc) {
+			toFree->resolveInfo->deleteProc(toFree->resolveInfo);
+		    } else {
+			ckfree(toFree->resolveInfo);
+		    }
+		}
+		ckfree(toFree);
+	    }
+	    procPtr->numCompiledLocals = procPtr->numArgs;
+	}
+
+	(void) TclPushStackFrame(interp, &framePtr, (Tcl_Namespace *) nsPtr,
+		/* isProcCallFrame */ 0);
+
+	/*
+	 * TIP #280: We get the invoking context from the cmdFrame which
+	 * was saved by 'Tcl_ProcObjCmd' (using linePBodyPtr).
+	 */
+
+	hePtr = Tcl_FindHashEntry(iPtr->linePBodyPtr, (char *) procPtr);
+
+	/*
+	 * Constructed saved frame has body as word 0. See Tcl_ProcObjCmd.
+	 */
+
+	iPtr->invokeWord = 0;
+	iPtr->invokeCmdFramePtr = (hePtr ? Tcl_GetHashValue(hePtr) : NULL);
+	TclSetByteCodeFromAny(interp, bodyPtr, NULL, NULL);
+	iPtr->invokeCmdFramePtr = NULL;
+	TclPopStackFrame(interp);
+    } else if (codePtr->nsEpoch != nsPtr->resolverEpoch) {
+	/*
+	 * The resolver epoch has changed, but we only need to invalidate the
+	 * resolver cache.
+	 */
+
+	codePtr->nsEpoch = nsPtr->resolverEpoch;
+	codePtr->flags |= TCL_BYTECODE_RESOLVE_VARS;
+    }
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * MakeProcError --
+ *
+ *	Function called by TclObjInterpProc to create the stack information
+ *	upon an error from a procedure.
+ *
+ * Results:
+ *	The interpreter's error info trace is set to a value that supplements
+ *	the error code.
+ *
+ * Side effects:
+ *	none.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+MakeProcError(
+    Tcl_Interp *interp,		/* The interpreter in which the procedure was
+				 * called. */
+    Tcl_Obj *procNameObj)	/* Name of the procedure. Used for error
+				 * messages and trace information. */
+{
+    int overflow, limit = 60, nameLen;
+    const char *procName = Tcl_GetStringFromObj(procNameObj, &nameLen);
+
+    overflow = (nameLen > limit);
+    Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf(
+	    "\n    (procedure \"%.*s%s\" line %d)",
+	    (overflow ? limit : nameLen), procName,
+	    (overflow ? "..." : ""), Tcl_GetErrorLine(interp)));
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclProcDeleteProc --
+ *
+ *	This function is invoked just before a command procedure is removed
+ *	from an interpreter. Its job is to release all the resources allocated
+ *	to the procedure.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Memory gets freed, unless the procedure is actively being executed.
+ *	In this case the cleanup is delayed until the last call to the current
+ *	procedure completes.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclProcDeleteProc(
+    ClientData clientData)	/* Procedure to be deleted. */
+{
+    Proc *procPtr = clientData;
+
+    if (procPtr->refCount-- <= 1) {
+	TclProcCleanupProc(procPtr);
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclProcCleanupProc --
+ *
+ *	This function does all the real work of freeing up a Proc structure.
+ *	It's called only when the structure's reference count becomes zero.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Memory gets freed.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclProcCleanupProc(
+    register Proc *procPtr)	/* Procedure to be deleted. */
+{
+    register CompiledLocal *localPtr;
+    Tcl_Obj *bodyPtr = procPtr->bodyPtr;
+    Tcl_Obj *defPtr;
+    Tcl_ResolvedVarInfo *resVarInfo;
+    Tcl_HashEntry *hePtr = NULL;
+    CmdFrame *cfPtr = NULL;
+    Interp *iPtr = procPtr->iPtr;
+
+    if (bodyPtr != NULL) {
+	Tcl_DecrRefCount(bodyPtr);
+    }
+    for (localPtr = procPtr->firstLocalPtr; localPtr != NULL; ) {
+	CompiledLocal *nextPtr = localPtr->nextPtr;
+
+	resVarInfo = localPtr->resolveInfo;
+	if (resVarInfo) {
+	    if (resVarInfo->deleteProc) {
+		resVarInfo->deleteProc(resVarInfo);
+	    } else {
+		ckfree(resVarInfo);
+	    }
+	}
+
+	if (localPtr->defValuePtr != NULL) {
+	    defPtr = localPtr->defValuePtr;
+	    Tcl_DecrRefCount(defPtr);
+	}
+	ckfree(localPtr);
+	localPtr = nextPtr;
+    }
+    ckfree(procPtr);
+
+    /*
+     * TIP #280: Release the location data associated with this Proc
+     * structure, if any. The interpreter may not exist (For example for
+     * procbody structures created by tbcload.
+     */
+
+    if (iPtr == NULL) {
+	return;
+    }
+
+    hePtr = Tcl_FindHashEntry(iPtr->linePBodyPtr, (char *) procPtr);
+    if (!hePtr) {
+	return;
+    }
+
+    cfPtr = Tcl_GetHashValue(hePtr);
+
+    if (cfPtr) {
+	if (cfPtr->type == TCL_LOCATION_SOURCE) {
+	    Tcl_DecrRefCount(cfPtr->data.eval.path);
+	    cfPtr->data.eval.path = NULL;
+	}
+	ckfree(cfPtr->line);
+	cfPtr->line = NULL;
+	ckfree(cfPtr);
+    }
+    Tcl_DeleteHashEntry(hePtr);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclUpdateReturnInfo --
+ *
+ *	This function is called when procedures return, and at other points
+ *	where the TCL_RETURN code is used. It examines the returnLevel and
+ *	returnCode to determine the real return status.
+ *
+ * Results:
+ *	The return value is the true completion code to use for the procedure
+ *	or script, instead of TCL_RETURN.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclUpdateReturnInfo(
+    Interp *iPtr)		/* Interpreter for which TCL_RETURN exception
+				 * is being processed. */
+{
+    int code = TCL_RETURN;
+
+    iPtr->returnLevel--;
+    if (iPtr->returnLevel < 0) {
+	Tcl_Panic("TclUpdateReturnInfo: negative return level");
+    }
+    if (iPtr->returnLevel == 0) {
+	/*
+	 * Now we've reached the level to return the requested -code.
+	 * Since iPtr->returnLevel and iPtr->returnCode have completed
+	 * their task, we now reset them to default values so that any
+	 * bare "return TCL_RETURN" that may follow will work [Bug 2152286].
+	 */
+
+	code = iPtr->returnCode;
+	iPtr->returnLevel = 1;
+	iPtr->returnCode = TCL_OK;
+	if (code == TCL_ERROR) {
+	    iPtr->flags |= ERR_LEGACY_COPY;
+	}
+    }
+    return code;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclGetObjInterpProc --
+ *
+ *	Returns a pointer to the TclObjInterpProc function; this is different
+ *	from the value obtained from the TclObjInterpProc reference on systems
+ *	like Windows where import and export versions of a function exported
+ *	by a DLL exist.
+ *
+ * Results:
+ *	Returns the internal address of the TclObjInterpProc function.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+TclObjCmdProcType
+TclGetObjInterpProc(void)
+{
+    return (TclObjCmdProcType) TclObjInterpProc;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclNewProcBodyObj --
+ *
+ *	Creates a new object, of type "procbody", whose internal
+ *	representation is the given Proc struct. The newly created object's
+ *	reference count is 0.
+ *
+ * Results:
+ *	Returns a pointer to a newly allocated Tcl_Obj, NULL on error.
+ *
+ * Side effects:
+ *	The reference count in the ByteCode attached to the Proc is bumped up
+ *	by one, since the internal rep stores a pointer to it.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_Obj *
+TclNewProcBodyObj(
+    Proc *procPtr)		/* the Proc struct to store as the internal
+				 * representation. */
+{
+    Tcl_Obj *objPtr;
+
+    if (!procPtr) {
+	return NULL;
+    }
+
+    TclNewObj(objPtr);
+    if (objPtr) {
+	objPtr->typePtr = &tclProcBodyType;
+	objPtr->internalRep.twoPtrValue.ptr1 = procPtr;
+
+	procPtr->refCount++;
+    }
+
+    return objPtr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ProcBodyDup --
+ *
+ *	Tcl_ObjType's Dup function for the proc body object. Bumps the
+ *	reference count on the Proc stored in the internal representation.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Sets up the object in dupPtr to be a duplicate of the one in srcPtr.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+ProcBodyDup(
+    Tcl_Obj *srcPtr,		/* Object to copy. */
+    Tcl_Obj *dupPtr)		/* Target object for the duplication. */
+{
+    Proc *procPtr = srcPtr->internalRep.twoPtrValue.ptr1;
+
+    dupPtr->typePtr = &tclProcBodyType;
+    dupPtr->internalRep.twoPtrValue.ptr1 = procPtr;
+    procPtr->refCount++;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ProcBodyFree --
+ *
+ *	Tcl_ObjType's Free function for the proc body object. The reference
+ *	count on its Proc struct is decreased by 1; if the count reaches 0,
+ *	the proc is freed.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	If the reference count on the Proc struct reaches 0, the struct is
+ *	freed.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+ProcBodyFree(
+    Tcl_Obj *objPtr)		/* The object to clean up. */
+{
+    Proc *procPtr = objPtr->internalRep.twoPtrValue.ptr1;
+
+    if (procPtr->refCount-- <= 1) {
+	TclProcCleanupProc(procPtr);
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * DupLambdaInternalRep, FreeLambdaInternalRep, SetLambdaFromAny --
+ *
+ *	How to manage the internal representations of lambda term objects.
+ *	Syntactically they look like a two- or three-element list, where the
+ *	first element is the formal arguments, the second is the the body, and
+ *	the (optional) third is the namespace to execute the lambda term
+ *	within (the global namespace is assumed if it is absent).
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+DupLambdaInternalRep(
+    Tcl_Obj *srcPtr,		/* Object with internal rep to copy. */
+    register Tcl_Obj *copyPtr)	/* Object with internal rep to set. */
+{
+    Proc *procPtr = srcPtr->internalRep.twoPtrValue.ptr1;
+    Tcl_Obj *nsObjPtr = srcPtr->internalRep.twoPtrValue.ptr2;
+
+    copyPtr->internalRep.twoPtrValue.ptr1 = procPtr;
+    copyPtr->internalRep.twoPtrValue.ptr2 = nsObjPtr;
+
+    procPtr->refCount++;
+    Tcl_IncrRefCount(nsObjPtr);
+    copyPtr->typePtr = &tclLambdaType;
+}
+
+static void
+FreeLambdaInternalRep(
+    register Tcl_Obj *objPtr)	/* CmdName object with internal representation
+				 * to free. */
+{
+    Proc *procPtr = objPtr->internalRep.twoPtrValue.ptr1;
+    Tcl_Obj *nsObjPtr = objPtr->internalRep.twoPtrValue.ptr2;
+
+    if (procPtr->refCount-- == 1) {
+	TclProcCleanupProc(procPtr);
+    }
+    TclDecrRefCount(nsObjPtr);
+    objPtr->typePtr = NULL;
+}
+
+static int
+SetLambdaFromAny(
+    Tcl_Interp *interp,		/* Used for error reporting if not NULL. */
+    register Tcl_Obj *objPtr)	/* The object to convert. */
+{
+    Interp *iPtr = (Interp *) interp;
+    const char *name;
+    Tcl_Obj *argsPtr, *bodyPtr, *nsObjPtr, **objv;
+    int isNew, objc, result;
+    CmdFrame *cfPtr = NULL;
+    Proc *procPtr;
+
+    if (interp == NULL) {
+	return TCL_ERROR;
+    }
+
+    /*
+     * Convert objPtr to list type first; if it cannot be converted, or if its
+     * length is not 2, then it cannot be converted to tclLambdaType.
+     */
+
+    result = TclListObjGetElements(NULL, objPtr, &objc, &objv);
+    if ((result != TCL_OK) || ((objc != 2) && (objc != 3))) {
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		"can't interpret \"%s\" as a lambda expression",
+		Tcl_GetString(objPtr)));
+	Tcl_SetErrorCode(interp, "TCL", "VALUE", "LAMBDA", NULL);
+	return TCL_ERROR;
+    }
+
+    argsPtr = objv[0];
+    bodyPtr = objv[1];
+
+    /*
+     * Create and initialize the Proc struct. The cmdPtr field is set to NULL
+     * to signal that this is an anonymous function.
+     */
+
+    name = TclGetString(objPtr);
+
+    if (TclCreateProc(interp, /*ignored nsPtr*/ NULL, name, argsPtr, bodyPtr,
+	    &procPtr) != TCL_OK) {
+	Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf(
+		"\n    (parsing lambda expression \"%s\")", name));
+	return TCL_ERROR;
+    }
+
+    /*
+     * CAREFUL: TclCreateProc returns refCount==1! [Bug 1578454]
+     * procPtr->refCount = 1;
+     */
+
+    procPtr->cmdPtr = NULL;
+
+    /*
+     * TIP #280: Remember the line the apply body is starting on. In a Byte
+     * code context we ask the engine to provide us with the necessary
+     * information. This is for the initialization of the byte code compiler
+     * when the body is used for the first time.
+     *
+     * NOTE: The body is the second word in the 'objPtr'. Its location,
+     * accessible through 'context.line[1]' (see below) is therefore only the
+     * first approximation of the actual line the body is on. We have to use
+     * the string rep of the 'objPtr' to determine the exact line. This is
+     * available already through 'name'. Use 'TclListLines', see 'switch'
+     * (tclCmdMZ.c).
+     *
+     * This code is nearly identical to the #280 code in Tcl_ProcObjCmd, see
+     * this file. The differences are the different index of the body in the
+     * line array of the context, and the special processing mentioned in the
+     * previous paragraph to track into the list. Find a way to factor the
+     * common elements into a single function.
+     */
+
+    if (iPtr->cmdFramePtr) {
+	CmdFrame *contextPtr = TclStackAlloc(interp, sizeof(CmdFrame));
+
+	*contextPtr = *iPtr->cmdFramePtr;
+	if (contextPtr->type == TCL_LOCATION_BC) {
+	    /*
+	     * Retrieve the source context from the bytecode. This call
+	     * accounts for the reference to the source file, if any, held in
+	     * 'context.data.eval.path'.
+	     */
+
+	    TclGetSrcInfoForPc(contextPtr);
+	} else if (contextPtr->type == TCL_LOCATION_SOURCE) {
+	    /*
+	     * We created a new reference to the source file path name when we
+	     * created 'context' above. Account for the reference.
+	     */
+
+	    Tcl_IncrRefCount(contextPtr->data.eval.path);
+
+	}
+
+	if (contextPtr->type == TCL_LOCATION_SOURCE) {
+	    /*
+	     * We can record source location within a lambda only if the body
+	     * was not created by substitution.
+	     */
+
+	    if (contextPtr->line
+		    && (contextPtr->nline >= 2) && (contextPtr->line[1] >= 0)) {
+		int buf[2];
+
+		/*
+		 * Move from approximation (line of list cmd word) to actual
+		 * location (line of 2nd list element).
+		 */
+
+		cfPtr = ckalloc(sizeof(CmdFrame));
+		TclListLines(objPtr, contextPtr->line[1], 2, buf, NULL);
+
+		cfPtr->level = -1;
+		cfPtr->type = contextPtr->type;
+		cfPtr->line = ckalloc(sizeof(int));
+		cfPtr->line[0] = buf[1];
+		cfPtr->nline = 1;
+		cfPtr->framePtr = NULL;
+		cfPtr->nextPtr = NULL;
+
+		cfPtr->data.eval.path = contextPtr->data.eval.path;
+		Tcl_IncrRefCount(cfPtr->data.eval.path);
+
+		cfPtr->cmd = NULL;
+		cfPtr->len = 0;
+	    }
+
+	    /*
+	     * 'contextPtr' is going out of scope. Release the reference that
+	     * it's holding to the source file path
+	     */
+
+	    Tcl_DecrRefCount(contextPtr->data.eval.path);
+	}
+	TclStackFree(interp, contextPtr);
+    }
+    Tcl_SetHashValue(Tcl_CreateHashEntry(iPtr->linePBodyPtr, procPtr,
+	    &isNew), cfPtr);
+
+    /*
+     * Set the namespace for this lambda: given by objv[2] understood as a
+     * global reference, or else global per default.
+     */
+
+    if (objc == 2) {
+	TclNewLiteralStringObj(nsObjPtr, "::");
+    } else {
+	const char *nsName = TclGetString(objv[2]);
+
+	if ((*nsName != ':') || (*(nsName+1) != ':')) {
+	    TclNewLiteralStringObj(nsObjPtr, "::");
+	    Tcl_AppendObjToObj(nsObjPtr, objv[2]);
+	} else {
+	    nsObjPtr = objv[2];
+	}
+    }
+
+    Tcl_IncrRefCount(nsObjPtr);
+
+    /*
+     * Free the list internalrep of objPtr - this will free argsPtr, but
+     * bodyPtr retains a reference from the Proc structure. Then finish the
+     * conversion to tclLambdaType.
+     */
+
+    TclFreeIntRep(objPtr);
+
+    objPtr->internalRep.twoPtrValue.ptr1 = procPtr;
+    objPtr->internalRep.twoPtrValue.ptr2 = nsObjPtr;
+    objPtr->typePtr = &tclLambdaType;
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_ApplyObjCmd --
+ *
+ *	This object-based function is invoked to process the "apply" Tcl
+ *	command. See the user documentation for details on what it does.
+ *
+ * Results:
+ *	A standard Tcl object result value.
+ *
+ * Side effects:
+ *	Depends on the content of the lambda term (i.e., objv[1]).
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_ApplyObjCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    return Tcl_NRCallObjProc(interp, TclNRApplyObjCmd, dummy, objc, objv);
+}
+
+int
+TclNRApplyObjCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    Interp *iPtr = (Interp *) interp;
+    Proc *procPtr = NULL;
+    Tcl_Obj *lambdaPtr, *nsObjPtr;
+    int result;
+    Tcl_Namespace *nsPtr;
+    ApplyExtraData *extraPtr;
+
+    if (objc < 2) {
+	Tcl_WrongNumArgs(interp, 1, objv, "lambdaExpr ?arg ...?");
+	return TCL_ERROR;
+    }
+
+    /*
+     * Set lambdaPtr, convert it to tclLambdaType in the current interp if
+     * necessary.
+     */
+
+    lambdaPtr = objv[1];
+    if (lambdaPtr->typePtr == &tclLambdaType) {
+	procPtr = lambdaPtr->internalRep.twoPtrValue.ptr1;
+    }
+
+#define JOE_EXTENSION 0
+/*
+ * Note: this code is NOT FUNCTIONAL due to the NR implementation; DO NOT
+ * ENABLE! Leaving here as reminder to (a) TIP the suggestion, and (b) adapt
+ * the code. (MS)
+ */
+
+#if JOE_EXTENSION
+    else {
+	/*
+	 * Joe English's suggestion to allow cmdNames to function as lambdas.
+	 */
+
+	Tcl_Obj *elemPtr;
+	int numElem;
+
+	if ((lambdaPtr->typePtr == &tclCmdNameType) ||
+		(TclListObjGetElements(interp, lambdaPtr, &numElem,
+		&elemPtr) == TCL_OK && numElem == 1)) {
+	    return Tcl_EvalObjv(interp, objc-1, objv+1, 0);
+	}
+    }
+#endif
+
+    if ((procPtr == NULL) || (procPtr->iPtr != iPtr)) {
+	result = SetLambdaFromAny(interp, lambdaPtr);
+	if (result != TCL_OK) {
+	    return result;
+	}
+	procPtr = lambdaPtr->internalRep.twoPtrValue.ptr1;
+    }
+
+    /*
+     * Find the namespace where this lambda should run, and push a call frame
+     * for that namespace. Note that TclObjInterpProc() will pop it.
+     */
+
+    nsObjPtr = lambdaPtr->internalRep.twoPtrValue.ptr2;
+    result = TclGetNamespaceFromObj(interp, nsObjPtr, &nsPtr);
+    if (result != TCL_OK) {
+	return TCL_ERROR;
+    }
+
+    extraPtr = TclStackAlloc(interp, sizeof(ApplyExtraData));
+    memset(&extraPtr->cmd, 0, sizeof(Command));
+    procPtr->cmdPtr = &extraPtr->cmd;
+    extraPtr->cmd.nsPtr = (Namespace *) nsPtr;
+
+    /*
+     * TIP#280 (semi-)HACK!
+     *
+     * Using cmd.clientData to tell [info frame] how to render the lambdaPtr.
+     * The InfoFrameCmd will detect this case by testing cmd.hPtr for NULL.
+     * This condition holds here because of the memset() above, and nowhere
+     * else (in the core). Regular commands always have a valid hPtr, and
+     * lambda's never.
+     */
+
+    extraPtr->efi.length = 1;
+    extraPtr->efi.fields[0].name = "lambda";
+    extraPtr->efi.fields[0].proc = NULL;
+    extraPtr->efi.fields[0].clientData = lambdaPtr;
+    extraPtr->cmd.clientData = &extraPtr->efi;
+
+    result = TclPushProcCallFrame(procPtr, interp, objc, objv, 1);
+    if (result == TCL_OK) {
+	TclNRAddCallback(interp, ApplyNR2, extraPtr, NULL, NULL, NULL);
+	result = TclNRInterpProcCore(interp, objv[1], 2, &MakeLambdaError);
+    }
+    return result;
+}
+
+static int
+ApplyNR2(
+    ClientData data[],
+    Tcl_Interp *interp,
+    int result)
+{
+    ApplyExtraData *extraPtr = data[0];
+
+    TclStackFree(interp, extraPtr);
+    return result;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * MakeLambdaError --
+ *
+ *	Function called by TclObjInterpProc to create the stack information
+ *	upon an error from a lambda term.
+ *
+ * Results:
+ *	The interpreter's error info trace is set to a value that supplements
+ *	the error code.
+ *
+ * Side effects:
+ *	none.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+MakeLambdaError(
+    Tcl_Interp *interp,		/* The interpreter in which the procedure was
+				 * called. */
+    Tcl_Obj *procNameObj)	/* Name of the procedure. Used for error
+				 * messages and trace information. */
+{
+    int overflow, limit = 60, nameLen;
+    const char *procName = Tcl_GetStringFromObj(procNameObj, &nameLen);
+
+    overflow = (nameLen > limit);
+    Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf(
+	    "\n    (lambda term \"%.*s%s\" line %d)",
+	    (overflow ? limit : nameLen), procName,
+	    (overflow ? "..." : ""), Tcl_GetErrorLine(interp)));
+}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tclRegexp.c b/generic/tclRegexp.c
new file mode 100644
index 0000000..ea25d4b
--- /dev/null
+++ b/generic/tclRegexp.c
@@ -0,0 +1,1074 @@
+/*
+ * tclRegexp.c --
+ *
+ *	This file contains the public interfaces to the Tcl regular expression
+ *	mechanism.
+ *
+ * Copyright (c) 1998 by Sun Microsystems, Inc.
+ * Copyright (c) 1998-1999 by Scriptics Corporation.
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#include "tclInt.h"
+#include "tclRegexp.h"
+
+/*
+ *----------------------------------------------------------------------
+ * The routines in this file use Henry Spencer's regular expression package
+ * contained in the following additional source files:
+ *
+ *	regc_color.c	regc_cvec.c	regc_lex.c
+ *	regc_nfa.c	regcomp.c	regcustom.h
+ *	rege_dfa.c	regerror.c	regerrs.h
+ *	regex.h		regexec.c	regfree.c
+ *	regfronts.c	regguts.h
+ *
+ * Copyright (c) 1998 Henry Spencer.  All rights reserved.
+ *
+ * Development of this software was funded, in part, by Cray Research Inc.,
+ * UUNET Communications Services Inc., Sun Microsystems Inc., and Scriptics
+ * Corporation, none of whom are responsible for the results. The author
+ * thanks all of them.
+ *
+ * Redistribution and use in source and binary forms -- with or without
+ * modification -- are permitted for any purpose, provided that
+ * redistributions in source form retain this entire copyright notice and
+ * indicate the origin and nature of any modifications.
+ *
+ * I'd appreciate being given credit for this package in the documentation of
+ * software which uses it, but that is not a requirement.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+ * HENRY SPENCER BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * *** NOTE: this code has been altered slightly for use in Tcl: ***
+ * *** 1. Names have been changed, e.g. from re_comp to		 ***
+ * ***    TclRegComp, to avoid clashes with other		 ***
+ * ***    regexp implementations used by applications.		 ***
+ */
+
+/*
+ * Thread local storage used to maintain a per-thread cache of compiled
+ * regular expressions.
+ */
+
+#define NUM_REGEXPS 30
+
+typedef struct ThreadSpecificData {
+    int initialized;		/* Set to 1 when the module is initialized. */
+    char *patterns[NUM_REGEXPS];/* Strings corresponding to compiled regular
+				 * expression patterns. NULL means that this
+				 * slot isn't used. Malloc-ed. */
+    int patLengths[NUM_REGEXPS];/* Number of non-null characters in
+				 * corresponding entry in patterns. -1 means
+				 * entry isn't used. */
+    struct TclRegexp *regexps[NUM_REGEXPS];
+				/* Compiled forms of above strings. Also
+				 * malloc-ed, or NULL if not in use yet. */
+} ThreadSpecificData;
+
+static Tcl_ThreadDataKey dataKey;
+
+/*
+ * Declarations for functions used only in this file.
+ */
+
+static TclRegexp *	CompileRegexp(Tcl_Interp *interp, const char *pattern,
+			    int length, int flags);
+static void		DupRegexpInternalRep(Tcl_Obj *srcPtr,
+			    Tcl_Obj *copyPtr);
+static void		FinalizeRegexp(ClientData clientData);
+static void		FreeRegexp(TclRegexp *regexpPtr);
+static void		FreeRegexpInternalRep(Tcl_Obj *objPtr);
+static int		RegExpExecUniChar(Tcl_Interp *interp, Tcl_RegExp re,
+			    const Tcl_UniChar *uniString, int numChars,
+			    int nmatches, int flags);
+static int		SetRegexpFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr);
+
+/*
+ * The regular expression Tcl object type. This serves as a cache of the
+ * compiled form of the regular expression.
+ */
+
+const Tcl_ObjType tclRegexpType = {
+    "regexp",				/* name */
+    FreeRegexpInternalRep,		/* freeIntRepProc */
+    DupRegexpInternalRep,		/* dupIntRepProc */
+    NULL,				/* updateStringProc */
+    SetRegexpFromAny			/* setFromAnyProc */
+};
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_RegExpCompile --
+ *
+ *	Compile a regular expression into a form suitable for fast matching.
+ *	This function is DEPRECATED in favor of the object version of the
+ *	command.
+ *
+ * Results:
+ *	The return value is a pointer to the compiled form of string, suitable
+ *	for passing to Tcl_RegExpExec. This compiled form is only valid up
+ *	until the next call to this function, so don't keep these around for a
+ *	long time! If an error occurred while compiling the pattern, then NULL
+ *	is returned and an error message is left in the interp's result.
+ *
+ * Side effects:
+ *	Updates the cache of compiled regexps.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_RegExp
+Tcl_RegExpCompile(
+    Tcl_Interp *interp,		/* For use in error reporting and to access
+				 * the interp regexp cache. */
+    const char *pattern)	/* String for which to produce compiled
+				 * regular expression. */
+{
+    return (Tcl_RegExp) CompileRegexp(interp, pattern, (int) strlen(pattern),
+	    REG_ADVANCED);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_RegExpExec --
+ *
+ *	Execute the regular expression matcher using a compiled form of a
+ *	regular expression and save information about any match that is found.
+ *
+ * Results:
+ *	If an error occurs during the matching operation then -1 is returned
+ *	and the interp's result contains an error message. Otherwise the
+ *	return value is 1 if a matching range is found and 0 if there is no
+ *	matching range.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_RegExpExec(
+    Tcl_Interp *interp,		/* Interpreter to use for error reporting. */
+    Tcl_RegExp re,		/* Compiled regular expression; must have been
+				 * returned by previous call to
+				 * Tcl_GetRegExpFromObj. */
+    const char *text,		/* Text against which to match re. */
+    const char *start)		/* If text is part of a larger string, this
+				 * identifies beginning of larger string, so
+				 * that "^" won't match. */
+{
+    int flags, result, numChars;
+    TclRegexp *regexp = (TclRegexp *) re;
+    Tcl_DString ds;
+    const Tcl_UniChar *ustr;
+
+    /*
+     * If the starting point is offset from the beginning of the buffer, then
+     * we need to tell the regexp engine not to match "^".
+     */
+
+    if (text > start) {
+	flags = REG_NOTBOL;
+    } else {
+	flags = 0;
+    }
+
+    /*
+     * Remember the string for use by Tcl_RegExpRange().
+     */
+
+    regexp->string = text;
+    regexp->objPtr = NULL;
+
+    /*
+     * Convert the string to Unicode and perform the match.
+     */
+
+    Tcl_DStringInit(&ds);
+    ustr = Tcl_UtfToUniCharDString(text, -1, &ds);
+    numChars = Tcl_DStringLength(&ds) / sizeof(Tcl_UniChar);
+    result = RegExpExecUniChar(interp, re, ustr, numChars, -1 /* nmatches */,
+	    flags);
+    Tcl_DStringFree(&ds);
+
+    return result;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Tcl_RegExpRange --
+ *
+ *	Returns pointers describing the range of a regular expression match,
+ *	or one of the subranges within the match.
+ *
+ * Results:
+ *	The variables at *startPtr and *endPtr are modified to hold the
+ *	addresses of the endpoints of the range given by index. If the
+ *	specified range doesn't exist then NULLs are returned.
+ *
+ * Side effects:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+void
+Tcl_RegExpRange(
+    Tcl_RegExp re,		/* Compiled regular expression that has been
+				 * passed to Tcl_RegExpExec. */
+    int index,			/* 0 means give the range of the entire match,
+				 * > 0 means give the range of a matching
+				 * subrange. */
+    const char **startPtr,	/* Store address of first character in
+				 * (sub-)range here. */
+    const char **endPtr)	/* Store address of character just after last
+				 * in (sub-)range here. */
+{
+    TclRegexp *regexpPtr = (TclRegexp *) re;
+    const char *string;
+
+    if ((size_t) index > regexpPtr->re.re_nsub) {
+	*startPtr = *endPtr = NULL;
+    } else if (regexpPtr->matches[index].rm_so < 0) {
+	*startPtr = *endPtr = NULL;
+    } else {
+	if (regexpPtr->objPtr) {
+	    string = TclGetString(regexpPtr->objPtr);
+	} else {
+	    string = regexpPtr->string;
+	}
+	*startPtr = Tcl_UtfAtIndex(string, regexpPtr->matches[index].rm_so);
+	*endPtr = Tcl_UtfAtIndex(string, regexpPtr->matches[index].rm_eo);
+    }
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * RegExpExecUniChar --
+ *
+ *	Execute the regular expression matcher using a compiled form of a
+ *	regular expression and save information about any match that is found.
+ *
+ * Results:
+ *	If an error occurs during the matching operation then -1 is returned
+ *	and an error message is left in interp's result. Otherwise the return
+ *	value is 1 if a matching range was found or 0 if there was no matching
+ *	range.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+RegExpExecUniChar(
+    Tcl_Interp *interp,		/* Interpreter to use for error reporting. */
+    Tcl_RegExp re,		/* Compiled regular expression; returned by a
+				 * previous call to Tcl_GetRegExpFromObj */
+    const Tcl_UniChar *wString,	/* String against which to match re. */
+    int numChars,		/* Length of Tcl_UniChar string (must be
+				 * >=0). */
+    int nmatches,		/* How many subexpression matches (counting
+				 * the whole match as subexpression 0) are of
+				 * interest. -1 means "don't know". */
+    int flags)			/* Regular expression flags. */
+{
+    int status;
+    TclRegexp *regexpPtr = (TclRegexp *) re;
+    size_t last = regexpPtr->re.re_nsub + 1;
+    size_t nm = last;
+
+    if (nmatches >= 0 && (size_t) nmatches < nm) {
+	nm = (size_t) nmatches;
+    }
+
+    status = TclReExec(&regexpPtr->re, wString, (size_t) numChars,
+	    &regexpPtr->details, nm, regexpPtr->matches, flags);
+
+    /*
+     * Check for errors.
+     */
+
+    if (status != REG_OKAY) {
+	if (status == REG_NOMATCH) {
+	    return 0;
+	}
+	if (interp != NULL) {
+	    TclRegError(interp, "error while matching regular expression: ",
+		    status);
+	}
+	return -1;
+    }
+    return 1;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * TclRegExpRangeUniChar --
+ *
+ *	Returns pointers describing the range of a regular expression match,
+ *	or one of the subranges within the match, or the hypothetical range
+ *	represented by the rm_extend field of the rm_detail_t.
+ *
+ * Results:
+ *	The variables at *startPtr and *endPtr are modified to hold the
+ *	offsets of the endpoints of the range given by index. If the specified
+ *	range doesn't exist then -1s are supplied.
+ *
+ * Side effects:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+void
+TclRegExpRangeUniChar(
+    Tcl_RegExp re,		/* Compiled regular expression that has been
+				 * passed to Tcl_RegExpExec. */
+    int index,			/* 0 means give the range of the entire match,
+				 * > 0 means give the range of a matching
+				 * subrange, -1 means the range of the
+				 * rm_extend field. */
+    int *startPtr,		/* Store address of first character in
+				 * (sub-)range here. */
+    int *endPtr)		/* Store address of character just after last
+				 * in (sub-)range here. */
+{
+    TclRegexp *regexpPtr = (TclRegexp *) re;
+
+    if ((regexpPtr->flags&REG_EXPECT) && index == -1) {
+	*startPtr = regexpPtr->details.rm_extend.rm_so;
+	*endPtr = regexpPtr->details.rm_extend.rm_eo;
+    } else if ((size_t) index > regexpPtr->re.re_nsub) {
+	*startPtr = -1;
+	*endPtr = -1;
+    } else {
+	*startPtr = regexpPtr->matches[index].rm_so;
+	*endPtr = regexpPtr->matches[index].rm_eo;
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_RegExpMatch --
+ *
+ *	See if a string matches a regular expression.
+ *
+ * Results:
+ *	If an error occurs during the matching operation then -1 is returned
+ *	and the interp's result contains an error message. Otherwise the
+ *	return value is 1 if "text" matches "pattern" and 0 otherwise.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_RegExpMatch(
+    Tcl_Interp *interp,		/* Used for error reporting. May be NULL. */
+    const char *text,		/* Text to search for pattern matches. */
+    const char *pattern)	/* Regular expression to match against text. */
+{
+    Tcl_RegExp re = Tcl_RegExpCompile(interp, pattern);
+
+    if (re == NULL) {
+	return -1;
+    }
+    return Tcl_RegExpExec(interp, re, text, text);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_RegExpExecObj --
+ *
+ *	Execute a precompiled regexp against the given object.
+ *
+ * Results:
+ *	If an error occurs during the matching operation then -1 is returned
+ *	and the interp's result contains an error message. Otherwise the
+ *	return value is 1 if "string" matches "pattern" and 0 otherwise.
+ *
+ * Side effects:
+ *	Converts the object to a Unicode object.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_RegExpExecObj(
+    Tcl_Interp *interp,		/* Interpreter to use for error reporting. */
+    Tcl_RegExp re,		/* Compiled regular expression; must have been
+				 * returned by previous call to
+				 * Tcl_GetRegExpFromObj. */
+    Tcl_Obj *textObj,		/* Text against which to match re. */
+    int offset,			/* Character index that marks where matching
+				 * should begin. */
+    int nmatches,		/* How many subexpression matches (counting
+				 * the whole match as subexpression 0) are of
+				 * interest. -1 means all of them. */
+    int flags)			/* Regular expression execution flags. */
+{
+    TclRegexp *regexpPtr = (TclRegexp *) re;
+    Tcl_UniChar *udata;
+    int length;
+    int reflags = regexpPtr->flags;
+#define TCL_REG_GLOBOK_FLAGS \
+	(TCL_REG_ADVANCED | TCL_REG_NOSUB | TCL_REG_NOCASE)
+
+    /*
+     * Take advantage of the equivalent glob pattern, if one exists.
+     * This is possible based only on the right mix of incoming flags (0)
+     * and regexp compile flags.
+     */
+    if ((offset == 0) && (nmatches == 0) && (flags == 0)
+	    && !(reflags & ~TCL_REG_GLOBOK_FLAGS)
+	    && (regexpPtr->globObjPtr != NULL)) {
+	int nocase = (reflags & TCL_REG_NOCASE) ? TCL_MATCH_NOCASE : 0;
+
+	/*
+	 * Pass to TclStringMatchObj for obj-specific handling.
+	 * XXX: Currently doesn't take advantage of exact-ness that
+	 * XXX: TclReToGlob tells us about
+	 */
+
+	return TclStringMatchObj(textObj, regexpPtr->globObjPtr, nocase);
+    }
+
+    /*
+     * Save the target object so we can extract strings from it later.
+     */
+
+    regexpPtr->string = NULL;
+    regexpPtr->objPtr = textObj;
+
+    udata = Tcl_GetUnicodeFromObj(textObj, &length);
+
+    if (offset > length) {
+	offset = length;
+    }
+    udata += offset;
+    length -= offset;
+
+    return RegExpExecUniChar(interp, re, udata, length, nmatches, flags);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_RegExpMatchObj --
+ *
+ *	See if an object matches a regular expression.
+ *
+ * Results:
+ *	If an error occurs during the matching operation then -1 is returned
+ *	and the interp's result contains an error message. Otherwise the
+ *	return value is 1 if "text" matches "pattern" and 0 otherwise.
+ *
+ * Side effects:
+ *	Changes the internal rep of the pattern and string objects.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_RegExpMatchObj(
+    Tcl_Interp *interp,		/* Used for error reporting. May be NULL. */
+    Tcl_Obj *textObj,		/* Object containing the String to search. */
+    Tcl_Obj *patternObj)	/* Regular expression to match against
+				 * string. */
+{
+    Tcl_RegExp re;
+
+    re = Tcl_GetRegExpFromObj(interp, patternObj,
+	    TCL_REG_ADVANCED | TCL_REG_NOSUB);
+    if (re == NULL) {
+	return -1;
+    }
+    return Tcl_RegExpExecObj(interp, re, textObj, 0 /* offset */,
+	    0 /* nmatches */, 0 /* flags */);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_RegExpGetInfo --
+ *
+ *	Retrieve information about the current match.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_RegExpGetInfo(
+    Tcl_RegExp regexp,		/* Pattern from which to get subexpressions. */
+    Tcl_RegExpInfo *infoPtr)	/* Match information is stored here. */
+{
+    TclRegexp *regexpPtr = (TclRegexp *) regexp;
+
+    infoPtr->nsubs = regexpPtr->re.re_nsub;
+    infoPtr->matches = (Tcl_RegExpIndices *) regexpPtr->matches;
+    infoPtr->extendStart = regexpPtr->details.rm_extend.rm_so;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_GetRegExpFromObj --
+ *
+ *	Compile a regular expression into a form suitable for fast matching.
+ *	This function caches the result in a Tcl_Obj.
+ *
+ * Results:
+ *	The return value is a pointer to the compiled form of string, suitable
+ *	for passing to Tcl_RegExpExec. If an error occurred while compiling
+ *	the pattern, then NULL is returned and an error message is left in the
+ *	interp's result.
+ *
+ * Side effects:
+ *	Updates the native rep of the Tcl_Obj.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_RegExp
+Tcl_GetRegExpFromObj(
+    Tcl_Interp *interp,		/* For use in error reporting, and to access
+				 * the interp regexp cache. */
+    Tcl_Obj *objPtr,		/* Object whose string rep contains regular
+				 * expression pattern. Internal rep will be
+				 * changed to compiled form of this regular
+				 * expression. */
+    int flags)			/* Regular expression compilation flags. */
+{
+    int length;
+    TclRegexp *regexpPtr;
+    const char *pattern;
+
+    /*
+     * This is OK because we only actually interpret this value properly as a
+     * TclRegexp* when the type is tclRegexpType.
+     */
+
+    regexpPtr = objPtr->internalRep.twoPtrValue.ptr1;
+
+    if ((objPtr->typePtr != &tclRegexpType) || (regexpPtr->flags != flags)) {
+	pattern = TclGetStringFromObj(objPtr, &length);
+
+	regexpPtr = CompileRegexp(interp, pattern, length, flags);
+	if (regexpPtr == NULL) {
+	    return NULL;
+	}
+
+	/*
+	 * Add a reference to the regexp so it will persist even if it is
+	 * pushed out of the current thread's regexp cache. This reference
+	 * will be removed when the object's internal rep is freed.
+	 */
+
+	regexpPtr->refCount++;
+
+	/*
+	 * Free the old representation and set our type.
+	 */
+
+	TclFreeIntRep(objPtr);
+	objPtr->internalRep.twoPtrValue.ptr1 = regexpPtr;
+	objPtr->typePtr = &tclRegexpType;
+    }
+    return (Tcl_RegExp) regexpPtr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclRegAbout --
+ *
+ *	Return information about a compiled regular expression.
+ *
+ * Results:
+ *	The return value is -1 for failure, 0 for success, although at the
+ *	moment there's nothing that could fail. On success, a list is left in
+ *	the interp's result: first element is the subexpression count, second
+ *	is a list of re_info bit names.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclRegAbout(
+    Tcl_Interp *interp,		/* For use in variable assignment. */
+    Tcl_RegExp re)		/* The compiled regular expression. */
+{
+    TclRegexp *regexpPtr = (TclRegexp *) re;
+    struct infoname {
+	int bit;
+	const char *text;
+    };
+    static const struct infoname infonames[] = {
+	{REG_UBACKREF,		"REG_UBACKREF"},
+	{REG_ULOOKAHEAD,	"REG_ULOOKAHEAD"},
+	{REG_UBOUNDS,		"REG_UBOUNDS"},
+	{REG_UBRACES,		"REG_UBRACES"},
+	{REG_UBSALNUM,		"REG_UBSALNUM"},
+	{REG_UPBOTCH,		"REG_UPBOTCH"},
+	{REG_UBBS,		"REG_UBBS"},
+	{REG_UNONPOSIX,		"REG_UNONPOSIX"},
+	{REG_UUNSPEC,		"REG_UUNSPEC"},
+	{REG_UUNPORT,		"REG_UUNPORT"},
+	{REG_ULOCALE,		"REG_ULOCALE"},
+	{REG_UEMPTYMATCH,	"REG_UEMPTYMATCH"},
+	{REG_UIMPOSSIBLE,	"REG_UIMPOSSIBLE"},
+	{REG_USHORTEST,		"REG_USHORTEST"},
+	{0,			NULL}
+    };
+    const struct infoname *inf;
+    Tcl_Obj *infoObj, *resultObj;
+
+    /*
+     * The reset here guarantees that the interpreter result is empty and
+     * unshared. This means that we can use Tcl_ListObjAppendElement on the
+     * result object quite safely.
+     */
+
+    Tcl_ResetResult(interp);
+
+    /*
+     * Assume that there will never be more than INT_MAX subexpressions. This
+     * is a pretty reasonable assumption; the RE engine doesn't scale _that_
+     * well and Tcl has other limits that constrain things as well...
+     */
+
+    resultObj = Tcl_NewObj();
+    Tcl_ListObjAppendElement(NULL, resultObj,
+	    Tcl_NewIntObj((int) regexpPtr->re.re_nsub));
+
+    /*
+     * Now append a list of all the bit-flags set for the RE.
+     */
+
+    TclNewObj(infoObj);
+    for (inf=infonames ; inf->bit != 0 ; inf++) {
+	if (regexpPtr->re.re_info & inf->bit) {
+	    Tcl_ListObjAppendElement(NULL, infoObj,
+		    Tcl_NewStringObj(inf->text, -1));
+	}
+    }
+    Tcl_ListObjAppendElement(NULL, resultObj, infoObj);
+    Tcl_SetObjResult(interp, resultObj);
+
+    return 0;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclRegError --
+ *
+ *	Generate an error message based on the regexp status code.
+ *
+ * Results:
+ *	Places an error in the interpreter.
+ *
+ * Side effects:
+ *	Sets errorCode as well.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclRegError(
+    Tcl_Interp *interp,		/* Interpreter for error reporting. */
+    const char *msg,		/* Message to prepend to error. */
+    int status)			/* Status code to report. */
+{
+    char buf[100];		/* ample in practice */
+    char cbuf[TCL_INTEGER_SPACE];
+    size_t n;
+    const char *p;
+
+    Tcl_ResetResult(interp);
+    n = TclReError(status, NULL, buf, sizeof(buf));
+    p = (n > sizeof(buf)) ? "..." : "";
+    Tcl_SetObjResult(interp, Tcl_ObjPrintf("%s%s%s", msg, buf, p));
+
+    sprintf(cbuf, "%d", status);
+    (void) TclReError(REG_ITOA, NULL, cbuf, sizeof(cbuf));
+    Tcl_SetErrorCode(interp, "REGEXP", cbuf, buf, NULL);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * FreeRegexpInternalRep --
+ *
+ *	Deallocate the storage associated with a regexp object's internal
+ *	representation.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Frees the compiled regular expression.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+FreeRegexpInternalRep(
+    Tcl_Obj *objPtr)		/* Regexp object with internal rep to free. */
+{
+    TclRegexp *regexpRepPtr = objPtr->internalRep.twoPtrValue.ptr1;
+
+    /*
+     * If this is the last reference to the regexp, free it.
+     */
+
+    if (regexpRepPtr->refCount-- <= 1) {
+	FreeRegexp(regexpRepPtr);
+    }
+    objPtr->typePtr = NULL;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * DupRegexpInternalRep --
+ *
+ *	We copy the reference to the compiled regexp and bump its reference
+ *	count.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Increments the reference count of the regexp.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+DupRegexpInternalRep(
+    Tcl_Obj *srcPtr,		/* Object with internal rep to copy. */
+    Tcl_Obj *copyPtr)		/* Object with internal rep to set. */
+{
+    TclRegexp *regexpPtr = srcPtr->internalRep.twoPtrValue.ptr1;
+
+    regexpPtr->refCount++;
+    copyPtr->internalRep.twoPtrValue.ptr1 = srcPtr->internalRep.twoPtrValue.ptr1;
+    copyPtr->typePtr = &tclRegexpType;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * SetRegexpFromAny --
+ *
+ *	Attempt to generate a compiled regular expression for the Tcl object
+ *	"objPtr".
+ *
+ * Results:
+ *	The return value is TCL_OK or TCL_ERROR. If an error occurs during
+ *	conversion, an error message is left in the interpreter's result
+ *	unless "interp" is NULL.
+ *
+ * Side effects:
+ *	If no error occurs, a regular expression is stored as "objPtr"s
+ *	internal representation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+SetRegexpFromAny(
+    Tcl_Interp *interp,		/* Used for error reporting if not NULL. */
+    Tcl_Obj *objPtr)		/* The object to convert. */
+{
+    if (Tcl_GetRegExpFromObj(interp, objPtr, REG_ADVANCED) == NULL) {
+	return TCL_ERROR;
+    }
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * CompileRegexp --
+ *
+ *	Attempt to compile the given regexp pattern. If the compiled regular
+ *	expression can be found in the per-thread cache, it will be used
+ *	instead of compiling a new copy.
+ *
+ * Results:
+ *	The return value is a pointer to a newly allocated TclRegexp that
+ *	represents the compiled pattern, or NULL if the pattern could not be
+ *	compiled. If NULL is returned, an error message is left in the
+ *	interp's result.
+ *
+ * Side effects:
+ *	The thread-local regexp cache is updated and a new TclRegexp may be
+ *	allocated.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static TclRegexp *
+CompileRegexp(
+    Tcl_Interp *interp,		/* Used for error reporting if not NULL. */
+    const char *string,		/* The regexp to compile (UTF-8). */
+    int length,			/* The length of the string in bytes. */
+    int flags)			/* Compilation flags. */
+{
+    TclRegexp *regexpPtr;
+    const Tcl_UniChar *uniString;
+    int numChars, status, i, exact;
+    Tcl_DString stringBuf;
+    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+
+    if (!tsdPtr->initialized) {
+	tsdPtr->initialized = 1;
+	Tcl_CreateThreadExitHandler(FinalizeRegexp, NULL);
+    }
+
+    /*
+     * This routine maintains a second-level regular expression cache in
+     * addition to the per-object regexp cache. The per-thread cache is needed
+     * to handle the case where for various reasons the object is lost between
+     * invocations of the regexp command, but the literal pattern is the same.
+     */
+
+    /*
+     * Check the per-thread compiled regexp cache. We can only reuse a regexp
+     * if it has the same pattern and the same flags.
+     */
+
+    for (i = 0; (i < NUM_REGEXPS) && (tsdPtr->patterns[i] != NULL); i++) {
+	if ((length == tsdPtr->patLengths[i])
+		&& (tsdPtr->regexps[i]->flags == flags)
+		&& (strcmp(string, tsdPtr->patterns[i]) == 0)) {
+	    /*
+	     * Move the matched pattern to the first slot in the cache and
+	     * shift the other patterns down one position.
+	     */
+
+	    if (i != 0) {
+		int j;
+		char *cachedString;
+
+		cachedString = tsdPtr->patterns[i];
+		regexpPtr = tsdPtr->regexps[i];
+		for (j = i-1; j >= 0; j--) {
+		    tsdPtr->patterns[j+1] = tsdPtr->patterns[j];
+		    tsdPtr->patLengths[j+1] = tsdPtr->patLengths[j];
+		    tsdPtr->regexps[j+1] = tsdPtr->regexps[j];
+		}
+		tsdPtr->patterns[0] = cachedString;
+		tsdPtr->patLengths[0] = length;
+		tsdPtr->regexps[0] = regexpPtr;
+	    }
+	    return tsdPtr->regexps[0];
+	}
+    }
+
+    /*
+     * This is a new expression, so compile it and add it to the cache.
+     */
+
+    regexpPtr = ckalloc(sizeof(TclRegexp));
+    regexpPtr->objPtr = NULL;
+    regexpPtr->string = NULL;
+    regexpPtr->details.rm_extend.rm_so = -1;
+    regexpPtr->details.rm_extend.rm_eo = -1;
+
+    /*
+     * Get the up-to-date string representation and map to unicode.
+     */
+
+    Tcl_DStringInit(&stringBuf);
+    uniString = Tcl_UtfToUniCharDString(string, length, &stringBuf);
+    numChars = Tcl_DStringLength(&stringBuf) / sizeof(Tcl_UniChar);
+
+    /*
+     * Compile the string and check for errors.
+     */
+
+    regexpPtr->flags = flags;
+    status = TclReComp(&regexpPtr->re, uniString, (size_t) numChars, flags);
+    Tcl_DStringFree(&stringBuf);
+
+    if (status != REG_OKAY) {
+	/*
+	 * Clean up and report errors in the interpreter, if possible.
+	 */
+
+	ckfree(regexpPtr);
+	if (interp) {
+	    TclRegError(interp,
+		    "couldn't compile regular expression pattern: ", status);
+	}
+	return NULL;
+    }
+
+    /*
+     * Convert RE to a glob pattern equivalent, if any, and cache it.  If this
+     * is not possible, then globObjPtr will be NULL.  This is used by
+     * Tcl_RegExpExecObj to optionally do a fast match (avoids RE engine).
+     */
+
+    if (TclReToGlob(NULL, string, length, &stringBuf, &exact,
+	    NULL) == TCL_OK) {
+	regexpPtr->globObjPtr = TclDStringToObj(&stringBuf);
+	Tcl_IncrRefCount(regexpPtr->globObjPtr);
+    } else {
+	regexpPtr->globObjPtr = NULL;
+    }
+
+    /*
+     * Allocate enough space for all of the subexpressions, plus one extra for
+     * the entire pattern.
+     */
+
+    regexpPtr->matches =
+	    ckalloc(sizeof(regmatch_t) * (regexpPtr->re.re_nsub + 1));
+
+    /*
+     * Initialize the refcount to one initially, since it is in the cache.
+     */
+
+    regexpPtr->refCount = 1;
+
+    /*
+     * Free the last regexp, if necessary, and make room at the head of the
+     * list for the new regexp.
+     */
+
+    if (tsdPtr->patterns[NUM_REGEXPS-1] != NULL) {
+	TclRegexp *oldRegexpPtr = tsdPtr->regexps[NUM_REGEXPS-1];
+
+	if (oldRegexpPtr->refCount-- <= 1) {
+	    FreeRegexp(oldRegexpPtr);
+	}
+	ckfree(tsdPtr->patterns[NUM_REGEXPS-1]);
+    }
+    for (i = NUM_REGEXPS - 2; i >= 0; i--) {
+	tsdPtr->patterns[i+1] = tsdPtr->patterns[i];
+	tsdPtr->patLengths[i+1] = tsdPtr->patLengths[i];
+	tsdPtr->regexps[i+1] = tsdPtr->regexps[i];
+    }
+    tsdPtr->patterns[0] = ckalloc(length + 1);
+    memcpy(tsdPtr->patterns[0], string, (unsigned) length + 1);
+    tsdPtr->patLengths[0] = length;
+    tsdPtr->regexps[0] = regexpPtr;
+
+    return regexpPtr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * FreeRegexp --
+ *
+ *	Release the storage associated with a TclRegexp.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+FreeRegexp(
+    TclRegexp *regexpPtr)	/* Compiled regular expression to free. */
+{
+    TclReFree(&regexpPtr->re);
+    if (regexpPtr->globObjPtr) {
+	TclDecrRefCount(regexpPtr->globObjPtr);
+    }
+    if (regexpPtr->matches) {
+	ckfree(regexpPtr->matches);
+    }
+    ckfree(regexpPtr);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * FinalizeRegexp --
+ *
+ *	Release the storage associated with the per-thread regexp cache.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+FinalizeRegexp(
+    ClientData clientData)	/* Not used. */
+{
+    int i;
+    TclRegexp *regexpPtr;
+    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+
+    for (i = 0; (i < NUM_REGEXPS) && (tsdPtr->patterns[i] != NULL); i++) {
+	regexpPtr = tsdPtr->regexps[i];
+	if (regexpPtr->refCount-- <= 1) {
+	    FreeRegexp(regexpPtr);
+	}
+	ckfree(tsdPtr->patterns[i]);
+	tsdPtr->patterns[i] = NULL;
+    }
+
+    /*
+     * We may find ourselves reinitialized if another finalization routine
+     * invokes regexps.
+     */
+
+    tsdPtr->initialized = 0;
+}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tclRegexp.h b/generic/tclRegexp.h
new file mode 100644
index 0000000..3b2433e
--- /dev/null
+++ b/generic/tclRegexp.h
@@ -0,0 +1,52 @@
+/*
+ * tclRegexp.h --
+ *
+ *	This file contains definitions used internally by Henry Spencer's
+ *	regular expression code.
+ *
+ * Copyright (c) 1998 by Sun Microsystems, Inc.
+ * Copyright (c) 1998-1999 by Scriptics Corporation.
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#ifndef _TCLREGEXP
+#define _TCLREGEXP
+
+#include "regex.h"
+
+/*
+ * The TclRegexp structure encapsulates a compiled regex_t, the flags that
+ * were used to compile it, and an array of pointers that are used to indicate
+ * subexpressions after a call to Tcl_RegExpExec. Note that the string and
+ * objPtr are mutually exclusive. These values are needed by Tcl_RegExpRange
+ * in order to return pointers into the original string.
+ */
+
+typedef struct TclRegexp {
+    int flags;			/* Regexp compile flags. */
+    regex_t re;			/* Compiled re, includes number of
+				 * subexpressions. */
+    const char *string;		/* Last string passed to Tcl_RegExpExec. */
+    Tcl_Obj *objPtr;		/* Last object passed to Tcl_RegExpExecObj. */
+    Tcl_Obj *globObjPtr;	/* Glob pattern rep of RE or NULL if none. */
+    regmatch_t *matches;	/* Array of indices into the Tcl_UniChar
+				 * representation of the last string matched
+				 * with this regexp to indicate the location
+				 * of subexpressions. */
+    rm_detail_t details;	/* Detailed information on match (currently
+				 * used only for REG_EXPECT). */
+    int refCount;		/* Count of number of references to this
+				 * compiled regexp. */
+} TclRegexp;
+
+#endif /* _TCLREGEXP */
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tclResolve.c b/generic/tclResolve.c
new file mode 100644
index 0000000..974737e
--- /dev/null
+++ b/generic/tclResolve.c
@@ -0,0 +1,424 @@
+/*
+ * tclResolve.c --
+ *
+ *	Contains hooks for customized command/variable name resolution
+ *	schemes. These hooks allow extensions like [incr Tcl] to add their own
+ *	name resolution rules to the Tcl language. Rules can be applied to a
+ *	particular namespace, to the interpreter as a whole, or both.
+ *
+ * Copyright (c) 1998 Lucent Technologies, Inc.
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#include "tclInt.h"
+
+/*
+ * Declarations for functions local to this file:
+ */
+
+static void		BumpCmdRefEpochs(Namespace *nsPtr);
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_AddInterpResolvers --
+ *
+ *	Adds a set of command/variable resolution functions to an interpreter.
+ *	These functions are consulted when commands are resolved in
+ *	Tcl_FindCommand, and when variables are resolved in TclLookupVar and
+ *	LookupCompiledLocal. Each namespace may also have its own set of
+ *	resolution functions which take precedence over those for the
+ *	interpreter.
+ *
+ *	When a name is resolved, it is handled as follows. First, the name is
+ *	passed to the resolution functions for the namespace. If not resolved,
+ *	the name is passed to each of the resolution functions added to the
+ *	interpreter. Finally, if still not resolved, the name is handled using
+ *	the default Tcl rules for name resolution.
+ *
+ * Results:
+ *	Returns pointers to the current name resolution functions in the
+ *	cmdProcPtr, varProcPtr and compiledVarProcPtr arguments.
+ *
+ * Side effects:
+ *	If a compiledVarProc is specified, this function bumps the
+ *	compileEpoch for the interpreter, forcing all code to be recompiled.
+ *	If a cmdProc is specified, this function bumps the cmdRefEpoch in all
+ *	namespaces, forcing commands to be resolved again using the new rules.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_AddInterpResolvers(
+    Tcl_Interp *interp,		/* Interpreter whose name resolution rules are
+				 * being modified. */
+    const char *name,		/* Name of this resolution scheme. */
+    Tcl_ResolveCmdProc *cmdProc,/* New function for command resolution. */
+    Tcl_ResolveVarProc *varProc,/* Function for variable resolution at
+				 * runtime. */
+    Tcl_ResolveCompiledVarProc *compiledVarProc)
+				/* Function for variable resolution at compile
+				 * time. */
+{
+    Interp *iPtr = (Interp *) interp;
+    ResolverScheme *resPtr;
+    unsigned len;
+
+    /*
+     * Since we're adding a new name resolution scheme, we must force all code
+     * to be recompiled to use the new scheme. If there are new compiled
+     * variable resolution rules, bump the compiler epoch to invalidate
+     * compiled code. If there are new command resolution rules, bump the
+     * cmdRefEpoch in all namespaces.
+     */
+
+    if (compiledVarProc) {
+	iPtr->compileEpoch++;
+    }
+    if (cmdProc) {
+	BumpCmdRefEpochs(iPtr->globalNsPtr);
+    }
+
+    /*
+     * Look for an existing scheme with the given name. If found, then replace
+     * its rules.
+     */
+
+    for (resPtr=iPtr->resolverPtr ; resPtr!=NULL ; resPtr=resPtr->nextPtr) {
+	if (*name == *resPtr->name && strcmp(name, resPtr->name) == 0) {
+	    resPtr->cmdResProc = cmdProc;
+	    resPtr->varResProc = varProc;
+	    resPtr->compiledVarResProc = compiledVarProc;
+	    return;
+	}
+    }
+
+    /*
+     * Otherwise, this is a new scheme. Add it to the FRONT of the linked
+     * list, so that it overrides existing schemes.
+     */
+
+    resPtr = ckalloc(sizeof(ResolverScheme));
+    len = strlen(name) + 1;
+    resPtr->name = ckalloc(len);
+    memcpy(resPtr->name, name, len);
+    resPtr->cmdResProc = cmdProc;
+    resPtr->varResProc = varProc;
+    resPtr->compiledVarResProc = compiledVarProc;
+    resPtr->nextPtr = iPtr->resolverPtr;
+    iPtr->resolverPtr = resPtr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_GetInterpResolvers --
+ *
+ *	Looks for a set of command/variable resolution functions with the
+ *	given name in an interpreter. These functions are registered by
+ *	calling Tcl_AddInterpResolvers.
+ *
+ * Results:
+ *	If the name is recognized, this function returns non-zero, along with
+ *	pointers to the name resolution functions in the Tcl_ResolverInfo
+ *	structure. If the name is not recognized, this function returns zero.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_GetInterpResolvers(
+    Tcl_Interp *interp,		/* Interpreter whose name resolution rules are
+				 * being queried. */
+    const char *name,		/* Look for a scheme with this name. */
+    Tcl_ResolverInfo *resInfoPtr)
+				/* Returns pointers to the functions, if
+				 * found */
+{
+    Interp *iPtr = (Interp *) interp;
+    ResolverScheme *resPtr;
+
+    /*
+     * Look for an existing scheme with the given name. If found, then return
+     * pointers to its functions.
+     */
+
+    for (resPtr=iPtr->resolverPtr ; resPtr!=NULL ; resPtr=resPtr->nextPtr) {
+	if (*name == *resPtr->name && strcmp(name, resPtr->name) == 0) {
+	    resInfoPtr->cmdResProc = resPtr->cmdResProc;
+	    resInfoPtr->varResProc = resPtr->varResProc;
+	    resInfoPtr->compiledVarResProc = resPtr->compiledVarResProc;
+	    return 1;
+	}
+    }
+
+    return 0;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_RemoveInterpResolvers --
+ *
+ *	Removes a set of command/variable resolution functions previously
+ *	added by Tcl_AddInterpResolvers. The next time a command/variable name
+ *	is resolved, these functions won't be consulted.
+ *
+ * Results:
+ *	Returns non-zero if the name was recognized and the resolution scheme
+ *	was deleted. Returns zero otherwise.
+ *
+ * Side effects:
+ *	If a scheme with a compiledVarProc was deleted, this function bumps
+ *	the compileEpoch for the interpreter, forcing all code to be
+ *	recompiled. If a scheme with a cmdProc was deleted, this function
+ *	bumps the cmdRefEpoch in all namespaces, forcing commands to be
+ *	resolved again using the new rules.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_RemoveInterpResolvers(
+    Tcl_Interp *interp,		/* Interpreter whose name resolution rules are
+				 * being modified. */
+    const char *name)		/* Name of the scheme to be removed. */
+{
+    Interp *iPtr = (Interp *) interp;
+    ResolverScheme **prevPtrPtr, *resPtr;
+
+    /*
+     * Look for an existing scheme with the given name.
+     */
+
+    prevPtrPtr = &iPtr->resolverPtr;
+    for (resPtr=iPtr->resolverPtr ; resPtr!=NULL ; resPtr=resPtr->nextPtr) {
+	if (*name == *resPtr->name && strcmp(name, resPtr->name) == 0) {
+	    break;
+	}
+	prevPtrPtr = &resPtr->nextPtr;
+    }
+
+    /*
+     * If we found the scheme, delete it.
+     */
+
+    if (resPtr) {
+	/*
+	 * If we're deleting a scheme with compiled variable resolution rules,
+	 * bump the compiler epoch to invalidate compiled code. If we're
+	 * deleting a scheme with command resolution rules, bump the
+	 * cmdRefEpoch in all namespaces.
+	 */
+
+	if (resPtr->compiledVarResProc) {
+	    iPtr->compileEpoch++;
+	}
+	if (resPtr->cmdResProc) {
+	    BumpCmdRefEpochs(iPtr->globalNsPtr);
+	}
+
+	*prevPtrPtr = resPtr->nextPtr;
+	ckfree(resPtr->name);
+	ckfree(resPtr);
+
+	return 1;
+    }
+    return 0;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * BumpCmdRefEpochs --
+ *
+ *	This function is used to bump the cmdRefEpoch counters in the
+ *	specified namespace and all of its child namespaces. It is used
+ *	whenever name resolution schemes are added/removed from an
+ *	interpreter, to invalidate all command references.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Bumps the cmdRefEpoch in the specified namespace and its children,
+ *	recursively.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+BumpCmdRefEpochs(
+    Namespace *nsPtr)		/* Namespace being modified. */
+{
+    Tcl_HashEntry *entry;
+    Tcl_HashSearch search;
+
+    nsPtr->cmdRefEpoch++;
+
+#ifndef BREAK_NAMESPACE_COMPAT
+    for (entry = Tcl_FirstHashEntry(&nsPtr->childTable, &search);
+	    entry != NULL; entry = Tcl_NextHashEntry(&search)) {
+	Namespace *childNsPtr = Tcl_GetHashValue(entry);
+
+	BumpCmdRefEpochs(childNsPtr);
+    }
+#else
+    if (nsPtr->childTablePtr != NULL) {
+	for (entry = Tcl_FirstHashEntry(nsPtr->childTablePtr, &search);
+		entry != NULL; entry = Tcl_NextHashEntry(&search)) {
+	    Namespace *childNsPtr = Tcl_GetHashValue(entry);
+
+	    BumpCmdRefEpochs(childNsPtr);
+	}
+    }
+#endif
+    TclInvalidateNsPath(nsPtr);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_SetNamespaceResolvers --
+ *
+ *	Sets the command/variable resolution functions for a namespace,
+ *	thereby changing the way that command/variable names are interpreted.
+ *	This allows extension writers to support different name resolution
+ *	schemes, such as those for object-oriented packages.
+ *
+ *	Command resolution is handled by a function of the following type:
+ *
+ *	  typedef int (Tcl_ResolveCmdProc)(Tcl_Interp *interp,
+ *		  const char *name, Tcl_Namespace *context,
+ *		  int flags, Tcl_Command *rPtr);
+ *
+ *	Whenever a command is executed or Tcl_FindCommand is invoked within
+ *	the namespace, this function is called to resolve the command name. If
+ *	this function is able to resolve the name, it should return the status
+ *	code TCL_OK, along with the corresponding Tcl_Command in the rPtr
+ *	argument. Otherwise, the function can return TCL_CONTINUE, and the
+ *	command will be treated under the usual name resolution rules. Or, it
+ *	can return TCL_ERROR, and the command will be considered invalid.
+ *
+ *	Variable resolution is handled by two functions. The first is called
+ *	whenever a variable needs to be resolved at compile time:
+ *
+ *	  typedef int (Tcl_ResolveCompiledVarProc)(Tcl_Interp *interp,
+ *		  const char *name, Tcl_Namespace *context,
+ *		  Tcl_ResolvedVarInfo *rPtr);
+ *
+ *	If this function is able to resolve the name, it should return the
+ *	status code TCL_OK, along with variable resolution info in the rPtr
+ *	argument; this info will be used to set up compiled locals in the call
+ *	frame at runtime. The function may also return TCL_CONTINUE, and the
+ *	variable will be treated under the usual name resolution rules. Or, it
+ *	can return TCL_ERROR, and the variable will be considered invalid.
+ *
+ *	Another function is used whenever a variable needs to be resolved at
+ *	runtime but it is not recognized as a compiled local. (For example,
+ *	the variable may be requested via Tcl_FindNamespaceVar.) This function
+ *	has the following type:
+ *
+ *	  typedef int (Tcl_ResolveVarProc)(Tcl_Interp *interp,
+ *		  const char *name, Tcl_Namespace *context,
+ *		  int flags, Tcl_Var *rPtr);
+ *
+ *	This function is quite similar to the compile-time version. It returns
+ *	the same status codes, but if variable resolution succeeds, this
+ *	function returns a Tcl_Var directly via the rPtr argument.
+ *
+ * Results:
+ *	Nothing.
+ *
+ * Side effects:
+ *	Bumps the command epoch counter for the namespace, invalidating all
+ *	command references in that namespace. Also bumps the resolver epoch
+ *	counter for the namespace, forcing all code in the namespace to be
+ *	recompiled.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_SetNamespaceResolvers(
+    Tcl_Namespace *namespacePtr,/* Namespace whose resolution rules are being
+				 * modified. */
+    Tcl_ResolveCmdProc *cmdProc,/* Function for command resolution */
+    Tcl_ResolveVarProc *varProc,/* Function for variable resolution at
+				 * run-time */
+    Tcl_ResolveCompiledVarProc *compiledVarProc)
+				/* Function for variable resolution at compile
+				 * time. */
+{
+    Namespace *nsPtr = (Namespace *) namespacePtr;
+
+    /*
+     * Plug in the new command resolver, and bump the epoch counters so that
+     * all code will have to be recompiled and all commands will have to be
+     * resolved again using the new policy.
+     */
+
+    nsPtr->cmdResProc = cmdProc;
+    nsPtr->varResProc = varProc;
+    nsPtr->compiledVarResProc = compiledVarProc;
+
+    nsPtr->cmdRefEpoch++;
+    nsPtr->resolverEpoch++;
+    TclInvalidateNsPath(nsPtr);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_GetNamespaceResolvers --
+ *
+ *	Returns the current command/variable resolution functions for a
+ *	namespace. By default, these functions are NULL. New functions can be
+ *	installed by calling Tcl_SetNamespaceResolvers, to provide new name
+ *	resolution rules.
+ *
+ * Results:
+ *	Returns non-zero if any name resolution functions have been assigned
+ *	to this namespace; also returns pointers to the functions in the
+ *	Tcl_ResolverInfo structure. Returns zero otherwise.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_GetNamespaceResolvers(
+    Tcl_Namespace *namespacePtr,/* Namespace whose resolution rules are being
+				 * modified. */
+    Tcl_ResolverInfo *resInfoPtr)
+				/* Returns: pointers for all name resolution
+				 * functions assigned to this namespace. */
+{
+    Namespace *nsPtr = (Namespace *) namespacePtr;
+
+    resInfoPtr->cmdResProc = nsPtr->cmdResProc;
+    resInfoPtr->varResProc = nsPtr->varResProc;
+    resInfoPtr->compiledVarResProc = nsPtr->compiledVarResProc;
+
+    if (nsPtr->cmdResProc != NULL || nsPtr->varResProc != NULL ||
+	    nsPtr->compiledVarResProc != NULL) {
+	return 1;
+    }
+    return 0;
+}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tclResult.c b/generic/tclResult.c
new file mode 100644
index 0000000..9d0714c
--- /dev/null
+++ b/generic/tclResult.c
@@ -0,0 +1,1755 @@
+/*
+ * tclResult.c --
+ *
+ *	This file contains code to manage the interpreter result.
+ *
+ * Copyright (c) 1997 by Sun Microsystems, Inc.
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#include "tclInt.h"
+
+/*
+ * Indices of the standard return options dictionary keys.
+ */
+
+enum returnKeys {
+    KEY_CODE,	KEY_ERRORCODE,	KEY_ERRORINFO,	KEY_ERRORLINE,
+    KEY_LEVEL,	KEY_OPTIONS,	KEY_ERRORSTACK,	KEY_LAST
+};
+
+/*
+ * Function prototypes for local functions in this file:
+ */
+
+static Tcl_Obj **	GetKeys(void);
+static void		ReleaseKeys(ClientData clientData);
+static void		ResetObjResult(Interp *iPtr);
+static void		SetupAppendBuffer(Interp *iPtr, int newSpace);
+
+/*
+ * This structure is used to take a snapshot of the interpreter state in
+ * Tcl_SaveInterpState. You can snapshot the state, execute a command, and
+ * then back up to the result or the error that was previously in progress.
+ */
+
+typedef struct InterpState {
+    int status;			/* return code status */
+    int flags;			/* Each remaining field saves the */
+    int returnLevel;		/* corresponding field of the Interp */
+    int returnCode;		/* struct. These fields taken together are */
+    Tcl_Obj *errorInfo;		/* the "state" of the interp. */
+    Tcl_Obj *errorCode;
+    Tcl_Obj *returnOpts;
+    Tcl_Obj *objResult;
+    Tcl_Obj *errorStack;
+    int resetErrorStack;
+} InterpState;
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_SaveInterpState --
+ *
+ *	Fills a token with a snapshot of the current state of the interpreter.
+ *	The snapshot can be restored at any point by TclRestoreInterpState.
+ *
+ *	The token returned must be eventally passed to one of the routines
+ *	TclRestoreInterpState or TclDiscardInterpState, or there will be a
+ *	memory leak.
+ *
+ * Results:
+ *	Returns a token representing the interp state.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_InterpState
+Tcl_SaveInterpState(
+    Tcl_Interp *interp,		/* Interpreter's state to be saved */
+    int status)			/* status code for current operation */
+{
+    Interp *iPtr = (Interp *) interp;
+    InterpState *statePtr = ckalloc(sizeof(InterpState));
+
+    statePtr->status = status;
+    statePtr->flags = iPtr->flags & ERR_ALREADY_LOGGED;
+    statePtr->returnLevel = iPtr->returnLevel;
+    statePtr->returnCode = iPtr->returnCode;
+    statePtr->errorInfo = iPtr->errorInfo;
+    statePtr->errorStack = iPtr->errorStack;
+    statePtr->resetErrorStack = iPtr->resetErrorStack;
+    if (statePtr->errorInfo) {
+	Tcl_IncrRefCount(statePtr->errorInfo);
+    }
+    statePtr->errorCode = iPtr->errorCode;
+    if (statePtr->errorCode) {
+	Tcl_IncrRefCount(statePtr->errorCode);
+    }
+    statePtr->returnOpts = iPtr->returnOpts;
+    if (statePtr->returnOpts) {
+	Tcl_IncrRefCount(statePtr->returnOpts);
+    }
+    if (statePtr->errorStack) {
+	Tcl_IncrRefCount(statePtr->errorStack);
+    }
+    statePtr->objResult = Tcl_GetObjResult(interp);
+    Tcl_IncrRefCount(statePtr->objResult);
+    return (Tcl_InterpState) statePtr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_RestoreInterpState --
+ *
+ *	Accepts an interp and a token previously returned by
+ *	Tcl_SaveInterpState. Restore the state of the interp to what it was at
+ *	the time of the Tcl_SaveInterpState call.
+ *
+ * Results:
+ *	Returns the status value originally passed in to Tcl_SaveInterpState.
+ *
+ * Side effects:
+ *	Restores the interp state and frees memory held by token.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_RestoreInterpState(
+    Tcl_Interp *interp,		/* Interpreter's state to be restored. */
+    Tcl_InterpState state)	/* Saved interpreter state. */
+{
+    Interp *iPtr = (Interp *) interp;
+    InterpState *statePtr = (InterpState *) state;
+    int status = statePtr->status;
+
+    iPtr->flags &= ~ERR_ALREADY_LOGGED;
+    iPtr->flags |= (statePtr->flags & ERR_ALREADY_LOGGED);
+
+    iPtr->returnLevel = statePtr->returnLevel;
+    iPtr->returnCode = statePtr->returnCode;
+    iPtr->resetErrorStack = statePtr->resetErrorStack;
+    if (iPtr->errorInfo) {
+	Tcl_DecrRefCount(iPtr->errorInfo);
+    }
+    iPtr->errorInfo = statePtr->errorInfo;
+    if (iPtr->errorInfo) {
+	Tcl_IncrRefCount(iPtr->errorInfo);
+    }
+    if (iPtr->errorCode) {
+	Tcl_DecrRefCount(iPtr->errorCode);
+    }
+    iPtr->errorCode = statePtr->errorCode;
+    if (iPtr->errorCode) {
+	Tcl_IncrRefCount(iPtr->errorCode);
+    }
+    if (iPtr->errorStack) {
+	Tcl_DecrRefCount(iPtr->errorStack);
+    }
+    iPtr->errorStack = statePtr->errorStack;
+    if (iPtr->errorStack) {
+	Tcl_IncrRefCount(iPtr->errorStack);
+    }
+    if (iPtr->returnOpts) {
+	Tcl_DecrRefCount(iPtr->returnOpts);
+    }
+    iPtr->returnOpts = statePtr->returnOpts;
+    if (iPtr->returnOpts) {
+	Tcl_IncrRefCount(iPtr->returnOpts);
+    }
+    Tcl_SetObjResult(interp, statePtr->objResult);
+    Tcl_DiscardInterpState(state);
+    return status;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_DiscardInterpState --
+ *
+ *	Accepts a token previously returned by Tcl_SaveInterpState. Frees the
+ *	memory it uses.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Frees memory.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_DiscardInterpState(
+    Tcl_InterpState state)	/* saved interpreter state */
+{
+    InterpState *statePtr = (InterpState *) state;
+
+    if (statePtr->errorInfo) {
+	Tcl_DecrRefCount(statePtr->errorInfo);
+    }
+    if (statePtr->errorCode) {
+	Tcl_DecrRefCount(statePtr->errorCode);
+    }
+    if (statePtr->returnOpts) {
+	Tcl_DecrRefCount(statePtr->returnOpts);
+    }
+    if (statePtr->errorStack) {
+	Tcl_DecrRefCount(statePtr->errorStack);
+    }
+    Tcl_DecrRefCount(statePtr->objResult);
+    ckfree(statePtr);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_SaveResult --
+ *
+ *	Takes a snapshot of the current result state of the interpreter. The
+ *	snapshot can be restored at any point by Tcl_RestoreResult. Note that
+ *	this routine does not preserve the errorCode, errorInfo, or flags
+ *	fields so it should not be used if an error is in progress.
+ *
+ *	Once a snapshot is saved, it must be restored by calling
+ *	Tcl_RestoreResult, or discarded by calling Tcl_DiscardResult.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Resets the interpreter result.
+ *
+ *----------------------------------------------------------------------
+ */
+
+#undef Tcl_SaveResult
+void
+Tcl_SaveResult(
+    Tcl_Interp *interp,		/* Interpreter to save. */
+    Tcl_SavedResult *statePtr)	/* Pointer to state structure. */
+{
+    Interp *iPtr = (Interp *) interp;
+
+    /*
+     * Move the result object into the save state. Note that we don't need to
+     * change its refcount because we're moving it, not adding a new
+     * reference. Put an empty object into the interpreter.
+     */
+
+    statePtr->objResultPtr = iPtr->objResultPtr;
+    iPtr->objResultPtr = Tcl_NewObj();
+    Tcl_IncrRefCount(iPtr->objResultPtr);
+
+    /*
+     * Save the string result.
+     */
+
+    statePtr->freeProc = iPtr->freeProc;
+    if (iPtr->result == iPtr->resultSpace) {
+	/*
+	 * Copy the static string data out of the interp buffer.
+	 */
+
+	statePtr->result = statePtr->resultSpace;
+	strcpy(statePtr->result, iPtr->result);
+	statePtr->appendResult = NULL;
+    } else if (iPtr->result == iPtr->appendResult) {
+	/*
+	 * Move the append buffer out of the interp.
+	 */
+
+	statePtr->appendResult = iPtr->appendResult;
+	statePtr->appendAvl = iPtr->appendAvl;
+	statePtr->appendUsed = iPtr->appendUsed;
+	statePtr->result = statePtr->appendResult;
+	iPtr->appendResult = NULL;
+	iPtr->appendAvl = 0;
+	iPtr->appendUsed = 0;
+    } else {
+	/*
+	 * Move the dynamic or static string out of the interpreter.
+	 */
+
+	statePtr->result = iPtr->result;
+	statePtr->appendResult = NULL;
+    }
+
+    iPtr->result = iPtr->resultSpace;
+    iPtr->resultSpace[0] = 0;
+    iPtr->freeProc = 0;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_RestoreResult --
+ *
+ *	Restores the state of the interpreter to a snapshot taken by
+ *	Tcl_SaveResult. After this call, the token for the interpreter state
+ *	is no longer valid.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Restores the interpreter result.
+ *
+ *----------------------------------------------------------------------
+ */
+
+#undef Tcl_RestoreResult
+void
+Tcl_RestoreResult(
+    Tcl_Interp *interp,		/* Interpreter being restored. */
+    Tcl_SavedResult *statePtr)	/* State returned by Tcl_SaveResult. */
+{
+    Interp *iPtr = (Interp *) interp;
+
+    Tcl_ResetResult(interp);
+
+    /*
+     * Restore the string result.
+     */
+
+    iPtr->freeProc = statePtr->freeProc;
+    if (statePtr->result == statePtr->resultSpace) {
+	/*
+	 * Copy the static string data into the interp buffer.
+	 */
+
+	iPtr->result = iPtr->resultSpace;
+	strcpy(iPtr->result, statePtr->result);
+    } else if (statePtr->result == statePtr->appendResult) {
+	/*
+	 * Move the append buffer back into the interp.
+	 */
+
+	if (iPtr->appendResult != NULL) {
+	    ckfree(iPtr->appendResult);
+	}
+
+	iPtr->appendResult = statePtr->appendResult;
+	iPtr->appendAvl = statePtr->appendAvl;
+	iPtr->appendUsed = statePtr->appendUsed;
+	iPtr->result = iPtr->appendResult;
+    } else {
+	/*
+	 * Move the dynamic or static string back into the interpreter.
+	 */
+
+	iPtr->result = statePtr->result;
+    }
+
+    /*
+     * Restore the object result.
+     */
+
+    Tcl_DecrRefCount(iPtr->objResultPtr);
+    iPtr->objResultPtr = statePtr->objResultPtr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_DiscardResult --
+ *
+ *	Frees the memory associated with an interpreter snapshot taken by
+ *	Tcl_SaveResult. If the snapshot is not restored, this function must be
+ *	called to discard it, or the memory will be lost.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+#undef Tcl_DiscardResult
+void
+Tcl_DiscardResult(
+    Tcl_SavedResult *statePtr)	/* State returned by Tcl_SaveResult. */
+{
+    TclDecrRefCount(statePtr->objResultPtr);
+
+    if (statePtr->result == statePtr->appendResult) {
+	ckfree(statePtr->appendResult);
+    } else if (statePtr->freeProc == TCL_DYNAMIC) {
+        ckfree(statePtr->result);
+    } else if (statePtr->freeProc) {
+        statePtr->freeProc(statePtr->result);
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_SetResult --
+ *
+ *	Arrange for "result" to be the Tcl return value.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	interp->result is left pointing either to "result" or to a copy of it.
+ *	Also, the object result is reset.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_SetResult(
+    Tcl_Interp *interp,		/* Interpreter with which to associate the
+				 * return value. */
+    register char *result,	/* Value to be returned. If NULL, the result
+				 * is set to an empty string. */
+    Tcl_FreeProc *freeProc)	/* Gives information about the string:
+				 * TCL_STATIC, TCL_VOLATILE, or the address of
+				 * a Tcl_FreeProc such as free. */
+{
+    Interp *iPtr = (Interp *) interp;
+    register Tcl_FreeProc *oldFreeProc = iPtr->freeProc;
+    char *oldResult = iPtr->result;
+
+    if (result == NULL) {
+	iPtr->resultSpace[0] = 0;
+	iPtr->result = iPtr->resultSpace;
+	iPtr->freeProc = 0;
+    } else if (freeProc == TCL_VOLATILE) {
+	int length = strlen(result);
+
+	if (length > TCL_RESULT_SIZE) {
+	    iPtr->result = ckalloc(length + 1);
+	    iPtr->freeProc = TCL_DYNAMIC;
+	} else {
+	    iPtr->result = iPtr->resultSpace;
+	    iPtr->freeProc = 0;
+	}
+	memcpy(iPtr->result, result, (unsigned) length+1);
+    } else {
+	iPtr->result = (char *) result;
+	iPtr->freeProc = freeProc;
+    }
+
+    /*
+     * If the old result was dynamically-allocated, free it up. Do it here,
+     * rather than at the beginning, in case the new result value was part of
+     * the old result value.
+     */
+
+    if (oldFreeProc != 0) {
+	if (oldFreeProc == TCL_DYNAMIC) {
+	    ckfree(oldResult);
+	} else {
+	    oldFreeProc(oldResult);
+	}
+    }
+
+    /*
+     * Reset the object result since we just set the string result.
+     */
+
+    ResetObjResult(iPtr);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_GetStringResult --
+ *
+ *	Returns an interpreter's result value as a string.
+ *
+ * Results:
+ *	The interpreter's result as a string.
+ *
+ * Side effects:
+ *	If the string result is empty, the object result is moved to the
+ *	string result, then the object result is reset.
+ *
+ *----------------------------------------------------------------------
+ */
+
+const char *
+Tcl_GetStringResult(
+    register Tcl_Interp *interp)/* Interpreter whose result to return. */
+{
+    /*
+     * If the string result is empty, move the object result to the string
+     * result, then reset the object result.
+     */
+
+    Interp *iPtr = (Interp *) interp;
+
+    if (*(iPtr->result) == 0) {
+	Tcl_SetResult(interp, TclGetString(Tcl_GetObjResult(interp)),
+		TCL_VOLATILE);
+    }
+    return iPtr->result;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_SetObjResult --
+ *
+ *	Arrange for objPtr to be an interpreter's result value.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	interp->objResultPtr is left pointing to the object referenced by
+ *	objPtr. The object's reference count is incremented since there is now
+ *	a new reference to it. The reference count for any old objResultPtr
+ *	value is decremented. Also, the string result is reset.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_SetObjResult(
+    Tcl_Interp *interp,		/* Interpreter with which to associate the
+				 * return object value. */
+    register Tcl_Obj *objPtr)	/* Tcl object to be returned. If NULL, the obj
+				 * result is made an empty string object. */
+{
+    register Interp *iPtr = (Interp *) interp;
+    register Tcl_Obj *oldObjResult = iPtr->objResultPtr;
+
+    iPtr->objResultPtr = objPtr;
+    Tcl_IncrRefCount(objPtr);	/* since interp result is a reference */
+
+    /*
+     * We wait until the end to release the old object result, in case we are
+     * setting the result to itself.
+     */
+
+    TclDecrRefCount(oldObjResult);
+
+    /*
+     * Reset the string result since we just set the result object.
+     */
+
+    if (iPtr->freeProc != NULL) {
+	if (iPtr->freeProc == TCL_DYNAMIC) {
+	    ckfree(iPtr->result);
+	} else {
+	    iPtr->freeProc(iPtr->result);
+	}
+	iPtr->freeProc = 0;
+    }
+    iPtr->result = iPtr->resultSpace;
+    iPtr->resultSpace[0] = 0;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_GetObjResult --
+ *
+ *	Returns an interpreter's result value as a Tcl object. The object's
+ *	reference count is not modified; the caller must do that if it needs
+ *	to hold on to a long-term reference to it.
+ *
+ * Results:
+ *	The interpreter's result as an object.
+ *
+ * Side effects:
+ *	If the interpreter has a non-empty string result, the result object is
+ *	either empty or stale because some function set interp->result
+ *	directly. If so, the string result is moved to the result object then
+ *	the string result is reset.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_Obj *
+Tcl_GetObjResult(
+    Tcl_Interp *interp)		/* Interpreter whose result to return. */
+{
+    register Interp *iPtr = (Interp *) interp;
+    Tcl_Obj *objResultPtr;
+    int length;
+
+    /*
+     * If the string result is non-empty, move the string result to the object
+     * result, then reset the string result.
+     */
+
+    if (iPtr->result[0] != 0) {
+	ResetObjResult(iPtr);
+
+	objResultPtr = iPtr->objResultPtr;
+	length = strlen(iPtr->result);
+	TclInitStringRep(objResultPtr, iPtr->result, length);
+
+	if (iPtr->freeProc != NULL) {
+	    if (iPtr->freeProc == TCL_DYNAMIC) {
+		ckfree(iPtr->result);
+	    } else {
+		iPtr->freeProc(iPtr->result);
+	    }
+	    iPtr->freeProc = 0;
+	}
+	iPtr->result = iPtr->resultSpace;
+	iPtr->result[0] = 0;
+    }
+    return iPtr->objResultPtr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_AppendResultVA --
+ *
+ *	Append a variable number of strings onto the interpreter's result.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The result of the interpreter given by the first argument is extended
+ *	by the strings in the va_list (up to a terminating NULL argument).
+ *
+ *	If the string result is non-empty, the object result forced to be a
+ *	duplicate of it first. There will be a string result afterwards.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_AppendResultVA(
+    Tcl_Interp *interp,		/* Interpreter with which to associate the
+				 * return value. */
+    va_list argList)		/* Variable argument list. */
+{
+    Tcl_Obj *objPtr = Tcl_GetObjResult(interp);
+
+    if (Tcl_IsShared(objPtr)) {
+	objPtr = Tcl_DuplicateObj(objPtr);
+    }
+    Tcl_AppendStringsToObjVA(objPtr, argList);
+    Tcl_SetObjResult(interp, objPtr);
+
+    /*
+     * Strictly we should call Tcl_GetStringResult(interp) here to make sure
+     * that interp->result is correct according to the old contract, but that
+     * makes the performance of much code (e.g. in Tk) absolutely awful. So we
+     * leave it out; code that really wants interp->result can just insert the
+     * calls to Tcl_GetStringResult() itself. [Patch 1041072 discussion]
+     */
+
+#ifdef USE_INTERP_RESULT
+    /*
+     * Ensure that the interp->result is legal so old Tcl 7.* code still
+     * works. There's still embarrasingly much of it about...
+     */
+
+    (void) Tcl_GetStringResult(interp);
+#endif /* USE_INTERP_RESULT */
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_AppendResult --
+ *
+ *	Append a variable number of strings onto the interpreter's result.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The result of the interpreter given by the first argument is extended
+ *	by the strings given by the second and following arguments (up to a
+ *	terminating NULL argument).
+ *
+ *	If the string result is non-empty, the object result forced to be a
+ *	duplicate of it first. There will be a string result afterwards.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_AppendResult(
+    Tcl_Interp *interp, ...)
+{
+    va_list argList;
+
+    va_start(argList, interp);
+    Tcl_AppendResultVA(interp, argList);
+    va_end(argList);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_AppendElement --
+ *
+ *	Convert a string to a valid Tcl list element and append it to the
+ *	result (which is ostensibly a list).
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The result in the interpreter given by the first argument is extended
+ *	with a list element converted from string. A separator space is added
+ *	before the converted list element unless the current result is empty,
+ *	contains the single character "{", or ends in " {".
+ *
+ *	If the string result is empty, the object result is moved to the
+ *	string result, then the object result is reset.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_AppendElement(
+    Tcl_Interp *interp,		/* Interpreter whose result is to be
+				 * extended. */
+    const char *element)	/* String to convert to list element and add
+				 * to result. */
+{
+    Interp *iPtr = (Interp *) interp;
+    char *dst;
+    int size;
+    int flags;
+
+    /*
+     * If the string result is empty, move the object result to the string
+     * result, then reset the object result.
+     */
+
+    (void) Tcl_GetStringResult(interp);
+
+    /*
+     * See how much space is needed, and grow the append buffer if needed to
+     * accommodate the list element.
+     */
+
+    size = Tcl_ScanElement(element, &flags) + 1;
+    if ((iPtr->result != iPtr->appendResult)
+	    || (iPtr->appendResult[iPtr->appendUsed] != 0)
+	    || ((size + iPtr->appendUsed) >= iPtr->appendAvl)) {
+	SetupAppendBuffer(iPtr, size+iPtr->appendUsed);
+    }
+
+    /*
+     * Convert the string into a list element and copy it to the buffer that's
+     * forming, with a space separator if needed.
+     */
+
+    dst = iPtr->appendResult + iPtr->appendUsed;
+    if (TclNeedSpace(iPtr->appendResult, dst)) {
+	iPtr->appendUsed++;
+	*dst = ' ';
+	dst++;
+
+	/*
+	 * If we need a space to separate this element from preceding stuff,
+	 * then this element will not lead a list, and need not have it's
+	 * leading '#' quoted.
+	 */
+
+	flags |= TCL_DONT_QUOTE_HASH;
+    }
+    iPtr->appendUsed += Tcl_ConvertElement(element, dst, flags);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * SetupAppendBuffer --
+ *
+ *	This function makes sure that there is an append buffer properly
+ *	initialized, if necessary, from the interpreter's result, and that it
+ *	has at least enough room to accommodate newSpace new bytes of
+ *	information.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+SetupAppendBuffer(
+    Interp *iPtr,		/* Interpreter whose result is being set up. */
+    int newSpace)		/* Make sure that at least this many bytes of
+				 * new information may be added. */
+{
+    int totalSpace;
+
+    /*
+     * Make the append buffer larger, if that's necessary, then copy the
+     * result into the append buffer and make the append buffer the official
+     * Tcl result.
+     */
+
+    if (iPtr->result != iPtr->appendResult) {
+	/*
+	 * If an oversized buffer was used recently, then free it up so we go
+	 * back to a smaller buffer. This avoids tying up memory forever after
+	 * a large operation.
+	 */
+
+	if (iPtr->appendAvl > 500) {
+	    ckfree(iPtr->appendResult);
+	    iPtr->appendResult = NULL;
+	    iPtr->appendAvl = 0;
+	}
+	iPtr->appendUsed = strlen(iPtr->result);
+    } else if (iPtr->result[iPtr->appendUsed] != 0) {
+	/*
+	 * Most likely someone has modified a result created by
+	 * Tcl_AppendResult et al. so that it has a different size. Just
+	 * recompute the size.
+	 */
+
+	iPtr->appendUsed = strlen(iPtr->result);
+    }
+
+    totalSpace = newSpace + iPtr->appendUsed;
+    if (totalSpace >= iPtr->appendAvl) {
+	char *new;
+
+	if (totalSpace < 100) {
+	    totalSpace = 200;
+	} else {
+	    totalSpace *= 2;
+	}
+	new = ckalloc(totalSpace);
+	strcpy(new, iPtr->result);
+	if (iPtr->appendResult != NULL) {
+	    ckfree(iPtr->appendResult);
+	}
+	iPtr->appendResult = new;
+	iPtr->appendAvl = totalSpace;
+    } else if (iPtr->result != iPtr->appendResult) {
+	strcpy(iPtr->appendResult, iPtr->result);
+    }
+
+    Tcl_FreeResult((Tcl_Interp *) iPtr);
+    iPtr->result = iPtr->appendResult;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_FreeResult --
+ *
+ *	This function frees up the memory associated with an interpreter's
+ *	string result. It also resets the interpreter's result object.
+ *	Tcl_FreeResult is most commonly used when a function is about to
+ *	replace one result value with another.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Frees the memory associated with interp's string result and sets
+ *	interp->freeProc to zero, but does not change interp->result or clear
+ *	error state. Resets interp's result object to an unshared empty
+ *	object.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_FreeResult(
+    register Tcl_Interp *interp)/* Interpreter for which to free result. */
+{
+    register Interp *iPtr = (Interp *) interp;
+
+    if (iPtr->freeProc != NULL) {
+	if (iPtr->freeProc == TCL_DYNAMIC) {
+	    ckfree(iPtr->result);
+	} else {
+	    iPtr->freeProc(iPtr->result);
+	}
+	iPtr->freeProc = 0;
+    }
+
+    ResetObjResult(iPtr);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_ResetResult --
+ *
+ *	This function resets both the interpreter's string and object results.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	It resets the result object to an unshared empty object. It then
+ *	restores the interpreter's string result area to its default
+ *	initialized state, freeing up any memory that may have been allocated.
+ *	It also clears any error information for the interpreter.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_ResetResult(
+    register Tcl_Interp *interp)/* Interpreter for which to clear result. */
+{
+    register Interp *iPtr = (Interp *) interp;
+
+    ResetObjResult(iPtr);
+    if (iPtr->freeProc != NULL) {
+	if (iPtr->freeProc == TCL_DYNAMIC) {
+	    ckfree(iPtr->result);
+	} else {
+	    iPtr->freeProc(iPtr->result);
+	}
+	iPtr->freeProc = 0;
+    }
+    iPtr->result = iPtr->resultSpace;
+    iPtr->resultSpace[0] = 0;
+    if (iPtr->errorCode) {
+	/* Legacy support */
+	if (iPtr->flags & ERR_LEGACY_COPY) {
+	    Tcl_ObjSetVar2(interp, iPtr->ecVar, NULL,
+		    iPtr->errorCode, TCL_GLOBAL_ONLY);
+	}
+	Tcl_DecrRefCount(iPtr->errorCode);
+	iPtr->errorCode = NULL;
+    }
+    if (iPtr->errorInfo) {
+	/* Legacy support */
+	if (iPtr->flags & ERR_LEGACY_COPY) {
+	    Tcl_ObjSetVar2(interp, iPtr->eiVar, NULL,
+		    iPtr->errorInfo, TCL_GLOBAL_ONLY);
+	}
+	Tcl_DecrRefCount(iPtr->errorInfo);
+	iPtr->errorInfo = NULL;
+    }
+    iPtr->resetErrorStack = 1;
+    iPtr->returnLevel = 1;
+    iPtr->returnCode = TCL_OK;
+    if (iPtr->returnOpts) {
+	Tcl_DecrRefCount(iPtr->returnOpts);
+	iPtr->returnOpts = NULL;
+    }
+    iPtr->flags &= ~(ERR_ALREADY_LOGGED | ERR_LEGACY_COPY);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ResetObjResult --
+ *
+ *	Function used to reset an interpreter's Tcl result object.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Resets the interpreter's result object to an unshared empty string
+ *	object with ref count one. It does not clear any error information in
+ *	the interpreter.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+ResetObjResult(
+    register Interp *iPtr)	/* Points to the interpreter whose result
+				 * object should be reset. */
+{
+    register Tcl_Obj *objResultPtr = iPtr->objResultPtr;
+
+    if (Tcl_IsShared(objResultPtr)) {
+	TclDecrRefCount(objResultPtr);
+	TclNewObj(objResultPtr);
+	Tcl_IncrRefCount(objResultPtr);
+	iPtr->objResultPtr = objResultPtr;
+    } else {
+	if (objResultPtr->bytes != tclEmptyStringRep) {
+	    if (objResultPtr->bytes) {
+		ckfree(objResultPtr->bytes);
+	    }
+	    objResultPtr->bytes = tclEmptyStringRep;
+	    objResultPtr->length = 0;
+	}
+	TclFreeIntRep(objResultPtr);
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_SetErrorCodeVA --
+ *
+ *	This function is called to record machine-readable information about
+ *	an error that is about to be returned.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The errorCode field of the interp is modified to hold all of the
+ *	arguments to this function, in a list form with each argument becoming
+ *	one element of the list.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_SetErrorCodeVA(
+    Tcl_Interp *interp,		/* Interpreter in which to set errorCode */
+    va_list argList)		/* Variable argument list. */
+{
+    Tcl_Obj *errorObj = Tcl_NewObj();
+
+    /*
+     * Scan through the arguments one at a time, appending them to the
+     * errorCode field as list elements.
+     */
+
+    while (1) {
+	char *elem = va_arg(argList, char *);
+
+	if (elem == NULL) {
+	    break;
+	}
+	Tcl_ListObjAppendElement(NULL, errorObj, Tcl_NewStringObj(elem, -1));
+    }
+    Tcl_SetObjErrorCode(interp, errorObj);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_SetErrorCode --
+ *
+ *	This function is called to record machine-readable information about
+ *	an error that is about to be returned.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The errorCode field of the interp is modified to hold all of the
+ *	arguments to this function, in a list form with each argument becoming
+ *	one element of the list.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_SetErrorCode(
+    Tcl_Interp *interp, ...)
+{
+    va_list argList;
+
+    /*
+     * Scan through the arguments one at a time, appending them to the
+     * errorCode field as list elements.
+     */
+
+    va_start(argList, interp);
+    Tcl_SetErrorCodeVA(interp, argList);
+    va_end(argList);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_SetObjErrorCode --
+ *
+ *	This function is called to record machine-readable information about
+ *	an error that is about to be returned. The caller should build a list
+ *	object up and pass it to this routine.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The errorCode field of the interp is set to the new value.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_SetObjErrorCode(
+    Tcl_Interp *interp,
+    Tcl_Obj *errorObjPtr)
+{
+    Interp *iPtr = (Interp *) interp;
+
+    if (iPtr->errorCode) {
+	Tcl_DecrRefCount(iPtr->errorCode);
+    }
+    iPtr->errorCode = errorObjPtr;
+    Tcl_IncrRefCount(iPtr->errorCode);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_GetErrorLine --
+ *
+ *      Returns the line number associated with the current error.
+ *
+ *----------------------------------------------------------------------
+ */
+
+#undef Tcl_GetErrorLine
+int
+Tcl_GetErrorLine(
+    Tcl_Interp *interp)
+{
+    return ((Interp *) interp)->errorLine;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_SetErrorLine --
+ *
+ *      Sets the line number associated with the current error.
+ *
+ *----------------------------------------------------------------------
+ */
+
+#undef Tcl_SetErrorLine
+void
+Tcl_SetErrorLine(
+    Tcl_Interp *interp,
+    int value)
+{
+    ((Interp *) interp)->errorLine = value;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * GetKeys --
+ *
+ *	Returns a Tcl_Obj * array of the standard keys used in the return
+ *	options dictionary.
+ *
+ *	Broadly sharing one copy of these key values helps with both memory
+ *	efficiency and dictionary lookup times.
+ *
+ * Results:
+ *	A Tcl_Obj * array.
+ *
+ * Side effects:
+ *	First time called in a thread, creates the keys (allocating memory)
+ *	and arranges for their cleanup at thread exit.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static Tcl_Obj **
+GetKeys(void)
+{
+    static Tcl_ThreadDataKey returnKeysKey;
+    Tcl_Obj **keys = Tcl_GetThreadData(&returnKeysKey,
+	    (int) (KEY_LAST * sizeof(Tcl_Obj *)));
+
+    if (keys[0] == NULL) {
+	/*
+	 * First call in this thread, create the keys...
+	 */
+
+	int i;
+
+	TclNewLiteralStringObj(keys[KEY_CODE],	    "-code");
+	TclNewLiteralStringObj(keys[KEY_ERRORCODE], "-errorcode");
+	TclNewLiteralStringObj(keys[KEY_ERRORINFO], "-errorinfo");
+	TclNewLiteralStringObj(keys[KEY_ERRORLINE], "-errorline");
+	TclNewLiteralStringObj(keys[KEY_ERRORSTACK],"-errorstack");
+	TclNewLiteralStringObj(keys[KEY_LEVEL],	    "-level");
+	TclNewLiteralStringObj(keys[KEY_OPTIONS],   "-options");
+
+	for (i = KEY_CODE; i < KEY_LAST; i++) {
+	    Tcl_IncrRefCount(keys[i]);
+	}
+
+	/*
+	 * ... and arrange for their clenaup.
+	 */
+
+	Tcl_CreateThreadExitHandler(ReleaseKeys, keys);
+    }
+    return keys;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ReleaseKeys --
+ *
+ *	Called as a thread exit handler to cleanup return options dictionary
+ *	keys.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Frees memory.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+ReleaseKeys(
+    ClientData clientData)
+{
+    Tcl_Obj **keys = clientData;
+    int i;
+
+    for (i = KEY_CODE; i < KEY_LAST; i++) {
+	Tcl_DecrRefCount(keys[i]);
+	keys[i] = NULL;
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclProcessReturn --
+ *
+ *	Does the work of the [return] command based on the code, level, and
+ *	returnOpts arguments. Note that the code argument must agree with the
+ *	-code entry in returnOpts and the level argument must agree with the
+ *	-level entry in returnOpts, as is the case for values returned from
+ *	TclMergeReturnOptions.
+ *
+ * Results:
+ *	Returns the return code the [return] command should return.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclProcessReturn(
+    Tcl_Interp *interp,
+    int code,
+    int level,
+    Tcl_Obj *returnOpts)
+{
+    Interp *iPtr = (Interp *) interp;
+    Tcl_Obj *valuePtr;
+    Tcl_Obj **keys = GetKeys();
+
+    /*
+     * Store the merged return options.
+     */
+
+    if (iPtr->returnOpts != returnOpts) {
+	if (iPtr->returnOpts) {
+	    Tcl_DecrRefCount(iPtr->returnOpts);
+	}
+	iPtr->returnOpts = returnOpts;
+	Tcl_IncrRefCount(iPtr->returnOpts);
+    }
+
+    if (code == TCL_ERROR) {
+	if (iPtr->errorInfo) {
+	    Tcl_DecrRefCount(iPtr->errorInfo);
+	    iPtr->errorInfo = NULL;
+	}
+	Tcl_DictObjGet(NULL, iPtr->returnOpts, keys[KEY_ERRORINFO],
+                &valuePtr);
+	if (valuePtr != NULL) {
+	    int infoLen;
+
+	    (void) TclGetStringFromObj(valuePtr, &infoLen);
+	    if (infoLen) {
+		iPtr->errorInfo = valuePtr;
+		Tcl_IncrRefCount(iPtr->errorInfo);
+		iPtr->flags |= ERR_ALREADY_LOGGED;
+	    }
+	}
+	Tcl_DictObjGet(NULL, iPtr->returnOpts, keys[KEY_ERRORSTACK],
+                &valuePtr);
+	if (valuePtr != NULL) {
+            int len, valueObjc;
+            Tcl_Obj **valueObjv;
+
+            if (Tcl_IsShared(iPtr->errorStack)) {
+                Tcl_Obj *newObj;
+
+                newObj = Tcl_DuplicateObj(iPtr->errorStack);
+                Tcl_DecrRefCount(iPtr->errorStack);
+                Tcl_IncrRefCount(newObj);
+                iPtr->errorStack = newObj;
+            }
+
+            /*
+             * List extraction done after duplication to avoid moving the rug
+             * if someone does [return -errorstack [info errorstack]]
+             */
+
+            if (Tcl_ListObjGetElements(interp, valuePtr, &valueObjc,
+                    &valueObjv) == TCL_ERROR) {
+                return TCL_ERROR;
+            }
+            iPtr->resetErrorStack = 0;
+            Tcl_ListObjLength(interp, iPtr->errorStack, &len);
+
+            /*
+             * Reset while keeping the list intrep as much as possible.
+             */
+
+            Tcl_ListObjReplace(interp, iPtr->errorStack, 0, len, valueObjc,
+                    valueObjv);
+ 	}
+	Tcl_DictObjGet(NULL, iPtr->returnOpts, keys[KEY_ERRORCODE],
+                &valuePtr);
+	if (valuePtr != NULL) {
+	    Tcl_SetObjErrorCode(interp, valuePtr);
+	} else {
+	    Tcl_SetErrorCode(interp, "NONE", NULL);
+	}
+
+	Tcl_DictObjGet(NULL, iPtr->returnOpts, keys[KEY_ERRORLINE],
+                &valuePtr);
+	if (valuePtr != NULL) {
+	    TclGetIntFromObj(NULL, valuePtr, &iPtr->errorLine);
+	}
+    }
+    if (level != 0) {
+	iPtr->returnLevel = level;
+	iPtr->returnCode = code;
+	return TCL_RETURN;
+    }
+    if (code == TCL_ERROR) {
+	iPtr->flags |= ERR_LEGACY_COPY;
+    }
+    return code;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclMergeReturnOptions --
+ *
+ *	Parses, checks, and stores the options to the [return] command.
+ *
+ * Results:
+ *	Returns TCL_ERROR if any of the option values are invalid. Otherwise,
+ *	returns TCL_OK, and writes the returnOpts, code, and level values to
+ *	the pointers provided.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclMergeReturnOptions(
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[],	/* Argument objects. */
+    Tcl_Obj **optionsPtrPtr,	/* If not NULL, points to space for a (Tcl_Obj
+				 * *) where the pointer to the merged return
+				 * options dictionary should be written. */
+    int *codePtr,		/* If not NULL, points to space where the
+				 * -code value should be written. */
+    int *levelPtr)		/* If not NULL, points to space where the
+				 * -level value should be written. */
+{
+    int code = TCL_OK;
+    int level = 1;
+    Tcl_Obj *valuePtr;
+    Tcl_Obj *returnOpts = Tcl_NewObj();
+    Tcl_Obj **keys = GetKeys();
+
+    for (;  objc > 1;  objv += 2, objc -= 2) {
+	int optLen;
+	const char *opt = TclGetStringFromObj(objv[0], &optLen);
+	int compareLen;
+	const char *compare =
+		TclGetStringFromObj(keys[KEY_OPTIONS], &compareLen);
+
+	if ((optLen == compareLen) && (memcmp(opt, compare, optLen) == 0)) {
+	    Tcl_DictSearch search;
+	    int done = 0;
+	    Tcl_Obj *keyPtr;
+	    Tcl_Obj *dict = objv[1];
+
+	nestedOptions:
+	    if (TCL_ERROR == Tcl_DictObjFirst(NULL, dict, &search,
+		    &keyPtr, &valuePtr, &done)) {
+		/*
+		 * Value is not a legal dictionary.
+		 */
+
+		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+                        "bad %s value: expected dictionary but got \"%s\"",
+                        compare, TclGetString(objv[1])));
+		Tcl_SetErrorCode(interp, "TCL", "RESULT", "ILLEGAL_OPTIONS",
+			NULL);
+		goto error;
+	    }
+
+	    while (!done) {
+		Tcl_DictObjPut(NULL, returnOpts, keyPtr, valuePtr);
+		Tcl_DictObjNext(&search, &keyPtr, &valuePtr, &done);
+	    }
+
+	    Tcl_DictObjGet(NULL, returnOpts, keys[KEY_OPTIONS], &valuePtr);
+	    if (valuePtr != NULL) {
+		dict = valuePtr;
+		Tcl_DictObjRemove(NULL, returnOpts, keys[KEY_OPTIONS]);
+		goto nestedOptions;
+	    }
+
+	} else {
+	    Tcl_DictObjPut(NULL, returnOpts, objv[0], objv[1]);
+	}
+    }
+
+    /*
+     * Check for bogus -code value.
+     */
+
+    Tcl_DictObjGet(NULL, returnOpts, keys[KEY_CODE], &valuePtr);
+    if (valuePtr != NULL) {
+	if (TclGetCompletionCodeFromObj(interp, valuePtr,
+                &code) == TCL_ERROR) {
+	    goto error;
+	}
+	Tcl_DictObjRemove(NULL, returnOpts, keys[KEY_CODE]);
+    }
+
+    /*
+     * Check for bogus -level value.
+     */
+
+    Tcl_DictObjGet(NULL, returnOpts, keys[KEY_LEVEL], &valuePtr);
+    if (valuePtr != NULL) {
+	if ((TCL_ERROR == TclGetIntFromObj(NULL, valuePtr, &level))
+		|| (level < 0)) {
+	    /*
+	     * Value is not a legal level.
+	     */
+
+	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+                    "bad -level value: expected non-negative integer but got"
+                    " \"%s\"", TclGetString(valuePtr)));
+	    Tcl_SetErrorCode(interp, "TCL", "RESULT", "ILLEGAL_LEVEL", NULL);
+	    goto error;
+	}
+	Tcl_DictObjRemove(NULL, returnOpts, keys[KEY_LEVEL]);
+    }
+
+    /*
+     * Check for bogus -errorcode value.
+     */
+
+    Tcl_DictObjGet(NULL, returnOpts, keys[KEY_ERRORCODE], &valuePtr);
+    if (valuePtr != NULL) {
+	int length;
+
+	if (TCL_ERROR == Tcl_ListObjLength(NULL, valuePtr, &length )) {
+	    /*
+	     * Value is not a list, which is illegal for -errorcode.
+	     */
+
+	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+                    "bad -errorcode value: expected a list but got \"%s\"",
+                    TclGetString(valuePtr)));
+	    Tcl_SetErrorCode(interp, "TCL", "RESULT", "ILLEGAL_ERRORCODE",
+		    NULL);
+	    goto error;
+	}
+    }
+
+    /*
+     * Check for bogus -errorstack value.
+     */
+
+    Tcl_DictObjGet(NULL, returnOpts, keys[KEY_ERRORSTACK], &valuePtr);
+    if (valuePtr != NULL) {
+	int length;
+
+	if (TCL_ERROR == Tcl_ListObjLength(NULL, valuePtr, &length )) {
+	    /*
+	     * Value is not a list, which is illegal for -errorstack.
+	     */
+
+	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+                    "bad -errorstack value: expected a list but got \"%s\"",
+                    TclGetString(valuePtr)));
+	    Tcl_SetErrorCode(interp, "TCL", "RESULT", "NONLIST_ERRORSTACK",
+                    NULL);
+	    goto error;
+	}
+        if (length % 2) {
+            /*
+             * Errorstack must always be an even-sized list
+             */
+
+	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+                    "forbidden odd-sized list for -errorstack: \"%s\"",
+		    TclGetString(valuePtr)));
+	    Tcl_SetErrorCode(interp, "TCL", "RESULT",
+                    "ODDSIZEDLIST_ERRORSTACK", NULL);
+	    goto error;
+        }
+    }
+
+    /*
+     * Convert [return -code return -level X] to [return -code ok -level X+1]
+     */
+
+    if (code == TCL_RETURN) {
+	level++;
+	code = TCL_OK;
+    }
+
+    if (codePtr != NULL) {
+	*codePtr = code;
+    }
+    if (levelPtr != NULL) {
+	*levelPtr = level;
+    }
+
+    if (optionsPtrPtr == NULL) {
+	/*
+	 * Not passing back the options (?!), so clean them up.
+	 */
+
+	Tcl_DecrRefCount(returnOpts);
+    } else {
+	*optionsPtrPtr = returnOpts;
+    }
+    return TCL_OK;
+
+  error:
+    Tcl_DecrRefCount(returnOpts);
+    return TCL_ERROR;
+}
+
+/*
+ *-------------------------------------------------------------------------
+ *
+ * Tcl_GetReturnOptions --
+ *
+ *	Packs up the interp state into a dictionary of return options.
+ *
+ * Results:
+ *	A dictionary of return options.
+ *
+ * Side effects:
+ *	None.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+Tcl_Obj *
+Tcl_GetReturnOptions(
+    Tcl_Interp *interp,
+    int result)
+{
+    Interp *iPtr = (Interp *) interp;
+    Tcl_Obj *options;
+    Tcl_Obj **keys = GetKeys();
+
+    if (iPtr->returnOpts) {
+	options = Tcl_DuplicateObj(iPtr->returnOpts);
+    } else {
+	options = Tcl_NewObj();
+    }
+
+    if (result == TCL_RETURN) {
+	Tcl_DictObjPut(NULL, options, keys[KEY_CODE],
+		Tcl_NewIntObj(iPtr->returnCode));
+	Tcl_DictObjPut(NULL, options, keys[KEY_LEVEL],
+		Tcl_NewIntObj(iPtr->returnLevel));
+    } else {
+	Tcl_DictObjPut(NULL, options, keys[KEY_CODE],
+		Tcl_NewIntObj(result));
+	Tcl_DictObjPut(NULL, options, keys[KEY_LEVEL],
+		Tcl_NewIntObj(0));
+    }
+
+    if (result == TCL_ERROR) {
+	Tcl_AddErrorInfo(interp, "");
+        Tcl_DictObjPut(NULL, options, keys[KEY_ERRORSTACK], iPtr->errorStack);
+    }
+    if (iPtr->errorCode) {
+	Tcl_DictObjPut(NULL, options, keys[KEY_ERRORCODE], iPtr->errorCode);
+    }
+    if (iPtr->errorInfo) {
+	Tcl_DictObjPut(NULL, options, keys[KEY_ERRORINFO], iPtr->errorInfo);
+	Tcl_DictObjPut(NULL, options, keys[KEY_ERRORLINE],
+		Tcl_NewIntObj(iPtr->errorLine));
+    }
+    return options;
+}
+
+/*
+ *-------------------------------------------------------------------------
+ *
+ * TclNoErrorStack --
+ *
+ *	Removes the -errorstack entry from an options dict to avoid reference
+ *	cycles.
+ *
+ * Results:
+ *	The (unshared) argument options dict, modified in -place.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+Tcl_Obj *
+TclNoErrorStack(
+    Tcl_Interp *interp,
+    Tcl_Obj *options)
+{
+    Tcl_Obj **keys = GetKeys();
+
+    Tcl_DictObjRemove(interp, options, keys[KEY_ERRORSTACK]);
+    return options;
+}
+
+/*
+ *-------------------------------------------------------------------------
+ *
+ * Tcl_SetReturnOptions --
+ *
+ *	Accepts an interp and a dictionary of return options, and sets the
+ *	return options of the interp to match the dictionary.
+ *
+ * Results:
+ *	A standard status code. Usually TCL_OK, but TCL_ERROR if an invalid
+ *	option value was found in the dictionary. If a -level value of 0 is in
+ *	the dictionary, then the -code value in the dictionary will be
+ *	returned (TCL_OK default).
+ *
+ * Side effects:
+ *	Sets the state of the interp.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+int
+Tcl_SetReturnOptions(
+    Tcl_Interp *interp,
+    Tcl_Obj *options)
+{
+    int objc, level, code;
+    Tcl_Obj **objv, *mergedOpts;
+
+    Tcl_IncrRefCount(options);
+    if (TCL_ERROR == TclListObjGetElements(interp, options, &objc, &objv)
+	    || (objc % 2)) {
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+                "expected dict but got \"%s\"", TclGetString(options)));
+	Tcl_SetErrorCode(interp, "TCL", "RESULT", "ILLEGAL_OPTIONS", NULL);
+	code = TCL_ERROR;
+    } else if (TCL_ERROR == TclMergeReturnOptions(interp, objc, objv,
+	    &mergedOpts, &code, &level)) {
+	code = TCL_ERROR;
+    } else {
+	code = TclProcessReturn(interp, code, level, mergedOpts);
+    }
+
+    Tcl_DecrRefCount(options);
+    return code;
+}
+
+/*
+ *-------------------------------------------------------------------------
+ *
+ * Tcl_TransferResult --
+ *
+ *	Copy the result (and error information) from one interp to another.
+ *	Used when one interp has caused another interp to evaluate a script
+ *	and then wants to transfer the results back to itself.
+ *
+ *	This routine copies the string reps of the result and error
+ *	information. It does not simply increment the refcounts of the result
+ *	and error information objects themselves. It is not legal to exchange
+ *	objects between interps, because an object may be kept alive by one
+ *	interp, but have an internal rep that is only valid while some other
+ *	interp is alive.
+ *
+ * Results:
+ *	The target interp's result is set to a copy of the source interp's
+ *	result. The source's errorInfo field may be transferred to the
+ *	target's errorInfo field, and the source's errorCode field may be
+ *	transferred to the target's errorCode field.
+ *
+ * Side effects:
+ *	None.
+ *
+ *-------------------------------------------------------------------------
+ */
+
+void
+Tcl_TransferResult(
+    Tcl_Interp *sourceInterp,	/* Interp whose result and error information
+				 * should be moved to the target interp.
+				 * After moving result, this interp's result
+				 * is reset. */
+    int result,			/* TCL_OK if just the result should be copied,
+				 * TCL_ERROR if both the result and error
+				 * information should be copied. */
+    Tcl_Interp *targetInterp)	/* Interp where result and error information
+				 * should be stored. If source and target are
+				 * the same, nothing is done. */
+{
+    Interp *tiPtr = (Interp *) targetInterp;
+    Interp *siPtr = (Interp *) sourceInterp;
+
+    if (sourceInterp == targetInterp) {
+	return;
+    }
+
+    if (result == TCL_OK && siPtr->returnOpts == NULL) {
+	/*
+	 * Special optimization for the common case of normal command return
+	 * code and no explicit return options.
+	 */
+
+	if (tiPtr->returnOpts) {
+	    Tcl_DecrRefCount(tiPtr->returnOpts);
+	    tiPtr->returnOpts = NULL;
+	}
+    } else {
+	Tcl_SetReturnOptions(targetInterp,
+		Tcl_GetReturnOptions(sourceInterp, result));
+	tiPtr->flags &= ~(ERR_ALREADY_LOGGED);
+    }
+    Tcl_SetObjResult(targetInterp, Tcl_GetObjResult(sourceInterp));
+    Tcl_ResetResult(sourceInterp);
+}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/generic/tclScan.c b/generic/tclScan.c
new file mode 100644
index 0000000..3edb8be
--- /dev/null
+++ b/generic/tclScan.c
@@ -0,0 +1,1079 @@
+/*
+ * tclScan.c --
+ *
+ *	This file contains the implementation of the "scan" command.
+ *
+ * Copyright (c) 1998 by Scriptics Corporation.
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#include "tclInt.h"
+
+/*
+ * Flag values used by Tcl_ScanObjCmd.
+ */
+
+#define SCAN_NOSKIP	0x1		/* Don't skip blanks. */
+#define SCAN_SUPPRESS	0x2		/* Suppress assignment. */
+#define SCAN_UNSIGNED	0x4		/* Read an unsigned value. */
+#define SCAN_WIDTH	0x8		/* A width value was supplied. */
+
+#define SCAN_LONGER	0x400		/* Asked for a wide value. */
+#define SCAN_BIG	0x800		/* Asked for a bignum value. */
+
+/*
+ * The following structure contains the information associated with a
+ * character set.
+ */
+
+typedef struct CharSet {
+    int exclude;		/* 1 if this is an exclusion set. */
+    int nchars;
+    Tcl_UniChar *chars;
+    int nranges;
+    struct Range {
+	Tcl_UniChar start;
+	Tcl_UniChar end;
+    } *ranges;
+} CharSet;
+
+/*
+ * Declarations for functions used only in this file.
+ */
+
+static const char *	BuildCharSet(CharSet *cset, const char *format);
+static int		CharInSet(CharSet *cset, int ch);
+static void		ReleaseCharSet(CharSet *cset);
+static int		ValidateFormat(Tcl_Interp *interp, const char *format,
+			    int numVars, int *totalVars);
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * BuildCharSet --
+ *
+ *	This function examines a character set format specification and builds
+ *	a CharSet containing the individual characters and character ranges
+ *	specified.
+ *
+ * Results:
+ *	Returns the next format position.
+ *
+ * Side effects:
+ *	Initializes the charset.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static const char *
+BuildCharSet(
+    CharSet *cset,
+    const char *format)		/* Points to first char of set. */
+{
+    Tcl_UniChar ch, start;
+    int offset, nranges;
+    const char *end;
+
+    memset(cset, 0, sizeof(CharSet));
+
+    offset = Tcl_UtfToUniChar(format, &ch);
+    if (ch == '^') {
+	cset->exclude = 1;
+	format += offset;
+	offset = Tcl_UtfToUniChar(format, &ch);
+    }
+    end = format + offset;
+
+    /*
+     * Find the close bracket so we can overallocate the set.
+     */
+
+    if (ch == ']') {
+	end += Tcl_UtfToUniChar(end, &ch);
+    }
+    nranges = 0;
+    while (ch != ']') {
+	if (ch == '-') {
+	    nranges++;
+	}
+	end += Tcl_UtfToUniChar(end, &ch);
+    }
+
+    cset->chars = ckalloc(sizeof(Tcl_UniChar) * (end - format - 1));
+    if (nranges > 0) {
+	cset->ranges = ckalloc(sizeof(struct Range) * nranges);
+    } else {
+	cset->ranges = NULL;
+    }
+
+    /*
+     * Now build the character set.
+     */
+
+    cset->nchars = cset->nranges = 0;
+    format += Tcl_UtfToUniChar(format, &ch);
+    start = ch;
+    if (ch == ']' || ch == '-') {
+	cset->chars[cset->nchars++] = ch;
+	format += Tcl_UtfToUniChar(format, &ch);
+    }
+    while (ch != ']') {
+	if (*format == '-') {
+	    /*
+	     * This may be the first character of a range, so don't add it
+	     * yet.
+	     */
+
+	    start = ch;
+	} else if (ch == '-') {
+	    /*
+	     * Check to see if this is the last character in the set, in which
+	     * case it is not a range and we should add the previous character
+	     * as well as the dash.
+	     */
+
+	    if (*format == ']') {
+		cset->chars[cset->nchars++] = start;
+		cset->chars[cset->nchars++] = ch;
+	    } else {
+		format += Tcl_UtfToUniChar(format, &ch);
+
+		/*
+		 * Check to see if the range is in reverse order.
+		 */
+
+		if (start < ch) {
+		    cset->ranges[cset->nranges].start = start;
+		    cset->ranges[cset->nranges].end = ch;
+		} else {
+		    cset->ranges[cset->nranges].start = ch;
+		    cset->ranges[cset->nranges].end = start;
+		}
+		cset->nranges++;
+	    }
+	} else {
+	    cset->chars[cset->nchars++] = ch;
+	}
+	format += Tcl_UtfToUniChar(format, &ch);
+    }
+    return format;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * CharInSet --
+ *
+ *	Check to see if a character matches the given set.
+ *
+ * Results:
+ *	Returns non-zero if the character matches the given set.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+CharInSet(
+    CharSet *cset,
+    int c)			/* Character to test, passed as int because of
+				 * non-ANSI prototypes. */
+{
+    Tcl_UniChar ch = (Tcl_UniChar) c;
+    int i, match = 0;
+
+    for (i = 0; i < cset->nchars; i++) {
+	if (cset->chars[i] == ch) {
+	    match = 1;
+	    break;
+	}
+    }
+    if (!match) {
+	for (i = 0; i < cset->nranges; i++) {
+	    if ((cset->ranges[i].start <= ch) && (ch <= cset->ranges[i].end)) {
+		match = 1;
+		break;
+	    }
+	}
+    }
+    return (cset->exclude ? !match : match);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ReleaseCharSet --
+ *
+ *	Free the storage associated with a character set.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+ReleaseCharSet(
+    CharSet *cset)
+{
+    ckfree(cset->chars);
+    if (cset->ranges) {
+	ckfree(cset->ranges);
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ValidateFormat --
+ *
+ *	Parse the format string and verify that it is properly formed and that
+ *	there are exactly enough variables on the command line.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	May place an error in the interpreter result.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+ValidateFormat(
+    Tcl_Interp *interp,		/* Current interpreter. */
+    const char *format,		/* The format string. */
+    int numVars,		/* The number of variables passed to the scan
+				 * command. */
+    int *totalSubs)		/* The number of variables that will be
+				 * required. */
+{
+    int gotXpg, gotSequential, value, i, flags;
+    char *end;
+    Tcl_UniChar ch;
+    int objIndex, xpgSize, nspace = numVars;
+    int *nassign = TclStackAlloc(interp, nspace * sizeof(int));
+    char buf[TCL_UTF_MAX+1];
+    Tcl_Obj *errorMsg;		/* Place to build an error messages. Note that
+				 * these are messy operations because we do
+				 * not want to use the formatting engine;
+				 * we're inside there! */
+
+    /*
+     * Initialize an array that records the number of times a variable is
+     * assigned to by the format string. We use this to detect if a variable
+     * is multiply assigned or left unassigned.
+     */
+
+    for (i = 0; i < nspace; i++) {
+	nassign[i] = 0;
+    }
+
+    xpgSize = objIndex = gotXpg = gotSequential = 0;
+
+    while (*format != '\0') {
+	format += Tcl_UtfToUniChar(format, &ch);
+
+	flags = 0;
+
+	if (ch != '%') {
+	    continue;
+	}
+	format += Tcl_UtfToUniChar(format, &ch);
+	if (ch == '%') {
+	    continue;
+	}
+	if (ch == '*') {
+	    flags |= SCAN_SUPPRESS;
+	    format += Tcl_UtfToUniChar(format, &ch);
+	    goto xpgCheckDone;
+	}
+
+	if ((ch < 0x80) && isdigit(UCHAR(ch))) {	/* INTL: "C" locale. */
+	    /*
+	     * Check for an XPG3-style %n$ specification. Note: there must
+	     * not be a mixture of XPG3 specs and non-XPG3 specs in the same
+	     * format string.
+	     */
+
+	    value = strtoul(format-1, &end, 10);	/* INTL: "C" locale. */
+	    if (*end != '$') {
+		goto notXpg;
+	    }
+	    format = end+1;
+	    format += Tcl_UtfToUniChar(format, &ch);
+	    gotXpg = 1;
+	    if (gotSequential) {
+		goto mixedXPG;
+	    }
+	    objIndex = value - 1;
+	    if ((objIndex < 0) || (numVars && (objIndex >= numVars))) {
+		goto badIndex;
+	    } else if (numVars == 0) {
+		/*
+		 * In the case where no vars are specified, the user can
+		 * specify %9999$ legally, so we have to consider special
+		 * rules for growing the assign array. 'value' is guaranteed
+		 * to be > 0.
+		 */
+		xpgSize = (xpgSize > value) ? xpgSize : value;
+	    }
+	    goto xpgCheckDone;
+	}
+
+    notXpg:
+	gotSequential = 1;
+	if (gotXpg) {
+	mixedXPG:
+	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		    "cannot mix \"%\" and \"%n$\" conversion specifiers",
+		    -1));
+	    Tcl_SetErrorCode(interp, "TCL", "FORMAT", "MIXEDSPECTYPES", NULL);
+	    goto error;
+	}
+
+    xpgCheckDone:
+	/*
+	 * Parse any width specifier.
+	 */
+
+	if ((ch < 0x80) && isdigit(UCHAR(ch))) {	/* INTL: "C" locale. */
+	    value = strtoul(format-1, (char **) &format, 10);	/* INTL: "C" locale. */
+	    flags |= SCAN_WIDTH;
+	    format += Tcl_UtfToUniChar(format, &ch);
+	}
+
+	/*
+	 * Handle any size specifier.
+	 */
+
+	switch (ch) {
+	case 'l':
+	    if (*format == 'l') {
+		flags |= SCAN_BIG;
+		format += 1;
+		format += Tcl_UtfToUniChar(format, &ch);
+		break;
+	    }
+	case 'L':
+	    flags |= SCAN_LONGER;
+	case 'h':
+	    format += Tcl_UtfToUniChar(format, &ch);
+	}
+
+	if (!(flags & SCAN_SUPPRESS) && numVars && (objIndex >= numVars)) {
+	    goto badIndex;
+	}
+
+	/*
+	 * Handle the various field types.
+	 */
+
+	switch (ch) {
+	case 'c':
+	    if (flags & SCAN_WIDTH) {
+		Tcl_SetObjResult(interp, Tcl_NewStringObj(
+			"field width may not be specified in %c conversion",
+			-1));
+		Tcl_SetErrorCode(interp, "TCL", "FORMAT", "BADWIDTH", NULL);
+		goto error;
+	    }
+	    /*
+	     * Fall through!
+	     */
+	case 'n':
+	case 's':
+	    if (flags & (SCAN_LONGER|SCAN_BIG)) {
+	    invalidFieldSize:
+		buf[Tcl_UniCharToUtf(ch, buf)] = '\0';
+		errorMsg = Tcl_NewStringObj(
+			"field size modifier may not be specified in %", -1);
+		Tcl_AppendToObj(errorMsg, buf, -1);
+		Tcl_AppendToObj(errorMsg, " conversion", -1);
+		Tcl_SetObjResult(interp, errorMsg);
+		Tcl_SetErrorCode(interp, "TCL", "FORMAT", "BADSIZE", NULL);
+		goto error;
+	    }
+	    /*
+	     * Fall through!
+	     */
+	case 'd':
+	case 'e':
+	case 'E':
+	case 'f':
+	case 'g':
+	case 'G':
+	case 'i':
+	case 'o':
+	case 'x':
+	case 'X':
+	case 'b':
+	    break;
+	case 'u':
+	    if (flags & SCAN_BIG) {
+		Tcl_SetObjResult(interp, Tcl_NewStringObj(
+			"unsigned bignum scans are invalid", -1));
+		Tcl_SetErrorCode(interp, "TCL", "FORMAT", "BADUNSIGNED",NULL);
+		goto error;
+	    }
+	    break;
+	    /*
+	     * Bracket terms need special checking
+	     */
+	case '[':
+	    if (flags & (SCAN_LONGER|SCAN_BIG)) {
+		goto invalidFieldSize;
+	    }
+	    if (*format == '\0') {
+		goto badSet;
+	    }
+	    format += Tcl_UtfToUniChar(format, &ch);
+	    if (ch == '^') {
+		if (*format == '\0') {
+		    goto badSet;
+		}
+		format += Tcl_UtfToUniChar(format, &ch);
+	    }
+	    if (ch == ']') {
+		if (*format == '\0') {
+		    goto badSet;
+		}
+		format += Tcl_UtfToUniChar(format, &ch);
+	    }
+	    while (ch != ']') {
+		if (*format == '\0') {
+		    goto badSet;
+		}
+		format += Tcl_UtfToUniChar(format, &ch);
+	    }
+	    break;
+	badSet:
+	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		    "unmatched [ in format string", -1));
+	    Tcl_SetErrorCode(interp, "TCL", "FORMAT", "BRACKET", NULL);
+	    goto error;
+	default:
+	    buf[Tcl_UniCharToUtf(ch, buf)] = '\0';
+	    errorMsg = Tcl_NewStringObj(
+		    "bad scan conversion character \"", -1);
+	    Tcl_AppendToObj(errorMsg, buf, -1);
+	    Tcl_AppendToObj(errorMsg, "\"", -1);
+	    Tcl_SetObjResult(interp, errorMsg);
+	    Tcl_SetErrorCode(interp, "TCL", "FORMAT", "BADTYPE", NULL);
+	    goto error;
+	}
+	if (!(flags & SCAN_SUPPRESS)) {
+	    if (objIndex >= nspace) {
+		/*
+		 * Expand the nassign buffer. If we are using XPG specifiers,
+		 * make sure that we grow to a large enough size. xpgSize is
+		 * guaranteed to be at least one larger than objIndex.
+		 */
+
+		value = nspace;
+		if (xpgSize) {
+		    nspace = xpgSize;
+		} else {
+		    nspace += 16;	/* formerly STATIC_LIST_SIZE */
+		}
+		nassign = TclStackRealloc(interp, nassign,
+			nspace * sizeof(int));
+		for (i = value; i < nspace; i++) {
+		    nassign[i] = 0;
+		}
+	    }
+	    nassign[objIndex]++;
+	    objIndex++;
+	}
+    }
+
+    /*
+     * Verify that all of the variable were assigned exactly once.
+     */
+
+    if (numVars == 0) {
+	if (xpgSize) {
+	    numVars = xpgSize;
+	} else {
+	    numVars = objIndex;
+	}
+    }
+    if (totalSubs) {
+	*totalSubs = numVars;
+    }
+    for (i = 0; i < numVars; i++) {
+	if (nassign[i] > 1) {
+	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		    "variable is assigned by multiple \"%n$\" conversion specifiers",
+		    -1));
+	    Tcl_SetErrorCode(interp, "TCL", "FORMAT", "POLYASSIGNED", NULL);
+	    goto error;
+	} else if (!xpgSize && (nassign[i] == 0)) {
+	    /*
+	     * If the space is empty, and xpgSize is 0 (means XPG wasn't used,
+	     * and/or numVars != 0), then too many vars were given
+	     */
+
+	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		    "variable is not assigned by any conversion specifiers",
+		    -1));
+	    Tcl_SetErrorCode(interp, "TCL", "FORMAT", "UNASSIGNED", NULL);
+	    goto error;
+	}
+    }
+
+    TclStackFree(interp, nassign);
+    return TCL_OK;
+
+  badIndex:
+    if (gotXpg) {
+	Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		"\"%n$\" argument index out of range", -1));
+	Tcl_SetErrorCode(interp, "TCL", "FORMAT", "INDEXRANGE", NULL);
+    } else {
+	Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		"different numbers of variable names and field specifiers",
+		-1));
+	Tcl_SetErrorCode(interp, "TCL", "FORMAT", "FIELDVARMISMATCH", NULL);
+    }
+
+  error:
+    TclStackFree(interp, nassign);
+    return TCL_ERROR;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_ScanObjCmd --
+ *
+ *	This function is invoked to process the "scan" Tcl command. See the
+ *	user documentation for details on what it does.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+	/* ARGSUSED */
+int
+Tcl_ScanObjCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    const char *format;
+    int numVars, nconversions, totalVars = -1;
+    int objIndex, offset, i, result, code;
+    long value;
+    const char *string, *end, *baseString;
+    char op = 0;
+    int width, underflow = 0;
+    Tcl_WideInt wideValue;
+    Tcl_UniChar ch, sch;
+    Tcl_Obj **objs = NULL, *objPtr = NULL;
+    int flags;
+    char buf[513];		/* Temporary buffer to hold scanned number
+				 * strings before they are passed to
+				 * strtoul. */
+
+    if (objc < 3) {
+	Tcl_WrongNumArgs(interp, 1, objv,
+		"string format ?varName ...?");
+	return TCL_ERROR;
+    }
+
+    format = Tcl_GetString(objv[2]);
+    numVars = objc-3;
+
+    /*
+     * Check for errors in the format string.
+     */
+
+    if (ValidateFormat(interp, format, numVars, &totalVars) == TCL_ERROR) {
+	return TCL_ERROR;
+    }
+
+    /*
+     * Allocate space for the result objects.
+     */
+
+    if (totalVars > 0) {
+	objs = ckalloc(sizeof(Tcl_Obj *) * totalVars);
+	for (i = 0; i < totalVars; i++) {
+	    objs[i] = NULL;
+	}
+    }
+
+    string = Tcl_GetString(objv[1]);
+    baseString = string;
+
+    /*
+     * Iterate over the format string filling in the result objects until we
+     * reach the end of input, the end of the format string, or there is a
+     * mismatch.
+     */
+
+    objIndex = 0;
+    nconversions = 0;
+    while (*format != '\0') {
+	int parseFlag = TCL_PARSE_NO_WHITESPACE;
+	format += Tcl_UtfToUniChar(format, &ch);
+
+	flags = 0;
+
+	/*
+	 * If we see whitespace in the format, skip whitespace in the string.
+	 */
+
+	if (Tcl_UniCharIsSpace(ch)) {
+	    offset = Tcl_UtfToUniChar(string, &sch);
+	    while (Tcl_UniCharIsSpace(sch)) {
+		if (*string == '\0') {
+		    goto done;
+		}
+		string += offset;
+		offset = Tcl_UtfToUniChar(string, &sch);
+	    }
+	    continue;
+	}
+
+	if (ch != '%') {
+	literal:
+	    if (*string == '\0') {
+		underflow = 1;
+		goto done;
+	    }
+	    string += Tcl_UtfToUniChar(string, &sch);
+	    if (ch != sch) {
+		goto done;
+	    }
+	    continue;
+	}
+
+	format += Tcl_UtfToUniChar(format, &ch);
+	if (ch == '%') {
+	    goto literal;
+	}
+
+	/*
+	 * Check for assignment suppression ('*') or an XPG3-style assignment
+	 * ('%n$').
+	 */
+
+	if (ch == '*') {
+	    flags |= SCAN_SUPPRESS;
+	    format += Tcl_UtfToUniChar(format, &ch);
+	} else if ((ch < 0x80) && isdigit(UCHAR(ch))) {	/* INTL: "C" locale. */
+	    char *formatEnd;
+	    value = strtoul(format-1, &formatEnd, 10);/* INTL: "C" locale. */
+	    if (*formatEnd == '$') {
+		format = formatEnd+1;
+		format += Tcl_UtfToUniChar(format, &ch);
+		objIndex = (int) value - 1;
+	    }
+	}
+
+	/*
+	 * Parse any width specifier.
+	 */
+
+	if ((ch < 0x80) && isdigit(UCHAR(ch))) {	/* INTL: "C" locale. */
+	    width = (int) strtoul(format-1, (char **) &format, 10);/* INTL: "C" locale. */
+	    format += Tcl_UtfToUniChar(format, &ch);
+	} else {
+	    width = 0;
+	}
+
+	/*
+	 * Handle any size specifier.
+	 */
+
+	switch (ch) {
+	case 'l':
+	    if (*format == 'l') {
+		flags |= SCAN_BIG;
+		format += 1;
+		format += Tcl_UtfToUniChar(format, &ch);
+		break;
+	    }
+	case 'L':
+	    flags |= SCAN_LONGER;
+	    /*
+	     * Fall through so we skip to the next character.
+	     */
+	case 'h':
+	    format += Tcl_UtfToUniChar(format, &ch);
+	}
+
+	/*
+	 * Handle the various field types.
+	 */
+
+	switch (ch) {
+	case 'n':
+	    if (!(flags & SCAN_SUPPRESS)) {
+		objPtr = Tcl_NewIntObj(string - baseString);
+		Tcl_IncrRefCount(objPtr);
+		CLANG_ASSERT(objs);
+		objs[objIndex++] = objPtr;
+	    }
+	    nconversions++;
+	    continue;
+
+	case 'd':
+	    op = 'i';
+	    parseFlag |= TCL_PARSE_DECIMAL_ONLY;
+	    break;
+	case 'i':
+	    op = 'i';
+	    parseFlag |= TCL_PARSE_SCAN_PREFIXES;
+	    break;
+	case 'o':
+	    op = 'i';
+	    parseFlag |= TCL_PARSE_OCTAL_ONLY | TCL_PARSE_SCAN_PREFIXES;
+	    break;
+	case 'x':
+	case 'X':
+	    op = 'i';
+	    parseFlag |= TCL_PARSE_HEXADECIMAL_ONLY;
+	    break;
+	case 'b':
+	    op = 'i';
+	    parseFlag |= TCL_PARSE_BINARY_ONLY;
+	    break;
+	case 'u':
+	    op = 'i';
+	    parseFlag |= TCL_PARSE_DECIMAL_ONLY;
+	    flags |= SCAN_UNSIGNED;
+	    break;
+
+	case 'f':
+	case 'e':
+	case 'E':
+	case 'g':
+	case 'G':
+	    op = 'f';
+	    break;
+
+	case 's':
+	    op = 's';
+	    break;
+
+	case 'c':
+	    op = 'c';
+	    flags |= SCAN_NOSKIP;
+	    break;
+	case '[':
+	    op = '[';
+	    flags |= SCAN_NOSKIP;
+	    break;
+	}
+
+	/*
+	 * At this point, we will need additional characters from the string
+	 * to proceed.
+	 */
+
+	if (*string == '\0') {
+	    underflow = 1;
+	    goto done;
+	}
+
+	/*
+	 * Skip any leading whitespace at the beginning of a field unless the
+	 * format suppresses this behavior.
+	 */
+
+	if (!(flags & SCAN_NOSKIP)) {
+	    while (*string != '\0') {
+		offset = Tcl_UtfToUniChar(string, &sch);
+		if (!Tcl_UniCharIsSpace(sch)) {
+		    break;
+		}
+		string += offset;
+	    }
+	    if (*string == '\0') {
+		underflow = 1;
+		goto done;
+	    }
+	}
+
+	/*
+	 * Perform the requested scanning operation.
+	 */
+
+	switch (op) {
+	case 's':
+	    /*
+	     * Scan a string up to width characters or whitespace.
+	     */
+
+	    if (width == 0) {
+		width = ~0;
+	    }
+	    end = string;
+	    while (*end != '\0') {
+		offset = Tcl_UtfToUniChar(end, &sch);
+		if (Tcl_UniCharIsSpace(sch)) {
+		    break;
+		}
+		end += offset;
+		if (--width == 0) {
+		    break;
+		}
+	    }
+	    if (!(flags & SCAN_SUPPRESS)) {
+		objPtr = Tcl_NewStringObj(string, end-string);
+		Tcl_IncrRefCount(objPtr);
+		CLANG_ASSERT(objs);
+		objs[objIndex++] = objPtr;
+	    }
+	    string = end;
+	    break;
+
+	case '[': {
+	    CharSet cset;
+
+	    if (width == 0) {
+		width = ~0;
+	    }
+	    end = string;
+
+	    format = BuildCharSet(&cset, format);
+	    while (*end != '\0') {
+		offset = Tcl_UtfToUniChar(end, &sch);
+		if (!CharInSet(&cset, (int)sch)) {
+		    break;
+		}
+		end += offset;
+		if (--width == 0) {
+		    break;
+		}
+	    }
+	    ReleaseCharSet(&cset);
+
+	    if (string == end) {
+		/*
+		 * Nothing matched the range, stop processing.
+		 */
+		goto done;
+	    }
+	    if (!(flags & SCAN_SUPPRESS)) {
+		objPtr = Tcl_NewStringObj(string, end-string);
+		Tcl_IncrRefCount(objPtr);
+		objs[objIndex++] = objPtr;
+	    }
+	    string = end;
+
+	    break;
+	}
+	case 'c':
+	    /*
+	     * Scan a single Unicode character.
+	     */
+
+	    string += Tcl_UtfToUniChar(string, &sch);
+	    if (!(flags & SCAN_SUPPRESS)) {
+		objPtr = Tcl_NewIntObj((int)sch);
+		Tcl_IncrRefCount(objPtr);
+		CLANG_ASSERT(objs);
+		objs[objIndex++] = objPtr;
+	    }
+	    break;
+
+	case 'i':
+	    /*
+	     * Scan an unsigned or signed integer.
+	     */
+	    objPtr = Tcl_NewLongObj(0);
+	    Tcl_IncrRefCount(objPtr);
+	    if (width == 0) {
+		width = ~0;
+	    }
+	    if (TCL_OK != TclParseNumber(NULL, objPtr, NULL, string, width,
+		    &end, TCL_PARSE_INTEGER_ONLY | parseFlag)) {
+		Tcl_DecrRefCount(objPtr);
+		if (width < 0) {
+		    if (*end == '\0') {
+			underflow = 1;
+		    }
+		} else {
+		    if (end == string + width) {
+			underflow = 1;
+		    }
+		}
+		goto done;
+	    }
+	    string = end;
+	    if (flags & SCAN_SUPPRESS) {
+		Tcl_DecrRefCount(objPtr);
+		break;
+	    }
+	    if (flags & SCAN_LONGER) {
+		if (Tcl_GetWideIntFromObj(NULL, objPtr, &wideValue) != TCL_OK) {
+		    wideValue = ~(Tcl_WideUInt)0 >> 1;	/* WIDE_MAX */
+		    if (TclGetString(objPtr)[0] == '-') {
+			wideValue++;	/* WIDE_MAX + 1 = WIDE_MIN */
+		    }
+		}
+		if ((flags & SCAN_UNSIGNED) && (wideValue < 0)) {
+		    sprintf(buf, "%" TCL_LL_MODIFIER "u",
+			    (Tcl_WideUInt)wideValue);
+		    Tcl_SetStringObj(objPtr, buf, -1);
+		} else {
+		    Tcl_SetWideIntObj(objPtr, wideValue);
+		}
+	    } else if (!(flags & SCAN_BIG)) {
+		if (TclGetLongFromObj(NULL, objPtr, &value) != TCL_OK) {
+		    if (TclGetString(objPtr)[0] == '-') {
+			value = LONG_MIN;
+		    } else {
+			value = LONG_MAX;
+		    }
+		}
+		if ((flags & SCAN_UNSIGNED) && (value < 0)) {
+		    sprintf(buf, "%lu", value);	/* INTL: ISO digit */
+		    Tcl_SetStringObj(objPtr, buf, -1);
+		} else {
+		    Tcl_SetLongObj(objPtr, value);
+		}
+	    }
+	    objs[objIndex++] = objPtr;
+	    break;
+
+	case 'f':
+	    /*
+	     * Scan a floating point number
+	     */
+
+	    objPtr = Tcl_NewDoubleObj(0.0);
+	    Tcl_IncrRefCount(objPtr);
+	    if (width == 0) {
+		width = ~0;
+	    }
+	    if (TCL_OK != TclParseNumber(NULL, objPtr, NULL, string, width,
+		    &end, TCL_PARSE_DECIMAL_ONLY | TCL_PARSE_NO_WHITESPACE)) {
+		Tcl_DecrRefCount(objPtr);
+		if (width < 0) {
+		    if (*end == '\0') {
+			underflow = 1;
+		    }
+		} else {
+		    if (end == string + width) {
+			underflow = 1;
+		    }
+		}
+		goto done;
+	    } else if (flags & SCAN_SUPPRESS) {
+		Tcl_DecrRefCount(objPtr);
+		string = end;
+	    } else {
+		double dvalue;
+		if (Tcl_GetDoubleFromObj(NULL, objPtr, &dvalue) != TCL_OK) {
+#ifdef ACCEPT_NAN
+		    if (objPtr->typePtr == &tclDoubleType) {
+			dvalue = objPtr->internalRep.doubleValue;
+		    } else
+#endif
+		    {
+			Tcl_DecrRefCount(objPtr);
+			goto done;
+		    }
+		}
+		Tcl_SetDoubleObj(objPtr, dvalue);
+		CLANG_ASSERT(objs);
+		objs[objIndex++] = objPtr;
+		string = end;
+	    }
+	}
+	nconversions++;
+    }
+
+  done:
+    result = 0;
+    code = TCL_OK;
+
+    if (numVars) {
+	/*
+	 * In this case, variables were specified (classic scan).
+	 */
+
+	for (i = 0; i < totalVars; i++) {
+	    if (objs[i] == NULL) {
+		continue;
+	    }
+	    result++;
+
+	    /*
+	     * In case of multiple errors in setting variables, just report
+	     * the first one.
+	     */
+
+	    if (Tcl_ObjSetVar2(interp, objv[i+3], NULL, objs[i],
+		    (code == TCL_OK) ? TCL_LEAVE_ERR_MSG : 0) == NULL) {
+		code = TCL_ERROR;
+	    }
+	    Tcl_DecrRefCount(objs[i]);
+	}
+    } else {
+	/*
+	 * Here no vars were specified, we want a list returned (inline scan)
+	 */
+
+	objPtr = Tcl_NewObj();
+	for (i = 0; i < totalVars; i++) {
+	    if (objs[i] != NULL) {
+		Tcl_ListObjAppendElement(NULL, objPtr, objs[i]);
+		Tcl_DecrRefCount(objs[i]);
+	    } else {
+		/*
+		 * More %-specifiers than matching chars, so we just spit out
+		 * empty strings for these.
+		 */
+
+		Tcl_ListObjAppendElement(NULL, objPtr, Tcl_NewObj());
+	    }
+	}
+    }
+    if (objs != NULL) {
+	ckfree(objs);
+    }
+    if (code == TCL_OK) {
+	if (underflow && (nconversions == 0)) {
+	    if (numVars) {
+		objPtr = Tcl_NewIntObj(-1);
+	    } else {
+		if (objPtr) {
+		    Tcl_SetListObj(objPtr, 0, NULL);
+		} else {
+		    objPtr = Tcl_NewObj();
+		}
+	    }
+	} else if (numVars) {
+	    objPtr = Tcl_NewIntObj(result);
+	}
+	Tcl_SetObjResult(interp, objPtr);
+    }
+    return code;
+}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tclStrToD.c b/generic/tclStrToD.c
new file mode 100644
index 0000000..f69f6b9
--- /dev/null
+++ b/generic/tclStrToD.c
@@ -0,0 +1,5039 @@
+/*
+ * tclStrToD.c --
+ *
+ *	This file contains a collection of procedures for managing conversions
+ *	to/from floating-point in Tcl. They include TclParseNumber, which
+ *	parses numbers from strings; TclDoubleDigits, which formats numbers
+ *	into strings of digits, and procedures for interconversion among
+ *	'double' and 'mp_int' types.
+ *
+ * Copyright (c) 2005 by Kevin B. Kenny. All rights reserved.
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#include "tclInt.h"
+#include "tommath.h"
+#include <math.h>
+
+/*
+ * Define KILL_OCTAL to suppress interpretation of numbers with leading zero
+ * as octal. (Ceterum censeo: numeros octonarios delendos esse.)
+ */
+
+#undef	KILL_OCTAL
+
+/*
+ * This code supports (at least hypothetically), IBM, Cray, VAX and IEEE-754
+ * floating point; of these, only IEEE-754 can represent NaN. IEEE-754 can be
+ * uniquely determined by radix and by the widths of significand and exponent.
+ */
+
+#if (FLT_RADIX == 2) && (DBL_MANT_DIG == 53) && (DBL_MAX_EXP == 1024)
+#   define IEEE_FLOATING_POINT
+#endif
+
+/*
+ * Rounding controls. (Thanks a lot, Intel!)
+ */
+
+#ifdef __i386
+/*
+ * gcc on x86 needs access to rounding controls, because of a questionable
+ * feature where it retains intermediate results as IEEE 'long double' values
+ * somewhat unpredictably. It is tempting to include fpu_control.h, but that
+ * file exists only on Linux; it is missing on Cygwin and MinGW. Most gcc-isms
+ * and ix86-isms are factored out here.
+ */
+
+#if defined(__GNUC__)
+typedef unsigned int	fpu_control_t __attribute__ ((__mode__ (__HI__)));
+
+#define _FPU_GETCW(cw)	__asm__ __volatile__ ("fnstcw %0" : "=m" (*&cw))
+#define _FPU_SETCW(cw)	__asm__ __volatile__ ("fldcw %0" : : "m" (*&cw))
+#   define FPU_IEEE_ROUNDING	0x027f
+#   define ADJUST_FPU_CONTROL_WORD
+#define TCL_IEEE_DOUBLE_ROUNDING \
+    fpu_control_t roundTo53Bits = FPU_IEEE_ROUNDING;	\
+    fpu_control_t oldRoundingMode;			\
+    _FPU_GETCW(oldRoundingMode);			\
+    _FPU_SETCW(roundTo53Bits)
+#define TCL_DEFAULT_DOUBLE_ROUNDING \
+    _FPU_SETCW(oldRoundingMode)
+
+/*
+ * Sun ProC needs sunmath for rounding control on x86 like gcc above.
+ */
+#elif defined(__sun)
+#include <sunmath.h>
+#define TCL_IEEE_DOUBLE_ROUNDING \
+    ieee_flags("set","precision","double",NULL)
+#define TCL_DEFAULT_DOUBLE_ROUNDING \
+    ieee_flags("clear","precision",NULL,NULL)
+
+/*
+ * Other platforms are assumed to always operate in full IEEE mode, so we make
+ * the macros to go in and out of that mode do nothing.
+ */
+
+#else /* !__GNUC__ && !__sun */
+#define TCL_IEEE_DOUBLE_ROUNDING	((void) 0)
+#define TCL_DEFAULT_DOUBLE_ROUNDING	((void) 0)
+#endif
+#else /* !__i386 */
+#define TCL_IEEE_DOUBLE_ROUNDING	((void) 0)
+#define TCL_DEFAULT_DOUBLE_ROUNDING	((void) 0)
+#endif
+
+/*
+ * MIPS floating-point units need special settings in control registers to use
+ * gradual underflow as we expect.  This fix is for the MIPSpro compiler.
+ */
+
+#if defined(__sgi) && defined(_COMPILER_VERSION)
+#include <sys/fpu.h>
+#endif
+
+/*
+ * HP's PA_RISC architecture uses 7ff4000000000000 to represent a quiet NaN.
+ * Everyone else uses 7ff8000000000000. (Why, HP, why?)
+ */
+
+#ifdef __hppa
+#   define NAN_START	0x7ff4
+#   define NAN_MASK	(((Tcl_WideUInt) 1) << 50)
+#else
+#   define NAN_START	0x7ff8
+#   define NAN_MASK	(((Tcl_WideUInt) 1) << 51)
+#endif
+
+/*
+ * Constants used by this file (most of which are only ever calculated at
+ * runtime).
+ */
+
+/* Magic constants */
+
+#define LOG10_2 0.3010299956639812
+#define TWO_OVER_3LOG10 0.28952965460216784
+#define LOG10_3HALVES_PLUS_FUDGE 0.1760912590558
+
+/*
+ * Definitions of the parts of an IEEE754-format floating point number.
+ */
+
+#define SIGN_BIT 	0x80000000
+				/* Mask for the sign bit in the first word of
+				 * a double. */
+#define EXP_MASK	0x7ff00000
+				/* Mask for the exponent field in the first
+				 * word of a double. */
+#define EXP_SHIFT	20	/* Shift count to make the exponent an
+				 * integer. */
+#define HIDDEN_BIT	(((Tcl_WideUInt) 0x00100000) << 32)
+				/* Hidden 1 bit for the significand. */
+#define HI_ORDER_SIG_MASK 0x000fffff
+				/* Mask for the high-order part of the
+				 * significand in the first word of a
+				 * double. */
+#define SIG_MASK	(((Tcl_WideUInt) HI_ORDER_SIG_MASK << 32) \
+			| 0xffffffff)
+				/* Mask for the 52-bit significand. */
+#define FP_PRECISION	53	/* Number of bits of significand plus the
+				 * hidden bit. */
+#define EXPONENT_BIAS	0x3ff	/* Bias of the exponent 0. */
+
+/*
+ * Derived quantities.
+ */
+
+#define TEN_PMAX	22	/* floor(FP_PRECISION*log(2)/log(5)) */
+#define QUICK_MAX	14	/* floor((FP_PRECISION-1)*log(2)/log(10))-1 */
+#define BLETCH		0x10	/* Highest power of two that is greater than
+				 * DBL_MAX_10_EXP, divided by 16. */
+#define DIGIT_GROUP	8	/* floor(DIGIT_BIT*log(2)/log(10)) */
+
+/*
+ * Union used to dismantle floating point numbers.
+ */
+
+typedef union Double {
+    struct {
+#ifdef WORDS_BIGENDIAN
+	int word0;
+	int word1;
+#else
+	int word1;
+	int word0;
+#endif
+    } w;
+    double d;
+    Tcl_WideUInt q;
+} Double;
+
+static int maxpow10_wide;	/* The powers of ten that can be represented
+				 * exactly as wide integers. */
+static Tcl_WideUInt *pow10_wide;
+#define MAXPOW	22
+static double pow10vals[MAXPOW+1];
+				/* The powers of ten that can be represented
+				 * exactly as IEEE754 doubles. */
+static int mmaxpow;		/* Largest power of ten that can be
+				 * represented exactly in a 'double'. */
+static int log10_DIGIT_MAX;	/* The number of decimal digits that fit in an
+				 * mp_digit. */
+static int log2FLT_RADIX;	/* Logarithm of the floating point radix. */
+static int mantBits;		/* Number of bits in a double's significand */
+static mp_int pow5[9];		/* Table of powers of 5**(2**n), up to
+				 * 5**256 */
+static double tiny = 0.0;	/* The smallest representable double. */
+static int maxDigits;		/* The maximum number of digits to the left of
+				 * the decimal point of a double. */
+static int minDigits;		/* The maximum number of digits to the right
+				 * of the decimal point in a double. */
+static const double pow_10_2_n[] = {	/* Inexact higher powers of ten. */
+    1.0,
+    100.0,
+    10000.0,
+    1.0e+8,
+    1.0e+16,
+    1.0e+32,
+    1.0e+64,
+    1.0e+128,
+    1.0e+256
+};
+
+static int n770_fp;		/* Flag is 1 on Nokia N770 floating point.
+				 * Nokia's floating point has the words
+				 * reversed: if big-endian is 7654 3210,
+				 * and little-endian is       0123 4567,
+				 * then Nokia's FP is         4567 0123;
+				 * little-endian within the 32-bit words but
+				 * big-endian between them. */
+
+/*
+ * Table of powers of 5 that are small enough to fit in an mp_digit.
+ */
+
+static const mp_digit dpow5[13] = {
+               1,              5,             25,            125,
+             625,           3125,          15625,          78125,
+          390625,        1953125,        9765625,       48828125,
+       244140625
+};
+
+/*
+ * Table of powers: pow5_13[n] = 5**(13*2**(n+1))
+ */
+
+static mp_int pow5_13[5];	/* Table of powers: 5**13, 5**26, 5**52,
+				 * 5**104, 5**208 */
+static const double tens[] = {
+    1e00, 1e01, 1e02, 1e03, 1e04, 1e05, 1e06, 1e07, 1e08, 1e09,
+    1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,
+    1e20, 1e21, 1e22
+};
+
+static const int itens [] = {
+    1,
+    10,
+    100,
+    1000,
+    10000,
+    100000,
+    1000000,
+    10000000,
+    100000000
+};
+
+static const double bigtens[] = {
+    1e016, 1e032, 1e064, 1e128, 1e256
+};
+#define N_BIGTENS 5
+
+static const int log2pow5[27] = {
+    01,  3,  5,  7, 10, 12, 14, 17, 19, 21,
+    24, 26, 28, 31, 33, 35, 38, 40, 42, 45,
+    47, 49, 52, 54, 56, 59, 61
+};
+#define N_LOG2POW5 27
+
+static const Tcl_WideUInt wuipow5[27] = {
+    (Tcl_WideUInt) 1,		/* 5**0 */
+    (Tcl_WideUInt) 5,
+    (Tcl_WideUInt) 25,
+    (Tcl_WideUInt) 125,
+    (Tcl_WideUInt) 625,
+    (Tcl_WideUInt) 3125,	/* 5**5 */
+    (Tcl_WideUInt) 3125*5,
+    (Tcl_WideUInt) 3125*25,
+    (Tcl_WideUInt) 3125*125,
+    (Tcl_WideUInt) 3125*625,
+    (Tcl_WideUInt) 3125*3125,	/* 5**10 */
+    (Tcl_WideUInt) 3125*3125*5,
+    (Tcl_WideUInt) 3125*3125*25,
+    (Tcl_WideUInt) 3125*3125*125,
+    (Tcl_WideUInt) 3125*3125*625,
+    (Tcl_WideUInt) 3125*3125*3125, /* 5**15 */
+    (Tcl_WideUInt) 3125*3125*3125*5,
+    (Tcl_WideUInt) 3125*3125*3125*25,
+    (Tcl_WideUInt) 3125*3125*3125*125,
+    (Tcl_WideUInt) 3125*3125*3125*625,
+    (Tcl_WideUInt) 3125*3125*3125*3125,	/* 5**20 */
+    (Tcl_WideUInt) 3125*3125*3125*3125*5,
+    (Tcl_WideUInt) 3125*3125*3125*3125*25,
+    (Tcl_WideUInt) 3125*3125*3125*3125*125,
+    (Tcl_WideUInt) 3125*3125*3125*3125*625,
+    (Tcl_WideUInt) 3125*3125*3125*3125*3125,  /* 5**25 */
+    (Tcl_WideUInt) 3125*3125*3125*3125*3125*5 /* 5**26 */
+};
+
+/*
+ * Static functions defined in this file.
+ */
+
+static int		AccumulateDecimalDigit(unsigned, int,
+			    Tcl_WideUInt *, mp_int *, int);
+static double		MakeHighPrecisionDouble(int signum,
+			    mp_int *significand, int nSigDigs, int exponent);
+static double		MakeLowPrecisionDouble(int signum,
+			    Tcl_WideUInt significand, int nSigDigs,
+			    int exponent);
+#ifdef IEEE_FLOATING_POINT
+static double		MakeNaN(int signum, Tcl_WideUInt tag);
+#endif
+static double		RefineApproximation(double approx,
+			    mp_int *exactSignificand, int exponent);
+static void		MulPow5(mp_int *, unsigned, mp_int *);
+static int 		NormalizeRightward(Tcl_WideUInt *);
+static int		RequiredPrecision(Tcl_WideUInt);
+static void		DoubleToExpAndSig(double, Tcl_WideUInt *, int *,
+			    int *);
+static void		TakeAbsoluteValue(Double *, int *);
+static char *		FormatInfAndNaN(Double *, int *, char **);
+static char *		FormatZero(int *, char **);
+static int		ApproximateLog10(Tcl_WideUInt, int, int);
+static int		BetterLog10(double, int, int *);
+static void		ComputeScale(int, int, int *, int *, int *, int *);
+static void		SetPrecisionLimits(int, int, int *, int *, int *,
+			    int *);
+static char *		BumpUp(char *, char *, int *);
+static int		AdjustRange(double *, int);
+static char *		ShorteningQuickFormat(double, int, int, double,
+			    char *, int *);
+static char *		StrictQuickFormat(double, int, int, double,
+			    char *, int *);
+static char *		QuickConversion(double, int, int, int, int, int, int,
+			    int *, char **);
+static void		CastOutPowersOf2(int *, int *, int *);
+static char *		ShorteningInt64Conversion(Double *, int, Tcl_WideUInt,
+			    int, int, int, int, int, int, int, int, int,
+			    int, int, int *, char **);
+static char *		StrictInt64Conversion(Double *, int, Tcl_WideUInt,
+			    int, int, int, int, int, int,
+			    int, int, int *, char **);
+static int		ShouldBankerRoundUpPowD(mp_int *, int, int);
+static int		ShouldBankerRoundUpToNextPowD(mp_int *, mp_int *,
+			    int, int, int, mp_int *);
+static char *		ShorteningBignumConversionPowD(Double *dPtr,
+			    int convType, Tcl_WideUInt bw, int b2, int b5,
+			    int m2plus, int m2minus, int m5,
+			    int sd, int k, int len,
+			    int ilim, int ilim1, int *decpt,
+			    char **endPtr);
+static char *		StrictBignumConversionPowD(Double *dPtr, int convType,
+			    Tcl_WideUInt bw, int b2, int b5,
+			    int sd, int k, int len,
+			    int ilim, int ilim1, int *decpt,
+			    char **endPtr);
+static int		ShouldBankerRoundUp(mp_int *, mp_int *, int);
+static int		ShouldBankerRoundUpToNext(mp_int *, mp_int *,
+			    mp_int *, int, int, mp_int *);
+static char *		ShorteningBignumConversion(Double *dPtr, int convType,
+			    Tcl_WideUInt bw, int b2,
+			    int m2plus, int m2minus,
+			    int s2, int s5, int k, int len,
+			    int ilim, int ilim1, int *decpt,
+			    char **endPtr);
+static char *		StrictBignumConversion(Double *dPtr, int convType,
+			    Tcl_WideUInt bw, int b2,
+			    int s2, int s5, int k, int len,
+			    int ilim, int ilim1, int *decpt,
+			    char **endPtr);
+static double		BignumToBiasedFrExp(const mp_int *big, int *machexp);
+static double		Pow10TimesFrExp(int exponent, double fraction,
+			    int *machexp);
+static double		SafeLdExp(double fraction, int exponent);
+#ifdef IEEE_FLOATING_POINT
+static Tcl_WideUInt	Nokia770Twiddle(Tcl_WideUInt w);
+#endif
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclParseNumber --
+ *
+ *	Scans bytes, interpreted as characters in Tcl's internal encoding, and
+ *	parses the longest prefix that is the string representation of a
+ *	number in a format recognized by Tcl.
+ *
+ *	The arguments bytes, numBytes, and objPtr are the inputs which
+ *	determine the string to be parsed. If bytes is non-NULL, it points to
+ *	the first byte to be scanned. If bytes is NULL, then objPtr must be
+ *	non-NULL, and the string representation of objPtr will be scanned
+ *	(generated first, if necessary). The numBytes argument determines the
+ *	number of bytes to be scanned. If numBytes is negative, the first NUL
+ *	byte encountered will terminate the scan. If numBytes is non-negative,
+ *	then no more than numBytes bytes will be scanned.
+ *
+ *	The argument flags is an input that controls the numeric formats
+ *	recognized by the parser. The flag bits are:
+ *
+ *	- TCL_PARSE_INTEGER_ONLY:	accept only integer values; reject
+ *		strings that denote floating point values (or accept only the
+ *		leading portion of them that are integer values).
+ *	- TCL_PARSE_SCAN_PREFIXES:	ignore the prefixes 0b and 0o that are
+ *		not part of the [scan] command's vocabulary. Use only in
+ *		combination with TCL_PARSE_INTEGER_ONLY.
+ *	- TCL_PARSE_OCTAL_ONLY:		parse only in the octal format, whether
+ *		or not a prefix is present that would lead to octal parsing.
+ *		Use only in combination with TCL_PARSE_INTEGER_ONLY.
+ *	- TCL_PARSE_HEXADECIMAL_ONLY:	parse only in the hexadecimal format,
+ *		whether or not a prefix is present that would lead to
+ *		hexadecimal parsing. Use only in combination with
+ *		TCL_PARSE_INTEGER_ONLY.
+ *	- TCL_PARSE_DECIMAL_ONLY:	parse only in the decimal format, no
+ *		matter whether a 0 prefix would normally force a different
+ *		base.
+ *	- TCL_PARSE_NO_WHITESPACE:	reject any leading/trailing whitespace
+ *
+ *	The arguments interp and expected are inputs that control error
+ *	message generation. If interp is NULL, no error message will be
+ *	generated. If interp is non-NULL, then expected must also be non-NULL.
+ *	When TCL_ERROR is returned, an error message will be left in the
+ *	result of interp, and the expected argument will appear in the error
+ *	message as the thing TclParseNumber expected, but failed to find in
+ *	the string.
+ *
+ *	The arguments objPtr and endPtrPtr as well as the return code are the
+ *	outputs.
+ *
+ *	When the parser cannot find any prefix of the string that matches a
+ *	format it is looking for, TCL_ERROR is returned and an error message
+ *	may be generated and returned as described above. The contents of
+ *	objPtr will not be changed. If endPtrPtr is non-NULL, a pointer to the
+ *	character in the string that terminated the scan will be written to
+ *	*endPtrPtr.
+ *
+ *	When the parser determines that the entire string matches a format it
+ *	is looking for, TCL_OK is returned, and if objPtr is non-NULL, then
+ *	the internal rep and Tcl_ObjType of objPtr are set to the "canonical"
+ *	numeric value that matches the scanned string. If endPtrPtr is not
+ *	NULL, a pointer to the end of the string will be written to *endPtrPtr
+ *	(that is, either bytes+numBytes or a pointer to a terminating NUL
+ *	byte).
+ *
+ *	When the parser determines that a partial string matches a format it
+ *	is looking for, the value of endPtrPtr determines what happens:
+ *
+ *	- If endPtrPtr is NULL, then TCL_ERROR is returned, with error message
+ *		generation as above.
+ *
+ *	- If endPtrPtr is non-NULL, then TCL_OK is returned and objPtr
+ *		internals are set as above. Also, a pointer to the first
+ *		character following the parsed numeric string is written to
+ *		*endPtrPtr.
+ *
+ *	In some cases where the string being scanned is the string rep of
+ *	objPtr, this routine can leave objPtr in an inconsistent state where
+ *	its string rep and its internal rep do not agree. In these cases the
+ *	internal rep will be in agreement with only some substring of the
+ *	string rep. This might happen if the caller passes in a non-NULL bytes
+ *	value that points somewhere into the string rep. It might happen if
+ *	the caller passes in a numBytes value that limits the scan to only a
+ *	prefix of the string rep. Or it might happen if a non-NULL value of
+ *	endPtrPtr permits a TCL_OK return from only a partial string match. It
+ *	is the responsibility of the caller to detect and correct such
+ *	inconsistencies when they can and do arise.
+ *
+ * Results:
+ *	Returns a standard Tcl result.
+ *
+ * Side effects:
+ *	The string representaton of objPtr may be generated.
+ *
+ *	The internal representation and Tcl_ObjType of objPtr may be changed.
+ *	This may involve allocation and/or freeing of memory.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclParseNumber(
+    Tcl_Interp *interp,		/* Used for error reporting. May be NULL. */
+    Tcl_Obj *objPtr,		/* Object to receive the internal rep. */
+    const char *expected,	/* Description of the type of number the
+				 * caller expects to be able to parse
+				 * ("integer", "boolean value", etc.). */
+    const char *bytes,		/* Pointer to the start of the string to
+				 * scan. */
+    int numBytes,		/* Maximum number of bytes to scan, see
+				 * above. */
+    const char **endPtrPtr,	/* Place to store pointer to the character
+				 * that terminated the scan. */
+    int flags)			/* Flags governing the parse. */
+{
+    enum State {
+	INITIAL, SIGNUM, ZERO, ZERO_X,
+	ZERO_O, ZERO_B, BINARY,
+	HEXADECIMAL, OCTAL, BAD_OCTAL, DECIMAL,
+	LEADING_RADIX_POINT, FRACTION,
+	EXPONENT_START, EXPONENT_SIGNUM, EXPONENT,
+	sI, sIN, sINF, sINFI, sINFIN, sINFINI, sINFINIT, sINFINITY
+#ifdef IEEE_FLOATING_POINT
+	, sN, sNA, sNAN, sNANPAREN, sNANHEX, sNANFINISH
+#endif
+    } state = INITIAL;
+    enum State acceptState = INITIAL;
+
+    int signum = 0;		/* Sign of the number being parsed. */
+    Tcl_WideUInt significandWide = 0;
+				/* Significand of the number being parsed (if
+				 * no overflow). */
+    mp_int significandBig;	/* Significand of the number being parsed (if
+				 * it overflows significandWide). */
+    int significandOverflow = 0;/* Flag==1 iff significandBig is used. */
+    Tcl_WideUInt octalSignificandWide = 0;
+				/* Significand of an octal number; needed
+				 * because we don't know whether a number with
+				 * a leading zero is octal or decimal until
+				 * we've scanned forward to a '.' or 'e'. */
+    mp_int octalSignificandBig;	/* Significand of octal number once
+				 * octalSignificandWide overflows. */
+    int octalSignificandOverflow = 0;
+				/* Flag==1 if octalSignificandBig is used. */
+    int numSigDigs = 0;		/* Number of significant digits in the decimal
+				 * significand. */
+    int numTrailZeros = 0;	/* Number of trailing zeroes at the current
+				 * point in the parse. */
+    int numDigitsAfterDp = 0;	/* Number of digits scanned after the decimal
+				 * point. */
+    int exponentSignum = 0;	/* Signum of the exponent of a floating point
+				 * number. */
+    long exponent = 0;		/* Exponent of a floating point number. */
+    const char *p;		/* Pointer to next character to scan. */
+    size_t len;			/* Number of characters remaining after p. */
+    const char *acceptPoint;	/* Pointer to position after last character in
+				 * an acceptable number. */
+    size_t acceptLen;		/* Number of characters following that
+				 * point. */
+    int status = TCL_OK;	/* Status to return to caller. */
+    char d = 0;			/* Last hexadecimal digit scanned; initialized
+				 * to avoid a compiler warning. */
+    int shift = 0;		/* Amount to shift when accumulating binary */
+    int explicitOctal = 0;
+
+#define ALL_BITS	(~(Tcl_WideUInt)0)
+#define MOST_BITS	(ALL_BITS >> 1)
+
+    /*
+     * Initialize bytes to start of the object's string rep if the caller
+     * didn't pass anything else.
+     */
+
+    if (bytes == NULL) {
+	bytes = TclGetString(objPtr);
+    }
+
+    p = bytes;
+    len = numBytes;
+    acceptPoint = p;
+    acceptLen = len;
+    while (1) {
+	char c = len ? *p : '\0';
+	switch (state) {
+
+	case INITIAL:
+	    /*
+	     * Initial state. Acceptable characters are +, -, digits, period,
+	     * I, N, and whitespace.
+	     */
+
+	    if (TclIsSpaceProc(c)) {
+		if (flags & TCL_PARSE_NO_WHITESPACE) {
+		    goto endgame;
+		}
+		break;
+	    } else if (c == '+') {
+		state = SIGNUM;
+		break;
+	    } else if (c == '-') {
+		signum = 1;
+		state = SIGNUM;
+		break;
+	    }
+	    /* FALLTHROUGH */
+
+	case SIGNUM:
+	    /*
+	     * Scanned a leading + or -. Acceptable characters are digits,
+	     * period, I, and N.
+	     */
+
+	    if (c == '0') {
+		if (flags & TCL_PARSE_DECIMAL_ONLY) {
+		    state = DECIMAL;
+		} else {
+		    state = ZERO;
+		}
+		break;
+	    } else if (flags & TCL_PARSE_HEXADECIMAL_ONLY) {
+		goto zerox;
+	    } else if (flags & TCL_PARSE_BINARY_ONLY) {
+		goto zerob;
+	    } else if (flags & TCL_PARSE_OCTAL_ONLY) {
+		goto zeroo;
+	    } else if (isdigit(UCHAR(c))) {
+		significandWide = c - '0';
+		numSigDigs = 1;
+		state = DECIMAL;
+		break;
+	    } else if (flags & TCL_PARSE_INTEGER_ONLY) {
+		goto endgame;
+	    } else if (c == '.') {
+		state = LEADING_RADIX_POINT;
+		break;
+	    } else if (c == 'I' || c == 'i') {
+		state = sI;
+		break;
+#ifdef IEEE_FLOATING_POINT
+	    } else if (c == 'N' || c == 'n') {
+		state = sN;
+		break;
+#endif
+	    }
+	    goto endgame;
+
+	case ZERO:
+	    /*
+	     * Scanned a leading zero (perhaps with a + or -). Acceptable
+	     * inputs are digits, period, X, b, and E. If 8 or 9 is
+	     * encountered, the number can't be octal. This state and the
+	     * OCTAL state differ only in whether they recognize 'X' and 'b'.
+	     */
+
+	    acceptState = state;
+	    acceptPoint = p;
+	    acceptLen = len;
+	    if (c == 'x' || c == 'X') {
+		state = ZERO_X;
+		break;
+	    }
+	    if (flags & TCL_PARSE_HEXADECIMAL_ONLY) {
+		goto zerox;
+	    }
+	    if (flags & TCL_PARSE_SCAN_PREFIXES) {
+		goto zeroo;
+	    }
+	    if (c == 'b' || c == 'B') {
+		state = ZERO_B;
+		break;
+	    }
+	    if (flags & TCL_PARSE_BINARY_ONLY) {
+		goto zerob;
+	    }
+	    if (c == 'o' || c == 'O') {
+		explicitOctal = 1;
+		state = ZERO_O;
+		break;
+	    }
+#ifdef KILL_OCTAL
+	    goto decimal;
+#endif
+	    /* FALLTHROUGH */
+
+	case OCTAL:
+	    /*
+	     * Scanned an optional + or -, followed by a string of octal
+	     * digits. Acceptable inputs are more digits, period, or E. If 8
+	     * or 9 is encountered, commit to floating point.
+	     */
+
+	    acceptState = state;
+	    acceptPoint = p;
+	    acceptLen = len;
+	    /* FALLTHROUGH */
+	case ZERO_O:
+	zeroo:
+	    if (c == '0') {
+		numTrailZeros++;
+		state = OCTAL;
+		break;
+	    } else if (c >= '1' && c <= '7') {
+		if (objPtr != NULL) {
+		    shift = 3 * (numTrailZeros + 1);
+		    significandOverflow = AccumulateDecimalDigit(
+			    (unsigned)(c-'0'), numTrailZeros,
+			    &significandWide, &significandBig,
+			    significandOverflow);
+
+		    if (!octalSignificandOverflow) {
+			/*
+			 * Shifting by more bits than are in the value being
+			 * shifted is at least de facto nonportable. Check for
+			 * too large shifts first.
+			 */
+
+			if ((octalSignificandWide != 0)
+				&& (((size_t)shift >=
+					CHAR_BIT*sizeof(Tcl_WideUInt))
+				|| (octalSignificandWide >
+					(~(Tcl_WideUInt)0 >> shift)))) {
+			    octalSignificandOverflow = 1;
+			    TclBNInitBignumFromWideUInt(&octalSignificandBig,
+				    octalSignificandWide);
+			}
+		    }
+		    if (!octalSignificandOverflow) {
+			octalSignificandWide =
+				(octalSignificandWide << shift) + (c - '0');
+		    } else {
+			mp_mul_2d(&octalSignificandBig, shift,
+				&octalSignificandBig);
+			mp_add_d(&octalSignificandBig, (mp_digit)(c - '0'),
+				&octalSignificandBig);
+		    }
+		}
+		if (numSigDigs != 0) {
+		    numSigDigs += numTrailZeros+1;
+		} else {
+		    numSigDigs = 1;
+		}
+		numTrailZeros = 0;
+		state = OCTAL;
+		break;
+	    }
+	    /* FALLTHROUGH */
+
+	case BAD_OCTAL:
+	    if (explicitOctal) {
+		/*
+		 * No forgiveness for bad digits in explicitly octal numbers.
+		 */
+
+		goto endgame;
+	    }
+	    if (flags & TCL_PARSE_INTEGER_ONLY) {
+		/*
+		 * No seeking floating point when parsing only integer.
+		 */
+
+		goto endgame;
+	    }
+#ifndef KILL_OCTAL
+
+	    /*
+	     * Scanned a number with a leading zero that contains an 8, 9,
+	     * radix point or E. This is an invalid octal number, but might
+	     * still be floating point.
+	     */
+
+	    if (c == '0') {
+		numTrailZeros++;
+		state = BAD_OCTAL;
+		break;
+	    } else if (isdigit(UCHAR(c))) {
+		if (objPtr != NULL) {
+		    significandOverflow = AccumulateDecimalDigit(
+			    (unsigned)(c-'0'), numTrailZeros,
+			    &significandWide, &significandBig,
+			    significandOverflow);
+		}
+		if (numSigDigs != 0) {
+		    numSigDigs += (numTrailZeros + 1);
+		} else {
+		    numSigDigs = 1;
+		}
+		numTrailZeros = 0;
+		state = BAD_OCTAL;
+		break;
+	    } else if (c == '.') {
+		state = FRACTION;
+		break;
+	    } else if (c == 'E' || c == 'e') {
+		state = EXPONENT_START;
+		break;
+	    }
+#endif
+	    goto endgame;
+
+	    /*
+	     * Scanned 0x. If state is HEXADECIMAL, scanned at least one
+	     * character following the 0x. The only acceptable inputs are
+	     * hexadecimal digits.
+	     */
+
+	case HEXADECIMAL:
+	    acceptState = state;
+	    acceptPoint = p;
+	    acceptLen = len;
+	    /* FALLTHROUGH */
+
+	case ZERO_X:
+	zerox:
+	    if (c == '0') {
+		numTrailZeros++;
+		state = HEXADECIMAL;
+		break;
+	    } else if (isdigit(UCHAR(c))) {
+		d = (c-'0');
+	    } else if (c >= 'A' && c <= 'F') {
+		d = (c-'A'+10);
+	    } else if (c >= 'a' && c <= 'f') {
+		d = (c-'a'+10);
+	    } else {
+		goto endgame;
+	    }
+	    if (objPtr != NULL) {
+		shift = 4 * (numTrailZeros + 1);
+		if (!significandOverflow) {
+		    /*
+		     * Shifting by more bits than are in the value being
+		     * shifted is at least de facto nonportable. Check for too
+		     * large shifts first.
+		     */
+
+		    if (significandWide != 0 &&
+			    ((size_t)shift >= CHAR_BIT*sizeof(Tcl_WideUInt) ||
+			    significandWide > (~(Tcl_WideUInt)0 >> shift))) {
+			significandOverflow = 1;
+			TclBNInitBignumFromWideUInt(&significandBig,
+				significandWide);
+		    }
+		}
+		if (!significandOverflow) {
+		    significandWide = (significandWide << shift) + d;
+		} else {
+		    mp_mul_2d(&significandBig, shift, &significandBig);
+		    mp_add_d(&significandBig, (mp_digit) d, &significandBig);
+		}
+	    }
+	    numTrailZeros = 0;
+	    state = HEXADECIMAL;
+	    break;
+
+	case BINARY:
+	    acceptState = state;
+	    acceptPoint = p;
+	    acceptLen = len;
+	case ZERO_B:
+	zerob:
+	    if (c == '0') {
+		numTrailZeros++;
+		state = BINARY;
+		break;
+	    } else if (c != '1') {
+		goto endgame;
+	    }
+	    if (objPtr != NULL) {
+		shift = numTrailZeros + 1;
+		if (!significandOverflow) {
+		    /*
+		     * Shifting by more bits than are in the value being
+		     * shifted is at least de facto nonportable. Check for too
+		     * large shifts first.
+		     */
+
+		    if (significandWide != 0 &&
+			    ((size_t)shift >= CHAR_BIT*sizeof(Tcl_WideUInt) ||
+			    significandWide > (~(Tcl_WideUInt)0 >> shift))) {
+			significandOverflow = 1;
+			TclBNInitBignumFromWideUInt(&significandBig,
+				significandWide);
+		    }
+		}
+		if (!significandOverflow) {
+		    significandWide = (significandWide << shift) + 1;
+		} else {
+		    mp_mul_2d(&significandBig, shift, &significandBig);
+		    mp_add_d(&significandBig, (mp_digit) 1, &significandBig);
+		}
+	    }
+	    numTrailZeros = 0;
+	    state = BINARY;
+	    break;
+
+	case DECIMAL:
+	    /*
+	     * Scanned an optional + or - followed by a string of decimal
+	     * digits.
+	     */
+
+#ifdef KILL_OCTAL
+	decimal:
+#endif
+	    acceptState = state;
+	    acceptPoint = p;
+	    acceptLen = len;
+	    if (c == '0') {
+		numTrailZeros++;
+		state = DECIMAL;
+		break;
+	    } else if (isdigit(UCHAR(c))) {
+		if (objPtr != NULL) {
+		    significandOverflow = AccumulateDecimalDigit(
+			    (unsigned)(c - '0'), numTrailZeros,
+			    &significandWide, &significandBig,
+			    significandOverflow);
+		}
+		numSigDigs += numTrailZeros+1;
+		numTrailZeros = 0;
+		state = DECIMAL;
+		break;
+	    } else if (flags & TCL_PARSE_INTEGER_ONLY) {
+		goto endgame;
+	    } else if (c == '.') {
+		state = FRACTION;
+		break;
+	    } else if (c == 'E' || c == 'e') {
+		state = EXPONENT_START;
+		break;
+	    }
+	    goto endgame;
+
+	    /*
+	     * Found a decimal point. If no digits have yet been scanned, E is
+	     * not allowed; otherwise, it introduces the exponent. If at least
+	     * one digit has been found, we have a possible complete number.
+	     */
+
+	case FRACTION:
+	    acceptState = state;
+	    acceptPoint = p;
+	    acceptLen = len;
+	    if (c == 'E' || c=='e') {
+		state = EXPONENT_START;
+		break;
+	    }
+	    /* FALLTHROUGH */
+
+	case LEADING_RADIX_POINT:
+	    if (c == '0') {
+		numDigitsAfterDp++;
+		numTrailZeros++;
+		state = FRACTION;
+		break;
+	    } else if (isdigit(UCHAR(c))) {
+		numDigitsAfterDp++;
+		if (objPtr != NULL) {
+		    significandOverflow = AccumulateDecimalDigit(
+			    (unsigned)(c-'0'), numTrailZeros,
+			    &significandWide, &significandBig,
+			    significandOverflow);
+		}
+		if (numSigDigs != 0) {
+		    numSigDigs += numTrailZeros+1;
+		} else {
+		    numSigDigs = 1;
+		}
+		numTrailZeros = 0;
+		state = FRACTION;
+		break;
+	    }
+	    goto endgame;
+
+	case EXPONENT_START:
+	    /*
+	     * Scanned the E at the start of an exponent. Make sure a legal
+	     * character follows before using the C library strtol routine,
+	     * which allows whitespace.
+	     */
+
+	    if (c == '+') {
+		state = EXPONENT_SIGNUM;
+		break;
+	    } else if (c == '-') {
+		exponentSignum = 1;
+		state = EXPONENT_SIGNUM;
+		break;
+	    }
+	    /* FALLTHROUGH */
+
+	case EXPONENT_SIGNUM:
+	    /*
+	     * Found the E at the start of the exponent, followed by a sign
+	     * character.
+	     */
+
+	    if (isdigit(UCHAR(c))) {
+		exponent = c - '0';
+		state = EXPONENT;
+		break;
+	    }
+	    goto endgame;
+
+	case EXPONENT:
+	    /*
+	     * Found an exponent with at least one digit. Accumulate it,
+	     * making sure to hard-pin it to LONG_MAX on overflow.
+	     */
+
+	    acceptState = state;
+	    acceptPoint = p;
+	    acceptLen = len;
+	    if (isdigit(UCHAR(c))) {
+		if (exponent < (LONG_MAX - 9) / 10) {
+		    exponent = 10 * exponent + (c - '0');
+		} else {
+		    exponent = LONG_MAX;
+		}
+		state = EXPONENT;
+		break;
+	    }
+	    goto endgame;
+
+	    /*
+	     * Parse out INFINITY by simply spelling it out. INF is accepted
+	     * as an abbreviation; other prefices are not.
+	     */
+
+	case sI:
+	    if (c == 'n' || c == 'N') {
+		state = sIN;
+		break;
+	    }
+	    goto endgame;
+	case sIN:
+	    if (c == 'f' || c == 'F') {
+		state = sINF;
+		break;
+	    }
+	    goto endgame;
+	case sINF:
+	    acceptState = state;
+	    acceptPoint = p;
+	    acceptLen = len;
+	    if (c == 'i' || c == 'I') {
+		state = sINFI;
+		break;
+	    }
+	    goto endgame;
+	case sINFI:
+	    if (c == 'n' || c == 'N') {
+		state = sINFIN;
+		break;
+	    }
+	    goto endgame;
+	case sINFIN:
+	    if (c == 'i' || c == 'I') {
+		state = sINFINI;
+		break;
+	    }
+	    goto endgame;
+	case sINFINI:
+	    if (c == 't' || c == 'T') {
+		state = sINFINIT;
+		break;
+	    }
+	    goto endgame;
+	case sINFINIT:
+	    if (c == 'y' || c == 'Y') {
+		state = sINFINITY;
+		break;
+	    }
+	    goto endgame;
+
+	    /*
+	     * Parse NaN's.
+	     */
+#ifdef IEEE_FLOATING_POINT
+	case sN:
+	    if (c == 'a' || c == 'A') {
+		state = sNA;
+		break;
+	    }
+	    goto endgame;
+	case sNA:
+	    if (c == 'n' || c == 'N') {
+		state = sNAN;
+		break;
+	    }
+	    goto endgame;
+	case sNAN:
+	    acceptState = state;
+	    acceptPoint = p;
+	    acceptLen = len;
+	    if (c == '(') {
+		state = sNANPAREN;
+		break;
+	    }
+	    goto endgame;
+
+	    /*
+	     * Parse NaN(hexdigits)
+	     */
+	case sNANHEX:
+	    if (c == ')') {
+		state = sNANFINISH;
+		break;
+	    }
+	    /* FALLTHROUGH */
+	case sNANPAREN:
+	    if (TclIsSpaceProc(c)) {
+		break;
+	    }
+	    if (numSigDigs < 13) {
+		if (c >= '0' && c <= '9') {
+		    d = c - '0';
+		} else if (c >= 'a' && c <= 'f') {
+		    d = 10 + c - 'a';
+		} else if (c >= 'A' && c <= 'F') {
+		    d = 10 + c - 'A';
+		} else {
+		    goto endgame;
+		}
+		numSigDigs++;
+		significandWide = (significandWide << 4) + d;
+		state = sNANHEX;
+		break;
+	    }
+	    goto endgame;
+	case sNANFINISH:
+#endif
+
+	case sINFINITY:
+	    acceptState = state;
+	    acceptPoint = p;
+	    acceptLen = len;
+	    goto endgame;
+	}
+	p++;
+	len--;
+    }
+
+  endgame:
+    if (acceptState == INITIAL) {
+	/*
+	 * No numeric string at all found.
+	 */
+
+	status = TCL_ERROR;
+	if (endPtrPtr != NULL) {
+	    *endPtrPtr = p;
+	}
+    } else {
+	/*
+	 * Back up to the last accepting state in the lexer.
+	 */
+
+	p = acceptPoint;
+	len = acceptLen;
+	if (!(flags & TCL_PARSE_NO_WHITESPACE)) {
+	    /*
+	     * Accept trailing whitespace.
+	     */
+
+	    while (len != 0 && TclIsSpaceProc(*p)) {
+		p++;
+		len--;
+	    }
+	}
+	if (endPtrPtr == NULL) {
+	    if ((len != 0) && ((numBytes > 0) || (*p != '\0'))) {
+		status = TCL_ERROR;
+	    }
+	} else {
+	    *endPtrPtr = p;
+	}
+    }
+
+    /*
+     * Generate and store the appropriate internal rep.
+     */
+
+    if (status == TCL_OK && objPtr != NULL) {
+	TclFreeIntRep(objPtr);
+	switch (acceptState) {
+	case SIGNUM:
+	case BAD_OCTAL:
+	case ZERO_X:
+	case ZERO_O:
+	case ZERO_B:
+	case LEADING_RADIX_POINT:
+	case EXPONENT_START:
+	case EXPONENT_SIGNUM:
+	case sI:
+	case sIN:
+	case sINFI:
+	case sINFIN:
+	case sINFINI:
+	case sINFINIT:
+#ifdef IEEE_FLOATING_POINT
+	case sN:
+	case sNA:
+	case sNANPAREN:
+	case sNANHEX:
+	    Tcl_Panic("TclParseNumber: bad acceptState %d parsing '%s'",
+		    acceptState, bytes);
+#endif
+	case BINARY:
+	    shift = numTrailZeros;
+	    if (!significandOverflow && significandWide != 0 &&
+		    ((size_t)shift >= CHAR_BIT*sizeof(Tcl_WideUInt) ||
+		    significandWide > (MOST_BITS + signum) >> shift)) {
+		significandOverflow = 1;
+		TclBNInitBignumFromWideUInt(&significandBig, significandWide);
+	    }
+	    if (shift) {
+		if (!significandOverflow) {
+		    significandWide <<= shift;
+		} else {
+		    mp_mul_2d(&significandBig, shift, &significandBig);
+		}
+	    }
+	    goto returnInteger;
+
+	case HEXADECIMAL:
+	    /*
+	     * Returning a hex integer. Final scaling step.
+	     */
+
+	    shift = 4 * numTrailZeros;
+	    if (!significandOverflow && significandWide !=0 &&
+		    ((size_t)shift >= CHAR_BIT*sizeof(Tcl_WideUInt) ||
+		    significandWide > (MOST_BITS + signum) >> shift)) {
+		significandOverflow = 1;
+		TclBNInitBignumFromWideUInt(&significandBig, significandWide);
+	    }
+	    if (shift) {
+		if (!significandOverflow) {
+		    significandWide <<= shift;
+		} else {
+		    mp_mul_2d(&significandBig, shift, &significandBig);
+		}
+	    }
+	    goto returnInteger;
+
+	case OCTAL:
+	    /*
+	     * Returning an octal integer. Final scaling step.
+	     */
+
+	    shift = 3 * numTrailZeros;
+	    if (!octalSignificandOverflow && octalSignificandWide != 0 &&
+		    ((size_t)shift >= CHAR_BIT*sizeof(Tcl_WideUInt) ||
+		    octalSignificandWide > (MOST_BITS + signum) >> shift)) {
+		octalSignificandOverflow = 1;
+		TclBNInitBignumFromWideUInt(&octalSignificandBig,
+			octalSignificandWide);
+	    }
+	    if (shift) {
+		if (!octalSignificandOverflow) {
+		    octalSignificandWide <<= shift;
+		} else {
+		    mp_mul_2d(&octalSignificandBig, shift,
+			    &octalSignificandBig);
+		}
+	    }
+	    if (!octalSignificandOverflow) {
+		if (octalSignificandWide >
+			(Tcl_WideUInt)(((~(unsigned long)0) >> 1) + signum)) {
+#ifndef TCL_WIDE_INT_IS_LONG
+		    if (octalSignificandWide <= (MOST_BITS + signum)) {
+			objPtr->typePtr = &tclWideIntType;
+			if (signum) {
+			    objPtr->internalRep.wideValue =
+				    - (Tcl_WideInt) octalSignificandWide;
+			} else {
+			    objPtr->internalRep.wideValue =
+				    (Tcl_WideInt) octalSignificandWide;
+			}
+			break;
+		    }
+#endif
+		    TclBNInitBignumFromWideUInt(&octalSignificandBig,
+			    octalSignificandWide);
+		    octalSignificandOverflow = 1;
+		} else {
+		    objPtr->typePtr = &tclIntType;
+		    if (signum) {
+			objPtr->internalRep.longValue =
+				- (long) octalSignificandWide;
+		    } else {
+			objPtr->internalRep.longValue =
+				(long) octalSignificandWide;
+		    }
+		}
+	    }
+	    if (octalSignificandOverflow) {
+		if (signum) {
+		    mp_neg(&octalSignificandBig, &octalSignificandBig);
+		}
+		TclSetBignumIntRep(objPtr, &octalSignificandBig);
+	    }
+	    break;
+
+	case ZERO:
+	case DECIMAL:
+	    significandOverflow = AccumulateDecimalDigit(0, numTrailZeros-1,
+		    &significandWide, &significandBig, significandOverflow);
+	    if (!significandOverflow && (significandWide > MOST_BITS+signum)){
+		significandOverflow = 1;
+		TclBNInitBignumFromWideUInt(&significandBig, significandWide);
+	    }
+	returnInteger:
+	    if (!significandOverflow) {
+		if (significandWide >
+			(Tcl_WideUInt)(((~(unsigned long)0) >> 1) + signum)) {
+#ifndef TCL_WIDE_INT_IS_LONG
+		    if (significandWide <= MOST_BITS+signum) {
+			objPtr->typePtr = &tclWideIntType;
+			if (signum) {
+			    objPtr->internalRep.wideValue =
+				    - (Tcl_WideInt) significandWide;
+			} else {
+			    objPtr->internalRep.wideValue =
+				    (Tcl_WideInt) significandWide;
+			}
+			break;
+		    }
+#endif
+		    TclBNInitBignumFromWideUInt(&significandBig,
+			    significandWide);
+		    significandOverflow = 1;
+		} else {
+		    objPtr->typePtr = &tclIntType;
+		    if (signum) {
+			objPtr->internalRep.longValue =
+				- (long) significandWide;
+		    } else {
+			objPtr->internalRep.longValue =
+				(long) significandWide;
+		    }
+		}
+	    }
+	    if (significandOverflow) {
+		if (signum) {
+		    mp_neg(&significandBig, &significandBig);
+		}
+		TclSetBignumIntRep(objPtr, &significandBig);
+	    }
+	    break;
+
+	case FRACTION:
+	case EXPONENT:
+
+	    /*
+	     * Here, we're parsing a floating-point number. 'significandWide'
+	     * or 'significandBig' contains the exact significand, according
+	     * to whether 'significandOverflow' is set. The desired floating
+	     * point value is significand * 10**k, where
+	     * k = numTrailZeros+exponent-numDigitsAfterDp.
+	     */
+
+	    objPtr->typePtr = &tclDoubleType;
+	    if (exponentSignum) {
+		exponent = -exponent;
+	    }
+	    if (!significandOverflow) {
+		objPtr->internalRep.doubleValue = MakeLowPrecisionDouble(
+			signum, significandWide, numSigDigs,
+			numTrailZeros + exponent - numDigitsAfterDp);
+	    } else {
+		objPtr->internalRep.doubleValue = MakeHighPrecisionDouble(
+			signum, &significandBig, numSigDigs,
+			numTrailZeros + exponent - numDigitsAfterDp);
+	    }
+	    break;
+
+	case sINF:
+	case sINFINITY:
+	    if (signum) {
+		objPtr->internalRep.doubleValue = -HUGE_VAL;
+	    } else {
+		objPtr->internalRep.doubleValue = HUGE_VAL;
+	    }
+	    objPtr->typePtr = &tclDoubleType;
+	    break;
+
+#ifdef IEEE_FLOATING_POINT
+	case sNAN:
+	case sNANFINISH:
+	    objPtr->internalRep.doubleValue = MakeNaN(signum,significandWide);
+	    objPtr->typePtr = &tclDoubleType;
+	    break;
+#endif
+	case INITIAL:
+	    /* This case only to silence compiler warning. */
+	    Tcl_Panic("TclParseNumber: state INITIAL can't happen here");
+	}
+    }
+
+    /*
+     * Format an error message when an invalid number is encountered.
+     */
+
+    if (status != TCL_OK) {
+	if (interp != NULL) {
+	    Tcl_Obj *msg = Tcl_ObjPrintf("expected %s but got \"",
+		    expected);
+
+	    Tcl_AppendLimitedToObj(msg, bytes, numBytes, 50, "");
+	    Tcl_AppendToObj(msg, "\"", -1);
+	    if (state == BAD_OCTAL) {
+		Tcl_AppendToObj(msg, " (looks like invalid octal number)", -1);
+	    }
+	    Tcl_SetObjResult(interp, msg);
+	    Tcl_SetErrorCode(interp, "TCL", "VALUE", "NUMBER", NULL);
+	}
+    }
+
+    /*
+     * Free memory.
+     */
+
+    if (octalSignificandOverflow) {
+	mp_clear(&octalSignificandBig);
+    }
+    if (significandOverflow) {
+	mp_clear(&significandBig);
+    }
+    return status;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * AccumulateDecimalDigit --
+ *
+ *	Consume a decimal digit in a number being scanned.
+ *
+ * Results:
+ *	Returns 1 if the number has overflowed to a bignum, 0 if it still fits
+ *	in a wide integer.
+ *
+ * Side effects:
+ *	Updates either the wide or bignum representation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+AccumulateDecimalDigit(
+    unsigned digit,		/* Digit being scanned. */
+    int numZeros,		/* Count of zero digits preceding the digit
+				 * being scanned. */
+    Tcl_WideUInt *wideRepPtr,	/* Representation of the partial number as a
+				 * wide integer. */
+    mp_int *bignumRepPtr,	/* Representation of the partial number as a
+				 * bignum. */
+    int bignumFlag)		/* Flag == 1 if the number overflowed previous
+				 * to this digit. */
+{
+    int i, n;
+    Tcl_WideUInt w;
+
+    /*
+     * Try wide multiplication first.
+     */
+
+    if (!bignumFlag) {
+	w = *wideRepPtr;
+	if (w == 0) {
+	    /*
+	     * There's no need to multiply if the multiplicand is zero.
+	     */
+
+	    *wideRepPtr = digit;
+	    return 0;
+	} else if (numZeros >= maxpow10_wide
+		|| w > ((~(Tcl_WideUInt)0)-digit)/pow10_wide[numZeros+1]) {
+	    /*
+	     * Wide multiplication will overflow.  Expand the number to a
+	     * bignum and fall through into the bignum case.
+	     */
+
+	    TclBNInitBignumFromWideUInt(bignumRepPtr, w);
+	} else {
+	    /*
+	     * Wide multiplication.
+	     */
+
+	    *wideRepPtr = w * pow10_wide[numZeros+1] + digit;
+	    return 0;
+	}
+    }
+
+    /*
+     * Bignum multiplication.
+     */
+
+    if (numZeros < log10_DIGIT_MAX) {
+	/*
+	 * Up to about 8 zeros - single digit multiplication.
+	 */
+
+	mp_mul_d(bignumRepPtr, (mp_digit) pow10_wide[numZeros+1],
+		bignumRepPtr);
+	mp_add_d(bignumRepPtr, (mp_digit) digit, bignumRepPtr);
+    } else {
+	/*
+	 * More than single digit multiplication. Multiply by the appropriate
+	 * small powers of 5, and then shift. Large strings of zeroes are
+	 * eaten 256 at a time; this is less efficient than it could be, but
+	 * seems implausible. We presume that DIGIT_BIT is at least 27. The
+	 * first multiplication, by up to 10**7, is done with a one-DIGIT
+	 * multiply (this presumes that DIGIT_BIT >= 24).
+	 */
+
+	n = numZeros + 1;
+	mp_mul_d(bignumRepPtr, (mp_digit) pow10_wide[n&0x7], bignumRepPtr);
+	for (i=3; i<=7; ++i) {
+	    if (n & (1 << i)) {
+		mp_mul(bignumRepPtr, pow5+i, bignumRepPtr);
+	    }
+	}
+	while (n >= 256) {
+	    mp_mul(bignumRepPtr, pow5+8, bignumRepPtr);
+	    n -= 256;
+	}
+	mp_mul_2d(bignumRepPtr, (int)(numZeros+1)&~0x7, bignumRepPtr);
+	mp_add_d(bignumRepPtr, (mp_digit) digit, bignumRepPtr);
+    }
+
+    return 1;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * MakeLowPrecisionDouble --
+ *
+ *	Makes the double precision number, signum*significand*10**exponent.
+ *
+ * Results:
+ *	Returns the constructed number.
+ *
+ *	Common cases, where there are few enough digits that the number can be
+ *	represented with at most roundoff, are handled specially here. If the
+ *	number requires more than one rounded operation to compute, the code
+ *	promotes the significand to a bignum and calls MakeHighPrecisionDouble
+ *	to do it instead.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static double
+MakeLowPrecisionDouble(
+    int signum,			/* 1 if the number is negative, 0 otherwise */
+    Tcl_WideUInt significand,	/* Significand of the number. */
+    int numSigDigs,		/* Number of digits in the significand. */
+    int exponent)		/* Power of ten. */
+{
+    double retval;		/* Value of the number. */
+    mp_int significandBig;	/* Significand expressed as a bignum. */
+
+    /*
+     * With gcc on x86, the floating point rounding mode is double-extended.
+     * This causes the result of double-precision calculations to be rounded
+     * twice: once to the precision of double-extended and then again to the
+     * precision of double. Double-rounding introduces gratuitous errors of 1
+     * ulp, so we need to change rounding mode to 53-bits.
+     */
+
+    TCL_IEEE_DOUBLE_ROUNDING;
+
+    /*
+     * Test for the easy cases.
+     */
+
+    if (numSigDigs <= QUICK_MAX) {
+	if (exponent >= 0) {
+	    if (exponent <= mmaxpow) {
+		/*
+		 * The significand is an exact integer, and so is
+		 * 10**exponent. The product will be correct to within 1/2 ulp
+		 * without special handling.
+		 */
+
+		retval = (double)
+			((Tcl_WideInt)significand * pow10vals[exponent]);
+		goto returnValue;
+	    } else {
+		int diff = QUICK_MAX - numSigDigs;
+
+		if (exponent-diff <= mmaxpow) {
+		    /*
+		     * 10**exponent is not an exact integer, but
+		     * 10**(exponent-diff) is exact, and so is
+		     * significand*10**diff, so we can still compute the value
+		     * with only one roundoff.
+		     */
+
+		    volatile double factor = (double)
+			    ((Tcl_WideInt)significand * pow10vals[diff]);
+		    retval = factor * pow10vals[exponent-diff];
+		    goto returnValue;
+		}
+	    }
+	} else {
+	    if (exponent >= -mmaxpow) {
+		/*
+		 * 10**-exponent is an exact integer, and so is the
+		 * significand. Compute the result by one division, again with
+		 * only one rounding.
+		 */
+
+		retval = (double)
+			((Tcl_WideInt)significand / pow10vals[-exponent]);
+		goto returnValue;
+	    }
+	}
+    }
+
+    /*
+     * All the easy cases have failed. Promote ths significand to bignum and
+     * call MakeHighPrecisionDouble to do it the hard way.
+     */
+
+    TclBNInitBignumFromWideUInt(&significandBig, significand);
+    retval = MakeHighPrecisionDouble(0, &significandBig, numSigDigs,
+	    exponent);
+    mp_clear(&significandBig);
+
+    /*
+     * Come here to return the computed value.
+     */
+
+  returnValue:
+    if (signum) {
+	retval = -retval;
+    }
+
+    /*
+     * On gcc on x86, restore the floating point mode word.
+     */
+
+    TCL_DEFAULT_DOUBLE_ROUNDING;
+
+    return retval;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * MakeHighPrecisionDouble --
+ *
+ *	Makes the double precision number, signum*significand*10**exponent.
+ *
+ * Results:
+ *	Returns the constructed number.
+ *
+ *	MakeHighPrecisionDouble is used when arbitrary-precision arithmetic is
+ *	needed to ensure correct rounding. It begins by calculating a
+ *	low-precision approximation to the desired number, and then refines
+ *	the answer in high precision.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static double
+MakeHighPrecisionDouble(
+    int signum,			/* 1=negative, 0=nonnegative. */
+    mp_int *significand,	/* Exact significand of the number. */
+    int numSigDigs,		/* Number of significant digits. */
+    int exponent)		/* Power of 10 by which to multiply. */
+{
+    double retval;
+    int machexp;		/* Machine exponent of a power of 10. */
+
+    /*
+     * With gcc on x86, the floating point rounding mode is double-extended.
+     * This causes the result of double-precision calculations to be rounded
+     * twice: once to the precision of double-extended and then again to the
+     * precision of double. Double-rounding introduces gratuitous errors of 1
+     * ulp, so we need to change rounding mode to 53-bits.
+     */
+
+    TCL_IEEE_DOUBLE_ROUNDING;
+
+    /*
+     * Quick checks for over/underflow.
+     */
+
+    if (numSigDigs+exponent-1 > maxDigits) {
+	retval = HUGE_VAL;
+	goto returnValue;
+    }
+    if (numSigDigs+exponent-1 < minDigits) {
+	retval = 0;
+	goto returnValue;
+    }
+
+    /*
+     * Develop a first approximation to the significand. It is tempting simply
+     * to force bignum to double, but that will overflow on input numbers like
+     * 1.[string repeat 0 1000]1; while this is a not terribly likely
+     * scenario, we still have to deal with it. Use fraction and exponent
+     * instead. Once we have the significand, multiply by 10**exponent. Test
+     * for overflow. Convert back to a double, and test for underflow.
+     */
+
+    retval = BignumToBiasedFrExp(significand, &machexp);
+    retval = Pow10TimesFrExp(exponent, retval, &machexp);
+    if (machexp > DBL_MAX_EXP*log2FLT_RADIX) {
+	retval = HUGE_VAL;
+	goto returnValue;
+    }
+    retval = SafeLdExp(retval, machexp);
+	if (tiny == 0.0) {
+	    tiny = SafeLdExp(1.0, DBL_MIN_EXP * log2FLT_RADIX - mantBits);
+	}
+    if (retval < tiny) {
+	retval = tiny;
+    }
+
+    /*
+     * Refine the result twice. (The second refinement should be necessary
+     * only if the best approximation is a power of 2 minus 1/2 ulp).
+     */
+
+    retval = RefineApproximation(retval, significand, exponent);
+    retval = RefineApproximation(retval, significand, exponent);
+
+    /*
+     * Come here to return the computed value.
+     */
+
+  returnValue:
+    if (signum) {
+	retval = -retval;
+    }
+
+    /*
+     * On gcc on x86, restore the floating point mode word.
+     */
+
+    TCL_DEFAULT_DOUBLE_ROUNDING;
+
+    return retval;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * MakeNaN --
+ *
+ *	Makes a "Not a Number" given a set of bits to put in the tag bits
+ *
+ *	Note that a signalling NaN is never returned.
+ *
+ *----------------------------------------------------------------------
+ */
+
+#ifdef IEEE_FLOATING_POINT
+static double
+MakeNaN(
+    int signum,			/* Sign bit (1=negative, 0=nonnegative. */
+    Tcl_WideUInt tags)		/* Tag bits to put in the NaN. */
+{
+    union {
+	Tcl_WideUInt iv;
+	double dv;
+    } theNaN;
+
+    theNaN.iv = tags;
+    theNaN.iv &= (((Tcl_WideUInt) 1) << 51) - 1;
+    if (signum) {
+	theNaN.iv |= ((Tcl_WideUInt) (0x8000 | NAN_START)) << 48;
+    } else {
+	theNaN.iv |= ((Tcl_WideUInt) NAN_START) << 48;
+    }
+    if (n770_fp) {
+	theNaN.iv = Nokia770Twiddle(theNaN.iv);
+    }
+    return theNaN.dv;
+}
+#endif
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * RefineApproximation --
+ *
+ *	Given a poor approximation to a floating point number, returns a
+ *	better one. (The better approximation is correct to within 1 ulp, and
+ *	is entirely correct if the poor approximation is correct to 1 ulp.)
+ *
+ * Results:
+ *	Returns the improved result.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static double
+RefineApproximation(
+    double approxResult,	/* Approximate result of conversion. */
+    mp_int *exactSignificand,	/* Integer significand. */
+    int exponent)		/* Power of 10 to multiply by significand. */
+{
+    int M2, M5;			/* Powers of 2 and of 5 needed to put the
+				 * decimal and binary numbers over a common
+				 * denominator. */
+    double significand;		/* Sigificand of the binary number. */
+    int binExponent;		/* Exponent of the binary number. */
+    int msb;			/* Most significant bit position of an
+				 * intermediate result. */
+    int nDigits;		/* Number of mp_digit's in an intermediate
+				 * result. */
+    mp_int twoMv;		/* Approx binary value expressed as an exact
+				 * integer scaled by the multiplier 2M. */
+    mp_int twoMd;		/* Exact decimal value expressed as an exact
+				 * integer scaled by the multiplier 2M. */
+    int scale;			/* Scale factor for M. */
+    int multiplier;		/* Power of two to scale M. */
+    double num, den;		/* Numerator and denominator of the correction
+				 * term. */
+    double quot;		/* Correction term. */
+    double minincr;		/* Lower bound on the absolute value of the
+				 * correction term. */
+    int roundToEven = 0;	/* Flag == TRUE if we need to invoke
+				 * "round to even" functionality */
+    double rteSignificand;	/* Significand of the round-to-even result */
+    int rteExponent;		/* Exponent of the round-to-even result */
+    Tcl_WideInt rteSigWide;	/* Wide integer version of the significand
+				 * for testing evenness */
+    int i;
+
+    /*
+     * The first approximation is always low. If we find that it's HUGE_VAL,
+     * we're done.
+     */
+
+    if (approxResult == HUGE_VAL) {
+	return approxResult;
+    }
+
+    /*
+     * Find a common denominator for the decimal and binary fractions. The
+     * common denominator will be 2**M2 + 5**M5.
+     */
+
+    significand = frexp(approxResult, &binExponent);
+    i = mantBits - binExponent;
+    if (i < 0) {
+	M2 = 0;
+    } else {
+	M2 = i;
+    }
+    if (exponent > 0) {
+	M5 = 0;
+    } else {
+	M5 = -exponent;
+	if (M5 - 1 > M2) {
+	    M2 = M5 - 1;
+	}
+    }
+
+    /*
+     * The floating point number is significand*2**binExponent. Compute the
+     * large integer significand*2**(binExponent+M2+1). The 2**-1 bit of the
+     * significand (the most significant) corresponds to the
+     * 2**(binExponent+M2 + 1) bit of 2*M2*v. Allocate enough digits to hold
+     * that quantity, then convert the significand to a large integer, scaled
+     * appropriately. Then multiply by the appropriate power of 5.
+     */
+
+    msb = binExponent + M2;	/* 1008 */
+    nDigits = msb / DIGIT_BIT + 1;
+    mp_init_size(&twoMv, nDigits);
+    i = (msb % DIGIT_BIT + 1);
+    twoMv.used = nDigits;
+    significand *= SafeLdExp(1.0, i);
+    while (--nDigits >= 0) {
+	twoMv.dp[nDigits] = (mp_digit) significand;
+	significand -= (mp_digit) significand;
+	significand = SafeLdExp(significand, DIGIT_BIT);
+    }
+    for (i = 0; i <= 8; ++i) {
+	if (M5 & (1 << i)) {
+	    mp_mul(&twoMv, pow5+i, &twoMv);
+	}
+    }
+
+    /*
+     * Collect the decimal significand as a high precision integer. The least
+     * significant bit corresponds to bit M2+exponent+1 so it will need to be
+     * shifted left by that many bits after being multiplied by
+     * 5**(M5+exponent).
+     */
+
+    mp_init_copy(&twoMd, exactSignificand);
+    for (i=0; i<=8; ++i) {
+	if ((M5 + exponent) & (1 << i)) {
+	    mp_mul(&twoMd, pow5+i, &twoMd);
+	}
+    }
+    mp_mul_2d(&twoMd, M2+exponent+1, &twoMd);
+    mp_sub(&twoMd, &twoMv, &twoMd);
+
+    /*
+     * The result, 2Mv-2Md, needs to be divided by 2M to yield a correction
+     * term. Because 2M may well overflow a double, we need to scale the
+     * denominator by a factor of 2**binExponent-mantBits.
+     */
+
+    scale = binExponent - mantBits - 1;
+
+    mp_set(&twoMv, 1);
+    for (i=0; i<=8; ++i) {
+	if (M5 & (1 << i)) {
+	    mp_mul(&twoMv, pow5+i, &twoMv);
+	}
+    }
+    multiplier = M2 + scale + 1;
+    if (multiplier > 0) {
+	mp_mul_2d(&twoMv, multiplier, &twoMv);
+    } else if (multiplier < 0) {
+	mp_div_2d(&twoMv, -multiplier, &twoMv, NULL);
+    }
+
+    switch (mp_cmp_mag(&twoMd, &twoMv)) {
+    case MP_LT:
+	/*
+	 * If the result is less than unity, the error is less than 1/2 unit in
+	 * the last place, so there's no correction to make.
+	 */
+	mp_clear(&twoMd);
+	mp_clear(&twoMv);
+	return approxResult;
+    case MP_EQ:
+	/*
+	 * If the result is exactly unity, we need to round to even.
+	 */
+	roundToEven = 1;
+	break;
+    case MP_GT:
+	break;
+    }
+
+    if (roundToEven) {
+	rteSignificand = frexp(approxResult, &rteExponent);
+	rteSigWide = (Tcl_WideInt) ldexp(rteSignificand, FP_PRECISION);
+	if ((rteSigWide & 1) == 0) {
+	    mp_clear(&twoMd);
+	    mp_clear(&twoMv);
+	    return approxResult;
+	}
+    }
+
+    /*
+     * Convert the numerator and denominator of the corrector term accurately
+     * to floating point numbers.
+     */
+
+    num = TclBignumToDouble(&twoMd);
+    den = TclBignumToDouble(&twoMv);
+
+    quot = SafeLdExp(num/den, scale);
+    minincr = SafeLdExp(1.0, binExponent-mantBits);
+
+    if (quot<0. && quot>-minincr) {
+	quot = -minincr;
+    } else if (quot>0. && quot<minincr) {
+	quot = minincr;
+    }
+
+    mp_clear(&twoMd);
+    mp_clear(&twoMv);
+
+    return approxResult + quot;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * MultPow5 --
+ *
+ *	Multiply a bignum by a power of 5.
+ *
+ * Side effects:
+ *	Stores base*5**n in result.
+ *
+ *----------------------------------------------------------------------
+ */
+
+inline static void
+MulPow5(
+    mp_int *base, 		/* Number to multiply. */
+    unsigned n,			/* Power of 5 to multiply by. */
+    mp_int *result)		/* Place to store the result. */
+{
+    mp_int *p = base;
+    int n13 = n / 13;
+    int r = n % 13;
+
+    if (r != 0) {
+	mp_mul_d(p, dpow5[r], result);
+	p = result;
+    }
+    r = 0;
+    while (n13 != 0) {
+	if (n13 & 1) {
+	    mp_mul(p, pow5_13+r, result);
+	    p = result;
+	}
+	n13 >>= 1;
+	++r;
+    }
+    if (p != result) {
+	mp_copy(p, result);
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * NormalizeRightward --
+ *
+ *	Shifts a number rightward until it is odd (that is, until the least
+ *	significant bit is nonzero.
+ *
+ * Results:
+ *	Returns the number of bit positions by which the number was shifted.
+ *
+ * Side effects:
+ *	Shifts the number in place; *wPtr is replaced by the shifted number.
+ *
+ *----------------------------------------------------------------------
+ */
+
+inline static int
+NormalizeRightward(
+    Tcl_WideUInt *wPtr)		/* INOUT: Number to shift. */
+{
+    int rv = 0;
+    Tcl_WideUInt w = *wPtr;
+
+    if (!(w & (Tcl_WideUInt) 0xffffffff)) {
+	w >>= 32; rv += 32;
+    }
+    if (!(w & (Tcl_WideUInt) 0xffff)) {
+	w >>= 16; rv += 16;
+    }
+    if (!(w & (Tcl_WideUInt) 0xff)) {
+	w >>= 8; rv += 8;
+    }
+    if (!(w & (Tcl_WideUInt) 0xf)) {
+	w >>= 4; rv += 4;
+    }
+    if (!(w & 0x3)) {
+	w >>= 2; rv += 2;
+    }
+    if (!(w & 0x1)) {
+	w >>= 1; ++rv;
+    }
+    *wPtr = w;
+    return rv;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * RequiredPrecision --
+ *
+ *	Determines the number of bits needed to hold an intger.
+ *
+ * Results:
+ *	Returns the position of the most significant bit (0 - 63).  Returns 0
+ *	if the number is zero.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+RequiredPrecision(
+    Tcl_WideUInt w)		/* Number to interrogate. */
+{
+    int rv;
+    unsigned long wi;
+
+    if (w & ((Tcl_WideUInt) 0xffffffff << 32)) {
+	wi = (unsigned long) (w >> 32); rv = 32;
+    } else {
+	wi = (unsigned long) w; rv = 0;
+    }
+    if (wi & 0xffff0000) {
+	wi >>= 16; rv += 16;
+    }
+    if (wi & 0xff00) {
+	wi >>= 8; rv += 8;
+    }
+    if (wi & 0xf0) {
+	wi >>= 4; rv += 4;
+    }
+    if (wi & 0xc) {
+	wi >>= 2; rv += 2;
+    }
+    if (wi & 0x2) {
+	wi >>= 1; ++rv;
+    }
+    if (wi & 0x1) {
+	++rv;
+    }
+    return rv;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * DoubleToExpAndSig --
+ *
+ *	Separates a 'double' into exponent and significand.
+ *
+ * Side effects:
+ *	Stores the significand in '*significand' and the exponent in '*expon'
+ *	so that dv == significand * 2.0**expon, and significand is odd.  Also
+ *	stores the position of the leftmost 1-bit in 'significand' in 'bits'.
+ *
+ *----------------------------------------------------------------------
+ */
+
+inline static void
+DoubleToExpAndSig(
+    double dv,			/* Number to convert. */
+    Tcl_WideUInt *significand,	/* OUTPUT: Significand of the number. */
+    int *expon,			/* OUTPUT: Exponent to multiply the number
+				 * by. */
+    int *bits)			/* OUTPUT: Number of significant bits. */
+{
+    Double d;			/* Number being converted. */
+    Tcl_WideUInt z;		/* Significand under construction. */
+    int de;			/* Exponent of the number. */
+    int k;			/* Bit count. */
+
+    d.d = dv;
+
+    /*
+     * Extract exponent and significand.
+     */
+
+    de = (d.w.word0 & EXP_MASK) >> EXP_SHIFT;
+    z = d.q & SIG_MASK;
+    if (de != 0) {
+	z |= HIDDEN_BIT;
+	k = NormalizeRightward(&z);
+	*bits = FP_PRECISION - k;
+	*expon = k + (de - EXPONENT_BIAS) - (FP_PRECISION-1);
+    } else {
+	k = NormalizeRightward(&z);
+	*expon = k + (de - EXPONENT_BIAS) - (FP_PRECISION-1) + 1;
+	*bits = RequiredPrecision(z);
+    }
+    *significand = z;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TakeAbsoluteValue --
+ *
+ *	Takes the absolute value of a 'double' including 0, Inf and NaN
+ *
+ * Side effects:
+ *	The 'double' in *d is replaced with its absolute value. The signum is
+ *	stored in 'sign': 1 for negative, 0 for nonnegative.
+ *
+ *----------------------------------------------------------------------
+ */
+
+inline static void
+TakeAbsoluteValue(
+    Double *d,			/* Number to replace with absolute value. */
+    int *sign)			/* Place to put the signum. */
+{
+    if (d->w.word0 & SIGN_BIT) {
+	*sign = 1;
+	d->w.word0 &= ~SIGN_BIT;
+    } else {
+	*sign = 0;
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * FormatInfAndNaN --
+ *
+ *	Bailout for formatting infinities and Not-A-Number.
+ *
+ * Results:
+ *	Returns one of the strings 'Infinity' and 'NaN'.  The string returned
+ *	must be freed by the caller using 'ckfree'.
+ *
+ * Side effects:
+ *	Stores 9999 in *decpt, and sets '*endPtr' to designate the terminating
+ *	NUL byte of the string if 'endPtr' is not NULL.
+ *
+ *----------------------------------------------------------------------
+ */
+
+inline static char *
+FormatInfAndNaN(
+    Double *d,			/* Exceptional number to format. */
+    int *decpt,			/* Decimal point to set to a bogus value. */
+    char **endPtr)		/* Pointer to the end of the formatted data */
+{
+    char *retval;
+
+    *decpt = 9999;
+    if (!(d->w.word1) && !(d->w.word0 & HI_ORDER_SIG_MASK)) {
+	retval = ckalloc(9);
+	strcpy(retval, "Infinity");
+	if (endPtr) {
+	    *endPtr = retval + 8;
+	}
+    } else {
+	retval = ckalloc(4);
+	strcpy(retval, "NaN");
+	if (endPtr) {
+	    *endPtr = retval + 3;
+	}
+    }
+    return retval;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * FormatZero --
+ *
+ *	Bailout to format a zero floating-point number.
+ *
+ * Results:
+ *	Returns the constant string "0"
+ *
+ * Side effects:
+ *	Stores 1 in '*decpt' and puts a pointer to the NUL byte terminating
+ *	the string in '*endPtr' if 'endPtr' is not NULL.
+ *
+ *----------------------------------------------------------------------
+ */
+
+inline static char *
+FormatZero(
+    int *decpt,			/* Location of the decimal point. */
+    char **endPtr)		/* Pointer to the end of the formatted data */
+{
+    char *retval = ckalloc(2);
+
+    strcpy(retval, "0");
+    if (endPtr) {
+	*endPtr = retval+1;
+    }
+    *decpt = 0;
+    return retval;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ApproximateLog10 --
+ *
+ *	Computes a two-term Taylor series approximation to the common log of a
+ *	number, and computes the number's binary log.
+ *
+ * Results:
+ *	Return an approximation to floor(log10(bw*2**be)) that is either exact
+ *	or 1 too high.
+ *
+ *----------------------------------------------------------------------
+ */
+
+inline static int
+ApproximateLog10(
+    Tcl_WideUInt bw,		/* Integer significand of the number. */
+    int be,			/* Power of two to scale bw. */
+    int bbits)			/* Number of bits of precision in bw. */
+{
+    int i;			/* Log base 2 of the number. */
+    int k;			/* Floor(Log base 10 of the number) */
+    double ds;			/* Mantissa of the number. */
+    Double d2;
+
+    /*
+     * Compute i and d2 such that d = d2*2**i, and 1 < d2 < 2.
+     * Compute an approximation to log10(d),
+     *   log10(d) ~ log10(2) * i + log10(1.5)
+     *            + (significand-1.5)/(1.5 * log(10))
+     */
+
+    d2.q = bw << (FP_PRECISION - bbits) & SIG_MASK;
+    d2.w.word0 |= (EXPONENT_BIAS) << EXP_SHIFT;
+    i = be + bbits - 1;
+    ds = (d2.d - 1.5) * TWO_OVER_3LOG10
+	    + LOG10_3HALVES_PLUS_FUDGE + LOG10_2 * i;
+    k = (int) ds;
+    if (k > ds) {
+	--k;
+    }
+    return k;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * BetterLog10 --
+ *
+ *	Improves the result of ApproximateLog10 for numbers in the range
+ *	1 .. 10**(TEN_PMAX)-1
+ *
+ * Side effects:
+ *	Sets k_check to 0 if the new result is known to be exact, and to 1 if
+ *	it may still be one too high.
+ *
+ * Results:
+ *	Returns the improved approximation to log10(d).
+ *
+ *----------------------------------------------------------------------
+ */
+
+inline static int
+BetterLog10(
+    double d,			/* Original number to format. */
+    int k,			/* Characteristic(Log base 10) of the
+				 * number. */
+    int *k_check)		/* Flag == 1 if k is inexact. */
+{
+    /*
+     * Performance hack. If k is in the range 0..TEN_PMAX, then we can use a
+     * powers-of-ten table to check it.
+     */
+
+    if (k >= 0 && k <= TEN_PMAX) {
+	if (d < tens[k]) {
+	    k--;
+	}
+	*k_check = 0;
+    } else {
+	*k_check = 1;
+    }
+    return k;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ComputeScale --
+ *
+ *	Prepares to format a floating-point number as decimal.
+ *
+ * Parameters:
+ *	floor(log10*x) is k (or possibly k-1).  floor(log2(x) is i.  The
+ *	significand of x requires bbits bits to represent.
+ *
+ * Results:
+ *	Determines integers b2, b5, s2, s5 so that sig*2**b2*5**b5/2**s2*2**s5
+ *	exactly represents the value of the x/10**k. This value will lie in
+ *	the range [1 .. 10), and allows for computing successive digits by
+ *	multiplying sig%10 by 10.
+ *
+ *----------------------------------------------------------------------
+ */
+
+inline static void
+ComputeScale(
+    int be,			/* Exponent part of number: d = bw * 2**be. */
+    int k,			/* Characteristic of log10(number). */
+    int *b2,			/* OUTPUT: Power of 2 in the numerator. */
+    int *b5,			/* OUTPUT: Power of 5 in the numerator. */
+    int *s2,			/* OUTPUT: Power of 2 in the denominator. */
+    int *s5)			/* OUTPUT: Power of 5 in the denominator. */
+{
+    /*
+     * Scale numerator and denominator powers of 2 so that the input binary
+     * number is the ratio of integers.
+     */
+
+    if (be <= 0) {
+	*b2 = 0;
+	*s2 = -be;
+    } else {
+	*b2 = be;
+	*s2 = 0;
+    }
+
+    /*
+     * Scale numerator and denominator so that the output decimal number is
+     * the ratio of integers.
+     */
+
+    if (k >= 0) {
+	*b5 = 0;
+	*s5 = k;
+	*s2 += k;
+    } else {
+	*b2 -= k;
+	*b5 = -k;
+	*s5 = 0;
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * SetPrecisionLimits --
+ *
+ *	Determines how many digits of significance should be computed (and,
+ *	hence, how much memory need be allocated) for formatting a floating
+ *	point number.
+ *
+ * Given that 'k' is floor(log10(x)):
+ * if 'shortest' format is used, there will be at most 18 digits in the
+ * result.
+ * if 'F' format is used, there will be at most 'ndigits' + k + 1 digits
+ * if 'E' format is used, there will be exactly 'ndigits' digits.
+ *
+ * Side effects:
+ *	Adjusts '*ndigitsPtr' to have a valid value. Stores the maximum memory
+ *	allocation needed in *iPtr.  Sets '*iLimPtr' to the limiting number of
+ *	digits to convert if k has been guessed correctly, and '*iLim1Ptr' to
+ *	the limiting number of digits to convert if k has been guessed to be
+ *	one too high.
+ *
+ *----------------------------------------------------------------------
+ */
+
+inline static void
+SetPrecisionLimits(
+    int convType,		/* Type of conversion: TCL_DD_SHORTEST,
+				 * TCL_DD_STEELE0, TCL_DD_E_FMT,
+				 * TCL_DD_F_FMT. */
+    int k,			/* Floor(log10(number to convert)) */
+    int *ndigitsPtr,		/* IN/OUT: Number of digits requested (will be
+				 *         adjusted if needed). */
+    int *iPtr,			/* OUT: Maximum number of digits to return. */
+    int *iLimPtr,		/* OUT: Number of digits of significance if
+				 *      the bignum method is used.*/
+    int *iLim1Ptr)		/* OUT: Number of digits of significance if
+				 *      the quick method is used. */
+{
+    switch (convType) {
+    case TCL_DD_SHORTEST0:
+    case TCL_DD_STEELE0:
+	*iLimPtr = *iLim1Ptr = -1;
+	*iPtr = 18;
+	*ndigitsPtr = 0;
+	break;
+    case TCL_DD_E_FORMAT:
+	if (*ndigitsPtr <= 0) {
+	    *ndigitsPtr = 1;
+	}
+	*iLimPtr = *iLim1Ptr = *iPtr = *ndigitsPtr;
+	break;
+    case TCL_DD_F_FORMAT:
+	*iPtr = *ndigitsPtr + k + 1;
+	*iLimPtr = *iPtr;
+	*iLim1Ptr = *iPtr - 1;
+	if (*iPtr <= 0) {
+	    *iPtr = 1;
+	}
+	break;
+    default:
+	*iPtr = -1;
+	*iLimPtr = -1;
+	*iLim1Ptr = -1;
+	Tcl_Panic("impossible conversion type in TclDoubleDigits");
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * BumpUp --
+ *
+ *	Increases a string of digits ending in a series of nines to designate
+ *	the next higher number.  xxxxb9999... -> xxxx(b+1)0000...
+ *
+ * Results:
+ *	Returns a pointer to the end of the adjusted string.
+ *
+ * Side effects:
+ *	In the case that the string consists solely of '999999', sets it to
+ *	"1" and moves the decimal point (*kPtr) one place to the right.
+ *
+ *----------------------------------------------------------------------
+ */
+
+inline static char *
+BumpUp(
+    char *s,		    	/* Cursor pointing one past the end of the
+				 * string. */
+    char *retval,		/* Start of the string of digits. */
+    int *kPtr)			/* Position of the decimal point. */
+{
+    while (*--s == '9') {
+	if (s == retval) {
+	    ++(*kPtr);
+	    *s = '1';
+	    return s+1;
+	}
+    }
+    ++*s;
+    ++s;
+    return s;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * AdjustRange --
+ *
+ *	Rescales a 'double' in preparation for formatting it using the 'quick'
+ *	double-to-string method.
+ *
+ * Results:
+ *	Returns the precision that has been lost in the prescaling as a count
+ *	of units in the least significant place.
+ *
+ *----------------------------------------------------------------------
+ */
+
+inline static int
+AdjustRange(
+    double *dPtr,		/* INOUT: Number to adjust. */
+    int k)			/* IN: floor(log10(d)) */
+{
+    int ieps;			/* Number of roundoff errors that have
+				 * accumulated. */
+    double d = *dPtr;		/* Number to adjust. */
+    double ds;
+    int i, j, j1;
+
+    ieps = 2;
+
+    if (k > 0) {
+	/*
+	 * The number must be reduced to bring it into range.
+	 */
+
+	ds = tens[k & 0xf];
+	j = k >> 4;
+	if (j & BLETCH) {
+	    j &= (BLETCH-1);
+	    d /= bigtens[N_BIGTENS - 1];
+	    ieps++;
+	}
+	i = 0;
+	for (; j != 0; j>>=1) {
+	    if (j & 1) {
+		ds *= bigtens[i];
+		++ieps;
+	    }
+	    ++i;
+	}
+	d /= ds;
+    } else if ((j1 = -k) != 0) {
+	/*
+	 * The number must be increased to bring it into range.
+	 */
+
+	d *= tens[j1 & 0xf];
+	i = 0;
+	for (j = j1>>4; j; j>>=1) {
+	    if (j & 1) {
+		ieps++;
+		d *= bigtens[i];
+	    }
+	    ++i;
+	}
+    }
+
+    *dPtr = d;
+    return ieps;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ShorteningQuickFormat --
+ *
+ *	Returns a 'quick' format of a double precision number to a string of
+ *	digits, preferring a shorter string of digits if the shorter string is
+ *	still within 1/2 ulp of the number.
+ *
+ * Results:
+ *	Returns the string of digits. Returns NULL if the 'quick' method fails
+ *	and the bignum method must be used.
+ *
+ * Side effects:
+ *	Stores the position of the decimal point at '*kPtr'.
+ *
+ *----------------------------------------------------------------------
+ */
+
+inline static char *
+ShorteningQuickFormat(
+    double d,			/* Number to convert. */
+    int k,			/* floor(log10(d)) */
+    int ilim,			/* Number of significant digits to return. */
+    double eps,			/* Estimated roundoff error. */
+    char *retval,		/* Buffer to receive the digit string. */
+    int *kPtr)			/* Pointer to stash the position of the
+				 * decimal point. */
+{
+    char *s = retval;		/* Cursor in the return value. */
+    int digit;			/* Current digit. */
+    int i;
+
+    eps = 0.5 / tens[ilim-1] - eps;
+    i = 0;
+    for (;;) {
+	/*
+	 * Convert a digit.
+	 */
+
+	digit = (int) d;
+	d -= digit;
+	*s++ = '0' + digit;
+
+	/*
+	 * Truncate the conversion if the string of digits is within 1/2 ulp
+	 * of the actual value.
+	 */
+
+	if (d < eps) {
+	    *kPtr = k;
+	    return s;
+	}
+	if ((1. - d) < eps) {
+	    *kPtr = k;
+	    return BumpUp(s, retval, kPtr);
+	}
+
+	/*
+	 * Bail out if the conversion fails to converge to a sufficiently
+	 * precise value.
+	 */
+
+	if (++i >= ilim) {
+	    return NULL;
+	}
+
+	/*
+	 * Bring the next digit to the integer part.
+	 */
+
+	eps *= 10;
+	d *= 10.0;
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * StrictQuickFormat --
+ *
+ *	Convert a double precision number of a string of a precise number of
+ *	digits, using the 'quick' double precision method.
+ *
+ * Results:
+ *	Returns the digit string, or NULL if the bignum method must be used to
+ *	do the formatting.
+ *
+ * Side effects:
+ *	Stores the position of the decimal point in '*kPtr'.
+ *
+ *----------------------------------------------------------------------
+ */
+
+inline static char *
+StrictQuickFormat(
+    double d,			/* Number to convert. */
+    int k,			/* floor(log10(d)) */
+    int ilim,			/* Number of significant digits to return. */
+    double eps,			/* Estimated roundoff error. */
+    char *retval,		/* Start of the digit string. */
+    int *kPtr)			/* Pointer to stash the position of the
+				 * decimal point. */
+{
+    char *s = retval;		/* Cursor in the return value. */
+    int digit;			/* Current digit of the answer. */
+    int i;
+
+    eps *= tens[ilim-1];
+    i = 1;
+    for (;;) {
+	/*
+	 * Extract a digit.
+	 */
+
+	digit = (int) d;
+	d -= digit;
+	if (d == 0.0) {
+	    ilim = i;
+	}
+	*s++ = '0' + digit;
+
+	/*
+	 * When the given digit count is reached, handle trailing strings of 0
+	 * and 9.
+	 */
+
+	if (i == ilim) {
+	    if (d > 0.5 + eps) {
+		*kPtr = k;
+		return BumpUp(s, retval, kPtr);
+	    } else if (d < 0.5 - eps) {
+		while (*--s == '0') {
+		    /* do nothing */
+		}
+		s++;
+		*kPtr = k;
+		return s;
+	    } else {
+		return NULL;
+	    }
+	}
+
+	/*
+	 * Advance to the next digit.
+	 */
+
+	++i;
+	d *= 10.0;
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * QuickConversion --
+ *
+ *	Converts a floating point number the 'quick' way, when only a limited
+ *	number of digits is required and floating point arithmetic can
+ *	therefore be used for the intermediate results.
+ *
+ * Results:
+ *	Returns the converted string, or NULL if the bignum method must be
+ *	used.
+ *
+ *----------------------------------------------------------------------
+ */
+
+inline static char *
+QuickConversion(
+    double e,			/* Number to format. */
+    int k,			/* floor(log10(d)), approximately. */
+    int k_check,		/* 0 if k is exact, 1 if it may be too high */
+    int flags,			/* Flags passed to dtoa:
+				 *    TCL_DD_SHORTEN_FLAG */
+    int len,			/* Length of the return value. */
+    int ilim,			/* Number of digits to store. */
+    int ilim1,			/* Number of digits to store if we misguessed
+				 * k. */
+    int *decpt,			/* OUTPUT: Location of the decimal point. */
+    char **endPtr)		/* OUTPUT: Pointer to the terminal null
+				 * byte. */
+{
+    int ieps;			/* Number of 1-ulp roundoff errors that have
+				 * accumulated in the calculation. */
+    Double eps;			/* Estimated roundoff error. */
+    char *retval;		/* Returned string. */
+    char *end;			/* Pointer to the terminal null byte in the
+				 * returned string. */
+    volatile double d;		/* Workaround for a bug in mingw gcc 3.4.5 */
+
+    /*
+     * Bring d into the range [1 .. 10).
+     */
+
+    ieps = AdjustRange(&e, k);
+    d = e;
+
+    /*
+     * If the guessed value of k didn't get d into range, adjust it by one. If
+     * that leaves us outside the range in which quick format is accurate,
+     * bail out.
+     */
+
+    if (k_check && d < 1. && ilim > 0) {
+	if (ilim1 < 0) {
+	    return NULL;
+	}
+	ilim = ilim1;
+	--k;
+	d *= 10.0;
+	++ieps;
+    }
+
+    /*
+     * Compute estimated roundoff error.
+     */
+
+    eps.d = ieps * d + 7.;
+    eps.w.word0 -= (FP_PRECISION-1) << EXP_SHIFT;
+
+    /*
+     * Handle the peculiar case where the result has no significant digits.
+     */
+
+    retval = ckalloc(len + 1);
+    if (ilim == 0) {
+	d -= 5.;
+	if (d > eps.d) {
+	    *retval = '1';
+	    *decpt = k;
+	    return retval;
+	} else if (d < -eps.d) {
+	    *decpt = k;
+	    return retval;
+	} else {
+	    ckfree(retval);
+	    return NULL;
+	}
+    }
+
+    /*
+     * Format the digit string.
+     */
+
+    if (flags & TCL_DD_SHORTEN_FLAG) {
+	end = ShorteningQuickFormat(d, k, ilim, eps.d, retval, decpt);
+    } else {
+	end = StrictQuickFormat(d, k, ilim, eps.d, retval, decpt);
+    }
+    if (end == NULL) {
+	ckfree(retval);
+	return NULL;
+    }
+    *end = '\0';
+    if (endPtr != NULL) {
+	*endPtr = end;
+    }
+    return retval;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * CastOutPowersOf2 --
+ *
+ *	Adjust the factors 'b2', 'm2', and 's2' to cast out common powers of 2
+ *	from numerator and denominator in preparation for the 'bignum' method
+ *	of floating point conversion.
+ *
+ *----------------------------------------------------------------------
+ */
+
+inline static void
+CastOutPowersOf2(
+    int *b2,			/* Power of 2 to multiply the significand. */
+    int *m2,			/* Power of 2 to multiply 1/2 ulp. */
+    int *s2)			/* Power of 2 to multiply the common
+				 * denominator. */
+{
+    int i;
+
+    if (*m2 > 0 && *s2 > 0) {	/* Find the smallest power of 2 in the
+				 * numerator. */
+	if (*m2 < *s2) {	/* Find the lowest common denominator. */
+	    i = *m2;
+	} else {
+	    i = *s2;
+	}
+	*b2 -= i;		/* Reduce to lowest terms. */
+	*m2 -= i;
+	*s2 -= i;
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ShorteningInt64Conversion --
+ *
+ *	Converts a double-precision number to the shortest string of digits
+ *	that reconverts exactly to the given number, or to 'ilim' digits if
+ *	that will yield a shorter result. The numerator and denominator in
+ *	David Gay's conversion algorithm are known to fit in Tcl_WideUInt,
+ *	giving considerably faster arithmetic than mp_int's.
+ *
+ * Results:
+ *	Returns the string of significant decimal digits, in newly allocated
+ *	memory
+ *
+ * Side effects:
+ *	Stores the location of the decimal point in '*decpt' and the location
+ *	of the terminal null byte in '*endPtr'.
+ *
+ *----------------------------------------------------------------------
+ */
+
+inline static char *
+ShorteningInt64Conversion(
+    Double *dPtr,		/* Original number to convert. */
+    int convType,		/* Type of conversion (shortest, Steele,
+				 * E format, F format). */
+    Tcl_WideUInt bw,		/* Integer significand. */
+    int b2, int b5,		/* Scale factor for the significand in the
+				 * numerator. */
+    int m2plus, int m2minus, int m5,
+				/* Scale factors for 1/2 ulp in the numerator
+				 * (will be different if bw == 1. */
+    int s2, int s5,		/* Scale factors for the denominator. */
+    int k,			/* Number of output digits before the decimal
+				 * point. */
+    int len,			/* Number of digits to allocate. */
+    int ilim,			/* Number of digits to convert if b >= s */
+    int ilim1,			/* Number of digits to convert if b < s */
+    int *decpt,			/* OUTPUT: Position of the decimal point. */
+    char **endPtr)		/* OUTPUT: Position of the terminal '\0' at
+				 *	   the end of the returned string. */
+{
+    char *retval = ckalloc(len + 1);
+				/* Output buffer. */
+    Tcl_WideUInt b = (bw * wuipow5[b5]) << b2;
+				/* Numerator of the fraction being
+				 * converted. */
+    Tcl_WideUInt S = wuipow5[s5] << s2;
+				/* Denominator of the fraction being
+				 * converted. */
+    Tcl_WideUInt mplus, mminus;	/* Ranges for testing whether the result is
+				 * within roundoff of being exact. */
+    int digit;			/* Current output digit. */
+    char *s = retval;		/* Cursor in the output buffer. */
+    int i;			/* Current position in the output buffer. */
+
+    /*
+     * Adjust if the logarithm was guessed wrong.
+     */
+
+    if (b < S) {
+	b = 10 * b;
+	++m2plus; ++m2minus; ++m5;
+	ilim = ilim1;
+	--k;
+    }
+
+    /*
+     * Compute roundoff ranges.
+     */
+
+    mplus = wuipow5[m5] << m2plus;
+    mminus = wuipow5[m5] << m2minus;
+
+    /*
+     * Loop through the digits.
+     */
+
+    i = 1;
+    for (;;) {
+	digit = (int)(b / S);
+	if (digit > 10) {
+	    Tcl_Panic("wrong digit!");
+	}
+	b = b % S;
+
+	/*
+	 * Does the current digit put us on the low side of the exact value
+	 * but within within roundoff of being exact?
+	 */
+
+	if (b < mplus || (b == mplus
+		&& convType != TCL_DD_STEELE0 && (dPtr->w.word1 & 1) == 0)) {
+	    /*
+	     * Make sure we shouldn't be rounding *up* instead, in case the
+	     * next number above is closer.
+	     */
+
+	    if (2 * b > S || (2 * b == S && (digit & 1) != 0)) {
+		++digit;
+		if (digit == 10) {
+		    *s++ = '9';
+		    s = BumpUp(s, retval, &k);
+		    break;
+		}
+	    }
+
+	    /*
+	     * Stash the current digit.
+	     */
+
+	    *s++ = '0' + digit;
+	    break;
+	}
+
+	/*
+	 * Does one plus the current digit put us within roundoff of the
+	 * number?
+	 */
+
+	if (b > S - mminus || (b == S - mminus
+		&& convType != TCL_DD_STEELE0 && (dPtr->w.word1 & 1) == 0)) {
+	    if (digit == 9) {
+		*s++ = '9';
+		s = BumpUp(s, retval, &k);
+		break;
+	    }
+	    ++digit;
+	    *s++ = '0' + digit;
+	    break;
+	}
+
+	/*
+	 * Have we converted all the requested digits?
+	 */
+
+	*s++ = '0' + digit;
+	if (i == ilim) {
+	    if (2*b > S || (2*b == S && (digit & 1) != 0)) {
+		s = BumpUp(s, retval, &k);
+	    }
+	    break;
+	}
+
+	/*
+	 * Advance to the next digit.
+	 */
+
+	b = 10 * b;
+	mplus = 10 * mplus;
+	mminus = 10 * mminus;
+	++i;
+    }
+
+    /*
+     * Endgame - store the location of the decimal point and the end of the
+     * string.
+     */
+
+    *s = '\0';
+    *decpt = k;
+    if (endPtr) {
+	*endPtr = s;
+    }
+    return retval;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * StrictInt64Conversion --
+ *
+ *	Converts a double-precision number to a fixed-length string of 'ilim'
+ *	digits that reconverts exactly to the given number.  ('ilim' should be
+ *	replaced with 'ilim1' in the case where log10(d) has been
+ *	overestimated).  The numerator and denominator in David Gay's
+ *	conversion algorithm are known to fit in Tcl_WideUInt, giving
+ *	considerably faster arithmetic than mp_int's.
+ *
+ * Results:
+ *	Returns the string of significant decimal digits, in newly allocated
+ *	memory
+ *
+ * Side effects:
+ *	Stores the location of the decimal point in '*decpt' and the location
+ *	of the terminal null byte in '*endPtr'.
+ *
+ *----------------------------------------------------------------------
+ */
+
+inline static char *
+StrictInt64Conversion(
+    Double *dPtr,		/* Original number to convert. */
+    int convType,		/* Type of conversion (shortest, Steele,
+				 * E format, F format). */
+    Tcl_WideUInt bw,		/* Integer significand. */
+    int b2, int b5,		/* Scale factor for the significand in the
+				 * numerator. */
+    int s2, int s5,		/* Scale factors for the denominator. */
+    int k,			/* Number of output digits before the decimal
+				 * point. */
+    int len,			/* Number of digits to allocate. */
+    int ilim,			/* Number of digits to convert if b >= s */
+    int ilim1,			/* Number of digits to convert if b < s */
+    int *decpt,			/* OUTPUT: Position of the decimal point. */
+    char **endPtr)		/* OUTPUT: Position of the terminal '\0' at
+				 *	   the end of the returned string. */
+{
+    char *retval = ckalloc(len + 1);
+				/* Output buffer. */
+    Tcl_WideUInt b = (bw * wuipow5[b5]) << b2;
+				/* Numerator of the fraction being
+				 * converted. */
+    Tcl_WideUInt S = wuipow5[s5] << s2;
+				/* Denominator of the fraction being
+				 * converted. */
+    int digit;			/* Current output digit. */
+    char *s = retval;		/* Cursor in the output buffer. */
+    int i;			/* Current position in the output buffer. */
+
+    /*
+     * Adjust if the logarithm was guessed wrong.
+     */
+
+    if (b < S) {
+	b = 10 * b;
+	ilim = ilim1;
+	--k;
+    }
+
+    /*
+     * Loop through the digits.
+     */
+
+    i = 1;
+    for (;;) {
+	digit = (int)(b / S);
+	if (digit > 10) {
+	    Tcl_Panic("wrong digit!");
+	}
+	b = b % S;
+
+	/*
+	 * Have we converted all the requested digits?
+	 */
+
+	*s++ = '0' + digit;
+	if (i == ilim) {
+	    if (2*b > S || (2*b == S && (digit & 1) != 0)) {
+		s = BumpUp(s, retval, &k);
+	    } else {
+		while (*--s == '0') {
+		    /* do nothing */
+		}
+		++s;
+	    }
+	    break;
+	}
+
+	/*
+	 * Advance to the next digit.
+	 */
+
+	b = 10 * b;
+	++i;
+    }
+
+    /*
+     * Endgame - store the location of the decimal point and the end of the
+     * string.
+     */
+
+    *s = '\0';
+    *decpt = k;
+    if (endPtr) {
+	*endPtr = s;
+    }
+    return retval;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ShouldBankerRoundUpPowD --
+ *
+ *	Test whether bankers' rounding should round a digit up. Assumption is
+ *	made that the denominator of the fraction being tested is a power of
+ *	2**DIGIT_BIT.
+ *
+ * Results:
+ *	Returns 1 iff the fraction is more than 1/2, or if the fraction is
+ *	exactly 1/2 and the digit is odd.
+ *
+ *----------------------------------------------------------------------
+ */
+
+inline static int
+ShouldBankerRoundUpPowD(
+    mp_int *b,			/* Numerator of the fraction. */
+    int sd,			/* Denominator is 2**(sd*DIGIT_BIT). */
+    int isodd)			/* 1 if the digit is odd, 0 if even. */
+{
+    int i;
+    static const mp_digit topbit = 1 << (DIGIT_BIT - 1);
+
+    if (b->used < sd || (b->dp[sd-1] & topbit) == 0) {
+	return 0;
+    }
+    if (b->dp[sd-1] != topbit) {
+	return 1;
+    }
+    for (i = sd-2; i >= 0; --i) {
+	if (b->dp[i] != 0) {
+	    return 1;
+	}
+    }
+    return isodd;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ShouldBankerRoundUpToNextPowD --
+ *
+ *	Tests whether bankers' rounding will round down in the "denominator is
+ *	a power of 2**MP_DIGIT" case.
+ *
+ * Results:
+ *	Returns 1 if the rounding will be performed - which increases the
+ *	digit by one - and 0 otherwise.
+ *
+ *----------------------------------------------------------------------
+ */
+
+inline static int
+ShouldBankerRoundUpToNextPowD(
+    mp_int *b,			/* Numerator of the fraction. */
+    mp_int *m,			/* Numerator of the rounding tolerance. */
+    int sd,			/* Common denominator is 2**(sd*DIGIT_BIT). */
+    int convType,		/* Conversion type: STEELE defeats
+				 * round-to-even (not sure why one wants to do
+				 * this; I copied it from Gay). FIXME */
+    int isodd,			/* 1 if the integer significand is odd. */
+    mp_int *temp)		/* Work area for the calculation. */
+{
+    int i;
+
+    /*
+     * Compare B and S-m - which is the same as comparing B+m and S - which we
+     * do by computing b+m and doing a bitwhack compare against
+     * 2**(DIGIT_BIT*sd)
+     */
+
+    mp_add(b, m, temp);
+    if (temp->used <= sd) {	/* Too few digits to be > s */
+	return 0;
+    }
+    if (temp->used > sd+1 || temp->dp[sd] > 1) {
+				/* >= 2s */
+	return 1;
+    }
+    for (i = sd-1; i >= 0; --i) {
+				/* Check for ==s */
+	if (temp->dp[i] != 0) {	/* > s */
+	    return 1;
+	}
+    }
+    if (convType == TCL_DD_STEELE0) {
+				/* Biased rounding. */
+	return 0;
+    }
+    return isodd;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ShorteningBignumConversionPowD --
+ *
+ *	Converts a double-precision number to the shortest string of digits
+ *	that reconverts exactly to the given number, or to 'ilim' digits if
+ *	that will yield a shorter result. The denominator in David Gay's
+ *	conversion algorithm is known to be a power of 2**DIGIT_BIT, and hence
+ *	the division in the main loop may be replaced by a digit shift and
+ *	mask.
+ *
+ * Results:
+ *	Returns the string of significant decimal digits, in newly allocated
+ *	memory
+ *
+ * Side effects:
+ *	Stores the location of the decimal point in '*decpt' and the location
+ *	of the terminal null byte in '*endPtr'.
+ *
+ *----------------------------------------------------------------------
+ */
+
+inline static char *
+ShorteningBignumConversionPowD(
+    Double *dPtr,		/* Original number to convert. */
+    int convType,		/* Type of conversion (shortest, Steele,
+				 * E format, F format). */
+    Tcl_WideUInt bw,		/* Integer significand. */
+    int b2, int b5,		/* Scale factor for the significand in the
+				 * numerator. */
+    int m2plus, int m2minus, int m5,
+				/* Scale factors for 1/2 ulp in the numerator
+				 * (will be different if bw == 1). */
+    int sd,			/* Scale factor for the denominator. */
+    int k,			/* Number of output digits before the decimal
+				 * point. */
+    int len,			/* Number of digits to allocate. */
+    int ilim,			/* Number of digits to convert if b >= s */
+    int ilim1,			/* Number of digits to convert if b < s */
+    int *decpt,			/* OUTPUT: Position of the decimal point. */
+    char **endPtr)		/* OUTPUT: Position of the terminal '\0' at
+				 *	   the end of the returned string. */
+{
+    char *retval = ckalloc(len + 1);
+				/* Output buffer. */
+    mp_int b;			/* Numerator of the fraction being
+				 * converted. */
+    mp_int mplus, mminus;	/* Bounds for roundoff. */
+    mp_digit digit;		/* Current output digit. */
+    char *s = retval;		/* Cursor in the output buffer. */
+    int i;			/* Index in the output buffer. */
+    mp_int temp;
+    int r1;
+
+    /*
+     * b = bw * 2**b2 * 5**b5
+     * mminus = 5**m5
+     */
+
+    TclBNInitBignumFromWideUInt(&b, bw);
+    mp_init_set_int(&mminus, 1);
+    MulPow5(&b, b5, &b);
+    mp_mul_2d(&b, b2, &b);
+
+    /*
+     * Adjust if the logarithm was guessed wrong.
+     */
+
+    if (b.used <= sd) {
+	mp_mul_d(&b, 10, &b);
+	++m2plus; ++m2minus; ++m5;
+	ilim = ilim1;
+	--k;
+    }
+
+    /*
+     * mminus = 5**m5 * 2**m2minus
+     * mplus = 5**m5 * 2**m2plus
+     */
+
+    mp_mul_2d(&mminus, m2minus, &mminus);
+    MulPow5(&mminus, m5, &mminus);
+    if (m2plus > m2minus) {
+	mp_init_copy(&mplus, &mminus);
+	mp_mul_2d(&mplus, m2plus-m2minus, &mplus);
+    }
+    mp_init(&temp);
+
+    /*
+     * Loop through the digits. Do division and mod by s == 2**(sd*DIGIT_BIT)
+     * by mp_digit extraction.
+     */
+
+    i = 0;
+    for (;;) {
+	if (b.used <= sd) {
+	    digit = 0;
+	} else {
+	    digit = b.dp[sd];
+	    if (b.used > sd+1 || digit >= 10) {
+		Tcl_Panic("wrong digit!");
+	    }
+	    --b.used; mp_clamp(&b);
+	}
+
+	/*
+	 * Does the current digit put us on the low side of the exact value
+	 * but within within roundoff of being exact?
+	 */
+
+	r1 = mp_cmp_mag(&b, (m2plus > m2minus)? &mplus : &mminus);
+	if (r1 == MP_LT || (r1 == MP_EQ
+		&& convType != TCL_DD_STEELE0 && (dPtr->w.word1 & 1) == 0)) {
+	    /*
+	     * Make sure we shouldn't be rounding *up* instead, in case the
+	     * next number above is closer.
+	     */
+
+	    if (ShouldBankerRoundUpPowD(&b, sd, digit&1)) {
+		++digit;
+		if (digit == 10) {
+		    *s++ = '9';
+		    s = BumpUp(s, retval, &k);
+		    break;
+		}
+	    }
+
+	    /*
+	     * Stash the last digit.
+	     */
+
+	    *s++ = '0' + digit;
+	    break;
+	}
+
+	/*
+	 * Does one plus the current digit put us within roundoff of the
+	 * number?
+	 */
+
+	if (ShouldBankerRoundUpToNextPowD(&b, &mminus, sd, convType,
+		dPtr->w.word1 & 1, &temp)) {
+	    if (digit == 9) {
+		*s++ = '9';
+		s = BumpUp(s, retval, &k);
+		break;
+	    }
+	    ++digit;
+	    *s++ = '0' + digit;
+	    break;
+	}
+
+	/*
+	 * Have we converted all the requested digits?
+	 */
+
+	*s++ = '0' + digit;
+	if (i == ilim) {
+	    if (ShouldBankerRoundUpPowD(&b, sd, digit&1)) {
+		s = BumpUp(s, retval, &k);
+	    }
+	    break;
+	}
+
+	/*
+	 * Advance to the next digit.
+	 */
+
+	mp_mul_d(&b, 10, &b);
+	mp_mul_d(&mminus, 10, &mminus);
+	if (m2plus > m2minus) {
+	    mp_mul_2d(&mminus, m2plus-m2minus, &mplus);
+	}
+	++i;
+    }
+
+    /*
+     * Endgame - store the location of the decimal point and the end of the
+     * string.
+     */
+
+    if (m2plus > m2minus) {
+	mp_clear(&mplus);
+    }
+    mp_clear_multi(&b, &mminus, &temp, NULL);
+    *s = '\0';
+    *decpt = k;
+    if (endPtr) {
+	*endPtr = s;
+    }
+    return retval;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * StrictBignumConversionPowD --
+ *
+ *	Converts a double-precision number to a fixed-lengt string of 'ilim'
+ *	digits (or 'ilim1' if log10(d) has been overestimated).  The
+ *	denominator in David Gay's conversion algorithm is known to be a power
+ *	of 2**DIGIT_BIT, and hence the division in the main loop may be
+ *	replaced by a digit shift and mask.
+ *
+ * Results:
+ *	Returns the string of significant decimal digits, in newly allocated
+ *	memory.
+ *
+ * Side effects:
+ *	Stores the location of the decimal point in '*decpt' and the location
+ *	of the terminal null byte in '*endPtr'.
+ *
+ *----------------------------------------------------------------------
+ */
+
+inline static char *
+StrictBignumConversionPowD(
+    Double *dPtr,		/* Original number to convert. */
+    int convType,		/* Type of conversion (shortest, Steele,
+				 * E format, F format). */
+    Tcl_WideUInt bw,		/* Integer significand. */
+    int b2, int b5,		/* Scale factor for the significand in the
+				 * numerator. */
+    int sd,			/* Scale factor for the denominator. */
+    int k,			/* Number of output digits before the decimal
+				 * point. */
+    int len,			/* Number of digits to allocate. */
+    int ilim,			/* Number of digits to convert if b >= s */
+    int ilim1,			/* Number of digits to convert if b < s */
+    int *decpt,			/* OUTPUT: Position of the decimal point. */
+    char **endPtr)		/* OUTPUT: Position of the terminal '\0' at
+				 *	   the end of the returned string. */
+{
+    char *retval = ckalloc(len + 1);
+				/* Output buffer. */
+    mp_int b;			/* Numerator of the fraction being
+				 * converted. */
+    mp_digit digit;		/* Current output digit. */
+    char *s = retval;		/* Cursor in the output buffer. */
+    int i;			/* Index in the output buffer. */
+    mp_int temp;
+
+    /*
+     * b = bw * 2**b2 * 5**b5
+     */
+
+    TclBNInitBignumFromWideUInt(&b, bw);
+    MulPow5(&b, b5, &b);
+    mp_mul_2d(&b, b2, &b);
+
+    /*
+     * Adjust if the logarithm was guessed wrong.
+     */
+
+    if (b.used <= sd) {
+	mp_mul_d(&b, 10, &b);
+	ilim = ilim1;
+	--k;
+    }
+    mp_init(&temp);
+
+    /*
+     * Loop through the digits. Do division and mod by s == 2**(sd*DIGIT_BIT)
+     * by mp_digit extraction.
+     */
+
+    i = 1;
+    for (;;) {
+	if (b.used <= sd) {
+	    digit = 0;
+	} else {
+	    digit = b.dp[sd];
+	    if (b.used > sd+1 || digit >= 10) {
+		Tcl_Panic("wrong digit!");
+	    }
+	    --b.used;
+	    mp_clamp(&b);
+	}
+
+	/*
+	 * Have we converted all the requested digits?
+	 */
+
+	*s++ = '0' + digit;
+	if (i == ilim) {
+	    if (ShouldBankerRoundUpPowD(&b, sd, digit&1)) {
+		s = BumpUp(s, retval, &k);
+	    }
+	    while (*--s == '0') {
+		/* do nothing */
+	    }
+	    ++s;
+	    break;
+	}
+
+	/*
+	 * Advance to the next digit.
+	 */
+
+	mp_mul_d(&b, 10, &b);
+	++i;
+    }
+
+    /*
+     * Endgame - store the location of the decimal point and the end of the
+     * string.
+     */
+
+    mp_clear_multi(&b, &temp, NULL);
+    *s = '\0';
+    *decpt = k;
+    if (endPtr) {
+	*endPtr = s;
+    }
+    return retval;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ShouldBankerRoundUp --
+ *
+ *	Tests whether a digit should be rounded up or down when finishing
+ *	bignum-based floating point conversion.
+ *
+ * Results:
+ *	Returns 1 if the number needs to be rounded up, 0 otherwise.
+ *
+ *----------------------------------------------------------------------
+ */
+
+inline static int
+ShouldBankerRoundUp(
+    mp_int *twor,		/* 2x the remainder from thd division that
+				 * produced the last digit. */
+    mp_int *S,			/* Denominator. */
+    int isodd)			/* Flag == 1 if the last digit is odd. */
+{
+    int r = mp_cmp_mag(twor, S);
+
+    switch (r) {
+    case MP_LT:
+	return 0;
+    case MP_EQ:
+	return isodd;
+    case MP_GT:
+	return 1;
+    }
+    Tcl_Panic("in ShouldBankerRoundUp, trichotomy fails!");
+    return 0;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ShouldBankerRoundUpToNext --
+ *
+ *	Tests whether the remainder is great enough to force rounding to the
+ *	next higher digit.
+ *
+ * Results:
+ *	Returns 1 if the number should be rounded up, 0 otherwise.
+ *
+ *----------------------------------------------------------------------
+ */
+
+inline static int
+ShouldBankerRoundUpToNext(
+    mp_int *b,			/* Remainder from the division that produced
+				 * the last digit. */
+    mp_int *m,			/* Numerator of the rounding tolerance. */
+    mp_int *S,			/* Denominator. */
+    int convType,		/* Conversion type: STEELE0 defeats
+				 * round-to-even. (Not sure why one would want
+				 * this; I coped it from Gay). FIXME */
+    int isodd,			/* 1 if the integer significand is odd. */
+    mp_int *temp)		/* Work area needed for the calculation. */
+{
+    int r;
+
+    /*
+     * Compare b and S-m: this is the same as comparing B+m and S.
+     */
+
+    mp_add(b, m, temp);
+    r = mp_cmp_mag(temp, S);
+    switch(r) {
+    case MP_LT:
+	return 0;
+    case MP_EQ:
+	if (convType == TCL_DD_STEELE0) {
+	    return 0;
+	} else {
+	    return isodd;
+	}
+    case MP_GT:
+	return 1;
+    }
+    Tcl_Panic("in ShouldBankerRoundUpToNext, trichotomy fails!");
+    return 0;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ShorteningBignumConversion --
+ *
+ *	Convert a floating point number to a variable-length digit string
+ *	using the multiprecision method.
+ *
+ * Results:
+ *	Returns the string of digits.
+ *
+ * Side effects:
+ *	Stores the position of the decimal point in *decpt.  Stores a pointer
+ *	to the end of the number in *endPtr.
+ *
+ *----------------------------------------------------------------------
+ */
+
+inline static char *
+ShorteningBignumConversion(
+    Double *dPtr,		/* Original number being converted. */
+    int convType,		/* Conversion type. */
+    Tcl_WideUInt bw,		/* Integer significand and exponent. */
+    int b2,			/* Scale factor for the significand. */
+    int m2plus, int m2minus,	/* Scale factors for 1/2 ulp in numerator. */
+    int s2, int s5,		/* Scale factors for denominator. */
+    int k,			/* Guessed position of the decimal point. */
+    int len,			/* Size of the digit buffer to allocate. */
+    int ilim,			/* Number of digits to convert if b >= s */
+    int ilim1,			/* Number of digits to convert if b < s */
+    int *decpt,			/* OUTPUT: Position of the decimal point. */
+    char **endPtr)		/* OUTPUT: Pointer to the end of the number */
+{
+    char *retval = ckalloc(len+1);
+				/* Buffer of digits to return. */
+    char *s = retval;		/* Cursor in the return value. */
+    mp_int b;			/* Numerator of the result. */
+    mp_int mminus;		/* 1/2 ulp below the result. */
+    mp_int mplus;		/* 1/2 ulp above the result. */
+    mp_int S;			/* Denominator of the result. */
+    mp_int dig;			/* Current digit of the result. */
+    int digit;			/* Current digit of the result. */
+    mp_int temp;		/* Work area. */
+    int minit = 1;		/* Fudge factor for when we misguess k. */
+    int i;
+    int r1;
+
+    /*
+     * b = bw * 2**b2 * 5**b5
+     * S = 2**s2 * 5*s5
+     */
+
+    TclBNInitBignumFromWideUInt(&b, bw);
+    mp_mul_2d(&b, b2, &b);
+    mp_init_set_int(&S, 1);
+    MulPow5(&S, s5, &S); mp_mul_2d(&S, s2, &S);
+
+    /*
+     * Handle the case where we guess the position of the decimal point wrong.
+     */
+
+    if (mp_cmp_mag(&b, &S) == MP_LT) {
+	mp_mul_d(&b, 10, &b);
+	minit = 10;
+	ilim =ilim1;
+	--k;
+    }
+
+    /*
+     * mminus = 2**m2minus * 5**m5
+     */
+
+    mp_init_set_int(&mminus, minit);
+    mp_mul_2d(&mminus, m2minus, &mminus);
+    if (m2plus > m2minus) {
+	mp_init_copy(&mplus, &mminus);
+	mp_mul_2d(&mplus, m2plus-m2minus, &mplus);
+    }
+    mp_init(&temp);
+
+    /*
+     * Loop through the digits.
+     */
+
+    mp_init(&dig);
+    i = 1;
+    for (;;) {
+	mp_div(&b, &S, &dig, &b);
+	if (dig.used > 1 || dig.dp[0] >= 10) {
+	    Tcl_Panic("wrong digit!");
+	}
+	digit = dig.dp[0];
+
+	/*
+	 * Does the current digit leave us with a remainder small enough to
+	 * round to it?
+	 */
+
+	r1 = mp_cmp_mag(&b, (m2plus > m2minus)? &mplus : &mminus);
+	if (r1 == MP_LT || (r1 == MP_EQ
+		&& convType != TCL_DD_STEELE0 && (dPtr->w.word1 & 1) == 0)) {
+	    mp_mul_2d(&b, 1, &b);
+	    if (ShouldBankerRoundUp(&b, &S, digit&1)) {
+		++digit;
+		if (digit == 10) {
+		    *s++ = '9';
+		    s = BumpUp(s, retval, &k);
+		    break;
+		}
+	    }
+	    *s++ = '0' + digit;
+	    break;
+	}
+
+	/*
+	 * Does the current digit leave us with a remainder large enough to
+	 * commit to rounding up to the next higher digit?
+	 */
+
+	if (ShouldBankerRoundUpToNext(&b, &mminus, &S, convType,
+		dPtr->w.word1 & 1, &temp)) {
+	    ++digit;
+	    if (digit == 10) {
+		*s++ = '9';
+		s = BumpUp(s, retval, &k);
+		break;
+	    }
+	    *s++ = '0' + digit;
+	    break;
+	}
+
+	/*
+	 * Have we converted all the requested digits?
+	 */
+
+	*s++ = '0' + digit;
+	if (i == ilim) {
+	    mp_mul_2d(&b, 1, &b);
+	    if (ShouldBankerRoundUp(&b, &S, digit&1)) {
+		s = BumpUp(s, retval, &k);
+	    }
+	    break;
+	}
+
+	/*
+	 * Advance to the next digit.
+	 */
+
+	if (s5 > 0) {
+	    /*
+	     * Can possibly shorten the denominator.
+	     */
+
+	    mp_mul_2d(&b, 1, &b);
+	    mp_mul_2d(&mminus, 1, &mminus);
+	    if (m2plus > m2minus) {
+		mp_mul_2d(&mplus, 1, &mplus);
+	    }
+	    mp_div_d(&S, 5, &S, NULL);
+	    --s5;
+
+	    /*
+	     * IDEA: It might possibly be a win to fall back to int64
+	     *       arithmetic here if S < 2**64/10. But it's a win only for
+	     *       a fairly narrow range of magnitudes so perhaps not worth
+	     *       bothering.  We already know that we shorten the
+	     *       denominator by at least 1 mp_digit, perhaps 2, as we do
+	     *       the conversion for 17 digits of significance.
+	     * Possible savings:
+	     * 10**26   1 trip through loop before fallback possible
+	     * 10**27   1 trip
+	     * 10**28   2 trips
+	     * 10**29   3 trips
+	     * 10**30   4 trips
+	     * 10**31   5 trips
+	     * 10**32   6 trips
+	     * 10**33   7 trips
+	     * 10**34   8 trips
+	     * 10**35   9 trips
+	     * 10**36  10 trips
+	     * 10**37  11 trips
+	     * 10**38  12 trips
+	     * 10**39  13 trips
+	     * 10**40  14 trips
+	     * 10**41  15 trips
+	     * 10**42  16 trips
+	     * thereafter no gain.
+	     */
+	} else {
+	    mp_mul_d(&b, 10, &b);
+	    mp_mul_d(&mminus, 10, &mminus);
+	    if (m2plus > m2minus) {
+		mp_mul_2d(&mplus, 10, &mplus);
+	    }
+	}
+
+	++i;
+    }
+
+    /*
+     * Endgame - store the location of the decimal point and the end of the
+     * string.
+     */
+
+    if (m2plus > m2minus) {
+	mp_clear(&mplus);
+    }
+    mp_clear_multi(&b, &mminus, &temp, &dig, &S, NULL);
+    *s = '\0';
+    *decpt = k;
+    if (endPtr) {
+	*endPtr = s;
+    }
+    return retval;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * StrictBignumConversion --
+ *
+ *	Convert a floating point number to a fixed-length digit string using
+ *	the multiprecision method.
+ *
+ * Results:
+ *	Returns the string of digits.
+ *
+ * Side effects:
+ *	Stores the position of the decimal point in *decpt.  Stores a pointer
+ *	to the end of the number in *endPtr.
+ *
+ *----------------------------------------------------------------------
+ */
+
+inline static char *
+StrictBignumConversion(
+    Double *dPtr,		/* Original number being converted. */
+    int convType,		/* Conversion type. */
+    Tcl_WideUInt bw,		/* Integer significand and exponent. */
+    int b2,			/* Scale factor for the significand. */
+    int s2, int s5,		/* Scale factors for denominator. */
+    int k,			/* Guessed position of the decimal point. */
+    int len,			/* Size of the digit buffer to allocate. */
+    int ilim,			/* Number of digits to convert if b >= s */
+    int ilim1,			/* Number of digits to convert if b < s */
+    int *decpt,			/* OUTPUT: Position of the decimal point. */
+    char **endPtr)		/* OUTPUT: Pointer to the end of the number */
+{
+    char *retval = ckalloc(len+1);
+				/* Buffer of digits to return. */
+    char *s = retval;		/* Cursor in the return value. */
+    mp_int b;			/* Numerator of the result. */
+    mp_int S;			/* Denominator of the result. */
+    mp_int dig;			/* Current digit of the result. */
+    int digit;			/* Current digit of the result. */
+    mp_int temp;		/* Work area. */
+    int g;			/* Size of the current digit ground. */
+    int i, j;
+
+    /*
+     * b = bw * 2**b2 * 5**b5
+     * S = 2**s2 * 5*s5
+     */
+
+    mp_init_multi(&temp, &dig, NULL);
+    TclBNInitBignumFromWideUInt(&b, bw);
+    mp_mul_2d(&b, b2, &b);
+    mp_init_set_int(&S, 1);
+    MulPow5(&S, s5, &S); mp_mul_2d(&S, s2, &S);
+
+    /*
+     * Handle the case where we guess the position of the decimal point wrong.
+     */
+
+    if (mp_cmp_mag(&b, &S) == MP_LT) {
+	mp_mul_d(&b, 10, &b);
+	ilim =ilim1;
+	--k;
+    }
+
+    /*
+     * Convert the leading digit.
+     */
+
+    i = 0;
+    mp_div(&b, &S, &dig, &b);
+    if (dig.used > 1 || dig.dp[0] >= 10) {
+	Tcl_Panic("wrong digit!");
+    }
+    digit = dig.dp[0];
+
+    /*
+     * Is a single digit all that was requested?
+     */
+
+    *s++ = '0' + digit;
+    if (++i >= ilim) {
+	mp_mul_2d(&b, 1, &b);
+	if (ShouldBankerRoundUp(&b, &S, digit&1)) {
+	    s = BumpUp(s, retval, &k);
+	}
+    } else {
+	for (;;) {
+	    /*
+	     * Shift by a group of digits.
+	     */
+
+	    g = ilim - i;
+	    if (g > DIGIT_GROUP) {
+		g = DIGIT_GROUP;
+	    }
+	    if (s5 >= g) {
+		mp_div_d(&S, dpow5[g], &S, NULL);
+		s5 -= g;
+	    } else if (s5 > 0) {
+		mp_div_d(&S, dpow5[s5], &S, NULL);
+		mp_mul_d(&b, dpow5[g - s5], &b);
+		s5 = 0;
+	    } else {
+		mp_mul_d(&b, dpow5[g], &b);
+	    }
+	    mp_mul_2d(&b, g, &b);
+
+	    /*
+	     * As with the shortening bignum conversion, it's possible at this
+	     * point that we will have reduced the denominator to less than
+	     * 2**64/10, at which point it would be possible to fall back to
+	     * to int64 arithmetic. But the potential payoff is tremendously
+	     * less - unless we're working in F format - because we know that
+	     * three groups of digits will always suffice for %#.17e, the
+	     * longest format that doesn't introduce empty precision.
+	     *
+	     * Extract the next group of digits.
+	     */
+
+	    mp_div(&b, &S, &dig, &b);
+	    if (dig.used > 1) {
+		Tcl_Panic("wrong digit!");
+	    }
+	    digit = dig.dp[0];
+	    for (j = g-1; j >= 0; --j) {
+		int t = itens[j];
+
+		*s++ = digit / t + '0';
+		digit %= t;
+	    }
+	    i += g;
+
+	    /*
+	     * Have we converted all the requested digits?
+	     */
+
+	    if (i == ilim) {
+		mp_mul_2d(&b, 1, &b);
+		if (ShouldBankerRoundUp(&b, &S, digit&1)) {
+		    s = BumpUp(s, retval, &k);
+		}
+		break;
+	    }
+	}
+    }
+    while (*--s == '0') {
+	/* do nothing */
+    }
+    ++s;
+
+    /*
+     * Endgame - store the location of the decimal point and the end of the
+     * string.
+     */
+
+    mp_clear_multi(&b, &S, &temp, &dig, NULL);
+    *s = '\0';
+    *decpt = k;
+    if (endPtr) {
+	*endPtr = s;
+    }
+    return retval;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclDoubleDigits --
+ *
+ *	Core of Tcl's conversion of double-precision floating point numbers to
+ *	decimal.
+ *
+ * Results:
+ *	Returns a newly-allocated string of digits.
+ *
+ * Side effects:
+ *	Sets *decpt to the index of the character in the string before the
+ *	place that the decimal point should go. If 'endPtr' is not NULL, sets
+ *	endPtr to point to the terminating '\0' byte of the string. Sets *sign
+ *	to 1 if a minus sign should be printed with the number, or 0 if a plus
+ *	sign (or no sign) should appear.
+ *
+ * This function is a service routine that produces the string of digits for
+ * floating-point-to-decimal conversion. It can do a number of things
+ * according to the 'flags' argument. Valid values for 'flags' include:
+ *	TCL_DD_SHORTEST - This is the default for floating point conversion if
+ *		::tcl_precision is 0. It constructs the shortest string of
+ *		digits that will reconvert to the given number when scanned.
+ *		For floating point numbers that are exactly between two
+ *		decimal numbers, it resolves using the 'round to even' rule.
+ *		With this value, the 'ndigits' parameter is ignored.
+ *	TCL_DD_STEELE - This value is not recommended and may be removed in
+ *		the future. It follows the conversion algorithm outlined in
+ *		"How to Print Floating-Point Numbers Accurately" by Guy
+ *		L. Steele, Jr. and Jon L. White [Proc. ACM SIGPLAN '90,
+ *		pp. 112-126]. This rule has the effect of rendering 1e23 as
+ *		9.9999999999999999e22 - which is a 'better' approximation in
+ *		the sense that it will reconvert correctly even if a
+ *		subsequent input conversion is 'round up' or 'round down'
+ *		rather than 'round to nearest', but is surprising otherwise.
+ *	TCL_DD_E_FORMAT - This value is used to prepare numbers for %e format
+ *		conversion (or for default floating->string if tcl_precision
+ *		is not 0). It constructs a string of at most 'ndigits' digits,
+ *		choosing the one that is closest to the given number (and
+ *		resolving ties with 'round to even').  It is allowed to return
+ *		fewer than 'ndigits' if the number converts exactly; if the
+ *		TCL_DD_E_FORMAT|TCL_DD_SHORTEN_FLAG is supplied instead, it
+ *		also returns fewer digits if the shorter string will still
+ *		reconvert without loss to the given input number. In any case,
+ *		strings of trailing zeroes are suppressed.
+ *	TCL_DD_F_FORMAT - This value is used to prepare numbers for %f format
+ *		conversion. It requests that conversion proceed until
+ *		'ndigits' digits after the decimal point have been converted.
+ *		It is possible for this format to result in a zero-length
+ *		string if the number is sufficiently small. Again, it is
+ *		permissible for TCL_DD_F_FORMAT to return fewer digits for a
+ *		number that converts exactly, and changing the argument to
+ *		TCL_DD_F_FORMAT|TCL_DD_SHORTEN_FLAG will allow the routine
+ *		also to return fewer digits if the shorter string will still
+ *		reconvert without loss to the given input number. Strings of
+ *		trailing zeroes are suppressed.
+ *
+ *	To any of these flags may be OR'ed TCL_DD_NO_QUICK; this flag requires
+ *	all calculations to be done in exact arithmetic. Normally, E and F
+ *	format with fewer than about 14 digits will be done with a quick
+ *	floating point approximation and fall back on the exact arithmetic
+ *	only if the input number is close enough to the midpoint between two
+ *	decimal strings that more precision is needed to resolve which string
+ *	is correct.
+ *
+ * The value stored in the 'decpt' argument on return may be negative
+ * (indicating that the decimal point falls to the left of the string) or
+ * greater than the length of the string. In addition, the value -9999 is used
+ * as a sentinel to indicate that the string is one of the special values
+ * "Infinity" and "NaN", and that no decimal point should be inserted.
+ *
+ *----------------------------------------------------------------------
+ */
+
+char *
+TclDoubleDigits(
+    double dv,			/* Number to convert. */
+    int ndigits,		/* Number of digits requested. */
+    int flags,			/* Conversion flags. */
+    int *decpt,			/* OUTPUT: Position of the decimal point. */
+    int *sign,			/* OUTPUT: 1 if the result is negative. */
+    char **endPtr)		/* OUTPUT: If not NULL, receives a pointer to
+				 *	   one character beyond the end of the
+				 *	   returned string. */
+{
+    int convType = (flags & TCL_DD_CONVERSION_TYPE_MASK);
+				/* Type of conversion being performed:
+				 * TCL_DD_SHORTEST0, TCL_DD_STEELE0,
+				 * TCL_DD_E_FORMAT, or TCL_DD_F_FORMAT. */
+    Double d;			/* Union for deconstructing doubles. */
+    Tcl_WideUInt bw;		/* Integer significand. */
+    int be;			/* Power of 2 by which b must be multiplied */
+    int bbits;			/* Number of bits needed to represent b. */
+    int denorm;			/* Flag == 1 iff the input number was
+				 * denormalized. */
+    int k;			/* Estimate of floor(log10(d)). */
+    int k_check;		/* Flag == 1 if d is near enough to a power of
+				 * ten that k must be checked. */
+    int b2, b5, s2, s5;		/* Powers of 2 and 5 in the numerator and
+				 * denominator of intermediate results. */
+    int ilim = -1, ilim1 = -1;	/* Number of digits to convert, and number to
+				 * convert if log10(d) has been
+				 * overestimated. */
+    char *retval;		/* Return value from this function. */
+    int i = -1;
+
+    /*
+     * Put the input number into a union for bit-whacking.
+     */
+
+    d.d = dv;
+
+    /*
+     * Handle the cases of negative numbers (by taking the absolute value:
+     * this includes -Inf and -NaN!), infinity, Not a Number, and zero.
+     */
+
+    TakeAbsoluteValue(&d, sign);
+    if ((d.w.word0 & EXP_MASK) == EXP_MASK) {
+	return FormatInfAndNaN(&d, decpt, endPtr);
+    }
+    if (d.d == 0.0) {
+	return FormatZero(decpt, endPtr);
+    }
+
+    /*
+     * Unpack the floating point into a wide integer and an exponent.
+     * Determine the number of bits that the big integer requires, and compute
+     * a quick approximation (which may be one too high) of ceil(log10(d.d)).
+     */
+
+    denorm = ((d.w.word0 & EXP_MASK) == 0);
+    DoubleToExpAndSig(d.d, &bw, &be, &bbits);
+    k = ApproximateLog10(bw, be, bbits);
+    k = BetterLog10(d.d, k, &k_check);
+
+    /* At this point, we have:
+     *	  d is the number to convert.
+     *    bw are significand and exponent: d == bw*2**be,
+     *    bbits is the length of bw: 2**bbits-1 <= bw < 2**bbits
+     *	  k is either ceil(log10(d)) or ceil(log10(d))+1. k_check is 0 if we
+     *      know that k is exactly ceil(log10(d)) and 1 if we need to check.
+     *    We want a rational number
+     *      r = b * 10**(1-k) = bw * 2**b2 * 5**b5 / (2**s2 / 5**s5),
+     *    with b2, b5, s2, s5 >= 0.  Note that the most significant decimal
+     *    digit is floor(r) and that successive digits can be obtained by
+     *    setting r <- 10*floor(r) (or b <= 10 * (b % S)).  Find appropriate
+     *    b2, b5, s2, s5.
+     */
+
+    ComputeScale(be, k, &b2, &b5, &s2, &s5);
+
+    /*
+     * Correct an incorrect caller-supplied 'ndigits'.  Also determine:
+     *	i = The maximum number of decimal digits that will be returned in the
+     *      formatted string.  This is k + 1 + ndigits for F format, 18 for
+     *      shortest and Steele, and ndigits for E format.
+     *  ilim = The number of significant digits to convert if k has been
+     *         guessed correctly. This is -1 for shortest and Steele (which
+     *         stop when all significance has been lost), 'ndigits' for E
+     *         format, and 'k + 1 + ndigits' for F format.
+     *  ilim1 = The minimum number of significant digits to convert if k has
+     *	        been guessed 1 too high. This, too, is -1 for shortest and
+     *	        Steele, and 'ndigits' for E format, but it's 'ndigits-1' for F
+     *	        format.
+     */
+
+    SetPrecisionLimits(convType, k, &ndigits, &i, &ilim, &ilim1);
+
+    /*
+     * Try to do low-precision conversion in floating point rather than
+     * resorting to expensive multiprecision arithmetic.
+     */
+
+    if (ilim >= 0 && ilim <= QUICK_MAX && !(flags & TCL_DD_NO_QUICK)) {
+	retval = QuickConversion(d.d, k, k_check, flags, i, ilim, ilim1,
+		decpt, endPtr);
+	if (retval != NULL) {
+	    return retval;
+	}
+    }
+
+    /*
+     * For shortening conversions, determine the upper and lower bounds for
+     * the remainder at which we can stop.
+     *   m+ = (2**m2plus * 5**m5) / (2**s2 * 5**s5) is the limit on the high
+     *        side, and
+     *   m- = (2**m2minus * 5**m5) / (2**s2 * 5**s5) is the limit on the low
+     *        side.
+     * We may need to increase s2 to put m2plus, m2minus, b2 over a common
+     * denominator.
+     */
+
+    if (flags & TCL_DD_SHORTEN_FLAG) {
+	int m2minus = b2;
+	int m2plus;
+	int m5 = b5;
+	int len = i;
+
+	/*
+	 * Find the quantity i so that (2**i*5**b5)/(2**s2*5**s5) is 1/2 unit
+	 * in the least significant place of the floating point number.
+	 */
+
+	if (denorm) {
+	    i = be + EXPONENT_BIAS + (FP_PRECISION-1);
+	} else {
+	    i = 1 + FP_PRECISION - bbits;
+	}
+	b2 += i;
+	s2 += i;
+
+	/*
+	 * Reduce the fractions to lowest terms, since the above calculation
+	 * may have left excess powers of 2 in numerator and denominator.
+	 */
+
+	CastOutPowersOf2(&b2, &m2minus, &s2);
+
+	/*
+	 * In the special case where bw==1, the nearest floating point number
+	 * to it on the low side is 1/4 ulp below it. Adjust accordingly.
+	 */
+
+	m2plus = m2minus;
+	if (!denorm && bw == 1) {
+	    ++b2;
+	    ++s2;
+	    ++m2plus;
+	}
+
+	if (s5+1 < N_LOG2POW5 && s2+1 + log2pow5[s5+1] <= 64) {
+	    /*
+	     * If 10*2**s2*5**s5 == 2**(s2+1)+5**(s5+1) fits in a 64-bit word,
+	     * then all our intermediate calculations can be done using exact
+	     * 64-bit arithmetic with no need for expensive multiprecision
+	     * operations. (This will be true for all numbers in the range
+	     * [1.0e-3 .. 1.0e+24]).
+	     */
+
+	    return ShorteningInt64Conversion(&d, convType, bw, b2, b5, m2plus,
+		    m2minus, m5, s2, s5, k, len, ilim, ilim1, decpt, endPtr);
+	} else if (s5 == 0) {
+	    /*
+	     * The denominator is a power of 2, so we can replace division by
+	     * digit shifts. First we round up s2 to a multiple of DIGIT_BIT,
+	     * and adjust m2 and b2 accordingly. Then we launch into a version
+	     * of the comparison that's specialized for the 'power of mp_digit
+	     * in the denominator' case.
+	     */
+
+	    if (s2 % DIGIT_BIT != 0) {
+		int delta = DIGIT_BIT - (s2 % DIGIT_BIT);
+
+		b2 += delta;
+		m2plus += delta;
+		m2minus += delta;
+		s2 += delta;
+	    }
+	    return ShorteningBignumConversionPowD(&d, convType, bw, b2, b5,
+		    m2plus, m2minus, m5, s2/DIGIT_BIT, k, len, ilim, ilim1,
+		    decpt, endPtr);
+	} else {
+	    /*
+	     * Alas, there's no helpful special case; use full-up bignum
+	     * arithmetic for the conversion.
+	     */
+
+	    return ShorteningBignumConversion(&d, convType, bw, b2, m2plus,
+		    m2minus, s2, s5, k, len, ilim, ilim1, decpt, endPtr);
+	}
+    } else {
+	/*
+	 * Non-shortening conversion.
+	 */
+
+	int len = i;
+
+	/*
+	 * Reduce numerator and denominator to lowest terms.
+	 */
+
+	if (b2 >= s2 && s2 > 0) {
+	    b2 -= s2; s2 = 0;
+	} else if (s2 >= b2 && b2 > 0) {
+	    s2 -= b2; b2 = 0;
+	}
+
+	if (s5+1 < N_LOG2POW5 && s2+1 + log2pow5[s5+1] <= 64) {
+	    /*
+	     * If 10*2**s2*5**s5 == 2**(s2+1)+5**(s5+1) fits in a 64-bit word,
+	     * then all our intermediate calculations can be done using exact
+	     * 64-bit arithmetic with no need for expensive multiprecision
+	     * operations.
+	     */
+
+	    return StrictInt64Conversion(&d, convType, bw, b2, b5, s2, s5, k,
+		    len, ilim, ilim1, decpt, endPtr);
+	} else if (s5 == 0) {
+	    /*
+	     * The denominator is a power of 2, so we can replace division by
+	     * digit shifts. First we round up s2 to a multiple of DIGIT_BIT,
+	     * and adjust m2 and b2 accordingly. Then we launch into a version
+	     * of the comparison that's specialized for the 'power of mp_digit
+	     * in the denominator' case.
+	     */
+
+	    if (s2 % DIGIT_BIT != 0) {
+		int delta = DIGIT_BIT - (s2 % DIGIT_BIT);
+
+		b2 += delta;
+		s2 += delta;
+	    }
+	    return StrictBignumConversionPowD(&d, convType, bw, b2, b5,
+		    s2/DIGIT_BIT, k, len, ilim, ilim1, decpt, endPtr);
+	} else {
+	    /*
+	     * There are no helpful special cases, but at least we know in
+	     * advance how many digits we will convert. We can run the
+	     * conversion in steps of DIGIT_GROUP digits, so as to have many
+	     * fewer mp_int divisions.
+	     */
+
+	    return StrictBignumConversion(&d, convType, bw, b2, s2, s5, k,
+		    len, ilim, ilim1, decpt, endPtr);
+	}
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclInitDoubleConversion --
+ *
+ *	Initializes constants that are needed for conversions to and from
+ *	'double'
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The log base 2 of the floating point radix, the number of bits in a
+ *	double mantissa, and a table of the powers of five and ten are
+ *	computed and stored.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclInitDoubleConversion(void)
+{
+    int i;
+    int x;
+    Tcl_WideUInt u;
+    double d;
+#ifdef IEEE_FLOATING_POINT
+    union {
+	double dv;
+	Tcl_WideUInt iv;
+    } bitwhack;
+#endif
+#if defined(__sgi) && defined(_COMPILER_VERSION)
+    union fpc_csr mipsCR;
+
+    mipsCR.fc_word = get_fpc_csr();
+    mipsCR.fc_struct.flush = 0;
+    set_fpc_csr(mipsCR.fc_word);
+#endif
+
+    /*
+     * Initialize table of powers of 10 expressed as wide integers.
+     */
+
+    maxpow10_wide = (int)
+	    floor(sizeof(Tcl_WideUInt) * CHAR_BIT * log(2.) / log(10.));
+    pow10_wide = ckalloc((maxpow10_wide + 1) * sizeof(Tcl_WideUInt));
+    u = 1;
+    for (i = 0; i < maxpow10_wide; ++i) {
+	pow10_wide[i] = u;
+	u *= 10;
+    }
+    pow10_wide[i] = u;
+
+    /*
+     * Determine how many bits of precision a double has, and how many decimal
+     * digits that represents.
+     */
+
+    if (frexp((double) FLT_RADIX, &log2FLT_RADIX) != 0.5) {
+	Tcl_Panic("This code doesn't work on a decimal machine!");
+    }
+    log2FLT_RADIX--;
+    mantBits = DBL_MANT_DIG * log2FLT_RADIX;
+    d = 1.0;
+
+    /*
+     * Initialize a table of powers of ten that can be exactly represented in
+     * a double.
+     */
+
+    x = (int) (DBL_MANT_DIG * log((double) FLT_RADIX) / log(5.0));
+    if (x < MAXPOW) {
+	mmaxpow = x;
+    } else {
+	mmaxpow = MAXPOW;
+    }
+    for (i=0 ; i<=mmaxpow ; ++i) {
+	pow10vals[i] = d;
+	d *= 10.0;
+    }
+
+    /*
+     * Initialize a table of large powers of five.
+     */
+
+    for (i=0; i<9; ++i) {
+	mp_init(pow5 + i);
+    }
+    mp_set(pow5, 5);
+    for (i=0; i<8; ++i) {
+	mp_sqr(pow5+i, pow5+i+1);
+    }
+    mp_init_set_int(pow5_13, 1220703125);
+    for (i = 1; i < 5; ++i) {
+	mp_init(pow5_13 + i);
+	mp_sqr(pow5_13 + i - 1, pow5_13 + i);
+    }
+
+    /*
+     * Determine the number of decimal digits to the left and right of the
+     * decimal point in the largest and smallest double, the smallest double
+     * that differs from zero, and the number of mp_digits needed to represent
+     * the significand of a double.
+     */
+
+    maxDigits = (int) ((DBL_MAX_EXP * log((double) FLT_RADIX)
+	    + 0.5 * log(10.)) / log(10.));
+    minDigits = (int) floor((DBL_MIN_EXP - DBL_MANT_DIG)
+	    * log((double) FLT_RADIX) / log(10.));
+    log10_DIGIT_MAX = (int) floor(DIGIT_BIT * log(2.) / log(10.));
+
+    /*
+     * Nokia 770's software-emulated floating point is "middle endian": the
+     * bytes within a 32-bit word are little-endian (like the native
+     * integers), but the two words of a 'double' are presented most
+     * significant word first.
+     */
+
+#ifdef IEEE_FLOATING_POINT
+    bitwhack.dv = 1.000000238418579;
+				/* 3ff0 0000 4000 0000 */
+    if ((bitwhack.iv >> 32) == 0x3ff00000) {
+	n770_fp = 0;
+    } else if ((bitwhack.iv & 0xffffffff) == 0x3ff00000) {
+	n770_fp = 1;
+    } else {
+	Tcl_Panic("unknown floating point word order on this machine");
+    }
+#endif
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclFinalizeDoubleConversion --
+ *
+ *	Cleans up this file on exit.
+ *
+ * Results:
+ *	None
+ *
+ * Side effects:
+ *	Memory allocated by TclInitDoubleConversion is freed.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclFinalizeDoubleConversion(void)
+{
+    int i;
+
+    ckfree(pow10_wide);
+    for (i=0; i<9; ++i) {
+	mp_clear(pow5 + i);
+    }
+    for (i=0; i < 5; ++i) {
+	mp_clear(pow5_13 + i);
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_InitBignumFromDouble --
+ *
+ *	Extracts the integer part of a double and converts it to an arbitrary
+ *	precision integer.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Initializes the bignum supplied, and stores the converted number in
+ *	it.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_InitBignumFromDouble(
+    Tcl_Interp *interp,		/* For error message. */
+    double d,			/* Number to convert. */
+    mp_int *b)			/* Place to store the result. */
+{
+    double fract;
+    int expt;
+
+    /*
+     * Infinite values can't convert to bignum.
+     */
+
+    if (TclIsInfinite(d)) {
+	if (interp != NULL) {
+	    const char *s = "integer value too large to represent";
+
+	    Tcl_SetObjResult(interp, Tcl_NewStringObj(s, -1));
+	    Tcl_SetErrorCode(interp, "ARITH", "IOVERFLOW", s, NULL);
+	}
+	return TCL_ERROR;
+    }
+
+    fract = frexp(d,&expt);
+    if (expt <= 0) {
+	mp_init(b);
+	mp_zero(b);
+    } else {
+	Tcl_WideInt w = (Tcl_WideInt) ldexp(fract, mantBits);
+	int shift = expt - mantBits;
+
+	TclBNInitBignumFromWideInt(b, w);
+	if (shift < 0) {
+	    mp_div_2d(b, -shift, b, NULL);
+	} else if (shift > 0) {
+	    mp_mul_2d(b, shift, b);
+	}
+    }
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclBignumToDouble --
+ *
+ *	Convert an arbitrary-precision integer to a native floating point
+ *	number.
+ *
+ * Results:
+ *	Returns the converted number. Sets errno to ERANGE if the number is
+ *	too large to convert.
+ *
+ *----------------------------------------------------------------------
+ */
+
+double
+TclBignumToDouble(
+    const mp_int *a)			/* Integer to convert. */
+{
+    mp_int b;
+    int bits, shift, i, lsb;
+    double r;
+
+
+    /*
+     * We need a 'mantBits'-bit significand.  Determine what shift will
+     * give us that.
+     */
+
+    bits = mp_count_bits(a);
+    if (bits > DBL_MAX_EXP*log2FLT_RADIX) {
+	errno = ERANGE;
+	if (a->sign == MP_ZPOS) {
+	    return HUGE_VAL;
+	} else {
+	    return -HUGE_VAL;
+	}
+    }
+    shift = mantBits - bits;
+
+    /*
+     * If shift > 0, shift the significand left by the requisite number of
+     * bits.  If shift == 0, the significand is already exactly 'mantBits'
+     * in length.  If shift < 0, we will need to shift the significand right
+     * by the requisite number of bits, and round it. If the '1-shift'
+     * least significant bits are 0, but the 'shift'th bit is nonzero,
+     * then the significand lies exactly between two values and must be
+     * 'rounded to even'.
+     */
+
+    mp_init(&b);
+    if (shift == 0) {
+	mp_copy(a, &b);
+    } else if (shift > 0) {
+	mp_mul_2d(a, shift, &b);
+    } else if (shift < 0) {
+	lsb = mp_cnt_lsb(a);
+	if (lsb == -1-shift) {
+
+	    /*
+	     * Round to even
+	     */
+
+	    mp_div_2d(a, -shift, &b, NULL);
+	    if (mp_isodd(&b)) {
+		if (b.sign == MP_ZPOS) {
+		    mp_add_d(&b, 1, &b);
+		} else {
+		    mp_sub_d(&b, 1, &b);
+		}
+	    }
+	} else {
+
+	    /*
+	     * Ordinary rounding
+	     */
+
+	    mp_div_2d(a, -1-shift, &b, NULL);
+	    if (b.sign == MP_ZPOS) {
+		mp_add_d(&b, 1, &b);
+	    } else {
+		mp_sub_d(&b, 1, &b);
+	    }
+	    mp_div_2d(&b, 1, &b, NULL);
+	}
+    }
+
+    /*
+     * Accumulate the result, one mp_digit at a time.
+     */
+
+    r = 0.0;
+    for (i=b.used-1 ; i>=0 ; --i) {
+	r = ldexp(r, DIGIT_BIT) + b.dp[i];
+    }
+    mp_clear(&b);
+
+    /*
+     * Scale the result to the correct number of bits.
+     */
+
+    r = ldexp(r, bits - mantBits);
+
+    /*
+     * Return the result with the appropriate sign.
+     */
+
+    if (a->sign == MP_ZPOS) {
+	return r;
+    } else {
+	return -r;
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclCeil --
+ *
+ *	Computes the smallest floating point number that is at least the
+ *	mp_int argument.
+ *
+ * Results:
+ *	Returns the floating point number.
+ *
+ *----------------------------------------------------------------------
+ */
+
+double
+TclCeil(
+    const mp_int *a)			/* Integer to convert. */
+{
+    double r = 0.0;
+    mp_int b;
+
+    mp_init(&b);
+    if (mp_cmp_d(a, 0) == MP_LT) {
+	mp_neg(a, &b);
+	r = -TclFloor(&b);
+    } else {
+	int bits = mp_count_bits(a);
+
+	if (bits > DBL_MAX_EXP*log2FLT_RADIX) {
+	    r = HUGE_VAL;
+	} else {
+	    int i, exact = 1, shift = mantBits - bits;
+
+	    if (shift > 0) {
+		mp_mul_2d(a, shift, &b);
+	    } else if (shift < 0) {
+		mp_int d;
+		mp_init(&d);
+		mp_div_2d(a, -shift, &b, &d);
+		exact = mp_iszero(&d);
+		mp_clear(&d);
+	    } else {
+		mp_copy(a, &b);
+	    }
+	    if (!exact) {
+		mp_add_d(&b, 1, &b);
+	    }
+	    for (i=b.used-1 ; i>=0 ; --i) {
+		r = ldexp(r, DIGIT_BIT) + b.dp[i];
+	    }
+	    r = ldexp(r, bits - mantBits);
+	}
+    }
+    mp_clear(&b);
+    return r;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclFloor --
+ *
+ *	Computes the largest floating point number less than or equal to the
+ *	mp_int argument.
+ *
+ * Results:
+ *	Returns the floating point value.
+ *
+ *----------------------------------------------------------------------
+ */
+
+double
+TclFloor(
+    const mp_int *a)			/* Integer to convert. */
+{
+    double r = 0.0;
+    mp_int b;
+
+    mp_init(&b);
+    if (mp_cmp_d(a, 0) == MP_LT) {
+	mp_neg(a, &b);
+	r = -TclCeil(&b);
+    } else {
+	int bits = mp_count_bits(a);
+
+	if (bits > DBL_MAX_EXP*log2FLT_RADIX) {
+	    r = DBL_MAX;
+	} else {
+	    int i, shift = mantBits - bits;
+
+	    if (shift > 0) {
+		mp_mul_2d(a, shift, &b);
+	    } else if (shift < 0) {
+		mp_div_2d(a, -shift, &b, NULL);
+	    } else {
+		mp_copy(a, &b);
+	    }
+	    for (i=b.used-1 ; i>=0 ; --i) {
+		r = ldexp(r, DIGIT_BIT) + b.dp[i];
+	    }
+	    r = ldexp(r, bits - mantBits);
+	}
+    }
+    mp_clear(&b);
+    return r;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * BignumToBiasedFrExp --
+ *
+ *	Convert an arbitrary-precision integer to a native floating point
+ *	number in the range [0.5,1) times a power of two. NOTE: Intentionally
+ *	converts to a number that's a few ulp too small, so that
+ *	RefineApproximation will not overflow near the high end of the
+ *	machine's arithmetic range.
+ *
+ * Results:
+ *	Returns the converted number.
+ *
+ * Side effects:
+ *	Stores the exponent of two in 'machexp'.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static double
+BignumToBiasedFrExp(
+    const mp_int *a,		/* Integer to convert. */
+    int *machexp)		/* Power of two. */
+{
+    mp_int b;
+    int bits;
+    int shift;
+    int i;
+    double r;
+
+    /*
+     * Determine how many bits we need, and extract that many from the input.
+     * Round to nearest unit in the last place.
+     */
+
+    bits = mp_count_bits(a);
+    shift = mantBits - 2 - bits;
+    mp_init(&b);
+    if (shift > 0) {
+	mp_mul_2d(a, shift, &b);
+    } else if (shift < 0) {
+	mp_div_2d(a, -shift, &b, NULL);
+    } else {
+	mp_copy(a, &b);
+    }
+
+    /*
+     * Accumulate the result, one mp_digit at a time.
+     */
+
+    r = 0.0;
+    for (i=b.used-1; i>=0; --i) {
+	r = ldexp(r, DIGIT_BIT) + b.dp[i];
+    }
+    mp_clear(&b);
+
+    /*
+     * Return the result with the appropriate sign.
+     */
+
+    *machexp = bits - mantBits + 2;
+    return ((a->sign == MP_ZPOS) ? r : -r);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Pow10TimesFrExp --
+ *
+ *	Multiply a power of ten by a number expressed as fraction and
+ *	exponent.
+ *
+ * Results:
+ *	Returns the significand of the result.
+ *
+ * Side effects:
+ *	Overwrites the 'machexp' parameter with the exponent of the result.
+ *
+ * Assumes that 'exponent' is such that 10**exponent would be a double, even
+ * though 'fraction*10**(machexp+exponent)' might overflow.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static double
+Pow10TimesFrExp(
+    int exponent,		/* Power of 10 to multiply by. */
+    double fraction,		/* Significand of multiplicand. */
+    int *machexp)		/* On input, exponent of multiplicand. On
+				 * output, exponent of result. */
+{
+    int i, j;
+    int expt = *machexp;
+    double retval = fraction;
+
+    if (exponent > 0) {
+	/*
+	 * Multiply by 10**exponent.
+	 */
+
+	retval = frexp(retval * pow10vals[exponent&0xf], &j);
+	expt += j;
+	for (i=4; i<9; ++i) {
+	    if (exponent & (1<<i)) {
+		retval = frexp(retval * pow_10_2_n[i], &j);
+		expt += j;
+	    }
+	}
+    } else if (exponent < 0) {
+	/*
+	 * Divide by 10**-exponent.
+	 */
+
+	retval = frexp(retval / pow10vals[(-exponent) & 0xf], &j);
+	expt += j;
+	for (i=4; i<9; ++i) {
+	    if ((-exponent) & (1<<i)) {
+		retval = frexp(retval / pow_10_2_n[i], &j);
+		expt += j;
+	    }
+	}
+    }
+
+    *machexp = expt;
+    return retval;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * SafeLdExp --
+ *
+ *	Do an 'ldexp' operation, but handle denormals gracefully.
+ *
+ * Results:
+ *	Returns the appropriately scaled value.
+ *
+ *	On some platforms, 'ldexp' fails when presented with a number too
+ *	small to represent as a normalized double. This routine does 'ldexp'
+ *	in two steps for those numbers, to return correctly denormalized
+ *	values.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static double
+SafeLdExp(
+    double fract,
+    int expt)
+{
+    int minexpt = DBL_MIN_EXP * log2FLT_RADIX;
+    volatile double a, b, retval;
+
+    if (expt < minexpt) {
+	a = ldexp(fract, expt - mantBits - minexpt);
+	b = ldexp(1.0, mantBits + minexpt);
+	retval = a * b;
+    } else {
+	retval = ldexp(fract, expt);
+    }
+    return retval;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclFormatNaN --
+ *
+ *	Makes the string representation of a "Not a Number"
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Stores the string representation in the supplied buffer, which must be
+ *	at least TCL_DOUBLE_SPACE characters.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclFormatNaN(
+    double value,		/* The Not-a-Number to format. */
+    char *buffer)		/* String representation. */
+{
+#ifndef IEEE_FLOATING_POINT
+    strcpy(buffer, "NaN");
+    return;
+#else
+    union {
+	double dv;
+	Tcl_WideUInt iv;
+    } bitwhack;
+
+    bitwhack.dv = value;
+    if (n770_fp) {
+	bitwhack.iv = Nokia770Twiddle(bitwhack.iv);
+    }
+    if (bitwhack.iv & ((Tcl_WideUInt) 1 << 63)) {
+	bitwhack.iv &= ~ ((Tcl_WideUInt) 1 << 63);
+	*buffer++ = '-';
+    }
+    *buffer++ = 'N';
+    *buffer++ = 'a';
+    *buffer++ = 'N';
+    bitwhack.iv &= (((Tcl_WideUInt) 1) << 51) - 1;
+    if (bitwhack.iv != 0) {
+	sprintf(buffer, "(%" TCL_LL_MODIFIER "x)", bitwhack.iv);
+    } else {
+	*buffer = '\0';
+    }
+#endif /* IEEE_FLOATING_POINT */
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Nokia770Twiddle --
+ *
+ *	Transpose the two words of a number for Nokia 770 floating point
+ *	handling.
+ *
+ *----------------------------------------------------------------------
+ */
+#ifdef IEEE_FLOATING_POINT
+static Tcl_WideUInt
+Nokia770Twiddle(
+    Tcl_WideUInt w)		/* Number to transpose. */
+{
+    return (((w >> 32) & 0xffffffff) | (w << 32));
+}
+#endif
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclNokia770Doubles --
+ *
+ *	Transpose the two words of a number for Nokia 770 floating point
+ *	handling.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclNokia770Doubles(void)
+{
+    return n770_fp;
+}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tclStringObj.c b/generic/tclStringObj.c
new file mode 100644
index 0000000..11a57e9
--- /dev/null
+++ b/generic/tclStringObj.c
@@ -0,0 +1,3128 @@
+/*
+ * tclStringObj.c --
+ *
+ *	This file contains functions that implement string operations on Tcl
+ *	objects. Some string operations work with UTF strings and others
+ *	require Unicode format. Functions that require knowledge of the width
+ *	of each character, such as indexing, operate on Unicode data.
+ *
+ *	A Unicode string is an internationalized string. Conceptually, a
+ *	Unicode string is an array of 16-bit quantities organized as a
+ *	sequence of properly formed UTF-8 characters. There is a one-to-one
+ *	map between Unicode and UTF characters. Because Unicode characters
+ *	have a fixed width, operations such as indexing operate on Unicode
+ *	data. The String object is optimized for the case where each UTF char
+ *	in a string is only one byte. In this case, we store the value of
+ *	numChars, but we don't store the Unicode data (unless Tcl_GetUnicode
+ *	is explicitly called).
+ *
+ *	The String object type stores one or both formats. The default
+ *	behavior is to store UTF. Once Unicode is calculated by a function, it
+ *	is stored in the internal rep for future access (without an additional
+ *	O(n) cost).
+ *
+ *	To allow many appends to be done to an object without constantly
+ *	reallocating the space for the string or Unicode representation, we
+ *	allocate double the space for the string or Unicode and use the
+ *	internal representation to keep track of how much space is used vs.
+ *	allocated.
+ *
+ * Copyright (c) 1995-1997 Sun Microsystems, Inc.
+ * Copyright (c) 1999 by Scriptics Corporation.
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#include "tclInt.h"
+#include "tommath.h"
+#include "tclStringRep.h"
+
+/*
+ * Set COMPAT to 1 to restore the shimmering patterns to those of Tcl 8.5.
+ * This is an escape hatch in case the changes have some unexpected unwelcome
+ * impact on performance. If things go well, this mechanism can go away when
+ * post-8.6 development begins.
+ */
+
+#define COMPAT 0
+
+/*
+ * Prototypes for functions defined later in this file:
+ */
+
+static void		AppendPrintfToObjVA(Tcl_Obj *objPtr,
+			    const char *format, va_list argList);
+static void		AppendUnicodeToUnicodeRep(Tcl_Obj *objPtr,
+			    const Tcl_UniChar *unicode, int appendNumChars);
+static void		AppendUnicodeToUtfRep(Tcl_Obj *objPtr,
+			    const Tcl_UniChar *unicode, int numChars);
+static void		AppendUtfToUnicodeRep(Tcl_Obj *objPtr,
+			    const char *bytes, int numBytes);
+static void		AppendUtfToUtfRep(Tcl_Obj *objPtr,
+			    const char *bytes, int numBytes);
+static void		DupStringInternalRep(Tcl_Obj *objPtr,
+			    Tcl_Obj *copyPtr);
+static int		ExtendStringRepWithUnicode(Tcl_Obj *objPtr,
+			    const Tcl_UniChar *unicode, int numChars);
+static void		ExtendUnicodeRepWithString(Tcl_Obj *objPtr,
+			    const char *bytes, int numBytes,
+			    int numAppendChars);
+static void		FillUnicodeRep(Tcl_Obj *objPtr);
+static void		FreeStringInternalRep(Tcl_Obj *objPtr);
+static void		GrowStringBuffer(Tcl_Obj *objPtr, int needed, int flag);
+static void		GrowUnicodeBuffer(Tcl_Obj *objPtr, int needed);
+static int		SetStringFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr);
+static void		SetUnicodeObj(Tcl_Obj *objPtr,
+			    const Tcl_UniChar *unicode, int numChars);
+static int		UnicodeLength(const Tcl_UniChar *unicode);
+static void		UpdateStringOfString(Tcl_Obj *objPtr);
+
+/*
+ * The structure below defines the string Tcl object type by means of
+ * functions that can be invoked by generic object code.
+ */
+
+const Tcl_ObjType tclStringType = {
+    "string",			/* name */
+    FreeStringInternalRep,	/* freeIntRepPro */
+    DupStringInternalRep,	/* dupIntRepProc */
+    UpdateStringOfString,	/* updateStringProc */
+    SetStringFromAny		/* setFromAnyProc */
+};
+
+/*
+ * TCL STRING GROWTH ALGORITHM
+ *
+ * When growing strings (during an append, for example), the following growth
+ * algorithm is used:
+ *
+ *   Attempt to allocate 2 * (originalLength + appendLength)
+ *   On failure:
+ *	attempt to allocate originalLength + 2*appendLength + TCL_MIN_GROWTH
+ *
+ * This algorithm allows very good performance, as it rapidly increases the
+ * memory allocated for a given string, which minimizes the number of
+ * reallocations that must be performed. However, using only the doubling
+ * algorithm can lead to a significant waste of memory. In particular, it may
+ * fail even when there is sufficient memory available to complete the append
+ * request (but there is not 2*totalLength memory available). So when the
+ * doubling fails (because there is not enough memory available), the
+ * algorithm requests a smaller amount of memory, which is still enough to
+ * cover the request, but which hopefully will be less than the total
+ * available memory.
+ *
+ * The addition of TCL_MIN_GROWTH allows for efficient handling of very
+ * small appends. Without this extra slush factor, a sequence of several small
+ * appends would cause several memory allocations. As long as
+ * TCL_MIN_GROWTH is a reasonable size, we can avoid that behavior.
+ *
+ * The growth algorithm can be tuned by adjusting the following parameters:
+ *
+ * TCL_MIN_GROWTH		Additional space, in bytes, to allocate when
+ *				the double allocation has failed. Default is
+ *				1024 (1 kilobyte).  See tclInt.h.
+ */
+
+#ifndef TCL_MIN_UNICHAR_GROWTH
+#define TCL_MIN_UNICHAR_GROWTH	TCL_MIN_GROWTH/sizeof(Tcl_UniChar)
+#endif
+
+static void
+GrowStringBuffer(
+    Tcl_Obj *objPtr,
+    int needed,
+    int flag)
+{
+    /*
+     * Pre-conditions:
+     *	objPtr->typePtr == &tclStringType
+     *	needed > stringPtr->allocated
+     *	flag || objPtr->bytes != NULL
+     */
+
+    String *stringPtr = GET_STRING(objPtr);
+    char *ptr = NULL;
+    int attempt;
+
+    if (objPtr->bytes == tclEmptyStringRep) {
+	objPtr->bytes = NULL;
+    }
+    if (flag == 0 || stringPtr->allocated > 0) {
+	attempt = 2 * needed;
+	if (attempt >= 0) {
+	    ptr = attemptckrealloc(objPtr->bytes, attempt + 1);
+	}
+	if (ptr == NULL) {
+	    /*
+	     * Take care computing the amount of modest growth to avoid
+	     * overflow into invalid argument values for attempt.
+	     */
+
+	    unsigned int limit = INT_MAX - needed;
+	    unsigned int extra = needed - objPtr->length + TCL_MIN_GROWTH;
+	    int growth = (int) ((extra > limit) ? limit : extra);
+
+	    attempt = needed + growth;
+	    ptr = attemptckrealloc(objPtr->bytes, attempt + 1);
+	}
+    }
+    if (ptr == NULL) {
+	/*
+	 * First allocation - just big enough; or last chance fallback.
+	 */
+
+	attempt = needed;
+	ptr = ckrealloc(objPtr->bytes, attempt + 1);
+    }
+    objPtr->bytes = ptr;
+    stringPtr->allocated = attempt;
+}
+
+static void
+GrowUnicodeBuffer(
+    Tcl_Obj *objPtr,
+    int needed)
+{
+    /*
+     * Pre-conditions:
+     *	objPtr->typePtr == &tclStringType
+     *	needed > stringPtr->maxChars
+     *	needed < STRING_MAXCHARS
+     */
+
+    String *ptr = NULL, *stringPtr = GET_STRING(objPtr);
+    int attempt;
+
+    if (stringPtr->maxChars > 0) {
+	/*
+	 * Subsequent appends - apply the growth algorithm.
+	 */
+
+	attempt = 2 * needed;
+	if (attempt >= 0 && attempt <= STRING_MAXCHARS) {
+	    ptr = stringAttemptRealloc(stringPtr, attempt);
+	}
+	if (ptr == NULL) {
+	    /*
+	     * Take care computing the amount of modest growth to avoid
+	     * overflow into invalid argument values for attempt.
+	     */
+
+	    unsigned int limit = STRING_MAXCHARS - needed;
+	    unsigned int extra = needed - stringPtr->numChars
+		    + TCL_MIN_UNICHAR_GROWTH;
+	    int growth = (int) ((extra > limit) ? limit : extra);
+
+	    attempt = needed + growth;
+	    ptr = stringAttemptRealloc(stringPtr, attempt);
+	}
+    }
+    if (ptr == NULL) {
+	/*
+	 * First allocation - just big enough; or last chance fallback.
+	 */
+
+	attempt = needed;
+	ptr = stringRealloc(stringPtr, attempt);
+    }
+    stringPtr = ptr;
+    stringPtr->maxChars = attempt;
+    SET_STRING(objPtr, stringPtr);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_NewStringObj --
+ *
+ *	This function is normally called when not debugging: i.e., when
+ *	TCL_MEM_DEBUG is not defined. It creates a new string object and
+ *	initializes it from the byte pointer and length arguments.
+ *
+ *	When TCL_MEM_DEBUG is defined, this function just returns the result
+ *	of calling the debugging version Tcl_DbNewStringObj.
+ *
+ * Results:
+ *	A newly created string object is returned that has ref count zero.
+ *
+ * Side effects:
+ *	The new object's internal string representation will be set to a copy
+ *	of the length bytes starting at "bytes". If "length" is negative, use
+ *	bytes up to the first NUL byte; i.e., assume "bytes" points to a
+ *	C-style NUL-terminated string. The object's type is set to NULL. An
+ *	extra NUL is added to the end of the new object's byte array.
+ *
+ *----------------------------------------------------------------------
+ */
+
+#ifdef TCL_MEM_DEBUG
+#undef Tcl_NewStringObj
+Tcl_Obj *
+Tcl_NewStringObj(
+    const char *bytes,		/* Points to the first of the length bytes
+				 * used to initialize the new object. */
+    int length)			/* The number of bytes to copy from "bytes"
+				 * when initializing the new object. If
+				 * negative, use bytes up to the first NUL
+				 * byte. */
+{
+    return Tcl_DbNewStringObj(bytes, length, "unknown", 0);
+}
+#else /* if not TCL_MEM_DEBUG */
+Tcl_Obj *
+Tcl_NewStringObj(
+    const char *bytes,		/* Points to the first of the length bytes
+				 * used to initialize the new object. */
+    int length)			/* The number of bytes to copy from "bytes"
+				 * when initializing the new object. If
+				 * negative, use bytes up to the first NUL
+				 * byte. */
+{
+    Tcl_Obj *objPtr;
+
+    if (length < 0) {
+	length = (bytes? strlen(bytes) : 0);
+    }
+    TclNewStringObj(objPtr, bytes, length);
+    return objPtr;
+}
+#endif /* TCL_MEM_DEBUG */
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_DbNewStringObj --
+ *
+ *	This function is normally called when debugging: i.e., when
+ *	TCL_MEM_DEBUG is defined. It creates new string objects. It is the
+ *	same as the Tcl_NewStringObj function above except that it calls
+ *	Tcl_DbCkalloc directly with the file name and line number from its
+ *	caller. This simplifies debugging since then the [memory active]
+ *	command will report the correct file name and line number when
+ *	reporting objects that haven't been freed.
+ *
+ *	When TCL_MEM_DEBUG is not defined, this function just returns the
+ *	result of calling Tcl_NewStringObj.
+ *
+ * Results:
+ *	A newly created string object is returned that has ref count zero.
+ *
+ * Side effects:
+ *	The new object's internal string representation will be set to a copy
+ *	of the length bytes starting at "bytes". If "length" is negative, use
+ *	bytes up to the first NUL byte; i.e., assume "bytes" points to a
+ *	C-style NUL-terminated string. The object's type is set to NULL. An
+ *	extra NUL is added to the end of the new object's byte array.
+ *
+ *----------------------------------------------------------------------
+ */
+
+#ifdef TCL_MEM_DEBUG
+Tcl_Obj *
+Tcl_DbNewStringObj(
+    const char *bytes,		/* Points to the first of the length bytes
+				 * used to initialize the new object. */
+    int length,			/* The number of bytes to copy from "bytes"
+				 * when initializing the new object. If
+				 * negative, use bytes up to the first NUL
+				 * byte. */
+    const char *file,		/* The name of the source file calling this
+				 * function; used for debugging. */
+    int line)			/* Line number in the source file; used for
+				 * debugging. */
+{
+    Tcl_Obj *objPtr;
+
+    if (length < 0) {
+	length = (bytes? strlen(bytes) : 0);
+    }
+    TclDbNewObj(objPtr, file, line);
+    TclInitStringRep(objPtr, bytes, length);
+    return objPtr;
+}
+#else /* if not TCL_MEM_DEBUG */
+Tcl_Obj *
+Tcl_DbNewStringObj(
+    const char *bytes,		/* Points to the first of the length bytes
+				 * used to initialize the new object. */
+    int length,			/* The number of bytes to copy from "bytes"
+				 * when initializing the new object. If
+				 * negative, use bytes up to the first NUL
+				 * byte. */
+    const char *file,		/* The name of the source file calling this
+				 * function; used for debugging. */
+    int line)			/* Line number in the source file; used for
+				 * debugging. */
+{
+    return Tcl_NewStringObj(bytes, length);
+}
+#endif /* TCL_MEM_DEBUG */
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Tcl_NewUnicodeObj --
+ *
+ *	This function is creates a new String object and initializes it from
+ *	the given Unicode String. If the Utf String is the same size as the
+ *	Unicode string, don't duplicate the data.
+ *
+ * Results:
+ *	The newly created object is returned. This object will have no initial
+ *	string representation. The returned object has a ref count of 0.
+ *
+ * Side effects:
+ *	Memory allocated for new object and copy of Unicode argument.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+Tcl_Obj *
+Tcl_NewUnicodeObj(
+    const Tcl_UniChar *unicode,	/* The unicode string used to initialize the
+				 * new object. */
+    int numChars)		/* Number of characters in the unicode
+				 * string. */
+{
+    Tcl_Obj *objPtr;
+
+    TclNewObj(objPtr);
+    SetUnicodeObj(objPtr, unicode, numChars);
+    return objPtr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_GetCharLength --
+ *
+ *	Get the length of the Unicode string from the Tcl object.
+ *
+ * Results:
+ *	Pointer to unicode string representing the unicode object.
+ *
+ * Side effects:
+ *	Frees old internal rep. Allocates memory for new "String" internal
+ *	rep.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_GetCharLength(
+    Tcl_Obj *objPtr)		/* The String object to get the num chars
+				 * of. */
+{
+    String *stringPtr;
+    int numChars;
+
+    /*
+     * Optimize the case where we're really dealing with a bytearray object
+     * without string representation; we don't need to convert to a string to
+     * perform the get-length operation.
+     */
+
+    if (TclIsPureByteArray(objPtr)) {
+	int length;
+
+	(void) Tcl_GetByteArrayFromObj(objPtr, &length);
+	return length;
+    }
+
+    /*
+     * OK, need to work with the object as a string.
+     */
+
+    SetStringFromAny(NULL, objPtr);
+    stringPtr = GET_STRING(objPtr);
+    numChars = stringPtr->numChars;
+
+    /*
+     * If numChars is unknown, compute it.
+     */
+
+    if (numChars == -1) {
+	TclNumUtfChars(numChars, objPtr->bytes, objPtr->length);
+	stringPtr->numChars = numChars;
+
+#if COMPAT
+	if (numChars < objPtr->length) {
+	    /*
+	     * Since we've just computed the number of chars, and not all UTF
+	     * chars are 1-byte long, go ahead and populate the unicode
+	     * string.
+	     */
+
+	    FillUnicodeRep(objPtr);
+	}
+#endif
+    }
+    return numChars;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_GetUniChar --
+ *
+ *	Get the index'th Unicode character from the String object. The index
+ *	is assumed to be in the appropriate range.
+ *
+ * Results:
+ *	Returns the index'th Unicode character in the Object.
+ *
+ * Side effects:
+ *	Fills unichar with the index'th Unicode character.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_UniChar
+Tcl_GetUniChar(
+    Tcl_Obj *objPtr,		/* The object to get the Unicode charater
+				 * from. */
+    int index)			/* Get the index'th Unicode character. */
+{
+    String *stringPtr;
+
+    /*
+     * Optimize the case where we're really dealing with a bytearray object
+     * without string representation; we don't need to convert to a string to
+     * perform the indexing operation.
+     */
+
+    if (TclIsPureByteArray(objPtr)) {
+	unsigned char *bytes = Tcl_GetByteArrayFromObj(objPtr, NULL);
+
+	return (Tcl_UniChar) bytes[index];
+    }
+
+    /*
+     * OK, need to work with the object as a string.
+     */
+
+    SetStringFromAny(NULL, objPtr);
+    stringPtr = GET_STRING(objPtr);
+
+    if (stringPtr->hasUnicode == 0) {
+	/*
+	 * If numChars is unknown, compute it.
+	 */
+
+	if (stringPtr->numChars == -1) {
+	    TclNumUtfChars(stringPtr->numChars, objPtr->bytes, objPtr->length);
+	}
+	if (stringPtr->numChars == objPtr->length) {
+	    return (Tcl_UniChar) objPtr->bytes[index];
+	}
+	FillUnicodeRep(objPtr);
+	stringPtr = GET_STRING(objPtr);
+    }
+    return stringPtr->unicode[index];
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_GetUnicode --
+ *
+ *	Get the Unicode form of the String object. If the object is not
+ *	already a String object, it will be converted to one. If the String
+ *	object does not have a Unicode rep, then one is create from the UTF
+ *	string format.
+ *
+ * Results:
+ *	Returns a pointer to the object's internal Unicode string.
+ *
+ * Side effects:
+ *	Converts the object to have the String internal rep.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_UniChar *
+Tcl_GetUnicode(
+    Tcl_Obj *objPtr)		/* The object to find the unicode string
+				 * for. */
+{
+    return Tcl_GetUnicodeFromObj(objPtr, NULL);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_GetUnicodeFromObj --
+ *
+ *	Get the Unicode form of the String object with length. If the object
+ *	is not already a String object, it will be converted to one. If the
+ *	String object does not have a Unicode rep, then one is create from the
+ *	UTF string format.
+ *
+ * Results:
+ *	Returns a pointer to the object's internal Unicode string.
+ *
+ * Side effects:
+ *	Converts the object to have the String internal rep.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_UniChar *
+Tcl_GetUnicodeFromObj(
+    Tcl_Obj *objPtr,		/* The object to find the unicode string
+				 * for. */
+    int *lengthPtr)		/* If non-NULL, the location where the string
+				 * rep's unichar length should be stored. If
+				 * NULL, no length is stored. */
+{
+    String *stringPtr;
+
+    SetStringFromAny(NULL, objPtr);
+    stringPtr = GET_STRING(objPtr);
+
+    if (stringPtr->hasUnicode == 0) {
+	FillUnicodeRep(objPtr);
+	stringPtr = GET_STRING(objPtr);
+    }
+
+    if (lengthPtr != NULL) {
+	*lengthPtr = stringPtr->numChars;
+    }
+    return stringPtr->unicode;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_GetRange --
+ *
+ *	Create a Tcl Object that contains the chars between first and last of
+ *	the object indicated by "objPtr". If the object is not already a
+ *	String object, convert it to one. The first and last indices are
+ *	assumed to be in the appropriate range.
+ *
+ * Results:
+ *	Returns a new Tcl Object of the String type.
+ *
+ * Side effects:
+ *	Changes the internal rep of "objPtr" to the String type.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_Obj *
+Tcl_GetRange(
+    Tcl_Obj *objPtr,		/* The Tcl object to find the range of. */
+    int first,			/* First index of the range. */
+    int last)			/* Last index of the range. */
+{
+    Tcl_Obj *newObjPtr;		/* The Tcl object to find the range of. */
+    String *stringPtr;
+
+    /*
+     * Optimize the case where we're really dealing with a bytearray object
+     * without string representation; we don't need to convert to a string to
+     * perform the substring operation.
+     */
+
+    if (TclIsPureByteArray(objPtr)) {
+	unsigned char *bytes = Tcl_GetByteArrayFromObj(objPtr, NULL);
+
+	return Tcl_NewByteArrayObj(bytes+first, last-first+1);
+    }
+
+    /*
+     * OK, need to work with the object as a string.
+     */
+
+    SetStringFromAny(NULL, objPtr);
+    stringPtr = GET_STRING(objPtr);
+
+    if (stringPtr->hasUnicode == 0) {
+	/*
+	 * If numChars is unknown, compute it.
+	 */
+
+	if (stringPtr->numChars == -1) {
+	    TclNumUtfChars(stringPtr->numChars, objPtr->bytes, objPtr->length);
+	}
+	if (stringPtr->numChars == objPtr->length) {
+	    newObjPtr = Tcl_NewStringObj(objPtr->bytes + first, last-first+1);
+
+	    /*
+	     * Since we know the char length of the result, store it.
+	     */
+
+	    SetStringFromAny(NULL, newObjPtr);
+	    stringPtr = GET_STRING(newObjPtr);
+	    stringPtr->numChars = newObjPtr->length;
+	    return newObjPtr;
+	}
+	FillUnicodeRep(objPtr);
+	stringPtr = GET_STRING(objPtr);
+    }
+
+    return Tcl_NewUnicodeObj(stringPtr->unicode + first, last-first+1);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_SetStringObj --
+ *
+ *	Modify an object to hold a string that is a copy of the bytes
+ *	indicated by the byte pointer and length arguments.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The object's string representation will be set to a copy of the
+ *	"length" bytes starting at "bytes". If "length" is negative, use bytes
+ *	up to the first NUL byte; i.e., assume "bytes" points to a C-style
+ *	NUL-terminated string. The object's old string and internal
+ *	representations are freed and the object's type is set NULL.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_SetStringObj(
+    Tcl_Obj *objPtr,		/* Object whose internal rep to init. */
+    const char *bytes,		/* Points to the first of the length bytes
+				 * used to initialize the object. */
+    int length)			/* The number of bytes to copy from "bytes"
+				 * when initializing the object. If negative,
+				 * use bytes up to the first NUL byte.*/
+{
+    if (Tcl_IsShared(objPtr)) {
+	Tcl_Panic("%s called with shared object", "Tcl_SetStringObj");
+    }
+
+    /*
+     * Set the type to NULL and free any internal rep for the old type.
+     */
+
+    TclFreeIntRep(objPtr);
+
+    /*
+     * Free any old string rep, then set the string rep to a copy of the
+     * length bytes starting at "bytes".
+     */
+
+    TclInvalidateStringRep(objPtr);
+    if (length < 0) {
+	length = (bytes? strlen(bytes) : 0);
+    }
+    TclInitStringRep(objPtr, bytes, length);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_SetObjLength --
+ *
+ *	This function changes the length of the string representation of an
+ *	object.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	If the size of objPtr's string representation is greater than length,
+ *	then it is reduced to length and a new terminating null byte is stored
+ *	in the strength. If the length of the string representation is greater
+ *	than length, the storage space is reallocated to the given length; a
+ *	null byte is stored at the end, but other bytes past the end of the
+ *	original string representation are undefined. The object's internal
+ *	representation is changed to "expendable string".
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_SetObjLength(
+    Tcl_Obj *objPtr,		/* Pointer to object. This object must not
+				 * currently be shared. */
+    int length)			/* Number of bytes desired for string
+				 * representation of object, not including
+				 * terminating null byte. */
+{
+    String *stringPtr;
+
+    if (length < 0) {
+	/*
+	 * Setting to a negative length is nonsense. This is probably the
+	 * result of overflowing the signed integer range.
+	 */
+
+	Tcl_Panic("Tcl_SetObjLength: negative length requested: "
+		"%d (integer overflow?)", length);
+    }
+    if (Tcl_IsShared(objPtr)) {
+	Tcl_Panic("%s called with shared object", "Tcl_SetObjLength");
+    }
+
+    if (objPtr->bytes && objPtr->length == length) {
+	return;
+    }
+
+    SetStringFromAny(NULL, objPtr);
+    stringPtr = GET_STRING(objPtr);
+
+    if (objPtr->bytes != NULL) {
+	/*
+	 * Change length of an existing string rep.
+	 */
+	if (length > stringPtr->allocated) {
+	    /*
+	     * Need to enlarge the buffer.
+	     */
+	    if (objPtr->bytes == tclEmptyStringRep) {
+		objPtr->bytes = ckalloc(length + 1);
+	    } else {
+		objPtr->bytes = ckrealloc(objPtr->bytes, length + 1);
+	    }
+	    stringPtr->allocated = length;
+	}
+
+	objPtr->length = length;
+	objPtr->bytes[length] = 0;
+
+	/*
+	 * Invalidate the unicode data.
+	 */
+
+	stringPtr->numChars = -1;
+	stringPtr->hasUnicode = 0;
+    } else {
+	/*
+	 * Changing length of pure unicode string.
+	 */
+
+	stringCheckLimits(length);
+	if (length > stringPtr->maxChars) {
+	    stringPtr = stringRealloc(stringPtr, length);
+	    SET_STRING(objPtr, stringPtr);
+	    stringPtr->maxChars = length;
+	}
+
+	/*
+	 * Mark the new end of the unicode string
+	 */
+
+	stringPtr->numChars = length;
+	stringPtr->unicode[length] = 0;
+	stringPtr->hasUnicode = 1;
+
+	/*
+	 * Can only get here when objPtr->bytes == NULL. No need to invalidate
+	 * the string rep.
+	 */
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_AttemptSetObjLength --
+ *
+ *	This function changes the length of the string representation of an
+ *	object. It uses the attempt* (non-panic'ing) memory allocators.
+ *
+ * Results:
+ *	1 if the requested memory was allocated, 0 otherwise.
+ *
+ * Side effects:
+ *	If the size of objPtr's string representation is greater than length,
+ *	then it is reduced to length and a new terminating null byte is stored
+ *	in the strength. If the length of the string representation is greater
+ *	than length, the storage space is reallocated to the given length; a
+ *	null byte is stored at the end, but other bytes past the end of the
+ *	original string representation are undefined. The object's internal
+ *	representation is changed to "expendable string".
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_AttemptSetObjLength(
+    Tcl_Obj *objPtr,		/* Pointer to object. This object must not
+				 * currently be shared. */
+    int length)			/* Number of bytes desired for string
+				 * representation of object, not including
+				 * terminating null byte. */
+{
+    String *stringPtr;
+
+    if (length < 0) {
+	/*
+	 * Setting to a negative length is nonsense. This is probably the
+	 * result of overflowing the signed integer range.
+	 */
+
+	return 0;
+    }
+    if (Tcl_IsShared(objPtr)) {
+	Tcl_Panic("%s called with shared object", "Tcl_AttemptSetObjLength");
+    }
+    if (objPtr->bytes && objPtr->length == length) {
+	return 1;
+    }
+
+    SetStringFromAny(NULL, objPtr);
+    stringPtr = GET_STRING(objPtr);
+
+    if (objPtr->bytes != NULL) {
+	/*
+	 * Change length of an existing string rep.
+	 */
+	if (length > stringPtr->allocated) {
+	    /*
+	     * Need to enlarge the buffer.
+	     */
+
+	    char *newBytes;
+
+	    if (objPtr->bytes == tclEmptyStringRep) {
+		newBytes = attemptckalloc(length + 1);
+	    } else {
+		newBytes = attemptckrealloc(objPtr->bytes, length + 1);
+	    }
+	    if (newBytes == NULL) {
+		return 0;
+	    }
+	    objPtr->bytes = newBytes;
+	    stringPtr->allocated = length;
+	}
+
+	objPtr->length = length;
+	objPtr->bytes[length] = 0;
+
+	/*
+	 * Invalidate the unicode data.
+	 */
+
+	stringPtr->numChars = -1;
+	stringPtr->hasUnicode = 0;
+    } else {
+	/*
+	 * Changing length of pure unicode string.
+	 */
+
+	if (length > STRING_MAXCHARS) {
+	    return 0;
+	}
+	if (length > stringPtr->maxChars) {
+	    stringPtr = stringAttemptRealloc(stringPtr, length);
+	    if (stringPtr == NULL) {
+		return 0;
+	    }
+	    SET_STRING(objPtr, stringPtr);
+	    stringPtr->maxChars = length;
+	}
+
+	/*
+	 * Mark the new end of the unicode string.
+	 */
+
+	stringPtr->unicode[length] = 0;
+	stringPtr->numChars = length;
+	stringPtr->hasUnicode = 1;
+
+	/*
+	 * Can only get here when objPtr->bytes == NULL. No need to invalidate
+	 * the string rep.
+	 */
+    }
+    return 1;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Tcl_SetUnicodeObj --
+ *
+ *	Modify an object to hold the Unicode string indicated by "unicode".
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Memory allocated for new "String" internal rep.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+void
+Tcl_SetUnicodeObj(
+    Tcl_Obj *objPtr,		/* The object to set the string of. */
+    const Tcl_UniChar *unicode,	/* The unicode string used to initialize the
+				 * object. */
+    int numChars)		/* Number of characters in the unicode
+				 * string. */
+{
+    if (Tcl_IsShared(objPtr)) {
+	Tcl_Panic("%s called with shared object", "Tcl_SetUnicodeObj");
+    }
+    TclFreeIntRep(objPtr);
+    SetUnicodeObj(objPtr, unicode, numChars);
+}
+
+static int
+UnicodeLength(
+    const Tcl_UniChar *unicode)
+{
+    int numChars = 0;
+
+    if (unicode) {
+	while (numChars >= 0 && unicode[numChars] != 0) {
+	    numChars++;
+	}
+    }
+    stringCheckLimits(numChars);
+    return numChars;
+}
+
+static void
+SetUnicodeObj(
+    Tcl_Obj *objPtr,		/* The object to set the string of. */
+    const Tcl_UniChar *unicode,	/* The unicode string used to initialize the
+				 * object. */
+    int numChars)		/* Number of characters in the unicode
+				 * string. */
+{
+    String *stringPtr;
+
+    if (numChars < 0) {
+	numChars = UnicodeLength(unicode);
+    }
+
+    /*
+     * Allocate enough space for the String structure + Unicode string.
+     */
+
+    stringCheckLimits(numChars);
+    stringPtr = stringAlloc(numChars);
+    SET_STRING(objPtr, stringPtr);
+    objPtr->typePtr = &tclStringType;
+
+    stringPtr->maxChars = numChars;
+    memcpy(stringPtr->unicode, unicode, numChars * sizeof(Tcl_UniChar));
+    stringPtr->unicode[numChars] = 0;
+    stringPtr->numChars = numChars;
+    stringPtr->hasUnicode = 1;
+
+    TclInvalidateStringRep(objPtr);
+    stringPtr->allocated = 0;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_AppendLimitedToObj --
+ *
+ *	This function appends a limited number of bytes from a sequence of
+ *	bytes to an object, marking any limitation with an ellipsis.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The bytes at *bytes are appended to the string representation of
+ *	objPtr.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_AppendLimitedToObj(
+    Tcl_Obj *objPtr,		/* Points to the object to append to. */
+    const char *bytes,		/* Points to the bytes to append to the
+				 * object. */
+    int length,			/* The number of bytes available to be
+				 * appended from "bytes". If < 0, then all
+				 * bytes up to a NUL byte are available. */
+    int limit,			/* The maximum number of bytes to append to
+				 * the object. */
+    const char *ellipsis)	/* Ellipsis marker string, appended to the
+				 * object to indicate not all available bytes
+				 * at "bytes" were appended. */
+{
+    String *stringPtr;
+    int toCopy = 0;
+
+    if (Tcl_IsShared(objPtr)) {
+	Tcl_Panic("%s called with shared object", "Tcl_AppendLimitedToObj");
+    }
+
+    if (length < 0) {
+	length = (bytes ? strlen(bytes) : 0);
+    }
+    if (length == 0) {
+	return;
+    }
+
+    if (length <= limit) {
+	toCopy = length;
+    } else {
+	if (ellipsis == NULL) {
+	    ellipsis = "...";
+	}
+	toCopy = (bytes == NULL) ? limit
+		: Tcl_UtfPrev(bytes+limit+1-strlen(ellipsis), bytes) - bytes;
+    }
+
+    /*
+     * If objPtr has a valid Unicode rep, then append the Unicode conversion
+     * of "bytes" to the objPtr's Unicode rep, otherwise append "bytes" to
+     * objPtr's string rep.
+     */
+
+    SetStringFromAny(NULL, objPtr);
+    stringPtr = GET_STRING(objPtr);
+
+    if (stringPtr->hasUnicode && stringPtr->numChars > 0) {
+	AppendUtfToUnicodeRep(objPtr, bytes, toCopy);
+    } else {
+	AppendUtfToUtfRep(objPtr, bytes, toCopy);
+    }
+
+    if (length <= limit) {
+	return;
+    }
+
+    stringPtr = GET_STRING(objPtr);
+    if (stringPtr->hasUnicode && stringPtr->numChars > 0) {
+	AppendUtfToUnicodeRep(objPtr, ellipsis, strlen(ellipsis));
+    } else {
+	AppendUtfToUtfRep(objPtr, ellipsis, strlen(ellipsis));
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_AppendToObj --
+ *
+ *	This function appends a sequence of bytes to an object.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The bytes at *bytes are appended to the string representation of
+ *	objPtr.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_AppendToObj(
+    Tcl_Obj *objPtr,		/* Points to the object to append to. */
+    const char *bytes,		/* Points to the bytes to append to the
+				 * object. */
+    int length)			/* The number of bytes to append from "bytes".
+				 * If < 0, then append all bytes up to NUL
+				 * byte. */
+{
+    Tcl_AppendLimitedToObj(objPtr, bytes, length, INT_MAX, NULL);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_AppendUnicodeToObj --
+ *
+ *	This function appends a Unicode string to an object in the most
+ *	efficient manner possible. Length must be >= 0.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Invalidates the string rep and creates a new Unicode string.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_AppendUnicodeToObj(
+    Tcl_Obj *objPtr,		/* Points to the object to append to. */
+    const Tcl_UniChar *unicode,	/* The unicode string to append to the
+				 * object. */
+    int length)			/* Number of chars in "unicode". */
+{
+    String *stringPtr;
+
+    if (Tcl_IsShared(objPtr)) {
+	Tcl_Panic("%s called with shared object", "Tcl_AppendUnicodeToObj");
+    }
+
+    if (length == 0) {
+	return;
+    }
+
+    SetStringFromAny(NULL, objPtr);
+    stringPtr = GET_STRING(objPtr);
+
+    /*
+     * If objPtr has a valid Unicode rep, then append the "unicode" to the
+     * objPtr's Unicode rep, otherwise the UTF conversion of "unicode" to
+     * objPtr's string rep.
+     */
+
+    if (stringPtr->hasUnicode
+#if COMPAT
+		&& stringPtr->numChars > 0
+#endif
+	    ) {
+	AppendUnicodeToUnicodeRep(objPtr, unicode, length);
+    } else {
+	AppendUnicodeToUtfRep(objPtr, unicode, length);
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_AppendObjToObj --
+ *
+ *	This function appends the string rep of one object to another.
+ *	"objPtr" cannot be a shared object.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The string rep of appendObjPtr is appended to the string
+ *	representation of objPtr.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_AppendObjToObj(
+    Tcl_Obj *objPtr,		/* Points to the object to append to. */
+    Tcl_Obj *appendObjPtr)	/* Object to append. */
+{
+    String *stringPtr;
+    int length, numChars, appendNumChars = -1;
+    const char *bytes;
+
+    /*
+     * Special case: second object is standard-empty is fast case. We know
+     * that appending nothing to anything leaves that starting anything...
+     */
+
+    if (appendObjPtr->bytes == tclEmptyStringRep) {
+	return;
+    }
+
+    /*
+     * Handle append of one bytearray object to another as a special case.
+     * Note that we only do this when the objects don't have string reps; if
+     * it did, then appending the byte arrays together could well lose
+     * information; this is a special-case optimization only.
+     */
+
+    if ((TclIsPureByteArray(objPtr) || objPtr->bytes == tclEmptyStringRep)
+	    && TclIsPureByteArray(appendObjPtr)) {
+
+	/*
+	 * You might expect the code here to be
+	 *
+	 *  bytes = Tcl_GetByteArrayFromObj(appendObjPtr, &length);
+	 *  TclAppendBytesToByteArray(objPtr, bytes, length);
+	 *
+	 * and essentially all of the time that would be fine.  However,
+	 * it would run into trouble in the case where objPtr and
+	 * appendObjPtr point to the same thing.  That may never be a
+	 * good idea.  It seems to violate Copy On Write, and we don't
+	 * have any tests for the situation, since making any Tcl commands
+	 * that call Tcl_AppendObjToObj() do that appears impossible
+	 * (They honor Copy On Write!).  For the sake of extensions that
+	 * go off into that realm, though, here's a more complex approach
+	 * that can handle all the cases.
+	 */
+
+	/* Get lengths */
+	int lengthSrc;
+
+	(void) Tcl_GetByteArrayFromObj(objPtr, &length);
+	(void) Tcl_GetByteArrayFromObj(appendObjPtr, &lengthSrc);
+
+	/* Grow buffer enough for the append */
+	TclAppendBytesToByteArray(objPtr, NULL, lengthSrc);
+
+	/* Reset objPtr back to the original value */
+	Tcl_SetByteArrayLength(objPtr, length);
+
+	/*
+	 * Now do the append knowing that buffer growth cannot cause
+	 * any trouble.
+	 */
+
+	TclAppendBytesToByteArray(objPtr,
+		Tcl_GetByteArrayFromObj(appendObjPtr, NULL), lengthSrc);
+	return;
+    }
+
+    /*
+     * Must append as strings.
+     */
+
+    SetStringFromAny(NULL, objPtr);
+    stringPtr = GET_STRING(objPtr);
+
+    /*
+     * If objPtr has a valid Unicode rep, then get a Unicode string from
+     * appendObjPtr and append it.
+     */
+
+    if (stringPtr->hasUnicode
+#if COMPAT
+		&& stringPtr->numChars > 0
+#endif
+	    ) {
+	/*
+	 * If appendObjPtr is not of the "String" type, don't convert it.
+	 */
+
+	if (appendObjPtr->typePtr == &tclStringType) {
+	    Tcl_UniChar *unicode =
+		    Tcl_GetUnicodeFromObj(appendObjPtr, &numChars);
+
+	    AppendUnicodeToUnicodeRep(objPtr, unicode, numChars);
+	} else {
+	    bytes = TclGetStringFromObj(appendObjPtr, &length);
+	    AppendUtfToUnicodeRep(objPtr, bytes, length);
+	}
+	return;
+    }
+
+    /*
+     * Append to objPtr's UTF string rep. If we know the number of characters
+     * in both objects before appending, then set the combined number of
+     * characters in the final (appended-to) object.
+     */
+
+    bytes = TclGetStringFromObj(appendObjPtr, &length);
+
+    numChars = stringPtr->numChars;
+    if ((numChars >= 0) && (appendObjPtr->typePtr == &tclStringType)) {
+	String *appendStringPtr = GET_STRING(appendObjPtr);
+	appendNumChars = appendStringPtr->numChars;
+    }
+
+    AppendUtfToUtfRep(objPtr, bytes, length);
+
+    if (numChars >= 0 && appendNumChars >= 0
+#if COMPAT
+		&& appendNumChars == length
+#endif
+	    ) {
+	stringPtr->numChars = numChars + appendNumChars;
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * AppendUnicodeToUnicodeRep --
+ *
+ *	This function appends the contents of "unicode" to the Unicode rep of
+ *	"objPtr". objPtr must already have a valid Unicode rep.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	objPtr's internal rep is reallocated.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+AppendUnicodeToUnicodeRep(
+    Tcl_Obj *objPtr,		/* Points to the object to append to. */
+    const Tcl_UniChar *unicode,	/* String to append. */
+    int appendNumChars)		/* Number of chars of "unicode" to append. */
+{
+    String *stringPtr;
+    int numChars;
+
+    if (appendNumChars < 0) {
+	appendNumChars = UnicodeLength(unicode);
+    }
+    if (appendNumChars == 0) {
+	return;
+    }
+
+    SetStringFromAny(NULL, objPtr);
+    stringPtr = GET_STRING(objPtr);
+
+    /*
+     * If not enough space has been allocated for the unicode rep, reallocate
+     * the internal rep object with additional space. First try to double the
+     * required allocation; if that fails, try a more modest increase. See the
+     * "TCL STRING GROWTH ALGORITHM" comment at the top of this file for an
+     * explanation of this growth algorithm.
+     */
+
+    numChars = stringPtr->numChars + appendNumChars;
+    stringCheckLimits(numChars);
+
+    if (numChars > stringPtr->maxChars) {
+	int offset = -1;
+
+	/*
+	 * Protect against case where unicode points into the existing
+	 * stringPtr->unicode array. Force it to follow any relocations due to
+	 * the reallocs below.
+	 */
+
+	if (unicode && unicode >= stringPtr->unicode
+		&& unicode <= stringPtr->unicode + stringPtr->maxChars) {
+	    offset = unicode - stringPtr->unicode;
+	}
+
+	GrowUnicodeBuffer(objPtr, numChars);
+	stringPtr = GET_STRING(objPtr);
+
+	/*
+	 * Relocate unicode if needed; see above.
+	 */
+
+	if (offset >= 0) {
+	    unicode = stringPtr->unicode + offset;
+	}
+    }
+
+    /*
+     * Copy the new string onto the end of the old string, then add the
+     * trailing null.
+     */
+
+    if (unicode) {
+	memmove(stringPtr->unicode + stringPtr->numChars, unicode,
+		appendNumChars * sizeof(Tcl_UniChar));
+    }
+    stringPtr->unicode[numChars] = 0;
+    stringPtr->numChars = numChars;
+    stringPtr->allocated = 0;
+
+    TclInvalidateStringRep(objPtr);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * AppendUnicodeToUtfRep --
+ *
+ *	This function converts the contents of "unicode" to UTF and appends
+ *	the UTF to the string rep of "objPtr".
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	objPtr's internal rep is reallocated.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+AppendUnicodeToUtfRep(
+    Tcl_Obj *objPtr,		/* Points to the object to append to. */
+    const Tcl_UniChar *unicode,	/* String to convert to UTF. */
+    int numChars)		/* Number of chars of "unicode" to convert. */
+{
+    String *stringPtr = GET_STRING(objPtr);
+
+    numChars = ExtendStringRepWithUnicode(objPtr, unicode, numChars);
+
+    if (stringPtr->numChars != -1) {
+	stringPtr->numChars += numChars;
+    }
+
+#if COMPAT
+    /*
+     * Invalidate the unicode rep.
+     */
+
+    stringPtr->hasUnicode = 0;
+#endif
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * AppendUtfToUnicodeRep --
+ *
+ *	This function converts the contents of "bytes" to Unicode and appends
+ *	the Unicode to the Unicode rep of "objPtr". objPtr must already have a
+ *	valid Unicode rep. numBytes must be non-negative.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	objPtr's internal rep is reallocated.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+AppendUtfToUnicodeRep(
+    Tcl_Obj *objPtr,		/* Points to the object to append to. */
+    const char *bytes,		/* String to convert to Unicode. */
+    int numBytes)		/* Number of bytes of "bytes" to convert. */
+{
+    String *stringPtr;
+
+    if (numBytes == 0) {
+	return;
+    }
+
+    ExtendUnicodeRepWithString(objPtr, bytes, numBytes, -1);
+    TclInvalidateStringRep(objPtr);
+    stringPtr = GET_STRING(objPtr);
+    stringPtr->allocated = 0;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * AppendUtfToUtfRep --
+ *
+ *	This function appends "numBytes" bytes of "bytes" to the UTF string
+ *	rep of "objPtr". objPtr must already have a valid String rep.
+ *	numBytes must be non-negative.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	objPtr's internal rep is reallocated.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+AppendUtfToUtfRep(
+    Tcl_Obj *objPtr,		/* Points to the object to append to. */
+    const char *bytes,		/* String to append. */
+    int numBytes)		/* Number of bytes of "bytes" to append. */
+{
+    String *stringPtr;
+    int newLength, oldLength;
+
+    if (numBytes == 0) {
+	return;
+    }
+
+    /*
+     * Copy the new string onto the end of the old string, then add the
+     * trailing null.
+     */
+
+    if (objPtr->bytes == NULL) {
+	objPtr->length = 0;
+    }
+    oldLength = objPtr->length;
+    newLength = numBytes + oldLength;
+    if (newLength < 0) {
+	Tcl_Panic("max size for a Tcl value (%d bytes) exceeded", INT_MAX);
+    }
+
+    stringPtr = GET_STRING(objPtr);
+    if (newLength > stringPtr->allocated) {
+	int offset = -1;
+
+	/*
+	 * Protect against case where unicode points into the existing
+	 * stringPtr->unicode array. Force it to follow any relocations due to
+	 * the reallocs below.
+	 */
+
+	if (bytes && bytes >= objPtr->bytes
+		&& bytes <= objPtr->bytes + objPtr->length) {
+	    offset = bytes - objPtr->bytes;
+	}
+
+	/*
+	 * TODO: consider passing flag=1: no overalloc on first append. This
+	 * would make test stringObj-8.1 fail.
+	 */
+
+	GrowStringBuffer(objPtr, newLength, 0);
+
+	/*
+	 * Relocate bytes if needed; see above.
+	 */
+
+	if (offset >= 0) {
+	    bytes = objPtr->bytes + offset;
+	}
+    }
+
+    /*
+     * Invalidate the unicode data.
+     */
+
+    stringPtr->numChars = -1;
+    stringPtr->hasUnicode = 0;
+
+    if (bytes) {
+	memmove(objPtr->bytes + oldLength, bytes, numBytes);
+    }
+    objPtr->bytes[newLength] = 0;
+    objPtr->length = newLength;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_AppendStringsToObjVA --
+ *
+ *	This function appends one or more null-terminated strings to an
+ *	object.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The contents of all the string arguments are appended to the string
+ *	representation of objPtr.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_AppendStringsToObjVA(
+    Tcl_Obj *objPtr,		/* Points to the object to append to. */
+    va_list argList)		/* Variable argument list. */
+{
+    if (Tcl_IsShared(objPtr)) {
+	Tcl_Panic("%s called with shared object", "Tcl_AppendStringsToObj");
+    }
+
+    while (1) {
+	const char *bytes = va_arg(argList, char *);
+
+	if (bytes == NULL) {
+	    break;
+	}
+	Tcl_AppendToObj(objPtr, bytes, -1);
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_AppendStringsToObj --
+ *
+ *	This function appends one or more null-terminated strings to an
+ *	object.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The contents of all the string arguments are appended to the string
+ *	representation of objPtr.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_AppendStringsToObj(
+    Tcl_Obj *objPtr,
+    ...)
+{
+    va_list argList;
+
+    va_start(argList, objPtr);
+    Tcl_AppendStringsToObjVA(objPtr, argList);
+    va_end(argList);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_AppendFormatToObj --
+ *
+ *	This function appends a list of Tcl_Obj's to a Tcl_Obj according to
+ *	the formatting instructions embedded in the format string. The
+ *	formatting instructions are inspired by sprintf(). Returns TCL_OK when
+ *	successful. If there's an error in the arguments, TCL_ERROR is
+ *	returned, and an error message is written to the interp, if non-NULL.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_AppendFormatToObj(
+    Tcl_Interp *interp,
+    Tcl_Obj *appendObj,
+    const char *format,
+    int objc,
+    Tcl_Obj *const objv[])
+{
+    const char *span = format, *msg, *errCode;
+    int numBytes = 0, objIndex = 0, gotXpg = 0, gotSequential = 0;
+    int originalLength, limit;
+    static const char *mixedXPG =
+	    "cannot mix \"%\" and \"%n$\" conversion specifiers";
+    static const char *const badIndex[2] = {
+	"not enough arguments for all format specifiers",
+	"\"%n$\" argument index out of range"
+    };
+    static const char *overflow = "max size for a Tcl value exceeded";
+
+    if (Tcl_IsShared(appendObj)) {
+	Tcl_Panic("%s called with shared object", "Tcl_AppendFormatToObj");
+    }
+    TclGetStringFromObj(appendObj, &originalLength);
+    limit = INT_MAX - originalLength;
+
+    /*
+     * Format string is NUL-terminated.
+     */
+
+    while (*format != '\0') {
+	char *end;
+	int gotMinus, gotHash, gotZero, gotSpace, gotPlus, sawFlag;
+	int width, gotPrecision, precision, useShort, useWide, useBig;
+	int newXpg, numChars, allocSegment = 0, segmentLimit, segmentNumBytes;
+	Tcl_Obj *segment;
+	Tcl_UniChar ch;
+	int step = Tcl_UtfToUniChar(format, &ch);
+
+	format += step;
+	if (ch != '%') {
+	    numBytes += step;
+	    continue;
+	}
+	if (numBytes) {
+	    if (numBytes > limit) {
+		msg = overflow;
+		errCode = "OVERFLOW";
+		goto errorMsg;
+	    }
+	    Tcl_AppendToObj(appendObj, span, numBytes);
+	    limit -= numBytes;
+	    numBytes = 0;
+	}
+
+	/*
+	 * Saw a % : process the format specifier.
+	 *
+	 * Step 0. Handle special case of escaped format marker (i.e., %%).
+	 */
+
+	step = Tcl_UtfToUniChar(format, &ch);
+	if (ch == '%') {
+	    span = format;
+	    numBytes = step;
+	    format += step;
+	    continue;
+	}
+
+	/*
+	 * Step 1. XPG3 position specifier
+	 */
+
+	newXpg = 0;
+	if (isdigit(UCHAR(ch))) {
+	    int position = strtoul(format, &end, 10);
+
+	    if (*end == '$') {
+		newXpg = 1;
+		objIndex = position - 1;
+		format = end + 1;
+		step = Tcl_UtfToUniChar(format, &ch);
+	    }
+	}
+	if (newXpg) {
+	    if (gotSequential) {
+		msg = mixedXPG;
+		errCode = "MIXEDSPECTYPES";
+		goto errorMsg;
+	    }
+	    gotXpg = 1;
+	} else {
+	    if (gotXpg) {
+		msg = mixedXPG;
+		errCode = "MIXEDSPECTYPES";
+		goto errorMsg;
+	    }
+	    gotSequential = 1;
+	}
+	if ((objIndex < 0) || (objIndex >= objc)) {
+	    msg = badIndex[gotXpg];
+	    errCode = gotXpg ? "INDEXRANGE" : "FIELDVARMISMATCH";
+	    goto errorMsg;
+	}
+
+	/*
+	 * Step 2. Set of flags.
+	 */
+
+	gotMinus = gotHash = gotZero = gotSpace = gotPlus = 0;
+	sawFlag = 1;
+	do {
+	    switch (ch) {
+	    case '-':
+		gotMinus = 1;
+		break;
+	    case '#':
+		gotHash = 1;
+		break;
+	    case '0':
+		gotZero = 1;
+		break;
+	    case ' ':
+		gotSpace = 1;
+		break;
+	    case '+':
+		gotPlus = 1;
+		break;
+	    default:
+		sawFlag = 0;
+	    }
+	    if (sawFlag) {
+		format += step;
+		step = Tcl_UtfToUniChar(format, &ch);
+	    }
+	} while (sawFlag);
+
+	/*
+	 * Step 3. Minimum field width.
+	 */
+
+	width = 0;
+	if (isdigit(UCHAR(ch))) {
+	    width = strtoul(format, &end, 10);
+	    format = end;
+	    step = Tcl_UtfToUniChar(format, &ch);
+	} else if (ch == '*') {
+	    if (objIndex >= objc - 1) {
+		msg = badIndex[gotXpg];
+		errCode = gotXpg ? "INDEXRANGE" : "FIELDVARMISMATCH";
+		goto errorMsg;
+	    }
+	    if (TclGetIntFromObj(interp, objv[objIndex], &width) != TCL_OK) {
+		goto error;
+	    }
+	    if (width < 0) {
+		width = -width;
+		gotMinus = 1;
+	    }
+	    objIndex++;
+	    format += step;
+	    step = Tcl_UtfToUniChar(format, &ch);
+	}
+	if (width > limit) {
+	    msg = overflow;
+	    errCode = "OVERFLOW";
+	    goto errorMsg;
+	}
+
+	/*
+	 * Step 4. Precision.
+	 */
+
+	gotPrecision = precision = 0;
+	if (ch == '.') {
+	    gotPrecision = 1;
+	    format += step;
+	    step = Tcl_UtfToUniChar(format, &ch);
+	}
+	if (isdigit(UCHAR(ch))) {
+	    precision = strtoul(format, &end, 10);
+	    format = end;
+	    step = Tcl_UtfToUniChar(format, &ch);
+	} else if (ch == '*') {
+	    if (objIndex >= objc - 1) {
+		msg = badIndex[gotXpg];
+		errCode = gotXpg ? "INDEXRANGE" : "FIELDVARMISMATCH";
+		goto errorMsg;
+	    }
+	    if (TclGetIntFromObj(interp, objv[objIndex], &precision)
+		    != TCL_OK) {
+		goto error;
+	    }
+
+	    /*
+	     * TODO: Check this truncation logic.
+	     */
+
+	    if (precision < 0) {
+		precision = 0;
+	    }
+	    objIndex++;
+	    format += step;
+	    step = Tcl_UtfToUniChar(format, &ch);
+	}
+
+	/*
+	 * Step 5. Length modifier.
+	 */
+
+	useShort = useWide = useBig = 0;
+	if (ch == 'h') {
+	    useShort = 1;
+	    format += step;
+	    step = Tcl_UtfToUniChar(format, &ch);
+	} else if (ch == 'l') {
+	    format += step;
+	    step = Tcl_UtfToUniChar(format, &ch);
+	    if (ch == 'l') {
+		useBig = 1;
+		format += step;
+		step = Tcl_UtfToUniChar(format, &ch);
+#ifndef TCL_WIDE_INT_IS_LONG
+	    } else {
+		useWide = 1;
+#endif
+	    }
+	}
+
+	format += step;
+	span = format;
+
+	/*
+	 * Step 6. The actual conversion character.
+	 */
+
+	segment = objv[objIndex];
+	numChars = -1;
+	if (ch == 'i') {
+	    ch = 'd';
+	}
+	switch (ch) {
+	case '\0':
+	    msg = "format string ended in middle of field specifier";
+	    errCode = "INCOMPLETE";
+	    goto errorMsg;
+	case 's':
+	    if (gotPrecision) {
+		numChars = Tcl_GetCharLength(segment);
+		if (precision < numChars) {
+		    segment = Tcl_GetRange(segment, 0, precision - 1);
+		    numChars = precision;
+		    Tcl_IncrRefCount(segment);
+		    allocSegment = 1;
+		}
+	    }
+	    break;
+	case 'c': {
+	    char buf[TCL_UTF_MAX];
+	    int code, length;
+
+	    if (TclGetIntFromObj(interp, segment, &code) != TCL_OK) {
+		goto error;
+	    }
+	    length = Tcl_UniCharToUtf(code, buf);
+	    segment = Tcl_NewStringObj(buf, length);
+	    Tcl_IncrRefCount(segment);
+	    allocSegment = 1;
+	    break;
+	}
+
+	case 'u':
+	    if (useBig) {
+		msg = "unsigned bignum format is invalid";
+		errCode = "BADUNSIGNED";
+		goto errorMsg;
+	    }
+	case 'd':
+	case 'o':
+	case 'x':
+	case 'X':
+	case 'b': {
+	    short s = 0;	/* Silence compiler warning; only defined and
+				 * used when useShort is true. */
+	    long l;
+	    Tcl_WideInt w;
+	    mp_int big;
+	    int toAppend, isNegative = 0;
+
+	    if (useBig) {
+		if (Tcl_GetBignumFromObj(interp, segment, &big) != TCL_OK) {
+		    goto error;
+		}
+		isNegative = (mp_cmp_d(&big, 0) == MP_LT);
+	    } else if (useWide) {
+		if (Tcl_GetWideIntFromObj(NULL, segment, &w) != TCL_OK) {
+		    Tcl_Obj *objPtr;
+
+		    if (Tcl_GetBignumFromObj(interp,segment,&big) != TCL_OK) {
+			goto error;
+		    }
+		    mp_mod_2d(&big, (int) CHAR_BIT*sizeof(Tcl_WideInt), &big);
+		    objPtr = Tcl_NewBignumObj(&big);
+		    Tcl_IncrRefCount(objPtr);
+		    Tcl_GetWideIntFromObj(NULL, objPtr, &w);
+		    Tcl_DecrRefCount(objPtr);
+		}
+		isNegative = (w < (Tcl_WideInt) 0);
+	    } else if (TclGetLongFromObj(NULL, segment, &l) != TCL_OK) {
+		if (Tcl_GetWideIntFromObj(NULL, segment, &w) != TCL_OK) {
+		    Tcl_Obj *objPtr;
+
+		    if (Tcl_GetBignumFromObj(interp,segment,&big) != TCL_OK) {
+			goto error;
+		    }
+		    mp_mod_2d(&big, (int) CHAR_BIT * sizeof(long), &big);
+		    objPtr = Tcl_NewBignumObj(&big);
+		    Tcl_IncrRefCount(objPtr);
+		    TclGetLongFromObj(NULL, objPtr, &l);
+		    Tcl_DecrRefCount(objPtr);
+		} else {
+		    l = Tcl_WideAsLong(w);
+		}
+		if (useShort) {
+		    s = (short) l;
+		    isNegative = (s < (short) 0);
+		} else {
+		    isNegative = (l < (long) 0);
+		}
+	    } else if (useShort) {
+		s = (short) l;
+		isNegative = (s < (short) 0);
+	    } else {
+		isNegative = (l < (long) 0);
+	    }
+
+	    segment = Tcl_NewObj();
+	    allocSegment = 1;
+	    segmentLimit = INT_MAX;
+	    Tcl_IncrRefCount(segment);
+
+	    if ((isNegative || gotPlus || gotSpace) && (useBig || ch=='d')) {
+		Tcl_AppendToObj(segment,
+			(isNegative ? "-" : gotPlus ? "+" : " "), 1);
+		segmentLimit -= 1;
+	    }
+
+	    if (gotHash) {
+		switch (ch) {
+		case 'o':
+		    Tcl_AppendToObj(segment, "0", 1);
+		    segmentLimit -= 1;
+		    precision--;
+		    break;
+		case 'x':
+		case 'X':
+		    Tcl_AppendToObj(segment, "0x", 2);
+		    segmentLimit -= 2;
+		    break;
+		case 'b':
+		    Tcl_AppendToObj(segment, "0b", 2);
+		    segmentLimit -= 2;
+		    break;
+		}
+	    }
+
+	    switch (ch) {
+	    case 'd': {
+		int length;
+		Tcl_Obj *pure;
+		const char *bytes;
+
+		if (useShort) {
+		    pure = Tcl_NewIntObj((int) s);
+		} else if (useWide) {
+		    pure = Tcl_NewWideIntObj(w);
+		} else if (useBig) {
+		    pure = Tcl_NewBignumObj(&big);
+		} else {
+		    pure = Tcl_NewLongObj(l);
+		}
+		Tcl_IncrRefCount(pure);
+		bytes = TclGetStringFromObj(pure, &length);
+
+		/*
+		 * Already did the sign above.
+		 */
+
+		if (*bytes == '-') {
+		    length--;
+		    bytes++;
+		}
+		toAppend = length;
+
+		/*
+		 * Canonical decimal string reps for integers are composed
+		 * entirely of one-byte encoded characters, so "length" is the
+		 * number of chars.
+		 */
+
+		if (gotPrecision) {
+		    if (length < precision) {
+			segmentLimit -= precision - length;
+		    }
+		    while (length < precision) {
+			Tcl_AppendToObj(segment, "0", 1);
+			length++;
+		    }
+		    gotZero = 0;
+		}
+		if (gotZero) {
+		    length += Tcl_GetCharLength(segment);
+		    if (length < width) {
+			segmentLimit -= width - length;
+		    }
+		    while (length < width) {
+			Tcl_AppendToObj(segment, "0", 1);
+			length++;
+		    }
+		}
+		if (toAppend > segmentLimit) {
+		    msg = overflow;
+		    errCode = "OVERFLOW";
+		    goto errorMsg;
+		}
+		Tcl_AppendToObj(segment, bytes, toAppend);
+		Tcl_DecrRefCount(pure);
+		break;
+	    }
+
+	    case 'u':
+	    case 'o':
+	    case 'x':
+	    case 'X':
+	    case 'b': {
+		Tcl_WideUInt bits = (Tcl_WideUInt) 0;
+		Tcl_WideInt numDigits = (Tcl_WideInt) 0;
+		int length, numBits = 4, base = 16, index = 0, shift = 0;
+		Tcl_Obj *pure;
+		char *bytes;
+
+		if (ch == 'u') {
+		    base = 10;
+		} else if (ch == 'o') {
+		    base = 8;
+		    numBits = 3;
+		} else if (ch == 'b') {
+		    base = 2;
+		    numBits = 1;
+		}
+		if (useShort) {
+		    unsigned short us = (unsigned short) s;
+
+		    bits = (Tcl_WideUInt) us;
+		    while (us) {
+			numDigits++;
+			us /= base;
+		    }
+		} else if (useWide) {
+		    Tcl_WideUInt uw = (Tcl_WideUInt) w;
+
+		    bits = uw;
+		    while (uw) {
+			numDigits++;
+			uw /= base;
+		    }
+		} else if (useBig && big.used) {
+		    int leftover = (big.used * DIGIT_BIT) % numBits;
+		    mp_digit mask = (~(mp_digit)0) << (DIGIT_BIT-leftover);
+
+		    numDigits = 1 +
+			    (((Tcl_WideInt) big.used * DIGIT_BIT) / numBits);
+		    while ((mask & big.dp[big.used-1]) == 0) {
+			numDigits--;
+			mask >>= numBits;
+		    }
+		    if (numDigits > INT_MAX) {
+			msg = overflow;
+			errCode = "OVERFLOW";
+			goto errorMsg;
+		    }
+		} else if (!useBig) {
+		    unsigned long ul = (unsigned long) l;
+
+		    bits = (Tcl_WideUInt) ul;
+		    while (ul) {
+			numDigits++;
+			ul /= base;
+		    }
+		}
+
+		/*
+		 * Need to be sure zero becomes "0", not "".
+		 */
+
+		if ((numDigits == 0) && !((ch == 'o') && gotHash)) {
+		    numDigits = 1;
+		}
+		pure = Tcl_NewObj();
+		Tcl_SetObjLength(pure, (int) numDigits);
+		bytes = TclGetString(pure);
+		toAppend = length = (int) numDigits;
+		while (numDigits--) {
+		    int digitOffset;
+
+		    if (useBig && big.used) {
+			if (index < big.used && (size_t) shift <
+				CHAR_BIT*sizeof(Tcl_WideUInt) - DIGIT_BIT) {
+			    bits |= ((Tcl_WideUInt) big.dp[index++]) << shift;
+			    shift += DIGIT_BIT;
+			}
+			shift -= numBits;
+		    }
+		    digitOffset = (int) (bits % base);
+		    if (digitOffset > 9) {
+			bytes[numDigits] = 'a' + digitOffset - 10;
+		    } else {
+			bytes[numDigits] = '0' + digitOffset;
+		    }
+		    bits /= base;
+		}
+		if (useBig) {
+		    mp_clear(&big);
+		}
+		if (gotPrecision) {
+		    if (length < precision) {
+			segmentLimit -= precision - length;
+		    }
+		    while (length < precision) {
+			Tcl_AppendToObj(segment, "0", 1);
+			length++;
+		    }
+		    gotZero = 0;
+		}
+		if (gotZero) {
+		    length += Tcl_GetCharLength(segment);
+		    if (length < width) {
+			segmentLimit -= width - length;
+		    }
+		    while (length < width) {
+			Tcl_AppendToObj(segment, "0", 1);
+			length++;
+		    }
+		}
+		if (toAppend > segmentLimit) {
+		    msg = overflow;
+		    errCode = "OVERFLOW";
+		    goto errorMsg;
+		}
+		Tcl_AppendObjToObj(segment, pure);
+		Tcl_DecrRefCount(pure);
+		break;
+	    }
+
+	    }
+	    break;
+	}
+
+	case 'e':
+	case 'E':
+	case 'f':
+	case 'g':
+	case 'G': {
+#define MAX_FLOAT_SIZE 320
+	    char spec[2*TCL_INTEGER_SPACE + 9], *p = spec;
+	    double d;
+	    int length = MAX_FLOAT_SIZE;
+	    char *bytes;
+
+	    if (Tcl_GetDoubleFromObj(interp, segment, &d) != TCL_OK) {
+		/* TODO: Figure out ACCEPT_NAN here */
+		goto error;
+	    }
+	    *p++ = '%';
+	    if (gotMinus) {
+		*p++ = '-';
+	    }
+	    if (gotHash) {
+		*p++ = '#';
+	    }
+	    if (gotZero) {
+		*p++ = '0';
+	    }
+	    if (gotSpace) {
+		*p++ = ' ';
+	    }
+	    if (gotPlus) {
+		*p++ = '+';
+	    }
+	    if (width) {
+		p += sprintf(p, "%d", width);
+		if (width > length) {
+		    length = width;
+		}
+	    }
+	    if (gotPrecision) {
+		*p++ = '.';
+		p += sprintf(p, "%d", precision);
+		if (precision > INT_MAX - length) {
+		    msg = overflow;
+		    errCode = "OVERFLOW";
+		    goto errorMsg;
+		}
+		length += precision;
+	    }
+
+	    /*
+	     * Don't pass length modifiers!
+	     */
+
+	    *p++ = (char) ch;
+	    *p = '\0';
+
+	    segment = Tcl_NewObj();
+	    allocSegment = 1;
+	    if (!Tcl_AttemptSetObjLength(segment, length)) {
+		msg = overflow;
+		errCode = "OVERFLOW";
+		goto errorMsg;
+	    }
+	    bytes = TclGetString(segment);
+	    if (!Tcl_AttemptSetObjLength(segment, sprintf(bytes, spec, d))) {
+		msg = overflow;
+		errCode = "OVERFLOW";
+		goto errorMsg;
+	    }
+	    break;
+	}
+	default:
+	    if (interp != NULL) {
+		Tcl_SetObjResult(interp,
+			Tcl_ObjPrintf("bad field specifier \"%c\"", ch));
+		Tcl_SetErrorCode(interp, "TCL", "FORMAT", "BADTYPE", NULL);
+	    }
+	    goto error;
+	}
+
+	switch (ch) {
+	case 'E':
+	case 'G':
+	case 'X': {
+	    Tcl_SetObjLength(segment, Tcl_UtfToUpper(TclGetString(segment)));
+	}
+	}
+
+	if (width>0 && numChars<0) {
+	    numChars = Tcl_GetCharLength(segment);
+	}
+	if (!gotMinus && width>0) {
+	    if (numChars < width) {
+		limit -= width - numChars;
+	    }
+	    while (numChars < width) {
+		Tcl_AppendToObj(appendObj, (gotZero ? "0" : " "), 1);
+		numChars++;
+	    }
+	}
+
+	Tcl_GetStringFromObj(segment, &segmentNumBytes);
+	if (segmentNumBytes > limit) {
+	    if (allocSegment) {
+		Tcl_DecrRefCount(segment);
+	    }
+	    msg = overflow;
+	    errCode = "OVERFLOW";
+	    goto errorMsg;
+	}
+	Tcl_AppendObjToObj(appendObj, segment);
+	limit -= segmentNumBytes;
+	if (allocSegment) {
+	    Tcl_DecrRefCount(segment);
+	}
+	if (width > 0) {
+	    if (numChars < width) {
+		limit -= width-numChars;
+	    }
+	    while (numChars < width) {
+		Tcl_AppendToObj(appendObj, (gotZero ? "0" : " "), 1);
+		numChars++;
+	    }
+	}
+
+	objIndex += gotSequential;
+    }
+    if (numBytes) {
+	if (numBytes > limit) {
+	    msg = overflow;
+	    errCode = "OVERFLOW";
+	    goto errorMsg;
+	}
+	Tcl_AppendToObj(appendObj, span, numBytes);
+	limit -= numBytes;
+	numBytes = 0;
+    }
+
+    return TCL_OK;
+
+  errorMsg:
+    if (interp != NULL) {
+	Tcl_SetObjResult(interp, Tcl_NewStringObj(msg, -1));
+	Tcl_SetErrorCode(interp, "TCL", "FORMAT", errCode, NULL);
+    }
+  error:
+    Tcl_SetObjLength(appendObj, originalLength);
+    return TCL_ERROR;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Tcl_Format--
+ *
+ * Results:
+ *	A refcount zero Tcl_Obj.
+ *
+ * Side effects:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+Tcl_Obj *
+Tcl_Format(
+    Tcl_Interp *interp,
+    const char *format,
+    int objc,
+    Tcl_Obj *const objv[])
+{
+    int result;
+    Tcl_Obj *objPtr = Tcl_NewObj();
+
+    result = Tcl_AppendFormatToObj(interp, objPtr, format, objc, objv);
+    if (result != TCL_OK) {
+	Tcl_DecrRefCount(objPtr);
+	return NULL;
+    }
+    return objPtr;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * AppendPrintfToObjVA --
+ *
+ * Results:
+ *
+ * Side effects:
+ *
+ *---------------------------------------------------------------------------
+ */
+
+static void
+AppendPrintfToObjVA(
+    Tcl_Obj *objPtr,
+    const char *format,
+    va_list argList)
+{
+    int code, objc;
+    Tcl_Obj **objv, *list = Tcl_NewObj();
+    const char *p;
+
+    p = format;
+    Tcl_IncrRefCount(list);
+    while (*p != '\0') {
+	int size = 0, seekingConversion = 1, gotPrecision = 0;
+	int lastNum = -1;
+
+	if (*p++ != '%') {
+	    continue;
+	}
+	if (*p == '%') {
+	    p++;
+	    continue;
+	}
+	do {
+	    switch (*p) {
+	    case '\0':
+		seekingConversion = 0;
+		break;
+	    case 's': {
+		const char *q, *end, *bytes = va_arg(argList, char *);
+		seekingConversion = 0;
+
+		/*
+		 * The buffer to copy characters from starts at bytes and ends
+		 * at either the first NUL byte, or after lastNum bytes, when
+		 * caller has indicated a limit.
+		 */
+
+		end = bytes;
+		while ((!gotPrecision || lastNum--) && (*end != '\0')) {
+		    end++;
+		}
+
+		/*
+		 * Within that buffer, we trim both ends if needed so that we
+		 * copy only whole characters, and avoid copying any partial
+		 * multi-byte characters.
+		 */
+
+		q = Tcl_UtfPrev(end, bytes);
+		if (!Tcl_UtfCharComplete(q, (int)(end - q))) {
+		    end = q;
+		}
+
+		q = bytes + TCL_UTF_MAX;
+		while ((bytes < end) && (bytes < q)
+			&& ((*bytes & 0xC0) == 0x80)) {
+		    bytes++;
+		}
+
+		Tcl_ListObjAppendElement(NULL, list,
+			Tcl_NewStringObj(bytes , (int)(end - bytes)));
+
+		break;
+	    }
+	    case 'c':
+	    case 'i':
+	    case 'u':
+	    case 'd':
+	    case 'o':
+	    case 'x':
+	    case 'X':
+		seekingConversion = 0;
+		switch (size) {
+		case -1:
+		case 0:
+		    Tcl_ListObjAppendElement(NULL, list, Tcl_NewLongObj(
+			    (long) va_arg(argList, int)));
+		    break;
+		case 1:
+		    Tcl_ListObjAppendElement(NULL, list, Tcl_NewLongObj(
+			    va_arg(argList, long)));
+		    break;
+		}
+		break;
+	    case 'e':
+	    case 'E':
+	    case 'f':
+	    case 'g':
+	    case 'G':
+		Tcl_ListObjAppendElement(NULL, list, Tcl_NewDoubleObj(
+			va_arg(argList, double)));
+		seekingConversion = 0;
+		break;
+	    case '*':
+		lastNum = (int) va_arg(argList, int);
+		Tcl_ListObjAppendElement(NULL, list, Tcl_NewIntObj(lastNum));
+		p++;
+		break;
+	    case '0': case '1': case '2': case '3': case '4':
+	    case '5': case '6': case '7': case '8': case '9': {
+		char *end;
+
+		lastNum = (int) strtoul(p, &end, 10);
+		p = end;
+		break;
+	    }
+	    case '.':
+		gotPrecision = 1;
+		p++;
+		break;
+	    /* TODO: support for wide (and bignum?) arguments */
+	    case 'l':
+		size = 1;
+		p++;
+		break;
+	    case 'h':
+		size = -1;
+	    default:
+		p++;
+	    }
+	} while (seekingConversion);
+    }
+    TclListObjGetElements(NULL, list, &objc, &objv);
+    code = Tcl_AppendFormatToObj(NULL, objPtr, format, objc, objv);
+    if (code != TCL_OK) {
+	Tcl_AppendPrintfToObj(objPtr,
+		"Unable to format \"%s\" with supplied arguments: %s",
+		format, Tcl_GetString(list));
+    }
+    Tcl_DecrRefCount(list);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Tcl_AppendPrintfToObj --
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+void
+Tcl_AppendPrintfToObj(
+    Tcl_Obj *objPtr,
+    const char *format,
+    ...)
+{
+    va_list argList;
+
+    va_start(argList, format);
+    AppendPrintfToObjVA(objPtr, format, argList);
+    va_end(argList);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Tcl_ObjPrintf --
+ *
+ * Results:
+ *	A refcount zero Tcl_Obj.
+ *
+ * Side effects:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+Tcl_Obj *
+Tcl_ObjPrintf(
+    const char *format,
+    ...)
+{
+    va_list argList;
+    Tcl_Obj *objPtr = Tcl_NewObj();
+
+    va_start(argList, format);
+    AppendPrintfToObjVA(objPtr, format, argList);
+    va_end(argList);
+    return objPtr;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * TclGetStringStorage --
+ *
+ *	Returns the string storage space of a Tcl_Obj.
+ *
+ * Results:
+ *	The pointer value objPtr->bytes is returned and the number of bytes
+ *	allocated there is written to *sizePtr (if known).
+ *
+ * Side effects:
+ *	May set objPtr->bytes.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+char *
+TclGetStringStorage(
+    Tcl_Obj *objPtr,
+    unsigned int *sizePtr)
+{
+    String *stringPtr;
+
+    if (objPtr->typePtr != &tclStringType || objPtr->bytes == NULL) {
+	return TclGetStringFromObj(objPtr, (int *)sizePtr);
+    }
+
+    stringPtr = GET_STRING(objPtr);
+    *sizePtr = stringPtr->allocated;
+    return objPtr->bytes;
+}
+/*
+ *---------------------------------------------------------------------------
+ *
+ * TclStringObjReverse --
+ *
+ *	Implements the [string reverse] operation.
+ *
+ * Results:
+ *	An unshared Tcl value which is the [string reverse] of the argument
+ *	supplied. When sharing rules permit, the returned value might be the
+ *	argument with modifications done in place.
+ *
+ * Side effects:
+ *	May allocate a new Tcl_Obj.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+static void
+ReverseBytes(
+    unsigned char *to,		/* Copy bytes into here... */
+    unsigned char *from,	/* ...from here... */
+    int count)		/* Until this many are copied, */
+				/* reversing as you go. */
+{
+    unsigned char *src = from + count;
+    if (to == from) {
+	/* Reversing in place */
+	while (--src > to) {
+	    unsigned char c = *src;
+	    *src = *to;
+	    *to++ = c;
+	}
+    }  else {
+	while (--src >= from) {
+	    *to++ = *src;
+	}
+    }
+}
+
+Tcl_Obj *
+TclStringObjReverse(
+    Tcl_Obj *objPtr)
+{
+    String *stringPtr;
+    Tcl_UniChar ch;
+
+    if (TclIsPureByteArray(objPtr)) {
+	int numBytes;
+	unsigned char *from = Tcl_GetByteArrayFromObj(objPtr, &numBytes);
+
+	if (Tcl_IsShared(objPtr)) {
+	    objPtr = Tcl_NewByteArrayObj(NULL, numBytes);
+	}
+	ReverseBytes(Tcl_GetByteArrayFromObj(objPtr, NULL), from, numBytes);
+	return objPtr;
+    }
+
+    SetStringFromAny(NULL, objPtr);
+    stringPtr = GET_STRING(objPtr);
+
+    if (stringPtr->hasUnicode) {
+	Tcl_UniChar *from = Tcl_GetUnicode(objPtr);
+	Tcl_UniChar *src = from + stringPtr->numChars;
+
+	if (Tcl_IsShared(objPtr)) {
+	    Tcl_UniChar *to;
+
+	    /*
+	     * Create a non-empty, pure unicode value, so we can coax
+	     * Tcl_SetObjLength into growing the unicode rep buffer.
+	     */
+
+	    ch = 0;
+	    objPtr = Tcl_NewUnicodeObj(&ch, 1);
+	    Tcl_SetObjLength(objPtr, stringPtr->numChars);
+	    to = Tcl_GetUnicode(objPtr);
+	    while (--src >= from) {
+		*to++ = *src;
+	    }
+	} else {
+	    /* Reversing in place */
+	    while (--src > from) {
+		ch = *src;
+		*src = *from;
+		*from++ = ch;
+	    }
+	}
+    }
+
+    if (objPtr->bytes) {
+	int numChars = stringPtr->numChars;
+	int numBytes = objPtr->length;
+	char *to, *from = objPtr->bytes;
+
+	if (Tcl_IsShared(objPtr)) {
+	    objPtr = Tcl_NewObj();
+	    Tcl_SetObjLength(objPtr, numBytes);
+	}
+	to = objPtr->bytes;
+
+	if (numChars < numBytes) {
+	    /*
+	     * Either numChars == -1 and we don't know how many chars are
+	     * represented by objPtr->bytes and we need Pass 1 just in case,
+	     * or numChars >= 0 and we know we have fewer chars than bytes,
+	     * so we know there's a multibyte character needing Pass 1.
+	     *
+	     * Pass 1. Reverse the bytes of each multi-byte character.
+	     */
+	    int charCount = 0;
+	    int bytesLeft = numBytes;
+
+	    while (bytesLeft) {
+		/*
+		 * NOTE: We know that the from buffer is NUL-terminated.
+		 * It's part of the contract for objPtr->bytes values.
+		 * Thus, we can skip calling Tcl_UtfCharComplete() here.
+		 */
+		int bytesInChar = Tcl_UtfToUniChar(from, &ch);
+
+		ReverseBytes((unsigned char *)to, (unsigned char *)from,
+			bytesInChar);
+		to += bytesInChar;
+		from += bytesInChar;
+		bytesLeft -= bytesInChar;
+		charCount++;
+	    }
+
+	    from = to = objPtr->bytes;
+	    stringPtr->numChars = charCount;
+	}
+	/* Pass 2. Reverse all the bytes. */
+	ReverseBytes((unsigned char *)to, (unsigned char *)from, numBytes);
+    }
+
+    return objPtr;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * FillUnicodeRep --
+ *
+ *	Populate the Unicode internal rep with the Unicode form of its string
+ *	rep. The object must alread have a "String" internal rep.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Reallocates the String internal rep.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+static void
+FillUnicodeRep(
+    Tcl_Obj *objPtr)		/* The object in which to fill the unicode
+				 * rep. */
+{
+    String *stringPtr = GET_STRING(objPtr);
+
+    ExtendUnicodeRepWithString(objPtr, objPtr->bytes, objPtr->length,
+	    stringPtr->numChars);
+}
+
+static void
+ExtendUnicodeRepWithString(
+    Tcl_Obj *objPtr,
+    const char *bytes,
+    int numBytes,
+    int numAppendChars)
+{
+    String *stringPtr = GET_STRING(objPtr);
+    int needed, numOrigChars = 0;
+    Tcl_UniChar *dst;
+
+    if (stringPtr->hasUnicode) {
+	numOrigChars = stringPtr->numChars;
+    }
+    if (numAppendChars == -1) {
+	TclNumUtfChars(numAppendChars, bytes, numBytes);
+    }
+    needed = numOrigChars + numAppendChars;
+    stringCheckLimits(needed);
+
+    if (needed > stringPtr->maxChars) {
+	GrowUnicodeBuffer(objPtr, needed);
+	stringPtr = GET_STRING(objPtr);
+    }
+
+    stringPtr->hasUnicode = 1;
+    if (bytes) {
+	stringPtr->numChars = needed;
+    } else {
+	numAppendChars = 0;
+    }
+    for (dst=stringPtr->unicode + numOrigChars; numAppendChars-- > 0; dst++) {
+	bytes += TclUtfToUniChar(bytes, dst);
+    }
+    *dst = 0;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * DupStringInternalRep --
+ *
+ *	Initialize the internal representation of a new Tcl_Obj to a copy of
+ *	the internal representation of an existing string object.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	copyPtr's internal rep is set to a copy of srcPtr's internal
+ *	representation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+DupStringInternalRep(
+    Tcl_Obj *srcPtr,		/* Object with internal rep to copy. Must have
+				 * an internal rep of type "String". */
+    Tcl_Obj *copyPtr)		/* Object with internal rep to set. Must not
+				 * currently have an internal rep.*/
+{
+    String *srcStringPtr = GET_STRING(srcPtr);
+    String *copyStringPtr = NULL;
+
+#if COMPAT==0
+    if (srcStringPtr->numChars == -1) {
+	/*
+	 * The String struct in the source value holds zero useful data. Don't
+	 * bother copying it. Don't even bother allocating space in which to
+	 * copy it. Just let the copy be untyped.
+	 */
+
+	return;
+    }
+
+    if (srcStringPtr->hasUnicode) {
+	int copyMaxChars;
+
+	if (srcStringPtr->maxChars / 2 >= srcStringPtr->numChars) {
+	    copyMaxChars = 2 * srcStringPtr->numChars;
+	} else {
+	    copyMaxChars = srcStringPtr->maxChars;
+	}
+	copyStringPtr = stringAttemptAlloc(copyMaxChars);
+	if (copyStringPtr == NULL) {
+	    copyMaxChars = srcStringPtr->numChars;
+	    copyStringPtr = stringAlloc(copyMaxChars);
+	}
+	copyStringPtr->maxChars = copyMaxChars;
+	memcpy(copyStringPtr->unicode, srcStringPtr->unicode,
+		srcStringPtr->numChars * sizeof(Tcl_UniChar));
+	copyStringPtr->unicode[srcStringPtr->numChars] = 0;
+    } else {
+	copyStringPtr = stringAlloc(0);
+	copyStringPtr->maxChars = 0;
+	copyStringPtr->unicode[0] = 0;
+    }
+    copyStringPtr->hasUnicode = srcStringPtr->hasUnicode;
+    copyStringPtr->numChars = srcStringPtr->numChars;
+
+    /*
+     * Tricky point: the string value was copied by generic object management
+     * code, so it doesn't contain any extra bytes that might exist in the
+     * source object.
+     */
+
+    copyStringPtr->allocated = copyPtr->bytes ? copyPtr->length : 0;
+#else /* COMPAT!=0 */
+    /*
+     * If the src obj is a string of 1-byte Utf chars, then copy the string
+     * rep of the source object and create an "empty" Unicode internal rep for
+     * the new object. Otherwise, copy Unicode internal rep, and invalidate
+     * the string rep of the new object.
+     */
+
+    if (srcStringPtr->hasUnicode && srcStringPtr->numChars > 0) {
+	/*
+	 * Copy the full allocation for the Unicode buffer.
+	 */
+
+	copyStringPtr = stringAlloc(srcStringPtr->maxChars);
+	copyStringPtr->maxChars = srcStringPtr->maxChars;
+	memcpy(copyStringPtr->unicode, srcStringPtr->unicode,
+		srcStringPtr->numChars * sizeof(Tcl_UniChar));
+	copyStringPtr->unicode[srcStringPtr->numChars] = 0;
+	copyStringPtr->allocated = 0;
+    } else {
+	copyStringPtr = stringAlloc(0);
+	copyStringPtr->unicode[0] = 0;
+	copyStringPtr->maxChars = 0;
+
+	/*
+	 * Tricky point: the string value was copied by generic object
+	 * management code, so it doesn't contain any extra bytes that might
+	 * exist in the source object.
+	 */
+
+	copyStringPtr->allocated = copyPtr->length;
+    }
+    copyStringPtr->numChars = srcStringPtr->numChars;
+    copyStringPtr->hasUnicode = srcStringPtr->hasUnicode;
+#endif /* COMPAT==0 */
+
+    SET_STRING(copyPtr, copyStringPtr);
+    copyPtr->typePtr = &tclStringType;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * SetStringFromAny --
+ *
+ *	Create an internal representation of type "String" for an object.
+ *
+ * Results:
+ *	This operation always succeeds and returns TCL_OK.
+ *
+ * Side effects:
+ *	Any old internal reputation for objPtr is freed and the internal
+ *	representation is set to "String".
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+SetStringFromAny(
+    Tcl_Interp *interp,		/* Used for error reporting if not NULL. */
+    Tcl_Obj *objPtr)		/* The object to convert. */
+{
+    if (objPtr->typePtr != &tclStringType) {
+	String *stringPtr = stringAlloc(0);
+
+	/*
+	 * Convert whatever we have into an untyped value. Just A String.
+	 */
+
+	(void) TclGetString(objPtr);
+	TclFreeIntRep(objPtr);
+
+	/*
+	 * Create a basic String intrep that just points to the UTF-8 string
+	 * already in place at objPtr->bytes.
+	 */
+
+	stringPtr->numChars = -1;
+	stringPtr->allocated = objPtr->length;
+	stringPtr->maxChars = 0;
+	stringPtr->hasUnicode = 0;
+	SET_STRING(objPtr, stringPtr);
+	objPtr->typePtr = &tclStringType;
+    }
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * UpdateStringOfString --
+ *
+ *	Update the string representation for an object whose internal
+ *	representation is "String".
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The object's string may be set by converting its Unicode represention
+ *	to UTF format.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+UpdateStringOfString(
+    Tcl_Obj *objPtr)		/* Object with string rep to update. */
+{
+    String *stringPtr = GET_STRING(objPtr);
+
+    if (stringPtr->numChars == 0) {
+	TclInitStringRep(objPtr, tclEmptyStringRep, 0);
+    } else {
+	(void) ExtendStringRepWithUnicode(objPtr, stringPtr->unicode,
+		stringPtr->numChars);
+    }
+}
+
+static int
+ExtendStringRepWithUnicode(
+    Tcl_Obj *objPtr,
+    const Tcl_UniChar *unicode,
+    int numChars)
+{
+    /*
+     * Pre-condition: this is the "string" Tcl_ObjType.
+     */
+
+    int i, origLength, size = 0;
+    char *dst, buf[TCL_UTF_MAX];
+    String *stringPtr = GET_STRING(objPtr);
+
+    if (numChars < 0) {
+	numChars = UnicodeLength(unicode);
+    }
+
+    if (numChars == 0) {
+	return 0;
+    }
+
+    if (objPtr->bytes == NULL) {
+	objPtr->length = 0;
+    }
+    size = origLength = objPtr->length;
+
+    /*
+     * Quick cheap check in case we have more than enough room.
+     */
+
+    if (numChars <= (INT_MAX - size)/TCL_UTF_MAX
+	    && stringPtr->allocated >= size + numChars * TCL_UTF_MAX) {
+	goto copyBytes;
+    }
+
+    for (i = 0; i < numChars && size >= 0; i++) {
+	size += Tcl_UniCharToUtf((int) unicode[i], buf);
+    }
+    if (size < 0) {
+	Tcl_Panic("max size for a Tcl value (%d bytes) exceeded", INT_MAX);
+    }
+
+    /*
+     * Grow space if needed.
+     */
+
+    if (size > stringPtr->allocated) {
+	GrowStringBuffer(objPtr, size, 1);
+    }
+
+  copyBytes:
+    dst = objPtr->bytes + origLength;
+    for (i = 0; i < numChars; i++) {
+	dst += Tcl_UniCharToUtf((int) unicode[i], dst);
+    }
+    *dst = '\0';
+    objPtr->length = dst - objPtr->bytes;
+    return numChars;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * FreeStringInternalRep --
+ *
+ *	Deallocate the storage associated with a String data object's internal
+ *	representation.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Frees memory.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+FreeStringInternalRep(
+    Tcl_Obj *objPtr)		/* Object with internal rep to free. */
+{
+    ckfree(GET_STRING(objPtr));
+    objPtr->typePtr = NULL;
+}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tclStringRep.h b/generic/tclStringRep.h
new file mode 100644
index 0000000..227e6bc
--- /dev/null
+++ b/generic/tclStringRep.h
@@ -0,0 +1,97 @@
+/*
+ * tclStringRep.h --
+ *
+ *	This file contains the definition of the Unicode string internal
+ *	representation and macros to access it.
+ *
+ *	A Unicode string is an internationalized string. Conceptually, a
+ *	Unicode string is an array of 16-bit quantities organized as a
+ *	sequence of properly formed UTF-8 characters. There is a one-to-one
+ *	map between Unicode and UTF characters. Because Unicode characters
+ *	have a fixed width, operations such as indexing operate on Unicode
+ *	data. The String object is optimized for the case where each UTF char
+ *	in a string is only one byte. In this case, we store the value of
+ *	numChars, but we don't store the Unicode data (unless Tcl_GetUnicode
+ *	is explicitly called).
+ *
+ *	The String object type stores one or both formats. The default
+ *	behavior is to store UTF. Once Unicode is calculated by a function, it
+ *	is stored in the internal rep for future access (without an additional
+ *	O(n) cost).
+ *
+ *	To allow many appends to be done to an object without constantly
+ *	reallocating the space for the string or Unicode representation, we
+ *	allocate double the space for the string or Unicode and use the
+ *	internal representation to keep track of how much space is used vs.
+ *	allocated.
+ *
+ * Copyright (c) 1995-1997 Sun Microsystems, Inc.
+ * Copyright (c) 1999 by Scriptics Corporation.
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+/*
+ * The following structure is the internal rep for a String object. It keeps
+ * track of how much memory has been used and how much has been allocated for
+ * the Unicode and UTF string to enable growing and shrinking of the UTF and
+ * Unicode reps of the String object with fewer mallocs. To optimize string
+ * length and indexing operations, this structure also stores the number of
+ * characters (same of UTF and Unicode!) once that value has been computed.
+ *
+ * Under normal configurations, what Tcl calls "Unicode" is actually UTF-16
+ * restricted to the Basic Multilingual Plane (i.e. U+00000 to U+0FFFF). This
+ * can be officially modified by altering the definition of Tcl_UniChar in
+ * tcl.h, but do not do that unless you are sure what you're doing!
+ */
+
+typedef struct String {
+    int numChars;		/* The number of chars in the string. -1 means
+				 * this value has not been calculated. >= 0
+				 * means that there is a valid Unicode rep, or
+				 * that the number of UTF bytes == the number
+				 * of chars. */
+    int allocated;		/* The amount of space actually allocated for
+				 * the UTF string (minus 1 byte for the
+				 * termination char). */
+    int maxChars;		/* Max number of chars that can fit in the
+				 * space allocated for the unicode array. */
+    int hasUnicode;		/* Boolean determining whether the string has
+				 * a Unicode representation. */
+    Tcl_UniChar unicode[1];	/* The array of Unicode chars. The actual size
+				 * of this field depends on the 'maxChars'
+				 * field above. */
+} String;
+
+#define STRING_MAXCHARS \
+    (int)(((size_t)UINT_MAX - sizeof(String))/sizeof(Tcl_UniChar))
+#define STRING_SIZE(numChars) \
+    (sizeof(String) + ((numChars) * sizeof(Tcl_UniChar)))
+#define stringCheckLimits(numChars) \
+    do {								\
+	if ((numChars) < 0 || (numChars) > STRING_MAXCHARS) {		\
+	    Tcl_Panic("max length for a Tcl unicode value (%d chars) exceeded", \
+		      STRING_MAXCHARS);					\
+	}								\
+    } while (0)
+#define stringAttemptAlloc(numChars) \
+    (String *) attemptckalloc((unsigned) STRING_SIZE(numChars))
+#define stringAlloc(numChars) \
+    (String *) ckalloc((unsigned) STRING_SIZE(numChars))
+#define stringRealloc(ptr, numChars) \
+    (String *) ckrealloc((ptr), (unsigned) STRING_SIZE(numChars))
+#define stringAttemptRealloc(ptr, numChars) \
+    (String *) attemptckrealloc((ptr), (unsigned) STRING_SIZE(numChars))
+#define GET_STRING(objPtr) \
+    ((String *) (objPtr)->internalRep.twoPtrValue.ptr1)
+#define SET_STRING(objPtr, stringPtr) \
+    ((objPtr)->internalRep.twoPtrValue.ptr1 = (void *) (stringPtr))
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tclStringTrim.h b/generic/tclStringTrim.h
new file mode 100644
index 0000000..030e4ec
--- /dev/null
+++ b/generic/tclStringTrim.h
@@ -0,0 +1,43 @@
+/*
+ * tclStringTrim.h --
+ *
+ *	This file contains the definition of what characters are to be trimmed
+ *	from a string by [string trim] by default. It's only needed by Tcl's
+ *	implementation; it does not form a public or private API at all.
+ *
+ * Copyright (c) 1987-1993 The Regents of the University of California.
+ * Copyright (c) 1994-1997 Sun Microsystems, Inc.
+ * Copyright (c) 1998-2000 Scriptics Corporation.
+ * Copyright (c) 2002 ActiveState Corporation.
+ * Copyright (c) 2003-2013 Donal K. Fellows.
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#ifndef TCL_STRING_TRIM_H
+#define TCL_STRING_TRIM_H
+
+/*
+ * Default set of characters to trim in [string trim] and friends. This is a
+ * UTF-8 literal string containing all Unicode space characters. [TIP #413]
+ */
+
+MODULE_SCOPE const char tclDefaultTrimSet[];
+
+/*
+ * The whitespace trimming set used when [concat]enating. This is a subset of
+ * the above, and deliberately so.
+ */
+
+#define CONCAT_TRIM_SET " \f\v\r\t\n"
+
+#endif /* TCL_STRING_TRIM_H */
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tclStubInit.c b/generic/tclStubInit.c
new file mode 100644
index 0000000..5b7a1cd
--- /dev/null
+++ b/generic/tclStubInit.c
@@ -0,0 +1,1420 @@
+/*
+ * tclStubInit.c --
+ *
+ *	This file contains the initializers for the Tcl stub vectors.
+ *
+ * Copyright (c) 1998-1999 by Scriptics Corporation.
+ *
+ * See the file "license.terms" for information on usage and redistribution
+ * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#include "tclInt.h"
+#include "tommath.h"
+
+#ifdef __GNUC__
+#pragma GCC dependency "tcl.decls"
+#pragma GCC dependency "tclInt.decls"
+#pragma GCC dependency "tclTomMath.decls"
+#endif
+
+/*
+ * Remove macros that will interfere with the definitions below.
+ */
+
+#undef Tcl_Alloc
+#undef Tcl_Free
+#undef Tcl_Realloc
+#undef Tcl_NewBooleanObj
+#undef Tcl_NewByteArrayObj
+#undef Tcl_NewDoubleObj
+#undef Tcl_NewIntObj
+#undef Tcl_NewListObj
+#undef Tcl_NewLongObj
+#undef Tcl_NewObj
+#undef Tcl_NewStringObj
+#undef Tcl_DumpActiveMemory
+#undef Tcl_ValidateAllMemory
+#undef Tcl_FindHashEntry
+#undef Tcl_CreateHashEntry
+#undef Tcl_Panic
+#undef Tcl_FindExecutable
+#undef TclpGetPid
+#undef TclSockMinimumBuffers
+#define TclBackgroundException Tcl_BackgroundException
+#undef Tcl_SetIntObj
+#undef TclpInetNtoa
+#undef TclWinGetServByName
+#undef TclWinGetSockOpt
+#undef TclWinSetSockOpt
+
+/* See bug 510001: TclSockMinimumBuffers needs plat imp */
+#ifdef _WIN64
+#   define TclSockMinimumBuffersOld 0
+#else
+#define TclSockMinimumBuffersOld sockMinimumBuffersOld
+static int TclSockMinimumBuffersOld(int sock, int size)
+{
+    return TclSockMinimumBuffers(INT2PTR(sock), size);
+}
+#endif
+
+#define TclSetStartupScriptPath setStartupScriptPath
+static void TclSetStartupScriptPath(Tcl_Obj *path)
+{
+    Tcl_SetStartupScript(path, NULL);
+}
+#define TclGetStartupScriptPath getStartupScriptPath
+static Tcl_Obj *TclGetStartupScriptPath(void)
+{
+    return Tcl_GetStartupScript(NULL);
+}
+#define TclSetStartupScriptFileName setStartupScriptFileName
+static void TclSetStartupScriptFileName(
+    const char *fileName)
+{
+    Tcl_SetStartupScript(Tcl_NewStringObj(fileName,-1), NULL);
+}
+#define TclGetStartupScriptFileName getStartupScriptFileName
+static const char *TclGetStartupScriptFileName(void)
+{
+    Tcl_Obj *path = Tcl_GetStartupScript(NULL);
+    if (path == NULL) {
+	return NULL;
+    }
+    return Tcl_GetString(path);
+}
+
+#if defined(_WIN32) || defined(__CYGWIN__)
+#undef TclWinNToHS
+#define TclWinNToHS winNToHS
+static unsigned short TclWinNToHS(unsigned short ns) {
+	return ntohs(ns);
+}
+#endif
+
+#ifdef _WIN32
+#   define TclUnixWaitForFile 0
+#   define TclUnixCopyFile 0
+#   define TclUnixOpenTemporaryFile 0
+#   define TclpReaddir 0
+#   define TclpIsAtty 0
+#elif defined(__CYGWIN__)
+#   define TclpIsAtty TclPlatIsAtty
+#   define TclWinSetInterfaces (void (*) (int)) doNothing
+#   define TclWinAddProcess (void (*) (void *, unsigned int)) doNothing
+#   define TclWinFlushDirtyChannels doNothing
+#   define TclWinResetInterfaces doNothing
+
+static Tcl_Encoding winTCharEncoding;
+
+static int
+TclpIsAtty(int fd)
+{
+    return isatty(fd);
+}
+
+#define TclWinGetPlatformId winGetPlatformId
+static int
+TclWinGetPlatformId()
+{
+    /* Don't bother to determine the real platform on cygwin,
+     * because VER_PLATFORM_WIN32_NT is the only supported platform */
+    return 2; /* VER_PLATFORM_WIN32_NT */;
+}
+
+void *TclWinGetTclInstance()
+{
+    void *hInstance = NULL;
+    GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
+	    (const char *)&winTCharEncoding, &hInstance);
+    return hInstance;
+}
+
+#define TclWinSetSockOpt winSetSockOpt
+static int
+TclWinSetSockOpt(SOCKET s, int level, int optname,
+	    const char *optval, int optlen)
+{
+    return setsockopt((int) s, level, optname, optval, optlen);
+}
+
+#define TclWinGetSockOpt winGetSockOpt
+static int
+TclWinGetSockOpt(SOCKET s, int level, int optname,
+	    char *optval, int *optlen)
+{
+    return getsockopt((int) s, level, optname, optval, optlen);
+}
+
+#define TclWinGetServByName winGetServByName
+static struct servent *
+TclWinGetServByName(const char *name, const char *proto)
+{
+    return getservbyname(name, proto);
+}
+
+#define TclWinNoBackslash winNoBackslash
+static char *
+TclWinNoBackslash(char *path)
+{
+    char *p;
+
+    for (p = path; *p != '\0'; p++) {
+	if (*p == '\\') {
+	    *p = '/';
+	}
+    }
+    return path;
+}
+
+int
+TclpGetPid(Tcl_Pid pid)
+{
+    return (int) (size_t) pid;
+}
+
+static void
+doNothing(void)
+{
+    /* dummy implementation, no need to do anything */
+}
+
+char *
+Tcl_WinUtfToTChar(
+    const char *string,
+    int len,
+    Tcl_DString *dsPtr)
+{
+    if (!winTCharEncoding) {
+	winTCharEncoding = Tcl_GetEncoding(0, "unicode");
+    }
+    return Tcl_UtfToExternalDString(winTCharEncoding,
+	    string, len, dsPtr);
+}
+
+char *
+Tcl_WinTCharToUtf(
+    const char *string,
+    int len,
+    Tcl_DString *dsPtr)
+{
+    if (!winTCharEncoding) {
+	winTCharEncoding = Tcl_GetEncoding(0, "unicode");
+    }
+    return Tcl_ExternalToUtfDString(winTCharEncoding,
+	    string, len, dsPtr);
+}
+
+#if defined(TCL_WIDE_INT_IS_LONG)
+/* On Cygwin64, long is 64-bit while on Win64 long is 32-bit. Therefore
+ * we have to make sure that all stub entries on Cygwin64 follow the Win64
+ * signature. Tcl 9 must find a better solution, but that cannot be done
+ * without introducing a binary incompatibility.
+ */
+#define Tcl_DbNewLongObj ((Tcl_Obj*(*)(long,const char*,int))dbNewLongObj)
+static Tcl_Obj *dbNewLongObj(
+    int intValue,
+    const char *file,
+    int line
+) {
+#ifdef TCL_MEM_DEBUG
+    register Tcl_Obj *objPtr;
+
+    TclDbNewObj(objPtr, file, line);
+    objPtr->bytes = NULL;
+
+    objPtr->internalRep.longValue = (long) intValue;
+    objPtr->typePtr = &tclIntType;
+    return objPtr;
+#else
+    return Tcl_NewIntObj(intValue);
+#endif
+}
+#define Tcl_GetLongFromObj (int(*)(Tcl_Interp*,Tcl_Obj*,long*))Tcl_GetIntFromObj
+#define Tcl_NewLongObj (Tcl_Obj*(*)(long))Tcl_NewIntObj
+#define Tcl_SetLongObj (void(*)(Tcl_Obj*,long))Tcl_SetIntObj
+static int exprInt(Tcl_Interp *interp, const char *expr, int *ptr){
+    long longValue;
+    int result = Tcl_ExprLong(interp, expr, &longValue);
+    if (result == TCL_OK) {
+	    if ((longValue >= -(long)(UINT_MAX))
+		    && (longValue <= (long)(UINT_MAX))) {
+	    *ptr = (int)longValue;
+	} else {
+	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		    "integer value too large to represent as non-long integer", -1));
+	    result = TCL_ERROR;
+	}
+    }
+    return result;
+}
+#define Tcl_ExprLong (int(*)(Tcl_Interp*,const char*,long*))exprInt
+static int exprIntObj(Tcl_Interp *interp, Tcl_Obj*expr, int *ptr){
+    long longValue;
+    int result = Tcl_ExprLongObj(interp, expr, &longValue);
+    if (result == TCL_OK) {
+	    if ((longValue >= -(long)(UINT_MAX))
+		    && (longValue <= (long)(UINT_MAX))) {
+	    *ptr = (int)longValue;
+	} else {
+	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		    "integer value too large to represent as non-long integer", -1));
+	    result = TCL_ERROR;
+	}
+    }
+    return result;
+}
+#define Tcl_ExprLongObj (int(*)(Tcl_Interp*,Tcl_Obj*,long*))exprIntObj
+static int uniCharNcmp(const Tcl_UniChar *ucs, const Tcl_UniChar *uct, unsigned int n){
+   return Tcl_UniCharNcmp(ucs, uct, (unsigned long)n);
+}
+#define Tcl_UniCharNcmp (int(*)(const Tcl_UniChar*,const Tcl_UniChar*,unsigned long))uniCharNcmp
+static int utfNcmp(const char *s1, const char *s2, unsigned int n){
+   return Tcl_UtfNcmp(s1, s2, (unsigned long)n);
+}
+#define Tcl_UtfNcmp (int(*)(const char*,const char*,unsigned long))utfNcmp
+static int utfNcasecmp(const char *s1, const char *s2, unsigned int n){
+   return Tcl_UtfNcasecmp(s1, s2, (unsigned long)n);
+}
+#define Tcl_UtfNcasecmp (int(*)(const char*,const char*,unsigned long))utfNcasecmp
+static int uniCharNcasecmp(const Tcl_UniChar *ucs, const Tcl_UniChar *uct, unsigned int n){
+   return Tcl_UniCharNcasecmp(ucs, uct, (unsigned long)n);
+}
+#define Tcl_UniCharNcasecmp (int(*)(const Tcl_UniChar*,const Tcl_UniChar*,unsigned long))uniCharNcasecmp
+static int formatInt(char *buffer, int n){
+   return TclFormatInt(buffer, (long)n);
+}
+#define TclFormatInt (int(*)(char *, long))formatInt
+
+#endif
+
+#else /* UNIX and MAC */
+#   define TclpLocaltime_unix TclpLocaltime
+#   define TclpGmtime_unix TclpGmtime
+#endif
+
+/*
+ * WARNING: The contents of this file is automatically generated by the
+ * tools/genStubs.tcl script. Any modifications to the function declarations
+ * below should be made in the generic/tcl.decls script.
+ */
+
+MODULE_SCOPE const TclStubs tclStubs;
+MODULE_SCOPE const TclTomMathStubs tclTomMathStubs;
+
+/* !BEGIN!: Do not edit below this line. */
+
+static const TclIntStubs tclIntStubs = {
+    TCL_STUB_MAGIC,
+    0,
+    0, /* 0 */
+    0, /* 1 */
+    0, /* 2 */
+    TclAllocateFreeObjects, /* 3 */
+    0, /* 4 */
+    TclCleanupChildren, /* 5 */
+    TclCleanupCommand, /* 6 */
+    TclCopyAndCollapse, /* 7 */
+    TclCopyChannelOld, /* 8 */
+    TclCreatePipeline, /* 9 */
+    TclCreateProc, /* 10 */
+    TclDeleteCompiledLocalVars, /* 11 */
+    TclDeleteVars, /* 12 */
+    0, /* 13 */
+    TclDumpMemoryInfo, /* 14 */
+    0, /* 15 */
+    TclExprFloatError, /* 16 */
+    0, /* 17 */
+    0, /* 18 */
+    0, /* 19 */
+    0, /* 20 */
+    0, /* 21 */
+    TclFindElement, /* 22 */
+    TclFindProc, /* 23 */
+    TclFormatInt, /* 24 */
+    TclFreePackageInfo, /* 25 */
+    0, /* 26 */
+    0, /* 27 */
+    TclpGetDefaultStdChannel, /* 28 */
+    0, /* 29 */
+    0, /* 30 */
+    TclGetExtension, /* 31 */
+    TclGetFrame, /* 32 */
+    0, /* 33 */
+    TclGetIntForIndex, /* 34 */
+    0, /* 35 */
+    0, /* 36 */
+    TclGetLoadedPackages, /* 37 */
+    TclGetNamespaceForQualName, /* 38 */
+    TclGetObjInterpProc, /* 39 */
+    TclGetOpenMode, /* 40 */
+    TclGetOriginalCommand, /* 41 */
+    TclpGetUserHome, /* 42 */
+    0, /* 43 */
+    TclGuessPackageName, /* 44 */
+    TclHideUnsafeCommands, /* 45 */
+    TclInExit, /* 46 */
+    0, /* 47 */
+    0, /* 48 */
+    0, /* 49 */
+    TclInitCompiledLocals, /* 50 */
+    TclInterpInit, /* 51 */
+    0, /* 52 */
+    TclInvokeObjectCommand, /* 53 */
+    TclInvokeStringCommand, /* 54 */
+    TclIsProc, /* 55 */
+    0, /* 56 */
+    0, /* 57 */
+    TclLookupVar, /* 58 */
+    0, /* 59 */
+    TclNeedSpace, /* 60 */
+    TclNewProcBodyObj, /* 61 */
+    TclObjCommandComplete, /* 62 */
+    TclObjInterpProc, /* 63 */
+    TclObjInvoke, /* 64 */
+    0, /* 65 */
+    0, /* 66 */
+    0, /* 67 */
+    0, /* 68 */
+    TclpAlloc, /* 69 */
+    0, /* 70 */
+    0, /* 71 */
+    0, /* 72 */
+    0, /* 73 */
+    TclpFree, /* 74 */
+    TclpGetClicks, /* 75 */
+    TclpGetSeconds, /* 76 */
+    TclpGetTime, /* 77 */
+    0, /* 78 */
+    0, /* 79 */
+    0, /* 80 */
+    TclpRealloc, /* 81 */
+    0, /* 82 */
+    0, /* 83 */
+    0, /* 84 */
+    0, /* 85 */
+    0, /* 86 */
+    0, /* 87 */
+    TclPrecTraceProc, /* 88 */
+    TclPreventAliasLoop, /* 89 */
+    0, /* 90 */
+    TclProcCleanupProc, /* 91 */
+    TclProcCompileProc, /* 92 */
+    TclProcDeleteProc, /* 93 */
+    0, /* 94 */
+    0, /* 95 */
+    TclRenameCommand, /* 96 */
+    TclResetShadowedCmdRefs, /* 97 */
+    TclServiceIdle, /* 98 */
+    0, /* 99 */
+    0, /* 100 */
+    TclSetPreInitScript, /* 101 */
+    TclSetupEnv, /* 102 */
+    TclSockGetPort, /* 103 */
+    TclSockMinimumBuffersOld, /* 104 */
+    0, /* 105 */
+    0, /* 106 */
+    0, /* 107 */
+    TclTeardownNamespace, /* 108 */
+    TclUpdateReturnInfo, /* 109 */
+    TclSockMinimumBuffers, /* 110 */
+    Tcl_AddInterpResolvers, /* 111 */
+    Tcl_AppendExportList, /* 112 */
+    Tcl_CreateNamespace, /* 113 */
+    Tcl_DeleteNamespace, /* 114 */
+    Tcl_Export, /* 115 */
+    Tcl_FindCommand, /* 116 */
+    Tcl_FindNamespace, /* 117 */
+    Tcl_GetInterpResolvers, /* 118 */
+    Tcl_GetNamespaceResolvers, /* 119 */
+    Tcl_FindNamespaceVar, /* 120 */
+    Tcl_ForgetImport, /* 121 */
+    Tcl_GetCommandFromObj, /* 122 */
+    Tcl_GetCommandFullName, /* 123 */
+    Tcl_GetCurrentNamespace, /* 124 */
+    Tcl_GetGlobalNamespace, /* 125 */
+    Tcl_GetVariableFullName, /* 126 */
+    Tcl_Import, /* 127 */
+    Tcl_PopCallFrame, /* 128 */
+    Tcl_PushCallFrame, /* 129 */
+    Tcl_RemoveInterpResolvers, /* 130 */
+    Tcl_SetNamespaceResolvers, /* 131 */
+    TclpHasSockets, /* 132 */
+    TclpGetDate, /* 133 */
+    0, /* 134 */
+    0, /* 135 */
+    0, /* 136 */
+    0, /* 137 */
+    TclGetEnv, /* 138 */
+    0, /* 139 */
+    0, /* 140 */
+    TclpGetCwd, /* 141 */
+    TclSetByteCodeFromAny, /* 142 */
+    TclAddLiteralObj, /* 143 */
+    TclHideLiteral, /* 144 */
+    TclGetAuxDataType, /* 145 */
+    TclHandleCreate, /* 146 */
+    TclHandleFree, /* 147 */
+    TclHandlePreserve, /* 148 */
+    TclHandleRelease, /* 149 */
+    TclRegAbout, /* 150 */
+    TclRegExpRangeUniChar, /* 151 */
+    TclSetLibraryPath, /* 152 */
+    TclGetLibraryPath, /* 153 */
+    0, /* 154 */
+    0, /* 155 */
+    TclRegError, /* 156 */
+    TclVarTraceExists, /* 157 */
+    TclSetStartupScriptFileName, /* 158 */
+    TclGetStartupScriptFileName, /* 159 */
+    0, /* 160 */
+    TclChannelTransform, /* 161 */
+    TclChannelEventScriptInvoker, /* 162 */
+    TclGetInstructionTable, /* 163 */
+    TclExpandCodeArray, /* 164 */
+    TclpSetInitialEncodings, /* 165 */
+    TclListObjSetElement, /* 166 */
+    TclSetStartupScriptPath, /* 167 */
+    TclGetStartupScriptPath, /* 168 */
+    TclpUtfNcmp2, /* 169 */
+    TclCheckInterpTraces, /* 170 */
+    TclCheckExecutionTraces, /* 171 */
+    TclInThreadExit, /* 172 */
+    TclUniCharMatch, /* 173 */
+    0, /* 174 */
+    TclCallVarTraces, /* 175 */
+    TclCleanupVar, /* 176 */
+    TclVarErrMsg, /* 177 */
+    Tcl_SetStartupScript, /* 178 */
+    Tcl_GetStartupScript, /* 179 */
+    0, /* 180 */
+    0, /* 181 */
+    TclpLocaltime, /* 182 */
+    TclpGmtime, /* 183 */
+    0, /* 184 */
+    0, /* 185 */
+    0, /* 186 */
+    0, /* 187 */
+    0, /* 188 */
+    0, /* 189 */
+    0, /* 190 */
+    0, /* 191 */
+    0, /* 192 */
+    0, /* 193 */
+    0, /* 194 */
+    0, /* 195 */
+    0, /* 196 */
+    0, /* 197 */
+    TclObjGetFrame, /* 198 */
+    0, /* 199 */
+    TclpObjRemoveDirectory, /* 200 */
+    TclpObjCopyDirectory, /* 201 */
+    TclpObjCreateDirectory, /* 202 */
+    TclpObjDeleteFile, /* 203 */
+    TclpObjCopyFile, /* 204 */
+    TclpObjRenameFile, /* 205 */
+    TclpObjStat, /* 206 */
+    TclpObjAccess, /* 207 */
+    TclpOpenFileChannel, /* 208 */
+    0, /* 209 */
+    0, /* 210 */
+    0, /* 211 */
+    TclpFindExecutable, /* 212 */
+    TclGetObjNameOfExecutable, /* 213 */
+    TclSetObjNameOfExecutable, /* 214 */
+    TclStackAlloc, /* 215 */
+    TclStackFree, /* 216 */
+    TclPushStackFrame, /* 217 */
+    TclPopStackFrame, /* 218 */
+    0, /* 219 */
+    0, /* 220 */
+    0, /* 221 */
+    0, /* 222 */
+    0, /* 223 */
+    TclGetPlatform, /* 224 */
+    TclTraceDictPath, /* 225 */
+    TclObjBeingDeleted, /* 226 */
+    TclSetNsPath, /* 227 */
+    0, /* 228 */
+    TclPtrMakeUpvar, /* 229 */
+    TclObjLookupVar, /* 230 */
+    TclGetNamespaceFromObj, /* 231 */
+    TclEvalObjEx, /* 232 */
+    TclGetSrcInfoForPc, /* 233 */
+    TclVarHashCreateVar, /* 234 */
+    TclInitVarHashTable, /* 235 */
+    TclBackgroundException, /* 236 */
+    TclResetCancellation, /* 237 */
+    TclNRInterpProc, /* 238 */
+    TclNRInterpProcCore, /* 239 */
+    TclNRRunCallbacks, /* 240 */
+    TclNREvalObjEx, /* 241 */
+    TclNREvalObjv, /* 242 */
+    TclDbDumpActiveObjects, /* 243 */
+    TclGetNamespaceChildTable, /* 244 */
+    TclGetNamespaceCommandTable, /* 245 */
+    TclInitRewriteEnsemble, /* 246 */
+    TclResetRewriteEnsemble, /* 247 */
+    TclCopyChannel, /* 248 */
+    TclDoubleDigits, /* 249 */
+    TclSetSlaveCancelFlags, /* 250 */
+    TclRegisterLiteral, /* 251 */
+};
+
+static const TclIntPlatStubs tclIntPlatStubs = {
+    TCL_STUB_MAGIC,
+    0,
+#if !defined(_WIN32) && !defined(__CYGWIN__) && !defined(MAC_OSX_TCL) /* UNIX */
+    TclGetAndDetachPids, /* 0 */
+    TclpCloseFile, /* 1 */
+    TclpCreateCommandChannel, /* 2 */
+    TclpCreatePipe, /* 3 */
+    TclpCreateProcess, /* 4 */
+    0, /* 5 */
+    TclpMakeFile, /* 6 */
+    TclpOpenFile, /* 7 */
+    TclUnixWaitForFile, /* 8 */
+    TclpCreateTempFile, /* 9 */
+    TclpReaddir, /* 10 */
+    TclpLocaltime_unix, /* 11 */
+    TclpGmtime_unix, /* 12 */
+    TclpInetNtoa, /* 13 */
+    TclUnixCopyFile, /* 14 */
+    0, /* 15 */
+    0, /* 16 */
+    0, /* 17 */
+    0, /* 18 */
+    0, /* 19 */
+    0, /* 20 */
+    0, /* 21 */
+    0, /* 22 */
+    0, /* 23 */
+    0, /* 24 */
+    0, /* 25 */
+    0, /* 26 */
+    0, /* 27 */
+    0, /* 28 */
+    TclWinCPUID, /* 29 */
+    TclUnixOpenTemporaryFile, /* 30 */
+#endif /* UNIX */
+#if defined(_WIN32) || defined(__CYGWIN__) /* WIN */
+    TclWinConvertError, /* 0 */
+    TclWinConvertWSAError, /* 1 */
+    TclWinGetServByName, /* 2 */
+    TclWinGetSockOpt, /* 3 */
+    TclWinGetTclInstance, /* 4 */
+    TclUnixWaitForFile, /* 5 */
+    TclWinNToHS, /* 6 */
+    TclWinSetSockOpt, /* 7 */
+    TclpGetPid, /* 8 */
+    TclWinGetPlatformId, /* 9 */
+    TclpReaddir, /* 10 */
+    TclGetAndDetachPids, /* 11 */
+    TclpCloseFile, /* 12 */
+    TclpCreateCommandChannel, /* 13 */
+    TclpCreatePipe, /* 14 */
+    TclpCreateProcess, /* 15 */
+    TclpIsAtty, /* 16 */
+    TclUnixCopyFile, /* 17 */
+    TclpMakeFile, /* 18 */
+    TclpOpenFile, /* 19 */
+    TclWinAddProcess, /* 20 */
+    TclpInetNtoa, /* 21 */
+    TclpCreateTempFile, /* 22 */
+    0, /* 23 */
+    TclWinNoBackslash, /* 24 */
+    0, /* 25 */
+    TclWinSetInterfaces, /* 26 */
+    TclWinFlushDirtyChannels, /* 27 */
+    TclWinResetInterfaces, /* 28 */
+    TclWinCPUID, /* 29 */
+    TclUnixOpenTemporaryFile, /* 30 */
+#endif /* WIN */
+#ifdef MAC_OSX_TCL /* MACOSX */
+    TclGetAndDetachPids, /* 0 */
+    TclpCloseFile, /* 1 */
+    TclpCreateCommandChannel, /* 2 */
+    TclpCreatePipe, /* 3 */
+    TclpCreateProcess, /* 4 */
+    0, /* 5 */
+    TclpMakeFile, /* 6 */
+    TclpOpenFile, /* 7 */
+    TclUnixWaitForFile, /* 8 */
+    TclpCreateTempFile, /* 9 */
+    TclpReaddir, /* 10 */
+    TclpLocaltime_unix, /* 11 */
+    TclpGmtime_unix, /* 12 */
+    TclpInetNtoa, /* 13 */
+    TclUnixCopyFile, /* 14 */
+    TclMacOSXGetFileAttribute, /* 15 */
+    TclMacOSXSetFileAttribute, /* 16 */
+    TclMacOSXCopyFileAttributes, /* 17 */
+    TclMacOSXMatchType, /* 18 */
+    TclMacOSXNotifierAddRunLoopMode, /* 19 */
+    0, /* 20 */
+    0, /* 21 */
+    0, /* 22 */
+    0, /* 23 */
+    0, /* 24 */
+    0, /* 25 */
+    0, /* 26 */
+    0, /* 27 */
+    0, /* 28 */
+    TclWinCPUID, /* 29 */
+    TclUnixOpenTemporaryFile, /* 30 */
+#endif /* MACOSX */
+};
+
+static const TclPlatStubs tclPlatStubs = {
+    TCL_STUB_MAGIC,
+    0,
+#if defined(_WIN32) || defined(__CYGWIN__) /* WIN */
+    Tcl_WinUtfToTChar, /* 0 */
+    Tcl_WinTCharToUtf, /* 1 */
+#endif /* WIN */
+#ifdef MAC_OSX_TCL /* MACOSX */
+    Tcl_MacOSXOpenBundleResources, /* 0 */
+    Tcl_MacOSXOpenVersionedBundleResources, /* 1 */
+#endif /* MACOSX */
+};
+
+const TclTomMathStubs tclTomMathStubs = {
+    TCL_STUB_MAGIC,
+    0,
+    TclBN_epoch, /* 0 */
+    TclBN_revision, /* 1 */
+    TclBN_mp_add, /* 2 */
+    TclBN_mp_add_d, /* 3 */
+    TclBN_mp_and, /* 4 */
+    TclBN_mp_clamp, /* 5 */
+    TclBN_mp_clear, /* 6 */
+    TclBN_mp_clear_multi, /* 7 */
+    TclBN_mp_cmp, /* 8 */
+    TclBN_mp_cmp_d, /* 9 */
+    TclBN_mp_cmp_mag, /* 10 */
+    TclBN_mp_copy, /* 11 */
+    TclBN_mp_count_bits, /* 12 */
+    TclBN_mp_div, /* 13 */
+    TclBN_mp_div_d, /* 14 */
+    TclBN_mp_div_2, /* 15 */
+    TclBN_mp_div_2d, /* 16 */
+    TclBN_mp_div_3, /* 17 */
+    TclBN_mp_exch, /* 18 */
+    TclBN_mp_expt_d, /* 19 */
+    TclBN_mp_grow, /* 20 */
+    TclBN_mp_init, /* 21 */
+    TclBN_mp_init_copy, /* 22 */
+    TclBN_mp_init_multi, /* 23 */
+    TclBN_mp_init_set, /* 24 */
+    TclBN_mp_init_size, /* 25 */
+    TclBN_mp_lshd, /* 26 */
+    TclBN_mp_mod, /* 27 */
+    TclBN_mp_mod_2d, /* 28 */
+    TclBN_mp_mul, /* 29 */
+    TclBN_mp_mul_d, /* 30 */
+    TclBN_mp_mul_2, /* 31 */
+    TclBN_mp_mul_2d, /* 32 */
+    TclBN_mp_neg, /* 33 */
+    TclBN_mp_or, /* 34 */
+    TclBN_mp_radix_size, /* 35 */
+    TclBN_mp_read_radix, /* 36 */
+    TclBN_mp_rshd, /* 37 */
+    TclBN_mp_shrink, /* 38 */
+    TclBN_mp_set, /* 39 */
+    TclBN_mp_sqr, /* 40 */
+    TclBN_mp_sqrt, /* 41 */
+    TclBN_mp_sub, /* 42 */
+    TclBN_mp_sub_d, /* 43 */
+    TclBN_mp_to_unsigned_bin, /* 44 */
+    TclBN_mp_to_unsigned_bin_n, /* 45 */
+    TclBN_mp_toradix_n, /* 46 */
+    TclBN_mp_unsigned_bin_size, /* 47 */
+    TclBN_mp_xor, /* 48 */
+    TclBN_mp_zero, /* 49 */
+    TclBN_reverse, /* 50 */
+    TclBN_fast_s_mp_mul_digs, /* 51 */
+    TclBN_fast_s_mp_sqr, /* 52 */
+    TclBN_mp_karatsuba_mul, /* 53 */
+    TclBN_mp_karatsuba_sqr, /* 54 */
+    TclBN_mp_toom_mul, /* 55 */
+    TclBN_mp_toom_sqr, /* 56 */
+    TclBN_s_mp_add, /* 57 */
+    TclBN_s_mp_mul_digs, /* 58 */
+    TclBN_s_mp_sqr, /* 59 */
+    TclBN_s_mp_sub, /* 60 */
+    TclBN_mp_init_set_int, /* 61 */
+    TclBN_mp_set_int, /* 62 */
+    TclBN_mp_cnt_lsb, /* 63 */
+    TclBNInitBignumFromLong, /* 64 */
+    TclBNInitBignumFromWideInt, /* 65 */
+    TclBNInitBignumFromWideUInt, /* 66 */
+};
+
+static const TclStubHooks tclStubHooks = {
+    &tclPlatStubs,
+    &tclIntStubs,
+    &tclIntPlatStubs
+};
+
+const TclStubs tclStubs = {
+    TCL_STUB_MAGIC,
+    &tclStubHooks,
+    Tcl_PkgProvideEx, /* 0 */
+    Tcl_PkgRequireEx, /* 1 */
+    Tcl_Panic, /* 2 */
+    Tcl_Alloc, /* 3 */
+    Tcl_Free, /* 4 */
+    Tcl_Realloc, /* 5 */
+    Tcl_DbCkalloc, /* 6 */
+    Tcl_DbCkfree, /* 7 */
+    Tcl_DbCkrealloc, /* 8 */
+#if !defined(_WIN32) && !defined(MAC_OSX_TCL) /* UNIX */
+    Tcl_CreateFileHandler, /* 9 */
+#endif /* UNIX */
+#if defined(_WIN32) /* WIN */
+    0, /* 9 */
+#endif /* WIN */
+#ifdef MAC_OSX_TCL /* MACOSX */
+    Tcl_CreateFileHandler, /* 9 */
+#endif /* MACOSX */
+#if !defined(_WIN32) && !defined(MAC_OSX_TCL) /* UNIX */
+    Tcl_DeleteFileHandler, /* 10 */
+#endif /* UNIX */
+#if defined(_WIN32) /* WIN */
+    0, /* 10 */
+#endif /* WIN */
+#ifdef MAC_OSX_TCL /* MACOSX */
+    Tcl_DeleteFileHandler, /* 10 */
+#endif /* MACOSX */
+    Tcl_SetTimer, /* 11 */
+    Tcl_Sleep, /* 12 */
+    Tcl_WaitForEvent, /* 13 */
+    Tcl_AppendAllObjTypes, /* 14 */
+    Tcl_AppendStringsToObj, /* 15 */
+    Tcl_AppendToObj, /* 16 */
+    Tcl_ConcatObj, /* 17 */
+    Tcl_ConvertToType, /* 18 */
+    Tcl_DbDecrRefCount, /* 19 */
+    Tcl_DbIncrRefCount, /* 20 */
+    Tcl_DbIsShared, /* 21 */
+    Tcl_DbNewBooleanObj, /* 22 */
+    Tcl_DbNewByteArrayObj, /* 23 */
+    Tcl_DbNewDoubleObj, /* 24 */
+    Tcl_DbNewListObj, /* 25 */
+    Tcl_DbNewLongObj, /* 26 */
+    Tcl_DbNewObj, /* 27 */
+    Tcl_DbNewStringObj, /* 28 */
+    Tcl_DuplicateObj, /* 29 */
+    TclFreeObj, /* 30 */
+    Tcl_GetBoolean, /* 31 */
+    Tcl_GetBooleanFromObj, /* 32 */
+    Tcl_GetByteArrayFromObj, /* 33 */
+    Tcl_GetDouble, /* 34 */
+    Tcl_GetDoubleFromObj, /* 35 */
+    Tcl_GetIndexFromObj, /* 36 */
+    Tcl_GetInt, /* 37 */
+    Tcl_GetIntFromObj, /* 38 */
+    Tcl_GetLongFromObj, /* 39 */
+    Tcl_GetObjType, /* 40 */
+    Tcl_GetStringFromObj, /* 41 */
+    Tcl_InvalidateStringRep, /* 42 */
+    Tcl_ListObjAppendList, /* 43 */
+    Tcl_ListObjAppendElement, /* 44 */
+    Tcl_ListObjGetElements, /* 45 */
+    Tcl_ListObjIndex, /* 46 */
+    Tcl_ListObjLength, /* 47 */
+    Tcl_ListObjReplace, /* 48 */
+    Tcl_NewBooleanObj, /* 49 */
+    Tcl_NewByteArrayObj, /* 50 */
+    Tcl_NewDoubleObj, /* 51 */
+    Tcl_NewIntObj, /* 52 */
+    Tcl_NewListObj, /* 53 */
+    Tcl_NewLongObj, /* 54 */
+    Tcl_NewObj, /* 55 */
+    Tcl_NewStringObj, /* 56 */
+    Tcl_SetBooleanObj, /* 57 */
+    Tcl_SetByteArrayLength, /* 58 */
+    Tcl_SetByteArrayObj, /* 59 */
+    Tcl_SetDoubleObj, /* 60 */
+    Tcl_SetIntObj, /* 61 */
+    Tcl_SetListObj, /* 62 */
+    Tcl_SetLongObj, /* 63 */
+    Tcl_SetObjLength, /* 64 */
+    Tcl_SetStringObj, /* 65 */
+    Tcl_AddErrorInfo, /* 66 */
+    Tcl_AddObjErrorInfo, /* 67 */
+    Tcl_AllowExceptions, /* 68 */
+    Tcl_AppendElement, /* 69 */
+    Tcl_AppendResult, /* 70 */
+    Tcl_AsyncCreate, /* 71 */
+    Tcl_AsyncDelete, /* 72 */
+    Tcl_AsyncInvoke, /* 73 */
+    Tcl_AsyncMark, /* 74 */
+    Tcl_AsyncReady, /* 75 */
+    Tcl_BackgroundError, /* 76 */
+    Tcl_Backslash, /* 77 */
+    Tcl_BadChannelOption, /* 78 */
+    Tcl_CallWhenDeleted, /* 79 */
+    Tcl_CancelIdleCall, /* 80 */
+    Tcl_Close, /* 81 */
+    Tcl_CommandComplete, /* 82 */
+    Tcl_Concat, /* 83 */
+    Tcl_ConvertElement, /* 84 */
+    Tcl_ConvertCountedElement, /* 85 */
+    Tcl_CreateAlias, /* 86 */
+    Tcl_CreateAliasObj, /* 87 */
+    Tcl_CreateChannel, /* 88 */
+    Tcl_CreateChannelHandler, /* 89 */
+    Tcl_CreateCloseHandler, /* 90 */
+    Tcl_CreateCommand, /* 91 */
+    Tcl_CreateEventSource, /* 92 */
+    Tcl_CreateExitHandler, /* 93 */
+    Tcl_CreateInterp, /* 94 */
+    Tcl_CreateMathFunc, /* 95 */
+    Tcl_CreateObjCommand, /* 96 */
+    Tcl_CreateSlave, /* 97 */
+    Tcl_CreateTimerHandler, /* 98 */
+    Tcl_CreateTrace, /* 99 */
+    Tcl_DeleteAssocData, /* 100 */
+    Tcl_DeleteChannelHandler, /* 101 */
+    Tcl_DeleteCloseHandler, /* 102 */
+    Tcl_DeleteCommand, /* 103 */
+    Tcl_DeleteCommandFromToken, /* 104 */
+    Tcl_DeleteEvents, /* 105 */
+    Tcl_DeleteEventSource, /* 106 */
+    Tcl_DeleteExitHandler, /* 107 */
+    Tcl_DeleteHashEntry, /* 108 */
+    Tcl_DeleteHashTable, /* 109 */
+    Tcl_DeleteInterp, /* 110 */
+    Tcl_DetachPids, /* 111 */
+    Tcl_DeleteTimerHandler, /* 112 */
+    Tcl_DeleteTrace, /* 113 */
+    Tcl_DontCallWhenDeleted, /* 114 */
+    Tcl_DoOneEvent, /* 115 */
+    Tcl_DoWhenIdle, /* 116 */
+    Tcl_DStringAppend, /* 117 */
+    Tcl_DStringAppendElement, /* 118 */
+    Tcl_DStringEndSublist, /* 119 */
+    Tcl_DStringFree, /* 120 */
+    Tcl_DStringGetResult, /* 121 */
+    Tcl_DStringInit, /* 122 */
+    Tcl_DStringResult, /* 123 */
+    Tcl_DStringSetLength, /* 124 */
+    Tcl_DStringStartSublist, /* 125 */
+    Tcl_Eof, /* 126 */
+    Tcl_ErrnoId, /* 127 */
+    Tcl_ErrnoMsg, /* 128 */
+    Tcl_Eval, /* 129 */
+    Tcl_EvalFile, /* 130 */
+    Tcl_EvalObj, /* 131 */
+    Tcl_EventuallyFree, /* 132 */
+    Tcl_Exit, /* 133 */
+    Tcl_ExposeCommand, /* 134 */
+    Tcl_ExprBoolean, /* 135 */
+    Tcl_ExprBooleanObj, /* 136 */
+    Tcl_ExprDouble, /* 137 */
+    Tcl_ExprDoubleObj, /* 138 */
+    Tcl_ExprLong, /* 139 */
+    Tcl_ExprLongObj, /* 140 */
+    Tcl_ExprObj, /* 141 */
+    Tcl_ExprString, /* 142 */
+    Tcl_Finalize, /* 143 */
+    Tcl_FindExecutable, /* 144 */
+    Tcl_FirstHashEntry, /* 145 */
+    Tcl_Flush, /* 146 */
+    Tcl_FreeResult, /* 147 */
+    Tcl_GetAlias, /* 148 */
+    Tcl_GetAliasObj, /* 149 */
+    Tcl_GetAssocData, /* 150 */
+    Tcl_GetChannel, /* 151 */
+    Tcl_GetChannelBufferSize, /* 152 */
+    Tcl_GetChannelHandle, /* 153 */
+    Tcl_GetChannelInstanceData, /* 154 */
+    Tcl_GetChannelMode, /* 155 */
+    Tcl_GetChannelName, /* 156 */
+    Tcl_GetChannelOption, /* 157 */
+    Tcl_GetChannelType, /* 158 */
+    Tcl_GetCommandInfo, /* 159 */
+    Tcl_GetCommandName, /* 160 */
+    Tcl_GetErrno, /* 161 */
+    Tcl_GetHostName, /* 162 */
+    Tcl_GetInterpPath, /* 163 */
+    Tcl_GetMaster, /* 164 */
+    Tcl_GetNameOfExecutable, /* 165 */
+    Tcl_GetObjResult, /* 166 */
+#if !defined(_WIN32) && !defined(MAC_OSX_TCL) /* UNIX */
+    Tcl_GetOpenFile, /* 167 */
+#endif /* UNIX */
+#if defined(_WIN32) /* WIN */
+    0, /* 167 */
+#endif /* WIN */
+#ifdef MAC_OSX_TCL /* MACOSX */
+    Tcl_GetOpenFile, /* 167 */
+#endif /* MACOSX */
+    Tcl_GetPathType, /* 168 */
+    Tcl_Gets, /* 169 */
+    Tcl_GetsObj, /* 170 */
+    Tcl_GetServiceMode, /* 171 */
+    Tcl_GetSlave, /* 172 */
+    Tcl_GetStdChannel, /* 173 */
+    Tcl_GetStringResult, /* 174 */
+    Tcl_GetVar, /* 175 */
+    Tcl_GetVar2, /* 176 */
+    Tcl_GlobalEval, /* 177 */
+    Tcl_GlobalEvalObj, /* 178 */
+    Tcl_HideCommand, /* 179 */
+    Tcl_Init, /* 180 */
+    Tcl_InitHashTable, /* 181 */
+    Tcl_InputBlocked, /* 182 */
+    Tcl_InputBuffered, /* 183 */
+    Tcl_InterpDeleted, /* 184 */
+    Tcl_IsSafe, /* 185 */
+    Tcl_JoinPath, /* 186 */
+    Tcl_LinkVar, /* 187 */
+    0, /* 188 */
+    Tcl_MakeFileChannel, /* 189 */
+    Tcl_MakeSafe, /* 190 */
+    Tcl_MakeTcpClientChannel, /* 191 */
+    Tcl_Merge, /* 192 */
+    Tcl_NextHashEntry, /* 193 */
+    Tcl_NotifyChannel, /* 194 */
+    Tcl_ObjGetVar2, /* 195 */
+    Tcl_ObjSetVar2, /* 196 */
+    Tcl_OpenCommandChannel, /* 197 */
+    Tcl_OpenFileChannel, /* 198 */
+    Tcl_OpenTcpClient, /* 199 */
+    Tcl_OpenTcpServer, /* 200 */
+    Tcl_Preserve, /* 201 */
+    Tcl_PrintDouble, /* 202 */
+    Tcl_PutEnv, /* 203 */
+    Tcl_PosixError, /* 204 */
+    Tcl_QueueEvent, /* 205 */
+    Tcl_Read, /* 206 */
+    Tcl_ReapDetachedProcs, /* 207 */
+    Tcl_RecordAndEval, /* 208 */
+    Tcl_RecordAndEvalObj, /* 209 */
+    Tcl_RegisterChannel, /* 210 */
+    Tcl_RegisterObjType, /* 211 */
+    Tcl_RegExpCompile, /* 212 */
+    Tcl_RegExpExec, /* 213 */
+    Tcl_RegExpMatch, /* 214 */
+    Tcl_RegExpRange, /* 215 */
+    Tcl_Release, /* 216 */
+    Tcl_ResetResult, /* 217 */
+    Tcl_ScanElement, /* 218 */
+    Tcl_ScanCountedElement, /* 219 */
+    Tcl_SeekOld, /* 220 */
+    Tcl_ServiceAll, /* 221 */
+    Tcl_ServiceEvent, /* 222 */
+    Tcl_SetAssocData, /* 223 */
+    Tcl_SetChannelBufferSize, /* 224 */
+    Tcl_SetChannelOption, /* 225 */
+    Tcl_SetCommandInfo, /* 226 */
+    Tcl_SetErrno, /* 227 */
+    Tcl_SetErrorCode, /* 228 */
+    Tcl_SetMaxBlockTime, /* 229 */
+    Tcl_SetPanicProc, /* 230 */
+    Tcl_SetRecursionLimit, /* 231 */
+    Tcl_SetResult, /* 232 */
+    Tcl_SetServiceMode, /* 233 */
+    Tcl_SetObjErrorCode, /* 234 */
+    Tcl_SetObjResult, /* 235 */
+    Tcl_SetStdChannel, /* 236 */
+    Tcl_SetVar, /* 237 */
+    Tcl_SetVar2, /* 238 */
+    Tcl_SignalId, /* 239 */
+    Tcl_SignalMsg, /* 240 */
+    Tcl_SourceRCFile, /* 241 */
+    Tcl_SplitList, /* 242 */
+    Tcl_SplitPath, /* 243 */
+    Tcl_StaticPackage, /* 244 */
+    Tcl_StringMatch, /* 245 */
+    Tcl_TellOld, /* 246 */
+    Tcl_TraceVar, /* 247 */
+    Tcl_TraceVar2, /* 248 */
+    Tcl_TranslateFileName, /* 249 */
+    Tcl_Ungets, /* 250 */
+    Tcl_UnlinkVar, /* 251 */
+    Tcl_UnregisterChannel, /* 252 */
+    Tcl_UnsetVar, /* 253 */
+    Tcl_UnsetVar2, /* 254 */
+    Tcl_UntraceVar, /* 255 */
+    Tcl_UntraceVar2, /* 256 */
+    Tcl_UpdateLinkedVar, /* 257 */
+    Tcl_UpVar, /* 258 */
+    Tcl_UpVar2, /* 259 */
+    Tcl_VarEval, /* 260 */
+    Tcl_VarTraceInfo, /* 261 */
+    Tcl_VarTraceInfo2, /* 262 */
+    Tcl_Write, /* 263 */
+    Tcl_WrongNumArgs, /* 264 */
+    Tcl_DumpActiveMemory, /* 265 */
+    Tcl_ValidateAllMemory, /* 266 */
+    Tcl_AppendResultVA, /* 267 */
+    Tcl_AppendStringsToObjVA, /* 268 */
+    Tcl_HashStats, /* 269 */
+    Tcl_ParseVar, /* 270 */
+    Tcl_PkgPresent, /* 271 */
+    Tcl_PkgPresentEx, /* 272 */
+    Tcl_PkgProvide, /* 273 */
+    Tcl_PkgRequire, /* 274 */
+    Tcl_SetErrorCodeVA, /* 275 */
+    Tcl_VarEvalVA, /* 276 */
+    Tcl_WaitPid, /* 277 */
+    Tcl_PanicVA, /* 278 */
+    Tcl_GetVersion, /* 279 */
+    Tcl_InitMemory, /* 280 */
+    Tcl_StackChannel, /* 281 */
+    Tcl_UnstackChannel, /* 282 */
+    Tcl_GetStackedChannel, /* 283 */
+    Tcl_SetMainLoop, /* 284 */
+    0, /* 285 */
+    Tcl_AppendObjToObj, /* 286 */
+    Tcl_CreateEncoding, /* 287 */
+    Tcl_CreateThreadExitHandler, /* 288 */
+    Tcl_DeleteThreadExitHandler, /* 289 */
+    Tcl_DiscardResult, /* 290 */
+    Tcl_EvalEx, /* 291 */
+    Tcl_EvalObjv, /* 292 */
+    Tcl_EvalObjEx, /* 293 */
+    Tcl_ExitThread, /* 294 */
+    Tcl_ExternalToUtf, /* 295 */
+    Tcl_ExternalToUtfDString, /* 296 */
+    Tcl_FinalizeThread, /* 297 */
+    Tcl_FinalizeNotifier, /* 298 */
+    Tcl_FreeEncoding, /* 299 */
+    Tcl_GetCurrentThread, /* 300 */
+    Tcl_GetEncoding, /* 301 */
+    Tcl_GetEncodingName, /* 302 */
+    Tcl_GetEncodingNames, /* 303 */
+    Tcl_GetIndexFromObjStruct, /* 304 */
+    Tcl_GetThreadData, /* 305 */
+    Tcl_GetVar2Ex, /* 306 */
+    Tcl_InitNotifier, /* 307 */
+    Tcl_MutexLock, /* 308 */
+    Tcl_MutexUnlock, /* 309 */
+    Tcl_ConditionNotify, /* 310 */
+    Tcl_ConditionWait, /* 311 */
+    Tcl_NumUtfChars, /* 312 */
+    Tcl_ReadChars, /* 313 */
+    Tcl_RestoreResult, /* 314 */
+    Tcl_SaveResult, /* 315 */
+    Tcl_SetSystemEncoding, /* 316 */
+    Tcl_SetVar2Ex, /* 317 */
+    Tcl_ThreadAlert, /* 318 */
+    Tcl_ThreadQueueEvent, /* 319 */
+    Tcl_UniCharAtIndex, /* 320 */
+    Tcl_UniCharToLower, /* 321 */
+    Tcl_UniCharToTitle, /* 322 */
+    Tcl_UniCharToUpper, /* 323 */
+    Tcl_UniCharToUtf, /* 324 */
+    Tcl_UtfAtIndex, /* 325 */
+    Tcl_UtfCharComplete, /* 326 */
+    Tcl_UtfBackslash, /* 327 */
+    Tcl_UtfFindFirst, /* 328 */
+    Tcl_UtfFindLast, /* 329 */
+    Tcl_UtfNext, /* 330 */
+    Tcl_UtfPrev, /* 331 */
+    Tcl_UtfToExternal, /* 332 */
+    Tcl_UtfToExternalDString, /* 333 */
+    Tcl_UtfToLower, /* 334 */
+    Tcl_UtfToTitle, /* 335 */
+    Tcl_UtfToUniChar, /* 336 */
+    Tcl_UtfToUpper, /* 337 */
+    Tcl_WriteChars, /* 338 */
+    Tcl_WriteObj, /* 339 */
+    Tcl_GetString, /* 340 */
+    Tcl_GetDefaultEncodingDir, /* 341 */
+    Tcl_SetDefaultEncodingDir, /* 342 */
+    Tcl_AlertNotifier, /* 343 */
+    Tcl_ServiceModeHook, /* 344 */
+    Tcl_UniCharIsAlnum, /* 345 */
+    Tcl_UniCharIsAlpha, /* 346 */
+    Tcl_UniCharIsDigit, /* 347 */
+    Tcl_UniCharIsLower, /* 348 */
+    Tcl_UniCharIsSpace, /* 349 */
+    Tcl_UniCharIsUpper, /* 350 */
+    Tcl_UniCharIsWordChar, /* 351 */
+    Tcl_UniCharLen, /* 352 */
+    Tcl_UniCharNcmp, /* 353 */
+    Tcl_UniCharToUtfDString, /* 354 */
+    Tcl_UtfToUniCharDString, /* 355 */
+    Tcl_GetRegExpFromObj, /* 356 */
+    Tcl_EvalTokens, /* 357 */
+    Tcl_FreeParse, /* 358 */
+    Tcl_LogCommandInfo, /* 359 */
+    Tcl_ParseBraces, /* 360 */
+    Tcl_ParseCommand, /* 361 */
+    Tcl_ParseExpr, /* 362 */
+    Tcl_ParseQuotedString, /* 363 */
+    Tcl_ParseVarName, /* 364 */
+    Tcl_GetCwd, /* 365 */
+    Tcl_Chdir, /* 366 */
+    Tcl_Access, /* 367 */
+    Tcl_Stat, /* 368 */
+    Tcl_UtfNcmp, /* 369 */
+    Tcl_UtfNcasecmp, /* 370 */
+    Tcl_StringCaseMatch, /* 371 */
+    Tcl_UniCharIsControl, /* 372 */
+    Tcl_UniCharIsGraph, /* 373 */
+    Tcl_UniCharIsPrint, /* 374 */
+    Tcl_UniCharIsPunct, /* 375 */
+    Tcl_RegExpExecObj, /* 376 */
+    Tcl_RegExpGetInfo, /* 377 */
+    Tcl_NewUnicodeObj, /* 378 */
+    Tcl_SetUnicodeObj, /* 379 */
+    Tcl_GetCharLength, /* 380 */
+    Tcl_GetUniChar, /* 381 */
+    Tcl_GetUnicode, /* 382 */
+    Tcl_GetRange, /* 383 */
+    Tcl_AppendUnicodeToObj, /* 384 */
+    Tcl_RegExpMatchObj, /* 385 */
+    Tcl_SetNotifier, /* 386 */
+    Tcl_GetAllocMutex, /* 387 */
+    Tcl_GetChannelNames, /* 388 */
+    Tcl_GetChannelNamesEx, /* 389 */
+    Tcl_ProcObjCmd, /* 390 */
+    Tcl_ConditionFinalize, /* 391 */
+    Tcl_MutexFinalize, /* 392 */
+    Tcl_CreateThread, /* 393 */
+    Tcl_ReadRaw, /* 394 */
+    Tcl_WriteRaw, /* 395 */
+    Tcl_GetTopChannel, /* 396 */
+    Tcl_ChannelBuffered, /* 397 */
+    Tcl_ChannelName, /* 398 */
+    Tcl_ChannelVersion, /* 399 */
+    Tcl_ChannelBlockModeProc, /* 400 */
+    Tcl_ChannelCloseProc, /* 401 */
+    Tcl_ChannelClose2Proc, /* 402 */
+    Tcl_ChannelInputProc, /* 403 */
+    Tcl_ChannelOutputProc, /* 404 */
+    Tcl_ChannelSeekProc, /* 405 */
+    Tcl_ChannelSetOptionProc, /* 406 */
+    Tcl_ChannelGetOptionProc, /* 407 */
+    Tcl_ChannelWatchProc, /* 408 */
+    Tcl_ChannelGetHandleProc, /* 409 */
+    Tcl_ChannelFlushProc, /* 410 */
+    Tcl_ChannelHandlerProc, /* 411 */
+    Tcl_JoinThread, /* 412 */
+    Tcl_IsChannelShared, /* 413 */
+    Tcl_IsChannelRegistered, /* 414 */
+    Tcl_CutChannel, /* 415 */
+    Tcl_SpliceChannel, /* 416 */
+    Tcl_ClearChannelHandlers, /* 417 */
+    Tcl_IsChannelExisting, /* 418 */
+    Tcl_UniCharNcasecmp, /* 419 */
+    Tcl_UniCharCaseMatch, /* 420 */
+    Tcl_FindHashEntry, /* 421 */
+    Tcl_CreateHashEntry, /* 422 */
+    Tcl_InitCustomHashTable, /* 423 */
+    Tcl_InitObjHashTable, /* 424 */
+    Tcl_CommandTraceInfo, /* 425 */
+    Tcl_TraceCommand, /* 426 */
+    Tcl_UntraceCommand, /* 427 */
+    Tcl_AttemptAlloc, /* 428 */
+    Tcl_AttemptDbCkalloc, /* 429 */
+    Tcl_AttemptRealloc, /* 430 */
+    Tcl_AttemptDbCkrealloc, /* 431 */
+    Tcl_AttemptSetObjLength, /* 432 */
+    Tcl_GetChannelThread, /* 433 */
+    Tcl_GetUnicodeFromObj, /* 434 */
+    Tcl_GetMathFuncInfo, /* 435 */
+    Tcl_ListMathFuncs, /* 436 */
+    Tcl_SubstObj, /* 437 */
+    Tcl_DetachChannel, /* 438 */
+    Tcl_IsStandardChannel, /* 439 */
+    Tcl_FSCopyFile, /* 440 */
+    Tcl_FSCopyDirectory, /* 441 */
+    Tcl_FSCreateDirectory, /* 442 */
+    Tcl_FSDeleteFile, /* 443 */
+    Tcl_FSLoadFile, /* 444 */
+    Tcl_FSMatchInDirectory, /* 445 */
+    Tcl_FSLink, /* 446 */
+    Tcl_FSRemoveDirectory, /* 447 */
+    Tcl_FSRenameFile, /* 448 */
+    Tcl_FSLstat, /* 449 */
+    Tcl_FSUtime, /* 450 */
+    Tcl_FSFileAttrsGet, /* 451 */
+    Tcl_FSFileAttrsSet, /* 452 */
+    Tcl_FSFileAttrStrings, /* 453 */
+    Tcl_FSStat, /* 454 */
+    Tcl_FSAccess, /* 455 */
+    Tcl_FSOpenFileChannel, /* 456 */
+    Tcl_FSGetCwd, /* 457 */
+    Tcl_FSChdir, /* 458 */
+    Tcl_FSConvertToPathType, /* 459 */
+    Tcl_FSJoinPath, /* 460 */
+    Tcl_FSSplitPath, /* 461 */
+    Tcl_FSEqualPaths, /* 462 */
+    Tcl_FSGetNormalizedPath, /* 463 */
+    Tcl_FSJoinToPath, /* 464 */
+    Tcl_FSGetInternalRep, /* 465 */
+    Tcl_FSGetTranslatedPath, /* 466 */
+    Tcl_FSEvalFile, /* 467 */
+    Tcl_FSNewNativePath, /* 468 */
+    Tcl_FSGetNativePath, /* 469 */
+    Tcl_FSFileSystemInfo, /* 470 */
+    Tcl_FSPathSeparator, /* 471 */
+    Tcl_FSListVolumes, /* 472 */
+    Tcl_FSRegister, /* 473 */
+    Tcl_FSUnregister, /* 474 */
+    Tcl_FSData, /* 475 */
+    Tcl_FSGetTranslatedStringPath, /* 476 */
+    Tcl_FSGetFileSystemForPath, /* 477 */
+    Tcl_FSGetPathType, /* 478 */
+    Tcl_OutputBuffered, /* 479 */
+    Tcl_FSMountsChanged, /* 480 */
+    Tcl_EvalTokensStandard, /* 481 */
+    Tcl_GetTime, /* 482 */
+    Tcl_CreateObjTrace, /* 483 */
+    Tcl_GetCommandInfoFromToken, /* 484 */
+    Tcl_SetCommandInfoFromToken, /* 485 */
+    Tcl_DbNewWideIntObj, /* 486 */
+    Tcl_GetWideIntFromObj, /* 487 */
+    Tcl_NewWideIntObj, /* 488 */
+    Tcl_SetWideIntObj, /* 489 */
+    Tcl_AllocStatBuf, /* 490 */
+    Tcl_Seek, /* 491 */
+    Tcl_Tell, /* 492 */
+    Tcl_ChannelWideSeekProc, /* 493 */
+    Tcl_DictObjPut, /* 494 */
+    Tcl_DictObjGet, /* 495 */
+    Tcl_DictObjRemove, /* 496 */
+    Tcl_DictObjSize, /* 497 */
+    Tcl_DictObjFirst, /* 498 */
+    Tcl_DictObjNext, /* 499 */
+    Tcl_DictObjDone, /* 500 */
+    Tcl_DictObjPutKeyList, /* 501 */
+    Tcl_DictObjRemoveKeyList, /* 502 */
+    Tcl_NewDictObj, /* 503 */
+    Tcl_DbNewDictObj, /* 504 */
+    Tcl_RegisterConfig, /* 505 */
+    Tcl_CreateNamespace, /* 506 */
+    Tcl_DeleteNamespace, /* 507 */
+    Tcl_AppendExportList, /* 508 */
+    Tcl_Export, /* 509 */
+    Tcl_Import, /* 510 */
+    Tcl_ForgetImport, /* 511 */
+    Tcl_GetCurrentNamespace, /* 512 */
+    Tcl_GetGlobalNamespace, /* 513 */
+    Tcl_FindNamespace, /* 514 */
+    Tcl_FindCommand, /* 515 */
+    Tcl_GetCommandFromObj, /* 516 */
+    Tcl_GetCommandFullName, /* 517 */
+    Tcl_FSEvalFileEx, /* 518 */
+    Tcl_SetExitProc, /* 519 */
+    Tcl_LimitAddHandler, /* 520 */
+    Tcl_LimitRemoveHandler, /* 521 */
+    Tcl_LimitReady, /* 522 */
+    Tcl_LimitCheck, /* 523 */
+    Tcl_LimitExceeded, /* 524 */
+    Tcl_LimitSetCommands, /* 525 */
+    Tcl_LimitSetTime, /* 526 */
+    Tcl_LimitSetGranularity, /* 527 */
+    Tcl_LimitTypeEnabled, /* 528 */
+    Tcl_LimitTypeExceeded, /* 529 */
+    Tcl_LimitTypeSet, /* 530 */
+    Tcl_LimitTypeReset, /* 531 */
+    Tcl_LimitGetCommands, /* 532 */
+    Tcl_LimitGetTime, /* 533 */
+    Tcl_LimitGetGranularity, /* 534 */
+    Tcl_SaveInterpState, /* 535 */
+    Tcl_RestoreInterpState, /* 536 */
+    Tcl_DiscardInterpState, /* 537 */
+    Tcl_SetReturnOptions, /* 538 */
+    Tcl_GetReturnOptions, /* 539 */
+    Tcl_IsEnsemble, /* 540 */
+    Tcl_CreateEnsemble, /* 541 */
+    Tcl_FindEnsemble, /* 542 */
+    Tcl_SetEnsembleSubcommandList, /* 543 */
+    Tcl_SetEnsembleMappingDict, /* 544 */
+    Tcl_SetEnsembleUnknownHandler, /* 545 */
+    Tcl_SetEnsembleFlags, /* 546 */
+    Tcl_GetEnsembleSubcommandList, /* 547 */
+    Tcl_GetEnsembleMappingDict, /* 548 */
+    Tcl_GetEnsembleUnknownHandler, /* 549 */
+    Tcl_GetEnsembleFlags, /* 550 */
+    Tcl_GetEnsembleNamespace, /* 551 */
+    Tcl_SetTimeProc, /* 552 */
+    Tcl_QueryTimeProc, /* 553 */
+    Tcl_ChannelThreadActionProc, /* 554 */
+    Tcl_NewBignumObj, /* 555 */
+    Tcl_DbNewBignumObj, /* 556 */
+    Tcl_SetBignumObj, /* 557 */
+    Tcl_GetBignumFromObj, /* 558 */
+    Tcl_TakeBignumFromObj, /* 559 */
+    Tcl_TruncateChannel, /* 560 */
+    Tcl_ChannelTruncateProc, /* 561 */
+    Tcl_SetChannelErrorInterp, /* 562 */
+    Tcl_GetChannelErrorInterp, /* 563 */
+    Tcl_SetChannelError, /* 564 */
+    Tcl_GetChannelError, /* 565 */
+    Tcl_InitBignumFromDouble, /* 566 */
+    Tcl_GetNamespaceUnknownHandler, /* 567 */
+    Tcl_SetNamespaceUnknownHandler, /* 568 */
+    Tcl_GetEncodingFromObj, /* 569 */
+    Tcl_GetEncodingSearchPath, /* 570 */
+    Tcl_SetEncodingSearchPath, /* 571 */
+    Tcl_GetEncodingNameFromEnvironment, /* 572 */
+    Tcl_PkgRequireProc, /* 573 */
+    Tcl_AppendObjToErrorInfo, /* 574 */
+    Tcl_AppendLimitedToObj, /* 575 */
+    Tcl_Format, /* 576 */
+    Tcl_AppendFormatToObj, /* 577 */
+    Tcl_ObjPrintf, /* 578 */
+    Tcl_AppendPrintfToObj, /* 579 */
+    Tcl_CancelEval, /* 580 */
+    Tcl_Canceled, /* 581 */
+    Tcl_CreatePipe, /* 582 */
+    Tcl_NRCreateCommand, /* 583 */
+    Tcl_NREvalObj, /* 584 */
+    Tcl_NREvalObjv, /* 585 */
+    Tcl_NRCmdSwap, /* 586 */
+    Tcl_NRAddCallback, /* 587 */
+    Tcl_NRCallObjProc, /* 588 */
+    Tcl_GetFSDeviceFromStat, /* 589 */
+    Tcl_GetFSInodeFromStat, /* 590 */
+    Tcl_GetModeFromStat, /* 591 */
+    Tcl_GetLinkCountFromStat, /* 592 */
+    Tcl_GetUserIdFromStat, /* 593 */
+    Tcl_GetGroupIdFromStat, /* 594 */
+    Tcl_GetDeviceTypeFromStat, /* 595 */
+    Tcl_GetAccessTimeFromStat, /* 596 */
+    Tcl_GetModificationTimeFromStat, /* 597 */
+    Tcl_GetChangeTimeFromStat, /* 598 */
+    Tcl_GetSizeFromStat, /* 599 */
+    Tcl_GetBlocksFromStat, /* 600 */
+    Tcl_GetBlockSizeFromStat, /* 601 */
+    Tcl_SetEnsembleParameterList, /* 602 */
+    Tcl_GetEnsembleParameterList, /* 603 */
+    Tcl_ParseArgsObjv, /* 604 */
+    Tcl_GetErrorLine, /* 605 */
+    Tcl_SetErrorLine, /* 606 */
+    Tcl_TransferResult, /* 607 */
+    Tcl_InterpActive, /* 608 */
+    Tcl_BackgroundException, /* 609 */
+    Tcl_ZlibDeflate, /* 610 */
+    Tcl_ZlibInflate, /* 611 */
+    Tcl_ZlibCRC32, /* 612 */
+    Tcl_ZlibAdler32, /* 613 */
+    Tcl_ZlibStreamInit, /* 614 */
+    Tcl_ZlibStreamGetCommandName, /* 615 */
+    Tcl_ZlibStreamEof, /* 616 */
+    Tcl_ZlibStreamChecksum, /* 617 */
+    Tcl_ZlibStreamPut, /* 618 */
+    Tcl_ZlibStreamGet, /* 619 */
+    Tcl_ZlibStreamClose, /* 620 */
+    Tcl_ZlibStreamReset, /* 621 */
+    Tcl_SetStartupScript, /* 622 */
+    Tcl_GetStartupScript, /* 623 */
+    Tcl_CloseEx, /* 624 */
+    Tcl_NRExprObj, /* 625 */
+    Tcl_NRSubstObj, /* 626 */
+    Tcl_LoadFile, /* 627 */
+    Tcl_FindSymbol, /* 628 */
+    Tcl_FSUnloadFile, /* 629 */
+    Tcl_ZlibStreamSetCompressionDictionary, /* 630 */
+};
+
+/* !END!: Do not edit above this line. */
diff --git a/generic/tclStubLib.c b/generic/tclStubLib.c
new file mode 100644
index 0000000..859cbf9
--- /dev/null
+++ b/generic/tclStubLib.c
@@ -0,0 +1,127 @@
+/*
+ * tclStubLib.c --
+ *
+ *	Stub object that will be statically linked into extensions that want
+ *	to access Tcl.
+ *
+ * Copyright (c) 1998-1999 by Scriptics Corporation.
+ * Copyright (c) 1998 Paul Duffin.
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#include "tclInt.h"
+
+MODULE_SCOPE const TclStubs *tclStubsPtr;
+MODULE_SCOPE const TclPlatStubs *tclPlatStubsPtr;
+MODULE_SCOPE const TclIntStubs *tclIntStubsPtr;
+MODULE_SCOPE const TclIntPlatStubs *tclIntPlatStubsPtr;
+
+const TclStubs *tclStubsPtr = NULL;
+const TclPlatStubs *tclPlatStubsPtr = NULL;
+const TclIntStubs *tclIntStubsPtr = NULL;
+const TclIntPlatStubs *tclIntPlatStubsPtr = NULL;
+
+/*
+ * Use our own isDigit to avoid linking to libc on windows
+ */
+
+static int isDigit(const int c)
+{
+    return (c >= '0' && c <= '9');
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_InitStubs --
+ *
+ *	Tries to initialise the stub table pointers and ensures that the
+ *	correct version of Tcl is loaded.
+ *
+ * Results:
+ *	The actual version of Tcl that satisfies the request, or NULL to
+ *	indicate that an error occurred.
+ *
+ * Side effects:
+ *	Sets the stub table pointers.
+ *
+ *----------------------------------------------------------------------
+ */
+#undef Tcl_InitStubs
+MODULE_SCOPE const char *
+Tcl_InitStubs(
+    Tcl_Interp *interp,
+    const char *version,
+    int exact)
+{
+    Interp *iPtr = (Interp *) interp;
+    const char *actualVersion = NULL;
+    ClientData pkgData = NULL;
+    const TclStubs *stubsPtr = iPtr->stubTable;
+
+    /*
+     * We can't optimize this check by caching tclStubsPtr because that
+     * prevents apps from being able to load/unload Tcl dynamically multiple
+     * times. [Bug 615304]
+     */
+
+    if (!stubsPtr || (stubsPtr->magic != TCL_STUB_MAGIC)) {
+	iPtr->result = "interpreter uses an incompatible stubs mechanism";
+	iPtr->freeProc = TCL_STATIC;
+	return NULL;
+    }
+
+    actualVersion = stubsPtr->tcl_PkgRequireEx(interp, "Tcl", version, 0, &pkgData);
+    if (actualVersion == NULL) {
+	return NULL;
+    }
+    if (exact) {
+	const char *p = version;
+	int count = 0;
+
+	while (*p) {
+	    count += !isDigit(*p++);
+	}
+	if (count == 1) {
+	    const char *q = actualVersion;
+
+	    p = version;
+	    while (*p && (*p == *q)) {
+		p++; q++;
+	    }
+	    if (*p || isDigit(*q)) {
+		/* Construct error message */
+		stubsPtr->tcl_PkgRequireEx(interp, "Tcl", version, 1, NULL);
+		return NULL;
+	    }
+	} else {
+	    actualVersion = stubsPtr->tcl_PkgRequireEx(interp, "Tcl", version, 1, NULL);
+	    if (actualVersion == NULL) {
+		return NULL;
+	    }
+	}
+    }
+    tclStubsPtr = (TclStubs *)pkgData;
+
+    if (tclStubsPtr->hooks) {
+	tclPlatStubsPtr = tclStubsPtr->hooks->tclPlatStubs;
+	tclIntStubsPtr = tclStubsPtr->hooks->tclIntStubs;
+	tclIntPlatStubsPtr = tclStubsPtr->hooks->tclIntPlatStubs;
+    } else {
+	tclPlatStubsPtr = NULL;
+	tclIntStubsPtr = NULL;
+	tclIntPlatStubsPtr = NULL;
+    }
+
+    return actualVersion;
+}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tclStubLibTbl.c b/generic/tclStubLibTbl.c
new file mode 100644
index 0000000..0391502
--- /dev/null
+++ b/generic/tclStubLibTbl.c
@@ -0,0 +1,58 @@
+/*
+ * tclStubLibTbl.c --
+ *
+ *	Stub object that will be statically linked into extensions that want
+ *	to access Tcl.
+ *
+ * Copyright (c) 1998-1999 by Scriptics Corporation.
+ * Copyright (c) 1998 Paul Duffin.
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#include "tclInt.h"
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclInitStubTable --
+ *
+ *	Initialize the stub table, using the structure pointed at
+ *	by the "version" argument.
+ *
+ * Results:
+ *	Outputs the value of the "version" argument.
+ *
+ * Side effects:
+ *	Sets the stub table pointers.
+ *
+ *----------------------------------------------------------------------
+ */
+MODULE_SCOPE const char *
+TclInitStubTable(
+	const char *version) /* points to the version field of a
+	                        TclStubInfoType structure variable. */
+{
+    tclStubsPtr = ((const TclStubInfoType *) version)->stubs;
+
+    if (tclStubsPtr->hooks) {
+	tclPlatStubsPtr = tclStubsPtr->hooks->tclPlatStubs;
+	tclIntStubsPtr = tclStubsPtr->hooks->tclIntStubs;
+	tclIntPlatStubsPtr = tclStubsPtr->hooks->tclIntPlatStubs;
+    } else {
+	tclPlatStubsPtr = NULL;
+	tclIntStubsPtr = NULL;
+	tclIntPlatStubsPtr = NULL;
+    }
+
+    return version;
+}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tclTest.c b/generic/tclTest.c
new file mode 100644
index 0000000..e33d263
--- /dev/null
+++ b/generic/tclTest.c
@@ -0,0 +1,7483 @@
+/*
+ * tclTest.c --
+ *
+ *	This file contains C command functions for a bunch of additional Tcl
+ *	commands that are used for testing out Tcl's C interfaces. These
+ *	commands are not normally included in Tcl applications; they're only
+ *	used for testing.
+ *
+ * Copyright (c) 1993-1994 The Regents of the University of California.
+ * Copyright (c) 1994-1997 Sun Microsystems, Inc.
+ * Copyright (c) 1998-2000 Ajuba Solutions.
+ * Copyright (c) 2003 by Kevin B. Kenny.  All rights reserved.
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#undef STATIC_BUILD
+#ifndef USE_TCL_STUBS
+#   define USE_TCL_STUBS
+#endif
+#include "tclInt.h"
+#include "tclOO.h"
+#include <math.h>
+
+/*
+ * Required for Testregexp*Cmd
+ */
+#include "tclRegexp.h"
+
+/*
+ * Required for TestlocaleCmd
+ */
+#include <locale.h>
+
+/*
+ * Required for the TestChannelCmd and TestChannelEventCmd
+ */
+#include "tclIO.h"
+
+/*
+ * Declare external functions used in Windows tests.
+ */
+
+/*
+ * TCL_STORAGE_CLASS is set unconditionally to DLLEXPORT because the
+ * Tcltest_Init declaration is in the source file itself, which is only
+ * accessed when we are building a library.
+ */
+
+#undef TCL_STORAGE_CLASS
+#define TCL_STORAGE_CLASS DLLEXPORT
+EXTERN int		Tcltest_Init(Tcl_Interp *interp);
+EXTERN int		Tcltest_SafeInit(Tcl_Interp *interp);
+
+/*
+ * Dynamic string shared by TestdcallCmd and DelCallbackProc; used to collect
+ * the results of the various deletion callbacks.
+ */
+
+static Tcl_DString delString;
+static Tcl_Interp *delInterp;
+
+/*
+ * One of the following structures exists for each asynchronous handler
+ * created by the "testasync" command".
+ */
+
+typedef struct TestAsyncHandler {
+    int id;			/* Identifier for this handler. */
+    Tcl_AsyncHandler handler;	/* Tcl's token for the handler. */
+    char *command;		/* Command to invoke when the handler is
+				 * invoked. */
+    struct TestAsyncHandler *nextPtr;
+				/* Next is list of handlers. */
+} TestAsyncHandler;
+
+TCL_DECLARE_MUTEX(asyncTestMutex)
+
+static TestAsyncHandler *firstHandler = NULL;
+
+/*
+ * The dynamic string below is used by the "testdstring" command to test the
+ * dynamic string facilities.
+ */
+
+static Tcl_DString dstring;
+
+/*
+ * The command trace below is used by the "testcmdtraceCmd" command to test
+ * the command tracing facilities.
+ */
+
+static Tcl_Trace cmdTrace;
+
+/*
+ * One of the following structures exists for each command created by
+ * TestdelCmd:
+ */
+
+typedef struct DelCmd {
+    Tcl_Interp *interp;		/* Interpreter in which command exists. */
+    char *deleteCmd;		/* Script to execute when command is deleted.
+				 * Malloc'ed. */
+} DelCmd;
+
+/*
+ * The following is used to keep track of an encoding that invokes a Tcl
+ * command.
+ */
+
+typedef struct TclEncoding {
+    Tcl_Interp *interp;
+    char *toUtfCmd;
+    char *fromUtfCmd;
+} TclEncoding;
+
+/*
+ * The counter below is used to determine if the TestsaveresultFree routine
+ * was called for a result.
+ */
+
+static int freeCount;
+
+/*
+ * Boolean flag used by the "testsetmainloop" and "testexitmainloop" commands.
+ */
+
+static int exitMainLoop = 0;
+
+/*
+ * Event structure used in testing the event queue management procedures.
+ */
+
+typedef struct TestEvent {
+    Tcl_Event header;		/* Header common to all events */
+    Tcl_Interp *interp;		/* Interpreter that will handle the event */
+    Tcl_Obj *command;		/* Command to evaluate when the event occurs */
+    Tcl_Obj *tag;		/* Tag for this event used to delete it */
+} TestEvent;
+
+/*
+ * Simple detach/attach facility for testchannel cut|splice. Allow testing of
+ * channel transfer in core testsuite.
+ */
+
+typedef struct TestChannel {
+    Tcl_Channel chan;		/* Detached channel */
+    struct TestChannel *nextPtr;/* Next in detached channel pool */
+} TestChannel;
+
+static TestChannel *firstDetached;
+
+/*
+ * Forward declarations for procedures defined later in this file:
+ */
+
+static int		AsyncHandlerProc(ClientData clientData,
+			    Tcl_Interp *interp, int code);
+#ifdef TCL_THREADS
+static Tcl_ThreadCreateType AsyncThreadProc(ClientData);
+#endif
+static void		CleanupTestSetassocdataTests(
+			    ClientData clientData, Tcl_Interp *interp);
+static void		CmdDelProc1(ClientData clientData);
+static void		CmdDelProc2(ClientData clientData);
+static int		CmdProc1(ClientData clientData,
+			    Tcl_Interp *interp, int argc, const char **argv);
+static int		CmdProc2(ClientData clientData,
+			    Tcl_Interp *interp, int argc, const char **argv);
+static void		CmdTraceDeleteProc(
+			    ClientData clientData, Tcl_Interp *interp,
+			    int level, char *command, Tcl_CmdProc *cmdProc,
+			    ClientData cmdClientData, int argc,
+			    const char *argv[]);
+static void		CmdTraceProc(ClientData clientData,
+			    Tcl_Interp *interp, int level, char *command,
+			    Tcl_CmdProc *cmdProc, ClientData cmdClientData,
+			    int argc, const char *argv[]);
+static int		CreatedCommandProc(
+			    ClientData clientData, Tcl_Interp *interp,
+			    int argc, const char **argv);
+static int		CreatedCommandProc2(
+			    ClientData clientData, Tcl_Interp *interp,
+			    int argc, const char **argv);
+static void		DelCallbackProc(ClientData clientData,
+			    Tcl_Interp *interp);
+static int		DelCmdProc(ClientData clientData,
+			    Tcl_Interp *interp, int argc, const char **argv);
+static void		DelDeleteProc(ClientData clientData);
+static void		EncodingFreeProc(ClientData clientData);
+static int		EncodingToUtfProc(ClientData clientData,
+			    const char *src, int srcLen, int flags,
+			    Tcl_EncodingState *statePtr, char *dst,
+			    int dstLen, int *srcReadPtr, int *dstWrotePtr,
+			    int *dstCharsPtr);
+static int		EncodingFromUtfProc(ClientData clientData,
+			    const char *src, int srcLen, int flags,
+			    Tcl_EncodingState *statePtr, char *dst,
+			    int dstLen, int *srcReadPtr, int *dstWrotePtr,
+			    int *dstCharsPtr);
+static void		ExitProcEven(ClientData clientData);
+static void		ExitProcOdd(ClientData clientData);
+static int		GetTimesObjCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+static void		MainLoop(void);
+static int		NoopCmd(ClientData clientData,
+			    Tcl_Interp *interp, int argc, const char **argv);
+static int		NoopObjCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+static int		ObjTraceProc(ClientData clientData,
+			    Tcl_Interp *interp, int level, const char *command,
+			    Tcl_Command commandToken, int objc,
+			    Tcl_Obj *const objv[]);
+static void		ObjTraceDeleteProc(ClientData clientData);
+static void		PrintParse(Tcl_Interp *interp, Tcl_Parse *parsePtr);
+static void		SpecialFree(char *blockPtr);
+static int		StaticInitProc(Tcl_Interp *interp);
+static int		TestasyncCmd(ClientData dummy,
+			    Tcl_Interp *interp, int argc, const char **argv);
+static int		TestbytestringObjCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+static int		TestcmdinfoCmd(ClientData dummy,
+			    Tcl_Interp *interp, int argc, const char **argv);
+static int		TestcmdtokenCmd(ClientData dummy,
+			    Tcl_Interp *interp, int argc, const char **argv);
+static int		TestcmdtraceCmd(ClientData dummy,
+			    Tcl_Interp *interp, int argc, const char **argv);
+static int		TestconcatobjCmd(ClientData dummy,
+			    Tcl_Interp *interp, int argc, const char **argv);
+static int		TestcreatecommandCmd(ClientData dummy,
+			    Tcl_Interp *interp, int argc, const char **argv);
+static int		TestdcallCmd(ClientData dummy,
+			    Tcl_Interp *interp, int argc, const char **argv);
+static int		TestdelCmd(ClientData dummy,
+			    Tcl_Interp *interp, int argc, const char **argv);
+static int		TestdelassocdataCmd(ClientData dummy,
+			    Tcl_Interp *interp, int argc, const char **argv);
+static int		TestdoubledigitsObjCmd(ClientData dummy,
+					       Tcl_Interp* interp,
+					       int objc, Tcl_Obj* const objv[]);
+static int		TestdstringCmd(ClientData dummy,
+			    Tcl_Interp *interp, int argc, const char **argv);
+static int		TestencodingObjCmd(ClientData dummy,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+static int		TestevalexObjCmd(ClientData dummy,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+static int		TestevalobjvObjCmd(ClientData dummy,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+static int		TesteventObjCmd(ClientData unused,
+			    Tcl_Interp *interp, int argc,
+			    Tcl_Obj *const objv[]);
+static int		TesteventProc(Tcl_Event *event, int flags);
+static int		TesteventDeleteProc(Tcl_Event *event,
+			    ClientData clientData);
+static int		TestexithandlerCmd(ClientData dummy,
+			    Tcl_Interp *interp, int argc, const char **argv);
+static int		TestexprlongCmd(ClientData dummy,
+			    Tcl_Interp *interp, int argc, const char **argv);
+static int		TestexprlongobjCmd(ClientData dummy,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+static int		TestexprdoubleCmd(ClientData dummy,
+			    Tcl_Interp *interp, int argc, const char **argv);
+static int		TestexprdoubleobjCmd(ClientData dummy,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+static int		TestexprparserObjCmd(ClientData dummy,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+static int		TestexprstringCmd(ClientData dummy,
+			    Tcl_Interp *interp, int argc, const char **argv);
+static int		TestfileCmd(ClientData dummy,
+			    Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]);
+static int		TestfilelinkCmd(ClientData dummy,
+			    Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]);
+static int		TestfeventCmd(ClientData dummy,
+			    Tcl_Interp *interp, int argc, const char **argv);
+static int		TestgetassocdataCmd(ClientData dummy,
+			    Tcl_Interp *interp, int argc, const char **argv);
+static int		TestgetintCmd(ClientData dummy,
+			    Tcl_Interp *interp, int argc, const char **argv);
+static int		TestgetplatformCmd(ClientData dummy,
+			    Tcl_Interp *interp, int argc, const char **argv);
+static int		TestgetvarfullnameCmd(
+			    ClientData dummy, Tcl_Interp *interp,
+			    int objc, Tcl_Obj *const objv[]);
+static int		TestinterpdeleteCmd(ClientData dummy,
+			    Tcl_Interp *interp, int argc, const char **argv);
+static int		TestlinkCmd(ClientData dummy,
+			    Tcl_Interp *interp, int argc, const char **argv);
+static int		TestlocaleCmd(ClientData dummy,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+static int		TestMathFunc(ClientData clientData,
+			    Tcl_Interp *interp, Tcl_Value *args,
+			    Tcl_Value *resultPtr);
+static int		TestMathFunc2(ClientData clientData,
+			    Tcl_Interp *interp, Tcl_Value *args,
+			    Tcl_Value *resultPtr);
+static int		TestmainthreadCmd(ClientData dummy,
+			    Tcl_Interp *interp, int argc, const char **argv);
+static int		TestsetmainloopCmd(ClientData dummy,
+			    Tcl_Interp *interp, int argc, const char **argv);
+static int		TestexitmainloopCmd(ClientData dummy,
+			    Tcl_Interp *interp, int argc, const char **argv);
+static int		TestpanicCmd(ClientData dummy,
+			    Tcl_Interp *interp, int argc, const char **argv);
+static int		TestparseargsCmd(ClientData dummy, Tcl_Interp *interp,
+			    int objc, Tcl_Obj *const objv[]);
+static int		TestparserObjCmd(ClientData dummy,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+static int		TestparsevarObjCmd(ClientData dummy,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+static int		TestparsevarnameObjCmd(ClientData dummy,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+static int		TestregexpObjCmd(ClientData dummy,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+static int		TestreturnObjCmd(ClientData dummy,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+static void		TestregexpXflags(const char *string,
+			    int length, int *cflagsPtr, int *eflagsPtr);
+#ifndef TCL_NO_DEPRECATED
+static int		TestsaveresultCmd(ClientData dummy,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+static void		TestsaveresultFree(char *blockPtr);
+#endif /* TCL_NO_DEPRECATED */
+static int		TestsetassocdataCmd(ClientData dummy,
+			    Tcl_Interp *interp, int argc, const char **argv);
+static int		TestsetCmd(ClientData dummy,
+			    Tcl_Interp *interp, int argc, const char **argv);
+static int		Testset2Cmd(ClientData dummy,
+			    Tcl_Interp *interp, int argc, const char **argv);
+static int		TestseterrorcodeCmd(ClientData dummy,
+			    Tcl_Interp *interp, int argc, const char **argv);
+static int		TestsetobjerrorcodeCmd(
+			    ClientData dummy, Tcl_Interp *interp,
+			    int objc, Tcl_Obj *const objv[]);
+static int		TestsetplatformCmd(ClientData dummy,
+			    Tcl_Interp *interp, int argc, const char **argv);
+static int		TeststaticpkgCmd(ClientData dummy,
+			    Tcl_Interp *interp, int argc, const char **argv);
+static int		TesttranslatefilenameCmd(ClientData dummy,
+			    Tcl_Interp *interp, int argc, const char **argv);
+static int		TestupvarCmd(ClientData dummy,
+			    Tcl_Interp *interp, int argc, const char **argv);
+static int		TestWrongNumArgsObjCmd(
+			    ClientData clientData, Tcl_Interp *interp,
+			    int objc, Tcl_Obj *const objv[]);
+static int		TestGetIndexFromObjStructObjCmd(
+			    ClientData clientData, Tcl_Interp *interp,
+			    int objc, Tcl_Obj *const objv[]);
+static int		TestChannelCmd(ClientData clientData,
+			    Tcl_Interp *interp, int argc, const char **argv);
+static int		TestChannelEventCmd(ClientData clientData,
+			    Tcl_Interp *interp, int argc, const char **argv);
+static int		TestFilesystemObjCmd(ClientData dummy,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+static int		TestSimpleFilesystemObjCmd(
+			    ClientData dummy, Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+static void		TestReport(const char *cmd, Tcl_Obj *arg1,
+			    Tcl_Obj *arg2);
+static Tcl_Obj *	TestReportGetNativePath(Tcl_Obj *pathPtr);
+static Tcl_FSStatProc TestReportStat;
+static Tcl_FSAccessProc TestReportAccess;
+static Tcl_FSOpenFileChannelProc TestReportOpenFileChannel;
+static Tcl_FSMatchInDirectoryProc TestReportMatchInDirectory;
+static Tcl_FSChdirProc TestReportChdir;
+static Tcl_FSLstatProc TestReportLstat;
+static Tcl_FSCopyFileProc TestReportCopyFile;
+static Tcl_FSDeleteFileProc TestReportDeleteFile;
+static Tcl_FSRenameFileProc TestReportRenameFile;
+static Tcl_FSCreateDirectoryProc TestReportCreateDirectory;
+static Tcl_FSCopyDirectoryProc TestReportCopyDirectory;
+static Tcl_FSRemoveDirectoryProc TestReportRemoveDirectory;
+static int TestReportLoadFile(Tcl_Interp *interp, Tcl_Obj *pathPtr,
+	Tcl_LoadHandle *handlePtr, Tcl_FSUnloadFileProc **unloadProcPtr);
+static Tcl_FSLinkProc TestReportLink;
+static Tcl_FSFileAttrStringsProc TestReportFileAttrStrings;
+static Tcl_FSFileAttrsGetProc TestReportFileAttrsGet;
+static Tcl_FSFileAttrsSetProc TestReportFileAttrsSet;
+static Tcl_FSUtimeProc TestReportUtime;
+static Tcl_FSNormalizePathProc TestReportNormalizePath;
+static Tcl_FSPathInFilesystemProc TestReportInFilesystem;
+static Tcl_FSFreeInternalRepProc TestReportFreeInternalRep;
+static Tcl_FSDupInternalRepProc TestReportDupInternalRep;
+
+static Tcl_FSStatProc SimpleStat;
+static Tcl_FSAccessProc SimpleAccess;
+static Tcl_FSOpenFileChannelProc SimpleOpenFileChannel;
+static Tcl_FSListVolumesProc SimpleListVolumes;
+static Tcl_FSPathInFilesystemProc SimplePathInFilesystem;
+static Tcl_Obj *	SimpleRedirect(Tcl_Obj *pathPtr);
+static Tcl_FSMatchInDirectoryProc SimpleMatchInDirectory;
+static int		TestNumUtfCharsCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+static int		TestHashSystemHashCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+
+static Tcl_NRPostProc	NREUnwind_callback;
+static int		TestNREUnwind(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+static int		TestNRELevels(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+static int		TestInterpResolverCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+#if defined(HAVE_CPUID) || defined(_WIN32)
+static int		TestcpuidCmd(ClientData dummy,
+			    Tcl_Interp* interp, int objc,
+			    Tcl_Obj *const objv[]);
+#endif
+
+static const Tcl_Filesystem testReportingFilesystem = {
+    "reporting",
+    sizeof(Tcl_Filesystem),
+    TCL_FILESYSTEM_VERSION_1,
+    TestReportInFilesystem, /* path in */
+    TestReportDupInternalRep,
+    TestReportFreeInternalRep,
+    NULL, /* native to norm */
+    NULL, /* convert to native */
+    TestReportNormalizePath,
+    NULL, /* path type */
+    NULL, /* separator */
+    TestReportStat,
+    TestReportAccess,
+    TestReportOpenFileChannel,
+    TestReportMatchInDirectory,
+    TestReportUtime,
+    TestReportLink,
+    NULL /* list volumes */,
+    TestReportFileAttrStrings,
+    TestReportFileAttrsGet,
+    TestReportFileAttrsSet,
+    TestReportCreateDirectory,
+    TestReportRemoveDirectory,
+    TestReportDeleteFile,
+    TestReportCopyFile,
+    TestReportRenameFile,
+    TestReportCopyDirectory,
+    TestReportLstat,
+    (Tcl_FSLoadFileProc *) TestReportLoadFile,
+    NULL /* cwd */,
+    TestReportChdir
+};
+
+static const Tcl_Filesystem simpleFilesystem = {
+    "simple",
+    sizeof(Tcl_Filesystem),
+    TCL_FILESYSTEM_VERSION_1,
+    SimplePathInFilesystem,
+    NULL,
+    NULL,
+    /* No internal to normalized, since we don't create any
+     * pure 'internal' Tcl_Obj path representations */
+    NULL,
+    /* No create native rep function, since we don't use it
+     * or 'Tcl_FSNewNativePath' */
+    NULL,
+    /* Normalize path isn't needed - we assume paths only have
+     * one representation */
+    NULL,
+    NULL,
+    NULL,
+    SimpleStat,
+    SimpleAccess,
+    SimpleOpenFileChannel,
+    SimpleMatchInDirectory,
+    NULL,
+    /* We choose not to support symbolic links inside our vfs's */
+    NULL,
+    SimpleListVolumes,
+    NULL,
+    NULL,
+    NULL,
+    NULL,
+    NULL,
+    NULL,
+    /* No copy file - fallback will occur at Tcl level */
+    NULL,
+    /* No rename file - fallback will occur at Tcl level */
+    NULL,
+    /* No copy directory - fallback will occur at Tcl level */
+    NULL,
+    /* Use stat for lstat */
+    NULL,
+    /* No load - fallback on core implementation */
+    NULL,
+    /* We don't need a getcwd or chdir - fallback on Tcl's versions */
+    NULL,
+    NULL
+};
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcltest_Init --
+ *
+ *	This procedure performs application-specific initialization. Most
+ *	applications, especially those that incorporate additional packages,
+ *	will have their own version of this procedure.
+ *
+ * Results:
+ *	Returns a standard Tcl completion code, and leaves an error message in
+ *	the interp's result if an error occurs.
+ *
+ * Side effects:
+ *	Depends on the startup script.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcltest_Init(
+    Tcl_Interp *interp)		/* Interpreter for application. */
+{
+#ifndef TCL_NO_DEPRECATED
+    Tcl_ValueType t3ArgTypes[2];
+#endif /* TCL_NO_DEPRECATED */
+
+    Tcl_Obj *listPtr;
+    Tcl_Obj **objv;
+    int objc, index;
+    static const char *const specialOptions[] = {
+	"-appinitprocerror", "-appinitprocdeleteinterp",
+	"-appinitprocclosestderr", "-appinitprocsetrcfile", NULL
+    };
+
+    if (Tcl_InitStubs(interp, "8.5", 0) == NULL) {
+	return TCL_ERROR;
+    }
+    if (Tcl_TomMath_InitStubs(interp, "8.5") == NULL) {
+	return TCL_ERROR;
+    }
+    if (Tcl_OOInitStubs(interp) == NULL) {
+	return TCL_ERROR;
+    }
+    /* TIP #268: Full patchlevel instead of just major.minor */
+
+    if (Tcl_PkgProvide(interp, "Tcltest", TCL_PATCH_LEVEL) == TCL_ERROR) {
+	return TCL_ERROR;
+    }
+
+    /*
+     * Create additional commands and math functions for testing Tcl.
+     */
+
+    Tcl_CreateObjCommand(interp, "gettimes", GetTimesObjCmd, NULL, NULL);
+    Tcl_CreateCommand(interp, "noop", NoopCmd, NULL, NULL);
+    Tcl_CreateObjCommand(interp, "noop", NoopObjCmd, NULL, NULL);
+    Tcl_CreateObjCommand(interp, "testbytestring", TestbytestringObjCmd, NULL, NULL);
+    Tcl_CreateObjCommand(interp, "testwrongnumargs", TestWrongNumArgsObjCmd,
+	    NULL, NULL);
+    Tcl_CreateObjCommand(interp, "testfilesystem", TestFilesystemObjCmd,
+	    NULL, NULL);
+    Tcl_CreateObjCommand(interp, "testsimplefilesystem", TestSimpleFilesystemObjCmd,
+	    NULL, NULL);
+    Tcl_CreateObjCommand(interp, "testgetindexfromobjstruct",
+	    TestGetIndexFromObjStructObjCmd, NULL, NULL);
+    Tcl_CreateCommand(interp, "testasync", TestasyncCmd, NULL, NULL);
+    Tcl_CreateCommand(interp, "testchannel", TestChannelCmd,
+	    NULL, NULL);
+    Tcl_CreateCommand(interp, "testchannelevent", TestChannelEventCmd,
+	    NULL, NULL);
+    Tcl_CreateCommand(interp, "testcmdtoken", TestcmdtokenCmd, NULL,
+	    NULL);
+    Tcl_CreateCommand(interp, "testcmdinfo", TestcmdinfoCmd, NULL,
+	    NULL);
+    Tcl_CreateCommand(interp, "testcmdtrace", TestcmdtraceCmd,
+	    NULL, NULL);
+    Tcl_CreateCommand(interp, "testconcatobj", TestconcatobjCmd,
+	    NULL, NULL);
+    Tcl_CreateCommand(interp, "testcreatecommand", TestcreatecommandCmd,
+	    NULL, NULL);
+    Tcl_CreateCommand(interp, "testdcall", TestdcallCmd, NULL, NULL);
+    Tcl_CreateCommand(interp, "testdel", TestdelCmd, NULL, NULL);
+    Tcl_CreateCommand(interp, "testdelassocdata", TestdelassocdataCmd,
+	    NULL, NULL);
+    Tcl_CreateObjCommand(interp, "testdoubledigits", TestdoubledigitsObjCmd,
+			 NULL, NULL);
+    Tcl_DStringInit(&dstring);
+    Tcl_CreateCommand(interp, "testdstring", TestdstringCmd, NULL,
+	    NULL);
+    Tcl_CreateObjCommand(interp, "testencoding", TestencodingObjCmd, NULL,
+	    NULL);
+    Tcl_CreateObjCommand(interp, "testevalex", TestevalexObjCmd,
+	    NULL, NULL);
+    Tcl_CreateObjCommand(interp, "testevalobjv", TestevalobjvObjCmd,
+	    NULL, NULL);
+    Tcl_CreateObjCommand(interp, "testevent", TesteventObjCmd,
+	    NULL, NULL);
+    Tcl_CreateCommand(interp, "testexithandler", TestexithandlerCmd,
+	    NULL, NULL);
+    Tcl_CreateCommand(interp, "testexprlong", TestexprlongCmd,
+	    NULL, NULL);
+    Tcl_CreateObjCommand(interp, "testexprlongobj", TestexprlongobjCmd,
+	    NULL, NULL);
+    Tcl_CreateCommand(interp, "testexprdouble", TestexprdoubleCmd,
+	    NULL, NULL);
+    Tcl_CreateObjCommand(interp, "testexprdoubleobj", TestexprdoubleobjCmd,
+	    NULL, NULL);
+    Tcl_CreateObjCommand(interp, "testexprparser", TestexprparserObjCmd,
+	    NULL, NULL);
+    Tcl_CreateCommand(interp, "testexprstring", TestexprstringCmd,
+	    NULL, NULL);
+    Tcl_CreateCommand(interp, "testfevent", TestfeventCmd, NULL,
+	    NULL);
+    Tcl_CreateObjCommand(interp, "testfilelink", TestfilelinkCmd,
+	    NULL, NULL);
+    Tcl_CreateObjCommand(interp, "testfile", TestfileCmd,
+	    NULL, NULL);
+    Tcl_CreateObjCommand(interp, "testhashsystemhash",
+	    TestHashSystemHashCmd, NULL, NULL);
+    Tcl_CreateCommand(interp, "testgetassocdata", TestgetassocdataCmd,
+	    NULL, NULL);
+    Tcl_CreateCommand(interp, "testgetint", TestgetintCmd,
+	    NULL, NULL);
+    Tcl_CreateCommand(interp, "testgetplatform", TestgetplatformCmd,
+	    NULL, NULL);
+    Tcl_CreateObjCommand(interp, "testgetvarfullname",
+	    TestgetvarfullnameCmd, NULL, NULL);
+    Tcl_CreateCommand(interp, "testinterpdelete", TestinterpdeleteCmd,
+	    NULL, NULL);
+    Tcl_CreateCommand(interp, "testlink", TestlinkCmd, NULL, NULL);
+    Tcl_CreateObjCommand(interp, "testlocale", TestlocaleCmd, NULL,
+	    NULL);
+    Tcl_CreateCommand(interp, "testpanic", TestpanicCmd, NULL, NULL);
+    Tcl_CreateObjCommand(interp, "testparseargs", TestparseargsCmd,NULL,NULL);
+    Tcl_CreateObjCommand(interp, "testparser", TestparserObjCmd,
+	    NULL, NULL);
+    Tcl_CreateObjCommand(interp, "testparsevar", TestparsevarObjCmd,
+	    NULL, NULL);
+    Tcl_CreateObjCommand(interp, "testparsevarname", TestparsevarnameObjCmd,
+	    NULL, NULL);
+    Tcl_CreateObjCommand(interp, "testregexp", TestregexpObjCmd,
+	    NULL, NULL);
+    Tcl_CreateObjCommand(interp, "testreturn", TestreturnObjCmd,
+	    NULL, NULL);
+#ifndef TCL_NO_DEPRECATED
+    Tcl_CreateObjCommand(interp, "testsaveresult", TestsaveresultCmd,
+	    NULL, NULL);
+#endif /* TCL_NO_DEPRECATED */
+    Tcl_CreateCommand(interp, "testsetassocdata", TestsetassocdataCmd,
+	    NULL, NULL);
+    Tcl_CreateCommand(interp, "testsetnoerr", TestsetCmd,
+	    NULL, NULL);
+    Tcl_CreateCommand(interp, "testseterr", TestsetCmd,
+	    (ClientData) TCL_LEAVE_ERR_MSG, NULL);
+    Tcl_CreateCommand(interp, "testset2", Testset2Cmd,
+	    (ClientData) TCL_LEAVE_ERR_MSG, NULL);
+    Tcl_CreateCommand(interp, "testseterrorcode", TestseterrorcodeCmd,
+	    NULL, NULL);
+    Tcl_CreateObjCommand(interp, "testsetobjerrorcode",
+	    TestsetobjerrorcodeCmd, NULL, NULL);
+    Tcl_CreateObjCommand(interp, "testnumutfchars",
+	    TestNumUtfCharsCmd, NULL, NULL);
+    Tcl_CreateCommand(interp, "testsetplatform", TestsetplatformCmd,
+	    NULL, NULL);
+    Tcl_CreateCommand(interp, "teststaticpkg", TeststaticpkgCmd,
+	    NULL, NULL);
+    Tcl_CreateCommand(interp, "testtranslatefilename",
+	    TesttranslatefilenameCmd, NULL, NULL);
+    Tcl_CreateCommand(interp, "testupvar", TestupvarCmd, NULL, NULL);
+#ifndef TCL_NO_DEPRECATED
+    Tcl_CreateMathFunc(interp, "T1", 0, NULL, TestMathFunc, (ClientData) 123);
+    Tcl_CreateMathFunc(interp, "T2", 0, NULL, TestMathFunc, (ClientData) 345);
+#endif /* TCL_NO_DEPRECATED */
+    Tcl_CreateCommand(interp, "testmainthread", TestmainthreadCmd, NULL,
+	    NULL);
+    Tcl_CreateCommand(interp, "testsetmainloop", TestsetmainloopCmd,
+	    NULL, NULL);
+    Tcl_CreateCommand(interp, "testexitmainloop", TestexitmainloopCmd,
+	    NULL, NULL);
+#if defined(HAVE_CPUID) || defined(_WIN32)
+    Tcl_CreateObjCommand(interp, "testcpuid", TestcpuidCmd,
+	    (ClientData) 0, NULL);
+#endif
+#ifndef TCL_NO_DEPRECATED
+    t3ArgTypes[0] = TCL_EITHER;
+    t3ArgTypes[1] = TCL_EITHER;
+    Tcl_CreateMathFunc(interp, "T3", 2, t3ArgTypes, TestMathFunc2,
+	    NULL);
+#endif /* TCL_NO_DEPRECATED */
+
+    Tcl_CreateObjCommand(interp, "testnreunwind", TestNREUnwind,
+	    NULL, NULL);
+    Tcl_CreateObjCommand(interp, "testnrelevels", TestNRELevels,
+	    NULL, NULL);
+    Tcl_CreateObjCommand(interp, "testinterpresolver", TestInterpResolverCmd,
+	    NULL, NULL);
+
+    if (TclObjTest_Init(interp) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    if (Procbodytest_Init(interp) != TCL_OK) {
+	return TCL_ERROR;
+    }
+#ifdef TCL_THREADS
+    if (TclThread_Init(interp) != TCL_OK) {
+	return TCL_ERROR;
+    }
+#endif
+
+    /*
+     * Check for special options used in ../tests/main.test
+     */
+
+    listPtr = Tcl_GetVar2Ex(interp, "argv", NULL, TCL_GLOBAL_ONLY);
+    if (listPtr != NULL) {
+	if (Tcl_ListObjGetElements(interp, listPtr, &objc, &objv) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	if (objc && (Tcl_GetIndexFromObj(NULL, objv[0], specialOptions, NULL,
+		TCL_EXACT, &index) == TCL_OK)) {
+	    switch (index) {
+	    case 0:
+		return TCL_ERROR;
+	    case 1:
+		Tcl_DeleteInterp(interp);
+		return TCL_ERROR;
+	    case 2: {
+		int mode;
+		Tcl_UnregisterChannel(interp,
+			Tcl_GetChannel(interp, "stderr", &mode));
+		return TCL_ERROR;
+	    }
+	    case 3:
+		if (objc-1) {
+		    Tcl_SetVar2Ex(interp, "tcl_rcFileName", NULL, objv[1],
+			    TCL_GLOBAL_ONLY);
+		}
+		return TCL_ERROR;
+	    }
+	}
+    }
+
+    /*
+     * And finally add any platform specific test commands.
+     */
+
+    return TclplatformtestInit(interp);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcltest_SafeInit --
+ *
+ *	This procedure performs application-specific initialization. Most
+ *	applications, especially those that incorporate additional packages,
+ *	will have their own version of this procedure.
+ *
+ * Results:
+ *	Returns a standard Tcl completion code, and leaves an error message in
+ *	the interp's result if an error occurs.
+ *
+ * Side effects:
+ *	Depends on the startup script.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcltest_SafeInit(
+    Tcl_Interp *interp)		/* Interpreter for application. */
+{
+    if (Tcl_InitStubs(interp, "8.5", 0) == NULL) {
+	return TCL_ERROR;
+    }
+    return Procbodytest_SafeInit(interp);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TestasyncCmd --
+ *
+ *	This procedure implements the "testasync" command.  It is used
+ *	to test the asynchronous handler facilities of Tcl.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	Creates, deletes, and invokes handlers.
+ *
+ *----------------------------------------------------------------------
+ */
+
+	/* ARGSUSED */
+static int
+TestasyncCmd(
+    ClientData dummy,			/* Not used. */
+    Tcl_Interp *interp,			/* Current interpreter. */
+    int argc,				/* Number of arguments. */
+    const char **argv)			/* Argument strings. */
+{
+    TestAsyncHandler *asyncPtr, *prevPtr;
+    int id, code;
+    static int nextId = 1;
+
+    if (argc < 2) {
+	wrongNumArgs:
+	Tcl_SetResult(interp, "wrong # args", TCL_STATIC);
+	return TCL_ERROR;
+    }
+    if (strcmp(argv[1], "create") == 0) {
+	if (argc != 3) {
+	    goto wrongNumArgs;
+	}
+	asyncPtr = ckalloc(sizeof(TestAsyncHandler));
+	asyncPtr->command = ckalloc(strlen(argv[2]) + 1);
+	strcpy(asyncPtr->command, argv[2]);
+        Tcl_MutexLock(&asyncTestMutex);
+	asyncPtr->id = nextId;
+	nextId++;
+	asyncPtr->handler = Tcl_AsyncCreate(AsyncHandlerProc,
+                                            INT2PTR(asyncPtr->id));
+	asyncPtr->nextPtr = firstHandler;
+	firstHandler = asyncPtr;
+        Tcl_MutexUnlock(&asyncTestMutex);
+	Tcl_SetObjResult(interp, Tcl_NewIntObj(asyncPtr->id));
+    } else if (strcmp(argv[1], "delete") == 0) {
+	if (argc == 2) {
+            Tcl_MutexLock(&asyncTestMutex);
+	    while (firstHandler != NULL) {
+		asyncPtr = firstHandler;
+		firstHandler = asyncPtr->nextPtr;
+		Tcl_AsyncDelete(asyncPtr->handler);
+		ckfree(asyncPtr->command);
+		ckfree(asyncPtr);
+	    }
+            Tcl_MutexUnlock(&asyncTestMutex);
+	    return TCL_OK;
+	}
+	if (argc != 3) {
+	    goto wrongNumArgs;
+	}
+	if (Tcl_GetInt(interp, argv[2], &id) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+        Tcl_MutexLock(&asyncTestMutex);
+	for (prevPtr = NULL, asyncPtr = firstHandler; asyncPtr != NULL;
+		prevPtr = asyncPtr, asyncPtr = asyncPtr->nextPtr) {
+	    if (asyncPtr->id != id) {
+		continue;
+	    }
+	    if (prevPtr == NULL) {
+		firstHandler = asyncPtr->nextPtr;
+	    } else {
+		prevPtr->nextPtr = asyncPtr->nextPtr;
+	    }
+	    Tcl_AsyncDelete(asyncPtr->handler);
+	    ckfree(asyncPtr->command);
+	    ckfree(asyncPtr);
+	    break;
+	}
+        Tcl_MutexUnlock(&asyncTestMutex);
+    } else if (strcmp(argv[1], "mark") == 0) {
+	if (argc != 5) {
+	    goto wrongNumArgs;
+	}
+	if ((Tcl_GetInt(interp, argv[2], &id) != TCL_OK)
+		|| (Tcl_GetInt(interp, argv[4], &code) != TCL_OK)) {
+	    return TCL_ERROR;
+	}
+	Tcl_MutexLock(&asyncTestMutex);
+	for (asyncPtr = firstHandler; asyncPtr != NULL;
+		asyncPtr = asyncPtr->nextPtr) {
+	    if (asyncPtr->id == id) {
+		Tcl_AsyncMark(asyncPtr->handler);
+		break;
+	    }
+	}
+	Tcl_SetObjResult(interp, Tcl_NewStringObj(argv[3], -1));
+	Tcl_MutexUnlock(&asyncTestMutex);
+	return code;
+#ifdef TCL_THREADS
+    } else if (strcmp(argv[1], "marklater") == 0) {
+	if (argc != 3) {
+	    goto wrongNumArgs;
+	}
+	if (Tcl_GetInt(interp, argv[2], &id) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+        Tcl_MutexLock(&asyncTestMutex);
+	for (asyncPtr = firstHandler; asyncPtr != NULL;
+		asyncPtr = asyncPtr->nextPtr) {
+	    if (asyncPtr->id == id) {
+		Tcl_ThreadId threadID;
+		if (Tcl_CreateThread(&threadID, AsyncThreadProc,
+			INT2PTR(id), TCL_THREAD_STACK_DEFAULT,
+			TCL_THREAD_NOFLAGS) != TCL_OK) {
+		    Tcl_SetResult(interp, "can't create thread", TCL_STATIC);
+		    Tcl_MutexUnlock(&asyncTestMutex);
+		    return TCL_ERROR;
+		}
+		break;
+	    }
+	}
+        Tcl_MutexUnlock(&asyncTestMutex);
+    } else {
+	Tcl_AppendResult(interp, "bad option \"", argv[1],
+		"\": must be create, delete, int, mark, or marklater", NULL);
+	return TCL_ERROR;
+#else /* !TCL_THREADS */
+    } else {
+	Tcl_AppendResult(interp, "bad option \"", argv[1],
+		"\": must be create, delete, int, or mark", NULL);
+	return TCL_ERROR;
+#endif
+    }
+    return TCL_OK;
+}
+
+static int
+AsyncHandlerProc(
+    ClientData clientData,	/* If of TestAsyncHandler structure.
+                                 * in global list. */
+    Tcl_Interp *interp,		/* Interpreter in which command was
+				 * executed, or NULL. */
+    int code)			/* Current return code from command. */
+{
+    TestAsyncHandler *asyncPtr;
+    int id = PTR2INT(clientData);
+    const char *listArgv[4], *cmd;
+    char string[TCL_INTEGER_SPACE];
+
+    Tcl_MutexLock(&asyncTestMutex);
+    for (asyncPtr = firstHandler; asyncPtr != NULL;
+         asyncPtr = asyncPtr->nextPtr) {
+        if (asyncPtr->id == id) break;
+    }
+    Tcl_MutexUnlock(&asyncTestMutex);
+
+    if (!asyncPtr) {
+        /* Woops - this one was deleted between the AsyncMark and now */
+        return TCL_OK;
+    }
+
+    TclFormatInt(string, code);
+    listArgv[0] = asyncPtr->command;
+    listArgv[1] = Tcl_GetString(Tcl_GetObjResult(interp));
+    listArgv[2] = string;
+    listArgv[3] = NULL;
+    cmd = Tcl_Merge(3, listArgv);
+    if (interp != NULL) {
+	code = Tcl_EvalEx(interp, cmd, -1, 0);
+    } else {
+	/*
+	 * this should not happen, but by definition of how async handlers are
+	 * invoked, it's possible.  Better error checking is needed here.
+	 */
+    }
+    ckfree(cmd);
+    return code;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * AsyncThreadProc --
+ *
+ *	Delivers an asynchronous event to a handler in another thread.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Invokes Tcl_AsyncMark on the handler
+ *
+ *----------------------------------------------------------------------
+ */
+
+#ifdef TCL_THREADS
+static Tcl_ThreadCreateType
+AsyncThreadProc(
+    ClientData clientData)	/* Parameter is the id of a
+				 * TestAsyncHandler, defined above. */
+{
+    TestAsyncHandler *asyncPtr;
+    int id = PTR2INT(clientData);
+
+    Tcl_Sleep(1);
+    Tcl_MutexLock(&asyncTestMutex);
+    for (asyncPtr = firstHandler; asyncPtr != NULL;
+         asyncPtr = asyncPtr->nextPtr) {
+        if (asyncPtr->id == id) {
+            Tcl_AsyncMark(asyncPtr->handler);
+            break;
+        }
+    }
+    Tcl_MutexUnlock(&asyncTestMutex);
+    Tcl_ExitThread(TCL_OK);
+    TCL_THREAD_CREATE_RETURN;
+}
+#endif
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TestcmdinfoCmd --
+ *
+ *	This procedure implements the "testcmdinfo" command.  It is used to
+ *	test Tcl_GetCommandInfo, Tcl_SetCommandInfo, and command creation and
+ *	deletion.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	Creates and deletes various commands and modifies their data.
+ *
+ *----------------------------------------------------------------------
+ */
+
+	/* ARGSUSED */
+static int
+TestcmdinfoCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int argc,			/* Number of arguments. */
+    const char **argv)		/* Argument strings. */
+{
+    Tcl_CmdInfo info;
+
+    if (argc != 3) {
+	Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
+		" option cmdName\"", NULL);
+	return TCL_ERROR;
+    }
+    if (strcmp(argv[1], "create") == 0) {
+	Tcl_CreateCommand(interp, argv[2], CmdProc1, (ClientData) "original",
+		CmdDelProc1);
+    } else if (strcmp(argv[1], "delete") == 0) {
+	Tcl_DStringInit(&delString);
+	Tcl_DeleteCommand(interp, argv[2]);
+	Tcl_DStringResult(interp, &delString);
+    } else if (strcmp(argv[1], "get") == 0) {
+	if (Tcl_GetCommandInfo(interp, argv[2], &info) ==0) {
+	    Tcl_SetResult(interp, "??", TCL_STATIC);
+	    return TCL_OK;
+	}
+	if (info.proc == CmdProc1) {
+	    Tcl_AppendResult(interp, "CmdProc1", " ",
+		    (char *) info.clientData, NULL);
+	} else if (info.proc == CmdProc2) {
+	    Tcl_AppendResult(interp, "CmdProc2", " ",
+		    (char *) info.clientData, NULL);
+	} else {
+	    Tcl_AppendResult(interp, "unknown", NULL);
+	}
+	if (info.deleteProc == CmdDelProc1) {
+	    Tcl_AppendResult(interp, " CmdDelProc1", " ",
+		    (char *) info.deleteData, NULL);
+	} else if (info.deleteProc == CmdDelProc2) {
+	    Tcl_AppendResult(interp, " CmdDelProc2", " ",
+		    (char *) info.deleteData, NULL);
+	} else {
+	    Tcl_AppendResult(interp, " unknown", NULL);
+	}
+	Tcl_AppendResult(interp, " ", info.namespacePtr->fullName, NULL);
+	if (info.isNativeObjectProc) {
+	    Tcl_AppendResult(interp, " nativeObjectProc", NULL);
+	} else {
+	    Tcl_AppendResult(interp, " stringProc", NULL);
+	}
+    } else if (strcmp(argv[1], "modify") == 0) {
+	info.proc = CmdProc2;
+	info.clientData = (ClientData) "new_command_data";
+	info.objProc = NULL;
+	info.objClientData = NULL;
+	info.deleteProc = CmdDelProc2;
+	info.deleteData = (ClientData) "new_delete_data";
+	if (Tcl_SetCommandInfo(interp, argv[2], &info) == 0) {
+	    Tcl_SetObjResult(interp, Tcl_NewIntObj(0));
+	} else {
+	    Tcl_SetObjResult(interp, Tcl_NewIntObj(1));
+	}
+    } else {
+	Tcl_AppendResult(interp, "bad option \"", argv[1],
+		"\": must be create, delete, get, or modify", NULL);
+	return TCL_ERROR;
+    }
+    return TCL_OK;
+}
+
+	/*ARGSUSED*/
+static int
+CmdProc1(
+    ClientData clientData,	/* String to return. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int argc,			/* Number of arguments. */
+    const char **argv)		/* Argument strings. */
+{
+    Tcl_AppendResult(interp, "CmdProc1 ", (char *) clientData, NULL);
+    return TCL_OK;
+}
+
+	/*ARGSUSED*/
+static int
+CmdProc2(
+    ClientData clientData,	/* String to return. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int argc,			/* Number of arguments. */
+    const char **argv)		/* Argument strings. */
+{
+    Tcl_AppendResult(interp, "CmdProc2 ", (char *) clientData, NULL);
+    return TCL_OK;
+}
+
+static void
+CmdDelProc1(
+    ClientData clientData)	/* String to save. */
+{
+    Tcl_DStringInit(&delString);
+    Tcl_DStringAppend(&delString, "CmdDelProc1 ", -1);
+    Tcl_DStringAppend(&delString, (char *) clientData, -1);
+}
+
+static void
+CmdDelProc2(
+    ClientData clientData)	/* String to save. */
+{
+    Tcl_DStringInit(&delString);
+    Tcl_DStringAppend(&delString, "CmdDelProc2 ", -1);
+    Tcl_DStringAppend(&delString, (char *) clientData, -1);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TestcmdtokenCmd --
+ *
+ *	This procedure implements the "testcmdtoken" command. It is used to
+ *	test Tcl_Command tokens and procedures such as Tcl_GetCommandFullName.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	Creates and deletes various commands and modifies their data.
+ *
+ *----------------------------------------------------------------------
+ */
+
+	/* ARGSUSED */
+static int
+TestcmdtokenCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int argc,			/* Number of arguments. */
+    const char **argv)		/* Argument strings. */
+{
+    Tcl_Command token;
+    int *l;
+    char buf[30];
+
+    if (argc != 3) {
+	Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
+		" option arg\"", NULL);
+	return TCL_ERROR;
+    }
+    if (strcmp(argv[1], "create") == 0) {
+	token = Tcl_CreateCommand(interp, argv[2], CmdProc1,
+		(ClientData) "original", NULL);
+	sprintf(buf, "%p", (void *)token);
+	Tcl_SetResult(interp, buf, TCL_VOLATILE);
+    } else if (strcmp(argv[1], "name") == 0) {
+	Tcl_Obj *objPtr;
+
+	if (sscanf(argv[2], "%p", &l) != 1) {
+	    Tcl_AppendResult(interp, "bad command token \"", argv[2],
+		    "\"", NULL);
+	    return TCL_ERROR;
+	}
+
+	objPtr = Tcl_NewObj();
+	Tcl_GetCommandFullName(interp, (Tcl_Command) l, objPtr);
+
+	Tcl_AppendElement(interp,
+		Tcl_GetCommandName(interp, (Tcl_Command) l));
+	Tcl_AppendElement(interp, Tcl_GetString(objPtr));
+	Tcl_DecrRefCount(objPtr);
+    } else {
+	Tcl_AppendResult(interp, "bad option \"", argv[1],
+		"\": must be create or name", NULL);
+	return TCL_ERROR;
+    }
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TestcmdtraceCmd --
+ *
+ *	This procedure implements the "testcmdtrace" command. It is used
+ *	to test Tcl_CreateTrace and Tcl_DeleteTrace.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	Creates and deletes a command trace, and tests the invocation of
+ *	a procedure by the command trace.
+ *
+ *----------------------------------------------------------------------
+ */
+
+	/* ARGSUSED */
+static int
+TestcmdtraceCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int argc,			/* Number of arguments. */
+    const char **argv)		/* Argument strings. */
+{
+    Tcl_DString buffer;
+    int result;
+
+    if (argc != 3) {
+	Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
+		" option script\"", NULL);
+	return TCL_ERROR;
+    }
+
+    if (strcmp(argv[1], "tracetest") == 0) {
+	Tcl_DStringInit(&buffer);
+	cmdTrace = Tcl_CreateTrace(interp, 50000, CmdTraceProc, &buffer);
+	result = Tcl_EvalEx(interp, argv[2], -1, 0);
+	if (result == TCL_OK) {
+	    Tcl_ResetResult(interp);
+	    Tcl_AppendResult(interp, Tcl_DStringValue(&buffer), NULL);
+	}
+	Tcl_DeleteTrace(interp, cmdTrace);
+	Tcl_DStringFree(&buffer);
+    } else if (strcmp(argv[1], "deletetest") == 0) {
+	/*
+	 * Create a command trace then eval a script to check whether it is
+	 * called. Note that this trace procedure removes itself as a further
+	 * check of the robustness of the trace proc calling code in
+	 * TclNRExecuteByteCode.
+	 */
+
+	cmdTrace = Tcl_CreateTrace(interp, 50000, CmdTraceDeleteProc, NULL);
+	Tcl_EvalEx(interp, argv[2], -1, 0);
+    } else if (strcmp(argv[1], "leveltest") == 0) {
+	Interp *iPtr = (Interp *) interp;
+	Tcl_DStringInit(&buffer);
+	cmdTrace = Tcl_CreateTrace(interp, iPtr->numLevels + 4, CmdTraceProc,
+		&buffer);
+	result = Tcl_EvalEx(interp, argv[2], -1, 0);
+	if (result == TCL_OK) {
+	    Tcl_ResetResult(interp);
+	    Tcl_AppendResult(interp, Tcl_DStringValue(&buffer), NULL);
+	}
+	Tcl_DeleteTrace(interp, cmdTrace);
+	Tcl_DStringFree(&buffer);
+    } else if (strcmp(argv[1], "resulttest") == 0) {
+	/* Create an object-based trace, then eval a script. This is used
+	 * to test return codes other than TCL_OK from the trace engine.
+	 */
+
+	static int deleteCalled;
+
+	deleteCalled = 0;
+	cmdTrace = Tcl_CreateObjTrace(interp, 50000,
+		TCL_ALLOW_INLINE_COMPILATION, ObjTraceProc,
+		(ClientData) &deleteCalled, ObjTraceDeleteProc);
+	result = Tcl_Eval(interp, argv[2]);
+	Tcl_DeleteTrace(interp, cmdTrace);
+	if (!deleteCalled) {
+	    Tcl_SetResult(interp, "Delete wasn't called", TCL_STATIC);
+	    return TCL_ERROR;
+	} else {
+	    return result;
+	}
+    } else if (strcmp(argv[1], "doubletest") == 0) {
+	Tcl_Trace t1, t2;
+
+	Tcl_DStringInit(&buffer);
+	t1 = Tcl_CreateTrace(interp, 1, CmdTraceProc, &buffer);
+	t2 = Tcl_CreateTrace(interp, 50000, CmdTraceProc, &buffer);
+	result = Tcl_Eval(interp, argv[2]);
+	if (result == TCL_OK) {
+	    Tcl_ResetResult(interp);
+	    Tcl_AppendResult(interp, Tcl_DStringValue(&buffer), NULL);
+	}
+	Tcl_DeleteTrace(interp, t2);
+	Tcl_DeleteTrace(interp, t1);
+	Tcl_DStringFree(&buffer);
+    } else {
+	Tcl_AppendResult(interp, "bad option \"", argv[1],
+		"\": must be tracetest, deletetest, doubletest or resulttest", NULL);
+	return TCL_ERROR;
+    }
+    return TCL_OK;
+}
+
+static void
+CmdTraceProc(
+    ClientData clientData,	/* Pointer to buffer in which the
+				 * command and arguments are appended.
+				 * Accumulates test result. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int level,			/* Current trace level. */
+    char *command,		/* The command being traced (after
+				 * substitutions). */
+    Tcl_CmdProc *cmdProc,	/* Points to command's command procedure. */
+    ClientData cmdClientData,	/* Client data associated with command
+				 * procedure. */
+    int argc,			/* Number of arguments. */
+    const char *argv[])		/* Argument strings. */
+{
+    Tcl_DString *bufPtr = (Tcl_DString *) clientData;
+    int i;
+
+    Tcl_DStringAppendElement(bufPtr, command);
+
+    Tcl_DStringStartSublist(bufPtr);
+    for (i = 0;  i < argc;  i++) {
+	Tcl_DStringAppendElement(bufPtr, argv[i]);
+    }
+    Tcl_DStringEndSublist(bufPtr);
+}
+
+static void
+CmdTraceDeleteProc(
+    ClientData clientData,	/* Unused. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int level,			/* Current trace level. */
+    char *command,		/* The command being traced (after
+				 * substitutions). */
+    Tcl_CmdProc *cmdProc,	/* Points to command's command procedure. */
+    ClientData cmdClientData,	/* Client data associated with command
+				 * procedure. */
+    int argc,			/* Number of arguments. */
+    const char *argv[])		/* Argument strings. */
+{
+    /*
+     * Remove ourselves to test whether calling Tcl_DeleteTrace within a trace
+     * callback causes the for loop in TclNRExecuteByteCode that calls traces to
+     * reference freed memory.
+     */
+
+    Tcl_DeleteTrace(interp, cmdTrace);
+}
+
+static int
+ObjTraceProc(
+    ClientData clientData,	/* unused */
+    Tcl_Interp *interp,		/* Tcl interpreter */
+    int level,			/* Execution level */
+    const char *command,	/* Command being executed */
+    Tcl_Command token,		/* Command information */
+    int objc,			/* Parameter count */
+    Tcl_Obj *const objv[])	/* Parameter list */
+{
+    const char *word = Tcl_GetString(objv[0]);
+
+    if (!strcmp(word, "Error")) {
+	Tcl_SetObjResult(interp, Tcl_NewStringObj(command, -1));
+	return TCL_ERROR;
+    } else if (!strcmp(word, "Break")) {
+	return TCL_BREAK;
+    } else if (!strcmp(word, "Continue")) {
+	return TCL_CONTINUE;
+    } else if (!strcmp(word, "Return")) {
+	return TCL_RETURN;
+    } else if (!strcmp(word, "OtherStatus")) {
+	return 6;
+    } else {
+	return TCL_OK;
+    }
+}
+
+static void
+ObjTraceDeleteProc(
+    ClientData clientData)
+{
+    int *intPtr = (int *) clientData;
+    *intPtr = 1;		/* Record that the trace was deleted */
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TestcreatecommandCmd --
+ *
+ *	This procedure implements the "testcreatecommand" command. It is used
+ *	to test that the Tcl_CreateCommand creates a new command in the
+ *	namespace specified as part of its name, if any. It also checks that
+ *	the namespace code ignore single ":"s in the middle or end of a
+ *	command name.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	Creates and deletes two commands ("test_ns_basic::createdcommand"
+ *	and "value:at:").
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+TestcreatecommandCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int argc,			/* Number of arguments. */
+    const char **argv)		/* Argument strings. */
+{
+    if (argc != 2) {
+	Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
+		" option\"", NULL);
+	return TCL_ERROR;
+    }
+    if (strcmp(argv[1], "create") == 0) {
+	Tcl_CreateCommand(interp, "test_ns_basic::createdcommand",
+		CreatedCommandProc, NULL, NULL);
+    } else if (strcmp(argv[1], "delete") == 0) {
+	Tcl_DeleteCommand(interp, "test_ns_basic::createdcommand");
+    } else if (strcmp(argv[1], "create2") == 0) {
+	Tcl_CreateCommand(interp, "value:at:",
+		CreatedCommandProc2, NULL, NULL);
+    } else if (strcmp(argv[1], "delete2") == 0) {
+	Tcl_DeleteCommand(interp, "value:at:");
+    } else {
+	Tcl_AppendResult(interp, "bad option \"", argv[1],
+		"\": must be create, delete, create2, or delete2", NULL);
+	return TCL_ERROR;
+    }
+    return TCL_OK;
+}
+
+static int
+CreatedCommandProc(
+    ClientData clientData,	/* String to return. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int argc,			/* Number of arguments. */
+    const char **argv)		/* Argument strings. */
+{
+    Tcl_CmdInfo info;
+    int found;
+
+    found = Tcl_GetCommandInfo(interp, "test_ns_basic::createdcommand",
+	    &info);
+    if (!found) {
+	Tcl_AppendResult(interp, "CreatedCommandProc could not get command info for test_ns_basic::createdcommand",
+		NULL);
+	return TCL_ERROR;
+    }
+    Tcl_AppendResult(interp, "CreatedCommandProc in ",
+	    info.namespacePtr->fullName, NULL);
+    return TCL_OK;
+}
+
+static int
+CreatedCommandProc2(
+    ClientData clientData,	/* String to return. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int argc,			/* Number of arguments. */
+    const char **argv)		/* Argument strings. */
+{
+    Tcl_CmdInfo info;
+    int found;
+
+    found = Tcl_GetCommandInfo(interp, "value:at:", &info);
+    if (!found) {
+	Tcl_AppendResult(interp, "CreatedCommandProc2 could not get command info for test_ns_basic::createdcommand",
+		NULL);
+	return TCL_ERROR;
+    }
+    Tcl_AppendResult(interp, "CreatedCommandProc2 in ",
+	    info.namespacePtr->fullName, NULL);
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TestdcallCmd --
+ *
+ *	This procedure implements the "testdcall" command.  It is used
+ *	to test Tcl_CallWhenDeleted.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	Creates and deletes interpreters.
+ *
+ *----------------------------------------------------------------------
+ */
+
+	/* ARGSUSED */
+static int
+TestdcallCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int argc,			/* Number of arguments. */
+    const char **argv)		/* Argument strings. */
+{
+    int i, id;
+
+    delInterp = Tcl_CreateInterp();
+    Tcl_DStringInit(&delString);
+    for (i = 1; i < argc; i++) {
+	if (Tcl_GetInt(interp, argv[i], &id) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	if (id < 0) {
+	    Tcl_DontCallWhenDeleted(delInterp, DelCallbackProc,
+		    (ClientData) INT2PTR(-id));
+	} else {
+	    Tcl_CallWhenDeleted(delInterp, DelCallbackProc,
+		    (ClientData) INT2PTR(id));
+	}
+    }
+    Tcl_DeleteInterp(delInterp);
+    Tcl_DStringResult(interp, &delString);
+    return TCL_OK;
+}
+
+/*
+ * The deletion callback used by TestdcallCmd:
+ */
+
+static void
+DelCallbackProc(
+    ClientData clientData,	/* Numerical value to append to delString. */
+    Tcl_Interp *interp)		/* Interpreter being deleted. */
+{
+    int id = PTR2INT(clientData);
+    char buffer[TCL_INTEGER_SPACE];
+
+    TclFormatInt(buffer, id);
+    Tcl_DStringAppendElement(&delString, buffer);
+    if (interp != delInterp) {
+	Tcl_DStringAppendElement(&delString, "bogus interpreter argument!");
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TestdelCmd --
+ *
+ *	This procedure implements the "testdel" command.  It is used
+ *	to test calling of command deletion callbacks.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	Creates a command.
+ *
+ *----------------------------------------------------------------------
+ */
+
+	/* ARGSUSED */
+static int
+TestdelCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int argc,			/* Number of arguments. */
+    const char **argv)		/* Argument strings. */
+{
+    DelCmd *dPtr;
+    Tcl_Interp *slave;
+
+    if (argc != 4) {
+	Tcl_SetResult(interp, "wrong # args", TCL_STATIC);
+	return TCL_ERROR;
+    }
+
+    slave = Tcl_GetSlave(interp, argv[1]);
+    if (slave == NULL) {
+	return TCL_ERROR;
+    }
+
+    dPtr = ckalloc(sizeof(DelCmd));
+    dPtr->interp = interp;
+    dPtr->deleteCmd = ckalloc(strlen(argv[3]) + 1);
+    strcpy(dPtr->deleteCmd, argv[3]);
+
+    Tcl_CreateCommand(slave, argv[2], DelCmdProc, (ClientData) dPtr,
+	    DelDeleteProc);
+    return TCL_OK;
+}
+
+static int
+DelCmdProc(
+    ClientData clientData,	/* String result to return. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int argc,			/* Number of arguments. */
+    const char **argv)		/* Argument strings. */
+{
+    DelCmd *dPtr = (DelCmd *) clientData;
+
+    Tcl_AppendResult(interp, dPtr->deleteCmd, NULL);
+    ckfree(dPtr->deleteCmd);
+    ckfree(dPtr);
+    return TCL_OK;
+}
+
+static void
+DelDeleteProc(
+    ClientData clientData)	/* String command to evaluate. */
+{
+    DelCmd *dPtr = clientData;
+
+    Tcl_Eval(dPtr->interp, dPtr->deleteCmd);
+    Tcl_ResetResult(dPtr->interp);
+    ckfree(dPtr->deleteCmd);
+    ckfree(dPtr);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TestdelassocdataCmd --
+ *
+ *	This procedure implements the "testdelassocdata" command. It is used
+ *	to test Tcl_DeleteAssocData.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	Deletes an association between a key and associated data from an
+ *	interpreter.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+TestdelassocdataCmd(
+    ClientData clientData,	/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int argc,			/* Number of arguments. */
+    const char **argv)		/* Argument strings. */
+{
+    if (argc != 2) {
+	Tcl_AppendResult(interp, "wrong # arguments: should be \"", argv[0],
+		" data_key\"", NULL);
+	return TCL_ERROR;
+    }
+    Tcl_DeleteAssocData(interp, argv[1]);
+    return TCL_OK;
+}
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * TestdoubledigitsCmd --
+ *
+ *	This procedure implements the 'testdoubledigits' command. It is
+ *	used to test the low-level floating-point formatting primitives
+ *	in Tcl.
+ *
+ * Usage:
+ *	testdoubledigits fpval ndigits type ?shorten"
+ *
+ * Parameters:
+ *	fpval - Floating-point value to format.
+ *	ndigits - Digit count to request from Tcl_DoubleDigits
+ *	type - One of 'shortest', 'Steele', 'e', 'f'
+ *	shorten - Indicates that the 'shorten' flag should be passed in.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static int
+TestdoubledigitsObjCmd(ClientData unused,
+				/* NULL */
+		       Tcl_Interp* interp,
+				/* Tcl interpreter */
+		       int objc,
+				/* Parameter count */
+		       Tcl_Obj* const objv[])
+				/* Parameter vector */
+{
+    static const char* options[] = {
+	"shortest",
+	"Steele",
+	"e",
+	"f",
+	NULL
+    };
+    static const int types[] = {
+	TCL_DD_SHORTEST,
+	TCL_DD_STEELE,
+	TCL_DD_E_FORMAT,
+	TCL_DD_F_FORMAT
+    };
+
+    const Tcl_ObjType* doubleType;
+    double d;
+    int status;
+    int ndigits;
+    int type;
+    int decpt;
+    int signum;
+    char* str;
+    char* endPtr;
+    Tcl_Obj* strObj;
+    Tcl_Obj* retval;
+
+    if (objc < 4 || objc > 5) {
+	Tcl_WrongNumArgs(interp, 1, objv, "fpval ndigits type ?shorten?");
+	return TCL_ERROR;
+    }
+    status = Tcl_GetDoubleFromObj(interp, objv[1], &d);
+    if (status != TCL_OK) {
+	doubleType = Tcl_GetObjType("double");
+	if (objv[1]->typePtr == doubleType
+	    || TclIsNaN(objv[1]->internalRep.doubleValue)) {
+	    status = TCL_OK;
+	    memcpy(&d, &(objv[1]->internalRep.doubleValue), sizeof(double));
+	}
+    }
+    if (status != TCL_OK
+	|| Tcl_GetIntFromObj(interp, objv[2], &ndigits) != TCL_OK
+	|| Tcl_GetIndexFromObj(interp, objv[3], options, "conversion type",
+			       TCL_EXACT, &type) != TCL_OK) {
+	fprintf(stderr, "bad value? %g\n", d);
+	return TCL_ERROR;
+    }
+    type = types[type];
+    if (objc > 4) {
+	if (strcmp(Tcl_GetString(objv[4]), "shorten")) {
+	    Tcl_SetObjResult(interp, Tcl_NewStringObj("bad flag", -1));
+	    return TCL_ERROR;
+	}
+	type |= TCL_DD_SHORTEN_FLAG;
+    }
+    str = TclDoubleDigits(d, ndigits, type, &decpt, &signum, &endPtr);
+    strObj = Tcl_NewStringObj(str, endPtr-str);
+    ckfree(str);
+    retval = Tcl_NewListObj(1, &strObj);
+    Tcl_ListObjAppendElement(NULL, retval, Tcl_NewIntObj(decpt));
+    strObj = Tcl_NewStringObj(signum ? "-" : "+", 1);
+    Tcl_ListObjAppendElement(NULL, retval, strObj);
+    Tcl_SetObjResult(interp, retval);
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TestdstringCmd --
+ *
+ *	This procedure implements the "testdstring" command.  It is used
+ *	to test the dynamic string facilities of Tcl.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	Creates, deletes, and invokes handlers.
+ *
+ *----------------------------------------------------------------------
+ */
+
+	/* ARGSUSED */
+static int
+TestdstringCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int argc,			/* Number of arguments. */
+    const char **argv)		/* Argument strings. */
+{
+    int count;
+
+    if (argc < 2) {
+	wrongNumArgs:
+	Tcl_SetResult(interp, "wrong # args", TCL_STATIC);
+	return TCL_ERROR;
+    }
+    if (strcmp(argv[1], "append") == 0) {
+	if (argc != 4) {
+	    goto wrongNumArgs;
+	}
+	if (Tcl_GetInt(interp, argv[3], &count) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	Tcl_DStringAppend(&dstring, argv[2], count);
+    } else if (strcmp(argv[1], "element") == 0) {
+	if (argc != 3) {
+	    goto wrongNumArgs;
+	}
+	Tcl_DStringAppendElement(&dstring, argv[2]);
+    } else if (strcmp(argv[1], "end") == 0) {
+	if (argc != 2) {
+	    goto wrongNumArgs;
+	}
+	Tcl_DStringEndSublist(&dstring);
+    } else if (strcmp(argv[1], "free") == 0) {
+	if (argc != 2) {
+	    goto wrongNumArgs;
+	}
+	Tcl_DStringFree(&dstring);
+    } else if (strcmp(argv[1], "get") == 0) {
+	if (argc != 2) {
+	    goto wrongNumArgs;
+	}
+	Tcl_SetResult(interp, Tcl_DStringValue(&dstring), TCL_VOLATILE);
+    } else if (strcmp(argv[1], "gresult") == 0) {
+	if (argc != 3) {
+	    goto wrongNumArgs;
+	}
+	if (strcmp(argv[2], "staticsmall") == 0) {
+	    Tcl_SetResult(interp, "short", TCL_STATIC);
+	} else if (strcmp(argv[2], "staticlarge") == 0) {
+	    Tcl_SetResult(interp, "first0 first1 first2 first3 first4 first5 first6 first7 first8 first9\nsecond0 second1 second2 second3 second4 second5 second6 second7 second8 second9\nthird0 third1 third2 third3 third4 third5 third6 third7 third8 third9\nfourth0 fourth1 fourth2 fourth3 fourth4 fourth5 fourth6 fourth7 fourth8 fourth9\nfifth0 fifth1 fifth2 fifth3 fifth4 fifth5 fifth6 fifth7 fifth8 fifth9\nsixth0 sixth1 sixth2 sixth3 sixth4 sixth5 sixth6 sixth7 sixth8 sixth9\nseventh0 seventh1 seventh2 seventh3 seventh4 seventh5 seventh6 seventh7 seventh8 seventh9\n", TCL_STATIC);
+	} else if (strcmp(argv[2], "free") == 0) {
+	    char *s = ckalloc(100);
+	    strcpy(s, "This is a malloc-ed string");
+	    Tcl_SetResult(interp, s, TCL_DYNAMIC);
+	} else if (strcmp(argv[2], "special") == 0) {
+	    char *s = (char*)ckalloc(100) + 16;
+	    strcpy(s, "This is a specially-allocated string");
+	    Tcl_SetResult(interp, s, SpecialFree);
+	} else {
+	    Tcl_AppendResult(interp, "bad gresult option \"", argv[2],
+		    "\": must be staticsmall, staticlarge, free, or special",
+		    NULL);
+	    return TCL_ERROR;
+	}
+	Tcl_DStringGetResult(interp, &dstring);
+    } else if (strcmp(argv[1], "length") == 0) {
+
+	if (argc != 2) {
+	    goto wrongNumArgs;
+	}
+	Tcl_SetObjResult(interp, Tcl_NewIntObj(Tcl_DStringLength(&dstring)));
+    } else if (strcmp(argv[1], "result") == 0) {
+	if (argc != 2) {
+	    goto wrongNumArgs;
+	}
+	Tcl_DStringResult(interp, &dstring);
+    } else if (strcmp(argv[1], "trunc") == 0) {
+	if (argc != 3) {
+	    goto wrongNumArgs;
+	}
+	if (Tcl_GetInt(interp, argv[2], &count) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	Tcl_DStringSetLength(&dstring, count);
+    } else if (strcmp(argv[1], "start") == 0) {
+	if (argc != 2) {
+	    goto wrongNumArgs;
+	}
+	Tcl_DStringStartSublist(&dstring);
+    } else {
+	Tcl_AppendResult(interp, "bad option \"", argv[1],
+		"\": must be append, element, end, free, get, length, "
+		"result, trunc, or start", NULL);
+	return TCL_ERROR;
+    }
+    return TCL_OK;
+}
+
+/*
+ * The procedure below is used as a special freeProc to test how well
+ * Tcl_DStringGetResult handles freeProc's other than free.
+ */
+
+static void SpecialFree(blockPtr)
+    char *blockPtr;			/* Block to free. */
+{
+    ckfree(blockPtr - 16);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TestencodingCmd --
+ *
+ *	This procedure implements the "testencoding" command.  It is used
+ *	to test the encoding package.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	Load encodings.
+ *
+ *----------------------------------------------------------------------
+ */
+
+	/* ARGSUSED */
+static int
+TestencodingObjCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    Tcl_Encoding encoding;
+    int index, length;
+    const char *string;
+    TclEncoding *encodingPtr;
+    static const char *const optionStrings[] = {
+	"create",	"delete",	NULL
+    };
+    enum options {
+	ENC_CREATE,	ENC_DELETE
+    };
+
+    if (Tcl_GetIndexFromObj(interp, objv[1], optionStrings, "option", 0,
+	    &index) != TCL_OK) {
+	return TCL_ERROR;
+    }
+
+    switch ((enum options) index) {
+    case ENC_CREATE: {
+	Tcl_EncodingType type;
+
+	if (objc != 5) {
+	    return TCL_ERROR;
+	}
+	encodingPtr = ckalloc(sizeof(TclEncoding));
+	encodingPtr->interp = interp;
+
+	string = Tcl_GetStringFromObj(objv[3], &length);
+	encodingPtr->toUtfCmd = ckalloc(length + 1);
+	memcpy(encodingPtr->toUtfCmd, string, (unsigned) length + 1);
+
+	string = Tcl_GetStringFromObj(objv[4], &length);
+	encodingPtr->fromUtfCmd = ckalloc(length + 1);
+	memcpy(encodingPtr->fromUtfCmd, string, (unsigned) (length + 1));
+
+	string = Tcl_GetStringFromObj(objv[2], &length);
+
+	type.encodingName = string;
+	type.toUtfProc = EncodingToUtfProc;
+	type.fromUtfProc = EncodingFromUtfProc;
+	type.freeProc = EncodingFreeProc;
+	type.clientData = (ClientData) encodingPtr;
+	type.nullSize = 1;
+
+	Tcl_CreateEncoding(&type);
+	break;
+    }
+    case ENC_DELETE:
+	if (objc != 3) {
+	    return TCL_ERROR;
+	}
+	encoding = Tcl_GetEncoding(NULL, Tcl_GetString(objv[2]));
+	Tcl_FreeEncoding(encoding);
+	Tcl_FreeEncoding(encoding);
+	break;
+    }
+    return TCL_OK;
+}
+
+static int
+EncodingToUtfProc(
+    ClientData clientData,	/* TclEncoding structure. */
+    const char *src,		/* Source string in specified encoding. */
+    int srcLen,			/* Source string length in bytes. */
+    int flags,			/* Conversion control flags. */
+    Tcl_EncodingState *statePtr,/* Current state. */
+    char *dst,			/* Output buffer. */
+    int dstLen,			/* The maximum length of output buffer. */
+    int *srcReadPtr,		/* Filled with number of bytes read. */
+    int *dstWrotePtr,		/* Filled with number of bytes stored. */
+    int *dstCharsPtr)		/* Filled with number of chars stored. */
+{
+    int len;
+    TclEncoding *encodingPtr;
+
+    encodingPtr = (TclEncoding *) clientData;
+    Tcl_EvalEx(encodingPtr->interp,encodingPtr->toUtfCmd,-1,TCL_EVAL_GLOBAL);
+
+    len = strlen(Tcl_GetStringResult(encodingPtr->interp));
+    if (len > dstLen) {
+	len = dstLen;
+    }
+    memcpy(dst, Tcl_GetStringResult(encodingPtr->interp), (unsigned) len);
+    Tcl_ResetResult(encodingPtr->interp);
+
+    *srcReadPtr = srcLen;
+    *dstWrotePtr = len;
+    *dstCharsPtr = len;
+    return TCL_OK;
+}
+
+static int
+EncodingFromUtfProc(
+    ClientData clientData,	/* TclEncoding structure. */
+    const char *src,		/* Source string in specified encoding. */
+    int srcLen,			/* Source string length in bytes. */
+    int flags,			/* Conversion control flags. */
+    Tcl_EncodingState *statePtr,/* Current state. */
+    char *dst,			/* Output buffer. */
+    int dstLen,			/* The maximum length of output buffer. */
+    int *srcReadPtr,		/* Filled with number of bytes read. */
+    int *dstWrotePtr,		/* Filled with number of bytes stored. */
+    int *dstCharsPtr)		/* Filled with number of chars stored. */
+{
+    int len;
+    TclEncoding *encodingPtr;
+
+    encodingPtr = (TclEncoding *) clientData;
+    Tcl_EvalEx(encodingPtr->interp, encodingPtr->fromUtfCmd,-1,TCL_EVAL_GLOBAL);
+
+    len = strlen(Tcl_GetStringResult(encodingPtr->interp));
+    if (len > dstLen) {
+	len = dstLen;
+    }
+    memcpy(dst, Tcl_GetStringResult(encodingPtr->interp), (unsigned) len);
+    Tcl_ResetResult(encodingPtr->interp);
+
+    *srcReadPtr = srcLen;
+    *dstWrotePtr = len;
+    *dstCharsPtr = len;
+    return TCL_OK;
+}
+
+static void
+EncodingFreeProc(
+    ClientData clientData)	/* ClientData associated with type. */
+{
+    TclEncoding *encodingPtr = clientData;
+
+    ckfree(encodingPtr->toUtfCmd);
+    ckfree(encodingPtr->fromUtfCmd);
+    ckfree(encodingPtr);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TestevalexObjCmd --
+ *
+ *	This procedure implements the "testevalex" command.  It is
+ *	used to test Tcl_EvalEx.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+TestevalexObjCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    int length, flags;
+    const char *script;
+
+    flags = 0;
+    if (objc == 3) {
+	const char *global = Tcl_GetStringFromObj(objv[2], &length);
+	if (strcmp(global, "global") != 0) {
+	    Tcl_AppendResult(interp, "bad value \"", global,
+		    "\": must be global", NULL);
+	    return TCL_ERROR;
+	}
+	flags = TCL_EVAL_GLOBAL;
+    } else if (objc != 2) {
+	Tcl_WrongNumArgs(interp, 1, objv, "script ?global?");
+	return TCL_ERROR;
+    }
+
+    script = Tcl_GetStringFromObj(objv[1], &length);
+    return Tcl_EvalEx(interp, script, length, flags);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TestevalobjvObjCmd --
+ *
+ *	This procedure implements the "testevalobjv" command.  It is
+ *	used to test Tcl_EvalObjv.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+TestevalobjvObjCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    int evalGlobal;
+
+    if (objc < 3) {
+	Tcl_WrongNumArgs(interp, 1, objv, "global word ?word ...?");
+	return TCL_ERROR;
+    }
+    if (Tcl_GetIntFromObj(interp, objv[1], &evalGlobal) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    return Tcl_EvalObjv(interp, objc-2, objv+2,
+	    (evalGlobal) ? TCL_EVAL_GLOBAL : 0);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TesteventObjCmd --
+ *
+ *	This procedure implements a 'testevent' command.  The command
+ *	is used to test event queue management.
+ *
+ * The command takes two forms:
+ *	- testevent queue name position script
+ *		Queues an event at the given position in the queue, and
+ *		associates a given name with it (the same name may be
+ *		associated with multiple events). When the event comes
+ *		to the head of the queue, executes the given script at
+ *		global level in the current interp. The position may be
+ *		one of 'head', 'tail' or 'mark'.
+ *	- testevent delete name
+ *		Deletes any events associated with the given name from
+ *		the queue.
+ *
+ * Return value:
+ *	Returns a standard Tcl result.
+ *
+ * Side effects:
+ *	Manipulates the event queue as directed.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+TesteventObjCmd(
+    ClientData unused,		/* Not used */
+    Tcl_Interp *interp,		/* Tcl interpreter */
+    int objc,			/* Parameter count */
+    Tcl_Obj *const objv[])	/* Parameter vector */
+{
+    static const char *const subcommands[] = { /* Possible subcommands */
+	"queue", "delete", NULL
+    };
+    int subCmdIndex;		/* Index of the chosen subcommand */
+    static const char *const positions[] = { /* Possible queue positions */
+	"head", "tail", "mark", NULL
+    };
+    int posIndex;		/* Index of the chosen position */
+    static const Tcl_QueuePosition posNum[] = {
+				/* Interpretation of the chosen position */
+	TCL_QUEUE_HEAD,
+	TCL_QUEUE_TAIL,
+	TCL_QUEUE_MARK
+    };
+    TestEvent *ev;		/* Event to be queued */
+
+    if (objc < 2) {
+	Tcl_WrongNumArgs(interp, 1, objv, "subcommand ?arg ...?");
+	return TCL_ERROR;
+    }
+    if (Tcl_GetIndexFromObj(interp, objv[1], subcommands, "subcommand",
+	    TCL_EXACT, &subCmdIndex) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    switch (subCmdIndex) {
+    case 0:			/* queue */
+	if (objc != 5) {
+	    Tcl_WrongNumArgs(interp, 2, objv, "name position script");
+	    return TCL_ERROR;
+	}
+	if (Tcl_GetIndexFromObj(interp, objv[3], positions,
+		"position specifier", TCL_EXACT, &posIndex) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	ev = ckalloc(sizeof(TestEvent));
+	ev->header.proc = TesteventProc;
+	ev->header.nextPtr = NULL;
+	ev->interp = interp;
+	ev->command = objv[4];
+	Tcl_IncrRefCount(ev->command);
+	ev->tag = objv[2];
+	Tcl_IncrRefCount(ev->tag);
+	Tcl_QueueEvent((Tcl_Event *) ev, posNum[posIndex]);
+	break;
+
+    case 1:			/* delete */
+	if (objc != 3) {
+	    Tcl_WrongNumArgs(interp, 2, objv, "name");
+	    return TCL_ERROR;
+	}
+	Tcl_DeleteEvents(TesteventDeleteProc, objv[2]);
+	break;
+    }
+
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TesteventProc --
+ *
+ *	Delivers a test event to the Tcl interpreter as part of event
+ *	queue testing.
+ *
+ * Results:
+ *	Returns 1 if the event has been serviced, 0 otherwise.
+ *
+ * Side effects:
+ *	Evaluates the event's callback script, so has whatever side effects
+ *	the callback has.  The return value of the callback script becomes the
+ *	return value of this function.  If the callback script reports an
+ *	error, it is reported as a background error.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+TesteventProc(
+    Tcl_Event *event,		/* Event to deliver */
+    int flags)			/* Current flags for Tcl_ServiceEvent */
+{
+    TestEvent *ev = (TestEvent *) event;
+    Tcl_Interp *interp = ev->interp;
+    Tcl_Obj *command = ev->command;
+    int result = Tcl_EvalObjEx(interp, command,
+	    TCL_EVAL_GLOBAL | TCL_EVAL_DIRECT);
+    int retval;
+
+    if (result != TCL_OK) {
+	Tcl_AddErrorInfo(interp,
+		"    (command bound to \"testevent\" callback)");
+	Tcl_BackgroundError(interp);
+	return 1;		/* Avoid looping on errors */
+    }
+    if (Tcl_GetBooleanFromObj(interp, Tcl_GetObjResult(interp),
+	    &retval) != TCL_OK) {
+	Tcl_AddErrorInfo(interp,
+		"    (return value from \"testevent\" callback)");
+	Tcl_BackgroundError(interp);
+	return 1;
+    }
+    if (retval) {
+	Tcl_DecrRefCount(ev->tag);
+	Tcl_DecrRefCount(ev->command);
+    }
+
+    return retval;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TesteventDeleteProc --
+ *
+ *	Removes some set of events from the queue.
+ *
+ * This procedure is used as part of testing event queue management.
+ *
+ * Results:
+ *	Returns 1 if a given event should be deleted, 0 otherwise.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+TesteventDeleteProc(
+    Tcl_Event *event,		/* Event to examine */
+    ClientData clientData)	/* Tcl_Obj containing the name of the event(s)
+				 * to remove */
+{
+    TestEvent *ev;		/* Event to examine */
+    const char *evNameStr;
+    Tcl_Obj *targetName;	/* Name of the event(s) to delete */
+    const char *targetNameStr;
+
+    if (event->proc != TesteventProc) {
+	return 0;
+    }
+    targetName = (Tcl_Obj *) clientData;
+    targetNameStr = (char *) Tcl_GetString(targetName);
+    ev = (TestEvent *) event;
+    evNameStr = Tcl_GetString(ev->tag);
+    if (strcmp(evNameStr, targetNameStr) == 0) {
+	Tcl_DecrRefCount(ev->tag);
+	Tcl_DecrRefCount(ev->command);
+	return 1;
+    } else {
+	return 0;
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TestexithandlerCmd --
+ *
+ *	This procedure implements the "testexithandler" command. It is
+ *	used to test Tcl_CreateExitHandler and Tcl_DeleteExitHandler.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+TestexithandlerCmd(
+    ClientData clientData,	/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int argc,			/* Number of arguments. */
+    const char **argv)		/* Argument strings. */
+{
+    int value;
+
+    if (argc != 3) {
+	Tcl_AppendResult(interp, "wrong # arguments: should be \"", argv[0],
+		" create|delete value\"", NULL);
+	return TCL_ERROR;
+    }
+    if (Tcl_GetInt(interp, argv[2], &value) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    if (strcmp(argv[1], "create") == 0) {
+	Tcl_CreateExitHandler((value & 1) ? ExitProcOdd : ExitProcEven,
+		(ClientData) INT2PTR(value));
+    } else if (strcmp(argv[1], "delete") == 0) {
+	Tcl_DeleteExitHandler((value & 1) ? ExitProcOdd : ExitProcEven,
+		(ClientData) INT2PTR(value));
+    } else {
+	Tcl_AppendResult(interp, "bad option \"", argv[1],
+		"\": must be create or delete", NULL);
+	return TCL_ERROR;
+    }
+    return TCL_OK;
+}
+
+static void
+ExitProcOdd(
+    ClientData clientData)	/* Integer value to print. */
+{
+    char buf[16 + TCL_INTEGER_SPACE];
+    size_t len;
+
+    sprintf(buf, "odd %d\n", PTR2INT(clientData));
+    len = strlen(buf);
+    if (len != (size_t) write(1, buf, len)) {
+	Tcl_Panic("ExitProcOdd: unable to write to stdout");
+    }
+}
+
+static void
+ExitProcEven(
+    ClientData clientData)	/* Integer value to print. */
+{
+    char buf[16 + TCL_INTEGER_SPACE];
+    size_t len;
+
+    sprintf(buf, "even %d\n", PTR2INT(clientData));
+    len = strlen(buf);
+    if (len != (size_t) write(1, buf, len)) {
+	Tcl_Panic("ExitProcEven: unable to write to stdout");
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TestexprlongCmd --
+ *
+ *	This procedure verifies that Tcl_ExprLong does not modify the
+ *	interpreter result if there is no error.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+TestexprlongCmd(
+    ClientData clientData,	/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int argc,			/* Number of arguments. */
+    const char **argv)		/* Argument strings. */
+{
+    long exprResult;
+    char buf[4 + TCL_INTEGER_SPACE];
+    int result;
+
+    if (argc != 2) {
+	Tcl_AppendResult(interp, "wrong # arguments: should be \"", argv[0],
+		" expression\"", NULL);
+	return TCL_ERROR;
+    }
+    Tcl_SetResult(interp, "This is a result", TCL_STATIC);
+    result = Tcl_ExprLong(interp, argv[1], &exprResult);
+    if (result != TCL_OK) {
+	return result;
+    }
+    sprintf(buf, ": %ld", exprResult);
+    Tcl_AppendResult(interp, buf, NULL);
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TestexprlongobjCmd --
+ *
+ *	This procedure verifies that Tcl_ExprLongObj does not modify the
+ *	interpreter result if there is no error.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+TestexprlongobjCmd(
+    ClientData clientData,	/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const *objv)	/* Argument objects. */
+{
+    long exprResult;
+    char buf[4 + TCL_INTEGER_SPACE];
+    int result;
+
+    if (objc != 2) {
+	Tcl_WrongNumArgs(interp, 1, objv, "expression");
+	return TCL_ERROR;
+    }
+    Tcl_SetResult(interp, "This is a result", TCL_STATIC);
+    result = Tcl_ExprLongObj(interp, objv[1], &exprResult);
+    if (result != TCL_OK) {
+	return result;
+    }
+    sprintf(buf, ": %ld", exprResult);
+    Tcl_AppendResult(interp, buf, NULL);
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TestexprdoubleCmd --
+ *
+ *	This procedure verifies that Tcl_ExprDouble does not modify the
+ *	interpreter result if there is no error.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+TestexprdoubleCmd(
+    ClientData clientData,	/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int argc,			/* Number of arguments. */
+    const char **argv)		/* Argument strings. */
+{
+    double exprResult;
+    char buf[4 + TCL_DOUBLE_SPACE];
+    int result;
+
+    if (argc != 2) {
+	Tcl_AppendResult(interp, "wrong # arguments: should be \"", argv[0],
+		" expression\"", NULL);
+	return TCL_ERROR;
+    }
+    Tcl_SetResult(interp, "This is a result", TCL_STATIC);
+    result = Tcl_ExprDouble(interp, argv[1], &exprResult);
+    if (result != TCL_OK) {
+	return result;
+    }
+    strcpy(buf, ": ");
+    Tcl_PrintDouble(interp, exprResult, buf+2);
+    Tcl_AppendResult(interp, buf, NULL);
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TestexprdoubleobjCmd --
+ *
+ *	This procedure verifies that Tcl_ExprLongObj does not modify the
+ *	interpreter result if there is no error.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+TestexprdoubleobjCmd(
+    ClientData clientData,	/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const *objv)	/* Argument objects. */
+{
+    double exprResult;
+    char buf[4 + TCL_DOUBLE_SPACE];
+    int result;
+
+    if (objc != 2) {
+	Tcl_WrongNumArgs(interp, 1, objv, "expression");
+	return TCL_ERROR;
+    }
+    Tcl_SetResult(interp, "This is a result", TCL_STATIC);
+    result = Tcl_ExprDoubleObj(interp, objv[1], &exprResult);
+    if (result != TCL_OK) {
+	return result;
+    }
+    strcpy(buf, ": ");
+    Tcl_PrintDouble(interp, exprResult, buf+2);
+    Tcl_AppendResult(interp, buf, NULL);
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TestexprstringCmd --
+ *
+ *	This procedure tests the basic operation of Tcl_ExprString.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+TestexprstringCmd(
+    ClientData clientData,	/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int argc,			/* Number of arguments. */
+    const char **argv)		/* Argument strings. */
+{
+    if (argc != 2) {
+	Tcl_AppendResult(interp, "wrong # arguments: should be \"", argv[0],
+		" expression\"", NULL);
+	return TCL_ERROR;
+    }
+    return Tcl_ExprString(interp, argv[1]);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TestfilelinkCmd --
+ *
+ *	This procedure implements the "testfilelink" command.  It is used to
+ *	test the effects of creating and manipulating filesystem links in Tcl.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	May create a link on disk.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+TestfilelinkCmd(
+    ClientData clientData,	/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* The argument objects. */
+{
+    Tcl_Obj *contents;
+
+    if (objc < 2 || objc > 3) {
+	Tcl_WrongNumArgs(interp, 1, objv, "source ?target?");
+	return TCL_ERROR;
+    }
+
+    if (Tcl_FSConvertToPathType(interp, objv[1]) != TCL_OK) {
+	return TCL_ERROR;
+    }
+
+    if (objc == 3) {
+	/* Create link from source to target */
+	contents = Tcl_FSLink(objv[1], objv[2],
+		TCL_CREATE_SYMBOLIC_LINK|TCL_CREATE_HARD_LINK);
+	if (contents == NULL) {
+	    Tcl_AppendResult(interp, "could not create link from \"",
+		    Tcl_GetString(objv[1]), "\" to \"",
+		    Tcl_GetString(objv[2]), "\": ",
+		    Tcl_PosixError(interp), NULL);
+	    return TCL_ERROR;
+	}
+    } else {
+	/* Read link */
+	contents = Tcl_FSLink(objv[1], NULL, 0);
+	if (contents == NULL) {
+	    Tcl_AppendResult(interp, "could not read link \"",
+		    Tcl_GetString(objv[1]), "\": ",
+		    Tcl_PosixError(interp), NULL);
+	    return TCL_ERROR;
+	}
+    }
+    Tcl_SetObjResult(interp, contents);
+    if (objc == 2) {
+	/*
+	 * If we are creating a link, this will actually just
+	 * be objv[3], and we don't own it
+	 */
+	Tcl_DecrRefCount(contents);
+    }
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TestgetassocdataCmd --
+ *
+ *	This procedure implements the "testgetassocdata" command. It is
+ *	used to test Tcl_GetAssocData.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+TestgetassocdataCmd(
+    ClientData clientData,	/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int argc,			/* Number of arguments. */
+    const char **argv)		/* Argument strings. */
+{
+    char *res;
+
+    if (argc != 2) {
+	Tcl_AppendResult(interp, "wrong # arguments: should be \"", argv[0],
+		" data_key\"", NULL);
+	return TCL_ERROR;
+    }
+    res = (char *) Tcl_GetAssocData(interp, argv[1], NULL);
+    if (res != NULL) {
+	Tcl_AppendResult(interp, res, NULL);
+    }
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TestgetplatformCmd --
+ *
+ *	This procedure implements the "testgetplatform" command. It is
+ *	used to retrievel the value of the tclPlatform global variable.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+TestgetplatformCmd(
+    ClientData clientData,	/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int argc,			/* Number of arguments. */
+    const char **argv)		/* Argument strings. */
+{
+    static const char *const platformStrings[] = { "unix", "mac", "windows" };
+    TclPlatformType *platform;
+
+    platform = TclGetPlatform();
+
+    if (argc != 1) {
+	Tcl_AppendResult(interp, "wrong # arguments: should be \"", argv[0],
+		NULL);
+	return TCL_ERROR;
+    }
+
+    Tcl_AppendResult(interp, platformStrings[*platform], NULL);
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TestinterpdeleteCmd --
+ *
+ *	This procedure tests the code in tclInterp.c that deals with
+ *	interpreter deletion. It deletes a user-specified interpreter
+ *	from the hierarchy, and subsequent code checks integrity.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	Deletes one or more interpreters.
+ *
+ *----------------------------------------------------------------------
+ */
+
+	/* ARGSUSED */
+static int
+TestinterpdeleteCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int argc,			/* Number of arguments. */
+    const char **argv)		/* Argument strings. */
+{
+    Tcl_Interp *slaveToDelete;
+
+    if (argc != 2) {
+	Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
+		" path\"", NULL);
+	return TCL_ERROR;
+    }
+    slaveToDelete = Tcl_GetSlave(interp, argv[1]);
+    if (slaveToDelete == NULL) {
+	return TCL_ERROR;
+    }
+    Tcl_DeleteInterp(slaveToDelete);
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TestlinkCmd --
+ *
+ *	This procedure implements the "testlink" command.  It is used
+ *	to test Tcl_LinkVar and related library procedures.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	Creates and deletes various variable links, plus returns
+ *	values of the linked variables.
+ *
+ *----------------------------------------------------------------------
+ */
+
+	/* ARGSUSED */
+static int
+TestlinkCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int argc,			/* Number of arguments. */
+    const char **argv)		/* Argument strings. */
+{
+    static int intVar = 43;
+    static int boolVar = 4;
+    static double realVar = 1.23;
+    static Tcl_WideInt wideVar = Tcl_LongAsWide(79);
+    static char *stringVar = NULL;
+    static char charVar = '@';
+    static unsigned char ucharVar = 130;
+    static short shortVar = 3000;
+    static unsigned short ushortVar = 60000;
+    static unsigned int uintVar = 0xbeeffeed;
+    static long longVar = 123456789L;
+    static unsigned long ulongVar = 3456789012UL;
+    static float floatVar = 4.5;
+    static Tcl_WideUInt uwideVar = (Tcl_WideUInt) Tcl_LongAsWide(123);
+    static int created = 0;
+    char buffer[2*TCL_DOUBLE_SPACE];
+    int writable, flag;
+    Tcl_Obj *tmp;
+
+    if (argc < 2) {
+	Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
+		" option ?arg arg arg arg arg arg arg arg arg arg arg arg"
+		" arg arg?\"", NULL);
+	return TCL_ERROR;
+    }
+    if (strcmp(argv[1], "create") == 0) {
+	if (argc != 16) {
+	    Tcl_AppendResult(interp, "wrong # args: should be \"",
+		argv[0], " ", argv[1],
+		" intRO realRO boolRO stringRO wideRO charRO ucharRO shortRO"
+		" ushortRO uintRO longRO ulongRO floatRO uwideRO\"", NULL);
+	    return TCL_ERROR;
+	}
+	if (created) {
+	    Tcl_UnlinkVar(interp, "int");
+	    Tcl_UnlinkVar(interp, "real");
+	    Tcl_UnlinkVar(interp, "bool");
+	    Tcl_UnlinkVar(interp, "string");
+	    Tcl_UnlinkVar(interp, "wide");
+	    Tcl_UnlinkVar(interp, "char");
+	    Tcl_UnlinkVar(interp, "uchar");
+	    Tcl_UnlinkVar(interp, "short");
+	    Tcl_UnlinkVar(interp, "ushort");
+	    Tcl_UnlinkVar(interp, "uint");
+	    Tcl_UnlinkVar(interp, "long");
+	    Tcl_UnlinkVar(interp, "ulong");
+	    Tcl_UnlinkVar(interp, "float");
+	    Tcl_UnlinkVar(interp, "uwide");
+	}
+	created = 1;
+	if (Tcl_GetBoolean(interp, argv[2], &writable) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	flag = (writable != 0) ? 0 : TCL_LINK_READ_ONLY;
+	if (Tcl_LinkVar(interp, "int", (char *) &intVar,
+		TCL_LINK_INT | flag) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	if (Tcl_GetBoolean(interp, argv[3], &writable) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	flag = (writable != 0) ? 0 : TCL_LINK_READ_ONLY;
+	if (Tcl_LinkVar(interp, "real", (char *) &realVar,
+		TCL_LINK_DOUBLE | flag) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	if (Tcl_GetBoolean(interp, argv[4], &writable) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	flag = (writable != 0) ? 0 : TCL_LINK_READ_ONLY;
+	if (Tcl_LinkVar(interp, "bool", (char *) &boolVar,
+		TCL_LINK_BOOLEAN | flag) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	if (Tcl_GetBoolean(interp, argv[5], &writable) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	flag = (writable != 0) ? 0 : TCL_LINK_READ_ONLY;
+	if (Tcl_LinkVar(interp, "string", (char *) &stringVar,
+		TCL_LINK_STRING | flag) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	if (Tcl_GetBoolean(interp, argv[6], &writable) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	flag = (writable != 0) ? 0 : TCL_LINK_READ_ONLY;
+	if (Tcl_LinkVar(interp, "wide", (char *) &wideVar,
+			TCL_LINK_WIDE_INT | flag) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	if (Tcl_GetBoolean(interp, argv[7], &writable) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	flag = (writable != 0) ? 0 : TCL_LINK_READ_ONLY;
+	if (Tcl_LinkVar(interp, "char", (char *) &charVar,
+		TCL_LINK_CHAR | flag) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	if (Tcl_GetBoolean(interp, argv[8], &writable) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	flag = (writable != 0) ? 0 : TCL_LINK_READ_ONLY;
+	if (Tcl_LinkVar(interp, "uchar", (char *) &ucharVar,
+		TCL_LINK_UCHAR | flag) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	if (Tcl_GetBoolean(interp, argv[9], &writable) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	flag = (writable != 0) ? 0 : TCL_LINK_READ_ONLY;
+	if (Tcl_LinkVar(interp, "short", (char *) &shortVar,
+		TCL_LINK_SHORT | flag) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	if (Tcl_GetBoolean(interp, argv[10], &writable) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	flag = (writable != 0) ? 0 : TCL_LINK_READ_ONLY;
+	if (Tcl_LinkVar(interp, "ushort", (char *) &ushortVar,
+		TCL_LINK_USHORT | flag) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	if (Tcl_GetBoolean(interp, argv[11], &writable) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	flag = (writable != 0) ? 0 : TCL_LINK_READ_ONLY;
+	if (Tcl_LinkVar(interp, "uint", (char *) &uintVar,
+		TCL_LINK_UINT | flag) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	if (Tcl_GetBoolean(interp, argv[12], &writable) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	flag = (writable != 0) ? 0 : TCL_LINK_READ_ONLY;
+	if (Tcl_LinkVar(interp, "long", (char *) &longVar,
+		TCL_LINK_LONG | flag) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	if (Tcl_GetBoolean(interp, argv[13], &writable) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	flag = (writable != 0) ? 0 : TCL_LINK_READ_ONLY;
+	if (Tcl_LinkVar(interp, "ulong", (char *) &ulongVar,
+		TCL_LINK_ULONG | flag) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	if (Tcl_GetBoolean(interp, argv[14], &writable) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	flag = (writable != 0) ? 0 : TCL_LINK_READ_ONLY;
+	if (Tcl_LinkVar(interp, "float", (char *) &floatVar,
+		TCL_LINK_FLOAT | flag) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	if (Tcl_GetBoolean(interp, argv[15], &writable) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	flag = (writable != 0) ? 0 : TCL_LINK_READ_ONLY;
+	if (Tcl_LinkVar(interp, "uwide", (char *) &uwideVar,
+		TCL_LINK_WIDE_UINT | flag) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+
+    } else if (strcmp(argv[1], "delete") == 0) {
+	Tcl_UnlinkVar(interp, "int");
+	Tcl_UnlinkVar(interp, "real");
+	Tcl_UnlinkVar(interp, "bool");
+	Tcl_UnlinkVar(interp, "string");
+	Tcl_UnlinkVar(interp, "wide");
+	Tcl_UnlinkVar(interp, "char");
+	Tcl_UnlinkVar(interp, "uchar");
+	Tcl_UnlinkVar(interp, "short");
+	Tcl_UnlinkVar(interp, "ushort");
+	Tcl_UnlinkVar(interp, "uint");
+	Tcl_UnlinkVar(interp, "long");
+	Tcl_UnlinkVar(interp, "ulong");
+	Tcl_UnlinkVar(interp, "float");
+	Tcl_UnlinkVar(interp, "uwide");
+	created = 0;
+    } else if (strcmp(argv[1], "get") == 0) {
+	TclFormatInt(buffer, intVar);
+	Tcl_AppendElement(interp, buffer);
+	Tcl_PrintDouble(NULL, realVar, buffer);
+	Tcl_AppendElement(interp, buffer);
+	TclFormatInt(buffer, boolVar);
+	Tcl_AppendElement(interp, buffer);
+	Tcl_AppendElement(interp, (stringVar == NULL) ? "-" : stringVar);
+	/*
+	 * Wide ints only have an object-based interface.
+	 */
+	tmp = Tcl_NewWideIntObj(wideVar);
+	Tcl_AppendElement(interp, Tcl_GetString(tmp));
+	Tcl_DecrRefCount(tmp);
+	TclFormatInt(buffer, (int) charVar);
+	Tcl_AppendElement(interp, buffer);
+	TclFormatInt(buffer, (int) ucharVar);
+	Tcl_AppendElement(interp, buffer);
+	TclFormatInt(buffer, (int) shortVar);
+	Tcl_AppendElement(interp, buffer);
+	TclFormatInt(buffer, (int) ushortVar);
+	Tcl_AppendElement(interp, buffer);
+	TclFormatInt(buffer, (int) uintVar);
+	Tcl_AppendElement(interp, buffer);
+	tmp = Tcl_NewLongObj(longVar);
+	Tcl_AppendElement(interp, Tcl_GetString(tmp));
+	Tcl_DecrRefCount(tmp);
+	tmp = Tcl_NewLongObj((long)ulongVar);
+	Tcl_AppendElement(interp, Tcl_GetString(tmp));
+	Tcl_DecrRefCount(tmp);
+	Tcl_PrintDouble(NULL, (double)floatVar, buffer);
+	Tcl_AppendElement(interp, buffer);
+	tmp = Tcl_NewWideIntObj((Tcl_WideInt)uwideVar);
+	Tcl_AppendElement(interp, Tcl_GetString(tmp));
+	Tcl_DecrRefCount(tmp);
+    } else if (strcmp(argv[1], "set") == 0) {
+	int v;
+
+	if (argc != 16) {
+	    Tcl_AppendResult(interp, "wrong # args: should be \"",
+		    argv[0], " ", argv[1],
+		    " intValue realValue boolValue stringValue wideValue"
+		    " charValue ucharValue shortValue ushortValue uintValue"
+		    " longValue ulongValue floatValue uwideValue\"", NULL);
+	    return TCL_ERROR;
+	}
+	if (argv[2][0] != 0) {
+	    if (Tcl_GetInt(interp, argv[2], &intVar) != TCL_OK) {
+		return TCL_ERROR;
+	    }
+	}
+	if (argv[3][0] != 0) {
+	    if (Tcl_GetDouble(interp, argv[3], &realVar) != TCL_OK) {
+		return TCL_ERROR;
+	    }
+	}
+	if (argv[4][0] != 0) {
+	    if (Tcl_GetInt(interp, argv[4], &boolVar) != TCL_OK) {
+		return TCL_ERROR;
+	    }
+	}
+	if (argv[5][0] != 0) {
+	    if (stringVar != NULL) {
+		ckfree(stringVar);
+	    }
+	    if (strcmp(argv[5], "-") == 0) {
+		stringVar = NULL;
+	    } else {
+		stringVar = ckalloc(strlen(argv[5]) + 1);
+		strcpy(stringVar, argv[5]);
+	    }
+	}
+	if (argv[6][0] != 0) {
+	    tmp = Tcl_NewStringObj(argv[6], -1);
+	    if (Tcl_GetWideIntFromObj(interp, tmp, &wideVar) != TCL_OK) {
+		Tcl_DecrRefCount(tmp);
+		return TCL_ERROR;
+	    }
+	    Tcl_DecrRefCount(tmp);
+	}
+	if (argv[7][0]) {
+	    if (Tcl_GetInt(interp, argv[7], &v) != TCL_OK) {
+		return TCL_ERROR;
+	    }
+	    charVar = (char) v;
+	}
+	if (argv[8][0]) {
+	    if (Tcl_GetInt(interp, argv[8], &v) != TCL_OK) {
+		return TCL_ERROR;
+	    }
+	    ucharVar = (unsigned char) v;
+	}
+	if (argv[9][0]) {
+	    if (Tcl_GetInt(interp, argv[9], &v) != TCL_OK) {
+		return TCL_ERROR;
+	    }
+	    shortVar = (short) v;
+	}
+	if (argv[10][0]) {
+	    if (Tcl_GetInt(interp, argv[10], &v) != TCL_OK) {
+		return TCL_ERROR;
+	    }
+	    ushortVar = (unsigned short) v;
+	}
+	if (argv[11][0]) {
+	    if (Tcl_GetInt(interp, argv[11], &v) != TCL_OK) {
+		return TCL_ERROR;
+	    }
+	    uintVar = (unsigned int) v;
+	}
+	if (argv[12][0]) {
+	    if (Tcl_GetInt(interp, argv[12], &v) != TCL_OK) {
+		return TCL_ERROR;
+	    }
+	    longVar = (long) v;
+	}
+	if (argv[13][0]) {
+	    if (Tcl_GetInt(interp, argv[13], &v) != TCL_OK) {
+		return TCL_ERROR;
+	    }
+	    ulongVar = (unsigned long) v;
+	}
+	if (argv[14][0]) {
+	    double d;
+	    if (Tcl_GetDouble(interp, argv[14], &d) != TCL_OK) {
+		return TCL_ERROR;
+	    }
+	    floatVar = (float) d;
+	}
+	if (argv[15][0]) {
+	    Tcl_WideInt w;
+	    tmp = Tcl_NewStringObj(argv[15], -1);
+	    if (Tcl_GetWideIntFromObj(interp, tmp, &w) != TCL_OK) {
+		Tcl_DecrRefCount(tmp);
+		return TCL_ERROR;
+	    }
+	    Tcl_DecrRefCount(tmp);
+	    uwideVar = (Tcl_WideUInt) w;
+	}
+    } else if (strcmp(argv[1], "update") == 0) {
+	int v;
+
+	if (argc != 16) {
+	    Tcl_AppendResult(interp, "wrong # args: should be \"",
+		    argv[0], " ", argv[1],
+		    " intValue realValue boolValue stringValue wideValue"
+		    " charValue ucharValue shortValue ushortValue uintValue"
+		    " longValue ulongValue floatValue uwideValue\"", NULL);
+	    return TCL_ERROR;
+	}
+	if (argv[2][0] != 0) {
+	    if (Tcl_GetInt(interp, argv[2], &intVar) != TCL_OK) {
+		return TCL_ERROR;
+	    }
+	    Tcl_UpdateLinkedVar(interp, "int");
+	}
+	if (argv[3][0] != 0) {
+	    if (Tcl_GetDouble(interp, argv[3], &realVar) != TCL_OK) {
+		return TCL_ERROR;
+	    }
+	    Tcl_UpdateLinkedVar(interp, "real");
+	}
+	if (argv[4][0] != 0) {
+	    if (Tcl_GetInt(interp, argv[4], &boolVar) != TCL_OK) {
+		return TCL_ERROR;
+	    }
+	    Tcl_UpdateLinkedVar(interp, "bool");
+	}
+	if (argv[5][0] != 0) {
+	    if (stringVar != NULL) {
+		ckfree(stringVar);
+	    }
+	    if (strcmp(argv[5], "-") == 0) {
+		stringVar = NULL;
+	    } else {
+		stringVar = ckalloc(strlen(argv[5]) + 1);
+		strcpy(stringVar, argv[5]);
+	    }
+	    Tcl_UpdateLinkedVar(interp, "string");
+	}
+	if (argv[6][0] != 0) {
+	    tmp = Tcl_NewStringObj(argv[6], -1);
+	    if (Tcl_GetWideIntFromObj(interp, tmp, &wideVar) != TCL_OK) {
+		Tcl_DecrRefCount(tmp);
+		return TCL_ERROR;
+	    }
+	    Tcl_DecrRefCount(tmp);
+	    Tcl_UpdateLinkedVar(interp, "wide");
+	}
+	if (argv[7][0]) {
+	    if (Tcl_GetInt(interp, argv[7], &v) != TCL_OK) {
+		return TCL_ERROR;
+	    }
+	    charVar = (char) v;
+	    Tcl_UpdateLinkedVar(interp, "char");
+	}
+	if (argv[8][0]) {
+	    if (Tcl_GetInt(interp, argv[8], &v) != TCL_OK) {
+		return TCL_ERROR;
+	    }
+	    ucharVar = (unsigned char) v;
+	    Tcl_UpdateLinkedVar(interp, "uchar");
+	}
+	if (argv[9][0]) {
+	    if (Tcl_GetInt(interp, argv[9], &v) != TCL_OK) {
+		return TCL_ERROR;
+	    }
+	    shortVar = (short) v;
+	    Tcl_UpdateLinkedVar(interp, "short");
+	}
+	if (argv[10][0]) {
+	    if (Tcl_GetInt(interp, argv[10], &v) != TCL_OK) {
+		return TCL_ERROR;
+	    }
+	    ushortVar = (unsigned short) v;
+	    Tcl_UpdateLinkedVar(interp, "ushort");
+	}
+	if (argv[11][0]) {
+	    if (Tcl_GetInt(interp, argv[11], &v) != TCL_OK) {
+		return TCL_ERROR;
+	    }
+	    uintVar = (unsigned int) v;
+	    Tcl_UpdateLinkedVar(interp, "uint");
+	}
+	if (argv[12][0]) {
+	    if (Tcl_GetInt(interp, argv[12], &v) != TCL_OK) {
+		return TCL_ERROR;
+	    }
+	    longVar = (long) v;
+	    Tcl_UpdateLinkedVar(interp, "long");
+	}
+	if (argv[13][0]) {
+	    if (Tcl_GetInt(interp, argv[13], &v) != TCL_OK) {
+		return TCL_ERROR;
+	    }
+	    ulongVar = (unsigned long) v;
+	    Tcl_UpdateLinkedVar(interp, "ulong");
+	}
+	if (argv[14][0]) {
+	    double d;
+	    if (Tcl_GetDouble(interp, argv[14], &d) != TCL_OK) {
+		return TCL_ERROR;
+	    }
+	    floatVar = (float) d;
+	    Tcl_UpdateLinkedVar(interp, "float");
+	}
+	if (argv[15][0]) {
+	    Tcl_WideInt w;
+	    tmp = Tcl_NewStringObj(argv[15], -1);
+	    if (Tcl_GetWideIntFromObj(interp, tmp, &w) != TCL_OK) {
+		Tcl_DecrRefCount(tmp);
+		return TCL_ERROR;
+	    }
+	    Tcl_DecrRefCount(tmp);
+	    uwideVar = (Tcl_WideUInt) w;
+	    Tcl_UpdateLinkedVar(interp, "uwide");
+	}
+    } else {
+	Tcl_AppendResult(interp, "bad option \"", argv[1],
+		"\": should be create, delete, get, set, or update", NULL);
+	return TCL_ERROR;
+    }
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TestlocaleCmd --
+ *
+ *	This procedure implements the "testlocale" command.  It is used
+ *	to test the effects of setting different locales in Tcl.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	Modifies the current C locale.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+TestlocaleCmd(
+    ClientData clientData,	/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* The argument objects. */
+{
+    int index;
+    const char *locale;
+
+    static const char *const optionStrings[] = {
+	"ctype", "numeric", "time", "collate", "monetary",
+	"all",	NULL
+    };
+    static const int lcTypes[] = {
+	LC_CTYPE, LC_NUMERIC, LC_TIME, LC_COLLATE, LC_MONETARY,
+	LC_ALL
+    };
+
+    /*
+     * LC_CTYPE, etc. correspond to the indices for the strings.
+     */
+
+    if (objc < 2 || objc > 3) {
+	Tcl_WrongNumArgs(interp, 1, objv, "category ?locale?");
+	return TCL_ERROR;
+    }
+
+    if (Tcl_GetIndexFromObj(interp, objv[1], optionStrings, "option", 0,
+	    &index) != TCL_OK) {
+	return TCL_ERROR;
+    }
+
+    if (objc == 3) {
+	locale = Tcl_GetString(objv[2]);
+    } else {
+	locale = NULL;
+    }
+    locale = setlocale(lcTypes[index], locale);
+    if (locale) {
+	Tcl_SetStringObj(Tcl_GetObjResult(interp), locale, -1);
+    }
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TestMathFunc --
+ *
+ *	This is a user-defined math procedure to test out math procedures
+ *	with no arguments.
+ *
+ * Results:
+ *	A normal Tcl completion code.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+	/* ARGSUSED */
+static int
+TestMathFunc(
+    ClientData clientData,	/* Integer value to return. */
+    Tcl_Interp *interp,		/* Not used. */
+    Tcl_Value *args,		/* Not used. */
+    Tcl_Value *resultPtr)	/* Where to store result. */
+{
+    resultPtr->type = TCL_INT;
+    resultPtr->intValue = PTR2INT(clientData);
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TestMathFunc2 --
+ *
+ *	This is a user-defined math procedure to test out math procedures
+ *	that do have arguments, in this case 2.
+ *
+ * Results:
+ *	A normal Tcl completion code.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+	/* ARGSUSED */
+static int
+TestMathFunc2(
+    ClientData clientData,	/* Integer value to return. */
+    Tcl_Interp *interp,		/* Used to report errors. */
+    Tcl_Value *args,		/* Points to an array of two Tcl_Value structs
+				 * for the two arguments. */
+    Tcl_Value *resultPtr)	/* Where to store the result. */
+{
+    int result = TCL_OK;
+
+    /*
+     * Return the maximum of the two arguments with the correct type.
+     */
+
+    if (args[0].type == TCL_INT) {
+	int i0 = args[0].intValue;
+
+	if (args[1].type == TCL_INT) {
+	    int i1 = args[1].intValue;
+
+	    resultPtr->type = TCL_INT;
+	    resultPtr->intValue = ((i0 > i1)? i0 : i1);
+	} else if (args[1].type == TCL_DOUBLE) {
+	    double d0 = i0;
+	    double d1 = args[1].doubleValue;
+
+	    resultPtr->type = TCL_DOUBLE;
+	    resultPtr->doubleValue = ((d0 > d1)? d0 : d1);
+	} else if (args[1].type == TCL_WIDE_INT) {
+	    Tcl_WideInt w0 = Tcl_LongAsWide(i0);
+	    Tcl_WideInt w1 = args[1].wideValue;
+
+	    resultPtr->type = TCL_WIDE_INT;
+	    resultPtr->wideValue = ((w0 > w1)? w0 : w1);
+	} else {
+	    Tcl_SetResult(interp, "T3: wrong type for arg 2", TCL_STATIC);
+	    result = TCL_ERROR;
+	}
+    } else if (args[0].type == TCL_DOUBLE) {
+	double d0 = args[0].doubleValue;
+
+	if (args[1].type == TCL_INT) {
+	    double d1 = args[1].intValue;
+
+	    resultPtr->type = TCL_DOUBLE;
+	    resultPtr->doubleValue = ((d0 > d1)? d0 : d1);
+	} else if (args[1].type == TCL_DOUBLE) {
+	    double d1 = args[1].doubleValue;
+
+	    resultPtr->type = TCL_DOUBLE;
+	    resultPtr->doubleValue = ((d0 > d1)? d0 : d1);
+	} else if (args[1].type == TCL_WIDE_INT) {
+	    double d1 = Tcl_WideAsDouble(args[1].wideValue);
+
+	    resultPtr->type = TCL_DOUBLE;
+	    resultPtr->doubleValue = ((d0 > d1)? d0 : d1);
+	} else {
+	    Tcl_SetResult(interp, "T3: wrong type for arg 2", TCL_STATIC);
+	    result = TCL_ERROR;
+	}
+    } else if (args[0].type == TCL_WIDE_INT) {
+	Tcl_WideInt w0 = args[0].wideValue;
+
+	if (args[1].type == TCL_INT) {
+	    Tcl_WideInt w1 = Tcl_LongAsWide(args[1].intValue);
+
+	    resultPtr->type = TCL_WIDE_INT;
+	    resultPtr->wideValue = ((w0 > w1)? w0 : w1);
+	} else if (args[1].type == TCL_DOUBLE) {
+	    double d0 = Tcl_WideAsDouble(w0);
+	    double d1 = args[1].doubleValue;
+
+	    resultPtr->type = TCL_DOUBLE;
+	    resultPtr->doubleValue = ((d0 > d1)? d0 : d1);
+	} else if (args[1].type == TCL_WIDE_INT) {
+	    Tcl_WideInt w1 = args[1].wideValue;
+
+	    resultPtr->type = TCL_WIDE_INT;
+	    resultPtr->wideValue = ((w0 > w1)? w0 : w1);
+	} else {
+	    Tcl_SetResult(interp, "T3: wrong type for arg 2", TCL_STATIC);
+	    result = TCL_ERROR;
+	}
+    } else {
+	Tcl_SetResult(interp, "T3: wrong type for arg 1", TCL_STATIC);
+	result = TCL_ERROR;
+    }
+    return result;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * CleanupTestSetassocdataTests --
+ *
+ *	This function is called when an interpreter is deleted to clean
+ *	up any data left over from running the testsetassocdata command.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Releases storage.
+ *
+ *----------------------------------------------------------------------
+ */
+	/* ARGSUSED */
+static void
+CleanupTestSetassocdataTests(
+    ClientData clientData,	/* Data to be released. */
+    Tcl_Interp *interp)		/* Interpreter being deleted. */
+{
+    ckfree(clientData);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TestparserObjCmd --
+ *
+ *	This procedure implements the "testparser" command.  It is
+ *	used for testing the new Tcl script parser in Tcl 8.1.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+TestparserObjCmd(
+    ClientData clientData,	/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* The argument objects. */
+{
+    const char *script;
+    int length, dummy;
+    Tcl_Parse parse;
+
+    if (objc != 3) {
+	Tcl_WrongNumArgs(interp, 1, objv, "script length");
+	return TCL_ERROR;
+    }
+    script = Tcl_GetStringFromObj(objv[1], &dummy);
+    if (Tcl_GetIntFromObj(interp, objv[2], &length)) {
+	return TCL_ERROR;
+    }
+    if (length == 0) {
+	length = dummy;
+    }
+    if (Tcl_ParseCommand(interp, script, length, 0, &parse) != TCL_OK) {
+	Tcl_AddErrorInfo(interp, "\n    (remainder of script: \"");
+	Tcl_AddErrorInfo(interp, parse.term);
+	Tcl_AddErrorInfo(interp, "\")");
+	return TCL_ERROR;
+    }
+
+    /*
+     * The parse completed successfully.  Just print out the contents
+     * of the parse structure into the interpreter's result.
+     */
+
+    PrintParse(interp, &parse);
+    Tcl_FreeParse(&parse);
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TestexprparserObjCmd --
+ *
+ *	This procedure implements the "testexprparser" command.  It is
+ *	used for testing the new Tcl expression parser in Tcl 8.1.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+TestexprparserObjCmd(
+    ClientData clientData,	/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* The argument objects. */
+{
+    const char *script;
+    int length, dummy;
+    Tcl_Parse parse;
+
+    if (objc != 3) {
+	Tcl_WrongNumArgs(interp, 1, objv, "expr length");
+	return TCL_ERROR;
+    }
+    script = Tcl_GetStringFromObj(objv[1], &dummy);
+    if (Tcl_GetIntFromObj(interp, objv[2], &length)) {
+	return TCL_ERROR;
+    }
+    if (length == 0) {
+	length = dummy;
+    }
+    parse.commentStart = NULL;
+    parse.commentSize = 0;
+    parse.commandStart = NULL;
+    parse.commandSize = 0;
+    if (Tcl_ParseExpr(interp, script, length, &parse) != TCL_OK) {
+	Tcl_AddErrorInfo(interp, "\n    (remainder of expr: \"");
+	Tcl_AddErrorInfo(interp, parse.term);
+	Tcl_AddErrorInfo(interp, "\")");
+	return TCL_ERROR;
+    }
+
+    /*
+     * The parse completed successfully.  Just print out the contents
+     * of the parse structure into the interpreter's result.
+     */
+
+    PrintParse(interp, &parse);
+    Tcl_FreeParse(&parse);
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * PrintParse --
+ *
+ *	This procedure prints out the contents of a Tcl_Parse structure
+ *	in the result of an interpreter.
+ *
+ * Results:
+ *	Interp's result is set to a prettily formatted version of the
+ *	contents of parsePtr.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+PrintParse(
+    Tcl_Interp *interp,		/* Interpreter whose result is to be set to
+				 * the contents of a parse structure. */
+    Tcl_Parse *parsePtr)	/* Parse structure to print out. */
+{
+    Tcl_Obj *objPtr;
+    const char *typeString;
+    Tcl_Token *tokenPtr;
+    int i;
+
+    objPtr = Tcl_GetObjResult(interp);
+    if (parsePtr->commentSize > 0) {
+	Tcl_ListObjAppendElement(NULL, objPtr,
+		Tcl_NewStringObj(parsePtr->commentStart,
+			parsePtr->commentSize));
+    } else {
+	Tcl_ListObjAppendElement(NULL, objPtr, Tcl_NewStringObj("-", 1));
+    }
+    Tcl_ListObjAppendElement(NULL, objPtr,
+	    Tcl_NewStringObj(parsePtr->commandStart, parsePtr->commandSize));
+    Tcl_ListObjAppendElement(NULL, objPtr,
+	    Tcl_NewIntObj(parsePtr->numWords));
+    for (i = 0; i < parsePtr->numTokens; i++) {
+	tokenPtr = &parsePtr->tokenPtr[i];
+	switch (tokenPtr->type) {
+	case TCL_TOKEN_EXPAND_WORD:
+	    typeString = "expand";
+	    break;
+	case TCL_TOKEN_WORD:
+	    typeString = "word";
+	    break;
+	case TCL_TOKEN_SIMPLE_WORD:
+	    typeString = "simple";
+	    break;
+	case TCL_TOKEN_TEXT:
+	    typeString = "text";
+	    break;
+	case TCL_TOKEN_BS:
+	    typeString = "backslash";
+	    break;
+	case TCL_TOKEN_COMMAND:
+	    typeString = "command";
+	    break;
+	case TCL_TOKEN_VARIABLE:
+	    typeString = "variable";
+	    break;
+	case TCL_TOKEN_SUB_EXPR:
+	    typeString = "subexpr";
+	    break;
+	case TCL_TOKEN_OPERATOR:
+	    typeString = "operator";
+	    break;
+	default:
+	    typeString = "??";
+	    break;
+	}
+	Tcl_ListObjAppendElement(NULL, objPtr,
+		Tcl_NewStringObj(typeString, -1));
+	Tcl_ListObjAppendElement(NULL, objPtr,
+		Tcl_NewStringObj(tokenPtr->start, tokenPtr->size));
+	Tcl_ListObjAppendElement(NULL, objPtr,
+		Tcl_NewIntObj(tokenPtr->numComponents));
+    }
+    Tcl_ListObjAppendElement(NULL, objPtr,
+	    Tcl_NewStringObj(parsePtr->commandStart + parsePtr->commandSize,
+	    -1));
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TestparsevarObjCmd --
+ *
+ *	This procedure implements the "testparsevar" command.  It is
+ *	used for testing Tcl_ParseVar.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+TestparsevarObjCmd(
+    ClientData clientData,	/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* The argument objects. */
+{
+    const char *value, *name, *termPtr;
+
+    if (objc != 2) {
+	Tcl_WrongNumArgs(interp, 1, objv, "varName");
+	return TCL_ERROR;
+    }
+    name = Tcl_GetString(objv[1]);
+    value = Tcl_ParseVar(interp, name, &termPtr);
+    if (value == NULL) {
+	return TCL_ERROR;
+    }
+
+    Tcl_AppendElement(interp, value);
+    Tcl_AppendElement(interp, termPtr);
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TestparsevarnameObjCmd --
+ *
+ *	This procedure implements the "testparsevarname" command.  It is
+ *	used for testing the new Tcl script parser in Tcl 8.1.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+TestparsevarnameObjCmd(
+    ClientData clientData,	/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* The argument objects. */
+{
+    const char *script;
+    int append, length, dummy;
+    Tcl_Parse parse;
+
+    if (objc != 4) {
+	Tcl_WrongNumArgs(interp, 1, objv, "script length append");
+	return TCL_ERROR;
+    }
+    script = Tcl_GetStringFromObj(objv[1], &dummy);
+    if (Tcl_GetIntFromObj(interp, objv[2], &length)) {
+	return TCL_ERROR;
+    }
+    if (length == 0) {
+	length = dummy;
+    }
+    if (Tcl_GetIntFromObj(interp, objv[3], &append)) {
+	return TCL_ERROR;
+    }
+    if (Tcl_ParseVarName(interp, script, length, &parse, append) != TCL_OK) {
+	Tcl_AddErrorInfo(interp, "\n    (remainder of script: \"");
+	Tcl_AddErrorInfo(interp, parse.term);
+	Tcl_AddErrorInfo(interp, "\")");
+	return TCL_ERROR;
+    }
+
+    /*
+     * The parse completed successfully.  Just print out the contents
+     * of the parse structure into the interpreter's result.
+     */
+
+    parse.commentSize = 0;
+    parse.commandStart = script + parse.tokenPtr->size;
+    parse.commandSize = 0;
+    PrintParse(interp, &parse);
+    Tcl_FreeParse(&parse);
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TestregexpObjCmd --
+ *
+ *	This procedure implements the "testregexp" command. It is used to give
+ *	a direct interface for regexp flags. It's identical to
+ *	Tcl_RegexpObjCmd except for the -xflags option, and the consequences
+ *	thereof (including the REG_EXPECT kludge).
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+	/* ARGSUSED */
+static int
+TestregexpObjCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    int i, ii, indices, stringLength, match, about;
+    int hasxflags, cflags, eflags;
+    Tcl_RegExp regExpr;
+    const char *string;
+    Tcl_Obj *objPtr;
+    Tcl_RegExpInfo info;
+    static const char *const options[] = {
+	"-indices",	"-nocase",	"-about",	"-expanded",
+	"-line",	"-linestop",	"-lineanchor",
+	"-xflags",
+	"--",		NULL
+    };
+    enum options {
+	REGEXP_INDICES, REGEXP_NOCASE,	REGEXP_ABOUT,	REGEXP_EXPANDED,
+	REGEXP_MULTI,	REGEXP_NOCROSS,	REGEXP_NEWL,
+	REGEXP_XFLAGS,
+	REGEXP_LAST
+    };
+
+    indices = 0;
+    about = 0;
+    cflags = REG_ADVANCED;
+    eflags = 0;
+    hasxflags = 0;
+
+    for (i = 1; i < objc; i++) {
+	const char *name;
+	int index;
+
+	name = Tcl_GetString(objv[i]);
+	if (name[0] != '-') {
+	    break;
+	}
+	if (Tcl_GetIndexFromObj(interp, objv[i], options, "switch", TCL_EXACT,
+		&index) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	switch ((enum options) index) {
+	case REGEXP_INDICES:
+	    indices = 1;
+	    break;
+	case REGEXP_NOCASE:
+	    cflags |= REG_ICASE;
+	    break;
+	case REGEXP_ABOUT:
+	    about = 1;
+	    break;
+	case REGEXP_EXPANDED:
+	    cflags |= REG_EXPANDED;
+	    break;
+	case REGEXP_MULTI:
+	    cflags |= REG_NEWLINE;
+	    break;
+	case REGEXP_NOCROSS:
+	    cflags |= REG_NLSTOP;
+	    break;
+	case REGEXP_NEWL:
+	    cflags |= REG_NLANCH;
+	    break;
+	case REGEXP_XFLAGS:
+	    hasxflags = 1;
+	    break;
+	case REGEXP_LAST:
+	    i++;
+	    goto endOfForLoop;
+	}
+    }
+
+  endOfForLoop:
+    if (objc - i < hasxflags + 2 - about) {
+	Tcl_WrongNumArgs(interp, 1, objv,
+		"?-switch ...? exp string ?matchVar? ?subMatchVar ...?");
+	return TCL_ERROR;
+    }
+    objc -= i;
+    objv += i;
+
+    if (hasxflags) {
+	string = Tcl_GetStringFromObj(objv[0], &stringLength);
+	TestregexpXflags(string, stringLength, &cflags, &eflags);
+	objc--;
+	objv++;
+    }
+
+    regExpr = Tcl_GetRegExpFromObj(interp, objv[0], cflags);
+    if (regExpr == NULL) {
+	return TCL_ERROR;
+    }
+
+    if (about) {
+	if (TclRegAbout(interp, regExpr) < 0) {
+	    return TCL_ERROR;
+	}
+	return TCL_OK;
+    }
+
+    objPtr = objv[1];
+    match = Tcl_RegExpExecObj(interp, regExpr, objPtr, 0 /* offset */,
+	    objc-2 /* nmatches */, eflags);
+
+    if (match < 0) {
+	return TCL_ERROR;
+    }
+    if (match == 0) {
+	/*
+	 * Set the interpreter's object result to an integer object w/
+	 * value 0.
+	 */
+
+	Tcl_SetIntObj(Tcl_GetObjResult(interp), 0);
+	if (objc > 2 && (cflags&REG_EXPECT) && indices) {
+	    const char *varName;
+	    const char *value;
+	    int start, end;
+	    char resinfo[TCL_INTEGER_SPACE * 2];
+
+	    varName = Tcl_GetString(objv[2]);
+	    TclRegExpRangeUniChar(regExpr, -1, &start, &end);
+	    sprintf(resinfo, "%d %d", start, end-1);
+	    value = Tcl_SetVar(interp, varName, resinfo, 0);
+	    if (value == NULL) {
+		Tcl_AppendResult(interp, "couldn't set variable \"",
+			varName, "\"", NULL);
+		return TCL_ERROR;
+	    }
+	} else if (cflags & TCL_REG_CANMATCH) {
+	    const char *varName;
+	    const char *value;
+	    char resinfo[TCL_INTEGER_SPACE * 2];
+
+	    Tcl_RegExpGetInfo(regExpr, &info);
+	    varName = Tcl_GetString(objv[2]);
+	    sprintf(resinfo, "%ld", info.extendStart);
+	    value = Tcl_SetVar(interp, varName, resinfo, 0);
+	    if (value == NULL) {
+		Tcl_AppendResult(interp, "couldn't set variable \"",
+			varName, "\"", NULL);
+		return TCL_ERROR;
+	    }
+	}
+	return TCL_OK;
+    }
+
+    /*
+     * If additional variable names have been specified, return
+     * index information in those variables.
+     */
+
+    objc -= 2;
+    objv += 2;
+
+    Tcl_RegExpGetInfo(regExpr, &info);
+    for (i = 0; i < objc; i++) {
+	int start, end;
+	Tcl_Obj *newPtr, *varPtr, *valuePtr;
+
+	varPtr = objv[i];
+	ii = ((cflags&REG_EXPECT) && i == objc-1) ? -1 : i;
+	if (indices) {
+	    Tcl_Obj *objs[2];
+
+	    if (ii == -1) {
+		TclRegExpRangeUniChar(regExpr, ii, &start, &end);
+	    } else if (ii > info.nsubs) {
+		start = -1;
+		end = -1;
+	    } else {
+		start = info.matches[ii].start;
+		end = info.matches[ii].end;
+	    }
+
+	    /*
+	     * Adjust index so it refers to the last character in the match
+	     * instead of the first character after the match.
+	     */
+
+	    if (end >= 0) {
+		end--;
+	    }
+
+	    objs[0] = Tcl_NewLongObj(start);
+	    objs[1] = Tcl_NewLongObj(end);
+
+	    newPtr = Tcl_NewListObj(2, objs);
+	} else {
+	    if (ii == -1) {
+		TclRegExpRangeUniChar(regExpr, ii, &start, &end);
+		newPtr = Tcl_GetRange(objPtr, start, end);
+	    } else if (ii > info.nsubs) {
+		newPtr = Tcl_NewObj();
+	    } else {
+		newPtr = Tcl_GetRange(objPtr, info.matches[ii].start,
+			info.matches[ii].end - 1);
+	    }
+	}
+	valuePtr = Tcl_ObjSetVar2(interp, varPtr, NULL, newPtr, TCL_LEAVE_ERR_MSG);
+	if (valuePtr == NULL) {
+	    return TCL_ERROR;
+	}
+    }
+
+    /*
+     * Set the interpreter's object result to an integer object w/ value 1.
+     */
+
+    Tcl_SetIntObj(Tcl_GetObjResult(interp), 1);
+    return TCL_OK;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * TestregexpXflags --
+ *
+ *	Parse a string of extended regexp flag letters, for testing.
+ *
+ * Results:
+ *	No return value (you're on your own for errors here).
+ *
+ * Side effects:
+ *	Modifies *cflagsPtr, a regcomp flags word, and *eflagsPtr, a
+ *	regexec flags word, as appropriate.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+TestregexpXflags(
+    const char *string,	/* The string of flags. */
+    int length,			/* The length of the string in bytes. */
+    int *cflagsPtr,		/* compile flags word */
+    int *eflagsPtr)		/* exec flags word */
+{
+    int i, cflags, eflags;
+
+    cflags = *cflagsPtr;
+    eflags = *eflagsPtr;
+    for (i = 0; i < length; i++) {
+	switch (string[i]) {
+	case 'a':
+	    cflags |= REG_ADVF;
+	    break;
+	case 'b':
+	    cflags &= ~REG_ADVANCED;
+	    break;
+	case 'c':
+	    cflags |= TCL_REG_CANMATCH;
+	    break;
+	case 'e':
+	    cflags &= ~REG_ADVANCED;
+	    cflags |= REG_EXTENDED;
+	    break;
+	case 'q':
+	    cflags &= ~REG_ADVANCED;
+	    cflags |= REG_QUOTE;
+	    break;
+	case 'o':			/* o for opaque */
+	    cflags |= REG_NOSUB;
+	    break;
+	case 's':			/* s for start */
+	    cflags |= REG_BOSONLY;
+	    break;
+	case '+':
+	    cflags |= REG_FAKE;
+	    break;
+	case ',':
+	    cflags |= REG_PROGRESS;
+	    break;
+	case '.':
+	    cflags |= REG_DUMP;
+	    break;
+	case ':':
+	    eflags |= REG_MTRACE;
+	    break;
+	case ';':
+	    eflags |= REG_FTRACE;
+	    break;
+	case '^':
+	    eflags |= REG_NOTBOL;
+	    break;
+	case '$':
+	    eflags |= REG_NOTEOL;
+	    break;
+	case 't':
+	    cflags |= REG_EXPECT;
+	    break;
+	case '%':
+	    eflags |= REG_SMALL;
+	    break;
+	}
+    }
+
+    *cflagsPtr = cflags;
+    *eflagsPtr = eflags;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TestreturnObjCmd --
+ *
+ *	This procedure implements the "testreturn" command. It is
+ *	used to verify that a
+ *		return TCL_RETURN;
+ *	has same behavior as
+ *		return Tcl_SetReturnOptions(interp, Tcl_NewObj());
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+	/* ARGSUSED */
+static int
+TestreturnObjCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    return TCL_RETURN;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TestsetassocdataCmd --
+ *
+ *	This procedure implements the "testsetassocdata" command. It is used
+ *	to test Tcl_SetAssocData.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	Modifies or creates an association between a key and associated
+ *	data for this interpreter.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+TestsetassocdataCmd(
+    ClientData clientData,	/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int argc,			/* Number of arguments. */
+    const char **argv)		/* Argument strings. */
+{
+    char *buf, *oldData;
+    Tcl_InterpDeleteProc *procPtr;
+
+    if (argc != 3) {
+	Tcl_AppendResult(interp, "wrong # arguments: should be \"", argv[0],
+		" data_key data_item\"", NULL);
+	return TCL_ERROR;
+    }
+
+    buf = ckalloc(strlen(argv[2]) + 1);
+    strcpy(buf, argv[2]);
+
+    /*
+     * If we previously associated a malloced value with the variable,
+     * free it before associating a new value.
+     */
+
+    oldData = (char *) Tcl_GetAssocData(interp, argv[1], &procPtr);
+    if ((oldData != NULL) && (procPtr == CleanupTestSetassocdataTests)) {
+	ckfree(oldData);
+    }
+
+    Tcl_SetAssocData(interp, argv[1], CleanupTestSetassocdataTests,
+	(ClientData) buf);
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TestsetplatformCmd --
+ *
+ *	This procedure implements the "testsetplatform" command. It is
+ *	used to change the tclPlatform global variable so all file
+ *	name conversions can be tested on a single platform.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	Sets the tclPlatform global variable.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+TestsetplatformCmd(
+    ClientData clientData,	/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int argc,			/* Number of arguments. */
+    const char **argv)		/* Argument strings. */
+{
+    size_t length;
+    TclPlatformType *platform;
+
+    platform = TclGetPlatform();
+
+    if (argc != 2) {
+	Tcl_AppendResult(interp, "wrong # arguments: should be \"", argv[0],
+		" platform\"", NULL);
+	return TCL_ERROR;
+    }
+
+    length = strlen(argv[1]);
+    if (strncmp(argv[1], "unix", length) == 0) {
+	*platform = TCL_PLATFORM_UNIX;
+    } else if (strncmp(argv[1], "windows", length) == 0) {
+	*platform = TCL_PLATFORM_WINDOWS;
+    } else {
+	Tcl_AppendResult(interp, "unsupported platform: should be one of "
+		"unix, or windows", NULL);
+	return TCL_ERROR;
+    }
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TeststaticpkgCmd --
+ *
+ *	This procedure implements the "teststaticpkg" command.
+ *	It is used to test the procedure Tcl_StaticPackage.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	When the packge given by argv[1] is loaded into an interpeter,
+ *	variable "x" in that interpreter is set to "loaded".
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+TeststaticpkgCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int argc,			/* Number of arguments. */
+    const char **argv)		/* Argument strings. */
+{
+    int safe, loaded;
+
+    if (argc != 4) {
+	Tcl_AppendResult(interp, "wrong # arguments: should be \"",
+		argv[0], " pkgName safe loaded\"", NULL);
+	return TCL_ERROR;
+    }
+    if (Tcl_GetInt(interp, argv[2], &safe) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    if (Tcl_GetInt(interp, argv[3], &loaded) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    tclStubsPtr->tcl_StaticPackage((loaded) ? interp : NULL, argv[1],
+	    StaticInitProc, (safe) ? StaticInitProc : NULL);
+    return TCL_OK;
+}
+
+static int
+StaticInitProc(
+    Tcl_Interp *interp)		/* Interpreter in which package is supposedly
+				 * being loaded. */
+{
+    Tcl_SetVar(interp, "x", "loaded", TCL_GLOBAL_ONLY);
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TesttranslatefilenameCmd --
+ *
+ *	This procedure implements the "testtranslatefilename" command.
+ *	It is used to test the Tcl_TranslateFileName command.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+TesttranslatefilenameCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int argc,			/* Number of arguments. */
+    const char **argv)		/* Argument strings. */
+{
+    Tcl_DString buffer;
+    const char *result;
+
+    if (argc != 2) {
+	Tcl_AppendResult(interp, "wrong # arguments: should be \"",
+		argv[0], " path\"", NULL);
+	return TCL_ERROR;
+    }
+    result = Tcl_TranslateFileName(interp, argv[1], &buffer);
+    if (result == NULL) {
+	return TCL_ERROR;
+    }
+    Tcl_AppendResult(interp, result, NULL);
+    Tcl_DStringFree(&buffer);
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TestupvarCmd --
+ *
+ *	This procedure implements the "testupvar2" command.  It is used
+ *	to test Tcl_UpVar and Tcl_UpVar2.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	Creates or modifies an "upvar" reference.
+ *
+ *----------------------------------------------------------------------
+ */
+
+	/* ARGSUSED */
+static int
+TestupvarCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int argc,			/* Number of arguments. */
+    const char **argv)		/* Argument strings. */
+{
+    int flags = 0;
+
+    if ((argc != 5) && (argc != 6)) {
+	Tcl_AppendResult(interp, "wrong # arguments: should be \"",
+		argv[0], " level name ?name2? dest global\"", NULL);
+	return TCL_ERROR;
+    }
+
+    if (argc == 5) {
+	if (strcmp(argv[4], "global") == 0) {
+	    flags = TCL_GLOBAL_ONLY;
+	} else if (strcmp(argv[4], "namespace") == 0) {
+	    flags = TCL_NAMESPACE_ONLY;
+	}
+	return Tcl_UpVar(interp, argv[1], argv[2], argv[3], flags);
+    } else {
+	if (strcmp(argv[5], "global") == 0) {
+	    flags = TCL_GLOBAL_ONLY;
+	} else if (strcmp(argv[5], "namespace") == 0) {
+	    flags = TCL_NAMESPACE_ONLY;
+	}
+	return Tcl_UpVar2(interp, argv[1], argv[2],
+		(argv[3][0] == 0) ? NULL : argv[3], argv[4],
+		flags);
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TestseterrorcodeCmd --
+ *
+ *	This procedure implements the "testseterrorcodeCmd".  This tests up to
+ *	five elements passed to the Tcl_SetErrorCode command.
+ *
+ * Results:
+ *	A standard Tcl result. Always returns TCL_ERROR so that
+ *	the error code can be tested.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+	/* ARGSUSED */
+static int
+TestseterrorcodeCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int argc,			/* Number of arguments. */
+    const char **argv)		/* Argument strings. */
+{
+    if (argc > 6) {
+	Tcl_SetResult(interp, "too many args", TCL_STATIC);
+	return TCL_ERROR;
+    }
+    switch (argc) {
+    case 1:
+	Tcl_SetErrorCode(interp, "NONE", NULL);
+	break;
+    case 2:
+	Tcl_SetErrorCode(interp, argv[1], NULL);
+	break;
+    case 3:
+	Tcl_SetErrorCode(interp, argv[1], argv[2], NULL);
+	break;
+    case 4:
+	Tcl_SetErrorCode(interp, argv[1], argv[2], argv[3], NULL);
+	break;
+    case 5:
+	Tcl_SetErrorCode(interp, argv[1], argv[2], argv[3], argv[4], NULL);
+	break;
+    case 6:
+	Tcl_SetErrorCode(interp, argv[1], argv[2], argv[3], argv[4],
+		argv[5], NULL);
+    }
+    return TCL_ERROR;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TestsetobjerrorcodeCmd --
+ *
+ *	This procedure implements the "testsetobjerrorcodeCmd".
+ *	This tests the Tcl_SetObjErrorCode function.
+ *
+ * Results:
+ *	A standard Tcl result. Always returns TCL_ERROR so that
+ *	the error code can be tested.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+	/* ARGSUSED */
+static int
+TestsetobjerrorcodeCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* The argument objects. */
+{
+    Tcl_SetObjErrorCode(interp, Tcl_ConcatObj(objc - 1, objv + 1));
+    return TCL_ERROR;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TestfeventCmd --
+ *
+ *	This procedure implements the "testfevent" command.  It is
+ *	used for testing the "fileevent" command.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	Creates and deletes interpreters.
+ *
+ *----------------------------------------------------------------------
+ */
+
+	/* ARGSUSED */
+static int
+TestfeventCmd(
+    ClientData clientData,	/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int argc,			/* Number of arguments. */
+    const char **argv)		/* Argument strings. */
+{
+    static Tcl_Interp *interp2 = NULL;
+    int code;
+    Tcl_Channel chan;
+
+    if (argc < 2) {
+	Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
+		" option ?arg ...?", NULL);
+	return TCL_ERROR;
+    }
+    if (strcmp(argv[1], "cmd") == 0) {
+	if (argc != 3) {
+	    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
+		    " cmd script", NULL);
+	    return TCL_ERROR;
+	}
+	if (interp2 != NULL) {
+	    code = Tcl_EvalEx(interp2, argv[2], -1, TCL_EVAL_GLOBAL);
+	    Tcl_SetObjResult(interp, Tcl_GetObjResult(interp2));
+	    return code;
+	} else {
+	    Tcl_AppendResult(interp,
+		    "called \"testfevent code\" before \"testfevent create\"",
+		    NULL);
+	    return TCL_ERROR;
+	}
+    } else if (strcmp(argv[1], "create") == 0) {
+	if (interp2 != NULL) {
+	    Tcl_DeleteInterp(interp2);
+	}
+	interp2 = Tcl_CreateInterp();
+	return Tcl_Init(interp2);
+    } else if (strcmp(argv[1], "delete") == 0) {
+	if (interp2 != NULL) {
+	    Tcl_DeleteInterp(interp2);
+	}
+	interp2 = NULL;
+    } else if (strcmp(argv[1], "share") == 0) {
+	if (interp2 != NULL) {
+	    chan = Tcl_GetChannel(interp, argv[2], NULL);
+	    if (chan == (Tcl_Channel) NULL) {
+		return TCL_ERROR;
+	    }
+	    Tcl_RegisterChannel(interp2, chan);
+	}
+    }
+
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TestpanicCmd --
+ *
+ *	Calls the panic routine.
+ *
+ * Results:
+ *	Always returns TCL_OK.
+ *
+ * Side effects:
+ *	May exit application.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+TestpanicCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int argc,			/* Number of arguments. */
+    const char **argv)		/* Argument strings. */
+{
+    const char *argString;
+
+    /*
+     *  Put the arguments into a var args structure
+     *  Append all of the arguments together separated by spaces
+     */
+
+    argString = Tcl_Merge(argc-1, argv+1);
+    Tcl_Panic("%s", argString);
+    ckfree(argString);
+
+    return TCL_OK;
+}
+
+static int
+TestfileCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int argc,			/* Number of arguments. */
+    Tcl_Obj *const argv[])	/* The argument objects. */
+{
+    int force, i, j, result;
+    Tcl_Obj *error = NULL;
+    const char *subcmd;
+
+    if (argc < 3) {
+	return TCL_ERROR;
+    }
+
+    force = 0;
+    i = 2;
+    if (strcmp(Tcl_GetString(argv[2]), "-force") == 0) {
+	force = 1;
+	i = 3;
+    }
+
+    if (argc - i > 2) {
+	return TCL_ERROR;
+    }
+
+    for (j = i; j < argc; j++) {
+	if (Tcl_FSGetNormalizedPath(interp, argv[j]) == NULL) {
+	    return TCL_ERROR;
+	}
+    }
+
+    subcmd = Tcl_GetString(argv[1]);
+
+    if (strcmp(subcmd, "mv") == 0) {
+	result = TclpObjRenameFile(argv[i], argv[i + 1]);
+    } else if (strcmp(subcmd, "cp") == 0) {
+	result = TclpObjCopyFile(argv[i], argv[i + 1]);
+    } else if (strcmp(subcmd, "rm") == 0) {
+	result = TclpObjDeleteFile(argv[i]);
+    } else if (strcmp(subcmd, "mkdir") == 0) {
+	result = TclpObjCreateDirectory(argv[i]);
+    } else if (strcmp(subcmd, "cpdir") == 0) {
+	result = TclpObjCopyDirectory(argv[i], argv[i + 1], &error);
+    } else if (strcmp(subcmd, "rmdir") == 0) {
+	result = TclpObjRemoveDirectory(argv[i], force, &error);
+    } else {
+	result = TCL_ERROR;
+	goto end;
+    }
+
+    if (result != TCL_OK) {
+	if (error != NULL) {
+	    if (Tcl_GetString(error)[0] != '\0') {
+		Tcl_AppendResult(interp, Tcl_GetString(error), " ", NULL);
+	    }
+	    Tcl_DecrRefCount(error);
+	}
+	Tcl_AppendResult(interp, Tcl_ErrnoId(), NULL);
+    }
+
+  end:
+    return result;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TestgetvarfullnameCmd --
+ *
+ *	Implements the "testgetvarfullname" cmd that is used when testing
+ *	the Tcl_GetVariableFullName procedure.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+TestgetvarfullnameCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* The argument objects. */
+{
+    const char *name, *arg;
+    int flags = 0;
+    Tcl_Namespace *namespacePtr;
+    Tcl_CallFrame *framePtr;
+    Tcl_Var variable;
+
+    if (objc != 3) {
+	Tcl_WrongNumArgs(interp, 1, objv, "name scope");
+	return TCL_ERROR;
+    }
+
+    name = Tcl_GetString(objv[1]);
+
+    arg = Tcl_GetString(objv[2]);
+    if (strcmp(arg, "global") == 0) {
+	flags = TCL_GLOBAL_ONLY;
+    } else if (strcmp(arg, "namespace") == 0) {
+	flags = TCL_NAMESPACE_ONLY;
+    }
+
+    /*
+     * This command, like any other created with Tcl_Create[Obj]Command, runs
+     * in the global namespace. As a "namespace-aware" command that needs to
+     * run in a particular namespace, it must activate that namespace itself.
+     */
+
+    if (flags == TCL_NAMESPACE_ONLY) {
+	namespacePtr = Tcl_FindNamespace(interp, "::test_ns_var", NULL,
+		TCL_LEAVE_ERR_MSG);
+	if (namespacePtr == NULL) {
+	    return TCL_ERROR;
+	}
+	(void) TclPushStackFrame(interp, &framePtr, namespacePtr,
+		/*isProcCallFrame*/ 0);
+    }
+
+    variable = Tcl_FindNamespaceVar(interp, name, NULL,
+	    (flags | TCL_LEAVE_ERR_MSG));
+
+    if (flags == TCL_NAMESPACE_ONLY) {
+	TclPopStackFrame(interp);
+    }
+    if (variable == (Tcl_Var) NULL) {
+	return TCL_ERROR;
+    }
+    Tcl_GetVariableFullName(interp, variable, Tcl_GetObjResult(interp));
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * GetTimesObjCmd --
+ *
+ *	This procedure implements the "gettimes" command.  It is used for
+ *	computing the time needed for various basic operations such as reading
+ *	variables, allocating memory, sprintf, converting variables, etc.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	Allocates and frees memory, sets a variable "a" in the interpreter.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+GetTimesObjCmd(
+    ClientData unused,		/* Unused. */
+    Tcl_Interp *interp,		/* The current interpreter. */
+    int notused1,			/* Number of arguments. */
+    Tcl_Obj *const notused2[])	/* The argument objects. */
+{
+    Interp *iPtr = (Interp *) interp;
+    int i, n;
+    double timePer;
+    Tcl_Time start, stop;
+    Tcl_Obj *objPtr, **objv;
+    const char *s;
+    char newString[TCL_INTEGER_SPACE];
+
+    /* alloc & free 100000 times */
+    fprintf(stderr, "alloc & free 100000 6 word items\n");
+    Tcl_GetTime(&start);
+    for (i = 0;  i < 100000;  i++) {
+	objPtr = ckalloc(sizeof(Tcl_Obj));
+	ckfree(objPtr);
+    }
+    Tcl_GetTime(&stop);
+    timePer = (stop.sec - start.sec)*1000000 + (stop.usec - start.usec);
+    fprintf(stderr, "   %.3f usec per alloc+free\n", timePer/100000);
+
+    /* alloc 5000 times */
+    fprintf(stderr, "alloc 5000 6 word items\n");
+    objv = ckalloc(5000 * sizeof(Tcl_Obj *));
+    Tcl_GetTime(&start);
+    for (i = 0;  i < 5000;  i++) {
+	objv[i] = ckalloc(sizeof(Tcl_Obj));
+    }
+    Tcl_GetTime(&stop);
+    timePer = (stop.sec - start.sec)*1000000 + (stop.usec - start.usec);
+    fprintf(stderr, "   %.3f usec per alloc\n", timePer/5000);
+
+    /* free 5000 times */
+    fprintf(stderr, "free 5000 6 word items\n");
+    Tcl_GetTime(&start);
+    for (i = 0;  i < 5000;  i++) {
+	ckfree(objv[i]);
+    }
+    Tcl_GetTime(&stop);
+    timePer = (stop.sec - start.sec)*1000000 + (stop.usec - start.usec);
+    fprintf(stderr, "   %.3f usec per free\n", timePer/5000);
+
+    /* Tcl_NewObj 5000 times */
+    fprintf(stderr, "Tcl_NewObj 5000 times\n");
+    Tcl_GetTime(&start);
+    for (i = 0;  i < 5000;  i++) {
+	objv[i] = Tcl_NewObj();
+    }
+    Tcl_GetTime(&stop);
+    timePer = (stop.sec - start.sec)*1000000 + (stop.usec - start.usec);
+    fprintf(stderr, "   %.3f usec per Tcl_NewObj\n", timePer/5000);
+
+    /* Tcl_DecrRefCount 5000 times */
+    fprintf(stderr, "Tcl_DecrRefCount 5000 times\n");
+    Tcl_GetTime(&start);
+    for (i = 0;  i < 5000;  i++) {
+	objPtr = objv[i];
+	Tcl_DecrRefCount(objPtr);
+    }
+    Tcl_GetTime(&stop);
+    timePer = (stop.sec - start.sec)*1000000 + (stop.usec - start.usec);
+    fprintf(stderr, "   %.3f usec per Tcl_DecrRefCount\n", timePer/5000);
+    ckfree(objv);
+
+    /* TclGetString 100000 times */
+    fprintf(stderr, "TclGetStringFromObj of \"12345\" 100000 times\n");
+    objPtr = Tcl_NewStringObj("12345", -1);
+    Tcl_GetTime(&start);
+    for (i = 0;  i < 100000;  i++) {
+	(void) TclGetString(objPtr);
+    }
+    Tcl_GetTime(&stop);
+    timePer = (stop.sec - start.sec)*1000000 + (stop.usec - start.usec);
+    fprintf(stderr, "   %.3f usec per TclGetStringFromObj of \"12345\"\n",
+	    timePer/100000);
+
+    /* Tcl_GetIntFromObj 100000 times */
+    fprintf(stderr, "Tcl_GetIntFromObj of \"12345\" 100000 times\n");
+    Tcl_GetTime(&start);
+    for (i = 0;  i < 100000;  i++) {
+	if (Tcl_GetIntFromObj(interp, objPtr, &n) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+    }
+    Tcl_GetTime(&stop);
+    timePer = (stop.sec - start.sec)*1000000 + (stop.usec - start.usec);
+    fprintf(stderr, "   %.3f usec per Tcl_GetIntFromObj of \"12345\"\n",
+	    timePer/100000);
+    Tcl_DecrRefCount(objPtr);
+
+    /* Tcl_GetInt 100000 times */
+    fprintf(stderr, "Tcl_GetInt of \"12345\" 100000 times\n");
+    Tcl_GetTime(&start);
+    for (i = 0;  i < 100000;  i++) {
+	if (Tcl_GetInt(interp, "12345", &n) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+    }
+    Tcl_GetTime(&stop);
+    timePer = (stop.sec - start.sec)*1000000 + (stop.usec - start.usec);
+    fprintf(stderr, "   %.3f usec per Tcl_GetInt of \"12345\"\n",
+	    timePer/100000);
+
+    /* sprintf 100000 times */
+    fprintf(stderr, "sprintf of 12345 100000 times\n");
+    Tcl_GetTime(&start);
+    for (i = 0;  i < 100000;  i++) {
+	sprintf(newString, "%d", 12345);
+    }
+    Tcl_GetTime(&stop);
+    timePer = (stop.sec - start.sec)*1000000 + (stop.usec - start.usec);
+    fprintf(stderr, "   %.3f usec per sprintf of 12345\n",
+	    timePer/100000);
+
+    /* hashtable lookup 100000 times */
+    fprintf(stderr, "hashtable lookup of \"gettimes\" 100000 times\n");
+    Tcl_GetTime(&start);
+    for (i = 0;  i < 100000;  i++) {
+	(void) Tcl_FindHashEntry(&iPtr->globalNsPtr->cmdTable, "gettimes");
+    }
+    Tcl_GetTime(&stop);
+    timePer = (stop.sec - start.sec)*1000000 + (stop.usec - start.usec);
+    fprintf(stderr, "   %.3f usec per hashtable lookup of \"gettimes\"\n",
+	    timePer/100000);
+
+    /* Tcl_SetVar 100000 times */
+    fprintf(stderr, "Tcl_SetVar of \"12345\" 100000 times\n");
+    Tcl_GetTime(&start);
+    for (i = 0;  i < 100000;  i++) {
+	s = Tcl_SetVar(interp, "a", "12345", TCL_LEAVE_ERR_MSG);
+	if (s == NULL) {
+	    return TCL_ERROR;
+	}
+    }
+    Tcl_GetTime(&stop);
+    timePer = (stop.sec - start.sec)*1000000 + (stop.usec - start.usec);
+    fprintf(stderr, "   %.3f usec per Tcl_SetVar of a to \"12345\"\n",
+	    timePer/100000);
+
+    /* Tcl_GetVar 100000 times */
+    fprintf(stderr, "Tcl_GetVar of a==\"12345\" 100000 times\n");
+    Tcl_GetTime(&start);
+    for (i = 0;  i < 100000;  i++) {
+	s = Tcl_GetVar(interp, "a", TCL_LEAVE_ERR_MSG);
+	if (s == NULL) {
+	    return TCL_ERROR;
+	}
+    }
+    Tcl_GetTime(&stop);
+    timePer = (stop.sec - start.sec)*1000000 + (stop.usec - start.usec);
+    fprintf(stderr, "   %.3f usec per Tcl_GetVar of a==\"12345\"\n",
+	    timePer/100000);
+
+    Tcl_ResetResult(interp);
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * NoopCmd --
+ *
+ *	This procedure is just used to time the overhead involved in
+ *	parsing and invoking a command.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+NoopCmd(
+    ClientData unused,		/* Unused. */
+    Tcl_Interp *interp,		/* The current interpreter. */
+    int argc,			/* The number of arguments. */
+    const char **argv)		/* The argument strings. */
+{
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * NoopObjCmd --
+ *
+ *	This object-based procedure is just used to time the overhead
+ *	involved in parsing and invoking a command.
+ *
+ * Results:
+ *	Returns the TCL_OK result code.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+NoopObjCmd(
+    ClientData unused,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* The argument objects. */
+{
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TestbytestringObjCmd --
+ *
+ *	This object-based procedure constructs a string which can
+ *	possibly contain invalid UTF-8 bytes.
+ *
+ * Results:
+ *	Returns the TCL_OK result code.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+TestbytestringObjCmd(
+    ClientData unused,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* The argument objects. */
+{
+    int n;
+    const char *p;
+
+    if (objc != 2) {
+	Tcl_WrongNumArgs(interp, 1, objv, "bytearray");
+	return TCL_ERROR;
+    }
+    p = (const char *)Tcl_GetByteArrayFromObj(objv[1], &n);
+    Tcl_SetObjResult(interp, Tcl_NewStringObj(p, n));
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TestsetCmd --
+ *
+ *	Implements the "testset{err,noerr}" cmds that are used when testing
+ *	Tcl_Set/GetVar C Api with/without TCL_LEAVE_ERR_MSG flag
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *     Variables may be set.
+ *
+ *----------------------------------------------------------------------
+ */
+
+	/* ARGSUSED */
+static int
+TestsetCmd(
+    ClientData data,		/* Additional flags for Get/SetVar2. */
+    register Tcl_Interp *interp,/* Current interpreter. */
+    int argc,			/* Number of arguments. */
+    const char **argv)		/* Argument strings. */
+{
+    int flags = PTR2INT(data);
+    const char *value;
+
+    if (argc == 2) {
+	Tcl_SetResult(interp, "before get", TCL_STATIC);
+	value = Tcl_GetVar2(interp, argv[1], NULL, flags);
+	if (value == NULL) {
+	    return TCL_ERROR;
+	}
+	Tcl_AppendElement(interp, value);
+	return TCL_OK;
+    } else if (argc == 3) {
+	Tcl_SetResult(interp, "before set", TCL_STATIC);
+	value = Tcl_SetVar2(interp, argv[1], NULL, argv[2], flags);
+	if (value == NULL) {
+	    return TCL_ERROR;
+	}
+	Tcl_AppendElement(interp, value);
+	return TCL_OK;
+    } else {
+	Tcl_AppendResult(interp, "wrong # args: should be \"",
+		argv[0], " varName ?newValue?\"", NULL);
+	return TCL_ERROR;
+    }
+}
+static int
+Testset2Cmd(
+    ClientData data,		/* Additional flags for Get/SetVar2. */
+    register Tcl_Interp *interp,/* Current interpreter. */
+    int argc,			/* Number of arguments. */
+    const char **argv)		/* Argument strings. */
+{
+    int flags = PTR2INT(data);
+    const char *value;
+
+    if (argc == 3) {
+	Tcl_SetResult(interp, "before get", TCL_STATIC);
+	value = Tcl_GetVar2(interp, argv[1], argv[2], flags);
+	if (value == NULL) {
+	    return TCL_ERROR;
+	}
+	Tcl_AppendElement(interp, value);
+	return TCL_OK;
+    } else if (argc == 4) {
+	Tcl_SetResult(interp, "before set", TCL_STATIC);
+	value = Tcl_SetVar2(interp, argv[1], argv[2], argv[3], flags);
+	if (value == NULL) {
+	    return TCL_ERROR;
+	}
+	Tcl_AppendElement(interp, value);
+	return TCL_OK;
+    } else {
+	Tcl_AppendResult(interp, "wrong # args: should be \"",
+		argv[0], " varName elemName ?newValue?\"", NULL);
+	return TCL_ERROR;
+    }
+}
+
+#ifndef TCL_NO_DEPRECATED
+/*
+ *----------------------------------------------------------------------
+ *
+ * TestsaveresultCmd --
+ *
+ *	Implements the "testsaveresult" cmd that is used when testing the
+ *	Tcl_SaveResult, Tcl_RestoreResult, and Tcl_DiscardResult interfaces.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+	/* ARGSUSED */
+static int
+TestsaveresultCmd(
+    ClientData dummy,		/* Not used. */
+    register Tcl_Interp *interp,/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* The argument objects. */
+{
+    Interp* iPtr = (Interp*) interp;
+    int discard, result, index;
+    Tcl_SavedResult state;
+    Tcl_Obj *objPtr;
+    static const char *const optionStrings[] = {
+	"append", "dynamic", "free", "object", "small", NULL
+    };
+    enum options {
+	RESULT_APPEND, RESULT_DYNAMIC, RESULT_FREE, RESULT_OBJECT, RESULT_SMALL
+    };
+
+    /*
+     * Parse arguments
+     */
+
+    if (objc != 4) {
+	Tcl_WrongNumArgs(interp, 1, objv, "type script discard");
+	return TCL_ERROR;
+    }
+    if (Tcl_GetIndexFromObj(interp, objv[1], optionStrings, "option", 0,
+	    &index) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    if (Tcl_GetBooleanFromObj(interp, objv[3], &discard) != TCL_OK) {
+	return TCL_ERROR;
+    }
+
+    objPtr = NULL;		/* Lint. */
+    switch ((enum options) index) {
+    case RESULT_SMALL:
+	Tcl_SetResult(interp, "small result", TCL_VOLATILE);
+	break;
+    case RESULT_APPEND:
+	Tcl_AppendResult(interp, "append result", NULL);
+	break;
+    case RESULT_FREE: {
+	char *buf = ckalloc(200);
+
+	strcpy(buf, "free result");
+	Tcl_SetResult(interp, buf, TCL_DYNAMIC);
+	break;
+    }
+    case RESULT_DYNAMIC:
+	Tcl_SetResult(interp, (char *)"dynamic result", TestsaveresultFree);
+	break;
+    case RESULT_OBJECT:
+	objPtr = Tcl_NewStringObj("object result", -1);
+	Tcl_SetObjResult(interp, objPtr);
+	break;
+    }
+
+    freeCount = 0;
+    Tcl_SaveResult(interp, &state);
+
+    if (((enum options) index) == RESULT_OBJECT) {
+	result = Tcl_EvalObjEx(interp, objv[2], 0);
+    } else {
+	result = Tcl_Eval(interp, Tcl_GetString(objv[2]));
+    }
+
+    if (discard) {
+	Tcl_DiscardResult(&state);
+    } else {
+	Tcl_RestoreResult(interp, &state);
+	result = TCL_OK;
+    }
+
+    switch ((enum options) index) {
+    case RESULT_DYNAMIC: {
+	int present = iPtr->freeProc == TestsaveresultFree;
+	int called = freeCount;
+
+	Tcl_AppendElement(interp, called ? "called" : "notCalled");
+	Tcl_AppendElement(interp, present ? "present" : "missing");
+	break;
+    }
+    case RESULT_OBJECT:
+	Tcl_AppendElement(interp, Tcl_GetObjResult(interp) == objPtr
+		? "same" : "different");
+	break;
+    default:
+	break;
+    }
+    return result;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TestsaveresultFree --
+ *
+ *	Special purpose freeProc used by TestsaveresultCmd.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Increments the freeCount.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+TestsaveresultFree(
+    char *blockPtr)
+{
+    freeCount++;
+}
+#endif /* TCL_NO_DEPRECATED */
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TestmainthreadCmd  --
+ *
+ *	Implements the "testmainthread" cmd that is used to test the
+ *	'Tcl_GetCurrentThread' API.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+TestmainthreadCmd(
+    ClientData dummy,		/* Not used. */
+    register Tcl_Interp *interp,/* Current interpreter. */
+    int argc,			/* Number of arguments. */
+    const char **argv)		/* Argument strings. */
+{
+    if (argc == 1) {
+	Tcl_Obj *idObj = Tcl_NewLongObj((long)(size_t)Tcl_GetCurrentThread());
+
+	Tcl_SetObjResult(interp, idObj);
+	return TCL_OK;
+    } else {
+	Tcl_SetResult(interp, "wrong # args", TCL_STATIC);
+	return TCL_ERROR;
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * MainLoop --
+ *
+ *	A main loop set by TestsetmainloopCmd below.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Event handlers could do anything.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+MainLoop(void)
+{
+    while (!exitMainLoop) {
+	Tcl_DoOneEvent(0);
+    }
+    fprintf(stdout,"Exit MainLoop\n");
+    fflush(stdout);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TestsetmainloopCmd  --
+ *
+ *	Implements the "testsetmainloop" cmd that is used to test the
+ *	'Tcl_SetMainLoop' API.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+TestsetmainloopCmd(
+    ClientData dummy,		/* Not used. */
+    register Tcl_Interp *interp,/* Current interpreter. */
+    int argc,			/* Number of arguments. */
+    const char **argv)		/* Argument strings. */
+{
+  exitMainLoop = 0;
+  Tcl_SetMainLoop(MainLoop);
+  return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TestexitmainloopCmd  --
+ *
+ *	Implements the "testexitmainloop" cmd that is used to test the
+ *	'Tcl_SetMainLoop' API.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+TestexitmainloopCmd(
+    ClientData dummy,		/* Not used. */
+    register Tcl_Interp *interp,/* Current interpreter. */
+    int argc,			/* Number of arguments. */
+    const char **argv)		/* Argument strings. */
+{
+  exitMainLoop = 1;
+  return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TestChannelCmd --
+ *
+ *	Implements the Tcl "testchannel" debugging command and its
+ *	subcommands. This is part of the testing environment.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+	/* ARGSUSED */
+static int
+TestChannelCmd(
+    ClientData clientData,	/* Not used. */
+    Tcl_Interp *interp,		/* Interpreter for result. */
+    int argc,			/* Count of additional args. */
+    const char **argv)		/* Additional arg strings. */
+{
+    const char *cmdName;	/* Sub command. */
+    Tcl_HashTable *hTblPtr;	/* Hash table of channels. */
+    Tcl_HashSearch hSearch;	/* Search variable. */
+    Tcl_HashEntry *hPtr;	/* Search variable. */
+    Channel *chanPtr;		/* The actual channel. */
+    ChannelState *statePtr;	/* state info for channel */
+    Tcl_Channel chan;		/* The opaque type. */
+    size_t len;			/* Length of subcommand string. */
+    int IOQueued;		/* How much IO is queued inside channel? */
+    char buf[TCL_INTEGER_SPACE];/* For sprintf. */
+    int mode;			/* rw mode of the channel */
+
+    if (argc < 2) {
+	Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
+		" subcommand ?additional args..?\"", NULL);
+	return TCL_ERROR;
+    }
+    cmdName = argv[1];
+    len = strlen(cmdName);
+
+    chanPtr = NULL;
+
+    if (argc > 2) {
+	if ((cmdName[0] == 's') && (strncmp(cmdName, "splice", len) == 0)) {
+	    /* For splice access the pool of detached channels.
+	     * Locate channel, remove from the list.
+	     */
+
+	    TestChannel **nextPtrPtr, *curPtr;
+
+	    chan = (Tcl_Channel) NULL;
+	    for (nextPtrPtr = &firstDetached, curPtr = firstDetached;
+		 curPtr != NULL;
+		 nextPtrPtr = &(curPtr->nextPtr), curPtr = curPtr->nextPtr) {
+
+		if (strcmp(argv[2], Tcl_GetChannelName(curPtr->chan)) == 0) {
+		    *nextPtrPtr = curPtr->nextPtr;
+		    curPtr->nextPtr = NULL;
+		    chan = curPtr->chan;
+		    ckfree(curPtr);
+		    break;
+		}
+	    }
+	} else {
+	    chan = Tcl_GetChannel(interp, argv[2], &mode);
+	}
+	if (chan == (Tcl_Channel) NULL) {
+	    return TCL_ERROR;
+	}
+	chanPtr		= (Channel *) chan;
+	statePtr	= chanPtr->state;
+	chanPtr		= statePtr->topChanPtr;
+	chan		= (Tcl_Channel) chanPtr;
+    } else {
+	/* lint */
+	statePtr	= NULL;
+	chan		= NULL;
+    }
+
+    if ((cmdName[0] == 's') && (strncmp(cmdName, "setchannelerror", len) == 0)) {
+
+	Tcl_Obj *msg = Tcl_NewStringObj(argv[3],-1);
+
+	Tcl_IncrRefCount(msg);
+	Tcl_SetChannelError(chan, msg);
+	Tcl_DecrRefCount(msg);
+
+	Tcl_GetChannelError(chan, &msg);
+	Tcl_SetObjResult(interp, msg);
+	Tcl_DecrRefCount(msg);
+	return TCL_OK;
+    }
+    if ((cmdName[0] == 's') && (strncmp(cmdName, "setchannelerrorinterp", len) == 0)) {
+
+	Tcl_Obj *msg = Tcl_NewStringObj(argv[3],-1);
+
+	Tcl_IncrRefCount(msg);
+	Tcl_SetChannelErrorInterp(interp, msg);
+	Tcl_DecrRefCount(msg);
+
+	Tcl_GetChannelErrorInterp(interp, &msg);
+	Tcl_SetObjResult(interp, msg);
+	Tcl_DecrRefCount(msg);
+	return TCL_OK;
+    }
+
+    /*
+     * "cut" is actually more a simplified detach facility as provided by the
+     * Thread package. Without the safeguards of a regular command (no
+     * checking that the command is truly cut'able, no mutexes for
+     * thread-safety). Its complementary command is "splice", see below.
+     */
+
+    if ((cmdName[0] == 'c') && (strncmp(cmdName, "cut", len) == 0)) {
+	TestChannel *det;
+
+	if (argc != 3) {
+	    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
+		    " cut channelName\"", NULL);
+	    return TCL_ERROR;
+	}
+
+	Tcl_RegisterChannel(NULL, chan); /* prevent closing */
+	Tcl_UnregisterChannel(interp, chan);
+
+	Tcl_CutChannel(chan);
+
+	/* Remember the channel in the pool of detached channels */
+
+	det = ckalloc(sizeof(TestChannel));
+	det->chan     = chan;
+	det->nextPtr  = firstDetached;
+	firstDetached = det;
+
+	return TCL_OK;
+    }
+
+    if ((cmdName[0] == 'c') &&
+	    (strncmp(cmdName, "clearchannelhandlers", len) == 0)) {
+	if (argc != 3) {
+	    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
+		    " clearchannelhandlers channelName\"", NULL);
+	    return TCL_ERROR;
+	}
+	Tcl_ClearChannelHandlers(chan);
+	return TCL_OK;
+    }
+
+    if ((cmdName[0] == 'i') && (strncmp(cmdName, "info", len) == 0)) {
+	if (argc != 3) {
+	    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
+		    " info channelName\"", NULL);
+	    return TCL_ERROR;
+	}
+	Tcl_AppendElement(interp, argv[2]);
+	Tcl_AppendElement(interp, Tcl_ChannelName(chanPtr->typePtr));
+	if (statePtr->flags & TCL_READABLE) {
+	    Tcl_AppendElement(interp, "read");
+	} else {
+	    Tcl_AppendElement(interp, "");
+	}
+	if (statePtr->flags & TCL_WRITABLE) {
+	    Tcl_AppendElement(interp, "write");
+	} else {
+	    Tcl_AppendElement(interp, "");
+	}
+	if (statePtr->flags & CHANNEL_NONBLOCKING) {
+	    Tcl_AppendElement(interp, "nonblocking");
+	} else {
+	    Tcl_AppendElement(interp, "blocking");
+	}
+	if (statePtr->flags & CHANNEL_LINEBUFFERED) {
+	    Tcl_AppendElement(interp, "line");
+	} else if (statePtr->flags & CHANNEL_UNBUFFERED) {
+	    Tcl_AppendElement(interp, "none");
+	} else {
+	    Tcl_AppendElement(interp, "full");
+	}
+	if (statePtr->flags & BG_FLUSH_SCHEDULED) {
+	    Tcl_AppendElement(interp, "async_flush");
+	} else {
+	    Tcl_AppendElement(interp, "");
+	}
+	if (statePtr->flags & CHANNEL_EOF) {
+	    Tcl_AppendElement(interp, "eof");
+	} else {
+	    Tcl_AppendElement(interp, "");
+	}
+	if (statePtr->flags & CHANNEL_BLOCKED) {
+	    Tcl_AppendElement(interp, "blocked");
+	} else {
+	    Tcl_AppendElement(interp, "unblocked");
+	}
+	if (statePtr->inputTranslation == TCL_TRANSLATE_AUTO) {
+	    Tcl_AppendElement(interp, "auto");
+	    if (statePtr->flags & INPUT_SAW_CR) {
+		Tcl_AppendElement(interp, "saw_cr");
+	    } else {
+		Tcl_AppendElement(interp, "");
+	    }
+	} else if (statePtr->inputTranslation == TCL_TRANSLATE_LF) {
+	    Tcl_AppendElement(interp, "lf");
+	    Tcl_AppendElement(interp, "");
+	} else if (statePtr->inputTranslation == TCL_TRANSLATE_CR) {
+	    Tcl_AppendElement(interp, "cr");
+	    Tcl_AppendElement(interp, "");
+	} else if (statePtr->inputTranslation == TCL_TRANSLATE_CRLF) {
+	    Tcl_AppendElement(interp, "crlf");
+	    if (statePtr->flags & INPUT_SAW_CR) {
+		Tcl_AppendElement(interp, "queued_cr");
+	    } else {
+		Tcl_AppendElement(interp, "");
+	    }
+	}
+	if (statePtr->outputTranslation == TCL_TRANSLATE_AUTO) {
+	    Tcl_AppendElement(interp, "auto");
+	} else if (statePtr->outputTranslation == TCL_TRANSLATE_LF) {
+	    Tcl_AppendElement(interp, "lf");
+	} else if (statePtr->outputTranslation == TCL_TRANSLATE_CR) {
+	    Tcl_AppendElement(interp, "cr");
+	} else if (statePtr->outputTranslation == TCL_TRANSLATE_CRLF) {
+	    Tcl_AppendElement(interp, "crlf");
+	}
+	IOQueued = Tcl_InputBuffered(chan);
+	TclFormatInt(buf, IOQueued);
+	Tcl_AppendElement(interp, buf);
+
+	IOQueued = Tcl_OutputBuffered(chan);
+	TclFormatInt(buf, IOQueued);
+	Tcl_AppendElement(interp, buf);
+
+	TclFormatInt(buf, (int)Tcl_Tell(chan));
+	Tcl_AppendElement(interp, buf);
+
+	TclFormatInt(buf, statePtr->refCount);
+	Tcl_AppendElement(interp, buf);
+
+	return TCL_OK;
+    }
+
+    if ((cmdName[0] == 'i') &&
+	    (strncmp(cmdName, "inputbuffered", len) == 0)) {
+	if (argc != 3) {
+	    Tcl_AppendResult(interp, "channel name required", NULL);
+	    return TCL_ERROR;
+	}
+	IOQueued = Tcl_InputBuffered(chan);
+	TclFormatInt(buf, IOQueued);
+	Tcl_AppendResult(interp, buf, NULL);
+	return TCL_OK;
+    }
+
+    if ((cmdName[0] == 'i') && (strncmp(cmdName, "isshared", len) == 0)) {
+	if (argc != 3) {
+	    Tcl_AppendResult(interp, "channel name required", NULL);
+	    return TCL_ERROR;
+	}
+
+	TclFormatInt(buf, Tcl_IsChannelShared(chan));
+	Tcl_AppendResult(interp, buf, NULL);
+	return TCL_OK;
+    }
+
+    if ((cmdName[0] == 'i') && (strncmp(cmdName, "isstandard", len) == 0)) {
+	if (argc != 3) {
+	    Tcl_AppendResult(interp, "channel name required", NULL);
+	    return TCL_ERROR;
+	}
+
+	TclFormatInt(buf, Tcl_IsStandardChannel(chan));
+	Tcl_AppendResult(interp, buf, NULL);
+	return TCL_OK;
+    }
+
+    if ((cmdName[0] == 'm') && (strncmp(cmdName, "mode", len) == 0)) {
+	if (argc != 3) {
+	    Tcl_AppendResult(interp, "channel name required", NULL);
+	    return TCL_ERROR;
+	}
+
+	if (statePtr->flags & TCL_READABLE) {
+	    Tcl_AppendElement(interp, "read");
+	} else {
+	    Tcl_AppendElement(interp, "");
+	}
+	if (statePtr->flags & TCL_WRITABLE) {
+	    Tcl_AppendElement(interp, "write");
+	} else {
+	    Tcl_AppendElement(interp, "");
+	}
+	return TCL_OK;
+    }
+
+    if ((cmdName[0] == 'm') && (strncmp(cmdName, "mthread", len) == 0)) {
+	if (argc != 3) {
+	    Tcl_AppendResult(interp, "channel name required", NULL);
+	    return TCL_ERROR;
+	}
+
+	TclFormatInt(buf, (size_t) Tcl_GetChannelThread(chan));
+	Tcl_AppendResult(interp, buf, NULL);
+	return TCL_OK;
+    }
+
+    if ((cmdName[0] == 'n') && (strncmp(cmdName, "name", len) == 0)) {
+	if (argc != 3) {
+	    Tcl_AppendResult(interp, "channel name required", NULL);
+	    return TCL_ERROR;
+	}
+	Tcl_AppendResult(interp, statePtr->channelName, NULL);
+	return TCL_OK;
+    }
+
+    if ((cmdName[0] == 'o') && (strncmp(cmdName, "open", len) == 0)) {
+	hTblPtr = (Tcl_HashTable *) Tcl_GetAssocData(interp, "tclIO", NULL);
+	if (hTblPtr == NULL) {
+	    return TCL_OK;
+	}
+	for (hPtr = Tcl_FirstHashEntry(hTblPtr, &hSearch);
+	     hPtr != NULL;
+	     hPtr = Tcl_NextHashEntry(&hSearch)) {
+	    Tcl_AppendElement(interp, Tcl_GetHashKey(hTblPtr, hPtr));
+	}
+	return TCL_OK;
+    }
+
+    if ((cmdName[0] == 'o') &&
+	    (strncmp(cmdName, "outputbuffered", len) == 0)) {
+	if (argc != 3) {
+	    Tcl_AppendResult(interp, "channel name required", NULL);
+	    return TCL_ERROR;
+	}
+
+	IOQueued = Tcl_OutputBuffered(chan);
+	TclFormatInt(buf, IOQueued);
+	Tcl_AppendResult(interp, buf, NULL);
+	return TCL_OK;
+    }
+
+    if ((cmdName[0] == 'q') &&
+	    (strncmp(cmdName, "queuedcr", len) == 0)) {
+	if (argc != 3) {
+	    Tcl_AppendResult(interp, "channel name required", NULL);
+	    return TCL_ERROR;
+	}
+
+	Tcl_AppendResult(interp,
+		(statePtr->flags & INPUT_SAW_CR) ? "1" : "0", NULL);
+	return TCL_OK;
+    }
+
+    if ((cmdName[0] == 'r') && (strncmp(cmdName, "readable", len) == 0)) {
+	hTblPtr = (Tcl_HashTable *) Tcl_GetAssocData(interp, "tclIO", NULL);
+	if (hTblPtr == NULL) {
+	    return TCL_OK;
+	}
+	for (hPtr = Tcl_FirstHashEntry(hTblPtr, &hSearch);
+	     hPtr != NULL;
+	     hPtr = Tcl_NextHashEntry(&hSearch)) {
+	    chanPtr  = (Channel *) Tcl_GetHashValue(hPtr);
+	    statePtr = chanPtr->state;
+	    if (statePtr->flags & TCL_READABLE) {
+		Tcl_AppendElement(interp, Tcl_GetHashKey(hTblPtr, hPtr));
+	    }
+	}
+	return TCL_OK;
+    }
+
+    if ((cmdName[0] == 'r') && (strncmp(cmdName, "refcount", len) == 0)) {
+	if (argc != 3) {
+	    Tcl_AppendResult(interp, "channel name required", NULL);
+	    return TCL_ERROR;
+	}
+
+	TclFormatInt(buf, statePtr->refCount);
+	Tcl_AppendResult(interp, buf, NULL);
+	return TCL_OK;
+    }
+
+    /*
+     * "splice" is actually more a simplified attach facility as provided by
+     * the Thread package. Without the safeguards of a regular command (no
+     * checking that the command is truly cut'able, no mutexes for
+     * thread-safety). Its complementary command is "cut", see above.
+     */
+
+    if ((cmdName[0] == 's') && (strncmp(cmdName, "splice", len) == 0)) {
+	if (argc != 3) {
+	    Tcl_AppendResult(interp, "channel name required", NULL);
+	    return TCL_ERROR;
+	}
+
+	Tcl_SpliceChannel(chan);
+
+	Tcl_RegisterChannel(interp, chan);
+	Tcl_UnregisterChannel(NULL, chan);
+
+	return TCL_OK;
+    }
+
+    if ((cmdName[0] == 't') && (strncmp(cmdName, "type", len) == 0)) {
+	if (argc != 3) {
+	    Tcl_AppendResult(interp, "channel name required", NULL);
+	    return TCL_ERROR;
+	}
+	Tcl_AppendResult(interp, Tcl_ChannelName(chanPtr->typePtr), NULL);
+	return TCL_OK;
+    }
+
+    if ((cmdName[0] == 'w') && (strncmp(cmdName, "writable", len) == 0)) {
+	hTblPtr = (Tcl_HashTable *) Tcl_GetAssocData(interp, "tclIO", NULL);
+	if (hTblPtr == NULL) {
+	    return TCL_OK;
+	}
+	for (hPtr = Tcl_FirstHashEntry(hTblPtr, &hSearch);
+		hPtr != NULL; hPtr = Tcl_NextHashEntry(&hSearch)) {
+	    chanPtr = (Channel *) Tcl_GetHashValue(hPtr);
+	    statePtr = chanPtr->state;
+	    if (statePtr->flags & TCL_WRITABLE) {
+		Tcl_AppendElement(interp, Tcl_GetHashKey(hTblPtr, hPtr));
+	    }
+	}
+	return TCL_OK;
+    }
+
+    if ((cmdName[0] == 't') && (strncmp(cmdName, "transform", len) == 0)) {
+	/*
+	 * Syntax: transform channel -command command
+	 */
+
+	if (argc != 5) {
+	    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
+		    " transform channelId -command cmd\"", NULL);
+	    return TCL_ERROR;
+	}
+	if (strcmp(argv[3], "-command") != 0) {
+	    Tcl_AppendResult(interp, "bad argument \"", argv[3],
+		    "\": should be \"-command\"", NULL);
+	    return TCL_ERROR;
+	}
+
+	return TclChannelTransform(interp, chan,
+		Tcl_NewStringObj(argv[4], -1));
+    }
+
+    if ((cmdName[0] == 'u') && (strncmp(cmdName, "unstack", len) == 0)) {
+	/*
+	 * Syntax: unstack channel
+	 */
+
+	if (argc != 3) {
+	    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
+		    " unstack channel\"", NULL);
+	    return TCL_ERROR;
+	}
+	return Tcl_UnstackChannel(interp, chan);
+    }
+
+    Tcl_AppendResult(interp, "bad option \"", cmdName, "\": should be "
+	    "cut, clearchannelhandlers, info, isshared, mode, open, "
+	    "readable, splice, writable, transform, unstack", NULL);
+    return TCL_ERROR;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TestChannelEventCmd --
+ *
+ *	This procedure implements the "testchannelevent" command. It is used
+ *	to test the Tcl channel event mechanism.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	Creates, deletes and returns channel event handlers.
+ *
+ *----------------------------------------------------------------------
+ */
+
+	/* ARGSUSED */
+static int
+TestChannelEventCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int argc,			/* Number of arguments. */
+    const char **argv)		/* Argument strings. */
+{
+    Tcl_Obj *resultListPtr;
+    Channel *chanPtr;
+    ChannelState *statePtr;	/* state info for channel */
+    EventScriptRecord *esPtr, *prevEsPtr, *nextEsPtr;
+    const char *cmd;
+    int index, i, mask, len;
+
+    if ((argc < 3) || (argc > 5)) {
+	Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
+		" channelName cmd ?arg1? ?arg2?\"", NULL);
+	return TCL_ERROR;
+    }
+    chanPtr = (Channel *) Tcl_GetChannel(interp, argv[1], NULL);
+    if (chanPtr == NULL) {
+	return TCL_ERROR;
+    }
+    statePtr = chanPtr->state;
+
+    cmd = argv[2];
+    len = strlen(cmd);
+    if ((cmd[0] == 'a') && (strncmp(cmd, "add", (unsigned) len) == 0)) {
+	if (argc != 5) {
+	    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
+		    " channelName add eventSpec script\"", NULL);
+	    return TCL_ERROR;
+	}
+	if (strcmp(argv[3], "readable") == 0) {
+	    mask = TCL_READABLE;
+	} else if (strcmp(argv[3], "writable") == 0) {
+	    mask = TCL_WRITABLE;
+	} else if (strcmp(argv[3], "none") == 0) {
+	    mask = 0;
+	} else {
+	    Tcl_AppendResult(interp, "bad event name \"", argv[3],
+		    "\": must be readable, writable, or none", NULL);
+	    return TCL_ERROR;
+	}
+
+	esPtr = ckalloc(sizeof(EventScriptRecord));
+	esPtr->nextPtr = statePtr->scriptRecordPtr;
+	statePtr->scriptRecordPtr = esPtr;
+
+	esPtr->chanPtr = chanPtr;
+	esPtr->interp = interp;
+	esPtr->mask = mask;
+	esPtr->scriptPtr = Tcl_NewStringObj(argv[4], -1);
+	Tcl_IncrRefCount(esPtr->scriptPtr);
+
+	Tcl_CreateChannelHandler((Tcl_Channel) chanPtr, mask,
+		TclChannelEventScriptInvoker, (ClientData) esPtr);
+
+	return TCL_OK;
+    }
+
+    if ((cmd[0] == 'd') && (strncmp(cmd, "delete", (unsigned) len) == 0)) {
+	if (argc != 4) {
+	    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
+		    " channelName delete index\"", NULL);
+	    return TCL_ERROR;
+	}
+	if (Tcl_GetInt(interp, argv[3], &index) == TCL_ERROR) {
+	    return TCL_ERROR;
+	}
+	if (index < 0) {
+	    Tcl_AppendResult(interp, "bad event index: ", argv[3],
+		    ": must be nonnegative", NULL);
+	    return TCL_ERROR;
+	}
+	for (i = 0, esPtr = statePtr->scriptRecordPtr;
+	     (i < index) && (esPtr != NULL);
+	     i++, esPtr = esPtr->nextPtr) {
+	    /* Empty loop body. */
+	}
+	if (esPtr == NULL) {
+	    Tcl_AppendResult(interp, "bad event index ", argv[3],
+		    ": out of range", NULL);
+	    return TCL_ERROR;
+	}
+	if (esPtr == statePtr->scriptRecordPtr) {
+	    statePtr->scriptRecordPtr = esPtr->nextPtr;
+	} else {
+	    for (prevEsPtr = statePtr->scriptRecordPtr;
+		 (prevEsPtr != NULL) &&
+		     (prevEsPtr->nextPtr != esPtr);
+		 prevEsPtr = prevEsPtr->nextPtr) {
+		/* Empty loop body. */
+	    }
+	    if (prevEsPtr == NULL) {
+		Tcl_Panic("TestChannelEventCmd: damaged event script list");
+	    }
+	    prevEsPtr->nextPtr = esPtr->nextPtr;
+	}
+	Tcl_DeleteChannelHandler((Tcl_Channel) chanPtr,
+		TclChannelEventScriptInvoker, (ClientData) esPtr);
+	Tcl_DecrRefCount(esPtr->scriptPtr);
+	ckfree(esPtr);
+
+	return TCL_OK;
+    }
+
+    if ((cmd[0] == 'l') && (strncmp(cmd, "list", (unsigned) len) == 0)) {
+	if (argc != 3) {
+	    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
+		    " channelName list\"", NULL);
+	    return TCL_ERROR;
+	}
+	resultListPtr = Tcl_GetObjResult(interp);
+	for (esPtr = statePtr->scriptRecordPtr;
+	     esPtr != NULL;
+	     esPtr = esPtr->nextPtr) {
+	    if (esPtr->mask) {
+		Tcl_ListObjAppendElement(interp, resultListPtr, Tcl_NewStringObj(
+		    (esPtr->mask == TCL_READABLE) ? "readable" : "writable", -1));
+	    } else {
+		Tcl_ListObjAppendElement(interp, resultListPtr,
+			Tcl_NewStringObj("none", -1));
+	    }
+	    Tcl_ListObjAppendElement(interp, resultListPtr, esPtr->scriptPtr);
+	}
+	Tcl_SetObjResult(interp, resultListPtr);
+	return TCL_OK;
+    }
+
+    if ((cmd[0] == 'r') && (strncmp(cmd, "removeall", (unsigned) len) == 0)) {
+	if (argc != 3) {
+	    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
+		    " channelName removeall\"", NULL);
+	    return TCL_ERROR;
+	}
+	for (esPtr = statePtr->scriptRecordPtr;
+	     esPtr != NULL;
+	     esPtr = nextEsPtr) {
+	    nextEsPtr = esPtr->nextPtr;
+	    Tcl_DeleteChannelHandler((Tcl_Channel) chanPtr,
+		    TclChannelEventScriptInvoker, (ClientData) esPtr);
+	    Tcl_DecrRefCount(esPtr->scriptPtr);
+	    ckfree(esPtr);
+	}
+	statePtr->scriptRecordPtr = NULL;
+	return TCL_OK;
+    }
+
+    if	((cmd[0] == 's') && (strncmp(cmd, "set", (unsigned) len) == 0)) {
+	if (argc != 5) {
+	    Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
+		    " channelName delete index event\"", NULL);
+	    return TCL_ERROR;
+	}
+	if (Tcl_GetInt(interp, argv[3], &index) == TCL_ERROR) {
+	    return TCL_ERROR;
+	}
+	if (index < 0) {
+	    Tcl_AppendResult(interp, "bad event index: ", argv[3],
+		    ": must be nonnegative", NULL);
+	    return TCL_ERROR;
+	}
+	for (i = 0, esPtr = statePtr->scriptRecordPtr;
+	     (i < index) && (esPtr != NULL);
+	     i++, esPtr = esPtr->nextPtr) {
+	    /* Empty loop body. */
+	}
+	if (esPtr == NULL) {
+	    Tcl_AppendResult(interp, "bad event index ", argv[3],
+		    ": out of range", NULL);
+	    return TCL_ERROR;
+	}
+
+	if (strcmp(argv[4], "readable") == 0) {
+	    mask = TCL_READABLE;
+	} else if (strcmp(argv[4], "writable") == 0) {
+	    mask = TCL_WRITABLE;
+	} else if (strcmp(argv[4], "none") == 0) {
+	    mask = 0;
+	} else {
+	    Tcl_AppendResult(interp, "bad event name \"", argv[4],
+		    "\": must be readable, writable, or none", NULL);
+	    return TCL_ERROR;
+	}
+	esPtr->mask = mask;
+	Tcl_CreateChannelHandler((Tcl_Channel) chanPtr, mask,
+		TclChannelEventScriptInvoker, (ClientData) esPtr);
+	return TCL_OK;
+    }
+    Tcl_AppendResult(interp, "bad command ", cmd, ", must be one of "
+	    "add, delete, list, set, or removeall", NULL);
+    return TCL_ERROR;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TestWrongNumArgsObjCmd --
+ *
+ *	Test the Tcl_WrongNumArgs function.
+ *
+ * Results:
+ *	Standard Tcl result.
+ *
+ * Side effects:
+ *	Sets interpreter result.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+TestWrongNumArgsObjCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    int i, length;
+    const char *msg;
+
+    if (objc < 3) {
+	/*
+	 * Don't use Tcl_WrongNumArgs here, as that is the function
+	 * we want to test!
+	 */
+	Tcl_SetResult(interp, "insufficient arguments", TCL_STATIC);
+	return TCL_ERROR;
+    }
+
+    if (Tcl_GetIntFromObj(interp, objv[1], &i) != TCL_OK) {
+	return TCL_ERROR;
+    }
+
+    msg = Tcl_GetStringFromObj(objv[2], &length);
+    if (length == 0) {
+	msg = NULL;
+    }
+
+    if (i > objc - 3) {
+	/*
+	 * Asked for more arguments than were given.
+	 */
+	Tcl_SetResult(interp, "insufficient arguments", TCL_STATIC);
+	return TCL_ERROR;
+    }
+
+    Tcl_WrongNumArgs(interp, i, &(objv[3]), msg);
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TestGetIndexFromObjStructObjCmd --
+ *
+ *	Test the Tcl_GetIndexFromObjStruct function.
+ *
+ * Results:
+ *	Standard Tcl result.
+ *
+ * Side effects:
+ *	Sets interpreter result.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+TestGetIndexFromObjStructObjCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    const char *const ary[] = {
+	"a", "b", "c", "d", "e", "f", NULL, NULL
+    };
+    int idx,target;
+
+    if (objc != 3) {
+	Tcl_WrongNumArgs(interp, 1, objv, "argument targetvalue");
+	return TCL_ERROR;
+    }
+    if (Tcl_GetIndexFromObjStruct(interp, objv[1], ary, 2*sizeof(char *),
+	    "dummy", 0, &idx) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    if (Tcl_GetIntFromObj(interp, objv[2], &target) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    if (idx != target) {
+	char buffer[64];
+	sprintf(buffer, "%d", idx);
+	Tcl_AppendResult(interp, "index value comparison failed: got ",
+		buffer, NULL);
+	sprintf(buffer, "%d", target);
+	Tcl_AppendResult(interp, " when ", buffer, " expected", NULL);
+	return TCL_ERROR;
+    }
+    Tcl_WrongNumArgs(interp, 3, objv, NULL);
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TestFilesystemObjCmd --
+ *
+ *	This procedure implements the "testfilesystem" command. It is used to
+ *	test Tcl_FSRegister, Tcl_FSUnregister, and can be used to test that
+ *	the pluggable filesystem works.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	Inserts or removes a filesystem from Tcl's stack.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+TestFilesystemObjCmd(
+    ClientData dummy,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const objv[])
+{
+    int res, boolVal;
+    const char *msg;
+
+    if (objc != 2) {
+	Tcl_WrongNumArgs(interp, 1, objv, "boolean");
+	return TCL_ERROR;
+    }
+    if (Tcl_GetBooleanFromObj(interp, objv[1], &boolVal) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    if (boolVal) {
+	res = Tcl_FSRegister((ClientData)interp, &testReportingFilesystem);
+	msg = (res == TCL_OK) ? "registered" : "failed";
+    } else {
+	res = Tcl_FSUnregister(&testReportingFilesystem);
+	msg = (res == TCL_OK) ? "unregistered" : "failed";
+    }
+    Tcl_SetObjResult(interp, Tcl_NewStringObj(msg , -1));
+    return res;
+}
+
+static int
+TestReportInFilesystem(
+    Tcl_Obj *pathPtr,
+    ClientData *clientDataPtr)
+{
+    static Tcl_Obj *lastPathPtr = NULL;
+    Tcl_Obj *newPathPtr;
+
+    if (pathPtr == lastPathPtr) {
+	/* Reject all files second time around */
+	return -1;
+    }
+
+    /* Try to claim all files first time around */
+
+    newPathPtr = Tcl_DuplicateObj(pathPtr);
+    lastPathPtr = newPathPtr;
+    Tcl_IncrRefCount(newPathPtr);
+    if (Tcl_FSGetFileSystemForPath(newPathPtr) == NULL) {
+	/* Nothing claimed it. Therefore we don't either */
+	Tcl_DecrRefCount(newPathPtr);
+	lastPathPtr = NULL;
+	return -1;
+    }
+    lastPathPtr = NULL;
+    *clientDataPtr = (ClientData) newPathPtr;
+    return TCL_OK;
+}
+
+/*
+ * Simple helper function to extract the native vfs representation of a path
+ * object, or NULL if no such representation exists.
+ */
+
+static Tcl_Obj *
+TestReportGetNativePath(
+    Tcl_Obj *pathPtr)
+{
+    return (Tcl_Obj*) Tcl_FSGetInternalRep(pathPtr, &testReportingFilesystem);
+}
+
+static void
+TestReportFreeInternalRep(
+    ClientData clientData)
+{
+    Tcl_Obj *nativeRep = (Tcl_Obj *) clientData;
+
+    if (nativeRep != NULL) {
+	/* Free the path */
+	Tcl_DecrRefCount(nativeRep);
+    }
+}
+
+static ClientData
+TestReportDupInternalRep(
+    ClientData clientData)
+{
+    Tcl_Obj *original = (Tcl_Obj *) clientData;
+
+    Tcl_IncrRefCount(original);
+    return clientData;
+}
+
+static void
+TestReport(
+    const char *cmd,
+    Tcl_Obj *path,
+    Tcl_Obj *arg2)
+{
+    Tcl_Interp *interp = (Tcl_Interp *) Tcl_FSData(&testReportingFilesystem);
+
+    if (interp == NULL) {
+	/* This is bad, but not much we can do about it */
+    } else {
+	/*
+	 * No idea why I decided to program this up using the old string-based
+	 * API, but there you go. We should convert it to objects.
+	 */
+
+	Tcl_Obj *savedResult;
+	Tcl_DString ds;
+
+	Tcl_DStringInit(&ds);
+	Tcl_DStringAppend(&ds, "lappend filesystemReport ", -1);
+	Tcl_DStringStartSublist(&ds);
+	Tcl_DStringAppendElement(&ds, cmd);
+	if (path != NULL) {
+	    Tcl_DStringAppendElement(&ds, Tcl_GetString(path));
+	}
+	if (arg2 != NULL) {
+	    Tcl_DStringAppendElement(&ds, Tcl_GetString(arg2));
+	}
+	Tcl_DStringEndSublist(&ds);
+	savedResult = Tcl_GetObjResult(interp);
+	Tcl_IncrRefCount(savedResult);
+	Tcl_SetObjResult(interp, Tcl_NewObj());
+	Tcl_Eval(interp, Tcl_DStringValue(&ds));
+	Tcl_DStringFree(&ds);
+	Tcl_ResetResult(interp);
+	Tcl_SetObjResult(interp, savedResult);
+	Tcl_DecrRefCount(savedResult);
+    }
+}
+
+static int
+TestReportStat(
+    Tcl_Obj *path,		/* Path of file to stat (in current CP). */
+    Tcl_StatBuf *buf)		/* Filled with results of stat call. */
+{
+    TestReport("stat", path, NULL);
+    return Tcl_FSStat(TestReportGetNativePath(path), buf);
+}
+
+static int
+TestReportLstat(
+    Tcl_Obj *path,		/* Path of file to stat (in current CP). */
+    Tcl_StatBuf *buf)		/* Filled with results of stat call. */
+{
+    TestReport("lstat", path, NULL);
+    return Tcl_FSLstat(TestReportGetNativePath(path), buf);
+}
+
+static int
+TestReportAccess(
+    Tcl_Obj *path,		/* Path of file to access (in current CP). */
+    int mode)			/* Permission setting. */
+{
+    TestReport("access", path, NULL);
+    return Tcl_FSAccess(TestReportGetNativePath(path), mode);
+}
+
+static Tcl_Channel
+TestReportOpenFileChannel(
+    Tcl_Interp *interp,		/* Interpreter for error reporting; can be
+				 * NULL. */
+    Tcl_Obj *fileName,		/* Name of file to open. */
+    int mode,			/* POSIX open mode. */
+    int permissions)		/* If the open involves creating a file, with
+				 * what modes to create it? */
+{
+    TestReport("open", fileName, NULL);
+    return TclpOpenFileChannel(interp, TestReportGetNativePath(fileName),
+	    mode, permissions);
+}
+
+static int
+TestReportMatchInDirectory(
+    Tcl_Interp *interp,		/* Interpreter for error messages. */
+    Tcl_Obj *resultPtr,		/* Object to lappend results. */
+    Tcl_Obj *dirPtr,		/* Contains path to directory to search. */
+    const char *pattern,	/* Pattern to match against. */
+    Tcl_GlobTypeData *types)	/* Object containing list of acceptable types.
+				 * May be NULL. */
+{
+    if (types != NULL && types->type & TCL_GLOB_TYPE_MOUNT) {
+	TestReport("matchmounts", dirPtr, NULL);
+	return TCL_OK;
+    } else {
+	TestReport("matchindirectory", dirPtr, NULL);
+	return Tcl_FSMatchInDirectory(interp, resultPtr,
+		TestReportGetNativePath(dirPtr), pattern, types);
+    }
+}
+
+static int
+TestReportChdir(
+    Tcl_Obj *dirName)
+{
+    TestReport("chdir", dirName, NULL);
+    return Tcl_FSChdir(TestReportGetNativePath(dirName));
+}
+
+static int
+TestReportLoadFile(
+    Tcl_Interp *interp,		/* Used for error reporting. */
+    Tcl_Obj *fileName,		/* Name of the file containing the desired
+				 * code. */
+    Tcl_LoadHandle *handlePtr,	/* Filled with token for dynamically loaded
+				 * file which will be passed back to
+				 * (*unloadProcPtr)() to unload the file. */
+    Tcl_FSUnloadFileProc **unloadProcPtr)
+				/* Filled with address of Tcl_FSUnloadFileProc
+				 * function which should be used for
+				 * this file. */
+{
+    TestReport("loadfile", fileName, NULL);
+    return Tcl_FSLoadFile(interp, TestReportGetNativePath(fileName), NULL,
+	    NULL, NULL, NULL, handlePtr, unloadProcPtr);
+}
+
+static Tcl_Obj *
+TestReportLink(
+    Tcl_Obj *path,		/* Path of file to readlink or link */
+    Tcl_Obj *to,		/* Path of file to link to, or NULL */
+    int linkType)
+{
+    TestReport("link", path, to);
+    return Tcl_FSLink(TestReportGetNativePath(path), to, linkType);
+}
+
+static int
+TestReportRenameFile(
+    Tcl_Obj *src,		/* Pathname of file or dir to be renamed
+				 * (UTF-8). */
+    Tcl_Obj *dst)		/* New pathname of file or directory
+				 * (UTF-8). */
+{
+    TestReport("renamefile", src, dst);
+    return Tcl_FSRenameFile(TestReportGetNativePath(src),
+	    TestReportGetNativePath(dst));
+}
+
+static int
+TestReportCopyFile(
+    Tcl_Obj *src,		/* Pathname of file to be copied (UTF-8). */
+    Tcl_Obj *dst)		/* Pathname of file to copy to (UTF-8). */
+{
+    TestReport("copyfile", src, dst);
+    return Tcl_FSCopyFile(TestReportGetNativePath(src),
+	    TestReportGetNativePath(dst));
+}
+
+static int
+TestReportDeleteFile(
+    Tcl_Obj *path)		/* Pathname of file to be removed (UTF-8). */
+{
+    TestReport("deletefile", path, NULL);
+    return Tcl_FSDeleteFile(TestReportGetNativePath(path));
+}
+
+static int
+TestReportCreateDirectory(
+    Tcl_Obj *path)		/* Pathname of directory to create (UTF-8). */
+{
+    TestReport("createdirectory", path, NULL);
+    return Tcl_FSCreateDirectory(TestReportGetNativePath(path));
+}
+
+static int
+TestReportCopyDirectory(
+    Tcl_Obj *src,		/* Pathname of directory to be copied
+				 * (UTF-8). */
+    Tcl_Obj *dst,		/* Pathname of target directory (UTF-8). */
+    Tcl_Obj **errorPtr)		/* If non-NULL, to be filled with UTF-8 name
+				 * of file causing error. */
+{
+    TestReport("copydirectory", src, dst);
+    return Tcl_FSCopyDirectory(TestReportGetNativePath(src),
+	    TestReportGetNativePath(dst), errorPtr);
+}
+
+static int
+TestReportRemoveDirectory(
+    Tcl_Obj *path,		/* Pathname of directory to be removed
+				 * (UTF-8). */
+    int recursive,		/* If non-zero, removes directories that
+				 * are nonempty.  Otherwise, will only remove
+				 * empty directories. */
+    Tcl_Obj **errorPtr)		/* If non-NULL, to be filled with UTF-8 name
+				 * of file causing error. */
+{
+    TestReport("removedirectory", path, NULL);
+    return Tcl_FSRemoveDirectory(TestReportGetNativePath(path), recursive,
+	    errorPtr);
+}
+
+static const char *const *
+TestReportFileAttrStrings(
+    Tcl_Obj *fileName,
+    Tcl_Obj **objPtrRef)
+{
+    TestReport("fileattributestrings", fileName, NULL);
+    return Tcl_FSFileAttrStrings(TestReportGetNativePath(fileName), objPtrRef);
+}
+
+static int
+TestReportFileAttrsGet(
+    Tcl_Interp *interp,		/* The interpreter for error reporting. */
+    int index,			/* index of the attribute command. */
+    Tcl_Obj *fileName,		/* filename we are operating on. */
+    Tcl_Obj **objPtrRef)	/* for output. */
+{
+    TestReport("fileattributesget", fileName, NULL);
+    return Tcl_FSFileAttrsGet(interp, index,
+	    TestReportGetNativePath(fileName), objPtrRef);
+}
+
+static int
+TestReportFileAttrsSet(
+    Tcl_Interp *interp,		/* The interpreter for error reporting. */
+    int index,			/* index of the attribute command. */
+    Tcl_Obj *fileName,		/* filename we are operating on. */
+    Tcl_Obj *objPtr)		/* for input. */
+{
+    TestReport("fileattributesset", fileName, objPtr);
+    return Tcl_FSFileAttrsSet(interp, index,
+	    TestReportGetNativePath(fileName), objPtr);
+}
+
+static int
+TestReportUtime(
+    Tcl_Obj *fileName,
+    struct utimbuf *tval)
+{
+    TestReport("utime", fileName, NULL);
+    return Tcl_FSUtime(TestReportGetNativePath(fileName), tval);
+}
+
+static int
+TestReportNormalizePath(
+    Tcl_Interp *interp,
+    Tcl_Obj *pathPtr,
+    int nextCheckpoint)
+{
+    TestReport("normalizepath", pathPtr, NULL);
+    return nextCheckpoint;
+}
+
+static int
+SimplePathInFilesystem(
+    Tcl_Obj *pathPtr,
+    ClientData *clientDataPtr)
+{
+    const char *str = Tcl_GetString(pathPtr);
+
+    if (strncmp(str, "simplefs:/", 10)) {
+	return -1;
+    }
+    return TCL_OK;
+}
+
+/*
+ * This is a slightly 'hacky' filesystem which is used just to test a few
+ * important features of the vfs code: (1) that you can load a shared library
+ * from a vfs, (2) that when copying files from one fs to another, the 'mtime'
+ * is preserved. (3) that recursive cross-filesystem directory copies have the
+ * correct behaviour with/without -force.
+ *
+ * It treats any file in 'simplefs:/' as a file, which it routes to the
+ * current directory. The real file it uses is whatever follows the trailing
+ * '/' (e.g. 'foo' in 'simplefs:/foo'), and that file exists or not according
+ * to what is in the native pwd.
+ *
+ * Please do not consider this filesystem a model of how things are to be
+ * done. It is quite the opposite!  But, it does allow us to test some
+ * important features.
+ */
+
+static int
+TestSimpleFilesystemObjCmd(
+    ClientData dummy,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const objv[])
+{
+    int res, boolVal;
+    const char *msg;
+
+    if (objc != 2) {
+	Tcl_WrongNumArgs(interp, 1, objv, "boolean");
+	return TCL_ERROR;
+    }
+    if (Tcl_GetBooleanFromObj(interp, objv[1], &boolVal) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    if (boolVal) {
+	res = Tcl_FSRegister((ClientData)interp, &simpleFilesystem);
+	msg = (res == TCL_OK) ? "registered" : "failed";
+    } else {
+	res = Tcl_FSUnregister(&simpleFilesystem);
+	msg = (res == TCL_OK) ? "unregistered" : "failed";
+    }
+    Tcl_SetObjResult(interp, Tcl_NewStringObj(msg , -1));
+    return res;
+}
+
+/*
+ * Treats a file name 'simplefs:/foo' by using the file 'foo' in the current
+ * (native) directory.
+ */
+
+static Tcl_Obj *
+SimpleRedirect(
+    Tcl_Obj *pathPtr)		/* Name of file to copy. */
+{
+    int len;
+    const char *str;
+    Tcl_Obj *origPtr;
+
+    /*
+     * We assume the same name in the current directory is ok.
+     */
+
+    str = Tcl_GetStringFromObj(pathPtr, &len);
+    if (len < 10 || strncmp(str, "simplefs:/", 10)) {
+	/* Probably shouldn't ever reach here */
+	Tcl_IncrRefCount(pathPtr);
+	return pathPtr;
+    }
+    origPtr = Tcl_NewStringObj(str+10,-1);
+    Tcl_IncrRefCount(origPtr);
+    return origPtr;
+}
+
+static int
+SimpleMatchInDirectory(
+    Tcl_Interp *interp,		/* Interpreter for error
+				 * messages. */
+    Tcl_Obj *resultPtr,		/* Object to lappend results. */
+    Tcl_Obj *dirPtr,		/* Contains path to directory to search. */
+    const char *pattern,	/* Pattern to match against. */
+    Tcl_GlobTypeData *types)	/* Object containing list of acceptable types.
+				 * May be NULL. */
+{
+    int res;
+    Tcl_Obj *origPtr;
+    Tcl_Obj *resPtr;
+
+    /* We only provide a new volume, therefore no mounts at all */
+    if (types != NULL && types->type & TCL_GLOB_TYPE_MOUNT) {
+	return TCL_OK;
+    }
+
+    /*
+     * We assume the same name in the current directory is ok.
+     */
+    resPtr = Tcl_NewObj();
+    Tcl_IncrRefCount(resPtr);
+    origPtr = SimpleRedirect(dirPtr);
+    res = Tcl_FSMatchInDirectory(interp, resPtr, origPtr, pattern, types);
+    if (res == TCL_OK) {
+	int gLength, j;
+	Tcl_ListObjLength(NULL, resPtr, &gLength);
+	for (j = 0; j < gLength; j++) {
+	    Tcl_Obj *gElt, *nElt;
+	    Tcl_ListObjIndex(NULL, resPtr, j, &gElt);
+	    nElt = Tcl_NewStringObj("simplefs:/",10);
+	    Tcl_AppendObjToObj(nElt, gElt);
+	    Tcl_ListObjAppendElement(NULL, resultPtr, nElt);
+	}
+    }
+    Tcl_DecrRefCount(origPtr);
+    Tcl_DecrRefCount(resPtr);
+    return res;
+}
+
+static Tcl_Channel
+SimpleOpenFileChannel(
+    Tcl_Interp *interp,		/* Interpreter for error reporting; can be
+				 * NULL. */
+    Tcl_Obj *pathPtr,		/* Name of file to open. */
+    int mode,			/* POSIX open mode. */
+    int permissions)		/* If the open involves creating a file, with
+				 * what modes to create it? */
+{
+    Tcl_Obj *tempPtr;
+    Tcl_Channel chan;
+
+    if ((mode != 0) && !(mode & O_RDONLY)) {
+	Tcl_AppendResult(interp, "read-only", NULL);
+	return NULL;
+    }
+
+    tempPtr = SimpleRedirect(pathPtr);
+    chan = Tcl_FSOpenFileChannel(interp, tempPtr, "r", permissions);
+    Tcl_DecrRefCount(tempPtr);
+    return chan;
+}
+
+static int
+SimpleAccess(
+    Tcl_Obj *pathPtr,		/* Path of file to access (in current CP). */
+    int mode)			/* Permission setting. */
+{
+    Tcl_Obj *tempPtr = SimpleRedirect(pathPtr);
+    int res = Tcl_FSAccess(tempPtr, mode);
+
+    Tcl_DecrRefCount(tempPtr);
+    return res;
+}
+
+static int
+SimpleStat(
+    Tcl_Obj *pathPtr,		/* Path of file to stat (in current CP). */
+    Tcl_StatBuf *bufPtr)	/* Filled with results of stat call. */
+{
+    Tcl_Obj *tempPtr = SimpleRedirect(pathPtr);
+    int res = Tcl_FSStat(tempPtr, bufPtr);
+
+    Tcl_DecrRefCount(tempPtr);
+    return res;
+}
+
+static Tcl_Obj *
+SimpleListVolumes(void)
+{
+    /* Add one new volume */
+    Tcl_Obj *retVal;
+
+    retVal = Tcl_NewStringObj("simplefs:/", -1);
+    Tcl_IncrRefCount(retVal);
+    return retVal;
+}
+
+/*
+ * Used to check correct string-length determining in Tcl_NumUtfChars
+ */
+
+static int
+TestNumUtfCharsCmd(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const objv[])
+{
+    if (objc > 1) {
+	int len = -1;
+
+	if (objc > 2) {
+	    (void) Tcl_GetStringFromObj(objv[1], &len);
+	}
+	len = Tcl_NumUtfChars(Tcl_GetString(objv[1]), len);
+	Tcl_SetObjResult(interp, Tcl_NewIntObj(len));
+    }
+    return TCL_OK;
+}
+
+#if defined(HAVE_CPUID) || defined(_WIN32)
+/*
+ *----------------------------------------------------------------------
+ *
+ * TestcpuidCmd --
+ *
+ *	Retrieves CPU ID information.
+ *
+ * Usage:
+ *	testwincpuid <eax>
+ *
+ * Parameters:
+ *	eax - The value to pass in the EAX register to a CPUID instruction.
+ *
+ * Results:
+ *	Returns a four-element list containing the values from the EAX, EBX,
+ *	ECX and EDX registers returned from the CPUID instruction.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+TestcpuidCmd(
+    ClientData dummy,
+    Tcl_Interp* interp,		/* Tcl interpreter */
+    int objc,			/* Parameter count */
+    Tcl_Obj *const * objv)	/* Parameter vector */
+{
+    int status, index, i;
+    unsigned int regs[4];
+    Tcl_Obj *regsObjs[4];
+
+    if (objc != 2) {
+	Tcl_WrongNumArgs(interp, 1, objv, "eax");
+	return TCL_ERROR;
+    }
+    if (Tcl_GetIntFromObj(interp, objv[1], &index) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    status = TclWinCPUID((unsigned) index, regs);
+    if (status != TCL_OK) {
+	Tcl_SetObjResult(interp,
+		Tcl_NewStringObj("operation not available", -1));
+	return status;
+    }
+    for (i=0 ; i<4 ; ++i) {
+	regsObjs[i] = Tcl_NewIntObj((int) regs[i]);
+    }
+    Tcl_SetObjResult(interp, Tcl_NewListObj(4, regsObjs));
+    return TCL_OK;
+}
+#endif
+
+/*
+ * Used to do basic checks of the TCL_HASH_KEY_SYSTEM_HASH flag
+ */
+
+static int
+TestHashSystemHashCmd(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const objv[])
+{
+    static const Tcl_HashKeyType hkType = {
+	TCL_HASH_KEY_TYPE_VERSION, TCL_HASH_KEY_SYSTEM_HASH,
+	NULL, NULL, NULL, NULL
+    };
+    Tcl_HashTable hash;
+    Tcl_HashEntry *hPtr;
+    int i, isNew, limit = 100;
+
+    if (objc>1 && Tcl_GetIntFromObj(interp, objv[1], &limit)!=TCL_OK) {
+	return TCL_ERROR;
+    }
+
+    Tcl_InitCustomHashTable(&hash, TCL_CUSTOM_TYPE_KEYS, &hkType);
+
+    if (hash.numEntries != 0) {
+	Tcl_AppendResult(interp, "non-zero initial size", NULL);
+	Tcl_DeleteHashTable(&hash);
+	return TCL_ERROR;
+    }
+
+    for (i=0 ; i<limit ; i++) {
+	hPtr = Tcl_CreateHashEntry(&hash, INT2PTR(i), &isNew);
+	if (!isNew) {
+	    Tcl_SetObjResult(interp, Tcl_NewIntObj(i));
+	    Tcl_AppendToObj(Tcl_GetObjResult(interp)," creation problem",-1);
+	    Tcl_DeleteHashTable(&hash);
+	    return TCL_ERROR;
+	}
+	Tcl_SetHashValue(hPtr, INT2PTR(i+42));
+    }
+
+    if (hash.numEntries != limit) {
+	Tcl_AppendResult(interp, "unexpected maximal size", NULL);
+	Tcl_DeleteHashTable(&hash);
+	return TCL_ERROR;
+    }
+
+    for (i=0 ; i<limit ; i++) {
+	hPtr = Tcl_FindHashEntry(&hash, (char *) INT2PTR(i));
+	if (hPtr == NULL) {
+	    Tcl_SetObjResult(interp, Tcl_NewIntObj(i));
+	    Tcl_AppendToObj(Tcl_GetObjResult(interp)," lookup problem",-1);
+	    Tcl_DeleteHashTable(&hash);
+	    return TCL_ERROR;
+	}
+	if (PTR2INT(Tcl_GetHashValue(hPtr)) != i+42) {
+	    Tcl_SetObjResult(interp, Tcl_NewIntObj(i));
+	    Tcl_AppendToObj(Tcl_GetObjResult(interp)," value problem",-1);
+	    Tcl_DeleteHashTable(&hash);
+	    return TCL_ERROR;
+	}
+	Tcl_DeleteHashEntry(hPtr);
+    }
+
+    if (hash.numEntries != 0) {
+	Tcl_AppendResult(interp, "non-zero final size", NULL);
+	Tcl_DeleteHashTable(&hash);
+	return TCL_ERROR;
+    }
+
+    Tcl_DeleteHashTable(&hash);
+    Tcl_AppendResult(interp, "OK", NULL);
+    return TCL_OK;
+}
+
+/*
+ * Used for testing Tcl_GetInt which is no longer used directly by the
+ * core very much.
+ */
+static int
+TestgetintCmd(
+    ClientData dummy,
+    Tcl_Interp *interp,
+    int argc,
+    const char **argv)
+{
+    if (argc < 2) {
+	Tcl_SetResult(interp, "wrong # args", TCL_STATIC);
+	return TCL_ERROR;
+    } else {
+	int val, i, total=0;
+
+	for (i=1 ; i<argc ; i++) {
+	    if (Tcl_GetInt(interp, argv[i], &val) != TCL_OK) {
+		return TCL_ERROR;
+	    }
+	    total += val;
+	}
+	Tcl_SetObjResult(interp, Tcl_NewIntObj(total));
+	return TCL_OK;
+    }
+}
+
+static int
+NREUnwind_callback(
+    ClientData data[],
+    Tcl_Interp *interp,
+    int result)
+{
+    int none;
+
+    if (data[0] == INT2PTR(-1)) {
+        Tcl_NRAddCallback(interp, NREUnwind_callback, &none, INT2PTR(-1),
+                INT2PTR(-1), NULL);
+    } else if (data[1] == INT2PTR(-1)) {
+        Tcl_NRAddCallback(interp, NREUnwind_callback, data[0], &none,
+                INT2PTR(-1), NULL);
+    } else if (data[2] == INT2PTR(-1)) {
+        Tcl_NRAddCallback(interp, NREUnwind_callback, data[0], data[1],
+                &none, NULL);
+    } else {
+        Tcl_Obj *idata[3];
+        idata[0] = Tcl_NewIntObj((int) ((char *) data[1] - (char *) data[0]));
+        idata[1] = Tcl_NewIntObj((int) ((char *) data[2] - (char *) data[0]));
+        idata[2] = Tcl_NewIntObj((int) ((char *) &none   - (char *) data[0]));
+        Tcl_SetObjResult(interp, Tcl_NewListObj(3, idata));
+    }
+    return TCL_OK;
+}
+
+static int
+TestNREUnwind(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const objv[])
+{
+    /*
+     * Insure that callbacks effectively run at the proper level during the
+     * unwinding of the NRE stack.
+     */
+
+    Tcl_NRAddCallback(interp, NREUnwind_callback, INT2PTR(-1), INT2PTR(-1),
+            INT2PTR(-1), NULL);
+    return TCL_OK;
+}
+
+
+static int
+TestNRELevels(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const objv[])
+{
+    Interp *iPtr = (Interp *) interp;
+    static ptrdiff_t *refDepth = NULL;
+    ptrdiff_t depth;
+    Tcl_Obj *levels[6];
+    int i = 0;
+    NRE_callback *cbPtr = iPtr->execEnvPtr->callbackPtr;
+
+    if (refDepth == NULL) {
+	refDepth = &depth;
+    }
+
+    depth = (refDepth - &depth);
+
+    levels[0] = Tcl_NewIntObj(depth);
+    levels[1] = Tcl_NewIntObj(iPtr->numLevels);
+    levels[2] = Tcl_NewIntObj(iPtr->cmdFramePtr->level);
+    levels[3] = Tcl_NewIntObj(iPtr->varFramePtr->level);
+    levels[4] = Tcl_NewIntObj(iPtr->execEnvPtr->execStackPtr->tosPtr
+	    - iPtr->execEnvPtr->execStackPtr->stackWords);
+
+    while (cbPtr) {
+	i++;
+	cbPtr = cbPtr->nextPtr;
+    }
+    levels[5] = Tcl_NewIntObj(i);
+
+    Tcl_SetObjResult(interp, Tcl_NewListObj(6, levels));
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TestconcatobjCmd --
+ *
+ *	This procedure implements the "testconcatobj" command. It is used
+ *	to test that Tcl_ConcatObj does indeed return a fresh Tcl_Obj in all
+ *	cases and thet it never corrupts its arguments. In other words, that
+ *	[Bug 1447328] was fixed properly.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+TestconcatobjCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int argc,			/* Number of arguments. */
+    const char **argv)		/* Argument strings. */
+{
+    Tcl_Obj *list1Ptr, *list2Ptr, *emptyPtr, *concatPtr, *tmpPtr;
+    int result = TCL_OK, len;
+    Tcl_Obj *objv[3];
+
+    /*
+     * Set the start of the error message as obj result; it will be cleared at
+     * the end if no errors were found.
+     */
+
+    Tcl_SetObjResult(interp,
+	    Tcl_NewStringObj("Tcl_ConcatObj is unsafe:", -1));
+
+    emptyPtr = Tcl_NewObj();
+
+    list1Ptr = Tcl_NewStringObj("foo bar sum", -1);
+    Tcl_ListObjLength(NULL, list1Ptr, &len);
+    if (list1Ptr->bytes != NULL) {
+	ckfree(list1Ptr->bytes);
+	list1Ptr->bytes = NULL;
+    }
+
+    list2Ptr = Tcl_NewStringObj("eeny meeny", -1);
+    Tcl_ListObjLength(NULL, list2Ptr, &len);
+    if (list2Ptr->bytes != NULL) {
+	ckfree(list2Ptr->bytes);
+	list2Ptr->bytes = NULL;
+    }
+
+    /*
+     * Verify that concat'ing a list obj with one or more empty strings does
+     * return a fresh Tcl_Obj (see also [Bug 2055782]).
+     */
+
+    tmpPtr = Tcl_DuplicateObj(list1Ptr);
+
+    objv[0] = tmpPtr;
+    objv[1] = emptyPtr;
+    concatPtr = Tcl_ConcatObj(2, objv);
+    if (concatPtr->refCount != 0) {
+	result = TCL_ERROR;
+	Tcl_AppendResult(interp,
+		"\n\t* (a) concatObj does not have refCount 0", NULL);
+    }
+    if (concatPtr == tmpPtr) {
+	result = TCL_ERROR;
+	Tcl_AppendResult(interp, "\n\t* (a) concatObj is not a new obj ",
+		NULL);
+	switch (tmpPtr->refCount) {
+	case 0:
+	    Tcl_AppendResult(interp, "(no new refCount)", NULL);
+	    break;
+	case 1:
+	    Tcl_AppendResult(interp, "(refCount added)", NULL);
+	    break;
+	default:
+	    Tcl_AppendResult(interp, "(more than one refCount added!)", NULL);
+	    Tcl_Panic("extremely unsafe behaviour by Tcl_ConcatObj()");
+	}
+	tmpPtr = Tcl_DuplicateObj(list1Ptr);
+	objv[0] = tmpPtr;
+    }
+    Tcl_DecrRefCount(concatPtr);
+
+    Tcl_IncrRefCount(tmpPtr);
+    concatPtr = Tcl_ConcatObj(2, objv);
+    if (concatPtr->refCount != 0) {
+	result = TCL_ERROR;
+	Tcl_AppendResult(interp,
+		"\n\t* (b) concatObj does not have refCount 0", NULL);
+    }
+    if (concatPtr == tmpPtr) {
+	result = TCL_ERROR;
+	Tcl_AppendResult(interp, "\n\t* (b) concatObj is not a new obj ",
+		NULL);
+	switch (tmpPtr->refCount) {
+	case 0:
+	    Tcl_AppendResult(interp, "(refCount removed?)", NULL);
+	    Tcl_Panic("extremely unsafe behaviour by Tcl_ConcatObj()");
+	    break;
+	case 1:
+	    Tcl_AppendResult(interp, "(no new refCount)", NULL);
+	    break;
+	case 2:
+	    Tcl_AppendResult(interp, "(refCount added)", NULL);
+	    Tcl_DecrRefCount(tmpPtr);
+	    break;
+	default:
+	    Tcl_AppendResult(interp, "(more than one refCount added!)", NULL);
+	    Tcl_Panic("extremely unsafe behaviour by Tcl_ConcatObj()");
+	}
+	tmpPtr = Tcl_DuplicateObj(list1Ptr);
+	objv[0] = tmpPtr;
+    }
+    Tcl_DecrRefCount(concatPtr);
+
+    objv[0] = emptyPtr;
+    objv[1] = tmpPtr;
+    objv[2] = emptyPtr;
+    concatPtr = Tcl_ConcatObj(3, objv);
+    if (concatPtr->refCount != 0) {
+	result = TCL_ERROR;
+	Tcl_AppendResult(interp,
+		"\n\t* (c) concatObj does not have refCount 0", NULL);
+    }
+    if (concatPtr == tmpPtr) {
+	result = TCL_ERROR;
+	Tcl_AppendResult(interp, "\n\t* (c) concatObj is not a new obj ",
+		NULL);
+	switch (tmpPtr->refCount) {
+	case 0:
+	    Tcl_AppendResult(interp, "(no new refCount)", NULL);
+	    break;
+	case 1:
+	    Tcl_AppendResult(interp, "(refCount added)", NULL);
+	    break;
+	default:
+	    Tcl_AppendResult(interp, "(more than one refCount added!)", NULL);
+	    Tcl_Panic("extremely unsafe behaviour by Tcl_ConcatObj()");
+	}
+	tmpPtr = Tcl_DuplicateObj(list1Ptr);
+	objv[1] = tmpPtr;
+    }
+    Tcl_DecrRefCount(concatPtr);
+
+    Tcl_IncrRefCount(tmpPtr);
+    concatPtr = Tcl_ConcatObj(3, objv);
+    if (concatPtr->refCount != 0) {
+	result = TCL_ERROR;
+	Tcl_AppendResult(interp,
+		"\n\t* (d) concatObj does not have refCount 0", NULL);
+    }
+    if (concatPtr == tmpPtr) {
+	result = TCL_ERROR;
+	Tcl_AppendResult(interp, "\n\t* (d) concatObj is not a new obj ",
+		NULL);
+	switch (tmpPtr->refCount) {
+	case 0:
+	    Tcl_AppendResult(interp, "(refCount removed?)", NULL);
+	    Tcl_Panic("extremely unsafe behaviour by Tcl_ConcatObj()");
+	    break;
+	case 1:
+	    Tcl_AppendResult(interp, "(no new refCount)", NULL);
+	    break;
+	case 2:
+	    Tcl_AppendResult(interp, "(refCount added)", NULL);
+	    Tcl_DecrRefCount(tmpPtr);
+	    break;
+	default:
+	    Tcl_AppendResult(interp, "(more than one refCount added!)", NULL);
+	    Tcl_Panic("extremely unsafe behaviour by Tcl_ConcatObj()");
+	}
+	tmpPtr = Tcl_DuplicateObj(list1Ptr);
+	objv[1] = tmpPtr;
+    }
+    Tcl_DecrRefCount(concatPtr);
+
+    /*
+     * Verify that an unshared list is not corrupted when concat'ing things to
+     * it.
+     */
+
+    objv[0] = tmpPtr;
+    objv[1] = list2Ptr;
+    concatPtr = Tcl_ConcatObj(2, objv);
+    if (concatPtr->refCount != 0) {
+	result = TCL_ERROR;
+	Tcl_AppendResult(interp,
+		"\n\t* (e) concatObj does not have refCount 0", NULL);
+    }
+    if (concatPtr == tmpPtr) {
+	int len;
+
+	result = TCL_ERROR;
+	Tcl_AppendResult(interp, "\n\t* (e) concatObj is not a new obj ",
+		NULL);
+
+	(void) Tcl_ListObjLength(NULL, concatPtr, &len);
+	switch (tmpPtr->refCount) {
+	case 3:
+	    Tcl_AppendResult(interp, "(failed to concat)", NULL);
+	    break;
+	default:
+	    Tcl_AppendResult(interp, "(corrupted input!)", NULL);
+	}
+	if (Tcl_IsShared(tmpPtr)) {
+	    Tcl_DecrRefCount(tmpPtr);
+	}
+	tmpPtr = Tcl_DuplicateObj(list1Ptr);
+	objv[0] = tmpPtr;
+    }
+    Tcl_DecrRefCount(concatPtr);
+
+    objv[0] = tmpPtr;
+    objv[1] = list2Ptr;
+    Tcl_IncrRefCount(tmpPtr);
+    concatPtr = Tcl_ConcatObj(2, objv);
+    if (concatPtr->refCount != 0) {
+	result = TCL_ERROR;
+	Tcl_AppendResult(interp,
+		"\n\t* (f) concatObj does not have refCount 0", NULL);
+    }
+    if (concatPtr == tmpPtr) {
+	int len;
+
+	result = TCL_ERROR;
+	Tcl_AppendResult(interp, "\n\t* (f) concatObj is not a new obj ",
+		NULL);
+
+	(void) Tcl_ListObjLength(NULL, concatPtr, &len);
+	switch (tmpPtr->refCount) {
+	case 3:
+	    Tcl_AppendResult(interp, "(failed to concat)", NULL);
+	    break;
+	default:
+	    Tcl_AppendResult(interp, "(corrupted input!)", NULL);
+	}
+	if (Tcl_IsShared(tmpPtr)) {
+	    Tcl_DecrRefCount(tmpPtr);
+	}
+	tmpPtr = Tcl_DuplicateObj(list1Ptr);
+	objv[0] = tmpPtr;
+    }
+    Tcl_DecrRefCount(concatPtr);
+
+    objv[0] = tmpPtr;
+    objv[1] = list2Ptr;
+    Tcl_IncrRefCount(tmpPtr);
+    Tcl_IncrRefCount(tmpPtr);
+    concatPtr = Tcl_ConcatObj(2, objv);
+    if (concatPtr->refCount != 0) {
+	result = TCL_ERROR;
+	Tcl_AppendResult(interp,
+		"\n\t* (g) concatObj does not have refCount 0", NULL);
+    }
+    if (concatPtr == tmpPtr) {
+	int len;
+
+	result = TCL_ERROR;
+	Tcl_AppendResult(interp, "\n\t* (g) concatObj is not a new obj ",
+		NULL);
+
+	(void) Tcl_ListObjLength(NULL, concatPtr, &len);
+	switch (tmpPtr->refCount) {
+	case 3:
+	    Tcl_AppendResult(interp, "(failed to concat)", NULL);
+	    break;
+	default:
+	    Tcl_AppendResult(interp, "(corrupted input!)", NULL);
+	}
+	Tcl_DecrRefCount(tmpPtr);
+	if (Tcl_IsShared(tmpPtr)) {
+	    Tcl_DecrRefCount(tmpPtr);
+	}
+	tmpPtr = Tcl_DuplicateObj(list1Ptr);
+	objv[0] = tmpPtr;
+    }
+    Tcl_DecrRefCount(concatPtr);
+
+    /*
+     * Clean everything up. Note that we don't actually know how many
+     * references there are to tmpPtr here; in the no-error case, it should be
+     * five... [Bug 2895367]
+     */
+
+    Tcl_DecrRefCount(list1Ptr);
+    Tcl_DecrRefCount(list2Ptr);
+    Tcl_DecrRefCount(emptyPtr);
+    while (tmpPtr->refCount > 1) {
+	Tcl_DecrRefCount(tmpPtr);
+    }
+    Tcl_DecrRefCount(tmpPtr);
+
+    if (result == TCL_OK) {
+	Tcl_ResetResult(interp);
+    }
+    return result;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TestparseargsCmd --
+ *
+ *	This procedure implements the "testparseargs" command. It is used to
+ *	test that Tcl_ParseArgsObjv does indeed return the right number of
+ *	arguments. In other words, that [Bug 3413857] was fixed properly.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+TestparseargsCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Arguments. */
+{
+    static int foo = 0;
+    int count = objc;
+    Tcl_Obj **remObjv, *result[3];
+    Tcl_ArgvInfo argTable[] = {
+        {TCL_ARGV_CONSTANT, "-bool", INT2PTR(1), &foo, "booltest", NULL},
+        TCL_ARGV_AUTO_REST, TCL_ARGV_AUTO_HELP, TCL_ARGV_TABLE_END
+    };
+
+    foo = 0;
+    if (Tcl_ParseArgsObjv(interp, argTable, &count, objv, &remObjv)!=TCL_OK) {
+        return TCL_ERROR;
+    }
+    result[0] = Tcl_NewIntObj(foo);
+    result[1] = Tcl_NewIntObj(count);
+    result[2] = Tcl_NewListObj(count, remObjv);
+    Tcl_SetObjResult(interp, Tcl_NewListObj(3, result));
+    ckfree(remObjv);
+    return TCL_OK;
+}
+
+/**
+ * Test harness for command and variable resolvers.
+ */
+
+static int
+InterpCmdResolver(
+    Tcl_Interp *interp,
+    const char *name,
+    Tcl_Namespace *context,
+    int flags,
+    Tcl_Command *rPtr)
+{
+    Interp *iPtr = (Interp *) interp;
+    CallFrame *varFramePtr = iPtr->varFramePtr;
+    Proc *procPtr = (varFramePtr->isProcCallFrame & FRAME_IS_PROC) ?
+            varFramePtr->procPtr : NULL;
+    Namespace *ns2NsPtr = (Namespace *)
+            Tcl_FindNamespace(interp, "::ns2", NULL, 0);
+
+    if (procPtr && (procPtr->cmdPtr->nsPtr == iPtr->globalNsPtr
+            || (ns2NsPtr && procPtr->cmdPtr->nsPtr == ns2NsPtr))) {
+        const char *callingCmdName =
+                Tcl_GetCommandName(interp, (Tcl_Command) procPtr->cmdPtr);
+
+        if ((callingCmdName[0] == 'x') && (callingCmdName[1] == '\0')
+                && (name[0] == 'z') && (name[1] == '\0')) {
+            Tcl_Command sourceCmdPtr = Tcl_FindCommand(interp, "y", NULL,
+                    TCL_GLOBAL_ONLY);
+
+            if (sourceCmdPtr != NULL) {
+                *rPtr = sourceCmdPtr;
+                return TCL_OK;
+            }
+        }
+    }
+    return TCL_CONTINUE;
+}
+
+static int
+InterpVarResolver(
+    Tcl_Interp *interp,
+    const char *name,
+    Tcl_Namespace *context,
+    int flags,
+    Tcl_Var *rPtr)
+{
+    /*
+     * Don't resolve the variable; use standard rules.
+     */
+
+    return TCL_CONTINUE;
+}
+
+typedef struct MyResolvedVarInfo {
+    Tcl_ResolvedVarInfo vInfo;  /* This must be the first element. */
+    Tcl_Var var;
+    Tcl_Obj *nameObj;
+} MyResolvedVarInfo;
+
+static inline void
+HashVarFree(
+    Tcl_Var var)
+{
+    if (VarHashRefCount(var) < 2) {
+        ckfree(var);
+    } else {
+        VarHashRefCount(var)--;
+    }
+}
+
+static void
+MyCompiledVarFree(
+    Tcl_ResolvedVarInfo *vInfoPtr)
+{
+    MyResolvedVarInfo *resVarInfo = (MyResolvedVarInfo *) vInfoPtr;
+
+    Tcl_DecrRefCount(resVarInfo->nameObj);
+    if (resVarInfo->var) {
+        HashVarFree(resVarInfo->var);
+    }
+    ckfree(vInfoPtr);
+}
+
+#define TclVarHashGetValue(hPtr) \
+    ((Var *) ((char *)hPtr - TclOffset(VarInHash, entry)))
+
+static Tcl_Var
+MyCompiledVarFetch(
+    Tcl_Interp *interp,
+    Tcl_ResolvedVarInfo *vinfoPtr)
+{
+    MyResolvedVarInfo *resVarInfo = (MyResolvedVarInfo *) vinfoPtr;
+    Tcl_Var var = resVarInfo->var;
+    int isNewVar;
+    Interp *iPtr = (Interp *) interp;
+    Tcl_HashEntry *hPtr;
+
+    if (var != NULL) {
+        if (!(((Var *) var)->flags & VAR_DEAD_HASH)) {
+            /*
+             * The cached variable is valid, return it.
+             */
+
+            return var;
+        }
+
+        /*
+         * The variable is not valid anymore. Clean it up.
+         */
+
+        HashVarFree(var);
+    }
+
+    hPtr = Tcl_CreateHashEntry((Tcl_HashTable *) &iPtr->globalNsPtr->varTable,
+            (char *) resVarInfo->nameObj, &isNewVar);
+    if (hPtr) {
+        var = (Tcl_Var) TclVarHashGetValue(hPtr);
+    } else {
+        var = NULL;
+    }
+    resVarInfo->var = var;
+
+    /*
+     * Increment the reference counter to avoid ckfree() of the variable in
+     * Tcl's FreeVarEntry(); for cleanup, we provide our own HashVarFree();
+     */
+
+    VarHashRefCount(var)++;
+    return var;
+}
+
+static int
+InterpCompiledVarResolver(
+    Tcl_Interp *interp,
+    const char *name,
+    int length,
+    Tcl_Namespace *context,
+    Tcl_ResolvedVarInfo **rPtr)
+{
+    if (*name == 'T') {
+ 	MyResolvedVarInfo *resVarInfo = ckalloc(sizeof(MyResolvedVarInfo));
+
+ 	resVarInfo->vInfo.fetchProc = MyCompiledVarFetch;
+ 	resVarInfo->vInfo.deleteProc = MyCompiledVarFree;
+ 	resVarInfo->var = NULL;
+ 	resVarInfo->nameObj = Tcl_NewStringObj(name, -1);
+ 	Tcl_IncrRefCount(resVarInfo->nameObj);
+ 	*rPtr = &resVarInfo->vInfo;
+ 	return TCL_OK;
+    }
+    return TCL_CONTINUE;
+}
+
+static int
+TestInterpResolverCmd(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const objv[])
+{
+    static const char *const table[] = {
+        "down", "up", NULL
+    };
+    int idx;
+#define RESOLVER_KEY "testInterpResolver"
+
+    if (objc != 2) {
+        Tcl_WrongNumArgs(interp, 1, objv, "up|down");
+ 	return TCL_ERROR;
+    }
+    if (Tcl_GetIndexFromObj(interp, objv[1], table, "operation", TCL_EXACT,
+            &idx) != TCL_OK) {
+        return TCL_ERROR;
+    }
+    switch (idx) {
+    case 1: /* up */
+        Tcl_AddInterpResolvers(interp, RESOLVER_KEY, InterpCmdResolver,
+                InterpVarResolver, InterpCompiledVarResolver);
+        break;
+    case 0: /*down*/
+        if (!Tcl_RemoveInterpResolvers(interp, RESOLVER_KEY)) {
+            Tcl_AppendResult(interp, "could not remove the resolver scheme",
+                    NULL);
+            return TCL_ERROR;
+        }
+    }
+    return TCL_OK;
+}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/generic/tclTestObj.c b/generic/tclTestObj.c
new file mode 100644
index 0000000..a637498
--- /dev/null
+++ b/generic/tclTestObj.c
@@ -0,0 +1,1495 @@
+/*
+ * tclTestObj.c --
+ *
+ *	This file contains C command functions for the additional Tcl commands
+ *	that are used for testing implementations of the Tcl object types.
+ *	These commands are not normally included in Tcl applications; they're
+ *	only used for testing.
+ *
+ * Copyright (c) 1995-1998 Sun Microsystems, Inc.
+ * Copyright (c) 1999 by Scriptics Corporation.
+ * Copyright (c) 2005 by Kevin B. Kenny.  All rights reserved.
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#ifndef USE_TCL_STUBS
+#   define USE_TCL_STUBS
+#endif
+#include "tclInt.h"
+#include "tommath.h"
+#include "tclStringRep.h"
+
+
+/*
+ * Forward declarations for functions defined later in this file:
+ */
+
+static int		CheckIfVarUnset(Tcl_Interp *interp, Tcl_Obj **varPtr, int varIndex);
+static int		GetVariableIndex(Tcl_Interp *interp,
+			    const char *string, int *indexPtr);
+static void		SetVarToObj(Tcl_Obj **varPtr, int varIndex, Tcl_Obj *objPtr);
+static int		TestbignumobjCmd(ClientData dummy, Tcl_Interp *interp,
+			    int objc, Tcl_Obj *const objv[]);
+static int		TestbooleanobjCmd(ClientData dummy,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+static int		TestdoubleobjCmd(ClientData dummy, Tcl_Interp *interp,
+			    int objc, Tcl_Obj *const objv[]);
+static int		TestindexobjCmd(ClientData dummy, Tcl_Interp *interp,
+			    int objc, Tcl_Obj *const objv[]);
+static int		TestintobjCmd(ClientData dummy, Tcl_Interp *interp,
+			    int objc, Tcl_Obj *const objv[]);
+static int 		TestlistobjCmd(ClientData dummy, Tcl_Interp *interp,
+			    int objc, Tcl_Obj *const objv[]);
+static int		TestobjCmd(ClientData dummy, Tcl_Interp *interp,
+			    int objc, Tcl_Obj *const objv[]);
+static int		TeststringobjCmd(ClientData dummy, Tcl_Interp *interp,
+			    int objc, Tcl_Obj *const objv[]);
+
+#define VARPTR_KEY "TCLOBJTEST_VARPTR"
+#define NUMBER_OF_OBJECT_VARS 20
+
+static void VarPtrDeleteProc(ClientData clientData, Tcl_Interp *interp)
+{
+    register int i;
+    Tcl_Obj **varPtr = (Tcl_Obj **) clientData;
+    for (i = 0;  i < NUMBER_OF_OBJECT_VARS;  i++) {
+	if (varPtr[i]) Tcl_DecrRefCount(varPtr[i]);
+    }
+    Tcl_DeleteAssocData(interp, VARPTR_KEY);
+    ckfree(varPtr);
+}
+
+static Tcl_Obj **GetVarPtr(Tcl_Interp *interp)
+{
+    Tcl_InterpDeleteProc *proc;
+
+    return (Tcl_Obj **) Tcl_GetAssocData(interp, VARPTR_KEY, &proc);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclObjTest_Init --
+ *
+ *	This function creates additional commands that are used to test the
+ *	Tcl object support.
+ *
+ * Results:
+ *	Returns a standard Tcl completion code, and leaves an error
+ *	message in the interp's result if an error occurs.
+ *
+ * Side effects:
+ *	Creates and registers several new testing commands.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclObjTest_Init(
+    Tcl_Interp *interp)
+{
+    register int i;
+    /*
+     * An array of Tcl_Obj pointers used in the commands that operate on or get
+     * the values of Tcl object-valued variables. varPtr[i] is the i-th variable's
+     * Tcl_Obj *.
+     */
+    Tcl_Obj **varPtr;
+
+    varPtr = (Tcl_Obj **) ckalloc(NUMBER_OF_OBJECT_VARS *sizeof(varPtr[0]));
+    if (!varPtr) {
+	return TCL_ERROR;
+    }
+    Tcl_SetAssocData(interp, VARPTR_KEY, VarPtrDeleteProc, varPtr);
+    for (i = 0;  i < NUMBER_OF_OBJECT_VARS;  i++) {
+	varPtr[i] = NULL;
+    }
+
+    Tcl_CreateObjCommand(interp, "testbignumobj", TestbignumobjCmd,
+	    NULL, NULL);
+    Tcl_CreateObjCommand(interp, "testbooleanobj", TestbooleanobjCmd,
+	    NULL, NULL);
+    Tcl_CreateObjCommand(interp, "testdoubleobj", TestdoubleobjCmd,
+	    NULL, NULL);
+    Tcl_CreateObjCommand(interp, "testintobj", TestintobjCmd,
+	    NULL, NULL);
+    Tcl_CreateObjCommand(interp, "testindexobj", TestindexobjCmd,
+	    NULL, NULL);
+    Tcl_CreateObjCommand(interp, "testlistobj", TestlistobjCmd,
+	    NULL, NULL);
+    Tcl_CreateObjCommand(interp, "testobj", TestobjCmd, NULL, NULL);
+    Tcl_CreateObjCommand(interp, "teststringobj", TeststringobjCmd,
+	    NULL, NULL);
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TestbignumobjCmd --
+ *
+ *	This function implmenets the "testbignumobj" command.  It is used
+ *	to exercise the bignum Tcl object type implementation.
+ *
+ * Results:
+ *	Returns a standard Tcl object result.
+ *
+ * Side effects:
+ *	Creates and frees bignum objects; converts objects to have bignum
+ *	type.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+TestbignumobjCmd(
+    ClientData clientData,	/* unused */
+    Tcl_Interp *interp,		/* Tcl interpreter */
+    int objc,			/* Argument count */
+    Tcl_Obj *const objv[])	/* Argument vector */
+{
+    const char *const subcmds[] = {
+	"set",	    "get",	"mult10",	"div10", NULL
+    };
+    enum options {
+	BIGNUM_SET, BIGNUM_GET,	BIGNUM_MULT10,	BIGNUM_DIV10
+    };
+    int index, varIndex;
+    const char *string;
+    mp_int bignumValue, newValue;
+    Tcl_Obj **varPtr;
+
+    if (objc < 3) {
+	Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?");
+	return TCL_ERROR;
+    }
+    if (Tcl_GetIndexFromObj(interp, objv[1], subcmds, "option", 0,
+	    &index) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    string = Tcl_GetString(objv[2]);
+    if (GetVariableIndex(interp, string, &varIndex) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    varPtr = GetVarPtr(interp);
+
+    switch (index) {
+    case BIGNUM_SET:
+	if (objc != 4) {
+	    Tcl_WrongNumArgs(interp, 2, objv, "var value");
+	    return TCL_ERROR;
+	}
+	string = Tcl_GetString(objv[3]);
+	if (mp_init(&bignumValue) != MP_OKAY) {
+	    Tcl_SetObjResult(interp,
+		    Tcl_NewStringObj("error in mp_init", -1));
+	    return TCL_ERROR;
+	}
+	if (mp_read_radix(&bignumValue, string, 10) != MP_OKAY) {
+	    mp_clear(&bignumValue);
+	    Tcl_SetObjResult(interp,
+		    Tcl_NewStringObj("error in mp_read_radix", -1));
+	    return TCL_ERROR;
+	}
+
+	/*
+	 * If the object currently bound to the variable with index varIndex
+	 * has ref count 1 (i.e. the object is unshared) we can modify that
+	 * object directly.  Otherwise, if RC>1 (i.e. the object is shared),
+	 * we must create a new object to modify/set and decrement the old
+	 * formerly-shared object's ref count. This is "copy on write".
+	 */
+
+	if ((varPtr[varIndex] != NULL) && !Tcl_IsShared(varPtr[varIndex])) {
+	    Tcl_SetBignumObj(varPtr[varIndex], &bignumValue);
+	} else {
+	    SetVarToObj(varPtr, varIndex, Tcl_NewBignumObj(&bignumValue));
+	}
+	break;
+
+    case BIGNUM_GET:
+	if (objc != 3) {
+	    Tcl_WrongNumArgs(interp, 2, objv, "varIndex");
+	    return TCL_ERROR;
+	}
+	if (CheckIfVarUnset(interp, varPtr,varIndex)) {
+	    return TCL_ERROR;
+	}
+	break;
+
+    case BIGNUM_MULT10:
+	if (objc != 3) {
+	    Tcl_WrongNumArgs(interp, 2, objv, "varIndex");
+	    return TCL_ERROR;
+	}
+	if (CheckIfVarUnset(interp, varPtr,varIndex)) {
+	    return TCL_ERROR;
+	}
+	if (Tcl_GetBignumFromObj(interp, varPtr[varIndex],
+		&bignumValue) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	if (mp_init(&newValue) != MP_OKAY
+		|| (mp_mul_d(&bignumValue, 10, &newValue) != MP_OKAY)) {
+	    mp_clear(&bignumValue);
+	    mp_clear(&newValue);
+	    Tcl_SetObjResult(interp,
+		    Tcl_NewStringObj("error in mp_mul_d", -1));
+	    return TCL_ERROR;
+	}
+	mp_clear(&bignumValue);
+	if (!Tcl_IsShared(varPtr[varIndex])) {
+	    Tcl_SetBignumObj(varPtr[varIndex], &newValue);
+	} else {
+	    SetVarToObj(varPtr, varIndex, Tcl_NewBignumObj(&newValue));
+	}
+	break;
+
+    case BIGNUM_DIV10:
+	if (objc != 3) {
+	    Tcl_WrongNumArgs(interp, 2, objv, "varIndex");
+	    return TCL_ERROR;
+	}
+	if (CheckIfVarUnset(interp, varPtr,varIndex)) {
+	    return TCL_ERROR;
+	}
+	if (Tcl_GetBignumFromObj(interp, varPtr[varIndex],
+		&bignumValue) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	if (mp_init(&newValue) != MP_OKAY
+		|| (mp_div_d(&bignumValue, 10, &newValue, NULL) != MP_OKAY)) {
+	    mp_clear(&bignumValue);
+	    mp_clear(&newValue);
+	    Tcl_SetObjResult(interp,
+		    Tcl_NewStringObj("error in mp_div_d", -1));
+	    return TCL_ERROR;
+	}
+	mp_clear(&bignumValue);
+	if (!Tcl_IsShared(varPtr[varIndex])) {
+	    Tcl_SetBignumObj(varPtr[varIndex], &newValue);
+	} else {
+	    SetVarToObj(varPtr, varIndex, Tcl_NewBignumObj(&newValue));
+	}
+    }
+
+    Tcl_SetObjResult(interp, varPtr[varIndex]);
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TestbooleanobjCmd --
+ *
+ *	This function implements the "testbooleanobj" command.  It is used to
+ *	test the boolean Tcl object type implementation.
+ *
+ * Results:
+ *	A standard Tcl object result.
+ *
+ * Side effects:
+ *	Creates and frees boolean objects, and also converts objects to
+ *	have boolean type.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+TestbooleanobjCmd(
+    ClientData clientData,	/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    int varIndex, boolValue;
+    const char *index, *subCmd;
+    Tcl_Obj **varPtr;
+
+    if (objc < 3) {
+	wrongNumArgs:
+	Tcl_WrongNumArgs(interp, 1, objv, "option arg ?arg ...?");
+	return TCL_ERROR;
+    }
+
+    index = Tcl_GetString(objv[2]);
+    if (GetVariableIndex(interp, index, &varIndex) != TCL_OK) {
+	return TCL_ERROR;
+    }
+
+    varPtr = GetVarPtr(interp);
+
+    subCmd = Tcl_GetString(objv[1]);
+    if (strcmp(subCmd, "set") == 0) {
+	if (objc != 4) {
+	    goto wrongNumArgs;
+	}
+	if (Tcl_GetBooleanFromObj(interp, objv[3], &boolValue) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+
+	/*
+	 * If the object currently bound to the variable with index varIndex
+	 * has ref count 1 (i.e. the object is unshared) we can modify that
+	 * object directly. Otherwise, if RC>1 (i.e. the object is shared),
+	 * we must create a new object to modify/set and decrement the old
+	 * formerly-shared object's ref count. This is "copy on write".
+	 */
+
+	if ((varPtr[varIndex] != NULL) && !Tcl_IsShared(varPtr[varIndex])) {
+	    Tcl_SetBooleanObj(varPtr[varIndex], boolValue);
+	} else {
+	    SetVarToObj(varPtr, varIndex, Tcl_NewBooleanObj(boolValue));
+	}
+	Tcl_SetObjResult(interp, varPtr[varIndex]);
+    } else if (strcmp(subCmd, "get") == 0) {
+	if (objc != 3) {
+	    goto wrongNumArgs;
+	}
+	if (CheckIfVarUnset(interp, varPtr,varIndex)) {
+	    return TCL_ERROR;
+	}
+	Tcl_SetObjResult(interp, varPtr[varIndex]);
+    } else if (strcmp(subCmd, "not") == 0) {
+	if (objc != 3) {
+	    goto wrongNumArgs;
+	}
+	if (CheckIfVarUnset(interp, varPtr,varIndex)) {
+	    return TCL_ERROR;
+	}
+	if (Tcl_GetBooleanFromObj(interp, varPtr[varIndex],
+				  &boolValue) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	if (!Tcl_IsShared(varPtr[varIndex])) {
+	    Tcl_SetBooleanObj(varPtr[varIndex], !boolValue);
+	} else {
+	    SetVarToObj(varPtr, varIndex, Tcl_NewBooleanObj(!boolValue));
+	}
+	Tcl_SetObjResult(interp, varPtr[varIndex]);
+    } else {
+	Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
+		"bad option \"", Tcl_GetString(objv[1]),
+		"\": must be set, get, or not", NULL);
+	return TCL_ERROR;
+    }
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TestdoubleobjCmd --
+ *
+ *	This function implements the "testdoubleobj" command.  It is used to
+ *	test the double-precision floating point Tcl object type
+ *	implementation.
+ *
+ * Results:
+ *	A standard Tcl object result.
+ *
+ * Side effects:
+ *	Creates and frees double objects, and also converts objects to
+ *	have double type.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+TestdoubleobjCmd(
+    ClientData clientData,	/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    int varIndex;
+    double doubleValue;
+    const char *index, *subCmd, *string;
+    Tcl_Obj **varPtr;
+
+    if (objc < 3) {
+	wrongNumArgs:
+	Tcl_WrongNumArgs(interp, 1, objv, "option arg ?arg ...?");
+	return TCL_ERROR;
+    }
+
+    varPtr = GetVarPtr(interp);
+
+    index = Tcl_GetString(objv[2]);
+    if (GetVariableIndex(interp, index, &varIndex) != TCL_OK) {
+	return TCL_ERROR;
+    }
+
+    subCmd = Tcl_GetString(objv[1]);
+    if (strcmp(subCmd, "set") == 0) {
+	if (objc != 4) {
+	    goto wrongNumArgs;
+	}
+	string = Tcl_GetString(objv[3]);
+	if (Tcl_GetDouble(interp, string, &doubleValue) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+
+	/*
+	 * If the object currently bound to the variable with index varIndex
+	 * has ref count 1 (i.e. the object is unshared) we can modify that
+	 * object directly. Otherwise, if RC>1 (i.e. the object is shared), we
+	 * must create a new object to modify/set and decrement the old
+	 * formerly-shared object's ref count. This is "copy on write".
+	 */
+
+	if ((varPtr[varIndex] != NULL) && !Tcl_IsShared(varPtr[varIndex])) {
+	    Tcl_SetDoubleObj(varPtr[varIndex], doubleValue);
+	} else {
+	    SetVarToObj(varPtr, varIndex, Tcl_NewDoubleObj(doubleValue));
+	}
+	Tcl_SetObjResult(interp, varPtr[varIndex]);
+    } else if (strcmp(subCmd, "get") == 0) {
+	if (objc != 3) {
+	    goto wrongNumArgs;
+	}
+	if (CheckIfVarUnset(interp, varPtr,varIndex)) {
+	    return TCL_ERROR;
+	}
+	Tcl_SetObjResult(interp, varPtr[varIndex]);
+    } else if (strcmp(subCmd, "mult10") == 0) {
+	if (objc != 3) {
+	    goto wrongNumArgs;
+	}
+	if (CheckIfVarUnset(interp, varPtr,varIndex)) {
+	    return TCL_ERROR;
+	}
+	if (Tcl_GetDoubleFromObj(interp, varPtr[varIndex],
+				 &doubleValue) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	if (!Tcl_IsShared(varPtr[varIndex])) {
+	    Tcl_SetDoubleObj(varPtr[varIndex], doubleValue * 10.0);
+	} else {
+	    SetVarToObj(varPtr, varIndex, Tcl_NewDoubleObj(doubleValue * 10.0));
+	}
+	Tcl_SetObjResult(interp, varPtr[varIndex]);
+    } else if (strcmp(subCmd, "div10") == 0) {
+	if (objc != 3) {
+	    goto wrongNumArgs;
+	}
+	if (CheckIfVarUnset(interp, varPtr,varIndex)) {
+	    return TCL_ERROR;
+	}
+	if (Tcl_GetDoubleFromObj(interp, varPtr[varIndex],
+		&doubleValue) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	if (!Tcl_IsShared(varPtr[varIndex])) {
+	    Tcl_SetDoubleObj(varPtr[varIndex], doubleValue / 10.0);
+	} else {
+	    SetVarToObj(varPtr, varIndex, Tcl_NewDoubleObj(doubleValue / 10.0));
+	}
+	Tcl_SetObjResult(interp, varPtr[varIndex]);
+    } else {
+	Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
+		"bad option \"", Tcl_GetString(objv[1]),
+		"\": must be set, get, mult10, or div10", NULL);
+	return TCL_ERROR;
+    }
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TestindexobjCmd --
+ *
+ *	This function implements the "testindexobj" command. It is used to
+ *	test the index Tcl object type implementation.
+ *
+ * Results:
+ *	A standard Tcl object result.
+ *
+ * Side effects:
+ *	Creates and frees int objects, and also converts objects to
+ *	have int type.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+TestindexobjCmd(
+    ClientData clientData,	/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    int allowAbbrev, index, index2, setError, i, result;
+    const char **argv;
+    static const char *const tablePtr[] = {"a", "b", "check", NULL};
+    /*
+     * Keep this structure declaration in sync with tclIndexObj.c
+     */
+    struct IndexRep {
+	void *tablePtr;		/* Pointer to the table of strings. */
+	int offset;		/* Offset between table entries. */
+	int index;		/* Selected index into table. */
+    };
+    struct IndexRep *indexRep;
+
+    if ((objc == 3) && (strcmp(Tcl_GetString(objv[1]),
+	    "check") == 0)) {
+	/*
+	 * This code checks to be sure that the results of Tcl_GetIndexFromObj
+	 * are properly cached in the object and returned on subsequent
+	 * lookups.
+	 */
+
+	if (Tcl_GetIntFromObj(interp, objv[2], &index2) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+
+	Tcl_GetIndexFromObj(NULL, objv[1], tablePtr, "token", 0, &index);
+	indexRep = objv[1]->internalRep.twoPtrValue.ptr1;
+	indexRep->index = index2;
+	result = Tcl_GetIndexFromObj(NULL, objv[1],
+		tablePtr, "token", 0, &index);
+	if (result == TCL_OK) {
+	    Tcl_SetIntObj(Tcl_GetObjResult(interp), index);
+	}
+	return result;
+    }
+
+    if (objc < 5) {
+	Tcl_AppendToObj(Tcl_GetObjResult(interp), "wrong # args", -1);
+	return TCL_ERROR;
+    }
+
+    if (Tcl_GetBooleanFromObj(interp, objv[1], &setError) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    if (Tcl_GetBooleanFromObj(interp, objv[2], &allowAbbrev) != TCL_OK) {
+	return TCL_ERROR;
+    }
+
+    argv = ckalloc((objc-3) * sizeof(char *));
+    for (i = 4; i < objc; i++) {
+	argv[i-4] = Tcl_GetString(objv[i]);
+    }
+    argv[objc-4] = NULL;
+
+    /*
+     * Tcl_GetIndexFromObj assumes that the table is statically-allocated so
+     * that its address is different for each index object. If we accidently
+     * allocate a table at the same address as that cached in the index
+     * object, clear out the object's cached state.
+     */
+
+    if (objv[3]->typePtr != NULL
+	    && !strcmp("index", objv[3]->typePtr->name)) {
+	indexRep = objv[3]->internalRep.twoPtrValue.ptr1;
+	if (indexRep->tablePtr == (void *) argv) {
+	    TclFreeIntRep(objv[3]);
+	}
+    }
+
+    result = Tcl_GetIndexFromObj((setError? interp : NULL), objv[3],
+	    argv, "token", (allowAbbrev? 0 : TCL_EXACT), &index);
+    ckfree(argv);
+    if (result == TCL_OK) {
+	Tcl_SetIntObj(Tcl_GetObjResult(interp), index);
+    }
+    return result;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TestintobjCmd --
+ *
+ *	This function implements the "testintobj" command. It is used to
+ *	test the int Tcl object type implementation.
+ *
+ * Results:
+ *	A standard Tcl object result.
+ *
+ * Side effects:
+ *	Creates and frees int objects, and also converts objects to
+ *	have int type.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+TestintobjCmd(
+    ClientData clientData,	/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    int intValue, varIndex, i;
+    long longValue;
+    const char *index, *subCmd, *string;
+    Tcl_Obj **varPtr;
+
+    if (objc < 3) {
+	wrongNumArgs:
+	Tcl_WrongNumArgs(interp, 1, objv, "option arg ?arg ...?");
+	return TCL_ERROR;
+    }
+
+    varPtr = GetVarPtr(interp);
+    index = Tcl_GetString(objv[2]);
+    if (GetVariableIndex(interp, index, &varIndex) != TCL_OK) {
+	return TCL_ERROR;
+    }
+
+    subCmd = Tcl_GetString(objv[1]);
+    if (strcmp(subCmd, "set") == 0) {
+	if (objc != 4) {
+	    goto wrongNumArgs;
+	}
+	string = Tcl_GetString(objv[3]);
+	if (Tcl_GetInt(interp, string, &i) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	intValue = i;
+
+	/*
+	 * If the object currently bound to the variable with index varIndex
+	 * has ref count 1 (i.e. the object is unshared) we can modify that
+	 * object directly. Otherwise, if RC>1 (i.e. the object is shared), we
+	 * must create a new object to modify/set and decrement the old
+	 * formerly-shared object's ref count. This is "copy on write".
+	 */
+
+	if ((varPtr[varIndex] != NULL) && !Tcl_IsShared(varPtr[varIndex])) {
+	    Tcl_SetIntObj(varPtr[varIndex], intValue);
+	} else {
+	    SetVarToObj(varPtr, varIndex, Tcl_NewIntObj(intValue));
+	}
+	Tcl_SetObjResult(interp, varPtr[varIndex]);
+    } else if (strcmp(subCmd, "set2") == 0) { /* doesn't set result */
+	if (objc != 4) {
+	    goto wrongNumArgs;
+	}
+	string = Tcl_GetString(objv[3]);
+	if (Tcl_GetInt(interp, string, &i) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	intValue = i;
+	if ((varPtr[varIndex] != NULL) && !Tcl_IsShared(varPtr[varIndex])) {
+	    Tcl_SetIntObj(varPtr[varIndex], intValue);
+	} else {
+	    SetVarToObj(varPtr, varIndex, Tcl_NewIntObj(intValue));
+	}
+    } else if (strcmp(subCmd, "setlong") == 0) {
+	if (objc != 4) {
+	    goto wrongNumArgs;
+	}
+	string = Tcl_GetString(objv[3]);
+	if (Tcl_GetInt(interp, string, &i) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	intValue = i;
+	if ((varPtr[varIndex] != NULL) && !Tcl_IsShared(varPtr[varIndex])) {
+	    Tcl_SetLongObj(varPtr[varIndex], intValue);
+	} else {
+	    SetVarToObj(varPtr, varIndex, Tcl_NewLongObj(intValue));
+	}
+	Tcl_SetObjResult(interp, varPtr[varIndex]);
+    } else if (strcmp(subCmd, "setmaxlong") == 0) {
+	long maxLong = LONG_MAX;
+	if (objc != 3) {
+	    goto wrongNumArgs;
+	}
+	if ((varPtr[varIndex] != NULL) && !Tcl_IsShared(varPtr[varIndex])) {
+	    Tcl_SetLongObj(varPtr[varIndex], maxLong);
+	} else {
+	    SetVarToObj(varPtr, varIndex, Tcl_NewLongObj(maxLong));
+	}
+    } else if (strcmp(subCmd, "ismaxlong") == 0) {
+	if (objc != 3) {
+	    goto wrongNumArgs;
+	}
+	if (CheckIfVarUnset(interp, varPtr,varIndex)) {
+	    return TCL_ERROR;
+	}
+	if (Tcl_GetLongFromObj(interp, varPtr[varIndex], &longValue) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	Tcl_AppendToObj(Tcl_GetObjResult(interp),
+		((longValue == LONG_MAX)? "1" : "0"), -1);
+    } else if (strcmp(subCmd, "get") == 0) {
+	if (objc != 3) {
+	    goto wrongNumArgs;
+	}
+	if (CheckIfVarUnset(interp, varPtr,varIndex)) {
+	    return TCL_ERROR;
+	}
+	Tcl_SetObjResult(interp, varPtr[varIndex]);
+    } else if (strcmp(subCmd, "get2") == 0) {
+	if (objc != 3) {
+	    goto wrongNumArgs;
+	}
+	if (CheckIfVarUnset(interp, varPtr,varIndex)) {
+	    return TCL_ERROR;
+	}
+	string = Tcl_GetString(varPtr[varIndex]);
+	Tcl_AppendToObj(Tcl_GetObjResult(interp), string, -1);
+    } else if (strcmp(subCmd, "inttoobigtest") == 0) {
+	/*
+	 * If long ints have more bits than ints on this platform, verify that
+	 * Tcl_GetIntFromObj returns an error if the long int held in an
+	 * integer object's internal representation is too large to fit in an
+	 * int.
+	 */
+
+	if (objc != 3) {
+	    goto wrongNumArgs;
+	}
+#if (INT_MAX == LONG_MAX)   /* int is same size as long int */
+	Tcl_AppendToObj(Tcl_GetObjResult(interp), "1", -1);
+#else
+	if ((varPtr[varIndex] != NULL) && !Tcl_IsShared(varPtr[varIndex])) {
+	    Tcl_SetLongObj(varPtr[varIndex], LONG_MAX);
+	} else {
+	    SetVarToObj(varPtr, varIndex, Tcl_NewLongObj(LONG_MAX));
+	}
+	if (Tcl_GetIntFromObj(interp, varPtr[varIndex], &i) != TCL_OK) {
+	    Tcl_ResetResult(interp);
+	    Tcl_AppendToObj(Tcl_GetObjResult(interp), "1", -1);
+	    return TCL_OK;
+	}
+	Tcl_AppendToObj(Tcl_GetObjResult(interp), "0", -1);
+#endif
+    } else if (strcmp(subCmd, "mult10") == 0) {
+	if (objc != 3) {
+	    goto wrongNumArgs;
+	}
+	if (CheckIfVarUnset(interp, varPtr,varIndex)) {
+	    return TCL_ERROR;
+	}
+	if (Tcl_GetIntFromObj(interp, varPtr[varIndex],
+		&intValue) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	if (!Tcl_IsShared(varPtr[varIndex])) {
+	    Tcl_SetIntObj(varPtr[varIndex], intValue * 10);
+	} else {
+	    SetVarToObj(varPtr, varIndex, Tcl_NewIntObj(intValue * 10));
+	}
+	Tcl_SetObjResult(interp, varPtr[varIndex]);
+    } else if (strcmp(subCmd, "div10") == 0) {
+	if (objc != 3) {
+	    goto wrongNumArgs;
+	}
+	if (CheckIfVarUnset(interp, varPtr,varIndex)) {
+	    return TCL_ERROR;
+	}
+	if (Tcl_GetIntFromObj(interp, varPtr[varIndex],
+		&intValue) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	if (!Tcl_IsShared(varPtr[varIndex])) {
+	    Tcl_SetIntObj(varPtr[varIndex], intValue / 10);
+	} else {
+	    SetVarToObj(varPtr, varIndex, Tcl_NewIntObj(intValue / 10));
+	}
+	Tcl_SetObjResult(interp, varPtr[varIndex]);
+    } else {
+	Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
+		"bad option \"", Tcl_GetString(objv[1]),
+		"\": must be set, get, get2, mult10, or div10", NULL);
+	return TCL_ERROR;
+    }
+    return TCL_OK;
+}
+
+/*
+ *-----------------------------------------------------------------------------
+ *
+ * TestlistobjCmd --
+ *
+ *	This function implements the 'testlistobj' command. It is used to
+ *	test a few possible corner cases in list object manipulation from
+ *	C code that cannot occur at the Tcl level.
+ *
+ * Results:
+ *	A standard Tcl object result.
+ *
+ * Side effects:
+ *	Creates, manipulates and frees list objects.
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+static int
+TestlistobjCmd(
+    ClientData clientData,	/* Not used */
+    Tcl_Interp *interp,		/* Tcl interpreter */
+    int objc,			/* Number of arguments */
+    Tcl_Obj *const objv[])	/* Argument objects */
+{
+    /* Subcommands supported by this command */
+    const char* subcommands[] = {
+	"set",
+	"get",
+	"replace"
+    };
+    enum listobjCmdIndex {
+	LISTOBJ_SET,
+	LISTOBJ_GET,
+	LISTOBJ_REPLACE
+    };
+
+    const char* index;		/* Argument giving the variable number */
+    int varIndex;		/* Variable number converted to binary */
+    int cmdIndex;		/* Ordinal number of the subcommand */
+    int first;			/* First index in the list */
+    int count;			/* Count of elements in a list */
+    Tcl_Obj **varPtr;
+
+    if (objc < 3) {
+	Tcl_WrongNumArgs(interp, 1, objv, "option arg ?arg...?");
+	return TCL_ERROR;
+    }
+    varPtr = GetVarPtr(interp);
+    index = Tcl_GetString(objv[2]);
+    if (GetVariableIndex(interp, index, &varIndex) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    if (Tcl_GetIndexFromObj(interp, objv[1], subcommands, "command",
+			    0, &cmdIndex) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    switch(cmdIndex) {
+    case LISTOBJ_SET:
+	if ((varPtr[varIndex] != NULL) && !Tcl_IsShared(varPtr[varIndex])) {
+	    Tcl_SetListObj(varPtr[varIndex], objc-3, objv+3);
+	} else {
+	    SetVarToObj(varPtr, varIndex, Tcl_NewListObj(objc-3, objv+3));
+	}
+	Tcl_SetObjResult(interp, varPtr[varIndex]);
+	break;
+
+    case LISTOBJ_GET:
+	if (objc != 3) {
+	    Tcl_WrongNumArgs(interp, 2, objv, "varIndex");
+	    return TCL_ERROR;
+	}
+	if (CheckIfVarUnset(interp, varPtr,varIndex)) {
+	    return TCL_ERROR;
+	}
+	Tcl_SetObjResult(interp, varPtr[varIndex]);
+	break;
+
+    case LISTOBJ_REPLACE:
+	if (objc < 5) {
+	    Tcl_WrongNumArgs(interp, 2, objv,
+			     "varIndex start count ?element...?");
+	    return TCL_ERROR;
+	}
+	if (Tcl_GetIntFromObj(interp, objv[3], &first) != TCL_OK
+	    || Tcl_GetIntFromObj(interp, objv[4], &count) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	if (Tcl_IsShared(varPtr[varIndex])) {
+	    SetVarToObj(varPtr, varIndex, Tcl_DuplicateObj(varPtr[varIndex]));
+	}
+	Tcl_ResetResult(interp);
+	return Tcl_ListObjReplace(interp, varPtr[varIndex], first, count,
+				  objc-5, objv+5);
+    }
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TestobjCmd --
+ *
+ *	This function implements the "testobj" command. It is used to test
+ *	the type-independent portions of the Tcl object type implementation.
+ *
+ * Results:
+ *	A standard Tcl object result.
+ *
+ * Side effects:
+ *	Creates and frees objects.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+TestobjCmd(
+    ClientData clientData,	/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    int varIndex, destIndex, i;
+    const char *index, *subCmd, *string;
+    const Tcl_ObjType *targetType;
+    Tcl_Obj **varPtr;
+
+    if (objc < 2) {
+	wrongNumArgs:
+	Tcl_WrongNumArgs(interp, 1, objv, "option arg ?arg ...?");
+	return TCL_ERROR;
+    }
+
+    varPtr = GetVarPtr(interp);
+    subCmd = Tcl_GetString(objv[1]);
+    if (strcmp(subCmd, "assign") == 0) {
+	if (objc != 4) {
+	    goto wrongNumArgs;
+	}
+	index = Tcl_GetString(objv[2]);
+	if (GetVariableIndex(interp, index, &varIndex) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	if (CheckIfVarUnset(interp, varPtr,varIndex)) {
+	    return TCL_ERROR;
+	}
+	string = Tcl_GetString(objv[3]);
+	if (GetVariableIndex(interp, string, &destIndex) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	SetVarToObj(varPtr, destIndex, varPtr[varIndex]);
+	Tcl_SetObjResult(interp, varPtr[destIndex]);
+    } else if (strcmp(subCmd, "bug3598580") == 0) {
+	Tcl_Obj *listObjPtr, *elemObjPtr;
+	if (objc != 2) {
+	    goto wrongNumArgs;
+	}
+	elemObjPtr = Tcl_NewIntObj(123);
+	listObjPtr = Tcl_NewListObj(1, &elemObjPtr);
+	/* Replace the single list element through itself, nonsense but legal. */
+	Tcl_ListObjReplace(interp, listObjPtr, 0, 1, 1, &elemObjPtr);
+	Tcl_SetObjResult(interp, listObjPtr);
+	return TCL_OK;
+    } else if (strcmp(subCmd, "convert") == 0) {
+	const char *typeName;
+
+	if (objc != 4) {
+	    goto wrongNumArgs;
+	}
+	index = Tcl_GetString(objv[2]);
+	if (GetVariableIndex(interp, index, &varIndex) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	if (CheckIfVarUnset(interp, varPtr,varIndex)) {
+	    return TCL_ERROR;
+	}
+	typeName = Tcl_GetString(objv[3]);
+	if ((targetType = Tcl_GetObjType(typeName)) == NULL) {
+	    Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
+		    "no type ", typeName, " found", NULL);
+	    return TCL_ERROR;
+	}
+	if (Tcl_ConvertToType(interp, varPtr[varIndex], targetType)
+		!= TCL_OK) {
+	    return TCL_ERROR;
+	}
+	Tcl_SetObjResult(interp, varPtr[varIndex]);
+    } else if (strcmp(subCmd, "duplicate") == 0) {
+	if (objc != 4) {
+	    goto wrongNumArgs;
+	}
+	index = Tcl_GetString(objv[2]);
+	if (GetVariableIndex(interp, index, &varIndex) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	if (CheckIfVarUnset(interp, varPtr,varIndex)) {
+	    return TCL_ERROR;
+	}
+	string = Tcl_GetString(objv[3]);
+	if (GetVariableIndex(interp, string, &destIndex) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	SetVarToObj(varPtr, destIndex, Tcl_DuplicateObj(varPtr[varIndex]));
+	Tcl_SetObjResult(interp, varPtr[destIndex]);
+    } else if (strcmp(subCmd, "freeallvars") == 0) {
+	if (objc != 2) {
+	    goto wrongNumArgs;
+	}
+	for (i = 0;  i < NUMBER_OF_OBJECT_VARS;  i++) {
+	    if (varPtr[i] != NULL) {
+		Tcl_DecrRefCount(varPtr[i]);
+		varPtr[i] = NULL;
+	    }
+	}
+    } else if (strcmp(subCmd, "invalidateStringRep") == 0) {
+	if (objc != 3) {
+	    goto wrongNumArgs;
+	}
+	index = Tcl_GetString(objv[2]);
+	if (GetVariableIndex(interp, index, &varIndex) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	if (CheckIfVarUnset(interp, varPtr,varIndex)) {
+	    return TCL_ERROR;
+	}
+	Tcl_InvalidateStringRep(varPtr[varIndex]);
+	Tcl_SetObjResult(interp, varPtr[varIndex]);
+    } else if (strcmp(subCmd, "newobj") == 0) {
+	if (objc != 3) {
+	    goto wrongNumArgs;
+	}
+	index = Tcl_GetString(objv[2]);
+	if (GetVariableIndex(interp, index, &varIndex) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	SetVarToObj(varPtr, varIndex, Tcl_NewObj());
+	Tcl_SetObjResult(interp, varPtr[varIndex]);
+    } else if (strcmp(subCmd, "objtype") == 0) {
+	const char *typeName;
+
+	/*
+	 * Return an object containing the name of the argument's type of
+	 * internal rep. If none exists, return "none".
+	 */
+
+	if (objc != 3) {
+	    goto wrongNumArgs;
+	}
+	if (objv[2]->typePtr == NULL) {
+	    Tcl_SetObjResult(interp, Tcl_NewStringObj("none", -1));
+	} else {
+	    typeName = objv[2]->typePtr->name;
+	    Tcl_SetObjResult(interp, Tcl_NewStringObj(typeName, -1));
+	}
+    } else if (strcmp(subCmd, "refcount") == 0) {
+	if (objc != 3) {
+	    goto wrongNumArgs;
+	}
+	index = Tcl_GetString(objv[2]);
+	if (GetVariableIndex(interp, index, &varIndex) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	if (CheckIfVarUnset(interp, varPtr,varIndex)) {
+	    return TCL_ERROR;
+	}
+	Tcl_SetObjResult(interp, Tcl_NewIntObj(varPtr[varIndex]->refCount));
+    } else if (strcmp(subCmd, "type") == 0) {
+	if (objc != 3) {
+	    goto wrongNumArgs;
+	}
+	index = Tcl_GetString(objv[2]);
+	if (GetVariableIndex(interp, index, &varIndex) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	if (CheckIfVarUnset(interp, varPtr,varIndex)) {
+	    return TCL_ERROR;
+	}
+	if (varPtr[varIndex]->typePtr == NULL) { /* a string! */
+	    Tcl_AppendToObj(Tcl_GetObjResult(interp), "string", -1);
+	} else {
+	    Tcl_AppendToObj(Tcl_GetObjResult(interp),
+		    varPtr[varIndex]->typePtr->name, -1);
+	}
+    } else if (strcmp(subCmd, "types") == 0) {
+	if (objc != 2) {
+	    goto wrongNumArgs;
+	}
+	if (Tcl_AppendAllObjTypes(interp,
+		Tcl_GetObjResult(interp)) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+    } else {
+	Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
+		"bad option \"", Tcl_GetString(objv[1]),
+		"\": must be assign, convert, duplicate, freeallvars, "
+		"newobj, objcount, objtype, refcount, type, or types", NULL);
+	return TCL_ERROR;
+    }
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TeststringobjCmd --
+ *
+ *	This function implements the "teststringobj" command. It is used to
+ *	test the string Tcl object type implementation.
+ *
+ * Results:
+ *	A standard Tcl object result.
+ *
+ * Side effects:
+ *	Creates and frees string objects, and also converts objects to
+ *	have string type.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+TeststringobjCmd(
+    ClientData clientData,	/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    Tcl_UniChar *unicode;
+    int varIndex, option, i, length;
+#define MAX_STRINGS 11
+    const char *index, *string, *strings[MAX_STRINGS+1];
+    String *strPtr;
+    Tcl_Obj **varPtr;
+    static const char *const options[] = {
+	"append", "appendstrings", "get", "get2", "length", "length2",
+	"set", "set2", "setlength", "maxchars", "getunicode",
+	"appendself", "appendself2", NULL
+    };
+
+    if (objc < 3) {
+	wrongNumArgs:
+	Tcl_WrongNumArgs(interp, 1, objv, "option arg ?arg ...?");
+	return TCL_ERROR;
+    }
+
+    varPtr = GetVarPtr(interp);
+    index = Tcl_GetString(objv[2]);
+    if (GetVariableIndex(interp, index, &varIndex) != TCL_OK) {
+	return TCL_ERROR;
+    }
+
+    if (Tcl_GetIndexFromObj(interp, objv[1], options, "option", 0, &option)
+	    != TCL_OK) {
+	return TCL_ERROR;
+    }
+    switch (option) {
+	case 0:				/* append */
+	    if (objc != 5) {
+		goto wrongNumArgs;
+	    }
+	    if (Tcl_GetIntFromObj(interp, objv[4], &length) != TCL_OK) {
+		return TCL_ERROR;
+	    }
+	    if (varPtr[varIndex] == NULL) {
+		SetVarToObj(varPtr, varIndex, Tcl_NewObj());
+	    }
+
+	    /*
+	     * If the object bound to variable "varIndex" is shared, we must
+	     * "copy on write" and append to a copy of the object.
+	     */
+
+	    if (Tcl_IsShared(varPtr[varIndex])) {
+		SetVarToObj(varPtr, varIndex, Tcl_DuplicateObj(varPtr[varIndex]));
+	    }
+	    string = Tcl_GetString(objv[3]);
+	    Tcl_AppendToObj(varPtr[varIndex], string, length);
+	    Tcl_SetObjResult(interp, varPtr[varIndex]);
+	    break;
+	case 1:				/* appendstrings */
+	    if (objc > (MAX_STRINGS+3)) {
+		goto wrongNumArgs;
+	    }
+	    if (varPtr[varIndex] == NULL) {
+		SetVarToObj(varPtr, varIndex, Tcl_NewObj());
+	    }
+
+	    /*
+	     * If the object bound to variable "varIndex" is shared, we must
+	     * "copy on write" and append to a copy of the object.
+	     */
+
+	    if (Tcl_IsShared(varPtr[varIndex])) {
+		SetVarToObj(varPtr, varIndex, Tcl_DuplicateObj(varPtr[varIndex]));
+	    }
+	    for (i = 3;  i < objc;  i++) {
+		strings[i-3] = Tcl_GetString(objv[i]);
+	    }
+	    for ( ; i < 12 + 3; i++) {
+		strings[i - 3] = NULL;
+	    }
+	    Tcl_AppendStringsToObj(varPtr[varIndex], strings[0], strings[1],
+		    strings[2], strings[3], strings[4], strings[5],
+		    strings[6], strings[7], strings[8], strings[9],
+		    strings[10], strings[11]);
+	    Tcl_SetObjResult(interp, varPtr[varIndex]);
+	    break;
+	case 2:				/* get */
+	    if (objc != 3) {
+		goto wrongNumArgs;
+	    }
+	    if (CheckIfVarUnset(interp, varPtr,varIndex)) {
+		return TCL_ERROR;
+	    }
+	    Tcl_SetObjResult(interp, varPtr[varIndex]);
+	    break;
+	case 3:				/* get2 */
+	    if (objc != 3) {
+		goto wrongNumArgs;
+	    }
+	    if (CheckIfVarUnset(interp, varPtr, varIndex)) {
+		return TCL_ERROR;
+	    }
+	    string = Tcl_GetString(varPtr[varIndex]);
+	    Tcl_AppendToObj(Tcl_GetObjResult(interp), string, -1);
+	    break;
+	case 4:				/* length */
+	    if (objc != 3) {
+		goto wrongNumArgs;
+	    }
+	    Tcl_SetIntObj(Tcl_GetObjResult(interp), (varPtr[varIndex] != NULL)
+		    ? varPtr[varIndex]->length : -1);
+	    break;
+	case 5:				/* length2 */
+	    if (objc != 3) {
+		goto wrongNumArgs;
+	    }
+	    if (varPtr[varIndex] != NULL) {
+		Tcl_ConvertToType(NULL, varPtr[varIndex],
+			Tcl_GetObjType("string"));
+		strPtr = varPtr[varIndex]->internalRep.twoPtrValue.ptr1;
+		length = (int) strPtr->allocated;
+	    } else {
+		length = -1;
+	    }
+	    Tcl_SetIntObj(Tcl_GetObjResult(interp), length);
+	    break;
+	case 6:				/* set */
+	    if (objc != 4) {
+		goto wrongNumArgs;
+	    }
+
+	    /*
+	     * If the object currently bound to the variable with index
+	     * varIndex has ref count 1 (i.e. the object is unshared) we can
+	     * modify that object directly. Otherwise, if RC>1 (i.e. the
+	     * object is shared), we must create a new object to modify/set
+	     * and decrement the old formerly-shared object's ref count. This
+	     * is "copy on write".
+	     */
+
+	    string = Tcl_GetStringFromObj(objv[3], &length);
+	    if ((varPtr[varIndex] != NULL)
+		    && !Tcl_IsShared(varPtr[varIndex])) {
+		Tcl_SetStringObj(varPtr[varIndex], string, length);
+	    } else {
+		SetVarToObj(varPtr, varIndex, Tcl_NewStringObj(string, length));
+	    }
+	    Tcl_SetObjResult(interp, varPtr[varIndex]);
+	    break;
+	case 7:				/* set2 */
+	    if (objc != 4) {
+		goto wrongNumArgs;
+	    }
+	    SetVarToObj(varPtr, varIndex, objv[3]);
+	    break;
+	case 8:				/* setlength */
+	    if (objc != 4) {
+		goto wrongNumArgs;
+	    }
+	    if (Tcl_GetIntFromObj(interp, objv[3], &length) != TCL_OK) {
+		return TCL_ERROR;
+	    }
+	    if (varPtr[varIndex] != NULL) {
+		Tcl_SetObjLength(varPtr[varIndex], length);
+	    }
+	    break;
+	case 9:				/* maxchars */
+	    if (objc != 3) {
+		goto wrongNumArgs;
+	    }
+	    if (varPtr[varIndex] != NULL) {
+		Tcl_ConvertToType(NULL, varPtr[varIndex],
+			Tcl_GetObjType("string"));
+		strPtr = varPtr[varIndex]->internalRep.twoPtrValue.ptr1;
+		length = strPtr->maxChars;
+	    } else {
+		length = -1;
+	    }
+	    Tcl_SetIntObj(Tcl_GetObjResult(interp), length);
+	    break;
+	case 10:			/* getunicode */
+	    if (objc != 3) {
+		goto wrongNumArgs;
+	    }
+	    Tcl_GetUnicodeFromObj(varPtr[varIndex], NULL);
+	    break;
+	case 11:			/* appendself */
+	    if (objc != 4) {
+		goto wrongNumArgs;
+	    }
+	    if (varPtr[varIndex] == NULL) {
+		SetVarToObj(varPtr, varIndex, Tcl_NewObj());
+	    }
+
+	    /*
+	     * If the object bound to variable "varIndex" is shared, we must
+	     * "copy on write" and append to a copy of the object.
+	     */
+
+	    if (Tcl_IsShared(varPtr[varIndex])) {
+		SetVarToObj(varPtr, varIndex, Tcl_DuplicateObj(varPtr[varIndex]));
+	    }
+
+	    string = Tcl_GetStringFromObj(varPtr[varIndex], &length);
+
+	    if (Tcl_GetIntFromObj(interp, objv[3], &i) != TCL_OK) {
+		return TCL_ERROR;
+	    }
+	    if ((i < 0) || (i > length)) {
+		Tcl_SetObjResult(interp, Tcl_NewStringObj(
+			"index value out of range", -1));
+		return TCL_ERROR;
+	    }
+
+	    Tcl_AppendToObj(varPtr[varIndex], string + i, length - i);
+	    Tcl_SetObjResult(interp, varPtr[varIndex]);
+	    break;
+	case 12:			/* appendself2 */
+	    if (objc != 4) {
+		goto wrongNumArgs;
+	    }
+	    if (varPtr[varIndex] == NULL) {
+		SetVarToObj(varPtr, varIndex, Tcl_NewObj());
+	    }
+
+	    /*
+	     * If the object bound to variable "varIndex" is shared, we must
+	     * "copy on write" and append to a copy of the object.
+	     */
+
+	    if (Tcl_IsShared(varPtr[varIndex])) {
+		SetVarToObj(varPtr, varIndex, Tcl_DuplicateObj(varPtr[varIndex]));
+	    }
+
+	    unicode = Tcl_GetUnicodeFromObj(varPtr[varIndex], &length);
+
+	    if (Tcl_GetIntFromObj(interp, objv[3], &i) != TCL_OK) {
+		return TCL_ERROR;
+	    }
+	    if ((i < 0) || (i > length)) {
+		Tcl_SetObjResult(interp, Tcl_NewStringObj(
+			"index value out of range", -1));
+		return TCL_ERROR;
+	    }
+
+	    Tcl_AppendUnicodeToObj(varPtr[varIndex], unicode + i, length - i);
+	    Tcl_SetObjResult(interp, varPtr[varIndex]);
+	    break;
+    }
+
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * SetVarToObj --
+ *
+ *	Utility routine to assign a Tcl_Obj* to a test variable. The
+ *	Tcl_Obj* can be NULL.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	This routine handles ref counting details for assignment: i.e. the old
+ *	value's ref count must be decremented (if not NULL) and the new one
+ *	incremented (also if not NULL).
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+SetVarToObj(
+    Tcl_Obj **varPtr,
+    int varIndex,		/* Designates the assignment variable. */
+    Tcl_Obj *objPtr)		/* Points to object to assign to var. */
+{
+    if (varPtr[varIndex] != NULL) {
+	Tcl_DecrRefCount(varPtr[varIndex]);
+    }
+    varPtr[varIndex] = objPtr;
+    if (objPtr != NULL) {
+	Tcl_IncrRefCount(objPtr);
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * GetVariableIndex --
+ *
+ *	Utility routine to get a test variable index from the command line.
+ *
+ * Results:
+ *	A standard Tcl object result.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+GetVariableIndex(
+    Tcl_Interp *interp,		/* Interpreter for error reporting. */
+    const char *string,		/* String containing a variable index
+				 * specified as a nonnegative number less than
+				 * NUMBER_OF_OBJECT_VARS. */
+    int *indexPtr)		/* Place to store converted result. */
+{
+    int index;
+
+    if (Tcl_GetInt(interp, string, &index) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    if (index < 0 || index >= NUMBER_OF_OBJECT_VARS) {
+	Tcl_ResetResult(interp);
+	Tcl_AppendToObj(Tcl_GetObjResult(interp), "bad variable index", -1);
+	return TCL_ERROR;
+    }
+
+    *indexPtr = index;
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * CheckIfVarUnset --
+ *
+ *	Utility function that checks whether a test variable is readable:
+ *	i.e., that varPtr[varIndex] is non-NULL.
+ *
+ * Results:
+ *	1 if the test variable is unset (NULL); 0 otherwise.
+ *
+ * Side effects:
+ *	Sets the interpreter result to an error message if the variable is
+ *	unset (NULL).
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+CheckIfVarUnset(
+    Tcl_Interp *interp,		/* Interpreter for error reporting. */
+    Tcl_Obj ** varPtr,
+    int varIndex)		/* Index of the test variable to check. */
+{
+    if (varPtr[varIndex] == NULL) {
+	char buf[32 + TCL_INTEGER_SPACE];
+
+	sprintf(buf, "variable %d is unset (NULL)", varIndex);
+	Tcl_ResetResult(interp);
+	Tcl_AppendToObj(Tcl_GetObjResult(interp), buf, -1);
+	return 1;
+    }
+    return 0;
+}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tclTestProcBodyObj.c b/generic/tclTestProcBodyObj.c
new file mode 100644
index 0000000..4d32c5a
--- /dev/null
+++ b/generic/tclTestProcBodyObj.c
@@ -0,0 +1,309 @@
+/*
+ * tclTestProcBodyObj.c --
+ *
+ *	Implements the "procbodytest" package, which contains commands to test
+ *	creation of Tcl procedures whose body argument is a Tcl_Obj of type
+ *	"procbody" rather than a string.
+ *
+ * Copyright (c) 1998 by Scriptics Corporation.
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#ifndef USE_TCL_STUBS
+#   define USE_TCL_STUBS
+#endif
+#include "tclInt.h"
+
+/*
+ * name and version of this package
+ */
+
+static const char packageName[] = "procbodytest";
+static const char packageVersion[] = "1.0";
+
+/*
+ * Name of the commands exported by this package
+ */
+
+static const char procCommand[] = "proc";
+
+/*
+ * this struct describes an entry in the table of command names and command
+ * procs
+ */
+
+typedef struct CmdTable {
+    const char *cmdName;		/* command name */
+    Tcl_ObjCmdProc *proc;	/* command proc */
+    int exportIt;		/* if 1, export the command */
+} CmdTable;
+
+/*
+ * Declarations for functions defined in this file.
+ */
+
+static int	ProcBodyTestProcObjCmd(ClientData dummy,
+			Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]);
+static int	ProcBodyTestInitInternal(Tcl_Interp *interp, int isSafe);
+static int	RegisterCommand(Tcl_Interp* interp,
+			const char *namespace, const CmdTable *cmdTablePtr);
+
+/*
+ * List of commands to create when the package is loaded; must go after the
+ * declarations of the enable command procedure.
+ */
+
+static const CmdTable commands[] = {
+    { procCommand,	ProcBodyTestProcObjCmd,	1 },
+    { 0, 0, 0 }
+};
+
+static const CmdTable safeCommands[] = {
+    { procCommand,	ProcBodyTestProcObjCmd,	1 },
+    { 0, 0, 0 }
+};
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Procbodytest_Init --
+ *
+ *	This function initializes the "procbodytest" package.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Procbodytest_Init(
+    Tcl_Interp *interp)		/* the Tcl interpreter for which the package
+				 * is initialized */
+{
+    return ProcBodyTestInitInternal(interp, 0);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Procbodytest_SafeInit --
+ *
+ *	This function initializes the "procbodytest" package.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Procbodytest_SafeInit(
+    Tcl_Interp *interp)		/* the Tcl interpreter for which the package
+				 * is initialized */
+{
+    return ProcBodyTestInitInternal(interp, 1);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * RegisterCommand --
+ *
+ *	This function registers a command in the context of the given
+ *	namespace.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+RegisterCommand(
+    Tcl_Interp* interp,		/* the Tcl interpreter for which the operation
+				 * is performed */
+    const char *namespace,		/* the namespace in which the command is
+				 * registered */
+    const CmdTable *cmdTablePtr)/* the command to register */
+{
+    char buf[128];
+
+    if (cmdTablePtr->exportIt) {
+	sprintf(buf, "namespace eval %s { namespace export %s }",
+		namespace, cmdTablePtr->cmdName);
+	if (Tcl_EvalEx(interp, buf, -1, 0) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+    }
+
+    sprintf(buf, "%s::%s", namespace, cmdTablePtr->cmdName);
+    Tcl_CreateObjCommand(interp, buf, cmdTablePtr->proc, 0, 0);
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ProcBodyTestInitInternal --
+ *
+ *  This function initializes the Loader package.
+ *  The isSafe flag is 1 if the interpreter is safe, 0 otherwise.
+ *
+ * Results:
+ *  A standard Tcl result.
+ *
+ * Side effects:
+ *  None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+ProcBodyTestInitInternal(
+    Tcl_Interp *interp,		/* the Tcl interpreter for which the package
+				 * is initialized */
+    int isSafe)			/* 1 if this is a safe interpreter */
+{
+    const CmdTable *cmdTablePtr;
+
+    cmdTablePtr = (isSafe) ? &safeCommands[0] : &commands[0];
+    for ( ; cmdTablePtr->cmdName ; cmdTablePtr++) {
+	if (RegisterCommand(interp, packageName, cmdTablePtr) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+    }
+
+    return Tcl_PkgProvide(interp, packageName, packageVersion);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ProcBodyTestProcObjCmd --
+ *
+ *  Implements the "procbodytest::proc" command. Here is the command
+ *  description:
+ *	procbodytest::proc newName argList bodyName
+ *  Looks up a procedure called $bodyName and, if the procedure exists,
+ *  constructs a Tcl_Obj of type "procbody" and calls Tcl_ProcObjCmd.
+ *  Arguments:
+ *    newName		the name of the procedure to be created
+ *    argList		the argument list for the procedure
+ *    bodyName		the name of an existing procedure from which the
+ *			body is to be copied.
+ *  This command can be used to trigger the branches in Tcl_ProcObjCmd that
+ *  construct a proc from a "procbody", for example:
+ *	proc a {x} {return $x}
+ *	a 123
+ *	procbodytest::proc b {x} a
+ *  Note the call to "a 123", which is necessary so that the Proc pointer
+ *  for "a" is filled in by the internal compiler; this is a hack.
+ *
+ * Results:
+ *  Returns a standard Tcl code.
+ *
+ * Side effects:
+ *  A new procedure is created.
+ *  Leaves an error message in the interp's result on error.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+ProcBodyTestProcObjCmd(
+    ClientData dummy,		/* context; not used */
+    Tcl_Interp *interp,		/* the current interpreter */
+    int objc,			/* argument count */
+    Tcl_Obj *const objv[])	/* arguments */
+{
+    const char *fullName;
+    Tcl_Command procCmd;
+    Command *cmdPtr;
+    Proc *procPtr = NULL;
+    Tcl_Obj *bodyObjPtr;
+    Tcl_Obj *myobjv[5];
+    int result;
+
+    if (objc != 4) {
+	Tcl_WrongNumArgs(interp, 1, objv, "newName argsList bodyName");
+	return TCL_ERROR;
+    }
+
+    /*
+     * Find the Command pointer to this procedure
+     */
+
+    fullName = Tcl_GetString(objv[3]);
+    procCmd = Tcl_FindCommand(interp, fullName, NULL, TCL_LEAVE_ERR_MSG);
+    if (procCmd == NULL) {
+	return TCL_ERROR;
+    }
+
+    cmdPtr = (Command *) procCmd;
+
+    /*
+     * check that this is a procedure and not a builtin command:
+     * If a procedure, cmdPtr->objClientData is TclIsProc(cmdPtr).
+     */
+
+    if (cmdPtr->objClientData != TclIsProc(cmdPtr)) {
+	Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
+		"command \"", fullName, "\" is not a Tcl procedure", NULL);
+	return TCL_ERROR;
+    }
+
+    /*
+     * it is a Tcl procedure: the client data is the Proc structure
+     */
+
+    procPtr = (Proc *) cmdPtr->objClientData;
+    if (procPtr == NULL) {
+	Tcl_AppendStringsToObj(Tcl_GetObjResult(interp), "procedure \"",
+		fullName, "\" does not have a Proc struct!", NULL);
+	return TCL_ERROR;
+    }
+
+    /*
+     * create a new object, initialize our argument vector, call into Tcl
+     */
+
+    bodyObjPtr = TclNewProcBodyObj(procPtr);
+    if (bodyObjPtr == NULL) {
+	Tcl_AppendStringsToObj(Tcl_GetObjResult(interp),
+		"failed to create a procbody object for procedure \"",
+		fullName, "\"", NULL);
+	return TCL_ERROR;
+    }
+    Tcl_IncrRefCount(bodyObjPtr);
+
+    myobjv[0] = objv[0];
+    myobjv[1] = objv[1];
+    myobjv[2] = objv[2];
+    myobjv[3] = bodyObjPtr;
+    myobjv[4] = NULL;
+
+    result = Tcl_ProcObjCmd(NULL, interp, objc, myobjv);
+    Tcl_DecrRefCount(bodyObjPtr);
+
+    return result;
+}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tclThread.c b/generic/tclThread.c
new file mode 100644
index 0000000..198fa6a
--- /dev/null
+++ b/generic/tclThread.c
@@ -0,0 +1,538 @@
+/*
+ * tclThread.c --
+ *
+ *	This file implements Platform independent thread operations. Most of
+ *	the real work is done in the platform dependent files.
+ *
+ * Copyright (c) 1998 by Sun Microsystems, Inc.
+ * Copyright (c) 2008 by George Peter Staplin
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#include "tclInt.h"
+
+/*
+ * There are three classes of synchronization objects: mutexes, thread data
+ * keys, and condition variables. The following are used to record the memory
+ * used for these objects so they can be finalized.
+ *
+ * These statics are guarded by the mutex in the caller of
+ * TclRememberThreadData, e.g., TclpThreadDataKeyInit
+ */
+
+typedef struct {
+    int num;		/* Number of objects remembered */
+    int max;		/* Max size of the array */
+    void **list;	/* List of pointers */
+} SyncObjRecord;
+
+static SyncObjRecord keyRecord = {0, 0, NULL};
+static SyncObjRecord mutexRecord = {0, 0, NULL};
+static SyncObjRecord condRecord = {0, 0, NULL};
+
+/*
+ * Prototypes of functions used only in this file.
+ */
+
+static void		ForgetSyncObject(void *objPtr, SyncObjRecord *recPtr);
+static void		RememberSyncObject(void *objPtr,
+			    SyncObjRecord *recPtr);
+
+/*
+ * Several functions are #defined to nothing in tcl.h if TCL_THREADS is not
+ * specified. Here we undo that so the functions are defined in the stubs
+ * table.
+ */
+
+#ifndef TCL_THREADS
+#undef Tcl_MutexLock
+#undef Tcl_MutexUnlock
+#undef Tcl_MutexFinalize
+#undef Tcl_ConditionNotify
+#undef Tcl_ConditionWait
+#undef Tcl_ConditionFinalize
+#endif
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_GetThreadData --
+ *
+ *	This function allocates and initializes a chunk of thread local
+ *	storage.
+ *
+ * Results:
+ *	A thread-specific pointer to the data structure.
+ *
+ * Side effects:
+ *	Will allocate memory the first time this thread calls for this chunk
+ *	of storage.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void *
+Tcl_GetThreadData(
+    Tcl_ThreadDataKey *keyPtr,	/* Identifier for the data chunk */
+    int size)			/* Size of storage block */
+{
+    void *result;
+#ifdef TCL_THREADS
+    /*
+     * Initialize the key for this thread.
+     */
+
+    result = TclThreadStorageKeyGet(keyPtr);
+
+    if (result == NULL) {
+	result = ckalloc(size);
+	memset(result, 0, (size_t) size);
+	TclThreadStorageKeySet(keyPtr, result);
+    }
+#else /* TCL_THREADS */
+    if (*keyPtr == NULL) {
+	result = ckalloc(size);
+	memset(result, 0, (size_t)size);
+	*keyPtr = result;
+	RememberSyncObject(keyPtr, &keyRecord);
+    } else {
+	result = *keyPtr;
+    }
+#endif /* TCL_THREADS */
+    return result;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclThreadDataKeyGet --
+ *
+ *	This function returns a pointer to a block of thread local storage.
+ *
+ * Results:
+ *	A thread-specific pointer to the data structure, or NULL if the memory
+ *	has not been assigned to this key for this thread.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void *
+TclThreadDataKeyGet(
+    Tcl_ThreadDataKey *keyPtr)	/* Identifier for the data chunk. */
+
+{
+#ifdef TCL_THREADS
+    return TclThreadStorageKeyGet(keyPtr);
+#else /* TCL_THREADS */
+    return *keyPtr;
+#endif /* TCL_THREADS */
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * RememberSyncObject
+ *
+ *	Keep a list of (mutexes/condition variable/data key) used during
+ *	finalization.
+ *
+ *	Assume master lock is held.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Add to the appropriate list.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+RememberSyncObject(
+    void *objPtr,		/* Pointer to sync object */
+    SyncObjRecord *recPtr)	/* Record of sync objects */
+{
+    void **newList;
+    int i, j;
+
+
+    /*
+     * Reuse any free slot in the list.
+     */
+
+    for (i=0 ; i < recPtr->num ; ++i) {
+	if (recPtr->list[i] == NULL) {
+	    recPtr->list[i] = objPtr;
+	    return;
+	}
+    }
+
+    /*
+     * Grow the list of pointers if necessary, copying only non-NULL
+     * pointers to the new list.
+     */
+
+    if (recPtr->num >= recPtr->max) {
+	recPtr->max += 8;
+	newList = ckalloc(recPtr->max * sizeof(void *));
+	for (i=0,j=0 ; i<recPtr->num ; i++) {
+	    if (recPtr->list[i] != NULL) {
+		newList[j++] = recPtr->list[i];
+	    }
+	}
+	if (recPtr->list != NULL) {
+	    ckfree(recPtr->list);
+	}
+	recPtr->list = newList;
+	recPtr->num = j;
+    }
+
+    recPtr->list[recPtr->num] = objPtr;
+    recPtr->num++;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ForgetSyncObject
+ *
+ *	Remove a single object from the list.
+ *	Assume master lock is held.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Remove from the appropriate list.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+ForgetSyncObject(
+    void *objPtr,		/* Pointer to sync object */
+    SyncObjRecord *recPtr)	/* Record of sync objects */
+{
+    int i;
+
+    for (i=0 ; i<recPtr->num ; i++) {
+	if (objPtr == recPtr->list[i]) {
+	    recPtr->list[i] = NULL;
+	    return;
+	}
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclRememberMutex
+ *
+ *	Keep a list of mutexes used during finalization.
+ *	Assume master lock is held.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Add to the mutex list.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclRememberMutex(
+    Tcl_Mutex *mutexPtr)
+{
+    RememberSyncObject(mutexPtr, &mutexRecord);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_MutexFinalize --
+ *
+ *	Finalize a single mutex and remove it from the list of remembered
+ *	objects.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Remove the mutex from the list.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_MutexFinalize(
+    Tcl_Mutex *mutexPtr)
+{
+#ifdef TCL_THREADS
+    TclpFinalizeMutex(mutexPtr);
+#endif
+    TclpMasterLock();
+    ForgetSyncObject(mutexPtr, &mutexRecord);
+    TclpMasterUnlock();
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclRememberCondition
+ *
+ *	Keep a list of condition variables used during finalization.
+ *	Assume master lock is held.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Add to the condition variable list.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclRememberCondition(
+    Tcl_Condition *condPtr)
+{
+    RememberSyncObject(condPtr, &condRecord);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_ConditionFinalize --
+ *
+ *	Finalize a single condition variable and remove it from the list of
+ *	remembered objects.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Remove the condition variable from the list.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_ConditionFinalize(
+    Tcl_Condition *condPtr)
+{
+#ifdef TCL_THREADS
+    TclpFinalizeCondition(condPtr);
+#endif
+    TclpMasterLock();
+    ForgetSyncObject(condPtr, &condRecord);
+    TclpMasterUnlock();
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclFinalizeThreadData --
+ *
+ *	This function cleans up the thread-local storage. Secondary, it cleans
+ *	thread alloc cache.
+ *	This is called once for each thread before thread exits.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Frees up all thread local storage.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclFinalizeThreadData(int quick)
+{
+    TclFinalizeThreadDataThread();
+#if defined(TCL_THREADS) && defined(USE_THREAD_ALLOC)
+    if (!quick) {
+	/*
+	 * Quick exit principle makes it useless to terminate allocators
+	 */
+	TclFinalizeThreadAllocThread();
+    }
+#endif
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclFinalizeSynchronization --
+ *
+ *	This function cleans up all synchronization objects: mutexes,
+ *	condition variables, and thread-local storage.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Frees up the memory.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclFinalizeSynchronization(void)
+{
+    int i;
+    void *blockPtr;
+    Tcl_ThreadDataKey *keyPtr;
+#ifdef TCL_THREADS
+    Tcl_Mutex *mutexPtr;
+    Tcl_Condition *condPtr;
+
+    TclpMasterLock();
+#endif
+
+    /*
+     * If we're running unthreaded, the TSD blocks are simply stored inside
+     * their thread data keys. Free them here.
+     */
+
+    if (keyRecord.list != NULL) {
+	for (i=0 ; i<keyRecord.num ; i++) {
+	    keyPtr = (Tcl_ThreadDataKey *) keyRecord.list[i];
+	    blockPtr = *keyPtr;
+	    ckfree(blockPtr);
+	}
+	ckfree(keyRecord.list);
+	keyRecord.list = NULL;
+    }
+    keyRecord.max = 0;
+    keyRecord.num = 0;
+
+#ifdef TCL_THREADS
+    /*
+     * Call thread storage master cleanup.
+     */
+
+    TclFinalizeThreadStorage();
+
+    for (i=0 ; i<mutexRecord.num ; i++) {
+	mutexPtr = (Tcl_Mutex *)mutexRecord.list[i];
+	if (mutexPtr != NULL) {
+	    TclpFinalizeMutex(mutexPtr);
+	}
+    }
+    if (mutexRecord.list != NULL) {
+	ckfree(mutexRecord.list);
+	mutexRecord.list = NULL;
+    }
+    mutexRecord.max = 0;
+    mutexRecord.num = 0;
+
+    for (i=0 ; i<condRecord.num ; i++) {
+	condPtr = (Tcl_Condition *) condRecord.list[i];
+	if (condPtr != NULL) {
+	    TclpFinalizeCondition(condPtr);
+	}
+    }
+    if (condRecord.list != NULL) {
+	ckfree(condRecord.list);
+	condRecord.list = NULL;
+    }
+    condRecord.max = 0;
+    condRecord.num = 0;
+
+    TclpMasterUnlock();
+#endif /* TCL_THREADS */
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_ExitThread --
+ *
+ *	This function is called to terminate the current thread. This should
+ *	be used by extensions that create threads with additional interpreters
+ *	in them.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	All thread exit handlers are invoked, then the thread dies.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_ExitThread(
+    int status)
+{
+    Tcl_FinalizeThread();
+#ifdef TCL_THREADS
+    TclpThreadExit(status);
+#endif
+}
+
+#ifndef TCL_THREADS
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_ConditionWait, et al. --
+ *
+ *	These noop functions are provided so the stub table does not have to
+ *	be conditionalized for threads. The real implementations of these
+ *	functions live in the platform specific files.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+#undef Tcl_ConditionWait
+void
+Tcl_ConditionWait(
+    Tcl_Condition *condPtr,	/* Really (pthread_cond_t **) */
+    Tcl_Mutex *mutexPtr,	/* Really (pthread_mutex_t **) */
+    const Tcl_Time *timePtr) /* Timeout on waiting period */
+{
+}
+
+#undef Tcl_ConditionNotify
+void
+Tcl_ConditionNotify(
+    Tcl_Condition *condPtr)
+{
+}
+
+#undef Tcl_MutexLock
+void
+Tcl_MutexLock(
+    Tcl_Mutex *mutexPtr)
+{
+}
+
+#undef Tcl_MutexUnlock
+void
+Tcl_MutexUnlock(
+    Tcl_Mutex *mutexPtr)
+{
+}
+#endif /* !TCL_THREADS */
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tclThreadAlloc.c b/generic/tclThreadAlloc.c
new file mode 100644
index 0000000..018f006
--- /dev/null
+++ b/generic/tclThreadAlloc.c
@@ -0,0 +1,1185 @@
+/*
+ * tclThreadAlloc.c --
+ *
+ *	This is a very fast storage allocator for used with threads (designed
+ *	avoid lock contention). The basic strategy is to allocate memory in
+ *	fixed size blocks from block caches.
+ *
+ * The Initial Developer of the Original Code is America Online, Inc.
+ * Portions created by AOL are Copyright (C) 1999 America Online, Inc.
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#include "tclInt.h"
+#if defined(TCL_THREADS) && defined(USE_THREAD_ALLOC)
+
+/*
+ * If range checking is enabled, an additional byte will be allocated to store
+ * the magic number at the end of the requested memory.
+ */
+
+#ifndef RCHECK
+#ifdef  NDEBUG
+#define RCHECK		0
+#else
+#define RCHECK		1
+#endif
+#endif
+
+/*
+ * The following define the number of Tcl_Obj's to allocate/move at a time and
+ * the high water mark to prune a per-thread cache. On a 32 bit system,
+ * sizeof(Tcl_Obj) = 24 so 800 * 24 = ~16k.
+ */
+
+#define NOBJALLOC	800
+
+/* Actual definition moved to tclInt.h */
+#define NOBJHIGH	ALLOC_NOBJHIGH
+
+/*
+ * The following union stores accounting information for each block including
+ * two small magic numbers and a bucket number when in use or a next pointer
+ * when free. The original requested size (not including the Block overhead)
+ * is also maintained.
+ */
+
+typedef union Block {
+    struct {
+	union {
+	    union Block *next;		/* Next in free list. */
+	    struct {
+		unsigned char magic1;	/* First magic number. */
+		unsigned char bucket;	/* Bucket block allocated from. */
+		unsigned char unused;	/* Padding. */
+		unsigned char magic2;	/* Second magic number. */
+	    } s;
+	} u;
+	size_t reqSize;			/* Requested allocation size. */
+    } b;
+    unsigned char padding[TCL_ALLOCALIGN];
+} Block;
+#define nextBlock	b.u.next
+#define sourceBucket	b.u.s.bucket
+#define magicNum1	b.u.s.magic1
+#define magicNum2	b.u.s.magic2
+#define MAGIC		0xEF
+#define blockReqSize	b.reqSize
+
+/*
+ * The following defines the minimum and and maximum block sizes and the number
+ * of buckets in the bucket cache.
+ */
+
+#define MINALLOC	((sizeof(Block) + 8 + (TCL_ALLOCALIGN-1)) & ~(TCL_ALLOCALIGN-1))
+#define NBUCKETS	(11 - (MINALLOC >> 5))
+#define MAXALLOC	(MINALLOC << (NBUCKETS - 1))
+
+/*
+ * The following structure defines a bucket of blocks with various accounting
+ * and statistics information.
+ */
+
+typedef struct Bucket {
+    Block *firstPtr;		/* First block available */
+    Block *lastPtr;		/* End of block list */
+    long numFree;		/* Number of blocks available */
+
+    /* All fields below for accounting only */
+
+    long numRemoves;		/* Number of removes from bucket */
+    long numInserts;		/* Number of inserts into bucket */
+    long numWaits;		/* Number of waits to acquire a lock */
+    long numLocks;		/* Number of locks acquired */
+    long totalAssigned;		/* Total space assigned to bucket */
+} Bucket;
+
+/*
+ * The following structure defines a cache of buckets and objs, of which there
+ * will be (at most) one per thread. Any changes need to be reflected in the
+ * struct AllocCache defined in tclInt.h, possibly also in the initialisation
+ * code in Tcl_CreateInterp().
+ */
+
+typedef struct Cache {
+    struct Cache *nextPtr;	/* Linked list of cache entries */
+    Tcl_ThreadId owner;		/* Which thread's cache is this? */
+    Tcl_Obj *firstObjPtr;	/* List of free objects for thread */
+    int numObjects;		/* Number of objects for thread */
+    Tcl_Obj *lastPtr;		/* Last object in this cache */
+    int totalAssigned;		/* Total space assigned to thread */
+    Bucket buckets[NBUCKETS];	/* The buckets for this thread */
+} Cache;
+
+/*
+ * The following array specifies various per-bucket limits and locks. The
+ * values are statically initialized to avoid calculating them repeatedly.
+ */
+
+static struct {
+    size_t blockSize;		/* Bucket blocksize. */
+    int maxBlocks;		/* Max blocks before move to share. */
+    int numMove;		/* Num blocks to move to share. */
+    Tcl_Mutex *lockPtr;		/* Share bucket lock. */
+} bucketInfo[NBUCKETS];
+
+/*
+ * Static functions defined in this file.
+ */
+
+static Cache *	GetCache(void);
+static void	LockBucket(Cache *cachePtr, int bucket);
+static void	UnlockBucket(Cache *cachePtr, int bucket);
+static void	PutBlocks(Cache *cachePtr, int bucket, int numMove);
+static int	GetBlocks(Cache *cachePtr, int bucket);
+static Block *	Ptr2Block(char *ptr);
+static char *	Block2Ptr(Block *blockPtr, int bucket, unsigned int reqSize);
+static void	MoveObjs(Cache *fromPtr, Cache *toPtr, int numMove);
+static void	PutObjs(Cache *fromPtr, int numMove);
+
+/*
+ * Local variables defined in this file and initialized at startup.
+ */
+
+static Tcl_Mutex *listLockPtr;
+static Tcl_Mutex *objLockPtr;
+static Cache sharedCache;
+static Cache *sharedPtr = &sharedCache;
+static Cache *firstCachePtr = &sharedCache;
+
+#if defined(HAVE_FAST_TSD)
+static __thread Cache *tcachePtr;
+
+# define GETCACHE(cachePtr)			\
+    do {					\
+	if (!tcachePtr) {			\
+	    tcachePtr = GetCache();		\
+	}					\
+	(cachePtr) = tcachePtr;			\
+    } while (0)
+#else
+# define GETCACHE(cachePtr)			\
+    do {					\
+	(cachePtr) = TclpGetAllocCache();	\
+	if ((cachePtr) == NULL) {		\
+	    (cachePtr) = GetCache();		\
+	}					\
+    } while (0)
+#endif
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * GetCache ---
+ *
+ *	Gets per-thread memory cache, allocating it if necessary.
+ *
+ * Results:
+ *	Pointer to cache.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static Cache *
+GetCache(void)
+{
+    Cache *cachePtr;
+
+    /*
+     * Check for first-time initialization.
+     */
+
+    if (listLockPtr == NULL) {
+	Tcl_Mutex *initLockPtr;
+	unsigned int i;
+
+	initLockPtr = Tcl_GetAllocMutex();
+	Tcl_MutexLock(initLockPtr);
+	if (listLockPtr == NULL) {
+	    listLockPtr = TclpNewAllocMutex();
+	    objLockPtr = TclpNewAllocMutex();
+	    for (i = 0; i < NBUCKETS; ++i) {
+		bucketInfo[i].blockSize = MINALLOC << i;
+		bucketInfo[i].maxBlocks = 1 << (NBUCKETS - 1 - i);
+		bucketInfo[i].numMove = i < NBUCKETS - 1 ?
+			1 << (NBUCKETS - 2 - i) : 1;
+		bucketInfo[i].lockPtr = TclpNewAllocMutex();
+	    }
+	}
+	Tcl_MutexUnlock(initLockPtr);
+    }
+
+    /*
+     * Get this thread's cache, allocating if necessary.
+     */
+
+    cachePtr = TclpGetAllocCache();
+    if (cachePtr == NULL) {
+	cachePtr = TclpSysAlloc(sizeof(Cache), 0);
+	if (cachePtr == NULL) {
+	    Tcl_Panic("alloc: could not allocate new cache");
+	}
+        memset(cachePtr, 0, sizeof(Cache));
+	Tcl_MutexLock(listLockPtr);
+	cachePtr->nextPtr = firstCachePtr;
+	firstCachePtr = cachePtr;
+	Tcl_MutexUnlock(listLockPtr);
+	cachePtr->owner = Tcl_GetCurrentThread();
+	TclpSetAllocCache(cachePtr);
+    }
+    return cachePtr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclFreeAllocCache --
+ *
+ *	Flush and delete a cache, removing from list of caches.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclFreeAllocCache(
+    void *arg)
+{
+    Cache *cachePtr = arg;
+    Cache **nextPtrPtr;
+    register unsigned int bucket;
+
+    /*
+     * Flush blocks.
+     */
+
+    for (bucket = 0; bucket < NBUCKETS; ++bucket) {
+	if (cachePtr->buckets[bucket].numFree > 0) {
+	    PutBlocks(cachePtr, bucket, cachePtr->buckets[bucket].numFree);
+	}
+    }
+
+    /*
+     * Flush objs.
+     */
+
+    if (cachePtr->numObjects > 0) {
+	PutObjs(cachePtr, cachePtr->numObjects);
+    }
+
+    /*
+     * Remove from pool list.
+     */
+
+    Tcl_MutexLock(listLockPtr);
+    nextPtrPtr = &firstCachePtr;
+    while (*nextPtrPtr != cachePtr) {
+	nextPtrPtr = &(*nextPtrPtr)->nextPtr;
+    }
+    *nextPtrPtr = cachePtr->nextPtr;
+    cachePtr->nextPtr = NULL;
+    Tcl_MutexUnlock(listLockPtr);
+    TclpSysFree(cachePtr);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclpAlloc --
+ *
+ *	Allocate memory.
+ *
+ * Results:
+ *	Pointer to memory just beyond Block pointer.
+ *
+ * Side effects:
+ *	May allocate more blocks for a bucket.
+ *
+ *----------------------------------------------------------------------
+ */
+
+char *
+TclpAlloc(
+    unsigned int reqSize)
+{
+    Cache *cachePtr;
+    Block *blockPtr;
+    register int bucket;
+    size_t size;
+
+#ifndef __LP64__
+    if (sizeof(int) >= sizeof(size_t)) {
+	/* An unsigned int overflow can also be a size_t overflow */
+	const size_t zero = 0;
+	const size_t max = ~zero;
+
+	if (((size_t) reqSize) > max - sizeof(Block) - RCHECK) {
+	    /* Requested allocation exceeds memory */
+	    return NULL;
+	}
+    }
+#endif
+
+    GETCACHE(cachePtr);
+
+    /*
+     * Increment the requested size to include room for the Block structure.
+     * Call TclpSysAlloc() directly if the required amount is greater than the
+     * largest block, otherwise pop the smallest block large enough,
+     * allocating more blocks if necessary.
+     */
+
+    blockPtr = NULL;
+    size = reqSize + sizeof(Block);
+#if RCHECK
+    size++;
+#endif
+    if (size > MAXALLOC) {
+	bucket = NBUCKETS;
+	blockPtr = TclpSysAlloc(size, 0);
+	if (blockPtr != NULL) {
+	    cachePtr->totalAssigned += reqSize;
+	}
+    } else {
+	bucket = 0;
+	while (bucketInfo[bucket].blockSize < size) {
+	    bucket++;
+	}
+	if (cachePtr->buckets[bucket].numFree || GetBlocks(cachePtr, bucket)) {
+	    blockPtr = cachePtr->buckets[bucket].firstPtr;
+	    cachePtr->buckets[bucket].firstPtr = blockPtr->nextBlock;
+	    cachePtr->buckets[bucket].numFree--;
+	    cachePtr->buckets[bucket].numRemoves++;
+	    cachePtr->buckets[bucket].totalAssigned += reqSize;
+	}
+    }
+    if (blockPtr == NULL) {
+	return NULL;
+    }
+    return Block2Ptr(blockPtr, bucket, reqSize);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclpFree --
+ *
+ *	Return blocks to the thread block cache.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	May move blocks to shared cache.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclpFree(
+    char *ptr)
+{
+    Cache *cachePtr;
+    Block *blockPtr;
+    int bucket;
+
+    if (ptr == NULL) {
+	return;
+    }
+
+    GETCACHE(cachePtr);
+
+    /*
+     * Get the block back from the user pointer and call system free directly
+     * for large blocks. Otherwise, push the block back on the bucket and move
+     * blocks to the shared cache if there are now too many free.
+     */
+
+    blockPtr = Ptr2Block(ptr);
+    bucket = blockPtr->sourceBucket;
+    if (bucket == NBUCKETS) {
+	cachePtr->totalAssigned -= blockPtr->blockReqSize;
+	TclpSysFree(blockPtr);
+	return;
+    }
+
+    cachePtr->buckets[bucket].totalAssigned -= blockPtr->blockReqSize;
+    blockPtr->nextBlock = cachePtr->buckets[bucket].firstPtr;
+    cachePtr->buckets[bucket].firstPtr = blockPtr;
+    if (cachePtr->buckets[bucket].numFree == 0) {
+	cachePtr->buckets[bucket].lastPtr = blockPtr;
+    }
+    cachePtr->buckets[bucket].numFree++;
+    cachePtr->buckets[bucket].numInserts++;
+
+    if (cachePtr != sharedPtr &&
+	    cachePtr->buckets[bucket].numFree > bucketInfo[bucket].maxBlocks) {
+	PutBlocks(cachePtr, bucket, bucketInfo[bucket].numMove);
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclpRealloc --
+ *
+ *	Re-allocate memory to a larger or smaller size.
+ *
+ * Results:
+ *	Pointer to memory just beyond Block pointer.
+ *
+ * Side effects:
+ *	Previous memory, if any, may be freed.
+ *
+ *----------------------------------------------------------------------
+ */
+
+char *
+TclpRealloc(
+    char *ptr,
+    unsigned int reqSize)
+{
+    Cache *cachePtr;
+    Block *blockPtr;
+    void *newPtr;
+    size_t size, min;
+    int bucket;
+
+    if (ptr == NULL) {
+	return TclpAlloc(reqSize);
+    }
+
+#ifndef __LP64__
+    if (sizeof(int) >= sizeof(size_t)) {
+	/* An unsigned int overflow can also be a size_t overflow */
+	const size_t zero = 0;
+	const size_t max = ~zero;
+
+	if (((size_t) reqSize) > max - sizeof(Block) - RCHECK) {
+	    /* Requested allocation exceeds memory */
+	    return NULL;
+	}
+    }
+#endif
+
+    GETCACHE(cachePtr);
+
+    /*
+     * If the block is not a system block and fits in place, simply return the
+     * existing pointer. Otherwise, if the block is a system block and the new
+     * size would also require a system block, call TclpSysRealloc() directly.
+     */
+
+    blockPtr = Ptr2Block(ptr);
+    size = reqSize + sizeof(Block);
+#if RCHECK
+    size++;
+#endif
+    bucket = blockPtr->sourceBucket;
+    if (bucket != NBUCKETS) {
+	if (bucket > 0) {
+	    min = bucketInfo[bucket-1].blockSize;
+	} else {
+	    min = 0;
+	}
+	if (size > min && size <= bucketInfo[bucket].blockSize) {
+	    cachePtr->buckets[bucket].totalAssigned -= blockPtr->blockReqSize;
+	    cachePtr->buckets[bucket].totalAssigned += reqSize;
+	    return Block2Ptr(blockPtr, bucket, reqSize);
+	}
+    } else if (size > MAXALLOC) {
+	cachePtr->totalAssigned -= blockPtr->blockReqSize;
+	cachePtr->totalAssigned += reqSize;
+	blockPtr = TclpSysRealloc(blockPtr, size);
+	if (blockPtr == NULL) {
+	    return NULL;
+	}
+	return Block2Ptr(blockPtr, NBUCKETS, reqSize);
+    }
+
+    /*
+     * Finally, perform an expensive malloc/copy/free.
+     */
+
+    newPtr = TclpAlloc(reqSize);
+    if (newPtr != NULL) {
+	if (reqSize > blockPtr->blockReqSize) {
+	    reqSize = blockPtr->blockReqSize;
+	}
+	memcpy(newPtr, ptr, reqSize);
+	TclpFree(ptr);
+    }
+    return newPtr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclThreadAllocObj --
+ *
+ *	Allocate a Tcl_Obj from the per-thread cache.
+ *
+ * Results:
+ *	Pointer to uninitialized Tcl_Obj.
+ *
+ * Side effects:
+ *	May move Tcl_Obj's from shared cached or allocate new Tcl_Obj's if
+ *	list is empty.
+ *
+ * Note:
+ *	If this code is updated, the changes need to be reflected in the macro
+ *	TclAllocObjStorageEx() defined in tclInt.h
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_Obj *
+TclThreadAllocObj(void)
+{
+    register Cache *cachePtr;
+    register Tcl_Obj *objPtr;
+
+    GETCACHE(cachePtr);
+
+    /*
+     * Get this thread's obj list structure and move or allocate new objs if
+     * necessary.
+     */
+
+    if (cachePtr->numObjects == 0) {
+	register int numMove;
+
+	Tcl_MutexLock(objLockPtr);
+	numMove = sharedPtr->numObjects;
+	if (numMove > 0) {
+	    if (numMove > NOBJALLOC) {
+		numMove = NOBJALLOC;
+	    }
+	    MoveObjs(sharedPtr, cachePtr, numMove);
+	}
+	Tcl_MutexUnlock(objLockPtr);
+	if (cachePtr->numObjects == 0) {
+	    Tcl_Obj *newObjsPtr;
+
+	    cachePtr->numObjects = numMove = NOBJALLOC;
+	    newObjsPtr = TclpSysAlloc(sizeof(Tcl_Obj) * numMove, 0);
+	    if (newObjsPtr == NULL) {
+		Tcl_Panic("alloc: could not allocate %d new objects", numMove);
+	    }
+	    cachePtr->lastPtr = newObjsPtr + numMove - 1;
+	    objPtr = cachePtr->firstObjPtr;	/* NULL */
+	    while (--numMove >= 0) {
+		newObjsPtr[numMove].internalRep.twoPtrValue.ptr1 = objPtr;
+		objPtr = newObjsPtr + numMove;
+	    }
+	    cachePtr->firstObjPtr = newObjsPtr;
+	}
+    }
+
+    /*
+     * Pop the first object.
+     */
+
+    objPtr = cachePtr->firstObjPtr;
+    cachePtr->firstObjPtr = objPtr->internalRep.twoPtrValue.ptr1;
+    cachePtr->numObjects--;
+    return objPtr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclThreadFreeObj --
+ *
+ *	Return a free Tcl_Obj to the per-thread cache.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	May move free Tcl_Obj's to shared list upon hitting high water mark.
+ *
+ * Note:
+ *	If this code is updated, the changes need to be reflected in the macro
+ *	TclAllocObjStorageEx() defined in tclInt.h
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclThreadFreeObj(
+    Tcl_Obj *objPtr)
+{
+    Cache *cachePtr;
+
+    GETCACHE(cachePtr);
+
+    /*
+     * Get this thread's list and push on the free Tcl_Obj.
+     */
+
+    objPtr->internalRep.twoPtrValue.ptr1 = cachePtr->firstObjPtr;
+    cachePtr->firstObjPtr = objPtr;
+    if (cachePtr->numObjects == 0) {
+	cachePtr->lastPtr = objPtr;
+    }
+    cachePtr->numObjects++;
+
+    /*
+     * If the number of free objects has exceeded the high water mark, move
+     * some blocks to the shared list.
+     */
+
+    if (cachePtr->numObjects > NOBJHIGH) {
+	PutObjs(cachePtr, NOBJALLOC);
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_GetMemoryInfo --
+ *
+ *	Return a list-of-lists of memory stats.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	List appended to given dstring.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_GetMemoryInfo(
+    Tcl_DString *dsPtr)
+{
+    Cache *cachePtr;
+    char buf[200];
+    unsigned int n;
+
+    Tcl_MutexLock(listLockPtr);
+    cachePtr = firstCachePtr;
+    while (cachePtr != NULL) {
+	Tcl_DStringStartSublist(dsPtr);
+	if (cachePtr == sharedPtr) {
+	    Tcl_DStringAppendElement(dsPtr, "shared");
+	} else {
+	    sprintf(buf, "thread%p", cachePtr->owner);
+	    Tcl_DStringAppendElement(dsPtr, buf);
+	}
+	for (n = 0; n < NBUCKETS; ++n) {
+	    sprintf(buf, "%lu %ld %ld %ld %ld %ld %ld",
+		    (unsigned long) bucketInfo[n].blockSize,
+		    cachePtr->buckets[n].numFree,
+		    cachePtr->buckets[n].numRemoves,
+		    cachePtr->buckets[n].numInserts,
+		    cachePtr->buckets[n].totalAssigned,
+		    cachePtr->buckets[n].numLocks,
+		    cachePtr->buckets[n].numWaits);
+	    Tcl_DStringAppendElement(dsPtr, buf);
+	}
+	Tcl_DStringEndSublist(dsPtr);
+	cachePtr = cachePtr->nextPtr;
+    }
+    Tcl_MutexUnlock(listLockPtr);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * MoveObjs --
+ *
+ *	Move Tcl_Obj's between caches.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+MoveObjs(
+    Cache *fromPtr,
+    Cache *toPtr,
+    int numMove)
+{
+    register Tcl_Obj *objPtr = fromPtr->firstObjPtr;
+    Tcl_Obj *fromFirstObjPtr = objPtr;
+
+    toPtr->numObjects += numMove;
+    fromPtr->numObjects -= numMove;
+
+    /*
+     * Find the last object to be moved; set the next one (the first one not
+     * to be moved) as the first object in the 'from' cache.
+     */
+
+    while (--numMove) {
+	objPtr = objPtr->internalRep.twoPtrValue.ptr1;
+    }
+    fromPtr->firstObjPtr = objPtr->internalRep.twoPtrValue.ptr1;
+
+    /*
+     * Move all objects as a block - they are already linked to each other, we
+     * just have to update the first and last.
+     */
+
+    toPtr->lastPtr = objPtr;
+    objPtr->internalRep.twoPtrValue.ptr1 = toPtr->firstObjPtr; /* NULL */
+    toPtr->firstObjPtr = fromFirstObjPtr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * PutObjs --
+ *
+ *	Move Tcl_Obj's from thread cache to shared cache.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+PutObjs(
+    Cache *fromPtr,
+    int numMove)
+{
+    int keep = fromPtr->numObjects - numMove;
+    Tcl_Obj *firstPtr, *lastPtr = NULL;
+
+    fromPtr->numObjects = keep;
+    firstPtr = fromPtr->firstObjPtr;
+    if (keep == 0) {
+	fromPtr->firstObjPtr = NULL;
+    } else {
+	do {
+	    lastPtr = firstPtr;
+	    firstPtr = firstPtr->internalRep.twoPtrValue.ptr1;
+	} while (--keep > 0);
+	lastPtr->internalRep.twoPtrValue.ptr1 = NULL;
+    }
+
+    /*
+     * Move all objects as a block - they are already linked to each other, we
+     * just have to update the first and last.
+     */
+
+    Tcl_MutexLock(objLockPtr);
+    fromPtr->lastPtr->internalRep.twoPtrValue.ptr1 = sharedPtr->firstObjPtr;
+    sharedPtr->firstObjPtr = firstPtr;
+    if (sharedPtr->numObjects == 0) {
+	sharedPtr->lastPtr = fromPtr->lastPtr;
+    }
+    sharedPtr->numObjects += numMove;
+    Tcl_MutexUnlock(objLockPtr);
+
+    fromPtr->lastPtr = lastPtr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Block2Ptr, Ptr2Block --
+ *
+ *	Convert between internal blocks and user pointers.
+ *
+ * Results:
+ *	User pointer or internal block.
+ *
+ * Side effects:
+ *	Invalid blocks will abort the server.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static char *
+Block2Ptr(
+    Block *blockPtr,
+    int bucket,
+    unsigned int reqSize)
+{
+    register void *ptr;
+
+    blockPtr->magicNum1 = blockPtr->magicNum2 = MAGIC;
+    blockPtr->sourceBucket = bucket;
+    blockPtr->blockReqSize = reqSize;
+    ptr = ((void *) (blockPtr + 1));
+#if RCHECK
+    ((unsigned char *)(ptr))[reqSize] = MAGIC;
+#endif
+    return (char *) ptr;
+}
+
+static Block *
+Ptr2Block(
+    char *ptr)
+{
+    register Block *blockPtr;
+
+    blockPtr = (((Block *) ptr) - 1);
+    if (blockPtr->magicNum1 != MAGIC || blockPtr->magicNum2 != MAGIC) {
+	Tcl_Panic("alloc: invalid block: %p: %x %x",
+		blockPtr, blockPtr->magicNum1, blockPtr->magicNum2);
+    }
+#if RCHECK
+    if (((unsigned char *) ptr)[blockPtr->blockReqSize] != MAGIC) {
+	Tcl_Panic("alloc: invalid block: %p: %x %x %x",
+		blockPtr, blockPtr->magicNum1, blockPtr->magicNum2,
+		((unsigned char *) ptr)[blockPtr->blockReqSize]);
+    }
+#endif
+    return blockPtr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * LockBucket, UnlockBucket --
+ *
+ *	Set/unset the lock to access a bucket in the shared cache.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Lock activity and contention are monitored globally and on a per-cache
+ *	basis.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+LockBucket(
+    Cache *cachePtr,
+    int bucket)
+{
+    Tcl_MutexLock(bucketInfo[bucket].lockPtr);
+    cachePtr->buckets[bucket].numLocks++;
+    sharedPtr->buckets[bucket].numLocks++;
+}
+
+static void
+UnlockBucket(
+    Cache *cachePtr,
+    int bucket)
+{
+    Tcl_MutexUnlock(bucketInfo[bucket].lockPtr);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * PutBlocks --
+ *
+ *	Return unused blocks to the shared cache.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+PutBlocks(
+    Cache *cachePtr,
+    int bucket,
+    int numMove)
+{
+    /*
+     * We have numFree.  Want to shed numMove. So compute how many
+     * Blocks to keep.
+     */
+
+    int keep = cachePtr->buckets[bucket].numFree - numMove;
+    Block *lastPtr = NULL, *firstPtr;
+
+    cachePtr->buckets[bucket].numFree = keep;
+    firstPtr = cachePtr->buckets[bucket].firstPtr;
+    if (keep == 0) {
+	cachePtr->buckets[bucket].firstPtr = NULL;
+    } else {
+	do {
+	    lastPtr = firstPtr;
+	    firstPtr = firstPtr->nextBlock;
+	} while (--keep > 0);
+	lastPtr->nextBlock = NULL;
+    }
+
+    /*
+     * Aquire the lock and place the list of blocks at the front of the shared
+     * cache bucket.
+     */
+
+    LockBucket(cachePtr, bucket);
+    cachePtr->buckets[bucket].lastPtr->nextBlock
+	    = sharedPtr->buckets[bucket].firstPtr;
+    sharedPtr->buckets[bucket].firstPtr = firstPtr;
+    if (sharedPtr->buckets[bucket].numFree == 0) {
+	sharedPtr->buckets[bucket].lastPtr
+		= cachePtr->buckets[bucket].lastPtr;
+    }
+    sharedPtr->buckets[bucket].numFree += numMove;
+    UnlockBucket(cachePtr, bucket);
+
+    cachePtr->buckets[bucket].lastPtr = lastPtr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * GetBlocks --
+ *
+ *	Get more blocks for a bucket.
+ *
+ * Results:
+ *	1 if blocks where allocated, 0 otherwise.
+ *
+ * Side effects:
+ *	Cache may be filled with available blocks.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+GetBlocks(
+    Cache *cachePtr,
+    int bucket)
+{
+    register Block *blockPtr;
+    register int n;
+
+    /*
+     * First, atttempt to move blocks from the shared cache. Note the
+     * potentially dirty read of numFree before acquiring the lock which is a
+     * slight performance enhancement. The value is verified after the lock is
+     * actually acquired.
+     */
+
+    if (cachePtr != sharedPtr && sharedPtr->buckets[bucket].numFree > 0) {
+	LockBucket(cachePtr, bucket);
+	if (sharedPtr->buckets[bucket].numFree > 0) {
+
+	    /*
+	     * Either move the entire list or walk the list to find the last
+	     * block to move.
+	     */
+
+	    n = bucketInfo[bucket].numMove;
+	    if (n >= sharedPtr->buckets[bucket].numFree) {
+		cachePtr->buckets[bucket].firstPtr =
+			sharedPtr->buckets[bucket].firstPtr;
+		cachePtr->buckets[bucket].lastPtr =
+			sharedPtr->buckets[bucket].lastPtr;
+		cachePtr->buckets[bucket].numFree =
+			sharedPtr->buckets[bucket].numFree;
+		sharedPtr->buckets[bucket].firstPtr = NULL;
+		sharedPtr->buckets[bucket].numFree = 0;
+	    } else {
+		blockPtr = sharedPtr->buckets[bucket].firstPtr;
+		cachePtr->buckets[bucket].firstPtr = blockPtr;
+		sharedPtr->buckets[bucket].numFree -= n;
+		cachePtr->buckets[bucket].numFree = n;
+		while (--n > 0) {
+		    blockPtr = blockPtr->nextBlock;
+		}
+		sharedPtr->buckets[bucket].firstPtr = blockPtr->nextBlock;
+		cachePtr->buckets[bucket].lastPtr = blockPtr;
+		blockPtr->nextBlock = NULL;
+	    }
+	}
+	UnlockBucket(cachePtr, bucket);
+    }
+
+    if (cachePtr->buckets[bucket].numFree == 0) {
+	register size_t size;
+
+	/*
+	 * If no blocks could be moved from shared, first look for a larger
+	 * block in this cache to split up.
+	 */
+
+	blockPtr = NULL;
+	n = NBUCKETS;
+	size = 0; /* lint */
+	while (--n > bucket) {
+	    if (cachePtr->buckets[n].numFree > 0) {
+		size = bucketInfo[n].blockSize;
+		blockPtr = cachePtr->buckets[n].firstPtr;
+		cachePtr->buckets[n].firstPtr = blockPtr->nextBlock;
+		cachePtr->buckets[n].numFree--;
+		break;
+	    }
+	}
+
+	/*
+	 * Otherwise, allocate a big new block directly.
+	 */
+
+	if (blockPtr == NULL) {
+	    size = MAXALLOC;
+	    blockPtr = TclpSysAlloc(size, 0);
+	    if (blockPtr == NULL) {
+		return 0;
+	    }
+	}
+
+	/*
+	 * Split the larger block into smaller blocks for this bucket.
+	 */
+
+	n = size / bucketInfo[bucket].blockSize;
+	cachePtr->buckets[bucket].numFree = n;
+	cachePtr->buckets[bucket].firstPtr = blockPtr;
+	while (--n > 0) {
+	    blockPtr->nextBlock = (Block *)
+		((char *) blockPtr + bucketInfo[bucket].blockSize);
+	    blockPtr = blockPtr->nextBlock;
+	}
+	cachePtr->buckets[bucket].lastPtr = blockPtr;
+	blockPtr->nextBlock = NULL;
+    }
+    return 1;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclFinalizeThreadAlloc --
+ *
+ *	This procedure is used to destroy all private resources used in this
+ *	file.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclFinalizeThreadAlloc(void)
+{
+    unsigned int i;
+
+    for (i = 0; i < NBUCKETS; ++i) {
+	TclpFreeAllocMutex(bucketInfo[i].lockPtr);
+	bucketInfo[i].lockPtr = NULL;
+    }
+
+    TclpFreeAllocMutex(objLockPtr);
+    objLockPtr = NULL;
+
+    TclpFreeAllocMutex(listLockPtr);
+    listLockPtr = NULL;
+
+    TclpFreeAllocCache(NULL);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclFinalizeThreadAllocThread --
+ *
+ *	This procedure is used to destroy single thread private resources used
+ *	in this file.
+ * Called in TclpFinalizeThreadData when a thread exits (Tcl_FinalizeThread).
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclFinalizeThreadAllocThread(void)
+{
+    Cache *cachePtr = TclpGetAllocCache();
+    if (cachePtr != NULL) {
+	TclpFreeAllocCache(cachePtr);
+    }
+}
+
+#else /* !(TCL_THREADS && USE_THREAD_ALLOC) */
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_GetMemoryInfo --
+ *
+ *	Return a list-of-lists of memory stats.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	List appended to given dstring.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_GetMemoryInfo(
+    Tcl_DString *dsPtr)
+{
+    Tcl_Panic("Tcl_GetMemoryInfo called when threaded memory allocator not in use");
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclFinalizeThreadAlloc --
+ *
+ *	This procedure is used to destroy all private resources used in this
+ *	file.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclFinalizeThreadAlloc(void)
+{
+    Tcl_Panic("TclFinalizeThreadAlloc called when threaded memory allocator not in use");
+}
+#endif /* TCL_THREADS && USE_THREAD_ALLOC */
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tclThreadJoin.c b/generic/tclThreadJoin.c
new file mode 100644
index 0000000..5c70a62
--- /dev/null
+++ b/generic/tclThreadJoin.c
@@ -0,0 +1,316 @@
+/*
+ * tclThreadJoin.c --
+ *
+ *	This file implements a platform independent emulation layer for the
+ *	handling of joinable threads. The Windows platform uses this code to
+ *	provide the functionality of joining threads.  This code is currently
+ *	not necessary on Unix.
+ *
+ * Copyright (c) 2000 by Scriptics Corporation
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#include "tclInt.h"
+
+#ifdef _WIN32
+
+/*
+ * The information about each joinable thread is remembered in a structure as
+ * defined below.
+ */
+
+typedef struct JoinableThread {
+    Tcl_ThreadId  id;		/* The id of the joinable thread. */
+    int result;			/* A place for the result after the demise of
+				 * the thread. */
+    int done;			/* Boolean flag. Initialized to 0 and set to 1
+				 * after the exit of the thread. This allows a
+				 * thread requesting a join to detect when
+				 * waiting is not necessary. */
+    int waitedUpon;		/* Boolean flag. Initialized to 0 and set to 1
+				 * by the thread waiting for this one via
+				 * Tcl_JoinThread.  Used to lock any other
+				 * thread trying to wait on this one. */
+    Tcl_Mutex threadMutex;	/* The mutex used to serialize access to this
+				 * structure. */
+    Tcl_Condition cond;		/* This is the condition a thread has to wait
+				 * upon to get notified of the end of the
+				 * described thread. It is signaled indirectly
+				 * by Tcl_ExitThread. */
+    struct JoinableThread *nextThreadPtr;
+				/* Reference to the next thread in the list of
+				 * joinable threads. */
+} JoinableThread;
+
+/*
+ * The following variable is used to maintain the global list of all joinable
+ * threads. Usage by a thread is allowed only if the thread acquired the
+ * 'joinMutex'.
+ */
+
+TCL_DECLARE_MUTEX(joinMutex)
+
+static JoinableThread *firstThreadPtr;
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclJoinThread --
+ *
+ *	This procedure waits for the exit of the thread with the specified id
+ *	and returns its result.
+ *
+ * Results:
+ *	A standard tcl result signaling the overall success/failure of the
+ *	operation and an integer result delivered by the thread which was
+ *	waited upon.
+ *
+ * Side effects:
+ *	Deallocates the memory allocated by TclRememberJoinableThread.
+ *	Removes the data associated to the thread waited upon from the list of
+ *	joinable threads.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclJoinThread(
+    Tcl_ThreadId id,		/* The id of the thread to wait upon. */
+    int *result)		/* Reference to a location for the result of
+				 * the thread we are waiting upon. */
+{
+    JoinableThread *threadPtr;
+
+    /*
+     * Steps done here:
+     * i.    Acquire the joinMutex and search for the thread.
+     * ii.   Error out if it could not be found.
+     * iii.  If found, switch from exclusive access to the list to exclusive
+     *	     access to the thread structure.
+     * iv.   Error out if some other is already waiting.
+     * v.    Skip the waiting part of the thread is already done.
+     * vi.   Wait for the thread to exit, mark it as waited upon too.
+     * vii.  Get the result form the structure,
+     * viii. switch to exclusive access of the list,
+     * ix.   remove the structure from the list,
+     * x.    then switch back to exclusive access to the structure
+     * xi.   and delete it.
+     */
+
+    Tcl_MutexLock(&joinMutex);
+
+    threadPtr = firstThreadPtr;
+    while (threadPtr!=NULL && threadPtr->id!=id) {
+	threadPtr = threadPtr->nextThreadPtr;
+    }
+
+    if (threadPtr == NULL) {
+	/*
+	 * Thread not found. Either not joinable, or already waited upon and
+	 * exited. Whatever, an error is in order.
+	 */
+
+	Tcl_MutexUnlock(&joinMutex);
+	return TCL_ERROR;
+    }
+
+    /*
+     * [1] If we don't lock the structure before giving up exclusive access to
+     * the list some other thread just completing its wait on the same thread
+     * can delete the structure from under us, leaving us with a dangling
+     * pointer.
+     */
+
+    Tcl_MutexLock(&threadPtr->threadMutex);
+    Tcl_MutexUnlock(&joinMutex);
+
+    /*
+     * [2] Now that we have the structure mutex any other thread that just
+     * tries to delete structure will wait at location [3] until we are done
+     * with the structure. And in that case we are done with it rather quickly
+     * as 'waitedUpon' will be set and we will have to error out.
+     */
+
+    if (threadPtr->waitedUpon) {
+	Tcl_MutexUnlock(&threadPtr->threadMutex);
+	return TCL_ERROR;
+    }
+
+    /*
+     * We are waiting now, let other threads recognize this.
+     */
+
+    threadPtr->waitedUpon = 1;
+
+    while (!threadPtr->done) {
+	Tcl_ConditionWait(&threadPtr->cond, &threadPtr->threadMutex, NULL);
+    }
+
+    /*
+     * We have to release the structure before trying to access the list again
+     * or we can run into deadlock with a thread at [1] (see above) because of
+     * us holding the structure and the other holding the list.  There is no
+     * problem with dangling pointers here as 'waitedUpon == 1' is still valid
+     * and any other thread will error out and not come to this place. IOW,
+     * the fact that we are here also means that no other thread came here
+     * before us and is able to delete the structure.
+     */
+
+    Tcl_MutexUnlock(&threadPtr->threadMutex);
+    Tcl_MutexLock(&joinMutex);
+
+    /*
+     * We have to search the list again as its structure may (may, almost
+     * certainly) have changed while we were waiting. Especially now is the
+     * time to compute the predecessor in the list. Any earlier result can be
+     * dangling by now.
+     */
+
+    if (firstThreadPtr == threadPtr) {
+	firstThreadPtr = threadPtr->nextThreadPtr;
+    } else {
+	JoinableThread *prevThreadPtr = firstThreadPtr;
+
+	while (prevThreadPtr->nextThreadPtr != threadPtr) {
+	    prevThreadPtr = prevThreadPtr->nextThreadPtr;
+	}
+	prevThreadPtr->nextThreadPtr = threadPtr->nextThreadPtr;
+    }
+
+    Tcl_MutexUnlock(&joinMutex);
+
+    /*
+     * [3] Now that the structure is not part of the list anymore no other
+     * thread can acquire its mutex from now on. But it is possible that
+     * another thread is still holding the mutex though, see location [2].  So
+     * we have to acquire the mutex one more time to wait for that thread to
+     * finish. We can (and have to) release the mutex immediately.
+     */
+
+    Tcl_MutexLock(&threadPtr->threadMutex);
+    Tcl_MutexUnlock(&threadPtr->threadMutex);
+
+    /*
+     * Copy the result to us, finalize the synchronisation objects, then free
+     * the structure and return.
+     */
+
+    *result = threadPtr->result;
+
+    Tcl_ConditionFinalize(&threadPtr->cond);
+    Tcl_MutexFinalize(&threadPtr->threadMutex);
+    ckfree(threadPtr);
+
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclRememberJoinableThread --
+ *
+ *	This procedure remebers a thread as joinable. Only a call to
+ *	TclJoinThread will remove the structre created (and initialized) here.
+ *	IOW, not waiting upon a joinable thread will cause memory leaks.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Allocates memory, adds it to the global list of all joinable threads.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclRememberJoinableThread(
+    Tcl_ThreadId id)		/* The thread to remember as joinable */
+{
+    JoinableThread *threadPtr;
+
+    threadPtr = ckalloc(sizeof(JoinableThread));
+    threadPtr->id = id;
+    threadPtr->done = 0;
+    threadPtr->waitedUpon = 0;
+    threadPtr->threadMutex = (Tcl_Mutex) NULL;
+    threadPtr->cond = (Tcl_Condition) NULL;
+
+    Tcl_MutexLock(&joinMutex);
+
+    threadPtr->nextThreadPtr = firstThreadPtr;
+    firstThreadPtr = threadPtr;
+
+    Tcl_MutexUnlock(&joinMutex);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclSignalExitThread --
+ *
+ *	This procedure signals that the specified thread is done with its
+ *	work. If the thread is joinable this signal is propagated to the
+ *	thread waiting upon it.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Modifies the associated structure to hold the result.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclSignalExitThread(
+    Tcl_ThreadId id,		/* Id of the thread signaling its exit. */
+    int result)			/* The result from the thread. */
+{
+    JoinableThread *threadPtr;
+
+    Tcl_MutexLock(&joinMutex);
+
+    threadPtr = firstThreadPtr;
+    while ((threadPtr != NULL) && (threadPtr->id != id)) {
+	threadPtr = threadPtr->nextThreadPtr;
+    }
+
+    if (threadPtr == NULL) {
+	/*
+	 * Thread not found. Not joinable. No problem, nothing to do.
+	 */
+
+	Tcl_MutexUnlock(&joinMutex);
+	return;
+    }
+
+    /*
+     * Switch over the exclusive access from the list to the structure, then
+     * store the result, set the flag and notify the waiting thread, provided
+     * that it exists. The order of lock/unlock ensures that a thread entering
+     * 'TclJoinThread' will not interfere with us.
+     */
+
+    Tcl_MutexLock(&threadPtr->threadMutex);
+    Tcl_MutexUnlock(&joinMutex);
+
+    threadPtr->done = 1;
+    threadPtr->result = result;
+
+    if (threadPtr->waitedUpon) {
+	Tcl_ConditionNotify(&threadPtr->cond);
+    }
+
+    Tcl_MutexUnlock(&threadPtr->threadMutex);
+}
+#endif /* _WIN32 */
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tclThreadStorage.c b/generic/tclThreadStorage.c
new file mode 100644
index 0000000..755a461
--- /dev/null
+++ b/generic/tclThreadStorage.c
@@ -0,0 +1,373 @@
+/*
+ * tclThreadStorage.c --
+ *
+ *	This file implements platform independent thread storage operations to
+ *	work around system limits on the number of thread-specific variables.
+ *
+ * Copyright (c) 2003-2004 by Joe Mistachkin
+ * Copyright (c) 2008 by George Peter Staplin
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#include "tclInt.h"
+
+#ifdef TCL_THREADS
+#include <signal.h>
+
+/*
+ * IMPLEMENTATION NOTES:
+ *
+ * The primary idea is that we create one platform-specific TSD slot, and use
+ * it for storing a table pointer. Each Tcl_ThreadDataKey has an offset into
+ * the table of TSD values. We don't use more than 1 platform-specific TSD
+ * slot, because there is a hard limit on the number of TSD slots. Valid key
+ * offsets are greater than 0; 0 is for the initialized Tcl_ThreadDataKey.
+ */
+
+/*
+ * The master collection of information about TSDs. This is shared across the
+ * whole process, and includes the mutex used to protect it.
+ */
+
+static struct TSDMaster {
+    void *key;			/* Key into the system TSD structure. The
+				 * collection of Tcl TSD values for a
+				 * particular thread will hang off the
+				 * back-end of this. */
+    sig_atomic_t counter;	/* The number of different Tcl TSDs used
+				 * across *all* threads. This is a strictly
+				 * increasing value. */
+    Tcl_Mutex mutex;		/* Protection for the rest of this structure,
+				 * which holds per-process data. */
+} tsdMaster = { NULL, 0, NULL };
+
+/*
+ * The type of the data held per thread in a system TSD.
+ */
+
+typedef struct TSDTable {
+    ClientData *tablePtr;	/* The table of Tcl TSDs. */
+    sig_atomic_t allocated;	/* The size of the table in the current
+				 * thread. */
+} TSDTable;
+
+/*
+ * The actual type of Tcl_ThreadDataKey.
+ */
+
+typedef union TSDUnion {
+    volatile sig_atomic_t offset;
+				/* The type is really an offset into the
+				 * thread-local table of TSDs, which is this
+				 * field. */
+    void *ptr;			/* For alignment purposes only. Not actually
+				 * accessed through this. */
+} TSDUnion;
+
+/*
+ * Forward declarations of functions in this file.
+ */
+
+static TSDTable *	TSDTableCreate(void);
+static void		TSDTableDelete(TSDTable *tsdTablePtr);
+static void		TSDTableGrow(TSDTable *tsdTablePtr,
+			    sig_atomic_t atLeast);
+
+/*
+ * Allocator and deallocator for a TSDTable structure.
+ */
+
+static TSDTable *
+TSDTableCreate(void)
+{
+    TSDTable *tsdTablePtr;
+    sig_atomic_t i;
+
+    tsdTablePtr = TclpSysAlloc(sizeof(TSDTable), 0);
+    if (tsdTablePtr == NULL) {
+	Tcl_Panic("unable to allocate TSDTable");
+    }
+
+    tsdTablePtr->allocated = 8;
+    tsdTablePtr->tablePtr =
+	    TclpSysAlloc(sizeof(void *) * tsdTablePtr->allocated, 0);
+    if (tsdTablePtr->tablePtr == NULL) {
+	Tcl_Panic("unable to allocate TSDTable");
+    }
+
+    for (i = 0; i < tsdTablePtr->allocated; ++i) {
+	tsdTablePtr->tablePtr[i] = NULL;
+    }
+
+    return tsdTablePtr;
+}
+
+static void
+TSDTableDelete(
+    TSDTable *tsdTablePtr)
+{
+    sig_atomic_t i;
+
+    for (i=0 ; i<tsdTablePtr->allocated ; i++) {
+	if (tsdTablePtr->tablePtr[i] != NULL) {
+	    /*
+	     * These values were allocated in Tcl_GetThreadData in tclThread.c
+	     * and must now be deallocated or they will leak.
+	     */
+
+	    ckfree(tsdTablePtr->tablePtr[i]);
+	}
+    }
+
+    TclpSysFree(tsdTablePtr->tablePtr);
+    TclpSysFree(tsdTablePtr);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TSDTableGrow --
+ *
+ *	This procedure makes the passed TSDTable grow to fit the atLeast
+ *	value.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The table is enlarged.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+TSDTableGrow(
+    TSDTable *tsdTablePtr,
+    sig_atomic_t atLeast)
+{
+    sig_atomic_t newAllocated = tsdTablePtr->allocated * 2;
+    ClientData *newTablePtr;
+    sig_atomic_t i;
+
+    if (newAllocated <= atLeast) {
+	newAllocated = atLeast + 10;
+    }
+
+    newTablePtr = TclpSysRealloc(tsdTablePtr->tablePtr,
+	    sizeof(ClientData) * newAllocated);
+    if (newTablePtr == NULL) {
+	Tcl_Panic("unable to reallocate TSDTable");
+    }
+
+    for (i = tsdTablePtr->allocated; i < newAllocated; ++i) {
+	newTablePtr[i] = NULL;
+    }
+
+    tsdTablePtr->allocated = newAllocated;
+    tsdTablePtr->tablePtr = newTablePtr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclThreadStorageKeyGet --
+ *
+ *    This procedure gets the value associated with the passed key.
+ *
+ * Results:
+ *	A pointer value associated with the Tcl_ThreadDataKey or NULL.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void *
+TclThreadStorageKeyGet(
+    Tcl_ThreadDataKey *dataKeyPtr)
+{
+    TSDTable *tsdTablePtr = TclpThreadGetMasterTSD(tsdMaster.key);
+    ClientData resultPtr = NULL;
+    TSDUnion *keyPtr = (TSDUnion *) dataKeyPtr;
+    sig_atomic_t offset = keyPtr->offset;
+
+    if ((tsdTablePtr != NULL) && (offset > 0)
+	    && (offset < tsdTablePtr->allocated)) {
+	resultPtr = tsdTablePtr->tablePtr[offset];
+    }
+    return resultPtr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclThreadStorageKeySet --
+ *
+ *	This procedure set an association of value with the key passed. The
+ *	associated value may be retrieved with TclThreadDataKeyGet().
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The thread-specific table may be created or reallocated.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclThreadStorageKeySet(
+    Tcl_ThreadDataKey *dataKeyPtr,
+    void *value)
+{
+    TSDTable *tsdTablePtr = TclpThreadGetMasterTSD(tsdMaster.key);
+    TSDUnion *keyPtr = (TSDUnion *) dataKeyPtr;
+
+    if (tsdTablePtr == NULL) {
+	tsdTablePtr = TSDTableCreate();
+	TclpThreadSetMasterTSD(tsdMaster.key, tsdTablePtr);
+    }
+
+    /*
+     * Get the lock while we check if this TSD is new or not. Note that this
+     * is the only place where Tcl_ThreadDataKey values are set. We use a
+     * double-checked lock to try to avoid having to grab this lock a lot,
+     * since it is on quite a few critical paths and will only get set once in
+     * each location.
+     */
+
+    if (keyPtr->offset == 0) {
+	Tcl_MutexLock(&tsdMaster.mutex);
+	if (keyPtr->offset == 0) {
+	    /*
+	     * The Tcl_ThreadDataKey hasn't been used yet. Make a new one.
+	     */
+
+	    keyPtr->offset = ++tsdMaster.counter;
+	}
+	Tcl_MutexUnlock(&tsdMaster.mutex);
+    }
+
+    /*
+     * Check if this is the first time this Tcl_ThreadDataKey has been used
+     * with the current thread. Note that we don't need to hold a lock when
+     * doing this, as we are *definitely* the only point accessing this
+     * tsdTablePtr right now; it's thread-local.
+     */
+
+    if (keyPtr->offset >= tsdTablePtr->allocated) {
+	TSDTableGrow(tsdTablePtr, keyPtr->offset);
+    }
+
+    /*
+     * Set the value in the Tcl thread-local variable.
+     */
+
+    tsdTablePtr->tablePtr[keyPtr->offset] = value;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclFinalizeThreadDataThread --
+ *
+ *	This procedure finalizes the data for a single thread.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The TSDTable is deleted/freed.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclFinalizeThreadDataThread(void)
+{
+    TSDTable *tsdTablePtr = TclpThreadGetMasterTSD(tsdMaster.key);
+
+    if (tsdTablePtr != NULL) {
+	TSDTableDelete(tsdTablePtr);
+	TclpThreadSetMasterTSD(tsdMaster.key, NULL);
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclInitializeThreadStorage --
+ *
+ *	This procedure initializes the TSD subsystem with per-platform code.
+ *	This should be called before any Tcl threads are created.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Allocates a system TSD.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclInitThreadStorage(void)
+{
+    tsdMaster.key = TclpThreadCreateKey();
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclFinalizeThreadStorage --
+ *
+ *	This procedure cleans up the thread storage data key for all threads.
+ *	IMPORTANT: All Tcl threads must be finalized before calling this!
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Releases the thread data key.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclFinalizeThreadStorage(void)
+{
+    TclpThreadDeleteKey(tsdMaster.key);
+    tsdMaster.key = NULL;
+}
+
+#else /* !TCL_THREADS */
+/*
+ * Stub functions for non-threaded builds
+ */
+
+void
+TclInitThreadStorage(void)
+{
+}
+
+void
+TclFinalizeThreadDataThread(void)
+{
+}
+
+void
+TclFinalizeThreadStorage(void)
+{
+}
+#endif /* TCL_THREADS */
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tclThreadTest.c b/generic/tclThreadTest.c
new file mode 100644
index 0000000..9c66313
--- /dev/null
+++ b/generic/tclThreadTest.c
@@ -0,0 +1,1211 @@
+/*
+ * tclThreadTest.c --
+ *
+ *	This file implements the testthread command. Eventually this should be
+ *	tclThreadCmd.c
+ *	Some of this code is based on work done by Richard Hipp on behalf of
+ *	Conservation Through Innovation, Limited, with their permission.
+ *
+ * Copyright (c) 1998 by Sun Microsystems, Inc.
+ * Copyright (c) 2006-2008 by Joe Mistachkin.  All rights reserved.
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#ifndef USE_TCL_STUBS
+#   define USE_TCL_STUBS
+#endif
+#include "tclInt.h"
+
+#ifdef TCL_THREADS
+/*
+ * Each thread has an single instance of the following structure. There is one
+ * instance of this structure per thread even if that thread contains multiple
+ * interpreters. The interpreter identified by this structure is the main
+ * interpreter for the thread.
+ *
+ * The main interpreter is the one that will process any messages received by
+ * a thread. Any thread can send messages but only the main interpreter can
+ * receive them.
+ */
+
+typedef struct ThreadSpecificData {
+    Tcl_ThreadId threadId;	/* Tcl ID for this thread */
+    Tcl_Interp *interp;		/* Main interpreter for this thread */
+    int flags;			/* See the TP_ defines below... */
+    struct ThreadSpecificData *nextPtr;
+				/* List for "thread names" */
+    struct ThreadSpecificData *prevPtr;
+				/* List for "thread names" */
+} ThreadSpecificData;
+static Tcl_ThreadDataKey dataKey;
+
+/*
+ * This list is used to list all threads that have interpreters. This is
+ * protected by threadMutex.
+ */
+
+static ThreadSpecificData *threadList = NULL;
+
+/*
+ * The following bit-values are legal for the "flags" field of the
+ * ThreadSpecificData structure.
+ */
+
+#define TP_Dying		0x001 /* This thread is being canceled */
+
+/*
+ * An instance of the following structure contains all information that is
+ * passed into a new thread when the thread is created using either the
+ * "thread create" Tcl command or the ThreadCreate() C function.
+ */
+
+typedef struct ThreadCtrl {
+    const char *script;		/* The Tcl command this thread should
+				 * execute */
+    int flags;			/* Initial value of the "flags" field in the
+				 * ThreadSpecificData structure for the new
+				 * thread. Might contain TP_Detached or
+				 * TP_TclThread. */
+    Tcl_Condition condWait;	/* This condition variable is used to
+				 * synchronize the parent and child threads.
+				 * The child won't run until it acquires
+				 * threadMutex, and the parent function won't
+				 * complete until signaled on this condition
+				 * variable. */
+} ThreadCtrl;
+
+/*
+ * This is the event used to send scripts to other threads.
+ */
+
+typedef struct ThreadEvent {
+    Tcl_Event event;		/* Must be first */
+    char *script;		/* The script to execute. */
+    struct ThreadEventResult *resultPtr;
+				/* To communicate the result. This is NULL if
+				 * we don't care about it. */
+} ThreadEvent;
+
+typedef struct ThreadEventResult {
+    Tcl_Condition done;		/* Signaled when the script completes */
+    int code;			/* Return value of Tcl_Eval */
+    char *result;		/* Result from the script */
+    char *errorInfo;		/* Copy of errorInfo variable */
+    char *errorCode;		/* Copy of errorCode variable */
+    Tcl_ThreadId srcThreadId;	/* Id of sending thread, in case it dies */
+    Tcl_ThreadId dstThreadId;	/* Id of target thread, in case it dies */
+    struct ThreadEvent *eventPtr;	/* Back pointer */
+    struct ThreadEventResult *nextPtr;	/* List for cleanup */
+    struct ThreadEventResult *prevPtr;
+
+} ThreadEventResult;
+
+static ThreadEventResult *resultList;
+
+/*
+ * This is for simple error handling when a thread script exits badly.
+ */
+
+static Tcl_ThreadId mainThreadId;
+static Tcl_ThreadId errorThreadId;
+static char *errorProcString;
+
+/*
+ * Access to the list of threads and to the thread send results is guarded by
+ * this mutex.
+ */
+
+TCL_DECLARE_MUTEX(threadMutex)
+
+static int		ThreadObjCmd(ClientData clientData,
+			    Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+static int		ThreadCreate(Tcl_Interp *interp, const char *script,
+			    int joinable);
+static int		ThreadList(Tcl_Interp *interp);
+static int		ThreadSend(Tcl_Interp *interp, Tcl_ThreadId id,
+			    const char *script, int wait);
+static int		ThreadCancel(Tcl_Interp *interp, Tcl_ThreadId id,
+			    const char *result, int flags);
+
+static Tcl_ThreadCreateType	NewTestThread(ClientData clientData);
+static void		ListRemove(ThreadSpecificData *tsdPtr);
+static void		ListUpdateInner(ThreadSpecificData *tsdPtr);
+static int		ThreadEventProc(Tcl_Event *evPtr, int mask);
+static void		ThreadErrorProc(Tcl_Interp *interp);
+static void		ThreadFreeProc(ClientData clientData);
+static int		ThreadDeleteEvent(Tcl_Event *eventPtr,
+			    ClientData clientData);
+static void		ThreadExitProc(ClientData clientData);
+extern int		Tcltest_Init(Tcl_Interp *interp);
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclThread_Init --
+ *
+ *	Initialize the test thread command.
+ *
+ * Results:
+ *	TCL_OK if the package was properly initialized.
+ *
+ * Side effects:
+ *	Add the "testthread" command to the interp.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclThread_Init(
+    Tcl_Interp *interp)		/* The current Tcl interpreter */
+{
+    /*
+     * If the main thread Id has not been set, do it now.
+     */
+
+    Tcl_MutexLock(&threadMutex);
+    if (mainThreadId == 0) {
+	mainThreadId = Tcl_GetCurrentThread();
+    }
+    Tcl_MutexUnlock(&threadMutex);
+
+    Tcl_CreateObjCommand(interp, "testthread", ThreadObjCmd, NULL, NULL);
+    return TCL_OK;
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ThreadObjCmd --
+ *
+ *	This procedure is invoked to process the "testthread" Tcl command. See
+ *	the user documentation for details on what it does.
+ *
+ *	thread cancel ?-unwind? id ?result?
+ *	thread create ?-joinable? ?script?
+ *	thread send ?-async? id script
+ *	thread event
+ *	thread exit
+ *	thread id ?-main?
+ *	thread names
+ *	thread wait
+ *	thread errorproc proc
+ *	thread join id
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+	/* ARGSUSED */
+static int
+ThreadObjCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+    int option;
+    static const char *const threadOptions[] = {
+	"cancel", "create", "event", "exit", "id",
+	"join", "names", "send", "wait", "errorproc",
+	NULL
+    };
+    enum options {
+	THREAD_CANCEL, THREAD_CREATE, THREAD_EVENT, THREAD_EXIT,
+	THREAD_ID, THREAD_JOIN, THREAD_NAMES, THREAD_SEND,
+	THREAD_WAIT, THREAD_ERRORPROC
+    };
+
+    if (objc < 2) {
+	Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?");
+	return TCL_ERROR;
+    }
+    if (Tcl_GetIndexFromObj(interp, objv[1], threadOptions, "option", 0,
+	    &option) != TCL_OK) {
+	return TCL_ERROR;
+    }
+
+    /*
+     * Make sure the initial thread is on the list before doing anything.
+     */
+
+    if (tsdPtr->interp == NULL) {
+	Tcl_MutexLock(&threadMutex);
+	tsdPtr->interp = interp;
+	ListUpdateInner(tsdPtr);
+	Tcl_CreateThreadExitHandler(ThreadExitProc, NULL);
+	Tcl_MutexUnlock(&threadMutex);
+    }
+
+    switch ((enum options)option) {
+    case THREAD_CANCEL: {
+	long id;
+	const char *result;
+	int flags, arg;
+
+	if ((objc < 3) || (objc > 5)) {
+	    Tcl_WrongNumArgs(interp, 2, objv, "?-unwind? id ?result?");
+	    return TCL_ERROR;
+	}
+	flags = 0;
+	arg = 2;
+	if ((objc == 4) || (objc == 5)) {
+	    if (strcmp("-unwind", Tcl_GetString(objv[arg])) == 0) {
+		flags = TCL_CANCEL_UNWIND;
+		arg++;
+	    }
+	}
+	if (Tcl_GetLongFromObj(interp, objv[arg], &id) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	arg++;
+	if (arg < objc) {
+	    result = Tcl_GetString(objv[arg]);
+	} else {
+	    result = NULL;
+	}
+	return ThreadCancel(interp, (Tcl_ThreadId) (size_t) id, result, flags);
+    }
+    case THREAD_CREATE: {
+	const char *script;
+	int joinable, len;
+
+	if (objc == 2) {
+	    /*
+	     * Neither joinable nor special script
+	     */
+
+	    joinable = 0;
+	    script = "testthread wait";		/* Just enter event loop */
+	} else if (objc == 3) {
+	    /*
+	     * Possibly -joinable, then no special script, no joinable, then
+	     * its a script.
+	     */
+
+	    script = Tcl_GetStringFromObj(objv[2], &len);
+
+	    if ((len > 1) && (script[0] == '-') && (script[1] == 'j') &&
+		    (0 == strncmp(script, "-joinable", (size_t) len))) {
+		joinable = 1;
+		script = "testthread wait";	/* Just enter event loop */
+	    } else {
+		/*
+		 * Remember the script
+		 */
+
+		joinable = 0;
+	    }
+	} else if (objc == 4) {
+	    /*
+	     * Definitely a script available, but is the flag -joinable?
+	     */
+
+	    script = Tcl_GetStringFromObj(objv[2], &len);
+	    joinable = ((len > 1) && (script[0] == '-') && (script[1] == 'j')
+		    && (0 == strncmp(script, "-joinable", (size_t) len)));
+	    script = Tcl_GetString(objv[3]);
+	} else {
+	    Tcl_WrongNumArgs(interp, 2, objv, "?-joinable? ?script?");
+	    return TCL_ERROR;
+	}
+	return ThreadCreate(interp, script, joinable);
+    }
+    case THREAD_EXIT:
+	if (objc > 2) {
+	    Tcl_WrongNumArgs(interp, 2, objv, NULL);
+	    return TCL_ERROR;
+	}
+	ListRemove(NULL);
+	Tcl_ExitThread(0);
+	return TCL_OK;
+    case THREAD_ID:
+	if (objc == 2 || objc == 3) {
+	    Tcl_Obj *idObj;
+
+	    /*
+	     * Check if they want the main thread id or the current thread id.
+	     */
+
+	    if (objc == 2) {
+		idObj = Tcl_NewWideIntObj((Tcl_WideInt)(size_t)Tcl_GetCurrentThread());
+	    } else if (objc == 3
+		    && strcmp("-main", Tcl_GetString(objv[2])) == 0) {
+		Tcl_MutexLock(&threadMutex);
+		idObj = Tcl_NewLongObj((long)(size_t)mainThreadId);
+		Tcl_MutexUnlock(&threadMutex);
+	    } else {
+		Tcl_WrongNumArgs(interp, 2, objv, NULL);
+		return TCL_ERROR;
+	    }
+
+	    Tcl_SetObjResult(interp, idObj);
+	    return TCL_OK;
+	} else {
+	    Tcl_WrongNumArgs(interp, 2, objv, NULL);
+	    return TCL_ERROR;
+	}
+    case THREAD_JOIN: {
+	Tcl_WideInt id;
+	int result, status;
+
+	if (objc != 3) {
+	    Tcl_WrongNumArgs(interp, 2, objv, "id");
+	    return TCL_ERROR;
+	}
+	if (Tcl_GetWideIntFromObj(interp, objv[2], &id) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+
+	result = Tcl_JoinThread((Tcl_ThreadId)(size_t)id, &status);
+	if (result == TCL_OK) {
+	    Tcl_SetIntObj(Tcl_GetObjResult(interp), status);
+	} else {
+	    char buf[20];
+
+	    sprintf(buf, "%" TCL_LL_MODIFIER "d", id);
+	    Tcl_AppendResult(interp, "cannot join thread ", buf, NULL);
+	}
+	return result;
+    }
+    case THREAD_NAMES:
+	if (objc > 2) {
+	    Tcl_WrongNumArgs(interp, 2, objv, NULL);
+	    return TCL_ERROR;
+	}
+	return ThreadList(interp);
+    case THREAD_SEND: {
+	Tcl_WideInt id;
+	const char *script;
+	int wait, arg;
+
+	if ((objc != 4) && (objc != 5)) {
+	    Tcl_WrongNumArgs(interp, 2, objv, "?-async? id script");
+	    return TCL_ERROR;
+	}
+	if (objc == 5) {
+	    if (strcmp("-async", Tcl_GetString(objv[2])) != 0) {
+		Tcl_WrongNumArgs(interp, 2, objv, "?-async? id script");
+		return TCL_ERROR;
+	    }
+	    wait = 0;
+	    arg = 3;
+	} else {
+	    wait = 1;
+	    arg = 2;
+	}
+	if (Tcl_GetWideIntFromObj(interp, objv[arg], &id) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	arg++;
+	script = Tcl_GetString(objv[arg]);
+	return ThreadSend(interp, (Tcl_ThreadId)(size_t)id, script, wait);
+    }
+    case THREAD_EVENT: {
+	if (objc > 2) {
+	    Tcl_WrongNumArgs(interp, 2, objv, NULL);
+	    return TCL_ERROR;
+	}
+	Tcl_SetObjResult(interp, Tcl_NewIntObj(
+		Tcl_DoOneEvent(TCL_ALL_EVENTS | TCL_DONT_WAIT)));
+	return TCL_OK;
+    }
+    case THREAD_ERRORPROC: {
+	/*
+	 * Arrange for this proc to handle thread death errors.
+	 */
+
+	const char *proc;
+
+	if (objc != 3) {
+	    Tcl_WrongNumArgs(interp, 2, objv, "proc");
+	    return TCL_ERROR;
+	}
+	Tcl_MutexLock(&threadMutex);
+	errorThreadId = Tcl_GetCurrentThread();
+	if (errorProcString) {
+	    ckfree(errorProcString);
+	}
+	proc = Tcl_GetString(objv[2]);
+	errorProcString = ckalloc(strlen(proc) + 1);
+	strcpy(errorProcString, proc);
+	Tcl_MutexUnlock(&threadMutex);
+	return TCL_OK;
+    }
+    case THREAD_WAIT:
+	if (objc > 2) {
+	    Tcl_WrongNumArgs(interp, 2, objv, "");
+	    return TCL_ERROR;
+	}
+	while (1) {
+	    /*
+	     * If the script has been unwound, bail out immediately. This does
+	     * not follow the recommended guidelines for how extensions should
+	     * handle the script cancellation functionality because this is
+	     * not a "normal" extension. Most extensions do not have a command
+	     * that simply enters an infinite Tcl event loop. Normal
+	     * extensions should not specify the TCL_CANCEL_UNWIND when
+	     * calling Tcl_Canceled to check if the command has been canceled.
+	     */
+
+	    if (Tcl_Canceled(interp,
+		    TCL_LEAVE_ERR_MSG | TCL_CANCEL_UNWIND) == TCL_ERROR) {
+		break;
+	    }
+	    (void) Tcl_DoOneEvent(TCL_ALL_EVENTS);
+	}
+
+	/*
+	 * If we get to this point, we have been canceled by another thread,
+	 * which is considered to be an "error".
+	 */
+
+	ThreadErrorProc(interp);
+	return TCL_OK;
+    }
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ThreadCreate --
+ *
+ *	This procedure is invoked to create a thread containing an interp to
+ *	run a script. This returns after the thread has started executing.
+ *
+ * Results:
+ *	A standard Tcl result, which is the thread ID.
+ *
+ * Side effects:
+ *	Create a thread.
+ *
+ *----------------------------------------------------------------------
+ */
+
+	/* ARGSUSED */
+static int
+ThreadCreate(
+    Tcl_Interp *interp,		/* Current interpreter. */
+    const char *script,		/* Script to execute */
+    int joinable)		/* Flag, joinable thread or not */
+{
+    ThreadCtrl ctrl;
+    Tcl_ThreadId id;
+
+    ctrl.script = script;
+    ctrl.condWait = NULL;
+    ctrl.flags = 0;
+
+    joinable = joinable ? TCL_THREAD_JOINABLE : TCL_THREAD_NOFLAGS;
+
+    Tcl_MutexLock(&threadMutex);
+    if (Tcl_CreateThread(&id, NewTestThread, (ClientData) &ctrl,
+	    TCL_THREAD_STACK_DEFAULT, joinable) != TCL_OK) {
+	Tcl_MutexUnlock(&threadMutex);
+	Tcl_AppendResult(interp, "can't create a new thread", NULL);
+	return TCL_ERROR;
+    }
+
+    /*
+     * Wait for the thread to start because it is using something on our stack!
+     */
+
+    Tcl_ConditionWait(&ctrl.condWait, &threadMutex, NULL);
+    Tcl_MutexUnlock(&threadMutex);
+    Tcl_ConditionFinalize(&ctrl.condWait);
+    Tcl_SetObjResult(interp, Tcl_NewWideIntObj((Tcl_WideInt)(size_t)id));
+    return TCL_OK;
+}
+
+/*
+ *------------------------------------------------------------------------
+ *
+ * NewTestThread --
+ *
+ *	This routine is the "main()" for a new thread whose task is to execute
+ *	a single Tcl script. The argument to this function is a pointer to a
+ *	structure that contains the text of the TCL script to be executed.
+ *
+ *	Space to hold the script field of the ThreadControl structure passed
+ *	in as the only argument was obtained from malloc() and must be freed
+ *	by this function before it exits. Space to hold the ThreadControl
+ *	structure itself is released by the calling function, and the two
+ *	condition variables in the ThreadControl structure are destroyed by
+ *	the calling function. The calling function will destroy the
+ *	ThreadControl structure and the condition variable as soon as
+ *	ctrlPtr->condWait is signaled, so this routine must make copies of any
+ *	data it might need after that point.
+ *
+ * Results:
+ *	None
+ *
+ * Side effects:
+ *	A Tcl script is executed in a new thread.
+ *
+ *------------------------------------------------------------------------
+ */
+
+Tcl_ThreadCreateType
+NewTestThread(
+    ClientData clientData)
+{
+    ThreadCtrl *ctrlPtr = clientData;
+    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+    int result;
+    char *threadEvalScript;
+
+    /*
+     * Initialize the interpreter. This should be more general.
+     */
+
+    tsdPtr->interp = Tcl_CreateInterp();
+    result = Tcl_Init(tsdPtr->interp);
+    if (result != TCL_OK) {
+	ThreadErrorProc(tsdPtr->interp);
+    }
+
+    /*
+     * This is part of the test facility. Initialize _ALL_ test commands for
+     * use by the new thread.
+     */
+
+    result = Tcltest_Init(tsdPtr->interp);
+    if (result != TCL_OK) {
+	ThreadErrorProc(tsdPtr->interp);
+    }
+
+    /*
+     * Update the list of threads.
+     */
+
+    Tcl_MutexLock(&threadMutex);
+    ListUpdateInner(tsdPtr);
+
+    /*
+     * We need to keep a pointer to the alloc'ed mem of the script we are
+     * eval'ing, for the case that we exit during evaluation
+     */
+
+    threadEvalScript = ckalloc(strlen(ctrlPtr->script) + 1);
+    strcpy(threadEvalScript, ctrlPtr->script);
+
+    Tcl_CreateThreadExitHandler(ThreadExitProc, threadEvalScript);
+
+    /*
+     * Notify the parent we are alive.
+     */
+
+    Tcl_ConditionNotify(&ctrlPtr->condWait);
+    Tcl_MutexUnlock(&threadMutex);
+
+    /*
+     * Run the script.
+     */
+
+    Tcl_Preserve(tsdPtr->interp);
+    result = Tcl_EvalEx(tsdPtr->interp, threadEvalScript, -1, 0);
+    if (result != TCL_OK) {
+	ThreadErrorProc(tsdPtr->interp);
+    }
+
+    /*
+     * Clean up.
+     */
+
+    Tcl_DeleteInterp(tsdPtr->interp);
+    Tcl_Release(tsdPtr->interp);
+    ListRemove(tsdPtr);
+    Tcl_ExitThread(result);
+
+    TCL_THREAD_CREATE_RETURN;
+}
+
+/*
+ *------------------------------------------------------------------------
+ *
+ * ThreadErrorProc --
+ *
+ *	Send a message to the thread willing to hear about errors.
+ *
+ * Results:
+ *	None
+ *
+ * Side effects:
+ *	Send an event.
+ *
+ *------------------------------------------------------------------------
+ */
+
+static void
+ThreadErrorProc(
+    Tcl_Interp *interp)		/* Interp that failed */
+{
+    Tcl_Channel errChannel;
+    const char *errorInfo, *argv[3];
+    char *script;
+    char buf[TCL_DOUBLE_SPACE+1];
+
+    sprintf(buf, "%" TCL_LL_MODIFIER "d", (Tcl_WideInt)(size_t)Tcl_GetCurrentThread());
+
+    errorInfo = Tcl_GetVar(interp, "errorInfo", TCL_GLOBAL_ONLY);
+    if (errorProcString == NULL) {
+	errChannel = Tcl_GetStdChannel(TCL_STDERR);
+	Tcl_WriteChars(errChannel, "Error from thread ", -1);
+	Tcl_WriteChars(errChannel, buf, -1);
+	Tcl_WriteChars(errChannel, "\n", 1);
+	Tcl_WriteChars(errChannel, errorInfo, -1);
+	Tcl_WriteChars(errChannel, "\n", 1);
+    } else {
+	argv[0] = errorProcString;
+	argv[1] = buf;
+	argv[2] = errorInfo;
+	script = Tcl_Merge(3, argv);
+	ThreadSend(interp, errorThreadId, script, 0);
+	ckfree(script);
+    }
+}
+
+
+/*
+ *------------------------------------------------------------------------
+ *
+ * ListUpdateInner --
+ *
+ *	Add the thread local storage to the list. This assumes the caller has
+ *	obtained the mutex.
+ *
+ * Results:
+ *	None
+ *
+ * Side effects:
+ *	Add the thread local storage to its list.
+ *
+ *------------------------------------------------------------------------
+ */
+
+static void
+ListUpdateInner(
+    ThreadSpecificData *tsdPtr)
+{
+    if (tsdPtr == NULL) {
+	tsdPtr = TCL_TSD_INIT(&dataKey);
+    }
+    tsdPtr->threadId = Tcl_GetCurrentThread();
+    tsdPtr->nextPtr = threadList;
+    if (threadList) {
+	threadList->prevPtr = tsdPtr;
+    }
+    tsdPtr->prevPtr = NULL;
+    threadList = tsdPtr;
+}
+
+/*
+ *------------------------------------------------------------------------
+ *
+ * ListRemove --
+ *
+ *	Remove the thread local storage from its list. This grabs the mutex to
+ *	protect the list.
+ *
+ * Results:
+ *	None
+ *
+ * Side effects:
+ *	Remove the thread local storage from its list.
+ *
+ *------------------------------------------------------------------------
+ */
+
+static void
+ListRemove(
+    ThreadSpecificData *tsdPtr)
+{
+    if (tsdPtr == NULL) {
+	tsdPtr = TCL_TSD_INIT(&dataKey);
+    }
+    Tcl_MutexLock(&threadMutex);
+    if (tsdPtr->prevPtr) {
+	tsdPtr->prevPtr->nextPtr = tsdPtr->nextPtr;
+    } else {
+	threadList = tsdPtr->nextPtr;
+    }
+    if (tsdPtr->nextPtr) {
+	tsdPtr->nextPtr->prevPtr = tsdPtr->prevPtr;
+    }
+    tsdPtr->nextPtr = tsdPtr->prevPtr = 0;
+    tsdPtr->interp = NULL;
+    Tcl_MutexUnlock(&threadMutex);
+}
+
+/*
+ *------------------------------------------------------------------------
+ *
+ * ThreadList --
+ *
+ *    Return a list of threads running Tcl interpreters.
+ *
+ * Results:
+ *    A standard Tcl result.
+ *
+ * Side effects:
+ *    None.
+ *
+ *------------------------------------------------------------------------
+ */
+static int
+ThreadList(
+    Tcl_Interp *interp)
+{
+    ThreadSpecificData *tsdPtr;
+    Tcl_Obj *listPtr;
+
+    listPtr = Tcl_NewListObj(0, NULL);
+    Tcl_MutexLock(&threadMutex);
+    for (tsdPtr = threadList ; tsdPtr ; tsdPtr = tsdPtr->nextPtr) {
+	Tcl_ListObjAppendElement(interp, listPtr,
+		Tcl_NewWideIntObj((Tcl_WideInt)(size_t)tsdPtr->threadId));
+    }
+    Tcl_MutexUnlock(&threadMutex);
+    Tcl_SetObjResult(interp, listPtr);
+    return TCL_OK;
+}
+
+/*
+ *------------------------------------------------------------------------
+ *
+ * ThreadSend --
+ *
+ *    Send a script to another thread.
+ *
+ * Results:
+ *    A standard Tcl result.
+ *
+ * Side effects:
+ *    None.
+ *
+ *------------------------------------------------------------------------
+ */
+
+static int
+ThreadSend(
+    Tcl_Interp *interp,		/* The current interpreter. */
+    Tcl_ThreadId id,		/* Thread Id of other interpreter. */
+    const char *script,		/* The script to evaluate. */
+    int wait)			/* If 1, we block for the result. */
+{
+    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+    ThreadEvent *threadEventPtr;
+    ThreadEventResult *resultPtr;
+    int found, code;
+    Tcl_ThreadId threadId = (Tcl_ThreadId) id;
+
+    /*
+     * Verify the thread exists.
+     */
+
+    Tcl_MutexLock(&threadMutex);
+    found = 0;
+    for (tsdPtr = threadList ; tsdPtr ; tsdPtr = tsdPtr->nextPtr) {
+	if (tsdPtr->threadId == threadId) {
+	    found = 1;
+	    break;
+	}
+    }
+    if (!found) {
+	Tcl_MutexUnlock(&threadMutex);
+	Tcl_AppendResult(interp, "invalid thread id", NULL);
+	return TCL_ERROR;
+    }
+
+    /*
+     * Short circut sends to ourself. Ought to do something with -async, like
+     * run in an idle handler.
+     */
+
+    if (threadId == Tcl_GetCurrentThread()) {
+	Tcl_MutexUnlock(&threadMutex);
+	return Tcl_EvalEx(interp, script,-1,TCL_EVAL_GLOBAL);
+    }
+
+    /*
+     * Create the event for its event queue.
+     */
+
+    threadEventPtr = ckalloc(sizeof(ThreadEvent));
+    threadEventPtr->script = ckalloc(strlen(script) + 1);
+    strcpy(threadEventPtr->script, script);
+    if (!wait) {
+	resultPtr = threadEventPtr->resultPtr = NULL;
+    } else {
+	resultPtr = ckalloc(sizeof(ThreadEventResult));
+	threadEventPtr->resultPtr = resultPtr;
+
+	/*
+	 * Initialize the result fields.
+	 */
+
+	resultPtr->done = NULL;
+	resultPtr->code = 0;
+	resultPtr->result = NULL;
+	resultPtr->errorInfo = NULL;
+	resultPtr->errorCode = NULL;
+
+	/*
+	 * Maintain the cleanup list.
+	 */
+
+	resultPtr->srcThreadId = Tcl_GetCurrentThread();
+	resultPtr->dstThreadId = threadId;
+	resultPtr->eventPtr = threadEventPtr;
+	resultPtr->nextPtr = resultList;
+	if (resultList) {
+	    resultList->prevPtr = resultPtr;
+	}
+	resultPtr->prevPtr = NULL;
+	resultList = resultPtr;
+    }
+
+    /*
+     * Queue the event and poke the other thread's notifier.
+     */
+
+    threadEventPtr->event.proc = ThreadEventProc;
+    Tcl_ThreadQueueEvent(threadId, (Tcl_Event *) threadEventPtr,
+	    TCL_QUEUE_TAIL);
+    Tcl_ThreadAlert(threadId);
+
+    if (!wait) {
+	Tcl_MutexUnlock(&threadMutex);
+	return TCL_OK;
+    }
+
+    /*
+     * Block on the results and then get them.
+     */
+
+    Tcl_ResetResult(interp);
+    while (resultPtr->result == NULL) {
+	Tcl_ConditionWait(&resultPtr->done, &threadMutex, NULL);
+    }
+
+    /*
+     * Unlink result from the result list.
+     */
+
+    if (resultPtr->prevPtr) {
+	resultPtr->prevPtr->nextPtr = resultPtr->nextPtr;
+    } else {
+	resultList = resultPtr->nextPtr;
+    }
+    if (resultPtr->nextPtr) {
+	resultPtr->nextPtr->prevPtr = resultPtr->prevPtr;
+    }
+    resultPtr->eventPtr = NULL;
+    resultPtr->nextPtr = NULL;
+    resultPtr->prevPtr = NULL;
+
+    Tcl_MutexUnlock(&threadMutex);
+
+    if (resultPtr->code != TCL_OK) {
+	if (resultPtr->errorCode) {
+	    Tcl_SetErrorCode(interp, resultPtr->errorCode, NULL);
+	    ckfree(resultPtr->errorCode);
+	}
+	if (resultPtr->errorInfo) {
+	    Tcl_AddErrorInfo(interp, resultPtr->errorInfo);
+	    ckfree(resultPtr->errorInfo);
+	}
+    }
+    Tcl_AppendResult(interp, resultPtr->result, NULL);
+    Tcl_ConditionFinalize(&resultPtr->done);
+    code = resultPtr->code;
+
+    ckfree(resultPtr->result);
+    ckfree(resultPtr);
+
+    return code;
+}
+
+/*
+ *------------------------------------------------------------------------
+ *
+ * ThreadCancel --
+ *
+ *    Cancels a script in another thread.
+ *
+ * Results:
+ *    A standard Tcl result.
+ *
+ * Side effects:
+ *    None.
+ *
+ *------------------------------------------------------------------------
+ */
+
+static int
+ThreadCancel(
+    Tcl_Interp *interp,		/* The current interpreter. */
+    Tcl_ThreadId id,		/* Thread Id of other interpreter. */
+    const char *result,		/* The result or NULL for default. */
+    int flags)			/* Flags for Tcl_CancelEval. */
+{
+    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+    int found;
+    Tcl_ThreadId threadId = (Tcl_ThreadId) id;
+
+    /*
+     * Verify the thread exists.
+     */
+
+    Tcl_MutexLock(&threadMutex);
+    found = 0;
+    for (tsdPtr = threadList ; tsdPtr ; tsdPtr = tsdPtr->nextPtr) {
+	if (tsdPtr->threadId == threadId) {
+	    found = 1;
+	    break;
+	}
+    }
+    if (!found) {
+	Tcl_MutexUnlock(&threadMutex);
+	Tcl_AppendResult(interp, "invalid thread id", NULL);
+	return TCL_ERROR;
+    }
+
+    /*
+     * Since Tcl_CancelEval can be safely called from any thread,
+     * we do it now.
+     */
+
+    Tcl_MutexUnlock(&threadMutex);
+    Tcl_ResetResult(interp);
+    return Tcl_CancelEval(tsdPtr->interp,
+    	(result != NULL) ? Tcl_NewStringObj(result, -1) : NULL, 0, flags);
+}
+
+/*
+ *------------------------------------------------------------------------
+ *
+ * ThreadEventProc --
+ *
+ *    Handle the event in the target thread.
+ *
+ * Results:
+ *    Returns 1 to indicate that the event was processed.
+ *
+ * Side effects:
+ *    Fills out the ThreadEventResult struct.
+ *
+ *------------------------------------------------------------------------
+ */
+
+static int
+ThreadEventProc(
+    Tcl_Event *evPtr,		/* Really ThreadEvent */
+    int mask)
+{
+    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+    ThreadEvent *threadEventPtr = (ThreadEvent *) evPtr;
+    ThreadEventResult *resultPtr = threadEventPtr->resultPtr;
+    Tcl_Interp *interp = tsdPtr->interp;
+    int code;
+    const char *result, *errorCode, *errorInfo;
+
+    if (interp == NULL) {
+	code = TCL_ERROR;
+	result = "no target interp!";
+	errorCode = "THREAD";
+	errorInfo = "";
+    } else {
+	Tcl_Preserve(interp);
+	Tcl_ResetResult(interp);
+	Tcl_CreateThreadExitHandler(ThreadFreeProc, threadEventPtr->script);
+	code = Tcl_EvalEx(interp, threadEventPtr->script,-1,TCL_EVAL_GLOBAL);
+	Tcl_DeleteThreadExitHandler(ThreadFreeProc, threadEventPtr->script);
+	if (code != TCL_OK) {
+	    errorCode = Tcl_GetVar(interp, "errorCode", TCL_GLOBAL_ONLY);
+	    errorInfo = Tcl_GetVar(interp, "errorInfo", TCL_GLOBAL_ONLY);
+	} else {
+	    errorCode = errorInfo = NULL;
+	}
+	result = Tcl_GetStringResult(interp);
+    }
+    ckfree(threadEventPtr->script);
+    if (resultPtr) {
+	Tcl_MutexLock(&threadMutex);
+	resultPtr->code = code;
+	resultPtr->result = ckalloc(strlen(result) + 1);
+	strcpy(resultPtr->result, result);
+	if (errorCode != NULL) {
+	    resultPtr->errorCode = ckalloc(strlen(errorCode) + 1);
+	    strcpy(resultPtr->errorCode, errorCode);
+	}
+	if (errorInfo != NULL) {
+	    resultPtr->errorInfo = ckalloc(strlen(errorInfo) + 1);
+	    strcpy(resultPtr->errorInfo, errorInfo);
+	}
+	Tcl_ConditionNotify(&resultPtr->done);
+	Tcl_MutexUnlock(&threadMutex);
+    }
+    if (interp != NULL) {
+	Tcl_Release(interp);
+    }
+    return 1;
+}
+
+/*
+ *------------------------------------------------------------------------
+ *
+ * ThreadFreeProc --
+ *
+ *    This is called from when we are exiting and memory needs
+ *    to be freed.
+ *
+ * Results:
+ *    None.
+ *
+ * Side effects:
+ *	Clears up mem specified in ClientData
+ *
+ *------------------------------------------------------------------------
+ */
+
+     /* ARGSUSED */
+static void
+ThreadFreeProc(
+    ClientData clientData)
+{
+    if (clientData) {
+	ckfree(clientData);
+    }
+}
+
+/*
+ *------------------------------------------------------------------------
+ *
+ * ThreadDeleteEvent --
+ *
+ *    This is called from the ThreadExitProc to delete memory related
+ *    to events that we put on the queue.
+ *
+ * Results:
+ *    1 it was our event and we want it removed, 0 otherwise.
+ *
+ * Side effects:
+ *	It cleans up our events in the event queue for this thread.
+ *
+ *------------------------------------------------------------------------
+ */
+
+     /* ARGSUSED */
+static int
+ThreadDeleteEvent(
+    Tcl_Event *eventPtr,	/* Really ThreadEvent */
+    ClientData clientData)	/* dummy */
+{
+    if (eventPtr->proc == ThreadEventProc) {
+	ckfree(((ThreadEvent *) eventPtr)->script);
+	return 1;
+    }
+
+    /*
+     * If it was NULL, we were in the middle of servicing the event and it
+     * should be removed
+     */
+
+    return (eventPtr->proc == NULL);
+}
+
+/*
+ *------------------------------------------------------------------------
+ *
+ * ThreadExitProc --
+ *
+ *    This is called when the thread exits.
+ *
+ * Results:
+ *    None.
+ *
+ * Side effects:
+ *	It unblocks anyone that is waiting on a send to this thread. It cleans
+ *	up any events in the event queue for this thread.
+ *
+ *------------------------------------------------------------------------
+ */
+
+     /* ARGSUSED */
+static void
+ThreadExitProc(
+    ClientData clientData)
+{
+    char *threadEvalScript = clientData;
+    ThreadEventResult *resultPtr, *nextPtr;
+    Tcl_ThreadId self = Tcl_GetCurrentThread();
+    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+
+    if (tsdPtr->interp != NULL) {
+	ListRemove(tsdPtr);
+    }
+
+    Tcl_MutexLock(&threadMutex);
+
+    if (threadEvalScript) {
+	ckfree(threadEvalScript);
+	threadEvalScript = NULL;
+    }
+    Tcl_DeleteEvents((Tcl_EventDeleteProc *) ThreadDeleteEvent, NULL);
+
+    for (resultPtr = resultList ; resultPtr ; resultPtr = nextPtr) {
+	nextPtr = resultPtr->nextPtr;
+	if (resultPtr->srcThreadId == self) {
+	    /*
+	     * We are going away. By freeing up the result we signal to the
+	     * other thread we don't care about the result.
+	     */
+
+	    if (resultPtr->prevPtr) {
+		resultPtr->prevPtr->nextPtr = resultPtr->nextPtr;
+	    } else {
+		resultList = resultPtr->nextPtr;
+	    }
+	    if (resultPtr->nextPtr) {
+		resultPtr->nextPtr->prevPtr = resultPtr->prevPtr;
+	    }
+	    resultPtr->nextPtr = resultPtr->prevPtr = 0;
+	    resultPtr->eventPtr->resultPtr = NULL;
+	    ckfree(resultPtr);
+	} else if (resultPtr->dstThreadId == self) {
+	    /*
+	     * Dang. The target is going away. Unblock the caller. The result
+	     * string must be dynamically allocated because the main thread is
+	     * going to call free on it.
+	     */
+
+	    const char *msg = "target thread died";
+
+	    resultPtr->result = ckalloc(strlen(msg) + 1);
+	    strcpy(resultPtr->result, msg);
+	    resultPtr->code = TCL_ERROR;
+	    Tcl_ConditionNotify(&resultPtr->done);
+	}
+    }
+    Tcl_MutexUnlock(&threadMutex);
+}
+#endif /* TCL_THREADS */
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tclTimer.c b/generic/tclTimer.c
new file mode 100644
index 0000000..c10986a
--- /dev/null
+++ b/generic/tclTimer.c
@@ -0,0 +1,1293 @@
+/*
+ * tclTimer.c --
+ *
+ *	This file provides timer event management facilities for Tcl,
+ *	including the "after" command.
+ *
+ * Copyright (c) 1997 by Sun Microsystems, Inc.
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#include "tclInt.h"
+
+/*
+ * For each timer callback that's pending there is one record of the following
+ * type. The normal handlers (created by Tcl_CreateTimerHandler) are chained
+ * together in a list sorted by time (earliest event first).
+ */
+
+typedef struct TimerHandler {
+    Tcl_Time time;		/* When timer is to fire. */
+    Tcl_TimerProc *proc;	/* Function to call. */
+    ClientData clientData;	/* Argument to pass to proc. */
+    Tcl_TimerToken token;	/* Identifies handler so it can be deleted. */
+    struct TimerHandler *nextPtr;
+				/* Next event in queue, or NULL for end of
+				 * queue. */
+} TimerHandler;
+
+/*
+ * The data structure below is used by the "after" command to remember the
+ * command to be executed later. All of the pending "after" commands for an
+ * interpreter are linked together in a list.
+ */
+
+typedef struct AfterInfo {
+    struct AfterAssocData *assocPtr;
+				/* Pointer to the "tclAfter" assocData for the
+				 * interp in which command will be
+				 * executed. */
+    Tcl_Obj *commandPtr;	/* Command to execute. */
+    int id;			/* Integer identifier for command; used to
+				 * cancel it. */
+    Tcl_TimerToken token;	/* Used to cancel the "after" command. NULL
+				 * means that the command is run as an idle
+				 * handler rather than as a timer handler.
+				 * NULL means this is an "after idle" handler
+				 * rather than a timer handler. */
+    struct AfterInfo *nextPtr;	/* Next in list of all "after" commands for
+				 * this interpreter. */
+} AfterInfo;
+
+/*
+ * One of the following structures is associated with each interpreter for
+ * which an "after" command has ever been invoked. A pointer to this structure
+ * is stored in the AssocData for the "tclAfter" key.
+ */
+
+typedef struct AfterAssocData {
+    Tcl_Interp *interp;		/* The interpreter for which this data is
+				 * registered. */
+    AfterInfo *firstAfterPtr;	/* First in list of all "after" commands still
+				 * pending for this interpreter, or NULL if
+				 * none. */
+} AfterAssocData;
+
+/*
+ * There is one of the following structures for each of the handlers declared
+ * in a call to Tcl_DoWhenIdle. All of the currently-active handlers are
+ * linked together into a list.
+ */
+
+typedef struct IdleHandler {
+    Tcl_IdleProc *proc;		/* Function to call. */
+    ClientData clientData;	/* Value to pass to proc. */
+    int generation;		/* Used to distinguish older handlers from
+				 * recently-created ones. */
+    struct IdleHandler *nextPtr;/* Next in list of active handlers. */
+} IdleHandler;
+
+/*
+ * The timer and idle queues are per-thread because they are associated with
+ * the notifier, which is also per-thread.
+ *
+ * All static variables used in this file are collected into a single instance
+ * of the following structure. For multi-threaded implementations, there is
+ * one instance of this structure for each thread.
+ *
+ * Notice that different structures with the same name appear in other files.
+ * The structure defined below is used in this file only.
+ */
+
+typedef struct ThreadSpecificData {
+    TimerHandler *firstTimerHandlerPtr;	/* First event in queue. */
+    int lastTimerId;		/* Timer identifier of most recently created
+				 * timer. */
+    int timerPending;		/* 1 if a timer event is in the queue. */
+    IdleHandler *idleList;	/* First in list of all idle handlers. */
+    IdleHandler *lastIdlePtr;	/* Last in list (or NULL for empty list). */
+    int idleGeneration;		/* Used to fill in the "generation" fields of
+				 * IdleHandler structures. Increments each
+				 * time Tcl_DoOneEvent starts calling idle
+				 * handlers, so that all old handlers can be
+				 * called without calling any of the new ones
+				 * created by old ones. */
+    int afterId;		/* For unique identifiers of after events. */
+} ThreadSpecificData;
+
+static Tcl_ThreadDataKey dataKey;
+
+/*
+ * Helper macros for working with times. TCL_TIME_BEFORE encodes how to write
+ * the ordering relation on (normalized) times, and TCL_TIME_DIFF_MS computes
+ * the number of milliseconds difference between two times. Both macros use
+ * both of their arguments multiple times, so make sure they are cheap and
+ * side-effect free. The "prototypes" for these macros are:
+ *
+ * static int	TCL_TIME_BEFORE(Tcl_Time t1, Tcl_Time t2);
+ * static long	TCL_TIME_DIFF_MS(Tcl_Time t1, Tcl_Time t2);
+ */
+
+#define TCL_TIME_BEFORE(t1, t2) \
+    (((t1).sec<(t2).sec) || ((t1).sec==(t2).sec && (t1).usec<(t2).usec))
+
+#define TCL_TIME_DIFF_MS(t1, t2) \
+    (1000*((Tcl_WideInt)(t1).sec - (Tcl_WideInt)(t2).sec) + \
+	    ((long)(t1).usec - (long)(t2).usec)/1000)
+
+#define TCL_TIME_DIFF_MS_CEILING(t1, t2) \
+    (1000*((Tcl_WideInt)(t1).sec - (Tcl_WideInt)(t2).sec) + \
+	    ((long)(t1).usec - (long)(t2).usec + 999)/1000)
+
+/*
+ * Sleeps under that number of milliseconds don't get double-checked
+ * and are done in exactly one Tcl_Sleep(). This to limit gettimeofday()s.
+ */
+
+#define SLEEP_OFFLOAD_GETTIMEOFDAY 20
+
+/*
+ * The maximum number of milliseconds for each Tcl_Sleep call in AfterDelay.
+ * This is used to limit the maximum lag between interp limit and script
+ * cancellation checks.
+ */
+
+#define TCL_TIME_MAXIMUM_SLICE 500
+
+/*
+ * Prototypes for functions referenced only in this file:
+ */
+
+static void		AfterCleanupProc(ClientData clientData,
+			    Tcl_Interp *interp);
+static int		AfterDelay(Tcl_Interp *interp, Tcl_WideInt ms);
+static void		AfterProc(ClientData clientData);
+static void		FreeAfterPtr(AfterInfo *afterPtr);
+static AfterInfo *	GetAfterEvent(AfterAssocData *assocPtr,
+			    Tcl_Obj *commandPtr);
+static ThreadSpecificData *InitTimer(void);
+static void		TimerExitProc(ClientData clientData);
+static int		TimerHandlerEventProc(Tcl_Event *evPtr, int flags);
+static void		TimerCheckProc(ClientData clientData, int flags);
+static void		TimerSetupProc(ClientData clientData, int flags);
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * InitTimer --
+ *
+ *	This function initializes the timer module.
+ *
+ * Results:
+ *	A pointer to the thread specific data.
+ *
+ * Side effects:
+ *	Registers the idle and timer event sources.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static ThreadSpecificData *
+InitTimer(void)
+{
+    ThreadSpecificData *tsdPtr = TclThreadDataKeyGet(&dataKey);
+
+    if (tsdPtr == NULL) {
+	tsdPtr = TCL_TSD_INIT(&dataKey);
+	Tcl_CreateEventSource(TimerSetupProc, TimerCheckProc, NULL);
+	Tcl_CreateThreadExitHandler(TimerExitProc, NULL);
+    }
+    return tsdPtr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TimerExitProc --
+ *
+ *	This function is call at exit or unload time to remove the timer and
+ *	idle event sources.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Removes the timer and idle event sources and remaining events.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+TimerExitProc(
+    ClientData clientData)	/* Not used. */
+{
+    ThreadSpecificData *tsdPtr = TclThreadDataKeyGet(&dataKey);
+
+    Tcl_DeleteEventSource(TimerSetupProc, TimerCheckProc, NULL);
+    if (tsdPtr != NULL) {
+	register TimerHandler *timerHandlerPtr;
+
+	timerHandlerPtr = tsdPtr->firstTimerHandlerPtr;
+	while (timerHandlerPtr != NULL) {
+	    tsdPtr->firstTimerHandlerPtr = timerHandlerPtr->nextPtr;
+	    ckfree(timerHandlerPtr);
+	    timerHandlerPtr = tsdPtr->firstTimerHandlerPtr;
+	}
+    }
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * Tcl_CreateTimerHandler --
+ *
+ *	Arrange for a given function to be invoked at a particular time in the
+ *	future.
+ *
+ * Results:
+ *	The return value is a token for the timer event, which may be used to
+ *	delete the event before it fires.
+ *
+ * Side effects:
+ *	When milliseconds have elapsed, proc will be invoked exactly once.
+ *
+ *--------------------------------------------------------------
+ */
+
+Tcl_TimerToken
+Tcl_CreateTimerHandler(
+    int milliseconds,		/* How many milliseconds to wait before
+				 * invoking proc. */
+    Tcl_TimerProc *proc,	/* Function to invoke. */
+    ClientData clientData)	/* Arbitrary data to pass to proc. */
+{
+    Tcl_Time time;
+
+    /*
+     * Compute when the event should fire.
+     */
+
+    Tcl_GetTime(&time);
+    time.sec += milliseconds/1000;
+    time.usec += (milliseconds%1000)*1000;
+    if (time.usec >= 1000000) {
+	time.usec -= 1000000;
+	time.sec += 1;
+    }
+    return TclCreateAbsoluteTimerHandler(&time, proc, clientData);
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * TclCreateAbsoluteTimerHandler --
+ *
+ *	Arrange for a given function to be invoked at a particular time in the
+ *	future.
+ *
+ * Results:
+ *	The return value is a token for the timer event, which may be used to
+ *	delete the event before it fires.
+ *
+ * Side effects:
+ *	When the time in timePtr has been reached, proc will be invoked
+ *	exactly once.
+ *
+ *--------------------------------------------------------------
+ */
+
+Tcl_TimerToken
+TclCreateAbsoluteTimerHandler(
+    Tcl_Time *timePtr,
+    Tcl_TimerProc *proc,
+    ClientData clientData)
+{
+    register TimerHandler *timerHandlerPtr, *tPtr2, *prevPtr;
+    ThreadSpecificData *tsdPtr = InitTimer();
+
+    timerHandlerPtr = ckalloc(sizeof(TimerHandler));
+
+    /*
+     * Fill in fields for the event.
+     */
+
+    memcpy(&timerHandlerPtr->time, timePtr, sizeof(Tcl_Time));
+    timerHandlerPtr->proc = proc;
+    timerHandlerPtr->clientData = clientData;
+    tsdPtr->lastTimerId++;
+    timerHandlerPtr->token = (Tcl_TimerToken) INT2PTR(tsdPtr->lastTimerId);
+
+    /*
+     * Add the event to the queue in the correct position
+     * (ordered by event firing time).
+     */
+
+    for (tPtr2 = tsdPtr->firstTimerHandlerPtr, prevPtr = NULL; tPtr2 != NULL;
+	    prevPtr = tPtr2, tPtr2 = tPtr2->nextPtr) {
+	if (TCL_TIME_BEFORE(timerHandlerPtr->time, tPtr2->time)) {
+	    break;
+	}
+    }
+    timerHandlerPtr->nextPtr = tPtr2;
+    if (prevPtr == NULL) {
+	tsdPtr->firstTimerHandlerPtr = timerHandlerPtr;
+    } else {
+	prevPtr->nextPtr = timerHandlerPtr;
+    }
+
+    TimerSetupProc(NULL, TCL_ALL_EVENTS);
+
+    return timerHandlerPtr->token;
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * Tcl_DeleteTimerHandler --
+ *
+ *	Delete a previously-registered timer handler.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Destroy the timer callback identified by TimerToken, so that its
+ *	associated function will not be called. If the callback has already
+ *	fired, or if the given token doesn't exist, then nothing happens.
+ *
+ *--------------------------------------------------------------
+ */
+
+void
+Tcl_DeleteTimerHandler(
+    Tcl_TimerToken token)	/* Result previously returned by
+				 * Tcl_DeleteTimerHandler. */
+{
+    register TimerHandler *timerHandlerPtr, *prevPtr;
+    ThreadSpecificData *tsdPtr = InitTimer();
+
+    if (token == NULL) {
+	return;
+    }
+
+    for (timerHandlerPtr = tsdPtr->firstTimerHandlerPtr, prevPtr = NULL;
+	    timerHandlerPtr != NULL; prevPtr = timerHandlerPtr,
+	    timerHandlerPtr = timerHandlerPtr->nextPtr) {
+	if (timerHandlerPtr->token != token) {
+	    continue;
+	}
+	if (prevPtr == NULL) {
+	    tsdPtr->firstTimerHandlerPtr = timerHandlerPtr->nextPtr;
+	} else {
+	    prevPtr->nextPtr = timerHandlerPtr->nextPtr;
+	}
+	ckfree(timerHandlerPtr);
+	return;
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TimerSetupProc --
+ *
+ *	This function is called by Tcl_DoOneEvent to setup the timer event
+ *	source for before blocking. This routine checks both the idle and
+ *	after timer lists.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	May update the maximum notifier block time.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+TimerSetupProc(
+    ClientData data,		/* Not used. */
+    int flags)			/* Event flags as passed to Tcl_DoOneEvent. */
+{
+    Tcl_Time blockTime;
+    ThreadSpecificData *tsdPtr = InitTimer();
+
+    if (((flags & TCL_IDLE_EVENTS) && tsdPtr->idleList)
+	    || ((flags & TCL_TIMER_EVENTS) && tsdPtr->timerPending)) {
+	/*
+	 * There is an idle handler or a pending timer event, so just poll.
+	 */
+
+	blockTime.sec = 0;
+	blockTime.usec = 0;
+    } else if ((flags & TCL_TIMER_EVENTS) && tsdPtr->firstTimerHandlerPtr) {
+	/*
+	 * Compute the timeout for the next timer on the list.
+	 */
+
+	Tcl_GetTime(&blockTime);
+	blockTime.sec = tsdPtr->firstTimerHandlerPtr->time.sec - blockTime.sec;
+	blockTime.usec = tsdPtr->firstTimerHandlerPtr->time.usec -
+		blockTime.usec;
+	if (blockTime.usec < 0) {
+	    blockTime.sec -= 1;
+	    blockTime.usec += 1000000;
+	}
+	if (blockTime.sec < 0) {
+	    blockTime.sec = 0;
+	    blockTime.usec = 0;
+	}
+    } else {
+	return;
+    }
+
+    Tcl_SetMaxBlockTime(&blockTime);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TimerCheckProc --
+ *
+ *	This function is called by Tcl_DoOneEvent to check the timer event
+ *	source for events. This routine checks both the idle and after timer
+ *	lists.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	May queue an event and update the maximum notifier block time.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+TimerCheckProc(
+    ClientData data,		/* Not used. */
+    int flags)			/* Event flags as passed to Tcl_DoOneEvent. */
+{
+    Tcl_Event *timerEvPtr;
+    Tcl_Time blockTime;
+    ThreadSpecificData *tsdPtr = InitTimer();
+
+    if ((flags & TCL_TIMER_EVENTS) && tsdPtr->firstTimerHandlerPtr) {
+	/*
+	 * Compute the timeout for the next timer on the list.
+	 */
+
+	Tcl_GetTime(&blockTime);
+	blockTime.sec = tsdPtr->firstTimerHandlerPtr->time.sec - blockTime.sec;
+	blockTime.usec = tsdPtr->firstTimerHandlerPtr->time.usec -
+		blockTime.usec;
+	if (blockTime.usec < 0) {
+	    blockTime.sec -= 1;
+	    blockTime.usec += 1000000;
+	}
+	if (blockTime.sec < 0) {
+	    blockTime.sec = 0;
+	    blockTime.usec = 0;
+	}
+
+	/*
+	 * If the first timer has expired, stick an event on the queue.
+	 */
+
+	if (blockTime.sec == 0 && blockTime.usec == 0 &&
+		!tsdPtr->timerPending) {
+	    tsdPtr->timerPending = 1;
+	    timerEvPtr = ckalloc(sizeof(Tcl_Event));
+	    timerEvPtr->proc = TimerHandlerEventProc;
+	    Tcl_QueueEvent(timerEvPtr, TCL_QUEUE_TAIL);
+	}
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TimerHandlerEventProc --
+ *
+ *	This function is called by Tcl_ServiceEvent when a timer event reaches
+ *	the front of the event queue. This function handles the event by
+ *	invoking the callbacks for all timers that are ready.
+ *
+ * Results:
+ *	Returns 1 if the event was handled, meaning it should be removed from
+ *	the queue. Returns 0 if the event was not handled, meaning it should
+ *	stay on the queue. The only time the event isn't handled is if the
+ *	TCL_TIMER_EVENTS flag bit isn't set.
+ *
+ * Side effects:
+ *	Whatever the timer handler callback functions do.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+TimerHandlerEventProc(
+    Tcl_Event *evPtr,		/* Event to service. */
+    int flags)			/* Flags that indicate what events to handle,
+				 * such as TCL_FILE_EVENTS. */
+{
+    TimerHandler *timerHandlerPtr, **nextPtrPtr;
+    Tcl_Time time;
+    int currentTimerId;
+    ThreadSpecificData *tsdPtr = InitTimer();
+
+    /*
+     * Do nothing if timers aren't enabled. This leaves the event on the
+     * queue, so we will get to it as soon as ServiceEvents() is called with
+     * timers enabled.
+     */
+
+    if (!(flags & TCL_TIMER_EVENTS)) {
+	return 0;
+    }
+
+    /*
+     * The code below is trickier than it may look, for the following reasons:
+     *
+     * 1. New handlers can get added to the list while the current one is
+     *	  being processed. If new ones get added, we don't want to process
+     *	  them during this pass through the list to avoid starving other event
+     *	  sources. This is implemented using the token number in the handler:
+     *	  new handlers will have a newer token than any of the ones currently
+     *	  on the list.
+     * 2. The handler can call Tcl_DoOneEvent, so we have to remove the
+     *	  handler from the list before calling it. Otherwise an infinite loop
+     *	  could result.
+     * 3. Tcl_DeleteTimerHandler can be called to remove an element from the
+     *	  list while a handler is executing, so the list could change
+     *	  structure during the call.
+     * 4. Because we only fetch the current time before entering the loop, the
+     *	  only way a new timer will even be considered runnable is if its
+     *	  expiration time is within the same millisecond as the current time.
+     *	  This is fairly likely on Windows, since it has a course granularity
+     *	  clock. Since timers are placed on the queue in time order with the
+     *	  most recently created handler appearing after earlier ones with the
+     *	  same expiration time, we don't have to worry about newer generation
+     *	  timers appearing before later ones.
+     */
+
+    tsdPtr->timerPending = 0;
+    currentTimerId = tsdPtr->lastTimerId;
+    Tcl_GetTime(&time);
+    while (1) {
+	nextPtrPtr = &tsdPtr->firstTimerHandlerPtr;
+	timerHandlerPtr = tsdPtr->firstTimerHandlerPtr;
+	if (timerHandlerPtr == NULL) {
+	    break;
+	}
+
+	if (TCL_TIME_BEFORE(time, timerHandlerPtr->time)) {
+	    break;
+	}
+
+	/*
+	 * Bail out if the next timer is of a newer generation.
+	 */
+
+	if ((currentTimerId - PTR2INT(timerHandlerPtr->token)) < 0) {
+	    break;
+	}
+
+	/*
+	 * Remove the handler from the queue before invoking it, to avoid
+	 * potential reentrancy problems.
+	 */
+
+	*nextPtrPtr = timerHandlerPtr->nextPtr;
+	timerHandlerPtr->proc(timerHandlerPtr->clientData);
+	ckfree(timerHandlerPtr);
+    }
+    TimerSetupProc(NULL, TCL_TIMER_EVENTS);
+    return 1;
+}
+
+/*
+ *--------------------------------------------------------------
+ *
+ * Tcl_DoWhenIdle --
+ *
+ *	Arrange for proc to be invoked the next time the system is idle (i.e.,
+ *	just before the next time that Tcl_DoOneEvent would have to wait for
+ *	something to happen).
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Proc will eventually be called, with clientData as argument. See the
+ *	manual entry for details.
+ *
+ *--------------------------------------------------------------
+ */
+
+void
+Tcl_DoWhenIdle(
+    Tcl_IdleProc *proc,		/* Function to invoke. */
+    ClientData clientData)	/* Arbitrary value to pass to proc. */
+{
+    register IdleHandler *idlePtr;
+    Tcl_Time blockTime;
+    ThreadSpecificData *tsdPtr = InitTimer();
+
+    idlePtr = ckalloc(sizeof(IdleHandler));
+    idlePtr->proc = proc;
+    idlePtr->clientData = clientData;
+    idlePtr->generation = tsdPtr->idleGeneration;
+    idlePtr->nextPtr = NULL;
+    if (tsdPtr->lastIdlePtr == NULL) {
+	tsdPtr->idleList = idlePtr;
+    } else {
+	tsdPtr->lastIdlePtr->nextPtr = idlePtr;
+    }
+    tsdPtr->lastIdlePtr = idlePtr;
+
+    blockTime.sec = 0;
+    blockTime.usec = 0;
+    Tcl_SetMaxBlockTime(&blockTime);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_CancelIdleCall --
+ *
+ *	If there are any when-idle calls requested to a given function with
+ *	given clientData, cancel all of them.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	If the proc/clientData combination were on the when-idle list, they
+ *	are removed so that they will never be called.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_CancelIdleCall(
+    Tcl_IdleProc *proc,		/* Function that was previously registered. */
+    ClientData clientData)	/* Arbitrary value to pass to proc. */
+{
+    register IdleHandler *idlePtr, *prevPtr;
+    IdleHandler *nextPtr;
+    ThreadSpecificData *tsdPtr = InitTimer();
+
+    for (prevPtr = NULL, idlePtr = tsdPtr->idleList; idlePtr != NULL;
+	    prevPtr = idlePtr, idlePtr = idlePtr->nextPtr) {
+	while ((idlePtr->proc == proc)
+		&& (idlePtr->clientData == clientData)) {
+	    nextPtr = idlePtr->nextPtr;
+	    ckfree(idlePtr);
+	    idlePtr = nextPtr;
+	    if (prevPtr == NULL) {
+		tsdPtr->idleList = idlePtr;
+	    } else {
+		prevPtr->nextPtr = idlePtr;
+	    }
+	    if (idlePtr == NULL) {
+		tsdPtr->lastIdlePtr = prevPtr;
+		return;
+	    }
+	}
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclServiceIdle --
+ *
+ *	This function is invoked by the notifier when it becomes idle. It will
+ *	invoke all idle handlers that are present at the time the call is
+ *	invoked, but not those added during idle processing.
+ *
+ * Results:
+ *	The return value is 1 if TclServiceIdle found something to do,
+ *	otherwise return value is 0.
+ *
+ * Side effects:
+ *	Invokes all pending idle handlers.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclServiceIdle(void)
+{
+    IdleHandler *idlePtr;
+    int oldGeneration;
+    Tcl_Time blockTime;
+    ThreadSpecificData *tsdPtr = InitTimer();
+
+    if (tsdPtr->idleList == NULL) {
+	return 0;
+    }
+
+    oldGeneration = tsdPtr->idleGeneration;
+    tsdPtr->idleGeneration++;
+
+    /*
+     * The code below is trickier than it may look, for the following reasons:
+     *
+     * 1. New handlers can get added to the list while the current one is
+     *	  being processed. If new ones get added, we don't want to process
+     *	  them during this pass through the list (want to check for other work
+     *	  to do first). This is implemented using the generation number in the
+     *	  handler: new handlers will have a different generation than any of
+     *	  the ones currently on the list.
+     * 2. The handler can call Tcl_DoOneEvent, so we have to remove the
+     *	  handler from the list before calling it. Otherwise an infinite loop
+     *	  could result.
+     * 3. Tcl_CancelIdleCall can be called to remove an element from the list
+     *	  while a handler is executing, so the list could change structure
+     *	  during the call.
+     */
+
+    for (idlePtr = tsdPtr->idleList;
+	    ((idlePtr != NULL)
+		    && ((oldGeneration - idlePtr->generation) >= 0));
+	    idlePtr = tsdPtr->idleList) {
+	tsdPtr->idleList = idlePtr->nextPtr;
+	if (tsdPtr->idleList == NULL) {
+	    tsdPtr->lastIdlePtr = NULL;
+	}
+	idlePtr->proc(idlePtr->clientData);
+	ckfree(idlePtr);
+    }
+    if (tsdPtr->idleList) {
+	blockTime.sec = 0;
+	blockTime.usec = 0;
+	Tcl_SetMaxBlockTime(&blockTime);
+    }
+    return 1;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_AfterObjCmd --
+ *
+ *	This function is invoked to process the "after" Tcl command. See the
+ *	user documentation for details on what it does.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+	/* ARGSUSED */
+int
+Tcl_AfterObjCmd(
+    ClientData clientData,	/* Unused */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    Tcl_WideInt ms = 0;		/* Number of milliseconds to wait */
+    Tcl_Time wakeup;
+    AfterInfo *afterPtr;
+    AfterAssocData *assocPtr;
+    int length;
+    int index;
+    static const char *const afterSubCmds[] = {
+	"cancel", "idle", "info", NULL
+    };
+    enum afterSubCmds {AFTER_CANCEL, AFTER_IDLE, AFTER_INFO};
+    ThreadSpecificData *tsdPtr = InitTimer();
+
+    if (objc < 2) {
+	Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?");
+	return TCL_ERROR;
+    }
+
+    /*
+     * Create the "after" information associated for this interpreter, if it
+     * doesn't already exist.
+     */
+
+    assocPtr = Tcl_GetAssocData(interp, "tclAfter", NULL);
+    if (assocPtr == NULL) {
+	assocPtr = ckalloc(sizeof(AfterAssocData));
+	assocPtr->interp = interp;
+	assocPtr->firstAfterPtr = NULL;
+	Tcl_SetAssocData(interp, "tclAfter", AfterCleanupProc, assocPtr);
+    }
+
+    /*
+     * First lets see if the command was passed a number as the first argument.
+     */
+
+    if (objv[1]->typePtr == &tclIntType
+#ifndef TCL_WIDE_INT_IS_LONG
+	    || objv[1]->typePtr == &tclWideIntType
+#endif
+	    || objv[1]->typePtr == &tclBignumType
+	    || (Tcl_GetIndexFromObj(NULL, objv[1], afterSubCmds, "", 0,
+		    &index) != TCL_OK)) {
+	index = -1;
+	if (Tcl_GetWideIntFromObj(NULL, objv[1], &ms) != TCL_OK) {
+            const char *arg = Tcl_GetString(objv[1]);
+
+	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+                    "bad argument \"%s\": must be"
+                    " cancel, idle, info, or an integer", arg));
+            Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "INDEX", "argument",
+                    arg, NULL);
+	    return TCL_ERROR;
+	}
+    }
+
+    /*
+     * At this point, either index = -1 and ms contains the number of ms
+     * to wait, or else index is the index of a subcommand.
+     */
+
+    switch (index) {
+    case -1: {
+	if (ms < 0) {
+	    ms = 0;
+	}
+	if (objc == 2) {
+	    return AfterDelay(interp, ms);
+	}
+	afterPtr = ckalloc(sizeof(AfterInfo));
+	afterPtr->assocPtr = assocPtr;
+	if (objc == 3) {
+	    afterPtr->commandPtr = objv[2];
+	} else {
+	    afterPtr->commandPtr = Tcl_ConcatObj(objc-2, objv+2);
+	}
+	Tcl_IncrRefCount(afterPtr->commandPtr);
+
+	/*
+	 * The variable below is used to generate unique identifiers for after
+	 * commands. This id can wrap around, which can potentially cause
+	 * problems. However, there are not likely to be problems in practice,
+	 * because after commands can only be requested to about a month in
+	 * the future, and wrap-around is unlikely to occur in less than about
+	 * 1-10 years. Thus it's unlikely that any old ids will still be
+	 * around when wrap-around occurs.
+	 */
+
+	afterPtr->id = tsdPtr->afterId;
+	tsdPtr->afterId += 1;
+	Tcl_GetTime(&wakeup);
+	wakeup.sec += (long)(ms / 1000);
+	wakeup.usec += ((long)(ms % 1000)) * 1000;
+	if (wakeup.usec > 1000000) {
+	    wakeup.sec++;
+	    wakeup.usec -= 1000000;
+	}
+	afterPtr->token = TclCreateAbsoluteTimerHandler(&wakeup,
+		AfterProc, afterPtr);
+	afterPtr->nextPtr = assocPtr->firstAfterPtr;
+	assocPtr->firstAfterPtr = afterPtr;
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf("after#%d", afterPtr->id));
+	return TCL_OK;
+    }
+    case AFTER_CANCEL: {
+	Tcl_Obj *commandPtr;
+	const char *command, *tempCommand;
+	int tempLength;
+
+	if (objc < 3) {
+	    Tcl_WrongNumArgs(interp, 2, objv, "id|command");
+	    return TCL_ERROR;
+	}
+	if (objc == 3) {
+	    commandPtr = objv[2];
+	} else {
+	    commandPtr = Tcl_ConcatObj(objc-2, objv+2);;
+	}
+	command = Tcl_GetStringFromObj(commandPtr, &length);
+	for (afterPtr = assocPtr->firstAfterPtr;  afterPtr != NULL;
+		afterPtr = afterPtr->nextPtr) {
+	    tempCommand = Tcl_GetStringFromObj(afterPtr->commandPtr,
+		    &tempLength);
+	    if ((length == tempLength)
+		    && !memcmp(command, tempCommand, (unsigned) length)) {
+		break;
+	    }
+	}
+	if (afterPtr == NULL) {
+	    afterPtr = GetAfterEvent(assocPtr, commandPtr);
+	}
+	if (objc != 3) {
+	    Tcl_DecrRefCount(commandPtr);
+	}
+	if (afterPtr != NULL) {
+	    if (afterPtr->token != NULL) {
+		Tcl_DeleteTimerHandler(afterPtr->token);
+	    } else {
+		Tcl_CancelIdleCall(AfterProc, afterPtr);
+	    }
+	    FreeAfterPtr(afterPtr);
+	}
+	break;
+    }
+    case AFTER_IDLE:
+	if (objc < 3) {
+	    Tcl_WrongNumArgs(interp, 2, objv, "script ?script ...?");
+	    return TCL_ERROR;
+	}
+	afterPtr = ckalloc(sizeof(AfterInfo));
+	afterPtr->assocPtr = assocPtr;
+	if (objc == 3) {
+	    afterPtr->commandPtr = objv[2];
+	} else {
+	    afterPtr->commandPtr = Tcl_ConcatObj(objc-2, objv+2);
+	}
+	Tcl_IncrRefCount(afterPtr->commandPtr);
+	afterPtr->id = tsdPtr->afterId;
+	tsdPtr->afterId += 1;
+	afterPtr->token = NULL;
+	afterPtr->nextPtr = assocPtr->firstAfterPtr;
+	assocPtr->firstAfterPtr = afterPtr;
+	Tcl_DoWhenIdle(AfterProc, afterPtr);
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf("after#%d", afterPtr->id));
+	break;
+    case AFTER_INFO:
+	if (objc == 2) {
+            Tcl_Obj *resultObj = Tcl_NewObj();
+
+	    for (afterPtr = assocPtr->firstAfterPtr; afterPtr != NULL;
+		    afterPtr = afterPtr->nextPtr) {
+		if (assocPtr->interp == interp) {
+                    Tcl_ListObjAppendElement(NULL, resultObj, Tcl_ObjPrintf(
+                            "after#%d", afterPtr->id));
+		}
+	    }
+            Tcl_SetObjResult(interp, resultObj);
+	    return TCL_OK;
+	}
+	if (objc != 3) {
+	    Tcl_WrongNumArgs(interp, 2, objv, "?id?");
+	    return TCL_ERROR;
+	}
+	afterPtr = GetAfterEvent(assocPtr, objv[2]);
+	if (afterPtr == NULL) {
+            const char *eventStr = TclGetString(objv[2]);
+
+	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+                    "event \"%s\" doesn't exist", eventStr));
+            Tcl_SetErrorCode(interp, "TCL","LOOKUP","EVENT", eventStr, NULL);
+	    return TCL_ERROR;
+	} else {
+            Tcl_Obj *resultListPtr = Tcl_NewObj();
+
+            Tcl_ListObjAppendElement(interp, resultListPtr,
+                    afterPtr->commandPtr);
+            Tcl_ListObjAppendElement(interp, resultListPtr, Tcl_NewStringObj(
+		    (afterPtr->token == NULL) ? "idle" : "timer", -1));
+            Tcl_SetObjResult(interp, resultListPtr);
+        }
+	break;
+    default:
+	Tcl_Panic("Tcl_AfterObjCmd: bad subcommand index to afterSubCmds");
+    }
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * AfterDelay --
+ *
+ *	Implements the blocking delay behaviour of [after $time]. Tricky
+ *	because it has to take into account any time limit that has been set.
+ *
+ * Results:
+ *	Standard Tcl result code (with error set if an error occurred due to a
+ *	time limit being exceeded or being canceled).
+ *
+ * Side effects:
+ *	May adjust the time limit granularity marker.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+AfterDelay(
+    Tcl_Interp *interp,
+    Tcl_WideInt ms)
+{
+    Interp *iPtr = (Interp *) interp;
+
+    Tcl_Time endTime, now;
+    Tcl_WideInt diff;
+
+    Tcl_GetTime(&now);
+    endTime = now;
+    endTime.sec += (long)(ms/1000);
+    endTime.usec += ((int)(ms%1000))*1000;
+    if (endTime.usec >= 1000000) {
+	endTime.sec++;
+	endTime.usec -= 1000000;
+    }
+
+    do {
+	if (Tcl_AsyncReady()) {
+	    if (Tcl_AsyncInvoke(interp, TCL_OK) != TCL_OK) {
+		return TCL_ERROR;
+	    }
+	}
+	if (Tcl_Canceled(interp, TCL_LEAVE_ERR_MSG) == TCL_ERROR) {
+	    return TCL_ERROR;
+	}
+	if (iPtr->limit.timeEvent != NULL
+		&& TCL_TIME_BEFORE(iPtr->limit.time, now)) {
+	    iPtr->limit.granularityTicker = 0;
+	    if (Tcl_LimitCheck(interp) != TCL_OK) {
+		return TCL_ERROR;
+	    }
+	}
+	if (iPtr->limit.timeEvent == NULL
+		|| TCL_TIME_BEFORE(endTime, iPtr->limit.time)) {
+	    diff = TCL_TIME_DIFF_MS_CEILING(endTime, now);
+#ifndef TCL_WIDE_INT_IS_LONG
+	    if (diff > LONG_MAX) {
+		diff = LONG_MAX;
+	    }
+#endif
+	    if (diff > TCL_TIME_MAXIMUM_SLICE) {
+		diff = TCL_TIME_MAXIMUM_SLICE;
+	    }
+            if (diff == 0 && TCL_TIME_BEFORE(now, endTime)) diff = 1;
+	    if (diff > 0) {
+		Tcl_Sleep((long) diff);
+                if (diff < SLEEP_OFFLOAD_GETTIMEOFDAY) break;
+	    } else break;
+	} else {
+	    diff = TCL_TIME_DIFF_MS(iPtr->limit.time, now);
+#ifndef TCL_WIDE_INT_IS_LONG
+	    if (diff > LONG_MAX) {
+		diff = LONG_MAX;
+	    }
+#endif
+	    if (diff > TCL_TIME_MAXIMUM_SLICE) {
+		diff = TCL_TIME_MAXIMUM_SLICE;
+	    }
+	    if (diff > 0) {
+		Tcl_Sleep((long) diff);
+	    }
+	    if (Tcl_AsyncReady()) {
+		if (Tcl_AsyncInvoke(interp, TCL_OK) != TCL_OK) {
+		    return TCL_ERROR;
+		}
+	    }
+	    if (Tcl_Canceled(interp, TCL_LEAVE_ERR_MSG) == TCL_ERROR) {
+		return TCL_ERROR;
+	    }
+	    if (Tcl_LimitCheck(interp) != TCL_OK) {
+		return TCL_ERROR;
+	    }
+	}
+        Tcl_GetTime(&now);
+    } while (TCL_TIME_BEFORE(now, endTime));
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * GetAfterEvent --
+ *
+ *	This function parses an "after" id such as "after#4" and returns a
+ *	pointer to the AfterInfo structure.
+ *
+ * Results:
+ *	The return value is either a pointer to an AfterInfo structure, if one
+ *	is found that corresponds to "cmdString" and is for interp, or NULL if
+ *	no corresponding after event can be found.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static AfterInfo *
+GetAfterEvent(
+    AfterAssocData *assocPtr,	/* Points to "after"-related information for
+				 * this interpreter. */
+    Tcl_Obj *commandPtr)
+{
+    const char *cmdString;	/* Textual identifier for after event, such as
+				 * "after#6". */
+    AfterInfo *afterPtr;
+    int id;
+    char *end;
+
+    cmdString = TclGetString(commandPtr);
+    if (strncmp(cmdString, "after#", 6) != 0) {
+	return NULL;
+    }
+    cmdString += 6;
+    id = strtoul(cmdString, &end, 10);
+    if ((end == cmdString) || (*end != 0)) {
+	return NULL;
+    }
+    for (afterPtr = assocPtr->firstAfterPtr; afterPtr != NULL;
+	    afterPtr = afterPtr->nextPtr) {
+	if (afterPtr->id == id) {
+	    return afterPtr;
+	}
+    }
+    return NULL;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * AfterProc --
+ *
+ *	Timer callback to execute commands registered with the "after"
+ *	command.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Executes whatever command was specified. If the command returns an
+ *	error, then the command "bgerror" is invoked to process the error; if
+ *	bgerror fails then information about the error is output on stderr.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+AfterProc(
+    ClientData clientData)	/* Describes command to execute. */
+{
+    AfterInfo *afterPtr = clientData;
+    AfterAssocData *assocPtr = afterPtr->assocPtr;
+    AfterInfo *prevPtr;
+    int result;
+    Tcl_Interp *interp;
+
+    /*
+     * First remove the callback from our list of callbacks; otherwise someone
+     * could delete the callback while it's being executed, which could cause
+     * a core dump.
+     */
+
+    if (assocPtr->firstAfterPtr == afterPtr) {
+	assocPtr->firstAfterPtr = afterPtr->nextPtr;
+    } else {
+	for (prevPtr = assocPtr->firstAfterPtr; prevPtr->nextPtr != afterPtr;
+		prevPtr = prevPtr->nextPtr) {
+	    /* Empty loop body. */
+	}
+	prevPtr->nextPtr = afterPtr->nextPtr;
+    }
+
+    /*
+     * Execute the callback.
+     */
+
+    interp = assocPtr->interp;
+    Tcl_Preserve(interp);
+    result = Tcl_EvalObjEx(interp, afterPtr->commandPtr, TCL_EVAL_GLOBAL);
+    if (result != TCL_OK) {
+	Tcl_AddErrorInfo(interp, "\n    (\"after\" script)");
+	Tcl_BackgroundException(interp, result);
+    }
+    Tcl_Release(interp);
+
+    /*
+     * Free the memory for the callback.
+     */
+
+    Tcl_DecrRefCount(afterPtr->commandPtr);
+    ckfree(afterPtr);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * FreeAfterPtr --
+ *
+ *	This function removes an "after" command from the list of those that
+ *	are pending and frees its resources. This function does *not* cancel
+ *	the timer handler; if that's needed, the caller must do it.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The memory associated with afterPtr is released.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+FreeAfterPtr(
+    AfterInfo *afterPtr)		/* Command to be deleted. */
+{
+    AfterInfo *prevPtr;
+    AfterAssocData *assocPtr = afterPtr->assocPtr;
+
+    if (assocPtr->firstAfterPtr == afterPtr) {
+	assocPtr->firstAfterPtr = afterPtr->nextPtr;
+    } else {
+	for (prevPtr = assocPtr->firstAfterPtr; prevPtr->nextPtr != afterPtr;
+		prevPtr = prevPtr->nextPtr) {
+	    /* Empty loop body. */
+	}
+	prevPtr->nextPtr = afterPtr->nextPtr;
+    }
+    Tcl_DecrRefCount(afterPtr->commandPtr);
+    ckfree(afterPtr);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * AfterCleanupProc --
+ *
+ *	This function is invoked whenever an interpreter is deleted
+ *	to cleanup the AssocData for "tclAfter".
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	After commands are removed.
+ *
+ *----------------------------------------------------------------------
+ */
+
+	/* ARGSUSED */
+static void
+AfterCleanupProc(
+    ClientData clientData,	/* Points to AfterAssocData for the
+				 * interpreter. */
+    Tcl_Interp *interp)		/* Interpreter that is being deleted. */
+{
+    AfterAssocData *assocPtr = clientData;
+    AfterInfo *afterPtr;
+
+    while (assocPtr->firstAfterPtr != NULL) {
+	afterPtr = assocPtr->firstAfterPtr;
+	assocPtr->firstAfterPtr = afterPtr->nextPtr;
+	if (afterPtr->token != NULL) {
+	    Tcl_DeleteTimerHandler(afterPtr->token);
+	} else {
+	    Tcl_CancelIdleCall(AfterProc, afterPtr);
+	}
+	Tcl_DecrRefCount(afterPtr->commandPtr);
+	ckfree(afterPtr);
+    }
+    ckfree(assocPtr);
+}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/generic/tclTomMath.decls b/generic/tclTomMath.decls
new file mode 100644
index 0000000..610a031
--- /dev/null
+++ b/generic/tclTomMath.decls
@@ -0,0 +1,238 @@
+# tclTomMath.decls --
+#
+#	This file contains the declarations for the functions in 'libtommath'
+#	that are contained within the Tcl library.  This file is used to
+#	generate the 'tclTomMathDecls.h' and 'tclStubInit.c' files.
+#
+# If you edit this file, advance the revision number (and the epoch
+# if the new stubs are not backward compatible) in tclTomMathDecls.h
+#
+# Copyright (c) 2005 by Kevin B. Kenny.  All rights reserved.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+library tcl
+
+# Define the unsupported generic interfaces.
+
+interface tclTomMath
+# hooks {tclTomMathInt}
+scspec EXTERN
+
+# Declare each of the functions in the Tcl tommath interface
+
+declare 0 {
+    int TclBN_epoch(void)
+}
+declare 1 {
+    int TclBN_revision(void)
+}
+
+declare 2 {
+    int TclBN_mp_add(mp_int *a, mp_int *b, mp_int *c)
+}
+declare 3 {
+    int TclBN_mp_add_d(mp_int *a, mp_digit b, mp_int *c)
+}
+declare 4 {
+    int TclBN_mp_and(mp_int *a, mp_int *b, mp_int *c)
+}
+declare 5 {
+    void TclBN_mp_clamp(mp_int *a)
+}
+declare 6 {
+    void TclBN_mp_clear(mp_int *a)
+}
+declare 7 {
+    void TclBN_mp_clear_multi(mp_int *a, ...)
+}
+declare 8 {
+    int TclBN_mp_cmp(const mp_int *a, const mp_int *b)
+}
+declare 9 {
+    int TclBN_mp_cmp_d(const mp_int *a, mp_digit b)
+}
+declare 10 {
+    int TclBN_mp_cmp_mag(const mp_int *a, const mp_int *b)
+}
+declare 11 {
+    int TclBN_mp_copy(const mp_int *a, mp_int *b)
+}
+declare 12 {
+    int TclBN_mp_count_bits(const mp_int *a)
+}
+declare 13 {
+    int TclBN_mp_div(mp_int *a, mp_int *b, mp_int *q, mp_int *r)
+}
+declare 14 {
+    int TclBN_mp_div_d(mp_int *a, mp_digit b, mp_int *q, mp_digit *r)
+}
+declare 15 {
+    int TclBN_mp_div_2(mp_int *a, mp_int *q)
+}
+declare 16 {
+    int TclBN_mp_div_2d(const mp_int *a, int b, mp_int *q, mp_int *r)
+}
+declare 17 {
+    int TclBN_mp_div_3(mp_int *a, mp_int *q, mp_digit *r)
+}
+declare 18 {
+    void TclBN_mp_exch(mp_int *a, mp_int *b)
+}
+declare 19 {
+    int TclBN_mp_expt_d(mp_int *a, mp_digit b, mp_int *c)
+}
+declare 20 {
+    int TclBN_mp_grow(mp_int *a, int size)
+}
+declare 21 {
+    int TclBN_mp_init(mp_int *a)
+}
+declare 22 {
+    int TclBN_mp_init_copy(mp_int *a, mp_int *b)
+}
+declare 23 {
+    int TclBN_mp_init_multi(mp_int *a, ...)
+}
+declare 24 {
+    int TclBN_mp_init_set(mp_int *a, mp_digit b)
+}
+declare 25 {
+    int TclBN_mp_init_size(mp_int *a, int size)
+}
+declare 26 {
+    int TclBN_mp_lshd(mp_int *a, int shift)
+}
+declare 27 {
+    int TclBN_mp_mod(mp_int *a, mp_int *b, mp_int *r)
+}
+declare 28 {
+    int TclBN_mp_mod_2d(const mp_int *a, int b, mp_int *r)
+}
+declare 29 {
+    int TclBN_mp_mul(mp_int *a, mp_int *b, mp_int *p)
+}
+declare 30 {
+    int TclBN_mp_mul_d(mp_int *a, mp_digit b, mp_int *p)
+}
+declare 31 {
+    int TclBN_mp_mul_2(mp_int *a, mp_int *p)
+}
+declare 32 {
+    int TclBN_mp_mul_2d(const mp_int *a, int d, mp_int *p)
+}
+declare 33 {
+    int TclBN_mp_neg(const mp_int *a, mp_int *b)
+}
+declare 34 {
+    int TclBN_mp_or(mp_int *a, mp_int *b, mp_int *c)
+}
+declare 35 {
+    int TclBN_mp_radix_size(mp_int *a, int radix, int *size)
+}
+declare 36 {
+    int TclBN_mp_read_radix(mp_int *a, const char *str, int radix)
+}
+declare 37 {
+    void TclBN_mp_rshd(mp_int *a, int shift)
+}
+declare 38 {
+    int TclBN_mp_shrink(mp_int *a)
+}
+declare 39 {
+    void TclBN_mp_set(mp_int *a, mp_digit b)
+}
+declare 40 {
+    int TclBN_mp_sqr(mp_int *a, mp_int *b)
+}
+declare 41 {
+    int TclBN_mp_sqrt(mp_int *a, mp_int *b)
+}
+declare 42 {
+    int TclBN_mp_sub(mp_int *a, mp_int *b, mp_int *c)
+}
+declare 43 {
+    int TclBN_mp_sub_d(mp_int *a, mp_digit b, mp_int *c)
+}
+declare 44 {
+    int TclBN_mp_to_unsigned_bin(mp_int *a, unsigned char *b)
+}
+declare 45 {
+    int TclBN_mp_to_unsigned_bin_n(mp_int *a, unsigned char *b,
+	    unsigned long *outlen)
+}
+declare 46 {
+    int TclBN_mp_toradix_n(mp_int *a, char *str, int radix, int maxlen)
+}
+declare 47 {
+    int TclBN_mp_unsigned_bin_size(mp_int *a)
+}
+declare 48 {
+    int TclBN_mp_xor(mp_int *a, mp_int *b, mp_int *c)
+}
+declare 49 {
+    void TclBN_mp_zero(mp_int *a)
+}
+
+# internal routines to libtommath - should not be called but must be
+# exported to accommodate the "tommath" extension
+
+declare 50 {
+    void TclBN_reverse(unsigned char *s, int len)
+}
+declare 51 {
+    int TclBN_fast_s_mp_mul_digs(mp_int *a, mp_int *b, mp_int *c, int digs)
+}
+declare 52 {
+    int TclBN_fast_s_mp_sqr(mp_int *a, mp_int *b)
+}
+declare 53 {
+    int TclBN_mp_karatsuba_mul(mp_int *a, mp_int *b, mp_int *c)
+}
+declare 54 {
+    int TclBN_mp_karatsuba_sqr(mp_int *a, mp_int *b)
+}
+declare 55 {
+    int TclBN_mp_toom_mul(mp_int *a, mp_int *b, mp_int *c)
+}
+declare 56 {
+    int TclBN_mp_toom_sqr(mp_int *a, mp_int *b)
+}
+declare 57 {
+    int TclBN_s_mp_add(mp_int *a, mp_int *b, mp_int *c)
+}
+declare 58 {
+    int TclBN_s_mp_mul_digs(mp_int *a, mp_int *b, mp_int *c, int digs)
+}
+declare 59 {
+    int TclBN_s_mp_sqr(mp_int *a, mp_int *b)
+}
+declare 60 {
+    int TclBN_s_mp_sub(mp_int *a, mp_int *b, mp_int *c)
+}
+declare 61 {
+    int TclBN_mp_init_set_int(mp_int *a, unsigned long i)
+}
+declare 62 {
+    int TclBN_mp_set_int(mp_int *a, unsigned long i)
+}
+declare 63 {
+    int TclBN_mp_cnt_lsb(const mp_int *a)
+}
+
+# Formerly internal API to allow initialisation of bignums without knowing the
+# typedefs of how a bignum works internally.
+declare 64 {
+    void TclBNInitBignumFromLong(mp_int *bignum, long initVal)
+}
+declare 65 {
+    void TclBNInitBignumFromWideInt(mp_int *bignum, Tcl_WideInt initVal)
+}
+declare 66 {
+    void TclBNInitBignumFromWideUInt(mp_int *bignum, Tcl_WideUInt initVal)
+}
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/generic/tclTomMath.h b/generic/tclTomMath.h
new file mode 100644
index 0000000..dd9edaf
--- /dev/null
+++ b/generic/tclTomMath.h
@@ -0,0 +1,832 @@
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+#ifndef BN_H_
+#define BN_H_
+
+#include "tclTomMathDecls.h"
+#ifndef MODULE_SCOPE
+#define MODULE_SCOPE extern
+#endif
+
+
+
+#ifndef MIN
+#   define MIN(x,y) ((x)<(y)?(x):(y))
+#endif
+
+#ifndef MAX
+#   define MAX(x,y) ((x)>(y)?(x):(y))
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+
+/* C++ compilers don't like assigning void * to mp_digit * */
+#define  OPT_CAST(x)  (x *)
+
+#else
+
+/* C on the other hand doesn't care */
+#define  OPT_CAST(x)
+
+#endif
+
+
+/* detect 64-bit mode if possible */
+#if defined(NEVER)  /* 128-bit ints fail in too many places */
+#   if !(defined(MP_64BIT) && defined(MP_16BIT) && defined(MP_8BIT))
+#	define MP_64BIT
+#   endif
+#endif
+
+/* some default configurations.
+ *
+ * A "mp_digit" must be able to hold DIGIT_BIT + 1 bits
+ * A "mp_word" must be able to hold 2*DIGIT_BIT + 1 bits
+ *
+ * At the very least a mp_digit must be able to hold 7 bits
+ * [any size beyond that is ok provided it doesn't overflow the data type]
+ */
+#ifdef MP_8BIT
+#ifndef MP_DIGIT_DECLARED
+   typedef unsigned char      mp_digit;
+#define MP_DIGIT_DECLARED
+#endif
+   typedef unsigned short     mp_word;
+#elif defined(MP_16BIT)
+#ifndef MP_DIGIT_DECLARED
+   typedef unsigned short     mp_digit;
+#define MP_DIGIT_DECLARED
+#endif
+   typedef unsigned long      mp_word;
+#elif defined(MP_64BIT)
+   /* for GCC only on supported platforms */
+#ifndef CRYPT
+   typedef unsigned long long ulong64;
+   typedef signed long long   long64;
+#endif
+
+#ifndef MP_DIGIT_DECLARED
+   typedef unsigned long      mp_digit;
+#define MP_DIGIT_DECLARED
+#endif
+   typedef unsigned long      mp_word __attribute__ ((mode(TI)));
+
+#  define DIGIT_BIT          60
+#else
+   /* this is the default case, 28-bit digits */
+   
+   /* this is to make porting into LibTomCrypt easier :-) */
+#ifndef CRYPT
+#  if defined(_MSC_VER) || defined(__BORLANDC__)
+      typedef unsigned __int64   ulong64;
+      typedef signed __int64     long64;
+#  else
+      typedef unsigned long long ulong64;
+      typedef signed long long   long64;
+#  endif
+#endif
+
+#ifndef MP_DIGIT_DECLARED
+   typedef unsigned int      mp_digit;
+#define MP_DIGIT_DECLARED
+#endif
+   typedef ulong64            mp_word;
+
+#ifdef MP_31BIT   
+   /* this is an extension that uses 31-bit digits */
+#  define DIGIT_BIT          31
+#else
+   /* default case is 28-bit digits, defines MP_28BIT as a handy macro to test */
+#  define DIGIT_BIT          28
+#  define MP_28BIT
+#endif   
+#endif
+
+/* define heap macros */
+#if 0 /* these are macros in tclTomMathDecls.h */
+#ifndef CRYPT
+   /* default to libc stuff */
+#  ifndef XMALLOC
+#     define XMALLOC  malloc
+#     define XFREE    free
+#     define XREALLOC realloc
+#     define XCALLOC  calloc
+#  else
+      /* prototypes for our heap functions */
+      extern void *XMALLOC(size_t n);
+      extern void *XREALLOC(void *p, size_t n);
+      extern void *XCALLOC(size_t n, size_t s);
+      extern void XFREE(void *p);
+#  endif
+#endif
+#endif
+
+
+/* otherwise the bits per digit is calculated automatically from the size of a mp_digit */
+#ifndef DIGIT_BIT
+#   define DIGIT_BIT     ((int)((CHAR_BIT * sizeof(mp_digit) - 1)))  /* bits per digit */
+#endif
+
+#define MP_DIGIT_BIT     DIGIT_BIT
+#define MP_MASK          ((((mp_digit)1)<<((mp_digit)DIGIT_BIT))-((mp_digit)1))
+#define MP_DIGIT_MAX     MP_MASK
+
+/* equalities */
+#define MP_LT        -1   /* less than */
+#define MP_EQ         0   /* equal to */
+#define MP_GT         1   /* greater than */
+
+#define MP_ZPOS       0   /* positive integer */
+#define MP_NEG        1   /* negative */
+
+#define MP_OKAY       0   /* ok result */
+#define MP_MEM        -2  /* out of mem */
+#define MP_VAL        -3  /* invalid input */
+#define MP_RANGE      MP_VAL
+
+#define MP_YES        1   /* yes response */
+#define MP_NO         0   /* no response */
+
+/* Primality generation flags */
+#define LTM_PRIME_BBS      0x0001 /* BBS style prime */
+#define LTM_PRIME_SAFE     0x0002 /* Safe prime (p-1)/2 == prime */
+#define LTM_PRIME_2MSB_ON  0x0008 /* force 2nd MSB to 1 */
+
+typedef int           mp_err;
+
+/* you'll have to tune these... */
+#if defined(BUILD_tcl) || !defined(_WIN32)
+MODULE_SCOPE int KARATSUBA_MUL_CUTOFF,
+           KARATSUBA_SQR_CUTOFF,
+           TOOM_MUL_CUTOFF,
+           TOOM_SQR_CUTOFF;
+#endif
+
+/* define this to use lower memory usage routines (exptmods mostly) */
+/* #define MP_LOW_MEM */
+
+/* default precision */
+#ifndef MP_PREC
+#  ifndef MP_LOW_MEM
+#     define MP_PREC                 32     /* default digits of precision */
+#  else
+#     define MP_PREC                 8      /* default digits of precision */
+#  endif
+#endif
+
+/* size of comba arrays, should be at least 2 * 2**(BITS_PER_WORD - BITS_PER_DIGIT*2) */
+#define MP_WARRAY               (1 << (sizeof(mp_word) * CHAR_BIT - 2 * DIGIT_BIT + 1))
+
+/* the infamous mp_int structure */
+#ifndef MP_INT_DECLARED
+#define MP_INT_DECLARED
+typedef struct mp_int mp_int;
+#endif
+struct mp_int {
+    int used, alloc, sign;
+    mp_digit *dp;
+};
+
+/* callback for mp_prime_random, should fill dst with random bytes and return how many read [upto len] */
+typedef int ltm_prime_callback(unsigned char *dst, int len, void *dat);
+
+
+#define USED(m)    ((m)->used)
+#define DIGIT(m,k) ((m)->dp[(k)])
+#define SIGN(m)    ((m)->sign)
+
+/* error code to char* string */
+/*
+char *mp_error_to_string(int code);
+*/
+
+/* ---> init and deinit bignum functions <--- */
+/* init a bignum */
+/*
+int mp_init(mp_int *a);
+*/
+
+/* free a bignum */
+/*
+void mp_clear(mp_int *a);
+*/
+
+/* init a null terminated series of arguments */
+/*
+int mp_init_multi(mp_int *mp, ...);
+*/
+
+/* clear a null terminated series of arguments */
+/*
+void mp_clear_multi(mp_int *mp, ...);
+*/
+
+/* exchange two ints */
+/*
+void mp_exch(mp_int *a, mp_int *b);
+*/
+
+/* shrink ram required for a bignum */
+/*
+int mp_shrink(mp_int *a);
+*/
+
+/* grow an int to a given size */
+/*
+int mp_grow(mp_int *a, int size);
+*/
+
+/* init to a given number of digits */
+/*
+int mp_init_size(mp_int *a, int size);
+*/
+
+/* ---> Basic Manipulations <--- */
+#define mp_iszero(a) (((a)->used == 0) ? MP_YES : MP_NO)
+#define mp_iseven(a) (((a)->used == 0 || (((a)->dp[0] & 1) == 0)) ? MP_YES : MP_NO)
+#define mp_isodd(a)  (((a)->used > 0 && (((a)->dp[0] & 1) == 1)) ? MP_YES : MP_NO)
+
+/* set to zero */
+/*
+void mp_zero(mp_int *a);
+*/
+
+/* set to a digit */
+/*
+void mp_set(mp_int *a, mp_digit b);
+*/
+
+/* set a 32-bit const */
+/*
+int mp_set_int(mp_int *a, unsigned long b);
+*/
+
+/* get a 32-bit value */
+unsigned long mp_get_int(mp_int * a);
+
+/* initialize and set a digit */
+/*
+int mp_init_set (mp_int * a, mp_digit b);
+*/
+
+/* initialize and set 32-bit value */
+/*
+int mp_init_set_int (mp_int * a, unsigned long b);
+*/
+
+/* copy, b = a */
+/*
+int mp_copy(const mp_int *a, mp_int *b);
+*/
+
+/* inits and copies, a = b */
+/*
+int mp_init_copy(mp_int *a, mp_int *b);
+*/
+
+/* trim unused digits */
+/*
+void mp_clamp(mp_int *a);
+*/
+
+/* ---> digit manipulation <--- */
+
+/* right shift by "b" digits */
+/*
+void mp_rshd(mp_int *a, int b);
+*/
+
+/* left shift by "b" digits */
+/*
+int mp_lshd(mp_int *a, int b);
+*/
+
+/* c = a / 2**b */
+/*
+int mp_div_2d(const mp_int *a, int b, mp_int *c, mp_int *d);
+*/
+
+/* b = a/2 */
+/*
+int mp_div_2(mp_int *a, mp_int *b);
+*/
+
+/* c = a * 2**b */
+/*
+int mp_mul_2d(const mp_int *a, int b, mp_int *c);
+*/
+
+/* b = a*2 */
+/*
+int mp_mul_2(mp_int *a, mp_int *b);
+*/
+
+/* c = a mod 2**d */
+/*
+int mp_mod_2d(const mp_int *a, int b, mp_int *c);
+*/
+
+/* computes a = 2**b */
+/*
+int mp_2expt(mp_int *a, int b);
+*/
+
+/* Counts the number of lsbs which are zero before the first zero bit */
+/*
+int mp_cnt_lsb(mp_int *a);
+*/
+
+/* I Love Earth! */
+
+/* makes a pseudo-random int of a given size */
+/*
+int mp_rand(mp_int *a, int digits);
+*/
+
+/* ---> binary operations <--- */
+/* c = a XOR b  */
+/*
+int mp_xor(mp_int *a, mp_int *b, mp_int *c);
+*/
+
+/* c = a OR b */
+/*
+int mp_or(mp_int *a, mp_int *b, mp_int *c);
+*/
+
+/* c = a AND b */
+/*
+int mp_and(mp_int *a, mp_int *b, mp_int *c);
+*/
+
+/* ---> Basic arithmetic <--- */
+
+/* b = -a */
+/*
+int mp_neg(const mp_int *a, mp_int *b);
+*/
+
+/* b = |a| */
+/*
+int mp_abs(mp_int *a, mp_int *b);
+*/
+
+/* compare a to b */
+/*
+int mp_cmp(const mp_int *a, const mp_int *b);
+*/
+
+/* compare |a| to |b| */
+/*
+int mp_cmp_mag(const mp_int *a, const mp_int *b);
+*/
+
+/* c = a + b */
+/*
+int mp_add(mp_int *a, mp_int *b, mp_int *c);
+*/
+
+/* c = a - b */
+/*
+int mp_sub(mp_int *a, mp_int *b, mp_int *c);
+*/
+
+/* c = a * b */
+/*
+int mp_mul(mp_int *a, mp_int *b, mp_int *c);
+*/
+
+/* b = a*a  */
+/*
+int mp_sqr(mp_int *a, mp_int *b);
+*/
+
+/* a/b => cb + d == a */
+/*
+int mp_div(mp_int *a, mp_int *b, mp_int *c, mp_int *d);
+*/
+
+/* c = a mod b, 0 <= c < b  */
+/*
+int mp_mod(mp_int *a, mp_int *b, mp_int *c);
+*/
+
+/* ---> single digit functions <--- */
+
+/* compare against a single digit */
+/*
+int mp_cmp_d(const mp_int *a, mp_digit b);
+*/
+
+/* c = a + b */
+/*
+int mp_add_d(mp_int *a, mp_digit b, mp_int *c);
+*/
+
+/* c = a - b */
+/*
+int mp_sub_d(mp_int *a, mp_digit b, mp_int *c);
+*/
+
+/* c = a * b */
+/*
+int mp_mul_d(mp_int *a, mp_digit b, mp_int *c);
+*/
+
+/* a/b => cb + d == a */
+/*
+int mp_div_d(mp_int *a, mp_digit b, mp_int *c, mp_digit *d);
+*/
+
+/* a/3 => 3c + d == a */
+/*
+int mp_div_3(mp_int *a, mp_int *c, mp_digit *d);
+*/
+
+/* c = a**b */
+/*
+int mp_expt_d(mp_int *a, mp_digit b, mp_int *c);
+*/
+
+/* c = a mod b, 0 <= c < b  */
+/*
+int mp_mod_d(mp_int *a, mp_digit b, mp_digit *c);
+*/
+
+/* ---> number theory <--- */
+
+/* d = a + b (mod c) */
+/*
+int mp_addmod(mp_int *a, mp_int *b, mp_int *c, mp_int *d);
+*/
+
+/* d = a - b (mod c) */
+/*
+int mp_submod(mp_int *a, mp_int *b, mp_int *c, mp_int *d);
+*/
+
+/* d = a * b (mod c) */
+/*
+int mp_mulmod(mp_int *a, mp_int *b, mp_int *c, mp_int *d);
+*/
+
+/* c = a * a (mod b) */
+/*
+int mp_sqrmod(mp_int *a, mp_int *b, mp_int *c);
+*/
+
+/* c = 1/a (mod b) */
+/*
+int mp_invmod(mp_int *a, mp_int *b, mp_int *c);
+*/
+
+/* c = (a, b) */
+/*
+int mp_gcd(mp_int *a, mp_int *b, mp_int *c);
+*/
+
+/* produces value such that U1*a + U2*b = U3 */
+/*
+int mp_exteuclid(mp_int *a, mp_int *b, mp_int *U1, mp_int *U2, mp_int *U3);
+*/
+
+/* c = [a, b] or (a*b)/(a, b) */
+/*
+int mp_lcm(mp_int *a, mp_int *b, mp_int *c);
+*/
+
+/* finds one of the b'th root of a, such that |c|**b <= |a|
+ *
+ * returns error if a < 0 and b is even
+ */
+/*
+int mp_n_root(mp_int *a, mp_digit b, mp_int *c);
+*/
+
+/* special sqrt algo */
+/*
+int mp_sqrt(mp_int *arg, mp_int *ret);
+*/
+
+/* is number a square? */
+/*
+int mp_is_square(mp_int *arg, int *ret);
+*/
+
+/* computes the jacobi c = (a | n) (or Legendre if b is prime)  */
+/*
+int mp_jacobi(mp_int *a, mp_int *n, int *c);
+*/
+
+/* used to setup the Barrett reduction for a given modulus b */
+/*
+int mp_reduce_setup(mp_int *a, mp_int *b);
+*/
+
+/* Barrett Reduction, computes a (mod b) with a precomputed value c
+ *
+ * Assumes that 0 < a <= b*b, note if 0 > a > -(b*b) then you can merely
+ * compute the reduction as -1 * mp_reduce(mp_abs(a)) [pseudo code].
+ */
+/*
+int mp_reduce(mp_int *a, mp_int *b, mp_int *c);
+*/
+
+/* setups the montgomery reduction */
+/*
+int mp_montgomery_setup(mp_int *a, mp_digit *mp);
+*/
+
+/* computes a = B**n mod b without division or multiplication useful for
+ * normalizing numbers in a Montgomery system.
+ */
+/*
+int mp_montgomery_calc_normalization(mp_int *a, mp_int *b);
+*/
+
+/* computes x/R == x (mod N) via Montgomery Reduction */
+/*
+int mp_montgomery_reduce(mp_int *a, mp_int *m, mp_digit mp);
+*/
+
+/* returns 1 if a is a valid DR modulus */
+/*
+int mp_dr_is_modulus(mp_int *a);
+*/
+
+/* sets the value of "d" required for mp_dr_reduce */
+/*
+void mp_dr_setup(mp_int *a, mp_digit *d);
+*/
+
+/* reduces a modulo b using the Diminished Radix method */
+/*
+int mp_dr_reduce(mp_int *a, mp_int *b, mp_digit mp);
+*/
+
+/* returns true if a can be reduced with mp_reduce_2k */
+/*
+int mp_reduce_is_2k(mp_int *a);
+*/
+
+/* determines k value for 2k reduction */
+/*
+int mp_reduce_2k_setup(mp_int *a, mp_digit *d);
+*/
+
+/* reduces a modulo b where b is of the form 2**p - k [0 <= a] */
+/*
+int mp_reduce_2k(mp_int *a, mp_int *n, mp_digit d);
+*/
+
+/* returns true if a can be reduced with mp_reduce_2k_l */
+/*
+int mp_reduce_is_2k_l(mp_int *a);
+*/
+
+/* determines k value for 2k reduction */
+/*
+int mp_reduce_2k_setup_l(mp_int *a, mp_int *d);
+*/
+
+/* reduces a modulo b where b is of the form 2**p - k [0 <= a] */
+/*
+int mp_reduce_2k_l(mp_int *a, mp_int *n, mp_int *d);
+*/
+
+/* d = a**b (mod c) */
+/*
+int mp_exptmod(mp_int *a, mp_int *b, mp_int *c, mp_int *d);
+*/
+
+/* ---> Primes <--- */
+
+/* number of primes */
+#ifdef MP_8BIT
+#  define PRIME_SIZE      31
+#else
+#  define PRIME_SIZE      256
+#endif
+
+/* table of first PRIME_SIZE primes */
+#if defined(BUILD_tcl) || !defined(_WIN32)
+MODULE_SCOPE const mp_digit ltm_prime_tab[];
+#endif
+
+/* result=1 if a is divisible by one of the first PRIME_SIZE primes */
+/*
+int mp_prime_is_divisible(mp_int *a, int *result);
+*/
+
+/* performs one Fermat test of "a" using base "b".
+ * Sets result to 0 if composite or 1 if probable prime
+ */
+/*
+int mp_prime_fermat(mp_int *a, mp_int *b, int *result);
+*/
+
+/* performs one Miller-Rabin test of "a" using base "b".
+ * Sets result to 0 if composite or 1 if probable prime
+ */
+/*
+int mp_prime_miller_rabin(mp_int *a, mp_int *b, int *result);
+*/
+
+/* This gives [for a given bit size] the number of trials required
+ * such that Miller-Rabin gives a prob of failure lower than 2^-96 
+ */
+/*
+int mp_prime_rabin_miller_trials(int size);
+*/
+
+/* performs t rounds of Miller-Rabin on "a" using the first
+ * t prime bases.  Also performs an initial sieve of trial
+ * division.  Determines if "a" is prime with probability
+ * of error no more than (1/4)**t.
+ *
+ * Sets result to 1 if probably prime, 0 otherwise
+ */
+/*
+int mp_prime_is_prime(mp_int *a, int t, int *result);
+*/
+
+/* finds the next prime after the number "a" using "t" trials
+ * of Miller-Rabin.
+ *
+ * bbs_style = 1 means the prime must be congruent to 3 mod 4
+ */
+/*
+int mp_prime_next_prime(mp_int *a, int t, int bbs_style);
+*/
+
+/* makes a truly random prime of a given size (bytes),
+ * call with bbs = 1 if you want it to be congruent to 3 mod 4 
+ *
+ * You have to supply a callback which fills in a buffer with random bytes.  "dat" is a parameter you can
+ * have passed to the callback (e.g. a state or something).  This function doesn't use "dat" itself
+ * so it can be NULL
+ *
+ * The prime generated will be larger than 2^(8*size).
+ */
+#define mp_prime_random(a, t, size, bbs, cb, dat) mp_prime_random_ex(a, t, ((size) * 8) + 1, (bbs==1)?LTM_PRIME_BBS:0, cb, dat)
+
+/* makes a truly random prime of a given size (bits),
+ *
+ * Flags are as follows:
+ * 
+ *   LTM_PRIME_BBS      - make prime congruent to 3 mod 4
+ *   LTM_PRIME_SAFE     - make sure (p-1)/2 is prime as well (implies LTM_PRIME_BBS)
+ *   LTM_PRIME_2MSB_OFF - make the 2nd highest bit zero
+ *   LTM_PRIME_2MSB_ON  - make the 2nd highest bit one
+ *
+ * You have to supply a callback which fills in a buffer with random bytes.  "dat" is a parameter you can
+ * have passed to the callback (e.g. a state or something).  This function doesn't use "dat" itself
+ * so it can be NULL
+ *
+ */
+/*
+int mp_prime_random_ex(mp_int *a, int t, int size, int flags, ltm_prime_callback cb, void *dat);
+*/
+
+/* ---> radix conversion <--- */
+/*
+int mp_count_bits(const mp_int *a);
+*/
+
+/*
+int mp_unsigned_bin_size(mp_int *a);
+*/
+/*
+int mp_read_unsigned_bin(mp_int *a, const unsigned char *b, int c);
+*/
+/*
+int mp_to_unsigned_bin(mp_int *a, unsigned char *b);
+*/
+/*
+int mp_to_unsigned_bin_n (mp_int * a, unsigned char *b, unsigned long *outlen);
+*/
+
+/*
+int mp_signed_bin_size(mp_int *a);
+*/
+/*
+int mp_read_signed_bin(mp_int *a, const unsigned char *b, int c);
+*/
+/*
+int mp_to_signed_bin(mp_int *a,  unsigned char *b);
+*/
+/*
+int mp_to_signed_bin_n (mp_int * a, unsigned char *b, unsigned long *outlen);
+*/
+
+/*
+int mp_read_radix(mp_int *a, const char *str, int radix);
+*/
+/*
+int mp_toradix(mp_int *a, char *str, int radix);
+*/
+/*
+int mp_toradix_n(mp_int * a, char *str, int radix, int maxlen);
+*/
+/*
+int mp_radix_size(mp_int *a, int radix, int *size);
+*/
+
+/*
+int mp_fread(mp_int *a, int radix, FILE *stream);
+*/
+/*
+int mp_fwrite(mp_int *a, int radix, FILE *stream);
+*/
+
+#define mp_read_raw(mp, str, len) mp_read_signed_bin((mp), (str), (len))
+#define mp_raw_size(mp)           mp_signed_bin_size(mp)
+#define mp_toraw(mp, str)         mp_to_signed_bin((mp), (str))
+#define mp_read_mag(mp, str, len) mp_read_unsigned_bin((mp), (str), (len))
+#define mp_mag_size(mp)           mp_unsigned_bin_size(mp)
+#define mp_tomag(mp, str)         mp_to_unsigned_bin((mp), (str))
+
+#define mp_tobinary(M, S)  mp_toradix((M), (S), 2)
+#define mp_tooctal(M, S)   mp_toradix((M), (S), 8)
+#define mp_todecimal(M, S) mp_toradix((M), (S), 10)
+#define mp_tohex(M, S)     mp_toradix((M), (S), 16)
+
+/* lowlevel functions, do not call! */
+/*
+int s_mp_add(mp_int *a, mp_int *b, mp_int *c);
+*/
+/*
+int s_mp_sub(mp_int *a, mp_int *b, mp_int *c);
+*/
+#define s_mp_mul(a, b, c) s_mp_mul_digs(a, b, c, (a)->used + (b)->used + 1)
+/*
+int fast_s_mp_mul_digs(mp_int *a, mp_int *b, mp_int *c, int digs);
+*/
+/*
+int s_mp_mul_digs(mp_int *a, mp_int *b, mp_int *c, int digs);
+*/
+/*
+int fast_s_mp_mul_high_digs(mp_int *a, mp_int *b, mp_int *c, int digs);
+*/
+/*
+int s_mp_mul_high_digs(mp_int *a, mp_int *b, mp_int *c, int digs);
+*/
+/*
+int fast_s_mp_sqr(mp_int *a, mp_int *b);
+*/
+/*
+int s_mp_sqr(mp_int *a, mp_int *b);
+*/
+/*
+int mp_karatsuba_mul(mp_int *a, mp_int *b, mp_int *c);
+*/
+/*
+int mp_toom_mul(mp_int *a, mp_int *b, mp_int *c);
+*/
+/*
+int mp_karatsuba_sqr(mp_int *a, mp_int *b);
+*/
+/*
+int mp_toom_sqr(mp_int *a, mp_int *b);
+*/
+/*
+int fast_mp_invmod(mp_int *a, mp_int *b, mp_int *c);
+*/
+/*
+int mp_invmod_slow (mp_int * a, mp_int * b, mp_int * c);
+*/
+/*
+int fast_mp_montgomery_reduce(mp_int *a, mp_int *m, mp_digit mp);
+*/
+/*
+int mp_exptmod_fast(mp_int *G, mp_int *X, mp_int *P, mp_int *Y, int mode);
+*/
+/*
+int s_mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int mode);
+*/
+/*
+void bn_reverse(unsigned char *s, int len);
+*/
+
+#if defined(BUILD_tcl) || !defined(_WIN32)
+MODULE_SCOPE const char *mp_s_rmap;
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/generic/tclTomMathDecls.h b/generic/tclTomMathDecls.h
new file mode 100644
index 0000000..2ce9d5a
--- /dev/null
+++ b/generic/tclTomMathDecls.h
@@ -0,0 +1,518 @@
+/*
+ *----------------------------------------------------------------------
+ *
+ * tclTomMathDecls.h --
+ *
+ *	This file contains the declarations for the 'libtommath'
+ *	functions that are exported by the Tcl library.
+ *
+ * Copyright (c) 2005 by Kevin B. Kenny.  All rights reserved.
+ *
+ * See the file "license.terms" for information on usage and redistribution
+ * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#ifndef _TCLTOMMATHDECLS
+#define _TCLTOMMATHDECLS
+
+#include "tcl.h"
+
+/*
+ * Define the version of the Stubs table that's exported for tommath
+ */
+
+#define TCLTOMMATH_EPOCH 0
+#define TCLTOMMATH_REVISION 0
+
+#define Tcl_TomMath_InitStubs(interp,version) \
+    (TclTomMathInitializeStubs((interp),(version),\
+                               TCLTOMMATH_EPOCH,TCLTOMMATH_REVISION))
+
+/* Define custom memory allocation for libtommath */
+
+/* MODULE_SCOPE void* TclBNAlloc( size_t ); */
+#define TclBNAlloc(s) ((void*)ckalloc((size_t)(s)))
+/* MODULE_SCOPE void* TclBNRealloc( void*, size_t ); */
+#define TclBNRealloc(x,s) ((void*)ckrealloc((char*)(x),(size_t)(s)))
+/* MODULE_SCOPE void  TclBNFree( void* ); */
+#define TclBNFree(x) (ckfree((char*)(x)))
+/* MODULE_SCOPE void* TclBNCalloc( size_t, size_t ); */
+/* unused - no macro */
+
+#define XMALLOC(x) TclBNAlloc(x)
+#define XFREE(x) TclBNFree(x)
+#define XREALLOC(x,n) TclBNRealloc(x,n)
+#define XCALLOC(n,x) TclBNCalloc(n,x)
+
+/* Rename the global symbols in libtommath to avoid linkage conflicts */
+
+#define KARATSUBA_MUL_CUTOFF TclBNKaratsubaMulCutoff
+#define KARATSUBA_SQR_CUTOFF TclBNKaratsubaSqrCutoff
+#define TOOM_MUL_CUTOFF TclBNToomMulCutoff
+#define TOOM_SQR_CUTOFF TclBNToomSqrCutoff
+
+#define bn_reverse TclBN_reverse
+#define fast_s_mp_mul_digs TclBN_fast_s_mp_mul_digs
+#define fast_s_mp_sqr TclBN_fast_s_mp_sqr
+#define mp_add TclBN_mp_add
+#define mp_add_d TclBN_mp_add_d
+#define mp_and TclBN_mp_and
+#define mp_clamp TclBN_mp_clamp
+#define mp_clear TclBN_mp_clear
+#define mp_clear_multi TclBN_mp_clear_multi
+#define mp_cmp TclBN_mp_cmp
+#define mp_cmp_d TclBN_mp_cmp_d
+#define mp_cmp_mag TclBN_mp_cmp_mag
+#define mp_cnt_lsb TclBN_mp_cnt_lsb
+#define mp_copy TclBN_mp_copy
+#define mp_count_bits TclBN_mp_count_bits
+#define mp_div TclBN_mp_div
+#define mp_div_2 TclBN_mp_div_2
+#define mp_div_2d TclBN_mp_div_2d
+#define mp_div_3 TclBN_mp_div_3
+#define mp_div_d TclBN_mp_div_d
+#define mp_exch TclBN_mp_exch
+#define mp_expt_d TclBN_mp_expt_d
+#define mp_grow TclBN_mp_grow
+#define mp_init TclBN_mp_init
+#define mp_init_copy TclBN_mp_init_copy
+#define mp_init_multi TclBN_mp_init_multi
+#define mp_init_set TclBN_mp_init_set
+#define mp_init_set_int TclBN_mp_init_set_int
+#define mp_init_size TclBN_mp_init_size
+#define mp_karatsuba_mul TclBN_mp_karatsuba_mul
+#define mp_karatsuba_sqr TclBN_mp_karatsuba_sqr
+#define mp_lshd TclBN_mp_lshd
+#define mp_mod TclBN_mp_mod
+#define mp_mod_2d TclBN_mp_mod_2d
+#define mp_mul TclBN_mp_mul
+#define mp_mul_2 TclBN_mp_mul_2
+#define mp_mul_2d TclBN_mp_mul_2d
+#define mp_mul_d TclBN_mp_mul_d
+#define mp_neg TclBN_mp_neg
+#define mp_or TclBN_mp_or
+#define mp_radix_size TclBN_mp_radix_size
+#define mp_read_radix TclBN_mp_read_radix
+#define mp_rshd TclBN_mp_rshd
+#define mp_s_rmap TclBNMpSRmap
+#define mp_set TclBN_mp_set
+#define mp_set_int TclBN_mp_set_int
+#define mp_shrink TclBN_mp_shrink
+#define mp_sqr TclBN_mp_sqr
+#define mp_sqrt TclBN_mp_sqrt
+#define mp_sub TclBN_mp_sub
+#define mp_sub_d TclBN_mp_sub_d
+#define mp_to_unsigned_bin TclBN_mp_to_unsigned_bin
+#define mp_to_unsigned_bin_n TclBN_mp_to_unsigned_bin_n
+#define mp_toom_mul TclBN_mp_toom_mul
+#define mp_toom_sqr TclBN_mp_toom_sqr
+#define mp_toradix_n TclBN_mp_toradix_n
+#define mp_unsigned_bin_size TclBN_mp_unsigned_bin_size
+#define mp_xor TclBN_mp_xor
+#define mp_zero TclBN_mp_zero
+#define s_mp_add TclBN_s_mp_add
+#define s_mp_mul_digs TclBN_s_mp_mul_digs
+#define s_mp_sqr TclBN_s_mp_sqr
+#define s_mp_sub TclBN_s_mp_sub
+
+#undef TCL_STORAGE_CLASS
+#ifdef BUILD_tcl
+#   define TCL_STORAGE_CLASS DLLEXPORT
+#else
+#   ifdef USE_TCL_STUBS
+#      define TCL_STORAGE_CLASS
+#   else
+#      define TCL_STORAGE_CLASS DLLIMPORT
+#   endif
+#endif
+
+/*
+ * WARNING: This file is automatically generated by the tools/genStubs.tcl
+ * script.  Any modifications to the function declarations below should be made
+ * in the generic/tclInt.decls script.
+ */
+
+/* !BEGIN!: Do not edit below this line. */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Exported function declarations:
+ */
+
+/* 0 */
+EXTERN int		TclBN_epoch(void);
+/* 1 */
+EXTERN int		TclBN_revision(void);
+/* 2 */
+EXTERN int		TclBN_mp_add(mp_int *a, mp_int *b, mp_int *c);
+/* 3 */
+EXTERN int		TclBN_mp_add_d(mp_int *a, mp_digit b, mp_int *c);
+/* 4 */
+EXTERN int		TclBN_mp_and(mp_int *a, mp_int *b, mp_int *c);
+/* 5 */
+EXTERN void		TclBN_mp_clamp(mp_int *a);
+/* 6 */
+EXTERN void		TclBN_mp_clear(mp_int *a);
+/* 7 */
+EXTERN void		TclBN_mp_clear_multi(mp_int *a, ...);
+/* 8 */
+EXTERN int		TclBN_mp_cmp(const mp_int *a, const mp_int *b);
+/* 9 */
+EXTERN int		TclBN_mp_cmp_d(const mp_int *a, mp_digit b);
+/* 10 */
+EXTERN int		TclBN_mp_cmp_mag(const mp_int *a, const mp_int *b);
+/* 11 */
+EXTERN int		TclBN_mp_copy(const mp_int *a, mp_int *b);
+/* 12 */
+EXTERN int		TclBN_mp_count_bits(const mp_int *a);
+/* 13 */
+EXTERN int		TclBN_mp_div(mp_int *a, mp_int *b, mp_int *q,
+				mp_int *r);
+/* 14 */
+EXTERN int		TclBN_mp_div_d(mp_int *a, mp_digit b, mp_int *q,
+				mp_digit *r);
+/* 15 */
+EXTERN int		TclBN_mp_div_2(mp_int *a, mp_int *q);
+/* 16 */
+EXTERN int		TclBN_mp_div_2d(const mp_int *a, int b, mp_int *q,
+				mp_int *r);
+/* 17 */
+EXTERN int		TclBN_mp_div_3(mp_int *a, mp_int *q, mp_digit *r);
+/* 18 */
+EXTERN void		TclBN_mp_exch(mp_int *a, mp_int *b);
+/* 19 */
+EXTERN int		TclBN_mp_expt_d(mp_int *a, mp_digit b, mp_int *c);
+/* 20 */
+EXTERN int		TclBN_mp_grow(mp_int *a, int size);
+/* 21 */
+EXTERN int		TclBN_mp_init(mp_int *a);
+/* 22 */
+EXTERN int		TclBN_mp_init_copy(mp_int *a, mp_int *b);
+/* 23 */
+EXTERN int		TclBN_mp_init_multi(mp_int *a, ...);
+/* 24 */
+EXTERN int		TclBN_mp_init_set(mp_int *a, mp_digit b);
+/* 25 */
+EXTERN int		TclBN_mp_init_size(mp_int *a, int size);
+/* 26 */
+EXTERN int		TclBN_mp_lshd(mp_int *a, int shift);
+/* 27 */
+EXTERN int		TclBN_mp_mod(mp_int *a, mp_int *b, mp_int *r);
+/* 28 */
+EXTERN int		TclBN_mp_mod_2d(const mp_int *a, int b, mp_int *r);
+/* 29 */
+EXTERN int		TclBN_mp_mul(mp_int *a, mp_int *b, mp_int *p);
+/* 30 */
+EXTERN int		TclBN_mp_mul_d(mp_int *a, mp_digit b, mp_int *p);
+/* 31 */
+EXTERN int		TclBN_mp_mul_2(mp_int *a, mp_int *p);
+/* 32 */
+EXTERN int		TclBN_mp_mul_2d(const mp_int *a, int d, mp_int *p);
+/* 33 */
+EXTERN int		TclBN_mp_neg(const mp_int *a, mp_int *b);
+/* 34 */
+EXTERN int		TclBN_mp_or(mp_int *a, mp_int *b, mp_int *c);
+/* 35 */
+EXTERN int		TclBN_mp_radix_size(mp_int *a, int radix, int *size);
+/* 36 */
+EXTERN int		TclBN_mp_read_radix(mp_int *a, const char *str,
+				int radix);
+/* 37 */
+EXTERN void		TclBN_mp_rshd(mp_int *a, int shift);
+/* 38 */
+EXTERN int		TclBN_mp_shrink(mp_int *a);
+/* 39 */
+EXTERN void		TclBN_mp_set(mp_int *a, mp_digit b);
+/* 40 */
+EXTERN int		TclBN_mp_sqr(mp_int *a, mp_int *b);
+/* 41 */
+EXTERN int		TclBN_mp_sqrt(mp_int *a, mp_int *b);
+/* 42 */
+EXTERN int		TclBN_mp_sub(mp_int *a, mp_int *b, mp_int *c);
+/* 43 */
+EXTERN int		TclBN_mp_sub_d(mp_int *a, mp_digit b, mp_int *c);
+/* 44 */
+EXTERN int		TclBN_mp_to_unsigned_bin(mp_int *a, unsigned char *b);
+/* 45 */
+EXTERN int		TclBN_mp_to_unsigned_bin_n(mp_int *a,
+				unsigned char *b, unsigned long *outlen);
+/* 46 */
+EXTERN int		TclBN_mp_toradix_n(mp_int *a, char *str, int radix,
+				int maxlen);
+/* 47 */
+EXTERN int		TclBN_mp_unsigned_bin_size(mp_int *a);
+/* 48 */
+EXTERN int		TclBN_mp_xor(mp_int *a, mp_int *b, mp_int *c);
+/* 49 */
+EXTERN void		TclBN_mp_zero(mp_int *a);
+/* 50 */
+EXTERN void		TclBN_reverse(unsigned char *s, int len);
+/* 51 */
+EXTERN int		TclBN_fast_s_mp_mul_digs(mp_int *a, mp_int *b,
+				mp_int *c, int digs);
+/* 52 */
+EXTERN int		TclBN_fast_s_mp_sqr(mp_int *a, mp_int *b);
+/* 53 */
+EXTERN int		TclBN_mp_karatsuba_mul(mp_int *a, mp_int *b,
+				mp_int *c);
+/* 54 */
+EXTERN int		TclBN_mp_karatsuba_sqr(mp_int *a, mp_int *b);
+/* 55 */
+EXTERN int		TclBN_mp_toom_mul(mp_int *a, mp_int *b, mp_int *c);
+/* 56 */
+EXTERN int		TclBN_mp_toom_sqr(mp_int *a, mp_int *b);
+/* 57 */
+EXTERN int		TclBN_s_mp_add(mp_int *a, mp_int *b, mp_int *c);
+/* 58 */
+EXTERN int		TclBN_s_mp_mul_digs(mp_int *a, mp_int *b, mp_int *c,
+				int digs);
+/* 59 */
+EXTERN int		TclBN_s_mp_sqr(mp_int *a, mp_int *b);
+/* 60 */
+EXTERN int		TclBN_s_mp_sub(mp_int *a, mp_int *b, mp_int *c);
+/* 61 */
+EXTERN int		TclBN_mp_init_set_int(mp_int *a, unsigned long i);
+/* 62 */
+EXTERN int		TclBN_mp_set_int(mp_int *a, unsigned long i);
+/* 63 */
+EXTERN int		TclBN_mp_cnt_lsb(const mp_int *a);
+/* 64 */
+EXTERN void		TclBNInitBignumFromLong(mp_int *bignum, long initVal);
+/* 65 */
+EXTERN void		TclBNInitBignumFromWideInt(mp_int *bignum,
+				Tcl_WideInt initVal);
+/* 66 */
+EXTERN void		TclBNInitBignumFromWideUInt(mp_int *bignum,
+				Tcl_WideUInt initVal);
+
+typedef struct TclTomMathStubs {
+    int magic;
+    void *hooks;
+
+    int (*tclBN_epoch) (void); /* 0 */
+    int (*tclBN_revision) (void); /* 1 */
+    int (*tclBN_mp_add) (mp_int *a, mp_int *b, mp_int *c); /* 2 */
+    int (*tclBN_mp_add_d) (mp_int *a, mp_digit b, mp_int *c); /* 3 */
+    int (*tclBN_mp_and) (mp_int *a, mp_int *b, mp_int *c); /* 4 */
+    void (*tclBN_mp_clamp) (mp_int *a); /* 5 */
+    void (*tclBN_mp_clear) (mp_int *a); /* 6 */
+    void (*tclBN_mp_clear_multi) (mp_int *a, ...); /* 7 */
+    int (*tclBN_mp_cmp) (const mp_int *a, const mp_int *b); /* 8 */
+    int (*tclBN_mp_cmp_d) (const mp_int *a, mp_digit b); /* 9 */
+    int (*tclBN_mp_cmp_mag) (const mp_int *a, const mp_int *b); /* 10 */
+    int (*tclBN_mp_copy) (const mp_int *a, mp_int *b); /* 11 */
+    int (*tclBN_mp_count_bits) (const mp_int *a); /* 12 */
+    int (*tclBN_mp_div) (mp_int *a, mp_int *b, mp_int *q, mp_int *r); /* 13 */
+    int (*tclBN_mp_div_d) (mp_int *a, mp_digit b, mp_int *q, mp_digit *r); /* 14 */
+    int (*tclBN_mp_div_2) (mp_int *a, mp_int *q); /* 15 */
+    int (*tclBN_mp_div_2d) (const mp_int *a, int b, mp_int *q, mp_int *r); /* 16 */
+    int (*tclBN_mp_div_3) (mp_int *a, mp_int *q, mp_digit *r); /* 17 */
+    void (*tclBN_mp_exch) (mp_int *a, mp_int *b); /* 18 */
+    int (*tclBN_mp_expt_d) (mp_int *a, mp_digit b, mp_int *c); /* 19 */
+    int (*tclBN_mp_grow) (mp_int *a, int size); /* 20 */
+    int (*tclBN_mp_init) (mp_int *a); /* 21 */
+    int (*tclBN_mp_init_copy) (mp_int *a, mp_int *b); /* 22 */
+    int (*tclBN_mp_init_multi) (mp_int *a, ...); /* 23 */
+    int (*tclBN_mp_init_set) (mp_int *a, mp_digit b); /* 24 */
+    int (*tclBN_mp_init_size) (mp_int *a, int size); /* 25 */
+    int (*tclBN_mp_lshd) (mp_int *a, int shift); /* 26 */
+    int (*tclBN_mp_mod) (mp_int *a, mp_int *b, mp_int *r); /* 27 */
+    int (*tclBN_mp_mod_2d) (const mp_int *a, int b, mp_int *r); /* 28 */
+    int (*tclBN_mp_mul) (mp_int *a, mp_int *b, mp_int *p); /* 29 */
+    int (*tclBN_mp_mul_d) (mp_int *a, mp_digit b, mp_int *p); /* 30 */
+    int (*tclBN_mp_mul_2) (mp_int *a, mp_int *p); /* 31 */
+    int (*tclBN_mp_mul_2d) (const mp_int *a, int d, mp_int *p); /* 32 */
+    int (*tclBN_mp_neg) (const mp_int *a, mp_int *b); /* 33 */
+    int (*tclBN_mp_or) (mp_int *a, mp_int *b, mp_int *c); /* 34 */
+    int (*tclBN_mp_radix_size) (mp_int *a, int radix, int *size); /* 35 */
+    int (*tclBN_mp_read_radix) (mp_int *a, const char *str, int radix); /* 36 */
+    void (*tclBN_mp_rshd) (mp_int *a, int shift); /* 37 */
+    int (*tclBN_mp_shrink) (mp_int *a); /* 38 */
+    void (*tclBN_mp_set) (mp_int *a, mp_digit b); /* 39 */
+    int (*tclBN_mp_sqr) (mp_int *a, mp_int *b); /* 40 */
+    int (*tclBN_mp_sqrt) (mp_int *a, mp_int *b); /* 41 */
+    int (*tclBN_mp_sub) (mp_int *a, mp_int *b, mp_int *c); /* 42 */
+    int (*tclBN_mp_sub_d) (mp_int *a, mp_digit b, mp_int *c); /* 43 */
+    int (*tclBN_mp_to_unsigned_bin) (mp_int *a, unsigned char *b); /* 44 */
+    int (*tclBN_mp_to_unsigned_bin_n) (mp_int *a, unsigned char *b, unsigned long *outlen); /* 45 */
+    int (*tclBN_mp_toradix_n) (mp_int *a, char *str, int radix, int maxlen); /* 46 */
+    int (*tclBN_mp_unsigned_bin_size) (mp_int *a); /* 47 */
+    int (*tclBN_mp_xor) (mp_int *a, mp_int *b, mp_int *c); /* 48 */
+    void (*tclBN_mp_zero) (mp_int *a); /* 49 */
+    void (*tclBN_reverse) (unsigned char *s, int len); /* 50 */
+    int (*tclBN_fast_s_mp_mul_digs) (mp_int *a, mp_int *b, mp_int *c, int digs); /* 51 */
+    int (*tclBN_fast_s_mp_sqr) (mp_int *a, mp_int *b); /* 52 */
+    int (*tclBN_mp_karatsuba_mul) (mp_int *a, mp_int *b, mp_int *c); /* 53 */
+    int (*tclBN_mp_karatsuba_sqr) (mp_int *a, mp_int *b); /* 54 */
+    int (*tclBN_mp_toom_mul) (mp_int *a, mp_int *b, mp_int *c); /* 55 */
+    int (*tclBN_mp_toom_sqr) (mp_int *a, mp_int *b); /* 56 */
+    int (*tclBN_s_mp_add) (mp_int *a, mp_int *b, mp_int *c); /* 57 */
+    int (*tclBN_s_mp_mul_digs) (mp_int *a, mp_int *b, mp_int *c, int digs); /* 58 */
+    int (*tclBN_s_mp_sqr) (mp_int *a, mp_int *b); /* 59 */
+    int (*tclBN_s_mp_sub) (mp_int *a, mp_int *b, mp_int *c); /* 60 */
+    int (*tclBN_mp_init_set_int) (mp_int *a, unsigned long i); /* 61 */
+    int (*tclBN_mp_set_int) (mp_int *a, unsigned long i); /* 62 */
+    int (*tclBN_mp_cnt_lsb) (const mp_int *a); /* 63 */
+    void (*tclBNInitBignumFromLong) (mp_int *bignum, long initVal); /* 64 */
+    void (*tclBNInitBignumFromWideInt) (mp_int *bignum, Tcl_WideInt initVal); /* 65 */
+    void (*tclBNInitBignumFromWideUInt) (mp_int *bignum, Tcl_WideUInt initVal); /* 66 */
+} TclTomMathStubs;
+
+extern const TclTomMathStubs *tclTomMathStubsPtr;
+
+#ifdef __cplusplus
+}
+#endif
+
+#if defined(USE_TCL_STUBS)
+
+/*
+ * Inline function declarations:
+ */
+
+#define TclBN_epoch \
+	(tclTomMathStubsPtr->tclBN_epoch) /* 0 */
+#define TclBN_revision \
+	(tclTomMathStubsPtr->tclBN_revision) /* 1 */
+#define TclBN_mp_add \
+	(tclTomMathStubsPtr->tclBN_mp_add) /* 2 */
+#define TclBN_mp_add_d \
+	(tclTomMathStubsPtr->tclBN_mp_add_d) /* 3 */
+#define TclBN_mp_and \
+	(tclTomMathStubsPtr->tclBN_mp_and) /* 4 */
+#define TclBN_mp_clamp \
+	(tclTomMathStubsPtr->tclBN_mp_clamp) /* 5 */
+#define TclBN_mp_clear \
+	(tclTomMathStubsPtr->tclBN_mp_clear) /* 6 */
+#define TclBN_mp_clear_multi \
+	(tclTomMathStubsPtr->tclBN_mp_clear_multi) /* 7 */
+#define TclBN_mp_cmp \
+	(tclTomMathStubsPtr->tclBN_mp_cmp) /* 8 */
+#define TclBN_mp_cmp_d \
+	(tclTomMathStubsPtr->tclBN_mp_cmp_d) /* 9 */
+#define TclBN_mp_cmp_mag \
+	(tclTomMathStubsPtr->tclBN_mp_cmp_mag) /* 10 */
+#define TclBN_mp_copy \
+	(tclTomMathStubsPtr->tclBN_mp_copy) /* 11 */
+#define TclBN_mp_count_bits \
+	(tclTomMathStubsPtr->tclBN_mp_count_bits) /* 12 */
+#define TclBN_mp_div \
+	(tclTomMathStubsPtr->tclBN_mp_div) /* 13 */
+#define TclBN_mp_div_d \
+	(tclTomMathStubsPtr->tclBN_mp_div_d) /* 14 */
+#define TclBN_mp_div_2 \
+	(tclTomMathStubsPtr->tclBN_mp_div_2) /* 15 */
+#define TclBN_mp_div_2d \
+	(tclTomMathStubsPtr->tclBN_mp_div_2d) /* 16 */
+#define TclBN_mp_div_3 \
+	(tclTomMathStubsPtr->tclBN_mp_div_3) /* 17 */
+#define TclBN_mp_exch \
+	(tclTomMathStubsPtr->tclBN_mp_exch) /* 18 */
+#define TclBN_mp_expt_d \
+	(tclTomMathStubsPtr->tclBN_mp_expt_d) /* 19 */
+#define TclBN_mp_grow \
+	(tclTomMathStubsPtr->tclBN_mp_grow) /* 20 */
+#define TclBN_mp_init \
+	(tclTomMathStubsPtr->tclBN_mp_init) /* 21 */
+#define TclBN_mp_init_copy \
+	(tclTomMathStubsPtr->tclBN_mp_init_copy) /* 22 */
+#define TclBN_mp_init_multi \
+	(tclTomMathStubsPtr->tclBN_mp_init_multi) /* 23 */
+#define TclBN_mp_init_set \
+	(tclTomMathStubsPtr->tclBN_mp_init_set) /* 24 */
+#define TclBN_mp_init_size \
+	(tclTomMathStubsPtr->tclBN_mp_init_size) /* 25 */
+#define TclBN_mp_lshd \
+	(tclTomMathStubsPtr->tclBN_mp_lshd) /* 26 */
+#define TclBN_mp_mod \
+	(tclTomMathStubsPtr->tclBN_mp_mod) /* 27 */
+#define TclBN_mp_mod_2d \
+	(tclTomMathStubsPtr->tclBN_mp_mod_2d) /* 28 */
+#define TclBN_mp_mul \
+	(tclTomMathStubsPtr->tclBN_mp_mul) /* 29 */
+#define TclBN_mp_mul_d \
+	(tclTomMathStubsPtr->tclBN_mp_mul_d) /* 30 */
+#define TclBN_mp_mul_2 \
+	(tclTomMathStubsPtr->tclBN_mp_mul_2) /* 31 */
+#define TclBN_mp_mul_2d \
+	(tclTomMathStubsPtr->tclBN_mp_mul_2d) /* 32 */
+#define TclBN_mp_neg \
+	(tclTomMathStubsPtr->tclBN_mp_neg) /* 33 */
+#define TclBN_mp_or \
+	(tclTomMathStubsPtr->tclBN_mp_or) /* 34 */
+#define TclBN_mp_radix_size \
+	(tclTomMathStubsPtr->tclBN_mp_radix_size) /* 35 */
+#define TclBN_mp_read_radix \
+	(tclTomMathStubsPtr->tclBN_mp_read_radix) /* 36 */
+#define TclBN_mp_rshd \
+	(tclTomMathStubsPtr->tclBN_mp_rshd) /* 37 */
+#define TclBN_mp_shrink \
+	(tclTomMathStubsPtr->tclBN_mp_shrink) /* 38 */
+#define TclBN_mp_set \
+	(tclTomMathStubsPtr->tclBN_mp_set) /* 39 */
+#define TclBN_mp_sqr \
+	(tclTomMathStubsPtr->tclBN_mp_sqr) /* 40 */
+#define TclBN_mp_sqrt \
+	(tclTomMathStubsPtr->tclBN_mp_sqrt) /* 41 */
+#define TclBN_mp_sub \
+	(tclTomMathStubsPtr->tclBN_mp_sub) /* 42 */
+#define TclBN_mp_sub_d \
+	(tclTomMathStubsPtr->tclBN_mp_sub_d) /* 43 */
+#define TclBN_mp_to_unsigned_bin \
+	(tclTomMathStubsPtr->tclBN_mp_to_unsigned_bin) /* 44 */
+#define TclBN_mp_to_unsigned_bin_n \
+	(tclTomMathStubsPtr->tclBN_mp_to_unsigned_bin_n) /* 45 */
+#define TclBN_mp_toradix_n \
+	(tclTomMathStubsPtr->tclBN_mp_toradix_n) /* 46 */
+#define TclBN_mp_unsigned_bin_size \
+	(tclTomMathStubsPtr->tclBN_mp_unsigned_bin_size) /* 47 */
+#define TclBN_mp_xor \
+	(tclTomMathStubsPtr->tclBN_mp_xor) /* 48 */
+#define TclBN_mp_zero \
+	(tclTomMathStubsPtr->tclBN_mp_zero) /* 49 */
+#define TclBN_reverse \
+	(tclTomMathStubsPtr->tclBN_reverse) /* 50 */
+#define TclBN_fast_s_mp_mul_digs \
+	(tclTomMathStubsPtr->tclBN_fast_s_mp_mul_digs) /* 51 */
+#define TclBN_fast_s_mp_sqr \
+	(tclTomMathStubsPtr->tclBN_fast_s_mp_sqr) /* 52 */
+#define TclBN_mp_karatsuba_mul \
+	(tclTomMathStubsPtr->tclBN_mp_karatsuba_mul) /* 53 */
+#define TclBN_mp_karatsuba_sqr \
+	(tclTomMathStubsPtr->tclBN_mp_karatsuba_sqr) /* 54 */
+#define TclBN_mp_toom_mul \
+	(tclTomMathStubsPtr->tclBN_mp_toom_mul) /* 55 */
+#define TclBN_mp_toom_sqr \
+	(tclTomMathStubsPtr->tclBN_mp_toom_sqr) /* 56 */
+#define TclBN_s_mp_add \
+	(tclTomMathStubsPtr->tclBN_s_mp_add) /* 57 */
+#define TclBN_s_mp_mul_digs \
+	(tclTomMathStubsPtr->tclBN_s_mp_mul_digs) /* 58 */
+#define TclBN_s_mp_sqr \
+	(tclTomMathStubsPtr->tclBN_s_mp_sqr) /* 59 */
+#define TclBN_s_mp_sub \
+	(tclTomMathStubsPtr->tclBN_s_mp_sub) /* 60 */
+#define TclBN_mp_init_set_int \
+	(tclTomMathStubsPtr->tclBN_mp_init_set_int) /* 61 */
+#define TclBN_mp_set_int \
+	(tclTomMathStubsPtr->tclBN_mp_set_int) /* 62 */
+#define TclBN_mp_cnt_lsb \
+	(tclTomMathStubsPtr->tclBN_mp_cnt_lsb) /* 63 */
+#define TclBNInitBignumFromLong \
+	(tclTomMathStubsPtr->tclBNInitBignumFromLong) /* 64 */
+#define TclBNInitBignumFromWideInt \
+	(tclTomMathStubsPtr->tclBNInitBignumFromWideInt) /* 65 */
+#define TclBNInitBignumFromWideUInt \
+	(tclTomMathStubsPtr->tclBNInitBignumFromWideUInt) /* 66 */
+
+#endif /* defined(USE_TCL_STUBS) */
+
+/* !END!: Do not edit above this line. */
+
+#undef TCL_STORAGE_CLASS
+#define TCL_STORAGE_CLASS DLLIMPORT
+
+#endif /* _TCLINTDECLS */
diff --git a/generic/tclTomMathInt.h b/generic/tclTomMathInt.h
new file mode 100644
index 0000000..831f13f
--- /dev/null
+++ b/generic/tclTomMathInt.h
@@ -0,0 +1,3 @@
+#include "tclInt.h"
+#include "tclTomMath.h"
+#include "tommath_class.h"
diff --git a/generic/tclTomMathInterface.c b/generic/tclTomMathInterface.c
new file mode 100644
index 0000000..48db8c3
--- /dev/null
+++ b/generic/tclTomMathInterface.c
@@ -0,0 +1,310 @@
+/*
+ *----------------------------------------------------------------------
+ *
+ * tclTomMathInterface.c --
+ *
+ *	This file contains procedures that are used as a 'glue' layer between
+ *	Tcl and libtommath.
+ *
+ * Copyright (c) 2005 by Kevin B. Kenny.  All rights reserved.
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#include "tclInt.h"
+#include "tommath.h"
+
+MODULE_SCOPE const TclTomMathStubs tclTomMathStubs;
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclTommath_Init --
+ *
+ *	Initializes the TclTomMath 'package', which exists as a
+ *	placeholder so that the package data can be used to hold
+ *	a stub table pointer.
+ *
+ * Results:
+ *	Returns a standard Tcl result.
+ *
+ * Side effects:
+ *	Installs the stub table for tommath.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclTommath_Init(
+    Tcl_Interp *interp)		/* Tcl interpreter */
+{
+    /* TIP #268: Full patchlevel instead of just major.minor */
+
+    if (Tcl_PkgProvideEx(interp, "tcl::tommath", TCL_PATCH_LEVEL,
+	    &tclTomMathStubs) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclBN_epoch --
+ *
+ *	Return the epoch number of the TclTomMath stubs table
+ *
+ * Results:
+ *	Returns an arbitrary integer that does not decrease with
+ *	release.  Stubs tables with different epochs are incompatible.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclBN_epoch(void)
+{
+    return TCLTOMMATH_EPOCH;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclBN_revision --
+ *
+ *	Returns the revision level of the TclTomMath stubs table
+ *
+ * Results:
+ *	Returns an arbitrary integer that increases with revisions.
+ *	If a client requires a given epoch and revision, any Stubs table
+ *	with the same epoch and an equal or higher revision satisfies
+ *	the request.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclBN_revision(void)
+{
+    return TCLTOMMATH_REVISION;
+}
+#if 0
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclBNAlloc --
+ *
+ *	Allocate memory for libtommath.
+ *
+ * Results:
+ *	Returns a pointer to the allocated block.
+ *
+ * This procedure is a wrapper around Tcl_Alloc, needed because of a
+ * mismatched type signature between Tcl_Alloc and malloc.
+ *
+ *----------------------------------------------------------------------
+ */
+
+extern void *
+TclBNAlloc(
+    size_t x)
+{
+    return (void *) ckalloc((unsigned int) x);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclBNRealloc --
+ *
+ *	Change the size of an allocated block of memory in libtommath
+ *
+ * Results:
+ *	Returns a pointer to the allocated block.
+ *
+ * This procedure is a wrapper around Tcl_Realloc, needed because of a
+ * mismatched type signature between Tcl_Realloc and realloc.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void *
+TclBNRealloc(
+    void *p,
+    size_t s)
+{
+    return (void *) ckrealloc((char *) p, (unsigned int) s);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclBNFree --
+ *
+ *	Free allocated memory in libtommath.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Memory is freed.
+ *
+ * This function is simply a wrapper around Tcl_Free, needed in libtommath
+ * because of a type mismatch between free and Tcl_Free.
+ *
+ *----------------------------------------------------------------------
+ */
+
+extern void
+TclBNFree(
+    void *p)
+{
+    ckree((char *) p);
+}
+#endif
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclBNInitBignumFromLong --
+ *
+ *	Allocate and initialize a 'bignum' from a native 'long'.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The 'bignum' is constructed.
+ *
+ *----------------------------------------------------------------------
+ */
+
+extern void
+TclBNInitBignumFromLong(
+    mp_int *a,
+    long initVal)
+{
+    int status;
+    unsigned long v;
+    mp_digit *p;
+
+    /*
+     * Allocate enough memory to hold the largest possible long
+     */
+
+    status = mp_init_size(a,
+	    (CHAR_BIT * sizeof(long) + DIGIT_BIT - 1) / DIGIT_BIT);
+    if (status != MP_OKAY) {
+	Tcl_Panic("initialization failure in TclBNInitBignumFromLong");
+    }
+
+    /*
+     * Convert arg to sign and magnitude.
+     */
+
+    if (initVal < 0) {
+	a->sign = MP_NEG;
+	v = -initVal;
+    } else {
+	a->sign = MP_ZPOS;
+	v = initVal;
+    }
+
+    /*
+     * Store the magnitude in the bignum.
+     */
+
+    p = a->dp;
+    while (v) {
+	*p++ = (mp_digit) (v & MP_MASK);
+	v >>= MP_DIGIT_BIT;
+    }
+    a->used = p - a->dp;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclBNInitBignumFromWideInt --
+ *
+ *	Allocate and initialize a 'bignum' from a Tcl_WideInt
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The 'bignum' is constructed.
+ *
+ *----------------------------------------------------------------------
+ */
+
+extern void
+TclBNInitBignumFromWideInt(
+    mp_int *a,			/* Bignum to initialize */
+    Tcl_WideInt v)		/* Initial value */
+{
+    if (v < (Tcl_WideInt)0) {
+	TclBNInitBignumFromWideUInt(a, (Tcl_WideUInt)(-v));
+	mp_neg(a, a);
+    } else {
+	TclBNInitBignumFromWideUInt(a, (Tcl_WideUInt)v);
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclBNInitBignumFromWideUInt --
+ *
+ *	Allocate and initialize a 'bignum' from a Tcl_WideUInt
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The 'bignum' is constructed.
+ *
+ *----------------------------------------------------------------------
+ */
+
+extern void
+TclBNInitBignumFromWideUInt(
+    mp_int *a,			/* Bignum to initialize */
+    Tcl_WideUInt v)		/* Initial value */
+{
+    int status;
+    mp_digit *p;
+
+    /*
+     * Allocate enough memory to hold the largest possible Tcl_WideUInt.
+     */
+
+    status = mp_init_size(a,
+	    (CHAR_BIT * sizeof(Tcl_WideUInt) + DIGIT_BIT - 1) / DIGIT_BIT);
+    if (status != MP_OKAY) {
+	Tcl_Panic("initialization failure in TclBNInitBignumFromWideUInt");
+    }
+
+    a->sign = MP_ZPOS;
+
+    /*
+     * Store the magnitude in the bignum.
+     */
+
+    p = a->dp;
+    while (v) {
+	*p++ = (mp_digit) (v & MP_MASK);
+	v >>= MP_DIGIT_BIT;
+    }
+    a->used = p - a->dp;
+}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tclTomMathStubLib.c b/generic/tclTomMathStubLib.c
new file mode 100644
index 0000000..324f2a3
--- /dev/null
+++ b/generic/tclTomMathStubLib.c
@@ -0,0 +1,79 @@
+/*
+ * tclTomMathStubLib.c --
+ *
+ *	Stub object that will be statically linked into extensions that want
+ *	to access Tcl.
+ *
+ * Copyright (c) 1998-1999 by Scriptics Corporation.
+ * Copyright (c) 1998 Paul Duffin.
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#include "tclInt.h"
+
+MODULE_SCOPE const TclTomMathStubs *tclTomMathStubsPtr;
+
+const TclTomMathStubs *tclTomMathStubsPtr = NULL;
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclTomMathInitStubs --
+ *
+ *	Initializes the Stubs table for Tcl's subset of libtommath
+ *
+ * Results:
+ *	Returns a standard Tcl result.
+ *
+ * This procedure should not be called directly, but rather through
+ * the TclTomMath_InitStubs macro, to insure that the Stubs table
+ * matches the header files used in compilation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+MODULE_SCOPE const char *
+TclTomMathInitializeStubs(
+    Tcl_Interp *interp,		/* Tcl interpreter */
+    const char *version,	/* Tcl version needed */
+    int epoch,			/* Stubs table epoch from the header files */
+    int revision)		/* Stubs table revision number from the
+				 * header files */
+{
+    int exact = 0;
+    const char *packageName = "tcl::tommath";
+    const char *errMsg = NULL;
+    TclTomMathStubs *stubsPtr = NULL;
+    const char *actualVersion = tclStubsPtr->tcl_PkgRequireEx(interp,
+	    packageName, version, exact, &stubsPtr);
+
+    if (actualVersion == NULL) {
+	return NULL;
+    }
+    if (stubsPtr == NULL) {
+	errMsg = "missing stub table pointer";
+    } else if(stubsPtr->tclBN_epoch() != epoch) {
+	errMsg = "epoch number mismatch";
+    } else if(stubsPtr->tclBN_revision() != revision) {
+	errMsg = "requires a later revision";
+    } else {
+	tclTomMathStubsPtr = stubsPtr;
+	return actualVersion;
+    }
+    tclStubsPtr->tcl_ResetResult(interp);
+    tclStubsPtr->tcl_AppendResult(interp, "Error loading ", packageName,
+	    " (requested version ", version, ", actual version ",
+	    actualVersion, "): ", errMsg, NULL);
+    return NULL;
+}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tclTrace.c b/generic/tclTrace.c
new file mode 100644
index 0000000..4e74c54
--- /dev/null
+++ b/generic/tclTrace.c
@@ -0,0 +1,3271 @@
+/*
+ * tclTrace.c --
+ *
+ *	This file contains code to handle most trace management.
+ *
+ * Copyright (c) 1987-1993 The Regents of the University of California.
+ * Copyright (c) 1994-1997 Sun Microsystems, Inc.
+ * Copyright (c) 1998-2000 Scriptics Corporation.
+ * Copyright (c) 2002 ActiveState Corporation.
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#include "tclInt.h"
+
+/*
+ * Structures used to hold information about variable traces:
+ */
+
+typedef struct {
+    int flags;			/* Operations for which Tcl command is to be
+				 * invoked. */
+    size_t length;		/* Number of non-NUL chars. in command. */
+    char command[1];		/* Space for Tcl command to invoke. Actual
+				 * size will be as large as necessary to hold
+				 * command. This field must be the last in the
+				 * structure, so that it can be larger than 1
+				 * byte. */
+} TraceVarInfo;
+
+typedef struct {
+    VarTrace traceInfo;
+    TraceVarInfo traceCmdInfo;
+} CombinedTraceVarInfo;
+
+/*
+ * Structure used to hold information about command traces:
+ */
+
+typedef struct {
+    int flags;			/* Operations for which Tcl command is to be
+				 * invoked. */
+    size_t length;		/* Number of non-NUL chars. in command. */
+    Tcl_Trace stepTrace;	/* Used for execution traces, when tracing
+				 * inside the given command */
+    int startLevel;		/* Used for bookkeeping with step execution
+				 * traces, store the level at which the step
+				 * trace was invoked */
+    char *startCmd;		/* Used for bookkeeping with step execution
+				 * traces, store the command name which
+				 * invoked step trace */
+    int curFlags;		/* Trace flags for the current command */
+    int curCode;		/* Return code for the current command */
+    int refCount;		/* Used to ensure this structure is not
+				 * deleted too early. Keeps track of how many
+				 * pieces of code have a pointer to this
+				 * structure. */
+    char command[1];		/* Space for Tcl command to invoke. Actual
+				 * size will be as large as necessary to hold
+				 * command. This field must be the last in the
+				 * structure, so that it can be larger than 1
+				 * byte. */
+} TraceCommandInfo;
+
+/*
+ * Used by command execution traces. Note that we assume in the code that
+ * TCL_TRACE_ENTER_DURING_EXEC == 4 * TCL_TRACE_ENTER_EXEC and that
+ * TCL_TRACE_LEAVE_DURING_EXEC == 4 * TCL_TRACE_LEAVE_EXEC.
+ *
+ * TCL_TRACE_ENTER_DURING_EXEC  - Trace each command inside the command
+ *				  currently being traced, before execution.
+ * TCL_TRACE_LEAVE_DURING_EXEC  - Trace each command inside the command
+ *				  currently being traced, after execution.
+ * TCL_TRACE_ANY_EXEC		- OR'd combination of all EXEC flags.
+ * TCL_TRACE_EXEC_IN_PROGRESS   - The callback function on this trace is
+ *				  currently executing. Therefore we don't let
+ *				  further traces execute.
+ * TCL_TRACE_EXEC_DIRECT	- This execution trace is triggered directly
+ *				  by the command being traced, not because of
+ *				  an internal trace.
+ * The flags 'TCL_TRACE_DESTROYED' and 'TCL_INTERP_DESTROYED' may also be used
+ * in command execution traces.
+ */
+
+#define TCL_TRACE_ENTER_DURING_EXEC	4
+#define TCL_TRACE_LEAVE_DURING_EXEC	8
+#define TCL_TRACE_ANY_EXEC		15
+#define TCL_TRACE_EXEC_IN_PROGRESS	0x10
+#define TCL_TRACE_EXEC_DIRECT		0x20
+
+/*
+ * Forward declarations for functions defined in this file:
+ */
+
+typedef int (Tcl_TraceTypeObjCmd)(Tcl_Interp *interp, int optionIndex,
+	int objc, Tcl_Obj *const objv[]);
+
+static Tcl_TraceTypeObjCmd TraceVariableObjCmd;
+static Tcl_TraceTypeObjCmd TraceCommandObjCmd;
+static Tcl_TraceTypeObjCmd TraceExecutionObjCmd;
+
+/*
+ * Each subcommand has a number of 'types' to which it can apply. Currently
+ * 'execution', 'command' and 'variable' are the only types supported. These
+ * three arrays MUST be kept in sync! In the future we may provide an API to
+ * add to the list of supported trace types.
+ */
+
+static const char *const traceTypeOptions[] = {
+    "execution", "command", "variable", NULL
+};
+static Tcl_TraceTypeObjCmd *const traceSubCmds[] = {
+    TraceExecutionObjCmd,
+    TraceCommandObjCmd,
+    TraceVariableObjCmd
+};
+
+/*
+ * Declarations for local functions to this file:
+ */
+
+static int		CallTraceFunction(Tcl_Interp *interp, Trace *tracePtr,
+			    Command *cmdPtr, const char *command, int numChars,
+			    int objc, Tcl_Obj *const objv[]);
+static char *		TraceVarProc(ClientData clientData, Tcl_Interp *interp,
+			    const char *name1, const char *name2, int flags);
+static void		TraceCommandProc(ClientData clientData,
+			    Tcl_Interp *interp, const char *oldName,
+			    const char *newName, int flags);
+static Tcl_CmdObjTraceProc TraceExecutionProc;
+static int		StringTraceProc(ClientData clientData,
+			    Tcl_Interp *interp, int level,
+			    const char *command, Tcl_Command commandInfo,
+			    int objc, Tcl_Obj *const objv[]);
+static void		StringTraceDeleteProc(ClientData clientData);
+static void		DisposeTraceResult(int flags, char *result);
+static int		TraceVarEx(Tcl_Interp *interp, const char *part1,
+			    const char *part2, register VarTrace *tracePtr);
+
+/*
+ * The following structure holds the client data for string-based
+ * trace procs
+ */
+
+typedef struct StringTraceData {
+    ClientData clientData;	/* Client data from Tcl_CreateTrace */
+    Tcl_CmdTraceProc *proc;	/* Trace function from Tcl_CreateTrace */
+} StringTraceData;
+
+/*
+ * Convenience macros for iterating over the list of traces. Note that each of
+ * these *must* be treated as a command, and *must* have a block following it.
+ */
+
+#define FOREACH_VAR_TRACE(interp, name, clientData) \
+    (clientData) = NULL; \
+    while (((clientData) = Tcl_VarTraceInfo2((interp), (name), NULL, \
+	    0, TraceVarProc, (clientData))) != NULL)
+
+#define FOREACH_COMMAND_TRACE(interp, name, clientData) \
+    (clientData) = NULL; \
+    while ((clientData = Tcl_CommandTraceInfo(interp, name, 0, \
+	    TraceCommandProc, clientData)) != NULL)
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_TraceObjCmd --
+ *
+ *	This function is invoked to process the "trace" Tcl command. See the
+ *	user documentation for details on what it does.
+ *
+ *	Standard syntax as of Tcl 8.4 is:
+ *	    trace {add|info|remove} {command|variable} name ops cmd
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *----------------------------------------------------------------------
+ */
+
+	/* ARGSUSED */
+int
+Tcl_TraceObjCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    int optionIndex;
+    const char *name;
+    const char *flagOps, *p;
+    /* Main sub commands to 'trace' */
+    static const char *const traceOptions[] = {
+	"add", "info", "remove",
+#ifndef TCL_REMOVE_OBSOLETE_TRACES
+	"variable", "vdelete", "vinfo",
+#endif
+	NULL
+    };
+    /* 'OLD' options are pre-Tcl-8.4 style */
+    enum traceOptions {
+	TRACE_ADD, TRACE_INFO, TRACE_REMOVE,
+#ifndef TCL_REMOVE_OBSOLETE_TRACES
+	TRACE_OLD_VARIABLE, TRACE_OLD_VDELETE, TRACE_OLD_VINFO
+#endif
+    };
+
+    if (objc < 2) {
+	Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?");
+	return TCL_ERROR;
+    }
+
+    if (Tcl_GetIndexFromObj(interp, objv[1], traceOptions, "option", 0,
+	    &optionIndex) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    switch ((enum traceOptions) optionIndex) {
+    case TRACE_ADD:
+    case TRACE_REMOVE: {
+	/*
+	 * All sub commands of trace add/remove must take at least one more
+	 * argument. Beyond that we let the subcommand itself control the
+	 * argument structure.
+	 */
+
+	int typeIndex;
+
+	if (objc < 3) {
+	    Tcl_WrongNumArgs(interp, 2, objv, "type ?arg ...?");
+	    return TCL_ERROR;
+	}
+	if (Tcl_GetIndexFromObj(interp, objv[2], traceTypeOptions, "option",
+		0, &typeIndex) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	return traceSubCmds[typeIndex](interp, optionIndex, objc, objv);
+    }
+    case TRACE_INFO: {
+	/*
+	 * All sub commands of trace info must take exactly two more arguments
+	 * which name the type of thing being traced and the name of the thing
+	 * being traced.
+	 */
+
+	int typeIndex;
+	if (objc < 3) {
+	    /*
+	     * Delegate other complaints to the type-specific code which can
+	     * give a better error message.
+	     */
+
+	    Tcl_WrongNumArgs(interp, 2, objv, "type name");
+	    return TCL_ERROR;
+	}
+	if (Tcl_GetIndexFromObj(interp, objv[2], traceTypeOptions, "option",
+		0, &typeIndex) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	return traceSubCmds[typeIndex](interp, optionIndex, objc, objv);
+	break;
+    }
+
+#ifndef TCL_REMOVE_OBSOLETE_TRACES
+    case TRACE_OLD_VARIABLE:
+    case TRACE_OLD_VDELETE: {
+	Tcl_Obj *copyObjv[6];
+	Tcl_Obj *opsList;
+	int code, numFlags;
+
+	if (objc != 5) {
+	    Tcl_WrongNumArgs(interp, 2, objv, "name ops command");
+	    return TCL_ERROR;
+	}
+
+	opsList = Tcl_NewObj();
+	Tcl_IncrRefCount(opsList);
+	flagOps = Tcl_GetStringFromObj(objv[3], &numFlags);
+	if (numFlags == 0) {
+	    Tcl_DecrRefCount(opsList);
+	    goto badVarOps;
+	}
+	for (p = flagOps; *p != 0; p++) {
+	    Tcl_Obj *opObj;
+
+	    if (*p == 'r') {
+		TclNewLiteralStringObj(opObj, "read");
+	    } else if (*p == 'w') {
+		TclNewLiteralStringObj(opObj, "write");
+	    } else if (*p == 'u') {
+		TclNewLiteralStringObj(opObj, "unset");
+	    } else if (*p == 'a') {
+		TclNewLiteralStringObj(opObj, "array");
+	    } else {
+		Tcl_DecrRefCount(opsList);
+		goto badVarOps;
+	    }
+	    Tcl_ListObjAppendElement(NULL, opsList, opObj);
+	}
+	copyObjv[0] = NULL;
+	memcpy(copyObjv+1, objv, objc*sizeof(Tcl_Obj *));
+	copyObjv[4] = opsList;
+	if (optionIndex == TRACE_OLD_VARIABLE) {
+	    code = traceSubCmds[2](interp, TRACE_ADD, objc+1, copyObjv);
+	} else {
+	    code = traceSubCmds[2](interp, TRACE_REMOVE, objc+1, copyObjv);
+	}
+	Tcl_DecrRefCount(opsList);
+	return code;
+    }
+    case TRACE_OLD_VINFO: {
+	ClientData clientData;
+	char ops[5];
+	Tcl_Obj *resultListPtr, *pairObjPtr, *elemObjPtr;
+
+	if (objc != 3) {
+	    Tcl_WrongNumArgs(interp, 2, objv, "name");
+	    return TCL_ERROR;
+	}
+	resultListPtr = Tcl_NewObj();
+	name = Tcl_GetString(objv[2]);
+	FOREACH_VAR_TRACE(interp, name, clientData) {
+	    TraceVarInfo *tvarPtr = clientData;
+	    char *q = ops;
+
+	    pairObjPtr = Tcl_NewListObj(0, NULL);
+	    if (tvarPtr->flags & TCL_TRACE_READS) {
+		*q = 'r';
+		q++;
+	    }
+	    if (tvarPtr->flags & TCL_TRACE_WRITES) {
+		*q = 'w';
+		q++;
+	    }
+	    if (tvarPtr->flags & TCL_TRACE_UNSETS) {
+		*q = 'u';
+		q++;
+	    }
+	    if (tvarPtr->flags & TCL_TRACE_ARRAY) {
+		*q = 'a';
+		q++;
+	    }
+	    *q = '\0';
+
+	    /*
+	     * Build a pair (2-item list) with the ops string as the first obj
+	     * element and the tvarPtr->command string as the second obj
+	     * element. Append the pair (as an element) to the end of the
+	     * result object list.
+	     */
+
+	    elemObjPtr = Tcl_NewStringObj(ops, -1);
+	    Tcl_ListObjAppendElement(NULL, pairObjPtr, elemObjPtr);
+	    elemObjPtr = Tcl_NewStringObj(tvarPtr->command, -1);
+	    Tcl_ListObjAppendElement(NULL, pairObjPtr, elemObjPtr);
+	    Tcl_ListObjAppendElement(interp, resultListPtr, pairObjPtr);
+	}
+	Tcl_SetObjResult(interp, resultListPtr);
+	break;
+    }
+#endif /* TCL_REMOVE_OBSOLETE_TRACES */
+    }
+    return TCL_OK;
+
+  badVarOps:
+    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+	    "bad operations \"%s\": should be one or more of rwua",
+	    flagOps));
+    Tcl_SetErrorCode(interp, "TCL", "OPERATION", "TRACE", "BADOPS", NULL);
+    return TCL_ERROR;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TraceExecutionObjCmd --
+ *
+ *	Helper function for Tcl_TraceObjCmd; implements the [trace
+ *	{add|remove|info} execution ...] subcommands. See the user
+ *	documentation for details on what these do.
+ *
+ * Results:
+ *	Standard Tcl result.
+ *
+ * Side effects:
+ *	Depends on the operation (add, remove, or info) being performed; may
+ *	add or remove command traces on a command.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+TraceExecutionObjCmd(
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int optionIndex,		/* Add, info or remove */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    int commandLength, index;
+    const char *name, *command;
+    size_t length;
+    enum traceOptions {
+	TRACE_ADD, TRACE_INFO, TRACE_REMOVE
+    };
+    static const char *const opStrings[] = {
+	"enter", "leave", "enterstep", "leavestep", NULL
+    };
+    enum operations {
+	TRACE_EXEC_ENTER, TRACE_EXEC_LEAVE,
+	TRACE_EXEC_ENTER_STEP, TRACE_EXEC_LEAVE_STEP
+    };
+
+    switch ((enum traceOptions) optionIndex) {
+    case TRACE_ADD:
+    case TRACE_REMOVE: {
+	int flags = 0;
+	int i, listLen, result;
+	Tcl_Obj **elemPtrs;
+
+	if (objc != 6) {
+	    Tcl_WrongNumArgs(interp, 3, objv, "name opList command");
+	    return TCL_ERROR;
+	}
+
+	/*
+	 * Make sure the ops argument is a list object; get its length and a
+	 * pointer to its array of element pointers.
+	 */
+
+	result = Tcl_ListObjGetElements(interp, objv[4], &listLen, &elemPtrs);
+	if (result != TCL_OK) {
+	    return result;
+	}
+	if (listLen == 0) {
+	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		    "bad operation list \"\": must be one or more of"
+		    " enter, leave, enterstep, or leavestep", -1));
+	    Tcl_SetErrorCode(interp, "TCL", "OPERATION", "TRACE", "NOOPS",
+		    NULL);
+	    return TCL_ERROR;
+	}
+	for (i = 0; i < listLen; i++) {
+	    if (Tcl_GetIndexFromObj(interp, elemPtrs[i], opStrings,
+		    "operation", TCL_EXACT, &index) != TCL_OK) {
+		return TCL_ERROR;
+	    }
+	    switch ((enum operations) index) {
+	    case TRACE_EXEC_ENTER:
+		flags |= TCL_TRACE_ENTER_EXEC;
+		break;
+	    case TRACE_EXEC_LEAVE:
+		flags |= TCL_TRACE_LEAVE_EXEC;
+		break;
+	    case TRACE_EXEC_ENTER_STEP:
+		flags |= TCL_TRACE_ENTER_DURING_EXEC;
+		break;
+	    case TRACE_EXEC_LEAVE_STEP:
+		flags |= TCL_TRACE_LEAVE_DURING_EXEC;
+		break;
+	    }
+	}
+	command = Tcl_GetStringFromObj(objv[5], &commandLength);
+	length = (size_t) commandLength;
+	if ((enum traceOptions) optionIndex == TRACE_ADD) {
+	    TraceCommandInfo *tcmdPtr = ckalloc(
+		    TclOffset(TraceCommandInfo, command) + 1 + length);
+
+	    tcmdPtr->flags = flags;
+	    tcmdPtr->stepTrace = NULL;
+	    tcmdPtr->startLevel = 0;
+	    tcmdPtr->startCmd = NULL;
+	    tcmdPtr->length = length;
+	    tcmdPtr->refCount = 1;
+	    flags |= TCL_TRACE_DELETE;
+	    if (flags & (TCL_TRACE_ENTER_DURING_EXEC |
+		    TCL_TRACE_LEAVE_DURING_EXEC)) {
+		flags |= (TCL_TRACE_ENTER_EXEC | TCL_TRACE_LEAVE_EXEC);
+	    }
+	    memcpy(tcmdPtr->command, command, length+1);
+	    name = Tcl_GetString(objv[3]);
+	    if (Tcl_TraceCommand(interp, name, flags, TraceCommandProc,
+		    tcmdPtr) != TCL_OK) {
+		ckfree(tcmdPtr);
+		return TCL_ERROR;
+	    }
+	} else {
+	    /*
+	     * Search through all of our traces on this command to see if
+	     * there's one with the given command. If so, then delete the
+	     * first one that matches.
+	     */
+
+	    ClientData clientData;
+
+	    /*
+	     * First ensure the name given is valid.
+	     */
+
+	    name = Tcl_GetString(objv[3]);
+	    if (Tcl_FindCommand(interp,name,NULL,TCL_LEAVE_ERR_MSG) == NULL) {
+		return TCL_ERROR;
+	    }
+
+	    FOREACH_COMMAND_TRACE(interp, name, clientData) {
+		TraceCommandInfo *tcmdPtr = clientData;
+
+		/*
+		 * In checking the 'flags' field we must remove any extraneous
+		 * flags which may have been temporarily added by various
+		 * pieces of the trace mechanism.
+		 */
+
+		if ((tcmdPtr->length == length)
+			&& ((tcmdPtr->flags & (TCL_TRACE_ANY_EXEC |
+				TCL_TRACE_RENAME | TCL_TRACE_DELETE)) == flags)
+			&& (strncmp(command, tcmdPtr->command,
+				(size_t) length) == 0)) {
+		    flags |= TCL_TRACE_DELETE;
+		    if (flags & (TCL_TRACE_ENTER_DURING_EXEC |
+			    TCL_TRACE_LEAVE_DURING_EXEC)) {
+			flags |= (TCL_TRACE_ENTER_EXEC | TCL_TRACE_LEAVE_EXEC);
+		    }
+		    Tcl_UntraceCommand(interp, name, flags,
+			    TraceCommandProc, clientData);
+		    if (tcmdPtr->stepTrace != NULL) {
+			/*
+			 * We need to remove the interpreter-wide trace which
+			 * we created to allow 'step' traces.
+			 */
+
+			Tcl_DeleteTrace(interp, tcmdPtr->stepTrace);
+			tcmdPtr->stepTrace = NULL;
+			if (tcmdPtr->startCmd != NULL) {
+			    ckfree(tcmdPtr->startCmd);
+			}
+		    }
+		    if (tcmdPtr->flags & TCL_TRACE_EXEC_IN_PROGRESS) {
+			/*
+			 * Postpone deletion.
+			 */
+
+			tcmdPtr->flags = 0;
+		    }
+		    if (tcmdPtr->refCount-- <= 1) {
+			ckfree(tcmdPtr);
+		    }
+		    break;
+		}
+	    }
+	}
+	break;
+    }
+    case TRACE_INFO: {
+	ClientData clientData;
+	Tcl_Obj *resultListPtr;
+
+	if (objc != 4) {
+	    Tcl_WrongNumArgs(interp, 3, objv, "name");
+	    return TCL_ERROR;
+	}
+
+	name = Tcl_GetString(objv[3]);
+
+	/*
+	 * First ensure the name given is valid.
+	 */
+
+	if (Tcl_FindCommand(interp, name, NULL, TCL_LEAVE_ERR_MSG) == NULL) {
+	    return TCL_ERROR;
+	}
+
+	resultListPtr = Tcl_NewListObj(0, NULL);
+	FOREACH_COMMAND_TRACE(interp, name, clientData) {
+	    int numOps = 0;
+	    Tcl_Obj *opObj, *eachTraceObjPtr, *elemObjPtr;
+	    TraceCommandInfo *tcmdPtr = clientData;
+
+	    /*
+	     * Build a list with the ops list as the first obj element and the
+	     * tcmdPtr->command string as the second obj element. Append this
+	     * list (as an element) to the end of the result object list.
+	     */
+
+	    elemObjPtr = Tcl_NewListObj(0, NULL);
+	    Tcl_IncrRefCount(elemObjPtr);
+	    if (tcmdPtr->flags & TCL_TRACE_ENTER_EXEC) {
+		TclNewLiteralStringObj(opObj, "enter");
+		Tcl_ListObjAppendElement(NULL, elemObjPtr, opObj);
+	    }
+	    if (tcmdPtr->flags & TCL_TRACE_LEAVE_EXEC) {
+		TclNewLiteralStringObj(opObj, "leave");
+		Tcl_ListObjAppendElement(NULL, elemObjPtr, opObj);
+	    }
+	    if (tcmdPtr->flags & TCL_TRACE_ENTER_DURING_EXEC) {
+		TclNewLiteralStringObj(opObj, "enterstep");
+		Tcl_ListObjAppendElement(NULL, elemObjPtr, opObj);
+	    }
+	    if (tcmdPtr->flags & TCL_TRACE_LEAVE_DURING_EXEC) {
+		TclNewLiteralStringObj(opObj, "leavestep");
+		Tcl_ListObjAppendElement(NULL, elemObjPtr, opObj);
+	    }
+	    Tcl_ListObjLength(NULL, elemObjPtr, &numOps);
+	    if (0 == numOps) {
+		Tcl_DecrRefCount(elemObjPtr);
+		continue;
+	    }
+	    eachTraceObjPtr = Tcl_NewListObj(0, NULL);
+	    Tcl_ListObjAppendElement(NULL, eachTraceObjPtr, elemObjPtr);
+	    Tcl_DecrRefCount(elemObjPtr);
+	    elemObjPtr = NULL;
+
+	    Tcl_ListObjAppendElement(NULL, eachTraceObjPtr,
+		    Tcl_NewStringObj(tcmdPtr->command, -1));
+	    Tcl_ListObjAppendElement(interp, resultListPtr, eachTraceObjPtr);
+	}
+	Tcl_SetObjResult(interp, resultListPtr);
+	break;
+    }
+    }
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TraceCommandObjCmd --
+ *
+ *	Helper function for Tcl_TraceObjCmd; implements the [trace
+ *	{add|info|remove} command ...] subcommands. See the user documentation
+ *	for details on what these do.
+ *
+ * Results:
+ *	Standard Tcl result.
+ *
+ * Side effects:
+ *	Depends on the operation (add, remove, or info) being performed; may
+ *	add or remove command traces on a command.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+TraceCommandObjCmd(
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int optionIndex,		/* Add, info or remove */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    int commandLength, index;
+    const char *name, *command;
+    size_t length;
+    enum traceOptions { TRACE_ADD, TRACE_INFO, TRACE_REMOVE };
+    static const char *const opStrings[] = { "delete", "rename", NULL };
+    enum operations { TRACE_CMD_DELETE, TRACE_CMD_RENAME };
+
+    switch ((enum traceOptions) optionIndex) {
+    case TRACE_ADD:
+    case TRACE_REMOVE: {
+	int flags = 0;
+	int i, listLen, result;
+	Tcl_Obj **elemPtrs;
+
+	if (objc != 6) {
+	    Tcl_WrongNumArgs(interp, 3, objv, "name opList command");
+	    return TCL_ERROR;
+	}
+
+	/*
+	 * Make sure the ops argument is a list object; get its length and a
+	 * pointer to its array of element pointers.
+	 */
+
+	result = Tcl_ListObjGetElements(interp, objv[4], &listLen, &elemPtrs);
+	if (result != TCL_OK) {
+	    return result;
+	}
+	if (listLen == 0) {
+	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		    "bad operation list \"\": must be one or more of"
+		    " delete or rename", -1));
+	    Tcl_SetErrorCode(interp, "TCL", "OPERATION", "TRACE", "NOOPS",
+		    NULL);
+	    return TCL_ERROR;
+	}
+
+	for (i = 0; i < listLen; i++) {
+	    if (Tcl_GetIndexFromObj(interp, elemPtrs[i], opStrings,
+		    "operation", TCL_EXACT, &index) != TCL_OK) {
+		return TCL_ERROR;
+	    }
+	    switch ((enum operations) index) {
+	    case TRACE_CMD_RENAME:
+		flags |= TCL_TRACE_RENAME;
+		break;
+	    case TRACE_CMD_DELETE:
+		flags |= TCL_TRACE_DELETE;
+		break;
+	    }
+	}
+
+	command = Tcl_GetStringFromObj(objv[5], &commandLength);
+	length = (size_t) commandLength;
+	if ((enum traceOptions) optionIndex == TRACE_ADD) {
+	    TraceCommandInfo *tcmdPtr = ckalloc(
+		    TclOffset(TraceCommandInfo, command) + 1 + length);
+
+	    tcmdPtr->flags = flags;
+	    tcmdPtr->stepTrace = NULL;
+	    tcmdPtr->startLevel = 0;
+	    tcmdPtr->startCmd = NULL;
+	    tcmdPtr->length = length;
+	    tcmdPtr->refCount = 1;
+	    flags |= TCL_TRACE_DELETE;
+	    memcpy(tcmdPtr->command, command, length+1);
+	    name = Tcl_GetString(objv[3]);
+	    if (Tcl_TraceCommand(interp, name, flags, TraceCommandProc,
+		    tcmdPtr) != TCL_OK) {
+		ckfree(tcmdPtr);
+		return TCL_ERROR;
+	    }
+	} else {
+	    /*
+	     * Search through all of our traces on this command to see if
+	     * there's one with the given command. If so, then delete the
+	     * first one that matches.
+	     */
+
+	    ClientData clientData;
+
+	    /*
+	     * First ensure the name given is valid.
+	     */
+
+	    name = Tcl_GetString(objv[3]);
+	    if (Tcl_FindCommand(interp,name,NULL,TCL_LEAVE_ERR_MSG) == NULL) {
+		return TCL_ERROR;
+	    }
+
+	    FOREACH_COMMAND_TRACE(interp, name, clientData) {
+		TraceCommandInfo *tcmdPtr = clientData;
+
+		if ((tcmdPtr->length == length) && (tcmdPtr->flags == flags)
+			&& (strncmp(command, tcmdPtr->command,
+				(size_t) length) == 0)) {
+		    Tcl_UntraceCommand(interp, name, flags | TCL_TRACE_DELETE,
+			    TraceCommandProc, clientData);
+		    tcmdPtr->flags |= TCL_TRACE_DESTROYED;
+		    if (tcmdPtr->refCount-- <= 1) {
+			ckfree(tcmdPtr);
+		    }
+		    break;
+		}
+	    }
+	}
+	break;
+    }
+    case TRACE_INFO: {
+	ClientData clientData;
+	Tcl_Obj *resultListPtr;
+
+	if (objc != 4) {
+	    Tcl_WrongNumArgs(interp, 3, objv, "name");
+	    return TCL_ERROR;
+	}
+
+	/*
+	 * First ensure the name given is valid.
+	 */
+
+	name = Tcl_GetString(objv[3]);
+	if (Tcl_FindCommand(interp, name, NULL, TCL_LEAVE_ERR_MSG) == NULL) {
+	    return TCL_ERROR;
+	}
+
+	resultListPtr = Tcl_NewListObj(0, NULL);
+	FOREACH_COMMAND_TRACE(interp, name, clientData) {
+	    int numOps = 0;
+	    Tcl_Obj *opObj, *eachTraceObjPtr, *elemObjPtr;
+	    TraceCommandInfo *tcmdPtr = clientData;
+
+	    /*
+	     * Build a list with the ops list as the first obj element and the
+	     * tcmdPtr->command string as the second obj element. Append this
+	     * list (as an element) to the end of the result object list.
+	     */
+
+	    elemObjPtr = Tcl_NewListObj(0, NULL);
+	    Tcl_IncrRefCount(elemObjPtr);
+	    if (tcmdPtr->flags & TCL_TRACE_RENAME) {
+		TclNewLiteralStringObj(opObj, "rename");
+		Tcl_ListObjAppendElement(NULL, elemObjPtr, opObj);
+	    }
+	    if (tcmdPtr->flags & TCL_TRACE_DELETE) {
+		TclNewLiteralStringObj(opObj, "delete");
+		Tcl_ListObjAppendElement(NULL, elemObjPtr, opObj);
+	    }
+	    Tcl_ListObjLength(NULL, elemObjPtr, &numOps);
+	    if (0 == numOps) {
+		Tcl_DecrRefCount(elemObjPtr);
+		continue;
+	    }
+	    eachTraceObjPtr = Tcl_NewListObj(0, NULL);
+	    Tcl_ListObjAppendElement(NULL, eachTraceObjPtr, elemObjPtr);
+	    Tcl_DecrRefCount(elemObjPtr);
+
+	    elemObjPtr = Tcl_NewStringObj(tcmdPtr->command, -1);
+	    Tcl_ListObjAppendElement(NULL, eachTraceObjPtr, elemObjPtr);
+	    Tcl_ListObjAppendElement(interp, resultListPtr, eachTraceObjPtr);
+	}
+	Tcl_SetObjResult(interp, resultListPtr);
+	break;
+    }
+    }
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TraceVariableObjCmd --
+ *
+ *	Helper function for Tcl_TraceObjCmd; implements the [trace
+ *	{add|info|remove} variable ...] subcommands. See the user
+ *	documentation for details on what these do.
+ *
+ * Results:
+ *	Standard Tcl result.
+ *
+ * Side effects:
+ *	Depends on the operation (add, remove, or info) being performed; may
+ *	add or remove variable traces on a variable.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+TraceVariableObjCmd(
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int optionIndex,		/* Add, info or remove */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    int commandLength, index;
+    const char *name, *command;
+    size_t length;
+    ClientData clientData;
+    enum traceOptions { TRACE_ADD, TRACE_INFO, TRACE_REMOVE };
+    static const char *const opStrings[] = {
+	"array", "read", "unset", "write", NULL
+    };
+    enum operations {
+	TRACE_VAR_ARRAY, TRACE_VAR_READ, TRACE_VAR_UNSET, TRACE_VAR_WRITE
+    };
+
+    switch ((enum traceOptions) optionIndex) {
+    case TRACE_ADD:
+    case TRACE_REMOVE: {
+	int flags = 0;
+	int i, listLen, result;
+	Tcl_Obj **elemPtrs;
+
+	if (objc != 6) {
+	    Tcl_WrongNumArgs(interp, 3, objv, "name opList command");
+	    return TCL_ERROR;
+	}
+
+	/*
+	 * Make sure the ops argument is a list object; get its length and a
+	 * pointer to its array of element pointers.
+	 */
+
+	result = Tcl_ListObjGetElements(interp, objv[4], &listLen, &elemPtrs);
+	if (result != TCL_OK) {
+	    return result;
+	}
+	if (listLen == 0) {
+	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		    "bad operation list \"\": must be one or more of"
+		    " array, read, unset, or write", -1));
+	    Tcl_SetErrorCode(interp, "TCL", "OPERATION", "TRACE", "NOOPS",
+		    NULL);
+	    return TCL_ERROR;
+	}
+	for (i = 0; i < listLen ; i++) {
+	    if (Tcl_GetIndexFromObj(interp, elemPtrs[i], opStrings,
+		    "operation", TCL_EXACT, &index) != TCL_OK) {
+		return TCL_ERROR;
+	    }
+	    switch ((enum operations) index) {
+	    case TRACE_VAR_ARRAY:
+		flags |= TCL_TRACE_ARRAY;
+		break;
+	    case TRACE_VAR_READ:
+		flags |= TCL_TRACE_READS;
+		break;
+	    case TRACE_VAR_UNSET:
+		flags |= TCL_TRACE_UNSETS;
+		break;
+	    case TRACE_VAR_WRITE:
+		flags |= TCL_TRACE_WRITES;
+		break;
+	    }
+	}
+	command = Tcl_GetStringFromObj(objv[5], &commandLength);
+	length = (size_t) commandLength;
+	if ((enum traceOptions) optionIndex == TRACE_ADD) {
+	    CombinedTraceVarInfo *ctvarPtr = ckalloc(
+		    TclOffset(CombinedTraceVarInfo, traceCmdInfo.command)
+		    + 1 + length);
+
+	    ctvarPtr->traceCmdInfo.flags = flags;
+	    if (objv[0] == NULL) {
+		ctvarPtr->traceCmdInfo.flags |= TCL_TRACE_OLD_STYLE;
+	    }
+	    ctvarPtr->traceCmdInfo.length = length;
+	    flags |= TCL_TRACE_UNSETS | TCL_TRACE_RESULT_OBJECT;
+	    memcpy(ctvarPtr->traceCmdInfo.command, command, length+1);
+	    ctvarPtr->traceInfo.traceProc = TraceVarProc;
+	    ctvarPtr->traceInfo.clientData = &ctvarPtr->traceCmdInfo;
+	    ctvarPtr->traceInfo.flags = flags;
+	    name = Tcl_GetString(objv[3]);
+	    if (TraceVarEx(interp, name, NULL, (VarTrace *) ctvarPtr)
+		    != TCL_OK) {
+		ckfree(ctvarPtr);
+		return TCL_ERROR;
+	    }
+	} else {
+	    /*
+	     * Search through all of our traces on this variable to see if
+	     * there's one with the given command. If so, then delete the
+	     * first one that matches.
+	     */
+
+	    name = Tcl_GetString(objv[3]);
+	    FOREACH_VAR_TRACE(interp, name, clientData) {
+		TraceVarInfo *tvarPtr = clientData;
+
+		if ((tvarPtr->length == length)
+			&& ((tvarPtr->flags & ~TCL_TRACE_OLD_STYLE)==flags)
+			&& (strncmp(command, tvarPtr->command,
+				(size_t) length) == 0)) {
+		    Tcl_UntraceVar2(interp, name, NULL,
+			    flags | TCL_TRACE_UNSETS | TCL_TRACE_RESULT_OBJECT,
+			    TraceVarProc, clientData);
+		    break;
+		}
+	    }
+	}
+	break;
+    }
+    case TRACE_INFO: {
+	Tcl_Obj *resultListPtr;
+
+	if (objc != 4) {
+	    Tcl_WrongNumArgs(interp, 3, objv, "name");
+	    return TCL_ERROR;
+	}
+
+	resultListPtr = Tcl_NewObj();
+	name = Tcl_GetString(objv[3]);
+	FOREACH_VAR_TRACE(interp, name, clientData) {
+	    Tcl_Obj *opObjPtr, *eachTraceObjPtr, *elemObjPtr;
+	    TraceVarInfo *tvarPtr = clientData;
+
+	    /*
+	     * Build a list with the ops list as the first obj element and the
+	     * tcmdPtr->command string as the second obj element. Append this
+	     * list (as an element) to the end of the result object list.
+	     */
+
+	    elemObjPtr = Tcl_NewListObj(0, NULL);
+	    if (tvarPtr->flags & TCL_TRACE_ARRAY) {
+		TclNewLiteralStringObj(opObjPtr, "array");
+		Tcl_ListObjAppendElement(NULL, elemObjPtr, opObjPtr);
+	    }
+	    if (tvarPtr->flags & TCL_TRACE_READS) {
+		TclNewLiteralStringObj(opObjPtr, "read");
+		Tcl_ListObjAppendElement(NULL, elemObjPtr, opObjPtr);
+	    }
+	    if (tvarPtr->flags & TCL_TRACE_WRITES) {
+		TclNewLiteralStringObj(opObjPtr, "write");
+		Tcl_ListObjAppendElement(NULL, elemObjPtr, opObjPtr);
+	    }
+	    if (tvarPtr->flags & TCL_TRACE_UNSETS) {
+		TclNewLiteralStringObj(opObjPtr, "unset");
+		Tcl_ListObjAppendElement(NULL, elemObjPtr, opObjPtr);
+	    }
+	    eachTraceObjPtr = Tcl_NewListObj(0, NULL);
+	    Tcl_ListObjAppendElement(NULL, eachTraceObjPtr, elemObjPtr);
+
+	    elemObjPtr = Tcl_NewStringObj(tvarPtr->command, -1);
+	    Tcl_ListObjAppendElement(NULL, eachTraceObjPtr, elemObjPtr);
+	    Tcl_ListObjAppendElement(interp, resultListPtr,
+		    eachTraceObjPtr);
+	}
+	Tcl_SetObjResult(interp, resultListPtr);
+	break;
+    }
+    }
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_CommandTraceInfo --
+ *
+ *	Return the clientData value associated with a trace on a command.
+ *	This function can also be used to step through all of the traces on a
+ *	particular command that have the same trace function.
+ *
+ * Results:
+ *	The return value is the clientData value associated with a trace on
+ *	the given command. Information will only be returned for a trace with
+ *	proc as trace function. If the clientData argument is NULL then the
+ *	first such trace is returned; otherwise, the next relevant one after
+ *	the one given by clientData will be returned. If the command doesn't
+ *	exist then an error message is left in the interpreter and NULL is
+ *	returned. Also, if there are no (more) traces for the given command,
+ *	NULL is returned.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+ClientData
+Tcl_CommandTraceInfo(
+    Tcl_Interp *interp,		/* Interpreter containing command. */
+    const char *cmdName,	/* Name of command. */
+    int flags,			/* OR-ed combo or TCL_GLOBAL_ONLY,
+				 * TCL_NAMESPACE_ONLY (can be 0). */
+    Tcl_CommandTraceProc *proc,	/* Function assocated with trace. */
+    ClientData prevClientData)	/* If non-NULL, gives last value returned by
+				 * this function, so this call will return the
+				 * next trace after that one. If NULL, this
+				 * call will return the first trace. */
+{
+    Command *cmdPtr;
+    register CommandTrace *tracePtr;
+
+    cmdPtr = (Command *) Tcl_FindCommand(interp, cmdName, NULL,
+	    TCL_LEAVE_ERR_MSG);
+    if (cmdPtr == NULL) {
+	return NULL;
+    }
+
+    /*
+     * Find the relevant trace, if any, and return its clientData.
+     */
+
+    tracePtr = cmdPtr->tracePtr;
+    if (prevClientData != NULL) {
+	for (; tracePtr!=NULL ; tracePtr=tracePtr->nextPtr) {
+	    if ((tracePtr->clientData == prevClientData)
+		    && (tracePtr->traceProc == proc)) {
+		tracePtr = tracePtr->nextPtr;
+		break;
+	    }
+	}
+    }
+    for (; tracePtr!=NULL ; tracePtr=tracePtr->nextPtr) {
+	if (tracePtr->traceProc == proc) {
+	    return tracePtr->clientData;
+	}
+    }
+    return NULL;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_TraceCommand --
+ *
+ *	Arrange for rename/deletes to a command to cause a function to be
+ *	invoked, which can monitor the operations.
+ *
+ *	Also optionally arrange for execution of that command to cause a
+ *	function to be invoked.
+ *
+ * Results:
+ *	A standard Tcl return value.
+ *
+ * Side effects:
+ *	A trace is set up on the command given by cmdName, such that future
+ *	changes to the command will be intermediated by proc. See the manual
+ *	entry for complete details on the calling sequence for proc.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_TraceCommand(
+    Tcl_Interp *interp,		/* Interpreter in which command is to be
+				 * traced. */
+    const char *cmdName,	/* Name of command. */
+    int flags,			/* OR-ed collection of bits, including any of
+				 * TCL_TRACE_RENAME, TCL_TRACE_DELETE, and any
+				 * of the TRACE_*_EXEC flags */
+    Tcl_CommandTraceProc *proc,	/* Function to call when specified ops are
+				 * invoked upon cmdName. */
+    ClientData clientData)	/* Arbitrary argument to pass to proc. */
+{
+    Command *cmdPtr;
+    register CommandTrace *tracePtr;
+
+    cmdPtr = (Command *) Tcl_FindCommand(interp, cmdName, NULL,
+	    TCL_LEAVE_ERR_MSG);
+    if (cmdPtr == NULL) {
+	return TCL_ERROR;
+    }
+
+    /*
+     * Set up trace information.
+     */
+
+    tracePtr = ckalloc(sizeof(CommandTrace));
+    tracePtr->traceProc = proc;
+    tracePtr->clientData = clientData;
+    tracePtr->flags = flags &
+	    (TCL_TRACE_RENAME | TCL_TRACE_DELETE | TCL_TRACE_ANY_EXEC);
+    tracePtr->nextPtr = cmdPtr->tracePtr;
+    tracePtr->refCount = 1;
+    cmdPtr->tracePtr = tracePtr;
+    if (tracePtr->flags & TCL_TRACE_ANY_EXEC) {
+	/*
+	 * Bug 3484621: up the interp's epoch if this is a BC'ed command
+	 */
+
+	if ((cmdPtr->compileProc != NULL) && !(cmdPtr->flags & CMD_HAS_EXEC_TRACES)){
+	    Interp *iPtr = (Interp *) interp;
+	    iPtr->compileEpoch++;
+	}
+	cmdPtr->flags |= CMD_HAS_EXEC_TRACES;
+    }
+
+
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_UntraceCommand --
+ *
+ *	Remove a previously-created trace for a command.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	If there exists a trace for the command given by cmdName with the
+ *	given flags, proc, and clientData, then that trace is removed.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_UntraceCommand(
+    Tcl_Interp *interp,		/* Interpreter containing command. */
+    const char *cmdName,	/* Name of command. */
+    int flags,			/* OR-ed collection of bits, including any of
+				 * TCL_TRACE_RENAME, TCL_TRACE_DELETE, and any
+				 * of the TRACE_*_EXEC flags */
+    Tcl_CommandTraceProc *proc,	/* Function assocated with trace. */
+    ClientData clientData)	/* Arbitrary argument to pass to proc. */
+{
+    register CommandTrace *tracePtr;
+    CommandTrace *prevPtr;
+    Command *cmdPtr;
+    Interp *iPtr = (Interp *) interp;
+    ActiveCommandTrace *activePtr;
+    int hasExecTraces = 0;
+
+    cmdPtr = (Command *) Tcl_FindCommand(interp, cmdName, NULL,
+	    TCL_LEAVE_ERR_MSG);
+    if (cmdPtr == NULL) {
+	return;
+    }
+
+    flags &= (TCL_TRACE_RENAME | TCL_TRACE_DELETE | TCL_TRACE_ANY_EXEC);
+
+    for (tracePtr = cmdPtr->tracePtr, prevPtr = NULL; ;
+	    prevPtr = tracePtr, tracePtr = tracePtr->nextPtr) {
+	if (tracePtr == NULL) {
+	    return;
+	}
+	if ((tracePtr->traceProc == proc)
+		&& ((tracePtr->flags & (TCL_TRACE_RENAME | TCL_TRACE_DELETE |
+			TCL_TRACE_ANY_EXEC)) == flags)
+		&& (tracePtr->clientData == clientData)) {
+	    if (tracePtr->flags & TCL_TRACE_ANY_EXEC) {
+		hasExecTraces = 1;
+	    }
+	    break;
+	}
+    }
+
+    /*
+     * The code below makes it possible to delete traces while traces are
+     * active: it makes sure that the deleted trace won't be processed by
+     * CallCommandTraces.
+     */
+
+    for (activePtr = iPtr->activeCmdTracePtr;  activePtr != NULL;
+	    activePtr = activePtr->nextPtr) {
+	if (activePtr->nextTracePtr == tracePtr) {
+	    if (activePtr->reverseScan) {
+		activePtr->nextTracePtr = prevPtr;
+	    } else {
+		activePtr->nextTracePtr = tracePtr->nextPtr;
+	    }
+	}
+    }
+    if (prevPtr == NULL) {
+	cmdPtr->tracePtr = tracePtr->nextPtr;
+    } else {
+	prevPtr->nextPtr = tracePtr->nextPtr;
+    }
+    tracePtr->flags = 0;
+
+    if (tracePtr->refCount-- <= 1) {
+	ckfree(tracePtr);
+    }
+
+    if (hasExecTraces) {
+	for (tracePtr = cmdPtr->tracePtr, prevPtr = NULL; tracePtr != NULL ;
+		prevPtr = tracePtr, tracePtr = tracePtr->nextPtr) {
+	    if (tracePtr->flags & TCL_TRACE_ANY_EXEC) {
+		return;
+	    }
+	}
+
+	/*
+	 * None of the remaining traces on this command are execution traces.
+	 * We therefore remove this flag:
+	 */
+
+	cmdPtr->flags &= ~CMD_HAS_EXEC_TRACES;
+
+        /*
+	 * Bug 3484621: up the interp's epoch if this is a BC'ed command
+	 */
+
+	if (cmdPtr->compileProc != NULL) {
+	    Interp *iPtr = (Interp *) interp;
+	    iPtr->compileEpoch++;
+	}
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TraceCommandProc --
+ *
+ *	This function is called to handle command changes that have been
+ *	traced using the "trace" command, when using the 'rename' or 'delete'
+ *	options.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Depends on the command associated with the trace.
+ *
+ *----------------------------------------------------------------------
+ */
+
+	/* ARGSUSED */
+static void
+TraceCommandProc(
+    ClientData clientData,	/* Information about the command trace. */
+    Tcl_Interp *interp,		/* Interpreter containing command. */
+    const char *oldName,	/* Name of command being changed. */
+    const char *newName,	/* New name of command. Empty string or NULL
+				 * means command is being deleted (renamed to
+				 * ""). */
+    int flags)			/* OR-ed bits giving operation and other
+				 * information. */
+{
+    TraceCommandInfo *tcmdPtr = clientData;
+    int code;
+    Tcl_DString cmd;
+
+    tcmdPtr->refCount++;
+
+    if ((tcmdPtr->flags & flags) && !Tcl_InterpDeleted(interp)
+	    && !Tcl_LimitExceeded(interp)) {
+	/*
+	 * Generate a command to execute by appending list elements for the
+	 * old and new command name and the operation.
+	 */
+
+	Tcl_DStringInit(&cmd);
+	Tcl_DStringAppend(&cmd, tcmdPtr->command, (int) tcmdPtr->length);
+	Tcl_DStringAppendElement(&cmd, oldName);
+	Tcl_DStringAppendElement(&cmd, (newName ? newName : ""));
+	if (flags & TCL_TRACE_RENAME) {
+	    TclDStringAppendLiteral(&cmd, " rename");
+	} else if (flags & TCL_TRACE_DELETE) {
+	    TclDStringAppendLiteral(&cmd, " delete");
+	}
+
+	/*
+	 * Execute the command. We discard any object result the command
+	 * returns.
+	 *
+	 * Add the TCL_TRACE_DESTROYED flag to tcmdPtr to indicate to other
+	 * areas that this will be destroyed by us, otherwise a double-free
+	 * might occur depending on what the eval does.
+	 */
+
+	if (flags & TCL_TRACE_DESTROYED) {
+	    tcmdPtr->flags |= TCL_TRACE_DESTROYED;
+	}
+	code = Tcl_EvalEx(interp, Tcl_DStringValue(&cmd),
+		Tcl_DStringLength(&cmd), 0);
+	if (code != TCL_OK) {
+	    /* We ignore errors in these traced commands */
+	    /*** QUESTION: Use Tcl_BackgroundException(interp, code); instead? ***/
+	}
+	Tcl_DStringFree(&cmd);
+    }
+
+    /*
+     * We delete when the trace was destroyed or if this is a delete trace,
+     * because command deletes are unconditional, so the trace must go away.
+     */
+
+    if (flags & (TCL_TRACE_DESTROYED | TCL_TRACE_DELETE)) {
+	int untraceFlags = tcmdPtr->flags;
+	Tcl_InterpState state;
+
+	if (tcmdPtr->stepTrace != NULL) {
+	    Tcl_DeleteTrace(interp, tcmdPtr->stepTrace);
+	    tcmdPtr->stepTrace = NULL;
+	    if (tcmdPtr->startCmd != NULL) {
+		ckfree(tcmdPtr->startCmd);
+	    }
+	}
+	if (tcmdPtr->flags & TCL_TRACE_EXEC_IN_PROGRESS) {
+	    /*
+	     * Postpone deletion, until exec trace returns.
+	     */
+
+	    tcmdPtr->flags = 0;
+	}
+
+	/*
+	 * We need to construct the same flags for Tcl_UntraceCommand as were
+	 * passed to Tcl_TraceCommand. Reproduce the processing of [trace add
+	 * execution/command]. Be careful to keep this code in sync with that.
+	 */
+
+	if (untraceFlags & TCL_TRACE_ANY_EXEC) {
+	    untraceFlags |= TCL_TRACE_DELETE;
+	    if (untraceFlags & (TCL_TRACE_ENTER_DURING_EXEC
+		    | TCL_TRACE_LEAVE_DURING_EXEC)) {
+		untraceFlags |= (TCL_TRACE_ENTER_EXEC | TCL_TRACE_LEAVE_EXEC);
+	    }
+	} else if (untraceFlags & TCL_TRACE_RENAME) {
+	    untraceFlags |= TCL_TRACE_DELETE;
+	}
+
+	/*
+	 * Remove the trace since TCL_TRACE_DESTROYED tells us to, or the
+	 * command we're tracing has just gone away. Then decrement the
+	 * clientData refCount that was set up by trace creation.
+	 *
+	 * Note that we save the (return) state of the interpreter to prevent
+	 * bizarre error messages.
+	 */
+
+	state = Tcl_SaveInterpState(interp, TCL_OK);
+	Tcl_UntraceCommand(interp, oldName, untraceFlags,
+		TraceCommandProc, clientData);
+	Tcl_RestoreInterpState(interp, state);
+	tcmdPtr->refCount--;
+    }
+    if (tcmdPtr->refCount-- <= 1) {
+	ckfree(tcmdPtr);
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclCheckExecutionTraces --
+ *
+ *	Checks on all current command execution traces, and invokes functions
+ *	which have been registered. This function can be used by other code
+ *	which performs execution to unify the tracing system, so that
+ *	execution traces will function for that other code.
+ *
+ *	For instance extensions like [incr Tcl] which use their own execution
+ *	technique can make use of Tcl's tracing.
+ *
+ *	This function is called by 'TclEvalObjvInternal'
+ *
+ * Results:
+ *	The return value is a standard Tcl completion code such as TCL_OK or
+ *	TCL_ERROR, etc.
+ *
+ * Side effects:
+ *	Those side effects made by any trace functions called.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclCheckExecutionTraces(
+    Tcl_Interp *interp,		/* The current interpreter. */
+    const char *command,	/* Pointer to beginning of the current command
+				 * string. */
+    int numChars,		/* The number of characters in 'command' which
+				 * are part of the command string. */
+    Command *cmdPtr,		/* Points to command's Command struct. */
+    int code,			/* The current result code. */
+    int traceFlags,		/* Current tracing situation. */
+    int objc,			/* Number of arguments for the command. */
+    Tcl_Obj *const objv[])	/* Pointers to Tcl_Obj of each argument. */
+{
+    Interp *iPtr = (Interp *) interp;
+    CommandTrace *tracePtr, *lastTracePtr;
+    ActiveCommandTrace active;
+    int curLevel;
+    int traceCode = TCL_OK;
+    Tcl_InterpState state = NULL;
+
+    if (cmdPtr->tracePtr == NULL) {
+	return traceCode;
+    }
+
+    curLevel = iPtr->varFramePtr->level;
+
+    active.nextPtr = iPtr->activeCmdTracePtr;
+    iPtr->activeCmdTracePtr = &active;
+
+    active.cmdPtr = cmdPtr;
+    lastTracePtr = NULL;
+    for (tracePtr = cmdPtr->tracePtr;
+	    (traceCode == TCL_OK) && (tracePtr != NULL);
+	    tracePtr = active.nextTracePtr) {
+	if (traceFlags & TCL_TRACE_LEAVE_EXEC) {
+	    /*
+	     * Execute the trace command in order of creation for "leave".
+	     */
+
+	    active.reverseScan = 1;
+	    active.nextTracePtr = NULL;
+	    tracePtr = cmdPtr->tracePtr;
+	    while (tracePtr->nextPtr != lastTracePtr) {
+		active.nextTracePtr = tracePtr;
+		tracePtr = tracePtr->nextPtr;
+	    }
+	} else {
+	    active.reverseScan = 0;
+	    active.nextTracePtr = tracePtr->nextPtr;
+	}
+	if (tracePtr->traceProc == TraceCommandProc) {
+	    TraceCommandInfo *tcmdPtr = tracePtr->clientData;
+
+	    if (tcmdPtr->flags != 0) {
+		tcmdPtr->curFlags = traceFlags | TCL_TRACE_EXEC_DIRECT;
+		tcmdPtr->curCode  = code;
+		tcmdPtr->refCount++;
+		if (state == NULL) {
+		    state = Tcl_SaveInterpState(interp, code);
+		}
+		traceCode = TraceExecutionProc(tcmdPtr, interp, curLevel,
+			command, (Tcl_Command) cmdPtr, objc, objv);
+		if (tcmdPtr->refCount-- <= 1) {
+		    ckfree(tcmdPtr);
+		}
+	    }
+	}
+	if (active.nextTracePtr) {
+	    lastTracePtr = active.nextTracePtr->nextPtr;
+	}
+    }
+    iPtr->activeCmdTracePtr = active.nextPtr;
+    if (state) {
+	if (traceCode == TCL_OK) {
+	    (void) Tcl_RestoreInterpState(interp, state);
+	} else {
+	    Tcl_DiscardInterpState(state);
+	}
+    }
+
+    return traceCode;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclCheckInterpTraces --
+ *
+ *	Checks on all current traces, and invokes functions which have been
+ *	registered. This function can be used by other code which performs
+ *	execution to unify the tracing system. For instance extensions like
+ *	[incr Tcl] which use their own execution technique can make use of
+ *	Tcl's tracing.
+ *
+ *	This function is called by 'TclEvalObjvInternal'
+ *
+ * Results:
+ *	The return value is a standard Tcl completion code such as TCL_OK or
+ *	TCL_ERROR, etc.
+ *
+ * Side effects:
+ *	Those side effects made by any trace functions called.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclCheckInterpTraces(
+    Tcl_Interp *interp,		/* The current interpreter. */
+    const char *command,	/* Pointer to beginning of the current command
+				 * string. */
+    int numChars,		/* The number of characters in 'command' which
+				 * are part of the command string. */
+    Command *cmdPtr,		/* Points to command's Command struct. */
+    int code,			/* The current result code. */
+    int traceFlags,		/* Current tracing situation. */
+    int objc,			/* Number of arguments for the command. */
+    Tcl_Obj *const objv[])	/* Pointers to Tcl_Obj of each argument. */
+{
+    Interp *iPtr = (Interp *) interp;
+    Trace *tracePtr, *lastTracePtr;
+    ActiveInterpTrace active;
+    int curLevel;
+    int traceCode = TCL_OK;
+    Tcl_InterpState state = NULL;
+
+    if ((iPtr->tracePtr == NULL)
+	    || (iPtr->flags & INTERP_TRACE_IN_PROGRESS)) {
+	return(traceCode);
+    }
+
+    curLevel = iPtr->numLevels;
+
+    active.nextPtr = iPtr->activeInterpTracePtr;
+    iPtr->activeInterpTracePtr = &active;
+
+    lastTracePtr = NULL;
+    for (tracePtr = iPtr->tracePtr;
+	    (traceCode == TCL_OK) && (tracePtr != NULL);
+	    tracePtr = active.nextTracePtr) {
+	if (traceFlags & TCL_TRACE_ENTER_EXEC) {
+	    /*
+	     * Execute the trace command in reverse order of creation for
+	     * "enterstep" operation. The order is changed for "enterstep"
+	     * instead of for "leavestep" as was done in
+	     * TclCheckExecutionTraces because for step traces,
+	     * Tcl_CreateObjTrace creates one more linked list of traces which
+	     * results in one more reversal of trace invocation.
+	     */
+
+	    active.reverseScan = 1;
+	    active.nextTracePtr = NULL;
+	    tracePtr = iPtr->tracePtr;
+	    while (tracePtr->nextPtr != lastTracePtr) {
+		active.nextTracePtr = tracePtr;
+		tracePtr = tracePtr->nextPtr;
+	    }
+	    if (active.nextTracePtr) {
+		lastTracePtr = active.nextTracePtr->nextPtr;
+	    }
+	} else {
+	    active.reverseScan = 0;
+	    active.nextTracePtr = tracePtr->nextPtr;
+	}
+
+	if (tracePtr->level > 0 && curLevel > tracePtr->level) {
+	    continue;
+	}
+
+	if (!(tracePtr->flags & TCL_TRACE_EXEC_IN_PROGRESS)) {
+	    /*
+	     * The proc invoked might delete the traced command which which
+	     * might try to free tracePtr. We want to use tracePtr until the
+	     * end of this if section, so we use Tcl_Preserve() and
+	     * Tcl_Release() to be sure it is not freed while we still need
+	     * it.
+	     */
+
+	    Tcl_Preserve(tracePtr);
+	    tracePtr->flags |= TCL_TRACE_EXEC_IN_PROGRESS;
+	    if (state == NULL) {
+		state = Tcl_SaveInterpState(interp, code);
+	    }
+
+	    if (tracePtr->flags &
+		    (TCL_TRACE_ENTER_EXEC | TCL_TRACE_LEAVE_EXEC)) {
+		/*
+		 * New style trace.
+		 */
+
+		if (tracePtr->flags & traceFlags) {
+		    if (tracePtr->proc == TraceExecutionProc) {
+			TraceCommandInfo *tcmdPtr = tracePtr->clientData;
+
+			tcmdPtr->curFlags = traceFlags;
+			tcmdPtr->curCode = code;
+		    }
+		    traceCode = tracePtr->proc(tracePtr->clientData, interp,
+			    curLevel, command, (Tcl_Command) cmdPtr, objc,
+			    objv);
+		}
+	    } else {
+		/*
+		 * Old-style trace.
+		 */
+
+		if (traceFlags & TCL_TRACE_ENTER_EXEC) {
+		    /*
+		     * Old-style interpreter-wide traces only trigger before
+		     * the command is executed.
+		     */
+
+		    traceCode = CallTraceFunction(interp, tracePtr, cmdPtr,
+			    command, numChars, objc, objv);
+		}
+	    }
+	    tracePtr->flags &= ~TCL_TRACE_EXEC_IN_PROGRESS;
+	    Tcl_Release(tracePtr);
+	}
+    }
+    iPtr->activeInterpTracePtr = active.nextPtr;
+    if (state) {
+	if (traceCode == TCL_OK) {
+	    Tcl_RestoreInterpState(interp, state);
+	} else {
+	    Tcl_DiscardInterpState(state);
+	}
+    }
+
+    return traceCode;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * CallTraceFunction --
+ *
+ *	Invokes a trace function registered with an interpreter. These
+ *	functions trace command execution. Currently this trace function is
+ *	called with the address of the string-based Tcl_CmdProc for the
+ *	command, not the Tcl_ObjCmdProc.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Those side effects made by the trace function.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+CallTraceFunction(
+    Tcl_Interp *interp,		/* The current interpreter. */
+    register Trace *tracePtr,	/* Describes the trace function to call. */
+    Command *cmdPtr,		/* Points to command's Command struct. */
+    const char *command,	/* Points to the first character of the
+				 * command's source before substitutions. */
+    int numChars,		/* The number of characters in the command's
+				 * source. */
+    register int objc,		/* Number of arguments for the command. */
+    Tcl_Obj *const objv[])	/* Pointers to Tcl_Obj of each argument. */
+{
+    Interp *iPtr = (Interp *) interp;
+    char *commandCopy;
+    int traceCode;
+
+    /*
+     * Copy the command characters into a new string.
+     */
+
+    commandCopy = TclStackAlloc(interp, (unsigned) numChars + 1);
+    memcpy(commandCopy, command, (size_t) numChars);
+    commandCopy[numChars] = '\0';
+
+    /*
+     * Call the trace function then free allocated storage.
+     */
+
+    traceCode = tracePtr->proc(tracePtr->clientData, (Tcl_Interp *) iPtr,
+	    iPtr->numLevels, commandCopy, (Tcl_Command) cmdPtr, objc, objv);
+
+    TclStackFree(interp, commandCopy);
+    return traceCode;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * CommandObjTraceDeleted --
+ *
+ *	Ensure the trace is correctly deleted by decrementing its refCount and
+ *	only deleting if no other references exist.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	May release memory.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+CommandObjTraceDeleted(
+    ClientData clientData)
+{
+    TraceCommandInfo *tcmdPtr = clientData;
+
+    if (tcmdPtr->refCount-- <= 1) {
+	ckfree(tcmdPtr);
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TraceExecutionProc --
+ *
+ *	This function is invoked whenever code relevant to a 'trace execution'
+ *	command is executed. It is called in one of two ways in Tcl's core:
+ *
+ *	(i) by the TclCheckExecutionTraces, when an execution trace has been
+ *	triggered.
+ *	(ii) by TclCheckInterpTraces, when a prior execution trace has created
+ *	a trace of the internals of a procedure, passing in this function as
+ *	the one to be called.
+ *
+ * Results:
+ *	The return value is a standard Tcl completion code such as TCL_OK or
+ *	TCL_ERROR, etc.
+ *
+ * Side effects:
+ *	May invoke an arbitrary Tcl procedure, and may create or delete an
+ *	interpreter-wide trace.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+TraceExecutionProc(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int level,
+    const char *command,
+    Tcl_Command cmdInfo,
+    int objc,
+    struct Tcl_Obj *const objv[])
+{
+    int call = 0;
+    Interp *iPtr = (Interp *) interp;
+    TraceCommandInfo *tcmdPtr = clientData;
+    int flags = tcmdPtr->curFlags;
+    int code = tcmdPtr->curCode;
+    int traceCode = TCL_OK;
+
+    if (tcmdPtr->flags & TCL_TRACE_EXEC_IN_PROGRESS) {
+	/*
+	 * Inside any kind of execution trace callback, we do not allow any
+	 * further execution trace callbacks to be called for the same trace.
+	 */
+
+	return traceCode;
+    }
+
+    if (!Tcl_InterpDeleted(interp) && !Tcl_LimitExceeded(interp)) {
+	/*
+	 * Check whether the current call is going to eval arbitrary Tcl code
+	 * with a generated trace, or whether we are only going to setup
+	 * interpreter-wide traces to implement the 'step' traces. This latter
+	 * situation can happen if we create a command trace without either
+	 * before or after operations, but with either of the step operations.
+	 */
+
+	if (flags & TCL_TRACE_EXEC_DIRECT) {
+	    call = flags & tcmdPtr->flags &
+		    (TCL_TRACE_ENTER_EXEC | TCL_TRACE_LEAVE_EXEC);
+	} else {
+	    call = 1;
+	}
+
+	/*
+	 * First, if we have returned back to the level at which we created an
+	 * interpreter trace for enterstep and/or leavestep execution traces,
+	 * we remove it here.
+	 */
+
+	if ((flags & TCL_TRACE_LEAVE_EXEC) && (tcmdPtr->stepTrace != NULL)
+		&& (level == tcmdPtr->startLevel)
+		&& (strcmp(command, tcmdPtr->startCmd) == 0)) {
+	    Tcl_DeleteTrace(interp, tcmdPtr->stepTrace);
+	    tcmdPtr->stepTrace = NULL;
+	    if (tcmdPtr->startCmd != NULL) {
+		ckfree(tcmdPtr->startCmd);
+	    }
+	}
+
+	/*
+	 * Second, create the tcl callback, if required.
+	 */
+
+	if (call) {
+	    Tcl_DString cmd, sub;
+	    int i, saveInterpFlags;
+
+	    Tcl_DStringInit(&cmd);
+	    Tcl_DStringAppend(&cmd, tcmdPtr->command, (int)tcmdPtr->length);
+
+	    /*
+	     * Append command with arguments.
+	     */
+
+	    Tcl_DStringInit(&sub);
+	    for (i = 0; i < objc; i++) {
+		Tcl_DStringAppendElement(&sub, Tcl_GetString(objv[i]));
+	    }
+	    Tcl_DStringAppendElement(&cmd, Tcl_DStringValue(&sub));
+	    Tcl_DStringFree(&sub);
+
+	    if (flags & TCL_TRACE_ENTER_EXEC) {
+		/*
+		 * Append trace operation.
+		 */
+
+		if (flags & TCL_TRACE_EXEC_DIRECT) {
+		    Tcl_DStringAppendElement(&cmd, "enter");
+		} else {
+		    Tcl_DStringAppendElement(&cmd, "enterstep");
+		}
+	    } else if (flags & TCL_TRACE_LEAVE_EXEC) {
+		Tcl_Obj *resultCode;
+		const char *resultCodeStr;
+
+		/*
+		 * Append result code.
+		 */
+
+		resultCode = Tcl_NewIntObj(code);
+		resultCodeStr = Tcl_GetString(resultCode);
+		Tcl_DStringAppendElement(&cmd, resultCodeStr);
+		Tcl_DecrRefCount(resultCode);
+
+		/*
+		 * Append result string.
+		 */
+
+		Tcl_DStringAppendElement(&cmd, Tcl_GetStringResult(interp));
+
+		/*
+		 * Append trace operation.
+		 */
+
+		if (flags & TCL_TRACE_EXEC_DIRECT) {
+		    Tcl_DStringAppendElement(&cmd, "leave");
+		} else {
+		    Tcl_DStringAppendElement(&cmd, "leavestep");
+		}
+	    } else {
+		Tcl_Panic("TraceExecutionProc: bad flag combination");
+	    }
+
+	    /*
+	     * Execute the command. We discard any object result the command
+	     * returns.
+	     */
+
+	    saveInterpFlags = iPtr->flags;
+	    iPtr->flags    |= INTERP_TRACE_IN_PROGRESS;
+	    tcmdPtr->flags |= TCL_TRACE_EXEC_IN_PROGRESS;
+	    tcmdPtr->refCount++;
+
+	    /*
+	     * This line can have quite arbitrary side-effects, including
+	     * deleting the trace, the command being traced, or even the
+	     * interpreter.
+	     */
+
+	    traceCode = Tcl_EvalEx(interp, Tcl_DStringValue(&cmd),
+		    Tcl_DStringLength(&cmd), 0);
+	    tcmdPtr->flags &= ~TCL_TRACE_EXEC_IN_PROGRESS;
+
+	    /*
+	     * Restore the interp tracing flag to prevent cmd traces from
+	     * affecting interp traces.
+	     */
+
+	    iPtr->flags = saveInterpFlags;
+	    if (tcmdPtr->flags == 0) {
+		flags |= TCL_TRACE_DESTROYED;
+	    }
+	    Tcl_DStringFree(&cmd);
+	}
+
+	/*
+	 * Third, if there are any step execution traces for this proc, we
+	 * register an interpreter trace to invoke enterstep and/or leavestep
+	 * traces. We also need to save the current stack level and the proc
+	 * string in startLevel and startCmd so that we can delete this
+	 * interpreter trace when it reaches the end of this proc.
+	 */
+
+	if ((flags & TCL_TRACE_ENTER_EXEC) && (tcmdPtr->stepTrace == NULL)
+		&& (tcmdPtr->flags & (TCL_TRACE_ENTER_DURING_EXEC |
+			TCL_TRACE_LEAVE_DURING_EXEC))) {
+	    register unsigned len = strlen(command) + 1;
+
+	    tcmdPtr->startLevel = level;
+	    tcmdPtr->startCmd = ckalloc(len);
+	    memcpy(tcmdPtr->startCmd, command, len);
+	    tcmdPtr->refCount++;
+	    tcmdPtr->stepTrace = Tcl_CreateObjTrace(interp, 0,
+		   (tcmdPtr->flags & TCL_TRACE_ANY_EXEC) >> 2,
+		   TraceExecutionProc, tcmdPtr, CommandObjTraceDeleted);
+	}
+    }
+    if (flags & TCL_TRACE_DESTROYED) {
+	if (tcmdPtr->stepTrace != NULL) {
+	    Tcl_DeleteTrace(interp, tcmdPtr->stepTrace);
+	    tcmdPtr->stepTrace = NULL;
+	    if (tcmdPtr->startCmd != NULL) {
+		ckfree(tcmdPtr->startCmd);
+	    }
+	}
+    }
+    if (call) {
+	if (tcmdPtr->refCount-- <= 1) {
+	    ckfree(tcmdPtr);
+	}
+    }
+    return traceCode;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TraceVarProc --
+ *
+ *	This function is called to handle variable accesses that have been
+ *	traced using the "trace" command.
+ *
+ * Results:
+ *	Normally returns NULL. If the trace command returns an error, then
+ *	this function returns an error string.
+ *
+ * Side effects:
+ *	Depends on the command associated with the trace.
+ *
+ *----------------------------------------------------------------------
+ */
+
+	/* ARGSUSED */
+static char *
+TraceVarProc(
+    ClientData clientData,	/* Information about the variable trace. */
+    Tcl_Interp *interp,		/* Interpreter containing variable. */
+    const char *name1,		/* Name of variable or array. */
+    const char *name2,		/* Name of element within array; NULL means
+				 * scalar variable is being referenced. */
+    int flags)			/* OR-ed bits giving operation and other
+				 * information. */
+{
+    TraceVarInfo *tvarPtr = clientData;
+    char *result;
+    int code, destroy = 0;
+    Tcl_DString cmd;
+    int rewind = ((Interp *)interp)->execEnvPtr->rewind;
+
+    /*
+     * We might call Tcl_Eval() below, and that might evaluate [trace vdelete]
+     * which might try to free tvarPtr. We want to use tvarPtr until the end
+     * of this function, so we use Tcl_Preserve() and Tcl_Release() to be sure
+     * it is not freed while we still need it.
+     */
+
+    result = NULL;
+    if ((tvarPtr->flags & flags) && !Tcl_InterpDeleted(interp)
+	    && !Tcl_LimitExceeded(interp)) {
+	if (tvarPtr->length != (size_t) 0) {
+	    /*
+	     * Generate a command to execute by appending list elements for
+	     * the two variable names and the operation.
+	     */
+
+	    Tcl_DStringInit(&cmd);
+	    Tcl_DStringAppend(&cmd, tvarPtr->command, (int) tvarPtr->length);
+	    Tcl_DStringAppendElement(&cmd, name1);
+	    Tcl_DStringAppendElement(&cmd, (name2 ? name2 : ""));
+#ifndef TCL_REMOVE_OBSOLETE_TRACES
+	    if (tvarPtr->flags & TCL_TRACE_OLD_STYLE) {
+		if (flags & TCL_TRACE_ARRAY) {
+		    TclDStringAppendLiteral(&cmd, " a");
+		} else if (flags & TCL_TRACE_READS) {
+		    TclDStringAppendLiteral(&cmd, " r");
+		} else if (flags & TCL_TRACE_WRITES) {
+		    TclDStringAppendLiteral(&cmd, " w");
+		} else if (flags & TCL_TRACE_UNSETS) {
+		    TclDStringAppendLiteral(&cmd, " u");
+		}
+	    } else {
+#endif
+		if (flags & TCL_TRACE_ARRAY) {
+		    TclDStringAppendLiteral(&cmd, " array");
+		} else if (flags & TCL_TRACE_READS) {
+		    TclDStringAppendLiteral(&cmd, " read");
+		} else if (flags & TCL_TRACE_WRITES) {
+		    TclDStringAppendLiteral(&cmd, " write");
+		} else if (flags & TCL_TRACE_UNSETS) {
+		    TclDStringAppendLiteral(&cmd, " unset");
+		}
+#ifndef TCL_REMOVE_OBSOLETE_TRACES
+	    }
+#endif
+
+	    /*
+	     * Execute the command. We discard any object result the command
+	     * returns.
+	     *
+	     * Add the TCL_TRACE_DESTROYED flag to tvarPtr to indicate to
+	     * other areas that this will be destroyed by us, otherwise a
+	     * double-free might occur depending on what the eval does.
+	     */
+
+	    if ((flags & TCL_TRACE_DESTROYED)
+		    && !(tvarPtr->flags & TCL_TRACE_DESTROYED)) {
+		destroy = 1;
+		tvarPtr->flags |= TCL_TRACE_DESTROYED;
+	    }
+
+	    /*
+	     * Make sure that unset traces are rune even if the execEnv is
+	     * rewinding (coroutine deletion, [Bug 2093947]
+	     */
+
+	    if (rewind && (flags & TCL_TRACE_UNSETS)) {
+		((Interp *)interp)->execEnvPtr->rewind = 0;
+	    }
+	    code = Tcl_EvalEx(interp, Tcl_DStringValue(&cmd),
+		    Tcl_DStringLength(&cmd), 0);
+	    if (rewind) {
+		((Interp *)interp)->execEnvPtr->rewind = rewind;
+	    }
+	    if (code != TCL_OK) {		/* copy error msg to result */
+		Tcl_Obj *errMsgObj = Tcl_GetObjResult(interp);
+
+		Tcl_IncrRefCount(errMsgObj);
+		result = (char *) errMsgObj;
+	    }
+	    Tcl_DStringFree(&cmd);
+	}
+    }
+    if (destroy && result != NULL) {
+	register Tcl_Obj *errMsgObj = (Tcl_Obj *) result;
+
+	Tcl_DecrRefCount(errMsgObj);
+	result = NULL;
+    }
+    return result;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_CreateObjTrace --
+ *
+ *	Arrange for a function to be called to trace command execution.
+ *
+ * Results:
+ *	The return value is a token for the trace, which may be passed to
+ *	Tcl_DeleteTrace to eliminate the trace.
+ *
+ * Side effects:
+ *	From now on, proc will be called just before a command function is
+ *	called to execute a Tcl command. Calls to proc will have the following
+ *	form:
+ *
+ *	void proc(ClientData	 clientData,
+ *		  Tcl_Interp *	 interp,
+ *		  int		 level,
+ *		  const char *	 command,
+ *		  Tcl_Command	 commandInfo,
+ *		  int		 objc,
+ *		  Tcl_Obj *const objv[]);
+ *
+ *	The 'clientData' and 'interp' arguments to 'proc' will be the same as
+ *	the arguments to Tcl_CreateObjTrace. The 'level' argument gives the
+ *	nesting depth of command interpretation within the interpreter. The
+ *	'command' argument is the ASCII text of the command being evaluated -
+ *	before any substitutions are performed. The 'commandInfo' argument
+ *	gives a handle to the command procedure that will be evaluated. The
+ *	'objc' and 'objv' parameters give the parameter vector that will be
+ *	passed to the command procedure. Proc does not return a value.
+ *
+ *	It is permissible for 'proc' to call Tcl_SetCommandTokenInfo to change
+ *	the command procedure or client data for the command being evaluated,
+ *	and these changes will take effect with the current evaluation.
+ *
+ *	The 'level' argument specifies the maximum nesting level of calls to
+ *	be traced. If the execution depth of the interpreter exceeds 'level',
+ *	the trace callback is not executed.
+ *
+ *	The 'flags' argument is either zero or the value,
+ *	TCL_ALLOW_INLINE_COMPILATION. If the TCL_ALLOW_INLINE_COMPILATION flag
+ *	is not present, the bytecode compiler will not generate inline code
+ *	for Tcl's built-in commands. This behavior will have a significant
+ *	impact on performance, but will ensure that all command evaluations
+ *	are traced. If the TCL_ALLOW_INLINE_COMPILATION flag is present, the
+ *	bytecode compiler will have its normal behavior of compiling in-line
+ *	code for some of Tcl's built-in commands. In this case, the tracing
+ *	will be imprecise - in-line code will not be traced - but run-time
+ *	performance will be improved. The latter behavior is desired for many
+ *	applications such as profiling of run time.
+ *
+ *	When the trace is deleted, the 'delProc' function will be invoked,
+ *	passing it the original client data.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_Trace
+Tcl_CreateObjTrace(
+    Tcl_Interp *interp,		/* Tcl interpreter */
+    int level,			/* Maximum nesting level */
+    int flags,			/* Flags, see above */
+    Tcl_CmdObjTraceProc *proc,	/* Trace callback */
+    ClientData clientData,	/* Client data for the callback */
+    Tcl_CmdObjTraceDeleteProc *delProc)
+				/* Function to call when trace is deleted */
+{
+    register Trace *tracePtr;
+    register Interp *iPtr = (Interp *) interp;
+
+    /*
+     * Test if this trace allows inline compilation of commands.
+     */
+
+    if (!(flags & TCL_ALLOW_INLINE_COMPILATION)) {
+	if (iPtr->tracesForbiddingInline == 0) {
+	    /*
+	     * When the first trace forbidding inline compilation is created,
+	     * invalidate existing compiled code for this interpreter and
+	     * arrange (by setting the DONT_COMPILE_CMDS_INLINE flag) that
+	     * when compiling new code, no commands will be compiled inline
+	     * (i.e., into an inline sequence of instructions). We do this
+	     * because commands that were compiled inline will never result in
+	     * a command trace being called.
+	     */
+
+	    iPtr->compileEpoch++;
+	    iPtr->flags |= DONT_COMPILE_CMDS_INLINE;
+	}
+	iPtr->tracesForbiddingInline++;
+    }
+
+    tracePtr = ckalloc(sizeof(Trace));
+    tracePtr->level = level;
+    tracePtr->proc = proc;
+    tracePtr->clientData = clientData;
+    tracePtr->delProc = delProc;
+    tracePtr->nextPtr = iPtr->tracePtr;
+    tracePtr->flags = flags;
+    iPtr->tracePtr = tracePtr;
+
+    return (Tcl_Trace) tracePtr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_CreateTrace --
+ *
+ *	Arrange for a function to be called to trace command execution.
+ *
+ * Results:
+ *	The return value is a token for the trace, which may be passed to
+ *	Tcl_DeleteTrace to eliminate the trace.
+ *
+ * Side effects:
+ *	From now on, proc will be called just before a command procedure is
+ *	called to execute a Tcl command. Calls to proc will have the following
+ *	form:
+ *
+ *	void
+ *	proc(clientData, interp, level, command, cmdProc, cmdClientData,
+ *		argc, argv)
+ *	    ClientData clientData;
+ *	    Tcl_Interp *interp;
+ *	    int level;
+ *	    char *command;
+ *	    int (*cmdProc)();
+ *	    ClientData cmdClientData;
+ *	    int argc;
+ *	    char **argv;
+ *	{
+ *	}
+ *
+ *	The clientData and interp arguments to proc will be the same as the
+ *	corresponding arguments to this function. Level gives the nesting
+ *	level of command interpretation for this interpreter (0 corresponds to
+ *	top level). Command gives the ASCII text of the raw command, cmdProc
+ *	and cmdClientData give the function that will be called to process the
+ *	command and the ClientData value it will receive, and argc and argv
+ *	give the arguments to the command, after any argument parsing and
+ *	substitution. Proc does not return a value.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_Trace
+Tcl_CreateTrace(
+    Tcl_Interp *interp,		/* Interpreter in which to create trace. */
+    int level,			/* Only call proc for commands at nesting
+				 * level<=argument level (1=>top level). */
+    Tcl_CmdTraceProc *proc,	/* Function to call before executing each
+				 * command. */
+    ClientData clientData)	/* Arbitrary value word to pass to proc. */
+{
+    StringTraceData *data = ckalloc(sizeof(StringTraceData));
+
+    data->clientData = clientData;
+    data->proc = proc;
+    return Tcl_CreateObjTrace(interp, level, 0, StringTraceProc,
+	    data, StringTraceDeleteProc);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * StringTraceProc --
+ *
+ *	Invoke a string-based trace function from an object-based callback.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Whatever the string-based trace function does.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+StringTraceProc(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int level,
+    const char *command,
+    Tcl_Command commandInfo,
+    int objc,
+    Tcl_Obj *const *objv)
+{
+    StringTraceData *data = clientData;
+    Command *cmdPtr = (Command *) commandInfo;
+    const char **argv;		/* Args to pass to string trace proc */
+    int i;
+
+    /*
+     * This is a bit messy because we have to emulate the old trace interface,
+     * which uses strings for everything.
+     */
+
+    argv = (const char **) TclStackAlloc(interp,
+	    (unsigned) ((objc + 1) * sizeof(const char *)));
+    for (i = 0; i < objc; i++) {
+	argv[i] = Tcl_GetString(objv[i]);
+    }
+    argv[objc] = 0;
+
+    /*
+     * Invoke the command function. Note that we cast away const-ness on two
+     * parameters for compatibility with legacy code; the code MUST NOT modify
+     * either command or argv.
+     */
+
+    data->proc(data->clientData, interp, level, (char *) command,
+	    cmdPtr->proc, cmdPtr->clientData, objc, argv);
+    TclStackFree(interp, (void *) argv);
+
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * StringTraceDeleteProc --
+ *
+ *	Clean up memory when a string-based trace is deleted.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Allocated memory is returned to the system.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+StringTraceDeleteProc(
+    ClientData clientData)
+{
+    ckfree(clientData);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_DeleteTrace --
+ *
+ *	Remove a trace.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	From now on there will be no more calls to the function given in
+ *	trace.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_DeleteTrace(
+    Tcl_Interp *interp,		/* Interpreter that contains trace. */
+    Tcl_Trace trace)		/* Token for trace (returned previously by
+				 * Tcl_CreateTrace). */
+{
+    Interp *iPtr = (Interp *) interp;
+    Trace *prevPtr, *tracePtr = (Trace *) trace;
+    register Trace **tracePtr2 = &iPtr->tracePtr;
+    ActiveInterpTrace *activePtr;
+
+    /*
+     * Locate the trace entry in the interpreter's trace list, and remove it
+     * from the list.
+     */
+
+    prevPtr = NULL;
+    while (*tracePtr2 != NULL && *tracePtr2 != tracePtr) {
+	prevPtr = *tracePtr2;
+	tracePtr2 = &prevPtr->nextPtr;
+    }
+    if (*tracePtr2 == NULL) {
+	return;
+    }
+    *tracePtr2 = (*tracePtr2)->nextPtr;
+
+    /*
+     * The code below makes it possible to delete traces while traces are
+     * active: it makes sure that the deleted trace won't be processed by
+     * TclCheckInterpTraces.
+     */
+
+    for (activePtr = iPtr->activeInterpTracePtr;  activePtr != NULL;
+	    activePtr = activePtr->nextPtr) {
+	if (activePtr->nextTracePtr == tracePtr) {
+	    if (activePtr->reverseScan) {
+		activePtr->nextTracePtr = prevPtr;
+	    } else {
+		activePtr->nextTracePtr = tracePtr->nextPtr;
+	    }
+	}
+    }
+
+    /*
+     * If the trace forbids bytecode compilation, change the interpreter's
+     * state. If bytecode compilation is now permitted, flag the fact and
+     * advance the compilation epoch so that procs will be recompiled to take
+     * advantage of it.
+     */
+
+    if (!(tracePtr->flags & TCL_ALLOW_INLINE_COMPILATION)) {
+	iPtr->tracesForbiddingInline--;
+	if (iPtr->tracesForbiddingInline == 0) {
+	    iPtr->flags &= ~DONT_COMPILE_CMDS_INLINE;
+	    iPtr->compileEpoch++;
+	}
+    }
+
+    /*
+     * Execute any delete callback.
+     */
+
+    if (tracePtr->delProc != NULL) {
+	tracePtr->delProc(tracePtr->clientData);
+    }
+
+    /*
+     * Delete the trace object.
+     */
+
+    Tcl_EventuallyFree((char *) tracePtr, TCL_DYNAMIC);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclTraceVarExists --
+ *
+ *	This is called from info exists. We need to trigger read and/or array
+ *	traces because they may end up creating a variable that doesn't
+ *	currently exist.
+ *
+ * Results:
+ *	A pointer to the Var structure, or NULL.
+ *
+ * Side effects:
+ *	May fill in error messages in the interp.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Var *
+TclVarTraceExists(
+    Tcl_Interp *interp,		/* The interpreter */
+    const char *varName)	/* The variable name */
+{
+    Var *varPtr, *arrayPtr;
+
+    /*
+     * The choice of "create" flag values is delicate here, and matches the
+     * semantics of GetVar. Things are still not perfect, however, because if
+     * you do "info exists x" you get a varPtr and therefore trigger traces.
+     * However, if you do "info exists x(i)", then you only get a varPtr if x
+     * is already known to be an array. Otherwise you get NULL, and no trace
+     * is triggered. This matches Tcl 7.6 semantics.
+     */
+
+    varPtr = TclLookupVar(interp, varName, NULL, 0, "access",
+	    /*createPart1*/ 0, /*createPart2*/ 1, &arrayPtr);
+
+    if (varPtr == NULL) {
+	return NULL;
+    }
+
+    if ((varPtr->flags & VAR_TRACED_READ)
+	    || (arrayPtr && (arrayPtr->flags & VAR_TRACED_READ))) {
+	TclCallVarTraces((Interp *) interp, arrayPtr, varPtr, varName, NULL,
+		TCL_TRACE_READS, /* leaveErrMsg */ 0);
+    }
+
+    /*
+     * If the variable doesn't exist anymore and no-one's using it, then free
+     * up the relevant structures and hash table entries.
+     */
+
+    if (TclIsVarUndefined(varPtr)) {
+	TclCleanupVar(varPtr, arrayPtr);
+	return NULL;
+    }
+
+    return varPtr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclCallVarTraces --
+ *
+ *	This function is invoked to find and invoke relevant trace functions
+ *	associated with a particular operation on a variable. This function
+ *	invokes traces both on the variable and on its containing array (where
+ *	relevant).
+ *
+ * Results:
+ *	Returns TCL_OK to indicate normal operation. Returns TCL_ERROR if
+ *	invocation of a trace function indicated an error. When TCL_ERROR is
+ *	returned and leaveErrMsg is true, then the errorInfo field of iPtr has
+ *	information about the error placed in it.
+ *
+ * Side effects:
+ *	Almost anything can happen, depending on trace; this function itself
+ *	doesn't have any side effects.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclObjCallVarTraces(
+    Interp *iPtr,		/* Interpreter containing variable. */
+    register Var *arrayPtr,	/* Pointer to array variable that contains the
+				 * variable, or NULL if the variable isn't an
+				 * element of an array. */
+    Var *varPtr,		/* Variable whose traces are to be invoked. */
+    Tcl_Obj *part1Ptr,
+    Tcl_Obj *part2Ptr,		/* Variable's two-part name. */
+    int flags,			/* Flags passed to trace functions: indicates
+				 * what's happening to variable, plus maybe
+				 * TCL_GLOBAL_ONLY or TCL_NAMESPACE_ONLY */
+    int leaveErrMsg,		/* If true, and one of the traces indicates an
+				 * error, then leave an error message and
+				 * stack trace information in *iPTr. */
+    int index)			/* Index into the local variable table of the
+				 * variable, or -1. Only used when part1Ptr is
+				 * NULL. */
+{
+    const char *part1, *part2;
+
+    if (!part1Ptr) {
+	part1Ptr = localName(iPtr->varFramePtr, index);
+    }
+    if (!part1Ptr) {
+	Tcl_Panic("Cannot trace a variable with no name");
+    }
+    part1 = TclGetString(part1Ptr);
+    part2 = part2Ptr? TclGetString(part2Ptr) : NULL;
+
+    return TclCallVarTraces(iPtr, arrayPtr, varPtr, part1, part2, flags,
+	    leaveErrMsg);
+}
+
+int
+TclCallVarTraces(
+    Interp *iPtr,		/* Interpreter containing variable. */
+    register Var *arrayPtr,	/* Pointer to array variable that contains the
+				 * variable, or NULL if the variable isn't an
+				 * element of an array. */
+    Var *varPtr,		/* Variable whose traces are to be invoked. */
+    const char *part1,
+    const char *part2,		/* Variable's two-part name. */
+    int flags,			/* Flags passed to trace functions: indicates
+				 * what's happening to variable, plus maybe
+				 * TCL_GLOBAL_ONLY or TCL_NAMESPACE_ONLY */
+    int leaveErrMsg)		/* If true, and one of the traces indicates an
+				 * error, then leave an error message and
+				 * stack trace information in *iPTr. */
+{
+    register VarTrace *tracePtr;
+    ActiveVarTrace active;
+    char *result;
+    const char *openParen, *p;
+    Tcl_DString nameCopy;
+    int copiedName;
+    int code = TCL_OK;
+    int disposeFlags = 0;
+    Tcl_InterpState state = NULL;
+    Tcl_HashEntry *hPtr;
+    int traceflags = flags & VAR_ALL_TRACES;
+
+    /*
+     * If there are already similar trace functions active for the variable,
+     * don't call them again.
+     */
+
+    if (TclIsVarTraceActive(varPtr)) {
+	return code;
+    }
+    TclSetVarTraceActive(varPtr);
+    if (TclIsVarInHash(varPtr)) {
+	VarHashRefCount(varPtr)++;
+    }
+    if (arrayPtr && TclIsVarInHash(arrayPtr)) {
+	VarHashRefCount(arrayPtr)++;
+    }
+
+    /*
+     * If the variable name hasn't been parsed into array name and element, do
+     * it here. If there really is an array element, make a copy of the
+     * original name so that NULLs can be inserted into it to separate the
+     * names (can't modify the name string in place, because the string might
+     * get used by the callbacks we invoke).
+     */
+
+    copiedName = 0;
+    if (part2 == NULL) {
+	for (p = part1; *p ; p++) {
+	    if (*p == '(') {
+		openParen = p;
+		do {
+		    p++;
+		} while (*p != '\0');
+		p--;
+		if (*p == ')') {
+		    int offset = (openParen - part1);
+		    char *newPart1;
+
+		    Tcl_DStringInit(&nameCopy);
+		    Tcl_DStringAppend(&nameCopy, part1, p-part1);
+		    newPart1 = Tcl_DStringValue(&nameCopy);
+		    newPart1[offset] = 0;
+		    part1 = newPart1;
+		    part2 = newPart1 + offset + 1;
+		    copiedName = 1;
+		}
+		break;
+	    }
+	}
+    }
+
+    /*
+     * Ignore any caller-provided TCL_INTERP_DESTROYED flag.  Only we can
+     * set it correctly.
+     */
+
+    flags &= ~TCL_INTERP_DESTROYED;
+
+    /*
+     * Invoke traces on the array containing the variable, if relevant.
+     */
+
+    result = NULL;
+    active.nextPtr = iPtr->activeVarTracePtr;
+    iPtr->activeVarTracePtr = &active;
+    Tcl_Preserve(iPtr);
+    if (arrayPtr && !TclIsVarTraceActive(arrayPtr)
+	    && (arrayPtr->flags & traceflags)) {
+	hPtr = Tcl_FindHashEntry(&iPtr->varTraces, (char *) arrayPtr);
+	active.varPtr = arrayPtr;
+	for (tracePtr = Tcl_GetHashValue(hPtr);
+		tracePtr != NULL; tracePtr = active.nextTracePtr) {
+	    active.nextTracePtr = tracePtr->nextPtr;
+	    if (!(tracePtr->flags & flags)) {
+		continue;
+	    }
+	    Tcl_Preserve(tracePtr);
+	    if (state == NULL) {
+		state = Tcl_SaveInterpState((Tcl_Interp *) iPtr, code);
+	    }
+	    if (Tcl_InterpDeleted((Tcl_Interp *) iPtr)) {
+		flags |= TCL_INTERP_DESTROYED;
+	    }
+	    result = tracePtr->traceProc(tracePtr->clientData,
+		    (Tcl_Interp *) iPtr, part1, part2, flags);
+	    if (result != NULL) {
+		if (flags & TCL_TRACE_UNSETS) {
+		    /*
+		     * Ignore errors in unset traces.
+		     */
+
+		    DisposeTraceResult(tracePtr->flags, result);
+		} else {
+		    disposeFlags = tracePtr->flags;
+		    code = TCL_ERROR;
+		}
+	    }
+	    Tcl_Release(tracePtr);
+	    if (code == TCL_ERROR) {
+		goto done;
+	    }
+	}
+    }
+
+    /*
+     * Invoke traces on the variable itself.
+     */
+
+    if (flags & TCL_TRACE_UNSETS) {
+	flags |= TCL_TRACE_DESTROYED;
+    }
+    active.varPtr = varPtr;
+    if (varPtr->flags & traceflags) {
+	hPtr = Tcl_FindHashEntry(&iPtr->varTraces, (char *) varPtr);
+	for (tracePtr = Tcl_GetHashValue(hPtr);
+		tracePtr != NULL; tracePtr = active.nextTracePtr) {
+	    active.nextTracePtr = tracePtr->nextPtr;
+	    if (!(tracePtr->flags & flags)) {
+		continue;
+	    }
+	    Tcl_Preserve(tracePtr);
+	    if (state == NULL) {
+		state = Tcl_SaveInterpState((Tcl_Interp *) iPtr, code);
+	    }
+	    if (Tcl_InterpDeleted((Tcl_Interp *) iPtr)) {
+		flags |= TCL_INTERP_DESTROYED;
+	    }
+	    result = tracePtr->traceProc(tracePtr->clientData,
+		    (Tcl_Interp *) iPtr, part1, part2, flags);
+	    if (result != NULL) {
+		if (flags & TCL_TRACE_UNSETS) {
+		    /*
+		     * Ignore errors in unset traces.
+		     */
+
+		    DisposeTraceResult(tracePtr->flags, result);
+		} else {
+		    disposeFlags = tracePtr->flags;
+		    code = TCL_ERROR;
+		}
+	    }
+	    Tcl_Release(tracePtr);
+	    if (code == TCL_ERROR) {
+		goto done;
+	    }
+	}
+    }
+
+    /*
+     * Restore the variable's flags, remove the record of our active traces,
+     * and then return.
+     */
+
+  done:
+    if (code == TCL_ERROR) {
+	if (leaveErrMsg) {
+	    const char *verb = "";
+	    const char *type = "";
+
+	    switch (flags&(TCL_TRACE_READS|TCL_TRACE_WRITES|TCL_TRACE_ARRAY)) {
+	    case TCL_TRACE_READS:
+		verb = "read";
+		type = verb;
+		break;
+	    case TCL_TRACE_WRITES:
+		verb = "set";
+		type = "write";
+		break;
+	    case TCL_TRACE_ARRAY:
+		verb = "trace array";
+		type = "array";
+		break;
+	    }
+
+	    if (disposeFlags & TCL_TRACE_RESULT_OBJECT) {
+		Tcl_SetObjResult((Tcl_Interp *)iPtr, (Tcl_Obj *) result);
+	    } else {
+		Tcl_SetObjResult((Tcl_Interp *)iPtr,
+			Tcl_NewStringObj(result, -1));
+	    }
+	    Tcl_AddErrorInfo((Tcl_Interp *)iPtr, "");
+
+	    Tcl_AppendObjToErrorInfo((Tcl_Interp *)iPtr, Tcl_ObjPrintf(
+		    "\n    (%s trace on \"%s%s%s%s\")", type, part1,
+		    (part2 ? "(" : ""), (part2 ? part2 : ""),
+		    (part2 ? ")" : "") ));
+	    if (disposeFlags & TCL_TRACE_RESULT_OBJECT) {
+		TclVarErrMsg((Tcl_Interp *) iPtr, part1, part2, verb,
+			Tcl_GetString((Tcl_Obj *) result));
+	    } else {
+		TclVarErrMsg((Tcl_Interp *) iPtr, part1, part2, verb, result);
+	    }
+	    iPtr->flags &= ~(ERR_ALREADY_LOGGED);
+	    Tcl_DiscardInterpState(state);
+	} else {
+	    Tcl_RestoreInterpState((Tcl_Interp *) iPtr, state);
+	}
+	DisposeTraceResult(disposeFlags,result);
+    } else if (state) {
+	if (code == TCL_OK) {
+	    code = Tcl_RestoreInterpState((Tcl_Interp *) iPtr, state);
+	} else {
+	    Tcl_DiscardInterpState(state);
+	}
+    }
+
+    if (arrayPtr && TclIsVarInHash(arrayPtr)) {
+	VarHashRefCount(arrayPtr)--;
+    }
+    if (copiedName) {
+	Tcl_DStringFree(&nameCopy);
+    }
+    TclClearVarTraceActive(varPtr);
+    if (TclIsVarInHash(varPtr)) {
+	VarHashRefCount(varPtr)--;
+    }
+    iPtr->activeVarTracePtr = active.nextPtr;
+    Tcl_Release(iPtr);
+    return code;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * DisposeTraceResult--
+ *
+ *	This function is called to dispose of the result returned from a trace
+ *	function. The disposal method appropriate to the type of result is
+ *	determined by flags.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The memory allocated for the trace result may be freed.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+DisposeTraceResult(
+    int flags,			/* Indicates type of result to determine
+				 * proper disposal method. */
+    char *result)		/* The result returned from a trace function
+				 * to be disposed. */
+{
+    if (flags & TCL_TRACE_RESULT_DYNAMIC) {
+	ckfree(result);
+    } else if (flags & TCL_TRACE_RESULT_OBJECT) {
+	Tcl_DecrRefCount((Tcl_Obj *) result);
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_UntraceVar --
+ *
+ *	Remove a previously-created trace for a variable.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	If there exists a trace for the variable given by varName with the
+ *	given flags, proc, and clientData, then that trace is removed.
+ *
+ *----------------------------------------------------------------------
+ */
+
+#undef Tcl_UntraceVar
+void
+Tcl_UntraceVar(
+    Tcl_Interp *interp,		/* Interpreter containing variable. */
+    const char *varName,	/* Name of variable; may end with "(index)" to
+				 * signify an array reference. */
+    int flags,			/* OR-ed collection of bits describing current
+				 * trace, including any of TCL_TRACE_READS,
+				 * TCL_TRACE_WRITES, TCL_TRACE_UNSETS,
+				 * TCL_GLOBAL_ONLY and TCL_NAMESPACE_ONLY. */
+    Tcl_VarTraceProc *proc,	/* Function assocated with trace. */
+    ClientData clientData)	/* Arbitrary argument to pass to proc. */
+{
+    Tcl_UntraceVar2(interp, varName, NULL, flags, proc, clientData);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_UntraceVar2 --
+ *
+ *	Remove a previously-created trace for a variable.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	If there exists a trace for the variable given by part1 and part2 with
+ *	the given flags, proc, and clientData, then that trace is removed.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_UntraceVar2(
+    Tcl_Interp *interp,		/* Interpreter containing variable. */
+    const char *part1,		/* Name of variable or array. */
+    const char *part2,		/* Name of element within array; NULL means
+				 * trace applies to scalar variable or array
+				 * as-a-whole. */
+    int flags,			/* OR-ed collection of bits describing current
+				 * trace, including any of TCL_TRACE_READS,
+				 * TCL_TRACE_WRITES, TCL_TRACE_UNSETS,
+				 * TCL_GLOBAL_ONLY, and TCL_NAMESPACE_ONLY. */
+    Tcl_VarTraceProc *proc,	/* Function assocated with trace. */
+    ClientData clientData)	/* Arbitrary argument to pass to proc. */
+{
+    register VarTrace *tracePtr;
+    VarTrace *prevPtr, *nextPtr;
+    Var *varPtr, *arrayPtr;
+    Interp *iPtr = (Interp *) interp;
+    ActiveVarTrace *activePtr;
+    int flagMask, allFlags = 0;
+    Tcl_HashEntry *hPtr;
+
+    /*
+     * Set up a mask to mask out the parts of the flags that we are not
+     * interested in now.
+     */
+
+    flagMask = TCL_GLOBAL_ONLY | TCL_NAMESPACE_ONLY;
+    varPtr = TclLookupVar(interp, part1, part2, flags & flagMask, /*msg*/ NULL,
+	    /*createPart1*/ 0, /*createPart2*/ 0, &arrayPtr);
+    if (varPtr == NULL || !(varPtr->flags & VAR_ALL_TRACES & flags)) {
+	return;
+    }
+
+    /*
+     * Set up a mask to mask out the parts of the flags that we are not
+     * interested in now.
+     */
+
+    flagMask = TCL_TRACE_READS | TCL_TRACE_WRITES | TCL_TRACE_UNSETS |
+	  TCL_TRACE_ARRAY | TCL_TRACE_RESULT_DYNAMIC | TCL_TRACE_RESULT_OBJECT;
+#ifndef TCL_REMOVE_OBSOLETE_TRACES
+    flagMask |= TCL_TRACE_OLD_STYLE;
+#endif
+    flags &= flagMask;
+
+    hPtr = Tcl_FindHashEntry(&iPtr->varTraces, (char *) varPtr);
+    for (tracePtr = Tcl_GetHashValue(hPtr), prevPtr = NULL; ;
+	    prevPtr = tracePtr, tracePtr = tracePtr->nextPtr) {
+	if (tracePtr == NULL) {
+	    goto updateFlags;
+	}
+	if ((tracePtr->traceProc == proc) && (tracePtr->flags == flags)
+		&& (tracePtr->clientData == clientData)) {
+	    break;
+	}
+	allFlags |= tracePtr->flags;
+    }
+
+    /*
+     * The code below makes it possible to delete traces while traces are
+     * active: it makes sure that the deleted trace won't be processed by
+     * TclCallVarTraces.
+     *
+     * Caveat (Bug 3062331): When an unset trace handler on a variable
+     * tries to delete a different unset trace handler on the same variable,
+     * the results may be surprising.  When variable unset traces fire, the
+     * traced variable is already gone.  So the TclLookupVar() call above
+     * will not find that variable, and not finding it will never reach here
+     * to perform the deletion.  This means callers of Tcl_UntraceVar*()
+     * attempting to delete unset traces from within the handler of another
+     * unset trace have to account for the possibility that their call to
+     * Tcl_UntraceVar*() is a no-op.
+     */
+
+    for (activePtr = iPtr->activeVarTracePtr;  activePtr != NULL;
+	    activePtr = activePtr->nextPtr) {
+	if (activePtr->nextTracePtr == tracePtr) {
+	    activePtr->nextTracePtr = tracePtr->nextPtr;
+	}
+    }
+    nextPtr = tracePtr->nextPtr;
+    if (prevPtr == NULL) {
+	if (nextPtr) {
+	    Tcl_SetHashValue(hPtr, nextPtr);
+	} else {
+	    Tcl_DeleteHashEntry(hPtr);
+	}
+    } else {
+	prevPtr->nextPtr = nextPtr;
+    }
+    tracePtr->nextPtr = NULL;
+    Tcl_EventuallyFree(tracePtr, TCL_DYNAMIC);
+
+    for (tracePtr = nextPtr; tracePtr != NULL;
+	    tracePtr = tracePtr->nextPtr) {
+	allFlags |= tracePtr->flags;
+    }
+
+  updateFlags:
+    varPtr->flags &= ~VAR_ALL_TRACES;
+    if (allFlags & VAR_ALL_TRACES) {
+	varPtr->flags |= (allFlags & VAR_ALL_TRACES);
+    } else if (TclIsVarUndefined(varPtr)) {
+	/*
+	 * If this is the last trace on the variable, and the variable is
+	 * unset and unused, then free up the variable.
+	 */
+
+	TclCleanupVar(varPtr, NULL);
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_VarTraceInfo --
+ *
+ *	Return the clientData value associated with a trace on a variable.
+ *	This function can also be used to step through all of the traces on a
+ *	particular variable that have the same trace function.
+ *
+ * Results:
+ *	The return value is the clientData value associated with a trace on
+ *	the given variable. Information will only be returned for a trace with
+ *	proc as trace function. If the clientData argument is NULL then the
+ *	first such trace is returned; otherwise, the next relevant one after
+ *	the one given by clientData will be returned. If the variable doesn't
+ *	exist, or if there are no (more) traces for it, then NULL is returned.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+#undef Tcl_VarTraceInfo
+ClientData
+Tcl_VarTraceInfo(
+    Tcl_Interp *interp,		/* Interpreter containing variable. */
+    const char *varName,	/* Name of variable; may end with "(index)" to
+				 * signify an array reference. */
+    int flags,			/* OR-ed combo or TCL_GLOBAL_ONLY,
+				 * TCL_NAMESPACE_ONLY (can be 0). */
+    Tcl_VarTraceProc *proc,	/* Function assocated with trace. */
+    ClientData prevClientData)	/* If non-NULL, gives last value returned by
+				 * this function, so this call will return the
+				 * next trace after that one. If NULL, this
+				 * call will return the first trace. */
+{
+    return Tcl_VarTraceInfo2(interp, varName, NULL, flags, proc,
+	    prevClientData);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_VarTraceInfo2 --
+ *
+ *	Same as Tcl_VarTraceInfo, except takes name in two pieces instead of
+ *	one.
+ *
+ * Results:
+ *	Same as Tcl_VarTraceInfo.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+ClientData
+Tcl_VarTraceInfo2(
+    Tcl_Interp *interp,		/* Interpreter containing variable. */
+    const char *part1,		/* Name of variable or array. */
+    const char *part2,		/* Name of element within array; NULL means
+				 * trace applies to scalar variable or array
+				 * as-a-whole. */
+    int flags,			/* OR-ed combination of TCL_GLOBAL_ONLY,
+				 * TCL_NAMESPACE_ONLY. */
+    Tcl_VarTraceProc *proc,	/* Function assocated with trace. */
+    ClientData prevClientData)	/* If non-NULL, gives last value returned by
+				 * this function, so this call will return the
+				 * next trace after that one. If NULL, this
+				 * call will return the first trace. */
+{
+    Interp *iPtr = (Interp *) interp;
+    Var *varPtr, *arrayPtr;
+    Tcl_HashEntry *hPtr;
+
+    varPtr = TclLookupVar(interp, part1, part2,
+	    flags & (TCL_GLOBAL_ONLY|TCL_NAMESPACE_ONLY), /*msg*/ NULL,
+	    /*createPart1*/ 0, /*createPart2*/ 0, &arrayPtr);
+    if (varPtr == NULL) {
+	return NULL;
+    }
+
+    /*
+     * Find the relevant trace, if any, and return its clientData.
+     */
+
+    hPtr = Tcl_FindHashEntry(&iPtr->varTraces, (char *) varPtr);
+
+    if (hPtr) {
+	register VarTrace *tracePtr = Tcl_GetHashValue(hPtr);
+
+	if (prevClientData != NULL) {
+	    for (; tracePtr != NULL; tracePtr = tracePtr->nextPtr) {
+		if ((tracePtr->clientData == prevClientData)
+			&& (tracePtr->traceProc == proc)) {
+		    tracePtr = tracePtr->nextPtr;
+		    break;
+		}
+	    }
+	}
+	for (; tracePtr != NULL ; tracePtr = tracePtr->nextPtr) {
+	    if (tracePtr->traceProc == proc) {
+		return tracePtr->clientData;
+	    }
+	}
+    }
+    return NULL;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_TraceVar --
+ *
+ *	Arrange for reads and/or writes to a variable to cause a function to
+ *	be invoked, which can monitor the operations and/or change their
+ *	actions.
+ *
+ * Results:
+ *	A standard Tcl return value.
+ *
+ * Side effects:
+ *	A trace is set up on the variable given by varName, such that future
+ *	references to the variable will be intermediated by proc. See the
+ *	manual entry for complete details on the calling sequence for proc.
+ *     The variable's flags are updated.
+ *
+ *----------------------------------------------------------------------
+ */
+
+#undef Tcl_TraceVar
+int
+Tcl_TraceVar(
+    Tcl_Interp *interp,		/* Interpreter in which variable is to be
+				 * traced. */
+    const char *varName,	/* Name of variable; may end with "(index)" to
+				 * signify an array reference. */
+    int flags,			/* OR-ed collection of bits, including any of
+				 * TCL_TRACE_READS, TCL_TRACE_WRITES,
+				 * TCL_TRACE_UNSETS, TCL_GLOBAL_ONLY, and
+				 * TCL_NAMESPACE_ONLY. */
+    Tcl_VarTraceProc *proc,	/* Function to call when specified ops are
+				 * invoked upon varName. */
+    ClientData clientData)	/* Arbitrary argument to pass to proc. */
+{
+    return Tcl_TraceVar2(interp, varName, NULL, flags, proc, clientData);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_TraceVar2 --
+ *
+ *	Arrange for reads and/or writes to a variable to cause a function to
+ *	be invoked, which can monitor the operations and/or change their
+ *	actions.
+ *
+ * Results:
+ *	A standard Tcl return value.
+ *
+ * Side effects:
+ *	A trace is set up on the variable given by part1 and part2, such that
+ *	future references to the variable will be intermediated by proc. See
+ *	the manual entry for complete details on the calling sequence for
+ *	proc. The variable's flags are updated.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_TraceVar2(
+    Tcl_Interp *interp,		/* Interpreter in which variable is to be
+				 * traced. */
+    const char *part1,		/* Name of scalar variable or array. */
+    const char *part2,		/* Name of element within array; NULL means
+				 * trace applies to scalar variable or array
+				 * as-a-whole. */
+    int flags,			/* OR-ed collection of bits, including any of
+				 * TCL_TRACE_READS, TCL_TRACE_WRITES,
+				 * TCL_TRACE_UNSETS, TCL_GLOBAL_ONLY, and
+				 * TCL_NAMESPACE_ONLY. */
+    Tcl_VarTraceProc *proc,	/* Function to call when specified ops are
+				 * invoked upon varName. */
+    ClientData clientData)	/* Arbitrary argument to pass to proc. */
+{
+    register VarTrace *tracePtr;
+    int result;
+
+    tracePtr = ckalloc(sizeof(VarTrace));
+    tracePtr->traceProc = proc;
+    tracePtr->clientData = clientData;
+    tracePtr->flags = flags;
+
+    result = TraceVarEx(interp, part1, part2, tracePtr);
+
+    if (result != TCL_OK) {
+	ckfree(tracePtr);
+    }
+    return result;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TraceVarEx --
+ *
+ *	Arrange for reads and/or writes to a variable to cause a function to
+ *	be invoked, which can monitor the operations and/or change their
+ *	actions.
+ *
+ * Results:
+ *	A standard Tcl return value.
+ *
+ * Side effects:
+ *	A trace is set up on the variable given by part1 and part2, such that
+ *	future references to the variable will be intermediated by the
+ *	traceProc listed in tracePtr. See the manual entry for complete
+ *	details on the calling sequence for proc.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+TraceVarEx(
+    Tcl_Interp *interp,		/* Interpreter in which variable is to be
+				 * traced. */
+    const char *part1,		/* Name of scalar variable or array. */
+    const char *part2,		/* Name of element within array; NULL means
+				 * trace applies to scalar variable or array
+				 * as-a-whole. */
+    register VarTrace *tracePtr)/* Structure containing flags, traceProc and
+				 * clientData fields. Others should be left
+				 * blank. Will be ckfree()d (eventually) if
+				 * this function returns TCL_OK, and up to
+				 * caller to free if this function returns
+				 * TCL_ERROR. */
+{
+    Interp *iPtr = (Interp *) interp;
+    Var *varPtr, *arrayPtr;
+    int flagMask, isNew;
+    Tcl_HashEntry *hPtr;
+
+    /*
+     * We strip 'flags' down to just the parts which are relevant to
+     * TclLookupVar, to avoid conflicts between trace flags and internal
+     * namespace flags such as 'TCL_FIND_ONLY_NS'. This can now occur since we
+     * have trace flags with values 0x1000 and higher.
+     */
+
+    flagMask = TCL_GLOBAL_ONLY | TCL_NAMESPACE_ONLY;
+    varPtr = TclLookupVar(interp, part1, part2,
+	    (tracePtr->flags & flagMask) | TCL_LEAVE_ERR_MSG,
+	    "trace", /*createPart1*/ 1, /*createPart2*/ 1, &arrayPtr);
+    if (varPtr == NULL) {
+	return TCL_ERROR;
+    }
+
+    /*
+     * Check for a nonsense flag combination. Note that this is a Tcl_Panic()
+     * because there should be no code path that ever sets both flags.
+     */
+
+    if ((tracePtr->flags & TCL_TRACE_RESULT_DYNAMIC)
+	    && (tracePtr->flags & TCL_TRACE_RESULT_OBJECT)) {
+	Tcl_Panic("bad result flag combination");
+    }
+
+    /*
+     * Set up trace information.
+     */
+
+    flagMask = TCL_TRACE_READS | TCL_TRACE_WRITES | TCL_TRACE_UNSETS |
+	  TCL_TRACE_ARRAY | TCL_TRACE_RESULT_DYNAMIC | TCL_TRACE_RESULT_OBJECT;
+#ifndef TCL_REMOVE_OBSOLETE_TRACES
+    flagMask |= TCL_TRACE_OLD_STYLE;
+#endif
+    tracePtr->flags = tracePtr->flags & flagMask;
+
+    hPtr = Tcl_CreateHashEntry(&iPtr->varTraces, varPtr, &isNew);
+    if (isNew) {
+	tracePtr->nextPtr = NULL;
+    } else {
+	tracePtr->nextPtr = Tcl_GetHashValue(hPtr);
+    }
+    Tcl_SetHashValue(hPtr, tracePtr);
+
+    /*
+     * Mark the variable as traced so we know to call them.
+     */
+
+    varPtr->flags |= (tracePtr->flags & VAR_ALL_TRACES);
+
+    return TCL_OK;
+}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tclUniData.c b/generic/tclUniData.c
new file mode 100644
index 0000000..d8b317a
--- /dev/null
+++ b/generic/tclUniData.c
@@ -0,0 +1,1614 @@
+/*
+ * tclUniData.c --
+ *
+ *	Declarations of Unicode character information tables.  This file is
+ *	automatically generated by the tools/uniParse.tcl script.  Do not
+ *	modify this file by hand.
+ *
+ * Copyright (c) 1998 by Scriptics Corporation.
+ * All rights reserved.
+ */
+
+/*
+ * A 16-bit Unicode character is split into two parts in order to index
+ * into the following tables.  The lower OFFSET_BITS comprise an offset
+ * into a page of characters.  The upper bits comprise the page number.
+ */
+
+#define OFFSET_BITS 5
+
+/*
+ * The pageMap is indexed by page number and returns an alternate page number
+ * that identifies a unique page of characters.  Many Unicode characters map
+ * to the same alternate page number.
+ */
+
+static const unsigned short pageMap[] = {
+    0, 32, 64, 96, 0, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416,
+    448, 224, 480, 512, 544, 576, 608, 640, 672, 704, 704, 736, 768, 800,
+    832, 864, 896, 928, 960, 992, 224, 1024, 224, 1056, 224, 224, 1088,
+    1120, 1152, 1184, 1216, 1248, 1280, 1312, 1344, 1376, 1408, 1344, 1344,
+    1440, 1472, 1504, 1536, 1568, 1344, 1344, 1600, 1632, 1664, 1696, 1728,
+    1760, 1792, 1792, 1824, 1856, 1888, 1920, 1952, 1984, 2016, 2048, 2080,
+    2112, 2144, 2176, 2208, 2240, 2272, 2304, 2336, 2368, 2400, 2432, 2464,
+    2496, 2528, 2560, 2592, 2624, 2656, 2688, 2720, 2752, 2784, 2816, 2848,
+    2880, 2912, 2944, 2976, 3008, 3040, 3072, 3104, 3136, 3168, 3200, 3232,
+    3264, 1792, 3296, 3328, 3360, 1792, 3392, 3424, 3456, 3488, 3520, 3552,
+    3584, 1792, 1344, 3616, 3648, 3680, 3712, 3744, 3776, 3808, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 3840, 1344, 3872, 3904,
+    3936, 1344, 3968, 1344, 4000, 4032, 4064, 4096, 4096, 4128, 4160, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 4192, 4224, 1344, 1344, 4256, 4288, 4320,
+    4352, 4384, 1344, 4416, 4448, 4480, 4512, 1344, 4544, 4576, 4608, 4640,
+    1344, 4672, 4704, 4736, 4768, 4800, 1344, 4832, 4864, 4896, 4928, 1344,
+    4960, 4992, 5024, 5056, 1792, 1792, 5088, 5120, 5152, 5184, 5216, 5248,
+    1344, 5280, 1344, 5312, 5344, 5376, 5408, 1792, 5440, 5472, 5504, 5536,
+    5568, 5600, 5632, 5568, 704, 5664, 224, 224, 224, 224, 5696, 224, 224,
+    224, 5728, 5760, 5792, 5824, 5856, 5888, 5920, 5952, 5984, 6016, 6048,
+    6080, 6112, 6144, 6176, 6208, 6240, 6272, 6304, 6336, 6368, 6400, 6432,
+    6464, 6496, 6496, 6496, 6496, 6496, 6496, 6496, 6496, 6528, 6560, 4896,
+    6592, 6624, 6656, 6688, 6720, 4896, 6752, 6784, 6816, 6848, 6880, 6912,
+    6944, 4896, 4896, 4896, 4896, 4896, 6976, 7008, 7040, 4896, 4896, 4896,
+    7072, 4896, 4896, 4896, 4896, 4896, 4896, 4896, 7104, 7136, 4896, 7168,
+    7200, 4896, 4896, 4896, 4896, 4896, 4896, 4896, 4896, 6496, 6496, 6496,
+    6496, 7232, 6496, 7264, 7296, 6496, 6496, 6496, 6496, 6496, 6496, 6496,
+    6496, 4896, 7328, 7360, 7392, 7424, 7456, 7488, 7520, 7552, 7584, 7616,
+    7648, 224, 224, 224, 7680, 7712, 7744, 1344, 7776, 7808, 7840, 7840,
+    704, 7872, 7904, 7936, 1792, 7968, 4896, 4896, 8000, 4896, 4896, 4896,
+    4896, 4896, 4896, 8032, 8064, 8096, 8128, 3200, 1344, 8160, 4160, 1344,
+    8192, 8224, 8256, 1344, 1344, 8288, 8320, 4896, 8352, 8384, 8416, 8448,
+    4896, 8416, 8480, 4896, 8384, 4896, 4896, 4896, 4896, 4896, 4896, 4896,
+    4896, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 4672, 4896, 4896, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 4672,
+    1792, 8512, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 8544, 4896, 8576, 5376, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 8608, 8640, 224, 8672, 8704, 1344, 1344, 8736, 8768, 8800, 224,
+    8832, 8864, 8896, 1792, 8928, 8960, 8992, 1344, 9024, 9056, 9088, 9120,
+    9152, 1632, 9184, 9216, 9248, 1920, 9280, 9312, 9344, 1344, 9376, 9408,
+    9440, 1344, 9472, 9504, 9536, 9568, 9600, 9632, 9664, 9696, 9696, 1344,
+    9728, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 9760, 9792, 9824, 9856, 9856, 9856, 9856, 9856, 9856, 9856,
+    9856, 9856, 9856, 9856, 9856, 9856, 9856, 9856, 9856, 9856, 9856, 9856,
+    9856, 9856, 9856, 9856, 9856, 9856, 9856, 9856, 9856, 9856, 9856, 9856,
+    9856, 9856, 9856, 9856, 9856, 9856, 9856, 9856, 9856, 9856, 9856, 9856,
+    9856, 9856, 9856, 9856, 9856, 9856, 9856, 9856, 9856, 9856, 9856, 9856,
+    9856, 9856, 9856, 9856, 9856, 9856, 9856, 9856, 9856, 9888, 9888, 9888,
+    9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888,
+    9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888,
+    9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888,
+    9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888,
+    9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888,
+    9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888,
+    9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888,
+    9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888,
+    9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888,
+    9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888,
+    9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888,
+    9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888,
+    9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888,
+    9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888,
+    9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888,
+    9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888, 9888,
+    9888, 9888, 9888, 9888, 9888, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 9920, 1344, 1344, 9952, 1792, 9984, 10016,
+    10048, 1344, 1344, 10080, 10112, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 10144, 10176, 1344, 10208, 1344, 10240, 10272,
+    10304, 10336, 10368, 10400, 1344, 1344, 1344, 10432, 10464, 64, 10496,
+    10528, 10560, 4704, 10592, 10624
+#if TCL_UTF_MAX > 3
+    ,10656, 10688, 10720, 1792, 1344, 1344, 1344, 8320, 10752, 10784, 10816,
+    10848, 10880, 10912, 10944, 10976, 1792, 1792, 1792, 1792, 9248, 1344,
+    11008, 11040, 1344, 11072, 11104, 11136, 11168, 1344, 11200, 1792,
+    11232, 11264, 11296, 1344, 11328, 11360, 11392, 11424, 1344, 11456,
+    1344, 11488, 1792, 1792, 1792, 1792, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 7808, 4672, 10240, 1792, 1792, 1792, 1792,
+    11520, 11552, 11584, 11616, 4704, 11648, 1792, 11680, 11712, 11744,
+    1792, 1792, 1344, 11776, 11808, 6816, 11840, 11872, 11904, 11936, 11968,
+    1792, 12000, 12032, 1344, 12064, 12096, 12128, 12160, 12192, 1792,
+    1792, 1344, 1344, 12224, 1792, 12256, 12288, 12320, 12352, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 12384, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 12416,
+    12448, 12480, 12512, 5216, 12544, 12576, 12608, 12640, 12672, 12704,
+    12736, 5216, 12768, 12800, 12832, 12864, 12896, 1792, 1792, 12928,
+    12960, 12992, 13024, 13056, 2336, 13088, 13120, 1792, 1792, 1792, 1792,
+    1344, 13152, 13184, 1792, 1344, 13216, 13248, 1792, 1792, 1792, 1792,
+    1792, 1344, 13280, 13312, 1792, 1344, 13344, 13376, 13408, 1344, 13440,
+    13472, 1792, 13504, 13536, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 13568, 13600, 13632, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1344, 13664,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 13696, 13728, 13760,
+    13792, 13824, 13856, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 9952, 1792,
+    1792, 1792, 10816, 10816, 10816, 13888, 1344, 1344, 1344, 1344, 1344,
+    1344, 13920, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 13952, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 13984, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 13664, 4704, 14016, 1792, 1792, 10176, 14048, 1344,
+    14080, 14112, 14144, 14176, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1344, 1344, 14208,
+    14240, 14272, 1792, 1792, 14304, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 14336, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 14368, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 14400, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1344, 1344, 1344, 14432, 14464, 14496,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 4896, 4896,
+    4896, 4896, 4896, 4896, 4896, 8032, 4896, 14528, 4896, 14560, 14592,
+    14624, 4896, 14656, 4896, 4896, 14688, 1792, 1792, 1792, 1792, 1792,
+    4896, 4896, 14720, 14752, 1792, 1792, 1792, 1792, 14784, 14816, 14848,
+    14880, 14912, 14944, 14976, 15008, 15040, 15072, 15104, 15136, 15168,
+    14784, 14816, 15200, 14880, 15232, 15264, 15296, 15008, 15328, 15360,
+    15392, 15424, 15456, 15488, 15520, 15552, 15584, 15616, 15648, 4896,
+    4896, 4896, 4896, 4896, 4896, 4896, 4896, 4896, 4896, 4896, 4896, 4896,
+    4896, 4896, 4896, 704, 15680, 704, 15712, 15744, 15776, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 15808, 15840, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1344, 1344, 1344,
+    1344, 1344, 1344, 15872, 1792, 15904, 15936, 15968, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 16000,
+    16032, 16064, 16096, 16128, 16160, 1792, 16192, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 4896, 16224, 4896, 4896, 8000, 16256, 16288,
+    8032, 16320, 16352, 4896, 16224, 4896, 16384, 1792, 16416, 16448, 16480,
+    16512, 1792, 1792, 1792, 1792, 1792, 4896, 4896, 4896, 4896, 4896,
+    4896, 4896, 16544, 4896, 4896, 4896, 4896, 4896, 4896, 4896, 4896,
+    4896, 4896, 4896, 4896, 4896, 4896, 4896, 4896, 4896, 4896, 4896, 4896,
+    4896, 4896, 16576, 16608, 4896, 4896, 4896, 8000, 4896, 4896, 16640,
+    1792, 16224, 4896, 16672, 4896, 16704, 16736, 1792, 1792, 16768, 16800,
+    16832, 1792, 16864, 1792, 10912, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 7808, 1792, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 16896, 1344, 1344,
+    1344, 1344, 1344, 1344, 11328, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 14400, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792, 1792,
+    1792, 1792, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344, 1344,
+    1344, 1344, 1344, 1344, 1344, 1344, 11328
+#endif /* TCL_UTF_MAX > 3 */
+};
+
+/*
+ * The groupMap is indexed by combining the alternate page number with
+ * the page offset and returns a group number that identifies a unique
+ * set of character attributes.
+ */
+
+static const unsigned char groupMap[] = {
+    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, 3, 3, 3, 4, 3, 3, 3, 5, 6, 3, 7, 3, 8,
+    3, 3, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 3, 3, 7, 7, 7, 3, 3, 10, 10, 10,
+    10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+    10, 10, 10, 10, 10, 10, 5, 3, 6, 11, 12, 11, 13, 13, 13, 13, 13, 13,
+    13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+    13, 13, 13, 5, 7, 6, 7, 1, 2, 3, 4, 4, 4, 4, 14, 3, 11, 14, 15, 16,
+    7, 17, 14, 11, 14, 7, 18, 18, 11, 19, 3, 3, 11, 18, 15, 20, 18, 18,
+    18, 3, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+    10, 10, 10, 10, 10, 10, 10, 10, 7, 10, 10, 10, 10, 10, 10, 10, 21,
+    13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+    13, 13, 13, 13, 13, 13, 7, 13, 13, 13, 13, 13, 13, 13, 22, 23, 24,
+    23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23,
+    24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24,
+    23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 25, 26, 23, 24, 23,
+    24, 23, 24, 21, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23,
+    24, 23, 24, 21, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23,
+    24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24,
+    23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 27,
+    23, 24, 23, 24, 23, 24, 28, 29, 30, 23, 24, 23, 24, 31, 23, 24, 32,
+    32, 23, 24, 21, 33, 34, 35, 23, 24, 32, 36, 37, 38, 39, 23, 24, 40,
+    21, 38, 41, 42, 43, 23, 24, 23, 24, 23, 24, 44, 23, 24, 44, 21, 21,
+    23, 24, 44, 23, 24, 45, 45, 23, 24, 23, 24, 46, 23, 24, 21, 15, 23,
+    24, 21, 47, 15, 15, 15, 15, 48, 49, 50, 48, 49, 50, 48, 49, 50, 23,
+    24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 51, 23,
+    24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24,
+    21, 48, 49, 50, 23, 24, 52, 53, 23, 24, 23, 24, 23, 24, 23, 24, 54,
+    21, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24,
+    23, 24, 21, 21, 21, 21, 21, 21, 55, 23, 24, 56, 57, 58, 58, 23, 24,
+    59, 60, 61, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 62, 63, 64, 65,
+    66, 21, 67, 67, 21, 68, 21, 69, 70, 21, 21, 21, 67, 71, 21, 72, 21,
+    73, 74, 21, 75, 76, 74, 77, 78, 21, 21, 76, 21, 79, 80, 21, 21, 81,
+    21, 21, 21, 21, 21, 21, 21, 82, 21, 21, 83, 21, 21, 83, 21, 21, 21,
+    84, 83, 85, 86, 86, 87, 21, 21, 21, 21, 21, 88, 21, 15, 21, 21, 21,
+    21, 21, 21, 21, 21, 89, 90, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+    21, 21, 21, 21, 21, 21, 21, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+    91, 91, 91, 91, 91, 91, 91, 91, 11, 11, 11, 11, 91, 91, 91, 91, 91,
+    91, 91, 91, 91, 91, 91, 91, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+    11, 11, 11, 11, 91, 91, 91, 91, 91, 11, 11, 11, 11, 11, 11, 11, 91,
+    11, 91, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+    11, 11, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+    92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+    92, 92, 92, 92, 92, 93, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+    92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+    92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 23, 24, 23,
+    24, 91, 11, 23, 24, 0, 0, 91, 42, 42, 42, 3, 94, 0, 0, 0, 0, 11, 11,
+    95, 3, 96, 96, 96, 0, 97, 0, 98, 98, 21, 10, 10, 10, 10, 10, 10, 10,
+    10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 0, 10, 10, 10, 10, 10, 10,
+    10, 10, 10, 99, 100, 100, 100, 21, 13, 13, 13, 13, 13, 13, 13, 13,
+    13, 13, 13, 13, 13, 13, 13, 13, 13, 101, 13, 13, 13, 13, 13, 13, 13,
+    13, 13, 102, 103, 103, 104, 105, 106, 107, 107, 107, 108, 109, 110,
+    23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23,
+    24, 23, 24, 23, 24, 23, 24, 111, 112, 113, 114, 115, 116, 7, 23, 24,
+    117, 23, 24, 21, 54, 54, 54, 118, 118, 118, 118, 118, 118, 118, 118,
+    118, 118, 118, 118, 118, 118, 118, 118, 10, 10, 10, 10, 10, 10, 10,
+    10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+    10, 10, 10, 10, 10, 10, 10, 10, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+    13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+    13, 13, 13, 13, 13, 13, 112, 112, 112, 112, 112, 112, 112, 112, 112,
+    112, 112, 112, 112, 112, 112, 112, 23, 24, 14, 92, 92, 92, 92, 92,
+    119, 119, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23,
+    24, 23, 24, 23, 24, 23, 24, 120, 23, 24, 23, 24, 23, 24, 23, 24, 23,
+    24, 23, 24, 23, 24, 121, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23,
+    24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24,
+    23, 24, 23, 24, 0, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122,
+    122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122,
+    122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122,
+    0, 0, 91, 3, 3, 3, 3, 3, 3, 0, 123, 123, 123, 123, 123, 123, 123, 123,
+    123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123,
+    123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123,
+    123, 123, 21, 0, 3, 8, 0, 0, 14, 14, 4, 0, 92, 92, 92, 92, 92, 92,
+    92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+    92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+    92, 92, 92, 92, 92, 8, 92, 3, 92, 92, 3, 92, 92, 3, 92, 0, 0, 0, 0,
+    0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0,
+    15, 15, 15, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 17, 17, 17,
+    17, 17, 7, 7, 7, 3, 3, 4, 3, 3, 14, 14, 92, 92, 92, 92, 92, 92, 92,
+    92, 92, 92, 92, 3, 17, 0, 3, 3, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 91, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+    92, 92, 92, 92, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 3, 3, 3, 3, 15, 15, 92,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 3, 15, 92, 92, 92, 92, 92, 92, 92, 17, 14, 92, 92, 92, 92, 92,
+    92, 91, 91, 92, 92, 14, 92, 92, 92, 92, 15, 15, 9, 9, 9, 9, 9, 9, 9,
+    9, 9, 9, 15, 15, 15, 14, 14, 15, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+    3, 3, 0, 17, 15, 92, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+    92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 0, 0, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 15, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 92, 92,
+    92, 92, 92, 92, 92, 92, 92, 91, 91, 14, 3, 3, 3, 91, 0, 0, 0, 0, 0,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 92, 92, 92, 92, 91, 92, 92, 92, 92, 92, 92, 92,
+    92, 92, 91, 92, 92, 92, 91, 92, 92, 92, 92, 92, 0, 0, 3, 3, 3, 3, 3,
+    3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 92,
+    92, 92, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0,
+    15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+    92, 92, 92, 92, 17, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+    92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+    92, 92, 92, 124, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 92, 124, 92, 15, 124, 124, 124, 92, 92,
+    92, 92, 92, 92, 92, 92, 124, 124, 124, 124, 92, 124, 124, 15, 92, 92,
+    92, 92, 92, 92, 92, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 92, 92,
+    3, 3, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 3, 91, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 92, 124, 124, 0, 15, 15, 15, 15,
+    15, 15, 15, 15, 0, 0, 15, 15, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15,
+    15, 15, 15, 15, 15, 0, 15, 0, 0, 0, 15, 15, 15, 15, 0, 0, 92, 15, 124,
+    124, 124, 92, 92, 92, 92, 0, 0, 124, 124, 0, 0, 124, 124, 92, 15, 0,
+    0, 0, 0, 0, 0, 0, 0, 124, 0, 0, 0, 0, 15, 15, 0, 15, 15, 15, 92, 92,
+    0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 15, 15, 4, 4, 18, 18, 18, 18, 18,
+    18, 14, 4, 0, 0, 0, 0, 0, 92, 92, 124, 0, 15, 15, 15, 15, 15, 15, 0,
+    0, 0, 0, 15, 15, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, 15,
+    15, 15, 0, 15, 15, 0, 15, 15, 0, 15, 15, 0, 0, 92, 0, 124, 124, 124,
+    92, 92, 0, 0, 0, 0, 92, 92, 0, 0, 92, 92, 92, 0, 0, 0, 92, 0, 0, 0,
+    0, 0, 0, 0, 15, 15, 15, 15, 0, 15, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9,
+    9, 9, 9, 9, 9, 9, 92, 92, 15, 15, 15, 92, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 92, 92, 124, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15,
+    15, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15,
+    0, 15, 15, 15, 15, 15, 0, 0, 92, 15, 124, 124, 124, 92, 92, 92, 92,
+    92, 0, 92, 92, 124, 0, 124, 124, 92, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 92, 92, 0, 0, 9, 9, 9, 9, 9, 9, 9,
+    9, 9, 9, 3, 4, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 92, 124,
+    124, 0, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 15, 15, 0, 0, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 0, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 0, 15, 15, 15,
+    15, 15, 0, 0, 92, 15, 124, 92, 124, 92, 92, 92, 92, 0, 0, 124, 124,
+    0, 0, 124, 124, 92, 0, 0, 0, 0, 0, 0, 0, 0, 92, 124, 0, 0, 0, 0, 15,
+    15, 0, 15, 15, 15, 92, 92, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 14,
+    15, 18, 18, 18, 18, 18, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 92, 15, 0,
+    15, 15, 15, 15, 15, 15, 0, 0, 0, 15, 15, 15, 0, 15, 15, 15, 15, 0,
+    0, 0, 15, 15, 0, 15, 0, 15, 15, 0, 0, 0, 15, 15, 0, 0, 0, 15, 15, 15,
+    0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0,
+    124, 124, 92, 124, 124, 0, 0, 0, 124, 124, 124, 0, 124, 124, 124, 92,
+    0, 0, 15, 0, 0, 0, 0, 0, 0, 124, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 18, 18, 18, 14, 14, 14, 14, 14,
+    14, 4, 14, 0, 0, 0, 0, 0, 92, 124, 124, 124, 0, 15, 15, 15, 15, 15,
+    15, 15, 15, 0, 15, 15, 15, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 15, 92,
+    92, 92, 124, 124, 124, 124, 0, 92, 92, 92, 0, 92, 92, 92, 92, 0, 0,
+    0, 0, 0, 0, 0, 92, 92, 0, 15, 15, 15, 0, 0, 0, 0, 0, 15, 15, 92, 92,
+    0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 18, 18,
+    18, 18, 18, 18, 18, 14, 15, 92, 124, 124, 0, 15, 15, 15, 15, 15, 15,
+    15, 15, 0, 15, 15, 15, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, 15, 0, 0, 92, 15, 124, 92,
+    124, 124, 124, 124, 124, 0, 92, 124, 124, 0, 124, 124, 92, 92, 0, 0,
+    0, 0, 0, 0, 0, 124, 124, 0, 0, 0, 0, 0, 0, 0, 15, 0, 15, 15, 92, 92,
+    0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 15, 15, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 92, 124, 124, 0, 15, 15, 15, 15, 15, 15, 15, 15,
+    0, 15, 15, 15, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 15, 124, 124, 124,
+    92, 92, 92, 92, 0, 124, 124, 124, 0, 124, 124, 124, 92, 15, 14, 0,
+    0, 0, 0, 15, 15, 15, 124, 18, 18, 18, 18, 18, 18, 18, 15, 15, 15, 92,
+    92, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 18, 18, 18, 18, 18, 18, 18,
+    18, 18, 14, 15, 15, 15, 15, 15, 15, 0, 0, 124, 124, 0, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    0, 15, 0, 0, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 92, 0, 0, 0, 0, 124,
+    124, 124, 92, 92, 92, 0, 92, 0, 124, 124, 124, 124, 124, 124, 124,
+    124, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 124, 124,
+    3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 92, 15, 15, 92, 92, 92, 92, 92, 92, 92,
+    0, 0, 0, 0, 4, 15, 15, 15, 15, 15, 15, 91, 92, 92, 92, 92, 92, 92,
+    92, 92, 3, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 3, 3, 0, 0, 0, 0, 0, 15, 15,
+    0, 15, 0, 0, 15, 15, 0, 15, 0, 0, 15, 0, 0, 0, 0, 0, 0, 15, 15, 15,
+    15, 0, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 0, 15, 0, 15, 0,
+    0, 15, 15, 0, 15, 15, 15, 15, 92, 15, 15, 92, 92, 92, 92, 92, 92, 0,
+    92, 92, 15, 0, 0, 15, 15, 15, 15, 15, 0, 91, 0, 92, 92, 92, 92, 92,
+    92, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 15, 15, 15, 15, 15, 14,
+    14, 14, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 14, 3, 14, 14,
+    14, 92, 92, 14, 14, 14, 14, 14, 14, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 18,
+    18, 18, 18, 18, 18, 18, 18, 18, 18, 14, 92, 14, 92, 14, 92, 5, 6, 5,
+    6, 124, 124, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0,
+    92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 124, 92, 92,
+    92, 92, 92, 3, 92, 92, 15, 15, 15, 15, 15, 92, 92, 92, 92, 92, 92,
+    92, 92, 92, 92, 92, 0, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+    92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+    92, 92, 92, 92, 92, 92, 92, 92, 0, 14, 14, 14, 14, 14, 14, 14, 14,
+    92, 14, 14, 14, 14, 14, 14, 0, 14, 14, 3, 3, 3, 3, 3, 14, 14, 14, 14,
+    3, 3, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 124,
+    124, 92, 92, 92, 92, 124, 92, 92, 92, 92, 92, 92, 124, 92, 92, 124,
+    124, 92, 92, 15, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 3, 3, 3, 3, 3, 3, 15,
+    15, 15, 15, 15, 15, 124, 124, 92, 92, 15, 15, 15, 15, 92, 92, 92, 15,
+    124, 124, 124, 15, 15, 124, 124, 124, 124, 124, 124, 124, 15, 15, 15,
+    92, 92, 92, 92, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    92, 124, 124, 92, 92, 124, 124, 124, 124, 124, 124, 92, 15, 124, 9,
+    9, 9, 9, 9, 9, 9, 9, 9, 9, 124, 124, 124, 92, 14, 14, 125, 125, 125,
+    125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125,
+    125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125, 125,
+    125, 125, 125, 125, 125, 125, 125, 0, 125, 0, 0, 0, 0, 0, 125, 0, 0,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 3, 91, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, 0, 0, 15, 15, 15, 15, 15,
+    15, 15, 0, 15, 0, 15, 15, 15, 15, 0, 0, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 0, 15, 15, 15, 15, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, 0, 0, 15, 15, 15, 15,
+    15, 15, 15, 0, 15, 0, 15, 15, 15, 15, 0, 0, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 0, 15, 15, 15, 15, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 92, 92, 92, 3, 3, 3, 3, 3, 3,
+    3, 3, 3, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+    18, 18, 18, 18, 18, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0,
+    0, 0, 0, 0, 0, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126,
+    126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126,
+    126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126, 126,
+    126, 126, 126, 126, 126, 126, 126, 126, 126, 104, 104, 104, 104, 104,
+    104, 0, 0, 110, 110, 110, 110, 110, 110, 0, 0, 8, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 3, 3, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 2, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 5,
+    6, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 3, 3, 3, 127,
+    127, 127, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 15,
+    92, 92, 92, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 92, 92, 92, 3, 3, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 92, 92, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15,
+    0, 92, 92, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 92, 92,
+    124, 92, 92, 92, 92, 92, 92, 92, 124, 124, 124, 124, 124, 124, 124,
+    124, 92, 124, 124, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 3, 3,
+    3, 91, 3, 3, 3, 4, 15, 92, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0,
+    0, 0, 0, 0, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 0, 0, 0, 0, 0,
+    0, 3, 3, 3, 3, 3, 3, 8, 3, 3, 3, 3, 92, 92, 92, 17, 0, 9, 9, 9, 9,
+    9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 15, 15, 15, 91, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0,
+    0, 0, 0, 0, 15, 15, 15, 15, 15, 92, 92, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 92, 15, 0, 0, 0, 0, 0, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 0, 92, 92, 92, 124, 124, 124, 124, 92,
+    92, 124, 124, 124, 0, 0, 0, 0, 124, 124, 92, 124, 124, 124, 124, 124,
+    124, 92, 92, 92, 0, 0, 0, 0, 14, 0, 0, 0, 3, 3, 9, 9, 9, 9, 9, 9, 9,
+    9, 9, 9, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 15,
+    15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 18, 0, 0, 0,
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 92, 92, 124, 124, 92, 0, 0, 3, 3, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 124, 92, 124, 92, 92, 92, 92, 92, 92, 92, 0, 92, 124, 92, 124,
+    124, 92, 92, 92, 92, 92, 92, 92, 92, 124, 124, 124, 124, 124, 124,
+    92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 0, 0, 92, 9, 9, 9, 9, 9, 9,
+    9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0,
+    0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 91, 3, 3, 3, 3, 3, 3, 0, 0, 92, 92, 92,
+    92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 119, 0, 92, 92, 92, 92,
+    124, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 92, 124, 92,
+    92, 92, 92, 92, 124, 92, 124, 124, 124, 124, 124, 92, 124, 124, 15,
+    15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 3,
+    3, 3, 3, 3, 3, 3, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 92, 92, 92,
+    92, 92, 92, 92, 92, 92, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0,
+    92, 92, 124, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 124,
+    92, 92, 92, 92, 124, 124, 92, 92, 124, 92, 92, 92, 15, 15, 9, 9, 9,
+    9, 9, 9, 9, 9, 9, 9, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    92, 124, 92, 92, 124, 124, 124, 92, 124, 92, 92, 92, 124, 124, 0, 0,
+    0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 15, 15, 15, 15, 124, 124, 124, 124, 124,
+    124, 124, 124, 92, 92, 92, 92, 92, 92, 92, 92, 124, 124, 92, 92, 0,
+    0, 0, 3, 3, 3, 3, 3, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 15, 15,
+    15, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 91, 91, 91, 91, 91, 91, 3, 3, 128, 129, 130, 131, 131,
+    132, 133, 134, 135, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0,
+    92, 92, 92, 3, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+    124, 92, 92, 92, 92, 92, 92, 92, 15, 15, 15, 15, 92, 15, 15, 15, 15,
+    124, 124, 92, 15, 15, 0, 92, 92, 0, 0, 0, 0, 0, 0, 21, 21, 21, 21,
+    21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+    21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+    21, 21, 21, 21, 21, 21, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+    91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+    91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+    91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+    91, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 91, 136, 21,
+    21, 21, 137, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+    21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 91, 91,
+    91, 91, 91, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+    92, 92, 92, 92, 92, 92, 92, 92, 0, 0, 0, 0, 0, 92, 92, 92, 92, 92,
+    23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23,
+    24, 23, 24, 23, 24, 21, 21, 21, 21, 21, 138, 21, 21, 139, 21, 140,
+    140, 140, 140, 140, 140, 140, 140, 141, 141, 141, 141, 141, 141, 141,
+    141, 140, 140, 140, 140, 140, 140, 0, 0, 141, 141, 141, 141, 141, 141,
+    0, 0, 140, 140, 140, 140, 140, 140, 140, 140, 141, 141, 141, 141, 141,
+    141, 141, 141, 140, 140, 140, 140, 140, 140, 140, 140, 141, 141, 141,
+    141, 141, 141, 141, 141, 140, 140, 140, 140, 140, 140, 0, 0, 141, 141,
+    141, 141, 141, 141, 0, 0, 21, 140, 21, 140, 21, 140, 21, 140, 0, 141,
+    0, 141, 0, 141, 0, 141, 140, 140, 140, 140, 140, 140, 140, 140, 141,
+    141, 141, 141, 141, 141, 141, 141, 142, 142, 143, 143, 143, 143, 144,
+    144, 145, 145, 146, 146, 147, 147, 0, 0, 140, 140, 140, 140, 140, 140,
+    140, 140, 148, 148, 148, 148, 148, 148, 148, 148, 140, 140, 140, 140,
+    140, 140, 140, 140, 148, 148, 148, 148, 148, 148, 148, 148, 140, 140,
+    140, 140, 140, 140, 140, 140, 148, 148, 148, 148, 148, 148, 148, 148,
+    140, 140, 21, 149, 21, 0, 21, 21, 141, 141, 150, 150, 151, 11, 152,
+    11, 11, 11, 21, 149, 21, 0, 21, 21, 153, 153, 153, 153, 151, 11, 11,
+    11, 140, 140, 21, 21, 0, 0, 21, 21, 141, 141, 154, 154, 0, 11, 11,
+    11, 140, 140, 21, 21, 21, 113, 21, 21, 141, 141, 155, 155, 117, 11,
+    11, 11, 0, 0, 21, 149, 21, 0, 21, 21, 156, 156, 157, 157, 151, 11,
+    11, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 17, 17, 17, 17, 17, 8, 8, 8,
+    8, 8, 8, 3, 3, 16, 20, 5, 16, 16, 20, 5, 16, 3, 3, 3, 3, 3, 3, 3, 3,
+    158, 159, 17, 17, 17, 17, 17, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 16, 20,
+    3, 3, 3, 3, 12, 12, 3, 3, 3, 7, 5, 6, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+    3, 7, 3, 12, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 17, 17, 17, 17, 17, 0,
+    17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 18, 91, 0, 0, 18, 18, 18, 18,
+    18, 18, 7, 7, 7, 5, 6, 91, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+    7, 7, 7, 5, 6, 0, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91,
+    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, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+    119, 119, 119, 119, 92, 119, 119, 119, 92, 92, 92, 92, 92, 92, 92,
+    92, 92, 92, 92, 92, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14,
+    14, 107, 14, 14, 14, 14, 107, 14, 14, 21, 107, 107, 107, 21, 21, 107,
+    107, 107, 21, 14, 107, 14, 14, 7, 107, 107, 107, 107, 107, 14, 14,
+    14, 14, 14, 14, 107, 14, 160, 14, 107, 14, 161, 162, 107, 107, 14,
+    21, 107, 107, 163, 107, 21, 15, 15, 15, 15, 21, 14, 14, 21, 21, 107,
+    107, 7, 7, 7, 7, 7, 107, 21, 21, 21, 21, 14, 7, 14, 14, 164, 14, 18,
+    18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 165, 165,
+    165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165,
+    166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166, 166,
+    166, 166, 127, 127, 127, 23, 24, 127, 127, 127, 127, 18, 14, 14, 0,
+    0, 0, 0, 7, 7, 7, 7, 7, 14, 14, 14, 14, 14, 7, 7, 14, 14, 14, 14, 7,
+    14, 14, 7, 14, 14, 7, 14, 14, 14, 14, 14, 14, 14, 7, 14, 14, 14, 14,
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 7, 7, 14, 14, 7, 14, 7, 14,
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 7, 7, 7, 7, 7,
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 14, 14, 14, 14, 14,
+    14, 14, 14, 5, 6, 5, 6, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 7, 7, 14, 14, 14, 14, 14, 14, 14,
+    5, 6, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 7,
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 7, 7, 7, 7, 7,
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 14, 14,
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+    14, 14, 14, 14, 7, 7, 7, 7, 7, 7, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+    14, 14, 14, 0, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 14, 14, 14,
+    14, 14, 14, 14, 14, 14, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+    18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+    18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+    18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 14, 14,
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+    14, 14, 14, 14, 14, 14, 14, 167, 167, 167, 167, 167, 167, 167, 167,
+    167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167, 167,
+    167, 167, 167, 167, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168,
+    168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, 168,
+    168, 168, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+    18, 18, 18, 18, 18, 18, 18, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 7, 14, 14, 14,
+    14, 14, 14, 14, 14, 14, 7, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 7, 7, 7, 7, 7, 7, 7, 7, 14,
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 7, 14, 14,
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+    14, 14, 14, 14, 14, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 18, 18,
+    18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+    18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 14, 14, 14, 14, 14, 14,
+    14, 14, 14, 14, 14, 14, 7, 7, 7, 7, 7, 5, 6, 7, 7, 7, 7, 7, 7, 7, 7,
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+    5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+    7, 7, 7, 7, 7, 7, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5,
+    6, 5, 6, 5, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 5, 6, 5, 6, 7, 7, 7, 7, 7, 7,
+    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+    7, 7, 7, 5, 6, 7, 7, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+    14, 14, 14, 14, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
+    7, 7, 7, 7, 14, 14, 7, 7, 7, 7, 7, 7, 14, 14, 14, 14, 14, 14, 14, 14,
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 14, 14,
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 14, 14, 14,
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, 14,
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 14, 14, 14, 14, 14,
+    14, 14, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 14, 14, 14, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122,
+    122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122,
+    122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122, 122,
+    122, 122, 122, 122, 122, 122, 122, 122, 122, 0, 123, 123, 123, 123,
+    123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123,
+    123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123,
+    123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123, 123,
+    123, 0, 23, 24, 169, 170, 171, 172, 173, 23, 24, 23, 24, 23, 24, 174,
+    175, 176, 177, 21, 23, 24, 21, 23, 24, 21, 21, 21, 21, 21, 91, 91,
+    178, 178, 23, 24, 23, 24, 21, 14, 14, 14, 14, 14, 14, 23, 24, 23, 24,
+    92, 92, 92, 23, 24, 0, 0, 0, 0, 0, 3, 3, 3, 3, 18, 3, 3, 179, 179,
+    179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179,
+    179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179, 179,
+    179, 179, 179, 179, 179, 179, 179, 179, 0, 179, 0, 0, 0, 0, 0, 179,
+    0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 91, 3, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 92, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, 15,
+    15, 15, 0, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, 15, 15, 15,
+    0, 3, 3, 16, 20, 16, 20, 3, 3, 3, 16, 20, 3, 16, 20, 3, 3, 3, 3, 3,
+    3, 3, 3, 3, 8, 3, 3, 8, 3, 16, 20, 3, 3, 16, 20, 5, 6, 5, 6, 5, 6,
+    5, 6, 3, 3, 3, 3, 3, 91, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 8, 8, 3, 3,
+    3, 3, 8, 3, 5, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+    0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+    14, 14, 14, 14, 14, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+    14, 14, 14, 0, 0, 0, 0, 2, 3, 3, 3, 14, 91, 15, 127, 5, 6, 5, 6, 5,
+    6, 5, 6, 5, 6, 14, 14, 5, 6, 5, 6, 5, 6, 5, 6, 8, 5, 6, 6, 14, 127,
+    127, 127, 127, 127, 127, 127, 127, 127, 92, 92, 92, 92, 124, 124, 8,
+    91, 91, 91, 91, 91, 14, 14, 127, 127, 127, 91, 15, 3, 14, 14, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 0, 0, 92, 92, 11, 11, 91, 91, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 3, 91, 91, 91, 15, 0, 0, 0, 0, 0, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 0, 14, 14, 18, 18, 18, 18, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+    14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 14, 14,
+    14, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 14, 14, 14, 14, 14, 14, 14,
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+    14, 14, 14, 14, 14, 14, 14, 0, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+    18, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 18, 18, 18,
+    18, 18, 18, 18, 18, 14, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+    18, 18, 18, 18, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+    14, 14, 14, 14, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+    18, 18, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 91, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 14, 14,
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+    14, 14, 14, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 91, 3, 3, 3, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 15, 15, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, 24, 23,
+    24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 15, 92, 119, 119, 119,
+    3, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 3, 91, 23, 24, 23, 24, 23,
+    24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24,
+    23, 24, 23, 24, 23, 24, 91, 91, 92, 92, 15, 15, 15, 15, 15, 15, 127,
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 92, 92, 3, 3, 3, 3, 3,
+    3, 0, 0, 0, 0, 0, 0, 0, 0, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+    11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 91, 91, 91, 91,
+    91, 91, 91, 91, 91, 11, 11, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24,
+    23, 24, 23, 24, 21, 21, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23,
+    24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24,
+    23, 24, 91, 21, 21, 21, 21, 21, 21, 21, 21, 23, 24, 23, 24, 180, 23,
+    24, 23, 24, 23, 24, 23, 24, 23, 24, 91, 11, 11, 23, 24, 181, 21, 15,
+    23, 24, 23, 24, 21, 21, 23, 24, 23, 24, 23, 24, 23, 24, 23, 24, 23,
+    24, 23, 24, 23, 24, 23, 24, 23, 24, 182, 183, 184, 185, 182, 0, 186,
+    187, 188, 189, 23, 24, 23, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 91, 91,
+    21, 15, 15, 15, 15, 15, 15, 15, 92, 15, 15, 15, 92, 15, 15, 15, 15,
+    92, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 124, 124, 92, 92, 124, 14, 14, 14, 14,
+    0, 0, 0, 0, 18, 18, 18, 18, 18, 18, 14, 14, 4, 14, 0, 0, 0, 0, 0, 0,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 124, 124, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 124, 124, 124,
+    124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 92,
+    92, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0,
+    0, 0, 0, 0, 0, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+    92, 92, 92, 92, 92, 15, 15, 15, 15, 15, 15, 3, 3, 3, 15, 3, 15, 0,
+    0, 15, 15, 15, 15, 15, 15, 92, 92, 92, 92, 92, 92, 92, 92, 3, 3, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 124,
+    124, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 92, 124, 124, 92, 92, 92, 92, 124,
+    124, 92, 124, 124, 124, 124, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+    0, 91, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 3, 3, 15, 15, 15,
+    15, 15, 92, 91, 15, 15, 15, 15, 15, 15, 15, 15, 15, 9, 9, 9, 9, 9,
+    9, 9, 9, 9, 9, 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 92, 92, 92, 92, 92, 92, 124, 124, 92, 92, 124, 124, 92, 92, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 92, 15, 15, 15, 15, 15, 15, 15,
+    15, 92, 124, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 3, 3, 3, 3,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 91,
+    15, 15, 15, 15, 15, 15, 14, 14, 14, 15, 124, 92, 124, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 92, 15, 92,
+    92, 92, 15, 15, 92, 92, 15, 15, 15, 15, 15, 92, 92, 15, 92, 15, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    15, 15, 91, 3, 3, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 124,
+    92, 92, 124, 124, 3, 3, 15, 91, 91, 124, 92, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 15, 15, 15, 15, 15, 15, 0, 0, 15, 15, 15, 15, 15, 15, 0, 0, 15,
+    15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15,
+    15, 15, 0, 15, 15, 15, 15, 15, 15, 15, 0, 21, 21, 21, 21, 21, 21, 21,
+    21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+    21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 190, 21, 21, 21, 21, 21,
+    21, 21, 11, 91, 91, 91, 91, 21, 21, 21, 21, 21, 21, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191,
+    191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191,
+    191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191, 191,
+    191, 191, 191, 191, 191, 191, 191, 191, 191, 15, 15, 15, 124, 124,
+    92, 124, 124, 92, 124, 124, 3, 124, 92, 0, 0, 9, 9, 9, 9, 9, 9, 9,
+    9, 9, 9, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 192, 192, 192,
+    192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192,
+    192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192, 192,
+    192, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193,
+    193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193, 193,
+    193, 193, 193, 193, 193, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 21,
+    21, 21, 21, 21, 21, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 21,
+    21, 21, 21, 0, 0, 0, 0, 0, 15, 92, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 7, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15,
+    15, 15, 15, 15, 0, 15, 0, 15, 15, 0, 15, 15, 0, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
+    11, 11, 11, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 6, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 4,
+    14, 0, 0, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+    92, 3, 3, 3, 3, 3, 3, 3, 5, 6, 3, 0, 0, 0, 0, 0, 0, 92, 92, 92, 92,
+    92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 3, 8, 8, 12, 12, 5,
+    6, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 5, 6, 3, 3, 5, 6, 3, 3, 3, 3,
+    12, 12, 12, 3, 3, 3, 0, 3, 3, 3, 3, 8, 5, 6, 5, 6, 5, 6, 3, 3, 3, 7,
+    8, 7, 7, 7, 0, 3, 4, 3, 3, 0, 0, 0, 0, 15, 15, 15, 15, 15, 0, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 0, 0, 17, 0, 3, 3, 3, 4, 3, 3, 3, 5, 6, 3, 7, 3, 8, 3,
+    3, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 3, 3, 7, 7, 7, 3, 11, 13, 13, 13,
+    13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+    13, 13, 13, 13, 13, 13, 5, 7, 6, 7, 5, 6, 3, 5, 6, 3, 3, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 91, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 91, 91, 0, 0, 15, 15, 15, 15, 15, 15, 0, 0, 15, 15, 15, 15,
+    15, 15, 0, 0, 15, 15, 15, 15, 15, 15, 0, 0, 15, 15, 15, 0, 0, 0, 4,
+    4, 7, 11, 14, 4, 4, 0, 14, 7, 7, 7, 7, 14, 14, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 17, 17, 17, 14, 14, 0, 0
+#if TCL_UTF_MAX > 3
+    ,15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 0, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 0, 0, 3, 3, 3, 0, 0, 0, 0, 18, 18, 18,
+    18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+    18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+    18, 18, 18, 18, 18, 18, 18, 18, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14,
+    14, 14, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+    127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 127, 18,
+    18, 18, 18, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+    14, 14, 14, 18, 18, 14, 14, 14, 0, 14, 14, 14, 14, 14, 14, 14, 14,
+    14, 14, 14, 14, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14,
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+    14, 14, 14, 92, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 92,
+    18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+    18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 0, 0, 0, 0, 18, 18, 18, 18,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 127, 15, 15, 15, 15, 15, 15, 15,
+    15, 127, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 92, 92, 92, 92, 92, 0, 0, 0,
+    0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 3, 15, 15,
+    15, 15, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 3, 127, 127, 127,
+    127, 127, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 194, 194, 194, 194, 194, 194,
+    194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194,
+    194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194,
+    194, 194, 194, 194, 194, 194, 195, 195, 195, 195, 195, 195, 195, 195,
+    195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195,
+    195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195,
+    195, 195, 195, 195, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 194, 194, 194,
+    194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194,
+    194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194, 194,
+    194, 194, 194, 194, 194, 0, 0, 0, 0, 195, 195, 195, 195, 195, 195,
+    195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195,
+    195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195,
+    195, 195, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0,
+    0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 0, 0, 15,
+    0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 0, 0, 0, 15,
+    0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 0, 3, 18, 18, 18, 18, 18, 18, 18, 18, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 14, 14, 18, 18, 18, 18, 18, 18, 18, 0, 0, 0, 0,
+    0, 0, 0, 18, 18, 18, 18, 18, 18, 18, 18, 18, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 0, 0, 0, 0, 0, 18, 18, 18,
+    18, 18, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 18, 18, 18, 18, 18, 18, 0, 0, 0, 3, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 3, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 0, 0, 0, 0, 18, 18, 15, 15, 18, 18, 18, 18, 18, 18, 18, 18,
+    18, 18, 18, 18, 18, 18, 18, 18, 0, 0, 18, 18, 18, 18, 18, 18, 18, 18,
+    18, 18, 18, 18, 18, 18, 15, 92, 92, 92, 0, 92, 92, 0, 0, 0, 0, 0, 92,
+    92, 92, 92, 15, 15, 15, 15, 0, 15, 15, 15, 0, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 0, 0, 0, 0, 92, 92, 92, 0, 0, 0, 0, 92, 18, 18, 18,
+    18, 18, 18, 18, 18, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3,
+    3, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 18, 18, 3, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 18,
+    18, 18, 15, 15, 15, 15, 15, 15, 15, 15, 14, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 92, 92, 0, 0, 0, 0, 18, 18, 18, 18, 18, 3, 3, 3,
+    3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0,
+    3, 3, 3, 3, 3, 3, 3, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 18, 18, 18, 18, 18, 18,
+    18, 18, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 0, 0, 0, 0, 0, 18, 18, 18, 18, 18, 18, 18, 18, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    18, 18, 18, 18, 18, 18, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 97, 97, 97, 97, 97, 97,
+    97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97,
+    97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97,
+    97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102,
+    102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102,
+    102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102,
+    102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 0, 0, 0,
+    0, 0, 0, 0, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+    18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+    18, 18, 18, 18, 18, 18, 0, 124, 92, 124, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 92, 92, 92, 92, 92,
+    92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 3, 3, 3, 3, 3, 3, 3, 0, 0,
+    0, 0, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+    18, 18, 18, 18, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 92, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 124, 124, 124, 92, 92, 92, 92, 124, 124, 92,
+    92, 3, 3, 17, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9,
+    9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 92, 92, 92, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 92, 92, 92, 92,
+    92, 124, 92, 92, 92, 92, 92, 92, 92, 92, 0, 9, 9, 9, 9, 9, 9, 9, 9,
+    9, 9, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 92, 3, 3, 15,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 124, 124, 124, 92, 92, 92, 92,
+    92, 92, 92, 92, 92, 124, 124, 15, 15, 15, 15, 3, 3, 3, 3, 3, 92, 92,
+    92, 3, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 15, 3, 15, 3, 3, 3, 0, 18,
+    18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+    18, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 124, 124, 124, 92, 92, 92, 124, 124, 92, 124, 92, 92, 3,
+    3, 3, 3, 3, 3, 92, 0, 15, 15, 15, 15, 15, 15, 15, 0, 15, 0, 15, 15,
+    15, 15, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 3, 0, 0, 0, 0, 0, 0,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 92, 124, 124, 124,
+    92, 92, 92, 92, 92, 92, 92, 92, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9,
+    9, 9, 9, 0, 0, 0, 0, 0, 0, 92, 92, 124, 124, 0, 15, 15, 15, 15, 15,
+    15, 15, 15, 0, 0, 15, 15, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 92, 124, 124, 124, 124, 0, 0, 124, 124, 0, 0, 124,
+    124, 124, 0, 0, 15, 0, 0, 0, 0, 0, 0, 124, 0, 0, 0, 0, 0, 15, 15, 15,
+    15, 15, 124, 124, 0, 0, 92, 92, 92, 92, 92, 92, 92, 0, 0, 0, 92, 92,
+    92, 92, 92, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 124, 124,
+    124, 92, 92, 92, 92, 92, 92, 92, 92, 124, 124, 92, 92, 92, 124, 92,
+    15, 15, 15, 15, 3, 3, 3, 3, 3, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 3,
+    0, 3, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 124, 124, 124, 92, 92, 92, 92, 92, 92, 124, 92, 124, 124, 124,
+    124, 92, 92, 124, 92, 92, 15, 15, 3, 15, 0, 0, 0, 0, 0, 0, 0, 0, 9,
+    9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 124, 124, 124, 92, 92, 92, 92,
+    0, 0, 124, 124, 124, 124, 92, 92, 124, 92, 92, 3, 3, 3, 3, 3, 3, 3,
+    3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 15, 15, 15, 15, 92,
+    92, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 124, 124, 124, 92, 92, 92, 92, 92, 92, 92, 92, 124, 124, 92, 124,
+    92, 92, 3, 3, 3, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9,
+    9, 9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+    3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 92, 124, 92, 124, 124, 92, 92,
+    92, 92, 92, 92, 124, 92, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9,
+    9, 9, 9, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 92, 92, 92, 124,
+    124, 92, 92, 92, 92, 124, 92, 92, 92, 92, 92, 0, 0, 0, 0, 9, 9, 9,
+    9, 9, 9, 9, 9, 9, 9, 18, 18, 3, 3, 3, 14, 10, 10, 10, 10, 10, 10, 10,
+    10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
+    10, 10, 10, 10, 10, 10, 10, 10, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+    13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
+    13, 13, 13, 13, 13, 13, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 18, 18, 18, 18,
+    18, 18, 18, 18, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 124, 92, 92, 92, 92, 92, 92, 92, 0, 124,
+    124, 124, 124, 92, 92, 124, 92, 15, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 18, 18, 18, 18, 18, 18, 18,
+    18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 0, 0, 0, 3, 3, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 92, 92, 92, 92,
+    92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+    92, 0, 124, 92, 92, 92, 92, 92, 92, 92, 124, 92, 92, 124, 92, 92, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 127, 127, 127, 127, 127, 127, 127, 127, 127,
+    127, 127, 127, 127, 127, 127, 0, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 0, 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, 9, 9, 9, 9,
+    9, 9, 9, 9, 9, 0, 0, 0, 0, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    0, 0, 92, 92, 92, 92, 92, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 92, 92, 92,
+    92, 92, 92, 92, 3, 3, 3, 3, 3, 14, 14, 14, 14, 91, 91, 91, 91, 3, 14,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 0, 18,
+    18, 18, 18, 18, 18, 18, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 124, 124, 124, 124, 124, 124,
+    124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124,
+    124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124,
+    124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 124, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 92, 92, 92, 92, 91, 91, 91,
+    91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 91, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0,
+    14, 92, 92, 3, 17, 17, 17, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 14, 14, 14, 14,
+    14, 14, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 124, 124, 92,
+    92, 92, 14, 14, 14, 124, 124, 124, 124, 124, 124, 17, 17, 17, 17, 17,
+    17, 17, 17, 92, 92, 92, 92, 92, 92, 92, 92, 14, 14, 92, 92, 92, 92,
+    92, 92, 92, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 92,
+    92, 92, 92, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 14, 92, 92,
+    92, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
+    18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 107, 107, 107, 107, 107,
+    107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107,
+    107, 107, 107, 107, 107, 107, 107, 21, 21, 21, 21, 21, 21, 21, 21,
+    21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+    21, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107,
+    107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 21,
+    21, 21, 21, 21, 21, 21, 0, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+    21, 21, 21, 21, 21, 21, 21, 21, 107, 107, 107, 107, 107, 107, 107,
+    107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107,
+    107, 107, 107, 107, 107, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+    21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 107, 0,
+    107, 107, 0, 0, 107, 0, 0, 107, 107, 0, 0, 107, 107, 107, 107, 0, 107,
+    107, 107, 107, 107, 107, 107, 107, 21, 21, 21, 21, 0, 21, 0, 21, 21,
+    21, 21, 21, 21, 21, 0, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+    107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107,
+    107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 21, 21,
+    21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+    21, 21, 21, 21, 21, 21, 21, 107, 107, 0, 107, 107, 107, 107, 0, 0,
+    107, 107, 107, 107, 107, 107, 107, 107, 0, 107, 107, 107, 107, 107,
+    107, 107, 0, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+    21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 107, 107, 0, 107, 107,
+    107, 107, 0, 107, 107, 107, 107, 107, 0, 107, 0, 0, 0, 107, 107, 107,
+    107, 107, 107, 107, 0, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+    21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 107, 107,
+    107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107,
+    107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 21, 21, 21, 21, 21,
+    21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+    21, 21, 21, 21, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107,
+    107, 107, 107, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+    21, 21, 21, 21, 21, 107, 107, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+    21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 107,
+    107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107,
+    107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 21, 21, 21,
+    21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+    21, 21, 21, 21, 21, 21, 107, 107, 107, 107, 107, 107, 107, 107, 107,
+    107, 107, 107, 107, 107, 107, 107, 21, 21, 21, 21, 21, 21, 0, 0, 107,
+    107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107,
+    107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 7, 21, 21, 21, 21,
+    21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+    21, 21, 21, 21, 7, 21, 21, 21, 21, 21, 21, 107, 107, 107, 107, 107,
+    107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107,
+    107, 107, 107, 107, 107, 107, 7, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+    21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 7,
+    21, 21, 21, 21, 21, 21, 107, 107, 107, 107, 107, 107, 107, 107, 107,
+    107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107,
+    107, 107, 7, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+    21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 7, 21, 21, 21, 21, 21,
+    21, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107,
+    107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 7, 21,
+    21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+    21, 21, 21, 21, 21, 21, 21, 7, 21, 21, 21, 21, 21, 21, 107, 107, 107,
+    107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107,
+    107, 107, 107, 107, 107, 107, 107, 107, 7, 21, 21, 21, 21, 21, 21,
+    21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+    21, 21, 7, 21, 21, 21, 21, 21, 21, 107, 21, 0, 0, 9, 9, 9, 9, 9, 9,
+    9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+    9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 92,
+    92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+    92, 92, 92, 92, 92, 14, 14, 14, 14, 92, 92, 92, 92, 92, 92, 92, 92,
+    92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 14, 14, 14, 14, 14, 14, 14,
+    14, 92, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 92,
+    14, 14, 3, 3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    92, 92, 92, 92, 92, 0, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+    92, 92, 92, 92, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 92,
+    92, 92, 92, 92, 92, 92, 0, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92,
+    92, 92, 92, 92, 92, 92, 92, 0, 0, 92, 92, 92, 92, 92, 92, 92, 0, 92,
+    92, 0, 92, 92, 92, 92, 92, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 0, 0, 18, 18, 18, 18, 18,
+    18, 18, 18, 18, 92, 92, 92, 92, 92, 92, 92, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196,
+    196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196, 196,
+    196, 196, 196, 196, 196, 196, 196, 197, 197, 197, 197, 197, 197, 197,
+    197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197,
+    197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 197, 92,
+    92, 92, 92, 92, 92, 92, 0, 0, 0, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
+    0, 0, 0, 0, 3, 3, 15, 15, 15, 15, 0, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 0, 15, 15, 0, 15, 0, 0, 15, 0, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 0, 15, 15, 15, 15, 0, 15, 0, 15, 0, 0, 0, 0, 0, 0, 15,
+    0, 0, 0, 0, 15, 0, 15, 0, 15, 0, 15, 15, 15, 0, 15, 15, 0, 15, 0, 0,
+    15, 0, 15, 0, 15, 0, 15, 0, 15, 0, 15, 15, 0, 15, 0, 0, 15, 15, 15,
+    15, 0, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, 0, 15, 15, 15,
+    15, 0, 15, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0,
+    0, 15, 15, 15, 0, 15, 15, 15, 15, 15, 0, 15, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0,
+    0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 14,
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 14, 14,
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 14, 14, 14,
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 18, 18, 18, 18, 18,
+    18, 18, 18, 18, 18, 18, 18, 18, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14,
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+    14, 14, 14, 14, 14, 14, 14, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+    14, 14, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14,
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+    14, 14, 0, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, 0,
+    0, 0, 0, 14, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 14,
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+    14, 14, 14, 14, 14, 14, 14, 14, 11, 11, 11, 11, 11, 14, 14, 14, 14,
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+    14, 14, 14, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+    14, 14, 14, 14, 14, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 14, 14,
+    14, 14, 14, 14, 14, 0, 0, 0, 0, 0, 0, 0, 0, 14, 14, 14, 14, 14, 14,
+    14, 14, 14, 14, 0, 0, 0, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 0,
+    0, 0, 0, 0, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+    14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 14, 14, 14, 14, 14, 14,
+    14, 14, 14, 14, 14, 14, 14, 14, 0, 14, 14, 14, 14, 14, 14, 14, 14,
+    0, 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+    14, 14, 14, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0, 0,
+    0, 0, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 0,
+    14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+    14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15,
+    15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0
+#endif /* TCL_UTF_MAX > 3 */
+};
+
+/*
+ * Each group represents a unique set of character attributes.  The attributes
+ * are encoded into a 32-bit value as follows:
+ *
+ * Bits 0-4	Character category: see the constants listed below.
+ *
+ * Bits 5-7	Case delta type: 000 = identity
+ *				 010 = add delta for lower
+ *				 011 = add delta for lower, add 1 for title
+ *				 100 = subtract delta for title/upper
+ *				 101 = sub delta for upper, sub 1 for title
+ *				 110 = sub delta for upper, add delta for lower
+ *
+ * Bits 8-31	Case delta: delta for case conversions.  This should be the
+ *			    highest field so we can easily sign extend.
+ */
+
+static const int groups[] = {
+    0, 15, 12, 25, 27, 21, 22, 26, 20, 9, 8257, 28, 19, 8322, 29,
+    5, 23, 16, 11, -190078, 24, 2, -30846, 321, 386, -50879, 59522,
+    -30911, 76930, -49790, 53825, 52801, 52545, 20289, 51777, 52033,
+    53057, -24702, 54081, 53569, -41598, 54593, -33150, 54849, 55873,
+    55617, 56129, -14206, 609, 451, 674, 20354, -24767, -14271, -33215,
+    2763585, -41663, 2762817, -2768510, -49855, 17729, 18241, -2760318,
+    -2759550, -2760062, 53890, 52866, 52610, 51842, 52098, -10833534,
+    -10832510, 53122, -10823550, -10830718, 53634, 54146, -2750078,
+    -10829950, -2751614, 54658, 54914, -2745982, 55938, -10824062,
+    17794, 55682, 18306, 56194, -10818686, -10817918, 4, 6, -21370,
+    29761, 9793, 9537, 16449, 16193, 9858, 9602, 8066, 16514, 16258,
+    2113, 16002, 14722, 1, 12162, 13954, 2178, 22146, 20610, -1662,
+    29826, -15295, 24706, -1727, 20545, 7, 3905, 3970, 12353, 12418,
+    8, 1859649, 9949249, 10, 1601154, 1600898, 1598594, 1598082, 1598338,
+    1596546, 1582466, -9027966, -9044862, -976254, 15234, -1949375,
+    -1918, -1983, -18814, -21886, -25470, -32638, -28542, -32126,
+    -1981, -2174, -18879, -2237, 1844610, -21951, -25535, -28607,
+    -32703, -32191, 13, 14, -1924287, -2145983, -2115007, 7233, 7298,
+    4170, 4234, 6749, 6813, -2750143, -976319, -2746047, 2763650,
+    2762882, -2759615, -2751679, -2760383, -2760127, -2768575, 1859714,
+    -9044927, -10823615, -10830783, -10833599, -10832575, -10830015,
+    -10817983, -10824127, -10818751, 237633, 237698, 9949314, 18,
+    17, 10305, 10370, 8769, 8834
+};
+
+#if TCL_UTF_MAX > 3
+#   define UNICODE_OUT_OF_RANGE(ch) (((ch) & 0x1fffff) >= 0x2fa20)
+#else
+#   define UNICODE_OUT_OF_RANGE(ch) (((ch) & 0x1f0000) != 0)
+#endif
+
+/*
+ * The following constants are used to determine the category of a
+ * Unicode character.
+ */
+
+enum {
+    UNASSIGNED,
+    UPPERCASE_LETTER,
+    LOWERCASE_LETTER,
+    TITLECASE_LETTER,
+    MODIFIER_LETTER,
+    OTHER_LETTER,
+    NON_SPACING_MARK,
+    ENCLOSING_MARK,
+    COMBINING_SPACING_MARK,
+    DECIMAL_DIGIT_NUMBER,
+    LETTER_NUMBER,
+    OTHER_NUMBER,
+    SPACE_SEPARATOR,
+    LINE_SEPARATOR,
+    PARAGRAPH_SEPARATOR,
+    CONTROL,
+    FORMAT,
+    PRIVATE_USE,
+    SURROGATE,
+    CONNECTOR_PUNCTUATION,
+    DASH_PUNCTUATION,
+    OPEN_PUNCTUATION,
+    CLOSE_PUNCTUATION,
+    INITIAL_QUOTE_PUNCTUATION,
+    FINAL_QUOTE_PUNCTUATION,
+    OTHER_PUNCTUATION,
+    MATH_SYMBOL,
+    CURRENCY_SYMBOL,
+    MODIFIER_SYMBOL,
+    OTHER_SYMBOL
+};
+
+/*
+ * The following macros extract the fields of the character info.  The
+ * GetDelta() macro is complicated because we can't rely on the C compiler
+ * to do sign extension on right shifts.
+ */
+
+#define GetCaseType(info) (((info) & 0xe0) >> 5)
+#define GetCategory(ch) (GetUniCharInfo(ch) & 0x1f)
+#define GetDelta(info) ((info) >> 8)
+
+/*
+ * This macro extracts the information about a character from the
+ * Unicode character tables.
+ */
+
+#if TCL_UTF_MAX > 3
+#   define GetUniCharInfo(ch) (groups[groupMap[pageMap[((ch) & 0x1fffff) >> OFFSET_BITS] | ((ch) & ((1 << OFFSET_BITS)-1))]])
+#else
+#   define GetUniCharInfo(ch) (groups[groupMap[pageMap[((ch) & 0xffff) >> OFFSET_BITS] | ((ch) & ((1 << OFFSET_BITS)-1))]])
+#endif
diff --git a/generic/tclUtf.c b/generic/tclUtf.c
new file mode 100644
index 0000000..b878149
--- /dev/null
+++ b/generic/tclUtf.c
@@ -0,0 +1,2062 @@
+/*
+ * tclUtf.c --
+ *
+ *	Routines for manipulating UTF-8 strings.
+ *
+ * Copyright (c) 1997-1998 Sun Microsystems, Inc.
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#include "tclInt.h"
+
+/*
+ * Include the static character classification tables and macros.
+ */
+
+#include "tclUniData.c"
+
+/*
+ * The following macros are used for fast character category tests. The x_BITS
+ * values are shifted right by the category value to determine whether the
+ * given category is included in the set.
+ */
+
+#define ALPHA_BITS ((1 << UPPERCASE_LETTER) | (1 << LOWERCASE_LETTER) \
+	| (1 << TITLECASE_LETTER) | (1 << MODIFIER_LETTER) | (1<<OTHER_LETTER))
+
+#define CONTROL_BITS ((1 << CONTROL) | (1 << FORMAT) | (1 << PRIVATE_USE))
+
+#define DIGIT_BITS (1 << DECIMAL_DIGIT_NUMBER)
+
+#define SPACE_BITS ((1 << SPACE_SEPARATOR) | (1 << LINE_SEPARATOR) \
+	| (1 << PARAGRAPH_SEPARATOR))
+
+#define WORD_BITS (ALPHA_BITS | DIGIT_BITS | (1 << CONNECTOR_PUNCTUATION))
+
+#define PUNCT_BITS ((1 << CONNECTOR_PUNCTUATION) | \
+	(1 << DASH_PUNCTUATION) | (1 << OPEN_PUNCTUATION) | \
+	(1 << CLOSE_PUNCTUATION) | (1 << INITIAL_QUOTE_PUNCTUATION) | \
+	(1 << FINAL_QUOTE_PUNCTUATION) | (1 << OTHER_PUNCTUATION))
+
+#define GRAPH_BITS (WORD_BITS | PUNCT_BITS | \
+	(1 << NON_SPACING_MARK) | (1 << ENCLOSING_MARK) | \
+	(1 << COMBINING_SPACING_MARK) | (1 << LETTER_NUMBER) | \
+	(1 << OTHER_NUMBER) | \
+	(1 << MATH_SYMBOL) | (1 << CURRENCY_SYMBOL) | \
+	(1 << MODIFIER_SYMBOL) | (1 << OTHER_SYMBOL))
+
+/*
+ * Unicode characters less than this value are represented by themselves in
+ * UTF-8 strings.
+ */
+
+#define UNICODE_SELF	0x80
+
+/*
+ * The following structures are used when mapping between Unicode (UCS-2) and
+ * UTF-8.
+ */
+
+static const unsigned char totalBytes[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,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,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,
+    3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
+#if TCL_UTF_MAX > 3
+    4,4,4,4,4,4,4,4,
+#else
+    1,1,1,1,1,1,1,1,
+#endif
+#if TCL_UTF_MAX > 4
+    5,5,5,5,
+#else
+    1,1,1,1,
+#endif
+#if TCL_UTF_MAX > 5
+    6,6,6,6
+#else
+    1,1,1,1
+#endif
+};
+
+/*
+ * Functions used only in this module.
+ */
+
+static int		UtfCount(int ch);
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * UtfCount --
+ *
+ *	Find the number of bytes in the Utf character "ch".
+ *
+ * Results:
+ *	The return values is the number of bytes in the Utf character "ch".
+ *
+ * Side effects:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+INLINE static int
+UtfCount(
+    int ch)			/* The Tcl_UniChar whose size is returned. */
+{
+    if ((ch > 0) && (ch < UNICODE_SELF)) {
+	return 1;
+    }
+    if (ch <= 0x7FF) {
+	return 2;
+    }
+#if TCL_UTF_MAX > 3
+    if ((ch > 0xFFFF) && (ch <= 0x10FFFF)) {
+	return 4;
+    }
+#endif
+    return 3;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Tcl_UniCharToUtf --
+ *
+ *	Store the given Tcl_UniChar as a sequence of UTF-8 bytes in the
+ *	provided buffer. Equivalent to Plan 9 runetochar().
+ *
+ * Results:
+ *	The return values is the number of bytes in the buffer that were
+ *	consumed.
+ *
+ * Side effects:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+INLINE int
+Tcl_UniCharToUtf(
+    int ch,			/* The Tcl_UniChar to be stored in the
+				 * buffer. */
+    char *buf)			/* Buffer in which the UTF-8 representation of
+				 * the Tcl_UniChar is stored. Buffer must be
+				 * large enough to hold the UTF-8 character
+				 * (at most TCL_UTF_MAX bytes). */
+{
+    if ((ch > 0) && (ch < UNICODE_SELF)) {
+	buf[0] = (char) ch;
+	return 1;
+    }
+    if (ch >= 0) {
+	if (ch <= 0x7FF) {
+	    buf[1] = (char) ((ch | 0x80) & 0xBF);
+	    buf[0] = (char) ((ch >> 6) | 0xC0);
+	    return 2;
+	}
+	if (ch <= 0xFFFF) {
+#if TCL_UTF_MAX == 4
+	    if ((ch & 0xF800) == 0xD800) {
+		if (ch & 0x0400) {
+		    /* Low surrogate */
+		    buf[3] = (char) ((ch | 0x80) & 0xBF);
+		    buf[2] |= (char) (((ch >> 6) | 0x80) & 0x8F);
+		    return 4;
+		} else {
+		    /* High surrogate */
+		    ch += 0x40;
+		    buf[2] = (char) (((ch << 4) | 0x80) & 0xB0);
+		    buf[1] = (char) (((ch >> 2) | 0x80) & 0xBF);
+		    buf[0] = (char) (((ch >> 8) | 0xF0) & 0xF7);
+		    return 0;
+		}
+	    }
+#endif
+	three:
+	    buf[2] = (char) ((ch | 0x80) & 0xBF);
+	    buf[1] = (char) (((ch >> 6) | 0x80) & 0xBF);
+	    buf[0] = (char) ((ch >> 12) | 0xE0);
+	    return 3;
+	}
+
+#if TCL_UTF_MAX > 3
+	if (ch <= 0x10FFFF) {
+	    buf[3] = (char) ((ch | 0x80) & 0xBF);
+	    buf[2] = (char) (((ch >> 6) | 0x80) & 0xBF);
+	    buf[1] = (char) (((ch >> 12) | 0x80) & 0xBF);
+	    buf[0] = (char) ((ch >> 18) | 0xF0);
+	    return 4;
+	}
+#endif
+    }
+
+    ch = 0xFFFD;
+    goto three;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Tcl_UniCharToUtfDString --
+ *
+ *	Convert the given Unicode string to UTF-8.
+ *
+ * Results:
+ *	The return value is a pointer to the UTF-8 representation of the
+ *	Unicode string. Storage for the return value is appended to the end of
+ *	dsPtr.
+ *
+ * Side effects:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+char *
+Tcl_UniCharToUtfDString(
+    const Tcl_UniChar *uniStr,	/* Unicode string to convert to UTF-8. */
+    int uniLength,		/* Length of Unicode string in Tcl_UniChars
+				 * (must be >= 0). */
+    Tcl_DString *dsPtr)		/* UTF-8 representation of string is appended
+				 * to this previously initialized DString. */
+{
+    const Tcl_UniChar *w, *wEnd;
+    char *p, *string;
+    int oldLength;
+
+    /*
+     * UTF-8 string length in bytes will be <= Unicode string length *
+     * TCL_UTF_MAX.
+     */
+
+    oldLength = Tcl_DStringLength(dsPtr);
+    Tcl_DStringSetLength(dsPtr, (oldLength + uniLength + 1) * TCL_UTF_MAX);
+    string = Tcl_DStringValue(dsPtr) + oldLength;
+
+    p = string;
+    wEnd = uniStr + uniLength;
+    for (w = uniStr; w < wEnd; ) {
+	p += Tcl_UniCharToUtf(*w, p);
+	w++;
+    }
+    Tcl_DStringSetLength(dsPtr, oldLength + (p - string));
+
+    return string;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Tcl_UtfToUniChar --
+ *
+ *	Extract the Tcl_UniChar represented by the UTF-8 string. Bad UTF-8
+ *	sequences are converted to valid Tcl_UniChars and processing
+ *	continues. Equivalent to Plan 9 chartorune().
+ *
+ *	The caller must ensure that the source buffer is long enough that this
+ *	routine does not run off the end and dereference non-existent memory
+ *	looking for trail bytes. If the source buffer is known to be '\0'
+ *	terminated, this cannot happen. Otherwise, the caller should call
+ *	Tcl_UtfCharComplete() before calling this routine to ensure that
+ *	enough bytes remain in the string.
+ *
+ * Results:
+ *	*chPtr is filled with the Tcl_UniChar, and the return value is the
+ *	number of bytes from the UTF-8 string that were consumed.
+ *
+ * Side effects:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+int
+Tcl_UtfToUniChar(
+    register const char *src,	/* The UTF-8 string. */
+    register Tcl_UniChar *chPtr)/* Filled with the Tcl_UniChar represented by
+				 * the UTF-8 string. */
+{
+    register int byte;
+
+    /*
+     * Unroll 1 to 3 byte UTF-8 sequences, use loop to handle longer ones.
+     */
+
+    byte = *((unsigned char *) src);
+    if (byte < 0xC0) {
+	/*
+	 * Handles properly formed UTF-8 characters between 0x01 and 0x7F.
+	 * Also treats \0 and naked trail bytes 0x80 to 0xBF as valid
+	 * characters representing themselves.
+	 */
+
+	*chPtr = (Tcl_UniChar) byte;
+	return 1;
+    } else if (byte < 0xE0) {
+	if ((src[1] & 0xC0) == 0x80) {
+	    /*
+	     * Two-byte-character lead-byte followed by a trail-byte.
+	     */
+
+	    *chPtr = (Tcl_UniChar) (((byte & 0x1F) << 6) | (src[1] & 0x3F));
+	    return 2;
+	}
+
+	/*
+	 * A two-byte-character lead-byte not followed by trail-byte
+	 * represents itself.
+	 */
+
+	*chPtr = (Tcl_UniChar) byte;
+	return 1;
+    } else if (byte < 0xF0) {
+	if (((src[1] & 0xC0) == 0x80) && ((src[2] & 0xC0) == 0x80)) {
+	    /*
+	     * Three-byte-character lead byte followed by two trail bytes.
+	     */
+
+	    *chPtr = (Tcl_UniChar) (((byte & 0x0F) << 12)
+		    | ((src[1] & 0x3F) << 6) | (src[2] & 0x3F));
+	    return 3;
+	}
+
+	/*
+	 * A three-byte-character lead-byte not followed by two trail-bytes
+	 * represents itself.
+	 */
+
+	*chPtr = (Tcl_UniChar) byte;
+	return 1;
+    }
+#if TCL_UTF_MAX > 3
+    {
+	int ch, total, trail;
+
+	total = totalBytes[byte];
+	trail = total - 1;
+	if (trail > 0) {
+	    ch = byte & (0x3F >> trail);
+	    do {
+		src++;
+		if ((*src & 0xC0) != 0x80) {
+		    *chPtr = byte;
+		    return 1;
+		}
+		ch <<= 6;
+		ch |= (*src & 0x3F);
+		trail--;
+	    } while (trail > 0);
+	    *chPtr = ch;
+	    return total;
+	}
+    }
+#endif
+
+    *chPtr = (Tcl_UniChar) byte;
+    return 1;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Tcl_UtfToUniCharDString --
+ *
+ *	Convert the UTF-8 string to Unicode.
+ *
+ * Results:
+ *	The return value is a pointer to the Unicode representation of the
+ *	UTF-8 string. Storage for the return value is appended to the end of
+ *	dsPtr. The Unicode string is terminated with a Unicode NULL character.
+ *
+ * Side effects:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+Tcl_UniChar *
+Tcl_UtfToUniCharDString(
+    const char *src,		/* UTF-8 string to convert to Unicode. */
+    int length,			/* Length of UTF-8 string in bytes, or -1 for
+				 * strlen(). */
+    Tcl_DString *dsPtr)		/* Unicode representation of string is
+				 * appended to this previously initialized
+				 * DString. */
+{
+    Tcl_UniChar *w, *wString;
+    const char *p, *end;
+    int oldLength;
+
+    if (length < 0) {
+	length = strlen(src);
+    }
+
+    /*
+     * Unicode string length in Tcl_UniChars will be <= UTF-8 string length in
+     * bytes.
+     */
+
+    oldLength = Tcl_DStringLength(dsPtr);
+/* TODO: fix overreach! */
+    Tcl_DStringSetLength(dsPtr,
+	    (int) ((oldLength + length + 1) * sizeof(Tcl_UniChar)));
+    wString = (Tcl_UniChar *) (Tcl_DStringValue(dsPtr) + oldLength);
+
+    w = wString;
+    end = src + length;
+    for (p = src; p < end; ) {
+	p += TclUtfToUniChar(p, w);
+	w++;
+    }
+    *w = '\0';
+    Tcl_DStringSetLength(dsPtr,
+	    (oldLength + ((char *) w - (char *) wString)));
+
+    return wString;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Tcl_UtfCharComplete --
+ *
+ *	Determine if the UTF-8 string of the given length is long enough to be
+ *	decoded by Tcl_UtfToUniChar(). This does not ensure that the UTF-8
+ *	string is properly formed. Equivalent to Plan 9 fullrune().
+ *
+ * Results:
+ *	The return value is 0 if the string is not long enough, non-zero
+ *	otherwise.
+ *
+ * Side effects:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+int
+Tcl_UtfCharComplete(
+    const char *src,		/* String to check if first few bytes contain
+				 * a complete UTF-8 character. */
+    int length)			/* Length of above string in bytes. */
+{
+    int ch;
+
+    ch = *((unsigned char *) src);
+    return length >= totalBytes[ch];
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Tcl_NumUtfChars --
+ *
+ *	Returns the number of characters (not bytes) in the UTF-8 string, not
+ *	including the terminating NULL byte. This is equivalent to Plan 9
+ *	utflen() and utfnlen().
+ *
+ * Results:
+ *	As above.
+ *
+ * Side effects:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+int
+Tcl_NumUtfChars(
+    register const char *src,	/* The UTF-8 string to measure. */
+    int length)			/* The length of the string in bytes, or -1
+				 * for strlen(string). */
+{
+    Tcl_UniChar ch;
+    register Tcl_UniChar *chPtr = &ch;
+    register int i;
+
+    /*
+     * The separate implementations are faster.
+     *
+     * Since this is a time-sensitive function, we also do the check for the
+     * single-byte char case specially.
+     */
+
+    i = 0;
+    if (length < 0) {
+	while (*src != '\0') {
+	    src += TclUtfToUniChar(src, chPtr);
+	    i++;
+	}
+    } else {
+	register int n;
+
+	while (length > 0) {
+	    if (UCHAR(*src) < 0xC0) {
+		length--;
+		src++;
+	    } else {
+		n = Tcl_UtfToUniChar(src, chPtr);
+		length -= n;
+		src += n;
+	    }
+	    i++;
+	}
+    }
+    return i;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Tcl_UtfFindFirst --
+ *
+ *	Returns a pointer to the first occurance of the given Tcl_UniChar in
+ *	the NULL-terminated UTF-8 string. The NULL terminator is considered
+ *	part of the UTF-8 string. Equivalent to Plan 9 utfrune().
+ *
+ * Results:
+ *	As above. If the Tcl_UniChar does not exist in the given string, the
+ *	return value is NULL.
+ *
+ * Side effects:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+const char *
+Tcl_UtfFindFirst(
+    const char *src,		/* The UTF-8 string to be searched. */
+    int ch)			/* The Tcl_UniChar to search for. */
+{
+    int len;
+    Tcl_UniChar find;
+
+    while (1) {
+	len = TclUtfToUniChar(src, &find);
+	if (find == ch) {
+	    return src;
+	}
+	if (*src == '\0') {
+	    return NULL;
+	}
+	src += len;
+    }
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Tcl_UtfFindLast --
+ *
+ *	Returns a pointer to the last occurance of the given Tcl_UniChar in
+ *	the NULL-terminated UTF-8 string. The NULL terminator is considered
+ *	part of the UTF-8 string. Equivalent to Plan 9 utfrrune().
+ *
+ * Results:
+ *	As above. If the Tcl_UniChar does not exist in the given string, the
+ *	return value is NULL.
+ *
+ * Side effects:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+const char *
+Tcl_UtfFindLast(
+    const char *src,		/* The UTF-8 string to be searched. */
+    int ch)			/* The Tcl_UniChar to search for. */
+{
+    int len;
+    Tcl_UniChar find;
+    const char *last;
+
+    last = NULL;
+    while (1) {
+	len = TclUtfToUniChar(src, &find);
+	if (find == ch) {
+	    last = src;
+	}
+	if (*src == '\0') {
+	    break;
+	}
+	src += len;
+    }
+    return last;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Tcl_UtfNext --
+ *
+ *	Given a pointer to some current location in a UTF-8 string, move
+ *	forward one character. The caller must ensure that they are not asking
+ *	for the next character after the last character in the string.
+ *
+ * Results:
+ *	The return value is the pointer to the next character in the UTF-8
+ *	string.
+ *
+ * Side effects:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+const char *
+Tcl_UtfNext(
+    const char *src)		/* The current location in the string. */
+{
+    Tcl_UniChar ch;
+
+    return src + TclUtfToUniChar(src, &ch);
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Tcl_UtfPrev --
+ *
+ *	Given a pointer to some current location in a UTF-8 string, move
+ *	backwards one character. This works correctly when the pointer is in
+ *	the middle of a UTF-8 character.
+ *
+ * Results:
+ *	The return value is a pointer to the previous character in the UTF-8
+ *	string. If the current location was already at the beginning of the
+ *	string, the return value will also be a pointer to the beginning of
+ *	the string.
+ *
+ * Side effects:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+const char *
+Tcl_UtfPrev(
+    const char *src,		/* The current location in the string. */
+    const char *start)		/* Pointer to the beginning of the string, to
+				 * avoid going backwards too far. */
+{
+    const char *look;
+    int i, byte;
+
+    src--;
+    look = src;
+    for (i = 0; i < TCL_UTF_MAX; i++) {
+	if (look < start) {
+	    if (src < start) {
+		src = start;
+	    }
+	    break;
+	}
+	byte = *((unsigned char *) look);
+	if (byte < 0x80) {
+	    break;
+	}
+	if (byte >= 0xC0) {
+	    return look;
+	}
+	look--;
+    }
+    return src;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Tcl_UniCharAtIndex --
+ *
+ *	Returns the Unicode character represented at the specified character
+ *	(not byte) position in the UTF-8 string.
+ *
+ * Results:
+ *	As above.
+ *
+ * Side effects:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+Tcl_UniChar
+Tcl_UniCharAtIndex(
+    register const char *src,	/* The UTF-8 string to dereference. */
+    register int index)		/* The position of the desired character. */
+{
+    Tcl_UniChar ch = 0;
+
+    while (index >= 0) {
+	index--;
+	src += TclUtfToUniChar(src, &ch);
+    }
+    return ch;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Tcl_UtfAtIndex --
+ *
+ *	Returns a pointer to the specified character (not byte) position in
+ *	the UTF-8 string.
+ *
+ * Results:
+ *	As above.
+ *
+ * Side effects:
+ *	None.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+const char *
+Tcl_UtfAtIndex(
+    register const char *src,	/* The UTF-8 string. */
+    register int index)		/* The position of the desired character. */
+{
+    Tcl_UniChar ch;
+
+    while (index > 0) {
+	index--;
+	src += TclUtfToUniChar(src, &ch);
+    }
+    return src;
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * Tcl_UtfBackslash --
+ *
+ *	Figure out how to handle a backslash sequence.
+ *
+ * Results:
+ *	Stores the bytes represented by the backslash sequence in dst and
+ *	returns the number of bytes written to dst. At most TCL_UTF_MAX bytes
+ *	are written to dst; dst must have been large enough to accept those
+ *	bytes. If readPtr isn't NULL then it is filled in with a count of the
+ *	number of bytes in the backslash sequence.
+ *
+ * Side effects:
+ *	The maximum number of bytes it takes to represent a Unicode character
+ *	in UTF-8 is guaranteed to be less than the number of bytes used to
+ *	express the backslash sequence that represents that Unicode character.
+ *	If the target buffer into which the caller is going to store the bytes
+ *	that represent the Unicode character is at least as large as the
+ *	source buffer from which the backslashed sequence was extracted, no
+ *	buffer overruns should occur.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+int
+Tcl_UtfBackslash(
+    const char *src,		/* Points to the backslash character of a
+				 * backslash sequence. */
+    int *readPtr,		/* Fill in with number of characters read from
+				 * src, unless NULL. */
+    char *dst)			/* Filled with the bytes represented by the
+				 * backslash sequence. */
+{
+#define LINE_LENGTH 128
+    int numRead;
+    int result;
+
+    result = TclParseBackslash(src, LINE_LENGTH, &numRead, dst);
+    if (numRead == LINE_LENGTH) {
+	/*
+	 * We ate a whole line. Pay the price of a strlen()
+	 */
+
+	result = TclParseBackslash(src, (int)strlen(src), &numRead, dst);
+    }
+    if (readPtr != NULL) {
+	*readPtr = numRead;
+    }
+    return result;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_UtfToUpper --
+ *
+ *	Convert lowercase characters to uppercase characters in a UTF string
+ *	in place. The conversion may shrink the UTF string.
+ *
+ * Results:
+ *	Returns the number of bytes in the resulting string excluding the
+ *	trailing null.
+ *
+ * Side effects:
+ *	Writes a terminating null after the last converted character.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_UtfToUpper(
+    char *str)			/* String to convert in place. */
+{
+    Tcl_UniChar ch, upChar;
+    char *src, *dst;
+    int bytes;
+
+    /*
+     * Iterate over the string until we hit the terminating null.
+     */
+
+    src = dst = str;
+    while (*src) {
+	bytes = TclUtfToUniChar(src, &ch);
+	upChar = Tcl_UniCharToUpper(ch);
+
+	/*
+	 * To keep badly formed Utf strings from getting inflated by the
+	 * conversion (thereby causing a segfault), only copy the upper case
+	 * char to dst if its size is <= the original char.
+	 */
+
+	if (bytes < UtfCount(upChar)) {
+	    memcpy(dst, src, (size_t) bytes);
+	    dst += bytes;
+	} else {
+	    dst += Tcl_UniCharToUtf(upChar, dst);
+	}
+	src += bytes;
+    }
+    *dst = '\0';
+    return (dst - str);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_UtfToLower --
+ *
+ *	Convert uppercase characters to lowercase characters in a UTF string
+ *	in place. The conversion may shrink the UTF string.
+ *
+ * Results:
+ *	Returns the number of bytes in the resulting string excluding the
+ *	trailing null.
+ *
+ * Side effects:
+ *	Writes a terminating null after the last converted character.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_UtfToLower(
+    char *str)			/* String to convert in place. */
+{
+    Tcl_UniChar ch, lowChar;
+    char *src, *dst;
+    int bytes;
+
+    /*
+     * Iterate over the string until we hit the terminating null.
+     */
+
+    src = dst = str;
+    while (*src) {
+	bytes = TclUtfToUniChar(src, &ch);
+	lowChar = Tcl_UniCharToLower(ch);
+
+	/*
+	 * To keep badly formed Utf strings from getting inflated by the
+	 * conversion (thereby causing a segfault), only copy the lower case
+	 * char to dst if its size is <= the original char.
+	 */
+
+	if (bytes < UtfCount(lowChar)) {
+	    memcpy(dst, src, (size_t) bytes);
+	    dst += bytes;
+	} else {
+	    dst += Tcl_UniCharToUtf(lowChar, dst);
+	}
+	src += bytes;
+    }
+    *dst = '\0';
+    return (dst - str);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_UtfToTitle --
+ *
+ *	Changes the first character of a UTF string to title case or uppercase
+ *	and the rest of the string to lowercase. The conversion happens in
+ *	place and may shrink the UTF string.
+ *
+ * Results:
+ *	Returns the number of bytes in the resulting string excluding the
+ *	trailing null.
+ *
+ * Side effects:
+ *	Writes a terminating null after the last converted character.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_UtfToTitle(
+    char *str)			/* String to convert in place. */
+{
+    Tcl_UniChar ch, titleChar, lowChar;
+    char *src, *dst;
+    int bytes;
+
+    /*
+     * Capitalize the first character and then lowercase the rest of the
+     * characters until we get to a null.
+     */
+
+    src = dst = str;
+
+    if (*src) {
+	bytes = TclUtfToUniChar(src, &ch);
+	titleChar = Tcl_UniCharToTitle(ch);
+
+	if (bytes < UtfCount(titleChar)) {
+	    memcpy(dst, src, (size_t) bytes);
+	    dst += bytes;
+	} else {
+	    dst += Tcl_UniCharToUtf(titleChar, dst);
+	}
+	src += bytes;
+    }
+    while (*src) {
+	bytes = TclUtfToUniChar(src, &ch);
+	lowChar = Tcl_UniCharToLower(ch);
+
+	if (bytes < UtfCount(lowChar)) {
+	    memcpy(dst, src, (size_t) bytes);
+	    dst += bytes;
+	} else {
+	    dst += Tcl_UniCharToUtf(lowChar, dst);
+	}
+	src += bytes;
+    }
+    *dst = '\0';
+    return (dst - str);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclpUtfNcmp2 --
+ *
+ *	Compare at most numBytes bytes of utf-8 strings cs and ct. Both cs and
+ *	ct are assumed to be at least numBytes bytes long.
+ *
+ * Results:
+ *	Return <0 if cs < ct, 0 if cs == ct, or >0 if cs > ct.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclpUtfNcmp2(
+    const char *cs,		/* UTF string to compare to ct. */
+    const char *ct,		/* UTF string cs is compared to. */
+    unsigned long numBytes)	/* Number of *bytes* to compare. */
+{
+    /*
+     * We can't simply call 'memcmp(cs, ct, numBytes);' because we need to
+     * check for Tcl's \xC0\x80 non-utf-8 null encoding. Otherwise utf-8 lexes
+     * fine in the strcmp manner.
+     */
+
+    register int result = 0;
+
+    for ( ; numBytes != 0; numBytes--, cs++, ct++) {
+	if (*cs != *ct) {
+	    result = UCHAR(*cs) - UCHAR(*ct);
+	    break;
+	}
+    }
+    if (numBytes && ((UCHAR(*cs) == 0xC0) || (UCHAR(*ct) == 0xC0))) {
+	unsigned char c1, c2;
+
+	c1 = ((UCHAR(*cs) == 0xC0) && (UCHAR(cs[1]) == 0x80)) ? 0 : UCHAR(*cs);
+	c2 = ((UCHAR(*ct) == 0xC0) && (UCHAR(ct[1]) == 0x80)) ? 0 : UCHAR(*ct);
+	result = (c1 - c2);
+    }
+    return result;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_UtfNcmp --
+ *
+ *	Compare at most numChars UTF chars of string cs to string ct. Both cs
+ *	and ct are assumed to be at least numChars UTF chars long.
+ *
+ * Results:
+ *	Return <0 if cs < ct, 0 if cs == ct, or >0 if cs > ct.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_UtfNcmp(
+    const char *cs,		/* UTF string to compare to ct. */
+    const char *ct,		/* UTF string cs is compared to. */
+    unsigned long numChars)	/* Number of UTF chars to compare. */
+{
+    Tcl_UniChar ch1, ch2;
+
+    /*
+     * Cannot use 'memcmp(cs, ct, n);' as byte representation of \u0000 (the
+     * pair of bytes 0xc0,0x80) is larger than byte representation of \u0001
+     * (the byte 0x01.)
+     */
+
+    while (numChars-- > 0) {
+	/*
+	 * n must be interpreted as chars, not bytes. This should be called
+	 * only when both strings are of at least n chars long (no need for \0
+	 * check)
+	 */
+
+	cs += TclUtfToUniChar(cs, &ch1);
+	ct += TclUtfToUniChar(ct, &ch2);
+	if (ch1 != ch2) {
+	    return (ch1 - ch2);
+	}
+    }
+    return 0;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_UtfNcasecmp --
+ *
+ *	Compare at most numChars UTF chars of string cs to string ct case
+ *	insensitive. Both cs and ct are assumed to be at least numChars UTF
+ *	chars long.
+ *
+ * Results:
+ *	Return <0 if cs < ct, 0 if cs == ct, or >0 if cs > ct.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_UtfNcasecmp(
+    const char *cs,		/* UTF string to compare to ct. */
+    const char *ct,		/* UTF string cs is compared to. */
+    unsigned long numChars)	/* Number of UTF chars to compare. */
+{
+    Tcl_UniChar ch1, ch2;
+    while (numChars-- > 0) {
+	/*
+	 * n must be interpreted as chars, not bytes.
+	 * This should be called only when both strings are of
+	 * at least n chars long (no need for \0 check)
+	 */
+	cs += TclUtfToUniChar(cs, &ch1);
+	ct += TclUtfToUniChar(ct, &ch2);
+	if (ch1 != ch2) {
+	    ch1 = Tcl_UniCharToLower(ch1);
+	    ch2 = Tcl_UniCharToLower(ch2);
+	    if (ch1 != ch2) {
+		return (ch1 - ch2);
+	    }
+	}
+    }
+    return 0;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_UtfNcasecmp --
+ *
+ *	Compare UTF chars of string cs to string ct case insensitively.
+ *	Replacement for strcasecmp in Tcl core, in places where UTF-8 should
+ *	be handled.
+ *
+ * Results:
+ *	Return <0 if cs < ct, 0 if cs == ct, or >0 if cs > ct.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclUtfCasecmp(
+    const char *cs,		/* UTF string to compare to ct. */
+    const char *ct)		/* UTF string cs is compared to. */
+{
+    while (*cs && *ct) {
+	Tcl_UniChar ch1, ch2;
+
+	cs += TclUtfToUniChar(cs, &ch1);
+	ct += TclUtfToUniChar(ct, &ch2);
+	if (ch1 != ch2) {
+	    ch1 = Tcl_UniCharToLower(ch1);
+	    ch2 = Tcl_UniCharToLower(ch2);
+	    if (ch1 != ch2) {
+		return ch1 - ch2;
+	    }
+	}
+    }
+    return UCHAR(*cs) - UCHAR(*ct);
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_UniCharToUpper --
+ *
+ *	Compute the uppercase equivalent of the given Unicode character.
+ *
+ * Results:
+ *	Returns the uppercase Unicode character.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_UniChar
+Tcl_UniCharToUpper(
+    int ch)			/* Unicode character to convert. */
+{
+    int info = GetUniCharInfo(ch);
+
+    if (GetCaseType(info) & 0x04) {
+	ch -= GetDelta(info);
+    }
+    return (Tcl_UniChar) ch;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_UniCharToLower --
+ *
+ *	Compute the lowercase equivalent of the given Unicode character.
+ *
+ * Results:
+ *	Returns the lowercase Unicode character.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_UniChar
+Tcl_UniCharToLower(
+    int ch)			/* Unicode character to convert. */
+{
+    int info = GetUniCharInfo(ch);
+
+    if (GetCaseType(info) & 0x02) {
+	ch += GetDelta(info);
+    }
+    return (Tcl_UniChar) ch;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_UniCharToTitle --
+ *
+ *	Compute the titlecase equivalent of the given Unicode character.
+ *
+ * Results:
+ *	Returns the titlecase Unicode character.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_UniChar
+Tcl_UniCharToTitle(
+    int ch)			/* Unicode character to convert. */
+{
+    int info = GetUniCharInfo(ch);
+    int mode = GetCaseType(info);
+
+    if (mode & 0x1) {
+	/*
+	 * Subtract or add one depending on the original case.
+	 */
+
+	ch += ((mode & 0x4) ? -1 : 1);
+    } else if (mode == 0x4) {
+	ch -= GetDelta(info);
+    }
+    return (Tcl_UniChar) ch;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_UniCharLen --
+ *
+ *	Find the length of a UniChar string. The str input must be null
+ *	terminated.
+ *
+ * Results:
+ *	Returns the length of str in UniChars (not bytes).
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_UniCharLen(
+    const Tcl_UniChar *uniStr)	/* Unicode string to find length of. */
+{
+    int len = 0;
+
+    while (*uniStr != '\0') {
+	len++;
+	uniStr++;
+    }
+    return len;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_UniCharNcmp --
+ *
+ *	Compare at most numChars unichars of string ucs to string uct.
+ *	Both ucs and uct are assumed to be at least numChars unichars long.
+ *
+ * Results:
+ *	Return <0 if ucs < uct, 0 if ucs == uct, or >0 if ucs > uct.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_UniCharNcmp(
+    const Tcl_UniChar *ucs,	/* Unicode string to compare to uct. */
+    const Tcl_UniChar *uct,	/* Unicode string ucs is compared to. */
+    unsigned long numChars)	/* Number of unichars to compare. */
+{
+#ifdef WORDS_BIGENDIAN
+    /*
+     * We are definitely on a big-endian machine; memcmp() is safe
+     */
+
+    return memcmp(ucs, uct, numChars*sizeof(Tcl_UniChar));
+
+#else /* !WORDS_BIGENDIAN */
+    /*
+     * We can't simply call memcmp() because that is not lexically correct.
+     */
+
+    for ( ; numChars != 0; ucs++, uct++, numChars--) {
+	if (*ucs != *uct) {
+	    return (*ucs - *uct);
+	}
+    }
+    return 0;
+#endif /* WORDS_BIGENDIAN */
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_UniCharNcasecmp --
+ *
+ *	Compare at most numChars unichars of string ucs to string uct case
+ *	insensitive. Both ucs and uct are assumed to be at least numChars
+ *	unichars long.
+ *
+ * Results:
+ *	Return <0 if ucs < uct, 0 if ucs == uct, or >0 if ucs > uct.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_UniCharNcasecmp(
+    const Tcl_UniChar *ucs,	/* Unicode string to compare to uct. */
+    const Tcl_UniChar *uct,	/* Unicode string ucs is compared to. */
+    unsigned long numChars)	/* Number of unichars to compare. */
+{
+    for ( ; numChars != 0; numChars--, ucs++, uct++) {
+	if (*ucs != *uct) {
+	    Tcl_UniChar lcs = Tcl_UniCharToLower(*ucs);
+	    Tcl_UniChar lct = Tcl_UniCharToLower(*uct);
+
+	    if (lcs != lct) {
+		return (lcs - lct);
+	    }
+	}
+    }
+    return 0;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_UniCharIsAlnum --
+ *
+ *	Test if a character is an alphanumeric Unicode character.
+ *
+ * Results:
+ *	Returns 1 if character is alphanumeric.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_UniCharIsAlnum(
+    int ch)			/* Unicode character to test. */
+{
+#if TCL_UTF_MAX > 3
+    if (UNICODE_OUT_OF_RANGE(ch)) {
+	return 0;
+    }
+#endif
+    return (((ALPHA_BITS | DIGIT_BITS) >> GetCategory(ch)) & 1);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_UniCharIsAlpha --
+ *
+ *	Test if a character is an alphabetic Unicode character.
+ *
+ * Results:
+ *	Returns 1 if character is alphabetic.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_UniCharIsAlpha(
+    int ch)			/* Unicode character to test. */
+{
+#if TCL_UTF_MAX > 3
+    if (UNICODE_OUT_OF_RANGE(ch)) {
+	return 0;
+    }
+#endif
+    return ((ALPHA_BITS >> GetCategory(ch)) & 1);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_UniCharIsControl --
+ *
+ *	Test if a character is a Unicode control character.
+ *
+ * Results:
+ *	Returns non-zero if character is a control.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_UniCharIsControl(
+    int ch)			/* Unicode character to test. */
+{
+#if TCL_UTF_MAX > 3
+    if (UNICODE_OUT_OF_RANGE(ch)) {
+	ch &= 0x1fffff;
+	if ((ch == 0xe0001) || ((ch >= 0xe0020) && (ch <= 0xe007f))) {
+	    return 1;
+	}
+	if ((ch >= 0xf0000) && ((ch & 0xffff) <= 0xfffd)) {
+	    return 1;
+	}
+	return 0;
+    }
+#endif
+    return ((CONTROL_BITS >> GetCategory(ch)) & 1);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_UniCharIsDigit --
+ *
+ *	Test if a character is a numeric Unicode character.
+ *
+ * Results:
+ *	Returns non-zero if character is a digit.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_UniCharIsDigit(
+    int ch)			/* Unicode character to test. */
+{
+#if TCL_UTF_MAX > 3
+    if (UNICODE_OUT_OF_RANGE(ch)) {
+	return 0;
+    }
+#endif
+    return (GetCategory(ch) == DECIMAL_DIGIT_NUMBER);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_UniCharIsGraph --
+ *
+ *	Test if a character is any Unicode print character except space.
+ *
+ * Results:
+ *	Returns non-zero if character is printable, but not space.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_UniCharIsGraph(
+    int ch)			/* Unicode character to test. */
+{
+#if TCL_UTF_MAX > 3
+    if (UNICODE_OUT_OF_RANGE(ch)) {
+	ch &= 0x1fffff;
+	return (ch >= 0xe0100) && (ch <= 0xe01ef);
+    }
+#endif
+    return ((GRAPH_BITS >> GetCategory(ch)) & 1);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_UniCharIsLower --
+ *
+ *	Test if a character is a lowercase Unicode character.
+ *
+ * Results:
+ *	Returns non-zero if character is lowercase.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_UniCharIsLower(
+    int ch)			/* Unicode character to test. */
+{
+#if TCL_UTF_MAX > 3
+    if (UNICODE_OUT_OF_RANGE(ch)) {
+	return 0;
+    }
+#endif
+    return (GetCategory(ch) == LOWERCASE_LETTER);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_UniCharIsPrint --
+ *
+ *	Test if a character is a Unicode print character.
+ *
+ * Results:
+ *	Returns non-zero if character is printable.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_UniCharIsPrint(
+    int ch)			/* Unicode character to test. */
+{
+#if TCL_UTF_MAX > 3
+    if (UNICODE_OUT_OF_RANGE(ch)) {
+	ch &= 0x1fffff;
+	return (ch >= 0xe0100) && (ch <= 0xe01ef);
+    }
+#endif
+    return (((GRAPH_BITS|SPACE_BITS) >> GetCategory(ch)) & 1);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_UniCharIsPunct --
+ *
+ *	Test if a character is a Unicode punctuation character.
+ *
+ * Results:
+ *	Returns non-zero if character is punct.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_UniCharIsPunct(
+    int ch)			/* Unicode character to test. */
+{
+#if TCL_UTF_MAX > 3
+    if (UNICODE_OUT_OF_RANGE(ch)) {
+	return 0;
+    }
+#endif
+    return ((PUNCT_BITS >> GetCategory(ch)) & 1);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_UniCharIsSpace --
+ *
+ *	Test if a character is a whitespace Unicode character.
+ *
+ * Results:
+ *	Returns non-zero if character is a space.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_UniCharIsSpace(
+    int ch)			/* Unicode character to test. */
+{
+#if TCL_UTF_MAX > 3
+    /* Ignore upper 11 bits. */
+    ch &= 0x1fffff;
+#else
+    /* Ignore upper 16 bits. */
+    ch &= 0xffff;
+#endif
+
+    /*
+     * If the character is within the first 127 characters, just use the
+     * standard C function, otherwise consult the Unicode table.
+     */
+
+    if (ch < 0x80) {
+	return TclIsSpaceProc((char) ch);
+#if TCL_UTF_MAX > 3
+    } else if (UNICODE_OUT_OF_RANGE(ch)) {
+	return 0;
+#endif
+    } else if (ch == 0x0085 || ch == 0x180e || ch == 0x200b
+	    || ch == 0x202f || ch == 0x2060 || ch == 0xfeff) {
+	return 1;
+    } else {
+	return ((SPACE_BITS >> GetCategory(ch)) & 1);
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_UniCharIsUpper --
+ *
+ *	Test if a character is a uppercase Unicode character.
+ *
+ * Results:
+ *	Returns non-zero if character is uppercase.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_UniCharIsUpper(
+    int ch)			/* Unicode character to test. */
+{
+#if TCL_UTF_MAX > 3
+    if (UNICODE_OUT_OF_RANGE(ch)) {
+	return 0;
+    }
+#endif
+    return (GetCategory(ch) == UPPERCASE_LETTER);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_UniCharIsWordChar --
+ *
+ *	Test if a character is alphanumeric or a connector punctuation mark.
+ *
+ * Results:
+ *	Returns 1 if character is a word character.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_UniCharIsWordChar(
+    int ch)			/* Unicode character to test. */
+{
+#if TCL_UTF_MAX > 3
+    if (UNICODE_OUT_OF_RANGE(ch)) {
+	return 0;
+    }
+#endif
+    return ((WORD_BITS >> GetCategory(ch)) & 1);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_UniCharCaseMatch --
+ *
+ *	See if a particular Unicode string matches a particular pattern.
+ *	Allows case insensitivity. This is the Unicode equivalent of the char*
+ *	Tcl_StringCaseMatch. The UniChar strings must be NULL-terminated.
+ *	This has no provision for counted UniChar strings, thus should not be
+ *	used where NULLs are expected in the UniChar string. Use
+ *	TclUniCharMatch where possible.
+ *
+ * Results:
+ *	The return value is 1 if string matches pattern, and 0 otherwise. The
+ *	matching operation permits the following special characters in the
+ *	pattern: *?\[] (see the manual entry for details on what these mean).
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_UniCharCaseMatch(
+    const Tcl_UniChar *uniStr,	/* Unicode String. */
+    const Tcl_UniChar *uniPattern,
+				/* Pattern, which may contain special
+				 * characters. */
+    int nocase)			/* 0 for case sensitive, 1 for insensitive */
+{
+    Tcl_UniChar ch1, p;
+
+    while (1) {
+	p = *uniPattern;
+
+	/*
+	 * See if we're at the end of both the pattern and the string. If so,
+	 * we succeeded. If we're at the end of the pattern but not at the end
+	 * of the string, we failed.
+	 */
+
+	if (p == 0) {
+	    return (*uniStr == 0);
+	}
+	if ((*uniStr == 0) && (p != '*')) {
+	    return 0;
+	}
+
+	/*
+	 * Check for a "*" as the next pattern character. It matches any
+	 * substring. We handle this by skipping all the characters up to the
+	 * next matching one in the pattern, and then calling ourselves
+	 * recursively for each postfix of string, until either we match or we
+	 * reach the end of the string.
+	 */
+
+	if (p == '*') {
+	    /*
+	     * Skip all successive *'s in the pattern
+	     */
+
+	    while (*(++uniPattern) == '*') {
+		/* empty body */
+	    }
+	    p = *uniPattern;
+	    if (p == 0) {
+		return 1;
+	    }
+	    if (nocase) {
+		p = Tcl_UniCharToLower(p);
+	    }
+	    while (1) {
+		/*
+		 * Optimization for matching - cruise through the string
+		 * quickly if the next char in the pattern isn't a special
+		 * character
+		 */
+
+		if ((p != '[') && (p != '?') && (p != '\\')) {
+		    if (nocase) {
+			while (*uniStr && (p != *uniStr)
+				&& (p != Tcl_UniCharToLower(*uniStr))) {
+			    uniStr++;
+			}
+		    } else {
+			while (*uniStr && (p != *uniStr)) {
+			    uniStr++;
+			}
+		    }
+		}
+		if (Tcl_UniCharCaseMatch(uniStr, uniPattern, nocase)) {
+		    return 1;
+		}
+		if (*uniStr == 0) {
+		    return 0;
+		}
+		uniStr++;
+	    }
+	}
+
+	/*
+	 * Check for a "?" as the next pattern character. It matches any
+	 * single character.
+	 */
+
+	if (p == '?') {
+	    uniPattern++;
+	    uniStr++;
+	    continue;
+	}
+
+	/*
+	 * Check for a "[" as the next pattern character. It is followed by a
+	 * list of characters that are acceptable, or by a range (two
+	 * characters separated by "-").
+	 */
+
+	if (p == '[') {
+	    Tcl_UniChar startChar, endChar;
+
+	    uniPattern++;
+	    ch1 = (nocase ? Tcl_UniCharToLower(*uniStr) : *uniStr);
+	    uniStr++;
+	    while (1) {
+		if ((*uniPattern == ']') || (*uniPattern == 0)) {
+		    return 0;
+		}
+		startChar = (nocase ? Tcl_UniCharToLower(*uniPattern)
+			: *uniPattern);
+		uniPattern++;
+		if (*uniPattern == '-') {
+		    uniPattern++;
+		    if (*uniPattern == 0) {
+			return 0;
+		    }
+		    endChar = (nocase ? Tcl_UniCharToLower(*uniPattern)
+			    : *uniPattern);
+		    uniPattern++;
+		    if (((startChar <= ch1) && (ch1 <= endChar))
+			    || ((endChar <= ch1) && (ch1 <= startChar))) {
+			/*
+			 * Matches ranges of form [a-z] or [z-a].
+			 */
+			break;
+		    }
+		} else if (startChar == ch1) {
+		    break;
+		}
+	    }
+	    while (*uniPattern != ']') {
+		if (*uniPattern == 0) {
+		    uniPattern--;
+		    break;
+		}
+		uniPattern++;
+	    }
+	    uniPattern++;
+	    continue;
+	}
+
+	/*
+	 * If the next pattern character is '\', just strip off the '\' so we
+	 * do exact matching on the character that follows.
+	 */
+
+	if (p == '\\') {
+	    if (*(++uniPattern) == '\0') {
+		return 0;
+	    }
+	}
+
+	/*
+	 * There's no special character. Just make sure that the next bytes of
+	 * each string match.
+	 */
+
+	if (nocase) {
+	    if (Tcl_UniCharToLower(*uniStr) !=
+		    Tcl_UniCharToLower(*uniPattern)) {
+		return 0;
+	    }
+	} else if (*uniStr != *uniPattern) {
+	    return 0;
+	}
+	uniStr++;
+	uniPattern++;
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclUniCharMatch --
+ *
+ *	See if a particular Unicode string matches a particular pattern.
+ *	Allows case insensitivity. This is the Unicode equivalent of the char*
+ *	Tcl_StringCaseMatch. This variant of Tcl_UniCharCaseMatch uses counted
+ *	Strings, so embedded NULLs are allowed.
+ *
+ * Results:
+ *	The return value is 1 if string matches pattern, and 0 otherwise. The
+ *	matching operation permits the following special characters in the
+ *	pattern: *?\[] (see the manual entry for details on what these mean).
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclUniCharMatch(
+    const Tcl_UniChar *string,	/* Unicode String. */
+    int strLen,			/* Length of String */
+    const Tcl_UniChar *pattern,	/* Pattern, which may contain special
+				 * characters. */
+    int ptnLen,			/* Length of Pattern */
+    int nocase)			/* 0 for case sensitive, 1 for insensitive */
+{
+    const Tcl_UniChar *stringEnd, *patternEnd;
+    Tcl_UniChar p;
+
+    stringEnd = string + strLen;
+    patternEnd = pattern + ptnLen;
+
+    while (1) {
+	/*
+	 * See if we're at the end of both the pattern and the string. If so,
+	 * we succeeded. If we're at the end of the pattern but not at the end
+	 * of the string, we failed.
+	 */
+
+	if (pattern == patternEnd) {
+	    return (string == stringEnd);
+	}
+	p = *pattern;
+	if ((string == stringEnd) && (p != '*')) {
+	    return 0;
+	}
+
+	/*
+	 * Check for a "*" as the next pattern character. It matches any
+	 * substring. We handle this by skipping all the characters up to the
+	 * next matching one in the pattern, and then calling ourselves
+	 * recursively for each postfix of string, until either we match or we
+	 * reach the end of the string.
+	 */
+
+	if (p == '*') {
+	    /*
+	     * Skip all successive *'s in the pattern.
+	     */
+
+	    while (*(++pattern) == '*') {
+		/* empty body */
+	    }
+	    if (pattern == patternEnd) {
+		return 1;
+	    }
+	    p = *pattern;
+	    if (nocase) {
+		p = Tcl_UniCharToLower(p);
+	    }
+	    while (1) {
+		/*
+		 * Optimization for matching - cruise through the string
+		 * quickly if the next char in the pattern isn't a special
+		 * character.
+		 */
+
+		if ((p != '[') && (p != '?') && (p != '\\')) {
+		    if (nocase) {
+			while ((string < stringEnd) && (p != *string)
+				&& (p != Tcl_UniCharToLower(*string))) {
+			    string++;
+			}
+		    } else {
+			while ((string < stringEnd) && (p != *string)) {
+			    string++;
+			}
+		    }
+		}
+		if (TclUniCharMatch(string, stringEnd - string,
+			pattern, patternEnd - pattern, nocase)) {
+		    return 1;
+		}
+		if (string == stringEnd) {
+		    return 0;
+		}
+		string++;
+	    }
+	}
+
+	/*
+	 * Check for a "?" as the next pattern character. It matches any
+	 * single character.
+	 */
+
+	if (p == '?') {
+	    pattern++;
+	    string++;
+	    continue;
+	}
+
+	/*
+	 * Check for a "[" as the next pattern character. It is followed by a
+	 * list of characters that are acceptable, or by a range (two
+	 * characters separated by "-").
+	 */
+
+	if (p == '[') {
+	    Tcl_UniChar ch1, startChar, endChar;
+
+	    pattern++;
+	    ch1 = (nocase ? Tcl_UniCharToLower(*string) : *string);
+	    string++;
+	    while (1) {
+		if ((*pattern == ']') || (pattern == patternEnd)) {
+		    return 0;
+		}
+		startChar = (nocase ? Tcl_UniCharToLower(*pattern) : *pattern);
+		pattern++;
+		if (*pattern == '-') {
+		    pattern++;
+		    if (pattern == patternEnd) {
+			return 0;
+		    }
+		    endChar = (nocase ? Tcl_UniCharToLower(*pattern)
+			    : *pattern);
+		    pattern++;
+		    if (((startChar <= ch1) && (ch1 <= endChar))
+			    || ((endChar <= ch1) && (ch1 <= startChar))) {
+			/*
+			 * Matches ranges of form [a-z] or [z-a].
+			 */
+			break;
+		    }
+		} else if (startChar == ch1) {
+		    break;
+		}
+	    }
+	    while (*pattern != ']') {
+		if (pattern == patternEnd) {
+		    pattern--;
+		    break;
+		}
+		pattern++;
+	    }
+	    pattern++;
+	    continue;
+	}
+
+	/*
+	 * If the next pattern character is '\', just strip off the '\' so we
+	 * do exact matching on the character that follows.
+	 */
+
+	if (p == '\\') {
+	    if (++pattern == patternEnd) {
+		return 0;
+	    }
+	}
+
+	/*
+	 * There's no special character. Just make sure that the next bytes of
+	 * each string match.
+	 */
+
+	if (nocase) {
+	    if (Tcl_UniCharToLower(*string) != Tcl_UniCharToLower(*pattern)) {
+		return 0;
+	    }
+	} else if (*string != *pattern) {
+	    return 0;
+	}
+	string++;
+	pattern++;
+    }
+}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tclUtil.c b/generic/tclUtil.c
new file mode 100644
index 0000000..553593c
--- /dev/null
+++ b/generic/tclUtil.c
@@ -0,0 +1,4485 @@
+/*
+ * tclUtil.c --
+ *
+ *	This file contains utility functions that are used by many Tcl
+ *	commands.
+ *
+ * Copyright (c) 1987-1993 The Regents of the University of California.
+ * Copyright (c) 1994-1998 Sun Microsystems, Inc.
+ * Copyright (c) 2001 by Kevin B. Kenny. All rights reserved.
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#include "tclInt.h"
+#include "tclParse.h"
+#include "tclStringTrim.h"
+#include <math.h>
+
+/*
+ * The absolute pathname of the executable in which this Tcl library is
+ * running.
+ */
+
+static ProcessGlobalValue executableName = {
+    0, 0, NULL, NULL, NULL, NULL, NULL
+};
+
+/*
+ * The following values are used in the flags arguments of Tcl*Scan*Element
+ * and Tcl*Convert*Element.  The values TCL_DONT_USE_BRACES and
+ * TCL_DONT_QUOTE_HASH are defined in tcl.h, like so:
+ *
+#define TCL_DONT_USE_BRACES     1
+#define TCL_DONT_QUOTE_HASH     8
+ *
+ * Those are public flag bits which callers of the public routines
+ * Tcl_Convert*Element() can use to indicate:
+ *
+ * TCL_DONT_USE_BRACES -	1 means the caller is insisting that brace
+ *				quoting not be used when converting the list
+ *				element.
+ * TCL_DONT_QUOTE_HASH -	1 means the caller insists that a leading hash
+ *				character ('#') should *not* be quoted. This
+ *				is appropriate when the caller can guarantee
+ *				the element is not the first element of a
+ *				list, so [eval] cannot mis-parse the element
+ *				as a comment.
+ *
+ * The remaining values which can be carried by the flags of these routines
+ * are for internal use only.  Make sure they do not overlap with the public
+ * values above.
+ *
+ * The Tcl*Scan*Element() routines make a determination which of 4 modes of
+ * conversion is most appropriate for Tcl*Convert*Element() to perform, and
+ * sets two bits of the flags value to indicate the mode selected.
+ *
+ * CONVERT_NONE		The element needs no quoting. Its literal string is
+ *			suitable as is.
+ * CONVERT_BRACE	The conversion should be enclosing the literal string
+ *			in braces.
+ * CONVERT_ESCAPE	The conversion should be using backslashes to escape
+ *			any characters in the string that require it.
+ * CONVERT_MASK		A mask value used to extract the conversion mode from
+ *			the flags argument.
+ *			Also indicates a strange conversion mode where all
+ *			special characters are escaped with backslashes
+ *			*except for braces*. This is a strange and unnecessary
+ *			case, but it's part of the historical way in which
+ *			lists have been formatted in Tcl. To experiment with
+ *			removing this case, set the value of COMPAT to 0.
+ *
+ * One last flag value is used only by callers of TclScanElement(). The flag
+ * value produced by a call to Tcl*Scan*Element() will never leave this bit
+ * set.
+ *
+ * CONVERT_ANY		The caller of TclScanElement() declares it can make no
+ *			promise about what public flags will be passed to the
+ *			matching call of TclConvertElement(). As such,
+ *			TclScanElement() has to determine the worst case
+ *			destination buffer length over all possibilities, and
+ *			in other cases this means an overestimate of the
+ *			required size.
+ *
+ * For more details, see the comments on the Tcl*Scan*Element and
+ * Tcl*Convert*Element routines.
+ */
+
+#define COMPAT 1
+#define CONVERT_NONE	0
+#define CONVERT_BRACE	2
+#define CONVERT_ESCAPE	4
+#define CONVERT_MASK	(CONVERT_BRACE | CONVERT_ESCAPE)
+#define CONVERT_ANY	16
+
+/*
+ * The following key is used by Tcl_PrintDouble and TclPrecTraceProc to
+ * access the precision to be used for double formatting.
+ */
+
+static Tcl_ThreadDataKey precisionKey;
+
+/*
+ * Prototypes for functions defined later in this file.
+ */
+
+static void		ClearHash(Tcl_HashTable *tablePtr);
+static void		FreeProcessGlobalValue(ClientData clientData);
+static void		FreeThreadHash(ClientData clientData);
+static Tcl_HashTable *	GetThreadHash(Tcl_ThreadDataKey *keyPtr);
+static int		SetEndOffsetFromAny(Tcl_Interp *interp,
+			    Tcl_Obj *objPtr);
+static void		UpdateStringOfEndOffset(Tcl_Obj *objPtr);
+static int		FindElement(Tcl_Interp *interp, const char *string,
+			    int stringLength, const char *typeStr,
+			    const char *typeCode, const char **elementPtr,
+			    const char **nextPtr, int *sizePtr,
+			    int *literalPtr);
+/*
+ * The following is the Tcl object type definition for an object that
+ * represents a list index in the form, "end-offset". It is used as a
+ * performance optimization in TclGetIntForIndex. The internal rep is an
+ * integer, so no memory management is required for it.
+ */
+
+const Tcl_ObjType tclEndOffsetType = {
+    "end-offset",			/* name */
+    NULL,				/* freeIntRepProc */
+    NULL,				/* dupIntRepProc */
+    UpdateStringOfEndOffset,		/* updateStringProc */
+    SetEndOffsetFromAny
+};
+
+/*
+ *	*	STRING REPRESENTATION OF LISTS	*	*	*
+ *
+ * The next several routines implement the conversions of strings to and from
+ * Tcl lists. To understand their operation, the rules of parsing and
+ * generating the string representation of lists must be known.  Here we
+ * describe them in one place.
+ *
+ * A list is made up of zero or more elements. Any string is a list if it is
+ * made up of alternating substrings of element-separating ASCII whitespace
+ * and properly formatted elements.
+ *
+ * The ASCII characters which can make up the whitespace between list elements
+ * are:
+ *
+ *	\u0009	\t	TAB
+ *	\u000A	\n	NEWLINE
+ *	\u000B	\v	VERTICAL TAB
+ *	\u000C	\f	FORM FEED
+ * 	\u000D	\r	CARRIAGE RETURN
+ *	\u0020		SPACE
+ *
+ * NOTE: differences between this and other places where Tcl defines a role
+ * for "whitespace".
+ *
+ *	* Unlike command parsing, here NEWLINE is just another whitespace
+ *	  character; its role as a command terminator in a script has no
+ *	  importance here.
+ *
+ *	* Unlike command parsing, the BACKSLASH NEWLINE sequence is not
+ *	  considered to be a whitespace character.
+ *
+ *	* Other Unicode whitespace characters (recognized by [string is space]
+ *	  or Tcl_UniCharIsSpace()) do not play any role as element separators
+ *	  in Tcl lists.
+ *
+ *	* The NUL byte ought not appear, as it is not in strings properly
+ *	  encoded for Tcl, but if it is present, it is not treated as
+ *	  separating whitespace, or a string terminator. It is just another
+ *	  character in a list element.
+ *
+ * The interpretation of a formatted substring as a list element follows rules
+ * similar to the parsing of the words of a command in a Tcl script. Backslash
+ * substitution plays a key role, and is defined exactly as it is in command
+ * parsing. The same routine, TclParseBackslash() is used in both command
+ * parsing and list parsing.
+ *
+ * NOTE: This means that if and when backslash substitution rules ever change
+ * for command parsing, the interpretation of strings as lists also changes.
+ *
+ * Backslash substitution replaces an "escape sequence" of one or more
+ * characters starting with
+ *		\u005c	\	BACKSLASH
+ * with a single character. The one character escape sequence case happens only
+ * when BACKSLASH is the last character in the string. In all other cases, the
+ * escape sequence is at least two characters long.
+ *
+ * The formatted substrings are interpreted as element values according to the
+ * following cases:
+ *
+ * * If the first character of a formatted substring is
+ *		\u007b	{	OPEN BRACE
+ *   then the end of the substring is the matching
+ *		\u007d	}	CLOSE BRACE
+ *   character, where matching is determined by counting nesting levels, and
+ *   not including any brace characters that are contained within a backslash
+ *   escape sequence in the nesting count. Having found the matching brace,
+ *   all characters between the braces are the string value of the element.
+ *   If no matching close brace is found before the end of the string, the
+ *   string is not a Tcl list. If the character following the close brace is
+ *   not an element separating whitespace character, or the end of the string,
+ *   then the string is not a Tcl list.
+ *
+ *   NOTE: this differs from a brace-quoted word in the parsing of a Tcl
+ *   command only in its treatment of the backslash-newline sequence. In a
+ *   list element, the literal characters in the backslash-newline sequence
+ *   become part of the element value. In a script word, conversion to a
+ *   single SPACE character is done.
+ *
+ *   NOTE: Most list element values can be represented by a formatted
+ *   substring using brace quoting. The exceptions are any element value that
+ *   includes an unbalanced brace not in a backslash escape sequence, and any
+ *   value that ends with a backslash not itself in a backslash escape
+ *   sequence.
+ *
+ * * If the first character of a formatted substring is
+ *		\u0022	"	QUOTE
+ *   then the end of the substring is the next QUOTE character, not counting
+ *   any QUOTE characters that are contained within a backslash escape
+ *   sequence. If no next QUOTE is found before the end of the string, the
+ *   string is not a Tcl list. If the character following the closing QUOTE is
+ *   not an element separating whitespace character, or the end of the string,
+ *   then the string is not a Tcl list. Having found the limits of the
+ *   substring, the element value is produced by performing backslash
+ *   substitution on the character sequence between the open and close QUOTEs.
+ *
+ *   NOTE: Any element value can be represented by this style of formatting,
+ *   given suitable choice of backslash escape sequences.
+ *
+ * * All other formatted substrings are terminated by the next element
+ *   separating whitespace character in the string.  Having found the limits
+ *   of the substring, the element value is produced by performing backslash
+ *   substitution on it.
+ *
+ *   NOTE: Any element value can be represented by this style of formatting,
+ *   given suitable choice of backslash escape sequences, with one exception.
+ *   The empty string cannot be represented as a list element without the use
+ *   of either braces or quotes to delimit it.
+ *
+ * This collection of parsing rules is implemented in the routine
+ * FindElement().
+ *
+ * In order to produce lists that can be parsed by these rules, we need the
+ * ability to distinguish between characters that are part of a list element
+ * value from characters providing syntax that define the structure of the
+ * list. This means that our code that generates lists must at a minimum be
+ * able to produce escape sequences for the 10 characters identified above
+ * that have significance to a list parser.
+ *
+ *	*	*	CANONICAL LISTS	*	*	*	*	*
+ *
+ * In addition to the basic rules for parsing strings into Tcl lists, there
+ * are additional properties to be met by the set of list values that are
+ * generated by Tcl.  Such list values are often said to be in "canonical
+ * form":
+ *
+ * * When any canonical list is evaluated as a Tcl script, it is a script of
+ *   either zero commands (an empty list) or exactly one command. The command
+ *   word is exactly the first element of the list, and each argument word is
+ *   exactly one of the following elements of the list. This means that any
+ *   characters that have special meaning during script evaluation need
+ *   special treatment when canonical lists are produced:
+ *
+ *	* Whitespace between elements may not include NEWLINE.
+ *	* The command terminating character,
+ *		\u003b	;	SEMICOLON
+ *	  must be BRACEd, QUOTEd, or escaped so that it does not terminate the
+ * 	  command prematurely.
+ *	* Any of the characters that begin substitutions in scripts,
+ *		\u0024	$	DOLLAR
+ *		\u005b	[	OPEN BRACKET
+ *		\u005c	\	BACKSLASH
+ *	  need to be BRACEd or escaped.
+ *	* In any list where the first character of the first element is
+ *		\u0023	#	HASH
+ *	  that HASH character must be BRACEd, QUOTEd, or escaped so that it
+ *	  does not convert the command into a comment.
+ *	* Any list element that contains the character sequence BACKSLASH
+ *	  NEWLINE cannot be formatted with BRACEs. The BACKSLASH character
+ *	  must be represented by an escape sequence, and unless QUOTEs are
+ *	  used, the NEWLINE must be as well.
+ *
+ * * It is also guaranteed that one can use a canonical list as a building
+ *   block of a larger script within command substitution, as in this example:
+ *	set script "puts \[[list $cmd $arg]]"; eval $script
+ *   To support this usage, any appearance of the character
+ *		\u005d	]	CLOSE BRACKET
+ *   in a list element must be BRACEd, QUOTEd, or escaped.
+ *
+ * * Finally it is guaranteed that enclosing a canonical list in braces
+ *   produces a new value that is also a canonical list.  This new list has
+ *   length 1, and its only element is the original canonical list.  This same
+ *   guarantee also makes it possible to construct scripts where an argument
+ *   word is given a list value by enclosing the canonical form of that list
+ *   in braces:
+ *	set script "puts {[list $one $two $three]}"; eval $script
+ *   This sort of coding was once fairly common, though it's become more
+ *   idiomatic to see the following instead:
+ *	set script [list puts [list $one $two $three]]; eval $script
+ *   In order to support this guarantee, every canonical list must have
+ *   balance when counting those braces that are not in escape sequences.
+ *
+ * Within these constraints, the canonical list generation routines
+ * TclScanElement() and TclConvertElement() attempt to generate the string for
+ * any list that is easiest to read. When an element value is itself
+ * acceptable as the formatted substring, it is usually used (CONVERT_NONE).
+ * When some quoting or escaping is required, use of BRACEs (CONVERT_BRACE) is
+ * usually preferred over the use of escape sequences (CONVERT_ESCAPE). There
+ * are some exceptions to both of these preferences for reasons of code
+ * simplicity, efficiency, and continuation of historical habits. Canonical
+ * lists never use the QUOTE formatting to delimit their elements because that
+ * form of quoting does not nest, which makes construction of nested lists far
+ * too much trouble.  Canonical lists always use only a single SPACE character
+ * for element-separating whitespace.
+ *
+ *	*	*	FUTURE CONSIDERATIONS	*	*	*
+ *
+ * When a list element requires quoting or escaping due to a CLOSE BRACKET
+ * character or an internal QUOTE character, a strange formatting mode is
+ * recommended. For example, if the value "a{b]c}d" is converted by the usual
+ * modes:
+ *
+ *	CONVERT_BRACE:	a{b]c}d		=> {a{b]c}d}
+ *	CONVERT_ESCAPE:	a{b]c}d		=> a\{b\]c\}d
+ *
+ * we get perfectly usable formatted list elements. However, this is not what
+ * Tcl releases have been producing. Instead, we have:
+ *
+ *	CONVERT_MASK:	a{b]c}d		=> a{b\]c}d
+ *
+ * where the CLOSE BRACKET is escaped, but the BRACEs are not. The same effect
+ * can be seen replacing ] with " in this example. There does not appear to be
+ * any functional or aesthetic purpose for this strange additional mode. The
+ * sole purpose I can see for preserving it is to keep generating the same
+ * formatted lists programmers have become accustomed to, and perhaps written
+ * tests to expect. That is, compatibility only. The additional code
+ * complexity required to support this mode is significant. The lines of code
+ * supporting it are delimited in the routines below with #if COMPAT
+ * directives. This makes it easy to experiment with eliminating this
+ * formatting mode simply with "#define COMPAT 0" above. I believe this is
+ * worth considering.
+ *
+ * Another consideration is the treatment of QUOTE characters in list
+ * elements. TclConvertElement() must have the ability to produce the escape
+ * sequence \" so that when a list element begins with a QUOTE we do not
+ * confuse that first character with a QUOTE used as list syntax to define
+ * list structure. However, that is the only place where QUOTE characters need
+ * quoting. In this way, handling QUOTE could really be much more like the way
+ * we handle HASH which also needs quoting and escaping only in particular
+ * situations. Following up this could increase the set of list elements that
+ * can use the CONVERT_NONE formatting mode.
+ *
+ * More speculative is that the demands of canonical list form require brace
+ * balance for the list as a whole, while the current implementation achieves
+ * this by establishing brace balance for every element.
+ *
+ * Finally, a reminder that the rules for parsing and formatting lists are
+ * closely tied together with the rules for parsing and evaluating scripts,
+ * and will need to evolve in sync.
+ */
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclMaxListLength --
+ *
+ *	Given 'bytes' pointing to 'numBytes' bytes, scan through them and
+ *	count the number of whitespace runs that could be list element
+ *	separators. If 'numBytes' is -1, scan to the terminating '\0'. Not a
+ *	full list parser. Typically used to get a quick and dirty overestimate
+ *	of length size in order to allocate space for an actual list parser to
+ *	operate with.
+ *
+ * Results:
+ *	Returns the largest number of list elements that could possibly be in
+ *	this string, interpreted as a Tcl list. If 'endPtr' is not NULL,
+ *	writes a pointer to the end of the string scanned there.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclMaxListLength(
+    const char *bytes,
+    int numBytes,
+    const char **endPtr)
+{
+    int count = 0;
+
+    if ((numBytes == 0) || ((numBytes == -1) && (*bytes == '\0'))) {
+	/* Empty string case - quick exit */
+	goto done;
+    }
+
+    /*
+     * No list element before leading white space.
+     */
+
+    count += 1 - TclIsSpaceProc(*bytes);
+
+    /*
+     * Count white space runs as potential element separators.
+     */
+
+    while (numBytes) {
+	if ((numBytes == -1) && (*bytes == '\0')) {
+	    break;
+	}
+	if (TclIsSpaceProc(*bytes)) {
+	    /*
+	     * Space run started; bump count.
+	     */
+
+	    count++;
+	    do {
+		bytes++;
+		numBytes -= (numBytes != -1);
+	    } while (numBytes && TclIsSpaceProc(*bytes));
+	    if ((numBytes == 0) || ((numBytes == -1) && (*bytes == '\0'))) {
+		break;
+	    }
+
+	    /*
+	     * (*bytes) is non-space; return to counting state.
+	     */
+	}
+	bytes++;
+	numBytes -= (numBytes != -1);
+    }
+
+    /*
+     * No list element following trailing white space.
+     */
+
+    count -= TclIsSpaceProc(bytes[-1]);
+
+  done:
+    if (endPtr) {
+	*endPtr = bytes;
+    }
+    return count;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclFindElement --
+ *
+ *	Given a pointer into a Tcl list, locate the first (or next) element in
+ *	the list.
+ *
+ * Results:
+ *	The return value is normally TCL_OK, which means that the element was
+ *	successfully located. If TCL_ERROR is returned it means that list
+ *	didn't have proper list structure; the interp's result contains a more
+ *	detailed error message.
+ *
+ *	If TCL_OK is returned, then *elementPtr will be set to point to the
+ *	first element of list, and *nextPtr will be set to point to the
+ *	character just after any white space following the last character
+ *	that's part of the element. If this is the last argument in the list,
+ *	then *nextPtr will point just after the last character in the list
+ *	(i.e., at the character at list+listLength). If sizePtr is non-NULL,
+ *	*sizePtr is filled in with the number of bytes in the element. If the
+ *	element is in braces, then *elementPtr will point to the character
+ *	after the opening brace and *sizePtr will not include either of the
+ *	braces. If there isn't an element in the list, *sizePtr will be zero,
+ *	and both *elementPtr and *nextPtr will point just after the last
+ *	character in the list. If literalPtr is non-NULL, *literalPtr is set
+ *	to a boolean value indicating whether the substring returned as the
+ *	values of **elementPtr and *sizePtr is the literal value of a list
+ *	element. If not, a call to TclCopyAndCollapse() is needed to produce
+ *	the actual value of the list element. Note: this function does NOT
+ *	collapse backslash sequences, but uses *literalPtr to tell callers
+ *	when it is required for them to do so.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclFindElement(
+    Tcl_Interp *interp,		/* Interpreter to use for error reporting. If
+				 * NULL, then no error message is left after
+				 * errors. */
+    const char *list,		/* Points to the first byte of a string
+				 * containing a Tcl list with zero or more
+				 * elements (possibly in braces). */
+    int listLength,		/* Number of bytes in the list's string. */
+    const char **elementPtr,	/* Where to put address of first significant
+				 * character in first element of list. */
+    const char **nextPtr,	/* Fill in with location of character just
+				 * after all white space following end of
+				 * argument (next arg or end of list). */
+    int *sizePtr,		/* If non-zero, fill in with size of
+				 * element. */
+    int *literalPtr)		/* If non-zero, fill in with non-zero/zero to
+				 * indicate that the substring of *sizePtr
+				 * bytes starting at **elementPtr is/is not
+				 * the literal list element and therefore
+				 * does not/does require a call to
+				 * TclCopyAndCollapse() by the caller. */
+{
+    return FindElement(interp, list, listLength, "list", "LIST", elementPtr,
+	    nextPtr, sizePtr, literalPtr);
+}
+
+int
+TclFindDictElement(
+    Tcl_Interp *interp,		/* Interpreter to use for error reporting. If
+				 * NULL, then no error message is left after
+				 * errors. */
+    const char *dict,		/* Points to the first byte of a string
+				 * containing a Tcl dictionary with zero or
+				 * more keys and values (possibly in
+				 * braces). */
+    int dictLength,		/* Number of bytes in the dict's string. */
+    const char **elementPtr,	/* Where to put address of first significant
+				 * character in the first element (i.e., key
+				 * or value) of dict. */
+    const char **nextPtr,	/* Fill in with location of character just
+				 * after all white space following end of
+				 * element (next arg or end of list). */
+    int *sizePtr,		/* If non-zero, fill in with size of
+				 * element. */
+    int *literalPtr)		/* If non-zero, fill in with non-zero/zero to
+				 * indicate that the substring of *sizePtr
+				 * bytes starting at **elementPtr is/is not
+				 * the literal key or value and therefore
+				 * does not/does require a call to
+				 * TclCopyAndCollapse() by the caller. */
+{
+    return FindElement(interp, dict, dictLength, "dict", "DICTIONARY",
+	    elementPtr, nextPtr, sizePtr, literalPtr);
+}
+
+static int
+FindElement(
+    Tcl_Interp *interp,		/* Interpreter to use for error reporting. If
+				 * NULL, then no error message is left after
+				 * errors. */
+    const char *string,		/* Points to the first byte of a string
+				 * containing a Tcl list or dictionary with
+				 * zero or more elements (possibly in
+				 * braces). */
+    int stringLength,		/* Number of bytes in the string. */
+    const char *typeStr,	/* The name of the type of thing we are
+				 * parsing, for error messages. */
+    const char *typeCode,	/* The type code for thing we are parsing, for
+				 * error messages. */
+    const char **elementPtr,	/* Where to put address of first significant
+				 * character in first element. */
+    const char **nextPtr,	/* Fill in with location of character just
+				 * after all white space following end of
+				 * argument (next arg or end of list/dict). */
+    int *sizePtr,		/* If non-zero, fill in with size of
+				 * element. */
+    int *literalPtr)		/* If non-zero, fill in with non-zero/zero to
+				 * indicate that the substring of *sizePtr
+				 * bytes starting at **elementPtr is/is not
+				 * the literal list/dict element and therefore
+				 * does not/does require a call to
+				 * TclCopyAndCollapse() by the caller. */
+{
+    const char *p = string;
+    const char *elemStart;	/* Points to first byte of first element. */
+    const char *limit;		/* Points just after list/dict's last byte. */
+    int openBraces = 0;		/* Brace nesting level during parse. */
+    int inQuotes = 0;
+    int size = 0;		/* lint. */
+    int numChars;
+    int literal = 1;
+    const char *p2;
+
+    /*
+     * Skim off leading white space and check for an opening brace or quote.
+     * We treat embedded NULLs in the list/dict as bytes belonging to a list
+     * element (or dictionary key or value).
+     */
+
+    limit = (string + stringLength);
+    while ((p < limit) && (TclIsSpaceProc(*p))) {
+	p++;
+    }
+    if (p == limit) {		/* no element found */
+	elemStart = limit;
+	goto done;
+    }
+
+    if (*p == '{') {
+	openBraces = 1;
+	p++;
+    } else if (*p == '"') {
+	inQuotes = 1;
+	p++;
+    }
+    elemStart = p;
+
+    /*
+     * Find element's end (a space, close brace, or the end of the string).
+     */
+
+    while (p < limit) {
+	switch (*p) {
+	    /*
+	     * Open brace: don't treat specially unless the element is in
+	     * braces. In this case, keep a nesting count.
+	     */
+
+	case '{':
+	    if (openBraces != 0) {
+		openBraces++;
+	    }
+	    break;
+
+	    /*
+	     * Close brace: if element is in braces, keep nesting count and
+	     * quit when the last close brace is seen.
+	     */
+
+	case '}':
+	    if (openBraces > 1) {
+		openBraces--;
+	    } else if (openBraces == 1) {
+		size = (p - elemStart);
+		p++;
+		if ((p >= limit) || TclIsSpaceProc(*p)) {
+		    goto done;
+		}
+
+		/*
+		 * Garbage after the closing brace; return an error.
+		 */
+
+		if (interp != NULL) {
+		    p2 = p;
+		    while ((p2 < limit) && (!TclIsSpaceProc(*p2))
+			    && (p2 < p+20)) {
+			p2++;
+		    }
+		    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+			    "%s element in braces followed by \"%.*s\" "
+			    "instead of space", typeStr, (int) (p2-p), p));
+		    Tcl_SetErrorCode(interp, "TCL", "VALUE", typeCode, "JUNK",
+			    NULL);
+		}
+		return TCL_ERROR;
+	    }
+	    break;
+
+	    /*
+	     * Backslash: skip over everything up to the end of the backslash
+	     * sequence.
+	     */
+
+	case '\\':
+	    if (openBraces == 0) {
+		/*
+		 * A backslash sequence not within a brace quoted element
+		 * means the value of the element is different from the
+		 * substring we are parsing. A call to TclCopyAndCollapse() is
+		 * needed to produce the element value. Inform the caller.
+		 */
+
+		literal = 0;
+	    }
+	    TclParseBackslash(p, limit - p, &numChars, NULL);
+	    p += (numChars - 1);
+	    break;
+
+	    /*
+	     * Space: ignore if element is in braces or quotes; otherwise
+	     * terminate element.
+	     */
+
+	case ' ':
+	case '\f':
+	case '\n':
+	case '\r':
+	case '\t':
+	case '\v':
+	    if ((openBraces == 0) && !inQuotes) {
+		size = (p - elemStart);
+		goto done;
+	    }
+	    break;
+
+	    /*
+	     * Double-quote: if element is in quotes then terminate it.
+	     */
+
+	case '"':
+	    if (inQuotes) {
+		size = (p - elemStart);
+		p++;
+		if ((p >= limit) || TclIsSpaceProc(*p)) {
+		    goto done;
+		}
+
+		/*
+		 * Garbage after the closing quote; return an error.
+		 */
+
+		if (interp != NULL) {
+		    p2 = p;
+		    while ((p2 < limit) && (!TclIsSpaceProc(*p2))
+			    && (p2 < p+20)) {
+			p2++;
+		    }
+		    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+			    "%s element in quotes followed by \"%.*s\" "
+			    "instead of space", typeStr, (int) (p2-p), p));
+		    Tcl_SetErrorCode(interp, "TCL", "VALUE", typeCode, "JUNK",
+			    NULL);
+		}
+		return TCL_ERROR;
+	    }
+	    break;
+	}
+	p++;
+    }
+
+    /*
+     * End of list/dict: terminate element.
+     */
+
+    if (p == limit) {
+	if (openBraces != 0) {
+	    if (interp != NULL) {
+		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+			"unmatched open brace in %s", typeStr));
+		Tcl_SetErrorCode(interp, "TCL", "VALUE", typeCode, "BRACE",
+			NULL);
+	    }
+	    return TCL_ERROR;
+	} else if (inQuotes) {
+	    if (interp != NULL) {
+		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+			"unmatched open quote in %s", typeStr));
+		Tcl_SetErrorCode(interp, "TCL", "VALUE", typeCode, "QUOTE",
+			NULL);
+	    }
+	    return TCL_ERROR;
+	}
+	size = (p - elemStart);
+    }
+
+  done:
+    while ((p < limit) && (TclIsSpaceProc(*p))) {
+	p++;
+    }
+    *elementPtr = elemStart;
+    *nextPtr = p;
+    if (sizePtr != 0) {
+	*sizePtr = size;
+    }
+    if (literalPtr != 0) {
+	*literalPtr = literal;
+    }
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclCopyAndCollapse --
+ *
+ *	Copy a string and substitute all backslash escape sequences
+ *
+ * Results:
+ *	Count bytes get copied from src to dst. Along the way, backslash
+ *	sequences are substituted in the copy. After scanning count bytes from
+ *	src, a null character is placed at the end of dst. Returns the number
+ *	of bytes that got written to dst.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclCopyAndCollapse(
+    int count,			/* Number of byte to copy from src. */
+    const char *src,		/* Copy from here... */
+    char *dst)			/* ... to here. */
+{
+    int newCount = 0;
+
+    while (count > 0) {
+	char c = *src;
+
+	if (c == '\\') {
+	    int numRead;
+	    int backslashCount = TclParseBackslash(src, count, &numRead, dst);
+
+	    dst += backslashCount;
+	    newCount += backslashCount;
+	    src += numRead;
+	    count -= numRead;
+	} else {
+	    *dst = c;
+	    dst++;
+	    newCount++;
+	    src++;
+	    count--;
+	}
+    }
+    *dst = 0;
+    return newCount;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_SplitList --
+ *
+ *	Splits a list up into its constituent fields.
+ *
+ * Results
+ *	The return value is normally TCL_OK, which means that the list was
+ *	successfully split up. If TCL_ERROR is returned, it means that "list"
+ *	didn't have proper list structure; the interp's result will contain a
+ *	more detailed error message.
+ *
+ *	*argvPtr will be filled in with the address of an array whose elements
+ *	point to the elements of list, in order. *argcPtr will get filled in
+ *	with the number of valid elements in the array. A single block of
+ *	memory is dynamically allocated to hold both the argv array and a copy
+ *	of the list (with backslashes and braces removed in the standard way).
+ *	The caller must eventually free this memory by calling free() on
+ *	*argvPtr. Note: *argvPtr and *argcPtr are only modified if the
+ *	function returns normally.
+ *
+ * Side effects:
+ *	Memory is allocated.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_SplitList(
+    Tcl_Interp *interp,		/* Interpreter to use for error reporting. If
+				 * NULL, no error message is left. */
+    const char *list,		/* Pointer to string with list structure. */
+    int *argcPtr,		/* Pointer to location to fill in with the
+				 * number of elements in the list. */
+    const char ***argvPtr)	/* Pointer to place to store pointer to array
+				 * of pointers to list elements. */
+{
+    const char **argv, *end, *element;
+    char *p;
+    int length, size, i, result, elSize;
+
+    /*
+     * Allocate enough space to work in. A (const char *) for each (possible)
+     * list element plus one more for terminating NULL, plus as many bytes as
+     * in the original string value, plus one more for a terminating '\0'.
+     * Space used to hold element separating white space in the original
+     * string gets re-purposed to hold '\0' characters in the argv array.
+     */
+
+    size = TclMaxListLength(list, -1, &end) + 1;
+    length = end - list;
+    argv = ckalloc((size * sizeof(char *)) + length + 1);
+
+    for (i = 0, p = ((char *) argv) + size*sizeof(char *);
+	    *list != 0;  i++) {
+	const char *prevList = list;
+	int literal;
+
+	result = TclFindElement(interp, list, length, &element, &list,
+		&elSize, &literal);
+	length -= (list - prevList);
+	if (result != TCL_OK) {
+	    ckfree(argv);
+	    return result;
+	}
+	if (*element == 0) {
+	    break;
+	}
+	if (i >= size) {
+	    ckfree(argv);
+	    if (interp != NULL) {
+		Tcl_SetObjResult(interp, Tcl_NewStringObj(
+			"internal error in Tcl_SplitList", -1));
+		Tcl_SetErrorCode(interp, "TCL", "INTERNAL", "Tcl_SplitList",
+			NULL);
+	    }
+	    return TCL_ERROR;
+	}
+	argv[i] = p;
+	if (literal) {
+	    memcpy(p, element, (size_t) elSize);
+	    p += elSize;
+	    *p = 0;
+	    p++;
+	} else {
+	    p += 1 + TclCopyAndCollapse(elSize, element, p);
+	}
+    }
+
+    argv[i] = NULL;
+    *argvPtr = argv;
+    *argcPtr = i;
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_ScanElement --
+ *
+ *	This function is a companion function to Tcl_ConvertElement. It scans
+ *	a string to see what needs to be done to it (e.g. add backslashes or
+ *	enclosing braces) to make the string into a valid Tcl list element.
+ *
+ * Results:
+ *	The return value is an overestimate of the number of bytes that will
+ *	be needed by Tcl_ConvertElement to produce a valid list element from
+ *	src. The word at *flagPtr is filled in with a value needed by
+ *	Tcl_ConvertElement when doing the actual conversion.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_ScanElement(
+    register const char *src,	/* String to convert to list element. */
+    register int *flagPtr)	/* Where to store information to guide
+				 * Tcl_ConvertCountedElement. */
+{
+    return Tcl_ScanCountedElement(src, -1, flagPtr);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_ScanCountedElement --
+ *
+ *	This function is a companion function to Tcl_ConvertCountedElement. It
+ *	scans a string to see what needs to be done to it (e.g. add
+ *	backslashes or enclosing braces) to make the string into a valid Tcl
+ *	list element. If length is -1, then the string is scanned from src up
+ *	to the first null byte.
+ *
+ * Results:
+ *	The return value is an overestimate of the number of bytes that will
+ *	be needed by Tcl_ConvertCountedElement to produce a valid list element
+ *	from src. The word at *flagPtr is filled in with a value needed by
+ *	Tcl_ConvertCountedElement when doing the actual conversion.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_ScanCountedElement(
+    const char *src,		/* String to convert to Tcl list element. */
+    int length,			/* Number of bytes in src, or -1. */
+    int *flagPtr)		/* Where to store information to guide
+				 * Tcl_ConvertElement. */
+{
+    int flags = CONVERT_ANY;
+    int numBytes = TclScanElement(src, length, &flags);
+
+    *flagPtr = flags;
+    return numBytes;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclScanElement --
+ *
+ *	This function is a companion function to TclConvertElement. It scans a
+ *	string to see what needs to be done to it (e.g. add backslashes or
+ *	enclosing braces) to make the string into a valid Tcl list element. If
+ *	length is -1, then the string is scanned from src up to the first null
+ *	byte. A NULL value for src is treated as an empty string. The incoming
+ *	value of *flagPtr is a report from the caller what additional flags it
+ *	will pass to TclConvertElement().
+ *
+ * Results:
+ *	The recommended formatting mode for the element is determined and a
+ *	value is written to *flagPtr indicating that recommendation. This
+ *	recommendation is combined with the incoming flag values in *flagPtr
+ *	set by the caller to determine how many bytes will be needed by
+ *	TclConvertElement() in which to write the formatted element following
+ *	the recommendation modified by the flag values. This number of bytes
+ *	is the return value of the routine.  In some situations it may be an
+ *	overestimate, but so long as the caller passes the same flags to
+ *	TclConvertElement(), it will be large enough.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclScanElement(
+    const char *src,		/* String to convert to Tcl list element. */
+    int length,			/* Number of bytes in src, or -1. */
+    int *flagPtr)		/* Where to store information to guide
+				 * Tcl_ConvertElement. */
+{
+    const char *p = src;
+    int nestingLevel = 0;	/* Brace nesting count */
+    int forbidNone = 0;		/* Do not permit CONVERT_NONE mode. Something
+				 * needs protection or escape. */
+    int requireEscape = 0;	/* Force use of CONVERT_ESCAPE mode.  For some
+				 * reason bare or brace-quoted form fails. */
+    int extra = 0;		/* Count of number of extra bytes needed for
+				 * formatted element, assuming we use escape
+				 * sequences in formatting. */
+    int bytesNeeded;		/* Buffer length computed to complete the
+				 * element formatting in the selected mode. */
+#if COMPAT
+    int preferEscape = 0;	/* Use preferences to track whether to use */
+    int preferBrace = 0;	/* CONVERT_MASK mode. */
+    int braceCount = 0;		/* Count of all braces '{' '}' seen. */
+#endif /* COMPAT */
+
+    if ((p == NULL) || (length == 0) || ((*p == '\0') && (length == -1))) {
+	/*
+	 * Empty string element must be brace quoted.
+	 */
+
+	*flagPtr = CONVERT_BRACE;
+	return 2;
+    }
+
+    if ((*p == '{') || (*p == '"')) {
+	/*
+	 * Must escape or protect so leading character of value is not
+	 * misinterpreted as list element delimiting syntax.
+	 */
+
+	forbidNone = 1;
+#if COMPAT
+	preferBrace = 1;
+#endif /* COMPAT */
+    }
+
+    while (length) {
+      if (CHAR_TYPE(*p) != TYPE_NORMAL) {
+	switch (*p) {
+	case '{':	/* TYPE_BRACE */
+#if COMPAT
+	    braceCount++;
+#endif /* COMPAT */
+	    extra++;				/* Escape '{' => '\{' */
+	    nestingLevel++;
+	    break;
+	case '}':	/* TYPE_BRACE */
+#if COMPAT
+	    braceCount++;
+#endif /* COMPAT */
+	    extra++;				/* Escape '}' => '\}' */
+	    nestingLevel--;
+	    if (nestingLevel < 0) {
+		/*
+		 * Unbalanced braces!  Cannot format with brace quoting.
+		 */
+
+		requireEscape = 1;
+	    }
+	    break;
+	case ']':	/* TYPE_CLOSE_BRACK */
+	case '"':	/* TYPE_SPACE */
+#if COMPAT
+	    forbidNone = 1;
+	    extra++;		/* Escapes all just prepend a backslash */
+	    preferEscape = 1;
+	    break;
+#else
+	    /* FLOW THROUGH */
+#endif /* COMPAT */
+	case '[':	/* TYPE_SUBS */
+	case '$':	/* TYPE_SUBS */
+	case ';':	/* TYPE_COMMAND_END */
+	case ' ':	/* TYPE_SPACE */
+	case '\f':	/* TYPE_SPACE */
+	case '\n':	/* TYPE_COMMAND_END */
+	case '\r':	/* TYPE_SPACE */
+	case '\t':	/* TYPE_SPACE */
+	case '\v':	/* TYPE_SPACE */
+	    forbidNone = 1;
+	    extra++;		/* Escape sequences all one byte longer. */
+#if COMPAT
+	    preferBrace = 1;
+#endif /* COMPAT */
+	    break;
+	case '\\':	/* TYPE_SUBS */
+	    extra++;				/* Escape '\' => '\\' */
+	    if ((length == 1) || ((length == -1) && (p[1] == '\0'))) {
+		/*
+		 * Final backslash. Cannot format with brace quoting.
+		 */
+
+		requireEscape = 1;
+		break;
+	    }
+	    if (p[1] == '\n') {
+		extra++;	/* Escape newline => '\n', one byte longer */
+
+		/*
+		 * Backslash newline sequence.  Brace quoting not permitted.
+		 */
+
+		requireEscape = 1;
+		length -= (length > 0);
+		p++;
+		break;
+	    }
+	    if ((p[1] == '{') || (p[1] == '}') || (p[1] == '\\')) {
+		extra++;	/* Escape sequences all one byte longer. */
+		length -= (length > 0);
+		p++;
+	    }
+	    forbidNone = 1;
+#if COMPAT
+	    preferBrace = 1;
+#endif /* COMPAT */
+	    break;
+	case '\0':	/* TYPE_SUBS */
+	    if (length == -1) {
+		goto endOfString;
+	    }
+	    /* TODO: Panic on improper encoding? */
+	    break;
+	}
+      }
+	length -= (length > 0);
+	p++;
+    }
+
+  endOfString:
+    if (nestingLevel != 0) {
+	/*
+	 * Unbalanced braces!  Cannot format with brace quoting.
+	 */
+
+	requireEscape = 1;
+    }
+
+    /*
+     * We need at least as many bytes as are in the element value...
+     */
+
+    bytesNeeded = p - src;
+
+    if (requireEscape) {
+	/*
+	 * We must use escape sequences.  Add all the extra bytes needed to
+	 * have room to create them.
+	 */
+
+	bytesNeeded += extra;
+
+	/*
+	 * Make room to escape leading #, if needed.
+	 */
+
+	if ((*src == '#') && !(*flagPtr & TCL_DONT_QUOTE_HASH)) {
+	    bytesNeeded++;
+	}
+	*flagPtr = CONVERT_ESCAPE;
+	goto overflowCheck;
+    }
+    if (*flagPtr & CONVERT_ANY) {
+	/*
+	 * The caller has not let us know what flags it will pass to
+	 * TclConvertElement() so compute the max size we might need for any
+	 * possible choice.  Normally the formatting using escape sequences is
+	 * the longer one, and a minimum "extra" value of 2 makes sure we
+	 * don't request too small a buffer in those edge cases where that's
+	 * not true.
+	 */
+
+	if (extra < 2) {
+	    extra = 2;
+	}
+	*flagPtr &= ~CONVERT_ANY;
+	*flagPtr |= TCL_DONT_USE_BRACES;
+    }
+    if (forbidNone) {
+	/*
+	 * We must request some form of quoting of escaping...
+	 */
+
+#if COMPAT
+	if (preferEscape && !preferBrace) {
+	    /*
+	     * If we are quoting solely due to ] or internal " characters use
+	     * the CONVERT_MASK mode where we escape all special characters
+	     * except for braces. "extra" counted space needed to escape
+	     * braces too, so substract "braceCount" to get our actual needs.
+	     */
+
+	    bytesNeeded += (extra - braceCount);
+	    /* Make room to escape leading #, if needed. */
+	    if ((*src == '#') && !(*flagPtr & TCL_DONT_QUOTE_HASH)) {
+		bytesNeeded++;
+	    }
+
+	    /*
+	     * If the caller reports it will direct TclConvertElement() to
+	     * use full escapes on the element, add back the bytes needed to
+	     * escape the braces.
+	     */
+
+	    if (*flagPtr & TCL_DONT_USE_BRACES) {
+		bytesNeeded += braceCount;
+	    }
+	    *flagPtr = CONVERT_MASK;
+	    goto overflowCheck;
+	}
+#endif /* COMPAT */
+	if (*flagPtr & TCL_DONT_USE_BRACES) {
+	    /*
+	     * If the caller reports it will direct TclConvertElement() to
+	     * use escapes, add the extra bytes needed to have room for them.
+	     */
+
+	    bytesNeeded += extra;
+
+	    /*
+	     * Make room to escape leading #, if needed.
+	     */
+
+	    if ((*src == '#') && !(*flagPtr & TCL_DONT_QUOTE_HASH)) {
+		bytesNeeded++;
+	    }
+	} else {
+	    /*
+	     * Add 2 bytes for room for the enclosing braces.
+	     */
+
+	    bytesNeeded += 2;
+	}
+	*flagPtr = CONVERT_BRACE;
+	goto overflowCheck;
+    }
+
+    /*
+     * So far, no need to quote or escape anything.
+     */
+
+    if ((*src == '#') && !(*flagPtr & TCL_DONT_QUOTE_HASH)) {
+	/*
+	 * If we need to quote a leading #, make room to enclose in braces.
+	 */
+
+	bytesNeeded += 2;
+    }
+    *flagPtr = CONVERT_NONE;
+
+  overflowCheck:
+    if (bytesNeeded < 0) {
+	Tcl_Panic("TclScanElement: string length overflow");
+    }
+    return bytesNeeded;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_ConvertElement --
+ *
+ *	This is a companion function to Tcl_ScanElement. Given the information
+ *	produced by Tcl_ScanElement, this function converts a string to a list
+ *	element equal to that string.
+ *
+ * Results:
+ *	Information is copied to *dst in the form of a list element identical
+ *	to src (i.e. if Tcl_SplitList is applied to dst it will produce a
+ *	string identical to src). The return value is a count of the number of
+ *	characters copied (not including the terminating NULL character).
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_ConvertElement(
+    register const char *src,	/* Source information for list element. */
+    register char *dst,		/* Place to put list-ified element. */
+    register int flags)		/* Flags produced by Tcl_ScanElement. */
+{
+    return Tcl_ConvertCountedElement(src, -1, dst, flags);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_ConvertCountedElement --
+ *
+ *	This is a companion function to Tcl_ScanCountedElement. Given the
+ *	information produced by Tcl_ScanCountedElement, this function converts
+ *	a string to a list element equal to that string.
+ *
+ * Results:
+ *	Information is copied to *dst in the form of a list element identical
+ *	to src (i.e. if Tcl_SplitList is applied to dst it will produce a
+ *	string identical to src). The return value is a count of the number of
+ *	characters copied (not including the terminating NULL character).
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_ConvertCountedElement(
+    register const char *src,	/* Source information for list element. */
+    int length,			/* Number of bytes in src, or -1. */
+    char *dst,			/* Place to put list-ified element. */
+    int flags)			/* Flags produced by Tcl_ScanElement. */
+{
+    int numBytes = TclConvertElement(src, length, dst, flags);
+    dst[numBytes] = '\0';
+    return numBytes;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclConvertElement --
+ *
+ *	This is a companion function to TclScanElement. Given the information
+ *	produced by TclScanElement, this function converts a string to a list
+ *	element equal to that string.
+ *
+ * Results:
+ *	Information is copied to *dst in the form of a list element identical
+ *	to src (i.e. if Tcl_SplitList is applied to dst it will produce a
+ *	string identical to src). The return value is a count of the number of
+ *	characters copied (not including the terminating NULL character).
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclConvertElement(
+    register const char *src,	/* Source information for list element. */
+    int length,			/* Number of bytes in src, or -1. */
+    char *dst,			/* Place to put list-ified element. */
+    int flags)			/* Flags produced by Tcl_ScanElement. */
+{
+    int conversion = flags & CONVERT_MASK;
+    char *p = dst;
+
+    /*
+     * Let the caller demand we use escape sequences rather than braces.
+     */
+
+    if ((flags & TCL_DONT_USE_BRACES) && (conversion & CONVERT_BRACE)) {
+	conversion = CONVERT_ESCAPE;
+    }
+
+    /*
+     * No matter what the caller demands, empty string must be braced!
+     */
+
+    if ((src == NULL) || (length == 0) || (*src == '\0' && length == -1)) {
+	src = tclEmptyStringRep;
+	length = 0;
+	conversion = CONVERT_BRACE;
+    }
+
+    /*
+     * Escape leading hash as needed and requested.
+     */
+
+    if ((*src == '#') && !(flags & TCL_DONT_QUOTE_HASH)) {
+	if (conversion == CONVERT_ESCAPE) {
+	    p[0] = '\\';
+	    p[1] = '#';
+	    p += 2;
+	    src++;
+	    length -= (length > 0);
+	} else {
+	    conversion = CONVERT_BRACE;
+	}
+    }
+
+    /*
+     * No escape or quoting needed.  Copy the literal string value.
+     */
+
+    if (conversion == CONVERT_NONE) {
+	if (length == -1) {
+	    /* TODO: INT_MAX overflow? */
+	    while (*src) {
+		*p++ = *src++;
+	    }
+	    return p - dst;
+	} else {
+	    memcpy(dst, src, length);
+	    return length;
+	}
+    }
+
+    /*
+     * Formatted string is original string enclosed in braces.
+     */
+
+    if (conversion == CONVERT_BRACE) {
+	*p = '{';
+	p++;
+	if (length == -1) {
+	    /* TODO: INT_MAX overflow? */
+	    while (*src) {
+		*p++ = *src++;
+	    }
+	} else {
+	    memcpy(p, src, length);
+	    p += length;
+	}
+	*p = '}';
+	p++;
+	return p - dst;
+    }
+
+    /* conversion == CONVERT_ESCAPE or CONVERT_MASK */
+
+    /*
+     * Formatted string is original string converted to escape sequences.
+     */
+
+    for ( ; length; src++, length -= (length > 0)) {
+	switch (*src) {
+	case ']':
+	case '[':
+	case '$':
+	case ';':
+	case ' ':
+	case '\\':
+	case '"':
+	    *p = '\\';
+	    p++;
+	    break;
+	case '{':
+	case '}':
+#if COMPAT
+	    if (conversion == CONVERT_ESCAPE)
+#endif /* COMPAT */
+	    {
+		*p = '\\';
+		p++;
+	    }
+	    break;
+	case '\f':
+	    *p = '\\';
+	    p++;
+	    *p = 'f';
+	    p++;
+	    continue;
+	case '\n':
+	    *p = '\\';
+	    p++;
+	    *p = 'n';
+	    p++;
+	    continue;
+	case '\r':
+	    *p = '\\';
+	    p++;
+	    *p = 'r';
+	    p++;
+	    continue;
+	case '\t':
+	    *p = '\\';
+	    p++;
+	    *p = 't';
+	    p++;
+	    continue;
+	case '\v':
+	    *p = '\\';
+	    p++;
+	    *p = 'v';
+	    p++;
+	    continue;
+	case '\0':
+	    if (length == -1) {
+		return p - dst;
+	    }
+
+	    /*
+	     * If we reach this point, there's an embedded NULL in the string
+	     * range being processed, which should not happen when the
+	     * encoding rules for Tcl strings are properly followed.  If the
+	     * day ever comes when we stop tolerating such things, this is
+	     * where to put the Tcl_Panic().
+	     */
+
+	    break;
+	}
+	*p = *src;
+	p++;
+    }
+    return p - dst;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_Merge --
+ *
+ *	Given a collection of strings, merge them together into a single
+ *	string that has proper Tcl list structured (i.e. Tcl_SplitList may be
+ *	used to retrieve strings equal to the original elements, and Tcl_Eval
+ *	will parse the string back into its original elements).
+ *
+ * Results:
+ *	The return value is the address of a dynamically-allocated string
+ *	containing the merged list.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+char *
+Tcl_Merge(
+    int argc,			/* How many strings to merge. */
+    const char *const *argv)	/* Array of string values. */
+{
+#define LOCAL_SIZE 20
+    int localFlags[LOCAL_SIZE], *flagPtr = NULL;
+    int i, bytesNeeded = 0;
+    char *result, *dst;
+    const int maxFlags = UINT_MAX / sizeof(int);
+
+    /*
+     * Handle empty list case first, so logic of the general case can be
+     * simpler.
+     */
+
+    if (argc == 0) {
+	result = ckalloc(1);
+	result[0] = '\0';
+	return result;
+    }
+
+    /*
+     * Pass 1: estimate space, gather flags.
+     */
+
+    if (argc <= LOCAL_SIZE) {
+	flagPtr = localFlags;
+    } else if (argc > maxFlags) {
+	/*
+	 * We cannot allocate a large enough flag array to format this list in
+	 * one pass.  We could imagine converting this routine to a multi-pass
+	 * implementation, but for sizeof(int) == 4, the limit is a max of
+	 * 2^30 list elements and since each element is at least one byte
+	 * formatted, and requires one byte space between it and the next one,
+	 * that a minimum space requirement of 2^31 bytes, which is already
+	 * INT_MAX. If we tried to format a list of > maxFlags elements, we're
+	 * just going to overflow the size limits on the formatted string
+	 * anyway, so just issue that same panic early.
+	 */
+
+	Tcl_Panic("max size for a Tcl value (%d bytes) exceeded", INT_MAX);
+    } else {
+	flagPtr = ckalloc(argc * sizeof(int));
+    }
+    for (i = 0; i < argc; i++) {
+	flagPtr[i] = ( i ? TCL_DONT_QUOTE_HASH : 0 );
+	bytesNeeded += TclScanElement(argv[i], -1, &flagPtr[i]);
+	if (bytesNeeded < 0) {
+	    Tcl_Panic("max size for a Tcl value (%d bytes) exceeded", INT_MAX);
+	}
+    }
+    if (bytesNeeded > INT_MAX - argc + 1) {
+	Tcl_Panic("max size for a Tcl value (%d bytes) exceeded", INT_MAX);
+    }
+    bytesNeeded += argc;
+
+    /*
+     * Pass two: copy into the result area.
+     */
+
+    result = ckalloc(bytesNeeded);
+    dst = result;
+    for (i = 0; i < argc; i++) {
+	flagPtr[i] |= ( i ? TCL_DONT_QUOTE_HASH : 0 );
+	dst += TclConvertElement(argv[i], -1, dst, flagPtr[i]);
+	*dst = ' ';
+	dst++;
+    }
+    dst[-1] = 0;
+
+    if (flagPtr != localFlags) {
+	ckfree(flagPtr);
+    }
+    return result;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_Backslash --
+ *
+ *	Figure out how to handle a backslash sequence.
+ *
+ * Results:
+ *	The return value is the character that should be substituted in place
+ *	of the backslash sequence that starts at src. If readPtr isn't NULL
+ *	then it is filled in with a count of the number of characters in the
+ *	backslash sequence.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+char
+Tcl_Backslash(
+    const char *src,		/* Points to the backslash character of a
+				 * backslash sequence. */
+    int *readPtr)		/* Fill in with number of characters read from
+				 * src, unless NULL. */
+{
+    char buf[TCL_UTF_MAX];
+    Tcl_UniChar ch;
+
+    Tcl_UtfBackslash(src, readPtr, buf);
+    TclUtfToUniChar(buf, &ch);
+    return (char) ch;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclTrimRight --
+ *
+ *	Takes two counted strings in the Tcl encoding which must both be null
+ *	terminated. Conceptually trims from the right side of the first string
+ *	all characters found in the second string.
+ *
+ * Results:
+ *	The number of bytes to be removed from the end of the string.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclTrimRight(
+    const char *bytes,		/* String to be trimmed... */
+    int numBytes,		/* ...and its length in bytes */
+    const char *trim,		/* String of trim characters... */
+    int numTrim)		/* ...and its length in bytes */
+{
+    const char *p = bytes + numBytes;
+    int pInc;
+
+    if ((bytes[numBytes] != '\0') || (trim[numTrim] != '\0')) {
+	Tcl_Panic("TclTrimRight works only on null-terminated strings");
+    }
+
+    /*
+     * Empty strings -> nothing to do.
+     */
+
+    if ((numBytes == 0) || (numTrim == 0)) {
+	return 0;
+    }
+
+    /*
+     * Outer loop: iterate over string to be trimmed.
+     */
+
+    do {
+	Tcl_UniChar ch1;
+	const char *q = trim;
+	int bytesLeft = numTrim;
+
+	p = Tcl_UtfPrev(p, bytes);
+ 	pInc = TclUtfToUniChar(p, &ch1);
+
+	/*
+	 * Inner loop: scan trim string for match to current character.
+	 */
+
+	do {
+	    Tcl_UniChar ch2;
+	    int qInc = TclUtfToUniChar(q, &ch2);
+
+	    if (ch1 == ch2) {
+		break;
+	    }
+
+	    q += qInc;
+	    bytesLeft -= qInc;
+	} while (bytesLeft);
+
+	if (bytesLeft == 0) {
+	    /*
+	     * No match; trim task done; *p is last non-trimmed char.
+	     */
+
+	    p += pInc;
+	    break;
+	}
+    } while (p > bytes);
+
+    return numBytes - (p - bytes);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclTrimLeft --
+ *
+ *	Takes two counted strings in the Tcl encoding which must both be null
+ *	terminated. Conceptually trims from the left side of the first string
+ *	all characters found in the second string.
+ *
+ * Results:
+ *	The number of bytes to be removed from the start of the string.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclTrimLeft(
+    const char *bytes,		/* String to be trimmed... */
+    int numBytes,		/* ...and its length in bytes */
+    const char *trim,		/* String of trim characters... */
+    int numTrim)		/* ...and its length in bytes */
+{
+    const char *p = bytes;
+
+    if ((bytes[numBytes] != '\0') || (trim[numTrim] != '\0')) {
+	Tcl_Panic("TclTrimLeft works only on null-terminated strings");
+    }
+
+    /*
+     * Empty strings -> nothing to do.
+     */
+
+    if ((numBytes == 0) || (numTrim == 0)) {
+	return 0;
+    }
+
+    /*
+     * Outer loop: iterate over string to be trimmed.
+     */
+
+    do {
+	Tcl_UniChar ch1;
+	int pInc = TclUtfToUniChar(p, &ch1);
+	const char *q = trim;
+	int bytesLeft = numTrim;
+
+	/*
+	 * Inner loop: scan trim string for match to current character.
+	 */
+
+	do {
+	    Tcl_UniChar ch2;
+	    int qInc = TclUtfToUniChar(q, &ch2);
+
+	    if (ch1 == ch2) {
+		break;
+	    }
+
+	    q += qInc;
+	    bytesLeft -= qInc;
+	} while (bytesLeft);
+
+	if (bytesLeft == 0) {
+	    /*
+	     * No match; trim task done; *p is first non-trimmed char.
+	     */
+
+	    break;
+	}
+
+	p += pInc;
+	numBytes -= pInc;
+    } while (numBytes);
+
+    return p - bytes;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_Concat --
+ *
+ *	Concatenate a set of strings into a single large string.
+ *
+ * Results:
+ *	The return value is dynamically-allocated string containing a
+ *	concatenation of all the strings in argv, with spaces between the
+ *	original argv elements.
+ *
+ * Side effects:
+ *	Memory is allocated for the result; the caller is responsible for
+ *	freeing the memory.
+ *
+ *----------------------------------------------------------------------
+ */
+
+/* The whitespace characters trimmed during [concat] operations */
+#define CONCAT_WS_SIZE (int) (sizeof(CONCAT_TRIM_SET "") - 1)
+
+char *
+Tcl_Concat(
+    int argc,			/* Number of strings to concatenate. */
+    const char *const *argv)	/* Array of strings to concatenate. */
+{
+    int i, needSpace = 0, bytesNeeded = 0;
+    char *result, *p;
+
+    /*
+     * Dispose of the empty result corner case first to simplify later code.
+     */
+
+    if (argc == 0) {
+	result = (char *) ckalloc(1);
+	result[0] = '\0';
+	return result;
+    }
+
+    /*
+     * First allocate the result buffer at the size required.
+     */
+
+    for (i = 0;  i < argc;  i++) {
+	bytesNeeded += strlen(argv[i]);
+	if (bytesNeeded < 0) {
+	    Tcl_Panic("Tcl_Concat: max size of Tcl value exceeded");
+	}
+    }
+    if (bytesNeeded + argc - 1 < 0) {
+	/*
+	 * Panic test could be tighter, but not going to bother for this
+	 * legacy routine.
+	 */
+
+	Tcl_Panic("Tcl_Concat: max size of Tcl value exceeded");
+    }
+
+    /*
+     * All element bytes + (argc - 1) spaces + 1 terminating NULL.
+     */
+
+    result = ckalloc((unsigned) (bytesNeeded + argc));
+
+    for (p = result, i = 0;  i < argc;  i++) {
+	int trim, elemLength;
+	const char *element;
+
+	element = argv[i];
+	elemLength = strlen(argv[i]);
+
+	/*
+	 * Trim away the leading whitespace.
+	 */
+
+	trim = TclTrimLeft(element, elemLength, CONCAT_TRIM_SET,
+		CONCAT_WS_SIZE);
+	element += trim;
+	elemLength -= trim;
+
+	/*
+	 * Trim away the trailing whitespace. Do not permit trimming to expose
+	 * a final backslash character.
+	 */
+
+	trim = TclTrimRight(element, elemLength, CONCAT_TRIM_SET,
+		CONCAT_WS_SIZE);
+	trim -= trim && (element[elemLength - trim - 1] == '\\');
+	elemLength -= trim;
+
+	/*
+	 * If we're left with empty element after trimming, do nothing.
+	 */
+
+	if (elemLength == 0) {
+	    continue;
+	}
+
+	/*
+	 * Append to the result with space if needed.
+	 */
+
+	if (needSpace) {
+	    *p++ = ' ';
+	}
+	memcpy(p, element, (size_t) elemLength);
+	p += elemLength;
+	needSpace = 1;
+    }
+    *p = '\0';
+    return result;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_ConcatObj --
+ *
+ *	Concatenate the strings from a set of objects into a single string
+ *	object with spaces between the original strings.
+ *
+ * Results:
+ *	The return value is a new string object containing a concatenation of
+ *	the strings in objv. Its ref count is zero.
+ *
+ * Side effects:
+ *	A new object is created.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_Obj *
+Tcl_ConcatObj(
+    int objc,			/* Number of objects to concatenate. */
+    Tcl_Obj *const objv[])	/* Array of objects to concatenate. */
+{
+    int i, elemLength, needSpace = 0, bytesNeeded = 0;
+    const char *element;
+    Tcl_Obj *objPtr, *resPtr;
+
+    /*
+     * Check first to see if all the items are of list type or empty. If so,
+     * we will concat them together as lists, and return a list object. This
+     * is only valid when the lists are in canonical form.
+     */
+
+    for (i = 0;  i < objc;  i++) {
+	int length;
+
+	objPtr = objv[i];
+	if (TclListObjIsCanonical(objPtr)) {
+	    continue;
+	}
+	Tcl_GetStringFromObj(objPtr, &length);
+	if (length > 0) {
+	    break;
+	}
+    }
+    if (i == objc) {
+	resPtr = NULL;
+	for (i = 0;  i < objc;  i++) {
+	    objPtr = objv[i];
+	    if (objPtr->bytes && objPtr->length == 0) {
+		continue;
+	    }
+	    if (resPtr) {
+		if (TCL_OK != Tcl_ListObjAppendList(NULL, resPtr, objPtr)) {
+		    /* Abandon ship! */
+		    Tcl_DecrRefCount(resPtr);
+		    goto slow;
+		}
+	    } else {
+		resPtr = TclListObjCopy(NULL, objPtr);
+	    }
+	}
+	if (!resPtr) {
+	    resPtr = Tcl_NewObj();
+	}
+	return resPtr;
+    }
+
+  slow:
+    /*
+     * Something cannot be determined to be safe, so build the concatenation
+     * the slow way, using the string representations.
+     *
+     * First try to pre-allocate the size required.
+     */
+
+    for (i = 0;  i < objc;  i++) {
+	element = TclGetStringFromObj(objv[i], &elemLength);
+	bytesNeeded += elemLength;
+	if (bytesNeeded < 0) {
+	    break;
+	}
+    }
+
+    /*
+     * Does not matter if this fails, will simply try later to build up the
+     * string with each Append reallocating as needed with the usual string
+     * append algorithm.  When that fails it will report the error.
+     */
+
+    TclNewObj(resPtr);
+    (void) Tcl_AttemptSetObjLength(resPtr, bytesNeeded + objc - 1);
+    Tcl_SetObjLength(resPtr, 0);
+
+    for (i = 0;  i < objc;  i++) {
+	int trim;
+
+	element = TclGetStringFromObj(objv[i], &elemLength);
+
+	/*
+	 * Trim away the leading whitespace.
+	 */
+
+	trim = TclTrimLeft(element, elemLength, CONCAT_TRIM_SET,
+		CONCAT_WS_SIZE);
+	element += trim;
+	elemLength -= trim;
+
+	/*
+	 * Trim away the trailing whitespace. Do not permit trimming to expose
+	 * a final backslash character.
+	 */
+
+	trim = TclTrimRight(element, elemLength, CONCAT_TRIM_SET,
+		CONCAT_WS_SIZE);
+	trim -= trim && (element[elemLength - trim - 1] == '\\');
+	elemLength -= trim;
+
+	/*
+	 * If we're left with empty element after trimming, do nothing.
+	 */
+
+	if (elemLength == 0) {
+	    continue;
+	}
+
+	/*
+	 * Append to the result with space if needed.
+	 */
+
+	if (needSpace) {
+	    Tcl_AppendToObj(resPtr, " ", 1);
+	}
+	Tcl_AppendToObj(resPtr, element, elemLength);
+	needSpace = 1;
+    }
+    return resPtr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_StringMatch --
+ *
+ *	See if a particular string matches a particular pattern.
+ *
+ * Results:
+ *	The return value is 1 if string matches pattern, and 0 otherwise. The
+ *	matching operation permits the following special characters in the
+ *	pattern: *?\[] (see the manual entry for details on what these mean).
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_StringMatch(
+    const char *str,		/* String. */
+    const char *pattern)	/* Pattern, which may contain special
+				 * characters. */
+{
+    return Tcl_StringCaseMatch(str, pattern, 0);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_StringCaseMatch --
+ *
+ *	See if a particular string matches a particular pattern. Allows case
+ *	insensitivity.
+ *
+ * Results:
+ *	The return value is 1 if string matches pattern, and 0 otherwise. The
+ *	matching operation permits the following special characters in the
+ *	pattern: *?\[] (see the manual entry for details on what these mean).
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_StringCaseMatch(
+    const char *str,		/* String. */
+    const char *pattern,	/* Pattern, which may contain special
+				 * characters. */
+    int nocase)			/* 0 for case sensitive, 1 for insensitive */
+{
+    int p, charLen;
+    const char *pstart = pattern;
+    Tcl_UniChar ch1, ch2;
+
+    while (1) {
+	p = *pattern;
+
+	/*
+	 * See if we're at the end of both the pattern and the string. If so,
+	 * we succeeded. If we're at the end of the pattern but not at the end
+	 * of the string, we failed.
+	 */
+
+	if (p == '\0') {
+	    return (*str == '\0');
+	}
+	if ((*str == '\0') && (p != '*')) {
+	    return 0;
+	}
+
+	/*
+	 * Check for a "*" as the next pattern character. It matches any
+	 * substring. We handle this by calling ourselves recursively for each
+	 * postfix of string, until either we match or we reach the end of the
+	 * string.
+	 */
+
+	if (p == '*') {
+	    /*
+	     * Skip all successive *'s in the pattern
+	     */
+
+	    while (*(++pattern) == '*') {}
+	    p = *pattern;
+	    if (p == '\0') {
+		return 1;
+	    }
+
+	    /*
+	     * This is a special case optimization for single-byte utf.
+	     */
+
+	    if (UCHAR(*pattern) < 0x80) {
+		ch2 = (Tcl_UniChar)
+			(nocase ? tolower(UCHAR(*pattern)) : UCHAR(*pattern));
+	    } else {
+		Tcl_UtfToUniChar(pattern, &ch2);
+		if (nocase) {
+		    ch2 = Tcl_UniCharToLower(ch2);
+		}
+	    }
+
+	    while (1) {
+		/*
+		 * Optimization for matching - cruise through the string
+		 * quickly if the next char in the pattern isn't a special
+		 * character
+		 */
+
+		if ((p != '[') && (p != '?') && (p != '\\')) {
+		    if (nocase) {
+			while (*str) {
+			    charLen = TclUtfToUniChar(str, &ch1);
+			    if (ch2==ch1 || ch2==Tcl_UniCharToLower(ch1)) {
+				break;
+			    }
+			    str += charLen;
+			}
+		    } else {
+			/*
+			 * There's no point in trying to make this code
+			 * shorter, as the number of bytes you want to compare
+			 * each time is non-constant.
+			 */
+
+			while (*str) {
+			    charLen = TclUtfToUniChar(str, &ch1);
+			    if (ch2 == ch1) {
+				break;
+			    }
+			    str += charLen;
+			}
+		    }
+		}
+		if (Tcl_StringCaseMatch(str, pattern, nocase)) {
+		    return 1;
+		}
+		if (*str == '\0') {
+		    return 0;
+		}
+		str += TclUtfToUniChar(str, &ch1);
+	    }
+	}
+
+	/*
+	 * Check for a "?" as the next pattern character. It matches any
+	 * single character.
+	 */
+
+	if (p == '?') {
+	    pattern++;
+	    str += TclUtfToUniChar(str, &ch1);
+	    continue;
+	}
+
+	/*
+	 * Check for a "[" as the next pattern character. It is followed by a
+	 * list of characters that are acceptable, or by a range (two
+	 * characters separated by "-").
+	 */
+
+	if (p == '[') {
+	    Tcl_UniChar startChar, endChar;
+
+	    pattern++;
+	    if (UCHAR(*str) < 0x80) {
+		ch1 = (Tcl_UniChar)
+			(nocase ? tolower(UCHAR(*str)) : UCHAR(*str));
+		str++;
+	    } else {
+		str += Tcl_UtfToUniChar(str, &ch1);
+		if (nocase) {
+		    ch1 = Tcl_UniCharToLower(ch1);
+		}
+	    }
+	    while (1) {
+		if ((*pattern == ']') || (*pattern == '\0')) {
+		    return 0;
+		}
+		if (UCHAR(*pattern) < 0x80) {
+		    startChar = (Tcl_UniChar) (nocase
+			    ? tolower(UCHAR(*pattern)) : UCHAR(*pattern));
+		    pattern++;
+		} else {
+		    pattern += Tcl_UtfToUniChar(pattern, &startChar);
+		    if (nocase) {
+			startChar = Tcl_UniCharToLower(startChar);
+		    }
+		}
+		if (*pattern == '-') {
+		    pattern++;
+		    if (*pattern == '\0') {
+			return 0;
+		    }
+		    if (UCHAR(*pattern) < 0x80) {
+			endChar = (Tcl_UniChar) (nocase
+				? tolower(UCHAR(*pattern)) : UCHAR(*pattern));
+			pattern++;
+		    } else {
+			pattern += Tcl_UtfToUniChar(pattern, &endChar);
+			if (nocase) {
+			    endChar = Tcl_UniCharToLower(endChar);
+			}
+		    }
+		    if (((startChar <= ch1) && (ch1 <= endChar))
+			    || ((endChar <= ch1) && (ch1 <= startChar))) {
+			/*
+			 * Matches ranges of form [a-z] or [z-a].
+			 */
+
+			break;
+		    }
+		} else if (startChar == ch1) {
+		    break;
+		}
+	    }
+	    while (*pattern != ']') {
+		if (*pattern == '\0') {
+		    pattern = Tcl_UtfPrev(pattern, pstart);
+		    break;
+		}
+		pattern++;
+	    }
+	    pattern++;
+	    continue;
+	}
+
+	/*
+	 * If the next pattern character is '\', just strip off the '\' so we
+	 * do exact matching on the character that follows.
+	 */
+
+	if (p == '\\') {
+	    pattern++;
+	    if (*pattern == '\0') {
+		return 0;
+	    }
+	}
+
+	/*
+	 * There's no special character. Just make sure that the next bytes of
+	 * each string match.
+	 */
+
+	str += TclUtfToUniChar(str, &ch1);
+	pattern += TclUtfToUniChar(pattern, &ch2);
+	if (nocase) {
+	    if (Tcl_UniCharToLower(ch1) != Tcl_UniCharToLower(ch2)) {
+		return 0;
+	    }
+	} else if (ch1 != ch2) {
+	    return 0;
+	}
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclByteArrayMatch --
+ *
+ *	See if a particular string matches a particular pattern.  Does not
+ *	allow for case insensitivity.
+ *	Parallels tclUtf.c:TclUniCharMatch, adjusted for char* and sans nocase.
+ *
+ * Results:
+ *	The return value is 1 if string matches pattern, and 0 otherwise. The
+ *	matching operation permits the following special characters in the
+ *	pattern: *?\[] (see the manual entry for details on what these mean).
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclByteArrayMatch(
+    const unsigned char *string,/* String. */
+    int strLen,			/* Length of String */
+    const unsigned char *pattern,
+				/* Pattern, which may contain special
+				 * characters. */
+    int ptnLen,			/* Length of Pattern */
+    int flags)
+{
+    const unsigned char *stringEnd, *patternEnd;
+    unsigned char p;
+
+    stringEnd = string + strLen;
+    patternEnd = pattern + ptnLen;
+
+    while (1) {
+	/*
+	 * See if we're at the end of both the pattern and the string. If so,
+	 * we succeeded. If we're at the end of the pattern but not at the end
+	 * of the string, we failed.
+	 */
+
+	if (pattern == patternEnd) {
+	    return (string == stringEnd);
+	}
+	p = *pattern;
+	if ((string == stringEnd) && (p != '*')) {
+	    return 0;
+	}
+
+	/*
+	 * Check for a "*" as the next pattern character. It matches any
+	 * substring. We handle this by skipping all the characters up to the
+	 * next matching one in the pattern, and then calling ourselves
+	 * recursively for each postfix of string, until either we match or we
+	 * reach the end of the string.
+	 */
+
+	if (p == '*') {
+	    /*
+	     * Skip all successive *'s in the pattern.
+	     */
+
+	    while ((++pattern < patternEnd) && (*pattern == '*')) {
+		/* empty body */
+	    }
+	    if (pattern == patternEnd) {
+		return 1;
+	    }
+	    p = *pattern;
+	    while (1) {
+		/*
+		 * Optimization for matching - cruise through the string
+		 * quickly if the next char in the pattern isn't a special
+		 * character.
+		 */
+
+		if ((p != '[') && (p != '?') && (p != '\\')) {
+		    while ((string < stringEnd) && (p != *string)) {
+			string++;
+		    }
+		}
+		if (TclByteArrayMatch(string, stringEnd - string,
+				pattern, patternEnd - pattern, 0)) {
+		    return 1;
+		}
+		if (string == stringEnd) {
+		    return 0;
+		}
+		string++;
+	    }
+	}
+
+	/*
+	 * Check for a "?" as the next pattern character. It matches any
+	 * single character.
+	 */
+
+	if (p == '?') {
+	    pattern++;
+	    string++;
+	    continue;
+	}
+
+	/*
+	 * Check for a "[" as the next pattern character. It is followed by a
+	 * list of characters that are acceptable, or by a range (two
+	 * characters separated by "-").
+	 */
+
+	if (p == '[') {
+	    unsigned char ch1, startChar, endChar;
+
+	    pattern++;
+	    ch1 = *string;
+	    string++;
+	    while (1) {
+		if ((*pattern == ']') || (pattern == patternEnd)) {
+		    return 0;
+		}
+		startChar = *pattern;
+		pattern++;
+		if (*pattern == '-') {
+		    pattern++;
+		    if (pattern == patternEnd) {
+			return 0;
+		    }
+		    endChar = *pattern;
+		    pattern++;
+		    if (((startChar <= ch1) && (ch1 <= endChar))
+			    || ((endChar <= ch1) && (ch1 <= startChar))) {
+			/*
+			 * Matches ranges of form [a-z] or [z-a].
+			 */
+
+			break;
+		    }
+		} else if (startChar == ch1) {
+		    break;
+		}
+	    }
+	    while (*pattern != ']') {
+		if (pattern == patternEnd) {
+		    pattern--;
+		    break;
+		}
+		pattern++;
+	    }
+	    pattern++;
+	    continue;
+	}
+
+	/*
+	 * If the next pattern character is '\', just strip off the '\' so we
+	 * do exact matching on the character that follows.
+	 */
+
+	if (p == '\\') {
+	    if (++pattern == patternEnd) {
+		return 0;
+	    }
+	}
+
+	/*
+	 * There's no special character. Just make sure that the next bytes of
+	 * each string match.
+	 */
+
+	if (*string != *pattern) {
+	    return 0;
+	}
+	string++;
+	pattern++;
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclStringMatchObj --
+ *
+ *	See if a particular string matches a particular pattern. Allows case
+ *	insensitivity. This is the generic multi-type handler for the various
+ *	matching algorithms.
+ *
+ * Results:
+ *	The return value is 1 if string matches pattern, and 0 otherwise. The
+ *	matching operation permits the following special characters in the
+ *	pattern: *?\[] (see the manual entry for details on what these mean).
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclStringMatchObj(
+    Tcl_Obj *strObj,		/* string object. */
+    Tcl_Obj *ptnObj,		/* pattern object. */
+    int flags)			/* Only TCL_MATCH_NOCASE should be passed, or
+				 * 0. */
+{
+    int match, length, plen;
+
+    /*
+     * Promote based on the type of incoming object.
+     * XXX: Currently doesn't take advantage of exact-ness that
+     * XXX: TclReToGlob tells us about
+    trivial = nocase ? 0 : TclMatchIsTrivial(TclGetString(ptnObj));
+     */
+
+    if ((strObj->typePtr == &tclStringType) || (strObj->typePtr == NULL)) {
+	Tcl_UniChar *udata, *uptn;
+
+	udata = Tcl_GetUnicodeFromObj(strObj, &length);
+	uptn  = Tcl_GetUnicodeFromObj(ptnObj, &plen);
+	match = TclUniCharMatch(udata, length, uptn, plen, flags);
+    } else if (TclIsPureByteArray(strObj) && !flags) {
+	unsigned char *data, *ptn;
+
+	data = Tcl_GetByteArrayFromObj(strObj, &length);
+	ptn  = Tcl_GetByteArrayFromObj(ptnObj, &plen);
+	match = TclByteArrayMatch(data, length, ptn, plen, 0);
+    } else {
+	match = Tcl_StringCaseMatch(TclGetString(strObj),
+		TclGetString(ptnObj), flags);
+    }
+    return match;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_DStringInit --
+ *
+ *	Initializes a dynamic string, discarding any previous contents of the
+ *	string (Tcl_DStringFree should have been called already if the dynamic
+ *	string was previously in use).
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The dynamic string is initialized to be empty.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_DStringInit(
+    Tcl_DString *dsPtr)		/* Pointer to structure for dynamic string. */
+{
+    dsPtr->string = dsPtr->staticSpace;
+    dsPtr->length = 0;
+    dsPtr->spaceAvl = TCL_DSTRING_STATIC_SIZE;
+    dsPtr->staticSpace[0] = '\0';
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_DStringAppend --
+ *
+ *	Append more bytes to the current value of a dynamic string.
+ *
+ * Results:
+ *	The return value is a pointer to the dynamic string's new value.
+ *
+ * Side effects:
+ *	Length bytes from "bytes" (or all of "bytes" if length is less than
+ *	zero) are added to the current value of the string. Memory gets
+ *	reallocated if needed to accomodate the string's new size.
+ *
+ *----------------------------------------------------------------------
+ */
+
+char *
+Tcl_DStringAppend(
+    Tcl_DString *dsPtr,		/* Structure describing dynamic string. */
+    const char *bytes,		/* String to append. If length is -1 then this
+				 * must be null-terminated. */
+    int length)			/* Number of bytes from "bytes" to append. If
+				 * < 0, then append all of bytes, up to null
+				 * at end. */
+{
+    int newSize;
+
+    if (length < 0) {
+	length = strlen(bytes);
+    }
+    newSize = length + dsPtr->length;
+
+    /*
+     * Allocate a larger buffer for the string if the current one isn't large
+     * enough. Allocate extra space in the new buffer so that there will be
+     * room to grow before we have to allocate again.
+     */
+
+    if (newSize >= dsPtr->spaceAvl) {
+	dsPtr->spaceAvl = newSize * 2;
+	if (dsPtr->string == dsPtr->staticSpace) {
+	    char *newString = ckalloc(dsPtr->spaceAvl);
+
+	    memcpy(newString, dsPtr->string, (size_t) dsPtr->length);
+	    dsPtr->string = newString;
+	} else {
+	    int offset = -1;
+
+	    /* See [16896d49fd] */
+	    if (bytes >= dsPtr->string
+		    && bytes <= dsPtr->string + dsPtr->length) {
+		offset = bytes - dsPtr->string;
+	    }
+
+	    dsPtr->string = ckrealloc(dsPtr->string, dsPtr->spaceAvl);
+
+	    if (offset >= 0) {
+		bytes = dsPtr->string + offset;
+	    }
+	}
+    }
+
+    /*
+     * Copy the new string into the buffer at the end of the old one.
+     */
+
+    memcpy(dsPtr->string + dsPtr->length, bytes, length);
+    dsPtr->length += length;
+    dsPtr->string[dsPtr->length] = '\0';
+    return dsPtr->string;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclDStringAppendObj, TclDStringAppendDString --
+ *
+ *	Simple wrappers round Tcl_DStringAppend that make it easier to append
+ *	from particular sources of strings.
+ *
+ *----------------------------------------------------------------------
+ */
+
+char *
+TclDStringAppendObj(
+    Tcl_DString *dsPtr,
+    Tcl_Obj *objPtr)
+{
+    int length;
+    char *bytes = Tcl_GetStringFromObj(objPtr, &length);
+
+    return Tcl_DStringAppend(dsPtr, bytes, length);
+}
+
+char *
+TclDStringAppendDString(
+    Tcl_DString *dsPtr,
+    Tcl_DString *toAppendPtr)
+{
+    return Tcl_DStringAppend(dsPtr, Tcl_DStringValue(toAppendPtr),
+	    Tcl_DStringLength(toAppendPtr));
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_DStringAppendElement --
+ *
+ *	Append a list element to the current value of a dynamic string.
+ *
+ * Results:
+ *	The return value is a pointer to the dynamic string's new value.
+ *
+ * Side effects:
+ *	String is reformatted as a list element and added to the current value
+ *	of the string. Memory gets reallocated if needed to accomodate the
+ *	string's new size.
+ *
+ *----------------------------------------------------------------------
+ */
+
+char *
+Tcl_DStringAppendElement(
+    Tcl_DString *dsPtr,		/* Structure describing dynamic string. */
+    const char *element)	/* String to append. Must be
+				 * null-terminated. */
+{
+    char *dst = dsPtr->string + dsPtr->length;
+    int needSpace = TclNeedSpace(dsPtr->string, dst);
+    int flags = needSpace ? TCL_DONT_QUOTE_HASH : 0;
+    int newSize = dsPtr->length + needSpace
+	    + TclScanElement(element, -1, &flags);
+
+    /*
+     * Allocate a larger buffer for the string if the current one isn't large
+     * enough. Allocate extra space in the new buffer so that there will be
+     * room to grow before we have to allocate again. SPECIAL NOTE: must use
+     * memcpy, not strcpy, to copy the string to a larger buffer, since there
+     * may be embedded NULLs in the string in some cases.
+     */
+
+    if (newSize >= dsPtr->spaceAvl) {
+	dsPtr->spaceAvl = newSize * 2;
+	if (dsPtr->string == dsPtr->staticSpace) {
+	    char *newString = ckalloc(dsPtr->spaceAvl);
+
+	    memcpy(newString, dsPtr->string, (size_t) dsPtr->length);
+	    dsPtr->string = newString;
+	} else {
+	    int offset = -1;
+
+	    /* See [16896d49fd] */
+	    if (element >= dsPtr->string
+		    && element <= dsPtr->string + dsPtr->length) {
+		offset = element - dsPtr->string;
+	    }
+
+	    dsPtr->string = ckrealloc(dsPtr->string, dsPtr->spaceAvl);
+
+	    if (offset >= 0) {
+		element = dsPtr->string + offset;
+	    }
+	}
+	dst = dsPtr->string + dsPtr->length;
+    }
+
+    /*
+     * Convert the new string to a list element and copy it into the buffer at
+     * the end, with a space, if needed.
+     */
+
+    if (needSpace) {
+	*dst = ' ';
+	dst++;
+	dsPtr->length++;
+
+	/*
+	 * If we need a space to separate this element from preceding stuff,
+	 * then this element will not lead a list, and need not have it's
+	 * leading '#' quoted.
+	 */
+
+	flags |= TCL_DONT_QUOTE_HASH;
+    }
+    dsPtr->length += TclConvertElement(element, -1, dst, flags);
+    dsPtr->string[dsPtr->length] = '\0';
+    return dsPtr->string;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_DStringSetLength --
+ *
+ *	Change the length of a dynamic string. This can cause the string to
+ *	either grow or shrink, depending on the value of length.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The length of dsPtr is changed to length and a null byte is stored at
+ *	that position in the string. If length is larger than the space
+ *	allocated for dsPtr, then a panic occurs.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_DStringSetLength(
+    Tcl_DString *dsPtr,		/* Structure describing dynamic string. */
+    int length)			/* New length for dynamic string. */
+{
+    int newsize;
+
+    if (length < 0) {
+	length = 0;
+    }
+    if (length >= dsPtr->spaceAvl) {
+	/*
+	 * There are two interesting cases here. In the first case, the user
+	 * may be trying to allocate a large buffer of a specific size. It
+	 * would be wasteful to overallocate that buffer, so we just allocate
+	 * enough for the requested size plus the trailing null byte. In the
+	 * second case, we are growing the buffer incrementally, so we need
+	 * behavior similar to Tcl_DStringAppend. The requested length will
+	 * usually be a small delta above the current spaceAvl, so we'll end
+	 * up doubling the old size. This won't grow the buffer quite as
+	 * quickly, but it should be close enough.
+	 */
+
+	newsize = dsPtr->spaceAvl * 2;
+	if (length < newsize) {
+	    dsPtr->spaceAvl = newsize;
+	} else {
+	    dsPtr->spaceAvl = length + 1;
+	}
+	if (dsPtr->string == dsPtr->staticSpace) {
+	    char *newString = ckalloc(dsPtr->spaceAvl);
+
+	    memcpy(newString, dsPtr->string, (size_t) dsPtr->length);
+	    dsPtr->string = newString;
+	} else {
+	    dsPtr->string = ckrealloc(dsPtr->string, dsPtr->spaceAvl);
+	}
+    }
+    dsPtr->length = length;
+    dsPtr->string[length] = 0;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_DStringFree --
+ *
+ *	Frees up any memory allocated for the dynamic string and reinitializes
+ *	the string to an empty state.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The previous contents of the dynamic string are lost, and the new
+ *	value is an empty string.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_DStringFree(
+    Tcl_DString *dsPtr)		/* Structure describing dynamic string. */
+{
+    if (dsPtr->string != dsPtr->staticSpace) {
+	ckfree(dsPtr->string);
+    }
+    dsPtr->string = dsPtr->staticSpace;
+    dsPtr->length = 0;
+    dsPtr->spaceAvl = TCL_DSTRING_STATIC_SIZE;
+    dsPtr->staticSpace[0] = '\0';
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_DStringResult --
+ *
+ *	This function moves the value of a dynamic string into an interpreter
+ *	as its string result. Afterwards, the dynamic string is reset to an
+ *	empty string.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The string is "moved" to interp's result, and any existing string
+ *	result for interp is freed. dsPtr is reinitialized to an empty string.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_DStringResult(
+    Tcl_Interp *interp,		/* Interpreter whose result is to be reset. */
+    Tcl_DString *dsPtr)		/* Dynamic string that is to become the
+				 * result of interp. */
+{
+    Tcl_ResetResult(interp);
+    Tcl_SetObjResult(interp, TclDStringToObj(dsPtr));
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_DStringGetResult --
+ *
+ *	This function moves an interpreter's result into a dynamic string.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The interpreter's string result is cleared, and the previous contents
+ *	of dsPtr are freed.
+ *
+ *	If the string result is empty, the object result is moved to the
+ *	string result, then the object result is reset.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_DStringGetResult(
+    Tcl_Interp *interp,		/* Interpreter whose result is to be reset. */
+    Tcl_DString *dsPtr)		/* Dynamic string that is to become the result
+				 * of interp. */
+{
+    Interp *iPtr = (Interp *) interp;
+
+    if (dsPtr->string != dsPtr->staticSpace) {
+	ckfree(dsPtr->string);
+    }
+
+    /*
+     * Do more efficient transfer when we know the result is a Tcl_Obj. When
+     * there's no st`ring result, we only have to deal with two cases:
+     *
+     *  1. When the string rep is the empty string, when we don't copy but
+     *     instead use the staticSpace in the DString to hold an empty string.
+
+     *  2. When the string rep is not there or there's a real string rep, when
+     *     we use Tcl_GetString to fetch (or generate) the string rep - which
+     *     we know to have been allocated with ckalloc() - and use it to
+     *     populate the DString space. Then, we free the internal rep. and set
+     *     the object's string representation back to the canonical empty
+     *     string.
+     */
+
+    if (!iPtr->result[0] && iPtr->objResultPtr
+	    && !Tcl_IsShared(iPtr->objResultPtr)) {
+	if (iPtr->objResultPtr->bytes == tclEmptyStringRep) {
+	    dsPtr->string = dsPtr->staticSpace;
+	    dsPtr->string[0] = 0;
+	    dsPtr->length = 0;
+	    dsPtr->spaceAvl = TCL_DSTRING_STATIC_SIZE;
+	} else {
+	    dsPtr->string = Tcl_GetString(iPtr->objResultPtr);
+	    dsPtr->length = iPtr->objResultPtr->length;
+	    dsPtr->spaceAvl = dsPtr->length + 1;
+	    TclFreeIntRep(iPtr->objResultPtr);
+	    iPtr->objResultPtr->bytes = tclEmptyStringRep;
+	    iPtr->objResultPtr->length = 0;
+	}
+	return;
+    }
+
+    /*
+     * If the string result is empty, move the object result to the string
+     * result, then reset the object result.
+     */
+
+    (void) Tcl_GetStringResult(interp);
+
+    dsPtr->length = strlen(iPtr->result);
+    if (iPtr->freeProc != NULL) {
+	if (iPtr->freeProc == TCL_DYNAMIC) {
+	    dsPtr->string = iPtr->result;
+	    dsPtr->spaceAvl = dsPtr->length+1;
+	} else {
+	    dsPtr->string = ckalloc(dsPtr->length+1);
+	    memcpy(dsPtr->string, iPtr->result, (unsigned) dsPtr->length+1);
+	    iPtr->freeProc(iPtr->result);
+	}
+	dsPtr->spaceAvl = dsPtr->length+1;
+	iPtr->freeProc = NULL;
+    } else {
+	if (dsPtr->length < TCL_DSTRING_STATIC_SIZE) {
+	    dsPtr->string = dsPtr->staticSpace;
+	    dsPtr->spaceAvl = TCL_DSTRING_STATIC_SIZE;
+	} else {
+	    dsPtr->string = ckalloc(dsPtr->length+1);
+	    dsPtr->spaceAvl = dsPtr->length + 1;
+	}
+	memcpy(dsPtr->string, iPtr->result, (unsigned) dsPtr->length+1);
+    }
+
+    iPtr->result = iPtr->resultSpace;
+    iPtr->resultSpace[0] = 0;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclDStringToObj --
+ *
+ *	This function moves a dynamic string's contents to a new Tcl_Obj. Be
+ *	aware that this function does *not* check that the encoding of the
+ *	contents of the dynamic string is correct; this is the caller's
+ *	responsibility to enforce.
+ *
+ * Results:
+ *	The newly-allocated untyped (i.e., typePtr==NULL) Tcl_Obj with a
+ *	reference count of zero.
+ *
+ * Side effects:
+ *	The string is "moved" to the object. dsPtr is reinitialized to an
+ *	empty string; it does not need to be Tcl_DStringFree'd after this if
+ *	not used further.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_Obj *
+TclDStringToObj(
+    Tcl_DString *dsPtr)
+{
+    Tcl_Obj *result;
+
+    if (dsPtr->string == dsPtr->staticSpace) {
+	if (dsPtr->length == 0) {
+	    TclNewObj(result);
+	} else {
+	    /*
+	     * Static buffer, so must copy.
+	     */
+
+	    TclNewStringObj(result, dsPtr->string, dsPtr->length);
+	}
+    } else {
+	/*
+	 * Dynamic buffer, so transfer ownership and reset.
+	 */
+
+	TclNewObj(result);
+	result->bytes = dsPtr->string;
+	result->length = dsPtr->length;
+    }
+
+    /*
+     * Re-establish the DString as empty with no buffer allocated.
+     */
+
+    dsPtr->string = dsPtr->staticSpace;
+    dsPtr->spaceAvl = TCL_DSTRING_STATIC_SIZE;
+    dsPtr->length = 0;
+    dsPtr->staticSpace[0] = '\0';
+
+    return result;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_DStringStartSublist --
+ *
+ *	This function adds the necessary information to a dynamic string
+ *	(e.g. " {") to start a sublist. Future element appends will be in the
+ *	sublist rather than the main list.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Characters get added to the dynamic string.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_DStringStartSublist(
+    Tcl_DString *dsPtr)		/* Dynamic string. */
+{
+    if (TclNeedSpace(dsPtr->string, dsPtr->string + dsPtr->length)) {
+	TclDStringAppendLiteral(dsPtr, " {");
+    } else {
+	TclDStringAppendLiteral(dsPtr, "{");
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_DStringEndSublist --
+ *
+ *	This function adds the necessary characters to a dynamic string to end
+ *	a sublist (e.g. "}"). Future element appends will be in the enclosing
+ *	(sub)list rather than the current sublist.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_DStringEndSublist(
+    Tcl_DString *dsPtr)		/* Dynamic string. */
+{
+    TclDStringAppendLiteral(dsPtr, "}");
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_PrintDouble --
+ *
+ *	Given a floating-point value, this function converts it to an ASCII
+ *	string using.
+ *
+ * Results:
+ *	The ASCII equivalent of "value" is written at "dst". It is written
+ *	using the current precision, and it is guaranteed to contain a decimal
+ *	point or exponent, so that it looks like a floating-point value and
+ *	not an integer.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_PrintDouble(
+    Tcl_Interp *interp,		/* Interpreter whose tcl_precision variable
+				 * used to be used to control printing. It's
+				 * ignored now. */
+    double value,		/* Value to print as string. */
+    char *dst)			/* Where to store converted value; must have
+				 * at least TCL_DOUBLE_SPACE characters. */
+{
+    char *p, c;
+    int exponent;
+    int signum;
+    char *digits;
+    char *end;
+    int *precisionPtr = Tcl_GetThreadData(&precisionKey, (int) sizeof(int));
+
+    /*
+     * Handle NaN.
+     */
+
+    if (TclIsNaN(value)) {
+	TclFormatNaN(value, dst);
+	return;
+    }
+
+    /*
+     * Handle infinities.
+     */
+
+    if (TclIsInfinite(value)) {
+	/*
+	 * Remember to copy the terminating NUL too.
+	 */
+
+	if (value < 0) {
+	    memcpy(dst, "-Inf", 5);
+	} else {
+	    memcpy(dst, "Inf", 4);
+	}
+	return;
+    }
+
+    /*
+     * Ordinary (normal and denormal) values.
+     */
+
+    if (*precisionPtr == 0) {
+	digits = TclDoubleDigits(value, -1, TCL_DD_SHORTEST,
+		&exponent, &signum, &end);
+    } else {
+	/*
+	 * There are at least two possible interpretations for tcl_precision.
+	 *
+	 * The first is, "choose the decimal representation having
+	 * $tcl_precision digits of significance that is nearest to the given
+	 * number, breaking ties by rounding to even, and then trimming
+	 * trailing zeros." This gives the greatest possible precision in the
+	 * decimal string, but offers the anomaly that [expr 0.1] will be
+	 * "0.10000000000000001".
+	 *
+	 * The second is "choose the decimal representation having at most
+	 * $tcl_precision digits of significance that is nearest to the given
+	 * number. If no such representation converts exactly to the given
+	 * number, choose the one that is closest, breaking ties by rounding
+	 * to even. If more than one such representation converts exactly to
+	 * the given number, choose the shortest, breaking ties in favour of
+	 * the nearest, breaking remaining ties in favour of the one ending in
+	 * an even digit."
+	 *
+	 * Tcl 8.4 implements the first of these, which gives rise to
+	 * anomalies in formatting:
+	 *
+	 *	% expr 0.1
+	 *	0.10000000000000001
+	 *	% expr 0.01
+	 *	0.01
+	 *	% expr 1e-7
+	 *	9.9999999999999995e-08
+	 *
+	 * For human readability, it appears better to choose the second rule,
+	 * and let [expr 0.1] return 0.1. But for 8.4 compatibility, we prefer
+	 * the first (the recommended zero value for tcl_precision avoids the
+	 * problem entirely).
+	 *
+	 * Uncomment TCL_DD_SHORTEN_FLAG in the next call to prefer the method
+	 * that allows floating point values to be shortened if it can be done
+	 * without loss of precision.
+	 */
+
+	digits = TclDoubleDigits(value, *precisionPtr,
+		TCL_DD_E_FORMAT /* | TCL_DD_SHORTEN_FLAG */,
+		&exponent, &signum, &end);
+    }
+    if (signum) {
+	*dst++ = '-';
+    }
+    p = digits;
+    if (exponent < -4 || exponent > 16) {
+	/*
+	 * E format for numbers < 1e-3 or >= 1e17.
+	 */
+
+	*dst++ = *p++;
+	c = *p;
+	if (c != '\0') {
+	    *dst++ = '.';
+	    while (c != '\0') {
+		*dst++ = c;
+		c = *++p;
+	    }
+	}
+
+	/*
+	 * Tcl 8.4 appears to format with at least a two-digit exponent;
+	 * preserve that behaviour when tcl_precision != 0
+	 */
+
+	if (*precisionPtr == 0) {
+	    sprintf(dst, "e%+d", exponent);
+	} else {
+	    sprintf(dst, "e%+03d", exponent);
+	}
+    } else {
+	/*
+	 * F format for others.
+	 */
+
+	if (exponent < 0) {
+	    *dst++ = '0';
+	}
+	c = *p;
+	while (exponent-- >= 0) {
+	    if (c != '\0') {
+		*dst++ = c;
+		c = *++p;
+	    } else {
+		*dst++ = '0';
+	    }
+	}
+	*dst++ = '.';
+	if (c == '\0') {
+	    *dst++ = '0';
+	} else {
+	    while (++exponent < -1) {
+		*dst++ = '0';
+	    }
+	    while (c != '\0') {
+		*dst++ = c;
+		c = *++p;
+	    }
+	}
+	*dst++ = '\0';
+    }
+    ckfree(digits);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclPrecTraceProc --
+ *
+ *	This function is invoked whenever the variable "tcl_precision" is
+ *	written.
+ *
+ * Results:
+ *	Returns NULL if all went well, or an error message if the new value
+ *	for the variable doesn't make sense.
+ *
+ * Side effects:
+ *	If the new value doesn't make sense then this function undoes the
+ *	effect of the variable modification. Otherwise it modifies the format
+ *	string that's used by Tcl_PrintDouble.
+ *
+ *----------------------------------------------------------------------
+ */
+
+	/* ARGSUSED */
+char *
+TclPrecTraceProc(
+    ClientData clientData,	/* Not used. */
+    Tcl_Interp *interp,		/* Interpreter containing variable. */
+    const char *name1,		/* Name of variable. */
+    const char *name2,		/* Second part of variable name. */
+    int flags)			/* Information about what happened. */
+{
+    Tcl_Obj *value;
+    int prec;
+    int *precisionPtr = Tcl_GetThreadData(&precisionKey, (int) sizeof(int));
+
+    /*
+     * If the variable is unset, then recreate the trace.
+     */
+
+    if (flags & TCL_TRACE_UNSETS) {
+	if ((flags & TCL_TRACE_DESTROYED) && !Tcl_InterpDeleted(interp)) {
+	    Tcl_TraceVar2(interp, name1, name2,
+		    TCL_GLOBAL_ONLY|TCL_TRACE_READS|TCL_TRACE_WRITES
+		    |TCL_TRACE_UNSETS, TclPrecTraceProc, clientData);
+	}
+	return NULL;
+    }
+
+    /*
+     * When the variable is read, reset its value from our shared value. This
+     * is needed in case the variable was modified in some other interpreter
+     * so that this interpreter's value is out of date.
+     */
+
+
+    if (flags & TCL_TRACE_READS) {
+	Tcl_SetVar2Ex(interp, name1, name2, Tcl_NewIntObj(*precisionPtr),
+		flags & TCL_GLOBAL_ONLY);
+	return NULL;
+    }
+
+    /*
+     * The variable is being written. Check the new value and disallow it if
+     * it isn't reasonable or if this is a safe interpreter (we don't want
+     * safe interpreters messing up the precision of other interpreters).
+     */
+
+    if (Tcl_IsSafe(interp)) {
+	return (char *) "can't modify precision from a safe interpreter";
+    }
+    value = Tcl_GetVar2Ex(interp, name1, name2, flags & TCL_GLOBAL_ONLY);
+    if (value == NULL
+	    || Tcl_GetIntFromObj(NULL, value, &prec) != TCL_OK
+	    || prec < 0 || prec > TCL_MAX_PREC) {
+	return (char *) "improper value for precision";
+    }
+    *precisionPtr = prec;
+    return NULL;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclNeedSpace --
+ *
+ *	This function checks to see whether it is appropriate to add a space
+ *	before appending a new list element to an existing string.
+ *
+ * Results:
+ *	The return value is 1 if a space is appropriate, 0 otherwise.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclNeedSpace(
+    const char *start,		/* First character in string. */
+    const char *end)		/* End of string (place where space will be
+				 * added, if appropriate). */
+{
+    /*
+     * A space is needed unless either:
+     * (a) we're at the start of the string, or
+     */
+
+    if (end == start) {
+	return 0;
+    }
+
+    /*
+     * (b) we're at the start of a nested list-element, quoted with an open
+     *	   curly brace; we can be nested arbitrarily deep, so long as the
+     *	   first curly brace starts an element, so backtrack over open curly
+     *	   braces that are trailing characters of the string; and
+     */
+
+    end = Tcl_UtfPrev(end, start);
+    while (*end == '{') {
+	if (end == start) {
+	    return 0;
+	}
+	end = Tcl_UtfPrev(end, start);
+    }
+
+    /*
+     * (c) the trailing character of the string is already a list-element
+     *	   separator (according to TclFindElement); that is, one of these
+     *	   characters:
+     *		\u0009	\t	TAB
+     *		\u000A	\n	NEWLINE
+     *		\u000B	\v	VERTICAL TAB
+     *		\u000C	\f	FORM FEED
+     *		\u000D	\r	CARRIAGE RETURN
+     *		\u0020		SPACE
+     *	   with the condition that the penultimate character is not a
+     *	   backslash.
+     */
+
+    if (*end > 0x20) {
+	/*
+	 * Performance tweak. All ASCII spaces are <= 0x20. So get a quick
+	 * answer for most characters before comparing against all spaces in
+	 * the switch below.
+	 *
+	 * NOTE: Remove this if other Unicode spaces ever get accepted as
+	 * list-element separators.
+	 */
+
+	return 1;
+    }
+    switch (*end) {
+    case ' ':
+    case '\t':
+    case '\n':
+    case '\r':
+    case '\v':
+    case '\f':
+	if ((end == start) || (end[-1] != '\\')) {
+	    return 0;
+	}
+    }
+    return 1;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclFormatInt --
+ *
+ *	This procedure formats an integer into a sequence of decimal digit
+ *	characters in a buffer. If the integer is negative, a minus sign is
+ *	inserted at the start of the buffer. A null character is inserted at
+ *	the end of the formatted characters. It is the caller's responsibility
+ *	to ensure that enough storage is available. This procedure has the
+ *	effect of sprintf(buffer, "%ld", n) but is faster as proven in
+ *	benchmarks.  This is key to UpdateStringOfInt, which is a common path
+ *	for a lot of code (e.g. int-indexed arrays).
+ *
+ * Results:
+ *	An integer representing the number of characters formatted, not
+ *	including the terminating \0.
+ *
+ * Side effects:
+ *	The formatted characters are written into the storage pointer to by
+ *	the "buffer" argument.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclFormatInt(
+    char *buffer,		/* Points to the storage into which the
+				 * formatted characters are written. */
+    long n)			/* The integer to format. */
+{
+    long intVal;
+    int i;
+    int numFormatted, j;
+    const char *digits = "0123456789";
+
+    /*
+     * Check first whether "n" is zero.
+     */
+
+    if (n == 0) {
+	buffer[0] = '0';
+	buffer[1] = 0;
+	return 1;
+    }
+
+    /*
+     * Check whether "n" is the maximum negative value. This is -2^(m-1) for
+     * an m-bit word, and has no positive equivalent; negating it produces the
+     * same value.
+     */
+
+    intVal = -n;			/* [Bug 3390638] Workaround for*/
+    if (n == -n || intVal == n) {	/* broken compiler optimizers. */
+	return sprintf(buffer, "%ld", n);
+    }
+
+    /*
+     * Generate the characters of the result backwards in the buffer.
+     */
+
+    intVal = (n < 0? -n : n);
+    i = 0;
+    buffer[0] = '\0';
+    do {
+	i++;
+	buffer[i] = digits[intVal % 10];
+	intVal = intVal/10;
+    } while (intVal > 0);
+    if (n < 0) {
+	i++;
+	buffer[i] = '-';
+    }
+    numFormatted = i;
+
+    /*
+     * Now reverse the characters.
+     */
+
+    for (j = 0;  j < i;  j++, i--) {
+	char tmp = buffer[i];
+
+	buffer[i] = buffer[j];
+	buffer[j] = tmp;
+    }
+    return numFormatted;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclGetIntForIndex --
+ *
+ *	This function returns an integer corresponding to the list index held
+ *	in a Tcl object. The Tcl object's value is expected to be in the
+ *	format integer([+-]integer)? or the format end([+-]integer)?.
+ *
+ * Results:
+ *	The return value is normally TCL_OK, which means that the index was
+ *	successfully stored into the location referenced by "indexPtr". If the
+ *	Tcl object referenced by "objPtr" has the value "end", the value
+ *	stored is "endValue". If "objPtr"s values is not of one of the
+ *	expected formats, TCL_ERROR is returned and, if "interp" is non-NULL,
+ *	an error message is left in the interpreter's result object.
+ *
+ * Side effects:
+ *	The object referenced by "objPtr" might be converted to an integer,
+ *	wide integer, or end-based-index object.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclGetIntForIndex(
+    Tcl_Interp *interp,		/* Interpreter to use for error reporting. If
+				 * NULL, then no error message is left after
+				 * errors. */
+    Tcl_Obj *objPtr,		/* Points to an object containing either "end"
+				 * or an integer. */
+    int endValue,		/* The value to be stored at "indexPtr" if
+				 * "objPtr" holds "end". */
+    int *indexPtr)		/* Location filled in with an integer
+				 * representing an index. */
+{
+    int length;
+    char *opPtr;
+    const char *bytes;
+
+    if (TclGetIntFromObj(NULL, objPtr, indexPtr) == TCL_OK) {
+	return TCL_OK;
+    }
+
+    if (SetEndOffsetFromAny(NULL, objPtr) == TCL_OK) {
+	/*
+	 * If the object is already an offset from the end of the list, or can
+	 * be converted to one, use it.
+	 */
+
+	*indexPtr = endValue + objPtr->internalRep.longValue;
+	return TCL_OK;
+    }
+
+    bytes = TclGetStringFromObj(objPtr, &length);
+
+    /*
+     * Leading whitespace is acceptable in an index.
+     */
+
+    while (length && TclIsSpaceProc(*bytes)) {
+	bytes++;
+	length--;
+    }
+
+    if (TclParseNumber(NULL, NULL, NULL, bytes, length, (const char **)&opPtr,
+	    TCL_PARSE_INTEGER_ONLY | TCL_PARSE_NO_WHITESPACE) == TCL_OK) {
+	int code, first, second;
+	char savedOp = *opPtr;
+
+	if ((savedOp != '+') && (savedOp != '-')) {
+	    goto parseError;
+	}
+	if (TclIsSpaceProc(opPtr[1])) {
+	    goto parseError;
+	}
+	*opPtr = '\0';
+	code = Tcl_GetInt(interp, bytes, &first);
+	*opPtr = savedOp;
+	if (code == TCL_ERROR) {
+	    goto parseError;
+	}
+	if (TCL_ERROR == Tcl_GetInt(interp, opPtr+1, &second)) {
+	    goto parseError;
+	}
+	if (savedOp == '+') {
+	    *indexPtr = first + second;
+	} else {
+	    *indexPtr = first - second;
+	}
+	return TCL_OK;
+    }
+
+    /*
+     * Report a parse error.
+     */
+
+  parseError:
+    if (interp != NULL) {
+	bytes = Tcl_GetString(objPtr);
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		"bad index \"%s\": must be integer?[+-]integer? or"
+		" end?[+-]integer?", bytes));
+	if (!strncmp(bytes, "end-", 4)) {
+	    bytes += 4;
+	}
+	TclCheckBadOctal(interp, bytes);
+	Tcl_SetErrorCode(interp, "TCL", "VALUE", "INDEX", NULL);
+    }
+
+    return TCL_ERROR;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * UpdateStringOfEndOffset --
+ *
+ *	Update the string rep of a Tcl object holding an "end-offset"
+ *	expression.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Stores a valid string in the object's string rep.
+ *
+ * This function does NOT free any earlier string rep. If it is called on an
+ * object that already has a valid string rep, it will leak memory.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+UpdateStringOfEndOffset(
+    register Tcl_Obj *objPtr)
+{
+    char buffer[TCL_INTEGER_SPACE + 5];
+    register int len = 3;
+
+    memcpy(buffer, "end", 4);
+    if (objPtr->internalRep.longValue != 0) {
+	buffer[len++] = '-';
+	len += TclFormatInt(buffer+len, -(objPtr->internalRep.longValue));
+    }
+    objPtr->bytes = ckalloc((unsigned) len+1);
+    memcpy(objPtr->bytes, buffer, (unsigned) len+1);
+    objPtr->length = len;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * SetEndOffsetFromAny --
+ *
+ *	Look for a string of the form "end[+-]offset" and convert it to an
+ *	internal representation holding the offset.
+ *
+ * Results:
+ *	Returns TCL_OK if ok, TCL_ERROR if the string was badly formed.
+ *
+ * Side effects:
+ *	If interp is not NULL, stores an error message in the interpreter
+ *	result.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+SetEndOffsetFromAny(
+    Tcl_Interp *interp,		/* Tcl interpreter or NULL */
+    Tcl_Obj *objPtr)		/* Pointer to the object to parse */
+{
+    int offset;			/* Offset in the "end-offset" expression */
+    register const char *bytes;	/* String rep of the object */
+    int length;			/* Length of the object's string rep */
+
+    /*
+     * If it's already the right type, we're fine.
+     */
+
+    if (objPtr->typePtr == &tclEndOffsetType) {
+	return TCL_OK;
+    }
+
+    /*
+     * Check for a string rep of the right form.
+     */
+
+    bytes = TclGetStringFromObj(objPtr, &length);
+    if ((*bytes != 'e') || (strncmp(bytes, "end",
+	    (size_t)((length > 3) ? 3 : length)) != 0)) {
+	if (interp != NULL) {
+	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		    "bad index \"%s\": must be end?[+-]integer?", bytes));
+	    Tcl_SetErrorCode(interp, "TCL", "VALUE", "INDEX", NULL);
+	}
+	return TCL_ERROR;
+    }
+
+    /*
+     * Convert the string rep.
+     */
+
+    if (length <= 3) {
+	offset = 0;
+    } else if ((length > 4) && ((bytes[3] == '-') || (bytes[3] == '+'))) {
+	/*
+	 * This is our limited string expression evaluator. Pass everything
+	 * after "end-" to Tcl_GetInt, then reverse for offset.
+	 */
+
+	if (TclIsSpaceProc(bytes[4])) {
+	    goto badIndexFormat;
+	}
+	if (Tcl_GetInt(interp, bytes+4, &offset) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	if (bytes[3] == '-') {
+	    offset = -offset;
+	}
+    } else {
+	/*
+	 * Conversion failed. Report the error.
+	 */
+
+    badIndexFormat:
+	if (interp != NULL) {
+	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		    "bad index \"%s\": must be end?[+-]integer?", bytes));
+	    Tcl_SetErrorCode(interp, "TCL", "VALUE", "INDEX", NULL);
+	}
+	return TCL_ERROR;
+    }
+
+    /*
+     * The conversion succeeded. Free the old internal rep and set the new
+     * one.
+     */
+
+    TclFreeIntRep(objPtr);
+    objPtr->internalRep.longValue = offset;
+    objPtr->typePtr = &tclEndOffsetType;
+
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclCheckBadOctal --
+ *
+ *	This function checks for a bad octal value and appends a meaningful
+ *	error to the interp's result.
+ *
+ * Results:
+ *	1 if the argument was a bad octal, else 0.
+ *
+ * Side effects:
+ *	The interpreter's result is modified.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclCheckBadOctal(
+    Tcl_Interp *interp,		/* Interpreter to use for error reporting. If
+				 * NULL, then no error message is left after
+				 * errors. */
+    const char *value)		/* String to check. */
+{
+    register const char *p = value;
+
+    /*
+     * A frequent mistake is invalid octal values due to an unwanted leading
+     * zero. Try to generate a meaningful error message.
+     */
+
+    while (TclIsSpaceProc(*p)) {
+	p++;
+    }
+    if (*p == '+' || *p == '-') {
+	p++;
+    }
+    if (*p == '0') {
+	if ((p[1] == 'o') || p[1] == 'O') {
+	    p += 2;
+	}
+	while (isdigit(UCHAR(*p))) {	/* INTL: digit. */
+	    p++;
+	}
+	while (TclIsSpaceProc(*p)) {
+	    p++;
+	}
+	if (*p == '\0') {
+	    /*
+	     * Reached end of string.
+	     */
+
+	    if (interp != NULL) {
+		/*
+		 * Don't reset the result here because we want this result to
+		 * be added to an existing error message as extra info.
+		 */
+
+		Tcl_AppendToObj(Tcl_GetObjResult(interp),
+			" (looks like invalid octal number)", -1);
+	    }
+	    return 1;
+	}
+    }
+    return 0;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ClearHash --
+ *
+ *	Remove all the entries in the hash table *tablePtr.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+ClearHash(
+    Tcl_HashTable *tablePtr)
+{
+    Tcl_HashSearch search;
+    Tcl_HashEntry *hPtr;
+
+    for (hPtr = Tcl_FirstHashEntry(tablePtr, &search); hPtr != NULL;
+	    hPtr = Tcl_NextHashEntry(&search)) {
+	Tcl_Obj *objPtr = Tcl_GetHashValue(hPtr);
+
+	Tcl_DecrRefCount(objPtr);
+	Tcl_DeleteHashEntry(hPtr);
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * GetThreadHash --
+ *
+ *	Get a thread-specific (Tcl_HashTable *) associated with a thread data
+ *	key.
+ *
+ * Results:
+ *	The Tcl_HashTable * corresponding to *keyPtr.
+ *
+ * Side effects:
+ *	The first call on a keyPtr in each thread creates a new Tcl_HashTable,
+ *	and registers a thread exit handler to dispose of it.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static Tcl_HashTable *
+GetThreadHash(
+    Tcl_ThreadDataKey *keyPtr)
+{
+    Tcl_HashTable **tablePtrPtr =
+	    Tcl_GetThreadData(keyPtr, sizeof(Tcl_HashTable *));
+
+    if (NULL == *tablePtrPtr) {
+	*tablePtrPtr = ckalloc(sizeof(Tcl_HashTable));
+	Tcl_CreateThreadExitHandler(FreeThreadHash, *tablePtrPtr);
+	Tcl_InitHashTable(*tablePtrPtr, TCL_ONE_WORD_KEYS);
+    }
+    return *tablePtrPtr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * FreeThreadHash --
+ *
+ *	Thread exit handler used by GetThreadHash to dispose of a thread hash
+ *	table.
+ *
+ * Side effects:
+ *	Frees a Tcl_HashTable.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+FreeThreadHash(
+    ClientData clientData)
+{
+    Tcl_HashTable *tablePtr = clientData;
+
+    ClearHash(tablePtr);
+    Tcl_DeleteHashTable(tablePtr);
+    ckfree(tablePtr);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * FreeProcessGlobalValue --
+ *
+ *	Exit handler used by Tcl(Set|Get)ProcessGlobalValue to cleanup a
+ *	ProcessGlobalValue at exit.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+FreeProcessGlobalValue(
+    ClientData clientData)
+{
+    ProcessGlobalValue *pgvPtr = clientData;
+
+    pgvPtr->epoch++;
+    pgvPtr->numBytes = 0;
+    ckfree(pgvPtr->value);
+    pgvPtr->value = NULL;
+    if (pgvPtr->encoding) {
+	Tcl_FreeEncoding(pgvPtr->encoding);
+	pgvPtr->encoding = NULL;
+    }
+    Tcl_MutexFinalize(&pgvPtr->mutex);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclSetProcessGlobalValue --
+ *
+ *	Utility routine to set a global value shared by all threads in the
+ *	process while keeping a thread-local copy as well.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclSetProcessGlobalValue(
+    ProcessGlobalValue *pgvPtr,
+    Tcl_Obj *newValue,
+    Tcl_Encoding encoding)
+{
+    const char *bytes;
+    Tcl_HashTable *cacheMap;
+    Tcl_HashEntry *hPtr;
+    int dummy;
+
+    Tcl_MutexLock(&pgvPtr->mutex);
+
+    /*
+     * Fill the global string value.
+     */
+
+    pgvPtr->epoch++;
+    if (NULL != pgvPtr->value) {
+	ckfree(pgvPtr->value);
+    } else {
+	Tcl_CreateExitHandler(FreeProcessGlobalValue, pgvPtr);
+    }
+    bytes = Tcl_GetStringFromObj(newValue, &pgvPtr->numBytes);
+    pgvPtr->value = ckalloc(pgvPtr->numBytes + 1);
+    memcpy(pgvPtr->value, bytes, (unsigned) pgvPtr->numBytes + 1);
+    if (pgvPtr->encoding) {
+	Tcl_FreeEncoding(pgvPtr->encoding);
+    }
+    pgvPtr->encoding = encoding;
+
+    /*
+     * Fill the local thread copy directly with the Tcl_Obj value to avoid
+     * loss of the intrep. Increment newValue refCount early to handle case
+     * where we set a PGV to itself.
+     */
+
+    Tcl_IncrRefCount(newValue);
+    cacheMap = GetThreadHash(&pgvPtr->key);
+    ClearHash(cacheMap);
+    hPtr = Tcl_CreateHashEntry(cacheMap, INT2PTR(pgvPtr->epoch), &dummy);
+    Tcl_SetHashValue(hPtr, newValue);
+    Tcl_MutexUnlock(&pgvPtr->mutex);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclGetProcessGlobalValue --
+ *
+ *	Retrieve a global value shared among all threads of the process,
+ *	preferring a thread-local copy as long as it remains valid.
+ *
+ * Results:
+ *	Returns a (Tcl_Obj *) that holds a copy of the global value.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_Obj *
+TclGetProcessGlobalValue(
+    ProcessGlobalValue *pgvPtr)
+{
+    Tcl_Obj *value = NULL;
+    Tcl_HashTable *cacheMap;
+    Tcl_HashEntry *hPtr;
+    int epoch = pgvPtr->epoch;
+
+    if (pgvPtr->encoding) {
+	Tcl_Encoding current = Tcl_GetEncoding(NULL, NULL);
+
+	if (pgvPtr->encoding != current) {
+	    /*
+	     * The system encoding has changed since the master string value
+	     * was saved. Convert the master value to be based on the new
+	     * system encoding.
+	     */
+
+	    Tcl_DString native, newValue;
+
+	    Tcl_MutexLock(&pgvPtr->mutex);
+	    pgvPtr->epoch++;
+	    epoch = pgvPtr->epoch;
+	    Tcl_UtfToExternalDString(pgvPtr->encoding, pgvPtr->value,
+		    pgvPtr->numBytes, &native);
+	    Tcl_ExternalToUtfDString(current, Tcl_DStringValue(&native),
+	    Tcl_DStringLength(&native), &newValue);
+	    Tcl_DStringFree(&native);
+	    ckfree(pgvPtr->value);
+	    pgvPtr->value = ckalloc(Tcl_DStringLength(&newValue) + 1);
+	    memcpy(pgvPtr->value, Tcl_DStringValue(&newValue),
+		    (size_t) Tcl_DStringLength(&newValue) + 1);
+	    Tcl_DStringFree(&newValue);
+	    Tcl_FreeEncoding(pgvPtr->encoding);
+	    pgvPtr->encoding = current;
+	    Tcl_MutexUnlock(&pgvPtr->mutex);
+	} else {
+	    Tcl_FreeEncoding(current);
+	}
+    }
+    cacheMap = GetThreadHash(&pgvPtr->key);
+    hPtr = Tcl_FindHashEntry(cacheMap, (char *) INT2PTR(epoch));
+    if (NULL == hPtr) {
+	int dummy;
+
+	/*
+	 * No cache for the current epoch - must be a new one.
+	 *
+	 * First, clear the cacheMap, as anything in it must refer to some
+	 * expired epoch.
+	 */
+
+	ClearHash(cacheMap);
+
+	/*
+	 * If no thread has set the shared value, call the initializer.
+	 */
+
+	Tcl_MutexLock(&pgvPtr->mutex);
+	if ((NULL == pgvPtr->value) && (pgvPtr->proc)) {
+	    pgvPtr->epoch++;
+	    pgvPtr->proc(&pgvPtr->value,&pgvPtr->numBytes,&pgvPtr->encoding);
+	    if (pgvPtr->value == NULL) {
+		Tcl_Panic("PGV Initializer did not initialize");
+	    }
+	    Tcl_CreateExitHandler(FreeProcessGlobalValue, pgvPtr);
+	}
+
+	/*
+	 * Store a copy of the shared value in our epoch-indexed cache.
+	 */
+
+	value = Tcl_NewStringObj(pgvPtr->value, pgvPtr->numBytes);
+	hPtr = Tcl_CreateHashEntry(cacheMap,
+		INT2PTR(pgvPtr->epoch), &dummy);
+	Tcl_MutexUnlock(&pgvPtr->mutex);
+	Tcl_SetHashValue(hPtr, value);
+	Tcl_IncrRefCount(value);
+    }
+    return Tcl_GetHashValue(hPtr);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclSetObjNameOfExecutable --
+ *
+ *	This function stores the absolute pathname of the executable file
+ *	(normally as computed by TclpFindExecutable).
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Stores the executable name.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclSetObjNameOfExecutable(
+    Tcl_Obj *name,
+    Tcl_Encoding encoding)
+{
+    TclSetProcessGlobalValue(&executableName, name, encoding);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclGetObjNameOfExecutable --
+ *
+ *	This function retrieves the absolute pathname of the application in
+ *	which the Tcl library is running, usually as previously stored by
+ *	TclpFindExecutable(). This function call is the C API equivalent to
+ *	the "info nameofexecutable" command.
+ *
+ * Results:
+ *	A pointer to an "fsPath" Tcl_Obj, or to an empty Tcl_Obj if the
+ *	pathname of the application is unknown.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_Obj *
+TclGetObjNameOfExecutable(void)
+{
+    return TclGetProcessGlobalValue(&executableName);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_GetNameOfExecutable --
+ *
+ *	This function retrieves the absolute pathname of the application in
+ *	which the Tcl library is running, and returns it in string form.
+ *
+ *	The returned string belongs to Tcl and should be copied if the caller
+ *	plans to keep it, to guard against it becoming invalid.
+ *
+ * Results:
+ *	A pointer to the internal string or NULL if the internal full path
+ *	name has not been computed or unknown.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+const char *
+Tcl_GetNameOfExecutable(void)
+{
+    int numBytes;
+    const char *bytes =
+	    Tcl_GetStringFromObj(TclGetObjNameOfExecutable(), &numBytes);
+
+    if (numBytes == 0) {
+	return NULL;
+    }
+    return bytes;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclpGetTime --
+ *
+ *	Deprecated synonym for Tcl_GetTime. This function is provided for the
+ *	benefit of extensions written before Tcl_GetTime was exported from the
+ *	library.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Stores current time in the buffer designated by "timePtr"
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclpGetTime(
+    Tcl_Time *timePtr)
+{
+    Tcl_GetTime(timePtr);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclGetPlatform --
+ *
+ *	This is a kludge that allows the test library to get access the
+ *	internal tclPlatform variable.
+ *
+ * Results:
+ *	Returns a pointer to the tclPlatform variable.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+TclPlatformType *
+TclGetPlatform(void)
+{
+    return &tclPlatform;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclReToGlob --
+ *
+ *	Attempt to convert a regular expression to an equivalent glob pattern.
+ *
+ * Results:
+ *	Returns TCL_OK on success, TCL_ERROR on failure. If interp is not
+ *	NULL, an error message is placed in the result. On success, the
+ *	DString will contain an exact equivalent glob pattern. The caller is
+ *	responsible for calling Tcl_DStringFree on success. If exactPtr is not
+ *	NULL, it will be 1 if an exact match qualifies.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclReToGlob(
+    Tcl_Interp *interp,
+    const char *reStr,
+    int reStrLen,
+    Tcl_DString *dsPtr,
+    int *exactPtr,
+    int *quantifiersFoundPtr)
+{
+    int anchorLeft, anchorRight, lastIsStar, numStars;
+    char *dsStr, *dsStrStart;
+    const char *msg, *p, *strEnd, *code;
+
+    strEnd = reStr + reStrLen;
+    Tcl_DStringInit(dsPtr);
+    if (quantifiersFoundPtr != NULL) {
+	*quantifiersFoundPtr = 0;
+    }
+
+    /*
+     * "***=xxx" == "*xxx*", watch for glob-sensitive chars.
+     */
+
+    if ((reStrLen >= 4) && (memcmp("***=", reStr, 4) == 0)) {
+	/*
+	 * At most, the glob pattern has length 2*reStrLen + 2 to backslash
+	 * escape every character and have * at each end.
+	 */
+
+	Tcl_DStringSetLength(dsPtr, reStrLen + 2);
+	dsStr = dsStrStart = Tcl_DStringValue(dsPtr);
+	*dsStr++ = '*';
+	for (p = reStr + 4; p < strEnd; p++) {
+	    switch (*p) {
+	    case '\\': case '*': case '[': case ']': case '?':
+		/* Only add \ where necessary for glob */
+		*dsStr++ = '\\';
+		/* fall through */
+	    default:
+		*dsStr++ = *p;
+		break;
+	    }
+	}
+	*dsStr++ = '*';
+	Tcl_DStringSetLength(dsPtr, dsStr - dsStrStart);
+	if (exactPtr) {
+	    *exactPtr = 0;
+	}
+	return TCL_OK;
+    }
+
+    /*
+     * At most, the glob pattern has length reStrLen + 2 to account for
+     * possible * at each end.
+     */
+
+    Tcl_DStringSetLength(dsPtr, reStrLen + 2);
+    dsStr = dsStrStart = Tcl_DStringValue(dsPtr);
+
+    /*
+     * Check for anchored REs (ie ^foo$), so we can use string equal if
+     * possible. Do not alter the start of str so we can free it correctly.
+     *
+     * Keep track of the last char being an unescaped star to prevent multiple
+     * instances.  Simpler than checking that the last star may be escaped.
+     */
+
+    msg = NULL;
+    code = NULL;
+    p = reStr;
+    anchorRight = 0;
+    lastIsStar = 0;
+    numStars = 0;
+
+    if (*p == '^') {
+	anchorLeft = 1;
+	p++;
+    } else {
+	anchorLeft = 0;
+	*dsStr++ = '*';
+	lastIsStar = 1;
+    }
+
+    for ( ; p < strEnd; p++) {
+	switch (*p) {
+	case '\\':
+	    p++;
+	    switch (*p) {
+	    case 'a':
+		*dsStr++ = '\a';
+		break;
+	    case 'b':
+		*dsStr++ = '\b';
+		break;
+	    case 'f':
+		*dsStr++ = '\f';
+		break;
+	    case 'n':
+		*dsStr++ = '\n';
+		break;
+	    case 'r':
+		*dsStr++ = '\r';
+		break;
+	    case 't':
+		*dsStr++ = '\t';
+		break;
+	    case 'v':
+		*dsStr++ = '\v';
+		break;
+	    case 'B': case '\\':
+		*dsStr++ = '\\';
+		*dsStr++ = '\\';
+		anchorLeft = 0; /* prevent exact match */
+		break;
+	    case '*': case '[': case ']': case '?':
+		/* Only add \ where necessary for glob */
+		*dsStr++ = '\\';
+		anchorLeft = 0; /* prevent exact match */
+		/* fall through */
+	    case '{': case '}': case '(': case ')': case '+':
+	    case '.': case '|': case '^': case '$':
+		*dsStr++ = *p;
+		break;
+	    default:
+		msg = "invalid escape sequence";
+		code = "BADESCAPE";
+		goto invalidGlob;
+	    }
+	    break;
+	case '.':
+	    if (quantifiersFoundPtr != NULL) {
+		*quantifiersFoundPtr = 1;
+	    }
+	    anchorLeft = 0; /* prevent exact match */
+	    if (p+1 < strEnd) {
+		if (p[1] == '*') {
+		    p++;
+		    if (!lastIsStar) {
+			*dsStr++ = '*';
+			lastIsStar = 1;
+			numStars++;
+		    }
+		    continue;
+		} else if (p[1] == '+') {
+		    p++;
+		    *dsStr++ = '?';
+		    *dsStr++ = '*';
+		    lastIsStar = 1;
+		    numStars++;
+		    continue;
+		}
+	    }
+	    *dsStr++ = '?';
+	    break;
+	case '$':
+	    if (p+1 != strEnd) {
+		msg = "$ not anchor";
+		code = "NONANCHOR";
+		goto invalidGlob;
+	    }
+	    anchorRight = 1;
+	    break;
+	case '*': case '+': case '?': case '|': case '^':
+	case '{': case '}': case '(': case ')': case '[': case ']':
+	    msg = "unhandled RE special char";
+	    code = "UNHANDLED";
+	    goto invalidGlob;
+	default:
+	    *dsStr++ = *p;
+	    break;
+	}
+	lastIsStar = 0;
+    }
+    if (numStars > 1) {
+	/*
+	 * Heuristic: if >1 non-anchoring *, the risk is large that glob
+	 * matching is slower than the RE engine, so report invalid.
+	 */
+
+	msg = "excessive recursive glob backtrack potential";
+	code = "OVERCOMPLEX";
+	goto invalidGlob;
+    }
+
+    if (!anchorRight && !lastIsStar) {
+	*dsStr++ = '*';
+    }
+    Tcl_DStringSetLength(dsPtr, dsStr - dsStrStart);
+
+    if (exactPtr) {
+	*exactPtr = (anchorLeft && anchorRight);
+    }
+
+    return TCL_OK;
+
+  invalidGlob:
+    if (interp != NULL) {
+	Tcl_SetObjResult(interp, Tcl_NewStringObj(msg, -1));
+	Tcl_SetErrorCode(interp, "TCL", "RE2GLOB", code, NULL);
+    }
+    Tcl_DStringFree(dsPtr);
+    return TCL_ERROR;
+}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tclVar.c b/generic/tclVar.c
new file mode 100644
index 0000000..2adffbc
--- /dev/null
+++ b/generic/tclVar.c
@@ -0,0 +1,6382 @@
+/*
+ * tclVar.c --
+ *
+ *	This file contains routines that implement Tcl variables (both scalars
+ *	and arrays).
+ *
+ *	The implementation of arrays is modelled after an initial
+ *	implementation by Mark Diekhans and Karl Lehenbauer.
+ *
+ * Copyright (c) 1987-1994 The Regents of the University of California.
+ * Copyright (c) 1994-1997 Sun Microsystems, Inc.
+ * Copyright (c) 1998-1999 by Scriptics Corporation.
+ * Copyright (c) 2001 by Kevin B. Kenny. All rights reserved.
+ * Copyright (c) 2007 Miguel Sofer
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#include "tclInt.h"
+#include "tclOOInt.h"
+
+/*
+ * Prototypes for the variable hash key methods.
+ */
+
+static Tcl_HashEntry *	AllocVarEntry(Tcl_HashTable *tablePtr, void *keyPtr);
+static void		FreeVarEntry(Tcl_HashEntry *hPtr);
+static int		CompareVarKeys(void *keyPtr, Tcl_HashEntry *hPtr);
+
+static const Tcl_HashKeyType tclVarHashKeyType = {
+    TCL_HASH_KEY_TYPE_VERSION,	/* version */
+    0,				/* flags */
+    TclHashObjKey,		/* hashKeyProc */
+    CompareVarKeys,		/* compareKeysProc */
+    AllocVarEntry,		/* allocEntryProc */
+    FreeVarEntry		/* freeEntryProc */
+};
+
+static inline Var *	VarHashCreateVar(TclVarHashTable *tablePtr,
+			    Tcl_Obj *key, int *newPtr);
+static inline Var *	VarHashFirstVar(TclVarHashTable *tablePtr,
+			    Tcl_HashSearch *searchPtr);
+static inline Var *	VarHashNextVar(Tcl_HashSearch *searchPtr);
+static inline void	CleanupVar(Var *varPtr, Var *arrayPtr);
+
+#define VarHashGetValue(hPtr) \
+    ((Var *) ((char *)hPtr - TclOffset(VarInHash, entry)))
+
+/*
+ * NOTE: VarHashCreateVar increments the recount of its key argument.
+ * All callers that will call Tcl_DecrRefCount on that argument must
+ * call Tcl_IncrRefCount on it before passing it in.  This requirement
+ * can bubble up to callers of callers .... etc.
+ */
+
+static inline Var *
+VarHashCreateVar(
+    TclVarHashTable *tablePtr,
+    Tcl_Obj *key,
+    int *newPtr)
+{
+    Tcl_HashEntry *hPtr = Tcl_CreateHashEntry(&tablePtr->table,
+	    key, newPtr);
+
+    if (hPtr) {
+	return VarHashGetValue(hPtr);
+    } else {
+	return NULL;
+    }
+}
+
+#define VarHashFindVar(tablePtr, key) \
+    VarHashCreateVar((tablePtr), (key), NULL)
+
+#define VarHashInvalidateEntry(varPtr) \
+    ((varPtr)->flags |= VAR_DEAD_HASH)
+
+#define VarHashDeleteEntry(varPtr) \
+    Tcl_DeleteHashEntry(&(((VarInHash *) varPtr)->entry))
+
+#define VarHashFirstEntry(tablePtr, searchPtr) \
+    Tcl_FirstHashEntry(&(tablePtr)->table, (searchPtr))
+
+#define VarHashNextEntry(searchPtr) \
+    Tcl_NextHashEntry((searchPtr))
+
+static inline Var *
+VarHashFirstVar(
+    TclVarHashTable *tablePtr,
+    Tcl_HashSearch *searchPtr)
+{
+    Tcl_HashEntry *hPtr = VarHashFirstEntry(tablePtr, searchPtr);
+
+    if (hPtr) {
+	return VarHashGetValue(hPtr);
+    } else {
+	return NULL;
+    }
+}
+
+static inline Var *
+VarHashNextVar(
+    Tcl_HashSearch *searchPtr)
+{
+    Tcl_HashEntry *hPtr = VarHashNextEntry(searchPtr);
+
+    if (hPtr) {
+	return VarHashGetValue(hPtr);
+    } else {
+	return NULL;
+    }
+}
+
+#define VarHashGetKey(varPtr) \
+    (((VarInHash *)(varPtr))->entry.key.objPtr)
+
+#define VarHashDeleteTable(tablePtr) \
+    Tcl_DeleteHashTable(&(tablePtr)->table)
+
+/*
+ * The strings below are used to indicate what went wrong when a variable
+ * access is denied.
+ */
+
+static const char *noSuchVar =		"no such variable";
+static const char *isArray =		"variable is array";
+static const char *needArray =		"variable isn't array";
+static const char *noSuchElement =	"no such element in array";
+static const char *danglingElement =
+	"upvar refers to element in deleted array";
+static const char *danglingVar =
+	"upvar refers to variable in deleted namespace";
+static const char *badNamespace =	"parent namespace doesn't exist";
+static const char *missingName =	"missing variable name";
+static const char *isArrayElement =
+	"name refers to an element in an array";
+
+/*
+ * A test to see if we are in a call frame that has local variables. This is
+ * true if we are inside a procedure body.
+ */
+
+#define HasLocalVars(framePtr) ((framePtr)->isProcCallFrame & FRAME_IS_PROC)
+
+/*
+ * The following structure describes an enumerative search in progress on an
+ * array variable; this are invoked with options to the "array" command.
+ */
+
+typedef struct ArraySearch {
+    int id;			/* Integer id used to distinguish among
+				 * multiple concurrent searches for the same
+				 * array. */
+    struct Var *varPtr;		/* Pointer to array variable that's being
+				 * searched. */
+    Tcl_HashSearch search;	/* Info kept by the hash module about progress
+				 * through the array. */
+    Tcl_HashEntry *nextEntry;	/* Non-null means this is the next element to
+				 * be enumerated (it's leftover from the
+				 * Tcl_FirstHashEntry call or from an "array
+				 * anymore" command). NULL means must call
+				 * Tcl_NextHashEntry to get value to
+				 * return. */
+    struct ArraySearch *nextPtr;/* Next in list of all active searches for
+				 * this variable, or NULL if this is the last
+				 * one. */
+} ArraySearch;
+
+/*
+ * Forward references to functions defined later in this file:
+ */
+
+static void		AppendLocals(Tcl_Interp *interp, Tcl_Obj *listPtr,
+			    Tcl_Obj *patternPtr, int includeLinks);
+static void		DeleteSearches(Interp *iPtr, Var *arrayVarPtr);
+static void		DeleteArray(Interp *iPtr, Tcl_Obj *arrayNamePtr,
+			    Var *varPtr, int flags, int index);
+static Tcl_Var		ObjFindNamespaceVar(Tcl_Interp *interp,
+			    Tcl_Obj *namePtr, Tcl_Namespace *contextNsPtr,
+			    int flags);
+static int		ObjMakeUpvar(Tcl_Interp *interp,
+			    CallFrame *framePtr, Tcl_Obj *otherP1Ptr,
+			    const char *otherP2, const int otherFlags,
+			    Tcl_Obj *myNamePtr, int myFlags, int index);
+static ArraySearch *	ParseSearchId(Tcl_Interp *interp, const Var *varPtr,
+			    Tcl_Obj *varNamePtr, Tcl_Obj *handleObj);
+static void		UnsetVarStruct(Var *varPtr, Var *arrayPtr,
+			    Interp *iPtr, Tcl_Obj *part1Ptr,
+			    Tcl_Obj *part2Ptr, int flags, int index);
+static int		SetArraySearchObj(Tcl_Interp *interp,
+			    Tcl_Obj *objPtr);
+
+/*
+ * Functions defined in this file that may be exported in the future for use
+ * by the bytecode compiler and engine or to the public interface.
+ */
+
+MODULE_SCOPE Var *	TclLookupSimpleVar(Tcl_Interp *interp,
+			    Tcl_Obj *varNamePtr, int flags, const int create,
+			    const char **errMsgPtr, int *indexPtr);
+
+static Tcl_DupInternalRepProc	DupLocalVarName;
+static Tcl_FreeInternalRepProc	FreeLocalVarName;
+static Tcl_UpdateStringProc	PanicOnUpdateVarName;
+
+static Tcl_FreeInternalRepProc	FreeParsedVarName;
+static Tcl_DupInternalRepProc	DupParsedVarName;
+static Tcl_UpdateStringProc	UpdateParsedVarName;
+
+static Tcl_UpdateStringProc	PanicOnUpdateVarName;
+static Tcl_SetFromAnyProc	PanicOnSetVarName;
+
+/*
+ * Types of Tcl_Objs used to cache variable lookups.
+ *
+ * localVarName - INTERNALREP DEFINITION:
+ *   twoPtrValue.ptr1:   pointer to name obj in varFramePtr->localCache
+ *			  or NULL if it is this same obj
+ *   twoPtrValue.ptr2: index into locals table
+ *
+ * parsedVarName - INTERNALREP DEFINITION:
+ *   twoPtrValue.ptr1:	pointer to the array name Tcl_Obj, or NULL if it is a
+ *			scalar variable
+ *   twoPtrValue.ptr2:	pointer to the element name string (owned by this
+ *			Tcl_Obj), or NULL if it is a scalar variable
+ */
+
+static const Tcl_ObjType localVarNameType = {
+    "localVarName",
+    FreeLocalVarName, DupLocalVarName, PanicOnUpdateVarName, PanicOnSetVarName
+};
+
+static const Tcl_ObjType tclParsedVarNameType = {
+    "parsedVarName",
+    FreeParsedVarName, DupParsedVarName, UpdateParsedVarName, PanicOnSetVarName
+};
+
+/*
+ * Type of Tcl_Objs used to speed up array searches.
+ *
+ * INTERNALREP DEFINITION:
+ *   twoPtrValue.ptr1:	searchIdNumber (cast to pointer)
+ *   twoPtrValue.ptr2:	variableNameStartInString (cast to pointer)
+ *
+ * Note that the value stored in ptr2 is the offset into the string of the
+ * start of the variable name and not the address of the variable name itself,
+ * as this can be safely copied.
+ */
+
+const Tcl_ObjType tclArraySearchType = {
+    "array search",
+    NULL, NULL, NULL, SetArraySearchObj
+};
+
+Var *
+TclVarHashCreateVar(
+    TclVarHashTable *tablePtr,
+    const char *key,
+    int *newPtr)
+{
+    Tcl_Obj *keyPtr;
+    Var *varPtr;
+
+    keyPtr = Tcl_NewStringObj(key, -1);
+    Tcl_IncrRefCount(keyPtr);
+    varPtr = VarHashCreateVar(tablePtr, keyPtr, newPtr);
+    Tcl_DecrRefCount(keyPtr);
+
+    return varPtr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclCleanupVar --
+ *
+ *	This function is called when it looks like it may be OK to free up a
+ *	variable's storage. If the variable is in a hashtable, its Var
+ *	structure and hash table entry will be freed along with those of its
+ *	containing array, if any. This function is called, for example, when
+ *	a trace on a variable deletes a variable.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	If the variable (or its containing array) really is dead and in a
+ *	hashtable, then its Var structure, and possibly its hash table entry,
+ *	is freed up.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static inline void
+CleanupVar(
+    Var *varPtr,		/* Pointer to variable that may be a candidate
+				 * for being expunged. */
+    Var *arrayPtr)		/* Array that contains the variable, or NULL
+				 * if this variable isn't an array element. */
+{
+    if (TclIsVarUndefined(varPtr) && TclIsVarInHash(varPtr)
+	    && !TclIsVarTraced(varPtr)
+	    && (VarHashRefCount(varPtr) == !TclIsVarDeadHash(varPtr))) {
+	if (VarHashRefCount(varPtr) == 0) {
+	    ckfree(varPtr);
+	} else {
+	    VarHashDeleteEntry(varPtr);
+	}
+    }
+    if (arrayPtr != NULL && TclIsVarUndefined(arrayPtr) &&
+	    TclIsVarInHash(arrayPtr) && !TclIsVarTraced(arrayPtr) &&
+	    (VarHashRefCount(arrayPtr) == !TclIsVarDeadHash(arrayPtr))) {
+	if (VarHashRefCount(arrayPtr) == 0) {
+	    ckfree(arrayPtr);
+	} else {
+	    VarHashDeleteEntry(arrayPtr);
+	}
+    }
+}
+
+void
+TclCleanupVar(
+    Var *varPtr,		/* Pointer to variable that may be a candidate
+				 * for being expunged. */
+    Var *arrayPtr)		/* Array that contains the variable, or NULL
+				 * if this variable isn't an array element. */
+{
+    CleanupVar(varPtr, arrayPtr);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclLookupVar --
+ *
+ *	This function is used to locate a variable given its name(s). It has
+ *	been mostly superseded by TclObjLookupVar, it is now only used by the
+ *	trace code. It is kept in tcl8.5 mainly because it is in the internal
+ *	stubs table, so that some extension may be calling it.
+ *
+ * Results:
+ *	The return value is a pointer to the variable structure indicated by
+ *	part1 and part2, or NULL if the variable couldn't be found. If the
+ *	variable is found, *arrayPtrPtr is filled in with the address of the
+ *	variable structure for the array that contains the variable (or NULL
+ *	if the variable is a scalar). If the variable can't be found and
+ *	either createPart1 or createPart2 are 1, a new as-yet-undefined
+ *	(VAR_UNDEFINED) variable structure is created, entered into a hash
+ *	table, and returned.
+ *
+ *	If the variable isn't found and creation wasn't specified, or some
+ *	other error occurs, NULL is returned and an error message is left in
+ *	the interp's result if TCL_LEAVE_ERR_MSG is set in flags.
+ *
+ *	Note: it's possible for the variable returned to be VAR_UNDEFINED even
+ *	if createPart1 or createPart2 are 1 (these only cause the hash table
+ *	entry or array to be created). For example, the variable might be a
+ *	global that has been unset but is still referenced by a procedure, or
+ *	a variable that has been unset but it only being kept in existence (if
+ *	VAR_UNDEFINED) by a trace.
+ *
+ * Side effects:
+ *	New hashtable entries may be created if createPart1 or createPart2
+ *	are 1.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Var *
+TclLookupVar(
+    Tcl_Interp *interp,		/* Interpreter to use for lookup. */
+    const char *part1,		/* If part2 isn't NULL, this is the name of an
+				 * array. Otherwise, this is a full variable
+				 * name that could include a parenthesized
+				 * array element. */
+    const char *part2,		/* Name of element within array, or NULL. */
+    int flags,			/* Only TCL_GLOBAL_ONLY, TCL_NAMESPACE_ONLY,
+				 * and TCL_LEAVE_ERR_MSG bits matter. */
+    const char *msg,		/* Verb to use in error messages, e.g. "read"
+				 * or "set". Only needed if TCL_LEAVE_ERR_MSG
+				 * is set in flags. */
+    int createPart1,		/* If 1, create hash table entry for part 1 of
+				 * name, if it doesn't already exist. If 0,
+				 * return error if it doesn't exist. */
+    int createPart2,		/* If 1, create hash table entry for part 2 of
+				 * name, if it doesn't already exist. If 0,
+				 * return error if it doesn't exist. */
+    Var **arrayPtrPtr)		/* If the name refers to an element of an
+				 * array, *arrayPtrPtr gets filled in with
+				 * address of array variable. Otherwise this
+				 * is set to NULL. */
+{
+    Var *varPtr;
+    Tcl_Obj *part1Ptr = Tcl_NewStringObj(part1, -1);
+
+    if (createPart1) {
+	Tcl_IncrRefCount(part1Ptr);
+    }
+
+    varPtr = TclObjLookupVar(interp, part1Ptr, part2, flags, msg,
+	    createPart1, createPart2, arrayPtrPtr);
+
+    TclDecrRefCount(part1Ptr);
+    return varPtr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclObjLookupVar, TclObjLookupVarEx --
+ *
+ *	This function is used by virtually all of the variable code to locate
+ *	a variable given its name(s). The parsing into array/element
+ *	components and (if possible) the lookup results are cached in
+ *	part1Ptr, which is converted to one of the varNameTypes.
+ *
+ * Results:
+ *	The return value is a pointer to the variable structure indicated by
+ *	part1Ptr and part2, or NULL if the variable couldn't be found. If *
+ *	the variable is found, *arrayPtrPtr is filled with the address of the
+ *	variable structure for the array that contains the variable (or NULL
+ *	if the variable is a scalar). If the variable can't be found and
+ *	either createPart1 or createPart2 are 1, a new as-yet-undefined
+ *	(VAR_UNDEFINED) variable structure is created, entered into a hash
+ *	table, and returned.
+ *
+ *	If the variable isn't found and creation wasn't specified, or some
+ *	other error occurs, NULL is returned and an error message is left in
+ *	the interp's result if TCL_LEAVE_ERR_MSG is set in flags.
+ *
+ *	Note: it's possible for the variable returned to be VAR_UNDEFINED even
+ *	if createPart1 or createPart2 are 1 (these only cause the hash table
+ *	entry or array to be created). For example, the variable might be a
+ *	global that has been unset but is still referenced by a procedure, or
+ *	a variable that has been unset but it only being kept in existence (if
+ *	VAR_UNDEFINED) by a trace.
+ *
+ * Side effects:
+ *	New hashtable entries may be created if createPart1 or createPart2
+ *	are 1. The object part1Ptr is converted to one of localVarNameType,
+ *	tclNsVarNameType or tclParsedVarNameType and caches as much of the
+ *	lookup as it can.
+ *	When createPart1 is 1, callers must IncrRefCount part1Ptr if they
+ *	plan to DecrRefCount it.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Var *
+TclObjLookupVar(
+    Tcl_Interp *interp,		/* Interpreter to use for lookup. */
+    register Tcl_Obj *part1Ptr,	/* If part2 isn't NULL, this is the name of an
+				 * array. Otherwise, this is a full variable
+				 * name that could include a parenthesized
+				 * array element. */
+    const char *part2,		/* Name of element within array, or NULL. */
+    int flags,			/* Only TCL_GLOBAL_ONLY, TCL_NAMESPACE_ONLY,
+				 * and TCL_LEAVE_ERR_MSG bits matter. */
+    const char *msg,		/* Verb to use in error messages, e.g. "read"
+				 * or "set". Only needed if TCL_LEAVE_ERR_MSG
+				 * is set in flags. */
+    const int createPart1,	/* If 1, create hash table entry for part 1 of
+				 * name, if it doesn't already exist. If 0,
+				 * return error if it doesn't exist. */
+    const int createPart2,	/* If 1, create hash table entry for part 2 of
+				 * name, if it doesn't already exist. If 0,
+				 * return error if it doesn't exist. */
+    Var **arrayPtrPtr)		/* If the name refers to an element of an
+				 * array, *arrayPtrPtr gets filled in with
+				 * address of array variable. Otherwise this
+				 * is set to NULL. */
+{
+    Tcl_Obj *part2Ptr = NULL;
+    Var *resPtr;
+
+    if (part2) {
+	part2Ptr = Tcl_NewStringObj(part2, -1);
+	if (createPart2) {
+	    Tcl_IncrRefCount(part2Ptr);
+	}
+    }
+
+    resPtr = TclObjLookupVarEx(interp, part1Ptr, part2Ptr,
+	    flags, msg, createPart1, createPart2, arrayPtrPtr);
+
+    if (part2Ptr) {
+	Tcl_DecrRefCount(part2Ptr);
+    }
+
+    return resPtr;
+}
+
+/*
+ *	When createPart1 is 1, callers must IncrRefCount part1Ptr if they
+ *	plan to DecrRefCount it.
+ *	When createPart2 is 1, callers must IncrRefCount part2Ptr if they
+ *	plan to DecrRefCount it.
+ */
+Var *
+TclObjLookupVarEx(
+    Tcl_Interp *interp,		/* Interpreter to use for lookup. */
+    Tcl_Obj *part1Ptr,		/* If part2Ptr isn't NULL, this is the name of
+				 * an array. Otherwise, this is a full
+				 * variable name that could include a
+				 * parenthesized array element. */
+    Tcl_Obj *part2Ptr,		/* Name of element within array, or NULL. */
+    int flags,			/* Only TCL_GLOBAL_ONLY, TCL_NAMESPACE_ONLY,
+				 * and TCL_LEAVE_ERR_MSG bits matter. */
+    const char *msg,		/* Verb to use in error messages, e.g. "read"
+				 * or "set". Only needed if TCL_LEAVE_ERR_MSG
+				 * is set in flags. */
+    const int createPart1,	/* If 1, create hash table entry for part 1 of
+				 * name, if it doesn't already exist. If 0,
+				 * return error if it doesn't exist. */
+    const int createPart2,	/* If 1, create hash table entry for part 2 of
+				 * name, if it doesn't already exist. If 0,
+				 * return error if it doesn't exist. */
+    Var **arrayPtrPtr)		/* If the name refers to an element of an
+				 * array, *arrayPtrPtr gets filled in with
+				 * address of array variable. Otherwise this
+				 * is set to NULL. */
+{
+    Interp *iPtr = (Interp *) interp;
+    register Var *varPtr;	/* Points to the variable's in-frame Var
+				 * structure. */
+    const char *part1;
+    int index, len1, len2;
+    int parsed = 0;
+    Tcl_Obj *objPtr;
+    const Tcl_ObjType *typePtr = part1Ptr->typePtr;
+    const char *errMsg = NULL;
+    CallFrame *varFramePtr = iPtr->varFramePtr;
+    const char *part2 = part2Ptr? TclGetString(part2Ptr):NULL;
+    char *newPart2 = NULL;
+    *arrayPtrPtr = NULL;
+
+    if (typePtr == &localVarNameType) {
+	int localIndex;
+
+    localVarNameTypeHandling:
+	localIndex = PTR2INT(part1Ptr->internalRep.twoPtrValue.ptr2);
+	if (HasLocalVars(varFramePtr)
+		&& !(flags & (TCL_GLOBAL_ONLY | TCL_NAMESPACE_ONLY))
+		&& (localIndex < varFramePtr->numCompiledLocals)) {
+	    /*
+	     * Use the cached index if the names coincide.
+	     */
+
+	    Tcl_Obj *namePtr = part1Ptr->internalRep.twoPtrValue.ptr1;
+	    Tcl_Obj *checkNamePtr = localName(iPtr->varFramePtr, localIndex);
+
+	    if ((!namePtr && (checkNamePtr == part1Ptr)) ||
+		    (namePtr && (checkNamePtr == namePtr))) {
+		varPtr = (Var *) &(varFramePtr->compiledLocals[localIndex]);
+		goto donePart1;
+	    }
+	}
+	goto doneParsing;
+    }
+
+    /*
+     * If part1Ptr is a tclParsedVarNameType, separate it into the pre-parsed
+     * parts.
+     */
+
+    if (typePtr == &tclParsedVarNameType) {
+	if (part1Ptr->internalRep.twoPtrValue.ptr1 != NULL) {
+	    if (part2Ptr != NULL) {
+		/*
+		 * ERROR: part1Ptr is already an array element, cannot specify
+		 * a part2.
+		 */
+
+		if (flags & TCL_LEAVE_ERR_MSG) {
+		    TclObjVarErrMsg(interp, part1Ptr, part2Ptr, msg,
+			    noSuchVar, -1);
+		    Tcl_SetErrorCode(interp, "TCL", "VALUE", "VARNAME", NULL);
+		}
+		return NULL;
+	    }
+	    part2 = newPart2 = part1Ptr->internalRep.twoPtrValue.ptr2;
+	    if (newPart2) {
+		part2Ptr = Tcl_NewStringObj(newPart2, -1);
+		if (createPart2) {
+		    Tcl_IncrRefCount(part2Ptr);
+		}
+	    }
+	    part1Ptr = part1Ptr->internalRep.twoPtrValue.ptr1;
+	    typePtr = part1Ptr->typePtr;
+	    if (typePtr == &localVarNameType) {
+		goto localVarNameTypeHandling;
+	    }
+	}
+	parsed = 1;
+    }
+    part1 = TclGetStringFromObj(part1Ptr, &len1);
+
+    if (!parsed && len1 && (*(part1 + len1 - 1) == ')')) {
+	/*
+	 * part1Ptr is possibly an unparsed array element.
+	 */
+
+	register int i;
+
+	len2 = -1;
+	for (i = 0; i < len1; i++) {
+	    if (*(part1 + i) == '(') {
+		if (part2Ptr != NULL) {
+		    if (flags & TCL_LEAVE_ERR_MSG) {
+			TclObjVarErrMsg(interp, part1Ptr, part2Ptr, msg,
+				needArray, -1);
+			Tcl_SetErrorCode(interp, "TCL", "VALUE", "VARNAME",
+				NULL);
+		    }
+		    return NULL;
+		}
+
+		/*
+		 * part1Ptr points to an array element; first copy the element
+		 * name to a new string part2.
+		 */
+
+		part2 = part1 + i + 1;
+		len2 = len1 - i - 2;
+		len1 = i;
+
+		newPart2 = ckalloc(len2 + 1);
+		memcpy(newPart2, part2, (unsigned) len2);
+		*(newPart2+len2) = '\0';
+		part2 = newPart2;
+		part2Ptr = Tcl_NewStringObj(newPart2, -1);
+		if (createPart2) {
+		    Tcl_IncrRefCount(part2Ptr);
+		}
+
+		/*
+		 * Free the internal rep of the original part1Ptr, now renamed
+		 * objPtr, and set it to tclParsedVarNameType.
+		 */
+
+		objPtr = part1Ptr;
+		TclFreeIntRep(objPtr);
+		objPtr->typePtr = &tclParsedVarNameType;
+
+		/*
+		 * Define a new string object to hold the new part1Ptr, i.e.,
+		 * the array name. Set the internal rep of objPtr, reset
+		 * typePtr and part1 to contain the references to the array
+		 * name.
+		 */
+
+		TclNewStringObj(part1Ptr, part1, len1);
+		Tcl_IncrRefCount(part1Ptr);
+
+		objPtr->internalRep.twoPtrValue.ptr1 = part1Ptr;
+		objPtr->internalRep.twoPtrValue.ptr2 = (void *) part2;
+
+		typePtr = part1Ptr->typePtr;
+		part1 = TclGetString(part1Ptr);
+		break;
+	    }
+	}
+    }
+
+  doneParsing:
+    /*
+     * part1Ptr is not an array element; look it up, and convert it to one of
+     * the cached types if possible.
+     */
+
+    TclFreeIntRep(part1Ptr);
+
+    varPtr = TclLookupSimpleVar(interp, part1Ptr, flags, createPart1,
+	    &errMsg, &index);
+    if (varPtr == NULL) {
+	if ((errMsg != NULL) && (flags & TCL_LEAVE_ERR_MSG)) {
+	    TclObjVarErrMsg(interp, part1Ptr, part2Ptr, msg, errMsg, -1);
+	    Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "VARNAME",
+		    TclGetString(part1Ptr), NULL);
+	}
+	if (newPart2) {
+	    Tcl_DecrRefCount(part2Ptr);
+	}
+	return NULL;
+    }
+
+    /*
+     * Cache the newly found variable if possible.
+     */
+
+    if (index >= 0) {
+	/*
+	 * An indexed local variable.
+	 */
+	Tcl_Obj *cachedNamePtr = localName(iPtr->varFramePtr, index);
+
+	part1Ptr->typePtr = &localVarNameType;
+	if (part1Ptr != cachedNamePtr) {
+	    part1Ptr->internalRep.twoPtrValue.ptr1 = cachedNamePtr;
+	    Tcl_IncrRefCount(cachedNamePtr);
+	    if (cachedNamePtr->typePtr != &localVarNameType
+		    || cachedNamePtr->internalRep.twoPtrValue.ptr1 != NULL) {
+	        TclFreeIntRep(cachedNamePtr);
+	    }
+	} else {
+	    part1Ptr->internalRep.twoPtrValue.ptr1 = NULL;
+	}
+	part1Ptr->internalRep.twoPtrValue.ptr2 = INT2PTR(index);
+    } else {
+	/*
+	 * At least mark part1Ptr as already parsed.
+	 */
+
+	part1Ptr->typePtr = &tclParsedVarNameType;
+	part1Ptr->internalRep.twoPtrValue.ptr1 = NULL;
+	part1Ptr->internalRep.twoPtrValue.ptr2 = NULL;
+    }
+
+  donePart1:
+    while (TclIsVarLink(varPtr)) {
+	varPtr = varPtr->value.linkPtr;
+    }
+
+    if (part2Ptr != NULL) {
+	/*
+	 * Array element sought: look it up.
+	 */
+
+	*arrayPtrPtr = varPtr;
+	varPtr = TclLookupArrayElement(interp, part1Ptr, part2Ptr, flags, msg,
+		createPart1, createPart2, varPtr, -1);
+	if (newPart2) {
+	    Tcl_DecrRefCount(part2Ptr);
+	}
+    }
+    return varPtr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclLookupSimpleVar --
+ *
+ *	This function is used by to locate a simple variable (i.e., not an
+ *	array element) given its name.
+ *
+ * Results:
+ *	The return value is a pointer to the variable structure indicated by
+ *	varName, or NULL if the variable couldn't be found. If the variable
+ *	can't be found and create is 1, a new as-yet-undefined (VAR_UNDEFINED)
+ *	variable structure is created, entered into a hash table, and
+ *	returned.
+ *
+ *	If the current CallFrame corresponds to a proc and the variable found
+ *	is one of the compiledLocals, its index is placed in *indexPtr.
+ *	Otherwise, *indexPtr will be set to (according to the needs of
+ *	TclObjLookupVar):
+ *	    -1 a global reference
+ *	    -2 a reference to a namespace variable
+ *	    -3 a non-cachable reference, i.e., one of:
+ *		. non-indexed local var
+ *		. a reference of unknown origin;
+ *		. resolution by a namespace or interp resolver
+ *
+ *	If the variable isn't found and creation wasn't specified, or some
+ *	other error occurs, NULL is returned and the corresponding error
+ *	message is left in *errMsgPtr.
+ *
+ *	Note: it's possible for the variable returned to be VAR_UNDEFINED even
+ *	if create is 1 (this only causes the hash table entry to be created).
+ *	For example, the variable might be a global that has been unset but is
+ *	still referenced by a procedure, or a variable that has been unset but
+ *	it only being kept in existence (if VAR_UNDEFINED) by a trace.
+ *
+ * Side effects:
+ *	A new hashtable entry may be created if create is 1.
+ *	Callers must Incr varNamePtr if they plan to Decr it if create is 1.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Var *
+TclLookupSimpleVar(
+    Tcl_Interp *interp,		/* Interpreter to use for lookup. */
+    Tcl_Obj *varNamePtr,	/* This is a simple variable name that could
+				 * represent a scalar or an array. */
+    int flags,			/* Only TCL_GLOBAL_ONLY, TCL_NAMESPACE_ONLY,
+				 * TCL_AVOID_RESOLVERS and TCL_LEAVE_ERR_MSG
+				 * bits matter. */
+    const int create,		/* If 1, create hash table entry for varname,
+				 * if it doesn't already exist. If 0, return
+				 * error if it doesn't exist. */
+    const char **errMsgPtr,
+    int *indexPtr)
+{
+    Interp *iPtr = (Interp *) interp;
+    CallFrame *varFramePtr = iPtr->varFramePtr;
+				/* Points to the procedure call frame whose
+				 * variables are currently in use. Same as the
+				 * current procedure's frame, if any, unless
+				 * an "uplevel" is executing. */
+    TclVarHashTable *tablePtr;	/* Points to the hashtable, if any, in which
+				 * to look up the variable. */
+    Tcl_Var var;		/* Used to search for global names. */
+    Var *varPtr;		/* Points to the Var structure returned for
+				 * the variable. */
+    Namespace *varNsPtr, *cxtNsPtr, *dummy1Ptr, *dummy2Ptr;
+    ResolverScheme *resPtr;
+    int isNew, i, result, varLen;
+    const char *varName = TclGetStringFromObj(varNamePtr, &varLen);
+
+    varPtr = NULL;
+    varNsPtr = NULL;		/* Set non-NULL if a nonlocal variable. */
+    *indexPtr = -3;
+
+    if (flags & TCL_GLOBAL_ONLY) {
+	cxtNsPtr = iPtr->globalNsPtr;
+    } else {
+	cxtNsPtr = iPtr->varFramePtr->nsPtr;
+    }
+
+    /*
+     * If this namespace has a variable resolver, then give it first crack at
+     * the variable resolution. It may return a Tcl_Var value, it may signal
+     * to continue onward, or it may signal an error.
+     */
+
+    if ((cxtNsPtr->varResProc != NULL || iPtr->resolverPtr != NULL)
+	    && !(flags & TCL_AVOID_RESOLVERS)) {
+	resPtr = iPtr->resolverPtr;
+	if (cxtNsPtr->varResProc) {
+	    result = cxtNsPtr->varResProc(interp, varName,
+		    (Tcl_Namespace *) cxtNsPtr, flags, &var);
+	} else {
+	    result = TCL_CONTINUE;
+	}
+
+	while (result == TCL_CONTINUE && resPtr) {
+	    if (resPtr->varResProc) {
+		result = resPtr->varResProc(interp, varName,
+			(Tcl_Namespace *) cxtNsPtr, flags, &var);
+	    }
+	    resPtr = resPtr->nextPtr;
+	}
+
+	if (result == TCL_OK) {
+	    return (Var *) var;
+	} else if (result != TCL_CONTINUE) {
+	    return NULL;
+	}
+    }
+
+    /*
+     * Look up varName. Look it up as either a namespace variable or as a
+     * local variable in a procedure call frame (varFramePtr). Interpret
+     * varName as a namespace variable if:
+     *    1) so requested by a TCL_GLOBAL_ONLY or TCL_NAMESPACE_ONLY flag,
+     *    2) there is no active frame (we're at the global :: scope),
+     *    3) the active frame was pushed to define the namespace context for a
+     *	     "namespace eval" or "namespace inscope" command,
+     *    4) the name has namespace qualifiers ("::"s).
+     * Otherwise, if varName is a local variable, search first in the frame's
+     * array of compiler-allocated local variables, then in its hashtable for
+     * runtime-created local variables.
+     *
+     * If create and the variable isn't found, create the variable and, if
+     * necessary, create varFramePtr's local var hashtable.
+     */
+
+    if (((flags & (TCL_GLOBAL_ONLY | TCL_NAMESPACE_ONLY)) != 0)
+	    || !HasLocalVars(varFramePtr)
+	    || (strstr(varName, "::") != NULL)) {
+	const char *tail;
+	int lookGlobal = (flags & TCL_GLOBAL_ONLY)
+		|| (cxtNsPtr == iPtr->globalNsPtr)
+		|| ((*varName == ':') && (*(varName+1) == ':'));
+
+	if (lookGlobal) {
+	    *indexPtr = -1;
+	    flags = (flags | TCL_GLOBAL_ONLY) & ~TCL_NAMESPACE_ONLY;
+	} else {
+	    if (flags & TCL_AVOID_RESOLVERS) {
+		flags = (flags | TCL_NAMESPACE_ONLY);
+	    }
+	    if (flags & TCL_NAMESPACE_ONLY) {
+		*indexPtr = -2;
+	    }
+	}
+
+	/*
+	 * Don't pass TCL_LEAVE_ERR_MSG, we may yet create the variable, or
+	 * otherwise generate our own error!
+	 */
+
+	varPtr = (Var *) ObjFindNamespaceVar(interp, varNamePtr,
+		(Tcl_Namespace *) cxtNsPtr,
+		(flags | TCL_AVOID_RESOLVERS) & ~TCL_LEAVE_ERR_MSG);
+	if (varPtr == NULL) {
+	    Tcl_Obj *tailPtr;
+
+	    if (create) {	/* Var wasn't found so create it. */
+		TclGetNamespaceForQualName(interp, varName, cxtNsPtr,
+			flags, &varNsPtr, &dummy1Ptr, &dummy2Ptr, &tail);
+		if (varNsPtr == NULL) {
+		    *errMsgPtr = badNamespace;
+		    return NULL;
+		} else if (tail == NULL) {
+		    *errMsgPtr = missingName;
+		    return NULL;
+		}
+		if (tail != varName) {
+		    tailPtr = Tcl_NewStringObj(tail, -1);
+		} else {
+		    tailPtr = varNamePtr;
+		}
+		varPtr = VarHashCreateVar(&varNsPtr->varTable, tailPtr,
+			&isNew);
+		if (lookGlobal) {
+		    /*
+		     * The variable was created starting from the global
+		     * namespace: a global reference is returned even if it
+		     * wasn't explicitly requested.
+		     */
+
+		    *indexPtr = -1;
+		} else {
+		    *indexPtr = -2;
+		}
+	    } else {		/* Var wasn't found and not to create it. */
+		*errMsgPtr = noSuchVar;
+		return NULL;
+	    }
+	}
+    } else {			/* Local var: look in frame varFramePtr. */
+	int localLen, localCt = varFramePtr->numCompiledLocals;
+	Tcl_Obj **objPtrPtr = &varFramePtr->localCachePtr->varName0;
+	const char *localNameStr;
+
+	for (i=0 ; i<localCt ; i++, objPtrPtr++) {
+	    register Tcl_Obj *objPtr = *objPtrPtr;
+
+	    if (objPtr) {
+		localNameStr = TclGetStringFromObj(objPtr, &localLen);
+
+		if ((varLen == localLen) && (varName[0] == localNameStr[0])
+			&& !memcmp(varName, localNameStr, varLen)) {
+		    *indexPtr = i;
+		    return (Var *) &varFramePtr->compiledLocals[i];
+		}
+	    }
+	}
+	tablePtr = varFramePtr->varTablePtr;
+	if (create) {
+	    if (tablePtr == NULL) {
+		tablePtr = ckalloc(sizeof(TclVarHashTable));
+		TclInitVarHashTable(tablePtr, NULL);
+		varFramePtr->varTablePtr = tablePtr;
+	    }
+	    varPtr = VarHashCreateVar(tablePtr, varNamePtr, &isNew);
+	} else {
+	    varPtr = NULL;
+	    if (tablePtr != NULL) {
+		varPtr = VarHashFindVar(tablePtr, varNamePtr);
+	    }
+	    if (varPtr == NULL) {
+		*errMsgPtr = noSuchVar;
+	    }
+	}
+    }
+    return varPtr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclLookupArrayElement --
+ *
+ *	This function is used to locate a variable which is in an array's
+ *	hashtable given a pointer to the array's Var structure and the
+ *	element's name.
+ *
+ * Results:
+ *	The return value is a pointer to the variable structure , or NULL if
+ *	the variable couldn't be found.
+ *
+ *	If arrayPtr points to a variable that isn't an array and createPart1
+ *	is 1, the corresponding variable will be converted to an array.
+ *	Otherwise, NULL is returned and an error message is left in the
+ *	interp's result if TCL_LEAVE_ERR_MSG is set in flags.
+ *
+ *	If the variable is not found and createPart2 is 1, the variable is
+ *	created. Otherwise, NULL is returned and an error message is left in
+ *	the interp's result if TCL_LEAVE_ERR_MSG is set in flags.
+ *
+ *	Note: it's possible for the variable returned to be VAR_UNDEFINED even
+ *	if createPart1 or createPart2 are 1 (these only cause the hash table
+ *	entry or array to be created). For example, the variable might be a
+ *	global that has been unset but is still referenced by a procedure, or
+ *	a variable that has been unset but it only being kept in existence (if
+ *	VAR_UNDEFINED) by a trace.
+ *
+ * Side effects:
+ *	The variable at arrayPtr may be converted to be an array if
+ *	createPart1 is 1. A new hashtable entry may be created if createPart2
+ *	is 1.
+ *	When createElem is 1, callers must incr elNamePtr if they plan
+ *	to decr it.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Var *
+TclLookupArrayElement(
+    Tcl_Interp *interp,		/* Interpreter to use for lookup. */
+    Tcl_Obj *arrayNamePtr,	/* This is the name of the array, or NULL if
+				 * index>= 0. */
+    Tcl_Obj *elNamePtr,		/* Name of element within array. */
+    const int flags,		/* Only TCL_LEAVE_ERR_MSG bit matters. */
+    const char *msg,		/* Verb to use in error messages, e.g. "read"
+				 * or "set". Only needed if TCL_LEAVE_ERR_MSG
+				 * is set in flags. */
+    const int createArray,	/* If 1, transform arrayName to be an array if
+				 * it isn't one yet and the transformation is
+				 * possible. If 0, return error if it isn't
+				 * already an array. */
+    const int createElem,	/* If 1, create hash table entry for the
+				 * element, if it doesn't already exist. If 0,
+				 * return error if it doesn't exist. */
+    Var *arrayPtr,		/* Pointer to the array's Var structure. */
+    int index)			/* If >=0, the index of the local array. */
+{
+    int isNew;
+    Var *varPtr;
+    TclVarHashTable *tablePtr;
+    Namespace *nsPtr;
+
+    /*
+     * We're dealing with an array element. Make sure the variable is an array
+     * and look up the element (create the element if desired).
+     */
+
+    if (TclIsVarUndefined(arrayPtr) && !TclIsVarArrayElement(arrayPtr)) {
+	if (!createArray) {
+	    if (flags & TCL_LEAVE_ERR_MSG) {
+		TclObjVarErrMsg(interp, arrayNamePtr, elNamePtr, msg,
+			noSuchVar, index);
+		Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "VARNAME",
+			arrayNamePtr?TclGetString(arrayNamePtr):NULL, NULL);
+	    }
+	    return NULL;
+	}
+
+	/*
+	 * Make sure we are not resurrecting a namespace variable from a
+	 * deleted namespace!
+	 */
+
+	if (TclIsVarDeadHash(arrayPtr)) {
+	    if (flags & TCL_LEAVE_ERR_MSG) {
+		TclObjVarErrMsg(interp, arrayNamePtr, elNamePtr, msg,
+			danglingVar, index);
+		Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "VARNAME",
+			arrayNamePtr?TclGetString(arrayNamePtr):NULL, NULL);
+	    }
+	    return NULL;
+	}
+
+	TclSetVarArray(arrayPtr);
+	tablePtr = ckalloc(sizeof(TclVarHashTable));
+	arrayPtr->value.tablePtr = tablePtr;
+
+	if (TclIsVarInHash(arrayPtr) && TclGetVarNsPtr(arrayPtr)) {
+	    nsPtr = TclGetVarNsPtr(arrayPtr);
+	} else {
+	    nsPtr = NULL;
+	}
+	TclInitVarHashTable(arrayPtr->value.tablePtr, nsPtr);
+    } else if (!TclIsVarArray(arrayPtr)) {
+	if (flags & TCL_LEAVE_ERR_MSG) {
+	    TclObjVarErrMsg(interp, arrayNamePtr, elNamePtr, msg, needArray,
+		    index);
+	    Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "VARNAME",
+		    arrayNamePtr?TclGetString(arrayNamePtr):NULL, NULL);
+	}
+	return NULL;
+    }
+
+    if (createElem) {
+	varPtr = VarHashCreateVar(arrayPtr->value.tablePtr, elNamePtr,
+		&isNew);
+	if (isNew) {
+	    if (arrayPtr->flags & VAR_SEARCH_ACTIVE) {
+		DeleteSearches((Interp *) interp, arrayPtr);
+	    }
+	    TclSetVarArrayElement(varPtr);
+	}
+    } else {
+	varPtr = VarHashFindVar(arrayPtr->value.tablePtr, elNamePtr);
+	if (varPtr == NULL) {
+	    if (flags & TCL_LEAVE_ERR_MSG) {
+		TclObjVarErrMsg(interp, arrayNamePtr, elNamePtr, msg,
+			noSuchElement, index);
+		Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "ELEMENT",
+			TclGetString(elNamePtr), NULL);
+	    }
+	}
+    }
+    return varPtr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_GetVar --
+ *
+ *	Return the value of a Tcl variable as a string.
+ *
+ * Results:
+ *	The return value points to the current value of varName as a string.
+ *	If the variable is not defined or can't be read because of a clash in
+ *	array usage then a NULL pointer is returned and an error message is
+ *	left in the interp's result if the TCL_LEAVE_ERR_MSG flag is set.
+ *	Note: the return value is only valid up until the next change to the
+ *	variable; if you depend on the value lasting longer than that, then
+ *	make yourself a private copy.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+#undef Tcl_GetVar
+const char *
+Tcl_GetVar(
+    Tcl_Interp *interp,		/* Command interpreter in which varName is to
+				 * be looked up. */
+    const char *varName,	/* Name of a variable in interp. */
+    int flags)			/* OR-ed combination of TCL_GLOBAL_ONLY,
+				 * TCL_NAMESPACE_ONLY or TCL_LEAVE_ERR_MSG
+				 * bits. */
+{
+    Tcl_Obj *varNamePtr = Tcl_NewStringObj(varName, -1);
+    Tcl_Obj *resultPtr = Tcl_ObjGetVar2(interp, varNamePtr, NULL, flags);
+
+    TclDecrRefCount(varNamePtr);
+
+    if (resultPtr == NULL) {
+	return NULL;
+    }
+    return TclGetString(resultPtr);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_GetVar2 --
+ *
+ *	Return the value of a Tcl variable as a string, given a two-part name
+ *	consisting of array name and element within array.
+ *
+ * Results:
+ *	The return value points to the current value of the variable given by
+ *	part1 and part2 as a string. If the specified variable doesn't exist,
+ *	or if there is a clash in array usage, then NULL is returned and a
+ *	message will be left in the interp's result if the TCL_LEAVE_ERR_MSG
+ *	flag is set. Note: the return value is only valid up until the next
+ *	change to the variable; if you depend on the value lasting longer than
+ *	that, then make yourself a private copy.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+const char *
+Tcl_GetVar2(
+    Tcl_Interp *interp,		/* Command interpreter in which variable is to
+				 * be looked up. */
+    const char *part1,		/* Name of an array (if part2 is non-NULL) or
+				 * the name of a variable. */
+    const char *part2,		/* If non-NULL, gives the name of an element
+				 * in the array part1. */
+    int flags)			/* OR-ed combination of TCL_GLOBAL_ONLY,
+				 * TCL_NAMESPACE_ONLY and TCL_LEAVE_ERR_MSG *
+				 * bits. */
+{
+    Tcl_Obj *resultPtr;
+    Tcl_Obj *part2Ptr = NULL, *part1Ptr = Tcl_NewStringObj(part1, -1);
+
+    if (part2) {
+	part2Ptr = Tcl_NewStringObj(part2, -1);
+	Tcl_IncrRefCount(part2Ptr);
+    }
+
+    resultPtr = Tcl_ObjGetVar2(interp, part1Ptr, part2Ptr, flags);
+
+    Tcl_DecrRefCount(part1Ptr);
+    if (part2Ptr) {
+	Tcl_DecrRefCount(part2Ptr);
+    }
+    if (resultPtr == NULL) {
+	return NULL;
+    }
+    return TclGetString(resultPtr);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_GetVar2Ex --
+ *
+ *	Return the value of a Tcl variable as a Tcl object, given a two-part
+ *	name consisting of array name and element within array.
+ *
+ * Results:
+ *	The return value points to the current object value of the variable
+ *	given by part1Ptr and part2Ptr. If the specified variable doesn't
+ *	exist, or if there is a clash in array usage, then NULL is returned
+ *	and a message will be left in the interpreter's result if the
+ *	TCL_LEAVE_ERR_MSG flag is set.
+ *
+ * Side effects:
+ *	The ref count for the returned object is _not_ incremented to reflect
+ *	the returned reference; if you want to keep a reference to the object
+ *	you must increment its ref count yourself.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_Obj *
+Tcl_GetVar2Ex(
+    Tcl_Interp *interp,		/* Command interpreter in which variable is to
+				 * be looked up. */
+    const char *part1,		/* Name of an array (if part2 is non-NULL) or
+				 * the name of a variable. */
+    const char *part2,		/* If non-NULL, gives the name of an element
+				 * in the array part1. */
+    int flags)			/* OR-ed combination of TCL_GLOBAL_ONLY, and
+				 * TCL_LEAVE_ERR_MSG bits. */
+{
+    Tcl_Obj *resPtr, *part2Ptr = NULL, *part1Ptr = Tcl_NewStringObj(part1, -1);
+
+    if (part2) {
+	part2Ptr = Tcl_NewStringObj(part2, -1);
+	Tcl_IncrRefCount(part2Ptr);
+    }
+
+    resPtr = Tcl_ObjGetVar2(interp, part1Ptr, part2Ptr, flags);
+
+    Tcl_DecrRefCount(part1Ptr);
+    if (part2Ptr) {
+	Tcl_DecrRefCount(part2Ptr);
+    }
+
+    return resPtr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_ObjGetVar2 --
+ *
+ *	Return the value of a Tcl variable as a Tcl object, given a two-part
+ *	name consisting of array name and element within array.
+ *
+ * Results:
+ *	The return value points to the current object value of the variable
+ *	given by part1Ptr and part2Ptr. If the specified variable doesn't
+ *	exist, or if there is a clash in array usage, then NULL is returned
+ *	and a message will be left in the interpreter's result if the
+ *	TCL_LEAVE_ERR_MSG flag is set.
+ *
+ * Side effects:
+ *	The ref count for the returned object is _not_ incremented to reflect
+ *	the returned reference; if you want to keep a reference to the object
+ *	you must increment its ref count yourself.
+ *
+ *	Callers must incr part2Ptr if they plan to decr it.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_Obj *
+Tcl_ObjGetVar2(
+    Tcl_Interp *interp,		/* Command interpreter in which variable is to
+				 * be looked up. */
+    register Tcl_Obj *part1Ptr,	/* Points to an object holding the name of an
+				 * array (if part2 is non-NULL) or the name of
+				 * a variable. */
+    register Tcl_Obj *part2Ptr,	/* If non-null, points to an object holding
+				 * the name of an element in the array
+				 * part1Ptr. */
+    int flags)			/* OR-ed combination of TCL_GLOBAL_ONLY and
+				 * TCL_LEAVE_ERR_MSG bits. */
+{
+    Var *varPtr, *arrayPtr;
+
+    /*
+     * Filter to pass through only the flags this interface supports.
+     */
+
+    flags &= (TCL_GLOBAL_ONLY|TCL_NAMESPACE_ONLY|TCL_LEAVE_ERR_MSG);
+    varPtr = TclObjLookupVarEx(interp, part1Ptr, part2Ptr, flags, "read",
+	    /*createPart1*/ 0, /*createPart2*/ 1, &arrayPtr);
+    if (varPtr == NULL) {
+	return NULL;
+    }
+
+    return TclPtrGetVar(interp, varPtr, arrayPtr, part1Ptr, part2Ptr,
+	    flags, -1);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclPtrGetVar --
+ *
+ *	Return the value of a Tcl variable as a Tcl object, given the pointers
+ *	to the variable's (and possibly containing array's) VAR structure.
+ *
+ * Results:
+ *	The return value points to the current object value of the variable
+ *	given by varPtr. If the specified variable doesn't exist, or if there
+ *	is a clash in array usage, then NULL is returned and a message will be
+ *	left in the interpreter's result if the TCL_LEAVE_ERR_MSG flag is set.
+ *
+ * Side effects:
+ *	The ref count for the returned object is _not_ incremented to reflect
+ *	the returned reference; if you want to keep a reference to the object
+ *	you must increment its ref count yourself.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_Obj *
+TclPtrGetVar(
+    Tcl_Interp *interp,		/* Command interpreter in which variable is to
+				 * be looked up. */
+    register Var *varPtr,	/* The variable to be read.*/
+    Var *arrayPtr,		/* NULL for scalar variables, pointer to the
+				 * containing array otherwise. */
+    Tcl_Obj *part1Ptr,		/* Name of an array (if part2 is non-NULL) or
+				 * the name of a variable. */
+    Tcl_Obj *part2Ptr,		/* If non-NULL, gives the name of an element
+				 * in the array part1. */
+    const int flags,		/* OR-ed combination of TCL_GLOBAL_ONLY, and
+				 * TCL_LEAVE_ERR_MSG bits. */
+    int index)			/* Index into the local variable table of the
+				 * variable, or -1. Only used when part1Ptr is
+				 * NULL. */
+{
+    Interp *iPtr = (Interp *) interp;
+    const char *msg;
+
+    /*
+     * Invoke any read traces that have been set for the variable.
+     */
+
+    if ((varPtr->flags & VAR_TRACED_READ)
+	    || (arrayPtr && (arrayPtr->flags & VAR_TRACED_READ))) {
+	if (TCL_ERROR == TclObjCallVarTraces(iPtr, arrayPtr, varPtr,
+		part1Ptr, part2Ptr,
+		(flags & (TCL_NAMESPACE_ONLY|TCL_GLOBAL_ONLY))
+		| TCL_TRACE_READS, (flags & TCL_LEAVE_ERR_MSG), index)) {
+	    goto errorReturn;
+	}
+    }
+
+    /*
+     * Return the element if it's an existing scalar variable.
+     */
+
+    if (TclIsVarScalar(varPtr) && !TclIsVarUndefined(varPtr)) {
+	return varPtr->value.objPtr;
+    }
+
+    if (flags & TCL_LEAVE_ERR_MSG) {
+	if (TclIsVarUndefined(varPtr) && arrayPtr
+		&& !TclIsVarUndefined(arrayPtr)) {
+	    msg = noSuchElement;
+	} else if (TclIsVarArray(varPtr)) {
+	    msg = isArray;
+	} else {
+	    msg = noSuchVar;
+	}
+	TclObjVarErrMsg(interp, part1Ptr, part2Ptr, "read", msg, index);
+    }
+
+    /*
+     * An error. If the variable doesn't exist anymore and no-one's using it,
+     * then free up the relevant structures and hash table entries.
+     */
+
+  errorReturn:
+    Tcl_SetErrorCode(interp, "TCL", "READ", "VARNAME", NULL);
+    if (TclIsVarUndefined(varPtr)) {
+	TclCleanupVar(varPtr, arrayPtr);
+    }
+    return NULL;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_SetObjCmd --
+ *
+ *	This function is invoked to process the "set" Tcl command. See the
+ *	user documentation for details on what it does.
+ *
+ * Results:
+ *	A standard Tcl result value.
+ *
+ * Side effects:
+ *	A variable's value may be changed.
+ *
+ *----------------------------------------------------------------------
+ */
+
+	/* ARGSUSED */
+int
+Tcl_SetObjCmd(
+    ClientData dummy,		/* Not used. */
+    register Tcl_Interp *interp,/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    Tcl_Obj *varValueObj;
+
+    if (objc == 2) {
+	varValueObj = Tcl_ObjGetVar2(interp, objv[1], NULL,TCL_LEAVE_ERR_MSG);
+	if (varValueObj == NULL) {
+	    return TCL_ERROR;
+	}
+	Tcl_SetObjResult(interp, varValueObj);
+	return TCL_OK;
+    } else if (objc == 3) {
+	varValueObj = Tcl_ObjSetVar2(interp, objv[1], NULL, objv[2],
+		TCL_LEAVE_ERR_MSG);
+	if (varValueObj == NULL) {
+	    return TCL_ERROR;
+	}
+	Tcl_SetObjResult(interp, varValueObj);
+	return TCL_OK;
+    } else {
+	Tcl_WrongNumArgs(interp, 1, objv, "varName ?newValue?");
+	return TCL_ERROR;
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_SetVar --
+ *
+ *	Change the value of a variable.
+ *
+ * Results:
+ *	Returns a pointer to the malloc'ed string which is the character
+ *	representation of the variable's new value. The caller must not modify
+ *	this string. If the write operation was disallowed then NULL is
+ *	returned; if the TCL_LEAVE_ERR_MSG flag is set, then an explanatory
+ *	message will be left in the interp's result. Note that the returned
+ *	string may not be the same as newValue; this is because variable
+ *	traces may modify the variable's value.
+ *
+ * Side effects:
+ *	If varName is defined as a local or global variable in interp, its
+ *	value is changed to newValue. If varName isn't currently defined, then
+ *	a new global variable by that name is created.
+ *
+ *----------------------------------------------------------------------
+ */
+
+#undef Tcl_SetVar
+const char *
+Tcl_SetVar(
+    Tcl_Interp *interp,		/* Command interpreter in which varName is to
+				 * be looked up. */
+    const char *varName,	/* Name of a variable in interp. */
+    const char *newValue,	/* New value for varName. */
+    int flags)			/* Various flags that tell how to set value:
+				 * any of TCL_GLOBAL_ONLY, TCL_NAMESPACE_ONLY,
+				 * TCL_APPEND_VALUE, TCL_LIST_ELEMENT,
+				 * TCL_LEAVE_ERR_MSG. */
+{
+    Tcl_Obj *varValuePtr, *varNamePtr = Tcl_NewStringObj(varName, -1);
+
+    Tcl_IncrRefCount(varNamePtr);
+    varValuePtr = Tcl_ObjSetVar2(interp, varNamePtr, NULL,
+	    Tcl_NewStringObj(newValue, -1), flags);
+    Tcl_DecrRefCount(varNamePtr);
+
+    if (varValuePtr == NULL) {
+	return NULL;
+    }
+    return TclGetString(varValuePtr);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_SetVar2 --
+ *
+ *	Given a two-part variable name, which may refer either to a scalar
+ *	variable or an element of an array, change the value of the variable.
+ *	If the named scalar or array or element doesn't exist then create one.
+ *
+ * Results:
+ *	Returns a pointer to the malloc'ed string which is the character
+ *	representation of the variable's new value. The caller must not modify
+ *	this string. If the write operation was disallowed because an array
+ *	was expected but not found (or vice versa), then NULL is returned; if
+ *	the TCL_LEAVE_ERR_MSG flag is set, then an explanatory message will be
+ *	left in the interp's result. Note that the returned string may not be
+ *	the same as newValue; this is because variable traces may modify the
+ *	variable's value.
+ *
+ * Side effects:
+ *	The value of the given variable is set. If either the array or the
+ *	entry didn't exist then a new one is created.
+ *
+ *----------------------------------------------------------------------
+ */
+
+const char *
+Tcl_SetVar2(
+    Tcl_Interp *interp,		/* Command interpreter in which variable is to
+				 * be looked up. */
+    const char *part1,		/* If part2 is NULL, this is name of scalar
+				 * variable. Otherwise it is the name of an
+				 * array. */
+    const char *part2,		/* Name of an element within an array, or
+				 * NULL. */
+    const char *newValue,	/* New value for variable. */
+    int flags)			/* Various flags that tell how to set value:
+				 * any of TCL_GLOBAL_ONLY, TCL_NAMESPACE_ONLY,
+				 * TCL_APPEND_VALUE, TCL_LIST_ELEMENT, or
+				 * TCL_LEAVE_ERR_MSG. */
+{
+    Tcl_Obj *varValuePtr = Tcl_SetVar2Ex(interp, part1, part2,
+	    Tcl_NewStringObj(newValue, -1), flags);
+
+    if (varValuePtr == NULL) {
+	return NULL;
+    }
+    return TclGetString(varValuePtr);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_SetVar2Ex --
+ *
+ *	Given a two-part variable name, which may refer either to a scalar
+ *	variable or an element of an array, change the value of the variable
+ *	to a new Tcl object value. If the named scalar or array or element
+ *	doesn't exist then create one.
+ *
+ * Results:
+ *	Returns a pointer to the Tcl_Obj holding the new value of the
+ *	variable. If the write operation was disallowed because an array was
+ *	expected but not found (or vice versa), then NULL is returned; if the
+ *	TCL_LEAVE_ERR_MSG flag is set, then an explanatory message will be
+ *	left in the interpreter's result. Note that the returned object may
+ *	not be the same one referenced by newValuePtr; this is because
+ *	variable traces may modify the variable's value.
+ *
+ * Side effects:
+ *	The value of the given variable is set. If either the array or the
+ *	entry didn't exist then a new variable is created.
+ *
+ *	The reference count is decremented for any old value of the variable
+ *	and incremented for its new value. If the new value for the variable
+ *	is not the same one referenced by newValuePtr (perhaps as a result of
+ *	a variable trace), then newValuePtr's ref count is left unchanged by
+ *	Tcl_SetVar2Ex. newValuePtr's ref count is also left unchanged if we
+ *	are appending it as a string value: that is, if "flags" includes
+ *	TCL_APPEND_VALUE but not TCL_LIST_ELEMENT.
+ *
+ *	The reference count for the returned object is _not_ incremented: if
+ *	you want to keep a reference to the object you must increment its ref
+ *	count yourself.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_Obj *
+Tcl_SetVar2Ex(
+    Tcl_Interp *interp,		/* Command interpreter in which variable is to
+				 * be found. */
+    const char *part1,		/* Name of an array (if part2 is non-NULL) or
+				 * the name of a variable. */
+    const char *part2,		/* If non-NULL, gives the name of an element
+				 * in the array part1. */
+    Tcl_Obj *newValuePtr,	/* New value for variable. */
+    int flags)			/* Various flags that tell how to set value:
+				 * any of TCL_GLOBAL_ONLY, TCL_NAMESPACE_ONLY,
+				 * TCL_APPEND_VALUE, TCL_LIST_ELEMENT or
+				 * TCL_LEAVE_ERR_MSG. */
+{
+    Tcl_Obj *resPtr, *part2Ptr = NULL, *part1Ptr = Tcl_NewStringObj(part1, -1);
+
+    Tcl_IncrRefCount(part1Ptr);
+    if (part2) {
+	part2Ptr = Tcl_NewStringObj(part2, -1);
+	Tcl_IncrRefCount(part2Ptr);
+    }
+
+    resPtr = Tcl_ObjSetVar2(interp, part1Ptr, part2Ptr, newValuePtr, flags);
+
+    Tcl_DecrRefCount(part1Ptr);
+    if (part2Ptr) {
+	Tcl_DecrRefCount(part2Ptr);
+    }
+
+    return resPtr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_ObjSetVar2 --
+ *
+ *	This function is the same as Tcl_SetVar2Ex above, except the variable
+ *	names are passed in Tcl object instead of strings.
+ *
+ * Results:
+ *	Returns a pointer to the Tcl_Obj holding the new value of the
+ *	variable. If the write operation was disallowed because an array was
+ *	expected but not found (or vice versa), then NULL is returned; if the
+ *	TCL_LEAVE_ERR_MSG flag is set, then an explanatory message will be
+ *	left in the interpreter's result. Note that the returned object may
+ *	not be the same one referenced by newValuePtr; this is because
+ *	variable traces may modify the variable's value.
+ *
+ * Side effects:
+ *	The value of the given variable is set. If either the array or the
+ *	entry didn't exist then a new variable is created.
+ *	Callers must Incr part1Ptr if they plan to Decr it.
+ *	Callers must Incr part2Ptr if they plan to Decr it.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_Obj *
+Tcl_ObjSetVar2(
+    Tcl_Interp *interp,		/* Command interpreter in which variable is to
+				 * be found. */
+    register Tcl_Obj *part1Ptr,	/* Points to an object holding the name of an
+				 * array (if part2 is non-NULL) or the name of
+				 * a variable. */
+    register Tcl_Obj *part2Ptr,	/* If non-NULL, points to an object holding
+				 * the name of an element in the array
+				 * part1Ptr. */
+    Tcl_Obj *newValuePtr,	/* New value for variable. */
+    int flags)			/* Various flags that tell how to set value:
+				 * any of TCL_GLOBAL_ONLY, TCL_NAMESPACE_ONLY,
+				 * TCL_APPEND_VALUE, TCL_LIST_ELEMENT, or
+				 * TCL_LEAVE_ERR_MSG. */
+{
+    Var *varPtr, *arrayPtr;
+
+    /*
+     * Filter to pass through only the flags this interface supports.
+     */
+
+    flags &= (TCL_GLOBAL_ONLY|TCL_NAMESPACE_ONLY|TCL_LEAVE_ERR_MSG
+	    |TCL_APPEND_VALUE|TCL_LIST_ELEMENT);
+    varPtr = TclObjLookupVarEx(interp, part1Ptr, part2Ptr, flags, "set",
+	    /*createPart1*/ 1, /*createPart2*/ 1, &arrayPtr);
+    if (varPtr == NULL) {
+	if (newValuePtr->refCount == 0) {
+	    Tcl_DecrRefCount(newValuePtr);
+	}
+	return NULL;
+    }
+
+    return TclPtrSetVar(interp, varPtr, arrayPtr, part1Ptr, part2Ptr,
+	    newValuePtr, flags, -1);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclPtrSetVar --
+ *
+ *	This function is the same as Tcl_SetVar2Ex above, except that it
+ *	requires pointers to the variable's Var structs in addition to the
+ *	variable names.
+ *
+ * Results:
+ *	Returns a pointer to the Tcl_Obj holding the new value of the
+ *	variable. If the write operation was disallowed because an array was
+ *	expected but not found (or vice versa), then NULL is returned; if the
+ *	TCL_LEAVE_ERR_MSG flag is set, then an explanatory message will be
+ *	left in the interpreter's result. Note that the returned object may
+ *	not be the same one referenced by newValuePtr; this is because
+ *	variable traces may modify the variable's value.
+ *
+ * Side effects:
+ *	The value of the given variable is set. If either the array or the
+ *	entry didn't exist then a new variable is created.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_Obj *
+TclPtrSetVar(
+    Tcl_Interp *interp,		/* Command interpreter in which variable is to
+				 * be looked up. */
+    register Var *varPtr,	/* Reference to the variable to set. */
+    Var *arrayPtr,		/* Reference to the array containing the
+				 * variable, or NULL if the variable is a
+				 * scalar. */
+    Tcl_Obj *part1Ptr,		/* Name of an array (if part2 is non-NULL) or
+				 * the name of a variable. NULL if the 'index'
+				 * parameter is >= 0 */
+    Tcl_Obj *part2Ptr,		/* If non-NULL, gives the name of an element
+				 * in the array part1. */
+    Tcl_Obj *newValuePtr,	/* New value for variable. */
+    const int flags,		/* OR-ed combination of TCL_GLOBAL_ONLY, and
+				 * TCL_LEAVE_ERR_MSG bits. */
+    int index)			/* Index of local var where part1 is to be
+				 * found. */
+{
+    Interp *iPtr = (Interp *) interp;
+    Tcl_Obj *oldValuePtr;
+    Tcl_Obj *resultPtr = NULL;
+    int result;
+    int cleanupOnEarlyError = (newValuePtr->refCount == 0);
+
+    /*
+     * If the variable is in a hashtable and its hPtr field is NULL, then we
+     * may have an upvar to an array element where the array was deleted or an
+     * upvar to a namespace variable whose namespace was deleted. Generate an
+     * error (allowing the variable to be reset would screw up our storage
+     * allocation and is meaningless anyway).
+     */
+
+    if (TclIsVarDeadHash(varPtr)) {
+	if (flags & TCL_LEAVE_ERR_MSG) {
+	    if (TclIsVarArrayElement(varPtr)) {
+		TclObjVarErrMsg(interp, part1Ptr, part2Ptr, "set",
+			danglingElement, index);
+		Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "ELEMENT", NULL);
+	    } else {
+		TclObjVarErrMsg(interp, part1Ptr, part2Ptr, "set",
+			danglingVar, index);
+		Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "VARNAME", NULL);
+	    }
+	}
+	goto earlyError;
+    }
+
+    /*
+     * It's an error to try to set an array variable itself.
+     */
+
+    if (TclIsVarArray(varPtr)) {
+	if (flags & TCL_LEAVE_ERR_MSG) {
+	    TclObjVarErrMsg(interp, part1Ptr, part2Ptr, "set", isArray,index);
+	    Tcl_SetErrorCode(interp, "TCL", "WRITE", "ARRAY", NULL);
+	}
+	goto earlyError;
+    }
+
+    /*
+     * Invoke any read traces that have been set for the variable if it is
+     * requested. This was done for INST_LAPPEND_* but that was inconsistent
+     * with the non-bc instruction, and would cause failures trying to
+     * lappend to any non-existing ::env var, which is inconsistent with
+     * documented behavior. [Bug #3057639].
+     */
+
+    if ((flags & TCL_TRACE_READS) && ((varPtr->flags & VAR_TRACED_READ)
+	    || (arrayPtr && (arrayPtr->flags & VAR_TRACED_READ)))) {
+	if (TCL_ERROR == TclObjCallVarTraces(iPtr, arrayPtr, varPtr,
+		part1Ptr, part2Ptr,
+		TCL_TRACE_READS, (flags & TCL_LEAVE_ERR_MSG), index)) {
+	    goto earlyError;
+	}
+    }
+
+    /*
+     * Set the variable's new value. If appending, append the new value to the
+     * variable, either as a list element or as a string. Also, if appending,
+     * then if the variable's old value is unshared we can modify it directly,
+     * otherwise we must create a new copy to modify: this is "copy on write".
+     */
+
+    oldValuePtr = varPtr->value.objPtr;
+    if (flags & TCL_LIST_ELEMENT && !(flags & TCL_APPEND_VALUE)) {
+	varPtr->value.objPtr = NULL;
+    }
+    if (flags & (TCL_APPEND_VALUE|TCL_LIST_ELEMENT)) {
+	if (flags & TCL_LIST_ELEMENT) {		/* Append list element. */
+	    if (oldValuePtr == NULL) {
+		TclNewObj(oldValuePtr);
+		varPtr->value.objPtr = oldValuePtr;
+		Tcl_IncrRefCount(oldValuePtr);	/* Since var is referenced. */
+	    } else if (Tcl_IsShared(oldValuePtr)) {
+		varPtr->value.objPtr = Tcl_DuplicateObj(oldValuePtr);
+		TclDecrRefCount(oldValuePtr);
+		oldValuePtr = varPtr->value.objPtr;
+		Tcl_IncrRefCount(oldValuePtr);	/* Since var is referenced. */
+	    }
+	    result = Tcl_ListObjAppendElement(interp, oldValuePtr,
+		    newValuePtr);
+	    if (result != TCL_OK) {
+		goto earlyError;
+	    }
+	} else {				/* Append string. */
+	    /*
+	     * We append newValuePtr's bytes but don't change its ref count.
+	     */
+
+	    if (oldValuePtr == NULL) {
+		varPtr->value.objPtr = newValuePtr;
+		Tcl_IncrRefCount(newValuePtr);
+	    } else {
+		if (Tcl_IsShared(oldValuePtr)) {	/* Append to copy. */
+		    varPtr->value.objPtr = Tcl_DuplicateObj(oldValuePtr);
+
+		    TclContinuationsCopy(varPtr->value.objPtr, oldValuePtr);
+
+		    TclDecrRefCount(oldValuePtr);
+		    oldValuePtr = varPtr->value.objPtr;
+		    Tcl_IncrRefCount(oldValuePtr);	/* Since var is ref */
+		}
+		Tcl_AppendObjToObj(oldValuePtr, newValuePtr);
+		if (newValuePtr->refCount == 0) {
+		    Tcl_DecrRefCount(newValuePtr);
+		}
+	    }
+	}
+    } else if (newValuePtr != oldValuePtr) {
+	/*
+	 * In this case we are replacing the value, so we don't need to do
+	 * more than swap the objects.
+	 */
+
+	varPtr->value.objPtr = newValuePtr;
+	Tcl_IncrRefCount(newValuePtr);		/* Var is another ref. */
+	if (oldValuePtr != NULL) {
+	    TclDecrRefCount(oldValuePtr);	/* Discard old value. */
+	}
+    }
+
+    /*
+     * Invoke any write traces for the variable.
+     */
+
+    if ((varPtr->flags & VAR_TRACED_WRITE)
+	    || (arrayPtr && (arrayPtr->flags & VAR_TRACED_WRITE))) {
+	if (TCL_ERROR == TclObjCallVarTraces(iPtr, arrayPtr, varPtr, part1Ptr,
+		part2Ptr, (flags & (TCL_GLOBAL_ONLY|TCL_NAMESPACE_ONLY))
+		| TCL_TRACE_WRITES, (flags & TCL_LEAVE_ERR_MSG), index)) {
+	    goto cleanup;
+	}
+    }
+
+    /*
+     * Return the variable's value unless the variable was changed in some
+     * gross way by a trace (e.g. it was unset and then recreated as an
+     * array).
+     */
+
+    if (TclIsVarScalar(varPtr) && !TclIsVarUndefined(varPtr)) {
+	return varPtr->value.objPtr;
+    }
+
+    /*
+     * A trace changed the value in some gross way. Return an empty string
+     * object.
+     */
+
+    resultPtr = iPtr->emptyObjPtr;
+
+    /*
+     * If the variable doesn't exist anymore and no-one's using it, then free
+     * up the relevant structures and hash table entries.
+     */
+
+  cleanup:
+    if (resultPtr == NULL) {
+	Tcl_SetErrorCode(interp, "TCL", "WRITE", "VARNAME", NULL);
+    }
+    if (TclIsVarUndefined(varPtr)) {
+	TclCleanupVar(varPtr, arrayPtr);
+    }
+    return resultPtr;
+
+  earlyError:
+    if (cleanupOnEarlyError) {
+	Tcl_DecrRefCount(newValuePtr);
+    }
+    goto cleanup;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclIncrObjVar2 --
+ *
+ *	Given a two-part variable name, which may refer either to a scalar
+ *	variable or an element of an array, increment the Tcl object value of
+ *	the variable by a specified Tcl_Obj increment value.
+ *
+ * Results:
+ *	Returns a pointer to the Tcl_Obj holding the new value of the
+ *	variable. If the specified variable doesn't exist, or there is a clash
+ *	in array usage, or an error occurs while executing variable traces,
+ *	then NULL is returned and a message will be left in the interpreter's
+ *	result.
+ *
+ * Side effects:
+ *	The value of the given variable is incremented by the specified
+ *	amount. If either the array or the entry didn't exist then a new
+ *	variable is created. The ref count for the returned object is _not_
+ *	incremented to reflect the returned reference; if you want to keep a
+ *	reference to the object you must increment its ref count yourself.
+ *	Callers must Incr part1Ptr if they plan to Decr it.
+ *	Callers must Incr part2Ptr if they plan to Decr it.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_Obj *
+TclIncrObjVar2(
+    Tcl_Interp *interp,		/* Command interpreter in which variable is to
+				 * be found. */
+    Tcl_Obj *part1Ptr,		/* Points to an object holding the name of an
+				 * array (if part2 is non-NULL) or the name of
+				 * a variable. */
+    Tcl_Obj *part2Ptr,		/* If non-null, points to an object holding
+				 * the name of an element in the array
+				 * part1Ptr. */
+    Tcl_Obj *incrPtr,		/* Amount to be added to variable. */
+    int flags)			/* Various flags that tell how to incr value:
+				 * any of TCL_GLOBAL_ONLY, TCL_NAMESPACE_ONLY,
+				 * TCL_APPEND_VALUE, TCL_LIST_ELEMENT,
+				 * TCL_LEAVE_ERR_MSG. */
+{
+    Var *varPtr, *arrayPtr;
+
+    varPtr = TclObjLookupVarEx(interp, part1Ptr, part2Ptr, flags, "read",
+	    1, 1, &arrayPtr);
+    if (varPtr == NULL) {
+	Tcl_AddErrorInfo(interp,
+		"\n    (reading value of variable to increment)");
+	return NULL;
+    }
+    return TclPtrIncrObjVar(interp, varPtr, arrayPtr, part1Ptr, part2Ptr,
+	    incrPtr, flags, -1);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclPtrIncrObjVar --
+ *
+ *	Given the pointers to a variable and possible containing array,
+ *	increment the Tcl object value of the variable by a Tcl_Obj increment.
+ *
+ * Results:
+ *	Returns a pointer to the Tcl_Obj holding the new value of the
+ *	variable. If the specified variable doesn't exist, or there is a clash
+ *	in array usage, or an error occurs while executing variable traces,
+ *	then NULL is returned and a message will be left in the interpreter's
+ *	result.
+ *
+ * Side effects:
+ *	The value of the given variable is incremented by the specified
+ *	amount. If either the array or the entry didn't exist then a new
+ *	variable is created. The ref count for the returned object is _not_
+ *	incremented to reflect the returned reference; if you want to keep a
+ *	reference to the object you must increment its ref count yourself.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_Obj *
+TclPtrIncrObjVar(
+    Tcl_Interp *interp,		/* Command interpreter in which variable is to
+				 * be found. */
+    Var *varPtr,		/* Reference to the variable to set. */
+    Var *arrayPtr,		/* Reference to the array containing the
+				 * variable, or NULL if the variable is a
+				 * scalar. */
+    Tcl_Obj *part1Ptr,		/* Points to an object holding the name of an
+				 * array (if part2 is non-NULL) or the name of
+				 * a variable. */
+    Tcl_Obj *part2Ptr,		/* If non-null, points to an object holding
+				 * the name of an element in the array
+				 * part1Ptr. */
+    Tcl_Obj *incrPtr,		/* Increment value. */
+/* TODO: Which of these flag values really make sense? */
+    const int flags,		/* Various flags that tell how to incr value:
+				 * any of TCL_GLOBAL_ONLY, TCL_NAMESPACE_ONLY,
+				 * TCL_APPEND_VALUE, TCL_LIST_ELEMENT,
+				 * TCL_LEAVE_ERR_MSG. */
+    int index)			/* Index into the local variable table of the
+				 * variable, or -1. Only used when part1Ptr is
+				 * NULL. */
+{
+    register Tcl_Obj *varValuePtr;
+
+    if (TclIsVarInHash(varPtr)) {
+	VarHashRefCount(varPtr)++;
+    }
+    varValuePtr = TclPtrGetVar(interp, varPtr, arrayPtr, part1Ptr, part2Ptr,
+	    flags, index);
+    if (TclIsVarInHash(varPtr)) {
+	VarHashRefCount(varPtr)--;
+    }
+    if (varValuePtr == NULL) {
+	varValuePtr = Tcl_NewIntObj(0);
+    }
+    if (Tcl_IsShared(varValuePtr)) {
+	/* Copy on write */
+	varValuePtr = Tcl_DuplicateObj(varValuePtr);
+
+	if (TCL_OK == TclIncrObj(interp, varValuePtr, incrPtr)) {
+	    return TclPtrSetVar(interp, varPtr, arrayPtr, part1Ptr, part2Ptr,
+		    varValuePtr, flags, index);
+	} else {
+	    Tcl_DecrRefCount(varValuePtr);
+	    return NULL;
+	}
+    } else {
+	/* Unshared - can Incr in place */
+	if (TCL_OK == TclIncrObj(interp, varValuePtr, incrPtr)) {
+
+	    /*
+	     * This seems dumb to write the incremeted value into the var
+	     * after we just adjusted the value in place, but the spec for
+	     * [incr] requires that write traces fire, and making this call
+	     * is the way to make that happen.
+	     */
+
+	    return TclPtrSetVar(interp, varPtr, arrayPtr, part1Ptr, part2Ptr,
+		    varValuePtr, flags, index);
+	} else {
+	    return NULL;
+	}
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_UnsetVar --
+ *
+ *	Delete a variable, so that it may not be accessed anymore.
+ *
+ * Results:
+ *	Returns TCL_OK if the variable was successfully deleted, TCL_ERROR if
+ *	the variable can't be unset. In the event of an error, if the
+ *	TCL_LEAVE_ERR_MSG flag is set then an error message is left in the
+ *	interp's result.
+ *
+ * Side effects:
+ *	If varName is defined as a local or global variable in interp, it is
+ *	deleted.
+ *
+ *----------------------------------------------------------------------
+ */
+
+#undef Tcl_UnsetVar
+int
+Tcl_UnsetVar(
+    Tcl_Interp *interp,		/* Command interpreter in which varName is to
+				 * be looked up. */
+    const char *varName,	/* Name of a variable in interp. May be either
+				 * a scalar name or an array name or an
+				 * element in an array. */
+    int flags)			/* OR-ed combination of any of
+				 * TCL_GLOBAL_ONLY, TCL_NAMESPACE_ONLY or
+				 * TCL_LEAVE_ERR_MSG. */
+{
+    int result;
+    Tcl_Obj *varNamePtr;
+
+    varNamePtr = Tcl_NewStringObj(varName, -1);
+    Tcl_IncrRefCount(varNamePtr);
+
+    /*
+     * Filter to pass through only the flags this interface supports.
+     */
+
+    flags &= (TCL_GLOBAL_ONLY|TCL_NAMESPACE_ONLY|TCL_LEAVE_ERR_MSG);
+    result = TclObjUnsetVar2(interp, varNamePtr, NULL, flags);
+
+    Tcl_DecrRefCount(varNamePtr);
+    return result;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_UnsetVar2 --
+ *
+ *	Delete a variable, given a 2-part name.
+ *
+ * Results:
+ *	Returns TCL_OK if the variable was successfully deleted, TCL_ERROR if
+ *	the variable can't be unset. In the event of an error, if the
+ *	TCL_LEAVE_ERR_MSG flag is set then an error message is left in the
+ *	interp's result.
+ *
+ * Side effects:
+ *	If part1 and part2 indicate a local or global variable in interp, it
+ *	is deleted. If part1 is an array name and part2 is NULL, then the
+ *	whole array is deleted.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_UnsetVar2(
+    Tcl_Interp *interp,		/* Command interpreter in which varName is to
+				 * be looked up. */
+    const char *part1,		/* Name of variable or array. */
+    const char *part2,		/* Name of element within array or NULL. */
+    int flags)			/* OR-ed combination of any of
+				 * TCL_GLOBAL_ONLY, TCL_NAMESPACE_ONLY,
+				 * TCL_LEAVE_ERR_MSG. */
+{
+    int result;
+    Tcl_Obj *part2Ptr = NULL, *part1Ptr = Tcl_NewStringObj(part1, -1);
+
+    if (part2) {
+	part2Ptr = Tcl_NewStringObj(part2, -1);
+    }
+
+    /*
+     * Filter to pass through only the flags this interface supports.
+     */
+
+    flags &= (TCL_GLOBAL_ONLY|TCL_NAMESPACE_ONLY|TCL_LEAVE_ERR_MSG);
+    result = TclObjUnsetVar2(interp, part1Ptr, part2Ptr, flags);
+
+    Tcl_DecrRefCount(part1Ptr);
+    if (part2Ptr) {
+	Tcl_DecrRefCount(part2Ptr);
+    }
+    return result;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclObjUnsetVar2 --
+ *
+ *	Delete a variable, given a 2-object name.
+ *
+ * Results:
+ *	Returns TCL_OK if the variable was successfully deleted, TCL_ERROR if
+ *	the variable can't be unset. In the event of an error, if the
+ *	TCL_LEAVE_ERR_MSG flag is set then an error message is left in the
+ *	interp's result.
+ *
+ * Side effects:
+ *	If part1ptr and part2Ptr indicate a local or global variable in
+ *	interp, it is deleted. If part1Ptr is an array name and part2Ptr is
+ *	NULL, then the whole array is deleted.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclObjUnsetVar2(
+    Tcl_Interp *interp,		/* Command interpreter in which varName is to
+				 * be looked up. */
+    Tcl_Obj *part1Ptr,		/* Name of variable or array. */
+    Tcl_Obj *part2Ptr,		/* Name of element within array or NULL. */
+    int flags)			/* OR-ed combination of any of
+				 * TCL_GLOBAL_ONLY, TCL_NAMESPACE_ONLY,
+				 * TCL_LEAVE_ERR_MSG. */
+{
+    Var *varPtr, *arrayPtr;
+
+    varPtr = TclObjLookupVarEx(interp, part1Ptr, part2Ptr, flags, "unset",
+	    /*createPart1*/ 0, /*createPart2*/ 0, &arrayPtr);
+    if (varPtr == NULL) {
+	return TCL_ERROR;
+    }
+
+    return TclPtrUnsetVar(interp, varPtr, arrayPtr, part1Ptr, part2Ptr, flags,
+	    -1);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclPtrUnsetVar --
+ *
+ *	Delete a variable, given the pointers to the variable's (and possibly
+ *	containing array's) VAR structure.
+ *
+ * Results:
+ *	Returns TCL_OK if the variable was successfully deleted, TCL_ERROR if
+ *	the variable can't be unset. In the event of an error, if the
+ *	TCL_LEAVE_ERR_MSG flag is set then an error message is left in the
+ *	interp's result.
+ *
+ * Side effects:
+ *	If varPtr and arrayPtr indicate a local or global variable in interp,
+ *	it is deleted. If varPtr is an array reference and part2Ptr is NULL,
+ *	then the whole array is deleted.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclPtrUnsetVar(
+    Tcl_Interp *interp,		/* Command interpreter in which varName is to
+				 * be looked up. */
+    register Var *varPtr,	/* The variable to be unset. */
+    Var *arrayPtr,		/* NULL for scalar variables, pointer to the
+				 * containing array otherwise. */
+    Tcl_Obj *part1Ptr,		/* Name of an array (if part2 is non-NULL) or
+				 * the name of a variable. */
+    Tcl_Obj *part2Ptr,		/* If non-NULL, gives the name of an element
+				 * in the array part1. */
+    const int flags,		/* OR-ed combination of any of
+				 * TCL_GLOBAL_ONLY, TCL_NAMESPACE_ONLY,
+				 * TCL_LEAVE_ERR_MSG. */
+    int index)			/* Index into the local variable table of the
+				 * variable, or -1. Only used when part1Ptr is
+				 * NULL. */
+{
+    Interp *iPtr = (Interp *) interp;
+    int result = (TclIsVarUndefined(varPtr)? TCL_ERROR : TCL_OK);
+
+    /*
+     * Keep the variable alive until we're done with it. We used to
+     * increase/decrease the refCount for each operation, making it hard to
+     * find [Bug 735335] - caused by unsetting the variable whose value was
+     * the variable's name.
+     */
+
+    if (TclIsVarInHash(varPtr)) {
+	VarHashRefCount(varPtr)++;
+    }
+
+    UnsetVarStruct(varPtr, arrayPtr, iPtr, part1Ptr, part2Ptr, flags, index);
+
+    /*
+     * It's an error to unset an undefined variable.
+     */
+
+    if (result != TCL_OK) {
+	if (flags & TCL_LEAVE_ERR_MSG) {
+	    TclObjVarErrMsg(interp, part1Ptr, part2Ptr, "unset",
+		    ((arrayPtr == NULL) ? noSuchVar : noSuchElement), index);
+	    Tcl_SetErrorCode(interp, "TCL", "UNSET", "VARNAME", NULL);
+	}
+    }
+
+    /*
+     * Finally, if the variable is truly not in use then free up its Var
+     * structure and remove it from its hash table, if any. The ref count of
+     * its value object, if any, was decremented above.
+     */
+
+    if (TclIsVarInHash(varPtr)) {
+	VarHashRefCount(varPtr)--;
+	CleanupVar(varPtr, arrayPtr);
+    }
+    return result;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * UnsetVarStruct --
+ *
+ *	Unset and delete a variable. This does the internal work for
+ *	TclObjUnsetVar2 and TclDeleteNamespaceVars, which call here for each
+ *	variable to be unset and deleted.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	If the arguments indicate a local or global variable in iPtr, it is
+ *	unset and deleted.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+UnsetVarStruct(
+    Var *varPtr,
+    Var *arrayPtr,
+    Interp *iPtr,
+    Tcl_Obj *part1Ptr,
+    Tcl_Obj *part2Ptr,
+    int flags,
+    int index)
+{
+    Var dummyVar;
+    int traced = TclIsVarTraced(varPtr)
+	    || (arrayPtr && (arrayPtr->flags & VAR_TRACED_UNSET));
+
+    if (arrayPtr && (arrayPtr->flags & VAR_SEARCH_ACTIVE)) {
+	DeleteSearches(iPtr, arrayPtr);
+    } else if (varPtr->flags & VAR_SEARCH_ACTIVE) {
+	DeleteSearches(iPtr, varPtr);
+    }
+
+    /*
+     * The code below is tricky, because of the possibility that a trace
+     * function might try to access a variable being deleted. To handle this
+     * situation gracefully, do things in three steps:
+     * 1. Copy the contents of the variable to a dummy variable structure, and
+     *    mark the original Var structure as undefined.
+     * 2. Invoke traces and clean up the variable, using the dummy copy.
+     * 3. If at the end of this the original variable is still undefined and
+     *    has no outstanding references, then delete it (but it could have
+     *    gotten recreated by a trace).
+     */
+
+    dummyVar = *varPtr;
+    dummyVar.flags &= ~VAR_ALL_HASH;
+    TclSetVarUndefined(varPtr);
+
+    /*
+     * Call trace functions for the variable being deleted. Then delete its
+     * traces. Be sure to abort any other traces for the variable that are
+     * still pending. Special tricks:
+     * 1. We need to increment varPtr's refCount around this: TclCallVarTraces
+     *    will use dummyVar so it won't increment varPtr's refCount itself.
+     * 2. Turn off the VAR_TRACE_ACTIVE flag in dummyVar: we want to call
+     *    unset traces even if other traces are pending.
+     */
+
+    if (traced) {
+	VarTrace *tracePtr = NULL;
+	Tcl_HashEntry *tPtr;
+
+	if (TclIsVarTraced(&dummyVar)) {
+	    /*
+	     * Transfer any existing traces on var, IF there are unset traces.
+	     * Otherwise just delete them.
+	     */
+
+	    int isNew;
+
+	    tPtr = Tcl_FindHashEntry(&iPtr->varTraces, varPtr);
+	    tracePtr = Tcl_GetHashValue(tPtr);
+	    varPtr->flags &= ~VAR_ALL_TRACES;
+	    Tcl_DeleteHashEntry(tPtr);
+	    if (dummyVar.flags & VAR_TRACED_UNSET) {
+		tPtr = Tcl_CreateHashEntry(&iPtr->varTraces,
+			&dummyVar, &isNew);
+		Tcl_SetHashValue(tPtr, tracePtr);
+	    }
+	}
+
+	if ((dummyVar.flags & VAR_TRACED_UNSET)
+		|| (arrayPtr && (arrayPtr->flags & VAR_TRACED_UNSET))) {
+	    dummyVar.flags &= ~VAR_TRACE_ACTIVE;
+	    TclObjCallVarTraces(iPtr, arrayPtr, &dummyVar, part1Ptr, part2Ptr,
+		    (flags & (TCL_GLOBAL_ONLY|TCL_NAMESPACE_ONLY))
+			    | TCL_TRACE_UNSETS,
+		    /* leaveErrMsg */ 0, index);
+
+	    /*
+	     * The traces that we just called may have triggered a change in
+	     * the set of traces. If so, reload the traces to manipulate.
+	     */
+
+	    tracePtr = NULL;
+	    if (TclIsVarTraced(&dummyVar)) {
+		tPtr = Tcl_FindHashEntry(&iPtr->varTraces, &dummyVar);
+		if (tPtr) {
+		    tracePtr = Tcl_GetHashValue(tPtr);
+		    Tcl_DeleteHashEntry(tPtr);
+		}
+	    }
+	}
+
+	if (tracePtr) {
+	    ActiveVarTrace *activePtr;
+
+	    while (tracePtr) {
+		VarTrace *prevPtr = tracePtr;
+
+		tracePtr = tracePtr->nextPtr;
+		prevPtr->nextPtr = NULL;
+		Tcl_EventuallyFree(prevPtr, TCL_DYNAMIC);
+	    }
+	    for (activePtr = iPtr->activeVarTracePtr;  activePtr != NULL;
+		    activePtr = activePtr->nextPtr) {
+		if (activePtr->varPtr == varPtr) {
+		    activePtr->nextTracePtr = NULL;
+		}
+	    }
+	    dummyVar.flags &= ~VAR_ALL_TRACES;
+	}
+    }
+
+    if (TclIsVarScalar(&dummyVar) && (dummyVar.value.objPtr != NULL)) {
+	/*
+	 * Decrement the ref count of the var's value.
+	 */
+
+	Tcl_Obj *objPtr = dummyVar.value.objPtr;
+
+	TclDecrRefCount(objPtr);
+    } else if (TclIsVarArray(&dummyVar)) {
+	/*
+	 * If the variable is an array, delete all of its elements. This must
+	 * be done after calling and deleting the traces on the array, above
+	 * (that's the way traces are defined). If the array name is not
+	 * present and is required for a trace on some element, it will be
+	 * computed at DeleteArray.
+	 */
+
+	DeleteArray(iPtr, part1Ptr, (Var *) &dummyVar, (flags
+		& (TCL_GLOBAL_ONLY|TCL_NAMESPACE_ONLY)) | TCL_TRACE_UNSETS,
+		index);
+    } else if (TclIsVarLink(&dummyVar)) {
+	/*
+	 * For global/upvar variables referenced in procedures, decrement the
+	 * reference count on the variable referred to, and free the
+	 * referenced variable if it's no longer needed.
+	 */
+
+	Var *linkPtr = dummyVar.value.linkPtr;
+
+	if (TclIsVarInHash(linkPtr)) {
+	    VarHashRefCount(linkPtr)--;
+	    CleanupVar(linkPtr, NULL);
+	}
+    }
+
+    /*
+     * If the variable was a namespace variable, decrement its reference
+     * count.
+     */
+
+    TclClearVarNamespaceVar(varPtr);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_UnsetObjCmd --
+ *
+ *	This object-based function is invoked to process the "unset" Tcl
+ *	command. See the user documentation for details on what it does.
+ *
+ * Results:
+ *	A standard Tcl object result value.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+	/* ARGSUSED */
+int
+Tcl_UnsetObjCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    register int i, flags = TCL_LEAVE_ERR_MSG;
+    register const char *name;
+
+    if (objc == 1) {
+	/*
+	 * Do nothing if no arguments supplied, so as to match command
+	 * documentation.
+	 */
+
+	return TCL_OK;
+    }
+
+    /*
+     * Simple, restrictive argument parsing. The only options are -- and
+     * -nocomplain (which must come first and be given exactly to be an
+     * option).
+     */
+
+    i = 1;
+    name = TclGetString(objv[i]);
+    if (name[0] == '-') {
+	if (strcmp("-nocomplain", name) == 0) {
+	    i++;
+	    if (i == objc) {
+		return TCL_OK;
+	    }
+	    flags = 0;
+	    name = TclGetString(objv[i]);
+	}
+	if (strcmp("--", name) == 0) {
+	    i++;
+	}
+    }
+
+    for (; i < objc; i++) {
+	if ((TclObjUnsetVar2(interp, objv[i], NULL, flags) != TCL_OK)
+		&& (flags == TCL_LEAVE_ERR_MSG)) {
+	    return TCL_ERROR;
+	}
+    }
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_AppendObjCmd --
+ *
+ *	This object-based function is invoked to process the "append" Tcl
+ *	command. See the user documentation for details on what it does.
+ *
+ * Results:
+ *	A standard Tcl object result value.
+ *
+ * Side effects:
+ *	A variable's value may be changed.
+ *
+ *----------------------------------------------------------------------
+ */
+
+	/* ARGSUSED */
+int
+Tcl_AppendObjCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    Var *varPtr, *arrayPtr;
+    register Tcl_Obj *varValuePtr = NULL;
+				/* Initialized to avoid compiler warning. */
+    int i;
+
+    if (objc < 2) {
+	Tcl_WrongNumArgs(interp, 1, objv, "varName ?value ...?");
+	return TCL_ERROR;
+    }
+
+    if (objc == 2) {
+	varValuePtr = Tcl_ObjGetVar2(interp, objv[1], NULL,TCL_LEAVE_ERR_MSG);
+	if (varValuePtr == NULL) {
+	    return TCL_ERROR;
+	}
+    } else {
+	varPtr = TclObjLookupVarEx(interp, objv[1], NULL, TCL_LEAVE_ERR_MSG,
+		"set", /*createPart1*/ 1, /*createPart2*/ 1, &arrayPtr);
+	if (varPtr == NULL) {
+	    return TCL_ERROR;
+	}
+	for (i=2 ; i<objc ; i++) {
+	    /*
+	     * Note that we do not need to increase the refCount of the Var
+	     * pointers: should a trace delete the variable, the return value
+	     * of TclPtrSetVar will be NULL or emptyObjPtr, and we will not
+	     * access the variable again.
+	     */
+
+	    varValuePtr = TclPtrSetVar(interp, varPtr, arrayPtr, objv[1],
+		    NULL, objv[i], TCL_APPEND_VALUE|TCL_LEAVE_ERR_MSG, -1);
+	    if ((varValuePtr == NULL) ||
+		    (varValuePtr == ((Interp *) interp)->emptyObjPtr)) {
+		return TCL_ERROR;
+	    }
+	}
+    }
+    Tcl_SetObjResult(interp, varValuePtr);
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_LappendObjCmd --
+ *
+ *	This object-based function is invoked to process the "lappend" Tcl
+ *	command. See the user documentation for details on what it does.
+ *
+ * Results:
+ *	A standard Tcl object result value.
+ *
+ * Side effects:
+ *	A variable's value may be changed.
+ *
+ *----------------------------------------------------------------------
+ */
+
+	/* ARGSUSED */
+int
+Tcl_LappendObjCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    Tcl_Obj *varValuePtr, *newValuePtr;
+    int numElems, createdNewObj;
+    Var *varPtr, *arrayPtr;
+    int result;
+
+    if (objc < 2) {
+	Tcl_WrongNumArgs(interp, 1, objv, "varName ?value ...?");
+	return TCL_ERROR;
+    }
+    if (objc == 2) {
+	newValuePtr = Tcl_ObjGetVar2(interp, objv[1], NULL, 0);
+	if (newValuePtr == NULL) {
+	    /*
+	     * The variable doesn't exist yet. Just create it with an empty
+	     * initial value.
+	     */
+
+	    TclNewObj(varValuePtr);
+	    newValuePtr = Tcl_ObjSetVar2(interp, objv[1], NULL, varValuePtr,
+		    TCL_LEAVE_ERR_MSG);
+	    if (newValuePtr == NULL) {
+		return TCL_ERROR;
+	    }
+	} else {
+	    result = TclListObjLength(interp, newValuePtr, &numElems);
+	    if (result != TCL_OK) {
+		return result;
+	    }
+	}
+    } else {
+	/*
+	 * We have arguments to append. We used to call Tcl_SetVar2 to append
+	 * each argument one at a time to ensure that traces were run for each
+	 * append step. We now append the arguments all at once because it's
+	 * faster. Note that a read trace and a write trace for the variable
+	 * will now each only be called once. Also, if the variable's old
+	 * value is unshared we modify it directly, otherwise we create a new
+	 * copy to modify: this is "copy on write".
+	 */
+
+	createdNewObj = 0;
+
+	/*
+	 * Protect the variable pointers around the TclPtrGetVar call
+	 * to insure that they remain valid even if the variable was undefined
+	 * and unused.
+	 */
+
+	varPtr = TclObjLookupVarEx(interp, objv[1], NULL, TCL_LEAVE_ERR_MSG,
+		"set", /*createPart1*/ 1, /*createPart2*/ 1, &arrayPtr);
+	if (varPtr == NULL) {
+	    return TCL_ERROR;
+	}
+	if (TclIsVarInHash(varPtr)) {
+	    VarHashRefCount(varPtr)++;
+	}
+	if (arrayPtr && TclIsVarInHash(arrayPtr)) {
+	    VarHashRefCount(arrayPtr)++;
+	}
+	varValuePtr = TclPtrGetVar(interp, varPtr, arrayPtr, objv[1], NULL,
+		TCL_LEAVE_ERR_MSG, -1);
+	if (TclIsVarInHash(varPtr)) {
+	    VarHashRefCount(varPtr)--;
+	}
+	if (arrayPtr && TclIsVarInHash(arrayPtr)) {
+	    VarHashRefCount(arrayPtr)--;
+	}
+
+	if (varValuePtr == NULL) {
+	    /*
+	     * We couldn't read the old value: either the var doesn't yet
+	     * exist or it's an array element. If it's new, we will try to
+	     * create it with Tcl_ObjSetVar2 below.
+	     */
+
+	    TclNewObj(varValuePtr);
+	    createdNewObj = 1;
+	} else if (Tcl_IsShared(varValuePtr)) {
+	    varValuePtr = Tcl_DuplicateObj(varValuePtr);
+	    createdNewObj = 1;
+	}
+
+	result = TclListObjLength(interp, varValuePtr, &numElems);
+	if (result == TCL_OK) {
+	    result = Tcl_ListObjReplace(interp, varValuePtr, numElems, 0,
+		    (objc-2), (objv+2));
+	}
+	if (result != TCL_OK) {
+	    if (createdNewObj) {
+		TclDecrRefCount(varValuePtr); /* Free unneeded obj. */
+	    }
+	    return result;
+	}
+
+	/*
+	 * Now store the list object back into the variable. If there is an
+	 * error setting the new value, decrement its ref count if it was new
+	 * and we didn't create the variable.
+	 */
+
+	newValuePtr = TclPtrSetVar(interp, varPtr, arrayPtr, objv[1], NULL,
+		varValuePtr, TCL_LEAVE_ERR_MSG, -1);
+	if (newValuePtr == NULL) {
+	    return TCL_ERROR;
+	}
+    }
+
+    /*
+     * Set the interpreter's object result to refer to the variable's value
+     * object.
+     */
+
+    Tcl_SetObjResult(interp, newValuePtr);
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclArraySet --
+ *
+ *	Set the elements of an array. If there are no elements to set, create
+ *	an empty array. This routine is used by the Tcl_ArrayObjCmd and by the
+ *	TclSetupEnv routine.
+ *
+ * Results:
+ *	A standard Tcl result object.
+ *
+ * Side effects:
+ *	A variable will be created if one does not already exist.
+ *	Callers must Incr arrayNameObj if they pland to Decr it.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclArraySet(
+    Tcl_Interp *interp,		/* Current interpreter. */
+    Tcl_Obj *arrayNameObj,	/* The array name. */
+    Tcl_Obj *arrayElemObj)	/* The array elements list or dict. If this is
+				 * NULL, create an empty array. */
+{
+    Var *varPtr, *arrayPtr;
+    int result, i;
+
+    varPtr = TclObjLookupVarEx(interp, arrayNameObj, NULL,
+	    /*flags*/ TCL_LEAVE_ERR_MSG, /*msg*/ "set", /*createPart1*/ 1,
+	    /*createPart2*/ 1, &arrayPtr);
+    if (varPtr == NULL) {
+	return TCL_ERROR;
+    }
+    if (arrayPtr) {
+	CleanupVar(varPtr, arrayPtr);
+	TclObjVarErrMsg(interp, arrayNameObj, NULL, "set", needArray, -1);
+	Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "VARNAME",
+		TclGetString(arrayNameObj), NULL);
+	return TCL_ERROR;
+    }
+
+    if (arrayElemObj == NULL) {
+	goto ensureArray;
+    }
+
+    /*
+     * Install the contents of the dictionary or list into the array.
+     */
+
+    if (arrayElemObj->typePtr == &tclDictType) {
+	Tcl_Obj *keyPtr, *valuePtr;
+	Tcl_DictSearch search;
+	int done;
+
+	if (Tcl_DictObjSize(interp, arrayElemObj, &done) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	if (done == 0) {
+	    /*
+	     * Empty, so we'll just force the array to be properly existing
+	     * instead.
+	     */
+
+	    goto ensureArray;
+	}
+
+	/*
+	 * Don't need to look at result of Tcl_DictObjFirst as we've just
+	 * successfully used a dictionary operation on the same object.
+	 */
+
+	for (Tcl_DictObjFirst(interp, arrayElemObj, &search,
+		&keyPtr, &valuePtr, &done) ; !done ;
+		Tcl_DictObjNext(&search, &keyPtr, &valuePtr, &done)) {
+	    /*
+	     * At this point, it would be nice if the key was directly usable
+	     * by the array. This isn't the case though.
+	     */
+
+	    Var *elemVarPtr = TclLookupArrayElement(interp, arrayNameObj,
+		    keyPtr, TCL_LEAVE_ERR_MSG, "set", 1, 1, varPtr, -1);
+
+	    if ((elemVarPtr == NULL) ||
+		    (TclPtrSetVar(interp, elemVarPtr, varPtr, arrayNameObj,
+		    keyPtr, valuePtr, TCL_LEAVE_ERR_MSG, -1) == NULL)) {
+		Tcl_DictObjDone(&search);
+		return TCL_ERROR;
+	    }
+	}
+	return TCL_OK;
+    } else {
+	/*
+	 * Not a dictionary, so assume (and convert to, for backward-
+	 * -compatability reasons) a list.
+	 */
+
+	int elemLen;
+	Tcl_Obj **elemPtrs, *copyListObj;
+
+	result = TclListObjGetElements(interp, arrayElemObj,
+		&elemLen, &elemPtrs);
+	if (result != TCL_OK) {
+	    return result;
+	}
+	if (elemLen & 1) {
+	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		    "list must have an even number of elements", -1));
+	    Tcl_SetErrorCode(interp, "TCL", "ARGUMENT", "FORMAT", NULL);
+	    return TCL_ERROR;
+	}
+	if (elemLen == 0) {
+	    goto ensureArray;
+	}
+
+	/*
+	 * We needn't worry about traces invalidating arrayPtr: should that be
+	 * the case, TclPtrSetVar will return NULL so that we break out of the
+	 * loop and return an error.
+	 */
+
+	copyListObj = TclListObjCopy(NULL, arrayElemObj);
+	for (i=0 ; i<elemLen ; i+=2) {
+	    Var *elemVarPtr = TclLookupArrayElement(interp, arrayNameObj,
+		    elemPtrs[i], TCL_LEAVE_ERR_MSG, "set", 1, 1, varPtr, -1);
+
+	    if ((elemVarPtr == NULL) ||
+		    (TclPtrSetVar(interp, elemVarPtr, varPtr, arrayNameObj,
+		    elemPtrs[i],elemPtrs[i+1],TCL_LEAVE_ERR_MSG,-1) == NULL)){
+		result = TCL_ERROR;
+		break;
+	    }
+	}
+	Tcl_DecrRefCount(copyListObj);
+	return result;
+    }
+
+    /*
+     * The list is empty make sure we have an array, or create one if
+     * necessary.
+     */
+
+  ensureArray:
+    if (varPtr != NULL) {
+	if (TclIsVarArray(varPtr)) {
+	    /*
+	     * Already an array, done.
+	     */
+
+	    return TCL_OK;
+	}
+	if (TclIsVarArrayElement(varPtr) || !TclIsVarUndefined(varPtr)) {
+	    /*
+	     * Either an array element, or a scalar: lose!
+	     */
+
+	    TclObjVarErrMsg(interp, arrayNameObj, NULL, "array set",
+		    needArray, -1);
+	    Tcl_SetErrorCode(interp, "TCL", "WRITE", "ARRAY", NULL);
+	    return TCL_ERROR;
+	}
+    }
+    TclSetVarArray(varPtr);
+    varPtr->value.tablePtr = ckalloc(sizeof(TclVarHashTable));
+    TclInitVarHashTable(varPtr->value.tablePtr, TclGetVarNsPtr(varPtr));
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ArrayStartSearchCmd --
+ *
+ *	This object-based function is invoked to process the "array
+ *	startsearch" Tcl command. See the user documentation for details on
+ *	what it does.
+ *
+ * Results:
+ *	A standard Tcl result object.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+	/* ARGSUSED */
+static int
+ArrayStartSearchCmd(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const objv[])
+{
+    Interp *iPtr = (Interp *) interp;
+    Var *varPtr, *arrayPtr;
+    Tcl_HashEntry *hPtr;
+    Tcl_Obj *varNameObj;
+    int isNew;
+    ArraySearch *searchPtr;
+    const char *varName;
+
+    if (objc != 2) {
+	Tcl_WrongNumArgs(interp, 1, objv, "arrayName");
+	return TCL_ERROR;
+    }
+    varNameObj = objv[1];
+
+    /*
+     * Locate the array variable.
+     */
+
+    varPtr = TclObjLookupVarEx(interp, varNameObj, NULL, /*flags*/ 0,
+	    /*msg*/ 0, /*createPart1*/ 0, /*createPart2*/ 0, &arrayPtr);
+    varName = TclGetString(varNameObj);
+
+    /*
+     * Special array trace used to keep the env array in sync for array names,
+     * array get, etc.
+     */
+
+    if (varPtr && (varPtr->flags & VAR_TRACED_ARRAY)
+	    && (TclIsVarArray(varPtr) || TclIsVarUndefined(varPtr))) {
+	if (TclObjCallVarTraces(iPtr, arrayPtr, varPtr, varNameObj, NULL,
+		(TCL_LEAVE_ERR_MSG|TCL_NAMESPACE_ONLY|TCL_GLOBAL_ONLY|
+		TCL_TRACE_ARRAY), /* leaveErrMsg */ 1, -1) == TCL_ERROR) {
+	    return TCL_ERROR;
+	}
+    }
+
+    /*
+     * Verify that it is indeed an array variable. This test comes after the
+     * traces - the variable may actually become an array as an effect of said
+     * traces.
+     */
+
+    if ((varPtr == NULL) || !TclIsVarArray(varPtr)
+	    || TclIsVarUndefined(varPtr)) {
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		"\"%s\" isn't an array", varName));
+	Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "ARRAY", varName, NULL);
+	return TCL_ERROR;
+    }
+
+    /*
+     * Make a new array search with a free name.
+     */
+
+    searchPtr = ckalloc(sizeof(ArraySearch));
+    hPtr = Tcl_CreateHashEntry(&iPtr->varSearches, varPtr, &isNew);
+    if (isNew) {
+	searchPtr->id = 1;
+	varPtr->flags |= VAR_SEARCH_ACTIVE;
+	searchPtr->nextPtr = NULL;
+    } else {
+	searchPtr->id = ((ArraySearch *) Tcl_GetHashValue(hPtr))->id + 1;
+	searchPtr->nextPtr = Tcl_GetHashValue(hPtr);
+    }
+    searchPtr->varPtr = varPtr;
+    searchPtr->nextEntry = VarHashFirstEntry(varPtr->value.tablePtr,
+	    &searchPtr->search);
+    Tcl_SetHashValue(hPtr, searchPtr);
+    Tcl_SetObjResult(interp,
+	    Tcl_ObjPrintf("s-%d-%s", searchPtr->id, varName));
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ArrayAnyMoreCmd --
+ *
+ *	This object-based function is invoked to process the "array anymore"
+ *	Tcl command. See the user documentation for details on what it does.
+ *
+ * Results:
+ *	A standard Tcl result object.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+	/* ARGSUSED */
+static int
+ArrayAnyMoreCmd(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const objv[])
+{
+    Interp *iPtr = (Interp *) interp;
+    Var *varPtr, *arrayPtr;
+    Tcl_Obj *varNameObj, *searchObj;
+    int gotValue;
+    ArraySearch *searchPtr;
+
+    if (objc != 3) {
+	Tcl_WrongNumArgs(interp, 1, objv, "arrayName searchId");
+	return TCL_ERROR;
+    }
+    varNameObj = objv[1];
+    searchObj = objv[2];
+
+    /*
+     * Locate the array variable.
+     */
+
+    varPtr = TclObjLookupVarEx(interp, varNameObj, NULL, /*flags*/ 0,
+	    /*msg*/ 0, /*createPart1*/ 0, /*createPart2*/ 0, &arrayPtr);
+
+    /*
+     * Special array trace used to keep the env array in sync for array names,
+     * array get, etc.
+     */
+
+    if (varPtr && (varPtr->flags & VAR_TRACED_ARRAY)
+	    && (TclIsVarArray(varPtr) || TclIsVarUndefined(varPtr))) {
+	if (TclObjCallVarTraces(iPtr, arrayPtr, varPtr, varNameObj, NULL,
+		(TCL_LEAVE_ERR_MSG|TCL_NAMESPACE_ONLY|TCL_GLOBAL_ONLY|
+		TCL_TRACE_ARRAY), /* leaveErrMsg */ 1, -1) == TCL_ERROR) {
+	    return TCL_ERROR;
+	}
+    }
+
+    /*
+     * Verify that it is indeed an array variable. This test comes after the
+     * traces - the variable may actually become an array as an effect of said
+     * traces.
+     */
+
+    if ((varPtr == NULL) || !TclIsVarArray(varPtr)
+	    || TclIsVarUndefined(varPtr)) {
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		"\"%s\" isn't an array", TclGetString(varNameObj)));
+	Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "ARRAY",
+		TclGetString(varNameObj), NULL);
+	return TCL_ERROR;
+    }
+
+    /*
+     * Get the search.
+     */
+
+    searchPtr = ParseSearchId(interp, varPtr, varNameObj, searchObj);
+    if (searchPtr == NULL) {
+	return TCL_ERROR;
+    }
+
+    /*
+     * Scan forward to find if there are any further elements in the array
+     * that are defined.
+     */
+
+    while (1) {
+	if (searchPtr->nextEntry != NULL) {
+	    varPtr = VarHashGetValue(searchPtr->nextEntry);
+	    if (!TclIsVarUndefined(varPtr)) {
+		gotValue = 1;
+		break;
+	    }
+	}
+	searchPtr->nextEntry = Tcl_NextHashEntry(&searchPtr->search);
+	if (searchPtr->nextEntry == NULL) {
+	    gotValue = 0;
+	    break;
+	}
+    }
+    Tcl_SetObjResult(interp, iPtr->execEnvPtr->constants[gotValue]);
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ArrayNextElementCmd --
+ *
+ *	This object-based function is invoked to process the "array
+ *	nextelement" Tcl command. See the user documentation for details on
+ *	what it does.
+ *
+ * Results:
+ *	A standard Tcl result object.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+	/* ARGSUSED */
+static int
+ArrayNextElementCmd(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const objv[])
+{
+    Interp *iPtr = (Interp *) interp;
+    Var *varPtr, *arrayPtr;
+    Tcl_Obj *varNameObj, *searchObj;
+    ArraySearch *searchPtr;
+
+    if (objc != 3) {
+	Tcl_WrongNumArgs(interp, 1, objv, "arrayName searchId");
+	return TCL_ERROR;
+    }
+    varNameObj = objv[1];
+    searchObj = objv[2];
+
+    /*
+     * Locate the array variable.
+     */
+
+    varPtr = TclObjLookupVarEx(interp, varNameObj, NULL, /*flags*/ 0,
+	    /*msg*/ 0, /*createPart1*/ 0, /*createPart2*/ 0, &arrayPtr);
+
+    /*
+     * Special array trace used to keep the env array in sync for array names,
+     * array get, etc.
+     */
+
+    if (varPtr && (varPtr->flags & VAR_TRACED_ARRAY)
+	    && (TclIsVarArray(varPtr) || TclIsVarUndefined(varPtr))) {
+	if (TclObjCallVarTraces(iPtr, arrayPtr, varPtr, varNameObj, NULL,
+		(TCL_LEAVE_ERR_MSG|TCL_NAMESPACE_ONLY|TCL_GLOBAL_ONLY|
+		TCL_TRACE_ARRAY), /* leaveErrMsg */ 1, -1) == TCL_ERROR) {
+	    return TCL_ERROR;
+	}
+    }
+
+    /*
+     * Verify that it is indeed an array variable. This test comes after the
+     * traces - the variable may actually become an array as an effect of said
+     * traces.
+     */
+
+    if ((varPtr == NULL) || !TclIsVarArray(varPtr)
+	    || TclIsVarUndefined(varPtr)) {
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		"\"%s\" isn't an array", TclGetString(varNameObj)));
+	Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "ARRAY",
+		TclGetString(varNameObj), NULL);
+	return TCL_ERROR;
+    }
+
+    /*
+     * Get the search.
+     */
+
+    searchPtr = ParseSearchId(interp, varPtr, varNameObj, searchObj);
+    if (searchPtr == NULL) {
+	return TCL_ERROR;
+    }
+
+    /*
+     * Get the next element from the search, or the empty string on
+     * exhaustion. Note that the [array anymore] command may well have already
+     * pulled a value from the hash enumeration, so we have to check the cache
+     * there first.
+     */
+
+    while (1) {
+	Tcl_HashEntry *hPtr = searchPtr->nextEntry;
+
+	if (hPtr == NULL) {
+	    hPtr = Tcl_NextHashEntry(&searchPtr->search);
+	    if (hPtr == NULL) {
+		return TCL_OK;
+	    }
+	} else {
+	    searchPtr->nextEntry = NULL;
+	}
+	varPtr = VarHashGetValue(hPtr);
+	if (!TclIsVarUndefined(varPtr)) {
+	    Tcl_SetObjResult(interp, VarHashGetKey(varPtr));
+	    return TCL_OK;
+	}
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ArrayDoneSearchCmd --
+ *
+ *	This object-based function is invoked to process the "array
+ *	donesearch" Tcl command. See the user documentation for details on
+ *	what it does.
+ *
+ * Results:
+ *	A standard Tcl result object.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+	/* ARGSUSED */
+static int
+ArrayDoneSearchCmd(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const objv[])
+{
+    Interp *iPtr = (Interp *) interp;
+    Var *varPtr, *arrayPtr;
+    Tcl_HashEntry *hPtr;
+    Tcl_Obj *varNameObj, *searchObj;
+    ArraySearch *searchPtr, *prevPtr;
+
+    if (objc != 3) {
+	Tcl_WrongNumArgs(interp, 1, objv, "arrayName searchId");
+	return TCL_ERROR;
+    }
+    varNameObj = objv[1];
+    searchObj = objv[2];
+
+    /*
+     * Locate the array variable.
+     */
+
+    varPtr = TclObjLookupVarEx(interp, varNameObj, NULL, /*flags*/ 0,
+	    /*msg*/ 0, /*createPart1*/ 0, /*createPart2*/ 0, &arrayPtr);
+
+    /*
+     * Special array trace used to keep the env array in sync for array names,
+     * array get, etc.
+     */
+
+    if (varPtr && (varPtr->flags & VAR_TRACED_ARRAY)
+	    && (TclIsVarArray(varPtr) || TclIsVarUndefined(varPtr))) {
+	if (TclObjCallVarTraces(iPtr, arrayPtr, varPtr, varNameObj, NULL,
+		(TCL_LEAVE_ERR_MSG|TCL_NAMESPACE_ONLY|TCL_GLOBAL_ONLY|
+		TCL_TRACE_ARRAY), /* leaveErrMsg */ 1, -1) == TCL_ERROR) {
+	    return TCL_ERROR;
+	}
+    }
+
+    /*
+     * Verify that it is indeed an array variable. This test comes after the
+     * traces - the variable may actually become an array as an effect of said
+     * traces.
+     */
+
+    if ((varPtr == NULL) || !TclIsVarArray(varPtr)
+	    || TclIsVarUndefined(varPtr)) {
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		"\"%s\" isn't an array", TclGetString(varNameObj)));
+	Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "ARRAY",
+		TclGetString(varNameObj), NULL);
+	return TCL_ERROR;
+    }
+
+    /*
+     * Get the search.
+     */
+
+    searchPtr = ParseSearchId(interp, varPtr, varNameObj, searchObj);
+    if (searchPtr == NULL) {
+	return TCL_ERROR;
+    }
+
+    /*
+     * Unhook the search from the list of searches associated with the
+     * variable.
+     */
+
+    hPtr = Tcl_FindHashEntry(&iPtr->varSearches, varPtr);
+    if (searchPtr == Tcl_GetHashValue(hPtr)) {
+	if (searchPtr->nextPtr) {
+	    Tcl_SetHashValue(hPtr, searchPtr->nextPtr);
+	} else {
+	    varPtr->flags &= ~VAR_SEARCH_ACTIVE;
+	    Tcl_DeleteHashEntry(hPtr);
+	}
+    } else {
+	for (prevPtr=Tcl_GetHashValue(hPtr) ;; prevPtr=prevPtr->nextPtr) {
+	    if (prevPtr->nextPtr == searchPtr) {
+		prevPtr->nextPtr = searchPtr->nextPtr;
+		break;
+	    }
+	}
+    }
+    ckfree(searchPtr);
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ArrayExistsCmd --
+ *
+ *	This object-based function is invoked to process the "array exists"
+ *	Tcl command. See the user documentation for details on what it does.
+ *
+ * Results:
+ *	A standard Tcl result object.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+	/* ARGSUSED */
+static int
+ArrayExistsCmd(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const objv[])
+{
+    Interp *iPtr = (Interp *) interp;
+    Var *varPtr, *arrayPtr;
+    Tcl_Obj *arrayNameObj;
+    int notArray;
+
+    if (objc != 2) {
+	Tcl_WrongNumArgs(interp, 1, objv, "arrayName");
+	return TCL_ERROR;
+    }
+    arrayNameObj = objv[1];
+
+    /*
+     * Locate the array variable.
+     */
+
+    varPtr = TclObjLookupVarEx(interp, arrayNameObj, NULL, /*flags*/ 0,
+	    /*msg*/ 0, /*createPart1*/ 0, /*createPart2*/ 0, &arrayPtr);
+
+    /*
+     * Special array trace used to keep the env array in sync for array names,
+     * array get, etc.
+     */
+
+    if (varPtr && (varPtr->flags & VAR_TRACED_ARRAY)
+	    && (TclIsVarArray(varPtr) || TclIsVarUndefined(varPtr))) {
+	if (TclObjCallVarTraces(iPtr, arrayPtr, varPtr, arrayNameObj, NULL,
+		(TCL_LEAVE_ERR_MSG|TCL_NAMESPACE_ONLY|TCL_GLOBAL_ONLY|
+		TCL_TRACE_ARRAY), /* leaveErrMsg */ 1, -1) == TCL_ERROR) {
+	    return TCL_ERROR;
+	}
+    }
+
+    /*
+     * Check whether we've actually got an array variable.
+     */
+
+    notArray = ((varPtr == NULL) || !TclIsVarArray(varPtr)
+	    || TclIsVarUndefined(varPtr));
+    Tcl_SetObjResult(interp, iPtr->execEnvPtr->constants[!notArray]);
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ArrayGetCmd --
+ *
+ *	This object-based function is invoked to process the "array get" Tcl
+ *	command. See the user documentation for details on what it does.
+ *
+ * Results:
+ *	A standard Tcl result object.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+	/* ARGSUSED */
+static int
+ArrayGetCmd(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const objv[])
+{
+    Interp *iPtr = (Interp *) interp;
+    Var *varPtr, *arrayPtr, *varPtr2;
+    Tcl_Obj *varNameObj, *nameObj, *valueObj, *nameLstObj, *tmpResObj;
+    Tcl_Obj **nameObjPtr, *patternObj;
+    Tcl_HashSearch search;
+    const char *pattern;
+    int i, count, result;
+
+    switch (objc) {
+    case 2:
+	varNameObj = objv[1];
+	patternObj = NULL;
+	break;
+    case 3:
+	varNameObj = objv[1];
+	patternObj = objv[2];
+	break;
+    default:
+	Tcl_WrongNumArgs(interp, 1, objv, "arrayName ?pattern?");
+	return TCL_ERROR;
+    }
+
+    /*
+     * Locate the array variable.
+     */
+
+    varPtr = TclObjLookupVarEx(interp, varNameObj, NULL, /*flags*/ 0,
+	    /*msg*/ 0, /*createPart1*/ 0, /*createPart2*/ 0, &arrayPtr);
+
+    /*
+     * Special array trace used to keep the env array in sync for array names,
+     * array get, etc.
+     */
+
+    if (varPtr && (varPtr->flags & VAR_TRACED_ARRAY)
+	    && (TclIsVarArray(varPtr) || TclIsVarUndefined(varPtr))) {
+	if (TclObjCallVarTraces(iPtr, arrayPtr, varPtr, varNameObj, NULL,
+		(TCL_LEAVE_ERR_MSG|TCL_NAMESPACE_ONLY|TCL_GLOBAL_ONLY|
+		TCL_TRACE_ARRAY), /* leaveErrMsg */ 1, -1) == TCL_ERROR) {
+	    return TCL_ERROR;
+	}
+    }
+
+    /*
+     * Verify that it is indeed an array variable. This test comes after the
+     * traces - the variable may actually become an array as an effect of said
+     * traces. If not an array, it's an empty result.
+     */
+
+    if ((varPtr == NULL) || !TclIsVarArray(varPtr)
+	    || TclIsVarUndefined(varPtr)) {
+	return TCL_OK;
+    }
+
+    pattern = (patternObj ? TclGetString(patternObj) : NULL);
+
+    /*
+     * Store the array names in a new object.
+     */
+
+    TclNewObj(nameLstObj);
+    Tcl_IncrRefCount(nameLstObj);
+    if ((patternObj != NULL) && TclMatchIsTrivial(pattern)) {
+	varPtr2 = VarHashFindVar(varPtr->value.tablePtr, patternObj);
+	if (varPtr2 == NULL) {
+	    goto searchDone;
+	}
+	if (TclIsVarUndefined(varPtr2)) {
+	    goto searchDone;
+	}
+	result = Tcl_ListObjAppendElement(interp, nameLstObj,
+		VarHashGetKey(varPtr2));
+	if (result != TCL_OK) {
+	    TclDecrRefCount(nameLstObj);
+	    return result;
+	}
+	goto searchDone;
+    }
+
+    for (varPtr2 = VarHashFirstVar(varPtr->value.tablePtr, &search);
+	    varPtr2; varPtr2 = VarHashNextVar(&search)) {
+	if (TclIsVarUndefined(varPtr2)) {
+	    continue;
+	}
+	nameObj = VarHashGetKey(varPtr2);
+	if (patternObj && !Tcl_StringMatch(TclGetString(nameObj), pattern)) {
+	    continue;		/* Element name doesn't match pattern. */
+	}
+
+	result = Tcl_ListObjAppendElement(interp, nameLstObj, nameObj);
+	if (result != TCL_OK) {
+	    TclDecrRefCount(nameLstObj);
+	    return result;
+	}
+    }
+
+    /*
+     * Make sure the Var structure of the array is not removed by a trace
+     * while we're working.
+     */
+
+  searchDone:
+    if (TclIsVarInHash(varPtr)) {
+	VarHashRefCount(varPtr)++;
+    }
+
+    /*
+     * Get the array values corresponding to each element name.
+     */
+
+    TclNewObj(tmpResObj);
+    result = Tcl_ListObjGetElements(interp, nameLstObj, &count, &nameObjPtr);
+    if (result != TCL_OK) {
+	goto errorInArrayGet;
+    }
+
+    for (i=0 ; i<count ; i++) {
+	nameObj = *nameObjPtr++;
+	valueObj = Tcl_ObjGetVar2(interp, varNameObj, nameObj,
+		TCL_LEAVE_ERR_MSG);
+	if (valueObj == NULL) {
+	    /*
+	     * Some trace played a trick on us; we need to diagnose to adapt
+	     * our behaviour: was the array element unset, or did the
+	     * modification modify the complete array?
+	     */
+
+	    if (TclIsVarArray(varPtr)) {
+		/*
+		 * The array itself looks OK, the variable was undefined:
+		 * forget it.
+		 */
+
+		continue;
+	    }
+	    result = TCL_ERROR;
+	    goto errorInArrayGet;
+	}
+	result = Tcl_DictObjPut(interp, tmpResObj, nameObj, valueObj);
+	if (result != TCL_OK) {
+	    goto errorInArrayGet;
+	}
+    }
+    if (TclIsVarInHash(varPtr)) {
+	VarHashRefCount(varPtr)--;
+    }
+    Tcl_SetObjResult(interp, tmpResObj);
+    TclDecrRefCount(nameLstObj);
+    return TCL_OK;
+
+  errorInArrayGet:
+    if (TclIsVarInHash(varPtr)) {
+	VarHashRefCount(varPtr)--;
+    }
+    TclDecrRefCount(nameLstObj);
+    TclDecrRefCount(tmpResObj);	/* Free unneeded temp result. */
+    return result;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ArrayNamesCmd --
+ *
+ *	This object-based function is invoked to process the "array names" Tcl
+ *	command. See the user documentation for details on what it does.
+ *
+ * Results:
+ *	A standard Tcl result object.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+	/* ARGSUSED */
+static int
+ArrayNamesCmd(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const objv[])
+{
+    static const char *const options[] = {
+	"-exact", "-glob", "-regexp", NULL
+    };
+    enum options { OPT_EXACT, OPT_GLOB, OPT_REGEXP };
+    Interp *iPtr = (Interp *) interp;
+    Var *varPtr, *arrayPtr, *varPtr2;
+    Tcl_Obj *varNameObj, *nameObj, *resultObj, *patternObj;
+    Tcl_HashSearch search;
+    const char *pattern = NULL;
+    int mode = OPT_GLOB;
+
+    if ((objc < 2) || (objc > 4)) {
+	Tcl_WrongNumArgs(interp, 1, objv, "arrayName ?mode? ?pattern?");
+	return TCL_ERROR;
+    }
+    varNameObj = objv[1];
+    patternObj = (objc > 2 ? objv[objc-1] : NULL);
+
+    /*
+     * Locate the array variable.
+     */
+
+    varPtr = TclObjLookupVarEx(interp, varNameObj, NULL, /*flags*/ 0,
+	    /*msg*/ 0, /*createPart1*/ 0, /*createPart2*/ 0, &arrayPtr);
+
+    /*
+     * Special array trace used to keep the env array in sync for array names,
+     * array get, etc.
+     */
+
+    if (varPtr && (varPtr->flags & VAR_TRACED_ARRAY)
+	    && (TclIsVarArray(varPtr) || TclIsVarUndefined(varPtr))) {
+	if (TclObjCallVarTraces(iPtr, arrayPtr, varPtr, varNameObj, NULL,
+		(TCL_LEAVE_ERR_MSG|TCL_NAMESPACE_ONLY|TCL_GLOBAL_ONLY|
+		TCL_TRACE_ARRAY), /* leaveErrMsg */ 1, -1) == TCL_ERROR) {
+	    return TCL_ERROR;
+	}
+    }
+
+    /*
+     * Finish parsing the arguments.
+     */
+
+    if ((objc == 4) && Tcl_GetIndexFromObj(interp, objv[2], options, "option",
+	    0, &mode) != TCL_OK) {
+	return TCL_ERROR;
+    }
+
+    /*
+     * Verify that it is indeed an array variable. This test comes after the
+     * traces - the variable may actually become an array as an effect of said
+     * traces. If not an array, the result is empty.
+     */
+
+    if ((varPtr == NULL) || !TclIsVarArray(varPtr)
+	    || TclIsVarUndefined(varPtr)) {
+	return TCL_OK;
+    }
+
+    /*
+     * Check for the trivial cases where we can use a direct lookup.
+     */
+
+    TclNewObj(resultObj);
+    if (patternObj) {
+	pattern = TclGetString(patternObj);
+    }
+    if ((mode==OPT_GLOB && patternObj && TclMatchIsTrivial(pattern))
+	    || (mode==OPT_EXACT)) {
+	varPtr2 = VarHashFindVar(varPtr->value.tablePtr, patternObj);
+	if ((varPtr2 != NULL) && !TclIsVarUndefined(varPtr2)) {
+	    /*
+	     * This can't fail; lappending to an empty object always works.
+	     */
+
+	    Tcl_ListObjAppendElement(NULL, resultObj, VarHashGetKey(varPtr2));
+	}
+	Tcl_SetObjResult(interp, resultObj);
+	return TCL_OK;
+    }
+
+    /*
+     * Must scan the array to select the elements.
+     */
+
+    for (varPtr2=VarHashFirstVar(varPtr->value.tablePtr, &search);
+	    varPtr2!=NULL ; varPtr2=VarHashNextVar(&search)) {
+	if (TclIsVarUndefined(varPtr2)) {
+	    continue;
+	}
+	nameObj = VarHashGetKey(varPtr2);
+	if (patternObj) {
+	    const char *name = TclGetString(nameObj);
+	    int matched = 0;
+
+	    switch ((enum options) mode) {
+	    case OPT_EXACT:
+		Tcl_Panic("exact matching shouldn't get here");
+	    case OPT_GLOB:
+		matched = Tcl_StringMatch(name, pattern);
+		break;
+	    case OPT_REGEXP:
+		matched = Tcl_RegExpMatchObj(interp, nameObj, patternObj);
+		if (matched < 0) {
+		    TclDecrRefCount(resultObj);
+		    return TCL_ERROR;
+		}
+		break;
+	    }
+	    if (matched == 0) {
+		continue;
+	    }
+	}
+
+	Tcl_ListObjAppendElement(NULL, resultObj, nameObj);
+    }
+    Tcl_SetObjResult(interp, resultObj);
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclFindArrayPtrElements --
+ *
+ *	Fill out a hash table (which *must* use Tcl_Obj* keys) with an entry
+ *	for each existing element of the given array. The provided hash table
+ *	is assumed to be initially empty.
+ *
+ * Result:
+ *	none
+ *
+ * Side effects:
+ *	The keys of the array gain an extra reference. The supplied hash table
+ *	has elements added to it.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclFindArrayPtrElements(
+    Var *arrayPtr,
+    Tcl_HashTable *tablePtr)
+{
+    Var *varPtr;
+    Tcl_HashSearch search;
+
+    if ((arrayPtr == NULL) || !TclIsVarArray(arrayPtr)
+	    || TclIsVarUndefined(arrayPtr)) {
+	return;
+    }
+
+    for (varPtr=VarHashFirstVar(arrayPtr->value.tablePtr, &search);
+	    varPtr!=NULL ; varPtr=VarHashNextVar(&search)) {
+	Tcl_HashEntry *hPtr;
+	Tcl_Obj *nameObj;
+	int dummy;
+
+	if (TclIsVarUndefined(varPtr)) {
+	    continue;
+	}
+	nameObj = VarHashGetKey(varPtr);
+	hPtr = Tcl_CreateHashEntry(tablePtr, (char *) nameObj, &dummy);
+	Tcl_SetHashValue(hPtr, nameObj);
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ArraySetCmd --
+ *
+ *	This object-based function is invoked to process the "array set" Tcl
+ *	command. See the user documentation for details on what it does.
+ *
+ * Results:
+ *	A standard Tcl result object.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+	/* ARGSUSED */
+static int
+ArraySetCmd(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const objv[])
+{
+    Interp *iPtr = (Interp *) interp;
+    Var *varPtr, *arrayPtr;
+
+    if (objc != 3) {
+	Tcl_WrongNumArgs(interp, 1, objv, "arrayName list");
+	return TCL_ERROR;
+    }
+
+    /*
+     * Locate the array variable.
+     */
+
+    varPtr = TclObjLookupVarEx(interp, objv[1], NULL, /*flags*/ 0,
+	    /*msg*/ 0, /*createPart1*/ 0, /*createPart2*/ 0, &arrayPtr);
+
+    /*
+     * Special array trace used to keep the env array in sync for array names,
+     * array get, etc.
+     */
+
+    if (varPtr && (varPtr->flags & VAR_TRACED_ARRAY)
+	    && (TclIsVarArray(varPtr) || TclIsVarUndefined(varPtr))) {
+	if (TclObjCallVarTraces(iPtr, arrayPtr, varPtr, objv[1], NULL,
+		(TCL_LEAVE_ERR_MSG|TCL_NAMESPACE_ONLY|TCL_GLOBAL_ONLY|
+		TCL_TRACE_ARRAY), /* leaveErrMsg */ 1, -1) == TCL_ERROR) {
+	    return TCL_ERROR;
+	}
+    }
+
+    return TclArraySet(interp, objv[1], objv[2]);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ArraySizeCmd --
+ *
+ *	This object-based function is invoked to process the "array size" Tcl
+ *	command. See the user documentation for details on what it does.
+ *
+ * Results:
+ *	A standard Tcl result object.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+	/* ARGSUSED */
+static int
+ArraySizeCmd(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const objv[])
+{
+    Interp *iPtr = (Interp *) interp;
+    Var *varPtr, *arrayPtr;
+    Tcl_Obj *varNameObj;
+    Tcl_HashSearch search;
+    Var *varPtr2;
+    int size = 0;
+
+    if (objc != 2) {
+	Tcl_WrongNumArgs(interp, 1, objv, "arrayName");
+	return TCL_ERROR;
+    }
+    varNameObj = objv[1];
+
+    /*
+     * Locate the array variable.
+     */
+
+    varPtr = TclObjLookupVarEx(interp, varNameObj, NULL, /*flags*/ 0,
+	    /*msg*/ 0, /*createPart1*/ 0, /*createPart2*/ 0, &arrayPtr);
+
+    /*
+     * Special array trace used to keep the env array in sync for array names,
+     * array get, etc.
+     */
+
+    if (varPtr && (varPtr->flags & VAR_TRACED_ARRAY)
+	    && (TclIsVarArray(varPtr) || TclIsVarUndefined(varPtr))) {
+	if (TclObjCallVarTraces(iPtr, arrayPtr, varPtr, varNameObj, NULL,
+		(TCL_LEAVE_ERR_MSG|TCL_NAMESPACE_ONLY|TCL_GLOBAL_ONLY|
+		TCL_TRACE_ARRAY), /* leaveErrMsg */ 1, -1) == TCL_ERROR) {
+	    return TCL_ERROR;
+	}
+    }
+
+    /*
+     * Verify that it is indeed an array variable. This test comes after the
+     * traces - the variable may actually become an array as an effect of said
+     * traces. We can only iterate over the array if it exists...
+     */
+
+    if (varPtr && TclIsVarArray(varPtr) && !TclIsVarUndefined(varPtr)) {
+	/*
+	 * Must iterate in order to get chance to check for present but
+	 * "undefined" entries.
+	 */
+
+	for (varPtr2=VarHashFirstVar(varPtr->value.tablePtr, &search);
+		varPtr2!=NULL ; varPtr2=VarHashNextVar(&search)) {
+	    if (!TclIsVarUndefined(varPtr2)) {
+		size++;
+	    }
+	}
+    }
+
+    Tcl_SetObjResult(interp, Tcl_NewIntObj(size));
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ArrayStatsCmd --
+ *
+ *	This object-based function is invoked to process the "array
+ *	statistics" Tcl command. See the user documentation for details on
+ *	what it does.
+ *
+ * Results:
+ *	A standard Tcl result object.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+	/* ARGSUSED */
+static int
+ArrayStatsCmd(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const objv[])
+{
+    Interp *iPtr = (Interp *) interp;
+    Var *varPtr, *arrayPtr;
+    Tcl_Obj *varNameObj;
+    char *stats;
+
+    if (objc != 2) {
+	Tcl_WrongNumArgs(interp, 1, objv, "arrayName");
+	return TCL_ERROR;
+    }
+    varNameObj = objv[1];
+
+    /*
+     * Locate the array variable.
+     */
+
+    varPtr = TclObjLookupVarEx(interp, varNameObj, NULL, /*flags*/ 0,
+	    /*msg*/ 0, /*createPart1*/ 0, /*createPart2*/ 0, &arrayPtr);
+
+    /*
+     * Special array trace used to keep the env array in sync for array names,
+     * array get, etc.
+     */
+
+    if (varPtr && (varPtr->flags & VAR_TRACED_ARRAY)
+	    && (TclIsVarArray(varPtr) || TclIsVarUndefined(varPtr))) {
+	if (TclObjCallVarTraces(iPtr, arrayPtr, varPtr, varNameObj, NULL,
+		(TCL_LEAVE_ERR_MSG|TCL_NAMESPACE_ONLY|TCL_GLOBAL_ONLY|
+		TCL_TRACE_ARRAY), /* leaveErrMsg */ 1, -1) == TCL_ERROR) {
+	    return TCL_ERROR;
+	}
+    }
+
+    /*
+     * Verify that it is indeed an array variable. This test comes after the
+     * traces - the variable may actually become an array as an effect of said
+     * traces.
+     */
+
+    if ((varPtr == NULL) || !TclIsVarArray(varPtr)
+	    || TclIsVarUndefined(varPtr)) {
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		"\"%s\" isn't an array", TclGetString(varNameObj)));
+	Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "ARRAY",
+		TclGetString(varNameObj), NULL);
+	return TCL_ERROR;
+    }
+
+    stats = Tcl_HashStats((Tcl_HashTable *) varPtr->value.tablePtr);
+    if (stats == NULL) {
+	Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		"error reading array statistics", -1));
+	return TCL_ERROR;
+    }
+    Tcl_SetObjResult(interp, Tcl_NewStringObj(stats, -1));
+    ckfree(stats);
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ArrayUnsetCmd --
+ *
+ *	This object-based function is invoked to process the "array unset" Tcl
+ *	command. See the user documentation for details on what it does.
+ *
+ * Results:
+ *	A standard Tcl result object.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+	/* ARGSUSED */
+static int
+ArrayUnsetCmd(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const objv[])
+{
+    Interp *iPtr = (Interp *) interp;
+    Var *varPtr, *arrayPtr, *varPtr2, *protectedVarPtr;
+    Tcl_Obj *varNameObj, *patternObj, *nameObj;
+    Tcl_HashSearch search;
+    const char *pattern;
+    const int unsetFlags = 0;	/* Should this be TCL_LEAVE_ERR_MSG? */
+
+    switch (objc) {
+    case 2:
+	varNameObj = objv[1];
+	patternObj = NULL;
+	break;
+    case 3:
+	varNameObj = objv[1];
+	patternObj = objv[2];
+	break;
+    default:
+	Tcl_WrongNumArgs(interp, 1, objv, "arrayName ?pattern?");
+	return TCL_ERROR;
+    }
+
+    /*
+     * Locate the array variable
+     */
+
+    varPtr = TclObjLookupVarEx(interp, varNameObj, NULL, /*flags*/ 0,
+	    /*msg*/ 0, /*createPart1*/ 0, /*createPart2*/ 0, &arrayPtr);
+
+    /*
+     * Special array trace used to keep the env array in sync for array names,
+     * array get, etc.
+     */
+
+    if (varPtr && (varPtr->flags & VAR_TRACED_ARRAY)
+	    && (TclIsVarArray(varPtr) || TclIsVarUndefined(varPtr))) {
+	if (TclObjCallVarTraces(iPtr, arrayPtr, varPtr, varNameObj, NULL,
+		(TCL_LEAVE_ERR_MSG|TCL_NAMESPACE_ONLY|TCL_GLOBAL_ONLY|
+		TCL_TRACE_ARRAY), /* leaveErrMsg */ 1, -1) == TCL_ERROR) {
+	    return TCL_ERROR;
+	}
+    }
+
+    /*
+     * Verify that it is indeed an array variable. This test comes after the
+     * traces - the variable may actually become an array as an effect of said
+     * traces.
+     */
+
+    if ((varPtr == NULL) || !TclIsVarArray(varPtr)
+	    || TclIsVarUndefined(varPtr)) {
+	return TCL_OK;
+    }
+
+    if (!patternObj) {
+	/*
+	 * When no pattern is given, just unset the whole array.
+	 */
+
+	return TclObjUnsetVar2(interp, varNameObj, NULL, 0);
+    }
+
+    /*
+     * With a trivial pattern, we can just unset.
+     */
+
+    pattern = TclGetString(patternObj);
+    if (TclMatchIsTrivial(pattern)) {
+	varPtr2 = VarHashFindVar(varPtr->value.tablePtr, patternObj);
+	if (!varPtr2 || TclIsVarUndefined(varPtr2)) {
+	    return TCL_OK;
+	}
+	return TclPtrUnsetVar(interp, varPtr2, varPtr, varNameObj, patternObj,
+		unsetFlags, -1);
+    }
+
+    /*
+     * Non-trivial case (well, deeply tricky really). We peek inside the hash
+     * iterator in order to allow us to guarantee that the following element
+     * in the array will not be scrubbed until we have dealt with it. This
+     * stops the overall iterator from ending up pointing into deallocated
+     * memory. [Bug 2939073]
+     */
+
+    protectedVarPtr = NULL;
+    for (varPtr2=VarHashFirstVar(varPtr->value.tablePtr, &search);
+	    varPtr2!=NULL ; varPtr2=VarHashNextVar(&search)) {
+	/*
+	 * Drop the extra ref immediately. We don't need to free it at this
+	 * point though; we'll be unsetting it if necessary soon.
+	 */
+
+	if (varPtr2 == protectedVarPtr) {
+	    VarHashRefCount(varPtr2)--;
+	}
+
+	/*
+	 * Guard the next (peeked) item in the search chain by incrementing
+	 * its refcount. This guarantees that the hash table iterator won't be
+	 * dangling on the next time through the loop.
+	 */
+
+	if (search.nextEntryPtr != NULL) {
+	    protectedVarPtr = VarHashGetValue(search.nextEntryPtr);
+	    VarHashRefCount(protectedVarPtr)++;
+	} else {
+	    protectedVarPtr = NULL;
+	}
+
+	/*
+	 * If the variable is undefined, clean it out as it has been hit by
+	 * something else (i.e., an unset trace).
+	 */
+
+	if (TclIsVarUndefined(varPtr2)) {
+	    CleanupVar(varPtr2, varPtr);
+	    continue;
+	}
+
+	nameObj = VarHashGetKey(varPtr2);
+	if (Tcl_StringMatch(TclGetString(nameObj), pattern)
+		&& TclPtrUnsetVar(interp, varPtr2, varPtr, varNameObj,
+			nameObj, unsetFlags, -1) != TCL_OK) {
+	    /*
+	     * If we incremented a refcount, we must decrement it here as we
+	     * will not be coming back properly due to the error.
+	     */
+
+	    if (protectedVarPtr) {
+		VarHashRefCount(protectedVarPtr)--;
+		CleanupVar(protectedVarPtr, varPtr);
+	    }
+	    return TCL_ERROR;
+	}
+    }
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclInitArrayCmd --
+ *
+ *	This creates the ensemble for the "array" command.
+ *
+ * Results:
+ *	The handle for the created ensemble.
+ *
+ * Side effects:
+ *	Creates a command in the global namespace.
+ *
+ *----------------------------------------------------------------------
+ */
+
+	/* ARGSUSED */
+Tcl_Command
+TclInitArrayCmd(
+    Tcl_Interp *interp)		/* Current interpreter. */
+{
+    static const EnsembleImplMap arrayImplMap[] = {
+	{"anymore",	ArrayAnyMoreCmd,	TclCompileBasic2ArgCmd, NULL, NULL, 0},
+	{"donesearch",	ArrayDoneSearchCmd,	TclCompileBasic2ArgCmd, NULL, NULL, 0},
+	{"exists",	ArrayExistsCmd,		TclCompileArrayExistsCmd, NULL, NULL, 0},
+	{"get",		ArrayGetCmd,		TclCompileBasic1Or2ArgCmd, NULL, NULL, 0},
+	{"names",	ArrayNamesCmd,		TclCompileBasic1To3ArgCmd, NULL, NULL, 0},
+	{"nextelement",	ArrayNextElementCmd,	TclCompileBasic2ArgCmd, NULL, NULL, 0},
+	{"set",		ArraySetCmd,		TclCompileArraySetCmd, NULL, NULL, 0},
+	{"size",	ArraySizeCmd,		TclCompileBasic1ArgCmd, NULL, NULL, 0},
+	{"startsearch",	ArrayStartSearchCmd,	TclCompileBasic1ArgCmd, NULL, NULL, 0},
+	{"statistics",	ArrayStatsCmd,		TclCompileBasic1ArgCmd, NULL, NULL, 0},
+	{"unset",	ArrayUnsetCmd,		TclCompileArrayUnsetCmd, NULL, NULL, 0},
+	{NULL, NULL, NULL, NULL, NULL, 0}
+    };
+
+    return TclMakeEnsemble(interp, "array", arrayImplMap);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ObjMakeUpvar --
+ *
+ *	This function does all of the work of the "global" and "upvar"
+ *	commands.
+ *
+ * Results:
+ *	A standard Tcl completion code. If an error occurs then an error
+ *	message is left in iPtr->result.
+ *
+ * Side effects:
+ *	The variable given by myName is linked to the variable in framePtr
+ *	given by otherP1 and otherP2, so that references to myName are
+ *	redirected to the other variable like a symbolic link.
+ *	Callers must Incr myNamePtr if they plan to Decr it.
+ *	Callers must Incr otherP1Ptr if they plan to Decr it.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+ObjMakeUpvar(
+    Tcl_Interp *interp,		/* Interpreter containing variables. Used for
+				 * error messages, too. */
+    CallFrame *framePtr,	/* Call frame containing "other" variable.
+				 * NULL means use global :: context. */
+    Tcl_Obj *otherP1Ptr,
+    const char *otherP2,	/* Two-part name of variable in framePtr. */
+    const int otherFlags,	/* 0, TCL_GLOBAL_ONLY or TCL_NAMESPACE_ONLY:
+				 * indicates scope of "other" variable. */
+    Tcl_Obj *myNamePtr,		/* Name of variable which will refer to
+				 * otherP1/otherP2. Must be a scalar. */
+    int myFlags,		/* 0, TCL_GLOBAL_ONLY or TCL_NAMESPACE_ONLY:
+				 * indicates scope of myName. */
+    int index)			/* If the variable to be linked is an indexed
+				 * scalar, this is its index. Otherwise, -1 */
+{
+    Interp *iPtr = (Interp *) interp;
+    Var *otherPtr, *arrayPtr;
+    CallFrame *varFramePtr;
+
+    /*
+     * Find "other" in "framePtr". If not looking up other in just the current
+     * namespace, temporarily replace the current var frame pointer in the
+     * interpreter in order to use TclObjLookupVar.
+     */
+
+    if (framePtr == NULL) {
+	framePtr = iPtr->rootFramePtr;
+    }
+
+    varFramePtr = iPtr->varFramePtr;
+    if (!(otherFlags & TCL_NAMESPACE_ONLY)) {
+	iPtr->varFramePtr = framePtr;
+    }
+    otherPtr = TclObjLookupVar(interp, otherP1Ptr, otherP2,
+	    (otherFlags | TCL_LEAVE_ERR_MSG), "access",
+	    /*createPart1*/ 1, /*createPart2*/ 1, &arrayPtr);
+    if (!(otherFlags & TCL_NAMESPACE_ONLY)) {
+	iPtr->varFramePtr = varFramePtr;
+    }
+    if (otherPtr == NULL) {
+	return TCL_ERROR;
+    }
+
+    /*
+     * Check that we are not trying to create a namespace var linked to a
+     * local variable in a procedure. If we allowed this, the local
+     * variable in the shorter-lived procedure frame could go away leaving
+     * the namespace var's reference invalid.
+     */
+
+    if (index < 0) {
+	if (!(arrayPtr != NULL
+		     ? (TclIsVarInHash(arrayPtr) && TclGetVarNsPtr(arrayPtr))
+		     : (TclIsVarInHash(otherPtr) && TclGetVarNsPtr(otherPtr)))
+		&& ((myFlags & (TCL_GLOBAL_ONLY | TCL_NAMESPACE_ONLY))
+			|| (varFramePtr == NULL)
+			|| !HasLocalVars(varFramePtr)
+			|| (strstr(TclGetString(myNamePtr), "::") != NULL))) {
+	    Tcl_SetObjResult((Tcl_Interp *) iPtr, Tcl_ObjPrintf(
+		    "bad variable name \"%s\": can't create namespace "
+		    "variable that refers to procedure variable",
+		    TclGetString(myNamePtr)));
+	    Tcl_SetErrorCode(interp, "TCL", "UPVAR", "INVERTED", NULL);
+	    return TCL_ERROR;
+	}
+    }
+
+    return TclPtrObjMakeUpvar(interp, otherPtr, myNamePtr, myFlags, index);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclPtrMakeUpvar --
+ *
+ *	This procedure does all of the work of the "global" and "upvar"
+ *	commands.
+ *
+ * Results:
+ *	A standard Tcl completion code. If an error occurs then an error
+ *	message is left in iPtr->result.
+ *
+ * Side effects:
+ *	The variable given by myName is linked to the variable in framePtr
+ *	given by otherP1 and otherP2, so that references to myName are
+ *	redirected to the other variable like a symbolic link.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclPtrMakeUpvar(
+    Tcl_Interp *interp,		/* Interpreter containing variables. Used for
+				 * error messages, too. */
+    Var *otherPtr,		/* Pointer to the variable being linked-to. */
+    const char *myName,		/* Name of variable which will refer to
+				 * otherP1/otherP2. Must be a scalar. */
+    int myFlags,		/* 0, TCL_GLOBAL_ONLY or TCL_NAMESPACE_ONLY:
+				 * indicates scope of myName. */
+    int index)			/* If the variable to be linked is an indexed
+				 * scalar, this is its index. Otherwise, -1 */
+{
+    Tcl_Obj *myNamePtr = NULL;
+    int result;
+
+    if (myName) {
+	myNamePtr = Tcl_NewStringObj(myName, -1);
+	Tcl_IncrRefCount(myNamePtr);
+    }
+    result = TclPtrObjMakeUpvar(interp, otherPtr, myNamePtr, myFlags, index);
+    if (myNamePtr) {
+	Tcl_DecrRefCount(myNamePtr);
+    }
+    return result;
+}
+
+/* Callers must Incr myNamePtr if they plan to Decr it. */
+
+int
+TclPtrObjMakeUpvar(
+    Tcl_Interp *interp,		/* Interpreter containing variables. Used for
+				 * error messages, too. */
+    Var *otherPtr,		/* Pointer to the variable being linked-to. */
+    Tcl_Obj *myNamePtr,		/* Name of variable which will refer to
+				 * otherP1/otherP2. Must be a scalar. */
+    int myFlags,		/* 0, TCL_GLOBAL_ONLY or TCL_NAMESPACE_ONLY:
+				 * indicates scope of myName. */
+    int index)			/* If the variable to be linked is an indexed
+				 * scalar, this is its index. Otherwise, -1 */
+{
+    Interp *iPtr = (Interp *) interp;
+    CallFrame *varFramePtr = iPtr->varFramePtr;
+    const char *errMsg, *p, *myName;
+    Var *varPtr;
+
+    if (index >= 0) {
+	if (!HasLocalVars(varFramePtr)) {
+	    Tcl_Panic("ObjMakeUpvar called with an index outside from a proc");
+	}
+	varPtr = (Var *) &(varFramePtr->compiledLocals[index]);
+	myNamePtr = localName(iPtr->varFramePtr, index);
+	myName = myNamePtr? TclGetString(myNamePtr) : NULL;
+    } else {
+	/*
+	 * Do not permit the new variable to look like an array reference, as
+	 * it will not be reachable in that case [Bug 600812, TIP 184]. The
+	 * "definition" of what "looks like an array reference" is consistent
+	 * (and must remain consistent) with the code in TclObjLookupVar().
+	 */
+
+	myName = TclGetString(myNamePtr);
+	p = strstr(myName, "(");
+	if (p != NULL) {
+	    p += strlen(p)-1;
+	    if (*p == ')') {
+		/*
+		 * myName looks like an array reference.
+		 */
+
+		Tcl_SetObjResult((Tcl_Interp *) iPtr, Tcl_ObjPrintf(
+			"bad variable name \"%s\": can't create a scalar "
+			"variable that looks like an array element", myName));
+		Tcl_SetErrorCode(interp, "TCL", "UPVAR", "LOCAL_ELEMENT",
+			NULL);
+		return TCL_ERROR;
+	    }
+	}
+
+	/*
+	 * Lookup and eventually create the new variable. Set the flag bit
+	 * TCL_AVOID_RESOLVERS to indicate the special resolution rules for
+	 * upvar purposes:
+	 *   - Bug #696893 - variable is either proc-local or in the current
+	 *     namespace; never follow the second (global) resolution path.
+	 *   - Bug #631741 - do not use special namespace or interp resolvers.
+	 */
+
+	varPtr = TclLookupSimpleVar(interp, myNamePtr,
+		myFlags|TCL_AVOID_RESOLVERS, /* create */ 1, &errMsg, &index);
+	if (varPtr == NULL) {
+	    TclObjVarErrMsg(interp, myNamePtr, NULL, "create", errMsg, -1);
+	    Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "VARNAME",
+		    TclGetString(myNamePtr), NULL);
+	    return TCL_ERROR;
+	}
+    }
+
+    if (varPtr == otherPtr) {
+	Tcl_SetObjResult((Tcl_Interp *) iPtr, Tcl_NewStringObj(
+		"can't upvar from variable to itself", -1));
+	Tcl_SetErrorCode(interp, "TCL", "UPVAR", "SELF", NULL);
+	return TCL_ERROR;
+    }
+
+    if (TclIsVarTraced(varPtr)) {
+	Tcl_SetObjResult((Tcl_Interp *) iPtr, Tcl_ObjPrintf(
+		"variable \"%s\" has traces: can't use for upvar", myName));
+	Tcl_SetErrorCode(interp, "TCL", "UPVAR", "TRACED", NULL);
+	return TCL_ERROR;
+    } else if (!TclIsVarUndefined(varPtr)) {
+	Var *linkPtr;
+
+	/*
+	 * The variable already existed. Make sure this variable "varPtr"
+	 * isn't the same as "otherPtr" (avoid circular links). Also, if it's
+	 * not an upvar then it's an error. If it is an upvar, then just
+	 * disconnect it from the thing it currently refers to.
+	 */
+
+	if (!TclIsVarLink(varPtr)) {
+	    Tcl_SetObjResult((Tcl_Interp *) iPtr, Tcl_ObjPrintf(
+		    "variable \"%s\" already exists", myName));
+	    Tcl_SetErrorCode(interp, "TCL", "UPVAR", "EXISTS", NULL);
+	    return TCL_ERROR;
+	}
+
+	linkPtr = varPtr->value.linkPtr;
+	if (linkPtr == otherPtr) {
+	    return TCL_OK;
+	}
+	if (TclIsVarInHash(linkPtr)) {
+	    VarHashRefCount(linkPtr)--;
+	    if (TclIsVarUndefined(linkPtr)) {
+		CleanupVar(linkPtr, NULL);
+	    }
+	}
+    }
+    TclSetVarLink(varPtr);
+    varPtr->value.linkPtr = otherPtr;
+    if (TclIsVarInHash(otherPtr)) {
+	VarHashRefCount(otherPtr)++;
+    }
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_UpVar --
+ *
+ *	This function links one variable to another, just like the "upvar"
+ *	command.
+ *
+ * Results:
+ *	A standard Tcl completion code. If an error occurs then an error
+ *	message is left in the interp's result.
+ *
+ * Side effects:
+ *	The variable in frameName whose name is given by varName becomes
+ *	accessible under the name localNameStr, so that references to
+ *	localNameStr are redirected to the other variable like a symbolic
+ *	link.
+ *
+ *----------------------------------------------------------------------
+ */
+
+#undef Tcl_UpVar
+int
+Tcl_UpVar(
+    Tcl_Interp *interp,		/* Command interpreter in which varName is to
+				 * be looked up. */
+    const char *frameName,	/* Name of the frame containing the source
+				 * variable, such as "1" or "#0". */
+    const char *varName,	/* Name of a variable in interp to link to.
+				 * May be either a scalar name or an element
+				 * in an array. */
+    const char *localNameStr,	/* Name of link variable. */
+    int flags)			/* 0, TCL_GLOBAL_ONLY or TCL_NAMESPACE_ONLY:
+				 * indicates scope of localNameStr. */
+{
+    int result;
+    CallFrame *framePtr;
+    Tcl_Obj *varNamePtr, *localNamePtr;
+
+    if (TclGetFrame(interp, frameName, &framePtr) == -1) {
+	return TCL_ERROR;
+    }
+
+    varNamePtr = Tcl_NewStringObj(varName, -1);
+    Tcl_IncrRefCount(varNamePtr);
+    localNamePtr = Tcl_NewStringObj(localNameStr, -1);
+    Tcl_IncrRefCount(localNamePtr);
+
+    result = ObjMakeUpvar(interp, framePtr, varNamePtr, NULL, 0,
+	    localNamePtr, flags, -1);
+    Tcl_DecrRefCount(varNamePtr);
+    Tcl_DecrRefCount(localNamePtr);
+    return result;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_UpVar2 --
+ *
+ *	This function links one variable to another, just like the "upvar"
+ *	command.
+ *
+ * Results:
+ *	A standard Tcl completion code. If an error occurs then an error
+ *	message is left in the interp's result.
+ *
+ * Side effects:
+ *	The variable in frameName whose name is given by part1 and part2
+ *	becomes accessible under the name localNameStr, so that references to
+ *	localNameStr are redirected to the other variable like a symbolic
+ *	link.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_UpVar2(
+    Tcl_Interp *interp,		/* Interpreter containing variables. Used for
+				 * error messages too. */
+    const char *frameName,	/* Name of the frame containing the source
+				 * variable, such as "1" or "#0". */
+    const char *part1,
+    const char *part2,		/* Two parts of source variable name to link
+				 * to. */
+    const char *localNameStr,	/* Name of link variable. */
+    int flags)			/* 0, TCL_GLOBAL_ONLY or TCL_NAMESPACE_ONLY:
+				 * indicates scope of localNameStr. */
+{
+    int result;
+    CallFrame *framePtr;
+    Tcl_Obj *part1Ptr, *localNamePtr;
+
+    if (TclGetFrame(interp, frameName, &framePtr) == -1) {
+	return TCL_ERROR;
+    }
+
+    part1Ptr = Tcl_NewStringObj(part1, -1);
+    Tcl_IncrRefCount(part1Ptr);
+    localNamePtr = Tcl_NewStringObj(localNameStr, -1);
+    Tcl_IncrRefCount(localNamePtr);
+
+    result = ObjMakeUpvar(interp, framePtr, part1Ptr, part2, 0,
+	    localNamePtr, flags, -1);
+    Tcl_DecrRefCount(part1Ptr);
+    Tcl_DecrRefCount(localNamePtr);
+    return result;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_GetVariableFullName --
+ *
+ *	Given a Tcl_Var token returned by Tcl_FindNamespaceVar, this function
+ *	appends to an object the namespace variable's full name, qualified by
+ *	a sequence of parent namespace names.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The variable's fully-qualified name is appended to the string
+ *	representation of objPtr.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_GetVariableFullName(
+    Tcl_Interp *interp,		/* Interpreter containing the variable. */
+    Tcl_Var variable,		/* Token for the variable returned by a
+				 * previous call to Tcl_FindNamespaceVar. */
+    Tcl_Obj *objPtr)		/* Points to the object onto which the
+				 * variable's full name is appended. */
+{
+    Interp *iPtr = (Interp *) interp;
+    register Var *varPtr = (Var *) variable;
+    Tcl_Obj *namePtr;
+    Namespace *nsPtr;
+
+    if (!varPtr || TclIsVarArrayElement(varPtr)) {
+	return;
+    }
+
+    /*
+     * Add the full name of the containing namespace (if any), followed by the
+     * "::" separator, then the variable name.
+     */
+
+    nsPtr = TclGetVarNsPtr(varPtr);
+    if (nsPtr) {
+	Tcl_AppendToObj(objPtr, nsPtr->fullName, -1);
+	if (nsPtr != iPtr->globalNsPtr) {
+	    Tcl_AppendToObj(objPtr, "::", 2);
+	}
+    }
+    if (TclIsVarInHash(varPtr)) {
+	if (!TclIsVarDeadHash(varPtr)) {
+	    namePtr = VarHashGetKey(varPtr);
+	    Tcl_AppendObjToObj(objPtr, namePtr);
+	}
+    } else if (iPtr->varFramePtr->procPtr) {
+	int index = varPtr - iPtr->varFramePtr->compiledLocals;
+
+	if (index >= 0 && index < iPtr->varFramePtr->numCompiledLocals) {
+	    namePtr = localName(iPtr->varFramePtr, index);
+	    Tcl_AppendObjToObj(objPtr, namePtr);
+	}
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_GlobalObjCmd --
+ *
+ *	This object-based function is invoked to process the "global" Tcl
+ *	command. See the user documentation for details on what it does.
+ *
+ * Results:
+ *	A standard Tcl object result value.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_GlobalObjCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    Interp *iPtr = (Interp *) interp;
+    register Tcl_Obj *objPtr, *tailPtr;
+    const char *varName;
+    register const char *tail;
+    int result, i;
+
+    /*
+     * If we are not executing inside a Tcl procedure, just return.
+     */
+
+    if (!HasLocalVars(iPtr->varFramePtr)) {
+	return TCL_OK;
+    }
+
+    for (i=1 ; i<objc ; i++) {
+	/*
+	 * Make a local variable linked to its counterpart in the global ::
+	 * namespace.
+	 */
+
+	objPtr = objv[i];
+	varName = TclGetString(objPtr);
+
+	/*
+	 * The variable name might have a scope qualifier, but the name for
+	 * the local "link" variable must be the simple name at the tail.
+	 */
+
+	for (tail=varName ; *tail!='\0' ; tail++) {
+	    /* empty body */
+	}
+	while ((tail > varName) && ((*tail != ':') || (*(tail-1) != ':'))) {
+	    tail--;
+	}
+	if ((*tail == ':') && (tail > varName)) {
+	    tail++;
+	}
+
+	if (tail == varName) {
+	    tailPtr = objPtr;
+	} else {
+	    tailPtr = Tcl_NewStringObj(tail, -1);
+	    Tcl_IncrRefCount(tailPtr);
+	}
+
+	/*
+	 * Link to the variable "varName" in the global :: namespace.
+	 */
+
+	result = ObjMakeUpvar(interp, NULL, objPtr, NULL,
+		TCL_GLOBAL_ONLY, /*myName*/ tailPtr, /*myFlags*/ 0, -1);
+
+	if (tail != varName) {
+	    Tcl_DecrRefCount(tailPtr);
+	}
+
+	if (result != TCL_OK) {
+	    return result;
+	}
+    }
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_VariableObjCmd --
+ *
+ *	Invoked to implement the "variable" command that creates one or more
+ *	global variables. Handles the following syntax:
+ *
+ *	    variable ?name value...? name ?value?
+ *
+ *	One or more variables can be created. The variables are initialized
+ *	with the specified values. The value for the last variable is
+ *	optional.
+ *
+ *	If the variable does not exist, it is created and given the optional
+ *	value. If it already exists, it is simply set to the optional value.
+ *	Normally, "name" is an unqualified name, so it is created in the
+ *	current namespace. If it includes namespace qualifiers, it can be
+ *	created in another namespace.
+ *
+ *	If the variable command is executed inside a Tcl procedure, it creates
+ *	a local variable linked to the newly-created namespace variable.
+ *
+ * Results:
+ *	Returns TCL_OK if the variable is found or created. Returns TCL_ERROR
+ *	if anything goes wrong.
+ *
+ * Side effects:
+ *	If anything goes wrong, this function returns an error message as the
+ *	result in the interpreter's result object.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_VariableObjCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    Interp *iPtr = (Interp *) interp;
+    const char *varName, *tail, *cp;
+    Var *varPtr, *arrayPtr;
+    Tcl_Obj *varValuePtr;
+    int i, result;
+    Tcl_Obj *varNamePtr, *tailPtr;
+
+    for (i=1 ; i<objc ; i+=2) {
+	/*
+	 * Look up each variable in the current namespace context, creating it
+	 * if necessary.
+	 */
+
+	varNamePtr = objv[i];
+	varName = TclGetString(varNamePtr);
+	varPtr = TclObjLookupVarEx(interp, varNamePtr, NULL,
+		(TCL_NAMESPACE_ONLY | TCL_LEAVE_ERR_MSG), "define",
+		/*createPart1*/ 1, /*createPart2*/ 0, &arrayPtr);
+
+	if (arrayPtr != NULL) {
+	    /*
+	     * Variable cannot be an element in an array. If arrayPtr is
+	     * non-NULL, it is, so throw up an error and return.
+	     */
+
+	    TclObjVarErrMsg(interp, varNamePtr, NULL, "define",
+		    isArrayElement, -1);
+	    Tcl_SetErrorCode(interp, "TCL", "UPVAR", "LOCAL_ELEMENT", NULL);
+	    return TCL_ERROR;
+	}
+
+	if (varPtr == NULL) {
+	    return TCL_ERROR;
+	}
+
+	/*
+	 * Mark the variable as a namespace variable and increment its
+	 * reference count so that it will persist until its namespace is
+	 * destroyed or until the variable is unset.
+	 */
+
+	TclSetVarNamespaceVar(varPtr);
+
+	/*
+	 * If a value was specified, set the variable to that value.
+	 * Otherwise, if the variable is new, leave it undefined. (If the
+	 * variable already exists and no value was specified, leave its value
+	 * unchanged; just create the local link if we're in a Tcl procedure).
+	 */
+
+	if (i+1 < objc) {	/* A value was specified. */
+	    varValuePtr = TclPtrSetVar(interp, varPtr, arrayPtr, varNamePtr,
+		    NULL, objv[i+1], TCL_NAMESPACE_ONLY|TCL_LEAVE_ERR_MSG,-1);
+	    if (varValuePtr == NULL) {
+		return TCL_ERROR;
+	    }
+	}
+
+	/*
+	 * If we are executing inside a Tcl procedure, create a local variable
+	 * linked to the new namespace variable "varName".
+	 */
+
+	if (HasLocalVars(iPtr->varFramePtr)) {
+	    /*
+	     * varName might have a scope qualifier, but the name for the
+	     * local "link" variable must be the simple name at the tail.
+	     *
+	     * Locate tail in one pass: drop any prefix after two *or more*
+	     * consecutive ":" characters).
+	     */
+
+	    for (tail=cp=varName ; *cp!='\0' ;) {
+		if (*cp++ == ':') {
+		    while (*cp == ':') {
+			tail = ++cp;
+		    }
+		}
+	    }
+
+	    /*
+	     * Create a local link "tail" to the variable "varName" in the
+	     * current namespace.
+	     */
+
+	    if (tail == varName) {
+		tailPtr = varNamePtr;
+	    } else {
+		tailPtr = Tcl_NewStringObj(tail, -1);
+		Tcl_IncrRefCount(tailPtr);
+	    }
+
+	    result = ObjMakeUpvar(interp, NULL, varNamePtr, /*otherP2*/ NULL,
+		    /*otherFlags*/ TCL_NAMESPACE_ONLY,
+		    /*myName*/ tailPtr, /*myFlags*/ 0, -1);
+
+	    if (tail != varName) {
+		Tcl_DecrRefCount(tailPtr);
+	    }
+
+	    if (result != TCL_OK) {
+		return result;
+	    }
+	}
+    }
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_UpvarObjCmd --
+ *
+ *	This object-based function is invoked to process the "upvar" Tcl
+ *	command. See the user documentation for details on what it does.
+ *
+ * Results:
+ *	A standard Tcl object result value.
+ *
+ * Side effects:
+ *	See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+	/* ARGSUSED */
+int
+Tcl_UpvarObjCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    CallFrame *framePtr;
+    int result, hasLevel;
+    Tcl_Obj *levelObj;
+
+    if (objc < 3) {
+	Tcl_WrongNumArgs(interp, 1, objv,
+		"?level? otherVar localVar ?otherVar localVar ...?");
+	return TCL_ERROR;
+    }
+
+    if (objc & 1) {
+	/*
+	 * Even number of arguments, so use the default level of "1" by
+	 * passing NULL to TclObjGetFrame.
+	 */
+
+	levelObj = NULL;
+	hasLevel = 0;
+    } else {
+	/*
+	 * Odd number of arguments, so objv[1] must contain the level.
+	 */
+
+	levelObj = objv[1];
+	hasLevel = 1;
+    }
+
+    /*
+     * Find the call frame containing each of the "other variables" to be
+     * linked to.
+     */
+
+    result = TclObjGetFrame(interp, levelObj, &framePtr);
+    if (result == -1) {
+	return TCL_ERROR;
+    }
+    if ((result == 0) && hasLevel) {
+	/*
+	 * Synthesize an error message since TclObjGetFrame doesn't do this
+	 * for this particular case.
+	 */
+
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		"bad level \"%s\"", TclGetString(levelObj)));
+	Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "LEVEL",
+		TclGetString(levelObj), NULL);
+	return TCL_ERROR;
+    }
+
+    /*
+     * We've now finished with parsing levels; skip to the variable names.
+     */
+
+    objc -= hasLevel + 1;
+    objv += hasLevel + 1;
+
+    /*
+     * Iterate over each (other variable, local variable) pair. Divide the
+     * other variable name into two parts, then call MakeUpvar to do all the
+     * work of linking it to the local variable.
+     */
+
+    for (; objc>0 ; objc-=2, objv+=2) {
+	result = ObjMakeUpvar(interp, framePtr, /* othervarName */ objv[0],
+		NULL, 0, /* myVarName */ objv[1], /*flags*/ 0, -1);
+	if (result != TCL_OK) {
+	    return TCL_ERROR;
+	}
+    }
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * SetArraySearchObj --
+ *
+ *	This function converts the given tcl object into one that has the
+ *	"array search" internal type.
+ *
+ * Results:
+ *	TCL_OK if the conversion succeeded, and TCL_ERROR if it failed (when
+ *	an error message will be placed in the interpreter's result.)
+ *
+ * Side effects:
+ *	Updates the internal type and representation of the object to make
+ *	this an array-search object. See the tclArraySearchType declaration
+ *	above for details of the internal representation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+SetArraySearchObj(
+    Tcl_Interp *interp,
+    Tcl_Obj *objPtr)
+{
+    const char *string;
+    char *end;			/* Can't be const due to strtoul defn. */
+    int id;
+    size_t offset;
+
+    /*
+     * Get the string representation. Make it up-to-date if necessary.
+     */
+
+    string = TclGetString(objPtr);
+
+    /*
+     * Parse the id into the three parts separated by dashes.
+     */
+
+    if ((string[0] != 's') || (string[1] != '-')) {
+	goto syntax;
+    }
+    id = strtoul(string+2, &end, 10);
+    if ((end == (string+2)) || (*end != '-')) {
+	goto syntax;
+    }
+
+    /*
+     * Can't perform value check in this context, so place reference to place
+     * in string to use for the check in the object instead.
+     */
+
+    end++;
+    offset = end - string;
+
+    TclFreeIntRep(objPtr);
+    objPtr->typePtr = &tclArraySearchType;
+    objPtr->internalRep.twoPtrValue.ptr1 = INT2PTR(id);
+    objPtr->internalRep.twoPtrValue.ptr2 = INT2PTR(offset);
+    return TCL_OK;
+
+  syntax:
+    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+	    "illegal search identifier \"%s\"", string));
+    Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "ARRAYSEARCH", string, NULL);
+    return TCL_ERROR;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ParseSearchId --
+ *
+ *	This function translates from a tcl object to a pointer to an active
+ *	array search (if there is one that matches the string).
+ *
+ * Results:
+ *	The return value is a pointer to the array search indicated by string,
+ *	or NULL if there isn't one. If NULL is returned, the interp's result
+ *	contains an error message.
+ *
+ * Side effects:
+ *	The tcl object might have its internal type and representation
+ *	modified.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static ArraySearch *
+ParseSearchId(
+    Tcl_Interp *interp,		/* Interpreter containing variable. */
+    const Var *varPtr,		/* Array variable search is for. */
+    Tcl_Obj *varNamePtr,	/* Name of array variable that search is
+				 * supposed to be for. */
+    Tcl_Obj *handleObj)		/* Object containing id of search. Must have
+				 * form "search-num-var" where "num" is a
+				 * decimal number and "var" is a variable
+				 * name. */
+{
+    Interp *iPtr = (Interp *) interp;
+    register const char *string;
+    register size_t offset;
+    int id;
+    ArraySearch *searchPtr;
+    const char *varName = TclGetString(varNamePtr);
+
+    /*
+     * Parse the id.
+     */
+
+    if ((handleObj->typePtr != &tclArraySearchType)
+	    && (SetArraySearchObj(interp, handleObj) != TCL_OK)) {
+	return NULL;
+    }
+
+    /*
+     * Extract the information out of the Tcl_Obj.
+     */
+
+    id = PTR2INT(handleObj->internalRep.twoPtrValue.ptr1);
+    string = TclGetString(handleObj);
+    offset = PTR2INT(handleObj->internalRep.twoPtrValue.ptr2);
+
+    /*
+     * This test cannot be placed inside the Tcl_Obj machinery, since it is
+     * dependent on the variable context.
+     */
+
+    if (strcmp(string+offset, varName) != 0) {
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		"search identifier \"%s\" isn't for variable \"%s\"",
+		string, varName));
+	goto badLookup;
+    }
+
+    /*
+     * Search through the list of active searches on the interpreter to see if
+     * the desired one exists.
+     *
+     * Note that we cannot store the searchPtr directly in the Tcl_Obj as that
+     * would run into trouble when DeleteSearches() was called so we must scan
+     * this list every time.
+     */
+
+    if (varPtr->flags & VAR_SEARCH_ACTIVE) {
+	Tcl_HashEntry *hPtr =
+		Tcl_FindHashEntry(&iPtr->varSearches, varPtr);
+
+	for (searchPtr = Tcl_GetHashValue(hPtr); searchPtr != NULL;
+		searchPtr = searchPtr->nextPtr) {
+	    if (searchPtr->id == id) {
+		return searchPtr;
+	    }
+	}
+    }
+    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+	    "couldn't find search \"%s\"", string));
+  badLookup:
+    Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "ARRAYSEARCH", string, NULL);
+    return NULL;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * DeleteSearches --
+ *
+ *	This function is called to free up all of the searches associated
+ *	with an array variable.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Memory is released to the storage allocator.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+DeleteSearches(
+    Interp *iPtr,
+    register Var *arrayVarPtr)	/* Variable whose searches are to be
+				 * deleted. */
+{
+    ArraySearch *searchPtr, *nextPtr;
+    Tcl_HashEntry *sPtr;
+
+    if (arrayVarPtr->flags & VAR_SEARCH_ACTIVE) {
+	sPtr = Tcl_FindHashEntry(&iPtr->varSearches, arrayVarPtr);
+	for (searchPtr = Tcl_GetHashValue(sPtr); searchPtr != NULL;
+		searchPtr = nextPtr) {
+	    nextPtr = searchPtr->nextPtr;
+	    ckfree(searchPtr);
+	}
+	arrayVarPtr->flags &= ~VAR_SEARCH_ACTIVE;
+	Tcl_DeleteHashEntry(sPtr);
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclDeleteNamespaceVars --
+ *
+ *	This function is called to recycle all the storage space associated
+ *	with a namespace's table of variables.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Variables are deleted and trace functions are invoked, if any are
+ *	declared.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclDeleteNamespaceVars(
+    Namespace *nsPtr)
+{
+    TclVarHashTable *tablePtr = &nsPtr->varTable;
+    Tcl_Interp *interp = nsPtr->interp;
+    Interp *iPtr = (Interp *)interp;
+    Tcl_HashSearch search;
+    int flags = 0;
+    Var *varPtr;
+
+    /*
+     * Determine what flags to pass to the trace callback functions.
+     */
+
+    if (nsPtr == iPtr->globalNsPtr) {
+	flags = TCL_GLOBAL_ONLY;
+    } else if (nsPtr == (Namespace *) TclGetCurrentNamespace(interp)) {
+	flags = TCL_NAMESPACE_ONLY;
+    }
+
+    for (varPtr = VarHashFirstVar(tablePtr, &search);  varPtr != NULL;
+	    varPtr = VarHashFirstVar(tablePtr, &search)) {
+	Tcl_Obj *objPtr = Tcl_NewObj();
+	VarHashRefCount(varPtr)++;	/* Make sure we get to remove from
+					 * hash. */
+	Tcl_GetVariableFullName(interp, (Tcl_Var) varPtr, objPtr);
+	UnsetVarStruct(varPtr, NULL, iPtr, /* part1 */ objPtr, NULL, flags,
+		-1);
+	Tcl_DecrRefCount(objPtr);	/* Free no longer needed obj */
+
+	/*
+	 * Remove the variable from the table and force it undefined in case
+	 * an unset trace brought it back from the dead.
+	 */
+
+	if (TclIsVarTraced(varPtr)) {
+	    Tcl_HashEntry *tPtr = Tcl_FindHashEntry(&iPtr->varTraces, varPtr);
+	    VarTrace *tracePtr = Tcl_GetHashValue(tPtr);
+	    ActiveVarTrace *activePtr;
+
+	    while (tracePtr) {
+		VarTrace *prevPtr = tracePtr;
+
+		tracePtr = tracePtr->nextPtr;
+		prevPtr->nextPtr = NULL;
+		Tcl_EventuallyFree(prevPtr, TCL_DYNAMIC);
+	    }
+	    Tcl_DeleteHashEntry(tPtr);
+	    varPtr->flags &= ~VAR_ALL_TRACES;
+	    for (activePtr = iPtr->activeVarTracePtr; activePtr != NULL;
+		    activePtr = activePtr->nextPtr) {
+		if (activePtr->varPtr == varPtr) {
+		    activePtr->nextTracePtr = NULL;
+		}
+	    }
+	}
+	VarHashRefCount(varPtr)--;
+	VarHashDeleteEntry(varPtr);
+    }
+    VarHashDeleteTable(tablePtr);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclDeleteVars --
+ *
+ *	This function is called to recycle all the storage space associated
+ *	with a table of variables. For this function to work correctly, it
+ *	must not be possible for any of the variables in the table to be
+ *	accessed from Tcl commands (e.g. from trace functions).
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Variables are deleted and trace functions are invoked, if any are
+ *	declared.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclDeleteVars(
+    Interp *iPtr,		/* Interpreter to which variables belong. */
+    TclVarHashTable *tablePtr)	/* Hash table containing variables to
+				 * delete. */
+{
+    Tcl_Interp *interp = (Tcl_Interp *) iPtr;
+    Tcl_HashSearch search;
+    register Var *varPtr;
+    int flags;
+    Namespace *currNsPtr = (Namespace *) TclGetCurrentNamespace(interp);
+
+    /*
+     * Determine what flags to pass to the trace callback functions.
+     */
+
+    flags = TCL_TRACE_UNSETS;
+    if (tablePtr == &iPtr->globalNsPtr->varTable) {
+	flags |= TCL_GLOBAL_ONLY;
+    } else if (tablePtr == &currNsPtr->varTable) {
+	flags |= TCL_NAMESPACE_ONLY;
+    }
+
+    for (varPtr = VarHashFirstVar(tablePtr, &search); varPtr != NULL;
+	 varPtr = VarHashFirstVar(tablePtr, &search)) {
+	UnsetVarStruct(varPtr, NULL, iPtr, VarHashGetKey(varPtr), NULL, flags,
+		-1);
+	VarHashDeleteEntry(varPtr);
+    }
+    VarHashDeleteTable(tablePtr);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclDeleteCompiledLocalVars --
+ *
+ *	This function is called to recycle storage space associated with the
+ *	compiler-allocated array of local variables in a procedure call frame.
+ *	This function resembles TclDeleteVars above except that each variable
+ *	is stored in a call frame and not a hash table. For this function to
+ *	work correctly, it must not be possible for any of the variable in the
+ *	table to be accessed from Tcl commands (e.g. from trace functions).
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Variables are deleted and trace functions are invoked, if any are
+ *	declared.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclDeleteCompiledLocalVars(
+    Interp *iPtr,		/* Interpreter to which variables belong. */
+    CallFrame *framePtr)	/* Procedure call frame containing compiler-
+				 * assigned local variables to delete. */
+{
+    register Var *varPtr;
+    int numLocals, i;
+    Tcl_Obj **namePtrPtr;
+
+    numLocals = framePtr->numCompiledLocals;
+    varPtr = framePtr->compiledLocals;
+    namePtrPtr = &localName(framePtr, 0);
+    for (i=0 ; i<numLocals ; i++, namePtrPtr++, varPtr++) {
+	UnsetVarStruct(varPtr, NULL, iPtr, *namePtrPtr, NULL,
+		TCL_TRACE_UNSETS, i);
+    }
+    framePtr->numCompiledLocals = 0;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * DeleteArray --
+ *
+ *	This function is called to free up everything in an array variable.
+ *	It's the caller's responsibility to make sure that the array is no
+ *	longer accessible before this function is called.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	All storage associated with varPtr's array elements is deleted
+ *	(including the array's hash table). Deletion trace functions for
+ *	array elements are invoked, then deleted. Any pending traces for array
+ *	elements are also deleted.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+DeleteArray(
+    Interp *iPtr,		/* Interpreter containing array. */
+    Tcl_Obj *arrayNamePtr,	/* Name of array (used for trace callbacks),
+				 * or NULL if it is to be computed on
+				 * demand. */
+    Var *varPtr,		/* Pointer to variable structure. */
+    int flags,			/* Flags to pass to TclCallVarTraces:
+				 * TCL_TRACE_UNSETS and sometimes
+				 * TCL_NAMESPACE_ONLY or TCL_GLOBAL_ONLY. */
+    int index)
+{
+    Tcl_HashSearch search;
+    Tcl_HashEntry *tPtr;
+    register Var *elPtr;
+    ActiveVarTrace *activePtr;
+    Tcl_Obj *objPtr;
+    VarTrace *tracePtr;
+
+    if (varPtr->flags & VAR_SEARCH_ACTIVE) {
+	DeleteSearches(iPtr, varPtr);
+    }
+    for (elPtr = VarHashFirstVar(varPtr->value.tablePtr, &search);
+	    elPtr != NULL; elPtr = VarHashNextVar(&search)) {
+	if (TclIsVarScalar(elPtr) && (elPtr->value.objPtr != NULL)) {
+	    objPtr = elPtr->value.objPtr;
+	    TclDecrRefCount(objPtr);
+	    elPtr->value.objPtr = NULL;
+	}
+
+	/*
+	 * Lie about the validity of the hashtable entry. In this way the
+	 * variables will be deleted by VarHashDeleteTable.
+	 */
+
+	VarHashInvalidateEntry(elPtr);
+	if (TclIsVarTraced(elPtr)) {
+	    /*
+	     * Compute the array name if it was not supplied.
+	     */
+
+	    if (elPtr->flags & VAR_TRACED_UNSET) {
+		Tcl_Obj *elNamePtr = VarHashGetKey(elPtr);
+
+		elPtr->flags &= ~VAR_TRACE_ACTIVE;
+		TclObjCallVarTraces(iPtr, NULL, elPtr, arrayNamePtr,
+			elNamePtr, flags,/* leaveErrMsg */ 0, index);
+	    }
+	    tPtr = Tcl_FindHashEntry(&iPtr->varTraces, elPtr);
+	    tracePtr = Tcl_GetHashValue(tPtr);
+	    while (tracePtr) {
+		VarTrace *prevPtr = tracePtr;
+
+		tracePtr = tracePtr->nextPtr;
+		prevPtr->nextPtr = NULL;
+		Tcl_EventuallyFree(prevPtr, TCL_DYNAMIC);
+	    }
+	    Tcl_DeleteHashEntry(tPtr);
+	    elPtr->flags &= ~VAR_ALL_TRACES;
+	    for (activePtr = iPtr->activeVarTracePtr; activePtr != NULL;
+		    activePtr = activePtr->nextPtr) {
+		if (activePtr->varPtr == elPtr) {
+		    activePtr->nextTracePtr = NULL;
+		}
+	    }
+	}
+	TclSetVarUndefined(elPtr);
+
+	/*
+	 * Even though array elements are not supposed to be namespace
+	 * variables, some combinations of [upvar] and [variable] may create
+	 * such beasts - see [Bug 604239]. This is necessary to avoid leaking
+	 * the corresponding Var struct, and is otherwise harmless.
+	 */
+
+	TclClearVarNamespaceVar(elPtr);
+    }
+    VarHashDeleteTable(varPtr->value.tablePtr);
+    ckfree(varPtr->value.tablePtr);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclObjVarErrMsg --
+ *
+ *	Generate a reasonable error message describing why a variable
+ *	operation failed.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The interp's result is set to hold a message identifying the variable
+ *	given by part1 and part2 and describing why the variable operation
+ *	failed.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclVarErrMsg(
+    Tcl_Interp *interp,		/* Interpreter in which to record message. */
+    const char *part1,
+    const char *part2,		/* Variable's two-part name. */
+    const char *operation,	/* String describing operation that failed,
+				 * e.g. "read", "set", or "unset". */
+    const char *reason)		/* String describing why operation failed. */
+{
+    Tcl_Obj *part2Ptr = NULL, *part1Ptr = Tcl_NewStringObj(part1, -1);
+
+    if (part2) {
+	part2Ptr = Tcl_NewStringObj(part2, -1);
+    }
+
+    TclObjVarErrMsg(interp, part1Ptr, part2Ptr, operation, reason, -1);
+
+    Tcl_DecrRefCount(part1Ptr);
+    if (part2Ptr) {
+	Tcl_DecrRefCount(part2Ptr);
+    }
+}
+
+void
+TclObjVarErrMsg(
+    Tcl_Interp *interp,		/* Interpreter in which to record message. */
+    Tcl_Obj *part1Ptr,		/* (may be NULL, if index >= 0) */
+    Tcl_Obj *part2Ptr,		/* Variable's two-part name. */
+    const char *operation,	/* String describing operation that failed,
+				 * e.g. "read", "set", or "unset". */
+    const char *reason,		/* String describing why operation failed. */
+    int index)			/* Index into the local variable table of the
+				 * variable, or -1. Only used when part1Ptr is
+				 * NULL. */
+{
+    if (!part1Ptr) {
+	if (index == -1) {
+	    Tcl_Panic("invalid part1Ptr and invalid index together");
+	}
+	part1Ptr = localName(((Interp *)interp)->varFramePtr, index);
+    }
+    Tcl_SetObjResult(interp, Tcl_ObjPrintf("can't %s \"%s%s%s%s\": %s",
+	    operation, TclGetString(part1Ptr), (part2Ptr ? "(" : ""),
+	    (part2Ptr ? TclGetString(part2Ptr) : ""), (part2Ptr ? ")" : ""),
+	    reason));
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Internal functions for variable name object types --
+ *
+ *----------------------------------------------------------------------
+ */
+
+/*
+ * Panic functions that should never be called in normal operation.
+ */
+
+static void
+PanicOnUpdateVarName(
+    Tcl_Obj *objPtr)
+{
+    Tcl_Panic("%s of type %s should not be called", "updateStringProc",
+	    objPtr->typePtr->name);
+}
+
+static int
+PanicOnSetVarName(
+    Tcl_Interp *interp,
+    Tcl_Obj *objPtr)
+{
+    Tcl_Panic("%s of type %s should not be called", "setFromAnyProc",
+	    objPtr->typePtr->name);
+    return TCL_ERROR;
+}
+
+/*
+ * localVarName -
+ *
+ * INTERNALREP DEFINITION:
+ *   twoPtrValue.ptr1:   pointer to name obj in varFramePtr->localCache
+ *			  or NULL if it is this same obj
+ *   twoPtrValue.ptr2: index into locals table
+ */
+
+static void
+FreeLocalVarName(
+    Tcl_Obj *objPtr)
+{
+    Tcl_Obj *namePtr = objPtr->internalRep.twoPtrValue.ptr1;
+
+    if (namePtr) {
+	Tcl_DecrRefCount(namePtr);
+    }
+    objPtr->typePtr = NULL;
+}
+
+static void
+DupLocalVarName(
+    Tcl_Obj *srcPtr,
+    Tcl_Obj *dupPtr)
+{
+    Tcl_Obj *namePtr = srcPtr->internalRep.twoPtrValue.ptr1;
+
+    if (!namePtr) {
+	namePtr = srcPtr;
+    }
+    dupPtr->internalRep.twoPtrValue.ptr1 = namePtr;
+    Tcl_IncrRefCount(namePtr);
+
+    dupPtr->internalRep.twoPtrValue.ptr2 =
+	    srcPtr->internalRep.twoPtrValue.ptr2;
+    dupPtr->typePtr = &localVarNameType;
+}
+
+/*
+ * parsedVarName -
+ *
+ * INTERNALREP DEFINITION:
+ *   twoPtrValue.ptr1 = pointer to the array name Tcl_Obj (NULL if scalar)
+ *   twoPtrValue.ptr2 = pointer to the element name string (owned by this
+ *			Tcl_Obj), or NULL if it is a scalar variable
+ */
+
+static void
+FreeParsedVarName(
+    Tcl_Obj *objPtr)
+{
+    register Tcl_Obj *arrayPtr = objPtr->internalRep.twoPtrValue.ptr1;
+    register char *elem = objPtr->internalRep.twoPtrValue.ptr2;
+
+    if (arrayPtr != NULL) {
+	TclDecrRefCount(arrayPtr);
+	ckfree(elem);
+    }
+    objPtr->typePtr = NULL;
+}
+
+static void
+DupParsedVarName(
+    Tcl_Obj *srcPtr,
+    Tcl_Obj *dupPtr)
+{
+    register Tcl_Obj *arrayPtr = srcPtr->internalRep.twoPtrValue.ptr1;
+    register char *elem = srcPtr->internalRep.twoPtrValue.ptr2;
+    char *elemCopy;
+    unsigned elemLen;
+
+    if (arrayPtr != NULL) {
+	Tcl_IncrRefCount(arrayPtr);
+	elemLen = strlen(elem);
+	elemCopy = ckalloc(elemLen + 1);
+	memcpy(elemCopy, elem, elemLen);
+	*(elemCopy + elemLen) = '\0';
+	elem = elemCopy;
+    }
+
+    dupPtr->internalRep.twoPtrValue.ptr1 = arrayPtr;
+    dupPtr->internalRep.twoPtrValue.ptr2 = elem;
+    dupPtr->typePtr = &tclParsedVarNameType;
+}
+
+static void
+UpdateParsedVarName(
+    Tcl_Obj *objPtr)
+{
+    Tcl_Obj *arrayPtr = objPtr->internalRep.twoPtrValue.ptr1;
+    char *part2 = objPtr->internalRep.twoPtrValue.ptr2;
+    const char *part1;
+    char *p;
+    int len1, len2, totalLen;
+
+    if (arrayPtr == NULL) {
+	/*
+	 * This is a parsed scalar name: what is it doing here?
+	 */
+
+	Tcl_Panic("scalar parsedVarName without a string rep");
+    }
+
+    part1 = TclGetStringFromObj(arrayPtr, &len1);
+    len2 = strlen(part2);
+
+    totalLen = len1 + len2 + 2;
+    p = ckalloc(totalLen + 1);
+    objPtr->bytes = p;
+    objPtr->length = totalLen;
+
+    memcpy(p, part1, (unsigned) len1);
+    p += len1;
+    *p++ = '(';
+    memcpy(p, part2, (unsigned) len2);
+    p += len2;
+    *p++ = ')';
+    *p = '\0';
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_FindNamespaceVar -- MOVED OVER from tclNamesp.c
+ *
+ *	Searches for a namespace variable, a variable not local to a
+ *	procedure. The variable can be either a scalar or an array, but may
+ *	not be an element of an array.
+ *
+ * Results:
+ *	Returns a token for the variable if it is found. Otherwise, if it
+ *	can't be found or there is an error, returns NULL and leaves an error
+ *	message in the interpreter's result object if "flags" contains
+ *	TCL_LEAVE_ERR_MSG.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_Var
+Tcl_FindNamespaceVar(
+    Tcl_Interp *interp,		/* The interpreter in which to find the
+				 * variable. */
+    const char *name,		/* Variable's name. If it starts with "::",
+				 * will be looked up in global namespace.
+				 * Else, looked up first in contextNsPtr
+				 * (current namespace if contextNsPtr is
+				 * NULL), then in global namespace. */
+    Tcl_Namespace *contextNsPtr,/* Ignored if TCL_GLOBAL_ONLY flag set.
+				 * Otherwise, points to namespace in which to
+				 * resolve name. If NULL, look up name in the
+				 * current namespace. */
+    int flags)			/* An OR'd combination of:
+				 * TCL_AVOID_RESOLVERS, TCL_GLOBAL_ONLY (look
+				 * up name only in global namespace),
+				 * TCL_NAMESPACE_ONLY (look up only in
+				 * contextNsPtr, or the current namespace if
+				 * contextNsPtr is NULL), and
+				 * TCL_LEAVE_ERR_MSG. If both TCL_GLOBAL_ONLY
+				 * and TCL_NAMESPACE_ONLY are given,
+				 * TCL_GLOBAL_ONLY is ignored. */
+{
+    Tcl_Obj *namePtr = Tcl_NewStringObj(name, -1);
+    Tcl_Var var;
+
+    var = ObjFindNamespaceVar(interp, namePtr, contextNsPtr, flags);
+    Tcl_DecrRefCount(namePtr);
+    return var;
+}
+
+static Tcl_Var
+ObjFindNamespaceVar(
+    Tcl_Interp *interp,		/* The interpreter in which to find the
+				 * variable. */
+    Tcl_Obj *namePtr,		/* Variable's name. If it starts with "::",
+				 * will be looked up in global namespace.
+				 * Else, looked up first in contextNsPtr
+				 * (current namespace if contextNsPtr is
+				 * NULL), then in global namespace. */
+    Tcl_Namespace *contextNsPtr,/* Ignored if TCL_GLOBAL_ONLY flag set.
+				 * Otherwise, points to namespace in which to
+				 * resolve name. If NULL, look up name in the
+				 * current namespace. */
+    int flags)			/* An OR'd combination of:
+				 * TCL_AVOID_RESOLVERS, TCL_GLOBAL_ONLY (look
+				 * up name only in global namespace),
+				 * TCL_NAMESPACE_ONLY (look up only in
+				 * contextNsPtr, or the current namespace if
+				 * contextNsPtr is NULL), and
+				 * TCL_LEAVE_ERR_MSG. If both TCL_GLOBAL_ONLY
+				 * and TCL_NAMESPACE_ONLY are given,
+				 * TCL_GLOBAL_ONLY is ignored. */
+{
+    Interp *iPtr = (Interp *) interp;
+    ResolverScheme *resPtr;
+    Namespace *nsPtr[2], *cxtNsPtr;
+    const char *simpleName;
+    Var *varPtr;
+    register int search;
+    int result;
+    Tcl_Var var;
+    Tcl_Obj *simpleNamePtr;
+    const char *name = TclGetString(namePtr);
+
+    /*
+     * If this namespace has a variable resolver, then give it first crack at
+     * the variable resolution. It may return a Tcl_Var value, it may signal
+     * to continue onward, or it may signal an error.
+     */
+
+    if ((flags & TCL_GLOBAL_ONLY) != 0) {
+	cxtNsPtr = (Namespace *) TclGetGlobalNamespace(interp);
+    } else if (contextNsPtr != NULL) {
+	cxtNsPtr = (Namespace *) contextNsPtr;
+    } else {
+	cxtNsPtr = (Namespace *) TclGetCurrentNamespace(interp);
+    }
+
+    if (!(flags & TCL_AVOID_RESOLVERS) &&
+	    (cxtNsPtr->varResProc != NULL || iPtr->resolverPtr != NULL)) {
+	resPtr = iPtr->resolverPtr;
+
+	if (cxtNsPtr->varResProc) {
+	    result = cxtNsPtr->varResProc(interp, name,
+		    (Tcl_Namespace *) cxtNsPtr, flags, &var);
+	} else {
+	    result = TCL_CONTINUE;
+	}
+
+	while (result == TCL_CONTINUE && resPtr) {
+	    if (resPtr->varResProc) {
+		result = resPtr->varResProc(interp, name,
+			(Tcl_Namespace *) cxtNsPtr, flags, &var);
+	    }
+	    resPtr = resPtr->nextPtr;
+	}
+
+	if (result == TCL_OK) {
+	    return var;
+	} else if (result != TCL_CONTINUE) {
+	    return NULL;
+	}
+    }
+
+    /*
+     * Find the namespace(s) that contain the variable.
+     */
+
+    TclGetNamespaceForQualName(interp, name, (Namespace *) contextNsPtr,
+	    flags, &nsPtr[0], &nsPtr[1], &cxtNsPtr, &simpleName);
+
+    /*
+     * Look for the variable in the variable table of its namespace. Be sure
+     * to check both possible search paths: from the specified namespace
+     * context and from the global namespace.
+     */
+
+    varPtr = NULL;
+    if (simpleName != name) {
+	simpleNamePtr = Tcl_NewStringObj(simpleName, -1);
+    } else {
+	simpleNamePtr = namePtr;
+    }
+
+    for (search = 0;  (search < 2) && (varPtr == NULL);  search++) {
+	if ((nsPtr[search] != NULL) && (simpleName != NULL)) {
+	    varPtr = VarHashFindVar(&nsPtr[search]->varTable, simpleNamePtr);
+	}
+    }
+    if (simpleName != name) {
+	Tcl_DecrRefCount(simpleNamePtr);
+    }
+    if ((varPtr == NULL) && (flags & TCL_LEAVE_ERR_MSG)) {
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		"unknown variable \"%s\"", name));
+	Tcl_SetErrorCode(interp, "TCL", "LOOKUP", "VARIABLE", name, NULL);
+    }
+    return (Tcl_Var) varPtr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * InfoVarsCmd -- (moved over from tclCmdIL.c)
+ *
+ *	Called to implement the "info vars" command that returns the list of
+ *	variables in the interpreter that match an optional pattern. The
+ *	pattern, if any, consists of an optional sequence of namespace names
+ *	separated by "::" qualifiers, which is followed by a glob-style
+ *	pattern that restricts which variables are returned. Handles the
+ *	following syntax:
+ *
+ *	    info vars ?pattern?
+ *
+ * Results:
+ *	Returns TCL_OK if successful and TCL_ERROR if there is an error.
+ *
+ * Side effects:
+ *	Returns a result in the interpreter's result object. If there is an
+ *	error, the result is an error message.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclInfoVarsCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    Interp *iPtr = (Interp *) interp;
+    const char *varName, *pattern, *simplePattern;
+    Tcl_HashSearch search;
+    Var *varPtr;
+    Namespace *nsPtr;
+    Namespace *globalNsPtr = (Namespace *) Tcl_GetGlobalNamespace(interp);
+    Namespace *currNsPtr = (Namespace *) Tcl_GetCurrentNamespace(interp);
+    Tcl_Obj *listPtr, *elemObjPtr, *varNamePtr;
+    int specificNsInPattern = 0;/* Init. to avoid compiler warning. */
+    Tcl_Obj *simplePatternPtr = NULL;
+
+    /*
+     * Get the pattern and find the "effective namespace" in which to list
+     * variables. We only use this effective namespace if there's no active
+     * Tcl procedure frame.
+     */
+
+    if (objc == 1) {
+	simplePattern = NULL;
+	nsPtr = currNsPtr;
+	specificNsInPattern = 0;
+    } else if (objc == 2) {
+	/*
+	 * From the pattern, get the effective namespace and the simple
+	 * pattern (no namespace qualifiers or ::'s) at the end. If an error
+	 * was found while parsing the pattern, return it. Otherwise, if the
+	 * namespace wasn't found, just leave nsPtr NULL: we will return an
+	 * empty list since no variables there can be found.
+	 */
+
+	Namespace *dummy1NsPtr, *dummy2NsPtr;
+
+	pattern = TclGetString(objv[1]);
+	TclGetNamespaceForQualName(interp, pattern, NULL, /*flags*/ 0,
+		&nsPtr, &dummy1NsPtr, &dummy2NsPtr, &simplePattern);
+
+	if (nsPtr != NULL) {	/* We successfully found the pattern's ns. */
+	    specificNsInPattern = (strcmp(simplePattern, pattern) != 0);
+	    if (simplePattern == pattern) {
+		simplePatternPtr = objv[1];
+	    } else {
+		simplePatternPtr = Tcl_NewStringObj(simplePattern, -1);
+	    }
+	    Tcl_IncrRefCount(simplePatternPtr);
+	}
+    } else {
+	Tcl_WrongNumArgs(interp, 1, objv, "?pattern?");
+	return TCL_ERROR;
+    }
+
+    /*
+     * If the namespace specified in the pattern wasn't found, just return.
+     */
+
+    if (nsPtr == NULL) {
+	return TCL_OK;
+    }
+
+    listPtr = Tcl_NewListObj(0, NULL);
+
+    if (!HasLocalVars(iPtr->varFramePtr) || specificNsInPattern) {
+	/*
+	 * There is no frame pointer, the frame pointer was pushed only to
+	 * activate a namespace, or we are in a procedure call frame but a
+	 * specific namespace was specified. Create a list containing only the
+	 * variables in the effective namespace's variable table.
+	 */
+
+	if (simplePattern && TclMatchIsTrivial(simplePattern)) {
+	    /*
+	     * If we can just do hash lookups, that simplifies things a lot.
+	     */
+
+	    varPtr = VarHashFindVar(&nsPtr->varTable, simplePatternPtr);
+	    if (varPtr) {
+		if (!TclIsVarUndefined(varPtr)
+			|| TclIsVarNamespaceVar(varPtr)) {
+		    if (specificNsInPattern) {
+			elemObjPtr = Tcl_NewObj();
+			Tcl_GetVariableFullName(interp, (Tcl_Var) varPtr,
+				elemObjPtr);
+		    } else {
+			elemObjPtr = VarHashGetKey(varPtr);
+		    }
+		    Tcl_ListObjAppendElement(interp, listPtr, elemObjPtr);
+		}
+	    } else if ((nsPtr != globalNsPtr) && !specificNsInPattern) {
+		varPtr = VarHashFindVar(&globalNsPtr->varTable,
+			simplePatternPtr);
+		if (varPtr) {
+		    if (!TclIsVarUndefined(varPtr)
+			    || TclIsVarNamespaceVar(varPtr)) {
+			Tcl_ListObjAppendElement(interp, listPtr,
+				VarHashGetKey(varPtr));
+		    }
+		}
+	    }
+	} else {
+	    /*
+	     * Have to scan the tables of variables.
+	     */
+
+	    varPtr = VarHashFirstVar(&nsPtr->varTable, &search);
+	    while (varPtr) {
+		if (!TclIsVarUndefined(varPtr)
+			|| TclIsVarNamespaceVar(varPtr)) {
+		    varNamePtr = VarHashGetKey(varPtr);
+		    varName = TclGetString(varNamePtr);
+		    if ((simplePattern == NULL)
+			    || Tcl_StringMatch(varName, simplePattern)) {
+			if (specificNsInPattern) {
+			    elemObjPtr = Tcl_NewObj();
+			    Tcl_GetVariableFullName(interp, (Tcl_Var) varPtr,
+				    elemObjPtr);
+			} else {
+			    elemObjPtr = varNamePtr;
+			}
+			Tcl_ListObjAppendElement(interp, listPtr, elemObjPtr);
+		    }
+		}
+		varPtr = VarHashNextVar(&search);
+	    }
+
+	    /*
+	     * If the effective namespace isn't the global :: namespace, and a
+	     * specific namespace wasn't requested in the pattern (i.e., the
+	     * pattern only specifies variable names), then add in all global
+	     * :: variables that match the simple pattern. Of course, add in
+	     * only those variables that aren't hidden by a variable in the
+	     * effective namespace.
+	     */
+
+	    if ((nsPtr != globalNsPtr) && !specificNsInPattern) {
+		varPtr = VarHashFirstVar(&globalNsPtr->varTable,&search);
+		while (varPtr) {
+		    if (!TclIsVarUndefined(varPtr)
+			    || TclIsVarNamespaceVar(varPtr)) {
+			varNamePtr = VarHashGetKey(varPtr);
+			varName = TclGetString(varNamePtr);
+			if ((simplePattern == NULL)
+				|| Tcl_StringMatch(varName, simplePattern)) {
+			    if (VarHashFindVar(&nsPtr->varTable,
+				    varNamePtr) == NULL) {
+				Tcl_ListObjAppendElement(interp, listPtr,
+					varNamePtr);
+			    }
+			}
+		    }
+		    varPtr = VarHashNextVar(&search);
+		}
+	    }
+	}
+    } else if (iPtr->varFramePtr->procPtr != NULL) {
+	AppendLocals(interp, listPtr, simplePatternPtr, 1);
+    }
+
+    if (simplePatternPtr) {
+	Tcl_DecrRefCount(simplePatternPtr);
+    }
+    Tcl_SetObjResult(interp, listPtr);
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * InfoGlobalsCmd -- (moved over from tclCmdIL.c)
+ *
+ *	Called to implement the "info globals" command that returns the list
+ *	of global variables matching an optional pattern. Handles the
+ *	following syntax:
+ *
+ *	    info globals ?pattern?
+ *
+ * Results:
+ *	Returns TCL_OK if successful and TCL_ERROR if there is an error.
+ *
+ * Side effects:
+ *	Returns a result in the interpreter's result object. If there is an
+ *	error, the result is an error message.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclInfoGlobalsCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    const char *varName, *pattern;
+    Namespace *globalNsPtr = (Namespace *) Tcl_GetGlobalNamespace(interp);
+    Tcl_HashSearch search;
+    Var *varPtr;
+    Tcl_Obj *listPtr, *varNamePtr, *patternPtr;
+
+    if (objc == 1) {
+	pattern = NULL;
+    } else if (objc == 2) {
+	pattern = TclGetString(objv[1]);
+
+	/*
+	 * Strip leading global-namespace qualifiers. [Bug 1057461]
+	 */
+
+	if (pattern[0] == ':' && pattern[1] == ':') {
+	    while (*pattern == ':') {
+		pattern++;
+	    }
+	}
+    } else {
+	Tcl_WrongNumArgs(interp, 1, objv, "?pattern?");
+	return TCL_ERROR;
+    }
+
+    /*
+     * Scan through the global :: namespace's variable table and create a list
+     * of all global variables that match the pattern.
+     */
+
+    listPtr = Tcl_NewListObj(0, NULL);
+    if (pattern != NULL && TclMatchIsTrivial(pattern)) {
+	if (pattern == TclGetString(objv[1])) {
+	    patternPtr = objv[1];
+	} else {
+	    patternPtr = Tcl_NewStringObj(pattern, -1);
+	}
+	Tcl_IncrRefCount(patternPtr);
+
+	varPtr = VarHashFindVar(&globalNsPtr->varTable, patternPtr);
+	if (varPtr) {
+	    if (!TclIsVarUndefined(varPtr)) {
+		Tcl_ListObjAppendElement(interp, listPtr,
+			VarHashGetKey(varPtr));
+	    }
+	}
+	Tcl_DecrRefCount(patternPtr);
+    } else {
+	for (varPtr = VarHashFirstVar(&globalNsPtr->varTable, &search);
+		varPtr != NULL;
+		varPtr = VarHashNextVar(&search)) {
+	    if (TclIsVarUndefined(varPtr)) {
+		continue;
+	    }
+	    varNamePtr = VarHashGetKey(varPtr);
+	    varName = TclGetString(varNamePtr);
+	    if ((pattern == NULL) || Tcl_StringMatch(varName, pattern)) {
+		Tcl_ListObjAppendElement(interp, listPtr, varNamePtr);
+	    }
+	}
+    }
+    Tcl_SetObjResult(interp, listPtr);
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclInfoLocalsCmd -- (moved over from tclCmdIl.c)
+ *
+ *	Called to implement the "info locals" command to return a list of
+ *	local variables that match an optional pattern. Handles the following
+ *	syntax:
+ *
+ *	    info locals ?pattern?
+ *
+ * Results:
+ *	Returns TCL_OK if successful and TCL_ERROR if there is an error.
+ *
+ * Side effects:
+ *	Returns a result in the interpreter's result object. If there is an
+ *	error, the result is an error message.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclInfoLocalsCmd(
+    ClientData dummy,		/* Not used. */
+    Tcl_Interp *interp,		/* Current interpreter. */
+    int objc,			/* Number of arguments. */
+    Tcl_Obj *const objv[])	/* Argument objects. */
+{
+    Interp *iPtr = (Interp *) interp;
+    Tcl_Obj *patternPtr, *listPtr;
+
+    if (objc == 1) {
+	patternPtr = NULL;
+    } else if (objc == 2) {
+	patternPtr = objv[1];
+    } else {
+	Tcl_WrongNumArgs(interp, 1, objv, "?pattern?");
+	return TCL_ERROR;
+    }
+
+    if (!HasLocalVars(iPtr->varFramePtr)) {
+	return TCL_OK;
+    }
+
+    /*
+     * Return a list containing names of first the compiled locals (i.e. the
+     * ones stored in the call frame), then the variables in the local hash
+     * table (if one exists).
+     */
+
+    listPtr = Tcl_NewListObj(0, NULL);
+    AppendLocals(interp, listPtr, patternPtr, 0);
+    Tcl_SetObjResult(interp, listPtr);
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * AppendLocals --
+ *
+ *	Append the local variables for the current frame to the specified list
+ *	object.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+AppendLocals(
+    Tcl_Interp *interp,		/* Current interpreter. */
+    Tcl_Obj *listPtr,		/* List object to append names to. */
+    Tcl_Obj *patternPtr,	/* Pattern to match against. */
+    int includeLinks)		/* 1 if upvars should be included, else 0. */
+{
+    Interp *iPtr = (Interp *) interp;
+    Var *varPtr;
+    int i, localVarCt, added;
+    Tcl_Obj **varNamePtr, *objNamePtr;
+    const char *varName;
+    TclVarHashTable *localVarTablePtr;
+    Tcl_HashSearch search;
+    Tcl_HashTable addedTable;
+    const char *pattern = patternPtr? TclGetString(patternPtr) : NULL;
+
+    localVarCt = iPtr->varFramePtr->numCompiledLocals;
+    varPtr = iPtr->varFramePtr->compiledLocals;
+    localVarTablePtr = iPtr->varFramePtr->varTablePtr;
+    varNamePtr = &iPtr->varFramePtr->localCachePtr->varName0;
+    if (includeLinks) {
+	Tcl_InitObjHashTable(&addedTable);
+    }
+
+    for (i = 0; i < localVarCt; i++, varNamePtr++) {
+	/*
+	 * Skip nameless (temporary) variables and undefined variables.
+	 */
+
+	if (*varNamePtr && !TclIsVarUndefined(varPtr)
+		&& (includeLinks || !TclIsVarLink(varPtr))) {
+	    varName = TclGetString(*varNamePtr);
+	    if ((pattern == NULL) || Tcl_StringMatch(varName, pattern)) {
+		Tcl_ListObjAppendElement(interp, listPtr, *varNamePtr);
+		if (includeLinks) {
+		    Tcl_CreateHashEntry(&addedTable, *varNamePtr, &added);
+		}
+	    }
+	}
+	varPtr++;
+    }
+
+    /*
+     * Do nothing if no local variables.
+     */
+
+    if (localVarTablePtr == NULL) {
+	goto objectVars;
+    }
+
+    /*
+     * Check for the simple and fast case.
+     */
+
+    if ((pattern != NULL) && TclMatchIsTrivial(pattern)) {
+	varPtr = VarHashFindVar(localVarTablePtr, patternPtr);
+	if (varPtr != NULL) {
+	    if (!TclIsVarUndefined(varPtr)
+		    && (includeLinks || !TclIsVarLink(varPtr))) {
+		Tcl_ListObjAppendElement(interp, listPtr,
+			VarHashGetKey(varPtr));
+		if (includeLinks) {
+		    Tcl_CreateHashEntry(&addedTable, VarHashGetKey(varPtr),
+			    &added);
+		}
+	    }
+	}
+	goto objectVars;
+    }
+
+    /*
+     * Scan over and process all local variables.
+     */
+
+    for (varPtr = VarHashFirstVar(localVarTablePtr, &search);
+	    varPtr != NULL;
+	    varPtr = VarHashNextVar(&search)) {
+	if (!TclIsVarUndefined(varPtr)
+		&& (includeLinks || !TclIsVarLink(varPtr))) {
+	    objNamePtr = VarHashGetKey(varPtr);
+	    varName = TclGetString(objNamePtr);
+	    if ((pattern == NULL) || Tcl_StringMatch(varName, pattern)) {
+		Tcl_ListObjAppendElement(interp, listPtr, objNamePtr);
+		if (includeLinks) {
+		    Tcl_CreateHashEntry(&addedTable, objNamePtr, &added);
+		}
+	    }
+	}
+    }
+
+  objectVars:
+    if (!includeLinks) {
+	return;
+    }
+
+    if (iPtr->varFramePtr->isProcCallFrame & FRAME_IS_METHOD) {
+	CallContext *contextPtr = iPtr->varFramePtr->clientData;
+	Method *mPtr = contextPtr->callPtr->chain[contextPtr->index].mPtr;
+
+	if (mPtr->declaringObjectPtr) {
+	    FOREACH(objNamePtr, mPtr->declaringObjectPtr->variables) {
+		Tcl_CreateHashEntry(&addedTable, objNamePtr, &added);
+		if (added && (!pattern ||
+			Tcl_StringMatch(TclGetString(objNamePtr), pattern))) {
+		    Tcl_ListObjAppendElement(interp, listPtr, objNamePtr);
+		}
+	    }
+	} else {
+	    FOREACH(objNamePtr, mPtr->declaringClassPtr->variables) {
+		Tcl_CreateHashEntry(&addedTable, objNamePtr, &added);
+		if (added && (!pattern ||
+			Tcl_StringMatch(TclGetString(objNamePtr), pattern))) {
+		    Tcl_ListObjAppendElement(interp, listPtr, objNamePtr);
+		}
+	    }
+	}
+    }
+    Tcl_DeleteHashTable(&addedTable);
+}
+
+/*
+ * Hash table implementation - first, just copy and adapt the obj key stuff
+ */
+
+void
+TclInitVarHashTable(
+    TclVarHashTable *tablePtr,
+    Namespace *nsPtr)
+{
+    Tcl_InitCustomHashTable(&tablePtr->table,
+	    TCL_CUSTOM_TYPE_KEYS, &tclVarHashKeyType);
+    tablePtr->nsPtr = nsPtr;
+}
+
+static Tcl_HashEntry *
+AllocVarEntry(
+    Tcl_HashTable *tablePtr,	/* Hash table. */
+    void *keyPtr)		/* Key to store in the hash table entry. */
+{
+    Tcl_Obj *objPtr = keyPtr;
+    Tcl_HashEntry *hPtr;
+    Var *varPtr;
+
+    varPtr = ckalloc(sizeof(VarInHash));
+    varPtr->flags = VAR_IN_HASHTABLE;
+    varPtr->value.objPtr = NULL;
+    VarHashRefCount(varPtr) = 1;
+
+    hPtr = &(((VarInHash *) varPtr)->entry);
+    Tcl_SetHashValue(hPtr, varPtr);
+    hPtr->key.objPtr = objPtr;
+    Tcl_IncrRefCount(objPtr);
+
+    return hPtr;
+}
+
+static void
+FreeVarEntry(
+    Tcl_HashEntry *hPtr)
+{
+    Var *varPtr = VarHashGetValue(hPtr);
+    Tcl_Obj *objPtr = hPtr->key.objPtr;
+
+    if (TclIsVarUndefined(varPtr) && !TclIsVarTraced(varPtr)
+	    && (VarHashRefCount(varPtr) == 1)) {
+	ckfree(varPtr);
+    } else {
+	VarHashInvalidateEntry(varPtr);
+	TclSetVarUndefined(varPtr);
+	VarHashRefCount(varPtr)--;
+    }
+    Tcl_DecrRefCount(objPtr);
+}
+
+static int
+CompareVarKeys(
+    void *keyPtr,		/* New key to compare. */
+    Tcl_HashEntry *hPtr)	/* Existing key to compare. */
+{
+    Tcl_Obj *objPtr1 = keyPtr;
+    Tcl_Obj *objPtr2 = hPtr->key.objPtr;
+    register const char *p1, *p2;
+    register int l1, l2;
+
+    /*
+     * If the object pointers are the same then they match.
+     * OPT: this comparison was moved to the caller
+
+       if (objPtr1 == objPtr2) return 1;
+    */
+
+    /*
+     * Don't use Tcl_GetStringFromObj as it would prevent l1 and l2 being in a
+     * register.
+     */
+
+    p1 = TclGetString(objPtr1);
+    l1 = objPtr1->length;
+    p2 = TclGetString(objPtr2);
+    l2 = objPtr2->length;
+
+    /*
+     * Only compare string representations of the same length.
+     */
+
+    return ((l1 == l2) && !memcmp(p1, p2, l1));
+}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tclZlib.c b/generic/tclZlib.c
new file mode 100644
index 0000000..dac47cf
--- /dev/null
+++ b/generic/tclZlib.c
@@ -0,0 +1,4017 @@
+/*
+ * tclZlib.c --
+ *
+ *	This file provides the interface to the Zlib library.
+ *
+ * Copyright (C) 2004-2005 Pascal Scheffers <pascal@scheffers.net>
+ * Copyright (C) 2005 Unitas Software B.V.
+ * Copyright (c) 2008-2012 Donal K. Fellows
+ *
+ * Parts written by Jean-Claude Wippler, as part of Tclkit, placed in the
+ * public domain March 2003.
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#include "tclInt.h"
+#ifdef HAVE_ZLIB
+#include <zlib.h>
+#include "tclIO.h"
+
+/*
+ * The version of the zlib "package" that this implements. Note that this
+ * thoroughly supersedes the versions included with tclkit, which are "1.1",
+ * so this is at least "2.0" (there's no general *commitment* to have the same
+ * interface, even if that is mostly true).
+ */
+
+#define TCL_ZLIB_VERSION	"2.0.1"
+
+/*
+ * Magic flags used with wbits fields to indicate that we're handling the gzip
+ * format or automatic detection of format. Putting it here is slightly less
+ * gross!
+ */
+
+#define WBITS_RAW		(-MAX_WBITS)
+#define WBITS_ZLIB		(MAX_WBITS)
+#define WBITS_GZIP		(MAX_WBITS | 16)
+#define WBITS_AUTODETECT	(MAX_WBITS | 32)
+
+/*
+ * Structure used for handling gzip headers that are generated from a
+ * dictionary. It comprises the header structure itself plus some working
+ * space that it is very convenient to have attached.
+ */
+
+#define MAX_COMMENT_LEN		256
+
+typedef struct {
+    gz_header header;
+    char nativeFilenameBuf[MAXPATHLEN];
+    char nativeCommentBuf[MAX_COMMENT_LEN];
+} GzipHeader;
+
+/*
+ * Structure used for the Tcl_ZlibStream* commands and [zlib stream ...]
+ */
+
+typedef struct {
+    Tcl_Interp *interp;
+    z_stream stream;		/* The interface to the zlib library. */
+    int streamEnd;		/* If we've got to end-of-stream. */
+    Tcl_Obj *inData, *outData;	/* Input / output buffers (lists) */
+    Tcl_Obj *currentInput;	/* Pointer to what is currently being
+				 * inflated. */
+    int outPos;
+    int mode;			/* Either TCL_ZLIB_STREAM_DEFLATE or
+				 * TCL_ZLIB_STREAM_INFLATE. */
+    int format;			/* Flags from the TCL_ZLIB_FORMAT_* */
+    int level;			/* Default 5, 0-9 */
+    int flush;			/* Stores the flush param for deferred the
+				 * decompression. */
+    int wbits;			/* The encoded compression mode, so we can
+				 * restart the stream if necessary. */
+    Tcl_Command cmd;		/* Token for the associated Tcl command. */
+    Tcl_Obj *compDictObj;	/* Byte-array object containing compression
+				 * dictionary (not dictObj!) to use if
+				 * necessary. */
+    int flags;			/* Miscellaneous flag bits. */
+    GzipHeader *gzHeaderPtr;	/* If we've allocated a gzip header
+				 * structure. */
+} ZlibStreamHandle;
+
+#define DICT_TO_SET	0x1	/* If we need to set a compression dictionary
+				 * in the low-level engine at the next
+				 * opportunity. */
+
+/*
+ * Macros to make it clearer in some of the twiddlier accesses what is
+ * happening.
+ */
+
+#define IsRawStream(zshPtr)	((zshPtr)->format == TCL_ZLIB_FORMAT_RAW)
+#define HaveDictToSet(zshPtr)	((zshPtr)->flags & DICT_TO_SET)
+#define DictWasSet(zshPtr)	((zshPtr)->flags |= ~DICT_TO_SET)
+
+/*
+ * Structure used for stacked channel compression and decompression.
+ */
+
+typedef struct {
+    Tcl_Channel chan;		/* Reference to the channel itself. */
+    Tcl_Channel parent;		/* The underlying source and sink of bytes. */
+    int flags;			/* General flag bits, see below... */
+    int mode;			/* Either the value TCL_ZLIB_STREAM_DEFLATE
+				 * for compression on output, or
+				 * TCL_ZLIB_STREAM_INFLATE for decompression
+				 * on input. */
+    int format;			/* What format of data is going on the wire.
+				 * Needed so that the correct [fconfigure]
+				 * options can be enabled. */
+    int readAheadLimit;		/* The maximum number of bytes to read from
+				 * the underlying stream in one go. */
+    z_stream inStream;		/* Structure used by zlib for decompression of
+				 * input. */
+    z_stream outStream;		/* Structure used by zlib for compression of
+				 * output. */
+    char *inBuffer, *outBuffer;	/* Working buffers. */
+    int inAllocated, outAllocated;
+				/* Sizes of working buffers. */
+    GzipHeader inHeader;	/* Header read from input stream, when
+				 * decompressing a gzip stream. */
+    GzipHeader outHeader;	/* Header to write to an output stream, when
+				 * compressing a gzip stream. */
+    Tcl_TimerToken timer;	/* Timer used for keeping events fresh. */
+    Tcl_DString decompressed;	/* Buffer for decompression results. */
+    Tcl_Obj *compDictObj;	/* Byte-array object containing compression
+				 * dictionary (not dictObj!) to use if
+				 * necessary. */
+} ZlibChannelData;
+
+/*
+ * Value bits for the flags field. Definitions are:
+ *	ASYNC -		Whether this is an asynchronous channel.
+ *	IN_HEADER -	Whether the inHeader field has been registered with
+ *			the input compressor.
+ *	OUT_HEADER -	Whether the outputHeader field has been registered
+ *			with the output decompressor.
+ */
+
+#define ASYNC			0x1
+#define IN_HEADER		0x2
+#define OUT_HEADER		0x4
+
+/*
+ * Size of buffers allocated by default, and the range it can be set to.  The
+ * same sorts of values apply to streams, except with different limits (they
+ * permit byte-level activity). Channels always use bytes unless told to use
+ * larger buffers.
+ */
+
+#define DEFAULT_BUFFER_SIZE	4096
+#define MIN_NONSTREAM_BUFFER_SIZE 16
+#define MAX_BUFFER_SIZE		65536
+
+/*
+ * Prototypes for private procedures defined later in this file:
+ */
+
+static Tcl_CmdDeleteProc	ZlibStreamCmdDelete;
+static Tcl_DriverBlockModeProc	ZlibTransformBlockMode;
+static Tcl_DriverCloseProc	ZlibTransformClose;
+static Tcl_DriverGetHandleProc	ZlibTransformGetHandle;
+static Tcl_DriverGetOptionProc	ZlibTransformGetOption;
+static Tcl_DriverHandlerProc	ZlibTransformEventHandler;
+static Tcl_DriverInputProc	ZlibTransformInput;
+static Tcl_DriverOutputProc	ZlibTransformOutput;
+static Tcl_DriverSetOptionProc	ZlibTransformSetOption;
+static Tcl_DriverWatchProc	ZlibTransformWatch;
+static Tcl_ObjCmdProc		ZlibCmd;
+static Tcl_ObjCmdProc		ZlibStreamCmd;
+static Tcl_ObjCmdProc		ZlibStreamAddCmd;
+static Tcl_ObjCmdProc		ZlibStreamHeaderCmd;
+static Tcl_ObjCmdProc		ZlibStreamPutCmd;
+
+static void		ConvertError(Tcl_Interp *interp, int code,
+			    uLong adler);
+static Tcl_Obj *	ConvertErrorToList(int code, uLong adler);
+static void		ExtractHeader(gz_header *headerPtr, Tcl_Obj *dictObj);
+static int		GenerateHeader(Tcl_Interp *interp, Tcl_Obj *dictObj,
+			    GzipHeader *headerPtr, int *extraSizePtr);
+static int		ZlibPushSubcmd(Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+static inline int	ResultCopy(ZlibChannelData *cd, char *buf,
+			    int toRead);
+static int		ResultGenerate(ZlibChannelData *cd, int n, int flush,
+			    int *errorCodePtr);
+static Tcl_Channel	ZlibStackChannelTransform(Tcl_Interp *interp,
+			    int mode, int format, int level, int limit,
+			    Tcl_Channel channel, Tcl_Obj *gzipHeaderDictPtr,
+			    Tcl_Obj *compDictObj);
+static void		ZlibStreamCleanup(ZlibStreamHandle *zshPtr);
+static int		ZlibStreamSubcmd(Tcl_Interp *interp, int objc,
+			    Tcl_Obj *const objv[]);
+static inline void	ZlibTransformEventTimerKill(ZlibChannelData *cd);
+static void		ZlibTransformTimerRun(ClientData clientData);
+
+/*
+ * Type of zlib-based compressing and decompressing channels.
+ */
+
+static const Tcl_ChannelType zlibChannelType = {
+    "zlib",
+    TCL_CHANNEL_VERSION_3,
+    ZlibTransformClose,
+    ZlibTransformInput,
+    ZlibTransformOutput,
+    NULL,			/* seekProc */
+    ZlibTransformSetOption,
+    ZlibTransformGetOption,
+    ZlibTransformWatch,
+    ZlibTransformGetHandle,
+    NULL,			/* close2Proc */
+    ZlibTransformBlockMode,
+    NULL,			/* flushProc */
+    ZlibTransformEventHandler,
+    NULL,			/* wideSeekProc */
+    NULL,
+    NULL
+};
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ConvertError --
+ *
+ *	Utility function for converting a zlib error into a Tcl error.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Updates the interpreter result and errorcode.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+ConvertError(
+    Tcl_Interp *interp,		/* Interpreter to store the error in. May be
+				 * NULL, in which case nothing happens. */
+    int code,			/* The zlib error code. */
+    uLong adler)		/* The checksum expected (for Z_NEED_DICT) */
+{
+    const char *codeStr, *codeStr2 = NULL;
+    char codeStrBuf[TCL_INTEGER_SPACE];
+
+    if (interp == NULL) {
+	return;
+    }
+
+    switch (code) {
+	/*
+	 * Firstly, the case that is *different* because it's really coming
+	 * from the OS and is just being reported via zlib. It should be
+	 * really uncommon because Tcl handles all I/O rather than delegating
+	 * it to zlib, but proving it can't happen is hard.
+	 */
+
+    case Z_ERRNO:
+	Tcl_SetObjResult(interp, Tcl_NewStringObj(Tcl_PosixError(interp),-1));
+	return;
+
+	/*
+	 * Normal errors/conditions, some of which have additional detail and
+	 * some which don't. (This is not defined by array lookup because zlib
+	 * error codes are sometimes negative.)
+	 */
+
+    case Z_STREAM_ERROR:
+	codeStr = "STREAM";
+	break;
+    case Z_DATA_ERROR:
+	codeStr = "DATA";
+	break;
+    case Z_MEM_ERROR:
+	codeStr = "MEM";
+	break;
+    case Z_BUF_ERROR:
+	codeStr = "BUF";
+	break;
+    case Z_VERSION_ERROR:
+	codeStr = "VERSION";
+	break;
+    case Z_NEED_DICT:
+	codeStr = "NEED_DICT";
+	codeStr2 = codeStrBuf;
+	sprintf(codeStrBuf, "%lu", adler);
+	break;
+
+	/*
+	 * These should _not_ happen! This function is for dealing with error
+	 * cases, not non-errors!
+	 */
+
+    case Z_OK:
+	Tcl_Panic("unexpected zlib result in error handler: Z_OK");
+    case Z_STREAM_END:
+	Tcl_Panic("unexpected zlib result in error handler: Z_STREAM_END");
+
+	/*
+	 * Anything else is bad news; it's unexpected. Convert to generic
+	 * error.
+	 */
+
+    default:
+	codeStr = "UNKNOWN";
+	codeStr2 = codeStrBuf;
+	sprintf(codeStrBuf, "%d", code);
+	break;
+    }
+    Tcl_SetObjResult(interp, Tcl_NewStringObj(zError(code), -1));
+
+    /*
+     * Tricky point! We might pass NULL twice here (and will when the error
+     * type is known).
+     */
+
+    Tcl_SetErrorCode(interp, "TCL", "ZLIB", codeStr, codeStr2, NULL);
+}
+
+static Tcl_Obj *
+ConvertErrorToList(
+    int code,			/* The zlib error code. */
+    uLong adler)		/* The checksum expected (for Z_NEED_DICT) */
+{
+    Tcl_Obj *objv[4];
+
+    TclNewLiteralStringObj(objv[0], "TCL");
+    TclNewLiteralStringObj(objv[1], "ZLIB");
+    switch (code) {
+    case Z_STREAM_ERROR:
+	TclNewLiteralStringObj(objv[2], "STREAM");
+	return Tcl_NewListObj(3, objv);
+    case Z_DATA_ERROR:
+	TclNewLiteralStringObj(objv[2], "DATA");
+	return Tcl_NewListObj(3, objv);
+    case Z_MEM_ERROR:
+	TclNewLiteralStringObj(objv[2], "MEM");
+	return Tcl_NewListObj(3, objv);
+    case Z_BUF_ERROR:
+	TclNewLiteralStringObj(objv[2], "BUF");
+	return Tcl_NewListObj(3, objv);
+    case Z_VERSION_ERROR:
+	TclNewLiteralStringObj(objv[2], "VERSION");
+	return Tcl_NewListObj(3, objv);
+    case Z_ERRNO:
+	TclNewLiteralStringObj(objv[2], "POSIX");
+	objv[3] = Tcl_NewStringObj(Tcl_ErrnoId(), -1);
+	return Tcl_NewListObj(4, objv);
+    case Z_NEED_DICT:
+	TclNewLiteralStringObj(objv[2], "NEED_DICT");
+	objv[3] = Tcl_NewWideIntObj((Tcl_WideInt) adler);
+	return Tcl_NewListObj(4, objv);
+
+	/*
+	 * These should _not_ happen! This function is for dealing with error
+	 * cases, not non-errors!
+	 */
+
+    case Z_OK:
+	Tcl_Panic("unexpected zlib result in error handler: Z_OK");
+    case Z_STREAM_END:
+	Tcl_Panic("unexpected zlib result in error handler: Z_STREAM_END");
+
+	/*
+	 * Catch-all. Should be unreachable because all cases are already
+	 * listed above.
+	 */
+
+    default:
+	TclNewLiteralStringObj(objv[2], "UNKNOWN");
+	TclNewIntObj(objv[3], code);
+	return Tcl_NewListObj(4, objv);
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * GenerateHeader --
+ *
+ *	Function for creating a gzip header from the contents of a dictionary
+ *	(as described in the documentation). GetValue is a helper function.
+ *
+ * Results:
+ *	A Tcl result code.
+ *
+ * Side effects:
+ *	Updates the fields of the given gz_header structure. Adds amount of
+ *	extra space required for the header to the variable referenced by the
+ *	extraSizePtr argument.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static inline int
+GetValue(
+    Tcl_Interp *interp,
+    Tcl_Obj *dictObj,
+    const char *nameStr,
+    Tcl_Obj **valuePtrPtr)
+{
+    Tcl_Obj *name = Tcl_NewStringObj(nameStr, -1);
+    int result = Tcl_DictObjGet(interp, dictObj, name, valuePtrPtr);
+
+    TclDecrRefCount(name);
+    return result;
+}
+
+static int
+GenerateHeader(
+    Tcl_Interp *interp,		/* Where to put error messages. */
+    Tcl_Obj *dictObj,		/* The dictionary whose contents are to be
+				 * parsed. */
+    GzipHeader *headerPtr,	/* Where to store the parsed-out values. */
+    int *extraSizePtr)		/* Variable to add the length of header
+				 * strings (filename, comment) to. */
+{
+    Tcl_Obj *value;
+    int len, result = TCL_ERROR;
+    const char *valueStr;
+    Tcl_Encoding latin1enc;
+    static const char *const types[] = {
+	"binary", "text"
+    };
+
+    /*
+     * RFC 1952 says that header strings are in ISO 8859-1 (LATIN-1).
+     */
+
+    latin1enc = Tcl_GetEncoding(NULL, "iso8859-1");
+    if (latin1enc == NULL) {
+	Tcl_Panic("no latin-1 encoding");
+    }
+
+    if (GetValue(interp, dictObj, "comment", &value) != TCL_OK) {
+	goto error;
+    } else if (value != NULL) {
+	valueStr = Tcl_GetStringFromObj(value, &len);
+	Tcl_UtfToExternal(NULL, latin1enc, valueStr, len, 0, NULL,
+		headerPtr->nativeCommentBuf, MAX_COMMENT_LEN-1, NULL, &len,
+		NULL);
+	headerPtr->nativeCommentBuf[len] = '\0';
+	headerPtr->header.comment = (Bytef *) headerPtr->nativeCommentBuf;
+	if (extraSizePtr != NULL) {
+	    *extraSizePtr += len;
+	}
+    }
+
+    if (GetValue(interp, dictObj, "crc", &value) != TCL_OK) {
+	goto error;
+    } else if (value != NULL &&
+	    Tcl_GetBooleanFromObj(interp, value, &headerPtr->header.hcrc)) {
+	goto error;
+    }
+
+    if (GetValue(interp, dictObj, "filename", &value) != TCL_OK) {
+	goto error;
+    } else if (value != NULL) {
+	valueStr = Tcl_GetStringFromObj(value, &len);
+	Tcl_UtfToExternal(NULL, latin1enc, valueStr, len, 0, NULL,
+		headerPtr->nativeFilenameBuf, MAXPATHLEN-1, NULL, &len, NULL);
+	headerPtr->nativeFilenameBuf[len] = '\0';
+	headerPtr->header.name = (Bytef *) headerPtr->nativeFilenameBuf;
+	if (extraSizePtr != NULL) {
+	    *extraSizePtr += len;
+	}
+    }
+
+    if (GetValue(interp, dictObj, "os", &value) != TCL_OK) {
+	goto error;
+    } else if (value != NULL && Tcl_GetIntFromObj(interp, value,
+	    &headerPtr->header.os) != TCL_OK) {
+	goto error;
+    }
+
+    /*
+     * Ignore the 'size' field, since that is controlled by the size of the
+     * input data.
+     */
+
+    if (GetValue(interp, dictObj, "time", &value) != TCL_OK) {
+	goto error;
+    } else if (value != NULL && Tcl_GetLongFromObj(interp, value,
+	    (long *) &headerPtr->header.time) != TCL_OK) {
+	goto error;
+    }
+
+    if (GetValue(interp, dictObj, "type", &value) != TCL_OK) {
+	goto error;
+    } else if (value != NULL && Tcl_GetIndexFromObj(interp, value, types,
+	    "type", TCL_EXACT, &headerPtr->header.text) != TCL_OK) {
+	goto error;
+    }
+
+    result = TCL_OK;
+  error:
+    Tcl_FreeEncoding(latin1enc);
+    return result;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ExtractHeader --
+ *
+ *	Take the values out of a gzip header and store them in a dictionary.
+ *	SetValue is a helper macro.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Updates the dictionary, which must be writable (i.e. refCount < 2).
+ *
+ *----------------------------------------------------------------------
+ */
+
+#define SetValue(dictObj, key, value) \
+	Tcl_DictObjPut(NULL, (dictObj), Tcl_NewStringObj((key), -1), (value))
+
+static void
+ExtractHeader(
+    gz_header *headerPtr,	/* The gzip header to extract from. */
+    Tcl_Obj *dictObj)		/* The dictionary to store in. */
+{
+    Tcl_Encoding latin1enc = NULL;
+    Tcl_DString tmp;
+
+    if (headerPtr->comment != Z_NULL) {
+	if (latin1enc == NULL) {
+	    /*
+	     * RFC 1952 says that header strings are in ISO 8859-1 (LATIN-1).
+	     */
+
+	    latin1enc = Tcl_GetEncoding(NULL, "iso8859-1");
+	    if (latin1enc == NULL) {
+		Tcl_Panic("no latin-1 encoding");
+	    }
+	}
+
+	Tcl_ExternalToUtfDString(latin1enc, (char *) headerPtr->comment, -1,
+		&tmp);
+	SetValue(dictObj, "comment", TclDStringToObj(&tmp));
+    }
+    SetValue(dictObj, "crc", Tcl_NewBooleanObj(headerPtr->hcrc));
+    if (headerPtr->name != Z_NULL) {
+	if (latin1enc == NULL) {
+	    /*
+	     * RFC 1952 says that header strings are in ISO 8859-1 (LATIN-1).
+	     */
+
+	    latin1enc = Tcl_GetEncoding(NULL, "iso8859-1");
+	    if (latin1enc == NULL) {
+		Tcl_Panic("no latin-1 encoding");
+	    }
+	}
+
+	Tcl_ExternalToUtfDString(latin1enc, (char *) headerPtr->name, -1,
+		&tmp);
+	SetValue(dictObj, "filename", TclDStringToObj(&tmp));
+    }
+    if (headerPtr->os != 255) {
+	SetValue(dictObj, "os", Tcl_NewIntObj(headerPtr->os));
+    }
+    if (headerPtr->time != 0 /* magic - no time */) {
+	SetValue(dictObj, "time", Tcl_NewLongObj((long) headerPtr->time));
+    }
+    if (headerPtr->text != Z_UNKNOWN) {
+	SetValue(dictObj, "type",
+		Tcl_NewStringObj(headerPtr->text ? "text" : "binary", -1));
+    }
+
+    if (latin1enc != NULL) {
+	Tcl_FreeEncoding(latin1enc);
+    }
+}
+
+static int
+SetInflateDictionary(
+    z_streamp strm,
+    Tcl_Obj *compDictObj)
+{
+    if (compDictObj != NULL) {
+	int length;
+	unsigned char *bytes = Tcl_GetByteArrayFromObj(compDictObj, &length);
+
+	return inflateSetDictionary(strm, bytes, (unsigned) length);
+    }
+    return Z_OK;
+}
+
+static int
+SetDeflateDictionary(
+    z_streamp strm,
+    Tcl_Obj *compDictObj)
+{
+    if (compDictObj != NULL) {
+	int length;
+	unsigned char *bytes = Tcl_GetByteArrayFromObj(compDictObj, &length);
+
+	return deflateSetDictionary(strm, bytes, (unsigned) length);
+    }
+    return Z_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_ZlibStreamInit --
+ *
+ *	This command initializes a (de)compression context/handle for
+ *	(de)compressing data in chunks.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	The variable pointed to by zshandlePtr is initialised and memory
+ *	allocated for internal state. Additionally, if interp is not null, a
+ *	Tcl command is created and its name placed in the interp result obj.
+ *
+ * Note:
+ *	At least one of interp and zshandlePtr should be non-NULL or the
+ *	reference to the stream will be completely lost.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_ZlibStreamInit(
+    Tcl_Interp *interp,
+    int mode,			/* Either TCL_ZLIB_STREAM_INFLATE or
+				 * TCL_ZLIB_STREAM_DEFLATE. */
+    int format,			/* Flags from the TCL_ZLIB_FORMAT_* set. */
+    int level,			/* 0-9 or TCL_ZLIB_COMPRESS_DEFAULT. */
+    Tcl_Obj *dictObj,		/* Dictionary containing headers for gzip. */
+    Tcl_ZlibStream *zshandlePtr)
+{
+    int wbits = 0;
+    int e;
+    ZlibStreamHandle *zshPtr = NULL;
+    Tcl_DString cmdname;
+    GzipHeader *gzHeaderPtr = NULL;
+
+    switch (mode) {
+    case TCL_ZLIB_STREAM_DEFLATE:
+	/*
+	 * Compressed format is specified by the wbits parameter. See zlib.h
+	 * for details.
+	 */
+
+	switch (format) {
+	case TCL_ZLIB_FORMAT_RAW:
+	    wbits = WBITS_RAW;
+	    break;
+	case TCL_ZLIB_FORMAT_GZIP:
+	    wbits = WBITS_GZIP;
+	    if (dictObj) {
+		gzHeaderPtr = ckalloc(sizeof(GzipHeader));
+		memset(gzHeaderPtr, 0, sizeof(GzipHeader));
+		if (GenerateHeader(interp, dictObj, gzHeaderPtr,
+			NULL) != TCL_OK) {
+		    ckfree(gzHeaderPtr);
+		    return TCL_ERROR;
+		}
+	    }
+	    break;
+	case TCL_ZLIB_FORMAT_ZLIB:
+	    wbits = WBITS_ZLIB;
+	    break;
+	default:
+	    Tcl_Panic("incorrect zlib data format, must be "
+		    "TCL_ZLIB_FORMAT_ZLIB, TCL_ZLIB_FORMAT_GZIP or "
+		    "TCL_ZLIB_FORMAT_RAW");
+	}
+	if (level < -1 || level > 9) {
+	    Tcl_Panic("compression level should be between 0 (no compression)"
+		    " and 9 (best compression) or -1 for default compression "
+		    "level");
+	}
+	break;
+    case TCL_ZLIB_STREAM_INFLATE:
+	/*
+	 * wbits are the same as DEFLATE, but FORMAT_AUTO is valid too.
+	 */
+
+	switch (format) {
+	case TCL_ZLIB_FORMAT_RAW:
+	    wbits = WBITS_RAW;
+	    break;
+	case TCL_ZLIB_FORMAT_GZIP:
+	    wbits = WBITS_GZIP;
+	    gzHeaderPtr = ckalloc(sizeof(GzipHeader));
+	    memset(gzHeaderPtr, 0, sizeof(GzipHeader));
+	    gzHeaderPtr->header.name = (Bytef *)
+		    gzHeaderPtr->nativeFilenameBuf;
+	    gzHeaderPtr->header.name_max = MAXPATHLEN - 1;
+	    gzHeaderPtr->header.comment = (Bytef *)
+		    gzHeaderPtr->nativeCommentBuf;
+	    gzHeaderPtr->header.name_max = MAX_COMMENT_LEN - 1;
+	    break;
+	case TCL_ZLIB_FORMAT_ZLIB:
+	    wbits = WBITS_ZLIB;
+	    break;
+	case TCL_ZLIB_FORMAT_AUTO:
+	    wbits = WBITS_AUTODETECT;
+	    break;
+	default:
+	    Tcl_Panic("incorrect zlib data format, must be "
+		    "TCL_ZLIB_FORMAT_ZLIB, TCL_ZLIB_FORMAT_GZIP, "
+		    "TCL_ZLIB_FORMAT_RAW or TCL_ZLIB_FORMAT_AUTO");
+	}
+	break;
+    default:
+	Tcl_Panic("bad mode, must be TCL_ZLIB_STREAM_DEFLATE or"
+		" TCL_ZLIB_STREAM_INFLATE");
+    }
+
+    zshPtr = ckalloc(sizeof(ZlibStreamHandle));
+    zshPtr->interp = interp;
+    zshPtr->mode = mode;
+    zshPtr->format = format;
+    zshPtr->level = level;
+    zshPtr->wbits = wbits;
+    zshPtr->currentInput = NULL;
+    zshPtr->streamEnd = 0;
+    zshPtr->compDictObj = NULL;
+    zshPtr->flags = 0;
+    zshPtr->gzHeaderPtr = gzHeaderPtr;
+    memset(&zshPtr->stream, 0, sizeof(z_stream));
+    zshPtr->stream.adler = 1;
+
+    /*
+     * No output buffer available yet
+     */
+
+    if (mode == TCL_ZLIB_STREAM_DEFLATE) {
+	e = deflateInit2(&zshPtr->stream, level, Z_DEFLATED, wbits,
+		MAX_MEM_LEVEL, Z_DEFAULT_STRATEGY);
+	if (e == Z_OK && zshPtr->gzHeaderPtr) {
+	    e = deflateSetHeader(&zshPtr->stream,
+		    &zshPtr->gzHeaderPtr->header);
+	}
+    } else {
+	e = inflateInit2(&zshPtr->stream, wbits);
+	if (e == Z_OK && zshPtr->gzHeaderPtr) {
+	    e = inflateGetHeader(&zshPtr->stream,
+		    &zshPtr->gzHeaderPtr->header);
+	}
+    }
+
+    if (e != Z_OK) {
+	ConvertError(interp, e, zshPtr->stream.adler);
+	goto error;
+    }
+
+    /*
+     * I could do all this in C, but this is easier.
+     */
+
+    if (interp != NULL) {
+	if (Tcl_EvalEx(interp, "::incr ::tcl::zlib::cmdcounter", -1, 0) != TCL_OK) {
+	    goto error;
+	}
+	Tcl_DStringInit(&cmdname);
+	TclDStringAppendLiteral(&cmdname, "::tcl::zlib::streamcmd_");
+	TclDStringAppendObj(&cmdname, Tcl_GetObjResult(interp));
+	if (Tcl_FindCommand(interp, Tcl_DStringValue(&cmdname),
+		NULL, 0) != NULL) {
+	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		    "BUG: Stream command name already exists", -1));
+	    Tcl_SetErrorCode(interp, "TCL", "BUG", "EXISTING_CMD", NULL);
+	    Tcl_DStringFree(&cmdname);
+	    goto error;
+	}
+	Tcl_ResetResult(interp);
+
+	/*
+	 * Create the command.
+	 */
+
+	zshPtr->cmd = Tcl_CreateObjCommand(interp, Tcl_DStringValue(&cmdname),
+		ZlibStreamCmd, zshPtr, ZlibStreamCmdDelete);
+	Tcl_DStringFree(&cmdname);
+	if (zshPtr->cmd == NULL) {
+	    goto error;
+	}
+    } else {
+	zshPtr->cmd = NULL;
+    }
+
+    /*
+     * Prepare the buffers for use.
+     */
+
+    zshPtr->inData = Tcl_NewListObj(0, NULL);
+    Tcl_IncrRefCount(zshPtr->inData);
+    zshPtr->outData = Tcl_NewListObj(0, NULL);
+    Tcl_IncrRefCount(zshPtr->outData);
+
+    zshPtr->outPos = 0;
+
+    /*
+     * Now set the variable pointed to by *zshandlePtr to the pointer to the
+     * zsh struct.
+     */
+
+    if (zshandlePtr) {
+	*zshandlePtr = (Tcl_ZlibStream) zshPtr;
+    }
+
+    return TCL_OK;
+
+  error:
+    if (zshPtr->compDictObj) {
+	Tcl_DecrRefCount(zshPtr->compDictObj);
+    }
+    if (zshPtr->gzHeaderPtr) {
+	ckfree(zshPtr->gzHeaderPtr);
+    }
+    ckfree(zshPtr);
+    return TCL_ERROR;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ZlibStreamCmdDelete --
+ *
+ *	This is the delete command which Tcl invokes when a zlibstream command
+ *	is deleted from the interpreter (on stream close, usually).
+ *
+ * Results:
+ *	None
+ *
+ * Side effects:
+ *	Invalidates the zlib stream handle as obtained from Tcl_ZlibStreamInit
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+ZlibStreamCmdDelete(
+    ClientData cd)
+{
+    ZlibStreamHandle *zshPtr = cd;
+
+    zshPtr->cmd = NULL;
+    ZlibStreamCleanup(zshPtr);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_ZlibStreamClose --
+ *
+ *	This procedure must be called after (de)compression is done to ensure
+ *	memory is freed and the command is deleted from the interpreter (if
+ *	any).
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	Invalidates the zlib stream handle as obtained from Tcl_ZlibStreamInit
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_ZlibStreamClose(
+    Tcl_ZlibStream zshandle)	/* As obtained from Tcl_ZlibStreamInit. */
+{
+    ZlibStreamHandle *zshPtr = (ZlibStreamHandle *) zshandle;
+
+    /*
+     * If the interp is set, deleting the command will trigger
+     * ZlibStreamCleanup in ZlibStreamCmdDelete. If no interp is set, call
+     * ZlibStreamCleanup directly.
+     */
+
+    if (zshPtr->interp && zshPtr->cmd) {
+	Tcl_DeleteCommandFromToken(zshPtr->interp, zshPtr->cmd);
+    } else {
+	ZlibStreamCleanup(zshPtr);
+    }
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ZlibStreamCleanup --
+ *
+ *	This procedure is called by either Tcl_ZlibStreamClose or
+ *	ZlibStreamCmdDelete to cleanup the stream context.
+ *
+ * Results:
+ *	None
+ *
+ * Side effects:
+ *	Invalidates the zlib stream handle.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+ZlibStreamCleanup(
+    ZlibStreamHandle *zshPtr)
+{
+    if (!zshPtr->streamEnd) {
+	if (zshPtr->mode == TCL_ZLIB_STREAM_DEFLATE) {
+	    deflateEnd(&zshPtr->stream);
+	} else {
+	    inflateEnd(&zshPtr->stream);
+	}
+    }
+
+    if (zshPtr->inData) {
+	Tcl_DecrRefCount(zshPtr->inData);
+    }
+    if (zshPtr->outData) {
+	Tcl_DecrRefCount(zshPtr->outData);
+    }
+    if (zshPtr->currentInput) {
+	Tcl_DecrRefCount(zshPtr->currentInput);
+    }
+    if (zshPtr->compDictObj) {
+	Tcl_DecrRefCount(zshPtr->compDictObj);
+    }
+    if (zshPtr->gzHeaderPtr) {
+	ckfree(zshPtr->gzHeaderPtr);
+    }
+
+    ckfree(zshPtr);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_ZlibStreamReset --
+ *
+ *	This procedure will reinitialize an existing stream handle.
+ *
+ * Results:
+ *	A standard Tcl result.
+ *
+ * Side effects:
+ *	Any data left in the (de)compression buffer is lost.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_ZlibStreamReset(
+    Tcl_ZlibStream zshandle)	/* As obtained from Tcl_ZlibStreamInit */
+{
+    ZlibStreamHandle *zshPtr = (ZlibStreamHandle *) zshandle;
+    int e;
+
+    if (!zshPtr->streamEnd) {
+	if (zshPtr->mode == TCL_ZLIB_STREAM_DEFLATE) {
+	    deflateEnd(&zshPtr->stream);
+	} else {
+	    inflateEnd(&zshPtr->stream);
+	}
+    }
+    Tcl_SetByteArrayLength(zshPtr->inData, 0);
+    Tcl_SetByteArrayLength(zshPtr->outData, 0);
+    if (zshPtr->currentInput) {
+	Tcl_DecrRefCount(zshPtr->currentInput);
+	zshPtr->currentInput = NULL;
+    }
+
+    zshPtr->outPos = 0;
+    zshPtr->streamEnd = 0;
+    memset(&zshPtr->stream, 0, sizeof(z_stream));
+
+    /*
+     * No output buffer available yet.
+     */
+
+    if (zshPtr->mode == TCL_ZLIB_STREAM_DEFLATE) {
+	e = deflateInit2(&zshPtr->stream, zshPtr->level, Z_DEFLATED,
+		zshPtr->wbits, MAX_MEM_LEVEL, Z_DEFAULT_STRATEGY);
+	if (e == Z_OK && HaveDictToSet(zshPtr)) {
+	    e = SetDeflateDictionary(&zshPtr->stream, zshPtr->compDictObj);
+	    if (e == Z_OK) {
+		DictWasSet(zshPtr);
+	    }
+	}
+    } else {
+	e = inflateInit2(&zshPtr->stream, zshPtr->wbits);
+	if (IsRawStream(zshPtr) && HaveDictToSet(zshPtr) && e == Z_OK) {
+	    e = SetInflateDictionary(&zshPtr->stream, zshPtr->compDictObj);
+	    if (e == Z_OK) {
+		DictWasSet(zshPtr);
+	    }
+	}
+    }
+
+    if (e != Z_OK) {
+	ConvertError(zshPtr->interp, e, zshPtr->stream.adler);
+	/* TODO:cleanup */
+	return TCL_ERROR;
+    }
+
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_ZlibStreamGetCommandName --
+ *
+ *	This procedure will return the command name associated with the
+ *	stream.
+ *
+ * Results:
+ *	A Tcl_Obj with the name of the Tcl command or NULL if no command is
+ *	associated with the stream.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+Tcl_Obj *
+Tcl_ZlibStreamGetCommandName(
+    Tcl_ZlibStream zshandle)	/* As obtained from Tcl_ZlibStreamInit */
+{
+    ZlibStreamHandle *zshPtr = (ZlibStreamHandle *) zshandle;
+    Tcl_Obj *objPtr;
+
+    if (!zshPtr->interp) {
+	return NULL;
+    }
+
+    TclNewObj(objPtr);
+    Tcl_GetCommandFullName(zshPtr->interp, zshPtr->cmd, objPtr);
+    return objPtr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_ZlibStreamEof --
+ *
+ *	This procedure This function returns 0 or 1 depending on the state of
+ *	the (de)compressor. For decompression, eof is reached when the entire
+ *	compressed stream has been decompressed. For compression, eof is
+ *	reached when the stream has been flushed with TCL_ZLIB_FINALIZE.
+ *
+ * Results:
+ *	Integer.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_ZlibStreamEof(
+    Tcl_ZlibStream zshandle)	/* As obtained from Tcl_ZlibStreamInit */
+{
+    ZlibStreamHandle *zshPtr = (ZlibStreamHandle *) zshandle;
+
+    return zshPtr->streamEnd;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_ZlibStreamChecksum --
+ *
+ *	Return the checksum of the uncompressed data seen so far by the
+ *	stream.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_ZlibStreamChecksum(
+    Tcl_ZlibStream zshandle)	/* As obtained from Tcl_ZlibStreamInit */
+{
+    ZlibStreamHandle *zshPtr = (ZlibStreamHandle *) zshandle;
+
+    return zshPtr->stream.adler;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_ZlibStreamSetCompressionDictionary --
+ *
+ *	Sets the compression dictionary for a stream. This will be used as
+ *	appropriate for the next compression or decompression action performed
+ *	on the stream.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_ZlibStreamSetCompressionDictionary(
+    Tcl_ZlibStream zshandle,
+    Tcl_Obj *compressionDictionaryObj)
+{
+    ZlibStreamHandle *zshPtr = (ZlibStreamHandle *) zshandle;
+
+    if (compressionDictionaryObj != NULL) {
+	if (Tcl_IsShared(compressionDictionaryObj)) {
+	    compressionDictionaryObj =
+		    Tcl_DuplicateObj(compressionDictionaryObj);
+	}
+	Tcl_IncrRefCount(compressionDictionaryObj);
+	zshPtr->flags |= DICT_TO_SET;
+    } else {
+	zshPtr->flags &= ~DICT_TO_SET;
+    }
+    if (zshPtr->compDictObj != NULL) {
+	Tcl_DecrRefCount(zshPtr->compDictObj);
+    }
+    zshPtr->compDictObj = compressionDictionaryObj;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_ZlibStreamPut --
+ *
+ *	Add data to the stream for compression or decompression from a
+ *	bytearray Tcl_Obj.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_ZlibStreamPut(
+    Tcl_ZlibStream zshandle,	/* As obtained from Tcl_ZlibStreamInit */
+    Tcl_Obj *data,		/* Data to compress/decompress */
+    int flush)			/* TCL_ZLIB_NO_FLUSH, TCL_ZLIB_FLUSH,
+				 * TCL_ZLIB_FULLFLUSH, or TCL_ZLIB_FINALIZE */
+{
+    ZlibStreamHandle *zshPtr = (ZlibStreamHandle *) zshandle;
+    char *dataTmp = NULL;
+    int e, size, outSize;
+    Tcl_Obj *obj;
+
+    if (zshPtr->streamEnd) {
+	if (zshPtr->interp) {
+	    Tcl_SetObjResult(zshPtr->interp, Tcl_NewStringObj(
+		    "already past compressed stream end", -1));
+	    Tcl_SetErrorCode(zshPtr->interp, "TCL", "ZIP", "CLOSED", NULL);
+	}
+	return TCL_ERROR;
+    }
+
+    if (zshPtr->mode == TCL_ZLIB_STREAM_DEFLATE) {
+	zshPtr->stream.next_in = Tcl_GetByteArrayFromObj(data, &size);
+	zshPtr->stream.avail_in = size;
+
+	/*
+	 * Must not do a zero-length compress. [Bug 25842c161]
+	 */
+
+	if (size == 0) {
+	    return TCL_OK;
+	}
+
+	if (HaveDictToSet(zshPtr)) {
+	    e = SetDeflateDictionary(&zshPtr->stream, zshPtr->compDictObj);
+	    if (e != Z_OK) {
+		if (zshPtr->interp) {
+		    ConvertError(zshPtr->interp, e, zshPtr->stream.adler);
+		}
+		return TCL_ERROR;
+	    }
+	    DictWasSet(zshPtr);
+	}
+
+	/*
+	 * Deflatebound doesn't seem to take various header sizes into
+	 * account, so we add 100 extra bytes.
+	 */
+
+	outSize = deflateBound(&zshPtr->stream, zshPtr->stream.avail_in)+100;
+	zshPtr->stream.avail_out = outSize;
+	dataTmp = ckalloc(zshPtr->stream.avail_out);
+	zshPtr->stream.next_out = (Bytef *) dataTmp;
+
+	e = deflate(&zshPtr->stream, flush);
+	while (e == Z_BUF_ERROR || (flush == Z_FINISH && e == Z_OK)) {
+	    /*
+	     * Output buffer too small to hold the data being generated or we
+	     * are doing the end-of-stream flush (which can spit out masses of
+	     * data). This means we need to put a new buffer into place after
+	     * saving the old generated data to the outData list.
+	     */
+
+	    obj = Tcl_NewByteArrayObj((unsigned char *) dataTmp, outSize);
+	    Tcl_ListObjAppendElement(NULL, zshPtr->outData, obj);
+
+	    if (outSize < 0xFFFF) {
+		outSize = 0xFFFF;	/* There may be *lots* of data left to
+					 * output... */
+		dataTmp = ckrealloc(dataTmp, outSize);
+	    }
+	    zshPtr->stream.avail_out = outSize;
+	    zshPtr->stream.next_out = (Bytef *) dataTmp;
+
+	    e = deflate(&zshPtr->stream, flush);
+	}
+
+	if (e != Z_OK && !(flush==Z_FINISH && e==Z_STREAM_END)) {
+	    if (zshPtr->interp) {
+		ConvertError(zshPtr->interp, e, zshPtr->stream.adler);
+	    }
+	    return TCL_ERROR;
+	}
+
+	/*
+	 * And append the final data block.
+	 */
+
+	if (outSize - zshPtr->stream.avail_out > 0) {
+	    obj = Tcl_NewByteArrayObj((unsigned char *) dataTmp,
+		    outSize - zshPtr->stream.avail_out);
+
+	    /*
+	     * Now append the compressed data to the outData list.
+	     */
+
+	    Tcl_ListObjAppendElement(NULL, zshPtr->outData, obj);
+	}
+
+	if (dataTmp) {
+	    ckfree(dataTmp);
+	}
+    } else {
+	/*
+	 * This is easy. Just append to the inData list.
+	 */
+
+	Tcl_ListObjAppendElement(NULL, zshPtr->inData, data);
+
+	/*
+	 * and we'll need the flush parameter for the Inflate call.
+	 */
+
+	zshPtr->flush = flush;
+    }
+
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_ZlibStreamGet --
+ *
+ *	Retrieve data (now compressed or decompressed) from the stream into a
+ *	bytearray Tcl_Obj.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_ZlibStreamGet(
+    Tcl_ZlibStream zshandle,	/* As obtained from Tcl_ZlibStreamInit */
+    Tcl_Obj *data,		/* A place to append the data. */
+    int count)			/* Number of bytes to grab as a maximum, you
+				 * may get less! */
+{
+    ZlibStreamHandle *zshPtr = (ZlibStreamHandle *) zshandle;
+    int e, i, listLen, itemLen, dataPos = 0;
+    Tcl_Obj *itemObj;
+    unsigned char *dataPtr, *itemPtr;
+    int existing;
+
+    /*
+     * Getting beyond the of stream, just return empty string.
+     */
+
+    if (zshPtr->streamEnd) {
+	return TCL_OK;
+    }
+
+    (void) Tcl_GetByteArrayFromObj(data, &existing);
+
+    if (zshPtr->mode == TCL_ZLIB_STREAM_INFLATE) {
+	if (count == -1) {
+	    /*
+	     * The only safe thing to do is restict to 65k. We might cause a
+	     * panic for out of memory if we just kept growing the buffer.
+	     */
+
+	    count = MAX_BUFFER_SIZE;
+	}
+
+	/*
+	 * Prepare the place to store the data.
+	 */
+
+	dataPtr = Tcl_SetByteArrayLength(data, existing+count);
+	dataPtr += existing;
+
+	zshPtr->stream.next_out = dataPtr;
+	zshPtr->stream.avail_out = count;
+	if (zshPtr->stream.avail_in == 0) {
+	    /*
+	     * zlib will probably need more data to decompress.
+	     */
+
+	    if (zshPtr->currentInput) {
+		Tcl_DecrRefCount(zshPtr->currentInput);
+		zshPtr->currentInput = NULL;
+	    }
+	    Tcl_ListObjLength(NULL, zshPtr->inData, &listLen);
+	    if (listLen > 0) {
+		/*
+		 * There is more input available, get it from the list and
+		 * give it to zlib. At this point, the data must not be shared
+		 * since we require the bytearray representation to not vanish
+		 * under our feet. [Bug 3081008]
+		 */
+
+		Tcl_ListObjIndex(NULL, zshPtr->inData, 0, &itemObj);
+		if (Tcl_IsShared(itemObj)) {
+		    itemObj = Tcl_DuplicateObj(itemObj);
+		}
+		itemPtr = Tcl_GetByteArrayFromObj(itemObj, &itemLen);
+		Tcl_IncrRefCount(itemObj);
+		zshPtr->currentInput = itemObj;
+		zshPtr->stream.next_in = itemPtr;
+		zshPtr->stream.avail_in = itemLen;
+
+		/*
+		 * And remove it from the list
+		 */
+
+		Tcl_ListObjReplace(NULL, zshPtr->inData, 0, 1, 0, NULL);
+	    }
+	}
+
+	/*
+	 * When dealing with a raw stream, we set the dictionary here, once.
+	 * (You can't do it in response to getting Z_NEED_DATA as raw streams
+	 * don't ever issue that.)
+	 */
+
+	if (IsRawStream(zshPtr) && HaveDictToSet(zshPtr)) {
+	    e = SetInflateDictionary(&zshPtr->stream, zshPtr->compDictObj);
+	    if (e != Z_OK) {
+		if (zshPtr->interp) {
+		    ConvertError(zshPtr->interp, e, zshPtr->stream.adler);
+		}
+		return TCL_ERROR;
+	    }
+	    DictWasSet(zshPtr);
+	}
+	e = inflate(&zshPtr->stream, zshPtr->flush);
+	if (e == Z_NEED_DICT && HaveDictToSet(zshPtr)) {
+	    e = SetInflateDictionary(&zshPtr->stream, zshPtr->compDictObj);
+	    if (e == Z_OK) {
+		DictWasSet(zshPtr);
+		e = inflate(&zshPtr->stream, zshPtr->flush);
+	    }
+	};
+	Tcl_ListObjLength(NULL, zshPtr->inData, &listLen);
+
+	while ((zshPtr->stream.avail_out > 0)
+		&& (e == Z_OK || e == Z_BUF_ERROR) && (listLen > 0)) {
+	    /*
+	     * State: We have not satisfied the request yet and there may be
+	     * more to inflate.
+	     */
+
+	    if (zshPtr->stream.avail_in > 0) {
+		if (zshPtr->interp) {
+		    Tcl_SetObjResult(zshPtr->interp, Tcl_NewStringObj(
+			    "unexpected zlib internal state during"
+			    " decompression", -1));
+		    Tcl_SetErrorCode(zshPtr->interp, "TCL", "ZIP", "STATE",
+			    NULL);
+		}
+		Tcl_SetByteArrayLength(data, existing);
+		return TCL_ERROR;
+	    }
+
+	    if (zshPtr->currentInput) {
+		Tcl_DecrRefCount(zshPtr->currentInput);
+		zshPtr->currentInput = 0;
+	    }
+
+	    /*
+	     * Get the next block of data to go to inflate. At this point, the
+	     * data must not be shared since we require the bytearray
+	     * representation to not vanish under our feet. [Bug 3081008]
+	     */
+
+	    Tcl_ListObjIndex(zshPtr->interp, zshPtr->inData, 0, &itemObj);
+	    if (Tcl_IsShared(itemObj)) {
+		itemObj = Tcl_DuplicateObj(itemObj);
+	    }
+	    itemPtr = Tcl_GetByteArrayFromObj(itemObj, &itemLen);
+	    Tcl_IncrRefCount(itemObj);
+	    zshPtr->currentInput = itemObj;
+	    zshPtr->stream.next_in = itemPtr;
+	    zshPtr->stream.avail_in = itemLen;
+
+	    /*
+	     * Remove it from the list.
+	     */
+
+	    Tcl_ListObjReplace(NULL, zshPtr->inData, 0, 1, 0, NULL);
+	    listLen--;
+
+	    /*
+	     * And call inflate again.
+	     */
+
+	    do {
+		e = inflate(&zshPtr->stream, zshPtr->flush);
+		if (e != Z_NEED_DICT || !HaveDictToSet(zshPtr)) {
+		    break;
+		}
+		e = SetInflateDictionary(&zshPtr->stream,zshPtr->compDictObj);
+		DictWasSet(zshPtr);
+	    } while (e == Z_OK);
+	}
+	if (zshPtr->stream.avail_out > 0) {
+	    Tcl_SetByteArrayLength(data,
+		    existing + count - zshPtr->stream.avail_out);
+	}
+	if (!(e==Z_OK || e==Z_STREAM_END || e==Z_BUF_ERROR)) {
+	    Tcl_SetByteArrayLength(data, existing);
+	    ConvertError(zshPtr->interp, e, zshPtr->stream.adler);
+	    return TCL_ERROR;
+	}
+	if (e == Z_STREAM_END) {
+	    zshPtr->streamEnd = 1;
+	    if (zshPtr->currentInput) {
+		Tcl_DecrRefCount(zshPtr->currentInput);
+		zshPtr->currentInput = 0;
+	    }
+	    inflateEnd(&zshPtr->stream);
+	}
+    } else {
+	Tcl_ListObjLength(NULL, zshPtr->outData, &listLen);
+	if (count == -1) {
+	    count = 0;
+	    for (i=0; i<listLen; i++) {
+		Tcl_ListObjIndex(NULL, zshPtr->outData, i, &itemObj);
+		itemPtr = Tcl_GetByteArrayFromObj(itemObj, &itemLen);
+		if (i == 0) {
+		    count += itemLen - zshPtr->outPos;
+		} else {
+		    count += itemLen;
+		}
+	    }
+	}
+
+	/*
+	 * Prepare the place to store the data.
+	 */
+
+	dataPtr = Tcl_SetByteArrayLength(data, existing + count);
+	dataPtr += existing;
+
+	while ((count > dataPos) &&
+		(Tcl_ListObjLength(NULL, zshPtr->outData, &listLen) == TCL_OK)
+		&& (listLen > 0)) {
+	    /*
+	     * Get the next chunk off our list of chunks and grab the data out
+	     * of it.
+	     */
+
+	    Tcl_ListObjIndex(NULL, zshPtr->outData, 0, &itemObj);
+	    itemPtr = Tcl_GetByteArrayFromObj(itemObj, &itemLen);
+	    if (itemLen-zshPtr->outPos >= count-dataPos) {
+		unsigned len = count - dataPos;
+
+		memcpy(dataPtr + dataPos, itemPtr + zshPtr->outPos, len);
+		zshPtr->outPos += len;
+		dataPos += len;
+		if (zshPtr->outPos == itemLen) {
+		    zshPtr->outPos = 0;
+		}
+	    } else {
+		unsigned len = itemLen - zshPtr->outPos;
+
+		memcpy(dataPtr + dataPos, itemPtr + zshPtr->outPos, len);
+		dataPos += len;
+		zshPtr->outPos = 0;
+	    }
+	    if (zshPtr->outPos == 0) {
+		Tcl_ListObjReplace(NULL, zshPtr->outData, 0, 1, 0, NULL);
+		listLen--;
+	    }
+	}
+	Tcl_SetByteArrayLength(data, existing + dataPos);
+    }
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_ZlibDeflate --
+ *
+ *	Compress the contents of Tcl_Obj *data with compression level in
+ *	output format, producing the compressed data in the interpreter
+ *	result.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_ZlibDeflate(
+    Tcl_Interp *interp,
+    int format,
+    Tcl_Obj *data,
+    int level,
+    Tcl_Obj *gzipHeaderDictObj)
+{
+    int wbits = 0, inLen = 0, e = 0, extraSize = 0;
+    Byte *inData = NULL;
+    z_stream stream;
+    GzipHeader header;
+    gz_header *headerPtr = NULL;
+    Tcl_Obj *obj;
+
+    if (!interp) {
+	return TCL_ERROR;
+    }
+
+    /*
+     * Compressed format is specified by the wbits parameter. See zlib.h for
+     * details.
+     */
+
+    if (format == TCL_ZLIB_FORMAT_RAW) {
+	wbits = WBITS_RAW;
+    } else if (format == TCL_ZLIB_FORMAT_GZIP) {
+	wbits = WBITS_GZIP;
+
+	/*
+	 * Need to allocate extra space for the gzip header and footer. The
+	 * amount of space is (a bit less than) 32 bytes, plus a byte for each
+	 * byte of string that we add. Note that over-allocation is not a
+	 * problem. [Bug 2419061]
+	 */
+
+	extraSize = 32;
+	if (gzipHeaderDictObj) {
+	    headerPtr = &header.header;
+	    memset(headerPtr, 0, sizeof(gz_header));
+	    if (GenerateHeader(interp, gzipHeaderDictObj, &header,
+		    &extraSize) != TCL_OK) {
+		return TCL_ERROR;
+	    }
+	}
+    } else if (format == TCL_ZLIB_FORMAT_ZLIB) {
+	wbits = WBITS_ZLIB;
+    } else {
+	Tcl_Panic("incorrect zlib data format, must be TCL_ZLIB_FORMAT_ZLIB, "
+		"TCL_ZLIB_FORMAT_GZIP or TCL_ZLIB_FORMAT_ZLIB");
+    }
+
+    if (level < -1 || level > 9) {
+	Tcl_Panic("compression level should be between 0 (uncompressed) and "
+		"9 (best compression) or -1 for default compression level");
+    }
+
+    /*
+     * Allocate some space to store the output.
+     */
+
+    TclNewObj(obj);
+
+    /*
+     * Obtain the pointer to the byte array, we'll pass this pointer straight
+     * to the deflate command.
+     */
+
+    inData = Tcl_GetByteArrayFromObj(data, &inLen);
+    memset(&stream, 0, sizeof(z_stream));
+    stream.avail_in = (uInt) inLen;
+    stream.next_in = inData;
+
+    /*
+     * No output buffer available yet, will alloc after deflateInit2.
+     */
+
+    e = deflateInit2(&stream, level, Z_DEFLATED, wbits, MAX_MEM_LEVEL,
+	    Z_DEFAULT_STRATEGY);
+    if (e != Z_OK) {
+	goto error;
+    }
+
+    if (headerPtr != NULL) {
+	e = deflateSetHeader(&stream, headerPtr);
+	if (e != Z_OK) {
+	    goto error;
+	}
+    }
+
+    /*
+     * Allocate the output buffer from the value of deflateBound(). This is
+     * probably too much space. Before returning to the caller, we will reduce
+     * it back to the actual compressed size.
+     */
+
+    stream.avail_out = deflateBound(&stream, inLen) + extraSize;
+    stream.next_out = Tcl_SetByteArrayLength(obj, stream.avail_out);
+
+    /*
+     * Perform the compression, Z_FINISH means do it in one go.
+     */
+
+    e = deflate(&stream, Z_FINISH);
+
+    if (e != Z_STREAM_END) {
+	e = deflateEnd(&stream);
+
+	/*
+	 * deflateEnd() returns Z_OK when there are bytes left to compress, at
+	 * this point we consider that an error, although we could continue by
+	 * allocating more memory and calling deflate() again.
+	 */
+
+	if (e == Z_OK) {
+	    e = Z_BUF_ERROR;
+	}
+    } else {
+	e = deflateEnd(&stream);
+    }
+
+    if (e != Z_OK) {
+	goto error;
+    }
+
+    /*
+     * Reduce the bytearray length to the actual data length produced by
+     * deflate.
+     */
+
+    Tcl_SetByteArrayLength(obj, stream.total_out);
+    Tcl_SetObjResult(interp, obj);
+    return TCL_OK;
+
+  error:
+    ConvertError(interp, e, stream.adler);
+    TclDecrRefCount(obj);
+    return TCL_ERROR;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_ZlibInflate --
+ *
+ *	Decompress data in an object into the interpreter result.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_ZlibInflate(
+    Tcl_Interp *interp,
+    int format,
+    Tcl_Obj *data,
+    int bufferSize,
+    Tcl_Obj *gzipHeaderDictObj)
+{
+    int wbits = 0, inLen = 0, e = 0, newBufferSize;
+    Byte *inData = NULL, *outData = NULL, *newOutData = NULL;
+    z_stream stream;
+    gz_header header, *headerPtr = NULL;
+    Tcl_Obj *obj;
+    char *nameBuf = NULL, *commentBuf = NULL;
+
+    if (!interp) {
+	return TCL_ERROR;
+    }
+
+    /*
+     * Compressed format is specified by the wbits parameter. See zlib.h for
+     * details.
+     */
+
+    switch (format) {
+    case TCL_ZLIB_FORMAT_RAW:
+	wbits = WBITS_RAW;
+	gzipHeaderDictObj = NULL;
+	break;
+    case TCL_ZLIB_FORMAT_ZLIB:
+	wbits = WBITS_ZLIB;
+	gzipHeaderDictObj = NULL;
+	break;
+    case TCL_ZLIB_FORMAT_GZIP:
+	wbits = WBITS_GZIP;
+	break;
+    case TCL_ZLIB_FORMAT_AUTO:
+	wbits = WBITS_AUTODETECT;
+	break;
+    default:
+	Tcl_Panic("incorrect zlib data format, must be TCL_ZLIB_FORMAT_ZLIB, "
+		"TCL_ZLIB_FORMAT_GZIP, TCL_ZLIB_FORMAT_RAW or "
+		"TCL_ZLIB_FORMAT_AUTO");
+    }
+
+    if (gzipHeaderDictObj) {
+	headerPtr = &header;
+	memset(headerPtr, 0, sizeof(gz_header));
+	nameBuf = ckalloc(MAXPATHLEN);
+	header.name = (Bytef *) nameBuf;
+	header.name_max = MAXPATHLEN - 1;
+	commentBuf = ckalloc(MAX_COMMENT_LEN);
+	header.comment = (Bytef *) commentBuf;
+	header.comm_max = MAX_COMMENT_LEN - 1;
+    }
+
+    inData = Tcl_GetByteArrayFromObj(data, &inLen);
+    if (bufferSize < 1) {
+	/*
+	 * Start with a buffer (up to) 3 times the size of the input data.
+	 */
+
+	if (inLen < 32*1024*1024) {
+	    bufferSize = 3*inLen;
+	} else if (inLen < 256*1024*1024) {
+	    bufferSize = 2*inLen;
+	} else {
+	    bufferSize = inLen;
+	}
+    }
+
+    TclNewObj(obj);
+    outData = Tcl_SetByteArrayLength(obj, bufferSize);
+    memset(&stream, 0, sizeof(z_stream));
+    stream.avail_in = (uInt) inLen+1;	/* +1 because zlib can "over-request"
+					 * input (but ignore it!) */
+    stream.next_in = inData;
+    stream.avail_out = bufferSize;
+    stream.next_out = outData;
+
+    /*
+     * Initialize zlib for decompression.
+     */
+
+    e = inflateInit2(&stream, wbits);
+    if (e != Z_OK) {
+	goto error;
+    }
+    if (headerPtr) {
+	e = inflateGetHeader(&stream, headerPtr);
+	if (e != Z_OK) {
+	    inflateEnd(&stream);
+	    goto error;
+	}
+    }
+
+    /*
+     * Start the decompression cycle.
+     */
+
+    while (1) {
+	e = inflate(&stream, Z_FINISH);
+	if (e != Z_BUF_ERROR) {
+	    break;
+	}
+
+	/*
+	 * Not enough room in the output buffer. Increase it by five times the
+	 * bytes still in the input buffer. (Because 3 times didn't do the
+	 * trick before, 5 times is what we do next.) Further optimization
+	 * should be done by the user, specify the decompressed size!
+	 */
+
+	if ((stream.avail_in == 0) && (stream.avail_out > 0)) {
+	    e = Z_STREAM_ERROR;
+	    break;
+	}
+	newBufferSize = bufferSize + 5 * stream.avail_in;
+	if (newBufferSize == bufferSize) {
+	    newBufferSize = bufferSize+1000;
+	}
+	newOutData = Tcl_SetByteArrayLength(obj, newBufferSize);
+
+	/*
+	 * Set next out to the same offset in the new location.
+	 */
+
+	stream.next_out = newOutData + stream.total_out;
+
+	/*
+	 * And increase avail_out with the number of new bytes allocated.
+	 */
+
+	stream.avail_out += newBufferSize - bufferSize;
+	outData = newOutData;
+	bufferSize = newBufferSize;
+    }
+
+    if (e != Z_STREAM_END) {
+	inflateEnd(&stream);
+	goto error;
+    }
+
+    e = inflateEnd(&stream);
+    if (e != Z_OK) {
+	goto error;
+    }
+
+    /*
+     * Reduce the BA length to the actual data length produced by deflate.
+     */
+
+    Tcl_SetByteArrayLength(obj, stream.total_out);
+    if (headerPtr != NULL) {
+	ExtractHeader(&header, gzipHeaderDictObj);
+	SetValue(gzipHeaderDictObj, "size",
+		Tcl_NewLongObj((long) stream.total_out));
+	ckfree(nameBuf);
+	ckfree(commentBuf);
+    }
+    Tcl_SetObjResult(interp, obj);
+    return TCL_OK;
+
+  error:
+    TclDecrRefCount(obj);
+    ConvertError(interp, e, stream.adler);
+    if (nameBuf) {
+	ckfree(nameBuf);
+    }
+    if (commentBuf) {
+	ckfree(commentBuf);
+    }
+    return TCL_ERROR;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_ZlibCRC32, Tcl_ZlibAdler32 --
+ *
+ *	Access to the checksumming engines.
+ *
+ *----------------------------------------------------------------------
+ */
+
+unsigned int
+Tcl_ZlibCRC32(
+    unsigned int crc,
+    const unsigned char *buf,
+    int len)
+{
+    /* Nothing much to do, just wrap the crc32(). */
+    return crc32(crc, (Bytef *) buf, (unsigned) len);
+}
+
+unsigned int
+Tcl_ZlibAdler32(
+    unsigned int adler,
+    const unsigned char *buf,
+    int len)
+{
+    return adler32(adler, (Bytef *) buf, (unsigned) len);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ZlibCmd --
+ *
+ *	Implementation of the [zlib] command.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+ZlibCmd(
+    ClientData notUsed,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const objv[])
+{
+    int command, dlen, i, option, level = -1;
+    unsigned start, buffersize = 0;
+    Byte *data;
+    Tcl_Obj *headerDictObj;
+    const char *extraInfoStr = NULL;
+    static const char *const commands[] = {
+	"adler32", "compress", "crc32", "decompress", "deflate", "gunzip",
+	"gzip", "inflate", "push", "stream",
+	NULL
+    };
+    enum zlibCommands {
+	CMD_ADLER, CMD_COMPRESS, CMD_CRC, CMD_DECOMPRESS, CMD_DEFLATE,
+	CMD_GUNZIP, CMD_GZIP, CMD_INFLATE, CMD_PUSH, CMD_STREAM
+    };
+
+    if (objc < 2) {
+	Tcl_WrongNumArgs(interp, 1, objv, "command arg ?...?");
+	return TCL_ERROR;
+    }
+    if (Tcl_GetIndexFromObj(interp, objv[1], commands, "command", 0,
+	    &command) != TCL_OK) {
+	return TCL_ERROR;
+    }
+
+    switch ((enum zlibCommands) command) {
+    case CMD_ADLER:			/* adler32 str ?startvalue?
+					 * -> checksum */
+	if (objc < 3 || objc > 4) {
+	    Tcl_WrongNumArgs(interp, 2, objv, "data ?startValue?");
+	    return TCL_ERROR;
+	}
+	if (objc>3 && Tcl_GetIntFromObj(interp, objv[3],
+		(int *) &start) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	if (objc < 4) {
+	    start = Tcl_ZlibAdler32(0, NULL, 0);
+	}
+	data = Tcl_GetByteArrayFromObj(objv[2], &dlen);
+	Tcl_SetObjResult(interp, Tcl_NewWideIntObj((Tcl_WideInt)
+		(uLong) Tcl_ZlibAdler32(start, data, dlen)));
+	return TCL_OK;
+    case CMD_CRC:			/* crc32 str ?startvalue?
+					 * -> checksum */
+	if (objc < 3 || objc > 4) {
+	    Tcl_WrongNumArgs(interp, 2, objv, "data ?startValue?");
+	    return TCL_ERROR;
+	}
+	if (objc>3 && Tcl_GetIntFromObj(interp, objv[3],
+		(int *) &start) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	if (objc < 4) {
+	    start = Tcl_ZlibCRC32(0, NULL, 0);
+	}
+	data = Tcl_GetByteArrayFromObj(objv[2], &dlen);
+	Tcl_SetObjResult(interp, Tcl_NewWideIntObj((Tcl_WideInt)
+		(uLong) Tcl_ZlibCRC32(start, data, dlen)));
+	return TCL_OK;
+    case CMD_DEFLATE:			/* deflate data ?level?
+					 * -> rawCompressedData */
+	if (objc < 3 || objc > 4) {
+	    Tcl_WrongNumArgs(interp, 2, objv, "data ?level?");
+	    return TCL_ERROR;
+	}
+	if (objc > 3) {
+	    if (Tcl_GetIntFromObj(interp, objv[3], &level) != TCL_OK) {
+		return TCL_ERROR;
+	    }
+	    if (level < 0 || level > 9) {
+		goto badLevel;
+	    }
+	}
+	return Tcl_ZlibDeflate(interp, TCL_ZLIB_FORMAT_RAW, objv[2], level,
+		NULL);
+    case CMD_COMPRESS:			/* compress data ?level?
+					 * -> zlibCompressedData */
+	if (objc < 3 || objc > 4) {
+	    Tcl_WrongNumArgs(interp, 2, objv, "data ?level?");
+	    return TCL_ERROR;
+	}
+	if (objc > 3) {
+	    if (Tcl_GetIntFromObj(interp, objv[3], &level) != TCL_OK) {
+		return TCL_ERROR;
+	    }
+	    if (level < 0 || level > 9) {
+		goto badLevel;
+	    }
+	}
+	return Tcl_ZlibDeflate(interp, TCL_ZLIB_FORMAT_ZLIB, objv[2], level,
+		NULL);
+    case CMD_GZIP:			/* gzip data ?level?
+					 * -> gzippedCompressedData */
+	headerDictObj = NULL;
+
+	/*
+	 * Legacy argument format support.
+	 */
+
+	if (objc == 4
+		&& Tcl_GetIntFromObj(interp, objv[3], &level) == TCL_OK) {
+	    if (level < 0 || level > 9) {
+		extraInfoStr = "\n    (in -level option)";
+		goto badLevel;
+	    }
+	    return Tcl_ZlibDeflate(interp, TCL_ZLIB_FORMAT_GZIP, objv[2],
+		    level, NULL);
+	}
+
+	if (objc < 3 || objc > 7 || ((objc & 1) == 0)) {
+	    Tcl_WrongNumArgs(interp, 2, objv,
+		    "data ?-level level? ?-header header?");
+	    return TCL_ERROR;
+	}
+	for (i=3 ; i<objc ; i+=2) {
+	    static const char *const gzipopts[] = {
+		"-header", "-level", NULL
+	    };
+
+	    if (Tcl_GetIndexFromObj(interp, objv[i], gzipopts, "option", 0,
+		    &option) != TCL_OK) {
+		return TCL_ERROR;
+	    }
+	    switch (option) {
+	    case 0:
+		headerDictObj = objv[i+1];
+		break;
+	    case 1:
+		if (Tcl_GetIntFromObj(interp, objv[i+1],
+			&level) != TCL_OK) {
+		    return TCL_ERROR;
+		}
+		if (level < 0 || level > 9) {
+		    extraInfoStr = "\n    (in -level option)";
+		    goto badLevel;
+		}
+		break;
+	    }
+	}
+	return Tcl_ZlibDeflate(interp, TCL_ZLIB_FORMAT_GZIP, objv[2], level,
+		headerDictObj);
+    case CMD_INFLATE:			/* inflate rawcomprdata ?bufferSize?
+					 *	-> decompressedData */
+	if (objc < 3 || objc > 4) {
+	    Tcl_WrongNumArgs(interp, 2, objv, "data ?bufferSize?");
+	    return TCL_ERROR;
+	}
+	if (objc > 3) {
+	    if (Tcl_GetIntFromObj(interp, objv[3],
+		    (int *) &buffersize) != TCL_OK) {
+		return TCL_ERROR;
+	    }
+	    if (buffersize < MIN_NONSTREAM_BUFFER_SIZE
+		    || buffersize > MAX_BUFFER_SIZE) {
+		goto badBuffer;
+	    }
+	}
+	return Tcl_ZlibInflate(interp, TCL_ZLIB_FORMAT_RAW, objv[2],
+		buffersize, NULL);
+    case CMD_DECOMPRESS:		/* decompress zlibcomprdata \
+					 *    ?bufferSize?
+					 *	-> decompressedData */
+	if (objc < 3 || objc > 4) {
+	    Tcl_WrongNumArgs(interp, 2, objv, "data ?bufferSize?");
+	    return TCL_ERROR;
+	}
+	if (objc > 3) {
+	    if (Tcl_GetIntFromObj(interp, objv[3],
+		    (int *) &buffersize) != TCL_OK) {
+		return TCL_ERROR;
+	    }
+	    if (buffersize < MIN_NONSTREAM_BUFFER_SIZE
+		    || buffersize > MAX_BUFFER_SIZE) {
+		goto badBuffer;
+	    }
+	}
+	return Tcl_ZlibInflate(interp, TCL_ZLIB_FORMAT_ZLIB, objv[2],
+		buffersize, NULL);
+    case CMD_GUNZIP: {			/* gunzip gzippeddata ?bufferSize?
+					 *	-> decompressedData */
+	Tcl_Obj *headerVarObj;
+
+	if (objc < 3 || objc > 5 || ((objc & 1) == 0)) {
+	    Tcl_WrongNumArgs(interp, 2, objv, "data ?-headerVar varName?");
+	    return TCL_ERROR;
+	}
+	headerDictObj = headerVarObj = NULL;
+	for (i=3 ; i<objc ; i+=2) {
+	    static const char *const gunzipopts[] = {
+		"-buffersize", "-headerVar", NULL
+	    };
+
+	    if (Tcl_GetIndexFromObj(interp, objv[i], gunzipopts, "option", 0,
+		    &option) != TCL_OK) {
+		return TCL_ERROR;
+	    }
+	    switch (option) {
+	    case 0:
+		if (Tcl_GetIntFromObj(interp, objv[i+1],
+			(int *) &buffersize) != TCL_OK) {
+		    return TCL_ERROR;
+		}
+		if (buffersize < MIN_NONSTREAM_BUFFER_SIZE
+			|| buffersize > MAX_BUFFER_SIZE) {
+		    goto badBuffer;
+		}
+		break;
+	    case 1:
+		headerVarObj = objv[i+1];
+		headerDictObj = Tcl_NewObj();
+		break;
+	    }
+	}
+	if (Tcl_ZlibInflate(interp, TCL_ZLIB_FORMAT_GZIP, objv[2],
+		buffersize, headerDictObj) != TCL_OK) {
+	    if (headerDictObj) {
+		TclDecrRefCount(headerDictObj);
+	    }
+	    return TCL_ERROR;
+	}
+	if (headerVarObj != NULL && Tcl_ObjSetVar2(interp, headerVarObj, NULL,
+		headerDictObj, TCL_LEAVE_ERR_MSG) == NULL) {
+	    return TCL_ERROR;
+	}
+	return TCL_OK;
+    }
+    case CMD_STREAM:			/* stream deflate/inflate/...gunzip \
+					 *    ?options...?
+					 *	-> handleCmd */
+	return ZlibStreamSubcmd(interp, objc, objv);
+    case CMD_PUSH:			/* push mode channel options...
+					 *	-> channel */
+	return ZlibPushSubcmd(interp, objc, objv);
+    };
+
+    return TCL_ERROR;
+
+  badLevel:
+    Tcl_SetObjResult(interp, Tcl_NewStringObj("level must be 0 to 9", -1));
+    Tcl_SetErrorCode(interp, "TCL", "VALUE", "COMPRESSIONLEVEL", NULL);
+    if (extraInfoStr) {
+	Tcl_AddErrorInfo(interp, extraInfoStr);
+    }
+    return TCL_ERROR;
+  badBuffer:
+    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+	    "buffer size must be %d to %d",
+	    MIN_NONSTREAM_BUFFER_SIZE, MAX_BUFFER_SIZE));
+    Tcl_SetErrorCode(interp, "TCL", "VALUE", "BUFFERSIZE", NULL);
+    return TCL_ERROR;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ZlibStreamSubcmd --
+ *
+ *	Implementation of the [zlib stream] subcommand.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+ZlibStreamSubcmd(
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const objv[])
+{
+    static const char *const stream_formats[] = {
+	"compress", "decompress", "deflate", "gunzip", "gzip", "inflate",
+	NULL
+    };
+    enum zlibFormats {
+	FMT_COMPRESS, FMT_DECOMPRESS, FMT_DEFLATE, FMT_GUNZIP, FMT_GZIP,
+	FMT_INFLATE
+    };
+    int i, format, mode = 0, option, level;
+    enum objIndices {
+	OPT_COMPRESSION_DICTIONARY = 0,
+	OPT_GZIP_HEADER = 1,
+	OPT_COMPRESSION_LEVEL = 2,
+	OPT_END = -1
+    };
+    Tcl_Obj *obj[3] = { NULL, NULL, NULL };
+#define compDictObj	obj[OPT_COMPRESSION_DICTIONARY]
+#define gzipHeaderObj	obj[OPT_GZIP_HEADER]
+#define levelObj	obj[OPT_COMPRESSION_LEVEL]
+    typedef struct {
+	const char *name;
+	enum objIndices offset;
+    } OptDescriptor;
+    static const OptDescriptor compressionOpts[] = {
+	{ "-dictionary", OPT_COMPRESSION_DICTIONARY },
+	{ "-level",	 OPT_COMPRESSION_LEVEL },
+	{ NULL, OPT_END }
+    };
+    static const OptDescriptor gzipOpts[] = {
+	{ "-header",	 OPT_GZIP_HEADER },
+	{ "-level",	 OPT_COMPRESSION_LEVEL },
+	{ NULL, OPT_END }
+    };
+    static const OptDescriptor expansionOpts[] = {
+	{ "-dictionary", OPT_COMPRESSION_DICTIONARY },
+	{ NULL, OPT_END }
+    };
+    static const OptDescriptor gunzipOpts[] = {
+	{ NULL, OPT_END }
+    };
+    const OptDescriptor *desc = NULL;
+    Tcl_ZlibStream zh;
+
+    if (objc < 3 || !(objc & 1)) {
+	Tcl_WrongNumArgs(interp, 2, objv, "mode ?-option value...?");
+	return TCL_ERROR;
+    }
+    if (Tcl_GetIndexFromObj(interp, objv[2], stream_formats, "mode", 0,
+	    &format) != TCL_OK) {
+	return TCL_ERROR;
+    }
+
+    /*
+     * The format determines the compression mode and the options that may be
+     * specified.
+     */
+
+    switch ((enum zlibFormats) format) {
+    case FMT_DEFLATE:
+	desc = compressionOpts;
+	mode = TCL_ZLIB_STREAM_DEFLATE;
+	format = TCL_ZLIB_FORMAT_RAW;
+	break;
+    case FMT_INFLATE:
+	desc = expansionOpts;
+	mode = TCL_ZLIB_STREAM_INFLATE;
+	format = TCL_ZLIB_FORMAT_RAW;
+	break;
+    case FMT_COMPRESS:
+	desc = compressionOpts;
+	mode = TCL_ZLIB_STREAM_DEFLATE;
+	format = TCL_ZLIB_FORMAT_ZLIB;
+	break;
+    case FMT_DECOMPRESS:
+	desc = expansionOpts;
+	mode = TCL_ZLIB_STREAM_INFLATE;
+	format = TCL_ZLIB_FORMAT_ZLIB;
+	break;
+    case FMT_GZIP:
+	desc = gzipOpts;
+	mode = TCL_ZLIB_STREAM_DEFLATE;
+	format = TCL_ZLIB_FORMAT_GZIP;
+	break;
+    case FMT_GUNZIP:
+	desc = gunzipOpts;
+	mode = TCL_ZLIB_STREAM_INFLATE;
+	format = TCL_ZLIB_FORMAT_GZIP;
+	break;
+    default:
+	Tcl_Panic("should be unreachable");
+    }
+
+    /*
+     * Parse the options.
+     */
+
+    for (i=3 ; i<objc ; i+=2) {
+	if (Tcl_GetIndexFromObjStruct(interp, objv[i], desc,
+		sizeof(OptDescriptor), "option", 0, &option) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	obj[desc[option].offset] = objv[i+1];
+    }
+
+    /*
+     * If a compression level was given, parse it (integral: 0..9). Otherwise
+     * use the default.
+     */
+
+    if (levelObj == NULL) {
+	level = Z_DEFAULT_COMPRESSION;
+    } else if (Tcl_GetIntFromObj(interp, levelObj, &level) != TCL_OK) {
+	return TCL_ERROR;
+    } else if (level < 0 || level > 9) {
+	Tcl_SetObjResult(interp, Tcl_NewStringObj("level must be 0 to 9",-1));
+	Tcl_SetErrorCode(interp, "TCL", "VALUE", "COMPRESSIONLEVEL", NULL);
+	Tcl_AddErrorInfo(interp, "\n    (in -level option)");
+	return TCL_ERROR;
+    }
+
+    /*
+     * Construct the stream now we know its configuration.
+     */
+
+    if (Tcl_ZlibStreamInit(interp, mode, format, level, gzipHeaderObj,
+	    &zh) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    if (compDictObj != NULL) {
+	Tcl_ZlibStreamSetCompressionDictionary(zh, compDictObj);
+    }
+    Tcl_SetObjResult(interp, Tcl_ZlibStreamGetCommandName(zh));
+    return TCL_OK;
+#undef compDictObj
+#undef gzipHeaderObj
+#undef levelObj
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ZlibPushSubcmd --
+ *
+ *	Implementation of the [zlib push] subcommand.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+ZlibPushSubcmd(
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const objv[])
+{
+    static const char *const stream_formats[] = {
+	"compress", "decompress", "deflate", "gunzip", "gzip", "inflate",
+	NULL
+    };
+    enum zlibFormats {
+	FMT_COMPRESS, FMT_DECOMPRESS, FMT_DEFLATE, FMT_GUNZIP, FMT_GZIP,
+	FMT_INFLATE
+    };
+    Tcl_Channel chan;
+    int chanMode, format, mode = 0, level, i, option;
+    static const char *const pushCompressOptions[] = {
+	"-dictionary", "-header", "-level", NULL
+    };
+    static const char *const pushDecompressOptions[] = {
+	"-dictionary", "-header", "-level", "-limit", NULL
+    };
+    const char *const *pushOptions = pushDecompressOptions;
+    enum pushOptions {poDictionary, poHeader, poLevel, poLimit};
+    Tcl_Obj *headerObj = NULL, *compDictObj = NULL;
+    int limit = 1, dummy;
+
+    if (objc < 4) {
+	Tcl_WrongNumArgs(interp, 2, objv, "mode channel ?options...?");
+	return TCL_ERROR;
+    }
+
+    if (Tcl_GetIndexFromObj(interp, objv[2], stream_formats, "mode", 0,
+	    &format) != TCL_OK) {
+	return TCL_ERROR;
+    }
+    switch ((enum zlibFormats) format) {
+    case FMT_DEFLATE:
+	mode = TCL_ZLIB_STREAM_DEFLATE;
+	format = TCL_ZLIB_FORMAT_RAW;
+	pushOptions = pushCompressOptions;
+	break;
+    case FMT_INFLATE:
+	mode = TCL_ZLIB_STREAM_INFLATE;
+	format = TCL_ZLIB_FORMAT_RAW;
+	break;
+    case FMT_COMPRESS:
+	mode = TCL_ZLIB_STREAM_DEFLATE;
+	format = TCL_ZLIB_FORMAT_ZLIB;
+	pushOptions = pushCompressOptions;
+	break;
+    case FMT_DECOMPRESS:
+	mode = TCL_ZLIB_STREAM_INFLATE;
+	format = TCL_ZLIB_FORMAT_ZLIB;
+	break;
+    case FMT_GZIP:
+	mode = TCL_ZLIB_STREAM_DEFLATE;
+	format = TCL_ZLIB_FORMAT_GZIP;
+	pushOptions = pushCompressOptions;
+	break;
+    case FMT_GUNZIP:
+	mode = TCL_ZLIB_STREAM_INFLATE;
+	format = TCL_ZLIB_FORMAT_GZIP;
+	break;
+    default:
+	Tcl_Panic("should be unreachable");
+    }
+
+    if (TclGetChannelFromObj(interp, objv[3], &chan, &chanMode, 0) != TCL_OK){
+	return TCL_ERROR;
+    }
+
+    /*
+     * Sanity checks.
+     */
+
+    if (mode == TCL_ZLIB_STREAM_DEFLATE && !(chanMode & TCL_WRITABLE)) {
+	Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		"compression may only be applied to writable channels", -1));
+	Tcl_SetErrorCode(interp, "TCL", "ZIP", "UNWRITABLE", NULL);
+	return TCL_ERROR;
+    }
+    if (mode == TCL_ZLIB_STREAM_INFLATE && !(chanMode & TCL_READABLE)) {
+	Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		"decompression may only be applied to readable channels",-1));
+	Tcl_SetErrorCode(interp, "TCL", "ZIP", "UNREADABLE", NULL);
+	return TCL_ERROR;
+    }
+
+    /*
+     * Parse options.
+     */
+
+    level = Z_DEFAULT_COMPRESSION;
+    for (i=4 ; i<objc ; i++) {
+	if (Tcl_GetIndexFromObj(interp, objv[i], pushOptions, "option", 0,
+		&option) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+	if (++i > objc-1) {
+	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		    "value missing for %s option", pushOptions[option]));
+	    Tcl_SetErrorCode(interp, "TCL", "ZIP", "NOVAL", NULL);
+	    return TCL_ERROR;
+	}
+	switch ((enum pushOptions) option) {
+	case poHeader:
+	    headerObj = objv[i];
+	    if (Tcl_DictObjSize(interp, headerObj, &dummy) != TCL_OK) {
+		goto genericOptionError;
+	    }
+	    break;
+	case poLevel:
+	    if (Tcl_GetIntFromObj(interp, objv[i], (int*) &level) != TCL_OK) {
+		goto genericOptionError;
+	    }
+	    if (level < 0 || level > 9) {
+		Tcl_SetObjResult(interp, Tcl_NewStringObj(
+			"level must be 0 to 9", -1));
+		Tcl_SetErrorCode(interp, "TCL", "VALUE", "COMPRESSIONLEVEL",
+			NULL);
+		goto genericOptionError;
+	    }
+	    break;
+	case poLimit:
+	    if (Tcl_GetIntFromObj(interp, objv[i], (int*) &limit) != TCL_OK) {
+		goto genericOptionError;
+	    }
+	    if (limit < 1 || limit > MAX_BUFFER_SIZE) {
+		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+			"read ahead limit must be 1 to %d",
+			MAX_BUFFER_SIZE));
+		Tcl_SetErrorCode(interp, "TCL", "VALUE", "BUFFERSIZE", NULL);
+		goto genericOptionError;
+	    }
+	    break;
+	case poDictionary:
+	    if (format == TCL_ZLIB_FORMAT_GZIP) {
+		Tcl_SetObjResult(interp, Tcl_NewStringObj(
+			"a compression dictionary may not be set in the "
+			"gzip format", -1));
+		Tcl_SetErrorCode(interp, "TCL", "ZIP", "BADOPT", NULL);
+		goto genericOptionError;
+	    }
+	    compDictObj = objv[i];
+	    break;
+	}
+    }
+
+    if (ZlibStackChannelTransform(interp, mode, format, level, limit, chan,
+	    headerObj, compDictObj) == NULL) {
+	return TCL_ERROR;
+    }
+    Tcl_SetObjResult(interp, objv[3]);
+    return TCL_OK;
+
+  genericOptionError:
+    Tcl_AddErrorInfo(interp, "\n    (in ");
+    Tcl_AddErrorInfo(interp, pushOptions[option]);
+    Tcl_AddErrorInfo(interp, " option)");
+    return TCL_ERROR;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ZlibStreamCmd --
+ *
+ *	Implementation of the commands returned by [zlib stream].
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+ZlibStreamCmd(
+    ClientData cd,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const objv[])
+{
+    Tcl_ZlibStream zstream = cd;
+    int command, count, code;
+    Tcl_Obj *obj;
+    static const char *const cmds[] = {
+	"add", "checksum", "close", "eof", "finalize", "flush",
+	"fullflush", "get", "header", "put", "reset",
+	NULL
+    };
+    enum zlibStreamCommands {
+	zs_add, zs_checksum, zs_close, zs_eof, zs_finalize, zs_flush,
+	zs_fullflush, zs_get, zs_header, zs_put, zs_reset
+    };
+
+    if (objc < 2) {
+	Tcl_WrongNumArgs(interp, 1, objv, "option data ?...?");
+	return TCL_ERROR;
+    }
+
+    if (Tcl_GetIndexFromObj(interp, objv[1], cmds, "option", 0,
+	    &command) != TCL_OK) {
+	return TCL_ERROR;
+    }
+
+    switch ((enum zlibStreamCommands) command) {
+    case zs_add:		/* $strm add ?$flushopt? $data */
+	return ZlibStreamAddCmd(zstream, interp, objc, objv);
+    case zs_header:		/* $strm header */
+	return ZlibStreamHeaderCmd(zstream, interp, objc, objv);
+    case zs_put:		/* $strm put ?$flushopt? $data */
+	return ZlibStreamPutCmd(zstream, interp, objc, objv);
+
+    case zs_get:		/* $strm get ?count? */
+	if (objc > 3) {
+	    Tcl_WrongNumArgs(interp, 2, objv, "?count?");
+	    return TCL_ERROR;
+	}
+
+	count = -1;
+	if (objc >= 3) {
+	    if (Tcl_GetIntFromObj(interp, objv[2], &count) != TCL_OK) {
+		return TCL_ERROR;
+	    }
+	}
+	TclNewObj(obj);
+	code = Tcl_ZlibStreamGet(zstream, obj, count);
+	if (code == TCL_OK) {
+	    Tcl_SetObjResult(interp, obj);
+	} else {
+	    TclDecrRefCount(obj);
+	}
+	return code;
+    case zs_flush:		/* $strm flush */
+	if (objc != 2) {
+	    Tcl_WrongNumArgs(interp, 2, objv, NULL);
+	    return TCL_ERROR;
+	}
+	TclNewObj(obj);
+	Tcl_IncrRefCount(obj);
+	code = Tcl_ZlibStreamPut(zstream, obj, Z_SYNC_FLUSH);
+	TclDecrRefCount(obj);
+	return code;
+    case zs_fullflush:		/* $strm fullflush */
+	if (objc != 2) {
+	    Tcl_WrongNumArgs(interp, 2, objv, NULL);
+	    return TCL_ERROR;
+	}
+	TclNewObj(obj);
+	Tcl_IncrRefCount(obj);
+	code = Tcl_ZlibStreamPut(zstream, obj, Z_FULL_FLUSH);
+	TclDecrRefCount(obj);
+	return code;
+    case zs_finalize:		/* $strm finalize */
+	if (objc != 2) {
+	    Tcl_WrongNumArgs(interp, 2, objv, NULL);
+	    return TCL_ERROR;
+	}
+
+	/*
+	 * The flush commands slightly abuse the empty result obj as input
+	 * data.
+	 */
+
+	TclNewObj(obj);
+	Tcl_IncrRefCount(obj);
+	code = Tcl_ZlibStreamPut(zstream, obj, Z_FINISH);
+	TclDecrRefCount(obj);
+	return code;
+    case zs_close:		/* $strm close */
+	if (objc != 2) {
+	    Tcl_WrongNumArgs(interp, 2, objv, NULL);
+	    return TCL_ERROR;
+	}
+	return Tcl_ZlibStreamClose(zstream);
+    case zs_eof:		/* $strm eof */
+	if (objc != 2) {
+	    Tcl_WrongNumArgs(interp, 2, objv, NULL);
+	    return TCL_ERROR;
+	}
+	Tcl_SetObjResult(interp, Tcl_NewIntObj(Tcl_ZlibStreamEof(zstream)));
+	return TCL_OK;
+    case zs_checksum:		/* $strm checksum */
+	if (objc != 2) {
+	    Tcl_WrongNumArgs(interp, 2, objv, NULL);
+	    return TCL_ERROR;
+	}
+	Tcl_SetObjResult(interp, Tcl_NewWideIntObj((Tcl_WideInt)
+		(uLong) Tcl_ZlibStreamChecksum(zstream)));
+	return TCL_OK;
+    case zs_reset:		/* $strm reset */
+	if (objc != 2) {
+	    Tcl_WrongNumArgs(interp, 2, objv, NULL);
+	    return TCL_ERROR;
+	}
+	return Tcl_ZlibStreamReset(zstream);
+    }
+
+    return TCL_OK;
+}
+
+static int
+ZlibStreamAddCmd(
+    ClientData cd,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const objv[])
+{
+    Tcl_ZlibStream zstream = cd;
+    int index, code, buffersize = -1, flush = -1, i;
+    Tcl_Obj *obj, *compDictObj = NULL;
+    static const char *const add_options[] = {
+	"-buffer", "-dictionary", "-finalize", "-flush", "-fullflush", NULL
+    };
+    enum addOptions {
+	ao_buffer, ao_dictionary, ao_finalize, ao_flush, ao_fullflush
+    };
+
+    for (i=2; i<objc-1; i++) {
+	if (Tcl_GetIndexFromObj(interp, objv[i], add_options, "option", 0,
+		&index) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+
+	switch ((enum addOptions) index) {
+	case ao_flush: /* -flush */
+	    if (flush > -1) {
+		flush = -2;
+	    } else {
+		flush = Z_SYNC_FLUSH;
+	    }
+	    break;
+	case ao_fullflush: /* -fullflush */
+	    if (flush > -1) {
+		flush = -2;
+	    } else {
+		flush = Z_FULL_FLUSH;
+	    }
+	    break;
+	case ao_finalize: /* -finalize */
+	    if (flush > -1) {
+		flush = -2;
+	    } else {
+		flush = Z_FINISH;
+	    }
+	    break;
+	case ao_buffer: /* -buffer */
+	    if (i == objc-2) {
+		Tcl_SetObjResult(interp, Tcl_NewStringObj(
+			"\"-buffer\" option must be followed by integer "
+			"decompression buffersize", -1));
+		Tcl_SetErrorCode(interp, "TCL", "ZIP", "NOVAL", NULL);
+		return TCL_ERROR;
+	    }
+	    if (Tcl_GetIntFromObj(interp, objv[++i], &buffersize) != TCL_OK) {
+		return TCL_ERROR;
+	    }
+	    if (buffersize < 1 || buffersize > MAX_BUFFER_SIZE) {
+		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+			"buffer size must be 1 to %d",
+			MAX_BUFFER_SIZE));
+		Tcl_SetErrorCode(interp, "TCL", "VALUE", "BUFFERSIZE", NULL);
+		return TCL_ERROR;
+	    }
+	    break;
+	case ao_dictionary:
+	    if (i == objc-2) {
+		Tcl_SetObjResult(interp, Tcl_NewStringObj(
+			"\"-dictionary\" option must be followed by"
+			" compression dictionary bytes", -1));
+		Tcl_SetErrorCode(interp, "TCL", "ZIP", "NOVAL", NULL);
+		return TCL_ERROR;
+	    }
+	    compDictObj = objv[++i];
+	    break;
+	}
+
+	if (flush == -2) {
+	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		    "\"-flush\", \"-fullflush\" and \"-finalize\" options"
+		    " are mutually exclusive", -1));
+	    Tcl_SetErrorCode(interp, "TCL", "ZIP", "EXCLUSIVE", NULL);
+	    return TCL_ERROR;
+	}
+    }
+    if (flush == -1) {
+	flush = 0;
+    }
+
+    /*
+     * Set the compression dictionary if requested.
+     */
+
+    if (compDictObj != NULL) {
+	int len;
+
+	(void) Tcl_GetByteArrayFromObj(compDictObj, &len);
+	if (len == 0) {
+	    compDictObj = NULL;
+	}
+	Tcl_ZlibStreamSetCompressionDictionary(zstream, compDictObj);
+    }
+
+    /*
+     * Send the data to the stream core, along with any flushing directive.
+     */
+
+    if (Tcl_ZlibStreamPut(zstream, objv[objc-1], flush) != TCL_OK) {
+	return TCL_ERROR;
+    }
+
+    /*
+     * Get such data out as we can (up to the requested length).
+     */
+
+    TclNewObj(obj);
+    code = Tcl_ZlibStreamGet(zstream, obj, buffersize);
+    if (code == TCL_OK) {
+	Tcl_SetObjResult(interp, obj);
+    } else {
+	TclDecrRefCount(obj);
+    }
+    return code;
+}
+
+static int
+ZlibStreamPutCmd(
+    ClientData cd,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const objv[])
+{
+    Tcl_ZlibStream zstream = cd;
+    int index, flush = -1, i;
+    Tcl_Obj *compDictObj = NULL;
+    static const char *const put_options[] = {
+	"-dictionary", "-finalize", "-flush", "-fullflush", NULL
+    };
+    enum putOptions {
+	po_dictionary, po_finalize, po_flush, po_fullflush
+    };
+
+    for (i=2; i<objc-1; i++) {
+	if (Tcl_GetIndexFromObj(interp, objv[i], put_options, "option", 0,
+		&index) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+
+	switch ((enum putOptions) index) {
+	case po_flush: /* -flush */
+	    if (flush > -1) {
+		flush = -2;
+	    } else {
+		flush = Z_SYNC_FLUSH;
+	    }
+	    break;
+	case po_fullflush: /* -fullflush */
+	    if (flush > -1) {
+		flush = -2;
+	    } else {
+		flush = Z_FULL_FLUSH;
+	    }
+	    break;
+	case po_finalize: /* -finalize */
+	    if (flush > -1) {
+		flush = -2;
+	    } else {
+		flush = Z_FINISH;
+	    }
+	    break;
+	case po_dictionary:
+	    if (i == objc-2) {
+		Tcl_SetObjResult(interp, Tcl_NewStringObj(
+			"\"-dictionary\" option must be followed by"
+			" compression dictionary bytes", -1));
+		Tcl_SetErrorCode(interp, "TCL", "ZIP", "NOVAL", NULL);
+		return TCL_ERROR;
+	    }
+	    compDictObj = objv[++i];
+	    break;
+	}
+	if (flush == -2) {
+	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		    "\"-flush\", \"-fullflush\" and \"-finalize\" options"
+		    " are mutually exclusive", -1));
+	    Tcl_SetErrorCode(interp, "TCL", "ZIP", "EXCLUSIVE", NULL);
+	    return TCL_ERROR;
+	}
+    }
+    if (flush == -1) {
+	flush = 0;
+    }
+
+    /*
+     * Set the compression dictionary if requested.
+     */
+
+    if (compDictObj != NULL) {
+	int len;
+
+	(void) Tcl_GetByteArrayFromObj(compDictObj, &len);
+	if (len == 0) {
+	    compDictObj = NULL;
+	}
+	Tcl_ZlibStreamSetCompressionDictionary(zstream, compDictObj);
+    }
+
+    /*
+     * Send the data to the stream core, along with any flushing directive.
+     */
+
+    return Tcl_ZlibStreamPut(zstream, objv[objc-1], flush);
+}
+
+static int
+ZlibStreamHeaderCmd(
+    ClientData cd,
+    Tcl_Interp *interp,
+    int objc,
+    Tcl_Obj *const objv[])
+{
+    ZlibStreamHandle *zshPtr = cd;
+    Tcl_Obj *resultObj;
+
+    if (objc != 2) {
+	Tcl_WrongNumArgs(interp, 2, objv, NULL);
+	return TCL_ERROR;
+    } else if (zshPtr->mode != TCL_ZLIB_STREAM_INFLATE
+	    || zshPtr->format != TCL_ZLIB_FORMAT_GZIP) {
+	Tcl_SetObjResult(interp, Tcl_NewStringObj(
+		"only gunzip streams can produce header information", -1));
+	Tcl_SetErrorCode(interp, "TCL", "ZIP", "BADOP", NULL);
+	return TCL_ERROR;
+    }
+
+    TclNewObj(resultObj);
+    ExtractHeader(&zshPtr->gzHeaderPtr->header, resultObj);
+    Tcl_SetObjResult(interp, resultObj);
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *	Set of functions to support channel stacking.
+ *----------------------------------------------------------------------
+ *
+ * ZlibTransformClose --
+ *
+ *	How to shut down a stacked compressing/decompressing transform.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+ZlibTransformClose(
+    ClientData instanceData,
+    Tcl_Interp *interp)
+{
+    ZlibChannelData *cd = instanceData;
+    int e, result = TCL_OK;
+
+    /*
+     * Delete the support timer.
+     */
+
+    ZlibTransformEventTimerKill(cd);
+
+    /*
+     * Flush any data waiting to be compressed.
+     */
+
+    if (cd->mode == TCL_ZLIB_STREAM_DEFLATE) {
+	cd->outStream.avail_in = 0;
+	do {
+	    cd->outStream.next_out = (Bytef *) cd->outBuffer;
+	    cd->outStream.avail_out = (unsigned) cd->outAllocated;
+	    e = deflate(&cd->outStream, Z_FINISH);
+	    if (e != Z_OK && e != Z_STREAM_END) {
+		/* TODO: is this the right way to do errors on close? */
+		if (!TclInThreadExit()) {
+		    ConvertError(interp, e, cd->outStream.adler);
+		}
+		result = TCL_ERROR;
+		break;
+	    }
+	    if (cd->outStream.avail_out != (unsigned) cd->outAllocated) {
+		if (Tcl_WriteRaw(cd->parent, cd->outBuffer,
+			cd->outAllocated - cd->outStream.avail_out) < 0) {
+		    /* TODO: is this the right way to do errors on close?
+		     * Note: when close is called from FinalizeIOSubsystem
+		     * then interp may be NULL */
+		    if (!TclInThreadExit() && interp) {
+			Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+				"error while finalizing file: %s",
+				Tcl_PosixError(interp)));
+		    }
+		    result = TCL_ERROR;
+		    break;
+		}
+	    }
+	} while (e != Z_STREAM_END);
+	(void) deflateEnd(&cd->outStream);
+    } else {
+	(void) inflateEnd(&cd->inStream);
+    }
+
+    /*
+     * Release all memory.
+     */
+
+    if (cd->compDictObj) {
+	Tcl_DecrRefCount(cd->compDictObj);
+	cd->compDictObj = NULL;
+    }
+    Tcl_DStringFree(&cd->decompressed);
+
+    if (cd->inBuffer) {
+	ckfree(cd->inBuffer);
+	cd->inBuffer = NULL;
+    }
+    if (cd->outBuffer) {
+	ckfree(cd->outBuffer);
+	cd->outBuffer = NULL;
+    }
+    ckfree(cd);
+    return result;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ZlibTransformInput --
+ *
+ *	Reader filter that does decompression.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+ZlibTransformInput(
+    ClientData instanceData,
+    char *buf,
+    int toRead,
+    int *errorCodePtr)
+{
+    ZlibChannelData *cd = instanceData;
+    Tcl_DriverInputProc *inProc =
+	    Tcl_ChannelInputProc(Tcl_GetChannelType(cd->parent));
+    int readBytes, gotBytes, copied;
+
+    if (cd->mode == TCL_ZLIB_STREAM_DEFLATE) {
+	return inProc(Tcl_GetChannelInstanceData(cd->parent), buf, toRead,
+		errorCodePtr);
+    }
+
+    gotBytes = 0;
+    while (toRead > 0) {
+	/*
+	 * Loop until the request is satisfied (or no data available from
+	 * below, possibly EOF).
+	 */
+
+	copied = ResultCopy(cd, buf, toRead);
+	toRead -= copied;
+	buf += copied;
+	gotBytes += copied;
+
+	if (toRead == 0) {
+	    return gotBytes;
+	}
+
+	/*
+	 * The buffer is exhausted, but the caller wants even more. We now
+	 * have to go to the underlying channel, get more bytes and then
+	 * transform them for delivery. We may not get what we want (full EOF
+	 * or temporarily out of data).
+	 *
+	 * Length (cd->decompressed) == 0, toRead > 0 here.
+	 *
+	 * The zlib transform allows us to read at most one character from the
+	 * underlying channel to properly identify Z_STREAM_END without
+	 * reading over the border.
+	 */
+
+	readBytes = Tcl_ReadRaw(cd->parent, cd->inBuffer, cd->readAheadLimit);
+
+	/*
+	 * Three cases here:
+	 *  1.	Got some data from the underlying channel (readBytes > 0) so
+	 *	it should be fed through the decompression engine.
+	 *  2.	Got an error (readBytes < 0) which we should report up except
+	 *	for the case where we can convert it to a short read.
+	 *  3.	Got an end-of-data from EOF or blocking (readBytes == 0). If
+	 *	it is EOF, try flushing the data out of the decompressor.
+	 */
+
+	if (readBytes < 0) {
+
+	    /* See ReflectInput() in tclIORTrans.c */
+	    if (Tcl_InputBlocked(cd->parent) && (gotBytes > 0)) {
+		return gotBytes;
+	    }
+
+	    *errorCodePtr = Tcl_GetErrno();
+	    return -1;
+	}
+	if (readBytes == 0) {
+	    /*
+	     * Eof in parent.
+	     *
+	     * Now this is a bit different. The partial data waiting is
+	     * converted and returned.
+	     */
+
+	    if (ResultGenerate(cd, 0, Z_SYNC_FLUSH, errorCodePtr) != TCL_OK) {
+		return -1;
+	    }
+
+	    if (Tcl_DStringLength(&cd->decompressed) == 0) {
+		/*
+		 * The drain delivered nothing. Time to deliver what we've
+		 * got.
+		 */
+
+		return gotBytes;
+	    }
+	} else /* readBytes > 0 */ {
+	    /*
+	     * Transform the read chunk, which was not empty. Anything we get
+	     * back is a transformation result to be put into our buffers, and
+	     * the next iteration will put it into the result.
+	     */
+
+	    if (ResultGenerate(cd, readBytes, Z_NO_FLUSH,
+		    errorCodePtr) != TCL_OK) {
+		return -1;
+	    }
+	}
+    }
+    return gotBytes;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ZlibTransformOutput --
+ *
+ *	Writer filter that does compression.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+ZlibTransformOutput(
+    ClientData instanceData,
+    const char *buf,
+    int toWrite,
+    int *errorCodePtr)
+{
+    ZlibChannelData *cd = instanceData;
+    Tcl_DriverOutputProc *outProc =
+	    Tcl_ChannelOutputProc(Tcl_GetChannelType(cd->parent));
+    int e, produced;
+    Tcl_Obj *errObj;
+
+    if (cd->mode == TCL_ZLIB_STREAM_INFLATE) {
+	return outProc(Tcl_GetChannelInstanceData(cd->parent), buf, toWrite,
+		errorCodePtr);
+    }
+
+    cd->outStream.next_in = (Bytef *) buf;
+    cd->outStream.avail_in = toWrite;
+    do {
+	cd->outStream.next_out = (Bytef *) cd->outBuffer;
+	cd->outStream.avail_out = cd->outAllocated;
+
+	e = deflate(&cd->outStream, Z_NO_FLUSH);
+	produced = cd->outAllocated - cd->outStream.avail_out;
+
+	if (e == Z_OK && produced > 0) {
+	    if (Tcl_WriteRaw(cd->parent, cd->outBuffer, produced) < 0) {
+		*errorCodePtr = Tcl_GetErrno();
+		return -1;
+	    }
+	}
+    } while (e == Z_OK && produced > 0 && cd->outStream.avail_in > 0);
+
+    if (e == Z_OK) {
+	return toWrite - cd->outStream.avail_in;
+    }
+
+    errObj = Tcl_NewListObj(0, NULL);
+    Tcl_ListObjAppendElement(NULL, errObj, Tcl_NewStringObj("-errorcode",-1));
+    Tcl_ListObjAppendElement(NULL, errObj,
+	    ConvertErrorToList(e, cd->outStream.adler));
+    Tcl_ListObjAppendElement(NULL, errObj,
+	    Tcl_NewStringObj(cd->outStream.msg, -1));
+    Tcl_SetChannelError(cd->parent, errObj);
+    *errorCodePtr = EINVAL;
+    return -1;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ZlibTransformFlush --
+ *
+ *	How to perform a flush of a compressing transform.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+ZlibTransformFlush(
+    Tcl_Interp *interp,
+    ZlibChannelData *cd,
+    int flushType)
+{
+    int e, len;
+
+    cd->outStream.avail_in = 0;
+    do {
+	/*
+	 * Get the bytes to go out of the compression engine.
+	 */
+
+	cd->outStream.next_out = (Bytef *) cd->outBuffer;
+	cd->outStream.avail_out = cd->outAllocated;
+
+	e = deflate(&cd->outStream, flushType);
+	if (e != Z_OK && e != Z_BUF_ERROR) {
+	    ConvertError(interp, e, cd->outStream.adler);
+	    return TCL_ERROR;
+	}
+
+	/*
+	 * Write the bytes we've received to the next layer.
+	 */
+
+	len = cd->outStream.next_out - (Bytef *) cd->outBuffer;
+	if (len > 0 && Tcl_WriteRaw(cd->parent, cd->outBuffer, len) < 0) {
+	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		    "problem flushing channel: %s",
+		    Tcl_PosixError(interp)));
+	    return TCL_ERROR;
+	}
+
+	/*
+	 * If we get to this point, either we're in the Z_OK or the
+	 * Z_BUF_ERROR state. In the former case, we're done. In the latter
+	 * case, it's because there's more bytes to go than would fit in the
+	 * buffer we provided, and we need to go round again to get some more.
+	 *
+	 * We also stop the loop if we would have done a zero-length write.
+	 * Those can cause problems at the OS level.
+	 */
+    } while (len > 0 && e == Z_BUF_ERROR);
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ZlibTransformSetOption --
+ *
+ *	Writing side of [fconfigure] on our channel.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+ZlibTransformSetOption(			/* not used */
+    ClientData instanceData,
+    Tcl_Interp *interp,
+    const char *optionName,
+    const char *value)
+{
+    ZlibChannelData *cd = instanceData;
+    Tcl_DriverSetOptionProc *setOptionProc =
+	    Tcl_ChannelSetOptionProc(Tcl_GetChannelType(cd->parent));
+    static const char *compressChanOptions = "dictionary flush";
+    static const char *gzipChanOptions = "flush";
+    static const char *decompressChanOptions = "dictionary limit";
+    static const char *gunzipChanOptions = "flush limit";
+    int haveFlushOpt = (cd->mode == TCL_ZLIB_STREAM_DEFLATE);
+
+    if (optionName && (strcmp(optionName, "-dictionary") == 0)
+	    && (cd->format != TCL_ZLIB_FORMAT_GZIP)) {
+	Tcl_Obj *compDictObj;
+	int code;
+
+	TclNewStringObj(compDictObj, value, strlen(value));
+	Tcl_IncrRefCount(compDictObj);
+	(void) Tcl_GetByteArrayFromObj(compDictObj, NULL);
+	if (cd->compDictObj) {
+	    TclDecrRefCount(cd->compDictObj);
+	}
+	cd->compDictObj = compDictObj;
+	code = Z_OK;
+	if (cd->mode == TCL_ZLIB_STREAM_DEFLATE) {
+	    code = SetDeflateDictionary(&cd->outStream, compDictObj);
+	    if (code != Z_OK) {
+		ConvertError(interp, code, cd->outStream.adler);
+		return TCL_ERROR;
+	    }
+	} else if (cd->format == TCL_ZLIB_FORMAT_RAW) {
+	    code = SetInflateDictionary(&cd->inStream, compDictObj);
+	    if (code != Z_OK) {
+		ConvertError(interp, code, cd->inStream.adler);
+		return TCL_ERROR;
+	    }
+	}
+	return TCL_OK;
+    }
+
+    if (haveFlushOpt) {
+	if (optionName && strcmp(optionName, "-flush") == 0) {
+	    int flushType;
+
+	    if (value[0] == 'f' && strcmp(value, "full") == 0) {
+		flushType = Z_FULL_FLUSH;
+	    } else if (value[0] == 's' && strcmp(value, "sync") == 0) {
+		flushType = Z_SYNC_FLUSH;
+	    } else {
+		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+			"unknown -flush type \"%s\": must be full or sync",
+			value));
+		Tcl_SetErrorCode(interp, "TCL", "VALUE", "FLUSH", NULL);
+		return TCL_ERROR;
+	    }
+
+	    /*
+	     * Try to actually do the flush now.
+	     */
+
+	    return ZlibTransformFlush(interp, cd, flushType);
+	}
+    } else {
+	if (optionName && strcmp(optionName, "-limit") == 0) {
+	    int newLimit;
+
+	    if (Tcl_GetInt(interp, value, &newLimit) != TCL_OK) {
+		return TCL_ERROR;
+	    } else if (newLimit < 1 || newLimit > MAX_BUFFER_SIZE) {
+		Tcl_SetObjResult(interp, Tcl_NewStringObj(
+			"-limit must be between 1 and 65536", -1));
+		Tcl_SetErrorCode(interp, "TCL", "VALUE", "READLIMIT", NULL);
+		return TCL_ERROR;
+	    }
+	}
+    }
+
+    if (setOptionProc == NULL) {
+	if (cd->format == TCL_ZLIB_FORMAT_GZIP) {
+	    return Tcl_BadChannelOption(interp, optionName,
+		    (cd->mode == TCL_ZLIB_STREAM_DEFLATE)
+		    ? gzipChanOptions : gunzipChanOptions);
+	} else {
+	    return Tcl_BadChannelOption(interp, optionName,
+		    (cd->mode == TCL_ZLIB_STREAM_DEFLATE)
+		    ? compressChanOptions : decompressChanOptions);
+	}
+    }
+
+    /*
+     * Pass all unknown options down, to deeper transforms and/or the base
+     * channel.
+     */
+
+    return setOptionProc(Tcl_GetChannelInstanceData(cd->parent), interp,
+	    optionName, value);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ZlibTransformGetOption --
+ *
+ *	Reading side of [fconfigure] on our channel.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+ZlibTransformGetOption(
+    ClientData instanceData,
+    Tcl_Interp *interp,
+    const char *optionName,
+    Tcl_DString *dsPtr)
+{
+    ZlibChannelData *cd = instanceData;
+    Tcl_DriverGetOptionProc *getOptionProc =
+	    Tcl_ChannelGetOptionProc(Tcl_GetChannelType(cd->parent));
+    static const char *compressChanOptions = "checksum dictionary";
+    static const char *gzipChanOptions = "checksum";
+    static const char *decompressChanOptions = "checksum dictionary limit";
+    static const char *gunzipChanOptions = "checksum header limit";
+
+    /*
+     * The "crc" option reports the current CRC (calculated with the Adler32
+     * or CRC32 algorithm according to the format) given the data that has
+     * been processed so far.
+     */
+
+    if (optionName == NULL || strcmp(optionName, "-checksum") == 0) {
+	uLong crc;
+	char buf[12];
+
+	if (cd->mode == TCL_ZLIB_STREAM_DEFLATE) {
+	    crc = cd->outStream.adler;
+	} else {
+	    crc = cd->inStream.adler;
+	}
+
+	sprintf(buf, "%lu", crc);
+	if (optionName == NULL) {
+	    Tcl_DStringAppendElement(dsPtr, "-checksum");
+	    Tcl_DStringAppendElement(dsPtr, buf);
+	} else {
+	    Tcl_DStringAppend(dsPtr, buf, -1);
+	    return TCL_OK;
+	}
+    }
+
+    if ((cd->format != TCL_ZLIB_FORMAT_GZIP) &&
+	    (optionName == NULL || strcmp(optionName, "-dictionary") == 0)) {
+	/*
+	 * Embedded NUL bytes are ok; they'll be C080-encoded.
+	 */
+
+	if (optionName == NULL) {
+	    Tcl_DStringAppendElement(dsPtr, "-dictionary");
+	    if (cd->compDictObj) {
+		Tcl_DStringAppendElement(dsPtr,
+			Tcl_GetString(cd->compDictObj));
+	    } else {
+		Tcl_DStringAppendElement(dsPtr, "");
+	    }
+	} else {
+	    if (cd->compDictObj) {
+		int len;
+		const char *str = Tcl_GetStringFromObj(cd->compDictObj, &len);
+
+		Tcl_DStringAppend(dsPtr, str, len);
+	    }
+	    return TCL_OK;
+	}
+    }
+
+    /*
+     * The "header" option, which is only valid on inflating gzip channels,
+     * reports the header that has been read from the start of the stream.
+     */
+
+    if ((cd->flags & IN_HEADER) && ((optionName == NULL) ||
+	    (strcmp(optionName, "-header") == 0))) {
+	Tcl_Obj *tmpObj = Tcl_NewObj();
+
+	ExtractHeader(&cd->inHeader.header, tmpObj);
+	if (optionName == NULL) {
+	    Tcl_DStringAppendElement(dsPtr, "-header");
+	    Tcl_DStringAppendElement(dsPtr, Tcl_GetString(tmpObj));
+	    Tcl_DecrRefCount(tmpObj);
+	} else {
+	    TclDStringAppendObj(dsPtr, tmpObj);
+	    Tcl_DecrRefCount(tmpObj);
+	    return TCL_OK;
+	}
+    }
+
+    /*
+     * Now we do the standard processing of the stream we wrapped.
+     */
+
+    if (getOptionProc) {
+	return getOptionProc(Tcl_GetChannelInstanceData(cd->parent),
+		interp, optionName, dsPtr);
+    }
+    if (optionName == NULL) {
+	return TCL_OK;
+    }
+    if (cd->format == TCL_ZLIB_FORMAT_GZIP) {
+	return Tcl_BadChannelOption(interp, optionName,
+		(cd->mode == TCL_ZLIB_STREAM_DEFLATE)
+		? gzipChanOptions : gunzipChanOptions);
+    } else {
+	return Tcl_BadChannelOption(interp, optionName,
+		(cd->mode == TCL_ZLIB_STREAM_DEFLATE)
+		? compressChanOptions : decompressChanOptions);
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ZlibTransformWatch, ZlibTransformEventHandler --
+ *
+ *	If we have data pending, trigger a readable event after a short time
+ *	(in order to allow a real event to catch up).
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+ZlibTransformWatch(
+    ClientData instanceData,
+    int mask)
+{
+    ZlibChannelData *cd = instanceData;
+    Tcl_DriverWatchProc *watchProc;
+
+    /*
+     * This code is based on the code in tclIORTrans.c
+     */
+
+    watchProc = Tcl_ChannelWatchProc(Tcl_GetChannelType(cd->parent));
+    watchProc(Tcl_GetChannelInstanceData(cd->parent), mask);
+
+    if (!(mask & TCL_READABLE) || Tcl_DStringLength(&cd->decompressed) == 0) {
+	ZlibTransformEventTimerKill(cd);
+    } else if (cd->timer == NULL) {
+	cd->timer = Tcl_CreateTimerHandler(SYNTHETIC_EVENT_TIME,
+		ZlibTransformTimerRun, cd);
+    }
+}
+
+static int
+ZlibTransformEventHandler(
+    ClientData instanceData,
+    int interestMask)
+{
+    ZlibChannelData *cd = instanceData;
+
+    ZlibTransformEventTimerKill(cd);
+    return interestMask;
+}
+
+static inline void
+ZlibTransformEventTimerKill(
+    ZlibChannelData *cd)
+{
+    if (cd->timer != NULL) {
+	Tcl_DeleteTimerHandler(cd->timer);
+	cd->timer = NULL;
+    }
+}
+
+static void
+ZlibTransformTimerRun(
+    ClientData clientData)
+{
+    ZlibChannelData *cd = clientData;
+
+    cd->timer = NULL;
+    Tcl_NotifyChannel(cd->chan, TCL_READABLE);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ZlibTransformGetHandle --
+ *
+ *	Anything that needs the OS handle is told to get it from what we are
+ *	stacked on top of.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+ZlibTransformGetHandle(
+    ClientData instanceData,
+    int direction,
+    ClientData *handlePtr)
+{
+    ZlibChannelData *cd = instanceData;
+
+    return Tcl_GetChannelHandle(cd->parent, direction, handlePtr);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ZlibTransformBlockMode --
+ *
+ *	We need to keep track of the blocking mode; it changes our behavior.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+ZlibTransformBlockMode(
+    ClientData instanceData,
+    int mode)
+{
+    ZlibChannelData *cd = instanceData;
+
+    if (mode == TCL_MODE_NONBLOCKING) {
+	cd->flags |= ASYNC;
+    } else {
+	cd->flags &= ~ASYNC;
+    }
+    return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ZlibStackChannelTransform --
+ *
+ *	Stacks either compression or decompression onto a channel.
+ *
+ * Results:
+ *	The stacked channel, or NULL if there was an error.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static Tcl_Channel
+ZlibStackChannelTransform(
+    Tcl_Interp *interp,		/* Where to write error messages. */
+    int mode,			/* Whether this is a compressing transform
+				 * (TCL_ZLIB_STREAM_DEFLATE) or a
+				 * decompressing transform
+				 * (TCL_ZLIB_STREAM_INFLATE). Note that
+				 * compressing transforms require that the
+				 * channel is writable, and decompressing
+				 * transforms require that the channel is
+				 * readable. */
+    int format,			/* One of the TCL_ZLIB_FORMAT_* values that
+				 * indicates what compressed format to allow.
+				 * TCL_ZLIB_FORMAT_AUTO is only supported for
+				 * decompressing transforms. */
+    int level,			/* What compression level to use. Ignored for
+				 * decompressing transforms. */
+    int limit,			/* The limit on the number of bytes to read
+				 * ahead; always at least 1. */
+    Tcl_Channel channel,	/* The channel to attach to. */
+    Tcl_Obj *gzipHeaderDictPtr,	/* A description of header to use, or NULL to
+				 * use a default. Ignored if not compressing
+				 * to produce gzip-format data. */
+    Tcl_Obj *compDictObj)	/* Byte-array object containing compression
+				 * dictionary (not dictObj!) to use if
+				 * necessary. */
+{
+    ZlibChannelData *cd = ckalloc(sizeof(ZlibChannelData));
+    Tcl_Channel chan;
+    int wbits = 0;
+
+    if (mode != TCL_ZLIB_STREAM_DEFLATE && mode != TCL_ZLIB_STREAM_INFLATE) {
+	Tcl_Panic("unknown mode: %d", mode);
+    }
+
+    memset(cd, 0, sizeof(ZlibChannelData));
+    cd->mode = mode;
+    cd->format = format;
+    cd->readAheadLimit = limit;
+
+    if (format == TCL_ZLIB_FORMAT_GZIP || format == TCL_ZLIB_FORMAT_AUTO) {
+	if (mode == TCL_ZLIB_STREAM_DEFLATE) {
+	    if (gzipHeaderDictPtr) {
+		cd->flags |= OUT_HEADER;
+		if (GenerateHeader(interp, gzipHeaderDictPtr, &cd->outHeader,
+			NULL) != TCL_OK) {
+		    goto error;
+		}
+	    }
+	} else {
+	    cd->flags |= IN_HEADER;
+	    cd->inHeader.header.name = (Bytef *)
+		    &cd->inHeader.nativeFilenameBuf;
+	    cd->inHeader.header.name_max = MAXPATHLEN - 1;
+	    cd->inHeader.header.comment = (Bytef *)
+		    &cd->inHeader.nativeCommentBuf;
+	    cd->inHeader.header.comm_max = MAX_COMMENT_LEN - 1;
+	}
+    }
+
+    if (compDictObj != NULL) {
+	cd->compDictObj = Tcl_DuplicateObj(compDictObj);
+	Tcl_IncrRefCount(cd->compDictObj);
+	Tcl_GetByteArrayFromObj(cd->compDictObj, NULL);
+    }
+
+    if (format == TCL_ZLIB_FORMAT_RAW) {
+	wbits = WBITS_RAW;
+    } else if (format == TCL_ZLIB_FORMAT_ZLIB) {
+	wbits = WBITS_ZLIB;
+    } else if (format == TCL_ZLIB_FORMAT_GZIP) {
+	wbits = WBITS_GZIP;
+    } else if (format == TCL_ZLIB_FORMAT_AUTO) {
+	wbits = WBITS_AUTODETECT;
+    } else {
+	Tcl_Panic("bad format: %d", format);
+    }
+
+    /*
+     * Initialize input inflater or the output deflater.
+     */
+
+    if (mode == TCL_ZLIB_STREAM_INFLATE) {
+	if (inflateInit2(&cd->inStream, wbits) != Z_OK) {
+	    goto error;
+	}
+	cd->inAllocated = DEFAULT_BUFFER_SIZE;
+	cd->inBuffer = ckalloc(cd->inAllocated);
+	if (cd->flags & IN_HEADER) {
+	    if (inflateGetHeader(&cd->inStream, &cd->inHeader.header) != Z_OK) {
+		goto error;
+	    }
+	}
+	if (cd->format == TCL_ZLIB_FORMAT_RAW && cd->compDictObj) {
+	    if (SetInflateDictionary(&cd->inStream, cd->compDictObj) != Z_OK) {
+		goto error;
+	    }
+	}
+    } else {
+	if (deflateInit2(&cd->outStream, level, Z_DEFLATED, wbits,
+		MAX_MEM_LEVEL, Z_DEFAULT_STRATEGY) != Z_OK) {
+	    goto error;
+	}
+	cd->outAllocated = DEFAULT_BUFFER_SIZE;
+	cd->outBuffer = ckalloc(cd->outAllocated);
+	if (cd->flags & OUT_HEADER) {
+	    if (deflateSetHeader(&cd->outStream, &cd->outHeader.header) != Z_OK) {
+		goto error;
+	    }
+	}
+	if (cd->compDictObj) {
+	    if (SetDeflateDictionary(&cd->outStream, cd->compDictObj) != Z_OK) {
+		goto error;
+	    }
+	}
+    }
+
+    Tcl_DStringInit(&cd->decompressed);
+
+    chan = Tcl_StackChannel(interp, &zlibChannelType, cd,
+	    Tcl_GetChannelMode(channel), channel);
+    if (chan == NULL) {
+	goto error;
+    }
+    cd->chan = chan;
+    cd->parent = Tcl_GetStackedChannel(chan);
+    Tcl_SetObjResult(interp, Tcl_NewStringObj(Tcl_GetChannelName(chan), -1));
+    return chan;
+
+  error:
+    if (cd->inBuffer) {
+	ckfree(cd->inBuffer);
+	inflateEnd(&cd->inStream);
+    }
+    if (cd->outBuffer) {
+	ckfree(cd->outBuffer);
+	deflateEnd(&cd->outStream);
+    }
+    if (cd->compDictObj) {
+	Tcl_DecrRefCount(cd->compDictObj);
+    }
+    ckfree(cd);
+    return NULL;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ResultCopy --
+ *
+ *	Copies the requested number of bytes from the buffer into the
+ *	specified array and removes them from the buffer afterward. Copies
+ *	less if there is not enough data in the buffer.
+ *
+ * Side effects:
+ *	See above.
+ *
+ * Result:
+ *	The number of actually copied bytes, possibly less than 'toRead'.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static inline int
+ResultCopy(
+    ZlibChannelData *cd,	/* The location of the buffer to read from. */
+    char *buf,			/* The buffer to copy into */
+    int toRead)			/* Number of requested bytes */
+{
+    int have = Tcl_DStringLength(&cd->decompressed);
+
+    if (have == 0) {
+	/*
+	 * Nothing to copy in the case of an empty buffer.
+	 */
+
+	return 0;
+    } else if (have > toRead) {
+	/*
+	 * The internal buffer contains more than requested. Copy the
+	 * requested subset to the caller, shift the remaining bytes down, and
+	 * truncate.
+	 */
+
+	char *src = Tcl_DStringValue(&cd->decompressed);
+
+	memcpy(buf, src, toRead);
+	memmove(src, src + toRead, have - toRead);
+
+	Tcl_DStringSetLength(&cd->decompressed, have - toRead);
+	return toRead;
+    } else /* have <= toRead */ {
+	/*
+	 * There is just or not enough in the buffer to fully satisfy the
+	 * caller, so take everything as best effort.
+	 */
+
+	memcpy(buf, Tcl_DStringValue(&cd->decompressed), have);
+	TclDStringClear(&cd->decompressed);
+	return have;
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * ResultGenerate --
+ *
+ *	Extract uncompressed bytes from the compression engine and store them
+ *	in our working buffer.
+ *
+ * Result:
+ *	TCL_OK/TCL_ERROR (with *errorCodePtr updated with reason).
+ *
+ * Side effects:
+ *	See above.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+ResultGenerate(
+    ZlibChannelData *cd,
+    int n,
+    int flush,
+    int *errorCodePtr)
+{
+#define MAXBUF	1024
+    unsigned char buf[MAXBUF];
+    int e, written;
+    Tcl_Obj *errObj;
+
+    cd->inStream.next_in = (Bytef *) cd->inBuffer;
+    cd->inStream.avail_in = n;
+
+    while (1) {
+	cd->inStream.next_out = (Bytef *) buf;
+	cd->inStream.avail_out = MAXBUF;
+
+	e = inflate(&cd->inStream, flush);
+	if (e == Z_NEED_DICT && cd->compDictObj) {
+	    e = SetInflateDictionary(&cd->inStream, cd->compDictObj);
+	    if (e == Z_OK) {
+		/*
+		 * A repetition of Z_NEED_DICT is just an error.
+		 */
+
+		cd->inStream.next_out = (Bytef *) buf;
+		cd->inStream.avail_out = MAXBUF;
+		e = inflate(&cd->inStream, flush);
+	    }
+	}
+
+	/*
+	 * avail_out is now the left over space in the output.  Therefore
+	 * "MAXBUF - avail_out" is the amount of bytes generated.
+	 */
+
+	written = MAXBUF - cd->inStream.avail_out;
+	if (written) {
+	    Tcl_DStringAppend(&cd->decompressed, (char *) buf, written);
+	}
+
+	/*
+	 * The cases where we're definitely done.
+	 */
+
+	if (((flush == Z_SYNC_FLUSH) && (e == Z_BUF_ERROR))
+		|| (e == Z_STREAM_END)
+		|| (e == Z_OK && cd->inStream.avail_out == 0)) {
+	    return TCL_OK;
+	}
+
+	/*
+	 * Z_BUF_ERROR can be ignored as per http://www.zlib.net/zlib_how.html
+	 *
+	 * Just indicates that the zlib couldn't consume input/produce output,
+	 * and is fixed by supplying more input.
+	 *
+	 * Otherwise, we've got errors and need to report to higher-up.
+	 */
+
+	if ((e != Z_OK) && (e != Z_BUF_ERROR)) {
+	    goto handleError;
+	}
+
+	/*
+	 * Check if the inflate stopped early.
+	 */
+
+	if (cd->inStream.avail_in <= 0 && flush != Z_SYNC_FLUSH) {
+	    return TCL_OK;
+	}
+    }
+
+  handleError:
+    errObj = Tcl_NewListObj(0, NULL);
+    Tcl_ListObjAppendElement(NULL, errObj, Tcl_NewStringObj("-errorcode",-1));
+    Tcl_ListObjAppendElement(NULL, errObj,
+	    ConvertErrorToList(e, cd->inStream.adler));
+    Tcl_ListObjAppendElement(NULL, errObj,
+	    Tcl_NewStringObj(cd->inStream.msg, -1));
+    Tcl_SetChannelError(cd->parent, errObj);
+    *errorCodePtr = EINVAL;
+    return TCL_ERROR;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *	Finally, the TclZlibInit function. Used to install the zlib API.
+ *----------------------------------------------------------------------
+ */
+
+int
+TclZlibInit(
+    Tcl_Interp *interp)
+{
+    Tcl_Config cfg[2];
+
+    /*
+     * This does two things. It creates a counter used in the creation of
+     * stream commands, and it creates the namespace that will contain those
+     * commands.
+     */
+
+    Tcl_EvalEx(interp, "namespace eval ::tcl::zlib {variable cmdcounter 0}", -1, 0);
+
+    /*
+     * Create the public scripted interface to this file's functionality.
+     */
+
+    Tcl_CreateObjCommand(interp, "zlib", ZlibCmd, 0, 0);
+
+    /*
+     * Store the underlying configuration information.
+     *
+     * TODO: Describe whether we're using the system version of the library or
+     * a compatibility version built into Tcl?
+     */
+
+    cfg[0].key = "zlibVersion";
+    cfg[0].value = zlibVersion();
+    cfg[1].key = NULL;
+    Tcl_RegisterConfig(interp, "zlib", cfg, "iso8859-1");
+
+    /*
+     * Formally provide the package as a Tcl built-in.
+     */
+
+    return Tcl_PkgProvide(interp, "zlib", TCL_ZLIB_VERSION);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *	Stubs used when a suitable zlib installation was not found during
+ *	configure.
+ *----------------------------------------------------------------------
+ */
+
+#else /* !HAVE_ZLIB */
+int
+Tcl_ZlibStreamInit(
+    Tcl_Interp *interp,
+    int mode,
+    int format,
+    int level,
+    Tcl_Obj *dictObj,
+    Tcl_ZlibStream *zshandle)
+{
+    if (interp) {
+	Tcl_SetObjResult(interp, Tcl_NewStringObj("unimplemented", -1));
+	Tcl_SetErrorCode(interp, "TCL", "UNIMPLEMENTED", NULL);
+    }
+    return TCL_ERROR;
+}
+
+int
+Tcl_ZlibStreamClose(
+    Tcl_ZlibStream zshandle)
+{
+    return TCL_OK;
+}
+
+int
+Tcl_ZlibStreamReset(
+    Tcl_ZlibStream zshandle)
+{
+    return TCL_OK;
+}
+
+Tcl_Obj *
+Tcl_ZlibStreamGetCommandName(
+    Tcl_ZlibStream zshandle)
+{
+    return NULL;
+}
+
+int
+Tcl_ZlibStreamEof(
+    Tcl_ZlibStream zshandle)
+{
+    return 1;
+}
+
+int
+Tcl_ZlibStreamChecksum(
+    Tcl_ZlibStream zshandle)
+{
+    return 0;
+}
+
+int
+Tcl_ZlibStreamPut(
+    Tcl_ZlibStream zshandle,
+    Tcl_Obj *data,
+    int flush)
+{
+    return TCL_OK;
+}
+
+int
+Tcl_ZlibStreamGet(
+    Tcl_ZlibStream zshandle,
+    Tcl_Obj *data,
+    int count)
+{
+    return TCL_OK;
+}
+
+int
+Tcl_ZlibDeflate(
+    Tcl_Interp *interp,
+    int format,
+    Tcl_Obj *data,
+    int level,
+    Tcl_Obj *gzipHeaderDictObj)
+{
+    if (interp) {
+	Tcl_SetObjResult(interp, Tcl_NewStringObj("unimplemented", -1));
+	Tcl_SetErrorCode(interp, "TCL", "UNIMPLEMENTED", NULL);
+    }
+    return TCL_ERROR;
+}
+
+int
+Tcl_ZlibInflate(
+    Tcl_Interp *interp,
+    int format,
+    Tcl_Obj *data,
+    int bufferSize,
+    Tcl_Obj *gzipHeaderDictObj)
+{
+    if (interp) {
+	Tcl_SetObjResult(interp, Tcl_NewStringObj("unimplemented", -1));
+	Tcl_SetErrorCode(interp, "TCL", "UNIMPLEMENTED", NULL);
+    }
+    return TCL_ERROR;
+}
+
+unsigned int
+Tcl_ZlibCRC32(
+    unsigned int crc,
+    const char *buf,
+    int len)
+{
+    return 0;
+}
+
+unsigned int
+Tcl_ZlibAdler32(
+    unsigned int adler,
+    const char *buf,
+    int len)
+{
+    return 0;
+}
+
+void
+Tcl_ZlibStreamSetCompressionDictionary(
+    Tcl_ZlibStream zshandle,
+    Tcl_Obj *compressionDictionaryObj)
+{
+    /* Do nothing. */
+}
+#endif /* HAVE_ZLIB */
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/generic/tommath.h b/generic/tommath.h
new file mode 100644
index 0000000..028a84d
--- /dev/null
+++ b/generic/tommath.h
@@ -0,0 +1 @@
+#include "tclTomMathInt.h"
diff --git a/library/auto.tcl b/library/auto.tcl
new file mode 100644
index 0000000..02edcc4
--- /dev/null
+++ b/library/auto.tcl
@@ -0,0 +1,651 @@
+# auto.tcl --
+#
+# utility procs formerly in init.tcl dealing with auto execution of commands
+# and can be auto loaded themselves.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994-1998 Sun Microsystems, Inc.
+#
+# See the file "license.terms" for information on usage and redistribution of
+# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+
+# auto_reset --
+#
+# Destroy all cached information for auto-loading and auto-execution, so that
+# the information gets recomputed the next time it's needed.  Also delete any
+# commands that are listed in the auto-load index.
+#
+# Arguments:
+# None.
+
+proc auto_reset {} {
+    global auto_execs auto_index auto_path
+    if {[array exists auto_index]} {
+	foreach cmdName [array names auto_index] {
+	    set fqcn [namespace which $cmdName]
+	    if {$fqcn eq ""} {
+		continue
+	    }
+	    rename $fqcn {}
+	}
+    }
+    unset -nocomplain auto_execs auto_index ::tcl::auto_oldpath
+    if {[catch {llength $auto_path}]} {
+	set auto_path [list [info library]]
+    } elseif {[info library] ni $auto_path} {
+	lappend auto_path [info library]
+    }
+}
+
+# tcl_findLibrary --
+#
+#	This is a utility for extensions that searches for a library directory
+#	using a canonical searching algorithm. A side effect is to source the
+#	initialization script and set a global library variable.
+#
+# Arguments:
+# 	basename	Prefix of the directory name, (e.g., "tk")
+#	version		Version number of the package, (e.g., "8.0")
+#	patch		Patchlevel of the package, (e.g., "8.0.3")
+#	initScript	Initialization script to source (e.g., tk.tcl)
+#	enVarName	environment variable to honor (e.g., TK_LIBRARY)
+#	varName		Global variable to set when done (e.g., tk_library)
+
+proc tcl_findLibrary {basename version patch initScript enVarName varName} {
+    upvar #0 $varName the_library
+    global auto_path env tcl_platform
+
+    set dirs {}
+    set errors {}
+
+    # The C application may have hardwired a path, which we honor
+
+    if {[info exists the_library] && $the_library ne ""} {
+	lappend dirs $the_library
+    } else {
+	# Do the canonical search
+
+	# 1. From an environment variable, if it exists.  Placing this first
+	#    gives the end-user ultimate control to work-around any bugs, or
+	#    to customize.
+
+        if {[info exists env($enVarName)]} {
+            lappend dirs $env($enVarName)
+        }
+
+	# 2. In the package script directory registered within the
+	#    configuration of the package itself.
+
+	catch {
+	    lappend dirs [::${basename}::pkgconfig get scriptdir,runtime]
+	}
+
+	# 3. Relative to auto_path directories.  This checks relative to the
+	# Tcl library as well as allowing loading of libraries added to the
+	# auto_path that is not relative to the core library or binary paths.
+	foreach d $auto_path {
+	    lappend dirs [file join $d $basename$version]
+	    if {$tcl_platform(platform) eq "unix"
+		    && $tcl_platform(os) eq "Darwin"} {
+		# 4. On MacOSX, check the Resources/Scripts subdir too
+		lappend dirs [file join $d $basename$version Resources Scripts]
+	    }
+	}
+
+	# 3. Various locations relative to the executable
+	# ../lib/foo1.0		(From bin directory in install hierarchy)
+	# ../../lib/foo1.0	(From bin/arch directory in install hierarchy)
+	# ../library		(From unix directory in build hierarchy)
+	#
+	# Remaining locations are out of date (when relevant, they ought to be
+	# covered by the $::auto_path seach above) and disabled.
+	#
+	# ../../library		(From unix/arch directory in build hierarchy)
+	# ../../foo1.0.1/library
+	#		(From unix directory in parallel build hierarchy)
+	# ../../../foo1.0.1/library
+	#		(From unix/arch directory in parallel build hierarchy)
+
+        set parentDir [file dirname [file dirname [info nameofexecutable]]]
+        set grandParentDir [file dirname $parentDir]
+        lappend dirs [file join $parentDir lib $basename$version]
+        lappend dirs [file join $grandParentDir lib $basename$version]
+        lappend dirs [file join $parentDir library]
+	if {0} {
+	    lappend dirs [file join $grandParentDir library]
+	    lappend dirs [file join $grandParentDir $basename$patch library]
+	    lappend dirs [file join [file dirname $grandParentDir] \
+			      $basename$patch library]
+	}
+    }
+    # uniquify $dirs in order
+    array set seen {}
+    foreach i $dirs {
+	# Take note that the [file normalize] below has been noted to cause
+	# difficulties for the freewrap utility.  See Bug 1072136.  Until
+	# freewrap resolves the matter, one might work around the problem by
+	# disabling that branch.
+	if {[interp issafe]} {
+	    set norm $i
+	} else {
+	    set norm [file normalize $i]
+	}
+	if {[info exists seen($norm)]} {
+	    continue
+	}
+	set seen($norm) {}
+	lappend uniqdirs $i
+    }
+    set dirs $uniqdirs
+    foreach i $dirs {
+        set the_library $i
+        set file [file join $i $initScript]
+
+	# source everything when in a safe interpreter because we have a
+	# source command, but no file exists command
+
+        if {[interp issafe] || [file exists $file]} {
+            if {![catch {uplevel #0 [list source $file]} msg opts]} {
+                return
+            }
+	    append errors "$file: $msg\n"
+	    append errors [dict get $opts -errorinfo]\n
+        }
+    }
+    unset -nocomplain the_library
+    set msg "Can't find a usable $initScript in the following directories: \n"
+    append msg "    $dirs\n\n"
+    append msg "$errors\n\n"
+    append msg "This probably means that $basename wasn't installed properly.\n"
+    error $msg
+}
+
+
+# ----------------------------------------------------------------------
+# auto_mkindex
+# ----------------------------------------------------------------------
+# The following procedures are used to generate the tclIndex file from Tcl
+# source files.  They use a special safe interpreter to parse Tcl source
+# files, writing out index entries as "proc" commands are encountered.  This
+# implementation won't work in a safe interpreter, since a safe interpreter
+# can't create the special parser and mess with its commands.
+
+if {[interp issafe]} {
+    return	;# Stop sourcing the file here
+}
+
+# auto_mkindex --
+# Regenerate a tclIndex file from Tcl source files.  Takes as argument the
+# name of the directory in which the tclIndex file is to be placed, followed
+# by any number of glob patterns to use in that directory to locate all of the
+# relevant files.
+#
+# Arguments:
+# dir -		Name of the directory in which to create an index.
+
+# args -	Any number of additional arguments giving the names of files
+#		within dir.  If no additional are given auto_mkindex will look
+#		for *.tcl.
+
+proc auto_mkindex {dir args} {
+    if {[interp issafe]} {
+        error "can't generate index within safe interpreter"
+    }
+
+    set oldDir [pwd]
+    cd $dir
+
+    append index "# Tcl autoload index file, version 2.0\n"
+    append index "# This file is generated by the \"auto_mkindex\" command\n"
+    append index "# and sourced to set up indexing information for one or\n"
+    append index "# more commands.  Typically each line is a command that\n"
+    append index "# sets an element in the auto_index array, where the\n"
+    append index "# element name is the name of a command and the value is\n"
+    append index "# a script that loads the command.\n\n"
+    if {![llength $args]} {
+	set args *.tcl
+    }
+
+    auto_mkindex_parser::init
+    foreach file [glob -- {*}$args] {
+	try {
+	    append index [auto_mkindex_parser::mkindex $file]
+	} on error {msg opts} {
+	    cd $oldDir
+	    return -options $opts $msg
+	}
+    }
+    auto_mkindex_parser::cleanup
+
+    set fid [open "tclIndex" w]
+    puts -nonewline $fid $index
+    close $fid
+    cd $oldDir
+}
+
+# Original version of auto_mkindex that just searches the source code for
+# "proc" at the beginning of the line.
+
+proc auto_mkindex_old {dir args} {
+    set oldDir [pwd]
+    cd $dir
+    set dir [pwd]
+    append index "# Tcl autoload index file, version 2.0\n"
+    append index "# This file is generated by the \"auto_mkindex\" command\n"
+    append index "# and sourced to set up indexing information for one or\n"
+    append index "# more commands.  Typically each line is a command that\n"
+    append index "# sets an element in the auto_index array, where the\n"
+    append index "# element name is the name of a command and the value is\n"
+    append index "# a script that loads the command.\n\n"
+    if {![llength $args]} {
+	set args *.tcl
+    }
+    foreach file [glob -- {*}$args] {
+	set f ""
+	set error [catch {
+	    set f [open $file]
+	    while {[gets $f line] >= 0} {
+		if {[regexp {^proc[ 	]+([^ 	]*)} $line match procName]} {
+		    set procName [lindex [auto_qualify $procName "::"] 0]
+		    append index "set [list auto_index($procName)]"
+		    append index " \[list source \[file join \$dir [list $file]\]\]\n"
+		}
+	    }
+	    close $f
+	} msg opts]
+	if {$error} {
+	    catch {close $f}
+	    cd $oldDir
+	    return -options $opts $msg
+	}
+    }
+    set f ""
+    set error [catch {
+	set f [open tclIndex w]
+	puts -nonewline $f $index
+	close $f
+	cd $oldDir
+    } msg opts]
+    if {$error} {
+	catch {close $f}
+	cd $oldDir
+	error $msg $info $code
+	return -options $opts $msg
+    }
+}
+
+# Create a safe interpreter that can be used to parse Tcl source files
+# generate a tclIndex file for autoloading.  This interp contains commands for
+# things that need index entries.  Each time a command is executed, it writes
+# an entry out to the index file.
+
+namespace eval auto_mkindex_parser {
+    variable parser ""          ;# parser used to build index
+    variable index ""           ;# maintains index as it is built
+    variable scriptFile ""      ;# name of file being processed
+    variable contextStack ""    ;# stack of namespace scopes
+    variable imports ""         ;# keeps track of all imported cmds
+    variable initCommands       ;# list of commands that create aliases
+    if {![info exists initCommands]} {
+	set initCommands [list]
+    }
+
+    proc init {} {
+	variable parser
+	variable initCommands
+
+	if {![interp issafe]} {
+	    set parser [interp create -safe]
+	    $parser hide info
+	    $parser hide rename
+	    $parser hide proc
+	    $parser hide namespace
+	    $parser hide eval
+	    $parser hide puts
+	    foreach ns [$parser invokehidden namespace children ::] {
+		# MUST NOT DELETE "::tcl" OR BAD THINGS HAPPEN!
+		if {$ns eq "::tcl"} continue
+		$parser invokehidden namespace delete $ns
+	    }
+	    foreach cmd [$parser invokehidden info commands ::*] {
+		$parser invokehidden rename $cmd {}
+	    }
+	    $parser invokehidden proc unknown {args} {}
+
+	    # We'll need access to the "namespace" command within the
+	    # interp.  Put it back, but move it out of the way.
+
+	    $parser expose namespace
+	    $parser invokehidden rename namespace _%@namespace
+	    $parser expose eval
+	    $parser invokehidden rename eval _%@eval
+
+	    # Install all the registered psuedo-command implementations
+
+	    foreach cmd $initCommands {
+		eval $cmd
+	    }
+	}
+    }
+    proc cleanup {} {
+	variable parser
+	interp delete $parser
+	unset parser
+    }
+}
+
+# auto_mkindex_parser::mkindex --
+#
+# Used by the "auto_mkindex" command to create a "tclIndex" file for the given
+# Tcl source file.  Executes the commands in the file, and handles things like
+# the "proc" command by adding an entry for the index file.  Returns a string
+# that represents the index file.
+#
+# Arguments:
+#	file	Name of Tcl source file to be indexed.
+
+proc auto_mkindex_parser::mkindex {file} {
+    variable parser
+    variable index
+    variable scriptFile
+    variable contextStack
+    variable imports
+
+    set scriptFile $file
+
+    set fid [open $file]
+    set contents [read $fid]
+    close $fid
+
+    # There is one problem with sourcing files into the safe interpreter:
+    # references like "$x" will fail since code is not really being executed
+    # and variables do not really exist.  To avoid this, we replace all $ with
+    # \0 (literally, the null char) later, when getting proc names we will
+    # have to reverse this replacement, in case there were any $ in the proc
+    # name.  This will cause a problem if somebody actually tries to have a \0
+    # in their proc name.  Too bad for them.
+    set contents [string map [list \$ \0] $contents]
+
+    set index ""
+    set contextStack ""
+    set imports ""
+
+    $parser eval $contents
+
+    foreach name $imports {
+        catch {$parser eval [list _%@namespace forget $name]}
+    }
+    return $index
+}
+
+# auto_mkindex_parser::hook command
+#
+# Registers a Tcl command to evaluate when initializing the slave interpreter
+# used by the mkindex parser.  The command is evaluated in the master
+# interpreter, and can use the variable auto_mkindex_parser::parser to get to
+# the slave
+
+proc auto_mkindex_parser::hook {cmd} {
+    variable initCommands
+
+    lappend initCommands $cmd
+}
+
+# auto_mkindex_parser::slavehook command
+#
+# Registers a Tcl command to evaluate when initializing the slave interpreter
+# used by the mkindex parser.  The command is evaluated in the slave
+# interpreter.
+
+proc auto_mkindex_parser::slavehook {cmd} {
+    variable initCommands
+
+    # The $parser variable is defined to be the name of the slave interpreter
+    # when this command is used later.
+
+    lappend initCommands "\$parser eval [list $cmd]"
+}
+
+# auto_mkindex_parser::command --
+#
+# Registers a new command with the "auto_mkindex_parser" interpreter that
+# parses Tcl files.  These commands are fake versions of things like the
+# "proc" command.  When you execute them, they simply write out an entry to a
+# "tclIndex" file for auto-loading.
+#
+# This procedure allows extensions to register their own commands with the
+# auto_mkindex facility.  For example, a package like [incr Tcl] might
+# register a "class" command so that class definitions could be added to a
+# "tclIndex" file for auto-loading.
+#
+# Arguments:
+#	name 	Name of command recognized in Tcl files.
+#	arglist	Argument list for command.
+#	body 	Implementation of command to handle indexing.
+
+proc auto_mkindex_parser::command {name arglist body} {
+    hook [list auto_mkindex_parser::commandInit $name $arglist $body]
+}
+
+# auto_mkindex_parser::commandInit --
+#
+# This does the actual work set up by auto_mkindex_parser::command. This is
+# called when the interpreter used by the parser is created.
+#
+# Arguments:
+#	name 	Name of command recognized in Tcl files.
+#	arglist	Argument list for command.
+#	body 	Implementation of command to handle indexing.
+
+proc auto_mkindex_parser::commandInit {name arglist body} {
+    variable parser
+
+    set ns [namespace qualifiers $name]
+    set tail [namespace tail $name]
+    if {$ns eq ""} {
+        set fakeName [namespace current]::_%@fake_$tail
+    } else {
+        set fakeName [namespace current]::[string map {:: _} _%@fake_$name]
+    }
+    proc $fakeName $arglist $body
+
+    # YUK!  Tcl won't let us alias fully qualified command names, so we can't
+    # handle names like "::itcl::class".  Instead, we have to build procs with
+    # the fully qualified names, and have the procs point to the aliases.
+
+    if {[string match *::* $name]} {
+        set exportCmd [list _%@namespace export [namespace tail $name]]
+        $parser eval [list _%@namespace eval $ns $exportCmd]
+
+	# The following proc definition does not work if you want to tolerate
+	# space or something else diabolical in the procedure name, (i.e.,
+	# space in $alias). The following does not work:
+	#   "_%@eval {$alias} \$args"
+	# because $alias gets concat'ed to $args.  The following does not work
+	# because $cmd is somehow undefined
+	#   "set cmd {$alias} \; _%@eval {\$cmd} \$args"
+	# A gold star to someone that can make test autoMkindex-3.3 work
+	# properly
+
+        set alias [namespace tail $fakeName]
+        $parser invokehidden proc $name {args} "_%@eval {$alias} \$args"
+        $parser alias $alias $fakeName
+    } else {
+        $parser alias $name $fakeName
+    }
+    return
+}
+
+# auto_mkindex_parser::fullname --
+#
+# Used by commands like "proc" within the auto_mkindex parser.  Returns the
+# qualified namespace name for the "name" argument.  If the "name" does not
+# start with "::", elements are added from the current namespace stack to
+# produce a qualified name.  Then, the name is examined to see whether or not
+# it should really be qualified.  If the name has more than the leading "::",
+# it is returned as a fully qualified name.  Otherwise, it is returned as a
+# simple name.  That way, the Tcl autoloader will recognize it properly.
+#
+# Arguments:
+# name -		Name that is being added to index.
+
+proc auto_mkindex_parser::fullname {name} {
+    variable contextStack
+
+    if {![string match ::* $name]} {
+        foreach ns $contextStack {
+            set name "${ns}::$name"
+            if {[string match ::* $name]} {
+                break
+            }
+        }
+    }
+
+    if {[namespace qualifiers $name] eq ""} {
+        set name [namespace tail $name]
+    } elseif {![string match ::* $name]} {
+        set name "::$name"
+    }
+
+    # Earlier, mkindex replaced all $'s with \0.  Now, we have to reverse that
+    # replacement.
+    return [string map [list \0 \$] $name]
+}
+
+# auto_mkindex_parser::indexEntry --
+#
+# Used by commands like "proc" within the auto_mkindex parser to add a
+# correctly-quoted entry to the index. This is shared code so it is done
+# *right*, in one place.
+#
+# Arguments:
+# name -		Name that is being added to index.
+
+proc auto_mkindex_parser::indexEntry {name} {
+    variable index
+    variable scriptFile
+
+    # We convert all metacharacters to their backslashed form, and pre-split
+    # the file name that we know about (which will be a proper list, and so
+    # correctly quoted).
+
+    set name [string range [list \}[fullname $name]] 2 end]
+    set filenameParts [file split $scriptFile]
+
+    append index [format \
+	    {set auto_index(%s) [list source [file join $dir %s]]%s} \
+	    $name $filenameParts \n]
+    return
+}
+
+if {[llength $::auto_mkindex_parser::initCommands]} {
+    return
+}
+
+# Register all of the procedures for the auto_mkindex parser that will build
+# the "tclIndex" file.
+
+# AUTO MKINDEX:  proc name arglist body
+# Adds an entry to the auto index list for the given procedure name.
+
+auto_mkindex_parser::command proc {name args} {
+    indexEntry $name
+}
+
+# Conditionally add support for Tcl byte code files.  There are some tricky
+# details here.  First, we need to get the tbcload library initialized in the
+# current interpreter.  We cannot load tbcload into the slave until we have
+# done so because it needs access to the tcl_patchLevel variable.  Second,
+# because the package index file may defer loading the library until we invoke
+# a command, we need to explicitly invoke auto_load to force it to be loaded.
+# This should be a noop if the package has already been loaded
+
+auto_mkindex_parser::hook {
+    try {
+	package require tbcload
+    } on error {} {
+	# OK, don't have it so do nothing
+    } on ok {} {
+	if {[namespace which -command tbcload::bcproc] eq ""} {
+	    auto_load tbcload::bcproc
+	}
+	load {} tbcload $auto_mkindex_parser::parser
+
+	# AUTO MKINDEX:  tbcload::bcproc name arglist body
+	# Adds an entry to the auto index list for the given pre-compiled
+	# procedure name.
+
+	auto_mkindex_parser::commandInit tbcload::bcproc {name args} {
+	    indexEntry $name
+	}
+    }
+}
+
+# AUTO MKINDEX:  namespace eval name command ?arg arg...?
+# Adds the namespace name onto the context stack and evaluates the associated
+# body of commands.
+#
+# AUTO MKINDEX:  namespace import ?-force? pattern ?pattern...?
+# Performs the "import" action in the parser interpreter.  This is important
+# for any commands contained in a namespace that affect the index.  For
+# example, a script may say "itcl::class ...", or it may import "itcl::*" and
+# then say "class ...".  This procedure does the import operation, but keeps
+# track of imported patterns so we can remove the imports later.
+
+auto_mkindex_parser::command namespace {op args} {
+    switch -- $op {
+        eval {
+            variable parser
+            variable contextStack
+
+            set name [lindex $args 0]
+            set args [lrange $args 1 end]
+
+            set contextStack [linsert $contextStack 0 $name]
+	    $parser eval [list _%@namespace eval $name] $args
+            set contextStack [lrange $contextStack 1 end]
+        }
+        import {
+            variable parser
+            variable imports
+            foreach pattern $args {
+                if {$pattern ne "-force"} {
+                    lappend imports $pattern
+                }
+            }
+            catch {$parser eval "_%@namespace import $args"}
+        }
+	ensemble {
+	    variable parser
+	    variable contextStack
+	    if {[lindex $args 0] eq "create"} {
+		set name ::[join [lreverse $contextStack] ::]
+		catch {
+		    set name [dict get [lrange $args 1 end] -command]
+		    if {![string match ::* $name]} {
+			set name ::[join [lreverse $contextStack] ::]$name
+		    }
+		    regsub -all ::+ $name :: name
+		}
+		# create artifical proc to force an entry in the tclIndex
+		$parser eval [list ::proc $name {} {}]
+	    }
+	}
+    }
+}
+
+# AUTO MKINDEX:  oo::class create name ?definition?
+# Adds an entry to the auto index list for the given class name.
+auto_mkindex_parser::command oo::class {op name {body ""}} {
+    if {$op eq "create"} {
+	indexEntry $name
+    }
+}
+auto_mkindex_parser::command class {op name {body ""}} {
+    if {$op eq "create"} {
+	indexEntry $name
+    }
+}
+
+return
diff --git a/library/clock.tcl b/library/clock.tcl
new file mode 100755
index 0000000..8e4b657
--- /dev/null
+++ b/library/clock.tcl
@@ -0,0 +1,4547 @@
+#----------------------------------------------------------------------
+#
+# clock.tcl --
+#
+#	This file implements the portions of the [clock] ensemble that are
+#	coded in Tcl.  Refer to the users' manual to see the description of
+#	the [clock] command and its subcommands.
+#
+#
+#----------------------------------------------------------------------
+#
+# Copyright (c) 2004,2005,2006,2007 by Kevin B. Kenny
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+#----------------------------------------------------------------------
+
+# We must have message catalogs that support the root locale, and we need
+# access to the Registry on Windows systems.
+
+uplevel \#0 {
+    package require msgcat 1.6
+    if { $::tcl_platform(platform) eq {windows} } {
+	if { [catch { package require registry 1.1 }] } {
+	    namespace eval ::tcl::clock [list variable NoRegistry {}]
+	}
+    }
+}
+
+# Put the library directory into the namespace for the ensemble so that the
+# library code can find message catalogs and time zone definition files.
+
+namespace eval ::tcl::clock \
+    [list variable LibDir [file dirname [info script]]]
+
+#----------------------------------------------------------------------
+#
+# clock --
+#
+#	Manipulate times.
+#
+# The 'clock' command manipulates time.  Refer to the user documentation for
+# the available subcommands and what they do.
+#
+#----------------------------------------------------------------------
+
+namespace eval ::tcl::clock {
+
+    # Export the subcommands
+
+    namespace export format
+    namespace export clicks
+    namespace export microseconds
+    namespace export milliseconds
+    namespace export scan
+    namespace export seconds
+    namespace export add
+
+    # Import the message catalog commands that we use.
+
+    namespace import ::msgcat::mcload
+    namespace import ::msgcat::mclocale
+    namespace import ::msgcat::mc
+    namespace import ::msgcat::mcpackagelocale
+
+}
+
+#----------------------------------------------------------------------
+#
+# ::tcl::clock::Initialize --
+#
+#	Finish initializing the 'clock' subsystem
+#
+# Results:
+#	None.
+#
+# Side effects:
+#	Namespace variable in the 'clock' subsystem are initialized.
+#
+# The '::tcl::clock::Initialize' procedure initializes the namespace variables
+# and root locale message catalog for the 'clock' subsystem.  It is broken
+# into a procedure rather than simply evaluated as a script so that it will be
+# able to use local variables, avoiding the dangers of 'creative writing' as
+# in Bug 1185933.
+#
+#----------------------------------------------------------------------
+
+proc ::tcl::clock::Initialize {} {
+
+    rename ::tcl::clock::Initialize {}
+
+    variable LibDir
+
+    # Define the Greenwich time zone
+
+    proc InitTZData {} {
+	variable TZData
+	array unset TZData
+	set TZData(:Etc/GMT) {
+	    {-9223372036854775808 0 0 GMT}
+	}
+	set TZData(:GMT) $TZData(:Etc/GMT)
+	set TZData(:Etc/UTC) {
+	    {-9223372036854775808 0 0 UTC}
+	}
+	set TZData(:UTC) $TZData(:Etc/UTC)
+	set TZData(:localtime) {}
+    }
+    InitTZData
+
+    mcpackagelocale set {}
+    ::msgcat::mcpackageconfig set mcfolder [file join $LibDir msgs]
+    ::msgcat::mcpackageconfig set unknowncmd ""
+    ::msgcat::mcpackageconfig set changecmd ChangeCurrentLocale
+
+    # Define the message catalog for the root locale.
+
+    ::msgcat::mcmset {} {
+	AM {am}
+	BCE {B.C.E.}
+	CE {C.E.}
+	DATE_FORMAT {%m/%d/%Y}
+	DATE_TIME_FORMAT {%a %b %e %H:%M:%S %Y}
+	DAYS_OF_WEEK_ABBREV	{
+	    Sun Mon Tue Wed Thu Fri Sat
+	}
+	DAYS_OF_WEEK_FULL	{
+	    Sunday Monday Tuesday Wednesday Thursday Friday Saturday
+	}
+	GREGORIAN_CHANGE_DATE	2299161
+	LOCALE_DATE_FORMAT {%m/%d/%Y}
+	LOCALE_DATE_TIME_FORMAT {%a %b %e %H:%M:%S %Y}
+	LOCALE_ERAS {}
+	LOCALE_NUMERALS		{
+	    00 01 02 03 04 05 06 07 08 09
+	    10 11 12 13 14 15 16 17 18 19
+	    20 21 22 23 24 25 26 27 28 29
+	    30 31 32 33 34 35 36 37 38 39
+	    40 41 42 43 44 45 46 47 48 49
+	    50 51 52 53 54 55 56 57 58 59
+	    60 61 62 63 64 65 66 67 68 69
+	    70 71 72 73 74 75 76 77 78 79
+	    80 81 82 83 84 85 86 87 88 89
+	    90 91 92 93 94 95 96 97 98 99
+	}
+	LOCALE_TIME_FORMAT {%H:%M:%S}
+	LOCALE_YEAR_FORMAT {%EC%Ey}
+	MONTHS_ABBREV		{
+	    Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec
+	}
+	MONTHS_FULL		{
+	    	January		February	March
+	    	April		May		June
+	    	July		August		September
+		October		November	December
+	}
+	PM {pm}
+	TIME_FORMAT {%H:%M:%S}
+	TIME_FORMAT_12 {%I:%M:%S %P}
+	TIME_FORMAT_24 {%H:%M}
+	TIME_FORMAT_24_SECS {%H:%M:%S}
+    }
+
+    # Define a few Gregorian change dates for other locales.  In most cases
+    # the change date follows a language, because a nation's colonies changed
+    # at the same time as the nation itself.  In many cases, different
+    # national boundaries existed; the dominating rule is to follow the
+    # nation's capital.
+
+    # Italy, Spain, Portugal, Poland
+
+    ::msgcat::mcset it GREGORIAN_CHANGE_DATE 2299161
+    ::msgcat::mcset es GREGORIAN_CHANGE_DATE 2299161
+    ::msgcat::mcset pt GREGORIAN_CHANGE_DATE 2299161
+    ::msgcat::mcset pl GREGORIAN_CHANGE_DATE 2299161
+
+    # France, Austria
+
+    ::msgcat::mcset fr GREGORIAN_CHANGE_DATE 2299227
+
+    # For Belgium, we follow Southern Netherlands; Liege Diocese changed
+    # several weeks later.
+
+    ::msgcat::mcset fr_BE GREGORIAN_CHANGE_DATE 2299238
+    ::msgcat::mcset nl_BE GREGORIAN_CHANGE_DATE 2299238
+
+    # Austria
+
+    ::msgcat::mcset de_AT GREGORIAN_CHANGE_DATE 2299527
+
+    # Hungary
+
+    ::msgcat::mcset hu GREGORIAN_CHANGE_DATE 2301004
+
+    # Germany, Norway, Denmark (Catholic Germany changed earlier)
+
+    ::msgcat::mcset de_DE GREGORIAN_CHANGE_DATE 2342032
+    ::msgcat::mcset nb GREGORIAN_CHANGE_DATE 2342032
+    ::msgcat::mcset nn GREGORIAN_CHANGE_DATE 2342032
+    ::msgcat::mcset no GREGORIAN_CHANGE_DATE 2342032
+    ::msgcat::mcset da GREGORIAN_CHANGE_DATE 2342032
+
+    # Holland (Brabant, Gelderland, Flanders, Friesland, etc. changed at
+    # various times)
+
+    ::msgcat::mcset nl GREGORIAN_CHANGE_DATE 2342165
+
+    # Protestant Switzerland (Catholic cantons changed earlier)
+
+    ::msgcat::mcset fr_CH GREGORIAN_CHANGE_DATE 2361342
+    ::msgcat::mcset it_CH GREGORIAN_CHANGE_DATE 2361342
+    ::msgcat::mcset de_CH GREGORIAN_CHANGE_DATE 2361342
+
+    # English speaking countries
+
+    ::msgcat::mcset en GREGORIAN_CHANGE_DATE 2361222
+
+    # Sweden (had several changes onto and off of the Gregorian calendar)
+
+    ::msgcat::mcset sv GREGORIAN_CHANGE_DATE 2361390
+
+    # Russia
+
+    ::msgcat::mcset ru GREGORIAN_CHANGE_DATE 2421639
+
+    # Romania (Transylvania changed earler - perhaps de_RO should show the
+    # earlier date?)
+
+    ::msgcat::mcset ro GREGORIAN_CHANGE_DATE 2422063
+
+    # Greece
+
+    ::msgcat::mcset el GREGORIAN_CHANGE_DATE 2423480
+
+    #------------------------------------------------------------------
+    #
+    #				CONSTANTS
+    #
+    #------------------------------------------------------------------
+
+    # Paths at which binary time zone data for the Olson libraries are known
+    # to reside on various operating systems
+
+    variable ZoneinfoPaths {}
+    foreach path {
+	/usr/share/zoneinfo
+	/usr/share/lib/zoneinfo
+	/usr/lib/zoneinfo
+	/usr/local/etc/zoneinfo
+    } {
+	if { [file isdirectory $path] } {
+	    lappend ZoneinfoPaths $path
+	}
+    }
+
+    # Define the directories for time zone data and message catalogs.
+
+    variable DataDir [file join $LibDir tzdata]
+
+    # Number of days in the months, in common years and leap years.
+
+    variable DaysInRomanMonthInCommonYear \
+	{ 31 28 31 30 31 30 31 31 30 31 30 31 }
+    variable DaysInRomanMonthInLeapYear \
+	{ 31 29 31 30 31 30 31 31 30 31 30 31 }
+    variable DaysInPriorMonthsInCommonYear [list 0]
+    variable DaysInPriorMonthsInLeapYear [list 0]
+    set i 0
+    foreach j $DaysInRomanMonthInCommonYear {
+	lappend DaysInPriorMonthsInCommonYear [incr i $j]
+    }
+    set i 0
+    foreach j $DaysInRomanMonthInLeapYear {
+	lappend DaysInPriorMonthsInLeapYear [incr i $j]
+    }
+
+    # Another epoch (Hi, Jeff!)
+
+    variable Roddenberry 1946
+
+    # Integer ranges
+
+    variable MINWIDE -9223372036854775808
+    variable MAXWIDE 9223372036854775807
+
+    # Day before Leap Day
+
+    variable FEB_28	       58
+
+    # Translation table to map Windows TZI onto cities, so that the Olson
+    # rules can apply.  In some cases the mapping is ambiguous, so it's wise
+    # to specify $::env(TCL_TZ) rather than simply depending on the system
+    # time zone.
+
+    # The keys are long lists of values obtained from the time zone
+    # information in the Registry.  In order, the list elements are:
+    # 	Bias StandardBias DaylightBias
+    #   StandardDate.wYear StandardDate.wMonth StandardDate.wDayOfWeek
+    #   StandardDate.wDay StandardDate.wHour StandardDate.wMinute
+    #   StandardDate.wSecond StandardDate.wMilliseconds
+    #   DaylightDate.wYear DaylightDate.wMonth DaylightDate.wDayOfWeek
+    #   DaylightDate.wDay DaylightDate.wHour DaylightDate.wMinute
+    #   DaylightDate.wSecond DaylightDate.wMilliseconds
+    # The values are the names of time zones where those rules apply.  There
+    # is considerable ambiguity in certain zones; an attempt has been made to
+    # make a reasonable guess, but this table needs to be taken with a grain
+    # of salt.
+
+    variable WinZoneInfo [dict create {*}{
+	{-43200 0 3600 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0}  :Pacific/Kwajalein
+	{-39600 0 3600 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0}	 :Pacific/Midway
+	{-36000 0 3600 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0}  :Pacific/Honolulu
+        {-32400 0 3600 0 11 0 1 2 0 0 0 0 3 0 2 2 0 0 0} :America/Anchorage
+        {-28800 0 3600 0 11 0 1 2 0 0 0 0 3 0 2 2 0 0 0} :America/Los_Angeles
+        {-28800 0 3600 0 10 0 5 2 0 0 0 0 4 0 1 2 0 0 0} :America/Tijuana
+        {-25200 0 3600 0 11 0 1 2 0 0 0 0 3 0 2 2 0 0 0} :America/Denver
+        {-25200 0 3600 0 10 0 5 2 0 0 0 0 4 0 1 2 0 0 0} :America/Chihuahua
+	{-25200 0 3600 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0}  :America/Phoenix
+	{-21600 0 3600 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0}  :America/Regina
+	{-21600 0 3600 0 11 0 1 2 0 0 0 0 3 0 2 2 0 0 0} :America/Chicago
+        {-21600 0 3600 0 10 0 5 2 0 0 0 0 4 0 1 2 0 0 0} :America/Mexico_City
+	{-18000 0 3600 0 11 0 1 2 0 0 0 0 3 0 2 2 0 0 0} :America/New_York
+	{-18000 0 3600 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0}  :America/Indianapolis
+	{-14400 0 3600 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0}  :America/Caracas
+        {-14400 0 3600 0 3 6 2 23 59 59 999 0 10 6 2 23 59 59 999}
+							 :America/Santiago
+        {-14400 0 3600 0 2 0 5 2 0 0 0 0 11 0 1 2 0 0 0} :America/Manaus
+        {-14400 0 3600 0 11 0 1 2 0 0 0 0 3 0 2 2 0 0 0} :America/Halifax
+	{-12600 0 3600 0 10 0 5 2 0 0 0 0 4 0 1 2 0 0 0} :America/St_Johns
+	{-10800 0 3600 0 2 0 2 2 0 0 0 0 10 0 3 2 0 0 0} :America/Sao_Paulo
+	{-10800 0 3600 0 10 0 5 2 0 0 0 0 4 0 1 2 0 0 0} :America/Godthab
+	{-10800 0 3600 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0}  :America/Buenos_Aires
+        {-10800 0 3600 0 2 0 5 2 0 0 0 0 11 0 1 2 0 0 0} :America/Bahia
+        {-10800 0 3600 0 3 0 2 2 0 0 0 0 10 0 1 2 0 0 0} :America/Montevideo
+	{-7200 0 3600 0 9 0 5 2 0 0 0 0 3 0 5 2 0 0 0}   :America/Noronha
+	{-3600 0 3600 0 10 0 5 3 0 0 0 0 3 0 5 2 0 0 0}  :Atlantic/Azores
+	{-3600 0 3600 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0}   :Atlantic/Cape_Verde
+	{0 0 3600 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0}       :UTC
+	{0 0 3600 0 10 0 5 2 0 0 0 0 3 0 5 1 0 0 0}      :Europe/London
+	{3600 0 3600 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0}    :Africa/Kinshasa
+	{3600 0 3600 0 10 0 5 3 0 0 0 0 3 0 5 2 0 0 0}   :CET
+        {7200 0 3600 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0}    :Africa/Harare
+        {7200 0 3600 0 9 4 5 23 59 59 0 0 4 4 5 23 59 59 0}
+			      				 :Africa/Cairo
+	{7200 0 3600 0 10 0 5 4 0 0 0 0 3 0 5 3 0 0 0}   :Europe/Helsinki
+        {7200 0 3600 0 9 0 3 2 0 0 0 0 3 5 5 2 0 0 0}    :Asia/Jerusalem
+	{7200 0 3600 0 9 0 5 1 0 0 0 0 3 0 5 0 0 0 0}    :Europe/Bucharest
+	{7200 0 3600 0 10 0 5 3 0 0 0 0 3 0 5 2 0 0 0}   :Europe/Athens
+        {7200 0 3600 0 9 5 5 1 0 0 0 0 3 4 5 0 0 0 0}    :Asia/Amman
+        {7200 0 3600 0 10 6 5 23 59 59 999 0 3 0 5 0 0 0 0}
+							 :Asia/Beirut
+        {7200 0 -3600 0 4 0 1 2 0 0 0 0 9 0 1 2 0 0 0}   :Africa/Windhoek
+	{10800 0 3600 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0}   :Asia/Riyadh
+	{10800 0 3600 0 10 0 1 4 0 0 0 0 4 0 1 3 0 0 0}  :Asia/Baghdad
+	{10800 0 3600 0 10 0 5 3 0 0 0 0 3 0 5 2 0 0 0}  :Europe/Moscow
+	{12600 0 3600 0 9 2 4 2 0 0 0 0 3 0 1 2 0 0 0}   :Asia/Tehran
+        {14400 0 3600 0 10 0 5 5 0 0 0 0 3 0 5 4 0 0 0}  :Asia/Baku
+	{14400 0 3600 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0}   :Asia/Muscat
+	{14400 0 3600 0 10 0 5 3 0 0 0 0 3 0 5 2 0 0 0}  :Asia/Tbilisi
+	{16200 0 3600 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0}   :Asia/Kabul
+	{18000 0 3600 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0}   :Asia/Karachi
+	{18000 0 3600 0 10 0 5 3 0 0 0 0 3 0 5 2 0 0 0}  :Asia/Yekaterinburg
+	{19800 0 3600 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0}   :Asia/Calcutta
+	{20700 0 3600 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0}   :Asia/Katmandu
+	{21600 0 3600 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0}   :Asia/Dhaka
+	{21600 0 3600 0 10 0 5 3 0 0 0 0 3 0 5 2 0 0 0}  :Asia/Novosibirsk
+	{23400 0 3600 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0}   :Asia/Rangoon
+	{25200 0 3600 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0}   :Asia/Bangkok
+	{25200 0 3600 0 10 0 5 3 0 0 0 0 3 0 5 2 0 0 0}  :Asia/Krasnoyarsk
+	{28800 0 3600 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0}   :Asia/Chongqing
+	{28800 0 3600 0 10 0 5 3 0 0 0 0 3 0 5 2 0 0 0}  :Asia/Irkutsk
+	{32400 0 3600 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0}   :Asia/Tokyo
+	{32400 0 3600 0 10 0 5 3 0 0 0 0 3 0 5 2 0 0 0}  :Asia/Yakutsk
+	{34200 0 3600 0 3 0 5 3 0 0 0 0 10 0 5 2 0 0 0}  :Australia/Adelaide
+	{34200 0 3600 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0}   :Australia/Darwin
+	{36000 0 3600 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0}   :Australia/Brisbane
+	{36000 0 3600 0 10 0 5 3 0 0 0 0 3 0 5 2 0 0 0}  :Asia/Vladivostok
+	{36000 0 3600 0 3 0 5 3 0 0 0 0 10 0 1 2 0 0 0}  :Australia/Hobart
+	{36000 0 3600 0 3 0 5 3 0 0 0 0 10 0 5 2 0 0 0}  :Australia/Sydney
+	{39600 0 3600 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0}   :Pacific/Noumea
+	{43200 0 3600 0 3 0 3 3 0 0 0 0 10 0 1 2 0 0 0}  :Pacific/Auckland
+	{43200 0 3600 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0}   :Pacific/Fiji
+	{46800 0 3600 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0}   :Pacific/Tongatapu
+    }]
+
+    # Groups of fields that specify the date, priorities, and code bursts that
+    # determine Julian Day Number given those groups.  The code in [clock
+    # scan] will choose the highest priority (lowest numbered) set of fields
+    # that determines the date.
+
+    variable DateParseActions {
+
+	{ seconds } 0 {}
+
+	{ julianDay } 1 {}
+
+	{ era century yearOfCentury month dayOfMonth } 2 {
+	    dict set date year [expr { 100 * [dict get $date century]
+				       + [dict get $date yearOfCentury] }]
+	    set date [GetJulianDayFromEraYearMonthDay $date[set date {}] \
+			  $changeover]
+	}
+	{ era century yearOfCentury dayOfYear } 2 {
+	    dict set date year [expr { 100 * [dict get $date century]
+				       + [dict get $date yearOfCentury] }]
+	    set date [GetJulianDayFromEraYearDay $date[set date {}] \
+			  $changeover]
+	}
+
+	{ century yearOfCentury month dayOfMonth } 3 {
+	    dict set date era CE
+	    dict set date year [expr { 100 * [dict get $date century]
+				       + [dict get $date yearOfCentury] }]
+	    set date [GetJulianDayFromEraYearMonthDay $date[set date {}] \
+			  $changeover]
+	}
+	{ century yearOfCentury dayOfYear } 3 {
+	    dict set date era CE
+	    dict set date year [expr { 100 * [dict get $date century]
+				       + [dict get $date yearOfCentury] }]
+	    set date [GetJulianDayFromEraYearDay $date[set date {}] \
+			  $changeover]
+	}
+	{ iso8601Century iso8601YearOfCentury iso8601Week dayOfWeek } 3 {
+	    dict set date era CE
+	    dict set date iso8601Year \
+		[expr { 100 * [dict get $date iso8601Century]
+			+ [dict get $date iso8601YearOfCentury] }]
+	    set date [GetJulianDayFromEraYearWeekDay $date[set date {}] \
+			 $changeover]
+	}
+
+	{ yearOfCentury month dayOfMonth } 4 {
+	    set date [InterpretTwoDigitYear $date[set date {}] $baseTime]
+	    dict set date era CE
+	    set date [GetJulianDayFromEraYearMonthDay $date[set date {}] \
+			  $changeover]
+	}
+	{ yearOfCentury dayOfYear } 4 {
+	    set date [InterpretTwoDigitYear $date[set date {}] $baseTime]
+	    dict set date era CE
+	    set date [GetJulianDayFromEraYearDay $date[set date {}] \
+			  $changeover]
+	}
+	{ iso8601YearOfCentury iso8601Week dayOfWeek } 4 {
+	    set date [InterpretTwoDigitYear \
+			  $date[set date {}] $baseTime \
+			  iso8601YearOfCentury iso8601Year]
+	    dict set date era CE
+	    set date [GetJulianDayFromEraYearWeekDay $date[set date {}] \
+			 $changeover]
+	}
+
+	{ month dayOfMonth } 5 {
+	    set date [AssignBaseYear $date[set date {}] \
+			  $baseTime $timeZone $changeover]
+	    set date [GetJulianDayFromEraYearMonthDay $date[set date {}] \
+			  $changeover]
+	}
+	{ dayOfYear } 5 {
+	    set date [AssignBaseYear $date[set date {}] \
+			  $baseTime $timeZone $changeover]
+	    set date [GetJulianDayFromEraYearDay $date[set date {}] \
+			 $changeover]
+	}
+	{ iso8601Week dayOfWeek } 5 {
+	    set date [AssignBaseIso8601Year $date[set date {}] \
+			  $baseTime $timeZone $changeover]
+	    set date [GetJulianDayFromEraYearWeekDay $date[set date {}] \
+			 $changeover]
+	}
+
+	{ dayOfMonth } 6 {
+	    set date [AssignBaseMonth $date[set date {}] \
+			  $baseTime $timeZone $changeover]
+	    set date [GetJulianDayFromEraYearMonthDay $date[set date {}] \
+			  $changeover]
+	}
+
+	{ dayOfWeek } 7 {
+	    set date [AssignBaseWeek $date[set date {}] \
+			  $baseTime $timeZone $changeover]
+	    set date [GetJulianDayFromEraYearWeekDay $date[set date {}] \
+			 $changeover]
+	}
+
+	{} 8 {
+	    set date [AssignBaseJulianDay $date[set date {}] \
+			  $baseTime $timeZone $changeover]
+	}
+    }
+
+    # Groups of fields that specify time of day, priorities, and code that
+    # processes them
+
+    variable TimeParseActions {
+
+	seconds 1 {}
+
+	{ hourAMPM minute second amPmIndicator } 2 {
+	    dict set date secondOfDay [InterpretHMSP $date]
+	}
+	{ hour minute second } 2 {
+	    dict set date secondOfDay [InterpretHMS $date]
+	}
+
+	{ hourAMPM minute amPmIndicator } 3 {
+	    dict set date second 0
+	    dict set date secondOfDay [InterpretHMSP $date]
+	}
+	{ hour minute } 3 {
+	    dict set date second 0
+	    dict set date secondOfDay [InterpretHMS $date]
+	}
+
+	{ hourAMPM amPmIndicator } 4 {
+	    dict set date minute 0
+	    dict set date second 0
+	    dict set date secondOfDay [InterpretHMSP $date]
+	}
+	{ hour } 4 {
+	    dict set date minute 0
+	    dict set date second 0
+	    dict set date secondOfDay [InterpretHMS $date]
+	}
+
+	{ } 5 {
+	    dict set date secondOfDay 0
+	}
+    }
+
+    # Legacy time zones, used primarily for parsing RFC822 dates.
+
+    variable LegacyTimeZone [dict create \
+	gmt	+0000 \
+	ut	+0000 \
+	utc	+0000 \
+	bst	+0100 \
+	wet	+0000 \
+	wat	-0100 \
+	at	-0200 \
+	nft	-0330 \
+	nst	-0330 \
+	ndt	-0230 \
+	ast	-0400 \
+	adt	-0300 \
+	est	-0500 \
+	edt	-0400 \
+	cst	-0600 \
+	cdt	-0500 \
+	mst	-0700 \
+	mdt	-0600 \
+	pst	-0800 \
+	pdt	-0700 \
+	yst	-0900 \
+	ydt	-0800 \
+	hst	-1000 \
+	hdt	-0900 \
+	cat	-1000 \
+	ahst	-1000 \
+	nt	-1100 \
+	idlw	-1200 \
+	cet	+0100 \
+	cest	+0200 \
+	met	+0100 \
+	mewt	+0100 \
+	mest	+0200 \
+	swt	+0100 \
+	sst	+0200 \
+	fwt	+0100 \
+	fst	+0200 \
+	eet	+0200 \
+	eest	+0300 \
+	bt	+0300 \
+	it	+0330 \
+	zp4	+0400 \
+	zp5	+0500 \
+	ist	+0530 \
+	zp6	+0600 \
+	wast	+0700 \
+	wadt	+0800 \
+	jt	+0730 \
+	cct	+0800 \
+	jst	+0900 \
+	kst     +0900 \
+	cast	+0930 \
+        jdt     +1000 \
+        kdt     +1000 \
+	cadt	+1030 \
+	east	+1000 \
+	eadt	+1030 \
+	gst	+1000 \
+	nzt	+1200 \
+	nzst	+1200 \
+	nzdt	+1300 \
+	idle	+1200 \
+	a	+0100 \
+	b	+0200 \
+	c	+0300 \
+	d	+0400 \
+	e	+0500 \
+	f	+0600 \
+	g	+0700 \
+	h	+0800 \
+	i	+0900 \
+	k	+1000 \
+	l	+1100 \
+	m	+1200 \
+	n	-0100 \
+	o	-0200 \
+	p	-0300 \
+	q	-0400 \
+	r	-0500 \
+	s	-0600 \
+	t	-0700 \
+	u	-0800 \
+	v	-0900 \
+	w	-1000 \
+	x	-1100 \
+	y	-1200 \
+	z	+0000 \
+    ]
+
+    # Caches
+
+    variable LocaleNumeralCache {};	# Dictionary whose keys are locale
+					# names and whose values are pairs
+					# comprising regexes matching numerals
+					# in the given locales and dictionaries
+					# mapping the numerals to their numeric
+					# values.
+    # variable CachedSystemTimeZone;    # If 'CachedSystemTimeZone' exists,
+					# it contains the value of the
+					# system time zone, as determined from
+					# the environment.
+    variable TimeZoneBad {};	        # Dictionary whose keys are time zone
+    					# names and whose values are 1 if
+					# the time zone is unknown and 0
+    					# if it is known.
+    variable TZData;			# Array whose keys are time zone names
+					# and whose values are lists of quads
+					# comprising start time, UTC offset,
+					# Daylight Saving Time indicator, and
+					# time zone abbreviation.
+    variable FormatProc;		# Array mapping format group
+					# and locale to the name of a procedure
+					# that renders the given format
+}
+::tcl::clock::Initialize
+
+#----------------------------------------------------------------------
+#
+# clock format --
+#
+#	Formats a count of seconds since the Posix Epoch as a time of day.
+#
+# The 'clock format' command formats times of day for output.  Refer to the
+# user documentation to see what it does.
+#
+#----------------------------------------------------------------------
+
+proc ::tcl::clock::format { args } {
+
+    variable FormatProc
+    variable TZData
+
+    lassign [ParseFormatArgs {*}$args] format locale timezone
+    set locale [string tolower $locale]
+    set clockval [lindex $args 0]
+
+    # Get the data for time changes in the given zone
+
+    if {$timezone eq ""} {
+	set timezone [GetSystemTimeZone]
+    }
+    if {![info exists TZData($timezone)]} {
+	if {[catch {SetupTimeZone $timezone} retval opts]} {
+	    dict unset opts -errorinfo
+	    return -options $opts $retval
+	}
+    }
+
+    # Build a procedure to format the result. Cache the built procedure's name
+    # in the 'FormatProc' array to avoid losing its internal representation,
+    # which contains the name resolution.
+
+    set procName formatproc'$format'$locale
+    set procName [namespace current]::[string map {: {\:} \\ {\\}} $procName]
+    if {[info exists FormatProc($procName)]} {
+	set procName $FormatProc($procName)
+    } else {
+	set FormatProc($procName) \
+	    [ParseClockFormatFormat $procName $format $locale]
+    }
+
+    return [$procName $clockval $timezone]
+
+}
+
+#----------------------------------------------------------------------
+#
+# ParseClockFormatFormat --
+#
+#	Builds and caches a procedure that formats a time value.
+#
+# Parameters:
+#	format -- Format string to use
+#	locale -- Locale in which the format string is to be interpreted
+#
+# Results:
+#	Returns the name of the newly-built procedure.
+#
+#----------------------------------------------------------------------
+
+proc ::tcl::clock::ParseClockFormatFormat {procName format locale} {
+
+    if {[namespace which $procName] ne {}} {
+	return $procName
+    }
+
+    # Map away the locale-dependent composite format groups
+
+    EnterLocale $locale
+
+    # Change locale if a fresh locale has been given on the command line.
+
+    try {
+	return [ParseClockFormatFormat2 $format $locale $procName]
+    } trap CLOCK {result opts} {
+	dict unset opts -errorinfo
+	return -options $opts $result
+    }
+}
+
+proc ::tcl::clock::ParseClockFormatFormat2 {format locale procName} {
+    set didLocaleEra 0
+    set didLocaleNumerals 0
+    set preFormatCode \
+	[string map [list @GREGORIAN_CHANGE_DATE@ \
+				       [mc GREGORIAN_CHANGE_DATE]] \
+	     {
+		 variable TZData
+		 set date [GetDateFields $clockval \
+			       $TZData($timezone) \
+			       @GREGORIAN_CHANGE_DATE@]
+	     }]
+    set formatString {}
+    set substituents {}
+    set state {}
+
+    set format [LocalizeFormat $locale $format]
+
+    foreach char [split $format {}] {
+	switch -exact -- $state {
+	    {} {
+		if { [string equal % $char] } {
+		    set state percent
+		} else {
+		    append formatString $char
+		}
+	    }
+	    percent {			# Character following a '%' character
+		set state {}
+		switch -exact -- $char {
+		    % {			# A literal character, '%'
+			append formatString %%
+		    }
+		    a {			# Day of week, abbreviated
+			append formatString %s
+			append substituents \
+			    [string map \
+				 [list @DAYS_OF_WEEK_ABBREV@ \
+				      [list [mc DAYS_OF_WEEK_ABBREV]]] \
+				 { [lindex @DAYS_OF_WEEK_ABBREV@ \
+					[expr {[dict get $date dayOfWeek] \
+						   % 7}]]}]
+		    }
+		    A {			# Day of week, spelt out.
+			append formatString %s
+			append substituents \
+			    [string map \
+				 [list @DAYS_OF_WEEK_FULL@ \
+				      [list [mc DAYS_OF_WEEK_FULL]]] \
+				 { [lindex @DAYS_OF_WEEK_FULL@ \
+					[expr {[dict get $date dayOfWeek] \
+						   % 7}]]}]
+		    }
+		    b - h {		# Name of month, abbreviated.
+			append formatString %s
+			append substituents \
+			    [string map \
+				 [list @MONTHS_ABBREV@ \
+				      [list [mc MONTHS_ABBREV]]] \
+				 { [lindex @MONTHS_ABBREV@ \
+					[expr {[dict get $date month]-1}]]}]
+		    }
+		    B {			# Name of month, spelt out
+			append formatString %s
+			append substituents \
+			    [string map \
+				 [list @MONTHS_FULL@ \
+				      [list [mc MONTHS_FULL]]] \
+				 { [lindex @MONTHS_FULL@ \
+					[expr {[dict get $date month]-1}]]}]
+		    }
+		    C {			# Century number
+			append formatString %02d
+			append substituents \
+			    { [expr {[dict get $date year] / 100}]}
+		    }
+		    d {			# Day of month, with leading zero
+			append formatString %02d
+			append substituents { [dict get $date dayOfMonth]}
+		    }
+		    e {			# Day of month, without leading zero
+			append formatString %2d
+			append substituents { [dict get $date dayOfMonth]}
+		    }
+		    E {			# Format group in a locale-dependent
+					# alternative era
+			set state percentE
+			if {!$didLocaleEra} {
+			    append preFormatCode \
+				[string map \
+				     [list @LOCALE_ERAS@ \
+					  [list [mc LOCALE_ERAS]]] \
+				     {
+					 set date [GetLocaleEra \
+						       $date[set date {}] \
+						       @LOCALE_ERAS@]}] \n
+			    set didLocaleEra 1
+			}
+			if {!$didLocaleNumerals} {
+			    append preFormatCode \
+				[list set localeNumerals \
+				     [mc LOCALE_NUMERALS]] \n
+			    set didLocaleNumerals 1
+			}
+		    }
+		    g {			# Two-digit year relative to ISO8601
+					# week number
+			append formatString %02d
+			append substituents \
+			    { [expr { [dict get $date iso8601Year] % 100 }]}
+		    }
+		    G {			# Four-digit year relative to ISO8601
+					# week number
+			append formatString %02d
+			append substituents { [dict get $date iso8601Year]}
+		    }
+		    H {			# Hour in the 24-hour day, leading zero
+			append formatString %02d
+			append substituents \
+			    { [expr { [dict get $date localSeconds] \
+					  / 3600 % 24}]}
+		    }
+		    I {			# Hour AM/PM, with leading zero
+			append formatString %02d
+			append substituents \
+			    { [expr { ( ( ( [dict get $date localSeconds] \
+					    % 86400 ) \
+					  + 86400 \
+					  - 3600 ) \
+					/ 3600 ) \
+				      % 12 + 1 }] }
+		    }
+		    j {			# Day of year (001-366)
+			append formatString %03d
+			append substituents { [dict get $date dayOfYear]}
+		    }
+		    J {			# Julian Day Number
+			append formatString %07ld
+			append substituents { [dict get $date julianDay]}
+		    }
+		    k {			# Hour (0-23), no leading zero
+			append formatString %2d
+			append substituents \
+			    { [expr { [dict get $date localSeconds]
+				      / 3600
+				      % 24 }]}
+		    }
+		    l {			# Hour (12-11), no leading zero
+			append formatString %2d
+			append substituents \
+			    { [expr { ( ( ( [dict get $date localSeconds]
+					   % 86400 )
+					 + 86400
+					 - 3600 )
+				       / 3600 )
+				     % 12 + 1 }]}
+		    }
+		    m {			# Month number, leading zero
+			append formatString %02d
+			append substituents { [dict get $date month]}
+		    }
+		    M {			# Minute of the hour, leading zero
+			append formatString %02d
+			append substituents \
+			    { [expr { [dict get $date localSeconds]
+				      / 60
+				      % 60 }]}
+		    }
+		    n {			# A literal newline
+			append formatString \n
+		    }
+		    N {			# Month number, no leading zero
+			append formatString %2d
+			append substituents { [dict get $date month]}
+		    }
+		    O {			# A format group in the locale's
+					# alternative numerals
+			set state percentO
+			if {!$didLocaleNumerals} {
+			    append preFormatCode \
+				[list set localeNumerals \
+				     [mc LOCALE_NUMERALS]] \n
+			    set didLocaleNumerals 1
+			}
+		    }
+		    p {			# Localized 'AM' or 'PM' indicator
+					# converted to uppercase
+			append formatString %s
+			append preFormatCode \
+			    [list set AM [string toupper [mc AM]]] \n \
+			    [list set PM [string toupper [mc PM]]] \n
+			append substituents \
+			    { [expr {(([dict get $date localSeconds]
+				       % 86400) < 43200) ?
+				     $AM : $PM}]}
+		    }
+		    P {			# Localized 'AM' or 'PM' indicator
+			append formatString %s
+			append preFormatCode \
+			    [list set am [mc AM]] \n \
+			    [list set pm [mc PM]] \n
+			append substituents \
+			    { [expr {(([dict get $date localSeconds]
+				       % 86400) < 43200) ?
+				     $am : $pm}]}
+
+		    }
+		    Q {			# Hi, Jeff!
+			append formatString %s
+			append substituents { [FormatStarDate $date]}
+		    }
+		    s {			# Seconds from the Posix Epoch
+			append formatString %s
+			append substituents { [dict get $date seconds]}
+		    }
+		    S {			# Second of the minute, with
+			# leading zero
+			append formatString %02d
+			append substituents \
+			    { [expr { [dict get $date localSeconds]
+				      % 60 }]}
+		    }
+		    t {			# A literal tab character
+			append formatString \t
+		    }
+		    u {			# Day of the week (1-Monday, 7-Sunday)
+			append formatString %1d
+			append substituents { [dict get $date dayOfWeek]}
+		    }
+		    U {			# Week of the year (00-53). The
+					# first Sunday of the year is the
+					# first day of week 01
+			append formatString %02d
+			append preFormatCode {
+			    set dow [dict get $date dayOfWeek]
+			    if { $dow == 7 } {
+				set dow 0
+			    }
+			    incr dow
+			    set UweekNumber \
+				[expr { ( [dict get $date dayOfYear]
+					  - $dow + 7 )
+					/ 7 }]
+			}
+			append substituents { $UweekNumber}
+		    }
+		    V {			# The ISO8601 week number
+			append formatString %02d
+			append substituents { [dict get $date iso8601Week]}
+		    }
+		    w {			# Day of the week (0-Sunday,
+					# 6-Saturday)
+			append formatString %1d
+			append substituents \
+			    { [expr { [dict get $date dayOfWeek] % 7 }]}
+		    }
+		    W {			# Week of the year (00-53). The first
+					# Monday of the year is the first day
+					# of week 01.
+			append preFormatCode {
+			    set WweekNumber \
+				[expr { ( [dict get $date dayOfYear]
+					  - [dict get $date dayOfWeek]
+					  + 7 )
+					/ 7 }]
+			}
+			append formatString %02d
+			append substituents { $WweekNumber}
+		    }
+		    y {			# The two-digit year of the century
+			append formatString %02d
+			append substituents \
+			    { [expr { [dict get $date year] % 100 }]}
+		    }
+		    Y {			# The four-digit year
+			append formatString %04d
+			append substituents { [dict get $date year]}
+		    }
+		    z {			# The time zone as hours and minutes
+					# east (+) or west (-) of Greenwich
+			append formatString %s
+			append substituents { [FormatNumericTimeZone \
+						   [dict get $date tzOffset]]}
+		    }
+		    Z {			# The name of the time zone
+			append formatString %s
+			append substituents { [dict get $date tzName]}
+		    }
+		    % {			# A literal percent character
+			append formatString %%
+		    }
+		    default {		# An unknown escape sequence
+			append formatString %% $char
+		    }
+		}
+	    }
+	    percentE {			# Character following %E
+		set state {}
+		switch -exact -- $char {
+		    E {
+			append formatString %s
+			append substituents { } \
+			    [string map \
+				 [list @BCE@ [list [mc BCE]] \
+				      @CE@ [list [mc CE]]] \
+				      {[dict get {BCE @BCE@ CE @CE@} \
+					    [dict get $date era]]}]
+		    }
+		    C {			# Locale-dependent era
+			append formatString %s
+			append substituents { [dict get $date localeEra]}
+		    }
+		    y {			# Locale-dependent year of the era
+			append preFormatCode {
+			    set y [dict get $date localeYear]
+			    if { $y >= 0 && $y < 100 } {
+				set Eyear [lindex $localeNumerals $y]
+			    } else {
+				set Eyear $y
+			    }
+			}
+			append formatString %s
+			append substituents { $Eyear}
+		    }
+		    default {		# Unknown %E format group
+			append formatString %%E $char
+		    }
+		}
+	    }
+	    percentO {			# Character following %O
+		set state {}
+		switch -exact -- $char {
+		    d - e {		# Day of the month in alternative
+			# numerals
+			append formatString %s
+			append substituents \
+			    { [lindex $localeNumerals \
+				   [dict get $date dayOfMonth]]}
+		    }
+		    H - k {		# Hour of the day in alternative
+					# numerals
+			append formatString %s
+			append substituents \
+			    { [lindex $localeNumerals \
+				   [expr { [dict get $date localSeconds]
+					   / 3600
+					   % 24 }]]}
+		    }
+		    I - l {		# Hour (12-11) AM/PM in alternative
+					# numerals
+			append formatString %s
+			append substituents \
+			    { [lindex $localeNumerals \
+				   [expr { ( ( ( [dict get $date localSeconds]
+						 % 86400 )
+					       + 86400
+					       - 3600 )
+					     / 3600 )
+					   % 12 + 1 }]]}
+		    }
+		    m {			# Month number in alternative numerals
+			append formatString %s
+			append substituents \
+			    { [lindex $localeNumerals [dict get $date month]]}
+		    }
+		    M {			# Minute of the hour in alternative
+					# numerals
+			append formatString %s
+			append substituents \
+			    { [lindex $localeNumerals \
+				   [expr { [dict get $date localSeconds]
+					   / 60
+					   % 60 }]]}
+		    }
+		    S {			# Second of the minute in alternative
+					# numerals
+			append formatString %s
+			append substituents \
+			    { [lindex $localeNumerals \
+				   [expr { [dict get $date localSeconds]
+					   % 60 }]]}
+		    }
+		    u {			# Day of the week (Monday=1,Sunday=7)
+					# in alternative numerals
+			append formatString %s
+			append substituents \
+			    { [lindex $localeNumerals \
+				   [dict get $date dayOfWeek]]}
+			}
+		    w {			# Day of the week (Sunday=0,Saturday=6)
+					# in alternative numerals
+			append formatString %s
+			append substituents \
+			    { [lindex $localeNumerals \
+				   [expr { [dict get $date dayOfWeek] % 7 }]]}
+		    }
+		    y {			# Year of the century in alternative
+					# numerals
+			append formatString %s
+			append substituents \
+			    { [lindex $localeNumerals \
+				   [expr { [dict get $date year] % 100 }]]}
+		    }
+		    default {	# Unknown format group
+			append formatString %%O $char
+		    }
+		}
+	    }
+	}
+    }
+
+    # Clean up any improperly terminated groups
+
+    switch -exact -- $state {
+	percent {
+	    append formatString %%
+	}
+	percentE {
+	    append retval %%E
+	}
+	percentO {
+	    append retval %%O
+	}
+    }
+
+    proc $procName {clockval timezone} "
+        $preFormatCode
+        return \[::format [list $formatString] $substituents\]
+    "
+
+    #    puts [list $procName [info args $procName] [info body $procName]]
+
+    return $procName
+}
+
+#----------------------------------------------------------------------
+#
+# clock scan --
+#
+#	Inputs a count of seconds since the Posix Epoch as a time of day.
+#
+# The 'clock format' command scans times of day on input.  Refer to the user
+# documentation to see what it does.
+#
+#----------------------------------------------------------------------
+
+proc ::tcl::clock::scan { args } {
+
+    set format {}
+
+    # Check the count of args
+
+    if { [llength $args] < 1 || [llength $args] % 2 != 1 } {
+	set cmdName "clock scan"
+	return -code error \
+	    -errorcode [list CLOCK wrongNumArgs] \
+	    "wrong \# args: should be\
+             \"$cmdName string\
+             ?-base seconds?\
+             ?-format string? ?-gmt boolean?\
+             ?-locale LOCALE? ?-timezone ZONE?\""
+    }
+
+    # Set defaults
+
+    set base [clock seconds]
+    set string [lindex $args 0]
+    set format {}
+    set gmt 0
+    set locale c
+    set timezone [GetSystemTimeZone]
+
+    # Pick up command line options.
+
+    foreach { flag value } [lreplace $args 0 0] {
+	set saw($flag) {}
+	switch -exact -- $flag {
+	    -b - -ba - -bas - -base {
+		set base $value
+	    }
+	    -f - -fo - -for - -form - -forma - -format {
+		set format $value
+	    }
+	    -g - -gm - -gmt {
+		set gmt $value
+	    }
+	    -l - -lo - -loc - -loca - -local - -locale {
+		set locale [string tolower $value]
+	    }
+	    -t - -ti - -tim - -time - -timez - -timezo - -timezon - -timezone {
+		set timezone $value
+	    }
+	    default {
+		return -code error \
+		    -errorcode [list CLOCK badOption $flag] \
+		    "bad option \"$flag\",\
+                     must be -base, -format, -gmt, -locale or -timezone"
+	    }
+	}
+    }
+
+    # Check options for validity
+
+    if { [info exists saw(-gmt)] && [info exists saw(-timezone)] } {
+	return -code error \
+	    -errorcode [list CLOCK gmtWithTimezone] \
+	    "cannot use -gmt and -timezone in same call"
+    }
+    if { [catch { expr { wide($base) } } result] } {
+	return -code error "expected integer but got \"$base\""
+    }
+    if { ![string is boolean -strict $gmt] } {
+	return -code error "expected boolean value but got \"$gmt\""
+    } elseif { $gmt } {
+	set timezone :GMT
+    }
+
+    if { ![info exists saw(-format)] } {
+	# Perhaps someday we'll localize the legacy code. Right now, it's not
+	# localized.
+	if { [info exists saw(-locale)] } {
+	    return -code error \
+		-errorcode [list CLOCK flagWithLegacyFormat] \
+		"legacy \[clock scan\] does not support -locale"
+
+	}
+	return [FreeScan $string $base $timezone $locale]
+    }
+
+    # Change locale if a fresh locale has been given on the command line.
+
+    EnterLocale $locale
+
+    try {
+	# Map away the locale-dependent composite format groups
+
+	set scanner [ParseClockScanFormat $format $locale]
+	return [$scanner $string $base $timezone]
+    } trap CLOCK {result opts} {
+	# Conceal location of generation of expected errors
+	dict unset opts -errorinfo
+	return -options $opts $result
+    }
+}
+
+#----------------------------------------------------------------------
+#
+# FreeScan --
+#
+#	Scans a time in free format
+#
+# Parameters:
+#	string - String containing the time to scan
+#	base - Base time, expressed in seconds from the Epoch
+#	timezone - Default time zone in which the time will be expressed
+#	locale - (Unused) Name of the locale where the time will be scanned.
+#
+# Results:
+#	Returns the date and time extracted from the string in seconds from
+#	the epoch
+#
+#----------------------------------------------------------------------
+
+proc ::tcl::clock::FreeScan { string base timezone locale } {
+
+    variable TZData
+
+    # Get the data for time changes in the given zone
+
+    try {
+	SetupTimeZone $timezone
+    } on error {retval opts} {
+	dict unset opts -errorinfo
+	return -options $opts $retval
+    }
+
+    # Extract year, month and day from the base time for the parser to use as
+    # defaults
+
+    set date [GetDateFields $base $TZData($timezone) 2361222]
+    dict set date secondOfDay [expr {
+	[dict get $date localSeconds] % 86400
+    }]
+
+    # Parse the date.  The parser will return a list comprising date, time,
+    # time zone, relative month/day/seconds, relative weekday, ordinal month.
+
+    try {
+	set scanned [Oldscan $string \
+		     [dict get $date year] \
+		     [dict get $date month] \
+		     [dict get $date dayOfMonth]]
+	lassign $scanned \
+	    parseDate parseTime parseZone parseRel \
+	    parseWeekday parseOrdinalMonth
+    } on error message {
+	return -code error \
+	    "unable to convert date-time string \"$string\": $message"
+    }
+
+    # If the caller supplied a date in the string, update the 'date' dict with
+    # the value. If the caller didn't specify a time with the date, default to
+    # midnight.
+
+    if { [llength $parseDate] > 0 } {
+	lassign $parseDate y m d
+	if { $y < 100 } {
+	    if { $y >= 39 } {
+		incr y 1900
+	    } else {
+		incr y 2000
+	    }
+	}
+	dict set date era CE
+	dict set date year $y
+	dict set date month $m
+	dict set date dayOfMonth $d
+	if { $parseTime eq {} } {
+	    set parseTime 0
+	}
+    }
+
+    # If the caller supplied a time zone in the string, it comes back as a
+    # two-element list; the first element is the number of minutes east of
+    # Greenwich, and the second is a Daylight Saving Time indicator (1 == yes,
+    # 0 == no, -1 == unknown). We make it into a time zone indicator of
+    # +-hhmm.
+
+    if { [llength $parseZone] > 0 } {
+	lassign $parseZone minEast dstFlag
+	set timezone [FormatNumericTimeZone \
+			  [expr { 60 * $minEast + 3600 * $dstFlag }]]
+	SetupTimeZone $timezone
+    }
+    dict set date tzName $timezone
+
+    # Assemble date, time, zone into seconds-from-epoch
+
+    set date [GetJulianDayFromEraYearMonthDay $date[set date {}] 2361222]
+    if { $parseTime ne {} } {
+	dict set date secondOfDay $parseTime
+    } elseif { [llength $parseWeekday] != 0
+	       || [llength $parseOrdinalMonth] != 0
+	       || ( [llength $parseRel] != 0
+		    && ( [lindex $parseRel 0] != 0
+			 || [lindex $parseRel 1] != 0 ) ) } {
+	dict set date secondOfDay 0
+    }
+
+    dict set date localSeconds [expr {
+	-210866803200
+	+ ( 86400 * wide([dict get $date julianDay]) )
+	+ [dict get $date secondOfDay]
+    }]
+    dict set date tzName $timezone
+    set date [ConvertLocalToUTC $date[set date {}] $TZData($timezone) 2361222]
+    set seconds [dict get $date seconds]
+
+    # Do relative times
+
+    if { [llength $parseRel] > 0 } {
+	lassign $parseRel relMonth relDay relSecond
+	set seconds [add $seconds \
+			 $relMonth months $relDay days $relSecond seconds \
+			 -timezone $timezone -locale $locale]
+    }
+
+    # Do relative weekday
+
+    if { [llength $parseWeekday] > 0 } {
+	lassign $parseWeekday dayOrdinal dayOfWeek
+	set date2 [GetDateFields $seconds $TZData($timezone) 2361222]
+	dict set date2 era CE
+	set jdwkday [WeekdayOnOrBefore $dayOfWeek [expr {
+	    [dict get $date2 julianDay] + 6
+	}]]
+	incr jdwkday [expr { 7 * $dayOrdinal }]
+	if { $dayOrdinal > 0 } {
+	    incr jdwkday -7
+	}
+	dict set date2 secondOfDay \
+	    [expr { [dict get $date2 localSeconds] % 86400 }]
+	dict set date2 julianDay $jdwkday
+	dict set date2 localSeconds [expr {
+	    -210866803200
+	    + ( 86400 * wide([dict get $date2 julianDay]) )
+	    + [dict get $date secondOfDay]
+	}]
+	dict set date2 tzName $timezone
+	set date2 [ConvertLocalToUTC $date2[set date2 {}] $TZData($timezone) \
+		       2361222]
+	set seconds [dict get $date2 seconds]
+
+    }
+
+    # Do relative month
+
+    if { [llength $parseOrdinalMonth] > 0 } {
+	lassign $parseOrdinalMonth monthOrdinal monthNumber
+	if { $monthOrdinal > 0 } {
+	    set monthDiff [expr { $monthNumber - [dict get $date month] }]
+	    if { $monthDiff <= 0 } {
+		incr monthDiff 12
+	    }
+	    incr monthOrdinal -1
+	} else {
+	    set monthDiff [expr { [dict get $date month] - $monthNumber }]
+	    if { $monthDiff >= 0 } {
+		incr monthDiff -12
+	    }
+	    incr monthOrdinal
+	}
+	set seconds [add $seconds $monthOrdinal years $monthDiff months \
+			 -timezone $timezone -locale $locale]
+    }
+
+    return $seconds
+}
+
+
+#----------------------------------------------------------------------
+#
+# ParseClockScanFormat --
+#
+#	Parses a format string given to [clock scan -format]
+#
+# Parameters:
+#	formatString - The format being parsed
+#	locale - The current locale
+#
+# Results:
+#	Constructs and returns a procedure that accepts the string being
+#	scanned, the base time, and the time zone.  The procedure will either
+#	return the scanned time or else throw an error that should be rethrown
+#	to the caller of [clock scan]
+#
+# Side effects:
+#	The given procedure is defined in the ::tcl::clock namespace.  Scan
+#	procedures are not deleted once installed.
+#
+# Why do we parse dates by defining a procedure to parse them?  The reason is
+# that by doing so, we have one convenient place to cache all the information:
+# the regular expressions that match the patterns (which will be compiled),
+# the code that assembles the date information, everything lands in one place.
+# In this way, when a given format is reused at run time, all the information
+# of how to apply it is available in a single place.
+#
+#----------------------------------------------------------------------
+
+proc ::tcl::clock::ParseClockScanFormat {formatString locale} {
+    # Check whether the format has been parsed previously, and return the
+    # existing recognizer if it has.
+
+    set procName scanproc'$formatString'$locale
+    set procName [namespace current]::[string map {: {\:} \\ {\\}} $procName]
+    if { [namespace which $procName] != {} } {
+	return $procName
+    }
+
+    variable DateParseActions
+    variable TimeParseActions
+
+    # Localize the %x, %X, etc. groups
+
+    set formatString [LocalizeFormat $locale $formatString]
+
+    # Condense whitespace
+
+    regsub -all {[[:space:]]+} $formatString { } formatString
+
+    # Walk through the groups of the format string.  In this loop, we
+    # accumulate:
+    #	- a regular expression that matches the string,
+    #   - the count of capturing brackets in the regexp
+    #   - a set of code that post-processes the fields captured by the regexp,
+    #   - a dictionary whose keys are the names of fields that are present
+    #     in the format string.
+
+    set re {^[[:space:]]*}
+    set captureCount 0
+    set postcode {}
+    set fieldSet [dict create]
+    set fieldCount 0
+    set postSep {}
+    set state {}
+
+    foreach c [split $formatString {}] {
+	switch -exact -- $state {
+	    {} {
+		if { $c eq "%" } {
+		    set state %
+		} elseif { $c eq " " } {
+		    append re {[[:space:]]+}
+		} else {
+		    if { ! [string is alnum $c] } {
+			append re "\\"
+		    }
+		    append re $c
+		}
+	    }
+	    % {
+		set state {}
+		switch -exact -- $c {
+		    % {
+			append re %
+		    }
+		    { } {
+			append re "\[\[:space:\]\]*"
+		    }
+		    a - A { 		# Day of week, in words
+			set l {}
+			foreach \
+			    i {7 1 2 3 4 5 6} \
+			    abr [mc DAYS_OF_WEEK_ABBREV] \
+			    full [mc DAYS_OF_WEEK_FULL] {
+				dict set l [string tolower $abr] $i
+				dict set l [string tolower $full] $i
+				incr i
+			    }
+			lassign [UniquePrefixRegexp $l] regex lookup
+			append re ( $regex )
+			dict set fieldSet dayOfWeek [incr fieldCount]
+			append postcode "dict set date dayOfWeek \[" \
+			    "dict get " [list $lookup] " " \
+			    \[ {string tolower $field} [incr captureCount] \] \
+			    "\]\n"
+		    }
+		    b - B - h {		# Name of month
+			set i 0
+			set l {}
+			foreach \
+			    abr [mc MONTHS_ABBREV] \
+			    full [mc MONTHS_FULL] {
+				incr i
+				dict set l [string tolower $abr] $i
+				dict set l [string tolower $full] $i
+			    }
+			lassign [UniquePrefixRegexp $l] regex lookup
+			append re ( $regex )
+			dict set fieldSet month [incr fieldCount]
+			append postcode "dict set date month \[" \
+			    "dict get " [list $lookup] \
+			    " " \[ {string tolower $field} \
+			    [incr captureCount] \] \
+			    "\]\n"
+		    }
+		    C {			# Gregorian century
+			append re \\s*(\\d\\d?)
+			dict set fieldSet century [incr fieldCount]
+			append postcode "dict set date century \[" \
+			    "::scan \$field" [incr captureCount] " %d" \
+			    "\]\n"
+		    }
+		    d - e {		# Day of month
+			append re \\s*(\\d\\d?)
+			dict set fieldSet dayOfMonth [incr fieldCount]
+			append postcode "dict set date dayOfMonth \[" \
+			    "::scan \$field" [incr captureCount] " %d" \
+			    "\]\n"
+		    }
+		    E {			# Prefix for locale-specific codes
+			set state %E
+		    }
+		    g {			# ISO8601 2-digit year
+			append re \\s*(\\d\\d)
+			dict set fieldSet iso8601YearOfCentury \
+			    [incr fieldCount]
+			append postcode \
+			    "dict set date iso8601YearOfCentury \[" \
+			    "::scan \$field" [incr captureCount] " %d" \
+			    "\]\n"
+		    }
+		    G {			# ISO8601 4-digit year
+			append re \\s*(\\d\\d)(\\d\\d)
+			dict set fieldSet iso8601Century [incr fieldCount]
+			dict set fieldSet iso8601YearOfCentury \
+			    [incr fieldCount]
+			append postcode \
+			    "dict set date iso8601Century \[" \
+			    "::scan \$field" [incr captureCount] " %d" \
+			    "\]\n" \
+			    "dict set date iso8601YearOfCentury \[" \
+			    "::scan \$field" [incr captureCount] " %d" \
+			    "\]\n"
+		    }
+		    H - k {		# Hour of day
+			append re \\s*(\\d\\d?)
+			dict set fieldSet hour [incr fieldCount]
+			append postcode "dict set date hour \[" \
+			    "::scan \$field" [incr captureCount] " %d" \
+			    "\]\n"
+		    }
+		    I - l {		# Hour, AM/PM
+			append re \\s*(\\d\\d?)
+			dict set fieldSet hourAMPM [incr fieldCount]
+			append postcode "dict set date hourAMPM \[" \
+			    "::scan \$field" [incr captureCount] " %d" \
+			    "\]\n"
+		    }
+		    j {			# Day of year
+			append re \\s*(\\d\\d?\\d?)
+			dict set fieldSet dayOfYear [incr fieldCount]
+			append postcode "dict set date dayOfYear \[" \
+			    "::scan \$field" [incr captureCount] " %d" \
+			    "\]\n"
+		    }
+		    J {			# Julian Day Number
+			append re \\s*(\\d+)
+			dict set fieldSet julianDay [incr fieldCount]
+			append postcode "dict set date julianDay \[" \
+			    "::scan \$field" [incr captureCount] " %ld" \
+			    "\]\n"
+		    }
+		    m - N {		# Month number
+			append re \\s*(\\d\\d?)
+			dict set fieldSet month [incr fieldCount]
+			append postcode "dict set date month \[" \
+			    "::scan \$field" [incr captureCount] " %d" \
+			    "\]\n"
+		    }
+		    M {			# Minute
+			append re \\s*(\\d\\d?)
+			dict set fieldSet minute [incr fieldCount]
+			append postcode "dict set date minute \[" \
+			    "::scan \$field" [incr captureCount] " %d" \
+			    "\]\n"
+		    }
+		    n {			# Literal newline
+			append re \\n
+		    }
+		    O {			# Prefix for locale numerics
+			set state %O
+		    }
+		    p - P { 		# AM/PM indicator
+			set l [list [string tolower [mc AM]] 0 \
+				   [string tolower [mc PM]] 1]
+			lassign [UniquePrefixRegexp $l] regex lookup
+			append re ( $regex )
+			dict set fieldSet amPmIndicator [incr fieldCount]
+			append postcode "dict set date amPmIndicator \[" \
+			    "dict get " [list $lookup] " \[string tolower " \
+			    "\$field" \
+			    [incr captureCount] \
+			    "\]\]\n"
+		    }
+		    Q {			# Hi, Jeff!
+			append re {Stardate\s+([-+]?\d+)(\d\d\d)[.](\d)}
+			incr captureCount
+			dict set fieldSet seconds [incr fieldCount]
+			append postcode {dict set date seconds } \[ \
+			    {ParseStarDate $field} [incr captureCount] \
+			    { $field} [incr captureCount] \
+			    { $field} [incr captureCount] \
+			    \] \n
+		    }
+		    s {			# Seconds from Posix Epoch
+			# This next case is insanely difficult, because it's
+			# problematic to determine whether the field is
+			# actually within the range of a wide integer.
+			append re {\s*([-+]?\d+)}
+			dict set fieldSet seconds [incr fieldCount]
+			append postcode {dict set date seconds } \[ \
+			    {ScanWide $field} [incr captureCount] \] \n
+		    }
+		    S {			# Second
+			append re \\s*(\\d\\d?)
+			dict set fieldSet second [incr fieldCount]
+			append postcode "dict set date second \[" \
+			    "::scan \$field" [incr captureCount] " %d" \
+			    "\]\n"
+		    }
+		    t {			# Literal tab character
+			append re \\t
+		    }
+		    u - w {		# Day number within week, 0 or 7 == Sun
+					# 1=Mon, 6=Sat
+			append re \\s*(\\d)
+			dict set fieldSet dayOfWeek [incr fieldCount]
+			append postcode {::scan $field} [incr captureCount] \
+			    { %d dow} \n \
+			    {
+				if { $dow == 0 } {
+				    set dow 7
+				} elseif { $dow > 7 } {
+				    return -code error \
+					-errorcode [list CLOCK badDayOfWeek] \
+					"day of week is greater than 7"
+				}
+				dict set date dayOfWeek $dow
+			    }
+		    }
+		    U {			# Week of year. The first Sunday of
+					# the year is the first day of week
+					# 01. No scan rule uses this group.
+			append re \\s*\\d\\d?
+		    }
+		    V {			# Week of ISO8601 year
+
+			append re \\s*(\\d\\d?)
+			dict set fieldSet iso8601Week [incr fieldCount]
+			append postcode "dict set date iso8601Week \[" \
+			    "::scan \$field" [incr captureCount] " %d" \
+			    "\]\n"
+		    }
+		    W {			# Week of the year (00-53). The first
+					# Monday of the year is the first day
+					# of week 01. No scan rule uses this
+					# group.
+			append re \\s*\\d\\d?
+		    }
+		    y {			# Two-digit Gregorian year
+			append re \\s*(\\d\\d?)
+			dict set fieldSet yearOfCentury [incr fieldCount]
+			append postcode "dict set date yearOfCentury \[" \
+			    "::scan \$field" [incr captureCount] " %d" \
+			    "\]\n"
+		    }
+		    Y {			# 4-digit Gregorian year
+			append re \\s*(\\d\\d)(\\d\\d)
+			dict set fieldSet century [incr fieldCount]
+			dict set fieldSet yearOfCentury [incr fieldCount]
+			append postcode \
+			    "dict set date century \[" \
+			    "::scan \$field" [incr captureCount] " %d" \
+			    "\]\n" \
+			    "dict set date yearOfCentury \[" \
+			    "::scan \$field" [incr captureCount] " %d" \
+			    "\]\n"
+		    }
+		    z - Z {			# Time zone name
+			append re {(?:([-+]\d\d(?::?\d\d(?::?\d\d)?)?)|([[:alnum:]]{1,4}))}
+			dict set fieldSet tzName [incr fieldCount]
+			append postcode \
+			    {if } \{ { $field} [incr captureCount] \
+			    { ne "" } \} { } \{ \n \
+			    {dict set date tzName $field} \
+			    $captureCount \n \
+			    \} { else } \{ \n \
+			    {dict set date tzName } \[ \
+			    {ConvertLegacyTimeZone $field} \
+			    [incr captureCount] \] \n \
+			    \} \n \
+		    }
+		    % {			# Literal percent character
+			append re %
+		    }
+		    default {
+			append re %
+			if { ! [string is alnum $c] } {
+			    append re \\
+			    }
+			append re $c
+		    }
+		}
+	    }
+	    %E {
+		switch -exact -- $c {
+		    C {			# Locale-dependent era
+			set d {}
+			foreach triple [mc LOCALE_ERAS] {
+			    lassign $triple t symbol year
+			    dict set d [string tolower $symbol] $year
+			}
+			lassign [UniquePrefixRegexp $d] regex lookup
+			append re (?: $regex )
+		    }
+		    E {
+			set l {}
+			dict set l [string tolower [mc BCE]] BCE
+			dict set l [string tolower [mc CE]] CE
+			dict set l b.c.e. BCE
+			dict set l c.e. CE
+			dict set l b.c. BCE
+			dict set l a.d. CE
+			lassign [UniquePrefixRegexp $l] regex lookup
+			append re ( $regex )
+			dict set fieldSet era [incr fieldCount]
+			append postcode "dict set date era \["\
+			    "dict get " [list $lookup] \
+			    { } \[ {string tolower $field} \
+			    [incr captureCount] \] \
+			    "\]\n"
+		    }
+		    y {			# Locale-dependent year of the era
+			lassign [LocaleNumeralMatcher $locale] regex lookup
+			append re $regex
+			incr captureCount
+		    }
+		    default {
+			append re %E
+			if { ! [string is alnum $c] } {
+			    append re \\
+			    }
+			append re $c
+		    }
+		}
+		set state {}
+	    }
+	    %O {
+		switch -exact -- $c {
+		    d - e {
+			lassign [LocaleNumeralMatcher $locale] regex lookup
+			append re $regex
+			dict set fieldSet dayOfMonth [incr fieldCount]
+			append postcode "dict set date dayOfMonth \[" \
+			    "dict get " [list $lookup] " \$field" \
+			    [incr captureCount] \
+			    "\]\n"
+		    }
+		    H - k {
+			lassign [LocaleNumeralMatcher $locale] regex lookup
+			append re $regex
+			dict set fieldSet hour [incr fieldCount]
+			append postcode "dict set date hour \[" \
+			    "dict get " [list $lookup] " \$field" \
+			    [incr captureCount] \
+			    "\]\n"
+		    }
+		    I - l {
+			lassign [LocaleNumeralMatcher $locale] regex lookup
+			append re $regex
+			dict set fieldSet hourAMPM [incr fieldCount]
+			append postcode "dict set date hourAMPM \[" \
+			    "dict get " [list $lookup] " \$field" \
+			    [incr captureCount] \
+			    "\]\n"
+		    }
+		    m {
+			lassign [LocaleNumeralMatcher $locale] regex lookup
+			append re $regex
+			dict set fieldSet month [incr fieldCount]
+			append postcode "dict set date month \[" \
+			    "dict get " [list $lookup] " \$field" \
+			    [incr captureCount] \
+			    "\]\n"
+		    }
+		    M {
+			lassign [LocaleNumeralMatcher $locale] regex lookup
+			append re $regex
+			dict set fieldSet minute [incr fieldCount]
+			append postcode "dict set date minute \[" \
+			    "dict get " [list $lookup] " \$field" \
+			    [incr captureCount] \
+			    "\]\n"
+		    }
+		    S {
+			lassign [LocaleNumeralMatcher $locale] regex lookup
+			append re $regex
+			dict set fieldSet second [incr fieldCount]
+			append postcode "dict set date second \[" \
+			    "dict get " [list $lookup] " \$field" \
+			    [incr captureCount] \
+			    "\]\n"
+		    }
+		    u - w {
+			lassign [LocaleNumeralMatcher $locale] regex lookup
+			append re $regex
+			dict set fieldSet dayOfWeek [incr fieldCount]
+			append postcode "set dow \[dict get " [list $lookup] \
+			    { $field} [incr captureCount] \] \n \
+			    {
+				if { $dow == 0 } {
+				    set dow 7
+				} elseif { $dow > 7 } {
+				    return -code error \
+					-errorcode [list CLOCK badDayOfWeek] \
+					"day of week is greater than 7"
+				}
+				dict set date dayOfWeek $dow
+			    }
+		    }
+		    y {
+			lassign [LocaleNumeralMatcher $locale] regex lookup
+			append re $regex
+			dict set fieldSet yearOfCentury [incr fieldCount]
+			append postcode {dict set date yearOfCentury } \[ \
+			    {dict get } [list $lookup] { $field} \
+			    [incr captureCount] \] \n
+		    }
+		    default {
+			append re %O
+			if { ! [string is alnum $c] } {
+			    append re \\
+			    }
+			append re $c
+		    }
+		}
+		set state {}
+	    }
+	}
+    }
+
+    # Clean up any unfinished format groups
+
+    append re $state \\s*\$
+
+    # Build the procedure
+
+    set procBody {}
+    append procBody "variable ::tcl::clock::TZData" \n
+    append procBody "if \{ !\[ regexp -nocase [list $re] \$string ->"
+    for { set i 1 } { $i <= $captureCount } { incr i } {
+	append procBody " " field $i
+    }
+    append procBody "\] \} \{" \n
+    append procBody {
+	return -code error -errorcode [list CLOCK badInputString] \
+	    {input string does not match supplied format}
+    }
+    append procBody \}\n
+    append procBody "set date \[dict create\]" \n
+    append procBody {dict set date tzName $timeZone} \n
+    append procBody $postcode
+    append procBody [list set changeover [mc GREGORIAN_CHANGE_DATE]] \n
+
+    # Set up the time zone before doing anything with a default base date
+    # that might need a timezone to interpret it.
+
+    if { ![dict exists $fieldSet seconds]
+	    && ![dict exists $fieldSet starDate] } {
+	if { [dict exists $fieldSet tzName] } {
+	    append procBody {
+		set timeZone [dict get $date tzName]
+	    }
+	}
+	append procBody {
+	    ::tcl::clock::SetupTimeZone $timeZone
+	}
+    }
+
+    # Add code that gets Julian Day Number from the fields.
+
+    append procBody [MakeParseCodeFromFields $fieldSet $DateParseActions]
+
+    # Get time of day
+
+    append procBody [MakeParseCodeFromFields $fieldSet $TimeParseActions]
+
+    # Assemble seconds from the Julian day and second of the day.
+    # Convert to local time unless epoch seconds or stardate are
+    # being processed - they're always absolute
+
+    if { ![dict exists $fieldSet seconds]
+         && ![dict exists $fieldSet starDate] } {
+	append procBody {
+	    if { [dict get $date julianDay] > 5373484 } {
+		return -code error -errorcode [list CLOCK dateTooLarge] \
+		    "requested date too large to represent"
+	    }
+	    dict set date localSeconds [expr {
+		-210866803200
+		+ ( 86400 * wide([dict get $date julianDay]) )
+		+ [dict get $date secondOfDay]
+	    }]
+	}
+
+	# Finally, convert the date to local time
+
+	append procBody {
+	    set date [::tcl::clock::ConvertLocalToUTC $date[set date {}] \
+			  $TZData($timeZone) $changeover]
+	}
+    }
+
+    # Return result
+
+    append procBody {return [dict get $date seconds]} \n
+
+    proc $procName { string baseTime timeZone } $procBody
+
+    # puts [list proc $procName [list string baseTime timeZone] $procBody]
+
+    return $procName
+}
+
+#----------------------------------------------------------------------
+#
+# LocaleNumeralMatcher --
+#
+#	Composes a regexp that captures the numerals in the given locale, and
+#	a dictionary to map them to conventional numerals.
+#
+# Parameters:
+#	locale - Name of the current locale
+#
+# Results:
+#	Returns a two-element list comprising the regexp and the dictionary.
+#
+# Side effects:
+#	Caches the result.
+#
+#----------------------------------------------------------------------
+
+proc ::tcl::clock::LocaleNumeralMatcher {l} {
+    variable LocaleNumeralCache
+
+    if { ![dict exists $LocaleNumeralCache $l] } {
+	set d {}
+	set i 0
+	set sep \(
+	foreach n [mc LOCALE_NUMERALS] {
+	    dict set d $n $i
+	    regsub -all {[^[:alnum:]]} $n \\\\& subex
+	    append re $sep $subex
+	    set sep |
+	    incr i
+	}
+	append re \)
+	dict set LocaleNumeralCache $l [list $re $d]
+    }
+    return [dict get $LocaleNumeralCache $l]
+}
+
+
+
+#----------------------------------------------------------------------
+#
+# UniquePrefixRegexp --
+#
+#	Composes a regexp that performs unique-prefix matching.  The RE
+#	matches one of a supplied set of strings, or any unique prefix
+#	thereof.
+#
+# Parameters:
+#	data - List of alternating match-strings and values.
+#	       Match-strings with distinct values are considered
+#	       distinct.
+#
+# Results:
+#	Returns a two-element list.  The first is a regexp that matches any
+#	unique prefix of any of the strings.  The second is a dictionary whose
+#	keys are match values from the regexp and whose values are the
+#	corresponding values from 'data'.
+#
+# Side effects:
+#	None.
+#
+#----------------------------------------------------------------------
+
+proc ::tcl::clock::UniquePrefixRegexp { data } {
+    # The 'successors' dictionary will contain, for each string that is a
+    # prefix of any key, all characters that may follow that prefix.  The
+    # 'prefixMapping' dictionary will have keys that are prefixes of keys and
+    # values that correspond to the keys.
+
+    set prefixMapping [dict create]
+    set successors [dict create {} {}]
+
+    # Walk the key-value pairs
+
+    foreach { key value } $data {
+	# Construct all prefixes of the key;
+
+	set prefix {}
+	foreach char [split $key {}] {
+	    set oldPrefix $prefix
+	    dict set successors $oldPrefix $char {}
+	    append prefix $char
+
+	    # Put the prefixes in the 'prefixMapping' and 'successors'
+	    # dictionaries
+
+	    dict lappend prefixMapping $prefix $value
+	    if { ![dict exists $successors $prefix] } {
+		dict set successors $prefix {}
+	    }
+	}
+    }
+
+    # Identify those prefixes that designate unique values, and those that are
+    # the full keys
+
+    set uniquePrefixMapping {}
+    dict for { key valueList } $prefixMapping {
+	if { [llength $valueList] == 1 } {
+	    dict set uniquePrefixMapping $key [lindex $valueList 0]
+	}
+    }
+    foreach { key value } $data {
+	dict set uniquePrefixMapping $key $value
+    }
+
+    # Construct the re.
+
+    return [list \
+		[MakeUniquePrefixRegexp $successors $uniquePrefixMapping {}] \
+		$uniquePrefixMapping]
+}
+
+#----------------------------------------------------------------------
+#
+# MakeUniquePrefixRegexp --
+#
+#	Service procedure for 'UniquePrefixRegexp' that constructs a regular
+#	expresison that matches the unique prefixes.
+#
+# Parameters:
+#	successors - Dictionary whose keys are all prefixes
+#		     of keys passed to 'UniquePrefixRegexp' and whose
+#		     values are dictionaries whose keys are the characters
+#		     that may follow those prefixes.
+#	uniquePrefixMapping - Dictionary whose keys are the unique
+#			      prefixes and whose values are not examined.
+#	prefixString - Current prefix being processed.
+#
+# Results:
+#	Returns a constructed regular expression that matches the set of
+#	unique prefixes beginning with the 'prefixString'.
+#
+# Side effects:
+#	None.
+#
+#----------------------------------------------------------------------
+
+proc ::tcl::clock::MakeUniquePrefixRegexp { successors
+					  uniquePrefixMapping
+					  prefixString } {
+
+    # Get the characters that may follow the current prefix string
+
+    set schars [lsort -ascii [dict keys [dict get $successors $prefixString]]]
+    if { [llength $schars] == 0 } {
+	return {}
+    }
+
+    # If there is more than one successor character, or if the current prefix
+    # is a unique prefix, surround the generated re with non-capturing
+    # parentheses.
+
+    set re {}
+    if {
+	[dict exists $uniquePrefixMapping $prefixString]
+	|| [llength $schars] > 1
+    } then {
+	append re "(?:"
+    }
+
+    # Generate a regexp that matches the successors.
+
+    set sep ""
+    foreach { c } $schars {
+	set nextPrefix $prefixString$c
+	regsub -all {[^[:alnum:]]} $c \\\\& rechar
+	append re $sep $rechar \
+	    [MakeUniquePrefixRegexp \
+		 $successors $uniquePrefixMapping $nextPrefix]
+	set sep |
+    }
+
+    # If the current prefix is a unique prefix, make all following text
+    # optional. Otherwise, if there is more than one successor character,
+    # close the non-capturing parentheses.
+
+    if { [dict exists $uniquePrefixMapping $prefixString] } {
+	append re ")?"
+    } elseif { [llength $schars] > 1 } {
+	append re ")"
+    }
+
+    return $re
+}
+
+#----------------------------------------------------------------------
+#
+# MakeParseCodeFromFields --
+#
+#	Composes Tcl code to extract the Julian Day Number from a dictionary
+#	containing date fields.
+#
+# Parameters:
+#	dateFields -- Dictionary whose keys are fields of the date,
+#	              and whose values are the rightmost positions
+#		      at which those fields appear.
+#	parseActions -- List of triples: field set, priority, and
+#			code to emit.  Smaller priorities are better, and
+#			the list must be in ascending order by priority
+#
+# Results:
+#	Returns a burst of code that extracts the day number from the given
+#	date.
+#
+# Side effects:
+#	None.
+#
+#----------------------------------------------------------------------
+
+proc ::tcl::clock::MakeParseCodeFromFields { dateFields parseActions } {
+
+    set currPrio 999
+    set currFieldPos [list]
+    set currCodeBurst {
+	error "in ::tcl::clock::MakeParseCodeFromFields: can't happen"
+    }
+
+    foreach { fieldSet prio parseAction } $parseActions {
+	# If we've found an answer that's better than any that follow, quit
+	# now.
+
+	if { $prio > $currPrio } {
+	    break
+	}
+
+	# Accumulate the field positions that are used in the current field
+	# grouping.
+
+	set fieldPos [list]
+	set ok true
+	foreach field $fieldSet {
+	    if { ! [dict exists $dateFields $field] } {
+		set ok 0
+		break
+	    }
+	    lappend fieldPos [dict get $dateFields $field]
+	}
+
+	# Quit if we don't have a complete set of fields
+	if { !$ok } {
+	    continue
+	}
+
+	# Determine whether the current answer is better than the last.
+
+	set fPos [lsort -integer -decreasing $fieldPos]
+
+	if { $prio ==  $currPrio } {
+	    foreach currPos $currFieldPos newPos $fPos {
+		if {
+		    ![string is integer $newPos]
+		    || ![string is integer $currPos]
+		    || $newPos > $currPos
+		} then {
+		    break
+		}
+		if { $newPos < $currPos } {
+		    set ok 0
+		    break
+		}
+	    }
+	}
+	if { !$ok } {
+	    continue
+	}
+
+	# Remember the best possibility for extracting date information
+
+	set currPrio $prio
+	set currFieldPos $fPos
+	set currCodeBurst $parseAction
+    }
+
+    return $currCodeBurst
+}
+
+#----------------------------------------------------------------------
+#
+# EnterLocale --
+#
+#	Switch [mclocale] to a given locale if necessary
+#
+# Parameters:
+#	locale -- Desired locale
+#
+# Results:
+#	Returns the locale that was previously current.
+#
+# Side effects:
+#	Does [mclocale].  If necessary, loades the designated locale's files.
+#
+#----------------------------------------------------------------------
+
+proc ::tcl::clock::EnterLocale { locale } {
+    if { $locale eq {system} } {
+	if { $::tcl_platform(platform) ne {windows} } {
+	    # On a non-windows platform, the 'system' locale is the same as
+	    # the 'current' locale
+
+	    set locale current
+	} else {
+	    # On a windows platform, the 'system' locale is adapted from the
+	    # 'current' locale by applying the date and time formats from the
+	    # Control Panel.  First, load the 'current' locale if it's not yet
+	    # loaded
+
+	    mcpackagelocale set [mclocale]
+
+	    # Make a new locale string for the system locale, and get the
+	    # Control Panel information
+
+	    set locale [mclocale]_windows
+	    if { ! [mcpackagelocale present $locale] } {
+		LoadWindowsDateTimeFormats $locale
+	    }
+	}
+    }
+    if { $locale eq {current}} {
+	set locale [mclocale]
+    }
+    # Eventually load the locale
+    mcpackagelocale set $locale
+}
+
+#----------------------------------------------------------------------
+#
+# LoadWindowsDateTimeFormats --
+#
+#	Load the date/time formats from the Control Panel in Windows and
+#	convert them so that they're usable by Tcl.
+#
+# Parameters:
+#	locale - Name of the locale in whose message catalog
+#	         the converted formats are to be stored.
+#
+# Results:
+#	None.
+#
+# Side effects:
+#	Updates the given message catalog with the locale strings.
+#
+# Presumes that on entry, [mclocale] is set to the current locale, so that
+# default strings can be obtained if the Registry query fails.
+#
+#----------------------------------------------------------------------
+
+proc ::tcl::clock::LoadWindowsDateTimeFormats { locale } {
+    # Bail out if we can't find the Registry
+
+    variable NoRegistry
+    if { [info exists NoRegistry] } return
+
+    if { ![catch {
+	registry get "HKEY_CURRENT_USER\\Control Panel\\International" \
+	    sShortDate
+    } string] } {
+	set quote {}
+	set datefmt {}
+	foreach { unquoted quoted } [split $string '] {
+	    append datefmt $quote [string map {
+		dddd %A
+		ddd  %a
+		dd   %d
+		d    %e
+		MMMM %B
+		MMM  %b
+		MM   %m
+		M    %N
+		yyyy %Y
+		yy   %y
+                y    %y
+                gg   {}
+	    } $unquoted]
+	    if { $quoted eq {} } {
+		set quote '
+	    } else {
+		set quote $quoted
+	    }
+	}
+	::msgcat::mcset $locale DATE_FORMAT $datefmt
+    }
+
+    if { ![catch {
+	registry get "HKEY_CURRENT_USER\\Control Panel\\International" \
+	    sLongDate
+    } string] } {
+	set quote {}
+	set ldatefmt {}
+	foreach { unquoted quoted } [split $string '] {
+	    append ldatefmt $quote [string map {
+		dddd %A
+		ddd  %a
+		dd   %d
+		d    %e
+		MMMM %B
+		MMM  %b
+		MM   %m
+		M    %N
+		yyyy %Y
+		yy   %y
+                y    %y
+                gg   {}
+	    } $unquoted]
+	    if { $quoted eq {} } {
+		set quote '
+	    } else {
+		set quote $quoted
+	    }
+	}
+	::msgcat::mcset $locale LOCALE_DATE_FORMAT $ldatefmt
+    }
+
+    if { ![catch {
+	registry get "HKEY_CURRENT_USER\\Control Panel\\International" \
+	    sTimeFormat
+    } string] } {
+	set quote {}
+	set timefmt {}
+	foreach { unquoted quoted } [split $string '] {
+	    append timefmt $quote [string map {
+		HH    %H
+		H     %k
+		hh    %I
+		h     %l
+		mm    %M
+		m     %M
+		ss    %S
+		s     %S
+		tt    %p
+		t     %p
+	    } $unquoted]
+	    if { $quoted eq {} } {
+		set quote '
+	    } else {
+		set quote $quoted
+	    }
+	}
+	::msgcat::mcset $locale TIME_FORMAT $timefmt
+    }
+
+    catch {
+	::msgcat::mcset $locale DATE_TIME_FORMAT "$datefmt $timefmt"
+    }
+    catch {
+	::msgcat::mcset $locale LOCALE_DATE_TIME_FORMAT "$ldatefmt $timefmt"
+    }
+
+    return
+
+}
+
+#----------------------------------------------------------------------
+#
+# LocalizeFormat --
+#
+#	Map away locale-dependent format groups in a clock format.
+#
+# Parameters:
+#	locale -- Current [mclocale] locale, supplied to avoid
+#		  an extra call
+#	format -- Format supplied to [clock scan] or [clock format]
+#
+# Results:
+#	Returns the string with locale-dependent composite format groups
+#	substituted out.
+#
+# Side effects:
+#	None.
+#
+#----------------------------------------------------------------------
+
+proc ::tcl::clock::LocalizeFormat { locale format } {
+
+    # message catalog key to cache this format
+    set key FORMAT_$format
+
+    if { [::msgcat::mcexists -exactlocale -exactnamespace $key] } {
+	return [mc $key]
+    }
+    # Handle locale-dependent format groups by mapping them out of the format
+    # string.  Note that the order of the [string map] operations is
+    # significant because later formats can refer to later ones; for example
+    # %c can refer to %X, which in turn can refer to %T.
+
+    set list {
+	%% %%
+	%D %m/%d/%Y
+	%+ {%a %b %e %H:%M:%S %Z %Y}
+    }
+    lappend list %EY [string map $list [mc LOCALE_YEAR_FORMAT]]
+    lappend list %T  [string map $list [mc TIME_FORMAT_24_SECS]]
+    lappend list %R  [string map $list [mc TIME_FORMAT_24]]
+    lappend list %r  [string map $list [mc TIME_FORMAT_12]]
+    lappend list %X  [string map $list [mc TIME_FORMAT]]
+    lappend list %EX [string map $list [mc LOCALE_TIME_FORMAT]]
+    lappend list %x  [string map $list [mc DATE_FORMAT]]
+    lappend list %Ex [string map $list [mc LOCALE_DATE_FORMAT]]
+    lappend list %c  [string map $list [mc DATE_TIME_FORMAT]]
+    lappend list %Ec [string map $list [mc LOCALE_DATE_TIME_FORMAT]]
+    set format [string map $list $format]
+
+    ::msgcat::mcset $locale $key $format
+    return $format
+}
+
+#----------------------------------------------------------------------
+#
+# FormatNumericTimeZone --
+#
+#	Formats a time zone as +hhmmss
+#
+# Parameters:
+#	z - Time zone in seconds east of Greenwich
+#
+# Results:
+#	Returns the time zone formatted in a numeric form
+#
+# Side effects:
+#	None.
+#
+#----------------------------------------------------------------------
+
+proc ::tcl::clock::FormatNumericTimeZone { z } {
+    if { $z < 0 } {
+	set z [expr { - $z }]
+	set retval -
+    } else {
+	set retval +
+    }
+    append retval [::format %02d [expr { $z / 3600 }]]
+    set z [expr { $z % 3600 }]
+    append retval [::format %02d [expr { $z / 60 }]]
+    set z [expr { $z % 60 }]
+    if { $z != 0 } {
+	append retval [::format %02d $z]
+    }
+    return $retval
+}
+
+#----------------------------------------------------------------------
+#
+# FormatStarDate --
+#
+#	Formats a date as a StarDate.
+#
+# Parameters:
+#	date - Dictionary containing 'year', 'dayOfYear', and
+#	       'localSeconds' fields.
+#
+# Results:
+#	Returns the given date formatted as a StarDate.
+#
+# Side effects:
+#	None.
+#
+# Jeff Hobbs put this in to support an atrocious pun about Tcl being
+# "Enterprise ready."  Now we're stuck with it.
+#
+#----------------------------------------------------------------------
+
+proc ::tcl::clock::FormatStarDate { date } {
+    variable Roddenberry
+
+    # Get day of year, zero based
+
+    set doy [expr { [dict get $date dayOfYear] - 1 }]
+
+    # Determine whether the year is a leap year
+
+    set lp [IsGregorianLeapYear $date]
+
+    # Convert day of year to a fractional year
+
+    if { $lp } {
+	set fractYear [expr { 1000 * $doy / 366 }]
+    } else {
+	set fractYear [expr { 1000 * $doy / 365 }]
+    }
+
+    # Put together the StarDate
+
+    return [::format "Stardate %02d%03d.%1d" \
+		[expr { [dict get $date year] - $Roddenberry }] \
+		$fractYear \
+		[expr { [dict get $date localSeconds] % 86400
+			/ ( 86400 / 10 ) }]]
+}
+
+#----------------------------------------------------------------------
+#
+# ParseStarDate --
+#
+#	Parses a StarDate
+#
+# Parameters:
+#	year - Year from the Roddenberry epoch
+#	fractYear - Fraction of a year specifiying the day of year.
+#	fractDay - Fraction of a day
+#
+# Results:
+#	Returns a count of seconds from the Posix epoch.
+#
+# Side effects:
+#	None.
+#
+# Jeff Hobbs put this in to support an atrocious pun about Tcl being
+# "Enterprise ready."  Now we're stuck with it.
+#
+#----------------------------------------------------------------------
+
+proc ::tcl::clock::ParseStarDate { year fractYear fractDay } {
+    variable Roddenberry
+
+    # Build a tentative date from year and fraction.
+
+    set date [dict create \
+		  gregorian 1 \
+		  era CE \
+		  year [expr { $year + $Roddenberry }] \
+		  dayOfYear [expr { $fractYear * 365 / 1000 + 1 }]]
+    set date [GetJulianDayFromGregorianEraYearDay $date[set date {}]]
+
+    # Determine whether the given year is a leap year
+
+    set lp [IsGregorianLeapYear $date]
+
+    # Reconvert the fractional year according to whether the given year is a
+    # leap year
+
+    if { $lp } {
+	dict set date dayOfYear \
+	    [expr { $fractYear * 366 / 1000 + 1 }]
+    } else {
+	dict set date dayOfYear \
+	    [expr { $fractYear * 365 / 1000 + 1 }]
+    }
+    dict unset date julianDay
+    dict unset date gregorian
+    set date [GetJulianDayFromGregorianEraYearDay $date[set date {}]]
+
+    return [expr {
+	86400 * [dict get $date julianDay]
+	- 210866803200
+	+ ( 86400 / 10 ) * $fractDay
+    }]
+}
+
+#----------------------------------------------------------------------
+#
+# ScanWide --
+#
+#	Scans a wide integer from an input
+#
+# Parameters:
+#	str - String containing a decimal wide integer
+#
+# Results:
+#	Returns the string as a pure wide integer.  Throws an error if the
+#	string is misformatted or out of range.
+#
+#----------------------------------------------------------------------
+
+proc ::tcl::clock::ScanWide { str } {
+    set count [::scan $str {%ld %c} result junk]
+    if { $count != 1 } {
+	return -code error -errorcode [list CLOCK notAnInteger $str] \
+	    "\"$str\" is not an integer"
+    }
+    if { [incr result 0] != $str } {
+	return -code error -errorcode [list CLOCK integervalueTooLarge] \
+	    "integer value too large to represent"
+    }
+    return $result
+}
+
+#----------------------------------------------------------------------
+#
+# InterpretTwoDigitYear --
+#
+#	Given a date that contains only the year of the century, determines
+#	the target value of a two-digit year.
+#
+# Parameters:
+#	date - Dictionary containing fields of the date.
+#	baseTime - Base time relative to which the date is expressed.
+#	twoDigitField - Name of the field that stores the two-digit year.
+#			Default is 'yearOfCentury'
+#	fourDigitField - Name of the field that will receive the four-digit
+#	                 year.  Default is 'year'
+#
+# Results:
+#	Returns the dictionary augmented with the four-digit year, stored in
+#	the given key.
+#
+# Side effects:
+#	None.
+#
+# The current rule for interpreting a two-digit year is that the year shall be
+# between 1937 and 2037, thus staying within the range of a 32-bit signed
+# value for time.  This rule may change to a sliding window in future
+# versions, so the 'baseTime' parameter (which is currently ignored) is
+# provided in the procedure signature.
+#
+#----------------------------------------------------------------------
+
+proc ::tcl::clock::InterpretTwoDigitYear { date baseTime
+					   { twoDigitField yearOfCentury }
+					   { fourDigitField year } } {
+    set yr [dict get $date $twoDigitField]
+    if { $yr <= 37 } {
+	dict set date $fourDigitField [expr { $yr + 2000 }]
+    } else {
+	dict set date $fourDigitField [expr { $yr + 1900 }]
+    }
+    return $date
+}
+
+#----------------------------------------------------------------------
+#
+# AssignBaseYear --
+#
+#	Places the number of the current year into a dictionary.
+#
+# Parameters:
+#	date - Dictionary value to update
+#	baseTime - Base time from which to extract the year, expressed
+#		   in seconds from the Posix epoch
+#	timezone - the time zone in which the date is being scanned
+#	changeover - the Julian Day on which the Gregorian calendar
+#		     was adopted in the target locale.
+#
+# Results:
+#	Returns the dictionary with the current year assigned.
+#
+# Side effects:
+#	None.
+#
+#----------------------------------------------------------------------
+
+proc ::tcl::clock::AssignBaseYear { date baseTime timezone changeover } {
+    variable TZData
+
+    # Find the Julian Day Number corresponding to the base time, and
+    # find the Gregorian year corresponding to that Julian Day.
+
+    set date2 [GetDateFields $baseTime $TZData($timezone) $changeover]
+
+    # Store the converted year
+
+    dict set date era [dict get $date2 era]
+    dict set date year [dict get $date2 year]
+
+    return $date
+}
+
+#----------------------------------------------------------------------
+#
+# AssignBaseIso8601Year --
+#
+#	Determines the base year in the ISO8601 fiscal calendar.
+#
+# Parameters:
+#	date - Dictionary containing the fields of the date that
+#	       is to be augmented with the base year.
+#	baseTime - Base time expressed in seconds from the Posix epoch.
+#	timeZone - Target time zone
+#	changeover - Julian Day of adoption of the Gregorian calendar in
+#		     the target locale.
+#
+# Results:
+#	Returns the given date with "iso8601Year" set to the
+#	base year.
+#
+# Side effects:
+#	None.
+#
+#----------------------------------------------------------------------
+
+proc ::tcl::clock::AssignBaseIso8601Year {date baseTime timeZone changeover} {
+    variable TZData
+
+    # Find the Julian Day Number corresponding to the base time
+
+    set date2 [GetDateFields $baseTime $TZData($timeZone) $changeover]
+
+    # Calculate the ISO8601 date and transfer the year
+
+    dict set date era CE
+    dict set date iso8601Year [dict get $date2 iso8601Year]
+    return $date
+}
+
+#----------------------------------------------------------------------
+#
+# AssignBaseMonth --
+#
+#	Places the number of the current year and month into a
+#	dictionary.
+#
+# Parameters:
+#	date - Dictionary value to update
+#	baseTime - Time from which the year and month are to be
+#	           obtained, expressed in seconds from the Posix epoch.
+#	timezone - Name of the desired time zone
+#	changeover - Julian Day on which the Gregorian calendar was adopted.
+#
+# Results:
+#	Returns the dictionary with the base year and month assigned.
+#
+# Side effects:
+#	None.
+#
+#----------------------------------------------------------------------
+
+proc ::tcl::clock::AssignBaseMonth {date baseTime timezone changeover} {
+    variable TZData
+
+    # Find the year and month corresponding to the base time
+
+    set date2 [GetDateFields $baseTime $TZData($timezone) $changeover]
+    dict set date era [dict get $date2 era]
+    dict set date year [dict get $date2 year]
+    dict set date month [dict get $date2 month]
+    return $date
+}
+
+#----------------------------------------------------------------------
+#
+# AssignBaseWeek --
+#
+#	Determines the base year and week in the ISO8601 fiscal calendar.
+#
+# Parameters:
+#	date - Dictionary containing the fields of the date that
+#	       is to be augmented with the base year and week.
+#	baseTime - Base time expressed in seconds from the Posix epoch.
+#	changeover - Julian Day on which the Gregorian calendar was adopted
+#		     in the target locale.
+#
+# Results:
+#	Returns the given date with "iso8601Year" set to the
+#	base year and "iso8601Week" to the week number.
+#
+# Side effects:
+#	None.
+#
+#----------------------------------------------------------------------
+
+proc ::tcl::clock::AssignBaseWeek {date baseTime timeZone changeover} {
+    variable TZData
+
+    # Find the Julian Day Number corresponding to the base time
+
+    set date2 [GetDateFields $baseTime $TZData($timeZone) $changeover]
+
+    # Calculate the ISO8601 date and transfer the year
+
+    dict set date era CE
+    dict set date iso8601Year [dict get $date2 iso8601Year]
+    dict set date iso8601Week [dict get $date2 iso8601Week]
+    return $date
+}
+
+#----------------------------------------------------------------------
+#
+# AssignBaseJulianDay --
+#
+#	Determines the base day for a time-of-day conversion.
+#
+# Parameters:
+#	date - Dictionary that is to get the base day
+#	baseTime - Base time expressed in seconds from the Posix epoch
+#	changeover - Julian day on which the Gregorian calendar was
+#		     adpoted in the target locale.
+#
+# Results:
+#	Returns the given dictionary augmented with a 'julianDay' field
+#	that contains the base day.
+#
+# Side effects:
+#	None.
+#
+#----------------------------------------------------------------------
+
+proc ::tcl::clock::AssignBaseJulianDay { date baseTime timeZone changeover } {
+    variable TZData
+
+    # Find the Julian Day Number corresponding to the base time
+
+    set date2 [GetDateFields $baseTime $TZData($timeZone) $changeover]
+    dict set date julianDay [dict get $date2 julianDay]
+
+    return $date
+}
+
+#----------------------------------------------------------------------
+#
+# InterpretHMSP --
+#
+#	Interprets a time in the form "hh:mm:ss am".
+#
+# Parameters:
+#	date -- Dictionary containing "hourAMPM", "minute", "second"
+#	        and "amPmIndicator" fields.
+#
+# Results:
+#	Returns the number of seconds from local midnight.
+#
+# Side effects:
+#	None.
+#
+#----------------------------------------------------------------------
+
+proc ::tcl::clock::InterpretHMSP { date } {
+    set hr [dict get $date hourAMPM]
+    if { $hr == 12 } {
+	set hr 0
+    }
+    if { [dict get $date amPmIndicator] } {
+	incr hr 12
+    }
+    dict set date hour $hr
+    return [InterpretHMS $date[set date {}]]
+}
+
+#----------------------------------------------------------------------
+#
+# InterpretHMS --
+#
+#	Interprets a 24-hour time "hh:mm:ss"
+#
+# Parameters:
+#	date -- Dictionary containing the "hour", "minute" and "second"
+#	        fields.
+#
+# Results:
+#	Returns the given dictionary augmented with a "secondOfDay"
+#	field containing the number of seconds from local midnight.
+#
+# Side effects:
+#	None.
+#
+#----------------------------------------------------------------------
+
+proc ::tcl::clock::InterpretHMS { date } {
+    return [expr {
+	( [dict get $date hour] * 60
+	  + [dict get $date minute] ) * 60
+	+ [dict get $date second]
+    }]
+}
+
+#----------------------------------------------------------------------
+#
+# GetSystemTimeZone --
+#
+#	Determines the system time zone, which is the default for the
+#	'clock' command if no other zone is supplied.
+#
+# Parameters:
+#	None.
+#
+# Results:
+#	Returns the system time zone.
+#
+# Side effects:
+#	Stores the sustem time zone in the 'CachedSystemTimeZone'
+#	variable, since determining it may be an expensive process.
+#
+#----------------------------------------------------------------------
+
+proc ::tcl::clock::GetSystemTimeZone {} {
+    variable CachedSystemTimeZone
+    variable TimeZoneBad
+
+    if {[set result [getenv TCL_TZ]] ne {}} {
+	set timezone $result
+    } elseif {[set result [getenv TZ]] ne {}} {
+	set timezone $result
+    }
+    if {![info exists timezone]} {
+        # Cache the time zone only if it was detected by one of the
+        # expensive methods.
+        if { [info exists CachedSystemTimeZone] } {
+            set timezone $CachedSystemTimeZone
+        } elseif { $::tcl_platform(platform) eq {windows} } {
+            set timezone [GuessWindowsTimeZone]
+        } elseif { [file exists /etc/localtime]
+                   && ![catch {ReadZoneinfoFile \
+                                   Tcl/Localtime /etc/localtime}] } {
+            set timezone :Tcl/Localtime
+        } else {
+            set timezone :localtime
+        }
+	set CachedSystemTimeZone $timezone
+    }
+    if { ![dict exists $TimeZoneBad $timezone] } {
+	dict set TimeZoneBad $timezone [catch {SetupTimeZone $timezone}]
+    }
+    if { [dict get $TimeZoneBad $timezone] } {
+	return :localtime
+    } else {
+	return $timezone
+    }
+}
+
+#----------------------------------------------------------------------
+#
+# ConvertLegacyTimeZone --
+#
+#	Given an alphanumeric time zone identifier and the system time zone,
+#	convert the alphanumeric identifier to an unambiguous time zone.
+#
+# Parameters:
+#	tzname - Name of the time zone to convert
+#
+# Results:
+#	Returns a time zone name corresponding to tzname, but in an
+#	unambiguous form, generally +hhmm.
+#
+# This procedure is implemented primarily to allow the parsing of RFC822
+# date/time strings.  Processing a time zone name on input is not recommended
+# practice, because there is considerable room for ambiguity; for instance, is
+# BST Brazilian Standard Time, or British Summer Time?
+#
+#----------------------------------------------------------------------
+
+proc ::tcl::clock::ConvertLegacyTimeZone { tzname } {
+    variable LegacyTimeZone
+
+    set tzname [string tolower $tzname]
+    if { ![dict exists $LegacyTimeZone $tzname] } {
+	return -code error -errorcode [list CLOCK badTZName $tzname] \
+	    "time zone \"$tzname\" not found"
+    }
+    return [dict get $LegacyTimeZone $tzname]
+}
+
+#----------------------------------------------------------------------
+#
+# SetupTimeZone --
+#
+#	Given the name or specification of a time zone, sets up its in-memory
+#	data.
+#
+# Parameters:
+#	tzname - Name of a time zone
+#
+# Results:
+#	Unless the time zone is ':localtime', sets the TZData array to contain
+#	the lookup table for local<->UTC conversion.  Returns an error if the
+#	time zone cannot be parsed.
+#
+#----------------------------------------------------------------------
+
+proc ::tcl::clock::SetupTimeZone { timezone } {
+    variable TZData
+
+    if {! [info exists TZData($timezone)] } {
+	variable MINWIDE
+	if { $timezone eq {:localtime} } {
+	    # Nothing to do, we'll convert using the localtime function
+
+	} elseif {
+	    [regexp {^([-+])(\d\d)(?::?(\d\d)(?::?(\d\d))?)?} $timezone \
+		    -> s hh mm ss]
+	} then {
+	    # Make a fixed offset
+
+	    ::scan $hh %d hh
+	    if { $mm eq {} } {
+		set mm 0
+	    } else {
+		::scan $mm %d mm
+	    }
+	    if { $ss eq {} } {
+		set ss 0
+	    } else {
+		::scan $ss %d ss
+	    }
+	    set offset [expr { ( $hh * 60 + $mm ) * 60 + $ss }]
+	    if { $s eq {-} } {
+		set offset [expr { - $offset }]
+	    }
+	    set TZData($timezone) [list [list $MINWIDE $offset -1 $timezone]]
+
+	} elseif { [string index $timezone 0] eq {:} } {
+	    # Convert using a time zone file
+
+	    if {
+		[catch {
+		    LoadTimeZoneFile [string range $timezone 1 end]
+		}] && [catch {
+		    LoadZoneinfoFile [string range $timezone 1 end]
+		}]
+	    } then {
+		return -code error \
+		    -errorcode [list CLOCK badTimeZone $timezone] \
+		    "time zone \"$timezone\" not found"
+	    }
+	} elseif { ![catch {ParsePosixTimeZone $timezone} tzfields] } {
+	    # This looks like a POSIX time zone - try to process it
+
+	    if { [catch {ProcessPosixTimeZone $tzfields} data opts] } {
+		if { [lindex [dict get $opts -errorcode] 0] eq {CLOCK} } {
+		    dict unset opts -errorinfo
+		}
+		return -options $opts $data
+	    } else {
+		set TZData($timezone) $data
+	    }
+
+	} else {
+	    # We couldn't parse this as a POSIX time zone.  Try again with a
+	    # time zone file - this time without a colon
+
+	    if { [catch { LoadTimeZoneFile $timezone }]
+		 && [catch { LoadZoneinfoFile $timezone } - opts] } {
+		dict unset opts -errorinfo
+		return -options $opts "time zone $timezone not found"
+	    }
+	    set TZData($timezone) $TZData(:$timezone)
+	}
+    }
+
+    return
+}
+
+#----------------------------------------------------------------------
+#
+# GuessWindowsTimeZone --
+#
+#	Determines the system time zone on windows.
+#
+# Parameters:
+#	None.
+#
+# Results:
+#	Returns a time zone specifier that corresponds to the system time zone
+#	information found in the Registry.
+#
+# Bugs:
+#	Fixed dates for DST change are unimplemented at present, because no
+#	time zone information supplied with Windows actually uses them!
+#
+# On a Windows system where neither $env(TCL_TZ) nor $env(TZ) is specified,
+# GuessWindowsTimeZone looks in the Registry for the system time zone
+# information.  It then attempts to find an entry in WinZoneInfo for a time
+# zone that uses the same rules.  If it finds one, it returns it; otherwise,
+# it constructs a Posix-style time zone string and returns that.
+#
+#----------------------------------------------------------------------
+
+proc ::tcl::clock::GuessWindowsTimeZone {} {
+    variable WinZoneInfo
+    variable NoRegistry
+    variable TimeZoneBad
+
+    if { [info exists NoRegistry] } {
+	return :localtime
+    }
+
+    # Dredge time zone information out of the registry
+
+    if { [catch {
+	set rpath HKEY_LOCAL_MACHINE\\System\\CurrentControlSet\\Control\\TimeZoneInformation
+	set data [list \
+		      [expr { -60
+			      * [registry get $rpath Bias] }] \
+		      [expr { -60
+				  * [registry get $rpath StandardBias] }] \
+		      [expr { -60 \
+				  * [registry get $rpath DaylightBias] }]]
+	set stdtzi [registry get $rpath StandardStart]
+	foreach ind {0 2 14 4 6 8 10 12} {
+	    binary scan $stdtzi @${ind}s val
+	    lappend data $val
+	}
+	set daytzi [registry get $rpath DaylightStart]
+	foreach ind {0 2 14 4 6 8 10 12} {
+	    binary scan $daytzi @${ind}s val
+	    lappend data $val
+	}
+    }] } {
+	# Missing values in the Registry - bail out
+
+	return :localtime
+    }
+
+    # Make up a Posix time zone specifier if we can't find one.  Check here
+    # that the tzdata file exists, in case we're running in an environment
+    # (e.g. starpack) where tzdata is incomplete.  (Bug 1237907)
+
+    if { [dict exists $WinZoneInfo $data] } {
+	set tzname [dict get $WinZoneInfo $data]
+	if { ! [dict exists $TimeZoneBad $tzname] } {
+	    dict set TimeZoneBad $tzname [catch {SetupTimeZone $tzname}]
+	}
+    } else {
+	set tzname {}
+    }
+    if { $tzname eq {} || [dict get $TimeZoneBad $tzname] } {
+	lassign $data \
+	    bias stdBias dstBias \
+	    stdYear stdMonth stdDayOfWeek stdDayOfMonth \
+	    stdHour stdMinute stdSecond stdMillisec \
+	    dstYear dstMonth dstDayOfWeek dstDayOfMonth \
+	    dstHour dstMinute dstSecond dstMillisec
+	set stdDelta [expr { $bias + $stdBias }]
+	set dstDelta [expr { $bias + $dstBias }]
+	if { $stdDelta <= 0 } {
+	    set stdSignum +
+	    set stdDelta [expr { - $stdDelta }]
+	    set dispStdSignum -
+	} else {
+	    set stdSignum -
+	    set dispStdSignum +
+	}
+	set hh [::format %02d [expr { $stdDelta / 3600 }]]
+	set mm [::format %02d [expr { ($stdDelta / 60 ) % 60 }]]
+	set ss [::format %02d [expr { $stdDelta % 60 }]]
+	set tzname {}
+	append tzname < $dispStdSignum $hh $mm > $stdSignum $hh : $mm : $ss
+	if { $stdMonth >= 0 } {
+	    if { $dstDelta <= 0 } {
+		set dstSignum +
+		set dstDelta [expr { - $dstDelta }]
+		set dispDstSignum -
+	    } else {
+		set dstSignum -
+		set dispDstSignum +
+	    }
+	    set hh [::format %02d [expr { $dstDelta / 3600 }]]
+	    set mm [::format %02d [expr { ($dstDelta / 60 ) % 60 }]]
+	    set ss [::format %02d [expr { $dstDelta % 60 }]]
+	    append tzname < $dispDstSignum $hh $mm > $dstSignum $hh : $mm : $ss
+	    if { $dstYear == 0 } {
+		append tzname ,M $dstMonth . $dstDayOfMonth . $dstDayOfWeek
+	    } else {
+		# I have not been able to find any locale on which Windows
+		# converts time zone on a fixed day of the year, hence don't
+		# know how to interpret the fields.  If someone can inform me,
+		# I'd be glad to code it up.  For right now, we bail out in
+		# such a case.
+		return :localtime
+	    }
+	    append tzname / [::format %02d $dstHour] \
+		: [::format %02d $dstMinute] \
+		: [::format %02d $dstSecond]
+	    if { $stdYear == 0 } {
+		append tzname ,M $stdMonth . $stdDayOfMonth . $stdDayOfWeek
+	    } else {
+		# I have not been able to find any locale on which Windows
+		# converts time zone on a fixed day of the year, hence don't
+		# know how to interpret the fields.  If someone can inform me,
+		# I'd be glad to code it up.  For right now, we bail out in
+		# such a case.
+		return :localtime
+	    }
+	    append tzname / [::format %02d $stdHour] \
+		: [::format %02d $stdMinute] \
+		: [::format %02d $stdSecond]
+	}
+	dict set WinZoneInfo $data $tzname
+    }
+
+    return [dict get $WinZoneInfo $data]
+}
+
+#----------------------------------------------------------------------
+#
+# LoadTimeZoneFile --
+#
+#	Load the data file that specifies the conversion between a
+#	given time zone and Greenwich.
+#
+# Parameters:
+#	fileName -- Name of the file to load
+#
+# Results:
+#	None.
+#
+# Side effects:
+#	TZData(:fileName) contains the time zone data
+#
+#----------------------------------------------------------------------
+
+proc ::tcl::clock::LoadTimeZoneFile { fileName } {
+    variable DataDir
+    variable TZData
+
+    if { [info exists TZData($fileName)] } {
+	return
+    }
+
+    # Since an unsafe interp uses the [clock] command in the master, this code
+    # is security sensitive.  Make sure that the path name cannot escape the
+    # given directory.
+
+    if { ![regexp {^[[.-.][:alpha:]_]+(?:/[[.-.][:alpha:]_]+)*$} $fileName] } {
+	return -code error \
+	    -errorcode [list CLOCK badTimeZone $:fileName] \
+	    "time zone \":$fileName\" not valid"
+    }
+    try {
+	source -encoding utf-8 [file join $DataDir $fileName]
+    } on error {} {
+	return -code error \
+	    -errorcode [list CLOCK badTimeZone :$fileName] \
+	    "time zone \":$fileName\" not found"
+    }
+    return
+}
+
+#----------------------------------------------------------------------
+#
+# LoadZoneinfoFile --
+#
+#	Loads a binary time zone information file in Olson format.
+#
+# Parameters:
+#	fileName - Relative path name of the file to load.
+#
+# Results:
+#	Returns an empty result normally; returns an error if no Olson file
+#	was found or the file was malformed in some way.
+#
+# Side effects:
+#	TZData(:fileName) contains the time zone data
+#
+#----------------------------------------------------------------------
+
+proc ::tcl::clock::LoadZoneinfoFile { fileName } {
+    variable ZoneinfoPaths
+
+    # Since an unsafe interp uses the [clock] command in the master, this code
+    # is security sensitive.  Make sure that the path name cannot escape the
+    # given directory.
+
+    if { ![regexp {^[[.-.][:alpha:]_]+(?:/[[.-.][:alpha:]_]+)*$} $fileName] } {
+	return -code error \
+	    -errorcode [list CLOCK badTimeZone $:fileName] \
+	    "time zone \":$fileName\" not valid"
+    }
+    foreach d $ZoneinfoPaths {
+	set fname [file join $d $fileName]
+	if { [file readable $fname] && [file isfile $fname] } {
+	    break
+	}
+	unset fname
+    }
+    ReadZoneinfoFile $fileName $fname
+}
+
+#----------------------------------------------------------------------
+#
+# ReadZoneinfoFile --
+#
+#	Loads a binary time zone information file in Olson format.
+#
+# Parameters:
+#	fileName - Name of the time zone (relative path name of the
+#		   file).
+#	fname - Absolute path name of the file.
+#
+# Results:
+#	Returns an empty result normally; returns an error if no Olson file
+#	was found or the file was malformed in some way.
+#
+# Side effects:
+#	TZData(:fileName) contains the time zone data
+#
+#----------------------------------------------------------------------
+
+proc ::tcl::clock::ReadZoneinfoFile {fileName fname} {
+    variable MINWIDE
+    variable TZData
+    if { ![file exists $fname] } {
+	return -code error "$fileName not found"
+    }
+
+    if { [file size $fname] > 262144 } {
+	return -code error "$fileName too big"
+    }
+
+    # Suck in all the data from the file
+
+    set f [open $fname r]
+    fconfigure $f -translation binary
+    set d [read $f]
+    close $f
+
+    # The file begins with a magic number, sixteen reserved bytes, and then
+    # six 4-byte integers giving counts of fileds in the file.
+
+    binary scan $d a4a1x15IIIIII \
+	magic version nIsGMT nIsStd nLeap nTime nType nChar
+    set seek 44
+    set ilen 4
+    set iformat I
+    if { $magic != {TZif} } {
+	return -code error "$fileName not a time zone information file"
+    }
+    if { $nType > 255 } {
+	return -code error "$fileName contains too many time types"
+    }
+    # Accept only Posix-style zoneinfo.  Sorry, 'leaps' bigots.
+    if { $nLeap != 0 } {
+	return -code error "$fileName contains leap seconds"
+    }
+
+    # In a version 2 file, we use the second part of the file, which contains
+    # 64-bit transition times.
+
+    if {$version eq "2"} {
+	set seek [expr {
+	    44
+	    + 5 * $nTime
+	    + 6 * $nType
+	    + 4 * $nLeap
+	    + $nIsStd
+	    + $nIsGMT
+	    + $nChar
+	}]
+	binary scan $d @${seek}a4a1x15IIIIII \
+	    magic version nIsGMT nIsStd nLeap nTime nType nChar
+	if {$magic ne {TZif}} {
+	    return -code error "seek address $seek miscomputed, magic = $magic"
+	}
+	set iformat W
+	set ilen 8
+	incr seek 44
+    }
+
+    # Next come ${nTime} transition times, followed by ${nTime} time type
+    # codes.  The type codes are unsigned 1-byte quantities.  We insert an
+    # arbitrary start time in front of the transitions.
+
+    binary scan $d @${seek}${iformat}${nTime}c${nTime} times tempCodes
+    incr seek [expr { ($ilen + 1) * $nTime }]
+    set times [linsert $times 0 $MINWIDE]
+    set codes {}
+    foreach c $tempCodes {
+	lappend codes [expr { $c & 0xff }]
+    }
+    set codes [linsert $codes 0 0]
+
+    # Next come ${nType} time type descriptions, each of which has an offset
+    # (seconds east of GMT), a DST indicator, and an index into the
+    # abbreviation text.
+
+    for { set i 0 } { $i < $nType } { incr i } {
+	binary scan $d @${seek}Icc gmtOff isDst abbrInd
+	lappend types [list $gmtOff $isDst $abbrInd]
+	incr seek 6
+    }
+
+    # Next come $nChar characters of time zone name abbreviations, which are
+    # null-terminated.
+    # We build them up into a dictionary indexed by character index, because
+    # that's what's in the indices above.
+
+    binary scan $d @${seek}a${nChar} abbrs
+    incr seek ${nChar}
+    set abbrList [split $abbrs \0]
+    set i 0
+    set abbrevs {}
+    foreach a $abbrList {
+	for {set j 0} {$j <= [string length $a]} {incr j} {
+	    dict set abbrevs $i [string range $a $j end]
+	    incr i
+	}
+    }
+
+    # Package up a list of tuples, each of which contains transition time,
+    # seconds east of Greenwich, DST flag and time zone abbreviation.
+
+    set r {}
+    set lastTime $MINWIDE
+    foreach t $times c $codes {
+	if { $t < $lastTime } {
+	    return -code error "$fileName has times out of order"
+	}
+	set lastTime $t
+	lassign [lindex $types $c] gmtoff isDst abbrInd
+	set abbrev [dict get $abbrevs $abbrInd]
+	lappend r [list $t $gmtoff $isDst $abbrev]
+    }
+
+    # In a version 2 file, there is also a POSIX-style time zone description
+    # at the very end of the file.  To get to it, skip over nLeap leap second
+    # values (8 bytes each),
+    # nIsStd standard/DST indicators and nIsGMT UTC/local indicators.
+
+    if {$version eq {2}} {
+	set seek [expr {$seek + 8 * $nLeap + $nIsStd + $nIsGMT + 1}]
+	set last [string first \n $d $seek]
+	set posix [string range $d $seek [expr {$last-1}]]
+	if {[llength $posix] > 0} {
+	    set posixFields [ParsePosixTimeZone $posix]
+	    foreach tuple [ProcessPosixTimeZone $posixFields] {
+		lassign $tuple t gmtoff isDst abbrev
+		if {$t > $lastTime} {
+		    lappend r $tuple
+		}
+	    }
+	}
+    }
+
+    set TZData(:$fileName) $r
+
+    return
+}
+
+#----------------------------------------------------------------------
+#
+# ParsePosixTimeZone --
+#
+#	Parses the TZ environment variable in Posix form
+#
+# Parameters:
+#	tz	Time zone specifier to be interpreted
+#
+# Results:
+#	Returns a dictionary whose values contain the various pieces of the
+#	time zone specification.
+#
+# Side effects:
+#	None.
+#
+# Errors:
+#	Throws an error if the syntax of the time zone is incorrect.
+#
+# The following keys are present in the dictionary:
+#	stdName - Name of the time zone when Daylight Saving Time
+#		  is not in effect.
+#	stdSignum - Sign (+, -, or empty) of the offset from Greenwich
+#		    to the given (non-DST) time zone.  + and the empty
+#		    string denote zones west of Greenwich, - denotes east
+#		    of Greenwich; this is contrary to the ISO convention
+#		    but follows Posix.
+#	stdHours - Hours part of the offset from Greenwich to the given
+#		   (non-DST) time zone.
+#	stdMinutes - Minutes part of the offset from Greenwich to the
+#		     given (non-DST) time zone. Empty denotes zero.
+#	stdSeconds - Seconds part of the offset from Greenwich to the
+#		     given (non-DST) time zone. Empty denotes zero.
+#	dstName - Name of the time zone when DST is in effect, or the
+#		  empty string if the time zone does not observe Daylight
+#		  Saving Time.
+#	dstSignum, dstHours, dstMinutes, dstSeconds -
+#		Fields corresponding to stdSignum, stdHours, stdMinutes,
+#		stdSeconds for the Daylight Saving Time version of the
+#		time zone.  If dstHours is empty, it is presumed to be 1.
+#	startDayOfYear - The ordinal number of the day of the year on which
+#			 Daylight Saving Time begins.  If this field is
+#			 empty, then DST begins on a given month-week-day,
+#			 as below.
+#	startJ - The letter J, or an empty string.  If a J is present in
+#		 this field, then startDayOfYear does not count February 29
+#		 even in leap years.
+#	startMonth - The number of the month in which Daylight Saving Time
+#		     begins, supplied if startDayOfYear is empty.  If both
+#		     startDayOfYear and startMonth are empty, then US rules
+#		     are presumed.
+#	startWeekOfMonth - The number of the week in the month in which
+#			   Daylight Saving Time begins, in the range 1-5.
+#			   5 denotes the last week of the month even in a
+#			   4-week month.
+#	startDayOfWeek - The number of the day of the week (Sunday=0,
+#			 Saturday=6) on which Daylight Saving Time begins.
+#	startHours - The hours part of the time of day at which Daylight
+#		     Saving Time begins. An empty string is presumed to be 2.
+#	startMinutes - The minutes part of the time of day at which DST begins.
+#		       An empty string is presumed zero.
+#	startSeconds - The seconds part of the time of day at which DST begins.
+#		       An empty string is presumed zero.
+#	endDayOfYear, endJ, endMonth, endWeekOfMonth, endDayOfWeek,
+#	endHours, endMinutes, endSeconds -
+#		Specify the end of DST in the same way that the start* fields
+#		specify the beginning of DST.
+#
+# This procedure serves only to break the time specifier into fields.  No
+# attempt is made to canonicalize the fields or supply default values.
+#
+#----------------------------------------------------------------------
+
+proc ::tcl::clock::ParsePosixTimeZone { tz } {
+    if {[regexp -expanded -nocase -- {
+	^
+	# 1 - Standard time zone name
+	([[:alpha:]]+ | <[-+[:alnum:]]+>)
+	# 2 - Standard time zone offset, signum
+	([-+]?)
+	# 3 - Standard time zone offset, hours
+	([[:digit:]]{1,2})
+	(?:
+	    # 4 - Standard time zone offset, minutes
+	    : ([[:digit:]]{1,2})
+	    (?:
+	        # 5 - Standard time zone offset, seconds
+		: ([[:digit:]]{1,2} )
+	    )?
+	)?
+	(?:
+	    # 6 - DST time zone name
+	    ([[:alpha:]]+ | <[-+[:alnum:]]+>)
+	    (?:
+	        (?:
+		    # 7 - DST time zone offset, signum
+		    ([-+]?)
+		    # 8 - DST time zone offset, hours
+		    ([[:digit:]]{1,2})
+		    (?:
+			# 9 - DST time zone offset, minutes
+			: ([[:digit:]]{1,2})
+			(?:
+		            # 10 - DST time zone offset, seconds
+			    : ([[:digit:]]{1,2})
+			)?
+		    )?
+		)?
+	        (?:
+		    ,
+		    (?:
+			# 11 - Optional J in n and Jn form 12 - Day of year
+		        ( J ? )	( [[:digit:]]+ )
+                        | M
+			# 13 - Month number 14 - Week of month 15 - Day of week
+			( [[:digit:]] + )
+			[.] ( [[:digit:]] + )
+			[.] ( [[:digit:]] + )
+		    )
+		    (?:
+			# 16 - Start time of DST - hours
+			/ ( [[:digit:]]{1,2} )
+		        (?:
+			    # 17 - Start time of DST - minutes
+			    : ( [[:digit:]]{1,2} )
+			    (?:
+				# 18 - Start time of DST - seconds
+				: ( [[:digit:]]{1,2} )
+			    )?
+			)?
+		    )?
+		    ,
+		    (?:
+			# 19 - Optional J in n and Jn form 20 - Day of year
+		        ( J ? )	( [[:digit:]]+ )
+                        | M
+			# 21 - Month number 22 - Week of month 23 - Day of week
+			( [[:digit:]] + )
+			[.] ( [[:digit:]] + )
+			[.] ( [[:digit:]] + )
+		    )
+		    (?:
+			# 24 - End time of DST - hours
+			/ ( [[:digit:]]{1,2} )
+		        (?:
+			    # 25 - End time of DST - minutes
+			    : ( [[:digit:]]{1,2} )
+			    (?:
+				# 26 - End time of DST - seconds
+				: ( [[:digit:]]{1,2} )
+			    )?
+			)?
+		    )?
+                )?
+	    )?
+        )?
+	$
+    } $tz -> x(stdName) x(stdSignum) x(stdHours) x(stdMinutes) x(stdSeconds) \
+	     x(dstName) x(dstSignum) x(dstHours) x(dstMinutes) x(dstSeconds) \
+	     x(startJ) x(startDayOfYear) \
+	     x(startMonth) x(startWeekOfMonth) x(startDayOfWeek) \
+	     x(startHours) x(startMinutes) x(startSeconds) \
+	     x(endJ) x(endDayOfYear) \
+	     x(endMonth) x(endWeekOfMonth) x(endDayOfWeek) \
+	     x(endHours) x(endMinutes) x(endSeconds)] } {
+	# it's a good timezone
+
+	return [array get x]
+    }
+
+    return -code error\
+	-errorcode [list CLOCK badTimeZone $tz] \
+	"unable to parse time zone specification \"$tz\""
+}
+
+#----------------------------------------------------------------------
+#
+# ProcessPosixTimeZone --
+#
+#	Handle a Posix time zone after it's been broken out into fields.
+#
+# Parameters:
+#	z - Dictionary returned from 'ParsePosixTimeZone'
+#
+# Results:
+#	Returns time zone information for the 'TZData' array.
+#
+# Side effects:
+#	None.
+#
+#----------------------------------------------------------------------
+
+proc ::tcl::clock::ProcessPosixTimeZone { z } {
+    variable MINWIDE
+    variable TZData
+
+    # Determine the standard time zone name and seconds east of Greenwich
+
+    set stdName [dict get $z stdName]
+    if { [string index $stdName 0] eq {<} } {
+	set stdName [string range $stdName 1 end-1]
+    }
+    if { [dict get $z stdSignum] eq {-} } {
+	set stdSignum +1
+    } else {
+	set stdSignum -1
+    }
+    set stdHours [lindex [::scan [dict get $z stdHours] %d] 0]
+    if { [dict get $z stdMinutes] ne {} } {
+	set stdMinutes [lindex [::scan [dict get $z stdMinutes] %d] 0]
+    } else {
+	set stdMinutes 0
+    }
+    if { [dict get $z stdSeconds] ne {} } {
+	set stdSeconds [lindex [::scan [dict get $z stdSeconds] %d] 0]
+    } else {
+	set stdSeconds 0
+    }
+    set stdOffset [expr {
+	(($stdHours * 60 + $stdMinutes) * 60 + $stdSeconds) * $stdSignum
+    }]
+    set data [list [list $MINWIDE $stdOffset 0 $stdName]]
+
+    # If there's no daylight zone, we're done
+
+    set dstName [dict get $z dstName]
+    if { $dstName eq {} } {
+	return $data
+    }
+    if { [string index $dstName 0] eq {<} } {
+	set dstName [string range $dstName 1 end-1]
+    }
+
+    # Determine the daylight name
+
+    if { [dict get $z dstSignum] eq {-} } {
+	set dstSignum +1
+    } else {
+	set dstSignum -1
+    }
+    if { [dict get $z dstHours] eq {} } {
+	set dstOffset [expr { 3600 + $stdOffset }]
+    } else {
+	set dstHours [lindex [::scan [dict get $z dstHours] %d] 0]
+	if { [dict get $z dstMinutes] ne {} } {
+	    set dstMinutes [lindex [::scan [dict get $z dstMinutes] %d] 0]
+	} else {
+	    set dstMinutes 0
+	}
+	if { [dict get $z dstSeconds] ne {} } {
+	    set dstSeconds [lindex [::scan [dict get $z dstSeconds] %d] 0]
+	} else {
+	    set dstSeconds 0
+	}
+	set dstOffset [expr {
+	    (($dstHours*60 + $dstMinutes) * 60 + $dstSeconds) * $dstSignum
+	}]
+    }
+
+    # Fill in defaults for European or US DST rules
+    # US start time is the second Sunday in March
+    # EU start time is the last Sunday in March
+    # US end time is the first Sunday in November.
+    # EU end time is the last Sunday in October
+
+    if {
+	[dict get $z startDayOfYear] eq {}
+	&& [dict get $z startMonth] eq {}
+    } then {
+	if {($stdSignum * $stdHours>=0) && ($stdSignum * $stdHours<=12)} {
+	    # EU
+	    dict set z startWeekOfMonth 5
+	    if {$stdHours>2} {
+		dict set z startHours 2
+	    } else {
+		dict set z startHours [expr {$stdHours+1}]
+	    }
+	} else {
+	    # US
+	    dict set z startWeekOfMonth 2
+	    dict set z startHours 2
+	}
+	dict set z startMonth 3
+	dict set z startDayOfWeek 0
+	dict set z startMinutes 0
+	dict set z startSeconds 0
+    }
+    if {
+	[dict get $z endDayOfYear] eq {}
+	&& [dict get $z endMonth] eq {}
+    } then {
+	if {($stdSignum * $stdHours>=0) && ($stdSignum * $stdHours<=12)} {
+	    # EU
+	    dict set z endMonth 10
+	    dict set z endWeekOfMonth 5
+	    if {$stdHours>2} {
+		dict set z endHours 3
+	    } else {
+		dict set z endHours [expr {$stdHours+2}]
+	    }
+	} else {
+	    # US
+	    dict set z endMonth 11
+	    dict set z endWeekOfMonth 1
+	    dict set z endHours 2
+	}
+	dict set z endDayOfWeek 0
+	dict set z endMinutes 0
+	dict set z endSeconds 0
+    }
+
+    # Put DST in effect in all years from 1916 to 2099.
+
+    for { set y 1916 } { $y < 2100 } { incr y } {
+	set startTime [DeterminePosixDSTTime $z start $y]
+	incr startTime [expr { - wide($stdOffset) }]
+	set endTime [DeterminePosixDSTTime $z end $y]
+	incr endTime [expr { - wide($dstOffset) }]
+	if { $startTime < $endTime } {
+	    lappend data \
+		[list $startTime $dstOffset 1 $dstName] \
+		[list $endTime $stdOffset 0 $stdName]
+	} else {
+	    lappend data \
+		[list $endTime $stdOffset 0 $stdName] \
+		[list $startTime $dstOffset 1 $dstName]
+	}
+    }
+
+    return $data
+}
+
+#----------------------------------------------------------------------
+#
+# DeterminePosixDSTTime --
+#
+#	Determines the time that Daylight Saving Time starts or ends from a
+#	Posix time zone specification.
+#
+# Parameters:
+#	z - Time zone data returned from ParsePosixTimeZone.
+#	    Missing fields are expected to be filled in with
+#	    default values.
+#	bound - The word 'start' or 'end'
+#	y - The year for which the transition time is to be determined.
+#
+# Results:
+#	Returns the transition time as a count of seconds from the epoch.  The
+#	time is relative to the wall clock, not UTC.
+#
+#----------------------------------------------------------------------
+
+proc ::tcl::clock::DeterminePosixDSTTime { z bound y } {
+
+    variable FEB_28
+
+    # Determine the start or end day of DST
+
+    set date [dict create era CE year $y]
+    set doy [dict get $z ${bound}DayOfYear]
+    if { $doy ne {} } {
+
+	# Time was specified as a day of the year
+
+	if { [dict get $z ${bound}J] ne {}
+	     && [IsGregorianLeapYear $y]
+	     && ( $doy > $FEB_28 ) } {
+	    incr doy
+	}
+	dict set date dayOfYear $doy
+	set date [GetJulianDayFromEraYearDay $date[set date {}] 2361222]
+    } else {
+	# Time was specified as a day of the week within a month
+
+	dict set date month [dict get $z ${bound}Month]
+	dict set date dayOfWeek [dict get $z ${bound}DayOfWeek]
+	set dowim [dict get $z ${bound}WeekOfMonth]
+	if { $dowim >= 5 } {
+	    set dowim -1
+	}
+	dict set date dayOfWeekInMonth $dowim
+	set date [GetJulianDayFromEraYearMonthWeekDay $date[set date {}] 2361222]
+
+    }
+
+    set jd [dict get $date julianDay]
+    set seconds [expr {
+	wide($jd) * wide(86400) - wide(210866803200)
+    }]
+
+    set h [dict get $z ${bound}Hours]
+    if { $h eq {} } {
+	set h 2
+    } else {
+	set h [lindex [::scan $h %d] 0]
+    }
+    set m [dict get $z ${bound}Minutes]
+    if { $m eq {} } {
+	set m 0
+    } else {
+	set m [lindex [::scan $m %d] 0]
+    }
+    set s [dict get $z ${bound}Seconds]
+    if { $s eq {} } {
+	set s 0
+    } else {
+	set s [lindex [::scan $s %d] 0]
+    }
+    set tod [expr { ( $h * 60 + $m ) * 60 + $s }]
+    return [expr { $seconds + $tod }]
+}
+
+#----------------------------------------------------------------------
+#
+# GetLocaleEra --
+#
+#	Given local time expressed in seconds from the Posix epoch,
+#	determine localized era and year within the era.
+#
+# Parameters:
+#	date - Dictionary that must contain the keys, 'localSeconds',
+#	       whose value is expressed as the appropriate local time;
+#	       and 'year', whose value is the Gregorian year.
+#	etable - Value of the LOCALE_ERAS key in the message catalogue
+#	         for the target locale.
+#
+# Results:
+#	Returns the dictionary, augmented with the keys, 'localeEra' and
+#	'localeYear'.
+#
+#----------------------------------------------------------------------
+
+proc ::tcl::clock::GetLocaleEra { date etable } {
+    set index [BSearch $etable [dict get $date localSeconds]]
+    if { $index < 0} {
+	dict set date localeEra \
+	    [::format %02d [expr { [dict get $date year] / 100 }]]
+	dict set date localeYear [expr {
+	    [dict get $date year] % 100
+	}]
+    } else {
+	dict set date localeEra [lindex $etable $index 1]
+	dict set date localeYear [expr {
+	    [dict get $date year] - [lindex $etable $index 2]
+	}]
+    }
+    return $date
+}
+
+#----------------------------------------------------------------------
+#
+# GetJulianDayFromEraYearDay --
+#
+#	Given a year, month and day on the Gregorian calendar, determines
+#	the Julian Day Number beginning at noon on that date.
+#
+# Parameters:
+#	date -- A dictionary in which the 'era', 'year', and
+#		'dayOfYear' slots are populated. The calendar in use
+#		is determined by the date itself relative to:
+#       changeover -- Julian day on which the Gregorian calendar was
+#		adopted in the current locale.
+#
+# Results:
+#	Returns the given dictionary augmented with a 'julianDay' key whose
+#	value is the desired Julian Day Number, and a 'gregorian' key that
+#	specifies whether the calendar is Gregorian (1) or Julian (0).
+#
+# Side effects:
+#	None.
+#
+# Bugs:
+#	This code needs to be moved to the C layer.
+#
+#----------------------------------------------------------------------
+
+proc ::tcl::clock::GetJulianDayFromEraYearDay {date changeover} {
+    # Get absolute year number from the civil year
+
+    switch -exact -- [dict get $date era] {
+	BCE {
+	    set year [expr { 1 - [dict get $date year] }]
+	}
+	CE {
+	    set year [dict get $date year]
+	}
+    }
+    set ym1 [expr { $year - 1 }]
+
+    # Try the Gregorian calendar first.
+
+    dict set date gregorian 1
+    set jd [expr {
+	1721425
+	+ [dict get $date dayOfYear]
+	+ ( 365 * $ym1 )
+	+ ( $ym1 / 4 )
+	- ( $ym1 / 100 )
+	+ ( $ym1 / 400 )
+    }]
+
+    # If the date is before the Gregorian change, use the Julian calendar.
+
+    if { $jd < $changeover } {
+	dict set date gregorian 0
+	set jd [expr {
+	    1721423
+	    + [dict get $date dayOfYear]
+	    + ( 365 * $ym1 )
+	    + ( $ym1 / 4 )
+	}]
+    }
+
+    dict set date julianDay $jd
+    return $date
+}
+
+#----------------------------------------------------------------------
+#
+# GetJulianDayFromEraYearMonthWeekDay --
+#
+#	Determines the Julian Day number corresponding to the nth given
+#	day-of-the-week in a given month.
+#
+# Parameters:
+#	date - Dictionary containing the keys, 'era', 'year', 'month'
+#	       'weekOfMonth', 'dayOfWeek', and 'dayOfWeekInMonth'.
+#	changeover - Julian Day of adoption of the Gregorian calendar
+#
+# Results:
+#	Returns the given dictionary, augmented with a 'julianDay' key.
+#
+# Side effects:
+#	None.
+#
+# Bugs:
+#	This code needs to be moved to the C layer.
+#
+#----------------------------------------------------------------------
+
+proc ::tcl::clock::GetJulianDayFromEraYearMonthWeekDay {date changeover} {
+    # Come up with a reference day; either the zeroeth day of the given month
+    # (dayOfWeekInMonth >= 0) or the seventh day of the following month
+    # (dayOfWeekInMonth < 0)
+
+    set date2 $date
+    set week [dict get $date dayOfWeekInMonth]
+    if { $week >= 0 } {
+	dict set date2 dayOfMonth 0
+    } else {
+	dict incr date2 month
+	dict set date2 dayOfMonth 7
+    }
+    set date2 [GetJulianDayFromEraYearMonthDay $date2[set date2 {}] \
+		   $changeover]
+    set wd0 [WeekdayOnOrBefore [dict get $date dayOfWeek] \
+		 [dict get $date2 julianDay]]
+    dict set date julianDay [expr { $wd0 + 7 * $week }]
+    return $date
+}
+
+#----------------------------------------------------------------------
+#
+# IsGregorianLeapYear --
+#
+#	Determines whether a given date represents a leap year in the
+#	Gregorian calendar.
+#
+# Parameters:
+#	date -- The date to test.  The fields, 'era', 'year' and 'gregorian'
+#	        must be set.
+#
+# Results:
+#	Returns 1 if the year is a leap year, 0 otherwise.
+#
+# Side effects:
+#	None.
+#
+#----------------------------------------------------------------------
+
+proc ::tcl::clock::IsGregorianLeapYear { date } {
+    switch -exact -- [dict get $date era] {
+	BCE {
+	    set year [expr { 1 - [dict get $date year]}]
+	}
+	CE {
+	    set year [dict get $date year]
+	}
+    }
+    if { $year % 4 != 0 } {
+	return 0
+    } elseif { ![dict get $date gregorian] } {
+	return 1
+    } elseif { $year % 400 == 0 } {
+	return 1
+    } elseif { $year % 100 == 0 } {
+	return 0
+    } else {
+	return 1
+    }
+}
+
+#----------------------------------------------------------------------
+#
+# WeekdayOnOrBefore --
+#
+#	Determine the nearest day of week (given by the 'weekday' parameter,
+#	Sunday==0) on or before a given Julian Day.
+#
+# Parameters:
+#	weekday -- Day of the week
+#	j -- Julian Day number
+#
+# Results:
+#	Returns the Julian Day Number of the desired date.
+#
+# Side effects:
+#	None.
+#
+#----------------------------------------------------------------------
+
+proc ::tcl::clock::WeekdayOnOrBefore { weekday j } {
+    set k [expr { ( $weekday + 6 )  % 7 }]
+    return [expr { $j - ( $j - $k ) % 7 }]
+}
+
+#----------------------------------------------------------------------
+#
+# BSearch --
+#
+#	Service procedure that does binary search in several places inside the
+#	'clock' command.
+#
+# Parameters:
+#	list - List of lists, sorted in ascending order by the
+#	       first elements
+#	key - Value to search for
+#
+# Results:
+#	Returns the index of the greatest element in $list that is less than
+#	or equal to $key.
+#
+# Side effects:
+#	None.
+#
+#----------------------------------------------------------------------
+
+proc ::tcl::clock::BSearch { list key } {
+    if {[llength $list] == 0} {
+	return -1
+    }
+    if { $key < [lindex $list 0 0] } {
+	return -1
+    }
+
+    set l 0
+    set u [expr { [llength $list] - 1 }]
+
+    while { $l < $u } {
+	# At this point, we know that
+	#   $k >= [lindex $list $l 0]
+	#   Either $u == [llength $list] or else $k < [lindex $list $u+1 0]
+	# We find the midpoint of the interval {l,u} rounded UP, compare
+	# against it, and set l or u to maintain the invariant.  Note that the
+	# interval shrinks at each step, guaranteeing convergence.
+
+	set m [expr { ( $l + $u + 1 ) / 2 }]
+	if { $key >= [lindex $list $m 0] } {
+	    set l $m
+	} else {
+	    set u [expr { $m - 1 }]
+	}
+    }
+
+    return $l
+}
+
+#----------------------------------------------------------------------
+#
+# clock add --
+#
+#	Adds an offset to a given time.
+#
+# Syntax:
+#	clock add clockval ?count unit?... ?-option value?
+#
+# Parameters:
+#	clockval -- Starting time value
+#	count -- Amount of a unit of time to add
+#	unit -- Unit of time to add, must be one of:
+#			years year months month weeks week
+#			days day hours hour minutes minute
+#			seconds second
+#
+# Options:
+#	-gmt BOOLEAN
+#		(Deprecated) Flag synonymous with '-timezone :GMT'
+#	-timezone ZONE
+#		Name of the time zone in which calculations are to be done.
+#	-locale NAME
+#		Name of the locale in which calculations are to be done.
+#		Used to determine the Gregorian change date.
+#
+# Results:
+#	Returns the given time adjusted by the given offset(s) in
+#	order.
+#
+# Notes:
+#	It is possible that adding a number of months or years will adjust the
+#	day of the month as well.  For instance, the time at one month after
+#	31 January is either 28 or 29 February, because February has fewer
+#	than 31 days.
+#
+#----------------------------------------------------------------------
+
+proc ::tcl::clock::add { clockval args } {
+    if { [llength $args] % 2 != 0 } {
+	set cmdName "clock add"
+	return -code error \
+	    -errorcode [list CLOCK wrongNumArgs] \
+	    "wrong \# args: should be\
+             \"$cmdName clockval ?number units?...\
+             ?-gmt boolean? ?-locale LOCALE? ?-timezone ZONE?\""
+    }
+    if { [catch { expr {wide($clockval)} } result] } {
+	return -code error $result
+    }
+
+    set offsets {}
+    set gmt 0
+    set locale c
+    set timezone [GetSystemTimeZone]
+
+    foreach { a b } $args {
+	if { [string is integer -strict $a] } {
+	    lappend offsets $a $b
+	} else {
+	    switch -exact -- $a {
+		-g - -gm - -gmt {
+		    set gmt $b
+		}
+		-l - -lo - -loc - -loca - -local - -locale {
+		    set locale [string tolower $b]
+		}
+		-t - -ti - -tim - -time - -timez - -timezo - -timezon -
+		-timezone {
+		    set timezone $b
+		}
+		default {
+		    throw [list CLOCK badOption $a] \
+			"bad option \"$a\",\
+                         must be -gmt, -locale or -timezone"
+		}
+	    }
+	}
+    }
+
+    # Check options for validity
+
+    if { [info exists saw(-gmt)] && [info exists saw(-timezone)] } {
+	return -code error \
+	    -errorcode [list CLOCK gmtWithTimezone] \
+	    "cannot use -gmt and -timezone in same call"
+    }
+    if { [catch { expr { wide($clockval) } } result] } {
+	return -code error "expected integer but got \"$clockval\""
+    }
+    if { ![string is boolean -strict $gmt] } {
+	return -code error "expected boolean value but got \"$gmt\""
+    } elseif { $gmt } {
+	set timezone :GMT
+    }
+
+    EnterLocale $locale
+
+    set changeover [mc GREGORIAN_CHANGE_DATE]
+
+    if {[catch {SetupTimeZone $timezone} retval opts]} {
+	dict unset opts -errorinfo
+	return -options $opts $retval
+    }
+
+    try {
+	foreach { quantity unit } $offsets {
+	    switch -exact -- $unit {
+		years - year {
+		    set clockval [AddMonths [expr { 12 * $quantity }] \
+			    $clockval $timezone $changeover]
+		}
+		months - month {
+		    set clockval [AddMonths $quantity $clockval $timezone \
+			    $changeover]
+		}
+
+		weeks - week {
+		    set clockval [AddDays [expr { 7 * $quantity }] \
+			    $clockval $timezone $changeover]
+		}
+		days - day {
+		    set clockval [AddDays $quantity $clockval $timezone \
+			    $changeover]
+		}
+
+		hours - hour {
+		    set clockval [expr { 3600 * $quantity + $clockval }]
+		}
+		minutes - minute {
+		    set clockval [expr { 60 * $quantity + $clockval }]
+		}
+		seconds - second {
+		    set clockval [expr { $quantity + $clockval }]
+		}
+
+		default {
+		    throw [list CLOCK badUnit $unit] \
+			"unknown unit \"$unit\", must be \
+                        years, months, weeks, days, hours, minutes or seconds"
+		}
+	    }
+	}
+	return $clockval
+    } trap CLOCK {result opts} {
+	# Conceal the innards of [clock] when it's an expected error
+	dict unset opts -errorinfo
+	return -options $opts $result
+    }
+}
+
+#----------------------------------------------------------------------
+#
+# AddMonths --
+#
+#	Add a given number of months to a given clock value in a given
+#	time zone.
+#
+# Parameters:
+#	months - Number of months to add (may be negative)
+#	clockval - Seconds since the epoch before the operation
+#	timezone - Time zone in which the operation is to be performed
+#
+# Results:
+#	Returns the new clock value as a number of seconds since
+#	the epoch.
+#
+# Side effects:
+#	None.
+#
+#----------------------------------------------------------------------
+
+proc ::tcl::clock::AddMonths { months clockval timezone changeover } {
+    variable DaysInRomanMonthInCommonYear
+    variable DaysInRomanMonthInLeapYear
+    variable TZData
+
+    # Convert the time to year, month, day, and fraction of day.
+
+    set date [GetDateFields $clockval $TZData($timezone) $changeover]
+    dict set date secondOfDay [expr {
+	[dict get $date localSeconds] % 86400
+    }]
+    dict set date tzName $timezone
+
+    # Add the requisite number of months
+
+    set m [dict get $date month]
+    incr m $months
+    incr m -1
+    set delta [expr { $m / 12 }]
+    set mm [expr { $m % 12 }]
+    dict set date month [expr { $mm + 1 }]
+    dict incr date year $delta
+
+    # If the date doesn't exist in the current month, repair it
+
+    if { [IsGregorianLeapYear $date] } {
+	set hath [lindex $DaysInRomanMonthInLeapYear $mm]
+    } else {
+	set hath [lindex $DaysInRomanMonthInCommonYear $mm]
+    }
+    if { [dict get $date dayOfMonth] > $hath } {
+	dict set date dayOfMonth $hath
+    }
+
+    # Reconvert to a number of seconds
+
+    set date [GetJulianDayFromEraYearMonthDay \
+		  $date[set date {}]\
+		  $changeover]
+    dict set date localSeconds [expr {
+	-210866803200
+	+ ( 86400 * wide([dict get $date julianDay]) )
+	+ [dict get $date secondOfDay]
+    }]
+    set date [ConvertLocalToUTC $date[set date {}] $TZData($timezone) \
+		 $changeover]
+
+    return [dict get $date seconds]
+
+}
+
+#----------------------------------------------------------------------
+#
+# AddDays --
+#
+#	Add a given number of days to a given clock value in a given time
+#	zone.
+#
+# Parameters:
+#	days - Number of days to add (may be negative)
+#	clockval - Seconds since the epoch before the operation
+#	timezone - Time zone in which the operation is to be performed
+#	changeover - Julian Day on which the Gregorian calendar was adopted
+#		     in the target locale.
+#
+# Results:
+#	Returns the new clock value as a number of seconds since the epoch.
+#
+# Side effects:
+#	None.
+#
+#----------------------------------------------------------------------
+
+proc ::tcl::clock::AddDays { days clockval timezone changeover } {
+    variable TZData
+
+    # Convert the time to Julian Day
+
+    set date [GetDateFields $clockval $TZData($timezone) $changeover]
+    dict set date secondOfDay [expr {
+	[dict get $date localSeconds] % 86400
+    }]
+    dict set date tzName $timezone
+
+    # Add the requisite number of days
+
+    dict incr date julianDay $days
+
+    # Reconvert to a number of seconds
+
+    dict set date localSeconds [expr {
+	-210866803200
+	+ ( 86400 * wide([dict get $date julianDay]) )
+	+ [dict get $date secondOfDay]
+    }]
+    set date [ConvertLocalToUTC $date[set date {}] $TZData($timezone) \
+		  $changeover]
+
+    return [dict get $date seconds]
+
+}
+
+#----------------------------------------------------------------------
+#
+# ChangeCurrentLocale --
+#
+#        The global locale was changed within msgcat.
+#        Clears the buffered parse functions of the current locale.
+#
+# Parameters:
+#        loclist (ignored)
+#
+# Results:
+#        None.
+#
+# Side effects:
+#        Buffered parse functions are cleared.
+#
+#----------------------------------------------------------------------
+
+proc ::tcl::clock::ChangeCurrentLocale {args} {
+    variable FormatProc
+    variable LocaleNumeralCache
+    variable CachedSystemTimeZone
+    variable TimeZoneBad
+
+    foreach p [info procs [namespace current]::scanproc'*'current] {
+        rename $p {}
+    }
+    foreach p [info procs [namespace current]::formatproc'*'current] {
+        rename $p {}
+    }
+
+    catch {array unset FormatProc *'current}
+    set LocaleNumeralCache {}
+}
+
+#----------------------------------------------------------------------
+#
+# ClearCaches --
+#
+#	Clears all caches to reclaim the memory used in [clock]
+#
+# Parameters:
+#	None.
+#
+# Results:
+#	None.
+#
+# Side effects:
+#	Caches are cleared.
+#
+#----------------------------------------------------------------------
+
+proc ::tcl::clock::ClearCaches {} {
+    variable FormatProc
+    variable LocaleNumeralCache
+    variable CachedSystemTimeZone
+    variable TimeZoneBad
+
+    foreach p [info procs [namespace current]::scanproc'*] {
+	rename $p {}
+    }
+    foreach p [info procs [namespace current]::formatproc'*] {
+	rename $p {}
+    }
+
+    catch {unset FormatProc}
+    set LocaleNumeralCache {}
+    catch {unset CachedSystemTimeZone}
+    set TimeZoneBad {}
+    InitTZData
+}
diff --git a/library/dde/pkgIndex.tcl b/library/dde/pkgIndex.tcl
new file mode 100644
index 0000000..4cf73d0
--- /dev/null
+++ b/library/dde/pkgIndex.tcl
@@ -0,0 +1,7 @@
+if {([info commands ::tcl::pkgconfig] eq "")
+	|| ([info sharedlibextension] ne ".dll")} return
+if {[::tcl::pkgconfig get debug]} {
+    package ifneeded dde 1.4.0 [list load [file join $dir tcldde14g.dll] dde]
+} else {
+    package ifneeded dde 1.4.0 [list load [file join $dir tcldde14.dll] dde]
+}
diff --git a/library/encoding/ascii.enc b/library/encoding/ascii.enc
new file mode 100644
index 0000000..e0320b8
--- /dev/null
+++ b/library/encoding/ascii.enc
@@ -0,0 +1,20 @@
+# Encoding file: ascii, single-byte
+S
+003F 0 1
+00
+0000000100020003000400050006000700080009000A000B000C000D000E000F
+0010001100120013001400150016001700180019001A001B001C001D001E001F
+0020002100220023002400250026002700280029002A002B002C002D002E002F
+0030003100320033003400350036003700380039003A003B003C003D003E003F
+0040004100420043004400450046004700480049004A004B004C004D004E004F
+0050005100520053005400550056005700580059005A005B005C005D005E005F
+0060006100620063006400650066006700680069006A006B006C006D006E006F
+0070007100720073007400750076007700780079007A007B007C007D007E0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
diff --git a/library/encoding/big5.enc b/library/encoding/big5.enc
new file mode 100644
index 0000000..26179f4
--- /dev/null
+++ b/library/encoding/big5.enc
@@ -0,0 +1,1516 @@
+# Encoding file: big5, multi-byte
+M
+003F 0 89
+00
+0000000100020003000400050006000700080009000A000B000C000D000E000F
+0010001100120013001400150016001700180019001A001B001C001D001E001F
+0020002100220023002400250026002700280029002A002B002C002D002E002F
+0030003100320033003400350036003700380039003A003B003C003D003E003F
+0040004100420043004400450046004700480049004A004B004C004D004E004F
+0050005100520053005400550056005700580059005A005B005C005D005E005F
+0060006100620063006400650066006700680069006A006B006C006D006E006F
+0070007100720073007400750076007700780079007A007B007C007D007E007F
+0080008100820083008400850086008700880089008A008B008C008D008E008F
+0090009100920093009400950096009700980099009A009B009C009D009E009F
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+A1
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+3000FF0C30013002FF0E2022FF1BFF1AFF1FFF01FE3020262025FE50FF64FE52
+00B7FE54FE55FE56FE57FF5C2013FE312014FE33FFFDFE34FE4FFF08FF09FE35
+FE36FF5BFF5DFE37FE3830143015FE39FE3A30103011FE3BFE3C300A300BFE3D
+FE3E30083009FE3FFE40300C300DFE41FE42300E300FFE43FE44FE59FE5A0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000FE5BFE5CFE5DFE5E20182019201C201D301D301E20352032FF03FF06FF0A
+203B00A7300325CB25CF25B325B225CE2606260525C725C625A125A025BD25BC
+32A32105203EFFFDFF3FFFFDFE49FE4AFE4DFE4EFE4BFE4CFE5FFE60FE61FF0B
+FF0D00D700F700B1221AFF1CFF1EFF1D226622672260221E22522261FE62FE63
+FE64FE65FE66223C2229222A22A52220221F22BF33D233D1222B222E22352234
+26402642264126092191219321902192219621972199219822252223FFFD0000
+A2
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+FFFDFF0FFF3CFF0400A5301200A200A3FF05FF2021032109FE69FE6AFE6B33D5
+339C339D339E33CE33A1338E338F33C400B05159515B515E515D5161516355E7
+74E97CCE25812582258325842585258625872588258F258E258D258C258B258A
+2589253C2534252C2524251C2594250025022595250C251025142518256D0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000256E2570256F2550255E256A256125E225E325E525E4257125722573FF10
+FF11FF12FF13FF14FF15FF16FF17FF18FF192160216121622163216421652166
+216721682169302130223023302430253026302730283029FFFD5344FFFDFF21
+FF22FF23FF24FF25FF26FF27FF28FF29FF2AFF2BFF2CFF2DFF2EFF2FFF30FF31
+FF32FF33FF34FF35FF36FF37FF38FF39FF3AFF41FF42FF43FF44FF45FF46FF47
+FF48FF49FF4AFF4BFF4CFF4DFF4EFF4FFF50FF51FF52FF53FF54FF55FF560000
+A3
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+FF57FF58FF59FF5A039103920393039403950396039703980399039A039B039C
+039D039E039F03A003A103A303A403A503A603A703A803A903B103B203B303B4
+03B503B603B703B803B903BA03BB03BC03BD03BE03BF03C003C103C303C403C5
+03C603C703C803C931053106310731083109310A310B310C310D310E310F0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00003110311131123113311431153116311731183119311A311B311C311D311E
+311F312031213122312331243125312631273128312902D902C902CA02C702CB
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+A4
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+4E004E594E014E034E434E5D4E864E8C4EBA513F5165516B51E052005201529B
+53155341535C53C84E094E0B4E084E0A4E2B4E3851E14E454E484E5F4E5E4E8E
+4EA15140520352FA534353C953E3571F58EB5915592759735B505B515B535BF8
+5C0F5C225C385C715DDD5DE55DF15DF25DF35DFE5E725EFE5F0B5F13624D0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00004E114E104E0D4E2D4E304E394E4B5C394E884E914E954E924E944EA24EC1
+4EC04EC34EC64EC74ECD4ECA4ECB4EC4514351415167516D516E516C519751F6
+52065207520852FB52FE52FF53165339534853475345535E538453CB53CA53CD
+58EC5929592B592A592D5B545C115C245C3A5C6F5DF45E7B5EFF5F145F155FC3
+62086236624B624E652F6587659765A465B965E566F0670867286B206B626B79
+6BCB6BD46BDB6C0F6C34706B722A7236723B72477259725B72AC738B4E190000
+A5
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+4E164E154E144E184E3B4E4D4E4F4E4E4EE54ED84ED44ED54ED64ED74EE34EE4
+4ED94EDE514551445189518A51AC51F951FA51F8520A52A0529F530553065317
+531D4EDF534A534953615360536F536E53BB53EF53E453F353EC53EE53E953E8
+53FC53F853F553EB53E653EA53F253F153F053E553ED53FB56DB56DA59160000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000592E5931597459765B555B835C3C5DE85DE75DE65E025E035E735E7C5F01
+5F185F175FC5620A625362546252625165A565E6672E672C672A672B672D6B63
+6BCD6C116C106C386C416C406C3E72AF7384738974DC74E67518751F75287529
+7530753175327533758B767D76AE76BF76EE77DB77E277F3793A79BE7A747ACB
+4E1E4E1F4E524E534E694E994EA44EA64EA54EFF4F094F194F0A4F154F0D4F10
+4F114F0F4EF24EF64EFB4EF04EF34EFD4F014F0B514951475146514851680000
+A6
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+5171518D51B0521752115212520E521652A3530853215320537053715409540F
+540C540A54105401540B54045411540D54085403540E5406541256E056DE56DD
+573357305728572D572C572F57295919591A59375938598459785983597D5979
+598259815B575B585B875B885B855B895BFA5C165C795DDE5E065E765E740000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00005F0F5F1B5FD95FD6620E620C620D62106263625B6258653665E965E865EC
+65ED66F266F36709673D6734673167356B216B646B7B6C166C5D6C576C596C5F
+6C606C506C556C616C5B6C4D6C4E7070725F725D767E7AF97C737CF87F367F8A
+7FBD80018003800C80128033807F8089808B808C81E381EA81F381FC820C821B
+821F826E8272827E866B8840884C8863897F96214E324EA84F4D4F4F4F474F57
+4F5E4F344F5B4F554F304F504F514F3D4F3A4F384F434F544F3C4F464F630000
+A7
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+4F5C4F604F2F4F4E4F364F594F5D4F484F5A514C514B514D517551B651B75225
+52245229522A522852AB52A952AA52AC532353735375541D542D541E543E5426
+544E542754465443543354485442541B5429544A5439543B5438542E54355436
+5420543C54405431542B541F542C56EA56F056E456EB574A57515740574D0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00005747574E573E5750574F573B58EF593E599D599259A8599E59A359995996
+598D59A45993598A59A55B5D5B5C5B5A5B5B5B8C5B8B5B8F5C2C5C405C415C3F
+5C3E5C905C915C945C8C5DEB5E0C5E8F5E875E8A5EF75F045F1F5F645F625F77
+5F795FD85FCC5FD75FCD5FF15FEB5FF85FEA6212621162846297629662806276
+6289626D628A627C627E627962736292626F6298626E62956293629162866539
+653B653865F166F4675F674E674F67506751675C6756675E6749674667600000
+A8
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+675367576B656BCF6C426C5E6C996C816C886C896C856C9B6C6A6C7A6C906C70
+6C8C6C686C966C926C7D6C836C726C7E6C746C866C766C8D6C946C986C827076
+707C707D707872627261726072C472C27396752C752B75377538768276EF77E3
+79C179C079BF7A767CFB7F5580968093809D8098809B809A80B2826F82920000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000828B828D898B89D28A008C378C468C558C9D8D648D708DB38EAB8ECA8F9B
+8FB08FC28FC68FC58FC45DE1909190A290AA90A690A3914991C691CC9632962E
+9631962A962C4E264E564E734E8B4E9B4E9E4EAB4EAC4F6F4F9D4F8D4F734F7F
+4F6C4F9B4F8B4F864F834F704F754F884F694F7B4F964F7E4F8F4F914F7A5154
+51525155516951775176517851BD51FD523B52385237523A5230522E52365241
+52BE52BB5352535453535351536653775378537953D653D453D7547354750000
+A9
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+5496547854955480547B5477548454925486547C549054715476548C549A5462
+5468548B547D548E56FA57835777576A5769576157665764577C591C59495947
+59485944595459BE59BB59D459B959AE59D159C659D059CD59CB59D359CA59AF
+59B359D259C55B5F5B645B635B975B9A5B985B9C5B995B9B5C1A5C485C450000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00005C465CB75CA15CB85CA95CAB5CB15CB35E185E1A5E165E155E1B5E115E78
+5E9A5E975E9C5E955E965EF65F265F275F295F805F815F7F5F7C5FDD5FE05FFD
+5FF55FFF600F6014602F60356016602A6015602160276029602B601B62166215
+623F623E6240627F62C962CC62C462BF62C262B962D262DB62AB62D362D462CB
+62C862A862BD62BC62D062D962C762CD62B562DA62B162D862D662D762C662AC
+62CE653E65A765BC65FA66146613660C66066602660E6600660F6615660A0000
+AA
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+6607670D670B676D678B67956771679C677367776787679D6797676F6770677F
+6789677E67906775679A6793677C676A67726B236B666B676B7F6C136C1B6CE3
+6CE86CF36CB16CCC6CE56CB36CBD6CBE6CBC6CE26CAB6CD56CD36CB86CC46CB9
+6CC16CAE6CD76CC56CF16CBF6CBB6CE16CDB6CCA6CAC6CEF6CDC6CD66CE00000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00007095708E7092708A7099722C722D723872487267726972C072CE72D972D7
+72D073A973A8739F73AB73A5753D759D7599759A768476C276F276F477E577FD
+793E7940794179C979C87A7A7A797AFA7CFE7F547F8C7F8B800580BA80A580A2
+80B180A180AB80A980B480AA80AF81E581FE820D82B3829D829982AD82BD829F
+82B982B182AC82A582AF82B882A382B082BE82B7864E8671521D88688ECB8FCE
+8FD48FD190B590B890B190B691C791D195779580961C9640963F963B96440000
+AB
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+964296B996E89752975E4E9F4EAD4EAE4FE14FB54FAF4FBF4FE04FD14FCF4FDD
+4FC34FB64FD84FDF4FCA4FD74FAE4FD04FC44FC24FDA4FCE4FDE4FB751575192
+519151A0524E5243524A524D524C524B524752C752C952C352C1530D5357537B
+539A53DB54AC54C054A854CE54C954B854A654B354C754C254BD54AA54C10000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000054C454C854AF54AB54B154BB54A954A754BF56FF5782578B57A057A357A2
+57CE57AE579359555951594F594E595059DC59D859FF59E359E85A0359E559EA
+59DA59E65A0159FB5B695BA35BA65BA45BA25BA55C015C4E5C4F5C4D5C4B5CD9
+5CD25DF75E1D5E255E1F5E7D5EA05EA65EFA5F085F2D5F655F885F855F8A5F8B
+5F875F8C5F896012601D60206025600E6028604D60706068606260466043606C
+606B606A6064624162DC6316630962FC62ED630162EE62FD630762F162F70000
+AC
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+62EF62EC62FE62F463116302653F654565AB65BD65E26625662D66206627662F
+661F66286631662466F767FF67D367F167D467D067EC67B667AF67F567E967EF
+67C467D167B467DA67E567B867CF67DE67F367B067D967E267DD67D26B6A6B83
+6B866BB56BD26BD76C1F6CC96D0B6D326D2A6D416D256D0C6D316D1E6D170000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00006D3B6D3D6D3E6D366D1B6CF56D396D276D386D296D2E6D356D0E6D2B70AB
+70BA70B370AC70AF70AD70B870AE70A472307272726F727472E972E072E173B7
+73CA73BB73B273CD73C073B3751A752D754F754C754E754B75AB75A475A575A2
+75A3767876867687768876C876C676C376C5770176F976F87709770B76FE76FC
+770777DC78027814780C780D794679497948794779B979BA79D179D279CB7A7F
+7A817AFF7AFD7C7D7D027D057D007D097D077D047D067F387F8E7FBF80040000
+AD
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+8010800D8011803680D680E580DA80C380C480CC80E180DB80CE80DE80E480DD
+81F4822282E78303830582E382DB82E6830482E58302830982D282D782F18301
+82DC82D482D182DE82D382DF82EF830686508679867B867A884D886B898189D4
+8A088A028A038C9E8CA08D748D738DB48ECD8ECC8FF08FE68FE28FEA8FE50000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00008FED8FEB8FE48FE890CA90CE90C190C3914B914A91CD95829650964B964C
+964D9762976997CB97ED97F3980198A898DB98DF999699994E584EB3500C500D
+50234FEF502650254FF8502950165006503C501F501A501250114FFA50005014
+50284FF15021500B501950184FF34FEE502D502A4FFE502B5009517C51A451A5
+51A251CD51CC51C651CB5256525C5254525B525D532A537F539F539D53DF54E8
+55105501553754FC54E554F2550654FA551454E954ED54E1550954EE54EA0000
+AE
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+54E65527550754FD550F5703570457C257D457CB57C35809590F59575958595A
+5A115A185A1C5A1F5A1B5A1359EC5A205A235A295A255A0C5A095B6B5C585BB0
+5BB35BB65BB45BAE5BB55BB95BB85C045C515C555C505CED5CFD5CFB5CEA5CE8
+5CF05CF65D015CF45DEE5E2D5E2B5EAB5EAD5EA75F315F925F915F9060590000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00006063606560506055606D6069606F6084609F609A608D6094608C60856096
+624762F3630862FF634E633E632F635563426346634F6349633A6350633D632A
+632B6328634D634C65486549659965C165C566426649664F66436652664C6645
+664166F867146715671768216838684868466853683968426854682968B36817
+684C6851683D67F468506840683C6843682A68456813681868416B8A6B896BB7
+6C236C276C286C266C246CF06D6A6D956D886D876D666D786D776D596D930000
+AF
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+6D6C6D896D6E6D5A6D746D696D8C6D8A6D796D856D656D9470CA70D870E470D9
+70C870CF7239727972FC72F972FD72F872F7738673ED740973EE73E073EA73DE
+7554755D755C755A755975BE75C575C775B275B375BD75BC75B975C275B8768B
+76B076CA76CD76CE7729771F7720772877E9783078277838781D783478370000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00007825782D7820781F7832795579507960795F7956795E795D7957795A79E4
+79E379E779DF79E679E979D87A847A887AD97B067B117C897D217D177D0B7D0A
+7D207D227D147D107D157D1A7D1C7D0D7D197D1B7F3A7F5F7F947FC57FC18006
+8018801580198017803D803F80F1810280F0810580ED80F4810680F880F38108
+80FD810A80FC80EF81ED81EC82008210822A822B8228822C82BB832B83528354
+834A83388350834983358334834F833283398336831783408331832883430000
+B0
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+8654868A86AA869386A486A9868C86A3869C8870887788818882887D88798A18
+8A108A0E8A0C8A158A0A8A178A138A168A0F8A118C488C7A8C798CA18CA28D77
+8EAC8ED28ED48ECF8FB1900190068FF790008FFA8FF490038FFD90058FF89095
+90E190DD90E29152914D914C91D891DD91D791DC91D995839662966396610000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000965B965D96649658965E96BB98E299AC9AA89AD89B259B329B3C4E7E507A
+507D505C50475043504C505A504950655076504E5055507550745077504F500F
+506F506D515C519551F0526A526F52D252D952D852D55310530F5319533F5340
+533E53C366FC5546556A55665544555E55615543554A55315556554F5555552F
+55645538552E555C552C55635533554155575708570B570957DF5805580A5806
+57E057E457FA5802583557F757F9592059625A365A415A495A665A6A5A400000
+B1
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+5A3C5A625A5A5A465A4A5B705BC75BC55BC45BC25BBF5BC65C095C085C075C60
+5C5C5C5D5D075D065D0E5D1B5D165D225D115D295D145D195D245D275D175DE2
+5E385E365E335E375EB75EB85EB65EB55EBE5F355F375F575F6C5F695F6B5F97
+5F995F9E5F985FA15FA05F9C607F60A3608960A060A860CB60B460E660BD0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000060C560BB60B560DC60BC60D860D560C660DF60B860DA60C7621A621B6248
+63A063A76372639663A263A563776367639863AA637163A963896383639B636B
+63A863846388639963A163AC6392638F6380637B63696368637A655D65566551
+65596557555F654F655865556554659C659B65AC65CF65CB65CC65CE665D665A
+666466686666665E66F952D7671B688168AF68A2689368B5687F687668B168A7
+689768B0688368C468AD688668856894689D68A8689F68A168826B326BBA0000
+B2
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+6BEB6BEC6C2B6D8E6DBC6DF36DD96DB26DE16DCC6DE46DFB6DFA6E056DC76DCB
+6DAF6DD16DAE6DDE6DF96DB86DF76DF56DC56DD26E1A6DB56DDA6DEB6DD86DEA
+6DF16DEE6DE86DC66DC46DAA6DEC6DBF6DE670F97109710A70FD70EF723D727D
+7281731C731B73167313731973877405740A7403740673FE740D74E074F60000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000074F7751C75227565756675627570758F75D475D575B575CA75CD768E76D4
+76D276DB7737773E773C77367738773A786B7843784E79657968796D79FB7A92
+7A957B207B287B1B7B2C7B267B197B1E7B2E7C927C977C957D467D437D717D2E
+7D397D3C7D407D307D337D447D2F7D427D327D317F3D7F9E7F9A7FCC7FCE7FD2
+801C804A8046812F81168123812B81298130812482028235823782368239838E
+839E8398837883A2839683BD83AB8392838A8393838983A08377837B837C0000
+B3
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+838683A786555F6A86C786C086B686C486B586C686CB86B186AF86C98853889E
+888888AB88928896888D888B8993898F8A2A8A1D8A238A258A318A2D8A1F8A1B
+8A228C498C5A8CA98CAC8CAB8CA88CAA8CA78D678D668DBE8DBA8EDB8EDF9019
+900D901A90179023901F901D90109015901E9020900F90229016901B90140000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000090E890ED90FD915791CE91F591E691E391E791ED91E99589966A96759673
+96789670967496769677966C96C096EA96E97AE07ADF980298039B5A9CE59E75
+9E7F9EA59EBB50A2508D508550995091508050965098509A670051F152725274
+5275526952DE52DD52DB535A53A5557B558055A7557C558A559D55985582559C
+55AA55945587558B558355B355AE559F553E55B2559A55BB55AC55B1557E5589
+55AB5599570D582F582A58345824583058315821581D582058F958FA59600000
+B4
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+5A775A9A5A7F5A925A9B5AA75B735B715BD25BCC5BD35BD05C0A5C0B5C315D4C
+5D505D345D475DFD5E455E3D5E405E435E7E5ECA5EC15EC25EC45F3C5F6D5FA9
+5FAA5FA860D160E160B260B660E0611C612360FA611560F060FB60F4616860F1
+610E60F6610961006112621F624963A3638C63CF63C063E963C963C663CD0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000063D263E363D063E163D663ED63EE637663F463EA63DB645263DA63F9655E
+6566656265636591659065AF666E667066746676666F6691667A667E667766FE
+66FF671F671D68FA68D568E068D868D7690568DF68F568EE68E768F968D268F2
+68E368CB68CD690D6912690E68C968DA696E68FB6B3E6B3A6B3D6B986B966BBC
+6BEF6C2E6C2F6C2C6E2F6E386E546E216E326E676E4A6E206E256E236E1B6E5B
+6E586E246E566E6E6E2D6E266E6F6E346E4D6E3A6E2C6E436E1D6E3E6ECB0000
+B5
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+6E896E196E4E6E636E446E726E696E5F7119711A7126713071217136716E711C
+724C728472807336732573347329743A742A743374227425743574367434742F
+741B7426742875257526756B756A75E275DB75E375D975D875DE75E0767B767C
+7696769376B476DC774F77ED785D786C786F7A0D7A087A0B7A057A007A980000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00007A977A967AE57AE37B497B567B467B507B527B547B4D7B4B7B4F7B517C9F
+7CA57D5E7D507D687D557D2B7D6E7D727D617D667D627D707D7355847FD47FD5
+800B8052808581558154814B8151814E81398146813E814C815381748212821C
+83E9840383F8840D83E083C5840B83C183EF83F183F48457840A83F0840C83CC
+83FD83F283CA8438840E840483DC840783D483DF865B86DF86D986ED86D486DB
+86E486D086DE885788C188C288B1898389968A3B8A608A558A5E8A3C8A410000
+B6
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+8A548A5B8A508A468A348A3A8A368A568C618C828CAF8CBC8CB38CBD8CC18CBB
+8CC08CB48CB78CB68CBF8CB88D8A8D858D818DCE8DDD8DCB8DDA8DD18DCC8DDB
+8DC68EFB8EF88EFC8F9C902E90359031903890329036910290F5910990FE9163
+916591CF9214921592239209921E920D9210920792119594958F958B95910000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000095939592958E968A968E968B967D96859686968D9672968496C196C596C4
+96C696C796EF96F297CC98059806980898E798EA98EF98E998F298ED99AE99AD
+9EC39ECD9ED14E8250AD50B550B250B350C550BE50AC50B750BB50AF50C7527F
+5277527D52DF52E652E452E252E3532F55DF55E855D355E655CE55DC55C755D1
+55E355E455EF55DA55E155C555C655E555C957125713585E585158585857585A
+5854586B584C586D584A58625852584B59675AC15AC95ACC5ABE5ABD5ABC0000
+B7
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+5AB35AC25AB25D695D6F5E4C5E795EC95EC85F125F595FAC5FAE611A610F6148
+611F60F3611B60F961016108614E614C6144614D613E61346127610D61066137
+622162226413643E641E642A642D643D642C640F641C6414640D643664166417
+6406656C659F65B06697668966876688669666846698668D67036994696D0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000695A697769606954697569306982694A6968696B695E695369796986695D
+6963695B6B476B726BC06BBF6BD36BFD6EA26EAF6ED36EB66EC26E906E9D6EC7
+6EC56EA56E986EBC6EBA6EAB6ED16E966E9C6EC46ED46EAA6EA76EB4714E7159
+7169716471497167715C716C7166714C7165715E714671687156723A72527337
+7345733F733E746F745A7455745F745E7441743F7459745B745C757675787600
+75F0760175F275F175FA75FF75F475F376DE76DF775B776B7766775E77630000
+B8
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+7779776A776C775C77657768776277EE788E78B078977898788C7889787C7891
+7893787F797A797F7981842C79BD7A1C7A1A7A207A147A1F7A1E7A9F7AA07B77
+7BC07B607B6E7B677CB17CB37CB57D937D797D917D817D8F7D5B7F6E7F697F6A
+7F727FA97FA87FA480568058808680848171817081788165816E8173816B0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00008179817A81668205824784828477843D843184758466846B8449846C845B
+843C8435846184638469846D8446865E865C865F86F9871387088707870086FE
+86FB870287038706870A885988DF88D488D988DC88D888DD88E188CA88D588D2
+899C89E38A6B8A728A738A668A698A708A878A7C8A638AA08A718A858A6D8A62
+8A6E8A6C8A798A7B8A3E8A688C628C8A8C898CCA8CC78CC88CC48CB28CC38CC2
+8CC58DE18DDF8DE88DEF8DF38DFA8DEA8DE48DE68EB28F038F098EFE8F0A0000
+B9
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+8F9F8FB2904B904A905390429054903C905590509047904F904E904D9051903E
+904191129117916C916A916991C9923792579238923D9240923E925B924B9264
+925192349249924D92459239923F925A959896989694969596CD96CB96C996CA
+96F796FB96F996F6975697749776981098119813980A9812980C98FC98F40000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000098FD98FE99B399B199B49AE19CE99E829F0E9F139F2050E750EE50E550D6
+50ED50DA50D550CF50D150F150CE50E9516251F352835282533153AD55FE5600
+561B561755FD561456065609560D560E55F75616561F5608561055F657185716
+5875587E58835893588A58795885587D58FD592559225924596A59695AE15AE6
+5AE95AD75AD65AD85AE35B755BDE5BE75BE15BE55BE65BE85BE25BE45BDF5C0D
+5C625D845D875E5B5E635E555E575E545ED35ED65F0A5F465F705FB961470000
+BA
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+613F614B617761626163615F615A61586175622A64876458645464A46478645F
+647A645164676434646D647B657265A165D765D666A266A8669D699C69A86995
+69C169AE69D369CB699B69B769BB69AB69B469D069CD69AD69CC69A669C369A3
+6B496B4C6C336F336F146EFE6F136EF46F296F3E6F206F2C6F0F6F026F220000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00006EFF6EEF6F066F316F386F326F236F156F2B6F2F6F886F2A6EEC6F016EF2
+6ECC6EF771947199717D718A71847192723E729272967344735074647463746A
+7470746D750475917627760D760B7609761376E176E37784777D777F776178C1
+789F78A778B378A978A3798E798F798D7A2E7A317AAA7AA97AED7AEF7BA17B95
+7B8B7B757B977B9D7B947B8F7BB87B877B847CB97CBD7CBE7DBB7DB07D9C7DBD
+7DBE7DA07DCA7DB47DB27DB17DBA7DA27DBF7DB57DB87DAD7DD27DC77DAC0000
+BB
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+7F707FE07FE17FDF805E805A808781508180818F8188818A817F818281E781FA
+82078214821E824B84C984BF84C684C48499849E84B2849C84CB84B884C084D3
+849084BC84D184CA873F871C873B872287258734871887558737872988F38902
+88F488F988F888FD88E8891A88EF8AA68A8C8A9E8AA38A8D8AA18A938AA40000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00008AAA8AA58AA88A988A918A9A8AA78C6A8C8D8C8C8CD38CD18CD28D6B8D99
+8D958DFC8F148F128F158F138FA390609058905C90639059905E9062905D905B
+91199118911E917591789177917492789280928592989296927B9293929C92A8
+927C929195A195A895A995A395A595A49699969C969B96CC96D29700977C9785
+97F69817981898AF98B199039905990C990999C19AAF9AB09AE69B419B429CF4
+9CF69CF39EBC9F3B9F4A5104510050FB50F550F9510251085109510551DC0000
+BC
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+528752885289528D528A52F053B2562E563B56395632563F563456295653564E
+565756745636562F56305880589F589E58B3589C58AE58A958A6596D5B095AFB
+5B0B5AF55B0C5B085BEE5BEC5BE95BEB5C645C655D9D5D945E625E5F5E615EE2
+5EDA5EDF5EDD5EE35EE05F485F715FB75FB561766167616E615D615561820000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000617C6170616B617E61A7619061AB618E61AC619A61A4619461AE622E6469
+646F6479649E64B26488649064B064A56493649564A9649264AE64AD64AB649A
+64AC649964A264B365756577657866AE66AB66B466B16A236A1F69E86A016A1E
+6A1969FD6A216A136A0A69F36A026A0569ED6A116B506B4E6BA46BC56BC66F3F
+6F7C6F846F516F666F546F866F6D6F5B6F786F6E6F8E6F7A6F706F646F976F58
+6ED56F6F6F606F5F719F71AC71B171A87256729B734E73577469748B74830000
+BD
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+747E7480757F76207629761F7624762676217622769A76BA76E4778E7787778C
+7791778B78CB78C578BA78CA78BE78D578BC78D07A3F7A3C7A407A3D7A377A3B
+7AAF7AAE7BAD7BB17BC47BB47BC67BC77BC17BA07BCC7CCA7DE07DF47DEF7DFB
+7DD87DEC7DDD7DE87DE37DDA7DDE7DE97D9E7DD97DF27DF97F757F777FAF0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00007FE98026819B819C819D81A0819A81988517853D851A84EE852C852D8513
+851185238521851484EC852584FF850687828774877687608766877887688759
+8757874C8753885B885D89108907891289138915890A8ABC8AD28AC78AC48A95
+8ACB8AF88AB28AC98AC28ABF8AB08AD68ACD8AB68AB98ADB8C4C8C4E8C6C8CE0
+8CDE8CE68CE48CEC8CED8CE28CE38CDC8CEA8CE18D6D8D9F8DA38E2B8E108E1D
+8E228E0F8E298E1F8E218E1E8EBA8F1D8F1B8F1F8F298F268F2A8F1C8F1E0000
+BE
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+8F259069906E9068906D90779130912D9127913191879189918B918392C592BB
+92B792EA92AC92E492C192B392BC92D292C792F092B295AD95B1970497069707
+97099760978D978B978F9821982B981C98B3990A99139912991899DD99D099DF
+99DB99D199D599D299D99AB79AEE9AEF9B279B459B449B779B6F9D069D090000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00009D039EA99EBE9ECE58A89F5251125118511451105115518051AA51DD5291
+529352F35659566B5679566956645678566A566856655671566F566C56625676
+58C158BE58C758C5596E5B1D5B345B785BF05C0E5F4A61B2619161A9618A61CD
+61B661BE61CA61C8623064C564C164CB64BB64BC64DA64C464C764C264CD64BF
+64D264D464BE657466C666C966B966C466C766B86A3D6A386A3A6A596A6B6A58
+6A396A446A626A616A4B6A476A356A5F6A486B596B776C056FC26FB16FA10000
+BF
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+6FC36FA46FC16FA76FB36FC06FB96FB66FA66FA06FB471BE71C971D071D271C8
+71D571B971CE71D971DC71C371C47368749C74A37498749F749E74E2750C750D
+76347638763A76E776E577A0779E779F77A578E878DA78EC78E779A67A4D7A4E
+7A467A4C7A4B7ABA7BD97C117BC97BE47BDB7BE17BE97BE67CD57CD67E0A0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00007E117E087E1B7E237E1E7E1D7E097E107F797FB27FF07FF17FEE802881B3
+81A981A881FB820882588259854A855985488568856985438549856D856A855E
+8783879F879E87A2878D8861892A89328925892B892189AA89A68AE68AFA8AEB
+8AF18B008ADC8AE78AEE8AFE8B018B028AF78AED8AF38AF68AFC8C6B8C6D8C93
+8CF48E448E318E348E428E398E358F3B8F2F8F388F338FA88FA6907590749078
+9072907C907A913491929320933692F89333932F932292FC932B9304931A0000
+C0
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+9310932693219315932E931995BB96A796A896AA96D5970E97119716970D9713
+970F975B975C9766979898309838983B9837982D9839982499109928991E991B
+9921991A99ED99E299F19AB89ABC9AFB9AED9B289B919D159D239D269D289D12
+9D1B9ED89ED49F8D9F9C512A511F5121513252F5568E56805690568556870000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000568F58D558D358D158CE5B305B2A5B245B7A5C375C685DBC5DBA5DBD5DB8
+5E6B5F4C5FBD61C961C261C761E661CB6232623464CE64CA64D864E064F064E6
+64EC64F164E264ED6582658366D966D66A806A946A846AA26A9C6ADB6AA36A7E
+6A976A906AA06B5C6BAE6BDA6C086FD86FF16FDF6FE06FDB6FE46FEB6FEF6F80
+6FEC6FE16FE96FD56FEE6FF071E771DF71EE71E671E571ED71EC71F471E07235
+72467370737274A974B074A674A876467642764C76EA77B377AA77B077AC0000
+C1
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+77A777AD77EF78F778FA78F478EF790179A779AA7A577ABF7C077C0D7BFE7BF7
+7C0C7BE07CE07CDC7CDE7CE27CDF7CD97CDD7E2E7E3E7E467E377E327E437E2B
+7E3D7E317E457E417E347E397E487E357E3F7E2F7F447FF37FFC807180728070
+806F807381C681C381BA81C281C081BF81BD81C981BE81E88209827185AA0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00008584857E859C8591859485AF859B858785A8858A866787C087D187B387D2
+87C687AB87BB87BA87C887CB893B893689448938893D89AC8B0E8B178B198B1B
+8B0A8B208B1D8B048B108C418C3F8C738CFA8CFD8CFC8CF88CFB8DA88E498E4B
+8E488E4A8F448F3E8F428F458F3F907F907D9084908190829080913991A3919E
+919C934D938293289375934A9365934B9318937E936C935B9370935A935495CA
+95CB95CC95C895C696B196B896D6971C971E97A097D3984698B699359A010000
+C2
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+99FF9BAE9BAB9BAA9BAD9D3B9D3F9E8B9ECF9EDE9EDC9EDD9EDB9F3E9F4B53E2
+569556AE58D958D85B385F5D61E3623364F464F264FE650664FA64FB64F765B7
+66DC67266AB36AAC6AC36ABB6AB86AC26AAE6AAF6B5F6B786BAF7009700B6FFE
+70066FFA7011700F71FB71FC71FE71F87377737574A774BF7515765676580000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000765277BD77BF77BB77BC790E79AE7A617A627A607AC47AC57C2B7C277C2A
+7C1E7C237C217CE77E547E557E5E7E5A7E617E527E597F487FF97FFB80778076
+81CD81CF820A85CF85A985CD85D085C985B085BA85B985A687EF87EC87F287E0
+898689B289F48B288B398B2C8B2B8C508D058E598E638E668E648E5F8E558EC0
+8F498F4D90879083908891AB91AC91D09394938A939693A293B393AE93AC93B0
+9398939A939795D495D695D095D596E296DC96D996DB96DE972497A397A60000
+C3
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+97AD97F9984D984F984C984E985398BA993E993F993D992E99A59A0E9AC19B03
+9B069B4F9B4E9B4D9BCA9BC99BFD9BC89BC09D519D5D9D609EE09F159F2C5133
+56A558DE58DF58E25BF59F905EEC61F261F761F661F56500650F66E066DD6AE5
+6ADD6ADA6AD3701B701F7028701A701D701570187206720D725872A273780000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000737A74BD74CA74E375877586765F766177C7791979B17A6B7A697C3E7C3F
+7C387C3D7C377C407E6B7E6D7E797E697E6A7F857E737FB67FB97FB881D885E9
+85DD85EA85D585E485E585F787FB8805880D87F987FE8960895F8956895E8B41
+8B5C8B588B498B5A8B4E8B4F8B468B598D088D0A8E7C8E728E878E768E6C8E7A
+8E748F548F4E8FAD908A908B91B191AE93E193D193DF93C393C893DC93DD93D6
+93E293CD93D893E493D793E895DC96B496E3972A9727976197DC97FB985E0000
+C4
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+9858985B98BC994599499A169A199B0D9BE89BE79BD69BDB9D899D619D729D6A
+9D6C9E929E979E939EB452F856A856B756B656B456BC58E45B405B435B7D5BF6
+5DC961F861FA65186514651966E667276AEC703E703070327210737B74CF7662
+76657926792A792C792B7AC77AF67C4C7C437C4D7CEF7CF08FAE7E7D7E7C0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00007E827F4C800081DA826685FB85F9861185FA8606860B8607860A88148815
+896489BA89F88B708B6C8B668B6F8B5F8B6B8D0F8D0D8E898E818E858E8291B4
+91CB9418940393FD95E1973098C49952995199A89A2B9A309A379A359C139C0D
+9E799EB59EE89F2F9F5F9F639F615137513856C156C056C259145C6C5DCD61FC
+61FE651D651C659566E96AFB6B046AFA6BB2704C721B72A774D674D4766977D3
+7C507E8F7E8C7FBC8617862D861A882388228821881F896A896C89BD8B740000
+C5
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+8B778B7D8D138E8A8E8D8E8B8F5F8FAF91BA942E94339435943A94389432942B
+95E297389739973297FF9867986599579A459A439A409A3E9ACF9B549B519C2D
+9C259DAF9DB49DC29DB89E9D9EEF9F199F5C9F669F67513C513B56C856CA56C9
+5B7F5DD45DD25F4E61FF65246B0A6B6170517058738074E4758A766E766C0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000079B37C607C5F807E807D81DF8972896F89FC8B808D168D178E918E938F61
+9148944494519452973D973E97C397C1986B99559A559A4D9AD29B1A9C499C31
+9C3E9C3B9DD39DD79F349F6C9F6A9F9456CC5DD662006523652B652A66EC6B10
+74DA7ACA7C647C637C657E937E967E9481E28638863F88318B8A9090908F9463
+946094649768986F995C9A5A9A5B9A579AD39AD49AD19C549C579C569DE59E9F
+9EF456D158E9652C705E7671767277D77F507F888836883988628B938B920000
+C6
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+8B9682778D1B91C0946A97429748974497C698709A5F9B229B589C5F9DF99DFA
+9E7C9E7D9F079F779F725EF36B1670637C6C7C6E883B89C08EA191C194729470
+9871995E9AD69B239ECC706477DA8B9A947797C99A629A657E9C8B9C8EAA91C5
+947D947E947C9C779C789EF78C54947F9E1A72289A6A9B319E1B9E1E7C720000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000030FE309D309E3005304130423043304430453046304730483049304A304B
+304C304D304E304F3050305130523053305430553056305730583059305A305B
+305C305D305E305F3060306130623063306430653066306730683069306A306B
+306C306D306E306F3070307130723073307430753076307730783079307A307B
+307C307D307E307F3080308130823083308430853086308730883089308A308B
+308C308D308E308F309030913092309330A130A230A330A430A530A630A70000
+C7
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+30A830A930AA30AB30AC30AD30AE30AF30B030B130B230B330B430B530B630B7
+30B830B930BA30BB30BC30BD30BE30BF30C030C130C230C330C430C530C630C7
+30C830C930CA30CB30CC30CD30CE30CF30D030D130D230D330D430D530D630D7
+30D830D930DA30DB30DC30DD30DE30DF30E030E130E230E330E430E530E60000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000030E730E830E930EA30EB30EC30ED30EE30EF30F030F130F230F330F430F5
+30F60414041504010416041704180419041A041B041C04230424042504260427
+04280429042A042B042C042D042E042F04300431043204330434043504510436
+043704380439043A043B043C043D043E043F0440044104420443044404450446
+044704480449044A044B044C044D044E044F2460246124622463246424652466
+246724682469247424752476247724782479247A247B247C247D000000000000
+C9
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+4E424E5C51F5531A53824E074E0C4E474E8D56D7FA0C5C6E5F734E0F51874E0E
+4E2E4E934EC24EC94EC8519852FC536C53B957205903592C5C105DFF65E16BB3
+6BCC6C14723F4E314E3C4EE84EDC4EE94EE14EDD4EDA520C531C534C57225723
+5917592F5B815B845C125C3B5C745C735E045E805E825FC9620962506C150000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00006C366C436C3F6C3B72AE72B0738A79B8808A961E4F0E4F184F2C4EF54F14
+4EF14F004EF74F084F1D4F024F054F224F134F044EF44F1251B1521352095210
+52A65322531F534D538A540756E156DF572E572A5734593C5980597C5985597B
+597E5977597F5B565C155C255C7C5C7A5C7B5C7E5DDF5E755E845F025F1A5F74
+5FD55FD45FCF625C625E626462616266626262596260625A626565EF65EE673E
+67396738673B673A673F673C67336C186C466C526C5C6C4F6C4A6C546C4B0000
+CA
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+6C4C7071725E72B472B5738E752A767F7A757F518278827C8280827D827F864D
+897E909990979098909B909496229624962096234F564F3B4F624F494F534F64
+4F3E4F674F524F5F4F414F584F2D4F334F3F4F61518F51B9521C521E522152AD
+52AE530953635372538E538F54305437542A545454455419541C542554180000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000543D544F544154285424544756EE56E756E557415745574C5749574B5752
+5906594059A6599859A05997598E59A25990598F59A759A15B8E5B925C285C2A
+5C8D5C8F5C885C8B5C895C925C8A5C865C935C955DE05E0A5E0E5E8B5E895E8C
+5E885E8D5F055F1D5F785F765FD25FD15FD05FED5FE85FEE5FF35FE15FE45FE3
+5FFA5FEF5FF75FFB60005FF4623A6283628C628E628F629462876271627B627A
+6270628162886277627D62726274653765F065F465F365F265F5674567470000
+CB
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+67596755674C6748675D674D675A674B6BD06C196C1A6C786C676C6B6C846C8B
+6C8F6C716C6F6C696C9A6C6D6C876C956C9C6C666C736C656C7B6C8E7074707A
+726372BF72BD72C372C672C172BA72C573957397739373947392753A75397594
+75957681793D80348095809980908092809C8290828F8285828E829182930000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000828A828382848C788FC98FBF909F90A190A5909E90A790A096309628962F
+962D4E334F984F7C4F854F7D4F804F874F764F744F894F844F774F4C4F974F6A
+4F9A4F794F814F784F904F9C4F944F9E4F924F824F954F6B4F6E519E51BC51BE
+5235523252335246523152BC530A530B533C539253945487547F548154915482
+5488546B547A547E5465546C54745466548D546F546154605498546354675464
+56F756F9576F5772576D576B57715770577657805775577B5773577457620000
+CC
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+5768577D590C594559B559BA59CF59CE59B259CC59C159B659BC59C359D659B1
+59BD59C059C859B459C75B625B655B935B955C445C475CAE5CA45CA05CB55CAF
+5CA85CAC5C9F5CA35CAD5CA25CAA5CA75C9D5CA55CB65CB05CA65E175E145E19
+5F285F225F235F245F545F825F7E5F7D5FDE5FE5602D602660196032600B0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00006034600A60176033601A601E602C6022600D6010602E60136011600C6009
+601C6214623D62AD62B462D162BE62AA62B662CA62AE62B362AF62BB62A962B0
+62B8653D65A865BB660965FC66046612660865FB6603660B660D660565FD6611
+661066F6670A6785676C678E67926776677B6798678667846774678D678C677A
+679F679167996783677D67816778677967946B256B806B7E6BDE6C1D6C936CEC
+6CEB6CEE6CD96CB66CD46CAD6CE76CB76CD06CC26CBA6CC36CC66CED6CF20000
+CD
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+6CD26CDD6CB46C8A6C9D6C806CDE6CC06D306CCD6CC76CB06CF96CCF6CE96CD1
+709470987085709370867084709170967082709A7083726A72D672CB72D872C9
+72DC72D272D472DA72CC72D173A473A173AD73A673A273A073AC739D74DD74E8
+753F7540753E758C759876AF76F376F176F076F577F877FC77F977FB77FA0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000077F77942793F79C57A787A7B7AFB7C757CFD8035808F80AE80A380B880B5
+80AD822082A082C082AB829A8298829B82B582A782AE82BC829E82BA82B482A8
+82A182A982C282A482C382B682A28670866F866D866E8C568FD28FCB8FD38FCD
+8FD68FD58FD790B290B490AF90B390B09639963D963C963A96434FCD4FC54FD3
+4FB24FC94FCB4FC14FD44FDC4FD94FBB4FB34FDB4FC74FD64FBA4FC04FB94FEC
+5244524952C052C2533D537C539753965399539854BA54A154AD54A554CF0000
+CE
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+54C3830D54B754AE54D654B654C554C654A0547054BC54A254BE547254DE54B0
+57B5579E579F57A4578C5797579D579B57945798578F579957A5579A579558F4
+590D595359E159DE59EE5A0059F159DD59FA59FD59FC59F659E459F259F759DB
+59E959F359F559E059FE59F459ED5BA85C4C5CD05CD85CCC5CD75CCB5CDB0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00005CDE5CDA5CC95CC75CCA5CD65CD35CD45CCF5CC85CC65CCE5CDF5CF85DF9
+5E215E225E235E205E245EB05EA45EA25E9B5EA35EA55F075F2E5F565F866037
+603960546072605E6045605360476049605B604C60406042605F602460446058
+6066606E6242624362CF630D630B62F5630E630362EB62F9630F630C62F862F6
+63006313631462FA631562FB62F06541654365AA65BF6636662166326635661C
+662666226633662B663A661D66346639662E670F671067C167F267C867BA0000
+CF
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+67DC67BB67F867D867C067B767C567EB67E467DF67B567CD67B367F767F667EE
+67E367C267B967CE67E767F067B267FC67C667ED67CC67AE67E667DB67FA67C9
+67CA67C367EA67CB6B286B826B846BB66BD66BD86BE06C206C216D286D346D2D
+6D1F6D3C6D3F6D126D0A6CDA6D336D046D196D3A6D1A6D116D006D1D6D420000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00006D016D186D376D036D0F6D406D076D206D2C6D086D226D096D1070B7709F
+70BE70B170B070A170B470B570A972417249724A726C72707273726E72CA72E4
+72E872EB72DF72EA72E672E3738573CC73C273C873C573B973B673B573B473EB
+73BF73C773BE73C373C673B873CB74EC74EE752E7547754875A775AA767976C4
+7708770377047705770A76F776FB76FA77E777E878067811781278057810780F
+780E780978037813794A794C794B7945794479D579CD79CF79D679CE7A800000
+D0
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+7A7E7AD17B007B017C7A7C787C797C7F7C807C817D037D087D017F587F917F8D
+7FBE8007800E800F8014803780D880C780E080D180C880C280D080C580E380D9
+80DC80CA80D580C980CF80D780E680CD81FF8221829482D982FE82F9830782E8
+830082D5833A82EB82D682F482EC82E182F282F5830C82FB82F682F082EA0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000082E482E082FA82F382ED86778674867C86738841884E8867886A886989D3
+8A048A078D728FE38FE18FEE8FE090F190BD90BF90D590C590BE90C790CB90C8
+91D491D39654964F96519653964A964E501E50055007501350225030501B4FF5
+4FF450335037502C4FF64FF75017501C502050275035502F5031500E515A5194
+519351CA51C451C551C851CE5261525A5252525E525F5255526252CD530E539E
+552654E25517551254E754F354E4551A54FF5504550854EB5511550554F10000
+D1
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+550A54FB54F754F854E0550E5503550B5701570257CC583257D557D257BA57C6
+57BD57BC57B857B657BF57C757D057B957C1590E594A5A195A165A2D5A2E5A15
+5A0F5A175A0A5A1E5A335B6C5BA75BAD5BAC5C035C565C545CEC5CFF5CEE5CF1
+5CF75D005CF95E295E285EA85EAE5EAA5EAC5F335F305F67605D605A60670000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000604160A26088608060926081609D60836095609B60976087609C608E6219
+624662F263106356632C634463456336634363E46339634B634A633C63296341
+6334635863546359632D63476333635A63516338635763406348654A654665C6
+65C365C465C2664A665F6647665167126713681F681A684968326833683B684B
+684F68166831681C6835682B682D682F684E68446834681D6812681468266828
+682E684D683A682568206B2C6B2F6B2D6B316B346B6D80826B886BE66BE40000
+D2
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+6BE86BE36BE26BE76C256D7A6D636D646D766D0D6D616D926D586D626D6D6D6F
+6D916D8D6DEF6D7F6D866D5E6D676D606D976D706D7C6D5F6D826D986D2F6D68
+6D8B6D7E6D806D846D166D836D7B6D7D6D756D9070DC70D370D170DD70CB7F39
+70E270D770D270DE70E070D470CD70C570C670C770DA70CE70E1724272780000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000072777276730072FA72F472FE72F672F372FB730173D373D973E573D673BC
+73E773E373E973DC73D273DB73D473DD73DA73D773D873E874DE74DF74F474F5
+7521755B755F75B075C175BB75C475C075BF75B675BA768A76C9771D771B7710
+771377127723771177157719771A772277277823782C78227835782F7828782E
+782B782178297833782A78317954795B794F795C79537952795179EB79EC79E0
+79EE79ED79EA79DC79DE79DD7A867A897A857A8B7A8C7A8A7A877AD87B100000
+D3
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+7B047B137B057B0F7B087B0A7B0E7B097B127C847C917C8A7C8C7C887C8D7C85
+7D1E7D1D7D117D0E7D187D167D137D1F7D127D0F7D0C7F5C7F617F5E7F607F5D
+7F5B7F967F927FC37FC27FC08016803E803980FA80F280F980F5810180FB8100
+8201822F82258333832D83448319835183258356833F83418326831C83220000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00008342834E831B832A8308833C834D8316832483208337832F832983478345
+834C8353831E832C834B832783488653865286A286A88696868D8691869E8687
+86978686868B869A868586A5869986A186A786958698868E869D869086948843
+8844886D88758876887288808871887F886F8883887E8874887C8A128C478C57
+8C7B8CA48CA38D768D788DB58DB78DB68ED18ED38FFE8FF590028FFF8FFB9004
+8FFC8FF690D690E090D990DA90E390DF90E590D890DB90D790DC90E491500000
+D4
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+914E914F91D591E291DA965C965F96BC98E39ADF9B2F4E7F5070506A5061505E
+50605053504B505D50725048504D5041505B504A506250155045505F5069506B
+5063506450465040506E50735057505151D0526B526D526C526E52D652D3532D
+539C55755576553C554D55505534552A55515562553655355530555255450000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000550C55325565554E55395548552D553B5540554B570A570757FB581457E2
+57F657DC57F4580057ED57FD580857F8580B57F357CF580757EE57E357F257E5
+57EC57E1580E57FC581057E75801580C57F157E957F0580D5804595C5A605A58
+5A555A675A5E5A385A355A6D5A505A5F5A655A6C5A535A645A575A435A5D5A52
+5A445A5B5A485A8E5A3E5A4D5A395A4C5A705A695A475A515A565A425A5C5B72
+5B6E5BC15BC05C595D1E5D0B5D1D5D1A5D205D0C5D285D0D5D265D255D0F0000
+D5
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+5D305D125D235D1F5D2E5E3E5E345EB15EB45EB95EB25EB35F365F385F9B5F96
+5F9F608A6090608660BE60B060BA60D360D460CF60E460D960DD60C860B160DB
+60B760CA60BF60C360CD60C063326365638A6382637D63BD639E63AD639D6397
+63AB638E636F63876390636E63AF6375639C636D63AE637C63A4633B639F0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00006378638563816391638D6370655365CD66656661665B6659665C66626718
+687968876890689C686D686E68AE68AB6956686F68A368AC68A96875687468B2
+688F68776892687C686B687268AA68806871687E689B6896688B68A0688968A4
+6878687B6891688C688A687D6B366B336B376B386B916B8F6B8D6B8E6B8C6C2A
+6DC06DAB6DB46DB36E746DAC6DE96DE26DB76DF66DD46E006DC86DE06DDF6DD6
+6DBE6DE56DDC6DDD6DDB6DF46DCA6DBD6DED6DF06DBA6DD56DC26DCF6DC90000
+D6
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+6DD06DF26DD36DFD6DD76DCD6DE36DBB70FA710D70F7711770F4710C70F07104
+70F3711070FC70FF71067113710070F870F6710B7102710E727E727B727C727F
+731D7317730773117318730A730872FF730F731E738873F673F873F574047401
+73FD7407740073FA73FC73FF740C740B73F474087564756375CE75D275CF0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000075CB75CC75D175D0768F768976D37739772F772D7731773277347733773D
+7725773B7735784878527849784D784A784C782678457850796479677969796A
+7963796B796179BB79FA79F879F679F77A8F7A947A907B357B477B347B257B30
+7B227B247B337B187B2A7B1D7B317B2B7B2D7B2F7B327B387B1A7B237C947C98
+7C967CA37D357D3D7D387D367D3A7D457D2C7D297D417D477D3E7D3F7D4A7D3B
+7D287F637F957F9C7F9D7F9B7FCA7FCB7FCD7FD07FD17FC77FCF7FC9801F0000
+D7
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+801E801B804780438048811881258119811B812D811F812C811E812181158127
+811D8122821182388233823A823482328274839083A383A8838D837A837383A4
+8374838F8381839583998375839483A9837D8383838C839D839B83AA838B837E
+83A583AF8388839783B0837F83A6838783AE8376839A8659865686BF86B70000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000086C286C186C586BA86B086C886B986B386B886CC86B486BB86BC86C386BD
+86BE88528889889588A888A288AA889A889188A1889F889888A78899889B8897
+88A488AC888C8893888E898289D689D989D58A308A278A2C8A1E8C398C3B8C5C
+8C5D8C7D8CA58D7D8D7B8D798DBC8DC28DB98DBF8DC18ED88EDE8EDD8EDC8ED7
+8EE08EE19024900B9011901C900C902190EF90EA90F090F490F290F390D490EB
+90EC90E991569158915A9153915591EC91F491F191F391F891E491F991EA0000
+D8
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+91EB91F791E891EE957A95869588967C966D966B9671966F96BF976A980498E5
+9997509B50955094509E508B50A35083508C508E509D5068509C509250825087
+515F51D45312531153A453A7559155A855A555AD5577564555A255935588558F
+55B5558155A3559255A4557D558C55A6557F559555A1558E570C582958370000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00005819581E58275823582857F558485825581C581B5833583F5836582E5839
+5838582D582C583B59615AAF5A945A9F5A7A5AA25A9E5A785AA65A7C5AA55AAC
+5A955AAE5A375A845A8A5A975A835A8B5AA95A7B5A7D5A8C5A9C5A8F5A935A9D
+5BEA5BCD5BCB5BD45BD15BCA5BCE5C0C5C305D375D435D6B5D415D4B5D3F5D35
+5D515D4E5D555D335D3A5D525D3D5D315D595D425D395D495D385D3C5D325D36
+5D405D455E445E415F585FA65FA55FAB60C960B960CC60E260CE60C461140000
+D9
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+60F2610A6116610560F5611360F860FC60FE60C161036118611D611060FF6104
+610B624A639463B163B063CE63E563E863EF63C3649D63F363CA63E063F663D5
+63F263F5646163DF63BE63DD63DC63C463D863D363C263C763CC63CB63C863F0
+63D763D965326567656A6564655C65686565658C659D659E65AE65D065D20000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000667C666C667B668066716679666A66726701690C68D3690468DC692A68EC
+68EA68F1690F68D668F768EB68E468F66913691068F368E1690768CC69086970
+68B4691168EF68C6691468F868D068FD68FC68E8690B690A691768CE68C868DD
+68DE68E668F468D1690668D468E96915692568C76B396B3B6B3F6B3C6B946B97
+6B996B956BBD6BF06BF26BF36C306DFC6E466E476E1F6E496E886E3C6E3D6E45
+6E626E2B6E3F6E416E5D6E736E1C6E336E4B6E406E516E3B6E036E2E6E5E0000
+DA
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+6E686E5C6E616E316E286E606E716E6B6E396E226E306E536E656E276E786E64
+6E776E556E796E526E666E356E366E5A7120711E712F70FB712E713171237125
+71227132711F7128713A711B724B725A7288728972867285728B7312730B7330
+73227331733373277332732D732673237335730C742E742C7430742B74160000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000741A7421742D743174247423741D74297420743274FB752F756F756C75E7
+75DA75E175E675DD75DF75E475D77695769276DA774677477744774D7745774A
+774E774B774C77DE77EC786078647865785C786D7871786A786E787078697868
+785E786279747973797279707A027A0A7A037A0C7A047A997AE67AE47B4A7B3B
+7B447B487B4C7B4E7B407B587B457CA27C9E7CA87CA17D587D6F7D637D537D56
+7D677D6A7D4F7D6D7D5C7D6B7D527D547D697D517D5F7D4E7F3E7F3F7F650000
+DB
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+7F667FA27FA07FA17FD78051804F805080FE80D48143814A8152814F8147813D
+814D813A81E681EE81F781F881F98204823C823D823F8275833B83CF83F98423
+83C083E8841283E783E483FC83F6841083C683C883EB83E383BF840183DD83E5
+83D883FF83E183CB83CE83D683F583C98409840F83DE8411840683C283F30000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000083D583FA83C783D183EA841383C383EC83EE83C483FB83D783E2841B83DB
+83FE86D886E286E686D386E386DA86EA86DD86EB86DC86EC86E986D786E886D1
+88488856885588BA88D788B988B888C088BE88B688BC88B788BD88B2890188C9
+89958998899789DD89DA89DB8A4E8A4D8A398A598A408A578A588A448A458A52
+8A488A518A4A8A4C8A4F8C5F8C818C808CBA8CBE8CB08CB98CB58D848D808D89
+8DD88DD38DCD8DC78DD68DDC8DCF8DD58DD98DC88DD78DC58EEF8EF78EFA0000
+DC
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+8EF98EE68EEE8EE58EF58EE78EE88EF68EEB8EF18EEC8EF48EE9902D9034902F
+9106912C910490FF90FC910890F990FB9101910091079105910391619164915F
+916291609201920A92259203921A9226920F920C9200921291FF91FD92069204
+92279202921C92249219921792059216957B958D958C95909687967E96880000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000096899683968096C296C896C396F196F0976C9770976E980798A998EB9CE6
+9EF94E834E844EB650BD50BF50C650AE50C450CA50B450C850C250B050C150BA
+50B150CB50C950B650B851D7527A5278527B527C55C355DB55CC55D055CB55CA
+55DD55C055D455C455E955BF55D2558D55CF55D555E255D655C855F255CD55D9
+55C25714585358685864584F584D5849586F5855584E585D58595865585B583D
+5863587158FC5AC75AC45ACB5ABA5AB85AB15AB55AB05ABF5AC85ABB5AC60000
+DD
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+5AB75AC05ACA5AB45AB65ACD5AB95A905BD65BD85BD95C1F5C335D715D635D4A
+5D655D725D6C5D5E5D685D675D625DF05E4F5E4E5E4A5E4D5E4B5EC55ECC5EC6
+5ECB5EC75F405FAF5FAD60F76149614A612B614561366132612E6146612F614F
+612961406220916862236225622463C563F163EB641064126409642064240000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000064336443641F641564186439643764226423640C64266430642864416435
+642F640A641A644064256427640B63E7641B642E6421640E656F659265D36686
+668C66956690668B668A66996694667867206966695F6938694E69626971693F
+6945696A6939694269576959697A694869496935696C6933693D696568F06978
+693469696940696F69446976695869416974694C693B694B6937695C694F6951
+69326952692F697B693C6B466B456B436B426B486B416B9BFA0D6BFB6BFC0000
+DE
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+6BF96BF76BF86E9B6ED66EC86E8F6EC06E9F6E936E946EA06EB16EB96EC66ED2
+6EBD6EC16E9E6EC96EB76EB06ECD6EA66ECF6EB26EBE6EC36EDC6ED86E996E92
+6E8E6E8D6EA46EA16EBF6EB36ED06ECA6E976EAE6EA371477154715271637160
+7141715D716271727178716A7161714271587143714B7170715F715071530000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00007144714D715A724F728D728C72917290728E733C7342733B733A7340734A
+73497444744A744B7452745174577440744F7450744E74427446744D745474E1
+74FF74FE74FD751D75797577698375EF760F760375F775FE75FC75F975F87610
+75FB75F675ED75F575FD769976B576DD7755775F776077527756775A77697767
+77547759776D77E07887789A7894788F788478957885788678A1788378797899
+78807896787B797C7982797D79797A117A187A197A127A177A157A227A130000
+DF
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+7A1B7A107AA37AA27A9E7AEB7B667B647B6D7B747B697B727B657B737B717B70
+7B617B787B767B637CB27CB47CAF7D887D867D807D8D7D7F7D857D7A7D8E7D7B
+7D837D7C7D8C7D947D847D7D7D927F6D7F6B7F677F687F6C7FA67FA57FA77FDB
+7FDC8021816481608177815C8169815B816281726721815E81768167816F0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000081448161821D8249824482408242824584F1843F845684768479848F848D
+846584518440848684678430844D847D845A845984748473845D8507845E8437
+843A8434847A8443847884328445842983D9844B842F8442842D845F84708439
+844E844C8452846F84C5848E843B8447843684338468847E8444842B84608454
+846E8450870B870486F7870C86FA86D686F5874D86F8870E8709870186F6870D
+870588D688CB88CD88CE88DE88DB88DA88CC88D08985899B89DF89E589E40000
+E0
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+89E189E089E289DC89E68A768A868A7F8A618A3F8A778A828A848A758A838A81
+8A748A7A8C3C8C4B8C4A8C658C648C668C868C848C858CCC8D688D698D918D8C
+8D8E8D8F8D8D8D938D948D908D928DF08DE08DEC8DF18DEE8DD08DE98DE38DE2
+8DE78DF28DEB8DF48F068EFF8F018F008F058F078F088F028F0B9052903F0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000090449049903D9110910D910F911191169114910B910E916E916F92489252
+9230923A926692339265925E9283922E924A9246926D926C924F92609267926F
+92369261927092319254926392509272924E9253924C92569232959F959C959E
+959B969296939691969796CE96FA96FD96F896F59773977797789772980F980D
+980E98AC98F698F999AF99B299B099B59AAD9AAB9B5B9CEA9CED9CE79E809EFD
+50E650D450D750E850F350DB50EA50DD50E450D350EC50F050EF50E350E00000
+E1
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+51D85280528152E952EB533053AC56275615560C561255FC560F561C56015613
+560255FA561D560455FF55F95889587C5890589858865881587F5874588B587A
+58875891588E587658825888587B5894588F58FE596B5ADC5AEE5AE55AD55AEA
+5ADA5AED5AEB5AF35AE25AE05ADB5AEC5ADE5ADD5AD95AE85ADF5B775BE00000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00005BE35C635D825D805D7D5D865D7A5D815D775D8A5D895D885D7E5D7C5D8D
+5D795D7F5E585E595E535ED85ED15ED75ECE5EDC5ED55ED95ED25ED45F445F43
+5F6F5FB6612C61286141615E61716173615261536172616C618061746154617A
+615B6165613B616A6161615662296227622B642B644D645B645D647464766472
+6473647D6475646664A6644E6482645E645C644B645364606450647F643F646C
+646B645964656477657365A066A166A0669F67056704672269B169B669C90000
+E2
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+69A069CE699669B069AC69BC69916999698E69A7698D69A969BE69AF69BF69C4
+69BD69A469D469B969CA699A69CF69B3699369AA69A1699E69D96997699069C2
+69B569A569C66B4A6B4D6B4B6B9E6B9F6BA06BC36BC46BFE6ECE6EF56EF16F03
+6F256EF86F376EFB6F2E6F096F4E6F196F1A6F276F186F3B6F126EED6F0A0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00006F366F736EF96EEE6F2D6F406F306F3C6F356EEB6F076F0E6F436F056EFD
+6EF66F396F1C6EFC6F3A6F1F6F0D6F1E6F086F21718771907189718071857182
+718F717B718671817197724472537297729572937343734D7351734C74627473
+7471747574727467746E750075027503757D759076167608760C76157611760A
+761476B87781777C77857782776E7780776F777E778378B278AA78B478AD78A8
+787E78AB789E78A578A078AC78A278A47998798A798B79967995799479930000
+E3
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+79977988799279907A2B7A4A7A307A2F7A287A267AA87AAB7AAC7AEE7B887B9C
+7B8A7B917B907B967B8D7B8C7B9B7B8E7B857B9852847B997BA47B827CBB7CBF
+7CBC7CBA7DA77DB77DC27DA37DAA7DC17DC07DC57D9D7DCE7DC47DC67DCB7DCC
+7DAF7DB97D967DBC7D9F7DA67DAE7DA97DA17DC97F737FE27FE37FE57FDE0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00008024805D805C8189818681838187818D818C818B8215849784A484A1849F
+84BA84CE84C284AC84AE84AB84B984B484C184CD84AA849A84B184D0849D84A7
+84BB84A2849484C784CC849B84A984AF84A884D6849884B684CF84A084D784D4
+84D284DB84B084918661873387238728876B8740872E871E87218719871B8743
+872C8741873E874687208732872A872D873C8712873A87318735874287268727
+87388724871A8730871188F788E788F188F288FA88FE88EE88FC88F688FB0000
+E4
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+88F088EC88EB899D89A1899F899E89E989EB89E88AAB8A998A8B8A928A8F8A96
+8C3D8C688C698CD58CCF8CD78D968E098E028DFF8E0D8DFD8E0A8E038E078E06
+8E058DFE8E008E048F108F118F0E8F0D9123911C91209122911F911D911A9124
+9121911B917A91729179917392A592A49276929B927A92A0929492AA928D0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000092A6929A92AB92799297927F92A392EE928E9282929592A2927D928892A1
+928A9286928C929992A7927E928792A9929D928B922D969E96A196FF9758977D
+977A977E978397809782977B97849781977F97CE97CD981698AD98AE99029900
+9907999D999C99C399B999BB99BA99C299BD99C79AB19AE39AE79B3E9B3F9B60
+9B619B5F9CF19CF29CF59EA750FF5103513050F85106510750F650FE510B510C
+50FD510A528B528C52F152EF56485642564C56355641564A5649564656580000
+E5
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+565A56405633563D562C563E5638562A563A571A58AB589D58B158A058A358AF
+58AC58A558A158FF5AFF5AF45AFD5AF75AF65B035AF85B025AF95B015B075B05
+5B0F5C675D995D975D9F5D925DA25D935D955DA05D9C5DA15D9A5D9E5E695E5D
+5E605E5C7DF35EDB5EDE5EE15F495FB2618B6183617961B161B061A261890000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000619B619361AF61AD619F619261AA61A1618D616661B3622D646E64706496
+64A064856497649C648F648B648A648C64A3649F646864B164986576657A6579
+657B65B265B366B566B066A966B266B766AA66AF6A006A066A1769E569F86A15
+69F169E46A2069FF69EC69E26A1B6A1D69FE6A2769F269EE6A1469F769E76A40
+6A0869E669FB6A0D69FC69EB6A096A046A186A256A0F69F66A266A0769F46A16
+6B516BA56BA36BA26BA66C016C006BFF6C026F416F266F7E6F876FC66F920000
+E6
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+6F8D6F896F8C6F626F4F6F856F5A6F966F766F6C6F826F556F726F526F506F57
+6F946F936F5D6F006F616F6B6F7D6F676F906F536F8B6F696F7F6F956F636F77
+6F6A6F7B71B271AF719B71B071A0719A71A971B5719D71A5719E71A471A171AA
+719C71A771B37298729A73587352735E735F7360735D735B7361735A73590000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000736274877489748A74867481747D74857488747C747975087507757E7625
+761E7619761D761C7623761A7628761B769C769D769E769B778D778F77897788
+78CD78BB78CF78CC78D178CE78D478C878C378C478C9799A79A179A0799C79A2
+799B6B767A397AB27AB47AB37BB77BCB7BBE7BAC7BCE7BAF7BB97BCA7BB57CC5
+7CC87CCC7CCB7DF77DDB7DEA7DE77DD77DE17E037DFA7DE67DF67DF17DF07DEE
+7DDF7F767FAC7FB07FAD7FED7FEB7FEA7FEC7FE67FE88064806781A3819F0000
+E7
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+819E819581A2819981978216824F825382528250824E82518524853B850F8500
+8529850E8509850D851F850A8527851C84FB852B84FA8508850C84F4852A84F2
+851584F784EB84F384FC851284EA84E9851684FE8528851D852E850284FD851E
+84F68531852684E784E884F084EF84F9851885208530850B8519852F86620000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000875687638764877787E1877387588754875B87528761875A8751875E876D
+876A8750874E875F875D876F876C877A876E875C8765874F877B877587628767
+8769885A8905890C8914890B891789188919890689168911890E890989A289A4
+89A389ED89F089EC8ACF8AC68AB88AD38AD18AD48AD58ABB8AD78ABE8AC08AC5
+8AD88AC38ABA8ABD8AD98C3E8C4D8C8F8CE58CDF8CD98CE88CDA8CDD8CE78DA0
+8D9C8DA18D9B8E208E238E258E248E2E8E158E1B8E168E118E198E268E270000
+E8
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+8E148E128E188E138E1C8E178E1A8F2C8F248F188F1A8F208F238F168F179073
+9070906F9067906B912F912B9129912A91329126912E91859186918A91819182
+9184918092D092C392C492C092D992B692CF92F192DF92D892E992D792DD92CC
+92EF92C292E892CA92C892CE92E692CD92D592C992E092DE92E792D192D30000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000092B592E192C692B4957C95AC95AB95AE95B096A496A296D3970597089702
+975A978A978E978897D097CF981E981D9826982998289820981B982798B29908
+98FA9911991499169917991599DC99CD99CF99D399D499CE99C999D699D899CB
+99D799CC9AB39AEC9AEB9AF39AF29AF19B469B439B679B749B719B669B769B75
+9B709B689B649B6C9CFC9CFA9CFD9CFF9CF79D079D009CF99CFB9D089D059D04
+9E839ED39F0F9F10511C51135117511A511151DE533453E156705660566E0000
+E9
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+567356665663566D5672565E5677571C571B58C858BD58C958BF58BA58C258BC
+58C65B175B195B1B5B215B145B135B105B165B285B1A5B205B1E5BEF5DAC5DB1
+5DA95DA75DB55DB05DAE5DAA5DA85DB25DAD5DAF5DB45E675E685E665E6F5EE9
+5EE75EE65EE85EE55F4B5FBC619D61A8619661C561B461C661C161CC61BA0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000061BF61B8618C64D764D664D064CF64C964BD648964C364DB64F364D96533
+657F657C65A266C866BE66C066CA66CB66CF66BD66BB66BA66CC67236A346A66
+6A496A676A326A686A3E6A5D6A6D6A766A5B6A516A286A5A6A3B6A3F6A416A6A
+6A646A506A4F6A546A6F6A696A606A3C6A5E6A566A556A4D6A4E6A466B556B54
+6B566BA76BAA6BAB6BC86BC76C046C036C066FAD6FCB6FA36FC76FBC6FCE6FC8
+6F5E6FC46FBD6F9E6FCA6FA870046FA56FAE6FBA6FAC6FAA6FCF6FBF6FB80000
+EA
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+6FA26FC96FAB6FCD6FAF6FB26FB071C571C271BF71B871D671C071C171CB71D4
+71CA71C771CF71BD71D871BC71C671DA71DB729D729E736973667367736C7365
+736B736A747F749A74A074947492749574A1750B7580762F762D7631763D7633
+763C76357632763076BB76E6779A779D77A1779C779B77A277A3779577990000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000779778DD78E978E578EA78DE78E378DB78E178E278ED78DF78E079A47A44
+7A487A477AB67AB87AB57AB17AB77BDE7BE37BE77BDD7BD57BE57BDA7BE87BF9
+7BD47BEA7BE27BDC7BEB7BD87BDF7CD27CD47CD77CD07CD17E127E217E177E0C
+7E1F7E207E137E0E7E1C7E157E1A7E227E0B7E0F7E167E0D7E147E257E247F43
+7F7B7F7C7F7A7FB17FEF802A8029806C81B181A681AE81B981B581AB81B081AC
+81B481B281B781A781F282558256825785568545856B854D8553856185580000
+EB
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+854085468564854185628544855185478563853E855B8571854E856E85758555
+85678560858C8566855D85548565856C866386658664879B878F879787938792
+87888781879687988779878787A3878587908791879D87848794879C879A8789
+891E89268930892D892E89278931892289298923892F892C891F89F18AE00000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00008AE28AF28AF48AF58ADD8B148AE48ADF8AF08AC88ADE8AE18AE88AFF8AEF
+8AFB8C918C928C908CF58CEE8CF18CF08CF38D6C8D6E8DA58DA78E338E3E8E38
+8E408E458E368E3C8E3D8E418E308E3F8EBD8F368F2E8F358F328F398F378F34
+90769079907B908690FA913391359136919391909191918D918F9327931E9308
+931F9306930F937A9338933C931B9323931293019346932D930E930D92CB931D
+92FA9325931392F992F793349302932492FF932993399335932A9314930C0000
+EC
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+930B92FE9309930092FB931695BC95CD95BE95B995BA95B695BF95B595BD96A9
+96D4970B9712971097999797979497F097F89835982F98329924991F99279929
+999E99EE99EC99E599E499F099E399EA99E999E79AB99ABF9AB49ABB9AF69AFA
+9AF99AF79B339B809B859B879B7C9B7E9B7B9B829B939B929B909B7A9B950000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00009B7D9B889D259D179D209D1E9D149D299D1D9D189D229D109D199D1F9E88
+9E869E879EAE9EAD9ED59ED69EFA9F129F3D51265125512251245120512952F4
+5693568C568D568656845683567E5682567F568158D658D458CF58D25B2D5B25
+5B325B235B2C5B275B265B2F5B2E5B7B5BF15BF25DB75E6C5E6A5FBE5FBB61C3
+61B561BC61E761E061E561E461E861DE64EF64E964E364EB64E464E865816580
+65B665DA66D26A8D6A966A816AA56A896A9F6A9B6AA16A9E6A876A936A8E0000
+ED
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+6A956A836AA86AA46A916A7F6AA66A9A6A856A8C6A926B5B6BAD6C096FCC6FA9
+6FF46FD46FE36FDC6FED6FE76FE66FDE6FF26FDD6FE26FE871E171F171E871F2
+71E471F071E27373736E736F749774B274AB749074AA74AD74B174A574AF7510
+75117512750F7584764376487649764776A476E977B577AB77B277B777B60000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000077B477B177A877F078F378FD790278FB78FC78F2790578F978FE790479AB
+79A87A5C7A5B7A567A587A547A5A7ABE7AC07AC17C057C0F7BF27C007BFF7BFB
+7C0E7BF47C0B7BF37C027C097C037C017BF87BFD7C067BF07BF17C107C0A7CE8
+7E2D7E3C7E427E3398487E387E2A7E497E407E477E297E4C7E307E3B7E367E44
+7E3A7F457F7F7F7E7F7D7FF47FF2802C81BB81C481CC81CA81C581C781BC81E9
+825B825A825C85838580858F85A7859585A0858B85A3857B85A4859A859E0000
+EE
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+8577857C858985A1857A85788557858E85968586858D8599859D858185A28582
+858885858579857685988590859F866887BE87AA87AD87C587B087AC87B987B5
+87BC87AE87C987C387C287CC87B787AF87C487CA87B487B687BF87B887BD87DE
+87B289358933893C893E894189528937894289AD89AF89AE89F289F38B1E0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00008B188B168B118B058B0B8B228B0F8B128B158B078B0D8B088B068B1C8B13
+8B1A8C4F8C708C728C718C6F8C958C948CF98D6F8E4E8E4D8E538E508E4C8E47
+8F438F409085907E9138919A91A2919B9199919F91A1919D91A093A1938393AF
+936493569347937C9358935C93769349935093519360936D938F934C936A9379
+935793559352934F93719377937B9361935E936393679380934E935995C795C0
+95C995C395C595B796AE96B096AC9720971F9718971D9719979A97A1979C0000
+EF
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+979E979D97D597D497F198419844984A9849984598439925992B992C992A9933
+9932992F992D99319930999899A399A19A0299FA99F499F799F999F899F699FB
+99FD99FE99FC9A039ABE9AFE9AFD9B019AFC9B489B9A9BA89B9E9B9B9BA69BA1
+9BA59BA49B869BA29BA09BAF9D339D419D679D369D2E9D2F9D319D389D300000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00009D459D429D439D3E9D379D409D3D7FF59D2D9E8A9E899E8D9EB09EC89EDA
+9EFB9EFF9F249F239F229F549FA05131512D512E5698569C5697569A569D5699
+59705B3C5C695C6A5DC05E6D5E6E61D861DF61ED61EE61F161EA61F061EB61D6
+61E964FF650464FD64F86501650364FC659465DB66DA66DB66D86AC56AB96ABD
+6AE16AC66ABA6AB66AB76AC76AB46AAD6B5E6BC96C0B7007700C700D70017005
+7014700E6FFF70006FFB70266FFC6FF7700A720171FF71F9720371FD73760000
+F0
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+74B874C074B574C174BE74B674BB74C275147513765C76647659765076537657
+765A76A676BD76EC77C277BA78FF790C79137914790979107912791179AD79AC
+7A5F7C1C7C297C197C207C1F7C2D7C1D7C267C287C227C257C307E5C7E507E56
+7E637E587E627E5F7E517E607E577E537FB57FB37FF77FF8807581D181D20000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000081D0825F825E85B485C685C085C385C285B385B585BD85C785C485BF85CB
+85CE85C885C585B185B685D2862485B885B785BE866987E787E687E287DB87EB
+87EA87E587DF87F387E487D487DC87D387ED87D887E387A487D787D9880187F4
+87E887DD8953894B894F894C89468950895189498B2A8B278B238B338B308B35
+8B478B2F8B3C8B3E8B318B258B378B268B368B2E8B248B3B8B3D8B3A8C428C75
+8C998C988C978CFE8D048D028D008E5C8E628E608E578E568E5E8E658E670000
+F1
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+8E5B8E5A8E618E5D8E698E548F468F478F488F4B9128913A913B913E91A891A5
+91A791AF91AA93B5938C939293B7939B939D938993A7938E93AA939E93A69395
+93889399939F938D93B1939193B293A493A893B493A393A595D295D395D196B3
+96D796DA5DC296DF96D896DD97239722972597AC97AE97A897AB97A497AA0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000097A297A597D797D997D697D897FA98509851985298B89941993C993A9A0F
+9A0B9A099A0D9A049A119A0A9A059A079A069AC09ADC9B089B049B059B299B35
+9B4A9B4C9B4B9BC79BC69BC39BBF9BC19BB59BB89BD39BB69BC49BB99BBD9D5C
+9D539D4F9D4A9D5B9D4B9D599D569D4C9D579D529D549D5F9D589D5A9E8E9E8C
+9EDF9F019F009F169F259F2B9F2A9F299F289F4C9F5551345135529652F753B4
+56AB56AD56A656A756AA56AC58DA58DD58DB59125B3D5B3E5B3F5DC35E700000
+F2
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+5FBF61FB65076510650D6509650C650E658465DE65DD66DE6AE76AE06ACC6AD1
+6AD96ACB6ADF6ADC6AD06AEB6ACF6ACD6ADE6B606BB06C0C7019702770207016
+702B702170227023702970177024701C702A720C720A72077202720572A572A6
+72A472A372A174CB74C574B774C37516766077C977CA77C477F1791D791B0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00007921791C7917791E79B07A677A687C337C3C7C397C2C7C3B7CEC7CEA7E76
+7E757E787E707E777E6F7E7A7E727E747E687F4B7F4A7F837F867FB77FFD7FFE
+807881D781D582648261826385EB85F185ED85D985E185E885DA85D785EC85F2
+85F885D885DF85E385DC85D185F085E685EF85DE85E2880087FA880387F687F7
+8809880C880B880687FC880887FF880A88028962895A895B89578961895C8958
+895D8959898889B789B689F68B508B488B4A8B408B538B568B548B4B8B550000
+F3
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+8B518B428B528B578C438C778C768C9A8D068D078D098DAC8DAA8DAD8DAB8E6D
+8E788E738E6A8E6F8E7B8EC28F528F518F4F8F508F538FB49140913F91B091AD
+93DE93C793CF93C293DA93D093F993EC93CC93D993A993E693CA93D493EE93E3
+93D593C493CE93C093D293E7957D95DA95DB96E19729972B972C972897260000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000097B397B797B697DD97DE97DF985C9859985D985798BF98BD98BB98BE9948
+9947994399A699A79A1A9A159A259A1D9A249A1B9A229A209A279A239A1E9A1C
+9A149AC29B0B9B0A9B0E9B0C9B379BEA9BEB9BE09BDE9BE49BE69BE29BF09BD4
+9BD79BEC9BDC9BD99BE59BD59BE19BDA9D779D819D8A9D849D889D719D809D78
+9D869D8B9D8C9D7D9D6B9D749D759D709D699D859D739D7B9D829D6F9D799D7F
+9D879D689E949E919EC09EFC9F2D9F409F419F4D9F569F579F58533756B20000
+F4
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+56B556B358E35B455DC65DC75EEE5EEF5FC05FC161F9651765166515651365DF
+66E866E366E46AF36AF06AEA6AE86AF96AF16AEE6AEF703C7035702F70377034
+703170427038703F703A70397040703B703370417213721472A8737D737C74BA
+76AB76AA76BE76ED77CC77CE77CF77CD77F27925792379277928792479290000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000079B27A6E7A6C7A6D7AF77C497C487C4A7C477C457CEE7E7B7E7E7E817E80
+7FBA7FFF807981DB81D9820B82688269862285FF860185FE861B860085F68604
+86098605860C85FD8819881088118817881388168963896689B989F78B608B6A
+8B5D8B688B638B658B678B6D8DAE8E868E888E848F598F568F578F558F588F5A
+908D9143914191B791B591B291B3940B941393FB9420940F941493FE94159410
+94289419940D93F5940093F79407940E9416941293FA940993F8940A93FF0000
+F5
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+93FC940C93F69411940695DE95E095DF972E972F97B997BB97FD97FE98609862
+9863985F98C198C29950994E9959994C994B99539A329A349A319A2C9A2A9A36
+9A299A2E9A389A2D9AC79ACA9AC69B109B129B119C0B9C089BF79C059C129BF8
+9C409C079C0E9C069C179C149C099D9F9D999DA49D9D9D929D989D909D9B0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00009DA09D949D9C9DAA9D979DA19D9A9DA29DA89D9E9DA39DBF9DA99D969DA6
+9DA79E999E9B9E9A9EE59EE49EE79EE69F309F2E9F5B9F609F5E9F5D9F599F91
+513A51395298529756C356BD56BE5B485B475DCB5DCF5EF161FD651B6B026AFC
+6B036AF86B0070437044704A7048704970457046721D721A7219737E7517766A
+77D0792D7931792F7C547C537CF27E8A7E877E887E8B7E867E8D7F4D7FBB8030
+81DD8618862A8626861F8623861C86198627862E862186208629861E86250000
+F6
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+8829881D881B88208824881C882B884A896D8969896E896B89FA8B798B788B45
+8B7A8B7B8D108D148DAF8E8E8E8C8F5E8F5B8F5D91469144914591B9943F943B
+94369429943D943C94309439942A9437942C9440943195E595E495E39735973A
+97BF97E1986498C998C698C0995899569A399A3D9A469A449A429A419A3A0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00009A3F9ACD9B159B179B189B169B3A9B529C2B9C1D9C1C9C2C9C239C289C29
+9C249C219DB79DB69DBC9DC19DC79DCA9DCF9DBE9DC59DC39DBB9DB59DCE9DB9
+9DBA9DAC9DC89DB19DAD9DCC9DB39DCD9DB29E7A9E9C9EEB9EEE9EED9F1B9F18
+9F1A9F319F4E9F659F649F924EB956C656C556CB59715B4B5B4C5DD55DD15EF2
+65216520652665226B0B6B086B096C0D7055705670577052721E721F72A9737F
+74D874D574D974D7766D76AD793579B47A707A717C577C5C7C597C5B7C5A0000
+F7
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+7CF47CF17E917F4F7F8781DE826B863486358633862C86328636882C88288826
+882A8825897189BF89BE89FB8B7E8B848B828B868B858B7F8D158E958E948E9A
+8E928E908E968E978F608F629147944C9450944A944B944F9447944594489449
+9446973F97E3986A986998CB9954995B9A4E9A539A549A4C9A4F9A489A4A0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00009A499A529A509AD09B199B2B9B3B9B569B559C469C489C3F9C449C399C33
+9C419C3C9C379C349C329C3D9C369DDB9DD29DDE9DDA9DCB9DD09DDC9DD19DDF
+9DE99DD99DD89DD69DF59DD59DDD9EB69EF09F359F339F329F429F6B9F959FA2
+513D529958E858E759725B4D5DD8882F5F4F62016203620465296525659666EB
+6B116B126B0F6BCA705B705A7222738273817383767077D47C677C667E95826C
+863A86408639863C8631863B863E88308832882E883389768974897389FE0000
+F8
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+8B8C8B8E8B8B8B888C458D198E988F648F6391BC94629455945D9457945E97C4
+97C598009A569A599B1E9B1F9B209C529C589C509C4A9C4D9C4B9C559C599C4C
+9C4E9DFB9DF79DEF9DE39DEB9DF89DE49DF69DE19DEE9DE69DF29DF09DE29DEC
+9DF49DF39DE89DED9EC29ED09EF29EF39F069F1C9F389F379F369F439F4F0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00009F719F709F6E9F6F56D356CD5B4E5C6D652D66ED66EE6B13705F7061705D
+7060722374DB74E577D5793879B779B67C6A7E977F89826D8643883888378835
+884B8B948B958E9E8E9F8EA08E9D91BE91BD91C2946B9468946996E597469743
+974797C797E59A5E9AD59B599C639C679C669C629C5E9C609E029DFE9E079E03
+9E069E059E009E019E099DFF9DFD9E049EA09F1E9F469F749F759F7656D4652E
+65B86B186B196B176B1A7062722672AA77D877D979397C697C6B7CF67E9A0000
+F9
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+7E987E9B7E9981E081E18646864786488979897A897C897B89FF8B988B998EA5
+8EA48EA3946E946D946F9471947397499872995F9C689C6E9C6D9E0B9E0D9E10
+9E0F9E129E119EA19EF59F099F479F789F7B9F7A9F79571E70667C6F883C8DB2
+8EA691C394749478947694759A609C749C739C719C759E149E139EF69F0A0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00009FA4706870657CF7866A883E883D883F8B9E8C9C8EA98EC9974B98739874
+98CC996199AB9A649A669A679B249E159E179F4862076B1E7227864C8EA89482
+948094819A699A689B2E9E197229864B8B9F94839C799EB776759A6B9C7A9E1D
+7069706A9EA49F7E9F499F980000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
diff --git a/library/encoding/cp1250.enc b/library/encoding/cp1250.enc
new file mode 100644
index 0000000..070ad90
--- /dev/null
+++ b/library/encoding/cp1250.enc
@@ -0,0 +1,20 @@
+# Encoding file: cp1250, single-byte
+S
+003F 0 1
+00
+0000000100020003000400050006000700080009000A000B000C000D000E000F
+0010001100120013001400150016001700180019001A001B001C001D001E001F
+0020002100220023002400250026002700280029002A002B002C002D002E002F
+0030003100320033003400350036003700380039003A003B003C003D003E003F
+0040004100420043004400450046004700480049004A004B004C004D004E004F
+0050005100520053005400550056005700580059005A005B005C005D005E005F
+0060006100620063006400650066006700680069006A006B006C006D006E006F
+0070007100720073007400750076007700780079007A007B007C007D007E007F
+20AC0081201A0083201E2026202020210088203001602039015A0164017D0179
+009020182019201C201D202220132014009821220161203A015B0165017E017A
+00A002C702D8014100A4010400A600A700A800A9015E00AB00AC00AD00AE017B
+00B000B102DB014200B400B500B600B700B80105015F00BB013D02DD013E017C
+015400C100C2010200C40139010600C7010C00C9011800CB011A00CD00CE010E
+01100143014700D300D4015000D600D70158016E00DA017000DC00DD016200DF
+015500E100E2010300E4013A010700E7010D00E9011900EB011B00ED00EE010F
+01110144014800F300F4015100F600F70159016F00FA017100FC00FD016302D9
diff --git a/library/encoding/cp1251.enc b/library/encoding/cp1251.enc
new file mode 100644
index 0000000..376b1b4
--- /dev/null
+++ b/library/encoding/cp1251.enc
@@ -0,0 +1,20 @@
+# Encoding file: cp1251, single-byte
+S
+003F 0 1
+00
+0000000100020003000400050006000700080009000A000B000C000D000E000F
+0010001100120013001400150016001700180019001A001B001C001D001E001F
+0020002100220023002400250026002700280029002A002B002C002D002E002F
+0030003100320033003400350036003700380039003A003B003C003D003E003F
+0040004100420043004400450046004700480049004A004B004C004D004E004F
+0050005100520053005400550056005700580059005A005B005C005D005E005F
+0060006100620063006400650066006700680069006A006B006C006D006E006F
+0070007100720073007400750076007700780079007A007B007C007D007E007F
+04020403201A0453201E20262020202120AC203004092039040A040C040B040F
+045220182019201C201D202220132014009821220459203A045A045C045B045F
+00A0040E045E040800A4049000A600A7040100A9040400AB00AC00AD00AE0407
+00B000B104060456049100B500B600B704512116045400BB0458040504550457
+0410041104120413041404150416041704180419041A041B041C041D041E041F
+0420042104220423042404250426042704280429042A042B042C042D042E042F
+0430043104320433043404350436043704380439043A043B043C043D043E043F
+0440044104420443044404450446044704480449044A044B044C044D044E044F
diff --git a/library/encoding/cp1252.enc b/library/encoding/cp1252.enc
new file mode 100644
index 0000000..dd525ea
--- /dev/null
+++ b/library/encoding/cp1252.enc
@@ -0,0 +1,20 @@
+# Encoding file: cp1252, single-byte
+S
+003F 0 1
+00
+0000000100020003000400050006000700080009000A000B000C000D000E000F
+0010001100120013001400150016001700180019001A001B001C001D001E001F
+0020002100220023002400250026002700280029002A002B002C002D002E002F
+0030003100320033003400350036003700380039003A003B003C003D003E003F
+0040004100420043004400450046004700480049004A004B004C004D004E004F
+0050005100520053005400550056005700580059005A005B005C005D005E005F
+0060006100620063006400650066006700680069006A006B006C006D006E006F
+0070007100720073007400750076007700780079007A007B007C007D007E007F
+20AC0081201A0192201E20262020202102C62030016020390152008D017D008F
+009020182019201C201D20222013201402DC21220161203A0153009D017E0178
+00A000A100A200A300A400A500A600A700A800A900AA00AB00AC00AD00AE00AF
+00B000B100B200B300B400B500B600B700B800B900BA00BB00BC00BD00BE00BF
+00C000C100C200C300C400C500C600C700C800C900CA00CB00CC00CD00CE00CF
+00D000D100D200D300D400D500D600D700D800D900DA00DB00DC00DD00DE00DF
+00E000E100E200E300E400E500E600E700E800E900EA00EB00EC00ED00EE00EF
+00F000F100F200F300F400F500F600F700F800F900FA00FB00FC00FD00FE00FF
diff --git a/library/encoding/cp1253.enc b/library/encoding/cp1253.enc
new file mode 100644
index 0000000..a8754c3
--- /dev/null
+++ b/library/encoding/cp1253.enc
@@ -0,0 +1,20 @@
+# Encoding file: cp1253, single-byte
+S
+003F 0 1
+00
+0000000100020003000400050006000700080009000A000B000C000D000E000F
+0010001100120013001400150016001700180019001A001B001C001D001E001F
+0020002100220023002400250026002700280029002A002B002C002D002E002F
+0030003100320033003400350036003700380039003A003B003C003D003E003F
+0040004100420043004400450046004700480049004A004B004C004D004E004F
+0050005100520053005400550056005700580059005A005B005C005D005E005F
+0060006100620063006400650066006700680069006A006B006C006D006E006F
+0070007100720073007400750076007700780079007A007B007C007D007E007F
+20AC0081201A0192201E20262020202100882030008A2039008C008D008E008F
+009020182019201C201D20222013201400982122009A203A009C009D009E009F
+00A00385038600A300A400A500A600A700A800A9000000AB00AC00AD00AE2015
+00B000B100B200B3038400B500B600B703880389038A00BB038C00BD038E038F
+0390039103920393039403950396039703980399039A039B039C039D039E039F
+03A003A1000003A303A403A503A603A703A803A903AA03AB03AC03AD03AE03AF
+03B003B103B203B303B403B503B603B703B803B903BA03BB03BC03BD03BE03BF
+03C003C103C203C303C403C503C603C703C803C903CA03CB03CC03CD03CE0000
diff --git a/library/encoding/cp1254.enc b/library/encoding/cp1254.enc
new file mode 100644
index 0000000..b9e3b3c
--- /dev/null
+++ b/library/encoding/cp1254.enc
@@ -0,0 +1,20 @@
+# Encoding file: cp1254, single-byte
+S
+003F 0 1
+00
+0000000100020003000400050006000700080009000A000B000C000D000E000F
+0010001100120013001400150016001700180019001A001B001C001D001E001F
+0020002100220023002400250026002700280029002A002B002C002D002E002F
+0030003100320033003400350036003700380039003A003B003C003D003E003F
+0040004100420043004400450046004700480049004A004B004C004D004E004F
+0050005100520053005400550056005700580059005A005B005C005D005E005F
+0060006100620063006400650066006700680069006A006B006C006D006E006F
+0070007100720073007400750076007700780079007A007B007C007D007E007F
+20AC0081201A0192201E20262020202102C62030016020390152008D008E008F
+009020182019201C201D20222013201402DC21220161203A0153009D009E0178
+00A000A100A200A300A400A500A600A700A800A900AA00AB00AC00AD00AE00AF
+00B000B100B200B300B400B500B600B700B800B900BA00BB00BC00BD00BE00BF
+00C000C100C200C300C400C500C600C700C800C900CA00CB00CC00CD00CE00CF
+011E00D100D200D300D400D500D600D700D800D900DA00DB00DC0130015E00DF
+00E000E100E200E300E400E500E600E700E800E900EA00EB00EC00ED00EE00EF
+011F00F100F200F300F400F500F600F700F800F900FA00FB00FC0131015F00FF
diff --git a/library/encoding/cp1255.enc b/library/encoding/cp1255.enc
new file mode 100644
index 0000000..6e78b95
--- /dev/null
+++ b/library/encoding/cp1255.enc
@@ -0,0 +1,20 @@
+# Encoding file: cp1255, single-byte
+S
+003F 0 1
+00
+0000000100020003000400050006000700080009000A000B000C000D000E000F
+0010001100120013001400150016001700180019001A001B001C001D001E001F
+0020002100220023002400250026002700280029002A002B002C002D002E002F
+0030003100320033003400350036003700380039003A003B003C003D003E003F
+0040004100420043004400450046004700480049004A004B004C004D004E004F
+0050005100520053005400550056005700580059005A005B005C005D005E005F
+0060006100620063006400650066006700680069006A006B006C006D006E006F
+0070007100720073007400750076007700780079007A007B007C007D007E007F
+20AC0081201A0192201E20262020202102C62030008A2039008C008D008E008F
+009020182019201C201D20222013201402DC2122009A203A009C009D009E009F
+00A000A100A200A320AA00A500A600A700A800A900D700AB00AC00AD00AE00AF
+00B000B100B200B300B400B500B600B700B800B900F700BB00BC00BD00BE00BF
+05B005B105B205B305B405B505B605B705B805B9000005BB05BC05BD05BE05BF
+05C005C105C205C305F005F105F205F305F40000000000000000000000000000
+05D005D105D205D305D405D505D605D705D805D905DA05DB05DC05DD05DE05DF
+05E005E105E205E305E405E505E605E705E805E905EA00000000200E200F0000
diff --git a/library/encoding/cp1256.enc b/library/encoding/cp1256.enc
new file mode 100644
index 0000000..a98762a
--- /dev/null
+++ b/library/encoding/cp1256.enc
@@ -0,0 +1,20 @@
+# Encoding file: cp1256, single-byte
+S
+003F 0 1
+00
+0000000100020003000400050006000700080009000A000B000C000D000E000F
+0010001100120013001400150016001700180019001A001B001C001D001E001F
+0020002100220023002400250026002700280029002A002B002C002D002E002F
+0030003100320033003400350036003700380039003A003B003C003D003E003F
+0040004100420043004400450046004700480049004A004B004C004D004E004F
+0050005100520053005400550056005700580059005A005B005C005D005E005F
+0060006100620063006400650066006700680069006A006B006C006D006E006F
+0070007100720073007400750076007700780079007A007B007C007D007E007F
+20AC067E201A0192201E20262020202102C62030067920390152068606980688
+06AF20182019201C201D20222013201406A921220691203A0153200C200D06BA
+00A0060C00A200A300A400A500A600A700A800A906BE00AB00AC00AD00AE00AF
+00B000B100B200B300B400B500B600B700B800B9061B00BB00BC00BD00BE061F
+06C1062106220623062406250626062706280629062A062B062C062D062E062F
+063006310632063306340635063600D7063706380639063A0640064106420643
+00E0064400E2064506460647064800E700E800E900EA00EB0649064A00EE00EF
+064B064C064D064E00F4064F065000F7065100F9065200FB00FC200E200F06D2
diff --git a/library/encoding/cp1257.enc b/library/encoding/cp1257.enc
new file mode 100644
index 0000000..4aa135d
--- /dev/null
+++ b/library/encoding/cp1257.enc
@@ -0,0 +1,20 @@
+# Encoding file: cp1257, single-byte
+S
+003F 0 1
+00
+0000000100020003000400050006000700080009000A000B000C000D000E000F
+0010001100120013001400150016001700180019001A001B001C001D001E001F
+0020002100220023002400250026002700280029002A002B002C002D002E002F
+0030003100320033003400350036003700380039003A003B003C003D003E003F
+0040004100420043004400450046004700480049004A004B004C004D004E004F
+0050005100520053005400550056005700580059005A005B005C005D005E005F
+0060006100620063006400650066006700680069006A006B006C006D006E006F
+0070007100720073007400750076007700780079007A007B007C007D007E007F
+20AC0081201A0083201E20262020202100882030008A2039008C00A802C700B8
+009020182019201C201D20222013201400982122009A203A009C00AF02DB009F
+00A0000000A200A300A4000000A600A700D800A9015600AB00AC00AD00AE00C6
+00B000B100B200B300B400B500B600B700F800B9015700BB00BC00BD00BE00E6
+0104012E0100010600C400C501180112010C00C90179011601220136012A013B
+01600143014500D3014C00D500D600D701720141015A016A00DC017B017D00DF
+0105012F0101010700E400E501190113010D00E9017A011701230137012B013C
+01610144014600F3014D00F500F600F701730142015B016B00FC017C017E02D9
diff --git a/library/encoding/cp1258.enc b/library/encoding/cp1258.enc
new file mode 100644
index 0000000..95fdef8
--- /dev/null
+++ b/library/encoding/cp1258.enc
@@ -0,0 +1,20 @@
+# Encoding file: cp1258, single-byte
+S
+003F 0 1
+00
+0000000100020003000400050006000700080009000A000B000C000D000E000F
+0010001100120013001400150016001700180019001A001B001C001D001E001F
+0020002100220023002400250026002700280029002A002B002C002D002E002F
+0030003100320033003400350036003700380039003A003B003C003D003E003F
+0040004100420043004400450046004700480049004A004B004C004D004E004F
+0050005100520053005400550056005700580059005A005B005C005D005E005F
+0060006100620063006400650066006700680069006A006B006C006D006E006F
+0070007100720073007400750076007700780079007A007B007C007D007E007F
+20AC0081201A0192201E20262020202102C62030008A20390152008D008E008F
+009020182019201C201D20222013201402DC2122009A203A0153009D009E0178
+00A000A100A200A300A400A500A600A700A800A900AA00AB00AC00AD00AE00AF
+00B000B100B200B300B400B500B600B700B800B900BA00BB00BC00BD00BE00BF
+00C000C100C2010200C400C500C600C700C800C900CA00CB030000CD00CE00CF
+011000D1030900D300D401A000D600D700D800D900DA00DB00DC01AF030300DF
+00E000E100E2010300E400E500E600E700E800E900EA00EB030100ED00EE00EF
+011100F1032300F300F401A100F600F700F800F900FA00FB00FC01B020AB00FF
diff --git a/library/encoding/cp437.enc b/library/encoding/cp437.enc
new file mode 100644
index 0000000..ecae4e6
--- /dev/null
+++ b/library/encoding/cp437.enc
@@ -0,0 +1,20 @@
+# Encoding file: cp437, single-byte
+S
+003F 0 1
+00
+0000000100020003000400050006000700080009000A000B000C000D000E000F
+0010001100120013001400150016001700180019001A001B001C001D001E001F
+0020002100220023002400250026002700280029002A002B002C002D002E002F
+0030003100320033003400350036003700380039003A003B003C003D003E003F
+0040004100420043004400450046004700480049004A004B004C004D004E004F
+0050005100520053005400550056005700580059005A005B005C005D005E005F
+0060006100620063006400650066006700680069006A006B006C006D006E006F
+0070007100720073007400750076007700780079007A007B007C007D007E007F
+00C700FC00E900E200E400E000E500E700EA00EB00E800EF00EE00EC00C400C5
+00C900E600C600F400F600F200FB00F900FF00D600DC00A200A300A520A70192
+00E100ED00F300FA00F100D100AA00BA00BF231000AC00BD00BC00A100AB00BB
+259125922593250225242561256225562555256325512557255D255C255B2510
+25142534252C251C2500253C255E255F255A25542569256625602550256C2567
+2568256425652559255825522553256B256A2518250C25882584258C25902580
+03B100DF039303C003A303C300B503C403A6039803A903B4221E03C603B52229
+226100B1226522642320232100F7224800B0221900B7221A207F00B225A000A0
diff --git a/library/encoding/cp737.enc b/library/encoding/cp737.enc
new file mode 100644
index 0000000..5b59661
--- /dev/null
+++ b/library/encoding/cp737.enc
@@ -0,0 +1,20 @@
+# Encoding file: cp737, single-byte
+S
+003F 0 1
+00
+0000000100020003000400050006000700080009000A000B000C000D000E000F
+0010001100120013001400150016001700180019001A001B001C001D001E001F
+0020002100220023002400250026002700280029002A002B002C002D002E002F
+0030003100320033003400350036003700380039003A003B003C003D003E003F
+0040004100420043004400450046004700480049004A004B004C004D004E004F
+0050005100520053005400550056005700580059005A005B005C005D005E005F
+0060006100620063006400650066006700680069006A006B006C006D006E006F
+0070007100720073007400750076007700780079007A007B007C007D007E007F
+039103920393039403950396039703980399039A039B039C039D039E039F03A0
+03A103A303A403A503A603A703A803A903B103B203B303B403B503B603B703B8
+03B903BA03BB03BC03BD03BE03BF03C003C103C303C203C403C503C603C703C8
+259125922593250225242561256225562555256325512557255D255C255B2510
+25142534252C251C2500253C255E255F255A25542569256625602550256C2567
+2568256425652559255825522553256B256A2518250C25882584258C25902580
+03C903AC03AD03AE03CA03AF03CC03CD03CB03CE038603880389038A038C038E
+038F00B12265226403AA03AB00F7224800B0221900B7221A207F00B225A000A0
diff --git a/library/encoding/cp775.enc b/library/encoding/cp775.enc
new file mode 100644
index 0000000..71b65c3
--- /dev/null
+++ b/library/encoding/cp775.enc
@@ -0,0 +1,20 @@
+# Encoding file: cp775, single-byte
+S
+003F 0 1
+00
+0000000100020003000400050006000700080009000A000B000C000D000E000F
+0010001100120013001400150016001700180019001A001B001C001D001E001F
+0020002100220023002400250026002700280029002A002B002C002D002E002F
+0030003100320033003400350036003700380039003A003B003C003D003E003F
+0040004100420043004400450046004700480049004A004B004C004D004E004F
+0050005100520053005400550056005700580059005A005B005C005D005E005F
+0060006100620063006400650066006700680069006A006B006C006D006E006F
+0070007100720073007400750076007700780079007A007B007C007D007E007F
+010600FC00E9010100E4012300E501070142011301560157012B017900C400C5
+00C900E600C6014D00F6012200A2015A015B00D600DC00F800A300D800D700A4
+0100012A00F3017B017C017A201D00A600A900AE00AC00BD00BC014100AB00BB
+259125922593250225240104010C01180116256325512557255D012E01602510
+25142534252C251C2500253C0172016A255A25542569256625602550256C017D
+0105010D01190117012F01610173016B017E2518250C25882584258C25902580
+00D300DF014C014300F500D500B5014401360137013B013C0146011201452019
+00AD00B1201C00BE00B600A700F7201E00B0221900B700B900B300B225A000A0
diff --git a/library/encoding/cp850.enc b/library/encoding/cp850.enc
new file mode 100644
index 0000000..4e7a90d
--- /dev/null
+++ b/library/encoding/cp850.enc
@@ -0,0 +1,20 @@
+# Encoding file: cp850, single-byte
+S
+003F 0 1
+00
+0000000100020003000400050006000700080009000A000B000C000D000E000F
+0010001100120013001400150016001700180019001A001B001C001D001E001F
+0020002100220023002400250026002700280029002A002B002C002D002E002F
+0030003100320033003400350036003700380039003A003B003C003D003E003F
+0040004100420043004400450046004700480049004A004B004C004D004E004F
+0050005100520053005400550056005700580059005A005B005C005D005E005F
+0060006100620063006400650066006700680069006A006B006C006D006E006F
+0070007100720073007400750076007700780079007A007B007C007D007E007F
+00C700FC00E900E200E400E000E500E700EA00EB00E800EF00EE00EC00C400C5
+00C900E600C600F400F600F200FB00F900FF00D600DC00F800A300D800D70192
+00E100ED00F300FA00F100D100AA00BA00BF00AE00AC00BD00BC00A100AB00BB
+2591259225932502252400C100C200C000A9256325512557255D00A200A52510
+25142534252C251C2500253C00E300C3255A25542569256625602550256C00A4
+00F000D000CA00CB00C8013100CD00CE00CF2518250C2588258400A600CC2580
+00D300DF00D400D200F500D500B500FE00DE00DA00DB00D900FD00DD00AF00B4
+00AD00B1201700BE00B600A700F700B800B000A800B700B900B300B225A000A0
diff --git a/library/encoding/cp852.enc b/library/encoding/cp852.enc
new file mode 100644
index 0000000..f34899e
--- /dev/null
+++ b/library/encoding/cp852.enc
@@ -0,0 +1,20 @@
+# Encoding file: cp852, single-byte
+S
+003F 0 1
+00
+0000000100020003000400050006000700080009000A000B000C000D000E000F
+0010001100120013001400150016001700180019001A001B001C001D001E001F
+0020002100220023002400250026002700280029002A002B002C002D002E002F
+0030003100320033003400350036003700380039003A003B003C003D003E003F
+0040004100420043004400450046004700480049004A004B004C004D004E004F
+0050005100520053005400550056005700580059005A005B005C005D005E005F
+0060006100620063006400650066006700680069006A006B006C006D006E006F
+0070007100720073007400750076007700780079007A007B007C007D007E007F
+00C700FC00E900E200E4016F010700E7014200EB0150015100EE017900C40106
+00C90139013A00F400F6013D013E015A015B00D600DC01640165014100D7010D
+00E100ED00F300FA01040105017D017E0118011900AC017A010C015F00AB00BB
+2591259225932502252400C100C2011A015E256325512557255D017B017C2510
+25142534252C251C2500253C01020103255A25542569256625602550256C00A4
+01110110010E00CB010F014700CD00CE011B2518250C258825840162016E2580
+00D300DF00D401430144014801600161015400DA0155017000FD00DD016300B4
+00AD02DD02DB02C702D800A700F700B800B000A802D901710158015925A000A0
diff --git a/library/encoding/cp855.enc b/library/encoding/cp855.enc
new file mode 100644
index 0000000..4d58b86
--- /dev/null
+++ b/library/encoding/cp855.enc
@@ -0,0 +1,20 @@
+# Encoding file: cp855, single-byte
+S
+003F 0 1
+00
+0000000100020003000400050006000700080009000A000B000C000D000E000F
+0010001100120013001400150016001700180019001A001B001C001D001E001F
+0020002100220023002400250026002700280029002A002B002C002D002E002F
+0030003100320033003400350036003700380039003A003B003C003D003E003F
+0040004100420043004400450046004700480049004A004B004C004D004E004F
+0050005100520053005400550056005700580059005A005B005C005D005E005F
+0060006100620063006400650066006700680069006A006B006C006D006E006F
+0070007100720073007400750076007700780079007A007B007C007D007E007F
+0452040204530403045104010454040404550405045604060457040704580408
+04590409045A040A045B040B045C040C045E040E045F040F044E042E044A042A
+0430041004310411044604260434041404350415044404240433041300AB00BB
+259125922593250225240445042504380418256325512557255D043904192510
+25142534252C251C2500253C043A041A255A25542569256625602550256C00A4
+043B041B043C041C043D041D043E041E043F2518250C25882584041F044F2580
+042F044004200441042104420422044304230436041604320412044C042C2116
+00AD044B042B0437041704480428044D042D044904290447042700A725A000A0
diff --git a/library/encoding/cp857.enc b/library/encoding/cp857.enc
new file mode 100644
index 0000000..b42ed55
--- /dev/null
+++ b/library/encoding/cp857.enc
@@ -0,0 +1,20 @@
+# Encoding file: cp857, single-byte
+S
+003F 0 1
+00
+0000000100020003000400050006000700080009000A000B000C000D000E000F
+0010001100120013001400150016001700180019001A001B001C001D001E001F
+0020002100220023002400250026002700280029002A002B002C002D002E002F
+0030003100320033003400350036003700380039003A003B003C003D003E003F
+0040004100420043004400450046004700480049004A004B004C004D004E004F
+0050005100520053005400550056005700580059005A005B005C005D005E005F
+0060006100620063006400650066006700680069006A006B006C006D006E006F
+0070007100720073007400750076007700780079007A007B007C007D007E007F
+00C700FC00E900E200E400E000E500E700EA00EB00E800EF00EE013100C400C5
+00C900E600C600F400F600F200FB00F9013000D600DC00F800A300D8015E015F
+00E100ED00F300FA00F100D1011E011F00BF00AE00AC00BD00BC00A100AB00BB
+2591259225932502252400C100C200C000A9256325512557255D00A200A52510
+25142534252C251C2500253C00E300C3255A25542569256625602550256C00A4
+00BA00AA00CA00CB00C8000000CD00CE00CF2518250C2588258400A600CC2580
+00D300DF00D400D200F500D500B5000000D700DA00DB00D900EC00FF00AF00B4
+00AD00B1000000BE00B600A700F700B800B000A800B700B900B300B225A000A0
diff --git a/library/encoding/cp860.enc b/library/encoding/cp860.enc
new file mode 100644
index 0000000..871943b
--- /dev/null
+++ b/library/encoding/cp860.enc
@@ -0,0 +1,20 @@
+# Encoding file: cp860, single-byte
+S
+003F 0 1
+00
+0000000100020003000400050006000700080009000A000B000C000D000E000F
+0010001100120013001400150016001700180019001A001B001C001D001E001F
+0020002100220023002400250026002700280029002A002B002C002D002E002F
+0030003100320033003400350036003700380039003A003B003C003D003E003F
+0040004100420043004400450046004700480049004A004B004C004D004E004F
+0050005100520053005400550056005700580059005A005B005C005D005E005F
+0060006100620063006400650066006700680069006A006B006C006D006E006F
+0070007100720073007400750076007700780079007A007B007C007D007E007F
+00C700FC00E900E200E300E000C100E700EA00CA00E800CD00D400EC00C300C2
+00C900C000C800F400F500F200DA00F900CC00D500DC00A200A300D920A700D3
+00E100ED00F300FA00F100D100AA00BA00BF00D200AC00BD00BC00A100AB00BB
+259125922593250225242561256225562555256325512557255D255C255B2510
+25142534252C251C2500253C255E255F255A25542569256625602550256C2567
+2568256425652559255825522553256B256A2518250C25882584258C25902580
+03B100DF039303C003A303C300B503C403A6039803A903B4221E03C603B52229
+226100B1226522642320232100F7224800B0221900B7221A207F00B225A000A0
diff --git a/library/encoding/cp861.enc b/library/encoding/cp861.enc
new file mode 100644
index 0000000..3f8f605
--- /dev/null
+++ b/library/encoding/cp861.enc
@@ -0,0 +1,20 @@
+# Encoding file: cp861, single-byte
+S
+003F 0 1
+00
+0000000100020003000400050006000700080009000A000B000C000D000E000F
+0010001100120013001400150016001700180019001A001B001C001D001E001F
+0020002100220023002400250026002700280029002A002B002C002D002E002F
+0030003100320033003400350036003700380039003A003B003C003D003E003F
+0040004100420043004400450046004700480049004A004B004C004D004E004F
+0050005100520053005400550056005700580059005A005B005C005D005E005F
+0060006100620063006400650066006700680069006A006B006C006D006E006F
+0070007100720073007400750076007700780079007A007B007C007D007E007F
+00C700FC00E900E200E400E000E500E700EA00EB00E800D000F000DE00C400C5
+00C900E600C600F400F600FE00FB00DD00FD00D600DC00F800A300D820A70192
+00E100ED00F300FA00C100CD00D300DA00BF231000AC00BD00BC00A100AB00BB
+259125922593250225242561256225562555256325512557255D255C255B2510
+25142534252C251C2500253C255E255F255A25542569256625602550256C2567
+2568256425652559255825522553256B256A2518250C25882584258C25902580
+03B100DF039303C003A303C300B503C403A6039803A903B4221E03C603B52229
+226100B1226522642320232100F7224800B0221900B7221A207F00B225A000A0
diff --git a/library/encoding/cp862.enc b/library/encoding/cp862.enc
new file mode 100644
index 0000000..5f9d16c
--- /dev/null
+++ b/library/encoding/cp862.enc
@@ -0,0 +1,20 @@
+# Encoding file: cp862, single-byte
+S
+003F 0 1
+00
+0000000100020003000400050006000700080009000A000B000C000D000E000F
+0010001100120013001400150016001700180019001A001B001C001D001E001F
+0020002100220023002400250026002700280029002A002B002C002D002E002F
+0030003100320033003400350036003700380039003A003B003C003D003E003F
+0040004100420043004400450046004700480049004A004B004C004D004E004F
+0050005100520053005400550056005700580059005A005B005C005D005E005F
+0060006100620063006400650066006700680069006A006B006C006D006E006F
+0070007100720073007400750076007700780079007A007B007C007D007E007F
+05D005D105D205D305D405D505D605D705D805D905DA05DB05DC05DD05DE05DF
+05E005E105E205E305E405E505E605E705E805E905EA00A200A300A520A70192
+00E100ED00F300FA00F100D100AA00BA00BF231000AC00BD00BC00A100AB00BB
+259125922593250225242561256225562555256325512557255D255C255B2510
+25142534252C251C2500253C255E255F255A25542569256625602550256C2567
+2568256425652559255825522553256B256A2518250C25882584258C25902580
+03B100DF039303C003A303C300B503C403A6039803A903B4221E03C603B52229
+226100B1226522642320232100F7224800B0221900B7221A207F00B225A000A0
diff --git a/library/encoding/cp863.enc b/library/encoding/cp863.enc
new file mode 100644
index 0000000..c8b8686
--- /dev/null
+++ b/library/encoding/cp863.enc
@@ -0,0 +1,20 @@
+# Encoding file: cp863, single-byte
+S
+003F 0 1
+00
+0000000100020003000400050006000700080009000A000B000C000D000E000F
+0010001100120013001400150016001700180019001A001B001C001D001E001F
+0020002100220023002400250026002700280029002A002B002C002D002E002F
+0030003100320033003400350036003700380039003A003B003C003D003E003F
+0040004100420043004400450046004700480049004A004B004C004D004E004F
+0050005100520053005400550056005700580059005A005B005C005D005E005F
+0060006100620063006400650066006700680069006A006B006C006D006E006F
+0070007100720073007400750076007700780079007A007B007C007D007E007F
+00C700FC00E900E200C200E000B600E700EA00EB00E800EF00EE201700C000A7
+00C900C800CA00F400CB00CF00FB00F900A400D400DC00A200A300D900DB0192
+00A600B400F300FA00A800B800B300AF00CE231000AC00BD00BC00BE00AB00BB
+259125922593250225242561256225562555256325512557255D255C255B2510
+25142534252C251C2500253C255E255F255A25542569256625602550256C2567
+2568256425652559255825522553256B256A2518250C25882584258C25902580
+03B100DF039303C003A303C300B503C403A6039803A903B4221E03C603B52229
+226100B1226522642320232100F7224800B0221900B7221A207F00B225A000A0
diff --git a/library/encoding/cp864.enc b/library/encoding/cp864.enc
new file mode 100644
index 0000000..71f9e62
--- /dev/null
+++ b/library/encoding/cp864.enc
@@ -0,0 +1,20 @@
+# Encoding file: cp864, single-byte
+S
+003F 0 1
+00
+0000000100020003000400050006000700080009000A000B000C000D000E000F
+0010001100120013001400150016001700180019001A001B001C001D001E001F
+00200021002200230024066A0026002700280029002A002B002C002D002E002F
+0030003100320033003400350036003700380039003A003B003C003D003E003F
+0040004100420043004400450046004700480049004A004B004C004D004E004F
+0050005100520053005400550056005700580059005A005B005C005D005E005F
+0060006100620063006400650066006700680069006A006B006C006D006E006F
+0070007100720073007400750076007700780079007A007B007C007D007E007F
+00B000B72219221A259225002502253C2524252C251C25342510250C25142518
+03B2221E03C600B100BD00BC224800AB00BBFEF7FEF8009B009CFEFBFEFC009F
+00A000ADFE8200A300A4FE8400000000FE8EFE8FFE95FE99060CFE9DFEA1FEA5
+0660066106620663066406650666066706680669FED1061BFEB1FEB5FEB9061F
+00A2FE80FE81FE83FE85FECAFE8BFE8DFE91FE93FE97FE9BFE9FFEA3FEA7FEA9
+FEABFEADFEAFFEB3FEB7FEBBFEBFFEC1FEC5FECBFECF00A600AC00F700D7FEC9
+0640FED3FED7FEDBFEDFFEE3FEE7FEEBFEEDFEEFFEF3FEBDFECCFECEFECDFEE1
+FE7D0651FEE5FEE9FEECFEF0FEF2FED0FED5FEF5FEF6FEDDFED9FEF125A00000
diff --git a/library/encoding/cp865.enc b/library/encoding/cp865.enc
new file mode 100644
index 0000000..543da9c
--- /dev/null
+++ b/library/encoding/cp865.enc
@@ -0,0 +1,20 @@
+# Encoding file: cp865, single-byte
+S
+003F 0 1
+00
+0000000100020003000400050006000700080009000A000B000C000D000E000F
+0010001100120013001400150016001700180019001A001B001C001D001E001F
+0020002100220023002400250026002700280029002A002B002C002D002E002F
+0030003100320033003400350036003700380039003A003B003C003D003E003F
+0040004100420043004400450046004700480049004A004B004C004D004E004F
+0050005100520053005400550056005700580059005A005B005C005D005E005F
+0060006100620063006400650066006700680069006A006B006C006D006E006F
+0070007100720073007400750076007700780079007A007B007C007D007E007F
+00C700FC00E900E200E400E000E500E700EA00EB00E800EF00EE00EC00C400C5
+00C900E600C600F400F600F200FB00F900FF00D600DC00F800A300D820A70192
+00E100ED00F300FA00F100D100AA00BA00BF231000AC00BD00BC00A100AB00A4
+259125922593250225242561256225562555256325512557255D255C255B2510
+25142534252C251C2500253C255E255F255A25542569256625602550256C2567
+2568256425652559255825522553256B256A2518250C25882584258C25902580
+03B100DF039303C003A303C300B503C403A6039803A903B4221E03C603B52229
+226100B1226522642320232100F7224800B0221900B7221A207F00B225A000A0
diff --git a/library/encoding/cp866.enc b/library/encoding/cp866.enc
new file mode 100644
index 0000000..b851cf5
--- /dev/null
+++ b/library/encoding/cp866.enc
@@ -0,0 +1,20 @@
+# Encoding file: cp866, single-byte
+S
+003F 0 1
+00
+0000000100020003000400050006000700080009000A000B000C000D000E000F
+0010001100120013001400150016001700180019001A001B001C001D001E001F
+0020002100220023002400250026002700280029002A002B002C002D002E002F
+0030003100320033003400350036003700380039003A003B003C003D003E003F
+0040004100420043004400450046004700480049004A004B004C004D004E004F
+0050005100520053005400550056005700580059005A005B005C005D005E005F
+0060006100620063006400650066006700680069006A006B006C006D006E006F
+0070007100720073007400750076007700780079007A007B007C007D007E007F
+0410041104120413041404150416041704180419041A041B041C041D041E041F
+0420042104220423042404250426042704280429042A042B042C042D042E042F
+0430043104320433043404350436043704380439043A043B043C043D043E043F
+259125922593250225242561256225562555256325512557255D255C255B2510
+25142534252C251C2500253C255E255F255A25542569256625602550256C2567
+2568256425652559255825522553256B256A2518250C25882584258C25902580
+0440044104420443044404450446044704480449044A044B044C044D044E044F
+040104510404045404070457040E045E00B0221900B7221A211600A425A000A0
diff --git a/library/encoding/cp869.enc b/library/encoding/cp869.enc
new file mode 100644
index 0000000..9fd2929
--- /dev/null
+++ b/library/encoding/cp869.enc
@@ -0,0 +1,20 @@
+# Encoding file: cp869, single-byte
+S
+003F 0 1
+00
+0000000100020003000400050006000700080009000A000B000C000D000E000F
+0010001100120013001400150016001700180019001A001B001C001D001E001F
+0020002100220023002400250026002700280029002A002B002C002D002E002F
+0030003100320033003400350036003700380039003A003B003C003D003E003F
+0040004100420043004400450046004700480049004A004B004C004D004E004F
+0050005100520053005400550056005700580059005A005B005C005D005E005F
+0060006100620063006400650066006700680069006A006B006C006D006E006F
+0070007100720073007400750076007700780079007A007B007C007D007E007F
+0080008100820083008400850386008700B700AC00A620182019038820150389
+038A03AA038C00930094038E03AB00A9038F00B200B303AC00A303AD03AE03AF
+03CA039003CC03CD039103920393039403950396039700BD0398039900AB00BB
+25912592259325022524039A039B039C039D256325512557255D039E039F2510
+25142534252C251C2500253C03A003A1255A25542569256625602550256C03A3
+03A403A503A603A703A803A903B103B203B32518250C2588258403B403B52580
+03B603B703B803B903BA03BB03BC03BD03BE03BF03C003C103C303C203C40384
+00AD00B103C503C603C700A703C8038500B000A803C903CB03B003CE25A000A0
diff --git a/library/encoding/cp874.enc b/library/encoding/cp874.enc
new file mode 100644
index 0000000..0487b97
--- /dev/null
+++ b/library/encoding/cp874.enc
@@ -0,0 +1,20 @@
+# Encoding file: cp874, single-byte
+S
+003F 0 1
+00
+0000000100020003000400050006000700080009000A000B000C000D000E000F
+0010001100120013001400150016001700180019001A001B001C001D001E001F
+0020002100220023002400250026002700280029002A002B002C002D002E002F
+0030003100320033003400350036003700380039003A003B003C003D003E003F
+0040004100420043004400450046004700480049004A004B004C004D004E004F
+0050005100520053005400550056005700580059005A005B005C005D005E005F
+0060006100620063006400650066006700680069006A006B006C006D006E006F
+0070007100720073007400750076007700780079007A007B007C007D007E007F
+20AC008100820083008420260086008700880089008A008B008C008D008E008F
+009020182019201C201D20222013201400980099009A009B009C009D009E009F
+00A00E010E020E030E040E050E060E070E080E090E0A0E0B0E0C0E0D0E0E0E0F
+0E100E110E120E130E140E150E160E170E180E190E1A0E1B0E1C0E1D0E1E0E1F
+0E200E210E220E230E240E250E260E270E280E290E2A0E2B0E2C0E2D0E2E0E2F
+0E300E310E320E330E340E350E360E370E380E390E3A00000000000000000E3F
+0E400E410E420E430E440E450E460E470E480E490E4A0E4B0E4C0E4D0E4E0E4F
+0E500E510E520E530E540E550E560E570E580E590E5A0E5B0000000000000000
diff --git a/library/encoding/cp932.enc b/library/encoding/cp932.enc
new file mode 100644
index 0000000..8da8cd6
--- /dev/null
+++ b/library/encoding/cp932.enc
@@ -0,0 +1,801 @@
+# Encoding file: cp932, multi-byte
+M
+003F 0 46
+00
+0000000100020003000400050006000700080009000A000B000C000D000E000F
+0010001100120013001400150016001700180019001A001B001C001D001E001F
+0020002100220023002400250026002700280029002A002B002C002D002E002F
+0030003100320033003400350036003700380039003A003B003C003D003E003F
+0040004100420043004400450046004700480049004A004B004C004D004E004F
+0050005100520053005400550056005700580059005A005B005C005D005E005F
+0060006100620063006400650066006700680069006A006B006C006D006E006F
+0070007100720073007400750076007700780079007A007B007C007D007E007F
+0080000000000000000000850086000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000FF61FF62FF63FF64FF65FF66FF67FF68FF69FF6AFF6BFF6CFF6DFF6EFF6F
+FF70FF71FF72FF73FF74FF75FF76FF77FF78FF79FF7AFF7BFF7CFF7DFF7EFF7F
+FF80FF81FF82FF83FF84FF85FF86FF87FF88FF89FF8AFF8BFF8CFF8DFF8EFF8F
+FF90FF91FF92FF93FF94FF95FF96FF97FF98FF99FF9AFF9BFF9CFF9DFF9EFF9F
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+81
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+300030013002FF0CFF0E30FBFF1AFF1BFF1FFF01309B309C00B4FF4000A8FF3E
+FFE3FF3F30FD30FE309D309E30034EDD30053006300730FC20152010FF0FFF3C
+FF5E2225FF5C2026202520182019201C201DFF08FF0930143015FF3BFF3DFF5B
+FF5D30083009300A300B300C300D300E300F30103011FF0BFF0D00B100D70000
+00F7FF1D2260FF1CFF1E22662267221E22342642264000B0203220332103FFE5
+FF04FFE0FFE1FF05FF03FF06FF0AFF2000A72606260525CB25CF25CE25C725C6
+25A125A025B325B225BD25BC203B301221922190219121933013000000000000
+000000000000000000000000000000002208220B2286228722822283222A2229
+0000000000000000000000000000000022272228FFE221D221D4220022030000
+0000000000000000000000000000000000000000222022A52312220222072261
+2252226A226B221A223D221D2235222B222C0000000000000000000000000000
+212B2030266F266D266A2020202100B6000000000000000025EF000000000000
+82
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000FF10
+FF11FF12FF13FF14FF15FF16FF17FF18FF190000000000000000000000000000
+FF21FF22FF23FF24FF25FF26FF27FF28FF29FF2AFF2BFF2CFF2DFF2EFF2FFF30
+FF31FF32FF33FF34FF35FF36FF37FF38FF39FF3A000000000000000000000000
+0000FF41FF42FF43FF44FF45FF46FF47FF48FF49FF4AFF4BFF4CFF4DFF4EFF4F
+FF50FF51FF52FF53FF54FF55FF56FF57FF58FF59FF5A00000000000000003041
+30423043304430453046304730483049304A304B304C304D304E304F30503051
+30523053305430553056305730583059305A305B305C305D305E305F30603061
+30623063306430653066306730683069306A306B306C306D306E306F30703071
+30723073307430753076307730783079307A307B307C307D307E307F30803081
+30823083308430853086308730883089308A308B308C308D308E308F30903091
+3092309300000000000000000000000000000000000000000000000000000000
+83
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+30A130A230A330A430A530A630A730A830A930AA30AB30AC30AD30AE30AF30B0
+30B130B230B330B430B530B630B730B830B930BA30BB30BC30BD30BE30BF30C0
+30C130C230C330C430C530C630C730C830C930CA30CB30CC30CD30CE30CF30D0
+30D130D230D330D430D530D630D730D830D930DA30DB30DC30DD30DE30DF0000
+30E030E130E230E330E430E530E630E730E830E930EA30EB30EC30ED30EE30EF
+30F030F130F230F330F430F530F6000000000000000000000000000000000391
+03920393039403950396039703980399039A039B039C039D039E039F03A003A1
+03A303A403A503A603A703A803A90000000000000000000000000000000003B1
+03B203B303B403B503B603B703B803B903BA03BB03BC03BD03BE03BF03C003C1
+03C303C403C503C603C703C803C9000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+84
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+04100411041204130414041504010416041704180419041A041B041C041D041E
+041F0420042104220423042404250426042704280429042A042B042C042D042E
+042F000000000000000000000000000000000000000000000000000000000000
+04300431043204330434043504510436043704380439043A043B043C043D0000
+043E043F0440044104420443044404450446044704480449044A044B044C044D
+044E044F00000000000000000000000000000000000000000000000000002500
+2502250C251025182514251C252C25242534253C25012503250F2513251B2517
+25232533252B253B254B2520252F25282537253F251D25302525253825420000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+87
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+2460246124622463246424652466246724682469246A246B246C246D246E246F
+2470247124722473216021612162216321642165216621672168216900003349
+33143322334D331833273303333633513357330D33263323332B334A333B339C
+339D339E338E338F33C433A100000000000000000000000000000000337B0000
+301D301F211633CD212132A432A532A632A732A8323132323239337E337D337C
+22522261222B222E2211221A22A52220221F22BF22352229222A000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+88
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000004E9C
+55165A03963F54C0611B632859F690228475831C7A5060AA63E16E2565ED8466
+82A69BF56893572765A162715B9B59D0867B98F47D627DBE9B8E62167C9F88B7
+5B895EB563096697684895C7978D674F4EE54F0A4F4D4F9D504956F2593759D4
+5A015C0960DF610F61706613690570BA754F757079FB7DAD7DEF80C3840E8863
+8B029055907A533B4E954EA557DF80B290C178EF4E0058F16EA290387A328328
+828B9C2F5141537054BD54E156E059FB5F1598F26DEB80E4852D000000000000
+89
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+9662967096A097FB540B53F35B8770CF7FBD8FC296E8536F9D5C7ABA4E117893
+81FC6E26561855046B1D851A9C3B59E553A96D6674DC958F56424E91904B96F2
+834F990C53E155B65B305F71662066F368046C386CF36D29745B76C87A4E9834
+82F1885B8A6092ED6DB275AB76CA99C560A68B018D8A95B2698E53AD51860000
+5712583059445BB45EF6602863A963F46CBF6F14708E7114715971D5733F7E01
+827682D185979060925B9D1B586965BC6C5A752551F9592E59655F805FDC62BC
+65FA6A2A6B276BB4738B7FC189569D2C9D0E9EC45CA16C96837B51045C4B61B6
+81C6687672614E594FFA537860696E297A4F97F34E0B53164EEE4F554F3D4FA1
+4F7352A053EF5609590F5AC15BB65BE179D16687679C67B66B4C6CB3706B73C2
+798D79BE7A3C7B8782B182DB8304837783EF83D387668AB256298CA88FE6904E
+971E868A4FC45CE862117259753B81E582BD86FE8CC096C5991399D54ECB4F1A
+89E356DE584A58CA5EFB5FEB602A6094606261D0621262D06539000000000000
+8A
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+9B41666668B06D777070754C76867D7582A587F9958B968E8C9D51F152BE5916
+54B35BB35D16616869826DAF788D84CB88578A7293A79AB86D6C99A886D957A3
+67FF86CE920E5283568754045ED362E164B9683C68386BBB737278BA7A6B899A
+89D28D6B8F0390ED95A3969497695B665CB3697D984D984E639B7B206A2B0000
+6A7F68B69C0D6F5F5272559D607062EC6D3B6E076ED1845B89108F444E149C39
+53F6691B6A3A9784682A515C7AC384B291DC938C565B9D286822830584317CA5
+520882C574E64E7E4F8351A05BD2520A52D852E75DFB559A582A59E65B8C5B98
+5BDB5E725E7960A3611F616361BE63DB656267D1685368FA6B3E6B536C576F22
+6F976F4574B0751876E3770B7AFF7BA17C217DE97F367FF0809D8266839E89B3
+8ACC8CAB908494519593959195A2966597D3992882184E38542B5CB85DCC73A9
+764C773C5CA97FEB8D0B96C19811985498584F014F0E5371559C566857FA5947
+5B095BC45C905E0C5E7E5FCC63EE673A65D765E2671F68CB68C4000000000000
+8B
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+6A5F5E306BC56C176C7D757F79485B637A007D005FBD898F8A188CB48D778ECC
+8F1D98E29A0E9B3C4E80507D510059935B9C622F628064EC6B3A72A075917947
+7FA987FB8ABC8B7063AC83CA97A05409540355AB68546A588A70782767759ECD
+53745BA2811A865090064E184E454EC74F1153CA54385BAE5F13602565510000
+673D6C426C726CE3707874037A767AAE7B087D1A7CFE7D6665E7725B53BB5C45
+5DE862D262E063196E20865A8A318DDD92F86F0179A69B5A4EA84EAB4EAC4F9B
+4FA050D151477AF6517151F653545321537F53EB55AC58835CE15F375F4A602F
+6050606D631F65596A4B6CC172C272ED77EF80F881058208854E90F793E197FF
+99579A5A4EF051DD5C2D6681696D5C4066F26975738968507C8150C552E45747
+5DFE932665A46B236B3D7434798179BD7B4B7DCA82B983CC887F895F8B398FD1
+91D1541F92804E5D503653E5533A72D7739677E982E68EAF99C699C899D25177
+611A865E55B07A7A50765BD3904796854E326ADB91E75C515C48000000000000
+8C
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+63987A9F6C9397748F617AAA718A96887C8268177E706851936C52F2541B85AB
+8A137FA48ECD90E15366888879414FC250BE521151445553572D73EA578B5951
+5F625F8460756176616761A963B2643A656C666F68426E1375667A3D7CFB7D4C
+7D997E4B7F6B830E834A86CD8A088A638B668EFD981A9D8F82B88FCE9BE80000
+5287621F64836FC09699684150916B206C7A6F547A747D5088408A2367084EF6
+503950265065517C5238526355A7570F58055ACC5EFA61B261F862F36372691C
+6A29727D72AC732E7814786F7D79770C80A9898B8B198CE28ED290639375967A
+98559A139E785143539F53B35E7B5F266E1B6E90738473FE7D4382378A008AFA
+96504E4E500B53E4547C56FA59D15B645DF15EAB5F276238654567AF6E5672D0
+7CCA88B480A180E183F0864E8A878DE8923796C798679F134E944E924F0D5348
+5449543E5A2F5F8C5FA1609F68A76A8E745A78818A9E8AA48B7791904E5E9BC9
+4EA44F7C4FAF501950165149516C529F52B952FE539A53E35411000000000000
+8D
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+540E5589575157A2597D5B545B5D5B8F5DE55DE75DF75E785E835E9A5EB75F18
+6052614C629762D863A7653B6602664366F4676D6821689769CB6C5F6D2A6D69
+6E2F6E9D75327687786C7A3F7CE07D057D187D5E7DB18015800380AF80B18154
+818F822A8352884C88618B1B8CA28CFC90CA91759271783F92FC95A4964D0000
+980599999AD89D3B525B52AB53F7540858D562F76FE08C6A8F5F9EB9514B523B
+544A56FD7A4091779D609ED273446F09817075115FFD60DA9AA872DB8FBC6B64
+98034ECA56F0576458BE5A5A606861C7660F6606683968B16DF775D57D3A826E
+9B424E9B4F5053C955065D6F5DE65DEE67FB6C99747378028A50939688DF5750
+5EA7632B50B550AC518D670054C9585E59BB5BB05F69624D63A1683D6B736E08
+707D91C7728078157826796D658E7D3083DC88C18F09969B5264572867507F6A
+8CA151B45742962A583A698A80B454B25D0E57FC78959DFA4F5C524A548B643E
+6628671467F57A847B567D22932F685C9BAD7B395319518A5237000000000000
+8E
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+5BDF62F664AE64E6672D6BBA85A996D176909BD6634C93069BAB76BF66524E09
+509853C25C7160E864926563685F71E673CA75237B977E8286958B838CDB9178
+991065AC66AB6B8B4ED54ED44F3A4F7F523A53F853F255E356DB58EB59CB59C9
+59FF5B505C4D5E025E2B5FD7601D6307652F5B5C65AF65BD65E8679D6B620000
+6B7B6C0F7345794979C17CF87D197D2B80A2810281F389968A5E8A698A668A8C
+8AEE8CC78CDC96CC98FC6B6F4E8B4F3C4F8D51505B575BFA6148630166426B21
+6ECB6CBB723E74BD75D478C1793A800C803381EA84948F9E6C509E7F5F0F8B58
+9D2B7AFA8EF85B8D96EB4E0353F157F759315AC95BA460896E7F6F0675BE8CEA
+5B9F85007BE0507267F4829D5C61854A7E1E820E51995C0463688D66659C716E
+793E7D1780058B1D8ECA906E86C790AA501F52FA5C3A6753707C7235914C91C8
+932B82E55BC25F3160F94E3B53D65B88624B67316B8A72E973E07A2E816B8DA3
+91529996511253D7546A5BFF63886A397DAC970056DA53CE5468000000000000
+8F
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+5B975C315DDE4FEE610162FE6D3279C079CB7D427E4D7FD281ED821F84908846
+89728B908E748F2F9031914B916C96C6919C4EC04F4F514553415F93620E67D4
+6C416E0B73637E2691CD928353D459195BBF6DD1795D7E2E7C9B587E719F51FA
+88538FF04FCA5CFB662577AC7AE3821C99FF51C65FAA65EC696F6B896DF30000
+6E966F6476FE7D145DE190759187980651E6521D6240669166D96E1A5EB67DD2
+7F7266F885AF85F78AF852A953D959735E8F5F90605592E4966450B7511F52DD
+5320534753EC54E8554655315617596859BE5A3C5BB55C065C0F5C115C1A5E84
+5E8A5EE05F70627F628462DB638C63776607660C662D6676677E68A26A1F6A35
+6CBC6D886E096E58713C7126716775C77701785D7901796579F07AE07B117CA7
+7D39809683D6848B8549885D88F38A1F8A3C8A548A738C618CDE91A49266937E
+9418969C97984E0A4E084E1E4E575197527057CE583458CC5B225E3860C564FE
+676167566D4472B675737A6384B88B7291B89320563157F498FE000000000000
+90
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+62ED690D6B9671ED7E548077827289E698DF87558FB15C3B4F384FE14FB55507
+5A205BDD5BE95FC3614E632F65B0664B68EE699B6D786DF1753375B9771F795E
+79E67D3381E382AF85AA89AA8A3A8EAB8F9B903291DD97074EBA4EC152035875
+58EC5C0B751A5C3D814E8A0A8FC59663976D7B258ACF9808916256F353A80000
+9017543957825E2563A86C34708A77617C8B7FE088709042915493109318968F
+745E9AC45D075D69657067A28DA896DB636E6749691983C5981796C088FE6F84
+647A5BF84E16702C755D662F51C4523652E259D35F8160276210653F6574661F
+667468F268166B636E057272751F76DB7CBE805658F088FD897F8AA08A938ACB
+901D91929752975965897A0E810696BB5E2D60DC621A65A56614679077F37A4D
+7C4D7E3E810A8CAC8D648DE18E5F78A9520762D963A5644262988A2D7A837BC0
+8AAC96EA7D76820C87494ED95148534353605BA35C025C165DDD6226624764B0
+681368346CC96D456D1767D36F5C714E717D65CB7A7F7BAD7DDA000000000000
+91
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+7E4A7FA8817A821B823985A68A6E8CCE8DF59078907792AD929195839BAE524D
+55846F387136516879857E5581B37CCE564C58515CA863AA66FE66FD695A72D9
+758F758E790E795679DF7C977D207D4486078A34963B90619F2050E7527553CC
+53E2500955AA58EE594F723D5B8B5C64531D60E360F3635C6383633F63BB0000
+64CD65E966F95DE369CD69FD6F1571E54E8975E976F87A937CDF7DCF7D9C8061
+83498358846C84BC85FB88C58D709001906D9397971C9A1250CF5897618E81D3
+85358D0890204FC3507452475373606F6349675F6E2C8DB3901F4FD75C5E8CCA
+65CF7D9A53528896517663C35B585B6B5C0A640D6751905C4ED6591A592A6C70
+8A51553E581559A560F0625367C182356955964099C49A284F5358065BFE8010
+5CB15E2F5F856020614B623466FF6CF06EDE80CE817F82D4888B8CB89000902E
+968A9EDB9BDB4EE353F059277B2C918D984C9DF96EDD7027535355445B856258
+629E62D36CA26FEF74228A1794386FC18AFE833851E786F853EA000000000000
+92
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+53E94F4690548FB0596A81315DFD7AEA8FBF68DA8C3772F89C486A3D8AB04E39
+53585606576662C563A265E66B4E6DE16E5B70AD77ED7AEF7BAA7DBB803D80C6
+86CB8A95935B56E358C75F3E65AD66966A806BB575378AC7502477E557305F1B
+6065667A6C6075F47A1A7F6E81F48718904599B37BC9755C7AF97B5184C40000
+901079E97A9283365AE177404E2D4EF25B995FE062BD663C67F16CE8866B8877
+8A3B914E92F399D06A177026732A82E784578CAF4E01514651CB558B5BF55E16
+5E335E815F145F355F6B5FB461F2631166A2671D6F6E7252753A773A80748139
+817887768ABF8ADC8D858DF3929A957798029CE552C5635776F467156C8873CD
+8CC393AE96736D25589C690E69CC8FFD939A75DB901A585A680263B469FB4F43
+6F2C67D88FBB85267DB49354693F6F70576A58F75B2C7D2C722A540A91E39DB4
+4EAD4F4E505C507552438C9E544858245B9A5E1D5E955EAD5EF75F1F608C62B5
+633A63D068AF6C407887798E7A0B7DE082478A028AE68E449013000000000000
+93
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+90B8912D91D89F0E6CE5645864E265756EF476847B1B906993D16EBA54F25FB9
+64A48F4D8FED92445178586B59295C555E976DFB7E8F751C8CBC8EE2985B70B9
+4F1D6BBF6FB1753096FB514E54105835585759AC5C605F926597675C6E21767B
+83DF8CED901490FD934D7825783A52AA5EA6571F597460125012515A51AC0000
+51CD520055105854585859575B955CF65D8B60BC6295642D6771684368BC68DF
+76D76DD86E6F6D9B706F71C85F5375D879777B497B547B527CD67D7152308463
+856985E48A0E8B048C468E0F9003900F94199676982D9A3095D850CD52D5540C
+58025C0E61A7649E6D1E77B37AE580F48404905392855CE09D07533F5F975FB3
+6D9C7279776379BF7BE46BD272EC8AAD68036A6151F87A8169345C4A9CF682EB
+5BC59149701E56785C6F60C765666C8C8C5A90419813545166C7920D594890A3
+51854E4D51EA85998B0E7058637A934B696299B47E047577535769608EDF96E3
+6C5D4E8C5C3C5F108FE953028CD1808986795EFF65E54E735165000000000000
+94
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+59825C3F97EE4EFB598A5FCD8A8D6FE179B079625BE78471732B71B15E745FF5
+637B649A71C37C984E435EFC4E4B57DC56A260A96FC37D0D80FD813381BF8FB2
+899786A45DF4628A64AD898767776CE26D3E743678345A467F7582AD99AC4FF3
+5EC362DD63926557676F76C3724C80CC80BA8F29914D500D57F95A9268850000
+6973716472FD8CB758F28CE0966A9019877F79E477E784294F2F5265535A62CD
+67CF6CCA767D7B947C95823685848FEB66DD6F2072067E1B83AB99C19EA651FD
+7BB178727BB880877B486AE85E61808C75517560516B92626E8C767A91979AEA
+4F107F70629C7B4F95A59CE9567A585986E496BC4F345224534A53CD53DB5E06
+642C6591677F6C3E6C4E724872AF73ED75547E41822C85E98CA97BC491C67169
+981298EF633D6669756A76E478D0854386EE532A5351542659835E875F7C60B2
+6249627962AB65906BD46CCC75B276AE789179D87DCB7F7780A588AB8AB98CBB
+907F975E98DB6A0B7C3850995C3E5FAE67876BD8743577097F8E000000000000
+95
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+9F3B67CA7A175339758B9AED5F66819D83F180985F3C5FC575627B46903C6867
+59EB5A9B7D10767E8B2C4FF55F6A6A196C376F0274E2796888688A558C795EDF
+63CF75C579D282D7932892F2849C86ED9C2D54C15F6C658C6D5C70158CA78CD3
+983B654F74F64E0D4ED857E0592B5A665BCC51A85E035E9C6016627665770000
+65A7666E6D6E72367B268150819A82998B5C8CA08CE68D74961C96444FAE64AB
+6B66821E8461856A90E85C01695398A8847A85574F0F526F5FA95E45670D798F
+8179890789866DF55F1762556CB84ECF72699B925206543B567458B361A4626E
+711A596E7C897CDE7D1B96F06587805E4E194F75517558405E635E735F0A67C4
+4E26853D9589965B7C73980150FB58C1765678A7522577A585117B86504F5909
+72477BC77DE88FBA8FD4904D4FBF52C95A295F0197AD4FDD821792EA57036355
+6B69752B88DC8F147A4252DF58936155620A66AE6BCD7C3F83E950234FF85305
+5446583159495B9D5CF05CEF5D295E9662B16367653E65B9670B000000000000
+96
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+6CD56CE170F978327E2B80DE82B3840C84EC870289128A2A8C4A90A692D298FD
+9CF39D6C4E4F4EA1508D5256574A59A85E3D5FD85FD9623F66B4671B67D068D2
+51927D2180AA81A88B008C8C8CBF927E96325420982C531750D5535C58A864B2
+6734726777667A4691E652C36CA16B8658005E4C5954672C7FFB51E176C60000
+646978E89B549EBB57CB59B96627679A6BCE54E969D95E55819C67959BAA67FE
+9C52685D4EA64FE353C862B9672B6CAB8FC44FAD7E6D9EBF4E0761626E806F2B
+85135473672A9B455DF37B955CAC5BC6871C6E4A84D17A14810859997C8D6C11
+772052D959227121725F77DB97279D61690B5A7F5A1851A5540D547D660E76DF
+8FF792989CF459EA725D6EC5514D68C97DBF7DEC97629EBA64786A2183025984
+5B5F6BDB731B76F27DB280178499513267289ED976EE676252FF99055C24623B
+7C7E8CB0554F60B67D0B958053014E5F51B6591C723A803691CE5F2577E25384
+5F797D0485AC8A338E8D975667F385AE9453610961086CB97652000000000000
+97
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+8AED8F38552F4F51512A52C753CB5BA55E7D60A0618263D6670967DA6E676D8C
+733673377531795088D58A98904A909190F596C4878D59154E884F594E0E8A89
+8F3F981050AD5E7C59965BB95EB863DA63FA64C166DC694A69D86D0B6EB67194
+75287AAF7F8A8000844984C989818B218E0A9065967D990A617E62916B320000
+6C836D747FCC7FFC6DC07F8587BA88F8676583B1983C96F76D1B7D61843D916A
+4E7153755D506B046FEB85CD862D89A75229540F5C65674E68A87406748375E2
+88CF88E191CC96E296785F8B73877ACB844E63A0756552896D416E9C74097559
+786B7C9296867ADC9F8D4FB6616E65C5865C4E864EAE50DA4E2151CC5BEE6599
+68816DBC731F764277AD7A1C7CE7826F8AD2907C91CF96759818529B7DD1502B
+539867976DCB71D0743381E88F2A96A39C579E9F746058416D997D2F985E4EE4
+4F364F8B51B752B15DBA601C73B2793C82D3923496B796F6970A9E979F6266A6
+6B74521752A370C888C25EC9604B61906F2371497C3E7DF4806F000000000000
+98
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+84EE9023932C54429B6F6AD370898CC28DEF973252B45A415ECA5F046717697C
+69946D6A6F0F726272FC7BED8001807E874B90CE516D9E937984808B93328AD6
+502D548C8A716B6A8CC4810760D167A09DF24E994E989C108A6B85C185686900
+6E7E789781550000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000005F0C
+4E104E154E2A4E314E364E3C4E3F4E424E564E584E824E858C6B4E8A82125F0D
+4E8E4E9E4E9F4EA04EA24EB04EB34EB64ECE4ECD4EC44EC64EC24ED74EDE4EED
+4EDF4EF74F094F5A4F304F5B4F5D4F574F474F764F884F8F4F984F7B4F694F70
+4F914F6F4F864F9651184FD44FDF4FCE4FD84FDB4FD14FDA4FD04FE44FE5501A
+50285014502A502550054F1C4FF650215029502C4FFE4FEF5011500650435047
+6703505550505048505A5056506C50785080509A508550B450B2000000000000
+99
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+50C950CA50B350C250D650DE50E550ED50E350EE50F950F55109510151025116
+51155114511A5121513A5137513C513B513F51405152514C515451627AF85169
+516A516E5180518256D8518C5189518F519151935195519651A451A651A251A9
+51AA51AB51B351B151B251B051B551BD51C551C951DB51E0865551E951ED0000
+51F051F551FE5204520B5214520E5227522A522E52335239524F5244524B524C
+525E5254526A527452695273527F527D528D529452925271528852918FA88FA7
+52AC52AD52BC52B552C152CD52D752DE52E352E698ED52E052F352F552F852F9
+530653087538530D5310530F5315531A5323532F533153335338534053465345
+4E175349534D51D6535E5369536E5918537B53775382539653A053A653A553AE
+53B053B653C37C1296D953DF66FC71EE53EE53E853ED53FA5401543D5440542C
+542D543C542E54365429541D544E548F5475548E545F5471547754705492547B
+5480547654845490548654C754A254B854A554AC54C454C854A8000000000000
+9A
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+54AB54C254A454BE54BC54D854E554E6550F551454FD54EE54ED54FA54E25539
+55405563554C552E555C55455556555755385533555D5599558054AF558A559F
+557B557E5598559E55AE557C558355A9558755A855DA55C555DF55C455DC55E4
+55D4561455F7561655FE55FD561B55F9564E565071DF56345636563256380000
+566B5664562F566C566A56865680568A56A05694568F56A556AE56B656B456C2
+56BC56C156C356C056C856CE56D156D356D756EE56F9570056FF570457095708
+570B570D57135718571655C7571C572657375738574E573B5740574F576957C0
+57885761577F5789579357A057B357A457AA57B057C357C657D457D257D3580A
+57D657E3580B5819581D587258215862584B58706BC05852583D5879588558B9
+589F58AB58BA58DE58BB58B858AE58C558D358D158D758D958D858E558DC58E4
+58DF58EF58FA58F958FB58FC58FD5902590A5910591B68A65925592C592D5932
+5938593E7AD259555950594E595A5958596259605967596C5969000000000000
+9B
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+59785981599D4F5E4FAB59A359B259C659E859DC598D59D959DA5A255A1F5A11
+5A1C5A095A1A5A405A6C5A495A355A365A625A6A5A9A5ABC5ABE5ACB5AC25ABD
+5AE35AD75AE65AE95AD65AFA5AFB5B0C5B0B5B165B325AD05B2A5B365B3E5B43
+5B455B405B515B555B5A5B5B5B655B695B705B735B755B7865885B7A5B800000
+5B835BA65BB85BC35BC75BC95BD45BD05BE45BE65BE25BDE5BE55BEB5BF05BF6
+5BF35C055C075C085C0D5C135C205C225C285C385C395C415C465C4E5C535C50
+5C4F5B715C6C5C6E4E625C765C795C8C5C915C94599B5CAB5CBB5CB65CBC5CB7
+5CC55CBE5CC75CD95CE95CFD5CFA5CED5D8C5CEA5D0B5D155D175D5C5D1F5D1B
+5D115D145D225D1A5D195D185D4C5D525D4E5D4B5D6C5D735D765D875D845D82
+5DA25D9D5DAC5DAE5DBD5D905DB75DBC5DC95DCD5DD35DD25DD65DDB5DEB5DF2
+5DF55E0B5E1A5E195E115E1B5E365E375E445E435E405E4E5E575E545E5F5E62
+5E645E475E755E765E7A9EBC5E7F5EA05EC15EC25EC85ED05ECF000000000000
+9C
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+5ED65EE35EDD5EDA5EDB5EE25EE15EE85EE95EEC5EF15EF35EF05EF45EF85EFE
+5F035F095F5D5F5C5F0B5F115F165F295F2D5F385F415F485F4C5F4E5F2F5F51
+5F565F575F595F615F6D5F735F775F835F825F7F5F8A5F885F915F875F9E5F99
+5F985FA05FA85FAD5FBC5FD65FFB5FE45FF85FF15FDD60B35FFF602160600000
+601960106029600E6031601B6015602B6026600F603A605A6041606A6077605F
+604A6046604D6063604360646042606C606B60596081608D60E76083609A6084
+609B60966097609260A7608B60E160B860E060D360B45FF060BD60C660B560D8
+614D6115610660F660F7610060F460FA6103612160FB60F1610D610E6147613E
+61286127614A613F613C612C6134613D614261446173617761586159615A616B
+6174616F61656171615F615D6153617561996196618761AC6194619A618A6191
+61AB61AE61CC61CA61C961F761C861C361C661BA61CB7F7961CD61E661E361F6
+61FA61F461FF61FD61FC61FE620062086209620D620C6214621B000000000000
+9D
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+621E6221622A622E6230623262336241624E625E6263625B62606268627C6282
+6289627E62926293629662D46283629462D762D162BB62CF62FF62C664D462C8
+62DC62CC62CA62C262C7629B62C9630C62EE62F163276302630862EF62F56350
+633E634D641C634F6396638E638063AB637663A3638F6389639F63B5636B0000
+636963BE63E963C063C663E363C963D263F663C4641664346406641364266436
+651D64176428640F6467646F6476644E652A6495649364A564A9648864BC64DA
+64D264C564C764BB64D864C264F164E7820964E064E162AC64E364EF652C64F6
+64F464F264FA650064FD6518651C650565246523652B65346535653765366538
+754B654865566555654D6558655E655D65726578658265838B8A659B659F65AB
+65B765C365C665C165C465CC65D265DB65D965E065E165F16772660A660365FB
+6773663566366634661C664F664466496641665E665D666466676668665F6662
+667066836688668E668966846698669D66C166B966C966BE66BC000000000000
+9E
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+66C466B866D666DA66E0663F66E666E966F066F566F7670F6716671E67266727
+9738672E673F67366741673867376746675E67606759676367646789677067A9
+677C676A678C678B67A667A1678567B767EF67B467EC67B367E967B867E467DE
+67DD67E267EE67B967CE67C667E76A9C681E684668296840684D6832684E0000
+68B3682B685968636877687F689F688F68AD6894689D689B68836AAE68B96874
+68B568A068BA690F688D687E690168CA690868D86922692668E1690C68CD68D4
+68E768D569366912690468D768E3692568F968E068EF6928692A691A69236921
+68C669796977695C6978696B6954697E696E69396974693D695969306961695E
+695D6981696A69B269AE69D069BF69C169D369BE69CE5BE869CA69DD69BB69C3
+69A76A2E699169A0699C699569B469DE69E86A026A1B69FF6B0A69F969F269E7
+6A0569B16A1E69ED6A1469EB6A0A6A126AC16A236A136A446A0C6A726A366A78
+6A476A626A596A666A486A386A226A906A8D6AA06A846AA26AA3000000000000
+9F
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+6A9786176ABB6AC36AC26AB86AB36AAC6ADE6AD16ADF6AAA6ADA6AEA6AFB6B05
+86166AFA6B126B169B316B1F6B386B3776DC6B3998EE6B476B436B496B506B59
+6B546B5B6B5F6B616B786B796B7F6B806B846B836B8D6B986B956B9E6BA46BAA
+6BAB6BAF6BB26BB16BB36BB76BBC6BC66BCB6BD36BDF6BEC6BEB6BF36BEF0000
+9EBE6C086C136C146C1B6C246C236C5E6C556C626C6A6C826C8D6C9A6C816C9B
+6C7E6C686C736C926C906CC46CF16CD36CBD6CD76CC56CDD6CAE6CB16CBE6CBA
+6CDB6CEF6CD96CEA6D1F884D6D366D2B6D3D6D386D196D356D336D126D0C6D63
+6D936D646D5A6D796D596D8E6D956FE46D856DF96E156E0A6DB56DC76DE66DB8
+6DC66DEC6DDE6DCC6DE86DD26DC56DFA6DD96DE46DD56DEA6DEE6E2D6E6E6E2E
+6E196E726E5F6E3E6E236E6B6E2B6E766E4D6E1F6E436E3A6E4E6E246EFF6E1D
+6E386E826EAA6E986EC96EB76ED36EBD6EAF6EC46EB26ED46ED56E8F6EA56EC2
+6E9F6F416F11704C6EEC6EF86EFE6F3F6EF26F316EEF6F326ECC000000000000
+E0
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+6F3E6F136EF76F866F7A6F786F816F806F6F6F5B6FF36F6D6F826F7C6F586F8E
+6F916FC26F666FB36FA36FA16FA46FB96FC66FAA6FDF6FD56FEC6FD46FD86FF1
+6FEE6FDB7009700B6FFA70117001700F6FFE701B701A6F74701D7018701F7030
+703E7032705170637099709270AF70F170AC70B870B370AE70DF70CB70DD0000
+70D9710970FD711C711971657155718871667162714C7156716C718F71FB7184
+719571A871AC71D771B971BE71D271C971D471CE71E071EC71E771F571FC71F9
+71FF720D7210721B7228722D722C72307232723B723C723F72407246724B7258
+7274727E7282728172877292729672A272A772B972B272C372C672C472CE72D2
+72E272E072E172F972F7500F7317730A731C7316731D7334732F73297325733E
+734E734F9ED87357736A7368737073787375737B737A73C873B373CE73BB73C0
+73E573EE73DE74A27405746F742573F87432743A7455743F745F74597441745C
+746974707463746A7476747E748B749E74A774CA74CF74D473F1000000000000
+E1
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+74E074E374E774E974EE74F274F074F174F874F7750475037505750C750E750D
+75157513751E7526752C753C7544754D754A7549755B7546755A756975647567
+756B756D75787576758675877574758A758975827594759A759D75A575A375C2
+75B375C375B575BD75B875BC75B175CD75CA75D275D975E375DE75FE75FF0000
+75FC760175F075FA75F275F3760B760D7609761F762776207621762276247634
+7630763B764776487646765C76587661766276687669766A7667766C76707672
+76767678767C768076837688768B768E769676937699769A76B076B476B876B9
+76BA76C276CD76D676D276DE76E176E576E776EA862F76FB7708770777047729
+7724771E77257726771B773777387747775A7768776B775B7765777F777E7779
+778E778B779177A0779E77B077B677B977BF77BC77BD77BB77C777CD77D777DA
+77DC77E377EE77FC780C781279267820792A7845788E78747886787C789A788C
+78A378B578AA78AF78D178C678CB78D478BE78BC78C578CA78EC000000000000
+E2
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+78E778DA78FD78F47907791279117919792C792B794079607957795F795A7955
+7953797A797F798A799D79A79F4B79AA79AE79B379B979BA79C979D579E779EC
+79E179E37A087A0D7A187A197A207A1F79807A317A3B7A3E7A377A437A577A49
+7A617A627A699F9D7A707A797A7D7A887A977A957A987A967AA97AC87AB00000
+7AB67AC57AC47ABF90837AC77ACA7ACD7ACF7AD57AD37AD97ADA7ADD7AE17AE2
+7AE67AED7AF07B027B0F7B0A7B067B337B187B197B1E7B357B287B367B507B7A
+7B047B4D7B0B7B4C7B457B757B657B747B677B707B717B6C7B6E7B9D7B987B9F
+7B8D7B9C7B9A7B8B7B927B8F7B5D7B997BCB7BC17BCC7BCF7BB47BC67BDD7BE9
+7C117C147BE67BE57C607C007C077C137BF37BF77C177C0D7BF67C237C277C2A
+7C1F7C377C2B7C3D7C4C7C437C547C4F7C407C507C587C5F7C647C567C657C6C
+7C757C837C907CA47CAD7CA27CAB7CA17CA87CB37CB27CB17CAE7CB97CBD7CC0
+7CC57CC27CD87CD27CDC7CE29B3B7CEF7CF27CF47CF67CFA7D06000000000000
+E3
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+7D027D1C7D157D0A7D457D4B7D2E7D327D3F7D357D467D737D567D4E7D727D68
+7D6E7D4F7D637D937D897D5B7D8F7D7D7D9B7DBA7DAE7DA37DB57DC77DBD7DAB
+7E3D7DA27DAF7DDC7DB87D9F7DB07DD87DDD7DE47DDE7DFB7DF27DE17E057E0A
+7E237E217E127E317E1F7E097E0B7E227E467E667E3B7E357E397E437E370000
+7E327E3A7E677E5D7E567E5E7E597E5A7E797E6A7E697E7C7E7B7E837DD57E7D
+8FAE7E7F7E887E897E8C7E927E907E937E947E967E8E7E9B7E9C7F387F3A7F45
+7F4C7F4D7F4E7F507F517F557F547F587F5F7F607F687F697F677F787F827F86
+7F837F887F877F8C7F947F9E7F9D7F9A7FA37FAF7FB27FB97FAE7FB67FB88B71
+7FC57FC67FCA7FD57FD47FE17FE67FE97FF37FF998DC80068004800B80128018
+8019801C80218028803F803B804A804680528058805A805F8062806880738072
+807080768079807D807F808480868085809B8093809A80AD519080AC80DB80E5
+80D980DD80C480DA80D6810980EF80F1811B81298123812F814B000000000000
+E4
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+968B8146813E8153815180FC8171816E81658166817481838188818A81808182
+81A0819581A481A3815F819381A981B081B581BE81B881BD81C081C281BA81C9
+81CD81D181D981D881C881DA81DF81E081E781FA81FB81FE8201820282058207
+820A820D821082168229822B82388233824082598258825D825A825F82640000
+82628268826A826B822E827182778278827E828D829282AB829F82BB82AC82E1
+82E382DF82D282F482F382FA8393830382FB82F982DE830682DC830982D98335
+83348316833283318340833983508345832F832B831783188385839A83AA839F
+83A283968323838E8387838A837C83B58373837583A0838983A883F4841383EB
+83CE83FD840383D8840B83C183F7840783E083F2840D8422842083BD84388506
+83FB846D842A843C855A84848477846B84AD846E848284698446842C846F8479
+843584CA846284B984BF849F84D984CD84BB84DA84D084C184C684D684A18521
+84FF84F485178518852C851F8515851484FC8540856385588548000000000000
+E5
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+85418602854B8555858085A485888591858A85A8856D8594859B85EA8587859C
+8577857E859085C985BA85CF85B985D085D585DD85E585DC85F9860A8613860B
+85FE85FA86068622861A8630863F864D4E558654865F86678671869386A386A9
+86AA868B868C86B686AF86C486C686B086C9882386AB86D486DE86E986EC0000
+86DF86DB86EF8712870687088700870386FB87118709870D86F9870A8734873F
+8737873B87258729871A8760875F8778874C874E877487578768876E87598753
+8763876A880587A2879F878287AF87CB87BD87C087D096D687AB87C487B387C7
+87C687BB87EF87F287E0880F880D87FE87F687F7880E87D28811881688158822
+88218831883688398827883B8844884288528859885E8862886B8881887E889E
+8875887D88B5887288828897889288AE889988A2888D88A488B088BF88B188C3
+88C488D488D888D988DD88F9890288FC88F488E888F28904890C890A89138943
+891E8925892A892B89418944893B89368938894C891D8960895E000000000000
+E6
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+89668964896D896A896F89748977897E89838988898A8993899889A189A989A6
+89AC89AF89B289BA89BD89BF89C089DA89DC89DD89E789F489F88A038A168A10
+8A0C8A1B8A1D8A258A368A418A5B8A528A468A488A7C8A6D8A6C8A628A858A82
+8A848AA88AA18A918AA58AA68A9A8AA38AC48ACD8AC28ADA8AEB8AF38AE70000
+8AE48AF18B148AE08AE28AF78ADE8ADB8B0C8B078B1A8AE18B168B108B178B20
+8B3397AB8B268B2B8B3E8B288B418B4C8B4F8B4E8B498B568B5B8B5A8B6B8B5F
+8B6C8B6F8B748B7D8B808B8C8B8E8B928B938B968B998B9A8C3A8C418C3F8C48
+8C4C8C4E8C508C558C628C6C8C788C7A8C828C898C858C8A8C8D8C8E8C948C7C
+8C98621D8CAD8CAA8CBD8CB28CB38CAE8CB68CC88CC18CE48CE38CDA8CFD8CFA
+8CFB8D048D058D0A8D078D0F8D0D8D109F4E8D138CCD8D148D168D678D6D8D71
+8D738D818D998DC28DBE8DBA8DCF8DDA8DD68DCC8DDB8DCB8DEA8DEB8DDF8DE3
+8DFC8E088E098DFF8E1D8E1E8E108E1F8E428E358E308E348E4A000000000000
+E7
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+8E478E498E4C8E508E488E598E648E608E2A8E638E558E768E728E7C8E818E87
+8E858E848E8B8E8A8E938E918E948E998EAA8EA18EAC8EB08EC68EB18EBE8EC5
+8EC88ECB8EDB8EE38EFC8EFB8EEB8EFE8F0A8F058F158F128F198F138F1C8F1F
+8F1B8F0C8F268F338F3B8F398F458F428F3E8F4C8F498F468F4E8F578F5C0000
+8F628F638F648F9C8F9F8FA38FAD8FAF8FB78FDA8FE58FE28FEA8FEF90878FF4
+90058FF98FFA901190159021900D901E9016900B90279036903590398FF8904F
+905090519052900E9049903E90569058905E9068906F907696A890729082907D
+90819080908A9089908F90A890AF90B190B590E290E4624890DB910291129119
+91329130914A9156915891639165916991739172918B9189918291A291AB91AF
+91AA91B591B491BA91C091C191C991CB91D091D691DF91E191DB91FC91F591F6
+921E91FF9214922C92159211925E925792459249926492489295923F924B9250
+929C92969293929B925A92CF92B992B792E9930F92FA9344932E000000000000
+E8
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+93199322931A9323933A9335933B935C9360937C936E935693B093AC93AD9394
+93B993D693D793E893E593D893C393DD93D093C893E4941A9414941394039407
+94109436942B94359421943A944194529444945B94609462945E946A92299470
+94759477947D945A947C947E9481947F95829587958A95949596959895990000
+95A095A895A795AD95BC95BB95B995BE95CA6FF695C395CD95CC95D595D495D6
+95DC95E195E595E296219628962E962F9642964C964F964B9677965C965E965D
+965F96669672966C968D96989695969796AA96A796B196B296B096B496B696B8
+96B996CE96CB96C996CD894D96DC970D96D596F99704970697089713970E9711
+970F971697199724972A97309739973D973E97449746974897429749975C9760
+97649766976852D2976B977197799785977C9781977A9786978B978F9790979C
+97A897A697A397B397B497C397C697C897CB97DC97ED9F4F97F27ADF97F697F5
+980F980C9838982498219837983D9846984F984B986B986F9870000000000000
+E9
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+98719874987398AA98AF98B198B698C498C398C698E998EB9903990999129914
+99189921991D991E99249920992C992E993D993E9942994999459950994B9951
+9952994C99559997999899A599AD99AE99BC99DF99DB99DD99D899D199ED99EE
+99F199F299FB99F89A019A0F9A0599E29A199A2B9A379A459A429A409A430000
+9A3E9A559A4D9A5B9A579A5F9A629A659A649A699A6B9A6A9AAD9AB09ABC9AC0
+9ACF9AD19AD39AD49ADE9ADF9AE29AE39AE69AEF9AEB9AEE9AF49AF19AF79AFB
+9B069B189B1A9B1F9B229B239B259B279B289B299B2A9B2E9B2F9B329B449B43
+9B4F9B4D9B4E9B519B589B749B939B839B919B969B979B9F9BA09BA89BB49BC0
+9BCA9BB99BC69BCF9BD19BD29BE39BE29BE49BD49BE19C3A9BF29BF19BF09C15
+9C149C099C139C0C9C069C089C129C0A9C049C2E9C1B9C259C249C219C309C47
+9C329C469C3E9C5A9C609C679C769C789CE79CEC9CF09D099D089CEB9D039D06
+9D2A9D269DAF9D239D1F9D449D159D129D419D3F9D3E9D469D48000000000000
+EA
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+9D5D9D5E9D649D519D509D599D729D899D879DAB9D6F9D7A9D9A9DA49DA99DB2
+9DC49DC19DBB9DB89DBA9DC69DCF9DC29DD99DD39DF89DE69DED9DEF9DFD9E1A
+9E1B9E1E9E759E799E7D9E819E889E8B9E8C9E929E959E919E9D9EA59EA99EB8
+9EAA9EAD97619ECC9ECE9ECF9ED09ED49EDC9EDE9EDD9EE09EE59EE89EEF0000
+9EF49EF69EF79EF99EFB9EFC9EFD9F079F0876B79F159F219F2C9F3E9F4A9F52
+9F549F639F5F9F609F619F669F679F6C9F6A9F779F729F769F959F9C9FA0582F
+69C79059746451DC719900000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+ED
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+7E8A891C9348928884DC4FC970BB663168C892F966FB5F454E284EE14EFC4F00
+4F034F394F564F924F8A4F9A4F944FCD504050224FFF501E5046507050425094
+50F450D8514A5164519D51BE51EC5215529C52A652C052DB5300530753245372
+539353B253DDFA0E549C548A54A954FF55865759576557AC57C857C7FA0F0000
+FA10589E58B2590B5953595B595D596359A459BA5B565BC0752F5BD85BEC5C1E
+5CA65CBA5CF55D275D53FA115D425D6D5DB85DB95DD05F215F345F675FB75FDE
+605D6085608A60DE60D5612060F26111613761306198621362A663F56460649D
+64CE654E66006615663B6609662E661E6624666566576659FA126673669966A0
+66B266BF66FA670EF929676667BB685267C06801684468CFFA136968FA146998
+69E26A306A6B6A466A736A7E6AE26AE46BD66C3F6C5C6C866C6F6CDA6D046D87
+6D6F6D966DAC6DCF6DF86DF26DFC6E396E5C6E276E3C6EBF6F886FB56FF57005
+70077028708570AB710F7104715C71467147FA1571C171FE72B1000000000000
+EE
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+72BE7324FA16737773BD73C973D673E373D2740773F57426742A7429742E7462
+7489749F7501756F7682769C769E769B76A6FA17774652AF7821784E7864787A
+7930FA18FA19FA1A7994FA1B799B7AD17AE7FA1C7AEB7B9EFA1D7D487D5C7DB7
+7DA07DD67E527F477FA1FA1E83018362837F83C783F6844884B4855385590000
+856BFA1F85B0FA20FA21880788F58A128A378A798AA78ABE8ADFFA228AF68B53
+8B7F8CF08CF48D128D76FA238ECFFA24FA25906790DEFA269115912791DA91D7
+91DE91ED91EE91E491E592069210920A923A9240923C924E9259925192399267
+92A79277927892E792D792D992D0FA2792D592E092D39325932192FBFA28931E
+92FF931D93029370935793A493C693DE93F89431944594489592F9DCFA29969D
+96AF9733973B9743974D974F9751975598579865FA2AFA2B9927FA2C999E9A4E
+9AD99ADC9B759B729B8F9BB19BBB9C009D709D6BFA2D9E199ED1000000002170
+217121722173217421752176217721782179FFE2FFE4FF07FF02000000000000
+FA
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+2170217121722173217421752176217721782179216021612162216321642165
+2166216721682169FFE2FFE4FF07FF0232312116212122357E8A891C93489288
+84DC4FC970BB663168C892F966FB5F454E284EE14EFC4F004F034F394F564F92
+4F8A4F9A4F944FCD504050224FFF501E504650705042509450F450D8514A0000
+5164519D51BE51EC5215529C52A652C052DB5300530753245372539353B253DD
+FA0E549C548A54A954FF55865759576557AC57C857C7FA0FFA10589E58B2590B
+5953595B595D596359A459BA5B565BC0752F5BD85BEC5C1E5CA65CBA5CF55D27
+5D53FA115D425D6D5DB85DB95DD05F215F345F675FB75FDE605D6085608A60DE
+60D5612060F26111613761306198621362A663F56460649D64CE654E66006615
+663B6609662E661E6624666566576659FA126673669966A066B266BF66FA670E
+F929676667BB685267C06801684468CFFA136968FA14699869E26A306A6B6A46
+6A736A7E6AE26AE46BD66C3F6C5C6C866C6F6CDA6D046D876D6F000000000000
+FB
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+6D966DAC6DCF6DF86DF26DFC6E396E5C6E276E3C6EBF6F886FB56FF570057007
+7028708570AB710F7104715C71467147FA1571C171FE72B172BE7324FA167377
+73BD73C973D673E373D2740773F57426742A7429742E74627489749F7501756F
+7682769C769E769B76A6FA17774652AF7821784E7864787A7930FA18FA190000
+FA1A7994FA1B799B7AD17AE7FA1C7AEB7B9EFA1D7D487D5C7DB77DA07DD67E52
+7F477FA1FA1E83018362837F83C783F6844884B485538559856BFA1F85B0FA20
+FA21880788F58A128A378A798AA78ABE8ADFFA228AF68B538B7F8CF08CF48D12
+8D76FA238ECFFA24FA25906790DEFA269115912791DA91D791DE91ED91EE91E4
+91E592069210920A923A9240923C924E925992519239926792A79277927892E7
+92D792D992D0FA2792D592E092D39325932192FBFA28931E92FF931D93029370
+935793A493C693DE93F89431944594489592F9DCFA29969D96AF9733973B9743
+974D974F9751975598579865FA2AFA2B9927FA2C999E9A4E9AD9000000000000
+FC
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+9ADC9B759B729B8F9BB19BBB9C009D709D6BFA2D9E199ED10000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+R
+8160 301C FF5E
+8161 2016 2225
+817C 2212 FF0D
+8191 00A2 FFE0
+8192 00A3 FFE1
+81CA 00AC FFE2
+81BE 222a
+81BF 2229
+81DA 2220
+81DB 22a5
+81DF 2261
+81E0 2252
+81E3 221a
+81E6 2235
+81E7 222b
diff --git a/library/encoding/cp936.enc b/library/encoding/cp936.enc
new file mode 100644
index 0000000..37bcc80
--- /dev/null
+++ b/library/encoding/cp936.enc
@@ -0,0 +1,2162 @@
+# Encoding file: cp936, multi-byte
+M
+003F 0 127
+00
+0000000100020003000400050006000700080009000A000B000C000D000E000F
+0010001100120013001400150016001700180019001A001B001C001D001E001F
+0020002100220023002400250026002700280029002A002B002C002D002E002F
+0030003100320033003400350036003700380039003A003B003C003D003E003F
+0040004100420043004400450046004700480049004A004B004C004D004E004F
+0050005100520053005400550056005700580059005A005B005C005D005E005F
+0060006100620063006400650066006700680069006A006B006C006D006E006F
+0070007100720073007400750076007700780079007A007B007C007D007E007F
+20AC000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+81
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+4E024E044E054E064E0F4E124E174E1F4E204E214E234E264E294E2E4E2F4E31
+4E334E354E374E3C4E404E414E424E444E464E4A4E514E554E574E5A4E5B4E62
+4E634E644E654E674E684E6A4E6B4E6C4E6D4E6E4E6F4E724E744E754E764E77
+4E784E794E7A4E7B4E7C4E7D4E7F4E804E814E824E834E844E854E874E8A0000
+4E904E964E974E994E9C4E9D4E9E4EA34EAA4EAF4EB04EB14EB44EB64EB74EB8
+4EB94EBC4EBD4EBE4EC84ECC4ECF4ED04ED24EDA4EDB4EDC4EE04EE24EE64EE7
+4EE94EED4EEE4EEF4EF14EF44EF84EF94EFA4EFC4EFE4F004F024F034F044F05
+4F064F074F084F0B4F0C4F124F134F144F154F164F1C4F1D4F214F234F284F29
+4F2C4F2D4F2E4F314F334F354F374F394F3B4F3E4F3F4F404F414F424F444F45
+4F474F484F494F4A4F4B4F4C4F524F544F564F614F624F664F684F6A4F6B4F6D
+4F6E4F714F724F754F774F784F794F7A4F7D4F804F814F824F854F864F874F8A
+4F8C4F8E4F904F924F934F954F964F984F994F9A4F9C4F9E4F9F4FA14FA20000
+82
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+4FA44FAB4FAD4FB04FB14FB24FB34FB44FB64FB74FB84FB94FBA4FBB4FBC4FBD
+4FBE4FC04FC14FC24FC64FC74FC84FC94FCB4FCC4FCD4FD24FD34FD44FD54FD6
+4FD94FDB4FE04FE24FE44FE54FE74FEB4FEC4FF04FF24FF44FF54FF64FF74FF9
+4FFB4FFC4FFD4FFF5000500150025003500450055006500750085009500A0000
+500B500E501050115013501550165017501B501D501E50205022502350245027
+502B502F5030503150325033503450355036503750385039503B503D503F5040
+504150425044504550465049504A504B504D5050505150525053505450565057
+50585059505B505D505E505F506050615062506350645066506750685069506A
+506B506D506E506F50705071507250735074507550785079507A507C507D5081
+508250835084508650875089508A508B508C508E508F50905091509250935094
+50955096509750985099509A509B509C509D509E509F50A050A150A250A450A6
+50AA50AB50AD50AE50AF50B050B150B350B450B550B650B750B850B950BC0000
+83
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+50BD50BE50BF50C050C150C250C350C450C550C650C750C850C950CA50CB50CC
+50CD50CE50D050D150D250D350D450D550D750D850D950DB50DC50DD50DE50DF
+50E050E150E250E350E450E550E850E950EA50EB50EF50F050F150F250F450F6
+50F750F850F950FA50FC50FD50FE50FF51005101510251035104510551080000
+5109510A510C510D510E510F511051115113511451155116511751185119511A
+511B511C511D511E511F512051225123512451255126512751285129512A512B
+512C512D512E512F5130513151325133513451355136513751385139513A513B
+513C513D513E51425147514A514C514E514F515051525153515751585159515B
+515D515E515F5160516151635164516651675169516A516F5172517A517E517F
+5183518451865187518A518B518E518F51905191519351945198519A519D519E
+519F51A151A351A651A751A851A951AA51AD51AE51B451B851B951BA51BE51BF
+51C151C251C351C551C851CA51CD51CE51D051D251D351D451D551D651D70000
+84
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+51D851D951DA51DC51DE51DF51E251E351E551E651E751E851E951EA51EC51EE
+51F151F251F451F751FE520452055209520B520C520F5210521352145215521C
+521E521F522152225223522552265227522A522C522F5231523252345235523C
+523E524452455246524752485249524B524E524F525252535255525752580000
+5259525A525B525D525F526052625263526452665268526B526C526D526E5270
+52715273527452755276527752785279527A527B527C527E5280528352845285
+528652875289528A528B528C528D528E528F5291529252945295529652975298
+5299529A529C52A452A552A652A752AE52AF52B052B452B552B652B752B852B9
+52BA52BB52BC52BD52C052C152C252C452C552C652C852CA52CC52CD52CE52CF
+52D152D352D452D552D752D952DA52DB52DC52DD52DE52E052E152E252E352E5
+52E652E752E852E952EA52EB52EC52ED52EE52EF52F152F252F352F452F552F6
+52F752F852FB52FC52FD530153025303530453075309530A530B530C530E0000
+85
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+53115312531353145318531B531C531E531F532253245325532753285329532B
+532C532D532F533053315332533353345335533653375338533C533D53405342
+53445346534B534C534D5350535453585359535B535D53655368536A536C536D
+537253765379537B537C537D537E53805381538353875388538A538E538F0000
+53905391539253935394539653975399539B539C539E53A053A153A453A753AA
+53AB53AC53AD53AF53B053B153B253B353B453B553B753B853B953BA53BC53BD
+53BE53C053C353C453C553C653C753CE53CF53D053D253D353D553DA53DC53DD
+53DE53E153E253E753F453FA53FE53FF5400540254055407540B541454185419
+541A541C542254245425542A5430543354365437543A543D543F544154425444
+544554475449544C544D544E544F5451545A545D545E545F5460546154635465
+54675469546A546B546C546D546E546F547054745479547A547E547F54815483
+5485548754885489548A548D5491549354975498549C549E549F54A054A10000
+86
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+54A254A554AE54B054B254B554B654B754B954BA54BC54BE54C354C554CA54CB
+54D654D854DB54E054E154E254E354E454EB54EC54EF54F054F154F454F554F6
+54F754F854F954FB54FE550055025503550455055508550A550B550C550D550E
+5512551355155516551755185519551A551C551D551E551F5521552555260000
+55285529552B552D553255345535553655385539553A553B553D554055425545
+55475548554B554C554D554E554F5551555255535554555755585559555A555B
+555D555E555F55605562556355685569556B556F557055715572557355745579
+557A557D557F55855586558C558D558E559055925593559555965597559A559B
+559E55A055A155A255A355A455A555A655A855A955AA55AB55AC55AD55AE55AF
+55B055B255B455B655B855BA55BC55BF55C055C155C255C355C655C755C855CA
+55CB55CE55CF55D055D555D755D855D955DA55DB55DE55E055E255E755E955ED
+55EE55F055F155F455F655F855F955FA55FB55FC55FF56025603560456050000
+87
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+56065607560A560B560D561056115612561356145615561656175619561A561C
+561D5620562156225625562656285629562A562B562E562F5630563356355637
+5638563A563C563D563E5640564156425643564456455646564756485649564A
+564B564F565056515652565356555656565A565B565D565E565F566056610000
+5663566556665667566D566E566F56705672567356745675567756785679567A
+567D567E567F56805681568256835684568756885689568A568B568C568D5690
+56915692569456955696569756985699569A569B569C569D569E569F56A056A1
+56A256A456A556A656A756A856A956AA56AB56AC56AD56AE56B056B156B256B3
+56B456B556B656B856B956BA56BB56BD56BE56BF56C056C156C256C356C456C5
+56C656C756C856C956CB56CC56CD56CE56CF56D056D156D256D356D556D656D8
+56D956DC56E356E556E656E756E856E956EA56EC56EE56EF56F256F356F656F7
+56F856FB56FC57005701570257055707570B570C570D570E570F571057110000
+88
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+57125713571457155716571757185719571A571B571D571E5720572157225724
+572557265727572B5731573257345735573657375738573C573D573F57415743
+57445745574657485749574B5752575357545755575657585759576257635765
+5767576C576E5770577157725774577557785779577A577D577E577F57800000
+5781578757885789578A578D578E578F57905791579457955796579757985799
+579A579C579D579E579F57A557A857AA57AC57AF57B057B157B357B557B657B7
+57B957BA57BB57BC57BD57BE57BF57C057C157C457C557C657C757C857C957CA
+57CC57CD57D057D157D357D657D757DB57DC57DE57E157E257E357E557E657E7
+57E857E957EA57EB57EC57EE57F057F157F257F357F557F657F757FB57FC57FE
+57FF580158035804580558085809580A580C580E580F58105812581358145816
+58175818581A581B581C581D581F5822582358255826582758285829582B582C
+582D582E582F58315832583358345836583758385839583A583B583C583D0000
+89
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+583E583F584058415842584358455846584758485849584A584B584E584F5850
+585258535855585658575859585A585B585C585D585F58605861586258635864
+5866586758685869586A586D586E586F58705871587258735874587558765877
+58785879587A587B587C587D587F58825884588658875888588A588B588C0000
+588D588E588F5890589158945895589658975898589B589C589D58A058A158A2
+58A358A458A558A658A758AA58AB58AC58AD58AE58AF58B058B158B258B358B4
+58B558B658B758B858B958BA58BB58BD58BE58BF58C058C258C358C458C658C7
+58C858C958CA58CB58CC58CD58CE58CF58D058D258D358D458D658D758D858D9
+58DA58DB58DC58DD58DE58DF58E058E158E258E358E558E658E758E858E958EA
+58ED58EF58F158F258F458F558F758F858FA58FB58FC58FD58FE58FF59005901
+59035905590659085909590A590B590C590E591059115912591359175918591B
+591D591E592059215922592359265928592C59305932593359355936593B0000
+8A
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+593D593E593F5940594359455946594A594C594D5950595259535959595B595C
+595D595E595F5961596359645966596759685969596A596B596C596D596E596F
+59705971597259755977597A597B597C597E597F598059855989598B598C598E
+598F59905991599459955998599A599B599C599D599F59A059A159A259A60000
+59A759AC59AD59B059B159B359B459B559B659B759B859BA59BC59BD59BF59C0
+59C159C259C359C459C559C759C859C959CC59CD59CE59CF59D559D659D959DB
+59DE59DF59E059E159E259E459E659E759E959EA59EB59ED59EE59EF59F059F1
+59F259F359F459F559F659F759F859FA59FC59FD59FE5A005A025A0A5A0B5A0D
+5A0E5A0F5A105A125A145A155A165A175A195A1A5A1B5A1D5A1E5A215A225A24
+5A265A275A285A2A5A2B5A2C5A2D5A2E5A2F5A305A335A355A375A385A395A3A
+5A3B5A3D5A3E5A3F5A415A425A435A445A455A475A485A4B5A4C5A4D5A4E5A4F
+5A505A515A525A535A545A565A575A585A595A5B5A5C5A5D5A5E5A5F5A600000
+8B
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+5A615A635A645A655A665A685A695A6B5A6C5A6D5A6E5A6F5A705A715A725A73
+5A785A795A7B5A7C5A7D5A7E5A805A815A825A835A845A855A865A875A885A89
+5A8A5A8B5A8C5A8D5A8E5A8F5A905A915A935A945A955A965A975A985A995A9C
+5A9D5A9E5A9F5AA05AA15AA25AA35AA45AA55AA65AA75AA85AA95AAB5AAC0000
+5AAD5AAE5AAF5AB05AB15AB45AB65AB75AB95ABA5ABB5ABC5ABD5ABF5AC05AC3
+5AC45AC55AC65AC75AC85ACA5ACB5ACD5ACE5ACF5AD05AD15AD35AD55AD75AD9
+5ADA5ADB5ADD5ADE5ADF5AE25AE45AE55AE75AE85AEA5AEC5AED5AEE5AEF5AF0
+5AF25AF35AF45AF55AF65AF75AF85AF95AFA5AFB5AFC5AFD5AFE5AFF5B005B01
+5B025B035B045B055B065B075B085B0A5B0B5B0C5B0D5B0E5B0F5B105B115B12
+5B135B145B155B185B195B1A5B1B5B1C5B1D5B1E5B1F5B205B215B225B235B24
+5B255B265B275B285B295B2A5B2B5B2C5B2D5B2E5B2F5B305B315B335B355B36
+5B385B395B3A5B3B5B3C5B3D5B3E5B3F5B415B425B435B445B455B465B470000
+8C
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+5B485B495B4A5B4B5B4C5B4D5B4E5B4F5B525B565B5E5B605B615B675B685B6B
+5B6D5B6E5B6F5B725B745B765B775B785B795B7B5B7C5B7E5B7F5B825B865B8A
+5B8D5B8E5B905B915B925B945B965B9F5BA75BA85BA95BAC5BAD5BAE5BAF5BB1
+5BB25BB75BBA5BBB5BBC5BC05BC15BC35BC85BC95BCA5BCB5BCD5BCE5BCF0000
+5BD15BD45BD55BD65BD75BD85BD95BDA5BDB5BDC5BE05BE25BE35BE65BE75BE9
+5BEA5BEB5BEC5BED5BEF5BF15BF25BF35BF45BF55BF65BF75BFD5BFE5C005C02
+5C035C055C075C085C0B5C0C5C0D5C0E5C105C125C135C175C195C1B5C1E5C1F
+5C205C215C235C265C285C295C2A5C2B5C2D5C2E5C2F5C305C325C335C355C36
+5C375C435C445C465C475C4C5C4D5C525C535C545C565C575C585C5A5C5B5C5C
+5C5D5C5F5C625C645C675C685C695C6A5C6B5C6C5C6D5C705C725C735C745C75
+5C765C775C785C7B5C7C5C7D5C7E5C805C835C845C855C865C875C895C8A5C8B
+5C8E5C8F5C925C935C955C9D5C9E5C9F5CA05CA15CA45CA55CA65CA75CA80000
+8D
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+5CAA5CAE5CAF5CB05CB25CB45CB65CB95CBA5CBB5CBC5CBE5CC05CC25CC35CC5
+5CC65CC75CC85CC95CCA5CCC5CCD5CCE5CCF5CD05CD15CD35CD45CD55CD65CD7
+5CD85CDA5CDB5CDC5CDD5CDE5CDF5CE05CE25CE35CE75CE95CEB5CEC5CEE5CEF
+5CF15CF25CF35CF45CF55CF65CF75CF85CF95CFA5CFC5CFD5CFE5CFF5D000000
+5D015D045D055D085D095D0A5D0B5D0C5D0D5D0F5D105D115D125D135D155D17
+5D185D195D1A5D1C5D1D5D1F5D205D215D225D235D255D285D2A5D2B5D2C5D2F
+5D305D315D325D335D355D365D375D385D395D3A5D3B5D3C5D3F5D405D415D42
+5D435D445D455D465D485D495D4D5D4E5D4F5D505D515D525D535D545D555D56
+5D575D595D5A5D5C5D5E5D5F5D605D615D625D635D645D655D665D675D685D6A
+5D6D5D6E5D705D715D725D735D755D765D775D785D795D7A5D7B5D7C5D7D5D7E
+5D7F5D805D815D835D845D855D865D875D885D895D8A5D8B5D8C5D8D5D8E5D8F
+5D905D915D925D935D945D955D965D975D985D9A5D9B5D9C5D9E5D9F5DA00000
+8E
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+5DA15DA25DA35DA45DA55DA65DA75DA85DA95DAA5DAB5DAC5DAD5DAE5DAF5DB0
+5DB15DB25DB35DB45DB55DB65DB85DB95DBA5DBB5DBC5DBD5DBE5DBF5DC05DC1
+5DC25DC35DC45DC65DC75DC85DC95DCA5DCB5DCC5DCE5DCF5DD05DD15DD25DD3
+5DD45DD55DD65DD75DD85DD95DDA5DDC5DDF5DE05DE35DE45DEA5DEC5DED0000
+5DF05DF55DF65DF85DF95DFA5DFB5DFC5DFF5E005E045E075E095E0A5E0B5E0D
+5E0E5E125E135E175E1E5E1F5E205E215E225E235E245E255E285E295E2A5E2B
+5E2C5E2F5E305E325E335E345E355E365E395E3A5E3E5E3F5E405E415E435E46
+5E475E485E495E4A5E4B5E4D5E4E5E4F5E505E515E525E535E565E575E585E59
+5E5A5E5C5E5D5E5F5E605E635E645E655E665E675E685E695E6A5E6B5E6C5E6D
+5E6E5E6F5E705E715E755E775E795E7E5E815E825E835E855E885E895E8C5E8D
+5E8E5E925E985E9B5E9D5EA15EA25EA35EA45EA85EA95EAA5EAB5EAC5EAE5EAF
+5EB05EB15EB25EB45EBA5EBB5EBC5EBD5EBF5EC05EC15EC25EC35EC45EC50000
+8F
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+5EC65EC75EC85ECB5ECC5ECD5ECE5ECF5ED05ED45ED55ED75ED85ED95EDA5EDC
+5EDD5EDE5EDF5EE05EE15EE25EE35EE45EE55EE65EE75EE95EEB5EEC5EED5EEE
+5EEF5EF05EF15EF25EF35EF55EF85EF95EFB5EFC5EFD5F055F065F075F095F0C
+5F0D5F0E5F105F125F145F165F195F1A5F1C5F1D5F1E5F215F225F235F240000
+5F285F2B5F2C5F2E5F305F325F335F345F355F365F375F385F3B5F3D5F3E5F3F
+5F415F425F435F445F455F465F475F485F495F4A5F4B5F4C5F4D5F4E5F4F5F51
+5F545F595F5A5F5B5F5C5F5E5F5F5F605F635F655F675F685F6B5F6E5F6F5F72
+5F745F755F765F785F7A5F7D5F7E5F7F5F835F865F8D5F8E5F8F5F915F935F94
+5F965F9A5F9B5F9D5F9E5F9F5FA05FA25FA35FA45FA55FA65FA75FA95FAB5FAC
+5FAF5FB05FB15FB25FB35FB45FB65FB85FB95FBA5FBB5FBE5FBF5FC05FC15FC2
+5FC75FC85FCA5FCB5FCE5FD35FD45FD55FDA5FDB5FDC5FDE5FDF5FE25FE35FE5
+5FE65FE85FE95FEC5FEF5FF05FF25FF35FF45FF65FF75FF95FFA5FFC60070000
+90
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+60086009600B600C60106011601360176018601A601E601F602260236024602C
+602D602E603060316032603360346036603760386039603A603D603E60406044
+60456046604760486049604A604C604E604F605160536054605660576058605B
+605C605E605F6060606160656066606E60716072607460756077607E60800000
+608160826085608660876088608A608B608E608F609060916093609560976098
+6099609C609E60A160A260A460A560A760A960AA60AE60B060B360B560B660B7
+60B960BA60BD60BE60BF60C060C160C260C360C460C760C860C960CC60CD60CE
+60CF60D060D260D360D460D660D760D960DB60DE60E160E260E360E460E560EA
+60F160F260F560F760F860FB60FC60FD60FE60FF61026103610461056107610A
+610B610C611061116112611361146116611761186119611B611C611D611E6121
+6122612561286129612A612C612D612E612F6130613161326133613461356136
+613761386139613A613B613C613D613E61406141614261436144614561460000
+91
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+61476149614B614D614F61506152615361546156615761586159615A615B615C
+615E615F6160616161636164616561666169616A616B616C616D616E616F6171
+617261736174617661786179617A617B617C617D617E617F6180618161826183
+618461856186618761886189618A618C618D618F619061916192619361950000
+6196619761986199619A619B619C619E619F61A061A161A261A361A461A561A6
+61AA61AB61AD61AE61AF61B061B161B261B361B461B561B661B861B961BA61BB
+61BC61BD61BF61C061C161C361C461C561C661C761C961CC61CD61CE61CF61D0
+61D361D561D661D761D861D961DA61DB61DC61DD61DE61DF61E061E161E261E3
+61E461E561E761E861E961EA61EB61EC61ED61EE61EF61F061F161F261F361F4
+61F661F761F861F961FA61FB61FC61FD61FE6200620162026203620462056207
+6209621362146219621C621D621E622062236226622762286229622B622D622F
+6230623162326235623662386239623A623B623C6242624462456246624A0000
+92
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+624F62506255625662576259625A625C625D625E625F62606261626262646265
+6268627162726274627562776278627A627B627D628162826283628562866287
+6288628B628C628D628E628F629062946299629C629D629E62A362A662A762A9
+62AA62AD62AE62AF62B062B262B362B462B662B762B862BA62BE62C062C10000
+62C362CB62CF62D162D562DD62DE62E062E162E462EA62EB62F062F262F562F8
+62F962FA62FB63006303630463056306630A630B630C630D630F631063126313
+63146315631763186319631C632663276329632C632D632E6330633163336334
+6335633663376338633B633C633E633F63406341634463476348634A63516352
+635363546356635763586359635A635B635C635D63606364636563666368636A
+636B636C636F6370637263736374637563786379637C637D637E637F63816383
+638463856386638B638D639163936394639563976399639A639B639C639D639E
+639F63A163A463A663AB63AF63B163B263B563B663B963BB63BD63BF63C00000
+93
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+63C163C263C363C563C763C863CA63CB63CC63D163D363D463D563D763D863D9
+63DA63DB63DC63DD63DF63E263E463E563E663E763E863EB63EC63EE63EF63F0
+63F163F363F563F763F963FA63FB63FC63FE640364046406640764086409640A
+640D640E6411641264156416641764186419641A641D641F6422642364240000
+6425642764286429642B642E642F643064316432643364356436643764386439
+643B643C643E6440644264436449644B644C644D644E644F6450645164536455
+645664576459645A645B645C645D645F64606461646264636464646564666468
+646A646B646C646E646F64706471647264736474647564766477647B647C647D
+647E647F648064816483648664886489648A648B648C648D648E648F64906493
+649464976498649A649B649C649D649F64A064A164A264A364A564A664A764A8
+64AA64AB64AF64B164B264B364B464B664B964BB64BD64BE64BF64C164C364C4
+64C664C764C864C964CA64CB64CC64CF64D164D364D464D564D664D964DA0000
+94
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+64DB64DC64DD64DF64E064E164E364E564E764E864E964EA64EB64EC64ED64EE
+64EF64F064F164F264F364F464F564F664F764F864F964FA64FB64FC64FD64FE
+64FF65016502650365046505650665076508650A650B650C650D650E650F6510
+6511651365146515651665176519651A651B651C651D651E651F652065210000
+6522652365246526652765286529652A652C652D65306531653265336537653A
+653C653D6540654165426543654465466547654A654B654D654E655065526553
+655465576558655A655C655F6560656165646565656765686569656A656D656E
+656F657165736575657665786579657A657B657C657D657E657F658065816582
+658365846585658665886589658A658D658E658F65926594659565966598659A
+659D659E65A065A265A365A665A865AA65AC65AE65B165B265B365B465B565B6
+65B765B865BA65BB65BE65BF65C065C265C765C865C965CA65CD65D065D165D3
+65D465D565D865D965DA65DB65DC65DD65DE65DF65E165E365E465EA65EB0000
+95
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+65F265F365F465F565F865F965FB65FC65FD65FE65FF66016604660566076608
+6609660B660D661066116612661666176618661A661B661C661E662166226623
+662466266629662A662B662C662E663066326633663766386639663A663B663D
+663F66406642664466456646664766486649664A664D664E6650665166580000
+6659665B665C665D665E666066626663666566676669666A666B666C666D6671
+66726673667566786679667B667C667D667F6680668166836685668666886689
+668A668B668D668E668F6690669266936694669566986699669A669B669C669E
+669F66A066A166A266A366A466A566A666A966AA66AB66AC66AD66AF66B066B1
+66B266B366B566B666B766B866BA66BB66BC66BD66BF66C066C166C266C366C4
+66C566C666C766C866C966CA66CB66CC66CD66CE66CF66D066D166D266D366D4
+66D566D666D766D866DA66DE66DF66E066E166E266E366E466E566E766E866EA
+66EB66EC66ED66EE66EF66F166F566F666F866FA66FB66FD6701670267030000
+96
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+6704670567066707670C670E670F671167126713671667186719671A671C671E
+67206721672267236724672567276729672E6730673267336736673767386739
+673B673C673E673F6741674467456747674A674B674D67526754675567576758
+6759675A675B675D67626763676467666767676B676C676E6771677467760000
+67786779677A677B677D678067826783678567866788678A678C678D678E678F
+679167926793679467966799679B679F67A067A167A467A667A967AC67AE67B1
+67B267B467B967BA67BB67BC67BD67BE67BF67C067C267C567C667C767C867C9
+67CA67CB67CC67CD67CE67D567D667D767DB67DF67E167E367E467E667E767E8
+67EA67EB67ED67EE67F267F567F667F767F867F967FA67FB67FC67FE68016802
+680368046806680D681068126814681568186819681A681B681C681E681F6820
+6822682368246825682668276828682B682C682D682E682F6830683168346835
+6836683A683B683F6847684B684D684F68526856685768586859685A685B0000
+97
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+685C685D685E685F686A686C686D686E686F6870687168726873687568786879
+687A687B687C687D687E687F688068826884688768886889688A688B688C688D
+688E68906891689268946895689668986899689A689B689C689D689E689F68A0
+68A168A368A468A568A968AA68AB68AC68AE68B168B268B468B668B768B80000
+68B968BA68BB68BC68BD68BE68BF68C168C368C468C568C668C768C868CA68CC
+68CE68CF68D068D168D368D468D668D768D968DB68DC68DD68DE68DF68E168E2
+68E468E568E668E768E868E968EA68EB68EC68ED68EF68F268F368F468F668F7
+68F868FB68FD68FE68FF69006902690369046906690769086909690A690C690F
+69116913691469156916691769186919691A691B691C691D691E692169226923
+69256926692769286929692A692B692C692E692F693169326933693569366937
+6938693A693B693C693E694069416943694469456946694769486949694A694B
+694C694D694E694F69506951695269536955695669586959695B695C695F0000
+98
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+6961696269646965696769686969696A696C696D696F69706972697369746975
+6976697A697B697D697E697F698169836985698A698B698C698E698F69906991
+69926993699669976999699A699D699E699F69A069A169A269A369A469A569A6
+69A969AA69AC69AE69AF69B069B269B369B569B669B869B969BA69BC69BD0000
+69BE69BF69C069C269C369C469C569C669C769C869C969CB69CD69CF69D169D2
+69D369D569D669D769D869D969DA69DC69DD69DE69E169E269E369E469E569E6
+69E769E869E969EA69EB69EC69EE69EF69F069F169F369F469F569F669F769F8
+69F969FA69FB69FC69FE6A006A016A026A036A046A056A066A076A086A096A0B
+6A0C6A0D6A0E6A0F6A106A116A126A136A146A156A166A196A1A6A1B6A1C6A1D
+6A1E6A206A226A236A246A256A266A276A296A2B6A2C6A2D6A2E6A306A326A33
+6A346A366A376A386A396A3A6A3B6A3C6A3F6A406A416A426A436A456A466A48
+6A496A4A6A4B6A4C6A4D6A4E6A4F6A516A526A536A546A556A566A576A5A0000
+99
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+6A5C6A5D6A5E6A5F6A606A626A636A646A666A676A686A696A6A6A6B6A6C6A6D
+6A6E6A6F6A706A726A736A746A756A766A776A786A7A6A7B6A7D6A7E6A7F6A81
+6A826A836A856A866A876A886A896A8A6A8B6A8C6A8D6A8F6A926A936A946A95
+6A966A986A996A9A6A9B6A9C6A9D6A9E6A9F6AA16AA26AA36AA46AA56AA60000
+6AA76AA86AAA6AAD6AAE6AAF6AB06AB16AB26AB36AB46AB56AB66AB76AB86AB9
+6ABA6ABB6ABC6ABD6ABE6ABF6AC06AC16AC26AC36AC46AC56AC66AC76AC86AC9
+6ACA6ACB6ACC6ACD6ACE6ACF6AD06AD16AD26AD36AD46AD56AD66AD76AD86AD9
+6ADA6ADB6ADC6ADD6ADE6ADF6AE06AE16AE26AE36AE46AE56AE66AE76AE86AE9
+6AEA6AEB6AEC6AED6AEE6AEF6AF06AF16AF26AF36AF46AF56AF66AF76AF86AF9
+6AFA6AFB6AFC6AFD6AFE6AFF6B006B016B026B036B046B056B066B076B086B09
+6B0A6B0B6B0C6B0D6B0E6B0F6B106B116B126B136B146B156B166B176B186B19
+6B1A6B1B6B1C6B1D6B1E6B1F6B256B266B286B296B2A6B2B6B2C6B2D6B2E0000
+9A
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+6B2F6B306B316B336B346B356B366B386B3B6B3C6B3D6B3F6B406B416B426B44
+6B456B486B4A6B4B6B4D6B4E6B4F6B506B516B526B536B546B556B566B576B58
+6B5A6B5B6B5C6B5D6B5E6B5F6B606B616B686B696B6B6B6C6B6D6B6E6B6F6B70
+6B716B726B736B746B756B766B776B786B7A6B7D6B7E6B7F6B806B856B880000
+6B8C6B8E6B8F6B906B916B946B956B976B986B996B9C6B9D6B9E6B9F6BA06BA2
+6BA36BA46BA56BA66BA76BA86BA96BAB6BAC6BAD6BAE6BAF6BB06BB16BB26BB6
+6BB86BB96BBA6BBB6BBC6BBD6BBE6BC06BC36BC46BC66BC76BC86BC96BCA6BCC
+6BCE6BD06BD16BD86BDA6BDC6BDD6BDE6BDF6BE06BE26BE36BE46BE56BE66BE7
+6BE86BE96BEC6BED6BEE6BF06BF16BF26BF46BF66BF76BF86BFA6BFB6BFC6BFE
+6BFF6C006C016C026C036C046C086C096C0A6C0B6C0C6C0E6C126C176C1C6C1D
+6C1E6C206C236C256C2B6C2C6C2D6C316C336C366C376C396C3A6C3B6C3C6C3E
+6C3F6C436C446C456C486C4B6C4C6C4D6C4E6C4F6C516C526C536C566C580000
+9B
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+6C596C5A6C626C636C656C666C676C6B6C6C6C6D6C6E6C6F6C716C736C756C77
+6C786C7A6C7B6C7C6C7F6C806C846C876C8A6C8B6C8D6C8E6C916C926C956C96
+6C976C986C9A6C9C6C9D6C9E6CA06CA26CA86CAC6CAF6CB06CB46CB56CB66CB7
+6CBA6CC06CC16CC26CC36CC66CC76CC86CCB6CCD6CCE6CCF6CD16CD26CD80000
+6CD96CDA6CDC6CDD6CDF6CE46CE66CE76CE96CEC6CED6CF26CF46CF96CFF6D00
+6D026D036D056D066D086D096D0A6D0D6D0F6D106D116D136D146D156D166D18
+6D1C6D1D6D1F6D206D216D226D236D246D266D286D296D2C6D2D6D2F6D306D34
+6D366D376D386D3A6D3F6D406D426D446D496D4C6D506D556D566D576D586D5B
+6D5D6D5F6D616D626D646D656D676D686D6B6D6C6D6D6D706D716D726D736D75
+6D766D796D7A6D7B6D7D6D7E6D7F6D806D816D836D846D866D876D8A6D8B6D8D
+6D8F6D906D926D966D976D986D996D9A6D9C6DA26DA56DAC6DAD6DB06DB16DB3
+6DB46DB66DB76DB96DBA6DBB6DBC6DBD6DBE6DC16DC26DC36DC86DC96DCA0000
+9C
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+6DCD6DCE6DCF6DD06DD26DD36DD46DD56DD76DDA6DDB6DDC6DDF6DE26DE36DE5
+6DE76DE86DE96DEA6DED6DEF6DF06DF26DF46DF56DF66DF86DFA6DFD6DFE6DFF
+6E006E016E026E036E046E066E076E086E096E0B6E0F6E126E136E156E186E19
+6E1B6E1C6E1E6E1F6E226E266E276E286E2A6E2C6E2E6E306E316E336E350000
+6E366E376E396E3B6E3C6E3D6E3E6E3F6E406E416E426E456E466E476E486E49
+6E4A6E4B6E4C6E4F6E506E516E526E556E576E596E5A6E5C6E5D6E5E6E606E61
+6E626E636E646E656E666E676E686E696E6A6E6C6E6D6E6F6E706E716E726E73
+6E746E756E766E776E786E796E7A6E7B6E7C6E7D6E806E816E826E846E876E88
+6E8A6E8B6E8C6E8D6E8E6E916E926E936E946E956E966E976E996E9A6E9B6E9D
+6E9E6EA06EA16EA36EA46EA66EA86EA96EAB6EAC6EAD6EAE6EB06EB36EB56EB8
+6EB96EBC6EBE6EBF6EC06EC36EC46EC56EC66EC86EC96ECA6ECC6ECD6ECE6ED0
+6ED26ED66ED86ED96EDB6EDC6EDD6EE36EE76EEA6EEB6EEC6EED6EEE6EEF0000
+9D
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+6EF06EF16EF26EF36EF56EF66EF76EF86EFA6EFB6EFC6EFD6EFE6EFF6F006F01
+6F036F046F056F076F086F0A6F0B6F0C6F0D6F0E6F106F116F126F166F176F18
+6F196F1A6F1B6F1C6F1D6F1E6F1F6F216F226F236F256F266F276F286F2C6F2E
+6F306F326F346F356F376F386F396F3A6F3B6F3C6F3D6F3F6F406F416F420000
+6F436F446F456F486F496F4A6F4C6F4E6F4F6F506F516F526F536F546F556F56
+6F576F596F5A6F5B6F5D6F5F6F606F616F636F646F656F676F686F696F6A6F6B
+6F6C6F6F6F706F716F736F756F766F776F796F7B6F7D6F7E6F7F6F806F816F82
+6F836F856F866F876F8A6F8B6F8F6F906F916F926F936F946F956F966F976F98
+6F996F9A6F9B6F9D6F9E6F9F6FA06FA26FA36FA46FA56FA66FA86FA96FAA6FAB
+6FAC6FAD6FAE6FAF6FB06FB16FB26FB46FB56FB76FB86FBA6FBB6FBC6FBD6FBE
+6FBF6FC16FC36FC46FC56FC66FC76FC86FCA6FCB6FCC6FCD6FCE6FCF6FD06FD3
+6FD46FD56FD66FD76FD86FD96FDA6FDB6FDC6FDD6FDF6FE26FE36FE46FE50000
+9E
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+6FE66FE76FE86FE96FEA6FEB6FEC6FED6FF06FF16FF26FF36FF46FF56FF66FF7
+6FF86FF96FFA6FFB6FFC6FFD6FFE6FFF70007001700270037004700570067007
+70087009700A700B700C700D700E700F70107012701370147015701670177018
+7019701C701D701E701F702070217022702470257026702770287029702A0000
+702B702C702D702E702F70307031703270337034703670377038703A703B703C
+703D703E703F7040704170427043704470457046704770487049704A704B704D
+704E7050705170527053705470557056705770587059705A705B705C705D705F
+7060706170627063706470657066706770687069706A706E7071707270737074
+70777079707A707B707D7081708270837084708670877088708B708C708D708F
+70907091709370977098709A709B709E709F70A070A170A270A370A470A570A6
+70A770A870A970AA70B070B270B470B570B670BA70BE70BF70C470C570C670C7
+70C970CB70CC70CD70CE70CF70D070D170D270D370D470D570D670D770DA0000
+9F
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+70DC70DD70DE70E070E170E270E370E570EA70EE70F070F170F270F370F470F5
+70F670F870FA70FB70FC70FE70FF710071017102710371047105710671077108
+710B710C710D710E710F7111711271147117711B711C711D711E711F71207121
+7122712371247125712771287129712A712B712C712D712E7132713371340000
+7135713771387139713A713B713C713D713E713F714071417142714371447146
+714771487149714B714D714F7150715171527153715471557156715771587159
+715A715B715D715F716071617162716371657169716A716B716C716D716F7170
+717171747175717671777179717B717C717E717F718071817182718371857186
+718771887189718B718C718D718E7190719171927193719571967197719A719B
+719C719D719E71A171A271A371A471A571A671A771A971AA71AB71AD71AE71AF
+71B071B171B271B471B671B771B871BA71BB71BC71BD71BE71BF71C071C171C2
+71C471C571C671C771C871C971CA71CB71CC71CD71CF71D071D171D271D30000
+A0
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+71D671D771D871D971DA71DB71DC71DD71DE71DF71E171E271E371E471E671E8
+71E971EA71EB71EC71ED71EF71F071F171F271F371F471F571F671F771F871FA
+71FB71FC71FD71FE71FF720072017202720372047205720772087209720A720B
+720C720D720E720F7210721172127213721472157216721772187219721A0000
+721B721C721E721F722072217222722372247225722672277229722B722D722E
+722F723272337234723A723C723E72407241724272437244724572467249724A
+724B724E724F7250725172537254725572577258725A725C725E726072637264
+72657268726A726B726C726D7270727172737274727672777278727B727C727D
+7282728372857286728772887289728C728E7290729172937294729572967297
+72987299729A729B729C729D729E72A072A172A272A372A472A572A672A772A8
+72A972AA72AB72AE72B172B272B372B572BA72BB72BC72BD72BE72BF72C072C5
+72C672C772C972CA72CB72CC72CF72D172D372D472D572D672D872DA72DB0000
+A1
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000030003001300200B702C902C700A8300330052014FF5E2016202620182019
+201C201D3014301530083009300A300B300C300D300E300F3016301730103011
+00B100D700F72236222722282211220F222A222922082237221A22A522252220
+23122299222B222E2261224C2248223D221D2260226E226F22642265221E2235
+22342642264000B0203220332103FF0400A4FFE0FFE1203000A7211626062605
+25CB25CF25CE25C725C625A125A025B325B2203B219221902191219330130000
+A2
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000217021712172217321742175217621772178217900000000000000000000
+000024882489248A248B248C248D248E248F2490249124922493249424952496
+249724982499249A249B247424752476247724782479247A247B247C247D247E
+247F248024812482248324842485248624872460246124622463246424652466
+2467246824690000000032203221322232233224322532263227322832290000
+00002160216121622163216421652166216721682169216A216B000000000000
+A3
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000FF01FF02FF03FFE5FF05FF06FF07FF08FF09FF0AFF0BFF0CFF0DFF0EFF0F
+FF10FF11FF12FF13FF14FF15FF16FF17FF18FF19FF1AFF1BFF1CFF1DFF1EFF1F
+FF20FF21FF22FF23FF24FF25FF26FF27FF28FF29FF2AFF2BFF2CFF2DFF2EFF2F
+FF30FF31FF32FF33FF34FF35FF36FF37FF38FF39FF3AFF3BFF3CFF3DFF3EFF3F
+FF40FF41FF42FF43FF44FF45FF46FF47FF48FF49FF4AFF4BFF4CFF4DFF4EFF4F
+FF50FF51FF52FF53FF54FF55FF56FF57FF58FF59FF5AFF5BFF5CFF5DFFE30000
+A4
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000304130423043304430453046304730483049304A304B304C304D304E304F
+3050305130523053305430553056305730583059305A305B305C305D305E305F
+3060306130623063306430653066306730683069306A306B306C306D306E306F
+3070307130723073307430753076307730783079307A307B307C307D307E307F
+3080308130823083308430853086308730883089308A308B308C308D308E308F
+3090309130923093000000000000000000000000000000000000000000000000
+A5
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000030A130A230A330A430A530A630A730A830A930AA30AB30AC30AD30AE30AF
+30B030B130B230B330B430B530B630B730B830B930BA30BB30BC30BD30BE30BF
+30C030C130C230C330C430C530C630C730C830C930CA30CB30CC30CD30CE30CF
+30D030D130D230D330D430D530D630D730D830D930DA30DB30DC30DD30DE30DF
+30E030E130E230E330E430E530E630E730E830E930EA30EB30EC30ED30EE30EF
+30F030F130F230F330F430F530F6000000000000000000000000000000000000
+A6
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000039103920393039403950396039703980399039A039B039C039D039E039F
+03A003A103A303A403A503A603A703A803A90000000000000000000000000000
+000003B103B203B303B403B503B603B703B803B903BA03BB03BC03BD03BE03BF
+03C003C103C303C403C503C603C703C803C90000000000000000000000000000
+FE35FE36FE39FE3AFE3FFE40FE3DFE3EFE41FE42FE43FE4400000000FE3BFE3C
+FE37FE38FE310000FE33FE340000000000000000000000000000000000000000
+A7
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000004100411041204130414041504010416041704180419041A041B041C041D
+041E041F0420042104220423042404250426042704280429042A042B042C042D
+042E042F00000000000000000000000000000000000000000000000000000000
+000004300431043204330434043504510436043704380439043A043B043C043D
+043E043F0440044104420443044404450446044704480449044A044B044C044D
+044E044F00000000000000000000000000000000000000000000000000000000
+A8
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+02CA02CB02D920132015202520352105210921962197219821992215221F2223
+22522266226722BF2550255125522553255425552556255725582559255A255B
+255C255D255E255F2560256125622563256425652566256725682569256A256B
+256C256D256E256F257025712572257325812582258325842585258625870000
+25882589258A258B258C258D258E258F25932594259525BC25BD25E225E325E4
+25E5260922953012301D301E0000000000000000000000000000000000000000
+0000010100E101CE00E0011300E9011B00E8012B00ED01D000EC014D00F301D2
+00F2016B00FA01D400F901D601D801DA01DC00FC00EA02510000014401480000
+0261000000000000000031053106310731083109310A310B310C310D310E310F
+3110311131123113311431153116311731183119311A311B311C311D311E311F
+3120312131223123312431253126312731283129000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+A9
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+30213022302330243025302630273028302932A3338E338F339C339D339E33A1
+33C433CE33D133D233D5FE30FFE2FFE400002121323100002010000000000000
+30FC309B309C30FD30FE3006309D309EFE49FE4AFE4BFE4CFE4DFE4EFE4FFE50
+FE51FE52FE54FE55FE56FE57FE59FE5AFE5BFE5CFE5DFE5EFE5FFE60FE610000
+FE62FE63FE64FE65FE66FE68FE69FE6AFE6B0000000000000000000000000000
+0000000000000000000000003007000000000000000000000000000000000000
+00000000000000002500250125022503250425052506250725082509250A250B
+250C250D250E250F2510251125122513251425152516251725182519251A251B
+251C251D251E251F2520252125222523252425252526252725282529252A252B
+252C252D252E252F2530253125322533253425352536253725382539253A253B
+253C253D253E253F2540254125422543254425452546254725482549254A254B
+0000000000000000000000000000000000000000000000000000000000000000
+AA
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+72DC72DD72DF72E272E372E472E572E672E772EA72EB72F572F672F972FD72FE
+72FF73007302730473057306730773087309730B730C730D730F731073117312
+731473187319731A731F732073237324732673277328732D732F733073327333
+73357336733A733B733C733D7340734173427343734473457346734773480000
+7349734A734B734C734E734F7351735373547355735673587359735A735B735C
+735D735E735F736173627363736473657366736773687369736A736B736E7370
+7371000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+AB
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+73727373737473757376737773787379737A737B737C737D737F738073817382
+7383738573867388738A738C738D738F73907392739373947395739773987399
+739A739C739D739E73A073A173A373A473A573A673A773A873AA73AC73AD73B1
+73B473B573B673B873B973BC73BD73BE73BF73C173C373C473C573C673C70000
+73CB73CC73CE73D273D373D473D573D673D773D873DA73DB73DC73DD73DF73E1
+73E273E373E473E673E873EA73EB73EC73EE73EF73F073F173F373F473F573F6
+73F7000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+AC
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+73F873F973FA73FB73FC73FD73FE73FF740074017402740474077408740B740C
+740D740E741174127413741474157416741774187419741C741D741E741F7420
+74217423742474277429742B742D742F74317432743774387439743A743B743D
+743E743F744074427443744474457446744774487449744A744B744C744D0000
+744E744F7450745174527453745474567458745D746074617462746374647465
+7466746774687469746A746B746C746E746F7471747274737474747574787479
+747A000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+AD
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+747B747C747D747F748274847485748674887489748A748C748D748F74917492
+7493749474957496749774987499749A749B749D749F74A074A174A274A374A4
+74A574A674AA74AB74AC74AD74AE74AF74B074B174B274B374B474B574B674B7
+74B874B974BB74BC74BD74BE74BF74C074C174C274C374C474C574C674C70000
+74C874C974CA74CB74CC74CD74CE74CF74D074D174D374D474D574D674D774D8
+74D974DA74DB74DD74DF74E174E574E774E874E974EA74EB74EC74ED74F074F1
+74F2000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+AE
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+74F374F574F874F974FA74FB74FC74FD74FE7500750175027503750575067507
+75087509750A750B750C750E751075127514751575167517751B751D751E7520
+752175227523752475267527752A752E753475367539753C753D753F75417542
+75437544754675477549754A754D755075517552755375557556755775580000
+755D755E755F75607561756275637564756775687569756B756C756D756E756F
+757075717573757575767577757A757B757C757D757E75807581758275847585
+7587000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+AF
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+75887589758A758C758D758E7590759375957598759B759C759E75A275A675A7
+75A875A975AA75AD75B675B775BA75BB75BF75C075C175C675CB75CC75CE75CF
+75D075D175D375D775D975DA75DC75DD75DF75E075E175E575E975EC75ED75EE
+75EF75F275F375F575F675F775F875FA75FB75FD75FE76027604760676070000
+76087609760B760D760E760F76117612761376147616761A761C761D761E7621
+762376277628762C762E762F76317632763676377639763A763B763D76417642
+7644000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+B0
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+76457646764776487649764A764B764E764F7650765176527653765576577658
+7659765A765B765D765F766076617662766476657666766776687669766A766C
+766D766E767076717672767376747675767676777679767A767C767F76807681
+768376857689768A768C768D768F769076927694769576977698769A769B0000
+769C769D769E769F76A076A176A276A376A576A676A776A876A976AA76AB76AC
+76AD76AF76B076B376B576B676B776B876B976BA76BB76BC76BD76BE76C076C1
+76C3554A963F57C3632854CE550954C07691764C853C77EE827E788D72319698
+978D6C285B894FFA630966975CB880FA684880AE660276CE51F9655671AC7FF1
+888450B2596561CA6FB382AD634C625253ED54277B06516B75A45DF462D48DCB
+9776628A8019575D97387F627238767D67CF767E64464F708D2562DC7A176591
+73ED642C6273822C9881677F7248626E62CC4F3474E3534A529E7ECA90A65E2E
+6886699C81807ED168D278C5868C9551508D8C2482DE80DE5305891252650000
+B1
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+76C476C776C976CB76CC76D376D576D976DA76DC76DD76DE76E076E176E276E3
+76E476E676E776E876E976EA76EB76EC76ED76F076F376F576F676F776FA76FB
+76FD76FF77007702770377057706770A770C770E770F77107711771277137714
+7715771677177718771B771C771D771E77217723772477257727772A772B0000
+772C772E773077317732773377347739773B773D773E773F7742774477457746
+77487749774A774B774C774D774E774F77527753775477557756775777587759
+775C858496F94FDD582199715B9D62B162A566B48C799C8D7206676F789160B2
+535153178F8880CC8D1D94A1500D72C8590760EB711988AB595482EF672C7B28
+5D297EF7752D6CF58E668FF8903C9F3B6BD491197B145F7C78A784D6853D6BD5
+6BD96BD65E015E8775F995ED655D5F0A5FC58F9F58C181C2907F965B97AD8FB9
+7F168D2C62414FBF53D8535E8FA88FA98FAB904D68075F6A819888689CD6618B
+522B762A5F6C658C6FD26EE85BBE6448517551B067C44E1979C9997C70B30000
+B2
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+775D775E775F7760776477677769776A776D776E776F77707771777277737774
+7775777677777778777A777B777C7781778277837786778777887789778A778B
+778F77907793779477957796779777987799779A779B779C779D779E77A177A3
+77A477A677A877AB77AD77AE77AF77B177B277B477B677B777B877B977BA0000
+77BC77BE77C077C177C277C377C477C577C677C777C877C977CA77CB77CC77CE
+77CF77D077D177D277D377D477D577D677D877D977DA77DD77DE77DF77E077E1
+77E475C55E7673BB83E064AD62E894B56CE2535A52C3640F94C27B944F2F5E1B
+82368116818A6E246CCA9A736355535C54FA886557E04E0D5E036B657C3F90E8
+601664E6731C88C16750624D8D22776C8E2991C75F6983DC8521991053C28695
+6B8B60ED60E8707F82CD82314ED36CA785CF64CD7CD969FD66F9834953957B56
+4FA7518C6D4B5C428E6D63D253C9832C833667E578B4643D5BDF5C945DEE8BE7
+62C667F48C7A640063BA8749998B8C177F2094F24EA7961098A4660C73160000
+B3
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+77E677E877EA77EF77F077F177F277F477F577F777F977FA77FB77FC78037804
+7805780678077808780A780B780E780F7810781378157819781B781E78207821
+782278247828782A782B782E782F78317832783378357836783D783F78417842
+78437844784678487849784A784B784D784F78517853785478587859785A0000
+785B785C785E785F7860786178627863786478657866786778687869786F7870
+78717872787378747875787678787879787A787B787D787E787F788078817882
+7883573A5C1D5E38957F507F80A05382655E7545553150218D856284949E671D
+56326F6E5DE2543570928F66626F64A463A35F7B6F8890F481E38FB05C186668
+5FF16C8996488D81886C649179F057CE6A59621054484E587A0B60E96F848BDA
+627F901E9A8B79E4540375F4630153196C608FDF5F1B9A70803B9F7F4F885C3A
+8D647FC565A570BD514551B2866B5D075BA062BD916C75748E0C7A2061017B79
+4EC77EF877854E1181ED521D51FA6A7153A88E87950496CF6EC19664695A0000
+B4
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+7884788578867888788A788B788F789078927894789578967899789D789E78A0
+78A278A478A678A878A978AA78AB78AC78AD78AE78AF78B578B678B778B878BA
+78BB78BC78BD78BF78C078C278C378C478C678C778C878CC78CD78CE78CF78D1
+78D278D378D678D778D878DA78DB78DC78DD78DE78DF78E078E178E278E30000
+78E478E578E678E778E978EA78EB78ED78EE78EF78F078F178F378F578F678F8
+78F978FB78FC78FD78FE78FF79007902790379047906790779087909790A790B
+790C784050A877D7641089E6590463E35DDD7A7F693D4F20823955984E3275AE
+7A975E625E8A95EF521B5439708A6376952457826625693F918755076DF37EAF
+882262337EF075B5832878C196CC8F9E614874F78BCD6B64523A8D506B21806A
+847156F153064ECE4E1B51D17C97918B7C074FC38E7F7BE17A9C64675D1450AC
+810676017CB96DEC7FE067515B585BF878CB64AE641363AA632B9519642D8FBE
+7B5476296253592754466B7950A362345E266B864EE38D37888B5F85902E0000
+B5
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+790D790E790F791079117912791479157916791779187919791A791B791C791D
+791F792079217922792379257926792779287929792A792B792C792D792E792F
+793079317932793379357936793779387939793D793F79427943794479457947
+794A794B794C794D794E794F7950795179527954795579587959796179630000
+796479667969796A796B796C796E79707971797279737974797579767979797B
+797C797D797E797F798279837986798779887989798B798C798D798E79907991
+79926020803D62C54E39535590F863B880C665E66C2E4F4660EE6DE18BDE5F39
+86CB5F536321515A83616863520063638E4850125C9B79775BFC52307A3B60BC
+905376D75FB75F9776848E6C706F767B7B4977AA51F3909358244F4E6EF48FEA
+654C7B1B72C46DA47FDF5AE162B55E95573084827B2C5E1D5F1F90127F1498A0
+63826EC7789870B95178975B57AB75354F4375385E9760E659606DC06BBF7889
+53FC96D551CB52016389540A94938C038DCC7239789F87768FED8C0D53E00000
+B6
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+7993799479957996799779987999799B799C799D799E799F79A079A179A279A3
+79A479A579A679A879A979AA79AB79AC79AD79AE79AF79B079B179B279B479B5
+79B679B779B879BC79BF79C279C479C579C779C879CA79CC79CE79CF79D079D3
+79D479D679D779D979DA79DB79DC79DD79DE79E079E179E279E579E879EA0000
+79EC79EE79F179F279F379F479F579F679F779F979FA79FC79FE79FF7A017A04
+7A057A077A087A097A0A7A0C7A0F7A107A117A127A137A157A167A187A197A1B
+7A1C4E0176EF53EE948998769F0E952D5B9A8BA24E224E1C51AC846361C252A8
+680B4F97606B51BB6D1E515C6296659796618C46901775D890FD77636BD2728A
+72EC8BFB583577798D4C675C9540809A5EA66E2159927AEF77ED953B6BB565AD
+7F0E58065151961F5BF958A954288E726566987F56E4949D76FE9041638754C6
+591A593A579B8EB267358DFA8235524160F0581586FE5CE89E454FC4989D8BB9
+5A2560765384627C904F9102997F6069800C513F80335C1499756D314E8C0000
+B7
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+7A1D7A1F7A217A227A247A257A267A277A287A297A2A7A2B7A2C7A2D7A2E7A2F
+7A307A317A327A347A357A367A387A3A7A3E7A407A417A427A437A447A457A47
+7A487A497A4A7A4B7A4C7A4D7A4E7A4F7A507A527A537A547A557A567A587A59
+7A5A7A5B7A5C7A5D7A5E7A5F7A607A617A627A637A647A657A667A677A680000
+7A697A6A7A6B7A6C7A6D7A6E7A6F7A717A727A737A757A7B7A7C7A7D7A7E7A82
+7A857A877A897A8A7A8B7A8C7A8E7A8F7A907A937A947A997A9A7A9B7A9E7AA1
+7AA28D3053D17F5A7B4F4F104E4F96006CD573D085E95E06756A7FFB6A0A77FE
+94927E4151E170E653CD8FD483038D2972AF996D6CDB574A82B365B980AA623F
+963259A84EFF8BBF7EBA653E83F2975E556198DE80A5532A8BFD542080BA5E9F
+6CB88D3982AC915A54296C1B52067EB7575F711A6C7E7C89594B4EFD5FFF6124
+7CAA4E305C0167AB87025CF0950B98CE75AF70FD902251AF7F1D8BBD594951E4
+4F5B5426592B657780A45B75627662C28F905E456C1F7B264F0F4FD8670D0000
+B8
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+7AA37AA47AA77AA97AAA7AAB7AAE7AAF7AB07AB17AB27AB47AB57AB67AB77AB8
+7AB97ABA7ABB7ABC7ABD7ABE7AC07AC17AC27AC37AC47AC57AC67AC77AC87AC9
+7ACA7ACC7ACD7ACE7ACF7AD07AD17AD27AD37AD47AD57AD77AD87ADA7ADB7ADC
+7ADD7AE17AE27AE47AE77AE87AE97AEA7AEB7AEC7AEE7AF07AF17AF27AF30000
+7AF47AF57AF67AF77AF87AFB7AFC7AFE7B007B017B027B057B077B097B0C7B0D
+7B0E7B107B127B137B167B177B187B1A7B1C7B1D7B1F7B217B227B237B277B29
+7B2D6D6E6DAA798F88B15F17752B629A8F854FEF91DC65A7812F81515E9C8150
+8D74526F89868D4B590D50854ED8961C723681798D1F5BCC8BA3964459877F1A
+54905676560E8BE565396982949976D66E895E727518674667D17AFF809D8D76
+611F79C665628D635188521A94A27F38809B7EB25C976E2F67607BD9768B9AD8
+818F7F947CD5641E95507A3F544A54E56B4C640162089E3D80F3759952729769
+845B683C86E49601969494EC4E2A54047ED968398DDF801566F45E9A7FB90000
+B9
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+7B2F7B307B327B347B357B367B377B397B3B7B3D7B3F7B407B417B427B437B44
+7B467B487B4A7B4D7B4E7B537B557B577B597B5C7B5E7B5F7B617B637B647B65
+7B667B677B687B697B6A7B6B7B6C7B6D7B6F7B707B737B747B767B787B7A7B7C
+7B7D7B7F7B817B827B837B847B867B877B887B897B8A7B8B7B8C7B8E7B8F0000
+7B917B927B937B967B987B997B9A7B9B7B9E7B9F7BA07BA37BA47BA57BAE7BAF
+7BB07BB27BB37BB57BB67BB77BB97BBA7BBB7BBC7BBD7BBE7BBF7BC07BC27BC3
+7BC457C2803F68975DE5653B529F606D9F9A4F9B8EAC516C5BAB5F135DE96C5E
+62F18D21517194A952FE6C9F82DF72D757A267848D2D591F8F9C83C754957B8D
+4F306CBD5B6459D19F1353E486CA9AA88C3780A16545987E56FA96C7522E74DC
+52505BE1630289024E5662D0602A68FA51735B9851A089C27BA199867F5060EF
+704C8D2F51495E7F901B747089C4572D78455F529F9F95FA8F689B3C8BE17678
+684267DC8DEA8D35523D8F8A6EDA68CD950590ED56FD679C88F98FC754C80000
+BA
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+7BC57BC87BC97BCA7BCB7BCD7BCE7BCF7BD07BD27BD47BD57BD67BD77BD87BDB
+7BDC7BDE7BDF7BE07BE27BE37BE47BE77BE87BE97BEB7BEC7BED7BEF7BF07BF2
+7BF37BF47BF57BF67BF87BF97BFA7BFB7BFD7BFF7C007C017C027C037C047C05
+7C067C087C097C0A7C0D7C0E7C107C117C127C137C147C157C177C187C190000
+7C1A7C1B7C1C7C1D7C1E7C207C217C227C237C247C257C287C297C2B7C2C7C2D
+7C2E7C2F7C307C317C327C337C347C357C367C377C397C3A7C3B7C3C7C3D7C3E
+7C429AB85B696D776C264EA55BB39A87916361A890AF97E9542B6DB55BD251FD
+558A7F557FF064BC634D65F161BE608D710A6C576C49592F676D822A58D5568E
+8C6A6BEB90DD597D801753F76D695475559D837783CF683879BE548C4F555408
+76D28C8996026CB36DB88D6B89109E648D3A563F9ED175D55F8872E0606854FC
+4EA86A2A886160528F7054C470D886799E3F6D2A5B8F5F187EA255894FAF7334
+543C539A5019540E547C4E4E5FFD745A58F6846B80E1877472D07CCA6E560000
+BB
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+7C437C447C457C467C477C487C497C4A7C4B7C4C7C4E7C4F7C507C517C527C53
+7C547C557C567C577C587C597C5A7C5B7C5C7C5D7C5E7C5F7C607C617C627C63
+7C647C657C667C677C687C697C6A7C6B7C6C7C6D7C6E7C6F7C707C717C727C75
+7C767C777C787C797C7A7C7E7C7F7C807C817C827C837C847C857C867C870000
+7C887C8A7C8B7C8C7C8D7C8E7C8F7C907C937C947C967C997C9A7C9B7CA07CA1
+7CA37CA67CA77CA87CA97CAB7CAC7CAD7CAF7CB07CB47CB57CB67CB77CB87CBA
+7CBB5F27864E552C62A44E926CAA623782B154D7534E733E6ED1753B52125316
+8BDD69D05F8A60006DEE574F6B2273AF68538FD87F13636260A3552475EA8C62
+71156DA35BA65E7B8352614C9EC478FA87577C27768751F060F6714C66435E4C
+604D8C0E707063258F895FBD606286D456DE6BC160946167534960E066668D3F
+79FD4F1A70E96C478BB38BF27ED88364660F5A5A9B426D516DF78C416D3B4F19
+706B83B7621660D1970D8D27797851FB573E57FA673A75787A3D79EF7B950000
+BC
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+7CBF7CC07CC27CC37CC47CC67CC97CCB7CCE7CCF7CD07CD17CD27CD37CD47CD8
+7CDA7CDB7CDD7CDE7CE17CE27CE37CE47CE57CE67CE77CE97CEA7CEB7CEC7CED
+7CEE7CF07CF17CF27CF37CF47CF57CF67CF77CF97CFA7CFC7CFD7CFE7CFF7D00
+7D017D027D037D047D057D067D077D087D097D0B7D0C7D0D7D0E7D0F7D100000
+7D117D127D137D147D157D167D177D187D197D1A7D1B7D1C7D1D7D1E7D1F7D21
+7D237D247D257D267D287D297D2A7D2C7D2D7D2E7D307D317D327D337D347D35
+7D36808C99658FF96FC08BA59E2159EC7EE97F095409678168D88F917C4D96C6
+53CA602575BE6C7253735AC97EA7632451E0810A5DF184DF628051805B634F0E
+796D524260B86D4E5BC45BC28BA18BB065E25FCC964559937EE77EAA560967B7
+59394F735BB652A0835A988A8D3E753294BE50477A3C4EF767B69A7E5AC16B7C
+76D1575A5C167B3A95F4714E517C80A9827059787F04832768C067EC78B17877
+62E363617B804FED526A51CF835069DB92748DF58D3189C1952E7BAD4EF60000
+BD
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+7D377D387D397D3A7D3B7D3C7D3D7D3E7D3F7D407D417D427D437D447D457D46
+7D477D487D497D4A7D4B7D4C7D4D7D4E7D4F7D507D517D527D537D547D557D56
+7D577D587D597D5A7D5B7D5C7D5D7D5E7D5F7D607D617D627D637D647D657D66
+7D677D687D697D6A7D6B7D6C7D6D7D6F7D707D717D727D737D747D757D760000
+7D787D797D7A7D7B7D7C7D7D7D7E7D7F7D807D817D827D837D847D857D867D87
+7D887D897D8A7D8B7D8C7D8D7D8E7D8F7D907D917D927D937D947D957D967D97
+7D98506582305251996F6E106E856DA75EFA50F559DC5C066D466C5F7586848B
+686859568BB253209171964D854969127901712680F64EA490CA6D479A845A07
+56BC640594F077EB4FA5811A72E189D2997A7F347EDE527F655991758F7F8F83
+53EB7A9663ED63A5768679F888579636622A52AB8282685467706377776B7AED
+6D017ED389E359D0621285C982A5754C501F4ECB75A58BEB5C4A5DFE7B4B65A4
+91D14ECA6D25895F7D2795264EC58C288FDB9773664B79818FD170EC6D780000
+BE
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+7D997D9A7D9B7D9C7D9D7D9E7D9F7DA07DA17DA27DA37DA47DA57DA77DA87DA9
+7DAA7DAB7DAC7DAD7DAF7DB07DB17DB27DB37DB47DB57DB67DB77DB87DB97DBA
+7DBB7DBC7DBD7DBE7DBF7DC07DC17DC27DC37DC47DC57DC67DC77DC87DC97DCA
+7DCB7DCC7DCD7DCE7DCF7DD07DD17DD27DD37DD47DD57DD67DD77DD87DD90000
+7DDA7DDB7DDC7DDD7DDE7DDF7DE07DE17DE27DE37DE47DE57DE67DE77DE87DE9
+7DEA7DEB7DEC7DED7DEE7DEF7DF07DF17DF27DF37DF47DF57DF67DF77DF87DF9
+7DFA5C3D52B283465162830E775B66769CB84EAC60CA7CBE7CB37ECF4E958B66
+666F988897595883656C955C5F8475C997567ADF7ADE51C070AF7A9863EA7A76
+7EA0739697ED4E4570784E5D915253A9655165E781FC8205548E5C31759A97A0
+62D872D975BD5C459A7983CA5C40548077E94E3E6CAE805A62D2636E5DE85177
+8DDD8E1E952F4FF153E560E770AC526763509E435A1F5026773753777EE26485
+652B628963985014723589C951B38BC07EDD574783CC94A7519B541B5CFB0000
+BF
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+7DFB7DFC7DFD7DFE7DFF7E007E017E027E037E047E057E067E077E087E097E0A
+7E0B7E0C7E0D7E0E7E0F7E107E117E127E137E147E157E167E177E187E197E1A
+7E1B7E1C7E1D7E1E7E1F7E207E217E227E237E247E257E267E277E287E297E2A
+7E2B7E2C7E2D7E2E7E2F7E307E317E327E337E347E357E367E377E387E390000
+7E3A7E3C7E3D7E3E7E3F7E407E427E437E447E457E467E487E497E4A7E4B7E4C
+7E4D7E4E7E4F7E507E517E527E537E547E557E567E577E587E597E5A7E5B7E5C
+7E5D4FCA7AE36D5A90E19A8F55805496536154AF5F0063E9697751EF6168520A
+582A52D8574E780D770B5EB761777CE0625B62974EA27095800362F770E49760
+577782DB67EF68F578D5989779D158F354B353EF6E34514B523B5BA28BFE80AF
+554357A660735751542D7A7A60505B5463A762A053E362635BC767AF54ED7A9F
+82E691775E9388E4593857AE630E8DE880EF57577B774FA95FEB5BBD6B3E5321
+7B5072C2684677FF773665F751B54E8F76D45CBF7AA58475594E9B4150800000
+C0
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+7E5E7E5F7E607E617E627E637E647E657E667E677E687E697E6A7E6B7E6C7E6D
+7E6E7E6F7E707E717E727E737E747E757E767E777E787E797E7A7E7B7E7C7E7D
+7E7E7E7F7E807E817E837E847E857E867E877E887E897E8A7E8B7E8C7E8D7E8E
+7E8F7E907E917E927E937E947E957E967E977E987E997E9A7E9C7E9D7E9E0000
+7EAE7EB47EBB7EBC7ED67EE47EEC7EF97F0A7F107F1E7F377F397F3B7F3C7F3D
+7F3E7F3F7F407F417F437F467F477F487F497F4A7F4B7F4C7F4D7F4E7F4F7F52
+7F53998861276E8357646606634656F062EC62695ED39614578362C955878721
+814A8FA3556683B167658D5684DD5A6A680F62E67BEE961151706F9C8C3063FD
+89C861D27F0670C26EE57405699472FC5ECA90CE67176D6A635E52B372628001
+4F6C59E5916A70D96D9D52D24E5096F7956D857E78CA7D2F5121579264C2808B
+7C7B6CEA68F1695E51B7539868A872819ECE7BF172F879BB6F137406674E91CC
+9CA4793C83898354540F68174E3D538952B1783E5386522950884F8B4FD00000
+C1
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+7F567F597F5B7F5C7F5D7F5E7F607F637F647F657F667F677F6B7F6C7F6D7F6F
+7F707F737F757F767F777F787F7A7F7B7F7C7F7D7F7F7F807F827F837F847F85
+7F867F877F887F897F8B7F8D7F8F7F907F917F927F937F957F967F977F987F99
+7F9B7F9C7FA07FA27FA37FA57FA67FA87FA97FAA7FAB7FAC7FAD7FAE7FB10000
+7FB37FB47FB57FB67FB77FBA7FBB7FBE7FC07FC27FC37FC47FC67FC77FC87FC9
+7FCB7FCD7FCF7FD07FD17FD27FD37FD67FD77FD97FDA7FDB7FDC7FDD7FDE7FE2
+7FE375E27ACB7C926CA596B6529B748354E94FE9805483B28FDE95705EC9601C
+6D9F5E18655B813894FE604B70BC7EC37CAE51C968817CB1826F4E248F8691CF
+667E4EAE8C0564A9804A50DA759771CE5BE58FBD6F664E86648295635ED66599
+521788C270C852A3730E7433679778F797164E3490BB9CDE6DCB51DB8D41541D
+62CE73B283F196F69F8494C34F367F9A51CC707596755CAD988653E64EE46E9C
+740969B4786B998F7559521876246D4167F3516D9F99804B54997B3C7ABF0000
+C2
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+7FE47FE77FE87FEA7FEB7FEC7FED7FEF7FF27FF47FF57FF67FF77FF87FF97FFA
+7FFD7FFE7FFF8002800780088009800A800E800F80118013801A801B801D801E
+801F802180238024802B802C802D802E802F8030803280348039803A803C803E
+8040804180448045804780488049804E804F8050805180538055805680570000
+8059805B805C805D805E805F806080618062806380648065806680678068806B
+806C806D806E806F807080728073807480758076807780788079807A807B807C
+807D9686578462E29647697C5A0464027BD36F0F964B82A6536298855E907089
+63B35364864F9C819E93788C97328DEF8D429E7F6F5E79845F559646622E9A74
+541594DD4FA365C55C655C617F1586516C2F5F8B73876EE47EFF5CE6631B5B6A
+6EE653754E7163A0756562A18F6E4F264ED16CA67EB68BBA841D87BA7F57903B
+95237BA99AA188F8843D6D1B9A867EDC59889EBB739B780186829A6C9A82561B
+541757CB4E709EA653568FC881097792999286EE6EE1851366FC61626F2B0000
+C3
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+807E8081808280858088808A808D808E808F8090809180928094809580978099
+809E80A380A680A780A880AC80B080B380B580B680B880B980BB80C580C780C8
+80C980CA80CB80CF80D080D180D280D380D480D580D880DF80E080E280E380E6
+80EE80F580F780F980FB80FE80FF8100810181038104810581078108810B0000
+810C811581178119811B811C811D811F81208121812281238124812581268127
+81288129812A812B812D812E813081338134813581378139813A813B813C813D
+813F8C298292832B76F26C135FD983BD732B8305951A6BDB77DB94C6536F8302
+51925E3D8C8C8D384E4873AB679A68859176970971646CA177095A9295416BCF
+7F8E66275BD059B95A9A95E895F74EEC840C84996AAC76DF9530731B68A65B5F
+772F919A97617CDC8FF78C1C5F257C7379D889C56CCC871C5BC65E4268C97720
+7EF55195514D52C95A297F05976282D763CF778485D079D26E3A5E9959998511
+706D6C1162BF76BF654F60AF95FD660E879F9E2394ED540D547D8C2C64780000
+C4
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+81408141814281438144814581478149814D814E814F8152815681578158815B
+815C815D815E815F816181628163816481668168816A816B816C816F81728173
+81758176817781788181818381848185818681878189818B818C818D818E8190
+8192819381948195819681978199819A819E819F81A081A181A281A481A50000
+81A781A981AB81AC81AD81AE81AF81B081B181B281B481B581B681B781B881B9
+81BC81BD81BE81BF81C481C581C781C881C981CB81CD81CE81CF81D081D181D2
+81D3647986116A21819C78E864699B5462B9672B83AB58A89ED86CAB6F205BDE
+964C8C0B725F67D062C772614EA959C66BCD589366AE5E5552DF6155672876EE
+776672677A4662FF54EA545094A090A35A1C7EB36C164E435976801059485357
+753796BE56CA63208111607C95F96DD65462998151855AE980FD59AE9713502A
+6CE55C3C62DF4F60533F817B90066EBA852B62C85E7478BE64B5637B5FF55A18
+917F9E1F5C3F634F80425B7D556E954A954D6D8560A867E072DE51DD5B810000
+C5
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+81D481D581D681D781D881D981DA81DB81DC81DD81DE81DF81E081E181E281E4
+81E581E681E881E981EB81EE81EF81F081F181F281F581F681F781F881F981FA
+81FD81FF8203820782088209820A820B820E820F821182138215821682178218
+8219821A821D822082248225822682278229822E8232823A823C823D823F0000
+8240824182428243824582468248824A824C824D824E82508251825282538254
+8255825682578259825B825C825D825E82608261826282638264826582668267
+826962E76CDE725B626D94AE7EBD81136D53519C5F04597452AA601259736696
+8650759F632A61E67CEF8BFA54E66B279E256BB485D5545550766CA4556A8DB4
+722C5E156015743662CD6392724C5F986E436D3E65006F5876D878D076FC7554
+522453DB4E535E9E65C1802A80D6629B5486522870AE888D8DD16CE1547880DA
+57F988F48D54966A914D4F696C9B55B776C6783062A870F96F8E5F6D84EC68DA
+787C7BF781A8670B9E4F636778B0576F78129739627962AB528874356BD70000
+C6
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+826A826B826C826D82718275827682778278827B827C82808281828382858286
+82878289828C82908293829482958296829A829B829E82A082A282A382A782B2
+82B582B682BA82BB82BC82BF82C082C282C382C582C682C982D082D682D982DA
+82DD82E282E782E882E982EA82EC82ED82EE82F082F282F382F582F682F80000
+82FA82FC82FD82FE82FF8300830A830B830D831083128313831683188319831D
+831E831F83208321832283238324832583268329832A832E833083328337833B
+833D5564813E75B276AE533975DE50FB5C418B6C7BC7504F72479A9798D86F02
+74E27968648777A562FC98918D2B54C180584E52576A82F9840D5E7351ED74F6
+8BC45C4F57616CFC98875A4678349B448FEB7C955256625194FA4EC683868461
+83E984B257D467345703666E6D668C3166DD7011671F6B3A6816621A59BB4E03
+51C46F0667D26C8F517668CB59476B6775665D0E81109F5065D7794879419A91
+8D775C824E5E4F01542F5951780C56686C148FC45F036C7D6CE38BAB63900000
+C7
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+833E833F83418342834483458348834A834B834C834D834E8353835583568357
+83588359835D836283708371837283738374837583768379837A837E837F8380
+838183828383838483878388838A838B838C838D838F83908391839483958396
+83978399839A839D839F83A183A283A383A483A583A683A783AC83AD83AE0000
+83AF83B583BB83BE83BF83C283C383C483C683C883C983CB83CD83CE83D083D1
+83D283D383D583D783D983DA83DB83DE83E283E383E483E683E783E883EB83EC
+83ED60706D3D72756266948E94C553438FC17B7E4EDF8C264E7E9ED494B194B3
+524D6F5C90636D458C3458115D4C6B206B4967AA545B81547F8C589985375F3A
+62A26A47953965726084686577A74E544FA85DE7979864AC7FD85CED4FCF7A8D
+520783044E14602F7A8394A64FB54EB279E6743452E482B964D279BD5BDD6C81
+97528F7B6C22503E537F6E0564CE66746C3060C598778BF75E86743C7A7779CB
+4E1890B174036C4256DA914B6CC58D8B533A86C666F28EAF5C489A716E200000
+C8
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+83EE83EF83F383F483F583F683F783FA83FB83FC83FE83FF8400840284058407
+84088409840A84108412841384148415841684178419841A841B841E841F8420
+8421842284238429842A842B842C842D842E842F843084328433843484358436
+84378439843A843B843E843F8440844184428443844484458447844884490000
+844A844B844C844D844E844F8450845284538454845584568458845D845E845F
+8460846284648465846684678468846A846E846F84708472847484778479847B
+847C53D65A369F8B8DA353BB570898A76743919B6CC9516875CA62F372AC5238
+529D7F3A7094763853749E4A69B7786E96C088D97FA4713671C3518967D374E4
+58E4651856B78BA9997662707ED560F970ED58EC4EC14EBA5FCD97E74EFB8BA4
+5203598A7EAB62544ECD65E5620E833884C98363878D71946EB65BB97ED25197
+63C967D480898339881551125B7A59828FB14E736C5D516589258F6F962E854A
+745E951095F06DA682E55F3164926D128428816E9CC3585E8D5B4E0953C10000
+C9
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+847D847E847F848084818483848484858486848A848D848F8490849184928493
+8494849584968498849A849B849D849E849F84A084A284A384A484A584A684A7
+84A884A984AA84AB84AC84AD84AE84B084B184B384B584B684B784BB84BC84BE
+84C084C284C384C584C684C784C884CB84CC84CE84CF84D284D484D584D70000
+84D884D984DA84DB84DC84DE84E184E284E484E784E884E984EA84EB84ED84EE
+84EF84F184F284F384F484F584F684F784F884F984FA84FB84FD84FE85008501
+85024F1E6563685155D34E2764149A9A626B5AC2745F82726DA968EE50E7838E
+7802674052396C997EB150BB5565715E7B5B665273CA82EB67495C715220717D
+886B95EA965564C58D6181B355846C5562477F2E58924F2455468D4F664C4E0A
+5C1A88F368A2634E7A0D70E7828D52FA97F65C1154E890B57ECD59628D4A86C7
+820C820D8D6664445C0461516D89793E8BBE78377533547B4F388EAB6DF15A20
+7EC5795E6C885BA15A76751A80BE614E6E1758F0751F7525727253477EF30000
+CA
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+8503850485058506850785088509850A850B850D850E850F8510851285148515
+851685188519851B851C851D851E852085228523852485258526852785288529
+852A852D852E852F8530853185328533853485358536853E853F854085418542
+8544854585468547854B854C854D854E854F8550855185528553855485550000
+85578558855A855B855C855D855F85608561856285638565856685678569856A
+856B856C856D856E856F8570857185738575857685778578857C857D857F8580
+8581770176DB526980DC57235E08593172EE65BD6E7F8BD75C388671534177F3
+62FE65F64EC098DF86805B9E8BC653F277E24F7F5C4E9A7659CB5F0F793A58EB
+4E1667FF4E8B62ED8A93901D52BF662F55DC566C90024ED54F8D91CA99706C0F
+5E0260435BA489C68BD56536624B99965B885BFF6388552E53D77626517D852C
+67A268B36B8A62928F9353D482126DD1758F4E668D4E5B70719F85AF669166D9
+7F7287009ECD9F205C5E672F8FF06811675F620D7AD658855EB665706F310000
+CB
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+85828583858685888589858A858B858C858D858E859085918592859385948595
+8596859785988599859A859D859E859F85A085A185A285A385A585A685A785A9
+85AB85AC85AD85B185B285B385B485B585B685B885BA85BB85BC85BD85BE85BF
+85C085C285C385C485C585C685C785C885CA85CB85CC85CD85CE85D185D20000
+85D485D685D785D885D985DA85DB85DD85DE85DF85E085E185E285E385E585E6
+85E785E885EA85EB85EC85ED85EE85EF85F085F185F285F385F485F585F685F7
+85F860555237800D6454887075295E05681362F4971C53CC723D8C016C347761
+7A0E542E77AC987A821C8BF47855671470C165AF64955636601D79C153F84E1D
+6B7B80865BFA55E356DB4F3A4F3C99725DF3677E80386002988290015B8B8BBC
+8BF5641C825864DE55FD82CF91654FD77D20901F7C9F50F358516EAF5BBF8BC9
+80839178849C7B97867D968B968F7EE59AD3788E5C817A57904296A7795F5B59
+635F7B0B84D168AD55067F2974107D2295016240584C4ED65B83597958540000
+CC
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+85F985FA85FC85FD85FE860086018602860386048606860786088609860A860B
+860C860D860E860F86108612861386148615861786188619861A861B861C861D
+861E861F86208621862286238624862586268628862A862B862C862D862E862F
+863086318632863386348635863686378639863A863B863D863E863F86400000
+864186428643864486458646864786488649864A864B864C8652865386558656
+865786588659865B865C865D865F866086618663866486658666866786688669
+866A736D631E8E4B8E0F80CE82D462AC53F06CF0915E592A60016C70574D644A
+8D2A762B6EE9575B6A8075F06F6D8C2D8C0857666BEF889278B363A253F970AD
+6C645858642A580268E0819B55107CD650188EBA6DCC8D9F70EB638F6D9B6ED4
+7EE68404684390036DD896768BA85957727985E4817E75BC8A8A68AF52548E22
+951163D098988E44557C4F5366FF568F60D56D9552435C4959296DFB586B7530
+751C606C82148146631167618FE2773A8DF38D3494C15E165385542C70C30000
+CD
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+866D866F86708672867386748675867686778678868386848685868686878688
+8689868E868F86908691869286948696869786988699869A869B869E869F86A0
+86A186A286A586A686AB86AD86AE86B286B386B786B886B986BB86BC86BD86BE
+86BF86C186C286C386C586C886CC86CD86D286D386D586D686D786DA86DC0000
+86DD86E086E186E286E386E586E686E786E886EA86EB86EC86EF86F586F686F7
+86FA86FB86FC86FD86FF8701870487058706870B870C870E870F871087118714
+87166C405EF7505C4EAD5EAD633A8247901A6850916E77B3540C94DC5F647AE5
+687663457B527EDF75DB507762955934900F51F879C37A8156FE5F9290146D82
+5C60571F541051546E4D56E263A89893817F8715892A9000541E5C6F81C062D6
+625881319E3596409A6E9A7C692D59A562D3553E631654C786D96D3C5A0374E6
+889C6B6A59168C4C5F2F6E7E73A9987D4E3870F75B8C7897633D665A769660CB
+5B9B5A494E0781556C6A738B4EA167897F515F8065FA671B5FD859845A010000
+CE
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+8719871B871D871F87208724872687278728872A872B872C872D872F87308732
+87338735873687388739873A873C873D8740874187428743874487458746874A
+874B874D874F8750875187528754875587568758875A875B875C875D875E875F
+876187628766876787688769876A876B876C876D876F87718772877387750000
+877787788779877A877F878087818784878687878789878A878C878E878F8790
+8791879287948795879687988799879A879B879C879D879E87A087A187A287A3
+87A45DCD5FAE537197E68FDD684556F4552F60DF4E3A6F4D7EF482C7840E59D4
+4F1F4F2A5C3E7EAC672A851A5473754F80C355829B4F4F4D6E2D8C135C096170
+536B761F6E29868A658795FB7EB9543B7A337D0A95EE55E17FC174EE631D8717
+6DA17A9D621165A1536763E16C835DEB545C94A84E4C6C618BEC5C4B65E0829C
+68A7543E54346BCB6B664E9463425348821E4F0D4FAE575E620A96FE66647269
+52FF52A1609F8BEF661471996790897F785277FD6670563B54389521727A0000
+CF
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+87A587A687A787A987AA87AE87B087B187B287B487B687B787B887B987BB87BC
+87BE87BF87C187C287C387C487C587C787C887C987CC87CD87CE87CF87D087D4
+87D587D687D787D887D987DA87DC87DD87DE87DF87E187E287E387E487E687E7
+87E887E987EB87EC87ED87EF87F087F187F287F387F487F587F687F787F80000
+87FA87FB87FC87FD87FF880088018802880488058806880788088809880B880C
+880D880E880F8810881188128814881788188819881A881C881D881E881F8820
+88237A00606F5E0C6089819D591560DC718470EF6EAA6C5072806A8488AD5E2D
+4E605AB3559C94E36D177CFB9699620F7EC6778E867E5323971E8F9666875CE1
+4FA072ED4E0B53A6590F54136380952851484ED99C9C7EA454B88D2488548237
+95F26D8E5F265ACC663E966973B0732E53BF817A99857FA15BAA967796507EBF
+76F853A2957699997BB189446E584E617FD479658BE660F354CD4EAB98795DF7
+6A6150CF54118C618427785D9704524A54EE56A395006D885BB56DC666530000
+D0
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+882488258826882788288829882A882B882C882D882E882F8830883188338834
+8835883688378838883A883B883D883E883F8841884288438846884788488849
+884A884B884E884F8850885188528853885588568858885A885B885C885D885E
+885F886088668867886A886D886F8871887388748875887688788879887A0000
+887B887C88808883888688878889888A888C888E888F88908891889388948895
+889788988899889A889B889D889E889F88A088A188A388A588A688A788A888A9
+88AA5C0F5B5D6821809655787B11654869544E9B6B47874E978B534F631F643A
+90AA659C80C18C10519968B0537887F961C86CC46CFB8C225C5185AA82AF950C
+6B238F9B65B05FFB5FC34FE18845661F8165732960FA51745211578B5F6290A2
+884C91925E78674F602759D3514451F680F853086C7996C4718A4F114FEE7F9E
+673D55C5950879C088967EE3589F620C9700865A5618987B5F908BB884C49157
+53D965ED5E8F755C60647D6E5A7F7EEA7EED8F6955A75BA360AC65CB73840000
+D1
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+88AC88AE88AF88B088B288B388B488B588B688B888B988BA88BB88BD88BE88BF
+88C088C388C488C788C888CA88CB88CC88CD88CF88D088D188D388D688D788DA
+88DB88DC88DD88DE88E088E188E688E788E988EA88EB88EC88ED88EE88EF88F2
+88F588F688F788FA88FB88FD88FF890089018903890489058906890789080000
+8909890B890C890D890E890F891189148915891689178918891C891D891E891F
+89208922892389248926892789288929892C892D892E892F8931893289338935
+89379009766377297EDA9774859B5B667A7496EA884052CB718F5FAA65EC8BE2
+5BFB9A6F5DE16B896C5B8BAD8BAF900A8FC5538B62BC9E269E2D54404E2B82BD
+7259869C5D1688596DAF96C554D14E9A8BB6710954BD960970DF6DF976D04E25
+781487125CA95EF68A00989C960E708E6CBF594463A9773C884D6F1482735830
+71D5538C781A96C155015F6671305BB48C1A9A8C6B83592E9E2F79E76768626C
+4F6F75A17F8A6D0B96336C274EF075D2517B68376F3E90808170599674760000
+D2
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+89388939893A893B893C893D893E893F89408942894389458946894789488949
+894A894B894C894D894E894F8950895189528953895489558956895789588959
+895A895B895C895D896089618962896389648965896789688969896A896B896C
+896D896E896F8970897189728973897489758976897789788979897A897C0000
+897D897E8980898289848985898789888989898A898B898C898D898E898F8990
+899189928993899489958996899789988999899A899B899C899D899E899F89A0
+89A164475C2790657A918C2359DA54AC8200836F898180006930564E80367237
+91CE51B64E5F987563964E1A53F666F3814B591C6DB24E0058F9533B63D694F1
+4F9D4F0A886398905937905779FB4EEA80F075916C825B9C59E85F5D69058681
+501A5DF24E5977E34EE5827A6291661390915C794EBF5F7981C69038808475AB
+4EA688D4610F6BC55FC64E4976CA6EA28BE38BAE8C0A8BD15F027FFC7FCC7ECE
+8335836B56E06BB797F3963459FB541F94F66DEB5BC5996E5C395F1596900000
+D3
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+89A289A389A489A589A689A789A889A989AA89AB89AC89AD89AE89AF89B089B1
+89B289B389B489B589B689B789B889B989BA89BB89BC89BD89BE89BF89C089C3
+89CD89D389D489D589D789D889D989DB89DD89DF89E089E189E289E489E789E8
+89E989EA89EC89ED89EE89F089F189F289F489F589F689F789F889F989FA0000
+89FB89FC89FD89FE89FF8A018A028A038A048A058A068A088A098A0A8A0B8A0C
+8A0D8A0E8A0F8A108A118A128A138A148A158A168A178A188A198A1A8A1B8A1C
+8A1D537082F16A315A749E705E947F2883B984248425836787478FCE8D6276C8
+5F719896786C662054DF62E54F6381C375C85EB896CD8E0A86F9548F6CF36D8C
+6C38607F52C775285E7D4F1860A05FE75C24753190AE94C072B96CB96E389149
+670953CB53F34F5191C98BF153C85E7C8FC26DE44E8E76C26986865E611A8206
+4F594FDE903E9C7C61096E1D6E1496854E885A3196E84E0E5C7F79B95B878BED
+7FBD738957DF828B90C15401904755BB5CEA5FA161086B3272F180B28A890000
+D4
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+8A1E8A1F8A208A218A228A238A248A258A268A278A288A298A2A8A2B8A2C8A2D
+8A2E8A2F8A308A318A328A338A348A358A368A378A388A398A3A8A3B8A3C8A3D
+8A3F8A408A418A428A438A448A458A468A478A498A4A8A4B8A4C8A4D8A4E8A4F
+8A508A518A528A538A548A558A568A578A588A598A5A8A5B8A5C8A5D8A5E0000
+8A5F8A608A618A628A638A648A658A668A678A688A698A6A8A6B8A6C8A6D8A6E
+8A6F8A708A718A728A738A748A758A768A778A788A7A8A7B8A7C8A7D8A7E8A7F
+8A806D745BD388D598848C6B9A6D9E336E0A51A4514357A38881539F63F48F95
+56ED54585706733F6E907F188FDC82D1613F6028966266F07EA68D8A8DC394A5
+5CB37CA4670860A6960580184E9190E75300966851418FD08574915D665597F5
+5B55531D78386742683D54C9707E5BB08F7D518D572854B1651266828D5E8D43
+810F846C906D7CDF51FF85FB67A365E96FA186A48E81566A90207682707671E5
+8D2362E952196CFD8D3C600E589E618E66FE8D60624E55B36E23672D8F670000
+D5
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+8A818A828A838A848A858A868A878A888A8B8A8C8A8D8A8E8A8F8A908A918A92
+8A948A958A968A978A988A998A9A8A9B8A9C8A9D8A9E8A9F8AA08AA18AA28AA3
+8AA48AA58AA68AA78AA88AA98AAA8AAB8AAC8AAD8AAE8AAF8AB08AB18AB28AB3
+8AB48AB58AB68AB78AB88AB98ABA8ABB8ABC8ABD8ABE8ABF8AC08AC18AC20000
+8AC38AC48AC58AC68AC78AC88AC98ACA8ACB8ACC8ACD8ACE8ACF8AD08AD18AD2
+8AD38AD48AD58AD68AD78AD88AD98ADA8ADB8ADC8ADD8ADE8ADF8AE08AE18AE2
+8AE394E195F87728680569A8548B4E4D70B88BC86458658B5B857A84503A5BE8
+77BB6BE18A797C986CBE76CF65A98F975D2D5C5586386808536062187AD96E5B
+7EFD6A1F7AE05F706F335F20638C6DA867564E085E108D264ED780C07634969C
+62DB662D627E6CBC8D7571677F695146808753EC906E629854F286F08F998005
+951785178FD96D5973CD659F771F7504782781FB8D1E94884FA6679575B98BCA
+9707632F9547963584B8632377415F8172F04E896014657462EF6B63653F0000
+D6
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+8AE48AE58AE68AE78AE88AE98AEA8AEB8AEC8AED8AEE8AEF8AF08AF18AF28AF3
+8AF48AF58AF68AF78AF88AF98AFA8AFB8AFC8AFD8AFE8AFF8B008B018B028B03
+8B048B058B068B088B098B0A8B0B8B0C8B0D8B0E8B0F8B108B118B128B138B14
+8B158B168B178B188B198B1A8B1B8B1C8B1D8B1E8B1F8B208B218B228B230000
+8B248B258B278B288B298B2A8B2B8B2C8B2D8B2E8B2F8B308B318B328B338B34
+8B358B368B378B388B398B3A8B3B8B3C8B3D8B3E8B3F8B408B418B428B438B44
+8B455E2775C790D18BC1829D679D652F5431871877E580A281026C414E4B7EC7
+804C76F4690D6B966267503C4F84574063076B628DBE53EA65E87EB85FD7631A
+63B781F381F47F6E5E1C5CD95236667A79E97A1A8D28709975D46EDE6CBB7A92
+4E2D76C55FE0949F88777EC879CD80BF91CD4EF24F17821F54685DDE6D328BCC
+7CA58F7480985E1A549276B15B99663C9AA473E0682A86DB6731732A8BF88BDB
+90107AF970DB716E62C477A956314E3B845767F152A986C08D2E94F87B510000
+D7
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+8B468B478B488B498B4A8B4B8B4C8B4D8B4E8B4F8B508B518B528B538B548B55
+8B568B578B588B598B5A8B5B8B5C8B5D8B5E8B5F8B608B618B628B638B648B65
+8B678B688B698B6A8B6B8B6D8B6E8B6F8B708B718B728B738B748B758B768B77
+8B788B798B7A8B7B8B7C8B7D8B7E8B7F8B808B818B828B838B848B858B860000
+8B878B888B898B8A8B8B8B8C8B8D8B8E8B8F8B908B918B928B938B948B958B96
+8B978B988B998B9A8B9B8B9C8B9D8B9E8B9F8BAC8BB18BBB8BC78BD08BEA8C09
+8C1E4F4F6CE8795D9A7B6293722A62FD4E1378168F6C64B08D5A7BC668695E84
+88C55986649E58EE72B6690E95258FFD8D5857607F008C0651C6634962D95353
+684C74228301914C55447740707C6D4A517954A88D4459FF6ECB6DC45B5C7D2B
+4ED47C7D6ED35B5081EA6E0D5B579B0368D58E2A5B977EFC603B7EB590B98D70
+594F63CD79DF8DB3535265CF79568BC5963B7EC494BB7E825634918967007F6A
+5C0A907566285DE64F5067DE505A4F5C57505EA7000000000000000000000000
+D8
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+8C388C398C3A8C3B8C3C8C3D8C3E8C3F8C408C428C438C448C458C488C4A8C4B
+8C4D8C4E8C4F8C508C518C528C538C548C568C578C588C598C5B8C5C8C5D8C5E
+8C5F8C608C638C648C658C668C678C688C698C6C8C6D8C6E8C6F8C708C718C72
+8C748C758C768C778C7B8C7C8C7D8C7E8C7F8C808C818C838C848C868C870000
+8C888C8B8C8D8C8E8C8F8C908C918C928C938C958C968C978C998C9A8C9B8C9C
+8C9D8C9E8C9F8CA08CA18CA28CA38CA48CA58CA68CA78CA88CA98CAA8CAB8CAC
+8CAD4E8D4E0C51404E105EFF53454E154E984E1E9B325B6C56694E2879BA4E3F
+53154E47592D723B536E6C1056DF80E499976BD3777E9F174E364E9F9F104E5C
+4E694E9382885B5B556C560F4EC4538D539D53A353A553AE97658D5D531A53F5
+5326532E533E8D5C5366536352025208520E522D5233523F5240524C525E5261
+525C84AF527D528252815290529351827F544EBB4EC34EC94EC24EE84EE14EEB
+4EDE4F1B4EF34F224F644EF54F254F274F094F2B4F5E4F6765384F5A4F5D0000
+D9
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+8CAE8CAF8CB08CB18CB28CB38CB48CB58CB68CB78CB88CB98CBA8CBB8CBC8CBD
+8CBE8CBF8CC08CC18CC28CC38CC48CC58CC68CC78CC88CC98CCA8CCB8CCC8CCD
+8CCE8CCF8CD08CD18CD28CD38CD48CD58CD68CD78CD88CD98CDA8CDB8CDC8CDD
+8CDE8CDF8CE08CE18CE28CE38CE48CE58CE68CE78CE88CE98CEA8CEB8CEC0000
+8CED8CEE8CEF8CF08CF18CF28CF38CF48CF58CF68CF78CF88CF98CFA8CFB8CFC
+8CFD8CFE8CFF8D008D018D028D038D048D058D068D078D088D098D0A8D0B8D0C
+8D0D4F5F4F574F324F3D4F764F744F914F894F834F8F4F7E4F7B4FAA4F7C4FAC
+4F944FE64FE84FEA4FC54FDA4FE34FDC4FD14FDF4FF85029504C4FF3502C500F
+502E502D4FFE501C500C50255028507E504350555048504E506C507B50A550A7
+50A950BA50D6510650ED50EC50E650EE5107510B4EDD6C3D4F584F654FCE9FA0
+6C467C74516E5DFD9EC999985181591452F9530D8A07531051EB591951554EA0
+51564EB3886E88A44EB5811488D279805B3488037FB851AB51B151BD51BC0000
+DA
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+8D0E8D0F8D108D118D128D138D148D158D168D178D188D198D1A8D1B8D1C8D20
+8D518D528D578D5F8D658D688D698D6A8D6C8D6E8D6F8D718D728D788D798D7A
+8D7B8D7C8D7D8D7E8D7F8D808D828D838D868D878D888D898D8C8D8D8D8E8D8F
+8D908D928D938D958D968D978D988D998D9A8D9B8D9C8D9D8D9E8DA08DA10000
+8DA28DA48DA58DA68DA78DA88DA98DAA8DAB8DAC8DAD8DAE8DAF8DB08DB28DB6
+8DB78DB98DBB8DBD8DC08DC18DC28DC58DC78DC88DC98DCA8DCD8DD08DD28DD3
+8DD451C7519651A251A58BA08BA68BA78BAA8BB48BB58BB78BC28BC38BCB8BCF
+8BCE8BD28BD38BD48BD68BD88BD98BDC8BDF8BE08BE48BE88BE98BEE8BF08BF3
+8BF68BF98BFC8BFF8C008C028C048C078C0C8C0F8C118C128C148C158C168C19
+8C1B8C188C1D8C1F8C208C218C258C278C2A8C2B8C2E8C2F8C328C338C358C36
+5369537A961D962296219631962A963D963C964296499654965F9667966C9672
+96749688968D969796B09097909B909D909990AC90A190B490B390B690BA0000
+DB
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+8DD58DD88DD98DDC8DE08DE18DE28DE58DE68DE78DE98DED8DEE8DF08DF18DF2
+8DF48DF68DFC8DFE8DFF8E008E018E028E038E048E068E078E088E0B8E0D8E0E
+8E108E118E128E138E158E168E178E188E198E1A8E1B8E1C8E208E218E248E25
+8E268E278E288E2B8E2D8E308E328E338E348E368E378E388E3B8E3C8E3E0000
+8E3F8E438E458E468E4C8E4D8E4E8E4F8E508E538E548E558E568E578E588E5A
+8E5B8E5C8E5D8E5E8E5F8E608E618E628E638E648E658E678E688E6A8E6B8E6E
+8E7190B890B090CF90C590BE90D090C490C790D390E690E290DC90D790DB90EB
+90EF90FE91049122911E91239131912F913991439146520D594252A252AC52AD
+52BE54FF52D052D652F053DF71EE77CD5EF451F551FC9B2F53B65F01755A5DEF
+574C57A957A1587E58BC58C558D15729572C572A57335739572E572F575C573B
+574257695785576B5786577C577B5768576D5776577357AD57A4578C57B257CF
+57A757B4579357A057D557D857DA57D957D257B857F457EF57F857E457DD0000
+DC
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+8E738E758E778E788E798E7A8E7B8E7D8E7E8E808E828E838E848E868E888E89
+8E8A8E8B8E8C8E8D8E8E8E918E928E938E958E968E978E988E998E9A8E9B8E9D
+8E9F8EA08EA18EA28EA38EA48EA58EA68EA78EA88EA98EAA8EAD8EAE8EB08EB1
+8EB38EB48EB58EB68EB78EB88EB98EBB8EBC8EBD8EBE8EBF8EC08EC18EC20000
+8EC38EC48EC58EC68EC78EC88EC98ECA8ECB8ECC8ECD8ECF8ED08ED18ED28ED3
+8ED48ED58ED68ED78ED88ED98EDA8EDB8EDC8EDD8EDE8EDF8EE08EE18EE28EE3
+8EE4580B580D57FD57ED5800581E5819584458205865586C58815889589A5880
+99A89F1961FF8279827D827F828F828A82A88284828E82918297829982AB82B8
+82BE82B082C882CA82E3829882B782AE82CB82CC82C182A982B482A182AA829F
+82C482CE82A482E1830982F782E4830F830782DC82F482D282D8830C82FB82D3
+8311831A83068314831582E082D5831C8351835B835C83088392833C83348331
+839B835E832F834F83478343835F834083178360832D833A8333836683650000
+DD
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+8EE58EE68EE78EE88EE98EEA8EEB8EEC8EED8EEE8EEF8EF08EF18EF28EF38EF4
+8EF58EF68EF78EF88EF98EFA8EFB8EFC8EFD8EFE8EFF8F008F018F028F038F04
+8F058F068F078F088F098F0A8F0B8F0C8F0D8F0E8F0F8F108F118F128F138F14
+8F158F168F178F188F198F1A8F1B8F1C8F1D8F1E8F1F8F208F218F228F230000
+8F248F258F268F278F288F298F2A8F2B8F2C8F2D8F2E8F2F8F308F318F328F33
+8F348F358F368F378F388F398F3A8F3B8F3C8F3D8F3E8F3F8F408F418F428F43
+8F448368831B8369836C836A836D836E83B0837883B383B483A083AA8393839C
+8385837C83B683A9837D83B8837B8398839E83A883BA83BC83C1840183E583D8
+58078418840B83DD83FD83D6841C84388411840683D483DF840F840383F883F9
+83EA83C583C0842683F083E1845C8451845A8459847384878488847A84898478
+843C844684698476848C848E8431846D84C184CD84D084E684BD84D384CA84BF
+84BA84E084A184B984B4849784E584E3850C750D853884F08539851F853A0000
+DE
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+8F458F468F478F488F498F4A8F4B8F4C8F4D8F4E8F4F8F508F518F528F538F54
+8F558F568F578F588F598F5A8F5B8F5C8F5D8F5E8F5F8F608F618F628F638F64
+8F658F6A8F808F8C8F928F9D8FA08FA18FA28FA48FA58FA68FA78FAA8FAC8FAD
+8FAE8FAF8FB28FB38FB48FB58FB78FB88FBA8FBB8FBC8FBF8FC08FC38FC60000
+8FC98FCA8FCB8FCC8FCD8FCF8FD28FD68FD78FDA8FE08FE18FE38FE78FEC8FEF
+8FF18FF28FF48FF58FF68FFA8FFB8FFC8FFE8FFF90079008900C900E90139015
+90188556853B84FF84FC8559854885688564855E857A77A285438572857B85A4
+85A88587858F857985AE859C858585B985B785B085D385C185DC85FF86278605
+86298616863C5EFE5F08593C594180375955595A5958530F5C225C255C2C5C34
+624C626A629F62BB62CA62DA62D762EE632262F66339634B634363AD63F66371
+637A638E63B4636D63AC638A636963AE63BC63F263F863E063FF63C463DE63CE
+645263C663BE64456441640B641B6420640C64266421645E6484646D64960000
+DF
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+9019901C902390249025902790289029902A902B902C90309031903290339034
+90379039903A903D903F904090439045904690489049904A904B904C904E9054
+905590569059905A905C905D905E905F906090619064906690679069906A906B
+906C906F90709071907290739076907790789079907A907B907C907E90810000
+90849085908690879089908A908C908D908E908F90909092909490969098909A
+909C909E909F90A090A490A590A790A890A990AB90AD90B290B790BC90BD90BF
+90C0647A64B764B8649964BA64C064D064D764E464E265096525652E5F0B5FD2
+75195F11535F53F153FD53E953E853FB541254165406544B5452545354545456
+54435421545754595423543254825494547754715464549A549B548454765466
+549D54D054AD54C254B454D254A754A654D354D4547254A354D554BB54BF54CC
+54D954DA54DC54A954AA54A454DD54CF54DE551B54E7552054FD551454F35522
+5523550F55115527552A5567558F55B55549556D55415555553F5550553C0000
+E0
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+90C290C390C690C890C990CB90CC90CD90D290D490D590D690D890D990DA90DE
+90DF90E090E390E490E590E990EA90EC90EE90F090F190F290F390F590F690F7
+90F990FA90FB90FC90FF91009101910391059106910791089109910A910B910C
+910D910E910F911091119112911391149115911691179118911A911B911C0000
+911D911F91209121912491259126912791289129912A912B912C912D912E9130
+9132913391349135913691379138913A913B913C913D913E913F914091419142
+91445537555655755576557755335530555C558B55D2558355B155B955885581
+559F557E55D65591557B55DF55BD55BE5594559955EA55F755C9561F55D155EB
+55EC55D455E655DD55C455EF55E555F255F355CC55CD55E855F555E48F94561E
+5608560C56015624562355FE56005627562D565856395657562C564D56625659
+565C564C5654568656645671566B567B567C5685569356AF56D456D756DD56E1
+56F556EB56F956FF5704570A5709571C5E0F5E195E145E115E315E3B5E3C0000
+E1
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+9145914791489151915391549155915691589159915B915C915F916091669167
+9168916B916D9173917A917B917C9180918191829183918491869188918A918E
+918F9193919491959196919791989199919C919D919E919F91A091A191A491A5
+91A691A791A891A991AB91AC91B091B191B291B391B691B791B891B991BB0000
+91BC91BD91BE91BF91C091C191C291C391C491C591C691C891CB91D091D291D3
+91D491D591D691D791D891D991DA91DB91DD91DE91DF91E091E191E291E391E4
+91E55E375E445E545E5B5E5E5E615C8C5C7A5C8D5C905C965C885C985C995C91
+5C9A5C9C5CB55CA25CBD5CAC5CAB5CB15CA35CC15CB75CC45CD25CE45CCB5CE5
+5D025D035D275D265D2E5D245D1E5D065D1B5D585D3E5D345D3D5D6C5D5B5D6F
+5D5D5D6B5D4B5D4A5D695D745D825D995D9D8C735DB75DC55F735F775F825F87
+5F895F8C5F955F995F9C5FA85FAD5FB55FBC88625F6172AD72B072B472B772B8
+72C372C172CE72CD72D272E872EF72E972F272F472F7730172F3730372FA0000
+E2
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+91E691E791E891E991EA91EB91EC91ED91EE91EF91F091F191F291F391F491F5
+91F691F791F891F991FA91FB91FC91FD91FE91FF920092019202920392049205
+9206920792089209920A920B920C920D920E920F921092119212921392149215
+9216921792189219921A921B921C921D921E921F922092219222922392240000
+92259226922792289229922A922B922C922D922E922F92309231923292339234
+92359236923792389239923A923B923C923D923E923F92409241924292439244
+924572FB731773137321730A731E731D7315732273397325732C733873317350
+734D73577360736C736F737E821B592598E7592459029963996799689969996A
+996B996C99749977997D998099849987998A998D999099919993999499955E80
+5E915E8B5E965EA55EA05EB95EB55EBE5EB38D535ED25ED15EDB5EE85EEA81BA
+5FC45FC95FD65FCF60035FEE60045FE15FE45FFE600560065FEA5FED5FF86019
+60356026601B600F600D6029602B600A603F602160786079607B607A60420000
+E3
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+9246924792489249924A924B924C924D924E924F925092519252925392549255
+9256925792589259925A925B925C925D925E925F926092619262926392649265
+9266926792689269926A926B926C926D926E926F927092719272927392759276
+927792789279927A927B927C927D927E927F9280928192829283928492850000
+9286928792889289928A928B928C928D928F9290929192929293929492959296
+929792989299929A929B929C929D929E929F92A092A192A292A392A492A592A6
+92A7606A607D6096609A60AD609D60836092608C609B60EC60BB60B160DD60D8
+60C660DA60B4612061266115612360F46100610E612B614A617561AC619461A7
+61B761D461F55FDD96B395E995EB95F195F395F595F695FC95FE960396049606
+9608960A960B960C960D960F96129615961696179619961A4E2C723F62156C35
+6C546C5C6C4A6CA36C856C906C946C8C6C686C696C746C766C866CA96CD06CD4
+6CAD6CF76CF86CF16CD76CB26CE06CD66CFA6CEB6CEE6CB16CD36CEF6CFE0000
+E4
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+92A892A992AA92AB92AC92AD92AF92B092B192B292B392B492B592B692B792B8
+92B992BA92BB92BC92BD92BE92BF92C092C192C292C392C492C592C692C792C9
+92CA92CB92CC92CD92CE92CF92D092D192D292D392D492D592D692D792D892D9
+92DA92DB92DC92DD92DE92DF92E092E192E292E392E492E592E692E792E80000
+92E992EA92EB92EC92ED92EE92EF92F092F192F292F392F492F592F692F792F8
+92F992FA92FB92FC92FD92FE92FF930093019302930393049305930693079308
+93096D396D276D0C6D436D486D076D046D196D0E6D2B6D4D6D2E6D356D1A6D4F
+6D526D546D336D916D6F6D9E6DA06D5E6D936D946D5C6D606D7C6D636E1A6DC7
+6DC56DDE6E0E6DBF6DE06E116DE66DDD6DD96E166DAB6E0C6DAE6E2B6E6E6E4E
+6E6B6EB26E5F6E866E536E546E326E256E446EDF6EB16E986EE06F2D6EE26EA5
+6EA76EBD6EBB6EB76ED76EB46ECF6E8F6EC26E9F6F626F466F476F246F156EF9
+6F2F6F366F4B6F746F2A6F096F296F896F8D6F8C6F786F726F7C6F7A6FD10000
+E5
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+930A930B930C930D930E930F9310931193129313931493159316931793189319
+931A931B931C931D931E931F9320932193229323932493259326932793289329
+932A932B932C932D932E932F9330933193329333933493359336933793389339
+933A933B933C933D933F93409341934293439344934593469347934893490000
+934A934B934C934D934E934F9350935193529353935493559356935793589359
+935A935B935C935D935E935F9360936193629363936493659366936793689369
+936B6FC96FA76FB96FB66FC26FE16FEE6FDE6FE06FEF701A7023701B70397035
+704F705E5B805B845B955B935BA55BB8752F9A9E64345BE45BEE89305BF08E47
+8B078FB68FD38FD58FE58FEE8FE48FE98FE68FF38FE890059004900B90269011
+900D9016902190359036902D902F9044905190529050906890589062905B66B9
+9074907D908290889083908B5F505F575F565F585C3B54AB5C505C595B715C63
+5C667FBC5F2A5F295F2D82745F3C9B3B5C6E59815983598D59A959AA59A30000
+E6
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+936C936D936E936F9370937193729373937493759376937793789379937A937B
+937C937D937E937F9380938193829383938493859386938793889389938A938B
+938C938D938E9390939193929393939493959396939793989399939A939B939C
+939D939E939F93A093A193A293A393A493A593A693A793A893A993AA93AB0000
+93AC93AD93AE93AF93B093B193B293B393B493B593B693B793B893B993BA93BB
+93BC93BD93BE93BF93C093C193C293C393C493C593C693C793C893C993CB93CC
+93CD599759CA59AB599E59A459D259B259AF59D759BE5A055A0659DD5A0859E3
+59D859F95A0C5A095A325A345A115A235A135A405A675A4A5A555A3C5A625A75
+80EC5AAA5A9B5A775A7A5ABE5AEB5AB25AD25AD45AB85AE05AE35AF15AD65AE6
+5AD85ADC5B095B175B165B325B375B405C155C1C5B5A5B655B735B515B535B62
+9A759A779A789A7A9A7F9A7D9A809A819A859A889A8A9A909A929A939A969A98
+9A9B9A9C9A9D9A9F9AA09AA29AA39AA59AA77E9F7EA17EA37EA57EA87EA90000
+E7
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+93CE93CF93D093D193D293D393D493D593D793D893D993DA93DB93DC93DD93DE
+93DF93E093E193E293E393E493E593E693E793E893E993EA93EB93EC93ED93EE
+93EF93F093F193F293F393F493F593F693F793F893F993FA93FB93FC93FD93FE
+93FF9400940194029403940494059406940794089409940A940B940C940D0000
+940E940F9410941194129413941494159416941794189419941A941B941C941D
+941E941F9420942194229423942494259426942794289429942A942B942C942D
+942E7EAD7EB07EBE7EC07EC17EC27EC97ECB7ECC7ED07ED47ED77EDB7EE07EE1
+7EE87EEB7EEE7EEF7EF17EF27F0D7EF67EFA7EFB7EFE7F017F027F037F077F08
+7F0B7F0C7F0F7F117F127F177F197F1C7F1B7F1F7F217F227F237F247F257F26
+7F277F2A7F2B7F2C7F2D7F2F7F307F317F327F337F355E7A757F5DDB753E9095
+738E739173AE73A2739F73CF73C273D173B773B373C073C973C873E573D9987C
+740A73E973E773DE73BA73F2740F742A745B7426742574287430742E742C0000
+E8
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+942F9430943194329433943494359436943794389439943A943B943C943D943F
+9440944194429443944494459446944794489449944A944B944C944D944E944F
+9450945194529453945494559456945794589459945A945B945C945D945E945F
+9460946194629463946494659466946794689469946A946C946D946E946F0000
+9470947194729473947494759476947794789479947A947B947C947D947E947F
+9480948194829483948494919496949894C794CF94D394D494DA94E694FB951C
+9520741B741A7441745C7457745574597477746D747E749C748E748074817487
+748B749E74A874A9749074A774D274BA97EA97EB97EC674C6753675E67486769
+67A56787676A6773679867A7677567A8679E67AD678B6777677C67F0680967D8
+680A67E967B0680C67D967B567DA67B367DD680067C367B867E2680E67C167FD
+6832683368606861684E6862684468646883681D68556866684168676840683E
+684A6849682968B5688F687468776893686B68C2696E68FC691F692068F90000
+E9
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+95279533953D95439548954B9555955A9560956E95749575957795789579957A
+957B957C957D957E9580958195829583958495859586958795889589958A958B
+958C958D958E958F9590959195929593959495959596959795989599959A959B
+959C959D959E959F95A095A195A295A395A495A595A695A795A895A995AA0000
+95AB95AC95AD95AE95AF95B095B195B295B395B495B595B695B795B895B995BA
+95BB95BC95BD95BE95BF95C095C195C295C395C495C595C695C795C895C995CA
+95CB692468F0690B6901695768E369106971693969606942695D6984696B6980
+69986978693469CC6987698869CE6989696669636979699B69A769BB69AB69AD
+69D469B169C169CA69DF699569E0698D69FF6A2F69ED6A176A186A6569F26A44
+6A3E6AA06A506A5B6A356A8E6A796A3D6A286A586A7C6A916A906AA96A976AAB
+733773526B816B826B876B846B926B936B8D6B9A6B9B6BA16BAA8F6B8F6D8F71
+8F728F738F758F768F788F778F798F7A8F7C8F7E8F818F828F848F878F8B0000
+EA
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+95CC95CD95CE95CF95D095D195D295D395D495D595D695D795D895D995DA95DB
+95DC95DD95DE95DF95E095E195E295E395E495E595E695E795EC95FF96079613
+9618961B961E96209623962496259626962796289629962B962C962D962F9630
+963796389639963A963E96419643964A964E964F965196529653965696570000
+96589659965A965C965D965E9660966396659666966B966D966E966F96709671
+967396789679967A967B967C967D967E967F9680968196829683968496879689
+968A8F8D8F8E8F8F8F988F9A8ECE620B6217621B621F6222622162256224622C
+81E774EF74F474FF750F75117513653465EE65EF65F0660A6619677266036615
+6600708566F7661D66346631663666358006665F66546641664F665666616657
+66776684668C66A7669D66BE66DB66DC66E666E98D328D338D368D3B8D3D8D40
+8D458D468D488D498D478D4D8D558D5989C789CA89CB89CC89CE89CF89D089D1
+726E729F725D7266726F727E727F7284728B728D728F72926308633263B00000
+EB
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+968C968E96919692969396959696969A969B969D969E969F96A096A196A296A3
+96A496A596A696A896A996AA96AB96AC96AD96AE96AF96B196B296B496B596B7
+96B896BA96BB96BF96C296C396C896CA96CB96D096D196D396D496D696D796D8
+96D996DA96DB96DC96DD96DE96DF96E196E296E396E496E596E696E796EB0000
+96EC96ED96EE96F096F196F296F496F596F896FA96FB96FC96FD96FF97029703
+9705970A970B970C97109711971297149715971797189719971A971B971D971F
+9720643F64D880046BEA6BF36BFD6BF56BF96C056C076C066C0D6C156C186C19
+6C1A6C216C296C246C2A6C3265356555656B724D72527256723086625216809F
+809C809380BC670A80BD80B180AB80AD80B480B780E780E880E980EA80DB80C2
+80C480D980CD80D7671080DD80EB80F180F480ED810D810E80F280FC67158112
+8C5A8136811E812C811881328148814C815381748159815A817181608169817C
+817D816D8167584D5AB58188818281916ED581A381AA81CC672681CA81BB0000
+EC
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+972197229723972497259726972797289729972B972C972E972F973197339734
+973597369737973A973B973C973D973F97409741974297439744974597469747
+97489749974A974B974C974D974E974F975097519754975597579758975A975C
+975D975F97639764976697679768976A976B976C976D976E976F977097710000
+97729775977797789779977A977B977D977E977F978097819782978397849786
+978797889789978A978C978E978F979097939795979697979799979A979B979C
+979D81C181A66B246B376B396B436B466B5998D198D298D398D598D998DA6BB3
+5F406BC289F365909F51659365BC65C665C465C365CC65CE65D265D67080709C
+7096709D70BB70C070B770AB70B170E870CA711071137116712F71317173715C
+716871457172714A7178717A719871B371B571A871A071E071D471E771F9721D
+7228706C7118716671B9623E623D624362486249793B794079467949795B795C
+7953795A796279577960796F7967797A7985798A799A79A779B35FD15FD00000
+ED
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+979E979F97A197A297A497A597A697A797A897A997AA97AC97AE97B097B197B3
+97B597B697B797B897B997BA97BB97BC97BD97BE97BF97C097C197C297C397C4
+97C597C697C797C897C997CA97CB97CC97CD97CE97CF97D097D197D297D397D4
+97D597D697D797D897D997DA97DB97DC97DD97DE97DF97E097E197E297E30000
+97E497E597E897EE97EF97F097F197F297F497F797F897F997FA97FB97FC97FD
+97FE97FF9800980198029803980498059806980798089809980A980B980C980D
+980E603C605D605A606760416059606360AB6106610D615D61A9619D61CB61D1
+62068080807F6C936CF66DFC77F677F87800780978177818781165AB782D781C
+781D7839783A783B781F783C7825782C78237829784E786D7856785778267850
+7847784C786A789B7893789A7887789C78A178A378B278B978A578D478D978C9
+78EC78F2790578F479137924791E79349F9B9EF99EFB9EFC76F17704770D76F9
+77077708771A77227719772D7726773577387750775177477743775A77680000
+EE
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+980F9810981198129813981498159816981798189819981A981B981C981D981E
+981F9820982198229823982498259826982798289829982A982B982C982D982E
+982F9830983198329833983498359836983798389839983A983B983C983D983E
+983F9840984198429843984498459846984798489849984A984B984C984D0000
+984E984F9850985198529853985498559856985798589859985A985B985C985D
+985E985F9860986198629863986498659866986798689869986A986B986C986D
+986E77627765777F778D777D7780778C7791779F77A077B077B577BD753A7540
+754E754B7548755B7572757975837F587F617F5F8A487F687F747F717F797F81
+7F7E76CD76E58832948594869487948B948A948C948D948F9490949494979495
+949A949B949C94A394A494AB94AA94AD94AC94AF94B094B294B494B694B794B8
+94B994BA94BC94BD94BF94C494C894C994CA94CB94CC94CD94CE94D094D194D2
+94D594D694D794D994D894DB94DE94DF94E094E294E494E594E794E894EA0000
+EF
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+986F98709871987298739874988B988E98929895989998A398A898A998AA98AB
+98AC98AD98AE98AF98B098B198B298B398B498B598B698B798B898B998BA98BB
+98BC98BD98BE98BF98C098C198C298C398C498C598C698C798C898C998CA98CB
+98CC98CD98CF98D098D498D698D798DB98DC98DD98E098E198E298E398E40000
+98E598E698E998EA98EB98EC98ED98EE98EF98F098F198F298F398F498F598F6
+98F798F898F998FA98FB98FC98FD98FE98FF9900990199029903990499059906
+990794E994EB94EE94EF94F394F494F594F794F994FC94FD94FF950395029506
+95079509950A950D950E950F951295139514951595169518951B951D951E951F
+9522952A952B9529952C953195329534953695379538953C953E953F95429535
+9544954595469549954C954E954F9552955395549556955795589559955B955E
+955F955D95619562956495659566956795689569956A956B956C956F95719572
+9573953A77E777EC96C979D579ED79E379EB7A065D477A037A027A1E7A140000
+F0
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+99089909990A990B990C990E990F991199129913991499159916991799189919
+991A991B991C991D991E991F9920992199229923992499259926992799289929
+992A992B992C992D992F9930993199329933993499359936993799389939993A
+993B993C993D993E993F99409941994299439944994599469947994899490000
+994A994B994C994D994E994F99509951995299539956995799589959995A995B
+995C995D995E995F99609961996299649966997399789979997B997E99829983
+99897A397A377A519ECF99A57A707688768E7693769976A474DE74E0752C9E20
+9E229E289E299E2A9E2B9E2C9E329E319E369E389E379E399E3A9E3E9E419E42
+9E449E469E479E489E499E4B9E4C9E4E9E519E559E579E5A9E5B9E5C9E5E9E63
+9E669E679E689E699E6A9E6B9E6C9E719E6D9E7375927594759675A0759D75AC
+75A375B375B475B875C475B175B075C375C275D675CD75E375E875E675E475EB
+75E7760375F175FC75FF761076007605760C7617760A76257618761576190000
+F1
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+998C998E999A999B999C999D999E999F99A099A199A299A399A499A699A799A9
+99AA99AB99AC99AD99AE99AF99B099B199B299B399B499B599B699B799B899B9
+99BA99BB99BC99BD99BE99BF99C099C199C299C399C499C599C699C799C899C9
+99CA99CB99CC99CD99CE99CF99D099D199D299D399D499D599D699D799D80000
+99D999DA99DB99DC99DD99DE99DF99E099E199E299E399E499E599E699E799E8
+99E999EA99EB99EC99ED99EE99EF99F099F199F299F399F499F599F699F799F8
+99F9761B763C762276207640762D7630763F76357643763E7633764D765E7654
+765C7656766B766F7FCA7AE67A787A797A807A867A887A957AA67AA07AAC7AA8
+7AAD7AB3886488698872887D887F888288A288C688B788BC88C988E288CE88E3
+88E588F1891A88FC88E888FE88F0892189198913891B890A8934892B89368941
+8966897B758B80E576B276B477DC801280148016801C80208022802580268027
+802980288031800B803580438046804D80528069807189839878988098830000
+F2
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+99FA99FB99FC99FD99FE99FF9A009A019A029A039A049A059A069A079A089A09
+9A0A9A0B9A0C9A0D9A0E9A0F9A109A119A129A139A149A159A169A179A189A19
+9A1A9A1B9A1C9A1D9A1E9A1F9A209A219A229A239A249A259A269A279A289A29
+9A2A9A2B9A2C9A2D9A2E9A2F9A309A319A329A339A349A359A369A379A380000
+9A399A3A9A3B9A3C9A3D9A3E9A3F9A409A419A429A439A449A459A469A479A48
+9A499A4A9A4B9A4C9A4D9A4E9A4F9A509A519A529A539A549A559A569A579A58
+9A599889988C988D988F9894989A989B989E989F98A198A298A598A6864D8654
+866C866E867F867A867C867B86A8868D868B86AC869D86A786A386AA869386A9
+86B686C486B586CE86B086BA86B186AF86C986CF86B486E986F186F286ED86F3
+86D0871386DE86F486DF86D886D18703870786F88708870A870D87098723873B
+871E8725872E871A873E87488734873187298737873F87828722877D877E877B
+87608770874C876E878B87538763877C876487598765879387AF87A887D20000
+F3
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+9A5A9A5B9A5C9A5D9A5E9A5F9A609A619A629A639A649A659A669A679A689A69
+9A6A9A6B9A729A839A899A8D9A8E9A949A959A999AA69AA99AAA9AAB9AAC9AAD
+9AAE9AAF9AB29AB39AB49AB59AB99ABB9ABD9ABE9ABF9AC39AC49AC69AC79AC8
+9AC99ACA9ACD9ACE9ACF9AD09AD29AD49AD59AD69AD79AD99ADA9ADB9ADC0000
+9ADD9ADE9AE09AE29AE39AE49AE59AE79AE89AE99AEA9AEC9AEE9AF09AF19AF2
+9AF39AF49AF59AF69AF79AF89AFA9AFC9AFD9AFE9AFF9B009B019B029B049B05
+9B0687C68788878587AD8797878387AB87E587AC87B587B387CB87D387BD87D1
+87C087CA87DB87EA87E087EE8816881387FE880A881B88218839883C7F367F42
+7F447F4582107AFA7AFD7B087B037B047B157B0A7B2B7B0F7B477B387B2A7B19
+7B2E7B317B207B257B247B337B3E7B1E7B587B5A7B457B757B4C7B5D7B607B6E
+7B7B7B627B727B717B907BA67BA77BB87BAC7B9D7BA87B857BAA7B9C7BA27BAB
+7BB47BD17BC17BCC7BDD7BDA7BE57BE67BEA7C0C7BFE7BFC7C0F7C167C0B0000
+F4
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+9B079B099B0A9B0B9B0C9B0D9B0E9B109B119B129B149B159B169B179B189B19
+9B1A9B1B9B1C9B1D9B1E9B209B219B229B249B259B269B279B289B299B2A9B2B
+9B2C9B2D9B2E9B309B319B339B349B359B369B379B389B399B3A9B3D9B3E9B3F
+9B409B469B4A9B4B9B4C9B4E9B509B529B539B559B569B579B589B599B5A0000
+9B5B9B5C9B5D9B5E9B5F9B609B619B629B639B649B659B669B679B689B699B6A
+9B6B9B6C9B6D9B6E9B6F9B709B719B729B739B749B759B769B779B789B799B7A
+9B7B7C1F7C2A7C267C387C417C4081FE82018202820481EC8844822182228223
+822D822F8228822B8238823B82338234823E82448249824B824F825A825F8268
+887E8885888888D888DF895E7F9D7F9F7FA77FAF7FB07FB27C7C65497C917C9D
+7C9C7C9E7CA27CB27CBC7CBD7CC17CC77CCC7CCD7CC87CC57CD77CE8826E66A8
+7FBF7FCE7FD57FE57FE17FE67FE97FEE7FF37CF87D777DA67DAE7E477E9B9EB8
+9EB48D738D848D948D918DB18D678D6D8C478C49914A9150914E914F91640000
+F5
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+9B7C9B7D9B7E9B7F9B809B819B829B839B849B859B869B879B889B899B8A9B8B
+9B8C9B8D9B8E9B8F9B909B919B929B939B949B959B969B979B989B999B9A9B9B
+9B9C9B9D9B9E9B9F9BA09BA19BA29BA39BA49BA59BA69BA79BA89BA99BAA9BAB
+9BAC9BAD9BAE9BAF9BB09BB19BB29BB39BB49BB59BB69BB79BB89BB99BBA0000
+9BBB9BBC9BBD9BBE9BBF9BC09BC19BC29BC39BC49BC59BC69BC79BC89BC99BCA
+9BCB9BCC9BCD9BCE9BCF9BD09BD19BD29BD39BD49BD59BD69BD79BD89BD99BDA
+9BDB9162916191709169916F917D917E917291749179918C91859190918D9191
+91A291A391AA91AD91AE91AF91B591B491BA8C559E7E8DB88DEB8E058E598E69
+8DB58DBF8DBC8DBA8DC48DD68DD78DDA8DDE8DCE8DCF8DDB8DC68DEC8DF78DF8
+8DE38DF98DFB8DE48E098DFD8E148E1D8E1F8E2C8E2E8E238E2F8E3A8E408E39
+8E358E3D8E318E498E418E428E518E528E4A8E708E768E7C8E6F8E748E858E8F
+8E948E908E9C8E9E8C788C828C8A8C858C988C94659B89D689DE89DA89DC0000
+F6
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+9BDC9BDD9BDE9BDF9BE09BE19BE29BE39BE49BE59BE69BE79BE89BE99BEA9BEB
+9BEC9BED9BEE9BEF9BF09BF19BF29BF39BF49BF59BF69BF79BF89BF99BFA9BFB
+9BFC9BFD9BFE9BFF9C009C019C029C039C049C059C069C079C089C099C0A9C0B
+9C0C9C0D9C0E9C0F9C109C119C129C139C149C159C169C179C189C199C1A0000
+9C1B9C1C9C1D9C1E9C1F9C209C219C229C239C249C259C269C279C289C299C2A
+9C2B9C2C9C2D9C2E9C2F9C309C319C329C339C349C359C369C379C389C399C3A
+9C3B89E589EB89EF8A3E8B26975396E996F396EF970697019708970F970E972A
+972D9730973E9F809F839F859F869F879F889F899F8A9F8C9EFE9F0B9F0D96B9
+96BC96BD96CE96D277BF96E0928E92AE92C8933E936A93CA938F943E946B9C7F
+9C829C859C869C879C887A239C8B9C8E9C909C919C929C949C959C9A9C9B9C9E
+9C9F9CA09CA19CA29CA39CA59CA69CA79CA89CA99CAB9CAD9CAE9CB09CB19CB2
+9CB39CB49CB59CB69CB79CBA9CBB9CBC9CBD9CC49CC59CC69CC79CCA9CCB0000
+F7
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+9C3C9C3D9C3E9C3F9C409C419C429C439C449C459C469C479C489C499C4A9C4B
+9C4C9C4D9C4E9C4F9C509C519C529C539C549C559C569C579C589C599C5A9C5B
+9C5C9C5D9C5E9C5F9C609C619C629C639C649C659C669C679C689C699C6A9C6B
+9C6C9C6D9C6E9C6F9C709C719C729C739C749C759C769C779C789C799C7A0000
+9C7B9C7D9C7E9C809C839C849C899C8A9C8C9C8F9C939C969C979C989C999C9D
+9CAA9CAC9CAF9CB99CBE9CBF9CC09CC19CC29CC89CC99CD19CD29CDA9CDB9CE0
+9CE19CCC9CCD9CCE9CCF9CD09CD39CD49CD59CD79CD89CD99CDC9CDD9CDF9CE2
+977C978597919792979497AF97AB97A397B297B49AB19AB09AB79E589AB69ABA
+9ABC9AC19AC09AC59AC29ACB9ACC9AD19B459B439B479B499B489B4D9B5198E8
+990D992E995599549ADF9AE19AE69AEF9AEB9AFB9AED9AF99B089B0F9B139B1F
+9B239EBD9EBE7E3B9E829E879E889E8B9E9293D69E9D9E9F9EDB9EDC9EDD9EE0
+9EDF9EE29EE99EE79EE59EEA9EEF9F229F2C9F2F9F399F379F3D9F3E9F440000
+F8
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+9CE39CE49CE59CE69CE79CE89CE99CEA9CEB9CEC9CED9CEE9CEF9CF09CF19CF2
+9CF39CF49CF59CF69CF79CF89CF99CFA9CFB9CFC9CFD9CFE9CFF9D009D019D02
+9D039D049D059D069D079D089D099D0A9D0B9D0C9D0D9D0E9D0F9D109D119D12
+9D139D149D159D169D179D189D199D1A9D1B9D1C9D1D9D1E9D1F9D209D210000
+9D229D239D249D259D269D279D289D299D2A9D2B9D2C9D2D9D2E9D2F9D309D31
+9D329D339D349D359D369D379D389D399D3A9D3B9D3C9D3D9D3E9D3F9D409D41
+9D42000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+F9
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+9D439D449D459D469D479D489D499D4A9D4B9D4C9D4D9D4E9D4F9D509D519D52
+9D539D549D559D569D579D589D599D5A9D5B9D5C9D5D9D5E9D5F9D609D619D62
+9D639D649D659D669D679D689D699D6A9D6B9D6C9D6D9D6E9D6F9D709D719D72
+9D739D749D759D769D779D789D799D7A9D7B9D7C9D7D9D7E9D7F9D809D810000
+9D829D839D849D859D869D879D889D899D8A9D8B9D8C9D8D9D8E9D8F9D909D91
+9D929D939D949D959D969D979D989D999D9A9D9B9D9C9D9D9D9E9D9F9DA09DA1
+9DA2000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+FA
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+9DA39DA49DA59DA69DA79DA89DA99DAA9DAB9DAC9DAD9DAE9DAF9DB09DB19DB2
+9DB39DB49DB59DB69DB79DB89DB99DBA9DBB9DBC9DBD9DBE9DBF9DC09DC19DC2
+9DC39DC49DC59DC69DC79DC89DC99DCA9DCB9DCC9DCD9DCE9DCF9DD09DD19DD2
+9DD39DD49DD59DD69DD79DD89DD99DDA9DDB9DDC9DDD9DDE9DDF9DE09DE10000
+9DE29DE39DE49DE59DE69DE79DE89DE99DEA9DEB9DEC9DED9DEE9DEF9DF09DF1
+9DF29DF39DF49DF59DF69DF79DF89DF99DFA9DFB9DFC9DFD9DFE9DFF9E009E01
+9E02000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+FB
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+9E039E049E059E069E079E089E099E0A9E0B9E0C9E0D9E0E9E0F9E109E119E12
+9E139E149E159E169E179E189E199E1A9E1B9E1C9E1D9E1E9E249E279E2E9E30
+9E349E3B9E3C9E409E4D9E509E529E539E549E569E599E5D9E5F9E609E619E62
+9E659E6E9E6F9E729E749E759E769E779E789E799E7A9E7B9E7C9E7D9E800000
+9E819E839E849E859E869E899E8A9E8C9E8D9E8E9E8F9E909E919E949E959E96
+9E979E989E999E9A9E9B9E9C9E9E9EA09EA19EA29EA39EA49EA59EA79EA89EA9
+9EAA000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+FC
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+9EAB9EAC9EAD9EAE9EAF9EB09EB19EB29EB39EB59EB69EB79EB99EBA9EBC9EBF
+9EC09EC19EC29EC39EC59EC69EC79EC89ECA9ECB9ECC9ED09ED29ED39ED59ED6
+9ED79ED99EDA9EDE9EE19EE39EE49EE69EE89EEB9EEC9EED9EEE9EF09EF19EF2
+9EF39EF49EF59EF69EF79EF89EFA9EFD9EFF9F009F019F029F039F049F050000
+9F069F079F089F099F0A9F0C9F0F9F119F129F149F159F169F189F1A9F1B9F1C
+9F1D9F1E9F1F9F219F239F249F259F269F279F289F299F2A9F2B9F2D9F2E9F30
+9F31000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+FD
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+9F329F339F349F359F369F389F3A9F3C9F3F9F409F419F429F439F459F469F47
+9F489F499F4A9F4B9F4C9F4D9F4E9F4F9F529F539F549F559F569F579F589F59
+9F5A9F5B9F5C9F5D9F5E9F5F9F609F619F629F639F649F659F669F679F689F69
+9F6A9F6B9F6C9F6D9F6E9F6F9F709F719F729F739F749F759F769F779F780000
+9F799F7A9F7B9F7C9F7D9F7E9F819F829F8D9F8E9F8F9F909F919F929F939F94
+9F959F969F979F989F9C9F9D9F9E9FA19FA29FA39FA49FA5F92CF979F995F9E7
+F9F1000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+FE
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+FA0CFA0DFA0EFA0FFA11FA13FA14FA18FA1FFA20FA21FA23FA24FA27FA28FA29
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
diff --git a/library/encoding/cp949.enc b/library/encoding/cp949.enc
new file mode 100644
index 0000000..2f3ec39
--- /dev/null
+++ b/library/encoding/cp949.enc
@@ -0,0 +1,2128 @@
+# Encoding file: cp949, multi-byte
+M
+003F 0 125
+00
+0000000100020003000400050006000700080009000A000B000C000D000E000F
+0010001100120013001400150016001700180019001A001B001C001D001E001F
+0020002100220023002400250026002700280029002A002B002C002D002E002F
+0030003100320033003400350036003700380039003A003B003C003D003E003F
+0040004100420043004400450046004700480049004A004B004C004D004E004F
+0050005100520053005400550056005700580059005A005B005C005D005E005F
+0060006100620063006400650066006700680069006A006B006C006D006E006F
+0070007100720073007400750076007700780079007A007B007C007D007E007F
+0080000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+81
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000AC02AC03AC05AC06AC0BAC0CAC0DAC0EAC0FAC18AC1EAC1FAC21AC22AC23
+AC25AC26AC27AC28AC29AC2AAC2BAC2EAC32AC33AC3400000000000000000000
+0000AC35AC36AC37AC3AAC3BAC3DAC3EAC3FAC41AC42AC43AC44AC45AC46AC47
+AC48AC49AC4AAC4CAC4EAC4FAC50AC51AC52AC53AC5500000000000000000000
+0000AC56AC57AC59AC5AAC5BAC5DAC5EAC5FAC60AC61AC62AC63AC64AC65AC66
+AC67AC68AC69AC6AAC6BAC6CAC6DAC6EAC6FAC72AC73AC75AC76AC79AC7BAC7C
+AC7DAC7EAC7FAC82AC87AC88AC8DAC8EAC8FAC91AC92AC93AC95AC96AC97AC98
+AC99AC9AAC9BAC9EACA2ACA3ACA4ACA5ACA6ACA7ACABACADACAEACB1ACB2ACB3
+ACB4ACB5ACB6ACB7ACBAACBEACBFACC0ACC2ACC3ACC5ACC6ACC7ACC9ACCAACCB
+ACCDACCEACCFACD0ACD1ACD2ACD3ACD4ACD6ACD8ACD9ACDAACDBACDCACDDACDE
+ACDFACE2ACE3ACE5ACE6ACE9ACEBACEDACEEACF2ACF4ACF7ACF8ACF9ACFAACFB
+ACFEACFFAD01AD02AD03AD05AD07AD08AD09AD0AAD0BAD0EAD10AD12AD130000
+82
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000AD14AD15AD16AD17AD19AD1AAD1BAD1DAD1EAD1FAD21AD22AD23AD24AD25
+AD26AD27AD28AD2AAD2BAD2EAD2FAD30AD31AD32AD3300000000000000000000
+0000AD36AD37AD39AD3AAD3BAD3DAD3EAD3FAD40AD41AD42AD43AD46AD48AD4A
+AD4BAD4CAD4DAD4EAD4FAD51AD52AD53AD55AD56AD5700000000000000000000
+0000AD59AD5AAD5BAD5CAD5DAD5EAD5FAD60AD62AD64AD65AD66AD67AD68AD69
+AD6AAD6BAD6EAD6FAD71AD72AD77AD78AD79AD7AAD7EAD80AD83AD84AD85AD86
+AD87AD8AAD8BAD8DAD8EAD8FAD91AD92AD93AD94AD95AD96AD97AD98AD99AD9A
+AD9BAD9EAD9FADA0ADA1ADA2ADA3ADA5ADA6ADA7ADA8ADA9ADAAADABADACADAD
+ADAEADAFADB0ADB1ADB2ADB3ADB4ADB5ADB6ADB8ADB9ADBAADBBADBCADBDADBE
+ADBFADC2ADC3ADC5ADC6ADC7ADC9ADCAADCBADCCADCDADCEADCFADD2ADD4ADD5
+ADD6ADD7ADD8ADD9ADDAADDBADDDADDEADDFADE1ADE2ADE3ADE5ADE6ADE7ADE8
+ADE9ADEAADEBADECADEDADEEADEFADF0ADF1ADF2ADF3ADF4ADF5ADF6ADF70000
+83
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000ADFAADFBADFDADFEAE02AE03AE04AE05AE06AE07AE0AAE0CAE0EAE0FAE10
+AE11AE12AE13AE15AE16AE17AE18AE19AE1AAE1BAE1C00000000000000000000
+0000AE1DAE1EAE1FAE20AE21AE22AE23AE24AE25AE26AE27AE28AE29AE2AAE2B
+AE2CAE2DAE2EAE2FAE32AE33AE35AE36AE39AE3BAE3C00000000000000000000
+0000AE3DAE3EAE3FAE42AE44AE47AE48AE49AE4BAE4FAE51AE52AE53AE55AE57
+AE58AE59AE5AAE5BAE5EAE62AE63AE64AE66AE67AE6AAE6BAE6DAE6EAE6FAE71
+AE72AE73AE74AE75AE76AE77AE7AAE7EAE7FAE80AE81AE82AE83AE86AE87AE88
+AE89AE8AAE8BAE8DAE8EAE8FAE90AE91AE92AE93AE94AE95AE96AE97AE98AE99
+AE9AAE9BAE9CAE9DAE9EAE9FAEA0AEA1AEA2AEA3AEA4AEA5AEA6AEA7AEA8AEA9
+AEAAAEABAEACAEADAEAEAEAFAEB0AEB1AEB2AEB3AEB4AEB5AEB6AEB7AEB8AEB9
+AEBAAEBBAEBFAEC1AEC2AEC3AEC5AEC6AEC7AEC8AEC9AECAAECBAECEAED2AED3
+AED4AED5AED6AED7AEDAAEDBAEDDAEDEAEDFAEE0AEE1AEE2AEE3AEE4AEE50000
+84
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000AEE6AEE7AEE9AEEAAEECAEEEAEEFAEF0AEF1AEF2AEF3AEF5AEF6AEF7AEF9
+AEFAAEFBAEFDAEFEAEFFAF00AF01AF02AF03AF04AF0500000000000000000000
+0000AF06AF09AF0AAF0BAF0CAF0EAF0FAF11AF12AF13AF14AF15AF16AF17AF18
+AF19AF1AAF1BAF1CAF1DAF1EAF1FAF20AF21AF22AF2300000000000000000000
+0000AF24AF25AF26AF27AF28AF29AF2AAF2BAF2EAF2FAF31AF33AF35AF36AF37
+AF38AF39AF3AAF3BAF3EAF40AF44AF45AF46AF47AF4AAF4BAF4CAF4DAF4EAF4F
+AF51AF52AF53AF54AF55AF56AF57AF58AF59AF5AAF5BAF5EAF5FAF60AF61AF62
+AF63AF66AF67AF68AF69AF6AAF6BAF6CAF6DAF6EAF6FAF70AF71AF72AF73AF74
+AF75AF76AF77AF78AF7AAF7BAF7CAF7DAF7EAF7FAF81AF82AF83AF85AF86AF87
+AF89AF8AAF8BAF8CAF8DAF8EAF8FAF92AF93AF94AF96AF97AF98AF99AF9AAF9B
+AF9DAF9EAF9FAFA0AFA1AFA2AFA3AFA4AFA5AFA6AFA7AFA8AFA9AFAAAFABAFAC
+AFADAFAEAFAFAFB0AFB1AFB2AFB3AFB4AFB5AFB6AFB7AFBAAFBBAFBDAFBE0000
+85
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000AFBFAFC1AFC2AFC3AFC4AFC5AFC6AFCAAFCCAFCFAFD0AFD1AFD2AFD3AFD5
+AFD6AFD7AFD8AFD9AFDAAFDBAFDDAFDEAFDFAFE0AFE100000000000000000000
+0000AFE2AFE3AFE4AFE5AFE6AFE7AFEAAFEBAFECAFEDAFEEAFEFAFF2AFF3AFF5
+AFF6AFF7AFF9AFFAAFFBAFFCAFFDAFFEAFFFB002B00300000000000000000000
+0000B005B006B007B008B009B00AB00BB00DB00EB00FB011B012B013B015B016
+B017B018B019B01AB01BB01EB01FB020B021B022B023B024B025B026B027B029
+B02AB02BB02CB02DB02EB02FB030B031B032B033B034B035B036B037B038B039
+B03AB03BB03CB03DB03EB03FB040B041B042B043B046B047B049B04BB04DB04F
+B050B051B052B056B058B05AB05BB05CB05EB05FB060B061B062B063B064B065
+B066B067B068B069B06AB06BB06CB06DB06EB06FB070B071B072B073B074B075
+B076B077B078B079B07AB07BB07EB07FB081B082B083B085B086B087B088B089
+B08AB08BB08EB090B092B093B094B095B096B097B09BB09DB09EB0A3B0A40000
+86
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000B0A5B0A6B0A7B0AAB0B0B0B2B0B6B0B7B0B9B0BAB0BBB0BDB0BEB0BFB0C0
+B0C1B0C2B0C3B0C6B0CAB0CBB0CCB0CDB0CEB0CFB0D200000000000000000000
+0000B0D3B0D5B0D6B0D7B0D9B0DAB0DBB0DCB0DDB0DEB0DFB0E1B0E2B0E3B0E4
+B0E6B0E7B0E8B0E9B0EAB0EBB0ECB0EDB0EEB0EFB0F000000000000000000000
+0000B0F1B0F2B0F3B0F4B0F5B0F6B0F7B0F8B0F9B0FAB0FBB0FCB0FDB0FEB0FF
+B100B101B102B103B104B105B106B107B10AB10DB10EB10FB111B114B115B116
+B117B11AB11EB11FB120B121B122B126B127B129B12AB12BB12DB12EB12FB130
+B131B132B133B136B13AB13BB13CB13DB13EB13FB142B143B145B146B147B149
+B14AB14BB14CB14DB14EB14FB152B153B156B157B159B15AB15BB15DB15EB15F
+B161B162B163B164B165B166B167B168B169B16AB16BB16CB16DB16EB16FB170
+B171B172B173B174B175B176B177B17AB17BB17DB17EB17FB181B183B184B185
+B186B187B18AB18CB18EB18FB190B191B195B196B197B199B19AB19BB19D0000
+87
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000B19EB19FB1A0B1A1B1A2B1A3B1A4B1A5B1A6B1A7B1A9B1AAB1ABB1ACB1AD
+B1AEB1AFB1B0B1B1B1B2B1B3B1B4B1B5B1B6B1B7B1B800000000000000000000
+0000B1B9B1BAB1BBB1BCB1BDB1BEB1BFB1C0B1C1B1C2B1C3B1C4B1C5B1C6B1C7
+B1C8B1C9B1CAB1CBB1CDB1CEB1CFB1D1B1D2B1D3B1D500000000000000000000
+0000B1D6B1D7B1D8B1D9B1DAB1DBB1DEB1E0B1E1B1E2B1E3B1E4B1E5B1E6B1E7
+B1EAB1EBB1EDB1EEB1EFB1F1B1F2B1F3B1F4B1F5B1F6B1F7B1F8B1FAB1FCB1FE
+B1FFB200B201B202B203B206B207B209B20AB20DB20EB20FB210B211B212B213
+B216B218B21AB21BB21CB21DB21EB21FB221B222B223B224B225B226B227B228
+B229B22AB22BB22CB22DB22EB22FB230B231B232B233B235B236B237B238B239
+B23AB23BB23DB23EB23FB240B241B242B243B244B245B246B247B248B249B24A
+B24BB24CB24DB24EB24FB250B251B252B253B254B255B256B257B259B25AB25B
+B25DB25EB25FB261B262B263B264B265B266B267B26AB26BB26CB26DB26E0000
+88
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000B26FB270B271B272B273B276B277B278B279B27AB27BB27DB27EB27FB280
+B281B282B283B286B287B288B28AB28BB28CB28DB28E00000000000000000000
+0000B28FB292B293B295B296B297B29BB29CB29DB29EB29FB2A2B2A4B2A7B2A8
+B2A9B2ABB2ADB2AEB2AFB2B1B2B2B2B3B2B5B2B6B2B700000000000000000000
+0000B2B8B2B9B2BAB2BBB2BCB2BDB2BEB2BFB2C0B2C1B2C2B2C3B2C4B2C5B2C6
+B2C7B2CAB2CBB2CDB2CEB2CFB2D1B2D3B2D4B2D5B2D6B2D7B2DAB2DCB2DEB2DF
+B2E0B2E1B2E3B2E7B2E9B2EAB2F0B2F1B2F2B2F6B2FCB2FDB2FEB302B303B305
+B306B307B309B30AB30BB30CB30DB30EB30FB312B316B317B318B319B31AB31B
+B31DB31EB31FB320B321B322B323B324B325B326B327B328B329B32AB32BB32C
+B32DB32EB32FB330B331B332B333B334B335B336B337B338B339B33AB33BB33C
+B33DB33EB33FB340B341B342B343B344B345B346B347B348B349B34AB34BB34C
+B34DB34EB34FB350B351B352B353B357B359B35AB35DB360B361B362B3630000
+89
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000B366B368B36AB36CB36DB36FB372B373B375B376B377B379B37AB37BB37C
+B37DB37EB37FB382B386B387B388B389B38AB38BB38D00000000000000000000
+0000B38EB38FB391B392B393B395B396B397B398B399B39AB39BB39CB39DB39E
+B39FB3A2B3A3B3A4B3A5B3A6B3A7B3A9B3AAB3ABB3AD00000000000000000000
+0000B3AEB3AFB3B0B3B1B3B2B3B3B3B4B3B5B3B6B3B7B3B8B3B9B3BAB3BBB3BC
+B3BDB3BEB3BFB3C0B3C1B3C2B3C3B3C6B3C7B3C9B3CAB3CDB3CFB3D1B3D2B3D3
+B3D6B3D8B3DAB3DCB3DEB3DFB3E1B3E2B3E3B3E5B3E6B3E7B3E9B3EAB3EBB3EC
+B3EDB3EEB3EFB3F0B3F1B3F2B3F3B3F4B3F5B3F6B3F7B3F8B3F9B3FAB3FBB3FD
+B3FEB3FFB400B401B402B403B404B405B406B407B408B409B40AB40BB40CB40D
+B40EB40FB411B412B413B414B415B416B417B419B41AB41BB41DB41EB41FB421
+B422B423B424B425B426B427B42AB42CB42DB42EB42FB430B431B432B433B435
+B436B437B438B439B43AB43BB43CB43DB43EB43FB440B441B442B443B4440000
+8A
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000B445B446B447B448B449B44AB44BB44CB44DB44EB44FB452B453B455B456
+B457B459B45AB45BB45CB45DB45EB45FB462B464B46600000000000000000000
+0000B467B468B469B46AB46BB46DB46EB46FB470B471B472B473B474B475B476
+B477B478B479B47AB47BB47CB47DB47EB47FB481B48200000000000000000000
+0000B483B484B485B486B487B489B48AB48BB48CB48DB48EB48FB490B491B492
+B493B494B495B496B497B498B499B49AB49BB49CB49EB49FB4A0B4A1B4A2B4A3
+B4A5B4A6B4A7B4A9B4AAB4ABB4ADB4AEB4AFB4B0B4B1B4B2B4B3B4B4B4B6B4B8
+B4BAB4BBB4BCB4BDB4BEB4BFB4C1B4C2B4C3B4C5B4C6B4C7B4C9B4CAB4CBB4CC
+B4CDB4CEB4CFB4D1B4D2B4D3B4D4B4D6B4D7B4D8B4D9B4DAB4DBB4DEB4DFB4E1
+B4E2B4E5B4E7B4E8B4E9B4EAB4EBB4EEB4F0B4F2B4F3B4F4B4F5B4F6B4F7B4F9
+B4FAB4FBB4FCB4FDB4FEB4FFB500B501B502B503B504B505B506B507B508B509
+B50AB50BB50CB50DB50EB50FB510B511B512B513B516B517B519B51AB51D0000
+8B
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000B51EB51FB520B521B522B523B526B52BB52CB52DB52EB52FB532B533B535
+B536B537B539B53AB53BB53CB53DB53EB53FB542B54600000000000000000000
+0000B547B548B549B54AB54EB54FB551B552B553B555B556B557B558B559B55A
+B55BB55EB562B563B564B565B566B567B568B569B56A00000000000000000000
+0000B56BB56CB56DB56EB56FB570B571B572B573B574B575B576B577B578B579
+B57AB57BB57CB57DB57EB57FB580B581B582B583B584B585B586B587B588B589
+B58AB58BB58CB58DB58EB58FB590B591B592B593B594B595B596B597B598B599
+B59AB59BB59CB59DB59EB59FB5A2B5A3B5A5B5A6B5A7B5A9B5ACB5ADB5AEB5AF
+B5B2B5B6B5B7B5B8B5B9B5BAB5BEB5BFB5C1B5C2B5C3B5C5B5C6B5C7B5C8B5C9
+B5CAB5CBB5CEB5D2B5D3B5D4B5D5B5D6B5D7B5D9B5DAB5DBB5DCB5DDB5DEB5DF
+B5E0B5E1B5E2B5E3B5E4B5E5B5E6B5E7B5E8B5E9B5EAB5EBB5EDB5EEB5EFB5F0
+B5F1B5F2B5F3B5F4B5F5B5F6B5F7B5F8B5F9B5FAB5FBB5FCB5FDB5FEB5FF0000
+8C
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000B600B601B602B603B604B605B606B607B608B609B60AB60BB60CB60DB60E
+B60FB612B613B615B616B617B619B61AB61BB61CB61D00000000000000000000
+0000B61EB61FB620B621B622B623B624B626B627B628B629B62AB62BB62DB62E
+B62FB630B631B632B633B635B636B637B638B639B63A00000000000000000000
+0000B63BB63CB63DB63EB63FB640B641B642B643B644B645B646B647B649B64A
+B64BB64CB64DB64EB64FB650B651B652B653B654B655B656B657B658B659B65A
+B65BB65CB65DB65EB65FB660B661B662B663B665B666B667B669B66AB66BB66C
+B66DB66EB66FB670B671B672B673B674B675B676B677B678B679B67AB67BB67C
+B67DB67EB67FB680B681B682B683B684B685B686B687B688B689B68AB68BB68C
+B68DB68EB68FB690B691B692B693B694B695B696B697B698B699B69AB69BB69E
+B69FB6A1B6A2B6A3B6A5B6A6B6A7B6A8B6A9B6AAB6ADB6AEB6AFB6B0B6B2B6B3
+B6B4B6B5B6B6B6B7B6B8B6B9B6BAB6BBB6BCB6BDB6BEB6BFB6C0B6C1B6C20000
+8D
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000B6C3B6C4B6C5B6C6B6C7B6C8B6C9B6CAB6CBB6CCB6CDB6CEB6CFB6D0B6D1
+B6D2B6D3B6D5B6D6B6D7B6D8B6D9B6DAB6DBB6DCB6DD00000000000000000000
+0000B6DEB6DFB6E0B6E1B6E2B6E3B6E4B6E5B6E6B6E7B6E8B6E9B6EAB6EBB6EC
+B6EDB6EEB6EFB6F1B6F2B6F3B6F5B6F6B6F7B6F9B6FA00000000000000000000
+0000B6FBB6FCB6FDB6FEB6FFB702B703B704B706B707B708B709B70AB70BB70C
+B70DB70EB70FB710B711B712B713B714B715B716B717B718B719B71AB71BB71C
+B71DB71EB71FB720B721B722B723B724B725B726B727B72AB72BB72DB72EB731
+B732B733B734B735B736B737B73AB73CB73DB73EB73FB740B741B742B743B745
+B746B747B749B74AB74BB74DB74EB74FB750B751B752B753B756B757B758B759
+B75AB75BB75CB75DB75EB75FB761B762B763B765B766B767B769B76AB76BB76C
+B76DB76EB76FB772B774B776B777B778B779B77AB77BB77EB77FB781B782B783
+B785B786B787B788B789B78AB78BB78EB793B794B795B79AB79BB79DB79E0000
+8E
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000B79FB7A1B7A2B7A3B7A4B7A5B7A6B7A7B7AAB7AEB7AFB7B0B7B1B7B2B7B3
+B7B6B7B7B7B9B7BAB7BBB7BCB7BDB7BEB7BFB7C0B7C100000000000000000000
+0000B7C2B7C3B7C4B7C5B7C6B7C8B7CAB7CBB7CCB7CDB7CEB7CFB7D0B7D1B7D2
+B7D3B7D4B7D5B7D6B7D7B7D8B7D9B7DAB7DBB7DCB7DD00000000000000000000
+0000B7DEB7DFB7E0B7E1B7E2B7E3B7E4B7E5B7E6B7E7B7E8B7E9B7EAB7EBB7EE
+B7EFB7F1B7F2B7F3B7F5B7F6B7F7B7F8B7F9B7FAB7FBB7FEB802B803B804B805
+B806B80AB80BB80DB80EB80FB811B812B813B814B815B816B817B81AB81CB81E
+B81FB820B821B822B823B826B827B829B82AB82BB82DB82EB82FB830B831B832
+B833B836B83AB83BB83CB83DB83EB83FB841B842B843B845B846B847B848B849
+B84AB84BB84CB84DB84EB84FB850B852B854B855B856B857B858B859B85AB85B
+B85EB85FB861B862B863B865B866B867B868B869B86AB86BB86EB870B872B873
+B874B875B876B877B879B87AB87BB87DB87EB87FB880B881B882B883B8840000
+8F
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000B885B886B887B888B889B88AB88BB88CB88EB88FB890B891B892B893B894
+B895B896B897B898B899B89AB89BB89CB89DB89EB89F00000000000000000000
+0000B8A0B8A1B8A2B8A3B8A4B8A5B8A6B8A7B8A9B8AAB8ABB8ACB8ADB8AEB8AF
+B8B1B8B2B8B3B8B5B8B6B8B7B8B9B8BAB8BBB8BCB8BD00000000000000000000
+0000B8BEB8BFB8C2B8C4B8C6B8C7B8C8B8C9B8CAB8CBB8CDB8CEB8CFB8D1B8D2
+B8D3B8D5B8D6B8D7B8D8B8D9B8DAB8DBB8DCB8DEB8E0B8E2B8E3B8E4B8E5B8E6
+B8E7B8EAB8EBB8EDB8EEB8EFB8F1B8F2B8F3B8F4B8F5B8F6B8F7B8FAB8FCB8FE
+B8FFB900B901B902B903B905B906B907B908B909B90AB90BB90CB90DB90EB90F
+B910B911B912B913B914B915B916B917B919B91AB91BB91CB91DB91EB91FB921
+B922B923B924B925B926B927B928B929B92AB92BB92CB92DB92EB92FB930B931
+B932B933B934B935B936B937B938B939B93AB93BB93EB93FB941B942B943B945
+B946B947B948B949B94AB94BB94DB94EB950B952B953B954B955B956B9570000
+90
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000B95AB95BB95DB95EB95FB961B962B963B964B965B966B967B96AB96CB96E
+B96FB970B971B972B973B976B977B979B97AB97BB97D00000000000000000000
+0000B97EB97FB980B981B982B983B986B988B98BB98CB98FB990B991B992B993
+B994B995B996B997B998B999B99AB99BB99CB99DB99E00000000000000000000
+0000B99FB9A0B9A1B9A2B9A3B9A4B9A5B9A6B9A7B9A8B9A9B9AAB9ABB9AEB9AF
+B9B1B9B2B9B3B9B5B9B6B9B7B9B8B9B9B9BAB9BBB9BEB9C0B9C2B9C3B9C4B9C5
+B9C6B9C7B9CAB9CBB9CDB9D3B9D4B9D5B9D6B9D7B9DAB9DCB9DFB9E0B9E2B9E6
+B9E7B9E9B9EAB9EBB9EDB9EEB9EFB9F0B9F1B9F2B9F3B9F6B9FBB9FCB9FDB9FE
+B9FFBA02BA03BA04BA05BA06BA07BA09BA0ABA0BBA0CBA0DBA0EBA0FBA10BA11
+BA12BA13BA14BA16BA17BA18BA19BA1ABA1BBA1CBA1DBA1EBA1FBA20BA21BA22
+BA23BA24BA25BA26BA27BA28BA29BA2ABA2BBA2CBA2DBA2EBA2FBA30BA31BA32
+BA33BA34BA35BA36BA37BA3ABA3BBA3DBA3EBA3FBA41BA43BA44BA45BA460000
+91
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000BA47BA4ABA4CBA4FBA50BA51BA52BA56BA57BA59BA5ABA5BBA5DBA5EBA5F
+BA60BA61BA62BA63BA66BA6ABA6BBA6CBA6DBA6EBA6F00000000000000000000
+0000BA72BA73BA75BA76BA77BA79BA7ABA7BBA7CBA7DBA7EBA7FBA80BA81BA82
+BA86BA88BA89BA8ABA8BBA8DBA8EBA8FBA90BA91BA9200000000000000000000
+0000BA93BA94BA95BA96BA97BA98BA99BA9ABA9BBA9CBA9DBA9EBA9FBAA0BAA1
+BAA2BAA3BAA4BAA5BAA6BAA7BAAABAADBAAEBAAFBAB1BAB3BAB4BAB5BAB6BAB7
+BABABABCBABEBABFBAC0BAC1BAC2BAC3BAC5BAC6BAC7BAC9BACABACBBACCBACD
+BACEBACFBAD0BAD1BAD2BAD3BAD4BAD5BAD6BAD7BADABADBBADCBADDBADEBADF
+BAE0BAE1BAE2BAE3BAE4BAE5BAE6BAE7BAE8BAE9BAEABAEBBAECBAEDBAEEBAEF
+BAF0BAF1BAF2BAF3BAF4BAF5BAF6BAF7BAF8BAF9BAFABAFBBAFDBAFEBAFFBB01
+BB02BB03BB05BB06BB07BB08BB09BB0ABB0BBB0CBB0EBB10BB12BB13BB14BB15
+BB16BB17BB19BB1ABB1BBB1DBB1EBB1FBB21BB22BB23BB24BB25BB26BB270000
+92
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000BB28BB2ABB2CBB2DBB2EBB2FBB30BB31BB32BB33BB37BB39BB3ABB3FBB40
+BB41BB42BB43BB46BB48BB4ABB4BBB4CBB4EBB51BB5200000000000000000000
+0000BB53BB55BB56BB57BB59BB5ABB5BBB5CBB5DBB5EBB5FBB60BB62BB64BB65
+BB66BB67BB68BB69BB6ABB6BBB6DBB6EBB6FBB70BB7100000000000000000000
+0000BB72BB73BB74BB75BB76BB77BB78BB79BB7ABB7BBB7CBB7DBB7EBB7FBB80
+BB81BB82BB83BB84BB85BB86BB87BB89BB8ABB8BBB8DBB8EBB8FBB91BB92BB93
+BB94BB95BB96BB97BB98BB99BB9ABB9BBB9CBB9DBB9EBB9FBBA0BBA1BBA2BBA3
+BBA5BBA6BBA7BBA9BBAABBABBBADBBAEBBAFBBB0BBB1BBB2BBB3BBB5BBB6BBB8
+BBB9BBBABBBBBBBCBBBDBBBEBBBFBBC1BBC2BBC3BBC5BBC6BBC7BBC9BBCABBCB
+BBCCBBCDBBCEBBCFBBD1BBD2BBD4BBD5BBD6BBD7BBD8BBD9BBDABBDBBBDCBBDD
+BBDEBBDFBBE0BBE1BBE2BBE3BBE4BBE5BBE6BBE7BBE8BBE9BBEABBEBBBECBBED
+BBEEBBEFBBF0BBF1BBF2BBF3BBF4BBF5BBF6BBF7BBFABBFBBBFDBBFEBC010000
+93
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000BC03BC04BC05BC06BC07BC0ABC0EBC10BC12BC13BC19BC1ABC20BC21BC22
+BC23BC26BC28BC2ABC2BBC2CBC2EBC2FBC32BC33BC3500000000000000000000
+0000BC36BC37BC39BC3ABC3BBC3CBC3DBC3EBC3FBC42BC46BC47BC48BC4ABC4B
+BC4EBC4FBC51BC52BC53BC54BC55BC56BC57BC58BC5900000000000000000000
+0000BC5ABC5BBC5CBC5EBC5FBC60BC61BC62BC63BC64BC65BC66BC67BC68BC69
+BC6ABC6BBC6CBC6DBC6EBC6FBC70BC71BC72BC73BC74BC75BC76BC77BC78BC79
+BC7ABC7BBC7CBC7DBC7EBC7FBC80BC81BC82BC83BC86BC87BC89BC8ABC8DBC8F
+BC90BC91BC92BC93BC96BC98BC9BBC9CBC9DBC9EBC9FBCA2BCA3BCA5BCA6BCA9
+BCAABCABBCACBCADBCAEBCAFBCB2BCB6BCB7BCB8BCB9BCBABCBBBCBEBCBFBCC1
+BCC2BCC3BCC5BCC6BCC7BCC8BCC9BCCABCCBBCCCBCCEBCD2BCD3BCD4BCD6BCD7
+BCD9BCDABCDBBCDDBCDEBCDFBCE0BCE1BCE2BCE3BCE4BCE5BCE6BCE7BCE8BCE9
+BCEABCEBBCECBCEDBCEEBCEFBCF0BCF1BCF2BCF3BCF7BCF9BCFABCFBBCFD0000
+94
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000BCFEBCFFBD00BD01BD02BD03BD06BD08BD0ABD0BBD0CBD0DBD0EBD0FBD11
+BD12BD13BD15BD16BD17BD18BD19BD1ABD1BBD1CBD1D00000000000000000000
+0000BD1EBD1FBD20BD21BD22BD23BD25BD26BD27BD28BD29BD2ABD2BBD2DBD2E
+BD2FBD30BD31BD32BD33BD34BD35BD36BD37BD38BD3900000000000000000000
+0000BD3ABD3BBD3CBD3DBD3EBD3FBD41BD42BD43BD44BD45BD46BD47BD4ABD4B
+BD4DBD4EBD4FBD51BD52BD53BD54BD55BD56BD57BD5ABD5BBD5CBD5DBD5EBD5F
+BD60BD61BD62BD63BD65BD66BD67BD69BD6ABD6BBD6CBD6DBD6EBD6FBD70BD71
+BD72BD73BD74BD75BD76BD77BD78BD79BD7ABD7BBD7CBD7DBD7EBD7FBD82BD83
+BD85BD86BD8BBD8CBD8DBD8EBD8FBD92BD94BD96BD97BD98BD9BBD9DBD9EBD9F
+BDA0BDA1BDA2BDA3BDA5BDA6BDA7BDA8BDA9BDAABDABBDACBDADBDAEBDAFBDB1
+BDB2BDB3BDB4BDB5BDB6BDB7BDB9BDBABDBBBDBCBDBDBDBEBDBFBDC0BDC1BDC2
+BDC3BDC4BDC5BDC6BDC7BDC8BDC9BDCABDCBBDCCBDCDBDCEBDCFBDD0BDD10000
+95
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000BDD2BDD3BDD6BDD7BDD9BDDABDDBBDDDBDDEBDDFBDE0BDE1BDE2BDE3BDE4
+BDE5BDE6BDE7BDE8BDEABDEBBDECBDEDBDEEBDEFBDF100000000000000000000
+0000BDF2BDF3BDF5BDF6BDF7BDF9BDFABDFBBDFCBDFDBDFEBDFFBE01BE02BE04
+BE06BE07BE08BE09BE0ABE0BBE0EBE0FBE11BE12BE1300000000000000000000
+0000BE15BE16BE17BE18BE19BE1ABE1BBE1EBE20BE21BE22BE23BE24BE25BE26
+BE27BE28BE29BE2ABE2BBE2CBE2DBE2EBE2FBE30BE31BE32BE33BE34BE35BE36
+BE37BE38BE39BE3ABE3BBE3CBE3DBE3EBE3FBE40BE41BE42BE43BE46BE47BE49
+BE4ABE4BBE4DBE4FBE50BE51BE52BE53BE56BE58BE5CBE5DBE5EBE5FBE62BE63
+BE65BE66BE67BE69BE6BBE6CBE6DBE6EBE6FBE72BE76BE77BE78BE79BE7ABE7E
+BE7FBE81BE82BE83BE85BE86BE87BE88BE89BE8ABE8BBE8EBE92BE93BE94BE95
+BE96BE97BE9ABE9BBE9CBE9DBE9EBE9FBEA0BEA1BEA2BEA3BEA4BEA5BEA6BEA7
+BEA9BEAABEABBEACBEADBEAEBEAFBEB0BEB1BEB2BEB3BEB4BEB5BEB6BEB70000
+96
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000BEB8BEB9BEBABEBBBEBCBEBDBEBEBEBFBEC0BEC1BEC2BEC3BEC4BEC5BEC6
+BEC7BEC8BEC9BECABECBBECCBECDBECEBECFBED2BED300000000000000000000
+0000BED5BED6BED9BEDABEDBBEDCBEDDBEDEBEDFBEE1BEE2BEE6BEE7BEE8BEE9
+BEEABEEBBEEDBEEEBEEFBEF0BEF1BEF2BEF3BEF4BEF500000000000000000000
+0000BEF6BEF7BEF8BEF9BEFABEFBBEFCBEFDBEFEBEFFBF00BF02BF03BF04BF05
+BF06BF07BF0ABF0BBF0CBF0DBF0EBF0FBF10BF11BF12BF13BF14BF15BF16BF17
+BF1ABF1EBF1FBF20BF21BF22BF23BF24BF25BF26BF27BF28BF29BF2ABF2BBF2C
+BF2DBF2EBF2FBF30BF31BF32BF33BF34BF35BF36BF37BF38BF39BF3ABF3BBF3C
+BF3DBF3EBF3FBF42BF43BF45BF46BF47BF49BF4ABF4BBF4CBF4DBF4EBF4FBF52
+BF53BF54BF56BF57BF58BF59BF5ABF5BBF5CBF5DBF5EBF5FBF60BF61BF62BF63
+BF64BF65BF66BF67BF68BF69BF6ABF6BBF6CBF6DBF6EBF6FBF70BF71BF72BF73
+BF74BF75BF76BF77BF78BF79BF7ABF7BBF7CBF7DBF7EBF7FBF80BF81BF820000
+97
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000BF83BF84BF85BF86BF87BF88BF89BF8ABF8BBF8CBF8DBF8EBF8FBF90BF91
+BF92BF93BF95BF96BF97BF98BF99BF9ABF9BBF9CBF9D00000000000000000000
+0000BF9EBF9FBFA0BFA1BFA2BFA3BFA4BFA5BFA6BFA7BFA8BFA9BFAABFABBFAC
+BFADBFAEBFAFBFB1BFB2BFB3BFB4BFB5BFB6BFB7BFB800000000000000000000
+0000BFB9BFBABFBBBFBCBFBDBFBEBFBFBFC0BFC1BFC2BFC3BFC4BFC6BFC7BFC8
+BFC9BFCABFCBBFCEBFCFBFD1BFD2BFD3BFD5BFD6BFD7BFD8BFD9BFDABFDBBFDD
+BFDEBFE0BFE2BFE3BFE4BFE5BFE6BFE7BFE8BFE9BFEABFEBBFECBFEDBFEEBFEF
+BFF0BFF1BFF2BFF3BFF4BFF5BFF6BFF7BFF8BFF9BFFABFFBBFFCBFFDBFFEBFFF
+C000C001C002C003C004C005C006C007C008C009C00AC00BC00CC00DC00EC00F
+C010C011C012C013C014C015C016C017C018C019C01AC01BC01CC01DC01EC01F
+C020C021C022C023C024C025C026C027C028C029C02AC02BC02CC02DC02EC02F
+C030C031C032C033C034C035C036C037C038C039C03AC03BC03DC03EC03F0000
+98
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000C040C041C042C043C044C045C046C047C048C049C04AC04BC04CC04DC04E
+C04FC050C052C053C054C055C056C057C059C05AC05B00000000000000000000
+0000C05DC05EC05FC061C062C063C064C065C066C067C06AC06BC06CC06DC06E
+C06FC070C071C072C073C074C075C076C077C078C07900000000000000000000
+0000C07AC07BC07CC07DC07EC07FC080C081C082C083C084C085C086C087C088
+C089C08AC08BC08CC08DC08EC08FC092C093C095C096C097C099C09AC09BC09C
+C09DC09EC09FC0A2C0A4C0A6C0A7C0A8C0A9C0AAC0ABC0AEC0B1C0B2C0B7C0B8
+C0B9C0BAC0BBC0BEC0C2C0C3C0C4C0C6C0C7C0CAC0CBC0CDC0CEC0CFC0D1C0D2
+C0D3C0D4C0D5C0D6C0D7C0DAC0DEC0DFC0E0C0E1C0E2C0E3C0E6C0E7C0E9C0EA
+C0EBC0EDC0EEC0EFC0F0C0F1C0F2C0F3C0F6C0F8C0FAC0FBC0FCC0FDC0FEC0FF
+C101C102C103C105C106C107C109C10AC10BC10CC10DC10EC10FC111C112C113
+C114C116C117C118C119C11AC11BC121C122C125C128C129C12AC12BC12E0000
+99
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000C132C133C134C135C137C13AC13BC13DC13EC13FC141C142C143C144C145
+C146C147C14AC14EC14FC150C151C152C153C156C15700000000000000000000
+0000C159C15AC15BC15DC15EC15FC160C161C162C163C166C16AC16BC16CC16D
+C16EC16FC171C172C173C175C176C177C179C17AC17B00000000000000000000
+0000C17CC17DC17EC17FC180C181C182C183C184C186C187C188C189C18AC18B
+C18FC191C192C193C195C197C198C199C19AC19BC19EC1A0C1A2C1A3C1A4C1A6
+C1A7C1AAC1ABC1ADC1AEC1AFC1B1C1B2C1B3C1B4C1B5C1B6C1B7C1B8C1B9C1BA
+C1BBC1BCC1BEC1BFC1C0C1C1C1C2C1C3C1C5C1C6C1C7C1C9C1CAC1CBC1CDC1CE
+C1CFC1D0C1D1C1D2C1D3C1D5C1D6C1D9C1DAC1DBC1DCC1DDC1DEC1DFC1E1C1E2
+C1E3C1E5C1E6C1E7C1E9C1EAC1EBC1ECC1EDC1EEC1EFC1F2C1F4C1F5C1F6C1F7
+C1F8C1F9C1FAC1FBC1FEC1FFC201C202C203C205C206C207C208C209C20AC20B
+C20EC210C212C213C214C215C216C217C21AC21BC21DC21EC221C222C2230000
+9A
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000C224C225C226C227C22AC22CC22EC230C233C235C236C237C238C239C23A
+C23BC23CC23DC23EC23FC240C241C242C243C244C24500000000000000000000
+0000C246C247C249C24AC24BC24CC24DC24EC24FC252C253C255C256C257C259
+C25AC25BC25CC25DC25EC25FC261C262C263C264C26600000000000000000000
+0000C267C268C269C26AC26BC26EC26FC271C272C273C275C276C277C278C279
+C27AC27BC27EC280C282C283C284C285C286C287C28AC28BC28CC28DC28EC28F
+C291C292C293C294C295C296C297C299C29AC29CC29EC29FC2A0C2A1C2A2C2A3
+C2A6C2A7C2A9C2AAC2ABC2AEC2AFC2B0C2B1C2B2C2B3C2B6C2B8C2BAC2BBC2BC
+C2BDC2BEC2BFC2C0C2C1C2C2C2C3C2C4C2C5C2C6C2C7C2C8C2C9C2CAC2CBC2CC
+C2CDC2CEC2CFC2D0C2D1C2D2C2D3C2D4C2D5C2D6C2D7C2D8C2D9C2DAC2DBC2DE
+C2DFC2E1C2E2C2E5C2E6C2E7C2E8C2E9C2EAC2EEC2F0C2F2C2F3C2F4C2F5C2F7
+C2FAC2FDC2FEC2FFC301C302C303C304C305C306C307C30AC30BC30EC30F0000
+9B
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000C310C311C312C316C317C319C31AC31BC31DC31EC31FC320C321C322C323
+C326C327C32AC32BC32CC32DC32EC32FC330C331C33200000000000000000000
+0000C333C334C335C336C337C338C339C33AC33BC33CC33DC33EC33FC340C341
+C342C343C344C346C347C348C349C34AC34BC34CC34D00000000000000000000
+0000C34EC34FC350C351C352C353C354C355C356C357C358C359C35AC35BC35C
+C35DC35EC35FC360C361C362C363C364C365C366C367C36AC36BC36DC36EC36F
+C371C373C374C375C376C377C37AC37BC37EC37FC380C381C382C383C385C386
+C387C389C38AC38BC38DC38EC38FC390C391C392C393C394C395C396C397C398
+C399C39AC39BC39CC39DC39EC39FC3A0C3A1C3A2C3A3C3A4C3A5C3A6C3A7C3A8
+C3A9C3AAC3ABC3ACC3ADC3AEC3AFC3B0C3B1C3B2C3B3C3B4C3B5C3B6C3B7C3B8
+C3B9C3BAC3BBC3BCC3BDC3BEC3BFC3C1C3C2C3C3C3C4C3C5C3C6C3C7C3C8C3C9
+C3CAC3CBC3CCC3CDC3CEC3CFC3D0C3D1C3D2C3D3C3D4C3D5C3D6C3D7C3DA0000
+9C
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000C3DBC3DDC3DEC3E1C3E3C3E4C3E5C3E6C3E7C3EAC3EBC3ECC3EEC3EFC3F0
+C3F1C3F2C3F3C3F6C3F7C3F9C3FAC3FBC3FCC3FDC3FE00000000000000000000
+0000C3FFC400C401C402C403C404C405C406C407C409C40AC40BC40CC40DC40E
+C40FC411C412C413C414C415C416C417C418C419C41A00000000000000000000
+0000C41BC41CC41DC41EC41FC420C421C422C423C425C426C427C428C429C42A
+C42BC42DC42EC42FC431C432C433C435C436C437C438C439C43AC43BC43EC43F
+C440C441C442C443C444C445C446C447C449C44AC44BC44CC44DC44EC44FC450
+C451C452C453C454C455C456C457C458C459C45AC45BC45CC45DC45EC45FC460
+C461C462C463C466C467C469C46AC46BC46DC46EC46FC470C471C472C473C476
+C477C478C47AC47BC47CC47DC47EC47FC481C482C483C484C485C486C487C488
+C489C48AC48BC48CC48DC48EC48FC490C491C492C493C495C496C497C498C499
+C49AC49BC49DC49EC49FC4A0C4A1C4A2C4A3C4A4C4A5C4A6C4A7C4A8C4A90000
+9D
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000C4AAC4ABC4ACC4ADC4AEC4AFC4B0C4B1C4B2C4B3C4B4C4B5C4B6C4B7C4B9
+C4BAC4BBC4BDC4BEC4BFC4C0C4C1C4C2C4C3C4C4C4C500000000000000000000
+0000C4C6C4C7C4C8C4C9C4CAC4CBC4CCC4CDC4CEC4CFC4D0C4D1C4D2C4D3C4D4
+C4D5C4D6C4D7C4D8C4D9C4DAC4DBC4DCC4DDC4DEC4DF00000000000000000000
+0000C4E0C4E1C4E2C4E3C4E4C4E5C4E6C4E7C4E8C4EAC4EBC4ECC4EDC4EEC4EF
+C4F2C4F3C4F5C4F6C4F7C4F9C4FBC4FCC4FDC4FEC502C503C504C505C506C507
+C508C509C50AC50BC50DC50EC50FC511C512C513C515C516C517C518C519C51A
+C51BC51DC51EC51FC520C521C522C523C524C525C526C527C52AC52BC52DC52E
+C52FC531C532C533C534C535C536C537C53AC53CC53EC53FC540C541C542C543
+C546C547C54BC54FC550C551C552C556C55AC55BC55CC55FC562C563C565C566
+C567C569C56AC56BC56CC56DC56EC56FC572C576C577C578C579C57AC57BC57E
+C57FC581C582C583C585C586C588C589C58AC58BC58EC590C592C593C5940000
+9E
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000C596C599C59AC59BC59DC59EC59FC5A1C5A2C5A3C5A4C5A5C5A6C5A7C5A8
+C5AAC5ABC5ACC5ADC5AEC5AFC5B0C5B1C5B2C5B3C5B600000000000000000000
+0000C5B7C5BAC5BFC5C0C5C1C5C2C5C3C5CBC5CDC5CFC5D2C5D3C5D5C5D6C5D7
+C5D9C5DAC5DBC5DCC5DDC5DEC5DFC5E2C5E4C5E6C5E700000000000000000000
+0000C5E8C5E9C5EAC5EBC5EFC5F1C5F2C5F3C5F5C5F8C5F9C5FAC5FBC602C603
+C604C609C60AC60BC60DC60EC60FC611C612C613C614C615C616C617C61AC61D
+C61EC61FC620C621C622C623C626C627C629C62AC62BC62FC631C632C636C638
+C63AC63CC63DC63EC63FC642C643C645C646C647C649C64AC64BC64CC64DC64E
+C64FC652C656C657C658C659C65AC65BC65EC65FC661C662C663C664C665C666
+C667C668C669C66AC66BC66DC66EC670C672C673C674C675C676C677C67AC67B
+C67DC67EC67FC681C682C683C684C685C686C687C68AC68CC68EC68FC690C691
+C692C693C696C697C699C69AC69BC69DC69EC69FC6A0C6A1C6A2C6A3C6A60000
+9F
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000C6A8C6AAC6ABC6ACC6ADC6AEC6AFC6B2C6B3C6B5C6B6C6B7C6BBC6BCC6BD
+C6BEC6BFC6C2C6C4C6C6C6C7C6C8C6C9C6CAC6CBC6CE00000000000000000000
+0000C6CFC6D1C6D2C6D3C6D5C6D6C6D7C6D8C6D9C6DAC6DBC6DEC6DFC6E2C6E3
+C6E4C6E5C6E6C6E7C6EAC6EBC6EDC6EEC6EFC6F1C6F200000000000000000000
+0000C6F3C6F4C6F5C6F6C6F7C6FAC6FBC6FCC6FEC6FFC700C701C702C703C706
+C707C709C70AC70BC70DC70EC70FC710C711C712C713C716C718C71AC71BC71C
+C71DC71EC71FC722C723C725C726C727C729C72AC72BC72CC72DC72EC72FC732
+C734C736C738C739C73AC73BC73EC73FC741C742C743C745C746C747C748C749
+C74BC74EC750C759C75AC75BC75DC75EC75FC761C762C763C764C765C766C767
+C769C76AC76CC76DC76EC76FC770C771C772C773C776C777C779C77AC77BC77F
+C780C781C782C786C78BC78CC78DC78FC792C793C795C799C79BC79CC79DC79E
+C79FC7A2C7A7C7A8C7A9C7AAC7ABC7AEC7AFC7B1C7B2C7B3C7B5C7B6C7B70000
+A0
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000C7B8C7B9C7BAC7BBC7BEC7C2C7C3C7C4C7C5C7C6C7C7C7CAC7CBC7CDC7CF
+C7D1C7D2C7D3C7D4C7D5C7D6C7D7C7D9C7DAC7DBC7DC00000000000000000000
+0000C7DEC7DFC7E0C7E1C7E2C7E3C7E5C7E6C7E7C7E9C7EAC7EBC7EDC7EEC7EF
+C7F0C7F1C7F2C7F3C7F4C7F5C7F6C7F7C7F8C7F9C7FA00000000000000000000
+0000C7FBC7FCC7FDC7FEC7FFC802C803C805C806C807C809C80BC80CC80DC80E
+C80FC812C814C817C818C819C81AC81BC81EC81FC821C822C823C825C826C827
+C828C829C82AC82BC82EC830C832C833C834C835C836C837C839C83AC83BC83D
+C83EC83FC841C842C843C844C845C846C847C84AC84BC84EC84FC850C851C852
+C853C855C856C857C858C859C85AC85BC85CC85DC85EC85FC860C861C862C863
+C864C865C866C867C868C869C86AC86BC86CC86DC86EC86FC872C873C875C876
+C877C879C87BC87CC87DC87EC87FC882C884C888C889C88AC88EC88FC890C891
+C892C893C895C896C897C898C899C89AC89BC89CC89EC8A0C8A2C8A3C8A40000
+A1
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000C8A5C8A6C8A7C8A9C8AAC8ABC8ACC8ADC8AEC8AFC8B0C8B1C8B2C8B3C8B4
+C8B5C8B6C8B7C8B8C8B9C8BAC8BBC8BEC8BFC8C0C8C100000000000000000000
+0000C8C2C8C3C8C5C8C6C8C7C8C9C8CAC8CBC8CDC8CEC8CFC8D0C8D1C8D2C8D3
+C8D6C8D8C8DAC8DBC8DCC8DDC8DEC8DFC8E2C8E3C8E500000000000000000000
+0000C8E6C8E7C8E8C8E9C8EAC8EBC8ECC8EDC8EEC8EFC8F0C8F1C8F2C8F3C8F4
+C8F6C8F7C8F8C8F9C8FAC8FBC8FEC8FFC901C902C903C907C908C909C90AC90B
+C90E30003001300200B72025202600A8300300AD20152225FF3C223C20182019
+201C201D3014301530083009300A300B300C300D300E300F3010301100B100D7
+00F7226022642265221E223400B0203220332103212BFFE0FFE1FFE526422640
+222022A52312220222072261225200A7203B2606260525CB25CF25CE25C725C6
+25A125A025B325B225BD25BC219221902191219321943013226A226B221A223D
+221D2235222B222C2208220B2286228722822283222A222922272228FFE20000
+A2
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000C910C912C913C914C915C916C917C919C91AC91BC91CC91DC91EC91FC920
+C921C922C923C924C925C926C927C928C929C92AC92B00000000000000000000
+0000C92DC92EC92FC930C931C932C933C935C936C937C938C939C93AC93BC93C
+C93DC93EC93FC940C941C942C943C944C945C946C94700000000000000000000
+0000C948C949C94AC94BC94CC94DC94EC94FC952C953C955C956C957C959C95A
+C95BC95CC95DC95EC95FC962C964C965C966C967C968C969C96AC96BC96DC96E
+C96F21D221D42200220300B4FF5E02C702D802DD02DA02D900B802DB00A100BF
+02D0222E2211220F00A42109203025C125C025B725B626642660266126652667
+2663229925C825A325D025D1259225A425A525A825A725A625A92668260F260E
+261C261E00B62020202121952197219921962198266D2669266A266C327F321C
+211633C7212233C233D8212120AC00AE00000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+A3
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000C971C972C973C975C976C977C978C979C97AC97BC97DC97EC97FC980C981
+C982C983C984C985C986C987C98AC98BC98DC98EC98F00000000000000000000
+0000C991C992C993C994C995C996C997C99AC99CC99EC99FC9A0C9A1C9A2C9A3
+C9A4C9A5C9A6C9A7C9A8C9A9C9AAC9ABC9ACC9ADC9AE00000000000000000000
+0000C9AFC9B0C9B1C9B2C9B3C9B4C9B5C9B6C9B7C9B8C9B9C9BAC9BBC9BCC9BD
+C9BEC9BFC9C2C9C3C9C5C9C6C9C9C9CBC9CCC9CDC9CEC9CFC9D2C9D4C9D7C9D8
+C9DBFF01FF02FF03FF04FF05FF06FF07FF08FF09FF0AFF0BFF0CFF0DFF0EFF0F
+FF10FF11FF12FF13FF14FF15FF16FF17FF18FF19FF1AFF1BFF1CFF1DFF1EFF1F
+FF20FF21FF22FF23FF24FF25FF26FF27FF28FF29FF2AFF2BFF2CFF2DFF2EFF2F
+FF30FF31FF32FF33FF34FF35FF36FF37FF38FF39FF3AFF3BFFE6FF3DFF3EFF3F
+FF40FF41FF42FF43FF44FF45FF46FF47FF48FF49FF4AFF4BFF4CFF4DFF4EFF4F
+FF50FF51FF52FF53FF54FF55FF56FF57FF58FF59FF5AFF5BFF5CFF5DFFE30000
+A4
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000C9DEC9DFC9E1C9E3C9E5C9E6C9E8C9E9C9EAC9EBC9EEC9F2C9F3C9F4C9F5
+C9F6C9F7C9FAC9FBC9FDC9FEC9FFCA01CA02CA03CA0400000000000000000000
+0000CA05CA06CA07CA0ACA0ECA0FCA10CA11CA12CA13CA15CA16CA17CA19CA1A
+CA1BCA1CCA1DCA1ECA1FCA20CA21CA22CA23CA24CA2500000000000000000000
+0000CA26CA27CA28CA2ACA2BCA2CCA2DCA2ECA2FCA30CA31CA32CA33CA34CA35
+CA36CA37CA38CA39CA3ACA3BCA3CCA3DCA3ECA3FCA40CA41CA42CA43CA44CA45
+CA46313131323133313431353136313731383139313A313B313C313D313E313F
+3140314131423143314431453146314731483149314A314B314C314D314E314F
+3150315131523153315431553156315731583159315A315B315C315D315E315F
+3160316131623163316431653166316731683169316A316B316C316D316E316F
+3170317131723173317431753176317731783179317A317B317C317D317E317F
+3180318131823183318431853186318731883189318A318B318C318D318E0000
+A5
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000CA47CA48CA49CA4ACA4BCA4ECA4FCA51CA52CA53CA55CA56CA57CA58CA59
+CA5ACA5BCA5ECA62CA63CA64CA65CA66CA67CA69CA6A00000000000000000000
+0000CA6BCA6CCA6DCA6ECA6FCA70CA71CA72CA73CA74CA75CA76CA77CA78CA79
+CA7ACA7BCA7CCA7ECA7FCA80CA81CA82CA83CA85CA8600000000000000000000
+0000CA87CA88CA89CA8ACA8BCA8CCA8DCA8ECA8FCA90CA91CA92CA93CA94CA95
+CA96CA97CA99CA9ACA9BCA9CCA9DCA9ECA9FCAA0CAA1CAA2CAA3CAA4CAA5CAA6
+CAA7217021712172217321742175217621772178217900000000000000000000
+2160216121622163216421652166216721682169000000000000000000000000
+0000039103920393039403950396039703980399039A039B039C039D039E039F
+03A003A103A303A403A503A603A703A803A90000000000000000000000000000
+000003B103B203B303B403B503B603B703B803B903BA03BB03BC03BD03BE03BF
+03C003C103C303C403C503C603C703C803C90000000000000000000000000000
+A6
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000CAA8CAA9CAAACAABCAACCAADCAAECAAFCAB0CAB1CAB2CAB3CAB4CAB5CAB6
+CAB7CAB8CAB9CABACABBCABECABFCAC1CAC2CAC3CAC500000000000000000000
+0000CAC6CAC7CAC8CAC9CACACACBCACECAD0CAD2CAD4CAD5CAD6CAD7CADACADB
+CADCCADDCADECADFCAE1CAE2CAE3CAE4CAE5CAE6CAE700000000000000000000
+0000CAE8CAE9CAEACAEBCAEDCAEECAEFCAF0CAF1CAF2CAF3CAF5CAF6CAF7CAF8
+CAF9CAFACAFBCAFCCAFDCAFECAFFCB00CB01CB02CB03CB04CB05CB06CB07CB09
+CB0A25002502250C251025182514251C252C25242534253C25012503250F2513
+251B251725232533252B253B254B2520252F25282537253F251D253025252538
+254225122511251A251925162515250E250D251E251F25212522252625272529
+252A252D252E25312532253525362539253A253D253E25402541254325442545
+2546254725482549254A00000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+A7
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000CB0BCB0CCB0DCB0ECB0FCB11CB12CB13CB15CB16CB17CB19CB1ACB1BCB1C
+CB1DCB1ECB1FCB22CB23CB24CB25CB26CB27CB28CB2900000000000000000000
+0000CB2ACB2BCB2CCB2DCB2ECB2FCB30CB31CB32CB33CB34CB35CB36CB37CB38
+CB39CB3ACB3BCB3CCB3DCB3ECB3FCB40CB42CB43CB4400000000000000000000
+0000CB45CB46CB47CB4ACB4BCB4DCB4ECB4FCB51CB52CB53CB54CB55CB56CB57
+CB5ACB5BCB5CCB5ECB5FCB60CB61CB62CB63CB65CB66CB67CB68CB69CB6ACB6B
+CB6C3395339633972113339833C433A333A433A533A63399339A339B339C339D
+339E339F33A033A133A233CA338D338E338F33CF3388338933C833A733A833B0
+33B133B233B333B433B533B633B733B833B93380338133823383338433BA33BB
+33BC33BD33BE33BF33903391339233933394212633C033C1338A338B338C33D6
+33C533AD33AE33AF33DB33A933AA33AB33AC33DD33D033D333C333C933DC33C6
+0000000000000000000000000000000000000000000000000000000000000000
+A8
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000CB6DCB6ECB6FCB70CB71CB72CB73CB74CB75CB76CB77CB7ACB7BCB7CCB7D
+CB7ECB7FCB80CB81CB82CB83CB84CB85CB86CB87CB8800000000000000000000
+0000CB89CB8ACB8BCB8CCB8DCB8ECB8FCB90CB91CB92CB93CB94CB95CB96CB97
+CB98CB99CB9ACB9BCB9DCB9ECB9FCBA0CBA1CBA2CBA300000000000000000000
+0000CBA4CBA5CBA6CBA7CBA8CBA9CBAACBABCBACCBADCBAECBAFCBB0CBB1CBB2
+CBB3CBB4CBB5CBB6CBB7CBB9CBBACBBBCBBCCBBDCBBECBBFCBC0CBC1CBC2CBC3
+CBC400C600D000AA0126000001320000013F014100D8015200BA00DE0166014A
+00003260326132623263326432653266326732683269326A326B326C326D326E
+326F3270327132723273327432753276327732783279327A327B24D024D124D2
+24D324D424D524D624D724D824D924DA24DB24DC24DD24DE24DF24E024E124E2
+24E324E424E524E624E724E824E9246024612462246324642465246624672468
+2469246A246B246C246D246E00BD2153215400BC00BE215B215C215D215E0000
+A9
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000CBC5CBC6CBC7CBC8CBC9CBCACBCBCBCCCBCDCBCECBCFCBD0CBD1CBD2CBD3
+CBD5CBD6CBD7CBD8CBD9CBDACBDBCBDCCBDDCBDECBDF00000000000000000000
+0000CBE0CBE1CBE2CBE3CBE5CBE6CBE8CBEACBEBCBECCBEDCBEECBEFCBF0CBF1
+CBF2CBF3CBF4CBF5CBF6CBF7CBF8CBF9CBFACBFBCBFC00000000000000000000
+0000CBFDCBFECBFFCC00CC01CC02CC03CC04CC05CC06CC07CC08CC09CC0ACC0B
+CC0ECC0FCC11CC12CC13CC15CC16CC17CC18CC19CC1ACC1BCC1ECC1FCC20CC23
+CC2400E6011100F001270131013301380140014200F8015300DF00FE0167014B
+01493200320132023203320432053206320732083209320A320B320C320D320E
+320F3210321132123213321432153216321732183219321A321B249C249D249E
+249F24A024A124A224A324A424A524A624A724A824A924AA24AB24AC24AD24AE
+24AF24B024B124B224B324B424B5247424752476247724782479247A247B247C
+247D247E247F24802481248200B900B200B32074207F20812082208320840000
+AA
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000CC25CC26CC2ACC2BCC2DCC2FCC31CC32CC33CC34CC35CC36CC37CC3ACC3F
+CC40CC41CC42CC43CC46CC47CC49CC4ACC4BCC4DCC4E00000000000000000000
+0000CC4FCC50CC51CC52CC53CC56CC5ACC5BCC5CCC5DCC5ECC5FCC61CC62CC63
+CC65CC67CC69CC6ACC6BCC6CCC6DCC6ECC6FCC71CC7200000000000000000000
+0000CC73CC74CC76CC77CC78CC79CC7ACC7BCC7CCC7DCC7ECC7FCC80CC81CC82
+CC83CC84CC85CC86CC87CC88CC89CC8ACC8BCC8CCC8DCC8ECC8FCC90CC91CC92
+CC93304130423043304430453046304730483049304A304B304C304D304E304F
+3050305130523053305430553056305730583059305A305B305C305D305E305F
+3060306130623063306430653066306730683069306A306B306C306D306E306F
+3070307130723073307430753076307730783079307A307B307C307D307E307F
+3080308130823083308430853086308730883089308A308B308C308D308E308F
+3090309130923093000000000000000000000000000000000000000000000000
+AB
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000CC94CC95CC96CC97CC9ACC9BCC9DCC9ECC9FCCA1CCA2CCA3CCA4CCA5CCA6
+CCA7CCAACCAECCAFCCB0CCB1CCB2CCB3CCB6CCB7CCB900000000000000000000
+0000CCBACCBBCCBDCCBECCBFCCC0CCC1CCC2CCC3CCC6CCC8CCCACCCBCCCCCCCD
+CCCECCCFCCD1CCD2CCD3CCD5CCD6CCD7CCD8CCD9CCDA00000000000000000000
+0000CCDBCCDCCCDDCCDECCDFCCE0CCE1CCE2CCE3CCE5CCE6CCE7CCE8CCE9CCEA
+CCEBCCEDCCEECCEFCCF1CCF2CCF3CCF4CCF5CCF6CCF7CCF8CCF9CCFACCFBCCFC
+CCFD30A130A230A330A430A530A630A730A830A930AA30AB30AC30AD30AE30AF
+30B030B130B230B330B430B530B630B730B830B930BA30BB30BC30BD30BE30BF
+30C030C130C230C330C430C530C630C730C830C930CA30CB30CC30CD30CE30CF
+30D030D130D230D330D430D530D630D730D830D930DA30DB30DC30DD30DE30DF
+30E030E130E230E330E430E530E630E730E830E930EA30EB30EC30ED30EE30EF
+30F030F130F230F330F430F530F6000000000000000000000000000000000000
+AC
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000CCFECCFFCD00CD02CD03CD04CD05CD06CD07CD0ACD0BCD0DCD0ECD0FCD11
+CD12CD13CD14CD15CD16CD17CD1ACD1CCD1ECD1FCD2000000000000000000000
+0000CD21CD22CD23CD25CD26CD27CD29CD2ACD2BCD2DCD2ECD2FCD30CD31CD32
+CD33CD34CD35CD36CD37CD38CD3ACD3BCD3CCD3DCD3E00000000000000000000
+0000CD3FCD40CD41CD42CD43CD44CD45CD46CD47CD48CD49CD4ACD4BCD4CCD4D
+CD4ECD4FCD50CD51CD52CD53CD54CD55CD56CD57CD58CD59CD5ACD5BCD5DCD5E
+CD5F04100411041204130414041504010416041704180419041A041B041C041D
+041E041F0420042104220423042404250426042704280429042A042B042C042D
+042E042F00000000000000000000000000000000000000000000000000000000
+000004300431043204330434043504510436043704380439043A043B043C043D
+043E043F0440044104420443044404450446044704480449044A044B044C044D
+044E044F00000000000000000000000000000000000000000000000000000000
+AD
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000CD61CD62CD63CD65CD66CD67CD68CD69CD6ACD6BCD6ECD70CD72CD73CD74
+CD75CD76CD77CD79CD7ACD7BCD7CCD7DCD7ECD7FCD8000000000000000000000
+0000CD81CD82CD83CD84CD85CD86CD87CD89CD8ACD8BCD8CCD8DCD8ECD8FCD90
+CD91CD92CD93CD96CD97CD99CD9ACD9BCD9DCD9ECD9F00000000000000000000
+0000CDA0CDA1CDA2CDA3CDA6CDA8CDAACDABCDACCDADCDAECDAFCDB1CDB2CDB3
+CDB4CDB5CDB6CDB7CDB8CDB9CDBACDBBCDBCCDBDCDBECDBFCDC0CDC1CDC2CDC3
+CDC5000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+AE
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000CDC6CDC7CDC8CDC9CDCACDCBCDCDCDCECDCFCDD1CDD2CDD3CDD4CDD5CDD6
+CDD7CDD8CDD9CDDACDDBCDDCCDDDCDDECDDFCDE0CDE100000000000000000000
+0000CDE2CDE3CDE4CDE5CDE6CDE7CDE9CDEACDEBCDEDCDEECDEFCDF1CDF2CDF3
+CDF4CDF5CDF6CDF7CDFACDFCCDFECDFFCE00CE01CE0200000000000000000000
+0000CE03CE05CE06CE07CE09CE0ACE0BCE0DCE0ECE0FCE10CE11CE12CE13CE15
+CE16CE17CE18CE1ACE1BCE1CCE1DCE1ECE1FCE22CE23CE25CE26CE27CE29CE2A
+CE2B000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+AF
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000CE2CCE2DCE2ECE2FCE32CE34CE36CE37CE38CE39CE3ACE3BCE3CCE3DCE3E
+CE3FCE40CE41CE42CE43CE44CE45CE46CE47CE48CE4900000000000000000000
+0000CE4ACE4BCE4CCE4DCE4ECE4FCE50CE51CE52CE53CE54CE55CE56CE57CE5A
+CE5BCE5DCE5ECE62CE63CE64CE65CE66CE67CE6ACE6C00000000000000000000
+0000CE6ECE6FCE70CE71CE72CE73CE76CE77CE79CE7ACE7BCE7DCE7ECE7FCE80
+CE81CE82CE83CE86CE88CE8ACE8BCE8CCE8DCE8ECE8FCE92CE93CE95CE96CE97
+CE99000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+B0
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000CE9ACE9BCE9CCE9DCE9ECE9FCEA2CEA6CEA7CEA8CEA9CEAACEABCEAECEAF
+CEB0CEB1CEB2CEB3CEB4CEB5CEB6CEB7CEB8CEB9CEBA00000000000000000000
+0000CEBBCEBCCEBDCEBECEBFCEC0CEC2CEC3CEC4CEC5CEC6CEC7CEC8CEC9CECA
+CECBCECCCECDCECECECFCED0CED1CED2CED3CED4CED500000000000000000000
+0000CED6CED7CED8CED9CEDACEDBCEDCCEDDCEDECEDFCEE0CEE1CEE2CEE3CEE6
+CEE7CEE9CEEACEEDCEEECEEFCEF0CEF1CEF2CEF3CEF6CEFACEFBCEFCCEFDCEFE
+CEFFAC00AC01AC04AC07AC08AC09AC0AAC10AC11AC12AC13AC14AC15AC16AC17
+AC19AC1AAC1BAC1CAC1DAC20AC24AC2CAC2DAC2FAC30AC31AC38AC39AC3CAC40
+AC4BAC4DAC54AC58AC5CAC70AC71AC74AC77AC78AC7AAC80AC81AC83AC84AC85
+AC86AC89AC8AAC8BAC8CAC90AC94AC9CAC9DAC9FACA0ACA1ACA8ACA9ACAAACAC
+ACAFACB0ACB8ACB9ACBBACBCACBDACC1ACC4ACC8ACCCACD5ACD7ACE0ACE1ACE4
+ACE7ACE8ACEAACECACEFACF0ACF1ACF3ACF5ACF6ACFCACFDAD00AD04AD060000
+B1
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000CF02CF03CF05CF06CF07CF09CF0ACF0BCF0CCF0DCF0ECF0FCF12CF14CF16
+CF17CF18CF19CF1ACF1BCF1DCF1ECF1FCF21CF22CF2300000000000000000000
+0000CF25CF26CF27CF28CF29CF2ACF2BCF2ECF32CF33CF34CF35CF36CF37CF39
+CF3ACF3BCF3CCF3DCF3ECF3FCF40CF41CF42CF43CF4400000000000000000000
+0000CF45CF46CF47CF48CF49CF4ACF4BCF4CCF4DCF4ECF4FCF50CF51CF52CF53
+CF56CF57CF59CF5ACF5BCF5DCF5ECF5FCF60CF61CF62CF63CF66CF68CF6ACF6B
+CF6CAD0CAD0DAD0FAD11AD18AD1CAD20AD29AD2CAD2DAD34AD35AD38AD3CAD44
+AD45AD47AD49AD50AD54AD58AD61AD63AD6CAD6DAD70AD73AD74AD75AD76AD7B
+AD7CAD7DAD7FAD81AD82AD88AD89AD8CAD90AD9CAD9DADA4ADB7ADC0ADC1ADC4
+ADC8ADD0ADD1ADD3ADDCADE0ADE4ADF8ADF9ADFCADFFAE00AE01AE08AE09AE0B
+AE0DAE14AE30AE31AE34AE37AE38AE3AAE40AE41AE43AE45AE46AE4AAE4CAE4D
+AE4EAE50AE54AE56AE5CAE5DAE5FAE60AE61AE65AE68AE69AE6CAE70AE780000
+B2
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000CF6DCF6ECF6FCF72CF73CF75CF76CF77CF79CF7ACF7BCF7CCF7DCF7ECF7F
+CF81CF82CF83CF84CF86CF87CF88CF89CF8ACF8BCF8D00000000000000000000
+0000CF8ECF8FCF90CF91CF92CF93CF94CF95CF96CF97CF98CF99CF9ACF9BCF9C
+CF9DCF9ECF9FCFA0CFA2CFA3CFA4CFA5CFA6CFA7CFA900000000000000000000
+0000CFAACFABCFACCFADCFAECFAFCFB1CFB2CFB3CFB4CFB5CFB6CFB7CFB8CFB9
+CFBACFBBCFBCCFBDCFBECFBFCFC0CFC1CFC2CFC3CFC5CFC6CFC7CFC8CFC9CFCA
+CFCBAE79AE7BAE7CAE7DAE84AE85AE8CAEBCAEBDAEBEAEC0AEC4AECCAECDAECF
+AED0AED1AED8AED9AEDCAEE8AEEBAEEDAEF4AEF8AEFCAF07AF08AF0DAF10AF2C
+AF2DAF30AF32AF34AF3CAF3DAF3FAF41AF42AF43AF48AF49AF50AF5CAF5DAF64
+AF65AF79AF80AF84AF88AF90AF91AF95AF9CAFB8AFB9AFBCAFC0AFC7AFC8AFC9
+AFCBAFCDAFCEAFD4AFDCAFE8AFE9AFF0AFF1AFF4AFF8B000B001B004B00CB010
+B014B01CB01DB028B044B045B048B04AB04CB04EB053B054B055B057B0590000
+B3
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000CFCCCFCDCFCECFCFCFD0CFD1CFD2CFD3CFD4CFD5CFD6CFD7CFD8CFD9CFDA
+CFDBCFDCCFDDCFDECFDFCFE2CFE3CFE5CFE6CFE7CFE900000000000000000000
+0000CFEACFEBCFECCFEDCFEECFEFCFF2CFF4CFF6CFF7CFF8CFF9CFFACFFBCFFD
+CFFECFFFD001D002D003D005D006D007D008D009D00A00000000000000000000
+0000D00BD00CD00DD00ED00FD010D012D013D014D015D016D017D019D01AD01B
+D01CD01DD01ED01FD020D021D022D023D024D025D026D027D028D029D02AD02B
+D02CB05DB07CB07DB080B084B08CB08DB08FB091B098B099B09AB09CB09FB0A0
+B0A1B0A2B0A8B0A9B0ABB0ACB0ADB0AEB0AFB0B1B0B3B0B4B0B5B0B8B0BCB0C4
+B0C5B0C7B0C8B0C9B0D0B0D1B0D4B0D8B0E0B0E5B108B109B10BB10CB110B112
+B113B118B119B11BB11CB11DB123B124B125B128B12CB134B135B137B138B139
+B140B141B144B148B150B151B154B155B158B15CB160B178B179B17CB180B182
+B188B189B18BB18DB192B193B194B198B19CB1A8B1CCB1D0B1D4B1DCB1DD0000
+B4
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000D02ED02FD030D031D032D033D036D037D039D03AD03BD03DD03ED03FD040
+D041D042D043D046D048D04AD04BD04CD04DD04ED04F00000000000000000000
+0000D051D052D053D055D056D057D059D05AD05BD05CD05DD05ED05FD061D062
+D063D064D065D066D067D068D069D06AD06BD06ED06F00000000000000000000
+0000D071D072D073D075D076D077D078D079D07AD07BD07ED07FD080D082D083
+D084D085D086D087D088D089D08AD08BD08CD08DD08ED08FD090D091D092D093
+D094B1DFB1E8B1E9B1ECB1F0B1F9B1FBB1FDB204B205B208B20BB20CB214B215
+B217B219B220B234B23CB258B25CB260B268B269B274B275B27CB284B285B289
+B290B291B294B298B299B29AB2A0B2A1B2A3B2A5B2A6B2AAB2ACB2B0B2B4B2C8
+B2C9B2CCB2D0B2D2B2D8B2D9B2DBB2DDB2E2B2E4B2E5B2E6B2E8B2EBB2ECB2ED
+B2EEB2EFB2F3B2F4B2F5B2F7B2F8B2F9B2FAB2FBB2FFB300B301B304B308B310
+B311B313B314B315B31CB354B355B356B358B35BB35CB35EB35FB364B3650000
+B5
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000D095D096D097D098D099D09AD09BD09CD09DD09ED09FD0A0D0A1D0A2D0A3
+D0A6D0A7D0A9D0AAD0ABD0ADD0AED0AFD0B0D0B1D0B200000000000000000000
+0000D0B3D0B6D0B8D0BAD0BBD0BCD0BDD0BED0BFD0C2D0C3D0C5D0C6D0C7D0CA
+D0CBD0CCD0CDD0CED0CFD0D2D0D6D0D7D0D8D0D9D0DA00000000000000000000
+0000D0DBD0DED0DFD0E1D0E2D0E3D0E5D0E6D0E7D0E8D0E9D0EAD0EBD0EED0F2
+D0F3D0F4D0F5D0F6D0F7D0F9D0FAD0FBD0FCD0FDD0FED0FFD100D101D102D103
+D104B367B369B36BB36EB370B371B374B378B380B381B383B384B385B38CB390
+B394B3A0B3A1B3A8B3ACB3C4B3C5B3C8B3CBB3CCB3CEB3D0B3D4B3D5B3D7B3D9
+B3DBB3DDB3E0B3E4B3E8B3FCB410B418B41CB420B428B429B42BB434B450B451
+B454B458B460B461B463B465B46CB480B488B49DB4A4B4A8B4ACB4B5B4B7B4B9
+B4C0B4C4B4C8B4D0B4D5B4DCB4DDB4E0B4E3B4E4B4E6B4ECB4EDB4EFB4F1B4F8
+B514B515B518B51BB51CB524B525B527B528B529B52AB530B531B534B5380000
+B6
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000D105D106D107D108D109D10AD10BD10CD10ED10FD110D111D112D113D114
+D115D116D117D118D119D11AD11BD11CD11DD11ED11F00000000000000000000
+0000D120D121D122D123D124D125D126D127D128D129D12AD12BD12CD12DD12E
+D12FD132D133D135D136D137D139D13BD13CD13DD13E00000000000000000000
+0000D13FD142D146D147D148D149D14AD14BD14ED14FD151D152D153D155D156
+D157D158D159D15AD15BD15ED160D162D163D164D165D166D167D169D16AD16B
+D16DB540B541B543B544B545B54BB54CB54DB550B554B55CB55DB55FB560B561
+B5A0B5A1B5A4B5A8B5AAB5ABB5B0B5B1B5B3B5B4B5B5B5BBB5BCB5BDB5C0B5C4
+B5CCB5CDB5CFB5D0B5D1B5D8B5ECB610B611B614B618B625B62CB634B648B664
+B668B69CB69DB6A0B6A4B6ABB6ACB6B1B6D4B6F0B6F4B6F8B700B701B705B728
+B729B72CB72FB730B738B739B73BB744B748B74CB754B755B760B764B768B770
+B771B773B775B77CB77DB780B784B78CB78DB78FB790B791B792B796B7970000
+B7
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000D16ED16FD170D171D172D173D174D175D176D177D178D179D17AD17BD17D
+D17ED17FD180D181D182D183D185D186D187D189D18A00000000000000000000
+0000D18BD18CD18DD18ED18FD190D191D192D193D194D195D196D197D198D199
+D19AD19BD19CD19DD19ED19FD1A2D1A3D1A5D1A6D1A700000000000000000000
+0000D1A9D1AAD1ABD1ACD1ADD1AED1AFD1B2D1B4D1B6D1B7D1B8D1B9D1BBD1BD
+D1BED1BFD1C1D1C2D1C3D1C4D1C5D1C6D1C7D1C8D1C9D1CAD1CBD1CCD1CDD1CE
+D1CFB798B799B79CB7A0B7A8B7A9B7ABB7ACB7ADB7B4B7B5B7B8B7C7B7C9B7EC
+B7EDB7F0B7F4B7FCB7FDB7FFB800B801B807B808B809B80CB810B818B819B81B
+B81DB824B825B828B82CB834B835B837B838B839B840B844B851B853B85CB85D
+B860B864B86CB86DB86FB871B878B87CB88DB8A8B8B0B8B4B8B8B8C0B8C1B8C3
+B8C5B8CCB8D0B8D4B8DDB8DFB8E1B8E8B8E9B8ECB8F0B8F8B8F9B8FBB8FDB904
+B918B920B93CB93DB940B944B94CB94FB951B958B959B95CB960B968B9690000
+B8
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000D1D0D1D1D1D2D1D3D1D4D1D5D1D6D1D7D1D9D1DAD1DBD1DCD1DDD1DED1DF
+D1E0D1E1D1E2D1E3D1E4D1E5D1E6D1E7D1E8D1E9D1EA00000000000000000000
+0000D1EBD1ECD1EDD1EED1EFD1F0D1F1D1F2D1F3D1F5D1F6D1F7D1F9D1FAD1FB
+D1FCD1FDD1FED1FFD200D201D202D203D204D205D20600000000000000000000
+0000D208D20AD20BD20CD20DD20ED20FD211D212D213D214D215D216D217D218
+D219D21AD21BD21CD21DD21ED21FD220D221D222D223D224D225D226D227D228
+D229B96BB96DB974B975B978B97CB984B985B987B989B98AB98DB98EB9ACB9AD
+B9B0B9B4B9BCB9BDB9BFB9C1B9C8B9C9B9CCB9CEB9CFB9D0B9D1B9D2B9D8B9D9
+B9DBB9DDB9DEB9E1B9E3B9E4B9E5B9E8B9ECB9F4B9F5B9F7B9F8B9F9B9FABA00
+BA01BA08BA15BA38BA39BA3CBA40BA42BA48BA49BA4BBA4DBA4EBA53BA54BA55
+BA58BA5CBA64BA65BA67BA68BA69BA70BA71BA74BA78BA83BA84BA85BA87BA8C
+BAA8BAA9BAABBAACBAB0BAB2BAB8BAB9BABBBABDBAC4BAC8BAD8BAD9BAFC0000
+B9
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000D22AD22BD22ED22FD231D232D233D235D236D237D238D239D23AD23BD23E
+D240D242D243D244D245D246D247D249D24AD24BD24C00000000000000000000
+0000D24DD24ED24FD250D251D252D253D254D255D256D257D258D259D25AD25B
+D25DD25ED25FD260D261D262D263D265D266D267D26800000000000000000000
+0000D269D26AD26BD26CD26DD26ED26FD270D271D272D273D274D275D276D277
+D278D279D27AD27BD27CD27DD27ED27FD282D283D285D286D287D289D28AD28B
+D28CBB00BB04BB0DBB0FBB11BB18BB1CBB20BB29BB2BBB34BB35BB36BB38BB3B
+BB3CBB3DBB3EBB44BB45BB47BB49BB4DBB4FBB50BB54BB58BB61BB63BB6CBB88
+BB8CBB90BBA4BBA8BBACBBB4BBB7BBC0BBC4BBC8BBD0BBD3BBF8BBF9BBFCBBFF
+BC00BC02BC08BC09BC0BBC0CBC0DBC0FBC11BC14BC15BC16BC17BC18BC1BBC1C
+BC1DBC1EBC1FBC24BC25BC27BC29BC2DBC30BC31BC34BC38BC40BC41BC43BC44
+BC45BC49BC4CBC4DBC50BC5DBC84BC85BC88BC8BBC8CBC8EBC94BC95BC970000
+BA
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000D28DD28ED28FD292D293D294D296D297D298D299D29AD29BD29DD29ED29F
+D2A1D2A2D2A3D2A5D2A6D2A7D2A8D2A9D2AAD2ABD2AD00000000000000000000
+0000D2AED2AFD2B0D2B2D2B3D2B4D2B5D2B6D2B7D2BAD2BBD2BDD2BED2C1D2C3
+D2C4D2C5D2C6D2C7D2CAD2CCD2CDD2CED2CFD2D0D2D100000000000000000000
+0000D2D2D2D3D2D5D2D6D2D7D2D9D2DAD2DBD2DDD2DED2DFD2E0D2E1D2E2D2E3
+D2E6D2E7D2E8D2E9D2EAD2EBD2ECD2EDD2EED2EFD2F2D2F3D2F5D2F6D2F7D2F9
+D2FABC99BC9ABCA0BCA1BCA4BCA7BCA8BCB0BCB1BCB3BCB4BCB5BCBCBCBDBCC0
+BCC4BCCDBCCFBCD0BCD1BCD5BCD8BCDCBCF4BCF5BCF6BCF8BCFCBD04BD05BD07
+BD09BD10BD14BD24BD2CBD40BD48BD49BD4CBD50BD58BD59BD64BD68BD80BD81
+BD84BD87BD88BD89BD8ABD90BD91BD93BD95BD99BD9ABD9CBDA4BDB0BDB8BDD4
+BDD5BDD8BDDCBDE9BDF0BDF4BDF8BE00BE03BE05BE0CBE0DBE10BE14BE1CBE1D
+BE1FBE44BE45BE48BE4CBE4EBE54BE55BE57BE59BE5ABE5BBE60BE61BE640000
+BB
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000D2FBD2FCD2FDD2FED2FFD302D304D306D307D308D309D30AD30BD30FD311
+D312D313D315D317D318D319D31AD31BD31ED322D32300000000000000000000
+0000D324D326D327D32AD32BD32DD32ED32FD331D332D333D334D335D336D337
+D33AD33ED33FD340D341D342D343D346D347D348D34900000000000000000000
+0000D34AD34BD34CD34DD34ED34FD350D351D352D353D354D355D356D357D358
+D359D35AD35BD35CD35DD35ED35FD360D361D362D363D364D365D366D367D368
+D369BE68BE6ABE70BE71BE73BE74BE75BE7BBE7CBE7DBE80BE84BE8CBE8DBE8F
+BE90BE91BE98BE99BEA8BED0BED1BED4BED7BED8BEE0BEE3BEE4BEE5BEECBF01
+BF08BF09BF18BF19BF1BBF1CBF1DBF40BF41BF44BF48BF50BF51BF55BF94BFB0
+BFC5BFCCBFCDBFD0BFD4BFDCBFDFBFE1C03CC051C058C05CC060C068C069C090
+C091C094C098C0A0C0A1C0A3C0A5C0ACC0ADC0AFC0B0C0B3C0B4C0B5C0B6C0BC
+C0BDC0BFC0C0C0C1C0C5C0C8C0C9C0CCC0D0C0D8C0D9C0DBC0DCC0DDC0E40000
+BC
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000D36AD36BD36CD36DD36ED36FD370D371D372D373D374D375D376D377D378
+D379D37AD37BD37ED37FD381D382D383D385D386D38700000000000000000000
+0000D388D389D38AD38BD38ED392D393D394D395D396D397D39AD39BD39DD39E
+D39FD3A1D3A2D3A3D3A4D3A5D3A6D3A7D3AAD3ACD3AE00000000000000000000
+0000D3AFD3B0D3B1D3B2D3B3D3B5D3B6D3B7D3B9D3BAD3BBD3BDD3BED3BFD3C0
+D3C1D3C2D3C3D3C6D3C7D3CAD3CBD3CCD3CDD3CED3CFD3D1D3D2D3D3D3D4D3D5
+D3D6C0E5C0E8C0ECC0F4C0F5C0F7C0F9C100C104C108C110C115C11CC11DC11E
+C11FC120C123C124C126C127C12CC12DC12FC130C131C136C138C139C13CC140
+C148C149C14BC14CC14DC154C155C158C15CC164C165C167C168C169C170C174
+C178C185C18CC18DC18EC190C194C196C19CC19DC19FC1A1C1A5C1A8C1A9C1AC
+C1B0C1BDC1C4C1C8C1CCC1D4C1D7C1D8C1E0C1E4C1E8C1F0C1F1C1F3C1FCC1FD
+C200C204C20CC20DC20FC211C218C219C21CC21FC220C228C229C22BC22D0000
+BD
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000D3D7D3D9D3DAD3DBD3DCD3DDD3DED3DFD3E0D3E2D3E4D3E5D3E6D3E7D3E8
+D3E9D3EAD3EBD3EED3EFD3F1D3F2D3F3D3F5D3F6D3F700000000000000000000
+0000D3F8D3F9D3FAD3FBD3FED400D402D403D404D405D406D407D409D40AD40B
+D40CD40DD40ED40FD410D411D412D413D414D415D41600000000000000000000
+0000D417D418D419D41AD41BD41CD41ED41FD420D421D422D423D424D425D426
+D427D428D429D42AD42BD42CD42DD42ED42FD430D431D432D433D434D435D436
+D437C22FC231C232C234C248C250C251C254C258C260C265C26CC26DC270C274
+C27CC27DC27FC281C288C289C290C298C29BC29DC2A4C2A5C2A8C2ACC2ADC2B4
+C2B5C2B7C2B9C2DCC2DDC2E0C2E3C2E4C2EBC2ECC2EDC2EFC2F1C2F6C2F8C2F9
+C2FBC2FCC300C308C309C30CC30DC313C314C315C318C31CC324C325C328C329
+C345C368C369C36CC370C372C378C379C37CC37DC384C388C38CC3C0C3D8C3D9
+C3DCC3DFC3E0C3E2C3E8C3E9C3EDC3F4C3F5C3F8C408C410C424C42CC4300000
+BE
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000D438D439D43AD43BD43CD43DD43ED43FD441D442D443D445D446D447D448
+D449D44AD44BD44CD44DD44ED44FD450D451D452D45300000000000000000000
+0000D454D455D456D457D458D459D45AD45BD45DD45ED45FD461D462D463D465
+D466D467D468D469D46AD46BD46CD46ED470D471D47200000000000000000000
+0000D473D474D475D476D477D47AD47BD47DD47ED481D483D484D485D486D487
+D48AD48CD48ED48FD490D491D492D493D495D496D497D498D499D49AD49BD49C
+D49DC434C43CC43DC448C464C465C468C46CC474C475C479C480C494C49CC4B8
+C4BCC4E9C4F0C4F1C4F4C4F8C4FAC4FFC500C501C50CC510C514C51CC528C529
+C52CC530C538C539C53BC53DC544C545C548C549C54AC54CC54DC54EC553C554
+C555C557C558C559C55DC55EC560C561C564C568C570C571C573C574C575C57C
+C57DC580C584C587C58CC58DC58FC591C595C597C598C59CC5A0C5A9C5B4C5B5
+C5B8C5B9C5BBC5BCC5BDC5BEC5C4C5C5C5C6C5C7C5C8C5C9C5CAC5CCC5CE0000
+BF
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000D49ED49FD4A0D4A1D4A2D4A3D4A4D4A5D4A6D4A7D4A8D4AAD4ABD4ACD4AD
+D4AED4AFD4B0D4B1D4B2D4B3D4B4D4B5D4B6D4B7D4B800000000000000000000
+0000D4B9D4BAD4BBD4BCD4BDD4BED4BFD4C0D4C1D4C2D4C3D4C4D4C5D4C6D4C7
+D4C8D4C9D4CAD4CBD4CDD4CED4CFD4D1D4D2D4D3D4D500000000000000000000
+0000D4D6D4D7D4D8D4D9D4DAD4DBD4DDD4DED4E0D4E1D4E2D4E3D4E4D4E5D4E6
+D4E7D4E9D4EAD4EBD4EDD4EED4EFD4F1D4F2D4F3D4F4D4F5D4F6D4F7D4F9D4FA
+D4FCC5D0C5D1C5D4C5D8C5E0C5E1C5E3C5E5C5ECC5EDC5EEC5F0C5F4C5F6C5F7
+C5FCC5FDC5FEC5FFC600C601C605C606C607C608C60CC610C618C619C61BC61C
+C624C625C628C62CC62DC62EC630C633C634C635C637C639C63BC640C641C644
+C648C650C651C653C654C655C65CC65DC660C66CC66FC671C678C679C67CC680
+C688C689C68BC68DC694C695C698C69CC6A4C6A5C6A7C6A9C6B0C6B1C6B4C6B8
+C6B9C6BAC6C0C6C1C6C3C6C5C6CCC6CDC6D0C6D4C6DCC6DDC6E0C6E1C6E80000
+C0
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000D4FED4FFD500D501D502D503D505D506D507D509D50AD50BD50DD50ED50F
+D510D511D512D513D516D518D519D51AD51BD51CD51D00000000000000000000
+0000D51ED51FD520D521D522D523D524D525D526D527D528D529D52AD52BD52C
+D52DD52ED52FD530D531D532D533D534D535D536D53700000000000000000000
+0000D538D539D53AD53BD53ED53FD541D542D543D545D546D547D548D549D54A
+D54BD54ED550D552D553D554D555D556D557D55AD55BD55DD55ED55FD561D562
+D563C6E9C6ECC6F0C6F8C6F9C6FDC704C705C708C70CC714C715C717C719C720
+C721C724C728C730C731C733C735C737C73CC73DC740C744C74AC74CC74DC74F
+C751C752C753C754C755C756C757C758C75CC760C768C76BC774C775C778C77C
+C77DC77EC783C784C785C787C788C789C78AC78EC790C791C794C796C797C798
+C79AC7A0C7A1C7A3C7A4C7A5C7A6C7ACC7ADC7B0C7B4C7BCC7BDC7BFC7C0C7C1
+C7C8C7C9C7CCC7CEC7D0C7D8C7DDC7E4C7E8C7ECC800C801C804C808C80A0000
+C1
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000D564D566D567D56AD56CD56ED56FD570D571D572D573D576D577D579D57A
+D57BD57DD57ED57FD580D581D582D583D586D58AD58B00000000000000000000
+0000D58CD58DD58ED58FD591D592D593D594D595D596D597D598D599D59AD59B
+D59CD59DD59ED59FD5A0D5A1D5A2D5A3D5A4D5A6D5A700000000000000000000
+0000D5A8D5A9D5AAD5ABD5ACD5ADD5AED5AFD5B0D5B1D5B2D5B3D5B4D5B5D5B6
+D5B7D5B8D5B9D5BAD5BBD5BCD5BDD5BED5BFD5C0D5C1D5C2D5C3D5C4D5C5D5C6
+D5C7C810C811C813C815C816C81CC81DC820C824C82CC82DC82FC831C838C83C
+C840C848C849C84CC84DC854C870C871C874C878C87AC880C881C883C885C886
+C887C88BC88CC88DC894C89DC89FC8A1C8A8C8BCC8BDC8C4C8C8C8CCC8D4C8D5
+C8D7C8D9C8E0C8E1C8E4C8F5C8FCC8FDC900C904C905C906C90CC90DC90FC911
+C918C92CC934C950C951C954C958C960C961C963C96CC970C974C97CC988C989
+C98CC990C998C999C99BC99DC9C0C9C1C9C4C9C7C9C8C9CAC9D0C9D1C9D30000
+C2
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000D5CAD5CBD5CDD5CED5CFD5D1D5D3D5D4D5D5D5D6D5D7D5DAD5DCD5DED5DF
+D5E0D5E1D5E2D5E3D5E6D5E7D5E9D5EAD5EBD5EDD5EE00000000000000000000
+0000D5EFD5F0D5F1D5F2D5F3D5F6D5F8D5FAD5FBD5FCD5FDD5FED5FFD602D603
+D605D606D607D609D60AD60BD60CD60DD60ED60FD61200000000000000000000
+0000D616D617D618D619D61AD61BD61DD61ED61FD621D622D623D625D626D627
+D628D629D62AD62BD62CD62ED62FD630D631D632D633D634D635D636D637D63A
+D63BC9D5C9D6C9D9C9DAC9DCC9DDC9E0C9E2C9E4C9E7C9ECC9EDC9EFC9F0C9F1
+C9F8C9F9C9FCCA00CA08CA09CA0BCA0CCA0DCA14CA18CA29CA4CCA4DCA50CA54
+CA5CCA5DCA5FCA60CA61CA68CA7DCA84CA98CABCCABDCAC0CAC4CACCCACDCACF
+CAD1CAD3CAD8CAD9CAE0CAECCAF4CB08CB10CB14CB18CB20CB21CB41CB48CB49
+CB4CCB50CB58CB59CB5DCB64CB78CB79CB9CCBB8CBD4CBE4CBE7CBE9CC0CCC0D
+CC10CC14CC1CCC1DCC21CC22CC27CC28CC29CC2CCC2ECC30CC38CC39CC3B0000
+C3
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000D63DD63ED63FD641D642D643D644D646D647D64AD64CD64ED64FD650D652
+D653D656D657D659D65AD65BD65DD65ED65FD660D66100000000000000000000
+0000D662D663D664D665D666D668D66AD66BD66CD66DD66ED66FD672D673D675
+D676D677D678D679D67AD67BD67CD67DD67ED67FD68000000000000000000000
+0000D681D682D684D686D687D688D689D68AD68BD68ED68FD691D692D693D695
+D696D697D698D699D69AD69BD69CD69ED6A0D6A2D6A3D6A4D6A5D6A6D6A7D6A9
+D6AACC3CCC3DCC3ECC44CC45CC48CC4CCC54CC55CC57CC58CC59CC60CC64CC66
+CC68CC70CC75CC98CC99CC9CCCA0CCA8CCA9CCABCCACCCADCCB4CCB5CCB8CCBC
+CCC4CCC5CCC7CCC9CCD0CCD4CCE4CCECCCF0CD01CD08CD09CD0CCD10CD18CD19
+CD1BCD1DCD24CD28CD2CCD39CD5CCD60CD64CD6CCD6DCD6FCD71CD78CD88CD94
+CD95CD98CD9CCDA4CDA5CDA7CDA9CDB0CDC4CDCCCDD0CDE8CDECCDF0CDF8CDF9
+CDFBCDFDCE04CE08CE0CCE14CE19CE20CE21CE24CE28CE30CE31CE33CE350000
+C4
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000D6ABD6ADD6AED6AFD6B1D6B2D6B3D6B4D6B5D6B6D6B7D6B8D6BAD6BCD6BD
+D6BED6BFD6C0D6C1D6C2D6C3D6C6D6C7D6C9D6CAD6CB00000000000000000000
+0000D6CDD6CED6CFD6D0D6D2D6D3D6D5D6D6D6D8D6DAD6DBD6DCD6DDD6DED6DF
+D6E1D6E2D6E3D6E5D6E6D6E7D6E9D6EAD6EBD6ECD6ED00000000000000000000
+0000D6EED6EFD6F1D6F2D6F3D6F4D6F6D6F7D6F8D6F9D6FAD6FBD6FED6FFD701
+D702D703D705D706D707D708D709D70AD70BD70CD70DD70ED70FD710D712D713
+D714CE58CE59CE5CCE5FCE60CE61CE68CE69CE6BCE6DCE74CE75CE78CE7CCE84
+CE85CE87CE89CE90CE91CE94CE98CEA0CEA1CEA3CEA4CEA5CEACCEADCEC1CEE4
+CEE5CEE8CEEBCEECCEF4CEF5CEF7CEF8CEF9CF00CF01CF04CF08CF10CF11CF13
+CF15CF1CCF20CF24CF2CCF2DCF2FCF30CF31CF38CF54CF55CF58CF5CCF64CF65
+CF67CF69CF70CF71CF74CF78CF80CF85CF8CCFA1CFA8CFB0CFC4CFE0CFE1CFE4
+CFE8CFF0CFF1CFF3CFF5CFFCD000D004D011D018D02DD034D035D038D03C0000
+C5
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000D715D716D717D71AD71BD71DD71ED71FD721D722D723D724D725D726D727
+D72AD72CD72ED72FD730D731D732D733D736D737D73900000000000000000000
+0000D73AD73BD73DD73ED73FD740D741D742D743D745D746D748D74AD74BD74C
+D74DD74ED74FD752D753D755D75AD75BD75CD75DD75E00000000000000000000
+0000D75FD762D764D766D767D768D76AD76BD76DD76ED76FD771D772D773D775
+D776D777D778D779D77AD77BD77ED77FD780D782D783D784D785D786D787D78A
+D78BD044D045D047D049D050D054D058D060D06CD06DD070D074D07CD07DD081
+D0A4D0A5D0A8D0ACD0B4D0B5D0B7D0B9D0C0D0C1D0C4D0C8D0C9D0D0D0D1D0D3
+D0D4D0D5D0DCD0DDD0E0D0E4D0ECD0EDD0EFD0F0D0F1D0F8D10DD130D131D134
+D138D13AD140D141D143D144D145D14CD14DD150D154D15CD15DD15FD161D168
+D16CD17CD184D188D1A0D1A1D1A4D1A8D1B0D1B1D1B3D1B5D1BAD1BCD1C0D1D8
+D1F4D1F8D207D209D210D22CD22DD230D234D23CD23DD23FD241D248D25C0000
+C6
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000D78DD78ED78FD791D792D793D794D795D796D797D79AD79CD79ED79FD7A0
+D7A1D7A2D7A30000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000D264D280D281D284D288D290D291D295D29CD2A0D2A4D2ACD2B1D2B8D2B9
+D2BCD2BFD2C0D2C2D2C8D2C9D2CBD2D4D2D8D2DCD2E4D2E5D2F0D2F1D2F4D2F8
+D300D301D303D305D30CD30DD30ED310D314D316D31CD31DD31FD320D321D325
+D328D329D32CD330D338D339D33BD33CD33DD344D345D37CD37DD380D384D38C
+D38DD38FD390D391D398D399D39CD3A0D3A8D3A9D3ABD3ADD3B4D3B8D3BCD3C4
+D3C5D3C8D3C9D3D0D3D8D3E1D3E3D3ECD3EDD3F0D3F4D3FCD3FDD3FFD4010000
+C7
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000D408D41DD440D444D45CD460D464D46DD46FD478D479D47CD47FD480D482
+D488D489D48BD48DD494D4A9D4CCD4D0D4D4D4DCD4DFD4E8D4ECD4F0D4F8D4FB
+D4FDD504D508D50CD514D515D517D53CD53DD540D544D54CD54DD54FD551D558
+D559D55CD560D565D568D569D56BD56DD574D575D578D57CD584D585D587D588
+D589D590D5A5D5C8D5C9D5CCD5D0D5D2D5D8D5D9D5DBD5DDD5E4D5E5D5E8D5EC
+D5F4D5F5D5F7D5F9D600D601D604D608D610D611D613D614D615D61CD6200000
+C8
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000D624D62DD638D639D63CD640D645D648D649D64BD64DD651D654D655D658
+D65CD667D669D670D671D674D683D685D68CD68DD690D694D69DD69FD6A1D6A8
+D6ACD6B0D6B9D6BBD6C4D6C5D6C8D6CCD6D1D6D4D6D7D6D9D6E0D6E4D6E8D6F0
+D6F5D6FCD6FDD700D704D711D718D719D71CD720D728D729D72BD72DD734D735
+D738D73CD744D747D749D750D751D754D756D757D758D759D760D761D763D765
+D769D76CD770D774D77CD77DD781D788D789D78CD790D798D799D79BD79D0000
+CA
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00004F3D4F73504750F952A053EF547554E556095AC15BB6668767B667B767EF
+6B4C73C275C27A3C82DB8304885788888A368CC88DCF8EFB8FE699D5523B5374
+5404606A61646BBC73CF811A89BA89D295A34F83520A58BE597859E65E725E79
+61C763C0674667EC687F6F97764E770B78F57A087AFF7C21809D826E82718AEB
+95934E6B559D66F76E3478A37AED845B8910874E97A852D8574E582A5D4C611F
+61BE6221656267D16A446E1B751875B376E377B07D3A90AF945194529F950000
+CB
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000053235CAC753280DB92409598525B580859DC5CA15D175EB75F3A5F4A6177
+6C5F757A75867CE07D737DB17F8C81548221859189418B1B92FC964D9C474ECB
+4EF7500B51F1584F6137613E6168653969EA6F1175A5768676D67B8782A584CB
+F90093A7958B55805BA25751F9017CB37FB991B5502853BB5C455DE862D2636E
+64DA64E76E2070AC795B8DDD8E1EF902907D924592F84E7E4EF650655DFE5EFA
+61066957817186548E4793759A2B4E5E5091677068405109528D52926AA20000
+CC
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000077BC92109ED452AB602F8FF2504861A963ED64CA683C6A846FC0818889A1
+96945805727D72AC75047D797E6D80A9898B8B7490639D5162896C7A6F547D50
+7F3A8A23517C614A7B9D8B199257938C4EAC4FD3501E50BE510652C152CD537F
+577058835E9A5F91617661AC64CE656C666F66BB66F468976D87708570F1749F
+74A574CA75D9786C78EC7ADF7AF67D457D938015803F811B83968B668F159015
+93E1980398389A5A9BE84FC25553583A59515B635C4660B86212684268B00000
+CD
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000068E86EAA754C767878CE7A3D7CFB7E6B7E7C8A088AA18C3F968E9DC453E4
+53E9544A547156FA59D15B645C3B5EAB62F765376545657266A067AF69C16CBD
+75FC7690777E7A3F7F94800380A1818F82E682FD83F085C1883188B48AA5F903
+8F9C932E96C798679AD89F1354ED659B66F2688F7A408C379D6056F057645D11
+660668B168CD6EFE7428889E9BE46C68F9049AA84F9B516C5171529F5B545DE5
+6050606D62F163A7653B73D97A7A86A38CA2978F4E325BE16208679C74DC0000
+CE
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000079D183D38A878AB28DE8904E934B98465ED369E885FF90EDF90551A05B98
+5BEC616368FA6B3E704C742F74D87BA17F5083C589C08CAB95DC9928522E605D
+62EC90024F8A5149532158D95EE366E06D38709A72C273D67B5080F1945B5366
+639B7F6B4E565080584A58DE602A612762D069D09B415B8F7D1880B18F5F4EA4
+50D154AC55AC5B0C5DA05DE7652A654E68216A4B72E1768E77EF7D5E7FF981A0
+854E86DF8F038F4E90CA99039A559BAB4E184E454E5D4EC74FF1517752FE0000
+CF
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000534053E353E5548E5614577557A25BC75D875ED061FC62D8655167B867E9
+69CB6B506BC66BEC6C426E9D707872D77396740377BF77E97A767D7F800981FC
+8205820A82DF88628B338CFC8EC0901190B1926492B699D29A459CE99DD79F9C
+570B5C4083CA97A097AB9EB4541B7A987FA488D98ECD90E158005C4863987A9F
+5BAE5F137A797AAE828E8EAC5026523852F85377570862F363726B0A6DC37737
+53A5735785688E7695D5673A6AC36F708A6D8ECC994BF90666776B788CB40000
+D0
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00009B3CF90753EB572D594E63C669FB73EA78457ABA7AC57CFE8475898F8D73
+903595A852FB574775477B6083CC921EF9086A58514B524B5287621F68D86975
+969950C552A452E461C365A4683969FF747E7B4B82B983EB89B28B398FD19949
+F9094ECA599764D266116A8E7434798179BD82A9887E887F895FF90A93264F0B
+53CA602562716C727D1A7D664E98516277DC80AF4F014F0E5176518055DC5668
+573B57FA57FC5914594759935BC45C905D0E5DF15E7E5FCC628065D765E30000
+D1
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000671E671F675E68CB68C46A5F6B3A6C236C7D6C826DC773987426742A7482
+74A37578757F788178EF794179477948797A7B957D007DBA7F888006802D808C
+8A188B4F8C488D779321932498E299519A0E9A0F9A659E927DCA4F76540962EE
+685491D155AB513AF90BF90C5A1C61E6F90D62CF62FFF90EF90FF910F911F912
+F91390A3F914F915F916F917F9188AFEF919F91AF91BF91C6696F91D7156F91E
+F91F96E3F920634F637A5357F921678F69606E73F9227537F923F924F9250000
+D2
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00007D0DF926F927887256CA5A18F928F929F92AF92BF92C4E43F92D51675948
+67F08010F92E59735E74649A79CA5FF5606C62C8637B5BE75BD752AAF92F5974
+5F296012F930F931F9327459F933F934F935F936F937F93899D1F939F93AF93B
+F93CF93DF93EF93FF940F941F942F9436FC3F944F94581BF8FB260F1F946F947
+8166F948F9495C3FF94AF94BF94CF94DF94EF94FF950F9515AE98A25677B7D10
+F952F953F954F955F956F95780FDF958F9595C3C6CE5533F6EBA591A83360000
+D3
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00004E394EB64F4655AE571858C75F5665B765E66A806BB56E4D77ED7AEF7C1E
+7DDE86CB88929132935B64BB6FBE737A75B890545556574D61BA64D466C76DE1
+6E5B6F6D6FB975F0804381BD854189838AC78B5A931F6C9375537B548E0F905D
+5510580258585E626207649E68E075767CD687B39EE84EE35788576E59275C0D
+5CB15E365F85623464E173B381FA888B8CB8968A9EDB5B855FB760B350125200
+52305716583558575C0E5C605CF65D8B5EA65F9260BC63116389641768430000
+D4
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000068F96AC26DD86E216ED46FE471FE76DC777979B17A3B840489A98CED8DF3
+8E4890039014905390FD934D967697DC6BD27006725872A27368776379BF7BE4
+7E9B8B8058A960C7656665FD66BE6C8C711E71C98C5A98134E6D7A814EDD51AC
+51CD52D5540C61A76771685068DF6D1E6F7C75BC77B37AE580F484639285515C
+6597675C679375D87AC78373F95A8C469017982D5C6F81C0829A9041906F920D
+5F975D9D6A5971C8767B7B4985E48B0491279A30558761F6F95B76697F850000
+D5
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000863F87BA88F8908FF95C6D1B70D973DE7D61843DF95D916A99F1F95E4E82
+53756B046B12703E721B862D9E1E524C8FA35D5064E5652C6B166FEB7C437E9C
+85CD896489BD62C981D8881F5ECA67176D6A72FC7405746F878290DE4F865D0D
+5FA0840A51B763A075654EAE5006516951C968816A117CAE7CB17CE7826F8AD2
+8F1B91CF4FB6513752F554425EEC616E623E65C56ADA6FFE792A85DC882395AD
+9A629A6A9E979ECE529B66C66B77701D792B8F6297426190620065236F230000
+D6
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000714974897DF4806F84EE8F269023934A51BD521752A36D0C70C888C25EC9
+65826BAE6FC27C3E73754EE44F3656F9F95F5CBA5DBA601C73B27B2D7F9A7FCE
+8046901E923496F6974898189F614F8B6FA779AE91B496B752DEF960648864C4
+6AD36F5E7018721076E780018606865C8DEF8F0597329B6F9DFA9E75788C797F
+7DA083C993049E7F9E938AD658DF5F046727702774CF7C60807E512170287262
+78CA8CC28CDA8CF496F74E8650DA5BEE5ED6659971CE764277AD804A84FC0000
+D7
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000907C9B279F8D58D85A415C626A136DDA6F0F763B7D2F7E37851E893893E4
+964B528965D267F369B46D416E9C700F7409746075597624786B8B2C985E516D
+622E96784F96502B5D196DEA7DB88F2A5F8B61446817F961968652D2808B51DC
+51CC695E7A1C7DBE83F196754FDA52295398540F550E5C6560A7674E68A86D6C
+728172F874067483F96275E27C6C7F797FB8838988CF88E191CC91D096E29BC9
+541D6F7E71D0749885FA8EAA96A39C579E9F67976DCB743381E89716782C0000
+D8
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00007ACB7B207C926469746A75F278BC78E899AC9B549EBB5BDE5E556F20819C
+83AB90884E07534D5A295DD25F4E6162633D666966FC6EFF6F2B7063779E842C
+8513883B8F1399459C3B551C62B9672B6CAB8309896A977A4EA159845FD85FD9
+671B7DB27F548292832B83BD8F1E909957CB59B95A925BD06627679A68856BCF
+71647F758CB78CE390819B4581088C8A964C9A409EA55B5F6C13731B76F276DF
+840C51AA8993514D519552C968C96C94770477207DBF7DEC97629EB56EC50000
+D9
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000851151A5540D547D660E669D69276E9F76BF7791831784C2879F91699298
+9CF488824FAE519252DF59C65E3D61556478647966AE67D06A216BCD6BDB725F
+72617441773877DB801782BC83058B008B288C8C67286C90726776EE77667A46
+9DA96B7F6C92592267268499536F589359995EDF63CF663467736E3A732B7AD7
+82D7932852D95DEB61AE61CB620A62C764AB65E069596B666BCB712173F7755D
+7E46821E8302856A8AA38CBF97279D6158A89ED85011520E543B554F65870000
+DA
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00006C767D0A7D0B805E868A958096EF52FF6C95726954735A9A5C3E5D4B5F4C
+5FAE672A68B669636E3C6E4477097C737F8E85878B0E8FF797619EF45CB760B6
+610D61AB654F65FB65FC6C116CEF739F73C97DE195945BC6871C8B10525D535A
+62CD640F64B267346A386CCA73C0749E7B947C957E1B818A823685848FEB96F9
+99C14F34534A53CD53DB62CC642C6500659169C36CEE6F5873ED7554762276E4
+76FC78D078FB792C7D46822C87E08FD4981298EF52C362D464A56E246F510000
+DB
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000767C8DCB91B192629AEE9B435023508D574A59A85C285E475F77623F653E
+65B965C16609678B699C6EC278C57D2180AA8180822B82B384A1868C8A2A8B17
+90A696329F90500D4FF3F96357F95F9862DC6392676F6E43711976C380CC80DA
+88F488F589198CE08F29914D966A4F2F4F705E1B67CF6822767D767E9B445E61
+6A0A716971D4756AF9647E41854385E998DC4F107B4F7F7095A551E15E0668B5
+6C3E6C4E6CDB72AF7BC483036CD5743A50FB528858C164D86A9774A776560000
+DC
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000078A7861795E29739F965535E5F018B8A8FA88FAF908A522577A59C499F08
+4E19500251755C5B5E77661E663A67C468C570B3750175C579C97ADD8F279920
+9A084FDD582158315BF6666E6B656D116E7A6F7D73E4752B83E988DC89138B5C
+8F144F0F50D55310535C5B935FA9670D798F8179832F8514890789868F398F3B
+99A59C12672C4E764FF859495C015CEF5CF0636768D270FD71A2742B7E2B84EC
+8702902292D29CF34E0D4ED84FEF50855256526F5426549057E0592B5A660000
+DD
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00005B5A5B755BCC5E9CF9666276657765A76D6E6EA572367B267C3F7F368150
+8151819A8240829983A98A038CA08CE68CFB8D748DBA90E891DC961C964499D9
+9CE7531752065429567458B35954596E5FFF61A4626E66106C7E711A76C67C89
+7CDE7D1B82AC8CC196F0F9674F5B5F175F7F62C25D29670B68DA787C7E439D6C
+4E1550995315532A535159835A625E8760B2618A624962796590678769A76BD4
+6BD66BD76BD86CB8F968743575FA7812789179D579D87C837DCB7FE180A50000
+DE
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000813E81C283F2871A88E88AB98B6C8CBB9119975E98DB9F3B56AC5B2A5F6C
+658C6AB36BAF6D5C6FF17015725D73AD8CA78CD3983B61916C3780589A014E4D
+4E8B4E9B4ED54F3A4F3C4F7F4FDF50FF53F253F8550655E356DB58EB59625A11
+5BEB5BFA5C045DF35E2B5F99601D6368659C65AF67F667FB68AD6B7B6C996CD7
+6E23700973457802793E7940796079C17BE97D177D728086820D838E84D186C7
+88DF8A508A5E8B1D8CDC8D668FAD90AA98FC99DF9E9D524AF9696714F96A0000
+DF
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00005098522A5C7165636C5573CA7523759D7B97849C917897304E7764926BBA
+715E85A94E09F96B674968EE6E17829F8518886B63F76F81921298AF4E0A50B7
+50CF511F554655AA56175B405C195CE05E385E8A5EA05EC260F368516A616E58
+723D724072C076F879657BB17FD488F389F48A738C618CDE971C585E74BD8CFD
+55C7F96C7A617D2282727272751F7525F96D7B19588558FB5DBC5E8F5EB65F90
+60556292637F654D669166D966F8681668F27280745E7B6E7D6E7DD67F720000
+E0
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000080E5821285AF897F8A93901D92E49ECD9F205915596D5E2D60DC66146673
+67906C506DC56F5F77F378A984C691CB932B4ED950CA514855845B0B5BA36247
+657E65CB6E32717D74017444748774BF766C79AA7DDA7E557FA8817A81B38239
+861A87EC8A758DE3907892919425994D9BAE53685C5169546CC46D296E2B820C
+859B893B8A2D8AAA96EA9F67526166B96BB27E9687FE8D0D9583965D651D6D89
+71EEF96E57CE59D35BAC602760FA6210661F665F732973F976DB77017B6C0000
+E1
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00008056807281658AA091924E1652E26B726D177A057B397D30F96F8CB053EC
+562F58515BB55C0F5C115DE2624063836414662D68B36CBC6D886EAF701F70A4
+71D27526758F758E76197B117BE07C2B7D207D39852C856D86078A34900D9061
+90B592B797F69A374FD75C6C675F6D917C9F7E8C8B168D16901F5B6B5DFD640D
+84C0905C98E173875B8B609A677E6DDE8A1F8AA69001980C5237F9707051788E
+9396887091D74FEE53D755FD56DA578258FD5AC25B885CAB5CC05E2561010000
+E2
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000620D624B6388641C653665786A396B8A6C346D196F3171E772E973787407
+74B27626776179C07A577AEA7CB97D8F7DAC7E617F9E81298331849084DA85EA
+88968AB08B908F3890429083916C929692B9968B96A796A896D6970098089996
+9AD39B1A53D4587E59195B705BBF6DD16F5A719F742174B9808583FD5DE15F87
+5FAA604265EC6812696F6A536B896D356DF373E376FE77AC7B4D7D148123821C
+834084F485638A628AC49187931E980699B4620C88538FF092655D075D270000
+E3
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00005D69745F819D87686FD562FE7FD2893689724E1E4E5850E752DD5347627F
+66077E698805965E4F8D5319563659CB5AA45C385C4E5C4D5E025F11604365BD
+662F664267BE67F4731C77E2793A7FC5849484CD89968A668A698AE18C558C7A
+57F45BD45F0F606F62ED690D6B966E5C71847BD287558B588EFE98DF98FE4F38
+4F814FE1547B5A205BB8613C65B0666871FC7533795E7D33814E81E3839885AA
+85CE87038A0A8EAB8F9BF9718FC559315BA45BE660895BE95C0B5FC36C810000
+E4
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000F9726DF1700B751A82AF8AF64EC05341F97396D96C0F4E9E4FC45152555E
+5A255CE86211725982BD83AA86FE88598A1D963F96C599139D099D5D580A5CB3
+5DBD5E4460E1611563E16A026E2591029354984E9C109F775B895CB86309664F
+6848773C96C1978D98549B9F65A18B018ECB95BC55355CA95DD65EB56697764C
+83F495C758D362BC72CE9D284EF0592E600F663B6B8379E79D26539354C057C3
+5D16611B66D66DAF788D827E969897445384627C63966DB27E0A814B984D0000
+E5
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00006AFB7F4C9DAF9E1A4E5F503B51B6591C60F963F66930723A8036F97491CE
+5F31F975F9767D0482E5846F84BB85E58E8DF9774F6FF978F97958E45B436059
+63DA6518656D6698F97A694A6A236D0B7001716C75D2760D79B37A70F97B7F8A
+F97C8944F97D8B9391C0967DF97E990A57045FA165BC6F01760079A68A9E99AD
+9B5A9F6C510461B662916A8D81C6504358305F6671098A008AFA5B7C86164FFA
+513C56B4594463A96DF95DAA696D51864E884F59F97FF980F9815982F9820000
+E6
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000F9836B5F6C5DF98474B57916F9858207824583398F3F8F5DF9869918F987
+F988F9894EA6F98A57DF5F796613F98BF98C75AB7E798B6FF98D90069A5B56A5
+582759F85A1F5BB4F98E5EF6F98FF9906350633BF991693D6C876CBF6D8E6D93
+6DF56F14F99270DF71367159F99371C371D5F994784F786FF9957B757DE3F996
+7E2FF997884D8EDFF998F999F99A925BF99B9CF6F99CF99DF99E60856D85F99F
+71B1F9A0F9A195B153ADF9A2F9A3F9A467D3F9A5708E71307430827682D20000
+E7
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000F9A695BB9AE59E7D66C4F9A771C18449F9A8F9A9584BF9AAF9AB5DB85F71
+F9AC6620668E697969AE6C386CF36E366F416FDA701B702F715071DF7370F9AD
+745BF9AE74D476C87A4E7E93F9AFF9B082F18A608FCEF9B19348F9B29719F9B3
+F9B44E42502AF9B5520853E166F36C6D6FCA730A777F7A6282AE85DD8602F9B6
+88D48A638B7D8C6BF9B792B3F9B8971398104E944F0D4FC950B25348543E5433
+55DA586258BA59675A1B5BE4609FF9B961CA655665FF666468A76C5A6FB30000
+E8
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000070CF71AC73527B7D87088AA49C329F075C4B6C8373447389923A6EAB7465
+761F7A697E15860A514058C564C174EE751576707FC1909596CD99546E2674E6
+7AA97AAA81E586D987788A1B5A495B8C5B9B68A169006D6373A97413742C7897
+7DE97FEB81188155839E8C4C962E981166F05F8065FA67896C6A738B502D5A03
+6B6A77EE59165D6C5DCD7325754FF9BAF9BB50E551F9582F592D599659DA5BE5
+F9BCF9BD5DA262D76416649364FEF9BE66DCF9BF6A48F9C071FF7464F9C10000
+E9
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00007A887AAF7E477E5E80008170F9C287EF89818B209059F9C390809952617E
+6B326D747E1F89258FB14FD150AD519752C757C758895BB95EB8614269956D8C
+6E676EB6719474627528752C8073833884C98E0A939493DEF9C44E8E4F515076
+512A53C853CB53F35B875BD35C24611A618265F4725B7397744076C279507991
+79B97D067FBD828B85D5865E8FC2904790F591EA968596E896E952D65F6765ED
+6631682F715C7A3690C1980A4E91F9C56A526B9E6F907189801882B885530000
+EA
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000904B969596F297FB851A9B314E90718A96C45143539F54E15713571257A3
+5A9B5AC45BC36028613F63F46C856D396E726E907230733F745782D188818F45
+9060F9C6966298589D1B67088D8A925E4F4D504950DE5371570D59D45A015C09
+617066906E2D7232744B7DEF80C3840E8466853F875F885B89188B02905597CB
+9B4F4E734F915112516AF9C7552F55A95B7A5BA55E7C5E7D5EBE60A060DF6108
+610963C465386709F9C867D467DAF9C9696169626CB96D27F9CA6E38F9CB0000
+EB
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00006FE173367337F9CC745C7531F9CD7652F9CEF9CF7DAD81FE843888D58A98
+8ADB8AED8E308E42904A903E907A914991C9936EF9D0F9D15809F9D26BD38089
+80B2F9D3F9D45141596B5C39F9D5F9D66F6473A780E48D07F9D79217958FF9D8
+F9D9F9DAF9DB807F620E701C7D68878DF9DC57A0606961476BB78ABE928096B1
+4E59541F6DEB852D967097F398EE63D66CE3909151DD61C981BA9DF94F9D501A
+51005B9C610F61FF64EC69056BC5759177E37FA98264858F87FB88638ABC0000
+EC
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00008B7091AB4E8C4EE54F0AF9DDF9DE593759E8F9DF5DF25F1B5F5B6021F9E0
+F9E1F9E2F9E3723E73E5F9E4757075CDF9E579FBF9E6800C8033808482E18351
+F9E7F9E88CBD8CB39087F9E9F9EA98F4990CF9EBF9EC703776CA7FCA7FCC7FFC
+8B1A4EBA4EC152035370F9ED54BD56E059FB5BC55F155FCD6E6EF9EEF9EF7D6A
+8335F9F086938A8DF9F1976D9777F9F2F9F34E004F5A4F7E58F965E56EA29038
+93B099B94EFB58EC598A59D96041F9F4F9F57A14F9F6834F8CC3516553440000
+ED
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000F9F7F9F8F9F94ECD52695B5582BF4ED4523A54A859C959FF5B505B575B5C
+606361486ECB7099716E738674F775B578C17D2B800581EA8328851785C98AEE
+8CC796CC4F5C52FA56BC65AB6628707C70B872357DBD828D914C96C09D725B71
+68E76B986F7A76DE5C9166AB6F5B7BB47C2A883696DC4E084ED75320583458BB
+58EF596C5C075E335E845F35638C66B267566A1F6AA36B0C6F3F7246F9FA7350
+748B7AE07CA7817881DF81E7838A846C8523859485CF88DD8D1391AC95770000
+EE
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000969C518D54C957285BB0624D6750683D68936E3D6ED3707D7E2188C18CA1
+8F099F4B9F4E722D7B8F8ACD931A4F474F4E5132548059D05E9562B56775696E
+6A176CAE6E1A72D9732A75BD7BB87D3582E783F9845785F78A5B8CAF8E879019
+90B896CE9F5F52E3540A5AE15BC2645865756EF472C4F9FB76847A4D7B1B7C4D
+7E3E7FDF837B8B2B8CCA8D648DE18E5F8FEA8FF9906993D14F434F7A50B35168
+5178524D526A5861587C59605C085C555EDB609B623068136BBF6C086FB10000
+EF
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000714E742075307538755176727B4C7B8B7BAD7BC67E8F8A6E8F3E8F49923F
+92939322942B96FB985A986B991E5207622A62986D5976647ACA7BC07D765360
+5CBE5E976F3870B97C9897119B8E9EDE63A5647A87764E014E954EAD505C5075
+544859C35B9A5E405EAD5EF75F8160C5633A653F657465CC6676667867FE6968
+6A896B636C406DC06DE86E1F6E5E701E70A1738E73FD753A775B7887798E7A0B
+7A7D7CBE7D8E82478A028AEA8C9E912D914A91D8926692CC9320970697560000
+F0
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000975C98029F0E52365291557C58245E1D5F1F608C63D068AF6FDF796D7B2C
+81CD85BA88FD8AF88E44918D9664969B973D984C9F4A4FCE514651CB52A95632
+5F145F6B63AA64CD65E9664166FA66F9671D689D68D769FD6F156F6E716771E5
+722A74AA773A7956795A79DF7A207A957C977CDF7D447E70808785FB86A48A54
+8ABF8D998E819020906D91E3963B96D59CE565CF7C078DB393C35B585C0A5352
+62D9731D50275B975F9E60B0616B68D56DD9742E7A2E7D427D9C7E31816B0000
+F1
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00008E2A8E35937E94184F5057505DE65EA7632B7F6A4E3B4F4F4F8F505A59DD
+80C4546A546855FE594F5B995DDE5EDA665D673167F1682A6CE86D326E4A6F8D
+70B773E075877C4C7D027D2C7DA2821F86DB8A3B8A858D708E8A8F339031914E
+9152944499D07AF97CA54FCA510151C657C85BEF5CFB66596A3D6D5A6E966FEC
+710C756F7AE388229021907596CB99FF83014E2D4EF2884691CD537D6ADB696B
+6C41847A589E618E66FE62EF70DD751175C77E5284B88B498D084E4B53EA0000
+F2
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000054AB573057405FD763016307646F652F65E8667A679D67B36B626C606C9A
+6F2C77E57825794979577D1980A2810281F3829D82B787188A8CF9FC8D048DBE
+907276F47A197A377E548077550755D45875632F64226649664B686D699B6B84
+6D256EB173CD746874A1755B75B976E1771E778B79E67E097E1D81FB852F8897
+8A3A8CD18EEB8FB0903293AD9663967397074F8453F159EA5AC95E19684E74C6
+75BE79E97A9281A386ED8CEA8DCC8FED659F6715F9FD57F76F577DDD8F2F0000
+F3
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000093F696C65FB561F26F844E144F98501F53C955DF5D6F5DEE6B216B6478CB
+7B9AF9FE8E498ECA906E6349643E77407A84932F947F9F6A64B06FAF71E674A8
+74DA7AC47C127E827CB27E988B9A8D0A947D9910994C52395BDF64E6672D7D2E
+50ED53C358796158615961FA65AC7AD98B928B9650095021527555315A3C5EE0
+5F706134655E660C663666A269CD6EC46F32731676217A938139825983D684BC
+50B557F05BC05BE85F6963A178267DB583DC852191C791F5518A67F57B560000
+F4
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00008CAC51C459BB60BD8655501CF9FF52545C3A617D621A62D364F265A56ECC
+7620810A8E60965F96BB4EDF5343559859295DDD64C56CC96DFA73947A7F821B
+85A68CE48E10907791E795E1962197C651F854F255865FB964A46F887DB48F1F
+8F4D943550C95C166CBE6DFB751B77BB7C3D7C648A798AC2581E59BE5E166377
+7252758A776B8ADC8CBC8F125EF366746DF8807D83C18ACB97519BD6FA005243
+66FF6D956EEF7DE08AE6902E905E9AD4521D527F54E86194628462DB68A20000
+F5
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00006912695A6A3570927126785D7901790E79D27A0D8096827882D583498549
+8C828D859162918B91AE4FC356D171ED77D7870089F85BF85FD6675190A853E2
+585A5BF560A4618164607E3D80708525928364AE50AC5D146700589C62BD63A8
+690E69786A1E6E6B76BA79CB82BB84298ACF8DA88FFD9112914B919C93109318
+939A96DB9A369C0D4E11755C795D7AFA7B517BC97E2E84C48E598E748EF89010
+6625693F744351FA672E9EDC51455FE06C9687F2885D887760B481B584030000
+F6
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00008D0553D6543956345A365C31708A7FE0805A810681ED8DA391899A5F9DF2
+50744EC453A060FB6E2C5C644F88502455E45CD95E5F606568946CBB6DC471BE
+75D475F476617A1A7A497DC77DFB7F6E81F486A98F1C96C999B39F52524752C5
+98ED89AA4E0367D26F064FB55BE267956C886D78741B782791DD937C87C479E4
+7A315FEB4ED654A4553E58AE59A560F0625362D6673669558235964099B199DD
+502C53535544577CFA016258FA0264E2666B67DD6FC16FEF742274388A170000
+F7
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000094385451560657665F48619A6B4E705870AD7DBB8A95596A812B63A27708
+803D8CAA5854642D69BB5B955E116E6FFA038569514C53F0592A6020614B6B86
+6C706CF07B1E80CE82D48DC690B098B1FA0464C76FA464916504514E5410571F
+8A0E615F6876FA0575DB7B527D71901A580669CC817F892A9000983950785957
+59AC6295900F9B2A615D727995D657615A465DF4628A64AD64FA67776CE26D3E
+722C743678347F7782AD8DDB981752245742677F724874E38CA98FA692110000
+F8
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000962A516B53ED634C4F695504609665576C9B6D7F724C72FD7A1789878C9D
+5F6D6F8E70F981A8610E4FBF504F624172477BC77DE87FE9904D97AD9A198CB6
+576A5E7367B0840D8A5554205B165E635EE25F0A658380BA853D9589965B4F48
+5305530D530F548654FA57035E036016629B62B16355FA066CE16D6675B17832
+80DE812F82DE846184B2888D8912900B92EA98FD9B915E4566B466DD70117206
+FA074FF5527D5F6A615367536A196F0274E2796888688C7998C798C49A430000
+F9
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000054C17A1F69538AF78C4A98A899AE5F7C62AB75B276AE88AB907F96425339
+5F3C5FC56CCC73CC7562758B7B4682FE999D4E4F903C4E0B4F5553A6590F5EC8
+66306CB37455837787668CC09050971E9C1558D15B7886508B149DB45BD26068
+608D65F16C576F226FA3701A7F557FF095919592965097D352728F4451FD542B
+54B85563558A6ABB6DB57DD88266929C96779E79540854C876D286E495A495D4
+965C4EA24F0959EE5AE65DF760526297676D68416C866E2F7F38809B822A0000
+FA
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000FA08FA0998054EA5505554B35793595A5B695BB361C869776D77702387F9
+89E38A728AE7908299ED9AB852BE683850165E78674F8347884C4EAB541156AE
+73E6911597FF9909995799995653589F865B8A3161B26AF6737B8ED26B4796AA
+9A57595572008D6B97694FD45CF45F2661F8665B6CEB70AB738473B973FE7729
+774D7D437D627E2382378852FA0A8CE29249986F5B517A74884098015ACC4FE0
+5354593E5CFD633E6D7972F98105810783A292CF98304EA851445211578B0000
+FB
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00005F626CC26ECE7005705070AF719273E97469834A87A28861900890A293A3
+99A8516E5F5760E0616766B385598E4A91AF978B4E4E4E92547C58D558FA597D
+5CB55F2762366248660A66676BEB6D696DCF6E566EF86F946FE06FE9705D72D0
+7425745A74E07693795C7CCA7E1E80E182A6846B84BF864E865F87748B778C6A
+93AC9800986560D1621691775A5A660F6DF76E3E743F9B425FFD60DA7B0F54C4
+5F186C5E6CD36D2A70D87D0586798A0C9D3B5316548C5B056A3A706B75750000
+FC
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000798D79BE82B183EF8A718B418CA89774FA0B64F4652B78BA78BB7A6B4E38
+559A59505BA65E7B60A363DB6B61666568536E19716574B07D0890849A699C25
+6D3B6ED1733E8C4195CA51F05E4C5FA8604D60F66130614C6643664469A56CC1
+6E5F6EC96F62714C749C76877BC17C27835287579051968D9EC3532F56DE5EFB
+5F8A6062609461F7666667036A9C6DEE6FAE7070736A7E6A81BE833486D48AA8
+8CC4528373725B966A6B940454EE56865B5D6548658566C9689F6D8D6DC60000
+FD
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000723B80B491759A4D4FAF5019539A540E543C558955C55E3F5F8C673D7166
+73DD900552DB52F3586458CE7104718F71FB85B08A13668885A855A76684714A
+8431534955996BC15F595FBD63EE668971478AF18F1D9EBE4F11643A70CB7566
+866760648B4E9DF8514751F653086D3680F89ED166156B23709875D554035C79
+7D078A166B206B3D6B46543860706D3D7FD5820850D651DE559C566B56CD59EC
+5B095E0C619961986231665E66E6719971B971BA72A779A77A007FB28A700000
diff --git a/library/encoding/cp950.enc b/library/encoding/cp950.enc
new file mode 100644
index 0000000..f33d785
--- /dev/null
+++ b/library/encoding/cp950.enc
@@ -0,0 +1,1499 @@
+# Encoding file: cp950, multi-byte
+M
+003F 0 88
+00
+0000000100020003000400050006000700080009000A000B000C000D000E000F
+0010001100120013001400150016001700180019001A001B001C001D001E001F
+0020002100220023002400250026002700280029002A002B002C002D002E002F
+0030003100320033003400350036003700380039003A003B003C003D003E003F
+0040004100420043004400450046004700480049004A004B004C004D004E004F
+0050005100520053005400550056005700580059005A005B005C005D005E005F
+0060006100620063006400650066006700680069006A006B006C006D006E006F
+0070007100720073007400750076007700780079007A007B007C007D007E007F
+0080008100820083008400850086008700880089008A008B008C008D008E008F
+0090009100920093009400950096009700980099009A009B009C009D009E009F
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+A1
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+3000FF0C30013002FF0E2027FF1BFF1AFF1FFF01FE3020262025FE50FE51FE52
+00B7FE54FE55FE56FE57FF5C2013FE312014FE332574FE34FE4FFF08FF09FE35
+FE36FF5BFF5DFE37FE3830143015FE39FE3A30103011FE3BFE3C300A300BFE3D
+FE3E30083009FE3FFE40300C300DFE41FE42300E300FFE43FE44FE59FE5A0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000FE5BFE5CFE5DFE5E20182019201C201D301D301E20352032FF03FF06FF0A
+203B00A7300325CB25CF25B325B225CE2606260525C725C625A125A025BD25BC
+32A3210500AFFFE3FF3F02CDFE49FE4AFE4DFE4EFE4BFE4CFE5FFE60FE61FF0B
+FF0D00D700F700B1221AFF1CFF1EFF1D226622672260221E22522261FE62FE63
+FE64FE65FE66FF5E2229222A22A52220221F22BF33D233D1222B222E22352234
+26402642229522992191219321902192219621972199219822252223FF0F0000
+A2
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+FF3C2215FE68FF04FFE53012FFE0FFE1FF05FF2021032109FE69FE6AFE6B33D5
+339C339D339E33CE33A1338E338F33C400B05159515B515E515D5161516355E7
+74E97CCE25812582258325842585258625872588258F258E258D258C258B258A
+2589253C2534252C2524251C2594250025022595250C251025142518256D0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000256E2570256F2550255E256A256125E225E325E525E4257125722573FF10
+FF11FF12FF13FF14FF15FF16FF17FF18FF192160216121622163216421652166
+216721682169302130223023302430253026302730283029534153445345FF21
+FF22FF23FF24FF25FF26FF27FF28FF29FF2AFF2BFF2CFF2DFF2EFF2FFF30FF31
+FF32FF33FF34FF35FF36FF37FF38FF39FF3AFF41FF42FF43FF44FF45FF46FF47
+FF48FF49FF4AFF4BFF4CFF4DFF4EFF4FFF50FF51FF52FF53FF54FF55FF560000
+A3
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+FF57FF58FF59FF5A039103920393039403950396039703980399039A039B039C
+039D039E039F03A003A103A303A403A503A603A703A803A903B103B203B303B4
+03B503B603B703B803B903BA03BB03BC03BD03BE03BF03C003C103C303C403C5
+03C603C703C803C931053106310731083109310A310B310C310D310E310F0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00003110311131123113311431153116311731183119311A311B311C311D311E
+311F312031213122312331243125312631273128312902D902C902CA02C702CB
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000020AC00000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+A4
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+4E004E594E014E034E434E5D4E864E8C4EBA513F5165516B51E052005201529B
+53155341535C53C84E094E0B4E084E0A4E2B4E3851E14E454E484E5F4E5E4E8E
+4EA15140520352FA534353C953E3571F58EB5915592759735B505B515B535BF8
+5C0F5C225C385C715DDD5DE55DF15DF25DF35DFE5E725EFE5F0B5F13624D0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00004E114E104E0D4E2D4E304E394E4B5C394E884E914E954E924E944EA24EC1
+4EC04EC34EC64EC74ECD4ECA4ECB4EC4514351415167516D516E516C519751F6
+52065207520852FB52FE52FF53165339534853475345535E538453CB53CA53CD
+58EC5929592B592A592D5B545C115C245C3A5C6F5DF45E7B5EFF5F145F155FC3
+62086236624B624E652F6587659765A465B965E566F0670867286B206B626B79
+6BCB6BD46BDB6C0F6C34706B722A7236723B72477259725B72AC738B4E190000
+A5
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+4E164E154E144E184E3B4E4D4E4F4E4E4EE54ED84ED44ED54ED64ED74EE34EE4
+4ED94EDE514551445189518A51AC51F951FA51F8520A52A0529F530553065317
+531D4EDF534A534953615360536F536E53BB53EF53E453F353EC53EE53E953E8
+53FC53F853F553EB53E653EA53F253F153F053E553ED53FB56DB56DA59160000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000592E5931597459765B555B835C3C5DE85DE75DE65E025E035E735E7C5F01
+5F185F175FC5620A625362546252625165A565E6672E672C672A672B672D6B63
+6BCD6C116C106C386C416C406C3E72AF7384738974DC74E67518751F75287529
+7530753175327533758B767D76AE76BF76EE77DB77E277F3793A79BE7A747ACB
+4E1E4E1F4E524E534E694E994EA44EA64EA54EFF4F094F194F0A4F154F0D4F10
+4F114F0F4EF24EF64EFB4EF04EF34EFD4F014F0B514951475146514851680000
+A6
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+5171518D51B0521752115212520E521652A3530853215320537053715409540F
+540C540A54105401540B54045411540D54085403540E5406541256E056DE56DD
+573357305728572D572C572F57295919591A59375938598459785983597D5979
+598259815B575B585B875B885B855B895BFA5C165C795DDE5E065E765E740000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00005F0F5F1B5FD95FD6620E620C620D62106263625B6258653665E965E865EC
+65ED66F266F36709673D6734673167356B216B646B7B6C166C5D6C576C596C5F
+6C606C506C556C616C5B6C4D6C4E7070725F725D767E7AF97C737CF87F367F8A
+7FBD80018003800C80128033807F8089808B808C81E381EA81F381FC820C821B
+821F826E8272827E866B8840884C8863897F96214E324EA84F4D4F4F4F474F57
+4F5E4F344F5B4F554F304F504F514F3D4F3A4F384F434F544F3C4F464F630000
+A7
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+4F5C4F604F2F4F4E4F364F594F5D4F484F5A514C514B514D517551B651B75225
+52245229522A522852AB52A952AA52AC532353735375541D542D541E543E5426
+544E542754465443543354485442541B5429544A5439543B5438542E54355436
+5420543C54405431542B541F542C56EA56F056E456EB574A57515740574D0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00005747574E573E5750574F573B58EF593E599D599259A8599E59A359995996
+598D59A45993598A59A55B5D5B5C5B5A5B5B5B8C5B8B5B8F5C2C5C405C415C3F
+5C3E5C905C915C945C8C5DEB5E0C5E8F5E875E8A5EF75F045F1F5F645F625F77
+5F795FD85FCC5FD75FCD5FF15FEB5FF85FEA6212621162846297629662806276
+6289626D628A627C627E627962736292626F6298626E62956293629162866539
+653B653865F166F4675F674E674F67506751675C6756675E6749674667600000
+A8
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+675367576B656BCF6C426C5E6C996C816C886C896C856C9B6C6A6C7A6C906C70
+6C8C6C686C966C926C7D6C836C726C7E6C746C866C766C8D6C946C986C827076
+707C707D707872627261726072C472C27396752C752B75377538768276EF77E3
+79C179C079BF7A767CFB7F5580968093809D8098809B809A80B2826F82920000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000828B828D898B89D28A008C378C468C558C9D8D648D708DB38EAB8ECA8F9B
+8FB08FC28FC68FC58FC45DE1909190A290AA90A690A3914991C691CC9632962E
+9631962A962C4E264E564E734E8B4E9B4E9E4EAB4EAC4F6F4F9D4F8D4F734F7F
+4F6C4F9B4F8B4F864F834F704F754F884F694F7B4F964F7E4F8F4F914F7A5154
+51525155516951775176517851BD51FD523B52385237523A5230522E52365241
+52BE52BB5352535453535351536653775378537953D653D453D7547354750000
+A9
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+5496547854955480547B5477548454925486547C549054715476548C549A5462
+5468548B547D548E56FA57835777576A5769576157665764577C591C59495947
+59485944595459BE59BB59D459B959AE59D159C659D059CD59CB59D359CA59AF
+59B359D259C55B5F5B645B635B975B9A5B985B9C5B995B9B5C1A5C485C450000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00005C465CB75CA15CB85CA95CAB5CB15CB35E185E1A5E165E155E1B5E115E78
+5E9A5E975E9C5E955E965EF65F265F275F295F805F815F7F5F7C5FDD5FE05FFD
+5FF55FFF600F6014602F60356016602A6015602160276029602B601B62166215
+623F623E6240627F62C962CC62C462BF62C262B962D262DB62AB62D362D462CB
+62C862A862BD62BC62D062D962C762CD62B562DA62B162D862D662D762C662AC
+62CE653E65A765BC65FA66146613660C66066602660E6600660F6615660A0000
+AA
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+6607670D670B676D678B67956771679C677367776787679D6797676F6770677F
+6789677E67906775679A6793677C676A67726B236B666B676B7F6C136C1B6CE3
+6CE86CF36CB16CCC6CE56CB36CBD6CBE6CBC6CE26CAB6CD56CD36CB86CC46CB9
+6CC16CAE6CD76CC56CF16CBF6CBB6CE16CDB6CCA6CAC6CEF6CDC6CD66CE00000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00007095708E7092708A7099722C722D723872487267726972C072CE72D972D7
+72D073A973A8739F73AB73A5753D759D7599759A768476C276F276F477E577FD
+793E7940794179C979C87A7A7A797AFA7CFE7F547F8C7F8B800580BA80A580A2
+80B180A180AB80A980B480AA80AF81E581FE820D82B3829D829982AD82BD829F
+82B982B182AC82A582AF82B882A382B082BE82B7864E8671521D88688ECB8FCE
+8FD48FD190B590B890B190B691C791D195779580961C9640963F963B96440000
+AB
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+964296B996E89752975E4E9F4EAD4EAE4FE14FB54FAF4FBF4FE04FD14FCF4FDD
+4FC34FB64FD84FDF4FCA4FD74FAE4FD04FC44FC24FDA4FCE4FDE4FB751575192
+519151A0524E5243524A524D524C524B524752C752C952C352C1530D5357537B
+539A53DB54AC54C054A854CE54C954B854A654B354C754C254BD54AA54C10000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000054C454C854AF54AB54B154BB54A954A754BF56FF5782578B57A057A357A2
+57CE57AE579359555951594F594E595059DC59D859FF59E359E85A0359E559EA
+59DA59E65A0159FB5B695BA35BA65BA45BA25BA55C015C4E5C4F5C4D5C4B5CD9
+5CD25DF75E1D5E255E1F5E7D5EA05EA65EFA5F085F2D5F655F885F855F8A5F8B
+5F875F8C5F896012601D60206025600E6028604D60706068606260466043606C
+606B606A6064624162DC6316630962FC62ED630162EE62FD630762F162F70000
+AC
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+62EF62EC62FE62F463116302653F654565AB65BD65E26625662D66206627662F
+661F66286631662466F767FF67D367F167D467D067EC67B667AF67F567E967EF
+67C467D167B467DA67E567B867CF67DE67F367B067D967E267DD67D26B6A6B83
+6B866BB56BD26BD76C1F6CC96D0B6D326D2A6D416D256D0C6D316D1E6D170000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00006D3B6D3D6D3E6D366D1B6CF56D396D276D386D296D2E6D356D0E6D2B70AB
+70BA70B370AC70AF70AD70B870AE70A472307272726F727472E972E072E173B7
+73CA73BB73B273CD73C073B3751A752D754F754C754E754B75AB75A475A575A2
+75A3767876867687768876C876C676C376C5770176F976F87709770B76FE76FC
+770777DC78027814780C780D794679497948794779B979BA79D179D279CB7A7F
+7A817AFF7AFD7C7D7D027D057D007D097D077D047D067F387F8E7FBF80040000
+AD
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+8010800D8011803680D680E580DA80C380C480CC80E180DB80CE80DE80E480DD
+81F4822282E78303830582E382DB82E6830482E58302830982D282D782F18301
+82DC82D482D182DE82D382DF82EF830686508679867B867A884D886B898189D4
+8A088A028A038C9E8CA08D748D738DB48ECD8ECC8FF08FE68FE28FEA8FE50000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00008FED8FEB8FE48FE890CA90CE90C190C3914B914A91CD95829650964B964C
+964D9762976997CB97ED97F3980198A898DB98DF999699994E584EB3500C500D
+50234FEF502650254FF8502950165006503C501F501A501250114FFA50005014
+50284FF15021500B501950184FF34FEE502D502A4FFE502B5009517C51A451A5
+51A251CD51CC51C651CB5256525C5254525B525D532A537F539F539D53DF54E8
+55105501553754FC54E554F2550654FA551454E954ED54E1550954EE54EA0000
+AE
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+54E65527550754FD550F5703570457C257D457CB57C35809590F59575958595A
+5A115A185A1C5A1F5A1B5A1359EC5A205A235A295A255A0C5A095B6B5C585BB0
+5BB35BB65BB45BAE5BB55BB95BB85C045C515C555C505CED5CFD5CFB5CEA5CE8
+5CF05CF65D015CF45DEE5E2D5E2B5EAB5EAD5EA75F315F925F915F9060590000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00006063606560506055606D6069606F6084609F609A608D6094608C60856096
+624762F3630862FF634E633E632F635563426346634F6349633A6350633D632A
+632B6328634D634C65486549659965C165C566426649664F66436652664C6645
+664166F867146715671768216838684868466853683968426854682968B36817
+684C6851683D67F468506840683C6843682A68456813681868416B8A6B896BB7
+6C236C276C286C266C246CF06D6A6D956D886D876D666D786D776D596D930000
+AF
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+6D6C6D896D6E6D5A6D746D696D8C6D8A6D796D856D656D9470CA70D870E470D9
+70C870CF7239727972FC72F972FD72F872F7738673ED740973EE73E073EA73DE
+7554755D755C755A755975BE75C575C775B275B375BD75BC75B975C275B8768B
+76B076CA76CD76CE7729771F7720772877E9783078277838781D783478370000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00007825782D7820781F7832795579507960795F7956795E795D7957795A79E4
+79E379E779DF79E679E979D87A847A887AD97B067B117C897D217D177D0B7D0A
+7D207D227D147D107D157D1A7D1C7D0D7D197D1B7F3A7F5F7F947FC57FC18006
+8018801580198017803D803F80F1810280F0810580ED80F4810680F880F38108
+80FD810A80FC80EF81ED81EC82008210822A822B8228822C82BB832B83528354
+834A83388350834983358334834F833283398336831783408331832883430000
+B0
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+8654868A86AA869386A486A9868C86A3869C8870887788818882887D88798A18
+8A108A0E8A0C8A158A0A8A178A138A168A0F8A118C488C7A8C798CA18CA28D77
+8EAC8ED28ED48ECF8FB1900190068FF790008FFA8FF490038FFD90058FF89095
+90E190DD90E29152914D914C91D891DD91D791DC91D995839662966396610000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000965B965D96649658965E96BB98E299AC9AA89AD89B259B329B3C4E7E507A
+507D505C50475043504C505A504950655076504E5055507550745077504F500F
+506F506D515C519551F0526A526F52D252D952D852D55310530F5319533F5340
+533E53C366FC5546556A55665544555E55615543554A55315556554F5555552F
+55645538552E555C552C55635533554155575708570B570957DF5805580A5806
+57E057E457FA5802583557F757F9592059625A365A415A495A665A6A5A400000
+B1
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+5A3C5A625A5A5A465A4A5B705BC75BC55BC45BC25BBF5BC65C095C085C075C60
+5C5C5C5D5D075D065D0E5D1B5D165D225D115D295D145D195D245D275D175DE2
+5E385E365E335E375EB75EB85EB65EB55EBE5F355F375F575F6C5F695F6B5F97
+5F995F9E5F985FA15FA05F9C607F60A3608960A060A860CB60B460E660BD0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000060C560BB60B560DC60BC60D860D560C660DF60B860DA60C7621A621B6248
+63A063A76372639663A263A563776367639863AA637163A963896383639B636B
+63A863846388639963A163AC6392638F6380637B63696368637A655D65566551
+65596557555F654F655865556554659C659B65AC65CF65CB65CC65CE665D665A
+666466686666665E66F952D7671B688168AF68A2689368B5687F687668B168A7
+689768B0688368C468AD688668856894689D68A8689F68A168826B326BBA0000
+B2
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+6BEB6BEC6C2B6D8E6DBC6DF36DD96DB26DE16DCC6DE46DFB6DFA6E056DC76DCB
+6DAF6DD16DAE6DDE6DF96DB86DF76DF56DC56DD26E1A6DB56DDA6DEB6DD86DEA
+6DF16DEE6DE86DC66DC46DAA6DEC6DBF6DE670F97109710A70FD70EF723D727D
+7281731C731B73167313731973877405740A7403740673FE740D74E074F60000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000074F7751C75227565756675627570758F75D475D575B575CA75CD768E76D4
+76D276DB7737773E773C77367738773A786B7843784E79657968796D79FB7A92
+7A957B207B287B1B7B2C7B267B197B1E7B2E7C927C977C957D467D437D717D2E
+7D397D3C7D407D307D337D447D2F7D427D327D317F3D7F9E7F9A7FCC7FCE7FD2
+801C804A8046812F81168123812B81298130812482028235823782368239838E
+839E8398837883A2839683BD83AB8392838A8393838983A08377837B837C0000
+B3
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+838683A786555F6A86C786C086B686C486B586C686CB86B186AF86C98853889E
+888888AB88928896888D888B8993898F8A2A8A1D8A238A258A318A2D8A1F8A1B
+8A228C498C5A8CA98CAC8CAB8CA88CAA8CA78D678D668DBE8DBA8EDB8EDF9019
+900D901A90179023901F901D90109015901E9020900F90229016901B90140000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000090E890ED90FD915791CE91F591E691E391E791ED91E99589966A96759673
+96789670967496769677966C96C096EA96E97AE07ADF980298039B5A9CE59E75
+9E7F9EA59EBB50A2508D508550995091508050965098509A670051F152725274
+5275526952DE52DD52DB535A53A5557B558055A7557C558A559D55985582559C
+55AA55945587558B558355B355AE559F553E55B2559A55BB55AC55B1557E5589
+55AB5599570D582F582A58345824583058315821581D582058F958FA59600000
+B4
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+5A775A9A5A7F5A925A9B5AA75B735B715BD25BCC5BD35BD05C0A5C0B5C315D4C
+5D505D345D475DFD5E455E3D5E405E435E7E5ECA5EC15EC25EC45F3C5F6D5FA9
+5FAA5FA860D160E160B260B660E0611C612360FA611560F060FB60F4616860F1
+610E60F6610961006112621F624963A3638C63CF63C063E963C963C663CD0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000063D263E363D063E163D663ED63EE637663F463EA63DB645263DA63F9655E
+6566656265636591659065AF666E667066746676666F6691667A667E667766FE
+66FF671F671D68FA68D568E068D868D7690568DF68F568EE68E768F968D268F2
+68E368CB68CD690D6912690E68C968DA696E68FB6B3E6B3A6B3D6B986B966BBC
+6BEF6C2E6C2F6C2C6E2F6E386E546E216E326E676E4A6E206E256E236E1B6E5B
+6E586E246E566E6E6E2D6E266E6F6E346E4D6E3A6E2C6E436E1D6E3E6ECB0000
+B5
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+6E896E196E4E6E636E446E726E696E5F7119711A7126713071217136716E711C
+724C728472807336732573347329743A742A743374227425743574367434742F
+741B7426742875257526756B756A75E275DB75E375D975D875DE75E0767B767C
+7696769376B476DC774F77ED785D786C786F7A0D7A087A0B7A057A007A980000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00007A977A967AE57AE37B497B567B467B507B527B547B4D7B4B7B4F7B517C9F
+7CA57D5E7D507D687D557D2B7D6E7D727D617D667D627D707D7355847FD47FD5
+800B8052808581558154814B8151814E81398146813E814C815381748212821C
+83E9840383F8840D83E083C5840B83C183EF83F183F48457840A83F0840C83CC
+83FD83F283CA8438840E840483DC840783D483DF865B86DF86D986ED86D486DB
+86E486D086DE885788C188C288B1898389968A3B8A608A558A5E8A3C8A410000
+B6
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+8A548A5B8A508A468A348A3A8A368A568C618C828CAF8CBC8CB38CBD8CC18CBB
+8CC08CB48CB78CB68CBF8CB88D8A8D858D818DCE8DDD8DCB8DDA8DD18DCC8DDB
+8DC68EFB8EF88EFC8F9C902E90359031903890329036910290F5910990FE9163
+916591CF9214921592239209921E920D9210920792119594958F958B95910000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000095939592958E968A968E968B967D96859686968D9672968496C196C596C4
+96C696C796EF96F297CC98059806980898E798EA98EF98E998F298ED99AE99AD
+9EC39ECD9ED14E8250AD50B550B250B350C550BE50AC50B750BB50AF50C7527F
+5277527D52DF52E652E452E252E3532F55DF55E855D355E655CE55DC55C755D1
+55E355E455EF55DA55E155C555C655E555C957125713585E585158585857585A
+5854586B584C586D584A58625852584B59675AC15AC95ACC5ABE5ABD5ABC0000
+B7
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+5AB35AC25AB25D695D6F5E4C5E795EC95EC85F125F595FAC5FAE611A610F6148
+611F60F3611B60F961016108614E614C6144614D613E61346127610D61066137
+622162226413643E641E642A642D643D642C640F641C6414640D643664166417
+6406656C659F65B06697668966876688669666846698668D67036994696D0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000695A697769606954697569306982694A6968696B695E695369796986695D
+6963695B6B476B726BC06BBF6BD36BFD6EA26EAF6ED36EB66EC26E906E9D6EC7
+6EC56EA56E986EBC6EBA6EAB6ED16E966E9C6EC46ED46EAA6EA76EB4714E7159
+7169716471497167715C716C7166714C7165715E714671687156723A72527337
+7345733F733E746F745A7455745F745E7441743F7459745B745C757675787600
+75F0760175F275F175FA75FF75F475F376DE76DF775B776B7766775E77630000
+B8
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+7779776A776C775C77657768776277EE788E78B078977898788C7889787C7891
+7893787F797A797F7981842C79BD7A1C7A1A7A207A147A1F7A1E7A9F7AA07B77
+7BC07B607B6E7B677CB17CB37CB57D937D797D917D817D8F7D5B7F6E7F697F6A
+7F727FA97FA87FA480568058808680848171817081788165816E8173816B0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00008179817A81668205824784828477843D843184758466846B8449846C845B
+843C8435846184638469846D8446865E865C865F86F9871387088707870086FE
+86FB870287038706870A885988DF88D488D988DC88D888DD88E188CA88D588D2
+899C89E38A6B8A728A738A668A698A708A878A7C8A638AA08A718A858A6D8A62
+8A6E8A6C8A798A7B8A3E8A688C628C8A8C898CCA8CC78CC88CC48CB28CC38CC2
+8CC58DE18DDF8DE88DEF8DF38DFA8DEA8DE48DE68EB28F038F098EFE8F0A0000
+B9
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+8F9F8FB2904B904A905390429054903C905590509047904F904E904D9051903E
+904191129117916C916A916991C9923792579238923D9240923E925B924B9264
+925192349249924D92459239923F925A959896989694969596CD96CB96C996CA
+96F796FB96F996F6975697749776981098119813980A9812980C98FC98F40000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000098FD98FE99B399B199B49AE19CE99E829F0E9F139F2050E750EE50E550D6
+50ED50DA50D550CF50D150F150CE50E9516251F352835282533153AD55FE5600
+561B561755FD561456065609560D560E55F75616561F5608561055F657185716
+5875587E58835893588A58795885587D58FD592559225924596A59695AE15AE6
+5AE95AD75AD65AD85AE35B755BDE5BE75BE15BE55BE65BE85BE25BE45BDF5C0D
+5C625D845D875E5B5E635E555E575E545ED35ED65F0A5F465F705FB961470000
+BA
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+613F614B617761626163615F615A61586175622A64876458645464A46478645F
+647A645164676434646D647B657265A165D765D666A266A8669D699C69A86995
+69C169AE69D369CB699B69B769BB69AB69B469D069CD69AD69CC69A669C369A3
+6B496B4C6C336F336F146EFE6F136EF46F296F3E6F206F2C6F0F6F026F220000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00006EFF6EEF6F066F316F386F326F236F156F2B6F2F6F886F2A6EEC6F016EF2
+6ECC6EF771947199717D718A71847192723E729272967344735074647463746A
+7470746D750475917627760D760B7609761376E176E37784777D777F776178C1
+789F78A778B378A978A3798E798F798D7A2E7A317AAA7AA97AED7AEF7BA17B95
+7B8B7B757B977B9D7B947B8F7BB87B877B847CB97CBD7CBE7DBB7DB07D9C7DBD
+7DBE7DA07DCA7DB47DB27DB17DBA7DA27DBF7DB57DB87DAD7DD27DC77DAC0000
+BB
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+7F707FE07FE17FDF805E805A808781508180818F8188818A817F818281E781FA
+82078214821E824B84C984BF84C684C48499849E84B2849C84CB84B884C084D3
+849084BC84D184CA873F871C873B872287258734871887558737872988F38902
+88F488F988F888FD88E8891A88EF8AA68A8C8A9E8AA38A8D8AA18A938AA40000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00008AAA8AA58AA88A988A918A9A8AA78C6A8C8D8C8C8CD38CD18CD28D6B8D99
+8D958DFC8F148F128F158F138FA390609058905C90639059905E9062905D905B
+91199118911E917591789177917492789280928592989296927B9293929C92A8
+927C929195A195A895A995A395A595A49699969C969B96CC96D29700977C9785
+97F69817981898AF98B199039905990C990999C19AAF9AB09AE69B419B429CF4
+9CF69CF39EBC9F3B9F4A5104510050FB50F550F9510251085109510551DC0000
+BC
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+528752885289528D528A52F053B2562E563B56395632563F563456295653564E
+565756745636562F56305880589F589E58B3589C58AE58A958A6596D5B095AFB
+5B0B5AF55B0C5B085BEE5BEC5BE95BEB5C645C655D9D5D945E625E5F5E615EE2
+5EDA5EDF5EDD5EE35EE05F485F715FB75FB561766167616E615D615561820000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000617C6170616B617E61A7619061AB618E61AC619A61A4619461AE622E6469
+646F6479649E64B26488649064B064A56493649564A9649264AE64AD64AB649A
+64AC649964A264B365756577657866AE66AB66B466B16A236A1F69E86A016A1E
+6A1969FD6A216A136A0A69F36A026A0569ED6A116B506B4E6BA46BC56BC66F3F
+6F7C6F846F516F666F546F866F6D6F5B6F786F6E6F8E6F7A6F706F646F976F58
+6ED56F6F6F606F5F719F71AC71B171A87256729B734E73577469748B74830000
+BD
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+747E7480757F76207629761F7624762676217622769A76BA76E4778E7787778C
+7791778B78CB78C578BA78CA78BE78D578BC78D07A3F7A3C7A407A3D7A377A3B
+7AAF7AAE7BAD7BB17BC47BB47BC67BC77BC17BA07BCC7CCA7DE07DF47DEF7DFB
+7DD87DEC7DDD7DE87DE37DDA7DDE7DE97D9E7DD97DF27DF97F757F777FAF0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00007FE98026819B819C819D81A0819A81988517853D851A84EE852C852D8513
+851185238521851484EC852584FF850687828774877687608766877887688759
+8757874C8753885B885D89108907891289138915890A8ABC8AD28AC78AC48A95
+8ACB8AF88AB28AC98AC28ABF8AB08AD68ACD8AB68AB98ADB8C4C8C4E8C6C8CE0
+8CDE8CE68CE48CEC8CED8CE28CE38CDC8CEA8CE18D6D8D9F8DA38E2B8E108E1D
+8E228E0F8E298E1F8E218E1E8EBA8F1D8F1B8F1F8F298F268F2A8F1C8F1E0000
+BE
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+8F259069906E9068906D90779130912D9127913191879189918B918392C592BB
+92B792EA92AC92E492C192B392BC92D292C792F092B295AD95B1970497069707
+97099760978D978B978F9821982B981C98B3990A99139912991899DD99D099DF
+99DB99D199D599D299D99AB79AEE9AEF9B279B459B449B779B6F9D069D090000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00009D039EA99EBE9ECE58A89F5251125118511451105115518051AA51DD5291
+529352F35659566B5679566956645678566A566856655671566F566C56625676
+58C158BE58C758C5596E5B1D5B345B785BF05C0E5F4A61B2619161A9618A61CD
+61B661BE61CA61C8623064C564C164CB64BB64BC64DA64C464C764C264CD64BF
+64D264D464BE657466C666C966B966C466C766B86A3D6A386A3A6A596A6B6A58
+6A396A446A626A616A4B6A476A356A5F6A486B596B776C056FC26FB16FA10000
+BF
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+6FC36FA46FC16FA76FB36FC06FB96FB66FA66FA06FB471BE71C971D071D271C8
+71D571B971CE71D971DC71C371C47368749C74A37498749F749E74E2750C750D
+76347638763A76E776E577A0779E779F77A578E878DA78EC78E779A67A4D7A4E
+7A467A4C7A4B7ABA7BD97C117BC97BE47BDB7BE17BE97BE67CD57CD67E0A0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00007E117E087E1B7E237E1E7E1D7E097E107F797FB27FF07FF17FEE802881B3
+81A981A881FB820882588259854A855985488568856985438549856D856A855E
+8783879F879E87A2878D8861892A89328925892B892189AA89A68AE68AFA8AEB
+8AF18B008ADC8AE78AEE8AFE8B018B028AF78AED8AF38AF68AFC8C6B8C6D8C93
+8CF48E448E318E348E428E398E358F3B8F2F8F388F338FA88FA6907590749078
+9072907C907A913491929320933692F89333932F932292FC932B9304931A0000
+C0
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+9310932693219315932E931995BB96A796A896AA96D5970E97119716970D9713
+970F975B975C9766979898309838983B9837982D9839982499109928991E991B
+9921991A99ED99E299F19AB89ABC9AFB9AED9B289B919D159D239D269D289D12
+9D1B9ED89ED49F8D9F9C512A511F5121513252F5568E56805690568556870000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000568F58D558D358D158CE5B305B2A5B245B7A5C375C685DBC5DBA5DBD5DB8
+5E6B5F4C5FBD61C961C261C761E661CB6232623464CE64CA64D864E064F064E6
+64EC64F164E264ED6582658366D966D66A806A946A846AA26A9C6ADB6AA36A7E
+6A976A906AA06B5C6BAE6BDA6C086FD86FF16FDF6FE06FDB6FE46FEB6FEF6F80
+6FEC6FE16FE96FD56FEE6FF071E771DF71EE71E671E571ED71EC71F471E07235
+72467370737274A974B074A674A876467642764C76EA77B377AA77B077AC0000
+C1
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+77A777AD77EF78F778FA78F478EF790179A779AA7A577ABF7C077C0D7BFE7BF7
+7C0C7BE07CE07CDC7CDE7CE27CDF7CD97CDD7E2E7E3E7E467E377E327E437E2B
+7E3D7E317E457E417E347E397E487E357E3F7E2F7F447FF37FFC807180728070
+806F807381C681C381BA81C281C081BF81BD81C981BE81E88209827185AA0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00008584857E859C8591859485AF859B858785A8858A866787C087D187B387D2
+87C687AB87BB87BA87C887CB893B893689448938893D89AC8B0E8B178B198B1B
+8B0A8B208B1D8B048B108C418C3F8C738CFA8CFD8CFC8CF88CFB8DA88E498E4B
+8E488E4A8F448F3E8F428F458F3F907F907D9084908190829080913991A3919E
+919C934D938293289375934A9365934B9318937E936C935B9370935A935495CA
+95CB95CC95C895C696B196B896D6971C971E97A097D3984698B699359A010000
+C2
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+99FF9BAE9BAB9BAA9BAD9D3B9D3F9E8B9ECF9EDE9EDC9EDD9EDB9F3E9F4B53E2
+569556AE58D958D85B385F5D61E3623364F464F264FE650664FA64FB64F765B7
+66DC67266AB36AAC6AC36ABB6AB86AC26AAE6AAF6B5F6B786BAF7009700B6FFE
+70066FFA7011700F71FB71FC71FE71F87377737574A774BF7515765676580000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000765277BD77BF77BB77BC790E79AE7A617A627A607AC47AC57C2B7C277C2A
+7C1E7C237C217CE77E547E557E5E7E5A7E617E527E597F487FF97FFB80778076
+81CD81CF820A85CF85A985CD85D085C985B085BA85B985A687EF87EC87F287E0
+898689B289F48B288B398B2C8B2B8C508D058E598E638E668E648E5F8E558EC0
+8F498F4D90879083908891AB91AC91D09394938A939693A293B393AE93AC93B0
+9398939A939795D495D695D095D596E296DC96D996DB96DE972497A397A60000
+C3
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+97AD97F9984D984F984C984E985398BA993E993F993D992E99A59A0E9AC19B03
+9B069B4F9B4E9B4D9BCA9BC99BFD9BC89BC09D519D5D9D609EE09F159F2C5133
+56A558DE58DF58E25BF59F905EEC61F261F761F661F56500650F66E066DD6AE5
+6ADD6ADA6AD3701B701F7028701A701D701570187206720D725872A273780000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000737A74BD74CA74E375877586765F766177C7791979B17A6B7A697C3E7C3F
+7C387C3D7C377C407E6B7E6D7E797E697E6A7F857E737FB67FB97FB881D885E9
+85DD85EA85D585E485E585F787FB8805880D87F987FE8960895F8956895E8B41
+8B5C8B588B498B5A8B4E8B4F8B468B598D088D0A8E7C8E728E878E768E6C8E7A
+8E748F548F4E8FAD908A908B91B191AE93E193D193DF93C393C893DC93DD93D6
+93E293CD93D893E493D793E895DC96B496E3972A9727976197DC97FB985E0000
+C4
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+9858985B98BC994599499A169A199B0D9BE89BE79BD69BDB9D899D619D729D6A
+9D6C9E929E979E939EB452F856A856B756B656B456BC58E45B405B435B7D5BF6
+5DC961F861FA65186514651966E667276AEC703E703070327210737B74CF7662
+76657926792A792C792B7AC77AF67C4C7C437C4D7CEF7CF08FAE7E7D7E7C0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00007E827F4C800081DA826685FB85F9861185FA8606860B8607860A88148815
+896489BA89F88B708B6C8B668B6F8B5F8B6B8D0F8D0D8E898E818E858E8291B4
+91CB9418940393FD95E1973098C49952995199A89A2B9A309A379A359C139C0D
+9E799EB59EE89F2F9F5F9F639F615137513856C156C056C259145C6C5DCD61FC
+61FE651D651C659566E96AFB6B046AFA6BB2704C721B72A774D674D4766977D3
+7C507E8F7E8C7FBC8617862D861A882388228821881F896A896C89BD8B740000
+C5
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+8B778B7D8D138E8A8E8D8E8B8F5F8FAF91BA942E94339435943A94389432942B
+95E297389739973297FF9867986599579A459A439A409A3E9ACF9B549B519C2D
+9C259DAF9DB49DC29DB89E9D9EEF9F199F5C9F669F67513C513B56C856CA56C9
+5B7F5DD45DD25F4E61FF65246B0A6B6170517058738074E4758A766E766C0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000079B37C607C5F807E807D81DF8972896F89FC8B808D168D178E918E938F61
+9148944494519452973D973E97C397C1986B99559A559A4D9AD29B1A9C499C31
+9C3E9C3B9DD39DD79F349F6C9F6A9F9456CC5DD662006523652B652A66EC6B10
+74DA7ACA7C647C637C657E937E967E9481E28638863F88318B8A9090908F9463
+946094649768986F995C9A5A9A5B9A579AD39AD49AD19C549C579C569DE59E9F
+9EF456D158E9652C705E7671767277D77F507F888836883988628B938B920000
+C6
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+8B9682778D1B91C0946A97429748974497C698709A5F9B229B589C5F9DF99DFA
+9E7C9E7D9F079F779F725EF36B1670637C6C7C6E883B89C08EA191C194729470
+9871995E9AD69B239ECC706477DA8B9A947797C99A629A657E9C8B9C8EAA91C5
+947D947E947C9C779C789EF78C54947F9E1A72289A6A9B319E1B9E1E7C720000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+C9
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+4E424E5C51F5531A53824E074E0C4E474E8D56D7FA0C5C6E5F734E0F51874E0E
+4E2E4E934EC24EC94EC8519852FC536C53B957205903592C5C105DFF65E16BB3
+6BCC6C14723F4E314E3C4EE84EDC4EE94EE14EDD4EDA520C531C534C57225723
+5917592F5B815B845C125C3B5C745C735E045E805E825FC9620962506C150000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00006C366C436C3F6C3B72AE72B0738A79B8808A961E4F0E4F184F2C4EF54F14
+4EF14F004EF74F084F1D4F024F054F224F134F044EF44F1251B1521352095210
+52A65322531F534D538A540756E156DF572E572A5734593C5980597C5985597B
+597E5977597F5B565C155C255C7C5C7A5C7B5C7E5DDF5E755E845F025F1A5F74
+5FD55FD45FCF625C625E626462616266626262596260625A626565EF65EE673E
+67396738673B673A673F673C67336C186C466C526C5C6C4F6C4A6C546C4B0000
+CA
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+6C4C7071725E72B472B5738E752A767F7A757F518278827C8280827D827F864D
+897E909990979098909B909496229624962096234F564F3B4F624F494F534F64
+4F3E4F674F524F5F4F414F584F2D4F334F3F4F61518F51B9521C521E522152AD
+52AE530953635372538E538F54305437542A545454455419541C542554180000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000543D544F544154285424544756EE56E756E557415745574C5749574B5752
+5906594059A6599859A05997598E59A25990598F59A759A15B8E5B925C285C2A
+5C8D5C8F5C885C8B5C895C925C8A5C865C935C955DE05E0A5E0E5E8B5E895E8C
+5E885E8D5F055F1D5F785F765FD25FD15FD05FED5FE85FEE5FF35FE15FE45FE3
+5FFA5FEF5FF75FFB60005FF4623A6283628C628E628F629462876271627B627A
+6270628162886277627D62726274653765F065F465F365F265F5674567470000
+CB
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+67596755674C6748675D674D675A674B6BD06C196C1A6C786C676C6B6C846C8B
+6C8F6C716C6F6C696C9A6C6D6C876C956C9C6C666C736C656C7B6C8E7074707A
+726372BF72BD72C372C672C172BA72C573957397739373947392753A75397594
+75957681793D80348095809980908092809C8290828F8285828E829182930000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000828A828382848C788FC98FBF909F90A190A5909E90A790A096309628962F
+962D4E334F984F7C4F854F7D4F804F874F764F744F894F844F774F4C4F974F6A
+4F9A4F794F814F784F904F9C4F944F9E4F924F824F954F6B4F6E519E51BC51BE
+5235523252335246523152BC530A530B533C539253945487547F548154915482
+5488546B547A547E5465546C54745466548D546F546154605498546354675464
+56F756F9576F5772576D576B57715770577657805775577B5773577457620000
+CC
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+5768577D590C594559B559BA59CF59CE59B259CC59C159B659BC59C359D659B1
+59BD59C059C859B459C75B625B655B935B955C445C475CAE5CA45CA05CB55CAF
+5CA85CAC5C9F5CA35CAD5CA25CAA5CA75C9D5CA55CB65CB05CA65E175E145E19
+5F285F225F235F245F545F825F7E5F7D5FDE5FE5602D602660196032600B0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00006034600A60176033601A601E602C6022600D6010602E60136011600C6009
+601C6214623D62AD62B462D162BE62AA62B662CA62AE62B362AF62BB62A962B0
+62B8653D65A865BB660965FC66046612660865FB6603660B660D660565FD6611
+661066F6670A6785676C678E67926776677B6798678667846774678D678C677A
+679F679167996783677D67816778677967946B256B806B7E6BDE6C1D6C936CEC
+6CEB6CEE6CD96CB66CD46CAD6CE76CB76CD06CC26CBA6CC36CC66CED6CF20000
+CD
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+6CD26CDD6CB46C8A6C9D6C806CDE6CC06D306CCD6CC76CB06CF96CCF6CE96CD1
+709470987085709370867084709170967082709A7083726A72D672CB72D872C9
+72DC72D272D472DA72CC72D173A473A173AD73A673A273A073AC739D74DD74E8
+753F7540753E758C759876AF76F376F176F076F577F877FC77F977FB77FA0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000077F77942793F79C57A787A7B7AFB7C757CFD8035808F80AE80A380B880B5
+80AD822082A082C082AB829A8298829B82B582A782AE82BC829E82BA82B482A8
+82A182A982C282A482C382B682A28670866F866D866E8C568FD28FCB8FD38FCD
+8FD68FD58FD790B290B490AF90B390B09639963D963C963A96434FCD4FC54FD3
+4FB24FC94FCB4FC14FD44FDC4FD94FBB4FB34FDB4FC74FD64FBA4FC04FB94FEC
+5244524952C052C2533D537C539753965399539854BA54A154AD54A554CF0000
+CE
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+54C3830D54B754AE54D654B654C554C654A0547054BC54A254BE547254DE54B0
+57B5579E579F57A4578C5797579D579B57945798578F579957A5579A579558F4
+590D595359E159DE59EE5A0059F159DD59FA59FD59FC59F659E459F259F759DB
+59E959F359F559E059FE59F459ED5BA85C4C5CD05CD85CCC5CD75CCB5CDB0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00005CDE5CDA5CC95CC75CCA5CD65CD35CD45CCF5CC85CC65CCE5CDF5CF85DF9
+5E215E225E235E205E245EB05EA45EA25E9B5EA35EA55F075F2E5F565F866037
+603960546072605E6045605360476049605B604C60406042605F602460446058
+6066606E6242624362CF630D630B62F5630E630362EB62F9630F630C62F862F6
+63006313631462FA631562FB62F06541654365AA65BF6636662166326635661C
+662666226633662B663A661D66346639662E670F671067C167F267C867BA0000
+CF
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+67DC67BB67F867D867C067B767C567EB67E467DF67B567CD67B367F767F667EE
+67E367C267B967CE67E767F067B267FC67C667ED67CC67AE67E667DB67FA67C9
+67CA67C367EA67CB6B286B826B846BB66BD66BD86BE06C206C216D286D346D2D
+6D1F6D3C6D3F6D126D0A6CDA6D336D046D196D3A6D1A6D116D006D1D6D420000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00006D016D186D376D036D0F6D406D076D206D2C6D086D226D096D1070B7709F
+70BE70B170B070A170B470B570A972417249724A726C72707273726E72CA72E4
+72E872EB72DF72EA72E672E3738573CC73C273C873C573B973B673B573B473EB
+73BF73C773BE73C373C673B873CB74EC74EE752E7547754875A775AA767976C4
+7708770377047705770A76F776FB76FA77E777E878067811781278057810780F
+780E780978037813794A794C794B7945794479D579CD79CF79D679CE7A800000
+D0
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+7A7E7AD17B007B017C7A7C787C797C7F7C807C817D037D087D017F587F917F8D
+7FBE8007800E800F8014803780D880C780E080D180C880C280D080C580E380D9
+80DC80CA80D580C980CF80D780E680CD81FF8221829482D982FE82F9830782E8
+830082D5833A82EB82D682F482EC82E182F282F5830C82FB82F682F082EA0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000082E482E082FA82F382ED86778674867C86738841884E8867886A886989D3
+8A048A078D728FE38FE18FEE8FE090F190BD90BF90D590C590BE90C790CB90C8
+91D491D39654964F96519653964A964E501E50055007501350225030501B4FF5
+4FF450335037502C4FF64FF75017501C502050275035502F5031500E515A5194
+519351CA51C451C551C851CE5261525A5252525E525F5255526252CD530E539E
+552654E25517551254E754F354E4551A54FF5504550854EB5511550554F10000
+D1
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+550A54FB54F754F854E0550E5503550B5701570257CC583257D557D257BA57C6
+57BD57BC57B857B657BF57C757D057B957C1590E594A5A195A165A2D5A2E5A15
+5A0F5A175A0A5A1E5A335B6C5BA75BAD5BAC5C035C565C545CEC5CFF5CEE5CF1
+5CF75D005CF95E295E285EA85EAE5EAA5EAC5F335F305F67605D605A60670000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000604160A26088608060926081609D60836095609B60976087609C608E6219
+624662F263106356632C634463456336634363E46339634B634A633C63296341
+6334635863546359632D63476333635A63516338635763406348654A654665C6
+65C365C465C2664A665F6647665167126713681F681A684968326833683B684B
+684F68166831681C6835682B682D682F684E68446834681D6812681468266828
+682E684D683A682568206B2C6B2F6B2D6B316B346B6D80826B886BE66BE40000
+D2
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+6BE86BE36BE26BE76C256D7A6D636D646D766D0D6D616D926D586D626D6D6D6F
+6D916D8D6DEF6D7F6D866D5E6D676D606D976D706D7C6D5F6D826D986D2F6D68
+6D8B6D7E6D806D846D166D836D7B6D7D6D756D9070DC70D370D170DD70CB7F39
+70E270D770D270DE70E070D470CD70C570C670C770DA70CE70E1724272780000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000072777276730072FA72F472FE72F672F372FB730173D373D973E573D673BC
+73E773E373E973DC73D273DB73D473DD73DA73D773D873E874DE74DF74F474F5
+7521755B755F75B075C175BB75C475C075BF75B675BA768A76C9771D771B7710
+771377127723771177157719771A772277277823782C78227835782F7828782E
+782B782178297833782A78317954795B794F795C79537952795179EB79EC79E0
+79EE79ED79EA79DC79DE79DD7A867A897A857A8B7A8C7A8A7A877AD87B100000
+D3
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+7B047B137B057B0F7B087B0A7B0E7B097B127C847C917C8A7C8C7C887C8D7C85
+7D1E7D1D7D117D0E7D187D167D137D1F7D127D0F7D0C7F5C7F617F5E7F607F5D
+7F5B7F967F927FC37FC27FC08016803E803980FA80F280F980F5810180FB8100
+8201822F82258333832D83448319835183258356833F83418326831C83220000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00008342834E831B832A8308833C834D8316832483208337832F832983478345
+834C8353831E832C834B832783488653865286A286A88696868D8691869E8687
+86978686868B869A868586A5869986A186A786958698868E869D869086948843
+8844886D88758876887288808871887F886F8883887E8874887C8A128C478C57
+8C7B8CA48CA38D768D788DB58DB78DB68ED18ED38FFE8FF590028FFF8FFB9004
+8FFC8FF690D690E090D990DA90E390DF90E590D890DB90D790DC90E491500000
+D4
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+914E914F91D591E291DA965C965F96BC98E39ADF9B2F4E7F5070506A5061505E
+50605053504B505D50725048504D5041505B504A506250155045505F5069506B
+5063506450465040506E50735057505151D0526B526D526C526E52D652D3532D
+539C55755576553C554D55505534552A55515562553655355530555255450000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000550C55325565554E55395548552D553B5540554B570A570757FB581457E2
+57F657DC57F4580057ED57FD580857F8580B57F357CF580757EE57E357F257E5
+57EC57E1580E57FC581057E75801580C57F157E957F0580D5804595C5A605A58
+5A555A675A5E5A385A355A6D5A505A5F5A655A6C5A535A645A575A435A5D5A52
+5A445A5B5A485A8E5A3E5A4D5A395A4C5A705A695A475A515A565A425A5C5B72
+5B6E5BC15BC05C595D1E5D0B5D1D5D1A5D205D0C5D285D0D5D265D255D0F0000
+D5
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+5D305D125D235D1F5D2E5E3E5E345EB15EB45EB95EB25EB35F365F385F9B5F96
+5F9F608A6090608660BE60B060BA60D360D460CF60E460D960DD60C860B160DB
+60B760CA60BF60C360CD60C063326365638A6382637D63BD639E63AD639D6397
+63AB638E636F63876390636E63AF6375639C636D63AE637C63A4633B639F0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00006378638563816391638D6370655365CD66656661665B6659665C66626718
+687968876890689C686D686E68AE68AB6956686F68A368AC68A96875687468B2
+688F68776892687C686B687268AA68806871687E689B6896688B68A0688968A4
+6878687B6891688C688A687D6B366B336B376B386B916B8F6B8D6B8E6B8C6C2A
+6DC06DAB6DB46DB36E746DAC6DE96DE26DB76DF66DD46E006DC86DE06DDF6DD6
+6DBE6DE56DDC6DDD6DDB6DF46DCA6DBD6DED6DF06DBA6DD56DC26DCF6DC90000
+D6
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+6DD06DF26DD36DFD6DD76DCD6DE36DBB70FA710D70F7711770F4710C70F07104
+70F3711070FC70FF71067113710070F870F6710B7102710E727E727B727C727F
+731D7317730773117318730A730872FF730F731E738873F673F873F574047401
+73FD7407740073FA73FC73FF740C740B73F474087564756375CE75D275CF0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000075CB75CC75D175D0768F768976D37739772F772D7731773277347733773D
+7725773B7735784878527849784D784A784C782678457850796479677969796A
+7963796B796179BB79FA79F879F679F77A8F7A947A907B357B477B347B257B30
+7B227B247B337B187B2A7B1D7B317B2B7B2D7B2F7B327B387B1A7B237C947C98
+7C967CA37D357D3D7D387D367D3A7D457D2C7D297D417D477D3E7D3F7D4A7D3B
+7D287F637F957F9C7F9D7F9B7FCA7FCB7FCD7FD07FD17FC77FCF7FC9801F0000
+D7
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+801E801B804780438048811881258119811B812D811F812C811E812181158127
+811D8122821182388233823A823482328274839083A383A8838D837A837383A4
+8374838F8381839583998375839483A9837D8383838C839D839B83AA838B837E
+83A583AF8388839783B0837F83A6838783AE8376839A8659865686BF86B70000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000086C286C186C586BA86B086C886B986B386B886CC86B486BB86BC86C386BD
+86BE88528889889588A888A288AA889A889188A1889F889888A78899889B8897
+88A488AC888C8893888E898289D689D989D58A308A278A2C8A1E8C398C3B8C5C
+8C5D8C7D8CA58D7D8D7B8D798DBC8DC28DB98DBF8DC18ED88EDE8EDD8EDC8ED7
+8EE08EE19024900B9011901C900C902190EF90EA90F090F490F290F390D490EB
+90EC90E991569158915A9153915591EC91F491F191F391F891E491F991EA0000
+D8
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+91EB91F791E891EE957A95869588967C966D966B9671966F96BF976A980498E5
+9997509B50955094509E508B50A35083508C508E509D5068509C509250825087
+515F51D45312531153A453A7559155A855A555AD5577564555A255935588558F
+55B5558155A3559255A4557D558C55A6557F559555A1558E570C582958370000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00005819581E58275823582857F558485825581C581B5833583F5836582E5839
+5838582D582C583B59615AAF5A945A9F5A7A5AA25A9E5A785AA65A7C5AA55AAC
+5A955AAE5A375A845A8A5A975A835A8B5AA95A7B5A7D5A8C5A9C5A8F5A935A9D
+5BEA5BCD5BCB5BD45BD15BCA5BCE5C0C5C305D375D435D6B5D415D4B5D3F5D35
+5D515D4E5D555D335D3A5D525D3D5D315D595D425D395D495D385D3C5D325D36
+5D405D455E445E415F585FA65FA55FAB60C960B960CC60E260CE60C461140000
+D9
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+60F2610A6116610560F5611360F860FC60FE60C161036118611D611060FF6104
+610B624A639463B163B063CE63E563E863EF63C3649D63F363CA63E063F663D5
+63F263F5646163DF63BE63DD63DC63C463D863D363C263C763CC63CB63C863F0
+63D763D965326567656A6564655C65686565658C659D659E65AE65D065D20000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000667C666C667B668066716679666A66726701690C68D3690468DC692A68EC
+68EA68F1690F68D668F768EB68E468F66913691068F368E1690768CC69086970
+68B4691168EF68C6691468F868D068FD68FC68E8690B690A691768CE68C868DD
+68DE68E668F468D1690668D468E96915692568C76B396B3B6B3F6B3C6B946B97
+6B996B956BBD6BF06BF26BF36C306DFC6E466E476E1F6E496E886E3C6E3D6E45
+6E626E2B6E3F6E416E5D6E736E1C6E336E4B6E406E516E3B6E036E2E6E5E0000
+DA
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+6E686E5C6E616E316E286E606E716E6B6E396E226E306E536E656E276E786E64
+6E776E556E796E526E666E356E366E5A7120711E712F70FB712E713171237125
+71227132711F7128713A711B724B725A7288728972867285728B7312730B7330
+73227331733373277332732D732673237335730C742E742C7430742B74160000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000741A7421742D743174247423741D74297420743274FB752F756F756C75E7
+75DA75E175E675DD75DF75E475D77695769276DA774677477744774D7745774A
+774E774B774C77DE77EC786078647865785C786D7871786A786E787078697868
+785E786279747973797279707A027A0A7A037A0C7A047A997AE67AE47B4A7B3B
+7B447B487B4C7B4E7B407B587B457CA27C9E7CA87CA17D587D6F7D637D537D56
+7D677D6A7D4F7D6D7D5C7D6B7D527D547D697D517D5F7D4E7F3E7F3F7F650000
+DB
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+7F667FA27FA07FA17FD78051804F805080FE80D48143814A8152814F8147813D
+814D813A81E681EE81F781F881F98204823C823D823F8275833B83CF83F98423
+83C083E8841283E783E483FC83F6841083C683C883EB83E383BF840183DD83E5
+83D883FF83E183CB83CE83D683F583C98409840F83DE8411840683C283F30000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000083D583FA83C783D183EA841383C383EC83EE83C483FB83D783E2841B83DB
+83FE86D886E286E686D386E386DA86EA86DD86EB86DC86EC86E986D786E886D1
+88488856885588BA88D788B988B888C088BE88B688BC88B788BD88B2890188C9
+89958998899789DD89DA89DB8A4E8A4D8A398A598A408A578A588A448A458A52
+8A488A518A4A8A4C8A4F8C5F8C818C808CBA8CBE8CB08CB98CB58D848D808D89
+8DD88DD38DCD8DC78DD68DDC8DCF8DD58DD98DC88DD78DC58EEF8EF78EFA0000
+DC
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+8EF98EE68EEE8EE58EF58EE78EE88EF68EEB8EF18EEC8EF48EE9902D9034902F
+9106912C910490FF90FC910890F990FB9101910091079105910391619164915F
+916291609201920A92259203921A9226920F920C9200921291FF91FD92069204
+92279202921C92249219921792059216957B958D958C95909687967E96880000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000096899683968096C296C896C396F196F0976C9770976E980798A998EB9CE6
+9EF94E834E844EB650BD50BF50C650AE50C450CA50B450C850C250B050C150BA
+50B150CB50C950B650B851D7527A5278527B527C55C355DB55CC55D055CB55CA
+55DD55C055D455C455E955BF55D2558D55CF55D555E255D655C855F255CD55D9
+55C25714585358685864584F584D5849586F5855584E585D58595865585B583D
+5863587158FC5AC75AC45ACB5ABA5AB85AB15AB55AB05ABF5AC85ABB5AC60000
+DD
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+5AB75AC05ACA5AB45AB65ACD5AB95A905BD65BD85BD95C1F5C335D715D635D4A
+5D655D725D6C5D5E5D685D675D625DF05E4F5E4E5E4A5E4D5E4B5EC55ECC5EC6
+5ECB5EC75F405FAF5FAD60F76149614A612B614561366132612E6146612F614F
+612961406220916862236225622463C563F163EB641064126409642064240000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000064336443641F641564186439643764226423640C64266430642864416435
+642F640A641A644064256427640B63E7641B642E6421640E656F659265D36686
+668C66956690668B668A66996694667867206966695F6938694E69626971693F
+6945696A6939694269576959697A694869496935696C6933693D696568F06978
+693469696940696F69446976695869416974694C693B694B6937695C694F6951
+69326952692F697B693C6B466B456B436B426B486B416B9BFA0D6BFB6BFC0000
+DE
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+6BF96BF76BF86E9B6ED66EC86E8F6EC06E9F6E936E946EA06EB16EB96EC66ED2
+6EBD6EC16E9E6EC96EB76EB06ECD6EA66ECF6EB26EBE6EC36EDC6ED86E996E92
+6E8E6E8D6EA46EA16EBF6EB36ED06ECA6E976EAE6EA371477154715271637160
+7141715D716271727178716A7161714271587143714B7170715F715071530000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00007144714D715A724F728D728C72917290728E733C7342733B733A7340734A
+73497444744A744B7452745174577440744F7450744E74427446744D745474E1
+74FF74FE74FD751D75797577698375EF760F760375F775FE75FC75F975F87610
+75FB75F675ED75F575FD769976B576DD7755775F776077527756775A77697767
+77547759776D77E07887789A7894788F788478957885788678A1788378797899
+78807896787B797C7982797D79797A117A187A197A127A177A157A227A130000
+DF
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+7A1B7A107AA37AA27A9E7AEB7B667B647B6D7B747B697B727B657B737B717B70
+7B617B787B767B637CB27CB47CAF7D887D867D807D8D7D7F7D857D7A7D8E7D7B
+7D837D7C7D8C7D947D847D7D7D927F6D7F6B7F677F687F6C7FA67FA57FA77FDB
+7FDC8021816481608177815C8169815B816281726721815E81768167816F0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000081448161821D8249824482408242824584F1843F845684768479848F848D
+846584518440848684678430844D847D845A845984748473845D8507845E8437
+843A8434847A8443847884328445842983D9844B842F8442842D845F84708439
+844E844C8452846F84C5848E843B8447843684338468847E8444842B84608454
+846E8450870B870486F7870C86FA86D686F5874D86F8870E8709870186F6870D
+870588D688CB88CD88CE88DE88DB88DA88CC88D08985899B89DF89E589E40000
+E0
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+89E189E089E289DC89E68A768A868A7F8A618A3F8A778A828A848A758A838A81
+8A748A7A8C3C8C4B8C4A8C658C648C668C868C848C858CCC8D688D698D918D8C
+8D8E8D8F8D8D8D938D948D908D928DF08DE08DEC8DF18DEE8DD08DE98DE38DE2
+8DE78DF28DEB8DF48F068EFF8F018F008F058F078F088F028F0B9052903F0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000090449049903D9110910D910F911191169114910B910E916E916F92489252
+9230923A926692339265925E9283922E924A9246926D926C924F92609267926F
+92369261927092319254926392509272924E9253924C92569232959F959C959E
+959B969296939691969796CE96FA96FD96F896F59773977797789772980F980D
+980E98AC98F698F999AF99B299B099B59AAD9AAB9B5B9CEA9CED9CE79E809EFD
+50E650D450D750E850F350DB50EA50DD50E450D350EC50F050EF50E350E00000
+E1
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+51D85280528152E952EB533053AC56275615560C561255FC560F561C56015613
+560255FA561D560455FF55F95889587C5890589858865881587F5874588B587A
+58875891588E587658825888587B5894588F58FE596B5ADC5AEE5AE55AD55AEA
+5ADA5AED5AEB5AF35AE25AE05ADB5AEC5ADE5ADD5AD95AE85ADF5B775BE00000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00005BE35C635D825D805D7D5D865D7A5D815D775D8A5D895D885D7E5D7C5D8D
+5D795D7F5E585E595E535ED85ED15ED75ECE5EDC5ED55ED95ED25ED45F445F43
+5F6F5FB6612C61286141615E61716173615261536172616C618061746154617A
+615B6165613B616A6161615662296227622B642B644D645B645D647464766472
+6473647D6475646664A6644E6482645E645C644B645364606450647F643F646C
+646B645964656477657365A066A166A0669F67056704672269B169B669C90000
+E2
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+69A069CE699669B069AC69BC69916999698E69A7698D69A969BE69AF69BF69C4
+69BD69A469D469B969CA699A69CF69B3699369AA69A1699E69D96997699069C2
+69B569A569C66B4A6B4D6B4B6B9E6B9F6BA06BC36BC46BFE6ECE6EF56EF16F03
+6F256EF86F376EFB6F2E6F096F4E6F196F1A6F276F186F3B6F126EED6F0A0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00006F366F736EF96EEE6F2D6F406F306F3C6F356EEB6F076F0E6F436F056EFD
+6EF66F396F1C6EFC6F3A6F1F6F0D6F1E6F086F21718771907189718071857182
+718F717B718671817197724472537297729572937343734D7351734C74627473
+7471747574727467746E750075027503757D759076167608760C76157611760A
+761476B87781777C77857782776E7780776F777E778378B278AA78B478AD78A8
+787E78AB789E78A578A078AC78A278A47998798A798B79967995799479930000
+E3
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+79977988799279907A2B7A4A7A307A2F7A287A267AA87AAB7AAC7AEE7B887B9C
+7B8A7B917B907B967B8D7B8C7B9B7B8E7B857B9852847B997BA47B827CBB7CBF
+7CBC7CBA7DA77DB77DC27DA37DAA7DC17DC07DC57D9D7DCE7DC47DC67DCB7DCC
+7DAF7DB97D967DBC7D9F7DA67DAE7DA97DA17DC97F737FE27FE37FE57FDE0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00008024805D805C8189818681838187818D818C818B8215849784A484A1849F
+84BA84CE84C284AC84AE84AB84B984B484C184CD84AA849A84B184D0849D84A7
+84BB84A2849484C784CC849B84A984AF84A884D6849884B684CF84A084D784D4
+84D284DB84B084918661873387238728876B8740872E871E87218719871B8743
+872C8741873E874687208732872A872D873C8712873A87318735874287268727
+87388724871A8730871188F788E788F188F288FA88FE88EE88FC88F688FB0000
+E4
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+88F088EC88EB899D89A1899F899E89E989EB89E88AAB8A998A8B8A928A8F8A96
+8C3D8C688C698CD58CCF8CD78D968E098E028DFF8E0D8DFD8E0A8E038E078E06
+8E058DFE8E008E048F108F118F0E8F0D9123911C91209122911F911D911A9124
+9121911B917A91729179917392A592A49276929B927A92A0929492AA928D0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000092A6929A92AB92799297927F92A392EE928E9282929592A2927D928892A1
+928A9286928C929992A7927E928792A9929D928B922D969E96A196FF9758977D
+977A977E978397809782977B97849781977F97CE97CD981698AD98AE99029900
+9907999D999C99C399B999BB99BA99C299BD99C79AB19AE39AE79B3E9B3F9B60
+9B619B5F9CF19CF29CF59EA750FF5103513050F85106510750F650FE510B510C
+50FD510A528B528C52F152EF56485642564C56355641564A5649564656580000
+E5
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+565A56405633563D562C563E5638562A563A571A58AB589D58B158A058A358AF
+58AC58A558A158FF5AFF5AF45AFD5AF75AF65B035AF85B025AF95B015B075B05
+5B0F5C675D995D975D9F5D925DA25D935D955DA05D9C5DA15D9A5D9E5E695E5D
+5E605E5C7DF35EDB5EDE5EE15F495FB2618B6183617961B161B061A261890000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000619B619361AF61AD619F619261AA61A1618D616661B3622D646E64706496
+64A064856497649C648F648B648A648C64A3649F646864B164986576657A6579
+657B65B265B366B566B066A966B266B766AA66AF6A006A066A1769E569F86A15
+69F169E46A2069FF69EC69E26A1B6A1D69FE6A2769F269EE6A1469F769E76A40
+6A0869E669FB6A0D69FC69EB6A096A046A186A256A0F69F66A266A0769F46A16
+6B516BA56BA36BA26BA66C016C006BFF6C026F416F266F7E6F876FC66F920000
+E6
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+6F8D6F896F8C6F626F4F6F856F5A6F966F766F6C6F826F556F726F526F506F57
+6F946F936F5D6F006F616F6B6F7D6F676F906F536F8B6F696F7F6F956F636F77
+6F6A6F7B71B271AF719B71B071A0719A71A971B5719D71A5719E71A471A171AA
+719C71A771B37298729A73587352735E735F7360735D735B7361735A73590000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000736274877489748A74867481747D74857488747C747975087507757E7625
+761E7619761D761C7623761A7628761B769C769D769E769B778D778F77897788
+78CD78BB78CF78CC78D178CE78D478C878C378C478C9799A79A179A0799C79A2
+799B6B767A397AB27AB47AB37BB77BCB7BBE7BAC7BCE7BAF7BB97BCA7BB57CC5
+7CC87CCC7CCB7DF77DDB7DEA7DE77DD77DE17E037DFA7DE67DF67DF17DF07DEE
+7DDF7F767FAC7FB07FAD7FED7FEB7FEA7FEC7FE67FE88064806781A3819F0000
+E7
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+819E819581A2819981978216824F825382528250824E82518524853B850F8500
+8529850E8509850D851F850A8527851C84FB852B84FA8508850C84F4852A84F2
+851584F784EB84F384FC851284EA84E9851684FE8528851D852E850284FD851E
+84F68531852684E784E884F084EF84F9851885208530850B8519852F86620000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000875687638764877787E1877387588754875B87528761875A8751875E876D
+876A8750874E875F875D876F876C877A876E875C8765874F877B877587628767
+8769885A8905890C8914890B891789188919890689168911890E890989A289A4
+89A389ED89F089EC8ACF8AC68AB88AD38AD18AD48AD58ABB8AD78ABE8AC08AC5
+8AD88AC38ABA8ABD8AD98C3E8C4D8C8F8CE58CDF8CD98CE88CDA8CDD8CE78DA0
+8D9C8DA18D9B8E208E238E258E248E2E8E158E1B8E168E118E198E268E270000
+E8
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+8E148E128E188E138E1C8E178E1A8F2C8F248F188F1A8F208F238F168F179073
+9070906F9067906B912F912B9129912A91329126912E91859186918A91819182
+9184918092D092C392C492C092D992B692CF92F192DF92D892E992D792DD92CC
+92EF92C292E892CA92C892CE92E692CD92D592C992E092DE92E792D192D30000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000092B592E192C692B4957C95AC95AB95AE95B096A496A296D3970597089702
+975A978A978E978897D097CF981E981D9826982998289820981B982798B29908
+98FA9911991499169917991599DC99CD99CF99D399D499CE99C999D699D899CB
+99D799CC9AB39AEC9AEB9AF39AF29AF19B469B439B679B749B719B669B769B75
+9B709B689B649B6C9CFC9CFA9CFD9CFF9CF79D079D009CF99CFB9D089D059D04
+9E839ED39F0F9F10511C51135117511A511151DE533453E156705660566E0000
+E9
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+567356665663566D5672565E5677571C571B58C858BD58C958BF58BA58C258BC
+58C65B175B195B1B5B215B145B135B105B165B285B1A5B205B1E5BEF5DAC5DB1
+5DA95DA75DB55DB05DAE5DAA5DA85DB25DAD5DAF5DB45E675E685E665E6F5EE9
+5EE75EE65EE85EE55F4B5FBC619D61A8619661C561B461C661C161CC61BA0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000061BF61B8618C64D764D664D064CF64C964BD648964C364DB64F364D96533
+657F657C65A266C866BE66C066CA66CB66CF66BD66BB66BA66CC67236A346A66
+6A496A676A326A686A3E6A5D6A6D6A766A5B6A516A286A5A6A3B6A3F6A416A6A
+6A646A506A4F6A546A6F6A696A606A3C6A5E6A566A556A4D6A4E6A466B556B54
+6B566BA76BAA6BAB6BC86BC76C046C036C066FAD6FCB6FA36FC76FBC6FCE6FC8
+6F5E6FC46FBD6F9E6FCA6FA870046FA56FAE6FBA6FAC6FAA6FCF6FBF6FB80000
+EA
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+6FA26FC96FAB6FCD6FAF6FB26FB071C571C271BF71B871D671C071C171CB71D4
+71CA71C771CF71BD71D871BC71C671DA71DB729D729E736973667367736C7365
+736B736A747F749A74A074947492749574A1750B7580762F762D7631763D7633
+763C76357632763076BB76E6779A779D77A1779C779B77A277A3779577990000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000779778DD78E978E578EA78DE78E378DB78E178E278ED78DF78E079A47A44
+7A487A477AB67AB87AB57AB17AB77BDE7BE37BE77BDD7BD57BE57BDA7BE87BF9
+7BD47BEA7BE27BDC7BEB7BD87BDF7CD27CD47CD77CD07CD17E127E217E177E0C
+7E1F7E207E137E0E7E1C7E157E1A7E227E0B7E0F7E167E0D7E147E257E247F43
+7F7B7F7C7F7A7FB17FEF802A8029806C81B181A681AE81B981B581AB81B081AC
+81B481B281B781A781F282558256825785568545856B854D8553856185580000
+EB
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+854085468564854185628544855185478563853E855B8571854E856E85758555
+85678560858C8566855D85548565856C866386658664879B878F879787938792
+87888781879687988779878787A3878587908791879D87848794879C879A8789
+891E89268930892D892E89278931892289298923892F892C891F89F18AE00000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00008AE28AF28AF48AF58ADD8B148AE48ADF8AF08AC88ADE8AE18AE88AFF8AEF
+8AFB8C918C928C908CF58CEE8CF18CF08CF38D6C8D6E8DA58DA78E338E3E8E38
+8E408E458E368E3C8E3D8E418E308E3F8EBD8F368F2E8F358F328F398F378F34
+90769079907B908690FA913391359136919391909191918D918F9327931E9308
+931F9306930F937A9338933C931B9323931293019346932D930E930D92CB931D
+92FA9325931392F992F793349302932492FF932993399335932A9314930C0000
+EC
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+930B92FE9309930092FB931695BC95CD95BE95B995BA95B695BF95B595BD96A9
+96D4970B9712971097999797979497F097F89835982F98329924991F99279929
+999E99EE99EC99E599E499F099E399EA99E999E79AB99ABF9AB49ABB9AF69AFA
+9AF99AF79B339B809B859B879B7C9B7E9B7B9B829B939B929B909B7A9B950000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00009B7D9B889D259D179D209D1E9D149D299D1D9D189D229D109D199D1F9E88
+9E869E879EAE9EAD9ED59ED69EFA9F129F3D51265125512251245120512952F4
+5693568C568D568656845683567E5682567F568158D658D458CF58D25B2D5B25
+5B325B235B2C5B275B265B2F5B2E5B7B5BF15BF25DB75E6C5E6A5FBE5FBB61C3
+61B561BC61E761E061E561E461E861DE64EF64E964E364EB64E464E865816580
+65B665DA66D26A8D6A966A816AA56A896A9F6A9B6AA16A9E6A876A936A8E0000
+ED
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+6A956A836AA86AA46A916A7F6AA66A9A6A856A8C6A926B5B6BAD6C096FCC6FA9
+6FF46FD46FE36FDC6FED6FE76FE66FDE6FF26FDD6FE26FE871E171F171E871F2
+71E471F071E27373736E736F749774B274AB749074AA74AD74B174A574AF7510
+75117512750F7584764376487649764776A476E977B577AB77B277B777B60000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000077B477B177A877F078F378FD790278FB78FC78F2790578F978FE790479AB
+79A87A5C7A5B7A567A587A547A5A7ABE7AC07AC17C057C0F7BF27C007BFF7BFB
+7C0E7BF47C0B7BF37C027C097C037C017BF87BFD7C067BF07BF17C107C0A7CE8
+7E2D7E3C7E427E3398487E387E2A7E497E407E477E297E4C7E307E3B7E367E44
+7E3A7F457F7F7F7E7F7D7FF47FF2802C81BB81C481CC81CA81C581C781BC81E9
+825B825A825C85838580858F85A7859585A0858B85A3857B85A4859A859E0000
+EE
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+8577857C858985A1857A85788557858E85968586858D8599859D858185A28582
+858885858579857685988590859F866887BE87AA87AD87C587B087AC87B987B5
+87BC87AE87C987C387C287CC87B787AF87C487CA87B487B687BF87B887BD87DE
+87B289358933893C893E894189528937894289AD89AF89AE89F289F38B1E0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00008B188B168B118B058B0B8B228B0F8B128B158B078B0D8B088B068B1C8B13
+8B1A8C4F8C708C728C718C6F8C958C948CF98D6F8E4E8E4D8E538E508E4C8E47
+8F438F409085907E9138919A91A2919B9199919F91A1919D91A093A1938393AF
+936493569347937C9358935C93769349935093519360936D938F934C936A9379
+935793559352934F93719377937B9361935E936393679380934E935995C795C0
+95C995C395C595B796AE96B096AC9720971F9718971D9719979A97A1979C0000
+EF
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+979E979D97D597D497F198419844984A9849984598439925992B992C992A9933
+9932992F992D99319930999899A399A19A0299FA99F499F799F999F899F699FB
+99FD99FE99FC9A039ABE9AFE9AFD9B019AFC9B489B9A9BA89B9E9B9B9BA69BA1
+9BA59BA49B869BA29BA09BAF9D339D419D679D369D2E9D2F9D319D389D300000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00009D459D429D439D3E9D379D409D3D7FF59D2D9E8A9E899E8D9EB09EC89EDA
+9EFB9EFF9F249F239F229F549FA05131512D512E5698569C5697569A569D5699
+59705B3C5C695C6A5DC05E6D5E6E61D861DF61ED61EE61F161EA61F061EB61D6
+61E964FF650464FD64F86501650364FC659465DB66DA66DB66D86AC56AB96ABD
+6AE16AC66ABA6AB66AB76AC76AB46AAD6B5E6BC96C0B7007700C700D70017005
+7014700E6FFF70006FFB70266FFC6FF7700A720171FF71F9720371FD73760000
+F0
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+74B874C074B574C174BE74B674BB74C275147513765C76647659765076537657
+765A76A676BD76EC77C277BA78FF790C79137914790979107912791179AD79AC
+7A5F7C1C7C297C197C207C1F7C2D7C1D7C267C287C227C257C307E5C7E507E56
+7E637E587E627E5F7E517E607E577E537FB57FB37FF77FF8807581D181D20000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000081D0825F825E85B485C685C085C385C285B385B585BD85C785C485BF85CB
+85CE85C885C585B185B685D2862485B885B785BE866987E787E687E287DB87EB
+87EA87E587DF87F387E487D487DC87D387ED87D887E387A487D787D9880187F4
+87E887DD8953894B894F894C89468950895189498B2A8B278B238B338B308B35
+8B478B2F8B3C8B3E8B318B258B378B268B368B2E8B248B3B8B3D8B3A8C428C75
+8C998C988C978CFE8D048D028D008E5C8E628E608E578E568E5E8E658E670000
+F1
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+8E5B8E5A8E618E5D8E698E548F468F478F488F4B9128913A913B913E91A891A5
+91A791AF91AA93B5938C939293B7939B939D938993A7938E93AA939E93A69395
+93889399939F938D93B1939193B293A493A893B493A393A595D295D395D196B3
+96D796DA5DC296DF96D896DD97239722972597AC97AE97A897AB97A497AA0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000097A297A597D797D997D697D897FA98509851985298B89941993C993A9A0F
+9A0B9A099A0D9A049A119A0A9A059A079A069AC09ADC9B089B049B059B299B35
+9B4A9B4C9B4B9BC79BC69BC39BBF9BC19BB59BB89BD39BB69BC49BB99BBD9D5C
+9D539D4F9D4A9D5B9D4B9D599D569D4C9D579D529D549D5F9D589D5A9E8E9E8C
+9EDF9F019F009F169F259F2B9F2A9F299F289F4C9F5551345135529652F753B4
+56AB56AD56A656A756AA56AC58DA58DD58DB59125B3D5B3E5B3F5DC35E700000
+F2
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+5FBF61FB65076510650D6509650C650E658465DE65DD66DE6AE76AE06ACC6AD1
+6AD96ACB6ADF6ADC6AD06AEB6ACF6ACD6ADE6B606BB06C0C7019702770207016
+702B702170227023702970177024701C702A720C720A72077202720572A572A6
+72A472A372A174CB74C574B774C37516766077C977CA77C477F1791D791B0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00007921791C7917791E79B07A677A687C337C3C7C397C2C7C3B7CEC7CEA7E76
+7E757E787E707E777E6F7E7A7E727E747E687F4B7F4A7F837F867FB77FFD7FFE
+807881D781D582648261826385EB85F185ED85D985E185E885DA85D785EC85F2
+85F885D885DF85E385DC85D185F085E685EF85DE85E2880087FA880387F687F7
+8809880C880B880687FC880887FF880A88028962895A895B89578961895C8958
+895D8959898889B789B689F68B508B488B4A8B408B538B568B548B4B8B550000
+F3
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+8B518B428B528B578C438C778C768C9A8D068D078D098DAC8DAA8DAD8DAB8E6D
+8E788E738E6A8E6F8E7B8EC28F528F518F4F8F508F538FB49140913F91B091AD
+93DE93C793CF93C293DA93D093F993EC93CC93D993A993E693CA93D493EE93E3
+93D593C493CE93C093D293E7957D95DA95DB96E19729972B972C972897260000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000097B397B797B697DD97DE97DF985C9859985D985798BF98BD98BB98BE9948
+9947994399A699A79A1A9A159A259A1D9A249A1B9A229A209A279A239A1E9A1C
+9A149AC29B0B9B0A9B0E9B0C9B379BEA9BEB9BE09BDE9BE49BE69BE29BF09BD4
+9BD79BEC9BDC9BD99BE59BD59BE19BDA9D779D819D8A9D849D889D719D809D78
+9D869D8B9D8C9D7D9D6B9D749D759D709D699D859D739D7B9D829D6F9D799D7F
+9D879D689E949E919EC09EFC9F2D9F409F419F4D9F569F579F58533756B20000
+F4
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+56B556B358E35B455DC65DC75EEE5EEF5FC05FC161F9651765166515651365DF
+66E866E366E46AF36AF06AEA6AE86AF96AF16AEE6AEF703C7035702F70377034
+703170427038703F703A70397040703B703370417213721472A8737D737C74BA
+76AB76AA76BE76ED77CC77CE77CF77CD77F27925792379277928792479290000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000079B27A6E7A6C7A6D7AF77C497C487C4A7C477C457CEE7E7B7E7E7E817E80
+7FBA7FFF807981DB81D9820B82688269862285FF860185FE861B860085F68604
+86098605860C85FD8819881088118817881388168963896689B989F78B608B6A
+8B5D8B688B638B658B678B6D8DAE8E868E888E848F598F568F578F558F588F5A
+908D9143914191B791B591B291B3940B941393FB9420940F941493FE94159410
+94289419940D93F5940093F79407940E9416941293FA940993F8940A93FF0000
+F5
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+93FC940C93F69411940695DE95E095DF972E972F97B997BB97FD97FE98609862
+9863985F98C198C29950994E9959994C994B99539A329A349A319A2C9A2A9A36
+9A299A2E9A389A2D9AC79ACA9AC69B109B129B119C0B9C089BF79C059C129BF8
+9C409C079C0E9C069C179C149C099D9F9D999DA49D9D9D929D989D909D9B0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00009DA09D949D9C9DAA9D979DA19D9A9DA29DA89D9E9DA39DBF9DA99D969DA6
+9DA79E999E9B9E9A9EE59EE49EE79EE69F309F2E9F5B9F609F5E9F5D9F599F91
+513A51395298529756C356BD56BE5B485B475DCB5DCF5EF161FD651B6B026AFC
+6B036AF86B0070437044704A7048704970457046721D721A7219737E7517766A
+77D0792D7931792F7C547C537CF27E8A7E877E887E8B7E867E8D7F4D7FBB8030
+81DD8618862A8626861F8623861C86198627862E862186208629861E86250000
+F6
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+8829881D881B88208824881C882B884A896D8969896E896B89FA8B798B788B45
+8B7A8B7B8D108D148DAF8E8E8E8C8F5E8F5B8F5D91469144914591B9943F943B
+94369429943D943C94309439942A9437942C9440943195E595E495E39735973A
+97BF97E1986498C998C698C0995899569A399A3D9A469A449A429A419A3A0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00009A3F9ACD9B159B179B189B169B3A9B529C2B9C1D9C1C9C2C9C239C289C29
+9C249C219DB79DB69DBC9DC19DC79DCA9DCF9DBE9DC59DC39DBB9DB59DCE9DB9
+9DBA9DAC9DC89DB19DAD9DCC9DB39DCD9DB29E7A9E9C9EEB9EEE9EED9F1B9F18
+9F1A9F319F4E9F659F649F924EB956C656C556CB59715B4B5B4C5DD55DD15EF2
+65216520652665226B0B6B086B096C0D7055705670577052721E721F72A9737F
+74D874D574D974D7766D76AD793579B47A707A717C577C5C7C597C5B7C5A0000
+F7
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+7CF47CF17E917F4F7F8781DE826B863486358633862C86328636882C88288826
+882A8825897189BF89BE89FB8B7E8B848B828B868B858B7F8D158E958E948E9A
+8E928E908E968E978F608F629147944C9450944A944B944F9447944594489449
+9446973F97E3986A986998CB9954995B9A4E9A539A549A4C9A4F9A489A4A0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00009A499A529A509AD09B199B2B9B3B9B569B559C469C489C3F9C449C399C33
+9C419C3C9C379C349C329C3D9C369DDB9DD29DDE9DDA9DCB9DD09DDC9DD19DDF
+9DE99DD99DD89DD69DF59DD59DDD9EB69EF09F359F339F329F429F6B9F959FA2
+513D529958E858E759725B4D5DD8882F5F4F62016203620465296525659666EB
+6B116B126B0F6BCA705B705A7222738273817383767077D47C677C667E95826C
+863A86408639863C8631863B863E88308832882E883389768974897389FE0000
+F8
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+8B8C8B8E8B8B8B888C458D198E988F648F6391BC94629455945D9457945E97C4
+97C598009A569A599B1E9B1F9B209C529C589C509C4A9C4D9C4B9C559C599C4C
+9C4E9DFB9DF79DEF9DE39DEB9DF89DE49DF69DE19DEE9DE69DF29DF09DE29DEC
+9DF49DF39DE89DED9EC29ED09EF29EF39F069F1C9F389F379F369F439F4F0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00009F719F709F6E9F6F56D356CD5B4E5C6D652D66ED66EE6B13705F7061705D
+7060722374DB74E577D5793879B779B67C6A7E977F89826D8643883888378835
+884B8B948B958E9E8E9F8EA08E9D91BE91BD91C2946B9468946996E597469743
+974797C797E59A5E9AD59B599C639C679C669C629C5E9C609E029DFE9E079E03
+9E069E059E009E019E099DFF9DFD9E049EA09F1E9F469F749F759F7656D4652E
+65B86B186B196B176B1A7062722672AA77D877D979397C697C6B7CF67E9A0000
+F9
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+7E987E9B7E9981E081E18646864786488979897A897C897B89FF8B988B998EA5
+8EA48EA3946E946D946F9471947397499872995F9C689C6E9C6D9E0B9E0D9E10
+9E0F9E129E119EA19EF59F099F479F789F7B9F7A9F79571E70667C6F883C8DB2
+8EA691C394749478947694759A609C749C739C719C759E149E139EF69F0A0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00009FA4706870657CF7866A883E883D883F8B9E8C9C8EA98EC9974B98739874
+98CC996199AB9A649A669A679B249E159E179F4862076B1E7227864C8EA89482
+948094819A699A689B2E9E197229864B8B9F94839C799EB776759A6B9C7A9E1D
+7069706A9EA49F7E9F499F98788192B988CF58BB60527CA75AFA255425662557
+2560256C2563255A2569255D255225642555255E256A256125582567255B2553
+25652556255F256B256225592568255C25512550256D256E2570256F25930000
diff --git a/library/encoding/dingbats.enc b/library/encoding/dingbats.enc
new file mode 100644
index 0000000..9729487
--- /dev/null
+++ b/library/encoding/dingbats.enc
@@ -0,0 +1,20 @@
+# Encoding file: dingbats, single-byte
+S
+003F 1 1
+00
+0000000100020003000400050006000700080009000A000B000C000D000E000F
+0010001100120013001400150016001700180019001A001B001C001D001E001F
+00202701270227032704260E2706270727082709261B261E270C270D270E270F
+2710271127122713271427152716271727182719271A271B271C271D271E271F
+2720272127222723272427252726272726052729272A272B272C272D272E272F
+2730273127322733273427352736273727382739273A273B273C273D273E273F
+2740274127422743274427452746274727482749274A274B25CF274D25A0274F
+27502751275225B225BC25C6275625D727582759275A275B275C275D275E007F
+0080008100820083008400850086008700880089008A008B008C008D008E008F
+0090009100920093009400950096009700980099009A009B009C009D009E009F
+0000276127622763276427652766276726632666266526602460246124622463
+2464246524662467246824692776277727782779277A277B277C277D277E277F
+2780278127822783278427852786278727882789278A278B278C278D278E278F
+2790279127922793279421922194219527982799279A279B279C279D279E279F
+27A027A127A227A327A427A527A627A727A827A927AA27AB27AC27AD27AE27AF
+000027B127B227B327B427B527B627B727B827B927BA27BB27BC27BD27BE0000
diff --git a/library/encoding/ebcdic.enc b/library/encoding/ebcdic.enc
new file mode 100644
index 0000000..f451de5
--- /dev/null
+++ b/library/encoding/ebcdic.enc
@@ -0,0 +1,19 @@
+S
+006F 0 1
+00
+0000000100020003008500090086007F0087008D008E000B000C000D000E000F
+0010001100120013008F000A0008009700180019009C009D001C001D001E001F
+0080008100820083008400920017001B00880089008A008B008C000500060007
+0090009100160093009400950096000400980099009A009B00140015009E001A
+002000A000E200E400E000E100E300E500E700F10060002E003C0028002B007C
+002600E900EA00EB00E800ED00EE00EF00EC00DF00210024002A0029003B009F
+002D002F00C200C400C000C100C300C500C700D1005E002C0025005F003E003F
+00F800C900CA00CB00C800CD00CE00CF00CC00A8003A002300400027003D0022
+00D800610062006300640065006600670068006900AB00BB00F000FD00FE00B1
+00B0006A006B006C006D006E006F00700071007200AA00BA00E600B800C600A4
+00B500AF0073007400750076007700780079007A00A100BF00D000DD00DE00AE
+00A200A300A500B700A900A700B600BC00BD00BE00AC005B005C005D00B400D7
+00F900410042004300440045004600470048004900AD00F400F600F200F300F5
+00A6004A004B004C004D004E004F00500051005200B900FB00FC00DB00FA00FF
+00D900F70053005400550056005700580059005A00B200D400D600D200D300D5
+003000310032003300340035003600370038003900B3007B00DC007D00DA007E
diff --git a/library/encoding/euc-cn.enc b/library/encoding/euc-cn.enc
new file mode 100644
index 0000000..4b2f8c7
--- /dev/null
+++ b/library/encoding/euc-cn.enc
@@ -0,0 +1,1397 @@
+# Encoding file: euc-cn, multi-byte
+M
+003F 0 82
+00
+0000000100020003000400050006000700080009000A000B000C000D000E000F
+0010001100120013001400150016001700180019001A001B001C001D001E001F
+0020002100220023002400250026002700280029002A002B002C002D002E002F
+0030003100320033003400350036003700380039003A003B003C003D003E003F
+0040004100420043004400450046004700480049004A004B004C004D004E004F
+0050005100520053005400550056005700580059005A005B005C005D005E005F
+0060006100620063006400650066006700680069006A006B006C006D006E006F
+0070007100720073007400750076007700780079007A007B007C007D007E007F
+0080008100820083008400850086008700880089008A008B008C008D008E008F
+0090009100920093009400950096009700980099009A009B009C009D009E009F
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+A1
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000030003001300230FB02C902C700A8300330052015FF5E2225202620182019
+201C201D3014301530083009300A300B300C300D300E300F3016301730103011
+00B100D700F72236222722282211220F222A222922082237221A22A522252220
+23122299222B222E2261224C2248223D221D2260226E226F22642265221E2235
+22342642264000B0203220332103FF0400A4FFE0FFE1203000A7211626062605
+25CB25CF25CE25C725C625A125A025B325B2203B219221902191219330130000
+A2
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000024882489248A248B248C248D248E248F2490249124922493249424952496
+249724982499249A249B247424752476247724782479247A247B247C247D247E
+247F248024812482248324842485248624872460246124622463246424652466
+2467246824690000000032203221322232233224322532263227322832290000
+00002160216121622163216421652166216721682169216A216B000000000000
+A3
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000FF01FF02FF03FFE5FF05FF06FF07FF08FF09FF0AFF0BFF0CFF0DFF0EFF0F
+FF10FF11FF12FF13FF14FF15FF16FF17FF18FF19FF1AFF1BFF1CFF1DFF1EFF1F
+FF20FF21FF22FF23FF24FF25FF26FF27FF28FF29FF2AFF2BFF2CFF2DFF2EFF2F
+FF30FF31FF32FF33FF34FF35FF36FF37FF38FF39FF3AFF3BFF3CFF3DFF3EFF3F
+FF40FF41FF42FF43FF44FF45FF46FF47FF48FF49FF4AFF4BFF4CFF4DFF4EFF4F
+FF50FF51FF52FF53FF54FF55FF56FF57FF58FF59FF5AFF5BFF5CFF5DFFE30000
+A4
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000304130423043304430453046304730483049304A304B304C304D304E304F
+3050305130523053305430553056305730583059305A305B305C305D305E305F
+3060306130623063306430653066306730683069306A306B306C306D306E306F
+3070307130723073307430753076307730783079307A307B307C307D307E307F
+3080308130823083308430853086308730883089308A308B308C308D308E308F
+3090309130923093000000000000000000000000000000000000000000000000
+A5
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000030A130A230A330A430A530A630A730A830A930AA30AB30AC30AD30AE30AF
+30B030B130B230B330B430B530B630B730B830B930BA30BB30BC30BD30BE30BF
+30C030C130C230C330C430C530C630C730C830C930CA30CB30CC30CD30CE30CF
+30D030D130D230D330D430D530D630D730D830D930DA30DB30DC30DD30DE30DF
+30E030E130E230E330E430E530E630E730E830E930EA30EB30EC30ED30EE30EF
+30F030F130F230F330F430F530F6000000000000000000000000000000000000
+A6
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000039103920393039403950396039703980399039A039B039C039D039E039F
+03A003A103A303A403A503A603A703A803A90000000000000000000000000000
+000003B103B203B303B403B503B603B703B803B903BA03BB03BC03BD03BE03BF
+03C003C103C303C403C503C603C703C803C90000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+A7
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000004100411041204130414041504010416041704180419041A041B041C041D
+041E041F0420042104220423042404250426042704280429042A042B042C042D
+042E042F00000000000000000000000000000000000000000000000000000000
+000004300431043204330434043504510436043704380439043A043B043C043D
+043E043F0440044104420443044404450446044704480449044A044B044C044D
+044E044F00000000000000000000000000000000000000000000000000000000
+A8
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000010100E101CE00E0011300E9011B00E8012B00ED01D000EC014D00F301D2
+00F2016B00FA01D400F901D601D801DA01DC00FC00EA00000000000000000000
+0000000000000000000031053106310731083109310A310B310C310D310E310F
+3110311131123113311431153116311731183119311A311B311C311D311E311F
+3120312131223123312431253126312731283129000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+A9
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00000000000000002500250125022503250425052506250725082509250A250B
+250C250D250E250F2510251125122513251425152516251725182519251A251B
+251C251D251E251F2520252125222523252425252526252725282529252A252B
+252C252D252E252F2530253125322533253425352536253725382539253A253B
+253C253D253E253F2540254125422543254425452546254725482549254A254B
+0000000000000000000000000000000000000000000000000000000000000000
+B0
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000554A963F57C3632854CE550954C07691764C853C77EE827E788D72319698
+978D6C285B894FFA630966975CB880FA684880AE660276CE51F9655671AC7FF1
+888450B2596561CA6FB382AD634C625253ED54277B06516B75A45DF462D48DCB
+9776628A8019575D97387F627238767D67CF767E64464F708D2562DC7A176591
+73ED642C6273822C9881677F7248626E62CC4F3474E3534A529E7ECA90A65E2E
+6886699C81807ED168D278C5868C9551508D8C2482DE80DE5305891252650000
+B1
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000858496F94FDD582199715B9D62B162A566B48C799C8D7206676F789160B2
+535153178F8880CC8D1D94A1500D72C8590760EB711988AB595482EF672C7B28
+5D297EF7752D6CF58E668FF8903C9F3B6BD491197B145F7C78A784D6853D6BD5
+6BD96BD65E015E8775F995ED655D5F0A5FC58F9F58C181C2907F965B97AD8FB9
+7F168D2C62414FBF53D8535E8FA88FA98FAB904D68075F6A819888689CD6618B
+522B762A5F6C658C6FD26EE85BBE6448517551B067C44E1979C9997C70B30000
+B2
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000075C55E7673BB83E064AD62E894B56CE2535A52C3640F94C27B944F2F5E1B
+82368116818A6E246CCA9A736355535C54FA886557E04E0D5E036B657C3F90E8
+601664E6731C88C16750624D8D22776C8E2991C75F6983DC8521991053C28695
+6B8B60ED60E8707F82CD82314ED36CA785CF64CD7CD969FD66F9834953957B56
+4FA7518C6D4B5C428E6D63D253C9832C833667E578B4643D5BDF5C945DEE8BE7
+62C667F48C7A640063BA8749998B8C177F2094F24EA7961098A4660C73160000
+B3
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000573A5C1D5E38957F507F80A05382655E7545553150218D856284949E671D
+56326F6E5DE2543570928F66626F64A463A35F7B6F8890F481E38FB05C186668
+5FF16C8996488D81886C649179F057CE6A59621054484E587A0B60E96F848BDA
+627F901E9A8B79E4540375F4630153196C608FDF5F1B9A70803B9F7F4F885C3A
+8D647FC565A570BD514551B2866B5D075BA062BD916C75748E0C7A2061017B79
+4EC77EF877854E1181ED521D51FA6A7153A88E87950496CF6EC19664695A0000
+B4
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000784050A877D7641089E6590463E35DDD7A7F693D4F20823955984E3275AE
+7A975E625E8A95EF521B5439708A6376952457826625693F918755076DF37EAF
+882262337EF075B5832878C196CC8F9E614874F78BCD6B64523A8D506B21806A
+847156F153064ECE4E1B51D17C97918B7C074FC38E7F7BE17A9C64675D1450AC
+810676017CB96DEC7FE067515B585BF878CB64AE641363AA632B9519642D8FBE
+7B5476296253592754466B7950A362345E266B864EE38D37888B5F85902E0000
+B5
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00006020803D62C54E39535590F863B880C665E66C2E4F4660EE6DE18BDE5F39
+86CB5F536321515A83616863520063638E4850125C9B79775BFC52307A3B60BC
+905376D75FB75F9776848E6C706F767B7B4977AA51F3909358244F4E6EF48FEA
+654C7B1B72C46DA47FDF5AE162B55E95573084827B2C5E1D5F1F90127F1498A0
+63826EC7789870B95178975B57AB75354F4375385E9760E659606DC06BBF7889
+53FC96D551CB52016389540A94938C038DCC7239789F87768FED8C0D53E00000
+B6
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00004E0176EF53EE948998769F0E952D5B9A8BA24E224E1C51AC846361C252A8
+680B4F97606B51BB6D1E515C6296659796618C46901775D890FD77636BD2728A
+72EC8BFB583577798D4C675C9540809A5EA66E2159927AEF77ED953B6BB565AD
+7F0E58065151961F5BF958A954288E726566987F56E4949D76FE9041638754C6
+591A593A579B8EB267358DFA8235524160F0581586FE5CE89E454FC4989D8BB9
+5A2560765384627C904F9102997F6069800C513F80335C1499756D314E8C0000
+B7
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00008D3053D17F5A7B4F4F104E4F96006CD573D085E95E06756A7FFB6A0A77FE
+94927E4151E170E653CD8FD483038D2972AF996D6CDB574A82B365B980AA623F
+963259A84EFF8BBF7EBA653E83F2975E556198DE80A5532A8BFD542080BA5E9F
+6CB88D3982AC915A54296C1B52067EB7575F711A6C7E7C89594B4EFD5FFF6124
+7CAA4E305C0167AB87025CF0950B98CE75AF70FD902251AF7F1D8BBD594951E4
+4F5B5426592B657780A45B75627662C28F905E456C1F7B264F0F4FD8670D0000
+B8
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00006D6E6DAA798F88B15F17752B629A8F854FEF91DC65A7812F81515E9C8150
+8D74526F89868D4B590D50854ED8961C723681798D1F5BCC8BA3964459877F1A
+54905676560E8BE565396982949976D66E895E727518674667D17AFF809D8D76
+611F79C665628D635188521A94A27F38809B7EB25C976E2F67607BD9768B9AD8
+818F7F947CD5641E95507A3F544A54E56B4C640162089E3D80F3759952729769
+845B683C86E49601969494EC4E2A54047ED968398DDF801566F45E9A7FB90000
+B9
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000057C2803F68975DE5653B529F606D9F9A4F9B8EAC516C5BAB5F135DE96C5E
+62F18D21517194A952FE6C9F82DF72D757A267848D2D591F8F9C83C754957B8D
+4F306CBD5B6459D19F1353E486CA9AA88C3780A16545987E56FA96C7522E74DC
+52505BE1630289024E5662D0602A68FA51735B9851A089C27BA199867F5060EF
+704C8D2F51495E7F901B747089C4572D78455F529F9F95FA8F689B3C8BE17678
+684267DC8DEA8D35523D8F8A6EDA68CD950590ED56FD679C88F98FC754C80000
+BA
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00009AB85B696D776C264EA55BB39A87916361A890AF97E9542B6DB55BD251FD
+558A7F557FF064BC634D65F161BE608D710A6C576C49592F676D822A58D5568E
+8C6A6BEB90DD597D801753F76D695475559D837783CF683879BE548C4F555408
+76D28C8996026CB36DB88D6B89109E648D3A563F9ED175D55F8872E0606854FC
+4EA86A2A886160528F7054C470D886799E3F6D2A5B8F5F187EA255894FAF7334
+543C539A5019540E547C4E4E5FFD745A58F6846B80E1877472D07CCA6E560000
+BB
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00005F27864E552C62A44E926CAA623782B154D7534E733E6ED1753B52125316
+8BDD69D05F8A60006DEE574F6B2273AF68538FD87F13636260A3552475EA8C62
+71156DA35BA65E7B8352614C9EC478FA87577C27768751F060F6714C66435E4C
+604D8C0E707063258F895FBD606286D456DE6BC160946167534960E066668D3F
+79FD4F1A70E96C478BB38BF27ED88364660F5A5A9B426D516DF78C416D3B4F19
+706B83B7621660D1970D8D27797851FB573E57FA673A75787A3D79EF7B950000
+BC
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000808C99658FF96FC08BA59E2159EC7EE97F095409678168D88F917C4D96C6
+53CA602575BE6C7253735AC97EA7632451E0810A5DF184DF628051805B634F0E
+796D524260B86D4E5BC45BC28BA18BB065E25FCC964559937EE77EAA560967B7
+59394F735BB652A0835A988A8D3E753294BE50477A3C4EF767B69A7E5AC16B7C
+76D1575A5C167B3A95F4714E517C80A9827059787F04832768C067EC78B17877
+62E363617B804FED526A51CF835069DB92748DF58D3189C1952E7BAD4EF60000
+BD
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000506582305251996F6E106E856DA75EFA50F559DC5C066D466C5F7586848B
+686859568BB253209171964D854969127901712680F64EA490CA6D479A845A07
+56BC640594F077EB4FA5811A72E189D2997A7F347EDE527F655991758F7F8F83
+53EB7A9663ED63A5768679F888579636622A52AB8282685467706377776B7AED
+6D017ED389E359D0621285C982A5754C501F4ECB75A58BEB5C4A5DFE7B4B65A4
+91D14ECA6D25895F7D2795264EC58C288FDB9773664B79818FD170EC6D780000
+BE
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00005C3D52B283465162830E775B66769CB84EAC60CA7CBE7CB37ECF4E958B66
+666F988897595883656C955C5F8475C997567ADF7ADE51C070AF7A9863EA7A76
+7EA0739697ED4E4570784E5D915253A9655165E781FC8205548E5C31759A97A0
+62D872D975BD5C459A7983CA5C40548077E94E3E6CAE805A62D2636E5DE85177
+8DDD8E1E952F4FF153E560E770AC526763509E435A1F5026773753777EE26485
+652B628963985014723589C951B38BC07EDD574783CC94A7519B541B5CFB0000
+BF
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00004FCA7AE36D5A90E19A8F55805496536154AF5F0063E9697751EF6168520A
+582A52D8574E780D770B5EB761777CE0625B62974EA27095800362F770E49760
+577782DB67EF68F578D5989779D158F354B353EF6E34514B523B5BA28BFE80AF
+554357A660735751542D7A7A60505B5463A762A053E362635BC767AF54ED7A9F
+82E691775E9388E4593857AE630E8DE880EF57577B774FA95FEB5BBD6B3E5321
+7B5072C2684677FF773665F751B54E8F76D45CBF7AA58475594E9B4150800000
+C0
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000998861276E8357646606634656F062EC62695ED39614578362C955878721
+814A8FA3556683B167658D5684DD5A6A680F62E67BEE961151706F9C8C3063FD
+89C861D27F0670C26EE57405699472FC5ECA90CE67176D6A635E52B372628001
+4F6C59E5916A70D96D9D52D24E5096F7956D857E78CA7D2F5121579264C2808B
+7C7B6CEA68F1695E51B7539868A872819ECE7BF172F879BB6F137406674E91CC
+9CA4793C83898354540F68174E3D538952B1783E5386522950884F8B4FD00000
+C1
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000075E27ACB7C926CA596B6529B748354E94FE9805483B28FDE95705EC9601C
+6D9F5E18655B813894FE604B70BC7EC37CAE51C968817CB1826F4E248F8691CF
+667E4EAE8C0564A9804A50DA759771CE5BE58FBD6F664E86648295635ED66599
+521788C270C852A3730E7433679778F797164E3490BB9CDE6DCB51DB8D41541D
+62CE73B283F196F69F8494C34F367F9A51CC707596755CAD988653E64EE46E9C
+740969B4786B998F7559521876246D4167F3516D9F99804B54997B3C7ABF0000
+C2
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00009686578462E29647697C5A0464027BD36F0F964B82A6536298855E907089
+63B35364864F9C819E93788C97328DEF8D429E7F6F5E79845F559646622E9A74
+541594DD4FA365C55C655C617F1586516C2F5F8B73876EE47EFF5CE6631B5B6A
+6EE653754E7163A0756562A18F6E4F264ED16CA67EB68BBA841D87BA7F57903B
+95237BA99AA188F8843D6D1B9A867EDC59889EBB739B780186829A6C9A82561B
+541757CB4E709EA653568FC881097792999286EE6EE1851366FC61626F2B0000
+C3
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00008C298292832B76F26C135FD983BD732B8305951A6BDB77DB94C6536F8302
+51925E3D8C8C8D384E4873AB679A68859176970971646CA177095A9295416BCF
+7F8E66275BD059B95A9A95E895F74EEC840C84996AAC76DF9530731B68A65B5F
+772F919A97617CDC8FF78C1C5F257C7379D889C56CCC871C5BC65E4268C97720
+7EF55195514D52C95A297F05976282D763CF778485D079D26E3A5E9959998511
+706D6C1162BF76BF654F60AF95FD660E879F9E2394ED540D547D8C2C64780000
+C4
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000647986116A21819C78E864699B5462B9672B83AB58A89ED86CAB6F205BDE
+964C8C0B725F67D062C772614EA959C66BCD589366AE5E5552DF6155672876EE
+776672677A4662FF54EA545094A090A35A1C7EB36C164E435976801059485357
+753796BE56CA63208111607C95F96DD65462998151855AE980FD59AE9713502A
+6CE55C3C62DF4F60533F817B90066EBA852B62C85E7478BE64B5637B5FF55A18
+917F9E1F5C3F634F80425B7D556E954A954D6D8560A867E072DE51DD5B810000
+C5
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000062E76CDE725B626D94AE7EBD81136D53519C5F04597452AA601259736696
+8650759F632A61E67CEF8BFA54E66B279E256BB485D5545550766CA4556A8DB4
+722C5E156015743662CD6392724C5F986E436D3E65006F5876D878D076FC7554
+522453DB4E535E9E65C1802A80D6629B5486522870AE888D8DD16CE1547880DA
+57F988F48D54966A914D4F696C9B55B776C6783062A870F96F8E5F6D84EC68DA
+787C7BF781A8670B9E4F636778B0576F78129739627962AB528874356BD70000
+C6
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00005564813E75B276AE533975DE50FB5C418B6C7BC7504F72479A9798D86F02
+74E27968648777A562FC98918D2B54C180584E52576A82F9840D5E7351ED74F6
+8BC45C4F57616CFC98875A4678349B448FEB7C955256625194FA4EC683868461
+83E984B257D467345703666E6D668C3166DD7011671F6B3A6816621A59BB4E03
+51C46F0667D26C8F517668CB59476B6775665D0E81109F5065D7794879419A91
+8D775C824E5E4F01542F5951780C56686C148FC45F036C7D6CE38BAB63900000
+C7
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000060706D3D72756266948E94C553438FC17B7E4EDF8C264E7E9ED494B194B3
+524D6F5C90636D458C3458115D4C6B206B4967AA545B81547F8C589985375F3A
+62A26A47953965726084686577A74E544FA85DE7979864AC7FD85CED4FCF7A8D
+520783044E14602F7A8394A64FB54EB279E6743452E482B964D279BD5BDD6C81
+97528F7B6C22503E537F6E0564CE66746C3060C598778BF75E86743C7A7779CB
+4E1890B174036C4256DA914B6CC58D8B533A86C666F28EAF5C489A716E200000
+C8
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000053D65A369F8B8DA353BB570898A76743919B6CC9516875CA62F372AC5238
+529D7F3A7094763853749E4A69B7786E96C088D97FA4713671C3518967D374E4
+58E4651856B78BA9997662707ED560F970ED58EC4EC14EBA5FCD97E74EFB8BA4
+5203598A7EAB62544ECD65E5620E833884C98363878D71946EB65BB97ED25197
+63C967D480898339881551125B7A59828FB14E736C5D516589258F6F962E854A
+745E951095F06DA682E55F3164926D128428816E9CC3585E8D5B4E0953C10000
+C9
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00004F1E6563685155D34E2764149A9A626B5AC2745F82726DA968EE50E7838E
+7802674052396C997EB150BB5565715E7B5B665273CA82EB67495C715220717D
+886B95EA965564C58D6181B355846C5562477F2E58924F2455468D4F664C4E0A
+5C1A88F368A2634E7A0D70E7828D52FA97F65C1154E890B57ECD59628D4A86C7
+820C820D8D6664445C0461516D89793E8BBE78377533547B4F388EAB6DF15A20
+7EC5795E6C885BA15A76751A80BE614E6E1758F0751F7525727253477EF30000
+CA
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000770176DB526980DC57235E08593172EE65BD6E7F8BD75C388671534177F3
+62FE65F64EC098DF86805B9E8BC653F277E24F7F5C4E9A7659CB5F0F793A58EB
+4E1667FF4E8B62ED8A93901D52BF662F55DC566C90024ED54F8D91CA99706C0F
+5E0260435BA489C68BD56536624B99965B885BFF6388552E53D77626517D852C
+67A268B36B8A62928F9353D482126DD1758F4E668D4E5B70719F85AF669166D9
+7F7287009ECD9F205C5E672F8FF06811675F620D7AD658855EB665706F310000
+CB
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000060555237800D6454887075295E05681362F4971C53CC723D8C016C347761
+7A0E542E77AC987A821C8BF47855671470C165AF64955636601D79C153F84E1D
+6B7B80865BFA55E356DB4F3A4F3C99725DF3677E80386002988290015B8B8BBC
+8BF5641C825864DE55FD82CF91654FD77D20901F7C9F50F358516EAF5BBF8BC9
+80839178849C7B97867D968B968F7EE59AD3788E5C817A57904296A7795F5B59
+635F7B0B84D168AD55067F2974107D2295016240584C4ED65B83597958540000
+CC
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000736D631E8E4B8E0F80CE82D462AC53F06CF0915E592A60016C70574D644A
+8D2A762B6EE9575B6A8075F06F6D8C2D8C0857666BEF889278B363A253F970AD
+6C645858642A580268E0819B55107CD650188EBA6DCC8D9F70EB638F6D9B6ED4
+7EE68404684390036DD896768BA85957727985E4817E75BC8A8A68AF52548E22
+951163D098988E44557C4F5366FF568F60D56D9552435C4959296DFB586B7530
+751C606C82148146631167618FE2773A8DF38D3494C15E165385542C70C30000
+CD
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00006C405EF7505C4EAD5EAD633A8247901A6850916E77B3540C94DC5F647AE5
+687663457B527EDF75DB507762955934900F51F879C37A8156FE5F9290146D82
+5C60571F541051546E4D56E263A89893817F8715892A9000541E5C6F81C062D6
+625881319E3596409A6E9A7C692D59A562D3553E631654C786D96D3C5A0374E6
+889C6B6A59168C4C5F2F6E7E73A9987D4E3870F75B8C7897633D665A769660CB
+5B9B5A494E0781556C6A738B4EA167897F515F8065FA671B5FD859845A010000
+CE
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00005DCD5FAE537197E68FDD684556F4552F60DF4E3A6F4D7EF482C7840E59D4
+4F1F4F2A5C3E7EAC672A851A5473754F80C355829B4F4F4D6E2D8C135C096170
+536B761F6E29868A658795FB7EB9543B7A337D0A95EE55E17FC174EE631D8717
+6DA17A9D621165A1536763E16C835DEB545C94A84E4C6C618BEC5C4B65E0829C
+68A7543E54346BCB6B664E9463425348821E4F0D4FAE575E620A96FE66647269
+52FF52A1609F8BEF661471996790897F785277FD6670563B54389521727A0000
+CF
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00007A00606F5E0C6089819D591560DC718470EF6EAA6C5072806A8488AD5E2D
+4E605AB3559C94E36D177CFB9699620F7EC6778E867E5323971E8F9666875CE1
+4FA072ED4E0B53A6590F54136380952851484ED99C9C7EA454B88D2488548237
+95F26D8E5F265ACC663E966973B0732E53BF817A99857FA15BAA967796507EBF
+76F853A2957699997BB189446E584E617FD479658BE660F354CD4EAB98795DF7
+6A6150CF54118C618427785D9704524A54EE56A395006D885BB56DC666530000
+D0
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00005C0F5B5D6821809655787B11654869544E9B6B47874E978B534F631F643A
+90AA659C80C18C10519968B0537887F961C86CC46CFB8C225C5185AA82AF950C
+6B238F9B65B05FFB5FC34FE18845661F8165732960FA51745211578B5F6290A2
+884C91925E78674F602759D3514451F680F853086C7996C4718A4F114FEE7F9E
+673D55C5950879C088967EE3589F620C9700865A5618987B5F908BB884C49157
+53D965ED5E8F755C60647D6E5A7F7EEA7EED8F6955A75BA360AC65CB73840000
+D1
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00009009766377297EDA9774859B5B667A7496EA884052CB718F5FAA65EC8BE2
+5BFB9A6F5DE16B896C5B8BAD8BAF900A8FC5538B62BC9E269E2D54404E2B82BD
+7259869C5D1688596DAF96C554D14E9A8BB6710954BD960970DF6DF976D04E25
+781487125CA95EF68A00989C960E708E6CBF594463A9773C884D6F1482735830
+71D5538C781A96C155015F6671305BB48C1A9A8C6B83592E9E2F79E76768626C
+4F6F75A17F8A6D0B96336C274EF075D2517B68376F3E90808170599674760000
+D2
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000064475C2790657A918C2359DA54AC8200836F898180006930564E80367237
+91CE51B64E5F987563964E1A53F666F3814B591C6DB24E0058F9533B63D694F1
+4F9D4F0A886398905937905779FB4EEA80F075916C825B9C59E85F5D69058681
+501A5DF24E5977E34EE5827A6291661390915C794EBF5F7981C69038808475AB
+4EA688D4610F6BC55FC64E4976CA6EA28BE38BAE8C0A8BD15F027FFC7FCC7ECE
+8335836B56E06BB797F3963459FB541F94F66DEB5BC5996E5C395F1596900000
+D3
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000537082F16A315A749E705E947F2883B984248425836787478FCE8D6276C8
+5F719896786C662054DF62E54F6381C375C85EB896CD8E0A86F9548F6CF36D8C
+6C38607F52C775285E7D4F1860A05FE75C24753190AE94C072B96CB96E389149
+670953CB53F34F5191C98BF153C85E7C8FC26DE44E8E76C26986865E611A8206
+4F594FDE903E9C7C61096E1D6E1496854E885A3196E84E0E5C7F79B95B878BED
+7FBD738957DF828B90C15401904755BB5CEA5FA161086B3272F180B28A890000
+D4
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00006D745BD388D598848C6B9A6D9E336E0A51A4514357A38881539F63F48F95
+56ED54585706733F6E907F188FDC82D1613F6028966266F07EA68D8A8DC394A5
+5CB37CA4670860A6960580184E9190E75300966851418FD08574915D665597F5
+5B55531D78386742683D54C9707E5BB08F7D518D572854B1651266828D5E8D43
+810F846C906D7CDF51FF85FB67A365E96FA186A48E81566A90207682707671E5
+8D2362E952196CFD8D3C600E589E618E66FE8D60624E55B36E23672D8F670000
+D5
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000094E195F87728680569A8548B4E4D70B88BC86458658B5B857A84503A5BE8
+77BB6BE18A797C986CBE76CF65A98F975D2D5C5586386808536062187AD96E5B
+7EFD6A1F7AE05F706F335F20638C6DA867564E085E108D264ED780C07634969C
+62DB662D627E6CBC8D7571677F695146808753EC906E629854F286F08F998005
+951785178FD96D5973CD659F771F7504782781FB8D1E94884FA6679575B98BCA
+9707632F9547963584B8632377415F8172F04E896014657462EF6B63653F0000
+D6
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00005E2775C790D18BC1829D679D652F5431871877E580A281026C414E4B7EC7
+804C76F4690D6B966267503C4F84574063076B628DBE53EA65E87EB85FD7631A
+63B781F381F47F6E5E1C5CD95236667A79E97A1A8D28709975D46EDE6CBB7A92
+4E2D76C55FE0949F88777EC879CD80BF91CD4EF24F17821F54685DDE6D328BCC
+7CA58F7480985E1A549276B15B99663C9AA473E0682A86DB6731732A8BF88BDB
+90107AF970DB716E62C477A956314E3B845767F152A986C08D2E94F87B510000
+D7
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00004F4F6CE8795D9A7B6293722A62FD4E1378168F6C64B08D5A7BC668695E84
+88C55986649E58EE72B6690E95258FFD8D5857607F008C0651C6634962D95353
+684C74228301914C55447740707C6D4A517954A88D4459FF6ECB6DC45B5C7D2B
+4ED47C7D6ED35B5081EA6E0D5B579B0368D58E2A5B977EFC603B7EB590B98D70
+594F63CD79DF8DB3535265CF79568BC5963B7EC494BB7E825634918967007F6A
+5C0A907566285DE64F5067DE505A4F5C57505EA7000000000000000000000000
+D8
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00004E8D4E0C51404E105EFF53454E154E984E1E9B325B6C56694E2879BA4E3F
+53154E47592D723B536E6C1056DF80E499976BD3777E9F174E364E9F9F104E5C
+4E694E9382885B5B556C560F4EC4538D539D53A353A553AE97658D5D531A53F5
+5326532E533E8D5C5366536352025208520E522D5233523F5240524C525E5261
+525C84AF527D528252815290529351827F544EBB4EC34EC94EC24EE84EE14EEB
+4EDE4F1B4EF34F224F644EF54F254F274F094F2B4F5E4F6765384F5A4F5D0000
+D9
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00004F5F4F574F324F3D4F764F744F914F894F834F8F4F7E4F7B4FAA4F7C4FAC
+4F944FE64FE84FEA4FC54FDA4FE34FDC4FD14FDF4FF85029504C4FF3502C500F
+502E502D4FFE501C500C50255028507E504350555048504E506C507B50A550A7
+50A950BA50D6510650ED50EC50E650EE5107510B4EDD6C3D4F584F654FCE9FA0
+6C467C74516E5DFD9EC999985181591452F9530D8A07531051EB591951554EA0
+51564EB3886E88A44EB5811488D279805B3488037FB851AB51B151BD51BC0000
+DA
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000051C7519651A251A58BA08BA68BA78BAA8BB48BB58BB78BC28BC38BCB8BCF
+8BCE8BD28BD38BD48BD68BD88BD98BDC8BDF8BE08BE48BE88BE98BEE8BF08BF3
+8BF68BF98BFC8BFF8C008C028C048C078C0C8C0F8C118C128C148C158C168C19
+8C1B8C188C1D8C1F8C208C218C258C278C2A8C2B8C2E8C2F8C328C338C358C36
+5369537A961D962296219631962A963D963C964296499654965F9667966C9672
+96749688968D969796B09097909B909D909990AC90A190B490B390B690BA0000
+DB
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000090B890B090CF90C590BE90D090C490C790D390E690E290DC90D790DB90EB
+90EF90FE91049122911E91239131912F913991439146520D594252A252AC52AD
+52BE54FF52D052D652F053DF71EE77CD5EF451F551FC9B2F53B65F01755A5DEF
+574C57A957A1587E58BC58C558D15729572C572A57335739572E572F575C573B
+574257695785576B5786577C577B5768576D5776577357AD57A4578C57B257CF
+57A757B4579357A057D557D857DA57D957D257B857F457EF57F857E457DD0000
+DC
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000580B580D57FD57ED5800581E5819584458205865586C58815889589A5880
+99A89F1961FF8279827D827F828F828A82A88284828E82918297829982AB82B8
+82BE82B082C882CA82E3829882B782AE82CB82CC82C182A982B482A182AA829F
+82C482CE82A482E1830982F782E4830F830782DC82F482D282D8830C82FB82D3
+8311831A83068314831582E082D5831C8351835B835C83088392833C83348331
+839B835E832F834F83478343835F834083178360832D833A8333836683650000
+DD
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00008368831B8369836C836A836D836E83B0837883B383B483A083AA8393839C
+8385837C83B683A9837D83B8837B8398839E83A883BA83BC83C1840183E583D8
+58078418840B83DD83FD83D6841C84388411840683D483DF840F840383F883F9
+83EA83C583C0842683F083E1845C8451845A8459847384878488847A84898478
+843C844684698476848C848E8431846D84C184CD84D084E684BD84D384CA84BF
+84BA84E084A184B984B4849784E584E3850C750D853884F08539851F853A0000
+DE
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00008556853B84FF84FC8559854885688564855E857A77A285438572857B85A4
+85A88587858F857985AE859C858585B985B785B085D385C185DC85FF86278605
+86298616863C5EFE5F08593C594180375955595A5958530F5C225C255C2C5C34
+624C626A629F62BB62CA62DA62D762EE632262F66339634B634363AD63F66371
+637A638E63B4636D63AC638A636963AE63BC63F263F863E063FF63C463DE63CE
+645263C663BE64456441640B641B6420640C64266421645E6484646D64960000
+DF
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000647A64B764B8649964BA64C064D064D764E464E265096525652E5F0B5FD2
+75195F11535F53F153FD53E953E853FB541254165406544B5452545354545456
+54435421545754595423543254825494547754715464549A549B548454765466
+549D54D054AD54C254B454D254A754A654D354D4547254A354D554BB54BF54CC
+54D954DA54DC54A954AA54A454DD54CF54DE551B54E7552054FD551454F35522
+5523550F55115527552A5567558F55B55549556D55415555553F5550553C0000
+E0
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00005537555655755576557755335530555C558B55D2558355B155B955885581
+559F557E55D65591557B55DF55BD55BE5594559955EA55F755C9561F55D155EB
+55EC55D455E655DD55C455EF55E555F255F355CC55CD55E855F555E48F94561E
+5608560C56015624562355FE56005627562D565856395657562C564D56625659
+565C564C5654568656645671566B567B567C5685569356AF56D456D756DD56E1
+56F556EB56F956FF5704570A5709571C5E0F5E195E145E115E315E3B5E3C0000
+E1
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00005E375E445E545E5B5E5E5E615C8C5C7A5C8D5C905C965C885C985C995C91
+5C9A5C9C5CB55CA25CBD5CAC5CAB5CB15CA35CC15CB75CC45CD25CE45CCB5CE5
+5D025D035D275D265D2E5D245D1E5D065D1B5D585D3E5D345D3D5D6C5D5B5D6F
+5D5D5D6B5D4B5D4A5D695D745D825D995D9D8C735DB75DC55F735F775F825F87
+5F895F8C5F955F995F9C5FA85FAD5FB55FBC88625F6172AD72B072B472B772B8
+72C372C172CE72CD72D272E872EF72E972F272F472F7730172F3730372FA0000
+E2
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000072FB731773137321730A731E731D7315732273397325732C733873317350
+734D73577360736C736F737E821B592598E7592459029963996799689969996A
+996B996C99749977997D998099849987998A998D999099919993999499955E80
+5E915E8B5E965EA55EA05EB95EB55EBE5EB38D535ED25ED15EDB5EE85EEA81BA
+5FC45FC95FD65FCF60035FEE60045FE15FE45FFE600560065FEA5FED5FF86019
+60356026601B600F600D6029602B600A603F602160786079607B607A60420000
+E3
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000606A607D6096609A60AD609D60836092608C609B60EC60BB60B160DD60D8
+60C660DA60B4612061266115612360F46100610E612B614A617561AC619461A7
+61B761D461F55FDD96B395E995EB95F195F395F595F695FC95FE960396049606
+9608960A960B960C960D960F96129615961696179619961A4E2C723F62156C35
+6C546C5C6C4A6CA36C856C906C946C8C6C686C696C746C766C866CA96CD06CD4
+6CAD6CF76CF86CF16CD76CB26CE06CD66CFA6CEB6CEE6CB16CD36CEF6CFE0000
+E4
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00006D396D276D0C6D436D486D076D046D196D0E6D2B6D4D6D2E6D356D1A6D4F
+6D526D546D336D916D6F6D9E6DA06D5E6D936D946D5C6D606D7C6D636E1A6DC7
+6DC56DDE6E0E6DBF6DE06E116DE66DDD6DD96E166DAB6E0C6DAE6E2B6E6E6E4E
+6E6B6EB26E5F6E866E536E546E326E256E446EDF6EB16E986EE06F2D6EE26EA5
+6EA76EBD6EBB6EB76ED76EB46ECF6E8F6EC26E9F6F626F466F476F246F156EF9
+6F2F6F366F4B6F746F2A6F096F296F896F8D6F8C6F786F726F7C6F7A6FD10000
+E5
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00006FC96FA76FB96FB66FC26FE16FEE6FDE6FE06FEF701A7023701B70397035
+704F705E5B805B845B955B935BA55BB8752F9A9E64345BE45BEE89305BF08E47
+8B078FB68FD38FD58FE58FEE8FE48FE98FE68FF38FE890059004900B90269011
+900D9016902190359036902D902F9044905190529050906890589062905B66B9
+9074907D908290889083908B5F505F575F565F585C3B54AB5C505C595B715C63
+5C667FBC5F2A5F295F2D82745F3C9B3B5C6E59815983598D59A959AA59A30000
+E6
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000599759CA59AB599E59A459D259B259AF59D759BE5A055A0659DD5A0859E3
+59D859F95A0C5A095A325A345A115A235A135A405A675A4A5A555A3C5A625A75
+80EC5AAA5A9B5A775A7A5ABE5AEB5AB25AD25AD45AB85AE05AE35AF15AD65AE6
+5AD85ADC5B095B175B165B325B375B405C155C1C5B5A5B655B735B515B535B62
+9A759A779A789A7A9A7F9A7D9A809A819A859A889A8A9A909A929A939A969A98
+9A9B9A9C9A9D9A9F9AA09AA29AA39AA59AA77E9F7EA17EA37EA57EA87EA90000
+E7
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00007EAD7EB07EBE7EC07EC17EC27EC97ECB7ECC7ED07ED47ED77EDB7EE07EE1
+7EE87EEB7EEE7EEF7EF17EF27F0D7EF67EFA7EFB7EFE7F017F027F037F077F08
+7F0B7F0C7F0F7F117F127F177F197F1C7F1B7F1F7F217F227F237F247F257F26
+7F277F2A7F2B7F2C7F2D7F2F7F307F317F327F337F355E7A757F5DDB753E9095
+738E739173AE73A2739F73CF73C273D173B773B373C073C973C873E573D9987C
+740A73E973E773DE73BA73F2740F742A745B7426742574287430742E742C0000
+E8
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000741B741A7441745C7457745574597477746D747E749C748E748074817487
+748B749E74A874A9749074A774D274BA97EA97EB97EC674C6753675E67486769
+67A56787676A6773679867A7677567A8679E67AD678B6777677C67F0680967D8
+680A67E967B0680C67D967B567DA67B367DD680067C367B867E2680E67C167FD
+6832683368606861684E6862684468646883681D68556866684168676840683E
+684A6849682968B5688F687468776893686B68C2696E68FC691F692068F90000
+E9
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000692468F0690B6901695768E369106971693969606942695D6984696B6980
+69986978693469CC6987698869CE6989696669636979699B69A769BB69AB69AD
+69D469B169C169CA69DF699569E0698D69FF6A2F69ED6A176A186A6569F26A44
+6A3E6AA06A506A5B6A356A8E6A796A3D6A286A586A7C6A916A906AA96A976AAB
+733773526B816B826B876B846B926B936B8D6B9A6B9B6BA16BAA8F6B8F6D8F71
+8F728F738F758F768F788F778F798F7A8F7C8F7E8F818F828F848F878F8B0000
+EA
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00008F8D8F8E8F8F8F988F9A8ECE620B6217621B621F6222622162256224622C
+81E774EF74F474FF750F75117513653465EE65EF65F0660A6619677266036615
+6600708566F7661D66346631663666358006665F66546641664F665666616657
+66776684668C66A7669D66BE66DB66DC66E666E98D328D338D368D3B8D3D8D40
+8D458D468D488D498D478D4D8D558D5989C789CA89CB89CC89CE89CF89D089D1
+726E729F725D7266726F727E727F7284728B728D728F72926308633263B00000
+EB
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000643F64D880046BEA6BF36BFD6BF56BF96C056C076C066C0D6C156C186C19
+6C1A6C216C296C246C2A6C3265356555656B724D72527256723086625216809F
+809C809380BC670A80BD80B180AB80AD80B480B780E780E880E980EA80DB80C2
+80C480D980CD80D7671080DD80EB80F180F480ED810D810E80F280FC67158112
+8C5A8136811E812C811881328148814C815381748159815A817181608169817C
+817D816D8167584D5AB58188818281916ED581A381AA81CC672681CA81BB0000
+EC
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000081C181A66B246B376B396B436B466B5998D198D298D398D598D998DA6BB3
+5F406BC289F365909F51659365BC65C665C465C365CC65CE65D265D67080709C
+7096709D70BB70C070B770AB70B170E870CA711071137116712F71317173715C
+716871457172714A7178717A719871B371B571A871A071E071D471E771F9721D
+7228706C7118716671B9623E623D624362486249793B794079467949795B795C
+7953795A796279577960796F7967797A7985798A799A79A779B35FD15FD00000
+ED
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000603C605D605A606760416059606360AB6106610D615D61A9619D61CB61D1
+62068080807F6C936CF66DFC77F677F87800780978177818781165AB782D781C
+781D7839783A783B781F783C7825782C78237829784E786D7856785778267850
+7847784C786A789B7893789A7887789C78A178A378B278B978A578D478D978C9
+78EC78F2790578F479137924791E79349F9B9EF99EFB9EFC76F17704770D76F9
+77077708771A77227719772D7726773577387750775177477743775A77680000
+EE
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000077627765777F778D777D7780778C7791779F77A077B077B577BD753A7540
+754E754B7548755B7572757975837F587F617F5F8A487F687F747F717F797F81
+7F7E76CD76E58832948594869487948B948A948C948D948F9490949494979495
+949A949B949C94A394A494AB94AA94AD94AC94AF94B094B294B494B694B794B8
+94B994BA94BC94BD94BF94C494C894C994CA94CB94CC94CD94CE94D094D194D2
+94D594D694D794D994D894DB94DE94DF94E094E294E494E594E794E894EA0000
+EF
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000094E994EB94EE94EF94F394F494F594F794F994FC94FD94FF950395029506
+95079509950A950D950E950F951295139514951595169518951B951D951E951F
+9522952A952B9529952C953195329534953695379538953C953E953F95429535
+9544954595469549954C954E954F9552955395549556955795589559955B955E
+955F955D95619562956495659566956795689569956A956B956C956F95719572
+9573953A77E777EC96C979D579ED79E379EB7A065D477A037A027A1E7A140000
+F0
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00007A397A377A519ECF99A57A707688768E7693769976A474DE74E0752C9E20
+9E229E289E299E2A9E2B9E2C9E329E319E369E389E379E399E3A9E3E9E419E42
+9E449E469E479E489E499E4B9E4C9E4E9E519E559E579E5A9E5B9E5C9E5E9E63
+9E669E679E689E699E6A9E6B9E6C9E719E6D9E7375927594759675A0759D75AC
+75A375B375B475B875C475B175B075C375C275D675CD75E375E875E675E475EB
+75E7760375F175FC75FF761076007605760C7617760A76257618761576190000
+F1
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000761B763C762276207640762D7630763F76357643763E7633764D765E7654
+765C7656766B766F7FCA7AE67A787A797A807A867A887A957AA67AA07AAC7AA8
+7AAD7AB3886488698872887D887F888288A288C688B788BC88C988E288CE88E3
+88E588F1891A88FC88E888FE88F0892189198913891B890A8934892B89368941
+8966897B758B80E576B276B477DC801280148016801C80208022802580268027
+802980288031800B803580438046804D80528069807189839878988098830000
+F2
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00009889988C988D988F9894989A989B989E989F98A198A298A598A6864D8654
+866C866E867F867A867C867B86A8868D868B86AC869D86A786A386AA869386A9
+86B686C486B586CE86B086BA86B186AF86C986CF86B486E986F186F286ED86F3
+86D0871386DE86F486DF86D886D18703870786F88708870A870D87098723873B
+871E8725872E871A873E87488734873187298737873F87828722877D877E877B
+87608770874C876E878B87538763877C876487598765879387AF87A887D20000
+F3
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000087C68788878587AD8797878387AB87E587AC87B587B387CB87D387BD87D1
+87C087CA87DB87EA87E087EE8816881387FE880A881B88218839883C7F367F42
+7F447F4582107AFA7AFD7B087B037B047B157B0A7B2B7B0F7B477B387B2A7B19
+7B2E7B317B207B257B247B337B3E7B1E7B587B5A7B457B757B4C7B5D7B607B6E
+7B7B7B627B727B717B907BA67BA77BB87BAC7B9D7BA87B857BAA7B9C7BA27BAB
+7BB47BD17BC17BCC7BDD7BDA7BE57BE67BEA7C0C7BFE7BFC7C0F7C167C0B0000
+F4
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00007C1F7C2A7C267C387C417C4081FE82018202820481EC8844822182228223
+822D822F8228822B8238823B82338234823E82448249824B824F825A825F8268
+887E8885888888D888DF895E7F9D7F9F7FA77FAF7FB07FB27C7C65497C917C9D
+7C9C7C9E7CA27CB27CBC7CBD7CC17CC77CCC7CCD7CC87CC57CD77CE8826E66A8
+7FBF7FCE7FD57FE57FE17FE67FE97FEE7FF37CF87D777DA67DAE7E477E9B9EB8
+9EB48D738D848D948D918DB18D678D6D8C478C49914A9150914E914F91640000
+F5
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00009162916191709169916F917D917E917291749179918C91859190918D9191
+91A291A391AA91AD91AE91AF91B591B491BA8C559E7E8DB88DEB8E058E598E69
+8DB58DBF8DBC8DBA8DC48DD68DD78DDA8DDE8DCE8DCF8DDB8DC68DEC8DF78DF8
+8DE38DF98DFB8DE48E098DFD8E148E1D8E1F8E2C8E2E8E238E2F8E3A8E408E39
+8E358E3D8E318E498E418E428E518E528E4A8E708E768E7C8E6F8E748E858E8F
+8E948E908E9C8E9E8C788C828C8A8C858C988C94659B89D689DE89DA89DC0000
+F6
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000089E589EB89EF8A3E8B26975396E996F396EF970697019708970F970E972A
+972D9730973E9F809F839F859F869F879F889F899F8A9F8C9EFE9F0B9F0D96B9
+96BC96BD96CE96D277BF96E0928E92AE92C8933E936A93CA938F943E946B9C7F
+9C829C859C869C879C887A239C8B9C8E9C909C919C929C949C959C9A9C9B9C9E
+9C9F9CA09CA19CA29CA39CA59CA69CA79CA89CA99CAB9CAD9CAE9CB09CB19CB2
+9CB39CB49CB59CB69CB79CBA9CBB9CBC9CBD9CC49CC59CC69CC79CCA9CCB0000
+F7
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00009CCC9CCD9CCE9CCF9CD09CD39CD49CD59CD79CD89CD99CDC9CDD9CDF9CE2
+977C978597919792979497AF97AB97A397B297B49AB19AB09AB79E589AB69ABA
+9ABC9AC19AC09AC59AC29ACB9ACC9AD19B459B439B479B499B489B4D9B5198E8
+990D992E995599549ADF9AE19AE69AEF9AEB9AFB9AED9AF99B089B0F9B139B1F
+9B239EBD9EBE7E3B9E829E879E889E8B9E9293D69E9D9E9F9EDB9EDC9EDD9EE0
+9EDF9EE29EE99EE79EE59EEA9EEF9F229F2C9F2F9F399F379F3D9F3E9F440000
diff --git a/library/encoding/euc-jp.enc b/library/encoding/euc-jp.enc
new file mode 100644
index 0000000..db56c88
--- /dev/null
+++ b/library/encoding/euc-jp.enc
@@ -0,0 +1,1353 @@
+# Encoding file: euc-jp, multi-byte
+M
+003F 0 79
+00
+0000000100020003000400050006000700080009000A000B000C000D000E000F
+0010001100120013001400150016001700180019001A001B001C001D001E001F
+0020002100220023002400250026002700280029002A002B002C002D002E002F
+0030003100320033003400350036003700380039003A003B003C003D003E003F
+0040004100420043004400450046004700480049004A004B004C004D004E004F
+0050005100520053005400550056005700580059005A005B005C005D005E005F
+0060006100620063006400650066006700680069006A006B006C006D006E006F
+0070007100720073007400750076007700780079007A007B007C007D007E007F
+0080008100820083008400850086008700880089008A008B008C008D0000008F
+0090009100920093009400950096009700980099009A009B009C009D009E009F
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+8E
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000FF61FF62FF63FF64FF65FF66FF67FF68FF69FF6AFF6BFF6CFF6DFF6EFF6F
+FF70FF71FF72FF73FF74FF75FF76FF77FF78FF79FF7AFF7BFF7CFF7DFF7EFF7F
+FF80FF81FF82FF83FF84FF85FF86FF87FF88FF89FF8AFF8BFF8CFF8DFF8EFF8F
+FF90FF91FF92FF93FF94FF95FF96FF97FF98FF99FF9AFF9BFF9CFF9DFF9EFF9F
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+A1
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000300030013002FF0CFF0E30FBFF1AFF1BFF1FFF01309B309C00B4FF4000A8
+FF3EFFE3FF3F30FD30FE309D309E30034EDD30053006300730FC20152010FF0F
+FF3C301C2016FF5C2026202520182019201C201DFF08FF0930143015FF3BFF3D
+FF5BFF5D30083009300A300B300C300D300E300F30103011FF0B221200B100D7
+00F7FF1D2260FF1CFF1E22662267221E22342642264000B0203220332103FFE5
+FF0400A200A3FF05FF03FF06FF0AFF2000A72606260525CB25CF25CE25C70000
+A2
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000025C625A125A025B325B225BD25BC203B3012219221902191219330130000
+00000000000000000000000000000000000000002208220B2286228722822283
+222A2229000000000000000000000000000000002227222800AC21D221D42200
+220300000000000000000000000000000000000000000000222022A523122202
+220722612252226A226B221A223D221D2235222B222C00000000000000000000
+00000000212B2030266F266D266A2020202100B6000000000000000025EF0000
+A3
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+FF10FF11FF12FF13FF14FF15FF16FF17FF18FF19000000000000000000000000
+0000FF21FF22FF23FF24FF25FF26FF27FF28FF29FF2AFF2BFF2CFF2DFF2EFF2F
+FF30FF31FF32FF33FF34FF35FF36FF37FF38FF39FF3A00000000000000000000
+0000FF41FF42FF43FF44FF45FF46FF47FF48FF49FF4AFF4BFF4CFF4DFF4EFF4F
+FF50FF51FF52FF53FF54FF55FF56FF57FF58FF59FF5A00000000000000000000
+A4
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000304130423043304430453046304730483049304A304B304C304D304E304F
+3050305130523053305430553056305730583059305A305B305C305D305E305F
+3060306130623063306430653066306730683069306A306B306C306D306E306F
+3070307130723073307430753076307730783079307A307B307C307D307E307F
+3080308130823083308430853086308730883089308A308B308C308D308E308F
+3090309130923093000000000000000000000000000000000000000000000000
+A5
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000030A130A230A330A430A530A630A730A830A930AA30AB30AC30AD30AE30AF
+30B030B130B230B330B430B530B630B730B830B930BA30BB30BC30BD30BE30BF
+30C030C130C230C330C430C530C630C730C830C930CA30CB30CC30CD30CE30CF
+30D030D130D230D330D430D530D630D730D830D930DA30DB30DC30DD30DE30DF
+30E030E130E230E330E430E530E630E730E830E930EA30EB30EC30ED30EE30EF
+30F030F130F230F330F430F530F6000000000000000000000000000000000000
+A6
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000039103920393039403950396039703980399039A039B039C039D039E039F
+03A003A103A303A403A503A603A703A803A90000000000000000000000000000
+000003B103B203B303B403B503B603B703B803B903BA03BB03BC03BD03BE03BF
+03C003C103C303C403C503C603C703C803C90000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+A7
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000004100411041204130414041504010416041704180419041A041B041C041D
+041E041F0420042104220423042404250426042704280429042A042B042C042D
+042E042F00000000000000000000000000000000000000000000000000000000
+000004300431043204330434043504510436043704380439043A043B043C043D
+043E043F0440044104420443044404450446044704480449044A044B044C044D
+044E044F00000000000000000000000000000000000000000000000000000000
+A8
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000025002502250C251025182514251C252C25242534253C25012503250F2513
+251B251725232533252B253B254B2520252F25282537253F251D253025252538
+2542000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+B0
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00004E9C55165A03963F54C0611B632859F690228475831C7A5060AA63E16E25
+65ED846682A69BF56893572765A162715B9B59D0867B98F47D627DBE9B8E6216
+7C9F88B75B895EB563096697684895C7978D674F4EE54F0A4F4D4F9D504956F2
+593759D45A015C0960DF610F61706613690570BA754F757079FB7DAD7DEF80C3
+840E88638B029055907A533B4E954EA557DF80B290C178EF4E0058F16EA29038
+7A328328828B9C2F5141537054BD54E156E059FB5F1598F26DEB80E4852D0000
+B1
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00009662967096A097FB540B53F35B8770CF7FBD8FC296E8536F9D5C7ABA4E11
+789381FC6E26561855046B1D851A9C3B59E553A96D6674DC958F56424E91904B
+96F2834F990C53E155B65B305F71662066F368046C386CF36D29745B76C87A4E
+983482F1885B8A6092ED6DB275AB76CA99C560A68B018D8A95B2698E53AD5186
+5712583059445BB45EF6602863A963F46CBF6F14708E7114715971D5733F7E01
+827682D185979060925B9D1B586965BC6C5A752551F9592E59655F805FDC0000
+B2
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000062BC65FA6A2A6B276BB4738B7FC189569D2C9D0E9EC45CA16C96837B5104
+5C4B61B681C6687672614E594FFA537860696E297A4F97F34E0B53164EEE4F55
+4F3D4FA14F7352A053EF5609590F5AC15BB65BE179D16687679C67B66B4C6CB3
+706B73C2798D79BE7A3C7B8782B182DB8304837783EF83D387668AB256298CA8
+8FE6904E971E868A4FC45CE862117259753B81E582BD86FE8CC096C5991399D5
+4ECB4F1A89E356DE584A58CA5EFB5FEB602A6094606261D0621262D065390000
+B3
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00009B41666668B06D777070754C76867D7582A587F9958B968E8C9D51F152BE
+591654B35BB35D16616869826DAF788D84CB88578A7293A79AB86D6C99A886D9
+57A367FF86CE920E5283568754045ED362E164B9683C68386BBB737278BA7A6B
+899A89D28D6B8F0390ED95A3969497695B665CB3697D984D984E639B7B206A2B
+6A7F68B69C0D6F5F5272559D607062EC6D3B6E076ED1845B89108F444E149C39
+53F6691B6A3A9784682A515C7AC384B291DC938C565B9D286822830584310000
+B4
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00007CA5520882C574E64E7E4F8351A05BD2520A52D852E75DFB559A582A59E6
+5B8C5B985BDB5E725E7960A3611F616361BE63DB656267D1685368FA6B3E6B53
+6C576F226F976F4574B0751876E3770B7AFF7BA17C217DE97F367FF0809D8266
+839E89B38ACC8CAB908494519593959195A2966597D3992882184E38542B5CB8
+5DCC73A9764C773C5CA97FEB8D0B96C19811985498584F014F0E5371559C5668
+57FA59475B095BC45C905E0C5E7E5FCC63EE673A65D765E2671F68CB68C40000
+B5
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00006A5F5E306BC56C176C7D757F79485B637A007D005FBD898F8A188CB48D77
+8ECC8F1D98E29A0E9B3C4E80507D510059935B9C622F628064EC6B3A72A07591
+79477FA987FB8ABC8B7063AC83CA97A05409540355AB68546A588A7078276775
+9ECD53745BA2811A865090064E184E454EC74F1153CA54385BAE5F1360256551
+673D6C426C726CE3707874037A767AAE7B087D1A7CFE7D6665E7725B53BB5C45
+5DE862D262E063196E20865A8A318DDD92F86F0179A69B5A4EA84EAB4EAC0000
+B6
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00004F9B4FA050D151477AF6517151F653545321537F53EB55AC58835CE15F37
+5F4A602F6050606D631F65596A4B6CC172C272ED77EF80F881058208854E90F7
+93E197FF99579A5A4EF051DD5C2D6681696D5C4066F26975738968507C8150C5
+52E457475DFE932665A46B236B3D7434798179BD7B4B7DCA82B983CC887F895F
+8B398FD191D1541F92804E5D503653E5533A72D7739677E982E68EAF99C699C8
+99D25177611A865E55B07A7A50765BD3904796854E326ADB91E75C515C480000
+B7
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000063987A9F6C9397748F617AAA718A96887C8268177E706851936C52F2541B
+85AB8A137FA48ECD90E15366888879414FC250BE521151445553572D73EA578B
+59515F625F8460756176616761A963B2643A656C666F68426E1375667A3D7CFB
+7D4C7D997E4B7F6B830E834A86CD8A088A638B668EFD981A9D8F82B88FCE9BE8
+5287621F64836FC09699684150916B206C7A6F547A747D5088408A2367084EF6
+503950265065517C5238526355A7570F58055ACC5EFA61B261F862F363720000
+B8
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000691C6A29727D72AC732E7814786F7D79770C80A9898B8B198CE28ED29063
+9375967A98559A139E785143539F53B35E7B5F266E1B6E90738473FE7D438237
+8A008AFA96504E4E500B53E4547C56FA59D15B645DF15EAB5F276238654567AF
+6E5672D07CCA88B480A180E183F0864E8A878DE8923796C798679F134E944E92
+4F0D53485449543E5A2F5F8C5FA1609F68A76A8E745A78818A9E8AA48B779190
+4E5E9BC94EA44F7C4FAF501950165149516C529F52B952FE539A53E354110000
+B9
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000540E5589575157A2597D5B545B5D5B8F5DE55DE75DF75E785E835E9A5EB7
+5F186052614C629762D863A7653B6602664366F4676D6821689769CB6C5F6D2A
+6D696E2F6E9D75327687786C7A3F7CE07D057D187D5E7DB18015800380AF80B1
+8154818F822A8352884C88618B1B8CA28CFC90CA91759271783F92FC95A4964D
+980599999AD89D3B525B52AB53F7540858D562F76FE08C6A8F5F9EB9514B523B
+544A56FD7A4091779D609ED273446F09817075115FFD60DA9AA872DB8FBC0000
+BA
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00006B6498034ECA56F0576458BE5A5A606861C7660F6606683968B16DF775D5
+7D3A826E9B424E9B4F5053C955065D6F5DE65DEE67FB6C99747378028A509396
+88DF57505EA7632B50B550AC518D670054C9585E59BB5BB05F69624D63A1683D
+6B736E08707D91C7728078157826796D658E7D3083DC88C18F09969B52645728
+67507F6A8CA151B45742962A583A698A80B454B25D0E57FC78959DFA4F5C524A
+548B643E6628671467F57A847B567D22932F685C9BAD7B395319518A52370000
+BB
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00005BDF62F664AE64E6672D6BBA85A996D176909BD6634C93069BAB76BF6652
+4E09509853C25C7160E864926563685F71E673CA75237B977E8286958B838CDB
+9178991065AC66AB6B8B4ED54ED44F3A4F7F523A53F853F255E356DB58EB59CB
+59C959FF5B505C4D5E025E2B5FD7601D6307652F5B5C65AF65BD65E8679D6B62
+6B7B6C0F7345794979C17CF87D197D2B80A2810281F389968A5E8A698A668A8C
+8AEE8CC78CDC96CC98FC6B6F4E8B4F3C4F8D51505B575BFA6148630166420000
+BC
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00006B216ECB6CBB723E74BD75D478C1793A800C803381EA84948F9E6C509E7F
+5F0F8B589D2B7AFA8EF85B8D96EB4E0353F157F759315AC95BA460896E7F6F06
+75BE8CEA5B9F85007BE0507267F4829D5C61854A7E1E820E51995C0463688D66
+659C716E793E7D1780058B1D8ECA906E86C790AA501F52FA5C3A6753707C7235
+914C91C8932B82E55BC25F3160F94E3B53D65B88624B67316B8A72E973E07A2E
+816B8DA391529996511253D7546A5BFF63886A397DAC970056DA53CE54680000
+BD
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00005B975C315DDE4FEE610162FE6D3279C079CB7D427E4D7FD281ED821F8490
+884689728B908E748F2F9031914B916C96C6919C4EC04F4F514553415F93620E
+67D46C416E0B73637E2691CD928353D459195BBF6DD1795D7E2E7C9B587E719F
+51FA88538FF04FCA5CFB662577AC7AE3821C99FF51C65FAA65EC696F6B896DF3
+6E966F6476FE7D145DE190759187980651E6521D6240669166D96E1A5EB67DD2
+7F7266F885AF85F78AF852A953D959735E8F5F90605592E4966450B7511F0000
+BE
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000052DD5320534753EC54E8554655315617596859BE5A3C5BB55C065C0F5C11
+5C1A5E845E8A5EE05F70627F628462DB638C63776607660C662D6676677E68A2
+6A1F6A356CBC6D886E096E58713C7126716775C77701785D7901796579F07AE0
+7B117CA77D39809683D6848B8549885D88F38A1F8A3C8A548A738C618CDE91A4
+9266937E9418969C97984E0A4E084E1E4E575197527057CE583458CC5B225E38
+60C564FE676167566D4472B675737A6384B88B7291B89320563157F498FE0000
+BF
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000062ED690D6B9671ED7E548077827289E698DF87558FB15C3B4F384FE14FB5
+55075A205BDD5BE95FC3614E632F65B0664B68EE699B6D786DF1753375B9771F
+795E79E67D3381E382AF85AA89AA8A3A8EAB8F9B903291DD97074EBA4EC15203
+587558EC5C0B751A5C3D814E8A0A8FC59663976D7B258ACF9808916256F353A8
+9017543957825E2563A86C34708A77617C8B7FE088709042915493109318968F
+745E9AC45D075D69657067A28DA896DB636E6749691983C5981796C088FE0000
+C0
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00006F84647A5BF84E16702C755D662F51C4523652E259D35F8160276210653F
+6574661F667468F268166B636E057272751F76DB7CBE805658F088FD897F8AA0
+8A938ACB901D91929752975965897A0E810696BB5E2D60DC621A65A566146790
+77F37A4D7C4D7E3E810A8CAC8D648DE18E5F78A9520762D963A5644262988A2D
+7A837BC08AAC96EA7D76820C87494ED95148534353605BA35C025C165DDD6226
+624764B0681368346CC96D456D1767D36F5C714E717D65CB7A7F7BAD7DDA0000
+C1
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00007E4A7FA8817A821B823985A68A6E8CCE8DF59078907792AD929195839BAE
+524D55846F387136516879857E5581B37CCE564C58515CA863AA66FE66FD695A
+72D9758F758E790E795679DF7C977D207D4486078A34963B90619F2050E75275
+53CC53E2500955AA58EE594F723D5B8B5C64531D60E360F3635C6383633F63BB
+64CD65E966F95DE369CD69FD6F1571E54E8975E976F87A937CDF7DCF7D9C8061
+83498358846C84BC85FB88C58D709001906D9397971C9A1250CF5897618E0000
+C2
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000081D385358D0890204FC3507452475373606F6349675F6E2C8DB3901F4FD7
+5C5E8CCA65CF7D9A53528896517663C35B585B6B5C0A640D6751905C4ED6591A
+592A6C708A51553E581559A560F0625367C182356955964099C49A284F535806
+5BFE80105CB15E2F5F856020614B623466FF6CF06EDE80CE817F82D4888B8CB8
+9000902E968A9EDB9BDB4EE353F059277B2C918D984C9DF96EDD702753535544
+5B856258629E62D36CA26FEF74228A1794386FC18AFE833851E786F853EA0000
+C3
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000053E94F4690548FB0596A81315DFD7AEA8FBF68DA8C3772F89C486A3D8AB0
+4E3953585606576662C563A265E66B4E6DE16E5B70AD77ED7AEF7BAA7DBB803D
+80C686CB8A95935B56E358C75F3E65AD66966A806BB575378AC7502477E55730
+5F1B6065667A6C6075F47A1A7F6E81F48718904599B37BC9755C7AF97B5184C4
+901079E97A9283365AE177404E2D4EF25B995FE062BD663C67F16CE8866B8877
+8A3B914E92F399D06A177026732A82E784578CAF4E01514651CB558B5BF50000
+C4
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00005E165E335E815F145F355F6B5FB461F2631166A2671D6F6E7252753A773A
+80748139817887768ABF8ADC8D858DF3929A957798029CE552C5635776F46715
+6C8873CD8CC393AE96736D25589C690E69CC8FFD939A75DB901A585A680263B4
+69FB4F436F2C67D88FBB85267DB49354693F6F70576A58F75B2C7D2C722A540A
+91E39DB44EAD4F4E505C507552438C9E544858245B9A5E1D5E955EAD5EF75F1F
+608C62B5633A63D068AF6C407887798E7A0B7DE082478A028AE68E4490130000
+C5
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000090B8912D91D89F0E6CE5645864E265756EF476847B1B906993D16EBA54F2
+5FB964A48F4D8FED92445178586B59295C555E976DFB7E8F751C8CBC8EE2985B
+70B94F1D6BBF6FB1753096FB514E54105835585759AC5C605F926597675C6E21
+767B83DF8CED901490FD934D7825783A52AA5EA6571F597460125012515A51AC
+51CD520055105854585859575B955CF65D8B60BC6295642D6771684368BC68DF
+76D76DD86E6F6D9B706F71C85F5375D879777B497B547B527CD67D7152300000
+C6
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00008463856985E48A0E8B048C468E0F9003900F94199676982D9A3095D850CD
+52D5540C58025C0E61A7649E6D1E77B37AE580F48404905392855CE09D07533F
+5F975FB36D9C7279776379BF7BE46BD272EC8AAD68036A6151F87A8169345C4A
+9CF682EB5BC59149701E56785C6F60C765666C8C8C5A90419813545166C7920D
+594890A351854E4D51EA85998B0E7058637A934B696299B47E04757753576960
+8EDF96E36C5D4E8C5C3C5F108FE953028CD1808986795EFF65E54E7351650000
+C7
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000059825C3F97EE4EFB598A5FCD8A8D6FE179B079625BE78471732B71B15E74
+5FF5637B649A71C37C984E435EFC4E4B57DC56A260A96FC37D0D80FD813381BF
+8FB2899786A45DF4628A64AD898767776CE26D3E743678345A467F7582AD99AC
+4FF35EC362DD63926557676F76C3724C80CC80BA8F29914D500D57F95A926885
+6973716472FD8CB758F28CE0966A9019877F79E477E784294F2F5265535A62CD
+67CF6CCA767D7B947C95823685848FEB66DD6F2072067E1B83AB99C19EA60000
+C8
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000051FD7BB178727BB880877B486AE85E61808C75517560516B92626E8C767A
+91979AEA4F107F70629C7B4F95A59CE9567A585986E496BC4F345224534A53CD
+53DB5E06642C6591677F6C3E6C4E724872AF73ED75547E41822C85E98CA97BC4
+91C67169981298EF633D6669756A76E478D0854386EE532A5351542659835E87
+5F7C60B26249627962AB65906BD46CCC75B276AE789179D87DCB7F7780A588AB
+8AB98CBB907F975E98DB6A0B7C3850995C3E5FAE67876BD8743577097F8E0000
+C9
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00009F3B67CA7A175339758B9AED5F66819D83F180985F3C5FC575627B46903C
+686759EB5A9B7D10767E8B2C4FF55F6A6A196C376F0274E2796888688A558C79
+5EDF63CF75C579D282D7932892F2849C86ED9C2D54C15F6C658C6D5C70158CA7
+8CD3983B654F74F64E0D4ED857E0592B5A665BCC51A85E035E9C601662766577
+65A7666E6D6E72367B268150819A82998B5C8CA08CE68D74961C96444FAE64AB
+6B66821E8461856A90E85C01695398A8847A85574F0F526F5FA95E45670D0000
+CA
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000798F8179890789866DF55F1762556CB84ECF72699B925206543B567458B3
+61A4626E711A596E7C897CDE7D1B96F06587805E4E194F75517558405E635E73
+5F0A67C44E26853D9589965B7C73980150FB58C1765678A7522577A585117B86
+504F590972477BC77DE88FBA8FD4904D4FBF52C95A295F0197AD4FDD821792EA
+570363556B69752B88DC8F147A4252DF58936155620A66AE6BCD7C3F83E95023
+4FF853055446583159495B9D5CF05CEF5D295E9662B16367653E65B9670B0000
+CB
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00006CD56CE170F978327E2B80DE82B3840C84EC870289128A2A8C4A90A692D2
+98FD9CF39D6C4E4F4EA1508D5256574A59A85E3D5FD85FD9623F66B4671B67D0
+68D251927D2180AA81A88B008C8C8CBF927E96325420982C531750D5535C58A8
+64B26734726777667A4691E652C36CA16B8658005E4C5954672C7FFB51E176C6
+646978E89B549EBB57CB59B96627679A6BCE54E969D95E55819C67959BAA67FE
+9C52685D4EA64FE353C862B9672B6CAB8FC44FAD7E6D9EBF4E0761626E800000
+CC
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00006F2B85135473672A9B455DF37B955CAC5BC6871C6E4A84D17A1481085999
+7C8D6C11772052D959227121725F77DB97279D61690B5A7F5A1851A5540D547D
+660E76DF8FF792989CF459EA725D6EC5514D68C97DBF7DEC97629EBA64786A21
+830259845B5F6BDB731B76F27DB280178499513267289ED976EE676252FF9905
+5C24623B7C7E8CB0554F60B67D0B958053014E5F51B6591C723A803691CE5F25
+77E253845F797D0485AC8A338E8D975667F385AE9453610961086CB976520000
+CD
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00008AED8F38552F4F51512A52C753CB5BA55E7D60A0618263D6670967DA6E67
+6D8C733673377531795088D58A98904A909190F596C4878D59154E884F594E0E
+8A898F3F981050AD5E7C59965BB95EB863DA63FA64C166DC694A69D86D0B6EB6
+719475287AAF7F8A8000844984C989818B218E0A9065967D990A617E62916B32
+6C836D747FCC7FFC6DC07F8587BA88F8676583B1983C96F76D1B7D61843D916A
+4E7153755D506B046FEB85CD862D89A75229540F5C65674E68A8740674830000
+CE
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000075E288CF88E191CC96E296785F8B73877ACB844E63A0756552896D416E9C
+74097559786B7C9296867ADC9F8D4FB6616E65C5865C4E864EAE50DA4E2151CC
+5BEE659968816DBC731F764277AD7A1C7CE7826F8AD2907C91CF96759818529B
+7DD1502B539867976DCB71D0743381E88F2A96A39C579E9F746058416D997D2F
+985E4EE44F364F8B51B752B15DBA601C73B2793C82D3923496B796F6970A9E97
+9F6266A66B74521752A370C888C25EC9604B61906F2371497C3E7DF4806F0000
+CF
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000084EE9023932C54429B6F6AD370898CC28DEF973252B45A415ECA5F046717
+697C69946D6A6F0F726272FC7BED8001807E874B90CE516D9E937984808B9332
+8AD6502D548C8A716B6A8CC4810760D167A09DF24E994E989C108A6B85C18568
+69006E7E78978155000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+D0
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00005F0C4E104E154E2A4E314E364E3C4E3F4E424E564E584E824E858C6B4E8A
+82125F0D4E8E4E9E4E9F4EA04EA24EB04EB34EB64ECE4ECD4EC44EC64EC24ED7
+4EDE4EED4EDF4EF74F094F5A4F304F5B4F5D4F574F474F764F884F8F4F984F7B
+4F694F704F914F6F4F864F9651184FD44FDF4FCE4FD84FDB4FD14FDA4FD04FE4
+4FE5501A50285014502A502550054F1C4FF650215029502C4FFE4FEF50115006
+504350476703505550505048505A5056506C50785080509A508550B450B20000
+D1
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000050C950CA50B350C250D650DE50E550ED50E350EE50F950F5510951015102
+511651155114511A5121513A5137513C513B513F51405152514C515451627AF8
+5169516A516E5180518256D8518C5189518F519151935195519651A451A651A2
+51A951AA51AB51B351B151B251B051B551BD51C551C951DB51E0865551E951ED
+51F051F551FE5204520B5214520E5227522A522E52335239524F5244524B524C
+525E5254526A527452695273527F527D528D529452925271528852918FA80000
+D2
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00008FA752AC52AD52BC52B552C152CD52D752DE52E352E698ED52E052F352F5
+52F852F9530653087538530D5310530F5315531A5323532F5331533353385340
+534653454E175349534D51D6535E5369536E5918537B53775382539653A053A6
+53A553AE53B053B653C37C1296D953DF66FC71EE53EE53E853ED53FA5401543D
+5440542C542D543C542E54365429541D544E548F5475548E545F547154775470
+5492547B5480547654845490548654C754A254B854A554AC54C454C854A80000
+D3
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000054AB54C254A454BE54BC54D854E554E6550F551454FD54EE54ED54FA54E2
+553955405563554C552E555C55455556555755385533555D5599558054AF558A
+559F557B557E5598559E55AE557C558355A9558755A855DA55C555DF55C455DC
+55E455D4561455F7561655FE55FD561B55F9564E565071DF5634563656325638
+566B5664562F566C566A56865680568A56A05694568F56A556AE56B656B456C2
+56BC56C156C356C056C856CE56D156D356D756EE56F9570056FF570457090000
+D4
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00005708570B570D57135718571655C7571C572657375738574E573B5740574F
+576957C057885761577F5789579357A057B357A457AA57B057C357C657D457D2
+57D3580A57D657E3580B5819581D587258215862584B58706BC05852583D5879
+588558B9589F58AB58BA58DE58BB58B858AE58C558D358D158D758D958D858E5
+58DC58E458DF58EF58FA58F958FB58FC58FD5902590A5910591B68A65925592C
+592D59325938593E7AD259555950594E595A5958596259605967596C59690000
+D5
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000059785981599D4F5E4FAB59A359B259C659E859DC598D59D959DA5A255A1F
+5A115A1C5A095A1A5A405A6C5A495A355A365A625A6A5A9A5ABC5ABE5ACB5AC2
+5ABD5AE35AD75AE65AE95AD65AFA5AFB5B0C5B0B5B165B325AD05B2A5B365B3E
+5B435B455B405B515B555B5A5B5B5B655B695B705B735B755B7865885B7A5B80
+5B835BA65BB85BC35BC75BC95BD45BD05BE45BE65BE25BDE5BE55BEB5BF05BF6
+5BF35C055C075C085C0D5C135C205C225C285C385C395C415C465C4E5C530000
+D6
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00005C505C4F5B715C6C5C6E4E625C765C795C8C5C915C94599B5CAB5CBB5CB6
+5CBC5CB75CC55CBE5CC75CD95CE95CFD5CFA5CED5D8C5CEA5D0B5D155D175D5C
+5D1F5D1B5D115D145D225D1A5D195D185D4C5D525D4E5D4B5D6C5D735D765D87
+5D845D825DA25D9D5DAC5DAE5DBD5D905DB75DBC5DC95DCD5DD35DD25DD65DDB
+5DEB5DF25DF55E0B5E1A5E195E115E1B5E365E375E445E435E405E4E5E575E54
+5E5F5E625E645E475E755E765E7A9EBC5E7F5EA05EC15EC25EC85ED05ECF0000
+D7
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00005ED65EE35EDD5EDA5EDB5EE25EE15EE85EE95EEC5EF15EF35EF05EF45EF8
+5EFE5F035F095F5D5F5C5F0B5F115F165F295F2D5F385F415F485F4C5F4E5F2F
+5F515F565F575F595F615F6D5F735F775F835F825F7F5F8A5F885F915F875F9E
+5F995F985FA05FA85FAD5FBC5FD65FFB5FE45FF85FF15FDD60B35FFF60216060
+601960106029600E6031601B6015602B6026600F603A605A6041606A6077605F
+604A6046604D6063604360646042606C606B60596081608D60E76083609A0000
+D8
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00006084609B60966097609260A7608B60E160B860E060D360B45FF060BD60C6
+60B560D8614D6115610660F660F7610060F460FA6103612160FB60F1610D610E
+6147613E61286127614A613F613C612C6134613D614261446173617761586159
+615A616B6174616F61656171615F615D6153617561996196618761AC6194619A
+618A619161AB61AE61CC61CA61C961F761C861C361C661BA61CB7F7961CD61E6
+61E361F661FA61F461FF61FD61FC61FE620062086209620D620C6214621B0000
+D9
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000621E6221622A622E6230623262336241624E625E6263625B62606268627C
+62826289627E62926293629662D46283629462D762D162BB62CF62FF62C664D4
+62C862DC62CC62CA62C262C7629B62C9630C62EE62F163276302630862EF62F5
+6350633E634D641C634F6396638E638063AB637663A3638F6389639F63B5636B
+636963BE63E963C063C663E363C963D263F663C4641664346406641364266436
+651D64176428640F6467646F6476644E652A6495649364A564A9648864BC0000
+DA
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000064DA64D264C564C764BB64D864C264F164E7820964E064E162AC64E364EF
+652C64F664F464F264FA650064FD6518651C650565246523652B653465356537
+65366538754B654865566555654D6558655E655D65726578658265838B8A659B
+659F65AB65B765C365C665C165C465CC65D265DB65D965E065E165F16772660A
+660365FB6773663566366634661C664F664466496641665E665D666466676668
+665F6662667066836688668E668966846698669D66C166B966C966BE66BC0000
+DB
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000066C466B866D666DA66E0663F66E666E966F066F566F7670F6716671E6726
+67279738672E673F67366741673867376746675E676067596763676467896770
+67A9677C676A678C678B67A667A1678567B767EF67B467EC67B367E967B867E4
+67DE67DD67E267EE67B967CE67C667E76A9C681E684668296840684D6832684E
+68B3682B685968636877687F689F688F68AD6894689D689B68836AAE68B96874
+68B568A068BA690F688D687E690168CA690868D86922692668E1690C68CD0000
+DC
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000068D468E768D569366912690468D768E3692568F968E068EF6928692A691A
+6923692168C669796977695C6978696B6954697E696E69396974693D69596930
+6961695E695D6981696A69B269AE69D069BF69C169D369BE69CE5BE869CA69DD
+69BB69C369A76A2E699169A0699C699569B469DE69E86A026A1B69FF6B0A69F9
+69F269E76A0569B16A1E69ED6A1469EB6A0A6A126AC16A236A136A446A0C6A72
+6A366A786A476A626A596A666A486A386A226A906A8D6AA06A846AA26AA30000
+DD
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00006A9786176ABB6AC36AC26AB86AB36AAC6ADE6AD16ADF6AAA6ADA6AEA6AFB
+6B0586166AFA6B126B169B316B1F6B386B3776DC6B3998EE6B476B436B496B50
+6B596B546B5B6B5F6B616B786B796B7F6B806B846B836B8D6B986B956B9E6BA4
+6BAA6BAB6BAF6BB26BB16BB36BB76BBC6BC66BCB6BD36BDF6BEC6BEB6BF36BEF
+9EBE6C086C136C146C1B6C246C236C5E6C556C626C6A6C826C8D6C9A6C816C9B
+6C7E6C686C736C926C906CC46CF16CD36CBD6CD76CC56CDD6CAE6CB16CBE0000
+DE
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00006CBA6CDB6CEF6CD96CEA6D1F884D6D366D2B6D3D6D386D196D356D336D12
+6D0C6D636D936D646D5A6D796D596D8E6D956FE46D856DF96E156E0A6DB56DC7
+6DE66DB86DC66DEC6DDE6DCC6DE86DD26DC56DFA6DD96DE46DD56DEA6DEE6E2D
+6E6E6E2E6E196E726E5F6E3E6E236E6B6E2B6E766E4D6E1F6E436E3A6E4E6E24
+6EFF6E1D6E386E826EAA6E986EC96EB76ED36EBD6EAF6EC46EB26ED46ED56E8F
+6EA56EC26E9F6F416F11704C6EEC6EF86EFE6F3F6EF26F316EEF6F326ECC0000
+DF
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00006F3E6F136EF76F866F7A6F786F816F806F6F6F5B6FF36F6D6F826F7C6F58
+6F8E6F916FC26F666FB36FA36FA16FA46FB96FC66FAA6FDF6FD56FEC6FD46FD8
+6FF16FEE6FDB7009700B6FFA70117001700F6FFE701B701A6F74701D7018701F
+7030703E7032705170637099709270AF70F170AC70B870B370AE70DF70CB70DD
+70D9710970FD711C711971657155718871667162714C7156716C718F71FB7184
+719571A871AC71D771B971BE71D271C971D471CE71E071EC71E771F571FC0000
+E0
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000071F971FF720D7210721B7228722D722C72307232723B723C723F72407246
+724B72587274727E7282728172877292729672A272A772B972B272C372C672C4
+72CE72D272E272E072E172F972F7500F7317730A731C7316731D7334732F7329
+7325733E734E734F9ED87357736A7368737073787375737B737A73C873B373CE
+73BB73C073E573EE73DE74A27405746F742573F87432743A7455743F745F7459
+7441745C746974707463746A7476747E748B749E74A774CA74CF74D473F10000
+E1
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000074E074E374E774E974EE74F274F074F174F874F7750475037505750C750E
+750D75157513751E7526752C753C7544754D754A7549755B7546755A75697564
+7567756B756D75787576758675877574758A758975827594759A759D75A575A3
+75C275B375C375B575BD75B875BC75B175CD75CA75D275D975E375DE75FE75FF
+75FC760175F075FA75F275F3760B760D7609761F762776207621762276247634
+7630763B764776487646765C76587661766276687669766A7667766C76700000
+E2
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000767276767678767C768076837688768B768E769676937699769A76B076B4
+76B876B976BA76C276CD76D676D276DE76E176E576E776EA862F76FB77087707
+770477297724771E77257726771B773777387747775A7768776B775B7765777F
+777E7779778E778B779177A0779E77B077B677B977BF77BC77BD77BB77C777CD
+77D777DA77DC77E377EE77FC780C781279267820792A7845788E78747886787C
+789A788C78A378B578AA78AF78D178C678CB78D478BE78BC78C578CA78EC0000
+E3
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000078E778DA78FD78F47907791279117919792C792B794079607957795F795A
+79557953797A797F798A799D79A79F4B79AA79AE79B379B979BA79C979D579E7
+79EC79E179E37A087A0D7A187A197A207A1F79807A317A3B7A3E7A377A437A57
+7A497A617A627A699F9D7A707A797A7D7A887A977A957A987A967AA97AC87AB0
+7AB67AC57AC47ABF90837AC77ACA7ACD7ACF7AD57AD37AD97ADA7ADD7AE17AE2
+7AE67AED7AF07B027B0F7B0A7B067B337B187B197B1E7B357B287B367B500000
+E4
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00007B7A7B047B4D7B0B7B4C7B457B757B657B747B677B707B717B6C7B6E7B9D
+7B987B9F7B8D7B9C7B9A7B8B7B927B8F7B5D7B997BCB7BC17BCC7BCF7BB47BC6
+7BDD7BE97C117C147BE67BE57C607C007C077C137BF37BF77C177C0D7BF67C23
+7C277C2A7C1F7C377C2B7C3D7C4C7C437C547C4F7C407C507C587C5F7C647C56
+7C657C6C7C757C837C907CA47CAD7CA27CAB7CA17CA87CB37CB27CB17CAE7CB9
+7CBD7CC07CC57CC27CD87CD27CDC7CE29B3B7CEF7CF27CF47CF67CFA7D060000
+E5
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00007D027D1C7D157D0A7D457D4B7D2E7D327D3F7D357D467D737D567D4E7D72
+7D687D6E7D4F7D637D937D897D5B7D8F7D7D7D9B7DBA7DAE7DA37DB57DC77DBD
+7DAB7E3D7DA27DAF7DDC7DB87D9F7DB07DD87DDD7DE47DDE7DFB7DF27DE17E05
+7E0A7E237E217E127E317E1F7E097E0B7E227E467E667E3B7E357E397E437E37
+7E327E3A7E677E5D7E567E5E7E597E5A7E797E6A7E697E7C7E7B7E837DD57E7D
+8FAE7E7F7E887E897E8C7E927E907E937E947E967E8E7E9B7E9C7F387F3A0000
+E6
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00007F457F4C7F4D7F4E7F507F517F557F547F587F5F7F607F687F697F677F78
+7F827F867F837F887F877F8C7F947F9E7F9D7F9A7FA37FAF7FB27FB97FAE7FB6
+7FB88B717FC57FC67FCA7FD57FD47FE17FE67FE97FF37FF998DC80068004800B
+801280188019801C80218028803F803B804A804680528058805A805F80628068
+80738072807080768079807D807F808480868085809B8093809A80AD519080AC
+80DB80E580D980DD80C480DA80D6810980EF80F1811B81298123812F814B0000
+E7
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000968B8146813E8153815180FC8171816E81658166817481838188818A8180
+818281A0819581A481A3815F819381A981B081B581BE81B881BD81C081C281BA
+81C981CD81D181D981D881C881DA81DF81E081E781FA81FB81FE820182028205
+8207820A820D821082168229822B82388233824082598258825D825A825F8264
+82628268826A826B822E827182778278827E828D829282AB829F82BB82AC82E1
+82E382DF82D282F482F382FA8393830382FB82F982DE830682DC830982D90000
+E8
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000833583348316833283318340833983508345832F832B831783188385839A
+83AA839F83A283968323838E8387838A837C83B58373837583A0838983A883F4
+841383EB83CE83FD840383D8840B83C183F7840783E083F2840D8422842083BD
+8438850683FB846D842A843C855A84848477846B84AD846E848284698446842C
+846F8479843584CA846284B984BF849F84D984CD84BB84DA84D084C184C684D6
+84A1852184FF84F485178518852C851F8515851484FC85408563855885480000
+E9
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000085418602854B8555858085A485888591858A85A8856D8594859B85EA8587
+859C8577857E859085C985BA85CF85B985D085D585DD85E585DC85F9860A8613
+860B85FE85FA86068622861A8630863F864D4E558654865F86678671869386A3
+86A986AA868B868C86B686AF86C486C686B086C9882386AB86D486DE86E986EC
+86DF86DB86EF8712870687088700870386FB87118709870D86F9870A8734873F
+8737873B87258729871A8760875F8778874C874E877487578768876E87590000
+EA
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000087538763876A880587A2879F878287AF87CB87BD87C087D096D687AB87C4
+87B387C787C687BB87EF87F287E0880F880D87FE87F687F7880E87D288118816
+8815882288218831883688398827883B8844884288528859885E8862886B8881
+887E889E8875887D88B5887288828897889288AE889988A2888D88A488B088BF
+88B188C388C488D488D888D988DD88F9890288FC88F488E888F28904890C890A
+89138943891E8925892A892B89418944893B89368938894C891D8960895E0000
+EB
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000089668964896D896A896F89748977897E89838988898A8993899889A189A9
+89A689AC89AF89B289BA89BD89BF89C089DA89DC89DD89E789F489F88A038A16
+8A108A0C8A1B8A1D8A258A368A418A5B8A528A468A488A7C8A6D8A6C8A628A85
+8A828A848AA88AA18A918AA58AA68A9A8AA38AC48ACD8AC28ADA8AEB8AF38AE7
+8AE48AF18B148AE08AE28AF78ADE8ADB8B0C8B078B1A8AE18B168B108B178B20
+8B3397AB8B268B2B8B3E8B288B418B4C8B4F8B4E8B498B568B5B8B5A8B6B0000
+EC
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00008B5F8B6C8B6F8B748B7D8B808B8C8B8E8B928B938B968B998B9A8C3A8C41
+8C3F8C488C4C8C4E8C508C558C628C6C8C788C7A8C828C898C858C8A8C8D8C8E
+8C948C7C8C98621D8CAD8CAA8CBD8CB28CB38CAE8CB68CC88CC18CE48CE38CDA
+8CFD8CFA8CFB8D048D058D0A8D078D0F8D0D8D109F4E8D138CCD8D148D168D67
+8D6D8D718D738D818D998DC28DBE8DBA8DCF8DDA8DD68DCC8DDB8DCB8DEA8DEB
+8DDF8DE38DFC8E088E098DFF8E1D8E1E8E108E1F8E428E358E308E348E4A0000
+ED
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00008E478E498E4C8E508E488E598E648E608E2A8E638E558E768E728E7C8E81
+8E878E858E848E8B8E8A8E938E918E948E998EAA8EA18EAC8EB08EC68EB18EBE
+8EC58EC88ECB8EDB8EE38EFC8EFB8EEB8EFE8F0A8F058F158F128F198F138F1C
+8F1F8F1B8F0C8F268F338F3B8F398F458F428F3E8F4C8F498F468F4E8F578F5C
+8F628F638F648F9C8F9F8FA38FAD8FAF8FB78FDA8FE58FE28FEA8FEF90878FF4
+90058FF98FFA901190159021900D901E9016900B90279036903590398FF80000
+EE
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000904F905090519052900E9049903E90569058905E9068906F907696A89072
+9082907D90819080908A9089908F90A890AF90B190B590E290E4624890DB9102
+9112911991329130914A9156915891639165916991739172918B9189918291A2
+91AB91AF91AA91B591B491BA91C091C191C991CB91D091D691DF91E191DB91FC
+91F591F6921E91FF9214922C92159211925E925792459249926492489295923F
+924B9250929C92969293929B925A92CF92B992B792E9930F92FA9344932E0000
+EF
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000093199322931A9323933A9335933B935C9360937C936E935693B093AC93AD
+939493B993D693D793E893E593D893C393DD93D093C893E4941A941494139403
+940794109436942B94359421943A944194529444945B94609462945E946A9229
+947094759477947D945A947C947E9481947F95829587958A9594959695989599
+95A095A895A795AD95BC95BB95B995BE95CA6FF695C395CD95CC95D595D495D6
+95DC95E195E595E296219628962E962F9642964C964F964B9677965C965E0000
+F0
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000965D965F96669672966C968D96989695969796AA96A796B196B296B096B4
+96B696B896B996CE96CB96C996CD894D96DC970D96D596F99704970697089713
+970E9711970F971697199724972A97309739973D973E97449746974897429749
+975C976097649766976852D2976B977197799785977C9781977A9786978B978F
+9790979C97A897A697A397B397B497C397C697C897CB97DC97ED9F4F97F27ADF
+97F697F5980F980C9838982498219837983D9846984F984B986B986F98700000
+F1
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000098719874987398AA98AF98B198B698C498C398C698E998EB990399099912
+991499189921991D991E99249920992C992E993D993E9942994999459950994B
+99519952994C99559997999899A599AD99AE99BC99DF99DB99DD99D899D199ED
+99EE99F199F299FB99F89A019A0F9A0599E29A199A2B9A379A459A429A409A43
+9A3E9A559A4D9A5B9A579A5F9A629A659A649A699A6B9A6A9AAD9AB09ABC9AC0
+9ACF9AD19AD39AD49ADE9ADF9AE29AE39AE69AEF9AEB9AEE9AF49AF19AF70000
+F2
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00009AFB9B069B189B1A9B1F9B229B239B259B279B289B299B2A9B2E9B2F9B32
+9B449B439B4F9B4D9B4E9B519B589B749B939B839B919B969B979B9F9BA09BA8
+9BB49BC09BCA9BB99BC69BCF9BD19BD29BE39BE29BE49BD49BE19C3A9BF29BF1
+9BF09C159C149C099C139C0C9C069C089C129C0A9C049C2E9C1B9C259C249C21
+9C309C479C329C469C3E9C5A9C609C679C769C789CE79CEC9CF09D099D089CEB
+9D039D069D2A9D269DAF9D239D1F9D449D159D129D419D3F9D3E9D469D480000
+F3
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00009D5D9D5E9D649D519D509D599D729D899D879DAB9D6F9D7A9D9A9DA49DA9
+9DB29DC49DC19DBB9DB89DBA9DC69DCF9DC29DD99DD39DF89DE69DED9DEF9DFD
+9E1A9E1B9E1E9E759E799E7D9E819E889E8B9E8C9E929E959E919E9D9EA59EA9
+9EB89EAA9EAD97619ECC9ECE9ECF9ED09ED49EDC9EDE9EDD9EE09EE59EE89EEF
+9EF49EF69EF79EF99EFB9EFC9EFD9F079F0876B79F159F219F2C9F3E9F4A9F52
+9F549F639F5F9F609F619F669F679F6C9F6A9F779F729F769F959F9C9FA00000
+F4
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000582F69C79059746451DC7199000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+R
+A1C1 301C FF5E
+A1C2 2016 2225
+A1DD 2212 FF0D
+A1F1 00A2 FFE0
+A1F2 00A3 FFE1
+A2CC 00AC FFE2
diff --git a/library/encoding/euc-kr.enc b/library/encoding/euc-kr.enc
new file mode 100644
index 0000000..5e9bb93
--- /dev/null
+++ b/library/encoding/euc-kr.enc
@@ -0,0 +1,1533 @@
+# Encoding file: euc-kr, multi-byte
+M
+003F 0 90
+00
+0000000100020003000400050006000700080009000A000B000C000D000E000F
+0010001100120013001400150016001700180019001A001B001C001D001E001F
+0020002100220023002400250026002700280029002A002B002C002D002E002F
+0030003100320033003400350036003700380039003A003B003C003D003E003F
+0040004100420043004400450046004700480049004A004B004C004D004E004F
+0050005100520053005400550056005700580059005A005B005C005D005E005F
+0060006100620063006400650066006700680069006A006B006C006D006E006F
+0070007100720073007400750076007700780079007A007B007C007D007E007F
+0080008100820083008400850086008700880089008A008B008C008D008E008F
+0090009100920093009400950096009700980099009A009B009C009D009E009F
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+A1
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000030003001300200B72025202600A8300300AD20152225FF3C223C20182019
+201C201D3014301530083009300A300B300C300D300E300F3010301100B100D7
+00F7226022642265221E223400B0203220332103212BFFE0FFE1FFE526422640
+222022A52312220222072261225200A7203B2606260525CB25CF25CE25C725C6
+25A125A025B325B225BD25BC219221902191219321943013226A226B221A223D
+221D2235222B222C2208220B2286228722822283222A222922272228FFE20000
+A2
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000021D221D42200220300B4FF5E02C702D802DD02DA02D900B802DB00A100BF
+02D0222E2211220F00A42109203025C125C025B725B626642660266126652667
+2663229925C825A325D025D1259225A425A525A825A725A625A92668260F260E
+261C261E00B62020202121952197219921962198266D2669266A266C327F321C
+211633C7212233C233D821210000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+A3
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000FF01FF02FF03FF04FF05FF06FF07FF08FF09FF0AFF0BFF0CFF0DFF0EFF0F
+FF10FF11FF12FF13FF14FF15FF16FF17FF18FF19FF1AFF1BFF1CFF1DFF1EFF1F
+FF20FF21FF22FF23FF24FF25FF26FF27FF28FF29FF2AFF2BFF2CFF2DFF2EFF2F
+FF30FF31FF32FF33FF34FF35FF36FF37FF38FF39FF3AFF3BFFE6FF3DFF3EFF3F
+FF40FF41FF42FF43FF44FF45FF46FF47FF48FF49FF4AFF4BFF4CFF4DFF4EFF4F
+FF50FF51FF52FF53FF54FF55FF56FF57FF58FF59FF5AFF5BFF5CFF5DFFE30000
+A4
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000313131323133313431353136313731383139313A313B313C313D313E313F
+3140314131423143314431453146314731483149314A314B314C314D314E314F
+3150315131523153315431553156315731583159315A315B315C315D315E315F
+3160316131623163316431653166316731683169316A316B316C316D316E316F
+3170317131723173317431753176317731783179317A317B317C317D317E317F
+3180318131823183318431853186318731883189318A318B318C318D318E0000
+A5
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000217021712172217321742175217621772178217900000000000000000000
+2160216121622163216421652166216721682169000000000000000000000000
+0000039103920393039403950396039703980399039A039B039C039D039E039F
+03A003A103A303A403A503A603A703A803A90000000000000000000000000000
+000003B103B203B303B403B503B603B703B803B903BA03BB03BC03BD03BE03BF
+03C003C103C303C403C503C603C703C803C90000000000000000000000000000
+A6
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000025002502250C251025182514251C252C25242534253C25012503250F2513
+251B251725232533252B253B254B2520252F25282537253F251D253025252538
+254225122511251A251925162515250E250D251E251F25212522252625272529
+252A252D252E25312532253525362539253A253D253E25402541254325442545
+2546254725482549254A00000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+A7
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00003395339633972113339833C433A333A433A533A63399339A339B339C339D
+339E339F33A033A133A233CA338D338E338F33CF3388338933C833A733A833B0
+33B133B233B333B433B533B633B733B833B93380338133823383338433BA33BB
+33BC33BD33BE33BF33903391339233933394212633C033C1338A338B338C33D6
+33C533AD33AE33AF33DB33A933AA33AB33AC33DD33D033D333C333C933DC33C6
+0000000000000000000000000000000000000000000000000000000000000000
+A8
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000000C600D000AA0126000001320000013F014100D8015200BA00DE0166014A
+00003260326132623263326432653266326732683269326A326B326C326D326E
+326F3270327132723273327432753276327732783279327A327B24D024D124D2
+24D324D424D524D624D724D824D924DA24DB24DC24DD24DE24DF24E024E124E2
+24E324E424E524E624E724E824E9246024612462246324642465246624672468
+2469246A246B246C246D246E00BD2153215400BC00BE215B215C215D215E0000
+A9
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000000E6011100F001270131013301380140014200F8015300DF00FE0167014B
+01493200320132023203320432053206320732083209320A320B320C320D320E
+320F3210321132123213321432153216321732183219321A321B249C249D249E
+249F24A024A124A224A324A424A524A624A724A824A924AA24AB24AC24AD24AE
+24AF24B024B124B224B324B424B5247424752476247724782479247A247B247C
+247D247E247F24802481248200B900B200B32074207F20812082208320840000
+AA
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000304130423043304430453046304730483049304A304B304C304D304E304F
+3050305130523053305430553056305730583059305A305B305C305D305E305F
+3060306130623063306430653066306730683069306A306B306C306D306E306F
+3070307130723073307430753076307730783079307A307B307C307D307E307F
+3080308130823083308430853086308730883089308A308B308C308D308E308F
+3090309130923093000000000000000000000000000000000000000000000000
+AB
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000030A130A230A330A430A530A630A730A830A930AA30AB30AC30AD30AE30AF
+30B030B130B230B330B430B530B630B730B830B930BA30BB30BC30BD30BE30BF
+30C030C130C230C330C430C530C630C730C830C930CA30CB30CC30CD30CE30CF
+30D030D130D230D330D430D530D630D730D830D930DA30DB30DC30DD30DE30DF
+30E030E130E230E330E430E530E630E730E830E930EA30EB30EC30ED30EE30EF
+30F030F130F230F330F430F530F6000000000000000000000000000000000000
+AC
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000004100411041204130414041504010416041704180419041A041B041C041D
+041E041F0420042104220423042404250426042704280429042A042B042C042D
+042E042F00000000000000000000000000000000000000000000000000000000
+000004300431043204330434043504510436043704380439043A043B043C043D
+043E043F0440044104420443044404450446044704480449044A044B044C044D
+044E044F00000000000000000000000000000000000000000000000000000000
+B0
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000AC00AC01AC04AC07AC08AC09AC0AAC10AC11AC12AC13AC14AC15AC16AC17
+AC19AC1AAC1BAC1CAC1DAC20AC24AC2CAC2DAC2FAC30AC31AC38AC39AC3CAC40
+AC4BAC4DAC54AC58AC5CAC70AC71AC74AC77AC78AC7AAC80AC81AC83AC84AC85
+AC86AC89AC8AAC8BAC8CAC90AC94AC9CAC9DAC9FACA0ACA1ACA8ACA9ACAAACAC
+ACAFACB0ACB8ACB9ACBBACBCACBDACC1ACC4ACC8ACCCACD5ACD7ACE0ACE1ACE4
+ACE7ACE8ACEAACECACEFACF0ACF1ACF3ACF5ACF6ACFCACFDAD00AD04AD060000
+B1
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000AD0CAD0DAD0FAD11AD18AD1CAD20AD29AD2CAD2DAD34AD35AD38AD3CAD44
+AD45AD47AD49AD50AD54AD58AD61AD63AD6CAD6DAD70AD73AD74AD75AD76AD7B
+AD7CAD7DAD7FAD81AD82AD88AD89AD8CAD90AD9CAD9DADA4ADB7ADC0ADC1ADC4
+ADC8ADD0ADD1ADD3ADDCADE0ADE4ADF8ADF9ADFCADFFAE00AE01AE08AE09AE0B
+AE0DAE14AE30AE31AE34AE37AE38AE3AAE40AE41AE43AE45AE46AE4AAE4CAE4D
+AE4EAE50AE54AE56AE5CAE5DAE5FAE60AE61AE65AE68AE69AE6CAE70AE780000
+B2
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000AE79AE7BAE7CAE7DAE84AE85AE8CAEBCAEBDAEBEAEC0AEC4AECCAECDAECF
+AED0AED1AED8AED9AEDCAEE8AEEBAEEDAEF4AEF8AEFCAF07AF08AF0DAF10AF2C
+AF2DAF30AF32AF34AF3CAF3DAF3FAF41AF42AF43AF48AF49AF50AF5CAF5DAF64
+AF65AF79AF80AF84AF88AF90AF91AF95AF9CAFB8AFB9AFBCAFC0AFC7AFC8AFC9
+AFCBAFCDAFCEAFD4AFDCAFE8AFE9AFF0AFF1AFF4AFF8B000B001B004B00CB010
+B014B01CB01DB028B044B045B048B04AB04CB04EB053B054B055B057B0590000
+B3
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000B05DB07CB07DB080B084B08CB08DB08FB091B098B099B09AB09CB09FB0A0
+B0A1B0A2B0A8B0A9B0ABB0ACB0ADB0AEB0AFB0B1B0B3B0B4B0B5B0B8B0BCB0C4
+B0C5B0C7B0C8B0C9B0D0B0D1B0D4B0D8B0E0B0E5B108B109B10BB10CB110B112
+B113B118B119B11BB11CB11DB123B124B125B128B12CB134B135B137B138B139
+B140B141B144B148B150B151B154B155B158B15CB160B178B179B17CB180B182
+B188B189B18BB18DB192B193B194B198B19CB1A8B1CCB1D0B1D4B1DCB1DD0000
+B4
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000B1DFB1E8B1E9B1ECB1F0B1F9B1FBB1FDB204B205B208B20BB20CB214B215
+B217B219B220B234B23CB258B25CB260B268B269B274B275B27CB284B285B289
+B290B291B294B298B299B29AB2A0B2A1B2A3B2A5B2A6B2AAB2ACB2B0B2B4B2C8
+B2C9B2CCB2D0B2D2B2D8B2D9B2DBB2DDB2E2B2E4B2E5B2E6B2E8B2EBB2ECB2ED
+B2EEB2EFB2F3B2F4B2F5B2F7B2F8B2F9B2FAB2FBB2FFB300B301B304B308B310
+B311B313B314B315B31CB354B355B356B358B35BB35CB35EB35FB364B3650000
+B5
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000B367B369B36BB36EB370B371B374B378B380B381B383B384B385B38CB390
+B394B3A0B3A1B3A8B3ACB3C4B3C5B3C8B3CBB3CCB3CEB3D0B3D4B3D5B3D7B3D9
+B3DBB3DDB3E0B3E4B3E8B3FCB410B418B41CB420B428B429B42BB434B450B451
+B454B458B460B461B463B465B46CB480B488B49DB4A4B4A8B4ACB4B5B4B7B4B9
+B4C0B4C4B4C8B4D0B4D5B4DCB4DDB4E0B4E3B4E4B4E6B4ECB4EDB4EFB4F1B4F8
+B514B515B518B51BB51CB524B525B527B528B529B52AB530B531B534B5380000
+B6
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000B540B541B543B544B545B54BB54CB54DB550B554B55CB55DB55FB560B561
+B5A0B5A1B5A4B5A8B5AAB5ABB5B0B5B1B5B3B5B4B5B5B5BBB5BCB5BDB5C0B5C4
+B5CCB5CDB5CFB5D0B5D1B5D8B5ECB610B611B614B618B625B62CB634B648B664
+B668B69CB69DB6A0B6A4B6ABB6ACB6B1B6D4B6F0B6F4B6F8B700B701B705B728
+B729B72CB72FB730B738B739B73BB744B748B74CB754B755B760B764B768B770
+B771B773B775B77CB77DB780B784B78CB78DB78FB790B791B792B796B7970000
+B7
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000B798B799B79CB7A0B7A8B7A9B7ABB7ACB7ADB7B4B7B5B7B8B7C7B7C9B7EC
+B7EDB7F0B7F4B7FCB7FDB7FFB800B801B807B808B809B80CB810B818B819B81B
+B81DB824B825B828B82CB834B835B837B838B839B840B844B851B853B85CB85D
+B860B864B86CB86DB86FB871B878B87CB88DB8A8B8B0B8B4B8B8B8C0B8C1B8C3
+B8C5B8CCB8D0B8D4B8DDB8DFB8E1B8E8B8E9B8ECB8F0B8F8B8F9B8FBB8FDB904
+B918B920B93CB93DB940B944B94CB94FB951B958B959B95CB960B968B9690000
+B8
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000B96BB96DB974B975B978B97CB984B985B987B989B98AB98DB98EB9ACB9AD
+B9B0B9B4B9BCB9BDB9BFB9C1B9C8B9C9B9CCB9CEB9CFB9D0B9D1B9D2B9D8B9D9
+B9DBB9DDB9DEB9E1B9E3B9E4B9E5B9E8B9ECB9F4B9F5B9F7B9F8B9F9B9FABA00
+BA01BA08BA15BA38BA39BA3CBA40BA42BA48BA49BA4BBA4DBA4EBA53BA54BA55
+BA58BA5CBA64BA65BA67BA68BA69BA70BA71BA74BA78BA83BA84BA85BA87BA8C
+BAA8BAA9BAABBAACBAB0BAB2BAB8BAB9BABBBABDBAC4BAC8BAD8BAD9BAFC0000
+B9
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000BB00BB04BB0DBB0FBB11BB18BB1CBB20BB29BB2BBB34BB35BB36BB38BB3B
+BB3CBB3DBB3EBB44BB45BB47BB49BB4DBB4FBB50BB54BB58BB61BB63BB6CBB88
+BB8CBB90BBA4BBA8BBACBBB4BBB7BBC0BBC4BBC8BBD0BBD3BBF8BBF9BBFCBBFF
+BC00BC02BC08BC09BC0BBC0CBC0DBC0FBC11BC14BC15BC16BC17BC18BC1BBC1C
+BC1DBC1EBC1FBC24BC25BC27BC29BC2DBC30BC31BC34BC38BC40BC41BC43BC44
+BC45BC49BC4CBC4DBC50BC5DBC84BC85BC88BC8BBC8CBC8EBC94BC95BC970000
+BA
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000BC99BC9ABCA0BCA1BCA4BCA7BCA8BCB0BCB1BCB3BCB4BCB5BCBCBCBDBCC0
+BCC4BCCDBCCFBCD0BCD1BCD5BCD8BCDCBCF4BCF5BCF6BCF8BCFCBD04BD05BD07
+BD09BD10BD14BD24BD2CBD40BD48BD49BD4CBD50BD58BD59BD64BD68BD80BD81
+BD84BD87BD88BD89BD8ABD90BD91BD93BD95BD99BD9ABD9CBDA4BDB0BDB8BDD4
+BDD5BDD8BDDCBDE9BDF0BDF4BDF8BE00BE03BE05BE0CBE0DBE10BE14BE1CBE1D
+BE1FBE44BE45BE48BE4CBE4EBE54BE55BE57BE59BE5ABE5BBE60BE61BE640000
+BB
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000BE68BE6ABE70BE71BE73BE74BE75BE7BBE7CBE7DBE80BE84BE8CBE8DBE8F
+BE90BE91BE98BE99BEA8BED0BED1BED4BED7BED8BEE0BEE3BEE4BEE5BEECBF01
+BF08BF09BF18BF19BF1BBF1CBF1DBF40BF41BF44BF48BF50BF51BF55BF94BFB0
+BFC5BFCCBFCDBFD0BFD4BFDCBFDFBFE1C03CC051C058C05CC060C068C069C090
+C091C094C098C0A0C0A1C0A3C0A5C0ACC0ADC0AFC0B0C0B3C0B4C0B5C0B6C0BC
+C0BDC0BFC0C0C0C1C0C5C0C8C0C9C0CCC0D0C0D8C0D9C0DBC0DCC0DDC0E40000
+BC
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000C0E5C0E8C0ECC0F4C0F5C0F7C0F9C100C104C108C110C115C11CC11DC11E
+C11FC120C123C124C126C127C12CC12DC12FC130C131C136C138C139C13CC140
+C148C149C14BC14CC14DC154C155C158C15CC164C165C167C168C169C170C174
+C178C185C18CC18DC18EC190C194C196C19CC19DC19FC1A1C1A5C1A8C1A9C1AC
+C1B0C1BDC1C4C1C8C1CCC1D4C1D7C1D8C1E0C1E4C1E8C1F0C1F1C1F3C1FCC1FD
+C200C204C20CC20DC20FC211C218C219C21CC21FC220C228C229C22BC22D0000
+BD
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000C22FC231C232C234C248C250C251C254C258C260C265C26CC26DC270C274
+C27CC27DC27FC281C288C289C290C298C29BC29DC2A4C2A5C2A8C2ACC2ADC2B4
+C2B5C2B7C2B9C2DCC2DDC2E0C2E3C2E4C2EBC2ECC2EDC2EFC2F1C2F6C2F8C2F9
+C2FBC2FCC300C308C309C30CC30DC313C314C315C318C31CC324C325C328C329
+C345C368C369C36CC370C372C378C379C37CC37DC384C388C38CC3C0C3D8C3D9
+C3DCC3DFC3E0C3E2C3E8C3E9C3EDC3F4C3F5C3F8C408C410C424C42CC4300000
+BE
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000C434C43CC43DC448C464C465C468C46CC474C475C479C480C494C49CC4B8
+C4BCC4E9C4F0C4F1C4F4C4F8C4FAC4FFC500C501C50CC510C514C51CC528C529
+C52CC530C538C539C53BC53DC544C545C548C549C54AC54CC54DC54EC553C554
+C555C557C558C559C55DC55EC560C561C564C568C570C571C573C574C575C57C
+C57DC580C584C587C58CC58DC58FC591C595C597C598C59CC5A0C5A9C5B4C5B5
+C5B8C5B9C5BBC5BCC5BDC5BEC5C4C5C5C5C6C5C7C5C8C5C9C5CAC5CCC5CE0000
+BF
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000C5D0C5D1C5D4C5D8C5E0C5E1C5E3C5E5C5ECC5EDC5EEC5F0C5F4C5F6C5F7
+C5FCC5FDC5FEC5FFC600C601C605C606C607C608C60CC610C618C619C61BC61C
+C624C625C628C62CC62DC62EC630C633C634C635C637C639C63BC640C641C644
+C648C650C651C653C654C655C65CC65DC660C66CC66FC671C678C679C67CC680
+C688C689C68BC68DC694C695C698C69CC6A4C6A5C6A7C6A9C6B0C6B1C6B4C6B8
+C6B9C6BAC6C0C6C1C6C3C6C5C6CCC6CDC6D0C6D4C6DCC6DDC6E0C6E1C6E80000
+C0
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000C6E9C6ECC6F0C6F8C6F9C6FDC704C705C708C70CC714C715C717C719C720
+C721C724C728C730C731C733C735C737C73CC73DC740C744C74AC74CC74DC74F
+C751C752C753C754C755C756C757C758C75CC760C768C76BC774C775C778C77C
+C77DC77EC783C784C785C787C788C789C78AC78EC790C791C794C796C797C798
+C79AC7A0C7A1C7A3C7A4C7A5C7A6C7ACC7ADC7B0C7B4C7BCC7BDC7BFC7C0C7C1
+C7C8C7C9C7CCC7CEC7D0C7D8C7DDC7E4C7E8C7ECC800C801C804C808C80A0000
+C1
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000C810C811C813C815C816C81CC81DC820C824C82CC82DC82FC831C838C83C
+C840C848C849C84CC84DC854C870C871C874C878C87AC880C881C883C885C886
+C887C88BC88CC88DC894C89DC89FC8A1C8A8C8BCC8BDC8C4C8C8C8CCC8D4C8D5
+C8D7C8D9C8E0C8E1C8E4C8F5C8FCC8FDC900C904C905C906C90CC90DC90FC911
+C918C92CC934C950C951C954C958C960C961C963C96CC970C974C97CC988C989
+C98CC990C998C999C99BC99DC9C0C9C1C9C4C9C7C9C8C9CAC9D0C9D1C9D30000
+C2
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000C9D5C9D6C9D9C9DAC9DCC9DDC9E0C9E2C9E4C9E7C9ECC9EDC9EFC9F0C9F1
+C9F8C9F9C9FCCA00CA08CA09CA0BCA0CCA0DCA14CA18CA29CA4CCA4DCA50CA54
+CA5CCA5DCA5FCA60CA61CA68CA7DCA84CA98CABCCABDCAC0CAC4CACCCACDCACF
+CAD1CAD3CAD8CAD9CAE0CAECCAF4CB08CB10CB14CB18CB20CB21CB41CB48CB49
+CB4CCB50CB58CB59CB5DCB64CB78CB79CB9CCBB8CBD4CBE4CBE7CBE9CC0CCC0D
+CC10CC14CC1CCC1DCC21CC22CC27CC28CC29CC2CCC2ECC30CC38CC39CC3B0000
+C3
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000CC3CCC3DCC3ECC44CC45CC48CC4CCC54CC55CC57CC58CC59CC60CC64CC66
+CC68CC70CC75CC98CC99CC9CCCA0CCA8CCA9CCABCCACCCADCCB4CCB5CCB8CCBC
+CCC4CCC5CCC7CCC9CCD0CCD4CCE4CCECCCF0CD01CD08CD09CD0CCD10CD18CD19
+CD1BCD1DCD24CD28CD2CCD39CD5CCD60CD64CD6CCD6DCD6FCD71CD78CD88CD94
+CD95CD98CD9CCDA4CDA5CDA7CDA9CDB0CDC4CDCCCDD0CDE8CDECCDF0CDF8CDF9
+CDFBCDFDCE04CE08CE0CCE14CE19CE20CE21CE24CE28CE30CE31CE33CE350000
+C4
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000CE58CE59CE5CCE5FCE60CE61CE68CE69CE6BCE6DCE74CE75CE78CE7CCE84
+CE85CE87CE89CE90CE91CE94CE98CEA0CEA1CEA3CEA4CEA5CEACCEADCEC1CEE4
+CEE5CEE8CEEBCEECCEF4CEF5CEF7CEF8CEF9CF00CF01CF04CF08CF10CF11CF13
+CF15CF1CCF20CF24CF2CCF2DCF2FCF30CF31CF38CF54CF55CF58CF5CCF64CF65
+CF67CF69CF70CF71CF74CF78CF80CF85CF8CCFA1CFA8CFB0CFC4CFE0CFE1CFE4
+CFE8CFF0CFF1CFF3CFF5CFFCD000D004D011D018D02DD034D035D038D03C0000
+C5
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000D044D045D047D049D050D054D058D060D06CD06DD070D074D07CD07DD081
+D0A4D0A5D0A8D0ACD0B4D0B5D0B7D0B9D0C0D0C1D0C4D0C8D0C9D0D0D0D1D0D3
+D0D4D0D5D0DCD0DDD0E0D0E4D0ECD0EDD0EFD0F0D0F1D0F8D10DD130D131D134
+D138D13AD140D141D143D144D145D14CD14DD150D154D15CD15DD15FD161D168
+D16CD17CD184D188D1A0D1A1D1A4D1A8D1B0D1B1D1B3D1B5D1BAD1BCD1C0D1D8
+D1F4D1F8D207D209D210D22CD22DD230D234D23CD23DD23FD241D248D25C0000
+C6
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000D264D280D281D284D288D290D291D295D29CD2A0D2A4D2ACD2B1D2B8D2B9
+D2BCD2BFD2C0D2C2D2C8D2C9D2CBD2D4D2D8D2DCD2E4D2E5D2F0D2F1D2F4D2F8
+D300D301D303D305D30CD30DD30ED310D314D316D31CD31DD31FD320D321D325
+D328D329D32CD330D338D339D33BD33CD33DD344D345D37CD37DD380D384D38C
+D38DD38FD390D391D398D399D39CD3A0D3A8D3A9D3ABD3ADD3B4D3B8D3BCD3C4
+D3C5D3C8D3C9D3D0D3D8D3E1D3E3D3ECD3EDD3F0D3F4D3FCD3FDD3FFD4010000
+C7
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000D408D41DD440D444D45CD460D464D46DD46FD478D479D47CD47FD480D482
+D488D489D48BD48DD494D4A9D4CCD4D0D4D4D4DCD4DFD4E8D4ECD4F0D4F8D4FB
+D4FDD504D508D50CD514D515D517D53CD53DD540D544D54CD54DD54FD551D558
+D559D55CD560D565D568D569D56BD56DD574D575D578D57CD584D585D587D588
+D589D590D5A5D5C8D5C9D5CCD5D0D5D2D5D8D5D9D5DBD5DDD5E4D5E5D5E8D5EC
+D5F4D5F5D5F7D5F9D600D601D604D608D610D611D613D614D615D61CD6200000
+C8
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000D624D62DD638D639D63CD640D645D648D649D64BD64DD651D654D655D658
+D65CD667D669D670D671D674D683D685D68CD68DD690D694D69DD69FD6A1D6A8
+D6ACD6B0D6B9D6BBD6C4D6C5D6C8D6CCD6D1D6D4D6D7D6D9D6E0D6E4D6E8D6F0
+D6F5D6FCD6FDD700D704D711D718D719D71CD720D728D729D72BD72DD734D735
+D738D73CD744D747D749D750D751D754D756D757D758D759D760D761D763D765
+D769D76CD770D774D77CD77DD781D788D789D78CD790D798D799D79BD79D0000
+CA
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00004F3D4F73504750F952A053EF547554E556095AC15BB6668767B667B767EF
+6B4C73C275C27A3C82DB8304885788888A368CC88DCF8EFB8FE699D5523B5374
+5404606A61646BBC73CF811A89BA89D295A34F83520A58BE597859E65E725E79
+61C763C0674667EC687F6F97764E770B78F57A087AFF7C21809D826E82718AEB
+95934E6B559D66F76E3478A37AED845B8910874E97A852D8574E582A5D4C611F
+61BE6221656267D16A446E1B751875B376E377B07D3A90AF945194529F950000
+CB
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000053235CAC753280DB92409598525B580859DC5CA15D175EB75F3A5F4A6177
+6C5F757A75867CE07D737DB17F8C81548221859189418B1B92FC964D9C474ECB
+4EF7500B51F1584F6137613E6168653969EA6F1175A5768676D67B8782A584CB
+F90093A7958B55805BA25751F9017CB37FB991B5502853BB5C455DE862D2636E
+64DA64E76E2070AC795B8DDD8E1EF902907D924592F84E7E4EF650655DFE5EFA
+61066957817186548E4793759A2B4E5E5091677068405109528D52926AA20000
+CC
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000077BC92109ED452AB602F8FF2504861A963ED64CA683C6A846FC0818889A1
+96945805727D72AC75047D797E6D80A9898B8B7490639D5162896C7A6F547D50
+7F3A8A23517C614A7B9D8B199257938C4EAC4FD3501E50BE510652C152CD537F
+577058835E9A5F91617661AC64CE656C666F66BB66F468976D87708570F1749F
+74A574CA75D9786C78EC7ADF7AF67D457D938015803F811B83968B668F159015
+93E1980398389A5A9BE84FC25553583A59515B635C4660B86212684268B00000
+CD
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000068E86EAA754C767878CE7A3D7CFB7E6B7E7C8A088AA18C3F968E9DC453E4
+53E9544A547156FA59D15B645C3B5EAB62F765376545657266A067AF69C16CBD
+75FC7690777E7A3F7F94800380A1818F82E682FD83F085C1883188B48AA5F903
+8F9C932E96C798679AD89F1354ED659B66F2688F7A408C379D6056F057645D11
+660668B168CD6EFE7428889E9BE46C68F9049AA84F9B516C5171529F5B545DE5
+6050606D62F163A7653B73D97A7A86A38CA2978F4E325BE16208679C74DC0000
+CE
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000079D183D38A878AB28DE8904E934B98465ED369E885FF90EDF90551A05B98
+5BEC616368FA6B3E704C742F74D87BA17F5083C589C08CAB95DC9928522E605D
+62EC90024F8A5149532158D95EE366E06D38709A72C273D67B5080F1945B5366
+639B7F6B4E565080584A58DE602A612762D069D09B415B8F7D1880B18F5F4EA4
+50D154AC55AC5B0C5DA05DE7652A654E68216A4B72E1768E77EF7D5E7FF981A0
+854E86DF8F038F4E90CA99039A559BAB4E184E454E5D4EC74FF1517752FE0000
+CF
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000534053E353E5548E5614577557A25BC75D875ED061FC62D8655167B867E9
+69CB6B506BC66BEC6C426E9D707872D77396740377BF77E97A767D7F800981FC
+8205820A82DF88628B338CFC8EC0901190B1926492B699D29A459CE99DD79F9C
+570B5C4083CA97A097AB9EB4541B7A987FA488D98ECD90E158005C4863987A9F
+5BAE5F137A797AAE828E8EAC5026523852F85377570862F363726B0A6DC37737
+53A5735785688E7695D5673A6AC36F708A6D8ECC994BF90666776B788CB40000
+D0
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00009B3CF90753EB572D594E63C669FB73EA78457ABA7AC57CFE8475898F8D73
+903595A852FB574775477B6083CC921EF9086A58514B524B5287621F68D86975
+969950C552A452E461C365A4683969FF747E7B4B82B983EB89B28B398FD19949
+F9094ECA599764D266116A8E7434798179BD82A9887E887F895FF90A93264F0B
+53CA602562716C727D1A7D664E98516277DC80AF4F014F0E5176518055DC5668
+573B57FA57FC5914594759935BC45C905D0E5DF15E7E5FCC628065D765E30000
+D1
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000671E671F675E68CB68C46A5F6B3A6C236C7D6C826DC773987426742A7482
+74A37578757F788178EF794179477948797A7B957D007DBA7F888006802D808C
+8A188B4F8C488D779321932498E299519A0E9A0F9A659E927DCA4F76540962EE
+685491D155AB513AF90BF90C5A1C61E6F90D62CF62FFF90EF90FF910F911F912
+F91390A3F914F915F916F917F9188AFEF919F91AF91BF91C6696F91D7156F91E
+F91F96E3F920634F637A5357F921678F69606E73F9227537F923F924F9250000
+D2
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00007D0DF926F927887256CA5A18F928F929F92AF92BF92C4E43F92D51675948
+67F08010F92E59735E74649A79CA5FF5606C62C8637B5BE75BD752AAF92F5974
+5F296012F930F931F9327459F933F934F935F936F937F93899D1F939F93AF93B
+F93CF93DF93EF93FF940F941F942F9436FC3F944F94581BF8FB260F1F946F947
+8166F948F9495C3FF94AF94BF94CF94DF94EF94FF950F9515AE98A25677B7D10
+F952F953F954F955F956F95780FDF958F9595C3C6CE5533F6EBA591A83360000
+D3
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00004E394EB64F4655AE571858C75F5665B765E66A806BB56E4D77ED7AEF7C1E
+7DDE86CB88929132935B64BB6FBE737A75B890545556574D61BA64D466C76DE1
+6E5B6F6D6FB975F0804381BD854189838AC78B5A931F6C9375537B548E0F905D
+5510580258585E626207649E68E075767CD687B39EE84EE35788576E59275C0D
+5CB15E365F85623464E173B381FA888B8CB8968A9EDB5B855FB760B350125200
+52305716583558575C0E5C605CF65D8B5EA65F9260BC63116389641768430000
+D4
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000068F96AC26DD86E216ED46FE471FE76DC777979B17A3B840489A98CED8DF3
+8E4890039014905390FD934D967697DC6BD27006725872A27368776379BF7BE4
+7E9B8B8058A960C7656665FD66BE6C8C711E71C98C5A98134E6D7A814EDD51AC
+51CD52D5540C61A76771685068DF6D1E6F7C75BC77B37AE580F484639285515C
+6597675C679375D87AC78373F95A8C469017982D5C6F81C0829A9041906F920D
+5F975D9D6A5971C8767B7B4985E48B0491279A30558761F6F95B76697F850000
+D5
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000863F87BA88F8908FF95C6D1B70D973DE7D61843DF95D916A99F1F95E4E82
+53756B046B12703E721B862D9E1E524C8FA35D5064E5652C6B166FEB7C437E9C
+85CD896489BD62C981D8881F5ECA67176D6A72FC7405746F878290DE4F865D0D
+5FA0840A51B763A075654EAE5006516951C968816A117CAE7CB17CE7826F8AD2
+8F1B91CF4FB6513752F554425EEC616E623E65C56ADA6FFE792A85DC882395AD
+9A629A6A9E979ECE529B66C66B77701D792B8F6297426190620065236F230000
+D6
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000714974897DF4806F84EE8F269023934A51BD521752A36D0C70C888C25EC9
+65826BAE6FC27C3E73754EE44F3656F9F95F5CBA5DBA601C73B27B2D7F9A7FCE
+8046901E923496F6974898189F614F8B6FA779AE91B496B752DEF960648864C4
+6AD36F5E7018721076E780018606865C8DEF8F0597329B6F9DFA9E75788C797F
+7DA083C993049E7F9E938AD658DF5F046727702774CF7C60807E512170287262
+78CA8CC28CDA8CF496F74E8650DA5BEE5ED6659971CE764277AD804A84FC0000
+D7
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000907C9B279F8D58D85A415C626A136DDA6F0F763B7D2F7E37851E893893E4
+964B528965D267F369B46D416E9C700F7409746075597624786B8B2C985E516D
+622E96784F96502B5D196DEA7DB88F2A5F8B61446817F961968652D2808B51DC
+51CC695E7A1C7DBE83F196754FDA52295398540F550E5C6560A7674E68A86D6C
+728172F874067483F96275E27C6C7F797FB8838988CF88E191CC91D096E29BC9
+541D6F7E71D0749885FA8EAA96A39C579E9F67976DCB743381E89716782C0000
+D8
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00007ACB7B207C926469746A75F278BC78E899AC9B549EBB5BDE5E556F20819C
+83AB90884E07534D5A295DD25F4E6162633D666966FC6EFF6F2B7063779E842C
+8513883B8F1399459C3B551C62B9672B6CAB8309896A977A4EA159845FD85FD9
+671B7DB27F548292832B83BD8F1E909957CB59B95A925BD06627679A68856BCF
+71647F758CB78CE390819B4581088C8A964C9A409EA55B5F6C13731B76F276DF
+840C51AA8993514D519552C968C96C94770477207DBF7DEC97629EB56EC50000
+D9
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000851151A5540D547D660E669D69276E9F76BF7791831784C2879F91699298
+9CF488824FAE519252DF59C65E3D61556478647966AE67D06A216BCD6BDB725F
+72617441773877DB801782BC83058B008B288C8C67286C90726776EE77667A46
+9DA96B7F6C92592267268499536F589359995EDF63CF663467736E3A732B7AD7
+82D7932852D95DEB61AE61CB620A62C764AB65E069596B666BCB712173F7755D
+7E46821E8302856A8AA38CBF97279D6158A89ED85011520E543B554F65870000
+DA
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00006C767D0A7D0B805E868A958096EF52FF6C95726954735A9A5C3E5D4B5F4C
+5FAE672A68B669636E3C6E4477097C737F8E85878B0E8FF797619EF45CB760B6
+610D61AB654F65FB65FC6C116CEF739F73C97DE195945BC6871C8B10525D535A
+62CD640F64B267346A386CCA73C0749E7B947C957E1B818A823685848FEB96F9
+99C14F34534A53CD53DB62CC642C6500659169C36CEE6F5873ED7554762276E4
+76FC78D078FB792C7D46822C87E08FD4981298EF52C362D464A56E246F510000
+DB
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000767C8DCB91B192629AEE9B435023508D574A59A85C285E475F77623F653E
+65B965C16609678B699C6EC278C57D2180AA8180822B82B384A1868C8A2A8B17
+90A696329F90500D4FF3F96357F95F9862DC6392676F6E43711976C380CC80DA
+88F488F589198CE08F29914D966A4F2F4F705E1B67CF6822767D767E9B445E61
+6A0A716971D4756AF9647E41854385E998DC4F107B4F7F7095A551E15E0668B5
+6C3E6C4E6CDB72AF7BC483036CD5743A50FB528858C164D86A9774A776560000
+DC
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000078A7861795E29739F965535E5F018B8A8FA88FAF908A522577A59C499F08
+4E19500251755C5B5E77661E663A67C468C570B3750175C579C97ADD8F279920
+9A084FDD582158315BF6666E6B656D116E7A6F7D73E4752B83E988DC89138B5C
+8F144F0F50D55310535C5B935FA9670D798F8179832F8514890789868F398F3B
+99A59C12672C4E764FF859495C015CEF5CF0636768D270FD71A2742B7E2B84EC
+8702902292D29CF34E0D4ED84FEF50855256526F5426549057E0592B5A660000
+DD
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00005B5A5B755BCC5E9CF9666276657765A76D6E6EA572367B267C3F7F368150
+8151819A8240829983A98A038CA08CE68CFB8D748DBA90E891DC961C964499D9
+9CE7531752065429567458B35954596E5FFF61A4626E66106C7E711A76C67C89
+7CDE7D1B82AC8CC196F0F9674F5B5F175F7F62C25D29670B68DA787C7E439D6C
+4E1550995315532A535159835A625E8760B2618A624962796590678769A76BD4
+6BD66BD76BD86CB8F968743575FA7812789179D579D87C837DCB7FE180A50000
+DE
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000813E81C283F2871A88E88AB98B6C8CBB9119975E98DB9F3B56AC5B2A5F6C
+658C6AB36BAF6D5C6FF17015725D73AD8CA78CD3983B61916C3780589A014E4D
+4E8B4E9B4ED54F3A4F3C4F7F4FDF50FF53F253F8550655E356DB58EB59625A11
+5BEB5BFA5C045DF35E2B5F99601D6368659C65AF67F667FB68AD6B7B6C996CD7
+6E23700973457802793E7940796079C17BE97D177D728086820D838E84D186C7
+88DF8A508A5E8B1D8CDC8D668FAD90AA98FC99DF9E9D524AF9696714F96A0000
+DF
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00005098522A5C7165636C5573CA7523759D7B97849C917897304E7764926BBA
+715E85A94E09F96B674968EE6E17829F8518886B63F76F81921298AF4E0A50B7
+50CF511F554655AA56175B405C195CE05E385E8A5EA05EC260F368516A616E58
+723D724072C076F879657BB17FD488F389F48A738C618CDE971C585E74BD8CFD
+55C7F96C7A617D2282727272751F7525F96D7B19588558FB5DBC5E8F5EB65F90
+60556292637F654D669166D966F8681668F27280745E7B6E7D6E7DD67F720000
+E0
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000080E5821285AF897F8A93901D92E49ECD9F205915596D5E2D60DC66146673
+67906C506DC56F5F77F378A984C691CB932B4ED950CA514855845B0B5BA36247
+657E65CB6E32717D74017444748774BF766C79AA7DDA7E557FA8817A81B38239
+861A87EC8A758DE3907892919425994D9BAE53685C5169546CC46D296E2B820C
+859B893B8A2D8AAA96EA9F67526166B96BB27E9687FE8D0D9583965D651D6D89
+71EEF96E57CE59D35BAC602760FA6210661F665F732973F976DB77017B6C0000
+E1
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00008056807281658AA091924E1652E26B726D177A057B397D30F96F8CB053EC
+562F58515BB55C0F5C115DE2624063836414662D68B36CBC6D886EAF701F70A4
+71D27526758F758E76197B117BE07C2B7D207D39852C856D86078A34900D9061
+90B592B797F69A374FD75C6C675F6D917C9F7E8C8B168D16901F5B6B5DFD640D
+84C0905C98E173875B8B609A677E6DDE8A1F8AA69001980C5237F9707051788E
+9396887091D74FEE53D755FD56DA578258FD5AC25B885CAB5CC05E2561010000
+E2
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000620D624B6388641C653665786A396B8A6C346D196F3171E772E973787407
+74B27626776179C07A577AEA7CB97D8F7DAC7E617F9E81298331849084DA85EA
+88968AB08B908F3890429083916C929692B9968B96A796A896D6970098089996
+9AD39B1A53D4587E59195B705BBF6DD16F5A719F742174B9808583FD5DE15F87
+5FAA604265EC6812696F6A536B896D356DF373E376FE77AC7B4D7D148123821C
+834084F485638A628AC49187931E980699B4620C88538FF092655D075D270000
+E3
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00005D69745F819D87686FD562FE7FD2893689724E1E4E5850E752DD5347627F
+66077E698805965E4F8D5319563659CB5AA45C385C4E5C4D5E025F11604365BD
+662F664267BE67F4731C77E2793A7FC5849484CD89968A668A698AE18C558C7A
+57F45BD45F0F606F62ED690D6B966E5C71847BD287558B588EFE98DF98FE4F38
+4F814FE1547B5A205BB8613C65B0666871FC7533795E7D33814E81E3839885AA
+85CE87038A0A8EAB8F9BF9718FC559315BA45BE660895BE95C0B5FC36C810000
+E4
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000F9726DF1700B751A82AF8AF64EC05341F97396D96C0F4E9E4FC45152555E
+5A255CE86211725982BD83AA86FE88598A1D963F96C599139D099D5D580A5CB3
+5DBD5E4460E1611563E16A026E2591029354984E9C109F775B895CB86309664F
+6848773C96C1978D98549B9F65A18B018ECB95BC55355CA95DD65EB56697764C
+83F495C758D362BC72CE9D284EF0592E600F663B6B8379E79D26539354C057C3
+5D16611B66D66DAF788D827E969897445384627C63966DB27E0A814B984D0000
+E5
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00006AFB7F4C9DAF9E1A4E5F503B51B6591C60F963F66930723A8036F97491CE
+5F31F975F9767D0482E5846F84BB85E58E8DF9774F6FF978F97958E45B436059
+63DA6518656D6698F97A694A6A236D0B7001716C75D2760D79B37A70F97B7F8A
+F97C8944F97D8B9391C0967DF97E990A57045FA165BC6F01760079A68A9E99AD
+9B5A9F6C510461B662916A8D81C6504358305F6671098A008AFA5B7C86164FFA
+513C56B4594463A96DF95DAA696D51864E884F59F97FF980F9815982F9820000
+E6
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000F9836B5F6C5DF98474B57916F9858207824583398F3F8F5DF9869918F987
+F988F9894EA6F98A57DF5F796613F98BF98C75AB7E798B6FF98D90069A5B56A5
+582759F85A1F5BB4F98E5EF6F98FF9906350633BF991693D6C876CBF6D8E6D93
+6DF56F14F99270DF71367159F99371C371D5F994784F786FF9957B757DE3F996
+7E2FF997884D8EDFF998F999F99A925BF99B9CF6F99CF99DF99E60856D85F99F
+71B1F9A0F9A195B153ADF9A2F9A3F9A467D3F9A5708E71307430827682D20000
+E7
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000F9A695BB9AE59E7D66C4F9A771C18449F9A8F9A9584BF9AAF9AB5DB85F71
+F9AC6620668E697969AE6C386CF36E366F416FDA701B702F715071DF7370F9AD
+745BF9AE74D476C87A4E7E93F9AFF9B082F18A608FCEF9B19348F9B29719F9B3
+F9B44E42502AF9B5520853E166F36C6D6FCA730A777F7A6282AE85DD8602F9B6
+88D48A638B7D8C6BF9B792B3F9B8971398104E944F0D4FC950B25348543E5433
+55DA586258BA59675A1B5BE4609FF9B961CA655665FF666468A76C5A6FB30000
+E8
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000070CF71AC73527B7D87088AA49C329F075C4B6C8373447389923A6EAB7465
+761F7A697E15860A514058C564C174EE751576707FC1909596CD99546E2674E6
+7AA97AAA81E586D987788A1B5A495B8C5B9B68A169006D6373A97413742C7897
+7DE97FEB81188155839E8C4C962E981166F05F8065FA67896C6A738B502D5A03
+6B6A77EE59165D6C5DCD7325754FF9BAF9BB50E551F9582F592D599659DA5BE5
+F9BCF9BD5DA262D76416649364FEF9BE66DCF9BF6A48F9C071FF7464F9C10000
+E9
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00007A887AAF7E477E5E80008170F9C287EF89818B209059F9C390809952617E
+6B326D747E1F89258FB14FD150AD519752C757C758895BB95EB8614269956D8C
+6E676EB6719474627528752C8073833884C98E0A939493DEF9C44E8E4F515076
+512A53C853CB53F35B875BD35C24611A618265F4725B7397744076C279507991
+79B97D067FBD828B85D5865E8FC2904790F591EA968596E896E952D65F6765ED
+6631682F715C7A3690C1980A4E91F9C56A526B9E6F907189801882B885530000
+EA
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000904B969596F297FB851A9B314E90718A96C45143539F54E15713571257A3
+5A9B5AC45BC36028613F63F46C856D396E726E907230733F745782D188818F45
+9060F9C6966298589D1B67088D8A925E4F4D504950DE5371570D59D45A015C09
+617066906E2D7232744B7DEF80C3840E8466853F875F885B89188B02905597CB
+9B4F4E734F915112516AF9C7552F55A95B7A5BA55E7C5E7D5EBE60A060DF6108
+610963C465386709F9C867D467DAF9C9696169626CB96D27F9CA6E38F9CB0000
+EB
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00006FE173367337F9CC745C7531F9CD7652F9CEF9CF7DAD81FE843888D58A98
+8ADB8AED8E308E42904A903E907A914991C9936EF9D0F9D15809F9D26BD38089
+80B2F9D3F9D45141596B5C39F9D5F9D66F6473A780E48D07F9D79217958FF9D8
+F9D9F9DAF9DB807F620E701C7D68878DF9DC57A0606961476BB78ABE928096B1
+4E59541F6DEB852D967097F398EE63D66CE3909151DD61C981BA9DF94F9D501A
+51005B9C610F61FF64EC69056BC5759177E37FA98264858F87FB88638ABC0000
+EC
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00008B7091AB4E8C4EE54F0AF9DDF9DE593759E8F9DF5DF25F1B5F5B6021F9E0
+F9E1F9E2F9E3723E73E5F9E4757075CDF9E579FBF9E6800C8033808482E18351
+F9E7F9E88CBD8CB39087F9E9F9EA98F4990CF9EBF9EC703776CA7FCA7FCC7FFC
+8B1A4EBA4EC152035370F9ED54BD56E059FB5BC55F155FCD6E6EF9EEF9EF7D6A
+8335F9F086938A8DF9F1976D9777F9F2F9F34E004F5A4F7E58F965E56EA29038
+93B099B94EFB58EC598A59D96041F9F4F9F57A14F9F6834F8CC3516553440000
+ED
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000F9F7F9F8F9F94ECD52695B5582BF4ED4523A54A859C959FF5B505B575B5C
+606361486ECB7099716E738674F775B578C17D2B800581EA8328851785C98AEE
+8CC796CC4F5C52FA56BC65AB6628707C70B872357DBD828D914C96C09D725B71
+68E76B986F7A76DE5C9166AB6F5B7BB47C2A883696DC4E084ED75320583458BB
+58EF596C5C075E335E845F35638C66B267566A1F6AA36B0C6F3F7246F9FA7350
+748B7AE07CA7817881DF81E7838A846C8523859485CF88DD8D1391AC95770000
+EE
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000969C518D54C957285BB0624D6750683D68936E3D6ED3707D7E2188C18CA1
+8F099F4B9F4E722D7B8F8ACD931A4F474F4E5132548059D05E9562B56775696E
+6A176CAE6E1A72D9732A75BD7BB87D3582E783F9845785F78A5B8CAF8E879019
+90B896CE9F5F52E3540A5AE15BC2645865756EF472C4F9FB76847A4D7B1B7C4D
+7E3E7FDF837B8B2B8CCA8D648DE18E5F8FEA8FF9906993D14F434F7A50B35168
+5178524D526A5861587C59605C085C555EDB609B623068136BBF6C086FB10000
+EF
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000714E742075307538755176727B4C7B8B7BAD7BC67E8F8A6E8F3E8F49923F
+92939322942B96FB985A986B991E5207622A62986D5976647ACA7BC07D765360
+5CBE5E976F3870B97C9897119B8E9EDE63A5647A87764E014E954EAD505C5075
+544859C35B9A5E405EAD5EF75F8160C5633A653F657465CC6676667867FE6968
+6A896B636C406DC06DE86E1F6E5E701E70A1738E73FD753A775B7887798E7A0B
+7A7D7CBE7D8E82478A028AEA8C9E912D914A91D8926692CC9320970697560000
+F0
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000975C98029F0E52365291557C58245E1D5F1F608C63D068AF6FDF796D7B2C
+81CD85BA88FD8AF88E44918D9664969B973D984C9F4A4FCE514651CB52A95632
+5F145F6B63AA64CD65E9664166FA66F9671D689D68D769FD6F156F6E716771E5
+722A74AA773A7956795A79DF7A207A957C977CDF7D447E70808785FB86A48A54
+8ABF8D998E819020906D91E3963B96D59CE565CF7C078DB393C35B585C0A5352
+62D9731D50275B975F9E60B0616B68D56DD9742E7A2E7D427D9C7E31816B0000
+F1
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00008E2A8E35937E94184F5057505DE65EA7632B7F6A4E3B4F4F4F8F505A59DD
+80C4546A546855FE594F5B995DDE5EDA665D673167F1682A6CE86D326E4A6F8D
+70B773E075877C4C7D027D2C7DA2821F86DB8A3B8A858D708E8A8F339031914E
+9152944499D07AF97CA54FCA510151C657C85BEF5CFB66596A3D6D5A6E966FEC
+710C756F7AE388229021907596CB99FF83014E2D4EF2884691CD537D6ADB696B
+6C41847A589E618E66FE62EF70DD751175C77E5284B88B498D084E4B53EA0000
+F2
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000054AB573057405FD763016307646F652F65E8667A679D67B36B626C606C9A
+6F2C77E57825794979577D1980A2810281F3829D82B787188A8CF9FC8D048DBE
+907276F47A197A377E548077550755D45875632F64226649664B686D699B6B84
+6D256EB173CD746874A1755B75B976E1771E778B79E67E097E1D81FB852F8897
+8A3A8CD18EEB8FB0903293AD9663967397074F8453F159EA5AC95E19684E74C6
+75BE79E97A9281A386ED8CEA8DCC8FED659F6715F9FD57F76F577DDD8F2F0000
+F3
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000093F696C65FB561F26F844E144F98501F53C955DF5D6F5DEE6B216B6478CB
+7B9AF9FE8E498ECA906E6349643E77407A84932F947F9F6A64B06FAF71E674A8
+74DA7AC47C127E827CB27E988B9A8D0A947D9910994C52395BDF64E6672D7D2E
+50ED53C358796158615961FA65AC7AD98B928B9650095021527555315A3C5EE0
+5F706134655E660C663666A269CD6EC46F32731676217A938139825983D684BC
+50B557F05BC05BE85F6963A178267DB583DC852191C791F5518A67F57B560000
+F4
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00008CAC51C459BB60BD8655501CF9FF52545C3A617D621A62D364F265A56ECC
+7620810A8E60965F96BB4EDF5343559859295DDD64C56CC96DFA73947A7F821B
+85A68CE48E10907791E795E1962197C651F854F255865FB964A46F887DB48F1F
+8F4D943550C95C166CBE6DFB751B77BB7C3D7C648A798AC2581E59BE5E166377
+7252758A776B8ADC8CBC8F125EF366746DF8807D83C18ACB97519BD6FA005243
+66FF6D956EEF7DE08AE6902E905E9AD4521D527F54E86194628462DB68A20000
+F5
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00006912695A6A3570927126785D7901790E79D27A0D8096827882D583498549
+8C828D859162918B91AE4FC356D171ED77D7870089F85BF85FD6675190A853E2
+585A5BF560A4618164607E3D80708525928364AE50AC5D146700589C62BD63A8
+690E69786A1E6E6B76BA79CB82BB84298ACF8DA88FFD9112914B919C93109318
+939A96DB9A369C0D4E11755C795D7AFA7B517BC97E2E84C48E598E748EF89010
+6625693F744351FA672E9EDC51455FE06C9687F2885D887760B481B584030000
+F6
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00008D0553D6543956345A365C31708A7FE0805A810681ED8DA391899A5F9DF2
+50744EC453A060FB6E2C5C644F88502455E45CD95E5F606568946CBB6DC471BE
+75D475F476617A1A7A497DC77DFB7F6E81F486A98F1C96C999B39F52524752C5
+98ED89AA4E0367D26F064FB55BE267956C886D78741B782791DD937C87C479E4
+7A315FEB4ED654A4553E58AE59A560F0625362D6673669558235964099B199DD
+502C53535544577CFA016258FA0264E2666B67DD6FC16FEF742274388A170000
+F7
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000094385451560657665F48619A6B4E705870AD7DBB8A95596A812B63A27708
+803D8CAA5854642D69BB5B955E116E6FFA038569514C53F0592A6020614B6B86
+6C706CF07B1E80CE82D48DC690B098B1FA0464C76FA464916504514E5410571F
+8A0E615F6876FA0575DB7B527D71901A580669CC817F892A9000983950785957
+59AC6295900F9B2A615D727995D657615A465DF4628A64AD64FA67776CE26D3E
+722C743678347F7782AD8DDB981752245742677F724874E38CA98FA692110000
+F8
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000962A516B53ED634C4F695504609665576C9B6D7F724C72FD7A1789878C9D
+5F6D6F8E70F981A8610E4FBF504F624172477BC77DE87FE9904D97AD9A198CB6
+576A5E7367B0840D8A5554205B165E635EE25F0A658380BA853D9589965B4F48
+5305530D530F548654FA57035E036016629B62B16355FA066CE16D6675B17832
+80DE812F82DE846184B2888D8912900B92EA98FD9B915E4566B466DD70117206
+FA074FF5527D5F6A615367536A196F0274E2796888688C7998C798C49A430000
+F9
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000054C17A1F69538AF78C4A98A899AE5F7C62AB75B276AE88AB907F96425339
+5F3C5FC56CCC73CC7562758B7B4682FE999D4E4F903C4E0B4F5553A6590F5EC8
+66306CB37455837787668CC09050971E9C1558D15B7886508B149DB45BD26068
+608D65F16C576F226FA3701A7F557FF095919592965097D352728F4451FD542B
+54B85563558A6ABB6DB57DD88266929C96779E79540854C876D286E495A495D4
+965C4EA24F0959EE5AE65DF760526297676D68416C866E2F7F38809B822A0000
+FA
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000FA08FA0998054EA5505554B35793595A5B695BB361C869776D77702387F9
+89E38A728AE7908299ED9AB852BE683850165E78674F8347884C4EAB541156AE
+73E6911597FF9909995799995653589F865B8A3161B26AF6737B8ED26B4796AA
+9A57595572008D6B97694FD45CF45F2661F8665B6CEB70AB738473B973FE7729
+774D7D437D627E2382378852FA0A8CE29249986F5B517A74884098015ACC4FE0
+5354593E5CFD633E6D7972F98105810783A292CF98304EA851445211578B0000
+FB
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00005F626CC26ECE7005705070AF719273E97469834A87A28861900890A293A3
+99A8516E5F5760E0616766B385598E4A91AF978B4E4E4E92547C58D558FA597D
+5CB55F2762366248660A66676BEB6D696DCF6E566EF86F946FE06FE9705D72D0
+7425745A74E07693795C7CCA7E1E80E182A6846B84BF864E865F87748B778C6A
+93AC9800986560D1621691775A5A660F6DF76E3E743F9B425FFD60DA7B0F54C4
+5F186C5E6CD36D2A70D87D0586798A0C9D3B5316548C5B056A3A706B75750000
+FC
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000798D79BE82B183EF8A718B418CA89774FA0B64F4652B78BA78BB7A6B4E38
+559A59505BA65E7B60A363DB6B61666568536E19716574B07D0890849A699C25
+6D3B6ED1733E8C4195CA51F05E4C5FA8604D60F66130614C6643664469A56CC1
+6E5F6EC96F62714C749C76877BC17C27835287579051968D9EC3532F56DE5EFB
+5F8A6062609461F7666667036A9C6DEE6FAE7070736A7E6A81BE833486D48AA8
+8CC4528373725B966A6B940454EE56865B5D6548658566C9689F6D8D6DC60000
+FD
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000723B80B491759A4D4FAF5019539A540E543C558955C55E3F5F8C673D7166
+73DD900552DB52F3586458CE7104718F71FB85B08A13668885A855A76684714A
+8431534955996BC15F595FBD63EE668971478AF18F1D9EBE4F11643A70CB7566
+866760648B4E9DF8514751F653086D3680F89ED166156B23709875D554035C79
+7D078A166B206B3D6B46543860706D3D7FD5820850D651DE559C566B56CD59EC
+5B095E0C619961986231665E66E6719971B971BA72A779A77A007FB28A700000
diff --git a/library/encoding/gb12345.enc b/library/encoding/gb12345.enc
new file mode 100644
index 0000000..3f3f4d2
--- /dev/null
+++ b/library/encoding/gb12345.enc
@@ -0,0 +1,1414 @@
+# Encoding file: gb12345, double-byte
+D
+233F 0 83
+21
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000030003001300230FB02C902C700A8300330052015FF5E2225202620182019
+201C201D3014301530083009300A300B300C300D300E300F3016301730103011
+00B100D700F72236222722282211220F222A222922082237221A22A522252220
+23122299222B222E2261224C2248223D221D2260226E226F22642265221E2235
+22342642264000B0203220332103FF0400A4FFE0FFE1203000A7211626062605
+25CB25CF25CE25C725C625A125A025B325B2203B219221902191219330130000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+22
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000024882489248A248B248C248D248E248F2490249124922493249424952496
+249724982499249A249B247424752476247724782479247A247B247C247D247E
+247F248024812482248324842485248624872460246124622463246424652466
+2467246824690000000032203221322232233224322532263227322832290000
+00002160216121622163216421652166216721682169216A216B000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+23
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000FF01FF02FF03FFE5FF05FF06FF07FF08FF09FF0AFF0BFF0CFF0DFF0EFF0F
+FF10FF11FF12FF13FF14FF15FF16FF17FF18FF19FF1AFF1BFF1CFF1DFF1EFF1F
+FF20FF21FF22FF23FF24FF25FF26FF27FF28FF29FF2AFF2BFF2CFF2DFF2EFF2F
+FF30FF31FF32FF33FF34FF35FF36FF37FF38FF39FF3AFF3BFF3CFF3DFF3EFF3F
+FF40FF41FF42FF43FF44FF45FF46FF47FF48FF49FF4AFF4BFF4CFF4DFF4EFF4F
+FF50FF51FF52FF53FF54FF55FF56FF57FF58FF59FF5AFF5BFF5CFF5DFFE30000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+24
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000304130423043304430453046304730483049304A304B304C304D304E304F
+3050305130523053305430553056305730583059305A305B305C305D305E305F
+3060306130623063306430653066306730683069306A306B306C306D306E306F
+3070307130723073307430753076307730783079307A307B307C307D307E307F
+3080308130823083308430853086308730883089308A308B308C308D308E308F
+3090309130923093000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+25
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000030A130A230A330A430A530A630A730A830A930AA30AB30AC30AD30AE30AF
+30B030B130B230B330B430B530B630B730B830B930BA30BB30BC30BD30BE30BF
+30C030C130C230C330C430C530C630C730C830C930CA30CB30CC30CD30CE30CF
+30D030D130D230D330D430D530D630D730D830D930DA30DB30DC30DD30DE30DF
+30E030E130E230E330E430E530E630E730E830E930EA30EB30EC30ED30EE30EF
+30F030F130F230F330F430F530F6000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+26
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000039103920393039403950396039703980399039A039B039C039D039E039F
+03A003A103A303A403A503A603A703A803A90000000000000000000000000000
+000003B103B203B303B403B503B603B703B803B903BA03BB03BC03BD03BE03BF
+03C003C103C303C403C503C603C703C803C90000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+27
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000004100411041204130414041504010416041704180419041A041B041C041D
+041E041F0420042104220423042404250426042704280429042A042B042C042D
+042E042F00000000000000000000000000000000000000000000000000000000
+000004300431043204330434043504510436043704380439043A043B043C043D
+043E043F0440044104420443044404450446044704480449044A044B044C044D
+044E044F00000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+28
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000010100E101CE00E0011300E9011B00E8012B00ED01D000EC014D00F301D2
+00F2016B00FA01D400F901D601D801DA01DC00FC00EA00000000000000000000
+0000000000000000000031053106310731083109310A310B310C310D310E310F
+3110311131123113311431153116311731183119311A311B311C311D311E311F
+3120312131223123312431253126312731283129000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+29
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00000000000000002500250125022503250425052506250725082509250A250B
+250C250D250E250F2510251125122513251425152516251725182519251A251B
+251C251D251E251F2520252125222523252425252526252725282529252A252B
+252C252D252E252F2530253125322533253425352536253725382539253A253B
+253C253D253E253F2540254125422543254425452546254725482549254A254B
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+30
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000554A963F57C3632854CE550954C0769A764C85F977EE827E7919611B9698
+978D6C285B894FFA630966975CB880FA68489AAF660276CE51F9655671AC7FF1
+895650B2596561CA6FB382AD634C625253ED54277B06516B75A45DF462D48DCB
+9776628A801958E997387F777238767D67CF767E64FA4F70655762DC7A176591
+73ED642C6273822C9812677F7248626E62CC4F3474E3534A8FA67D4690A65E6B
+6886699C81807D8168D278C5868C938A508D8B1782DE80DE5305891252650000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+31
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000858496F94FDD582198FD5BF662B1583166B48C799B917206676F789160B2
+535153178F2980CC8C9D92C7500D72FD5099618A711988AB595482EF672C7B28
+5D297DB3752D6CF58E668FF8903C9F3B6BD491197B465F7C78A784D6853D7562
+65836BD65E635E8775F99589655D5F0A5FC58F9F58C181C2907F965B97AD908A
+7DE88CB662414FBF8B8A535E8FA88FAF8FAE904D6A195F6A819888689C49618B
+522B765F5F6C658C70156FF18CD364EF517551B067C44E1979C9990570B30000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+32
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000075C55E7673BB83E064AD64A592626CE2535A52C3640F92517B944F2F5E1B
+82368116818A6E246CCA99C16355535C54FA88DC57E04E0D5E036B657C3F90E8
+601664E6731C88C16750624D8CA1776C8E2991C75F6983DC8521991053C38836
+6B98615A615871E684BC825950096EC485CF64CD7CD969FD66F9834953A07B56
+5074518C6E2C5C648E6D63D253C9832C833667E578B4643D5BDF5C945DEE8A6B
+62C667F48C7A6519647B87EC995E8B927E8F93DF752395E1986B660C73160000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+33
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000583456175E389577511F81785EE0655E66A2553150218D8562849214671D
+56326F6E5DE2543570928ECA626F64A463A35FB96F8890F481E38FB058756668
+5FF16C8996738D81896F64917A3157CE6A59621054484E587A0B61F26F848AA0
+627F901E9A0179E4540375F4630153196C6090725F1B99B3803B9F524F885C3A
+8D647FC565A571BE5145885D87F25D075BF562BD916C75878E8A7A2061017C4C
+4EC77DA27785919C81ED521D51FA6A7153A88E8792E496DB6EC19664695A0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+34
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000790E513277D7641089F8865563E35DDD7A7F693D50B3823955984E327621
+7A975E625E8A95D652755439708A6376931857826625693F918755076DF37D14
+882262337DBD75B5832878C196CC8FAD614874F78A5E6B64523A8CDC6B218070
+847156F153065F9E53E251D17C97918B7C074FC38EA57BE17AC464675D1450AC
+810676017CB96DEC7FE067515B585BF878CB64AE641363AA632B932F642D9054
+7B5476296253592754466B7950A362345E366B864EE38CB8888B5F85902E0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+35
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00006020803D64D44E3955AE913264A381BD65E66C2E4F46619A6DE18A955F48
+86CB757664CB9EE885696A94520064178E4850125CF679B15C0E52307A3B60BC
+905376D75FB75F9776848E6C71C8767B7B4977AA51F3912758244F4E6EF48FEA
+65757B1B72C46ECC7FDF5AE162B55E95573084827B2C5E1D5F1F905E7DE0985B
+63826EC778989EDE5178975B588A96FB4F4375385E9760E659606FB16BBF7889
+53FC96D551CB52016389540A91E38ABF8DCC7239789F87768FED8ADC758A0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+36
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00004E0176EF53EE91D898029F0E93205B9A8A024E22677151AC846361C252D5
+68DF4F97606B51CD6D1E515C62969B2596618C46901775D890FD77636BD272A2
+73688B80583577798CED675C934D809A5EA66E2159927AEF77ED935B6BB565B7
+7DDE58065151968A5C0D58A956788E726566981356E4920D76FE9041638754C6
+591A596A579B8EB267358DFA8235524160F058AE86FE5CE89D5D4FC4984D8A1B
+5A2560E15384627C904F910299136069800C51528033723E990C6D314E8C0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+37
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00008CB3767C7F707B4F4F104E4F95A56CD573D085E95E06756A7FFB6A0A792C
+91E97E4151E1716953CD8FD47BC48CA972AF98EF6CDB574A82B365B980AA623F
+963259A84EFF8A2A7D21653E83F2975E556198DB80A5532A8AB9542080BA5EE2
+6CB88CBB82AC915A54296C1B52067D1B58B3711A6C7E7C89596E4EFD5FFF61A4
+7CDE8C505C01695387025CF092D298A8760B70FD902299AE7E2B8AF759499CF3
+4F5B5426592B6577819A5B75627662C28F3B5E456C1F7B264F0F4FD8670D0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+38
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00006D6E6DAA798F88B15F17752B64AB8F144FEF91DC65A7812F81515E9C8150
+8D74526F89868CE65FA950854ED8961C723681798CA05BCC8A0396445A667E1B
+54905676560E8A7265396982922384CB6E895E797518674667D17AFF809D8D95
+611F79C665628D1B5CA1525B92FC7F38809B7DB15D176E2F67607BD9768B9AD8
+818F7F947CD5641E93AC7A3F544A54E56B4C64F162089D3F80F3759952729769
+845B683C86E495A39694927B500B54047D6668398DDF801566F45E9A7FB90000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+39
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000057C2803F68975DE5653B529F606D9F944F9B8EAC516C5BAB5F13978F6C5E
+62F18CA25171920E52FE6E9D82DF72D757A269CB8CFC591F8F9C83C754957B8D
+4F306CBD5B6459D19F1353E488319AA88C3780A16545986756FA96C7522E74DC
+526E5BE1630289024E5662D0602A68FA95DC5B9851A089C07BA199287F506163
+704C8CAB51495EE3901B7470898F572D78456B789F9C95A88ECC9B3C8A6D7678
+68426AC38DEA8CB4528A8F256EDA68CD934B90ED570B679C88F9904E54C80000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+3A
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00009AB85B696D776C264EA55BB399ED916361A890AF97D3542B6DB55BD251FD
+558A7F557FF064BC634D65F161BE608D710A6C576F22592F676D822A58D5568E
+8C6A6BEB90DD597D8017865F6D695475559D837783CF683879BE548C4F555408
+76D28C8995A16CB36DB88D6B89109DB48CC0563F9ED175D55F8872E0606854FC
+4EA86A2A886160528F5F54C470D886799D3B6D2A5B8F5F187D0555894FAF7334
+543C539A50195F8C547C4E4E5FFD745A58FA846B80E1877472D07CCA6E560000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+3B
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00005F27864E552C8B774E926EEC623782B1562983EF733E6ED1756B52835316
+8A7169D05F8A61F76DEE58DE6B6174B0685390847DE963DB60A3559A76138C62
+71656E195BA65E7B8352614C9EC478FA87577C27768751F060F6714C66435E4C
+604D8B0A707063EE8F1D5FBD606286D456DE6BC160946167534960E066668CC4
+7A62670371F4532F8AF18AA87E6A8477660F5A5A9B426E3E6DF78C416D3B4F19
+706B7372621660D1970D8CA8798D64CA573E57FA6A5F75787A3D7A4D7B950000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+3C
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000808C99518FF96FC08B4F9DC459EC7E3E7DDD5409697568D88F2F7C4D96C6
+53CA602575BE6C7253735AC97D1A64E05E7E810A5DF1858A628051805B634F0E
+796D529160B86FDF5BC45BC28A088A1865E25FCC969B59937E7C7D00560967B7
+593E4F735BB652A083A298308CC87532924050477A3C50F967B699D55AC16BB2
+76E358055C167B8B9593714E517C80A9827159787DD87E6D6AA267EC78B19E7C
+63C064BF7C215109526A51CF85A66ABB94528E108CE4898B93757BAD4EF60000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+3D
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000050658266528D991E6F386FFA6F975EFA50F559DC5C076F3F6C5F75868523
+69F3596C8B1B532091AC964D854969127901712681A04EA490CA6F869A555B0C
+56BC652A927877EF50E5811A72E189D299037E737D5E527F655991758F4E8F03
+53EB7A9663ED63A5768679F88857968E622A52AB7BC0685467706377776B7AED
+6F547D5089E359D0621285C982A5754C501F4ECB75A58AA15C4A5DFE7B4B65A4
+91D14ECA6D25895F7DCA932650C58B3990329773664979818FD171FC6D780000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+3E
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000076E152C1834651628396775B66769BE84EAC9A5A7CBE7CB37D934E958B66
+666F9838975C5883656C93E15F9175D997567ADF7AF651C870AF7A9863EA7A76
+7CFE739697ED4E4570784E5D915253A96551820A81FC8205548E5C31759A97A0
+62D872D975BD5C4599D283CA5C40548077E982096CAE805A62D264DA5DE85177
+8DDD8E1E92F84FF153E561FC70AC528763509D515A1F5026773753777D796485
+652B628963985014723589BA51B38A237D76574783CC921E8ECD541B5CFB0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+3F
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00004FCA7AE36D5A90E199FF55805496536154AF958B63E9697751F16168520A
+582A52D8574E780D770B5EB761777CE0625B62974EA27095800362F770E49760
+577782DB67EF68F578D5984679D16BBB54B353EF6E34514B523B5BA28AB280AF
+554358BE61C75751542D7A7A60505B5463A7647353E362635BC767AF54ED7A9F
+82E691775EAB89328A8757AE630E8DE880EF584A7B7751085FEB5BEC6B3E5321
+7B5072C268467926773666E051B5866776D45DCB7ABA8475594E9B4150800000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+40
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000994B61276F7057646606634656F062EC64F45ED395CA578362C95587881F
+81D88FA35566840A4F868CF485CD5A6A6B0465147C4395CC862D703E8B95652C
+89BD61F67E9C721B6FEB7405699472FC5ECA90CE67176D6A648852DE72628001
+4F6C59E5916A70D96F8752D26A0296F79433857E78CA7D2F512158D864C2808B
+985E6CEA68F1695E51B7539868A872819ECE7C6C72F896E270557406674E88CF
+9BC979AE83898354540F68179E9753B252F5792B6B77522950884F8B4FD00000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+41
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000075E27ACB7C92701D96B8529B748354E95006806F84EE9023942E5EC96190
+6F237C3E658281C993C8620071497DF47CE751C968817CB1826F51698F1B91CF
+667E4EAE8AD264A9804A50DA764271CE5BE5907C6F664E86648294105ED66599
+521788C270C852A373757433679778F7971681E891309C576DCB51DB8CC3541D
+62CE73B283F196F69F6192344F367F9A51CC974896755DBA981853E64EE46E9C
+740969B4786B993E7559528976246D4167F3516D9F8D807E56A87C607ABF0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+42
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000968658DF650F96B46A135A41645F7C0D6F0F964B860676E798715EEC7210
+64C46EF7865C9B6F9E93788C97328DEF8CC29E7F6F5E798493329678622E9A62
+541592C14FA365C55C655C627E37616E6C2F5F8B73876FFE7DD15DD265235B7F
+706453754E8263A0756563848F2A502B4F966DEA7DB88AD6863F87BA7F85908F
+947C7C6E9A3E88F8843D6D1B99F17D615ABD9EBB746A78BC879E99AC99E1561B
+55CE57CB8CB79EA58CE390818109779E9945883B6EFF851366FC61626F2B0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+43
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00008B3E8292832B76F26C135FD983BD732B830593286BDB77DB925A536F8302
+51925E3D8C8C8CBF9EBD73AB679A68859176970971646CA177095A9293826BCF
+7F8E66275BD059B95A9A958060B65011840C84996AAC76DF9333731B59225B5F
+772F919A97617CDC8FF78B0E5F4C7C7379D889936CCC871C5BC65E4268C97720
+7DBF5195514D52C95A297DEC976282D763CF778485D079D26E3A5EDF59998511
+6EC56C1162BF76BF654F61AB95A9660E879F9CF49298540D547D8B2C64780000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+44
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000647986116A21819C78E864699B5462B9672B83AB58A89ED86CAB6F205BDE
+964C8B00725F67D062C77261755D59C66BCD589366AE5E5552DF6155672876EE
+776672677A4662FF54EA5450920990A35A1C7D0D6C164E435976801059485357
+753796E356CA6493816660F19B276DD65462991251855AE980FD59AE9713502A
+6CE55C3C64EC4F60533F81A990066EBA852B62C85E7478BE6506637B5FF55A18
+91C09CE55C3F634F80765B7D5699947793B36D8560A86AB8737051DD5BE70000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+45
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000064F06FD8725B626D92157D1081BF6FC38FB25F04597452AA601259736696
+86507627632A61E67CEF8AFE54E66B509DD76BC685D5561450766F1A556A8DB4
+722C5E156015743662CD6392724C5F986E436D3E65006F5876E478D076FC7554
+522453DB4E539F9065C1802A80D6629B5486522870AE888D8DD16CE1547880DA
+57F988F48CE0966A914D4F696C9B567476C6783062A870F96F8E5F6D84EC68DA
+787C7BF781A8670B9D6C636778B0576F78129739627962AB528874356BD70000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+46
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00005564813E75B276AE533975DE50FB5C418B6C7BC7504F72479A1998C46F02
+74E27968648777A562FC983B8CA754C180584E52576A860B840D5E73619174F6
+8A555C4F57616F5198175A4678349B448FEB7C95525664B292EA50D583868461
+83E984B257D46A385703666E6D668B5C66DD7011671F6B3A68F2621A59BB4E03
+51C46F0667D26C8F517668CB59476B6775665D0E81CD9F4A65D7794879419A0E
+8D778C484E5E4F0155535951780C56686C238FC468C46C7D6CE38A1663900000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+47
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000060706D3D727D626691FA925B534390777C3D4EDF8B194E7E9ED493229257
+524D6F5B90636DFA8B7458795D4C6B206B4969CD55C681547F8C58BB85945F3A
+64366A47936C657260846A4B77A755AC50D15DE7979864AC7FF95CED4FCF7AC5
+520783044E14602F7ACA6B3D4FB589AA79E6743452E482B964D279BD5BE26C81
+97528F156C2B50BE537F6E0564CE66746C3060C598038ACB617674CA7AAE79CB
+4E1890B174036C4256DA914B6CC58DA8534086C666F28EC05C489A456E200000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+48
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000053D65A369F728DA353BB570898746B0A919B6CC9516875CA62F372AC5238
+52F87F3A7094763853749D7269B778BA96C088D97FA4713671C3518967D374E4
+58E4651856B78B93995264FE7E5E60F971B158EC4EC14EBA5FCD97CC4EFB8A8D
+5203598A7D0962544ECD65E5620E833884C969AE878D71946EB65BB97D685197
+63C967D480898339881551125B7A59828FB14E736C5D516589258EDF962E854A
+745E92ED958F6F6482E55F316492705185A9816E9C13585E8CFD4E0953C10000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+49
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000050986563685155D355AA64149A3763835AC2745F82726F8068EE50E7838E
+78026BBA52396C997D1750BB5565715E7BE966EC73CA82EB67495C715220717D
+886B9583965D64C58D0D81B355846C5562477E55589250B755468CDE664C4E0A
+5C1A88F368A2634E7A0D71D2828D52FA97F65C1154E890B57D3959628CD286C7
+820C63688D66651D5C0461FE6D89793E8A2D78377533547B4F388EAB6DF15A20
+7D33795E6C885BE95B38751A814E614E6EF28072751F7525727253477E690000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+4A
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000770176DB526952DD80565E2B5931734565BD6FD58A695C388671534177F3
+62FE66424EC098DF87555BE68B5853F277E24F7F5C4E99DB59CB5F0F793A58EB
+4E1667FF4E8B62ED8A93901D52E2662F55DC566C90694ED54F8D91CB98FE6C0F
+5E0260435BA489968A666536624B99965B8858FD6388552E53D776267378852C
+6A1E68B36B8A62928F3853D482126DD1758F66F88D165B70719F85AF669166D9
+7F7287009ECD9F205C6C88538FF06A39675F620D7AEA58855EB665786F310000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+4B
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000060555237800D6454887075295E25681362F4971C96D9723D8AB06C347761
+7A0E542E77AC9806821C8AAC78A96714720D65AF64955636601D79C153F87D72
+6B7B80865BFA55E356DB4F3A4F3C98FC5DF39B068073616B980C90015B8B8A1F
+8AA6641C825864FB55FD860791654FD77D20901F7C9F50F358516EAF5BBF8A34
+80859178849C7B9796D6968B96A87D8F9AD3788E6B727A57904296A7795F5B6B
+640D7B0B84D168AD55067E2E74637D2293966240584C4ED65B83597958540000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+4C
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000737A64BB8E4B8E0F80CE82D462AC81FA6CF0915E592A614B6C70574D6524
+8CAA7671705858C76A8075F06F6D8B5A8AC757666BEF889278B363A2560670AD
+6E6F5858642A580268E0819B55107CD650188EBA6DCC8D9F71D9638F6FE46ED4
+7E278404684390036DD896768A0E5957727985E49A3075BC8B0468AF52548E22
+92BB63D0984C8E44557C9AD466FF568F60D56D9552435C4959296DFB586B7530
+751C606C821481466311689D8FE2773A8DF38CBC94355E165EF3807D70F40000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+4D
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00006C405EF7505C4EAD5EAD633A8247901A6850916E77B3540C92855F647AE5
+687663457B527D7175DB50776295982D900F51F879C37A8157165F9290145857
+5C60571F541051546E4D571863A8983D817F8715892A9000541E5C6F81C062D6
+625881319D15964099B199DD6A6259A562D3553E631654C786D97AAA5A0374E6
+896A6B6A59168C4C5F4E706373A998114E3870F75B8C7897633D665A769660CB
+5B9B5A49842C81556C6A738B4EA167897DB25F8065FA671B5FD859845A010000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+4E
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00005DCD5FAE537197CB90556845570D552F60DF72326FF07DAD8466840E59D4
+504950DE5C3E7DEF672A851A5473754F80C355829B4F4F4D6E2D8B025C096170
+885B761F6E29868A6587805E7D0B543B7A697D0A554F55E17FC174EE64BE8778
+6E267AA9621165A1536763E16C835DEB55DA93A270CF6C618AA35C4B7121856A
+68A7543E54346BCB6B664E9463425348821E4F0D4FAE5862620A972766647269
+52FF52D9609F8AA4661471996790897F785277FD6670563B5438932B72A70000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+4F
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00007A00606F5E0C6089819D591560DC718470EF6EAA6C5072806A8489725E2D
+7FD25AB3559C92916D177CFB969962327D30778E87665323971E8F4466875CFD
+4FE072F94E0B53A6590F56876380934151484ED99BAE7E9654B88CE2929C8237
+95916D8E5F265ACC986F96AA73FE737B7E23817A99217FA161B2967796507DAB
+76F853A2947299997BB189446E5891097FD479658A7360F397FF4EAB98055DF7
+6A6150CF54118C61856D785D9704524A54EE56C292B76D885BB56DC666C90000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+50
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00005C0F5B5D68218096562F7B11654869544E9B6B47874E978B5354633E643A
+90AA659C81058AE75BEB68B0537887F961C86CC470098B1D5C5185AA82AF92C5
+6B238F9B65B05FFB5FC34FE191C1661F8165732960FA82085211578B5F6290A2
+884C91925E78674F602759D3514451F680F853086C7996C4718A4F114FEE7F9E
+673D55C592B979C088967D89589F620C9700865A561898085F908A3184C49157
+53D965ED5E8F755C60647D6E5A7F7DD27E8C8ED255A75BA361F865CB73840000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+51
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00009078766C77297D629774859B5B787A7496EA884052DB718F5FAA65EC8A62
+5C0B99B45DE16B896C5B8A138A0A905C8FC558D362BC9D099D2854404E2B82BD
+7259869C5D1688596DAF96C5555E4E9E8A1D710954BD95B970DF6DF99E7D56B4
+781487125CA95EF68A00985495BB708E6CBF594463A9773C884D6F1482775830
+71D553AD786F96C155015F6671305BB48AFA9A576B83592E9D2679E7694A63DA
+4F6F760D7F8A6D0B967D6C274EF07662990A6A236F3E90808170599674760000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+52
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00006447582F90657A918B2159DA54AC820085E5898180006930564E8036723A
+91CE51B64E5F98016396696D844966F3814B591C6DB24E0058F991AB63D692A5
+4F9D4F0A886398245937907A79FB510080F075916C825B9C59E85F5D690587FB
+501A5DF24E5977E34EE585DD6291661390915C7951045F7981C69038808475AB
+4EA688D4610F6BC561B67FA976CA6EA28A638B708ABC8B6F5F027FFC7FCC7E79
+8335852D56E06BB797F3967059FB541F92806DEB5BC598F25C395F1596B10000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+53
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000537082F16AFB5B309DF961C97E93746987A271DF719288058FCE8D0F76C8
+5F717A4E786C662055B264C150AD81C376705EB896CD8E3486F9548F6CF36D8C
+6C38607F52C775285E7D512A60A061825C24753190F5923E73366CB96E389149
+670953CB53F34F5191C98A9853C85E7C8FC26DE44E8E76C26986865E611A8F3F
+99184FDE903E9B5A61096E1D6F0196854E885A3196E882075DBC79B95B878A9E
+7FBD738957DF828B9B315401904755BB5CEA5FA161086B32734480B28B7D0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+54
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00006D745BD388D598108C6B99AD9D1B6DF551A4514357A38881539F63F48F45
+571254E15713733F6E907DE3906082D198586028966266F07D048D8A8E8D9470
+5CB37CA4670860A695B2801896F29116530096955141904B85F49196668897F5
+5B55531D783896DC683D54C9707E5BB08F09518D572854B1652266AB8D0A8D1C
+81DF846C906D7CDF947F85FB68D765E96FA186A48E81566A902076827AC871E5
+8CAC64C752476FA48CCA600E589E618E66FE8D08624E55B36E23672D8ECB0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+55
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000935895987728680569A8548B4E4D70B88A5064589F4B5B857A8450B55BE8
+77BB6C088A797C986CBE76DE65AC8F3E5D845C55863868E7536062307AD96E5B
+7DBB6A1F7AE05F706F335F35638C6F3267564E085E338CEC4ED781397634969C
+62DB662D627E6CBC8D9971677F695146808753EC906E629854F287C48F4D8005
+937A851790196D5973CD659F771F7504782781FB8C9E91DD5075679575B98A3A
+9707632F93AE966384B86399775C5F817319722D6014657462EF6B63653F0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+56
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00005E407665912D8B49829D679D652F5431871877E580A281026C414E4B7E54
+807776F4690D6B9657F7503C4F84574063076B628DBE887965E87D195FD7646F
+64F281F381F47F6E5E5F5CD95236667A79E97A1A8CEA709975D46EEF6CBB7A92
+4E2D76C55FE0941888777D427A2E816B91CD4EF28846821F54685DDE6D328B05
+7CA58EF880985E1A549276BA5B99665D9A5F73E0682A86DB6731732A8AF88A85
+90107AF971ED716E62C477DA56D14E3B845767F152A986C08CAF94447BC90000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+57
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00004F4F6CE8795D99D06293722A62FD5C0878DA8F4964B08CFA7BC66A01838A
+88DD599D649E58EF72C0690E93108FFD8D05589C7DB48AC46E96634962D95353
+684C74228301914C55447740707C6FC1517954A88CC759FF6ECB6DC45B5C7D2B
+4ED47C7D6ED35B5081EA6F2C5B579B0368D58E2A5B977D9C7E3D7E3191128D70
+594F63CD79DF8DB3535265CF79568A5B963B7D44947D7E825634918967007F6A
+5C0A907566285DE64F5067DE505A4F5C57505EA7000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+58
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00004E8D4E0C51404E105EFF53454E154E984E1E9B325B6C56694E2879BA4E3F
+53154E47592D723B536E6C1056DF80E499976BD3777E9F174E364E9F9F104E5C
+4E694E9382885B5B55C7560F4EC45399539D53B453A553AE97688D0B531A53F5
+532D5331533E8CFE5366536352025208520E52445233528C5274524C525E5261
+525C84AF527D528252815290529351827F544EBB4EC34EC94EC24EE84EE14EEB
+4EDE50B44EF34F224F644EF5500050964F094F474F5E4F6765384F5A4F5D0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+59
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00004F5F4F574F324F3D4F764F744F914F894F834F8F4F7E4F7B51154F7C5102
+4F945114513C51374FC54FDA4FE34FDC4FD14FDF4FF85029504C4FF3502C500F
+502E502D4FFE501C500C5025502850E8504350555048504E506C50C2513B5110
+513A50BA50D6510650ED50EC50E650EE5107510B4EDD6C3D4F5850C94FCE9FA0
+6C467CF4516E5DFD9ECC999856C5591452F9530D8A0753109CEC591951554EA0
+51564EB3886E88A4893B81E088D279805B3488037FB851AB51B151BD51BC0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+5A
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000051C7519651A251A58A018A108A0C8A158B338A4E8A258A418A368A468A54
+8A588A528A868A848A7F8A708A7C8A758A6C8A6E8ACD8AE28A618A9A8AA58A91
+8A928ACF8AD18AC98ADB8AD78AC28AB68AF68AEB8B148B018AE48AED8AFC8AF3
+8AE68AEE8ADE8B288B9C8B168B1A8B108B2B8B2D8B568B598B4E8B9E8B6B8B96
+5369537A961D962296219631962A963D963C964296589654965F9689966C9672
+96749688968D969796B09097909B913A9099911490A190B490B390B691340000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+5B
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000090B890B090DF90C590BE913690C490C79106914890E290DC90D790DB90EB
+90EF90FE91049122911E91239131912F91399143914682BB595052F152AC52AD
+52BE54FF52D052D652F053DF71EE77CD5EF451F551FC9B2F53B65F01755A5DF0
+574C580A57A1587E58BC58C558D15729572C572A573358D9572E572F58E2573B
+5742576958E0576B58DA577C577B5768576D5776577357E157A4578C584F57CF
+57A75816579357A057D55852581D586457D257B857F457EF57F857E457DD0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+5C
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000580B580D57FD57ED5800581E5819584458205865586C58815889589A5880
+99A89F1961FF8279827D827F828F828A82A88284828E8291858C829982AB8553
+82BE82B085F682CA82E3829882B782AE83A7840784EF82A982B482A182AA829F
+82C482E782A482E1830982F782E48622830782DC82F482D282D8830C82FB82D3
+8526831A8306584B716282E082D5831C8351855884FD83088392833C83348331
+839B854E832F834F8347834385888340831785BA832D833A833372966ECE0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+5D
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00008541831B85CE855284C08452846483B083788494843583A083AA8393839C
+8385837C859F83A9837D8555837B8398839E83A89DAF849383C1840183E583D8
+58078418840B83DD83FD83D6841C84388411840683D483DF840F840383F883F9
+83EA83C583C07E0883F083E1845C8451845A8459847385468488847A85628478
+843C844684698476851E848E8431846D84C184CD84D09A4084BD84D384CA84BF
+84BA863A84A184B984B4849793A38577850C750D853884F0861E851F85FA0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+5E
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00008556853B84FF84FC8559854885688564855E857A77A285438604857B85A4
+85A88587858F857985EA859C858585B985B785B0861A85C185DC85FF86278605
+86298616863C5EFE5F08593C596980375955595A5958530F5C225C255C2C5C37
+624C636B647662BB62CA62DA62D762EE649F62F66339634B634363AD63F66371
+637A638E6451636D63AC638A636963AE645C63F263F863E064B363C463DE63CE
+645263C663BE65046441640B641B6420640C64266421645E6516646D64960000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+5F
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000647A64F764FC6499651B64C064D064D764E464E265096525652E5F0B5FD2
+75195F11535F53F1563053E953E853FB541254165406544B563856C8545456A6
+54435421550454BC5423543254825494547754715464549A5680548454765466
+565D54D054AD54C254B4566054A754A6563555F6547254A3566654BB54BF54CC
+567254DA568C54A954AA54A4566554CF54DE561C54E7562E54FD551454F355E9
+5523550F55115527552A5616558F55B5554956C055415555553F5550553C0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+60
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00005537555655755576557755335530555C558B55D2558355B155B955885581
+559F557E55D65591557B55DF560D56B35594559955EA55F755C9561F55D156C1
+55EC55D455E655DD55C455EF55E555F2566F55CC55CD55E855F555E48F61561E
+5608560C560156B6562355FE56005627562D565856395657562C564D56625659
+5695564C5654568656645671566B567B567C5685569356AF56D456D756DD56E1
+570756EB56F956FF5704570A5709571C5E435E195E145E115E6C5E585E570000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+61
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00005E375E445E545E5B5E5E5E615C8C5C7A5C8D5C905D875C885CF45C995C91
+5D505C9C5CB55CA25D2C5CAC5CAB5CB15CA35CC15CB75DA75CD25DA05CCB5D22
+5D975D0D5D275D265D2E5D245D1E5D065D1B5DB85D3E5D345D3D5D6C5D5B5D6F
+5D815D6B5D4B5D4A5D695D745D825D995D9D8C735DB75DD45F735F775F825F87
+5F89540E5FA05F995F9C5FA85FAD5FB55FBC88625F6172AD72B072B473777341
+72C372C172CE72CD72D272E8736A72E9733B72F472F7730172F3736B72FA0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+62
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000072FB731773137380730A731E731D737C732273397325732C733873317350
+734D73577360736C736F737E821B592598E75924590298E0993398E9993C98EA
+98EB98ED98F4990999114F59991B9937993F994399489949994A994C99625E80
+5EE15E8B5E965EA55EA05EB95EB55EBE5EB38CE15ED25ED15EDB5EE85EEA81BA
+5FC45FC95FD661FA61AE5FEE616A5FE15FE4613E60B561345FEA5FED5FF86019
+60356026601B600F600D6029602B600A61CC6021615F61E860FB613760420000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+63
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000606A60F26096609A6173609D60836092608C609B611C60BB60B160DD60D8
+60C660DA60B4612061926115612360F46100610E612B614A617561AC619461A7
+61B761D461F55FDD96B39582958695C8958E9594958C95E595AD95AB9B2E95AC
+95BE95B69B2995BF95BD95BC95C395CB95D495D095D595DE4E2C723F62156C35
+6C546C5C6C4A70436C856C906C946C8C6C686C696C746C766C866F596CD06CD4
+6CAD702770186CF16CD76CB26CE06CD66FFC6CEB6CEE6CB16CD36CEF6D870000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+64
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00006D396D276D0C6D796E5E6D076D046D196D0E6D2B6FAE6D2E6D356D1A700F
+6EF86F6F6D336D916D6F6DF66F7F6D5E6D936D946D5C6D606D7C6D636E1A6DC7
+6DC56DDE70066DBF6DE06FA06DE66DDD6DD9700B6DAB6E0C6DAE6E2B6E6E6E4E
+6E6B6EB26E5F6E866E536E546E326E256E4470676EB16E9870446F2D70056EA5
+6EA76EBD6EBB6EB76F776EB46ECF6E8F6EC26E9F6F627020701F6F246F156EF9
+6F2F6F3670326F746F2A6F096F296F896F8D6F8C6F786F726F7C6F7A70280000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+65
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00006FC96FA76FB96FB66FC26FE16FEE6FDE6FE06FEF701A7023701B70397035
+705D705E5B805B845B955B935BA55BB8752F9A2B64345BE45BEE89305BF08E47
+8B078FB68FD38FD58FE58FEE8FE490878FE690158FE890059004900B90909011
+900D9016902190359036902D902F9044905190529050906890589062905B66B9
+9074907D908290889083908B5F505F575F565F585C3B54AB5C505C595B715C63
+5C687FBC5F335F295F2D82745F3C9B3B5C6E59815983598D5AF55AD759A30000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+66
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000599759CA5B00599E59A459D259B259AF59D759BE5A6D5B0859DD5B4C59E3
+59D859F95A0C5A095AA75AFB5A115A235A135A405A675A4A5A555A3C5A625B0B
+80EC5AAA5A9B5A775A7A5ABE5AEB5AB25B215B2A5AB85AE05AE35B195AD65AE6
+5AD85ADC5B095B175B165B325B375B405C155C1C5B5A5B655B735B515B535B62
+99D499DF99D99A369A5B99D199D89A4D9A4A99E29A6A9A0F9A0D9A059A429A2D
+9A169A419A2E9A389A439A449A4F9A659A647CF97D067D027D077D087E8A0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+67
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00007D1C7D157D137D3A7D327D317E107D3C7D407D3F7D5D7D4E7D737D867D83
+7D887DBE7DBA7DCB7DD47DC47D9E7DAC7DB97DA37DB07DC77DD97DD77DF97DF2
+7E627DE67DF67DF17E0B7DE17E097E1D7E1F7E1E7E2D7E0A7E117E7D7E397E35
+7E327E467E457E887E5A7E527E6E7E7E7E707E6F7E985E7A757F5DDB753E9095
+738E74A3744B73A2739F73CF73C274CF73B773B373C073C973C873E573D9980A
+740A73E973E773DE74BD743F7489742A745B7426742574287430742E742C0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+68
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000741B741A7441745C74577455745974A6746D747E749C74D4748074817487
+748B749E74A874A9749074A774DA74BA97D997DE97DC674C6753675E674869AA
+6AEA6787676A677367986898677568D66A05689F678B6777677C67F06ADB67D8
+6AF367E967B06AE867D967B567DA67B367DD680067C367B867E26ADF67C16A89
+68326833690F6A48684E6968684469BF6883681D68556A3A68416A9C68406B12
+684A6849682968B5688F687468776893686B6B1E696E68FC6ADD69E768F90000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+69
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00006B0F68F0690B6901695768E369106971693969606942695D6B16696B6980
+69986978693469CC6AEC6ADA69CE6AF8696669636979699B69A769BB69AB69AD
+69D469B169C169CA6AB369956AE7698D69FF6AA369ED6A176A186A6569F26A44
+6A3E6AA06A506A5B6A356A8E6AD36A3D6A286A586ADE6A916A906AA96A976AAB
+733773526B816B826BA46B846B9E6BAE6B8D6BAB6B9B6BAF6BAA8ED48EDB8EF2
+8EFB8F648EF98EFC8EEB8EE48F628EFA8EFE8F0A8F078F058F128F268F1E0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+6A
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00008F1F8F1C8F338F468F548ECE62146227621B621F62226221622562246229
+81E7750C74F474FF750F75117513653465EE65EF65F0660A66C7677266036615
+6600708566F7661D66346631663666358006665F66C46641664F668966616657
+66776684668C66D6669D66BE66DB66DC66E666E98CC18CB08CBA8CBD8D048CB2
+8CC58D108CD18CDA8CD58CEB8CE78CFB899889AC89A189BF89A689AF89B289B7
+726E729F725D7266726F727E727F7284728B728D728F72926308633263B00000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+6B
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000643F64D880046BEA6BF36BFD6BFF6BF96C056C0C6C066C0D6C156C186C19
+6C1A6C216C2C6C246C2A6C3265356555656B725872527256723086625216809F
+809C809380BC670A80BD80B180AB80AD80B480B76727815680E981DA80DB80C2
+80C480D980CD80D7671080DD811B80F180F480ED81BE810E80F280FC67158112
+8C5A8161811E812C811881328148814C815381748159815A817181608169817C
+817D816D8167584D5AB58188818281CF6ED581A381AA81CC672681CA81BB0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+6C
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000081C181A66B5F6B376B396B436B466B5998AE98AF98B698BC98C698C86BB3
+5F408F4289F365909F4F659565BC65C665C465C365CC65CE65D265D6716C7152
+7096719770BB70C070B770AB70B171C170CA7110711371DC712F71317173715C
+716871457172714A7178717A719871B371B571A871A071E071D471E771F9721D
+7228706C71FE716671B9623E623D624362486249793B794079467949795B795C
+7953795A79B079577960798E7967797A79AA798A799A79A779B35FD15FD00000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+6D
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000061DF605D605A606760416059606361646106610D615D61A9619D61CB61E3
+62078080807F6C936FA96DFC78EF77F878AD780978687818781165AB782D78B8
+781D7839792A7931781F783C7825782C78237829784E786D786478FD78267850
+7847784C786A78E77893789A788778E378A178A378B278B978A578D478D978C9
+78EC78F2790578F479137924791E79349F959EF99EFB9EFC76F17704779876F9
+77077708771A77227719772D772677357738775E77BC77477743775A77680000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+6E
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000077627765777F778D777D7780778C7791779F77A077B077B577BD753A7540
+754E754B7548755B7572757975837F587F617F5F8A487F687F867F717F797F88
+7F7E76CD76E5883291D291D391D491D991D791D591F791E791E4934691F591F9
+9208922692459211921092019227920492259200923A9266923792339255923D
+9238925E926C926D923F9460923092499248924D922E9239943892AC92A0927A
+92AA92EE92CF940392E3943A92B192A693A7929692CC92A993F59293927F0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+6F
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000093A9929A931A92AB9283940B92A892A39412933892F193D792E592F092EF
+92E892BC92DD92F69426942792C392DF92E6931293069369931B934093019315
+932E934393079308931F93199365934793769354936493AA9370938493E493D8
+9428938793CC939893B893BF93A693B093B5944C93E293DC93DD93CD93DE93C3
+93C793D19414941D93F794659413946D9420947993F99419944A9432943F9454
+9463937E77E777EC96C979D579ED79E379EB7A065D477A037A027A1E7A140000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+70
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00007A397A377A619ECF99A57A707688768E7693769976A474DE74E0752C9CE9
+9CF69D079D069D239D879E159D1D9D1F9DE59D2F9DD99D309D429E1E9D539E1D
+9D609D529DF39D5C9D619D939D6A9D6F9D899D989D9A9DC09DA59DA99DC29DBC
+9E1A9DD39DDA9DEF9DE69DF29DF89E0C9DFA9E1B7592759476647658759D7667
+75A375B375B475B875C475B175B075C375C2760275CD75E3764675E675E47647
+75E7760375F175FC75FF761076007649760C761E760A7625763B761576190000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+71
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000761B763C762276207640762D7630766D76357643766E7633764D76697654
+765C76567672766F7FCA7AE67A787A797A807A867A887A957AC77AA07AAC7AA8
+7AB67AB3886488698872887D887F888288A2896088B788BC88C9893388CE895D
+894788F1891A88FC88E888FE88F08921891989138938890A8964892B89368941
+8966897B758B80E576B876B477DC801280148016801C8020802E80258026802C
+802980288031800B803580438046807980528075807189839807980E980F0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+72
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00009821981C6F4198269837984E98539873986298599865986C9870864D8654
+866C87E38806867A867C867B86A8868D868B8706869D86A786A386AA869386A9
+86B686C486B5882386B086BA86B186AF86C987F686B486E986FA87EF86ED8784
+86D0871386DE881086DF86D886D18703870786F88708870A870D87098723873B
+871E8725872E871A873E87C88734873187298737873F87828722877D8811877B
+87608770874C876E878B8753876387BB876487598765879387AF87CE87D20000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+73
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000087C68788878587AD8797878387AB87E587AC87B587B387CB87D387BD87D1
+87C087CA87DB87EA87E087EE8816881387FE880A881B88218839883C7F367F4C
+7F447F4582107AFA7AFD7B087BE47B047B677B0A7B2B7B0F7B477B387B2A7B19
+7B2E7B317B207B257B247B337C697B1E7B587BF37B457B757B4C7B8F7B607B6E
+7B7B7B627B727B717B907C007BCB7BB87BAC7B9D7C5C7B857C1E7B9C7BA27C2B
+7BB47C237BC17BCC7BDD7BDA7BE57BE67BEA7C0C7BFE7BFC7C0F7C6A7C0B0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+74
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00007C1F7C2A7C267C387C5F7C4081FE82018202820481EC8844822182228264
+822D822F8228822B8238826B82338234823E82448249824B824F825A825F8268
+887E88CA888888D888DF895E7F9D7FA57FA77FAF7FB07FB27C7C65497C917CF2
+7CF67C9E7CA27CB27CBC7CBD7CDD7CC77CCC7CCD7CC87CC57CD77CE8826E66A8
+7FBF7FCE7FD57FE57FE17FE67FE97FEE7FF37CF87E367DA67DAE7E477E9B9EA9
+9EB48D738D848D948D918DB28D678D6D8C478C49914A9150914E914F91640000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+75
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00009162916191709169916F91C591C3917291749179918C91859190918D9191
+91A291A391AA91AD91AE91AF91B591B491BA8C559E7A8E898DEB8E058E598E69
+8DB58DBF8DBC8DBA8E4C8DD68DD78DDA8E928DCE8DCF8DDB8DC68DEC8E7A8E55
+8DE38E9A8E8B8DE48E098DFD8E148E1D8E1F8E938E2E8E238E918E3A8E408E39
+8E358E3D8E318E498E418E428EA18E638E4A8E708E768E7C8E6F8E748E858EAA
+8E948E908EA68E9E8C788C828C8A8C858C988C94659B89D689F489DA89DC0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+76
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000089E589EB89F68A3E8B26975A96E9974296EF9706973D9708970F970E972A
+97449730973E9F549F5F9F599F609F5C9F669F6C9F6A9F779EFD9EFF9F0996B9
+96BC96BD96CE96D277BF8B8E928E947E92C893E8936A93CA938F943E946B9B77
+9B749B819B839B8E9C787A4C9B929C5F9B909BAD9B9A9BAA9B9E9C6D9BAB9B9D
+9C589BC19C7A9C319C399C239C379BC09BCA9BC79BFD9BD69BEA9BEB9BE19BE4
+9BE79BDD9BE29BF09BDB9BF49BD49C5D9C089C109C0D9C129C099BFF9C200000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+77
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00009C329C2D9C289C259C299C339C3E9C489C3B9C359C459C569C549C529C67
+977C978597C397BD979497C997AB97A397B297B49AB19AB09AB79DBB9AB69ABA
+9ABC9AC19AC09ACF9AC29AD69AD59AD19B459B439B589B4E9B489B4D9B519957
+995C992E995599549ADF9AE19AE69AEF9AEB9AFB9AED9AF99B089B0F9B229B1F
+9B234E489EBE7E3B9E829E879E889E8B9E9293D69E9D9E9F9EDB9EDC9EDD9EE0
+9EDF9EE29EF79EE79EE59EF29EEF9F229F2C9F2F9F399F379F3D9F3E9F440000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+78
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000896C95C693365F4685147E94538251B24E119F635679515A6DC09F156597
+56419AEE83034E3089075E727A4098B35E7F95A49B0D52128FF45F597A6B98E2
+51E050A24EF7835085915118636E6372524B5938774F8721814A7E8D91CC66C6
+5E1877AD9E7556C99EF46FDB61DE77C770309EB5884A95E282F951ED62514EC6
+673497C67C647E3497A69EAF786E820D672F677E56CC53F098B16AAF7F4E6D82
+7CF04E074FC27E6B9E7956AE9B1A846F53F690C179A67C72613F4E919AD20000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+79
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000075C796BB53EA7DFB88FD79CD78437B5151C6000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
diff --git a/library/encoding/gb1988.enc b/library/encoding/gb1988.enc
new file mode 100644
index 0000000..298732c
--- /dev/null
+++ b/library/encoding/gb1988.enc
@@ -0,0 +1,20 @@
+# Encoding file: gb1988, single-byte
+S
+003F 0 1
+00
+0000000100020003000400050006000700080009000A000B000C000D000E000F
+0010001100120013001400150016001700180019001A001B001C001D001E001F
+002000210022002300A500250026002700280029002A002B002C002D002E002F
+0030003100320033003400350036003700380039003A003B003C003D003E003F
+0040004100420043004400450046004700480049004A004B004C004D004E004F
+0050005100520053005400550056005700580059005A005B005C005D005E005F
+0060006100620063006400650066006700680069006A006B006C006D006E006F
+0070007100720073007400750076007700780079007A007B007C007D203E007F
+0080008100820083008400850086008700880089008A008B008C008D008E008F
+0090009100920093009400950096009700980099009A009B009C009D009E009F
+0000FF61FF62FF63FF64FF65FF66FF67FF68FF69FF6AFF6BFF6CFF6DFF6EFF6F
+FF70FF71FF72FF73FF74FF75FF76FF77FF78FF79FF7AFF7BFF7CFF7DFF7EFF7F
+FF80FF81FF82FF83FF84FF85FF86FF87FF88FF89FF8AFF8BFF8CFF8DFF8EFF8F
+FF90FF91FF92FF93FF94FF95FF96FF97FF98FF99FF9AFF9BFF9CFF9DFF9EFF9F
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
diff --git a/library/encoding/gb2312-raw.enc b/library/encoding/gb2312-raw.enc
new file mode 100644
index 0000000..813d7a6
--- /dev/null
+++ b/library/encoding/gb2312-raw.enc
@@ -0,0 +1,1380 @@
+# Encoding file: gb2312, double-byte
+D
+233F 0 81
+21
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000030003001300230FB02C902C700A8300330052015FF5E2225202620182019
+201C201D3014301530083009300A300B300C300D300E300F3016301730103011
+00B100D700F72236222722282211220F222A222922082237221A22A522252220
+23122299222B222E2261224C2248223D221D2260226E226F22642265221E2235
+22342642264000B0203220332103FF0400A4FFE0FFE1203000A7211626062605
+25CB25CF25CE25C725C625A125A025B325B2203B219221902191219330130000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+22
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000024882489248A248B248C248D248E248F2490249124922493249424952496
+249724982499249A249B247424752476247724782479247A247B247C247D247E
+247F248024812482248324842485248624872460246124622463246424652466
+2467246824690000000032203221322232233224322532263227322832290000
+00002160216121622163216421652166216721682169216A216B000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+23
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000FF01FF02FF03FFE5FF05FF06FF07FF08FF09FF0AFF0BFF0CFF0DFF0EFF0F
+FF10FF11FF12FF13FF14FF15FF16FF17FF18FF19FF1AFF1BFF1CFF1DFF1EFF1F
+FF20FF21FF22FF23FF24FF25FF26FF27FF28FF29FF2AFF2BFF2CFF2DFF2EFF2F
+FF30FF31FF32FF33FF34FF35FF36FF37FF38FF39FF3AFF3BFF3CFF3DFF3EFF3F
+FF40FF41FF42FF43FF44FF45FF46FF47FF48FF49FF4AFF4BFF4CFF4DFF4EFF4F
+FF50FF51FF52FF53FF54FF55FF56FF57FF58FF59FF5AFF5BFF5CFF5DFFE30000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+24
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000304130423043304430453046304730483049304A304B304C304D304E304F
+3050305130523053305430553056305730583059305A305B305C305D305E305F
+3060306130623063306430653066306730683069306A306B306C306D306E306F
+3070307130723073307430753076307730783079307A307B307C307D307E307F
+3080308130823083308430853086308730883089308A308B308C308D308E308F
+3090309130923093000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+25
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000030A130A230A330A430A530A630A730A830A930AA30AB30AC30AD30AE30AF
+30B030B130B230B330B430B530B630B730B830B930BA30BB30BC30BD30BE30BF
+30C030C130C230C330C430C530C630C730C830C930CA30CB30CC30CD30CE30CF
+30D030D130D230D330D430D530D630D730D830D930DA30DB30DC30DD30DE30DF
+30E030E130E230E330E430E530E630E730E830E930EA30EB30EC30ED30EE30EF
+30F030F130F230F330F430F530F6000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+26
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000039103920393039403950396039703980399039A039B039C039D039E039F
+03A003A103A303A403A503A603A703A803A90000000000000000000000000000
+000003B103B203B303B403B503B603B703B803B903BA03BB03BC03BD03BE03BF
+03C003C103C303C403C503C603C703C803C90000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+27
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000004100411041204130414041504010416041704180419041A041B041C041D
+041E041F0420042104220423042404250426042704280429042A042B042C042D
+042E042F00000000000000000000000000000000000000000000000000000000
+000004300431043204330434043504510436043704380439043A043B043C043D
+043E043F0440044104420443044404450446044704480449044A044B044C044D
+044E044F00000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+28
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000010100E101CE00E0011300E9011B00E8012B00ED01D000EC014D00F301D2
+00F2016B00FA01D400F901D601D801DA01DC00FC00EA00000000000000000000
+0000000000000000000031053106310731083109310A310B310C310D310E310F
+3110311131123113311431153116311731183119311A311B311C311D311E311F
+3120312131223123312431253126312731283129000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+29
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00000000000000002500250125022503250425052506250725082509250A250B
+250C250D250E250F2510251125122513251425152516251725182519251A251B
+251C251D251E251F2520252125222523252425252526252725282529252A252B
+252C252D252E252F2530253125322533253425352536253725382539253A253B
+253C253D253E253F2540254125422543254425452546254725482549254A254B
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+30
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000554A963F57C3632854CE550954C07691764C853C77EE827E788D72319698
+978D6C285B894FFA630966975CB880FA684880AE660276CE51F9655671AC7FF1
+888450B2596561CA6FB382AD634C625253ED54277B06516B75A45DF462D48DCB
+9776628A8019575D97387F627238767D67CF767E64464F708D2562DC7A176591
+73ED642C6273822C9881677F7248626E62CC4F3474E3534A529E7ECA90A65E2E
+6886699C81807ED168D278C5868C9551508D8C2482DE80DE5305891252650000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+31
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000858496F94FDD582199715B9D62B162A566B48C799C8D7206676F789160B2
+535153178F8880CC8D1D94A1500D72C8590760EB711988AB595482EF672C7B28
+5D297EF7752D6CF58E668FF8903C9F3B6BD491197B145F7C78A784D6853D6BD5
+6BD96BD65E015E8775F995ED655D5F0A5FC58F9F58C181C2907F965B97AD8FB9
+7F168D2C62414FBF53D8535E8FA88FA98FAB904D68075F6A819888689CD6618B
+522B762A5F6C658C6FD26EE85BBE6448517551B067C44E1979C9997C70B30000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+32
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000075C55E7673BB83E064AD62E894B56CE2535A52C3640F94C27B944F2F5E1B
+82368116818A6E246CCA9A736355535C54FA886557E04E0D5E036B657C3F90E8
+601664E6731C88C16750624D8D22776C8E2991C75F6983DC8521991053C28695
+6B8B60ED60E8707F82CD82314ED36CA785CF64CD7CD969FD66F9834953957B56
+4FA7518C6D4B5C428E6D63D253C9832C833667E578B4643D5BDF5C945DEE8BE7
+62C667F48C7A640063BA8749998B8C177F2094F24EA7961098A4660C73160000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+33
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000573A5C1D5E38957F507F80A05382655E7545553150218D856284949E671D
+56326F6E5DE2543570928F66626F64A463A35F7B6F8890F481E38FB05C186668
+5FF16C8996488D81886C649179F057CE6A59621054484E587A0B60E96F848BDA
+627F901E9A8B79E4540375F4630153196C608FDF5F1B9A70803B9F7F4F885C3A
+8D647FC565A570BD514551B2866B5D075BA062BD916C75748E0C7A2061017B79
+4EC77EF877854E1181ED521D51FA6A7153A88E87950496CF6EC19664695A0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+34
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000784050A877D7641089E6590463E35DDD7A7F693D4F20823955984E3275AE
+7A975E625E8A95EF521B5439708A6376952457826625693F918755076DF37EAF
+882262337EF075B5832878C196CC8F9E614874F78BCD6B64523A8D506B21806A
+847156F153064ECE4E1B51D17C97918B7C074FC38E7F7BE17A9C64675D1450AC
+810676017CB96DEC7FE067515B585BF878CB64AE641363AA632B9519642D8FBE
+7B5476296253592754466B7950A362345E266B864EE38D37888B5F85902E0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+35
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00006020803D62C54E39535590F863B880C665E66C2E4F4660EE6DE18BDE5F39
+86CB5F536321515A83616863520063638E4850125C9B79775BFC52307A3B60BC
+905376D75FB75F9776848E6C706F767B7B4977AA51F3909358244F4E6EF48FEA
+654C7B1B72C46DA47FDF5AE162B55E95573084827B2C5E1D5F1F90127F1498A0
+63826EC7789870B95178975B57AB75354F4375385E9760E659606DC06BBF7889
+53FC96D551CB52016389540A94938C038DCC7239789F87768FED8C0D53E00000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+36
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00004E0176EF53EE948998769F0E952D5B9A8BA24E224E1C51AC846361C252A8
+680B4F97606B51BB6D1E515C6296659796618C46901775D890FD77636BD2728A
+72EC8BFB583577798D4C675C9540809A5EA66E2159927AEF77ED953B6BB565AD
+7F0E58065151961F5BF958A954288E726566987F56E4949D76FE9041638754C6
+591A593A579B8EB267358DFA8235524160F0581586FE5CE89E454FC4989D8BB9
+5A2560765384627C904F9102997F6069800C513F80335C1499756D314E8C0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+37
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00008D3053D17F5A7B4F4F104E4F96006CD573D085E95E06756A7FFB6A0A77FE
+94927E4151E170E653CD8FD483038D2972AF996D6CDB574A82B365B980AA623F
+963259A84EFF8BBF7EBA653E83F2975E556198DE80A5532A8BFD542080BA5E9F
+6CB88D3982AC915A54296C1B52067EB7575F711A6C7E7C89594B4EFD5FFF6124
+7CAA4E305C0167AB87025CF0950B98CE75AF70FD902251AF7F1D8BBD594951E4
+4F5B5426592B657780A45B75627662C28F905E456C1F7B264F0F4FD8670D0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+38
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00006D6E6DAA798F88B15F17752B629A8F854FEF91DC65A7812F81515E9C8150
+8D74526F89868D4B590D50854ED8961C723681798D1F5BCC8BA3964459877F1A
+54905676560E8BE565396982949976D66E895E727518674667D17AFF809D8D76
+611F79C665628D635188521A94A27F38809B7EB25C976E2F67607BD9768B9AD8
+818F7F947CD5641E95507A3F544A54E56B4C640162089E3D80F3759952729769
+845B683C86E49601969494EC4E2A54047ED968398DDF801566F45E9A7FB90000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+39
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000057C2803F68975DE5653B529F606D9F9A4F9B8EAC516C5BAB5F135DE96C5E
+62F18D21517194A952FE6C9F82DF72D757A267848D2D591F8F9C83C754957B8D
+4F306CBD5B6459D19F1353E486CA9AA88C3780A16545987E56FA96C7522E74DC
+52505BE1630289024E5662D0602A68FA51735B9851A089C27BA199867F5060EF
+704C8D2F51495E7F901B747089C4572D78455F529F9F95FA8F689B3C8BE17678
+684267DC8DEA8D35523D8F8A6EDA68CD950590ED56FD679C88F98FC754C80000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+3A
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00009AB85B696D776C264EA55BB39A87916361A890AF97E9542B6DB55BD251FD
+558A7F557FF064BC634D65F161BE608D710A6C576C49592F676D822A58D5568E
+8C6A6BEB90DD597D801753F76D695475559D837783CF683879BE548C4F555408
+76D28C8996026CB36DB88D6B89109E648D3A563F9ED175D55F8872E0606854FC
+4EA86A2A886160528F7054C470D886799E3F6D2A5B8F5F187EA255894FAF7334
+543C539A5019540E547C4E4E5FFD745A58F6846B80E1877472D07CCA6E560000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+3B
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00005F27864E552C62A44E926CAA623782B154D7534E733E6ED1753B52125316
+8BDD69D05F8A60006DEE574F6B2273AF68538FD87F13636260A3552475EA8C62
+71156DA35BA65E7B8352614C9EC478FA87577C27768751F060F6714C66435E4C
+604D8C0E707063258F895FBD606286D456DE6BC160946167534960E066668D3F
+79FD4F1A70E96C478BB38BF27ED88364660F5A5A9B426D516DF78C416D3B4F19
+706B83B7621660D1970D8D27797851FB573E57FA673A75787A3D79EF7B950000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+3C
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000808C99658FF96FC08BA59E2159EC7EE97F095409678168D88F917C4D96C6
+53CA602575BE6C7253735AC97EA7632451E0810A5DF184DF628051805B634F0E
+796D524260B86D4E5BC45BC28BA18BB065E25FCC964559937EE77EAA560967B7
+59394F735BB652A0835A988A8D3E753294BE50477A3C4EF767B69A7E5AC16B7C
+76D1575A5C167B3A95F4714E517C80A9827059787F04832768C067EC78B17877
+62E363617B804FED526A51CF835069DB92748DF58D3189C1952E7BAD4EF60000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+3D
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000506582305251996F6E106E856DA75EFA50F559DC5C066D466C5F7586848B
+686859568BB253209171964D854969127901712680F64EA490CA6D479A845A07
+56BC640594F077EB4FA5811A72E189D2997A7F347EDE527F655991758F7F8F83
+53EB7A9663ED63A5768679F888579636622A52AB8282685467706377776B7AED
+6D017ED389E359D0621285C982A5754C501F4ECB75A58BEB5C4A5DFE7B4B65A4
+91D14ECA6D25895F7D2795264EC58C288FDB9773664B79818FD170EC6D780000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+3E
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00005C3D52B283465162830E775B66769CB84EAC60CA7CBE7CB37ECF4E958B66
+666F988897595883656C955C5F8475C997567ADF7ADE51C070AF7A9863EA7A76
+7EA0739697ED4E4570784E5D915253A9655165E781FC8205548E5C31759A97A0
+62D872D975BD5C459A7983CA5C40548077E94E3E6CAE805A62D2636E5DE85177
+8DDD8E1E952F4FF153E560E770AC526763509E435A1F5026773753777EE26485
+652B628963985014723589C951B38BC07EDD574783CC94A7519B541B5CFB0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+3F
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00004FCA7AE36D5A90E19A8F55805496536154AF5F0063E9697751EF6168520A
+582A52D8574E780D770B5EB761777CE0625B62974EA27095800362F770E49760
+577782DB67EF68F578D5989779D158F354B353EF6E34514B523B5BA28BFE80AF
+554357A660735751542D7A7A60505B5463A762A053E362635BC767AF54ED7A9F
+82E691775E9388E4593857AE630E8DE880EF57577B774FA95FEB5BBD6B3E5321
+7B5072C2684677FF773665F751B54E8F76D45CBF7AA58475594E9B4150800000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+40
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000998861276E8357646606634656F062EC62695ED39614578362C955878721
+814A8FA3556683B167658D5684DD5A6A680F62E67BEE961151706F9C8C3063FD
+89C861D27F0670C26EE57405699472FC5ECA90CE67176D6A635E52B372628001
+4F6C59E5916A70D96D9D52D24E5096F7956D857E78CA7D2F5121579264C2808B
+7C7B6CEA68F1695E51B7539868A872819ECE7BF172F879BB6F137406674E91CC
+9CA4793C83898354540F68174E3D538952B1783E5386522950884F8B4FD00000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+41
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000075E27ACB7C926CA596B6529B748354E94FE9805483B28FDE95705EC9601C
+6D9F5E18655B813894FE604B70BC7EC37CAE51C968817CB1826F4E248F8691CF
+667E4EAE8C0564A9804A50DA759771CE5BE58FBD6F664E86648295635ED66599
+521788C270C852A3730E7433679778F797164E3490BB9CDE6DCB51DB8D41541D
+62CE73B283F196F69F8494C34F367F9A51CC707596755CAD988653E64EE46E9C
+740969B4786B998F7559521876246D4167F3516D9F99804B54997B3C7ABF0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+42
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00009686578462E29647697C5A0464027BD36F0F964B82A6536298855E907089
+63B35364864F9C819E93788C97328DEF8D429E7F6F5E79845F559646622E9A74
+541594DD4FA365C55C655C617F1586516C2F5F8B73876EE47EFF5CE6631B5B6A
+6EE653754E7163A0756562A18F6E4F264ED16CA67EB68BBA841D87BA7F57903B
+95237BA99AA188F8843D6D1B9A867EDC59889EBB739B780186829A6C9A82561B
+541757CB4E709EA653568FC881097792999286EE6EE1851366FC61626F2B0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+43
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00008C298292832B76F26C135FD983BD732B8305951A6BDB77DB94C6536F8302
+51925E3D8C8C8D384E4873AB679A68859176970971646CA177095A9295416BCF
+7F8E66275BD059B95A9A95E895F74EEC840C84996AAC76DF9530731B68A65B5F
+772F919A97617CDC8FF78C1C5F257C7379D889C56CCC871C5BC65E4268C97720
+7EF55195514D52C95A297F05976282D763CF778485D079D26E3A5E9959998511
+706D6C1162BF76BF654F60AF95FD660E879F9E2394ED540D547D8C2C64780000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+44
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000647986116A21819C78E864699B5462B9672B83AB58A89ED86CAB6F205BDE
+964C8C0B725F67D062C772614EA959C66BCD589366AE5E5552DF6155672876EE
+776672677A4662FF54EA545094A090A35A1C7EB36C164E435976801059485357
+753796BE56CA63208111607C95F96DD65462998151855AE980FD59AE9713502A
+6CE55C3C62DF4F60533F817B90066EBA852B62C85E7478BE64B5637B5FF55A18
+917F9E1F5C3F634F80425B7D556E954A954D6D8560A867E072DE51DD5B810000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+45
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000062E76CDE725B626D94AE7EBD81136D53519C5F04597452AA601259736696
+8650759F632A61E67CEF8BFA54E66B279E256BB485D5545550766CA4556A8DB4
+722C5E156015743662CD6392724C5F986E436D3E65006F5876D878D076FC7554
+522453DB4E535E9E65C1802A80D6629B5486522870AE888D8DD16CE1547880DA
+57F988F48D54966A914D4F696C9B55B776C6783062A870F96F8E5F6D84EC68DA
+787C7BF781A8670B9E4F636778B0576F78129739627962AB528874356BD70000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+46
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00005564813E75B276AE533975DE50FB5C418B6C7BC7504F72479A9798D86F02
+74E27968648777A562FC98918D2B54C180584E52576A82F9840D5E7351ED74F6
+8BC45C4F57616CFC98875A4678349B448FEB7C955256625194FA4EC683868461
+83E984B257D467345703666E6D668C3166DD7011671F6B3A6816621A59BB4E03
+51C46F0667D26C8F517668CB59476B6775665D0E81109F5065D7794879419A91
+8D775C824E5E4F01542F5951780C56686C148FC45F036C7D6CE38BAB63900000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+47
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000060706D3D72756266948E94C553438FC17B7E4EDF8C264E7E9ED494B194B3
+524D6F5C90636D458C3458115D4C6B206B4967AA545B81547F8C589985375F3A
+62A26A47953965726084686577A74E544FA85DE7979864AC7FD85CED4FCF7A8D
+520783044E14602F7A8394A64FB54EB279E6743452E482B964D279BD5BDD6C81
+97528F7B6C22503E537F6E0564CE66746C3060C598778BF75E86743C7A7779CB
+4E1890B174036C4256DA914B6CC58D8B533A86C666F28EAF5C489A716E200000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+48
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000053D65A369F8B8DA353BB570898A76743919B6CC9516875CA62F372AC5238
+529D7F3A7094763853749E4A69B7786E96C088D97FA4713671C3518967D374E4
+58E4651856B78BA9997662707ED560F970ED58EC4EC14EBA5FCD97E74EFB8BA4
+5203598A7EAB62544ECD65E5620E833884C98363878D71946EB65BB97ED25197
+63C967D480898339881551125B7A59828FB14E736C5D516589258F6F962E854A
+745E951095F06DA682E55F3164926D128428816E9CC3585E8D5B4E0953C10000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+49
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00004F1E6563685155D34E2764149A9A626B5AC2745F82726DA968EE50E7838E
+7802674052396C997EB150BB5565715E7B5B665273CA82EB67495C715220717D
+886B95EA965564C58D6181B355846C5562477F2E58924F2455468D4F664C4E0A
+5C1A88F368A2634E7A0D70E7828D52FA97F65C1154E890B57ECD59628D4A86C7
+820C820D8D6664445C0461516D89793E8BBE78377533547B4F388EAB6DF15A20
+7EC5795E6C885BA15A76751A80BE614E6E1758F0751F7525727253477EF30000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+4A
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000770176DB526980DC57235E08593172EE65BD6E7F8BD75C388671534177F3
+62FE65F64EC098DF86805B9E8BC653F277E24F7F5C4E9A7659CB5F0F793A58EB
+4E1667FF4E8B62ED8A93901D52BF662F55DC566C90024ED54F8D91CA99706C0F
+5E0260435BA489C68BD56536624B99965B885BFF6388552E53D77626517D852C
+67A268B36B8A62928F9353D482126DD1758F4E668D4E5B70719F85AF669166D9
+7F7287009ECD9F205C5E672F8FF06811675F620D7AD658855EB665706F310000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+4B
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000060555237800D6454887075295E05681362F4971C53CC723D8C016C347761
+7A0E542E77AC987A821C8BF47855671470C165AF64955636601D79C153F84E1D
+6B7B80865BFA55E356DB4F3A4F3C99725DF3677E80386002988290015B8B8BBC
+8BF5641C825864DE55FD82CF91654FD77D20901F7C9F50F358516EAF5BBF8BC9
+80839178849C7B97867D968B968F7EE59AD3788E5C817A57904296A7795F5B59
+635F7B0B84D168AD55067F2974107D2295016240584C4ED65B83597958540000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+4C
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000736D631E8E4B8E0F80CE82D462AC53F06CF0915E592A60016C70574D644A
+8D2A762B6EE9575B6A8075F06F6D8C2D8C0857666BEF889278B363A253F970AD
+6C645858642A580268E0819B55107CD650188EBA6DCC8D9F70EB638F6D9B6ED4
+7EE68404684390036DD896768BA85957727985E4817E75BC8A8A68AF52548E22
+951163D098988E44557C4F5366FF568F60D56D9552435C4959296DFB586B7530
+751C606C82148146631167618FE2773A8DF38D3494C15E165385542C70C30000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+4D
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00006C405EF7505C4EAD5EAD633A8247901A6850916E77B3540C94DC5F647AE5
+687663457B527EDF75DB507762955934900F51F879C37A8156FE5F9290146D82
+5C60571F541051546E4D56E263A89893817F8715892A9000541E5C6F81C062D6
+625881319E3596409A6E9A7C692D59A562D3553E631654C786D96D3C5A0374E6
+889C6B6A59168C4C5F2F6E7E73A9987D4E3870F75B8C7897633D665A769660CB
+5B9B5A494E0781556C6A738B4EA167897F515F8065FA671B5FD859845A010000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+4E
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00005DCD5FAE537197E68FDD684556F4552F60DF4E3A6F4D7EF482C7840E59D4
+4F1F4F2A5C3E7EAC672A851A5473754F80C355829B4F4F4D6E2D8C135C096170
+536B761F6E29868A658795FB7EB9543B7A337D0A95EE55E17FC174EE631D8717
+6DA17A9D621165A1536763E16C835DEB545C94A84E4C6C618BEC5C4B65E0829C
+68A7543E54346BCB6B664E9463425348821E4F0D4FAE575E620A96FE66647269
+52FF52A1609F8BEF661471996790897F785277FD6670563B54389521727A0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+4F
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00007A00606F5E0C6089819D591560DC718470EF6EAA6C5072806A8488AD5E2D
+4E605AB3559C94E36D177CFB9699620F7EC6778E867E5323971E8F9666875CE1
+4FA072ED4E0B53A6590F54136380952851484ED99C9C7EA454B88D2488548237
+95F26D8E5F265ACC663E966973B0732E53BF817A99857FA15BAA967796507EBF
+76F853A2957699997BB189446E584E617FD479658BE660F354CD4EAB98795DF7
+6A6150CF54118C618427785D9704524A54EE56A395006D885BB56DC666530000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+50
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00005C0F5B5D6821809655787B11654869544E9B6B47874E978B534F631F643A
+90AA659C80C18C10519968B0537887F961C86CC46CFB8C225C5185AA82AF950C
+6B238F9B65B05FFB5FC34FE18845661F8165732960FA51745211578B5F6290A2
+884C91925E78674F602759D3514451F680F853086C7996C4718A4F114FEE7F9E
+673D55C5950879C088967EE3589F620C9700865A5618987B5F908BB884C49157
+53D965ED5E8F755C60647D6E5A7F7EEA7EED8F6955A75BA360AC65CB73840000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+51
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00009009766377297EDA9774859B5B667A7496EA884052CB718F5FAA65EC8BE2
+5BFB9A6F5DE16B896C5B8BAD8BAF900A8FC5538B62BC9E269E2D54404E2B82BD
+7259869C5D1688596DAF96C554D14E9A8BB6710954BD960970DF6DF976D04E25
+781487125CA95EF68A00989C960E708E6CBF594463A9773C884D6F1482735830
+71D5538C781A96C155015F6671305BB48C1A9A8C6B83592E9E2F79E76768626C
+4F6F75A17F8A6D0B96336C274EF075D2517B68376F3E90808170599674760000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+52
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000064475C2790657A918C2359DA54AC8200836F898180006930564E80367237
+91CE51B64E5F987563964E1A53F666F3814B591C6DB24E0058F9533B63D694F1
+4F9D4F0A886398905937905779FB4EEA80F075916C825B9C59E85F5D69058681
+501A5DF24E5977E34EE5827A6291661390915C794EBF5F7981C69038808475AB
+4EA688D4610F6BC55FC64E4976CA6EA28BE38BAE8C0A8BD15F027FFC7FCC7ECE
+8335836B56E06BB797F3963459FB541F94F66DEB5BC5996E5C395F1596900000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+53
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000537082F16A315A749E705E947F2883B984248425836787478FCE8D6276C8
+5F719896786C662054DF62E54F6381C375C85EB896CD8E0A86F9548F6CF36D8C
+6C38607F52C775285E7D4F1860A05FE75C24753190AE94C072B96CB96E389149
+670953CB53F34F5191C98BF153C85E7C8FC26DE44E8E76C26986865E611A8206
+4F594FDE903E9C7C61096E1D6E1496854E885A3196E84E0E5C7F79B95B878BED
+7FBD738957DF828B90C15401904755BB5CEA5FA161086B3272F180B28A890000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+54
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00006D745BD388D598848C6B9A6D9E336E0A51A4514357A38881539F63F48F95
+56ED54585706733F6E907F188FDC82D1613F6028966266F07EA68D8A8DC394A5
+5CB37CA4670860A6960580184E9190E75300966851418FD08574915D665597F5
+5B55531D78386742683D54C9707E5BB08F7D518D572854B1651266828D5E8D43
+810F846C906D7CDF51FF85FB67A365E96FA186A48E81566A90207682707671E5
+8D2362E952196CFD8D3C600E589E618E66FE8D60624E55B36E23672D8F670000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+55
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000094E195F87728680569A8548B4E4D70B88BC86458658B5B857A84503A5BE8
+77BB6BE18A797C986CBE76CF65A98F975D2D5C5586386808536062187AD96E5B
+7EFD6A1F7AE05F706F335F20638C6DA867564E085E108D264ED780C07634969C
+62DB662D627E6CBC8D7571677F695146808753EC906E629854F286F08F998005
+951785178FD96D5973CD659F771F7504782781FB8D1E94884FA6679575B98BCA
+9707632F9547963584B8632377415F8172F04E896014657462EF6B63653F0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+56
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00005E2775C790D18BC1829D679D652F5431871877E580A281026C414E4B7EC7
+804C76F4690D6B966267503C4F84574063076B628DBE53EA65E87EB85FD7631A
+63B781F381F47F6E5E1C5CD95236667A79E97A1A8D28709975D46EDE6CBB7A92
+4E2D76C55FE0949F88777EC879CD80BF91CD4EF24F17821F54685DDE6D328BCC
+7CA58F7480985E1A549276B15B99663C9AA473E0682A86DB6731732A8BF88BDB
+90107AF970DB716E62C477A956314E3B845767F152A986C08D2E94F87B510000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+57
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00004F4F6CE8795D9A7B6293722A62FD4E1378168F6C64B08D5A7BC668695E84
+88C55986649E58EE72B6690E95258FFD8D5857607F008C0651C6634962D95353
+684C74228301914C55447740707C6D4A517954A88D4459FF6ECB6DC45B5C7D2B
+4ED47C7D6ED35B5081EA6E0D5B579B0368D58E2A5B977EFC603B7EB590B98D70
+594F63CD79DF8DB3535265CF79568BC5963B7EC494BB7E825634918967007F6A
+5C0A907566285DE64F5067DE505A4F5C57505EA7000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+58
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00004E8D4E0C51404E105EFF53454E154E984E1E9B325B6C56694E2879BA4E3F
+53154E47592D723B536E6C1056DF80E499976BD3777E9F174E364E9F9F104E5C
+4E694E9382885B5B556C560F4EC4538D539D53A353A553AE97658D5D531A53F5
+5326532E533E8D5C5366536352025208520E522D5233523F5240524C525E5261
+525C84AF527D528252815290529351827F544EBB4EC34EC94EC24EE84EE14EEB
+4EDE4F1B4EF34F224F644EF54F254F274F094F2B4F5E4F6765384F5A4F5D0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+59
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00004F5F4F574F324F3D4F764F744F914F894F834F8F4F7E4F7B4FAA4F7C4FAC
+4F944FE64FE84FEA4FC54FDA4FE34FDC4FD14FDF4FF85029504C4FF3502C500F
+502E502D4FFE501C500C50255028507E504350555048504E506C507B50A550A7
+50A950BA50D6510650ED50EC50E650EE5107510B4EDD6C3D4F584F654FCE9FA0
+6C467C74516E5DFD9EC999985181591452F9530D8A07531051EB591951554EA0
+51564EB3886E88A44EB5811488D279805B3488037FB851AB51B151BD51BC0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+5A
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000051C7519651A251A58BA08BA68BA78BAA8BB48BB58BB78BC28BC38BCB8BCF
+8BCE8BD28BD38BD48BD68BD88BD98BDC8BDF8BE08BE48BE88BE98BEE8BF08BF3
+8BF68BF98BFC8BFF8C008C028C048C078C0C8C0F8C118C128C148C158C168C19
+8C1B8C188C1D8C1F8C208C218C258C278C2A8C2B8C2E8C2F8C328C338C358C36
+5369537A961D962296219631962A963D963C964296499654965F9667966C9672
+96749688968D969796B09097909B909D909990AC90A190B490B390B690BA0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+5B
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000090B890B090CF90C590BE90D090C490C790D390E690E290DC90D790DB90EB
+90EF90FE91049122911E91239131912F913991439146520D594252A252AC52AD
+52BE54FF52D052D652F053DF71EE77CD5EF451F551FC9B2F53B65F01755A5DEF
+574C57A957A1587E58BC58C558D15729572C572A57335739572E572F575C573B
+574257695785576B5786577C577B5768576D5776577357AD57A4578C57B257CF
+57A757B4579357A057D557D857DA57D957D257B857F457EF57F857E457DD0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+5C
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000580B580D57FD57ED5800581E5819584458205865586C58815889589A5880
+99A89F1961FF8279827D827F828F828A82A88284828E82918297829982AB82B8
+82BE82B082C882CA82E3829882B782AE82CB82CC82C182A982B482A182AA829F
+82C482CE82A482E1830982F782E4830F830782DC82F482D282D8830C82FB82D3
+8311831A83068314831582E082D5831C8351835B835C83088392833C83348331
+839B835E832F834F83478343835F834083178360832D833A8333836683650000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+5D
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00008368831B8369836C836A836D836E83B0837883B383B483A083AA8393839C
+8385837C83B683A9837D83B8837B8398839E83A883BA83BC83C1840183E583D8
+58078418840B83DD83FD83D6841C84388411840683D483DF840F840383F883F9
+83EA83C583C0842683F083E1845C8451845A8459847384878488847A84898478
+843C844684698476848C848E8431846D84C184CD84D084E684BD84D384CA84BF
+84BA84E084A184B984B4849784E584E3850C750D853884F08539851F853A0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+5E
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00008556853B84FF84FC8559854885688564855E857A77A285438572857B85A4
+85A88587858F857985AE859C858585B985B785B085D385C185DC85FF86278605
+86298616863C5EFE5F08593C594180375955595A5958530F5C225C255C2C5C34
+624C626A629F62BB62CA62DA62D762EE632262F66339634B634363AD63F66371
+637A638E63B4636D63AC638A636963AE63BC63F263F863E063FF63C463DE63CE
+645263C663BE64456441640B641B6420640C64266421645E6484646D64960000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+5F
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000647A64B764B8649964BA64C064D064D764E464E265096525652E5F0B5FD2
+75195F11535F53F153FD53E953E853FB541254165406544B5452545354545456
+54435421545754595423543254825494547754715464549A549B548454765466
+549D54D054AD54C254B454D254A754A654D354D4547254A354D554BB54BF54CC
+54D954DA54DC54A954AA54A454DD54CF54DE551B54E7552054FD551454F35522
+5523550F55115527552A5567558F55B55549556D55415555553F5550553C0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+60
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00005537555655755576557755335530555C558B55D2558355B155B955885581
+559F557E55D65591557B55DF55BD55BE5594559955EA55F755C9561F55D155EB
+55EC55D455E655DD55C455EF55E555F255F355CC55CD55E855F555E48F94561E
+5608560C56015624562355FE56005627562D565856395657562C564D56625659
+565C564C5654568656645671566B567B567C5685569356AF56D456D756DD56E1
+56F556EB56F956FF5704570A5709571C5E0F5E195E145E115E315E3B5E3C0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+61
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00005E375E445E545E5B5E5E5E615C8C5C7A5C8D5C905C965C885C985C995C91
+5C9A5C9C5CB55CA25CBD5CAC5CAB5CB15CA35CC15CB75CC45CD25CE45CCB5CE5
+5D025D035D275D265D2E5D245D1E5D065D1B5D585D3E5D345D3D5D6C5D5B5D6F
+5D5D5D6B5D4B5D4A5D695D745D825D995D9D8C735DB75DC55F735F775F825F87
+5F895F8C5F955F995F9C5FA85FAD5FB55FBC88625F6172AD72B072B472B772B8
+72C372C172CE72CD72D272E872EF72E972F272F472F7730172F3730372FA0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+62
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000072FB731773137321730A731E731D7315732273397325732C733873317350
+734D73577360736C736F737E821B592598E7592459029963996799689969996A
+996B996C99749977997D998099849987998A998D999099919993999499955E80
+5E915E8B5E965EA55EA05EB95EB55EBE5EB38D535ED25ED15EDB5EE85EEA81BA
+5FC45FC95FD65FCF60035FEE60045FE15FE45FFE600560065FEA5FED5FF86019
+60356026601B600F600D6029602B600A603F602160786079607B607A60420000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+63
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000606A607D6096609A60AD609D60836092608C609B60EC60BB60B160DD60D8
+60C660DA60B4612061266115612360F46100610E612B614A617561AC619461A7
+61B761D461F55FDD96B395E995EB95F195F395F595F695FC95FE960396049606
+9608960A960B960C960D960F96129615961696179619961A4E2C723F62156C35
+6C546C5C6C4A6CA36C856C906C946C8C6C686C696C746C766C866CA96CD06CD4
+6CAD6CF76CF86CF16CD76CB26CE06CD66CFA6CEB6CEE6CB16CD36CEF6CFE0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+64
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00006D396D276D0C6D436D486D076D046D196D0E6D2B6D4D6D2E6D356D1A6D4F
+6D526D546D336D916D6F6D9E6DA06D5E6D936D946D5C6D606D7C6D636E1A6DC7
+6DC56DDE6E0E6DBF6DE06E116DE66DDD6DD96E166DAB6E0C6DAE6E2B6E6E6E4E
+6E6B6EB26E5F6E866E536E546E326E256E446EDF6EB16E986EE06F2D6EE26EA5
+6EA76EBD6EBB6EB76ED76EB46ECF6E8F6EC26E9F6F626F466F476F246F156EF9
+6F2F6F366F4B6F746F2A6F096F296F896F8D6F8C6F786F726F7C6F7A6FD10000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+65
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00006FC96FA76FB96FB66FC26FE16FEE6FDE6FE06FEF701A7023701B70397035
+704F705E5B805B845B955B935BA55BB8752F9A9E64345BE45BEE89305BF08E47
+8B078FB68FD38FD58FE58FEE8FE48FE98FE68FF38FE890059004900B90269011
+900D9016902190359036902D902F9044905190529050906890589062905B66B9
+9074907D908290889083908B5F505F575F565F585C3B54AB5C505C595B715C63
+5C667FBC5F2A5F295F2D82745F3C9B3B5C6E59815983598D59A959AA59A30000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+66
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000599759CA59AB599E59A459D259B259AF59D759BE5A055A0659DD5A0859E3
+59D859F95A0C5A095A325A345A115A235A135A405A675A4A5A555A3C5A625A75
+80EC5AAA5A9B5A775A7A5ABE5AEB5AB25AD25AD45AB85AE05AE35AF15AD65AE6
+5AD85ADC5B095B175B165B325B375B405C155C1C5B5A5B655B735B515B535B62
+9A759A779A789A7A9A7F9A7D9A809A819A859A889A8A9A909A929A939A969A98
+9A9B9A9C9A9D9A9F9AA09AA29AA39AA59AA77E9F7EA17EA37EA57EA87EA90000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+67
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00007EAD7EB07EBE7EC07EC17EC27EC97ECB7ECC7ED07ED47ED77EDB7EE07EE1
+7EE87EEB7EEE7EEF7EF17EF27F0D7EF67EFA7EFB7EFE7F017F027F037F077F08
+7F0B7F0C7F0F7F117F127F177F197F1C7F1B7F1F7F217F227F237F247F257F26
+7F277F2A7F2B7F2C7F2D7F2F7F307F317F327F337F355E7A757F5DDB753E9095
+738E739173AE73A2739F73CF73C273D173B773B373C073C973C873E573D9987C
+740A73E973E773DE73BA73F2740F742A745B7426742574287430742E742C0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+68
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000741B741A7441745C7457745574597477746D747E749C748E748074817487
+748B749E74A874A9749074A774D274BA97EA97EB97EC674C6753675E67486769
+67A56787676A6773679867A7677567A8679E67AD678B6777677C67F0680967D8
+680A67E967B0680C67D967B567DA67B367DD680067C367B867E2680E67C167FD
+6832683368606861684E6862684468646883681D68556866684168676840683E
+684A6849682968B5688F687468776893686B68C2696E68FC691F692068F90000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+69
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000692468F0690B6901695768E369106971693969606942695D6984696B6980
+69986978693469CC6987698869CE6989696669636979699B69A769BB69AB69AD
+69D469B169C169CA69DF699569E0698D69FF6A2F69ED6A176A186A6569F26A44
+6A3E6AA06A506A5B6A356A8E6A796A3D6A286A586A7C6A916A906AA96A976AAB
+733773526B816B826B876B846B926B936B8D6B9A6B9B6BA16BAA8F6B8F6D8F71
+8F728F738F758F768F788F778F798F7A8F7C8F7E8F818F828F848F878F8B0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+6A
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00008F8D8F8E8F8F8F988F9A8ECE620B6217621B621F6222622162256224622C
+81E774EF74F474FF750F75117513653465EE65EF65F0660A6619677266036615
+6600708566F7661D66346631663666358006665F66546641664F665666616657
+66776684668C66A7669D66BE66DB66DC66E666E98D328D338D368D3B8D3D8D40
+8D458D468D488D498D478D4D8D558D5989C789CA89CB89CC89CE89CF89D089D1
+726E729F725D7266726F727E727F7284728B728D728F72926308633263B00000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+6B
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000643F64D880046BEA6BF36BFD6BF56BF96C056C076C066C0D6C156C186C19
+6C1A6C216C296C246C2A6C3265356555656B724D72527256723086625216809F
+809C809380BC670A80BD80B180AB80AD80B480B780E780E880E980EA80DB80C2
+80C480D980CD80D7671080DD80EB80F180F480ED810D810E80F280FC67158112
+8C5A8136811E812C811881328148814C815381748159815A817181608169817C
+817D816D8167584D5AB58188818281916ED581A381AA81CC672681CA81BB0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+6C
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000081C181A66B246B376B396B436B466B5998D198D298D398D598D998DA6BB3
+5F406BC289F365909F51659365BC65C665C465C365CC65CE65D265D67080709C
+7096709D70BB70C070B770AB70B170E870CA711071137116712F71317173715C
+716871457172714A7178717A719871B371B571A871A071E071D471E771F9721D
+7228706C7118716671B9623E623D624362486249793B794079467949795B795C
+7953795A796279577960796F7967797A7985798A799A79A779B35FD15FD00000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+6D
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000603C605D605A606760416059606360AB6106610D615D61A9619D61CB61D1
+62068080807F6C936CF66DFC77F677F87800780978177818781165AB782D781C
+781D7839783A783B781F783C7825782C78237829784E786D7856785778267850
+7847784C786A789B7893789A7887789C78A178A378B278B978A578D478D978C9
+78EC78F2790578F479137924791E79349F9B9EF99EFB9EFC76F17704770D76F9
+77077708771A77227719772D7726773577387750775177477743775A77680000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+6E
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000077627765777F778D777D7780778C7791779F77A077B077B577BD753A7540
+754E754B7548755B7572757975837F587F617F5F8A487F687F747F717F797F81
+7F7E76CD76E58832948594869487948B948A948C948D948F9490949494979495
+949A949B949C94A394A494AB94AA94AD94AC94AF94B094B294B494B694B794B8
+94B994BA94BC94BD94BF94C494C894C994CA94CB94CC94CD94CE94D094D194D2
+94D594D694D794D994D894DB94DE94DF94E094E294E494E594E794E894EA0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+6F
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000094E994EB94EE94EF94F394F494F594F794F994FC94FD94FF950395029506
+95079509950A950D950E950F951295139514951595169518951B951D951E951F
+9522952A952B9529952C953195329534953695379538953C953E953F95429535
+9544954595469549954C954E954F9552955395549556955795589559955B955E
+955F955D95619562956495659566956795689569956A956B956C956F95719572
+9573953A77E777EC96C979D579ED79E379EB7A065D477A037A027A1E7A140000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+70
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00007A397A377A519ECF99A57A707688768E7693769976A474DE74E0752C9E20
+9E229E289E299E2A9E2B9E2C9E329E319E369E389E379E399E3A9E3E9E419E42
+9E449E469E479E489E499E4B9E4C9E4E9E519E559E579E5A9E5B9E5C9E5E9E63
+9E669E679E689E699E6A9E6B9E6C9E719E6D9E7375927594759675A0759D75AC
+75A375B375B475B875C475B175B075C375C275D675CD75E375E875E675E475EB
+75E7760375F175FC75FF761076007605760C7617760A76257618761576190000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+71
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000761B763C762276207640762D7630763F76357643763E7633764D765E7654
+765C7656766B766F7FCA7AE67A787A797A807A867A887A957AA67AA07AAC7AA8
+7AAD7AB3886488698872887D887F888288A288C688B788BC88C988E288CE88E3
+88E588F1891A88FC88E888FE88F0892189198913891B890A8934892B89368941
+8966897B758B80E576B276B477DC801280148016801C80208022802580268027
+802980288031800B803580438046804D80528069807189839878988098830000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+72
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00009889988C988D988F9894989A989B989E989F98A198A298A598A6864D8654
+866C866E867F867A867C867B86A8868D868B86AC869D86A786A386AA869386A9
+86B686C486B586CE86B086BA86B186AF86C986CF86B486E986F186F286ED86F3
+86D0871386DE86F486DF86D886D18703870786F88708870A870D87098723873B
+871E8725872E871A873E87488734873187298737873F87828722877D877E877B
+87608770874C876E878B87538763877C876487598765879387AF87A887D20000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+73
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000087C68788878587AD8797878387AB87E587AC87B587B387CB87D387BD87D1
+87C087CA87DB87EA87E087EE8816881387FE880A881B88218839883C7F367F42
+7F447F4582107AFA7AFD7B087B037B047B157B0A7B2B7B0F7B477B387B2A7B19
+7B2E7B317B207B257B247B337B3E7B1E7B587B5A7B457B757B4C7B5D7B607B6E
+7B7B7B627B727B717B907BA67BA77BB87BAC7B9D7BA87B857BAA7B9C7BA27BAB
+7BB47BD17BC17BCC7BDD7BDA7BE57BE67BEA7C0C7BFE7BFC7C0F7C167C0B0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+74
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00007C1F7C2A7C267C387C417C4081FE82018202820481EC8844822182228223
+822D822F8228822B8238823B82338234823E82448249824B824F825A825F8268
+887E8885888888D888DF895E7F9D7F9F7FA77FAF7FB07FB27C7C65497C917C9D
+7C9C7C9E7CA27CB27CBC7CBD7CC17CC77CCC7CCD7CC87CC57CD77CE8826E66A8
+7FBF7FCE7FD57FE57FE17FE67FE97FEE7FF37CF87D777DA67DAE7E477E9B9EB8
+9EB48D738D848D948D918DB18D678D6D8C478C49914A9150914E914F91640000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+75
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00009162916191709169916F917D917E917291749179918C91859190918D9191
+91A291A391AA91AD91AE91AF91B591B491BA8C559E7E8DB88DEB8E058E598E69
+8DB58DBF8DBC8DBA8DC48DD68DD78DDA8DDE8DCE8DCF8DDB8DC68DEC8DF78DF8
+8DE38DF98DFB8DE48E098DFD8E148E1D8E1F8E2C8E2E8E238E2F8E3A8E408E39
+8E358E3D8E318E498E418E428E518E528E4A8E708E768E7C8E6F8E748E858E8F
+8E948E908E9C8E9E8C788C828C8A8C858C988C94659B89D689DE89DA89DC0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+76
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000089E589EB89EF8A3E8B26975396E996F396EF970697019708970F970E972A
+972D9730973E9F809F839F859F869F879F889F899F8A9F8C9EFE9F0B9F0D96B9
+96BC96BD96CE96D277BF96E0928E92AE92C8933E936A93CA938F943E946B9C7F
+9C829C859C869C879C887A239C8B9C8E9C909C919C929C949C959C9A9C9B9C9E
+9C9F9CA09CA19CA29CA39CA59CA69CA79CA89CA99CAB9CAD9CAE9CB09CB19CB2
+9CB39CB49CB59CB69CB79CBA9CBB9CBC9CBD9CC49CC59CC69CC79CCA9CCB0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+77
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00009CCC9CCD9CCE9CCF9CD09CD39CD49CD59CD79CD89CD99CDC9CDD9CDF9CE2
+977C978597919792979497AF97AB97A397B297B49AB19AB09AB79E589AB69ABA
+9ABC9AC19AC09AC59AC29ACB9ACC9AD19B459B439B479B499B489B4D9B5198E8
+990D992E995599549ADF9AE19AE69AEF9AEB9AFB9AED9AF99B089B0F9B139B1F
+9B239EBD9EBE7E3B9E829E879E889E8B9E9293D69E9D9E9F9EDB9EDC9EDD9EE0
+9EDF9EE29EE99EE79EE59EEA9EEF9F229F2C9F2F9F399F379F3D9F3E9F440000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
diff --git a/library/encoding/gb2312.enc b/library/encoding/gb2312.enc
new file mode 100644
index 0000000..4b2f8c7
--- /dev/null
+++ b/library/encoding/gb2312.enc
@@ -0,0 +1,1397 @@
+# Encoding file: euc-cn, multi-byte
+M
+003F 0 82
+00
+0000000100020003000400050006000700080009000A000B000C000D000E000F
+0010001100120013001400150016001700180019001A001B001C001D001E001F
+0020002100220023002400250026002700280029002A002B002C002D002E002F
+0030003100320033003400350036003700380039003A003B003C003D003E003F
+0040004100420043004400450046004700480049004A004B004C004D004E004F
+0050005100520053005400550056005700580059005A005B005C005D005E005F
+0060006100620063006400650066006700680069006A006B006C006D006E006F
+0070007100720073007400750076007700780079007A007B007C007D007E007F
+0080008100820083008400850086008700880089008A008B008C008D008E008F
+0090009100920093009400950096009700980099009A009B009C009D009E009F
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+A1
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000030003001300230FB02C902C700A8300330052015FF5E2225202620182019
+201C201D3014301530083009300A300B300C300D300E300F3016301730103011
+00B100D700F72236222722282211220F222A222922082237221A22A522252220
+23122299222B222E2261224C2248223D221D2260226E226F22642265221E2235
+22342642264000B0203220332103FF0400A4FFE0FFE1203000A7211626062605
+25CB25CF25CE25C725C625A125A025B325B2203B219221902191219330130000
+A2
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000024882489248A248B248C248D248E248F2490249124922493249424952496
+249724982499249A249B247424752476247724782479247A247B247C247D247E
+247F248024812482248324842485248624872460246124622463246424652466
+2467246824690000000032203221322232233224322532263227322832290000
+00002160216121622163216421652166216721682169216A216B000000000000
+A3
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000FF01FF02FF03FFE5FF05FF06FF07FF08FF09FF0AFF0BFF0CFF0DFF0EFF0F
+FF10FF11FF12FF13FF14FF15FF16FF17FF18FF19FF1AFF1BFF1CFF1DFF1EFF1F
+FF20FF21FF22FF23FF24FF25FF26FF27FF28FF29FF2AFF2BFF2CFF2DFF2EFF2F
+FF30FF31FF32FF33FF34FF35FF36FF37FF38FF39FF3AFF3BFF3CFF3DFF3EFF3F
+FF40FF41FF42FF43FF44FF45FF46FF47FF48FF49FF4AFF4BFF4CFF4DFF4EFF4F
+FF50FF51FF52FF53FF54FF55FF56FF57FF58FF59FF5AFF5BFF5CFF5DFFE30000
+A4
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000304130423043304430453046304730483049304A304B304C304D304E304F
+3050305130523053305430553056305730583059305A305B305C305D305E305F
+3060306130623063306430653066306730683069306A306B306C306D306E306F
+3070307130723073307430753076307730783079307A307B307C307D307E307F
+3080308130823083308430853086308730883089308A308B308C308D308E308F
+3090309130923093000000000000000000000000000000000000000000000000
+A5
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000030A130A230A330A430A530A630A730A830A930AA30AB30AC30AD30AE30AF
+30B030B130B230B330B430B530B630B730B830B930BA30BB30BC30BD30BE30BF
+30C030C130C230C330C430C530C630C730C830C930CA30CB30CC30CD30CE30CF
+30D030D130D230D330D430D530D630D730D830D930DA30DB30DC30DD30DE30DF
+30E030E130E230E330E430E530E630E730E830E930EA30EB30EC30ED30EE30EF
+30F030F130F230F330F430F530F6000000000000000000000000000000000000
+A6
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000039103920393039403950396039703980399039A039B039C039D039E039F
+03A003A103A303A403A503A603A703A803A90000000000000000000000000000
+000003B103B203B303B403B503B603B703B803B903BA03BB03BC03BD03BE03BF
+03C003C103C303C403C503C603C703C803C90000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+A7
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000004100411041204130414041504010416041704180419041A041B041C041D
+041E041F0420042104220423042404250426042704280429042A042B042C042D
+042E042F00000000000000000000000000000000000000000000000000000000
+000004300431043204330434043504510436043704380439043A043B043C043D
+043E043F0440044104420443044404450446044704480449044A044B044C044D
+044E044F00000000000000000000000000000000000000000000000000000000
+A8
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000010100E101CE00E0011300E9011B00E8012B00ED01D000EC014D00F301D2
+00F2016B00FA01D400F901D601D801DA01DC00FC00EA00000000000000000000
+0000000000000000000031053106310731083109310A310B310C310D310E310F
+3110311131123113311431153116311731183119311A311B311C311D311E311F
+3120312131223123312431253126312731283129000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+A9
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00000000000000002500250125022503250425052506250725082509250A250B
+250C250D250E250F2510251125122513251425152516251725182519251A251B
+251C251D251E251F2520252125222523252425252526252725282529252A252B
+252C252D252E252F2530253125322533253425352536253725382539253A253B
+253C253D253E253F2540254125422543254425452546254725482549254A254B
+0000000000000000000000000000000000000000000000000000000000000000
+B0
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000554A963F57C3632854CE550954C07691764C853C77EE827E788D72319698
+978D6C285B894FFA630966975CB880FA684880AE660276CE51F9655671AC7FF1
+888450B2596561CA6FB382AD634C625253ED54277B06516B75A45DF462D48DCB
+9776628A8019575D97387F627238767D67CF767E64464F708D2562DC7A176591
+73ED642C6273822C9881677F7248626E62CC4F3474E3534A529E7ECA90A65E2E
+6886699C81807ED168D278C5868C9551508D8C2482DE80DE5305891252650000
+B1
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000858496F94FDD582199715B9D62B162A566B48C799C8D7206676F789160B2
+535153178F8880CC8D1D94A1500D72C8590760EB711988AB595482EF672C7B28
+5D297EF7752D6CF58E668FF8903C9F3B6BD491197B145F7C78A784D6853D6BD5
+6BD96BD65E015E8775F995ED655D5F0A5FC58F9F58C181C2907F965B97AD8FB9
+7F168D2C62414FBF53D8535E8FA88FA98FAB904D68075F6A819888689CD6618B
+522B762A5F6C658C6FD26EE85BBE6448517551B067C44E1979C9997C70B30000
+B2
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000075C55E7673BB83E064AD62E894B56CE2535A52C3640F94C27B944F2F5E1B
+82368116818A6E246CCA9A736355535C54FA886557E04E0D5E036B657C3F90E8
+601664E6731C88C16750624D8D22776C8E2991C75F6983DC8521991053C28695
+6B8B60ED60E8707F82CD82314ED36CA785CF64CD7CD969FD66F9834953957B56
+4FA7518C6D4B5C428E6D63D253C9832C833667E578B4643D5BDF5C945DEE8BE7
+62C667F48C7A640063BA8749998B8C177F2094F24EA7961098A4660C73160000
+B3
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000573A5C1D5E38957F507F80A05382655E7545553150218D856284949E671D
+56326F6E5DE2543570928F66626F64A463A35F7B6F8890F481E38FB05C186668
+5FF16C8996488D81886C649179F057CE6A59621054484E587A0B60E96F848BDA
+627F901E9A8B79E4540375F4630153196C608FDF5F1B9A70803B9F7F4F885C3A
+8D647FC565A570BD514551B2866B5D075BA062BD916C75748E0C7A2061017B79
+4EC77EF877854E1181ED521D51FA6A7153A88E87950496CF6EC19664695A0000
+B4
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000784050A877D7641089E6590463E35DDD7A7F693D4F20823955984E3275AE
+7A975E625E8A95EF521B5439708A6376952457826625693F918755076DF37EAF
+882262337EF075B5832878C196CC8F9E614874F78BCD6B64523A8D506B21806A
+847156F153064ECE4E1B51D17C97918B7C074FC38E7F7BE17A9C64675D1450AC
+810676017CB96DEC7FE067515B585BF878CB64AE641363AA632B9519642D8FBE
+7B5476296253592754466B7950A362345E266B864EE38D37888B5F85902E0000
+B5
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00006020803D62C54E39535590F863B880C665E66C2E4F4660EE6DE18BDE5F39
+86CB5F536321515A83616863520063638E4850125C9B79775BFC52307A3B60BC
+905376D75FB75F9776848E6C706F767B7B4977AA51F3909358244F4E6EF48FEA
+654C7B1B72C46DA47FDF5AE162B55E95573084827B2C5E1D5F1F90127F1498A0
+63826EC7789870B95178975B57AB75354F4375385E9760E659606DC06BBF7889
+53FC96D551CB52016389540A94938C038DCC7239789F87768FED8C0D53E00000
+B6
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00004E0176EF53EE948998769F0E952D5B9A8BA24E224E1C51AC846361C252A8
+680B4F97606B51BB6D1E515C6296659796618C46901775D890FD77636BD2728A
+72EC8BFB583577798D4C675C9540809A5EA66E2159927AEF77ED953B6BB565AD
+7F0E58065151961F5BF958A954288E726566987F56E4949D76FE9041638754C6
+591A593A579B8EB267358DFA8235524160F0581586FE5CE89E454FC4989D8BB9
+5A2560765384627C904F9102997F6069800C513F80335C1499756D314E8C0000
+B7
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00008D3053D17F5A7B4F4F104E4F96006CD573D085E95E06756A7FFB6A0A77FE
+94927E4151E170E653CD8FD483038D2972AF996D6CDB574A82B365B980AA623F
+963259A84EFF8BBF7EBA653E83F2975E556198DE80A5532A8BFD542080BA5E9F
+6CB88D3982AC915A54296C1B52067EB7575F711A6C7E7C89594B4EFD5FFF6124
+7CAA4E305C0167AB87025CF0950B98CE75AF70FD902251AF7F1D8BBD594951E4
+4F5B5426592B657780A45B75627662C28F905E456C1F7B264F0F4FD8670D0000
+B8
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00006D6E6DAA798F88B15F17752B629A8F854FEF91DC65A7812F81515E9C8150
+8D74526F89868D4B590D50854ED8961C723681798D1F5BCC8BA3964459877F1A
+54905676560E8BE565396982949976D66E895E727518674667D17AFF809D8D76
+611F79C665628D635188521A94A27F38809B7EB25C976E2F67607BD9768B9AD8
+818F7F947CD5641E95507A3F544A54E56B4C640162089E3D80F3759952729769
+845B683C86E49601969494EC4E2A54047ED968398DDF801566F45E9A7FB90000
+B9
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000057C2803F68975DE5653B529F606D9F9A4F9B8EAC516C5BAB5F135DE96C5E
+62F18D21517194A952FE6C9F82DF72D757A267848D2D591F8F9C83C754957B8D
+4F306CBD5B6459D19F1353E486CA9AA88C3780A16545987E56FA96C7522E74DC
+52505BE1630289024E5662D0602A68FA51735B9851A089C27BA199867F5060EF
+704C8D2F51495E7F901B747089C4572D78455F529F9F95FA8F689B3C8BE17678
+684267DC8DEA8D35523D8F8A6EDA68CD950590ED56FD679C88F98FC754C80000
+BA
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00009AB85B696D776C264EA55BB39A87916361A890AF97E9542B6DB55BD251FD
+558A7F557FF064BC634D65F161BE608D710A6C576C49592F676D822A58D5568E
+8C6A6BEB90DD597D801753F76D695475559D837783CF683879BE548C4F555408
+76D28C8996026CB36DB88D6B89109E648D3A563F9ED175D55F8872E0606854FC
+4EA86A2A886160528F7054C470D886799E3F6D2A5B8F5F187EA255894FAF7334
+543C539A5019540E547C4E4E5FFD745A58F6846B80E1877472D07CCA6E560000
+BB
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00005F27864E552C62A44E926CAA623782B154D7534E733E6ED1753B52125316
+8BDD69D05F8A60006DEE574F6B2273AF68538FD87F13636260A3552475EA8C62
+71156DA35BA65E7B8352614C9EC478FA87577C27768751F060F6714C66435E4C
+604D8C0E707063258F895FBD606286D456DE6BC160946167534960E066668D3F
+79FD4F1A70E96C478BB38BF27ED88364660F5A5A9B426D516DF78C416D3B4F19
+706B83B7621660D1970D8D27797851FB573E57FA673A75787A3D79EF7B950000
+BC
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000808C99658FF96FC08BA59E2159EC7EE97F095409678168D88F917C4D96C6
+53CA602575BE6C7253735AC97EA7632451E0810A5DF184DF628051805B634F0E
+796D524260B86D4E5BC45BC28BA18BB065E25FCC964559937EE77EAA560967B7
+59394F735BB652A0835A988A8D3E753294BE50477A3C4EF767B69A7E5AC16B7C
+76D1575A5C167B3A95F4714E517C80A9827059787F04832768C067EC78B17877
+62E363617B804FED526A51CF835069DB92748DF58D3189C1952E7BAD4EF60000
+BD
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000506582305251996F6E106E856DA75EFA50F559DC5C066D466C5F7586848B
+686859568BB253209171964D854969127901712680F64EA490CA6D479A845A07
+56BC640594F077EB4FA5811A72E189D2997A7F347EDE527F655991758F7F8F83
+53EB7A9663ED63A5768679F888579636622A52AB8282685467706377776B7AED
+6D017ED389E359D0621285C982A5754C501F4ECB75A58BEB5C4A5DFE7B4B65A4
+91D14ECA6D25895F7D2795264EC58C288FDB9773664B79818FD170EC6D780000
+BE
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00005C3D52B283465162830E775B66769CB84EAC60CA7CBE7CB37ECF4E958B66
+666F988897595883656C955C5F8475C997567ADF7ADE51C070AF7A9863EA7A76
+7EA0739697ED4E4570784E5D915253A9655165E781FC8205548E5C31759A97A0
+62D872D975BD5C459A7983CA5C40548077E94E3E6CAE805A62D2636E5DE85177
+8DDD8E1E952F4FF153E560E770AC526763509E435A1F5026773753777EE26485
+652B628963985014723589C951B38BC07EDD574783CC94A7519B541B5CFB0000
+BF
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00004FCA7AE36D5A90E19A8F55805496536154AF5F0063E9697751EF6168520A
+582A52D8574E780D770B5EB761777CE0625B62974EA27095800362F770E49760
+577782DB67EF68F578D5989779D158F354B353EF6E34514B523B5BA28BFE80AF
+554357A660735751542D7A7A60505B5463A762A053E362635BC767AF54ED7A9F
+82E691775E9388E4593857AE630E8DE880EF57577B774FA95FEB5BBD6B3E5321
+7B5072C2684677FF773665F751B54E8F76D45CBF7AA58475594E9B4150800000
+C0
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000998861276E8357646606634656F062EC62695ED39614578362C955878721
+814A8FA3556683B167658D5684DD5A6A680F62E67BEE961151706F9C8C3063FD
+89C861D27F0670C26EE57405699472FC5ECA90CE67176D6A635E52B372628001
+4F6C59E5916A70D96D9D52D24E5096F7956D857E78CA7D2F5121579264C2808B
+7C7B6CEA68F1695E51B7539868A872819ECE7BF172F879BB6F137406674E91CC
+9CA4793C83898354540F68174E3D538952B1783E5386522950884F8B4FD00000
+C1
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000075E27ACB7C926CA596B6529B748354E94FE9805483B28FDE95705EC9601C
+6D9F5E18655B813894FE604B70BC7EC37CAE51C968817CB1826F4E248F8691CF
+667E4EAE8C0564A9804A50DA759771CE5BE58FBD6F664E86648295635ED66599
+521788C270C852A3730E7433679778F797164E3490BB9CDE6DCB51DB8D41541D
+62CE73B283F196F69F8494C34F367F9A51CC707596755CAD988653E64EE46E9C
+740969B4786B998F7559521876246D4167F3516D9F99804B54997B3C7ABF0000
+C2
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00009686578462E29647697C5A0464027BD36F0F964B82A6536298855E907089
+63B35364864F9C819E93788C97328DEF8D429E7F6F5E79845F559646622E9A74
+541594DD4FA365C55C655C617F1586516C2F5F8B73876EE47EFF5CE6631B5B6A
+6EE653754E7163A0756562A18F6E4F264ED16CA67EB68BBA841D87BA7F57903B
+95237BA99AA188F8843D6D1B9A867EDC59889EBB739B780186829A6C9A82561B
+541757CB4E709EA653568FC881097792999286EE6EE1851366FC61626F2B0000
+C3
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00008C298292832B76F26C135FD983BD732B8305951A6BDB77DB94C6536F8302
+51925E3D8C8C8D384E4873AB679A68859176970971646CA177095A9295416BCF
+7F8E66275BD059B95A9A95E895F74EEC840C84996AAC76DF9530731B68A65B5F
+772F919A97617CDC8FF78C1C5F257C7379D889C56CCC871C5BC65E4268C97720
+7EF55195514D52C95A297F05976282D763CF778485D079D26E3A5E9959998511
+706D6C1162BF76BF654F60AF95FD660E879F9E2394ED540D547D8C2C64780000
+C4
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000647986116A21819C78E864699B5462B9672B83AB58A89ED86CAB6F205BDE
+964C8C0B725F67D062C772614EA959C66BCD589366AE5E5552DF6155672876EE
+776672677A4662FF54EA545094A090A35A1C7EB36C164E435976801059485357
+753796BE56CA63208111607C95F96DD65462998151855AE980FD59AE9713502A
+6CE55C3C62DF4F60533F817B90066EBA852B62C85E7478BE64B5637B5FF55A18
+917F9E1F5C3F634F80425B7D556E954A954D6D8560A867E072DE51DD5B810000
+C5
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000062E76CDE725B626D94AE7EBD81136D53519C5F04597452AA601259736696
+8650759F632A61E67CEF8BFA54E66B279E256BB485D5545550766CA4556A8DB4
+722C5E156015743662CD6392724C5F986E436D3E65006F5876D878D076FC7554
+522453DB4E535E9E65C1802A80D6629B5486522870AE888D8DD16CE1547880DA
+57F988F48D54966A914D4F696C9B55B776C6783062A870F96F8E5F6D84EC68DA
+787C7BF781A8670B9E4F636778B0576F78129739627962AB528874356BD70000
+C6
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00005564813E75B276AE533975DE50FB5C418B6C7BC7504F72479A9798D86F02
+74E27968648777A562FC98918D2B54C180584E52576A82F9840D5E7351ED74F6
+8BC45C4F57616CFC98875A4678349B448FEB7C955256625194FA4EC683868461
+83E984B257D467345703666E6D668C3166DD7011671F6B3A6816621A59BB4E03
+51C46F0667D26C8F517668CB59476B6775665D0E81109F5065D7794879419A91
+8D775C824E5E4F01542F5951780C56686C148FC45F036C7D6CE38BAB63900000
+C7
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000060706D3D72756266948E94C553438FC17B7E4EDF8C264E7E9ED494B194B3
+524D6F5C90636D458C3458115D4C6B206B4967AA545B81547F8C589985375F3A
+62A26A47953965726084686577A74E544FA85DE7979864AC7FD85CED4FCF7A8D
+520783044E14602F7A8394A64FB54EB279E6743452E482B964D279BD5BDD6C81
+97528F7B6C22503E537F6E0564CE66746C3060C598778BF75E86743C7A7779CB
+4E1890B174036C4256DA914B6CC58D8B533A86C666F28EAF5C489A716E200000
+C8
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000053D65A369F8B8DA353BB570898A76743919B6CC9516875CA62F372AC5238
+529D7F3A7094763853749E4A69B7786E96C088D97FA4713671C3518967D374E4
+58E4651856B78BA9997662707ED560F970ED58EC4EC14EBA5FCD97E74EFB8BA4
+5203598A7EAB62544ECD65E5620E833884C98363878D71946EB65BB97ED25197
+63C967D480898339881551125B7A59828FB14E736C5D516589258F6F962E854A
+745E951095F06DA682E55F3164926D128428816E9CC3585E8D5B4E0953C10000
+C9
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00004F1E6563685155D34E2764149A9A626B5AC2745F82726DA968EE50E7838E
+7802674052396C997EB150BB5565715E7B5B665273CA82EB67495C715220717D
+886B95EA965564C58D6181B355846C5562477F2E58924F2455468D4F664C4E0A
+5C1A88F368A2634E7A0D70E7828D52FA97F65C1154E890B57ECD59628D4A86C7
+820C820D8D6664445C0461516D89793E8BBE78377533547B4F388EAB6DF15A20
+7EC5795E6C885BA15A76751A80BE614E6E1758F0751F7525727253477EF30000
+CA
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000770176DB526980DC57235E08593172EE65BD6E7F8BD75C388671534177F3
+62FE65F64EC098DF86805B9E8BC653F277E24F7F5C4E9A7659CB5F0F793A58EB
+4E1667FF4E8B62ED8A93901D52BF662F55DC566C90024ED54F8D91CA99706C0F
+5E0260435BA489C68BD56536624B99965B885BFF6388552E53D77626517D852C
+67A268B36B8A62928F9353D482126DD1758F4E668D4E5B70719F85AF669166D9
+7F7287009ECD9F205C5E672F8FF06811675F620D7AD658855EB665706F310000
+CB
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000060555237800D6454887075295E05681362F4971C53CC723D8C016C347761
+7A0E542E77AC987A821C8BF47855671470C165AF64955636601D79C153F84E1D
+6B7B80865BFA55E356DB4F3A4F3C99725DF3677E80386002988290015B8B8BBC
+8BF5641C825864DE55FD82CF91654FD77D20901F7C9F50F358516EAF5BBF8BC9
+80839178849C7B97867D968B968F7EE59AD3788E5C817A57904296A7795F5B59
+635F7B0B84D168AD55067F2974107D2295016240584C4ED65B83597958540000
+CC
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000736D631E8E4B8E0F80CE82D462AC53F06CF0915E592A60016C70574D644A
+8D2A762B6EE9575B6A8075F06F6D8C2D8C0857666BEF889278B363A253F970AD
+6C645858642A580268E0819B55107CD650188EBA6DCC8D9F70EB638F6D9B6ED4
+7EE68404684390036DD896768BA85957727985E4817E75BC8A8A68AF52548E22
+951163D098988E44557C4F5366FF568F60D56D9552435C4959296DFB586B7530
+751C606C82148146631167618FE2773A8DF38D3494C15E165385542C70C30000
+CD
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00006C405EF7505C4EAD5EAD633A8247901A6850916E77B3540C94DC5F647AE5
+687663457B527EDF75DB507762955934900F51F879C37A8156FE5F9290146D82
+5C60571F541051546E4D56E263A89893817F8715892A9000541E5C6F81C062D6
+625881319E3596409A6E9A7C692D59A562D3553E631654C786D96D3C5A0374E6
+889C6B6A59168C4C5F2F6E7E73A9987D4E3870F75B8C7897633D665A769660CB
+5B9B5A494E0781556C6A738B4EA167897F515F8065FA671B5FD859845A010000
+CE
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00005DCD5FAE537197E68FDD684556F4552F60DF4E3A6F4D7EF482C7840E59D4
+4F1F4F2A5C3E7EAC672A851A5473754F80C355829B4F4F4D6E2D8C135C096170
+536B761F6E29868A658795FB7EB9543B7A337D0A95EE55E17FC174EE631D8717
+6DA17A9D621165A1536763E16C835DEB545C94A84E4C6C618BEC5C4B65E0829C
+68A7543E54346BCB6B664E9463425348821E4F0D4FAE575E620A96FE66647269
+52FF52A1609F8BEF661471996790897F785277FD6670563B54389521727A0000
+CF
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00007A00606F5E0C6089819D591560DC718470EF6EAA6C5072806A8488AD5E2D
+4E605AB3559C94E36D177CFB9699620F7EC6778E867E5323971E8F9666875CE1
+4FA072ED4E0B53A6590F54136380952851484ED99C9C7EA454B88D2488548237
+95F26D8E5F265ACC663E966973B0732E53BF817A99857FA15BAA967796507EBF
+76F853A2957699997BB189446E584E617FD479658BE660F354CD4EAB98795DF7
+6A6150CF54118C618427785D9704524A54EE56A395006D885BB56DC666530000
+D0
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00005C0F5B5D6821809655787B11654869544E9B6B47874E978B534F631F643A
+90AA659C80C18C10519968B0537887F961C86CC46CFB8C225C5185AA82AF950C
+6B238F9B65B05FFB5FC34FE18845661F8165732960FA51745211578B5F6290A2
+884C91925E78674F602759D3514451F680F853086C7996C4718A4F114FEE7F9E
+673D55C5950879C088967EE3589F620C9700865A5618987B5F908BB884C49157
+53D965ED5E8F755C60647D6E5A7F7EEA7EED8F6955A75BA360AC65CB73840000
+D1
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00009009766377297EDA9774859B5B667A7496EA884052CB718F5FAA65EC8BE2
+5BFB9A6F5DE16B896C5B8BAD8BAF900A8FC5538B62BC9E269E2D54404E2B82BD
+7259869C5D1688596DAF96C554D14E9A8BB6710954BD960970DF6DF976D04E25
+781487125CA95EF68A00989C960E708E6CBF594463A9773C884D6F1482735830
+71D5538C781A96C155015F6671305BB48C1A9A8C6B83592E9E2F79E76768626C
+4F6F75A17F8A6D0B96336C274EF075D2517B68376F3E90808170599674760000
+D2
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000064475C2790657A918C2359DA54AC8200836F898180006930564E80367237
+91CE51B64E5F987563964E1A53F666F3814B591C6DB24E0058F9533B63D694F1
+4F9D4F0A886398905937905779FB4EEA80F075916C825B9C59E85F5D69058681
+501A5DF24E5977E34EE5827A6291661390915C794EBF5F7981C69038808475AB
+4EA688D4610F6BC55FC64E4976CA6EA28BE38BAE8C0A8BD15F027FFC7FCC7ECE
+8335836B56E06BB797F3963459FB541F94F66DEB5BC5996E5C395F1596900000
+D3
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000537082F16A315A749E705E947F2883B984248425836787478FCE8D6276C8
+5F719896786C662054DF62E54F6381C375C85EB896CD8E0A86F9548F6CF36D8C
+6C38607F52C775285E7D4F1860A05FE75C24753190AE94C072B96CB96E389149
+670953CB53F34F5191C98BF153C85E7C8FC26DE44E8E76C26986865E611A8206
+4F594FDE903E9C7C61096E1D6E1496854E885A3196E84E0E5C7F79B95B878BED
+7FBD738957DF828B90C15401904755BB5CEA5FA161086B3272F180B28A890000
+D4
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00006D745BD388D598848C6B9A6D9E336E0A51A4514357A38881539F63F48F95
+56ED54585706733F6E907F188FDC82D1613F6028966266F07EA68D8A8DC394A5
+5CB37CA4670860A6960580184E9190E75300966851418FD08574915D665597F5
+5B55531D78386742683D54C9707E5BB08F7D518D572854B1651266828D5E8D43
+810F846C906D7CDF51FF85FB67A365E96FA186A48E81566A90207682707671E5
+8D2362E952196CFD8D3C600E589E618E66FE8D60624E55B36E23672D8F670000
+D5
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000094E195F87728680569A8548B4E4D70B88BC86458658B5B857A84503A5BE8
+77BB6BE18A797C986CBE76CF65A98F975D2D5C5586386808536062187AD96E5B
+7EFD6A1F7AE05F706F335F20638C6DA867564E085E108D264ED780C07634969C
+62DB662D627E6CBC8D7571677F695146808753EC906E629854F286F08F998005
+951785178FD96D5973CD659F771F7504782781FB8D1E94884FA6679575B98BCA
+9707632F9547963584B8632377415F8172F04E896014657462EF6B63653F0000
+D6
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00005E2775C790D18BC1829D679D652F5431871877E580A281026C414E4B7EC7
+804C76F4690D6B966267503C4F84574063076B628DBE53EA65E87EB85FD7631A
+63B781F381F47F6E5E1C5CD95236667A79E97A1A8D28709975D46EDE6CBB7A92
+4E2D76C55FE0949F88777EC879CD80BF91CD4EF24F17821F54685DDE6D328BCC
+7CA58F7480985E1A549276B15B99663C9AA473E0682A86DB6731732A8BF88BDB
+90107AF970DB716E62C477A956314E3B845767F152A986C08D2E94F87B510000
+D7
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00004F4F6CE8795D9A7B6293722A62FD4E1378168F6C64B08D5A7BC668695E84
+88C55986649E58EE72B6690E95258FFD8D5857607F008C0651C6634962D95353
+684C74228301914C55447740707C6D4A517954A88D4459FF6ECB6DC45B5C7D2B
+4ED47C7D6ED35B5081EA6E0D5B579B0368D58E2A5B977EFC603B7EB590B98D70
+594F63CD79DF8DB3535265CF79568BC5963B7EC494BB7E825634918967007F6A
+5C0A907566285DE64F5067DE505A4F5C57505EA7000000000000000000000000
+D8
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00004E8D4E0C51404E105EFF53454E154E984E1E9B325B6C56694E2879BA4E3F
+53154E47592D723B536E6C1056DF80E499976BD3777E9F174E364E9F9F104E5C
+4E694E9382885B5B556C560F4EC4538D539D53A353A553AE97658D5D531A53F5
+5326532E533E8D5C5366536352025208520E522D5233523F5240524C525E5261
+525C84AF527D528252815290529351827F544EBB4EC34EC94EC24EE84EE14EEB
+4EDE4F1B4EF34F224F644EF54F254F274F094F2B4F5E4F6765384F5A4F5D0000
+D9
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00004F5F4F574F324F3D4F764F744F914F894F834F8F4F7E4F7B4FAA4F7C4FAC
+4F944FE64FE84FEA4FC54FDA4FE34FDC4FD14FDF4FF85029504C4FF3502C500F
+502E502D4FFE501C500C50255028507E504350555048504E506C507B50A550A7
+50A950BA50D6510650ED50EC50E650EE5107510B4EDD6C3D4F584F654FCE9FA0
+6C467C74516E5DFD9EC999985181591452F9530D8A07531051EB591951554EA0
+51564EB3886E88A44EB5811488D279805B3488037FB851AB51B151BD51BC0000
+DA
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000051C7519651A251A58BA08BA68BA78BAA8BB48BB58BB78BC28BC38BCB8BCF
+8BCE8BD28BD38BD48BD68BD88BD98BDC8BDF8BE08BE48BE88BE98BEE8BF08BF3
+8BF68BF98BFC8BFF8C008C028C048C078C0C8C0F8C118C128C148C158C168C19
+8C1B8C188C1D8C1F8C208C218C258C278C2A8C2B8C2E8C2F8C328C338C358C36
+5369537A961D962296219631962A963D963C964296499654965F9667966C9672
+96749688968D969796B09097909B909D909990AC90A190B490B390B690BA0000
+DB
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000090B890B090CF90C590BE90D090C490C790D390E690E290DC90D790DB90EB
+90EF90FE91049122911E91239131912F913991439146520D594252A252AC52AD
+52BE54FF52D052D652F053DF71EE77CD5EF451F551FC9B2F53B65F01755A5DEF
+574C57A957A1587E58BC58C558D15729572C572A57335739572E572F575C573B
+574257695785576B5786577C577B5768576D5776577357AD57A4578C57B257CF
+57A757B4579357A057D557D857DA57D957D257B857F457EF57F857E457DD0000
+DC
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000580B580D57FD57ED5800581E5819584458205865586C58815889589A5880
+99A89F1961FF8279827D827F828F828A82A88284828E82918297829982AB82B8
+82BE82B082C882CA82E3829882B782AE82CB82CC82C182A982B482A182AA829F
+82C482CE82A482E1830982F782E4830F830782DC82F482D282D8830C82FB82D3
+8311831A83068314831582E082D5831C8351835B835C83088392833C83348331
+839B835E832F834F83478343835F834083178360832D833A8333836683650000
+DD
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00008368831B8369836C836A836D836E83B0837883B383B483A083AA8393839C
+8385837C83B683A9837D83B8837B8398839E83A883BA83BC83C1840183E583D8
+58078418840B83DD83FD83D6841C84388411840683D483DF840F840383F883F9
+83EA83C583C0842683F083E1845C8451845A8459847384878488847A84898478
+843C844684698476848C848E8431846D84C184CD84D084E684BD84D384CA84BF
+84BA84E084A184B984B4849784E584E3850C750D853884F08539851F853A0000
+DE
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00008556853B84FF84FC8559854885688564855E857A77A285438572857B85A4
+85A88587858F857985AE859C858585B985B785B085D385C185DC85FF86278605
+86298616863C5EFE5F08593C594180375955595A5958530F5C225C255C2C5C34
+624C626A629F62BB62CA62DA62D762EE632262F66339634B634363AD63F66371
+637A638E63B4636D63AC638A636963AE63BC63F263F863E063FF63C463DE63CE
+645263C663BE64456441640B641B6420640C64266421645E6484646D64960000
+DF
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000647A64B764B8649964BA64C064D064D764E464E265096525652E5F0B5FD2
+75195F11535F53F153FD53E953E853FB541254165406544B5452545354545456
+54435421545754595423543254825494547754715464549A549B548454765466
+549D54D054AD54C254B454D254A754A654D354D4547254A354D554BB54BF54CC
+54D954DA54DC54A954AA54A454DD54CF54DE551B54E7552054FD551454F35522
+5523550F55115527552A5567558F55B55549556D55415555553F5550553C0000
+E0
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00005537555655755576557755335530555C558B55D2558355B155B955885581
+559F557E55D65591557B55DF55BD55BE5594559955EA55F755C9561F55D155EB
+55EC55D455E655DD55C455EF55E555F255F355CC55CD55E855F555E48F94561E
+5608560C56015624562355FE56005627562D565856395657562C564D56625659
+565C564C5654568656645671566B567B567C5685569356AF56D456D756DD56E1
+56F556EB56F956FF5704570A5709571C5E0F5E195E145E115E315E3B5E3C0000
+E1
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00005E375E445E545E5B5E5E5E615C8C5C7A5C8D5C905C965C885C985C995C91
+5C9A5C9C5CB55CA25CBD5CAC5CAB5CB15CA35CC15CB75CC45CD25CE45CCB5CE5
+5D025D035D275D265D2E5D245D1E5D065D1B5D585D3E5D345D3D5D6C5D5B5D6F
+5D5D5D6B5D4B5D4A5D695D745D825D995D9D8C735DB75DC55F735F775F825F87
+5F895F8C5F955F995F9C5FA85FAD5FB55FBC88625F6172AD72B072B472B772B8
+72C372C172CE72CD72D272E872EF72E972F272F472F7730172F3730372FA0000
+E2
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000072FB731773137321730A731E731D7315732273397325732C733873317350
+734D73577360736C736F737E821B592598E7592459029963996799689969996A
+996B996C99749977997D998099849987998A998D999099919993999499955E80
+5E915E8B5E965EA55EA05EB95EB55EBE5EB38D535ED25ED15EDB5EE85EEA81BA
+5FC45FC95FD65FCF60035FEE60045FE15FE45FFE600560065FEA5FED5FF86019
+60356026601B600F600D6029602B600A603F602160786079607B607A60420000
+E3
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000606A607D6096609A60AD609D60836092608C609B60EC60BB60B160DD60D8
+60C660DA60B4612061266115612360F46100610E612B614A617561AC619461A7
+61B761D461F55FDD96B395E995EB95F195F395F595F695FC95FE960396049606
+9608960A960B960C960D960F96129615961696179619961A4E2C723F62156C35
+6C546C5C6C4A6CA36C856C906C946C8C6C686C696C746C766C866CA96CD06CD4
+6CAD6CF76CF86CF16CD76CB26CE06CD66CFA6CEB6CEE6CB16CD36CEF6CFE0000
+E4
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00006D396D276D0C6D436D486D076D046D196D0E6D2B6D4D6D2E6D356D1A6D4F
+6D526D546D336D916D6F6D9E6DA06D5E6D936D946D5C6D606D7C6D636E1A6DC7
+6DC56DDE6E0E6DBF6DE06E116DE66DDD6DD96E166DAB6E0C6DAE6E2B6E6E6E4E
+6E6B6EB26E5F6E866E536E546E326E256E446EDF6EB16E986EE06F2D6EE26EA5
+6EA76EBD6EBB6EB76ED76EB46ECF6E8F6EC26E9F6F626F466F476F246F156EF9
+6F2F6F366F4B6F746F2A6F096F296F896F8D6F8C6F786F726F7C6F7A6FD10000
+E5
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00006FC96FA76FB96FB66FC26FE16FEE6FDE6FE06FEF701A7023701B70397035
+704F705E5B805B845B955B935BA55BB8752F9A9E64345BE45BEE89305BF08E47
+8B078FB68FD38FD58FE58FEE8FE48FE98FE68FF38FE890059004900B90269011
+900D9016902190359036902D902F9044905190529050906890589062905B66B9
+9074907D908290889083908B5F505F575F565F585C3B54AB5C505C595B715C63
+5C667FBC5F2A5F295F2D82745F3C9B3B5C6E59815983598D59A959AA59A30000
+E6
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000599759CA59AB599E59A459D259B259AF59D759BE5A055A0659DD5A0859E3
+59D859F95A0C5A095A325A345A115A235A135A405A675A4A5A555A3C5A625A75
+80EC5AAA5A9B5A775A7A5ABE5AEB5AB25AD25AD45AB85AE05AE35AF15AD65AE6
+5AD85ADC5B095B175B165B325B375B405C155C1C5B5A5B655B735B515B535B62
+9A759A779A789A7A9A7F9A7D9A809A819A859A889A8A9A909A929A939A969A98
+9A9B9A9C9A9D9A9F9AA09AA29AA39AA59AA77E9F7EA17EA37EA57EA87EA90000
+E7
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00007EAD7EB07EBE7EC07EC17EC27EC97ECB7ECC7ED07ED47ED77EDB7EE07EE1
+7EE87EEB7EEE7EEF7EF17EF27F0D7EF67EFA7EFB7EFE7F017F027F037F077F08
+7F0B7F0C7F0F7F117F127F177F197F1C7F1B7F1F7F217F227F237F247F257F26
+7F277F2A7F2B7F2C7F2D7F2F7F307F317F327F337F355E7A757F5DDB753E9095
+738E739173AE73A2739F73CF73C273D173B773B373C073C973C873E573D9987C
+740A73E973E773DE73BA73F2740F742A745B7426742574287430742E742C0000
+E8
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000741B741A7441745C7457745574597477746D747E749C748E748074817487
+748B749E74A874A9749074A774D274BA97EA97EB97EC674C6753675E67486769
+67A56787676A6773679867A7677567A8679E67AD678B6777677C67F0680967D8
+680A67E967B0680C67D967B567DA67B367DD680067C367B867E2680E67C167FD
+6832683368606861684E6862684468646883681D68556866684168676840683E
+684A6849682968B5688F687468776893686B68C2696E68FC691F692068F90000
+E9
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000692468F0690B6901695768E369106971693969606942695D6984696B6980
+69986978693469CC6987698869CE6989696669636979699B69A769BB69AB69AD
+69D469B169C169CA69DF699569E0698D69FF6A2F69ED6A176A186A6569F26A44
+6A3E6AA06A506A5B6A356A8E6A796A3D6A286A586A7C6A916A906AA96A976AAB
+733773526B816B826B876B846B926B936B8D6B9A6B9B6BA16BAA8F6B8F6D8F71
+8F728F738F758F768F788F778F798F7A8F7C8F7E8F818F828F848F878F8B0000
+EA
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00008F8D8F8E8F8F8F988F9A8ECE620B6217621B621F6222622162256224622C
+81E774EF74F474FF750F75117513653465EE65EF65F0660A6619677266036615
+6600708566F7661D66346631663666358006665F66546641664F665666616657
+66776684668C66A7669D66BE66DB66DC66E666E98D328D338D368D3B8D3D8D40
+8D458D468D488D498D478D4D8D558D5989C789CA89CB89CC89CE89CF89D089D1
+726E729F725D7266726F727E727F7284728B728D728F72926308633263B00000
+EB
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000643F64D880046BEA6BF36BFD6BF56BF96C056C076C066C0D6C156C186C19
+6C1A6C216C296C246C2A6C3265356555656B724D72527256723086625216809F
+809C809380BC670A80BD80B180AB80AD80B480B780E780E880E980EA80DB80C2
+80C480D980CD80D7671080DD80EB80F180F480ED810D810E80F280FC67158112
+8C5A8136811E812C811881328148814C815381748159815A817181608169817C
+817D816D8167584D5AB58188818281916ED581A381AA81CC672681CA81BB0000
+EC
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000081C181A66B246B376B396B436B466B5998D198D298D398D598D998DA6BB3
+5F406BC289F365909F51659365BC65C665C465C365CC65CE65D265D67080709C
+7096709D70BB70C070B770AB70B170E870CA711071137116712F71317173715C
+716871457172714A7178717A719871B371B571A871A071E071D471E771F9721D
+7228706C7118716671B9623E623D624362486249793B794079467949795B795C
+7953795A796279577960796F7967797A7985798A799A79A779B35FD15FD00000
+ED
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000603C605D605A606760416059606360AB6106610D615D61A9619D61CB61D1
+62068080807F6C936CF66DFC77F677F87800780978177818781165AB782D781C
+781D7839783A783B781F783C7825782C78237829784E786D7856785778267850
+7847784C786A789B7893789A7887789C78A178A378B278B978A578D478D978C9
+78EC78F2790578F479137924791E79349F9B9EF99EFB9EFC76F17704770D76F9
+77077708771A77227719772D7726773577387750775177477743775A77680000
+EE
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000077627765777F778D777D7780778C7791779F77A077B077B577BD753A7540
+754E754B7548755B7572757975837F587F617F5F8A487F687F747F717F797F81
+7F7E76CD76E58832948594869487948B948A948C948D948F9490949494979495
+949A949B949C94A394A494AB94AA94AD94AC94AF94B094B294B494B694B794B8
+94B994BA94BC94BD94BF94C494C894C994CA94CB94CC94CD94CE94D094D194D2
+94D594D694D794D994D894DB94DE94DF94E094E294E494E594E794E894EA0000
+EF
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000094E994EB94EE94EF94F394F494F594F794F994FC94FD94FF950395029506
+95079509950A950D950E950F951295139514951595169518951B951D951E951F
+9522952A952B9529952C953195329534953695379538953C953E953F95429535
+9544954595469549954C954E954F9552955395549556955795589559955B955E
+955F955D95619562956495659566956795689569956A956B956C956F95719572
+9573953A77E777EC96C979D579ED79E379EB7A065D477A037A027A1E7A140000
+F0
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00007A397A377A519ECF99A57A707688768E7693769976A474DE74E0752C9E20
+9E229E289E299E2A9E2B9E2C9E329E319E369E389E379E399E3A9E3E9E419E42
+9E449E469E479E489E499E4B9E4C9E4E9E519E559E579E5A9E5B9E5C9E5E9E63
+9E669E679E689E699E6A9E6B9E6C9E719E6D9E7375927594759675A0759D75AC
+75A375B375B475B875C475B175B075C375C275D675CD75E375E875E675E475EB
+75E7760375F175FC75FF761076007605760C7617760A76257618761576190000
+F1
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000761B763C762276207640762D7630763F76357643763E7633764D765E7654
+765C7656766B766F7FCA7AE67A787A797A807A867A887A957AA67AA07AAC7AA8
+7AAD7AB3886488698872887D887F888288A288C688B788BC88C988E288CE88E3
+88E588F1891A88FC88E888FE88F0892189198913891B890A8934892B89368941
+8966897B758B80E576B276B477DC801280148016801C80208022802580268027
+802980288031800B803580438046804D80528069807189839878988098830000
+F2
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00009889988C988D988F9894989A989B989E989F98A198A298A598A6864D8654
+866C866E867F867A867C867B86A8868D868B86AC869D86A786A386AA869386A9
+86B686C486B586CE86B086BA86B186AF86C986CF86B486E986F186F286ED86F3
+86D0871386DE86F486DF86D886D18703870786F88708870A870D87098723873B
+871E8725872E871A873E87488734873187298737873F87828722877D877E877B
+87608770874C876E878B87538763877C876487598765879387AF87A887D20000
+F3
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000087C68788878587AD8797878387AB87E587AC87B587B387CB87D387BD87D1
+87C087CA87DB87EA87E087EE8816881387FE880A881B88218839883C7F367F42
+7F447F4582107AFA7AFD7B087B037B047B157B0A7B2B7B0F7B477B387B2A7B19
+7B2E7B317B207B257B247B337B3E7B1E7B587B5A7B457B757B4C7B5D7B607B6E
+7B7B7B627B727B717B907BA67BA77BB87BAC7B9D7BA87B857BAA7B9C7BA27BAB
+7BB47BD17BC17BCC7BDD7BDA7BE57BE67BEA7C0C7BFE7BFC7C0F7C167C0B0000
+F4
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00007C1F7C2A7C267C387C417C4081FE82018202820481EC8844822182228223
+822D822F8228822B8238823B82338234823E82448249824B824F825A825F8268
+887E8885888888D888DF895E7F9D7F9F7FA77FAF7FB07FB27C7C65497C917C9D
+7C9C7C9E7CA27CB27CBC7CBD7CC17CC77CCC7CCD7CC87CC57CD77CE8826E66A8
+7FBF7FCE7FD57FE57FE17FE67FE97FEE7FF37CF87D777DA67DAE7E477E9B9EB8
+9EB48D738D848D948D918DB18D678D6D8C478C49914A9150914E914F91640000
+F5
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00009162916191709169916F917D917E917291749179918C91859190918D9191
+91A291A391AA91AD91AE91AF91B591B491BA8C559E7E8DB88DEB8E058E598E69
+8DB58DBF8DBC8DBA8DC48DD68DD78DDA8DDE8DCE8DCF8DDB8DC68DEC8DF78DF8
+8DE38DF98DFB8DE48E098DFD8E148E1D8E1F8E2C8E2E8E238E2F8E3A8E408E39
+8E358E3D8E318E498E418E428E518E528E4A8E708E768E7C8E6F8E748E858E8F
+8E948E908E9C8E9E8C788C828C8A8C858C988C94659B89D689DE89DA89DC0000
+F6
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000089E589EB89EF8A3E8B26975396E996F396EF970697019708970F970E972A
+972D9730973E9F809F839F859F869F879F889F899F8A9F8C9EFE9F0B9F0D96B9
+96BC96BD96CE96D277BF96E0928E92AE92C8933E936A93CA938F943E946B9C7F
+9C829C859C869C879C887A239C8B9C8E9C909C919C929C949C959C9A9C9B9C9E
+9C9F9CA09CA19CA29CA39CA59CA69CA79CA89CA99CAB9CAD9CAE9CB09CB19CB2
+9CB39CB49CB59CB69CB79CBA9CBB9CBC9CBD9CC49CC59CC69CC79CCA9CCB0000
+F7
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00009CCC9CCD9CCE9CCF9CD09CD39CD49CD59CD79CD89CD99CDC9CDD9CDF9CE2
+977C978597919792979497AF97AB97A397B297B49AB19AB09AB79E589AB69ABA
+9ABC9AC19AC09AC59AC29ACB9ACC9AD19B459B439B479B499B489B4D9B5198E8
+990D992E995599549ADF9AE19AE69AEF9AEB9AFB9AED9AF99B089B0F9B139B1F
+9B239EBD9EBE7E3B9E829E879E889E8B9E9293D69E9D9E9F9EDB9EDC9EDD9EE0
+9EDF9EE29EE99EE79EE59EEA9EEF9F229F2C9F2F9F399F379F3D9F3E9F440000
diff --git a/library/encoding/iso2022-jp.enc b/library/encoding/iso2022-jp.enc
new file mode 100644
index 0000000..f6dabe5
--- /dev/null
+++ b/library/encoding/iso2022-jp.enc
@@ -0,0 +1,12 @@
+# Encoding file: iso2022-jp, escape-driven
+E
+name		iso2022-jp
+init		{}
+final		{}
+ascii		\x1b(B
+jis0201		\x1b(J
+jis0208		\x1b$B
+jis0208		\x1b$@
+jis0212		\x1b$(D
+gb2312		\x1b$A
+ksc5601		\x1b$(C
diff --git a/library/encoding/iso2022-kr.enc b/library/encoding/iso2022-kr.enc
new file mode 100644
index 0000000..d20ce2b
--- /dev/null
+++ b/library/encoding/iso2022-kr.enc
@@ -0,0 +1,7 @@
+# Encoding file: iso2022-kr, escape-driven
+E
+name		iso2022-kr
+init		\x1b$)C
+final		{}
+iso8859-1	\x0f
+ksc5601		\x0e
diff --git a/library/encoding/iso2022.enc b/library/encoding/iso2022.enc
new file mode 100644
index 0000000..a58f8e3
--- /dev/null
+++ b/library/encoding/iso2022.enc
@@ -0,0 +1,14 @@
+# Encoding file: iso2022, escape-driven
+E
+name		iso2022
+init		{}
+final		{}
+iso8859-1	\x1b(B
+jis0201		\x1b(J
+gb1988		\x1b(T
+jis0208		\x1b$B
+jis0208		\x1b$@
+jis0212		\x1b$(D
+gb2312		\x1b$A
+ksc5601		\x1b$(C
+jis0208		\x1b&@\x1b$B
diff --git a/library/encoding/iso8859-1.enc b/library/encoding/iso8859-1.enc
new file mode 100644
index 0000000..045d8fa
--- /dev/null
+++ b/library/encoding/iso8859-1.enc
@@ -0,0 +1,20 @@
+# Encoding file: iso8859-1, single-byte
+S
+003F 0 1
+00
+0000000100020003000400050006000700080009000A000B000C000D000E000F
+0010001100120013001400150016001700180019001A001B001C001D001E001F
+0020002100220023002400250026002700280029002A002B002C002D002E002F
+0030003100320033003400350036003700380039003A003B003C003D003E003F
+0040004100420043004400450046004700480049004A004B004C004D004E004F
+0050005100520053005400550056005700580059005A005B005C005D005E005F
+0060006100620063006400650066006700680069006A006B006C006D006E006F
+0070007100720073007400750076007700780079007A007B007C007D007E007F
+0080008100820083008400850086008700880089008A008B008C008D008E008F
+0090009100920093009400950096009700980099009A009B009C009D009E009F
+00A000A100A200A300A400A500A600A700A800A900AA00AB00AC00AD00AE00AF
+00B000B100B200B300B400B500B600B700B800B900BA00BB00BC00BD00BE00BF
+00C000C100C200C300C400C500C600C700C800C900CA00CB00CC00CD00CE00CF
+00D000D100D200D300D400D500D600D700D800D900DA00DB00DC00DD00DE00DF
+00E000E100E200E300E400E500E600E700E800E900EA00EB00EC00ED00EE00EF
+00F000F100F200F300F400F500F600F700F800F900FA00FB00FC00FD00FE00FF
diff --git a/library/encoding/iso8859-10.enc b/library/encoding/iso8859-10.enc
new file mode 100644
index 0000000..934b3b9
--- /dev/null
+++ b/library/encoding/iso8859-10.enc
@@ -0,0 +1,20 @@
+# Encoding file: iso8859-10, single-byte
+S
+003F 0 1
+00
+0000000100020003000400050006000700080009000A000B000C000D000E000F
+0010001100120013001400150016001700180019001A001B001C001D001E001F
+0020002100220023002400250026002700280029002A002B002C002D002E002F
+0030003100320033003400350036003700380039003A003B003C003D003E003F
+0040004100420043004400450046004700480049004A004B004C004D004E004F
+0050005100520053005400550056005700580059005A005B005C005D005E005F
+0060006100620063006400650066006700680069006A006B006C006D006E006F
+0070007100720073007400750076007700780079007A007B007C007D007E007F
+0080008100820083008400850086008700880089008A008B008C008D008E008F
+0090009100920093009400950096009700980099009A009B009C009D009E009F
+00A0010401120122012A0128013600A7013B011001600166017D00AD016A014A
+00B0010501130123012B0129013700B7013C011101610167017E2015016B014B
+010000C100C200C300C400C500C6012E010C00C9011800CB011600CD00CE00CF
+00D00145014C00D300D400D500D6016800D8017200DA00DB00DC00DD00DE00DF
+010100E100E200E300E400E500E6012F010D00E9011900EB011700ED00EE00EF
+00F00146014D00F300F400F500F6016900F8017300FA00FB00FC00FD00FE0138
diff --git a/library/encoding/iso8859-13.enc b/library/encoding/iso8859-13.enc
new file mode 100644
index 0000000..b7edcaf
--- /dev/null
+++ b/library/encoding/iso8859-13.enc
@@ -0,0 +1,20 @@
+# Encoding file: iso8859-13, single-byte
+S
+003F 0 1
+00
+0000000100020003000400050006000700080009000A000B000C000D000E000F
+0010001100120013001400150016001700180019001A001B001C001D001E001F
+0020002100220023002400250026002700280029002A002B002C002D002E002F
+0030003100320033003400350036003700380039003A003B003C003D003E003F
+0040004100420043004400450046004700480049004A004B004C004D004E004F
+0050005100520053005400550056005700580059005A005B005C005D005E005F
+0060006100620063006400650066006700680069006A006B006C006D006E006F
+0070007100720073007400750076007700780079007A007B007C007D007E007F
+0080008100820083008400850086008700880089008A008B008C008D008E008F
+0090009100920093009400950096009700980099009A009B009C009D009E009F
+00A0201D00A200A300A4201E00A600A700D800A9015600AB00AC00AD00AE00C6
+00B000B100B200B3201C00B500B600B700F800B9015700BB00BC00BD00BE00E6
+0104012E0100010600C400C501180112010C00C90179011601220136012A013B
+01600143014500D3014C00D500D600D701720141015A016A00DC017B017D00DF
+0105012F0101010700E400E501190113010D00E9017A011701230137012B013C
+01610144014600F3014D00F500F600F701730142015B016B00FC017C017E2019
diff --git a/library/encoding/iso8859-14.enc b/library/encoding/iso8859-14.enc
new file mode 100644
index 0000000..a65ba05
--- /dev/null
+++ b/library/encoding/iso8859-14.enc
@@ -0,0 +1,20 @@
+# Encoding file: iso8859-14, single-byte
+S
+003F 0 1
+00
+0000000100020003000400050006000700080009000A000B000C000D000E000F
+0010001100120013001400150016001700180019001A001B001C001D001E001F
+0020002100220023002400250026002700280029002A002B002C002D002E002F
+0030003100320033003400350036003700380039003A003B003C003D003E003F
+0040004100420043004400450046004700480049004A004B004C004D004E004F
+0050005100520053005400550056005700580059005A005B005C005D005E005F
+0060006100620063006400650066006700680069006A006B006C006D006E006F
+0070007100720073007400750076007700780079007A007B007C007D007E007F
+0080008100820083008400850086008700880089008A008B008C008D008E008F
+0090009100920093009400950096009700980099009A009B009C009D009E009F
+00A01E021E0300A3010A010B1E0A00A71E8000A91E821E0B1EF200AD00AE0178
+1E1E1E1F012001211E401E4100B61E561E811E571E831E601EF31E841E851E61
+00C000C100C200C300C400C500C600C700C800C900CA00CB00CC00CD00CE00CF
+017400D100D200D300D400D500D61E6A00D800D900DA00DB00DC00DD017600DF
+00E000E100E200E300E400E500E600E700E800E900EA00EB00EC00ED00EE00EF
+017500F100F200F300F400F500F61E6B00F800F900FA00FB00FC00FD017700FF
diff --git a/library/encoding/iso8859-15.enc b/library/encoding/iso8859-15.enc
new file mode 100644
index 0000000..823af46
--- /dev/null
+++ b/library/encoding/iso8859-15.enc
@@ -0,0 +1,20 @@
+# Encoding file: iso8859-15, single-byte
+S
+003F 0 1
+00
+0000000100020003000400050006000700080009000A000B000C000D000E000F
+0010001100120013001400150016001700180019001A001B001C001D001E001F
+0020002100220023002400250026002700280029002A002B002C002D002E002F
+0030003100320033003400350036003700380039003A003B003C003D003E003F
+0040004100420043004400450046004700480049004A004B004C004D004E004F
+0050005100520053005400550056005700580059005A005B005C005D005E005F
+0060006100620063006400650066006700680069006A006B006C006D006E006F
+0070007100720073007400750076007700780079007A007B007C007D007E007F
+0080008100820083008400850086008700880089008A008B008C008D008E008F
+0090009100920093009400950096009700980099009A009B009C009D009E009F
+00A000A100A200A320AC00A5016000A7016100A900AA00AB00AC00AD00AE00AF
+00B000B100B200B3017D00B500B600B7017E00B900BA00BB01520153017800BF
+00C000C100C200C300C400C500C600C700C800C900CA00CB00CC00CD00CE00CF
+00D000D100D200D300D400D500D600D700D800D900DA00DB00DC00DD00DE00DF
+00E000E100E200E300E400E500E600E700E800E900EA00EB00EC00ED00EE00EF
+00F000F100F200F300F400F500F600F700F800F900FA00FB00FC00FD00FE00FF
diff --git a/library/encoding/iso8859-16.enc b/library/encoding/iso8859-16.enc
new file mode 100644
index 0000000..da33709
--- /dev/null
+++ b/library/encoding/iso8859-16.enc
@@ -0,0 +1,20 @@
+# Encoding file: iso8859-16, single-byte
+S
+003F 0 1
+00
+0000000100020003000400050006000700080009000A000B000C000D000E000F
+0010001100120013001400150016001700180019001A001B001C001D001E001F
+0020002100220023002400250026002700280029002A002B002C002D002E002F
+0030003100320033003400350036003700380039003A003B003C003D003E003F
+0040004100420043004400450046004700480049004A004B004C004D004E004F
+0050005100520053005400550056005700580059005A005B005C005D005E005F
+0060006100620063006400650066006700680069006A006B006C006D006E006F
+0070007100720073007400750076007700780079007A007B007C007D007E007F
+0080008100820083008400850086008700880089008A008B008C008D008E008F
+0090009100920093009400950096009700980099009A009B009C009D009E009F
+00A001040105014120AC201E016000A7016100A9021800AB017900AD017A017B
+00B000B1010C0142017D201D00B600B7017E010D021900BB015201530178017C
+00C000C100C2010200C4010600C600C700C800C900CA00CB00CC00CD00CE00CF
+0110014300D200D300D4015000D6015A017000D900DA00DB00DC0118021A00DF
+00E000E100E2010300E4010700E600E700E800E900EA00EB00EC00ED00EE00EF
+0111014400F200F300F4015100F6015B017100F900FA00FB00FC0119021B00FF
diff --git a/library/encoding/iso8859-2.enc b/library/encoding/iso8859-2.enc
new file mode 100644
index 0000000..16faab6
--- /dev/null
+++ b/library/encoding/iso8859-2.enc
@@ -0,0 +1,20 @@
+# Encoding file: iso8859-2, single-byte
+S
+003F 0 1
+00
+0000000100020003000400050006000700080009000A000B000C000D000E000F
+0010001100120013001400150016001700180019001A001B001C001D001E001F
+0020002100220023002400250026002700280029002A002B002C002D002E002F
+0030003100320033003400350036003700380039003A003B003C003D003E003F
+0040004100420043004400450046004700480049004A004B004C004D004E004F
+0050005100520053005400550056005700580059005A005B005C005D005E005F
+0060006100620063006400650066006700680069006A006B006C006D006E006F
+0070007100720073007400750076007700780079007A007B007C007D007E007F
+0080008100820083008400850086008700880089008A008B008C008D008E008F
+0090009100920093009400950096009700980099009A009B009C009D009E009F
+00A0010402D8014100A4013D015A00A700A80160015E0164017900AD017D017B
+00B0010502DB014200B4013E015B02C700B80161015F0165017A02DD017E017C
+015400C100C2010200C40139010600C7010C00C9011800CB011A00CD00CE010E
+01100143014700D300D4015000D600D70158016E00DA017000DC00DD016200DF
+015500E100E2010300E4013A010700E7010D00E9011900EB011B00ED00EE010F
+01110144014800F300F4015100F600F70159016F00FA017100FC00FD016302D9
diff --git a/library/encoding/iso8859-3.enc b/library/encoding/iso8859-3.enc
new file mode 100644
index 0000000..c914bce
--- /dev/null
+++ b/library/encoding/iso8859-3.enc
@@ -0,0 +1,20 @@
+# Encoding file: iso8859-3, single-byte
+S
+003F 0 1
+00
+0000000100020003000400050006000700080009000A000B000C000D000E000F
+0010001100120013001400150016001700180019001A001B001C001D001E001F
+0020002100220023002400250026002700280029002A002B002C002D002E002F
+0030003100320033003400350036003700380039003A003B003C003D003E003F
+0040004100420043004400450046004700480049004A004B004C004D004E004F
+0050005100520053005400550056005700580059005A005B005C005D005E005F
+0060006100620063006400650066006700680069006A006B006C006D006E006F
+0070007100720073007400750076007700780079007A007B007C007D007E007F
+0080008100820083008400850086008700880089008A008B008C008D008E008F
+0090009100920093009400950096009700980099009A009B009C009D009E009F
+00A0012602D800A300A40000012400A700A80130015E011E013400AD0000017B
+00B0012700B200B300B400B5012500B700B80131015F011F013500BD0000017C
+00C000C100C2000000C4010A010800C700C800C900CA00CB00CC00CD00CE00CF
+000000D100D200D300D4012000D600D7011C00D900DA00DB00DC016C015C00DF
+00E000E100E2000000E4010B010900E700E800E900EA00EB00EC00ED00EE00EF
+000000F100F200F300F4012100F600F7011D00F900FA00FB00FC016D015D02D9
diff --git a/library/encoding/iso8859-4.enc b/library/encoding/iso8859-4.enc
new file mode 100644
index 0000000..ef5c5a9
--- /dev/null
+++ b/library/encoding/iso8859-4.enc
@@ -0,0 +1,20 @@
+# Encoding file: iso8859-4, single-byte
+S
+003F 0 1
+00
+0000000100020003000400050006000700080009000A000B000C000D000E000F
+0010001100120013001400150016001700180019001A001B001C001D001E001F
+0020002100220023002400250026002700280029002A002B002C002D002E002F
+0030003100320033003400350036003700380039003A003B003C003D003E003F
+0040004100420043004400450046004700480049004A004B004C004D004E004F
+0050005100520053005400550056005700580059005A005B005C005D005E005F
+0060006100620063006400650066006700680069006A006B006C006D006E006F
+0070007100720073007400750076007700780079007A007B007C007D007E007F
+0080008100820083008400850086008700880089008A008B008C008D008E008F
+0090009100920093009400950096009700980099009A009B009C009D009E009F
+00A001040138015600A40128013B00A700A8016001120122016600AD017D00AF
+00B0010502DB015700B40129013C02C700B80161011301230167014A017E014B
+010000C100C200C300C400C500C6012E010C00C9011800CB011600CD00CE012A
+01100145014C013600D400D500D600D700D8017200DA00DB00DC0168016A00DF
+010100E100E200E300E400E500E6012F010D00E9011900EB011700ED00EE012B
+01110146014D013700F400F500F600F700F8017300FA00FB00FC0169016B02D9
diff --git a/library/encoding/iso8859-5.enc b/library/encoding/iso8859-5.enc
new file mode 100644
index 0000000..bf4ee82
--- /dev/null
+++ b/library/encoding/iso8859-5.enc
@@ -0,0 +1,20 @@
+# Encoding file: iso8859-5, single-byte
+S
+003F 0 1
+00
+0000000100020003000400050006000700080009000A000B000C000D000E000F
+0010001100120013001400150016001700180019001A001B001C001D001E001F
+0020002100220023002400250026002700280029002A002B002C002D002E002F
+0030003100320033003400350036003700380039003A003B003C003D003E003F
+0040004100420043004400450046004700480049004A004B004C004D004E004F
+0050005100520053005400550056005700580059005A005B005C005D005E005F
+0060006100620063006400650066006700680069006A006B006C006D006E006F
+0070007100720073007400750076007700780079007A007B007C007D007E007F
+0080008100820083008400850086008700880089008A008B008C008D008E008F
+0090009100920093009400950096009700980099009A009B009C009D009E009F
+00A0040104020403040404050406040704080409040A040B040C00AD040E040F
+0410041104120413041404150416041704180419041A041B041C041D041E041F
+0420042104220423042404250426042704280429042A042B042C042D042E042F
+0430043104320433043404350436043704380439043A043B043C043D043E043F
+0440044104420443044404450446044704480449044A044B044C044D044E044F
+2116045104520453045404550456045704580459045A045B045C00A7045E045F
diff --git a/library/encoding/iso8859-6.enc b/library/encoding/iso8859-6.enc
new file mode 100644
index 0000000..19ddefb
--- /dev/null
+++ b/library/encoding/iso8859-6.enc
@@ -0,0 +1,20 @@
+# Encoding file: iso8859-6, single-byte
+S
+003F 0 1
+00
+0000000100020003000400050006000700080009000A000B000C000D000E000F
+0010001100120013001400150016001700180019001A001B001C001D001E001F
+0020002100220023002400250026002700280029002A002B002C002D002E002F
+0030003100320033003400350036003700380039003A003B003C003D003E003F
+0040004100420043004400450046004700480049004A004B004C004D004E004F
+0050005100520053005400550056005700580059005A005B005C005D005E005F
+0060006100620063006400650066006700680069006A006B006C006D006E006F
+0070007100720073007400750076007700780079007A007B007C007D007E007F
+0080008100820083008400850086008700880089008A008B008C008D008E008F
+0090009100920093009400950096009700980099009A009B009C009D009E009F
+00A000000000000000A40000000000000000000000000000060C00AD00000000
+00000000000000000000000000000000000000000000061B000000000000061F
+0000062106220623062406250626062706280629062A062B062C062D062E062F
+0630063106320633063406350636063706380639063A00000000000000000000
+0640064106420643064406450646064706480649064A064B064C064D064E064F
+0650065106520000000000000000000000000000000000000000000000000000
diff --git a/library/encoding/iso8859-7.enc b/library/encoding/iso8859-7.enc
new file mode 100644
index 0000000..0f93ac8
--- /dev/null
+++ b/library/encoding/iso8859-7.enc
@@ -0,0 +1,20 @@
+# Encoding file: iso8859-7, single-byte
+S
+003F 0 1
+00
+0000000100020003000400050006000700080009000A000B000C000D000E000F
+0010001100120013001400150016001700180019001A001B001C001D001E001F
+0020002100220023002400250026002700280029002A002B002C002D002E002F
+0030003100320033003400350036003700380039003A003B003C003D003E003F
+0040004100420043004400450046004700480049004A004B004C004D004E004F
+0050005100520053005400550056005700580059005A005B005C005D005E005F
+0060006100620063006400650066006700680069006A006B006C006D006E006F
+0070007100720073007400750076007700780079007A007B007C007D007E007F
+0080008100820083008400850086008700880089008A008B008C008D008E008F
+0090009100920093009400950096009700980099009A009B009C009D009E009F
+00A02018201900A30000000000A600A700A800A9000000AB00AC00AD00002015
+00B000B100B200B303840385038600B703880389038A00BB038C00BD038E038F
+0390039103920393039403950396039703980399039A039B039C039D039E039F
+03A003A1000003A303A403A503A603A703A803A903AA03AB03AC03AD03AE03AF
+03B003B103B203B303B403B503B603B703B803B903BA03BB03BC03BD03BE03BF
+03C003C103C203C303C403C503C603C703C803C903CA03CB03CC03CD03CE0000
diff --git a/library/encoding/iso8859-8.enc b/library/encoding/iso8859-8.enc
new file mode 100644
index 0000000..579fa5b
--- /dev/null
+++ b/library/encoding/iso8859-8.enc
@@ -0,0 +1,20 @@
+# Encoding file: iso8859-8, single-byte
+S
+003F 0 1
+00
+0000000100020003000400050006000700080009000A000B000C000D000E000F
+0010001100120013001400150016001700180019001A001B001C001D001E001F
+0020002100220023002400250026002700280029002A002B002C002D002E002F
+0030003100320033003400350036003700380039003A003B003C003D003E003F
+0040004100420043004400450046004700480049004A004B004C004D004E004F
+0050005100520053005400550056005700580059005A005B005C005D005E005F
+0060006100620063006400650066006700680069006A006B006C006D006E006F
+0070007100720073007400750076007700780079007A007B007C007D007E007F
+0080008100820083008400850086008700880089008A008B008C008D008E008F
+0090009100920093009400950096009700980099009A009B009C009D009E009F
+00A0000000A200A300A400A500A600A700A800A900D700AB00AC00AD00AE00AF
+00B000B100B200B300B400B500B600B700B800B900F700BB00BC00BD00BE0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000002017
+05D005D105D205D305D405D505D605D705D805D905DA05DB05DC05DD05DE05DF
+05E005E105E205E305E405E505E605E705E805E905EA00000000200E200F0000
diff --git a/library/encoding/iso8859-9.enc b/library/encoding/iso8859-9.enc
new file mode 100644
index 0000000..6eed3f1
--- /dev/null
+++ b/library/encoding/iso8859-9.enc
@@ -0,0 +1,20 @@
+# Encoding file: iso8859-9, single-byte
+S
+003F 0 1
+00
+0000000100020003000400050006000700080009000A000B000C000D000E000F
+0010001100120013001400150016001700180019001A001B001C001D001E001F
+0020002100220023002400250026002700280029002A002B002C002D002E002F
+0030003100320033003400350036003700380039003A003B003C003D003E003F
+0040004100420043004400450046004700480049004A004B004C004D004E004F
+0050005100520053005400550056005700580059005A005B005C005D005E005F
+0060006100620063006400650066006700680069006A006B006C006D006E006F
+0070007100720073007400750076007700780079007A007B007C007D007E007F
+0080008100820083008400850086008700880089008A008B008C008D008E008F
+0090009100920093009400950096009700980099009A009B009C009D009E009F
+00A000A100A200A300A400A500A600A700A800A900AA00AB00AC00AD00AE00AF
+00B000B100B200B300B400B500B600B700B800B900BA00BB00BC00BD00BE00BF
+00C000C100C200C300C400C500C600C700C800C900CA00CB00CC00CD00CE00CF
+011E00D100D200D300D400D500D600D700D800D900DA00DB00DC0130015E00DF
+00E000E100E200E300E400E500E600E700E800E900EA00EB00EC00ED00EE00EF
+011F00F100F200F300F400F500F600F700F800F900FA00FB00FC0131015F00FF
diff --git a/library/encoding/jis0201.enc b/library/encoding/jis0201.enc
new file mode 100644
index 0000000..64f423f
--- /dev/null
+++ b/library/encoding/jis0201.enc
@@ -0,0 +1,20 @@
+# Encoding file: jis0201, single-byte
+S
+003F 0 1
+00
+0000000100020003000400050006000700080009000A000B000C000D000E000F
+0010001100120013001400150016001700180019001A001B001C001D001E001F
+0020002100220023002400250026002700280029002A002B002C002D002E002F
+0030003100320033003400350036003700380039003A003B003C003D003E003F
+0040004100420043004400450046004700480049004A004B004C004D004E004F
+0050005100520053005400550056005700580059005A005B005C005D005E005F
+0060006100620063006400650066006700680069006A006B006C006D006E006F
+0070007100720073007400750076007700780079007A007B007C007D203E007F
+0080008100820083008400850086008700880089008A008B008C008D008E008F
+0090009100920093009400950096009700980099009A009B009C009D009E009F
+0000FF61FF62FF63FF64FF65FF66FF67FF68FF69FF6AFF6BFF6CFF6DFF6EFF6F
+FF70FF71FF72FF73FF74FF75FF76FF77FF78FF79FF7AFF7BFF7CFF7DFF7EFF7F
+FF80FF81FF82FF83FF84FF85FF86FF87FF88FF89FF8AFF8BFF8CFF8DFF8EFF8F
+FF90FF91FF92FF93FF94FF95FF96FF97FF98FF99FF9AFF9BFF9CFF9DFF9EFF9F
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
diff --git a/library/encoding/jis0208.enc b/library/encoding/jis0208.enc
new file mode 100644
index 0000000..11c49a4
--- /dev/null
+++ b/library/encoding/jis0208.enc
@@ -0,0 +1,1319 @@
+# Encoding file: jis0208, double-byte
+D
+2129 0 77
+21
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000300030013002FF0CFF0E30FBFF1AFF1BFF1FFF01309B309C00B4FF4000A8
+FF3EFFE3FF3F30FD30FE309D309E30034EDD30053006300730FC20152010FF0F
+FF3C301C2016FF5C2026202520182019201C201DFF08FF0930143015FF3BFF3D
+FF5BFF5D30083009300A300B300C300D300E300F30103011FF0B221200B100D7
+00F7FF1D2260FF1CFF1E22662267221E22342642264000B0203220332103FFE5
+FF0400A200A3FF05FF03FF06FF0AFF2000A72606260525CB25CF25CE25C70000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+22
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000025C625A125A025B325B225BD25BC203B3012219221902191219330130000
+00000000000000000000000000000000000000002208220B2286228722822283
+222A2229000000000000000000000000000000002227222800AC21D221D42200
+220300000000000000000000000000000000000000000000222022A523122202
+220722612252226A226B221A223D221D2235222B222C00000000000000000000
+00000000212B2030266F266D266A2020202100B6000000000000000025EF0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+23
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+FF10FF11FF12FF13FF14FF15FF16FF17FF18FF19000000000000000000000000
+0000FF21FF22FF23FF24FF25FF26FF27FF28FF29FF2AFF2BFF2CFF2DFF2EFF2F
+FF30FF31FF32FF33FF34FF35FF36FF37FF38FF39FF3A00000000000000000000
+0000FF41FF42FF43FF44FF45FF46FF47FF48FF49FF4AFF4BFF4CFF4DFF4EFF4F
+FF50FF51FF52FF53FF54FF55FF56FF57FF58FF59FF5A00000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+24
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000304130423043304430453046304730483049304A304B304C304D304E304F
+3050305130523053305430553056305730583059305A305B305C305D305E305F
+3060306130623063306430653066306730683069306A306B306C306D306E306F
+3070307130723073307430753076307730783079307A307B307C307D307E307F
+3080308130823083308430853086308730883089308A308B308C308D308E308F
+3090309130923093000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+25
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000030A130A230A330A430A530A630A730A830A930AA30AB30AC30AD30AE30AF
+30B030B130B230B330B430B530B630B730B830B930BA30BB30BC30BD30BE30BF
+30C030C130C230C330C430C530C630C730C830C930CA30CB30CC30CD30CE30CF
+30D030D130D230D330D430D530D630D730D830D930DA30DB30DC30DD30DE30DF
+30E030E130E230E330E430E530E630E730E830E930EA30EB30EC30ED30EE30EF
+30F030F130F230F330F430F530F6000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+26
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000039103920393039403950396039703980399039A039B039C039D039E039F
+03A003A103A303A403A503A603A703A803A90000000000000000000000000000
+000003B103B203B303B403B503B603B703B803B903BA03BB03BC03BD03BE03BF
+03C003C103C303C403C503C603C703C803C90000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+27
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000004100411041204130414041504010416041704180419041A041B041C041D
+041E041F0420042104220423042404250426042704280429042A042B042C042D
+042E042F00000000000000000000000000000000000000000000000000000000
+000004300431043204330434043504510436043704380439043A043B043C043D
+043E043F0440044104420443044404450446044704480449044A044B044C044D
+044E044F00000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+28
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000025002502250C251025182514251C252C25242534253C25012503250F2513
+251B251725232533252B253B254B2520252F25282537253F251D253025252538
+2542000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+30
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00004E9C55165A03963F54C0611B632859F690228475831C7A5060AA63E16E25
+65ED846682A69BF56893572765A162715B9B59D0867B98F47D627DBE9B8E6216
+7C9F88B75B895EB563096697684895C7978D674F4EE54F0A4F4D4F9D504956F2
+593759D45A015C0960DF610F61706613690570BA754F757079FB7DAD7DEF80C3
+840E88638B029055907A533B4E954EA557DF80B290C178EF4E0058F16EA29038
+7A328328828B9C2F5141537054BD54E156E059FB5F1598F26DEB80E4852D0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+31
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00009662967096A097FB540B53F35B8770CF7FBD8FC296E8536F9D5C7ABA4E11
+789381FC6E26561855046B1D851A9C3B59E553A96D6674DC958F56424E91904B
+96F2834F990C53E155B65B305F71662066F368046C386CF36D29745B76C87A4E
+983482F1885B8A6092ED6DB275AB76CA99C560A68B018D8A95B2698E53AD5186
+5712583059445BB45EF6602863A963F46CBF6F14708E7114715971D5733F7E01
+827682D185979060925B9D1B586965BC6C5A752551F9592E59655F805FDC0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+32
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000062BC65FA6A2A6B276BB4738B7FC189569D2C9D0E9EC45CA16C96837B5104
+5C4B61B681C6687672614E594FFA537860696E297A4F97F34E0B53164EEE4F55
+4F3D4FA14F7352A053EF5609590F5AC15BB65BE179D16687679C67B66B4C6CB3
+706B73C2798D79BE7A3C7B8782B182DB8304837783EF83D387668AB256298CA8
+8FE6904E971E868A4FC45CE862117259753B81E582BD86FE8CC096C5991399D5
+4ECB4F1A89E356DE584A58CA5EFB5FEB602A6094606261D0621262D065390000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+33
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00009B41666668B06D777070754C76867D7582A587F9958B968E8C9D51F152BE
+591654B35BB35D16616869826DAF788D84CB88578A7293A79AB86D6C99A886D9
+57A367FF86CE920E5283568754045ED362E164B9683C68386BBB737278BA7A6B
+899A89D28D6B8F0390ED95A3969497695B665CB3697D984D984E639B7B206A2B
+6A7F68B69C0D6F5F5272559D607062EC6D3B6E076ED1845B89108F444E149C39
+53F6691B6A3A9784682A515C7AC384B291DC938C565B9D286822830584310000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+34
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00007CA5520882C574E64E7E4F8351A05BD2520A52D852E75DFB559A582A59E6
+5B8C5B985BDB5E725E7960A3611F616361BE63DB656267D1685368FA6B3E6B53
+6C576F226F976F4574B0751876E3770B7AFF7BA17C217DE97F367FF0809D8266
+839E89B38ACC8CAB908494519593959195A2966597D3992882184E38542B5CB8
+5DCC73A9764C773C5CA97FEB8D0B96C19811985498584F014F0E5371559C5668
+57FA59475B095BC45C905E0C5E7E5FCC63EE673A65D765E2671F68CB68C40000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+35
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00006A5F5E306BC56C176C7D757F79485B637A007D005FBD898F8A188CB48D77
+8ECC8F1D98E29A0E9B3C4E80507D510059935B9C622F628064EC6B3A72A07591
+79477FA987FB8ABC8B7063AC83CA97A05409540355AB68546A588A7078276775
+9ECD53745BA2811A865090064E184E454EC74F1153CA54385BAE5F1360256551
+673D6C426C726CE3707874037A767AAE7B087D1A7CFE7D6665E7725B53BB5C45
+5DE862D262E063196E20865A8A318DDD92F86F0179A69B5A4EA84EAB4EAC0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+36
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00004F9B4FA050D151477AF6517151F653545321537F53EB55AC58835CE15F37
+5F4A602F6050606D631F65596A4B6CC172C272ED77EF80F881058208854E90F7
+93E197FF99579A5A4EF051DD5C2D6681696D5C4066F26975738968507C8150C5
+52E457475DFE932665A46B236B3D7434798179BD7B4B7DCA82B983CC887F895F
+8B398FD191D1541F92804E5D503653E5533A72D7739677E982E68EAF99C699C8
+99D25177611A865E55B07A7A50765BD3904796854E326ADB91E75C515C480000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+37
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000063987A9F6C9397748F617AAA718A96887C8268177E706851936C52F2541B
+85AB8A137FA48ECD90E15366888879414FC250BE521151445553572D73EA578B
+59515F625F8460756176616761A963B2643A656C666F68426E1375667A3D7CFB
+7D4C7D997E4B7F6B830E834A86CD8A088A638B668EFD981A9D8F82B88FCE9BE8
+5287621F64836FC09699684150916B206C7A6F547A747D5088408A2367084EF6
+503950265065517C5238526355A7570F58055ACC5EFA61B261F862F363720000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+38
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000691C6A29727D72AC732E7814786F7D79770C80A9898B8B198CE28ED29063
+9375967A98559A139E785143539F53B35E7B5F266E1B6E90738473FE7D438237
+8A008AFA96504E4E500B53E4547C56FA59D15B645DF15EAB5F276238654567AF
+6E5672D07CCA88B480A180E183F0864E8A878DE8923796C798679F134E944E92
+4F0D53485449543E5A2F5F8C5FA1609F68A76A8E745A78818A9E8AA48B779190
+4E5E9BC94EA44F7C4FAF501950165149516C529F52B952FE539A53E354110000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+39
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000540E5589575157A2597D5B545B5D5B8F5DE55DE75DF75E785E835E9A5EB7
+5F186052614C629762D863A7653B6602664366F4676D6821689769CB6C5F6D2A
+6D696E2F6E9D75327687786C7A3F7CE07D057D187D5E7DB18015800380AF80B1
+8154818F822A8352884C88618B1B8CA28CFC90CA91759271783F92FC95A4964D
+980599999AD89D3B525B52AB53F7540858D562F76FE08C6A8F5F9EB9514B523B
+544A56FD7A4091779D609ED273446F09817075115FFD60DA9AA872DB8FBC0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+3A
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00006B6498034ECA56F0576458BE5A5A606861C7660F6606683968B16DF775D5
+7D3A826E9B424E9B4F5053C955065D6F5DE65DEE67FB6C99747378028A509396
+88DF57505EA7632B50B550AC518D670054C9585E59BB5BB05F69624D63A1683D
+6B736E08707D91C7728078157826796D658E7D3083DC88C18F09969B52645728
+67507F6A8CA151B45742962A583A698A80B454B25D0E57FC78959DFA4F5C524A
+548B643E6628671467F57A847B567D22932F685C9BAD7B395319518A52370000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+3B
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00005BDF62F664AE64E6672D6BBA85A996D176909BD6634C93069BAB76BF6652
+4E09509853C25C7160E864926563685F71E673CA75237B977E8286958B838CDB
+9178991065AC66AB6B8B4ED54ED44F3A4F7F523A53F853F255E356DB58EB59CB
+59C959FF5B505C4D5E025E2B5FD7601D6307652F5B5C65AF65BD65E8679D6B62
+6B7B6C0F7345794979C17CF87D197D2B80A2810281F389968A5E8A698A668A8C
+8AEE8CC78CDC96CC98FC6B6F4E8B4F3C4F8D51505B575BFA6148630166420000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+3C
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00006B216ECB6CBB723E74BD75D478C1793A800C803381EA84948F9E6C509E7F
+5F0F8B589D2B7AFA8EF85B8D96EB4E0353F157F759315AC95BA460896E7F6F06
+75BE8CEA5B9F85007BE0507267F4829D5C61854A7E1E820E51995C0463688D66
+659C716E793E7D1780058B1D8ECA906E86C790AA501F52FA5C3A6753707C7235
+914C91C8932B82E55BC25F3160F94E3B53D65B88624B67316B8A72E973E07A2E
+816B8DA391529996511253D7546A5BFF63886A397DAC970056DA53CE54680000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+3D
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00005B975C315DDE4FEE610162FE6D3279C079CB7D427E4D7FD281ED821F8490
+884689728B908E748F2F9031914B916C96C6919C4EC04F4F514553415F93620E
+67D46C416E0B73637E2691CD928353D459195BBF6DD1795D7E2E7C9B587E719F
+51FA88538FF04FCA5CFB662577AC7AE3821C99FF51C65FAA65EC696F6B896DF3
+6E966F6476FE7D145DE190759187980651E6521D6240669166D96E1A5EB67DD2
+7F7266F885AF85F78AF852A953D959735E8F5F90605592E4966450B7511F0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+3E
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000052DD5320534753EC54E8554655315617596859BE5A3C5BB55C065C0F5C11
+5C1A5E845E8A5EE05F70627F628462DB638C63776607660C662D6676677E68A2
+6A1F6A356CBC6D886E096E58713C7126716775C77701785D7901796579F07AE0
+7B117CA77D39809683D6848B8549885D88F38A1F8A3C8A548A738C618CDE91A4
+9266937E9418969C97984E0A4E084E1E4E575197527057CE583458CC5B225E38
+60C564FE676167566D4472B675737A6384B88B7291B89320563157F498FE0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+3F
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000062ED690D6B9671ED7E548077827289E698DF87558FB15C3B4F384FE14FB5
+55075A205BDD5BE95FC3614E632F65B0664B68EE699B6D786DF1753375B9771F
+795E79E67D3381E382AF85AA89AA8A3A8EAB8F9B903291DD97074EBA4EC15203
+587558EC5C0B751A5C3D814E8A0A8FC59663976D7B258ACF9808916256F353A8
+9017543957825E2563A86C34708A77617C8B7FE088709042915493109318968F
+745E9AC45D075D69657067A28DA896DB636E6749691983C5981796C088FE0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+40
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00006F84647A5BF84E16702C755D662F51C4523652E259D35F8160276210653F
+6574661F667468F268166B636E057272751F76DB7CBE805658F088FD897F8AA0
+8A938ACB901D91929752975965897A0E810696BB5E2D60DC621A65A566146790
+77F37A4D7C4D7E3E810A8CAC8D648DE18E5F78A9520762D963A5644262988A2D
+7A837BC08AAC96EA7D76820C87494ED95148534353605BA35C025C165DDD6226
+624764B0681368346CC96D456D1767D36F5C714E717D65CB7A7F7BAD7DDA0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+41
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00007E4A7FA8817A821B823985A68A6E8CCE8DF59078907792AD929195839BAE
+524D55846F387136516879857E5581B37CCE564C58515CA863AA66FE66FD695A
+72D9758F758E790E795679DF7C977D207D4486078A34963B90619F2050E75275
+53CC53E2500955AA58EE594F723D5B8B5C64531D60E360F3635C6383633F63BB
+64CD65E966F95DE369CD69FD6F1571E54E8975E976F87A937CDF7DCF7D9C8061
+83498358846C84BC85FB88C58D709001906D9397971C9A1250CF5897618E0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+42
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000081D385358D0890204FC3507452475373606F6349675F6E2C8DB3901F4FD7
+5C5E8CCA65CF7D9A53528896517663C35B585B6B5C0A640D6751905C4ED6591A
+592A6C708A51553E581559A560F0625367C182356955964099C49A284F535806
+5BFE80105CB15E2F5F856020614B623466FF6CF06EDE80CE817F82D4888B8CB8
+9000902E968A9EDB9BDB4EE353F059277B2C918D984C9DF96EDD702753535544
+5B856258629E62D36CA26FEF74228A1794386FC18AFE833851E786F853EA0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+43
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000053E94F4690548FB0596A81315DFD7AEA8FBF68DA8C3772F89C486A3D8AB0
+4E3953585606576662C563A265E66B4E6DE16E5B70AD77ED7AEF7BAA7DBB803D
+80C686CB8A95935B56E358C75F3E65AD66966A806BB575378AC7502477E55730
+5F1B6065667A6C6075F47A1A7F6E81F48718904599B37BC9755C7AF97B5184C4
+901079E97A9283365AE177404E2D4EF25B995FE062BD663C67F16CE8866B8877
+8A3B914E92F399D06A177026732A82E784578CAF4E01514651CB558B5BF50000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+44
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00005E165E335E815F145F355F6B5FB461F2631166A2671D6F6E7252753A773A
+80748139817887768ABF8ADC8D858DF3929A957798029CE552C5635776F46715
+6C8873CD8CC393AE96736D25589C690E69CC8FFD939A75DB901A585A680263B4
+69FB4F436F2C67D88FBB85267DB49354693F6F70576A58F75B2C7D2C722A540A
+91E39DB44EAD4F4E505C507552438C9E544858245B9A5E1D5E955EAD5EF75F1F
+608C62B5633A63D068AF6C407887798E7A0B7DE082478A028AE68E4490130000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+45
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000090B8912D91D89F0E6CE5645864E265756EF476847B1B906993D16EBA54F2
+5FB964A48F4D8FED92445178586B59295C555E976DFB7E8F751C8CBC8EE2985B
+70B94F1D6BBF6FB1753096FB514E54105835585759AC5C605F926597675C6E21
+767B83DF8CED901490FD934D7825783A52AA5EA6571F597460125012515A51AC
+51CD520055105854585859575B955CF65D8B60BC6295642D6771684368BC68DF
+76D76DD86E6F6D9B706F71C85F5375D879777B497B547B527CD67D7152300000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+46
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00008463856985E48A0E8B048C468E0F9003900F94199676982D9A3095D850CD
+52D5540C58025C0E61A7649E6D1E77B37AE580F48404905392855CE09D07533F
+5F975FB36D9C7279776379BF7BE46BD272EC8AAD68036A6151F87A8169345C4A
+9CF682EB5BC59149701E56785C6F60C765666C8C8C5A90419813545166C7920D
+594890A351854E4D51EA85998B0E7058637A934B696299B47E04757753576960
+8EDF96E36C5D4E8C5C3C5F108FE953028CD1808986795EFF65E54E7351650000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+47
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000059825C3F97EE4EFB598A5FCD8A8D6FE179B079625BE78471732B71B15E74
+5FF5637B649A71C37C984E435EFC4E4B57DC56A260A96FC37D0D80FD813381BF
+8FB2899786A45DF4628A64AD898767776CE26D3E743678345A467F7582AD99AC
+4FF35EC362DD63926557676F76C3724C80CC80BA8F29914D500D57F95A926885
+6973716472FD8CB758F28CE0966A9019877F79E477E784294F2F5265535A62CD
+67CF6CCA767D7B947C95823685848FEB66DD6F2072067E1B83AB99C19EA60000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+48
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000051FD7BB178727BB880877B486AE85E61808C75517560516B92626E8C767A
+91979AEA4F107F70629C7B4F95A59CE9567A585986E496BC4F345224534A53CD
+53DB5E06642C6591677F6C3E6C4E724872AF73ED75547E41822C85E98CA97BC4
+91C67169981298EF633D6669756A76E478D0854386EE532A5351542659835E87
+5F7C60B26249627962AB65906BD46CCC75B276AE789179D87DCB7F7780A588AB
+8AB98CBB907F975E98DB6A0B7C3850995C3E5FAE67876BD8743577097F8E0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+49
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00009F3B67CA7A175339758B9AED5F66819D83F180985F3C5FC575627B46903C
+686759EB5A9B7D10767E8B2C4FF55F6A6A196C376F0274E2796888688A558C79
+5EDF63CF75C579D282D7932892F2849C86ED9C2D54C15F6C658C6D5C70158CA7
+8CD3983B654F74F64E0D4ED857E0592B5A665BCC51A85E035E9C601662766577
+65A7666E6D6E72367B268150819A82998B5C8CA08CE68D74961C96444FAE64AB
+6B66821E8461856A90E85C01695398A8847A85574F0F526F5FA95E45670D0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+4A
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000798F8179890789866DF55F1762556CB84ECF72699B925206543B567458B3
+61A4626E711A596E7C897CDE7D1B96F06587805E4E194F75517558405E635E73
+5F0A67C44E26853D9589965B7C73980150FB58C1765678A7522577A585117B86
+504F590972477BC77DE88FBA8FD4904D4FBF52C95A295F0197AD4FDD821792EA
+570363556B69752B88DC8F147A4252DF58936155620A66AE6BCD7C3F83E95023
+4FF853055446583159495B9D5CF05CEF5D295E9662B16367653E65B9670B0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+4B
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00006CD56CE170F978327E2B80DE82B3840C84EC870289128A2A8C4A90A692D2
+98FD9CF39D6C4E4F4EA1508D5256574A59A85E3D5FD85FD9623F66B4671B67D0
+68D251927D2180AA81A88B008C8C8CBF927E96325420982C531750D5535C58A8
+64B26734726777667A4691E652C36CA16B8658005E4C5954672C7FFB51E176C6
+646978E89B549EBB57CB59B96627679A6BCE54E969D95E55819C67959BAA67FE
+9C52685D4EA64FE353C862B9672B6CAB8FC44FAD7E6D9EBF4E0761626E800000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+4C
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00006F2B85135473672A9B455DF37B955CAC5BC6871C6E4A84D17A1481085999
+7C8D6C11772052D959227121725F77DB97279D61690B5A7F5A1851A5540D547D
+660E76DF8FF792989CF459EA725D6EC5514D68C97DBF7DEC97629EBA64786A21
+830259845B5F6BDB731B76F27DB280178499513267289ED976EE676252FF9905
+5C24623B7C7E8CB0554F60B67D0B958053014E5F51B6591C723A803691CE5F25
+77E253845F797D0485AC8A338E8D975667F385AE9453610961086CB976520000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+4D
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00008AED8F38552F4F51512A52C753CB5BA55E7D60A0618263D6670967DA6E67
+6D8C733673377531795088D58A98904A909190F596C4878D59154E884F594E0E
+8A898F3F981050AD5E7C59965BB95EB863DA63FA64C166DC694A69D86D0B6EB6
+719475287AAF7F8A8000844984C989818B218E0A9065967D990A617E62916B32
+6C836D747FCC7FFC6DC07F8587BA88F8676583B1983C96F76D1B7D61843D916A
+4E7153755D506B046FEB85CD862D89A75229540F5C65674E68A8740674830000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+4E
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000075E288CF88E191CC96E296785F8B73877ACB844E63A0756552896D416E9C
+74097559786B7C9296867ADC9F8D4FB6616E65C5865C4E864EAE50DA4E2151CC
+5BEE659968816DBC731F764277AD7A1C7CE7826F8AD2907C91CF96759818529B
+7DD1502B539867976DCB71D0743381E88F2A96A39C579E9F746058416D997D2F
+985E4EE44F364F8B51B752B15DBA601C73B2793C82D3923496B796F6970A9E97
+9F6266A66B74521752A370C888C25EC9604B61906F2371497C3E7DF4806F0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+4F
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000084EE9023932C54429B6F6AD370898CC28DEF973252B45A415ECA5F046717
+697C69946D6A6F0F726272FC7BED8001807E874B90CE516D9E937984808B9332
+8AD6502D548C8A716B6A8CC4810760D167A09DF24E994E989C108A6B85C18568
+69006E7E78978155000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+50
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00005F0C4E104E154E2A4E314E364E3C4E3F4E424E564E584E824E858C6B4E8A
+82125F0D4E8E4E9E4E9F4EA04EA24EB04EB34EB64ECE4ECD4EC44EC64EC24ED7
+4EDE4EED4EDF4EF74F094F5A4F304F5B4F5D4F574F474F764F884F8F4F984F7B
+4F694F704F914F6F4F864F9651184FD44FDF4FCE4FD84FDB4FD14FDA4FD04FE4
+4FE5501A50285014502A502550054F1C4FF650215029502C4FFE4FEF50115006
+504350476703505550505048505A5056506C50785080509A508550B450B20000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+51
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000050C950CA50B350C250D650DE50E550ED50E350EE50F950F5510951015102
+511651155114511A5121513A5137513C513B513F51405152514C515451627AF8
+5169516A516E5180518256D8518C5189518F519151935195519651A451A651A2
+51A951AA51AB51B351B151B251B051B551BD51C551C951DB51E0865551E951ED
+51F051F551FE5204520B5214520E5227522A522E52335239524F5244524B524C
+525E5254526A527452695273527F527D528D529452925271528852918FA80000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+52
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00008FA752AC52AD52BC52B552C152CD52D752DE52E352E698ED52E052F352F5
+52F852F9530653087538530D5310530F5315531A5323532F5331533353385340
+534653454E175349534D51D6535E5369536E5918537B53775382539653A053A6
+53A553AE53B053B653C37C1296D953DF66FC71EE53EE53E853ED53FA5401543D
+5440542C542D543C542E54365429541D544E548F5475548E545F547154775470
+5492547B5480547654845490548654C754A254B854A554AC54C454C854A80000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+53
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000054AB54C254A454BE54BC54D854E554E6550F551454FD54EE54ED54FA54E2
+553955405563554C552E555C55455556555755385533555D5599558054AF558A
+559F557B557E5598559E55AE557C558355A9558755A855DA55C555DF55C455DC
+55E455D4561455F7561655FE55FD561B55F9564E565071DF5634563656325638
+566B5664562F566C566A56865680568A56A05694568F56A556AE56B656B456C2
+56BC56C156C356C056C856CE56D156D356D756EE56F9570056FF570457090000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+54
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00005708570B570D57135718571655C7571C572657375738574E573B5740574F
+576957C057885761577F5789579357A057B357A457AA57B057C357C657D457D2
+57D3580A57D657E3580B5819581D587258215862584B58706BC05852583D5879
+588558B9589F58AB58BA58DE58BB58B858AE58C558D358D158D758D958D858E5
+58DC58E458DF58EF58FA58F958FB58FC58FD5902590A5910591B68A65925592C
+592D59325938593E7AD259555950594E595A5958596259605967596C59690000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+55
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000059785981599D4F5E4FAB59A359B259C659E859DC598D59D959DA5A255A1F
+5A115A1C5A095A1A5A405A6C5A495A355A365A625A6A5A9A5ABC5ABE5ACB5AC2
+5ABD5AE35AD75AE65AE95AD65AFA5AFB5B0C5B0B5B165B325AD05B2A5B365B3E
+5B435B455B405B515B555B5A5B5B5B655B695B705B735B755B7865885B7A5B80
+5B835BA65BB85BC35BC75BC95BD45BD05BE45BE65BE25BDE5BE55BEB5BF05BF6
+5BF35C055C075C085C0D5C135C205C225C285C385C395C415C465C4E5C530000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+56
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00005C505C4F5B715C6C5C6E4E625C765C795C8C5C915C94599B5CAB5CBB5CB6
+5CBC5CB75CC55CBE5CC75CD95CE95CFD5CFA5CED5D8C5CEA5D0B5D155D175D5C
+5D1F5D1B5D115D145D225D1A5D195D185D4C5D525D4E5D4B5D6C5D735D765D87
+5D845D825DA25D9D5DAC5DAE5DBD5D905DB75DBC5DC95DCD5DD35DD25DD65DDB
+5DEB5DF25DF55E0B5E1A5E195E115E1B5E365E375E445E435E405E4E5E575E54
+5E5F5E625E645E475E755E765E7A9EBC5E7F5EA05EC15EC25EC85ED05ECF0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+57
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00005ED65EE35EDD5EDA5EDB5EE25EE15EE85EE95EEC5EF15EF35EF05EF45EF8
+5EFE5F035F095F5D5F5C5F0B5F115F165F295F2D5F385F415F485F4C5F4E5F2F
+5F515F565F575F595F615F6D5F735F775F835F825F7F5F8A5F885F915F875F9E
+5F995F985FA05FA85FAD5FBC5FD65FFB5FE45FF85FF15FDD60B35FFF60216060
+601960106029600E6031601B6015602B6026600F603A605A6041606A6077605F
+604A6046604D6063604360646042606C606B60596081608D60E76083609A0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+58
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00006084609B60966097609260A7608B60E160B860E060D360B45FF060BD60C6
+60B560D8614D6115610660F660F7610060F460FA6103612160FB60F1610D610E
+6147613E61286127614A613F613C612C6134613D614261446173617761586159
+615A616B6174616F61656171615F615D6153617561996196618761AC6194619A
+618A619161AB61AE61CC61CA61C961F761C861C361C661BA61CB7F7961CD61E6
+61E361F661FA61F461FF61FD61FC61FE620062086209620D620C6214621B0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+59
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000621E6221622A622E6230623262336241624E625E6263625B62606268627C
+62826289627E62926293629662D46283629462D762D162BB62CF62FF62C664D4
+62C862DC62CC62CA62C262C7629B62C9630C62EE62F163276302630862EF62F5
+6350633E634D641C634F6396638E638063AB637663A3638F6389639F63B5636B
+636963BE63E963C063C663E363C963D263F663C4641664346406641364266436
+651D64176428640F6467646F6476644E652A6495649364A564A9648864BC0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+5A
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000064DA64D264C564C764BB64D864C264F164E7820964E064E162AC64E364EF
+652C64F664F464F264FA650064FD6518651C650565246523652B653465356537
+65366538754B654865566555654D6558655E655D65726578658265838B8A659B
+659F65AB65B765C365C665C165C465CC65D265DB65D965E065E165F16772660A
+660365FB6773663566366634661C664F664466496641665E665D666466676668
+665F6662667066836688668E668966846698669D66C166B966C966BE66BC0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+5B
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000066C466B866D666DA66E0663F66E666E966F066F566F7670F6716671E6726
+67279738672E673F67366741673867376746675E676067596763676467896770
+67A9677C676A678C678B67A667A1678567B767EF67B467EC67B367E967B867E4
+67DE67DD67E267EE67B967CE67C667E76A9C681E684668296840684D6832684E
+68B3682B685968636877687F689F688F68AD6894689D689B68836AAE68B96874
+68B568A068BA690F688D687E690168CA690868D86922692668E1690C68CD0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+5C
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000068D468E768D569366912690468D768E3692568F968E068EF6928692A691A
+6923692168C669796977695C6978696B6954697E696E69396974693D69596930
+6961695E695D6981696A69B269AE69D069BF69C169D369BE69CE5BE869CA69DD
+69BB69C369A76A2E699169A0699C699569B469DE69E86A026A1B69FF6B0A69F9
+69F269E76A0569B16A1E69ED6A1469EB6A0A6A126AC16A236A136A446A0C6A72
+6A366A786A476A626A596A666A486A386A226A906A8D6AA06A846AA26AA30000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+5D
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00006A9786176ABB6AC36AC26AB86AB36AAC6ADE6AD16ADF6AAA6ADA6AEA6AFB
+6B0586166AFA6B126B169B316B1F6B386B3776DC6B3998EE6B476B436B496B50
+6B596B546B5B6B5F6B616B786B796B7F6B806B846B836B8D6B986B956B9E6BA4
+6BAA6BAB6BAF6BB26BB16BB36BB76BBC6BC66BCB6BD36BDF6BEC6BEB6BF36BEF
+9EBE6C086C136C146C1B6C246C236C5E6C556C626C6A6C826C8D6C9A6C816C9B
+6C7E6C686C736C926C906CC46CF16CD36CBD6CD76CC56CDD6CAE6CB16CBE0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+5E
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00006CBA6CDB6CEF6CD96CEA6D1F884D6D366D2B6D3D6D386D196D356D336D12
+6D0C6D636D936D646D5A6D796D596D8E6D956FE46D856DF96E156E0A6DB56DC7
+6DE66DB86DC66DEC6DDE6DCC6DE86DD26DC56DFA6DD96DE46DD56DEA6DEE6E2D
+6E6E6E2E6E196E726E5F6E3E6E236E6B6E2B6E766E4D6E1F6E436E3A6E4E6E24
+6EFF6E1D6E386E826EAA6E986EC96EB76ED36EBD6EAF6EC46EB26ED46ED56E8F
+6EA56EC26E9F6F416F11704C6EEC6EF86EFE6F3F6EF26F316EEF6F326ECC0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+5F
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00006F3E6F136EF76F866F7A6F786F816F806F6F6F5B6FF36F6D6F826F7C6F58
+6F8E6F916FC26F666FB36FA36FA16FA46FB96FC66FAA6FDF6FD56FEC6FD46FD8
+6FF16FEE6FDB7009700B6FFA70117001700F6FFE701B701A6F74701D7018701F
+7030703E7032705170637099709270AF70F170AC70B870B370AE70DF70CB70DD
+70D9710970FD711C711971657155718871667162714C7156716C718F71FB7184
+719571A871AC71D771B971BE71D271C971D471CE71E071EC71E771F571FC0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+60
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000071F971FF720D7210721B7228722D722C72307232723B723C723F72407246
+724B72587274727E7282728172877292729672A272A772B972B272C372C672C4
+72CE72D272E272E072E172F972F7500F7317730A731C7316731D7334732F7329
+7325733E734E734F9ED87357736A7368737073787375737B737A73C873B373CE
+73BB73C073E573EE73DE74A27405746F742573F87432743A7455743F745F7459
+7441745C746974707463746A7476747E748B749E74A774CA74CF74D473F10000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+61
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000074E074E374E774E974EE74F274F074F174F874F7750475037505750C750E
+750D75157513751E7526752C753C7544754D754A7549755B7546755A75697564
+7567756B756D75787576758675877574758A758975827594759A759D75A575A3
+75C275B375C375B575BD75B875BC75B175CD75CA75D275D975E375DE75FE75FF
+75FC760175F075FA75F275F3760B760D7609761F762776207621762276247634
+7630763B764776487646765C76587661766276687669766A7667766C76700000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+62
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000767276767678767C768076837688768B768E769676937699769A76B076B4
+76B876B976BA76C276CD76D676D276DE76E176E576E776EA862F76FB77087707
+770477297724771E77257726771B773777387747775A7768776B775B7765777F
+777E7779778E778B779177A0779E77B077B677B977BF77BC77BD77BB77C777CD
+77D777DA77DC77E377EE77FC780C781279267820792A7845788E78747886787C
+789A788C78A378B578AA78AF78D178C678CB78D478BE78BC78C578CA78EC0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+63
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000078E778DA78FD78F47907791279117919792C792B794079607957795F795A
+79557953797A797F798A799D79A79F4B79AA79AE79B379B979BA79C979D579E7
+79EC79E179E37A087A0D7A187A197A207A1F79807A317A3B7A3E7A377A437A57
+7A497A617A627A699F9D7A707A797A7D7A887A977A957A987A967AA97AC87AB0
+7AB67AC57AC47ABF90837AC77ACA7ACD7ACF7AD57AD37AD97ADA7ADD7AE17AE2
+7AE67AED7AF07B027B0F7B0A7B067B337B187B197B1E7B357B287B367B500000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+64
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00007B7A7B047B4D7B0B7B4C7B457B757B657B747B677B707B717B6C7B6E7B9D
+7B987B9F7B8D7B9C7B9A7B8B7B927B8F7B5D7B997BCB7BC17BCC7BCF7BB47BC6
+7BDD7BE97C117C147BE67BE57C607C007C077C137BF37BF77C177C0D7BF67C23
+7C277C2A7C1F7C377C2B7C3D7C4C7C437C547C4F7C407C507C587C5F7C647C56
+7C657C6C7C757C837C907CA47CAD7CA27CAB7CA17CA87CB37CB27CB17CAE7CB9
+7CBD7CC07CC57CC27CD87CD27CDC7CE29B3B7CEF7CF27CF47CF67CFA7D060000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+65
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00007D027D1C7D157D0A7D457D4B7D2E7D327D3F7D357D467D737D567D4E7D72
+7D687D6E7D4F7D637D937D897D5B7D8F7D7D7D9B7DBA7DAE7DA37DB57DC77DBD
+7DAB7E3D7DA27DAF7DDC7DB87D9F7DB07DD87DDD7DE47DDE7DFB7DF27DE17E05
+7E0A7E237E217E127E317E1F7E097E0B7E227E467E667E3B7E357E397E437E37
+7E327E3A7E677E5D7E567E5E7E597E5A7E797E6A7E697E7C7E7B7E837DD57E7D
+8FAE7E7F7E887E897E8C7E927E907E937E947E967E8E7E9B7E9C7F387F3A0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+66
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00007F457F4C7F4D7F4E7F507F517F557F547F587F5F7F607F687F697F677F78
+7F827F867F837F887F877F8C7F947F9E7F9D7F9A7FA37FAF7FB27FB97FAE7FB6
+7FB88B717FC57FC67FCA7FD57FD47FE17FE67FE97FF37FF998DC80068004800B
+801280188019801C80218028803F803B804A804680528058805A805F80628068
+80738072807080768079807D807F808480868085809B8093809A80AD519080AC
+80DB80E580D980DD80C480DA80D6810980EF80F1811B81298123812F814B0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+67
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000968B8146813E8153815180FC8171816E81658166817481838188818A8180
+818281A0819581A481A3815F819381A981B081B581BE81B881BD81C081C281BA
+81C981CD81D181D981D881C881DA81DF81E081E781FA81FB81FE820182028205
+8207820A820D821082168229822B82388233824082598258825D825A825F8264
+82628268826A826B822E827182778278827E828D829282AB829F82BB82AC82E1
+82E382DF82D282F482F382FA8393830382FB82F982DE830682DC830982D90000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+68
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000833583348316833283318340833983508345832F832B831783188385839A
+83AA839F83A283968323838E8387838A837C83B58373837583A0838983A883F4
+841383EB83CE83FD840383D8840B83C183F7840783E083F2840D8422842083BD
+8438850683FB846D842A843C855A84848477846B84AD846E848284698446842C
+846F8479843584CA846284B984BF849F84D984CD84BB84DA84D084C184C684D6
+84A1852184FF84F485178518852C851F8515851484FC85408563855885480000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+69
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000085418602854B8555858085A485888591858A85A8856D8594859B85EA8587
+859C8577857E859085C985BA85CF85B985D085D585DD85E585DC85F9860A8613
+860B85FE85FA86068622861A8630863F864D4E558654865F86678671869386A3
+86A986AA868B868C86B686AF86C486C686B086C9882386AB86D486DE86E986EC
+86DF86DB86EF8712870687088700870386FB87118709870D86F9870A8734873F
+8737873B87258729871A8760875F8778874C874E877487578768876E87590000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+6A
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000087538763876A880587A2879F878287AF87CB87BD87C087D096D687AB87C4
+87B387C787C687BB87EF87F287E0880F880D87FE87F687F7880E87D288118816
+8815882288218831883688398827883B8844884288528859885E8862886B8881
+887E889E8875887D88B5887288828897889288AE889988A2888D88A488B088BF
+88B188C388C488D488D888D988DD88F9890288FC88F488E888F28904890C890A
+89138943891E8925892A892B89418944893B89368938894C891D8960895E0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+6B
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000089668964896D896A896F89748977897E89838988898A8993899889A189A9
+89A689AC89AF89B289BA89BD89BF89C089DA89DC89DD89E789F489F88A038A16
+8A108A0C8A1B8A1D8A258A368A418A5B8A528A468A488A7C8A6D8A6C8A628A85
+8A828A848AA88AA18A918AA58AA68A9A8AA38AC48ACD8AC28ADA8AEB8AF38AE7
+8AE48AF18B148AE08AE28AF78ADE8ADB8B0C8B078B1A8AE18B168B108B178B20
+8B3397AB8B268B2B8B3E8B288B418B4C8B4F8B4E8B498B568B5B8B5A8B6B0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+6C
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00008B5F8B6C8B6F8B748B7D8B808B8C8B8E8B928B938B968B998B9A8C3A8C41
+8C3F8C488C4C8C4E8C508C558C628C6C8C788C7A8C828C898C858C8A8C8D8C8E
+8C948C7C8C98621D8CAD8CAA8CBD8CB28CB38CAE8CB68CC88CC18CE48CE38CDA
+8CFD8CFA8CFB8D048D058D0A8D078D0F8D0D8D109F4E8D138CCD8D148D168D67
+8D6D8D718D738D818D998DC28DBE8DBA8DCF8DDA8DD68DCC8DDB8DCB8DEA8DEB
+8DDF8DE38DFC8E088E098DFF8E1D8E1E8E108E1F8E428E358E308E348E4A0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+6D
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00008E478E498E4C8E508E488E598E648E608E2A8E638E558E768E728E7C8E81
+8E878E858E848E8B8E8A8E938E918E948E998EAA8EA18EAC8EB08EC68EB18EBE
+8EC58EC88ECB8EDB8EE38EFC8EFB8EEB8EFE8F0A8F058F158F128F198F138F1C
+8F1F8F1B8F0C8F268F338F3B8F398F458F428F3E8F4C8F498F468F4E8F578F5C
+8F628F638F648F9C8F9F8FA38FAD8FAF8FB78FDA8FE58FE28FEA8FEF90878FF4
+90058FF98FFA901190159021900D901E9016900B90279036903590398FF80000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+6E
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000904F905090519052900E9049903E90569058905E9068906F907696A89072
+9082907D90819080908A9089908F90A890AF90B190B590E290E4624890DB9102
+9112911991329130914A9156915891639165916991739172918B9189918291A2
+91AB91AF91AA91B591B491BA91C091C191C991CB91D091D691DF91E191DB91FC
+91F591F6921E91FF9214922C92159211925E925792459249926492489295923F
+924B9250929C92969293929B925A92CF92B992B792E9930F92FA9344932E0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+6F
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000093199322931A9323933A9335933B935C9360937C936E935693B093AC93AD
+939493B993D693D793E893E593D893C393DD93D093C893E4941A941494139403
+940794109436942B94359421943A944194529444945B94609462945E946A9229
+947094759477947D945A947C947E9481947F95829587958A9594959695989599
+95A095A895A795AD95BC95BB95B995BE95CA6FF695C395CD95CC95D595D495D6
+95DC95E195E595E296219628962E962F9642964C964F964B9677965C965E0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+70
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000965D965F96669672966C968D96989695969796AA96A796B196B296B096B4
+96B696B896B996CE96CB96C996CD894D96DC970D96D596F99704970697089713
+970E9711970F971697199724972A97309739973D973E97449746974897429749
+975C976097649766976852D2976B977197799785977C9781977A9786978B978F
+9790979C97A897A697A397B397B497C397C697C897CB97DC97ED9F4F97F27ADF
+97F697F5980F980C9838982498219837983D9846984F984B986B986F98700000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+71
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000098719874987398AA98AF98B198B698C498C398C698E998EB990399099912
+991499189921991D991E99249920992C992E993D993E9942994999459950994B
+99519952994C99559997999899A599AD99AE99BC99DF99DB99DD99D899D199ED
+99EE99F199F299FB99F89A019A0F9A0599E29A199A2B9A379A459A429A409A43
+9A3E9A559A4D9A5B9A579A5F9A629A659A649A699A6B9A6A9AAD9AB09ABC9AC0
+9ACF9AD19AD39AD49ADE9ADF9AE29AE39AE69AEF9AEB9AEE9AF49AF19AF70000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+72
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00009AFB9B069B189B1A9B1F9B229B239B259B279B289B299B2A9B2E9B2F9B32
+9B449B439B4F9B4D9B4E9B519B589B749B939B839B919B969B979B9F9BA09BA8
+9BB49BC09BCA9BB99BC69BCF9BD19BD29BE39BE29BE49BD49BE19C3A9BF29BF1
+9BF09C159C149C099C139C0C9C069C089C129C0A9C049C2E9C1B9C259C249C21
+9C309C479C329C469C3E9C5A9C609C679C769C789CE79CEC9CF09D099D089CEB
+9D039D069D2A9D269DAF9D239D1F9D449D159D129D419D3F9D3E9D469D480000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+73
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00009D5D9D5E9D649D519D509D599D729D899D879DAB9D6F9D7A9D9A9DA49DA9
+9DB29DC49DC19DBB9DB89DBA9DC69DCF9DC29DD99DD39DF89DE69DED9DEF9DFD
+9E1A9E1B9E1E9E759E799E7D9E819E889E8B9E8C9E929E959E919E9D9EA59EA9
+9EB89EAA9EAD97619ECC9ECE9ECF9ED09ED49EDC9EDE9EDD9EE09EE59EE89EEF
+9EF49EF69EF79EF99EFB9EFC9EFD9F079F0876B79F159F219F2C9F3E9F4A9F52
+9F549F639F5F9F609F619F669F679F6C9F6A9F779F729F769F959F9C9FA00000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+74
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000582F69C79059746451DC7199000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+R
+2141 301C FF5E
+2142 2016 2225
+215D 2212 FF0D
+2171 00A2 FFE0
+2172 00A3 FFE1
+224C 00AC FFE2
diff --git a/library/encoding/jis0212.enc b/library/encoding/jis0212.enc
new file mode 100644
index 0000000..cddbbba
--- /dev/null
+++ b/library/encoding/jis0212.enc
@@ -0,0 +1,1159 @@
+# Encoding file: jis0212, double-byte
+D
+2244 0 68
+22
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000000000000000000002D8
+02C700B802D902DD00AF02DB02DA007E03840385000000000000000000000000
+0000000000A100A600BF00000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000BA00AA00A900AE2122
+00A4211600000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+26
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000038603880389038A03AA0000038C0000038E03AB0000038F000000000000
+000003AC03AD03AE03AF03CA039003CC03C203CD03CB03B003CE000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+27
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000004020403040404050406040704080409040A040B040C040E040F0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000004520453045404550456045704580459045A045B045C045E045F0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+29
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000000C60110000001260000013200000141013F0000014A00D8015200000166
+00DE000000000000000000000000000000000000000000000000000000000000
+000000E6011100F00127013101330138014201400149014B00F8015300DF0167
+00FE000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+2A
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000000C100C000C400C2010201CD0100010400C500C301060108010C00C7010A
+010E00C900C800CB00CA011A0116011201180000011C011E01220120012400CD
+00CC00CF00CE01CF0130012A012E0128013401360139013D013B014301470145
+00D100D300D200D600D401D10150014C00D5015401580156015A015C0160015E
+0164016200DA00D900DC00DB016C01D30170016A0172016E016801D701DB01D9
+01D5017400DD017801760179017D017B00000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+2B
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000000E100E000E400E2010301CE0101010500E500E301070109010D00E7010B
+010F00E900E800EB00EA011B01170113011901F5011D011F00000121012500ED
+00EC00EF00EE01D00000012B012F012901350137013A013E013C014401480146
+00F100F300F200F600F401D20151014D00F5015501590157015B015D0161015F
+0165016300FA00F900FC00FB016D01D40171016B0173016F016901D801DC01DA
+01D6017500FD00FF0177017A017E017C00000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+30
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00004E024E044E054E0C4E124E1F4E234E244E284E2B4E2E4E2F4E304E354E40
+4E414E444E474E514E5A4E5C4E634E684E694E744E754E794E7F4E8D4E964E97
+4E9D4EAF4EB94EC34ED04EDA4EDB4EE04EE14EE24EE84EEF4EF14EF34EF54EFD
+4EFE4EFF4F004F024F034F084F0B4F0C4F124F154F164F174F194F2E4F314F60
+4F334F354F374F394F3B4F3E4F404F424F484F494F4B4F4C4F524F544F564F58
+4F5F4F634F6A4F6C4F6E4F714F774F784F794F7A4F7D4F7E4F814F824F840000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+31
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00004F854F894F8A4F8C4F8E4F904F924F934F944F974F994F9A4F9E4F9F4FB2
+4FB74FB94FBB4FBC4FBD4FBE4FC04FC14FC54FC64FC84FC94FCB4FCC4FCD4FCF
+4FD24FDC4FE04FE24FF04FF24FFC4FFD4FFF5000500150045007500A500C500E
+5010501350175018501B501C501D501E50225027502E50305032503350355040
+5041504250455046504A504C504E50515052505350575059505F506050625063
+50665067506A506D50705071503B5081508350845086508A508E508F50900000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+32
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00005092509350945096509B509C509E509F50A050A150A250AA50AF50B050B9
+50BA50BD50C050C350C450C750CC50CE50D050D350D450D850DC50DD50DF50E2
+50E450E650E850E950EF50F150F650FA50FE5103510651075108510B510C510D
+510E50F2511051175119511B511C511D511E512351275128512C512D512F5131
+513351345135513851395142514A514F5153515551575158515F51645166517E
+51835184518B518E5198519D51A151A351AD51B851BA51BC51BE51BF51C20000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+33
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000051C851CF51D151D251D351D551D851DE51E251E551EE51F251F351F451F7
+5201520252055212521352155216521852225228523152325235523C52455249
+525552575258525A525C525F526052615266526E527752785279528052825285
+528A528C52935295529652975298529A529C52A452A552A652A752AF52B052B6
+52B752B852BA52BB52BD52C052C452C652C852CC52CF52D152D452D652DB52DC
+52E152E552E852E952EA52EC52F052F152F452F652F753005303530A530B0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+34
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000530C531153135318531B531C531E531F5325532753285329532B532C532D
+533053325335533C533D533E5342534C534B5359535B536153635365536C536D
+53725379537E538353875388538E539353945399539D53A153A453AA53AB53AF
+53B253B453B553B753B853BA53BD53C053C553CF53D253D353D553DA53DD53DE
+53E053E653E753F554025413541A542154275428542A542F5431543454355443
+54445447544D544F545E54625464546654675469546B546D546E5474547F0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+35
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000054815483548554885489548D549154955496549C549F54A154A654A754A9
+54AA54AD54AE54B154B754B954BA54BB54BF54C654CA54CD54CE54E054EA54EC
+54EF54F654FC54FE54FF55005501550555085509550C550D550E5515552A552B
+553255355536553B553C553D554155475549554A554D555055515558555A555B
+555E5560556155645566557F5581558255865588558E558F5591559255935594
+559755A355A455AD55B255BF55C155C355C655C955CB55CC55CE55D155D20000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+36
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000055D355D755D855DB55DE55E255E955F655FF56055608560A560D560E560F
+5610561156125619562C56305633563556375639563B563C563D563F56405641
+5643564456465649564B564D564F5654565E566056615662566356665669566D
+566F567156725675568456855688568B568C56955699569A569D569E569F56A6
+56A756A856A956AB56AC56AD56B156B356B756BE56C556C956CA56CB56CF56D0
+56CC56CD56D956DC56DD56DF56E156E456E556E656E756E856F156EB56ED0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+37
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000056F656F7570157025707570A570C57115715571A571B571D572057225723
+572457255729572A572C572E572F57335734573D573E573F57455746574C574D
+57525762576557675768576B576D576E576F5770577157735774577557775779
+577A577B577C577E57815783578C579457975799579A579C579D579E579F57A1
+579557A757A857A957AC57B857BD57C757C857CC57CF57D557DD57DE57E457E6
+57E757E957ED57F057F557F657F857FD57FE57FF580358045808580957E10000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+38
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000580C580D581B581E581F582058265827582D58325839583F5849584C584D
+584F58505855585F58615864586758685878587C587F58805881588758885889
+588A588C588D588F589058945896589D58A058A158A258A658A958B158B258C4
+58BC58C258C858CD58CE58D058D258D458D658DA58DD58E158E258E958F35905
+5906590B590C5912591359148641591D5921592359245928592F593059335935
+5936593F59435946595259535959595B595D595E595F59615963596B596D0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+39
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000596F5972597559765979597B597C598B598C598E599259955997599F59A4
+59A759AD59AE59AF59B059B359B759BA59BC59C159C359C459C859CA59CD59D2
+59DD59DE59DF59E359E459E759EE59EF59F159F259F459F75A005A045A0C5A0D
+5A0E5A125A135A1E5A235A245A275A285A2A5A2D5A305A445A455A475A485A4C
+5A505A555A5E5A635A655A675A6D5A775A7A5A7B5A7E5A8B5A905A935A965A99
+5A9C5A9E5A9F5AA05AA25AA75AAC5AB15AB25AB35AB55AB85ABA5ABB5ABF0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+3A
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00005AC45AC65AC85ACF5ADA5ADC5AE05AE55AEA5AEE5AF55AF65AFD5B005B01
+5B085B175B345B195B1B5B1D5B215B255B2D5B385B415B4B5B4C5B525B565B5E
+5B685B6E5B6F5B7C5B7D5B7E5B7F5B815B845B865B8A5B8E5B905B915B935B94
+5B965BA85BA95BAC5BAD5BAF5BB15BB25BB75BBA5BBC5BC05BC15BCD5BCF5BD6
+5BD75BD85BD95BDA5BE05BEF5BF15BF45BFD5C0C5C175C1E5C1F5C235C265C29
+5C2B5C2C5C2E5C305C325C355C365C595C5A5C5C5C625C635C675C685C690000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+3B
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00005C6D5C705C745C755C7A5C7B5C7C5C7D5C875C885C8A5C8F5C925C9D5C9F
+5CA05CA25CA35CA65CAA5CB25CB45CB55CBA5CC95CCB5CD25CDD5CD75CEE5CF1
+5CF25CF45D015D065D0D5D125D2B5D235D245D265D275D315D345D395D3D5D3F
+5D425D435D465D485D555D515D595D4A5D5F5D605D615D625D645D6A5D6D5D70
+5D795D7A5D7E5D7F5D815D835D885D8A5D925D935D945D955D995D9B5D9F5DA0
+5DA75DAB5DB05DB45DB85DB95DC35DC75DCB5DD05DCE5DD85DD95DE05DE40000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+3C
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00005DE95DF85DF95E005E075E0D5E125E145E155E185E1F5E205E2E5E285E32
+5E355E3E5E4B5E505E495E515E565E585E5B5E5C5E5E5E685E6A5E6B5E6C5E6D
+5E6E5E705E805E8B5E8E5EA25EA45EA55EA85EAA5EAC5EB15EB35EBD5EBE5EBF
+5EC65ECC5ECB5ECE5ED15ED25ED45ED55EDC5EDE5EE55EEB5F025F065F075F08
+5F0E5F195F1C5F1D5F215F225F235F245F285F2B5F2C5F2E5F305F345F365F3B
+5F3D5F3F5F405F445F455F475F4D5F505F545F585F5B5F605F635F645F670000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+3D
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00005F6F5F725F745F755F785F7A5F7D5F7E5F895F8D5F8F5F965F9C5F9D5FA2
+5FA75FAB5FA45FAC5FAF5FB05FB15FB85FC45FC75FC85FC95FCB5FD05FD15FD2
+5FD35FD45FDE5FE15FE25FE85FE95FEA5FEC5FED5FEE5FEF5FF25FF35FF65FFA
+5FFC6007600A600D6013601460176018601A601F6024602D6033603560406047
+60486049604C6051605460566057605D606160676071607E607F608260866088
+608A608E6091609360956098609D609E60A260A460A560A860B060B160B70000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+3E
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000060BB60BE60C260C460C860C960CA60CB60CE60CF60D460D560D960DB60DD
+60DE60E260E560F260F560F860FC60FD61026107610A610C6110611161126113
+6114611661176119611C611E6122612A612B6130613161356136613761396141
+614561466149615E6160616C61726178617B617C617F6180618161836184618B
+618D6192619361976198619C619D619F61A061A561A861AA61AD61B861B961BC
+61C061C161C261CE61CF61D561DC61DD61DE61DF61E161E261E761E961E50000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+3F
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000061EC61ED61EF620162036204620762136215621C62206222622362276229
+622B6239623D6242624362446246624C62506251625262546256625A625C6264
+626D626F6273627A627D628D628E628F629062A662A862B362B662B762BA62BE
+62BF62C462CE62D562D662DA62EA62F262F462FC62FD63036304630A630B630D
+63106313631663186329632A632D633563366339633C63416342634363446346
+634A634B634E6352635363546358635B63656366636C636D6371637463750000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+40
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00006378637C637D637F638263846387638A6390639463956399639A639E63A4
+63A663AD63AE63AF63BD63C163C563C863CE63D163D363D463D563DC63E063E5
+63EA63EC63F263F363F563F863F96409640A6410641264146418641E64206422
+642464256429642A642F64306435643D643F644B644F6451645264536454645A
+645B645C645D645F646064616463646D64736474647B647D64856487648F6490
+649164986499649B649D649F64A164A364A664A864AC64B364BD64BE64BF0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+41
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000064C464C964CA64CB64CC64CE64D064D164D564D764E464E564E964EA64ED
+64F064F564F764FB64FF6501650465086509650A650F6513651465166519651B
+651E651F652265266529652E6531653A653C653D654365476549655065526554
+655F65606567656B657A657D65816585658A659265956598659D65A065A365A6
+65AE65B265B365B465BF65C265C865C965CE65D065D465D665D865DF65F065F2
+65F465F565F965FE65FF6600660466086609660D6611661266156616661D0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+42
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000661E662166226623662466266629662A662B662C662E6630663166336639
+6637664066456646664A664C6651664E665766586659665B665C6660666166FB
+666A666B666C667E66736675667F667766786679667B6680667C668B668C668D
+669066926699669A669B669C669F66A066A466AD66B166B266B566BB66BF66C0
+66C266C366C866CC66CE66CF66D466DB66DF66E866EB66EC66EE66FA67056707
+670E67136719671C672067226733673E674567476748674C67546755675D0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+43
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00006766676C676E67746776677B67816784678E678F67916793679667986799
+679B67B067B167B267B567BB67BC67BD67F967C067C267C367C567C867C967D2
+67D767D967DC67E167E667F067F267F667F7685268146819681D681F68286827
+682C682D682F683068316833683B683F68446845684A684C685568576858685B
+686B686E686F68706871687268756879687A687B687C68826884688668886896
+6898689A689C68A168A368A568A968AA68AE68B268BB68C568C868CC68CF0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+44
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000068D068D168D368D668D968DC68DD68E568E868EA68EB68EC68ED68F068F1
+68F568F668FB68FC68FD69066909690A69106911691369166917693169336935
+6938693B694269456949694E6957695B696369646965696669686969696C6970
+69716972697A697B697F6980698D69926996699869A169A569A669A869AB69AD
+69AF69B769B869BA69BC69C569C869D169D669D769E269E569EE69EF69F169F3
+69F569FE6A006A016A036A0F6A116A156A1A6A1D6A206A246A286A306A320000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+45
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00006A346A376A3B6A3E6A3F6A456A466A496A4A6A4E6A506A516A526A556A56
+6A5B6A646A676A6A6A716A736A7E6A816A836A866A876A896A8B6A916A9B6A9D
+6A9E6A9F6AA56AAB6AAF6AB06AB16AB46ABD6ABE6ABF6AC66AC96AC86ACC6AD0
+6AD46AD56AD66ADC6ADD6AE46AE76AEC6AF06AF16AF26AFC6AFD6B026B036B06
+6B076B096B0F6B106B116B176B1B6B1E6B246B286B2B6B2C6B2F6B356B366B3B
+6B3F6B466B4A6B4D6B526B566B586B5D6B606B676B6B6B6E6B706B756B7D0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+46
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00006B7E6B826B856B976B9B6B9F6BA06BA26BA36BA86BA96BAC6BAD6BAE6BB0
+6BB86BB96BBD6BBE6BC36BC46BC96BCC6BD66BDA6BE16BE36BE66BE76BEE6BF1
+6BF76BF96BFF6C026C046C056C096C0D6C0E6C106C126C196C1F6C266C276C28
+6C2C6C2E6C336C356C366C3A6C3B6C3F6C4A6C4B6C4D6C4F6C526C546C596C5B
+6C5C6C6B6C6D6C6F6C746C766C786C796C7B6C856C866C876C896C946C956C97
+6C986C9C6C9F6CB06CB26CB46CC26CC66CCD6CCF6CD06CD16CD26CD46CD60000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+47
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00006CDA6CDC6CE06CE76CE96CEB6CEC6CEE6CF26CF46D046D076D0A6D0E6D0F
+6D116D136D1A6D266D276D286C676D2E6D2F6D316D396D3C6D3F6D576D5E6D5F
+6D616D656D676D6F6D706D7C6D826D876D916D926D946D966D976D986DAA6DAC
+6DB46DB76DB96DBD6DBF6DC46DC86DCA6DCE6DCF6DD66DDB6DDD6DDF6DE06DE2
+6DE56DE96DEF6DF06DF46DF66DFC6E006E046E1E6E226E276E326E366E396E3B
+6E3C6E446E456E486E496E4B6E4F6E516E526E536E546E576E5C6E5D6E5E0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+48
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00006E626E636E686E736E7B6E7D6E8D6E936E996EA06EA76EAD6EAE6EB16EB3
+6EBB6EBF6EC06EC16EC36EC76EC86ECA6ECD6ECE6ECF6EEB6EED6EEE6EF96EFB
+6EFD6F046F086F0A6F0C6F0D6F166F186F1A6F1B6F266F296F2A6F2F6F306F33
+6F366F3B6F3C6F2D6F4F6F516F526F536F576F596F5A6F5D6F5E6F616F626F68
+6F6C6F7D6F7E6F836F876F886F8B6F8C6F8D6F906F926F936F946F966F9A6F9F
+6FA06FA56FA66FA76FA86FAE6FAF6FB06FB56FB66FBC6FC56FC76FC86FCA0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+49
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00006FDA6FDE6FE86FE96FF06FF56FF96FFC6FFD7000700570067007700D7017
+70207023702F703470377039703C7043704470487049704A704B70547055705D
+705E704E70647065706C706E70757076707E7081708570867094709570967097
+7098709B70A470AB70B070B170B470B770CA70D170D370D470D570D670D870DC
+70E470FA71037104710571067107710B710C710F711E7120712B712D712F7130
+713171387141714571467147714A714B715071527157715A715C715E71600000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+4A
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000071687179718071857187718C7192719A719B71A071A271AF71B071B271B3
+71BA71BF71C071C171C471CB71CC71D371D671D971DA71DC71F871FE72007207
+7208720972137217721A721D721F7224722B722F723472387239724172427243
+7245724E724F7250725372557256725A725C725E726072637268726B726E726F
+727172777278727B727C727F72847289728D728E7293729B72A872AD72AE72B1
+72B472BE72C172C772C972CC72D572D672D872DF72E572F372F472FA72FB0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+4B
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000072FE7302730473057307730B730D7312731373187319731E732273247327
+7328732C733173327335733A733B733D7343734D7350735273567358735D735E
+735F7360736673677369736B736C736E736F737173777379737C738073817383
+73857386738E73907393739573977398739C739E739F73A073A273A573A673AA
+73AB73AD73B573B773B973BC73BD73BF73C573C673C973CB73CC73CF73D273D3
+73D673D973DD73E173E373E673E773E973F473F573F773F973FA73FB73FD0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+4C
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000073FF7400740174047407740A7411741A741B7424742674287429742A742B
+742C742D742E742F74307431743974407443744474467447744B744D74517452
+7457745D7462746674677468746B746D746E7471747274807481748574867487
+7489748F74907491749274987499749A749C749F74A074A174A374A674A874A9
+74AA74AB74AE74AF74B174B274B574B974BB74BF74C874C974CC74D074D374D8
+74DA74DB74DE74DF74E474E874EA74EB74EF74F474FA74FB74FC74FF75060000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+4D
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000075127516751775207521752475277529752A752F75367539753D753E753F
+7540754375477548754E755075527557755E755F7561756F75717579757A757B
+757C757D757E7581758575907592759375957599759C75A275A475B475BA75BF
+75C075C175C475C675CC75CE75CF75D775DC75DF75E075E175E475E775EC75EE
+75EF75F175F9760076027603760476077608760A760C760F7612761376157616
+7619761B761C761D761E7623762576267629762D763276337635763876390000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+4E
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000763A763C764A764076417643764476457649764B76557659765F76647665
+766D766E766F7671767476817685768C768D7695769B769C769D769F76A076A2
+76A376A476A576A676A776A876AA76AD76BD76C176C576C976CB76CC76CE76D4
+76D976E076E676E876EC76F076F176F676F976FC77007706770A770E77127714
+771577177719771A771C77227728772D772E772F7734773577367739773D773E
+774277457746774A774D774E774F775277567757775C775E775F776077620000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+4F
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000077647767776A776C7770777277737774777A777D77807784778C778D7794
+77957796779A779F77A277A777AA77AE77AF77B177B577BE77C377C977D177D2
+77D577D977DE77DF77E077E477E677EA77EC77F077F177F477F877FB78057806
+7809780D780E7811781D782178227823782D782E783078357837784378447847
+7848784C784E7852785C785E78607861786378647868786A786E787A787E788A
+788F7894789878A1789D789E789F78A478A878AC78AD78B078B178B278B30000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+50
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000078BB78BD78BF78C778C878C978CC78CE78D278D378D578D678E478DB78DF
+78E078E178E678EA78F278F3790078F678F778FA78FB78FF7906790C7910791A
+791C791E791F7920792579277929792D793179347935793B793D793F79447945
+7946794A794B794F795179547958795B795C79677969796B79727979797B797C
+797E798B798C799179937994799579967998799B799C79A179A879A979AB79AF
+79B179B479B879BB79C279C479C779C879CA79CF79D479D679DA79DD79DE0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+51
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000079E079E279E579EA79EB79ED79F179F879FC7A027A037A077A097A0A7A0C
+7A117A157A1B7A1E7A217A277A2B7A2D7A2F7A307A347A357A387A397A3A7A44
+7A457A477A487A4C7A557A567A597A5C7A5D7A5F7A607A657A677A6A7A6D7A75
+7A787A7E7A807A827A857A867A8A7A8B7A907A917A947A9E7AA07AA37AAC7AB3
+7AB57AB97ABB7ABC7AC67AC97ACC7ACE7AD17ADB7AE87AE97AEB7AEC7AF17AF4
+7AFB7AFD7AFE7B077B147B1F7B237B277B297B2A7B2B7B2D7B2E7B2F7B300000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+52
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00007B317B347B3D7B3F7B407B417B477B4E7B557B607B647B667B697B6A7B6D
+7B6F7B727B737B777B847B897B8E7B907B917B967B9B7B9E7BA07BA57BAC7BAF
+7BB07BB27BB57BB67BBA7BBB7BBC7BBD7BC27BC57BC87BCA7BD47BD67BD77BD9
+7BDA7BDB7BE87BEA7BF27BF47BF57BF87BF97BFA7BFC7BFE7C017C027C037C04
+7C067C097C0B7C0C7C0E7C0F7C197C1B7C207C257C267C287C2C7C317C337C34
+7C367C397C3A7C467C4A7C557C517C527C537C597C5A7C5B7C5C7C5D7C5E0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+53
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00007C617C637C677C697C6D7C6E7C707C727C797C7C7C7D7C867C877C8F7C94
+7C9E7CA07CA67CB07CB67CB77CBA7CBB7CBC7CBF7CC47CC77CC87CC97CCD7CCF
+7CD37CD47CD57CD77CD97CDA7CDD7CE67CE97CEB7CF57D037D077D087D097D0F
+7D117D127D137D167D1D7D1E7D237D267D2A7D2D7D317D3C7D3D7D3E7D407D41
+7D477D487D4D7D517D537D577D597D5A7D5C7D5D7D657D677D6A7D707D787D7A
+7D7B7D7F7D817D827D837D857D867D887D8B7D8C7D8D7D917D967D977D9D0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+54
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00007D9E7DA67DA77DAA7DB37DB67DB77DB97DC27DC37DC47DC57DC67DCC7DCD
+7DCE7DD77DD97E007DE27DE57DE67DEA7DEB7DED7DF17DF57DF67DF97DFA7E08
+7E107E117E157E177E1C7E1D7E207E277E287E2C7E2D7E2F7E337E367E3F7E44
+7E457E477E4E7E507E527E587E5F7E617E627E657E6B7E6E7E6F7E737E787E7E
+7E817E867E877E8A7E8D7E917E957E987E9A7E9D7E9E7F3C7F3B7F3D7F3E7F3F
+7F437F447F477F4F7F527F537F5B7F5C7F5D7F617F637F647F657F667F6D0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+55
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00007F717F7D7F7E7F7F7F807F8B7F8D7F8F7F907F917F967F977F9C7FA17FA2
+7FA67FAA7FAD7FB47FBC7FBF7FC07FC37FC87FCE7FCF7FDB7FDF7FE37FE57FE8
+7FEC7FEE7FEF7FF27FFA7FFD7FFE7FFF80078008800A800D800E800F80118013
+80148016801D801E801F802080248026802C802E80308034803580378039803A
+803C803E80408044806080648066806D8071807580818088808E809C809E80A6
+80A780AB80B880B980C880CD80CF80D280D480D580D780D880E080ED80EE0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+56
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000080F080F280F380F680F980FA80FE8103810B811681178118811C811E8120
+81248127812C81308135813A813C81458147814A814C81528157816081618167
+81688169816D816F817781818190818481858186818B818E81968198819B819E
+81A281AE81B281B481BB81CB81C381C581CA81CE81CF81D581D781DB81DD81DE
+81E181E481EB81EC81F081F181F281F581F681F881F981FD81FF82008203820F
+821382148219821A821D82218222822882328234823A82438244824582460000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+57
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000824B824E824F82518256825C826082638267826D8274827B827D827F8280
+82818283828482878289828A828E8291829482968298829A829B82A082A182A3
+82A482A782A882A982AA82AE82B082B282B482B782BA82BC82BE82BF82C682D0
+82D582DA82E082E282E482E882EA82ED82EF82F682F782FD82FE830083018307
+8308830A830B8354831B831D831E831F83218322832C832D832E833083338337
+833A833C833D8342834383448347834D834E8351835583568357837083780000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+58
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000837D837F8380838283848386838D83928394839583988399839B839C839D
+83A683A783A983AC83BE83BF83C083C783C983CF83D083D183D483DD835383E8
+83EA83F683F883F983FC84018406840A840F84118415841983AD842F84398445
+84478448844A844D844F84518452845684588459845A845C8460846484658467
+846A84708473847484768478847C847D84818485849284938495849E84A684A8
+84A984AA84AF84B184B484BA84BD84BE84C084C284C784C884CC84CF84D30000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+59
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000084DC84E784EA84EF84F084F184F284F7853284FA84FB84FD850285038507
+850C850E8510851C851E85228523852485258527852A852B852F853385348536
+853F8546854F855085518552855385568559855C855D855E855F856085618562
+8564856B856F8579857A857B857D857F8581858585868589858B858C858F8593
+8598859D859F85A085A285A585A785B485B685B785B885BC85BD85BE85BF85C2
+85C785CA85CB85CE85AD85D885DA85DF85E085E685E885ED85F385F685FC0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+5A
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000085FF860086048605860D860E86108611861286188619861B861E86218627
+862986368638863A863C863D864086428646865286538656865786588659865D
+866086618662866386648669866C866F867586768677867A868D869186968698
+869A869C86A186A686A786A886AD86B186B386B486B586B786B886B986BF86C0
+86C186C386C586D186D286D586D786DA86DC86E086E386E586E7868886FA86FC
+86FD870487058707870B870E870F8710871387148719871E871F872187230000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+5B
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00008728872E872F873187328739873A873C873D873E874087438745874D8758
+875D876187648765876F87718772877B8783878487858786878787888789878B
+878C879087938795879787988799879E87A087A387A787AC87AD87AE87B187B5
+87BE87BF87C187C887C987CA87CE87D587D687D987DA87DC87DF87E287E387E4
+87EA87EB87ED87F187F387F887FA87FF8801880388068809880A880B88108819
+8812881388148818881A881B881C881E881F8828882D882E8830883288350000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+5C
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000883A883C88418843884588488849884A884B884E8851885588568858885A
+885C885F88608864886988718879887B88808898889A889B889C889F88A088A8
+88AA88BA88BD88BE88C088CA88CB88CC88CD88CE88D188D288D388DB88DE88E7
+88EF88F088F188F588F789018906890D890E890F8915891689188919891A891C
+892089268927892889308931893289358939893A893E89408942894589468949
+894F89528957895A895B895C896189628963896B896E897089738975897A0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+5D
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000897B897C897D8989898D899089948995899B899C899F89A089A589B089B4
+89B589B689B789BC89D489D589D689D789D889E589E989EB89ED89F189F389F6
+89F989FD89FF8A048A058A078A0F8A118A128A148A158A1E8A208A228A248A26
+8A2B8A2C8A2F8A358A378A3D8A3E8A408A438A458A478A498A4D8A4E8A538A56
+8A578A588A5C8A5D8A618A658A678A758A768A778A798A7A8A7B8A7E8A7F8A80
+8A838A868A8B8A8F8A908A928A968A978A998A9F8AA78AA98AAE8AAF8AB30000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+5E
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00008AB68AB78ABB8ABE8AC38AC68AC88AC98ACA8AD18AD38AD48AD58AD78ADD
+8ADF8AEC8AF08AF48AF58AF68AFC8AFF8B058B068B0B8B118B1C8B1E8B1F8B0A
+8B2D8B308B378B3C8B428B438B448B458B468B488B528B538B548B598B4D8B5E
+8B638B6D8B768B788B798B7C8B7E8B818B848B858B8B8B8D8B8F8B948B958B9C
+8B9E8B9F8C388C398C3D8C3E8C458C478C498C4B8C4F8C518C538C548C578C58
+8C5B8C5D8C598C638C648C668C688C698C6D8C738C758C768C7B8C7E8C860000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+5F
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00008C878C8B8C908C928C938C998C9B8C9C8CA48CB98CBA8CC58CC68CC98CCB
+8CCF8CD68CD58CD98CDD8CE18CE88CEC8CEF8CF08CF28CF58CF78CF88CFE8CFF
+8D018D038D098D128D178D1B8D658D698D6C8D6E8D7F8D828D848D888D8D8D90
+8D918D958D9E8D9F8DA08DA68DAB8DAC8DAF8DB28DB58DB78DB98DBB8DC08DC5
+8DC68DC78DC88DCA8DCE8DD18DD48DD58DD78DD98DE48DE58DE78DEC8DF08DBC
+8DF18DF28DF48DFD8E018E048E058E068E0B8E118E148E168E208E218E220000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+60
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00008E238E268E278E318E338E368E378E388E398E3D8E408E418E4B8E4D8E4E
+8E4F8E548E5B8E5C8E5D8E5E8E618E628E698E6C8E6D8E6F8E708E718E798E7A
+8E7B8E828E838E898E908E928E958E9A8E9B8E9D8E9E8EA28EA78EA98EAD8EAE
+8EB38EB58EBA8EBB8EC08EC18EC38EC48EC78ECF8ED18ED48EDC8EE88EEE8EF0
+8EF18EF78EF98EFA8EED8F008F028F078F088F0F8F108F168F178F188F1E8F20
+8F218F238F258F278F288F2C8F2D8F2E8F348F358F368F378F3A8F408F410000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+61
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00008F438F478F4F8F518F528F538F548F558F588F5D8F5E8F658F9D8FA08FA1
+8FA48FA58FA68FB58FB68FB88FBE8FC08FC18FC68FCA8FCB8FCD8FD08FD28FD3
+8FD58FE08FE38FE48FE88FEE8FF18FF58FF68FFB8FFE900290049008900C9018
+901B90289029902F902A902C902D903390349037903F90439044904C905B905D
+906290669067906C90709074907990859088908B908C908E9090909590979098
+9099909B90A090A190A290A590B090B290B390B490B690BD90CC90BE90C30000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+62
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000090C490C590C790C890D590D790D890D990DC90DD90DF90E590D290F690EB
+90EF90F090F490FE90FF91009104910591069108910D91109114911691179118
+911A911C911E912091259122912391279129912E912F91319134913691379139
+913A913C913D914391479148914F915391579159915A915B916191649167916D
+91749179917A917B9181918391859186918A918E91919193919491959198919E
+91A191A691A891AC91AD91AE91B091B191B291B391B691BB91BC91BD91BF0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+63
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000091C291C391C591D391D491D791D991DA91DE91E491E591E991EA91EC91ED
+91EE91EF91F091F191F791F991FB91FD9200920192049205920692079209920A
+920C92109212921392169218921C921D92239224922592269228922E922F9230
+92339235923692389239923A923C923E92409242924392469247924A924D924E
+924F925192589259925C925D926092619265926792689269926E926F92709275
+9276927792789279927B927C927D927F92889289928A928D928E929292970000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+64
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00009299929F92A092A492A592A792A892AB92AF92B292B692B892BA92BB92BC
+92BD92BF92C092C192C292C392C592C692C792C892CB92CC92CD92CE92D092D3
+92D592D792D892D992DC92DD92DF92E092E192E392E592E792E892EC92EE92F0
+92F992FB92FF930093029308930D931193149315931C931D931E931F93219324
+932593279329932A933393349336933793479348934993509351935293559357
+9358935A935E9364936593679369936A936D936F937093719373937493760000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+65
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000937A937D937F9380938193829388938A938B938D938F939293959398939B
+939E93A193A393A493A693A893AB93B493B593B693BA93A993C193C493C593C6
+93C793C993CA93CB93CC93CD93D393D993DC93DE93DF93E293E693E793F993F7
+93F893FA93FB93FD94019402940494089409940D940E940F941594169417941F
+942E942F9431943294339434943B943F943D944394459448944A944C94559459
+945C945F946194639468946B946D946E946F9471947294849483957895790000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+66
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000957E95849588958C958D958E959D959E959F95A195A695A995AB95AC95B4
+95B695BA95BD95BF95C695C895C995CB95D095D195D295D395D995DA95DD95DE
+95DF95E095E495E6961D961E9622962496259626962C96319633963796389639
+963A963C963D9641965296549656965796589661966E9674967B967C967E967F
+9681968296839684968996919696969A969D969F96A496A596A696A996AE96AF
+96B396BA96CA96D25DB296D896DA96DD96DE96DF96E996EF96F196FA97020000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+67
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000970397059709971A971B971D97219722972397289731973397419743974A
+974E974F975597579758975A975B97639767976A976E9773977697779778977B
+977D977F978097899795979697979799979A979E979F97A297AC97AE97B197B2
+97B597B697B897B997BA97BC97BE97BF97C197C497C597C797C997CA97CC97CD
+97CE97D097D197D497D797D897D997DD97DE97E097DB97E197E497EF97F197F4
+97F797F897FA9807980A9819980D980E98149816981C981E9820982398260000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+68
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000982B982E982F98309832983398359825983E98449847984A985198529853
+985698579859985A9862986398659866986A986C98AB98AD98AE98B098B498B7
+98B898BA98BB98BF98C298C598C898CC98E198E398E598E698E798EA98F398F6
+9902990799089911991599169917991A991B991C991F992299269927992B9931
+99329933993499359939993A993B993C99409941994699479948994D994E9954
+99589959995B995C995E995F9960999B999D999F99A699B099B199B299B50000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+69
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000099B999BA99BD99BF99C399C999D399D499D999DA99DC99DE99E799EA99EB
+99EC99F099F499F599F999FD99FE9A029A039A049A0B9A0C9A109A119A169A1E
+9A209A229A239A249A279A2D9A2E9A339A359A369A389A479A419A449A4A9A4B
+9A4C9A4E9A519A549A569A5D9AAA9AAC9AAE9AAF9AB29AB49AB59AB69AB99ABB
+9ABE9ABF9AC19AC39AC69AC89ACE9AD09AD29AD59AD69AD79ADB9ADC9AE09AE4
+9AE59AE79AE99AEC9AF29AF39AF59AF99AFA9AFD9AFF9B009B019B029B030000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+6A
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00009B049B059B089B099B0B9B0C9B0D9B0E9B109B129B169B199B1B9B1C9B20
+9B269B2B9B2D9B339B349B359B379B399B3A9B3D9B489B4B9B4C9B559B569B57
+9B5B9B5E9B619B639B659B669B689B6A9B6B9B6C9B6D9B6E9B739B759B779B78
+9B799B7F9B809B849B859B869B879B899B8A9B8B9B8D9B8F9B909B949B9A9B9D
+9B9E9BA69BA79BA99BAC9BB09BB19BB29BB79BB89BBB9BBC9BBE9BBF9BC19BC7
+9BC89BCE9BD09BD79BD89BDD9BDF9BE59BE79BEA9BEB9BEF9BF39BF79BF80000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+6B
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00009BF99BFA9BFD9BFF9C009C029C0B9C0F9C119C169C189C199C1A9C1C9C1E
+9C229C239C269C279C289C299C2A9C319C359C369C379C3D9C419C439C449C45
+9C499C4A9C4E9C4F9C509C539C549C569C589C5B9C5D9C5E9C5F9C639C699C6A
+9C5C9C6B9C689C6E9C709C729C759C779C7B9CE69CF29CF79CF99D0B9D029D11
+9D179D189D1C9D1D9D1E9D2F9D309D329D339D349D3A9D3C9D459D3D9D429D43
+9D479D4A9D539D549D5F9D639D629D659D699D6A9D6B9D709D769D779D7B0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+6C
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00009D7C9D7E9D839D849D869D8A9D8D9D8E9D929D939D959D969D979D989DA1
+9DAA9DAC9DAE9DB19DB59DB99DBC9DBF9DC39DC79DC99DCA9DD49DD59DD69DD7
+9DDA9DDE9DDF9DE09DE59DE79DE99DEB9DEE9DF09DF39DF49DFE9E0A9E029E07
+9E0E9E109E119E129E159E169E199E1C9E1D9E7A9E7B9E7C9E809E829E839E84
+9E859E879E8E9E8F9E969E989E9B9E9E9EA49EA89EAC9EAE9EAF9EB09EB39EB4
+9EB59EC69EC89ECB9ED59EDF9EE49EE79EEC9EED9EEE9EF09EF19EF29EF50000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+6D
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00009EF89EFF9F029F039F099F0F9F109F119F129F149F169F179F199F1A9F1B
+9F1F9F229F269F2A9F2B9F2F9F319F329F349F379F399F3A9F3C9F3D9F3F9F41
+9F439F449F459F469F479F539F559F569F579F589F5A9F5D9F5E9F689F699F6D
+9F6E9F6F9F709F719F739F759F7A9F7D9F8F9F909F919F929F949F969F979F9E
+9FA19FA29FA39FA5000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
diff --git a/library/encoding/koi8-r.enc b/library/encoding/koi8-r.enc
new file mode 100644
index 0000000..49bf2ea
--- /dev/null
+++ b/library/encoding/koi8-r.enc
@@ -0,0 +1,20 @@
+# Encoding file: koi8-r, single-byte
+S
+003F 0 1
+00
+0000000100020003000400050006000700080009000A000B000C000D000E000F
+0010001100120013001400150016001700180019001A001B001C001D001E001F
+0020002100220023002400250026002700280029002A002B002C002D002E002F
+0030003100320033003400350036003700380039003A003B003C003D003E003F
+0040004100420043004400450046004700480049004A004B004C004D004E004F
+0050005100520053005400550056005700580059005A005B005C005D005E005F
+0060006100620063006400650066006700680069006A006B006C006D006E006F
+0070007100720073007400750076007700780079007A007B007C007D007E007F
+25002502250C251025142518251C2524252C2534253C258025842588258C2590
+259125922593232025A02219221A22482264226500A0232100B000B200B700F7
+25502551255204512553255425552556255725582559255A255B255C255D255E
+255F25602561040125622563256425652566256725682569256A256B256C00A9
+044E0430043104460434043504440433044504380439043A043B043C043D043E
+043F044F044004410442044304360432044C044B04370448044D04490447044A
+042E0410041104260414041504240413042504180419041A041B041C041D041E
+041F042F042004210422042304160412042C042B04170428042D04290427042A
diff --git a/library/encoding/koi8-u.enc b/library/encoding/koi8-u.enc
new file mode 100644
index 0000000..e4eeb84
--- /dev/null
+++ b/library/encoding/koi8-u.enc
@@ -0,0 +1,20 @@
+# Encoding file: koi8-u, single-byte
+S
+003F 0 1
+00
+0000000100020003000400050006000700080009000A000B000C000D000E000F
+0010001100120013001400150016001700180019001A001B001C001D001E001F
+0020002100220023002400250026002700280029002A002B002C002D002E002F
+0030003100320033003400350036003700380039003A003B003C003D003E003F
+0040004100420043004400450046004700480049004A004B004C004D004E004F
+0050005100520053005400550056005700580059005A005B005C005D005E005F
+0060006100620063006400650066006700680069006A006B006C006D006E006F
+0070007100720073007400750076007700780079007A007B007C007D007E007F
+25002502250C251025142518251C2524252C2534253C258025842588258C2590
+259125922593232025A02219221A22482264226500A0232100B000B200B700F7
+25502551255204510454255404560457255725582559255A255B0491255D255E
+255F25602561040104032563040604072566256725682569256A0490256C00A9
+044E0430043104460434043504440433044504380439043A043B043C043D043E
+043F044F044004410442044304360432044C044B04370448044D04490447044A
+042E0410041104260414041504240413042504180419041A041B041C041D041E
+041F042F042004210422042304160412042C042B04170428042D04290427042A
diff --git a/library/encoding/ksc5601.enc b/library/encoding/ksc5601.enc
new file mode 100644
index 0000000..bec61d0
--- /dev/null
+++ b/library/encoding/ksc5601.enc
@@ -0,0 +1,1516 @@
+# Encoding file: ksc5601, double-byte
+D
+233F 0 89
+21
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000030003001300200B72025202600A8300300AD20152225FF3C223C20182019
+201C201D3014301530083009300A300B300C300D300E300F3010301100B100D7
+00F7226022642265221E223400B0203220332103212BFFE0FFE1FFE526422640
+222022A52312220222072261225200A7203B2606260525CB25CF25CE25C725C6
+25A125A025B325B225BD25BC219221902191219321943013226A226B221A223D
+221D2235222B222C2208220B2286228722822283222A222922272228FFE20000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+22
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000021D221D42200220300B4FF5E02C702D802DD02DA02D900B802DB00A100BF
+02D0222E2211220F00A42109203025C125C025B725B626642660266126652667
+2663229925C825A325D025D1259225A425A525A825A725A625A92668260F260E
+261C261E00B62020202121952197219921962198266D2669266A266C327F321C
+211633C7212233C233D821210000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+23
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000FF01FF02FF03FF04FF05FF06FF07FF08FF09FF0AFF0BFF0CFF0DFF0EFF0F
+FF10FF11FF12FF13FF14FF15FF16FF17FF18FF19FF1AFF1BFF1CFF1DFF1EFF1F
+FF20FF21FF22FF23FF24FF25FF26FF27FF28FF29FF2AFF2BFF2CFF2DFF2EFF2F
+FF30FF31FF32FF33FF34FF35FF36FF37FF38FF39FF3AFF3BFFE6FF3DFF3EFF3F
+FF40FF41FF42FF43FF44FF45FF46FF47FF48FF49FF4AFF4BFF4CFF4DFF4EFF4F
+FF50FF51FF52FF53FF54FF55FF56FF57FF58FF59FF5AFF5BFF5CFF5DFFE30000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+24
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000313131323133313431353136313731383139313A313B313C313D313E313F
+3140314131423143314431453146314731483149314A314B314C314D314E314F
+3150315131523153315431553156315731583159315A315B315C315D315E315F
+3160316131623163316431653166316731683169316A316B316C316D316E316F
+3170317131723173317431753176317731783179317A317B317C317D317E317F
+3180318131823183318431853186318731883189318A318B318C318D318E0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+25
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000217021712172217321742175217621772178217900000000000000000000
+2160216121622163216421652166216721682169000000000000000000000000
+0000039103920393039403950396039703980399039A039B039C039D039E039F
+03A003A103A303A403A503A603A703A803A90000000000000000000000000000
+000003B103B203B303B403B503B603B703B803B903BA03BB03BC03BD03BE03BF
+03C003C103C303C403C503C603C703C803C90000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+26
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000025002502250C251025182514251C252C25242534253C25012503250F2513
+251B251725232533252B253B254B2520252F25282537253F251D253025252538
+254225122511251A251925162515250E250D251E251F25212522252625272529
+252A252D252E25312532253525362539253A253D253E25402541254325442545
+2546254725482549254A00000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+27
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00003395339633972113339833C433A333A433A533A63399339A339B339C339D
+339E339F33A033A133A233CA338D338E338F33CF3388338933C833A733A833B0
+33B133B233B333B433B533B633B733B833B93380338133823383338433BA33BB
+33BC33BD33BE33BF33903391339233933394212633C033C1338A338B338C33D6
+33C533AD33AE33AF33DB33A933AA33AB33AC33DD33D033D333C333C933DC33C6
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+28
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000000C600D000AA0126000001320000013F014100D8015200BA00DE0166014A
+00003260326132623263326432653266326732683269326A326B326C326D326E
+326F3270327132723273327432753276327732783279327A327B24D024D124D2
+24D324D424D524D624D724D824D924DA24DB24DC24DD24DE24DF24E024E124E2
+24E324E424E524E624E724E824E9246024612462246324642465246624672468
+2469246A246B246C246D246E00BD2153215400BC00BE215B215C215D215E0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+29
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000000E6011100F001270131013301380140014200F8015300DF00FE0167014B
+01493200320132023203320432053206320732083209320A320B320C320D320E
+320F3210321132123213321432153216321732183219321A321B249C249D249E
+249F24A024A124A224A324A424A524A624A724A824A924AA24AB24AC24AD24AE
+24AF24B024B124B224B324B424B5247424752476247724782479247A247B247C
+247D247E247F24802481248200B900B200B32074207F20812082208320840000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+2A
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000304130423043304430453046304730483049304A304B304C304D304E304F
+3050305130523053305430553056305730583059305A305B305C305D305E305F
+3060306130623063306430653066306730683069306A306B306C306D306E306F
+3070307130723073307430753076307730783079307A307B307C307D307E307F
+3080308130823083308430853086308730883089308A308B308C308D308E308F
+3090309130923093000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+2B
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000030A130A230A330A430A530A630A730A830A930AA30AB30AC30AD30AE30AF
+30B030B130B230B330B430B530B630B730B830B930BA30BB30BC30BD30BE30BF
+30C030C130C230C330C430C530C630C730C830C930CA30CB30CC30CD30CE30CF
+30D030D130D230D330D430D530D630D730D830D930DA30DB30DC30DD30DE30DF
+30E030E130E230E330E430E530E630E730E830E930EA30EB30EC30ED30EE30EF
+30F030F130F230F330F430F530F6000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+2C
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000004100411041204130414041504010416041704180419041A041B041C041D
+041E041F0420042104220423042404250426042704280429042A042B042C042D
+042E042F00000000000000000000000000000000000000000000000000000000
+000004300431043204330434043504510436043704380439043A043B043C043D
+043E043F0440044104420443044404450446044704480449044A044B044C044D
+044E044F00000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+30
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000AC00AC01AC04AC07AC08AC09AC0AAC10AC11AC12AC13AC14AC15AC16AC17
+AC19AC1AAC1BAC1CAC1DAC20AC24AC2CAC2DAC2FAC30AC31AC38AC39AC3CAC40
+AC4BAC4DAC54AC58AC5CAC70AC71AC74AC77AC78AC7AAC80AC81AC83AC84AC85
+AC86AC89AC8AAC8BAC8CAC90AC94AC9CAC9DAC9FACA0ACA1ACA8ACA9ACAAACAC
+ACAFACB0ACB8ACB9ACBBACBCACBDACC1ACC4ACC8ACCCACD5ACD7ACE0ACE1ACE4
+ACE7ACE8ACEAACECACEFACF0ACF1ACF3ACF5ACF6ACFCACFDAD00AD04AD060000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+31
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000AD0CAD0DAD0FAD11AD18AD1CAD20AD29AD2CAD2DAD34AD35AD38AD3CAD44
+AD45AD47AD49AD50AD54AD58AD61AD63AD6CAD6DAD70AD73AD74AD75AD76AD7B
+AD7CAD7DAD7FAD81AD82AD88AD89AD8CAD90AD9CAD9DADA4ADB7ADC0ADC1ADC4
+ADC8ADD0ADD1ADD3ADDCADE0ADE4ADF8ADF9ADFCADFFAE00AE01AE08AE09AE0B
+AE0DAE14AE30AE31AE34AE37AE38AE3AAE40AE41AE43AE45AE46AE4AAE4CAE4D
+AE4EAE50AE54AE56AE5CAE5DAE5FAE60AE61AE65AE68AE69AE6CAE70AE780000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+32
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000AE79AE7BAE7CAE7DAE84AE85AE8CAEBCAEBDAEBEAEC0AEC4AECCAECDAECF
+AED0AED1AED8AED9AEDCAEE8AEEBAEEDAEF4AEF8AEFCAF07AF08AF0DAF10AF2C
+AF2DAF30AF32AF34AF3CAF3DAF3FAF41AF42AF43AF48AF49AF50AF5CAF5DAF64
+AF65AF79AF80AF84AF88AF90AF91AF95AF9CAFB8AFB9AFBCAFC0AFC7AFC8AFC9
+AFCBAFCDAFCEAFD4AFDCAFE8AFE9AFF0AFF1AFF4AFF8B000B001B004B00CB010
+B014B01CB01DB028B044B045B048B04AB04CB04EB053B054B055B057B0590000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+33
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000B05DB07CB07DB080B084B08CB08DB08FB091B098B099B09AB09CB09FB0A0
+B0A1B0A2B0A8B0A9B0ABB0ACB0ADB0AEB0AFB0B1B0B3B0B4B0B5B0B8B0BCB0C4
+B0C5B0C7B0C8B0C9B0D0B0D1B0D4B0D8B0E0B0E5B108B109B10BB10CB110B112
+B113B118B119B11BB11CB11DB123B124B125B128B12CB134B135B137B138B139
+B140B141B144B148B150B151B154B155B158B15CB160B178B179B17CB180B182
+B188B189B18BB18DB192B193B194B198B19CB1A8B1CCB1D0B1D4B1DCB1DD0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+34
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000B1DFB1E8B1E9B1ECB1F0B1F9B1FBB1FDB204B205B208B20BB20CB214B215
+B217B219B220B234B23CB258B25CB260B268B269B274B275B27CB284B285B289
+B290B291B294B298B299B29AB2A0B2A1B2A3B2A5B2A6B2AAB2ACB2B0B2B4B2C8
+B2C9B2CCB2D0B2D2B2D8B2D9B2DBB2DDB2E2B2E4B2E5B2E6B2E8B2EBB2ECB2ED
+B2EEB2EFB2F3B2F4B2F5B2F7B2F8B2F9B2FAB2FBB2FFB300B301B304B308B310
+B311B313B314B315B31CB354B355B356B358B35BB35CB35EB35FB364B3650000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+35
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000B367B369B36BB36EB370B371B374B378B380B381B383B384B385B38CB390
+B394B3A0B3A1B3A8B3ACB3C4B3C5B3C8B3CBB3CCB3CEB3D0B3D4B3D5B3D7B3D9
+B3DBB3DDB3E0B3E4B3E8B3FCB410B418B41CB420B428B429B42BB434B450B451
+B454B458B460B461B463B465B46CB480B488B49DB4A4B4A8B4ACB4B5B4B7B4B9
+B4C0B4C4B4C8B4D0B4D5B4DCB4DDB4E0B4E3B4E4B4E6B4ECB4EDB4EFB4F1B4F8
+B514B515B518B51BB51CB524B525B527B528B529B52AB530B531B534B5380000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+36
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000B540B541B543B544B545B54BB54CB54DB550B554B55CB55DB55FB560B561
+B5A0B5A1B5A4B5A8B5AAB5ABB5B0B5B1B5B3B5B4B5B5B5BBB5BCB5BDB5C0B5C4
+B5CCB5CDB5CFB5D0B5D1B5D8B5ECB610B611B614B618B625B62CB634B648B664
+B668B69CB69DB6A0B6A4B6ABB6ACB6B1B6D4B6F0B6F4B6F8B700B701B705B728
+B729B72CB72FB730B738B739B73BB744B748B74CB754B755B760B764B768B770
+B771B773B775B77CB77DB780B784B78CB78DB78FB790B791B792B796B7970000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+37
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000B798B799B79CB7A0B7A8B7A9B7ABB7ACB7ADB7B4B7B5B7B8B7C7B7C9B7EC
+B7EDB7F0B7F4B7FCB7FDB7FFB800B801B807B808B809B80CB810B818B819B81B
+B81DB824B825B828B82CB834B835B837B838B839B840B844B851B853B85CB85D
+B860B864B86CB86DB86FB871B878B87CB88DB8A8B8B0B8B4B8B8B8C0B8C1B8C3
+B8C5B8CCB8D0B8D4B8DDB8DFB8E1B8E8B8E9B8ECB8F0B8F8B8F9B8FBB8FDB904
+B918B920B93CB93DB940B944B94CB94FB951B958B959B95CB960B968B9690000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+38
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000B96BB96DB974B975B978B97CB984B985B987B989B98AB98DB98EB9ACB9AD
+B9B0B9B4B9BCB9BDB9BFB9C1B9C8B9C9B9CCB9CEB9CFB9D0B9D1B9D2B9D8B9D9
+B9DBB9DDB9DEB9E1B9E3B9E4B9E5B9E8B9ECB9F4B9F5B9F7B9F8B9F9B9FABA00
+BA01BA08BA15BA38BA39BA3CBA40BA42BA48BA49BA4BBA4DBA4EBA53BA54BA55
+BA58BA5CBA64BA65BA67BA68BA69BA70BA71BA74BA78BA83BA84BA85BA87BA8C
+BAA8BAA9BAABBAACBAB0BAB2BAB8BAB9BABBBABDBAC4BAC8BAD8BAD9BAFC0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+39
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000BB00BB04BB0DBB0FBB11BB18BB1CBB20BB29BB2BBB34BB35BB36BB38BB3B
+BB3CBB3DBB3EBB44BB45BB47BB49BB4DBB4FBB50BB54BB58BB61BB63BB6CBB88
+BB8CBB90BBA4BBA8BBACBBB4BBB7BBC0BBC4BBC8BBD0BBD3BBF8BBF9BBFCBBFF
+BC00BC02BC08BC09BC0BBC0CBC0DBC0FBC11BC14BC15BC16BC17BC18BC1BBC1C
+BC1DBC1EBC1FBC24BC25BC27BC29BC2DBC30BC31BC34BC38BC40BC41BC43BC44
+BC45BC49BC4CBC4DBC50BC5DBC84BC85BC88BC8BBC8CBC8EBC94BC95BC970000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+3A
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000BC99BC9ABCA0BCA1BCA4BCA7BCA8BCB0BCB1BCB3BCB4BCB5BCBCBCBDBCC0
+BCC4BCCDBCCFBCD0BCD1BCD5BCD8BCDCBCF4BCF5BCF6BCF8BCFCBD04BD05BD07
+BD09BD10BD14BD24BD2CBD40BD48BD49BD4CBD50BD58BD59BD64BD68BD80BD81
+BD84BD87BD88BD89BD8ABD90BD91BD93BD95BD99BD9ABD9CBDA4BDB0BDB8BDD4
+BDD5BDD8BDDCBDE9BDF0BDF4BDF8BE00BE03BE05BE0CBE0DBE10BE14BE1CBE1D
+BE1FBE44BE45BE48BE4CBE4EBE54BE55BE57BE59BE5ABE5BBE60BE61BE640000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+3B
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000BE68BE6ABE70BE71BE73BE74BE75BE7BBE7CBE7DBE80BE84BE8CBE8DBE8F
+BE90BE91BE98BE99BEA8BED0BED1BED4BED7BED8BEE0BEE3BEE4BEE5BEECBF01
+BF08BF09BF18BF19BF1BBF1CBF1DBF40BF41BF44BF48BF50BF51BF55BF94BFB0
+BFC5BFCCBFCDBFD0BFD4BFDCBFDFBFE1C03CC051C058C05CC060C068C069C090
+C091C094C098C0A0C0A1C0A3C0A5C0ACC0ADC0AFC0B0C0B3C0B4C0B5C0B6C0BC
+C0BDC0BFC0C0C0C1C0C5C0C8C0C9C0CCC0D0C0D8C0D9C0DBC0DCC0DDC0E40000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+3C
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000C0E5C0E8C0ECC0F4C0F5C0F7C0F9C100C104C108C110C115C11CC11DC11E
+C11FC120C123C124C126C127C12CC12DC12FC130C131C136C138C139C13CC140
+C148C149C14BC14CC14DC154C155C158C15CC164C165C167C168C169C170C174
+C178C185C18CC18DC18EC190C194C196C19CC19DC19FC1A1C1A5C1A8C1A9C1AC
+C1B0C1BDC1C4C1C8C1CCC1D4C1D7C1D8C1E0C1E4C1E8C1F0C1F1C1F3C1FCC1FD
+C200C204C20CC20DC20FC211C218C219C21CC21FC220C228C229C22BC22D0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+3D
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000C22FC231C232C234C248C250C251C254C258C260C265C26CC26DC270C274
+C27CC27DC27FC281C288C289C290C298C29BC29DC2A4C2A5C2A8C2ACC2ADC2B4
+C2B5C2B7C2B9C2DCC2DDC2E0C2E3C2E4C2EBC2ECC2EDC2EFC2F1C2F6C2F8C2F9
+C2FBC2FCC300C308C309C30CC30DC313C314C315C318C31CC324C325C328C329
+C345C368C369C36CC370C372C378C379C37CC37DC384C388C38CC3C0C3D8C3D9
+C3DCC3DFC3E0C3E2C3E8C3E9C3EDC3F4C3F5C3F8C408C410C424C42CC4300000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+3E
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000C434C43CC43DC448C464C465C468C46CC474C475C479C480C494C49CC4B8
+C4BCC4E9C4F0C4F1C4F4C4F8C4FAC4FFC500C501C50CC510C514C51CC528C529
+C52CC530C538C539C53BC53DC544C545C548C549C54AC54CC54DC54EC553C554
+C555C557C558C559C55DC55EC560C561C564C568C570C571C573C574C575C57C
+C57DC580C584C587C58CC58DC58FC591C595C597C598C59CC5A0C5A9C5B4C5B5
+C5B8C5B9C5BBC5BCC5BDC5BEC5C4C5C5C5C6C5C7C5C8C5C9C5CAC5CCC5CE0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+3F
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000C5D0C5D1C5D4C5D8C5E0C5E1C5E3C5E5C5ECC5EDC5EEC5F0C5F4C5F6C5F7
+C5FCC5FDC5FEC5FFC600C601C605C606C607C608C60CC610C618C619C61BC61C
+C624C625C628C62CC62DC62EC630C633C634C635C637C639C63BC640C641C644
+C648C650C651C653C654C655C65CC65DC660C66CC66FC671C678C679C67CC680
+C688C689C68BC68DC694C695C698C69CC6A4C6A5C6A7C6A9C6B0C6B1C6B4C6B8
+C6B9C6BAC6C0C6C1C6C3C6C5C6CCC6CDC6D0C6D4C6DCC6DDC6E0C6E1C6E80000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+40
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000C6E9C6ECC6F0C6F8C6F9C6FDC704C705C708C70CC714C715C717C719C720
+C721C724C728C730C731C733C735C737C73CC73DC740C744C74AC74CC74DC74F
+C751C752C753C754C755C756C757C758C75CC760C768C76BC774C775C778C77C
+C77DC77EC783C784C785C787C788C789C78AC78EC790C791C794C796C797C798
+C79AC7A0C7A1C7A3C7A4C7A5C7A6C7ACC7ADC7B0C7B4C7BCC7BDC7BFC7C0C7C1
+C7C8C7C9C7CCC7CEC7D0C7D8C7DDC7E4C7E8C7ECC800C801C804C808C80A0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+41
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000C810C811C813C815C816C81CC81DC820C824C82CC82DC82FC831C838C83C
+C840C848C849C84CC84DC854C870C871C874C878C87AC880C881C883C885C886
+C887C88BC88CC88DC894C89DC89FC8A1C8A8C8BCC8BDC8C4C8C8C8CCC8D4C8D5
+C8D7C8D9C8E0C8E1C8E4C8F5C8FCC8FDC900C904C905C906C90CC90DC90FC911
+C918C92CC934C950C951C954C958C960C961C963C96CC970C974C97CC988C989
+C98CC990C998C999C99BC99DC9C0C9C1C9C4C9C7C9C8C9CAC9D0C9D1C9D30000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+42
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000C9D5C9D6C9D9C9DAC9DCC9DDC9E0C9E2C9E4C9E7C9ECC9EDC9EFC9F0C9F1
+C9F8C9F9C9FCCA00CA08CA09CA0BCA0CCA0DCA14CA18CA29CA4CCA4DCA50CA54
+CA5CCA5DCA5FCA60CA61CA68CA7DCA84CA98CABCCABDCAC0CAC4CACCCACDCACF
+CAD1CAD3CAD8CAD9CAE0CAECCAF4CB08CB10CB14CB18CB20CB21CB41CB48CB49
+CB4CCB50CB58CB59CB5DCB64CB78CB79CB9CCBB8CBD4CBE4CBE7CBE9CC0CCC0D
+CC10CC14CC1CCC1DCC21CC22CC27CC28CC29CC2CCC2ECC30CC38CC39CC3B0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+43
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000CC3CCC3DCC3ECC44CC45CC48CC4CCC54CC55CC57CC58CC59CC60CC64CC66
+CC68CC70CC75CC98CC99CC9CCCA0CCA8CCA9CCABCCACCCADCCB4CCB5CCB8CCBC
+CCC4CCC5CCC7CCC9CCD0CCD4CCE4CCECCCF0CD01CD08CD09CD0CCD10CD18CD19
+CD1BCD1DCD24CD28CD2CCD39CD5CCD60CD64CD6CCD6DCD6FCD71CD78CD88CD94
+CD95CD98CD9CCDA4CDA5CDA7CDA9CDB0CDC4CDCCCDD0CDE8CDECCDF0CDF8CDF9
+CDFBCDFDCE04CE08CE0CCE14CE19CE20CE21CE24CE28CE30CE31CE33CE350000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+44
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000CE58CE59CE5CCE5FCE60CE61CE68CE69CE6BCE6DCE74CE75CE78CE7CCE84
+CE85CE87CE89CE90CE91CE94CE98CEA0CEA1CEA3CEA4CEA5CEACCEADCEC1CEE4
+CEE5CEE8CEEBCEECCEF4CEF5CEF7CEF8CEF9CF00CF01CF04CF08CF10CF11CF13
+CF15CF1CCF20CF24CF2CCF2DCF2FCF30CF31CF38CF54CF55CF58CF5CCF64CF65
+CF67CF69CF70CF71CF74CF78CF80CF85CF8CCFA1CFA8CFB0CFC4CFE0CFE1CFE4
+CFE8CFF0CFF1CFF3CFF5CFFCD000D004D011D018D02DD034D035D038D03C0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+45
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000D044D045D047D049D050D054D058D060D06CD06DD070D074D07CD07DD081
+D0A4D0A5D0A8D0ACD0B4D0B5D0B7D0B9D0C0D0C1D0C4D0C8D0C9D0D0D0D1D0D3
+D0D4D0D5D0DCD0DDD0E0D0E4D0ECD0EDD0EFD0F0D0F1D0F8D10DD130D131D134
+D138D13AD140D141D143D144D145D14CD14DD150D154D15CD15DD15FD161D168
+D16CD17CD184D188D1A0D1A1D1A4D1A8D1B0D1B1D1B3D1B5D1BAD1BCD1C0D1D8
+D1F4D1F8D207D209D210D22CD22DD230D234D23CD23DD23FD241D248D25C0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+46
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000D264D280D281D284D288D290D291D295D29CD2A0D2A4D2ACD2B1D2B8D2B9
+D2BCD2BFD2C0D2C2D2C8D2C9D2CBD2D4D2D8D2DCD2E4D2E5D2F0D2F1D2F4D2F8
+D300D301D303D305D30CD30DD30ED310D314D316D31CD31DD31FD320D321D325
+D328D329D32CD330D338D339D33BD33CD33DD344D345D37CD37DD380D384D38C
+D38DD38FD390D391D398D399D39CD3A0D3A8D3A9D3ABD3ADD3B4D3B8D3BCD3C4
+D3C5D3C8D3C9D3D0D3D8D3E1D3E3D3ECD3EDD3F0D3F4D3FCD3FDD3FFD4010000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+47
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000D408D41DD440D444D45CD460D464D46DD46FD478D479D47CD47FD480D482
+D488D489D48BD48DD494D4A9D4CCD4D0D4D4D4DCD4DFD4E8D4ECD4F0D4F8D4FB
+D4FDD504D508D50CD514D515D517D53CD53DD540D544D54CD54DD54FD551D558
+D559D55CD560D565D568D569D56BD56DD574D575D578D57CD584D585D587D588
+D589D590D5A5D5C8D5C9D5CCD5D0D5D2D5D8D5D9D5DBD5DDD5E4D5E5D5E8D5EC
+D5F4D5F5D5F7D5F9D600D601D604D608D610D611D613D614D615D61CD6200000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+48
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000D624D62DD638D639D63CD640D645D648D649D64BD64DD651D654D655D658
+D65CD667D669D670D671D674D683D685D68CD68DD690D694D69DD69FD6A1D6A8
+D6ACD6B0D6B9D6BBD6C4D6C5D6C8D6CCD6D1D6D4D6D7D6D9D6E0D6E4D6E8D6F0
+D6F5D6FCD6FDD700D704D711D718D719D71CD720D728D729D72BD72DD734D735
+D738D73CD744D747D749D750D751D754D756D757D758D759D760D761D763D765
+D769D76CD770D774D77CD77DD781D788D789D78CD790D798D799D79BD79D0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+4A
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00004F3D4F73504750F952A053EF547554E556095AC15BB6668767B667B767EF
+6B4C73C275C27A3C82DB8304885788888A368CC88DCF8EFB8FE699D5523B5374
+5404606A61646BBC73CF811A89BA89D295A34F83520A58BE597859E65E725E79
+61C763C0674667EC687F6F97764E770B78F57A087AFF7C21809D826E82718AEB
+95934E6B559D66F76E3478A37AED845B8910874E97A852D8574E582A5D4C611F
+61BE6221656267D16A446E1B751875B376E377B07D3A90AF945194529F950000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+4B
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000053235CAC753280DB92409598525B580859DC5CA15D175EB75F3A5F4A6177
+6C5F757A75867CE07D737DB17F8C81548221859189418B1B92FC964D9C474ECB
+4EF7500B51F1584F6137613E6168653969EA6F1175A5768676D67B8782A584CB
+F90093A7958B55805BA25751F9017CB37FB991B5502853BB5C455DE862D2636E
+64DA64E76E2070AC795B8DDD8E1EF902907D924592F84E7E4EF650655DFE5EFA
+61066957817186548E4793759A2B4E5E5091677068405109528D52926AA20000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+4C
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000077BC92109ED452AB602F8FF2504861A963ED64CA683C6A846FC0818889A1
+96945805727D72AC75047D797E6D80A9898B8B7490639D5162896C7A6F547D50
+7F3A8A23517C614A7B9D8B199257938C4EAC4FD3501E50BE510652C152CD537F
+577058835E9A5F91617661AC64CE656C666F66BB66F468976D87708570F1749F
+74A574CA75D9786C78EC7ADF7AF67D457D938015803F811B83968B668F159015
+93E1980398389A5A9BE84FC25553583A59515B635C4660B86212684268B00000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+4D
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000068E86EAA754C767878CE7A3D7CFB7E6B7E7C8A088AA18C3F968E9DC453E4
+53E9544A547156FA59D15B645C3B5EAB62F765376545657266A067AF69C16CBD
+75FC7690777E7A3F7F94800380A1818F82E682FD83F085C1883188B48AA5F903
+8F9C932E96C798679AD89F1354ED659B66F2688F7A408C379D6056F057645D11
+660668B168CD6EFE7428889E9BE46C68F9049AA84F9B516C5171529F5B545DE5
+6050606D62F163A7653B73D97A7A86A38CA2978F4E325BE16208679C74DC0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+4E
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000079D183D38A878AB28DE8904E934B98465ED369E885FF90EDF90551A05B98
+5BEC616368FA6B3E704C742F74D87BA17F5083C589C08CAB95DC9928522E605D
+62EC90024F8A5149532158D95EE366E06D38709A72C273D67B5080F1945B5366
+639B7F6B4E565080584A58DE602A612762D069D09B415B8F7D1880B18F5F4EA4
+50D154AC55AC5B0C5DA05DE7652A654E68216A4B72E1768E77EF7D5E7FF981A0
+854E86DF8F038F4E90CA99039A559BAB4E184E454E5D4EC74FF1517752FE0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+4F
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000534053E353E5548E5614577557A25BC75D875ED061FC62D8655167B867E9
+69CB6B506BC66BEC6C426E9D707872D77396740377BF77E97A767D7F800981FC
+8205820A82DF88628B338CFC8EC0901190B1926492B699D29A459CE99DD79F9C
+570B5C4083CA97A097AB9EB4541B7A987FA488D98ECD90E158005C4863987A9F
+5BAE5F137A797AAE828E8EAC5026523852F85377570862F363726B0A6DC37737
+53A5735785688E7695D5673A6AC36F708A6D8ECC994BF90666776B788CB40000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+50
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00009B3CF90753EB572D594E63C669FB73EA78457ABA7AC57CFE8475898F8D73
+903595A852FB574775477B6083CC921EF9086A58514B524B5287621F68D86975
+969950C552A452E461C365A4683969FF747E7B4B82B983EB89B28B398FD19949
+F9094ECA599764D266116A8E7434798179BD82A9887E887F895FF90A93264F0B
+53CA602562716C727D1A7D664E98516277DC80AF4F014F0E5176518055DC5668
+573B57FA57FC5914594759935BC45C905D0E5DF15E7E5FCC628065D765E30000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+51
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000671E671F675E68CB68C46A5F6B3A6C236C7D6C826DC773987426742A7482
+74A37578757F788178EF794179477948797A7B957D007DBA7F888006802D808C
+8A188B4F8C488D779321932498E299519A0E9A0F9A659E927DCA4F76540962EE
+685491D155AB513AF90BF90C5A1C61E6F90D62CF62FFF90EF90FF910F911F912
+F91390A3F914F915F916F917F9188AFEF919F91AF91BF91C6696F91D7156F91E
+F91F96E3F920634F637A5357F921678F69606E73F9227537F923F924F9250000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+52
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00007D0DF926F927887256CA5A18F928F929F92AF92BF92C4E43F92D51675948
+67F08010F92E59735E74649A79CA5FF5606C62C8637B5BE75BD752AAF92F5974
+5F296012F930F931F9327459F933F934F935F936F937F93899D1F939F93AF93B
+F93CF93DF93EF93FF940F941F942F9436FC3F944F94581BF8FB260F1F946F947
+8166F948F9495C3FF94AF94BF94CF94DF94EF94FF950F9515AE98A25677B7D10
+F952F953F954F955F956F95780FDF958F9595C3C6CE5533F6EBA591A83360000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+53
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00004E394EB64F4655AE571858C75F5665B765E66A806BB56E4D77ED7AEF7C1E
+7DDE86CB88929132935B64BB6FBE737A75B890545556574D61BA64D466C76DE1
+6E5B6F6D6FB975F0804381BD854189838AC78B5A931F6C9375537B548E0F905D
+5510580258585E626207649E68E075767CD687B39EE84EE35788576E59275C0D
+5CB15E365F85623464E173B381FA888B8CB8968A9EDB5B855FB760B350125200
+52305716583558575C0E5C605CF65D8B5EA65F9260BC63116389641768430000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+54
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000068F96AC26DD86E216ED46FE471FE76DC777979B17A3B840489A98CED8DF3
+8E4890039014905390FD934D967697DC6BD27006725872A27368776379BF7BE4
+7E9B8B8058A960C7656665FD66BE6C8C711E71C98C5A98134E6D7A814EDD51AC
+51CD52D5540C61A76771685068DF6D1E6F7C75BC77B37AE580F484639285515C
+6597675C679375D87AC78373F95A8C469017982D5C6F81C0829A9041906F920D
+5F975D9D6A5971C8767B7B4985E48B0491279A30558761F6F95B76697F850000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+55
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000863F87BA88F8908FF95C6D1B70D973DE7D61843DF95D916A99F1F95E4E82
+53756B046B12703E721B862D9E1E524C8FA35D5064E5652C6B166FEB7C437E9C
+85CD896489BD62C981D8881F5ECA67176D6A72FC7405746F878290DE4F865D0D
+5FA0840A51B763A075654EAE5006516951C968816A117CAE7CB17CE7826F8AD2
+8F1B91CF4FB6513752F554425EEC616E623E65C56ADA6FFE792A85DC882395AD
+9A629A6A9E979ECE529B66C66B77701D792B8F6297426190620065236F230000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+56
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000714974897DF4806F84EE8F269023934A51BD521752A36D0C70C888C25EC9
+65826BAE6FC27C3E73754EE44F3656F9F95F5CBA5DBA601C73B27B2D7F9A7FCE
+8046901E923496F6974898189F614F8B6FA779AE91B496B752DEF960648864C4
+6AD36F5E7018721076E780018606865C8DEF8F0597329B6F9DFA9E75788C797F
+7DA083C993049E7F9E938AD658DF5F046727702774CF7C60807E512170287262
+78CA8CC28CDA8CF496F74E8650DA5BEE5ED6659971CE764277AD804A84FC0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+57
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000907C9B279F8D58D85A415C626A136DDA6F0F763B7D2F7E37851E893893E4
+964B528965D267F369B46D416E9C700F7409746075597624786B8B2C985E516D
+622E96784F96502B5D196DEA7DB88F2A5F8B61446817F961968652D2808B51DC
+51CC695E7A1C7DBE83F196754FDA52295398540F550E5C6560A7674E68A86D6C
+728172F874067483F96275E27C6C7F797FB8838988CF88E191CC91D096E29BC9
+541D6F7E71D0749885FA8EAA96A39C579E9F67976DCB743381E89716782C0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+58
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00007ACB7B207C926469746A75F278BC78E899AC9B549EBB5BDE5E556F20819C
+83AB90884E07534D5A295DD25F4E6162633D666966FC6EFF6F2B7063779E842C
+8513883B8F1399459C3B551C62B9672B6CAB8309896A977A4EA159845FD85FD9
+671B7DB27F548292832B83BD8F1E909957CB59B95A925BD06627679A68856BCF
+71647F758CB78CE390819B4581088C8A964C9A409EA55B5F6C13731B76F276DF
+840C51AA8993514D519552C968C96C94770477207DBF7DEC97629EB56EC50000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+59
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000851151A5540D547D660E669D69276E9F76BF7791831784C2879F91699298
+9CF488824FAE519252DF59C65E3D61556478647966AE67D06A216BCD6BDB725F
+72617441773877DB801782BC83058B008B288C8C67286C90726776EE77667A46
+9DA96B7F6C92592267268499536F589359995EDF63CF663467736E3A732B7AD7
+82D7932852D95DEB61AE61CB620A62C764AB65E069596B666BCB712173F7755D
+7E46821E8302856A8AA38CBF97279D6158A89ED85011520E543B554F65870000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+5A
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00006C767D0A7D0B805E868A958096EF52FF6C95726954735A9A5C3E5D4B5F4C
+5FAE672A68B669636E3C6E4477097C737F8E85878B0E8FF797619EF45CB760B6
+610D61AB654F65FB65FC6C116CEF739F73C97DE195945BC6871C8B10525D535A
+62CD640F64B267346A386CCA73C0749E7B947C957E1B818A823685848FEB96F9
+99C14F34534A53CD53DB62CC642C6500659169C36CEE6F5873ED7554762276E4
+76FC78D078FB792C7D46822C87E08FD4981298EF52C362D464A56E246F510000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+5B
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000767C8DCB91B192629AEE9B435023508D574A59A85C285E475F77623F653E
+65B965C16609678B699C6EC278C57D2180AA8180822B82B384A1868C8A2A8B17
+90A696329F90500D4FF3F96357F95F9862DC6392676F6E43711976C380CC80DA
+88F488F589198CE08F29914D966A4F2F4F705E1B67CF6822767D767E9B445E61
+6A0A716971D4756AF9647E41854385E998DC4F107B4F7F7095A551E15E0668B5
+6C3E6C4E6CDB72AF7BC483036CD5743A50FB528858C164D86A9774A776560000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+5C
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000078A7861795E29739F965535E5F018B8A8FA88FAF908A522577A59C499F08
+4E19500251755C5B5E77661E663A67C468C570B3750175C579C97ADD8F279920
+9A084FDD582158315BF6666E6B656D116E7A6F7D73E4752B83E988DC89138B5C
+8F144F0F50D55310535C5B935FA9670D798F8179832F8514890789868F398F3B
+99A59C12672C4E764FF859495C015CEF5CF0636768D270FD71A2742B7E2B84EC
+8702902292D29CF34E0D4ED84FEF50855256526F5426549057E0592B5A660000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+5D
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00005B5A5B755BCC5E9CF9666276657765A76D6E6EA572367B267C3F7F368150
+8151819A8240829983A98A038CA08CE68CFB8D748DBA90E891DC961C964499D9
+9CE7531752065429567458B35954596E5FFF61A4626E66106C7E711A76C67C89
+7CDE7D1B82AC8CC196F0F9674F5B5F175F7F62C25D29670B68DA787C7E439D6C
+4E1550995315532A535159835A625E8760B2618A624962796590678769A76BD4
+6BD66BD76BD86CB8F968743575FA7812789179D579D87C837DCB7FE180A50000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+5E
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000813E81C283F2871A88E88AB98B6C8CBB9119975E98DB9F3B56AC5B2A5F6C
+658C6AB36BAF6D5C6FF17015725D73AD8CA78CD3983B61916C3780589A014E4D
+4E8B4E9B4ED54F3A4F3C4F7F4FDF50FF53F253F8550655E356DB58EB59625A11
+5BEB5BFA5C045DF35E2B5F99601D6368659C65AF67F667FB68AD6B7B6C996CD7
+6E23700973457802793E7940796079C17BE97D177D728086820D838E84D186C7
+88DF8A508A5E8B1D8CDC8D668FAD90AA98FC99DF9E9D524AF9696714F96A0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+5F
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00005098522A5C7165636C5573CA7523759D7B97849C917897304E7764926BBA
+715E85A94E09F96B674968EE6E17829F8518886B63F76F81921298AF4E0A50B7
+50CF511F554655AA56175B405C195CE05E385E8A5EA05EC260F368516A616E58
+723D724072C076F879657BB17FD488F389F48A738C618CDE971C585E74BD8CFD
+55C7F96C7A617D2282727272751F7525F96D7B19588558FB5DBC5E8F5EB65F90
+60556292637F654D669166D966F8681668F27280745E7B6E7D6E7DD67F720000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+60
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000080E5821285AF897F8A93901D92E49ECD9F205915596D5E2D60DC66146673
+67906C506DC56F5F77F378A984C691CB932B4ED950CA514855845B0B5BA36247
+657E65CB6E32717D74017444748774BF766C79AA7DDA7E557FA8817A81B38239
+861A87EC8A758DE3907892919425994D9BAE53685C5169546CC46D296E2B820C
+859B893B8A2D8AAA96EA9F67526166B96BB27E9687FE8D0D9583965D651D6D89
+71EEF96E57CE59D35BAC602760FA6210661F665F732973F976DB77017B6C0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+61
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00008056807281658AA091924E1652E26B726D177A057B397D30F96F8CB053EC
+562F58515BB55C0F5C115DE2624063836414662D68B36CBC6D886EAF701F70A4
+71D27526758F758E76197B117BE07C2B7D207D39852C856D86078A34900D9061
+90B592B797F69A374FD75C6C675F6D917C9F7E8C8B168D16901F5B6B5DFD640D
+84C0905C98E173875B8B609A677E6DDE8A1F8AA69001980C5237F9707051788E
+9396887091D74FEE53D755FD56DA578258FD5AC25B885CAB5CC05E2561010000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+62
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000620D624B6388641C653665786A396B8A6C346D196F3171E772E973787407
+74B27626776179C07A577AEA7CB97D8F7DAC7E617F9E81298331849084DA85EA
+88968AB08B908F3890429083916C929692B9968B96A796A896D6970098089996
+9AD39B1A53D4587E59195B705BBF6DD16F5A719F742174B9808583FD5DE15F87
+5FAA604265EC6812696F6A536B896D356DF373E376FE77AC7B4D7D148123821C
+834084F485638A628AC49187931E980699B4620C88538FF092655D075D270000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+63
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00005D69745F819D87686FD562FE7FD2893689724E1E4E5850E752DD5347627F
+66077E698805965E4F8D5319563659CB5AA45C385C4E5C4D5E025F11604365BD
+662F664267BE67F4731C77E2793A7FC5849484CD89968A668A698AE18C558C7A
+57F45BD45F0F606F62ED690D6B966E5C71847BD287558B588EFE98DF98FE4F38
+4F814FE1547B5A205BB8613C65B0666871FC7533795E7D33814E81E3839885AA
+85CE87038A0A8EAB8F9BF9718FC559315BA45BE660895BE95C0B5FC36C810000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+64
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000F9726DF1700B751A82AF8AF64EC05341F97396D96C0F4E9E4FC45152555E
+5A255CE86211725982BD83AA86FE88598A1D963F96C599139D099D5D580A5CB3
+5DBD5E4460E1611563E16A026E2591029354984E9C109F775B895CB86309664F
+6848773C96C1978D98549B9F65A18B018ECB95BC55355CA95DD65EB56697764C
+83F495C758D362BC72CE9D284EF0592E600F663B6B8379E79D26539354C057C3
+5D16611B66D66DAF788D827E969897445384627C63966DB27E0A814B984D0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+65
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00006AFB7F4C9DAF9E1A4E5F503B51B6591C60F963F66930723A8036F97491CE
+5F31F975F9767D0482E5846F84BB85E58E8DF9774F6FF978F97958E45B436059
+63DA6518656D6698F97A694A6A236D0B7001716C75D2760D79B37A70F97B7F8A
+F97C8944F97D8B9391C0967DF97E990A57045FA165BC6F01760079A68A9E99AD
+9B5A9F6C510461B662916A8D81C6504358305F6671098A008AFA5B7C86164FFA
+513C56B4594463A96DF95DAA696D51864E884F59F97FF980F9815982F9820000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+66
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000F9836B5F6C5DF98474B57916F9858207824583398F3F8F5DF9869918F987
+F988F9894EA6F98A57DF5F796613F98BF98C75AB7E798B6FF98D90069A5B56A5
+582759F85A1F5BB4F98E5EF6F98FF9906350633BF991693D6C876CBF6D8E6D93
+6DF56F14F99270DF71367159F99371C371D5F994784F786FF9957B757DE3F996
+7E2FF997884D8EDFF998F999F99A925BF99B9CF6F99CF99DF99E60856D85F99F
+71B1F9A0F9A195B153ADF9A2F9A3F9A467D3F9A5708E71307430827682D20000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+67
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000F9A695BB9AE59E7D66C4F9A771C18449F9A8F9A9584BF9AAF9AB5DB85F71
+F9AC6620668E697969AE6C386CF36E366F416FDA701B702F715071DF7370F9AD
+745BF9AE74D476C87A4E7E93F9AFF9B082F18A608FCEF9B19348F9B29719F9B3
+F9B44E42502AF9B5520853E166F36C6D6FCA730A777F7A6282AE85DD8602F9B6
+88D48A638B7D8C6BF9B792B3F9B8971398104E944F0D4FC950B25348543E5433
+55DA586258BA59675A1B5BE4609FF9B961CA655665FF666468A76C5A6FB30000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+68
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000070CF71AC73527B7D87088AA49C329F075C4B6C8373447389923A6EAB7465
+761F7A697E15860A514058C564C174EE751576707FC1909596CD99546E2674E6
+7AA97AAA81E586D987788A1B5A495B8C5B9B68A169006D6373A97413742C7897
+7DE97FEB81188155839E8C4C962E981166F05F8065FA67896C6A738B502D5A03
+6B6A77EE59165D6C5DCD7325754FF9BAF9BB50E551F9582F592D599659DA5BE5
+F9BCF9BD5DA262D76416649364FEF9BE66DCF9BF6A48F9C071FF7464F9C10000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+69
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00007A887AAF7E477E5E80008170F9C287EF89818B209059F9C390809952617E
+6B326D747E1F89258FB14FD150AD519752C757C758895BB95EB8614269956D8C
+6E676EB6719474627528752C8073833884C98E0A939493DEF9C44E8E4F515076
+512A53C853CB53F35B875BD35C24611A618265F4725B7397744076C279507991
+79B97D067FBD828B85D5865E8FC2904790F591EA968596E896E952D65F6765ED
+6631682F715C7A3690C1980A4E91F9C56A526B9E6F907189801882B885530000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+6A
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000904B969596F297FB851A9B314E90718A96C45143539F54E15713571257A3
+5A9B5AC45BC36028613F63F46C856D396E726E907230733F745782D188818F45
+9060F9C6966298589D1B67088D8A925E4F4D504950DE5371570D59D45A015C09
+617066906E2D7232744B7DEF80C3840E8466853F875F885B89188B02905597CB
+9B4F4E734F915112516AF9C7552F55A95B7A5BA55E7C5E7D5EBE60A060DF6108
+610963C465386709F9C867D467DAF9C9696169626CB96D27F9CA6E38F9CB0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+6B
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00006FE173367337F9CC745C7531F9CD7652F9CEF9CF7DAD81FE843888D58A98
+8ADB8AED8E308E42904A903E907A914991C9936EF9D0F9D15809F9D26BD38089
+80B2F9D3F9D45141596B5C39F9D5F9D66F6473A780E48D07F9D79217958FF9D8
+F9D9F9DAF9DB807F620E701C7D68878DF9DC57A0606961476BB78ABE928096B1
+4E59541F6DEB852D967097F398EE63D66CE3909151DD61C981BA9DF94F9D501A
+51005B9C610F61FF64EC69056BC5759177E37FA98264858F87FB88638ABC0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+6C
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00008B7091AB4E8C4EE54F0AF9DDF9DE593759E8F9DF5DF25F1B5F5B6021F9E0
+F9E1F9E2F9E3723E73E5F9E4757075CDF9E579FBF9E6800C8033808482E18351
+F9E7F9E88CBD8CB39087F9E9F9EA98F4990CF9EBF9EC703776CA7FCA7FCC7FFC
+8B1A4EBA4EC152035370F9ED54BD56E059FB5BC55F155FCD6E6EF9EEF9EF7D6A
+8335F9F086938A8DF9F1976D9777F9F2F9F34E004F5A4F7E58F965E56EA29038
+93B099B94EFB58EC598A59D96041F9F4F9F57A14F9F6834F8CC3516553440000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+6D
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000F9F7F9F8F9F94ECD52695B5582BF4ED4523A54A859C959FF5B505B575B5C
+606361486ECB7099716E738674F775B578C17D2B800581EA8328851785C98AEE
+8CC796CC4F5C52FA56BC65AB6628707C70B872357DBD828D914C96C09D725B71
+68E76B986F7A76DE5C9166AB6F5B7BB47C2A883696DC4E084ED75320583458BB
+58EF596C5C075E335E845F35638C66B267566A1F6AA36B0C6F3F7246F9FA7350
+748B7AE07CA7817881DF81E7838A846C8523859485CF88DD8D1391AC95770000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+6E
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000969C518D54C957285BB0624D6750683D68936E3D6ED3707D7E2188C18CA1
+8F099F4B9F4E722D7B8F8ACD931A4F474F4E5132548059D05E9562B56775696E
+6A176CAE6E1A72D9732A75BD7BB87D3582E783F9845785F78A5B8CAF8E879019
+90B896CE9F5F52E3540A5AE15BC2645865756EF472C4F9FB76847A4D7B1B7C4D
+7E3E7FDF837B8B2B8CCA8D648DE18E5F8FEA8FF9906993D14F434F7A50B35168
+5178524D526A5861587C59605C085C555EDB609B623068136BBF6C086FB10000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+6F
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000714E742075307538755176727B4C7B8B7BAD7BC67E8F8A6E8F3E8F49923F
+92939322942B96FB985A986B991E5207622A62986D5976647ACA7BC07D765360
+5CBE5E976F3870B97C9897119B8E9EDE63A5647A87764E014E954EAD505C5075
+544859C35B9A5E405EAD5EF75F8160C5633A653F657465CC6676667867FE6968
+6A896B636C406DC06DE86E1F6E5E701E70A1738E73FD753A775B7887798E7A0B
+7A7D7CBE7D8E82478A028AEA8C9E912D914A91D8926692CC9320970697560000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+70
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000975C98029F0E52365291557C58245E1D5F1F608C63D068AF6FDF796D7B2C
+81CD85BA88FD8AF88E44918D9664969B973D984C9F4A4FCE514651CB52A95632
+5F145F6B63AA64CD65E9664166FA66F9671D689D68D769FD6F156F6E716771E5
+722A74AA773A7956795A79DF7A207A957C977CDF7D447E70808785FB86A48A54
+8ABF8D998E819020906D91E3963B96D59CE565CF7C078DB393C35B585C0A5352
+62D9731D50275B975F9E60B0616B68D56DD9742E7A2E7D427D9C7E31816B0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+71
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00008E2A8E35937E94184F5057505DE65EA7632B7F6A4E3B4F4F4F8F505A59DD
+80C4546A546855FE594F5B995DDE5EDA665D673167F1682A6CE86D326E4A6F8D
+70B773E075877C4C7D027D2C7DA2821F86DB8A3B8A858D708E8A8F339031914E
+9152944499D07AF97CA54FCA510151C657C85BEF5CFB66596A3D6D5A6E966FEC
+710C756F7AE388229021907596CB99FF83014E2D4EF2884691CD537D6ADB696B
+6C41847A589E618E66FE62EF70DD751175C77E5284B88B498D084E4B53EA0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+72
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000054AB573057405FD763016307646F652F65E8667A679D67B36B626C606C9A
+6F2C77E57825794979577D1980A2810281F3829D82B787188A8CF9FC8D048DBE
+907276F47A197A377E548077550755D45875632F64226649664B686D699B6B84
+6D256EB173CD746874A1755B75B976E1771E778B79E67E097E1D81FB852F8897
+8A3A8CD18EEB8FB0903293AD9663967397074F8453F159EA5AC95E19684E74C6
+75BE79E97A9281A386ED8CEA8DCC8FED659F6715F9FD57F76F577DDD8F2F0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+73
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000093F696C65FB561F26F844E144F98501F53C955DF5D6F5DEE6B216B6478CB
+7B9AF9FE8E498ECA906E6349643E77407A84932F947F9F6A64B06FAF71E674A8
+74DA7AC47C127E827CB27E988B9A8D0A947D9910994C52395BDF64E6672D7D2E
+50ED53C358796158615961FA65AC7AD98B928B9650095021527555315A3C5EE0
+5F706134655E660C663666A269CD6EC46F32731676217A938139825983D684BC
+50B557F05BC05BE85F6963A178267DB583DC852191C791F5518A67F57B560000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+74
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00008CAC51C459BB60BD8655501CF9FF52545C3A617D621A62D364F265A56ECC
+7620810A8E60965F96BB4EDF5343559859295DDD64C56CC96DFA73947A7F821B
+85A68CE48E10907791E795E1962197C651F854F255865FB964A46F887DB48F1F
+8F4D943550C95C166CBE6DFB751B77BB7C3D7C648A798AC2581E59BE5E166377
+7252758A776B8ADC8CBC8F125EF366746DF8807D83C18ACB97519BD6FA005243
+66FF6D956EEF7DE08AE6902E905E9AD4521D527F54E86194628462DB68A20000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+75
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00006912695A6A3570927126785D7901790E79D27A0D8096827882D583498549
+8C828D859162918B91AE4FC356D171ED77D7870089F85BF85FD6675190A853E2
+585A5BF560A4618164607E3D80708525928364AE50AC5D146700589C62BD63A8
+690E69786A1E6E6B76BA79CB82BB84298ACF8DA88FFD9112914B919C93109318
+939A96DB9A369C0D4E11755C795D7AFA7B517BC97E2E84C48E598E748EF89010
+6625693F744351FA672E9EDC51455FE06C9687F2885D887760B481B584030000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+76
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00008D0553D6543956345A365C31708A7FE0805A810681ED8DA391899A5F9DF2
+50744EC453A060FB6E2C5C644F88502455E45CD95E5F606568946CBB6DC471BE
+75D475F476617A1A7A497DC77DFB7F6E81F486A98F1C96C999B39F52524752C5
+98ED89AA4E0367D26F064FB55BE267956C886D78741B782791DD937C87C479E4
+7A315FEB4ED654A4553E58AE59A560F0625362D6673669558235964099B199DD
+502C53535544577CFA016258FA0264E2666B67DD6FC16FEF742274388A170000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+77
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000094385451560657665F48619A6B4E705870AD7DBB8A95596A812B63A27708
+803D8CAA5854642D69BB5B955E116E6FFA038569514C53F0592A6020614B6B86
+6C706CF07B1E80CE82D48DC690B098B1FA0464C76FA464916504514E5410571F
+8A0E615F6876FA0575DB7B527D71901A580669CC817F892A9000983950785957
+59AC6295900F9B2A615D727995D657615A465DF4628A64AD64FA67776CE26D3E
+722C743678347F7782AD8DDB981752245742677F724874E38CA98FA692110000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+78
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000962A516B53ED634C4F695504609665576C9B6D7F724C72FD7A1789878C9D
+5F6D6F8E70F981A8610E4FBF504F624172477BC77DE87FE9904D97AD9A198CB6
+576A5E7367B0840D8A5554205B165E635EE25F0A658380BA853D9589965B4F48
+5305530D530F548654FA57035E036016629B62B16355FA066CE16D6675B17832
+80DE812F82DE846184B2888D8912900B92EA98FD9B915E4566B466DD70117206
+FA074FF5527D5F6A615367536A196F0274E2796888688C7998C798C49A430000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+79
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000054C17A1F69538AF78C4A98A899AE5F7C62AB75B276AE88AB907F96425339
+5F3C5FC56CCC73CC7562758B7B4682FE999D4E4F903C4E0B4F5553A6590F5EC8
+66306CB37455837787668CC09050971E9C1558D15B7886508B149DB45BD26068
+608D65F16C576F226FA3701A7F557FF095919592965097D352728F4451FD542B
+54B85563558A6ABB6DB57DD88266929C96779E79540854C876D286E495A495D4
+965C4EA24F0959EE5AE65DF760526297676D68416C866E2F7F38809B822A0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+7A
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000FA08FA0998054EA5505554B35793595A5B695BB361C869776D77702387F9
+89E38A728AE7908299ED9AB852BE683850165E78674F8347884C4EAB541156AE
+73E6911597FF9909995799995653589F865B8A3161B26AF6737B8ED26B4796AA
+9A57595572008D6B97694FD45CF45F2661F8665B6CEB70AB738473B973FE7729
+774D7D437D627E2382378852FA0A8CE29249986F5B517A74884098015ACC4FE0
+5354593E5CFD633E6D7972F98105810783A292CF98304EA851445211578B0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+7B
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00005F626CC26ECE7005705070AF719273E97469834A87A28861900890A293A3
+99A8516E5F5760E0616766B385598E4A91AF978B4E4E4E92547C58D558FA597D
+5CB55F2762366248660A66676BEB6D696DCF6E566EF86F946FE06FE9705D72D0
+7425745A74E07693795C7CCA7E1E80E182A6846B84BF864E865F87748B778C6A
+93AC9800986560D1621691775A5A660F6DF76E3E743F9B425FFD60DA7B0F54C4
+5F186C5E6CD36D2A70D87D0586798A0C9D3B5316548C5B056A3A706B75750000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+7C
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000798D79BE82B183EF8A718B418CA89774FA0B64F4652B78BA78BB7A6B4E38
+559A59505BA65E7B60A363DB6B61666568536E19716574B07D0890849A699C25
+6D3B6ED1733E8C4195CA51F05E4C5FA8604D60F66130614C6643664469A56CC1
+6E5F6EC96F62714C749C76877BC17C27835287579051968D9EC3532F56DE5EFB
+5F8A6062609461F7666667036A9C6DEE6FAE7070736A7E6A81BE833486D48AA8
+8CC4528373725B966A6B940454EE56865B5D6548658566C9689F6D8D6DC60000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+7D
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000723B80B491759A4D4FAF5019539A540E543C558955C55E3F5F8C673D7166
+73DD900552DB52F3586458CE7104718F71FB85B08A13668885A855A76684714A
+8431534955996BC15F595FBD63EE668971478AF18F1D9EBE4F11643A70CB7566
+866760648B4E9DF8514751F653086D3680F89ED166156B23709875D554035C79
+7D078A166B206B3D6B46543860706D3D7FD5820850D651DE559C566B56CD59EC
+5B095E0C619961986231665E66E6719971B971BA72A779A77A007FB28A700000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
diff --git a/library/encoding/macCentEuro.enc b/library/encoding/macCentEuro.enc
new file mode 100644
index 0000000..dde616a
--- /dev/null
+++ b/library/encoding/macCentEuro.enc
@@ -0,0 +1,20 @@
+# Encoding file: macCentEuro, single-byte
+S
+003F 0 1
+00
+0000000100020003000400050006000700080009000A000B000C000D000E000F
+0010001100120013001400150016001700180019001A001B001C001D001E001F
+0020002100220023002400250026002700280029002A002B002C002D002E002F
+0030003100320033003400350036003700380039003A003B003C003D003E003F
+0040004100420043004400450046004700480049004A004B004C004D004E004F
+0050005100520053005400550056005700580059005A005B005C005D005E005F
+0060006100620063006400650066006700680069006A006B006C006D006E006F
+0070007100720073007400750076007700780079007A007B007C007D007E007F
+00C40100010100C9010400D600DC00E10105010C00E4010D0106010700E90179
+017A010E00ED010F01120113011600F3011700F400F600F500FA011A011B00FC
+202000B0011800A300A7202200B600DF00AE00A92122011900A822600123012E
+012F012A22642265012B0136220222110142013B013C013D013E0139013A0145
+0146014300AC221A01440147220600AB00BB202600A00148015000D50151014C
+20132014201C201D2018201900F725CA014D0154015501582039203A01590156
+01570160201A201E0161015A015B00C10164016500CD017D017E016A00D300D4
+016B016E00DA016F017001710172017300DD00FD0137017B0141017C012202C7
diff --git a/library/encoding/macCroatian.enc b/library/encoding/macCroatian.enc
new file mode 100644
index 0000000..c23d0f0
--- /dev/null
+++ b/library/encoding/macCroatian.enc
@@ -0,0 +1,20 @@
+# Encoding file: macCroatian, single-byte
+S
+003F 0 1
+00
+0000000100020003000400050006000700080009000A000B000C000D000E000F
+0010001100120013001400150016001700180019001A001B001C001D001E001F
+0020002100220023002400250026002700280029002A002B002C002D002E002F
+0030003100320033003400350036003700380039003A003B003C003D003E003F
+0040004100420043004400450046004700480049004A004B004C004D004E004F
+0050005100520053005400550056005700580059005A005B005C005D005E005F
+0060006100620063006400650066006700680069006A006B006C006D006E006F
+0070007100720073007400750076007700780079007A007B007C007D007E007F
+00C400C500C700C900D100D600DC00E100E000E200E400E300E500E700E900E8
+00EA00EB00ED00EC00EE00EF00F100F300F200F400F600F500FA00F900FB00FC
+202000B000A200A300A7202200B600DF00AE0160212200B400A82260017D00D8
+221E00B122642265220600B522022211220F0161222B00AA00BA03A9017E00F8
+00BF00A100AC221A01922248010600AB010C202600A000C000C300D501520153
+01102014201C201D2018201900F725CAF8FF00A9204420AC2039203A00C600BB
+201300B7201A201E203000C2010700C1010D00C800CD00CE00CF00CC00D300D4
+011100D200DA00DB00D9013102C602DC00AF03C000CB02DA00B800CA00E602C7
diff --git a/library/encoding/macCyrillic.enc b/library/encoding/macCyrillic.enc
new file mode 100644
index 0000000..e657739
--- /dev/null
+++ b/library/encoding/macCyrillic.enc
@@ -0,0 +1,20 @@
+# Encoding file: macCyrillic, single-byte
+S
+003F 0 1
+00
+0000000100020003000400050006000700080009000A000B000C000D000E000F
+0010001100120013001400150016001700180019001A001B001C001D001E001F
+0020002100220023002400250026002700280029002A002B002C002D002E002F
+0030003100320033003400350036003700380039003A003B003C003D003E003F
+0040004100420043004400450046004700480049004A004B004C004D004E004F
+0050005100520053005400550056005700580059005A005B005C005D005E005F
+0060006100620063006400650066006700680069006A006B006C006D006E006F
+0070007100720073007400750076007700780079007A007B007C007D007E007F
+0410041104120413041404150416041704180419041A041B041C041D041E041F
+0420042104220423042404250426042704280429042A042B042C042D042E042F
+202000B0049000A300A7202200B6040600AE00A9212204020452226004030453
+221E00B122642265045600B504910408040404540407045704090459040A045A
+0458040500AC221A01922248220600AB00BB202600A0040B045B040C045C0455
+20132014201C201D2018201900F7201E040E045E040F045F211604010451044F
+0430043104320433043404350436043704380439043A043B043C043D043E043F
+0440044104420443044404450446044704480449044A044B044C044D044E20AC
diff --git a/library/encoding/macDingbats.enc b/library/encoding/macDingbats.enc
new file mode 100644
index 0000000..28449cd
--- /dev/null
+++ b/library/encoding/macDingbats.enc
@@ -0,0 +1,20 @@
+# Encoding file: macDingbats, single-byte
+S
+003F 1 1
+00
+0000000100020003000400050006000700080009000A000B000C000D000E000F
+0010001100120013001400150016001700180019001A001B001C001D001E001F
+00202701270227032704260E2706270727082709261B261E270C270D270E270F
+2710271127122713271427152716271727182719271A271B271C271D271E271F
+2720272127222723272427252726272726052729272A272B272C272D272E272F
+2730273127322733273427352736273727382739273A273B273C273D273E273F
+2740274127422743274427452746274727482749274A274B25CF274D25A0274F
+27502751275225B225BC25C6275625D727582759275A275B275C275D275E007F
+F8D7F8D8F8D9F8DAF8DBF8DCF8DDF8DEF8DFF8E0F8E1F8E2F8E3F8E4008E008F
+0090009100920093009400950096009700980099009A009B009C009D009E009F
+0000276127622763276427652766276726632666266526602460246124622463
+2464246524662467246824692776277727782779277A277B277C277D277E277F
+2780278127822783278427852786278727882789278A278B278C278D278E278F
+2790279127922793279421922194219527982799279A279B279C279D279E279F
+27A027A127A227A327A427A527A627A727A827A927AA27AB27AC27AD27AE27AF
+000027B127B227B327B427B527B627B727B827B927BA27BB27BC27BD27BE0000
diff --git a/library/encoding/macGreek.enc b/library/encoding/macGreek.enc
new file mode 100644
index 0000000..67b9953
--- /dev/null
+++ b/library/encoding/macGreek.enc
@@ -0,0 +1,20 @@
+# Encoding file: macGreek, single-byte
+S
+003F 0 1
+00
+0000000100020003000400050006000700080009000A000B000C000D000E000F
+0010001100120013001400150016001700180019001A001B001C001D001E001F
+0020002100220023002400250026002700280029002A002B002C002D002E002F
+0030003100320033003400350036003700380039003A003B003C003D003E003F
+0040004100420043004400450046004700480049004A004B004C004D004E004F
+0050005100520053005400550056005700580059005A005B005C005D005E005F
+0060006100620063006400650066006700680069006A006B006C006D006E006F
+0070007100720073007400750076007700780079007A007B007C007D007E007F
+00C400B900B200C900B300D600DC038500E000E200E4038400A800E700E900E8
+00EA00EB00A3212200EE00EF202200BD203000F400F600A600AD00F900FB00FC
+2020039303940398039B039E03A000DF00AE00A903A303AA00A7226000B000B7
+039100B12264226500A503920395039603970399039A039C03A603AB03A803A9
+03AC039D00AC039F03A1224803A400AB00BB202600A003A503A7038603880153
+20132015201C201D2018201900F70389038A038C038E03AD03AE03AF03CC038F
+03CD03B103B203C803B403B503C603B303B703B903BE03BA03BB03BC03BD03BF
+03C003CE03C103C303C403B803C903C203C703C503B603CA03CB039003B0F8A0
diff --git a/library/encoding/macIceland.enc b/library/encoding/macIceland.enc
new file mode 100644
index 0000000..c636069
--- /dev/null
+++ b/library/encoding/macIceland.enc
@@ -0,0 +1,20 @@
+# Encoding file: macIceland, single-byte
+S
+003F 0 1
+00
+0000000100020003000400050006000700080009000A000B000C000D000E000F
+0010001100120013001400150016001700180019001A001B001C001D001E001F
+0020002100220023002400250026002700280029002A002B002C002D002E002F
+0030003100320033003400350036003700380039003A003B003C003D003E003F
+0040004100420043004400450046004700480049004A004B004C004D004E004F
+0050005100520053005400550056005700580059005A005B005C005D005E005F
+0060006100620063006400650066006700680069006A006B006C006D006E006F
+0070007100720073007400750076007700780079007A007B007C007D007E007F
+00C400C500C700C900D100D600DC00E100E000E200E400E300E500E700E900E8
+00EA00EB00ED00EC00EE00EF00F100F300F200F400F600F500FA00F900FB00FC
+00DD00B000A200A300A7202200B600DF00AE00A9212200B400A8226000C600D8
+221E00B12264226500A500B522022211220F03C0222B00AA00BA03A900E600F8
+00BF00A100AC221A01922248220600AB00BB202600A000C000C300D501520153
+20132014201C201D2018201900F725CA00FF0178204420AC00D000F000DE00FE
+00FD00B7201A201E203000C200CA00C100CB00C800CD00CE00CF00CC00D300D4
+F8FF00D200DA00DB00D9013102C602DC00AF02D802D902DA00B802DD02DB02C7
diff --git a/library/encoding/macJapan.enc b/library/encoding/macJapan.enc
new file mode 100644
index 0000000..dba24bd
--- /dev/null
+++ b/library/encoding/macJapan.enc
@@ -0,0 +1,785 @@
+# Encoding file: macJapan, multi-byte
+M
+003F 0 46
+00
+0000000100020003000400050006000700080009000A000B000C000D000E000F
+0010001100120013001400150016001700180019001A001B001C001D001E001F
+0020002100220023002400250026002700280029002A002B002C002D002E002F
+0030003100320033003400350036003700380039003A003B003C003D003E003F
+0040004100420043004400450046004700480049004A004B004C004D004E004F
+0050005100520053005400550056005700580059005A005B005C005D005E005F
+0060006100620063006400650066006700680069006A006B006C006D006E006F
+0070007100720073007400750076007700780079007A007B007C007D007E007F
+0080000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00A0FF61FF62FF63FF64FF65FF66FF67FF68FF69FF6AFF6BFF6CFF6DFF6EFF6F
+FF70FF71FF72FF73FF74FF75FF76FF77FF78FF79FF7AFF7BFF7CFF7DFF7EFF7F
+FF80FF81FF82FF83FF84FF85FF86FF87FF88FF89FF8AFF8BFF8CFF8DFF8EFF8F
+FF90FF91FF92FF93FF94FF95FF96FF97FF98FF99FF9AFF9BFF9CFF9DFF9EFF9F
+0000000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000A921222026
+81
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+300030013002FF0CFF0E30FBFF1AFF1BFF1FFF01309B309C00B4FF4000A8FF3E
+203EFF3F30FD30FE309D309E30034EDD30053006300730FC20142010FF0FFF3C
+301C2016FF5C22EF202520182019201C201DFF08FF0930143015FF3BFF3DFF5B
+FF5D30083009300A300B300C300D300E300F30103011FF0B221200B100D70000
+00F7FF1D2260FF1CFF1E22662267221E22342642264000B0203220332103FFE5
+FF0400A200A3FF05FF03FF06FF0AFF2000A72606260525CB25CF25CE25C725C6
+25A125A025B325B225BD25BC203B301221922190219121933013000000000000
+000000000000000000000000000000002208220B2286228722822283222A2229
+000000000000000000000000000000002227222800AC21D221D4220022030000
+0000000000000000000000000000000000000000222022A52312220222072261
+2252226A226B221A223D221D2235222B222C0000000000000000000000000000
+212B2030266F266D266A2020202100B6000000000000000025EF000000000000
+82
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000FF10
+FF11FF12FF13FF14FF15FF16FF17FF18FF190000000000000000000000000000
+FF21FF22FF23FF24FF25FF26FF27FF28FF29FF2AFF2BFF2CFF2DFF2EFF2FFF30
+FF31FF32FF33FF34FF35FF36FF37FF38FF39FF3A000000000000000000000000
+0000FF41FF42FF43FF44FF45FF46FF47FF48FF49FF4AFF4BFF4CFF4DFF4EFF4F
+FF50FF51FF52FF53FF54FF55FF56FF57FF58FF59FF5A00000000000000003041
+30423043304430453046304730483049304A304B304C304D304E304F30503051
+30523053305430553056305730583059305A305B305C305D305E305F30603061
+30623063306430653066306730683069306A306B306C306D306E306F30703071
+30723073307430753076307730783079307A307B307C307D307E307F30803081
+30823083308430853086308730883089308A308B308C308D308E308F30903091
+3092309300000000000000000000000000000000000000000000000000000000
+83
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+30A130A230A330A430A530A630A730A830A930AA30AB30AC30AD30AE30AF30B0
+30B130B230B330B430B530B630B730B830B930BA30BB30BC30BD30BE30BF30C0
+30C130C230C330C430C530C630C730C830C930CA30CB30CC30CD30CE30CF30D0
+30D130D230D330D430D530D630D730D830D930DA30DB30DC30DD30DE30DF0000
+30E030E130E230E330E430E530E630E730E830E930EA30EB30EC30ED30EE30EF
+30F030F130F230F330F430F530F6000000000000000000000000000000000391
+03920393039403950396039703980399039A039B039C039D039E039F03A003A1
+03A303A403A503A603A703A803A90000000000000000000000000000000003B1
+03B203B303B403B503B603B703B803B903BA03BB03BC03BD03BE03BF03C003C1
+03C303C403C503C603C703C803C9000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+84
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+04100411041204130414041504010416041704180419041A041B041C041D041E
+041F0420042104220423042404250426042704280429042A042B042C042D042E
+042F000000000000000000000000000000000000000000000000000000000000
+04300431043204330434043504510436043704380439043A043B043C043D0000
+043E043F0440044104420443044404450446044704480449044A044B044C044D
+044E044F00000000000000000000000000000000000000000000000000002500
+2502250C251025182514251C252C25242534253C25012503250F2513251B2517
+25232533252B253B254B2520252F25282537253F251D25302525253825420000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+85
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+2460246124622463246424652466246724682469246A246B246C246D246E246F
+2470247124722473000000000000000000000000000000000000000024742475
+2476247724782479247A247B247C247D247E247F248024812482248324842485
+2486248700000000000000000000000000000000000000002776277727780000
+2779277A277B277C277D277E0000000000000000000000000000000000000000
+0000F8A124882489248A248B248C248D248E248F249000000000000000002160
+216121622163216421652166216721682169216A216BF8A2F8A3F8A400000000
+0000000000002170217121722173217421752176217721782179217A217BF8A5
+F8A6F8A700000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000249C249D249E249F24A0
+24A124A224A324A424A524A624A724A824A924AA24AB24AC24AD24AE24AF24B0
+24B124B224B324B424B500000000000000000000000000000000000000000000
+86
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+339C339F339D33A033A4F8A833A133A5339E33A2338EF8A9338F33C433963397
+F8AA339833B333B233B133B0210933D433CB3390338533863387F8AB00000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00000000000000000000000000000000000000000000211633CD2121F8AC2664
+2667266126622660266326652666000000000000000000000000000000000000
+0000000000003020260E30040000000000000000000000000000000000000000
+0000000000000000000000000000261E261C261D261F21C621C421C5F8AD21E8
+21E621E721E9F8AEF8AFF8B0F8B1000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+87
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+3230322A322B322C322D322E322F32403237324232433239323A3231323E3234
+3232323B323632333235323C323D323F32380000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000059275C0F32A432A532A632A732A832A93296329D3298329E63A732993349
+3322334D3314331633053333334E330333363318331533273351334A33393357
+330D334233233326333B332B00000000000000000000000000003300331E332A
+3331334700000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00000000000000000000337E337D337C337B0000000000000000000000000000
+0000000000000000000000000000000000000000337FF8B2F8B3000000000000
+88
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+222E221F22BF0000000000000000000000000000000000000000000000000000
+0000000000000000301DF8B40000000000000000000000000000000000000000
+000000000000000000000000000000003094000030F730F830F930FA00000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000004E9C
+55165A03963F54C0611B632859F690228475831C7A5060AA63E16E2565ED8466
+82A69BF56893572765A162715B9B59D0867B98F47D627DBE9B8E62167C9F88B7
+5B895EB563096697684895C7978D674F4EE54F0A4F4D4F9D504956F2593759D4
+5A015C0960DF610F61706613690570BA754F757079FB7DAD7DEF80C3840E8863
+8B029055907A533B4E954EA557DF80B290C178EF4E0058F16EA290387A328328
+828B9C2F5141537054BD54E156E059FB5F1598F26DEB80E4852D000000000000
+89
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+9662967096A097FB540B53F35B8770CF7FBD8FC296E8536F9D5C7ABA4E117893
+81FC6E26561855046B1D851A9C3B59E553A96D6674DC958F56424E91904B96F2
+834F990C53E155B65B305F71662066F368046C386CF36D29745B76C87A4E9834
+82F1885B8A6092ED6DB275AB76CA99C560A68B018D8A95B2698E53AD51860000
+5712583059445BB45EF6602863A963F46CBF6F14708E7114715971D5733F7E01
+827682D185979060925B9D1B586965BC6C5A752551F9592E59655F805FDC62BC
+65FA6A2A6B276BB4738B7FC189569D2C9D0E9EC45CA16C96837B51045C4B61B6
+81C6687672614E594FFA537860696E297A4F97F34E0B53164EEE4F554F3D4FA1
+4F7352A053EF5609590F5AC15BB65BE179D16687679C67B66B4C6CB3706B73C2
+798D79BE7A3C7B8782B182DB8304837783EF83D387668AB256298CA88FE6904E
+971E868A4FC45CE862117259753B81E582BD86FE8CC096C5991399D54ECB4F1A
+89E356DE584A58CA5EFB5FEB602A6094606261D0621262D06539000000000000
+8A
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+9B41666668B06D777070754C76867D7582A587F9958B968E8C9D51F152BE5916
+54B35BB35D16616869826DAF788D84CB88578A7293A79AB86D6C99A886D957A3
+67FF86CE920E5283568754045ED362E164B9683C68386BBB737278BA7A6B899A
+89D28D6B8F0390ED95A3969497695B665CB3697D984D984E639B7B206A2B0000
+6A7F68B69C0D6F5F5272559D607062EC6D3B6E076ED1845B89108F444E149C39
+53F6691B6A3A9784682A515C7AC384B291DC938C565B9D286822830584317CA5
+520882C574E64E7E4F8351A05BD2520A52D852E75DFB559A582A59E65B8C5B98
+5BDB5E725E7960A3611F616361BE63DB656267D1685368FA6B3E6B536C576F22
+6F976F4574B0751876E3770B7AFF7BA17C217DE97F367FF0809D8266839E89B3
+8ACC8CAB908494519593959195A2966597D3992882184E38542B5CB85DCC73A9
+764C773C5CA97FEB8D0B96C19811985498584F014F0E5371559C566857FA5947
+5B095BC45C905E0C5E7E5FCC63EE673A65D765E2671F68CB68C4000000000000
+8B
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+6A5F5E306BC56C176C7D757F79485B637A007D005FBD898F8A188CB48D778ECC
+8F1D98E29A0E9B3C4E80507D510059935B9C622F628064EC6B3A72A075917947
+7FA987FB8ABC8B7063AC83CA97A05409540355AB68546A588A70782767759ECD
+53745BA2811A865090064E184E454EC74F1153CA54385BAE5F13602565510000
+673D6C426C726CE3707874037A767AAE7B087D1A7CFE7D6665E7725B53BB5C45
+5DE862D262E063196E20865A8A318DDD92F86F0179A69B5A4EA84EAB4EAC4F9B
+4FA050D151477AF6517151F653545321537F53EB55AC58835CE15F375F4A602F
+6050606D631F65596A4B6CC172C272ED77EF80F881058208854E90F793E197FF
+99579A5A4EF051DD5C2D6681696D5C4066F26975738968507C8150C552E45747
+5DFE932665A46B236B3D7434798179BD7B4B7DCA82B983CC887F895F8B398FD1
+91D1541F92804E5D503653E5533A72D7739677E982E68EAF99C699C899D25177
+611A865E55B07A7A50765BD3904796854E326ADB91E75C515C48000000000000
+8C
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+63987A9F6C9397748F617AAA718A96887C8268177E706851936C52F2541B85AB
+8A137FA48ECD90E15366888879414FC250BE521151445553572D73EA578B5951
+5F625F8460756176616761A963B2643A656C666F68426E1375667A3D7CFB7D4C
+7D997E4B7F6B830E834A86CD8A088A638B668EFD981A9D8F82B88FCE9BE80000
+5287621F64836FC09699684150916B206C7A6F547A747D5088408A2367084EF6
+503950265065517C5238526355A7570F58055ACC5EFA61B261F862F36372691C
+6A29727D72AC732E7814786F7D79770C80A9898B8B198CE28ED290639375967A
+98559A139E785143539F53B35E7B5F266E1B6E90738473FE7D4382378A008AFA
+96504E4E500B53E4547C56FA59D15B645DF15EAB5F276238654567AF6E5672D0
+7CCA88B480A180E183F0864E8A878DE8923796C798679F134E944E924F0D5348
+5449543E5A2F5F8C5FA1609F68A76A8E745A78818A9E8AA48B7791904E5E9BC9
+4EA44F7C4FAF501950165149516C529F52B952FE539A53E35411000000000000
+8D
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+540E5589575157A2597D5B545B5D5B8F5DE55DE75DF75E785E835E9A5EB75F18
+6052614C629762D863A7653B6602664366F4676D6821689769CB6C5F6D2A6D69
+6E2F6E9D75327687786C7A3F7CE07D057D187D5E7DB18015800380AF80B18154
+818F822A8352884C88618B1B8CA28CFC90CA91759271783F92FC95A4964D0000
+980599999AD89D3B525B52AB53F7540858D562F76FE08C6A8F5F9EB9514B523B
+544A56FD7A4091779D609ED273446F09817075115FFD60DA9AA872DB8FBC6B64
+98034ECA56F0576458BE5A5A606861C7660F6606683968B16DF775D57D3A826E
+9B424E9B4F5053C955065D6F5DE65DEE67FB6C99747378028A50939688DF5750
+5EA7632B50B550AC518D670054C9585E59BB5BB05F69624D63A1683D6B736E08
+707D91C7728078157826796D658E7D3083DC88C18F09969B5264572867507F6A
+8CA151B45742962A583A698A80B454B25D0E57FC78959DFA4F5C524A548B643E
+6628671467F57A847B567D22932F685C9BAD7B395319518A5237000000000000
+8E
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+5BDF62F664AE64E6672D6BBA85A996D176909BD6634C93069BAB76BF66524E09
+509853C25C7160E864926563685F71E673CA75237B977E8286958B838CDB9178
+991065AC66AB6B8B4ED54ED44F3A4F7F523A53F853F255E356DB58EB59CB59C9
+59FF5B505C4D5E025E2B5FD7601D6307652F5B5C65AF65BD65E8679D6B620000
+6B7B6C0F7345794979C17CF87D197D2B80A2810281F389968A5E8A698A668A8C
+8AEE8CC78CDC96CC98FC6B6F4E8B4F3C4F8D51505B575BFA6148630166426B21
+6ECB6CBB723E74BD75D478C1793A800C803381EA84948F9E6C509E7F5F0F8B58
+9D2B7AFA8EF85B8D96EB4E0353F157F759315AC95BA460896E7F6F0675BE8CEA
+5B9F85007BE0507267F4829D5C61854A7E1E820E51995C0463688D66659C716E
+793E7D1780058B1D8ECA906E86C790AA501F52FA5C3A6753707C7235914C91C8
+932B82E55BC25F3160F94E3B53D65B88624B67316B8A72E973E07A2E816B8DA3
+91529996511253D7546A5BFF63886A397DAC970056DA53CE5468000000000000
+8F
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+5B975C315DDE4FEE610162FE6D3279C079CB7D427E4D7FD281ED821F84908846
+89728B908E748F2F9031914B916C96C6919C4EC04F4F514553415F93620E67D4
+6C416E0B73637E2691CD928353D459195BBF6DD1795D7E2E7C9B587E719F51FA
+88538FF04FCA5CFB662577AC7AE3821C99FF51C65FAA65EC696F6B896DF30000
+6E966F6476FE7D145DE190759187980651E6521D6240669166D96E1A5EB67DD2
+7F7266F885AF85F78AF852A953D959735E8F5F90605592E4966450B7511F52DD
+5320534753EC54E8554655315617596859BE5A3C5BB55C065C0F5C115C1A5E84
+5E8A5EE05F70627F628462DB638C63776607660C662D6676677E68A26A1F6A35
+6CBC6D886E096E58713C7126716775C77701785D7901796579F07AE07B117CA7
+7D39809683D6848B8549885D88F38A1F8A3C8A548A738C618CDE91A49266937E
+9418969C97984E0A4E084E1E4E575197527057CE583458CC5B225E3860C564FE
+676167566D4472B675737A6384B88B7291B89320563157F498FE000000000000
+90
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+62ED690D6B9671ED7E548077827289E698DF87558FB15C3B4F384FE14FB55507
+5A205BDD5BE95FC3614E632F65B0664B68EE699B6D786DF1753375B9771F795E
+79E67D3381E382AF85AA89AA8A3A8EAB8F9B903291DD97074EBA4EC152035875
+58EC5C0B751A5C3D814E8A0A8FC59663976D7B258ACF9808916256F353A80000
+9017543957825E2563A86C34708A77617C8B7FE088709042915493109318968F
+745E9AC45D075D69657067A28DA896DB636E6749691983C5981796C088FE6F84
+647A5BF84E16702C755D662F51C4523652E259D35F8160276210653F6574661F
+667468F268166B636E057272751F76DB7CBE805658F088FD897F8AA08A938ACB
+901D91929752975965897A0E810696BB5E2D60DC621A65A56614679077F37A4D
+7C4D7E3E810A8CAC8D648DE18E5F78A9520762D963A5644262988A2D7A837BC0
+8AAC96EA7D76820C87494ED95148534353605BA35C025C165DDD6226624764B0
+681368346CC96D456D1767D36F5C714E717D65CB7A7F7BAD7DDA000000000000
+91
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+7E4A7FA8817A821B823985A68A6E8CCE8DF59078907792AD929195839BAE524D
+55846F387136516879857E5581B37CCE564C58515CA863AA66FE66FD695A72D9
+758F758E790E795679DF7C977D207D4486078A34963B90619F2050E7527553CC
+53E2500955AA58EE594F723D5B8B5C64531D60E360F3635C6383633F63BB0000
+64CD65E966F95DE369CD69FD6F1571E54E8975E976F87A937CDF7DCF7D9C8061
+83498358846C84BC85FB88C58D709001906D9397971C9A1250CF5897618E81D3
+85358D0890204FC3507452475373606F6349675F6E2C8DB3901F4FD75C5E8CCA
+65CF7D9A53528896517663C35B585B6B5C0A640D6751905C4ED6591A592A6C70
+8A51553E581559A560F0625367C182356955964099C49A284F5358065BFE8010
+5CB15E2F5F856020614B623466FF6CF06EDE80CE817F82D4888B8CB89000902E
+968A9EDB9BDB4EE353F059277B2C918D984C9DF96EDD7027535355445B856258
+629E62D36CA26FEF74228A1794386FC18AFE833851E786F853EA000000000000
+92
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+53E94F4690548FB0596A81315DFD7AEA8FBF68DA8C3772F89C486A3D8AB04E39
+53585606576662C563A265E66B4E6DE16E5B70AD77ED7AEF7BAA7DBB803D80C6
+86CB8A95935B56E358C75F3E65AD66966A806BB575378AC7502477E557305F1B
+6065667A6C6075F47A1A7F6E81F48718904599B37BC9755C7AF97B5184C40000
+901079E97A9283365AE177404E2D4EF25B995FE062BD663C67F16CE8866B8877
+8A3B914E92F399D06A177026732A82E784578CAF4E01514651CB558B5BF55E16
+5E335E815F145F355F6B5FB461F2631166A2671D6F6E7252753A773A80748139
+817887768ABF8ADC8D858DF3929A957798029CE552C5635776F467156C8873CD
+8CC393AE96736D25589C690E69CC8FFD939A75DB901A585A680263B469FB4F43
+6F2C67D88FBB85267DB49354693F6F70576A58F75B2C7D2C722A540A91E39DB4
+4EAD4F4E505C507552438C9E544858245B9A5E1D5E955EAD5EF75F1F608C62B5
+633A63D068AF6C407887798E7A0B7DE082478A028AE68E449013000000000000
+93
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+90B8912D91D89F0E6CE5645864E265756EF476847B1B906993D16EBA54F25FB9
+64A48F4D8FED92445178586B59295C555E976DFB7E8F751C8CBC8EE2985B70B9
+4F1D6BBF6FB1753096FB514E54105835585759AC5C605F926597675C6E21767B
+83DF8CED901490FD934D7825783A52AA5EA6571F597460125012515A51AC0000
+51CD520055105854585859575B955CF65D8B60BC6295642D6771684368BC68DF
+76D76DD86E6F6D9B706F71C85F5375D879777B497B547B527CD67D7152308463
+856985E48A0E8B048C468E0F9003900F94199676982D9A3095D850CD52D5540C
+58025C0E61A7649E6D1E77B37AE580F48404905392855CE09D07533F5F975FB3
+6D9C7279776379BF7BE46BD272EC8AAD68036A6151F87A8169345C4A9CF682EB
+5BC59149701E56785C6F60C765666C8C8C5A90419813545166C7920D594890A3
+51854E4D51EA85998B0E7058637A934B696299B47E047577535769608EDF96E3
+6C5D4E8C5C3C5F108FE953028CD1808986795EFF65E54E735165000000000000
+94
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+59825C3F97EE4EFB598A5FCD8A8D6FE179B079625BE78471732B71B15E745FF5
+637B649A71C37C984E435EFC4E4B57DC56A260A96FC37D0D80FD813381BF8FB2
+899786A45DF4628A64AD898767776CE26D3E743678345A467F7582AD99AC4FF3
+5EC362DD63926557676F76C3724C80CC80BA8F29914D500D57F95A9268850000
+6973716472FD8CB758F28CE0966A9019877F79E477E784294F2F5265535A62CD
+67CF6CCA767D7B947C95823685848FEB66DD6F2072067E1B83AB99C19EA651FD
+7BB178727BB880877B486AE85E61808C75517560516B92626E8C767A91979AEA
+4F107F70629C7B4F95A59CE9567A585986E496BC4F345224534A53CD53DB5E06
+642C6591677F6C3E6C4E724872AF73ED75547E41822C85E98CA97BC491C67169
+981298EF633D6669756A76E478D0854386EE532A5351542659835E875F7C60B2
+6249627962AB65906BD46CCC75B276AE789179D87DCB7F7780A588AB8AB98CBB
+907F975E98DB6A0B7C3850995C3E5FAE67876BD8743577097F8E000000000000
+95
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+9F3B67CA7A175339758B9AED5F66819D83F180985F3C5FC575627B46903C6867
+59EB5A9B7D10767E8B2C4FF55F6A6A196C376F0274E2796888688A558C795EDF
+63CF75C579D282D7932892F2849C86ED9C2D54C15F6C658C6D5C70158CA78CD3
+983B654F74F64E0D4ED857E0592B5A665BCC51A85E035E9C6016627665770000
+65A7666E6D6E72367B268150819A82998B5C8CA08CE68D74961C96444FAE64AB
+6B66821E8461856A90E85C01695398A8847A85574F0F526F5FA95E45670D798F
+8179890789866DF55F1762556CB84ECF72699B925206543B567458B361A4626E
+711A596E7C897CDE7D1B96F06587805E4E194F75517558405E635E735F0A67C4
+4E26853D9589965B7C73980150FB58C1765678A7522577A585117B86504F5909
+72477BC77DE88FBA8FD4904D4FBF52C95A295F0197AD4FDD821792EA57036355
+6B69752B88DC8F147A4252DF58936155620A66AE6BCD7C3F83E950234FF85305
+5446583159495B9D5CF05CEF5D295E9662B16367653E65B9670B000000000000
+96
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+6CD56CE170F978327E2B80DE82B3840C84EC870289128A2A8C4A90A692D298FD
+9CF39D6C4E4F4EA1508D5256574A59A85E3D5FD85FD9623F66B4671B67D068D2
+51927D2180AA81A88B008C8C8CBF927E96325420982C531750D5535C58A864B2
+6734726777667A4691E652C36CA16B8658005E4C5954672C7FFB51E176C60000
+646978E89B549EBB57CB59B96627679A6BCE54E969D95E55819C67959BAA67FE
+9C52685D4EA64FE353C862B9672B6CAB8FC44FAD7E6D9EBF4E0761626E806F2B
+85135473672A9B455DF37B955CAC5BC6871C6E4A84D17A14810859997C8D6C11
+772052D959227121725F77DB97279D61690B5A7F5A1851A5540D547D660E76DF
+8FF792989CF459EA725D6EC5514D68C97DBF7DEC97629EBA64786A2183025984
+5B5F6BDB731B76F27DB280178499513267289ED976EE676252FF99055C24623B
+7C7E8CB0554F60B67D0B958053014E5F51B6591C723A803691CE5F2577E25384
+5F797D0485AC8A338E8D975667F385AE9453610961086CB97652000000000000
+97
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+8AED8F38552F4F51512A52C753CB5BA55E7D60A0618263D6670967DA6E676D8C
+733673377531795088D58A98904A909190F596C4878D59154E884F594E0E8A89
+8F3F981050AD5E7C59965BB95EB863DA63FA64C166DC694A69D86D0B6EB67194
+75287AAF7F8A8000844984C989818B218E0A9065967D990A617E62916B320000
+6C836D747FCC7FFC6DC07F8587BA88F8676583B1983C96F76D1B7D61843D916A
+4E7153755D506B046FEB85CD862D89A75229540F5C65674E68A87406748375E2
+88CF88E191CC96E296785F8B73877ACB844E63A0756552896D416E9C74097559
+786B7C9296867ADC9F8D4FB6616E65C5865C4E864EAE50DA4E2151CC5BEE6599
+68816DBC731F764277AD7A1C7CE7826F8AD2907C91CF96759818529B7DD1502B
+539867976DCB71D0743381E88F2A96A39C579E9F746058416D997D2F985E4EE4
+4F364F8B51B752B15DBA601C73B2793C82D3923496B796F6970A9E979F6266A6
+6B74521752A370C888C25EC9604B61906F2371497C3E7DF4806F000000000000
+98
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+84EE9023932C54429B6F6AD370898CC28DEF973252B45A415ECA5F046717697C
+69946D6A6F0F726272FC7BED8001807E874B90CE516D9E937984808B93328AD6
+502D548C8A716B6A8CC4810760D167A09DF24E994E989C108A6B85C185686900
+6E7E789781550000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000005F0C
+4E104E154E2A4E314E364E3C4E3F4E424E564E584E824E858C6B4E8A82125F0D
+4E8E4E9E4E9F4EA04EA24EB04EB34EB64ECE4ECD4EC44EC64EC24ED74EDE4EED
+4EDF4EF74F094F5A4F304F5B4F5D4F574F474F764F884F8F4F984F7B4F694F70
+4F914F6F4F864F9651184FD44FDF4FCE4FD84FDB4FD14FDA4FD04FE44FE5501A
+50285014502A502550054F1C4FF650215029502C4FFE4FEF5011500650435047
+6703505550505048505A5056506C50785080509A508550B450B2000000000000
+99
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+50C950CA50B350C250D650DE50E550ED50E350EE50F950F55109510151025116
+51155114511A5121513A5137513C513B513F51405152514C515451627AF85169
+516A516E5180518256D8518C5189518F519151935195519651A451A651A251A9
+51AA51AB51B351B151B251B051B551BD51C551C951DB51E0865551E951ED0000
+51F051F551FE5204520B5214520E5227522A522E52335239524F5244524B524C
+525E5254526A527452695273527F527D528D529452925271528852918FA88FA7
+52AC52AD52BC52B552C152CD52D752DE52E352E698ED52E052F352F552F852F9
+530653087538530D5310530F5315531A5323532F533153335338534053465345
+4E175349534D51D6535E5369536E5918537B53775382539653A053A653A553AE
+53B053B653C37C1296D953DF66FC71EE53EE53E853ED53FA5401543D5440542C
+542D543C542E54365429541D544E548F5475548E545F5471547754705492547B
+5480547654845490548654C754A254B854A554AC54C454C854A8000000000000
+9A
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+54AB54C254A454BE54BC54D854E554E6550F551454FD54EE54ED54FA54E25539
+55405563554C552E555C55455556555755385533555D5599558054AF558A559F
+557B557E5598559E55AE557C558355A9558755A855DA55C555DF55C455DC55E4
+55D4561455F7561655FE55FD561B55F9564E565071DF56345636563256380000
+566B5664562F566C566A56865680568A56A05694568F56A556AE56B656B456C2
+56BC56C156C356C056C856CE56D156D356D756EE56F9570056FF570457095708
+570B570D57135718571655C7571C572657375738574E573B5740574F576957C0
+57885761577F5789579357A057B357A457AA57B057C357C657D457D257D3580A
+57D657E3580B5819581D587258215862584B58706BC05852583D5879588558B9
+589F58AB58BA58DE58BB58B858AE58C558D358D158D758D958D858E558DC58E4
+58DF58EF58FA58F958FB58FC58FD5902590A5910591B68A65925592C592D5932
+5938593E7AD259555950594E595A5958596259605967596C5969000000000000
+9B
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+59785981599D4F5E4FAB59A359B259C659E859DC598D59D959DA5A255A1F5A11
+5A1C5A095A1A5A405A6C5A495A355A365A625A6A5A9A5ABC5ABE5ACB5AC25ABD
+5AE35AD75AE65AE95AD65AFA5AFB5B0C5B0B5B165B325AD05B2A5B365B3E5B43
+5B455B405B515B555B5A5B5B5B655B695B705B735B755B7865885B7A5B800000
+5B835BA65BB85BC35BC75BC95BD45BD05BE45BE65BE25BDE5BE55BEB5BF05BF6
+5BF35C055C075C085C0D5C135C205C225C285C385C395C415C465C4E5C535C50
+5C4F5B715C6C5C6E4E625C765C795C8C5C915C94599B5CAB5CBB5CB65CBC5CB7
+5CC55CBE5CC75CD95CE95CFD5CFA5CED5D8C5CEA5D0B5D155D175D5C5D1F5D1B
+5D115D145D225D1A5D195D185D4C5D525D4E5D4B5D6C5D735D765D875D845D82
+5DA25D9D5DAC5DAE5DBD5D905DB75DBC5DC95DCD5DD35DD25DD65DDB5DEB5DF2
+5DF55E0B5E1A5E195E115E1B5E365E375E445E435E405E4E5E575E545E5F5E62
+5E645E475E755E765E7A9EBC5E7F5EA05EC15EC25EC85ED05ECF000000000000
+9C
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+5ED65EE35EDD5EDA5EDB5EE25EE15EE85EE95EEC5EF15EF35EF05EF45EF85EFE
+5F035F095F5D5F5C5F0B5F115F165F295F2D5F385F415F485F4C5F4E5F2F5F51
+5F565F575F595F615F6D5F735F775F835F825F7F5F8A5F885F915F875F9E5F99
+5F985FA05FA85FAD5FBC5FD65FFB5FE45FF85FF15FDD60B35FFF602160600000
+601960106029600E6031601B6015602B6026600F603A605A6041606A6077605F
+604A6046604D6063604360646042606C606B60596081608D60E76083609A6084
+609B60966097609260A7608B60E160B860E060D360B45FF060BD60C660B560D8
+614D6115610660F660F7610060F460FA6103612160FB60F1610D610E6147613E
+61286127614A613F613C612C6134613D614261446173617761586159615A616B
+6174616F61656171615F615D6153617561996196618761AC6194619A618A6191
+61AB61AE61CC61CA61C961F761C861C361C661BA61CB7F7961CD61E661E361F6
+61FA61F461FF61FD61FC61FE620062086209620D620C6214621B000000000000
+9D
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+621E6221622A622E6230623262336241624E625E6263625B62606268627C6282
+6289627E62926293629662D46283629462D762D162BB62CF62FF62C664D462C8
+62DC62CC62CA62C262C7629B62C9630C62EE62F163276302630862EF62F56350
+633E634D641C634F6396638E638063AB637663A3638F6389639F63B5636B0000
+636963BE63E963C063C663E363C963D263F663C4641664346406641364266436
+651D64176428640F6467646F6476644E652A6495649364A564A9648864BC64DA
+64D264C564C764BB64D864C264F164E7820964E064E162AC64E364EF652C64F6
+64F464F264FA650064FD6518651C650565246523652B65346535653765366538
+754B654865566555654D6558655E655D65726578658265838B8A659B659F65AB
+65B765C365C665C165C465CC65D265DB65D965E065E165F16772660A660365FB
+6773663566366634661C664F664466496641665E665D666466676668665F6662
+667066836688668E668966846698669D66C166B966C966BE66BC000000000000
+9E
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+66C466B866D666DA66E0663F66E666E966F066F566F7670F6716671E67266727
+9738672E673F67366741673867376746675E67606759676367646789677067A9
+677C676A678C678B67A667A1678567B767EF67B467EC67B367E967B867E467DE
+67DD67E267EE67B967CE67C667E76A9C681E684668296840684D6832684E0000
+68B3682B685968636877687F689F688F68AD6894689D689B68836AAE68B96874
+68B568A068BA690F688D687E690168CA690868D86922692668E1690C68CD68D4
+68E768D569366912690468D768E3692568F968E068EF6928692A691A69236921
+68C669796977695C6978696B6954697E696E69396974693D695969306961695E
+695D6981696A69B269AE69D069BF69C169D369BE69CE5BE869CA69DD69BB69C3
+69A76A2E699169A0699C699569B469DE69E86A026A1B69FF6B0A69F969F269E7
+6A0569B16A1E69ED6A1469EB6A0A6A126AC16A236A136A446A0C6A726A366A78
+6A476A626A596A666A486A386A226A906A8D6AA06A846AA26AA3000000000000
+9F
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+6A9786176ABB6AC36AC26AB86AB36AAC6ADE6AD16ADF6AAA6ADA6AEA6AFB6B05
+86166AFA6B126B169B316B1F6B386B3776DC6B3998EE6B476B436B496B506B59
+6B546B5B6B5F6B616B786B796B7F6B806B846B836B8D6B986B956B9E6BA46BAA
+6BAB6BAF6BB26BB16BB36BB76BBC6BC66BCB6BD36BDF6BEC6BEB6BF36BEF0000
+9EBE6C086C136C146C1B6C246C236C5E6C556C626C6A6C826C8D6C9A6C816C9B
+6C7E6C686C736C926C906CC46CF16CD36CBD6CD76CC56CDD6CAE6CB16CBE6CBA
+6CDB6CEF6CD96CEA6D1F884D6D366D2B6D3D6D386D196D356D336D126D0C6D63
+6D936D646D5A6D796D596D8E6D956FE46D856DF96E156E0A6DB56DC76DE66DB8
+6DC66DEC6DDE6DCC6DE86DD26DC56DFA6DD96DE46DD56DEA6DEE6E2D6E6E6E2E
+6E196E726E5F6E3E6E236E6B6E2B6E766E4D6E1F6E436E3A6E4E6E246EFF6E1D
+6E386E826EAA6E986EC96EB76ED36EBD6EAF6EC46EB26ED46ED56E8F6EA56EC2
+6E9F6F416F11704C6EEC6EF86EFE6F3F6EF26F316EEF6F326ECC000000000000
+E0
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+6F3E6F136EF76F866F7A6F786F816F806F6F6F5B6FF36F6D6F826F7C6F586F8E
+6F916FC26F666FB36FA36FA16FA46FB96FC66FAA6FDF6FD56FEC6FD46FD86FF1
+6FEE6FDB7009700B6FFA70117001700F6FFE701B701A6F74701D7018701F7030
+703E7032705170637099709270AF70F170AC70B870B370AE70DF70CB70DD0000
+70D9710970FD711C711971657155718871667162714C7156716C718F71FB7184
+719571A871AC71D771B971BE71D271C971D471CE71E071EC71E771F571FC71F9
+71FF720D7210721B7228722D722C72307232723B723C723F72407246724B7258
+7274727E7282728172877292729672A272A772B972B272C372C672C472CE72D2
+72E272E072E172F972F7500F7317730A731C7316731D7334732F73297325733E
+734E734F9ED87357736A7368737073787375737B737A73C873B373CE73BB73C0
+73E573EE73DE74A27405746F742573F87432743A7455743F745F74597441745C
+746974707463746A7476747E748B749E74A774CA74CF74D473F1000000000000
+E1
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+74E074E374E774E974EE74F274F074F174F874F7750475037505750C750E750D
+75157513751E7526752C753C7544754D754A7549755B7546755A756975647567
+756B756D75787576758675877574758A758975827594759A759D75A575A375C2
+75B375C375B575BD75B875BC75B175CD75CA75D275D975E375DE75FE75FF0000
+75FC760175F075FA75F275F3760B760D7609761F762776207621762276247634
+7630763B764776487646765C76587661766276687669766A7667766C76707672
+76767678767C768076837688768B768E769676937699769A76B076B476B876B9
+76BA76C276CD76D676D276DE76E176E576E776EA862F76FB7708770777047729
+7724771E77257726771B773777387747775A7768776B775B7765777F777E7779
+778E778B779177A0779E77B077B677B977BF77BC77BD77BB77C777CD77D777DA
+77DC77E377EE77FC780C781279267820792A7845788E78747886787C789A788C
+78A378B578AA78AF78D178C678CB78D478BE78BC78C578CA78EC000000000000
+E2
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+78E778DA78FD78F47907791279117919792C792B794079607957795F795A7955
+7953797A797F798A799D79A79F4B79AA79AE79B379B979BA79C979D579E779EC
+79E179E37A087A0D7A187A197A207A1F79807A317A3B7A3E7A377A437A577A49
+7A617A627A699F9D7A707A797A7D7A887A977A957A987A967AA97AC87AB00000
+7AB67AC57AC47ABF90837AC77ACA7ACD7ACF7AD57AD37AD97ADA7ADD7AE17AE2
+7AE67AED7AF07B027B0F7B0A7B067B337B187B197B1E7B357B287B367B507B7A
+7B047B4D7B0B7B4C7B457B757B657B747B677B707B717B6C7B6E7B9D7B987B9F
+7B8D7B9C7B9A7B8B7B927B8F7B5D7B997BCB7BC17BCC7BCF7BB47BC67BDD7BE9
+7C117C147BE67BE57C607C007C077C137BF37BF77C177C0D7BF67C237C277C2A
+7C1F7C377C2B7C3D7C4C7C437C547C4F7C407C507C587C5F7C647C567C657C6C
+7C757C837C907CA47CAD7CA27CAB7CA17CA87CB37CB27CB17CAE7CB97CBD7CC0
+7CC57CC27CD87CD27CDC7CE29B3B7CEF7CF27CF47CF67CFA7D06000000000000
+E3
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+7D027D1C7D157D0A7D457D4B7D2E7D327D3F7D357D467D737D567D4E7D727D68
+7D6E7D4F7D637D937D897D5B7D8F7D7D7D9B7DBA7DAE7DA37DB57DC77DBD7DAB
+7E3D7DA27DAF7DDC7DB87D9F7DB07DD87DDD7DE47DDE7DFB7DF27DE17E057E0A
+7E237E217E127E317E1F7E097E0B7E227E467E667E3B7E357E397E437E370000
+7E327E3A7E677E5D7E567E5E7E597E5A7E797E6A7E697E7C7E7B7E837DD57E7D
+8FAE7E7F7E887E897E8C7E927E907E937E947E967E8E7E9B7E9C7F387F3A7F45
+7F4C7F4D7F4E7F507F517F557F547F587F5F7F607F687F697F677F787F827F86
+7F837F887F877F8C7F947F9E7F9D7F9A7FA37FAF7FB27FB97FAE7FB67FB88B71
+7FC57FC67FCA7FD57FD47FE17FE67FE97FF37FF998DC80068004800B80128018
+8019801C80218028803F803B804A804680528058805A805F8062806880738072
+807080768079807D807F808480868085809B8093809A80AD519080AC80DB80E5
+80D980DD80C480DA80D6810980EF80F1811B81298123812F814B000000000000
+E4
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+968B8146813E8153815180FC8171816E81658166817481838188818A81808182
+81A0819581A481A3815F819381A981B081B581BE81B881BD81C081C281BA81C9
+81CD81D181D981D881C881DA81DF81E081E781FA81FB81FE8201820282058207
+820A820D821082168229822B82388233824082598258825D825A825F82640000
+82628268826A826B822E827182778278827E828D829282AB829F82BB82AC82E1
+82E382DF82D282F482F382FA8393830382FB82F982DE830682DC830982D98335
+83348316833283318340833983508345832F832B831783188385839A83AA839F
+83A283968323838E8387838A837C83B58373837583A0838983A883F4841383EB
+83CE83FD840383D8840B83C183F7840783E083F2840D8422842083BD84388506
+83FB846D842A843C855A84848477846B84AD846E848284698446842C846F8479
+843584CA846284B984BF849F84D984CD84BB84DA84D084C184C684D684A18521
+84FF84F485178518852C851F8515851484FC8540856385588548000000000000
+E5
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+85418602854B8555858085A485888591858A85A8856D8594859B85EA8587859C
+8577857E859085C985BA85CF85B985D085D585DD85E585DC85F9860A8613860B
+85FE85FA86068622861A8630863F864D4E558654865F86678671869386A386A9
+86AA868B868C86B686AF86C486C686B086C9882386AB86D486DE86E986EC0000
+86DF86DB86EF8712870687088700870386FB87118709870D86F9870A8734873F
+8737873B87258729871A8760875F8778874C874E877487578768876E87598753
+8763876A880587A2879F878287AF87CB87BD87C087D096D687AB87C487B387C7
+87C687BB87EF87F287E0880F880D87FE87F687F7880E87D28811881688158822
+88218831883688398827883B8844884288528859885E8862886B8881887E889E
+8875887D88B5887288828897889288AE889988A2888D88A488B088BF88B188C3
+88C488D488D888D988DD88F9890288FC88F488E888F28904890C890A89138943
+891E8925892A892B89418944893B89368938894C891D8960895E000000000000
+E6
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+89668964896D896A896F89748977897E89838988898A8993899889A189A989A6
+89AC89AF89B289BA89BD89BF89C089DA89DC89DD89E789F489F88A038A168A10
+8A0C8A1B8A1D8A258A368A418A5B8A528A468A488A7C8A6D8A6C8A628A858A82
+8A848AA88AA18A918AA58AA68A9A8AA38AC48ACD8AC28ADA8AEB8AF38AE70000
+8AE48AF18B148AE08AE28AF78ADE8ADB8B0C8B078B1A8AE18B168B108B178B20
+8B3397AB8B268B2B8B3E8B288B418B4C8B4F8B4E8B498B568B5B8B5A8B6B8B5F
+8B6C8B6F8B748B7D8B808B8C8B8E8B928B938B968B998B9A8C3A8C418C3F8C48
+8C4C8C4E8C508C558C628C6C8C788C7A8C828C898C858C8A8C8D8C8E8C948C7C
+8C98621D8CAD8CAA8CBD8CB28CB38CAE8CB68CC88CC18CE48CE38CDA8CFD8CFA
+8CFB8D048D058D0A8D078D0F8D0D8D109F4E8D138CCD8D148D168D678D6D8D71
+8D738D818D998DC28DBE8DBA8DCF8DDA8DD68DCC8DDB8DCB8DEA8DEB8DDF8DE3
+8DFC8E088E098DFF8E1D8E1E8E108E1F8E428E358E308E348E4A000000000000
+E7
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+8E478E498E4C8E508E488E598E648E608E2A8E638E558E768E728E7C8E818E87
+8E858E848E8B8E8A8E938E918E948E998EAA8EA18EAC8EB08EC68EB18EBE8EC5
+8EC88ECB8EDB8EE38EFC8EFB8EEB8EFE8F0A8F058F158F128F198F138F1C8F1F
+8F1B8F0C8F268F338F3B8F398F458F428F3E8F4C8F498F468F4E8F578F5C0000
+8F628F638F648F9C8F9F8FA38FAD8FAF8FB78FDA8FE58FE28FEA8FEF90878FF4
+90058FF98FFA901190159021900D901E9016900B90279036903590398FF8904F
+905090519052900E9049903E90569058905E9068906F907696A890729082907D
+90819080908A9089908F90A890AF90B190B590E290E4624890DB910291129119
+91329130914A9156915891639165916991739172918B9189918291A291AB91AF
+91AA91B591B491BA91C091C191C991CB91D091D691DF91E191DB91FC91F591F6
+921E91FF9214922C92159211925E925792459249926492489295923F924B9250
+929C92969293929B925A92CF92B992B792E9930F92FA9344932E000000000000
+E8
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+93199322931A9323933A9335933B935C9360937C936E935693B093AC93AD9394
+93B993D693D793E893E593D893C393DD93D093C893E4941A9414941394039407
+94109436942B94359421943A944194529444945B94609462945E946A92299470
+94759477947D945A947C947E9481947F95829587958A95949596959895990000
+95A095A895A795AD95BC95BB95B995BE95CA6FF695C395CD95CC95D595D495D6
+95DC95E195E595E296219628962E962F9642964C964F964B9677965C965E965D
+965F96669672966C968D96989695969796AA96A796B196B296B096B496B696B8
+96B996CE96CB96C996CD894D96DC970D96D596F99704970697089713970E9711
+970F971697199724972A97309739973D973E97449746974897429749975C9760
+97649766976852D2976B977197799785977C9781977A9786978B978F9790979C
+97A897A697A397B397B497C397C697C897CB97DC97ED9F4F97F27ADF97F697F5
+980F980C9838982498219837983D9846984F984B986B986F9870000000000000
+E9
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+98719874987398AA98AF98B198B698C498C398C698E998EB9903990999129914
+99189921991D991E99249920992C992E993D993E9942994999459950994B9951
+9952994C99559997999899A599AD99AE99BC99DF99DB99DD99D899D199ED99EE
+99F199F299FB99F89A019A0F9A0599E29A199A2B9A379A459A429A409A430000
+9A3E9A559A4D9A5B9A579A5F9A629A659A649A699A6B9A6A9AAD9AB09ABC9AC0
+9ACF9AD19AD39AD49ADE9ADF9AE29AE39AE69AEF9AEB9AEE9AF49AF19AF79AFB
+9B069B189B1A9B1F9B229B239B259B279B289B299B2A9B2E9B2F9B329B449B43
+9B4F9B4D9B4E9B519B589B749B939B839B919B969B979B9F9BA09BA89BB49BC0
+9BCA9BB99BC69BCF9BD19BD29BE39BE29BE49BD49BE19C3A9BF29BF19BF09C15
+9C149C099C139C0C9C069C089C129C0A9C049C2E9C1B9C259C249C219C309C47
+9C329C469C3E9C5A9C609C679C769C789CE79CEC9CF09D099D089CEB9D039D06
+9D2A9D269DAF9D239D1F9D449D159D129D419D3F9D3E9D469D48000000000000
+EA
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+9D5D9D5E9D649D519D509D599D729D899D879DAB9D6F9D7A9D9A9DA49DA99DB2
+9DC49DC19DBB9DB89DBA9DC69DCF9DC29DD99DD39DF89DE69DED9DEF9DFD9E1A
+9E1B9E1E9E759E799E7D9E819E889E8B9E8C9E929E959E919E9D9EA59EA99EB8
+9EAA9EAD97619ECC9ECE9ECF9ED09ED49EDC9EDE9EDD9EE09EE59EE89EEF0000
+9EF49EF69EF79EF99EFB9EFC9EFD9F079F0876B79F159F219F2C9F3E9F4A9F52
+9F549F639F5F9F609F619F669F679F6C9F6A9F779F729F769F959F9C9FA0582F
+69C79059746451DC719900000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+EB
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000F8B5F8B60000000000000000000000000000000000000000000000000000
+F8B7FE33000000000000000000000000000000000000F8B8FE31F8B900000000
+F8BAF8BBF8BCF8BDFE300000000000000000FE35FE36FE39FE3AF8BEF8BFFE37
+FE38FE3FFE40FE3DFE3EFE41FE42FE43FE44FE3BFE3C00000000000000000000
+0000F8C000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+EC
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000F8C1
+0000F8C20000F8C30000F8C40000F8C500000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000F8C600000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000F8C70000F8C80000F8C9000000000000000000000000F8CA000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+ED
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+F8CB0000F8CC0000F8CD0000F8CE0000F8CF0000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00000000F8D00000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000000000000F8D10000F8D20000F8D3000000000000000000000000F8D40000
+00000000000000000000F8D5F8D6000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
diff --git a/library/encoding/macRoman.enc b/library/encoding/macRoman.enc
new file mode 100644
index 0000000..15de266
--- /dev/null
+++ b/library/encoding/macRoman.enc
@@ -0,0 +1,20 @@
+# Encoding file: macRoman, single-byte
+S
+003F 0 1
+00
+0000000100020003000400050006000700080009000A000B000C000D000E000F
+0010001100120013001400150016001700180019001A001B001C001D001E001F
+0020002100220023002400250026002700280029002A002B002C002D002E002F
+0030003100320033003400350036003700380039003A003B003C003D003E003F
+0040004100420043004400450046004700480049004A004B004C004D004E004F
+0050005100520053005400550056005700580059005A005B005C005D005E005F
+0060006100620063006400650066006700680069006A006B006C006D006E006F
+0070007100720073007400750076007700780079007A007B007C007D007E007F
+00C400C500C700C900D100D600DC00E100E000E200E400E300E500E700E900E8
+00EA00EB00ED00EC00EE00EF00F100F300F200F400F600F500FA00F900FB00FC
+202000B000A200A300A7202200B600DF00AE00A9212200B400A8226000C600D8
+221E00B12264226500A500B522022211220F03C0222B00AA00BA03A900E600F8
+00BF00A100AC221A01922248220600AB00BB202600A000C000C300D501520153
+20132014201C201D2018201900F725CA00FF0178204420AC2039203AFB01FB02
+202100B7201A201E203000C200CA00C100CB00C800CD00CE00CF00CC00D300D4
+F8FF00D200DA00DB00D9013102C602DC00AF02D802D902DA00B802DD02DB02C7
diff --git a/library/encoding/macRomania.enc b/library/encoding/macRomania.enc
new file mode 100644
index 0000000..ce41cf4
--- /dev/null
+++ b/library/encoding/macRomania.enc
@@ -0,0 +1,20 @@
+# Encoding file: macRomania, single-byte
+S
+003F 0 1
+00
+0000000100020003000400050006000700080009000A000B000C000D000E000F
+0010001100120013001400150016001700180019001A001B001C001D001E001F
+0020002100220023002400250026002700280029002A002B002C002D002E002F
+0030003100320033003400350036003700380039003A003B003C003D003E003F
+0040004100420043004400450046004700480049004A004B004C004D004E004F
+0050005100520053005400550056005700580059005A005B005C005D005E005F
+0060006100620063006400650066006700680069006A006B006C006D006E006F
+0070007100720073007400750076007700780079007A007B007C007D007E007F
+00C400C500C700C900D100D600DC00E100E000E200E400E300E500E700E900E8
+00EA00EB00ED00EC00EE00EF00F100F300F200F400F600F500FA00F900FB00FC
+202000B000A200A300A7202200B600DF00AE00A9212200B400A822600102015E
+221E00B12264226500A500B522022211220F03C0222B00AA00BA21260103015F
+00BF00A100AC221A01922248220600AB00BB202600A000C000C300D501520153
+20132014201C201D2018201900F725CA00FF0178204400A42039203A01620163
+202100B7201A201E203000C200CA00C100CB00C800CD00CE00CF00CC00D300D4
+F8FF00D200DA00DB00D9013102C602DC00AF02D802D902DA00B802DD02DB02C7
diff --git a/library/encoding/macThai.enc b/library/encoding/macThai.enc
new file mode 100644
index 0000000..7d9c8ad
--- /dev/null
+++ b/library/encoding/macThai.enc
@@ -0,0 +1,20 @@
+# Encoding file: macThai, single-byte
+S
+003F 0 1
+00
+0000000100020003000400050006000700080009000A000B000C000D000E000F
+0010001100120013001400150016001700180019001A001B001C001D001E001F
+0020002100220023002400250026002700280029002A002B002C002D002E002F
+0030003100320033003400350036003700380039003A003B003C003D003E003F
+0040004100420043004400450046004700480049004A004B004C004D004E004F
+0050005100520053005400550056005700580059005A005B005C005D005E005F
+0060006100620063006400650066006700680069006A006B006C006D006E006F
+0070007100720073007400750076007700780079007A007B007C007D007E007F
+00AB00BB2026F88CF88FF892F895F898F88BF88EF891F894F897201C201DF899
+FFFD2022F884F889F885F886F887F888F88AF88DF890F893F89620182019FFFD
+00A00E010E020E030E040E050E060E070E080E090E0A0E0B0E0C0E0D0E0E0E0F
+0E100E110E120E130E140E150E160E170E180E190E1A0E1B0E1C0E1D0E1E0E1F
+0E200E210E220E230E240E250E260E270E280E290E2A0E2B0E2C0E2D0E2E0E2F
+0E300E310E320E330E340E350E360E370E380E390E3AFEFF200B201320140E3F
+0E400E410E420E430E440E450E460E470E480E490E4A0E4B0E4C0E4D21220E4F
+0E500E510E520E530E540E550E560E570E580E5900AE00A9FFFDFFFDFFFDFFFD
diff --git a/library/encoding/macTurkish.enc b/library/encoding/macTurkish.enc
new file mode 100644
index 0000000..f9542ae
--- /dev/null
+++ b/library/encoding/macTurkish.enc
@@ -0,0 +1,20 @@
+# Encoding file: macTurkish, single-byte
+S
+003F 0 1
+00
+0000000100020003000400050006000700080009000A000B000C000D000E000F
+0010001100120013001400150016001700180019001A001B001C001D001E001F
+0020002100220023002400250026002700280029002A002B002C002D002E002F
+0030003100320033003400350036003700380039003A003B003C003D003E003F
+0040004100420043004400450046004700480049004A004B004C004D004E004F
+0050005100520053005400550056005700580059005A005B005C005D005E005F
+0060006100620063006400650066006700680069006A006B006C006D006E006F
+0070007100720073007400750076007700780079007A007B007C007D007E007F
+00C400C500C700C900D100D600DC00E100E000E200E400E300E500E700E900E8
+00EA00EB00ED00EC00EE00EF00F100F300F200F400F600F500FA00F900FB00FC
+202000B000A200A300A7202200B600DF00AE00A9212200B400A8226000C600D8
+221E00B12264226500A500B522022211220F03C0222B00AA00BA03A900E600F8
+00BF00A100AC221A01922248220600AB00BB202600A000C000C300D501520153
+20132014201C201D2018201900F725CA00FF0178011E011F01300131015E015F
+202100B7201A201E203000C200CA00C100CB00C800CD00CE00CF00CC00D300D4
+F8FF00D200DA00DB00D9F8A002C602DC00AF02D802D902DA00B802DD02DB02C7
diff --git a/library/encoding/macUkraine.enc b/library/encoding/macUkraine.enc
new file mode 100644
index 0000000..643cc45
--- /dev/null
+++ b/library/encoding/macUkraine.enc
@@ -0,0 +1,20 @@
+# Encoding file: macUkraine, single-byte
+S
+003F 0 1
+00
+0000000100020003000400050006000700080009000A000B000C000D000E000F
+0010001100120013001400150016001700180019001A001B001C001D001E001F
+0020002100220023002400250026002700280029002A002B002C002D002E002F
+0030003100320033003400350036003700380039003A003B003C003D003E003F
+0040004100420043004400450046004700480049004A004B004C004D004E004F
+0050005100520053005400550056005700580059005A005B005C005D005E005F
+0060006100620063006400650066006700680069006A006B006C006D006E006F
+0070007100720073007400750076007700780079007A007B007C007D007E007F
+0410041104120413041404150416041704180419041A041B041C041D041E041F
+0420042104220423042404250426042704280429042A042B042C042D042E042F
+202000B0049000A300A7202200B6040600AE00A9212204020452226004030453
+221E00B122642265045600B504910408040404540407045704090459040A045A
+0458040500AC221A01922248220600AB00BB202600A0040B045B040C045C0455
+20132014201C201D2018201900F7201E040E045E040F045F211604010451044F
+0430043104320433043404350436043704380439043A043B043C043D043E043F
+0440044104420443044404450446044704480449044A044B044C044D044E00A4
diff --git a/library/encoding/shiftjis.enc b/library/encoding/shiftjis.enc
new file mode 100644
index 0000000..140aec4
--- /dev/null
+++ b/library/encoding/shiftjis.enc
@@ -0,0 +1,690 @@
+# Encoding file: shiftjis, multi-byte
+M
+003F 0 40
+00
+0000000100020003000400050006000700080009000A000B000C000D000E000F
+0010001100120013001400150016001700180019001A001B001C001D001E001F
+0020002100220023002400250026002700280029002A002B002C002D002E002F
+0030003100320033003400350036003700380039003A003B003C003D003E003F
+0040004100420043004400450046004700480049004A004B004C004D004E004F
+0050005100520053005400550056005700580059005A005B005C005D005E005F
+0060006100620063006400650066006700680069006A006B006C006D006E006F
+0070007100720073007400750076007700780079007A007B007C007D007E007F
+0080000000000000000000850086008700000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000FF61FF62FF63FF64FF65FF66FF67FF68FF69FF6AFF6BFF6CFF6DFF6EFF6F
+FF70FF71FF72FF73FF74FF75FF76FF77FF78FF79FF7AFF7BFF7CFF7DFF7EFF7F
+FF80FF81FF82FF83FF84FF85FF86FF87FF88FF89FF8AFF8BFF8CFF8DFF8EFF8F
+FF90FF91FF92FF93FF94FF95FF96FF97FF98FF99FF9AFF9BFF9CFF9DFF9EFF9F
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+81
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+300030013002FF0CFF0E30FBFF1AFF1BFF1FFF01309B309C00B4FF4000A8FF3E
+FFE3FF3F30FD30FE309D309E30034EDD30053006300730FC20152010FF0FFF3C
+301C2016FF5C2026202520182019201C201DFF08FF0930143015FF3BFF3DFF5B
+FF5D30083009300A300B300C300D300E300F30103011FF0B221200B100D70000
+00F7FF1D2260FF1CFF1E22662267221E22342642264000B0203220332103FFE5
+FF0400A200A3FF05FF03FF06FF0AFF2000A72606260525CB25CF25CE25C725C6
+25A125A025B325B225BD25BC203B301221922190219121933013000000000000
+000000000000000000000000000000002208220B2286228722822283222A2229
+000000000000000000000000000000002227222800AC21D221D4220022030000
+0000000000000000000000000000000000000000222022A52312220222072261
+2252226A226B221A223D221D2235222B222C0000000000000000000000000000
+212B2030266F266D266A2020202100B6000000000000000025EF000000000000
+82
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+000000000000000000000000000000000000000000000000000000000000FF10
+FF11FF12FF13FF14FF15FF16FF17FF18FF190000000000000000000000000000
+FF21FF22FF23FF24FF25FF26FF27FF28FF29FF2AFF2BFF2CFF2DFF2EFF2FFF30
+FF31FF32FF33FF34FF35FF36FF37FF38FF39FF3A000000000000000000000000
+0000FF41FF42FF43FF44FF45FF46FF47FF48FF49FF4AFF4BFF4CFF4DFF4EFF4F
+FF50FF51FF52FF53FF54FF55FF56FF57FF58FF59FF5A00000000000000003041
+30423043304430453046304730483049304A304B304C304D304E304F30503051
+30523053305430553056305730583059305A305B305C305D305E305F30603061
+30623063306430653066306730683069306A306B306C306D306E306F30703071
+30723073307430753076307730783079307A307B307C307D307E307F30803081
+30823083308430853086308730883089308A308B308C308D308E308F30903091
+3092309300000000000000000000000000000000000000000000000000000000
+83
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+30A130A230A330A430A530A630A730A830A930AA30AB30AC30AD30AE30AF30B0
+30B130B230B330B430B530B630B730B830B930BA30BB30BC30BD30BE30BF30C0
+30C130C230C330C430C530C630C730C830C930CA30CB30CC30CD30CE30CF30D0
+30D130D230D330D430D530D630D730D830D930DA30DB30DC30DD30DE30DF0000
+30E030E130E230E330E430E530E630E730E830E930EA30EB30EC30ED30EE30EF
+30F030F130F230F330F430F530F6000000000000000000000000000000000391
+03920393039403950396039703980399039A039B039C039D039E039F03A003A1
+03A303A403A503A603A703A803A90000000000000000000000000000000003B1
+03B203B303B403B503B603B703B803B903BA03BB03BC03BD03BE03BF03C003C1
+03C303C403C503C603C703C803C9000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+84
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+04100411041204130414041504010416041704180419041A041B041C041D041E
+041F0420042104220423042404250426042704280429042A042B042C042D042E
+042F000000000000000000000000000000000000000000000000000000000000
+04300431043204330434043504510436043704380439043A043B043C043D0000
+043E043F0440044104420443044404450446044704480449044A044B044C044D
+044E044F00000000000000000000000000000000000000000000000000002500
+2502250C251025182514251C252C25242534253C25012503250F2513251B2517
+25232533252B253B254B2520252F25282537253F251D25302525253825420000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+88
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000004E9C
+55165A03963F54C0611B632859F690228475831C7A5060AA63E16E2565ED8466
+82A69BF56893572765A162715B9B59D0867B98F47D627DBE9B8E62167C9F88B7
+5B895EB563096697684895C7978D674F4EE54F0A4F4D4F9D504956F2593759D4
+5A015C0960DF610F61706613690570BA754F757079FB7DAD7DEF80C3840E8863
+8B029055907A533B4E954EA557DF80B290C178EF4E0058F16EA290387A328328
+828B9C2F5141537054BD54E156E059FB5F1598F26DEB80E4852D000000000000
+89
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+9662967096A097FB540B53F35B8770CF7FBD8FC296E8536F9D5C7ABA4E117893
+81FC6E26561855046B1D851A9C3B59E553A96D6674DC958F56424E91904B96F2
+834F990C53E155B65B305F71662066F368046C386CF36D29745B76C87A4E9834
+82F1885B8A6092ED6DB275AB76CA99C560A68B018D8A95B2698E53AD51860000
+5712583059445BB45EF6602863A963F46CBF6F14708E7114715971D5733F7E01
+827682D185979060925B9D1B586965BC6C5A752551F9592E59655F805FDC62BC
+65FA6A2A6B276BB4738B7FC189569D2C9D0E9EC45CA16C96837B51045C4B61B6
+81C6687672614E594FFA537860696E297A4F97F34E0B53164EEE4F554F3D4FA1
+4F7352A053EF5609590F5AC15BB65BE179D16687679C67B66B4C6CB3706B73C2
+798D79BE7A3C7B8782B182DB8304837783EF83D387668AB256298CA88FE6904E
+971E868A4FC45CE862117259753B81E582BD86FE8CC096C5991399D54ECB4F1A
+89E356DE584A58CA5EFB5FEB602A6094606261D0621262D06539000000000000
+8A
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+9B41666668B06D777070754C76867D7582A587F9958B968E8C9D51F152BE5916
+54B35BB35D16616869826DAF788D84CB88578A7293A79AB86D6C99A886D957A3
+67FF86CE920E5283568754045ED362E164B9683C68386BBB737278BA7A6B899A
+89D28D6B8F0390ED95A3969497695B665CB3697D984D984E639B7B206A2B0000
+6A7F68B69C0D6F5F5272559D607062EC6D3B6E076ED1845B89108F444E149C39
+53F6691B6A3A9784682A515C7AC384B291DC938C565B9D286822830584317CA5
+520882C574E64E7E4F8351A05BD2520A52D852E75DFB559A582A59E65B8C5B98
+5BDB5E725E7960A3611F616361BE63DB656267D1685368FA6B3E6B536C576F22
+6F976F4574B0751876E3770B7AFF7BA17C217DE97F367FF0809D8266839E89B3
+8ACC8CAB908494519593959195A2966597D3992882184E38542B5CB85DCC73A9
+764C773C5CA97FEB8D0B96C19811985498584F014F0E5371559C566857FA5947
+5B095BC45C905E0C5E7E5FCC63EE673A65D765E2671F68CB68C4000000000000
+8B
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+6A5F5E306BC56C176C7D757F79485B637A007D005FBD898F8A188CB48D778ECC
+8F1D98E29A0E9B3C4E80507D510059935B9C622F628064EC6B3A72A075917947
+7FA987FB8ABC8B7063AC83CA97A05409540355AB68546A588A70782767759ECD
+53745BA2811A865090064E184E454EC74F1153CA54385BAE5F13602565510000
+673D6C426C726CE3707874037A767AAE7B087D1A7CFE7D6665E7725B53BB5C45
+5DE862D262E063196E20865A8A318DDD92F86F0179A69B5A4EA84EAB4EAC4F9B
+4FA050D151477AF6517151F653545321537F53EB55AC58835CE15F375F4A602F
+6050606D631F65596A4B6CC172C272ED77EF80F881058208854E90F793E197FF
+99579A5A4EF051DD5C2D6681696D5C4066F26975738968507C8150C552E45747
+5DFE932665A46B236B3D7434798179BD7B4B7DCA82B983CC887F895F8B398FD1
+91D1541F92804E5D503653E5533A72D7739677E982E68EAF99C699C899D25177
+611A865E55B07A7A50765BD3904796854E326ADB91E75C515C48000000000000
+8C
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+63987A9F6C9397748F617AAA718A96887C8268177E706851936C52F2541B85AB
+8A137FA48ECD90E15366888879414FC250BE521151445553572D73EA578B5951
+5F625F8460756176616761A963B2643A656C666F68426E1375667A3D7CFB7D4C
+7D997E4B7F6B830E834A86CD8A088A638B668EFD981A9D8F82B88FCE9BE80000
+5287621F64836FC09699684150916B206C7A6F547A747D5088408A2367084EF6
+503950265065517C5238526355A7570F58055ACC5EFA61B261F862F36372691C
+6A29727D72AC732E7814786F7D79770C80A9898B8B198CE28ED290639375967A
+98559A139E785143539F53B35E7B5F266E1B6E90738473FE7D4382378A008AFA
+96504E4E500B53E4547C56FA59D15B645DF15EAB5F276238654567AF6E5672D0
+7CCA88B480A180E183F0864E8A878DE8923796C798679F134E944E924F0D5348
+5449543E5A2F5F8C5FA1609F68A76A8E745A78818A9E8AA48B7791904E5E9BC9
+4EA44F7C4FAF501950165149516C529F52B952FE539A53E35411000000000000
+8D
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+540E5589575157A2597D5B545B5D5B8F5DE55DE75DF75E785E835E9A5EB75F18
+6052614C629762D863A7653B6602664366F4676D6821689769CB6C5F6D2A6D69
+6E2F6E9D75327687786C7A3F7CE07D057D187D5E7DB18015800380AF80B18154
+818F822A8352884C88618B1B8CA28CFC90CA91759271783F92FC95A4964D0000
+980599999AD89D3B525B52AB53F7540858D562F76FE08C6A8F5F9EB9514B523B
+544A56FD7A4091779D609ED273446F09817075115FFD60DA9AA872DB8FBC6B64
+98034ECA56F0576458BE5A5A606861C7660F6606683968B16DF775D57D3A826E
+9B424E9B4F5053C955065D6F5DE65DEE67FB6C99747378028A50939688DF5750
+5EA7632B50B550AC518D670054C9585E59BB5BB05F69624D63A1683D6B736E08
+707D91C7728078157826796D658E7D3083DC88C18F09969B5264572867507F6A
+8CA151B45742962A583A698A80B454B25D0E57FC78959DFA4F5C524A548B643E
+6628671467F57A847B567D22932F685C9BAD7B395319518A5237000000000000
+8E
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+5BDF62F664AE64E6672D6BBA85A996D176909BD6634C93069BAB76BF66524E09
+509853C25C7160E864926563685F71E673CA75237B977E8286958B838CDB9178
+991065AC66AB6B8B4ED54ED44F3A4F7F523A53F853F255E356DB58EB59CB59C9
+59FF5B505C4D5E025E2B5FD7601D6307652F5B5C65AF65BD65E8679D6B620000
+6B7B6C0F7345794979C17CF87D197D2B80A2810281F389968A5E8A698A668A8C
+8AEE8CC78CDC96CC98FC6B6F4E8B4F3C4F8D51505B575BFA6148630166426B21
+6ECB6CBB723E74BD75D478C1793A800C803381EA84948F9E6C509E7F5F0F8B58
+9D2B7AFA8EF85B8D96EB4E0353F157F759315AC95BA460896E7F6F0675BE8CEA
+5B9F85007BE0507267F4829D5C61854A7E1E820E51995C0463688D66659C716E
+793E7D1780058B1D8ECA906E86C790AA501F52FA5C3A6753707C7235914C91C8
+932B82E55BC25F3160F94E3B53D65B88624B67316B8A72E973E07A2E816B8DA3
+91529996511253D7546A5BFF63886A397DAC970056DA53CE5468000000000000
+8F
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+5B975C315DDE4FEE610162FE6D3279C079CB7D427E4D7FD281ED821F84908846
+89728B908E748F2F9031914B916C96C6919C4EC04F4F514553415F93620E67D4
+6C416E0B73637E2691CD928353D459195BBF6DD1795D7E2E7C9B587E719F51FA
+88538FF04FCA5CFB662577AC7AE3821C99FF51C65FAA65EC696F6B896DF30000
+6E966F6476FE7D145DE190759187980651E6521D6240669166D96E1A5EB67DD2
+7F7266F885AF85F78AF852A953D959735E8F5F90605592E4966450B7511F52DD
+5320534753EC54E8554655315617596859BE5A3C5BB55C065C0F5C115C1A5E84
+5E8A5EE05F70627F628462DB638C63776607660C662D6676677E68A26A1F6A35
+6CBC6D886E096E58713C7126716775C77701785D7901796579F07AE07B117CA7
+7D39809683D6848B8549885D88F38A1F8A3C8A548A738C618CDE91A49266937E
+9418969C97984E0A4E084E1E4E575197527057CE583458CC5B225E3860C564FE
+676167566D4472B675737A6384B88B7291B89320563157F498FE000000000000
+90
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+62ED690D6B9671ED7E548077827289E698DF87558FB15C3B4F384FE14FB55507
+5A205BDD5BE95FC3614E632F65B0664B68EE699B6D786DF1753375B9771F795E
+79E67D3381E382AF85AA89AA8A3A8EAB8F9B903291DD97074EBA4EC152035875
+58EC5C0B751A5C3D814E8A0A8FC59663976D7B258ACF9808916256F353A80000
+9017543957825E2563A86C34708A77617C8B7FE088709042915493109318968F
+745E9AC45D075D69657067A28DA896DB636E6749691983C5981796C088FE6F84
+647A5BF84E16702C755D662F51C4523652E259D35F8160276210653F6574661F
+667468F268166B636E057272751F76DB7CBE805658F088FD897F8AA08A938ACB
+901D91929752975965897A0E810696BB5E2D60DC621A65A56614679077F37A4D
+7C4D7E3E810A8CAC8D648DE18E5F78A9520762D963A5644262988A2D7A837BC0
+8AAC96EA7D76820C87494ED95148534353605BA35C025C165DDD6226624764B0
+681368346CC96D456D1767D36F5C714E717D65CB7A7F7BAD7DDA000000000000
+91
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+7E4A7FA8817A821B823985A68A6E8CCE8DF59078907792AD929195839BAE524D
+55846F387136516879857E5581B37CCE564C58515CA863AA66FE66FD695A72D9
+758F758E790E795679DF7C977D207D4486078A34963B90619F2050E7527553CC
+53E2500955AA58EE594F723D5B8B5C64531D60E360F3635C6383633F63BB0000
+64CD65E966F95DE369CD69FD6F1571E54E8975E976F87A937CDF7DCF7D9C8061
+83498358846C84BC85FB88C58D709001906D9397971C9A1250CF5897618E81D3
+85358D0890204FC3507452475373606F6349675F6E2C8DB3901F4FD75C5E8CCA
+65CF7D9A53528896517663C35B585B6B5C0A640D6751905C4ED6591A592A6C70
+8A51553E581559A560F0625367C182356955964099C49A284F5358065BFE8010
+5CB15E2F5F856020614B623466FF6CF06EDE80CE817F82D4888B8CB89000902E
+968A9EDB9BDB4EE353F059277B2C918D984C9DF96EDD7027535355445B856258
+629E62D36CA26FEF74228A1794386FC18AFE833851E786F853EA000000000000
+92
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+53E94F4690548FB0596A81315DFD7AEA8FBF68DA8C3772F89C486A3D8AB04E39
+53585606576662C563A265E66B4E6DE16E5B70AD77ED7AEF7BAA7DBB803D80C6
+86CB8A95935B56E358C75F3E65AD66966A806BB575378AC7502477E557305F1B
+6065667A6C6075F47A1A7F6E81F48718904599B37BC9755C7AF97B5184C40000
+901079E97A9283365AE177404E2D4EF25B995FE062BD663C67F16CE8866B8877
+8A3B914E92F399D06A177026732A82E784578CAF4E01514651CB558B5BF55E16
+5E335E815F145F355F6B5FB461F2631166A2671D6F6E7252753A773A80748139
+817887768ABF8ADC8D858DF3929A957798029CE552C5635776F467156C8873CD
+8CC393AE96736D25589C690E69CC8FFD939A75DB901A585A680263B469FB4F43
+6F2C67D88FBB85267DB49354693F6F70576A58F75B2C7D2C722A540A91E39DB4
+4EAD4F4E505C507552438C9E544858245B9A5E1D5E955EAD5EF75F1F608C62B5
+633A63D068AF6C407887798E7A0B7DE082478A028AE68E449013000000000000
+93
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+90B8912D91D89F0E6CE5645864E265756EF476847B1B906993D16EBA54F25FB9
+64A48F4D8FED92445178586B59295C555E976DFB7E8F751C8CBC8EE2985B70B9
+4F1D6BBF6FB1753096FB514E54105835585759AC5C605F926597675C6E21767B
+83DF8CED901490FD934D7825783A52AA5EA6571F597460125012515A51AC0000
+51CD520055105854585859575B955CF65D8B60BC6295642D6771684368BC68DF
+76D76DD86E6F6D9B706F71C85F5375D879777B497B547B527CD67D7152308463
+856985E48A0E8B048C468E0F9003900F94199676982D9A3095D850CD52D5540C
+58025C0E61A7649E6D1E77B37AE580F48404905392855CE09D07533F5F975FB3
+6D9C7279776379BF7BE46BD272EC8AAD68036A6151F87A8169345C4A9CF682EB
+5BC59149701E56785C6F60C765666C8C8C5A90419813545166C7920D594890A3
+51854E4D51EA85998B0E7058637A934B696299B47E047577535769608EDF96E3
+6C5D4E8C5C3C5F108FE953028CD1808986795EFF65E54E735165000000000000
+94
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+59825C3F97EE4EFB598A5FCD8A8D6FE179B079625BE78471732B71B15E745FF5
+637B649A71C37C984E435EFC4E4B57DC56A260A96FC37D0D80FD813381BF8FB2
+899786A45DF4628A64AD898767776CE26D3E743678345A467F7582AD99AC4FF3
+5EC362DD63926557676F76C3724C80CC80BA8F29914D500D57F95A9268850000
+6973716472FD8CB758F28CE0966A9019877F79E477E784294F2F5265535A62CD
+67CF6CCA767D7B947C95823685848FEB66DD6F2072067E1B83AB99C19EA651FD
+7BB178727BB880877B486AE85E61808C75517560516B92626E8C767A91979AEA
+4F107F70629C7B4F95A59CE9567A585986E496BC4F345224534A53CD53DB5E06
+642C6591677F6C3E6C4E724872AF73ED75547E41822C85E98CA97BC491C67169
+981298EF633D6669756A76E478D0854386EE532A5351542659835E875F7C60B2
+6249627962AB65906BD46CCC75B276AE789179D87DCB7F7780A588AB8AB98CBB
+907F975E98DB6A0B7C3850995C3E5FAE67876BD8743577097F8E000000000000
+95
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+9F3B67CA7A175339758B9AED5F66819D83F180985F3C5FC575627B46903C6867
+59EB5A9B7D10767E8B2C4FF55F6A6A196C376F0274E2796888688A558C795EDF
+63CF75C579D282D7932892F2849C86ED9C2D54C15F6C658C6D5C70158CA78CD3
+983B654F74F64E0D4ED857E0592B5A665BCC51A85E035E9C6016627665770000
+65A7666E6D6E72367B268150819A82998B5C8CA08CE68D74961C96444FAE64AB
+6B66821E8461856A90E85C01695398A8847A85574F0F526F5FA95E45670D798F
+8179890789866DF55F1762556CB84ECF72699B925206543B567458B361A4626E
+711A596E7C897CDE7D1B96F06587805E4E194F75517558405E635E735F0A67C4
+4E26853D9589965B7C73980150FB58C1765678A7522577A585117B86504F5909
+72477BC77DE88FBA8FD4904D4FBF52C95A295F0197AD4FDD821792EA57036355
+6B69752B88DC8F147A4252DF58936155620A66AE6BCD7C3F83E950234FF85305
+5446583159495B9D5CF05CEF5D295E9662B16367653E65B9670B000000000000
+96
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+6CD56CE170F978327E2B80DE82B3840C84EC870289128A2A8C4A90A692D298FD
+9CF39D6C4E4F4EA1508D5256574A59A85E3D5FD85FD9623F66B4671B67D068D2
+51927D2180AA81A88B008C8C8CBF927E96325420982C531750D5535C58A864B2
+6734726777667A4691E652C36CA16B8658005E4C5954672C7FFB51E176C60000
+646978E89B549EBB57CB59B96627679A6BCE54E969D95E55819C67959BAA67FE
+9C52685D4EA64FE353C862B9672B6CAB8FC44FAD7E6D9EBF4E0761626E806F2B
+85135473672A9B455DF37B955CAC5BC6871C6E4A84D17A14810859997C8D6C11
+772052D959227121725F77DB97279D61690B5A7F5A1851A5540D547D660E76DF
+8FF792989CF459EA725D6EC5514D68C97DBF7DEC97629EBA64786A2183025984
+5B5F6BDB731B76F27DB280178499513267289ED976EE676252FF99055C24623B
+7C7E8CB0554F60B67D0B958053014E5F51B6591C723A803691CE5F2577E25384
+5F797D0485AC8A338E8D975667F385AE9453610961086CB9765200000000FF5E
+97
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+8AED8F38552F4F51512A52C753CB5BA55E7D60A0618263D6670967DA6E676D8C
+733673377531795088D58A98904A909190F596C4878D59154E884F594E0E8A89
+8F3F981050AD5E7C59965BB95EB863DA63FA64C166DC694A69D86D0B6EB67194
+75287AAF7F8A8000844984C989818B218E0A9065967D990A617E62916B320000
+6C836D747FCC7FFC6DC07F8587BA88F8676583B1983C96F76D1B7D61843D916A
+4E7153755D506B046FEB85CD862D89A75229540F5C65674E68A87406748375E2
+88CF88E191CC96E296785F8B73877ACB844E63A0756552896D416E9C74097559
+786B7C9296867ADC9F8D4FB6616E65C5865C4E864EAE50DA4E2151CC5BEE6599
+68816DBC731F764277AD7A1C7CE7826F8AD2907C91CF96759818529B7DD1502B
+539867976DCB71D0743381E88F2A96A39C579E9F746058416D997D2F985E4EE4
+4F364F8B51B752B15DBA601C73B2793C82D3923496B796F6970A9E979F6266A6
+6B74521752A370C888C25EC9604B61906F2371497C3E7DF4806F000000000000
+98
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+84EE9023932C54429B6F6AD370898CC28DEF973252B45A415ECA5F046717697C
+69946D6A6F0F726272FC7BED8001807E874B90CE516D9E937984808B93328AD6
+502D548C8A716B6A8CC4810760D167A09DF24E994E989C108A6B85C185686900
+6E7E789781550000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000005F0C
+4E104E154E2A4E314E364E3C4E3F4E424E564E584E824E858C6B4E8A82125F0D
+4E8E4E9E4E9F4EA04EA24EB04EB34EB64ECE4ECD4EC44EC64EC24ED74EDE4EED
+4EDF4EF74F094F5A4F304F5B4F5D4F574F474F764F884F8F4F984F7B4F694F70
+4F914F6F4F864F9651184FD44FDF4FCE4FD84FDB4FD14FDA4FD04FE44FE5501A
+50285014502A502550054F1C4FF650215029502C4FFE4FEF5011500650435047
+6703505550505048505A5056506C50785080509A508550B450B2000000000000
+99
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+50C950CA50B350C250D650DE50E550ED50E350EE50F950F55109510151025116
+51155114511A5121513A5137513C513B513F51405152514C515451627AF85169
+516A516E5180518256D8518C5189518F519151935195519651A451A651A251A9
+51AA51AB51B351B151B251B051B551BD51C551C951DB51E0865551E951ED0000
+51F051F551FE5204520B5214520E5227522A522E52335239524F5244524B524C
+525E5254526A527452695273527F527D528D529452925271528852918FA88FA7
+52AC52AD52BC52B552C152CD52D752DE52E352E698ED52E052F352F552F852F9
+530653087538530D5310530F5315531A5323532F533153335338534053465345
+4E175349534D51D6535E5369536E5918537B53775382539653A053A653A553AE
+53B053B653C37C1296D953DF66FC71EE53EE53E853ED53FA5401543D5440542C
+542D543C542E54365429541D544E548F5475548E545F5471547754705492547B
+5480547654845490548654C754A254B854A554AC54C454C854A8000000000000
+9A
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+54AB54C254A454BE54BC54D854E554E6550F551454FD54EE54ED54FA54E25539
+55405563554C552E555C55455556555755385533555D5599558054AF558A559F
+557B557E5598559E55AE557C558355A9558755A855DA55C555DF55C455DC55E4
+55D4561455F7561655FE55FD561B55F9564E565071DF56345636563256380000
+566B5664562F566C566A56865680568A56A05694568F56A556AE56B656B456C2
+56BC56C156C356C056C856CE56D156D356D756EE56F9570056FF570457095708
+570B570D57135718571655C7571C572657375738574E573B5740574F576957C0
+57885761577F5789579357A057B357A457AA57B057C357C657D457D257D3580A
+57D657E3580B5819581D587258215862584B58706BC05852583D5879588558B9
+589F58AB58BA58DE58BB58B858AE58C558D358D158D758D958D858E558DC58E4
+58DF58EF58FA58F958FB58FC58FD5902590A5910591B68A65925592C592D5932
+5938593E7AD259555950594E595A5958596259605967596C5969000000000000
+9B
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+59785981599D4F5E4FAB59A359B259C659E859DC598D59D959DA5A255A1F5A11
+5A1C5A095A1A5A405A6C5A495A355A365A625A6A5A9A5ABC5ABE5ACB5AC25ABD
+5AE35AD75AE65AE95AD65AFA5AFB5B0C5B0B5B165B325AD05B2A5B365B3E5B43
+5B455B405B515B555B5A5B5B5B655B695B705B735B755B7865885B7A5B800000
+5B835BA65BB85BC35BC75BC95BD45BD05BE45BE65BE25BDE5BE55BEB5BF05BF6
+5BF35C055C075C085C0D5C135C205C225C285C385C395C415C465C4E5C535C50
+5C4F5B715C6C5C6E4E625C765C795C8C5C915C94599B5CAB5CBB5CB65CBC5CB7
+5CC55CBE5CC75CD95CE95CFD5CFA5CED5D8C5CEA5D0B5D155D175D5C5D1F5D1B
+5D115D145D225D1A5D195D185D4C5D525D4E5D4B5D6C5D735D765D875D845D82
+5DA25D9D5DAC5DAE5DBD5D905DB75DBC5DC95DCD5DD35DD25DD65DDB5DEB5DF2
+5DF55E0B5E1A5E195E115E1B5E365E375E445E435E405E4E5E575E545E5F5E62
+5E645E475E755E765E7A9EBC5E7F5EA05EC15EC25EC85ED05ECF000000000000
+9C
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+5ED65EE35EDD5EDA5EDB5EE25EE15EE85EE95EEC5EF15EF35EF05EF45EF85EFE
+5F035F095F5D5F5C5F0B5F115F165F295F2D5F385F415F485F4C5F4E5F2F5F51
+5F565F575F595F615F6D5F735F775F835F825F7F5F8A5F885F915F875F9E5F99
+5F985FA05FA85FAD5FBC5FD65FFB5FE45FF85FF15FDD60B35FFF602160600000
+601960106029600E6031601B6015602B6026600F603A605A6041606A6077605F
+604A6046604D6063604360646042606C606B60596081608D60E76083609A6084
+609B60966097609260A7608B60E160B860E060D360B45FF060BD60C660B560D8
+614D6115610660F660F7610060F460FA6103612160FB60F1610D610E6147613E
+61286127614A613F613C612C6134613D614261446173617761586159615A616B
+6174616F61656171615F615D6153617561996196618761AC6194619A618A6191
+61AB61AE61CC61CA61C961F761C861C361C661BA61CB7F7961CD61E661E361F6
+61FA61F461FF61FD61FC61FE620062086209620D620C6214621B000000000000
+9D
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+621E6221622A622E6230623262336241624E625E6263625B62606268627C6282
+6289627E62926293629662D46283629462D762D162BB62CF62FF62C664D462C8
+62DC62CC62CA62C262C7629B62C9630C62EE62F163276302630862EF62F56350
+633E634D641C634F6396638E638063AB637663A3638F6389639F63B5636B0000
+636963BE63E963C063C663E363C963D263F663C4641664346406641364266436
+651D64176428640F6467646F6476644E652A6495649364A564A9648864BC64DA
+64D264C564C764BB64D864C264F164E7820964E064E162AC64E364EF652C64F6
+64F464F264FA650064FD6518651C650565246523652B65346535653765366538
+754B654865566555654D6558655E655D65726578658265838B8A659B659F65AB
+65B765C365C665C165C465CC65D265DB65D965E065E165F16772660A660365FB
+6773663566366634661C664F664466496641665E665D666466676668665F6662
+667066836688668E668966846698669D66C166B966C966BE66BC000000000000
+9E
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+66C466B866D666DA66E0663F66E666E966F066F566F7670F6716671E67266727
+9738672E673F67366741673867376746675E67606759676367646789677067A9
+677C676A678C678B67A667A1678567B767EF67B467EC67B367E967B867E467DE
+67DD67E267EE67B967CE67C667E76A9C681E684668296840684D6832684E0000
+68B3682B685968636877687F689F688F68AD6894689D689B68836AAE68B96874
+68B568A068BA690F688D687E690168CA690868D86922692668E1690C68CD68D4
+68E768D569366912690468D768E3692568F968E068EF6928692A691A69236921
+68C669796977695C6978696B6954697E696E69396974693D695969306961695E
+695D6981696A69B269AE69D069BF69C169D369BE69CE5BE869CA69DD69BB69C3
+69A76A2E699169A0699C699569B469DE69E86A026A1B69FF6B0A69F969F269E7
+6A0569B16A1E69ED6A1469EB6A0A6A126AC16A236A136A446A0C6A726A366A78
+6A476A626A596A666A486A386A226A906A8D6AA06A846AA26AA3000000000000
+9F
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+6A9786176ABB6AC36AC26AB86AB36AAC6ADE6AD16ADF6AAA6ADA6AEA6AFB6B05
+86166AFA6B126B169B316B1F6B386B3776DC6B3998EE6B476B436B496B506B59
+6B546B5B6B5F6B616B786B796B7F6B806B846B836B8D6B986B956B9E6BA46BAA
+6BAB6BAF6BB26BB16BB36BB76BBC6BC66BCB6BD36BDF6BEC6BEB6BF36BEF0000
+9EBE6C086C136C146C1B6C246C236C5E6C556C626C6A6C826C8D6C9A6C816C9B
+6C7E6C686C736C926C906CC46CF16CD36CBD6CD76CC56CDD6CAE6CB16CBE6CBA
+6CDB6CEF6CD96CEA6D1F884D6D366D2B6D3D6D386D196D356D336D126D0C6D63
+6D936D646D5A6D796D596D8E6D956FE46D856DF96E156E0A6DB56DC76DE66DB8
+6DC66DEC6DDE6DCC6DE86DD26DC56DFA6DD96DE46DD56DEA6DEE6E2D6E6E6E2E
+6E196E726E5F6E3E6E236E6B6E2B6E766E4D6E1F6E436E3A6E4E6E246EFF6E1D
+6E386E826EAA6E986EC96EB76ED36EBD6EAF6EC46EB26ED46ED56E8F6EA56EC2
+6E9F6F416F11704C6EEC6EF86EFE6F3F6EF26F316EEF6F326ECC000000000000
+E0
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+6F3E6F136EF76F866F7A6F786F816F806F6F6F5B6FF36F6D6F826F7C6F586F8E
+6F916FC26F666FB36FA36FA16FA46FB96FC66FAA6FDF6FD56FEC6FD46FD86FF1
+6FEE6FDB7009700B6FFA70117001700F6FFE701B701A6F74701D7018701F7030
+703E7032705170637099709270AF70F170AC70B870B370AE70DF70CB70DD0000
+70D9710970FD711C711971657155718871667162714C7156716C718F71FB7184
+719571A871AC71D771B971BE71D271C971D471CE71E071EC71E771F571FC71F9
+71FF720D7210721B7228722D722C72307232723B723C723F72407246724B7258
+7274727E7282728172877292729672A272A772B972B272C372C672C472CE72D2
+72E272E072E172F972F7500F7317730A731C7316731D7334732F73297325733E
+734E734F9ED87357736A7368737073787375737B737A73C873B373CE73BB73C0
+73E573EE73DE74A27405746F742573F87432743A7455743F745F74597441745C
+746974707463746A7476747E748B749E74A774CA74CF74D473F1000000000000
+E1
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+74E074E374E774E974EE74F274F074F174F874F7750475037505750C750E750D
+75157513751E7526752C753C7544754D754A7549755B7546755A756975647567
+756B756D75787576758675877574758A758975827594759A759D75A575A375C2
+75B375C375B575BD75B875BC75B175CD75CA75D275D975E375DE75FE75FF0000
+75FC760175F075FA75F275F3760B760D7609761F762776207621762276247634
+7630763B764776487646765C76587661766276687669766A7667766C76707672
+76767678767C768076837688768B768E769676937699769A76B076B476B876B9
+76BA76C276CD76D676D276DE76E176E576E776EA862F76FB7708770777047729
+7724771E77257726771B773777387747775A7768776B775B7765777F777E7779
+778E778B779177A0779E77B077B677B977BF77BC77BD77BB77C777CD77D777DA
+77DC77E377EE77FC780C781279267820792A7845788E78747886787C789A788C
+78A378B578AA78AF78D178C678CB78D478BE78BC78C578CA78EC000000000000
+E2
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+78E778DA78FD78F47907791279117919792C792B794079607957795F795A7955
+7953797A797F798A799D79A79F4B79AA79AE79B379B979BA79C979D579E779EC
+79E179E37A087A0D7A187A197A207A1F79807A317A3B7A3E7A377A437A577A49
+7A617A627A699F9D7A707A797A7D7A887A977A957A987A967AA97AC87AB00000
+7AB67AC57AC47ABF90837AC77ACA7ACD7ACF7AD57AD37AD97ADA7ADD7AE17AE2
+7AE67AED7AF07B027B0F7B0A7B067B337B187B197B1E7B357B287B367B507B7A
+7B047B4D7B0B7B4C7B457B757B657B747B677B707B717B6C7B6E7B9D7B987B9F
+7B8D7B9C7B9A7B8B7B927B8F7B5D7B997BCB7BC17BCC7BCF7BB47BC67BDD7BE9
+7C117C147BE67BE57C607C007C077C137BF37BF77C177C0D7BF67C237C277C2A
+7C1F7C377C2B7C3D7C4C7C437C547C4F7C407C507C587C5F7C647C567C657C6C
+7C757C837C907CA47CAD7CA27CAB7CA17CA87CB37CB27CB17CAE7CB97CBD7CC0
+7CC57CC27CD87CD27CDC7CE29B3B7CEF7CF27CF47CF67CFA7D06000000000000
+E3
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+7D027D1C7D157D0A7D457D4B7D2E7D327D3F7D357D467D737D567D4E7D727D68
+7D6E7D4F7D637D937D897D5B7D8F7D7D7D9B7DBA7DAE7DA37DB57DC77DBD7DAB
+7E3D7DA27DAF7DDC7DB87D9F7DB07DD87DDD7DE47DDE7DFB7DF27DE17E057E0A
+7E237E217E127E317E1F7E097E0B7E227E467E667E3B7E357E397E437E370000
+7E327E3A7E677E5D7E567E5E7E597E5A7E797E6A7E697E7C7E7B7E837DD57E7D
+8FAE7E7F7E887E897E8C7E927E907E937E947E967E8E7E9B7E9C7F387F3A7F45
+7F4C7F4D7F4E7F507F517F557F547F587F5F7F607F687F697F677F787F827F86
+7F837F887F877F8C7F947F9E7F9D7F9A7FA37FAF7FB27FB97FAE7FB67FB88B71
+7FC57FC67FCA7FD57FD47FE17FE67FE97FF37FF998DC80068004800B80128018
+8019801C80218028803F803B804A804680528058805A805F8062806880738072
+807080768079807D807F808480868085809B8093809A80AD519080AC80DB80E5
+80D980DD80C480DA80D6810980EF80F1811B81298123812F814B000000000000
+E4
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+968B8146813E8153815180FC8171816E81658166817481838188818A81808182
+81A0819581A481A3815F819381A981B081B581BE81B881BD81C081C281BA81C9
+81CD81D181D981D881C881DA81DF81E081E781FA81FB81FE8201820282058207
+820A820D821082168229822B82388233824082598258825D825A825F82640000
+82628268826A826B822E827182778278827E828D829282AB829F82BB82AC82E1
+82E382DF82D282F482F382FA8393830382FB82F982DE830682DC830982D98335
+83348316833283318340833983508345832F832B831783188385839A83AA839F
+83A283968323838E8387838A837C83B58373837583A0838983A883F4841383EB
+83CE83FD840383D8840B83C183F7840783E083F2840D8422842083BD84388506
+83FB846D842A843C855A84848477846B84AD846E848284698446842C846F8479
+843584CA846284B984BF849F84D984CD84BB84DA84D084C184C684D684A18521
+84FF84F485178518852C851F8515851484FC8540856385588548000000000000
+E5
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+85418602854B8555858085A485888591858A85A8856D8594859B85EA8587859C
+8577857E859085C985BA85CF85B985D085D585DD85E585DC85F9860A8613860B
+85FE85FA86068622861A8630863F864D4E558654865F86678671869386A386A9
+86AA868B868C86B686AF86C486C686B086C9882386AB86D486DE86E986EC0000
+86DF86DB86EF8712870687088700870386FB87118709870D86F9870A8734873F
+8737873B87258729871A8760875F8778874C874E877487578768876E87598753
+8763876A880587A2879F878287AF87CB87BD87C087D096D687AB87C487B387C7
+87C687BB87EF87F287E0880F880D87FE87F687F7880E87D28811881688158822
+88218831883688398827883B8844884288528859885E8862886B8881887E889E
+8875887D88B5887288828897889288AE889988A2888D88A488B088BF88B188C3
+88C488D488D888D988DD88F9890288FC88F488E888F28904890C890A89138943
+891E8925892A892B89418944893B89368938894C891D8960895E000000000000
+E6
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+89668964896D896A896F89748977897E89838988898A8993899889A189A989A6
+89AC89AF89B289BA89BD89BF89C089DA89DC89DD89E789F489F88A038A168A10
+8A0C8A1B8A1D8A258A368A418A5B8A528A468A488A7C8A6D8A6C8A628A858A82
+8A848AA88AA18A918AA58AA68A9A8AA38AC48ACD8AC28ADA8AEB8AF38AE70000
+8AE48AF18B148AE08AE28AF78ADE8ADB8B0C8B078B1A8AE18B168B108B178B20
+8B3397AB8B268B2B8B3E8B288B418B4C8B4F8B4E8B498B568B5B8B5A8B6B8B5F
+8B6C8B6F8B748B7D8B808B8C8B8E8B928B938B968B998B9A8C3A8C418C3F8C48
+8C4C8C4E8C508C558C628C6C8C788C7A8C828C898C858C8A8C8D8C8E8C948C7C
+8C98621D8CAD8CAA8CBD8CB28CB38CAE8CB68CC88CC18CE48CE38CDA8CFD8CFA
+8CFB8D048D058D0A8D078D0F8D0D8D109F4E8D138CCD8D148D168D678D6D8D71
+8D738D818D998DC28DBE8DBA8DCF8DDA8DD68DCC8DDB8DCB8DEA8DEB8DDF8DE3
+8DFC8E088E098DFF8E1D8E1E8E108E1F8E428E358E308E348E4A000000000000
+E7
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+8E478E498E4C8E508E488E598E648E608E2A8E638E558E768E728E7C8E818E87
+8E858E848E8B8E8A8E938E918E948E998EAA8EA18EAC8EB08EC68EB18EBE8EC5
+8EC88ECB8EDB8EE38EFC8EFB8EEB8EFE8F0A8F058F158F128F198F138F1C8F1F
+8F1B8F0C8F268F338F3B8F398F458F428F3E8F4C8F498F468F4E8F578F5C0000
+8F628F638F648F9C8F9F8FA38FAD8FAF8FB78FDA8FE58FE28FEA8FEF90878FF4
+90058FF98FFA901190159021900D901E9016900B90279036903590398FF8904F
+905090519052900E9049903E90569058905E9068906F907696A890729082907D
+90819080908A9089908F90A890AF90B190B590E290E4624890DB910291129119
+91329130914A9156915891639165916991739172918B9189918291A291AB91AF
+91AA91B591B491BA91C091C191C991CB91D091D691DF91E191DB91FC91F591F6
+921E91FF9214922C92159211925E925792459249926492489295923F924B9250
+929C92969293929B925A92CF92B992B792E9930F92FA9344932E000000000000
+E8
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+93199322931A9323933A9335933B935C9360937C936E935693B093AC93AD9394
+93B993D693D793E893E593D893C393DD93D093C893E4941A9414941394039407
+94109436942B94359421943A944194529444945B94609462945E946A92299470
+94759477947D945A947C947E9481947F95829587958A95949596959895990000
+95A095A895A795AD95BC95BB95B995BE95CA6FF695C395CD95CC95D595D495D6
+95DC95E195E595E296219628962E962F9642964C964F964B9677965C965E965D
+965F96669672966C968D96989695969796AA96A796B196B296B096B496B696B8
+96B996CE96CB96C996CD894D96DC970D96D596F99704970697089713970E9711
+970F971697199724972A97309739973D973E97449746974897429749975C9760
+97649766976852D2976B977197799785977C9781977A9786978B978F9790979C
+97A897A697A397B397B497C397C697C897CB97DC97ED9F4F97F27ADF97F697F5
+980F980C9838982498219837983D9846984F984B986B986F9870000000000000
+E9
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+98719874987398AA98AF98B198B698C498C398C698E998EB9903990999129914
+99189921991D991E99249920992C992E993D993E9942994999459950994B9951
+9952994C99559997999899A599AD99AE99BC99DF99DB99DD99D899D199ED99EE
+99F199F299FB99F89A019A0F9A0599E29A199A2B9A379A459A429A409A430000
+9A3E9A559A4D9A5B9A579A5F9A629A659A649A699A6B9A6A9AAD9AB09ABC9AC0
+9ACF9AD19AD39AD49ADE9ADF9AE29AE39AE69AEF9AEB9AEE9AF49AF19AF79AFB
+9B069B189B1A9B1F9B229B239B259B279B289B299B2A9B2E9B2F9B329B449B43
+9B4F9B4D9B4E9B519B589B749B939B839B919B969B979B9F9BA09BA89BB49BC0
+9BCA9BB99BC69BCF9BD19BD29BE39BE29BE49BD49BE19C3A9BF29BF19BF09C15
+9C149C099C139C0C9C069C089C129C0A9C049C2E9C1B9C259C249C219C309C47
+9C329C469C3E9C5A9C609C679C769C789CE79CEC9CF09D099D089CEB9D039D06
+9D2A9D269DAF9D239D1F9D449D159D129D419D3F9D3E9D469D48000000000000
+EA
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+9D5D9D5E9D649D519D509D599D729D899D879DAB9D6F9D7A9D9A9DA49DA99DB2
+9DC49DC19DBB9DB89DBA9DC69DCF9DC29DD99DD39DF89DE69DED9DEF9DFD9E1A
+9E1B9E1E9E759E799E7D9E819E889E8B9E8C9E929E959E919E9D9EA59EA99EB8
+9EAA9EAD97619ECC9ECE9ECF9ED09ED49EDC9EDE9EDD9EE09EE59EE89EEF0000
+9EF49EF69EF79EF99EFB9EFC9EFD9F079F0876B79F159F219F2C9F3E9F4A9F52
+9F549F639F5F9F609F619F669F679F6C9F6A9F779F729F769F959F9C9FA0582F
+69C79059746451DC719900000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+R
+8160 301C FF5E
+8161 2016 2225
+817C 2212 FF0D
+8191 00A2 FFE0
+8192 00A3 FFE1
+81CA 00AC FFE2
diff --git a/library/encoding/symbol.enc b/library/encoding/symbol.enc
new file mode 100644
index 0000000..ffda9e3
--- /dev/null
+++ b/library/encoding/symbol.enc
@@ -0,0 +1,20 @@
+# Encoding file: symbol, single-byte
+S
+003F 1 1
+00
+0000000100020003000400050006000700080009000A000B000C000D000E000F
+0010001100120013001400150016001700180019001A001B001C001D001E001F
+0020002122000023220300250026220D002800292217002B002C2212002E002F
+0030003100320033003400350036003700380039003A003B003C003D003E003F
+22450391039203A70394039503A603930397039903D1039A039B039C039D039F
+03A0039803A103A303A403A503C203A9039E03A80396005B2234005D22A5005F
+F8E503B103B203C703B403B503C603B303B703B903D503BA03BB03BC03BD03BF
+03C003B803C103C303C403C503D603C903BE03C803B6007B007C007D223C007F
+0080008100820083008400850086008700880089008A008B008C008D008E008F
+0090009100920093009400950096009700980099009A009B009C009D009E009F
+000003D2203222642044221E0192266326662665266021942190219121922193
+00B000B12033226500D7221D2202202200F72260226122482026F8E6F8E721B5
+21352111211C21182297229522052229222A2283228722842282228622082209
+2220220700AE00A92122220F221A22C500AC2227222821D421D021D121D221D3
+22C42329F8E8F8E9F8EA2211F8EBF8ECF8EDF8EEF8EFF8F0F8F1F8F2F8F3F8F4
+F8FF232A222B2320F8F52321F8F6F8F7F8F8F8F9F8FAF8FBF8FCF8FDF8FE0000
diff --git a/library/encoding/tis-620.enc b/library/encoding/tis-620.enc
new file mode 100644
index 0000000..c233be5
--- /dev/null
+++ b/library/encoding/tis-620.enc
@@ -0,0 +1,20 @@
+# Encoding file: tis-620, single-byte
+S
+003F 0 1
+00
+0000000100020003000400050006000700080009000A000B000C000D000E000F
+0010001100120013001400150016001700180019001A001B001C001D001E001F
+0020002100220023002400250026002700280029002A002B002C002D002E002F
+0030003100320033003400350036003700380039003A003B003C003D003E003F
+0040004100420043004400450046004700480049004A004B004C004D004E004F
+0050005100520053005400550056005700580059005A005B005C005D005E005F
+0060006100620063006400650066006700680069006A006B006C006D006E006F
+0070007100720073007400750076007700780079007A007B007C007D007E0000
+0000000000000000000000000000000000000000000000000000000000000000
+0000000000000000000000000000000000000000000000000000000000000000
+00000E010E020E030E040E050E060E070E080E090E0A0E0B0E0C0E0D0E0E0E0F
+0E100E110E120E130E140E150E160E170E180E190E1A0E1B0E1C0E1D0E1E0E1F
+0E200E210E220E230E240E250E260E270E280E290E2A0E2B0E2C0E2D0E2E0E2F
+0E300E310E320E330E340E350E360E370E380E390E3A00000000000000000E3F
+0E400E410E420E430E440E450E460E470E480E490E4A0E4B0E4C0E4D0E4E0E4F
+0E500E510E520E530E540E550E560E570E580E590E5A0E5B0000000000000000
\ No newline at end of file
diff --git a/library/history.tcl b/library/history.tcl
new file mode 100644
index 0000000..51d2404
--- /dev/null
+++ b/library/history.tcl
@@ -0,0 +1,311 @@
+# history.tcl --
+#
+# Implementation of the history command.
+#
+# Copyright (c) 1997 Sun Microsystems, Inc.
+#
+# See the file "license.terms" for information on usage and redistribution of
+# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+
+# The tcl::history array holds the history list and some additional
+# bookkeeping variables.
+#
+# nextid	the index used for the next history list item.
+# keep		the max size of the history list
+# oldest	the index of the oldest item in the history.
+
+namespace eval ::tcl {
+    variable history
+    if {![info exists history]} {
+	array set history {
+	    nextid	0
+	    keep	20
+	    oldest	-20
+	}
+    }
+
+    namespace ensemble create -command ::tcl::history -map {
+	add	::tcl::HistAdd
+	change	::tcl::HistChange
+	clear	::tcl::HistClear
+	event	::tcl::HistEvent
+	info	::tcl::HistInfo
+	keep	::tcl::HistKeep
+	nextid	::tcl::HistNextID
+	redo	::tcl::HistRedo
+    }
+}
+
+# history --
+#
+#	This is the main history command.  See the man page for its interface.
+#	This does some argument checking and calls the helper ensemble in the
+#	tcl namespace.
+
+proc ::history {args} {
+    # If no command given, we're doing 'history info'. Can't be done with an
+    # ensemble unknown handler, as those don't fire when no subcommand is
+    # given at all.
+
+    if {![llength $args]} {
+	set args info
+    }
+
+    # Tricky stuff needed to make stack and errors come out right!
+    tailcall apply {arglist {tailcall history {*}$arglist} ::tcl} $args
+}
+
+# tcl::HistAdd --
+#
+#	Add an item to the history, and optionally eval it at the global scope
+#
+# Parameters:
+#	event		the command to add
+#	exec		(optional) a substring of "exec" causes the command to
+#			be evaled.
+# Results:
+# 	If executing, then the results of the command are returned
+#
+# Side Effects:
+#	Adds to the history list
+
+proc ::tcl::HistAdd {event {exec {}}} {
+    variable history
+
+    if {
+	[prefix longest {exec {}} $exec] eq ""
+	&& [llength [info level 0]] == 3
+    } then {
+	return -code error "bad argument \"$exec\": should be \"exec\""
+    }
+
+    # Do not add empty commands to the history
+    if {[string trim $event] eq ""} {
+	return ""
+    }
+
+    # Maintain the history
+    set history([incr history(nextid)]) $event
+    unset -nocomplain history([incr history(oldest)])
+
+    # Only execute if 'exec' (or non-empty prefix of it) given
+    if {$exec eq ""} {
+	return ""
+    }
+    tailcall eval $event
+}
+
+# tcl::HistKeep --
+#
+#	Set or query the limit on the length of the history list
+#
+# Parameters:
+#	limit	(optional) the length of the history list
+#
+# Results:
+#	If no limit is specified, the current limit is returned
+#
+# Side Effects:
+#	Updates history(keep) if a limit is specified
+
+proc ::tcl::HistKeep {{count {}}} {
+    variable history
+    if {[llength [info level 0]] == 1} {
+	return $history(keep)
+    }
+    if {![string is integer -strict $count] || ($count < 0)} {
+	return -code error "illegal keep count \"$count\""
+    }
+    set oldold $history(oldest)
+    set history(oldest) [expr {$history(nextid) - $count}]
+    for {} {$oldold <= $history(oldest)} {incr oldold} {
+	unset -nocomplain history($oldold)
+    }
+    set history(keep) $count
+}
+
+# tcl::HistClear --
+#
+#	Erase the history list
+#
+# Parameters:
+#	none
+#
+# Results:
+#	none
+#
+# Side Effects:
+#	Resets the history array, except for the keep limit
+
+proc ::tcl::HistClear {} {
+    variable history
+    set keep $history(keep)
+    unset history
+    array set history [list \
+	nextid	0	\
+	keep	$keep	\
+	oldest	-$keep	\
+    ]
+}
+
+# tcl::HistInfo --
+#
+#	Return a pretty-printed version of the history list
+#
+# Parameters:
+#	num	(optional) the length of the history list to return
+#
+# Results:
+#	A formatted history list
+
+proc ::tcl::HistInfo {{count {}}} {
+    variable history
+    if {[llength [info level 0]] == 1} {
+	set count [expr {$history(keep) + 1}]
+    } elseif {![string is integer -strict $count]} {
+	return -code error "bad integer \"$count\""
+    }
+    set result {}
+    set newline ""
+    for {set i [expr {$history(nextid) - $count + 1}]} \
+	    {$i <= $history(nextid)} {incr i} {
+	if {![info exists history($i)]} {
+	    continue
+	}
+        set cmd [string map [list \n \n\t] [string trimright $history($i) \ \n]]
+	append result $newline[format "%6d  %s" $i $cmd]
+	set newline \n
+    }
+    return $result
+}
+
+# tcl::HistRedo --
+#
+#	Fetch the previous or specified event, execute it, and then replace
+#	the current history item with that event.
+#
+# Parameters:
+#	event	(optional) index of history item to redo.  Defaults to -1,
+#		which means the previous event.
+#
+# Results:
+#	Those of the command being redone.
+#
+# Side Effects:
+#	Replaces the current history list item with the one being redone.
+
+proc ::tcl::HistRedo {{event -1}} {
+    variable history
+
+    set i [HistIndex $event]
+    if {$i == $history(nextid)} {
+	return -code error "cannot redo the current event"
+    }
+    set cmd $history($i)
+    HistChange $cmd 0
+    tailcall eval $cmd
+}
+
+# tcl::HistIndex --
+#
+#	Map from an event specifier to an index in the history list.
+#
+# Parameters:
+#	event	index of history item to redo.
+#		If this is a positive number, it is used directly.
+#		If it is a negative number, then it counts back to a previous
+#		event, where -1 is the most recent event.
+#		A string can be matched, either by being the prefix of a
+#		command or by matching a command with string match.
+#
+# Results:
+#	The index into history, or an error if the index didn't match.
+
+proc ::tcl::HistIndex {event} {
+    variable history
+    if {![string is integer -strict $event]} {
+	for {set i [expr {$history(nextid)-1}]} {[info exists history($i)]} \
+		{incr i -1} {
+	    if {[string match $event* $history($i)]} {
+		return $i
+	    }
+	    if {[string match $event $history($i)]} {
+		return $i
+	    }
+	}
+	return -code error "no event matches \"$event\""
+    } elseif {$event <= 0} {
+	set i [expr {$history(nextid) + $event}]
+    } else {
+	set i $event
+    }
+    if {$i <= $history(oldest)} {
+	return -code error "event \"$event\" is too far in the past"
+    }
+    if {$i > $history(nextid)} {
+	return -code error "event \"$event\" hasn't occured yet"
+    }
+    return $i
+}
+
+# tcl::HistEvent --
+#
+#	Map from an event specifier to the value in the history list.
+#
+# Parameters:
+#	event	index of history item to redo.  See index for a description of
+#		possible event patterns.
+#
+# Results:
+#	The value from the history list.
+
+proc ::tcl::HistEvent {{event -1}} {
+    variable history
+    set i [HistIndex $event]
+    if {![info exists history($i)]} {
+	return ""
+    }
+    return [string trimright $history($i) \ \n]
+}
+
+# tcl::HistChange --
+#
+#	Replace a value in the history list.
+#
+# Parameters:
+#	newValue  The new value to put into the history list.
+#	event	  (optional) index of history item to redo.  See index for a
+#		  description of possible event patterns.  This defaults to 0,
+#		  which specifies the current event.
+#
+# Side Effects:
+#	Changes the history list.
+
+proc ::tcl::HistChange {newValue {event 0}} {
+    variable history
+    set i [HistIndex $event]
+    set history($i) $newValue
+}
+
+# tcl::HistNextID --
+#
+#	Returns the number of the next history event.
+#
+# Parameters:
+#	None.
+#
+# Side Effects:
+#	None.
+
+proc ::tcl::HistNextID {} {
+    variable history
+    return [expr {$history(nextid) + 1}]
+}
+
+return
+
+# Local Variables:
+# mode: tcl
+# fill-column: 78
+# End:
diff --git a/library/http/http.tcl b/library/http/http.tcl
new file mode 100644
index 0000000..5a05fa0
--- /dev/null
+++ b/library/http/http.tcl
@@ -0,0 +1,1541 @@
+# http.tcl --
+#
+#	Client-side HTTP for GET, POST, and HEAD commands. These routines can
+#	be used in untrusted code that uses the Safesock security policy.
+#	These procedures use a callback interface to avoid using vwait, which
+#	is not defined in the safe base.
+#
+# See the file "license.terms" for information on usage and redistribution of
+# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+package require Tcl 8.6
+# Keep this in sync with pkgIndex.tcl and with the install directories in
+# Makefiles
+package provide http 2.8.9
+
+namespace eval http {
+    # Allow resourcing to not clobber existing data
+
+    variable http
+    if {![info exists http]} {
+	array set http {
+	    -accept */*
+	    -proxyhost {}
+	    -proxyport {}
+	    -proxyfilter http::ProxyRequired
+	    -urlencoding utf-8
+	}
+	# We need a useragent string of this style or various servers will refuse to
+	# send us compressed content even when we ask for it. This follows the
+	# de-facto layout of user-agent strings in current browsers.
+	set http(-useragent) "Mozilla/5.0\
+            ([string totitle $::tcl_platform(platform)]; U;\
+            $::tcl_platform(os) $::tcl_platform(osVersion))\
+            http/[package provide http] Tcl/[package provide Tcl]"
+    }
+
+    proc init {} {
+	# Set up the map for quoting chars. RFC3986 Section 2.3 say percent
+	# encode all except: "... percent-encoded octets in the ranges of
+	# ALPHA (%41-%5A and %61-%7A), DIGIT (%30-%39), hyphen (%2D), period
+	# (%2E), underscore (%5F), or tilde (%7E) should not be created by URI
+	# producers ..."
+	for {set i 0} {$i <= 256} {incr i} {
+	    set c [format %c $i]
+	    if {![string match {[-._~a-zA-Z0-9]} $c]} {
+		set map($c) %[format %.2X $i]
+	    }
+	}
+	# These are handled specially
+	set map(\n) %0D%0A
+	variable formMap [array get map]
+
+	# Create a map for HTTP/1.1 open sockets
+	variable socketmap
+	if {[info exists socketmap]} {
+	    # Close but don't remove open sockets on re-init
+	    foreach {url sock} [array get socketmap] {
+		catch {close $sock}
+	    }
+	}
+	array set socketmap {}
+    }
+    init
+
+    variable urlTypes
+    if {![info exists urlTypes]} {
+	set urlTypes(http) [list 80 ::socket]
+    }
+
+    variable encodings [string tolower [encoding names]]
+    # This can be changed, but iso8859-1 is the RFC standard.
+    variable defaultCharset
+    if {![info exists defaultCharset]} {
+	set defaultCharset "iso8859-1"
+    }
+
+    # Force RFC 3986 strictness in geturl url verification?
+    variable strict
+    if {![info exists strict]} {
+	set strict 1
+    }
+
+    # Let user control default keepalive for compatibility
+    variable defaultKeepalive
+    if {![info exists defaultKeepalive]} {
+	set defaultKeepalive 0
+    }
+
+    namespace export geturl config reset wait formatQuery register unregister
+    # Useful, but not exported: data size status code
+}
+
+# http::Log --
+#
+#	Debugging output -- define this to observe HTTP/1.1 socket usage.
+#	Should echo any args received.
+#
+# Arguments:
+#     msg	Message to output
+#
+if {[info command http::Log] eq {}} {proc http::Log {args} {}}
+
+# http::register --
+#
+#     See documentation for details.
+#
+# Arguments:
+#     proto	URL protocol prefix, e.g. https
+#     port	Default port for protocol
+#     command	Command to use to create socket
+# Results:
+#     list of port and command that was registered.
+
+proc http::register {proto port command} {
+    variable urlTypes
+    set urlTypes([string tolower $proto]) [list $port $command]
+}
+
+# http::unregister --
+#
+#     Unregisters URL protocol handler
+#
+# Arguments:
+#     proto	URL protocol prefix, e.g. https
+# Results:
+#     list of port and command that was unregistered.
+
+proc http::unregister {proto} {
+    variable urlTypes
+    set lower [string tolower $proto]
+    if {![info exists urlTypes($lower)]} {
+	return -code error "unsupported url type \"$proto\""
+    }
+    set old $urlTypes($lower)
+    unset urlTypes($lower)
+    return $old
+}
+
+# http::config --
+#
+#	See documentation for details.
+#
+# Arguments:
+#	args		Options parsed by the procedure.
+# Results:
+#        TODO
+
+proc http::config {args} {
+    variable http
+    set options [lsort [array names http -*]]
+    set usage [join $options ", "]
+    if {[llength $args] == 0} {
+	set result {}
+	foreach name $options {
+	    lappend result $name $http($name)
+	}
+	return $result
+    }
+    set options [string map {- ""} $options]
+    set pat ^-(?:[join $options |])$
+    if {[llength $args] == 1} {
+	set flag [lindex $args 0]
+	if {![regexp -- $pat $flag]} {
+	    return -code error "Unknown option $flag, must be: $usage"
+	}
+	return $http($flag)
+    } else {
+	foreach {flag value} $args {
+	    if {![regexp -- $pat $flag]} {
+		return -code error "Unknown option $flag, must be: $usage"
+	    }
+	    set http($flag) $value
+	}
+    }
+}
+
+# http::Finish --
+#
+#	Clean up the socket and eval close time callbacks
+#
+# Arguments:
+#	token	    Connection token.
+#	errormsg    (optional) If set, forces status to error.
+#       skipCB      (optional) If set, don't call the -command callback. This
+#		    is useful when geturl wants to throw an exception instead
+#		    of calling the callback. That way, the same error isn't
+#		    reported to two places.
+#
+# Side Effects:
+#        Closes the socket
+
+proc http::Finish {token {errormsg ""} {skipCB 0}} {
+    variable $token
+    upvar 0 $token state
+    global errorInfo errorCode
+    if {$errormsg ne ""} {
+	set state(error) [list $errormsg $errorInfo $errorCode]
+	set state(status) "error"
+    }
+    if {
+	($state(status) eq "timeout") || ($state(status) eq "error") ||
+	([info exists state(connection)] && ($state(connection) eq "close"))
+    } {
+        CloseSocket $state(sock) $token
+    }
+    if {[info exists state(after)]} {
+	after cancel $state(after)
+    }
+    if {[info exists state(-command)] && !$skipCB
+	    && ![info exists state(done-command-cb)]} {
+	set state(done-command-cb) yes
+	if {[catch {eval $state(-command) {$token}} err] && $errormsg eq ""} {
+	    set state(error) [list $err $errorInfo $errorCode]
+	    set state(status) error
+	}
+    }
+}
+
+# http::CloseSocket -
+#
+#	Close a socket and remove it from the persistent sockets table.  If
+#	possible an http token is included here but when we are called from a
+#	fileevent on remote closure we need to find the correct entry - hence
+#	the second section.
+
+proc ::http::CloseSocket {s {token {}}} {
+    variable socketmap
+    catch {fileevent $s readable {}}
+    set conn_id {}
+    if {$token ne ""} {
+        variable $token
+        upvar 0 $token state
+        if {[info exists state(socketinfo)]} {
+	    set conn_id $state(socketinfo)
+        }
+    } else {
+        set map [array get socketmap]
+        set ndx [lsearch -exact $map $s]
+        if {$ndx != -1} {
+	    incr ndx -1
+	    set conn_id [lindex $map $ndx]
+        }
+    }
+    if {$conn_id eq {} || ![info exists socketmap($conn_id)]} {
+        Log "Closing socket $s (no connection info)"
+        if {[catch {close $s} err]} {
+	    Log "Error: $err"
+	}
+    } else {
+	if {[info exists socketmap($conn_id)]} {
+	    Log "Closing connection $conn_id (sock $socketmap($conn_id))"
+	    if {[catch {close $socketmap($conn_id)} err]} {
+		Log "Error: $err"
+	    }
+	    unset socketmap($conn_id)
+	} else {
+	    Log "Cannot close connection $conn_id - no socket in socket map"
+	}
+    }
+}
+
+# http::reset --
+#
+#	See documentation for details.
+#
+# Arguments:
+#	token	Connection token.
+#	why	Status info.
+#
+# Side Effects:
+#       See Finish
+
+proc http::reset {token {why reset}} {
+    variable $token
+    upvar 0 $token state
+    set state(status) $why
+    catch {fileevent $state(sock) readable {}}
+    catch {fileevent $state(sock) writable {}}
+    Finish $token
+    if {[info exists state(error)]} {
+	set errorlist $state(error)
+	unset state
+	eval ::error $errorlist
+    }
+}
+
+# http::geturl --
+#
+#	Establishes a connection to a remote url via http.
+#
+# Arguments:
+#       url		The http URL to goget.
+#       args		Option value pairs. Valid options include:
+#				-blocksize, -validate, -headers, -timeout
+# Results:
+#	Returns a token for this connection. This token is the name of an
+#	array that the caller should unset to garbage collect the state.
+
+proc http::geturl {url args} {
+    variable http
+    variable urlTypes
+    variable defaultCharset
+    variable defaultKeepalive
+    variable strict
+
+    # Initialize the state variable, an array. We'll return the name of this
+    # array as the token for the transaction.
+
+    if {![info exists http(uid)]} {
+	set http(uid) 0
+    }
+    set token [namespace current]::[incr http(uid)]
+    variable $token
+    upvar 0 $token state
+    reset $token
+
+    # Process command options.
+
+    array set state {
+	-binary		false
+	-blocksize	8192
+	-queryblocksize 8192
+	-validate	0
+	-headers	{}
+	-timeout	0
+	-type		application/x-www-form-urlencoded
+	-queryprogress	{}
+	-protocol	1.1
+	binary		0
+	state		connecting
+	meta		{}
+	coding		{}
+	currentsize	0
+	totalsize	0
+	querylength	0
+	queryoffset	0
+	type		text/html
+	body		{}
+	status		""
+	http		""
+	connection	close
+    }
+    set state(-keepalive) $defaultKeepalive
+    set state(-strict) $strict
+    # These flags have their types verified [Bug 811170]
+    array set type {
+	-binary		boolean
+	-blocksize	integer
+	-queryblocksize integer
+	-strict		boolean
+	-timeout	integer
+	-validate	boolean
+    }
+    set state(charset)	$defaultCharset
+    set options {
+	-binary -blocksize -channel -command -handler -headers -keepalive
+	-method -myaddr -progress -protocol -query -queryblocksize
+	-querychannel -queryprogress -strict -timeout -type -validate
+    }
+    set usage [join [lsort $options] ", "]
+    set options [string map {- ""} $options]
+    set pat ^-(?:[join $options |])$
+    foreach {flag value} $args {
+	if {[regexp -- $pat $flag]} {
+	    # Validate numbers
+	    if {
+		[info exists type($flag)] &&
+		![string is $type($flag) -strict $value]
+	    } {
+		unset $token
+		return -code error \
+		    "Bad value for $flag ($value), must be $type($flag)"
+	    }
+	    set state($flag) $value
+	} else {
+	    unset $token
+	    return -code error "Unknown option $flag, can be: $usage"
+	}
+    }
+
+    # Make sure -query and -querychannel aren't both specified
+
+    set isQueryChannel [info exists state(-querychannel)]
+    set isQuery [info exists state(-query)]
+    if {$isQuery && $isQueryChannel} {
+	unset $token
+	return -code error "Can't combine -query and -querychannel options!"
+    }
+
+    # Validate URL, determine the server host and port, and check proxy case
+    # Recognize user:pass@host URLs also, although we do not do anything with
+    # that info yet.
+
+    # URLs have basically four parts.
+    # First, before the colon, is the protocol scheme (e.g. http)
+    # Second, for HTTP-like protocols, is the authority
+    #	The authority is preceded by // and lasts up to (but not including)
+    #	the following / or ? and it identifies up to four parts, of which
+    #	only one, the host, is required (if an authority is present at all).
+    #	All other parts of the authority (user name, password, port number)
+    #	are optional.
+    # Third is the resource name, which is split into two parts at a ?
+    #	The first part (from the single "/" up to "?") is the path, and the
+    #	second part (from that "?" up to "#") is the query. *HOWEVER*, we do
+    #	not need to separate them; we send the whole lot to the server.
+    #	Both, path and query are allowed to be missing, including their
+    #	delimiting character.
+    # Fourth is the fragment identifier, which is everything after the first
+    #	"#" in the URL. The fragment identifier MUST NOT be sent to the server
+    #	and indeed, we don't bother to validate it (it could be an error to
+    #	pass it in here, but it's cheap to strip).
+    #
+    # An example of a URL that has all the parts:
+    #
+    #     http://jschmoe:xyzzy@www.bogus.net:8000/foo/bar.tml?q=foo#changes
+    #
+    # The "http" is the protocol, the user is "jschmoe", the password is
+    # "xyzzy", the host is "www.bogus.net", the port is "8000", the path is
+    # "/foo/bar.tml", the query is "q=foo", and the fragment is "changes".
+    #
+    # Note that the RE actually combines the user and password parts, as
+    # recommended in RFC 3986. Indeed, that RFC states that putting passwords
+    # in URLs is a Really Bad Idea, something with which I would agree utterly.
+    #
+    # From a validation perspective, we need to ensure that the parts of the
+    # URL that are going to the server are correctly encoded.  This is only
+    # done if $state(-strict) is true (inherited from $::http::strict).
+
+    set URLmatcher {(?x)		# this is _expanded_ syntax
+	^
+	(?: (\w+) : ) ?			# <protocol scheme>
+	(?: //
+	    (?:
+		(
+		    [^@/\#?]+		# <userinfo part of authority>
+		) @
+	    )?
+	    (				# <host part of authority>
+		[^/:\#?]+ |		# host name or IPv4 address
+		\[ [^/\#?]+ \]		# IPv6 address in square brackets
+	    )
+	    (?: : (\d+) )?		# <port part of authority>
+	)?
+	( [/\?] [^\#]*)?		# <path> (including query)
+	(?: \# (.*) )?			# <fragment>
+	$
+    }
+
+    # Phase one: parse
+    if {![regexp -- $URLmatcher $url -> proto user host port srvurl]} {
+	unset $token
+	return -code error "Unsupported URL: $url"
+    }
+    # Phase two: validate
+    set host [string trim $host {[]}]; # strip square brackets from IPv6 address
+    if {$host eq ""} {
+	# Caller has to provide a host name; we do not have a "default host"
+	# that would enable us to handle relative URLs.
+	unset $token
+	return -code error "Missing host part: $url"
+	# Note that we don't check the hostname for validity here; if it's
+	# invalid, we'll simply fail to resolve it later on.
+    }
+    if {$port ne "" && $port > 65535} {
+	unset $token
+	return -code error "Invalid port number: $port"
+    }
+    # The user identification and resource identification parts of the URL can
+    # have encoded characters in them; take care!
+    if {$user ne ""} {
+	# Check for validity according to RFC 3986, Appendix A
+	set validityRE {(?xi)
+	    ^
+	    (?: [-\w.~!$&'()*+,;=:] | %[0-9a-f][0-9a-f] )+
+	    $
+	}
+	if {$state(-strict) && ![regexp -- $validityRE $user]} {
+	    unset $token
+	    # Provide a better error message in this error case
+	    if {[regexp {(?i)%(?![0-9a-f][0-9a-f]).?.?} $user bad]} {
+		return -code error \
+			"Illegal encoding character usage \"$bad\" in URL user"
+	    }
+	    return -code error "Illegal characters in URL user"
+	}
+    }
+    if {$srvurl ne ""} {
+	# RFC 3986 allows empty paths (not even a /), but servers
+	# return 400 if the path in the HTTP request doesn't start
+	# with / , so add it here if needed.
+	if {[string index $srvurl 0] ne "/"} {
+	    set srvurl /$srvurl
+	}
+	# Check for validity according to RFC 3986, Appendix A
+	set validityRE {(?xi)
+	    ^
+	    # Path part (already must start with / character)
+	    (?:	      [-\w.~!$&'()*+,;=:@/]  | %[0-9a-f][0-9a-f] )*
+	    # Query part (optional, permits ? characters)
+	    (?: \? (?: [-\w.~!$&'()*+,;=:@/?] | %[0-9a-f][0-9a-f] )* )?
+	    $
+	}
+	if {$state(-strict) && ![regexp -- $validityRE $srvurl]} {
+	    unset $token
+	    # Provide a better error message in this error case
+	    if {[regexp {(?i)%(?![0-9a-f][0-9a-f])..} $srvurl bad]} {
+		return -code error \
+		    "Illegal encoding character usage \"$bad\" in URL path"
+	    }
+	    return -code error "Illegal characters in URL path"
+	}
+    } else {
+	set srvurl /
+    }
+    if {$proto eq ""} {
+	set proto http
+    }
+    set lower [string tolower $proto]
+    if {![info exists urlTypes($lower)]} {
+	unset $token
+	return -code error "Unsupported URL type \"$proto\""
+    }
+    set defport [lindex $urlTypes($lower) 0]
+    set defcmd [lindex $urlTypes($lower) 1]
+
+    if {$port eq ""} {
+	set port $defport
+    }
+    if {![catch {$http(-proxyfilter) $host} proxy]} {
+	set phost [lindex $proxy 0]
+	set pport [lindex $proxy 1]
+    }
+
+    # OK, now reassemble into a full URL
+    set url ${proto}://
+    if {$user ne ""} {
+	append url $user
+	append url @
+    }
+    append url $host
+    if {$port != $defport} {
+	append url : $port
+    }
+    append url $srvurl
+    # Don't append the fragment!
+    set state(url) $url
+
+    # If a timeout is specified we set up the after event and arrange for an
+    # asynchronous socket connection.
+
+    set sockopts [list -async]
+    if {$state(-timeout) > 0} {
+	set state(after) [after $state(-timeout) \
+		[list http::reset $token timeout]]
+    }
+
+    # If we are using the proxy, we must pass in the full URL that includes
+    # the server name.
+
+    if {[info exists phost] && ($phost ne "")} {
+	set srvurl $url
+	set targetAddr [list $phost $pport]
+    } else {
+	set targetAddr [list $host $port]
+    }
+    # Proxy connections aren't shared among different hosts.
+    set state(socketinfo) $host:$port
+
+    # Save the accept types at this point to prevent a race condition. [Bug
+    # c11a51c482]
+    set state(accept-types) $http(-accept)
+
+    # See if we are supposed to use a previously opened channel.
+    if {$state(-keepalive)} {
+	variable socketmap
+	if {[info exists socketmap($state(socketinfo))]} {
+	    if {[catch {fconfigure $socketmap($state(socketinfo))}]} {
+		Log "WARNING: socket for $state(socketinfo) was closed"
+		unset socketmap($state(socketinfo))
+	    } else {
+		set sock $socketmap($state(socketinfo))
+		Log "reusing socket $sock for $state(socketinfo)"
+		catch {fileevent $sock writable {}}
+		catch {fileevent $sock readable {}}
+	    }
+	}
+	# don't automatically close this connection socket
+	set state(connection) {}
+    }
+    if {![info exists sock]} {
+	# Pass -myaddr directly to the socket command
+	if {[info exists state(-myaddr)]} {
+	    lappend sockopts -myaddr $state(-myaddr)
+	}
+        if {[catch {eval $defcmd $sockopts $targetAddr} sock]} {
+	    # something went wrong while trying to establish the connection.
+	    # Clean up after events and such, but DON'T call the command
+	    # callback (if available) because we're going to throw an
+	    # exception from here instead.
+
+	    set state(sock) $sock
+	    Finish $token "" 1
+	    cleanup $token
+	    return -code error $sock
+        }
+    }
+    set state(sock) $sock
+    Log "Using $sock for $state(socketinfo)" \
+        [expr {$state(-keepalive)?"keepalive":""}]
+    if {$state(-keepalive)} {
+        set socketmap($state(socketinfo)) $sock
+    }
+
+    if {![info exists phost]} {
+	set phost ""
+    }
+    fileevent $sock writable [list http::Connect $token $proto $phost $srvurl]
+
+    # Wait for the connection to complete.
+    if {![info exists state(-command)]} {
+	# geturl does EVERYTHING asynchronously, so if the user
+	# calls it synchronously, we just do a wait here.
+	http::wait $token
+
+	if {![info exists state]} {
+	    # If we timed out then Finish has been called and the users
+	    # command callback may have cleaned up the token. If so we end up
+	    # here with nothing left to do.
+	    return $token
+	} elseif {$state(status) eq "error"} {
+	    # Something went wrong while trying to establish the connection.
+	    # Clean up after events and such, but DON'T call the command
+	    # callback (if available) because we're going to throw an
+	    # exception from here instead.
+	    set err [lindex $state(error) 0]
+	    cleanup $token
+	    return -code error $err
+	}
+    }
+
+    return $token
+}
+
+# http::Connected --
+#
+#	Callback used when the connection to the HTTP server is actually
+#	established.
+#
+# Arguments:
+#       token	State token.
+#       proto	What protocol (http, https, etc.) was used to connect.
+#	phost	Are we using keep-alive? Non-empty if yes.
+#	srvurl	Service-local URL that we're requesting
+# Results:
+#	None.
+
+proc http::Connected {token proto phost srvurl} {
+    variable http
+    variable urlTypes
+
+    variable $token
+    upvar 0 $token state
+
+    # Set back the variables needed here
+    set sock $state(sock)
+    set isQueryChannel [info exists state(-querychannel)]
+    set isQuery [info exists state(-query)]
+    set host [lindex [split $state(socketinfo) :] 0]
+    set port [lindex [split $state(socketinfo) :] 1]
+
+    set lower [string tolower $proto]
+    set defport [lindex $urlTypes($lower) 0]
+
+    # Send data in cr-lf format, but accept any line terminators
+
+    fconfigure $sock -translation {auto crlf} -buffersize $state(-blocksize)
+
+    # The following is disallowed in safe interpreters, but the socket is
+    # already in non-blocking mode in that case.
+
+    catch {fconfigure $sock -blocking off}
+    set how GET
+    if {$isQuery} {
+	set state(querylength) [string length $state(-query)]
+	if {$state(querylength) > 0} {
+	    set how POST
+	    set contDone 0
+	} else {
+	    # There's no query data.
+	    unset state(-query)
+	    set isQuery 0
+	}
+    } elseif {$state(-validate)} {
+	set how HEAD
+    } elseif {$isQueryChannel} {
+	set how POST
+	# The query channel must be blocking for the async Write to
+	# work properly.
+	fconfigure $state(-querychannel) -blocking 1 -translation binary
+	set contDone 0
+    }
+    if {[info exists state(-method)] && $state(-method) ne ""} {
+	set how $state(-method)
+    }
+    # We cannot handle chunked encodings with -handler, so force HTTP/1.0
+    # until we can manage this.
+    if {[info exists state(-handler)]} {
+	set state(-protocol) 1.0
+    }
+    set accept_types_seen 0
+    if {[catch {
+	puts $sock "$how $srvurl HTTP/$state(-protocol)"
+	if {[dict exists $state(-headers) Host]} {
+	    # Allow Host spoofing. [Bug 928154]
+	    puts $sock "Host: [dict get $state(-headers) Host]"
+	} elseif {$port == $defport} {
+	    # Don't add port in this case, to handle broken servers. [Bug
+	    # #504508]
+	    puts $sock "Host: $host"
+	} else {
+	    puts $sock "Host: $host:$port"
+	}
+	puts $sock "User-Agent: $http(-useragent)"
+        if {$state(-protocol) == 1.0 && $state(-keepalive)} {
+	    puts $sock "Connection: keep-alive"
+        }
+        if {$state(-protocol) > 1.0 && !$state(-keepalive)} {
+	    puts $sock "Connection: close" ;# RFC2616 sec 8.1.2.1
+        }
+        if {[info exists phost] && ($phost ne "") && $state(-keepalive)} {
+	    puts $sock "Proxy-Connection: Keep-Alive"
+        }
+        set accept_encoding_seen 0
+	set content_type_seen 0
+	dict for {key value} $state(-headers) {
+	    set value [string map [list \n "" \r ""] $value]
+	    set key [string map {" " -} [string trim $key]]
+	    if {[string equal -nocase $key "host"]} {
+		continue
+	    }
+	    if {[string equal -nocase $key "accept-encoding"]} {
+		set accept_encoding_seen 1
+	    }
+	    if {[string equal -nocase $key "accept"]} {
+		set accept_types_seen 1
+	    }
+	    if {[string equal -nocase $key "content-type"]} {
+		set content_type_seen 1
+	    }
+	    if {[string equal -nocase $key "content-length"]} {
+		set contDone 1
+		set state(querylength) $value
+	    }
+	    if {[string length $key]} {
+		puts $sock "$key: $value"
+	    }
+	}
+	# Allow overriding the Accept header on a per-connection basis. Useful
+	# for working with REST services. [Bug c11a51c482]
+	if {!$accept_types_seen} {
+	    puts $sock "Accept: $state(accept-types)"
+	}
+        if {!$accept_encoding_seen && ![info exists state(-handler)]} {
+	    puts $sock "Accept-Encoding: gzip,deflate,compress"
+        }
+	if {$isQueryChannel && $state(querylength) == 0} {
+	    # Try to determine size of data in channel. If we cannot seek, the
+	    # surrounding catch will trap us
+
+	    set start [tell $state(-querychannel)]
+	    seek $state(-querychannel) 0 end
+	    set state(querylength) \
+		    [expr {[tell $state(-querychannel)] - $start}]
+	    seek $state(-querychannel) $start
+	}
+
+	# Flush the request header and set up the fileevent that will either
+	# push the POST data or read the response.
+	#
+	# fileevent note:
+	#
+	# It is possible to have both the read and write fileevents active at
+	# this point. The only scenario it seems to affect is a server that
+	# closes the connection without reading the POST data. (e.g., early
+	# versions TclHttpd in various error cases). Depending on the
+	# platform, the client may or may not be able to get the response from
+	# the server because of the error it will get trying to write the post
+	# data. Having both fileevents active changes the timing and the
+	# behavior, but no two platforms (among Solaris, Linux, and NT) behave
+	# the same, and none behave all that well in any case. Servers should
+	# always read their POST data if they expect the client to read their
+	# response.
+
+	if {$isQuery || $isQueryChannel} {
+	    if {!$content_type_seen} {
+		puts $sock "Content-Type: $state(-type)"
+	    }
+	    if {!$contDone} {
+		puts $sock "Content-Length: $state(querylength)"
+	    }
+	    puts $sock ""
+	    fconfigure $sock -translation {auto binary}
+	    fileevent $sock writable [list http::Write $token]
+	} else {
+	    puts $sock ""
+	    flush $sock
+	    fileevent $sock readable [list http::Event $sock $token]
+	}
+
+    } err]} {
+	# The socket probably was never connected, or the connection dropped
+	# later.
+
+	# if state(status) is error, it means someone's already called Finish
+	# to do the above-described clean up.
+	if {$state(status) ne "error"} {
+	    Finish $token $err
+	}
+    }
+}
+
+# Data access functions:
+# Data - the URL data
+# Status - the transaction status: ok, reset, eof, timeout
+# Code - the HTTP transaction code, e.g., 200
+# Size - the size of the URL data
+
+proc http::data {token} {
+    variable $token
+    upvar 0 $token state
+    return $state(body)
+}
+proc http::status {token} {
+    if {![info exists $token]} {
+	return "error"
+    }
+    variable $token
+    upvar 0 $token state
+    return $state(status)
+}
+proc http::code {token} {
+    variable $token
+    upvar 0 $token state
+    return $state(http)
+}
+proc http::ncode {token} {
+    variable $token
+    upvar 0 $token state
+    if {[regexp {[0-9]{3}} $state(http) numeric_code]} {
+	return $numeric_code
+    } else {
+	return $state(http)
+    }
+}
+proc http::size {token} {
+    variable $token
+    upvar 0 $token state
+    return $state(currentsize)
+}
+proc http::meta {token} {
+    variable $token
+    upvar 0 $token state
+    return $state(meta)
+}
+proc http::error {token} {
+    variable $token
+    upvar 0 $token state
+    if {[info exists state(error)]} {
+	return $state(error)
+    }
+    return ""
+}
+
+# http::cleanup
+#
+#	Garbage collect the state associated with a transaction
+#
+# Arguments
+#	token	The token returned from http::geturl
+#
+# Side Effects
+#	unsets the state array
+
+proc http::cleanup {token} {
+    variable $token
+    upvar 0 $token state
+    if {[info exists state]} {
+	unset state
+    }
+}
+
+# http::Connect
+#
+#	This callback is made when an asyncronous connection completes.
+#
+# Arguments
+#	token	The token returned from http::geturl
+#
+# Side Effects
+#	Sets the status of the connection, which unblocks
+# 	the waiting geturl call
+
+proc http::Connect {token proto phost srvurl} {
+    variable $token
+    upvar 0 $token state
+    set err "due to unexpected EOF"
+    if {
+	[eof $state(sock)] ||
+	[set err [fconfigure $state(sock) -error]] ne ""
+    } {
+	Finish $token "connect failed $err"
+    } else {
+	fileevent $state(sock) writable {}
+	::http::Connected $token $proto $phost $srvurl
+    }
+    return
+}
+
+# http::Write
+#
+#	Write POST query data to the socket
+#
+# Arguments
+#	token	The token for the connection
+#
+# Side Effects
+#	Write the socket and handle callbacks.
+
+proc http::Write {token} {
+    variable $token
+    upvar 0 $token state
+    set sock $state(sock)
+
+    # Output a block.  Tcl will buffer this if the socket blocks
+    set done 0
+    if {[catch {
+	# Catch I/O errors on dead sockets
+
+	if {[info exists state(-query)]} {
+	    # Chop up large query strings so queryprogress callback can give
+	    # smooth feedback.
+
+	    puts -nonewline $sock \
+		[string range $state(-query) $state(queryoffset) \
+		     [expr {$state(queryoffset) + $state(-queryblocksize) - 1}]]
+	    incr state(queryoffset) $state(-queryblocksize)
+	    if {$state(queryoffset) >= $state(querylength)} {
+		set state(queryoffset) $state(querylength)
+		set done 1
+	    }
+	} else {
+	    # Copy blocks from the query channel
+
+	    set outStr [read $state(-querychannel) $state(-queryblocksize)]
+	    puts -nonewline $sock $outStr
+	    incr state(queryoffset) [string length $outStr]
+	    if {[eof $state(-querychannel)]} {
+		set done 1
+	    }
+	}
+    } err]} {
+	# Do not call Finish here, but instead let the read half of the socket
+	# process whatever server reply there is to get.
+
+	set state(posterror) $err
+	set done 1
+    }
+    if {$done} {
+	catch {flush $sock}
+	fileevent $sock writable {}
+	fileevent $sock readable [list http::Event $sock $token]
+    }
+
+    # Callback to the client after we've completely handled everything.
+
+    if {[string length $state(-queryprogress)]} {
+	eval $state(-queryprogress) \
+	    [list $token $state(querylength) $state(queryoffset)]
+    }
+}
+
+# http::Event
+#
+#	Handle input on the socket
+#
+# Arguments
+#	sock	The socket receiving input.
+#	token	The token returned from http::geturl
+#
+# Side Effects
+#	Read the socket and handle callbacks.
+
+proc http::Event {sock token} {
+    variable $token
+    upvar 0 $token state
+
+    if {![info exists state]} {
+	Log "Event $sock with invalid token '$token' - remote close?"
+	if {![eof $sock]} {
+	    if {[set d [read $sock]] ne ""} {
+		Log "WARNING: additional data left on closed socket"
+	    }
+	}
+	CloseSocket $sock
+	return
+    }
+    if {$state(state) eq "connecting"} {
+	if {[catch {gets $sock state(http)} n]} {
+	    return [Finish $token $n]
+	} elseif {$n >= 0} {
+	    set state(state) "header"
+	}
+    } elseif {$state(state) eq "header"} {
+	if {[catch {gets $sock line} n]} {
+	    return [Finish $token $n]
+	} elseif {$n == 0} {
+	    # We have now read all headers
+	    # We ignore HTTP/1.1 100 Continue returns. RFC2616 sec 8.2.3
+	    if {$state(http) == "" || ([regexp {^\S+\s(\d+)} $state(http) {} x] && $x == 100)} {
+		return
+	    }
+
+	    set state(state) body
+
+	    # If doing a HEAD, then we won't get any body
+	    if {$state(-validate)} {
+		Eof $token
+		return
+	    }
+
+	    # For non-chunked transfer we may have no body - in this case we
+	    # may get no further file event if the connection doesn't close
+	    # and no more data is sent. We can tell and must finish up now -
+	    # not later.
+	    if {
+		!(([info exists state(connection)]
+			&& ($state(connection) eq "close"))
+		    || [info exists state(transfer)])
+		&& ($state(totalsize) == 0)
+	    } {
+		Log "body size is 0 and no events likely - complete."
+		Eof $token
+		return
+	    }
+
+	    # We have to use binary translation to count bytes properly.
+	    fconfigure $sock -translation binary
+
+	    if {
+		$state(-binary) || ![string match -nocase text* $state(type)]
+	    } {
+		# Turn off conversions for non-text data
+		set state(binary) 1
+	    }
+	    if {[info exists state(-channel)]} {
+		if {$state(binary) || [llength [ContentEncoding $token]]} {
+		    fconfigure $state(-channel) -translation binary
+		}
+		if {![info exists state(-handler)]} {
+		    # Initiate a sequence of background fcopies
+		    fileevent $sock readable {}
+		    CopyStart $sock $token
+		    return
+		}
+	    }
+	} elseif {$n > 0} {
+	    # Process header lines
+	    if {[regexp -nocase {^([^:]+):(.+)$} $line x key value]} {
+		switch -- [string tolower $key] {
+		    content-type {
+			set state(type) [string trim [string tolower $value]]
+			# grab the optional charset information
+			if {[regexp -nocase \
+				 {charset\s*=\s*\"((?:[^""]|\\\")*)\"} \
+				 $state(type) -> cs]} {
+			    set state(charset) [string map {{\"} \"} $cs]
+			} else {
+			    regexp -nocase {charset\s*=\s*(\S+?);?} \
+				$state(type) -> state(charset)
+			}
+		    }
+		    content-length {
+			set state(totalsize) [string trim $value]
+		    }
+		    content-encoding {
+			set state(coding) [string trim $value]
+		    }
+		    transfer-encoding {
+			set state(transfer) \
+			    [string trim [string tolower $value]]
+		    }
+		    proxy-connection -
+		    connection {
+			set state(connection) \
+			    [string trim [string tolower $value]]
+		    }
+		}
+		lappend state(meta) $key [string trim $value]
+	    }
+	}
+    } else {
+	# Now reading body
+	if {[catch {
+	    if {[info exists state(-handler)]} {
+		set n [eval $state(-handler) [list $sock $token]]
+	    } elseif {[info exists state(transfer_final)]} {
+		set line [getTextLine $sock]
+		set n [string length $line]
+		if {$n > 0} {
+		    Log "found $n bytes following final chunk"
+		    append state(transfer_final) $line
+		} else {
+		    Log "final chunk part"
+		    Eof $token
+		}
+	    } elseif {
+		[info exists state(transfer)]
+		&& $state(transfer) eq "chunked"
+	    } {
+		set size 0
+		set chunk [getTextLine $sock]
+		set n [string length $chunk]
+		if {[string trim $chunk] ne ""} {
+		    scan $chunk %x size
+		    if {$size != 0} {
+			set bl [fconfigure $sock -blocking]
+			fconfigure $sock -blocking 1
+			set chunk [read $sock $size]
+			fconfigure $sock -blocking $bl
+			set n [string length $chunk]
+			if {$n >= 0} {
+			    append state(body) $chunk
+			}
+			if {$size != [string length $chunk]} {
+			    Log "WARNING: mis-sized chunk:\
+				was [string length $chunk], should be $size"
+			}
+			getTextLine $sock
+		    } else {
+			set state(transfer_final) {}
+		    }
+		}
+	    } else {
+		#Log "read non-chunk $state(currentsize) of $state(totalsize)"
+		set block [read $sock $state(-blocksize)]
+		set n [string length $block]
+		if {$n >= 0} {
+		    append state(body) $block
+		}
+	    }
+	    if {[info exists state]} {
+		if {$n >= 0} {
+		    incr state(currentsize) $n
+		}
+		# If Content-Length - check for end of data.
+		if {
+		    ($state(totalsize) > 0)
+		    && ($state(currentsize) >= $state(totalsize))
+		} {
+		    Eof $token
+		}
+	    }
+	} err]} {
+	    return [Finish $token $err]
+	} else {
+	    if {[info exists state(-progress)]} {
+		eval $state(-progress) \
+		    [list $token $state(totalsize) $state(currentsize)]
+	    }
+	}
+    }
+
+    # catch as an Eof above may have closed the socket already
+    if {![catch {eof $sock} eof] && $eof} {
+	if {[info exists $token]} {
+	    set state(connection) close
+	    Eof $token
+	} else {
+	    # open connection closed on a token that has been cleaned up.
+	    CloseSocket $sock
+	}
+	return
+    }
+}
+
+# http::getTextLine --
+#
+#	Get one line with the stream in blocking crlf mode
+#
+# Arguments
+#	sock	The socket receiving input.
+#
+# Results:
+#	The line of text, without trailing newline
+
+proc http::getTextLine {sock} {
+    set tr [fconfigure $sock -translation]
+    set bl [fconfigure $sock -blocking]
+    fconfigure $sock -translation crlf -blocking 1
+    set r [gets $sock]
+    fconfigure $sock -translation $tr -blocking $bl
+    return $r
+}
+
+# http::CopyStart
+#
+#	Error handling wrapper around fcopy
+#
+# Arguments
+#	sock	The socket to copy from
+#	token	The token returned from http::geturl
+#
+# Side Effects
+#	This closes the connection upon error
+
+proc http::CopyStart {sock token {initial 1}} {
+    upvar #0 $token state
+    if {[info exists state(transfer)] && $state(transfer) eq "chunked"} {
+	foreach coding [ContentEncoding $token] {
+	    lappend state(zlib) [zlib stream $coding]
+	}
+	make-transformation-chunked $sock [namespace code [list CopyChunk $token]]
+    } else {
+	if {$initial} {
+	    foreach coding [ContentEncoding $token] {
+		zlib push $coding $sock
+	    }
+	}
+	if {[catch {
+	    fcopy $sock $state(-channel) -size $state(-blocksize) -command \
+		[list http::CopyDone $token]
+	} err]} {
+	    Finish $token $err
+	}
+    }
+}
+
+proc http::CopyChunk {token chunk} {
+    upvar 0 $token state
+    if {[set count [string length $chunk]]} {
+	incr state(currentsize) $count
+	if {[info exists state(zlib)]} {
+	    foreach stream $state(zlib) {
+		set chunk [$stream add $chunk]
+	    }
+	}
+	puts -nonewline $state(-channel) $chunk
+	if {[info exists state(-progress)]} {
+	    eval [linsert $state(-progress) end \
+		      $token $state(totalsize) $state(currentsize)]
+	}
+    } else {
+	Log "CopyChunk Finish $token"
+	if {[info exists state(zlib)]} {
+	    set excess ""
+	    foreach stream $state(zlib) {
+		catch {set excess [$stream add -finalize $excess]}
+	    }
+	    puts -nonewline $state(-channel) $excess
+	    foreach stream $state(zlib) { $stream close }
+	    unset state(zlib)
+	}
+	Eof $token ;# FIX ME: pipelining.
+    }
+}
+
+# http::CopyDone
+#
+#	fcopy completion callback
+#
+# Arguments
+#	token	The token returned from http::geturl
+#	count	The amount transfered
+#
+# Side Effects
+#	Invokes callbacks
+
+proc http::CopyDone {token count {error {}}} {
+    variable $token
+    upvar 0 $token state
+    set sock $state(sock)
+    incr state(currentsize) $count
+    if {[info exists state(-progress)]} {
+	eval $state(-progress) \
+	    [list $token $state(totalsize) $state(currentsize)]
+    }
+    # At this point the token may have been reset
+    if {[string length $error]} {
+	Finish $token $error
+    } elseif {[catch {eof $sock} iseof] || $iseof} {
+	Eof $token
+    } else {
+	CopyStart $sock $token 0
+    }
+}
+
+# http::Eof
+#
+#	Handle eof on the socket
+#
+# Arguments
+#	token	The token returned from http::geturl
+#
+# Side Effects
+#	Clean up the socket
+
+proc http::Eof {token {force 0}} {
+    variable $token
+    upvar 0 $token state
+    if {$state(state) eq "header"} {
+	# Premature eof
+	set state(status) eof
+    } else {
+	set state(status) ok
+    }
+
+    if {[string length $state(body)] > 0} {
+	if {[catch {
+	    foreach coding [ContentEncoding $token] {
+		set state(body) [zlib $coding $state(body)]
+	    }
+	} err]} {
+	    Log "error doing decompression: $err"
+	    return [Finish $token $err]
+	}
+
+	if {!$state(binary)} {
+	    # If we are getting text, set the incoming channel's encoding
+	    # correctly.  iso8859-1 is the RFC default, but this could be any IANA
+	    # charset.  However, we only know how to convert what we have
+	    # encodings for.
+
+	    set enc [CharsetToEncoding $state(charset)]
+	    if {$enc ne "binary"} {
+		set state(body) [encoding convertfrom $enc $state(body)]
+	    }
+
+	    # Translate text line endings.
+	    set state(body) [string map {\r\n \n \r \n} $state(body)]
+	}
+    }
+    Finish $token
+}
+
+# http::wait --
+#
+#	See documentation for details.
+#
+# Arguments:
+#	token	Connection token.
+#
+# Results:
+#        The status after the wait.
+
+proc http::wait {token} {
+    variable $token
+    upvar 0 $token state
+
+    if {![info exists state(status)] || $state(status) eq ""} {
+	# We must wait on the original variable name, not the upvar alias
+	vwait ${token}(status)
+    }
+
+    return [status $token]
+}
+
+# http::formatQuery --
+#
+#	See documentation for details.  Call http::formatQuery with an even
+#	number of arguments, where the first is a name, the second is a value,
+#	the third is another name, and so on.
+#
+# Arguments:
+#	args	A list of name-value pairs.
+#
+# Results:
+#	TODO
+
+proc http::formatQuery {args} {
+    set result ""
+    set sep ""
+    foreach i $args {
+	append result $sep [mapReply $i]
+	if {$sep eq "="} {
+	    set sep &
+	} else {
+	    set sep =
+	}
+    }
+    return $result
+}
+
+# http::mapReply --
+#
+#	Do x-www-urlencoded character mapping
+#
+# Arguments:
+#	string	The string the needs to be encoded
+#
+# Results:
+#       The encoded string
+
+proc http::mapReply {string} {
+    variable http
+    variable formMap
+
+    # The spec says: "non-alphanumeric characters are replaced by '%HH'". Use
+    # a pre-computed map and [string map] to do the conversion (much faster
+    # than [regsub]/[subst]). [Bug 1020491]
+
+    if {$http(-urlencoding) ne ""} {
+	set string [encoding convertto $http(-urlencoding) $string]
+	return [string map $formMap $string]
+    }
+    set converted [string map $formMap $string]
+    if {[string match "*\[\u0100-\uffff\]*" $converted]} {
+	regexp "\[\u0100-\uffff\]" $converted badChar
+	# Return this error message for maximum compatability... :^/
+	return -code error \
+	    "can't read \"formMap($badChar)\": no such element in array"
+    }
+    return $converted
+}
+
+# http::ProxyRequired --
+#	Default proxy filter.
+#
+# Arguments:
+#	host	The destination host
+#
+# Results:
+#       The current proxy settings
+
+proc http::ProxyRequired {host} {
+    variable http
+    if {[info exists http(-proxyhost)] && [string length $http(-proxyhost)]} {
+	if {
+	    ![info exists http(-proxyport)] ||
+	    ![string length $http(-proxyport)]
+	} {
+	    set http(-proxyport) 8080
+	}
+	return [list $http(-proxyhost) $http(-proxyport)]
+    }
+}
+
+# http::CharsetToEncoding --
+#
+#	Tries to map a given IANA charset to a tcl encoding.  If no encoding
+#	can be found, returns binary.
+#
+
+proc http::CharsetToEncoding {charset} {
+    variable encodings
+
+    set charset [string tolower $charset]
+    if {[regexp {iso-?8859-([0-9]+)} $charset -> num]} {
+	set encoding "iso8859-$num"
+    } elseif {[regexp {iso-?2022-(jp|kr)} $charset -> ext]} {
+	set encoding "iso2022-$ext"
+    } elseif {[regexp {shift[-_]?js} $charset]} {
+	set encoding "shiftjis"
+    } elseif {[regexp {(?:windows|cp)-?([0-9]+)} $charset -> num]} {
+	set encoding "cp$num"
+    } elseif {$charset eq "us-ascii"} {
+	set encoding "ascii"
+    } elseif {[regexp {(?:iso-?)?lat(?:in)?-?([0-9]+)} $charset -> num]} {
+	switch -- $num {
+	    5 {set encoding "iso8859-9"}
+	    1 - 2 - 3 {
+		set encoding "iso8859-$num"
+	    }
+	}
+    } else {
+	# other charset, like euc-xx, utf-8,...  may directly map to encoding
+	set encoding $charset
+    }
+    set idx [lsearch -exact $encodings $encoding]
+    if {$idx >= 0} {
+	return $encoding
+    } else {
+	return "binary"
+    }
+}
+
+# Return the list of content-encoding transformations we need to do in order.
+proc http::ContentEncoding {token} {
+    upvar 0 $token state
+    set r {}
+    if {[info exists state(coding)]} {
+	foreach coding [split $state(coding) ,] {
+	    switch -exact -- $coding {
+		deflate { lappend r inflate }
+		gzip - x-gzip { lappend r gunzip }
+		compress - x-compress { lappend r decompress }
+		identity {}
+		default {
+		    return -code error "unsupported content-encoding \"$coding\""
+		}
+	    }
+	}
+    }
+    return $r
+}
+
+proc http::make-transformation-chunked {chan command} {
+    set lambda {{chan command} {
+        set data ""
+        set size -1
+        yield
+        while {1} {
+            chan configure $chan -translation {crlf binary}
+            while {[gets $chan line] < 1} { yield }
+            chan configure $chan -translation {binary binary}
+            if {[scan $line %x size] != 1} { return -code error "invalid size: \"$line\"" }
+            set chunk ""
+            while {$size && ![chan eof $chan]} {
+                set part [chan read $chan $size]
+                incr size -[string length $part]
+                append chunk $part
+            }
+            if {[catch {
+		uplevel #0 [linsert $command end $chunk]
+	    }]} {
+		http::Log "Error in callback: $::errorInfo"
+	    }
+            if {[string length $chunk] == 0} {
+		# channel might have been closed in the callback
+                catch {chan event $chan readable {}}
+                return
+            }
+        }
+    }}
+    coroutine dechunk$chan ::apply $lambda $chan $command
+    chan event $chan readable [namespace origin dechunk$chan]
+    return
+}
+
+# Local variables:
+# indent-tabs-mode: t
+# End:
diff --git a/library/http/pkgIndex.tcl b/library/http/pkgIndex.tcl
new file mode 100644
index 0000000..6e0301a
--- /dev/null
+++ b/library/http/pkgIndex.tcl
@@ -0,0 +1,2 @@
+if {![package vsatisfies [package provide Tcl] 8.6]} {return}
+package ifneeded http 2.8.9 [list tclPkgSetup $dir http 2.8.9 {{http.tcl source {::http::config ::http::formatQuery ::http::geturl ::http::reset ::http::wait ::http::register ::http::unregister ::http::mapReply}}}]
diff --git a/library/http1.0/http.tcl b/library/http1.0/http.tcl
new file mode 100644
index 0000000..8329de4
--- /dev/null
+++ b/library/http1.0/http.tcl
@@ -0,0 +1,377 @@
+# http.tcl
+# Client-side HTTP for GET, POST, and HEAD commands.
+# These routines can be used in untrusted code that uses the Safesock
+# security policy.
+# These procedures use a callback interface to avoid using vwait,
+# which is not defined in the safe base.
+#
+# See the http.n man page for documentation
+
+package provide http 1.0
+
+array set http {
+    -accept */*
+    -proxyhost {}
+    -proxyport {}
+    -useragent {Tcl http client package 1.0}
+    -proxyfilter httpProxyRequired
+}
+proc http_config {args} {
+    global http
+    set options [lsort [array names http -*]]
+    set usage [join $options ", "]
+    if {[llength $args] == 0} {
+	set result {}
+	foreach name $options {
+	    lappend result $name $http($name)
+	}
+	return $result
+    }
+    regsub -all -- - $options {} options
+    set pat ^-([join $options |])$
+    if {[llength $args] == 1} {
+	set flag [lindex $args 0]
+	if {[regexp -- $pat $flag]} {
+	    return $http($flag)
+	} else {
+	    return -code error "Unknown option $flag, must be: $usage"
+	}
+    } else {
+	foreach {flag value} $args {
+	    if {[regexp -- $pat $flag]} {
+		set http($flag) $value
+	    } else {
+		return -code error "Unknown option $flag, must be: $usage"
+	    }
+	}
+    }
+}
+
+ proc httpFinish { token {errormsg ""} } {
+    upvar #0 $token state
+    global errorInfo errorCode
+    if {[string length $errormsg] != 0} {
+	set state(error) [list $errormsg $errorInfo $errorCode]
+	set state(status) error
+    }
+    catch {close $state(sock)}
+    catch {after cancel $state(after)}
+    if {[info exists state(-command)]} {
+	if {[catch {eval $state(-command) {$token}} err]} {
+	    if {[string length $errormsg] == 0} {
+		set state(error) [list $err $errorInfo $errorCode]
+		set state(status) error
+	    }
+	}
+	unset state(-command)
+    }
+}
+proc http_reset { token {why reset} } {
+    upvar #0 $token state
+    set state(status) $why
+    catch {fileevent $state(sock) readable {}}
+    httpFinish $token
+    if {[info exists state(error)]} {
+	set errorlist $state(error)
+	unset state(error)
+	eval error $errorlist
+    }
+}
+proc http_get { url args } {
+    global http
+    if {![info exists http(uid)]} {
+	set http(uid) 0
+    }
+    set token http#[incr http(uid)]
+    upvar #0 $token state
+    http_reset $token
+    array set state {
+	-blocksize 	8192
+	-validate 	0
+	-headers 	{}
+	-timeout 	0
+	state		header
+	meta		{}
+	currentsize	0
+	totalsize	0
+        type            text/html
+        body            {}
+	status		""
+    }
+    set options {-blocksize -channel -command -handler -headers \
+		-progress -query -validate -timeout}
+    set usage [join $options ", "]
+    regsub -all -- - $options {} options
+    set pat ^-([join $options |])$
+    foreach {flag value} $args {
+	if {[regexp $pat $flag]} {
+	    # Validate numbers
+	    if {[info exists state($flag)] && \
+		    [regexp {^[0-9]+$} $state($flag)] && \
+		    ![regexp {^[0-9]+$} $value]} {
+		return -code error "Bad value for $flag ($value), must be integer"
+	    }
+	    set state($flag) $value
+	} else {
+	    return -code error "Unknown option $flag, can be: $usage"
+	}
+    }
+    if {! [regexp -nocase {^(http://)?([^/:]+)(:([0-9]+))?(/.*)?$} $url \
+	    x proto host y port srvurl]} {
+	error "Unsupported URL: $url"
+    }
+    if {[string length $port] == 0} {
+	set port 80
+    }
+    if {[string length $srvurl] == 0} {
+	set srvurl /
+    }
+    if {[string length $proto] == 0} {
+	set url http://$url
+    }
+    set state(url) $url
+    if {![catch {$http(-proxyfilter) $host} proxy]} {
+	set phost [lindex $proxy 0]
+	set pport [lindex $proxy 1]
+    }
+    if {$state(-timeout) > 0} {
+	set state(after) [after $state(-timeout) [list http_reset $token timeout]]
+    }
+    if {[info exists phost] && [string length $phost]} {
+	set srvurl $url
+	set s [socket $phost $pport]
+    } else {
+	set s [socket $host $port]
+    }
+    set state(sock) $s
+
+    # Send data in cr-lf format, but accept any line terminators
+
+    fconfigure $s -translation {auto crlf} -buffersize $state(-blocksize)
+
+    # The following is disallowed in safe interpreters, but the socket
+    # is already in non-blocking mode in that case.
+
+    catch {fconfigure $s -blocking off}
+    set len 0
+    set how GET
+    if {[info exists state(-query)]} {
+	set len [string length $state(-query)]
+	if {$len > 0} {
+	    set how POST
+	}
+    } elseif {$state(-validate)} {
+	set how HEAD
+    }
+    puts $s "$how $srvurl HTTP/1.0"
+    puts $s "Accept: $http(-accept)"
+    puts $s "Host: $host"
+    puts $s "User-Agent: $http(-useragent)"
+    foreach {key value} $state(-headers) {
+	regsub -all \[\n\r\]  $value {} value
+	set key [string trim $key]
+	if {[string length $key]} {
+	    puts $s "$key: $value"
+	}
+    }
+    if {$len > 0} {
+	puts $s "Content-Length: $len"
+	puts $s "Content-Type: application/x-www-form-urlencoded"
+	puts $s ""
+	fconfigure $s -translation {auto binary}
+	puts -nonewline $s $state(-query)
+    } else {
+	puts $s ""
+    }
+    flush $s
+    fileevent $s readable [list httpEvent $token]
+    if {! [info exists state(-command)]} {
+	http_wait $token
+    }
+    return $token
+}
+proc http_data {token} {
+    upvar #0 $token state
+    return $state(body)
+}
+proc http_status {token} {
+    upvar #0 $token state
+    return $state(status)
+}
+proc http_code {token} {
+    upvar #0 $token state
+    return $state(http)
+}
+proc http_size {token} {
+    upvar #0 $token state
+    return $state(currentsize)
+}
+
+ proc httpEvent {token} {
+    upvar #0 $token state
+    set s $state(sock)
+
+     if {[eof $s]} {
+	httpEof $token
+	return
+    }
+    if {$state(state) == "header"} {
+	set n [gets $s line]
+	if {$n == 0} {
+	    set state(state) body
+	    if {![regexp -nocase ^text $state(type)]} {
+		# Turn off conversions for non-text data
+		fconfigure $s -translation binary
+		if {[info exists state(-channel)]} {
+		    fconfigure $state(-channel) -translation binary
+		}
+	    }
+	    if {[info exists state(-channel)] &&
+		    ![info exists state(-handler)]} {
+		# Initiate a sequence of background fcopies
+		fileevent $s readable {}
+		httpCopyStart $s $token
+	    }
+	} elseif {$n > 0} {
+	    if {[regexp -nocase {^content-type:(.+)$} $line x type]} {
+		set state(type) [string trim $type]
+	    }
+	    if {[regexp -nocase {^content-length:(.+)$} $line x length]} {
+		set state(totalsize) [string trim $length]
+	    }
+	    if {[regexp -nocase {^([^:]+):(.+)$} $line x key value]} {
+		lappend state(meta) $key $value
+	    } elseif {[regexp ^HTTP $line]} {
+		set state(http) $line
+	    }
+	}
+    } else {
+	if {[catch {
+	    if {[info exists state(-handler)]} {
+		set n [eval $state(-handler) {$s $token}]
+	    } else {
+		set block [read $s $state(-blocksize)]
+		set n [string length $block]
+		if {$n >= 0} {
+		    append state(body) $block
+		}
+	    }
+	    if {$n >= 0} {
+		incr state(currentsize) $n
+	    }
+	} err]} {
+	    httpFinish $token $err
+	} else {
+	    if {[info exists state(-progress)]} {
+		eval $state(-progress) {$token $state(totalsize) $state(currentsize)}
+	    }
+	}
+    }
+}
+ proc httpCopyStart {s token} {
+    upvar #0 $token state
+    if {[catch {
+	fcopy $s $state(-channel) -size $state(-blocksize) -command \
+	    [list httpCopyDone $token]
+    } err]} {
+	httpFinish $token $err
+    }
+}
+ proc httpCopyDone {token count {error {}}} {
+    upvar #0 $token state
+    set s $state(sock)
+    incr state(currentsize) $count
+    if {[info exists state(-progress)]} {
+	eval $state(-progress) {$token $state(totalsize) $state(currentsize)}
+    }
+    if {([string length $error] != 0)} {
+	httpFinish $token $error
+    } elseif {[eof $s]} {
+	httpEof $token
+    } else {
+	httpCopyStart $s $token
+    }
+}
+ proc httpEof {token} {
+    upvar #0 $token state
+    if {$state(state) == "header"} {
+	# Premature eof
+	set state(status) eof
+    } else {
+	set state(status) ok
+    }
+    set state(state) eof
+    httpFinish $token
+}
+proc http_wait {token} {
+    upvar #0 $token state
+    if {![info exists state(status)] || [string length $state(status)] == 0} {
+	vwait $token\(status)
+    }
+    if {[info exists state(error)]} {
+	set errorlist $state(error)
+	unset state(error)
+	eval error $errorlist
+    }
+    return $state(status)
+}
+
+# Call http_formatQuery with an even number of arguments, where the first is
+# a name, the second is a value, the third is another name, and so on.
+
+proc http_formatQuery {args} {
+    set result ""
+    set sep ""
+    foreach i $args {
+	append result  $sep [httpMapReply $i]
+	if {$sep != "="} {
+	    set sep =
+	} else {
+	    set sep &
+	}
+    }
+    return $result
+}
+
+# do x-www-urlencoded character mapping
+# The spec says: "non-alphanumeric characters are replaced by '%HH'"
+# 1 leave alphanumerics characters alone
+# 2 Convert every other character to an array lookup
+# 3 Escape constructs that are "special" to the tcl parser
+# 4 "subst" the result, doing all the array substitutions
+
+ proc httpMapReply {string} {
+    global httpFormMap
+    set alphanumeric	a-zA-Z0-9
+    if {![info exists httpFormMap]} {
+
+	for {set i 1} {$i <= 256} {incr i} {
+	    set c [format %c $i]
+	    if {![string match \[$alphanumeric\] $c]} {
+		set httpFormMap($c) %[format %.2x $i]
+	    }
+	}
+	# These are handled specially
+	array set httpFormMap {
+	    " " +   \n %0d%0a
+	}
+    }
+    regsub -all \[^$alphanumeric\] $string {$httpFormMap(&)} string
+    regsub -all \n $string {\\n} string
+    regsub -all \t $string {\\t} string
+    regsub -all {[][{})\\]\)} $string {\\&} string
+    return [subst $string]
+}
+
+# Default proxy filter.
+ proc httpProxyRequired {host} {
+    global http
+    if {[info exists http(-proxyhost)] && [string length $http(-proxyhost)]} {
+	if {![info exists http(-proxyport)] || ![string length $http(-proxyport)]} {
+	    set http(-proxyport) 8080
+	}
+	return [list $http(-proxyhost) $http(-proxyport)]
+    } else {
+	return {}
+    }
+}
diff --git a/library/http1.0/pkgIndex.tcl b/library/http1.0/pkgIndex.tcl
new file mode 100644
index 0000000..ab6170f
--- /dev/null
+++ b/library/http1.0/pkgIndex.tcl
@@ -0,0 +1,11 @@
+# Tcl package index file, version 1.0
+# This file is generated by the "pkg_mkIndex" command
+# and sourced either when an application starts up or
+# by a "package unknown" script.  It invokes the
+# "package ifneeded" command to set up package-related
+# information so that packages will be loaded automatically
+# in response to "package require" commands.  When this
+# script is sourced, the variable $dir must contain the
+# full path name of this file's directory.
+
+package ifneeded http 1.0 [list tclPkgSetup $dir http 1.0 {{http.tcl source {httpCopyDone httpCopyStart httpEof httpEvent httpFinish httpMapReply httpProxyRequired http_code http_config http_data http_formatQuery http_get http_reset http_size http_status http_wait}}}]
diff --git a/library/init.tcl b/library/init.tcl
new file mode 100644
index 0000000..9ca4514
--- /dev/null
+++ b/library/init.tcl
@@ -0,0 +1,818 @@
+# init.tcl --
+#
+# Default system startup file for Tcl-based applications.  Defines
+# "unknown" procedure and auto-load facilities.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994-1996 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 Scriptics Corporation.
+# Copyright (c) 2004 by Kevin B. Kenny.  All rights reserved.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+
+# This test intentionally written in pre-7.5 Tcl
+if {[info commands package] == ""} {
+    error "version mismatch: library\nscripts expect Tcl version 7.5b1 or later but the loaded version is\nonly [info patchlevel]"
+}
+package require -exact Tcl 8.6.6
+
+# Compute the auto path to use in this interpreter.
+# The values on the path come from several locations:
+#
+# The environment variable TCLLIBPATH
+#
+# tcl_library, which is the directory containing this init.tcl script.
+# [tclInit] (Tcl_Init()) searches around for the directory containing this
+# init.tcl and defines tcl_library to that location before sourcing it.
+#
+# The parent directory of tcl_library. Adding the parent
+# means that packages in peer directories will be found automatically.
+#
+# Also add the directory ../lib relative to the directory where the
+# executable is located.  This is meant to find binary packages for the
+# same architecture as the current executable.
+#
+# tcl_pkgPath, which is set by the platform-specific initialization routines
+#	On UNIX it is compiled in
+#       On Windows, it is not used
+
+if {![info exists auto_path]} {
+    if {[info exists env(TCLLIBPATH)]} {
+	set auto_path $env(TCLLIBPATH)
+    } else {
+	set auto_path ""
+    }
+}
+namespace eval tcl {
+    variable Dir
+    foreach Dir [list $::tcl_library [file dirname $::tcl_library]] {
+	if {$Dir ni $::auto_path} {
+	    lappend ::auto_path $Dir
+	}
+    }
+    set Dir [file join [file dirname [file dirname \
+	    [info nameofexecutable]]] lib]
+    if {$Dir ni $::auto_path} {
+	lappend ::auto_path $Dir
+    }
+    catch {
+	foreach Dir $::tcl_pkgPath {
+	    if {$Dir ni $::auto_path} {
+		lappend ::auto_path $Dir
+	    }
+	}
+    }
+
+    if {![interp issafe]} {
+        variable Path [encoding dirs]
+        set Dir [file join $::tcl_library encoding]
+        if {$Dir ni $Path} {
+	    lappend Path $Dir
+	    encoding dirs $Path
+        }
+    }
+
+    # TIP #255 min and max functions
+    namespace eval mathfunc {
+	proc min {args} {
+	    if {![llength $args]} {
+		return -code error \
+		    "too few arguments to math function \"min\""
+	    }
+	    set val Inf
+	    foreach arg $args {
+		# This will handle forcing the numeric value without
+		# ruining the internal type of a numeric object
+		if {[catch {expr {double($arg)}} err]} {
+		    return -code error $err
+		}
+		if {$arg < $val} {set val $arg}
+	    }
+	    return $val
+	}
+	proc max {args} {
+	    if {![llength $args]} {
+		return -code error \
+		    "too few arguments to math function \"max\""
+	    }
+	    set val -Inf
+	    foreach arg $args {
+		# This will handle forcing the numeric value without
+		# ruining the internal type of a numeric object
+		if {[catch {expr {double($arg)}} err]} {
+		    return -code error $err
+		}
+		if {$arg > $val} {set val $arg}
+	    }
+	    return $val
+	}
+	namespace export min max
+    }
+}
+
+# Windows specific end of initialization
+
+if {(![interp issafe]) && ($tcl_platform(platform) eq "windows")} {
+    namespace eval tcl {
+	proc EnvTraceProc {lo n1 n2 op} {
+	    global env
+	    set x $env($n2)
+	    set env($lo) $x
+	    set env([string toupper $lo]) $x
+	}
+	proc InitWinEnv {} {
+	    global env tcl_platform
+	    foreach p [array names env] {
+		set u [string toupper $p]
+		if {$u ne $p} {
+		    switch -- $u {
+			COMSPEC -
+			PATH {
+			    set temp $env($p)
+			    unset env($p)
+			    set env($u) $temp
+			    trace add variable env($p) write \
+				    [namespace code [list EnvTraceProc $p]]
+			    trace add variable env($u) write \
+				    [namespace code [list EnvTraceProc $p]]
+			}
+		    }
+		}
+	    }
+	    if {![info exists env(COMSPEC)]} {
+		set env(COMSPEC) cmd.exe
+	    }
+	}
+	InitWinEnv
+    }
+}
+
+# Setup the unknown package handler
+
+
+if {[interp issafe]} {
+    package unknown {::tcl::tm::UnknownHandler ::tclPkgUnknown}
+} else {
+    # Set up search for Tcl Modules (TIP #189).
+    # and setup platform specific unknown package handlers
+    if {$tcl_platform(os) eq "Darwin"
+	    && $tcl_platform(platform) eq "unix"} {
+	package unknown {::tcl::tm::UnknownHandler \
+		{::tcl::MacOSXPkgUnknown ::tclPkgUnknown}}
+    } else {
+	package unknown {::tcl::tm::UnknownHandler ::tclPkgUnknown}
+    }
+
+    # Set up the 'clock' ensemble
+
+    namespace eval ::tcl::clock [list variable TclLibDir $::tcl_library]
+
+    proc clock args {
+	namespace eval ::tcl::clock [list namespace ensemble create -command \
+		[uplevel 1 [list namespace origin [lindex [info level 0] 0]]] \
+		-subcommands {
+		    add clicks format microseconds milliseconds scan seconds
+		}]
+
+	# Auto-loading stubs for 'clock.tcl'
+
+	foreach cmd {add format scan} {
+	    proc ::tcl::clock::$cmd args {
+		variable TclLibDir
+		source -encoding utf-8 [file join $TclLibDir clock.tcl]
+		return [uplevel 1 [info level 0]]
+	    }
+	}
+
+	return [uplevel 1 [info level 0]]
+    }
+}
+
+# Conditionalize for presence of exec.
+
+if {[namespace which -command exec] eq ""} {
+
+    # Some machines do not have exec. Also, on all
+    # platforms, safe interpreters do not have exec.
+
+    set auto_noexec 1
+}
+
+# Define a log command (which can be overwitten to log errors
+# differently, specially when stderr is not available)
+
+if {[namespace which -command tclLog] eq ""} {
+    proc tclLog {string} {
+	catch {puts stderr $string}
+    }
+}
+
+# unknown --
+# This procedure is called when a Tcl command is invoked that doesn't
+# exist in the interpreter.  It takes the following steps to make the
+# command available:
+#
+#	1. See if the autoload facility can locate the command in a
+#	   Tcl script file.  If so, load it and execute it.
+#	2. If the command was invoked interactively at top-level:
+#	    (a) see if the command exists as an executable UNIX program.
+#		If so, "exec" the command.
+#	    (b) see if the command requests csh-like history substitution
+#		in one of the common forms !!, !<number>, or ^old^new.  If
+#		so, emulate csh's history substitution.
+#	    (c) see if the command is a unique abbreviation for another
+#		command.  If so, invoke the command.
+#
+# Arguments:
+# args -	A list whose elements are the words of the original
+#		command, including the command name.
+
+proc unknown args {
+    variable ::tcl::UnknownPending
+    global auto_noexec auto_noload env tcl_interactive errorInfo errorCode
+
+    if {[info exists errorInfo]} {
+	set savedErrorInfo $errorInfo
+    }
+    if {[info exists errorCode]} {
+	set savedErrorCode $errorCode
+    }
+
+    set name [lindex $args 0]
+    if {![info exists auto_noload]} {
+	#
+	# Make sure we're not trying to load the same proc twice.
+	#
+	if {[info exists UnknownPending($name)]} {
+	    return -code error "self-referential recursion\
+		    in \"unknown\" for command \"$name\""
+	}
+	set UnknownPending($name) pending
+	set ret [catch {
+		auto_load $name [uplevel 1 {::namespace current}]
+	} msg opts]
+	unset UnknownPending($name)
+	if {$ret != 0} {
+	    dict append opts -errorinfo "\n    (autoloading \"$name\")"
+	    return -options $opts $msg
+	}
+	if {![array size UnknownPending]} {
+	    unset UnknownPending
+	}
+	if {$msg} {
+	    if {[info exists savedErrorCode]} {
+		set ::errorCode $savedErrorCode
+	    } else {
+		unset -nocomplain ::errorCode
+	    }
+	    if {[info exists savedErrorInfo]} {
+		set errorInfo $savedErrorInfo
+	    } else {
+		unset -nocomplain errorInfo
+	    }
+	    set code [catch {uplevel 1 $args} msg opts]
+	    if {$code ==  1} {
+		#
+		# Compute stack trace contribution from the [uplevel].
+		# Note the dependence on how Tcl_AddErrorInfo, etc.
+		# construct the stack trace.
+		#
+		set errInfo [dict get $opts -errorinfo]
+		set errCode [dict get $opts -errorcode]
+		set cinfo $args
+		if {[string bytelength $cinfo] > 150} {
+		    set cinfo [string range $cinfo 0 150]
+		    while {[string bytelength $cinfo] > 150} {
+			set cinfo [string range $cinfo 0 end-1]
+		    }
+		    append cinfo ...
+		}
+		append cinfo "\"\n    (\"uplevel\" body line 1)"
+		append cinfo "\n    invoked from within"
+		append cinfo "\n\"uplevel 1 \$args\""
+		#
+		# Try each possible form of the stack trace
+		# and trim the extra contribution from the matching case
+		#
+		set expect "$msg\n    while executing\n\"$cinfo"
+		if {$errInfo eq $expect} {
+		    #
+		    # The stack has only the eval from the expanded command
+		    # Do not generate any stack trace here.
+		    #
+		    dict unset opts -errorinfo
+		    dict incr opts -level
+		    return -options $opts $msg
+		}
+		#
+		# Stack trace is nested, trim off just the contribution
+		# from the extra "eval" of $args due to the "catch" above.
+		#
+		set expect "\n    invoked from within\n\"$cinfo"
+		set exlen [string length $expect]
+		set eilen [string length $errInfo]
+		set i [expr {$eilen - $exlen - 1}]
+		set einfo [string range $errInfo 0 $i]
+		#
+		# For now verify that $errInfo consists of what we are about
+		# to return plus what we expected to trim off.
+		#
+		if {$errInfo ne "$einfo$expect"} {
+		    error "Tcl bug: unexpected stack trace in \"unknown\"" {} \
+			[list CORE UNKNOWN BADTRACE $einfo $expect $errInfo]
+		}
+		return -code error -errorcode $errCode \
+			-errorinfo $einfo $msg
+	    } else {
+		dict incr opts -level
+		return -options $opts $msg
+	    }
+	}
+    }
+
+    if {([info level] == 1) && ([info script] eq "")
+	    && [info exists tcl_interactive] && $tcl_interactive} {
+	if {![info exists auto_noexec]} {
+	    set new [auto_execok $name]
+	    if {$new ne ""} {
+		set redir ""
+		if {[namespace which -command console] eq ""} {
+		    set redir ">&@stdout <@stdin"
+		}
+		uplevel 1 [list ::catch \
+			[concat exec $redir $new [lrange $args 1 end]] \
+			::tcl::UnknownResult ::tcl::UnknownOptions]
+		dict incr ::tcl::UnknownOptions -level
+		return -options $::tcl::UnknownOptions $::tcl::UnknownResult
+	    }
+	}
+	if {$name eq "!!"} {
+	    set newcmd [history event]
+	} elseif {[regexp {^!(.+)$} $name -> event]} {
+	    set newcmd [history event $event]
+	} elseif {[regexp {^\^([^^]*)\^([^^]*)\^?$} $name -> old new]} {
+	    set newcmd [history event -1]
+	    catch {regsub -all -- $old $newcmd $new newcmd}
+	}
+	if {[info exists newcmd]} {
+	    tclLog $newcmd
+	    history change $newcmd 0
+	    uplevel 1 [list ::catch $newcmd \
+		    ::tcl::UnknownResult ::tcl::UnknownOptions]
+	    dict incr ::tcl::UnknownOptions -level
+	    return -options $::tcl::UnknownOptions $::tcl::UnknownResult
+	}
+
+	set ret [catch {set candidates [info commands $name*]} msg]
+	if {$name eq "::"} {
+	    set name ""
+	}
+	if {$ret != 0} {
+	    dict append opts -errorinfo \
+		    "\n    (expanding command prefix \"$name\" in unknown)"
+	    return -options $opts $msg
+	}
+	# Filter out bogus matches when $name contained
+	# a glob-special char [Bug 946952]
+	if {$name eq ""} {
+	    # Handle empty $name separately due to strangeness
+	    # in [string first] (See RFE 1243354)
+	    set cmds $candidates
+	} else {
+	    set cmds [list]
+	    foreach x $candidates {
+		if {[string first $name $x] == 0} {
+		    lappend cmds $x
+		}
+	    }
+	}
+	if {[llength $cmds] == 1} {
+	    uplevel 1 [list ::catch [lreplace $args 0 0 [lindex $cmds 0]] \
+		    ::tcl::UnknownResult ::tcl::UnknownOptions]
+	    dict incr ::tcl::UnknownOptions -level
+	    return -options $::tcl::UnknownOptions $::tcl::UnknownResult
+	}
+	if {[llength $cmds]} {
+	    return -code error "ambiguous command name \"$name\": [lsort $cmds]"
+	}
+    }
+    return -code error -errorcode [list TCL LOOKUP COMMAND $name] \
+	"invalid command name \"$name\""
+}
+
+# auto_load --
+# Checks a collection of library directories to see if a procedure
+# is defined in one of them.  If so, it sources the appropriate
+# library file to create the procedure.  Returns 1 if it successfully
+# loaded the procedure, 0 otherwise.
+#
+# Arguments:
+# cmd -			Name of the command to find and load.
+# namespace (optional)  The namespace where the command is being used - must be
+#                       a canonical namespace as returned [namespace current]
+#                       for instance. If not given, namespace current is used.
+
+proc auto_load {cmd {namespace {}}} {
+    global auto_index auto_path
+
+    if {$namespace eq ""} {
+	set namespace [uplevel 1 [list ::namespace current]]
+    }
+    set nameList [auto_qualify $cmd $namespace]
+    # workaround non canonical auto_index entries that might be around
+    # from older auto_mkindex versions
+    lappend nameList $cmd
+    foreach name $nameList {
+	if {[info exists auto_index($name)]} {
+	    namespace eval :: $auto_index($name)
+	    # There's a couple of ways to look for a command of a given
+	    # name.  One is to use
+	    #    info commands $name
+	    # Unfortunately, if the name has glob-magic chars in it like *
+	    # or [], it may not match.  For our purposes here, a better
+	    # route is to use
+	    #    namespace which -command $name
+	    if {[namespace which -command $name] ne ""} {
+		return 1
+	    }
+	}
+    }
+    if {![info exists auto_path]} {
+	return 0
+    }
+
+    if {![auto_load_index]} {
+	return 0
+    }
+    foreach name $nameList {
+	if {[info exists auto_index($name)]} {
+	    namespace eval :: $auto_index($name)
+	    if {[namespace which -command $name] ne ""} {
+		return 1
+	    }
+	}
+    }
+    return 0
+}
+
+# auto_load_index --
+# Loads the contents of tclIndex files on the auto_path directory
+# list.  This is usually invoked within auto_load to load the index
+# of available commands.  Returns 1 if the index is loaded, and 0 if
+# the index is already loaded and up to date.
+#
+# Arguments:
+# None.
+
+proc auto_load_index {} {
+    variable ::tcl::auto_oldpath
+    global auto_index auto_path
+
+    if {[info exists auto_oldpath] && ($auto_oldpath eq $auto_path)} {
+	return 0
+    }
+    set auto_oldpath $auto_path
+
+    # Check if we are a safe interpreter. In that case, we support only
+    # newer format tclIndex files.
+
+    set issafe [interp issafe]
+    for {set i [expr {[llength $auto_path] - 1}]} {$i >= 0} {incr i -1} {
+	set dir [lindex $auto_path $i]
+	set f ""
+	if {$issafe} {
+	    catch {source [file join $dir tclIndex]}
+	} elseif {[catch {set f [open [file join $dir tclIndex]]}]} {
+	    continue
+	} else {
+	    set error [catch {
+		set id [gets $f]
+		if {$id eq "# Tcl autoload index file, version 2.0"} {
+		    eval [read $f]
+		} elseif {$id eq "# Tcl autoload index file: each line identifies a Tcl"} {
+		    while {[gets $f line] >= 0} {
+			if {([string index $line 0] eq "#") \
+				|| ([llength $line] != 2)} {
+			    continue
+			}
+			set name [lindex $line 0]
+			set auto_index($name) \
+				"source [file join $dir [lindex $line 1]]"
+		    }
+		} else {
+		    error "[file join $dir tclIndex] isn't a proper Tcl index file"
+		}
+	    } msg opts]
+	    if {$f ne ""} {
+		close $f
+	    }
+	    if {$error} {
+		return -options $opts $msg
+	    }
+	}
+    }
+    return 1
+}
+
+# auto_qualify --
+#
+# Compute a fully qualified names list for use in the auto_index array.
+# For historical reasons, commands in the global namespace do not have leading
+# :: in the index key. The list has two elements when the command name is
+# relative (no leading ::) and the namespace is not the global one. Otherwise
+# only one name is returned (and searched in the auto_index).
+#
+# Arguments -
+# cmd		The command name. Can be any name accepted for command
+#               invocations (Like "foo::::bar").
+# namespace	The namespace where the command is being used - must be
+#               a canonical namespace as returned by [namespace current]
+#               for instance.
+
+proc auto_qualify {cmd namespace} {
+
+    # count separators and clean them up
+    # (making sure that foo:::::bar will be treated as foo::bar)
+    set n [regsub -all {::+} $cmd :: cmd]
+
+    # Ignore namespace if the name starts with ::
+    # Handle special case of only leading ::
+
+    # Before each return case we give an example of which category it is
+    # with the following form :
+    # (inputCmd, inputNameSpace) -> output
+
+    if {[string match ::* $cmd]} {
+	if {$n > 1} {
+	    # (::foo::bar , *) -> ::foo::bar
+	    return [list $cmd]
+	} else {
+	    # (::global , *) -> global
+	    return [list [string range $cmd 2 end]]
+	}
+    }
+
+    # Potentially returning 2 elements to try  :
+    # (if the current namespace is not the global one)
+
+    if {$n == 0} {
+	if {$namespace eq "::"} {
+	    # (nocolons , ::) -> nocolons
+	    return [list $cmd]
+	} else {
+	    # (nocolons , ::sub) -> ::sub::nocolons nocolons
+	    return [list ${namespace}::$cmd $cmd]
+	}
+    } elseif {$namespace eq "::"} {
+	#  (foo::bar , ::) -> ::foo::bar
+	return [list ::$cmd]
+    } else {
+	# (foo::bar , ::sub) -> ::sub::foo::bar ::foo::bar
+	return [list ${namespace}::$cmd ::$cmd]
+    }
+}
+
+# auto_import --
+#
+# Invoked during "namespace import" to make see if the imported commands
+# reside in an autoloaded library.  If so, the commands are loaded so
+# that they will be available for the import links.  If not, then this
+# procedure does nothing.
+#
+# Arguments -
+# pattern	The pattern of commands being imported (like "foo::*")
+#               a canonical namespace as returned by [namespace current]
+
+proc auto_import {pattern} {
+    global auto_index
+
+    # If no namespace is specified, this will be an error case
+
+    if {![string match *::* $pattern]} {
+	return
+    }
+
+    set ns [uplevel 1 [list ::namespace current]]
+    set patternList [auto_qualify $pattern $ns]
+
+    auto_load_index
+
+    foreach pattern $patternList {
+        foreach name [array names auto_index $pattern] {
+            if {([namespace which -command $name] eq "")
+		    && ([namespace qualifiers $pattern] eq [namespace qualifiers $name])} {
+                namespace eval :: $auto_index($name)
+            }
+        }
+    }
+}
+
+# auto_execok --
+#
+# Returns string that indicates name of program to execute if
+# name corresponds to a shell builtin or an executable in the
+# Windows search path, or "" otherwise.  Builds an associative
+# array auto_execs that caches information about previous checks,
+# for speed.
+#
+# Arguments:
+# name -			Name of a command.
+
+if {$tcl_platform(platform) eq "windows"} {
+# Windows version.
+#
+# Note that info executable doesn't work under Windows, so we have to
+# look for files with .exe, .com, or .bat extensions.  Also, the path
+# may be in the Path or PATH environment variables, and path
+# components are separated with semicolons, not colons as under Unix.
+#
+proc auto_execok name {
+    global auto_execs env tcl_platform
+
+    if {[info exists auto_execs($name)]} {
+	return $auto_execs($name)
+    }
+    set auto_execs($name) ""
+
+    set shellBuiltins [list cls copy date del dir echo erase md mkdir \
+	    mklink rd ren rename rmdir start time type ver vol]
+    if {[info exists env(PATHEXT)]} {
+	# Add an initial ; to have the {} extension check first.
+	set execExtensions [split ";$env(PATHEXT)" ";"]
+    } else {
+	set execExtensions [list {} .com .exe .bat .cmd]
+    }
+
+    if {[string tolower $name] in $shellBuiltins} {
+	# When this is command.com for some reason on Win2K, Tcl won't
+	# exec it unless the case is right, which this corrects.  COMSPEC
+	# may not point to a real file, so do the check.
+	set cmd $env(COMSPEC)
+	if {[file exists $cmd]} {
+	    set cmd [file attributes $cmd -shortname]
+	}
+	return [set auto_execs($name) [list $cmd /c $name]]
+    }
+
+    if {[llength [file split $name]] != 1} {
+	foreach ext $execExtensions {
+	    set file ${name}${ext}
+	    if {[file exists $file] && ![file isdirectory $file]} {
+		return [set auto_execs($name) [list $file]]
+	    }
+	}
+	return ""
+    }
+
+    set path "[file dirname [info nameof]];.;"
+    if {[info exists env(WINDIR)]} {
+	set windir $env(WINDIR)
+    }
+    if {[info exists windir]} {
+	if {$tcl_platform(os) eq "Windows NT"} {
+	    append path "$windir/system32;"
+	}
+	append path "$windir/system;$windir;"
+    }
+
+    foreach var {PATH Path path} {
+	if {[info exists env($var)]} {
+	    append path ";$env($var)"
+	}
+    }
+
+    foreach ext $execExtensions {
+	unset -nocomplain checked
+	foreach dir [split $path {;}] {
+	    # Skip already checked directories
+	    if {[info exists checked($dir)] || ($dir eq "")} {
+		continue
+	    }
+	    set checked($dir) {}
+	    set file [file join $dir ${name}${ext}]
+	    if {[file exists $file] && ![file isdirectory $file]} {
+		return [set auto_execs($name) [list $file]]
+	    }
+	}
+    }
+    return ""
+}
+
+} else {
+# Unix version.
+#
+proc auto_execok name {
+    global auto_execs env
+
+    if {[info exists auto_execs($name)]} {
+	return $auto_execs($name)
+    }
+    set auto_execs($name) ""
+    if {[llength [file split $name]] != 1} {
+	if {[file executable $name] && ![file isdirectory $name]} {
+	    set auto_execs($name) [list $name]
+	}
+	return $auto_execs($name)
+    }
+    foreach dir [split $env(PATH) :] {
+	if {$dir eq ""} {
+	    set dir .
+	}
+	set file [file join $dir $name]
+	if {[file executable $file] && ![file isdirectory $file]} {
+	    set auto_execs($name) [list $file]
+	    return $auto_execs($name)
+	}
+    }
+    return ""
+}
+
+}
+
+# ::tcl::CopyDirectory --
+#
+# This procedure is called by Tcl's core when attempts to call the
+# filesystem's copydirectory function fail.  The semantics of the call
+# are that 'dest' does not yet exist, i.e. dest should become the exact
+# image of src.  If dest does exist, we throw an error.
+#
+# Note that making changes to this procedure can change the results
+# of running Tcl's tests.
+#
+# Arguments:
+# action -              "renaming" or "copying"
+# src -			source directory
+# dest -		destination directory
+proc tcl::CopyDirectory {action src dest} {
+    set nsrc [file normalize $src]
+    set ndest [file normalize $dest]
+
+    if {$action eq "renaming"} {
+	# Can't rename volumes.  We could give a more precise
+	# error message here, but that would break the test suite.
+	if {$nsrc in [file volumes]} {
+	    return -code error "error $action \"$src\" to\
+	      \"$dest\": trying to rename a volume or move a directory\
+	      into itself"
+	}
+    }
+    if {[file exists $dest]} {
+	if {$nsrc eq $ndest} {
+	    return -code error "error $action \"$src\" to\
+	      \"$dest\": trying to rename a volume or move a directory\
+	      into itself"
+	}
+	if {$action eq "copying"} {
+	    # We used to throw an error here, but, looking more closely
+	    # at the core copy code in tclFCmd.c, if the destination
+	    # exists, then we should only call this function if -force
+	    # is true, which means we just want to over-write.  So,
+	    # the following code is now commented out.
+	    #
+	    # return -code error "error $action \"$src\" to\
+	    # \"$dest\": file already exists"
+	} else {
+	    # Depending on the platform, and on the current
+	    # working directory, the directories '.', '..'
+	    # can be returned in various combinations.  Anyway,
+	    # if any other file is returned, we must signal an error.
+	    set existing [glob -nocomplain -directory $dest * .*]
+	    lappend existing {*}[glob -nocomplain -directory $dest \
+		    -type hidden * .*]
+	    foreach s $existing {
+		if {[file tail $s] ni {. ..}} {
+		    return -code error "error $action \"$src\" to\
+		      \"$dest\": file already exists"
+		}
+	    }
+	}
+    } else {
+	if {[string first $nsrc $ndest] != -1} {
+	    set srclen [expr {[llength [file split $nsrc]] - 1}]
+	    set ndest [lindex [file split $ndest] $srclen]
+	    if {$ndest eq [file tail $nsrc]} {
+		return -code error "error $action \"$src\" to\
+		  \"$dest\": trying to rename a volume or move a directory\
+		  into itself"
+	    }
+	}
+	file mkdir $dest
+    }
+    # Have to be careful to capture both visible and hidden files.
+    # We will also be more generous to the file system and not
+    # assume the hidden and non-hidden lists are non-overlapping.
+    #
+    # On Unix 'hidden' files begin with '.'.  On other platforms
+    # or filesystems hidden files may have other interpretations.
+    set filelist [concat [glob -nocomplain -directory $src *] \
+      [glob -nocomplain -directory $src -types hidden *]]
+
+    foreach s [lsort -unique $filelist] {
+	if {[file tail $s] ni {. ..}} {
+	    file copy -force -- $s [file join $dest [file tail $s]]
+	}
+    }
+    return
+}
diff --git a/library/msgcat/msgcat.tcl b/library/msgcat/msgcat.tcl
new file mode 100644
index 0000000..a43f13e
--- /dev/null
+++ b/library/msgcat/msgcat.tcl
@@ -0,0 +1,1210 @@
+# msgcat.tcl --
+#
+#	This file defines various procedures which implement a
+#	message catalog facility for Tcl programs.  It should be
+#	loaded with the command "package require msgcat".
+#
+# Copyright (c) 2010-2015 by Harald Oehlmann.
+# Copyright (c) 1998-2000 by Ajuba Solutions.
+# Copyright (c) 1998 by Mark Harrison.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+package require Tcl 8.5
+# When the version number changes, be sure to update the pkgIndex.tcl file,
+# and the installation directory in the Makefiles.
+package provide msgcat 1.6.0
+
+namespace eval msgcat {
+    namespace export mc mcexists mcload mclocale mcmax mcmset mcpreferences mcset\
+            mcunknown mcflset mcflmset mcloadedlocales mcforgetpackage\
+	    mcpackageconfig mcpackagelocale
+
+    # Records the list of locales to search
+    variable Loclist {}
+
+    # List of currently loaded locales
+    variable LoadedLocales {}
+
+    # Records the locale of the currently sourced message catalogue file
+    variable FileLocale
+
+    # Configuration values per Package (e.g. client namespace).
+    # The dict key is of the form "<option> <namespace>" and the value is the
+    # configuration option. A nonexisting key is an unset option.
+    variable PackageConfig [dict create mcfolder {} loadcmd {} changecmd {}\
+	    unknowncmd {} loadedlocales {} loclist {}]
+
+    # Records the mapping between source strings and translated strings.  The
+    # dict key is of the form "<namespace> <locale> <src>", where locale and
+    # namespace should be themselves dict values and the value is
+    # the translated string.
+    variable Msgs [dict create]
+
+    # Map of language codes used in Windows registry to those of ISO-639
+    if {[info sharedlibextension] eq ".dll"} {
+	variable WinRegToISO639 [dict create  {*}{
+	    01 ar 0401 ar_SA 0801 ar_IQ 0c01 ar_EG 1001 ar_LY 1401 ar_DZ
+		  1801 ar_MA 1c01 ar_TN 2001 ar_OM 2401 ar_YE 2801 ar_SY
+		  2c01 ar_JO 3001 ar_LB 3401 ar_KW 3801 ar_AE 3c01 ar_BH
+		  4001 ar_QA
+	    02 bg 0402 bg_BG
+	    03 ca 0403 ca_ES
+	    04 zh 0404 zh_TW 0804 zh_CN 0c04 zh_HK 1004 zh_SG 1404 zh_MO
+	    05 cs 0405 cs_CZ
+	    06 da 0406 da_DK
+	    07 de 0407 de_DE 0807 de_CH 0c07 de_AT 1007 de_LU 1407 de_LI
+	    08 el 0408 el_GR
+	    09 en 0409 en_US 0809 en_GB 0c09 en_AU 1009 en_CA 1409 en_NZ
+		  1809 en_IE 1c09 en_ZA 2009 en_JM 2409 en_GD 2809 en_BZ
+		  2c09 en_TT 3009 en_ZW 3409 en_PH
+	    0a es 040a es_ES 080a es_MX 0c0a es_ES@modern 100a es_GT 140a es_CR
+		  180a es_PA 1c0a es_DO 200a es_VE 240a es_CO 280a es_PE
+		  2c0a es_AR 300a es_EC 340a es_CL 380a es_UY 3c0a es_PY
+		  400a es_BO 440a es_SV 480a es_HN 4c0a es_NI 500a es_PR
+	    0b fi 040b fi_FI
+	    0c fr 040c fr_FR 080c fr_BE 0c0c fr_CA 100c fr_CH 140c fr_LU
+		  180c fr_MC
+	    0d he 040d he_IL
+	    0e hu 040e hu_HU
+	    0f is 040f is_IS
+	    10 it 0410 it_IT 0810 it_CH
+	    11 ja 0411 ja_JP
+	    12 ko 0412 ko_KR
+	    13 nl 0413 nl_NL 0813 nl_BE
+	    14 no 0414 no_NO 0814 nn_NO
+	    15 pl 0415 pl_PL
+	    16 pt 0416 pt_BR 0816 pt_PT
+	    17 rm 0417 rm_CH
+	    18 ro 0418 ro_RO 0818 ro_MO
+	    19 ru 0819 ru_MO
+	    1a hr 041a hr_HR 081a sr_YU 0c1a sr_YU@cyrillic
+	    1b sk 041b sk_SK
+	    1c sq 041c sq_AL
+	    1d sv 041d sv_SE 081d sv_FI
+	    1e th 041e th_TH
+	    1f tr 041f tr_TR
+	    20 ur 0420 ur_PK 0820 ur_IN
+	    21 id 0421 id_ID
+	    22 uk 0422 uk_UA
+	    23 be 0423 be_BY
+	    24 sl 0424 sl_SI
+	    25 et 0425 et_EE
+	    26 lv 0426 lv_LV
+	    27 lt 0427 lt_LT
+	    28 tg 0428 tg_TJ
+	    29 fa 0429 fa_IR
+	    2a vi 042a vi_VN
+	    2b hy 042b hy_AM
+	    2c az 042c az_AZ@latin 082c az_AZ@cyrillic
+	    2d eu
+	    2e wen 042e wen_DE
+	    2f mk 042f mk_MK
+	    30 bnt 0430 bnt_TZ
+	    31 ts 0431 ts_ZA
+	    32 tn
+	    33 ven 0433 ven_ZA
+	    34 xh 0434 xh_ZA
+	    35 zu 0435 zu_ZA
+	    36 af 0436 af_ZA
+	    37 ka 0437 ka_GE
+	    38 fo 0438 fo_FO
+	    39 hi 0439 hi_IN
+	    3a mt 043a mt_MT
+	    3b se 043b se_NO
+	    043c gd_UK 083c ga_IE
+	    3d yi 043d yi_IL
+	    3e ms 043e ms_MY 083e ms_BN
+	    3f kk 043f kk_KZ
+	    40 ky 0440 ky_KG
+	    41 sw 0441 sw_KE
+	    42 tk 0442 tk_TM
+	    43 uz 0443 uz_UZ@latin 0843 uz_UZ@cyrillic
+	    44 tt 0444 tt_RU
+	    45 bn 0445 bn_IN
+	    46 pa 0446 pa_IN
+	    47 gu 0447 gu_IN
+	    48 or 0448 or_IN
+	    49 ta
+	    4a te 044a te_IN
+	    4b kn 044b kn_IN
+	    4c ml 044c ml_IN
+	    4d as 044d as_IN
+	    4e mr 044e mr_IN
+	    4f sa 044f sa_IN
+	    50 mn
+	    51 bo 0451 bo_CN
+	    52 cy 0452 cy_GB
+	    53 km 0453 km_KH
+	    54 lo 0454 lo_LA
+	    55 my 0455 my_MM
+	    56 gl 0456 gl_ES
+	    57 kok 0457 kok_IN
+	    58 mni 0458 mni_IN
+	    59 sd
+	    5a syr 045a syr_TR
+	    5b si 045b si_LK
+	    5c chr 045c chr_US
+	    5d iu 045d iu_CA
+	    5e am 045e am_ET
+	    5f ber 045f ber_MA
+	    60 ks 0460 ks_PK 0860 ks_IN
+	    61 ne 0461 ne_NP 0861 ne_IN
+	    62 fy 0462 fy_NL
+	    63 ps
+	    64 tl 0464 tl_PH
+	    65 div 0465 div_MV
+	    66 bin 0466 bin_NG
+	    67 ful 0467 ful_NG
+	    68 ha 0468 ha_NG
+	    69 nic 0469 nic_NG
+	    6a yo 046a yo_NG
+	    70 ibo 0470 ibo_NG
+	    71 kau 0471 kau_NG
+	    72 om 0472 om_ET
+	    73 ti 0473 ti_ET
+	    74 gn 0474 gn_PY
+	    75 cpe 0475 cpe_US
+	    76 la 0476 la_VA
+	    77 so 0477 so_SO
+	    78 sit 0478 sit_CN
+	    79 pap 0479 pap_AN
+	}]
+    }
+}
+
+# msgcat::mc --
+#
+#	Find the translation for the given string based on the current
+#	locale setting. Check the local namespace first, then look in each
+#	parent namespace until the source is found.  If additional args are
+#	specified, use the format command to work them into the traslated
+#	string.
+#	If no catalog item is found, mcunknown is called in the caller frame
+#	and its result is returned.
+#
+# Arguments:
+#	src	The string to translate.
+#	args	Args to pass to the format command
+#
+# Results:
+#	Returns the translated string.  Propagates errors thrown by the
+#	format command.
+
+proc msgcat::mc {src args} {
+    # this may be replaced by:
+    # return [mcget -namespace [uplevel 1 [list ::namespace current]] --\
+    #	    $src {*}$args]
+
+    # Check for the src in each namespace starting from the local and
+    # ending in the global.
+
+    variable Msgs
+    variable Loclist
+
+    set ns [uplevel 1 [list ::namespace current]]
+    set loclist [PackagePreferences $ns]
+
+    set nscur $ns
+    while {$nscur != ""} {
+	foreach loc $loclist {
+	    if {[dict exists $Msgs $nscur $loc $src]} {
+		return [DefaultUnknown "" [dict get $Msgs $nscur $loc $src]\
+			{*}$args]
+	    }
+	}
+	set nscur [namespace parent $nscur]
+    }
+    # call package local or default unknown command
+    set args [linsert $args 0 [lindex $loclist 0] $src]
+    switch -exact -- [Invoke unknowncmd $args $ns result 1] {
+	0 { return [uplevel 1 [linsert $args 0 [namespace origin mcunknown]]] }
+	1 { return [DefaultUnknown {*}$args] }
+	default { return $result }
+    }
+}
+
+# msgcat::mcexists --
+#
+#	Check if a catalog item is set or if mc would invoke mcunknown.
+#
+# Arguments:
+#	-exactnamespace		Only check the exact namespace and no
+#				parent namespaces
+#	-exactlocale		Only check the exact locale and not all members
+#				of the preferences list
+#	src			Message catalog key
+#
+# Results:
+#	true if an adequate catalog key was found
+
+proc msgcat::mcexists {args} {
+
+    variable Msgs
+    variable Loclist
+    variable PackageConfig
+
+    set ns [uplevel 1 [list ::namespace current]]
+    set loclist [PackagePreferences $ns]
+
+    while {[llength $args] != 1} {
+	set args [lassign $args option]
+	switch -glob -- $option {
+	    -exactnamespace { set exactnamespace 1 }
+	    -exactlocale { set loclist [lrange $loclist 0 0] }
+	    -* { return -code error "unknown option \"$option\"" }
+	    default {
+		return -code error "wrong # args: should be\
+			\"[lindex [info level 0] 0] ?-exactnamespace?\
+			?-exactlocale? src\""
+	    }
+	}
+    }
+    set src [lindex $args 0]
+
+    while {$ns ne ""} {
+	foreach loc $loclist {
+	    if {[dict exists $Msgs $ns $loc $src]} {
+		return 1
+	    }
+	}
+	if {[info exists exactnamespace]} {return 0}
+	set ns [namespace parent $ns]
+    }
+    return 0
+}
+
+# msgcat::mclocale --
+#
+#	Query or set the current locale.
+#
+# Arguments:
+#	newLocale	(Optional) The new locale string. Locale strings
+#			should be composed of one or more sublocale parts
+#			separated by underscores (e.g. en_US).
+#
+# Results:
+#	Returns the normalized set locale.
+
+proc msgcat::mclocale {args} {
+    variable Loclist
+    variable LoadedLocales
+    set len [llength $args]
+
+    if {$len > 1} {
+	return -code error "wrong # args: should be\
+		\"[lindex [info level 0] 0] ?newLocale?\""
+    }
+
+    if {$len == 1} {
+	set newLocale [string tolower [lindex $args 0]]
+	if {$newLocale ne [file tail $newLocale]} {
+	    return -code error "invalid newLocale value \"$newLocale\":\
+		    could be path to unsafe code."
+	}
+	if {[lindex $Loclist 0] ne $newLocale} {
+	    set Loclist [GetPreferences $newLocale]
+
+	    # locale not loaded jet
+	    LoadAll $Loclist
+	    # Invoke callback
+	    Invoke changecmd $Loclist
+	}
+    }
+    return [lindex $Loclist 0]
+}
+
+# msgcat::GetPreferences --
+#
+#	Get list of locales from a locale.
+#	The first element is always the lowercase locale.
+#	Other elements have one component separated by "_" less.
+#	Multiple "_" are seen as one separator: de__ch_spec de__ch de {}
+#
+# Arguments:
+#	Locale.
+#
+# Results:
+#	Locale list
+
+proc msgcat::GetPreferences {locale} {
+    set locale [string tolower $locale]
+    set loclist [list $locale]
+    while {-1 !=[set pos [string last "_" $locale]]} {
+	set locale [string range $locale 0 $pos-1]
+	if { "_" ne [string index $locale end] } {
+	    lappend loclist $locale
+	}
+    }
+    if {"" ne [lindex $loclist end]} {
+	lappend loclist {}
+    }
+    return $loclist
+}
+
+# msgcat::mcpreferences --
+#
+#	Fetch the list of locales used to look up strings, ordered from
+#	most preferred to least preferred.
+#
+# Arguments:
+#	None.
+#
+# Results:
+#	Returns an ordered list of the locales preferred by the user.
+
+proc msgcat::mcpreferences {} {
+    variable Loclist
+    return $Loclist
+}
+
+# msgcat::mcloadedlocales --
+#
+#	Get or change the list of currently loaded default locales
+#
+#	The following subcommands are available:
+#	loaded
+#	    Get the current list of loaded locales
+#	clear
+#	    Remove all loaded locales not present in mcpreferences.
+#
+# Arguments:
+#	subcommand		One of loaded or clear
+#
+# Results:
+#	Empty string, if not stated differently for the subcommand
+
+proc msgcat::mcloadedlocales {subcommand} {
+    variable Loclist
+    variable LoadedLocales
+    variable Msgs
+    variable PackageConfig
+    switch -exact -- $subcommand {
+	clear {
+	    # Remove all locales not contained in Loclist
+	    # skip any packages with package locale
+	    set LoadedLocales $Loclist
+	    foreach ns [dict keys $Msgs] {
+		if {![dict exists $PackageConfig loclist $ns]} {
+		    foreach locale [dict keys [dict get $Msgs $ns]] {
+			if {$locale ni $Loclist} {
+			    dict unset Msgs $ns $locale
+			}
+		    }
+		}
+	    }
+	}
+	loaded { return $LoadedLocales }
+	default {
+	    return -code error "unknown subcommand \"$subcommand\": must be\
+		    clear, or loaded"
+	}
+    }
+    return
+}
+
+# msgcat::mcpackagelocale --
+#
+#	Get or change the package locale of the calling package.
+#
+#	The following subcommands are available:
+#	set
+#	    Set a package locale.
+#	    This may load message catalog files and may clear message catalog
+#	    items, if the former locale was the default locale.
+#	    Returns the normalized set locale.
+#	    The default locale is taken, if locale is not given.
+#	get
+#	    Get the locale valid for this package.
+#	isset
+#	    Returns true, if a package locale is set
+#	unset
+#	    Unset the package locale and activate the default locale.
+#	    This loads message catalog file which where missing in the package
+#	    locale.
+#	preferences
+#	    Return locale preference list valid for the package.
+#	loaded
+#	    Return loaded locale list valid for the current package.
+#	clear
+#	    If the current package has a package locale, remove all package
+#	    locales not containes in package mcpreferences.
+#	    It is an error to call this without a package locale set.
+#
+#	The subcommands get, preferences and loaded return the corresponding
+#	default data, if no package locale is set.
+#
+# Arguments:
+#	subcommand		see list above
+#	locale			package locale (only set subcommand)
+#
+# Results:
+#	Empty string, if not stated differently for the subcommand
+
+proc msgcat::mcpackagelocale {subcommand {locale ""}} {
+    # todo: implement using an ensemble
+    variable Loclist
+    variable LoadedLocales
+    variable Msgs
+    variable PackageConfig
+    # Check option
+    # check if required item is exactly provided
+    if {[llength [info level 0]] == 2} {
+	# locale not given
+	unset locale
+    } else {
+	# locale given
+	if {$subcommand in
+		{"get" "isset" "unset" "preferences" "loaded" "clear"} } {
+	    return -code error "wrong # args: should be\
+		    \"[lrange [info level 0] 0 1]\""
+	}
+        set locale [string tolower $locale]
+    }
+    set ns [uplevel 1 {::namespace current}]
+
+    switch -exact -- $subcommand {
+	get { return [lindex [PackagePreferences $ns] 0] }
+	preferences { return [PackagePreferences $ns] }
+	loaded { return [PackageLocales $ns] }
+	present { return [expr {$locale in [PackageLocales $ns]} ]}
+	isset { return [dict exists $PackageConfig loclist $ns] }
+	set { # set a package locale or add a package locale
+
+	    # Copy the default locale if no package locale set so far
+	    if {![dict exists $PackageConfig loclist $ns]} {
+		dict set PackageConfig loclist $ns $Loclist
+		dict set PackageConfig loadedlocales $ns $LoadedLocales
+	    }
+
+	    # Check if changed
+	    set loclist [dict get $PackageConfig loclist $ns]
+	    if {! [info exists locale] || $locale eq [lindex $loclist 0] } {
+		return [lindex $loclist 0]
+	    }
+
+	    # Change loclist
+	    set loclist [GetPreferences $locale]
+	    set locale [lindex $loclist 0]
+	    dict set PackageConfig loclist $ns $loclist
+
+	    # load eventual missing locales
+	    set loadedLocales [dict get $PackageConfig loadedlocales $ns]
+	    if {$locale in $loadedLocales} { return $locale }
+	    set loadLocales [ListComplement $loadedLocales $loclist]
+	    dict set PackageConfig loadedlocales $ns\
+		    [concat $loadedLocales $loadLocales]
+	    Load $ns $loadLocales
+	    return $locale
+	}
+	clear { # Remove all locales not contained in Loclist
+	    if {![dict exists $PackageConfig loclist $ns]} {
+		return -code error "clear only when package locale set"
+	    }
+	    set loclist [dict get $PackageConfig loclist $ns]
+	    dict set PackageConfig loadedlocales $ns $loclist
+	    if {[dict exists $Msgs $ns]} {
+		foreach locale [dict keys [dict get $Msgs $ns]] {
+		    if {$locale ni $loclist} {
+			dict unset Msgs $ns $locale
+		    }
+		}
+	    }
+	}
+	unset {	# unset package locale and restore default locales
+
+	    if { ![dict exists $PackageConfig loclist $ns] } { return }
+
+	    # unset package locale
+	    set loadLocales [ListComplement\
+		    [dict get $PackageConfig loadedlocales $ns] $LoadedLocales]
+	    dict unset PackageConfig loadedlocales $ns
+	    dict unset PackageConfig loclist $ns
+
+	    # unset keys not in global loaded locales
+	    if {[dict exists $Msgs $ns]} {
+		foreach locale [dict keys [dict get $Msgs $ns]] {
+		    if {$locale ni $LoadedLocales} {
+			dict unset Msgs $ns $locale
+		    }
+		}
+	    }
+
+	    # Add missing locales
+	    Load $ns $loadLocales
+	}
+	default {
+	    return -code error "unknown subcommand \"$subcommand\": must be\
+		    clear, get, isset, loaded, present, set, or unset"
+	}
+    }
+    return
+}
+
+# msgcat::mcforgetpackage --
+#
+#	Remove any data of the calling package from msgcat
+#
+
+proc msgcat::mcforgetpackage {} {
+    # todo: this may be implemented using an ensemble
+    variable PackageConfig
+    variable Msgs
+    set ns [uplevel 1 {::namespace current}]
+    # Remove MC items
+    dict unset Msgs $ns
+    # Remove config items
+    foreach key [dict keys $PackageConfig] {
+	dict unset PackageConfig $key $ns
+    }
+    return
+}
+
+# msgcat::mcpackageconfig --
+#
+#	Get or modify the per caller namespace (e.g. packages) config options.
+#
+#	Available subcommands are:
+#
+#	    get		get the current value or an error if not set.
+#	    isset	return true, if the option is set
+#	    set		set the value (see also distinct option).
+#			Returns the number of loaded message files.
+#	    unset	Clear option. return "".
+#
+#	Available options are:
+#
+#	mcfolder
+#	    The message catalog folder of the package.
+#	    This is automatically set by mcload.
+#	    If the value is changed using the set subcommand, an evntual
+#	    loadcmd is invoked and all message files of the package locale are
+#	    loaded.
+#
+#	loadcmd
+#	    The command gets executed before a message file would be
+#	    sourced for this module.
+#	    The command is invoked with the expanded locale list to load.
+#	    The command is not invoked if the registering package namespace
+#	    is not present.
+#	    This callback might also be used as an alternative to message
+#	    files.
+#	    If the value is changed using the set subcommand, the callback is
+#	    directly invoked with the current file locale list. No file load is
+#	    executed.
+#
+#	changecmd
+#	    The command is invoked, after an executed locale change.
+#	    Appended argument is expanded mcpreferences.
+#
+#	unknowncmd
+#	    Use a package locale mcunknown procedure instead the global one.
+#	    The appended arguments are identical to mcunknown.
+#	    A default unknown handler is used if set to the empty string.
+#	    This consists in returning the key if no arguments are given.
+#	    With given arguments, format is used to process the arguments.
+#
+# Arguments:
+#	subcommand		Operation on the package
+#	option			The package option to get or set.
+#	?value?			Eventual value for the subcommand
+#
+# Results:
+#	Depends on the subcommand and option and is described there
+
+proc msgcat::mcpackageconfig {subcommand option {value ""}} {
+    variable PackageConfig
+    # get namespace
+    set ns [uplevel 1 {::namespace current}]
+
+    if {$option ni {"mcfolder" "loadcmd" "changecmd" "unknowncmd"}} {
+	return -code error "bad option \"$option\": must be mcfolder, loadcmd,\
+		changecmd, or unknowncmd"
+    }
+
+    # check if value argument is exactly provided
+    if {[llength [info level 0]] == 4 } {
+	# value provided
+	if {$subcommand in {"get" "isset" "unset"}} {
+	    return -code error "wrong # args: should be\
+		    \"[lrange [info level 0] 0 2] value\""
+	}
+    } elseif {$subcommand eq "set"} {
+        return -code error\
+		"wrong # args: should be \"[lrange [info level 0] 0 2]\""
+    }
+
+    # Execute subcommands
+    switch -exact -- $subcommand {
+	get {	# Operation get return current value
+	    if {![dict exists $PackageConfig $option $ns]} {
+		return -code error "package option \"$option\" not set"
+	    }
+	    return [dict get $PackageConfig $option $ns]
+	}
+	isset {	return [dict exists $PackageConfig $option $ns] }
+	unset {	dict unset PackageConfig $option $ns }
+	set {	# Set option
+
+	    if {$option eq "mcfolder"} {
+		set value [file normalize $value]
+	    }
+	    # Check if changed
+	    if { [dict exists $PackageConfig $option $ns]
+		    && $value eq [dict get $PackageConfig $option $ns] } {
+		return 0
+	    }
+
+	    # set new value
+	    dict set PackageConfig $option $ns $value
+
+	    # Reload pending message catalogs
+	    switch -exact -- $option {
+		mcfolder { return [Load $ns [PackageLocales $ns]] }
+		loadcmd { return [Load $ns [PackageLocales $ns] 1] }
+	    }
+	    return 0
+	}
+	default {
+	    return -code error "unknown subcommand \"$subcommand\":\
+		    must be get, isset, set, or unset"
+	}
+    }
+    return
+}
+
+# msgcat::PackagePreferences --
+#
+#	Return eventual present package preferences or the default list if not
+#	present.
+#
+# Arguments:
+#	ns		Package namespace
+#
+# Results:
+#	locale list
+
+proc msgcat::PackagePreferences {ns} {
+    variable PackageConfig
+    if {[dict exists $PackageConfig loclist $ns]} {
+	return [dict get $PackageConfig loclist $ns]
+    }
+    variable Loclist
+    return $Loclist
+}
+
+# msgcat::PackageLocales --
+#
+#	Return eventual present package locales or the default list if not
+#	present.
+#
+# Arguments:
+#	ns		Package namespace
+#
+# Results:
+#	locale list
+
+proc msgcat::PackageLocales {ns} {
+    variable PackageConfig
+    if {[dict exists $PackageConfig loadedlocales $ns]} {
+	return [dict get $PackageConfig loadedlocales $ns]
+    }
+    variable LoadedLocales
+    return $LoadedLocales
+}
+
+# msgcat::ListComplement --
+#
+#	Build the complement of two lists.
+#	Return a list with all elements in list2 but not in list1.
+#	Optionally return the intersection.
+#
+# Arguments:
+#	list1		excluded list
+#	list2		included list
+#	inlistname	If not "", write in this variable the intersection list
+#
+# Results:
+#	list with all elements in list2 but not in list1
+
+proc msgcat::ListComplement {list1 list2 {inlistname ""}} {
+    if {"" ne $inlistname} {
+	upvar 1 $inlistname inlist
+    }
+    set inlist {}
+    set outlist {}
+    foreach item $list2 {
+	if {$item in $list1} {
+	    lappend inlist $item
+	} else {
+	    lappend outlist $item
+	}
+    }
+    return $outlist
+}
+
+# msgcat::mcload --
+#
+#	Attempt to load message catalogs for each locale in the
+#	preference list from the specified directory.
+#
+# Arguments:
+#	langdir		The directory to search.
+#
+# Results:
+#	Returns the number of message catalogs that were loaded.
+
+proc msgcat::mcload {langdir} {
+    return [uplevel 1 [list\
+	    [namespace origin mcpackageconfig] set mcfolder $langdir]]
+}
+
+# msgcat::LoadAll --
+#
+#	Load a list of locales for all packages not having a package locale
+#	list.
+#
+# Arguments:
+#	langdir		The directory to search.
+#
+# Results:
+#	Returns the number of message catalogs that were loaded.
+
+proc msgcat::LoadAll {locales} {
+    variable PackageConfig
+    variable LoadedLocales
+    if {0 == [llength $locales]} { return {} }
+    # filter jet unloaded locales
+    set locales [ListComplement $LoadedLocales $locales]
+    if {0 == [llength $locales]} { return {} }
+    lappend LoadedLocales {*}$locales
+
+    set packages [lsort -unique [concat\
+	    [dict keys [dict get $PackageConfig loadcmd]]\
+	    [dict keys [dict get $PackageConfig mcfolder]]]]
+    foreach ns $packages {
+	if {! [dict exists $PackageConfig loclist $ns] } {
+	    Load $ns $locales
+	}
+    }
+    return $locales
+}
+
+# msgcat::Load --
+#
+#	Invoke message load callback and load message catalog files.
+#
+# Arguments:
+#	ns		Namespace (equal package) to load the message catalog.
+#	locales		List of locales to load.
+#	callbackonly	true if only callback should be invoked
+#
+# Results:
+#	Returns the number of message catalogs that were loaded.
+
+proc msgcat::Load {ns locales {callbackonly 0}} {
+    variable FileLocale
+    variable PackageConfig
+    variable LoadedLocals
+
+    if {0 == [llength $locales]} { return 0 }
+
+    # Invoke callback
+    Invoke loadcmd $locales $ns
+
+    if {$callbackonly || ![dict exists $PackageConfig mcfolder $ns]} {
+	return 0
+    }
+
+    # Invoke file load
+    set langdir [dict get $PackageConfig mcfolder $ns]
+
+    # Save the file locale if we are recursively called
+    if {[info exists FileLocale]} {
+	set nestedFileLocale $FileLocale
+    }
+    set x 0
+    foreach p $locales {
+	if {$p eq {}} {
+	    set p ROOT
+	}
+	set langfile [file join $langdir $p.msg]
+	if {[file exists $langfile]} {
+	    incr x
+	    set FileLocale [string tolower\
+		    [file tail [file rootname $langfile]]]
+	    if {"root" eq $FileLocale} {
+		set FileLocale ""
+	    }
+	    namespace inscope $ns [list ::source -encoding utf-8 $langfile]
+	    unset FileLocale
+	}
+    }
+    if {[info exists nestedFileLocale]} {
+	set FileLocale $nestedFileLocale
+    }
+    return $x
+}
+
+# msgcat::Invoke --
+#
+#	Invoke a set of registered callbacks.
+#	The callback is only invoked, if its registered namespace exists.
+#
+# Arguments:
+#	index		Index into PackageConfig to get callback command
+#	arglist		parameters to the callback invocation
+#	ns		(Optional) package to call.
+#			If not given or empty, check all registered packages.
+#	resultname	Variable to save the callback result of the last called
+#			callback to. May be set to "" to discard the result.
+#	failerror (0)	Fail on error if true. Otherwise call bgerror.
+#
+# Results:
+#	Possible values:
+#	- 0: no valid command registered
+#	- 1: registered command was the empty string
+#	- 2: registered command called, resultname is set
+#	- 3: registered command failed
+#	If multiple commands are called, the maximum of all results is returned.
+
+proc msgcat::Invoke {index arglist {ns ""} {resultname ""} {failerror 0}} {
+    variable PackageConfig
+    variable Config
+    if {"" ne $resultname} {
+	upvar 1 $resultname result
+    }
+    if {"" eq $ns} {
+	set packageList [dict keys [dict get $PackageConfig $index]]
+    } else {
+	set packageList [list $ns]
+    }
+    set ret 0
+    foreach ns $packageList {
+	if {[dict exists $PackageConfig $index $ns] && [namespace exists $ns]} {
+	    set cmd [dict get $PackageConfig $index $ns]
+	    if {"" eq $cmd} {
+		if {$ret == 0} {set ret 1}
+	    } else {
+		if {$failerror} {
+		    set result [namespace inscope $ns $cmd {*}$arglist]
+		    set ret 2
+		} elseif {1 == [catch {
+		    set result [namespace inscope $ns $cmd {*}$arglist]
+		    if {$ret < 2} {set ret 2}
+		} err derr]} {
+		    after idle [concat [::interp bgerror ""]\
+			    [list $err $derr]]
+		    set ret 3
+		}
+	    }
+	}
+    }
+    return $ret
+}
+
+# msgcat::mcset --
+#
+#	Set the translation for a given string in a specified locale.
+#
+# Arguments:
+#	locale		The locale to use.
+#	src		The source string.
+#	dest		(Optional) The translated string.  If omitted,
+#			the source string is used.
+#
+# Results:
+#	Returns the new locale.
+
+proc msgcat::mcset {locale src {dest ""}} {
+    variable Msgs
+    if {[llength [info level 0]] == 3} { ;# dest not specified
+	set dest $src
+    }
+
+    set ns [uplevel 1 [list ::namespace current]]
+
+    set locale [string tolower $locale]
+
+    dict set Msgs $ns $locale $src $dest
+    return $dest
+}
+
+# msgcat::mcflset --
+#
+#	Set the translation for a given string in the current file locale.
+#
+# Arguments:
+#	src		The source string.
+#	dest		(Optional) The translated string.  If omitted,
+#			the source string is used.
+#
+# Results:
+#	Returns the new locale.
+
+proc msgcat::mcflset {src {dest ""}} {
+    variable FileLocale
+    variable Msgs
+
+    if {![info exists FileLocale]} {
+	return -code error "must only be used inside a message catalog loaded\
+		with ::msgcat::mcload"
+    }
+    return [uplevel 1 [list [namespace origin mcset] $FileLocale $src $dest]]
+}
+
+# msgcat::mcmset --
+#
+#	Set the translation for multiple strings in a specified locale.
+#
+# Arguments:
+#	locale		The locale to use.
+#	pairs		One or more src/dest pairs (must be even length)
+#
+# Results:
+#	Returns the number of pairs processed
+
+proc msgcat::mcmset {locale pairs} {
+    variable Msgs
+
+    set length [llength $pairs]
+    if {$length % 2} {
+	return -code error "bad translation list:\
+		should be \"[lindex [info level 0] 0] locale {src dest ...}\""
+    }
+
+    set locale [string tolower $locale]
+    set ns [uplevel 1 [list ::namespace current]]
+
+    foreach {src dest} $pairs {
+	dict set Msgs $ns $locale $src $dest
+    }
+
+    return [expr {$length / 2}]
+}
+
+# msgcat::mcflmset --
+#
+#	Set the translation for multiple strings in the mc file locale.
+#
+# Arguments:
+#	pairs		One or more src/dest pairs (must be even length)
+#
+# Results:
+#	Returns the number of pairs processed
+
+proc msgcat::mcflmset {pairs} {
+    variable FileLocale
+    variable Msgs
+
+    if {![info exists FileLocale]} {
+	return -code error "must only be used inside a message catalog loaded\
+		with ::msgcat::mcload"
+    }
+    return [uplevel 1 [list [namespace origin mcmset] $FileLocale $pairs]]
+}
+
+# msgcat::mcunknown --
+#
+#	This routine is called by msgcat::mc if a translation cannot
+#	be found for a string and no unknowncmd is set for the current
+#	package. This routine is intended to be replaced
+#	by an application specific routine for error reporting
+#	purposes.  The default behavior is to return the source string.
+#	If additional args are specified, the format command will be used
+#	to work them into the traslated string.
+#
+# Arguments:
+#	locale		The current locale.
+#	src		The string to be translated.
+#	args		Args to pass to the format command
+#
+# Results:
+#	Returns the translated value.
+
+proc msgcat::mcunknown {args} {
+    return [uplevel 1 [list [namespace origin DefaultUnknown] {*}$args]]
+}
+
+# msgcat::DefaultUnknown --
+#
+#	This routine is called by msgcat::mc if a translation cannot
+#	be found for a string in the following circumstances:
+#	- Default global handler, if mcunknown is not redefined.
+#	- Per package handler, if the package sets unknowncmd to the empty
+#	  string.
+#	It returna the source string if the argument list is empty.
+#	If additional args are specified, the format command will be used
+#	to work them into the traslated string.
+#
+# Arguments:
+#	locale		(unused) The current locale.
+#	src		The string to be translated.
+#	args		Args to pass to the format command
+#
+# Results:
+#	Returns the translated value.
+
+proc msgcat::DefaultUnknown {locale src args} {
+    if {[llength $args]} {
+	return [format $src {*}$args]
+    } else {
+	return $src
+    }
+}
+
+# msgcat::mcmax --
+#
+#	Calculates the maximum length of the translated strings of the given
+#	list.
+#
+# Arguments:
+#	args	strings to translate.
+#
+# Results:
+#	Returns the length of the longest translated string.
+
+proc msgcat::mcmax {args} {
+    set max 0
+    foreach string $args {
+	set translated [uplevel 1 [list [namespace origin mc] $string]]
+	set len [string length $translated]
+	if {$len>$max} {
+	    set max $len
+	}
+    }
+    return $max
+}
+
+# Convert the locale values stored in environment variables to a form
+# suitable for passing to [mclocale]
+proc msgcat::ConvertLocale {value} {
+    # Assume $value is of form: $language[_$territory][.$codeset][@modifier]
+    # Convert to form: $language[_$territory][_$modifier]
+    #
+    # Comment out expanded RE version -- bugs alleged
+    # regexp -expanded {
+    #	^		# Match all the way to the beginning
+    #	([^_.@]*)	# Match "lanugage"; ends with _, ., or @
+    #	(_([^.@]*))?	# Match (optional) "territory"; starts with _
+    #	([.]([^@]*))?	# Match (optional) "codeset"; starts with .
+    #	(@(.*))?	# Match (optional) "modifier"; starts with @
+    #	$		# Match all the way to the end
+    # } $value -> language _ territory _ codeset _ modifier
+    if {![regexp {^([^_.@]+)(_([^.@]*))?([.]([^@]*))?(@(.*))?$} $value \
+	    -> language _ territory _ codeset _ modifier]} {
+	return -code error "invalid locale '$value': empty language part"
+    }
+    set ret $language
+    if {[string length $territory]} {
+	append ret _$territory
+    }
+    if {[string length $modifier]} {
+	append ret _$modifier
+    }
+    return $ret
+}
+
+# Initialize the default locale
+proc msgcat::Init {} {
+    global env
+
+    #
+    # set default locale, try to get from environment
+    #
+    foreach varName {LC_ALL LC_MESSAGES LANG} {
+	if {[info exists env($varName)] && ("" ne $env($varName))} {
+	    if {![catch {
+		mclocale [ConvertLocale $env($varName)]
+	    }]} {
+		return
+	    }
+	}
+    }
+    #
+    # On Darwin, fallback to current CFLocale identifier if available.
+    #
+    if {[info exists ::tcl::mac::locale] && $::tcl::mac::locale ne ""} {
+	if {![catch {
+	    mclocale [ConvertLocale $::tcl::mac::locale]
+	}]} {
+	    return
+	}
+    }
+    #
+    # The rest of this routine is special processing for Windows or
+    # Cygwin. All other platforms, get out now.
+    #
+    if {([info sharedlibextension] ne ".dll")
+	    || [catch {package require registry}]} {
+	mclocale C
+	return
+    }
+    #
+    # On Windows or Cygwin, try to set locale depending on registry
+    # settings, or fall back on locale of "C".
+    #
+
+    # On Vista and later:
+    # HCU/Control Panel/Desktop : PreferredUILanguages is for language packs,
+    # HCU/Control Pannel/International : localName is the default locale.
+    #
+    # They contain the local string as RFC5646, composed of:
+    # [a-z]{2,3} : language
+    # -[a-z]{4}  : script (optional, translated by table Latn->latin)
+    # -[a-z]{2}|[0-9]{3} : territory (optional, numerical region codes not used)
+    # (-.*)* : variant, extension, private use (optional, not used)
+    # Those are translated to local strings.
+    # Examples: de-CH -> de_ch, sr-Latn-CS -> sr_cs@latin, es-419 -> es
+    #
+    foreach key {{HKEY_CURRENT_USER\Control Panel\Desktop} {HKEY_CURRENT_USER\Control Panel\International}}\
+	    value {PreferredUILanguages localeName} {
+	if {![catch {registry get $key $value} localeName]
+		&& [regexp {^([a-z]{2,3})(?:-([a-z]{4}))?(?:-([a-z]{2}))?(?:-.+)?$}\
+		    [string tolower $localeName] match locale script territory]} {
+	    if {"" ne $territory} {
+		append locale _ $territory
+	    }
+	    set modifierDict [dict create latn latin cyrl cyrillic]
+	    if {[dict exists $modifierDict $script]} {
+		append locale @ [dict get $modifierDict $script]
+	    }
+	    if {![catch {mclocale [ConvertLocale $locale]}]} {
+		return
+	    }
+	}
+    }
+
+    # then check value locale which contains a numerical language ID
+    if {[catch {
+	set locale [registry get $key "locale"]
+    }]} {
+	mclocale C
+	return
+    }
+    #
+    # Keep trying to match against smaller and smaller suffixes
+    # of the registry value, since the latter hexadigits appear
+    # to determine general language and earlier hexadigits determine
+    # more precise information, such as territory.  For example,
+    #     0409 - English - United States
+    #     0809 - English - United Kingdom
+    # Add more translations to the WinRegToISO639 array above.
+    #
+    variable WinRegToISO639
+    set locale [string tolower $locale]
+    while {[string length $locale]} {
+	if {![catch {
+	    mclocale [ConvertLocale [dict get $WinRegToISO639 $locale]]
+	}]} {
+	    return
+	}
+	set locale [string range $locale 1 end]
+    }
+    #
+    # No translation known.  Fall back on "C" locale
+    #
+    mclocale C
+}
+msgcat::Init
diff --git a/library/msgcat/pkgIndex.tcl b/library/msgcat/pkgIndex.tcl
new file mode 100644
index 0000000..7399c92
--- /dev/null
+++ b/library/msgcat/pkgIndex.tcl
@@ -0,0 +1,2 @@
+if {![package vsatisfies [package provide Tcl] 8.5]} {return}
+package ifneeded msgcat 1.6.0 [list source [file join $dir msgcat.tcl]]
diff --git a/library/msgs/af.msg b/library/msgs/af.msg
new file mode 100644
index 0000000..0892615
--- /dev/null
+++ b/library/msgs/af.msg
@@ -0,0 +1,49 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset af DAYS_OF_WEEK_ABBREV [list \
+        "So"\
+        "Ma"\
+        "Di"\
+        "Wo"\
+        "Do"\
+        "Vr"\
+        "Sa"]
+    ::msgcat::mcset af DAYS_OF_WEEK_FULL [list \
+        "Sondag"\
+        "Maandag"\
+        "Dinsdag"\
+        "Woensdag"\
+        "Donderdag"\
+        "Vrydag"\
+        "Saterdag"]
+    ::msgcat::mcset af MONTHS_ABBREV [list \
+        "Jan"\
+        "Feb"\
+        "Mar"\
+        "Apr"\
+        "Mei"\
+        "Jun"\
+        "Jul"\
+        "Aug"\
+        "Sep"\
+        "Okt"\
+        "Nov"\
+        "Des"\
+        ""]
+    ::msgcat::mcset af MONTHS_FULL [list \
+        "Januarie"\
+        "Februarie"\
+        "Maart"\
+        "April"\
+        "Mei"\
+        "Junie"\
+        "Julie"\
+        "Augustus"\
+        "September"\
+        "Oktober"\
+        "November"\
+        "Desember"\
+        ""]
+    ::msgcat::mcset af AM "VM"
+    ::msgcat::mcset af PM "NM"
+}
diff --git a/library/msgs/af_za.msg b/library/msgs/af_za.msg
new file mode 100644
index 0000000..fef48ad
--- /dev/null
+++ b/library/msgs/af_za.msg
@@ -0,0 +1,6 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset af_ZA DATE_FORMAT "%d %B %Y"
+    ::msgcat::mcset af_ZA TIME_FORMAT_12 "%l:%M:%S %P"
+    ::msgcat::mcset af_ZA DATE_TIME_FORMAT "%d %B %Y %l:%M:%S %P %z"
+}
diff --git a/library/msgs/ar.msg b/library/msgs/ar.msg
new file mode 100644
index 0000000..257157f
--- /dev/null
+++ b/library/msgs/ar.msg
@@ -0,0 +1,54 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset ar DAYS_OF_WEEK_ABBREV [list \
+        "\u062d"\
+        "\u0646"\
+        "\u062b"\
+        "\u0631"\
+        "\u062e"\
+        "\u062c"\
+        "\u0633"]
+    ::msgcat::mcset ar DAYS_OF_WEEK_FULL [list \
+        "\u0627\u0644\u0623\u062d\u062f"\
+        "\u0627\u0644\u0627\u062b\u0646\u064a\u0646"\
+        "\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621"\
+        "\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621"\
+        "\u0627\u0644\u062e\u0645\u064a\u0633"\
+        "\u0627\u0644\u062c\u0645\u0639\u0629"\
+        "\u0627\u0644\u0633\u0628\u062a"]
+    ::msgcat::mcset ar MONTHS_ABBREV [list \
+        "\u064a\u0646\u0627"\
+        "\u0641\u0628\u0631"\
+        "\u0645\u0627\u0631"\
+        "\u0623\u0628\u0631"\
+        "\u0645\u0627\u064a"\
+        "\u064a\u0648\u0646"\
+        "\u064a\u0648\u0644"\
+        "\u0623\u063a\u0633"\
+        "\u0633\u0628\u062a"\
+        "\u0623\u0643\u062a"\
+        "\u0646\u0648\u0641"\
+        "\u062f\u064a\u0633"\
+        ""]
+    ::msgcat::mcset ar MONTHS_FULL [list \
+        "\u064a\u0646\u0627\u064a\u0631"\
+        "\u0641\u0628\u0631\u0627\u064a\u0631"\
+        "\u0645\u0627\u0631\u0633"\
+        "\u0623\u0628\u0631\u064a\u0644"\
+        "\u0645\u0627\u064a\u0648"\
+        "\u064a\u0648\u0646\u064a\u0648"\
+        "\u064a\u0648\u0644\u064a\u0648"\
+        "\u0623\u063a\u0633\u0637\u0633"\
+        "\u0633\u0628\u062a\u0645\u0628\u0631"\
+        "\u0623\u0643\u062a\u0648\u0628\u0631"\
+        "\u0646\u0648\u0641\u0645\u0628\u0631"\
+        "\u062f\u064a\u0633\u0645\u0628\u0631"\
+        ""]
+    ::msgcat::mcset ar BCE "\u0642.\u0645"
+    ::msgcat::mcset ar CE "\u0645"
+    ::msgcat::mcset ar AM "\u0635"
+    ::msgcat::mcset ar PM "\u0645"
+    ::msgcat::mcset ar DATE_FORMAT "%d/%m/%Y"
+    ::msgcat::mcset ar TIME_FORMAT_12 "%I:%M:%S %P"
+    ::msgcat::mcset ar DATE_TIME_FORMAT "%d/%m/%Y %I:%M:%S %P %z"
+}
diff --git a/library/msgs/ar_in.msg b/library/msgs/ar_in.msg
new file mode 100644
index 0000000..185e49c
--- /dev/null
+++ b/library/msgs/ar_in.msg
@@ -0,0 +1,6 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset ar_IN DATE_FORMAT "%A %d %B %Y"
+    ::msgcat::mcset ar_IN TIME_FORMAT_12 "%I:%M:%S  %z"
+    ::msgcat::mcset ar_IN DATE_TIME_FORMAT "%A %d %B %Y %I:%M:%S  %z %z"
+}
diff --git a/library/msgs/ar_jo.msg b/library/msgs/ar_jo.msg
new file mode 100644
index 0000000..0f5e269
--- /dev/null
+++ b/library/msgs/ar_jo.msg
@@ -0,0 +1,39 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset ar_JO DAYS_OF_WEEK_ABBREV [list \
+        "\u0627\u0644\u0623\u062d\u062f"\
+        "\u0627\u0644\u0627\u062b\u0646\u064a\u0646"\
+        "\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621"\
+        "\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621"\
+        "\u0627\u0644\u062e\u0645\u064a\u0633"\
+        "\u0627\u0644\u062c\u0645\u0639\u0629"\
+        "\u0627\u0644\u0633\u0628\u062a"]
+    ::msgcat::mcset ar_JO MONTHS_ABBREV [list \
+        "\u0643\u0627\u0646\u0648\u0646 \u0627\u0644\u062b\u0627\u0646\u064a"\
+        "\u0634\u0628\u0627\u0637"\
+        "\u0622\u0630\u0627\u0631"\
+        "\u0646\u064a\u0633\u0627\u0646"\
+        "\u0646\u0648\u0627\u0631"\
+        "\u062d\u0632\u064a\u0631\u0627\u0646"\
+        "\u062a\u0645\u0648\u0632"\
+        "\u0622\u0628"\
+        "\u0623\u064a\u0644\u0648\u0644"\
+        "\u062a\u0634\u0631\u064a\u0646 \u0627\u0644\u0623\u0648\u0644"\
+        "\u062a\u0634\u0631\u064a\u0646 \u0627\u0644\u062b\u0627\u0646\u064a"\
+        "\u0643\u0627\u0646\u0648\u0646 \u0627\u0644\u0623\u0648\u0644"\
+        ""]
+    ::msgcat::mcset ar_JO MONTHS_FULL [list \
+        "\u0643\u0627\u0646\u0648\u0646 \u0627\u0644\u062b\u0627\u0646\u064a"\
+        "\u0634\u0628\u0627\u0637"\
+        "\u0622\u0630\u0627\u0631"\
+        "\u0646\u064a\u0633\u0627\u0646"\
+        "\u0646\u0648\u0627\u0631"\
+        "\u062d\u0632\u064a\u0631\u0627\u0646"\
+        "\u062a\u0645\u0648\u0632"\
+        "\u0622\u0628"\
+        "\u0623\u064a\u0644\u0648\u0644"\
+        "\u062a\u0634\u0631\u064a\u0646 \u0627\u0644\u0623\u0648\u0644"\
+        "\u062a\u0634\u0631\u064a\u0646 \u0627\u0644\u062b\u0627\u0646\u064a"\
+        "\u0643\u0627\u0646\u0648\u0646 \u0627\u0644\u0623\u0648\u0644"\
+        ""]
+}
diff --git a/library/msgs/ar_lb.msg b/library/msgs/ar_lb.msg
new file mode 100644
index 0000000..e62acd3
--- /dev/null
+++ b/library/msgs/ar_lb.msg
@@ -0,0 +1,39 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset ar_LB DAYS_OF_WEEK_ABBREV [list \
+        "\u0627\u0644\u0623\u062d\u062f"\
+        "\u0627\u0644\u0627\u062b\u0646\u064a\u0646"\
+        "\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621"\
+        "\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621"\
+        "\u0627\u0644\u062e\u0645\u064a\u0633"\
+        "\u0627\u0644\u062c\u0645\u0639\u0629"\
+        "\u0627\u0644\u0633\u0628\u062a"]
+    ::msgcat::mcset ar_LB MONTHS_ABBREV [list \
+        "\u0643\u0627\u0646\u0648\u0646 \u0627\u0644\u062b\u0627\u0646\u064a"\
+        "\u0634\u0628\u0627\u0637"\
+        "\u0622\u0630\u0627\u0631"\
+        "\u0646\u064a\u0633\u0627\u0646"\
+        "\u0646\u0648\u0627\u0631"\
+        "\u062d\u0632\u064a\u0631\u0627\u0646"\
+        "\u062a\u0645\u0648\u0632"\
+        "\u0622\u0628"\
+        "\u0623\u064a\u0644\u0648\u0644"\
+        "\u062a\u0634\u0631\u064a\u0646 \u0627\u0644\u0623\u0648\u0644"\
+        "\u062a\u0634\u0631\u064a\u0646 \u0627\u0644\u062b\u0627\u0646\u064a"\
+        "\u0643\u0627\u0646\u0648\u0646 \u0627\u0644\u0623\u0648\u0644"\
+        ""]
+    ::msgcat::mcset ar_LB MONTHS_FULL [list \
+        "\u0643\u0627\u0646\u0648\u0646 \u0627\u0644\u062b\u0627\u0646\u064a"\
+        "\u0634\u0628\u0627\u0637"\
+        "\u0622\u0630\u0627\u0631"\
+        "\u0646\u064a\u0633\u0627\u0646"\
+        "\u0646\u0648\u0627\u0631"\
+        "\u062d\u0632\u064a\u0631\u0627\u0646"\
+        "\u062a\u0645\u0648\u0632"\
+        "\u0622\u0628"\
+        "\u0623\u064a\u0644\u0648\u0644"\
+        "\u062a\u0634\u0631\u064a\u0646 \u0627\u0644\u0623\u0648\u0644"\
+        "\u062a\u0634\u0631\u064a\u0646 \u0627\u0644\u062b\u0627\u0646\u064a"\
+        "\u0643\u0627\u0646\u0648\u0646 \u0627\u0644\u0623\u0648\u0644"\
+        ""]
+}
diff --git a/library/msgs/ar_sy.msg b/library/msgs/ar_sy.msg
new file mode 100644
index 0000000..d5e1c87
--- /dev/null
+++ b/library/msgs/ar_sy.msg
@@ -0,0 +1,39 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset ar_SY DAYS_OF_WEEK_ABBREV [list \
+        "\u0627\u0644\u0623\u062d\u062f"\
+        "\u0627\u0644\u0627\u062b\u0646\u064a\u0646"\
+        "\u0627\u0644\u062b\u0644\u0627\u062b\u0627\u0621"\
+        "\u0627\u0644\u0623\u0631\u0628\u0639\u0627\u0621"\
+        "\u0627\u0644\u062e\u0645\u064a\u0633"\
+        "\u0627\u0644\u062c\u0645\u0639\u0629"\
+        "\u0627\u0644\u0633\u0628\u062a"]
+    ::msgcat::mcset ar_SY MONTHS_ABBREV [list \
+        "\u0643\u0627\u0646\u0648\u0646 \u0627\u0644\u062b\u0627\u0646\u064a"\
+        "\u0634\u0628\u0627\u0637"\
+        "\u0622\u0630\u0627\u0631"\
+        "\u0646\u064a\u0633\u0627\u0646"\
+        "\u0646\u0648\u0627\u0631"\
+        "\u062d\u0632\u064a\u0631\u0627\u0646"\
+        "\u062a\u0645\u0648\u0632"\
+        "\u0622\u0628"\
+        "\u0623\u064a\u0644\u0648\u0644"\
+        "\u062a\u0634\u0631\u064a\u0646 \u0627\u0644\u0623\u0648\u0644"\
+        "\u062a\u0634\u0631\u064a\u0646 \u0627\u0644\u062b\u0627\u0646\u064a"\
+        "\u0643\u0627\u0646\u0648\u0646 \u0627\u0644\u0623\u0648\u0644"\
+        ""]
+    ::msgcat::mcset ar_SY MONTHS_FULL [list \
+        "\u0643\u0627\u0646\u0648\u0646 \u0627\u0644\u062b\u0627\u0646\u064a"\
+        "\u0634\u0628\u0627\u0637"\
+        "\u0622\u0630\u0627\u0631"\
+        "\u0646\u064a\u0633\u0627\u0646"\
+        "\u0646\u0648\u0627\u0631\u0627\u0646"\
+        "\u062d\u0632\u064a\u0631"\
+        "\u062a\u0645\u0648\u0632"\
+        "\u0622\u0628"\
+        "\u0623\u064a\u0644\u0648\u0644"\
+        "\u062a\u0634\u0631\u064a\u0646 \u0627\u0644\u0623\u0648\u0644"\
+        "\u062a\u0634\u0631\u064a\u0646 \u0627\u0644\u062b\u0627\u0646\u064a"\
+        "\u0643\u0627\u0646\u0648\u0646 \u0627\u0644\u0623\u0648\u0644"\
+        ""]
+}
diff --git a/library/msgs/be.msg b/library/msgs/be.msg
new file mode 100644
index 0000000..379a1d7
--- /dev/null
+++ b/library/msgs/be.msg
@@ -0,0 +1,52 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset be DAYS_OF_WEEK_ABBREV [list \
+        "\u043d\u0434"\
+        "\u043f\u043d"\
+        "\u0430\u0442"\
+        "\u0441\u0440"\
+        "\u0447\u0446"\
+        "\u043f\u0442"\
+        "\u0441\u0431"]
+    ::msgcat::mcset be DAYS_OF_WEEK_FULL [list \
+        "\u043d\u044f\u0434\u0437\u0435\u043b\u044f"\
+        "\u043f\u0430\u043d\u044f\u0434\u0437\u0435\u043b\u0430\u043a"\
+        "\u0430\u045e\u0442\u043e\u0440\u0430\u043a"\
+        "\u0441\u0435\u0440\u0430\u0434\u0430"\
+        "\u0447\u0430\u0446\u0432\u0435\u0440"\
+        "\u043f\u044f\u0442\u043d\u0456\u0446\u0430"\
+        "\u0441\u0443\u0431\u043e\u0442\u0430"]
+    ::msgcat::mcset be MONTHS_ABBREV [list \
+        "\u0441\u0442\u0434"\
+        "\u043b\u044e\u0442"\
+        "\u0441\u043a\u0432"\
+        "\u043a\u0440\u0441"\
+        "\u043c\u0430\u0439"\
+        "\u0447\u0440\u0432"\
+        "\u043b\u043f\u043d"\
+        "\u0436\u043d\u0432"\
+        "\u0432\u0440\u0441"\
+        "\u043a\u0441\u0442"\
+        "\u043b\u0441\u0442"\
+        "\u0441\u043d\u0436"\
+        ""]
+    ::msgcat::mcset be MONTHS_FULL [list \
+        "\u0441\u0442\u0443\u0434\u0437\u0435\u043d\u044f"\
+        "\u043b\u044e\u0442\u0430\u0433\u0430"\
+        "\u0441\u0430\u043a\u0430\u0432\u0456\u043a\u0430"\
+        "\u043a\u0440\u0430\u0441\u0430\u0432\u0456\u043a\u0430"\
+        "\u043c\u0430\u044f"\
+        "\u0447\u0440\u0432\u0435\u043d\u044f"\
+        "\u043b\u0456\u043f\u0435\u043d\u044f"\
+        "\u0436\u043d\u0456\u045e\u043d\u044f"\
+        "\u0432\u0435\u0440\u0430\u0441\u043d\u044f"\
+        "\u043a\u0430\u0441\u0442\u0440\u044b\u0447\u043d\u0456\u043a\u0430"\
+        "\u043b\u0438\u0441\u0442\u0430\u043f\u0430\u0434\u0430"\
+        "\u0441\u043d\u0435\u0436\u043d\u044f"\
+        ""]
+    ::msgcat::mcset be BCE "\u0434\u0430 \u043d.\u0435."
+    ::msgcat::mcset be CE "\u043d.\u0435."
+    ::msgcat::mcset be DATE_FORMAT "%e.%m.%Y"
+    ::msgcat::mcset be TIME_FORMAT "%k.%M.%S"
+    ::msgcat::mcset be DATE_TIME_FORMAT "%e.%m.%Y %k.%M.%S %z"
+}
diff --git a/library/msgs/bg.msg b/library/msgs/bg.msg
new file mode 100644
index 0000000..ff17759
--- /dev/null
+++ b/library/msgs/bg.msg
@@ -0,0 +1,52 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset bg DAYS_OF_WEEK_ABBREV [list \
+        "\u041d\u0434"\
+        "\u041f\u043d"\
+        "\u0412\u0442"\
+        "\u0421\u0440"\
+        "\u0427\u0442"\
+        "\u041f\u0442"\
+        "\u0421\u0431"]
+    ::msgcat::mcset bg DAYS_OF_WEEK_FULL [list \
+        "\u041d\u0435\u0434\u0435\u043b\u044f"\
+        "\u041f\u043e\u043d\u0435\u0434\u0435\u043b\u043d\u0438\u043a"\
+        "\u0412\u0442\u043e\u0440\u043d\u0438\u043a"\
+        "\u0421\u0440\u044f\u0434\u0430"\
+        "\u0427\u0435\u0442\u0432\u044a\u0440\u0442\u044a\u043a"\
+        "\u041f\u0435\u0442\u044a\u043a"\
+        "\u0421\u044a\u0431\u043e\u0442\u0430"]
+    ::msgcat::mcset bg MONTHS_ABBREV [list \
+        "I"\
+        "II"\
+        "III"\
+        "IV"\
+        "V"\
+        "VI"\
+        "VII"\
+        "VIII"\
+        "IX"\
+        "X"\
+        "XI"\
+        "XII"\
+        ""]
+    ::msgcat::mcset bg MONTHS_FULL [list \
+        "\u042f\u043d\u0443\u0430\u0440\u0438"\
+        "\u0424\u0435\u0432\u0440\u0443\u0430\u0440\u0438"\
+        "\u041c\u0430\u0440\u0442"\
+        "\u0410\u043f\u0440\u0438\u043b"\
+        "\u041c\u0430\u0439"\
+        "\u042e\u043d\u0438"\
+        "\u042e\u043b\u0438"\
+        "\u0410\u0432\u0433\u0443\u0441\u0442"\
+        "\u0421\u0435\u043f\u0442\u0435\u043c\u0432\u0440\u0438"\
+        "\u041e\u043a\u0442\u043e\u043c\u0432\u0440\u0438"\
+        "\u041d\u043e\u0435\u043c\u0432\u0440\u0438"\
+        "\u0414\u0435\u043a\u0435\u043c\u0432\u0440\u0438"\
+        ""]
+    ::msgcat::mcset bg BCE "\u043f\u0440.\u043d.\u0435."
+    ::msgcat::mcset bg CE "\u043d.\u0435."
+    ::msgcat::mcset bg DATE_FORMAT "%Y-%m-%e"
+    ::msgcat::mcset bg TIME_FORMAT "%k:%M:%S"
+    ::msgcat::mcset bg DATE_TIME_FORMAT "%Y-%m-%e %k:%M:%S %z"
+}
diff --git a/library/msgs/bn.msg b/library/msgs/bn.msg
new file mode 100644
index 0000000..664b9d8
--- /dev/null
+++ b/library/msgs/bn.msg
@@ -0,0 +1,49 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset bn DAYS_OF_WEEK_ABBREV [list \
+        "\u09b0\u09ac\u09bf"\
+        "\u09b8\u09cb\u09ae"\
+        "\u09ae\u0999\u0997\u09b2"\
+        "\u09ac\u09c1\u09a7"\
+        "\u09ac\u09c3\u09b9\u09b8\u09cd\u09aa\u09a4\u09bf"\
+        "\u09b6\u09c1\u0995\u09cd\u09b0"\
+        "\u09b6\u09a8\u09bf"]
+    ::msgcat::mcset bn DAYS_OF_WEEK_FULL [list \
+        "\u09b0\u09ac\u09bf\u09ac\u09be\u09b0"\
+        "\u09b8\u09cb\u09ae\u09ac\u09be\u09b0"\
+        "\u09ae\u0999\u0997\u09b2\u09ac\u09be\u09b0"\
+        "\u09ac\u09c1\u09a7\u09ac\u09be\u09b0"\
+        "\u09ac\u09c3\u09b9\u09b8\u09cd\u09aa\u09a4\u09bf\u09ac\u09be\u09b0"\
+        "\u09b6\u09c1\u0995\u09cd\u09b0\u09ac\u09be\u09b0"\
+        "\u09b6\u09a8\u09bf\u09ac\u09be\u09b0"]
+    ::msgcat::mcset bn MONTHS_ABBREV [list \
+        "\u099c\u09be\u09a8\u09c1\u09df\u09be\u09b0\u09c0"\
+        "\u09ab\u09c7\u09ac\u09cd\u09b0\u09c1\u09df\u09be\u09b0\u09c0"\
+        "\u09ae\u09be\u09b0\u09cd\u099a"\
+        "\u098f\u09aa\u09cd\u09b0\u09bf\u09b2"\
+        "\u09ae\u09c7"\
+        "\u099c\u09c1\u09a8"\
+        "\u099c\u09c1\u09b2\u09be\u0987"\
+        "\u0986\u0997\u09b8\u09cd\u099f"\
+        "\u09b8\u09c7\u09aa\u09cd\u099f\u09c7\u09ae\u09cd\u09ac\u09b0"\
+        "\u0985\u0995\u09cd\u099f\u09cb\u09ac\u09b0"\
+        "\u09a8\u09ad\u09c7\u09ae\u09cd\u09ac\u09b0"\
+        "\u09a1\u09bf\u09b8\u09c7\u09ae\u09cd\u09ac\u09b0"\
+        ""]
+    ::msgcat::mcset bn MONTHS_FULL [list \
+        "\u099c\u09be\u09a8\u09c1\u09df\u09be\u09b0\u09c0"\
+        "\u09ab\u09c7\u09ac\u09cd\u09b0\u09c1\u09df\u09be\u09b0\u09c0"\
+        "\u09ae\u09be\u09b0\u09cd\u099a"\
+        "\u098f\u09aa\u09cd\u09b0\u09bf\u09b2"\
+        "\u09ae\u09c7"\
+        "\u099c\u09c1\u09a8"\
+        "\u099c\u09c1\u09b2\u09be\u0987"\
+        "\u0986\u0997\u09b8\u09cd\u099f"\
+        "\u09b8\u09c7\u09aa\u09cd\u099f\u09c7\u09ae\u09cd\u09ac\u09b0"\
+        "\u0985\u0995\u09cd\u099f\u09cb\u09ac\u09b0"\
+        "\u09a8\u09ad\u09c7\u09ae\u09cd\u09ac\u09b0"\
+        "\u09a1\u09bf\u09b8\u09c7\u09ae\u09cd\u09ac\u09b0"\
+        ""]
+    ::msgcat::mcset bn AM "\u09aa\u09c2\u09b0\u09cd\u09ac\u09be\u09b9\u09cd\u09a3"
+    ::msgcat::mcset bn PM "\u0985\u09aa\u09b0\u09be\u09b9\u09cd\u09a3"
+}
diff --git a/library/msgs/bn_in.msg b/library/msgs/bn_in.msg
new file mode 100644
index 0000000..28c000f
--- /dev/null
+++ b/library/msgs/bn_in.msg
@@ -0,0 +1,6 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset bn_IN DATE_FORMAT "%A %d %b %Y"
+    ::msgcat::mcset bn_IN TIME_FORMAT_12 "%I:%M:%S  %z"
+    ::msgcat::mcset bn_IN DATE_TIME_FORMAT "%A %d %b %Y %I:%M:%S  %z %z"
+}
diff --git a/library/msgs/ca.msg b/library/msgs/ca.msg
new file mode 100644
index 0000000..36c9772
--- /dev/null
+++ b/library/msgs/ca.msg
@@ -0,0 +1,50 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset ca DAYS_OF_WEEK_ABBREV [list \
+        "dg."\
+        "dl."\
+        "dt."\
+        "dc."\
+        "dj."\
+        "dv."\
+        "ds."]
+    ::msgcat::mcset ca DAYS_OF_WEEK_FULL [list \
+        "diumenge"\
+        "dilluns"\
+        "dimarts"\
+        "dimecres"\
+        "dijous"\
+        "divendres"\
+        "dissabte"]
+    ::msgcat::mcset ca MONTHS_ABBREV [list \
+        "gen."\
+        "feb."\
+        "mar\u00e7"\
+        "abr."\
+        "maig"\
+        "juny"\
+        "jul."\
+        "ag."\
+        "set."\
+        "oct."\
+        "nov."\
+        "des."\
+        ""]
+    ::msgcat::mcset ca MONTHS_FULL [list \
+        "gener"\
+        "febrer"\
+        "mar\u00e7"\
+        "abril"\
+        "maig"\
+        "juny"\
+        "juliol"\
+        "agost"\
+        "setembre"\
+        "octubre"\
+        "novembre"\
+        "desembre"\
+        ""]
+    ::msgcat::mcset ca DATE_FORMAT "%d/%m/%Y"
+    ::msgcat::mcset ca TIME_FORMAT "%H:%M:%S"
+    ::msgcat::mcset ca DATE_TIME_FORMAT "%d/%m/%Y %H:%M:%S %z"
+}
diff --git a/library/msgs/cs.msg b/library/msgs/cs.msg
new file mode 100644
index 0000000..8db8bdd
--- /dev/null
+++ b/library/msgs/cs.msg
@@ -0,0 +1,54 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset cs DAYS_OF_WEEK_ABBREV [list \
+        "Ne"\
+        "Po"\
+        "\u00dat"\
+        "St"\
+        "\u010ct"\
+        "P\u00e1"\
+        "So"]
+    ::msgcat::mcset cs DAYS_OF_WEEK_FULL [list \
+        "Ned\u011ble"\
+        "Pond\u011bl\u00ed"\
+        "\u00dater\u00fd"\
+        "St\u0159eda"\
+        "\u010ctvrtek"\
+        "P\u00e1tek"\
+        "Sobota"]
+    ::msgcat::mcset cs MONTHS_ABBREV [list \
+        "I"\
+        "II"\
+        "III"\
+        "IV"\
+        "V"\
+        "VI"\
+        "VII"\
+        "VIII"\
+        "IX"\
+        "X"\
+        "XI"\
+        "XII"\
+        ""]
+    ::msgcat::mcset cs MONTHS_FULL [list \
+        "leden"\
+        "\u00fanor"\
+        "b\u0159ezen"\
+        "duben"\
+        "kv\u011bten"\
+        "\u010derven"\
+        "\u010dervenec"\
+        "srpen"\
+        "z\u00e1\u0159\u00ed"\
+        "\u0159\u00edjen"\
+        "listopad"\
+        "prosinec"\
+        ""]
+    ::msgcat::mcset cs BCE "p\u0159.Kr."
+    ::msgcat::mcset cs CE "po Kr."
+    ::msgcat::mcset cs AM "dop."
+    ::msgcat::mcset cs PM "odp."
+    ::msgcat::mcset cs DATE_FORMAT "%e.%m.%Y"
+    ::msgcat::mcset cs TIME_FORMAT "%k:%M:%S"
+    ::msgcat::mcset cs DATE_TIME_FORMAT "%e.%m.%Y %k:%M:%S %z"
+}
diff --git a/library/msgs/da.msg b/library/msgs/da.msg
new file mode 100644
index 0000000..e4fec7f
--- /dev/null
+++ b/library/msgs/da.msg
@@ -0,0 +1,52 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset da DAYS_OF_WEEK_ABBREV [list \
+        "s\u00f8"\
+        "ma"\
+        "ti"\
+        "on"\
+        "to"\
+        "fr"\
+        "l\u00f8"]
+    ::msgcat::mcset da DAYS_OF_WEEK_FULL [list \
+        "s\u00f8ndag"\
+        "mandag"\
+        "tirsdag"\
+        "onsdag"\
+        "torsdag"\
+        "fredag"\
+        "l\u00f8rdag"]
+    ::msgcat::mcset da MONTHS_ABBREV [list \
+        "jan"\
+        "feb"\
+        "mar"\
+        "apr"\
+        "maj"\
+        "jun"\
+        "jul"\
+        "aug"\
+        "sep"\
+        "okt"\
+        "nov"\
+        "dec"\
+        ""]
+    ::msgcat::mcset da MONTHS_FULL [list \
+        "januar"\
+        "februar"\
+        "marts"\
+        "april"\
+        "maj"\
+        "juni"\
+        "juli"\
+        "august"\
+        "september"\
+        "oktober"\
+        "november"\
+        "december"\
+        ""]
+    ::msgcat::mcset da BCE "f.Kr."
+    ::msgcat::mcset da CE "e.Kr."
+    ::msgcat::mcset da DATE_FORMAT "%d-%m-%Y"
+    ::msgcat::mcset da TIME_FORMAT "%H:%M:%S"
+    ::msgcat::mcset da DATE_TIME_FORMAT "%d-%m-%Y %H:%M:%S %z"
+}
diff --git a/library/msgs/de.msg b/library/msgs/de.msg
new file mode 100644
index 0000000..9eb3145
--- /dev/null
+++ b/library/msgs/de.msg
@@ -0,0 +1,54 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset de DAYS_OF_WEEK_ABBREV [list \
+        "So"\
+        "Mo"\
+        "Di"\
+        "Mi"\
+        "Do"\
+        "Fr"\
+        "Sa"]
+    ::msgcat::mcset de DAYS_OF_WEEK_FULL [list \
+        "Sonntag"\
+        "Montag"\
+        "Dienstag"\
+        "Mittwoch"\
+        "Donnerstag"\
+        "Freitag"\
+        "Samstag"]
+    ::msgcat::mcset de MONTHS_ABBREV [list \
+        "Jan"\
+        "Feb"\
+        "Mrz"\
+        "Apr"\
+        "Mai"\
+        "Jun"\
+        "Jul"\
+        "Aug"\
+        "Sep"\
+        "Okt"\
+        "Nov"\
+        "Dez"\
+        ""]
+    ::msgcat::mcset de MONTHS_FULL [list \
+        "Januar"\
+        "Februar"\
+        "M\u00e4rz"\
+        "April"\
+        "Mai"\
+        "Juni"\
+        "Juli"\
+        "August"\
+        "September"\
+        "Oktober"\
+        "November"\
+        "Dezember"\
+        ""]
+    ::msgcat::mcset de BCE "v. Chr."
+    ::msgcat::mcset de CE "n. Chr."
+    ::msgcat::mcset de AM "vorm."
+    ::msgcat::mcset de PM "nachm."
+    ::msgcat::mcset de DATE_FORMAT "%d.%m.%Y"
+    ::msgcat::mcset de TIME_FORMAT "%H:%M:%S"
+    ::msgcat::mcset de DATE_TIME_FORMAT "%d.%m.%Y %H:%M:%S %z"
+}
diff --git a/library/msgs/de_at.msg b/library/msgs/de_at.msg
new file mode 100644
index 0000000..61bc266
--- /dev/null
+++ b/library/msgs/de_at.msg
@@ -0,0 +1,35 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset de_AT MONTHS_ABBREV [list \
+        "J\u00e4n"\
+        "Feb"\
+        "M\u00e4r"\
+        "Apr"\
+        "Mai"\
+        "Jun"\
+        "Jul"\
+        "Aug"\
+        "Sep"\
+        "Okt"\
+        "Nov"\
+        "Dez"\
+        ""]
+    ::msgcat::mcset de_AT MONTHS_FULL [list \
+        "J\u00e4nner"\
+        "Februar"\
+        "M\u00e4rz"\
+        "April"\
+        "Mai"\
+        "Juni"\
+        "Juli"\
+        "August"\
+        "September"\
+        "Oktober"\
+        "November"\
+        "Dezember"\
+        ""]
+    ::msgcat::mcset de_AT DATE_FORMAT "%Y-%m-%d"
+    ::msgcat::mcset de_AT TIME_FORMAT "%T"
+    ::msgcat::mcset de_AT TIME_FORMAT_12 "%T"
+    ::msgcat::mcset de_AT DATE_TIME_FORMAT "%a %d %b %Y %T %z"
+}
diff --git a/library/msgs/de_be.msg b/library/msgs/de_be.msg
new file mode 100644
index 0000000..3614763
--- /dev/null
+++ b/library/msgs/de_be.msg
@@ -0,0 +1,53 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset de_BE DAYS_OF_WEEK_ABBREV [list \
+        "Son"\
+        "Mon"\
+        "Die"\
+        "Mit"\
+        "Don"\
+        "Fre"\
+        "Sam"]
+    ::msgcat::mcset de_BE DAYS_OF_WEEK_FULL [list \
+        "Sonntag"\
+        "Montag"\
+        "Dienstag"\
+        "Mittwoch"\
+        "Donnerstag"\
+        "Freitag"\
+        "Samstag"]
+    ::msgcat::mcset de_BE MONTHS_ABBREV [list \
+        "Jan"\
+        "Feb"\
+        "M\u00e4r"\
+        "Apr"\
+        "Mai"\
+        "Jun"\
+        "Jul"\
+        "Aug"\
+        "Sep"\
+        "Okt"\
+        "Nov"\
+        "Dez"\
+        ""]
+    ::msgcat::mcset de_BE MONTHS_FULL [list \
+        "Januar"\
+        "Februar"\
+        "M\u00e4rz"\
+        "April"\
+        "Mai"\
+        "Juni"\
+        "Juli"\
+        "August"\
+        "September"\
+        "Oktober"\
+        "November"\
+        "Dezember"\
+        ""]
+    ::msgcat::mcset de_BE AM "vorm"
+    ::msgcat::mcset de_BE PM "nachm"
+    ::msgcat::mcset de_BE DATE_FORMAT "%Y-%m-%d"
+    ::msgcat::mcset de_BE TIME_FORMAT "%T"
+    ::msgcat::mcset de_BE TIME_FORMAT_12 "%T"
+    ::msgcat::mcset de_BE DATE_TIME_FORMAT "%a %d %b %Y %T %z"
+}
diff --git a/library/msgs/el.msg b/library/msgs/el.msg
new file mode 100644
index 0000000..ac19f62
--- /dev/null
+++ b/library/msgs/el.msg
@@ -0,0 +1,52 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset el DAYS_OF_WEEK_ABBREV [list \
+        "\u039a\u03c5\u03c1"\
+        "\u0394\u03b5\u03c5"\
+        "\u03a4\u03c1\u03b9"\
+        "\u03a4\u03b5\u03c4"\
+        "\u03a0\u03b5\u03bc"\
+        "\u03a0\u03b1\u03c1"\
+        "\u03a3\u03b1\u03b2"]
+    ::msgcat::mcset el DAYS_OF_WEEK_FULL [list \
+        "\u039a\u03c5\u03c1\u03b9\u03b1\u03ba\u03ae"\
+        "\u0394\u03b5\u03c5\u03c4\u03ad\u03c1\u03b1"\
+        "\u03a4\u03c1\u03af\u03c4\u03b7"\
+        "\u03a4\u03b5\u03c4\u03ac\u03c1\u03c4\u03b7"\
+        "\u03a0\u03ad\u03bc\u03c0\u03c4\u03b7"\
+        "\u03a0\u03b1\u03c1\u03b1\u03c3\u03ba\u03b5\u03c5\u03ae"\
+        "\u03a3\u03ac\u03b2\u03b2\u03b1\u03c4\u03bf"]
+    ::msgcat::mcset el MONTHS_ABBREV [list \
+        "\u0399\u03b1\u03bd"\
+        "\u03a6\u03b5\u03b2"\
+        "\u039c\u03b1\u03c1"\
+        "\u0391\u03c0\u03c1"\
+        "\u039c\u03b1\u03ca"\
+        "\u0399\u03bf\u03c5\u03bd"\
+        "\u0399\u03bf\u03c5\u03bb"\
+        "\u0391\u03c5\u03b3"\
+        "\u03a3\u03b5\u03c0"\
+        "\u039f\u03ba\u03c4"\
+        "\u039d\u03bf\u03b5"\
+        "\u0394\u03b5\u03ba"\
+        ""]
+    ::msgcat::mcset el MONTHS_FULL [list \
+        "\u0399\u03b1\u03bd\u03bf\u03c5\u03ac\u03c1\u03b9\u03bf\u03c2"\
+        "\u03a6\u03b5\u03b2\u03c1\u03bf\u03c5\u03ac\u03c1\u03b9\u03bf\u03c2"\
+        "\u039c\u03ac\u03c1\u03c4\u03b9\u03bf\u03c2"\
+        "\u0391\u03c0\u03c1\u03af\u03bb\u03b9\u03bf\u03c2"\
+        "\u039c\u03ac\u03ca\u03bf\u03c2"\
+        "\u0399\u03bf\u03cd\u03bd\u03b9\u03bf\u03c2"\
+        "\u0399\u03bf\u03cd\u03bb\u03b9\u03bf\u03c2"\
+        "\u0391\u03cd\u03b3\u03bf\u03c5\u03c3\u03c4\u03bf\u03c2"\
+        "\u03a3\u03b5\u03c0\u03c4\u03ad\u03bc\u03b2\u03c1\u03b9\u03bf\u03c2"\
+        "\u039f\u03ba\u03c4\u03ce\u03b2\u03c1\u03b9\u03bf\u03c2"\
+        "\u039d\u03bf\u03ad\u03bc\u03b2\u03c1\u03b9\u03bf\u03c2"\
+        "\u0394\u03b5\u03ba\u03ad\u03bc\u03b2\u03c1\u03b9\u03bf\u03c2"\
+        ""]
+    ::msgcat::mcset el AM "\u03c0\u03bc"
+    ::msgcat::mcset el PM "\u03bc\u03bc"
+    ::msgcat::mcset el DATE_FORMAT "%e/%m/%Y"
+    ::msgcat::mcset el TIME_FORMAT_12 "%l:%M:%S %P"
+    ::msgcat::mcset el DATE_TIME_FORMAT "%e/%m/%Y %l:%M:%S %P %z"
+}
diff --git a/library/msgs/en_au.msg b/library/msgs/en_au.msg
new file mode 100644
index 0000000..7f9870c
--- /dev/null
+++ b/library/msgs/en_au.msg
@@ -0,0 +1,7 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset en_AU DATE_FORMAT "%e/%m/%Y"
+    ::msgcat::mcset en_AU TIME_FORMAT "%H:%M:%S"
+    ::msgcat::mcset en_AU TIME_FORMAT_12 "%I:%M:%S %P %z"
+    ::msgcat::mcset en_AU DATE_TIME_FORMAT "%e/%m/%Y %H:%M:%S %z"
+}
diff --git a/library/msgs/en_be.msg b/library/msgs/en_be.msg
new file mode 100644
index 0000000..5072986
--- /dev/null
+++ b/library/msgs/en_be.msg
@@ -0,0 +1,7 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset en_BE DATE_FORMAT "%d %b %Y"
+    ::msgcat::mcset en_BE TIME_FORMAT "%k:%M:%S"
+    ::msgcat::mcset en_BE TIME_FORMAT_12 "%k h %M min %S s %z"
+    ::msgcat::mcset en_BE DATE_TIME_FORMAT "%d %b %Y %k:%M:%S %z"
+}
diff --git a/library/msgs/en_bw.msg b/library/msgs/en_bw.msg
new file mode 100644
index 0000000..8fd20c7
--- /dev/null
+++ b/library/msgs/en_bw.msg
@@ -0,0 +1,6 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset en_BW DATE_FORMAT "%d %B %Y"
+    ::msgcat::mcset en_BW TIME_FORMAT_12 "%l:%M:%S %P"
+    ::msgcat::mcset en_BW DATE_TIME_FORMAT "%d %B %Y %l:%M:%S %P %z"
+}
diff --git a/library/msgs/en_ca.msg b/library/msgs/en_ca.msg
new file mode 100644
index 0000000..278efe7
--- /dev/null
+++ b/library/msgs/en_ca.msg
@@ -0,0 +1,7 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset en_CA DATE_FORMAT "%d/%m/%y"
+    ::msgcat::mcset en_CA TIME_FORMAT "%r"
+    ::msgcat::mcset en_CA TIME_FORMAT_12 "%I:%M:%S %p"
+    ::msgcat::mcset en_CA DATE_TIME_FORMAT "%a %d %b %Y %r %z"
+}
diff --git a/library/msgs/en_gb.msg b/library/msgs/en_gb.msg
new file mode 100644
index 0000000..5c61c43
--- /dev/null
+++ b/library/msgs/en_gb.msg
@@ -0,0 +1,7 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset en_GB DATE_FORMAT "%d/%m/%y"
+    ::msgcat::mcset en_GB TIME_FORMAT "%T"
+    ::msgcat::mcset en_GB TIME_FORMAT_12 "%T"
+    ::msgcat::mcset en_GB DATE_TIME_FORMAT "%a %d %b %Y %T %z"
+}
diff --git a/library/msgs/en_hk.msg b/library/msgs/en_hk.msg
new file mode 100644
index 0000000..8b33bc0
--- /dev/null
+++ b/library/msgs/en_hk.msg
@@ -0,0 +1,8 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset en_HK AM "AM"
+    ::msgcat::mcset en_HK PM "PM"
+    ::msgcat::mcset en_HK DATE_FORMAT "%B %e, %Y"
+    ::msgcat::mcset en_HK TIME_FORMAT_12 "%l:%M:%S %P"
+    ::msgcat::mcset en_HK DATE_TIME_FORMAT "%B %e, %Y %l:%M:%S %P %z"
+}
diff --git a/library/msgs/en_ie.msg b/library/msgs/en_ie.msg
new file mode 100644
index 0000000..ba621cf
--- /dev/null
+++ b/library/msgs/en_ie.msg
@@ -0,0 +1,7 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset en_IE DATE_FORMAT "%d/%m/%y"
+    ::msgcat::mcset en_IE TIME_FORMAT "%T"
+    ::msgcat::mcset en_IE TIME_FORMAT_12 "%T"
+    ::msgcat::mcset en_IE DATE_TIME_FORMAT "%a %d %b %Y %T %z"
+}
diff --git a/library/msgs/en_in.msg b/library/msgs/en_in.msg
new file mode 100644
index 0000000..a1f155d
--- /dev/null
+++ b/library/msgs/en_in.msg
@@ -0,0 +1,8 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset en_IN AM "AM"
+    ::msgcat::mcset en_IN PM "PM"
+    ::msgcat::mcset en_IN DATE_FORMAT "%d %B %Y"
+    ::msgcat::mcset en_IN TIME_FORMAT "%H:%M:%S"
+    ::msgcat::mcset en_IN DATE_TIME_FORMAT "%d %B %Y %H:%M:%S %z"
+}
diff --git a/library/msgs/en_nz.msg b/library/msgs/en_nz.msg
new file mode 100644
index 0000000..b419017
--- /dev/null
+++ b/library/msgs/en_nz.msg
@@ -0,0 +1,7 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset en_NZ DATE_FORMAT "%e/%m/%Y"
+    ::msgcat::mcset en_NZ TIME_FORMAT "%H:%M:%S"
+    ::msgcat::mcset en_NZ TIME_FORMAT_12 "%I:%M:%S %P %z"
+    ::msgcat::mcset en_NZ DATE_TIME_FORMAT "%e/%m/%Y %H:%M:%S %z"
+}
diff --git a/library/msgs/en_ph.msg b/library/msgs/en_ph.msg
new file mode 100644
index 0000000..682666d
--- /dev/null
+++ b/library/msgs/en_ph.msg
@@ -0,0 +1,8 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset en_PH AM "AM"
+    ::msgcat::mcset en_PH PM "PM"
+    ::msgcat::mcset en_PH DATE_FORMAT "%B %e, %Y"
+    ::msgcat::mcset en_PH TIME_FORMAT_12 "%l:%M:%S %P"
+    ::msgcat::mcset en_PH DATE_TIME_FORMAT "%B %e, %Y %l:%M:%S %P %z"
+}
diff --git a/library/msgs/en_sg.msg b/library/msgs/en_sg.msg
new file mode 100644
index 0000000..4dc5b1d
--- /dev/null
+++ b/library/msgs/en_sg.msg
@@ -0,0 +1,6 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset en_SG DATE_FORMAT "%d %b %Y"
+    ::msgcat::mcset en_SG TIME_FORMAT_12 "%P %I:%M:%S"
+    ::msgcat::mcset en_SG DATE_TIME_FORMAT "%d %b %Y %P %I:%M:%S %z"
+}
diff --git a/library/msgs/en_za.msg b/library/msgs/en_za.msg
new file mode 100644
index 0000000..fe43797
--- /dev/null
+++ b/library/msgs/en_za.msg
@@ -0,0 +1,6 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset en_ZA DATE_FORMAT "%Y/%m/%d"
+    ::msgcat::mcset en_ZA TIME_FORMAT_12 "%I:%M:%S"
+    ::msgcat::mcset en_ZA DATE_TIME_FORMAT "%Y/%m/%d %I:%M:%S %z"
+}
diff --git a/library/msgs/en_zw.msg b/library/msgs/en_zw.msg
new file mode 100644
index 0000000..2a5804f
--- /dev/null
+++ b/library/msgs/en_zw.msg
@@ -0,0 +1,6 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset en_ZW DATE_FORMAT "%d %B %Y"
+    ::msgcat::mcset en_ZW TIME_FORMAT_12 "%l:%M:%S %P"
+    ::msgcat::mcset en_ZW DATE_TIME_FORMAT "%d %B %Y %l:%M:%S %P %z"
+}
diff --git a/library/msgs/eo.msg b/library/msgs/eo.msg
new file mode 100644
index 0000000..1d2a24f
--- /dev/null
+++ b/library/msgs/eo.msg
@@ -0,0 +1,54 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset eo DAYS_OF_WEEK_ABBREV [list \
+        "di"\
+        "lu"\
+        "ma"\
+        "me"\
+        "\u0135a"\
+        "ve"\
+        "sa"]
+    ::msgcat::mcset eo DAYS_OF_WEEK_FULL [list \
+        "diman\u0109o"\
+        "lundo"\
+        "mardo"\
+        "merkredo"\
+        "\u0135a\u016ddo"\
+        "vendredo"\
+        "sabato"]
+    ::msgcat::mcset eo MONTHS_ABBREV [list \
+        "jan"\
+        "feb"\
+        "mar"\
+        "apr"\
+        "maj"\
+        "jun"\
+        "jul"\
+        "a\u016dg"\
+        "sep"\
+        "okt"\
+        "nov"\
+        "dec"\
+        ""]
+    ::msgcat::mcset eo MONTHS_FULL [list \
+        "januaro"\
+        "februaro"\
+        "marto"\
+        "aprilo"\
+        "majo"\
+        "junio"\
+        "julio"\
+        "a\u016dgusto"\
+        "septembro"\
+        "oktobro"\
+        "novembro"\
+        "decembro"\
+        ""]
+    ::msgcat::mcset eo BCE "aK"
+    ::msgcat::mcset eo CE "pK"
+    ::msgcat::mcset eo AM "atm"
+    ::msgcat::mcset eo PM "ptm"
+    ::msgcat::mcset eo DATE_FORMAT "%Y-%b-%d"
+    ::msgcat::mcset eo TIME_FORMAT "%H:%M:%S"
+    ::msgcat::mcset eo DATE_TIME_FORMAT "%Y-%b-%d %H:%M:%S %z"
+}
diff --git a/library/msgs/es.msg b/library/msgs/es.msg
new file mode 100644
index 0000000..a24f0a1
--- /dev/null
+++ b/library/msgs/es.msg
@@ -0,0 +1,52 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset es DAYS_OF_WEEK_ABBREV [list \
+        "dom"\
+        "lun"\
+        "mar"\
+        "mi\u00e9"\
+        "jue"\
+        "vie"\
+        "s\u00e1b"]
+    ::msgcat::mcset es DAYS_OF_WEEK_FULL [list \
+        "domingo"\
+        "lunes"\
+        "martes"\
+        "mi\u00e9rcoles"\
+        "jueves"\
+        "viernes"\
+        "s\u00e1bado"]
+    ::msgcat::mcset es MONTHS_ABBREV [list \
+        "ene"\
+        "feb"\
+        "mar"\
+        "abr"\
+        "may"\
+        "jun"\
+        "jul"\
+        "ago"\
+        "sep"\
+        "oct"\
+        "nov"\
+        "dic"\
+        ""]
+    ::msgcat::mcset es MONTHS_FULL [list \
+        "enero"\
+        "febrero"\
+        "marzo"\
+        "abril"\
+        "mayo"\
+        "junio"\
+        "julio"\
+        "agosto"\
+        "septiembre"\
+        "octubre"\
+        "noviembre"\
+        "diciembre"\
+        ""]
+    ::msgcat::mcset es BCE "a.C."
+    ::msgcat::mcset es CE "d.C."
+    ::msgcat::mcset es DATE_FORMAT "%e de %B de %Y"
+    ::msgcat::mcset es TIME_FORMAT "%k:%M:%S"
+    ::msgcat::mcset es DATE_TIME_FORMAT "%e de %B de %Y %k:%M:%S %z"
+}
diff --git a/library/msgs/es_ar.msg b/library/msgs/es_ar.msg
new file mode 100644
index 0000000..7d35027
--- /dev/null
+++ b/library/msgs/es_ar.msg
@@ -0,0 +1,6 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset es_AR DATE_FORMAT "%d/%m/%Y"
+    ::msgcat::mcset es_AR TIME_FORMAT "%H:%M:%S"
+    ::msgcat::mcset es_AR DATE_TIME_FORMAT "%d/%m/%Y %H:%M:%S %z"
+}
diff --git a/library/msgs/es_bo.msg b/library/msgs/es_bo.msg
new file mode 100644
index 0000000..498ad0d
--- /dev/null
+++ b/library/msgs/es_bo.msg
@@ -0,0 +1,6 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset es_BO DATE_FORMAT "%d-%m-%Y"
+    ::msgcat::mcset es_BO TIME_FORMAT_12 "%I:%M:%S %P"
+    ::msgcat::mcset es_BO DATE_TIME_FORMAT "%d-%m-%Y %I:%M:%S %P %z"
+}
diff --git a/library/msgs/es_cl.msg b/library/msgs/es_cl.msg
new file mode 100644
index 0000000..31d465c
--- /dev/null
+++ b/library/msgs/es_cl.msg
@@ -0,0 +1,6 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset es_CL DATE_FORMAT "%d-%m-%Y"
+    ::msgcat::mcset es_CL TIME_FORMAT_12 "%I:%M:%S %P"
+    ::msgcat::mcset es_CL DATE_TIME_FORMAT "%d-%m-%Y %I:%M:%S %P %z"
+}
diff --git a/library/msgs/es_co.msg b/library/msgs/es_co.msg
new file mode 100644
index 0000000..77e57f0
--- /dev/null
+++ b/library/msgs/es_co.msg
@@ -0,0 +1,6 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset es_CO DATE_FORMAT "%e/%m/%Y"
+    ::msgcat::mcset es_CO TIME_FORMAT_12 "%I:%M:%S %P"
+    ::msgcat::mcset es_CO DATE_TIME_FORMAT "%e/%m/%Y %I:%M:%S %P %z"
+}
diff --git a/library/msgs/es_cr.msg b/library/msgs/es_cr.msg
new file mode 100644
index 0000000..7a652fa
--- /dev/null
+++ b/library/msgs/es_cr.msg
@@ -0,0 +1,6 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset es_CR DATE_FORMAT "%d/%m/%Y"
+    ::msgcat::mcset es_CR TIME_FORMAT_12 "%I:%M:%S %P"
+    ::msgcat::mcset es_CR DATE_TIME_FORMAT "%d/%m/%Y %I:%M:%S %P %z"
+}
diff --git a/library/msgs/es_do.msg b/library/msgs/es_do.msg
new file mode 100644
index 0000000..0e283da
--- /dev/null
+++ b/library/msgs/es_do.msg
@@ -0,0 +1,6 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset es_DO DATE_FORMAT "%m/%d/%Y"
+    ::msgcat::mcset es_DO TIME_FORMAT_12 "%I:%M:%S %P"
+    ::msgcat::mcset es_DO DATE_TIME_FORMAT "%m/%d/%Y %I:%M:%S %P %z"
+}
diff --git a/library/msgs/es_ec.msg b/library/msgs/es_ec.msg
new file mode 100644
index 0000000..9e921e0
--- /dev/null
+++ b/library/msgs/es_ec.msg
@@ -0,0 +1,6 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset es_EC DATE_FORMAT "%d/%m/%Y"
+    ::msgcat::mcset es_EC TIME_FORMAT_12 "%I:%M:%S %P"
+    ::msgcat::mcset es_EC DATE_TIME_FORMAT "%d/%m/%Y %I:%M:%S %P %z"
+}
diff --git a/library/msgs/es_gt.msg b/library/msgs/es_gt.msg
new file mode 100644
index 0000000..ecd6faf
--- /dev/null
+++ b/library/msgs/es_gt.msg
@@ -0,0 +1,6 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset es_GT DATE_FORMAT "%e/%m/%Y"
+    ::msgcat::mcset es_GT TIME_FORMAT_12 "%I:%M:%S %P"
+    ::msgcat::mcset es_GT DATE_TIME_FORMAT "%e/%m/%Y %I:%M:%S %P %z"
+}
diff --git a/library/msgs/es_hn.msg b/library/msgs/es_hn.msg
new file mode 100644
index 0000000..a758ca2
--- /dev/null
+++ b/library/msgs/es_hn.msg
@@ -0,0 +1,6 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset es_HN DATE_FORMAT "%m-%d-%Y"
+    ::msgcat::mcset es_HN TIME_FORMAT_12 "%I:%M:%S %P"
+    ::msgcat::mcset es_HN DATE_TIME_FORMAT "%m-%d-%Y %I:%M:%S %P %z"
+}
diff --git a/library/msgs/es_mx.msg b/library/msgs/es_mx.msg
new file mode 100644
index 0000000..7cfb545
--- /dev/null
+++ b/library/msgs/es_mx.msg
@@ -0,0 +1,6 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset es_MX DATE_FORMAT "%e/%m/%Y"
+    ::msgcat::mcset es_MX TIME_FORMAT_12 "%I:%M:%S %P"
+    ::msgcat::mcset es_MX DATE_TIME_FORMAT "%e/%m/%Y %I:%M:%S %P %z"
+}
diff --git a/library/msgs/es_ni.msg b/library/msgs/es_ni.msg
new file mode 100644
index 0000000..7c39495
--- /dev/null
+++ b/library/msgs/es_ni.msg
@@ -0,0 +1,6 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset es_NI DATE_FORMAT "%m-%d-%Y"
+    ::msgcat::mcset es_NI TIME_FORMAT_12 "%I:%M:%S %P"
+    ::msgcat::mcset es_NI DATE_TIME_FORMAT "%m-%d-%Y %I:%M:%S %P %z"
+}
diff --git a/library/msgs/es_pa.msg b/library/msgs/es_pa.msg
new file mode 100644
index 0000000..cecacdc
--- /dev/null
+++ b/library/msgs/es_pa.msg
@@ -0,0 +1,6 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset es_PA DATE_FORMAT "%m/%d/%Y"
+    ::msgcat::mcset es_PA TIME_FORMAT_12 "%I:%M:%S %P"
+    ::msgcat::mcset es_PA DATE_TIME_FORMAT "%m/%d/%Y %I:%M:%S %P %z"
+}
diff --git a/library/msgs/es_pe.msg b/library/msgs/es_pe.msg
new file mode 100644
index 0000000..9f90595
--- /dev/null
+++ b/library/msgs/es_pe.msg
@@ -0,0 +1,6 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset es_PE DATE_FORMAT "%d/%m/%Y"
+    ::msgcat::mcset es_PE TIME_FORMAT_12 "%I:%M:%S %P"
+    ::msgcat::mcset es_PE DATE_TIME_FORMAT "%d/%m/%Y %I:%M:%S %P %z"
+}
diff --git a/library/msgs/es_pr.msg b/library/msgs/es_pr.msg
new file mode 100644
index 0000000..8511b12
--- /dev/null
+++ b/library/msgs/es_pr.msg
@@ -0,0 +1,6 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset es_PR DATE_FORMAT "%m-%d-%Y"
+    ::msgcat::mcset es_PR TIME_FORMAT_12 "%I:%M:%S %P"
+    ::msgcat::mcset es_PR DATE_TIME_FORMAT "%m-%d-%Y %I:%M:%S %P %z"
+}
diff --git a/library/msgs/es_py.msg b/library/msgs/es_py.msg
new file mode 100644
index 0000000..aa93d36
--- /dev/null
+++ b/library/msgs/es_py.msg
@@ -0,0 +1,6 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset es_PY DATE_FORMAT "%d/%m/%Y"
+    ::msgcat::mcset es_PY TIME_FORMAT_12 "%I:%M:%S %P"
+    ::msgcat::mcset es_PY DATE_TIME_FORMAT "%d/%m/%Y %I:%M:%S %P %z"
+}
diff --git a/library/msgs/es_sv.msg b/library/msgs/es_sv.msg
new file mode 100644
index 0000000..fc7954d
--- /dev/null
+++ b/library/msgs/es_sv.msg
@@ -0,0 +1,6 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset es_SV DATE_FORMAT "%m-%d-%Y"
+    ::msgcat::mcset es_SV TIME_FORMAT_12 "%I:%M:%S %P"
+    ::msgcat::mcset es_SV DATE_TIME_FORMAT "%m-%d-%Y %I:%M:%S %P %z"
+}
diff --git a/library/msgs/es_uy.msg b/library/msgs/es_uy.msg
new file mode 100644
index 0000000..b33525c
--- /dev/null
+++ b/library/msgs/es_uy.msg
@@ -0,0 +1,6 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset es_UY DATE_FORMAT "%d/%m/%Y"
+    ::msgcat::mcset es_UY TIME_FORMAT_12 "%I:%M:%S %P"
+    ::msgcat::mcset es_UY DATE_TIME_FORMAT "%d/%m/%Y %I:%M:%S %P %z"
+}
diff --git a/library/msgs/es_ve.msg b/library/msgs/es_ve.msg
new file mode 100644
index 0000000..7c2a7b0
--- /dev/null
+++ b/library/msgs/es_ve.msg
@@ -0,0 +1,6 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset es_VE DATE_FORMAT "%d/%m/%Y"
+    ::msgcat::mcset es_VE TIME_FORMAT_12 "%I:%M:%S %P"
+    ::msgcat::mcset es_VE DATE_TIME_FORMAT "%d/%m/%Y %I:%M:%S %P %z"
+}
diff --git a/library/msgs/et.msg b/library/msgs/et.msg
new file mode 100644
index 0000000..8d32e9e
--- /dev/null
+++ b/library/msgs/et.msg
@@ -0,0 +1,52 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset et DAYS_OF_WEEK_ABBREV [list \
+        "P"\
+        "E"\
+        "T"\
+        "K"\
+        "N"\
+        "R"\
+        "L"]
+    ::msgcat::mcset et DAYS_OF_WEEK_FULL [list \
+        "p\u00fchap\u00e4ev"\
+        "esmasp\u00e4ev"\
+        "teisip\u00e4ev"\
+        "kolmap\u00e4ev"\
+        "neljap\u00e4ev"\
+        "reede"\
+        "laup\u00e4ev"]
+    ::msgcat::mcset et MONTHS_ABBREV [list \
+        "Jaan"\
+        "Veebr"\
+        "M\u00e4rts"\
+        "Apr"\
+        "Mai"\
+        "Juuni"\
+        "Juuli"\
+        "Aug"\
+        "Sept"\
+        "Okt"\
+        "Nov"\
+        "Dets"\
+        ""]
+    ::msgcat::mcset et MONTHS_FULL [list \
+        "Jaanuar"\
+        "Veebruar"\
+        "M\u00e4rts"\
+        "Aprill"\
+        "Mai"\
+        "Juuni"\
+        "Juuli"\
+        "August"\
+        "September"\
+        "Oktoober"\
+        "November"\
+        "Detsember"\
+        ""]
+    ::msgcat::mcset et BCE "e.m.a."
+    ::msgcat::mcset et CE "m.a.j."
+    ::msgcat::mcset et DATE_FORMAT "%e-%m-%Y"
+    ::msgcat::mcset et TIME_FORMAT "%k:%M:%S"
+    ::msgcat::mcset et DATE_TIME_FORMAT "%e-%m-%Y %k:%M:%S %z"
+}
diff --git a/library/msgs/eu.msg b/library/msgs/eu.msg
new file mode 100644
index 0000000..cf708b6
--- /dev/null
+++ b/library/msgs/eu.msg
@@ -0,0 +1,47 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset eu DAYS_OF_WEEK_ABBREV [list \
+        "igandea"\
+        "astelehena"\
+        "asteartea"\
+        "asteazkena"\
+        "osteguna"\
+        "ostirala"\
+        "larunbata"]
+    ::msgcat::mcset eu DAYS_OF_WEEK_FULL [list \
+        "igandea"\
+        "astelehena"\
+        "asteartea"\
+        "asteazkena"\
+        "osteguna"\
+        "ostirala"\
+        "larunbata"]
+    ::msgcat::mcset eu MONTHS_ABBREV [list \
+        "urt"\
+        "ots"\
+        "mar"\
+        "api"\
+        "mai"\
+        "eka"\
+        "uzt"\
+        "abu"\
+        "ira"\
+        "urr"\
+        "aza"\
+        "abe"\
+        ""]
+    ::msgcat::mcset eu MONTHS_FULL [list \
+        "urtarrila"\
+        "otsaila"\
+        "martxoa"\
+        "apirila"\
+        "maiatza"\
+        "ekaina"\
+        "uztaila"\
+        "abuztua"\
+        "iraila"\
+        "urria"\
+        "azaroa"\
+        "abendua"\
+        ""]
+}
diff --git a/library/msgs/eu_es.msg b/library/msgs/eu_es.msg
new file mode 100644
index 0000000..2694418
--- /dev/null
+++ b/library/msgs/eu_es.msg
@@ -0,0 +1,7 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset eu_ES DATE_FORMAT "%a, %Yeko %bren %da"
+    ::msgcat::mcset eu_ES TIME_FORMAT "%T"
+    ::msgcat::mcset eu_ES TIME_FORMAT_12 "%T"
+    ::msgcat::mcset eu_ES DATE_TIME_FORMAT "%y-%m-%d %T %z"
+}
diff --git a/library/msgs/fa.msg b/library/msgs/fa.msg
new file mode 100644
index 0000000..89b2f90
--- /dev/null
+++ b/library/msgs/fa.msg
@@ -0,0 +1,47 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset fa DAYS_OF_WEEK_ABBREV [list \
+        "\u06cc\u2214"\
+        "\u062f\u2214"\
+        "\u0633\u2214"\
+        "\u0686\u2214"\
+        "\u067e\u2214"\
+        "\u062c\u2214"\
+        "\u0634\u2214"]
+    ::msgcat::mcset fa DAYS_OF_WEEK_FULL [list \
+        "\u06cc\u06cc\u200c\u0634\u0646\u0628\u0647"\
+        "\u062f\u0648\u0634\u0646\u0628\u0647"\
+        "\u0633\u0647\u200c\u0634\u0646\u0628\u0647"\
+        "\u0686\u0647\u0627\u0631\u0634\u0646\u0628\u0647"\
+        "\u067e\u0646\u062c\u200c\u0634\u0646\u0628\u0647"\
+        "\u062c\u0645\u0639\u0647"\
+        "\u0634\u0646\u0628\u0647"]
+    ::msgcat::mcset fa MONTHS_ABBREV [list \
+        "\u0698\u0627\u0646"\
+        "\u0641\u0648\u0631"\
+        "\u0645\u0627\u0631"\
+        "\u0622\u0648\u0631"\
+        "\u0645\u0640\u0647"\
+        "\u0698\u0648\u0646"\
+        "\u0698\u0648\u06cc"\
+        "\u0627\u0648\u062a"\
+        "\u0633\u067e\u062a"\
+        "\u0627\u0643\u062a"\
+        "\u0646\u0648\u0627"\
+        "\u062f\u0633\u0627"\
+        ""]
+    ::msgcat::mcset fa MONTHS_FULL [list \
+        "\u0698\u0627\u0646\u0648\u06cc\u0647"\
+        "\u0641\u0648\u0631\u0648\u06cc\u0647"\
+        "\u0645\u0627\u0631\u0633"\
+        "\u0622\u0648\u0631\u06cc\u0644"\
+        "\u0645\u0647"\
+        "\u0698\u0648\u0626\u0646"\
+        "\u0698\u0648\u0626\u06cc\u0647"\
+        "\u0627\u0648\u062a"\
+        "\u0633\u067e\u062a\u0627\u0645\u0628\u0631"\
+        "\u0627\u0643\u062a\u0628\u0631"\
+        "\u0646\u0648\u0627\u0645\u0628\u0631"\
+        "\u062f\u0633\u0627\u0645\u0628\u0631"\
+        ""]
+}
diff --git a/library/msgs/fa_in.msg b/library/msgs/fa_in.msg
new file mode 100644
index 0000000..adc9e91
--- /dev/null
+++ b/library/msgs/fa_in.msg
@@ -0,0 +1,52 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset fa_IN DAYS_OF_WEEK_ABBREV [list \
+        "\u06cc\u2214"\
+        "\u062f\u2214"\
+        "\u0633\u2214"\
+        "\u0686\u2214"\
+        "\u067e\u2214"\
+        "\u062c\u2214"\
+        "\u0634\u2214"]
+    ::msgcat::mcset fa_IN DAYS_OF_WEEK_FULL [list \
+        "\u06cc\u06cc\u200c\u0634\u0646\u0628\u0647"\
+        "\u062f\u0648\u0634\u0646\u0628\u0647"\
+        "\u0633\u0647\u200c\u0634\u0646\u0628\u0647"\
+        "\u0686\u0647\u0627\u0631\u0634\u0646\u0628\u0647"\
+        "\u067e\u0646\u062c\u200c\u0634\u0646\u0628\u0647"\
+        "\u062c\u0645\u0639\u0647"\
+        "\u0634\u0646\u0628\u0647"]
+    ::msgcat::mcset fa_IN MONTHS_ABBREV [list \
+        "\u0698\u0627\u0646"\
+        "\u0641\u0648\u0631"\
+        "\u0645\u0627\u0631"\
+        "\u0622\u0648\u0631"\
+        "\u0645\u0640\u0647"\
+        "\u0698\u0648\u0646"\
+        "\u0698\u0648\u06cc"\
+        "\u0627\u0648\u062a"\
+        "\u0633\u067e\u062a"\
+        "\u0627\u0643\u062a"\
+        "\u0646\u0648\u0627"\
+        "\u062f\u0633\u0627"\
+        ""]
+    ::msgcat::mcset fa_IN MONTHS_FULL [list \
+        "\u0698\u0627\u0646\u0648\u06cc\u0647"\
+        "\u0641\u0648\u0631\u0648\u06cc\u0647"\
+        "\u0645\u0627\u0631\u0633"\
+        "\u0622\u0648\u0631\u06cc\u0644"\
+        "\u0645\u0647"\
+        "\u0698\u0648\u0626\u0646"\
+        "\u0698\u0648\u0626\u06cc\u0647"\
+        "\u0627\u0648\u062a"\
+        "\u0633\u067e\u062a\u0627\u0645\u0628\u0631"\
+        "\u0627\u0643\u062a\u0628\u0631"\
+        "\u0646\u0648\u0627\u0645\u0628\u0631"\
+        "\u062f\u0633\u0627\u0645\u0628\u0631"\
+        ""]
+    ::msgcat::mcset fa_IN AM "\u0635\u0628\u062d"
+    ::msgcat::mcset fa_IN PM "\u0639\u0635\u0631"
+    ::msgcat::mcset fa_IN DATE_FORMAT "%A %d %B %Y"
+    ::msgcat::mcset fa_IN TIME_FORMAT_12 "%I:%M:%S  %z"
+    ::msgcat::mcset fa_IN DATE_TIME_FORMAT "%A %d %B %Y %I:%M:%S  %z %z"
+}
diff --git a/library/msgs/fa_ir.msg b/library/msgs/fa_ir.msg
new file mode 100644
index 0000000..597ce9d
--- /dev/null
+++ b/library/msgs/fa_ir.msg
@@ -0,0 +1,9 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset fa_IR AM "\u0635\u0628\u062d"
+    ::msgcat::mcset fa_IR PM "\u0639\u0635\u0631"
+    ::msgcat::mcset fa_IR DATE_FORMAT "%d\u2044%m\u2044%Y"
+    ::msgcat::mcset fa_IR TIME_FORMAT "%S:%M:%H"
+    ::msgcat::mcset fa_IR TIME_FORMAT_12 "%S:%M:%l %P"
+    ::msgcat::mcset fa_IR DATE_TIME_FORMAT "%d\u2044%m\u2044%Y %S:%M:%H %z"
+}
diff --git a/library/msgs/fi.msg b/library/msgs/fi.msg
new file mode 100644
index 0000000..acabba0
--- /dev/null
+++ b/library/msgs/fi.msg
@@ -0,0 +1,50 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset fi DAYS_OF_WEEK_ABBREV [list \
+        "su"\
+        "ma"\
+        "ti"\
+        "ke"\
+        "to"\
+        "pe"\
+        "la"]
+    ::msgcat::mcset fi DAYS_OF_WEEK_FULL [list \
+        "sunnuntai"\
+        "maanantai"\
+        "tiistai"\
+        "keskiviikko"\
+        "torstai"\
+        "perjantai"\
+        "lauantai"]
+    ::msgcat::mcset fi MONTHS_ABBREV [list \
+        "tammi"\
+        "helmi"\
+        "maalis"\
+        "huhti"\
+        "touko"\
+        "kes\u00e4"\
+        "hein\u00e4"\
+        "elo"\
+        "syys"\
+        "loka"\
+        "marras"\
+        "joulu"\
+        ""]
+    ::msgcat::mcset fi MONTHS_FULL [list \
+        "tammikuu"\
+        "helmikuu"\
+        "maaliskuu"\
+        "huhtikuu"\
+        "toukokuu"\
+        "kes\u00e4kuu"\
+        "hein\u00e4kuu"\
+        "elokuu"\
+        "syyskuu"\
+        "lokakuu"\
+        "marraskuu"\
+        "joulukuu"\
+        ""]
+    ::msgcat::mcset fi DATE_FORMAT "%e.%m.%Y"
+    ::msgcat::mcset fi TIME_FORMAT "%k:%M:%S"
+    ::msgcat::mcset fi DATE_TIME_FORMAT "%e.%m.%Y %k:%M:%S %z"
+}
diff --git a/library/msgs/fo.msg b/library/msgs/fo.msg
new file mode 100644
index 0000000..4696e62
--- /dev/null
+++ b/library/msgs/fo.msg
@@ -0,0 +1,47 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset fo DAYS_OF_WEEK_ABBREV [list \
+        "sun"\
+        "m\u00e1n"\
+        "t\u00fds"\
+        "mik"\
+        "h\u00f3s"\
+        "fr\u00ed"\
+        "ley"]
+    ::msgcat::mcset fo DAYS_OF_WEEK_FULL [list \
+        "sunnudagur"\
+        "m\u00e1nadagur"\
+        "t\u00fdsdagur"\
+        "mikudagur"\
+        "h\u00f3sdagur"\
+        "fr\u00edggjadagur"\
+        "leygardagur"]
+    ::msgcat::mcset fo MONTHS_ABBREV [list \
+        "jan"\
+        "feb"\
+        "mar"\
+        "apr"\
+        "mai"\
+        "jun"\
+        "jul"\
+        "aug"\
+        "sep"\
+        "okt"\
+        "nov"\
+        "des"\
+        ""]
+    ::msgcat::mcset fo MONTHS_FULL [list \
+        "januar"\
+        "februar"\
+        "mars"\
+        "apr\u00edl"\
+        "mai"\
+        "juni"\
+        "juli"\
+        "august"\
+        "september"\
+        "oktober"\
+        "november"\
+        "desember"\
+        ""]
+}
diff --git a/library/msgs/fo_fo.msg b/library/msgs/fo_fo.msg
new file mode 100644
index 0000000..2392b8e
--- /dev/null
+++ b/library/msgs/fo_fo.msg
@@ -0,0 +1,7 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset fo_FO DATE_FORMAT "%d/%m-%Y"
+    ::msgcat::mcset fo_FO TIME_FORMAT "%T"
+    ::msgcat::mcset fo_FO TIME_FORMAT_12 "%T"
+    ::msgcat::mcset fo_FO DATE_TIME_FORMAT "%a %d %b %Y %T %z"
+}
diff --git a/library/msgs/fr.msg b/library/msgs/fr.msg
new file mode 100644
index 0000000..55b19bf
--- /dev/null
+++ b/library/msgs/fr.msg
@@ -0,0 +1,52 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset fr DAYS_OF_WEEK_ABBREV [list \
+        "dim."\
+        "lun."\
+        "mar."\
+        "mer."\
+        "jeu."\
+        "ven."\
+        "sam."]
+    ::msgcat::mcset fr DAYS_OF_WEEK_FULL [list \
+        "dimanche"\
+        "lundi"\
+        "mardi"\
+        "mercredi"\
+        "jeudi"\
+        "vendredi"\
+        "samedi"]
+    ::msgcat::mcset fr MONTHS_ABBREV [list \
+        "janv."\
+        "f\u00e9vr."\
+        "mars"\
+        "avr."\
+        "mai"\
+        "juin"\
+        "juil."\
+        "ao\u00fbt"\
+        "sept."\
+        "oct."\
+        "nov."\
+        "d\u00e9c."\
+        ""]
+    ::msgcat::mcset fr MONTHS_FULL [list \
+        "janvier"\
+        "f\u00e9vrier"\
+        "mars"\
+        "avril"\
+        "mai"\
+        "juin"\
+        "juillet"\
+        "ao\u00fbt"\
+        "septembre"\
+        "octobre"\
+        "novembre"\
+        "d\u00e9cembre"\
+        ""]
+    ::msgcat::mcset fr BCE "av. J.-C."
+    ::msgcat::mcset fr CE "ap. J.-C."
+    ::msgcat::mcset fr DATE_FORMAT "%e %B %Y"
+    ::msgcat::mcset fr TIME_FORMAT "%H:%M:%S"
+    ::msgcat::mcset fr DATE_TIME_FORMAT "%e %B %Y %H:%M:%S %z"
+}
diff --git a/library/msgs/fr_be.msg b/library/msgs/fr_be.msg
new file mode 100644
index 0000000..cdb13bd
--- /dev/null
+++ b/library/msgs/fr_be.msg
@@ -0,0 +1,7 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset fr_BE DATE_FORMAT "%d/%m/%y"
+    ::msgcat::mcset fr_BE TIME_FORMAT "%T"
+    ::msgcat::mcset fr_BE TIME_FORMAT_12 "%T"
+    ::msgcat::mcset fr_BE DATE_TIME_FORMAT "%a %d %b %Y %T %z"
+}
diff --git a/library/msgs/fr_ca.msg b/library/msgs/fr_ca.msg
new file mode 100644
index 0000000..00ccfff
--- /dev/null
+++ b/library/msgs/fr_ca.msg
@@ -0,0 +1,7 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset fr_CA DATE_FORMAT "%Y-%m-%d"
+    ::msgcat::mcset fr_CA TIME_FORMAT "%T"
+    ::msgcat::mcset fr_CA TIME_FORMAT_12 "%T"
+    ::msgcat::mcset fr_CA DATE_TIME_FORMAT "%a %d %b %Y %T %z"
+}
diff --git a/library/msgs/fr_ch.msg b/library/msgs/fr_ch.msg
new file mode 100644
index 0000000..7e2bac7
--- /dev/null
+++ b/library/msgs/fr_ch.msg
@@ -0,0 +1,7 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset fr_CH DATE_FORMAT "%d. %m. %y"
+    ::msgcat::mcset fr_CH TIME_FORMAT "%T"
+    ::msgcat::mcset fr_CH TIME_FORMAT_12 "%T"
+    ::msgcat::mcset fr_CH DATE_TIME_FORMAT "%a %d %b %Y %T %z"
+}
diff --git a/library/msgs/ga.msg b/library/msgs/ga.msg
new file mode 100644
index 0000000..6edf13a
--- /dev/null
+++ b/library/msgs/ga.msg
@@ -0,0 +1,47 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset ga DAYS_OF_WEEK_ABBREV [list \
+        "Domh"\
+        "Luan"\
+        "M\u00e1irt"\
+        "C\u00e9ad"\
+        "D\u00e9ar"\
+        "Aoine"\
+        "Sath"]
+    ::msgcat::mcset ga DAYS_OF_WEEK_FULL [list \
+        "D\u00e9 Domhnaigh"\
+        "D\u00e9 Luain"\
+        "D\u00e9 M\u00e1irt"\
+        "D\u00e9 C\u00e9adaoin"\
+        "D\u00e9ardaoin"\
+        "D\u00e9 hAoine"\
+        "D\u00e9 Sathairn"]
+    ::msgcat::mcset ga MONTHS_ABBREV [list \
+        "Ean"\
+        "Feabh"\
+        "M\u00e1rta"\
+        "Aib"\
+        "Beal"\
+        "Meith"\
+        "I\u00fail"\
+        "L\u00fan"\
+        "MF\u00f3mh"\
+        "DF\u00f3mh"\
+        "Samh"\
+        "Noll"\
+        ""]
+    ::msgcat::mcset ga MONTHS_FULL [list \
+        "Ean\u00e1ir"\
+        "Feabhra"\
+        "M\u00e1rta"\
+        "Aibre\u00e1n"\
+        "M\u00ed na Bealtaine"\
+        "Meith"\
+        "I\u00fail"\
+        "L\u00fanasa"\
+        "Me\u00e1n F\u00f3mhair"\
+        "Deireadh F\u00f3mhair"\
+        "M\u00ed na Samhna"\
+        "M\u00ed na Nollag"\
+        ""]
+}
diff --git a/library/msgs/ga_ie.msg b/library/msgs/ga_ie.msg
new file mode 100644
index 0000000..b6acbbc
--- /dev/null
+++ b/library/msgs/ga_ie.msg
@@ -0,0 +1,7 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset ga_IE DATE_FORMAT "%d.%m.%y"
+    ::msgcat::mcset ga_IE TIME_FORMAT "%T"
+    ::msgcat::mcset ga_IE TIME_FORMAT_12 "%T"
+    ::msgcat::mcset ga_IE DATE_TIME_FORMAT "%a %d %b %Y %T %z"
+}
diff --git a/library/msgs/gl.msg b/library/msgs/gl.msg
new file mode 100644
index 0000000..4b869e8
--- /dev/null
+++ b/library/msgs/gl.msg
@@ -0,0 +1,47 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset gl DAYS_OF_WEEK_ABBREV [list \
+        "Dom"\
+        "Lun"\
+        "Mar"\
+        "M\u00e9r"\
+        "Xov"\
+        "Ven"\
+        "S\u00e1b"]
+    ::msgcat::mcset gl DAYS_OF_WEEK_FULL [list \
+        "Domingo"\
+        "Luns"\
+        "Martes"\
+        "M\u00e9rcores"\
+        "Xoves"\
+        "Venres"\
+        "S\u00e1bado"]
+    ::msgcat::mcset gl MONTHS_ABBREV [list \
+        "Xan"\
+        "Feb"\
+        "Mar"\
+        "Abr"\
+        "Mai"\
+        "Xu\u00f1"\
+        "Xul"\
+        "Ago"\
+        "Set"\
+        "Out"\
+        "Nov"\
+        "Dec"\
+        ""]
+    ::msgcat::mcset gl MONTHS_FULL [list \
+        "Xaneiro"\
+        "Febreiro"\
+        "Marzo"\
+        "Abril"\
+        "Maio"\
+        "Xu\u00f1o"\
+        "Xullo"\
+        "Agosto"\
+        "Setembro"\
+        "Outubro"\
+        "Novembro"\
+        "Decembro"\
+        ""]
+}
diff --git a/library/msgs/gl_es.msg b/library/msgs/gl_es.msg
new file mode 100644
index 0000000..d4ed270
--- /dev/null
+++ b/library/msgs/gl_es.msg
@@ -0,0 +1,6 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset gl_ES DATE_FORMAT "%d %B %Y"
+    ::msgcat::mcset gl_ES TIME_FORMAT_12 "%l:%M:%S %P"
+    ::msgcat::mcset gl_ES DATE_TIME_FORMAT "%d %B %Y %l:%M:%S %P %z"
+}
diff --git a/library/msgs/gv.msg b/library/msgs/gv.msg
new file mode 100644
index 0000000..7d332ad
--- /dev/null
+++ b/library/msgs/gv.msg
@@ -0,0 +1,47 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset gv DAYS_OF_WEEK_ABBREV [list \
+        "Jed"\
+        "Jel"\
+        "Jem"\
+        "Jerc"\
+        "Jerd"\
+        "Jeh"\
+        "Jes"]
+    ::msgcat::mcset gv DAYS_OF_WEEK_FULL [list \
+        "Jedoonee"\
+        "Jelhein"\
+        "Jemayrt"\
+        "Jercean"\
+        "Jerdein"\
+        "Jeheiney"\
+        "Jesarn"]
+    ::msgcat::mcset gv MONTHS_ABBREV [list \
+        "J-guer"\
+        "T-arree"\
+        "Mayrnt"\
+        "Avrril"\
+        "Boaldyn"\
+        "M-souree"\
+        "J-souree"\
+        "Luanistyn"\
+        "M-fouyir"\
+        "J-fouyir"\
+        "M.Houney"\
+        "M.Nollick"\
+        ""]
+    ::msgcat::mcset gv MONTHS_FULL [list \
+        "Jerrey-geuree"\
+        "Toshiaght-arree"\
+        "Mayrnt"\
+        "Averil"\
+        "Boaldyn"\
+        "Mean-souree"\
+        "Jerrey-souree"\
+        "Luanistyn"\
+        "Mean-fouyir"\
+        "Jerrey-fouyir"\
+        "Mee Houney"\
+        "Mee ny Nollick"\
+        ""]
+}
diff --git a/library/msgs/gv_gb.msg b/library/msgs/gv_gb.msg
new file mode 100644
index 0000000..5e96e6f
--- /dev/null
+++ b/library/msgs/gv_gb.msg
@@ -0,0 +1,6 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset gv_GB DATE_FORMAT "%d %B %Y"
+    ::msgcat::mcset gv_GB TIME_FORMAT_12 "%l:%M:%S %P"
+    ::msgcat::mcset gv_GB DATE_TIME_FORMAT "%d %B %Y %l:%M:%S %P %z"
+}
diff --git a/library/msgs/he.msg b/library/msgs/he.msg
new file mode 100644
index 0000000..4fd921d
--- /dev/null
+++ b/library/msgs/he.msg
@@ -0,0 +1,52 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset he DAYS_OF_WEEK_ABBREV [list \
+        "\u05d0"\
+        "\u05d1"\
+        "\u05d2"\
+        "\u05d3"\
+        "\u05d4"\
+        "\u05d5"\
+        "\u05e9"]
+    ::msgcat::mcset he DAYS_OF_WEEK_FULL [list \
+        "\u05d9\u05d5\u05dd \u05e8\u05d0\u05e9\u05d5\u05df"\
+        "\u05d9\u05d5\u05dd \u05e9\u05e0\u05d9"\
+        "\u05d9\u05d5\u05dd \u05e9\u05dc\u05d9\u05e9\u05d9"\
+        "\u05d9\u05d5\u05dd \u05e8\u05d1\u05d9\u05e2\u05d9"\
+        "\u05d9\u05d5\u05dd \u05d7\u05de\u05d9\u05e9\u05d9"\
+        "\u05d9\u05d5\u05dd \u05e9\u05d9\u05e9\u05d9"\
+        "\u05e9\u05d1\u05ea"]
+    ::msgcat::mcset he MONTHS_ABBREV [list \
+        "\u05d9\u05e0\u05d5"\
+        "\u05e4\u05d1\u05e8"\
+        "\u05de\u05e8\u05e5"\
+        "\u05d0\u05e4\u05e8"\
+        "\u05de\u05d0\u05d9"\
+        "\u05d9\u05d5\u05e0"\
+        "\u05d9\u05d5\u05dc"\
+        "\u05d0\u05d5\u05d2"\
+        "\u05e1\u05e4\u05d8"\
+        "\u05d0\u05d5\u05e7"\
+        "\u05e0\u05d5\u05d1"\
+        "\u05d3\u05e6\u05de"\
+        ""]
+    ::msgcat::mcset he MONTHS_FULL [list \
+        "\u05d9\u05e0\u05d5\u05d0\u05e8"\
+        "\u05e4\u05d1\u05e8\u05d5\u05d0\u05e8"\
+        "\u05de\u05e8\u05e5"\
+        "\u05d0\u05e4\u05e8\u05d9\u05dc"\
+        "\u05de\u05d0\u05d9"\
+        "\u05d9\u05d5\u05e0\u05d9"\
+        "\u05d9\u05d5\u05dc\u05d9"\
+        "\u05d0\u05d5\u05d2\u05d5\u05e1\u05d8"\
+        "\u05e1\u05e4\u05d8\u05de\u05d1\u05e8"\
+        "\u05d0\u05d5\u05e7\u05d8\u05d5\u05d1\u05e8"\
+        "\u05e0\u05d5\u05d1\u05de\u05d1\u05e8"\
+        "\u05d3\u05e6\u05de\u05d1\u05e8"\
+        ""]
+    ::msgcat::mcset he BCE "\u05dc\u05e1\u05d4\u0022\u05e0"
+    ::msgcat::mcset he CE "\u05dc\u05e4\u05e1\u05d4\u0022\u05e0"
+    ::msgcat::mcset he DATE_FORMAT "%d/%m/%Y"
+    ::msgcat::mcset he TIME_FORMAT "%H:%M:%S"
+    ::msgcat::mcset he DATE_TIME_FORMAT "%d/%m/%Y %H:%M:%S %z"
+}
diff --git a/library/msgs/hi.msg b/library/msgs/hi.msg
new file mode 100644
index 0000000..50c9fb8
--- /dev/null
+++ b/library/msgs/hi.msg
@@ -0,0 +1,39 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset hi DAYS_OF_WEEK_FULL [list \
+        "\u0930\u0935\u093f\u0935\u093e\u0930"\
+        "\u0938\u094b\u092e\u0935\u093e\u0930"\
+        "\u092e\u0902\u0917\u0932\u0935\u093e\u0930"\
+        "\u092c\u0941\u0927\u0935\u093e\u0930"\
+        "\u0917\u0941\u0930\u0941\u0935\u093e\u0930"\
+        "\u0936\u0941\u0915\u094d\u0930\u0935\u093e\u0930"\
+        "\u0936\u0928\u093f\u0935\u093e\u0930"]
+    ::msgcat::mcset hi MONTHS_ABBREV [list \
+        "\u091c\u0928\u0935\u0930\u0940"\
+        "\u092b\u093c\u0930\u0935\u0930\u0940"\
+        "\u092e\u093e\u0930\u094d\u091a"\
+        "\u0905\u092a\u094d\u0930\u0947\u0932"\
+        "\u092e\u0908"\
+        "\u091c\u0942\u0928"\
+        "\u091c\u0941\u0932\u093e\u0908"\
+        "\u0905\u0917\u0938\u094d\u0924"\
+        "\u0938\u093f\u0924\u092e\u094d\u092c\u0930"\
+        "\u0905\u0915\u094d\u091f\u0942\u092c\u0930"\
+        "\u0928\u0935\u092e\u094d\u092c\u0930"\
+        "\u0926\u093f\u0938\u092e\u094d\u092c\u0930"]
+    ::msgcat::mcset hi MONTHS_FULL [list \
+        "\u091c\u0928\u0935\u0930\u0940"\
+        "\u092b\u093c\u0930\u0935\u0930\u0940"\
+        "\u092e\u093e\u0930\u094d\u091a"\
+        "\u0905\u092a\u094d\u0930\u0947\u0932"\
+        "\u092e\u0908"\
+        "\u091c\u0942\u0928"\
+        "\u091c\u0941\u0932\u093e\u0908"\
+        "\u0905\u0917\u0938\u094d\u0924"\
+        "\u0938\u093f\u0924\u092e\u094d\u092c\u0930"\
+        "\u0905\u0915\u094d\u091f\u0942\u092c\u0930"\
+        "\u0928\u0935\u092e\u094d\u092c\u0930"\
+        "\u0926\u093f\u0938\u092e\u094d\u092c\u0930"]
+    ::msgcat::mcset hi AM "\u0908\u0938\u093e\u092a\u0942\u0930\u094d\u0935"
+    ::msgcat::mcset hi PM "."
+}
diff --git a/library/msgs/hi_in.msg b/library/msgs/hi_in.msg
new file mode 100644
index 0000000..239793f
--- /dev/null
+++ b/library/msgs/hi_in.msg
@@ -0,0 +1,6 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset hi_IN DATE_FORMAT "%d %M %Y"
+    ::msgcat::mcset hi_IN TIME_FORMAT_12 "%I:%M:%S %P"
+    ::msgcat::mcset hi_IN DATE_TIME_FORMAT "%d %M %Y %I:%M:%S %P %z"
+}
diff --git a/library/msgs/hr.msg b/library/msgs/hr.msg
new file mode 100644
index 0000000..cec145b
--- /dev/null
+++ b/library/msgs/hr.msg
@@ -0,0 +1,50 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset hr DAYS_OF_WEEK_ABBREV [list \
+        "ned"\
+        "pon"\
+        "uto"\
+        "sri"\
+        "\u010det"\
+        "pet"\
+        "sub"]
+    ::msgcat::mcset hr DAYS_OF_WEEK_FULL [list \
+        "nedjelja"\
+        "ponedjeljak"\
+        "utorak"\
+        "srijeda"\
+        "\u010detvrtak"\
+        "petak"\
+        "subota"]
+    ::msgcat::mcset hr MONTHS_ABBREV [list \
+        "sij"\
+        "vel"\
+        "o\u017eu"\
+        "tra"\
+        "svi"\
+        "lip"\
+        "srp"\
+        "kol"\
+        "ruj"\
+        "lis"\
+        "stu"\
+        "pro"\
+        ""]
+    ::msgcat::mcset hr MONTHS_FULL [list \
+        "sije\u010danj"\
+        "velja\u010da"\
+        "o\u017eujak"\
+        "travanj"\
+        "svibanj"\
+        "lipanj"\
+        "srpanj"\
+        "kolovoz"\
+        "rujan"\
+        "listopad"\
+        "studeni"\
+        "prosinac"\
+        ""]
+    ::msgcat::mcset hr DATE_FORMAT "%Y.%m.%d"
+    ::msgcat::mcset hr TIME_FORMAT "%H:%M:%S"
+    ::msgcat::mcset hr DATE_TIME_FORMAT "%Y.%m.%d %H:%M:%S %z"
+}
diff --git a/library/msgs/hu.msg b/library/msgs/hu.msg
new file mode 100644
index 0000000..e5e68d9
--- /dev/null
+++ b/library/msgs/hu.msg
@@ -0,0 +1,54 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset hu DAYS_OF_WEEK_ABBREV [list \
+        "V"\
+        "H"\
+        "K"\
+        "Sze"\
+        "Cs"\
+        "P"\
+        "Szo"]
+    ::msgcat::mcset hu DAYS_OF_WEEK_FULL [list \
+        "vas\u00e1rnap"\
+        "h\u00e9tf\u0151"\
+        "kedd"\
+        "szerda"\
+        "cs\u00fct\u00f6rt\u00f6k"\
+        "p\u00e9ntek"\
+        "szombat"]
+    ::msgcat::mcset hu MONTHS_ABBREV [list \
+        "jan."\
+        "febr."\
+        "m\u00e1rc."\
+        "\u00e1pr."\
+        "m\u00e1j."\
+        "j\u00fan."\
+        "j\u00fal."\
+        "aug."\
+        "szept."\
+        "okt."\
+        "nov."\
+        "dec."\
+        ""]
+    ::msgcat::mcset hu MONTHS_FULL [list \
+        "janu\u00e1r"\
+        "febru\u00e1r"\
+        "m\u00e1rcius"\
+        "\u00e1prilis"\
+        "m\u00e1jus"\
+        "j\u00fanius"\
+        "j\u00falius"\
+        "augusztus"\
+        "szeptember"\
+        "okt\u00f3ber"\
+        "november"\
+        "december"\
+        ""]
+    ::msgcat::mcset hu BCE "i.e."
+    ::msgcat::mcset hu CE "i.u."
+    ::msgcat::mcset hu AM "DE"
+    ::msgcat::mcset hu PM "DU"
+    ::msgcat::mcset hu DATE_FORMAT "%Y.%m.%d."
+    ::msgcat::mcset hu TIME_FORMAT "%k:%M:%S"
+    ::msgcat::mcset hu DATE_TIME_FORMAT "%Y.%m.%d. %k:%M:%S %z"
+}
diff --git a/library/msgs/id.msg b/library/msgs/id.msg
new file mode 100644
index 0000000..17c6bb5
--- /dev/null
+++ b/library/msgs/id.msg
@@ -0,0 +1,47 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset id DAYS_OF_WEEK_ABBREV [list \
+        "Min"\
+        "Sen"\
+        "Sel"\
+        "Rab"\
+        "Kam"\
+        "Jum"\
+        "Sab"]
+    ::msgcat::mcset id DAYS_OF_WEEK_FULL [list \
+        "Minggu"\
+        "Senin"\
+        "Selasa"\
+        "Rabu"\
+        "Kamis"\
+        "Jumat"\
+        "Sabtu"]
+    ::msgcat::mcset id MONTHS_ABBREV [list \
+        "Jan"\
+        "Peb"\
+        "Mar"\
+        "Apr"\
+        "Mei"\
+        "Jun"\
+        "Jul"\
+        "Agu"\
+        "Sep"\
+        "Okt"\
+        "Nov"\
+        "Des"\
+        ""]
+    ::msgcat::mcset id MONTHS_FULL [list \
+        "Januari"\
+        "Pebruari"\
+        "Maret"\
+        "April"\
+        "Mei"\
+        "Juni"\
+        "Juli"\
+        "Agustus"\
+        "September"\
+        "Oktober"\
+        "November"\
+        "Desember"\
+        ""]
+}
diff --git a/library/msgs/id_id.msg b/library/msgs/id_id.msg
new file mode 100644
index 0000000..bb672c1
--- /dev/null
+++ b/library/msgs/id_id.msg
@@ -0,0 +1,6 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset id_ID DATE_FORMAT "%d %B %Y"
+    ::msgcat::mcset id_ID TIME_FORMAT_12 "%l:%M:%S %P"
+    ::msgcat::mcset id_ID DATE_TIME_FORMAT "%d %B %Y %l:%M:%S %P %z"
+}
diff --git a/library/msgs/is.msg b/library/msgs/is.msg
new file mode 100644
index 0000000..adc2d2a
--- /dev/null
+++ b/library/msgs/is.msg
@@ -0,0 +1,50 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset is DAYS_OF_WEEK_ABBREV [list \
+        "sun."\
+        "m\u00e1n."\
+        "\u00feri."\
+        "mi\u00f0."\
+        "fim."\
+        "f\u00f6s."\
+        "lau."]
+    ::msgcat::mcset is DAYS_OF_WEEK_FULL [list \
+        "sunnudagur"\
+        "m\u00e1nudagur"\
+        "\u00feri\u00f0judagur"\
+        "mi\u00f0vikudagur"\
+        "fimmtudagur"\
+        "f\u00f6studagur"\
+        "laugardagur"]
+    ::msgcat::mcset is MONTHS_ABBREV [list \
+        "jan."\
+        "feb."\
+        "mar."\
+        "apr."\
+        "ma\u00ed"\
+        "j\u00fan."\
+        "j\u00fal."\
+        "\u00e1g\u00fa."\
+        "sep."\
+        "okt."\
+        "n\u00f3v."\
+        "des."\
+        ""]
+    ::msgcat::mcset is MONTHS_FULL [list \
+        "jan\u00faar"\
+        "febr\u00faar"\
+        "mars"\
+        "apr\u00edl"\
+        "ma\u00ed"\
+        "j\u00fan\u00ed"\
+        "j\u00fal\u00ed"\
+        "\u00e1g\u00fast"\
+        "september"\
+        "okt\u00f3ber"\
+        "n\u00f3vember"\
+        "desember"\
+        ""]
+    ::msgcat::mcset is DATE_FORMAT "%e.%m.%Y"
+    ::msgcat::mcset is TIME_FORMAT "%H:%M:%S"
+    ::msgcat::mcset is DATE_TIME_FORMAT "%e.%m.%Y %H:%M:%S %z"
+}
diff --git a/library/msgs/it.msg b/library/msgs/it.msg
new file mode 100644
index 0000000..b641cde
--- /dev/null
+++ b/library/msgs/it.msg
@@ -0,0 +1,54 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset it DAYS_OF_WEEK_ABBREV [list \
+        "dom"\
+        "lun"\
+        "mar"\
+        "mer"\
+        "gio"\
+        "ven"\
+        "sab"]
+    ::msgcat::mcset it DAYS_OF_WEEK_FULL [list \
+        "domenica"\
+        "luned\u00ec"\
+        "marted\u00ec"\
+        "mercoled\u00ec"\
+        "gioved\u00ec"\
+        "venerd\u00ec"\
+        "sabato"]
+    ::msgcat::mcset it MONTHS_ABBREV [list \
+        "gen"\
+        "feb"\
+        "mar"\
+        "apr"\
+        "mag"\
+        "giu"\
+        "lug"\
+        "ago"\
+        "set"\
+        "ott"\
+        "nov"\
+        "dic"\
+        ""]
+    ::msgcat::mcset it MONTHS_FULL [list \
+        "gennaio"\
+        "febbraio"\
+        "marzo"\
+        "aprile"\
+        "maggio"\
+        "giugno"\
+        "luglio"\
+        "agosto"\
+        "settembre"\
+        "ottobre"\
+        "novembre"\
+        "dicembre"\
+        ""]
+    ::msgcat::mcset it BCE "aC"
+    ::msgcat::mcset it CE "dC"
+    ::msgcat::mcset it AM "m."
+    ::msgcat::mcset it PM "p."
+    ::msgcat::mcset it DATE_FORMAT "%d %B %Y"
+    ::msgcat::mcset it TIME_FORMAT "%H:%M:%S"
+    ::msgcat::mcset it DATE_TIME_FORMAT "%d %B %Y %H:%M:%S %z"
+}
diff --git a/library/msgs/it_ch.msg b/library/msgs/it_ch.msg
new file mode 100644
index 0000000..b36ed36
--- /dev/null
+++ b/library/msgs/it_ch.msg
@@ -0,0 +1,6 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset it_CH DATE_FORMAT "%e. %B %Y"
+    ::msgcat::mcset it_CH TIME_FORMAT "%H:%M:%S"
+    ::msgcat::mcset it_CH DATE_TIME_FORMAT "%e. %B %Y %H:%M:%S %z"
+}
diff --git a/library/msgs/ja.msg b/library/msgs/ja.msg
new file mode 100644
index 0000000..2767665
--- /dev/null
+++ b/library/msgs/ja.msg
@@ -0,0 +1,44 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset ja DAYS_OF_WEEK_ABBREV [list \
+        "\u65e5"\
+        "\u6708"\
+        "\u706b"\
+        "\u6c34"\
+        "\u6728"\
+        "\u91d1"\
+        "\u571f"]
+    ::msgcat::mcset ja DAYS_OF_WEEK_FULL [list \
+        "\u65e5\u66dc\u65e5"\
+        "\u6708\u66dc\u65e5"\
+        "\u706b\u66dc\u65e5"\
+        "\u6c34\u66dc\u65e5"\
+        "\u6728\u66dc\u65e5"\
+        "\u91d1\u66dc\u65e5"\
+        "\u571f\u66dc\u65e5"]
+    ::msgcat::mcset ja MONTHS_FULL [list \
+        "1\u6708"\
+        "2\u6708"\
+        "3\u6708"\
+        "4\u6708"\
+        "5\u6708"\
+        "6\u6708"\
+        "7\u6708"\
+        "8\u6708"\
+        "9\u6708"\
+        "10\u6708"\
+        "11\u6708"\
+        "12\u6708"]
+    ::msgcat::mcset ja BCE "\u7d00\u5143\u524d"
+    ::msgcat::mcset ja CE "\u897f\u66a6"
+    ::msgcat::mcset ja AM "\u5348\u524d"
+    ::msgcat::mcset ja PM "\u5348\u5f8c"
+    ::msgcat::mcset ja DATE_FORMAT "%Y/%m/%d"
+    ::msgcat::mcset ja TIME_FORMAT "%k:%M:%S"
+    ::msgcat::mcset ja TIME_FORMAT_12 "%P %I:%M:%S"
+    ::msgcat::mcset ja DATE_TIME_FORMAT "%Y/%m/%d %k:%M:%S %z"
+    ::msgcat::mcset ja LOCALE_DATE_FORMAT "%EY\u5e74%m\u6708%d\u65e5"
+    ::msgcat::mcset ja LOCALE_TIME_FORMAT "%H\u6642%M\u5206%S\u79d2"
+    ::msgcat::mcset ja LOCALE_DATE_TIME_FORMAT "%EY\u5e74%m\u6708%d\u65e5 (%a) %H\u6642%M\u5206%S\u79d2 %z"
+    ::msgcat::mcset ja LOCALE_ERAS "\u007b-9223372036854775808 \u897f\u66a6 0\u007d \u007b-3061011600 \u660e\u6cbb 1867\u007d \u007b-1812186000 \u5927\u6b63 1911\u007d \u007b-1357635600 \u662d\u548c 1925\u007d \u007b600220800 \u5e73\u6210 1988\u007d"
+}
diff --git a/library/msgs/kl.msg b/library/msgs/kl.msg
new file mode 100644
index 0000000..d877bfe
--- /dev/null
+++ b/library/msgs/kl.msg
@@ -0,0 +1,47 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset kl DAYS_OF_WEEK_ABBREV [list \
+        "sab"\
+        "ata"\
+        "mar"\
+        "pin"\
+        "sis"\
+        "tal"\
+        "arf"]
+    ::msgcat::mcset kl DAYS_OF_WEEK_FULL [list \
+        "sabaat"\
+        "ataasinngorneq"\
+        "marlunngorneq"\
+        "pingasunngorneq"\
+        "sisamanngorneq"\
+        "tallimanngorneq"\
+        "arfininngorneq"]
+    ::msgcat::mcset kl MONTHS_ABBREV [list \
+        "jan"\
+        "feb"\
+        "mar"\
+        "apr"\
+        "maj"\
+        "jun"\
+        "jul"\
+        "aug"\
+        "sep"\
+        "okt"\
+        "nov"\
+        "dec"\
+        ""]
+    ::msgcat::mcset kl MONTHS_FULL [list \
+        "januari"\
+        "februari"\
+        "martsi"\
+        "aprili"\
+        "maji"\
+        "juni"\
+        "juli"\
+        "augustusi"\
+        "septemberi"\
+        "oktoberi"\
+        "novemberi"\
+        "decemberi"\
+        ""]
+}
diff --git a/library/msgs/kl_gl.msg b/library/msgs/kl_gl.msg
new file mode 100644
index 0000000..403aa10
--- /dev/null
+++ b/library/msgs/kl_gl.msg
@@ -0,0 +1,7 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset kl_GL DATE_FORMAT "%d %b %Y"
+    ::msgcat::mcset kl_GL TIME_FORMAT "%T"
+    ::msgcat::mcset kl_GL TIME_FORMAT_12 "%T"
+    ::msgcat::mcset kl_GL DATE_TIME_FORMAT "%a %d %b %Y %T %z"
+}
diff --git a/library/msgs/ko.msg b/library/msgs/ko.msg
new file mode 100644
index 0000000..0cd17a1
--- /dev/null
+++ b/library/msgs/ko.msg
@@ -0,0 +1,55 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset ko DAYS_OF_WEEK_ABBREV [list \
+        "\uc77c"\
+        "\uc6d4"\
+        "\ud654"\
+        "\uc218"\
+        "\ubaa9"\
+        "\uae08"\
+        "\ud1a0"]
+    ::msgcat::mcset ko DAYS_OF_WEEK_FULL [list \
+        "\uc77c\uc694\uc77c"\
+        "\uc6d4\uc694\uc77c"\
+        "\ud654\uc694\uc77c"\
+        "\uc218\uc694\uc77c"\
+        "\ubaa9\uc694\uc77c"\
+        "\uae08\uc694\uc77c"\
+        "\ud1a0\uc694\uc77c"]
+    ::msgcat::mcset ko MONTHS_ABBREV [list \
+        "1\uc6d4"\
+        "2\uc6d4"\
+        "3\uc6d4"\
+        "4\uc6d4"\
+        "5\uc6d4"\
+        "6\uc6d4"\
+        "7\uc6d4"\
+        "8\uc6d4"\
+        "9\uc6d4"\
+        "10\uc6d4"\
+        "11\uc6d4"\
+        "12\uc6d4"\
+        ""]
+    ::msgcat::mcset ko MONTHS_FULL [list \
+        "1\uc6d4"\
+        "2\uc6d4"\
+        "3\uc6d4"\
+        "4\uc6d4"\
+        "5\uc6d4"\
+        "6\uc6d4"\
+        "7\uc6d4"\
+        "8\uc6d4"\
+        "9\uc6d4"\
+        "10\uc6d4"\
+        "11\uc6d4"\
+        "12\uc6d4"\
+        ""]
+    ::msgcat::mcset ko AM "\uc624\uc804"
+    ::msgcat::mcset ko PM "\uc624\ud6c4"
+    ::msgcat::mcset ko DATE_FORMAT "%Y-%m-%d"
+    ::msgcat::mcset ko TIME_FORMAT_12 "%P %l:%M:%S"
+    ::msgcat::mcset ko DATE_TIME_FORMAT "%Y-%m-%d %P %l:%M:%S %z"
+    ::msgcat::mcset ko LOCALE_DATE_FORMAT "%Y\ub144%B%Od\uc77c"
+    ::msgcat::mcset ko LOCALE_TIME_FORMAT "%H\uc2dc%M\ubd84%S\ucd08"
+    ::msgcat::mcset ko LOCALE_DATE_TIME_FORMAT "%A %Y\ub144%B%Od\uc77c%H\uc2dc%M\ubd84%S\ucd08 %z"
+}
diff --git a/library/msgs/ko_kr.msg b/library/msgs/ko_kr.msg
new file mode 100644
index 0000000..ea5bbd7
--- /dev/null
+++ b/library/msgs/ko_kr.msg
@@ -0,0 +1,8 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset ko_KR BCE "\uae30\uc6d0\uc804"
+    ::msgcat::mcset ko_KR CE "\uc11c\uae30"
+    ::msgcat::mcset ko_KR DATE_FORMAT "%Y.%m.%d"
+    ::msgcat::mcset ko_KR TIME_FORMAT_12 "%P %l:%M:%S"
+    ::msgcat::mcset ko_KR DATE_TIME_FORMAT "%Y.%m.%d %P %l:%M:%S %z"
+}
diff --git a/library/msgs/kok.msg b/library/msgs/kok.msg
new file mode 100644
index 0000000..0869f20
--- /dev/null
+++ b/library/msgs/kok.msg
@@ -0,0 +1,39 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset kok DAYS_OF_WEEK_FULL [list \
+        "\u0906\u0926\u093f\u0924\u094d\u092f\u0935\u093e\u0930"\
+        "\u0938\u094b\u092e\u0935\u093e\u0930"\
+        "\u092e\u0902\u0917\u0933\u093e\u0930"\
+        "\u092c\u0941\u0927\u0935\u093e\u0930"\
+        "\u0917\u0941\u0930\u0941\u0935\u093e\u0930"\
+        "\u0936\u0941\u0915\u094d\u0930\u0935\u093e\u0930"\
+        "\u0936\u0928\u093f\u0935\u093e\u0930"]
+    ::msgcat::mcset kok MONTHS_ABBREV [list \
+        "\u091c\u093e\u0928\u0947\u0935\u093e\u0930\u0940"\
+        "\u092b\u0947\u092c\u0943\u0935\u093e\u0930\u0940"\
+        "\u092e\u093e\u0930\u094d\u091a"\
+        "\u090f\u092a\u094d\u0930\u093f\u0932"\
+        "\u092e\u0947"\
+        "\u091c\u0942\u0928"\
+        "\u091c\u0941\u0932\u0948"\
+        "\u0913\u0917\u0938\u094d\u091f"\
+        "\u0938\u0947\u092a\u094d\u091f\u0947\u0902\u092c\u0930"\
+        "\u0913\u0915\u094d\u091f\u094b\u092c\u0930"\
+        "\u0928\u094b\u0935\u094d\u0939\u0947\u0902\u092c\u0930"\
+        "\u0921\u093f\u0938\u0947\u0902\u092c\u0930"]
+    ::msgcat::mcset kok MONTHS_FULL [list \
+        "\u091c\u093e\u0928\u0947\u0935\u093e\u0930\u0940"\
+        "\u092b\u0947\u092c\u094d\u0930\u0941\u0935\u093e\u0930\u0940"\
+        "\u092e\u093e\u0930\u094d\u091a"\
+        "\u090f\u092a\u094d\u0930\u093f\u0932"\
+        "\u092e\u0947"\
+        "\u091c\u0942\u0928"\
+        "\u091c\u0941\u0932\u0948"\
+        "\u0913\u0917\u0938\u094d\u091f"\
+        "\u0938\u0947\u092a\u094d\u091f\u0947\u0902\u092c\u0930"\
+        "\u0913\u0915\u094d\u091f\u094b\u092c\u0930"\
+        "\u0928\u094b\u0935\u094d\u0939\u0947\u0902\u092c\u0930"\
+        "\u0921\u093f\u0938\u0947\u0902\u092c\u0930"]
+    ::msgcat::mcset kok AM "\u0915\u094d\u0930\u093f\u0938\u094d\u0924\u092a\u0942\u0930\u094d\u0935"
+    ::msgcat::mcset kok PM "\u0915\u094d\u0930\u093f\u0938\u094d\u0924\u0936\u0916\u093e"
+}
diff --git a/library/msgs/kok_in.msg b/library/msgs/kok_in.msg
new file mode 100644
index 0000000..abcb1ff
--- /dev/null
+++ b/library/msgs/kok_in.msg
@@ -0,0 +1,6 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset kok_IN DATE_FORMAT "%d %M %Y"
+    ::msgcat::mcset kok_IN TIME_FORMAT_12 "%I:%M:%S %P"
+    ::msgcat::mcset kok_IN DATE_TIME_FORMAT "%d %M %Y %I:%M:%S %P %z"
+}
diff --git a/library/msgs/kw.msg b/library/msgs/kw.msg
new file mode 100644
index 0000000..aaf79b3
--- /dev/null
+++ b/library/msgs/kw.msg
@@ -0,0 +1,47 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset kw DAYS_OF_WEEK_ABBREV [list \
+        "Sul"\
+        "Lun"\
+        "Mth"\
+        "Mhr"\
+        "Yow"\
+        "Gwe"\
+        "Sad"]
+    ::msgcat::mcset kw DAYS_OF_WEEK_FULL [list \
+        "De Sul"\
+        "De Lun"\
+        "De Merth"\
+        "De Merher"\
+        "De Yow"\
+        "De Gwener"\
+        "De Sadorn"]
+    ::msgcat::mcset kw MONTHS_ABBREV [list \
+        "Gen"\
+        "Whe"\
+        "Mer"\
+        "Ebr"\
+        "Me"\
+        "Evn"\
+        "Gor"\
+        "Est"\
+        "Gwn"\
+        "Hed"\
+        "Du"\
+        "Kev"\
+        ""]
+    ::msgcat::mcset kw MONTHS_FULL [list \
+        "Mys Genver"\
+        "Mys Whevrel"\
+        "Mys Merth"\
+        "Mys Ebrel"\
+        "Mys Me"\
+        "Mys Evan"\
+        "Mys Gortheren"\
+        "Mye Est"\
+        "Mys Gwyngala"\
+        "Mys Hedra"\
+        "Mys Du"\
+        "Mys Kevardhu"\
+        ""]
+}
diff --git a/library/msgs/kw_gb.msg b/library/msgs/kw_gb.msg
new file mode 100644
index 0000000..2967680
--- /dev/null
+++ b/library/msgs/kw_gb.msg
@@ -0,0 +1,6 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset kw_GB DATE_FORMAT "%d %B %Y"
+    ::msgcat::mcset kw_GB TIME_FORMAT_12 "%l:%M:%S %P"
+    ::msgcat::mcset kw_GB DATE_TIME_FORMAT "%d %B %Y %l:%M:%S %P %z"
+}
diff --git a/library/msgs/lt.msg b/library/msgs/lt.msg
new file mode 100644
index 0000000..27b0985
--- /dev/null
+++ b/library/msgs/lt.msg
@@ -0,0 +1,52 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset lt DAYS_OF_WEEK_ABBREV [list \
+        "Sk"\
+        "Pr"\
+        "An"\
+        "Tr"\
+        "Kt"\
+        "Pn"\
+        "\u0160t"]
+    ::msgcat::mcset lt DAYS_OF_WEEK_FULL [list \
+        "Sekmadienis"\
+        "Pirmadienis"\
+        "Antradienis"\
+        "Tre\u010diadienis"\
+        "Ketvirtadienis"\
+        "Penktadienis"\
+        "\u0160e\u0161tadienis"]
+    ::msgcat::mcset lt MONTHS_ABBREV [list \
+        "Sau"\
+        "Vas"\
+        "Kov"\
+        "Bal"\
+        "Geg"\
+        "Bir"\
+        "Lie"\
+        "Rgp"\
+        "Rgs"\
+        "Spa"\
+        "Lap"\
+        "Grd"\
+        ""]
+    ::msgcat::mcset lt MONTHS_FULL [list \
+        "Sausio"\
+        "Vasario"\
+        "Kovo"\
+        "Baland\u017eio"\
+        "Gegu\u017e\u0117s"\
+        "Bir\u017eelio"\
+        "Liepos"\
+        "Rugpj\u016b\u010dio"\
+        "Rugs\u0117jo"\
+        "Spalio"\
+        "Lapkri\u010dio"\
+        "Gruod\u017eio"\
+        ""]
+    ::msgcat::mcset lt BCE "pr.Kr."
+    ::msgcat::mcset lt CE "po.Kr."
+    ::msgcat::mcset lt DATE_FORMAT "%Y.%m.%e"
+    ::msgcat::mcset lt TIME_FORMAT "%H.%M.%S"
+    ::msgcat::mcset lt DATE_TIME_FORMAT "%Y.%m.%e %H.%M.%S %z"
+}
diff --git a/library/msgs/lv.msg b/library/msgs/lv.msg
new file mode 100644
index 0000000..a037b15
--- /dev/null
+++ b/library/msgs/lv.msg
@@ -0,0 +1,52 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset lv DAYS_OF_WEEK_ABBREV [list \
+        "Sv"\
+        "P"\
+        "O"\
+        "T"\
+        "C"\
+        "Pk"\
+        "S"]
+    ::msgcat::mcset lv DAYS_OF_WEEK_FULL [list \
+        "sv\u0113tdiena"\
+        "pirmdiena"\
+        "otrdiena"\
+        "tre\u0161diena"\
+        "ceturdien"\
+        "piektdiena"\
+        "sestdiena"]
+    ::msgcat::mcset lv MONTHS_ABBREV [list \
+        "Jan"\
+        "Feb"\
+        "Mar"\
+        "Apr"\
+        "Maijs"\
+        "J\u016bn"\
+        "J\u016bl"\
+        "Aug"\
+        "Sep"\
+        "Okt"\
+        "Nov"\
+        "Dec"\
+        ""]
+    ::msgcat::mcset lv MONTHS_FULL [list \
+        "janv\u0101ris"\
+        "febru\u0101ris"\
+        "marts"\
+        "apr\u012blis"\
+        "maijs"\
+        "j\u016bnijs"\
+        "j\u016blijs"\
+        "augusts"\
+        "septembris"\
+        "oktobris"\
+        "novembris"\
+        "decembris"\
+        ""]
+    ::msgcat::mcset lv BCE "pm\u0113"
+    ::msgcat::mcset lv CE "m\u0113"
+    ::msgcat::mcset lv DATE_FORMAT "%Y.%e.%m"
+    ::msgcat::mcset lv TIME_FORMAT "%H:%M:%S"
+    ::msgcat::mcset lv DATE_TIME_FORMAT "%Y.%e.%m %H:%M:%S %z"
+}
diff --git a/library/msgs/mk.msg b/library/msgs/mk.msg
new file mode 100644
index 0000000..41cf60d
--- /dev/null
+++ b/library/msgs/mk.msg
@@ -0,0 +1,52 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset mk DAYS_OF_WEEK_ABBREV [list \
+        "\u043d\u0435\u0434."\
+        "\u043f\u043e\u043d."\
+        "\u0432\u0442."\
+        "\u0441\u0440\u0435."\
+        "\u0447\u0435\u0442."\
+        "\u043f\u0435\u0442."\
+        "\u0441\u0430\u0431."]
+    ::msgcat::mcset mk DAYS_OF_WEEK_FULL [list \
+        "\u043d\u0435\u0434\u0435\u043b\u0430"\
+        "\u043f\u043e\u043d\u0435\u0434\u0435\u043b\u043d\u0438\u043a"\
+        "\u0432\u0442\u043e\u0440\u043d\u0438\u043a"\
+        "\u0441\u0440\u0435\u0434\u0430"\
+        "\u0447\u0435\u0442\u0432\u0440\u0442\u043e\u043a"\
+        "\u043f\u0435\u0442\u043e\u043a"\
+        "\u0441\u0430\u0431\u043e\u0442\u0430"]
+    ::msgcat::mcset mk MONTHS_ABBREV [list \
+        "\u0458\u0430\u043d."\
+        "\u0444\u0435\u0432."\
+        "\u043c\u0430\u0440."\
+        "\u0430\u043f\u0440."\
+        "\u043c\u0430\u0458."\
+        "\u0458\u0443\u043d."\
+        "\u0458\u0443\u043b."\
+        "\u0430\u0432\u0433."\
+        "\u0441\u0435\u043f\u0442."\
+        "\u043e\u043a\u0442."\
+        "\u043d\u043e\u0435\u043c."\
+        "\u0434\u0435\u043a\u0435\u043c."\
+        ""]
+    ::msgcat::mcset mk MONTHS_FULL [list \
+        "\u0458\u0430\u043d\u0443\u0430\u0440\u0438"\
+        "\u0444\u0435\u0432\u0440\u0443\u0430\u0440\u0438"\
+        "\u043c\u0430\u0440\u0442"\
+        "\u0430\u043f\u0440\u0438\u043b"\
+        "\u043c\u0430\u0458"\
+        "\u0458\u0443\u043d\u0438"\
+        "\u0458\u0443\u043b\u0438"\
+        "\u0430\u0432\u0433\u0443\u0441\u0442"\
+        "\u0441\u0435\u043f\u0442\u0435\u043c\u0432\u0440\u0438"\
+        "\u043e\u043a\u0442\u043e\u043c\u0432\u0440\u0438"\
+        "\u043d\u043e\u0435\u043c\u0432\u0440\u0438"\
+        "\u0434\u0435\u043a\u0435\u043c\u0432\u0440\u0438"\
+        ""]
+    ::msgcat::mcset mk BCE "\u043f\u0440.\u043d.\u0435."
+    ::msgcat::mcset mk CE "\u0430\u0435."
+    ::msgcat::mcset mk DATE_FORMAT "%e.%m.%Y"
+    ::msgcat::mcset mk TIME_FORMAT "%H:%M:%S %z"
+    ::msgcat::mcset mk DATE_TIME_FORMAT "%e.%m.%Y %H:%M:%S %z %z"
+}
diff --git a/library/msgs/mr.msg b/library/msgs/mr.msg
new file mode 100644
index 0000000..cea427a
--- /dev/null
+++ b/library/msgs/mr.msg
@@ -0,0 +1,39 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset mr DAYS_OF_WEEK_FULL [list \
+        "\u0930\u0935\u093f\u0935\u093e\u0930"\
+        "\u0938\u094b\u092e\u0935\u093e\u0930"\
+        "\u092e\u0902\u0917\u0933\u0935\u093e\u0930"\
+        "\u092e\u0902\u0917\u0933\u0935\u093e\u0930"\
+        "\u0917\u0941\u0930\u0941\u0935\u093e\u0930"\
+        "\u0936\u0941\u0915\u094d\u0930\u0935\u093e\u0930"\
+        "\u0936\u0928\u093f\u0935\u093e\u0930"]
+    ::msgcat::mcset mr MONTHS_ABBREV [list \
+        "\u091c\u093e\u0928\u0947\u0935\u093e\u0930\u0940"\
+        "\u092b\u0947\u092c\u0943\u0935\u093e\u0930\u0940"\
+        "\u092e\u093e\u0930\u094d\u091a"\
+        "\u090f\u092a\u094d\u0930\u093f\u0932"\
+        "\u092e\u0947"\
+        "\u091c\u0942\u0928"\
+        "\u091c\u0941\u0932\u0948"\
+        "\u0913\u0917\u0938\u094d\u091f"\
+        "\u0938\u0947\u092a\u094d\u091f\u0947\u0902\u092c\u0930"\
+        "\u0913\u0915\u094d\u091f\u094b\u092c\u0930"\
+        "\u0928\u094b\u0935\u094d\u0939\u0947\u0902\u092c\u0930"\
+        "\u0921\u093f\u0938\u0947\u0902\u092c\u0930"]
+    ::msgcat::mcset mr MONTHS_FULL [list \
+        "\u091c\u093e\u0928\u0947\u0935\u093e\u0930\u0940"\
+        "\u092b\u0947\u092c\u0943\u0935\u093e\u0930\u0940"\
+        "\u092e\u093e\u0930\u094d\u091a"\
+        "\u090f\u092a\u094d\u0930\u093f\u0932"\
+        "\u092e\u0947"\
+        "\u091c\u0942\u0928"\
+        "\u091c\u0941\u0932\u0948"\
+        "\u0913\u0917\u0938\u094d\u091f"\
+        "\u0938\u0947\u092a\u094d\u091f\u0947\u0902\u092c\u0930"\
+        "\u0913\u0915\u094d\u091f\u094b\u092c\u0930"\
+        "\u0928\u094b\u0935\u094d\u0939\u0947\u0902\u092c\u0930"\
+        "\u0921\u093f\u0938\u0947\u0902\u092c\u0930"]
+    ::msgcat::mcset mr AM "BC"
+    ::msgcat::mcset mr PM "AD"
+}
diff --git a/library/msgs/mr_in.msg b/library/msgs/mr_in.msg
new file mode 100644
index 0000000..1889da5
--- /dev/null
+++ b/library/msgs/mr_in.msg
@@ -0,0 +1,6 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset mr_IN DATE_FORMAT "%d %M %Y"
+    ::msgcat::mcset mr_IN TIME_FORMAT_12 "%I:%M:%S %P"
+    ::msgcat::mcset mr_IN DATE_TIME_FORMAT "%d %M %Y %I:%M:%S %P %z"
+}
diff --git a/library/msgs/ms.msg b/library/msgs/ms.msg
new file mode 100644
index 0000000..e954431
--- /dev/null
+++ b/library/msgs/ms.msg
@@ -0,0 +1,47 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset ms DAYS_OF_WEEK_ABBREV [list \
+        "Aha"\
+        "Isn"\
+        "Sei"\
+        "Rab"\
+        "Kha"\
+        "Jum"\
+        "Sab"]
+    ::msgcat::mcset ms DAYS_OF_WEEK_FULL [list \
+        "Ahad"\
+        "Isnin"\
+        "Selasa"\
+        "Rahu"\
+        "Khamis"\
+        "Jumaat"\
+        "Sabtu"]
+    ::msgcat::mcset ms MONTHS_ABBREV [list \
+        "Jan"\
+        "Feb"\
+        "Mac"\
+        "Apr"\
+        "Mei"\
+        "Jun"\
+        "Jul"\
+        "Ogos"\
+        "Sep"\
+        "Okt"\
+        "Nov"\
+        "Dis"\
+        ""]
+    ::msgcat::mcset ms MONTHS_FULL [list \
+        "Januari"\
+        "Februari"\
+        "Mac"\
+        "April"\
+        "Mei"\
+        "Jun"\
+        "Julai"\
+        "Ogos"\
+        "September"\
+        "Oktober"\
+        "November"\
+        "Disember"\
+        ""]
+}
diff --git a/library/msgs/ms_my.msg b/library/msgs/ms_my.msg
new file mode 100644
index 0000000..c1f93d4
--- /dev/null
+++ b/library/msgs/ms_my.msg
@@ -0,0 +1,6 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset ms_MY DATE_FORMAT "%A %d %b %Y"
+    ::msgcat::mcset ms_MY TIME_FORMAT_12 "%I:%M:%S  %z"
+    ::msgcat::mcset ms_MY DATE_TIME_FORMAT "%A %d %b %Y %I:%M:%S  %z %z"
+}
diff --git a/library/msgs/mt.msg b/library/msgs/mt.msg
new file mode 100644
index 0000000..ddd5446
--- /dev/null
+++ b/library/msgs/mt.msg
@@ -0,0 +1,27 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset mt DAYS_OF_WEEK_ABBREV [list \
+        "\u0126ad"\
+        "Tne"\
+        "Tli"\
+        "Erb"\
+        "\u0126am"\
+        "\u0120im"]
+    ::msgcat::mcset mt MONTHS_ABBREV [list \
+        "Jan"\
+        "Fra"\
+        "Mar"\
+        "Apr"\
+        "Mej"\
+        "\u0120un"\
+        "Lul"\
+        "Awi"\
+        "Set"\
+        "Ott"\
+        "Nov"]
+    ::msgcat::mcset mt BCE "QK"
+    ::msgcat::mcset mt CE ""
+    ::msgcat::mcset mt DATE_FORMAT "%A, %e ta %B, %Y"
+    ::msgcat::mcset mt TIME_FORMAT_12 "%l:%M:%S %P"
+    ::msgcat::mcset mt DATE_TIME_FORMAT "%A, %e ta %B, %Y %l:%M:%S %P %z"
+}
diff --git a/library/msgs/nb.msg b/library/msgs/nb.msg
new file mode 100644
index 0000000..90d49a3
--- /dev/null
+++ b/library/msgs/nb.msg
@@ -0,0 +1,52 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset nb DAYS_OF_WEEK_ABBREV [list \
+        "s\u00f8"\
+        "ma"\
+        "ti"\
+        "on"\
+        "to"\
+        "fr"\
+        "l\u00f8"]
+    ::msgcat::mcset nb DAYS_OF_WEEK_FULL [list \
+        "s\u00f8ndag"\
+        "mandag"\
+        "tirsdag"\
+        "onsdag"\
+        "torsdag"\
+        "fredag"\
+        "l\u00f8rdag"]
+    ::msgcat::mcset nb MONTHS_ABBREV [list \
+        "jan"\
+        "feb"\
+        "mar"\
+        "apr"\
+        "mai"\
+        "jun"\
+        "jul"\
+        "aug"\
+        "sep"\
+        "okt"\
+        "nov"\
+        "des"\
+        ""]
+    ::msgcat::mcset nb MONTHS_FULL [list \
+        "januar"\
+        "februar"\
+        "mars"\
+        "april"\
+        "mai"\
+        "juni"\
+        "juli"\
+        "august"\
+        "september"\
+        "oktober"\
+        "november"\
+        "desember"\
+        ""]
+    ::msgcat::mcset nb BCE "f.Kr."
+    ::msgcat::mcset nb CE "e.Kr."
+    ::msgcat::mcset nb DATE_FORMAT "%e. %B %Y"
+    ::msgcat::mcset nb TIME_FORMAT "%H:%M:%S"
+    ::msgcat::mcset nb DATE_TIME_FORMAT "%e. %B %Y %H:%M:%S %z"
+}
diff --git a/library/msgs/nl.msg b/library/msgs/nl.msg
new file mode 100644
index 0000000..4c5c675
--- /dev/null
+++ b/library/msgs/nl.msg
@@ -0,0 +1,50 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset nl DAYS_OF_WEEK_ABBREV [list \
+        "zo"\
+        "ma"\
+        "di"\
+        "wo"\
+        "do"\
+        "vr"\
+        "za"]
+    ::msgcat::mcset nl DAYS_OF_WEEK_FULL [list \
+        "zondag"\
+        "maandag"\
+        "dinsdag"\
+        "woensdag"\
+        "donderdag"\
+        "vrijdag"\
+        "zaterdag"]
+    ::msgcat::mcset nl MONTHS_ABBREV [list \
+        "jan"\
+        "feb"\
+        "mrt"\
+        "apr"\
+        "mei"\
+        "jun"\
+        "jul"\
+        "aug"\
+        "sep"\
+        "okt"\
+        "nov"\
+        "dec"\
+        ""]
+    ::msgcat::mcset nl MONTHS_FULL [list \
+        "januari"\
+        "februari"\
+        "maart"\
+        "april"\
+        "mei"\
+        "juni"\
+        "juli"\
+        "augustus"\
+        "september"\
+        "oktober"\
+        "november"\
+        "december"\
+        ""]
+    ::msgcat::mcset nl DATE_FORMAT "%e %B %Y"
+    ::msgcat::mcset nl TIME_FORMAT "%k:%M:%S"
+    ::msgcat::mcset nl DATE_TIME_FORMAT "%e %B %Y %k:%M:%S %z"
+}
diff --git a/library/msgs/nl_be.msg b/library/msgs/nl_be.msg
new file mode 100644
index 0000000..4b19670
--- /dev/null
+++ b/library/msgs/nl_be.msg
@@ -0,0 +1,7 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset nl_BE DATE_FORMAT "%d-%m-%y"
+    ::msgcat::mcset nl_BE TIME_FORMAT "%T"
+    ::msgcat::mcset nl_BE TIME_FORMAT_12 "%T"
+    ::msgcat::mcset nl_BE DATE_TIME_FORMAT "%a %d %b %Y %T %z"
+}
diff --git a/library/msgs/nn.msg b/library/msgs/nn.msg
new file mode 100644
index 0000000..bd61ac9
--- /dev/null
+++ b/library/msgs/nn.msg
@@ -0,0 +1,52 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset nn DAYS_OF_WEEK_ABBREV [list \
+        "su"\
+        "m\u00e5"\
+        "ty"\
+        "on"\
+        "to"\
+        "fr"\
+        "lau"]
+    ::msgcat::mcset nn DAYS_OF_WEEK_FULL [list \
+        "sundag"\
+        "m\u00e5ndag"\
+        "tysdag"\
+        "onsdag"\
+        "torsdag"\
+        "fredag"\
+        "laurdag"]
+    ::msgcat::mcset nn MONTHS_ABBREV [list \
+        "jan"\
+        "feb"\
+        "mar"\
+        "apr"\
+        "mai"\
+        "jun"\
+        "jul"\
+        "aug"\
+        "sep"\
+        "okt"\
+        "nov"\
+        "des"\
+        ""]
+    ::msgcat::mcset nn MONTHS_FULL [list \
+        "januar"\
+        "februar"\
+        "mars"\
+        "april"\
+        "mai"\
+        "juni"\
+        "juli"\
+        "august"\
+        "september"\
+        "oktober"\
+        "november"\
+        "desember"\
+        ""]
+    ::msgcat::mcset nn BCE "f.Kr."
+    ::msgcat::mcset nn CE "e.Kr."
+    ::msgcat::mcset nn DATE_FORMAT "%e. %B %Y"
+    ::msgcat::mcset nn TIME_FORMAT "%H:%M:%S"
+    ::msgcat::mcset nn DATE_TIME_FORMAT "%e. %B %Y %H:%M:%S %z"
+}
diff --git a/library/msgs/pl.msg b/library/msgs/pl.msg
new file mode 100644
index 0000000..d206f4b
--- /dev/null
+++ b/library/msgs/pl.msg
@@ -0,0 +1,52 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset pl DAYS_OF_WEEK_ABBREV [list \
+        "N"\
+        "Pn"\
+        "Wt"\
+        "\u015ar"\
+        "Cz"\
+        "Pt"\
+        "So"]
+    ::msgcat::mcset pl DAYS_OF_WEEK_FULL [list \
+        "niedziela"\
+        "poniedzia\u0142ek"\
+        "wtorek"\
+        "\u015broda"\
+        "czwartek"\
+        "pi\u0105tek"\
+        "sobota"]
+    ::msgcat::mcset pl MONTHS_ABBREV [list \
+        "sty"\
+        "lut"\
+        "mar"\
+        "kwi"\
+        "maj"\
+        "cze"\
+        "lip"\
+        "sie"\
+        "wrz"\
+        "pa\u017a"\
+        "lis"\
+        "gru"\
+        ""]
+    ::msgcat::mcset pl MONTHS_FULL [list \
+        "stycze\u0144"\
+        "luty"\
+        "marzec"\
+        "kwiecie\u0144"\
+        "maj"\
+        "czerwiec"\
+        "lipiec"\
+        "sierpie\u0144"\
+        "wrzesie\u0144"\
+        "pa\u017adziernik"\
+        "listopad"\
+        "grudzie\u0144"\
+        ""]
+    ::msgcat::mcset pl BCE "p.n.e."
+    ::msgcat::mcset pl CE "n.e."
+    ::msgcat::mcset pl DATE_FORMAT "%Y-%m-%d"
+    ::msgcat::mcset pl TIME_FORMAT "%H:%M:%S"
+    ::msgcat::mcset pl DATE_TIME_FORMAT "%Y-%m-%d %H:%M:%S %z"
+}
diff --git a/library/msgs/pt.msg b/library/msgs/pt.msg
new file mode 100644
index 0000000..96fdb35
--- /dev/null
+++ b/library/msgs/pt.msg
@@ -0,0 +1,50 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset pt DAYS_OF_WEEK_ABBREV [list \
+        "Dom"\
+        "Seg"\
+        "Ter"\
+        "Qua"\
+        "Qui"\
+        "Sex"\
+        "S\u00e1b"]
+    ::msgcat::mcset pt DAYS_OF_WEEK_FULL [list \
+        "Domingo"\
+        "Segunda-feira"\
+        "Ter\u00e7a-feira"\
+        "Quarta-feira"\
+        "Quinta-feira"\
+        "Sexta-feira"\
+        "S\u00e1bado"]
+    ::msgcat::mcset pt MONTHS_ABBREV [list \
+        "Jan"\
+        "Fev"\
+        "Mar"\
+        "Abr"\
+        "Mai"\
+        "Jun"\
+        "Jul"\
+        "Ago"\
+        "Set"\
+        "Out"\
+        "Nov"\
+        "Dez"\
+        ""]
+    ::msgcat::mcset pt MONTHS_FULL [list \
+        "Janeiro"\
+        "Fevereiro"\
+        "Mar\u00e7o"\
+        "Abril"\
+        "Maio"\
+        "Junho"\
+        "Julho"\
+        "Agosto"\
+        "Setembro"\
+        "Outubro"\
+        "Novembro"\
+        "Dezembro"\
+        ""]
+    ::msgcat::mcset pt DATE_FORMAT "%d-%m-%Y"
+    ::msgcat::mcset pt TIME_FORMAT "%k:%M:%S"
+    ::msgcat::mcset pt DATE_TIME_FORMAT "%d-%m-%Y %k:%M:%S %z"
+}
diff --git a/library/msgs/pt_br.msg b/library/msgs/pt_br.msg
new file mode 100644
index 0000000..8684327
--- /dev/null
+++ b/library/msgs/pt_br.msg
@@ -0,0 +1,7 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset pt_BR DATE_FORMAT "%d-%m-%Y"
+    ::msgcat::mcset pt_BR TIME_FORMAT "%T"
+    ::msgcat::mcset pt_BR TIME_FORMAT_12 "%T"
+    ::msgcat::mcset pt_BR DATE_TIME_FORMAT "%a %d %b %Y %T %z"
+}
diff --git a/library/msgs/ro.msg b/library/msgs/ro.msg
new file mode 100644
index 0000000..bdd7c61
--- /dev/null
+++ b/library/msgs/ro.msg
@@ -0,0 +1,52 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset ro DAYS_OF_WEEK_ABBREV [list \
+        "D"\
+        "L"\
+        "Ma"\
+        "Mi"\
+        "J"\
+        "V"\
+        "S"]
+    ::msgcat::mcset ro DAYS_OF_WEEK_FULL [list \
+        "duminic\u0103"\
+        "luni"\
+        "mar\u0163i"\
+        "miercuri"\
+        "joi"\
+        "vineri"\
+        "s\u00eemb\u0103t\u0103"]
+    ::msgcat::mcset ro MONTHS_ABBREV [list \
+        "Ian"\
+        "Feb"\
+        "Mar"\
+        "Apr"\
+        "Mai"\
+        "Iun"\
+        "Iul"\
+        "Aug"\
+        "Sep"\
+        "Oct"\
+        "Nov"\
+        "Dec"\
+        ""]
+    ::msgcat::mcset ro MONTHS_FULL [list \
+        "ianuarie"\
+        "februarie"\
+        "martie"\
+        "aprilie"\
+        "mai"\
+        "iunie"\
+        "iulie"\
+        "august"\
+        "septembrie"\
+        "octombrie"\
+        "noiembrie"\
+        "decembrie"\
+        ""]
+    ::msgcat::mcset ro BCE "d.C."
+    ::msgcat::mcset ro CE "\u00ee.d.C."
+    ::msgcat::mcset ro DATE_FORMAT "%d.%m.%Y"
+    ::msgcat::mcset ro TIME_FORMAT "%H:%M:%S"
+    ::msgcat::mcset ro DATE_TIME_FORMAT "%d.%m.%Y %H:%M:%S %z"
+}
diff --git a/library/msgs/ru.msg b/library/msgs/ru.msg
new file mode 100644
index 0000000..65b075d
--- /dev/null
+++ b/library/msgs/ru.msg
@@ -0,0 +1,52 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset ru DAYS_OF_WEEK_ABBREV [list \
+        "\u0412\u0441"\
+        "\u041f\u043d"\
+        "\u0412\u0442"\
+        "\u0421\u0440"\
+        "\u0427\u0442"\
+        "\u041f\u0442"\
+        "\u0421\u0431"]
+    ::msgcat::mcset ru DAYS_OF_WEEK_FULL [list \
+        "\u0432\u043e\u0441\u043a\u0440\u0435\u0441\u0435\u043d\u044c\u0435"\
+        "\u043f\u043e\u043d\u0435\u0434\u0435\u043b\u044c\u043d\u0438\u043a"\
+        "\u0432\u0442\u043e\u0440\u043d\u0438\u043a"\
+        "\u0441\u0440\u0435\u0434\u0430"\
+        "\u0447\u0435\u0442\u0432\u0435\u0440\u0433"\
+        "\u043f\u044f\u0442\u043d\u0438\u0446\u0430"\
+        "\u0441\u0443\u0431\u0431\u043e\u0442\u0430"]
+    ::msgcat::mcset ru MONTHS_ABBREV [list \
+        "\u044f\u043d\u0432"\
+        "\u0444\u0435\u0432"\
+        "\u043c\u0430\u0440"\
+        "\u0430\u043f\u0440"\
+        "\u043c\u0430\u0439"\
+        "\u0438\u044e\u043d"\
+        "\u0438\u044e\u043b"\
+        "\u0430\u0432\u0433"\
+        "\u0441\u0435\u043d"\
+        "\u043e\u043a\u0442"\
+        "\u043d\u043e\u044f"\
+        "\u0434\u0435\u043a"\
+        ""]
+    ::msgcat::mcset ru MONTHS_FULL [list \
+        "\u042f\u043d\u0432\u0430\u0440\u044c"\
+        "\u0424\u0435\u0432\u0440\u0430\u043b\u044c"\
+        "\u041c\u0430\u0440\u0442"\
+        "\u0410\u043f\u0440\u0435\u043b\u044c"\
+        "\u041c\u0430\u0439"\
+        "\u0418\u044e\u043d\u044c"\
+        "\u0418\u044e\u043b\u044c"\
+        "\u0410\u0432\u0433\u0443\u0441\u0442"\
+        "\u0421\u0435\u043d\u0442\u044f\u0431\u0440\u044c"\
+        "\u041e\u043a\u0442\u044f\u0431\u0440\u044c"\
+        "\u041d\u043e\u044f\u0431\u0440\u044c"\
+        "\u0414\u0435\u043a\u0430\u0431\u0440\u044c"\
+        ""]
+    ::msgcat::mcset ru BCE "\u0434\u043e \u043d.\u044d."
+    ::msgcat::mcset ru CE "\u043d.\u044d."
+    ::msgcat::mcset ru DATE_FORMAT "%d.%m.%Y"
+    ::msgcat::mcset ru TIME_FORMAT "%k:%M:%S"
+    ::msgcat::mcset ru DATE_TIME_FORMAT "%d.%m.%Y %k:%M:%S %z"
+}
diff --git a/library/msgs/ru_ua.msg b/library/msgs/ru_ua.msg
new file mode 100644
index 0000000..6e1f8a8
--- /dev/null
+++ b/library/msgs/ru_ua.msg
@@ -0,0 +1,6 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset ru_UA DATE_FORMAT "%d.%m.%Y"
+    ::msgcat::mcset ru_UA TIME_FORMAT "%k:%M:%S"
+    ::msgcat::mcset ru_UA DATE_TIME_FORMAT "%d.%m.%Y %k:%M:%S %z"
+}
diff --git a/library/msgs/sh.msg b/library/msgs/sh.msg
new file mode 100644
index 0000000..6ee0fc7
--- /dev/null
+++ b/library/msgs/sh.msg
@@ -0,0 +1,52 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset sh DAYS_OF_WEEK_ABBREV [list \
+        "Ned"\
+        "Pon"\
+        "Uto"\
+        "Sre"\
+        "\u010cet"\
+        "Pet"\
+        "Sub"]
+    ::msgcat::mcset sh DAYS_OF_WEEK_FULL [list \
+        "Nedelja"\
+        "Ponedeljak"\
+        "Utorak"\
+        "Sreda"\
+        "\u010cetvrtak"\
+        "Petak"\
+        "Subota"]
+    ::msgcat::mcset sh MONTHS_ABBREV [list \
+        "Jan"\
+        "Feb"\
+        "Mar"\
+        "Apr"\
+        "Maj"\
+        "Jun"\
+        "Jul"\
+        "Avg"\
+        "Sep"\
+        "Okt"\
+        "Nov"\
+        "Dec"\
+        ""]
+    ::msgcat::mcset sh MONTHS_FULL [list \
+        "Januar"\
+        "Februar"\
+        "Mart"\
+        "April"\
+        "Maj"\
+        "Juni"\
+        "Juli"\
+        "Avgust"\
+        "Septembar"\
+        "Oktobar"\
+        "Novembar"\
+        "Decembar"\
+        ""]
+    ::msgcat::mcset sh BCE "p. n. e."
+    ::msgcat::mcset sh CE "n. e."
+    ::msgcat::mcset sh DATE_FORMAT "%d.%m.%Y."
+    ::msgcat::mcset sh TIME_FORMAT "%k.%M.%S"
+    ::msgcat::mcset sh DATE_TIME_FORMAT "%d.%m.%Y. %k.%M.%S %z"
+}
diff --git a/library/msgs/sk.msg b/library/msgs/sk.msg
new file mode 100644
index 0000000..9b2f0aa
--- /dev/null
+++ b/library/msgs/sk.msg
@@ -0,0 +1,52 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset sk DAYS_OF_WEEK_ABBREV [list \
+        "Ne"\
+        "Po"\
+        "Ut"\
+        "St"\
+        "\u0160t"\
+        "Pa"\
+        "So"]
+    ::msgcat::mcset sk DAYS_OF_WEEK_FULL [list \
+        "Nede\u013ee"\
+        "Pondelok"\
+        "Utorok"\
+        "Streda"\
+        "\u0160tvrtok"\
+        "Piatok"\
+        "Sobota"]
+    ::msgcat::mcset sk MONTHS_ABBREV [list \
+        "jan"\
+        "feb"\
+        "mar"\
+        "apr"\
+        "m\u00e1j"\
+        "j\u00fan"\
+        "j\u00fal"\
+        "aug"\
+        "sep"\
+        "okt"\
+        "nov"\
+        "dec"\
+        ""]
+    ::msgcat::mcset sk MONTHS_FULL [list \
+        "janu\u00e1r"\
+        "febru\u00e1r"\
+        "marec"\
+        "apr\u00edl"\
+        "m\u00e1j"\
+        "j\u00fan"\
+        "j\u00fal"\
+        "august"\
+        "september"\
+        "okt\u00f3ber"\
+        "november"\
+        "december"\
+        ""]
+    ::msgcat::mcset sk BCE "pred n.l."
+    ::msgcat::mcset sk CE "n.l."
+    ::msgcat::mcset sk DATE_FORMAT "%e.%m.%Y"
+    ::msgcat::mcset sk TIME_FORMAT "%k:%M:%S"
+    ::msgcat::mcset sk DATE_TIME_FORMAT "%e.%m.%Y %k:%M:%S %z"
+}
diff --git a/library/msgs/sl.msg b/library/msgs/sl.msg
new file mode 100644
index 0000000..42bc509
--- /dev/null
+++ b/library/msgs/sl.msg
@@ -0,0 +1,52 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset sl DAYS_OF_WEEK_ABBREV [list \
+        "Ned"\
+        "Pon"\
+        "Tor"\
+        "Sre"\
+        "\u010cet"\
+        "Pet"\
+        "Sob"]
+    ::msgcat::mcset sl DAYS_OF_WEEK_FULL [list \
+        "Nedelja"\
+        "Ponedeljek"\
+        "Torek"\
+        "Sreda"\
+        "\u010cetrtek"\
+        "Petek"\
+        "Sobota"]
+    ::msgcat::mcset sl MONTHS_ABBREV [list \
+        "jan"\
+        "feb"\
+        "mar"\
+        "apr"\
+        "maj"\
+        "jun"\
+        "jul"\
+        "avg"\
+        "sep"\
+        "okt"\
+        "nov"\
+        "dec"\
+        ""]
+    ::msgcat::mcset sl MONTHS_FULL [list \
+        "januar"\
+        "februar"\
+        "marec"\
+        "april"\
+        "maj"\
+        "junij"\
+        "julij"\
+        "avgust"\
+        "september"\
+        "oktober"\
+        "november"\
+        "december"\
+        ""]
+    ::msgcat::mcset sl BCE "pr.n.\u0161."
+    ::msgcat::mcset sl CE "po Kr."
+    ::msgcat::mcset sl DATE_FORMAT "%Y.%m.%e"
+    ::msgcat::mcset sl TIME_FORMAT "%k:%M:%S"
+    ::msgcat::mcset sl DATE_TIME_FORMAT "%Y.%m.%e %k:%M:%S %z"
+}
diff --git a/library/msgs/sq.msg b/library/msgs/sq.msg
new file mode 100644
index 0000000..8fb1fce
--- /dev/null
+++ b/library/msgs/sq.msg
@@ -0,0 +1,54 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset sq DAYS_OF_WEEK_ABBREV [list \
+        "Die"\
+        "H\u00ebn"\
+        "Mar"\
+        "M\u00ebr"\
+        "Enj"\
+        "Pre"\
+        "Sht"]
+    ::msgcat::mcset sq DAYS_OF_WEEK_FULL [list \
+        "e diel"\
+        "e h\u00ebn\u00eb"\
+        "e mart\u00eb"\
+        "e m\u00ebrkur\u00eb"\
+        "e enjte"\
+        "e premte"\
+        "e shtun\u00eb"]
+    ::msgcat::mcset sq MONTHS_ABBREV [list \
+        "Jan"\
+        "Shk"\
+        "Mar"\
+        "Pri"\
+        "Maj"\
+        "Qer"\
+        "Kor"\
+        "Gsh"\
+        "Sht"\
+        "Tet"\
+        "N\u00ebn"\
+        "Dhj"\
+        ""]
+    ::msgcat::mcset sq MONTHS_FULL [list \
+        "janar"\
+        "shkurt"\
+        "mars"\
+        "prill"\
+        "maj"\
+        "qershor"\
+        "korrik"\
+        "gusht"\
+        "shtator"\
+        "tetor"\
+        "n\u00ebntor"\
+        "dhjetor"\
+        ""]
+    ::msgcat::mcset sq BCE "p.e.r."
+    ::msgcat::mcset sq CE "n.e.r."
+    ::msgcat::mcset sq AM "PD"
+    ::msgcat::mcset sq PM "MD"
+    ::msgcat::mcset sq DATE_FORMAT "%Y-%m-%d"
+    ::msgcat::mcset sq TIME_FORMAT_12 "%l:%M:%S.%P"
+    ::msgcat::mcset sq DATE_TIME_FORMAT "%Y-%m-%d %l:%M:%S.%P %z"
+}
diff --git a/library/msgs/sr.msg b/library/msgs/sr.msg
new file mode 100644
index 0000000..7576668
--- /dev/null
+++ b/library/msgs/sr.msg
@@ -0,0 +1,52 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset sr DAYS_OF_WEEK_ABBREV [list \
+        "\u041d\u0435\u0434"\
+        "\u041f\u043e\u043d"\
+        "\u0423\u0442\u043e"\
+        "\u0421\u0440\u0435"\
+        "\u0427\u0435\u0442"\
+        "\u041f\u0435\u0442"\
+        "\u0421\u0443\u0431"]
+    ::msgcat::mcset sr DAYS_OF_WEEK_FULL [list \
+        "\u041d\u0435\u0434\u0435\u0459\u0430"\
+        "\u041f\u043e\u043d\u0435\u0434\u0435\u0459\u0430\u043a"\
+        "\u0423\u0442\u043e\u0440\u0430\u043a"\
+        "\u0421\u0440\u0435\u0434\u0430"\
+        "\u0427\u0435\u0442\u0432\u0440\u0442\u0430\u043a"\
+        "\u041f\u0435\u0442\u0430\u043a"\
+        "\u0421\u0443\u0431\u043e\u0442\u0430"]
+    ::msgcat::mcset sr MONTHS_ABBREV [list \
+        "\u0408\u0430\u043d"\
+        "\u0424\u0435\u0431"\
+        "\u041c\u0430\u0440"\
+        "\u0410\u043f\u0440"\
+        "\u041c\u0430\u0458"\
+        "\u0408\u0443\u043d"\
+        "\u0408\u0443\u043b"\
+        "\u0410\u0432\u0433"\
+        "\u0421\u0435\u043f"\
+        "\u041e\u043a\u0442"\
+        "\u041d\u043e\u0432"\
+        "\u0414\u0435\u0446"\
+        ""]
+    ::msgcat::mcset sr MONTHS_FULL [list \
+        "\u0408\u0430\u043d\u0443\u0430\u0440"\
+        "\u0424\u0435\u0431\u0440\u0443\u0430\u0440"\
+        "\u041c\u0430\u0440\u0442"\
+        "\u0410\u043f\u0440\u0438\u043b"\
+        "\u041c\u0430\u0458"\
+        "\u0408\u0443\u043d\u0438"\
+        "\u0408\u0443\u043b\u0438"\
+        "\u0410\u0432\u0433\u0443\u0441\u0442"\
+        "\u0421\u0435\u043f\u0442\u0435\u043c\u0431\u0430\u0440"\
+        "\u041e\u043a\u0442\u043e\u0431\u0430\u0440"\
+        "\u041d\u043e\u0432\u0435\u043c\u0431\u0430\u0440"\
+        "\u0414\u0435\u0446\u0435\u043c\u0431\u0430\u0440"\
+        ""]
+    ::msgcat::mcset sr BCE "\u043f. \u043d. \u0435."
+    ::msgcat::mcset sr CE "\u043d. \u0435"
+    ::msgcat::mcset sr DATE_FORMAT "%Y.%m.%e"
+    ::msgcat::mcset sr TIME_FORMAT "%k.%M.%S"
+    ::msgcat::mcset sr DATE_TIME_FORMAT "%Y.%m.%e %k.%M.%S %z"
+}
diff --git a/library/msgs/sv.msg b/library/msgs/sv.msg
new file mode 100644
index 0000000..f7a67c6
--- /dev/null
+++ b/library/msgs/sv.msg
@@ -0,0 +1,52 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset sv DAYS_OF_WEEK_ABBREV [list \
+        "s\u00f6"\
+        "m\u00e5"\
+        "ti"\
+        "on"\
+        "to"\
+        "fr"\
+        "l\u00f6"]
+    ::msgcat::mcset sv DAYS_OF_WEEK_FULL [list \
+        "s\u00f6ndag"\
+        "m\u00e5ndag"\
+        "tisdag"\
+        "onsdag"\
+        "torsdag"\
+        "fredag"\
+        "l\u00f6rdag"]
+    ::msgcat::mcset sv MONTHS_ABBREV [list \
+        "jan"\
+        "feb"\
+        "mar"\
+        "apr"\
+        "maj"\
+        "jun"\
+        "jul"\
+        "aug"\
+        "sep"\
+        "okt"\
+        "nov"\
+        "dec"\
+        ""]
+    ::msgcat::mcset sv MONTHS_FULL [list \
+        "januari"\
+        "februari"\
+        "mars"\
+        "april"\
+        "maj"\
+        "juni"\
+        "juli"\
+        "augusti"\
+        "september"\
+        "oktober"\
+        "november"\
+        "december"\
+        ""]
+    ::msgcat::mcset sv BCE "f.Kr."
+    ::msgcat::mcset sv CE "e.Kr."
+    ::msgcat::mcset sv DATE_FORMAT "%Y-%m-%d"
+    ::msgcat::mcset sv TIME_FORMAT "%H:%M:%S"
+    ::msgcat::mcset sv DATE_TIME_FORMAT "%Y-%m-%d %H:%M:%S %z"
+}
diff --git a/library/msgs/sw.msg b/library/msgs/sw.msg
new file mode 100644
index 0000000..b888b43
--- /dev/null
+++ b/library/msgs/sw.msg
@@ -0,0 +1,49 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset sw DAYS_OF_WEEK_ABBREV [list \
+        "Jpi"\
+        "Jtt"\
+        "Jnn"\
+        "Jtn"\
+        "Alh"\
+        "Iju"\
+        "Jmo"]
+    ::msgcat::mcset sw DAYS_OF_WEEK_FULL [list \
+        "Jumapili"\
+        "Jumatatu"\
+        "Jumanne"\
+        "Jumatano"\
+        "Alhamisi"\
+        "Ijumaa"\
+        "Jumamosi"]
+    ::msgcat::mcset sw MONTHS_ABBREV [list \
+        "Jan"\
+        "Feb"\
+        "Mar"\
+        "Apr"\
+        "Mei"\
+        "Jun"\
+        "Jul"\
+        "Ago"\
+        "Sep"\
+        "Okt"\
+        "Nov"\
+        "Des"\
+        ""]
+    ::msgcat::mcset sw MONTHS_FULL [list \
+        "Januari"\
+        "Februari"\
+        "Machi"\
+        "Aprili"\
+        "Mei"\
+        "Juni"\
+        "Julai"\
+        "Agosti"\
+        "Septemba"\
+        "Oktoba"\
+        "Novemba"\
+        "Desemba"\
+        ""]
+    ::msgcat::mcset sw BCE "KK"
+    ::msgcat::mcset sw CE "BK"
+}
diff --git a/library/msgs/ta.msg b/library/msgs/ta.msg
new file mode 100644
index 0000000..4abb90c
--- /dev/null
+++ b/library/msgs/ta.msg
@@ -0,0 +1,39 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset ta DAYS_OF_WEEK_FULL [list \
+        "\u0b9e\u0bbe\u0baf\u0bbf\u0bb1\u0bc1"\
+        "\u0ba4\u0bbf\u0b99\u0bcd\u0b95\u0bb3\u0bcd"\
+        "\u0b9a\u0bc6\u0bb5\u0bcd\u0bb5\u0bbe\u0baf\u0bcd"\
+        "\u0baa\u0bc1\u0ba4\u0ba9\u0bcd"\
+        "\u0bb5\u0bbf\u0baf\u0bbe\u0bb4\u0ba9\u0bcd"\
+        "\u0bb5\u0bc6\u0bb3\u0bcd\u0bb3\u0bbf"\
+        "\u0b9a\u0ba9\u0bbf"]
+    ::msgcat::mcset ta MONTHS_ABBREV [list \
+        "\u0b9c\u0ba9\u0bb5\u0bb0\u0bbf"\
+        "\u0baa\u0bc6\u0baa\u0bcd\u0bb0\u0bb5\u0bb0\u0bbf"\
+        "\u0bae\u0bbe\u0bb0\u0bcd\u0b9a\u0bcd"\
+        "\u0b8f\u0baa\u0bcd\u0bb0\u0bb2\u0bcd"\
+        "\u0bae\u0bc7"\
+        "\u0b9c\u0bc2\u0ba9\u0bcd"\
+        "\u0b9c\u0bc2\u0bb2\u0bc8"\
+        "\u0b86\u0b95\u0bb8\u0bcd\u0b9f\u0bcd"\
+        "\u0b9a\u0bc6\u0baa\u0bcd\u0b9f\u0bae\u0bcd\u0baa\u0bb0\u0bcd"\
+        "\u0b85\u0b95\u0bcd\u0b9f\u0bcb\u0baa\u0bb0\u0bcd"\
+        "\u0ba8\u0bb5\u0bae\u0bcd\u0baa\u0bb0\u0bcd"\
+        "\u0b9f\u0bbf\u0b9a\u0bae\u0bcd\u0baa\u0bb0\u0bcdr"]
+    ::msgcat::mcset ta MONTHS_FULL [list \
+        "\u0b9c\u0ba9\u0bb5\u0bb0\u0bbf"\
+        "\u0baa\u0bc6\u0baa\u0bcd\u0bb0\u0bb5\u0bb0\u0bbf"\
+        "\u0bae\u0bbe\u0bb0\u0bcd\u0b9a\u0bcd"\
+        "\u0b8f\u0baa\u0bcd\u0bb0\u0bb2\u0bcd"\
+        "\u0bae\u0bc7"\
+        "\u0b9c\u0bc2\u0ba9\u0bcd"\
+        "\u0b9c\u0bc2\u0bb2\u0bc8"\
+        "\u0b86\u0b95\u0bb8\u0bcd\u0b9f\u0bcd"\
+        "\u0b9a\u0bc6\u0baa\u0bcd\u0b9f\u0bae\u0bcd\u0baa\u0bb0\u0bcd"\
+        "\u0b85\u0b95\u0bcd\u0b9f\u0bcb\u0baa\u0bb0\u0bcd"\
+        "\u0ba8\u0bb5\u0bae\u0bcd\u0baa\u0bb0\u0bcd"\
+        "\u0b9f\u0bbf\u0b9a\u0bae\u0bcd\u0baa\u0bb0\u0bcdr"]
+    ::msgcat::mcset ta AM "\u0b95\u0bbf\u0bae\u0bc1"
+    ::msgcat::mcset ta PM "\u0b95\u0bbf\u0baa\u0bbf"
+}
diff --git a/library/msgs/ta_in.msg b/library/msgs/ta_in.msg
new file mode 100644
index 0000000..24590ac
--- /dev/null
+++ b/library/msgs/ta_in.msg
@@ -0,0 +1,6 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset ta_IN DATE_FORMAT "%d %M %Y"
+    ::msgcat::mcset ta_IN TIME_FORMAT_12 "%I:%M:%S %P"
+    ::msgcat::mcset ta_IN DATE_TIME_FORMAT "%d %M %Y %I:%M:%S %P %z"
+}
diff --git a/library/msgs/te.msg b/library/msgs/te.msg
new file mode 100644
index 0000000..6111473
--- /dev/null
+++ b/library/msgs/te.msg
@@ -0,0 +1,47 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset te DAYS_OF_WEEK_ABBREV [list \
+        "\u0c06\u0c26\u0c3f"\
+        "\u0c38\u0c4b\u0c2e"\
+        "\u0c2e\u0c02\u0c17\u0c33"\
+        "\u0c2c\u0c41\u0c27"\
+        "\u0c17\u0c41\u0c30\u0c41"\
+        "\u0c36\u0c41\u0c15\u0c4d\u0c30"\
+        "\u0c36\u0c28\u0c3f"]
+    ::msgcat::mcset te DAYS_OF_WEEK_FULL [list \
+        "\u0c06\u0c26\u0c3f\u0c35\u0c3e\u0c30\u0c02"\
+        "\u0c38\u0c4b\u0c2e\u0c35\u0c3e\u0c30\u0c02"\
+        "\u0c2e\u0c02\u0c17\u0c33\u0c35\u0c3e\u0c30\u0c02"\
+        "\u0c2c\u0c41\u0c27\u0c35\u0c3e\u0c30\u0c02"\
+        "\u0c17\u0c41\u0c30\u0c41\u0c35\u0c3e\u0c30\u0c02"\
+        "\u0c36\u0c41\u0c15\u0c4d\u0c30\u0c35\u0c3e\u0c30\u0c02"\
+        "\u0c36\u0c28\u0c3f\u0c35\u0c3e\u0c30\u0c02"]
+    ::msgcat::mcset te MONTHS_ABBREV [list \
+        "\u0c1c\u0c28\u0c35\u0c30\u0c3f"\
+        "\u0c2b\u0c3f\u0c2c\u0c4d\u0c30\u0c35\u0c30\u0c3f"\
+        "\u0c2e\u0c3e\u0c30\u0c4d\u0c1a\u0c3f"\
+        "\u0c0f\u0c2a\u0c4d\u0c30\u0c3f\u0c32\u0c4d"\
+        "\u0c2e\u0c47"\
+        "\u0c1c\u0c42\u0c28\u0c4d"\
+        "\u0c1c\u0c42\u0c32\u0c48"\
+        "\u0c06\u0c17\u0c38\u0c4d\u0c1f\u0c41"\
+        "\u0c38\u0c46\u0c2a\u0c4d\u0c1f\u0c46\u0c02\u0c2c\u0c30\u0c4d"\
+        "\u0c05\u0c15\u0c4d\u0c1f\u0c4b\u0c2c\u0c30\u0c4d"\
+        "\u0c28\u0c35\u0c02\u0c2c\u0c30\u0c4d"\
+        "\u0c21\u0c3f\u0c38\u0c46\u0c02\u0c2c\u0c30\u0c4d"\
+        ""]
+    ::msgcat::mcset te MONTHS_FULL [list \
+        "\u0c1c\u0c28\u0c35\u0c30\u0c3f"\
+        "\u0c2b\u0c3f\u0c2c\u0c4d\u0c30\u0c35\u0c30\u0c3f"\
+        "\u0c2e\u0c3e\u0c30\u0c4d\u0c1a\u0c3f"\
+        "\u0c0f\u0c2a\u0c4d\u0c30\u0c3f\u0c32\u0c4d"\
+        "\u0c2e\u0c47"\
+        "\u0c1c\u0c42\u0c28\u0c4d"\
+        "\u0c1c\u0c42\u0c32\u0c48"\
+        "\u0c06\u0c17\u0c38\u0c4d\u0c1f\u0c41"\
+        "\u0c38\u0c46\u0c2a\u0c4d\u0c1f\u0c46\u0c02\u0c2c\u0c30\u0c4d"\
+        "\u0c05\u0c15\u0c4d\u0c1f\u0c4b\u0c2c\u0c30\u0c4d"\
+        "\u0c28\u0c35\u0c02\u0c2c\u0c30\u0c4d"\
+        "\u0c21\u0c3f\u0c38\u0c46\u0c02\u0c2c\u0c30\u0c4d"\
+        ""]
+}
diff --git a/library/msgs/te_in.msg b/library/msgs/te_in.msg
new file mode 100644
index 0000000..61638b5
--- /dev/null
+++ b/library/msgs/te_in.msg
@@ -0,0 +1,8 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset te_IN AM "\u0c2a\u0c42\u0c30\u0c4d\u0c35\u0c3e\u0c39\u0c4d\u0c28"
+    ::msgcat::mcset te_IN PM "\u0c05\u0c2a\u0c30\u0c3e\u0c39\u0c4d\u0c28"
+    ::msgcat::mcset te_IN DATE_FORMAT "%d/%m/%Y"
+    ::msgcat::mcset te_IN TIME_FORMAT_12 "%I:%M:%S %P"
+    ::msgcat::mcset te_IN DATE_TIME_FORMAT "%d/%m/%Y %I:%M:%S %P %z"
+}
diff --git a/library/msgs/th.msg b/library/msgs/th.msg
new file mode 100644
index 0000000..7486c35
--- /dev/null
+++ b/library/msgs/th.msg
@@ -0,0 +1,54 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset th DAYS_OF_WEEK_ABBREV [list \
+        "\u0e2d\u0e32."\
+        "\u0e08."\
+        "\u0e2d."\
+        "\u0e1e."\
+        "\u0e1e\u0e24."\
+        "\u0e28."\
+        "\u0e2a."]
+    ::msgcat::mcset th DAYS_OF_WEEK_FULL [list \
+        "\u0e27\u0e31\u0e19\u0e2d\u0e32\u0e17\u0e34\u0e15\u0e22\u0e4c"\
+        "\u0e27\u0e31\u0e19\u0e08\u0e31\u0e19\u0e17\u0e23\u0e4c"\
+        "\u0e27\u0e31\u0e19\u0e2d\u0e31\u0e07\u0e04\u0e32\u0e23"\
+        "\u0e27\u0e31\u0e19\u0e1e\u0e38\u0e18"\
+        "\u0e27\u0e31\u0e19\u0e1e\u0e24\u0e2b\u0e31\u0e2a\u0e1a\u0e14\u0e35"\
+        "\u0e27\u0e31\u0e19\u0e28\u0e38\u0e01\u0e23\u0e4c"\
+        "\u0e27\u0e31\u0e19\u0e40\u0e2a\u0e32\u0e23\u0e4c"]
+    ::msgcat::mcset th MONTHS_ABBREV [list \
+        "\u0e21.\u0e04."\
+        "\u0e01.\u0e1e."\
+        "\u0e21\u0e35.\u0e04."\
+        "\u0e40\u0e21.\u0e22."\
+        "\u0e1e.\u0e04."\
+        "\u0e21\u0e34.\u0e22."\
+        "\u0e01.\u0e04."\
+        "\u0e2a.\u0e04."\
+        "\u0e01.\u0e22."\
+        "\u0e15.\u0e04."\
+        "\u0e1e.\u0e22."\
+        "\u0e18.\u0e04."\
+        ""]
+    ::msgcat::mcset th MONTHS_FULL [list \
+        "\u0e21\u0e01\u0e23\u0e32\u0e04\u0e21"\
+        "\u0e01\u0e38\u0e21\u0e20\u0e32\u0e1e\u0e31\u0e19\u0e18\u0e4c"\
+        "\u0e21\u0e35\u0e19\u0e32\u0e04\u0e21"\
+        "\u0e40\u0e21\u0e29\u0e32\u0e22\u0e19"\
+        "\u0e1e\u0e24\u0e29\u0e20\u0e32\u0e04\u0e21"\
+        "\u0e21\u0e34\u0e16\u0e38\u0e19\u0e32\u0e22\u0e19"\
+        "\u0e01\u0e23\u0e01\u0e0e\u0e32\u0e04\u0e21"\
+        "\u0e2a\u0e34\u0e07\u0e2b\u0e32\u0e04\u0e21"\
+        "\u0e01\u0e31\u0e19\u0e22\u0e32\u0e22\u0e19"\
+        "\u0e15\u0e38\u0e25\u0e32\u0e04\u0e21"\
+        "\u0e1e\u0e24\u0e28\u0e08\u0e34\u0e01\u0e32\u0e22\u0e19"\
+        "\u0e18\u0e31\u0e19\u0e27\u0e32\u0e04\u0e21"\
+        ""]
+    ::msgcat::mcset th BCE "\u0e25\u0e17\u0e35\u0e48"
+    ::msgcat::mcset th CE "\u0e04.\u0e28."
+    ::msgcat::mcset th AM "\u0e01\u0e48\u0e2d\u0e19\u0e40\u0e17\u0e35\u0e48\u0e22\u0e07"
+    ::msgcat::mcset th PM "\u0e2b\u0e25\u0e31\u0e07\u0e40\u0e17\u0e35\u0e48\u0e22\u0e07"
+    ::msgcat::mcset th DATE_FORMAT "%e/%m/%Y"
+    ::msgcat::mcset th TIME_FORMAT "%k:%M:%S"
+    ::msgcat::mcset th DATE_TIME_FORMAT "%e/%m/%Y %k:%M:%S %z"
+}
diff --git a/library/msgs/tr.msg b/library/msgs/tr.msg
new file mode 100644
index 0000000..7b2ecf9
--- /dev/null
+++ b/library/msgs/tr.msg
@@ -0,0 +1,50 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset tr DAYS_OF_WEEK_ABBREV [list \
+        "Paz"\
+        "Pzt"\
+        "Sal"\
+        "\u00c7ar"\
+        "Per"\
+        "Cum"\
+        "Cmt"]
+    ::msgcat::mcset tr DAYS_OF_WEEK_FULL [list \
+        "Pazar"\
+        "Pazartesi"\
+        "Sal\u0131"\
+        "\u00c7ar\u015famba"\
+        "Per\u015fembe"\
+        "Cuma"\
+        "Cumartesi"]
+    ::msgcat::mcset tr MONTHS_ABBREV [list \
+        "Oca"\
+        "\u015eub"\
+        "Mar"\
+        "Nis"\
+        "May"\
+        "Haz"\
+        "Tem"\
+        "A\u011fu"\
+        "Eyl"\
+        "Eki"\
+        "Kas"\
+        "Ara"\
+        ""]
+    ::msgcat::mcset tr MONTHS_FULL [list \
+        "Ocak"\
+        "\u015eubat"\
+        "Mart"\
+        "Nisan"\
+        "May\u0131s"\
+        "Haziran"\
+        "Temmuz"\
+        "A\u011fustos"\
+        "Eyl\u00fcl"\
+        "Ekim"\
+        "Kas\u0131m"\
+        "Aral\u0131k"\
+        ""]
+    ::msgcat::mcset tr DATE_FORMAT "%d.%m.%Y"
+    ::msgcat::mcset tr TIME_FORMAT "%H:%M:%S"
+    ::msgcat::mcset tr DATE_TIME_FORMAT "%d.%m.%Y %H:%M:%S %z"
+}
diff --git a/library/msgs/uk.msg b/library/msgs/uk.msg
new file mode 100644
index 0000000..7d4c64a
--- /dev/null
+++ b/library/msgs/uk.msg
@@ -0,0 +1,52 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset uk DAYS_OF_WEEK_ABBREV [list \
+        "\u043d\u0434"\
+        "\u043f\u043d"\
+        "\u0432\u0442"\
+        "\u0441\u0440"\
+        "\u0447\u0442"\
+        "\u043f\u0442"\
+        "\u0441\u0431"]
+    ::msgcat::mcset uk DAYS_OF_WEEK_FULL [list \
+        "\u043d\u0435\u0434\u0456\u043b\u044f"\
+        "\u043f\u043e\u043d\u0435\u0434\u0456\u043b\u043e\u043a"\
+        "\u0432\u0456\u0432\u0442\u043e\u0440\u043e\u043a"\
+        "\u0441\u0435\u0440\u0435\u0434\u0430"\
+        "\u0447\u0435\u0442\u0432\u0435\u0440"\
+        "\u043f'\u044f\u0442\u043d\u0438\u0446\u044f"\
+        "\u0441\u0443\u0431\u043e\u0442\u0430"]
+    ::msgcat::mcset uk MONTHS_ABBREV [list \
+        "\u0441\u0456\u0447"\
+        "\u043b\u044e\u0442"\
+        "\u0431\u0435\u0440"\
+        "\u043a\u0432\u0456\u0442"\
+        "\u0442\u0440\u0430\u0432"\
+        "\u0447\u0435\u0440\u0432"\
+        "\u043b\u0438\u043f"\
+        "\u0441\u0435\u0440\u043f"\
+        "\u0432\u0435\u0440"\
+        "\u0436\u043e\u0432\u0442"\
+        "\u043b\u0438\u0441\u0442"\
+        "\u0433\u0440\u0443\u0434"\
+        ""]
+    ::msgcat::mcset uk MONTHS_FULL [list \
+        "\u0441\u0456\u0447\u043d\u044f"\
+        "\u043b\u044e\u0442\u043e\u0433\u043e"\
+        "\u0431\u0435\u0440\u0435\u0437\u043d\u044f"\
+        "\u043a\u0432\u0456\u0442\u043d\u044f"\
+        "\u0442\u0440\u0430\u0432\u043d\u044f"\
+        "\u0447\u0435\u0440\u0432\u043d\u044f"\
+        "\u043b\u0438\u043f\u043d\u044f"\
+        "\u0441\u0435\u0440\u043f\u043d\u044f"\
+        "\u0432\u0435\u0440\u0435\u0441\u043d\u044f"\
+        "\u0436\u043e\u0432\u0442\u043d\u044f"\
+        "\u043b\u0438\u0441\u0442\u043e\u043f\u0430\u0434\u0430"\
+        "\u0433\u0440\u0443\u0434\u043d\u044f"\
+        ""]
+    ::msgcat::mcset uk BCE "\u0434\u043e \u043d.\u0435."
+    ::msgcat::mcset uk CE "\u043f\u0456\u0441\u043b\u044f \u043d.\u0435."
+    ::msgcat::mcset uk DATE_FORMAT "%e/%m/%Y"
+    ::msgcat::mcset uk TIME_FORMAT "%k:%M:%S"
+    ::msgcat::mcset uk DATE_TIME_FORMAT "%e/%m/%Y %k:%M:%S %z"
+}
diff --git a/library/msgs/vi.msg b/library/msgs/vi.msg
new file mode 100644
index 0000000..c98b2a6
--- /dev/null
+++ b/library/msgs/vi.msg
@@ -0,0 +1,50 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset vi DAYS_OF_WEEK_ABBREV [list \
+        "Th 2"\
+        "Th 3"\
+        "Th 4"\
+        "Th 5"\
+        "Th 6"\
+        "Th 7"\
+        "CN"]
+    ::msgcat::mcset vi DAYS_OF_WEEK_FULL [list \
+        "Th\u01b0\u0301 hai"\
+        "Th\u01b0\u0301 ba"\
+        "Th\u01b0\u0301 t\u01b0"\
+        "Th\u01b0\u0301 n\u0103m"\
+        "Th\u01b0\u0301 s\u00e1u"\
+        "Th\u01b0\u0301 ba\u0309y"\
+        "Chu\u0309 nh\u00e2\u0323t"]
+    ::msgcat::mcset vi MONTHS_ABBREV [list \
+        "Thg 1"\
+        "Thg 2"\
+        "Thg 3"\
+        "Thg 4"\
+        "Thg 5"\
+        "Thg 6"\
+        "Thg 7"\
+        "Thg 8"\
+        "Thg 9"\
+        "Thg 10"\
+        "Thg 11"\
+        "Thg 12"\
+        ""]
+    ::msgcat::mcset vi MONTHS_FULL [list \
+        "Th\u00e1ng m\u00f4\u0323t"\
+        "Th\u00e1ng hai"\
+        "Th\u00e1ng ba"\
+        "Th\u00e1ng t\u01b0"\
+        "Th\u00e1ng n\u0103m"\
+        "Th\u00e1ng s\u00e1u"\
+        "Th\u00e1ng ba\u0309y"\
+        "Th\u00e1ng t\u00e1m"\
+        "Th\u00e1ng ch\u00edn"\
+        "Th\u00e1ng m\u01b0\u01a1\u0300i"\
+        "Th\u00e1ng m\u01b0\u01a1\u0300i m\u00f4\u0323t"\
+        "Th\u00e1ng m\u01b0\u01a1\u0300i hai"\
+        ""]
+    ::msgcat::mcset vi DATE_FORMAT "%d %b %Y"
+    ::msgcat::mcset vi TIME_FORMAT "%H:%M:%S"
+    ::msgcat::mcset vi DATE_TIME_FORMAT "%d %b %Y %H:%M:%S %z"
+}
diff --git a/library/msgs/zh.msg b/library/msgs/zh.msg
new file mode 100644
index 0000000..b799a32
--- /dev/null
+++ b/library/msgs/zh.msg
@@ -0,0 +1,55 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset zh DAYS_OF_WEEK_ABBREV [list \
+        "\u661f\u671f\u65e5"\
+        "\u661f\u671f\u4e00"\
+        "\u661f\u671f\u4e8c"\
+        "\u661f\u671f\u4e09"\
+        "\u661f\u671f\u56db"\
+        "\u661f\u671f\u4e94"\
+        "\u661f\u671f\u516d"]
+    ::msgcat::mcset zh DAYS_OF_WEEK_FULL [list \
+        "\u661f\u671f\u65e5"\
+        "\u661f\u671f\u4e00"\
+        "\u661f\u671f\u4e8c"\
+        "\u661f\u671f\u4e09"\
+        "\u661f\u671f\u56db"\
+        "\u661f\u671f\u4e94"\
+        "\u661f\u671f\u516d"]
+    ::msgcat::mcset zh MONTHS_ABBREV [list \
+        "\u4e00\u6708"\
+        "\u4e8c\u6708"\
+        "\u4e09\u6708"\
+        "\u56db\u6708"\
+        "\u4e94\u6708"\
+        "\u516d\u6708"\
+        "\u4e03\u6708"\
+        "\u516b\u6708"\
+        "\u4e5d\u6708"\
+        "\u5341\u6708"\
+        "\u5341\u4e00\u6708"\
+        "\u5341\u4e8c\u6708"\
+        ""]
+    ::msgcat::mcset zh MONTHS_FULL [list \
+        "\u4e00\u6708"\
+        "\u4e8c\u6708"\
+        "\u4e09\u6708"\
+        "\u56db\u6708"\
+        "\u4e94\u6708"\
+        "\u516d\u6708"\
+        "\u4e03\u6708"\
+        "\u516b\u6708"\
+        "\u4e5d\u6708"\
+        "\u5341\u6708"\
+        "\u5341\u4e00\u6708"\
+        "\u5341\u4e8c\u6708"\
+        ""]
+    ::msgcat::mcset zh BCE "\u516c\u5143\u524d"
+    ::msgcat::mcset zh CE "\u516c\u5143"
+    ::msgcat::mcset zh AM "\u4e0a\u5348"
+    ::msgcat::mcset zh PM "\u4e0b\u5348"
+    ::msgcat::mcset zh LOCALE_NUMERALS "\u3007 \u4e00 \u4e8c \u4e09 \u56db \u4e94 \u516d \u4e03 \u516b \u4e5d \u5341 \u5341\u4e00 \u5341\u4e8c \u5341\u4e09 \u5341\u56db \u5341\u4e94 \u5341\u516d \u5341\u4e03 \u5341\u516b \u5341\u4e5d \u4e8c\u5341 \u5eff\u4e00 \u5eff\u4e8c \u5eff\u4e09 \u5eff\u56db \u5eff\u4e94 \u5eff\u516d \u5eff\u4e03 \u5eff\u516b \u5eff\u4e5d \u4e09\u5341 \u5345\u4e00 \u5345\u4e8c \u5345\u4e09 \u5345\u56db \u5345\u4e94 \u5345\u516d \u5345\u4e03 \u5345\u516b \u5345\u4e5d \u56db\u5341 \u56db\u5341\u4e00 \u56db\u5341\u4e8c \u56db\u5341\u4e09 \u56db\u5341\u56db \u56db\u5341\u4e94 \u56db\u5341\u516d \u56db\u5341\u4e03 \u56db\u5341\u516b \u56db\u5341\u4e5d \u4e94\u5341 \u4e94\u5341\u4e00 \u4e94\u5341\u4e8c \u4e94\u5341\u4e09 \u4e94\u5341\u56db \u4e94\u5341\u4e94 \u4e94\u5341\u516d \u4e94\u5341\u4e03 \u4e94\u5341\u516b \u4e94\u5341\u4e5d \u516d\u5341 \u516d\u5341\u4e00 \u516d\u5341\u4e8c \u516d\u5341\u4e09 \u516d\u5341\u56db \u516d\u5341\u4e94 \u516d\u5341\u516d \u516d\u5341\u4e03 \u516d\u5341\u516b \u516d\u5341\u4e5d \u4e03\u5341 \u4e03\u5341\u4e00 \u4e03\u5341\u4e8c \u4e03\u5341\u4e09 \u4e03\u5341\u56db \u4e03\u5341\u4e94 \u4e03\u5341\u516d \u4e03\u5341\u4e03 \u4e03\u5341\u516b \u4e03\u5341\u4e5d \u516b\u5341 \u516b\u5341\u4e00 \u516b\u5341\u4e8c \u516b\u5341\u4e09 \u516b\u5341\u56db \u516b\u5341\u4e94 \u516b\u5341\u516d \u516b\u5341\u4e03 \u516b\u5341\u516b \u516b\u5341\u4e5d \u4e5d\u5341 \u4e5d\u5341\u4e00 \u4e5d\u5341\u4e8c \u4e5d\u5341\u4e09 \u4e5d\u5341\u56db \u4e5d\u5341\u4e94 \u4e5d\u5341\u516d \u4e5d\u5341\u4e03 \u4e5d\u5341\u516b \u4e5d\u5341\u4e5d"
+    ::msgcat::mcset zh LOCALE_DATE_FORMAT "\u516c\u5143%Y\u5e74%B%Od\u65e5"
+    ::msgcat::mcset zh LOCALE_TIME_FORMAT "%OH\u65f6%OM\u5206%OS\u79d2"
+    ::msgcat::mcset zh LOCALE_DATE_TIME_FORMAT "%A %Y\u5e74%B%Od\u65e5%OH\u65f6%OM\u5206%OS\u79d2 %z"
+}
diff --git a/library/msgs/zh_cn.msg b/library/msgs/zh_cn.msg
new file mode 100644
index 0000000..d62ce77
--- /dev/null
+++ b/library/msgs/zh_cn.msg
@@ -0,0 +1,7 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset zh_CN DATE_FORMAT "%Y-%m-%e"
+    ::msgcat::mcset zh_CN TIME_FORMAT "%k:%M:%S"
+    ::msgcat::mcset zh_CN TIME_FORMAT_12 "%P%I\u65f6%M\u5206%S\u79d2"
+    ::msgcat::mcset zh_CN DATE_TIME_FORMAT "%Y-%m-%e %k:%M:%S %z"
+}
diff --git a/library/msgs/zh_hk.msg b/library/msgs/zh_hk.msg
new file mode 100644
index 0000000..badb1dd
--- /dev/null
+++ b/library/msgs/zh_hk.msg
@@ -0,0 +1,28 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset zh_HK DAYS_OF_WEEK_ABBREV [list \
+        "\u65e5"\
+        "\u4e00"\
+        "\u4e8c"\
+        "\u4e09"\
+        "\u56db"\
+        "\u4e94"\
+        "\u516d"]
+    ::msgcat::mcset zh_HK MONTHS_ABBREV [list \
+        "1\u6708"\
+        "2\u6708"\
+        "3\u6708"\
+        "4\u6708"\
+        "5\u6708"\
+        "6\u6708"\
+        "7\u6708"\
+        "8\u6708"\
+        "9\u6708"\
+        "10\u6708"\
+        "11\u6708"\
+        "12\u6708"\
+        ""]
+    ::msgcat::mcset zh_HK DATE_FORMAT "%Y\u5e74%m\u6708%e\u65e5"
+    ::msgcat::mcset zh_HK TIME_FORMAT_12 "%P%I:%M:%S"
+    ::msgcat::mcset zh_HK DATE_TIME_FORMAT "%Y\u5e74%m\u6708%e\u65e5 %P%I:%M:%S %z"
+}
diff --git a/library/msgs/zh_sg.msg b/library/msgs/zh_sg.msg
new file mode 100644
index 0000000..a2f3e39
--- /dev/null
+++ b/library/msgs/zh_sg.msg
@@ -0,0 +1,8 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset zh_SG AM "\u4e0a\u5348"
+    ::msgcat::mcset zh_SG PM "\u4e2d\u5348"
+    ::msgcat::mcset zh_SG DATE_FORMAT "%d %B %Y"
+    ::msgcat::mcset zh_SG TIME_FORMAT_12 "%P %I:%M:%S"
+    ::msgcat::mcset zh_SG DATE_TIME_FORMAT "%d %B %Y %P %I:%M:%S %z"
+}
diff --git a/library/msgs/zh_tw.msg b/library/msgs/zh_tw.msg
new file mode 100644
index 0000000..e0796b1
--- /dev/null
+++ b/library/msgs/zh_tw.msg
@@ -0,0 +1,8 @@
+# created by tools/loadICU.tcl -- do not edit
+namespace eval ::tcl::clock {
+    ::msgcat::mcset zh_TW BCE "\u6c11\u570b\u524d"
+    ::msgcat::mcset zh_TW CE "\u6c11\u570b"
+    ::msgcat::mcset zh_TW DATE_FORMAT "%Y/%m/%e"
+    ::msgcat::mcset zh_TW TIME_FORMAT_12 "%P %I:%M:%S"
+    ::msgcat::mcset zh_TW DATE_TIME_FORMAT "%Y/%m/%e %P %I:%M:%S %z"
+}
diff --git a/library/opt/optparse.tcl b/library/opt/optparse.tcl
new file mode 100644
index 0000000..869a2b6
--- /dev/null
+++ b/library/opt/optparse.tcl
@@ -0,0 +1,1072 @@
+# optparse.tcl --
+#
+#       (private) Option parsing package
+#       Primarily used internally by the safe:: code.
+#
+#	WARNING: This code will go away in a future release
+#	of Tcl.  It is NOT supported and you should not rely
+#	on it.  If your code does rely on this package you
+#	may directly incorporate this code into your application.
+
+package require Tcl 8.2
+# When this version number changes, update the pkgIndex.tcl file
+# and the install directory in the Makefiles.
+package provide opt 0.4.6
+
+namespace eval ::tcl {
+
+    # Exported APIs
+    namespace export OptKeyRegister OptKeyDelete OptKeyError OptKeyParse \
+             OptProc OptProcArgGiven OptParse \
+	     Lempty Lget \
+             Lassign Lvarpop Lvarpop1 Lvarset Lvarincr \
+             SetMax SetMin
+
+
+#################  Example of use / 'user documentation'  ###################
+
+    proc OptCreateTestProc {} {
+
+	# Defines ::tcl::OptParseTest as a test proc with parsed arguments
+	# (can't be defined before the code below is loaded (before "OptProc"))
+
+	# Every OptProc give usage information on "procname -help".
+	# Try "tcl::OptParseTest -help" and "tcl::OptParseTest -a" and
+	# then other arguments.
+	#
+	# example of 'valid' call:
+	# ::tcl::OptParseTest save -4 -pr 23 -libsok SybTcl\
+	#		-nostatics false ch1
+	OptProc OptParseTest {
+            {subcommand -choice {save print} "sub command"}
+            {arg1 3 "some number"}
+            {-aflag}
+            {-intflag      7}
+            {-weirdflag                    "help string"}
+            {-noStatics                    "Not ok to load static packages"}
+            {-nestedloading1 true           "OK to load into nested slaves"}
+            {-nestedloading2 -boolean true "OK to load into nested slaves"}
+            {-libsOK        -choice {Tk SybTcl}
+		                      "List of packages that can be loaded"}
+            {-precision     -int 12        "Number of digits of precision"}
+            {-intval        7               "An integer"}
+            {-scale         -float 1.0     "Scale factor"}
+            {-zoom          1.0             "Zoom factor"}
+            {-arbitrary     foobar          "Arbitrary string"}
+            {-random        -string 12   "Random string"}
+            {-listval       -list {}       "List value"}
+            {-blahflag       -blah abc       "Funny type"}
+	    {arg2 -boolean "a boolean"}
+	    {arg3 -choice "ch1 ch2"}
+	    {?optarg? -list {} "optional argument"}
+        } {
+	    foreach v [info locals] {
+		puts stderr [format "%14s : %s" $v [set $v]]
+	    }
+	}
+    }
+
+###################  No User serviceable part below ! ###############
+
+    # Array storing the parsed descriptions
+    variable OptDesc
+    array set OptDesc {}
+    # Next potentially free key id (numeric)
+    variable OptDescN 0
+
+# Inside algorithm/mechanism description:
+# (not for the faint hearted ;-)
+#
+# The argument description is parsed into a "program tree"
+# It is called a "program" because it is the program used by
+# the state machine interpreter that use that program to
+# actually parse the arguments at run time.
+#
+# The general structure of a "program" is
+# notation (pseudo bnf like)
+#    name :== definition        defines "name" as being "definition"
+#    { x y z }                  means list of x, y, and z
+#    x*                         means x repeated 0 or more time
+#    x+                         means "x x*"
+#    x?                         means optionally x
+#    x | y                      means x or y
+#    "cccc"                     means the literal string
+#
+#    program        :== { programCounter programStep* }
+#
+#    programStep    :== program | singleStep
+#
+#    programCounter :== {"P" integer+ }
+#
+#    singleStep     :== { instruction parameters* }
+#
+#    instruction    :== single element list
+#
+# (the difference between singleStep and program is that \
+#   llength [lindex $program 0] >= 2
+# while
+#   llength [lindex $singleStep 0] == 1
+# )
+#
+# And for this application:
+#
+#    singleStep     :== { instruction varname {hasBeenSet currentValue} type
+#                         typeArgs help }
+#    instruction    :== "flags" | "value"
+#    type           :== knowType | anyword
+#    knowType       :== "string" | "int" | "boolean" | "boolflag" | "float"
+#                       | "choice"
+#
+# for type "choice" typeArgs is a list of possible choices, the first one
+# is the default value. for all other types the typeArgs is the default value
+#
+# a "boolflag" is the type for a flag whose presence or absence, without
+# additional arguments means respectively true or false (default flag type).
+#
+# programCounter is the index in the list of the currently processed
+# programStep (thus starting at 1 (0 is {"P" prgCounterValue}).
+# If it is a list it points toward each currently selected programStep.
+# (like for "flags", as they are optional, form a set and programStep).
+
+# Performance/Implementation issues
+# ---------------------------------
+# We use tcl lists instead of arrays because with tcl8.0
+# they should start to be much faster.
+# But this code use a lot of helper procs (like Lvarset)
+# which are quite slow and would be helpfully optimized
+# for instance by being written in C. Also our struture
+# is complex and there is maybe some places where the
+# string rep might be calculated at great exense. to be checked.
+
+#
+# Parse a given description and saves it here under the given key
+# generate a unused keyid if not given
+#
+proc ::tcl::OptKeyRegister {desc {key ""}} {
+    variable OptDesc
+    variable OptDescN
+    if {[string equal $key ""]} {
+        # in case a key given to us as a parameter was a number
+        while {[info exists OptDesc($OptDescN)]} {incr OptDescN}
+        set key $OptDescN
+        incr OptDescN
+    }
+    # program counter
+    set program [list [list "P" 1]]
+
+    # are we processing flags (which makes a single program step)
+    set inflags 0
+
+    set state {}
+
+    # flag used to detect that we just have a single (flags set) subprogram.
+    set empty 1
+
+    foreach item $desc {
+	if {$state == "args"} {
+	    # more items after 'args'...
+	    return -code error "'args' special argument must be the last one"
+	}
+        set res [OptNormalizeOne $item]
+        set state [lindex $res 0]
+        if {$inflags} {
+            if {$state == "flags"} {
+		# add to 'subprogram'
+                lappend flagsprg $res
+            } else {
+                # put in the flags
+                # structure for flag programs items is a list of
+                # {subprgcounter {prg flag 1} {prg flag 2} {...}}
+                lappend program $flagsprg
+                # put the other regular stuff
+                lappend program $res
+		set inflags 0
+		set empty 0
+            }
+        } else {
+           if {$state == "flags"} {
+               set inflags 1
+               # sub program counter + first sub program
+               set flagsprg [list [list "P" 1] $res]
+           } else {
+               lappend program $res
+               set empty 0
+           }
+       }
+   }
+   if {$inflags} {
+       if {$empty} {
+	   # We just have the subprogram, optimize and remove
+	   # unneeded level:
+	   set program $flagsprg
+       } else {
+	   lappend program $flagsprg
+       }
+   }
+
+   set OptDesc($key) $program
+
+   return $key
+}
+
+#
+# Free the storage for that given key
+#
+proc ::tcl::OptKeyDelete {key} {
+    variable OptDesc
+    unset OptDesc($key)
+}
+
+    # Get the parsed description stored under the given key.
+    proc OptKeyGetDesc {descKey} {
+        variable OptDesc
+        if {![info exists OptDesc($descKey)]} {
+            return -code error "Unknown option description key \"$descKey\""
+        }
+        set OptDesc($descKey)
+    }
+
+# Parse entry point for ppl who don't want to register with a key,
+# for instance because the description changes dynamically.
+#  (otherwise one should really use OptKeyRegister once + OptKeyParse
+#   as it is way faster or simply OptProc which does it all)
+# Assign a temporary key, call OptKeyParse and then free the storage
+proc ::tcl::OptParse {desc arglist} {
+    set tempkey [OptKeyRegister $desc]
+    set ret [catch {uplevel 1 [list ::tcl::OptKeyParse $tempkey $arglist]} res]
+    OptKeyDelete $tempkey
+    return -code $ret $res
+}
+
+# Helper function, replacement for proc that both
+# register the description under a key which is the name of the proc
+# (and thus unique to that code)
+# and add a first line to the code to call the OptKeyParse proc
+# Stores the list of variables that have been actually given by the user
+# (the other will be sets to their default value)
+# into local variable named "Args".
+proc ::tcl::OptProc {name desc body} {
+    set namespace [uplevel 1 [list ::namespace current]]
+    if {[string match "::*" $name] || [string equal $namespace "::"]} {
+        # absolute name or global namespace, name is the key
+        set key $name
+    } else {
+        # we are relative to some non top level namespace:
+        set key "${namespace}::${name}"
+    }
+    OptKeyRegister $desc $key
+    uplevel 1 [list ::proc $name args "set Args \[::tcl::OptKeyParse $key \$args\]\n$body"]
+    return $key
+}
+# Check that a argument has been given
+# assumes that "OptProc" has been used as it will check in "Args" list
+proc ::tcl::OptProcArgGiven {argname} {
+    upvar Args alist
+    expr {[lsearch $alist $argname] >=0}
+}
+
+    #######
+    # Programs/Descriptions manipulation
+
+    # Return the instruction word/list of a given step/(sub)program
+    proc OptInstr {lst} {
+	lindex $lst 0
+    }
+    # Is a (sub) program or a plain instruction ?
+    proc OptIsPrg {lst} {
+	expr {[llength [OptInstr $lst]]>=2}
+    }
+    # Is this instruction a program counter or a real instr
+    proc OptIsCounter {item} {
+	expr {[lindex $item 0]=="P"}
+    }
+    # Current program counter (2nd word of first word)
+    proc OptGetPrgCounter {lst} {
+	Lget $lst {0 1}
+    }
+    # Current program counter (2nd word of first word)
+    proc OptSetPrgCounter {lstName newValue} {
+	upvar $lstName lst
+	set lst [lreplace $lst 0 0 [concat "P" $newValue]]
+    }
+    # returns a list of currently selected items.
+    proc OptSelection {lst} {
+	set res {}
+	foreach idx [lrange [lindex $lst 0] 1 end] {
+	    lappend res [Lget $lst $idx]
+	}
+	return $res
+    }
+
+    # Advance to next description
+    proc OptNextDesc {descName} {
+        uplevel 1 [list Lvarincr $descName {0 1}]
+    }
+
+    # Get the current description, eventually descend
+    proc OptCurDesc {descriptions} {
+        lindex $descriptions [OptGetPrgCounter $descriptions]
+    }
+    # get the current description, eventually descend
+    # through sub programs as needed.
+    proc OptCurDescFinal {descriptions} {
+        set item [OptCurDesc $descriptions]
+	# Descend untill we get the actual item and not a sub program
+        while {[OptIsPrg $item]} {
+            set item [OptCurDesc $item]
+        }
+	return $item
+    }
+    # Current final instruction adress
+    proc OptCurAddr {descriptions {start {}}} {
+	set adress [OptGetPrgCounter $descriptions]
+	lappend start $adress
+	set item [lindex $descriptions $adress]
+	if {[OptIsPrg $item]} {
+	    return [OptCurAddr $item $start]
+	} else {
+	    return $start
+	}
+    }
+    # Set the value field of the current instruction
+    proc OptCurSetValue {descriptionsName value} {
+	upvar $descriptionsName descriptions
+	# get the current item full adress
+        set adress [OptCurAddr $descriptions]
+	# use the 3th field of the item  (see OptValue / OptNewInst)
+	lappend adress 2
+	Lvarset descriptions $adress [list 1 $value]
+	#                                  ^hasBeenSet flag
+    }
+
+    # empty state means done/paste the end of the program
+    proc OptState {item} {
+        lindex $item 0
+    }
+
+    # current state
+    proc OptCurState {descriptions} {
+        OptState [OptCurDesc $descriptions]
+    }
+
+    #######
+    # Arguments manipulation
+
+    # Returns the argument that has to be processed now
+    proc OptCurrentArg {lst} {
+        lindex $lst 0
+    }
+    # Advance to next argument
+    proc OptNextArg {argsName} {
+        uplevel 1 [list Lvarpop1 $argsName]
+    }
+    #######
+
+
+
+
+
+    # Loop over all descriptions, calling OptDoOne which will
+    # eventually eat all the arguments.
+    proc OptDoAll {descriptionsName argumentsName} {
+	upvar $descriptionsName descriptions
+	upvar $argumentsName arguments
+#	puts "entered DoAll"
+	# Nb: the places where "state" can be set are tricky to figure
+	#     because DoOne sets the state to flagsValue and return -continue
+	#     when needed...
+	set state [OptCurState $descriptions]
+	# We'll exit the loop in "OptDoOne" or when state is empty.
+        while 1 {
+	    set curitem [OptCurDesc $descriptions]
+	    # Do subprograms if needed, call ourselves on the sub branch
+	    while {[OptIsPrg $curitem]} {
+		OptDoAll curitem arguments
+#		puts "done DoAll sub"
+		# Insert back the results in current tree
+		Lvarset1nc descriptions [OptGetPrgCounter $descriptions]\
+			$curitem
+		OptNextDesc descriptions
+		set curitem [OptCurDesc $descriptions]
+                set state [OptCurState $descriptions]
+	    }
+#           puts "state = \"$state\" - arguments=($arguments)"
+	    if {[Lempty $state]} {
+		# Nothing left to do, we are done in this branch:
+		break
+	    }
+	    # The following statement can make us terminate/continue
+	    # as it use return -code {break, continue, return and error}
+	    # codes
+            OptDoOne descriptions state arguments
+	    # If we are here, no special return code where issued,
+	    # we'll step to next instruction :
+#           puts "new state  = \"$state\""
+	    OptNextDesc descriptions
+	    set state [OptCurState $descriptions]
+        }
+    }
+
+    # Process one step for the state machine,
+    # eventually consuming the current argument.
+    proc OptDoOne {descriptionsName stateName argumentsName} {
+        upvar $argumentsName arguments
+        upvar $descriptionsName descriptions
+	upvar $stateName state
+
+	# the special state/instruction "args" eats all
+	# the remaining args (if any)
+	if {($state == "args")} {
+	    if {![Lempty $arguments]} {
+		# If there is no additional arguments, leave the default value
+		# in.
+		OptCurSetValue descriptions $arguments
+		set arguments {}
+	    }
+#            puts "breaking out ('args' state: consuming every reminding args)"
+	    return -code break
+	}
+
+	if {[Lempty $arguments]} {
+	    if {$state == "flags"} {
+		# no argument and no flags : we're done
+#                puts "returning to previous (sub)prg (no more args)"
+		return -code return
+	    } elseif {$state == "optValue"} {
+		set state next; # not used, for debug only
+		# go to next state
+		return
+	    } else {
+		return -code error [OptMissingValue $descriptions]
+	    }
+	} else {
+	    set arg [OptCurrentArg $arguments]
+	}
+
+        switch $state {
+            flags {
+                # A non-dash argument terminates the options, as does --
+
+                # Still a flag ?
+                if {![OptIsFlag $arg]} {
+                    # don't consume the argument, return to previous prg
+                    return -code return
+                }
+                # consume the flag
+                OptNextArg arguments
+                if {[string equal "--" $arg]} {
+                    # return from 'flags' state
+                    return -code return
+                }
+
+                set hits [OptHits descriptions $arg]
+                if {$hits > 1} {
+                    return -code error [OptAmbigous $descriptions $arg]
+                } elseif {$hits == 0} {
+                    return -code error [OptFlagUsage $descriptions $arg]
+                }
+		set item [OptCurDesc $descriptions]
+                if {[OptNeedValue $item]} {
+		    # we need a value, next state is
+		    set state flagValue
+                } else {
+                    OptCurSetValue descriptions 1
+                }
+		# continue
+		return -code continue
+            }
+	    flagValue -
+	    value {
+		set item [OptCurDesc $descriptions]
+                # Test the values against their required type
+		if {[catch {OptCheckType $arg\
+			[OptType $item] [OptTypeArgs $item]} val]} {
+		    return -code error [OptBadValue $item $arg $val]
+		}
+                # consume the value
+                OptNextArg arguments
+		# set the value
+		OptCurSetValue descriptions $val
+		# go to next state
+		if {$state == "flagValue"} {
+		    set state flags
+		    return -code continue
+		} else {
+		    set state next; # not used, for debug only
+		    return ; # will go on next step
+		}
+	    }
+	    optValue {
+		set item [OptCurDesc $descriptions]
+                # Test the values against their required type
+		if {![catch {OptCheckType $arg\
+			[OptType $item] [OptTypeArgs $item]} val]} {
+		    # right type, so :
+		    # consume the value
+		    OptNextArg arguments
+		    # set the value
+		    OptCurSetValue descriptions $val
+		}
+		# go to next state
+		set state next; # not used, for debug only
+		return ; # will go on next step
+	    }
+        }
+	# If we reach this point: an unknown
+	# state as been entered !
+	return -code error "Bug! unknown state in DoOne \"$state\"\
+		(prg counter [OptGetPrgCounter $descriptions]:\
+			[OptCurDesc $descriptions])"
+    }
+
+# Parse the options given the key to previously registered description
+# and arguments list
+proc ::tcl::OptKeyParse {descKey arglist} {
+
+    set desc [OptKeyGetDesc $descKey]
+
+    # make sure -help always give usage
+    if {[string equal -nocase "-help" $arglist]} {
+	return -code error [OptError "Usage information:" $desc 1]
+    }
+
+    OptDoAll desc arglist
+
+    if {![Lempty $arglist]} {
+	return -code error [OptTooManyArgs $desc $arglist]
+    }
+
+    # Analyse the result
+    # Walk through the tree:
+    OptTreeVars $desc "#[expr {[info level]-1}]"
+}
+
+    # determine string length for nice tabulated output
+    proc OptTreeVars {desc level {vnamesLst {}}} {
+	foreach item $desc {
+	    if {[OptIsCounter $item]} continue
+	    if {[OptIsPrg $item]} {
+		set vnamesLst [OptTreeVars $item $level $vnamesLst]
+	    } else {
+		set vname [OptVarName $item]
+		upvar $level $vname var
+		if {[OptHasBeenSet $item]} {
+#		    puts "adding $vname"
+		    # lets use the input name for the returned list
+		    # it is more usefull, for instance you can check that
+		    # no flags at all was given with expr
+		    # {![string match "*-*" $Args]}
+		    lappend vnamesLst [OptName $item]
+		    set var [OptValue $item]
+		} else {
+		    set var [OptDefaultValue $item]
+		}
+	    }
+	}
+	return $vnamesLst
+    }
+
+
+# Check the type of a value
+# and emit an error if arg is not of the correct type
+# otherwise returns the canonical value of that arg (ie 0/1 for booleans)
+proc ::tcl::OptCheckType {arg type {typeArgs ""}} {
+#    puts "checking '$arg' against '$type' ($typeArgs)"
+
+    # only types "any", "choice", and numbers can have leading "-"
+
+    switch -exact -- $type {
+        int {
+            if {![string is integer -strict $arg]} {
+                error "not an integer"
+            }
+	    return $arg
+        }
+        float {
+            return [expr {double($arg)}]
+        }
+	script -
+        list {
+	    # if llength fail : malformed list
+            if {[llength $arg]==0 && [OptIsFlag $arg]} {
+		error "no values with leading -"
+	    }
+	    return $arg
+        }
+        boolean {
+	    if {![string is boolean -strict $arg]} {
+		error "non canonic boolean"
+            }
+	    # convert true/false because expr/if is broken with "!,...
+	    return [expr {$arg ? 1 : 0}]
+        }
+        choice {
+            if {[lsearch -exact $typeArgs $arg] < 0} {
+                error "invalid choice"
+            }
+	    return $arg
+        }
+	any {
+	    return $arg
+	}
+	string -
+	default {
+            if {[OptIsFlag $arg]} {
+                error "no values with leading -"
+            }
+	    return $arg
+        }
+    }
+    return neverReached
+}
+
+    # internal utilities
+
+    # returns the number of flags matching the given arg
+    # sets the (local) prg counter to the list of matches
+    proc OptHits {descName arg} {
+        upvar $descName desc
+        set hits 0
+        set hitems {}
+	set i 1
+
+	set larg [string tolower $arg]
+	set len  [string length $larg]
+	set last [expr {$len-1}]
+
+        foreach item [lrange $desc 1 end] {
+            set flag [OptName $item]
+	    # lets try to match case insensitively
+	    # (string length ought to be cheap)
+	    set lflag [string tolower $flag]
+	    if {$len == [string length $lflag]} {
+		if {[string equal $larg $lflag]} {
+		    # Exact match case
+		    OptSetPrgCounter desc $i
+		    return 1
+		}
+	    } elseif {[string equal $larg [string range $lflag 0 $last]]} {
+		lappend hitems $i
+		incr hits
+            }
+	    incr i
+        }
+	if {$hits} {
+	    OptSetPrgCounter desc $hitems
+	}
+        return $hits
+    }
+
+    # Extract fields from the list structure:
+
+    proc OptName {item} {
+        lindex $item 1
+    }
+    proc OptHasBeenSet {item} {
+	Lget $item {2 0}
+    }
+    proc OptValue {item} {
+	Lget $item {2 1}
+    }
+
+    proc OptIsFlag {name} {
+        string match "-*" $name
+    }
+    proc OptIsOpt {name} {
+        string match {\?*} $name
+    }
+    proc OptVarName {item} {
+        set name [OptName $item]
+        if {[OptIsFlag $name]} {
+            return [string range $name 1 end]
+        } elseif {[OptIsOpt $name]} {
+	    return [string trim $name "?"]
+	} else {
+            return $name
+        }
+    }
+    proc OptType {item} {
+        lindex $item 3
+    }
+    proc OptTypeArgs {item} {
+        lindex $item 4
+    }
+    proc OptHelp {item} {
+        lindex $item 5
+    }
+    proc OptNeedValue {item} {
+        expr {![string equal [OptType $item] boolflag]}
+    }
+    proc OptDefaultValue {item} {
+        set val [OptTypeArgs $item]
+        switch -exact -- [OptType $item] {
+            choice {return [lindex $val 0]}
+	    boolean -
+	    boolflag {
+		# convert back false/true to 0/1 because expr !$bool
+		# is broken..
+		if {$val} {
+		    return 1
+		} else {
+		    return 0
+		}
+	    }
+        }
+        return $val
+    }
+
+    # Description format error helper
+    proc OptOptUsage {item {what ""}} {
+        return -code error "invalid description format$what: $item\n\
+                should be a list of {varname|-flagname ?-type? ?defaultvalue?\
+                ?helpstring?}"
+    }
+
+
+    # Generate a canonical form single instruction
+    proc OptNewInst {state varname type typeArgs help} {
+	list $state $varname [list 0 {}] $type $typeArgs $help
+	#                          ^  ^
+	#                          |  |
+	#               hasBeenSet=+  +=currentValue
+    }
+
+    # Translate one item to canonical form
+    proc OptNormalizeOne {item} {
+        set lg [Lassign $item varname arg1 arg2 arg3]
+#       puts "called optnormalizeone '$item' v=($varname), lg=$lg"
+        set isflag [OptIsFlag $varname]
+	set isopt  [OptIsOpt  $varname]
+        if {$isflag} {
+            set state "flags"
+        } elseif {$isopt} {
+	    set state "optValue"
+	} elseif {![string equal $varname "args"]} {
+	    set state "value"
+	} else {
+	    set state "args"
+	}
+
+	# apply 'smart' 'fuzzy' logic to try to make
+	# description writer's life easy, and our's difficult :
+	# let's guess the missing arguments :-)
+
+        switch $lg {
+            1 {
+                if {$isflag} {
+                    return [OptNewInst $state $varname boolflag false ""]
+                } else {
+                    return [OptNewInst $state $varname any "" ""]
+                }
+            }
+            2 {
+                # varname default
+                # varname help
+                set type [OptGuessType $arg1]
+                if {[string equal $type "string"]} {
+                    if {$isflag} {
+			set type boolflag
+			set def false
+		    } else {
+			set type any
+			set def ""
+		    }
+		    set help $arg1
+                } else {
+                    set help ""
+                    set def $arg1
+                }
+                return [OptNewInst $state $varname $type $def $help]
+            }
+            3 {
+                # varname type value
+                # varname value comment
+
+                if {[regexp {^-(.+)$} $arg1 x type]} {
+		    # flags/optValue as they are optional, need a "value",
+		    # on the contrary, for a variable (non optional),
+	            # default value is pointless, 'cept for choices :
+		    if {$isflag || $isopt || ($type == "choice")} {
+			return [OptNewInst $state $varname $type $arg2 ""]
+		    } else {
+			return [OptNewInst $state $varname $type "" $arg2]
+		    }
+                } else {
+                    return [OptNewInst $state $varname\
+			    [OptGuessType $arg1] $arg1 $arg2]
+                }
+            }
+            4 {
+                if {[regexp {^-(.+)$} $arg1 x type]} {
+		    return [OptNewInst $state $varname $type $arg2 $arg3]
+                } else {
+                    return -code error [OptOptUsage $item]
+                }
+            }
+            default {
+                return -code error [OptOptUsage $item]
+            }
+        }
+    }
+
+    # Auto magic lazy type determination
+    proc OptGuessType {arg} {
+ 	 if { $arg == "true" || $arg == "false" } {
+            return boolean
+        }
+        if {[string is integer -strict $arg]} {
+            return int
+        }
+        if {[string is double -strict $arg]} {
+            return float
+        }
+        return string
+    }
+
+    # Error messages front ends
+
+    proc OptAmbigous {desc arg} {
+        OptError "ambigous option \"$arg\", choose from:" [OptSelection $desc]
+    }
+    proc OptFlagUsage {desc arg} {
+        OptError "bad flag \"$arg\", must be one of" $desc
+    }
+    proc OptTooManyArgs {desc arguments} {
+        OptError "too many arguments (unexpected argument(s): $arguments),\
+		usage:"\
+		$desc 1
+    }
+    proc OptParamType {item} {
+	if {[OptIsFlag $item]} {
+	    return "flag"
+	} else {
+	    return "parameter"
+	}
+    }
+    proc OptBadValue {item arg {err {}}} {
+#       puts "bad val err = \"$err\""
+        OptError "bad value \"$arg\" for [OptParamType $item]"\
+		[list $item]
+    }
+    proc OptMissingValue {descriptions} {
+#        set item [OptCurDescFinal $descriptions]
+        set item [OptCurDesc $descriptions]
+        OptError "no value given for [OptParamType $item] \"[OptName $item]\"\
+		(use -help for full usage) :"\
+		[list $item]
+    }
+
+proc ::tcl::OptKeyError {prefix descKey {header 0}} {
+    OptError $prefix [OptKeyGetDesc $descKey] $header
+}
+
+    # determine string length for nice tabulated output
+    proc OptLengths {desc nlName tlName dlName} {
+	upvar $nlName nl
+	upvar $tlName tl
+	upvar $dlName dl
+	foreach item $desc {
+	    if {[OptIsCounter $item]} continue
+	    if {[OptIsPrg $item]} {
+		OptLengths $item nl tl dl
+	    } else {
+		SetMax nl [string length [OptName $item]]
+		SetMax tl [string length [OptType $item]]
+		set dv [OptTypeArgs $item]
+		if {[OptState $item] != "header"} {
+		    set dv "($dv)"
+		}
+		set l [string length $dv]
+		# limit the space allocated to potentially big "choices"
+		if {([OptType $item] != "choice") || ($l<=12)} {
+		    SetMax dl $l
+		} else {
+		    if {![info exists dl]} {
+			set dl 0
+		    }
+		}
+	    }
+	}
+    }
+    # output the tree
+    proc OptTree {desc nl tl dl} {
+	set res ""
+	foreach item $desc {
+	    if {[OptIsCounter $item]} continue
+	    if {[OptIsPrg $item]} {
+		append res [OptTree $item $nl $tl $dl]
+	    } else {
+		set dv [OptTypeArgs $item]
+		if {[OptState $item] != "header"} {
+		    set dv "($dv)"
+		}
+		append res [string trimright [format "\n    %-*s %-*s %-*s %s" \
+			$nl [OptName $item] $tl [OptType $item] \
+			$dl $dv [OptHelp $item]]]
+	    }
+	}
+	return $res
+    }
+
+# Give nice usage string
+proc ::tcl::OptError {prefix desc {header 0}} {
+    # determine length
+    if {$header} {
+	# add faked instruction
+	set h [list [OptNewInst header Var/FlagName Type Value Help]]
+	lappend h   [OptNewInst header ------------ ---- ----- ----]
+	lappend h   [OptNewInst header {(-help} "" "" {gives this help)}]
+	set desc [concat $h $desc]
+    }
+    OptLengths $desc nl tl dl
+    # actually output
+    return "$prefix[OptTree $desc $nl $tl $dl]"
+}
+
+
+################     General Utility functions   #######################
+
+#
+# List utility functions
+# Naming convention:
+#     "Lvarxxx" take the list VARiable name as argument
+#     "Lxxxx"   take the list value as argument
+#               (which is not costly with Tcl8 objects system
+#                as it's still a reference and not a copy of the values)
+#
+
+# Is that list empty ?
+proc ::tcl::Lempty {list} {
+    expr {[llength $list]==0}
+}
+
+# Gets the value of one leaf of a lists tree
+proc ::tcl::Lget {list indexLst} {
+    if {[llength $indexLst] <= 1} {
+        return [lindex $list $indexLst]
+    }
+    Lget [lindex $list [lindex $indexLst 0]] [lrange $indexLst 1 end]
+}
+# Sets the value of one leaf of a lists tree
+# (we use the version that does not create the elements because
+#  it would be even slower... needs to be written in C !)
+# (nb: there is a non trivial recursive problem with indexes 0,
+#  which appear because there is no difference between a list
+#  of 1 element and 1 element alone : [list "a"] == "a" while
+#  it should be {a} and [listp a] should be 0 while [listp {a b}] would be 1
+#  and [listp "a b"] maybe 0. listp does not exist either...)
+proc ::tcl::Lvarset {listName indexLst newValue} {
+    upvar $listName list
+    if {[llength $indexLst] <= 1} {
+        Lvarset1nc list $indexLst $newValue
+    } else {
+        set idx [lindex $indexLst 0]
+        set targetList [lindex $list $idx]
+        # reduce refcount on targetList (not really usefull now,
+	# could be with optimizing compiler)
+#        Lvarset1 list $idx {}
+        # recursively replace in targetList
+        Lvarset targetList [lrange $indexLst 1 end] $newValue
+        # put updated sub list back in the tree
+        Lvarset1nc list $idx $targetList
+    }
+}
+# Set one cell to a value, eventually create all the needed elements
+# (on level-1 of lists)
+variable emptyList {}
+proc ::tcl::Lvarset1 {listName index newValue} {
+    upvar $listName list
+    if {$index < 0} {return -code error "invalid negative index"}
+    set lg [llength $list]
+    if {$index >= $lg} {
+        variable emptyList
+        for {set i $lg} {$i<$index} {incr i} {
+            lappend list $emptyList
+        }
+        lappend list $newValue
+    } else {
+        set list [lreplace $list $index $index $newValue]
+    }
+}
+# same as Lvarset1 but no bound checking / creation
+proc ::tcl::Lvarset1nc {listName index newValue} {
+    upvar $listName list
+    set list [lreplace $list $index $index $newValue]
+}
+# Increments the value of one leaf of a lists tree
+# (which must exists)
+proc ::tcl::Lvarincr {listName indexLst {howMuch 1}} {
+    upvar $listName list
+    if {[llength $indexLst] <= 1} {
+        Lvarincr1 list $indexLst $howMuch
+    } else {
+        set idx [lindex $indexLst 0]
+        set targetList [lindex $list $idx]
+        # reduce refcount on targetList
+        Lvarset1nc list $idx {}
+        # recursively replace in targetList
+        Lvarincr targetList [lrange $indexLst 1 end] $howMuch
+        # put updated sub list back in the tree
+        Lvarset1nc list $idx $targetList
+    }
+}
+# Increments the value of one cell of a list
+proc ::tcl::Lvarincr1 {listName index {howMuch 1}} {
+    upvar $listName list
+    set newValue [expr {[lindex $list $index]+$howMuch}]
+    set list [lreplace $list $index $index $newValue]
+    return $newValue
+}
+# Removes the first element of a list
+# and returns the new list value
+proc ::tcl::Lvarpop1 {listName} {
+    upvar $listName list
+    set list [lrange $list 1 end]
+}
+# Same but returns the removed element
+# (Like the tclX version)
+proc ::tcl::Lvarpop {listName} {
+    upvar $listName list
+    set el [lindex $list 0]
+    set list [lrange $list 1 end]
+    return $el
+}
+# Assign list elements to variables and return the length of the list
+proc ::tcl::Lassign {list args} {
+    # faster than direct blown foreach (which does not byte compile)
+    set i 0
+    set lg [llength $list]
+    foreach vname $args {
+        if {$i>=$lg} break
+        uplevel 1 [list ::set $vname [lindex $list $i]]
+        incr i
+    }
+    return $lg
+}
+
+# Misc utilities
+
+# Set the varname to value if value is greater than varname's current value
+# or if varname is undefined
+proc ::tcl::SetMax {varname value} {
+    upvar 1 $varname var
+    if {![info exists var] || $value > $var} {
+        set var $value
+    }
+}
+
+# Set the varname to value if value is smaller than varname's current value
+# or if varname is undefined
+proc ::tcl::SetMin {varname value} {
+    upvar 1 $varname var
+    if {![info exists var] || $value < $var} {
+        set var $value
+    }
+}
+
+
+    # everything loaded fine, lets create the test proc:
+ #    OptCreateTestProc
+    # Don't need the create temp proc anymore:
+ #    rename OptCreateTestProc {}
+}
diff --git a/library/opt/pkgIndex.tcl b/library/opt/pkgIndex.tcl
new file mode 100644
index 0000000..107d4c6
--- /dev/null
+++ b/library/opt/pkgIndex.tcl
@@ -0,0 +1,12 @@
+# Tcl package index file, version 1.1
+# This file is generated by the "pkg_mkIndex -direct" command
+# and sourced either when an application starts up or
+# by a "package unknown" script.  It invokes the
+# "package ifneeded" command to set up package-related
+# information so that packages will be loaded automatically
+# in response to "package require" commands.  When this
+# script is sourced, the variable $dir must contain the
+# full path name of this file's directory.
+
+if {![package vsatisfies [package provide Tcl] 8.2]} {return}
+package ifneeded opt 0.4.6 [list source [file join $dir optparse.tcl]]
diff --git a/library/package.tcl b/library/package.tcl
new file mode 100644
index 0000000..44e3b28
--- /dev/null
+++ b/library/package.tcl
@@ -0,0 +1,747 @@
+# package.tcl --
+#
+# utility procs formerly in init.tcl which can be loaded on demand
+# for package management.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994-1998 Sun Microsystems, Inc.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+
+namespace eval tcl::Pkg {}
+
+# ::tcl::Pkg::CompareExtension --
+#
+# Used internally by pkg_mkIndex to compare the extension of a file to a given
+# extension. On Windows, it uses a case-insensitive comparison because the
+# file system can be file insensitive.
+#
+# Arguments:
+#  fileName	name of a file whose extension is compared
+#  ext		(optional) The extension to compare against; you must
+#		provide the starting dot.
+#		Defaults to [info sharedlibextension]
+#
+# Results:
+#  Returns 1 if the extension matches, 0 otherwise
+
+proc tcl::Pkg::CompareExtension {fileName {ext {}}} {
+    global tcl_platform
+    if {$ext eq ""} {set ext [info sharedlibextension]}
+    if {$tcl_platform(platform) eq "windows"} {
+        return [string equal -nocase [file extension $fileName] $ext]
+    } else {
+        # Some unices add trailing numbers after the .so, so
+        # we could have something like '.so.1.2'.
+        set root $fileName
+        while {1} {
+            set currExt [file extension $root]
+            if {$currExt eq $ext} {
+                return 1
+            }
+
+	    # The current extension does not match; if it is not a numeric
+	    # value, quit, as we are only looking to ignore version number
+	    # extensions.  Otherwise we might return 1 in this case:
+	    #		tcl::Pkg::CompareExtension foo.so.bar .so
+	    # which should not match.
+
+	    if {![string is integer -strict [string range $currExt 1 end]]} {
+		return 0
+	    }
+            set root [file rootname $root]
+	}
+    }
+}
+
+# pkg_mkIndex --
+# This procedure creates a package index in a given directory.  The package
+# index consists of a "pkgIndex.tcl" file whose contents are a Tcl script that
+# sets up package information with "package require" commands.  The commands
+# describe all of the packages defined by the files given as arguments.
+#
+# Arguments:
+# -direct		(optional) If this flag is present, the generated
+#			code in pkgMkIndex.tcl will cause the package to be
+#			loaded when "package require" is executed, rather
+#			than lazily when the first reference to an exported
+#			procedure in the package is made.
+# -verbose		(optional) Verbose output; the name of each file that
+#			was successfully rocessed is printed out. Additionally,
+#			if processing of a file failed a message is printed.
+# -load pat		(optional) Preload any packages whose names match
+#			the pattern.  Used to handle DLLs that depend on
+#			other packages during their Init procedure.
+# dir -			Name of the directory in which to create the index.
+# args -		Any number of additional arguments, each giving
+#			a glob pattern that matches the names of one or
+#			more shared libraries or Tcl script files in
+#			dir.
+
+proc pkg_mkIndex {args} {
+    set usage {"pkg_mkIndex ?-direct? ?-lazy? ?-load pattern? ?-verbose? ?--? dir ?pattern ...?"}
+
+    set argCount [llength $args]
+    if {$argCount < 1} {
+	return -code error "wrong # args: should be\n$usage"
+    }
+
+    set more ""
+    set direct 1
+    set doVerbose 0
+    set loadPat ""
+    for {set idx 0} {$idx < $argCount} {incr idx} {
+	set flag [lindex $args $idx]
+	switch -glob -- $flag {
+	    -- {
+		# done with the flags
+		incr idx
+		break
+	    }
+	    -verbose {
+		set doVerbose 1
+	    }
+	    -lazy {
+		set direct 0
+		append more " -lazy"
+	    }
+	    -direct {
+		append more " -direct"
+	    }
+	    -load {
+		incr idx
+		set loadPat [lindex $args $idx]
+		append more " -load $loadPat"
+	    }
+	    -* {
+		return -code error "unknown flag $flag: should be\n$usage"
+	    }
+	    default {
+		# done with the flags
+		break
+	    }
+	}
+    }
+
+    set dir [lindex $args $idx]
+    set patternList [lrange $args [expr {$idx + 1}] end]
+    if {![llength $patternList]} {
+	set patternList [list "*.tcl" "*[info sharedlibextension]"]
+    }
+
+    try {
+	set fileList [glob -directory $dir -tails -types {r f} -- \
+		{*}$patternList]
+    } on error {msg opt} {
+	return -options $opt $msg
+    }
+    foreach file $fileList {
+	# For each file, figure out what commands and packages it provides.
+	# To do this, create a child interpreter, load the file into the
+	# interpreter, and get a list of the new commands and packages that
+	# are defined.
+
+	if {$file eq "pkgIndex.tcl"} {
+	    continue
+	}
+
+	set c [interp create]
+
+	# Load into the child any packages currently loaded in the parent
+	# interpreter that match the -load pattern.
+
+	if {$loadPat ne ""} {
+	    if {$doVerbose} {
+		tclLog "currently loaded packages: '[info loaded]'"
+		tclLog "trying to load all packages matching $loadPat"
+	    }
+	    if {![llength [info loaded]]} {
+		tclLog "warning: no packages are currently loaded, nothing"
+		tclLog "can possibly match '$loadPat'"
+	    }
+	}
+	foreach pkg [info loaded] {
+	    if {![string match -nocase $loadPat [lindex $pkg 1]]} {
+		continue
+	    }
+	    if {$doVerbose} {
+		tclLog "package [lindex $pkg 1] matches '$loadPat'"
+	    }
+	    try {
+		load [lindex $pkg 0] [lindex $pkg 1] $c
+	    } on error err {
+		if {$doVerbose} {
+		    tclLog "warning: load [lindex $pkg 0]\
+			    [lindex $pkg 1]\nfailed with: $err"
+		}
+	    } on ok {} {
+		if {$doVerbose} {
+		    tclLog "loaded [lindex $pkg 0] [lindex $pkg 1]"
+		}
+	    }
+	    if {[lindex $pkg 1] eq "Tk"} {
+		# Withdraw . if Tk was loaded, to avoid showing a window.
+		$c eval [list wm withdraw .]
+	    }
+	}
+
+	$c eval {
+	    # Stub out the package command so packages can require other
+	    # packages.
+
+	    rename package __package_orig
+	    proc package {what args} {
+		switch -- $what {
+		    require {
+			return;		# Ignore transitive requires
+		    }
+		    default {
+			__package_orig $what {*}$args
+		    }
+		}
+	    }
+	    proc tclPkgUnknown args {}
+	    package unknown tclPkgUnknown
+
+	    # Stub out the unknown command so package can call into each other
+	    # during their initialilzation.
+
+	    proc unknown {args} {}
+
+	    # Stub out the auto_import mechanism
+
+	    proc auto_import {args} {}
+
+	    # reserve the ::tcl namespace for support procs and temporary
+	    # variables.  This might make it awkward to generate a
+	    # pkgIndex.tcl file for the ::tcl namespace.
+
+	    namespace eval ::tcl {
+		variable dir		;# Current directory being processed
+		variable file		;# Current file being processed
+		variable direct		;# -direct flag value
+		variable x		;# Loop variable
+		variable debug		;# For debugging
+		variable type		;# "load" or "source", for -direct
+		variable namespaces	;# Existing namespaces (e.g., ::tcl)
+		variable packages	;# Existing packages (e.g., Tcl)
+		variable origCmds	;# Existing commands
+		variable newCmds	;# Newly created commands
+		variable newPkgs {}	;# Newly created packages
+	    }
+	}
+
+	$c eval [list set ::tcl::dir $dir]
+	$c eval [list set ::tcl::file $file]
+	$c eval [list set ::tcl::direct $direct]
+
+	# Download needed procedures into the slave because we've just deleted
+	# the unknown procedure.  This doesn't handle procedures with default
+	# arguments.
+
+	foreach p {::tcl::Pkg::CompareExtension} {
+	    $c eval [list namespace eval [namespace qualifiers $p] {}]
+	    $c eval [list proc $p [info args $p] [info body $p]]
+	}
+
+	try {
+	    $c eval {
+		set ::tcl::debug "loading or sourcing"
+
+		# we need to track command defined by each package even in the
+		# -direct case, because they are needed internally by the
+		# "partial pkgIndex.tcl" step above.
+
+		proc ::tcl::GetAllNamespaces {{root ::}} {
+		    set list $root
+		    foreach ns [namespace children $root] {
+			lappend list {*}[::tcl::GetAllNamespaces $ns]
+		    }
+		    return $list
+		}
+
+		# init the list of existing namespaces, packages, commands
+
+		foreach ::tcl::x [::tcl::GetAllNamespaces] {
+		    set ::tcl::namespaces($::tcl::x) 1
+		}
+		foreach ::tcl::x [package names] {
+		    if {[package provide $::tcl::x] ne ""} {
+			set ::tcl::packages($::tcl::x) 1
+		    }
+		}
+		set ::tcl::origCmds [info commands]
+
+		# Try to load the file if it has the shared library extension,
+		# otherwise source it.  It's important not to try to load
+		# files that aren't shared libraries, because on some systems
+		# (like SunOS) the loader will abort the whole application
+		# when it gets an error.
+
+		if {[::tcl::Pkg::CompareExtension $::tcl::file [info sharedlibextension]]} {
+		    # The "file join ." command below is necessary.  Without
+		    # it, if the file name has no \'s and we're on UNIX, the
+		    # load command will invoke the LD_LIBRARY_PATH search
+		    # mechanism, which could cause the wrong file to be used.
+
+		    set ::tcl::debug loading
+		    load [file join $::tcl::dir $::tcl::file]
+		    set ::tcl::type load
+		} else {
+		    set ::tcl::debug sourcing
+		    source [file join $::tcl::dir $::tcl::file]
+		    set ::tcl::type source
+		}
+
+		# As a performance optimization, if we are creating direct
+		# load packages, don't bother figuring out the set of commands
+		# created by the new packages.  We only need that list for
+		# setting up the autoloading used in the non-direct case.
+		if {!$::tcl::direct} {
+		    # See what new namespaces appeared, and import commands
+		    # from them.  Only exported commands go into the index.
+
+		    foreach ::tcl::x [::tcl::GetAllNamespaces] {
+			if {![info exists ::tcl::namespaces($::tcl::x)]} {
+			    namespace import -force ${::tcl::x}::*
+			}
+
+			# Figure out what commands appeared
+
+			foreach ::tcl::x [info commands] {
+			    set ::tcl::newCmds($::tcl::x) 1
+			}
+			foreach ::tcl::x $::tcl::origCmds {
+			    unset -nocomplain ::tcl::newCmds($::tcl::x)
+			}
+			foreach ::tcl::x [array names ::tcl::newCmds] {
+			    # determine which namespace a command comes from
+
+			    set ::tcl::abs [namespace origin $::tcl::x]
+
+			    # special case so that global names have no
+			    # leading ::, this is required by the unknown
+			    # command
+
+			    set ::tcl::abs \
+				    [lindex [auto_qualify $::tcl::abs ::] 0]
+
+			    if {$::tcl::x ne $::tcl::abs} {
+				# Name changed during qualification
+
+				set ::tcl::newCmds($::tcl::abs) 1
+				unset ::tcl::newCmds($::tcl::x)
+			    }
+			}
+		    }
+		}
+
+		# Look through the packages that appeared, and if there is a
+		# version provided, then record it
+
+		foreach ::tcl::x [package names] {
+		    if {[package provide $::tcl::x] ne ""
+			    && ![info exists ::tcl::packages($::tcl::x)]} {
+			lappend ::tcl::newPkgs \
+			    [list $::tcl::x [package provide $::tcl::x]]
+		    }
+		}
+	    }
+	} on error msg {
+	    set what [$c eval set ::tcl::debug]
+	    if {$doVerbose} {
+		tclLog "warning: error while $what $file: $msg"
+	    }
+	} on ok {} {
+	    set what [$c eval set ::tcl::debug]
+	    if {$doVerbose} {
+		tclLog "successful $what of $file"
+	    }
+	    set type [$c eval set ::tcl::type]
+	    set cmds [lsort [$c eval array names ::tcl::newCmds]]
+	    set pkgs [$c eval set ::tcl::newPkgs]
+	    if {$doVerbose} {
+		if {!$direct} {
+		    tclLog "commands provided were $cmds"
+		}
+		tclLog "packages provided were $pkgs"
+	    }
+	    if {[llength $pkgs] > 1} {
+		tclLog "warning: \"$file\" provides more than one package ($pkgs)"
+	    }
+	    foreach pkg $pkgs {
+		# cmds is empty/not used in the direct case
+		lappend files($pkg) [list $file $type $cmds]
+	    }
+
+	    if {$doVerbose} {
+		tclLog "processed $file"
+	    }
+	}
+	interp delete $c
+    }
+
+    append index "# Tcl package index file, version 1.1\n"
+    append index "# This file is generated by the \"pkg_mkIndex$more\" command\n"
+    append index "# and sourced either when an application starts up or\n"
+    append index "# by a \"package unknown\" script.  It invokes the\n"
+    append index "# \"package ifneeded\" command to set up package-related\n"
+    append index "# information so that packages will be loaded automatically\n"
+    append index "# in response to \"package require\" commands.  When this\n"
+    append index "# script is sourced, the variable \$dir must contain the\n"
+    append index "# full path name of this file's directory.\n"
+
+    foreach pkg [lsort [array names files]] {
+	set cmd {}
+	lassign $pkg name version
+	lappend cmd ::tcl::Pkg::Create -name $name -version $version
+	foreach spec [lsort -index 0 $files($pkg)] {
+	    foreach {file type procs} $spec {
+		if {$direct} {
+		    set procs {}
+		}
+		lappend cmd "-$type" [list $file $procs]
+	    }
+	}
+	append index "\n[eval $cmd]"
+    }
+
+    set f [open [file join $dir pkgIndex.tcl] w]
+    puts $f $index
+    close $f
+}
+
+# tclPkgSetup --
+# This is a utility procedure use by pkgIndex.tcl files.  It is invoked as
+# part of a "package ifneeded" script.  It calls "package provide" to indicate
+# that a package is available, then sets entries in the auto_index array so
+# that the package's files will be auto-loaded when the commands are used.
+#
+# Arguments:
+# dir -			Directory containing all the files for this package.
+# pkg -			Name of the package (no version number).
+# version -		Version number for the package, such as 2.1.3.
+# files -		List of files that constitute the package.  Each
+#			element is a sub-list with three elements.  The first
+#			is the name of a file relative to $dir, the second is
+#			"load" or "source", indicating whether the file is a
+#			loadable binary or a script to source, and the third
+#			is a list of commands defined by this file.
+
+proc tclPkgSetup {dir pkg version files} {
+    global auto_index
+
+    package provide $pkg $version
+    foreach fileInfo $files {
+	set f [lindex $fileInfo 0]
+	set type [lindex $fileInfo 1]
+	foreach cmd [lindex $fileInfo 2] {
+	    if {$type eq "load"} {
+		set auto_index($cmd) [list load [file join $dir $f] $pkg]
+	    } else {
+		set auto_index($cmd) [list source [file join $dir $f]]
+	    }
+	}
+    }
+}
+
+# tclPkgUnknown --
+# This procedure provides the default for the "package unknown" function.  It
+# is invoked when a package that's needed can't be found.  It scans the
+# auto_path directories and their immediate children looking for pkgIndex.tcl
+# files and sources any such files that are found to setup the package
+# database. As it searches, it will recognize changes to the auto_path and
+# scan any new directories.
+#
+# Arguments:
+# name -		Name of desired package.  Not used.
+# version -		Version of desired package.  Not used.
+# exact -		Either "-exact" or omitted.  Not used.
+
+proc tclPkgUnknown {name args} {
+    global auto_path env
+
+    if {![info exists auto_path]} {
+	return
+    }
+    # Cache the auto_path, because it may change while we run through the
+    # first set of pkgIndex.tcl files
+    set old_path [set use_path $auto_path]
+    while {[llength $use_path]} {
+	set dir [lindex $use_path end]
+
+	# Make sure we only scan each directory one time.
+	if {[info exists tclSeenPath($dir)]} {
+	    set use_path [lrange $use_path 0 end-1]
+	    continue
+	}
+	set tclSeenPath($dir) 1
+
+	# we can't use glob in safe interps, so enclose the following in a
+	# catch statement, where we get the pkgIndex files out of the
+	# subdirectories
+	catch {
+	    foreach file [glob -directory $dir -join -nocomplain \
+		    * pkgIndex.tcl] {
+		set dir [file dirname $file]
+		if {![info exists procdDirs($dir)]} {
+		    try {
+			source $file
+		    } trap {POSIX EACCES} {} {
+			# $file was not readable; silently ignore
+			continue
+		    } on error msg {
+			tclLog "error reading package index file $file: $msg"
+		    } on ok {} {
+			set procdDirs($dir) 1
+		    }
+		}
+	    }
+	}
+	set dir [lindex $use_path end]
+	if {![info exists procdDirs($dir)]} {
+	    set file [file join $dir pkgIndex.tcl]
+	    # safe interps usually don't have "file exists",
+	    if {([interp issafe] || [file exists $file])} {
+		try {
+		    source $file
+		} trap {POSIX EACCES} {} {
+		    # $file was not readable; silently ignore
+		    continue
+		} on error msg {
+		    tclLog "error reading package index file $file: $msg"
+		} on ok {} {
+		    set procdDirs($dir) 1
+		}
+	    }
+	}
+
+	set use_path [lrange $use_path 0 end-1]
+
+	# Check whether any of the index scripts we [source]d above set a new
+	# value for $::auto_path.  If so, then find any new directories on the
+	# $::auto_path, and lappend them to the $use_path we are working from.
+	# This gives index scripts the (arguably unwise) power to expand the
+	# index script search path while the search is in progress.
+	set index 0
+	if {[llength $old_path] == [llength $auto_path]} {
+	    foreach dir $auto_path old $old_path {
+		if {$dir ne $old} {
+		    # This entry in $::auto_path has changed.
+		    break
+		}
+		incr index
+	    }
+	}
+
+	# $index now points to the first element of $auto_path that has
+	# changed, or the beginning if $auto_path has changed length Scan the
+	# new elements of $auto_path for directories to add to $use_path.
+	# Don't add directories we've already seen, or ones already on the
+	# $use_path.
+	foreach dir [lrange $auto_path $index end] {
+	    if {![info exists tclSeenPath($dir)] && ($dir ni $use_path)} {
+		lappend use_path $dir
+	    }
+	}
+	set old_path $auto_path
+    }
+}
+
+# tcl::MacOSXPkgUnknown --
+# This procedure extends the "package unknown" function for MacOSX.  It scans
+# the Resources/Scripts directories of the immediate children of the auto_path
+# directories for pkgIndex files.
+#
+# Arguments:
+# original -		original [package unknown] procedure
+# name -		Name of desired package.  Not used.
+# version -		Version of desired package.  Not used.
+# exact -		Either "-exact" or omitted.  Not used.
+
+proc tcl::MacOSXPkgUnknown {original name args} {
+    #  First do the cross-platform default search
+    uplevel 1 $original [linsert $args 0 $name]
+
+    # Now do MacOSX specific searching
+    global auto_path
+
+    if {![info exists auto_path]} {
+	return
+    }
+    # Cache the auto_path, because it may change while we run through the
+    # first set of pkgIndex.tcl files
+    set old_path [set use_path $auto_path]
+    while {[llength $use_path]} {
+	set dir [lindex $use_path end]
+
+	# Make sure we only scan each directory one time.
+	if {[info exists tclSeenPath($dir)]} {
+	    set use_path [lrange $use_path 0 end-1]
+	    continue
+	}
+	set tclSeenPath($dir) 1
+
+	# get the pkgIndex files out of the subdirectories
+	foreach file [glob -directory $dir -join -nocomplain \
+		* Resources Scripts pkgIndex.tcl] {
+	    set dir [file dirname $file]
+	    if {![info exists procdDirs($dir)]} {
+		try {
+		    source $file
+		} trap {POSIX EACCES} {} {
+		    # $file was not readable; silently ignore
+		    continue
+		} on error msg {
+		    tclLog "error reading package index file $file: $msg"
+		} on ok {} {
+		    set procdDirs($dir) 1
+		}
+	    }
+	}
+	set use_path [lrange $use_path 0 end-1]
+
+	# Check whether any of the index scripts we [source]d above set a new
+	# value for $::auto_path.  If so, then find any new directories on the
+	# $::auto_path, and lappend them to the $use_path we are working from.
+	# This gives index scripts the (arguably unwise) power to expand the
+	# index script search path while the search is in progress.
+	set index 0
+	if {[llength $old_path] == [llength $auto_path]} {
+	    foreach dir $auto_path old $old_path {
+		if {$dir ne $old} {
+		    # This entry in $::auto_path has changed.
+		    break
+		}
+		incr index
+	    }
+	}
+
+	# $index now points to the first element of $auto_path that has
+	# changed, or the beginning if $auto_path has changed length Scan the
+	# new elements of $auto_path for directories to add to $use_path.
+	# Don't add directories we've already seen, or ones already on the
+	# $use_path.
+	foreach dir [lrange $auto_path $index end] {
+	    if {![info exists tclSeenPath($dir)] && ($dir ni $use_path)} {
+		lappend use_path $dir
+	    }
+	}
+	set old_path $auto_path
+    }
+}
+
+# ::tcl::Pkg::Create --
+#
+#	Given a package specification generate a "package ifneeded" statement
+#	for the package, suitable for inclusion in a pkgIndex.tcl file.
+#
+# Arguments:
+#	args		arguments used by the Create function:
+#			-name		packageName
+#			-version	packageVersion
+#			-load		{filename ?{procs}?}
+#			...
+#			-source		{filename ?{procs}?}
+#			...
+#
+#			Any number of -load and -source parameters may be
+#			specified, so long as there is at least one -load or
+#			-source parameter.  If the procs component of a module
+#			specifier is left off, that module will be set up for
+#			direct loading; otherwise, it will be set up for lazy
+#			loading.  If both -source and -load are specified, the
+#			-load'ed files will be loaded first, followed by the
+#			-source'd files.
+#
+# Results:
+#	An appropriate "package ifneeded" statement for the package.
+
+proc ::tcl::Pkg::Create {args} {
+    append err(usage) "[lindex [info level 0] 0] "
+    append err(usage) "-name packageName -version packageVersion"
+    append err(usage) "?-load {filename ?{procs}?}? ... "
+    append err(usage) "?-source {filename ?{procs}?}? ..."
+
+    set err(wrongNumArgs) "wrong # args: should be \"$err(usage)\""
+    set err(valueMissing) "value for \"%s\" missing: should be \"$err(usage)\""
+    set err(unknownOpt)   "unknown option \"%s\": should be \"$err(usage)\""
+    set err(noLoadOrSource) "at least one of -load and -source must be given"
+
+    # process arguments
+    set len [llength $args]
+    if {$len < 6} {
+	error $err(wrongNumArgs)
+    }
+
+    # Initialize parameters
+    array set opts {-name {} -version {} -source {} -load {}}
+
+    # process parameters
+    for {set i 0} {$i < $len} {incr i} {
+	set flag [lindex $args $i]
+	incr i
+	switch -glob -- $flag {
+	    "-name"		-
+	    "-version"		{
+		if {$i >= $len} {
+		    error [format $err(valueMissing) $flag]
+		}
+		set opts($flag) [lindex $args $i]
+	    }
+	    "-source"		-
+	    "-load"		{
+		if {$i >= $len} {
+		    error [format $err(valueMissing) $flag]
+		}
+		lappend opts($flag) [lindex $args $i]
+	    }
+	    default {
+		error [format $err(unknownOpt) [lindex $args $i]]
+	    }
+	}
+    }
+
+    # Validate the parameters
+    if {![llength $opts(-name)]} {
+	error [format $err(valueMissing) "-name"]
+    }
+    if {![llength $opts(-version)]} {
+	error [format $err(valueMissing) "-version"]
+    }
+
+    if {!([llength $opts(-source)] || [llength $opts(-load)])} {
+	error $err(noLoadOrSource)
+    }
+
+    # OK, now everything is good.  Generate the package ifneeded statment.
+    set cmdline "package ifneeded $opts(-name) $opts(-version) "
+
+    set cmdList {}
+    set lazyFileList {}
+
+    # Handle -load and -source specs
+    foreach key {load source} {
+	foreach filespec $opts(-$key) {
+	    lassign $filespec filename proclist
+
+	    if { [llength $proclist] == 0 } {
+		set cmd "\[list $key \[file join \$dir [list $filename]\]\]"
+		lappend cmdList $cmd
+	    } else {
+		lappend lazyFileList [list $filename $key $proclist]
+	    }
+	}
+    }
+
+    if {[llength $lazyFileList]} {
+	lappend cmdList "\[list tclPkgSetup \$dir $opts(-name)\
+		$opts(-version) [list $lazyFileList]\]"
+    }
+    append cmdline [join $cmdList "\\n"]
+    return $cmdline
+}
+
+interp alias {} ::pkg::create {} ::tcl::Pkg::Create
diff --git a/library/parray.tcl b/library/parray.tcl
new file mode 100644
index 0000000..a9c2cb1
--- /dev/null
+++ b/library/parray.tcl
@@ -0,0 +1,28 @@
+# parray:
+# Print the contents of a global array on stdout.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994 Sun Microsystems, Inc.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+
+proc parray {a {pattern *}} {
+    upvar 1 $a array
+    if {![array exists array]} {
+	return -code error "\"$a\" isn't an array"
+    }
+    set maxl 0
+    set names [lsort [array names array $pattern]]
+    foreach name $names {
+	if {[string length $name] > $maxl} {
+	    set maxl [string length $name]
+	}
+    }
+    set maxl [expr {$maxl + [string length $a] + 2}]
+    foreach name $names {
+	set nameString [format %s(%s) $a $name]
+	puts stdout [format "%-*s = %s" $maxl $nameString $array($name)]
+    }
+}
diff --git a/library/platform/pkgIndex.tcl b/library/platform/pkgIndex.tcl
new file mode 100644
index 0000000..5970a3f
--- /dev/null
+++ b/library/platform/pkgIndex.tcl
@@ -0,0 +1,3 @@
+package ifneeded platform        1.0.14 [list source [file join $dir platform.tcl]]
+package ifneeded platform::shell 1.1.4 [list source [file join $dir shell.tcl]]
+
diff --git a/library/platform/platform.tcl b/library/platform/platform.tcl
new file mode 100644
index 0000000..35a22a3
--- /dev/null
+++ b/library/platform/platform.tcl
@@ -0,0 +1,397 @@
+# -*- tcl -*-
+# ### ### ### ######### ######### #########
+## Overview
+
+# Heuristics to assemble a platform identifier from publicly available
+# information. The identifier describes the platform of the currently
+# running tcl shell. This is a mixture of the runtime environment and
+# of build-time properties of the executable itself.
+#
+# Examples:
+# <1> A tcl shell executing on a x86_64 processor, but having a
+#   wordsize of 4 was compiled for the x86 environment, i.e. 32
+#   bit, and loaded packages have to match that, and not the
+#   actual cpu.
+#
+# <2> The hp/solaris 32/64 bit builds of the core cannot be
+#   distinguished by looking at tcl_platform. As packages have to
+#   match the 32/64 information we have to look in more places. In
+#   this case we inspect the executable itself (magic numbers,
+#   i.e. fileutil::magic::filetype).
+#
+# The basic information used comes out of the 'os' and 'machine'
+# entries of the 'tcl_platform' array. A number of general and
+# os/machine specific transformation are applied to get a canonical
+# result.
+#
+# General
+# Only the first element of 'os' is used - we don't care whether we
+# are on "Windows NT" or "Windows XP" or whatever.
+#
+# Machine specific
+# % arm*   -> arm
+# % sun4*  -> sparc
+# % intel  -> ix86
+# % i*86*  -> ix86
+# % Power* -> powerpc
+# % x86_64 + wordSize 4 => x86 code
+#
+# OS specific
+# % AIX are always powerpc machines
+# % HP-UX 9000/800 etc means parisc
+# % linux has to take glibc version into account
+# % sunos -> solaris, and keep version number
+#
+# NOTE: A platform like linux glibc 2.3, which can use glibc 2.2 stuff
+# has to provide all possible allowed platform identifiers when
+# searching search. Ditto a solaris 2.8 platform can use solaris 2.6
+# packages. Etc. This is handled by the other procedure, see below.
+
+# ### ### ### ######### ######### #########
+## Requirements
+
+namespace eval ::platform {}
+
+# ### ### ### ######### ######### #########
+## Implementation
+
+# -- platform::generic
+#
+# Assembles an identifier for the generic platform. It leaves out
+# details like kernel version, libc version, etc.
+
+proc ::platform::generic {} {
+    global tcl_platform
+
+    set plat [string tolower [lindex $tcl_platform(os) 0]]
+    set cpu  $tcl_platform(machine)
+
+    switch -glob -- $cpu {
+	sun4* {
+	    set cpu sparc
+	}
+	intel -
+	i*86* {
+	    set cpu ix86
+	}
+	x86_64 {
+	    if {$tcl_platform(wordSize) == 4} {
+		# See Example <1> at the top of this file.
+		set cpu ix86
+	    }
+	}
+	"Power*" {
+	    set cpu powerpc
+	}
+	"arm*" {
+	    set cpu arm
+	}
+	ia64 {
+	    if {$tcl_platform(wordSize) == 4} {
+		append cpu _32
+	    }
+	}
+    }
+
+    switch -glob -- $plat {
+	cygwin* {
+	    set plat cygwin
+	}
+	windows {
+	    if {$tcl_platform(platform) == "unix"} {
+		set plat cygwin
+	    } else {
+		set plat win32
+	    }
+	    if {$cpu eq "amd64"} {
+		# Do not check wordSize, win32-x64 is an IL32P64 platform.
+		set cpu x86_64
+	    }
+	}
+	sunos {
+	    set plat solaris
+	    if {[string match "ix86" $cpu]} {
+		if {$tcl_platform(wordSize) == 8} {
+		    set cpu x86_64
+		}
+	    } elseif {![string match "ia64*" $cpu]} {
+		# sparc
+		if {$tcl_platform(wordSize) == 8} {
+		    append cpu 64
+		}
+	    }
+	}
+	darwin {
+	    set plat macosx
+	    # Correctly identify the cpu when running as a 64bit
+	    # process on a machine with a 32bit kernel
+	    if {$cpu eq "ix86"} {
+		if {$tcl_platform(wordSize) == 8} {
+		    set cpu x86_64
+		}
+	    }
+	}
+	aix {
+	    set cpu powerpc
+	    if {$tcl_platform(wordSize) == 8} {
+		append cpu 64
+	    }
+	}
+	hp-ux {
+	    set plat hpux
+	    if {![string match "ia64*" $cpu]} {
+		set cpu parisc
+		if {$tcl_platform(wordSize) == 8} {
+		    append cpu 64
+		}
+	    }
+	}
+	osf1 {
+	    set plat tru64
+	}
+    }
+
+    return "${plat}-${cpu}"
+}
+
+# -- platform::identify
+#
+# Assembles an identifier for the exact platform, by extending the
+# generic identifier. I.e. it adds in details like kernel version,
+# libc version, etc., if they are relevant for the loading of
+# packages on the platform.
+
+proc ::platform::identify {} {
+    global tcl_platform
+
+    set id [generic]
+    regexp {^([^-]+)-([^-]+)$} $id -> plat cpu
+
+    switch -- $plat {
+	solaris {
+	    regsub {^5} $tcl_platform(osVersion) 2 text
+	    append plat $text
+	    return "${plat}-${cpu}"
+	}
+	macosx {
+	    set major [lindex [split $tcl_platform(osVersion) .] 0]
+	    if {$major > 8} {
+		incr major -4
+		append plat 10.$major
+		return "${plat}-${cpu}"
+	    }
+	}
+	linux {
+	    # Look for the libc*.so and determine its version
+	    # (libc5/6, libc6 further glibc 2.X)
+
+	    set v unknown
+
+	    # Determine in which directory to look. /lib, or /lib64.
+	    # For that we use the tcl_platform(wordSize).
+	    #
+	    # We could use the 'cpu' info, per the equivalence below,
+	    # that however would be restricted to intel. And this may
+	    # be a arm, mips, etc. system. The wordsize is more
+	    # fundamental.
+	    #
+	    # ix86   <=> (wordSize == 4) <=> 32 bit ==> /lib
+	    # x86_64 <=> (wordSize == 8) <=> 64 bit ==> /lib64
+	    #
+	    # Do not look into /lib64 even if present, if the cpu
+	    # doesn't fit.
+
+	    # TODO: Determine the prefixes (i386, x86_64, ...) for
+	    # other cpus.  The path after the generic one is utterly
+	    # specific to intel right now.  Ok, on Ubuntu, possibly
+	    # other Debian systems we may apparently be able to query
+	    # the necessary CPU code. If we can't we simply use the
+	    # hardwired fallback.
+
+	    switch -exact -- $tcl_platform(wordSize) {
+		4 {
+		    lappend bases /lib
+		    if {[catch {
+			exec dpkg-architecture -qDEB_HOST_MULTIARCH
+		    } res]} {
+			lappend bases /lib/i386-linux-gnu
+		    } else {
+			# dpkg-arch returns the full tripled, not just cpu.
+			lappend bases /lib/$res
+		    }
+		}
+		8 {
+		    lappend bases /lib64
+		    if {[catch {
+			exec dpkg-architecture -qDEB_HOST_MULTIARCH
+		    } res]} {
+			lappend bases /lib/x86_64-linux-gnu
+		    } else {
+			# dpkg-arch returns the full tripled, not just cpu.
+			lappend bases /lib/$res
+		    }
+		}
+		default {
+		    return -code error "Bad wordSize $tcl_platform(wordSize), expected 4 or 8"
+		}
+	    }
+
+	    foreach base $bases {
+		if {[LibcVersion $base -> v]} break
+	    }
+
+	    append plat -$v
+	    return "${plat}-${cpu}"
+	}
+    }
+
+    return $id
+}
+
+proc ::platform::LibcVersion {base _->_ vv} {
+    upvar 1 $vv v
+    set libclist [lsort [glob -nocomplain -directory $base libc*]]
+
+    if {![llength $libclist]} { return 0 }
+
+    set libc [lindex $libclist 0]
+
+    # Try executing the library first. This should suceed
+    # for a glibc library, and return the version
+    # information.
+
+    if {![catch {
+	set vdata [lindex [split [exec $libc] \n] 0]
+    }]} {
+	regexp {version ([0-9]+(\.[0-9]+)*)} $vdata -> v
+	foreach {major minor} [split $v .] break
+	set v glibc${major}.${minor}
+	return 1
+    } else {
+	# We had trouble executing the library. We are now
+	# inspecting its name to determine the version
+	# number. This code by Larry McVoy.
+
+	if {[regexp -- {libc-([0-9]+)\.([0-9]+)} $libc -> major minor]} {
+	    set v glibc${major}.${minor}
+	    return 1
+	}
+    }
+    return 0
+}
+
+# -- platform::patterns
+#
+# Given an exact platform identifier, i.e. _not_ the generic
+# identifier it assembles a list of exact platform identifier
+# describing platform which should be compatible with the
+# input.
+#
+# I.e. packages for all platforms in the result list should be
+# loadable on the specified platform.
+
+# << Should we add the generic identifier to the list as well ? In
+#    general it is not compatible I believe. So better not. In many
+#    cases the exact identifier is identical to the generic one
+#    anyway.
+# >>
+
+proc ::platform::patterns {id} {
+    set res [list $id]
+    if {$id eq "tcl"} {return $res}
+
+    switch -glob --  $id {
+	solaris*-* {
+	    if {[regexp {solaris([^-]*)-(.*)} $id -> v cpu]} {
+		if {$v eq ""} {return $id}
+		foreach {major minor} [split $v .] break
+		incr minor -1
+		for {set j $minor} {$j >= 6} {incr j -1} {
+		    lappend res solaris${major}.${j}-${cpu}
+		}
+	    }
+	}
+	linux*-* {
+	    if {[regexp {linux-glibc([^-]*)-(.*)} $id -> v cpu]} {
+		foreach {major minor} [split $v .] break
+		incr minor -1
+		for {set j $minor} {$j >= 0} {incr j -1} {
+		    lappend res linux-glibc${major}.${j}-${cpu}
+		}
+	    }
+	}
+	macosx-powerpc {
+	    lappend res macosx-universal
+	}
+	macosx-x86_64 {
+	    lappend res macosx-i386-x86_64
+	}
+	macosx-ix86 {
+	    lappend res macosx-universal macosx-i386-x86_64
+	}
+	macosx*-*    {
+	    # 10.5+
+	    if {[regexp {macosx([^-]*)-(.*)} $id -> v cpu]} {
+
+		switch -exact -- $cpu {
+		    ix86    {
+			lappend alt i386-x86_64
+			lappend alt universal
+		    }
+		    x86_64  { lappend alt i386-x86_64 }
+		    default { set alt {} }
+		}
+
+		if {$v ne ""} {
+		    foreach {major minor} [split $v .] break
+
+		    # Add 10.5 to 10.minor to patterns.
+		    set res {}
+		    for {set j $minor} {$j >= 5} {incr j -1} {
+			lappend res macosx${major}.${j}-${cpu}
+			foreach a $alt {
+			    lappend res macosx${major}.${j}-$a
+			}
+		    }
+
+		    # Add unversioned patterns for 10.3/10.4 builds.
+		    lappend res macosx-${cpu}
+		    foreach a $alt {
+			lappend res macosx-$a
+		    }
+		} else {
+		    # No version, just do unversioned patterns.
+		    foreach a $alt {
+			lappend res macosx-$a
+		    }
+		}
+	    } else {
+		# no v, no cpu ... nothing
+	    }
+	}
+    }
+    lappend res tcl ; # Pure tcl packages are always compatible.
+    return $res
+}
+
+
+# ### ### ### ######### ######### #########
+## Ready
+
+package provide platform 1.0.14
+
+# ### ### ### ######### ######### #########
+## Demo application
+
+if {[info exists argv0] && ($argv0 eq [info script])} {
+    puts ====================================
+    parray tcl_platform
+    puts ====================================
+    puts Generic\ identification:\ [::platform::generic]
+    puts Exact\ identification:\ \ \ [::platform::identify]
+    puts ====================================
+    puts Search\ patterns:
+    puts *\ [join [::platform::patterns [::platform::identify]] \n*\ ]
+    puts ====================================
+    exit 0
+}
diff --git a/library/platform/shell.tcl b/library/platform/shell.tcl
new file mode 100644
index 0000000..6eb9691
--- /dev/null
+++ b/library/platform/shell.tcl
@@ -0,0 +1,241 @@
+
+# -*- tcl -*-
+# ### ### ### ######### ######### #########
+## Overview
+
+# Higher-level commands which invoke the functionality of this package
+# for an arbitrary tcl shell (tclsh, wish, ...). This is required by a
+# repository as while the tcl shell executing packages uses the same
+# platform in general as a repository application there can be
+# differences in detail (i.e. 32/64 bit builds).
+
+# ### ### ### ######### ######### #########
+## Requirements
+
+package require platform
+namespace eval ::platform::shell {}
+
+# ### ### ### ######### ######### #########
+## Implementation
+
+# -- platform::shell::generic
+
+proc ::platform::shell::generic {shell} {
+    # Argument is the path to a tcl shell.
+
+    CHECK $shell
+    LOCATE base out
+
+    set     code {}
+    # Forget any pre-existing platform package, it might be in
+    # conflict with this one.
+    lappend code {package forget platform}
+    # Inject our platform package
+    lappend code [list source $base]
+    # Query and print the architecture
+    lappend code {puts [platform::generic]}
+    # And done
+    lappend code {exit 0}
+
+    set arch [RUN $shell [join $code \n]]
+
+    if {$out} {file delete -force $base}
+    return $arch
+}
+
+# -- platform::shell::identify
+
+proc ::platform::shell::identify {shell} {
+    # Argument is the path to a tcl shell.
+
+    CHECK $shell
+    LOCATE base out
+
+    set     code {}
+    # Forget any pre-existing platform package, it might be in
+    # conflict with this one.
+    lappend code {package forget platform}
+    # Inject our platform package
+    lappend code [list source $base]
+    # Query and print the architecture
+    lappend code {puts [platform::identify]}
+    # And done
+    lappend code {exit 0}
+
+    set arch [RUN $shell [join $code \n]]
+
+    if {$out} {file delete -force $base}
+    return $arch
+}
+
+# -- platform::shell::platform
+
+proc ::platform::shell::platform {shell} {
+    # Argument is the path to a tcl shell.
+
+    CHECK $shell
+
+    set     code {}
+    lappend code {puts $tcl_platform(platform)}
+    lappend code {exit 0}
+
+    return [RUN $shell [join $code \n]]
+}
+
+# ### ### ### ######### ######### #########
+## Internal helper commands.
+
+proc ::platform::shell::CHECK {shell} {
+    if {![file exists $shell]} {
+	return -code error "Shell \"$shell\" does not exist"
+    }
+    if {![file executable $shell]} {
+	return -code error "Shell \"$shell\" is not executable (permissions)"
+    }
+    return
+}
+
+proc ::platform::shell::LOCATE {bv ov} {
+    upvar 1 $bv base $ov out
+
+    # Locate the platform package for injection into the specified
+    # shell. We are using package management to find it, whereever it
+    # is, instead of using hardwired relative paths. This allows us to
+    # install the two packages as TMs without breaking the code
+    # here. If the found package is wrapped we copy the code somewhere
+    # where the spawned shell will be able to read it.
+
+    # This code is brittle, it needs has to adapt to whatever changes
+    # are made to the TM code, i.e. the provide statement generated by
+    # tm.tcl
+
+    set pl [package ifneeded platform [package require platform]]
+    set base [lindex $pl end]
+
+    set out 0
+    if {[lindex [file system $base]] ne "native"} {
+	set temp [TEMP]
+	file copy -force $base $temp
+	set base $temp
+	set out 1
+    }
+    return
+}
+
+proc ::platform::shell::RUN {shell code} {
+    set     c [TEMP]
+    set    cc [open $c w]
+    puts  $cc $code
+    close $cc
+
+    set e [TEMP]
+
+    set code [catch {
+        exec $shell $c 2> $e
+    } res]
+
+    file delete $c
+
+    if {$code} {
+	append res \n[read [set chan [open $e r]]][close $chan]
+	file delete $e
+	return -code error "Shell \"$shell\" is not executable ($res)"
+    }
+
+    file delete $e
+    return $res
+}
+
+proc ::platform::shell::TEMP {} {
+    set prefix platform
+
+    # This code is copied out of Tcllib's fileutil package.
+    # (TempFile/tempfile)
+
+    set tmpdir [DIR]
+
+    set chars "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
+    set nrand_chars 10
+    set maxtries 10
+    set access [list RDWR CREAT EXCL TRUNC]
+    set permission 0600
+    set channel ""
+    set checked_dir_writable 0
+    set mypid [pid]
+    for {set i 0} {$i < $maxtries} {incr i} {
+ 	set newname $prefix
+ 	for {set j 0} {$j < $nrand_chars} {incr j} {
+ 	    append newname [string index $chars \
+		    [expr {int(rand()*62)}]]
+ 	}
+	set newname [file join $tmpdir $newname]
+ 	if {[file exists $newname]} {
+ 	    after 1
+ 	} else {
+ 	    if {[catch {open $newname $access $permission} channel]} {
+ 		if {!$checked_dir_writable} {
+ 		    set dirname [file dirname $newname]
+ 		    if {![file writable $dirname]} {
+ 			return -code error "Directory $dirname is not writable"
+ 		    }
+ 		    set checked_dir_writable 1
+ 		}
+ 	    } else {
+ 		# Success
+		close $channel
+ 		return [file normalize $newname]
+ 	    }
+ 	}
+    }
+    if {$channel ne ""} {
+ 	return -code error "Failed to open a temporary file: $channel"
+    } else {
+ 	return -code error "Failed to find an unused temporary file name"
+    }
+}
+
+proc ::platform::shell::DIR {} {
+    # This code is copied out of Tcllib's fileutil package.
+    # (TempDir/tempdir)
+
+    global tcl_platform env
+
+    set attempdirs [list]
+
+    foreach tmp {TMPDIR TEMP TMP} {
+	if { [info exists env($tmp)] } {
+	    lappend attempdirs $env($tmp)
+	}
+    }
+
+    switch $tcl_platform(platform) {
+	windows {
+	    lappend attempdirs "C:\\TEMP" "C:\\TMP" "\\TEMP" "\\TMP"
+	}
+	macintosh {
+	    set tmpdir $env(TRASH_FOLDER)  ;# a better place?
+	}
+	default {
+	    lappend attempdirs \
+		[file join / tmp] \
+		[file join / var tmp] \
+		[file join / usr tmp]
+	}
+    }
+
+    lappend attempdirs [pwd]
+
+    foreach tmp $attempdirs {
+	if { [file isdirectory $tmp] && [file writable $tmp] } {
+	    return [file normalize $tmp]
+	}
+    }
+
+    # Fail if nothing worked.
+    return -code error "Unable to determine a proper directory for temporary files"
+}
+
+# ### ### ### ######### ######### #########
+## Ready
+
+package provide platform::shell 1.1.4
diff --git a/library/reg/pkgIndex.tcl b/library/reg/pkgIndex.tcl
new file mode 100755
index 0000000..b1fe234
--- /dev/null
+++ b/library/reg/pkgIndex.tcl
@@ -0,0 +1,9 @@
+if {([info commands ::tcl::pkgconfig] eq "")
+	|| ([info sharedlibextension] ne ".dll")} return
+if {[::tcl::pkgconfig get debug]} {
+    package ifneeded registry 1.3.2 \
+            [list load [file join $dir tclreg13g.dll] registry]
+} else {
+    package ifneeded registry 1.3.2 \
+            [list load [file join $dir tclreg13.dll] registry]
+}
diff --git a/library/safe.tcl b/library/safe.tcl
new file mode 100644
index 0000000..ea6391d
--- /dev/null
+++ b/library/safe.tcl
@@ -0,0 +1,1133 @@
+# safe.tcl --
+#
+# This file provide a safe loading/sourcing mechanism for safe interpreters.
+# It implements a virtual path mecanism to hide the real pathnames from the
+# slave. It runs in a master interpreter and sets up data structure and
+# aliases that will be invoked when used from a slave interpreter.
+#
+# See the safe.n man page for details.
+#
+# Copyright (c) 1996-1997 Sun Microsystems, Inc.
+#
+# See the file "license.terms" for information on usage and redistribution of
+# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+#
+# The implementation is based on namespaces. These naming conventions are
+# followed:
+# Private procs starts with uppercase.
+# Public  procs are exported and starts with lowercase
+#
+
+# Needed utilities package
+package require opt 0.4.1
+
+# Create the safe namespace
+namespace eval ::safe {
+    # Exported API:
+    namespace export interpCreate interpInit interpConfigure interpDelete \
+	interpAddToAccessPath interpFindInAccessPath setLogCmd
+}
+
+# Helper function to resolve the dual way of specifying staticsok (either
+# by -noStatics or -statics 0)
+proc ::safe::InterpStatics {} {
+    foreach v {Args statics noStatics} {
+	upvar $v $v
+    }
+    set flag [::tcl::OptProcArgGiven -noStatics]
+    if {$flag && (!$noStatics == !$statics)
+	&& ([::tcl::OptProcArgGiven -statics])} {
+	return -code error\
+	    "conflicting values given for -statics and -noStatics"
+    }
+    if {$flag} {
+	return [expr {!$noStatics}]
+    } else {
+	return $statics
+    }
+}
+
+# Helper function to resolve the dual way of specifying nested loading
+# (either by -nestedLoadOk or -nested 1)
+proc ::safe::InterpNested {} {
+    foreach v {Args nested nestedLoadOk} {
+	upvar $v $v
+    }
+    set flag [::tcl::OptProcArgGiven -nestedLoadOk]
+    # note that the test here is the opposite of the "InterpStatics" one
+    # (it is not -noNested... because of the wanted default value)
+    if {$flag && (!$nestedLoadOk != !$nested)
+	&& ([::tcl::OptProcArgGiven -nested])} {
+	return -code error\
+	    "conflicting values given for -nested and -nestedLoadOk"
+    }
+    if {$flag} {
+	# another difference with "InterpStatics"
+	return $nestedLoadOk
+    } else {
+	return $nested
+    }
+}
+
+####
+#
+#  API entry points that needs argument parsing :
+#
+####
+
+# Interface/entry point function and front end for "Create"
+proc ::safe::interpCreate {args} {
+    set Args [::tcl::OptKeyParse ::safe::interpCreate $args]
+    InterpCreate $slave $accessPath \
+	[InterpStatics] [InterpNested] $deleteHook
+}
+
+proc ::safe::interpInit {args} {
+    set Args [::tcl::OptKeyParse ::safe::interpIC $args]
+    if {![::interp exists $slave]} {
+	return -code error "\"$slave\" is not an interpreter"
+    }
+    InterpInit $slave $accessPath \
+	[InterpStatics] [InterpNested] $deleteHook
+}
+
+# Check that the given slave is "one of us"
+proc ::safe::CheckInterp {slave} {
+    namespace upvar ::safe S$slave state
+    if {![info exists state] || ![::interp exists $slave]} {
+	return -code error \
+	    "\"$slave\" is not an interpreter managed by ::safe::"
+    }
+}
+
+# Interface/entry point function and front end for "Configure".  This code
+# is awfully pedestrian because it would need more coupling and support
+# between the way we store the configuration values in safe::interp's and
+# the Opt package. Obviously we would like an OptConfigure to avoid
+# duplicating all this code everywhere.
+# -> TODO (the app should share or access easily the program/value stored
+# by opt)
+
+# This is even more complicated by the boolean flags with no values that
+# we had the bad idea to support for the sake of user simplicity in
+# create/init but which makes life hard in configure...
+# So this will be hopefully written and some integrated with opt1.0
+# (hopefully for tcl8.1 ?)
+proc ::safe::interpConfigure {args} {
+    switch [llength $args] {
+	1 {
+	    # If we have exactly 1 argument the semantic is to return all
+	    # the current configuration. We still call OptKeyParse though
+	    # we know that "slave" is our given argument because it also
+	    # checks for the "-help" option.
+	    set Args [::tcl::OptKeyParse ::safe::interpIC $args]
+	    CheckInterp $slave
+	    namespace upvar ::safe S$slave state
+
+	    return [join [list \
+		[list -accessPath $state(access_path)] \
+		[list -statics    $state(staticsok)]   \
+		[list -nested     $state(nestedok)]    \
+	        [list -deleteHook $state(cleanupHook)]]]
+	}
+	2 {
+	    # If we have exactly 2 arguments the semantic is a "configure
+	    # get"
+	    lassign $args slave arg
+
+	    # get the flag sub program (we 'know' about Opt's internal
+	    # representation of data)
+	    set desc [lindex [::tcl::OptKeyGetDesc ::safe::interpIC] 2]
+	    set hits [::tcl::OptHits desc $arg]
+	    if {$hits > 1} {
+		return -code error [::tcl::OptAmbigous $desc $arg]
+	    } elseif {$hits == 0} {
+		return -code error [::tcl::OptFlagUsage $desc $arg]
+	    }
+	    CheckInterp $slave
+	    namespace upvar ::safe S$slave state
+
+	    set item [::tcl::OptCurDesc $desc]
+	    set name [::tcl::OptName $item]
+	    switch -exact -- $name {
+		-accessPath {
+		    return [list -accessPath $state(access_path)]
+		}
+		-statics    {
+		    return [list -statics $state(staticsok)]
+		}
+		-nested     {
+		    return [list -nested $state(nestedok)]
+		}
+		-deleteHook {
+		    return [list -deleteHook $state(cleanupHook)]
+		}
+		-noStatics {
+		    # it is most probably a set in fact but we would need
+		    # then to jump to the set part and it is not *sure*
+		    # that it is a set action that the user want, so force
+		    # it to use the unambigous -statics ?value? instead:
+		    return -code error\
+			"ambigous query (get or set -noStatics ?)\
+				use -statics instead"
+		}
+		-nestedLoadOk {
+		    return -code error\
+			"ambigous query (get or set -nestedLoadOk ?)\
+				use -nested instead"
+		}
+		default {
+		    return -code error "unknown flag $name (bug)"
+		}
+	    }
+	}
+	default {
+	    # Otherwise we want to parse the arguments like init and
+	    # create did
+	    set Args [::tcl::OptKeyParse ::safe::interpIC $args]
+	    CheckInterp $slave
+	    namespace upvar ::safe S$slave state
+
+	    # Get the current (and not the default) values of whatever has
+	    # not been given:
+	    if {![::tcl::OptProcArgGiven -accessPath]} {
+		set doreset 1
+		set accessPath $state(access_path)
+	    } else {
+		set doreset 0
+	    }
+	    if {
+		![::tcl::OptProcArgGiven -statics]
+		&& ![::tcl::OptProcArgGiven -noStatics]
+	    } then {
+		set statics    $state(staticsok)
+	    } else {
+		set statics    [InterpStatics]
+	    }
+	    if {
+		[::tcl::OptProcArgGiven -nested] ||
+		[::tcl::OptProcArgGiven -nestedLoadOk]
+	    } then {
+		set nested     [InterpNested]
+	    } else {
+		set nested     $state(nestedok)
+	    }
+	    if {![::tcl::OptProcArgGiven -deleteHook]} {
+		set deleteHook $state(cleanupHook)
+	    }
+	    # we can now reconfigure :
+	    InterpSetConfig $slave $accessPath $statics $nested $deleteHook
+	    # auto_reset the slave (to completly synch the new access_path)
+	    if {$doreset} {
+		if {[catch {::interp eval $slave {auto_reset}} msg]} {
+		    Log $slave "auto_reset failed: $msg"
+		} else {
+		    Log $slave "successful auto_reset" NOTICE
+		}
+	    }
+	}
+    }
+}
+
+####
+#
+#  Functions that actually implements the exported APIs
+#
+####
+
+#
+# safe::InterpCreate : doing the real job
+#
+# This procedure creates a safe slave and initializes it with the safe
+# base aliases.
+# NB: slave name must be simple alphanumeric string, no spaces, no (), no
+# {},...  {because the state array is stored as part of the name}
+#
+# Returns the slave name.
+#
+# Optional Arguments :
+# + slave name : if empty, generated name will be used
+# + access_path: path list controlling where load/source can occur,
+#                if empty: the master auto_path will be used.
+# + staticsok  : flag, if 0 :no static package can be loaded (load {} Xxx)
+#                      if 1 :static packages are ok.
+# + nestedok: flag, if 0 :no loading to sub-sub interps (load xx xx sub)
+#                      if 1 : multiple levels are ok.
+
+# use the full name and no indent so auto_mkIndex can find us
+proc ::safe::InterpCreate {
+			   slave
+			   access_path
+			   staticsok
+			   nestedok
+			   deletehook
+		       } {
+    # Create the slave.
+    if {$slave ne ""} {
+	::interp create -safe $slave
+    } else {
+	# empty argument: generate slave name
+	set slave [::interp create -safe]
+    }
+    Log $slave "Created" NOTICE
+
+    # Initialize it. (returns slave name)
+    InterpInit $slave $access_path $staticsok $nestedok $deletehook
+}
+
+#
+# InterpSetConfig (was setAccessPath) :
+#    Sets up slave virtual auto_path and corresponding structure within
+#    the master. Also sets the tcl_library in the slave to be the first
+#    directory in the path.
+#    NB: If you change the path after the slave has been initialized you
+#    probably need to call "auto_reset" in the slave in order that it gets
+#    the right auto_index() array values.
+
+proc ::safe::InterpSetConfig {slave access_path staticsok nestedok deletehook} {
+    global auto_path
+
+    # determine and store the access path if empty
+    if {$access_path eq ""} {
+	set access_path $auto_path
+
+	# Make sure that tcl_library is in auto_path and at the first
+	# position (needed by setAccessPath)
+	set where [lsearch -exact $access_path [info library]]
+	if {$where == -1} {
+	    # not found, add it.
+	    set access_path [linsert $access_path 0 [info library]]
+	    Log $slave "tcl_library was not in auto_path,\
+			added it to slave's access_path" NOTICE
+	} elseif {$where != 0} {
+	    # not first, move it first
+	    set access_path [linsert \
+				 [lreplace $access_path $where $where] \
+				 0 [info library]]
+	    Log $slave "tcl_libray was not in first in auto_path,\
+			moved it to front of slave's access_path" NOTICE
+	}
+
+	# Add 1st level sub dirs (will searched by auto loading from tcl
+	# code in the slave using glob and thus fail, so we add them here
+	# so by default it works the same).
+	set access_path [AddSubDirs $access_path]
+    }
+
+    Log $slave "Setting accessPath=($access_path) staticsok=$staticsok\
+		nestedok=$nestedok deletehook=($deletehook)" NOTICE
+
+    namespace upvar ::safe S$slave state
+
+    # clear old autopath if it existed
+    # build new one
+    # Extend the access list with the paths used to look for Tcl Modules.
+    # We save the virtual form separately as well, as syncing it with the
+    # slave has to be defered until the necessary commands are present for
+    # setup.
+
+    set norm_access_path  {}
+    set slave_access_path {}
+    set map_access_path   {}
+    set remap_access_path {}
+    set slave_tm_path     {}
+
+    set i 0
+    foreach dir $access_path {
+	set token [PathToken $i]
+	lappend slave_access_path  $token
+	lappend map_access_path    $token $dir
+	lappend remap_access_path  $dir $token
+	lappend norm_access_path   [file normalize $dir]
+	incr i
+    }
+
+    set morepaths [::tcl::tm::list]
+    while {[llength $morepaths]} {
+	set addpaths $morepaths
+	set morepaths {}
+
+	foreach dir $addpaths {
+	    # Prevent the addition of dirs on the tm list to the
+	    # result if they are already known.
+	    if {[dict exists $remap_access_path $dir]} {
+		continue
+	    }
+
+	    set token [PathToken $i]
+	    lappend access_path        $dir
+	    lappend slave_access_path  $token
+	    lappend map_access_path    $token $dir
+	    lappend remap_access_path  $dir $token
+	    lappend norm_access_path   [file normalize $dir]
+	    lappend slave_tm_path $token
+	    incr i
+
+	    # [Bug 2854929]
+	    # Recursively find deeper paths which may contain
+	    # modules. Required to handle modules with names like
+	    # 'platform::shell', which translate into
+	    # 'platform/shell-X.tm', i.e arbitrarily deep
+	    # subdirectories.
+	    lappend morepaths {*}[glob -nocomplain -directory $dir -type d *]
+	}
+    }
+
+    set state(access_path)       $access_path
+    set state(access_path,map)   $map_access_path
+    set state(access_path,remap) $remap_access_path
+    set state(access_path,norm)  $norm_access_path
+    set state(access_path,slave) $slave_access_path
+    set state(tm_path_slave)     $slave_tm_path
+    set state(staticsok)         $staticsok
+    set state(nestedok)          $nestedok
+    set state(cleanupHook)       $deletehook
+
+    SyncAccessPath $slave
+}
+
+#
+#
+# FindInAccessPath:
+#    Search for a real directory and returns its virtual Id (including the
+#    "$")
+proc ::safe::interpFindInAccessPath {slave path} {
+    namespace upvar ::safe S$slave state
+
+    if {![dict exists $state(access_path,remap) $path]} {
+	return -code error "$path not found in access path $access_path"
+    }
+
+    return [dict get $state(access_path,remap) $path]
+}
+
+#
+# addToAccessPath:
+#    add (if needed) a real directory to access path and return its
+#    virtual token (including the "$").
+proc ::safe::interpAddToAccessPath {slave path} {
+    # first check if the directory is already in there
+    # (inlined interpFindInAccessPath).
+    namespace upvar ::safe S$slave state
+
+    if {[dict exists $state(access_path,remap) $path]} {
+	return [dict get $state(access_path,remap) $path]
+    }
+
+    # new one, add it:
+    set token [PathToken [llength $state(access_path)]]
+
+    lappend state(access_path)       $path
+    lappend state(access_path,slave) $token
+    lappend state(access_path,map)   $token $path
+    lappend state(access_path,remap) $path $token
+    lappend state(access_path,norm)  [file normalize $path]
+
+    SyncAccessPath $slave
+    return $token
+}
+
+# This procedure applies the initializations to an already existing
+# interpreter. It is useful when you want to install the safe base aliases
+# into a preexisting safe interpreter.
+proc ::safe::InterpInit {
+			 slave
+			 access_path
+			 staticsok
+			 nestedok
+			 deletehook
+		     } {
+    # Configure will generate an access_path when access_path is empty.
+    InterpSetConfig $slave $access_path $staticsok $nestedok $deletehook
+
+    # NB we need to add [namespace current], aliases are always absolute
+    # paths.
+
+    # These aliases let the slave load files to define new commands
+    # This alias lets the slave use the encoding names, convertfrom,
+    # convertto, and system, but not "encoding system <name>" to set the
+    # system encoding.
+    # Handling Tcl Modules, we need a restricted form of Glob.
+    # This alias interposes on the 'exit' command and cleanly terminates
+    # the slave.
+
+    foreach {command alias} {
+	source   AliasSource
+	load     AliasLoad
+	encoding AliasEncoding
+	exit     interpDelete
+	glob     AliasGlob
+    } {
+	::interp alias $slave $command {} [namespace current]::$alias $slave
+    }
+
+    # This alias lets the slave have access to a subset of the 'file'
+    # command functionality.
+
+    ::interp expose $slave file
+    foreach subcommand {dirname extension rootname tail} {
+	::interp alias $slave ::tcl::file::$subcommand {} \
+	    ::safe::AliasFileSubcommand $slave $subcommand
+    }
+    foreach subcommand {
+	atime attributes copy delete executable exists isdirectory isfile
+	link lstat mtime mkdir nativename normalize owned readable readlink
+	rename size stat tempfile type volumes writable
+    } {
+	::interp alias $slave ::tcl::file::$subcommand {} \
+	    ::safe::BadSubcommand $slave file $subcommand
+    }
+
+    # Subcommands of info
+    foreach {subcommand alias} {
+	nameofexecutable   AliasExeName
+    } {
+	::interp alias $slave ::tcl::info::$subcommand \
+	    {} [namespace current]::$alias $slave
+    }
+
+    # The allowed slave variables already have been set by Tcl_MakeSafe(3)
+
+    # Source init.tcl and tm.tcl into the slave, to get auto_load and
+    # other procedures defined:
+
+    if {[catch {::interp eval $slave {
+	source [file join $tcl_library init.tcl]
+    }} msg opt]} {
+	Log $slave "can't source init.tcl ($msg)"
+	return -options $opt "can't source init.tcl into slave $slave ($msg)"
+    }
+
+    if {[catch {::interp eval $slave {
+	source [file join $tcl_library tm.tcl]
+    }} msg opt]} {
+	Log $slave "can't source tm.tcl ($msg)"
+	return -options $opt "can't source tm.tcl into slave $slave ($msg)"
+    }
+
+    # Sync the paths used to search for Tcl modules. This can be done only
+    # now, after tm.tcl was loaded.
+    namespace upvar ::safe S$slave state
+    if {[llength $state(tm_path_slave)] > 0} {
+	::interp eval $slave [list \
+		::tcl::tm::add {*}[lreverse $state(tm_path_slave)]]
+    }
+    return $slave
+}
+
+# Add (only if needed, avoid duplicates) 1 level of sub directories to an
+# existing path list.  Also removes non directories from the returned
+# list.
+proc ::safe::AddSubDirs {pathList} {
+    set res {}
+    foreach dir $pathList {
+	if {[file isdirectory $dir]} {
+	    # check that we don't have it yet as a children of a previous
+	    # dir
+	    if {$dir ni $res} {
+		lappend res $dir
+	    }
+	    foreach sub [glob -directory $dir -nocomplain *] {
+		if {[file isdirectory $sub] && ($sub ni $res)} {
+		    # new sub dir, add it !
+		    lappend res $sub
+		}
+	    }
+	}
+    }
+    return $res
+}
+
+# This procedure deletes a safe slave managed by Safe Tcl and cleans up
+# associated state:
+
+proc ::safe::interpDelete {slave} {
+    Log $slave "About to delete" NOTICE
+
+    namespace upvar ::safe S$slave state
+
+    # If the slave has a cleanup hook registered, call it.  Check the
+    # existance because we might be called to delete an interp which has
+    # not been registered with us at all
+
+    if {[info exists state(cleanupHook)]} {
+	set hook $state(cleanupHook)
+	if {[llength $hook]} {
+	    # remove the hook now, otherwise if the hook calls us somehow,
+	    # we'll loop
+	    unset state(cleanupHook)
+	    try {
+		{*}$hook $slave
+	    } on error err {
+		Log $slave "Delete hook error ($err)"
+	    }
+	}
+    }
+
+    # Discard the global array of state associated with the slave, and
+    # delete the interpreter.
+
+    if {[info exists state]} {
+	unset state
+    }
+
+    # if we have been called twice, the interp might have been deleted
+    # already
+    if {[::interp exists $slave]} {
+	::interp delete $slave
+	Log $slave "Deleted" NOTICE
+    }
+
+    return
+}
+
+# Set (or get) the logging mecanism
+
+proc ::safe::setLogCmd {args} {
+    variable Log
+    set la [llength $args]
+    if {$la == 0} {
+	return $Log
+    } elseif {$la == 1} {
+	set Log [lindex $args 0]
+    } else {
+	set Log $args
+    }
+
+    if {$Log eq ""} {
+	# Disable logging completely. Calls to it will be compiled out
+	# of all users.
+	proc ::safe::Log {args} {}
+    } else {
+	# Activate logging, define proper command.
+
+	proc ::safe::Log {slave msg {type ERROR}} {
+	    variable Log
+	    {*}$Log "$type for slave $slave : $msg"
+	    return
+	}
+    }
+}
+
+# ------------------- END OF PUBLIC METHODS ------------
+
+#
+# Sets the slave auto_path to the master recorded value.  Also sets
+# tcl_library to the first token of the virtual path.
+#
+proc ::safe::SyncAccessPath {slave} {
+    namespace upvar ::safe S$slave state
+
+    set slave_access_path $state(access_path,slave)
+    ::interp eval $slave [list set auto_path $slave_access_path]
+
+    Log $slave "auto_path in $slave has been set to $slave_access_path"\
+	NOTICE
+
+    # This code assumes that info library is the first element in the
+    # list of auto_path's. See -> InterpSetConfig for the code which
+    # ensures this condition.
+
+    ::interp eval $slave [list \
+	      set tcl_library [lindex $slave_access_path 0]]
+}
+
+# Returns the virtual token for directory number N.
+proc ::safe::PathToken {n} {
+    # We need to have a ":" in the token string so [file join] on the
+    # mac won't turn it into a relative path.
+    return "\$p(:$n:)" ;# Form tested by case 7.2
+}
+
+#
+# translate virtual path into real path
+#
+proc ::safe::TranslatePath {slave path} {
+    namespace upvar ::safe S$slave state
+
+    # somehow strip the namespaces 'functionality' out (the danger is that
+    # we would strip valid macintosh "../" queries... :
+    if {[string match "*::*" $path] || [string match "*..*" $path]} {
+	return -code error "invalid characters in path $path"
+    }
+
+    # Use a cached map instead of computed local vars and subst.
+
+    return [string map $state(access_path,map) $path]
+}
+
+# file name control (limit access to files/resources that should be a
+# valid tcl source file)
+proc ::safe::CheckFileName {slave file} {
+    # This used to limit what can be sourced to ".tcl" and forbid files
+    # with more than 1 dot and longer than 14 chars, but I changed that
+    # for 8.4 as a safe interp has enough internal protection already to
+    # allow sourcing anything. - hobbs
+
+    if {![file exists $file]} {
+	# don't tell the file path
+	return -code error "no such file or directory"
+    }
+
+    if {![file readable $file]} {
+	# don't tell the file path
+	return -code error "not readable"
+    }
+}
+
+# AliasFileSubcommand handles selected subcommands of [file] in safe
+# interpreters that are *almost* safe. In particular, it just acts to
+# prevent discovery of what home directories exist.
+
+proc ::safe::AliasFileSubcommand {slave subcommand name} {
+    if {[string match ~* $name]} {
+	set name ./$name
+    }
+    tailcall ::interp invokehidden $slave tcl:file:$subcommand $name
+}
+
+# AliasGlob is the target of the "glob" alias in safe interpreters.
+
+proc ::safe::AliasGlob {slave args} {
+    Log $slave "GLOB ! $args" NOTICE
+    set cmd {}
+    set at 0
+    array set got {
+	-directory 0
+	-nocomplain 0
+	-join 0
+	-tails 0
+	-- 0
+    }
+
+    if {$::tcl_platform(platform) eq "windows"} {
+	set dirPartRE {^(.*)[\\/]([^\\/]*)$}
+    } else {
+	set dirPartRE {^(.*)/([^/]*)$}
+    }
+
+    set dir        {}
+    set virtualdir {}
+
+    while {$at < [llength $args]} {
+	switch -glob -- [set opt [lindex $args $at]] {
+	    -nocomplain - -- - -join - -tails {
+		lappend cmd $opt
+		set got($opt) 1
+		incr at
+	    }
+	    -types - -type {
+		lappend cmd -types [lindex $args [incr at]]
+		incr at
+	    }
+	    -directory {
+		if {$got($opt)} {
+		    return -code error \
+			{"-directory" cannot be used with "-path"}
+		}
+		set got($opt) 1
+		set virtualdir [lindex $args [incr at]]
+		incr at
+	    }
+	    pkgIndex.tcl {
+		# Oops, this is globbing a subdirectory in regular package
+		# search. That is not wanted. Abort, handler does catch
+		# already (because glob was not defined before). See
+		# package.tcl, lines 484ff in tclPkgUnknown.
+		return -code error "unknown command glob"
+	    }
+	    -* {
+		Log $slave "Safe base rejecting glob option '$opt'"
+		return -code error "Safe base rejecting glob option '$opt'"
+	    }
+	    default {
+		break
+	    }
+	}
+	if {$got(--)} break
+    }
+
+    # Get the real path from the virtual one and check that the path is in the
+    # access path of that slave. Done after basic argument processing so that
+    # we know if -nocomplain is set.
+    if {$got(-directory)} {
+	try {
+	    set dir [TranslatePath $slave $virtualdir]
+	    DirInAccessPath $slave $dir
+	} on error msg {
+	    Log $slave $msg
+	    if {$got(-nocomplain)} return
+	    return -code error "permission denied"
+	}
+	lappend cmd -directory $dir
+    }
+
+    # Apply the -join semantics ourselves
+    if {$got(-join)} {
+	set args [lreplace $args $at end [join [lrange $args $at end] "/"]]
+    }
+
+    # Process remaining pattern arguments
+    set firstPattern [llength $cmd]
+    foreach opt [lrange $args $at end] {
+	if {![regexp $dirPartRE $opt -> thedir thefile]} {
+	    set thedir .
+	} elseif {[string match ~* $thedir]} {
+	    set thedir ./$thedir
+	}
+	if {$thedir eq "*" &&
+		($thefile eq "pkgIndex.tcl" || $thefile eq "*.tm")} {
+	    set mapped 0
+	    foreach d [glob -directory [TranslatePath $slave $virtualdir] \
+			   -types d -tails *] {
+		catch {
+		    DirInAccessPath $slave \
+			[TranslatePath $slave [file join $virtualdir $d]]
+		    lappend cmd [file join $d $thefile]
+		    set mapped 1
+		}
+	    }
+	    if {$mapped} continue
+	}
+	try {
+	    DirInAccessPath $slave [TranslatePath $slave \
+		    [file join $virtualdir $thedir]]
+	} on error msg {
+	    Log $slave $msg
+	    if {$got(-nocomplain)} continue
+	    return -code error "permission denied"
+	}
+	lappend cmd $opt
+    }
+
+    Log $slave "GLOB = $cmd" NOTICE
+
+    if {$got(-nocomplain) && [llength $cmd] eq $firstPattern} {
+	return
+    }
+    try {
+	set entries [::interp invokehidden $slave glob {*}$cmd]
+    } on error msg {
+	Log $slave $msg
+	return -code error "script error"
+    }
+
+    Log $slave "GLOB < $entries" NOTICE
+
+    # Translate path back to what the slave should see.
+    set res {}
+    set l [string length $dir]
+    foreach p $entries {
+	if {[string equal -length $l $dir $p]} {
+	    set p [string replace $p 0 [expr {$l-1}] $virtualdir]
+	}
+	lappend res $p
+    }
+
+    Log $slave "GLOB > $res" NOTICE
+    return $res
+}
+
+# AliasSource is the target of the "source" alias in safe interpreters.
+
+proc ::safe::AliasSource {slave args} {
+    set argc [llength $args]
+    # Extended for handling of Tcl Modules to allow not only "source
+    # filename", but "source -encoding E filename" as well.
+    if {[lindex $args 0] eq "-encoding"} {
+	incr argc -2
+	set encoding [lindex $args 1]
+	set at 2
+	if {$encoding eq "identity"} {
+	    Log $slave "attempt to use the identity encoding"
+	    return -code error "permission denied"
+	}
+    } else {
+	set at 0
+	set encoding {}
+    }
+    if {$argc != 1} {
+	set msg "wrong # args: should be \"source ?-encoding E? fileName\""
+	Log $slave "$msg ($args)"
+	return -code error $msg
+    }
+    set file [lindex $args $at]
+
+    # get the real path from the virtual one.
+    if {[catch {
+	set realfile [TranslatePath $slave $file]
+    } msg]} {
+	Log $slave $msg
+	return -code error "permission denied"
+    }
+
+    # check that the path is in the access path of that slave
+    if {[catch {
+	FileInAccessPath $slave $realfile
+    } msg]} {
+	Log $slave $msg
+	return -code error "permission denied"
+    }
+
+    # do the checks on the filename :
+    if {[catch {
+	CheckFileName $slave $realfile
+    } msg]} {
+	Log $slave "$realfile:$msg"
+	return -code error $msg
+    }
+
+    # Passed all the tests, lets source it. Note that we do this all manually
+    # because we want to control [info script] in the slave so information
+    # doesn't leak so much. [Bug 2913625]
+    set old [::interp eval $slave {info script}]
+    set replacementMsg "script error"
+    set code [catch {
+	set f [open $realfile]
+	fconfigure $f -eofchar \032
+	if {$encoding ne ""} {
+	    fconfigure $f -encoding $encoding
+	}
+	set contents [read $f]
+	close $f
+	::interp eval $slave [list info script $file]
+    } msg opt]
+    if {$code == 0} {
+	set code [catch {::interp eval $slave $contents} msg opt]
+	set replacementMsg $msg
+    }
+    catch {interp eval $slave [list info script $old]}
+    # Note that all non-errors are fine result codes from [source], so we must
+    # take a little care to do it properly. [Bug 2923613]
+    if {$code == 1} {
+	Log $slave $msg
+	return -code error $replacementMsg
+    }
+    return -code $code -options $opt $msg
+}
+
+# AliasLoad is the target of the "load" alias in safe interpreters.
+
+proc ::safe::AliasLoad {slave file args} {
+    set argc [llength $args]
+    if {$argc > 2} {
+	set msg "load error: too many arguments"
+	Log $slave "$msg ($argc) {$file $args}"
+	return -code error $msg
+    }
+
+    # package name (can be empty if file is not).
+    set package [lindex $args 0]
+
+    namespace upvar ::safe S$slave state
+
+    # Determine where to load. load use a relative interp path and {}
+    # means self, so we can directly and safely use passed arg.
+    set target [lindex $args 1]
+    if {$target ne ""} {
+	# we will try to load into a sub sub interp; check that we want to
+	# authorize that.
+	if {!$state(nestedok)} {
+	    Log $slave "loading to a sub interp (nestedok)\
+			disabled (trying to load $package to $target)"
+	    return -code error "permission denied (nested load)"
+	}
+    }
+
+    # Determine what kind of load is requested
+    if {$file eq ""} {
+	# static package loading
+	if {$package eq ""} {
+	    set msg "load error: empty filename and no package name"
+	    Log $slave $msg
+	    return -code error $msg
+	}
+	if {!$state(staticsok)} {
+	    Log $slave "static packages loading disabled\
+			(trying to load $package to $target)"
+	    return -code error "permission denied (static package)"
+	}
+    } else {
+	# file loading
+
+	# get the real path from the virtual one.
+	try {
+	    set file [TranslatePath $slave $file]
+	} on error msg {
+	    Log $slave $msg
+	    return -code error "permission denied"
+	}
+
+	# check the translated path
+	try {
+	    FileInAccessPath $slave $file
+	} on error msg {
+	    Log $slave $msg
+	    return -code error "permission denied (path)"
+	}
+    }
+
+    try {
+	return [::interp invokehidden $slave load $file $package $target]
+    } on error msg {
+	Log $slave $msg
+	return -code error $msg
+    }
+}
+
+# FileInAccessPath raises an error if the file is not found in the list of
+# directories contained in the (master side recorded) slave's access path.
+
+# the security here relies on "file dirname" answering the proper
+# result... needs checking ?
+proc ::safe::FileInAccessPath {slave file} {
+    namespace upvar ::safe S$slave state
+    set access_path $state(access_path)
+
+    if {[file isdirectory $file]} {
+	return -code error "\"$file\": is a directory"
+    }
+    set parent [file dirname $file]
+
+    # Normalize paths for comparison since lsearch knows nothing of
+    # potential pathname anomalies.
+    set norm_parent [file normalize $parent]
+
+    namespace upvar ::safe S$slave state
+    if {$norm_parent ni $state(access_path,norm)} {
+	return -code error "\"$file\": not in access_path"
+    }
+}
+
+proc ::safe::DirInAccessPath {slave dir} {
+    namespace upvar ::safe S$slave state
+    set access_path $state(access_path)
+
+    if {[file isfile $dir]} {
+	return -code error "\"$dir\": is a file"
+    }
+
+    # Normalize paths for comparison since lsearch knows nothing of
+    # potential pathname anomalies.
+    set norm_dir [file normalize $dir]
+
+    namespace upvar ::safe S$slave state
+    if {$norm_dir ni $state(access_path,norm)} {
+	return -code error "\"$dir\": not in access_path"
+    }
+}
+
+# This procedure is used to report an attempt to use an unsafe member of an
+# ensemble command.
+
+proc ::safe::BadSubcommand {slave command subcommand args} {
+    set msg "not allowed to invoke subcommand $subcommand of $command"
+    Log $slave $msg
+    return -code error -errorcode {TCL SAFE SUBCOMMAND} $msg
+}
+
+# AliasEncoding is the target of the "encoding" alias in safe interpreters.
+
+proc ::safe::AliasEncoding {slave option args} {
+    # Note that [encoding dirs] is not supported in safe slaves at all
+    set subcommands {convertfrom convertto names system}
+    try {
+	set option [tcl::prefix match -error [list -level 1 -errorcode \
+		[list TCL LOOKUP INDEX option $option]] $subcommands $option]
+	# Special case: [encoding system] ok, but [encoding system foo] not
+	if {$option eq "system" && [llength $args]} {
+	    return -code error -errorcode {TCL WRONGARGS} \
+		"wrong # args: should be \"encoding system\""
+	}
+    } on error {msg options} {
+	Log $slave $msg
+	return -options $options $msg
+    }
+    tailcall ::interp invokehidden $slave encoding $option {*}$args
+}
+
+# Various minor hiding of platform features. [Bug 2913625]
+
+proc ::safe::AliasExeName {slave} {
+    return ""
+}
+
+proc ::safe::Setup {} {
+    ####
+    #
+    # Setup the arguments parsing
+    #
+    ####
+
+    # Share the descriptions
+    set temp [::tcl::OptKeyRegister {
+	{-accessPath -list {} "access path for the slave"}
+	{-noStatics "prevent loading of statically linked pkgs"}
+	{-statics true "loading of statically linked pkgs"}
+	{-nestedLoadOk "allow nested loading"}
+	{-nested false "nested loading"}
+	{-deleteHook -script {} "delete hook"}
+    }]
+
+    # create case (slave is optional)
+    ::tcl::OptKeyRegister {
+	{?slave? -name {} "name of the slave (optional)"}
+    } ::safe::interpCreate
+
+    # adding the flags sub programs to the command program (relying on Opt's
+    # internal implementation details)
+    lappend ::tcl::OptDesc(::safe::interpCreate) $::tcl::OptDesc($temp)
+
+    # init and configure (slave is needed)
+    ::tcl::OptKeyRegister {
+	{slave -name {} "name of the slave"}
+    } ::safe::interpIC
+
+    # adding the flags sub programs to the command program (relying on Opt's
+    # internal implementation details)
+    lappend ::tcl::OptDesc(::safe::interpIC) $::tcl::OptDesc($temp)
+
+    # temp not needed anymore
+    ::tcl::OptKeyDelete $temp
+
+    ####
+    #
+    # Default: No logging.
+    #
+    ####
+
+    setLogCmd {}
+
+    # Log eventually.
+    # To enable error logging, set Log to {puts stderr} for instance,
+    # via setLogCmd.
+    return
+}
+
+namespace eval ::safe {
+    # internal variables
+
+    # Log command, set via 'setLogCmd'. Logging is disabled when empty.
+    variable Log {}
+
+    # The package maintains a state array per slave interp under its
+    # control. The name of this array is S<interp-name>. This array is
+    # brought into scope where needed, using 'namespace upvar'. The S
+    # prefix is used to avoid that a slave interp called "Log" smashes
+    # the "Log" variable.
+    #
+    # The array's elements are:
+    #
+    # access_path       : List of paths accessible to the slave.
+    # access_path,norm  : Ditto, in normalized form.
+    # access_path,slave : Ditto, as the path tokens as seen by the slave.
+    # access_path,map   : dict ( token -> path )
+    # access_path,remap : dict ( path -> token )
+    # tm_path_slave     : List of TM root directories, as tokens seen by the slave.
+    # staticsok         : Value of option -statics
+    # nestedok          : Value of option -nested
+    # cleanupHook       : Value of option -deleteHook
+}
+
+::safe::Setup
diff --git a/library/tclIndex b/library/tclIndex
new file mode 100644
index 0000000..26603c1
--- /dev/null
+++ b/library/tclIndex
@@ -0,0 +1,75 @@
+# Tcl autoload index file, version 2.0
+# -*- tcl -*-
+# This file is generated by the "auto_mkindex" command
+# and sourced to set up indexing information for one or
+# more commands.  Typically each line is a command that
+# sets an element in the auto_index array, where the
+# element name is the name of a command and the value is
+# a script that loads the command.
+
+set auto_index(auto_reset) [list source [file join $dir auto.tcl]]
+set auto_index(tcl_findLibrary) [list source [file join $dir auto.tcl]]
+set auto_index(auto_mkindex) [list source [file join $dir auto.tcl]]
+set auto_index(auto_mkindex_old) [list source [file join $dir auto.tcl]]
+set auto_index(::auto_mkindex_parser::init) [list source [file join $dir auto.tcl]]
+set auto_index(::auto_mkindex_parser::cleanup) [list source [file join $dir auto.tcl]]
+set auto_index(::auto_mkindex_parser::mkindex) [list source [file join $dir auto.tcl]]
+set auto_index(::auto_mkindex_parser::hook) [list source [file join $dir auto.tcl]]
+set auto_index(::auto_mkindex_parser::slavehook) [list source [file join $dir auto.tcl]]
+set auto_index(::auto_mkindex_parser::command) [list source [file join $dir auto.tcl]]
+set auto_index(::auto_mkindex_parser::commandInit) [list source [file join $dir auto.tcl]]
+set auto_index(::auto_mkindex_parser::fullname) [list source [file join $dir auto.tcl]]
+set auto_index(history) [list source [file join $dir history.tcl]]
+set auto_index(::tcl::HistAdd) [list source [file join $dir history.tcl]]
+set auto_index(::tcl::HistKeep) [list source [file join $dir history.tcl]]
+set auto_index(::tcl::HistClear) [list source [file join $dir history.tcl]]
+set auto_index(::tcl::HistInfo) [list source [file join $dir history.tcl]]
+set auto_index(::tcl::HistRedo) [list source [file join $dir history.tcl]]
+set auto_index(::tcl::HistIndex) [list source [file join $dir history.tcl]]
+set auto_index(::tcl::HistEvent) [list source [file join $dir history.tcl]]
+set auto_index(::tcl::HistChange) [list source [file join $dir history.tcl]]
+set auto_index(pkg_mkIndex) [list source [file join $dir package.tcl]]
+set auto_index(tclPkgSetup) [list source [file join $dir package.tcl]]
+set auto_index(tclPkgUnknown) [list source [file join $dir package.tcl]]
+set auto_index(::tcl::MacOSXPkgUnknown) [list source [file join $dir package.tcl]]
+set auto_index(::pkg::create) [list source [file join $dir package.tcl]]
+set auto_index(parray) [list source [file join $dir parray.tcl]]
+set auto_index(::safe::InterpStatics) [list source [file join $dir safe.tcl]]
+set auto_index(::safe::InterpNested) [list source [file join $dir safe.tcl]]
+set auto_index(::safe::interpCreate) [list source [file join $dir safe.tcl]]
+set auto_index(::safe::interpInit) [list source [file join $dir safe.tcl]]
+set auto_index(::safe::CheckInterp) [list source [file join $dir safe.tcl]]
+set auto_index(::safe::interpConfigure) [list source [file join $dir safe.tcl]]
+set auto_index(::safe::InterpCreate) [list source [file join $dir safe.tcl]]
+set auto_index(::safe::InterpSetConfig) [list source [file join $dir safe.tcl]]
+set auto_index(::safe::interpFindInAccessPath) [list source [file join $dir safe.tcl]]
+set auto_index(::safe::interpAddToAccessPath) [list source [file join $dir safe.tcl]]
+set auto_index(::safe::InterpInit) [list source [file join $dir safe.tcl]]
+set auto_index(::safe::AddSubDirs) [list source [file join $dir safe.tcl]]
+set auto_index(::safe::interpDelete) [list source [file join $dir safe.tcl]]
+set auto_index(::safe::setLogCmd) [list source [file join $dir safe.tcl]]
+set auto_index(::safe::SyncAccessPath) [list source [file join $dir safe.tcl]]
+set auto_index(::safe::PathToken) [list source [file join $dir safe.tcl]]
+set auto_index(::safe::TranslatePath) [list source [file join $dir safe.tcl]]
+set auto_index(::safe::Log) [list source [file join $dir safe.tcl]]
+set auto_index(::safe::CheckFileName) [list source [file join $dir safe.tcl]]
+set auto_index(::safe::AliasGlob) [list source [file join $dir safe.tcl]]
+set auto_index(::safe::AliasSource) [list source [file join $dir safe.tcl]]
+set auto_index(::safe::AliasLoad) [list source [file join $dir safe.tcl]]
+set auto_index(::safe::FileInAccessPath) [list source [file join $dir safe.tcl]]
+set auto_index(::safe::DirInAccessPath) [list source [file join $dir safe.tcl]]
+set auto_index(::safe::Subset) [list source [file join $dir safe.tcl]]
+set auto_index(::safe::AliasSubset) [list source [file join $dir safe.tcl]]
+set auto_index(::safe::AliasEncoding) [list source [file join $dir safe.tcl]]
+set auto_index(tcl_wordBreakAfter) [list source [file join $dir word.tcl]]
+set auto_index(tcl_wordBreakBefore) [list source [file join $dir word.tcl]]
+set auto_index(tcl_endOfWord) [list source [file join $dir word.tcl]]
+set auto_index(tcl_startOfNextWord) [list source [file join $dir word.tcl]]
+set auto_index(tcl_startOfPreviousWord) [list source [file join $dir word.tcl]]
+set auto_index(::tcl::tm::add) [list source [file join $dir tm.tcl]]
+set auto_index(::tcl::tm::remove) [list source [file join $dir tm.tcl]]
+set auto_index(::tcl::tm::list) [list source [file join $dir tm.tcl]]
+set auto_index(::tcl::tm::Defaults) [list source [file join $dir tm.tcl]]
+set auto_index(::tcl::tm::UnknownHandler) [list source [file join $dir tm.tcl]]
+set auto_index(::tcl::tm::roots) [list source [file join $dir tm.tcl]]
+set auto_index(::tcl::tm::path) [list source [file join $dir tm.tcl]]
diff --git a/library/tcltest/pkgIndex.tcl b/library/tcltest/pkgIndex.tcl
new file mode 100644
index 0000000..5ac8823
--- /dev/null
+++ b/library/tcltest/pkgIndex.tcl
@@ -0,0 +1,12 @@
+# Tcl package index file, version 1.1
+# This file is generated by the "pkg_mkIndex -direct" command
+# and sourced either when an application starts up or
+# by a "package unknown" script.  It invokes the
+# "package ifneeded" command to set up package-related
+# information so that packages will be loaded automatically
+# in response to "package require" commands.  When this
+# script is sourced, the variable $dir must contain the
+# full path name of this file's directory.
+
+if {![package vsatisfies [package provide Tcl] 8.5]} {return}
+package ifneeded tcltest 2.4.0 [list source [file join $dir tcltest.tcl]]
diff --git a/library/tcltest/tcltest.tcl b/library/tcltest/tcltest.tcl
new file mode 100644
index 0000000..cde2660
--- /dev/null
+++ b/library/tcltest/tcltest.tcl
@@ -0,0 +1,3420 @@
+# tcltest.tcl --
+#
+#	This file contains support code for the Tcl test suite.  It
+#       defines the tcltest namespace and finds and defines the output
+#       directory, constraints available, output and error channels,
+#	etc. used by Tcl tests.  See the tcltest man page for more
+#	details.
+#
+#       This design was based on the Tcl testing approach designed and
+#       initially implemented by Mary Ann May-Pumphrey of Sun
+#	Microsystems.
+#
+# Copyright (c) 1994-1997 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+# Copyright (c) 2000 by Ajuba Solutions
+# Contributions from Don Porter, NIST, 2002.  (not subject to US copyright)
+# All rights reserved.
+
+package require Tcl 8.5		;# -verbose line uses [info frame]
+namespace eval tcltest {
+
+    # When the version number changes, be sure to update the pkgIndex.tcl file,
+    # and the install directory in the Makefiles.  When the minor version
+    # changes (new feature) be sure to update the man page as well.
+    variable Version 2.4.0
+
+    # Compatibility support for dumb variables defined in tcltest 1
+    # Do not use these.  Call [package provide Tcl] and [info patchlevel]
+    # yourself.  You don't need tcltest to wrap it for you.
+    variable version [package provide Tcl]
+    variable patchLevel [info patchlevel]
+
+##### Export the public tcltest procs; several categories
+    #
+    # Export the main functional commands that do useful things
+    namespace export cleanupTests loadTestedCommands makeDirectory \
+	makeFile removeDirectory removeFile runAllTests test
+
+    # Export configuration commands that control the functional commands
+    namespace export configure customMatch errorChannel interpreter \
+	    outputChannel testConstraint
+
+    # Export commands that are duplication (candidates for deprecation)
+    namespace export bytestring		;# dups [encoding convertfrom identity]
+    namespace export debug		;#	[configure -debug]
+    namespace export errorFile		;#	[configure -errfile]
+    namespace export limitConstraints	;#	[configure -limitconstraints]
+    namespace export loadFile		;#	[configure -loadfile]
+    namespace export loadScript		;#	[configure -load]
+    namespace export match		;#	[configure -match]
+    namespace export matchFiles		;#	[configure -file]
+    namespace export matchDirectories	;#	[configure -relateddir]
+    namespace export normalizeMsg	;#	application of [customMatch]
+    namespace export normalizePath	;#	[file normalize] (8.4)
+    namespace export outputFile		;#	[configure -outfile]
+    namespace export preserveCore	;#	[configure -preservecore]
+    namespace export singleProcess	;#	[configure -singleproc]
+    namespace export skip		;#	[configure -skip]
+    namespace export skipFiles		;#	[configure -notfile]
+    namespace export skipDirectories	;#	[configure -asidefromdir]
+    namespace export temporaryDirectory	;#	[configure -tmpdir]
+    namespace export testsDirectory	;#	[configure -testdir]
+    namespace export verbose		;#	[configure -verbose]
+    namespace export viewFile		;#	binary encoding [read]
+    namespace export workingDirectory	;#	[cd] [pwd]
+
+    # Export deprecated commands for tcltest 1 compatibility
+    namespace export getMatchingFiles mainThread restoreState saveState \
+	    threadReap
+
+    # tcltest::normalizePath --
+    #
+    #     This procedure resolves any symlinks in the path thus creating
+    #     a path without internal redirection. It assumes that the
+    #     incoming path is absolute.
+    #
+    # Arguments
+    #     pathVar - name of variable containing path to modify.
+    #
+    # Results
+    #     The path is modified in place.
+    #
+    # Side Effects:
+    #     None.
+    #
+    proc normalizePath {pathVar} {
+	upvar 1 $pathVar path
+	set oldpwd [pwd]
+	catch {cd $path}
+	set path [pwd]
+	cd $oldpwd
+	return $path
+    }
+
+##### Verification commands used to test values of variables and options
+    #
+    # Verification command that accepts everything
+    proc AcceptAll {value} {
+	return $value
+    }
+
+    # Verification command that accepts valid Tcl lists
+    proc AcceptList { list } {
+	return [lrange $list 0 end]
+    }
+
+    # Verification command that accepts a glob pattern
+    proc AcceptPattern { pattern } {
+	return [AcceptAll $pattern]
+    }
+
+    # Verification command that accepts integers
+    proc AcceptInteger { level } {
+	return [incr level 0]
+    }
+
+    # Verification command that accepts boolean values
+    proc AcceptBoolean { boolean } {
+	return [expr {$boolean && $boolean}]
+    }
+
+    # Verification command that accepts (syntactically) valid Tcl scripts
+    proc AcceptScript { script } {
+	if {![info complete $script]} {
+	    return -code error "invalid Tcl script: $script"
+	}
+	return $script
+    }
+
+    # Verification command that accepts (converts to) absolute pathnames
+    proc AcceptAbsolutePath { path } {
+	return [file join [pwd] $path]
+    }
+
+    # Verification command that accepts existing readable directories
+    proc AcceptReadable { path } {
+	if {![file readable $path]} {
+	    return -code error "\"$path\" is not readable"
+	}
+	return $path
+    }
+    proc AcceptDirectory { directory } {
+	set directory [AcceptAbsolutePath $directory]
+	if {![file exists $directory]} {
+	    return -code error "\"$directory\" does not exist"
+	}
+	if {![file isdir $directory]} {
+	    return -code error "\"$directory\" is not a directory"
+	}
+	return [AcceptReadable $directory]
+    }
+
+##### Initialize internal arrays of tcltest, but only if the caller
+    # has not already pre-initialized them.  This is done to support
+    # compatibility with older tests that directly access internals
+    # rather than go through command interfaces.
+    #
+    proc ArrayDefault {varName value} {
+	variable $varName
+	if {[array exists $varName]} {
+	    return
+	}
+	if {[info exists $varName]} {
+	    # Pre-initialized value is a scalar: destroy it!
+	    unset $varName
+	}
+	array set $varName $value
+    }
+
+    # save the original environment so that it can be restored later
+    ArrayDefault originalEnv [array get ::env]
+
+    # initialize numTests array to keep track of the number of tests
+    # that pass, fail, and are skipped.
+    ArrayDefault numTests [list Total 0 Passed 0 Skipped 0 Failed 0]
+
+    # createdNewFiles will store test files as indices and the list of
+    # files (that should not have been) left behind by the test files
+    # as values.
+    ArrayDefault createdNewFiles {}
+
+    # initialize skippedBecause array to keep track of constraints that
+    # kept tests from running; a constraint name of "userSpecifiedSkip"
+    # means that the test appeared on the list of tests that matched the
+    # -skip value given to the flag; "userSpecifiedNonMatch" means that
+    # the test didn't match the argument given to the -match flag; both
+    # of these constraints are counted only if tcltest::debug is set to
+    # true.
+    ArrayDefault skippedBecause {}
+
+    # initialize the testConstraints array to keep track of valid
+    # predefined constraints (see the explanation for the
+    # InitConstraints proc for more details).
+    ArrayDefault testConstraints {}
+
+##### Initialize internal variables of tcltest, but only if the caller
+    # has not already pre-initialized them.  This is done to support
+    # compatibility with older tests that directly access internals
+    # rather than go through command interfaces.
+    #
+    proc Default {varName value {verify AcceptAll}} {
+	variable $varName
+	if {![info exists $varName]} {
+	    variable $varName [$verify $value]
+	} else {
+	    variable $varName [$verify [set $varName]]
+	}
+    }
+
+    # Save any arguments that we might want to pass through to other
+    # programs.  This is used by the -args flag.
+    # FINDUSER
+    Default parameters {}
+
+    # Count the number of files tested (0 if runAllTests wasn't called).
+    # runAllTests will set testSingleFile to false, so stats will
+    # not be printed until runAllTests calls the cleanupTests proc.
+    # The currentFailure var stores the boolean value of whether the
+    # current test file has had any failures.  The failFiles list
+    # stores the names of test files that had failures.
+    Default numTestFiles 0 AcceptInteger
+    Default testSingleFile true AcceptBoolean
+    Default currentFailure false AcceptBoolean
+    Default failFiles {} AcceptList
+
+    # Tests should remove all files they create.  The test suite will
+    # check the current working dir for files created by the tests.
+    # filesMade keeps track of such files created using the makeFile and
+    # makeDirectory procedures.  filesExisted stores the names of
+    # pre-existing files.
+    #
+    # Note that $filesExisted lists only those files that exist in
+    # the original [temporaryDirectory].
+    Default filesMade {} AcceptList
+    Default filesExisted {} AcceptList
+    proc FillFilesExisted {} {
+	variable filesExisted
+
+	# Save the names of files that already exist in the scratch directory.
+	foreach file [glob -nocomplain -directory [temporaryDirectory] *] {
+	    lappend filesExisted [file tail $file]
+	}
+
+	# After successful filling, turn this into a no-op.
+	proc FillFilesExisted args {}
+    }
+
+    # Kept only for compatibility
+    Default constraintsSpecified {} AcceptList
+    trace add variable constraintsSpecified read [namespace code {
+	    set constraintsSpecified [array names testConstraints] ;#}]
+
+    # tests that use threads need to know which is the main thread
+    Default mainThread 1
+    variable mainThread
+    if {[info commands thread::id] ne {}} {
+	set mainThread [thread::id]
+    } elseif {[info commands testthread] ne {}} {
+	set mainThread [testthread id]
+    }
+
+    # Set workingDirectory to [pwd]. The default output directory for
+    # Tcl tests is the working directory.  Whenever this value changes
+    # change to that directory.
+    variable workingDirectory
+    trace add variable workingDirectory write \
+	    [namespace code {cd $workingDirectory ;#}]
+
+    Default workingDirectory [pwd] AcceptAbsolutePath
+    proc workingDirectory { {dir ""} } {
+	variable workingDirectory
+	if {[llength [info level 0]] == 1} {
+	    return $workingDirectory
+	}
+	set workingDirectory [AcceptAbsolutePath $dir]
+    }
+
+    # Set the location of the execuatble
+    Default tcltest [info nameofexecutable]
+    trace add variable tcltest write [namespace code {testConstraint stdio \
+	    [eval [ConstraintInitializer stdio]] ;#}]
+
+    # save the platform information so it can be restored later
+    Default originalTclPlatform [array get ::tcl_platform]
+
+    # If a core file exists, save its modification time.
+    if {[file exists [file join [workingDirectory] core]]} {
+	Default coreModTime \
+		[file mtime [file join [workingDirectory] core]]
+    }
+
+    # stdout and stderr buffers for use when we want to store them
+    Default outData {}
+    Default errData {}
+
+    # keep track of test level for nested test commands
+    variable testLevel 0
+
+    # the variables and procs that existed when saveState was called are
+    # stored in a variable of the same name
+    Default saveState {}
+
+    # Internationalization support -- used in [SetIso8859_1_Locale] and
+    # [RestoreLocale]. Those commands are used in cmdIL.test.
+
+    if {![info exists [namespace current]::isoLocale]} {
+	variable isoLocale fr
+	switch -- $::tcl_platform(platform) {
+	    "unix" {
+
+		# Try some 'known' values for some platforms:
+
+		switch -exact -- $::tcl_platform(os) {
+		    "FreeBSD" {
+			set isoLocale fr_FR.ISO_8859-1
+		    }
+		    HP-UX {
+			set isoLocale fr_FR.iso88591
+		    }
+		    Linux -
+		    IRIX {
+			set isoLocale fr
+		    }
+		    default {
+
+			# Works on SunOS 4 and Solaris, and maybe
+			# others...  Define it to something else on your
+			# system if you want to test those.
+
+			set isoLocale iso_8859_1
+		    }
+		}
+	    }
+	    "windows" {
+		set isoLocale French
+	    }
+	}
+    }
+
+    variable ChannelsWeOpened; array set ChannelsWeOpened {}
+    # output goes to stdout by default
+    Default outputChannel stdout
+    proc outputChannel { {filename ""} } {
+	variable outputChannel
+	variable ChannelsWeOpened
+
+	# This is very subtle and tricky, so let me try to explain.
+	# (Hopefully this longer comment will be clear when I come
+	# back in a few months, unlike its predecessor :) )
+	#
+	# The [outputChannel] command (and underlying variable) have to
+	# be kept in sync with the [configure -outfile] configuration
+	# option ( and underlying variable Option(-outfile) ).  This is
+	# accomplished with a write trace on Option(-outfile) that will
+	# update [outputChannel] whenver a new value is written.  That
+	# much is easy.
+	#
+	# The trick is that in order to maintain compatibility with
+	# version 1 of tcltest, we must allow every configuration option
+	# to get its inital value from command line arguments.  This is
+	# accomplished by setting initial read traces on all the
+	# configuration options to parse the command line option the first
+	# time they are read.  These traces are cancelled whenever the
+	# program itself calls [configure].
+	#
+	# OK, then so to support tcltest 1 compatibility, it seems we want
+	# to get the return from [outputFile] to trigger the read traces,
+	# just in case.
+	#
+	# BUT!  A little known feature of Tcl variable traces is that
+	# traces are disabled during the handling of other traces.  So,
+	# if we trigger read traces on Option(-outfile) and that triggers
+	# command line parsing which turns around and sets an initial
+	# value for Option(-outfile) -- <whew!> -- the write trace that
+	# would keep [outputChannel] in sync with that new initial value
+	# would not fire!
+	#
+	# SO, finally, as a workaround, instead of triggering read traces
+	# by invoking [outputFile], we instead trigger the same set of
+	# read traces by invoking [debug].  Any command that reads a
+	# configuration option would do.  [debug] is just a handy one.
+	# The end result is that we support tcltest 1 compatibility and
+	# keep outputChannel and -outfile in sync in all cases.
+	debug
+
+	if {[llength [info level 0]] == 1} {
+	    return $outputChannel
+	}
+	if {[info exists ChannelsWeOpened($outputChannel)]} {
+	    close $outputChannel
+	    unset ChannelsWeOpened($outputChannel)
+	}
+	switch -exact -- $filename {
+	    stderr -
+	    stdout {
+		set outputChannel $filename
+	    }
+	    default {
+		set outputChannel [open $filename a]
+		set ChannelsWeOpened($outputChannel) 1
+
+		# If we created the file in [temporaryDirectory], then
+		# [cleanupTests] will delete it, unless we claim it was
+		# already there.
+		set outdir [normalizePath [file dirname \
+			[file join [pwd] $filename]]]
+		if {$outdir eq [temporaryDirectory]} {
+		    variable filesExisted
+		    FillFilesExisted
+		    set filename [file tail $filename]
+		    if {$filename ni $filesExisted} {
+			lappend filesExisted $filename
+		    }
+		}
+	    }
+	}
+	return $outputChannel
+    }
+
+    # errors go to stderr by default
+    Default errorChannel stderr
+    proc errorChannel { {filename ""} } {
+	variable errorChannel
+	variable ChannelsWeOpened
+
+	# This is subtle and tricky.  See the comment above in
+	# [outputChannel] for a detailed explanation.
+	debug
+
+	if {[llength [info level 0]] == 1} {
+	    return $errorChannel
+	}
+	if {[info exists ChannelsWeOpened($errorChannel)]} {
+	    close $errorChannel
+	    unset ChannelsWeOpened($errorChannel)
+	}
+	switch -exact -- $filename {
+	    stderr -
+	    stdout {
+		set errorChannel $filename
+	    }
+	    default {
+		set errorChannel [open $filename a]
+		set ChannelsWeOpened($errorChannel) 1
+
+		# If we created the file in [temporaryDirectory], then
+		# [cleanupTests] will delete it, unless we claim it was
+		# already there.
+		set outdir [normalizePath [file dirname \
+			[file join [pwd] $filename]]]
+		if {$outdir eq [temporaryDirectory]} {
+		    variable filesExisted
+		    FillFilesExisted
+		    set filename [file tail $filename]
+		    if {$filename ni $filesExisted} {
+			lappend filesExisted $filename
+		    }
+		}
+	    }
+	}
+	return $errorChannel
+    }
+
+##### Set up the configurable options
+    #
+    # The configurable options of the package
+    variable Option; array set Option {}
+
+    # Usage strings for those options
+    variable Usage; array set Usage {}
+
+    # Verification commands for those options
+    variable Verify; array set Verify {}
+
+    # Initialize the default values of the configurable options that are
+    # historically associated with an exported variable.  If that variable
+    # is already set, support compatibility by accepting its pre-set value.
+    # Use [trace] to establish ongoing connection between the deprecated
+    # exported variable and the modern option kept as a true internal var.
+    # Also set up usage string and value testing for the option.
+    proc Option {option value usage {verify AcceptAll} {varName {}}} {
+	variable Option
+	variable Verify
+	variable Usage
+	variable OptionControlledVariables
+	variable DefaultValue
+	set Usage($option) $usage
+	set Verify($option) $verify
+	set DefaultValue($option) $value
+	if {[catch {$verify $value} msg]} {
+	    return -code error $msg
+	} else {
+	    set Option($option) $msg
+	}
+	if {[string length $varName]} {
+	    variable $varName
+	    if {[info exists $varName]} {
+		if {[catch {$verify [set $varName]} msg]} {
+		    return -code error $msg
+		} else {
+		    set Option($option) $msg
+		}
+		unset $varName
+	    }
+	    namespace eval [namespace current] \
+	    	    [list upvar 0 Option($option) $varName]
+	    # Workaround for Bug (now Feature Request) 572889.  Grrrr....
+	    # Track all the variables tied to options
+	    lappend OptionControlledVariables $varName
+	    # Later, set auto-configure read traces on all
+	    # of them, since a single trace on Option does not work.
+	    proc $varName {{value {}}} [subst -nocommands {
+		if {[llength [info level 0]] == 2} {
+		    Configure $option [set value]
+		}
+		return [Configure $option]
+	    }]
+	}
+    }
+
+    proc MatchingOption {option} {
+	variable Option
+	set match [array names Option $option*]
+	switch -- [llength $match] {
+	    0 {
+		set sorted [lsort [array names Option]]
+		set values [join [lrange $sorted 0 end-1] ", "]
+		append values ", or [lindex $sorted end]"
+		return -code error "unknown option $option: should be\
+			one of $values"
+	    }
+	    1 {
+		return [lindex $match 0]
+	    }
+	    default {
+		# Exact match trumps ambiguity
+		if {$option in $match} {
+		    return $option
+		}
+		set values [join [lrange $match 0 end-1] ", "]
+		append values ", or [lindex $match end]"
+		return -code error "ambiguous option $option:\
+			could match $values"
+	    }
+	}
+    }
+
+    proc EstablishAutoConfigureTraces {} {
+	variable OptionControlledVariables
+	foreach varName [concat $OptionControlledVariables Option] {
+	    variable $varName
+	    trace add variable $varName read [namespace code {
+		    ProcessCmdLineArgs ;#}]
+	}
+    }
+
+    proc RemoveAutoConfigureTraces {} {
+	variable OptionControlledVariables
+	foreach varName [concat $OptionControlledVariables Option] {
+	    variable $varName
+	    foreach pair [trace info variable $varName] {
+		lassign $pair op cmd
+		if {($op eq "read") &&
+			[string match *ProcessCmdLineArgs* $cmd]} {
+		    trace remove variable $varName $op $cmd
+		}
+	    }
+	}
+	# Once the traces are removed, this can become a no-op
+	proc RemoveAutoConfigureTraces {} {}
+    }
+
+    proc Configure args {
+	variable Option
+	variable Verify
+	set n [llength $args]
+	if {$n == 0} {
+	    return [lsort [array names Option]]
+	}
+	if {$n == 1} {
+	    if {[catch {MatchingOption [lindex $args 0]} option]} {
+		return -code error $option
+	    }
+	    return $Option($option)
+	}
+	while {[llength $args] > 1} {
+	    if {[catch {MatchingOption [lindex $args 0]} option]} {
+		return -code error $option
+	    }
+	    if {[catch {$Verify($option) [lindex $args 1]} value]} {
+		return -code error "invalid $option\
+			value \"[lindex $args 1]\": $value"
+	    }
+	    set Option($option) $value
+	    set args [lrange $args 2 end]
+	}
+	if {[llength $args]} {
+	    if {[catch {MatchingOption [lindex $args 0]} option]} {
+		return -code error $option
+	    }
+	    return -code error "missing value for option $option"
+	}
+    }
+    proc configure args {
+	if {[llength $args] > 1} {
+	    RemoveAutoConfigureTraces
+	}
+	set code [catch {Configure {*}$args} msg]
+	return -code $code $msg
+    }
+
+    proc AcceptVerbose { level } {
+	set level [AcceptList $level]
+	set levelMap {
+	    l list
+	    p pass
+	    b body
+	    s skip
+	    t start
+	    e error
+	    l line
+	    m msec
+	    u usec
+	}
+	set levelRegexp "^([join [dict values $levelMap] |])\$"
+	if {[llength $level] == 1} {
+	    if {![regexp $levelRegexp $level]} {
+		# translate single characters abbreviations to expanded list
+		set level [string map $levelMap [split $level {}]]
+	    }
+	}
+	set valid [list]
+	foreach v $level {
+	    if {[regexp $levelRegexp $v]} {
+		lappend valid $v
+	    }
+	}
+	return $valid
+    }
+
+    proc IsVerbose {level} {
+	variable Option
+	return [expr {[lsearch -exact $Option(-verbose) $level] != -1}]
+    }
+
+    # Default verbosity is to show bodies of failed tests
+    Option -verbose {body error} {
+	Takes any combination of the values 'p', 's', 'b', 't', 'e' and 'l'.
+	Test suite will display all passed tests if 'p' is specified, all
+	skipped tests if 's' is specified, the bodies of failed tests if
+	'b' is specified, and when tests start if 't' is specified.
+	ErrorInfo is displayed if 'e' is specified. Source file line
+	information of failed tests is displayed if 'l' is specified.
+    } AcceptVerbose verbose
+
+    # Match and skip patterns default to the empty list, except for
+    # matchFiles, which defaults to all .test files in the
+    # testsDirectory and matchDirectories, which defaults to all
+    # directories.
+    Option -match * {
+	Run all tests within the specified files that match one of the
+	list of glob patterns given.
+    } AcceptList match
+
+    Option -skip {} {
+	Skip all tests within the specified tests (via -match) and files
+	that match one of the list of glob patterns given.
+    } AcceptList skip
+
+    Option -file *.test {
+	Run tests in all test files that match the glob pattern given.
+    } AcceptPattern matchFiles
+
+    # By default, skip files that appear to be SCCS lock files.
+    Option -notfile l.*.test {
+	Skip all test files that match the glob pattern given.
+    } AcceptPattern skipFiles
+
+    Option -relateddir * {
+	Run tests in directories that match the glob pattern given.
+    } AcceptPattern matchDirectories
+
+    Option -asidefromdir {} {
+	Skip tests in directories that match the glob pattern given.
+    } AcceptPattern skipDirectories
+
+    # By default, don't save core files
+    Option -preservecore 0 {
+	If 2, save any core files produced during testing in the directory
+	specified by -tmpdir. If 1, notify the user if core files are
+	created.
+    } AcceptInteger preserveCore
+
+    # debug output doesn't get printed by default; debug level 1 spits
+    # up only the tests that were skipped because they didn't match or
+    # were specifically skipped.  A debug level of 2 would spit up the
+    # tcltest variables and flags provided; a debug level of 3 causes
+    # some additional output regarding operations of the test harness.
+    # The tcltest package currently implements only up to debug level 3.
+    Option -debug 0 {
+	Internal debug level
+    } AcceptInteger debug
+
+    proc SetSelectedConstraints args {
+	variable Option
+	foreach c $Option(-constraints) {
+	    testConstraint $c 1
+	}
+    }
+    Option -constraints {} {
+	Do not skip the listed constraints listed in -constraints.
+    } AcceptList
+    trace add variable Option(-constraints) write \
+	    [namespace code {SetSelectedConstraints ;#}]
+
+    # Don't run only the "-constraint" specified tests by default
+    proc ClearUnselectedConstraints args {
+	variable Option
+	variable testConstraints
+	if {!$Option(-limitconstraints)} {return}
+	foreach c [array names testConstraints] {
+	    if {$c ni $Option(-constraints)} {
+		testConstraint $c 0
+	    }
+	}
+    }
+    Option -limitconstraints 0 {
+	whether to run only tests with the constraints
+    } AcceptBoolean limitConstraints
+    trace add variable Option(-limitconstraints) write \
+	    [namespace code {ClearUnselectedConstraints ;#}]
+
+    # A test application has to know how to load the tested commands
+    # into the interpreter.
+    Option -load {} {
+	Specifies the script to load the tested commands.
+    } AcceptScript loadScript
+
+    # Default is to run each test file in a separate process
+    Option -singleproc 0 {
+	whether to run all tests in one process
+    } AcceptBoolean singleProcess
+
+    proc AcceptTemporaryDirectory { directory } {
+	set directory [AcceptAbsolutePath $directory]
+	if {![file exists $directory]} {
+	    file mkdir $directory
+	}
+	set directory [AcceptDirectory $directory]
+	if {![file writable $directory]} {
+	    if {[workingDirectory] eq $directory} {
+		# Special exception: accept the default value
+		# even if the directory is not writable
+		return $directory
+	    }
+	    return -code error "\"$directory\" is not writeable"
+	}
+	return $directory
+    }
+
+    # Directory where files should be created
+    Option -tmpdir [workingDirectory] {
+	Save temporary files in the specified directory.
+    } AcceptTemporaryDirectory temporaryDirectory
+    trace add variable Option(-tmpdir) write \
+	    [namespace code {normalizePath Option(-tmpdir) ;#}]
+
+    # Tests should not rely on the current working directory.
+    # Files that are part of the test suite should be accessed relative
+    # to [testsDirectory]
+    Option -testdir [workingDirectory] {
+	Search tests in the specified directory.
+    } AcceptDirectory testsDirectory
+    trace add variable Option(-testdir) write \
+	    [namespace code {normalizePath Option(-testdir) ;#}]
+
+    proc AcceptLoadFile { file } {
+	if {$file eq {}} {return $file}
+	set file [file join [temporaryDirectory] $file]
+	return [AcceptReadable $file]
+    }
+    proc ReadLoadScript {args} {
+	variable Option
+	if {$Option(-loadfile) eq {}} {return}
+	set tmp [open $Option(-loadfile) r]
+	loadScript [read $tmp]
+	close $tmp
+    }
+    Option -loadfile {} {
+	Read the script to load the tested commands from the specified file.
+    } AcceptLoadFile loadFile
+    trace add variable Option(-loadfile) write [namespace code ReadLoadScript]
+
+    proc AcceptOutFile { file } {
+	if {[string equal stderr $file]} {return $file}
+	if {[string equal stdout $file]} {return $file}
+	return [file join [temporaryDirectory] $file]
+    }
+
+    # output goes to stdout by default
+    Option -outfile stdout {
+	Send output from test runs to the specified file.
+    } AcceptOutFile outputFile
+    trace add variable Option(-outfile) write \
+	    [namespace code {outputChannel $Option(-outfile) ;#}]
+
+    # errors go to stderr by default
+    Option -errfile stderr {
+	Send errors from test runs to the specified file.
+    } AcceptOutFile errorFile
+    trace add variable Option(-errfile) write \
+	    [namespace code {errorChannel $Option(-errfile) ;#}]
+
+    proc loadIntoSlaveInterpreter {slave args} {
+	variable Version
+	interp eval $slave [package ifneeded tcltest $Version]
+	interp eval $slave "tcltest::configure {*}{$args}"
+	interp alias $slave ::tcltest::ReportToMaster \
+	    {} ::tcltest::ReportedFromSlave
+    }
+    proc ReportedFromSlave {total passed skipped failed because newfiles} {
+	variable numTests
+	variable skippedBecause
+	variable createdNewFiles
+	incr numTests(Total)   $total
+	incr numTests(Passed)  $passed
+	incr numTests(Skipped) $skipped
+	incr numTests(Failed)  $failed
+	foreach {constraint count} $because {
+	    incr skippedBecause($constraint) $count
+	}
+	foreach {testfile created} $newfiles {
+	    lappend createdNewFiles($testfile) {*}$created
+	}
+	return
+    }
+}
+
+#####################################################################
+
+# tcltest::Debug* --
+#
+#     Internal helper procedures to write out debug information
+#     dependent on the chosen level. A test shell may overide
+#     them, f.e. to redirect the output into a different
+#     channel, or even into a GUI.
+
+# tcltest::DebugPuts --
+#
+#     Prints the specified string if the current debug level is
+#     higher than the provided level argument.
+#
+# Arguments:
+#     level   The lowest debug level triggering the output
+#     string  The string to print out.
+#
+# Results:
+#     Prints the string. Nothing else is allowed.
+#
+# Side Effects:
+#     None.
+#
+
+proc tcltest::DebugPuts {level string} {
+    variable debug
+    if {$debug >= $level} {
+	puts $string
+    }
+    return
+}
+
+# tcltest::DebugPArray --
+#
+#     Prints the contents of the specified array if the current
+#       debug level is higher than the provided level argument
+#
+# Arguments:
+#     level           The lowest debug level triggering the output
+#     arrayvar        The name of the array to print out.
+#
+# Results:
+#     Prints the contents of the array. Nothing else is allowed.
+#
+# Side Effects:
+#     None.
+#
+
+proc tcltest::DebugPArray {level arrayvar} {
+    variable debug
+
+    if {$debug >= $level} {
+	catch {upvar 1 $arrayvar $arrayvar}
+	parray $arrayvar
+    }
+    return
+}
+
+# Define our own [parray] in ::tcltest that will inherit use of the [puts]
+# defined in ::tcltest.  NOTE: Ought to construct with [info args] and
+# [info default], but can't be bothered now.  If [parray] changes, then
+# this will need changing too.
+auto_load ::parray
+proc tcltest::parray {a {pattern *}} [info body ::parray]
+
+# tcltest::DebugDo --
+#
+#     Executes the script if the current debug level is greater than
+#       the provided level argument
+#
+# Arguments:
+#     level   The lowest debug level triggering the execution.
+#     script  The tcl script executed upon a debug level high enough.
+#
+# Results:
+#     Arbitrary side effects, dependent on the executed script.
+#
+# Side Effects:
+#     None.
+#
+
+proc tcltest::DebugDo {level script} {
+    variable debug
+
+    if {$debug >= $level} {
+	uplevel 1 $script
+    }
+    return
+}
+
+#####################################################################
+
+proc tcltest::Warn {msg} {
+    puts [outputChannel] "WARNING: $msg"
+}
+
+# tcltest::mainThread
+#
+#     Accessor command for tcltest variable mainThread.
+#
+proc tcltest::mainThread { {new ""} } {
+    variable mainThread
+    if {[llength [info level 0]] == 1} {
+	return $mainThread
+    }
+    set mainThread $new
+}
+
+# tcltest::testConstraint --
+#
+#	sets a test constraint to a value; to do multiple constraints,
+#       call this proc multiple times.  also returns the value of the
+#       named constraint if no value was supplied.
+#
+# Arguments:
+#	constraint - name of the constraint
+#       value - new value for constraint (should be boolean) - if not
+#               supplied, this is a query
+#
+# Results:
+#	content of tcltest::testConstraints($constraint)
+#
+# Side effects:
+#	none
+
+proc tcltest::testConstraint {constraint {value ""}} {
+    variable testConstraints
+    variable Option
+    DebugPuts 3 "entering testConstraint $constraint $value"
+    if {[llength [info level 0]] == 2} {
+	return $testConstraints($constraint)
+    }
+    # Check for boolean values
+    if {[catch {expr {$value && $value}} msg]} {
+	return -code error $msg
+    }
+    if {[limitConstraints] && ($constraint ni $Option(-constraints))} {
+	set value 0
+    }
+    set testConstraints($constraint) $value
+}
+
+# tcltest::interpreter --
+#
+#	the interpreter name stored in tcltest::tcltest
+#
+# Arguments:
+#	executable name
+#
+# Results:
+#	content of tcltest::tcltest
+#
+# Side effects:
+#	None.
+
+proc tcltest::interpreter { {interp ""} } {
+    variable tcltest
+    if {[llength [info level 0]] == 1} {
+	return $tcltest
+    }
+    set tcltest $interp
+}
+
+#####################################################################
+
+# tcltest::AddToSkippedBecause --
+#
+#	Increments the variable used to track how many tests were
+#       skipped because of a particular constraint.
+#
+# Arguments:
+#	constraint     The name of the constraint to be modified
+#
+# Results:
+#	Modifies tcltest::skippedBecause; sets the variable to 1 if
+#       didn't previously exist - otherwise, it just increments it.
+#
+# Side effects:
+#	None.
+
+proc tcltest::AddToSkippedBecause { constraint {value 1}} {
+    # add the constraint to the list of constraints that kept tests
+    # from running
+    variable skippedBecause
+
+    if {[info exists skippedBecause($constraint)]} {
+	incr skippedBecause($constraint) $value
+    } else {
+	set skippedBecause($constraint) $value
+    }
+    return
+}
+
+# tcltest::PrintError --
+#
+#	Prints errors to tcltest::errorChannel and then flushes that
+#       channel, making sure that all messages are < 80 characters per
+#       line.
+#
+# Arguments:
+#	errorMsg     String containing the error to be printed
+#
+# Results:
+#	None.
+#
+# Side effects:
+#	None.
+
+proc tcltest::PrintError {errorMsg} {
+    set InitialMessage "Error:  "
+    set InitialMsgLen  [string length $InitialMessage]
+    puts -nonewline [errorChannel] $InitialMessage
+
+    # Keep track of where the end of the string is.
+    set endingIndex [string length $errorMsg]
+
+    if {$endingIndex < (80 - $InitialMsgLen)} {
+	puts [errorChannel] $errorMsg
+    } else {
+	# Print up to 80 characters on the first line, including the
+	# InitialMessage.
+	set beginningIndex [string last " " [string range $errorMsg 0 \
+		[expr {80 - $InitialMsgLen}]]]
+	puts [errorChannel] [string range $errorMsg 0 $beginningIndex]
+
+	while {$beginningIndex ne "end"} {
+	    puts -nonewline [errorChannel] \
+		    [string repeat " " $InitialMsgLen]
+	    if {($endingIndex - $beginningIndex)
+		    < (80 - $InitialMsgLen)} {
+		puts [errorChannel] [string trim \
+			[string range $errorMsg $beginningIndex end]]
+		break
+	    } else {
+		set newEndingIndex [expr {[string last " " \
+			[string range $errorMsg $beginningIndex \
+				[expr {$beginningIndex
+					+ (80 - $InitialMsgLen)}]
+		]] + $beginningIndex}]
+		if {($newEndingIndex <= 0)
+			|| ($newEndingIndex <= $beginningIndex)} {
+		    set newEndingIndex end
+		}
+		puts [errorChannel] [string trim \
+			[string range $errorMsg \
+			    $beginningIndex $newEndingIndex]]
+		set beginningIndex $newEndingIndex
+	    }
+	}
+    }
+    flush [errorChannel]
+    return
+}
+
+# tcltest::SafeFetch --
+#
+#	 The following trace procedure makes it so that we can safely
+#        refer to non-existent members of the testConstraints array
+#        without causing an error.  Instead, reading a non-existent
+#        member will return 0. This is necessary because tests are
+#        allowed to use constraint "X" without ensuring that
+#        testConstraints("X") is defined.
+#
+# Arguments:
+#	n1 - name of the array (testConstraints)
+#       n2 - array key value (constraint name)
+#       op - operation performed on testConstraints (generally r)
+#
+# Results:
+#	none
+#
+# Side effects:
+#	sets testConstraints($n2) to 0 if it's referenced but never
+#       before used
+
+proc tcltest::SafeFetch {n1 n2 op} {
+    variable testConstraints
+    DebugPuts 3 "entering SafeFetch $n1 $n2 $op"
+    if {$n2 eq {}} {return}
+    if {![info exists testConstraints($n2)]} {
+	if {[catch {testConstraint $n2 [eval [ConstraintInitializer $n2]]}]} {
+	    testConstraint $n2 0
+	}
+    }
+}
+
+# tcltest::ConstraintInitializer --
+#
+#	Get or set a script that when evaluated in the tcltest namespace
+#	will return a boolean value with which to initialize the
+#	associated constraint.
+#
+# Arguments:
+#	constraint - name of the constraint initialized by the script
+#	script - the initializer script
+#
+# Results
+#	boolean value of the constraint - enabled or disabled
+#
+# Side effects:
+#	Constraint is initialized for future reference by [test]
+proc tcltest::ConstraintInitializer {constraint {script ""}} {
+    variable ConstraintInitializer
+    DebugPuts 3 "entering ConstraintInitializer $constraint $script"
+    if {[llength [info level 0]] == 2} {
+	return $ConstraintInitializer($constraint)
+    }
+    # Check for boolean values
+    if {![info complete $script]} {
+	return -code error "ConstraintInitializer must be complete script"
+    }
+    set ConstraintInitializer($constraint) $script
+}
+
+# tcltest::InitConstraints --
+#
+# Call all registered constraint initializers to force initialization
+# of all known constraints.
+# See the tcltest man page for the list of built-in constraints defined
+# in this procedure.
+#
+# Arguments:
+#	none
+#
+# Results:
+#	The testConstraints array is reset to have an index for each
+#	built-in test constraint.
+#
+# Side Effects:
+#       None.
+#
+
+proc tcltest::InitConstraints {} {
+    variable ConstraintInitializer
+    initConstraintsHook
+    foreach constraint [array names ConstraintInitializer] {
+	testConstraint $constraint
+    }
+}
+
+proc tcltest::DefineConstraintInitializers {} {
+    ConstraintInitializer singleTestInterp {singleProcess}
+
+    # All the 'pc' constraints are here for backward compatibility and
+    # are not documented.  They have been replaced with equivalent 'win'
+    # constraints.
+
+    ConstraintInitializer unixOnly \
+	    {string equal $::tcl_platform(platform) unix}
+    ConstraintInitializer macOnly \
+	    {string equal $::tcl_platform(platform) macintosh}
+    ConstraintInitializer pcOnly \
+	    {string equal $::tcl_platform(platform) windows}
+    ConstraintInitializer winOnly \
+	    {string equal $::tcl_platform(platform) windows}
+
+    ConstraintInitializer unix {testConstraint unixOnly}
+    ConstraintInitializer mac {testConstraint macOnly}
+    ConstraintInitializer pc {testConstraint pcOnly}
+    ConstraintInitializer win {testConstraint winOnly}
+
+    ConstraintInitializer unixOrPc \
+	    {expr {[testConstraint unix] || [testConstraint pc]}}
+    ConstraintInitializer macOrPc \
+	    {expr {[testConstraint mac] || [testConstraint pc]}}
+    ConstraintInitializer unixOrWin \
+	    {expr {[testConstraint unix] || [testConstraint win]}}
+    ConstraintInitializer macOrWin \
+	    {expr {[testConstraint mac] || [testConstraint win]}}
+    ConstraintInitializer macOrUnix \
+	    {expr {[testConstraint mac] || [testConstraint unix]}}
+
+    ConstraintInitializer nt {string equal $::tcl_platform(os) "Windows NT"}
+    ConstraintInitializer 95 {string equal $::tcl_platform(os) "Windows 95"}
+    ConstraintInitializer 98 {string equal $::tcl_platform(os) "Windows 98"}
+
+    # The following Constraints switches are used to mark tests that
+    # should work, but have been temporarily disabled on certain
+    # platforms because they don't and we haven't gotten around to
+    # fixing the underlying problem.
+
+    ConstraintInitializer tempNotPc {expr {![testConstraint pc]}}
+    ConstraintInitializer tempNotWin {expr {![testConstraint win]}}
+    ConstraintInitializer tempNotMac {expr {![testConstraint mac]}}
+    ConstraintInitializer tempNotUnix {expr {![testConstraint unix]}}
+
+    # The following Constraints switches are used to mark tests that
+    # crash on certain platforms, so that they can be reactivated again
+    # when the underlying problem is fixed.
+
+    ConstraintInitializer pcCrash {expr {![testConstraint pc]}}
+    ConstraintInitializer winCrash {expr {![testConstraint win]}}
+    ConstraintInitializer macCrash {expr {![testConstraint mac]}}
+    ConstraintInitializer unixCrash {expr {![testConstraint unix]}}
+
+    # Skip empty tests
+
+    ConstraintInitializer emptyTest {format 0}
+
+    # By default, tests that expose known bugs are skipped.
+
+    ConstraintInitializer knownBug {format 0}
+
+    # By default, non-portable tests are skipped.
+
+    ConstraintInitializer nonPortable {format 0}
+
+    # Some tests require user interaction.
+
+    ConstraintInitializer userInteraction {format 0}
+
+    # Some tests must be skipped if the interpreter is not in
+    # interactive mode
+
+    ConstraintInitializer interactive \
+	    {expr {[info exists ::tcl_interactive] && $::tcl_interactive}}
+
+    # Some tests can only be run if the installation came from a CD
+    # image instead of a web image.  Some tests must be skipped if you
+    # are running as root on Unix.  Other tests can only be run if you
+    # are running as root on Unix.
+
+    ConstraintInitializer root {expr \
+	    {($::tcl_platform(platform) eq "unix") &&
+		    ($::tcl_platform(user) in {root {}})}}
+    ConstraintInitializer notRoot {expr {![testConstraint root]}}
+
+    # Set nonBlockFiles constraint: 1 means this platform supports
+    # setting files into nonblocking mode.
+
+    ConstraintInitializer nonBlockFiles {
+	    set code [expr {[catch {set f [open defs r]}]
+		    || [catch {chan configure $f -blocking off}]}]
+	    catch {close $f}
+	    set code
+    }
+
+    # Set asyncPipeClose constraint: 1 means this platform supports
+    # async flush and async close on a pipe.
+    #
+    # Test for SCO Unix - cannot run async flushing tests because a
+    # potential problem with select is apparently interfering.
+    # (Mark Diekhans).
+
+    ConstraintInitializer asyncPipeClose {expr {
+	    !([string equal unix $::tcl_platform(platform)]
+	    && ([catch {exec uname -X | fgrep {Release = 3.2v}}] == 0))}}
+
+    # Test to see if we have a broken version of sprintf with respect
+    # to the "e" format of floating-point numbers.
+
+    ConstraintInitializer eformat {string equal [format %g 5e-5] 5e-05}
+
+    # Test to see if execed commands such as cat, echo, rm and so forth
+    # are present on this machine.
+
+    ConstraintInitializer unixExecs {
+	set code 1
+        if {$::tcl_platform(platform) eq "macintosh"} {
+	    set code 0
+        }
+        if {$::tcl_platform(platform) eq "windows"} {
+	    if {[catch {
+	        set file _tcl_test_remove_me.txt
+	        makeFile {hello} $file
+	    }]} {
+	        set code 0
+	    } elseif {
+	        [catch {exec cat $file}] ||
+	        [catch {exec echo hello}] ||
+	        [catch {exec sh -c echo hello}] ||
+	        [catch {exec wc $file}] ||
+	        [catch {exec sleep 1}] ||
+	        [catch {exec echo abc > $file}] ||
+	        [catch {exec chmod 644 $file}] ||
+	        [catch {exec rm $file}] ||
+	        [llength [auto_execok mkdir]] == 0 ||
+	        [llength [auto_execok fgrep]] == 0 ||
+	        [llength [auto_execok grep]] == 0 ||
+	        [llength [auto_execok ps]] == 0
+	    } {
+	        set code 0
+	    }
+	    removeFile $file
+        }
+	set code
+    }
+
+    ConstraintInitializer stdio {
+	set code 0
+	if {![catch {set f [open "|[list [interpreter]]" w]}]} {
+	    if {![catch {puts $f exit}]} {
+		if {![catch {close $f}]} {
+		    set code 1
+		}
+	    }
+	}
+	set code
+    }
+
+    # Deliberately call socket with the wrong number of arguments.  The
+    # error message you get will indicate whether sockets are available
+    # on this system.
+
+    ConstraintInitializer socket {
+	catch {socket} msg
+	string compare $msg "sockets are not available on this system"
+    }
+
+    # Check for internationalization
+    ConstraintInitializer hasIsoLocale {
+	if {[llength [info commands testlocale]] == 0} {
+	    set code 0
+	} else {
+	    set code [string length [SetIso8859_1_Locale]]
+	    RestoreLocale
+	}
+	set code
+    }
+
+}
+#####################################################################
+
+# Usage and command line arguments processing.
+
+# tcltest::PrintUsageInfo
+#
+#	Prints out the usage information for package tcltest.  This can
+#	be customized with the redefinition of [PrintUsageInfoHook].
+#
+# Arguments:
+#	none
+#
+# Results:
+#       none
+#
+# Side Effects:
+#       none
+proc tcltest::PrintUsageInfo {} {
+    puts [Usage]
+    PrintUsageInfoHook
+}
+
+proc tcltest::Usage { {option ""} } {
+    variable Usage
+    variable Verify
+    if {[llength [info level 0]] == 1} {
+	set msg "Usage: [file tail [info nameofexecutable]] script "
+	append msg "?-help? ?flag value? ... \n"
+	append msg "Available flags (and valid input values) are:"
+
+	set max 0
+	set allOpts [concat -help [Configure]]
+	foreach opt $allOpts {
+	    set foo [Usage $opt]
+	    lassign $foo x type($opt) usage($opt)
+	    set line($opt) "  $opt $type($opt)  "
+	    set length($opt) [string length $line($opt)]
+	    if {$length($opt) > $max} {set max $length($opt)}
+	}
+	set rest [expr {72 - $max}]
+	foreach opt $allOpts {
+	    append msg \n$line($opt)
+	    append msg [string repeat " " [expr {$max - $length($opt)}]]
+	    set u [string trim $usage($opt)]
+	    catch {append u "  (default: \[[Configure $opt]])"}
+	    regsub -all {\s*\n\s*} $u " " u
+	    while {[string length $u] > $rest} {
+		set break [string wordstart $u $rest]
+		if {$break == 0} {
+		    set break [string wordend $u 0]
+		}
+		append msg [string range $u 0 [expr {$break - 1}]]
+		set u [string trim [string range $u $break end]]
+		append msg \n[string repeat " " $max]
+	    }
+	    append msg $u
+	}
+	return $msg\n
+    } elseif {$option eq "-help"} {
+	return [list -help "" "Display this usage information."]
+    } else {
+	set type [lindex [info args $Verify($option)] 0]
+	return [list $option $type $Usage($option)]
+    }
+}
+
+# tcltest::ProcessFlags --
+#
+#	process command line arguments supplied in the flagArray - this
+#	is called by processCmdLineArgs.  Modifies tcltest variables
+#	according to the content of the flagArray.
+#
+# Arguments:
+#	flagArray - array containing name/value pairs of flags
+#
+# Results:
+#	sets tcltest variables according to their values as defined by
+#       flagArray
+#
+# Side effects:
+#	None.
+
+proc tcltest::ProcessFlags {flagArray} {
+    # Process -help first
+    if {"-help" in $flagArray} {
+	PrintUsageInfo
+	exit 1
+    }
+
+    if {[llength $flagArray] == 0} {
+	RemoveAutoConfigureTraces
+    } else {
+	set args $flagArray
+	while {[llength $args] > 1 && [catch {configure {*}$args} msg]} {
+
+	    # Something went wrong parsing $args for tcltest options
+	    # Check whether the problem is "unknown option"
+	    if {[regexp {^unknown option (\S+):} $msg -> option]} {
+		# Could be this is an option the Hook knows about
+		set moreOptions [processCmdLineArgsAddFlagsHook]
+		if {$option ni $moreOptions} {
+		    # Nope.  Report the error, including additional options,
+		    # but keep going
+		    if {[llength $moreOptions]} {
+			append msg ", "
+			append msg [join [lrange $moreOptions 0 end-1] ", "]
+			append msg "or [lindex $moreOptions end]"
+		    }
+		    Warn $msg
+		}
+	    } else {
+		# error is something other than "unknown option"
+		# notify user of the error; and exit
+		puts [errorChannel] $msg
+		exit 1
+	    }
+
+	    # To recover, find that unknown option and remove up to it.
+	    # then retry
+	    while {[lindex $args 0] ne $option} {
+		set args [lrange $args 2 end]
+	    }
+	    set args [lrange $args 2 end]
+	}
+	if {[llength $args] == 1} {
+	    puts [errorChannel] \
+		    "missing value for option [lindex $args 0]"
+	    exit 1
+	}
+    }
+
+    # Call the hook
+    catch {
+        array set flag $flagArray
+        processCmdLineArgsHook [array get flag]
+    }
+    return
+}
+
+# tcltest::ProcessCmdLineArgs --
+#
+#       This procedure must be run after constraint initialization is
+#	set up (by [DefineConstraintInitializers]) because some constraints
+#	can be overridden.
+#
+#       Perform configuration according to the command-line options.
+#
+# Arguments:
+#	none
+#
+# Results:
+#	Sets the above-named variables in the tcltest namespace.
+#
+# Side Effects:
+#       None.
+#
+
+proc tcltest::ProcessCmdLineArgs {} {
+    variable originalEnv
+    variable testConstraints
+
+    # The "argv" var doesn't exist in some cases, so use {}.
+    if {![info exists ::argv]} {
+	ProcessFlags {}
+    } else {
+	ProcessFlags $::argv
+    }
+
+    # Spit out everything you know if we're at a debug level 2 or
+    # greater
+    DebugPuts 2 "Flags passed into tcltest:"
+    if {[info exists ::env(TCLTEST_OPTIONS)]} {
+	DebugPuts 2 \
+		"    ::env(TCLTEST_OPTIONS): $::env(TCLTEST_OPTIONS)"
+    }
+    if {[info exists ::argv]} {
+	DebugPuts 2 "    argv: $::argv"
+    }
+    DebugPuts    2 "tcltest::debug              = [debug]"
+    DebugPuts    2 "tcltest::testsDirectory     = [testsDirectory]"
+    DebugPuts    2 "tcltest::workingDirectory   = [workingDirectory]"
+    DebugPuts    2 "tcltest::temporaryDirectory = [temporaryDirectory]"
+    DebugPuts    2 "tcltest::outputChannel      = [outputChannel]"
+    DebugPuts    2 "tcltest::errorChannel       = [errorChannel]"
+    DebugPuts    2 "Original environment (tcltest::originalEnv):"
+    DebugPArray  2 originalEnv
+    DebugPuts    2 "Constraints:"
+    DebugPArray  2 testConstraints
+}
+
+#####################################################################
+
+# Code to run the tests goes here.
+
+# tcltest::TestPuts --
+#
+#	Used to redefine puts in test environment.  Stores whatever goes
+#	out on stdout in tcltest::outData and stderr in errData before
+#	sending it on to the regular puts.
+#
+# Arguments:
+#	same as standard puts
+#
+# Results:
+#	none
+#
+# Side effects:
+#       Intercepts puts; data that would otherwise go to stdout, stderr,
+#	or file channels specified in outputChannel and errorChannel
+#	does not get sent to the normal puts function.
+namespace eval tcltest::Replace {
+    namespace export puts
+}
+proc tcltest::Replace::puts {args} {
+    variable [namespace parent]::outData
+    variable [namespace parent]::errData
+    switch [llength $args] {
+	1 {
+	    # Only the string to be printed is specified
+	    append outData [lindex $args 0]\n
+	    return
+	    # return [Puts [lindex $args 0]]
+	}
+	2 {
+	    # Either -nonewline or channelId has been specified
+	    if {[lindex $args 0] eq "-nonewline"} {
+		append outData [lindex $args end]
+		return
+		# return [Puts -nonewline [lindex $args end]]
+	    } else {
+		set channel [lindex $args 0]
+		set newline \n
+	    }
+	}
+	3 {
+	    if {[lindex $args 0] eq "-nonewline"} {
+		# Both -nonewline and channelId are specified, unless
+		# it's an error.  -nonewline is supposed to be argv[0].
+		set channel [lindex $args 1]
+		set newline ""
+	    }
+	}
+    }
+
+    if {[info exists channel]} {
+	if {$channel in [list [[namespace parent]::outputChannel] stdout]} {
+	    append outData [lindex $args end]$newline
+	    return
+	} elseif {$channel in [list [[namespace parent]::errorChannel] stderr]} {
+	    append errData [lindex $args end]$newline
+	    return
+	}
+    }
+
+    # If we haven't returned by now, we don't know how to handle the
+    # input.  Let puts handle it.
+    return [Puts {*}$args]
+}
+
+# tcltest::Eval --
+#
+#	Evaluate the script in the test environment.  If ignoreOutput is
+#       false, store data sent to stderr and stdout in outData and
+#       errData.  Otherwise, ignore this output altogether.
+#
+# Arguments:
+#	script             Script to evaluate
+#       ?ignoreOutput?     Indicates whether or not to ignore output
+#			   sent to stdout & stderr
+#
+# Results:
+#	result from running the script
+#
+# Side effects:
+#	Empties the contents of outData and errData before running a
+#	test if ignoreOutput is set to 0.
+
+proc tcltest::Eval {script {ignoreOutput 1}} {
+    variable outData
+    variable errData
+    DebugPuts 3 "[lindex [info level 0] 0] called"
+    if {!$ignoreOutput} {
+	set outData {}
+	set errData {}
+	rename ::puts [namespace current]::Replace::Puts
+	namespace eval :: [list namespace import [namespace origin Replace::puts]]
+	namespace import Replace::puts
+    }
+    set result [uplevel 1 $script]
+    if {!$ignoreOutput} {
+	namespace forget puts
+	namespace eval :: namespace forget puts
+	rename [namespace current]::Replace::Puts ::puts
+    }
+    return $result
+}
+
+# tcltest::CompareStrings --
+#
+#	compares the expected answer to the actual answer, depending on
+#	the mode provided.  Mode determines whether a regexp, exact,
+#	glob or custom comparison is done.
+#
+# Arguments:
+#	actual - string containing the actual result
+#       expected - pattern to be matched against
+#       mode - type of comparison to be done
+#
+# Results:
+#	result of the match
+#
+# Side effects:
+#	None.
+
+proc tcltest::CompareStrings {actual expected mode} {
+    variable CustomMatch
+    if {![info exists CustomMatch($mode)]} {
+        return -code error "No matching command registered for `-match $mode'"
+    }
+    set match [namespace eval :: $CustomMatch($mode) [list $expected $actual]]
+    if {[catch {expr {$match && $match}} result]} {
+	return -code error "Invalid result from `-match $mode' command: $result"
+    }
+    return $match
+}
+
+# tcltest::customMatch --
+#
+#	registers a command to be called when a particular type of
+#	matching is required.
+#
+# Arguments:
+#	nickname - Keyword for the type of matching
+#	cmd - Incomplete command that implements that type of matching
+#		when completed with expected string and actual string
+#		and then evaluated.
+#
+# Results:
+#	None.
+#
+# Side effects:
+#	Sets the variable tcltest::CustomMatch
+
+proc tcltest::customMatch {mode script} {
+    variable CustomMatch
+    if {![info complete $script]} {
+	return -code error \
+		"invalid customMatch script; can't evaluate after completion"
+    }
+    set CustomMatch($mode) $script
+}
+
+# tcltest::SubstArguments list
+#
+# This helper function takes in a list of words, then perform a
+# substitution on the list as though each word in the list is a separate
+# argument to the Tcl function.  For example, if this function is
+# invoked as:
+#
+#      SubstArguments {$a {$a}}
+#
+# Then it is as though the function is invoked as:
+#
+#      SubstArguments $a {$a}
+#
+# This code is adapted from Paul Duffin's function "SplitIntoWords".
+# The original function can be found  on:
+#
+#      http://purl.org/thecliff/tcl/wiki/858.html
+#
+# Results:
+#     a list containing the result of the substitution
+#
+# Exceptions:
+#     An error may occur if the list containing unbalanced quote or
+#     unknown variable.
+#
+# Side Effects:
+#     None.
+#
+
+proc tcltest::SubstArguments {argList} {
+
+    # We need to split the argList up into tokens but cannot use list
+    # operations as they throw away some significant quoting, and
+    # [split] ignores braces as it should.  Therefore what we do is
+    # gradually build up a string out of whitespace seperated strings.
+    # We cannot use [split] to split the argList into whitespace
+    # separated strings as it throws away the whitespace which maybe
+    # important so we have to do it all by hand.
+
+    set result {}
+    set token ""
+
+    while {[string length $argList]} {
+        # Look for the next word containing a quote: " { }
+        if {[regexp -indices {[^ \t\n]*[\"\{\}]+[^ \t\n]*} \
+		$argList all]} {
+            # Get the text leading up to this word, but not including
+	    # this word, from the argList.
+            set text [string range $argList 0 \
+		    [expr {[lindex $all 0] - 1}]]
+            # Get the word with the quote
+            set word [string range $argList \
+                    [lindex $all 0] [lindex $all 1]]
+
+            # Remove all text up to and including the word from the
+            # argList.
+            set argList [string range $argList \
+                    [expr {[lindex $all 1] + 1}] end]
+        } else {
+            # Take everything up to the end of the argList.
+            set text $argList
+            set word {}
+            set argList {}
+        }
+
+        if {$token ne {}} {
+            # If we saw a word with quote before, then there is a
+            # multi-word token starting with that word.  In this case,
+            # add the text and the current word to this token.
+            append token $text $word
+        } else {
+            # Add the text to the result.  There is no need to parse
+            # the text because it couldn't be a part of any multi-word
+            # token.  Then start a new multi-word token with the word
+            # because we need to pass this token to the Tcl parser to
+            # check for balancing quotes
+            append result $text
+            set token $word
+        }
+
+        if { [catch {llength $token} length] == 0 && $length == 1} {
+            # The token is a valid list so add it to the result.
+            # lappend result [string trim $token]
+            append result \{$token\}
+            set token {}
+        }
+    }
+
+    # If the last token has not been added to the list then there
+    # is a problem.
+    if { [string length $token] } {
+        error "incomplete token \"$token\""
+    }
+
+    return $result
+}
+
+
+# tcltest::test --
+#
+# This procedure runs a test and prints an error message if the test
+# fails.  If verbose has been set, it also prints a message even if the
+# test succeeds.  The test will be skipped if it doesn't match the
+# match variable, if it matches an element in skip, or if one of the
+# elements of "constraints" turns out not to be true.
+#
+# If testLevel is 1, then this is a top level test, and we record
+# pass/fail information; otherwise, this information is not logged and
+# is not added to running totals.
+#
+# Attributes:
+#   Only description is a required attribute.  All others are optional.
+#   Default values are indicated.
+#
+#   constraints -	A list of one or more keywords, each of which
+#			must be the name of an element in the array
+#			"testConstraints".  If any of these elements is
+#			zero, the test is skipped. This attribute is
+#			optional; default is {}
+#   body -	        Script to run to carry out the test.  It must
+#		        return a result that can be checked for
+#		        correctness.  This attribute is optional;
+#                       default is {}
+#   result -	        Expected result from script.  This attribute is
+#                       optional; default is {}.
+#   output -            Expected output sent to stdout.  This attribute
+#                       is optional; default is {}.
+#   errorOutput -       Expected output sent to stderr.  This attribute
+#                       is optional; default is {}.
+#   returnCodes -       Expected return codes.  This attribute is
+#                       optional; default is {0 2}.
+#   setup -             Code to run before $script (above).  This
+#                       attribute is optional; default is {}.
+#   cleanup -           Code to run after $script (above).  This
+#                       attribute is optional; default is {}.
+#   match -             specifies type of matching to do on result,
+#                       output, errorOutput; this must be a string
+#			previously registered by a call to [customMatch].
+#			The strings exact, glob, and regexp are pre-registered
+#			by the tcltest package.  Default value is exact.
+#
+# Arguments:
+#   name -		Name of test, in the form foo-1.2.
+#   description -	Short textual description of the test, to
+#  		  	help humans understand what it does.
+#
+# Results:
+#	None.
+#
+# Side effects:
+#       Just about anything is possible depending on the test.
+#
+
+proc tcltest::test {name description args} {
+    global tcl_platform
+    variable testLevel
+    variable coreModTime
+    DebugPuts 3 "test $name $args"
+    DebugDo 1 {
+	variable TestNames
+	catch {
+	    puts "test name '$name' re-used; prior use in $TestNames($name)"
+	}
+	set TestNames($name) [info script]
+    }
+
+    FillFilesExisted
+    incr testLevel
+
+    # Pre-define everything to null except output and errorOutput.  We
+    # determine whether or not to trap output based on whether or not
+    # these variables (output & errorOutput) are defined.
+    lassign {} constraints setup cleanup body result returnCodes match
+
+    # Set the default match mode
+    set match exact
+
+    # Set the default match values for return codes (0 is the standard
+    # expected return value if everything went well; 2 represents
+    # 'return' being used in the test script).
+    set returnCodes [list 0 2]
+
+    # The old test format can't have a 3rd argument (constraints or
+    # script) that starts with '-'.
+    if {[string match -* [lindex $args 0]] || ([llength $args] <= 1)} {
+	if {[llength $args] == 1} {
+	    set list [SubstArguments [lindex $args 0]]
+	    foreach {element value} $list {
+		set testAttributes($element) $value
+	    }
+	    foreach item {constraints match setup body cleanup \
+		    result returnCodes output errorOutput} {
+		if {[info exists testAttributes(-$item)]} {
+		    set testAttributes(-$item) [uplevel 1 \
+			    ::concat $testAttributes(-$item)]
+		}
+	    }
+	} else {
+	    array set testAttributes $args
+	}
+
+	set validFlags {-setup -cleanup -body -result -returnCodes \
+		-match -output -errorOutput -constraints}
+
+	foreach flag [array names testAttributes] {
+	    if {$flag ni $validFlags} {
+		incr testLevel -1
+		set sorted [lsort $validFlags]
+		set options [join [lrange $sorted 0 end-1] ", "]
+		append options ", or [lindex $sorted end]"
+		return -code error "bad option \"$flag\": must be $options"
+	    }
+	}
+
+	# store whatever the user gave us
+	foreach item [array names testAttributes] {
+	    set [string trimleft $item "-"] $testAttributes($item)
+	}
+
+	# Check the values supplied for -match
+	variable CustomMatch
+	if {$match ni [array names CustomMatch]} {
+	    incr testLevel -1
+	    set sorted [lsort [array names CustomMatch]]
+	    set values [join [lrange $sorted 0 end-1] ", "]
+	    append values ", or [lindex $sorted end]"
+	    return -code error "bad -match value \"$match\":\
+		    must be $values"
+	}
+
+	# Replace symbolic valies supplied for -returnCodes
+	foreach {strcode numcode} {ok 0 normal 0 error 1 return 2 break 3 continue 4} {
+	    set returnCodes [string map -nocase [list $strcode $numcode] $returnCodes]
+	}
+    } else {
+	# This is parsing for the old test command format; it is here
+	# for backward compatibility.
+	set result [lindex $args end]
+	if {[llength $args] == 2} {
+	    set body [lindex $args 0]
+	} elseif {[llength $args] == 3} {
+	    set constraints [lindex $args 0]
+	    set body [lindex $args 1]
+	} else {
+	    incr testLevel -1
+	    return -code error "wrong # args:\
+		    should be \"test name desc ?options?\""
+	}
+    }
+
+    if {[Skipped $name $constraints]} {
+	incr testLevel -1
+	return
+    }
+
+    # Save information about the core file.
+    if {[preserveCore]} {
+	if {[file exists [file join [workingDirectory] core]]} {
+	    set coreModTime [file mtime [file join [workingDirectory] core]]
+	}
+    }
+
+    # First, run the setup script
+    set code [catch {uplevel 1 $setup} setupMsg]
+    if {$code == 1} {
+	set errorInfo(setup) $::errorInfo
+	set errorCode(setup) $::errorCode
+    }
+    set setupFailure [expr {$code != 0}]
+
+    # Only run the test body if the setup was successful
+    if {!$setupFailure} {
+
+	# Register startup time
+	if {[IsVerbose msec] || [IsVerbose usec]} {
+	    set timeStart [clock microseconds]
+	}
+
+	# Verbose notification of $body start
+	if {[IsVerbose start]} {
+	    puts [outputChannel] "---- $name start"
+	    flush [outputChannel]
+	}
+
+	set command [list [namespace origin RunTest] $name $body]
+	if {[info exists output] || [info exists errorOutput]} {
+	    set testResult [uplevel 1 [list [namespace origin Eval] $command 0]]
+	} else {
+	    set testResult [uplevel 1 [list [namespace origin Eval] $command 1]]
+	}
+	lassign $testResult actualAnswer returnCode
+	if {$returnCode == 1} {
+	    set errorInfo(body) $::errorInfo
+	    set errorCode(body) $::errorCode
+	}
+    }
+
+    # check if the return code matched the expected return code
+    set codeFailure 0
+    if {!$setupFailure && ($returnCode ni $returnCodes)} {
+	set codeFailure 1
+    }
+
+    # If expected output/error strings exist, we have to compare
+    # them.  If the comparison fails, then so did the test.
+    set outputFailure 0
+    variable outData
+    if {[info exists output] && !$codeFailure} {
+	if {[set outputCompare [catch {
+	    CompareStrings $outData $output $match
+	} outputMatch]] == 0} {
+	    set outputFailure [expr {!$outputMatch}]
+	} else {
+	    set outputFailure 1
+	}
+    }
+
+    set errorFailure 0
+    variable errData
+    if {[info exists errorOutput] && !$codeFailure} {
+	if {[set errorCompare [catch {
+	    CompareStrings $errData $errorOutput $match
+	} errorMatch]] == 0} {
+	    set errorFailure [expr {!$errorMatch}]
+	} else {
+	    set errorFailure 1
+	}
+    }
+
+    # check if the answer matched the expected answer
+    # Only check if we ran the body of the test (no setup failure)
+    if {$setupFailure || $codeFailure} {
+	set scriptFailure 0
+    } elseif {[set scriptCompare [catch {
+	CompareStrings $actualAnswer $result $match
+    } scriptMatch]] == 0} {
+	set scriptFailure [expr {!$scriptMatch}]
+    } else {
+	set scriptFailure 1
+    }
+
+    # Always run the cleanup script
+    set code [catch {uplevel 1 $cleanup} cleanupMsg]
+    if {$code == 1} {
+	set errorInfo(cleanup) $::errorInfo
+	set errorCode(cleanup) $::errorCode
+    }
+    set cleanupFailure [expr {$code != 0}]
+
+    set coreFailure 0
+    set coreMsg ""
+    # check for a core file first - if one was created by the test,
+    # then the test failed
+    if {[preserveCore]} {
+	if {[file exists [file join [workingDirectory] core]]} {
+	    # There's only a test failure if there is a core file
+	    # and (1) there previously wasn't one or (2) the new
+	    # one is different from the old one.
+	    if {[info exists coreModTime]} {
+		if {$coreModTime != [file mtime \
+			[file join [workingDirectory] core]]} {
+		    set coreFailure 1
+		}
+	    } else {
+		set coreFailure 1
+	    }
+
+	    if {([preserveCore] > 1) && ($coreFailure)} {
+		append coreMsg "\nMoving file to:\
+		    [file join [temporaryDirectory] core-$name]"
+		catch {file rename -force -- \
+		    [file join [workingDirectory] core] \
+		    [file join [temporaryDirectory] core-$name]
+		} msg
+		if {$msg ne {}} {
+		    append coreMsg "\nError:\
+			Problem renaming core file: $msg"
+		}
+	    }
+	}
+    }
+
+    if {[IsVerbose msec] || [IsVerbose usec]} {
+	set t [expr {[clock microseconds] - $timeStart}]
+	if {[IsVerbose usec]} {
+	    puts [outputChannel] "++++ $name took $t μs"
+	}
+	if {[IsVerbose msec]} {
+	    puts [outputChannel] "++++ $name took [expr {round($t/1000.)}] ms"
+	}
+    }
+
+    # if we didn't experience any failures, then we passed
+    variable numTests
+    if {!($setupFailure || $cleanupFailure || $coreFailure
+	    || $outputFailure || $errorFailure || $codeFailure
+	    || $scriptFailure)} {
+	if {$testLevel == 1} {
+	    incr numTests(Passed)
+	    if {[IsVerbose pass]} {
+		puts [outputChannel] "++++ $name PASSED"
+	    }
+	}
+	incr testLevel -1
+	return
+    }
+
+    # We know the test failed, tally it...
+    if {$testLevel == 1} {
+	incr numTests(Failed)
+    }
+
+    # ... then report according to the type of failure
+    variable currentFailure true
+    if {![IsVerbose body]} {
+	set body ""
+    }
+    puts [outputChannel] "\n"
+    if {[IsVerbose line]} {
+	if {![catch {set testFrame [info frame -1]}] &&
+		[dict get $testFrame type] eq "source"} {
+	    set testFile [dict get $testFrame file]
+	    set testLine [dict get $testFrame line]
+	} else {
+	    set testFile [file normalize [uplevel 1 {info script}]]
+	    if {[file readable $testFile]} {
+		set testFd [open $testFile r]
+		set testLine [expr {[lsearch -regexp \
+			[split [read $testFd] "\n"] \
+			"^\[ \t\]*test [string map {. \\.} $name] "] + 1}]
+		close $testFd
+	    }
+	}
+	if {[info exists testLine]} {
+	    puts [outputChannel] "$testFile:$testLine: error: test failed:\
+		    $name [string trim $description]"
+	}
+    }
+    puts [outputChannel] "==== $name\
+	    [string trim $description] FAILED"
+    if {[string length $body]} {
+	puts [outputChannel] "==== Contents of test case:"
+	puts [outputChannel] $body
+    }
+    if {$setupFailure} {
+	puts [outputChannel] "---- Test setup\
+		failed:\n$setupMsg"
+	if {[info exists errorInfo(setup)]} {
+	    puts [outputChannel] "---- errorInfo(setup): $errorInfo(setup)"
+	    puts [outputChannel] "---- errorCode(setup): $errorCode(setup)"
+	}
+    }
+    if {$scriptFailure} {
+	if {$scriptCompare} {
+	    puts [outputChannel] "---- Error testing result: $scriptMatch"
+	} else {
+	    puts [outputChannel] "---- Result was:\n$actualAnswer"
+	    puts [outputChannel] "---- Result should have been\
+		    ($match matching):\n$result"
+	}
+    }
+    if {$codeFailure} {
+	switch -- $returnCode {
+	    0 { set msg "Test completed normally" }
+	    1 { set msg "Test generated error" }
+	    2 { set msg "Test generated return exception" }
+	    3 { set msg "Test generated break exception" }
+	    4 { set msg "Test generated continue exception" }
+	    default { set msg "Test generated exception" }
+	}
+	puts [outputChannel] "---- $msg; Return code was: $returnCode"
+	puts [outputChannel] "---- Return code should have been\
+		one of: $returnCodes"
+	if {[IsVerbose error]} {
+	    if {[info exists errorInfo(body)] && (1 ni $returnCodes)} {
+		puts [outputChannel] "---- errorInfo: $errorInfo(body)"
+		puts [outputChannel] "---- errorCode: $errorCode(body)"
+	    }
+	}
+    }
+    if {$outputFailure} {
+	if {$outputCompare} {
+	    puts [outputChannel] "---- Error testing output: $outputMatch"
+	} else {
+	    puts [outputChannel] "---- Output was:\n$outData"
+	    puts [outputChannel] "---- Output should have been\
+		    ($match matching):\n$output"
+	}
+    }
+    if {$errorFailure} {
+	if {$errorCompare} {
+	    puts [outputChannel] "---- Error testing errorOutput: $errorMatch"
+	} else {
+	    puts [outputChannel] "---- Error output was:\n$errData"
+	    puts [outputChannel] "---- Error output should have\
+		    been ($match matching):\n$errorOutput"
+	}
+    }
+    if {$cleanupFailure} {
+	puts [outputChannel] "---- Test cleanup failed:\n$cleanupMsg"
+	if {[info exists errorInfo(cleanup)]} {
+	    puts [outputChannel] "---- errorInfo(cleanup): $errorInfo(cleanup)"
+	    puts [outputChannel] "---- errorCode(cleanup): $errorCode(cleanup)"
+	}
+    }
+    if {$coreFailure} {
+	puts [outputChannel] "---- Core file produced while running\
+		test!  $coreMsg"
+    }
+    puts [outputChannel] "==== $name FAILED\n"
+
+    incr testLevel -1
+    return
+}
+
+# Skipped --
+#
+# Given a test name and it constraints, returns a boolean indicating
+# whether the current configuration says the test should be skipped.
+#
+# Side Effects:  Maintains tally of total tests seen and tests skipped.
+#
+proc tcltest::Skipped {name constraints} {
+    variable testLevel
+    variable numTests
+    variable testConstraints
+
+    if {$testLevel == 1} {
+	incr numTests(Total)
+    }
+    # skip the test if it's name matches an element of skip
+    foreach pattern [skip] {
+	if {[string match $pattern $name]} {
+	    if {$testLevel == 1} {
+		incr numTests(Skipped)
+		DebugDo 1 {AddToSkippedBecause userSpecifiedSkip}
+	    }
+	    return 1
+	}
+    }
+    # skip the test if it's name doesn't match any element of match
+    set ok 0
+    foreach pattern [match] {
+	if {[string match $pattern $name]} {
+	    set ok 1
+	    break
+	}
+    }
+    if {!$ok} {
+	if {$testLevel == 1} {
+	    incr numTests(Skipped)
+	    DebugDo 1 {AddToSkippedBecause userSpecifiedNonMatch}
+	}
+	return 1
+    }
+    if {$constraints eq {}} {
+	# If we're limited to the listed constraints and there aren't
+	# any listed, then we shouldn't run the test.
+	if {[limitConstraints]} {
+	    AddToSkippedBecause userSpecifiedLimitConstraint
+	    if {$testLevel == 1} {
+		incr numTests(Skipped)
+	    }
+	    return 1
+	}
+    } else {
+	# "constraints" argument exists;
+	# make sure that the constraints are satisfied.
+
+	set doTest 0
+	if {[string match {*[$\[]*} $constraints] != 0} {
+	    # full expression, e.g. {$foo > [info tclversion]}
+	    catch {set doTest [uplevel #0 [list expr $constraints]]}
+	} elseif {[regexp {[^.:_a-zA-Z0-9 \n\r\t]+} $constraints] != 0} {
+	    # something like {a || b} should be turned into
+	    # $testConstraints(a) || $testConstraints(b).
+	    regsub -all {[.\w]+} $constraints {$testConstraints(&)} c
+	    catch {set doTest [eval [list expr $c]]}
+	} elseif {![catch {llength $constraints}]} {
+	    # just simple constraints such as {unixOnly fonts}.
+	    set doTest 1
+	    foreach constraint $constraints {
+		if {(![info exists testConstraints($constraint)]) \
+			|| (!$testConstraints($constraint))} {
+		    set doTest 0
+
+		    # store the constraint that kept the test from
+		    # running
+		    set constraints $constraint
+		    break
+		}
+	    }
+	}
+
+	if {!$doTest} {
+	    if {[IsVerbose skip]} {
+		puts [outputChannel] "++++ $name SKIPPED: $constraints"
+	    }
+
+	    if {$testLevel == 1} {
+		incr numTests(Skipped)
+		AddToSkippedBecause $constraints
+	    }
+	    return 1
+	}
+    }
+    return 0
+}
+
+# RunTest --
+#
+# This is where the body of a test is evaluated.  The combination of
+# [RunTest] and [Eval] allows the output and error output of the test
+# body to be captured for comparison against the expected values.
+
+proc tcltest::RunTest {name script} {
+    DebugPuts 3 "Running $name {$script}"
+
+    # If there is no "memory" command (because memory debugging isn't
+    # enabled), then don't attempt to use the command.
+
+    if {[llength [info commands memory]] == 1} {
+	memory tag $name
+    }
+
+    set code [catch {uplevel 1 $script} actualAnswer]
+
+    return [list $actualAnswer $code]
+}
+
+#####################################################################
+
+# tcltest::cleanupTestsHook --
+#
+#	This hook allows a harness that builds upon tcltest to specify
+#       additional things that should be done at cleanup.
+#
+
+if {[llength [info commands tcltest::cleanupTestsHook]] == 0} {
+    proc tcltest::cleanupTestsHook {} {}
+}
+
+# tcltest::cleanupTests --
+#
+# Remove files and dirs created using the makeFile and makeDirectory
+# commands since the last time this proc was invoked.
+#
+# Print the names of the files created without the makeFile command
+# since the tests were invoked.
+#
+# Print the number tests (total, passed, failed, and skipped) since the
+# tests were invoked.
+#
+# Restore original environment (as reported by special variable env).
+#
+# Arguments:
+#      calledFromAllFile - if 0, behave as if we are running a single
+#      test file within an entire suite of tests.  if we aren't running
+#      a single test file, then don't report status.  check for new
+#      files created during the test run and report on them.  if 1,
+#      report collated status from all the test file runs.
+#
+# Results:
+#      None.
+#
+# Side Effects:
+#      None
+#
+
+proc tcltest::cleanupTests {{calledFromAllFile 0}} {
+    variable filesMade
+    variable filesExisted
+    variable createdNewFiles
+    variable testSingleFile
+    variable numTests
+    variable numTestFiles
+    variable failFiles
+    variable skippedBecause
+    variable currentFailure
+    variable originalEnv
+    variable originalTclPlatform
+    variable coreModTime
+
+    FillFilesExisted
+    set testFileName [file tail [info script]]
+
+    # Hook to handle reporting to a parent interpreter
+    if {[llength [info commands [namespace current]::ReportToMaster]]} {
+	ReportToMaster $numTests(Total) $numTests(Passed) $numTests(Skipped) \
+	    $numTests(Failed) [array get skippedBecause] \
+	    [array get createdNewFiles]
+	set testSingleFile false
+    }
+
+    # Call the cleanup hook
+    cleanupTestsHook
+
+    # Remove files and directories created by the makeFile and
+    # makeDirectory procedures.  Record the names of files in
+    # workingDirectory that were not pre-existing, and associate them
+    # with the test file that created them.
+
+    if {!$calledFromAllFile} {
+	foreach file $filesMade {
+	    if {[file exists $file]} {
+		DebugDo 1 {Warn "cleanupTests deleting $file..."}
+		catch {file delete -force -- $file}
+	    }
+	}
+	set currentFiles {}
+	foreach file [glob -nocomplain \
+		-directory [temporaryDirectory] *] {
+	    lappend currentFiles [file tail $file]
+	}
+	set newFiles {}
+	foreach file $currentFiles {
+	    if {$file ni $filesExisted} {
+		lappend newFiles $file
+	    }
+	}
+	set filesExisted $currentFiles
+	if {[llength $newFiles] > 0} {
+	    set createdNewFiles($testFileName) $newFiles
+	}
+    }
+
+    if {$calledFromAllFile || $testSingleFile} {
+
+	# print stats
+
+	puts -nonewline [outputChannel] "$testFileName:"
+	foreach index [list "Total" "Passed" "Skipped" "Failed"] {
+	    puts -nonewline [outputChannel] \
+		    "\t$index\t$numTests($index)"
+	}
+	puts [outputChannel] ""
+
+	# print number test files sourced
+	# print names of files that ran tests which failed
+
+	if {$calledFromAllFile} {
+	    puts [outputChannel] \
+		    "Sourced $numTestFiles Test Files."
+	    set numTestFiles 0
+	    if {[llength $failFiles] > 0} {
+		puts [outputChannel] \
+			"Files with failing tests: $failFiles"
+		set failFiles {}
+	    }
+	}
+
+	# if any tests were skipped, print the constraints that kept
+	# them from running.
+
+	set constraintList [array names skippedBecause]
+	if {[llength $constraintList] > 0} {
+	    puts [outputChannel] \
+		    "Number of tests skipped for each constraint:"
+	    foreach constraint [lsort $constraintList] {
+		puts [outputChannel] \
+			"\t$skippedBecause($constraint)\t$constraint"
+		unset skippedBecause($constraint)
+	    }
+	}
+
+	# report the names of test files in createdNewFiles, and reset
+	# the array to be empty.
+
+	set testFilesThatTurded [lsort [array names createdNewFiles]]
+	if {[llength $testFilesThatTurded] > 0} {
+	    puts [outputChannel] "Warning: files left behind:"
+	    foreach testFile $testFilesThatTurded {
+		puts [outputChannel] \
+			"\t$testFile:\t$createdNewFiles($testFile)"
+		unset createdNewFiles($testFile)
+	    }
+	}
+
+	# reset filesMade, filesExisted, and numTests
+
+	set filesMade {}
+	foreach index [list "Total" "Passed" "Skipped" "Failed"] {
+	    set numTests($index) 0
+	}
+
+	# exit only if running Tk in non-interactive mode
+	# This should be changed to determine if an event
+	# loop is running, which is the real issue.
+	# Actually, this doesn't belong here at all.  A package
+	# really has no business [exit]-ing an application.
+	if {![catch {package present Tk}] && ![testConstraint interactive]} {
+	    exit
+	}
+    } else {
+
+	# if we're deferring stat-reporting until all files are sourced,
+	# then add current file to failFile list if any tests in this
+	# file failed
+
+	if {$currentFailure && ($testFileName ni $failFiles)} {
+	    lappend failFiles $testFileName
+	}
+	set currentFailure false
+
+	# restore the environment to the state it was in before this package
+	# was loaded
+
+	set newEnv {}
+	set changedEnv {}
+	set removedEnv {}
+	foreach index [array names ::env] {
+	    if {![info exists originalEnv($index)]} {
+		lappend newEnv $index
+		unset ::env($index)
+	    }
+	}
+	foreach index [array names originalEnv] {
+	    if {![info exists ::env($index)]} {
+		lappend removedEnv $index
+		set ::env($index) $originalEnv($index)
+	    } elseif {$::env($index) ne $originalEnv($index)} {
+		lappend changedEnv $index
+		set ::env($index) $originalEnv($index)
+	    }
+	}
+	if {[llength $newEnv] > 0} {
+	    puts [outputChannel] \
+		    "env array elements created:\t$newEnv"
+	}
+	if {[llength $changedEnv] > 0} {
+	    puts [outputChannel] \
+		    "env array elements changed:\t$changedEnv"
+	}
+	if {[llength $removedEnv] > 0} {
+	    puts [outputChannel] \
+		    "env array elements removed:\t$removedEnv"
+	}
+
+	set changedTclPlatform {}
+	foreach index [array names originalTclPlatform] {
+	    if {$::tcl_platform($index) \
+		    != $originalTclPlatform($index)} {
+		lappend changedTclPlatform $index
+		set ::tcl_platform($index) $originalTclPlatform($index)
+	    }
+	}
+	if {[llength $changedTclPlatform] > 0} {
+	    puts [outputChannel] "tcl_platform array elements\
+		    changed:\t$changedTclPlatform"
+	}
+
+	if {[file exists [file join [workingDirectory] core]]} {
+	    if {[preserveCore] > 1} {
+		puts "rename core file (> 1)"
+		puts [outputChannel] "produced core file! \
+			Moving file to: \
+			[file join [temporaryDirectory] core-$testFileName]"
+		catch {file rename -force -- \
+			[file join [workingDirectory] core] \
+			[file join [temporaryDirectory] core-$testFileName]
+		} msg
+		if {$msg ne {}} {
+		    PrintError "Problem renaming file: $msg"
+		}
+	    } else {
+		# Print a message if there is a core file and (1) there
+		# previously wasn't one or (2) the new one is different
+		# from the old one.
+
+		if {[info exists coreModTime]} {
+		    if {$coreModTime != [file mtime \
+			    [file join [workingDirectory] core]]} {
+			puts [outputChannel] "A core file was created!"
+		    }
+		} else {
+		    puts [outputChannel] "A core file was created!"
+		}
+	    }
+	}
+    }
+    flush [outputChannel]
+    flush [errorChannel]
+    return
+}
+
+#####################################################################
+
+# Procs that determine which tests/test files to run
+
+# tcltest::GetMatchingFiles
+#
+#       Looks at the patterns given to match and skip files and uses
+#	them to put together a list of the tests that will be run.
+#
+# Arguments:
+#       directory to search
+#
+# Results:
+#       The constructed list is returned to the user.  This will
+#	primarily be used in 'all.tcl' files.  It is used in
+#	runAllTests.
+#
+# Side Effects:
+#       None
+
+# a lower case version is needed for compatibility with tcltest 1.0
+proc tcltest::getMatchingFiles args {GetMatchingFiles {*}$args}
+
+proc tcltest::GetMatchingFiles { args } {
+    if {[llength $args]} {
+	set dirList $args
+    } else {
+	# Finding tests only in [testsDirectory] is normal operation.
+	# This procedure is written to accept multiple directory arguments
+	# only to satisfy version 1 compatibility.
+	set dirList [list [testsDirectory]]
+    }
+
+    set matchingFiles [list]
+    foreach directory $dirList {
+
+	# List files in $directory that match patterns to run.
+	set matchFileList [list]
+	foreach match [matchFiles] {
+	    set matchFileList [concat $matchFileList \
+		    [glob -directory $directory -types {b c f p s} \
+		    -nocomplain -- $match]]
+	}
+
+	# List files in $directory that match patterns to skip.
+	set skipFileList [list]
+	foreach skip [skipFiles] {
+	    set skipFileList [concat $skipFileList \
+		    [glob -directory $directory -types {b c f p s} \
+		    -nocomplain -- $skip]]
+	}
+
+	# Add to result list all files in match list and not in skip list
+	foreach file $matchFileList {
+	    if {$file ni $skipFileList} {
+		lappend matchingFiles $file
+	    }
+	}
+    }
+
+    if {[llength $matchingFiles] == 0} {
+	PrintError "No test files remain after applying your match and\
+		skip patterns!"
+    }
+    return $matchingFiles
+}
+
+# tcltest::GetMatchingDirectories --
+#
+#	Looks at the patterns given to match and skip directories and
+#	uses them to put together a list of the test directories that we
+#	should attempt to run.  (Only subdirectories containing an
+#	"all.tcl" file are put into the list.)
+#
+# Arguments:
+#	root directory from which to search
+#
+# Results:
+#	The constructed list is returned to the user.  This is used in
+#	the primary all.tcl file.
+#
+# Side Effects:
+#       None.
+
+proc tcltest::GetMatchingDirectories {rootdir} {
+
+    # Determine the skip list first, to avoid [glob]-ing over subdirectories
+    # we're going to throw away anyway.  Be sure we skip the $rootdir if it
+    # comes up to avoid infinite loops.
+    set skipDirs [list $rootdir]
+    foreach pattern [skipDirectories] {
+	set skipDirs [concat $skipDirs [glob -directory $rootdir -types d \
+		-nocomplain -- $pattern]]
+    }
+
+    # Now step through the matching directories, prune out the skipped ones
+    # as you go.
+    set matchDirs [list]
+    foreach pattern [matchDirectories] {
+	foreach path [glob -directory $rootdir -types d -nocomplain -- \
+		$pattern] {
+	    if {$path ni $skipDirs} {
+		set matchDirs [concat $matchDirs [GetMatchingDirectories $path]]
+		if {[file exists [file join $path all.tcl]]} {
+		    lappend matchDirs $path
+		}
+	    }
+	}
+    }
+
+    if {[llength $matchDirs] == 0} {
+	DebugPuts 1 "No test directories remain after applying match\
+		and skip patterns!"
+    }
+    return [lsort $matchDirs]
+}
+
+# tcltest::runAllTests --
+#
+#	prints output and sources test files according to the match and
+#	skip patterns provided.  after sourcing test files, it goes on
+#	to source all.tcl files in matching test subdirectories.
+#
+# Arguments:
+#	shell being tested
+#
+# Results:
+#	None.
+#
+# Side effects:
+#	None.
+
+proc tcltest::runAllTests { {shell ""} } {
+    variable testSingleFile
+    variable numTestFiles
+    variable numTests
+    variable failFiles
+    variable DefaultValue
+
+    FillFilesExisted
+    if {[llength [info level 0]] == 1} {
+	set shell [interpreter]
+    }
+
+    set testSingleFile false
+
+    puts [outputChannel] "Tests running in interp:  $shell"
+    puts [outputChannel] "Tests located in:  [testsDirectory]"
+    puts [outputChannel] "Tests running in:  [workingDirectory]"
+    puts [outputChannel] "Temporary files stored in\
+	    [temporaryDirectory]"
+
+    # [file system] first available in Tcl 8.4
+    if {![catch {file system [testsDirectory]} result]
+	    && ([lindex $result 0] ne "native")} {
+	# If we aren't running in the native filesystem, then we must
+	# run the tests in a single process (via 'source'), because
+	# trying to run then via a pipe will fail since the files don't
+	# really exist.
+	singleProcess 1
+    }
+
+    if {[singleProcess]} {
+	puts [outputChannel] \
+		"Test files sourced into current interpreter"
+    } else {
+	puts [outputChannel] \
+		"Test files run in separate interpreters"
+    }
+    if {[llength [skip]] > 0} {
+	puts [outputChannel] "Skipping tests that match:  [skip]"
+    }
+    puts [outputChannel] "Running tests that match:  [match]"
+
+    if {[llength [skipFiles]] > 0} {
+	puts [outputChannel] \
+		"Skipping test files that match:  [skipFiles]"
+    }
+    if {[llength [matchFiles]] > 0} {
+	puts [outputChannel] \
+		"Only running test files that match:  [matchFiles]"
+    }
+
+    set timeCmd {clock format [clock seconds]}
+    puts [outputChannel] "Tests began at [eval $timeCmd]"
+
+    # Run each of the specified tests
+    foreach file [lsort [GetMatchingFiles]] {
+	set tail [file tail $file]
+	puts [outputChannel] $tail
+	flush [outputChannel]
+
+	if {[singleProcess]} {
+	    incr numTestFiles
+	    uplevel 1 [list ::source $file]
+	} else {
+	    # Pass along our configuration to the child processes.
+	    # EXCEPT for the -outfile, because the parent process
+	    # needs to read and process output of children.
+	    set childargv [list]
+	    foreach opt [Configure] {
+		if {$opt eq "-outfile"} {continue}
+		set value [Configure $opt]
+		# Don't bother passing default configuration options
+		if {$value eq $DefaultValue($opt)} {
+			continue
+		}
+		lappend childargv $opt $value
+	    }
+	    set cmd [linsert $childargv 0 | $shell $file]
+	    if {[catch {
+		incr numTestFiles
+		set pipeFd [open $cmd "r"]
+		while {[gets $pipeFd line] >= 0} {
+		    if {[regexp [join {
+			    {^([^:]+):\t}
+			    {Total\t([0-9]+)\t}
+			    {Passed\t([0-9]+)\t}
+			    {Skipped\t([0-9]+)\t}
+			    {Failed\t([0-9]+)}
+			    } ""] $line null testFile \
+			    Total Passed Skipped Failed]} {
+			foreach index {Total Passed Skipped Failed} {
+			    incr numTests($index) [set $index]
+			}
+			if {$Failed > 0} {
+			    lappend failFiles $testFile
+			}
+		    } elseif {[regexp [join {
+			    {^Number of tests skipped }
+			    {for each constraint:}
+			    {|^\t(\d+)\t(.+)$}
+			    } ""] $line match skipped constraint]} {
+			if {[string match \t* $match]} {
+			    AddToSkippedBecause $constraint $skipped
+			}
+		    } else {
+			puts [outputChannel] $line
+		    }
+		}
+		close $pipeFd
+	    } msg]} {
+		puts [outputChannel] "Test file error: $msg"
+		# append the name of the test to a list to be reported
+		# later
+		lappend testFileFailures $file
+	    }
+	}
+    }
+
+    # cleanup
+    puts [outputChannel] "\nTests ended at [eval $timeCmd]"
+    cleanupTests 1
+    if {[info exists testFileFailures]} {
+	puts [outputChannel] "\nTest files exiting with errors:  \n"
+	foreach file $testFileFailures {
+	    puts [outputChannel] "  [file tail $file]\n"
+	}
+    }
+
+    # Checking for subdirectories in which to run tests
+    foreach directory [GetMatchingDirectories [testsDirectory]] {
+	set dir [file tail $directory]
+	puts [outputChannel] [string repeat ~ 44]
+	puts [outputChannel] "$dir test began at [eval $timeCmd]\n"
+
+	uplevel 1 [list ::source [file join $directory all.tcl]]
+
+	set endTime [eval $timeCmd]
+	puts [outputChannel] "\n$dir test ended at $endTime"
+	puts [outputChannel] ""
+	puts [outputChannel] [string repeat ~ 44]
+    }
+    return
+}
+
+#####################################################################
+
+# Test utility procs - not used in tcltest, but may be useful for
+# testing.
+
+# tcltest::loadTestedCommands --
+#
+#     Uses the specified script to load the commands to test. Allowed to
+#     be empty, as the tested commands could have been compiled into the
+#     interpreter.
+#
+# Arguments
+#     none
+#
+# Results
+#     none
+#
+# Side Effects:
+#     none.
+
+proc tcltest::loadTestedCommands {} {
+    return [uplevel 1 [loadScript]]
+}
+
+# tcltest::saveState --
+#
+#	Save information regarding what procs and variables exist.
+#
+# Arguments:
+#	none
+#
+# Results:
+#	Modifies the variable saveState
+#
+# Side effects:
+#	None.
+
+proc tcltest::saveState {} {
+    variable saveState
+    uplevel 1 [list ::set [namespace which -variable saveState]] \
+	    {[::list [::info procs] [::info vars]]}
+    DebugPuts  2 "[lindex [info level 0] 0]: $saveState"
+    return
+}
+
+# tcltest::restoreState --
+#
+#	Remove procs and variables that didn't exist before the call to
+#       [saveState].
+#
+# Arguments:
+#	none
+#
+# Results:
+#	Removes procs and variables from your environment if they don't
+#	exist in the saveState variable.
+#
+# Side effects:
+#	None.
+
+proc tcltest::restoreState {} {
+    variable saveState
+    foreach p [uplevel 1 {::info procs}] {
+	if {($p ni [lindex $saveState 0]) && ("[namespace current]::$p" ne
+		[uplevel 1 [list ::namespace origin $p]])} {
+
+	    DebugPuts 2 "[lindex [info level 0] 0]: Removing proc $p"
+	    uplevel 1 [list ::catch [list ::rename $p {}]]
+	}
+    }
+    foreach p [uplevel 1 {::info vars}] {
+	if {$p ni [lindex $saveState 1]} {
+	    DebugPuts 2 "[lindex [info level 0] 0]:\
+		    Removing variable $p"
+	    uplevel 1 [list ::catch [list ::unset $p]]
+	}
+    }
+    return
+}
+
+# tcltest::normalizeMsg --
+#
+#	Removes "extra" newlines from a string.
+#
+# Arguments:
+#	msg        String to be modified
+#
+# Results:
+#	string with extra newlines removed
+#
+# Side effects:
+#	None.
+
+proc tcltest::normalizeMsg {msg} {
+    regsub "\n$" [string tolower $msg] "" msg
+    set msg [string map [list "\n\n" "\n"] $msg]
+    return [string map [list "\n\}" "\}"] $msg]
+}
+
+# tcltest::makeFile --
+#
+# Create a new file with the name <name>, and write <contents> to it.
+#
+# If this file hasn't been created via makeFile since the last time
+# cleanupTests was called, add it to the $filesMade list, so it will be
+# removed by the next call to cleanupTests.
+#
+# Arguments:
+#	contents        content of the new file
+#       name            name of the new file
+#       directory       directory name for new file
+#
+# Results:
+#	absolute path to the file created
+#
+# Side effects:
+#	None.
+
+proc tcltest::makeFile {contents name {directory ""}} {
+    variable filesMade
+    FillFilesExisted
+
+    if {[llength [info level 0]] == 3} {
+	set directory [temporaryDirectory]
+    }
+
+    set fullName [file join $directory $name]
+
+    DebugPuts 3 "[lindex [info level 0] 0]:\
+	     putting ``$contents'' into $fullName"
+
+    set fd [open $fullName w]
+    chan configure $fd -translation lf
+    if {[string index $contents end] eq "\n"} {
+	puts -nonewline $fd $contents
+    } else {
+	puts $fd $contents
+    }
+    close $fd
+
+    if {$fullName ni $filesMade} {
+	lappend filesMade $fullName
+    }
+    return $fullName
+}
+
+# tcltest::removeFile --
+#
+#	Removes the named file from the filesystem
+#
+# Arguments:
+#	name          file to be removed
+#       directory     directory from which to remove file
+#
+# Results:
+#	return value from [file delete]
+#
+# Side effects:
+#	None.
+
+proc tcltest::removeFile {name {directory ""}} {
+    variable filesMade
+    FillFilesExisted
+    if {[llength [info level 0]] == 2} {
+	set directory [temporaryDirectory]
+    }
+    set fullName [file join $directory $name]
+    DebugPuts 3 "[lindex [info level 0] 0]: removing $fullName"
+    set idx [lsearch -exact $filesMade $fullName]
+    set filesMade [lreplace $filesMade $idx $idx]
+    if {$idx == -1} {
+	DebugDo 1 {
+	    Warn "removeFile removing \"$fullName\":\n  not created by makeFile"
+	}
+    }
+    if {![file isfile $fullName]} {
+	DebugDo 1 {
+	    Warn "removeFile removing \"$fullName\":\n  not a file"
+	}
+    }
+    return [file delete -- $fullName]
+}
+
+# tcltest::makeDirectory --
+#
+# Create a new dir with the name <name>.
+#
+# If this dir hasn't been created via makeDirectory since the last time
+# cleanupTests was called, add it to the $directoriesMade list, so it
+# will be removed by the next call to cleanupTests.
+#
+# Arguments:
+#       name            name of the new directory
+#       directory       directory in which to create new dir
+#
+# Results:
+#	absolute path to the directory created
+#
+# Side effects:
+#	None.
+
+proc tcltest::makeDirectory {name {directory ""}} {
+    variable filesMade
+    FillFilesExisted
+    if {[llength [info level 0]] == 2} {
+	set directory [temporaryDirectory]
+    }
+    set fullName [file join $directory $name]
+    DebugPuts 3 "[lindex [info level 0] 0]: creating $fullName"
+    file mkdir $fullName
+    if {$fullName ni $filesMade} {
+	lappend filesMade $fullName
+    }
+    return $fullName
+}
+
+# tcltest::removeDirectory --
+#
+#	Removes a named directory from the file system.
+#
+# Arguments:
+#	name          Name of the directory to remove
+#       directory     Directory from which to remove
+#
+# Results:
+#	return value from [file delete]
+#
+# Side effects:
+#	None
+
+proc tcltest::removeDirectory {name {directory ""}} {
+    variable filesMade
+    FillFilesExisted
+    if {[llength [info level 0]] == 2} {
+	set directory [temporaryDirectory]
+    }
+    set fullName [file join $directory $name]
+    DebugPuts 3 "[lindex [info level 0] 0]: deleting $fullName"
+    set idx [lsearch -exact $filesMade $fullName]
+    set filesMade [lreplace $filesMade $idx $idx]
+    if {$idx == -1} {
+	DebugDo 1 {
+	    Warn "removeDirectory removing \"$fullName\":\n  not created\
+		    by makeDirectory"
+	}
+    }
+    if {![file isdirectory $fullName]} {
+	DebugDo 1 {
+	    Warn "removeDirectory removing \"$fullName\":\n  not a directory"
+	}
+    }
+    return [file delete -force -- $fullName]
+}
+
+# tcltest::viewFile --
+#
+#	reads the content of a file and returns it
+#
+# Arguments:
+#	name of the file to read
+#       directory in which file is located
+#
+# Results:
+#	content of the named file
+#
+# Side effects:
+#	None.
+
+proc tcltest::viewFile {name {directory ""}} {
+    FillFilesExisted
+    if {[llength [info level 0]] == 2} {
+	set directory [temporaryDirectory]
+    }
+    set fullName [file join $directory $name]
+    set f [open $fullName]
+    set data [read -nonewline $f]
+    close $f
+    return $data
+}
+
+# tcltest::bytestring --
+#
+# Construct a string that consists of the requested sequence of bytes,
+# as opposed to a string of properly formed UTF-8 characters.
+# This allows the tester to
+# 1. Create denormalized or improperly formed strings to pass to C
+#    procedures that are supposed to accept strings with embedded NULL
+#    bytes.
+# 2. Confirm that a string result has a certain pattern of bytes, for
+#    instance to confirm that "\xe0\0" in a Tcl script is stored
+#    internally in UTF-8 as the sequence of bytes "\xc3\xa0\xc0\x80".
+#
+# Generally, it's a bad idea to examine the bytes in a Tcl string or to
+# construct improperly formed strings in this manner, because it involves
+# exposing that Tcl uses UTF-8 internally.
+#
+# Arguments:
+#	string being converted
+#
+# Results:
+#	result fom encoding
+#
+# Side effects:
+#	None
+
+proc tcltest::bytestring {string} {
+    return [encoding convertfrom identity $string]
+}
+
+# tcltest::OpenFiles --
+#
+#	used in io tests, uses testchannel
+#
+# Arguments:
+#	None.
+#
+# Results:
+#	???
+#
+# Side effects:
+#	None.
+
+proc tcltest::OpenFiles {} {
+    if {[catch {testchannel open} result]} {
+	return {}
+    }
+    return $result
+}
+
+# tcltest::LeakFiles --
+#
+#	used in io tests, uses testchannel
+#
+# Arguments:
+#	None.
+#
+# Results:
+#	???
+#
+# Side effects:
+#	None.
+
+proc tcltest::LeakFiles {old} {
+    if {[catch {testchannel open} new]} {
+	return {}
+    }
+    set leak {}
+    foreach p $new {
+	if {$p ni $old} {
+	    lappend leak $p
+	}
+    }
+    return $leak
+}
+
+#
+# Internationalization / ISO support procs     -- dl
+#
+
+# tcltest::SetIso8859_1_Locale --
+#
+#	used in cmdIL.test, uses testlocale
+#
+# Arguments:
+#	None.
+#
+# Results:
+#	None.
+#
+# Side effects:
+#	None.
+
+proc tcltest::SetIso8859_1_Locale {} {
+    variable previousLocale
+    variable isoLocale
+    if {[info commands testlocale] != ""} {
+	set previousLocale [testlocale ctype]
+	testlocale ctype $isoLocale
+    }
+    return
+}
+
+# tcltest::RestoreLocale --
+#
+#	used in cmdIL.test, uses testlocale
+#
+# Arguments:
+#	None.
+#
+# Results:
+#	None.
+#
+# Side effects:
+#	None.
+
+proc tcltest::RestoreLocale {} {
+    variable previousLocale
+    if {[info commands testlocale] != ""} {
+	testlocale ctype $previousLocale
+    }
+    return
+}
+
+# tcltest::threadReap --
+#
+#	Kill all threads except for the main thread.
+#	Do nothing if testthread is not defined.
+#
+# Arguments:
+#	none.
+#
+# Results:
+#	Returns the number of existing threads.
+#
+# Side Effects:
+#       none.
+#
+
+proc tcltest::threadReap {} {
+    if {[info commands testthread] ne {}} {
+
+	# testthread built into tcltest
+
+	testthread errorproc ThreadNullError
+	while {[llength [testthread names]] > 1} {
+	    foreach tid [testthread names] {
+		if {$tid != [mainThread]} {
+		    catch {
+			testthread send -async $tid {testthread exit}
+		    }
+		}
+	    }
+	    ## Enter a bit a sleep to give the threads enough breathing
+	    ## room to kill themselves off, otherwise the end up with a
+	    ## massive queue of repeated events
+	    after 1
+	}
+	testthread errorproc ThreadError
+	return [llength [testthread names]]
+    } elseif {[info commands thread::id] ne {}} {
+
+	# Thread extension
+
+	thread::errorproc ThreadNullError
+	while {[llength [thread::names]] > 1} {
+	    foreach tid [thread::names] {
+		if {$tid != [mainThread]} {
+		    catch {thread::send -async $tid {thread::exit}}
+		}
+	    }
+	    ## Enter a bit a sleep to give the threads enough breathing
+	    ## room to kill themselves off, otherwise the end up with a
+	    ## massive queue of repeated events
+	    after 1
+	}
+	thread::errorproc ThreadError
+	return [llength [thread::names]]
+    } else {
+	return 1
+    }
+    return 0
+}
+
+# Initialize the constraints and set up command line arguments
+namespace eval tcltest {
+    # Define initializers for all the built-in contraint definitions
+    DefineConstraintInitializers
+
+    # Set up the constraints in the testConstraints array to be lazily
+    # initialized by a registered initializer, or by "false" if no
+    # initializer is registered.
+    trace add variable testConstraints read [namespace code SafeFetch]
+
+    # Only initialize constraints at package load time if an
+    # [initConstraintsHook] has been pre-defined.  This is only
+    # for compatibility support.  The modern way to add a custom
+    # test constraint is to just call the [testConstraint] command
+    # straight away, without all this "hook" nonsense.
+    if {[namespace current] eq
+	    [namespace qualifiers [namespace which initConstraintsHook]]} {
+	InitConstraints
+    } else {
+	proc initConstraintsHook {} {}
+    }
+
+    # Define the standard match commands
+    customMatch exact	[list string equal]
+    customMatch glob	[list string match]
+    customMatch regexp	[list regexp --]
+
+    # If the TCLTEST_OPTIONS environment variable exists, configure
+    # tcltest according to the option values it specifies.  This has
+    # the effect of resetting tcltest's default configuration.
+    proc ConfigureFromEnvironment {} {
+	upvar #0 env(TCLTEST_OPTIONS) options
+	if {[catch {llength $options} msg]} {
+	    Warn "invalid TCLTEST_OPTIONS \"$options\":\n  invalid\
+		    Tcl list: $msg"
+	    return
+	}
+	if {[llength $options] % 2} {
+	    Warn "invalid TCLTEST_OPTIONS: \"$options\":\n  should be\
+		    -option value ?-option value ...?"
+	    return
+	}
+	if {[catch {Configure {*}$options} msg]} {
+	    Warn "invalid TCLTEST_OPTIONS: \"$options\":\n  $msg"
+	    return
+	}
+    }
+    if {[info exists ::env(TCLTEST_OPTIONS)]} {
+	ConfigureFromEnvironment
+    }
+
+    proc LoadTimeCmdLineArgParsingRequired {} {
+	set required false
+	if {[info exists ::argv] && ("-help" in $::argv)} {
+	    # The command line asks for -help, so give it (and exit)
+	    # right now.  ([configure] does not process -help)
+	    set required true
+	}
+	foreach hook { PrintUsageInfoHook processCmdLineArgsHook
+			processCmdLineArgsAddFlagsHook } {
+	    if {[namespace current] eq
+		    [namespace qualifiers [namespace which $hook]]} {
+		set required true
+	    } else {
+		proc $hook args {}
+	    }
+	}
+	return $required
+    }
+
+    # Only initialize configurable options from the command line arguments
+    # at package load time if necessary for backward compatibility.  This
+    # lets the tcltest user call [configure] for themselves if they wish.
+    # Traces are established for auto-configuration from the command line
+    # if any configurable options are accessed before the user calls
+    # [configure].
+    if {[LoadTimeCmdLineArgParsingRequired]} {
+	ProcessCmdLineArgs
+    } else {
+	EstablishAutoConfigureTraces
+    }
+
+    package provide [namespace tail [namespace current]] $Version
+}
diff --git a/library/tm.tcl b/library/tm.tcl
new file mode 100644
index 0000000..66c56a1
--- /dev/null
+++ b/library/tm.tcl
@@ -0,0 +1,375 @@
+# -*- tcl -*-
+#
+# Searching for Tcl Modules. Defines a procedure, declares it as the primary
+# command for finding packages, however also uses the former 'package unknown'
+# command as a fallback.
+#
+# Locates all possible packages in a directory via a less restricted glob. The
+# targeted directory is derived from the name of the requested package, i.e.
+# the TM scan will look only at directories which can contain the requested
+# package. It will register all packages it found in the directory so that
+# future requests have a higher chance of being fulfilled by the ifneeded
+# database without having to come to us again.
+#
+# We do not remember where we have been and simply rescan targeted directories
+# when invoked again. The reasoning is this:
+#
+# - The only way we get back to the same directory is if someone is trying to
+#   [package require] something that wasn't there on the first scan.
+#
+#   Either
+#   1) It is there now:  If we rescan, you get it; if not you don't.
+#
+#      This covers the possibility that the application asked for a package
+#      late, and the package was actually added to the installation after the
+#      application was started. It shoukld still be able to find it.
+#
+#   2) It still is not there: Either way, you don't get it, but the rescan
+#      takes time. This is however an error case and we dont't care that much
+#      about it
+#
+#   3) It was there the first time; but for some reason a "package forget" has
+#      been run, and "package" doesn't know about it anymore.
+#
+#      This can be an indication that the application wishes to reload some
+#      functionality. And should work as well.
+#
+# Note that this also strikes a balance between doing a glob targeting a
+# single package, and thus most likely requiring multiple globs of the same
+# directory when the application is asking for many packages, and trying to
+# glob for _everything_ in all subdirectories when looking for a package,
+# which comes with a heavy startup cost.
+#
+# We scan for regular packages only if no satisfying module was found.
+
+namespace eval ::tcl::tm {
+    # Default paths. None yet.
+
+    variable paths {}
+
+    # The regex pattern a file name has to match to make it a Tcl Module.
+
+    set pkgpattern {^([_[:alpha:]][:_[:alnum:]]*)-([[:digit:]].*)[.]tm$}
+
+    # Export the public API
+
+    namespace export path
+    namespace ensemble create -command path -subcommands {add remove list}
+}
+
+# ::tcl::tm::path implementations --
+#
+#	Public API to the module path. See specification.
+#
+# Arguments
+#	cmd -	The subcommand to execute
+#	args -	The paths to add/remove. Must not appear querying the
+#		path with 'list'.
+#
+# Results
+#	No result for subcommands 'add' and 'remove'. A list of paths for
+#	'list'.
+#
+# Sideeffects
+#	The subcommands 'add' and 'remove' manipulate the list of paths to
+#	search for Tcl Modules. The subcommand 'list' has no sideeffects.
+
+proc ::tcl::tm::add {args} {
+    # PART OF THE ::tcl::tm::path ENSEMBLE
+    #
+    # The path is added at the head to the list of module paths.
+    #
+    # The command enforces the restriction that no path may be an ancestor
+    # directory of any other path on the list. If the new path violates this
+    # restriction an error wil be raised.
+    #
+    # If the path is already present as is no error will be raised and no
+    # action will be taken.
+
+    variable paths
+
+    # We use a copy of the path as source during validation, and extend it as
+    # well. Because we not only have to detect if the new paths are bogus with
+    # respect to the existing paths, but also between themselves. Otherwise we
+    # can still add bogus paths, by specifying them in a single call. This
+    # makes the use of the new paths simpler as well, a trivial assignment of
+    # the collected paths to the official state var.
+
+    set newpaths $paths
+    foreach p $args {
+	if {$p in $newpaths} {
+	    # Ignore a path already on the list.
+	    continue
+	}
+
+	# Search for paths which are subdirectories of the new one. If there
+	# are any then the new path violates the restriction about ancestors.
+
+	set pos [lsearch -glob $newpaths ${p}/*]
+	# Cannot use "in", we need the position for the message.
+	if {$pos >= 0} {
+	    return -code error \
+		"$p is ancestor of existing module path [lindex $newpaths $pos]."
+	}
+
+	# Now look for existing paths which are ancestors of the new one. This
+	# reverse question forces us to loop over the existing paths, as each
+	# element is the pattern, not the new path :(
+
+	foreach ep $newpaths {
+	    if {[string match ${ep}/* $p]} {
+		return -code error \
+		    "$p is subdirectory of existing module path $ep."
+	    }
+	}
+
+	set newpaths [linsert $newpaths 0 $p]
+    }
+
+    # The validation of the input is complete and successful, and everything
+    # in newpaths is either an old path, or added. We can now extend the
+    # official list of paths, a simple assignment is sufficient.
+
+    set paths $newpaths
+    return
+}
+
+proc ::tcl::tm::remove {args} {
+    # PART OF THE ::tcl::tm::path ENSEMBLE
+    #
+    # Removes the path from the list of module paths. The command is silently
+    # ignored if the path is not on the list.
+
+    variable paths
+
+    foreach p $args {
+	set pos [lsearch -exact $paths $p]
+	if {$pos >= 0} {
+	    set paths [lreplace $paths $pos $pos]
+	}
+    }
+}
+
+proc ::tcl::tm::list {} {
+    # PART OF THE ::tcl::tm::path ENSEMBLE
+
+    variable paths
+    return  $paths
+}
+
+# ::tcl::tm::UnknownHandler --
+#
+#	Unknown handler for Tcl Modules, i.e. packages in module form.
+#
+# Arguments
+#	original	- Original [package unknown] procedure.
+#	name		- Name of desired package.
+#	version		- Version of desired package. Can be the
+#			  empty string.
+#	exact		- Either -exact or ommitted.
+#
+#	Name, version, and exact are used to determine satisfaction. The
+#	original is called iff no satisfaction was achieved. The name is also
+#	used to compute the directory to target in the search.
+#
+# Results
+#	None.
+#
+# Sideeffects
+#	May populate the package ifneeded database with additional provide
+#	scripts.
+
+proc ::tcl::tm::UnknownHandler {original name args} {
+    # Import the list of paths to search for packages in module form.
+    # Import the pattern used to check package names in detail.
+
+    variable paths
+    variable pkgpattern
+
+    # Without paths to search we can do nothing. (Except falling back to the
+    # regular search).
+
+    if {[llength $paths]} {
+	set pkgpath [string map {:: /} $name]
+	set pkgroot [file dirname $pkgpath]
+	if {$pkgroot eq "."} {
+	    set pkgroot ""
+	}
+
+	# We don't remember a copy of the paths while looping. Tcl Modules are
+	# unable to change the list while we are searching for them. This also
+	# simplifies the loop, as we cannot get additional directories while
+	# iterating over the list. A simple foreach is sufficient.
+
+	set satisfied 0
+	foreach path $paths {
+	    if {![interp issafe] && ![file exists $path]} {
+		continue
+	    }
+	    set currentsearchpath [file join $path $pkgroot]
+	    if {![interp issafe] && ![file exists $currentsearchpath]} {
+		continue
+	    }
+	    set strip [llength [file split $path]]
+
+	    # We can't use glob in safe interps, so enclose the following in a
+	    # catch statement, where we get the module files out of the
+	    # subdirectories. In other words, Tcl Modules are not-functional
+	    # in such an interpreter. This is the same as for the command
+	    # "tclPkgUnknown", i.e. the search for regular packages.
+
+	    catch {
+		# We always look for _all_ possible modules in the current
+		# path, to get the max result out of the glob.
+
+		foreach file [glob -nocomplain -directory $currentsearchpath *.tm] {
+		    set pkgfilename [join [lrange [file split $file] $strip end] ::]
+
+		    if {![regexp -- $pkgpattern $pkgfilename --> pkgname pkgversion]} {
+			# Ignore everything not matching our pattern for
+			# package names.
+			continue
+		    }
+		    try {
+			package vcompare $pkgversion 0
+		    } on error {} {
+			# Ignore everything where the version part is not
+			# acceptable to "package vcompare".
+			continue
+		    }
+
+		    if {[package ifneeded $pkgname $pkgversion] ne {}} {
+			# There's already a provide script registered for
+			# this version of this package.  Since all units of
+			# code claiming to be the same version of the same
+			# package ought to be identical, just stick with
+			# the one we already have.
+			continue
+		    }
+
+		    # We have found a candidate, generate a "provide script"
+		    # for it, and remember it.  Note that we are using ::list
+		    # to do this; locally [list] means something else without
+		    # the namespace specifier.
+
+		    # NOTE. When making changes to the format of the provide
+		    # command generated below CHECK that the 'LOCATE'
+		    # procedure in core file 'platform/shell.tcl' still
+		    # understands it, or, if not, update its implementation
+		    # appropriately.
+		    #
+		    # Right now LOCATE's implementation assumes that the path
+		    # of the package file is the last element in the list.
+
+		    package ifneeded $pkgname $pkgversion \
+			"[::list package provide $pkgname $pkgversion];[::list source -encoding utf-8 $file]"
+
+		    # We abort in this unknown handler only if we got a
+		    # satisfying candidate for the requested package.
+		    # Otherwise we still have to fallback to the regular
+		    # package search to complete the processing.
+
+		    if {($pkgname eq $name)
+			    && [package vsatisfies $pkgversion {*}$args]} {
+			set satisfied 1
+
+			# We do not abort the loop, and keep adding provide
+			# scripts for every candidate in the directory, just
+			# remember to not fall back to the regular search
+			# anymore.
+		    }
+		}
+	    }
+	}
+
+	if {$satisfied} {
+	    return
+	}
+    }
+
+    # Fallback to previous command, if existing.  See comment above about
+    # ::list...
+
+    if {[llength $original]} {
+	uplevel 1 $original [::linsert $args 0 $name]
+    }
+}
+
+# ::tcl::tm::Defaults --
+#
+#	Determines the default search paths.
+#
+# Arguments
+#	None
+#
+# Results
+#	None.
+#
+# Sideeffects
+#	May add paths to the list of defaults.
+
+proc ::tcl::tm::Defaults {} {
+    global env tcl_platform
+
+    lassign [split [info tclversion] .] major minor
+    set exe [file normalize [info nameofexecutable]]
+
+    # Note that we're using [::list], not [list] because [list] means
+    # something other than [::list] in this namespace.
+    roots [::list \
+	    [file dirname [info library]] \
+	    [file join [file dirname [file dirname $exe]] lib] \
+	    ]
+
+    if {$tcl_platform(platform) eq "windows"} {
+	set sep ";"
+    } else {
+	set sep ":"
+    }
+    for {set n $minor} {$n >= 0} {incr n -1} {
+	foreach ev [::list \
+			TCL${major}.${n}_TM_PATH \
+			TCL${major}_${n}_TM_PATH \
+        ] {
+	    if {![info exists env($ev)]} continue
+	    foreach p [split $env($ev) $sep] {
+		path add $p
+	    }
+	}
+    }
+    return
+}
+
+# ::tcl::tm::roots --
+#
+#	Public API to the module path. See specification.
+#
+# Arguments
+#	paths -	List of 'root' paths to derive search paths from.
+#
+# Results
+#	No result.
+#
+# Sideeffects
+#	Calls 'path add' to paths to the list of module search paths.
+
+proc ::tcl::tm::roots {paths} {
+    regexp {^(\d+)\.(\d+)} [package present Tcl] - major minor
+    foreach pa $paths {
+	set p [file join $pa tcl$major]
+	for {set n $minor} {$n >= 0} {incr n -1} {
+	    set px [file join $p ${major}.${n}]
+	    if {![interp issafe]} {set px [file normalize $px]}
+	    path add $px
+	}
+	set px [file join $p site-tcl]
+	if {![interp issafe]} {set px [file normalize $px]}
+	path add $px
+    }
+    return
+}
+
+# Initialization. Set up the default paths, then insert the new handler into
+# the chain.
+
+if {![interp issafe]} {::tcl::tm::Defaults}
diff --git a/library/tzdata/Africa/Abidjan b/library/tzdata/Africa/Abidjan
new file mode 100644
index 0000000..4b4f5b2
--- /dev/null
+++ b/library/tzdata/Africa/Abidjan
@@ -0,0 +1,6 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Africa/Abidjan) {
+    {-9223372036854775808 -968 0 LMT}
+    {-1830383032 0 0 GMT}
+}
diff --git a/library/tzdata/Africa/Accra b/library/tzdata/Africa/Accra
new file mode 100644
index 0000000..39db976
--- /dev/null
+++ b/library/tzdata/Africa/Accra
@@ -0,0 +1,52 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Africa/Accra) {
+    {-9223372036854775808 -52 0 LMT}
+    {-1640995148 0 0 GMT}
+    {-1556841600 1200 1 GHST}
+    {-1546388400 0 0 GMT}
+    {-1525305600 1200 1 GHST}
+    {-1514852400 0 0 GMT}
+    {-1493769600 1200 1 GHST}
+    {-1483316400 0 0 GMT}
+    {-1462233600 1200 1 GHST}
+    {-1451780400 0 0 GMT}
+    {-1430611200 1200 1 GHST}
+    {-1420158000 0 0 GMT}
+    {-1399075200 1200 1 GHST}
+    {-1388622000 0 0 GMT}
+    {-1367539200 1200 1 GHST}
+    {-1357086000 0 0 GMT}
+    {-1336003200 1200 1 GHST}
+    {-1325550000 0 0 GMT}
+    {-1304380800 1200 1 GHST}
+    {-1293927600 0 0 GMT}
+    {-1272844800 1200 1 GHST}
+    {-1262391600 0 0 GMT}
+    {-1241308800 1200 1 GHST}
+    {-1230855600 0 0 GMT}
+    {-1209772800 1200 1 GHST}
+    {-1199319600 0 0 GMT}
+    {-1178150400 1200 1 GHST}
+    {-1167697200 0 0 GMT}
+    {-1146614400 1200 1 GHST}
+    {-1136161200 0 0 GMT}
+    {-1115078400 1200 1 GHST}
+    {-1104625200 0 0 GMT}
+    {-1083542400 1200 1 GHST}
+    {-1073089200 0 0 GMT}
+    {-1051920000 1200 1 GHST}
+    {-1041466800 0 0 GMT}
+    {-1020384000 1200 1 GHST}
+    {-1009930800 0 0 GMT}
+    {-988848000 1200 1 GHST}
+    {-978394800 0 0 GMT}
+    {-957312000 1200 1 GHST}
+    {-946858800 0 0 GMT}
+    {-925689600 1200 1 GHST}
+    {-915236400 0 0 GMT}
+    {-894153600 1200 1 GHST}
+    {-883700400 0 0 GMT}
+    {-862617600 1200 1 GHST}
+    {-852164400 0 0 GMT}
+}
diff --git a/library/tzdata/Africa/Addis_Ababa b/library/tzdata/Africa/Addis_Ababa
new file mode 100644
index 0000000..7aa5653
--- /dev/null
+++ b/library/tzdata/Africa/Addis_Ababa
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Africa/Nairobi)]} {
+    LoadTimeZoneFile Africa/Nairobi
+}
+set TZData(:Africa/Addis_Ababa) $TZData(:Africa/Nairobi)
diff --git a/library/tzdata/Africa/Algiers b/library/tzdata/Africa/Algiers
new file mode 100644
index 0000000..fe4de22
--- /dev/null
+++ b/library/tzdata/Africa/Algiers
@@ -0,0 +1,39 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Africa/Algiers) {
+    {-9223372036854775808 732 0 LMT}
+    {-2486679072 561 0 PMT}
+    {-1855958961 0 0 WET}
+    {-1689814800 3600 1 WEST}
+    {-1680397200 0 0 WET}
+    {-1665363600 3600 1 WEST}
+    {-1648342800 0 0 WET}
+    {-1635123600 3600 1 WEST}
+    {-1616893200 0 0 WET}
+    {-1604278800 3600 1 WEST}
+    {-1585443600 0 0 WET}
+    {-1574038800 3600 1 WEST}
+    {-1552266000 0 0 WET}
+    {-1539997200 3600 1 WEST}
+    {-1531443600 0 0 WET}
+    {-956365200 3600 1 WEST}
+    {-950486400 0 0 WET}
+    {-942012000 3600 0 CET}
+    {-812502000 7200 1 CEST}
+    {-796262400 3600 0 CET}
+    {-781052400 7200 1 CEST}
+    {-766630800 3600 0 CET}
+    {-733280400 0 0 WET}
+    {-439430400 3600 0 CET}
+    {-212029200 0 0 WET}
+    {41468400 3600 1 WEST}
+    {54774000 0 0 WET}
+    {231724800 3600 1 WEST}
+    {246240000 3600 0 CET}
+    {259545600 7200 1 CEST}
+    {275274000 3600 0 CET}
+    {309740400 0 0 WET}
+    {325468800 3600 1 WEST}
+    {341802000 0 0 WET}
+    {357523200 3600 0 CET}
+}
diff --git a/library/tzdata/Africa/Asmara b/library/tzdata/Africa/Asmara
new file mode 100644
index 0000000..3d33c94
--- /dev/null
+++ b/library/tzdata/Africa/Asmara
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Africa/Nairobi)]} {
+    LoadTimeZoneFile Africa/Nairobi
+}
+set TZData(:Africa/Asmara) $TZData(:Africa/Nairobi)
diff --git a/library/tzdata/Africa/Asmera b/library/tzdata/Africa/Asmera
new file mode 100644
index 0000000..ca8d123
--- /dev/null
+++ b/library/tzdata/Africa/Asmera
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Africa/Nairobi)]} {
+    LoadTimeZoneFile Africa/Nairobi
+}
+set TZData(:Africa/Asmera) $TZData(:Africa/Nairobi)
diff --git a/library/tzdata/Africa/Bamako b/library/tzdata/Africa/Bamako
new file mode 100644
index 0000000..0818378
--- /dev/null
+++ b/library/tzdata/Africa/Bamako
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Africa/Abidjan)]} {
+    LoadTimeZoneFile Africa/Abidjan
+}
+set TZData(:Africa/Bamako) $TZData(:Africa/Abidjan)
diff --git a/library/tzdata/Africa/Bangui b/library/tzdata/Africa/Bangui
new file mode 100644
index 0000000..0326a6c
--- /dev/null
+++ b/library/tzdata/Africa/Bangui
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Africa/Lagos)]} {
+    LoadTimeZoneFile Africa/Lagos
+}
+set TZData(:Africa/Bangui) $TZData(:Africa/Lagos)
diff --git a/library/tzdata/Africa/Banjul b/library/tzdata/Africa/Banjul
new file mode 100644
index 0000000..ded0e57
--- /dev/null
+++ b/library/tzdata/Africa/Banjul
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Africa/Abidjan)]} {
+    LoadTimeZoneFile Africa/Abidjan
+}
+set TZData(:Africa/Banjul) $TZData(:Africa/Abidjan)
diff --git a/library/tzdata/Africa/Bissau b/library/tzdata/Africa/Bissau
new file mode 100644
index 0000000..5693228
--- /dev/null
+++ b/library/tzdata/Africa/Bissau
@@ -0,0 +1,7 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Africa/Bissau) {
+    {-9223372036854775808 -3740 0 LMT}
+    {-1830380260 -3600 0 WAT}
+    {157770000 0 0 GMT}
+}
diff --git a/library/tzdata/Africa/Blantyre b/library/tzdata/Africa/Blantyre
new file mode 100644
index 0000000..9a404c5
--- /dev/null
+++ b/library/tzdata/Africa/Blantyre
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Africa/Maputo)]} {
+    LoadTimeZoneFile Africa/Maputo
+}
+set TZData(:Africa/Blantyre) $TZData(:Africa/Maputo)
diff --git a/library/tzdata/Africa/Brazzaville b/library/tzdata/Africa/Brazzaville
new file mode 100644
index 0000000..111eff4
--- /dev/null
+++ b/library/tzdata/Africa/Brazzaville
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Africa/Lagos)]} {
+    LoadTimeZoneFile Africa/Lagos
+}
+set TZData(:Africa/Brazzaville) $TZData(:Africa/Lagos)
diff --git a/library/tzdata/Africa/Bujumbura b/library/tzdata/Africa/Bujumbura
new file mode 100644
index 0000000..1e463d8
--- /dev/null
+++ b/library/tzdata/Africa/Bujumbura
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Africa/Maputo)]} {
+    LoadTimeZoneFile Africa/Maputo
+}
+set TZData(:Africa/Bujumbura) $TZData(:Africa/Maputo)
diff --git a/library/tzdata/Africa/Cairo b/library/tzdata/Africa/Cairo
new file mode 100644
index 0000000..aaeec54
--- /dev/null
+++ b/library/tzdata/Africa/Cairo
@@ -0,0 +1,132 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Africa/Cairo) {
+    {-9223372036854775808 7509 0 LMT}
+    {-2185409109 7200 0 EET}
+    {-929844000 10800 1 EEST}
+    {-923108400 7200 0 EET}
+    {-906170400 10800 1 EEST}
+    {-892868400 7200 0 EET}
+    {-875844000 10800 1 EEST}
+    {-857790000 7200 0 EET}
+    {-844308000 10800 1 EEST}
+    {-825822000 7200 0 EET}
+    {-812685600 10800 1 EEST}
+    {-794199600 7200 0 EET}
+    {-779853600 10800 1 EEST}
+    {-762663600 7200 0 EET}
+    {-399088800 10800 1 EEST}
+    {-386650800 7200 0 EET}
+    {-368330400 10800 1 EEST}
+    {-355114800 7200 0 EET}
+    {-336790800 10800 1 EEST}
+    {-323654400 7200 0 EET}
+    {-305168400 10800 1 EEST}
+    {-292032000 7200 0 EET}
+    {-273632400 10800 1 EEST}
+    {-260496000 7200 0 EET}
+    {-242096400 10800 1 EEST}
+    {-228960000 7200 0 EET}
+    {-210560400 10800 1 EEST}
+    {-197424000 7200 0 EET}
+    {-178938000 10800 1 EEST}
+    {-165801600 7200 0 EET}
+    {-147402000 10800 1 EEST}
+    {-134265600 7200 0 EET}
+    {-115866000 10800 1 EEST}
+    {-102643200 7200 0 EET}
+    {-84330000 10800 1 EEST}
+    {-71107200 7200 0 EET}
+    {-52707600 10800 1 EEST}
+    {-39484800 7200 0 EET}
+    {-21171600 10800 1 EEST}
+    {-7948800 7200 0 EET}
+    {10364400 10800 1 EEST}
+    {23587200 7200 0 EET}
+    {41900400 10800 1 EEST}
+    {55123200 7200 0 EET}
+    {73522800 10800 1 EEST}
+    {86745600 7200 0 EET}
+    {105058800 10800 1 EEST}
+    {118281600 7200 0 EET}
+    {136594800 10800 1 EEST}
+    {149817600 7200 0 EET}
+    {168130800 10800 1 EEST}
+    {181353600 7200 0 EET}
+    {199753200 10800 1 EEST}
+    {212976000 7200 0 EET}
+    {231289200 10800 1 EEST}
+    {244512000 7200 0 EET}
+    {262825200 10800 1 EEST}
+    {276048000 7200 0 EET}
+    {294361200 10800 1 EEST}
+    {307584000 7200 0 EET}
+    {325983600 10800 1 EEST}
+    {339206400 7200 0 EET}
+    {357519600 10800 1 EEST}
+    {370742400 7200 0 EET}
+    {396399600 10800 1 EEST}
+    {402278400 7200 0 EET}
+    {426812400 10800 1 EEST}
+    {433814400 7200 0 EET}
+    {452214000 10800 1 EEST}
+    {465436800 7200 0 EET}
+    {483750000 10800 1 EEST}
+    {496972800 7200 0 EET}
+    {515286000 10800 1 EEST}
+    {528508800 7200 0 EET}
+    {546822000 10800 1 EEST}
+    {560044800 7200 0 EET}
+    {578444400 10800 1 EEST}
+    {591667200 7200 0 EET}
+    {610412400 10800 1 EEST}
+    {623203200 7200 0 EET}
+    {641516400 10800 1 EEST}
+    {654739200 7200 0 EET}
+    {673052400 10800 1 EEST}
+    {686275200 7200 0 EET}
+    {704674800 10800 1 EEST}
+    {717897600 7200 0 EET}
+    {736210800 10800 1 EEST}
+    {749433600 7200 0 EET}
+    {767746800 10800 1 EEST}
+    {780969600 7200 0 EET}
+    {799020000 10800 1 EEST}
+    {812322000 7200 0 EET}
+    {830469600 10800 1 EEST}
+    {843771600 7200 0 EET}
+    {861919200 10800 1 EEST}
+    {875221200 7200 0 EET}
+    {893368800 10800 1 EEST}
+    {906670800 7200 0 EET}
+    {925423200 10800 1 EEST}
+    {938725200 7200 0 EET}
+    {956872800 10800 1 EEST}
+    {970174800 7200 0 EET}
+    {988322400 10800 1 EEST}
+    {1001624400 7200 0 EET}
+    {1019772000 10800 1 EEST}
+    {1033074000 7200 0 EET}
+    {1051221600 10800 1 EEST}
+    {1064523600 7200 0 EET}
+    {1083276000 10800 1 EEST}
+    {1096578000 7200 0 EET}
+    {1114725600 10800 1 EEST}
+    {1128027600 7200 0 EET}
+    {1146175200 10800 1 EEST}
+    {1158872400 7200 0 EET}
+    {1177624800 10800 1 EEST}
+    {1189112400 7200 0 EET}
+    {1209074400 10800 1 EEST}
+    {1219957200 7200 0 EET}
+    {1240524000 10800 1 EEST}
+    {1250802000 7200 0 EET}
+    {1272578400 10800 1 EEST}
+    {1281474000 7200 0 EET}
+    {1284069600 10800 1 EEST}
+    {1285880400 7200 0 EET}
+    {1400191200 10800 1 EEST}
+    {1403816400 7200 0 EET}
+    {1406844000 10800 1 EEST}
+    {1411678800 7200 0 EET}
+}
diff --git a/library/tzdata/Africa/Casablanca b/library/tzdata/Africa/Casablanca
new file mode 100644
index 0000000..33ad99b
--- /dev/null
+++ b/library/tzdata/Africa/Casablanca
@@ -0,0 +1,230 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Africa/Casablanca) {
+    {-9223372036854775808 -1820 0 LMT}
+    {-1773012580 0 0 WET}
+    {-956361600 3600 1 WEST}
+    {-950490000 0 0 WET}
+    {-942019200 3600 1 WEST}
+    {-761187600 0 0 WET}
+    {-617241600 3600 1 WEST}
+    {-605149200 0 0 WET}
+    {-81432000 3600 1 WEST}
+    {-71110800 0 0 WET}
+    {141264000 3600 1 WEST}
+    {147222000 0 0 WET}
+    {199756800 3600 1 WEST}
+    {207702000 0 0 WET}
+    {231292800 3600 1 WEST}
+    {244249200 0 0 WET}
+    {265507200 3600 1 WEST}
+    {271033200 0 0 WET}
+    {448243200 3600 0 CET}
+    {504918000 0 0 WET}
+    {1212278400 3600 1 WEST}
+    {1220223600 0 0 WET}
+    {1243814400 3600 1 WEST}
+    {1250809200 0 0 WET}
+    {1272758400 3600 1 WEST}
+    {1281222000 0 0 WET}
+    {1301788800 3600 1 WEST}
+    {1312066800 0 0 WET}
+    {1335664800 3600 1 WEST}
+    {1342749600 0 0 WET}
+    {1345428000 3600 1 WEST}
+    {1348970400 0 0 WET}
+    {1367114400 3600 1 WEST}
+    {1373162400 0 0 WET}
+    {1376100000 3600 1 WEST}
+    {1382839200 0 0 WET}
+    {1396144800 3600 1 WEST}
+    {1403920800 0 0 WET}
+    {1406944800 3600 1 WEST}
+    {1414288800 0 0 WET}
+    {1427594400 3600 1 WEST}
+    {1434247200 0 0 WET}
+    {1437271200 3600 1 WEST}
+    {1445738400 0 0 WET}
+    {1459044000 3600 1 WEST}
+    {1465092000 0 0 WET}
+    {1468116000 3600 1 WEST}
+    {1477792800 0 0 WET}
+    {1490493600 3600 1 WEST}
+    {1495332000 0 0 WET}
+    {1498960800 3600 1 WEST}
+    {1509242400 0 0 WET}
+    {1521943200 3600 1 WEST}
+    {1526176800 0 0 WET}
+    {1529200800 3600 1 WEST}
+    {1540692000 0 0 WET}
+    {1553997600 3600 1 WEST}
+    {1557021600 0 0 WET}
+    {1560045600 3600 1 WEST}
+    {1572141600 0 0 WET}
+    {1585447200 3600 1 WEST}
+    {1587261600 0 0 WET}
+    {1590285600 3600 1 WEST}
+    {1603591200 0 0 WET}
+    {1616896800 3600 1 WEST}
+    {1618106400 0 0 WET}
+    {1621130400 3600 1 WEST}
+    {1635645600 0 0 WET}
+    {1651975200 3600 1 WEST}
+    {1667095200 0 0 WET}
+    {1682215200 3600 1 WEST}
+    {1698544800 0 0 WET}
+    {1713060000 3600 1 WEST}
+    {1729994400 0 0 WET}
+    {1743904800 3600 1 WEST}
+    {1761444000 0 0 WET}
+    {1774749600 3600 1 WEST}
+    {1792893600 0 0 WET}
+    {1806199200 3600 1 WEST}
+    {1824948000 0 0 WET}
+    {1837648800 3600 1 WEST}
+    {1856397600 0 0 WET}
+    {1869098400 3600 1 WEST}
+    {1887847200 0 0 WET}
+    {1901152800 3600 1 WEST}
+    {1919296800 0 0 WET}
+    {1932602400 3600 1 WEST}
+    {1950746400 0 0 WET}
+    {1964052000 3600 1 WEST}
+    {1982800800 0 0 WET}
+    {1995501600 3600 1 WEST}
+    {2014250400 0 0 WET}
+    {2026951200 3600 1 WEST}
+    {2045700000 0 0 WET}
+    {2058400800 3600 1 WEST}
+    {2077149600 0 0 WET}
+    {2090455200 3600 1 WEST}
+    {2107994400 0 0 WET}
+    {2108602800 0 0 WET}
+    {2121904800 3600 1 WEST}
+    {2138234400 0 0 WET}
+    {2140052400 0 0 WET}
+    {2153354400 3600 1 WEST}
+    {2172103200 0 0 WET}
+    {2184804000 3600 1 WEST}
+    {2203552800 0 0 WET}
+    {2216253600 3600 1 WEST}
+    {2235002400 0 0 WET}
+    {2248308000 3600 1 WEST}
+    {2266452000 0 0 WET}
+    {2279757600 3600 1 WEST}
+    {2297901600 0 0 WET}
+    {2311207200 3600 1 WEST}
+    {2329351200 0 0 WET}
+    {2342656800 3600 1 WEST}
+    {2361405600 0 0 WET}
+    {2374106400 3600 1 WEST}
+    {2392855200 0 0 WET}
+    {2405556000 3600 1 WEST}
+    {2424304800 0 0 WET}
+    {2437610400 3600 1 WEST}
+    {2455754400 0 0 WET}
+    {2469060000 3600 1 WEST}
+    {2487204000 0 0 WET}
+    {2500509600 3600 1 WEST}
+    {2519258400 0 0 WET}
+    {2531959200 3600 1 WEST}
+    {2550708000 0 0 WET}
+    {2563408800 3600 1 WEST}
+    {2582157600 0 0 WET}
+    {2595463200 3600 1 WEST}
+    {2613607200 0 0 WET}
+    {2626912800 3600 1 WEST}
+    {2645056800 0 0 WET}
+    {2658362400 3600 1 WEST}
+    {2676506400 0 0 WET}
+    {2689812000 3600 1 WEST}
+    {2708560800 0 0 WET}
+    {2721261600 3600 1 WEST}
+    {2740010400 0 0 WET}
+    {2752711200 3600 1 WEST}
+    {2771460000 0 0 WET}
+    {2784765600 3600 1 WEST}
+    {2802909600 0 0 WET}
+    {2816215200 3600 1 WEST}
+    {2834359200 0 0 WET}
+    {2847664800 3600 1 WEST}
+    {2866413600 0 0 WET}
+    {2879114400 3600 1 WEST}
+    {2897863200 0 0 WET}
+    {2910564000 3600 1 WEST}
+    {2929312800 0 0 WET}
+    {2942013600 3600 1 WEST}
+    {2960762400 0 0 WET}
+    {2974068000 3600 1 WEST}
+    {2992212000 0 0 WET}
+    {3005517600 3600 1 WEST}
+    {3023661600 0 0 WET}
+    {3036967200 3600 1 WEST}
+    {3055716000 0 0 WET}
+    {3068416800 3600 1 WEST}
+    {3087165600 0 0 WET}
+    {3099866400 3600 1 WEST}
+    {3118615200 0 0 WET}
+    {3131920800 3600 1 WEST}
+    {3150064800 0 0 WET}
+    {3163370400 3600 1 WEST}
+    {3181514400 0 0 WET}
+    {3194820000 3600 1 WEST}
+    {3212964000 0 0 WET}
+    {3226269600 3600 1 WEST}
+    {3245018400 0 0 WET}
+    {3257719200 3600 1 WEST}
+    {3276468000 0 0 WET}
+    {3289168800 3600 1 WEST}
+    {3307917600 0 0 WET}
+    {3321223200 3600 1 WEST}
+    {3339367200 0 0 WET}
+    {3352672800 3600 1 WEST}
+    {3370816800 0 0 WET}
+    {3384122400 3600 1 WEST}
+    {3402871200 0 0 WET}
+    {3415572000 3600 1 WEST}
+    {3434320800 0 0 WET}
+    {3447021600 3600 1 WEST}
+    {3465770400 0 0 WET}
+    {3479076000 3600 1 WEST}
+    {3497220000 0 0 WET}
+    {3510525600 3600 1 WEST}
+    {3528669600 0 0 WET}
+    {3541975200 3600 1 WEST}
+    {3560119200 0 0 WET}
+    {3573424800 3600 1 WEST}
+    {3592173600 0 0 WET}
+    {3604874400 3600 1 WEST}
+    {3623623200 0 0 WET}
+    {3636324000 3600 1 WEST}
+    {3655072800 0 0 WET}
+    {3668378400 3600 1 WEST}
+    {3686522400 0 0 WET}
+    {3699828000 3600 1 WEST}
+    {3717972000 0 0 WET}
+    {3731277600 3600 1 WEST}
+    {3750026400 0 0 WET}
+    {3762727200 3600 1 WEST}
+    {3781476000 0 0 WET}
+    {3794176800 3600 1 WEST}
+    {3812925600 0 0 WET}
+    {3825626400 3600 1 WEST}
+    {3844375200 0 0 WET}
+    {3857680800 3600 1 WEST}
+    {3875824800 0 0 WET}
+    {3889130400 3600 1 WEST}
+    {3907274400 0 0 WET}
+    {3920580000 3600 1 WEST}
+    {3939328800 0 0 WET}
+    {3952029600 3600 1 WEST}
+    {3970778400 0 0 WET}
+    {3983479200 3600 1 WEST}
+    {4002228000 0 0 WET}
+    {4015533600 3600 1 WEST}
+    {4033677600 0 0 WET}
+    {4046983200 3600 1 WEST}
+    {4065127200 0 0 WET}
+    {4078432800 3600 1 WEST}
+    {4096576800 0 0 WET}
+}
diff --git a/library/tzdata/Africa/Ceuta b/library/tzdata/Africa/Ceuta
new file mode 100644
index 0000000..882c13d
--- /dev/null
+++ b/library/tzdata/Africa/Ceuta
@@ -0,0 +1,258 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Africa/Ceuta) {
+    {-9223372036854775808 -1276 0 LMT}
+    {-2177451524 0 0 WET}
+    {-1630112400 3600 1 WEST}
+    {-1616810400 0 0 WET}
+    {-1451692800 0 0 WET}
+    {-1442451600 3600 1 WEST}
+    {-1427677200 0 0 WET}
+    {-1379293200 3600 1 WEST}
+    {-1364778000 0 0 WET}
+    {-1348448400 3600 1 WEST}
+    {-1333328400 0 0 WET}
+    {-1316394000 3600 1 WEST}
+    {-1301274000 0 0 WET}
+    {-1293840000 0 0 WET}
+    {-81432000 3600 1 WEST}
+    {-71110800 0 0 WET}
+    {141264000 3600 1 WEST}
+    {147222000 0 0 WET}
+    {199756800 3600 1 WEST}
+    {207702000 0 0 WET}
+    {231292800 3600 1 WEST}
+    {244249200 0 0 WET}
+    {265507200 3600 1 WEST}
+    {271033200 0 0 WET}
+    {448243200 3600 0 CET}
+    {504918000 3600 0 CET}
+    {512528400 7200 1 CEST}
+    {528253200 3600 0 CET}
+    {543978000 7200 1 CEST}
+    {559702800 3600 0 CET}
+    {575427600 7200 1 CEST}
+    {591152400 3600 0 CET}
+    {606877200 7200 1 CEST}
+    {622602000 3600 0 CET}
+    {638326800 7200 1 CEST}
+    {654656400 3600 0 CET}
+    {670381200 7200 1 CEST}
+    {686106000 3600 0 CET}
+    {701830800 7200 1 CEST}
+    {717555600 3600 0 CET}
+    {733280400 7200 1 CEST}
+    {749005200 3600 0 CET}
+    {764730000 7200 1 CEST}
+    {780454800 3600 0 CET}
+    {796179600 7200 1 CEST}
+    {811904400 3600 0 CET}
+    {828234000 7200 1 CEST}
+    {846378000 3600 0 CET}
+    {859683600 7200 1 CEST}
+    {877827600 3600 0 CET}
+    {891133200 7200 1 CEST}
+    {909277200 3600 0 CET}
+    {922582800 7200 1 CEST}
+    {941331600 3600 0 CET}
+    {954032400 7200 1 CEST}
+    {972781200 3600 0 CET}
+    {985482000 7200 1 CEST}
+    {1004230800 3600 0 CET}
+    {1017536400 7200 1 CEST}
+    {1035680400 3600 0 CET}
+    {1048986000 7200 1 CEST}
+    {1067130000 3600 0 CET}
+    {1080435600 7200 1 CEST}
+    {1099184400 3600 0 CET}
+    {1111885200 7200 1 CEST}
+    {1130634000 3600 0 CET}
+    {1143334800 7200 1 CEST}
+    {1162083600 3600 0 CET}
+    {1174784400 7200 1 CEST}
+    {1193533200 3600 0 CET}
+    {1206838800 7200 1 CEST}
+    {1224982800 3600 0 CET}
+    {1238288400 7200 1 CEST}
+    {1256432400 3600 0 CET}
+    {1269738000 7200 1 CEST}
+    {1288486800 3600 0 CET}
+    {1301187600 7200 1 CEST}
+    {1319936400 3600 0 CET}
+    {1332637200 7200 1 CEST}
+    {1351386000 3600 0 CET}
+    {1364691600 7200 1 CEST}
+    {1382835600 3600 0 CET}
+    {1396141200 7200 1 CEST}
+    {1414285200 3600 0 CET}
+    {1427590800 7200 1 CEST}
+    {1445734800 3600 0 CET}
+    {1459040400 7200 1 CEST}
+    {1477789200 3600 0 CET}
+    {1490490000 7200 1 CEST}
+    {1509238800 3600 0 CET}
+    {1521939600 7200 1 CEST}
+    {1540688400 3600 0 CET}
+    {1553994000 7200 1 CEST}
+    {1572138000 3600 0 CET}
+    {1585443600 7200 1 CEST}
+    {1603587600 3600 0 CET}
+    {1616893200 7200 1 CEST}
+    {1635642000 3600 0 CET}
+    {1648342800 7200 1 CEST}
+    {1667091600 3600 0 CET}
+    {1679792400 7200 1 CEST}
+    {1698541200 3600 0 CET}
+    {1711846800 7200 1 CEST}
+    {1729990800 3600 0 CET}
+    {1743296400 7200 1 CEST}
+    {1761440400 3600 0 CET}
+    {1774746000 7200 1 CEST}
+    {1792890000 3600 0 CET}
+    {1806195600 7200 1 CEST}
+    {1824944400 3600 0 CET}
+    {1837645200 7200 1 CEST}
+    {1856394000 3600 0 CET}
+    {1869094800 7200 1 CEST}
+    {1887843600 3600 0 CET}
+    {1901149200 7200 1 CEST}
+    {1919293200 3600 0 CET}
+    {1932598800 7200 1 CEST}
+    {1950742800 3600 0 CET}
+    {1964048400 7200 1 CEST}
+    {1982797200 3600 0 CET}
+    {1995498000 7200 1 CEST}
+    {2014246800 3600 0 CET}
+    {2026947600 7200 1 CEST}
+    {2045696400 3600 0 CET}
+    {2058397200 7200 1 CEST}
+    {2077146000 3600 0 CET}
+    {2090451600 7200 1 CEST}
+    {2108595600 3600 0 CET}
+    {2121901200 7200 1 CEST}
+    {2140045200 3600 0 CET}
+    {2153350800 7200 1 CEST}
+    {2172099600 3600 0 CET}
+    {2184800400 7200 1 CEST}
+    {2203549200 3600 0 CET}
+    {2216250000 7200 1 CEST}
+    {2234998800 3600 0 CET}
+    {2248304400 7200 1 CEST}
+    {2266448400 3600 0 CET}
+    {2279754000 7200 1 CEST}
+    {2297898000 3600 0 CET}
+    {2311203600 7200 1 CEST}
+    {2329347600 3600 0 CET}
+    {2342653200 7200 1 CEST}
+    {2361402000 3600 0 CET}
+    {2374102800 7200 1 CEST}
+    {2392851600 3600 0 CET}
+    {2405552400 7200 1 CEST}
+    {2424301200 3600 0 CET}
+    {2437606800 7200 1 CEST}
+    {2455750800 3600 0 CET}
+    {2469056400 7200 1 CEST}
+    {2487200400 3600 0 CET}
+    {2500506000 7200 1 CEST}
+    {2519254800 3600 0 CET}
+    {2531955600 7200 1 CEST}
+    {2550704400 3600 0 CET}
+    {2563405200 7200 1 CEST}
+    {2582154000 3600 0 CET}
+    {2595459600 7200 1 CEST}
+    {2613603600 3600 0 CET}
+    {2626909200 7200 1 CEST}
+    {2645053200 3600 0 CET}
+    {2658358800 7200 1 CEST}
+    {2676502800 3600 0 CET}
+    {2689808400 7200 1 CEST}
+    {2708557200 3600 0 CET}
+    {2721258000 7200 1 CEST}
+    {2740006800 3600 0 CET}
+    {2752707600 7200 1 CEST}
+    {2771456400 3600 0 CET}
+    {2784762000 7200 1 CEST}
+    {2802906000 3600 0 CET}
+    {2816211600 7200 1 CEST}
+    {2834355600 3600 0 CET}
+    {2847661200 7200 1 CEST}
+    {2866410000 3600 0 CET}
+    {2879110800 7200 1 CEST}
+    {2897859600 3600 0 CET}
+    {2910560400 7200 1 CEST}
+    {2929309200 3600 0 CET}
+    {2942010000 7200 1 CEST}
+    {2960758800 3600 0 CET}
+    {2974064400 7200 1 CEST}
+    {2992208400 3600 0 CET}
+    {3005514000 7200 1 CEST}
+    {3023658000 3600 0 CET}
+    {3036963600 7200 1 CEST}
+    {3055712400 3600 0 CET}
+    {3068413200 7200 1 CEST}
+    {3087162000 3600 0 CET}
+    {3099862800 7200 1 CEST}
+    {3118611600 3600 0 CET}
+    {3131917200 7200 1 CEST}
+    {3150061200 3600 0 CET}
+    {3163366800 7200 1 CEST}
+    {3181510800 3600 0 CET}
+    {3194816400 7200 1 CEST}
+    {3212960400 3600 0 CET}
+    {3226266000 7200 1 CEST}
+    {3245014800 3600 0 CET}
+    {3257715600 7200 1 CEST}
+    {3276464400 3600 0 CET}
+    {3289165200 7200 1 CEST}
+    {3307914000 3600 0 CET}
+    {3321219600 7200 1 CEST}
+    {3339363600 3600 0 CET}
+    {3352669200 7200 1 CEST}
+    {3370813200 3600 0 CET}
+    {3384118800 7200 1 CEST}
+    {3402867600 3600 0 CET}
+    {3415568400 7200 1 CEST}
+    {3434317200 3600 0 CET}
+    {3447018000 7200 1 CEST}
+    {3465766800 3600 0 CET}
+    {3479072400 7200 1 CEST}
+    {3497216400 3600 0 CET}
+    {3510522000 7200 1 CEST}
+    {3528666000 3600 0 CET}
+    {3541971600 7200 1 CEST}
+    {3560115600 3600 0 CET}
+    {3573421200 7200 1 CEST}
+    {3592170000 3600 0 CET}
+    {3604870800 7200 1 CEST}
+    {3623619600 3600 0 CET}
+    {3636320400 7200 1 CEST}
+    {3655069200 3600 0 CET}
+    {3668374800 7200 1 CEST}
+    {3686518800 3600 0 CET}
+    {3699824400 7200 1 CEST}
+    {3717968400 3600 0 CET}
+    {3731274000 7200 1 CEST}
+    {3750022800 3600 0 CET}
+    {3762723600 7200 1 CEST}
+    {3781472400 3600 0 CET}
+    {3794173200 7200 1 CEST}
+    {3812922000 3600 0 CET}
+    {3825622800 7200 1 CEST}
+    {3844371600 3600 0 CET}
+    {3857677200 7200 1 CEST}
+    {3875821200 3600 0 CET}
+    {3889126800 7200 1 CEST}
+    {3907270800 3600 0 CET}
+    {3920576400 7200 1 CEST}
+    {3939325200 3600 0 CET}
+    {3952026000 7200 1 CEST}
+    {3970774800 3600 0 CET}
+    {3983475600 7200 1 CEST}
+    {4002224400 3600 0 CET}
+    {4015530000 7200 1 CEST}
+    {4033674000 3600 0 CET}
+    {4046979600 7200 1 CEST}
+    {4065123600 3600 0 CET}
+    {4078429200 7200 1 CEST}
+    {4096573200 3600 0 CET}
+}
diff --git a/library/tzdata/Africa/Conakry b/library/tzdata/Africa/Conakry
new file mode 100644
index 0000000..4373720
--- /dev/null
+++ b/library/tzdata/Africa/Conakry
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Africa/Abidjan)]} {
+    LoadTimeZoneFile Africa/Abidjan
+}
+set TZData(:Africa/Conakry) $TZData(:Africa/Abidjan)
diff --git a/library/tzdata/Africa/Dakar b/library/tzdata/Africa/Dakar
new file mode 100644
index 0000000..78e800c
--- /dev/null
+++ b/library/tzdata/Africa/Dakar
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Africa/Abidjan)]} {
+    LoadTimeZoneFile Africa/Abidjan
+}
+set TZData(:Africa/Dakar) $TZData(:Africa/Abidjan)
diff --git a/library/tzdata/Africa/Dar_es_Salaam b/library/tzdata/Africa/Dar_es_Salaam
new file mode 100644
index 0000000..00e8d4e
--- /dev/null
+++ b/library/tzdata/Africa/Dar_es_Salaam
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Africa/Nairobi)]} {
+    LoadTimeZoneFile Africa/Nairobi
+}
+set TZData(:Africa/Dar_es_Salaam) $TZData(:Africa/Nairobi)
diff --git a/library/tzdata/Africa/Djibouti b/library/tzdata/Africa/Djibouti
new file mode 100644
index 0000000..859ea32
--- /dev/null
+++ b/library/tzdata/Africa/Djibouti
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Africa/Nairobi)]} {
+    LoadTimeZoneFile Africa/Nairobi
+}
+set TZData(:Africa/Djibouti) $TZData(:Africa/Nairobi)
diff --git a/library/tzdata/Africa/Douala b/library/tzdata/Africa/Douala
new file mode 100644
index 0000000..892b16a
--- /dev/null
+++ b/library/tzdata/Africa/Douala
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Africa/Lagos)]} {
+    LoadTimeZoneFile Africa/Lagos
+}
+set TZData(:Africa/Douala) $TZData(:Africa/Lagos)
diff --git a/library/tzdata/Africa/El_Aaiun b/library/tzdata/Africa/El_Aaiun
new file mode 100644
index 0000000..77e149e
--- /dev/null
+++ b/library/tzdata/Africa/El_Aaiun
@@ -0,0 +1,219 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Africa/El_Aaiun) {
+    {-9223372036854775808 -3168 0 LMT}
+    {-1136070432 -3600 0 WAT}
+    {198291600 0 0 WET}
+    {199756800 3600 1 WEST}
+    {207702000 0 0 WET}
+    {231292800 3600 1 WEST}
+    {244249200 0 0 WET}
+    {265507200 3600 1 WEST}
+    {271033200 0 0 WET}
+    {1212278400 3600 1 WEST}
+    {1220223600 0 0 WET}
+    {1243814400 3600 1 WEST}
+    {1250809200 0 0 WET}
+    {1272758400 3600 1 WEST}
+    {1281222000 0 0 WET}
+    {1301788800 3600 1 WEST}
+    {1312066800 0 0 WET}
+    {1335664800 3600 1 WEST}
+    {1342749600 0 0 WET}
+    {1345428000 3600 1 WEST}
+    {1348970400 0 0 WET}
+    {1367114400 3600 1 WEST}
+    {1373162400 0 0 WET}
+    {1376100000 3600 1 WEST}
+    {1382839200 0 0 WET}
+    {1396144800 3600 1 WEST}
+    {1403920800 0 0 WET}
+    {1406944800 3600 1 WEST}
+    {1414288800 0 0 WET}
+    {1427594400 3600 1 WEST}
+    {1434247200 0 0 WET}
+    {1437271200 3600 1 WEST}
+    {1445738400 0 0 WET}
+    {1459044000 3600 1 WEST}
+    {1465092000 0 0 WET}
+    {1468116000 3600 1 WEST}
+    {1477792800 0 0 WET}
+    {1490493600 3600 1 WEST}
+    {1495332000 0 0 WET}
+    {1498960800 3600 1 WEST}
+    {1509242400 0 0 WET}
+    {1521943200 3600 1 WEST}
+    {1526176800 0 0 WET}
+    {1529200800 3600 1 WEST}
+    {1540692000 0 0 WET}
+    {1553997600 3600 1 WEST}
+    {1557021600 0 0 WET}
+    {1560045600 3600 1 WEST}
+    {1572141600 0 0 WET}
+    {1585447200 3600 1 WEST}
+    {1587261600 0 0 WET}
+    {1590285600 3600 1 WEST}
+    {1603591200 0 0 WET}
+    {1616896800 3600 1 WEST}
+    {1618106400 0 0 WET}
+    {1621130400 3600 1 WEST}
+    {1635645600 0 0 WET}
+    {1651975200 3600 1 WEST}
+    {1667095200 0 0 WET}
+    {1682215200 3600 1 WEST}
+    {1698544800 0 0 WET}
+    {1713060000 3600 1 WEST}
+    {1729994400 0 0 WET}
+    {1743904800 3600 1 WEST}
+    {1761444000 0 0 WET}
+    {1774749600 3600 1 WEST}
+    {1792893600 0 0 WET}
+    {1806199200 3600 1 WEST}
+    {1824948000 0 0 WET}
+    {1837648800 3600 1 WEST}
+    {1856397600 0 0 WET}
+    {1869098400 3600 1 WEST}
+    {1887847200 0 0 WET}
+    {1901152800 3600 1 WEST}
+    {1919296800 0 0 WET}
+    {1932602400 3600 1 WEST}
+    {1950746400 0 0 WET}
+    {1964052000 3600 1 WEST}
+    {1982800800 0 0 WET}
+    {1995501600 3600 1 WEST}
+    {2014250400 0 0 WET}
+    {2026951200 3600 1 WEST}
+    {2045700000 0 0 WET}
+    {2058400800 3600 1 WEST}
+    {2077149600 0 0 WET}
+    {2090455200 3600 1 WEST}
+    {2107994400 0 0 WET}
+    {2108602800 0 0 WET}
+    {2121904800 3600 1 WEST}
+    {2138234400 0 0 WET}
+    {2140052400 0 0 WET}
+    {2153354400 3600 1 WEST}
+    {2172103200 0 0 WET}
+    {2184804000 3600 1 WEST}
+    {2203552800 0 0 WET}
+    {2216253600 3600 1 WEST}
+    {2235002400 0 0 WET}
+    {2248308000 3600 1 WEST}
+    {2266452000 0 0 WET}
+    {2279757600 3600 1 WEST}
+    {2297901600 0 0 WET}
+    {2311207200 3600 1 WEST}
+    {2329351200 0 0 WET}
+    {2342656800 3600 1 WEST}
+    {2361405600 0 0 WET}
+    {2374106400 3600 1 WEST}
+    {2392855200 0 0 WET}
+    {2405556000 3600 1 WEST}
+    {2424304800 0 0 WET}
+    {2437610400 3600 1 WEST}
+    {2455754400 0 0 WET}
+    {2469060000 3600 1 WEST}
+    {2487204000 0 0 WET}
+    {2500509600 3600 1 WEST}
+    {2519258400 0 0 WET}
+    {2531959200 3600 1 WEST}
+    {2550708000 0 0 WET}
+    {2563408800 3600 1 WEST}
+    {2582157600 0 0 WET}
+    {2595463200 3600 1 WEST}
+    {2613607200 0 0 WET}
+    {2626912800 3600 1 WEST}
+    {2645056800 0 0 WET}
+    {2658362400 3600 1 WEST}
+    {2676506400 0 0 WET}
+    {2689812000 3600 1 WEST}
+    {2708560800 0 0 WET}
+    {2721261600 3600 1 WEST}
+    {2740010400 0 0 WET}
+    {2752711200 3600 1 WEST}
+    {2771460000 0 0 WET}
+    {2784765600 3600 1 WEST}
+    {2802909600 0 0 WET}
+    {2816215200 3600 1 WEST}
+    {2834359200 0 0 WET}
+    {2847664800 3600 1 WEST}
+    {2866413600 0 0 WET}
+    {2879114400 3600 1 WEST}
+    {2897863200 0 0 WET}
+    {2910564000 3600 1 WEST}
+    {2929312800 0 0 WET}
+    {2942013600 3600 1 WEST}
+    {2960762400 0 0 WET}
+    {2974068000 3600 1 WEST}
+    {2992212000 0 0 WET}
+    {3005517600 3600 1 WEST}
+    {3023661600 0 0 WET}
+    {3036967200 3600 1 WEST}
+    {3055716000 0 0 WET}
+    {3068416800 3600 1 WEST}
+    {3087165600 0 0 WET}
+    {3099866400 3600 1 WEST}
+    {3118615200 0 0 WET}
+    {3131920800 3600 1 WEST}
+    {3150064800 0 0 WET}
+    {3163370400 3600 1 WEST}
+    {3181514400 0 0 WET}
+    {3194820000 3600 1 WEST}
+    {3212964000 0 0 WET}
+    {3226269600 3600 1 WEST}
+    {3245018400 0 0 WET}
+    {3257719200 3600 1 WEST}
+    {3276468000 0 0 WET}
+    {3289168800 3600 1 WEST}
+    {3307917600 0 0 WET}
+    {3321223200 3600 1 WEST}
+    {3339367200 0 0 WET}
+    {3352672800 3600 1 WEST}
+    {3370816800 0 0 WET}
+    {3384122400 3600 1 WEST}
+    {3402871200 0 0 WET}
+    {3415572000 3600 1 WEST}
+    {3434320800 0 0 WET}
+    {3447021600 3600 1 WEST}
+    {3465770400 0 0 WET}
+    {3479076000 3600 1 WEST}
+    {3497220000 0 0 WET}
+    {3510525600 3600 1 WEST}
+    {3528669600 0 0 WET}
+    {3541975200 3600 1 WEST}
+    {3560119200 0 0 WET}
+    {3573424800 3600 1 WEST}
+    {3592173600 0 0 WET}
+    {3604874400 3600 1 WEST}
+    {3623623200 0 0 WET}
+    {3636324000 3600 1 WEST}
+    {3655072800 0 0 WET}
+    {3668378400 3600 1 WEST}
+    {3686522400 0 0 WET}
+    {3699828000 3600 1 WEST}
+    {3717972000 0 0 WET}
+    {3731277600 3600 1 WEST}
+    {3750026400 0 0 WET}
+    {3762727200 3600 1 WEST}
+    {3781476000 0 0 WET}
+    {3794176800 3600 1 WEST}
+    {3812925600 0 0 WET}
+    {3825626400 3600 1 WEST}
+    {3844375200 0 0 WET}
+    {3857680800 3600 1 WEST}
+    {3875824800 0 0 WET}
+    {3889130400 3600 1 WEST}
+    {3907274400 0 0 WET}
+    {3920580000 3600 1 WEST}
+    {3939328800 0 0 WET}
+    {3952029600 3600 1 WEST}
+    {3970778400 0 0 WET}
+    {3983479200 3600 1 WEST}
+    {4002228000 0 0 WET}
+    {4015533600 3600 1 WEST}
+    {4033677600 0 0 WET}
+    {4046983200 3600 1 WEST}
+    {4065127200 0 0 WET}
+    {4078432800 3600 1 WEST}
+    {4096576800 0 0 WET}
+}
diff --git a/library/tzdata/Africa/Freetown b/library/tzdata/Africa/Freetown
new file mode 100644
index 0000000..4a8e2e1
--- /dev/null
+++ b/library/tzdata/Africa/Freetown
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Africa/Abidjan)]} {
+    LoadTimeZoneFile Africa/Abidjan
+}
+set TZData(:Africa/Freetown) $TZData(:Africa/Abidjan)
diff --git a/library/tzdata/Africa/Gaborone b/library/tzdata/Africa/Gaborone
new file mode 100644
index 0000000..56c0772
--- /dev/null
+++ b/library/tzdata/Africa/Gaborone
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Africa/Maputo)]} {
+    LoadTimeZoneFile Africa/Maputo
+}
+set TZData(:Africa/Gaborone) $TZData(:Africa/Maputo)
diff --git a/library/tzdata/Africa/Harare b/library/tzdata/Africa/Harare
new file mode 100644
index 0000000..644be26
--- /dev/null
+++ b/library/tzdata/Africa/Harare
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Africa/Maputo)]} {
+    LoadTimeZoneFile Africa/Maputo
+}
+set TZData(:Africa/Harare) $TZData(:Africa/Maputo)
diff --git a/library/tzdata/Africa/Johannesburg b/library/tzdata/Africa/Johannesburg
new file mode 100644
index 0000000..b9a8348
--- /dev/null
+++ b/library/tzdata/Africa/Johannesburg
@@ -0,0 +1,11 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Africa/Johannesburg) {
+    {-9223372036854775808 6720 0 LMT}
+    {-2458173120 5400 0 SAST}
+    {-2109288600 7200 0 SAST}
+    {-860976000 10800 1 SAST}
+    {-845254800 7200 0 SAST}
+    {-829526400 10800 1 SAST}
+    {-813805200 7200 0 SAST}
+}
diff --git a/library/tzdata/Africa/Juba b/library/tzdata/Africa/Juba
new file mode 100644
index 0000000..40551f2
--- /dev/null
+++ b/library/tzdata/Africa/Juba
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Africa/Khartoum)]} {
+    LoadTimeZoneFile Africa/Khartoum
+}
+set TZData(:Africa/Juba) $TZData(:Africa/Khartoum)
diff --git a/library/tzdata/Africa/Kampala b/library/tzdata/Africa/Kampala
new file mode 100644
index 0000000..1fbaffc
--- /dev/null
+++ b/library/tzdata/Africa/Kampala
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Africa/Nairobi)]} {
+    LoadTimeZoneFile Africa/Nairobi
+}
+set TZData(:Africa/Kampala) $TZData(:Africa/Nairobi)
diff --git a/library/tzdata/Africa/Khartoum b/library/tzdata/Africa/Khartoum
new file mode 100644
index 0000000..dfcac82
--- /dev/null
+++ b/library/tzdata/Africa/Khartoum
@@ -0,0 +1,39 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Africa/Khartoum) {
+    {-9223372036854775808 7808 0 LMT}
+    {-1230775808 7200 0 CAT}
+    {10360800 10800 1 CAST}
+    {24786000 7200 0 CAT}
+    {41810400 10800 1 CAST}
+    {56322000 7200 0 CAT}
+    {73432800 10800 1 CAST}
+    {87944400 7200 0 CAT}
+    {104882400 10800 1 CAST}
+    {119480400 7200 0 CAT}
+    {136332000 10800 1 CAST}
+    {151016400 7200 0 CAT}
+    {167781600 10800 1 CAST}
+    {182552400 7200 0 CAT}
+    {199231200 10800 1 CAST}
+    {214174800 7200 0 CAT}
+    {230680800 10800 1 CAST}
+    {245710800 7200 0 CAT}
+    {262735200 10800 1 CAST}
+    {277246800 7200 0 CAT}
+    {294184800 10800 1 CAST}
+    {308782800 7200 0 CAT}
+    {325634400 10800 1 CAST}
+    {340405200 7200 0 CAT}
+    {357084000 10800 1 CAST}
+    {371941200 7200 0 CAT}
+    {388533600 10800 1 CAST}
+    {403477200 7200 0 CAT}
+    {419983200 10800 1 CAST}
+    {435013200 7200 0 CAT}
+    {452037600 10800 1 CAST}
+    {466635600 7200 0 CAT}
+    {483487200 10800 1 CAST}
+    {498171600 7200 0 CAT}
+    {947930400 10800 0 EAT}
+}
diff --git a/library/tzdata/Africa/Kigali b/library/tzdata/Africa/Kigali
new file mode 100644
index 0000000..192e0e8
--- /dev/null
+++ b/library/tzdata/Africa/Kigali
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Africa/Maputo)]} {
+    LoadTimeZoneFile Africa/Maputo
+}
+set TZData(:Africa/Kigali) $TZData(:Africa/Maputo)
diff --git a/library/tzdata/Africa/Kinshasa b/library/tzdata/Africa/Kinshasa
new file mode 100644
index 0000000..04dc62e
--- /dev/null
+++ b/library/tzdata/Africa/Kinshasa
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Africa/Lagos)]} {
+    LoadTimeZoneFile Africa/Lagos
+}
+set TZData(:Africa/Kinshasa) $TZData(:Africa/Lagos)
diff --git a/library/tzdata/Africa/Lagos b/library/tzdata/Africa/Lagos
new file mode 100644
index 0000000..079572f
--- /dev/null
+++ b/library/tzdata/Africa/Lagos
@@ -0,0 +1,6 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Africa/Lagos) {
+    {-9223372036854775808 816 0 LMT}
+    {-1588464816 3600 0 WAT}
+}
diff --git a/library/tzdata/Africa/Libreville b/library/tzdata/Africa/Libreville
new file mode 100644
index 0000000..ba1f686
--- /dev/null
+++ b/library/tzdata/Africa/Libreville
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Africa/Lagos)]} {
+    LoadTimeZoneFile Africa/Lagos
+}
+set TZData(:Africa/Libreville) $TZData(:Africa/Lagos)
diff --git a/library/tzdata/Africa/Lome b/library/tzdata/Africa/Lome
new file mode 100644
index 0000000..9adecc7
--- /dev/null
+++ b/library/tzdata/Africa/Lome
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Africa/Abidjan)]} {
+    LoadTimeZoneFile Africa/Abidjan
+}
+set TZData(:Africa/Lome) $TZData(:Africa/Abidjan)
diff --git a/library/tzdata/Africa/Luanda b/library/tzdata/Africa/Luanda
new file mode 100644
index 0000000..8dcd107
--- /dev/null
+++ b/library/tzdata/Africa/Luanda
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Africa/Lagos)]} {
+    LoadTimeZoneFile Africa/Lagos
+}
+set TZData(:Africa/Luanda) $TZData(:Africa/Lagos)
diff --git a/library/tzdata/Africa/Lubumbashi b/library/tzdata/Africa/Lubumbashi
new file mode 100644
index 0000000..7da101a
--- /dev/null
+++ b/library/tzdata/Africa/Lubumbashi
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Africa/Maputo)]} {
+    LoadTimeZoneFile Africa/Maputo
+}
+set TZData(:Africa/Lubumbashi) $TZData(:Africa/Maputo)
diff --git a/library/tzdata/Africa/Lusaka b/library/tzdata/Africa/Lusaka
new file mode 100644
index 0000000..bcf519d
--- /dev/null
+++ b/library/tzdata/Africa/Lusaka
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Africa/Maputo)]} {
+    LoadTimeZoneFile Africa/Maputo
+}
+set TZData(:Africa/Lusaka) $TZData(:Africa/Maputo)
diff --git a/library/tzdata/Africa/Malabo b/library/tzdata/Africa/Malabo
new file mode 100644
index 0000000..7dcee39
--- /dev/null
+++ b/library/tzdata/Africa/Malabo
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Africa/Lagos)]} {
+    LoadTimeZoneFile Africa/Lagos
+}
+set TZData(:Africa/Malabo) $TZData(:Africa/Lagos)
diff --git a/library/tzdata/Africa/Maputo b/library/tzdata/Africa/Maputo
new file mode 100644
index 0000000..6ee208c
--- /dev/null
+++ b/library/tzdata/Africa/Maputo
@@ -0,0 +1,6 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Africa/Maputo) {
+    {-9223372036854775808 7820 0 LMT}
+    {-2109291020 7200 0 CAT}
+}
diff --git a/library/tzdata/Africa/Maseru b/library/tzdata/Africa/Maseru
new file mode 100644
index 0000000..665f15d
--- /dev/null
+++ b/library/tzdata/Africa/Maseru
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Africa/Johannesburg)]} {
+    LoadTimeZoneFile Africa/Johannesburg
+}
+set TZData(:Africa/Maseru) $TZData(:Africa/Johannesburg)
diff --git a/library/tzdata/Africa/Mbabane b/library/tzdata/Africa/Mbabane
new file mode 100644
index 0000000..0edb590
--- /dev/null
+++ b/library/tzdata/Africa/Mbabane
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Africa/Johannesburg)]} {
+    LoadTimeZoneFile Africa/Johannesburg
+}
+set TZData(:Africa/Mbabane) $TZData(:Africa/Johannesburg)
diff --git a/library/tzdata/Africa/Mogadishu b/library/tzdata/Africa/Mogadishu
new file mode 100644
index 0000000..4220655
--- /dev/null
+++ b/library/tzdata/Africa/Mogadishu
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Africa/Nairobi)]} {
+    LoadTimeZoneFile Africa/Nairobi
+}
+set TZData(:Africa/Mogadishu) $TZData(:Africa/Nairobi)
diff --git a/library/tzdata/Africa/Monrovia b/library/tzdata/Africa/Monrovia
new file mode 100644
index 0000000..1cfff58
--- /dev/null
+++ b/library/tzdata/Africa/Monrovia
@@ -0,0 +1,8 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Africa/Monrovia) {
+    {-9223372036854775808 -2588 0 LMT}
+    {-2776979812 -2588 0 MMT}
+    {-1604359012 -2670 0 LRT}
+    {73529070 0 0 GMT}
+}
diff --git a/library/tzdata/Africa/Nairobi b/library/tzdata/Africa/Nairobi
new file mode 100644
index 0000000..6846069
--- /dev/null
+++ b/library/tzdata/Africa/Nairobi
@@ -0,0 +1,9 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Africa/Nairobi) {
+    {-9223372036854775808 8836 0 LMT}
+    {-1309746436 10800 0 EAT}
+    {-1262314800 9000 0 BEAT}
+    {-946780200 9900 0 BEAUT}
+    {-315629100 10800 0 EAT}
+}
diff --git a/library/tzdata/Africa/Ndjamena b/library/tzdata/Africa/Ndjamena
new file mode 100644
index 0000000..af4daaa
--- /dev/null
+++ b/library/tzdata/Africa/Ndjamena
@@ -0,0 +1,8 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Africa/Ndjamena) {
+    {-9223372036854775808 3612 0 LMT}
+    {-1830387612 3600 0 WAT}
+    {308703600 7200 1 WAST}
+    {321314400 3600 0 WAT}
+}
diff --git a/library/tzdata/Africa/Niamey b/library/tzdata/Africa/Niamey
new file mode 100644
index 0000000..278571d
--- /dev/null
+++ b/library/tzdata/Africa/Niamey
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Africa/Lagos)]} {
+    LoadTimeZoneFile Africa/Lagos
+}
+set TZData(:Africa/Niamey) $TZData(:Africa/Lagos)
diff --git a/library/tzdata/Africa/Nouakchott b/library/tzdata/Africa/Nouakchott
new file mode 100644
index 0000000..d33b6bc
--- /dev/null
+++ b/library/tzdata/Africa/Nouakchott
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Africa/Abidjan)]} {
+    LoadTimeZoneFile Africa/Abidjan
+}
+set TZData(:Africa/Nouakchott) $TZData(:Africa/Abidjan)
diff --git a/library/tzdata/Africa/Ouagadougou b/library/tzdata/Africa/Ouagadougou
new file mode 100644
index 0000000..8178c82
--- /dev/null
+++ b/library/tzdata/Africa/Ouagadougou
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Africa/Abidjan)]} {
+    LoadTimeZoneFile Africa/Abidjan
+}
+set TZData(:Africa/Ouagadougou) $TZData(:Africa/Abidjan)
diff --git a/library/tzdata/Africa/Porto-Novo b/library/tzdata/Africa/Porto-Novo
new file mode 100644
index 0000000..3fa2b51
--- /dev/null
+++ b/library/tzdata/Africa/Porto-Novo
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Africa/Lagos)]} {
+    LoadTimeZoneFile Africa/Lagos
+}
+set TZData(:Africa/Porto-Novo) $TZData(:Africa/Lagos)
diff --git a/library/tzdata/Africa/Sao_Tome b/library/tzdata/Africa/Sao_Tome
new file mode 100644
index 0000000..078591d
--- /dev/null
+++ b/library/tzdata/Africa/Sao_Tome
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Africa/Abidjan)]} {
+    LoadTimeZoneFile Africa/Abidjan
+}
+set TZData(:Africa/Sao_Tome) $TZData(:Africa/Abidjan)
diff --git a/library/tzdata/Africa/Timbuktu b/library/tzdata/Africa/Timbuktu
new file mode 100644
index 0000000..9852d7a
--- /dev/null
+++ b/library/tzdata/Africa/Timbuktu
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Africa/Abidjan)]} {
+    LoadTimeZoneFile Africa/Abidjan
+}
+set TZData(:Africa/Timbuktu) $TZData(:Africa/Abidjan)
diff --git a/library/tzdata/Africa/Tripoli b/library/tzdata/Africa/Tripoli
new file mode 100644
index 0000000..0e72df4
--- /dev/null
+++ b/library/tzdata/Africa/Tripoli
@@ -0,0 +1,34 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Africa/Tripoli) {
+    {-9223372036854775808 3164 0 LMT}
+    {-1577926364 3600 0 CET}
+    {-574902000 7200 1 CEST}
+    {-512175600 7200 1 CEST}
+    {-449888400 7200 1 CEST}
+    {-347158800 7200 0 EET}
+    {378684000 3600 0 CET}
+    {386463600 7200 1 CEST}
+    {402271200 3600 0 CET}
+    {417999600 7200 1 CEST}
+    {433807200 3600 0 CET}
+    {449622000 7200 1 CEST}
+    {465429600 3600 0 CET}
+    {481590000 7200 1 CEST}
+    {496965600 3600 0 CET}
+    {512953200 7200 1 CEST}
+    {528674400 3600 0 CET}
+    {544230000 7200 1 CEST}
+    {560037600 3600 0 CET}
+    {575852400 7200 1 CEST}
+    {591660000 3600 0 CET}
+    {607388400 7200 1 CEST}
+    {623196000 3600 0 CET}
+    {641775600 7200 0 EET}
+    {844034400 3600 0 CET}
+    {860108400 7200 1 CEST}
+    {875919600 7200 0 EET}
+    {1352505600 3600 0 CET}
+    {1364515200 7200 1 CEST}
+    {1382662800 7200 0 EET}
+}
diff --git a/library/tzdata/Africa/Tunis b/library/tzdata/Africa/Tunis
new file mode 100644
index 0000000..0c1db4d
--- /dev/null
+++ b/library/tzdata/Africa/Tunis
@@ -0,0 +1,39 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Africa/Tunis) {
+    {-9223372036854775808 2444 0 LMT}
+    {-2797202444 561 0 PMT}
+    {-1855958961 3600 0 CET}
+    {-969242400 7200 1 CEST}
+    {-950493600 3600 0 CET}
+    {-941940000 7200 1 CEST}
+    {-891136800 3600 0 CET}
+    {-877827600 7200 1 CEST}
+    {-857257200 3600 0 CET}
+    {-844556400 7200 1 CEST}
+    {-842918400 3600 0 CET}
+    {-842223600 7200 1 CEST}
+    {-828230400 3600 0 CET}
+    {-812502000 7200 1 CEST}
+    {-796269600 3600 0 CET}
+    {-781052400 7200 1 CEST}
+    {-766634400 3600 0 CET}
+    {231202800 7200 1 CEST}
+    {243903600 3600 0 CET}
+    {262825200 7200 1 CEST}
+    {276044400 3600 0 CET}
+    {581122800 7200 1 CEST}
+    {591145200 3600 0 CET}
+    {606870000 7200 1 CEST}
+    {622594800 3600 0 CET}
+    {641516400 7200 1 CEST}
+    {654649200 3600 0 CET}
+    {1114902000 7200 1 CEST}
+    {1128038400 3600 0 CET}
+    {1143334800 7200 1 CEST}
+    {1162083600 3600 0 CET}
+    {1174784400 7200 1 CEST}
+    {1193533200 3600 0 CET}
+    {1206838800 7200 1 CEST}
+    {1224982800 3600 0 CET}
+}
diff --git a/library/tzdata/Africa/Windhoek b/library/tzdata/Africa/Windhoek
new file mode 100644
index 0000000..a655f2e
--- /dev/null
+++ b/library/tzdata/Africa/Windhoek
@@ -0,0 +1,222 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Africa/Windhoek) {
+    {-9223372036854775808 4104 0 LMT}
+    {-2458170504 5400 0 SWAT}
+    {-2109288600 7200 0 SAST}
+    {-860976000 10800 1 SAST}
+    {-845254800 7200 0 SAST}
+    {637970400 7200 0 CAT}
+    {765324000 3600 0 WAT}
+    {778640400 7200 1 WAST}
+    {796780800 3600 0 WAT}
+    {810090000 7200 1 WAST}
+    {828835200 3600 0 WAT}
+    {841539600 7200 1 WAST}
+    {860284800 3600 0 WAT}
+    {873594000 7200 1 WAST}
+    {891734400 3600 0 WAT}
+    {905043600 7200 1 WAST}
+    {923184000 3600 0 WAT}
+    {936493200 7200 1 WAST}
+    {954633600 3600 0 WAT}
+    {967942800 7200 1 WAST}
+    {986083200 3600 0 WAT}
+    {999392400 7200 1 WAST}
+    {1018137600 3600 0 WAT}
+    {1030842000 7200 1 WAST}
+    {1049587200 3600 0 WAT}
+    {1062896400 7200 1 WAST}
+    {1081036800 3600 0 WAT}
+    {1094346000 7200 1 WAST}
+    {1112486400 3600 0 WAT}
+    {1125795600 7200 1 WAST}
+    {1143936000 3600 0 WAT}
+    {1157245200 7200 1 WAST}
+    {1175385600 3600 0 WAT}
+    {1188694800 7200 1 WAST}
+    {1207440000 3600 0 WAT}
+    {1220749200 7200 1 WAST}
+    {1238889600 3600 0 WAT}
+    {1252198800 7200 1 WAST}
+    {1270339200 3600 0 WAT}
+    {1283648400 7200 1 WAST}
+    {1301788800 3600 0 WAT}
+    {1315098000 7200 1 WAST}
+    {1333238400 3600 0 WAT}
+    {1346547600 7200 1 WAST}
+    {1365292800 3600 0 WAT}
+    {1377997200 7200 1 WAST}
+    {1396742400 3600 0 WAT}
+    {1410051600 7200 1 WAST}
+    {1428192000 3600 0 WAT}
+    {1441501200 7200 1 WAST}
+    {1459641600 3600 0 WAT}
+    {1472950800 7200 1 WAST}
+    {1491091200 3600 0 WAT}
+    {1504400400 7200 1 WAST}
+    {1522540800 3600 0 WAT}
+    {1535850000 7200 1 WAST}
+    {1554595200 3600 0 WAT}
+    {1567299600 7200 1 WAST}
+    {1586044800 3600 0 WAT}
+    {1599354000 7200 1 WAST}
+    {1617494400 3600 0 WAT}
+    {1630803600 7200 1 WAST}
+    {1648944000 3600 0 WAT}
+    {1662253200 7200 1 WAST}
+    {1680393600 3600 0 WAT}
+    {1693702800 7200 1 WAST}
+    {1712448000 3600 0 WAT}
+    {1725152400 7200 1 WAST}
+    {1743897600 3600 0 WAT}
+    {1757206800 7200 1 WAST}
+    {1775347200 3600 0 WAT}
+    {1788656400 7200 1 WAST}
+    {1806796800 3600 0 WAT}
+    {1820106000 7200 1 WAST}
+    {1838246400 3600 0 WAT}
+    {1851555600 7200 1 WAST}
+    {1869696000 3600 0 WAT}
+    {1883005200 7200 1 WAST}
+    {1901750400 3600 0 WAT}
+    {1914454800 7200 1 WAST}
+    {1933200000 3600 0 WAT}
+    {1946509200 7200 1 WAST}
+    {1964649600 3600 0 WAT}
+    {1977958800 7200 1 WAST}
+    {1996099200 3600 0 WAT}
+    {2009408400 7200 1 WAST}
+    {2027548800 3600 0 WAT}
+    {2040858000 7200 1 WAST}
+    {2058998400 3600 0 WAT}
+    {2072307600 7200 1 WAST}
+    {2091052800 3600 0 WAT}
+    {2104362000 7200 1 WAST}
+    {2122502400 3600 0 WAT}
+    {2135811600 7200 1 WAST}
+    {2153952000 3600 0 WAT}
+    {2167261200 7200 1 WAST}
+    {2185401600 3600 0 WAT}
+    {2198710800 7200 1 WAST}
+    {2216851200 3600 0 WAT}
+    {2230160400 7200 1 WAST}
+    {2248905600 3600 0 WAT}
+    {2261610000 7200 1 WAST}
+    {2280355200 3600 0 WAT}
+    {2293664400 7200 1 WAST}
+    {2311804800 3600 0 WAT}
+    {2325114000 7200 1 WAST}
+    {2343254400 3600 0 WAT}
+    {2356563600 7200 1 WAST}
+    {2374704000 3600 0 WAT}
+    {2388013200 7200 1 WAST}
+    {2406153600 3600 0 WAT}
+    {2419462800 7200 1 WAST}
+    {2438208000 3600 0 WAT}
+    {2450912400 7200 1 WAST}
+    {2469657600 3600 0 WAT}
+    {2482966800 7200 1 WAST}
+    {2501107200 3600 0 WAT}
+    {2514416400 7200 1 WAST}
+    {2532556800 3600 0 WAT}
+    {2545866000 7200 1 WAST}
+    {2564006400 3600 0 WAT}
+    {2577315600 7200 1 WAST}
+    {2596060800 3600 0 WAT}
+    {2608765200 7200 1 WAST}
+    {2627510400 3600 0 WAT}
+    {2640819600 7200 1 WAST}
+    {2658960000 3600 0 WAT}
+    {2672269200 7200 1 WAST}
+    {2690409600 3600 0 WAT}
+    {2703718800 7200 1 WAST}
+    {2721859200 3600 0 WAT}
+    {2735168400 7200 1 WAST}
+    {2753308800 3600 0 WAT}
+    {2766618000 7200 1 WAST}
+    {2785363200 3600 0 WAT}
+    {2798067600 7200 1 WAST}
+    {2816812800 3600 0 WAT}
+    {2830122000 7200 1 WAST}
+    {2848262400 3600 0 WAT}
+    {2861571600 7200 1 WAST}
+    {2879712000 3600 0 WAT}
+    {2893021200 7200 1 WAST}
+    {2911161600 3600 0 WAT}
+    {2924470800 7200 1 WAST}
+    {2942611200 3600 0 WAT}
+    {2955920400 7200 1 WAST}
+    {2974665600 3600 0 WAT}
+    {2987974800 7200 1 WAST}
+    {3006115200 3600 0 WAT}
+    {3019424400 7200 1 WAST}
+    {3037564800 3600 0 WAT}
+    {3050874000 7200 1 WAST}
+    {3069014400 3600 0 WAT}
+    {3082323600 7200 1 WAST}
+    {3100464000 3600 0 WAT}
+    {3113773200 7200 1 WAST}
+    {3132518400 3600 0 WAT}
+    {3145222800 7200 1 WAST}
+    {3163968000 3600 0 WAT}
+    {3177277200 7200 1 WAST}
+    {3195417600 3600 0 WAT}
+    {3208726800 7200 1 WAST}
+    {3226867200 3600 0 WAT}
+    {3240176400 7200 1 WAST}
+    {3258316800 3600 0 WAT}
+    {3271626000 7200 1 WAST}
+    {3289766400 3600 0 WAT}
+    {3303075600 7200 1 WAST}
+    {3321820800 3600 0 WAT}
+    {3334525200 7200 1 WAST}
+    {3353270400 3600 0 WAT}
+    {3366579600 7200 1 WAST}
+    {3384720000 3600 0 WAT}
+    {3398029200 7200 1 WAST}
+    {3416169600 3600 0 WAT}
+    {3429478800 7200 1 WAST}
+    {3447619200 3600 0 WAT}
+    {3460928400 7200 1 WAST}
+    {3479673600 3600 0 WAT}
+    {3492378000 7200 1 WAST}
+    {3511123200 3600 0 WAT}
+    {3524432400 7200 1 WAST}
+    {3542572800 3600 0 WAT}
+    {3555882000 7200 1 WAST}
+    {3574022400 3600 0 WAT}
+    {3587331600 7200 1 WAST}
+    {3605472000 3600 0 WAT}
+    {3618781200 7200 1 WAST}
+    {3636921600 3600 0 WAT}
+    {3650230800 7200 1 WAST}
+    {3668976000 3600 0 WAT}
+    {3681680400 7200 1 WAST}
+    {3700425600 3600 0 WAT}
+    {3713734800 7200 1 WAST}
+    {3731875200 3600 0 WAT}
+    {3745184400 7200 1 WAST}
+    {3763324800 3600 0 WAT}
+    {3776634000 7200 1 WAST}
+    {3794774400 3600 0 WAT}
+    {3808083600 7200 1 WAST}
+    {3826224000 3600 0 WAT}
+    {3839533200 7200 1 WAST}
+    {3858278400 3600 0 WAT}
+    {3871587600 7200 1 WAST}
+    {3889728000 3600 0 WAT}
+    {3903037200 7200 1 WAST}
+    {3921177600 3600 0 WAT}
+    {3934486800 7200 1 WAST}
+    {3952627200 3600 0 WAT}
+    {3965936400 7200 1 WAST}
+    {3984076800 3600 0 WAT}
+    {3997386000 7200 1 WAST}
+    {4016131200 3600 0 WAT}
+    {4028835600 7200 1 WAST}
+    {4047580800 3600 0 WAT}
+    {4060890000 7200 1 WAST}
+    {4079030400 3600 0 WAT}
+    {4092339600 7200 1 WAST}
+}
diff --git a/library/tzdata/America/Adak b/library/tzdata/America/Adak
new file mode 100644
index 0000000..bd5d5ab
--- /dev/null
+++ b/library/tzdata/America/Adak
@@ -0,0 +1,276 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Adak) {
+    {-9223372036854775808 44001 0 LMT}
+    {-3225356001 -42398 0 LMT}
+    {-2188944802 -39600 0 NST}
+    {-883573200 -39600 0 NST}
+    {-880196400 -36000 1 NWT}
+    {-769395600 -36000 1 NPT}
+    {-765374400 -39600 0 NST}
+    {-757342800 -39600 0 NST}
+    {-86878800 -39600 0 BST}
+    {-31496400 -39600 0 BST}
+    {-21466800 -36000 1 BDT}
+    {-5745600 -39600 0 BST}
+    {9982800 -36000 1 BDT}
+    {25704000 -39600 0 BST}
+    {41432400 -36000 1 BDT}
+    {57758400 -39600 0 BST}
+    {73486800 -36000 1 BDT}
+    {89208000 -39600 0 BST}
+    {104936400 -36000 1 BDT}
+    {120657600 -39600 0 BST}
+    {126709200 -36000 1 BDT}
+    {152107200 -39600 0 BST}
+    {162392400 -36000 1 BDT}
+    {183556800 -39600 0 BST}
+    {199285200 -36000 1 BDT}
+    {215611200 -39600 0 BST}
+    {230734800 -36000 1 BDT}
+    {247060800 -39600 0 BST}
+    {262789200 -36000 1 BDT}
+    {278510400 -39600 0 BST}
+    {294238800 -36000 1 BDT}
+    {309960000 -39600 0 BST}
+    {325688400 -36000 1 BDT}
+    {341409600 -39600 0 BST}
+    {357138000 -36000 1 BDT}
+    {372859200 -39600 0 BST}
+    {388587600 -36000 1 BDT}
+    {404913600 -39600 0 BST}
+    {420037200 -36000 1 BDT}
+    {439034400 -36000 0 HST}
+    {452088000 -32400 1 HDT}
+    {467809200 -36000 0 HST}
+    {483537600 -32400 1 HDT}
+    {499258800 -36000 0 HST}
+    {514987200 -32400 1 HDT}
+    {530708400 -36000 0 HST}
+    {544622400 -32400 1 HDT}
+    {562158000 -36000 0 HST}
+    {576072000 -32400 1 HDT}
+    {594212400 -36000 0 HST}
+    {607521600 -32400 1 HDT}
+    {625662000 -36000 0 HST}
+    {638971200 -32400 1 HDT}
+    {657111600 -36000 0 HST}
+    {671025600 -32400 1 HDT}
+    {688561200 -36000 0 HST}
+    {702475200 -32400 1 HDT}
+    {720010800 -36000 0 HST}
+    {733924800 -32400 1 HDT}
+    {752065200 -36000 0 HST}
+    {765374400 -32400 1 HDT}
+    {783514800 -36000 0 HST}
+    {796824000 -32400 1 HDT}
+    {814964400 -36000 0 HST}
+    {828878400 -32400 1 HDT}
+    {846414000 -36000 0 HST}
+    {860328000 -32400 1 HDT}
+    {877863600 -36000 0 HST}
+    {891777600 -32400 1 HDT}
+    {909313200 -36000 0 HST}
+    {923227200 -32400 1 HDT}
+    {941367600 -36000 0 HST}
+    {954676800 -32400 1 HDT}
+    {972817200 -36000 0 HST}
+    {986126400 -32400 1 HDT}
+    {1004266800 -36000 0 HST}
+    {1018180800 -32400 1 HDT}
+    {1035716400 -36000 0 HST}
+    {1049630400 -32400 1 HDT}
+    {1067166000 -36000 0 HST}
+    {1081080000 -32400 1 HDT}
+    {1099220400 -36000 0 HST}
+    {1112529600 -32400 1 HDT}
+    {1130670000 -36000 0 HST}
+    {1143979200 -32400 1 HDT}
+    {1162119600 -36000 0 HST}
+    {1173614400 -32400 1 HDT}
+    {1194174000 -36000 0 HST}
+    {1205064000 -32400 1 HDT}
+    {1225623600 -36000 0 HST}
+    {1236513600 -32400 1 HDT}
+    {1257073200 -36000 0 HST}
+    {1268568000 -32400 1 HDT}
+    {1289127600 -36000 0 HST}
+    {1300017600 -32400 1 HDT}
+    {1320577200 -36000 0 HST}
+    {1331467200 -32400 1 HDT}
+    {1352026800 -36000 0 HST}
+    {1362916800 -32400 1 HDT}
+    {1383476400 -36000 0 HST}
+    {1394366400 -32400 1 HDT}
+    {1414926000 -36000 0 HST}
+    {1425816000 -32400 1 HDT}
+    {1446375600 -36000 0 HST}
+    {1457870400 -32400 1 HDT}
+    {1478430000 -36000 0 HST}
+    {1489320000 -32400 1 HDT}
+    {1509879600 -36000 0 HST}
+    {1520769600 -32400 1 HDT}
+    {1541329200 -36000 0 HST}
+    {1552219200 -32400 1 HDT}
+    {1572778800 -36000 0 HST}
+    {1583668800 -32400 1 HDT}
+    {1604228400 -36000 0 HST}
+    {1615723200 -32400 1 HDT}
+    {1636282800 -36000 0 HST}
+    {1647172800 -32400 1 HDT}
+    {1667732400 -36000 0 HST}
+    {1678622400 -32400 1 HDT}
+    {1699182000 -36000 0 HST}
+    {1710072000 -32400 1 HDT}
+    {1730631600 -36000 0 HST}
+    {1741521600 -32400 1 HDT}
+    {1762081200 -36000 0 HST}
+    {1772971200 -32400 1 HDT}
+    {1793530800 -36000 0 HST}
+    {1805025600 -32400 1 HDT}
+    {1825585200 -36000 0 HST}
+    {1836475200 -32400 1 HDT}
+    {1857034800 -36000 0 HST}
+    {1867924800 -32400 1 HDT}
+    {1888484400 -36000 0 HST}
+    {1899374400 -32400 1 HDT}
+    {1919934000 -36000 0 HST}
+    {1930824000 -32400 1 HDT}
+    {1951383600 -36000 0 HST}
+    {1962878400 -32400 1 HDT}
+    {1983438000 -36000 0 HST}
+    {1994328000 -32400 1 HDT}
+    {2014887600 -36000 0 HST}
+    {2025777600 -32400 1 HDT}
+    {2046337200 -36000 0 HST}
+    {2057227200 -32400 1 HDT}
+    {2077786800 -36000 0 HST}
+    {2088676800 -32400 1 HDT}
+    {2109236400 -36000 0 HST}
+    {2120126400 -32400 1 HDT}
+    {2140686000 -36000 0 HST}
+    {2152180800 -32400 1 HDT}
+    {2172740400 -36000 0 HST}
+    {2183630400 -32400 1 HDT}
+    {2204190000 -36000 0 HST}
+    {2215080000 -32400 1 HDT}
+    {2235639600 -36000 0 HST}
+    {2246529600 -32400 1 HDT}
+    {2267089200 -36000 0 HST}
+    {2277979200 -32400 1 HDT}
+    {2298538800 -36000 0 HST}
+    {2309428800 -32400 1 HDT}
+    {2329988400 -36000 0 HST}
+    {2341483200 -32400 1 HDT}
+    {2362042800 -36000 0 HST}
+    {2372932800 -32400 1 HDT}
+    {2393492400 -36000 0 HST}
+    {2404382400 -32400 1 HDT}
+    {2424942000 -36000 0 HST}
+    {2435832000 -32400 1 HDT}
+    {2456391600 -36000 0 HST}
+    {2467281600 -32400 1 HDT}
+    {2487841200 -36000 0 HST}
+    {2499336000 -32400 1 HDT}
+    {2519895600 -36000 0 HST}
+    {2530785600 -32400 1 HDT}
+    {2551345200 -36000 0 HST}
+    {2562235200 -32400 1 HDT}
+    {2582794800 -36000 0 HST}
+    {2593684800 -32400 1 HDT}
+    {2614244400 -36000 0 HST}
+    {2625134400 -32400 1 HDT}
+    {2645694000 -36000 0 HST}
+    {2656584000 -32400 1 HDT}
+    {2677143600 -36000 0 HST}
+    {2688638400 -32400 1 HDT}
+    {2709198000 -36000 0 HST}
+    {2720088000 -32400 1 HDT}
+    {2740647600 -36000 0 HST}
+    {2751537600 -32400 1 HDT}
+    {2772097200 -36000 0 HST}
+    {2782987200 -32400 1 HDT}
+    {2803546800 -36000 0 HST}
+    {2814436800 -32400 1 HDT}
+    {2834996400 -36000 0 HST}
+    {2846491200 -32400 1 HDT}
+    {2867050800 -36000 0 HST}
+    {2877940800 -32400 1 HDT}
+    {2898500400 -36000 0 HST}
+    {2909390400 -32400 1 HDT}
+    {2929950000 -36000 0 HST}
+    {2940840000 -32400 1 HDT}
+    {2961399600 -36000 0 HST}
+    {2972289600 -32400 1 HDT}
+    {2992849200 -36000 0 HST}
+    {3003739200 -32400 1 HDT}
+    {3024298800 -36000 0 HST}
+    {3035793600 -32400 1 HDT}
+    {3056353200 -36000 0 HST}
+    {3067243200 -32400 1 HDT}
+    {3087802800 -36000 0 HST}
+    {3098692800 -32400 1 HDT}
+    {3119252400 -36000 0 HST}
+    {3130142400 -32400 1 HDT}
+    {3150702000 -36000 0 HST}
+    {3161592000 -32400 1 HDT}
+    {3182151600 -36000 0 HST}
+    {3193041600 -32400 1 HDT}
+    {3213601200 -36000 0 HST}
+    {3225096000 -32400 1 HDT}
+    {3245655600 -36000 0 HST}
+    {3256545600 -32400 1 HDT}
+    {3277105200 -36000 0 HST}
+    {3287995200 -32400 1 HDT}
+    {3308554800 -36000 0 HST}
+    {3319444800 -32400 1 HDT}
+    {3340004400 -36000 0 HST}
+    {3350894400 -32400 1 HDT}
+    {3371454000 -36000 0 HST}
+    {3382948800 -32400 1 HDT}
+    {3403508400 -36000 0 HST}
+    {3414398400 -32400 1 HDT}
+    {3434958000 -36000 0 HST}
+    {3445848000 -32400 1 HDT}
+    {3466407600 -36000 0 HST}
+    {3477297600 -32400 1 HDT}
+    {3497857200 -36000 0 HST}
+    {3508747200 -32400 1 HDT}
+    {3529306800 -36000 0 HST}
+    {3540196800 -32400 1 HDT}
+    {3560756400 -36000 0 HST}
+    {3572251200 -32400 1 HDT}
+    {3592810800 -36000 0 HST}
+    {3603700800 -32400 1 HDT}
+    {3624260400 -36000 0 HST}
+    {3635150400 -32400 1 HDT}
+    {3655710000 -36000 0 HST}
+    {3666600000 -32400 1 HDT}
+    {3687159600 -36000 0 HST}
+    {3698049600 -32400 1 HDT}
+    {3718609200 -36000 0 HST}
+    {3730104000 -32400 1 HDT}
+    {3750663600 -36000 0 HST}
+    {3761553600 -32400 1 HDT}
+    {3782113200 -36000 0 HST}
+    {3793003200 -32400 1 HDT}
+    {3813562800 -36000 0 HST}
+    {3824452800 -32400 1 HDT}
+    {3845012400 -36000 0 HST}
+    {3855902400 -32400 1 HDT}
+    {3876462000 -36000 0 HST}
+    {3887352000 -32400 1 HDT}
+    {3907911600 -36000 0 HST}
+    {3919406400 -32400 1 HDT}
+    {3939966000 -36000 0 HST}
+    {3950856000 -32400 1 HDT}
+    {3971415600 -36000 0 HST}
+    {3982305600 -32400 1 HDT}
+    {4002865200 -36000 0 HST}
+    {4013755200 -32400 1 HDT}
+    {4034314800 -36000 0 HST}
+    {4045204800 -32400 1 HDT}
+    {4065764400 -36000 0 HST}
+    {4076654400 -32400 1 HDT}
+    {4097214000 -36000 0 HST}
+}
diff --git a/library/tzdata/America/Anchorage b/library/tzdata/America/Anchorage
new file mode 100644
index 0000000..e02dd01
--- /dev/null
+++ b/library/tzdata/America/Anchorage
@@ -0,0 +1,276 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Anchorage) {
+    {-9223372036854775808 50424 0 LMT}
+    {-3225362424 -35976 0 LMT}
+    {-2188951224 -36000 0 CAT}
+    {-883576800 -36000 0 CAWT}
+    {-880200000 -32400 1 CAWT}
+    {-769395600 -32400 0 CAPT}
+    {-765378000 -36000 0 CAPT}
+    {-757346400 -36000 0 CAT}
+    {-86882400 -36000 0 AHST}
+    {-31500000 -36000 0 AHST}
+    {-21470400 -32400 1 AHDT}
+    {-5749200 -36000 0 AHST}
+    {9979200 -32400 1 AHDT}
+    {25700400 -36000 0 AHST}
+    {41428800 -32400 1 AHDT}
+    {57754800 -36000 0 AHST}
+    {73483200 -32400 1 AHDT}
+    {89204400 -36000 0 AHST}
+    {104932800 -32400 1 AHDT}
+    {120654000 -36000 0 AHST}
+    {126705600 -32400 1 AHDT}
+    {152103600 -36000 0 AHST}
+    {162388800 -32400 1 AHDT}
+    {183553200 -36000 0 AHST}
+    {199281600 -32400 1 AHDT}
+    {215607600 -36000 0 AHST}
+    {230731200 -32400 1 AHDT}
+    {247057200 -36000 0 AHST}
+    {262785600 -32400 1 AHDT}
+    {278506800 -36000 0 AHST}
+    {294235200 -32400 1 AHDT}
+    {309956400 -36000 0 AHST}
+    {325684800 -32400 1 AHDT}
+    {341406000 -36000 0 AHST}
+    {357134400 -32400 1 AHDT}
+    {372855600 -36000 0 AHST}
+    {388584000 -32400 1 AHDT}
+    {404910000 -36000 0 AHST}
+    {420033600 -32400 1 AHDT}
+    {439030800 -32400 0 AKST}
+    {452084400 -28800 1 AKDT}
+    {467805600 -32400 0 AKST}
+    {483534000 -28800 1 AKDT}
+    {499255200 -32400 0 AKST}
+    {514983600 -28800 1 AKDT}
+    {530704800 -32400 0 AKST}
+    {544618800 -28800 1 AKDT}
+    {562154400 -32400 0 AKST}
+    {576068400 -28800 1 AKDT}
+    {594208800 -32400 0 AKST}
+    {607518000 -28800 1 AKDT}
+    {625658400 -32400 0 AKST}
+    {638967600 -28800 1 AKDT}
+    {657108000 -32400 0 AKST}
+    {671022000 -28800 1 AKDT}
+    {688557600 -32400 0 AKST}
+    {702471600 -28800 1 AKDT}
+    {720007200 -32400 0 AKST}
+    {733921200 -28800 1 AKDT}
+    {752061600 -32400 0 AKST}
+    {765370800 -28800 1 AKDT}
+    {783511200 -32400 0 AKST}
+    {796820400 -28800 1 AKDT}
+    {814960800 -32400 0 AKST}
+    {828874800 -28800 1 AKDT}
+    {846410400 -32400 0 AKST}
+    {860324400 -28800 1 AKDT}
+    {877860000 -32400 0 AKST}
+    {891774000 -28800 1 AKDT}
+    {909309600 -32400 0 AKST}
+    {923223600 -28800 1 AKDT}
+    {941364000 -32400 0 AKST}
+    {954673200 -28800 1 AKDT}
+    {972813600 -32400 0 AKST}
+    {986122800 -28800 1 AKDT}
+    {1004263200 -32400 0 AKST}
+    {1018177200 -28800 1 AKDT}
+    {1035712800 -32400 0 AKST}
+    {1049626800 -28800 1 AKDT}
+    {1067162400 -32400 0 AKST}
+    {1081076400 -28800 1 AKDT}
+    {1099216800 -32400 0 AKST}
+    {1112526000 -28800 1 AKDT}
+    {1130666400 -32400 0 AKST}
+    {1143975600 -28800 1 AKDT}
+    {1162116000 -32400 0 AKST}
+    {1173610800 -28800 1 AKDT}
+    {1194170400 -32400 0 AKST}
+    {1205060400 -28800 1 AKDT}
+    {1225620000 -32400 0 AKST}
+    {1236510000 -28800 1 AKDT}
+    {1257069600 -32400 0 AKST}
+    {1268564400 -28800 1 AKDT}
+    {1289124000 -32400 0 AKST}
+    {1300014000 -28800 1 AKDT}
+    {1320573600 -32400 0 AKST}
+    {1331463600 -28800 1 AKDT}
+    {1352023200 -32400 0 AKST}
+    {1362913200 -28800 1 AKDT}
+    {1383472800 -32400 0 AKST}
+    {1394362800 -28800 1 AKDT}
+    {1414922400 -32400 0 AKST}
+    {1425812400 -28800 1 AKDT}
+    {1446372000 -32400 0 AKST}
+    {1457866800 -28800 1 AKDT}
+    {1478426400 -32400 0 AKST}
+    {1489316400 -28800 1 AKDT}
+    {1509876000 -32400 0 AKST}
+    {1520766000 -28800 1 AKDT}
+    {1541325600 -32400 0 AKST}
+    {1552215600 -28800 1 AKDT}
+    {1572775200 -32400 0 AKST}
+    {1583665200 -28800 1 AKDT}
+    {1604224800 -32400 0 AKST}
+    {1615719600 -28800 1 AKDT}
+    {1636279200 -32400 0 AKST}
+    {1647169200 -28800 1 AKDT}
+    {1667728800 -32400 0 AKST}
+    {1678618800 -28800 1 AKDT}
+    {1699178400 -32400 0 AKST}
+    {1710068400 -28800 1 AKDT}
+    {1730628000 -32400 0 AKST}
+    {1741518000 -28800 1 AKDT}
+    {1762077600 -32400 0 AKST}
+    {1772967600 -28800 1 AKDT}
+    {1793527200 -32400 0 AKST}
+    {1805022000 -28800 1 AKDT}
+    {1825581600 -32400 0 AKST}
+    {1836471600 -28800 1 AKDT}
+    {1857031200 -32400 0 AKST}
+    {1867921200 -28800 1 AKDT}
+    {1888480800 -32400 0 AKST}
+    {1899370800 -28800 1 AKDT}
+    {1919930400 -32400 0 AKST}
+    {1930820400 -28800 1 AKDT}
+    {1951380000 -32400 0 AKST}
+    {1962874800 -28800 1 AKDT}
+    {1983434400 -32400 0 AKST}
+    {1994324400 -28800 1 AKDT}
+    {2014884000 -32400 0 AKST}
+    {2025774000 -28800 1 AKDT}
+    {2046333600 -32400 0 AKST}
+    {2057223600 -28800 1 AKDT}
+    {2077783200 -32400 0 AKST}
+    {2088673200 -28800 1 AKDT}
+    {2109232800 -32400 0 AKST}
+    {2120122800 -28800 1 AKDT}
+    {2140682400 -32400 0 AKST}
+    {2152177200 -28800 1 AKDT}
+    {2172736800 -32400 0 AKST}
+    {2183626800 -28800 1 AKDT}
+    {2204186400 -32400 0 AKST}
+    {2215076400 -28800 1 AKDT}
+    {2235636000 -32400 0 AKST}
+    {2246526000 -28800 1 AKDT}
+    {2267085600 -32400 0 AKST}
+    {2277975600 -28800 1 AKDT}
+    {2298535200 -32400 0 AKST}
+    {2309425200 -28800 1 AKDT}
+    {2329984800 -32400 0 AKST}
+    {2341479600 -28800 1 AKDT}
+    {2362039200 -32400 0 AKST}
+    {2372929200 -28800 1 AKDT}
+    {2393488800 -32400 0 AKST}
+    {2404378800 -28800 1 AKDT}
+    {2424938400 -32400 0 AKST}
+    {2435828400 -28800 1 AKDT}
+    {2456388000 -32400 0 AKST}
+    {2467278000 -28800 1 AKDT}
+    {2487837600 -32400 0 AKST}
+    {2499332400 -28800 1 AKDT}
+    {2519892000 -32400 0 AKST}
+    {2530782000 -28800 1 AKDT}
+    {2551341600 -32400 0 AKST}
+    {2562231600 -28800 1 AKDT}
+    {2582791200 -32400 0 AKST}
+    {2593681200 -28800 1 AKDT}
+    {2614240800 -32400 0 AKST}
+    {2625130800 -28800 1 AKDT}
+    {2645690400 -32400 0 AKST}
+    {2656580400 -28800 1 AKDT}
+    {2677140000 -32400 0 AKST}
+    {2688634800 -28800 1 AKDT}
+    {2709194400 -32400 0 AKST}
+    {2720084400 -28800 1 AKDT}
+    {2740644000 -32400 0 AKST}
+    {2751534000 -28800 1 AKDT}
+    {2772093600 -32400 0 AKST}
+    {2782983600 -28800 1 AKDT}
+    {2803543200 -32400 0 AKST}
+    {2814433200 -28800 1 AKDT}
+    {2834992800 -32400 0 AKST}
+    {2846487600 -28800 1 AKDT}
+    {2867047200 -32400 0 AKST}
+    {2877937200 -28800 1 AKDT}
+    {2898496800 -32400 0 AKST}
+    {2909386800 -28800 1 AKDT}
+    {2929946400 -32400 0 AKST}
+    {2940836400 -28800 1 AKDT}
+    {2961396000 -32400 0 AKST}
+    {2972286000 -28800 1 AKDT}
+    {2992845600 -32400 0 AKST}
+    {3003735600 -28800 1 AKDT}
+    {3024295200 -32400 0 AKST}
+    {3035790000 -28800 1 AKDT}
+    {3056349600 -32400 0 AKST}
+    {3067239600 -28800 1 AKDT}
+    {3087799200 -32400 0 AKST}
+    {3098689200 -28800 1 AKDT}
+    {3119248800 -32400 0 AKST}
+    {3130138800 -28800 1 AKDT}
+    {3150698400 -32400 0 AKST}
+    {3161588400 -28800 1 AKDT}
+    {3182148000 -32400 0 AKST}
+    {3193038000 -28800 1 AKDT}
+    {3213597600 -32400 0 AKST}
+    {3225092400 -28800 1 AKDT}
+    {3245652000 -32400 0 AKST}
+    {3256542000 -28800 1 AKDT}
+    {3277101600 -32400 0 AKST}
+    {3287991600 -28800 1 AKDT}
+    {3308551200 -32400 0 AKST}
+    {3319441200 -28800 1 AKDT}
+    {3340000800 -32400 0 AKST}
+    {3350890800 -28800 1 AKDT}
+    {3371450400 -32400 0 AKST}
+    {3382945200 -28800 1 AKDT}
+    {3403504800 -32400 0 AKST}
+    {3414394800 -28800 1 AKDT}
+    {3434954400 -32400 0 AKST}
+    {3445844400 -28800 1 AKDT}
+    {3466404000 -32400 0 AKST}
+    {3477294000 -28800 1 AKDT}
+    {3497853600 -32400 0 AKST}
+    {3508743600 -28800 1 AKDT}
+    {3529303200 -32400 0 AKST}
+    {3540193200 -28800 1 AKDT}
+    {3560752800 -32400 0 AKST}
+    {3572247600 -28800 1 AKDT}
+    {3592807200 -32400 0 AKST}
+    {3603697200 -28800 1 AKDT}
+    {3624256800 -32400 0 AKST}
+    {3635146800 -28800 1 AKDT}
+    {3655706400 -32400 0 AKST}
+    {3666596400 -28800 1 AKDT}
+    {3687156000 -32400 0 AKST}
+    {3698046000 -28800 1 AKDT}
+    {3718605600 -32400 0 AKST}
+    {3730100400 -28800 1 AKDT}
+    {3750660000 -32400 0 AKST}
+    {3761550000 -28800 1 AKDT}
+    {3782109600 -32400 0 AKST}
+    {3792999600 -28800 1 AKDT}
+    {3813559200 -32400 0 AKST}
+    {3824449200 -28800 1 AKDT}
+    {3845008800 -32400 0 AKST}
+    {3855898800 -28800 1 AKDT}
+    {3876458400 -32400 0 AKST}
+    {3887348400 -28800 1 AKDT}
+    {3907908000 -32400 0 AKST}
+    {3919402800 -28800 1 AKDT}
+    {3939962400 -32400 0 AKST}
+    {3950852400 -28800 1 AKDT}
+    {3971412000 -32400 0 AKST}
+    {3982302000 -28800 1 AKDT}
+    {4002861600 -32400 0 AKST}
+    {4013751600 -28800 1 AKDT}
+    {4034311200 -32400 0 AKST}
+    {4045201200 -28800 1 AKDT}
+    {4065760800 -32400 0 AKST}
+    {4076650800 -28800 1 AKDT}
+    {4097210400 -32400 0 AKST}
+}
diff --git a/library/tzdata/America/Anguilla b/library/tzdata/America/Anguilla
new file mode 100644
index 0000000..39a0d18
--- /dev/null
+++ b/library/tzdata/America/Anguilla
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(America/Port_of_Spain)]} {
+    LoadTimeZoneFile America/Port_of_Spain
+}
+set TZData(:America/Anguilla) $TZData(:America/Port_of_Spain)
diff --git a/library/tzdata/America/Antigua b/library/tzdata/America/Antigua
new file mode 100644
index 0000000..be0c88e
--- /dev/null
+++ b/library/tzdata/America/Antigua
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(America/Port_of_Spain)]} {
+    LoadTimeZoneFile America/Port_of_Spain
+}
+set TZData(:America/Antigua) $TZData(:America/Port_of_Spain)
diff --git a/library/tzdata/America/Araguaina b/library/tzdata/America/Araguaina
new file mode 100644
index 0000000..e4a0d52
--- /dev/null
+++ b/library/tzdata/America/Araguaina
@@ -0,0 +1,60 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Araguaina) {
+    {-9223372036854775808 -11568 0 LMT}
+    {-1767214032 -10800 0 BRT}
+    {-1206957600 -7200 1 BRST}
+    {-1191362400 -10800 0 BRT}
+    {-1175374800 -7200 1 BRST}
+    {-1159826400 -10800 0 BRT}
+    {-633819600 -7200 1 BRST}
+    {-622069200 -10800 0 BRT}
+    {-602283600 -7200 1 BRST}
+    {-591832800 -10800 0 BRT}
+    {-570747600 -7200 1 BRST}
+    {-560210400 -10800 0 BRT}
+    {-539125200 -7200 1 BRST}
+    {-531352800 -10800 0 BRT}
+    {-191365200 -7200 1 BRST}
+    {-184197600 -10800 0 BRT}
+    {-155163600 -7200 1 BRST}
+    {-150069600 -10800 0 BRT}
+    {-128898000 -7200 1 BRST}
+    {-121125600 -10800 0 BRT}
+    {-99954000 -7200 1 BRST}
+    {-89589600 -10800 0 BRT}
+    {-68418000 -7200 1 BRST}
+    {-57967200 -10800 0 BRT}
+    {499748400 -7200 1 BRST}
+    {511236000 -10800 0 BRT}
+    {530593200 -7200 1 BRST}
+    {540266400 -10800 0 BRT}
+    {562129200 -7200 1 BRST}
+    {571197600 -10800 0 BRT}
+    {592974000 -7200 1 BRST}
+    {602042400 -10800 0 BRT}
+    {624423600 -7200 1 BRST}
+    {634701600 -10800 0 BRT}
+    {653536800 -10800 0 BRT}
+    {811047600 -10800 0 BRT}
+    {813726000 -7200 1 BRST}
+    {824004000 -10800 0 BRT}
+    {844570800 -7200 1 BRST}
+    {856058400 -10800 0 BRT}
+    {876106800 -7200 1 BRST}
+    {888717600 -10800 0 BRT}
+    {908074800 -7200 1 BRST}
+    {919562400 -10800 0 BRT}
+    {938919600 -7200 1 BRST}
+    {951616800 -10800 0 BRT}
+    {970974000 -7200 1 BRST}
+    {982461600 -10800 0 BRT}
+    {1003028400 -7200 1 BRST}
+    {1013911200 -10800 0 BRT}
+    {1036292400 -7200 1 BRST}
+    {1045360800 -10800 0 BRT}
+    {1064368800 -10800 0 BRT}
+    {1350788400 -7200 0 BRST}
+    {1361066400 -10800 0 BRT}
+    {1378000800 -10800 0 BRT}
+}
diff --git a/library/tzdata/America/Argentina/Buenos_Aires b/library/tzdata/America/Argentina/Buenos_Aires
new file mode 100644
index 0000000..73cc8e9
--- /dev/null
+++ b/library/tzdata/America/Argentina/Buenos_Aires
@@ -0,0 +1,67 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Argentina/Buenos_Aires) {
+    {-9223372036854775808 -14028 0 LMT}
+    {-2372097972 -15408 0 CMT}
+    {-1567453392 -14400 0 ART}
+    {-1233432000 -10800 0 ARST}
+    {-1222981200 -14400 0 ART}
+    {-1205956800 -10800 1 ARST}
+    {-1194037200 -14400 0 ART}
+    {-1172865600 -10800 1 ARST}
+    {-1162501200 -14400 0 ART}
+    {-1141329600 -10800 1 ARST}
+    {-1130965200 -14400 0 ART}
+    {-1109793600 -10800 1 ARST}
+    {-1099429200 -14400 0 ART}
+    {-1078257600 -10800 1 ARST}
+    {-1067806800 -14400 0 ART}
+    {-1046635200 -10800 1 ARST}
+    {-1036270800 -14400 0 ART}
+    {-1015099200 -10800 1 ARST}
+    {-1004734800 -14400 0 ART}
+    {-983563200 -10800 1 ARST}
+    {-973198800 -14400 0 ART}
+    {-952027200 -10800 1 ARST}
+    {-941576400 -14400 0 ART}
+    {-931032000 -10800 1 ARST}
+    {-900882000 -14400 0 ART}
+    {-890337600 -10800 1 ARST}
+    {-833749200 -14400 0 ART}
+    {-827265600 -10800 1 ARST}
+    {-752274000 -14400 0 ART}
+    {-733780800 -10800 1 ARST}
+    {-197326800 -14400 0 ART}
+    {-190843200 -10800 1 ARST}
+    {-184194000 -14400 0 ART}
+    {-164491200 -10800 1 ARST}
+    {-152658000 -14400 0 ART}
+    {-132955200 -10800 1 ARST}
+    {-121122000 -14400 0 ART}
+    {-101419200 -10800 1 ARST}
+    {-86821200 -14400 0 ART}
+    {-71092800 -10800 1 ARST}
+    {-54766800 -14400 0 ART}
+    {-39038400 -10800 1 ARST}
+    {-23317200 -14400 0 ART}
+    {-7588800 -10800 0 ART}
+    {128142000 -7200 1 ARST}
+    {136605600 -10800 0 ART}
+    {596948400 -7200 1 ARST}
+    {605066400 -10800 0 ART}
+    {624423600 -7200 1 ARST}
+    {636516000 -10800 0 ART}
+    {656478000 -7200 1 ARST}
+    {667965600 -10800 0 ART}
+    {687927600 -7200 1 ARST}
+    {699415200 -10800 0 ART}
+    {719377200 -7200 1 ARST}
+    {731469600 -10800 0 ART}
+    {938916000 -10800 0 ART}
+    {938919600 -10800 1 ARST}
+    {952056000 -10800 0 ART}
+    {1198983600 -7200 1 ARST}
+    {1205632800 -10800 0 ART}
+    {1224385200 -7200 1 ARST}
+    {1237082400 -10800 0 ART}
+}
diff --git a/library/tzdata/America/Argentina/Catamarca b/library/tzdata/America/Argentina/Catamarca
new file mode 100644
index 0000000..7739203
--- /dev/null
+++ b/library/tzdata/America/Argentina/Catamarca
@@ -0,0 +1,68 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Argentina/Catamarca) {
+    {-9223372036854775808 -15788 0 LMT}
+    {-2372096212 -15408 0 CMT}
+    {-1567453392 -14400 0 ART}
+    {-1233432000 -10800 0 ARST}
+    {-1222981200 -14400 0 ART}
+    {-1205956800 -10800 1 ARST}
+    {-1194037200 -14400 0 ART}
+    {-1172865600 -10800 1 ARST}
+    {-1162501200 -14400 0 ART}
+    {-1141329600 -10800 1 ARST}
+    {-1130965200 -14400 0 ART}
+    {-1109793600 -10800 1 ARST}
+    {-1099429200 -14400 0 ART}
+    {-1078257600 -10800 1 ARST}
+    {-1067806800 -14400 0 ART}
+    {-1046635200 -10800 1 ARST}
+    {-1036270800 -14400 0 ART}
+    {-1015099200 -10800 1 ARST}
+    {-1004734800 -14400 0 ART}
+    {-983563200 -10800 1 ARST}
+    {-973198800 -14400 0 ART}
+    {-952027200 -10800 1 ARST}
+    {-941576400 -14400 0 ART}
+    {-931032000 -10800 1 ARST}
+    {-900882000 -14400 0 ART}
+    {-890337600 -10800 1 ARST}
+    {-833749200 -14400 0 ART}
+    {-827265600 -10800 1 ARST}
+    {-752274000 -14400 0 ART}
+    {-733780800 -10800 1 ARST}
+    {-197326800 -14400 0 ART}
+    {-190843200 -10800 1 ARST}
+    {-184194000 -14400 0 ART}
+    {-164491200 -10800 1 ARST}
+    {-152658000 -14400 0 ART}
+    {-132955200 -10800 1 ARST}
+    {-121122000 -14400 0 ART}
+    {-101419200 -10800 1 ARST}
+    {-86821200 -14400 0 ART}
+    {-71092800 -10800 1 ARST}
+    {-54766800 -14400 0 ART}
+    {-39038400 -10800 1 ARST}
+    {-23317200 -14400 0 ART}
+    {-7588800 -10800 0 ART}
+    {128142000 -7200 1 ARST}
+    {136605600 -10800 0 ART}
+    {596948400 -7200 1 ARST}
+    {605066400 -10800 0 ART}
+    {624423600 -7200 1 ARST}
+    {636516000 -10800 0 ART}
+    {656478000 -7200 1 ARST}
+    {667965600 -14400 0 WART}
+    {687931200 -7200 0 ARST}
+    {699415200 -10800 0 ART}
+    {719377200 -7200 1 ARST}
+    {731469600 -10800 0 ART}
+    {938916000 -10800 0 ART}
+    {938919600 -10800 1 ARST}
+    {952056000 -10800 0 ART}
+    {1086058800 -14400 0 WART}
+    {1087704000 -10800 0 ART}
+    {1198983600 -7200 1 ARST}
+    {1205632800 -10800 0 ART}
+    {1224295200 -10800 0 ART}
+}
diff --git a/library/tzdata/America/Argentina/ComodRivadavia b/library/tzdata/America/Argentina/ComodRivadavia
new file mode 100644
index 0000000..2611a3d
--- /dev/null
+++ b/library/tzdata/America/Argentina/ComodRivadavia
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(America/Argentina/Catamarca)]} {
+    LoadTimeZoneFile America/Argentina/Catamarca
+}
+set TZData(:America/Argentina/ComodRivadavia) $TZData(:America/Argentina/Catamarca)
diff --git a/library/tzdata/America/Argentina/Cordoba b/library/tzdata/America/Argentina/Cordoba
new file mode 100644
index 0000000..b08539e
--- /dev/null
+++ b/library/tzdata/America/Argentina/Cordoba
@@ -0,0 +1,67 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Argentina/Cordoba) {
+    {-9223372036854775808 -15408 0 LMT}
+    {-2372096592 -15408 0 CMT}
+    {-1567453392 -14400 0 ART}
+    {-1233432000 -10800 0 ARST}
+    {-1222981200 -14400 0 ART}
+    {-1205956800 -10800 1 ARST}
+    {-1194037200 -14400 0 ART}
+    {-1172865600 -10800 1 ARST}
+    {-1162501200 -14400 0 ART}
+    {-1141329600 -10800 1 ARST}
+    {-1130965200 -14400 0 ART}
+    {-1109793600 -10800 1 ARST}
+    {-1099429200 -14400 0 ART}
+    {-1078257600 -10800 1 ARST}
+    {-1067806800 -14400 0 ART}
+    {-1046635200 -10800 1 ARST}
+    {-1036270800 -14400 0 ART}
+    {-1015099200 -10800 1 ARST}
+    {-1004734800 -14400 0 ART}
+    {-983563200 -10800 1 ARST}
+    {-973198800 -14400 0 ART}
+    {-952027200 -10800 1 ARST}
+    {-941576400 -14400 0 ART}
+    {-931032000 -10800 1 ARST}
+    {-900882000 -14400 0 ART}
+    {-890337600 -10800 1 ARST}
+    {-833749200 -14400 0 ART}
+    {-827265600 -10800 1 ARST}
+    {-752274000 -14400 0 ART}
+    {-733780800 -10800 1 ARST}
+    {-197326800 -14400 0 ART}
+    {-190843200 -10800 1 ARST}
+    {-184194000 -14400 0 ART}
+    {-164491200 -10800 1 ARST}
+    {-152658000 -14400 0 ART}
+    {-132955200 -10800 1 ARST}
+    {-121122000 -14400 0 ART}
+    {-101419200 -10800 1 ARST}
+    {-86821200 -14400 0 ART}
+    {-71092800 -10800 1 ARST}
+    {-54766800 -14400 0 ART}
+    {-39038400 -10800 1 ARST}
+    {-23317200 -14400 0 ART}
+    {-7588800 -10800 0 ART}
+    {128142000 -7200 1 ARST}
+    {136605600 -10800 0 ART}
+    {596948400 -7200 1 ARST}
+    {605066400 -10800 0 ART}
+    {624423600 -7200 1 ARST}
+    {636516000 -10800 0 ART}
+    {656478000 -7200 1 ARST}
+    {667965600 -14400 0 WART}
+    {687931200 -7200 0 ARST}
+    {699415200 -10800 0 ART}
+    {719377200 -7200 1 ARST}
+    {731469600 -10800 0 ART}
+    {938916000 -10800 0 ART}
+    {938919600 -10800 1 ARST}
+    {952056000 -10800 0 ART}
+    {1198983600 -7200 1 ARST}
+    {1205632800 -10800 0 ART}
+    {1224385200 -7200 1 ARST}
+    {1237082400 -10800 0 ART}
+}
diff --git a/library/tzdata/America/Argentina/Jujuy b/library/tzdata/America/Argentina/Jujuy
new file mode 100644
index 0000000..4f95f8a
--- /dev/null
+++ b/library/tzdata/America/Argentina/Jujuy
@@ -0,0 +1,67 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Argentina/Jujuy) {
+    {-9223372036854775808 -15672 0 LMT}
+    {-2372096328 -15408 0 CMT}
+    {-1567453392 -14400 0 ART}
+    {-1233432000 -10800 0 ARST}
+    {-1222981200 -14400 0 ART}
+    {-1205956800 -10800 1 ARST}
+    {-1194037200 -14400 0 ART}
+    {-1172865600 -10800 1 ARST}
+    {-1162501200 -14400 0 ART}
+    {-1141329600 -10800 1 ARST}
+    {-1130965200 -14400 0 ART}
+    {-1109793600 -10800 1 ARST}
+    {-1099429200 -14400 0 ART}
+    {-1078257600 -10800 1 ARST}
+    {-1067806800 -14400 0 ART}
+    {-1046635200 -10800 1 ARST}
+    {-1036270800 -14400 0 ART}
+    {-1015099200 -10800 1 ARST}
+    {-1004734800 -14400 0 ART}
+    {-983563200 -10800 1 ARST}
+    {-973198800 -14400 0 ART}
+    {-952027200 -10800 1 ARST}
+    {-941576400 -14400 0 ART}
+    {-931032000 -10800 1 ARST}
+    {-900882000 -14400 0 ART}
+    {-890337600 -10800 1 ARST}
+    {-833749200 -14400 0 ART}
+    {-827265600 -10800 1 ARST}
+    {-752274000 -14400 0 ART}
+    {-733780800 -10800 1 ARST}
+    {-197326800 -14400 0 ART}
+    {-190843200 -10800 1 ARST}
+    {-184194000 -14400 0 ART}
+    {-164491200 -10800 1 ARST}
+    {-152658000 -14400 0 ART}
+    {-132955200 -10800 1 ARST}
+    {-121122000 -14400 0 ART}
+    {-101419200 -10800 1 ARST}
+    {-86821200 -14400 0 ART}
+    {-71092800 -10800 1 ARST}
+    {-54766800 -14400 0 ART}
+    {-39038400 -10800 1 ARST}
+    {-23317200 -14400 0 ART}
+    {-7588800 -10800 0 ART}
+    {128142000 -7200 1 ARST}
+    {136605600 -10800 0 ART}
+    {596948400 -7200 1 ARST}
+    {605066400 -10800 0 ART}
+    {624423600 -7200 1 ARST}
+    {636516000 -14400 0 WART}
+    {657086400 -10800 1 WARST}
+    {669178800 -14400 0 WART}
+    {686721600 -7200 1 ARST}
+    {694231200 -7200 0 ART}
+    {699415200 -10800 0 ART}
+    {719377200 -7200 1 ARST}
+    {731469600 -10800 0 ART}
+    {938916000 -10800 0 ART}
+    {938919600 -10800 1 ARST}
+    {952056000 -10800 0 ART}
+    {1198983600 -7200 1 ARST}
+    {1205632800 -10800 0 ART}
+    {1224295200 -10800 0 ART}
+}
diff --git a/library/tzdata/America/Argentina/La_Rioja b/library/tzdata/America/Argentina/La_Rioja
new file mode 100644
index 0000000..835e29d
--- /dev/null
+++ b/library/tzdata/America/Argentina/La_Rioja
@@ -0,0 +1,69 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Argentina/La_Rioja) {
+    {-9223372036854775808 -16044 0 LMT}
+    {-2372095956 -15408 0 CMT}
+    {-1567453392 -14400 0 ART}
+    {-1233432000 -10800 0 ARST}
+    {-1222981200 -14400 0 ART}
+    {-1205956800 -10800 1 ARST}
+    {-1194037200 -14400 0 ART}
+    {-1172865600 -10800 1 ARST}
+    {-1162501200 -14400 0 ART}
+    {-1141329600 -10800 1 ARST}
+    {-1130965200 -14400 0 ART}
+    {-1109793600 -10800 1 ARST}
+    {-1099429200 -14400 0 ART}
+    {-1078257600 -10800 1 ARST}
+    {-1067806800 -14400 0 ART}
+    {-1046635200 -10800 1 ARST}
+    {-1036270800 -14400 0 ART}
+    {-1015099200 -10800 1 ARST}
+    {-1004734800 -14400 0 ART}
+    {-983563200 -10800 1 ARST}
+    {-973198800 -14400 0 ART}
+    {-952027200 -10800 1 ARST}
+    {-941576400 -14400 0 ART}
+    {-931032000 -10800 1 ARST}
+    {-900882000 -14400 0 ART}
+    {-890337600 -10800 1 ARST}
+    {-833749200 -14400 0 ART}
+    {-827265600 -10800 1 ARST}
+    {-752274000 -14400 0 ART}
+    {-733780800 -10800 1 ARST}
+    {-197326800 -14400 0 ART}
+    {-190843200 -10800 1 ARST}
+    {-184194000 -14400 0 ART}
+    {-164491200 -10800 1 ARST}
+    {-152658000 -14400 0 ART}
+    {-132955200 -10800 1 ARST}
+    {-121122000 -14400 0 ART}
+    {-101419200 -10800 1 ARST}
+    {-86821200 -14400 0 ART}
+    {-71092800 -10800 1 ARST}
+    {-54766800 -14400 0 ART}
+    {-39038400 -10800 1 ARST}
+    {-23317200 -14400 0 ART}
+    {-7588800 -10800 0 ART}
+    {128142000 -7200 1 ARST}
+    {136605600 -10800 0 ART}
+    {596948400 -7200 1 ARST}
+    {605066400 -10800 0 ART}
+    {624423600 -7200 1 ARST}
+    {636516000 -10800 0 ART}
+    {656478000 -7200 1 ARST}
+    {667792800 -14400 0 WART}
+    {673588800 -10800 0 ART}
+    {687927600 -7200 1 ARST}
+    {699415200 -10800 0 ART}
+    {719377200 -7200 1 ARST}
+    {731469600 -10800 0 ART}
+    {938916000 -10800 0 ART}
+    {938919600 -10800 1 ARST}
+    {952056000 -10800 0 ART}
+    {1086058800 -14400 0 WART}
+    {1087704000 -10800 0 ART}
+    {1198983600 -7200 1 ARST}
+    {1205632800 -10800 0 ART}
+    {1224295200 -10800 0 ART}
+}
diff --git a/library/tzdata/America/Argentina/Mendoza b/library/tzdata/America/Argentina/Mendoza
new file mode 100644
index 0000000..2c6fb58
--- /dev/null
+++ b/library/tzdata/America/Argentina/Mendoza
@@ -0,0 +1,68 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Argentina/Mendoza) {
+    {-9223372036854775808 -16516 0 LMT}
+    {-2372095484 -15408 0 CMT}
+    {-1567453392 -14400 0 ART}
+    {-1233432000 -10800 0 ARST}
+    {-1222981200 -14400 0 ART}
+    {-1205956800 -10800 1 ARST}
+    {-1194037200 -14400 0 ART}
+    {-1172865600 -10800 1 ARST}
+    {-1162501200 -14400 0 ART}
+    {-1141329600 -10800 1 ARST}
+    {-1130965200 -14400 0 ART}
+    {-1109793600 -10800 1 ARST}
+    {-1099429200 -14400 0 ART}
+    {-1078257600 -10800 1 ARST}
+    {-1067806800 -14400 0 ART}
+    {-1046635200 -10800 1 ARST}
+    {-1036270800 -14400 0 ART}
+    {-1015099200 -10800 1 ARST}
+    {-1004734800 -14400 0 ART}
+    {-983563200 -10800 1 ARST}
+    {-973198800 -14400 0 ART}
+    {-952027200 -10800 1 ARST}
+    {-941576400 -14400 0 ART}
+    {-931032000 -10800 1 ARST}
+    {-900882000 -14400 0 ART}
+    {-890337600 -10800 1 ARST}
+    {-833749200 -14400 0 ART}
+    {-827265600 -10800 1 ARST}
+    {-752274000 -14400 0 ART}
+    {-733780800 -10800 1 ARST}
+    {-197326800 -14400 0 ART}
+    {-190843200 -10800 1 ARST}
+    {-184194000 -14400 0 ART}
+    {-164491200 -10800 1 ARST}
+    {-152658000 -14400 0 ART}
+    {-132955200 -10800 1 ARST}
+    {-121122000 -14400 0 ART}
+    {-101419200 -10800 1 ARST}
+    {-86821200 -14400 0 ART}
+    {-71092800 -10800 1 ARST}
+    {-54766800 -14400 0 ART}
+    {-39038400 -10800 1 ARST}
+    {-23317200 -14400 0 ART}
+    {-7588800 -10800 0 ART}
+    {128142000 -7200 1 ARST}
+    {136605600 -10800 0 ART}
+    {596948400 -7200 1 ARST}
+    {605066400 -10800 0 ART}
+    {624423600 -7200 1 ARST}
+    {636516000 -14400 0 WART}
+    {655963200 -10800 1 WARST}
+    {667796400 -14400 0 WART}
+    {687499200 -10800 1 WARST}
+    {699418800 -14400 0 WART}
+    {719380800 -7200 0 ARST}
+    {731469600 -10800 0 ART}
+    {938916000 -10800 0 ART}
+    {938919600 -10800 1 ARST}
+    {952056000 -10800 0 ART}
+    {1085281200 -14400 0 WART}
+    {1096171200 -10800 0 ART}
+    {1198983600 -7200 1 ARST}
+    {1205632800 -10800 0 ART}
+    {1224295200 -10800 0 ART}
+}
diff --git a/library/tzdata/America/Argentina/Rio_Gallegos b/library/tzdata/America/Argentina/Rio_Gallegos
new file mode 100644
index 0000000..91d37dd
--- /dev/null
+++ b/library/tzdata/America/Argentina/Rio_Gallegos
@@ -0,0 +1,68 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Argentina/Rio_Gallegos) {
+    {-9223372036854775808 -16612 0 LMT}
+    {-2372095388 -15408 0 CMT}
+    {-1567453392 -14400 0 ART}
+    {-1233432000 -10800 0 ARST}
+    {-1222981200 -14400 0 ART}
+    {-1205956800 -10800 1 ARST}
+    {-1194037200 -14400 0 ART}
+    {-1172865600 -10800 1 ARST}
+    {-1162501200 -14400 0 ART}
+    {-1141329600 -10800 1 ARST}
+    {-1130965200 -14400 0 ART}
+    {-1109793600 -10800 1 ARST}
+    {-1099429200 -14400 0 ART}
+    {-1078257600 -10800 1 ARST}
+    {-1067806800 -14400 0 ART}
+    {-1046635200 -10800 1 ARST}
+    {-1036270800 -14400 0 ART}
+    {-1015099200 -10800 1 ARST}
+    {-1004734800 -14400 0 ART}
+    {-983563200 -10800 1 ARST}
+    {-973198800 -14400 0 ART}
+    {-952027200 -10800 1 ARST}
+    {-941576400 -14400 0 ART}
+    {-931032000 -10800 1 ARST}
+    {-900882000 -14400 0 ART}
+    {-890337600 -10800 1 ARST}
+    {-833749200 -14400 0 ART}
+    {-827265600 -10800 1 ARST}
+    {-752274000 -14400 0 ART}
+    {-733780800 -10800 1 ARST}
+    {-197326800 -14400 0 ART}
+    {-190843200 -10800 1 ARST}
+    {-184194000 -14400 0 ART}
+    {-164491200 -10800 1 ARST}
+    {-152658000 -14400 0 ART}
+    {-132955200 -10800 1 ARST}
+    {-121122000 -14400 0 ART}
+    {-101419200 -10800 1 ARST}
+    {-86821200 -14400 0 ART}
+    {-71092800 -10800 1 ARST}
+    {-54766800 -14400 0 ART}
+    {-39038400 -10800 1 ARST}
+    {-23317200 -14400 0 ART}
+    {-7588800 -10800 0 ART}
+    {128142000 -7200 1 ARST}
+    {136605600 -10800 0 ART}
+    {596948400 -7200 1 ARST}
+    {605066400 -10800 0 ART}
+    {624423600 -7200 1 ARST}
+    {636516000 -10800 0 ART}
+    {656478000 -7200 1 ARST}
+    {667965600 -10800 0 ART}
+    {687927600 -7200 1 ARST}
+    {699415200 -10800 0 ART}
+    {719377200 -7200 1 ARST}
+    {731469600 -10800 0 ART}
+    {938916000 -10800 0 ART}
+    {938919600 -10800 1 ARST}
+    {952056000 -10800 0 ART}
+    {1086058800 -14400 0 WART}
+    {1087704000 -10800 0 ART}
+    {1198983600 -7200 1 ARST}
+    {1205632800 -10800 0 ART}
+    {1224295200 -10800 0 ART}
+}
diff --git a/library/tzdata/America/Argentina/Salta b/library/tzdata/America/Argentina/Salta
new file mode 100644
index 0000000..a5a7010
--- /dev/null
+++ b/library/tzdata/America/Argentina/Salta
@@ -0,0 +1,66 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Argentina/Salta) {
+    {-9223372036854775808 -15700 0 LMT}
+    {-2372096300 -15408 0 CMT}
+    {-1567453392 -14400 0 ART}
+    {-1233432000 -10800 0 ARST}
+    {-1222981200 -14400 0 ART}
+    {-1205956800 -10800 1 ARST}
+    {-1194037200 -14400 0 ART}
+    {-1172865600 -10800 1 ARST}
+    {-1162501200 -14400 0 ART}
+    {-1141329600 -10800 1 ARST}
+    {-1130965200 -14400 0 ART}
+    {-1109793600 -10800 1 ARST}
+    {-1099429200 -14400 0 ART}
+    {-1078257600 -10800 1 ARST}
+    {-1067806800 -14400 0 ART}
+    {-1046635200 -10800 1 ARST}
+    {-1036270800 -14400 0 ART}
+    {-1015099200 -10800 1 ARST}
+    {-1004734800 -14400 0 ART}
+    {-983563200 -10800 1 ARST}
+    {-973198800 -14400 0 ART}
+    {-952027200 -10800 1 ARST}
+    {-941576400 -14400 0 ART}
+    {-931032000 -10800 1 ARST}
+    {-900882000 -14400 0 ART}
+    {-890337600 -10800 1 ARST}
+    {-833749200 -14400 0 ART}
+    {-827265600 -10800 1 ARST}
+    {-752274000 -14400 0 ART}
+    {-733780800 -10800 1 ARST}
+    {-197326800 -14400 0 ART}
+    {-190843200 -10800 1 ARST}
+    {-184194000 -14400 0 ART}
+    {-164491200 -10800 1 ARST}
+    {-152658000 -14400 0 ART}
+    {-132955200 -10800 1 ARST}
+    {-121122000 -14400 0 ART}
+    {-101419200 -10800 1 ARST}
+    {-86821200 -14400 0 ART}
+    {-71092800 -10800 1 ARST}
+    {-54766800 -14400 0 ART}
+    {-39038400 -10800 1 ARST}
+    {-23317200 -14400 0 ART}
+    {-7588800 -10800 0 ART}
+    {128142000 -7200 1 ARST}
+    {136605600 -10800 0 ART}
+    {596948400 -7200 1 ARST}
+    {605066400 -10800 0 ART}
+    {624423600 -7200 1 ARST}
+    {636516000 -10800 0 ART}
+    {656478000 -7200 1 ARST}
+    {667965600 -14400 0 WART}
+    {687931200 -7200 0 ARST}
+    {699415200 -10800 0 ART}
+    {719377200 -7200 1 ARST}
+    {731469600 -10800 0 ART}
+    {938916000 -10800 0 ART}
+    {938919600 -10800 1 ARST}
+    {952056000 -10800 0 ART}
+    {1198983600 -7200 1 ARST}
+    {1205632800 -10800 0 ART}
+    {1224295200 -10800 0 ART}
+}
diff --git a/library/tzdata/America/Argentina/San_Juan b/library/tzdata/America/Argentina/San_Juan
new file mode 100644
index 0000000..417e234
--- /dev/null
+++ b/library/tzdata/America/Argentina/San_Juan
@@ -0,0 +1,69 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Argentina/San_Juan) {
+    {-9223372036854775808 -16444 0 LMT}
+    {-2372095556 -15408 0 CMT}
+    {-1567453392 -14400 0 ART}
+    {-1233432000 -10800 0 ARST}
+    {-1222981200 -14400 0 ART}
+    {-1205956800 -10800 1 ARST}
+    {-1194037200 -14400 0 ART}
+    {-1172865600 -10800 1 ARST}
+    {-1162501200 -14400 0 ART}
+    {-1141329600 -10800 1 ARST}
+    {-1130965200 -14400 0 ART}
+    {-1109793600 -10800 1 ARST}
+    {-1099429200 -14400 0 ART}
+    {-1078257600 -10800 1 ARST}
+    {-1067806800 -14400 0 ART}
+    {-1046635200 -10800 1 ARST}
+    {-1036270800 -14400 0 ART}
+    {-1015099200 -10800 1 ARST}
+    {-1004734800 -14400 0 ART}
+    {-983563200 -10800 1 ARST}
+    {-973198800 -14400 0 ART}
+    {-952027200 -10800 1 ARST}
+    {-941576400 -14400 0 ART}
+    {-931032000 -10800 1 ARST}
+    {-900882000 -14400 0 ART}
+    {-890337600 -10800 1 ARST}
+    {-833749200 -14400 0 ART}
+    {-827265600 -10800 1 ARST}
+    {-752274000 -14400 0 ART}
+    {-733780800 -10800 1 ARST}
+    {-197326800 -14400 0 ART}
+    {-190843200 -10800 1 ARST}
+    {-184194000 -14400 0 ART}
+    {-164491200 -10800 1 ARST}
+    {-152658000 -14400 0 ART}
+    {-132955200 -10800 1 ARST}
+    {-121122000 -14400 0 ART}
+    {-101419200 -10800 1 ARST}
+    {-86821200 -14400 0 ART}
+    {-71092800 -10800 1 ARST}
+    {-54766800 -14400 0 ART}
+    {-39038400 -10800 1 ARST}
+    {-23317200 -14400 0 ART}
+    {-7588800 -10800 0 ART}
+    {128142000 -7200 1 ARST}
+    {136605600 -10800 0 ART}
+    {596948400 -7200 1 ARST}
+    {605066400 -10800 0 ART}
+    {624423600 -7200 1 ARST}
+    {636516000 -10800 0 ART}
+    {656478000 -7200 1 ARST}
+    {667792800 -14400 0 WART}
+    {673588800 -10800 0 ART}
+    {687927600 -7200 1 ARST}
+    {699415200 -10800 0 ART}
+    {719377200 -7200 1 ARST}
+    {731469600 -10800 0 ART}
+    {938916000 -10800 0 ART}
+    {938919600 -10800 1 ARST}
+    {952056000 -10800 0 ART}
+    {1085972400 -14400 0 WART}
+    {1090728000 -10800 0 ART}
+    {1198983600 -7200 1 ARST}
+    {1205632800 -10800 0 ART}
+    {1224295200 -10800 0 ART}
+}
diff --git a/library/tzdata/America/Argentina/San_Luis b/library/tzdata/America/Argentina/San_Luis
new file mode 100644
index 0000000..8ca55d7
--- /dev/null
+++ b/library/tzdata/America/Argentina/San_Luis
@@ -0,0 +1,68 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Argentina/San_Luis) {
+    {-9223372036854775808 -15924 0 LMT}
+    {-2372096076 -15408 0 CMT}
+    {-1567453392 -14400 0 ART}
+    {-1233432000 -10800 0 ARST}
+    {-1222981200 -14400 0 ART}
+    {-1205956800 -10800 1 ARST}
+    {-1194037200 -14400 0 ART}
+    {-1172865600 -10800 1 ARST}
+    {-1162501200 -14400 0 ART}
+    {-1141329600 -10800 1 ARST}
+    {-1130965200 -14400 0 ART}
+    {-1109793600 -10800 1 ARST}
+    {-1099429200 -14400 0 ART}
+    {-1078257600 -10800 1 ARST}
+    {-1067806800 -14400 0 ART}
+    {-1046635200 -10800 1 ARST}
+    {-1036270800 -14400 0 ART}
+    {-1015099200 -10800 1 ARST}
+    {-1004734800 -14400 0 ART}
+    {-983563200 -10800 1 ARST}
+    {-973198800 -14400 0 ART}
+    {-952027200 -10800 1 ARST}
+    {-941576400 -14400 0 ART}
+    {-931032000 -10800 1 ARST}
+    {-900882000 -14400 0 ART}
+    {-890337600 -10800 1 ARST}
+    {-833749200 -14400 0 ART}
+    {-827265600 -10800 1 ARST}
+    {-752274000 -14400 0 ART}
+    {-733780800 -10800 1 ARST}
+    {-197326800 -14400 0 ART}
+    {-190843200 -10800 1 ARST}
+    {-184194000 -14400 0 ART}
+    {-164491200 -10800 1 ARST}
+    {-152658000 -14400 0 ART}
+    {-132955200 -10800 1 ARST}
+    {-121122000 -14400 0 ART}
+    {-101419200 -10800 1 ARST}
+    {-86821200 -14400 0 ART}
+    {-71092800 -10800 1 ARST}
+    {-54766800 -14400 0 ART}
+    {-39038400 -10800 1 ARST}
+    {-23317200 -14400 0 ART}
+    {-7588800 -10800 0 ART}
+    {128142000 -7200 1 ARST}
+    {136605600 -10800 0 ART}
+    {596948400 -7200 1 ARST}
+    {605066400 -10800 0 ART}
+    {624423600 -7200 1 ARST}
+    {631159200 -7200 1 ARST}
+    {637380000 -14400 0 WART}
+    {655963200 -10800 1 WARST}
+    {667796400 -14400 0 WART}
+    {675748800 -10800 0 ART}
+    {938919600 -10800 1 WARST}
+    {952052400 -10800 0 ART}
+    {1085972400 -14400 0 WART}
+    {1090728000 -10800 0 ART}
+    {1198983600 -7200 1 ARST}
+    {1200880800 -10800 0 WART}
+    {1205031600 -14400 0 WART}
+    {1223784000 -10800 1 WARST}
+    {1236481200 -14400 0 WART}
+    {1255233600 -10800 0 ART}
+}
diff --git a/library/tzdata/America/Argentina/Tucuman b/library/tzdata/America/Argentina/Tucuman
new file mode 100644
index 0000000..3500986
--- /dev/null
+++ b/library/tzdata/America/Argentina/Tucuman
@@ -0,0 +1,69 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Argentina/Tucuman) {
+    {-9223372036854775808 -15652 0 LMT}
+    {-2372096348 -15408 0 CMT}
+    {-1567453392 -14400 0 ART}
+    {-1233432000 -10800 0 ARST}
+    {-1222981200 -14400 0 ART}
+    {-1205956800 -10800 1 ARST}
+    {-1194037200 -14400 0 ART}
+    {-1172865600 -10800 1 ARST}
+    {-1162501200 -14400 0 ART}
+    {-1141329600 -10800 1 ARST}
+    {-1130965200 -14400 0 ART}
+    {-1109793600 -10800 1 ARST}
+    {-1099429200 -14400 0 ART}
+    {-1078257600 -10800 1 ARST}
+    {-1067806800 -14400 0 ART}
+    {-1046635200 -10800 1 ARST}
+    {-1036270800 -14400 0 ART}
+    {-1015099200 -10800 1 ARST}
+    {-1004734800 -14400 0 ART}
+    {-983563200 -10800 1 ARST}
+    {-973198800 -14400 0 ART}
+    {-952027200 -10800 1 ARST}
+    {-941576400 -14400 0 ART}
+    {-931032000 -10800 1 ARST}
+    {-900882000 -14400 0 ART}
+    {-890337600 -10800 1 ARST}
+    {-833749200 -14400 0 ART}
+    {-827265600 -10800 1 ARST}
+    {-752274000 -14400 0 ART}
+    {-733780800 -10800 1 ARST}
+    {-197326800 -14400 0 ART}
+    {-190843200 -10800 1 ARST}
+    {-184194000 -14400 0 ART}
+    {-164491200 -10800 1 ARST}
+    {-152658000 -14400 0 ART}
+    {-132955200 -10800 1 ARST}
+    {-121122000 -14400 0 ART}
+    {-101419200 -10800 1 ARST}
+    {-86821200 -14400 0 ART}
+    {-71092800 -10800 1 ARST}
+    {-54766800 -14400 0 ART}
+    {-39038400 -10800 1 ARST}
+    {-23317200 -14400 0 ART}
+    {-7588800 -10800 0 ART}
+    {128142000 -7200 1 ARST}
+    {136605600 -10800 0 ART}
+    {596948400 -7200 1 ARST}
+    {605066400 -10800 0 ART}
+    {624423600 -7200 1 ARST}
+    {636516000 -10800 0 ART}
+    {656478000 -7200 1 ARST}
+    {667965600 -14400 0 WART}
+    {687931200 -7200 0 ARST}
+    {699415200 -10800 0 ART}
+    {719377200 -7200 1 ARST}
+    {731469600 -10800 0 ART}
+    {938916000 -10800 0 ART}
+    {938919600 -10800 1 ARST}
+    {952056000 -10800 0 ART}
+    {1086058800 -14400 0 WART}
+    {1087099200 -10800 0 ART}
+    {1198983600 -7200 1 ARST}
+    {1205632800 -10800 0 ART}
+    {1224385200 -7200 1 ARST}
+    {1237082400 -10800 0 ART}
+}
diff --git a/library/tzdata/America/Argentina/Ushuaia b/library/tzdata/America/Argentina/Ushuaia
new file mode 100644
index 0000000..4fcf92d
--- /dev/null
+++ b/library/tzdata/America/Argentina/Ushuaia
@@ -0,0 +1,68 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Argentina/Ushuaia) {
+    {-9223372036854775808 -16392 0 LMT}
+    {-2372095608 -15408 0 CMT}
+    {-1567453392 -14400 0 ART}
+    {-1233432000 -10800 0 ARST}
+    {-1222981200 -14400 0 ART}
+    {-1205956800 -10800 1 ARST}
+    {-1194037200 -14400 0 ART}
+    {-1172865600 -10800 1 ARST}
+    {-1162501200 -14400 0 ART}
+    {-1141329600 -10800 1 ARST}
+    {-1130965200 -14400 0 ART}
+    {-1109793600 -10800 1 ARST}
+    {-1099429200 -14400 0 ART}
+    {-1078257600 -10800 1 ARST}
+    {-1067806800 -14400 0 ART}
+    {-1046635200 -10800 1 ARST}
+    {-1036270800 -14400 0 ART}
+    {-1015099200 -10800 1 ARST}
+    {-1004734800 -14400 0 ART}
+    {-983563200 -10800 1 ARST}
+    {-973198800 -14400 0 ART}
+    {-952027200 -10800 1 ARST}
+    {-941576400 -14400 0 ART}
+    {-931032000 -10800 1 ARST}
+    {-900882000 -14400 0 ART}
+    {-890337600 -10800 1 ARST}
+    {-833749200 -14400 0 ART}
+    {-827265600 -10800 1 ARST}
+    {-752274000 -14400 0 ART}
+    {-733780800 -10800 1 ARST}
+    {-197326800 -14400 0 ART}
+    {-190843200 -10800 1 ARST}
+    {-184194000 -14400 0 ART}
+    {-164491200 -10800 1 ARST}
+    {-152658000 -14400 0 ART}
+    {-132955200 -10800 1 ARST}
+    {-121122000 -14400 0 ART}
+    {-101419200 -10800 1 ARST}
+    {-86821200 -14400 0 ART}
+    {-71092800 -10800 1 ARST}
+    {-54766800 -14400 0 ART}
+    {-39038400 -10800 1 ARST}
+    {-23317200 -14400 0 ART}
+    {-7588800 -10800 0 ART}
+    {128142000 -7200 1 ARST}
+    {136605600 -10800 0 ART}
+    {596948400 -7200 1 ARST}
+    {605066400 -10800 0 ART}
+    {624423600 -7200 1 ARST}
+    {636516000 -10800 0 ART}
+    {656478000 -7200 1 ARST}
+    {667965600 -10800 0 ART}
+    {687927600 -7200 1 ARST}
+    {699415200 -10800 0 ART}
+    {719377200 -7200 1 ARST}
+    {731469600 -10800 0 ART}
+    {938916000 -10800 0 ART}
+    {938919600 -10800 1 ARST}
+    {952056000 -10800 0 ART}
+    {1085886000 -14400 0 WART}
+    {1087704000 -10800 0 ART}
+    {1198983600 -7200 1 ARST}
+    {1205632800 -10800 0 ART}
+    {1224295200 -10800 0 ART}
+}
diff --git a/library/tzdata/America/Aruba b/library/tzdata/America/Aruba
new file mode 100644
index 0000000..e02d5fc
--- /dev/null
+++ b/library/tzdata/America/Aruba
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(America/Curacao)]} {
+    LoadTimeZoneFile America/Curacao
+}
+set TZData(:America/Aruba) $TZData(:America/Curacao)
diff --git a/library/tzdata/America/Asuncion b/library/tzdata/America/Asuncion
new file mode 100644
index 0000000..9ea30da
--- /dev/null
+++ b/library/tzdata/America/Asuncion
@@ -0,0 +1,259 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Asuncion) {
+    {-9223372036854775808 -13840 0 LMT}
+    {-2524507760 -13840 0 AMT}
+    {-1206389360 -14400 0 PYT}
+    {86760000 -10800 0 PYT}
+    {134017200 -14400 0 PYT}
+    {162878400 -14400 0 PYT}
+    {181368000 -10800 1 PYST}
+    {194497200 -14400 0 PYT}
+    {212990400 -10800 1 PYST}
+    {226033200 -14400 0 PYT}
+    {244526400 -10800 1 PYST}
+    {257569200 -14400 0 PYT}
+    {276062400 -10800 1 PYST}
+    {291783600 -14400 0 PYT}
+    {307598400 -10800 1 PYST}
+    {323406000 -14400 0 PYT}
+    {339220800 -10800 1 PYST}
+    {354942000 -14400 0 PYT}
+    {370756800 -10800 1 PYST}
+    {386478000 -14400 0 PYT}
+    {402292800 -10800 1 PYST}
+    {418014000 -14400 0 PYT}
+    {433828800 -10800 1 PYST}
+    {449636400 -14400 0 PYT}
+    {465451200 -10800 1 PYST}
+    {481172400 -14400 0 PYT}
+    {496987200 -10800 1 PYST}
+    {512708400 -14400 0 PYT}
+    {528523200 -10800 1 PYST}
+    {544244400 -14400 0 PYT}
+    {560059200 -10800 1 PYST}
+    {575866800 -14400 0 PYT}
+    {591681600 -10800 1 PYST}
+    {607402800 -14400 0 PYT}
+    {625032000 -10800 1 PYST}
+    {638938800 -14400 0 PYT}
+    {654753600 -10800 1 PYST}
+    {670474800 -14400 0 PYT}
+    {686721600 -10800 1 PYST}
+    {699418800 -14400 0 PYT}
+    {718257600 -10800 1 PYST}
+    {733546800 -14400 0 PYT}
+    {749448000 -10800 1 PYST}
+    {762318000 -14400 0 PYT}
+    {780984000 -10800 1 PYST}
+    {793767600 -14400 0 PYT}
+    {812520000 -10800 1 PYST}
+    {825649200 -14400 0 PYT}
+    {844574400 -10800 1 PYST}
+    {856666800 -14400 0 PYT}
+    {876024000 -10800 1 PYST}
+    {888721200 -14400 0 PYT}
+    {907473600 -10800 1 PYST}
+    {920775600 -14400 0 PYT}
+    {938923200 -10800 1 PYST}
+    {952225200 -14400 0 PYT}
+    {970372800 -10800 1 PYST}
+    {983674800 -14400 0 PYT}
+    {1002427200 -10800 1 PYST}
+    {1018148400 -14400 0 PYT}
+    {1030852800 -10800 1 PYST}
+    {1049598000 -14400 0 PYT}
+    {1062907200 -10800 1 PYST}
+    {1081047600 -14400 0 PYT}
+    {1097985600 -10800 1 PYST}
+    {1110682800 -14400 0 PYT}
+    {1129435200 -10800 1 PYST}
+    {1142132400 -14400 0 PYT}
+    {1160884800 -10800 1 PYST}
+    {1173582000 -14400 0 PYT}
+    {1192939200 -10800 1 PYST}
+    {1205031600 -14400 0 PYT}
+    {1224388800 -10800 1 PYST}
+    {1236481200 -14400 0 PYT}
+    {1255838400 -10800 1 PYST}
+    {1270954800 -14400 0 PYT}
+    {1286078400 -10800 1 PYST}
+    {1302404400 -14400 0 PYT}
+    {1317528000 -10800 1 PYST}
+    {1333854000 -14400 0 PYT}
+    {1349582400 -10800 1 PYST}
+    {1364094000 -14400 0 PYT}
+    {1381032000 -10800 1 PYST}
+    {1395543600 -14400 0 PYT}
+    {1412481600 -10800 1 PYST}
+    {1426993200 -14400 0 PYT}
+    {1443931200 -10800 1 PYST}
+    {1459047600 -14400 0 PYT}
+    {1475380800 -10800 1 PYST}
+    {1490497200 -14400 0 PYT}
+    {1506830400 -10800 1 PYST}
+    {1521946800 -14400 0 PYT}
+    {1538884800 -10800 1 PYST}
+    {1553396400 -14400 0 PYT}
+    {1570334400 -10800 1 PYST}
+    {1584846000 -14400 0 PYT}
+    {1601784000 -10800 1 PYST}
+    {1616900400 -14400 0 PYT}
+    {1633233600 -10800 1 PYST}
+    {1648350000 -14400 0 PYT}
+    {1664683200 -10800 1 PYST}
+    {1679799600 -14400 0 PYT}
+    {1696132800 -10800 1 PYST}
+    {1711249200 -14400 0 PYT}
+    {1728187200 -10800 1 PYST}
+    {1742698800 -14400 0 PYT}
+    {1759636800 -10800 1 PYST}
+    {1774148400 -14400 0 PYT}
+    {1791086400 -10800 1 PYST}
+    {1806202800 -14400 0 PYT}
+    {1822536000 -10800 1 PYST}
+    {1837652400 -14400 0 PYT}
+    {1853985600 -10800 1 PYST}
+    {1869102000 -14400 0 PYT}
+    {1886040000 -10800 1 PYST}
+    {1900551600 -14400 0 PYT}
+    {1917489600 -10800 1 PYST}
+    {1932001200 -14400 0 PYT}
+    {1948939200 -10800 1 PYST}
+    {1964055600 -14400 0 PYT}
+    {1980388800 -10800 1 PYST}
+    {1995505200 -14400 0 PYT}
+    {2011838400 -10800 1 PYST}
+    {2026954800 -14400 0 PYT}
+    {2043288000 -10800 1 PYST}
+    {2058404400 -14400 0 PYT}
+    {2075342400 -10800 1 PYST}
+    {2089854000 -14400 0 PYT}
+    {2106792000 -10800 1 PYST}
+    {2121303600 -14400 0 PYT}
+    {2138241600 -10800 1 PYST}
+    {2153358000 -14400 0 PYT}
+    {2169691200 -10800 1 PYST}
+    {2184807600 -14400 0 PYT}
+    {2201140800 -10800 1 PYST}
+    {2216257200 -14400 0 PYT}
+    {2233195200 -10800 1 PYST}
+    {2247706800 -14400 0 PYT}
+    {2264644800 -10800 1 PYST}
+    {2279156400 -14400 0 PYT}
+    {2296094400 -10800 1 PYST}
+    {2310606000 -14400 0 PYT}
+    {2327544000 -10800 1 PYST}
+    {2342660400 -14400 0 PYT}
+    {2358993600 -10800 1 PYST}
+    {2374110000 -14400 0 PYT}
+    {2390443200 -10800 1 PYST}
+    {2405559600 -14400 0 PYT}
+    {2422497600 -10800 1 PYST}
+    {2437009200 -14400 0 PYT}
+    {2453947200 -10800 1 PYST}
+    {2468458800 -14400 0 PYT}
+    {2485396800 -10800 1 PYST}
+    {2500513200 -14400 0 PYT}
+    {2516846400 -10800 1 PYST}
+    {2531962800 -14400 0 PYT}
+    {2548296000 -10800 1 PYST}
+    {2563412400 -14400 0 PYT}
+    {2579745600 -10800 1 PYST}
+    {2594862000 -14400 0 PYT}
+    {2611800000 -10800 1 PYST}
+    {2626311600 -14400 0 PYT}
+    {2643249600 -10800 1 PYST}
+    {2657761200 -14400 0 PYT}
+    {2674699200 -10800 1 PYST}
+    {2689815600 -14400 0 PYT}
+    {2706148800 -10800 1 PYST}
+    {2721265200 -14400 0 PYT}
+    {2737598400 -10800 1 PYST}
+    {2752714800 -14400 0 PYT}
+    {2769652800 -10800 1 PYST}
+    {2784164400 -14400 0 PYT}
+    {2801102400 -10800 1 PYST}
+    {2815614000 -14400 0 PYT}
+    {2832552000 -10800 1 PYST}
+    {2847668400 -14400 0 PYT}
+    {2864001600 -10800 1 PYST}
+    {2879118000 -14400 0 PYT}
+    {2895451200 -10800 1 PYST}
+    {2910567600 -14400 0 PYT}
+    {2926900800 -10800 1 PYST}
+    {2942017200 -14400 0 PYT}
+    {2958955200 -10800 1 PYST}
+    {2973466800 -14400 0 PYT}
+    {2990404800 -10800 1 PYST}
+    {3004916400 -14400 0 PYT}
+    {3021854400 -10800 1 PYST}
+    {3036970800 -14400 0 PYT}
+    {3053304000 -10800 1 PYST}
+    {3068420400 -14400 0 PYT}
+    {3084753600 -10800 1 PYST}
+    {3099870000 -14400 0 PYT}
+    {3116808000 -10800 1 PYST}
+    {3131319600 -14400 0 PYT}
+    {3148257600 -10800 1 PYST}
+    {3162769200 -14400 0 PYT}
+    {3179707200 -10800 1 PYST}
+    {3194218800 -14400 0 PYT}
+    {3211156800 -10800 1 PYST}
+    {3226273200 -14400 0 PYT}
+    {3242606400 -10800 1 PYST}
+    {3257722800 -14400 0 PYT}
+    {3274056000 -10800 1 PYST}
+    {3289172400 -14400 0 PYT}
+    {3306110400 -10800 1 PYST}
+    {3320622000 -14400 0 PYT}
+    {3337560000 -10800 1 PYST}
+    {3352071600 -14400 0 PYT}
+    {3369009600 -10800 1 PYST}
+    {3384126000 -14400 0 PYT}
+    {3400459200 -10800 1 PYST}
+    {3415575600 -14400 0 PYT}
+    {3431908800 -10800 1 PYST}
+    {3447025200 -14400 0 PYT}
+    {3463358400 -10800 1 PYST}
+    {3478474800 -14400 0 PYT}
+    {3495412800 -10800 1 PYST}
+    {3509924400 -14400 0 PYT}
+    {3526862400 -10800 1 PYST}
+    {3541374000 -14400 0 PYT}
+    {3558312000 -10800 1 PYST}
+    {3573428400 -14400 0 PYT}
+    {3589761600 -10800 1 PYST}
+    {3604878000 -14400 0 PYT}
+    {3621211200 -10800 1 PYST}
+    {3636327600 -14400 0 PYT}
+    {3653265600 -10800 1 PYST}
+    {3667777200 -14400 0 PYT}
+    {3684715200 -10800 1 PYST}
+    {3699226800 -14400 0 PYT}
+    {3716164800 -10800 1 PYST}
+    {3731281200 -14400 0 PYT}
+    {3747614400 -10800 1 PYST}
+    {3762730800 -14400 0 PYT}
+    {3779064000 -10800 1 PYST}
+    {3794180400 -14400 0 PYT}
+    {3810513600 -10800 1 PYST}
+    {3825630000 -14400 0 PYT}
+    {3842568000 -10800 1 PYST}
+    {3857079600 -14400 0 PYT}
+    {3874017600 -10800 1 PYST}
+    {3888529200 -14400 0 PYT}
+    {3905467200 -10800 1 PYST}
+    {3920583600 -14400 0 PYT}
+    {3936916800 -10800 1 PYST}
+    {3952033200 -14400 0 PYT}
+    {3968366400 -10800 1 PYST}
+    {3983482800 -14400 0 PYT}
+    {4000420800 -10800 1 PYST}
+    {4014932400 -14400 0 PYT}
+    {4031870400 -10800 1 PYST}
+    {4046382000 -14400 0 PYT}
+    {4063320000 -10800 1 PYST}
+    {4077831600 -14400 0 PYT}
+    {4094769600 -10800 1 PYST}
+}
diff --git a/library/tzdata/America/Atikokan b/library/tzdata/America/Atikokan
new file mode 100644
index 0000000..e72b04f
--- /dev/null
+++ b/library/tzdata/America/Atikokan
@@ -0,0 +1,12 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Atikokan) {
+    {-9223372036854775808 -21988 0 LMT}
+    {-2366733212 -21600 0 CST}
+    {-1632067200 -18000 1 CDT}
+    {-1615136400 -21600 0 CST}
+    {-923248800 -18000 1 CDT}
+    {-880214400 -18000 0 CWT}
+    {-769395600 -18000 1 CPT}
+    {-765388800 -18000 0 EST}
+}
diff --git a/library/tzdata/America/Atka b/library/tzdata/America/Atka
new file mode 100644
index 0000000..8da3302
--- /dev/null
+++ b/library/tzdata/America/Atka
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(America/Adak)]} {
+    LoadTimeZoneFile America/Adak
+}
+set TZData(:America/Atka) $TZData(:America/Adak)
diff --git a/library/tzdata/America/Bahia b/library/tzdata/America/Bahia
new file mode 100644
index 0000000..ac67b71
--- /dev/null
+++ b/library/tzdata/America/Bahia
@@ -0,0 +1,68 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Bahia) {
+    {-9223372036854775808 -9244 0 LMT}
+    {-1767216356 -10800 0 BRT}
+    {-1206957600 -7200 1 BRST}
+    {-1191362400 -10800 0 BRT}
+    {-1175374800 -7200 1 BRST}
+    {-1159826400 -10800 0 BRT}
+    {-633819600 -7200 1 BRST}
+    {-622069200 -10800 0 BRT}
+    {-602283600 -7200 1 BRST}
+    {-591832800 -10800 0 BRT}
+    {-570747600 -7200 1 BRST}
+    {-560210400 -10800 0 BRT}
+    {-539125200 -7200 1 BRST}
+    {-531352800 -10800 0 BRT}
+    {-191365200 -7200 1 BRST}
+    {-184197600 -10800 0 BRT}
+    {-155163600 -7200 1 BRST}
+    {-150069600 -10800 0 BRT}
+    {-128898000 -7200 1 BRST}
+    {-121125600 -10800 0 BRT}
+    {-99954000 -7200 1 BRST}
+    {-89589600 -10800 0 BRT}
+    {-68418000 -7200 1 BRST}
+    {-57967200 -10800 0 BRT}
+    {499748400 -7200 1 BRST}
+    {511236000 -10800 0 BRT}
+    {530593200 -7200 1 BRST}
+    {540266400 -10800 0 BRT}
+    {562129200 -7200 1 BRST}
+    {571197600 -10800 0 BRT}
+    {592974000 -7200 1 BRST}
+    {602042400 -10800 0 BRT}
+    {624423600 -7200 1 BRST}
+    {634701600 -10800 0 BRT}
+    {656478000 -7200 1 BRST}
+    {666756000 -10800 0 BRT}
+    {687927600 -7200 1 BRST}
+    {697600800 -10800 0 BRT}
+    {719982000 -7200 1 BRST}
+    {728445600 -10800 0 BRT}
+    {750826800 -7200 1 BRST}
+    {761709600 -10800 0 BRT}
+    {782276400 -7200 1 BRST}
+    {793159200 -10800 0 BRT}
+    {813726000 -7200 1 BRST}
+    {824004000 -10800 0 BRT}
+    {844570800 -7200 1 BRST}
+    {856058400 -10800 0 BRT}
+    {876106800 -7200 1 BRST}
+    {888717600 -10800 0 BRT}
+    {908074800 -7200 1 BRST}
+    {919562400 -10800 0 BRT}
+    {938919600 -7200 1 BRST}
+    {951616800 -10800 0 BRT}
+    {970974000 -7200 1 BRST}
+    {982461600 -10800 0 BRT}
+    {1003028400 -7200 1 BRST}
+    {1013911200 -10800 0 BRT}
+    {1036292400 -7200 1 BRST}
+    {1045360800 -10800 0 BRT}
+    {1064368800 -10800 0 BRT}
+    {1318734000 -7200 0 BRST}
+    {1330221600 -10800 0 BRT}
+    {1350784800 -10800 0 BRT}
+}
diff --git a/library/tzdata/America/Bahia_Banderas b/library/tzdata/America/Bahia_Banderas
new file mode 100644
index 0000000..8c40a0e
--- /dev/null
+++ b/library/tzdata/America/Bahia_Banderas
@@ -0,0 +1,222 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Bahia_Banderas) {
+    {-9223372036854775808 -25260 0 LMT}
+    {-1514739600 -25200 0 MST}
+    {-1343066400 -21600 0 CST}
+    {-1234807200 -25200 0 MST}
+    {-1220292000 -21600 0 CST}
+    {-1207159200 -25200 0 MST}
+    {-1191344400 -21600 0 CST}
+    {-873828000 -25200 0 MST}
+    {-661539600 -28800 0 PST}
+    {28800 -25200 0 MST}
+    {828867600 -21600 1 MDT}
+    {846403200 -25200 0 MST}
+    {860317200 -21600 1 MDT}
+    {877852800 -25200 0 MST}
+    {891766800 -21600 1 MDT}
+    {909302400 -25200 0 MST}
+    {923216400 -21600 1 MDT}
+    {941356800 -25200 0 MST}
+    {954666000 -21600 1 MDT}
+    {972806400 -25200 0 MST}
+    {989139600 -21600 1 MDT}
+    {1001836800 -25200 0 MST}
+    {1018170000 -21600 1 MDT}
+    {1035705600 -25200 0 MST}
+    {1049619600 -21600 1 MDT}
+    {1067155200 -25200 0 MST}
+    {1081069200 -21600 1 MDT}
+    {1099209600 -25200 0 MST}
+    {1112518800 -21600 1 MDT}
+    {1130659200 -25200 0 MST}
+    {1143968400 -21600 1 MDT}
+    {1162108800 -25200 0 MST}
+    {1175418000 -21600 1 MDT}
+    {1193558400 -25200 0 MST}
+    {1207472400 -21600 1 MDT}
+    {1225008000 -25200 0 MST}
+    {1238922000 -21600 1 MDT}
+    {1256457600 -25200 0 MST}
+    {1270371600 -18000 0 CDT}
+    {1288508400 -21600 0 CST}
+    {1301817600 -18000 1 CDT}
+    {1319958000 -21600 0 CST}
+    {1333267200 -18000 1 CDT}
+    {1351407600 -21600 0 CST}
+    {1365321600 -18000 1 CDT}
+    {1382857200 -21600 0 CST}
+    {1396771200 -18000 1 CDT}
+    {1414306800 -21600 0 CST}
+    {1428220800 -18000 1 CDT}
+    {1445756400 -21600 0 CST}
+    {1459670400 -18000 1 CDT}
+    {1477810800 -21600 0 CST}
+    {1491120000 -18000 1 CDT}
+    {1509260400 -21600 0 CST}
+    {1522569600 -18000 1 CDT}
+    {1540710000 -21600 0 CST}
+    {1554624000 -18000 1 CDT}
+    {1572159600 -21600 0 CST}
+    {1586073600 -18000 1 CDT}
+    {1603609200 -21600 0 CST}
+    {1617523200 -18000 1 CDT}
+    {1635663600 -21600 0 CST}
+    {1648972800 -18000 1 CDT}
+    {1667113200 -21600 0 CST}
+    {1680422400 -18000 1 CDT}
+    {1698562800 -21600 0 CST}
+    {1712476800 -18000 1 CDT}
+    {1730012400 -21600 0 CST}
+    {1743926400 -18000 1 CDT}
+    {1761462000 -21600 0 CST}
+    {1775376000 -18000 1 CDT}
+    {1792911600 -21600 0 CST}
+    {1806825600 -18000 1 CDT}
+    {1824966000 -21600 0 CST}
+    {1838275200 -18000 1 CDT}
+    {1856415600 -21600 0 CST}
+    {1869724800 -18000 1 CDT}
+    {1887865200 -21600 0 CST}
+    {1901779200 -18000 1 CDT}
+    {1919314800 -21600 0 CST}
+    {1933228800 -18000 1 CDT}
+    {1950764400 -21600 0 CST}
+    {1964678400 -18000 1 CDT}
+    {1982818800 -21600 0 CST}
+    {1996128000 -18000 1 CDT}
+    {2014268400 -21600 0 CST}
+    {2027577600 -18000 1 CDT}
+    {2045718000 -21600 0 CST}
+    {2059027200 -18000 1 CDT}
+    {2077167600 -21600 0 CST}
+    {2091081600 -18000 1 CDT}
+    {2108617200 -21600 0 CST}
+    {2122531200 -18000 1 CDT}
+    {2140066800 -21600 0 CST}
+    {2153980800 -18000 1 CDT}
+    {2172121200 -21600 0 CST}
+    {2185430400 -18000 1 CDT}
+    {2203570800 -21600 0 CST}
+    {2216880000 -18000 1 CDT}
+    {2235020400 -21600 0 CST}
+    {2248934400 -18000 1 CDT}
+    {2266470000 -21600 0 CST}
+    {2280384000 -18000 1 CDT}
+    {2297919600 -21600 0 CST}
+    {2311833600 -18000 1 CDT}
+    {2329369200 -21600 0 CST}
+    {2343283200 -18000 1 CDT}
+    {2361423600 -21600 0 CST}
+    {2374732800 -18000 1 CDT}
+    {2392873200 -21600 0 CST}
+    {2406182400 -18000 1 CDT}
+    {2424322800 -21600 0 CST}
+    {2438236800 -18000 1 CDT}
+    {2455772400 -21600 0 CST}
+    {2469686400 -18000 1 CDT}
+    {2487222000 -21600 0 CST}
+    {2501136000 -18000 1 CDT}
+    {2519276400 -21600 0 CST}
+    {2532585600 -18000 1 CDT}
+    {2550726000 -21600 0 CST}
+    {2564035200 -18000 1 CDT}
+    {2582175600 -21600 0 CST}
+    {2596089600 -18000 1 CDT}
+    {2613625200 -21600 0 CST}
+    {2627539200 -18000 1 CDT}
+    {2645074800 -21600 0 CST}
+    {2658988800 -18000 1 CDT}
+    {2676524400 -21600 0 CST}
+    {2690438400 -18000 1 CDT}
+    {2708578800 -21600 0 CST}
+    {2721888000 -18000 1 CDT}
+    {2740028400 -21600 0 CST}
+    {2753337600 -18000 1 CDT}
+    {2771478000 -21600 0 CST}
+    {2785392000 -18000 1 CDT}
+    {2802927600 -21600 0 CST}
+    {2816841600 -18000 1 CDT}
+    {2834377200 -21600 0 CST}
+    {2848291200 -18000 1 CDT}
+    {2866431600 -21600 0 CST}
+    {2879740800 -18000 1 CDT}
+    {2897881200 -21600 0 CST}
+    {2911190400 -18000 1 CDT}
+    {2929330800 -21600 0 CST}
+    {2942640000 -18000 1 CDT}
+    {2960780400 -21600 0 CST}
+    {2974694400 -18000 1 CDT}
+    {2992230000 -21600 0 CST}
+    {3006144000 -18000 1 CDT}
+    {3023679600 -21600 0 CST}
+    {3037593600 -18000 1 CDT}
+    {3055734000 -21600 0 CST}
+    {3069043200 -18000 1 CDT}
+    {3087183600 -21600 0 CST}
+    {3100492800 -18000 1 CDT}
+    {3118633200 -21600 0 CST}
+    {3132547200 -18000 1 CDT}
+    {3150082800 -21600 0 CST}
+    {3163996800 -18000 1 CDT}
+    {3181532400 -21600 0 CST}
+    {3195446400 -18000 1 CDT}
+    {3212982000 -21600 0 CST}
+    {3226896000 -18000 1 CDT}
+    {3245036400 -21600 0 CST}
+    {3258345600 -18000 1 CDT}
+    {3276486000 -21600 0 CST}
+    {3289795200 -18000 1 CDT}
+    {3307935600 -21600 0 CST}
+    {3321849600 -18000 1 CDT}
+    {3339385200 -21600 0 CST}
+    {3353299200 -18000 1 CDT}
+    {3370834800 -21600 0 CST}
+    {3384748800 -18000 1 CDT}
+    {3402889200 -21600 0 CST}
+    {3416198400 -18000 1 CDT}
+    {3434338800 -21600 0 CST}
+    {3447648000 -18000 1 CDT}
+    {3465788400 -21600 0 CST}
+    {3479702400 -18000 1 CDT}
+    {3497238000 -21600 0 CST}
+    {3511152000 -18000 1 CDT}
+    {3528687600 -21600 0 CST}
+    {3542601600 -18000 1 CDT}
+    {3560137200 -21600 0 CST}
+    {3574051200 -18000 1 CDT}
+    {3592191600 -21600 0 CST}
+    {3605500800 -18000 1 CDT}
+    {3623641200 -21600 0 CST}
+    {3636950400 -18000 1 CDT}
+    {3655090800 -21600 0 CST}
+    {3669004800 -18000 1 CDT}
+    {3686540400 -21600 0 CST}
+    {3700454400 -18000 1 CDT}
+    {3717990000 -21600 0 CST}
+    {3731904000 -18000 1 CDT}
+    {3750044400 -21600 0 CST}
+    {3763353600 -18000 1 CDT}
+    {3781494000 -21600 0 CST}
+    {3794803200 -18000 1 CDT}
+    {3812943600 -21600 0 CST}
+    {3826252800 -18000 1 CDT}
+    {3844393200 -21600 0 CST}
+    {3858307200 -18000 1 CDT}
+    {3875842800 -21600 0 CST}
+    {3889756800 -18000 1 CDT}
+    {3907292400 -21600 0 CST}
+    {3921206400 -18000 1 CDT}
+    {3939346800 -21600 0 CST}
+    {3952656000 -18000 1 CDT}
+    {3970796400 -21600 0 CST}
+    {3984105600 -18000 1 CDT}
+    {4002246000 -21600 0 CST}
+    {4016160000 -18000 1 CDT}
+    {4033695600 -21600 0 CST}
+    {4047609600 -18000 1 CDT}
+    {4065145200 -21600 0 CST}
+    {4079059200 -18000 1 CDT}
+    {4096594800 -21600 0 CST}
+}
diff --git a/library/tzdata/America/Barbados b/library/tzdata/America/Barbados
new file mode 100644
index 0000000..ea17073
--- /dev/null
+++ b/library/tzdata/America/Barbados
@@ -0,0 +1,15 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Barbados) {
+    {-9223372036854775808 -14309 0 LMT}
+    {-1451678491 -14309 0 BMT}
+    {-1199217691 -14400 0 AST}
+    {234943200 -10800 1 ADT}
+    {244616400 -14400 0 AST}
+    {261554400 -10800 1 ADT}
+    {276066000 -14400 0 AST}
+    {293004000 -10800 1 ADT}
+    {307515600 -14400 0 AST}
+    {325058400 -10800 1 ADT}
+    {338706000 -14400 0 AST}
+}
diff --git a/library/tzdata/America/Belem b/library/tzdata/America/Belem
new file mode 100644
index 0000000..ed92fd1
--- /dev/null
+++ b/library/tzdata/America/Belem
@@ -0,0 +1,35 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Belem) {
+    {-9223372036854775808 -11636 0 LMT}
+    {-1767213964 -10800 0 BRT}
+    {-1206957600 -7200 1 BRST}
+    {-1191362400 -10800 0 BRT}
+    {-1175374800 -7200 1 BRST}
+    {-1159826400 -10800 0 BRT}
+    {-633819600 -7200 1 BRST}
+    {-622069200 -10800 0 BRT}
+    {-602283600 -7200 1 BRST}
+    {-591832800 -10800 0 BRT}
+    {-570747600 -7200 1 BRST}
+    {-560210400 -10800 0 BRT}
+    {-539125200 -7200 1 BRST}
+    {-531352800 -10800 0 BRT}
+    {-191365200 -7200 1 BRST}
+    {-184197600 -10800 0 BRT}
+    {-155163600 -7200 1 BRST}
+    {-150069600 -10800 0 BRT}
+    {-128898000 -7200 1 BRST}
+    {-121125600 -10800 0 BRT}
+    {-99954000 -7200 1 BRST}
+    {-89589600 -10800 0 BRT}
+    {-68418000 -7200 1 BRST}
+    {-57967200 -10800 0 BRT}
+    {499748400 -7200 1 BRST}
+    {511236000 -10800 0 BRT}
+    {530593200 -7200 1 BRST}
+    {540266400 -10800 0 BRT}
+    {562129200 -7200 1 BRST}
+    {571197600 -10800 0 BRT}
+    {590032800 -10800 0 BRT}
+}
diff --git a/library/tzdata/America/Belize b/library/tzdata/America/Belize
new file mode 100644
index 0000000..547fd72
--- /dev/null
+++ b/library/tzdata/America/Belize
@@ -0,0 +1,60 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Belize) {
+    {-9223372036854775808 -21168 0 LMT}
+    {-1822500432 -21600 0 CST}
+    {-1616954400 -19800 1 CHDT}
+    {-1606069800 -21600 0 CST}
+    {-1585504800 -19800 1 CHDT}
+    {-1574015400 -21600 0 CST}
+    {-1554055200 -19800 1 CHDT}
+    {-1542565800 -21600 0 CST}
+    {-1522605600 -19800 1 CHDT}
+    {-1511116200 -21600 0 CST}
+    {-1490551200 -19800 1 CHDT}
+    {-1479666600 -21600 0 CST}
+    {-1459101600 -19800 1 CHDT}
+    {-1448217000 -21600 0 CST}
+    {-1427652000 -19800 1 CHDT}
+    {-1416162600 -21600 0 CST}
+    {-1396202400 -19800 1 CHDT}
+    {-1384713000 -21600 0 CST}
+    {-1364752800 -19800 1 CHDT}
+    {-1353263400 -21600 0 CST}
+    {-1333303200 -19800 1 CHDT}
+    {-1321813800 -21600 0 CST}
+    {-1301248800 -19800 1 CHDT}
+    {-1290364200 -21600 0 CST}
+    {-1269799200 -19800 1 CHDT}
+    {-1258914600 -21600 0 CST}
+    {-1238349600 -19800 1 CHDT}
+    {-1226860200 -21600 0 CST}
+    {-1206900000 -19800 1 CHDT}
+    {-1195410600 -21600 0 CST}
+    {-1175450400 -19800 1 CHDT}
+    {-1163961000 -21600 0 CST}
+    {-1143396000 -19800 1 CHDT}
+    {-1132511400 -21600 0 CST}
+    {-1111946400 -19800 1 CHDT}
+    {-1101061800 -21600 0 CST}
+    {-1080496800 -19800 1 CHDT}
+    {-1069612200 -21600 0 CST}
+    {-1049047200 -19800 1 CHDT}
+    {-1037557800 -21600 0 CST}
+    {-1017597600 -19800 1 CHDT}
+    {-1006108200 -21600 0 CST}
+    {-986148000 -19800 1 CHDT}
+    {-974658600 -21600 0 CST}
+    {-954093600 -19800 1 CHDT}
+    {-943209000 -21600 0 CST}
+    {-922644000 -19800 1 CHDT}
+    {-911759400 -21600 0 CST}
+    {-891194400 -19800 1 CHDT}
+    {-879705000 -21600 0 CST}
+    {-859744800 -19800 1 CHDT}
+    {-848255400 -21600 0 CST}
+    {123919200 -18000 1 CDT}
+    {129618000 -21600 0 CST}
+    {409039200 -18000 1 CDT}
+    {413874000 -21600 0 CST}
+}
diff --git a/library/tzdata/America/Blanc-Sablon b/library/tzdata/America/Blanc-Sablon
new file mode 100644
index 0000000..d5485e8
--- /dev/null
+++ b/library/tzdata/America/Blanc-Sablon
@@ -0,0 +1,12 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Blanc-Sablon) {
+    {-9223372036854775808 -13708 0 LMT}
+    {-2713896692 -14400 0 AST}
+    {-1632074400 -10800 1 ADT}
+    {-1615143600 -14400 0 AST}
+    {-880221600 -10800 1 AWT}
+    {-769395600 -10800 1 APT}
+    {-765399600 -14400 0 AST}
+    {14400 -14400 0 AST}
+}
diff --git a/library/tzdata/America/Boa_Vista b/library/tzdata/America/Boa_Vista
new file mode 100644
index 0000000..c85bc27
--- /dev/null
+++ b/library/tzdata/America/Boa_Vista
@@ -0,0 +1,40 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Boa_Vista) {
+    {-9223372036854775808 -14560 0 LMT}
+    {-1767211040 -14400 0 AMT}
+    {-1206954000 -10800 1 AMST}
+    {-1191358800 -14400 0 AMT}
+    {-1175371200 -10800 1 AMST}
+    {-1159822800 -14400 0 AMT}
+    {-633816000 -10800 1 AMST}
+    {-622065600 -14400 0 AMT}
+    {-602280000 -10800 1 AMST}
+    {-591829200 -14400 0 AMT}
+    {-570744000 -10800 1 AMST}
+    {-560206800 -14400 0 AMT}
+    {-539121600 -10800 1 AMST}
+    {-531349200 -14400 0 AMT}
+    {-191361600 -10800 1 AMST}
+    {-184194000 -14400 0 AMT}
+    {-155160000 -10800 1 AMST}
+    {-150066000 -14400 0 AMT}
+    {-128894400 -10800 1 AMST}
+    {-121122000 -14400 0 AMT}
+    {-99950400 -10800 1 AMST}
+    {-89586000 -14400 0 AMT}
+    {-68414400 -10800 1 AMST}
+    {-57963600 -14400 0 AMT}
+    {499752000 -10800 1 AMST}
+    {511239600 -14400 0 AMT}
+    {530596800 -10800 1 AMST}
+    {540270000 -14400 0 AMT}
+    {562132800 -10800 1 AMST}
+    {571201200 -14400 0 AMT}
+    {590036400 -14400 0 AMT}
+    {938664000 -14400 0 AMT}
+    {938923200 -10800 1 AMST}
+    {951620400 -14400 0 AMT}
+    {970977600 -10800 1 AMST}
+    {971578800 -14400 0 AMT}
+}
diff --git a/library/tzdata/America/Bogota b/library/tzdata/America/Bogota
new file mode 100644
index 0000000..b28abc1
--- /dev/null
+++ b/library/tzdata/America/Bogota
@@ -0,0 +1,9 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Bogota) {
+    {-9223372036854775808 -17776 0 LMT}
+    {-2707671824 -17776 0 BMT}
+    {-1739041424 -18000 0 COT}
+    {704869200 -14400 1 COST}
+    {733896000 -18000 0 COT}
+}
diff --git a/library/tzdata/America/Boise b/library/tzdata/America/Boise
new file mode 100644
index 0000000..62b22a0
--- /dev/null
+++ b/library/tzdata/America/Boise
@@ -0,0 +1,281 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Boise) {
+    {-9223372036854775808 -27889 0 LMT}
+    {-2717640000 -28800 0 PST}
+    {-1633269600 -25200 1 PDT}
+    {-1615129200 -28800 0 PST}
+    {-1601820000 -25200 1 PDT}
+    {-1583679600 -28800 0 PST}
+    {-1471788000 -25200 0 MST}
+    {-880210800 -21600 1 MWT}
+    {-769395600 -21600 1 MPT}
+    {-765388800 -25200 0 MST}
+    {-84380400 -21600 1 MDT}
+    {-68659200 -25200 0 MST}
+    {-52930800 -21600 1 MDT}
+    {-37209600 -25200 0 MST}
+    {-21481200 -21600 1 MDT}
+    {-5760000 -25200 0 MST}
+    {9968400 -21600 1 MDT}
+    {25689600 -25200 0 MST}
+    {41418000 -21600 1 MDT}
+    {57744000 -25200 0 MST}
+    {73472400 -21600 1 MDT}
+    {89193600 -25200 0 MST}
+    {104922000 -21600 1 MDT}
+    {120643200 -25200 0 MST}
+    {126255600 -25200 0 MST}
+    {129114000 -21600 0 MDT}
+    {152092800 -25200 0 MST}
+    {162378000 -21600 1 MDT}
+    {183542400 -25200 0 MST}
+    {199270800 -21600 1 MDT}
+    {215596800 -25200 0 MST}
+    {230720400 -21600 1 MDT}
+    {247046400 -25200 0 MST}
+    {262774800 -21600 1 MDT}
+    {278496000 -25200 0 MST}
+    {294224400 -21600 1 MDT}
+    {309945600 -25200 0 MST}
+    {325674000 -21600 1 MDT}
+    {341395200 -25200 0 MST}
+    {357123600 -21600 1 MDT}
+    {372844800 -25200 0 MST}
+    {388573200 -21600 1 MDT}
+    {404899200 -25200 0 MST}
+    {420022800 -21600 1 MDT}
+    {436348800 -25200 0 MST}
+    {452077200 -21600 1 MDT}
+    {467798400 -25200 0 MST}
+    {483526800 -21600 1 MDT}
+    {499248000 -25200 0 MST}
+    {514976400 -21600 1 MDT}
+    {530697600 -25200 0 MST}
+    {544611600 -21600 1 MDT}
+    {562147200 -25200 0 MST}
+    {576061200 -21600 1 MDT}
+    {594201600 -25200 0 MST}
+    {607510800 -21600 1 MDT}
+    {625651200 -25200 0 MST}
+    {638960400 -21600 1 MDT}
+    {657100800 -25200 0 MST}
+    {671014800 -21600 1 MDT}
+    {688550400 -25200 0 MST}
+    {702464400 -21600 1 MDT}
+    {720000000 -25200 0 MST}
+    {733914000 -21600 1 MDT}
+    {752054400 -25200 0 MST}
+    {765363600 -21600 1 MDT}
+    {783504000 -25200 0 MST}
+    {796813200 -21600 1 MDT}
+    {814953600 -25200 0 MST}
+    {828867600 -21600 1 MDT}
+    {846403200 -25200 0 MST}
+    {860317200 -21600 1 MDT}
+    {877852800 -25200 0 MST}
+    {891766800 -21600 1 MDT}
+    {909302400 -25200 0 MST}
+    {923216400 -21600 1 MDT}
+    {941356800 -25200 0 MST}
+    {954666000 -21600 1 MDT}
+    {972806400 -25200 0 MST}
+    {986115600 -21600 1 MDT}
+    {1004256000 -25200 0 MST}
+    {1018170000 -21600 1 MDT}
+    {1035705600 -25200 0 MST}
+    {1049619600 -21600 1 MDT}
+    {1067155200 -25200 0 MST}
+    {1081069200 -21600 1 MDT}
+    {1099209600 -25200 0 MST}
+    {1112518800 -21600 1 MDT}
+    {1130659200 -25200 0 MST}
+    {1143968400 -21600 1 MDT}
+    {1162108800 -25200 0 MST}
+    {1173603600 -21600 1 MDT}
+    {1194163200 -25200 0 MST}
+    {1205053200 -21600 1 MDT}
+    {1225612800 -25200 0 MST}
+    {1236502800 -21600 1 MDT}
+    {1257062400 -25200 0 MST}
+    {1268557200 -21600 1 MDT}
+    {1289116800 -25200 0 MST}
+    {1300006800 -21600 1 MDT}
+    {1320566400 -25200 0 MST}
+    {1331456400 -21600 1 MDT}
+    {1352016000 -25200 0 MST}
+    {1362906000 -21600 1 MDT}
+    {1383465600 -25200 0 MST}
+    {1394355600 -21600 1 MDT}
+    {1414915200 -25200 0 MST}
+    {1425805200 -21600 1 MDT}
+    {1446364800 -25200 0 MST}
+    {1457859600 -21600 1 MDT}
+    {1478419200 -25200 0 MST}
+    {1489309200 -21600 1 MDT}
+    {1509868800 -25200 0 MST}
+    {1520758800 -21600 1 MDT}
+    {1541318400 -25200 0 MST}
+    {1552208400 -21600 1 MDT}
+    {1572768000 -25200 0 MST}
+    {1583658000 -21600 1 MDT}
+    {1604217600 -25200 0 MST}
+    {1615712400 -21600 1 MDT}
+    {1636272000 -25200 0 MST}
+    {1647162000 -21600 1 MDT}
+    {1667721600 -25200 0 MST}
+    {1678611600 -21600 1 MDT}
+    {1699171200 -25200 0 MST}
+    {1710061200 -21600 1 MDT}
+    {1730620800 -25200 0 MST}
+    {1741510800 -21600 1 MDT}
+    {1762070400 -25200 0 MST}
+    {1772960400 -21600 1 MDT}
+    {1793520000 -25200 0 MST}
+    {1805014800 -21600 1 MDT}
+    {1825574400 -25200 0 MST}
+    {1836464400 -21600 1 MDT}
+    {1857024000 -25200 0 MST}
+    {1867914000 -21600 1 MDT}
+    {1888473600 -25200 0 MST}
+    {1899363600 -21600 1 MDT}
+    {1919923200 -25200 0 MST}
+    {1930813200 -21600 1 MDT}
+    {1951372800 -25200 0 MST}
+    {1962867600 -21600 1 MDT}
+    {1983427200 -25200 0 MST}
+    {1994317200 -21600 1 MDT}
+    {2014876800 -25200 0 MST}
+    {2025766800 -21600 1 MDT}
+    {2046326400 -25200 0 MST}
+    {2057216400 -21600 1 MDT}
+    {2077776000 -25200 0 MST}
+    {2088666000 -21600 1 MDT}
+    {2109225600 -25200 0 MST}
+    {2120115600 -21600 1 MDT}
+    {2140675200 -25200 0 MST}
+    {2152170000 -21600 1 MDT}
+    {2172729600 -25200 0 MST}
+    {2183619600 -21600 1 MDT}
+    {2204179200 -25200 0 MST}
+    {2215069200 -21600 1 MDT}
+    {2235628800 -25200 0 MST}
+    {2246518800 -21600 1 MDT}
+    {2267078400 -25200 0 MST}
+    {2277968400 -21600 1 MDT}
+    {2298528000 -25200 0 MST}
+    {2309418000 -21600 1 MDT}
+    {2329977600 -25200 0 MST}
+    {2341472400 -21600 1 MDT}
+    {2362032000 -25200 0 MST}
+    {2372922000 -21600 1 MDT}
+    {2393481600 -25200 0 MST}
+    {2404371600 -21600 1 MDT}
+    {2424931200 -25200 0 MST}
+    {2435821200 -21600 1 MDT}
+    {2456380800 -25200 0 MST}
+    {2467270800 -21600 1 MDT}
+    {2487830400 -25200 0 MST}
+    {2499325200 -21600 1 MDT}
+    {2519884800 -25200 0 MST}
+    {2530774800 -21600 1 MDT}
+    {2551334400 -25200 0 MST}
+    {2562224400 -21600 1 MDT}
+    {2582784000 -25200 0 MST}
+    {2593674000 -21600 1 MDT}
+    {2614233600 -25200 0 MST}
+    {2625123600 -21600 1 MDT}
+    {2645683200 -25200 0 MST}
+    {2656573200 -21600 1 MDT}
+    {2677132800 -25200 0 MST}
+    {2688627600 -21600 1 MDT}
+    {2709187200 -25200 0 MST}
+    {2720077200 -21600 1 MDT}
+    {2740636800 -25200 0 MST}
+    {2751526800 -21600 1 MDT}
+    {2772086400 -25200 0 MST}
+    {2782976400 -21600 1 MDT}
+    {2803536000 -25200 0 MST}
+    {2814426000 -21600 1 MDT}
+    {2834985600 -25200 0 MST}
+    {2846480400 -21600 1 MDT}
+    {2867040000 -25200 0 MST}
+    {2877930000 -21600 1 MDT}
+    {2898489600 -25200 0 MST}
+    {2909379600 -21600 1 MDT}
+    {2929939200 -25200 0 MST}
+    {2940829200 -21600 1 MDT}
+    {2961388800 -25200 0 MST}
+    {2972278800 -21600 1 MDT}
+    {2992838400 -25200 0 MST}
+    {3003728400 -21600 1 MDT}
+    {3024288000 -25200 0 MST}
+    {3035782800 -21600 1 MDT}
+    {3056342400 -25200 0 MST}
+    {3067232400 -21600 1 MDT}
+    {3087792000 -25200 0 MST}
+    {3098682000 -21600 1 MDT}
+    {3119241600 -25200 0 MST}
+    {3130131600 -21600 1 MDT}
+    {3150691200 -25200 0 MST}
+    {3161581200 -21600 1 MDT}
+    {3182140800 -25200 0 MST}
+    {3193030800 -21600 1 MDT}
+    {3213590400 -25200 0 MST}
+    {3225085200 -21600 1 MDT}
+    {3245644800 -25200 0 MST}
+    {3256534800 -21600 1 MDT}
+    {3277094400 -25200 0 MST}
+    {3287984400 -21600 1 MDT}
+    {3308544000 -25200 0 MST}
+    {3319434000 -21600 1 MDT}
+    {3339993600 -25200 0 MST}
+    {3350883600 -21600 1 MDT}
+    {3371443200 -25200 0 MST}
+    {3382938000 -21600 1 MDT}
+    {3403497600 -25200 0 MST}
+    {3414387600 -21600 1 MDT}
+    {3434947200 -25200 0 MST}
+    {3445837200 -21600 1 MDT}
+    {3466396800 -25200 0 MST}
+    {3477286800 -21600 1 MDT}
+    {3497846400 -25200 0 MST}
+    {3508736400 -21600 1 MDT}
+    {3529296000 -25200 0 MST}
+    {3540186000 -21600 1 MDT}
+    {3560745600 -25200 0 MST}
+    {3572240400 -21600 1 MDT}
+    {3592800000 -25200 0 MST}
+    {3603690000 -21600 1 MDT}
+    {3624249600 -25200 0 MST}
+    {3635139600 -21600 1 MDT}
+    {3655699200 -25200 0 MST}
+    {3666589200 -21600 1 MDT}
+    {3687148800 -25200 0 MST}
+    {3698038800 -21600 1 MDT}
+    {3718598400 -25200 0 MST}
+    {3730093200 -21600 1 MDT}
+    {3750652800 -25200 0 MST}
+    {3761542800 -21600 1 MDT}
+    {3782102400 -25200 0 MST}
+    {3792992400 -21600 1 MDT}
+    {3813552000 -25200 0 MST}
+    {3824442000 -21600 1 MDT}
+    {3845001600 -25200 0 MST}
+    {3855891600 -21600 1 MDT}
+    {3876451200 -25200 0 MST}
+    {3887341200 -21600 1 MDT}
+    {3907900800 -25200 0 MST}
+    {3919395600 -21600 1 MDT}
+    {3939955200 -25200 0 MST}
+    {3950845200 -21600 1 MDT}
+    {3971404800 -25200 0 MST}
+    {3982294800 -21600 1 MDT}
+    {4002854400 -25200 0 MST}
+    {4013744400 -21600 1 MDT}
+    {4034304000 -25200 0 MST}
+    {4045194000 -21600 1 MDT}
+    {4065753600 -25200 0 MST}
+    {4076643600 -21600 1 MDT}
+    {4097203200 -25200 0 MST}
+}
diff --git a/library/tzdata/America/Buenos_Aires b/library/tzdata/America/Buenos_Aires
new file mode 100644
index 0000000..1389195
--- /dev/null
+++ b/library/tzdata/America/Buenos_Aires
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(America/Argentina/Buenos_Aires)]} {
+    LoadTimeZoneFile America/Argentina/Buenos_Aires
+}
+set TZData(:America/Buenos_Aires) $TZData(:America/Argentina/Buenos_Aires)
diff --git a/library/tzdata/America/Cambridge_Bay b/library/tzdata/America/Cambridge_Bay
new file mode 100644
index 0000000..3115ee1
--- /dev/null
+++ b/library/tzdata/America/Cambridge_Bay
@@ -0,0 +1,252 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Cambridge_Bay) {
+    {-9223372036854775808 0 0 -00}
+    {-1577923200 -25200 0 MST}
+    {-880210800 -21600 1 MWT}
+    {-769395600 -21600 1 MPT}
+    {-765388800 -25200 0 MST}
+    {-147891600 -18000 1 MDDT}
+    {-131562000 -25200 0 MST}
+    {325674000 -21600 1 MDT}
+    {341395200 -25200 0 MST}
+    {357123600 -21600 1 MDT}
+    {372844800 -25200 0 MST}
+    {388573200 -21600 1 MDT}
+    {404899200 -25200 0 MST}
+    {420022800 -21600 1 MDT}
+    {436348800 -25200 0 MST}
+    {452077200 -21600 1 MDT}
+    {467798400 -25200 0 MST}
+    {483526800 -21600 1 MDT}
+    {499248000 -25200 0 MST}
+    {514976400 -21600 1 MDT}
+    {530697600 -25200 0 MST}
+    {544611600 -21600 1 MDT}
+    {562147200 -25200 0 MST}
+    {576061200 -21600 1 MDT}
+    {594201600 -25200 0 MST}
+    {607510800 -21600 1 MDT}
+    {625651200 -25200 0 MST}
+    {638960400 -21600 1 MDT}
+    {657100800 -25200 0 MST}
+    {671014800 -21600 1 MDT}
+    {688550400 -25200 0 MST}
+    {702464400 -21600 1 MDT}
+    {720000000 -25200 0 MST}
+    {733914000 -21600 1 MDT}
+    {752054400 -25200 0 MST}
+    {765363600 -21600 1 MDT}
+    {783504000 -25200 0 MST}
+    {796813200 -21600 1 MDT}
+    {814953600 -25200 0 MST}
+    {828867600 -21600 1 MDT}
+    {846403200 -25200 0 MST}
+    {860317200 -21600 1 MDT}
+    {877852800 -25200 0 MST}
+    {891766800 -21600 1 MDT}
+    {909302400 -25200 0 MST}
+    {923216400 -21600 1 MDT}
+    {941360400 -21600 0 CST}
+    {954662400 -18000 1 CDT}
+    {972806400 -18000 0 EST}
+    {973400400 -21600 0 CST}
+    {986115600 -21600 0 MDT}
+    {1004256000 -25200 0 MST}
+    {1018170000 -21600 1 MDT}
+    {1035705600 -25200 0 MST}
+    {1049619600 -21600 1 MDT}
+    {1067155200 -25200 0 MST}
+    {1081069200 -21600 1 MDT}
+    {1099209600 -25200 0 MST}
+    {1112518800 -21600 1 MDT}
+    {1130659200 -25200 0 MST}
+    {1143968400 -21600 1 MDT}
+    {1162108800 -25200 0 MST}
+    {1173603600 -21600 1 MDT}
+    {1194163200 -25200 0 MST}
+    {1205053200 -21600 1 MDT}
+    {1225612800 -25200 0 MST}
+    {1236502800 -21600 1 MDT}
+    {1257062400 -25200 0 MST}
+    {1268557200 -21600 1 MDT}
+    {1289116800 -25200 0 MST}
+    {1300006800 -21600 1 MDT}
+    {1320566400 -25200 0 MST}
+    {1331456400 -21600 1 MDT}
+    {1352016000 -25200 0 MST}
+    {1362906000 -21600 1 MDT}
+    {1383465600 -25200 0 MST}
+    {1394355600 -21600 1 MDT}
+    {1414915200 -25200 0 MST}
+    {1425805200 -21600 1 MDT}
+    {1446364800 -25200 0 MST}
+    {1457859600 -21600 1 MDT}
+    {1478419200 -25200 0 MST}
+    {1489309200 -21600 1 MDT}
+    {1509868800 -25200 0 MST}
+    {1520758800 -21600 1 MDT}
+    {1541318400 -25200 0 MST}
+    {1552208400 -21600 1 MDT}
+    {1572768000 -25200 0 MST}
+    {1583658000 -21600 1 MDT}
+    {1604217600 -25200 0 MST}
+    {1615712400 -21600 1 MDT}
+    {1636272000 -25200 0 MST}
+    {1647162000 -21600 1 MDT}
+    {1667721600 -25200 0 MST}
+    {1678611600 -21600 1 MDT}
+    {1699171200 -25200 0 MST}
+    {1710061200 -21600 1 MDT}
+    {1730620800 -25200 0 MST}
+    {1741510800 -21600 1 MDT}
+    {1762070400 -25200 0 MST}
+    {1772960400 -21600 1 MDT}
+    {1793520000 -25200 0 MST}
+    {1805014800 -21600 1 MDT}
+    {1825574400 -25200 0 MST}
+    {1836464400 -21600 1 MDT}
+    {1857024000 -25200 0 MST}
+    {1867914000 -21600 1 MDT}
+    {1888473600 -25200 0 MST}
+    {1899363600 -21600 1 MDT}
+    {1919923200 -25200 0 MST}
+    {1930813200 -21600 1 MDT}
+    {1951372800 -25200 0 MST}
+    {1962867600 -21600 1 MDT}
+    {1983427200 -25200 0 MST}
+    {1994317200 -21600 1 MDT}
+    {2014876800 -25200 0 MST}
+    {2025766800 -21600 1 MDT}
+    {2046326400 -25200 0 MST}
+    {2057216400 -21600 1 MDT}
+    {2077776000 -25200 0 MST}
+    {2088666000 -21600 1 MDT}
+    {2109225600 -25200 0 MST}
+    {2120115600 -21600 1 MDT}
+    {2140675200 -25200 0 MST}
+    {2152170000 -21600 1 MDT}
+    {2172729600 -25200 0 MST}
+    {2183619600 -21600 1 MDT}
+    {2204179200 -25200 0 MST}
+    {2215069200 -21600 1 MDT}
+    {2235628800 -25200 0 MST}
+    {2246518800 -21600 1 MDT}
+    {2267078400 -25200 0 MST}
+    {2277968400 -21600 1 MDT}
+    {2298528000 -25200 0 MST}
+    {2309418000 -21600 1 MDT}
+    {2329977600 -25200 0 MST}
+    {2341472400 -21600 1 MDT}
+    {2362032000 -25200 0 MST}
+    {2372922000 -21600 1 MDT}
+    {2393481600 -25200 0 MST}
+    {2404371600 -21600 1 MDT}
+    {2424931200 -25200 0 MST}
+    {2435821200 -21600 1 MDT}
+    {2456380800 -25200 0 MST}
+    {2467270800 -21600 1 MDT}
+    {2487830400 -25200 0 MST}
+    {2499325200 -21600 1 MDT}
+    {2519884800 -25200 0 MST}
+    {2530774800 -21600 1 MDT}
+    {2551334400 -25200 0 MST}
+    {2562224400 -21600 1 MDT}
+    {2582784000 -25200 0 MST}
+    {2593674000 -21600 1 MDT}
+    {2614233600 -25200 0 MST}
+    {2625123600 -21600 1 MDT}
+    {2645683200 -25200 0 MST}
+    {2656573200 -21600 1 MDT}
+    {2677132800 -25200 0 MST}
+    {2688627600 -21600 1 MDT}
+    {2709187200 -25200 0 MST}
+    {2720077200 -21600 1 MDT}
+    {2740636800 -25200 0 MST}
+    {2751526800 -21600 1 MDT}
+    {2772086400 -25200 0 MST}
+    {2782976400 -21600 1 MDT}
+    {2803536000 -25200 0 MST}
+    {2814426000 -21600 1 MDT}
+    {2834985600 -25200 0 MST}
+    {2846480400 -21600 1 MDT}
+    {2867040000 -25200 0 MST}
+    {2877930000 -21600 1 MDT}
+    {2898489600 -25200 0 MST}
+    {2909379600 -21600 1 MDT}
+    {2929939200 -25200 0 MST}
+    {2940829200 -21600 1 MDT}
+    {2961388800 -25200 0 MST}
+    {2972278800 -21600 1 MDT}
+    {2992838400 -25200 0 MST}
+    {3003728400 -21600 1 MDT}
+    {3024288000 -25200 0 MST}
+    {3035782800 -21600 1 MDT}
+    {3056342400 -25200 0 MST}
+    {3067232400 -21600 1 MDT}
+    {3087792000 -25200 0 MST}
+    {3098682000 -21600 1 MDT}
+    {3119241600 -25200 0 MST}
+    {3130131600 -21600 1 MDT}
+    {3150691200 -25200 0 MST}
+    {3161581200 -21600 1 MDT}
+    {3182140800 -25200 0 MST}
+    {3193030800 -21600 1 MDT}
+    {3213590400 -25200 0 MST}
+    {3225085200 -21600 1 MDT}
+    {3245644800 -25200 0 MST}
+    {3256534800 -21600 1 MDT}
+    {3277094400 -25200 0 MST}
+    {3287984400 -21600 1 MDT}
+    {3308544000 -25200 0 MST}
+    {3319434000 -21600 1 MDT}
+    {3339993600 -25200 0 MST}
+    {3350883600 -21600 1 MDT}
+    {3371443200 -25200 0 MST}
+    {3382938000 -21600 1 MDT}
+    {3403497600 -25200 0 MST}
+    {3414387600 -21600 1 MDT}
+    {3434947200 -25200 0 MST}
+    {3445837200 -21600 1 MDT}
+    {3466396800 -25200 0 MST}
+    {3477286800 -21600 1 MDT}
+    {3497846400 -25200 0 MST}
+    {3508736400 -21600 1 MDT}
+    {3529296000 -25200 0 MST}
+    {3540186000 -21600 1 MDT}
+    {3560745600 -25200 0 MST}
+    {3572240400 -21600 1 MDT}
+    {3592800000 -25200 0 MST}
+    {3603690000 -21600 1 MDT}
+    {3624249600 -25200 0 MST}
+    {3635139600 -21600 1 MDT}
+    {3655699200 -25200 0 MST}
+    {3666589200 -21600 1 MDT}
+    {3687148800 -25200 0 MST}
+    {3698038800 -21600 1 MDT}
+    {3718598400 -25200 0 MST}
+    {3730093200 -21600 1 MDT}
+    {3750652800 -25200 0 MST}
+    {3761542800 -21600 1 MDT}
+    {3782102400 -25200 0 MST}
+    {3792992400 -21600 1 MDT}
+    {3813552000 -25200 0 MST}
+    {3824442000 -21600 1 MDT}
+    {3845001600 -25200 0 MST}
+    {3855891600 -21600 1 MDT}
+    {3876451200 -25200 0 MST}
+    {3887341200 -21600 1 MDT}
+    {3907900800 -25200 0 MST}
+    {3919395600 -21600 1 MDT}
+    {3939955200 -25200 0 MST}
+    {3950845200 -21600 1 MDT}
+    {3971404800 -25200 0 MST}
+    {3982294800 -21600 1 MDT}
+    {4002854400 -25200 0 MST}
+    {4013744400 -21600 1 MDT}
+    {4034304000 -25200 0 MST}
+    {4045194000 -21600 1 MDT}
+    {4065753600 -25200 0 MST}
+    {4076643600 -21600 1 MDT}
+    {4097203200 -25200 0 MST}
+}
diff --git a/library/tzdata/America/Campo_Grande b/library/tzdata/America/Campo_Grande
new file mode 100644
index 0000000..2cafe14
--- /dev/null
+++ b/library/tzdata/America/Campo_Grande
@@ -0,0 +1,257 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Campo_Grande) {
+    {-9223372036854775808 -13108 0 LMT}
+    {-1767212492 -14400 0 AMT}
+    {-1206954000 -10800 1 AMST}
+    {-1191358800 -14400 0 AMT}
+    {-1175371200 -10800 1 AMST}
+    {-1159822800 -14400 0 AMT}
+    {-633816000 -10800 1 AMST}
+    {-622065600 -14400 0 AMT}
+    {-602280000 -10800 1 AMST}
+    {-591829200 -14400 0 AMT}
+    {-570744000 -10800 1 AMST}
+    {-560206800 -14400 0 AMT}
+    {-539121600 -10800 1 AMST}
+    {-531349200 -14400 0 AMT}
+    {-191361600 -10800 1 AMST}
+    {-184194000 -14400 0 AMT}
+    {-155160000 -10800 1 AMST}
+    {-150066000 -14400 0 AMT}
+    {-128894400 -10800 1 AMST}
+    {-121122000 -14400 0 AMT}
+    {-99950400 -10800 1 AMST}
+    {-89586000 -14400 0 AMT}
+    {-68414400 -10800 1 AMST}
+    {-57963600 -14400 0 AMT}
+    {499752000 -10800 1 AMST}
+    {511239600 -14400 0 AMT}
+    {530596800 -10800 1 AMST}
+    {540270000 -14400 0 AMT}
+    {562132800 -10800 1 AMST}
+    {571201200 -14400 0 AMT}
+    {592977600 -10800 1 AMST}
+    {602046000 -14400 0 AMT}
+    {624427200 -10800 1 AMST}
+    {634705200 -14400 0 AMT}
+    {656481600 -10800 1 AMST}
+    {666759600 -14400 0 AMT}
+    {687931200 -10800 1 AMST}
+    {697604400 -14400 0 AMT}
+    {719985600 -10800 1 AMST}
+    {728449200 -14400 0 AMT}
+    {750830400 -10800 1 AMST}
+    {761713200 -14400 0 AMT}
+    {782280000 -10800 1 AMST}
+    {793162800 -14400 0 AMT}
+    {813729600 -10800 1 AMST}
+    {824007600 -14400 0 AMT}
+    {844574400 -10800 1 AMST}
+    {856062000 -14400 0 AMT}
+    {876110400 -10800 1 AMST}
+    {888721200 -14400 0 AMT}
+    {908078400 -10800 1 AMST}
+    {919566000 -14400 0 AMT}
+    {938923200 -10800 1 AMST}
+    {951620400 -14400 0 AMT}
+    {970977600 -10800 1 AMST}
+    {982465200 -14400 0 AMT}
+    {1003032000 -10800 1 AMST}
+    {1013914800 -14400 0 AMT}
+    {1036296000 -10800 1 AMST}
+    {1045364400 -14400 0 AMT}
+    {1066536000 -10800 1 AMST}
+    {1076814000 -14400 0 AMT}
+    {1099368000 -10800 1 AMST}
+    {1108868400 -14400 0 AMT}
+    {1129435200 -10800 1 AMST}
+    {1140318000 -14400 0 AMT}
+    {1162699200 -10800 1 AMST}
+    {1172372400 -14400 0 AMT}
+    {1192334400 -10800 1 AMST}
+    {1203217200 -14400 0 AMT}
+    {1224388800 -10800 1 AMST}
+    {1234666800 -14400 0 AMT}
+    {1255838400 -10800 1 AMST}
+    {1266721200 -14400 0 AMT}
+    {1287288000 -10800 1 AMST}
+    {1298170800 -14400 0 AMT}
+    {1318737600 -10800 1 AMST}
+    {1330225200 -14400 0 AMT}
+    {1350792000 -10800 1 AMST}
+    {1361070000 -14400 0 AMT}
+    {1382241600 -10800 1 AMST}
+    {1392519600 -14400 0 AMT}
+    {1413691200 -10800 1 AMST}
+    {1424574000 -14400 0 AMT}
+    {1445140800 -10800 1 AMST}
+    {1456023600 -14400 0 AMT}
+    {1476590400 -10800 1 AMST}
+    {1487473200 -14400 0 AMT}
+    {1508040000 -10800 1 AMST}
+    {1518922800 -14400 0 AMT}
+    {1540094400 -10800 1 AMST}
+    {1550372400 -14400 0 AMT}
+    {1571544000 -10800 1 AMST}
+    {1581822000 -14400 0 AMT}
+    {1602993600 -10800 1 AMST}
+    {1613876400 -14400 0 AMT}
+    {1634443200 -10800 1 AMST}
+    {1645326000 -14400 0 AMT}
+    {1665892800 -10800 1 AMST}
+    {1677380400 -14400 0 AMT}
+    {1697342400 -10800 1 AMST}
+    {1708225200 -14400 0 AMT}
+    {1729396800 -10800 1 AMST}
+    {1739674800 -14400 0 AMT}
+    {1760846400 -10800 1 AMST}
+    {1771729200 -14400 0 AMT}
+    {1792296000 -10800 1 AMST}
+    {1803178800 -14400 0 AMT}
+    {1823745600 -10800 1 AMST}
+    {1834628400 -14400 0 AMT}
+    {1855195200 -10800 1 AMST}
+    {1866078000 -14400 0 AMT}
+    {1887249600 -10800 1 AMST}
+    {1897527600 -14400 0 AMT}
+    {1918699200 -10800 1 AMST}
+    {1928977200 -14400 0 AMT}
+    {1950148800 -10800 1 AMST}
+    {1960426800 -14400 0 AMT}
+    {1981598400 -10800 1 AMST}
+    {1992481200 -14400 0 AMT}
+    {2013048000 -10800 1 AMST}
+    {2024535600 -14400 0 AMT}
+    {2044497600 -10800 1 AMST}
+    {2055380400 -14400 0 AMT}
+    {2076552000 -10800 1 AMST}
+    {2086830000 -14400 0 AMT}
+    {2108001600 -10800 1 AMST}
+    {2118884400 -14400 0 AMT}
+    {2139451200 -10800 1 AMST}
+    {2150334000 -14400 0 AMT}
+    {2170900800 -10800 1 AMST}
+    {2181783600 -14400 0 AMT}
+    {2202350400 -10800 1 AMST}
+    {2213233200 -14400 0 AMT}
+    {2234404800 -10800 1 AMST}
+    {2244682800 -14400 0 AMT}
+    {2265854400 -10800 1 AMST}
+    {2276132400 -14400 0 AMT}
+    {2297304000 -10800 1 AMST}
+    {2307582000 -14400 0 AMT}
+    {2328753600 -10800 1 AMST}
+    {2339636400 -14400 0 AMT}
+    {2360203200 -10800 1 AMST}
+    {2371086000 -14400 0 AMT}
+    {2391652800 -10800 1 AMST}
+    {2402535600 -14400 0 AMT}
+    {2423707200 -10800 1 AMST}
+    {2433985200 -14400 0 AMT}
+    {2455156800 -10800 1 AMST}
+    {2465434800 -14400 0 AMT}
+    {2486606400 -10800 1 AMST}
+    {2497489200 -14400 0 AMT}
+    {2518056000 -10800 1 AMST}
+    {2528938800 -14400 0 AMT}
+    {2549505600 -10800 1 AMST}
+    {2560388400 -14400 0 AMT}
+    {2580955200 -10800 1 AMST}
+    {2591838000 -14400 0 AMT}
+    {2613009600 -10800 1 AMST}
+    {2623287600 -14400 0 AMT}
+    {2644459200 -10800 1 AMST}
+    {2654737200 -14400 0 AMT}
+    {2675908800 -10800 1 AMST}
+    {2686791600 -14400 0 AMT}
+    {2707358400 -10800 1 AMST}
+    {2718241200 -14400 0 AMT}
+    {2738808000 -10800 1 AMST}
+    {2749690800 -14400 0 AMT}
+    {2770862400 -10800 1 AMST}
+    {2781140400 -14400 0 AMT}
+    {2802312000 -10800 1 AMST}
+    {2812590000 -14400 0 AMT}
+    {2833761600 -10800 1 AMST}
+    {2844039600 -14400 0 AMT}
+    {2865211200 -10800 1 AMST}
+    {2876094000 -14400 0 AMT}
+    {2896660800 -10800 1 AMST}
+    {2907543600 -14400 0 AMT}
+    {2928110400 -10800 1 AMST}
+    {2938993200 -14400 0 AMT}
+    {2960164800 -10800 1 AMST}
+    {2970442800 -14400 0 AMT}
+    {2991614400 -10800 1 AMST}
+    {3001892400 -14400 0 AMT}
+    {3023064000 -10800 1 AMST}
+    {3033946800 -14400 0 AMT}
+    {3054513600 -10800 1 AMST}
+    {3065396400 -14400 0 AMT}
+    {3085963200 -10800 1 AMST}
+    {3096846000 -14400 0 AMT}
+    {3118017600 -10800 1 AMST}
+    {3128295600 -14400 0 AMT}
+    {3149467200 -10800 1 AMST}
+    {3159745200 -14400 0 AMT}
+    {3180916800 -10800 1 AMST}
+    {3191194800 -14400 0 AMT}
+    {3212366400 -10800 1 AMST}
+    {3223249200 -14400 0 AMT}
+    {3243816000 -10800 1 AMST}
+    {3254698800 -14400 0 AMT}
+    {3275265600 -10800 1 AMST}
+    {3286148400 -14400 0 AMT}
+    {3307320000 -10800 1 AMST}
+    {3317598000 -14400 0 AMT}
+    {3338769600 -10800 1 AMST}
+    {3349047600 -14400 0 AMT}
+    {3370219200 -10800 1 AMST}
+    {3381102000 -14400 0 AMT}
+    {3401668800 -10800 1 AMST}
+    {3412551600 -14400 0 AMT}
+    {3433118400 -10800 1 AMST}
+    {3444001200 -14400 0 AMT}
+    {3464568000 -10800 1 AMST}
+    {3475450800 -14400 0 AMT}
+    {3496622400 -10800 1 AMST}
+    {3506900400 -14400 0 AMT}
+    {3528072000 -10800 1 AMST}
+    {3538350000 -14400 0 AMT}
+    {3559521600 -10800 1 AMST}
+    {3570404400 -14400 0 AMT}
+    {3590971200 -10800 1 AMST}
+    {3601854000 -14400 0 AMT}
+    {3622420800 -10800 1 AMST}
+    {3633303600 -14400 0 AMT}
+    {3654475200 -10800 1 AMST}
+    {3664753200 -14400 0 AMT}
+    {3685924800 -10800 1 AMST}
+    {3696202800 -14400 0 AMT}
+    {3717374400 -10800 1 AMST}
+    {3727652400 -14400 0 AMT}
+    {3748824000 -10800 1 AMST}
+    {3759706800 -14400 0 AMT}
+    {3780273600 -10800 1 AMST}
+    {3791156400 -14400 0 AMT}
+    {3811723200 -10800 1 AMST}
+    {3822606000 -14400 0 AMT}
+    {3843777600 -10800 1 AMST}
+    {3854055600 -14400 0 AMT}
+    {3875227200 -10800 1 AMST}
+    {3885505200 -14400 0 AMT}
+    {3906676800 -10800 1 AMST}
+    {3917559600 -14400 0 AMT}
+    {3938126400 -10800 1 AMST}
+    {3949009200 -14400 0 AMT}
+    {3969576000 -10800 1 AMST}
+    {3980458800 -14400 0 AMT}
+    {4001630400 -10800 1 AMST}
+    {4011908400 -14400 0 AMT}
+    {4033080000 -10800 1 AMST}
+    {4043358000 -14400 0 AMT}
+    {4064529600 -10800 1 AMST}
+    {4074807600 -14400 0 AMT}
+    {4095979200 -10800 1 AMST}
+}
diff --git a/library/tzdata/America/Cancun b/library/tzdata/America/Cancun
new file mode 100644
index 0000000..fe5a060
--- /dev/null
+++ b/library/tzdata/America/Cancun
@@ -0,0 +1,47 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Cancun) {
+    {-9223372036854775808 -20824 0 LMT}
+    {-1514743200 -21600 0 CST}
+    {377935200 -18000 0 EST}
+    {828860400 -14400 1 EDT}
+    {846396000 -18000 0 EST}
+    {860310000 -14400 1 EDT}
+    {877845600 -18000 0 EST}
+    {891759600 -14400 1 EDT}
+    {902041200 -18000 0 CDT}
+    {909298800 -21600 0 CST}
+    {923212800 -18000 1 CDT}
+    {941353200 -21600 0 CST}
+    {954662400 -18000 1 CDT}
+    {972802800 -21600 0 CST}
+    {989136000 -18000 1 CDT}
+    {1001833200 -21600 0 CST}
+    {1018166400 -18000 1 CDT}
+    {1035702000 -21600 0 CST}
+    {1049616000 -18000 1 CDT}
+    {1067151600 -21600 0 CST}
+    {1081065600 -18000 1 CDT}
+    {1099206000 -21600 0 CST}
+    {1112515200 -18000 1 CDT}
+    {1130655600 -21600 0 CST}
+    {1143964800 -18000 1 CDT}
+    {1162105200 -21600 0 CST}
+    {1175414400 -18000 1 CDT}
+    {1193554800 -21600 0 CST}
+    {1207468800 -18000 1 CDT}
+    {1225004400 -21600 0 CST}
+    {1238918400 -18000 1 CDT}
+    {1256454000 -21600 0 CST}
+    {1270368000 -18000 1 CDT}
+    {1288508400 -21600 0 CST}
+    {1301817600 -18000 1 CDT}
+    {1319958000 -21600 0 CST}
+    {1333267200 -18000 1 CDT}
+    {1351407600 -21600 0 CST}
+    {1365321600 -18000 1 CDT}
+    {1382857200 -21600 0 CST}
+    {1396771200 -18000 1 CDT}
+    {1414306800 -21600 0 CST}
+    {1422777600 -18000 0 EST}
+}
diff --git a/library/tzdata/America/Caracas b/library/tzdata/America/Caracas
new file mode 100644
index 0000000..253c4ce
--- /dev/null
+++ b/library/tzdata/America/Caracas
@@ -0,0 +1,10 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Caracas) {
+    {-9223372036854775808 -16064 0 LMT}
+    {-2524505536 -16060 0 CMT}
+    {-1826739140 -16200 0 VET}
+    {-157750200 -14400 0 VET}
+    {1197183600 -16200 0 VET}
+    {1462086000 -14400 0 VET}
+}
diff --git a/library/tzdata/America/Catamarca b/library/tzdata/America/Catamarca
new file mode 100644
index 0000000..01c8ab6
--- /dev/null
+++ b/library/tzdata/America/Catamarca
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(America/Argentina/Catamarca)]} {
+    LoadTimeZoneFile America/Argentina/Catamarca
+}
+set TZData(:America/Catamarca) $TZData(:America/Argentina/Catamarca)
diff --git a/library/tzdata/America/Cayenne b/library/tzdata/America/Cayenne
new file mode 100644
index 0000000..de3d65b
--- /dev/null
+++ b/library/tzdata/America/Cayenne
@@ -0,0 +1,7 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Cayenne) {
+    {-9223372036854775808 -12560 0 LMT}
+    {-1846269040 -14400 0 GFT}
+    {-71092800 -10800 0 GFT}
+}
diff --git a/library/tzdata/America/Cayman b/library/tzdata/America/Cayman
new file mode 100644
index 0000000..92ce5e2
--- /dev/null
+++ b/library/tzdata/America/Cayman
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(America/Panama)]} {
+    LoadTimeZoneFile America/Panama
+}
+set TZData(:America/Cayman) $TZData(:America/Panama)
diff --git a/library/tzdata/America/Chicago b/library/tzdata/America/Chicago
new file mode 100644
index 0000000..545aedb
--- /dev/null
+++ b/library/tzdata/America/Chicago
@@ -0,0 +1,369 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Chicago) {
+    {-9223372036854775808 -21036 0 LMT}
+    {-2717647200 -21600 0 CST}
+    {-1633276800 -18000 1 CDT}
+    {-1615136400 -21600 0 CST}
+    {-1601827200 -18000 1 CDT}
+    {-1583686800 -21600 0 CST}
+    {-1577901600 -21600 0 CST}
+    {-1563724800 -18000 1 CDT}
+    {-1551632400 -21600 0 CST}
+    {-1538928000 -18000 1 CDT}
+    {-1520182800 -21600 0 CST}
+    {-1504454400 -18000 1 CDT}
+    {-1491757200 -21600 0 CST}
+    {-1473004800 -18000 1 CDT}
+    {-1459702800 -21600 0 CST}
+    {-1441555200 -18000 1 CDT}
+    {-1428253200 -21600 0 CST}
+    {-1410105600 -18000 1 CDT}
+    {-1396803600 -21600 0 CST}
+    {-1378656000 -18000 1 CDT}
+    {-1365354000 -21600 0 CST}
+    {-1347206400 -18000 1 CDT}
+    {-1333904400 -21600 0 CST}
+    {-1315152000 -18000 1 CDT}
+    {-1301850000 -21600 0 CST}
+    {-1283702400 -18000 1 CDT}
+    {-1270400400 -21600 0 CST}
+    {-1252252800 -18000 1 CDT}
+    {-1238950800 -21600 0 CST}
+    {-1220803200 -18000 1 CDT}
+    {-1207501200 -21600 0 CST}
+    {-1189353600 -18000 1 CDT}
+    {-1176051600 -21600 0 CST}
+    {-1157299200 -18000 1 CDT}
+    {-1144602000 -21600 0 CST}
+    {-1125849600 -18000 1 CDT}
+    {-1112547600 -21600 0 CST}
+    {-1094400000 -18000 1 CDT}
+    {-1081098000 -21600 0 CST}
+    {-1067788800 -18000 0 EST}
+    {-1045414800 -21600 0 CST}
+    {-1031500800 -18000 1 CDT}
+    {-1018198800 -21600 0 CST}
+    {-1000051200 -18000 1 CDT}
+    {-986749200 -21600 0 CST}
+    {-967996800 -18000 1 CDT}
+    {-955299600 -21600 0 CST}
+    {-936547200 -18000 1 CDT}
+    {-923245200 -21600 0 CST}
+    {-905097600 -18000 1 CDT}
+    {-891795600 -21600 0 CST}
+    {-883591200 -21600 0 CST}
+    {-880214400 -18000 1 CWT}
+    {-769395600 -18000 1 CPT}
+    {-765392400 -21600 0 CST}
+    {-757360800 -21600 0 CST}
+    {-747244800 -18000 1 CDT}
+    {-733942800 -21600 0 CST}
+    {-715795200 -18000 1 CDT}
+    {-702493200 -21600 0 CST}
+    {-684345600 -18000 1 CDT}
+    {-671043600 -21600 0 CST}
+    {-652896000 -18000 1 CDT}
+    {-639594000 -21600 0 CST}
+    {-620841600 -18000 1 CDT}
+    {-608144400 -21600 0 CST}
+    {-589392000 -18000 1 CDT}
+    {-576090000 -21600 0 CST}
+    {-557942400 -18000 1 CDT}
+    {-544640400 -21600 0 CST}
+    {-526492800 -18000 1 CDT}
+    {-513190800 -21600 0 CST}
+    {-495043200 -18000 1 CDT}
+    {-481741200 -21600 0 CST}
+    {-463593600 -18000 1 CDT}
+    {-447267600 -21600 0 CST}
+    {-431539200 -18000 1 CDT}
+    {-415818000 -21600 0 CST}
+    {-400089600 -18000 1 CDT}
+    {-384368400 -21600 0 CST}
+    {-368640000 -18000 1 CDT}
+    {-352918800 -21600 0 CST}
+    {-337190400 -18000 1 CDT}
+    {-321469200 -21600 0 CST}
+    {-305740800 -18000 1 CDT}
+    {-289414800 -21600 0 CST}
+    {-273686400 -18000 1 CDT}
+    {-257965200 -21600 0 CST}
+    {-242236800 -18000 1 CDT}
+    {-226515600 -21600 0 CST}
+    {-210787200 -18000 1 CDT}
+    {-195066000 -21600 0 CST}
+    {-179337600 -18000 1 CDT}
+    {-163616400 -21600 0 CST}
+    {-147888000 -18000 1 CDT}
+    {-131562000 -21600 0 CST}
+    {-116438400 -18000 1 CDT}
+    {-100112400 -21600 0 CST}
+    {-94672800 -21600 0 CST}
+    {-84384000 -18000 1 CDT}
+    {-68662800 -21600 0 CST}
+    {-52934400 -18000 1 CDT}
+    {-37213200 -21600 0 CST}
+    {-21484800 -18000 1 CDT}
+    {-5763600 -21600 0 CST}
+    {9964800 -18000 1 CDT}
+    {25686000 -21600 0 CST}
+    {41414400 -18000 1 CDT}
+    {57740400 -21600 0 CST}
+    {73468800 -18000 1 CDT}
+    {89190000 -21600 0 CST}
+    {104918400 -18000 1 CDT}
+    {120639600 -21600 0 CST}
+    {126691200 -18000 1 CDT}
+    {152089200 -21600 0 CST}
+    {162374400 -18000 1 CDT}
+    {183538800 -21600 0 CST}
+    {199267200 -18000 1 CDT}
+    {215593200 -21600 0 CST}
+    {230716800 -18000 1 CDT}
+    {247042800 -21600 0 CST}
+    {262771200 -18000 1 CDT}
+    {278492400 -21600 0 CST}
+    {294220800 -18000 1 CDT}
+    {309942000 -21600 0 CST}
+    {325670400 -18000 1 CDT}
+    {341391600 -21600 0 CST}
+    {357120000 -18000 1 CDT}
+    {372841200 -21600 0 CST}
+    {388569600 -18000 1 CDT}
+    {404895600 -21600 0 CST}
+    {420019200 -18000 1 CDT}
+    {436345200 -21600 0 CST}
+    {452073600 -18000 1 CDT}
+    {467794800 -21600 0 CST}
+    {483523200 -18000 1 CDT}
+    {499244400 -21600 0 CST}
+    {514972800 -18000 1 CDT}
+    {530694000 -21600 0 CST}
+    {544608000 -18000 1 CDT}
+    {562143600 -21600 0 CST}
+    {576057600 -18000 1 CDT}
+    {594198000 -21600 0 CST}
+    {607507200 -18000 1 CDT}
+    {625647600 -21600 0 CST}
+    {638956800 -18000 1 CDT}
+    {657097200 -21600 0 CST}
+    {671011200 -18000 1 CDT}
+    {688546800 -21600 0 CST}
+    {702460800 -18000 1 CDT}
+    {719996400 -21600 0 CST}
+    {733910400 -18000 1 CDT}
+    {752050800 -21600 0 CST}
+    {765360000 -18000 1 CDT}
+    {783500400 -21600 0 CST}
+    {796809600 -18000 1 CDT}
+    {814950000 -21600 0 CST}
+    {828864000 -18000 1 CDT}
+    {846399600 -21600 0 CST}
+    {860313600 -18000 1 CDT}
+    {877849200 -21600 0 CST}
+    {891763200 -18000 1 CDT}
+    {909298800 -21600 0 CST}
+    {923212800 -18000 1 CDT}
+    {941353200 -21600 0 CST}
+    {954662400 -18000 1 CDT}
+    {972802800 -21600 0 CST}
+    {986112000 -18000 1 CDT}
+    {1004252400 -21600 0 CST}
+    {1018166400 -18000 1 CDT}
+    {1035702000 -21600 0 CST}
+    {1049616000 -18000 1 CDT}
+    {1067151600 -21600 0 CST}
+    {1081065600 -18000 1 CDT}
+    {1099206000 -21600 0 CST}
+    {1112515200 -18000 1 CDT}
+    {1130655600 -21600 0 CST}
+    {1143964800 -18000 1 CDT}
+    {1162105200 -21600 0 CST}
+    {1173600000 -18000 1 CDT}
+    {1194159600 -21600 0 CST}
+    {1205049600 -18000 1 CDT}
+    {1225609200 -21600 0 CST}
+    {1236499200 -18000 1 CDT}
+    {1257058800 -21600 0 CST}
+    {1268553600 -18000 1 CDT}
+    {1289113200 -21600 0 CST}
+    {1300003200 -18000 1 CDT}
+    {1320562800 -21600 0 CST}
+    {1331452800 -18000 1 CDT}
+    {1352012400 -21600 0 CST}
+    {1362902400 -18000 1 CDT}
+    {1383462000 -21600 0 CST}
+    {1394352000 -18000 1 CDT}
+    {1414911600 -21600 0 CST}
+    {1425801600 -18000 1 CDT}
+    {1446361200 -21600 0 CST}
+    {1457856000 -18000 1 CDT}
+    {1478415600 -21600 0 CST}
+    {1489305600 -18000 1 CDT}
+    {1509865200 -21600 0 CST}
+    {1520755200 -18000 1 CDT}
+    {1541314800 -21600 0 CST}
+    {1552204800 -18000 1 CDT}
+    {1572764400 -21600 0 CST}
+    {1583654400 -18000 1 CDT}
+    {1604214000 -21600 0 CST}
+    {1615708800 -18000 1 CDT}
+    {1636268400 -21600 0 CST}
+    {1647158400 -18000 1 CDT}
+    {1667718000 -21600 0 CST}
+    {1678608000 -18000 1 CDT}
+    {1699167600 -21600 0 CST}
+    {1710057600 -18000 1 CDT}
+    {1730617200 -21600 0 CST}
+    {1741507200 -18000 1 CDT}
+    {1762066800 -21600 0 CST}
+    {1772956800 -18000 1 CDT}
+    {1793516400 -21600 0 CST}
+    {1805011200 -18000 1 CDT}
+    {1825570800 -21600 0 CST}
+    {1836460800 -18000 1 CDT}
+    {1857020400 -21600 0 CST}
+    {1867910400 -18000 1 CDT}
+    {1888470000 -21600 0 CST}
+    {1899360000 -18000 1 CDT}
+    {1919919600 -21600 0 CST}
+    {1930809600 -18000 1 CDT}
+    {1951369200 -21600 0 CST}
+    {1962864000 -18000 1 CDT}
+    {1983423600 -21600 0 CST}
+    {1994313600 -18000 1 CDT}
+    {2014873200 -21600 0 CST}
+    {2025763200 -18000 1 CDT}
+    {2046322800 -21600 0 CST}
+    {2057212800 -18000 1 CDT}
+    {2077772400 -21600 0 CST}
+    {2088662400 -18000 1 CDT}
+    {2109222000 -21600 0 CST}
+    {2120112000 -18000 1 CDT}
+    {2140671600 -21600 0 CST}
+    {2152166400 -18000 1 CDT}
+    {2172726000 -21600 0 CST}
+    {2183616000 -18000 1 CDT}
+    {2204175600 -21600 0 CST}
+    {2215065600 -18000 1 CDT}
+    {2235625200 -21600 0 CST}
+    {2246515200 -18000 1 CDT}
+    {2267074800 -21600 0 CST}
+    {2277964800 -18000 1 CDT}
+    {2298524400 -21600 0 CST}
+    {2309414400 -18000 1 CDT}
+    {2329974000 -21600 0 CST}
+    {2341468800 -18000 1 CDT}
+    {2362028400 -21600 0 CST}
+    {2372918400 -18000 1 CDT}
+    {2393478000 -21600 0 CST}
+    {2404368000 -18000 1 CDT}
+    {2424927600 -21600 0 CST}
+    {2435817600 -18000 1 CDT}
+    {2456377200 -21600 0 CST}
+    {2467267200 -18000 1 CDT}
+    {2487826800 -21600 0 CST}
+    {2499321600 -18000 1 CDT}
+    {2519881200 -21600 0 CST}
+    {2530771200 -18000 1 CDT}
+    {2551330800 -21600 0 CST}
+    {2562220800 -18000 1 CDT}
+    {2582780400 -21600 0 CST}
+    {2593670400 -18000 1 CDT}
+    {2614230000 -21600 0 CST}
+    {2625120000 -18000 1 CDT}
+    {2645679600 -21600 0 CST}
+    {2656569600 -18000 1 CDT}
+    {2677129200 -21600 0 CST}
+    {2688624000 -18000 1 CDT}
+    {2709183600 -21600 0 CST}
+    {2720073600 -18000 1 CDT}
+    {2740633200 -21600 0 CST}
+    {2751523200 -18000 1 CDT}
+    {2772082800 -21600 0 CST}
+    {2782972800 -18000 1 CDT}
+    {2803532400 -21600 0 CST}
+    {2814422400 -18000 1 CDT}
+    {2834982000 -21600 0 CST}
+    {2846476800 -18000 1 CDT}
+    {2867036400 -21600 0 CST}
+    {2877926400 -18000 1 CDT}
+    {2898486000 -21600 0 CST}
+    {2909376000 -18000 1 CDT}
+    {2929935600 -21600 0 CST}
+    {2940825600 -18000 1 CDT}
+    {2961385200 -21600 0 CST}
+    {2972275200 -18000 1 CDT}
+    {2992834800 -21600 0 CST}
+    {3003724800 -18000 1 CDT}
+    {3024284400 -21600 0 CST}
+    {3035779200 -18000 1 CDT}
+    {3056338800 -21600 0 CST}
+    {3067228800 -18000 1 CDT}
+    {3087788400 -21600 0 CST}
+    {3098678400 -18000 1 CDT}
+    {3119238000 -21600 0 CST}
+    {3130128000 -18000 1 CDT}
+    {3150687600 -21600 0 CST}
+    {3161577600 -18000 1 CDT}
+    {3182137200 -21600 0 CST}
+    {3193027200 -18000 1 CDT}
+    {3213586800 -21600 0 CST}
+    {3225081600 -18000 1 CDT}
+    {3245641200 -21600 0 CST}
+    {3256531200 -18000 1 CDT}
+    {3277090800 -21600 0 CST}
+    {3287980800 -18000 1 CDT}
+    {3308540400 -21600 0 CST}
+    {3319430400 -18000 1 CDT}
+    {3339990000 -21600 0 CST}
+    {3350880000 -18000 1 CDT}
+    {3371439600 -21600 0 CST}
+    {3382934400 -18000 1 CDT}
+    {3403494000 -21600 0 CST}
+    {3414384000 -18000 1 CDT}
+    {3434943600 -21600 0 CST}
+    {3445833600 -18000 1 CDT}
+    {3466393200 -21600 0 CST}
+    {3477283200 -18000 1 CDT}
+    {3497842800 -21600 0 CST}
+    {3508732800 -18000 1 CDT}
+    {3529292400 -21600 0 CST}
+    {3540182400 -18000 1 CDT}
+    {3560742000 -21600 0 CST}
+    {3572236800 -18000 1 CDT}
+    {3592796400 -21600 0 CST}
+    {3603686400 -18000 1 CDT}
+    {3624246000 -21600 0 CST}
+    {3635136000 -18000 1 CDT}
+    {3655695600 -21600 0 CST}
+    {3666585600 -18000 1 CDT}
+    {3687145200 -21600 0 CST}
+    {3698035200 -18000 1 CDT}
+    {3718594800 -21600 0 CST}
+    {3730089600 -18000 1 CDT}
+    {3750649200 -21600 0 CST}
+    {3761539200 -18000 1 CDT}
+    {3782098800 -21600 0 CST}
+    {3792988800 -18000 1 CDT}
+    {3813548400 -21600 0 CST}
+    {3824438400 -18000 1 CDT}
+    {3844998000 -21600 0 CST}
+    {3855888000 -18000 1 CDT}
+    {3876447600 -21600 0 CST}
+    {3887337600 -18000 1 CDT}
+    {3907897200 -21600 0 CST}
+    {3919392000 -18000 1 CDT}
+    {3939951600 -21600 0 CST}
+    {3950841600 -18000 1 CDT}
+    {3971401200 -21600 0 CST}
+    {3982291200 -18000 1 CDT}
+    {4002850800 -21600 0 CST}
+    {4013740800 -18000 1 CDT}
+    {4034300400 -21600 0 CST}
+    {4045190400 -18000 1 CDT}
+    {4065750000 -21600 0 CST}
+    {4076640000 -18000 1 CDT}
+    {4097199600 -21600 0 CST}
+}
diff --git a/library/tzdata/America/Chihuahua b/library/tzdata/America/Chihuahua
new file mode 100644
index 0000000..5444930
--- /dev/null
+++ b/library/tzdata/America/Chihuahua
@@ -0,0 +1,221 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Chihuahua) {
+    {-9223372036854775808 -25460 0 LMT}
+    {-1514739600 -25200 0 MST}
+    {-1343066400 -21600 0 CST}
+    {-1234807200 -25200 0 MST}
+    {-1220292000 -21600 0 CST}
+    {-1207159200 -25200 0 MST}
+    {-1191344400 -21600 0 CST}
+    {820476000 -21600 0 CST}
+    {828864000 -18000 1 CDT}
+    {846399600 -21600 0 CST}
+    {860313600 -18000 1 CDT}
+    {877849200 -21600 0 CST}
+    {883634400 -21600 0 CST}
+    {891766800 -21600 0 MDT}
+    {909302400 -25200 0 MST}
+    {923216400 -21600 1 MDT}
+    {941356800 -25200 0 MST}
+    {954666000 -21600 1 MDT}
+    {972806400 -25200 0 MST}
+    {989139600 -21600 1 MDT}
+    {1001836800 -25200 0 MST}
+    {1018170000 -21600 1 MDT}
+    {1035705600 -25200 0 MST}
+    {1049619600 -21600 1 MDT}
+    {1067155200 -25200 0 MST}
+    {1081069200 -21600 1 MDT}
+    {1099209600 -25200 0 MST}
+    {1112518800 -21600 1 MDT}
+    {1130659200 -25200 0 MST}
+    {1143968400 -21600 1 MDT}
+    {1162108800 -25200 0 MST}
+    {1175418000 -21600 1 MDT}
+    {1193558400 -25200 0 MST}
+    {1207472400 -21600 1 MDT}
+    {1225008000 -25200 0 MST}
+    {1238922000 -21600 1 MDT}
+    {1256457600 -25200 0 MST}
+    {1270371600 -21600 1 MDT}
+    {1288512000 -25200 0 MST}
+    {1301821200 -21600 1 MDT}
+    {1319961600 -25200 0 MST}
+    {1333270800 -21600 1 MDT}
+    {1351411200 -25200 0 MST}
+    {1365325200 -21600 1 MDT}
+    {1382860800 -25200 0 MST}
+    {1396774800 -21600 1 MDT}
+    {1414310400 -25200 0 MST}
+    {1428224400 -21600 1 MDT}
+    {1445760000 -25200 0 MST}
+    {1459674000 -21600 1 MDT}
+    {1477814400 -25200 0 MST}
+    {1491123600 -21600 1 MDT}
+    {1509264000 -25200 0 MST}
+    {1522573200 -21600 1 MDT}
+    {1540713600 -25200 0 MST}
+    {1554627600 -21600 1 MDT}
+    {1572163200 -25200 0 MST}
+    {1586077200 -21600 1 MDT}
+    {1603612800 -25200 0 MST}
+    {1617526800 -21600 1 MDT}
+    {1635667200 -25200 0 MST}
+    {1648976400 -21600 1 MDT}
+    {1667116800 -25200 0 MST}
+    {1680426000 -21600 1 MDT}
+    {1698566400 -25200 0 MST}
+    {1712480400 -21600 1 MDT}
+    {1730016000 -25200 0 MST}
+    {1743930000 -21600 1 MDT}
+    {1761465600 -25200 0 MST}
+    {1775379600 -21600 1 MDT}
+    {1792915200 -25200 0 MST}
+    {1806829200 -21600 1 MDT}
+    {1824969600 -25200 0 MST}
+    {1838278800 -21600 1 MDT}
+    {1856419200 -25200 0 MST}
+    {1869728400 -21600 1 MDT}
+    {1887868800 -25200 0 MST}
+    {1901782800 -21600 1 MDT}
+    {1919318400 -25200 0 MST}
+    {1933232400 -21600 1 MDT}
+    {1950768000 -25200 0 MST}
+    {1964682000 -21600 1 MDT}
+    {1982822400 -25200 0 MST}
+    {1996131600 -21600 1 MDT}
+    {2014272000 -25200 0 MST}
+    {2027581200 -21600 1 MDT}
+    {2045721600 -25200 0 MST}
+    {2059030800 -21600 1 MDT}
+    {2077171200 -25200 0 MST}
+    {2091085200 -21600 1 MDT}
+    {2108620800 -25200 0 MST}
+    {2122534800 -21600 1 MDT}
+    {2140070400 -25200 0 MST}
+    {2153984400 -21600 1 MDT}
+    {2172124800 -25200 0 MST}
+    {2185434000 -21600 1 MDT}
+    {2203574400 -25200 0 MST}
+    {2216883600 -21600 1 MDT}
+    {2235024000 -25200 0 MST}
+    {2248938000 -21600 1 MDT}
+    {2266473600 -25200 0 MST}
+    {2280387600 -21600 1 MDT}
+    {2297923200 -25200 0 MST}
+    {2311837200 -21600 1 MDT}
+    {2329372800 -25200 0 MST}
+    {2343286800 -21600 1 MDT}
+    {2361427200 -25200 0 MST}
+    {2374736400 -21600 1 MDT}
+    {2392876800 -25200 0 MST}
+    {2406186000 -21600 1 MDT}
+    {2424326400 -25200 0 MST}
+    {2438240400 -21600 1 MDT}
+    {2455776000 -25200 0 MST}
+    {2469690000 -21600 1 MDT}
+    {2487225600 -25200 0 MST}
+    {2501139600 -21600 1 MDT}
+    {2519280000 -25200 0 MST}
+    {2532589200 -21600 1 MDT}
+    {2550729600 -25200 0 MST}
+    {2564038800 -21600 1 MDT}
+    {2582179200 -25200 0 MST}
+    {2596093200 -21600 1 MDT}
+    {2613628800 -25200 0 MST}
+    {2627542800 -21600 1 MDT}
+    {2645078400 -25200 0 MST}
+    {2658992400 -21600 1 MDT}
+    {2676528000 -25200 0 MST}
+    {2690442000 -21600 1 MDT}
+    {2708582400 -25200 0 MST}
+    {2721891600 -21600 1 MDT}
+    {2740032000 -25200 0 MST}
+    {2753341200 -21600 1 MDT}
+    {2771481600 -25200 0 MST}
+    {2785395600 -21600 1 MDT}
+    {2802931200 -25200 0 MST}
+    {2816845200 -21600 1 MDT}
+    {2834380800 -25200 0 MST}
+    {2848294800 -21600 1 MDT}
+    {2866435200 -25200 0 MST}
+    {2879744400 -21600 1 MDT}
+    {2897884800 -25200 0 MST}
+    {2911194000 -21600 1 MDT}
+    {2929334400 -25200 0 MST}
+    {2942643600 -21600 1 MDT}
+    {2960784000 -25200 0 MST}
+    {2974698000 -21600 1 MDT}
+    {2992233600 -25200 0 MST}
+    {3006147600 -21600 1 MDT}
+    {3023683200 -25200 0 MST}
+    {3037597200 -21600 1 MDT}
+    {3055737600 -25200 0 MST}
+    {3069046800 -21600 1 MDT}
+    {3087187200 -25200 0 MST}
+    {3100496400 -21600 1 MDT}
+    {3118636800 -25200 0 MST}
+    {3132550800 -21600 1 MDT}
+    {3150086400 -25200 0 MST}
+    {3164000400 -21600 1 MDT}
+    {3181536000 -25200 0 MST}
+    {3195450000 -21600 1 MDT}
+    {3212985600 -25200 0 MST}
+    {3226899600 -21600 1 MDT}
+    {3245040000 -25200 0 MST}
+    {3258349200 -21600 1 MDT}
+    {3276489600 -25200 0 MST}
+    {3289798800 -21600 1 MDT}
+    {3307939200 -25200 0 MST}
+    {3321853200 -21600 1 MDT}
+    {3339388800 -25200 0 MST}
+    {3353302800 -21600 1 MDT}
+    {3370838400 -25200 0 MST}
+    {3384752400 -21600 1 MDT}
+    {3402892800 -25200 0 MST}
+    {3416202000 -21600 1 MDT}
+    {3434342400 -25200 0 MST}
+    {3447651600 -21600 1 MDT}
+    {3465792000 -25200 0 MST}
+    {3479706000 -21600 1 MDT}
+    {3497241600 -25200 0 MST}
+    {3511155600 -21600 1 MDT}
+    {3528691200 -25200 0 MST}
+    {3542605200 -21600 1 MDT}
+    {3560140800 -25200 0 MST}
+    {3574054800 -21600 1 MDT}
+    {3592195200 -25200 0 MST}
+    {3605504400 -21600 1 MDT}
+    {3623644800 -25200 0 MST}
+    {3636954000 -21600 1 MDT}
+    {3655094400 -25200 0 MST}
+    {3669008400 -21600 1 MDT}
+    {3686544000 -25200 0 MST}
+    {3700458000 -21600 1 MDT}
+    {3717993600 -25200 0 MST}
+    {3731907600 -21600 1 MDT}
+    {3750048000 -25200 0 MST}
+    {3763357200 -21600 1 MDT}
+    {3781497600 -25200 0 MST}
+    {3794806800 -21600 1 MDT}
+    {3812947200 -25200 0 MST}
+    {3826256400 -21600 1 MDT}
+    {3844396800 -25200 0 MST}
+    {3858310800 -21600 1 MDT}
+    {3875846400 -25200 0 MST}
+    {3889760400 -21600 1 MDT}
+    {3907296000 -25200 0 MST}
+    {3921210000 -21600 1 MDT}
+    {3939350400 -25200 0 MST}
+    {3952659600 -21600 1 MDT}
+    {3970800000 -25200 0 MST}
+    {3984109200 -21600 1 MDT}
+    {4002249600 -25200 0 MST}
+    {4016163600 -21600 1 MDT}
+    {4033699200 -25200 0 MST}
+    {4047613200 -21600 1 MDT}
+    {4065148800 -25200 0 MST}
+    {4079062800 -21600 1 MDT}
+    {4096598400 -25200 0 MST}
+}
diff --git a/library/tzdata/America/Coral_Harbour b/library/tzdata/America/Coral_Harbour
new file mode 100644
index 0000000..a27dc03
--- /dev/null
+++ b/library/tzdata/America/Coral_Harbour
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(America/Atikokan)]} {
+    LoadTimeZoneFile America/Atikokan
+}
+set TZData(:America/Coral_Harbour) $TZData(:America/Atikokan)
diff --git a/library/tzdata/America/Cordoba b/library/tzdata/America/Cordoba
new file mode 100644
index 0000000..c881558
--- /dev/null
+++ b/library/tzdata/America/Cordoba
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(America/Argentina/Cordoba)]} {
+    LoadTimeZoneFile America/Argentina/Cordoba
+}
+set TZData(:America/Cordoba) $TZData(:America/Argentina/Cordoba)
diff --git a/library/tzdata/America/Costa_Rica b/library/tzdata/America/Costa_Rica
new file mode 100644
index 0000000..8fc9343
--- /dev/null
+++ b/library/tzdata/America/Costa_Rica
@@ -0,0 +1,15 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Costa_Rica) {
+    {-9223372036854775808 -20173 0 LMT}
+    {-2524501427 -20173 0 SJMT}
+    {-1545071027 -21600 0 CST}
+    {288770400 -18000 1 CDT}
+    {297234000 -21600 0 CST}
+    {320220000 -18000 1 CDT}
+    {328683600 -21600 0 CST}
+    {664264800 -18000 1 CDT}
+    {678344400 -21600 0 CST}
+    {695714400 -18000 1 CDT}
+    {700635600 -21600 0 CST}
+}
diff --git a/library/tzdata/America/Creston b/library/tzdata/America/Creston
new file mode 100644
index 0000000..30369a9
--- /dev/null
+++ b/library/tzdata/America/Creston
@@ -0,0 +1,8 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Creston) {
+    {-9223372036854775808 -27964 0 LMT}
+    {-2713882436 -25200 0 MST}
+    {-1680454800 -28800 0 PST}
+    {-1627833600 -25200 0 MST}
+}
diff --git a/library/tzdata/America/Cuiaba b/library/tzdata/America/Cuiaba
new file mode 100644
index 0000000..0301862
--- /dev/null
+++ b/library/tzdata/America/Cuiaba
@@ -0,0 +1,257 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Cuiaba) {
+    {-9223372036854775808 -13460 0 LMT}
+    {-1767212140 -14400 0 AMT}
+    {-1206954000 -10800 1 AMST}
+    {-1191358800 -14400 0 AMT}
+    {-1175371200 -10800 1 AMST}
+    {-1159822800 -14400 0 AMT}
+    {-633816000 -10800 1 AMST}
+    {-622065600 -14400 0 AMT}
+    {-602280000 -10800 1 AMST}
+    {-591829200 -14400 0 AMT}
+    {-570744000 -10800 1 AMST}
+    {-560206800 -14400 0 AMT}
+    {-539121600 -10800 1 AMST}
+    {-531349200 -14400 0 AMT}
+    {-191361600 -10800 1 AMST}
+    {-184194000 -14400 0 AMT}
+    {-155160000 -10800 1 AMST}
+    {-150066000 -14400 0 AMT}
+    {-128894400 -10800 1 AMST}
+    {-121122000 -14400 0 AMT}
+    {-99950400 -10800 1 AMST}
+    {-89586000 -14400 0 AMT}
+    {-68414400 -10800 1 AMST}
+    {-57963600 -14400 0 AMT}
+    {499752000 -10800 1 AMST}
+    {511239600 -14400 0 AMT}
+    {530596800 -10800 1 AMST}
+    {540270000 -14400 0 AMT}
+    {562132800 -10800 1 AMST}
+    {571201200 -14400 0 AMT}
+    {592977600 -10800 1 AMST}
+    {602046000 -14400 0 AMT}
+    {624427200 -10800 1 AMST}
+    {634705200 -14400 0 AMT}
+    {656481600 -10800 1 AMST}
+    {666759600 -14400 0 AMT}
+    {687931200 -10800 1 AMST}
+    {697604400 -14400 0 AMT}
+    {719985600 -10800 1 AMST}
+    {728449200 -14400 0 AMT}
+    {750830400 -10800 1 AMST}
+    {761713200 -14400 0 AMT}
+    {782280000 -10800 1 AMST}
+    {793162800 -14400 0 AMT}
+    {813729600 -10800 1 AMST}
+    {824007600 -14400 0 AMT}
+    {844574400 -10800 1 AMST}
+    {856062000 -14400 0 AMT}
+    {876110400 -10800 1 AMST}
+    {888721200 -14400 0 AMT}
+    {908078400 -10800 1 AMST}
+    {919566000 -14400 0 AMT}
+    {938923200 -10800 1 AMST}
+    {951620400 -14400 0 AMT}
+    {970977600 -10800 1 AMST}
+    {982465200 -14400 0 AMT}
+    {1003032000 -10800 1 AMST}
+    {1013914800 -14400 0 AMT}
+    {1036296000 -10800 1 AMST}
+    {1045364400 -14400 0 AMT}
+    {1064372400 -14400 0 AMT}
+    {1096603200 -14400 0 AMT}
+    {1099368000 -10800 1 AMST}
+    {1108868400 -14400 0 AMT}
+    {1129435200 -10800 1 AMST}
+    {1140318000 -14400 0 AMT}
+    {1162699200 -10800 1 AMST}
+    {1172372400 -14400 0 AMT}
+    {1192334400 -10800 1 AMST}
+    {1203217200 -14400 0 AMT}
+    {1224388800 -10800 1 AMST}
+    {1234666800 -14400 0 AMT}
+    {1255838400 -10800 1 AMST}
+    {1266721200 -14400 0 AMT}
+    {1287288000 -10800 1 AMST}
+    {1298170800 -14400 0 AMT}
+    {1318737600 -10800 1 AMST}
+    {1330225200 -14400 0 AMT}
+    {1350792000 -10800 1 AMST}
+    {1361070000 -14400 0 AMT}
+    {1382241600 -10800 1 AMST}
+    {1392519600 -14400 0 AMT}
+    {1413691200 -10800 1 AMST}
+    {1424574000 -14400 0 AMT}
+    {1445140800 -10800 1 AMST}
+    {1456023600 -14400 0 AMT}
+    {1476590400 -10800 1 AMST}
+    {1487473200 -14400 0 AMT}
+    {1508040000 -10800 1 AMST}
+    {1518922800 -14400 0 AMT}
+    {1540094400 -10800 1 AMST}
+    {1550372400 -14400 0 AMT}
+    {1571544000 -10800 1 AMST}
+    {1581822000 -14400 0 AMT}
+    {1602993600 -10800 1 AMST}
+    {1613876400 -14400 0 AMT}
+    {1634443200 -10800 1 AMST}
+    {1645326000 -14400 0 AMT}
+    {1665892800 -10800 1 AMST}
+    {1677380400 -14400 0 AMT}
+    {1697342400 -10800 1 AMST}
+    {1708225200 -14400 0 AMT}
+    {1729396800 -10800 1 AMST}
+    {1739674800 -14400 0 AMT}
+    {1760846400 -10800 1 AMST}
+    {1771729200 -14400 0 AMT}
+    {1792296000 -10800 1 AMST}
+    {1803178800 -14400 0 AMT}
+    {1823745600 -10800 1 AMST}
+    {1834628400 -14400 0 AMT}
+    {1855195200 -10800 1 AMST}
+    {1866078000 -14400 0 AMT}
+    {1887249600 -10800 1 AMST}
+    {1897527600 -14400 0 AMT}
+    {1918699200 -10800 1 AMST}
+    {1928977200 -14400 0 AMT}
+    {1950148800 -10800 1 AMST}
+    {1960426800 -14400 0 AMT}
+    {1981598400 -10800 1 AMST}
+    {1992481200 -14400 0 AMT}
+    {2013048000 -10800 1 AMST}
+    {2024535600 -14400 0 AMT}
+    {2044497600 -10800 1 AMST}
+    {2055380400 -14400 0 AMT}
+    {2076552000 -10800 1 AMST}
+    {2086830000 -14400 0 AMT}
+    {2108001600 -10800 1 AMST}
+    {2118884400 -14400 0 AMT}
+    {2139451200 -10800 1 AMST}
+    {2150334000 -14400 0 AMT}
+    {2170900800 -10800 1 AMST}
+    {2181783600 -14400 0 AMT}
+    {2202350400 -10800 1 AMST}
+    {2213233200 -14400 0 AMT}
+    {2234404800 -10800 1 AMST}
+    {2244682800 -14400 0 AMT}
+    {2265854400 -10800 1 AMST}
+    {2276132400 -14400 0 AMT}
+    {2297304000 -10800 1 AMST}
+    {2307582000 -14400 0 AMT}
+    {2328753600 -10800 1 AMST}
+    {2339636400 -14400 0 AMT}
+    {2360203200 -10800 1 AMST}
+    {2371086000 -14400 0 AMT}
+    {2391652800 -10800 1 AMST}
+    {2402535600 -14400 0 AMT}
+    {2423707200 -10800 1 AMST}
+    {2433985200 -14400 0 AMT}
+    {2455156800 -10800 1 AMST}
+    {2465434800 -14400 0 AMT}
+    {2486606400 -10800 1 AMST}
+    {2497489200 -14400 0 AMT}
+    {2518056000 -10800 1 AMST}
+    {2528938800 -14400 0 AMT}
+    {2549505600 -10800 1 AMST}
+    {2560388400 -14400 0 AMT}
+    {2580955200 -10800 1 AMST}
+    {2591838000 -14400 0 AMT}
+    {2613009600 -10800 1 AMST}
+    {2623287600 -14400 0 AMT}
+    {2644459200 -10800 1 AMST}
+    {2654737200 -14400 0 AMT}
+    {2675908800 -10800 1 AMST}
+    {2686791600 -14400 0 AMT}
+    {2707358400 -10800 1 AMST}
+    {2718241200 -14400 0 AMT}
+    {2738808000 -10800 1 AMST}
+    {2749690800 -14400 0 AMT}
+    {2770862400 -10800 1 AMST}
+    {2781140400 -14400 0 AMT}
+    {2802312000 -10800 1 AMST}
+    {2812590000 -14400 0 AMT}
+    {2833761600 -10800 1 AMST}
+    {2844039600 -14400 0 AMT}
+    {2865211200 -10800 1 AMST}
+    {2876094000 -14400 0 AMT}
+    {2896660800 -10800 1 AMST}
+    {2907543600 -14400 0 AMT}
+    {2928110400 -10800 1 AMST}
+    {2938993200 -14400 0 AMT}
+    {2960164800 -10800 1 AMST}
+    {2970442800 -14400 0 AMT}
+    {2991614400 -10800 1 AMST}
+    {3001892400 -14400 0 AMT}
+    {3023064000 -10800 1 AMST}
+    {3033946800 -14400 0 AMT}
+    {3054513600 -10800 1 AMST}
+    {3065396400 -14400 0 AMT}
+    {3085963200 -10800 1 AMST}
+    {3096846000 -14400 0 AMT}
+    {3118017600 -10800 1 AMST}
+    {3128295600 -14400 0 AMT}
+    {3149467200 -10800 1 AMST}
+    {3159745200 -14400 0 AMT}
+    {3180916800 -10800 1 AMST}
+    {3191194800 -14400 0 AMT}
+    {3212366400 -10800 1 AMST}
+    {3223249200 -14400 0 AMT}
+    {3243816000 -10800 1 AMST}
+    {3254698800 -14400 0 AMT}
+    {3275265600 -10800 1 AMST}
+    {3286148400 -14400 0 AMT}
+    {3307320000 -10800 1 AMST}
+    {3317598000 -14400 0 AMT}
+    {3338769600 -10800 1 AMST}
+    {3349047600 -14400 0 AMT}
+    {3370219200 -10800 1 AMST}
+    {3381102000 -14400 0 AMT}
+    {3401668800 -10800 1 AMST}
+    {3412551600 -14400 0 AMT}
+    {3433118400 -10800 1 AMST}
+    {3444001200 -14400 0 AMT}
+    {3464568000 -10800 1 AMST}
+    {3475450800 -14400 0 AMT}
+    {3496622400 -10800 1 AMST}
+    {3506900400 -14400 0 AMT}
+    {3528072000 -10800 1 AMST}
+    {3538350000 -14400 0 AMT}
+    {3559521600 -10800 1 AMST}
+    {3570404400 -14400 0 AMT}
+    {3590971200 -10800 1 AMST}
+    {3601854000 -14400 0 AMT}
+    {3622420800 -10800 1 AMST}
+    {3633303600 -14400 0 AMT}
+    {3654475200 -10800 1 AMST}
+    {3664753200 -14400 0 AMT}
+    {3685924800 -10800 1 AMST}
+    {3696202800 -14400 0 AMT}
+    {3717374400 -10800 1 AMST}
+    {3727652400 -14400 0 AMT}
+    {3748824000 -10800 1 AMST}
+    {3759706800 -14400 0 AMT}
+    {3780273600 -10800 1 AMST}
+    {3791156400 -14400 0 AMT}
+    {3811723200 -10800 1 AMST}
+    {3822606000 -14400 0 AMT}
+    {3843777600 -10800 1 AMST}
+    {3854055600 -14400 0 AMT}
+    {3875227200 -10800 1 AMST}
+    {3885505200 -14400 0 AMT}
+    {3906676800 -10800 1 AMST}
+    {3917559600 -14400 0 AMT}
+    {3938126400 -10800 1 AMST}
+    {3949009200 -14400 0 AMT}
+    {3969576000 -10800 1 AMST}
+    {3980458800 -14400 0 AMT}
+    {4001630400 -10800 1 AMST}
+    {4011908400 -14400 0 AMT}
+    {4033080000 -10800 1 AMST}
+    {4043358000 -14400 0 AMT}
+    {4064529600 -10800 1 AMST}
+    {4074807600 -14400 0 AMT}
+    {4095979200 -10800 1 AMST}
+}
diff --git a/library/tzdata/America/Curacao b/library/tzdata/America/Curacao
new file mode 100644
index 0000000..5189e9c
--- /dev/null
+++ b/library/tzdata/America/Curacao
@@ -0,0 +1,7 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Curacao) {
+    {-9223372036854775808 -16547 0 LMT}
+    {-1826738653 -16200 0 ANT}
+    {-157750200 -14400 0 AST}
+}
diff --git a/library/tzdata/America/Danmarkshavn b/library/tzdata/America/Danmarkshavn
new file mode 100644
index 0000000..8d66d3a
--- /dev/null
+++ b/library/tzdata/America/Danmarkshavn
@@ -0,0 +1,39 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Danmarkshavn) {
+    {-9223372036854775808 -4480 0 LMT}
+    {-1686091520 -10800 0 WGT}
+    {323845200 -7200 0 WGST}
+    {338950800 -10800 0 WGT}
+    {354675600 -7200 1 WGST}
+    {370400400 -10800 0 WGT}
+    {386125200 -7200 1 WGST}
+    {401850000 -10800 0 WGT}
+    {417574800 -7200 1 WGST}
+    {433299600 -10800 0 WGT}
+    {449024400 -7200 1 WGST}
+    {465354000 -10800 0 WGT}
+    {481078800 -7200 1 WGST}
+    {496803600 -10800 0 WGT}
+    {512528400 -7200 1 WGST}
+    {528253200 -10800 0 WGT}
+    {543978000 -7200 1 WGST}
+    {559702800 -10800 0 WGT}
+    {575427600 -7200 1 WGST}
+    {591152400 -10800 0 WGT}
+    {606877200 -7200 1 WGST}
+    {622602000 -10800 0 WGT}
+    {638326800 -7200 1 WGST}
+    {654656400 -10800 0 WGT}
+    {670381200 -7200 1 WGST}
+    {686106000 -10800 0 WGT}
+    {701830800 -7200 1 WGST}
+    {717555600 -10800 0 WGT}
+    {733280400 -7200 1 WGST}
+    {749005200 -10800 0 WGT}
+    {764730000 -7200 1 WGST}
+    {780454800 -10800 0 WGT}
+    {796179600 -7200 1 WGST}
+    {811904400 -10800 0 WGT}
+    {820465200 0 0 GMT}
+}
diff --git a/library/tzdata/America/Dawson b/library/tzdata/America/Dawson
new file mode 100644
index 0000000..8d2b641
--- /dev/null
+++ b/library/tzdata/America/Dawson
@@ -0,0 +1,256 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Dawson) {
+    {-9223372036854775808 -33460 0 LMT}
+    {-2188996940 -32400 0 YST}
+    {-1632056400 -28800 1 YDT}
+    {-1615125600 -32400 0 YST}
+    {-1596978000 -28800 1 YDT}
+    {-1583164800 -32400 0 YST}
+    {-880203600 -28800 1 YWT}
+    {-769395600 -28800 1 YPT}
+    {-765381600 -32400 0 YST}
+    {-147884400 -25200 1 YDDT}
+    {-131554800 -32400 0 YST}
+    {315561600 -28800 0 PST}
+    {325677600 -25200 1 PDT}
+    {341398800 -28800 0 PST}
+    {357127200 -25200 1 PDT}
+    {372848400 -28800 0 PST}
+    {388576800 -25200 1 PDT}
+    {404902800 -28800 0 PST}
+    {420026400 -25200 1 PDT}
+    {436352400 -28800 0 PST}
+    {452080800 -25200 1 PDT}
+    {467802000 -28800 0 PST}
+    {483530400 -25200 1 PDT}
+    {499251600 -28800 0 PST}
+    {514980000 -25200 1 PDT}
+    {530701200 -28800 0 PST}
+    {544615200 -25200 1 PDT}
+    {562150800 -28800 0 PST}
+    {576064800 -25200 1 PDT}
+    {594205200 -28800 0 PST}
+    {607514400 -25200 1 PDT}
+    {625654800 -28800 0 PST}
+    {638964000 -25200 1 PDT}
+    {657104400 -28800 0 PST}
+    {671018400 -25200 1 PDT}
+    {688554000 -28800 0 PST}
+    {702468000 -25200 1 PDT}
+    {720003600 -28800 0 PST}
+    {733917600 -25200 1 PDT}
+    {752058000 -28800 0 PST}
+    {765367200 -25200 1 PDT}
+    {783507600 -28800 0 PST}
+    {796816800 -25200 1 PDT}
+    {814957200 -28800 0 PST}
+    {828871200 -25200 1 PDT}
+    {846406800 -28800 0 PST}
+    {860320800 -25200 1 PDT}
+    {877856400 -28800 0 PST}
+    {891770400 -25200 1 PDT}
+    {909306000 -28800 0 PST}
+    {923220000 -25200 1 PDT}
+    {941360400 -28800 0 PST}
+    {954669600 -25200 1 PDT}
+    {972810000 -28800 0 PST}
+    {986119200 -25200 1 PDT}
+    {1004259600 -28800 0 PST}
+    {1018173600 -25200 1 PDT}
+    {1035709200 -28800 0 PST}
+    {1049623200 -25200 1 PDT}
+    {1067158800 -28800 0 PST}
+    {1081072800 -25200 1 PDT}
+    {1099213200 -28800 0 PST}
+    {1112522400 -25200 1 PDT}
+    {1130662800 -28800 0 PST}
+    {1143972000 -25200 1 PDT}
+    {1162112400 -28800 0 PST}
+    {1173607200 -25200 1 PDT}
+    {1194166800 -28800 0 PST}
+    {1205056800 -25200 1 PDT}
+    {1225616400 -28800 0 PST}
+    {1236506400 -25200 1 PDT}
+    {1257066000 -28800 0 PST}
+    {1268560800 -25200 1 PDT}
+    {1289120400 -28800 0 PST}
+    {1300010400 -25200 1 PDT}
+    {1320570000 -28800 0 PST}
+    {1331460000 -25200 1 PDT}
+    {1352019600 -28800 0 PST}
+    {1362909600 -25200 1 PDT}
+    {1383469200 -28800 0 PST}
+    {1394359200 -25200 1 PDT}
+    {1414918800 -28800 0 PST}
+    {1425808800 -25200 1 PDT}
+    {1446368400 -28800 0 PST}
+    {1457863200 -25200 1 PDT}
+    {1478422800 -28800 0 PST}
+    {1489312800 -25200 1 PDT}
+    {1509872400 -28800 0 PST}
+    {1520762400 -25200 1 PDT}
+    {1541322000 -28800 0 PST}
+    {1552212000 -25200 1 PDT}
+    {1572771600 -28800 0 PST}
+    {1583661600 -25200 1 PDT}
+    {1604221200 -28800 0 PST}
+    {1615716000 -25200 1 PDT}
+    {1636275600 -28800 0 PST}
+    {1647165600 -25200 1 PDT}
+    {1667725200 -28800 0 PST}
+    {1678615200 -25200 1 PDT}
+    {1699174800 -28800 0 PST}
+    {1710064800 -25200 1 PDT}
+    {1730624400 -28800 0 PST}
+    {1741514400 -25200 1 PDT}
+    {1762074000 -28800 0 PST}
+    {1772964000 -25200 1 PDT}
+    {1793523600 -28800 0 PST}
+    {1805018400 -25200 1 PDT}
+    {1825578000 -28800 0 PST}
+    {1836468000 -25200 1 PDT}
+    {1857027600 -28800 0 PST}
+    {1867917600 -25200 1 PDT}
+    {1888477200 -28800 0 PST}
+    {1899367200 -25200 1 PDT}
+    {1919926800 -28800 0 PST}
+    {1930816800 -25200 1 PDT}
+    {1951376400 -28800 0 PST}
+    {1962871200 -25200 1 PDT}
+    {1983430800 -28800 0 PST}
+    {1994320800 -25200 1 PDT}
+    {2014880400 -28800 0 PST}
+    {2025770400 -25200 1 PDT}
+    {2046330000 -28800 0 PST}
+    {2057220000 -25200 1 PDT}
+    {2077779600 -28800 0 PST}
+    {2088669600 -25200 1 PDT}
+    {2109229200 -28800 0 PST}
+    {2120119200 -25200 1 PDT}
+    {2140678800 -28800 0 PST}
+    {2152173600 -25200 1 PDT}
+    {2172733200 -28800 0 PST}
+    {2183623200 -25200 1 PDT}
+    {2204182800 -28800 0 PST}
+    {2215072800 -25200 1 PDT}
+    {2235632400 -28800 0 PST}
+    {2246522400 -25200 1 PDT}
+    {2267082000 -28800 0 PST}
+    {2277972000 -25200 1 PDT}
+    {2298531600 -28800 0 PST}
+    {2309421600 -25200 1 PDT}
+    {2329981200 -28800 0 PST}
+    {2341476000 -25200 1 PDT}
+    {2362035600 -28800 0 PST}
+    {2372925600 -25200 1 PDT}
+    {2393485200 -28800 0 PST}
+    {2404375200 -25200 1 PDT}
+    {2424934800 -28800 0 PST}
+    {2435824800 -25200 1 PDT}
+    {2456384400 -28800 0 PST}
+    {2467274400 -25200 1 PDT}
+    {2487834000 -28800 0 PST}
+    {2499328800 -25200 1 PDT}
+    {2519888400 -28800 0 PST}
+    {2530778400 -25200 1 PDT}
+    {2551338000 -28800 0 PST}
+    {2562228000 -25200 1 PDT}
+    {2582787600 -28800 0 PST}
+    {2593677600 -25200 1 PDT}
+    {2614237200 -28800 0 PST}
+    {2625127200 -25200 1 PDT}
+    {2645686800 -28800 0 PST}
+    {2656576800 -25200 1 PDT}
+    {2677136400 -28800 0 PST}
+    {2688631200 -25200 1 PDT}
+    {2709190800 -28800 0 PST}
+    {2720080800 -25200 1 PDT}
+    {2740640400 -28800 0 PST}
+    {2751530400 -25200 1 PDT}
+    {2772090000 -28800 0 PST}
+    {2782980000 -25200 1 PDT}
+    {2803539600 -28800 0 PST}
+    {2814429600 -25200 1 PDT}
+    {2834989200 -28800 0 PST}
+    {2846484000 -25200 1 PDT}
+    {2867043600 -28800 0 PST}
+    {2877933600 -25200 1 PDT}
+    {2898493200 -28800 0 PST}
+    {2909383200 -25200 1 PDT}
+    {2929942800 -28800 0 PST}
+    {2940832800 -25200 1 PDT}
+    {2961392400 -28800 0 PST}
+    {2972282400 -25200 1 PDT}
+    {2992842000 -28800 0 PST}
+    {3003732000 -25200 1 PDT}
+    {3024291600 -28800 0 PST}
+    {3035786400 -25200 1 PDT}
+    {3056346000 -28800 0 PST}
+    {3067236000 -25200 1 PDT}
+    {3087795600 -28800 0 PST}
+    {3098685600 -25200 1 PDT}
+    {3119245200 -28800 0 PST}
+    {3130135200 -25200 1 PDT}
+    {3150694800 -28800 0 PST}
+    {3161584800 -25200 1 PDT}
+    {3182144400 -28800 0 PST}
+    {3193034400 -25200 1 PDT}
+    {3213594000 -28800 0 PST}
+    {3225088800 -25200 1 PDT}
+    {3245648400 -28800 0 PST}
+    {3256538400 -25200 1 PDT}
+    {3277098000 -28800 0 PST}
+    {3287988000 -25200 1 PDT}
+    {3308547600 -28800 0 PST}
+    {3319437600 -25200 1 PDT}
+    {3339997200 -28800 0 PST}
+    {3350887200 -25200 1 PDT}
+    {3371446800 -28800 0 PST}
+    {3382941600 -25200 1 PDT}
+    {3403501200 -28800 0 PST}
+    {3414391200 -25200 1 PDT}
+    {3434950800 -28800 0 PST}
+    {3445840800 -25200 1 PDT}
+    {3466400400 -28800 0 PST}
+    {3477290400 -25200 1 PDT}
+    {3497850000 -28800 0 PST}
+    {3508740000 -25200 1 PDT}
+    {3529299600 -28800 0 PST}
+    {3540189600 -25200 1 PDT}
+    {3560749200 -28800 0 PST}
+    {3572244000 -25200 1 PDT}
+    {3592803600 -28800 0 PST}
+    {3603693600 -25200 1 PDT}
+    {3624253200 -28800 0 PST}
+    {3635143200 -25200 1 PDT}
+    {3655702800 -28800 0 PST}
+    {3666592800 -25200 1 PDT}
+    {3687152400 -28800 0 PST}
+    {3698042400 -25200 1 PDT}
+    {3718602000 -28800 0 PST}
+    {3730096800 -25200 1 PDT}
+    {3750656400 -28800 0 PST}
+    {3761546400 -25200 1 PDT}
+    {3782106000 -28800 0 PST}
+    {3792996000 -25200 1 PDT}
+    {3813555600 -28800 0 PST}
+    {3824445600 -25200 1 PDT}
+    {3845005200 -28800 0 PST}
+    {3855895200 -25200 1 PDT}
+    {3876454800 -28800 0 PST}
+    {3887344800 -25200 1 PDT}
+    {3907904400 -28800 0 PST}
+    {3919399200 -25200 1 PDT}
+    {3939958800 -28800 0 PST}
+    {3950848800 -25200 1 PDT}
+    {3971408400 -28800 0 PST}
+    {3982298400 -25200 1 PDT}
+    {4002858000 -28800 0 PST}
+    {4013748000 -25200 1 PDT}
+    {4034307600 -28800 0 PST}
+    {4045197600 -25200 1 PDT}
+    {4065757200 -28800 0 PST}
+    {4076647200 -25200 1 PDT}
+    {4097206800 -28800 0 PST}
+}
diff --git a/library/tzdata/America/Dawson_Creek b/library/tzdata/America/Dawson_Creek
new file mode 100644
index 0000000..a0b5c44
--- /dev/null
+++ b/library/tzdata/America/Dawson_Creek
@@ -0,0 +1,64 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Dawson_Creek) {
+    {-9223372036854775808 -28856 0 LMT}
+    {-2713881544 -28800 0 PST}
+    {-1632060000 -25200 1 PDT}
+    {-1615129200 -28800 0 PST}
+    {-880207200 -25200 1 PWT}
+    {-769395600 -25200 1 PPT}
+    {-765385200 -28800 0 PST}
+    {-725817600 -28800 0 PST}
+    {-715788000 -25200 1 PDT}
+    {-702486000 -28800 0 PST}
+    {-684338400 -25200 1 PDT}
+    {-671036400 -28800 0 PST}
+    {-652888800 -25200 1 PDT}
+    {-639586800 -28800 0 PST}
+    {-620834400 -25200 1 PDT}
+    {-608137200 -28800 0 PST}
+    {-589384800 -25200 1 PDT}
+    {-576082800 -28800 0 PST}
+    {-557935200 -25200 1 PDT}
+    {-544633200 -28800 0 PST}
+    {-526485600 -25200 1 PDT}
+    {-513183600 -28800 0 PST}
+    {-495036000 -25200 1 PDT}
+    {-481734000 -28800 0 PST}
+    {-463586400 -25200 1 PDT}
+    {-450284400 -28800 0 PST}
+    {-431532000 -25200 1 PDT}
+    {-418230000 -28800 0 PST}
+    {-400082400 -25200 1 PDT}
+    {-386780400 -28800 0 PST}
+    {-368632800 -25200 1 PDT}
+    {-355330800 -28800 0 PST}
+    {-337183200 -25200 1 PDT}
+    {-323881200 -28800 0 PST}
+    {-305733600 -25200 1 PDT}
+    {-292431600 -28800 0 PST}
+    {-273679200 -25200 1 PDT}
+    {-260982000 -28800 0 PST}
+    {-242229600 -25200 1 PDT}
+    {-226508400 -28800 0 PST}
+    {-210780000 -25200 1 PDT}
+    {-195058800 -28800 0 PST}
+    {-179330400 -25200 1 PDT}
+    {-163609200 -28800 0 PST}
+    {-147880800 -25200 1 PDT}
+    {-131554800 -28800 0 PST}
+    {-116431200 -25200 1 PDT}
+    {-100105200 -28800 0 PST}
+    {-84376800 -25200 1 PDT}
+    {-68655600 -28800 0 PST}
+    {-52927200 -25200 1 PDT}
+    {-37206000 -28800 0 PST}
+    {-21477600 -25200 1 PDT}
+    {-5756400 -28800 0 PST}
+    {9972000 -25200 1 PDT}
+    {25693200 -28800 0 PST}
+    {41421600 -25200 1 PDT}
+    {57747600 -28800 0 PST}
+    {73476000 -25200 1 PDT}
+    {84016800 -25200 0 MST}
+}
diff --git a/library/tzdata/America/Denver b/library/tzdata/America/Denver
new file mode 100644
index 0000000..06bc80d
--- /dev/null
+++ b/library/tzdata/America/Denver
@@ -0,0 +1,291 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Denver) {
+    {-9223372036854775808 -25196 0 LMT}
+    {-2717643600 -25200 0 MST}
+    {-1633273200 -21600 1 MDT}
+    {-1615132800 -25200 0 MST}
+    {-1601823600 -21600 1 MDT}
+    {-1583683200 -25200 0 MST}
+    {-1577898000 -25200 0 MST}
+    {-1570374000 -21600 1 MDT}
+    {-1551628800 -25200 0 MST}
+    {-1538924400 -21600 1 MDT}
+    {-1534089600 -25200 0 MST}
+    {-883587600 -25200 0 MST}
+    {-880210800 -21600 1 MWT}
+    {-769395600 -21600 1 MPT}
+    {-765388800 -25200 0 MST}
+    {-757357200 -25200 0 MST}
+    {-147884400 -21600 1 MDT}
+    {-131558400 -25200 0 MST}
+    {-116434800 -21600 1 MDT}
+    {-100108800 -25200 0 MST}
+    {-94669200 -25200 0 MST}
+    {-84380400 -21600 1 MDT}
+    {-68659200 -25200 0 MST}
+    {-52930800 -21600 1 MDT}
+    {-37209600 -25200 0 MST}
+    {-21481200 -21600 1 MDT}
+    {-5760000 -25200 0 MST}
+    {9968400 -21600 1 MDT}
+    {25689600 -25200 0 MST}
+    {41418000 -21600 1 MDT}
+    {57744000 -25200 0 MST}
+    {73472400 -21600 1 MDT}
+    {89193600 -25200 0 MST}
+    {104922000 -21600 1 MDT}
+    {120643200 -25200 0 MST}
+    {126694800 -21600 1 MDT}
+    {152092800 -25200 0 MST}
+    {162378000 -21600 1 MDT}
+    {183542400 -25200 0 MST}
+    {199270800 -21600 1 MDT}
+    {215596800 -25200 0 MST}
+    {230720400 -21600 1 MDT}
+    {247046400 -25200 0 MST}
+    {262774800 -21600 1 MDT}
+    {278496000 -25200 0 MST}
+    {294224400 -21600 1 MDT}
+    {309945600 -25200 0 MST}
+    {325674000 -21600 1 MDT}
+    {341395200 -25200 0 MST}
+    {357123600 -21600 1 MDT}
+    {372844800 -25200 0 MST}
+    {388573200 -21600 1 MDT}
+    {404899200 -25200 0 MST}
+    {420022800 -21600 1 MDT}
+    {436348800 -25200 0 MST}
+    {452077200 -21600 1 MDT}
+    {467798400 -25200 0 MST}
+    {483526800 -21600 1 MDT}
+    {499248000 -25200 0 MST}
+    {514976400 -21600 1 MDT}
+    {530697600 -25200 0 MST}
+    {544611600 -21600 1 MDT}
+    {562147200 -25200 0 MST}
+    {576061200 -21600 1 MDT}
+    {594201600 -25200 0 MST}
+    {607510800 -21600 1 MDT}
+    {625651200 -25200 0 MST}
+    {638960400 -21600 1 MDT}
+    {657100800 -25200 0 MST}
+    {671014800 -21600 1 MDT}
+    {688550400 -25200 0 MST}
+    {702464400 -21600 1 MDT}
+    {720000000 -25200 0 MST}
+    {733914000 -21600 1 MDT}
+    {752054400 -25200 0 MST}
+    {765363600 -21600 1 MDT}
+    {783504000 -25200 0 MST}
+    {796813200 -21600 1 MDT}
+    {814953600 -25200 0 MST}
+    {828867600 -21600 1 MDT}
+    {846403200 -25200 0 MST}
+    {860317200 -21600 1 MDT}
+    {877852800 -25200 0 MST}
+    {891766800 -21600 1 MDT}
+    {909302400 -25200 0 MST}
+    {923216400 -21600 1 MDT}
+    {941356800 -25200 0 MST}
+    {954666000 -21600 1 MDT}
+    {972806400 -25200 0 MST}
+    {986115600 -21600 1 MDT}
+    {1004256000 -25200 0 MST}
+    {1018170000 -21600 1 MDT}
+    {1035705600 -25200 0 MST}
+    {1049619600 -21600 1 MDT}
+    {1067155200 -25200 0 MST}
+    {1081069200 -21600 1 MDT}
+    {1099209600 -25200 0 MST}
+    {1112518800 -21600 1 MDT}
+    {1130659200 -25200 0 MST}
+    {1143968400 -21600 1 MDT}
+    {1162108800 -25200 0 MST}
+    {1173603600 -21600 1 MDT}
+    {1194163200 -25200 0 MST}
+    {1205053200 -21600 1 MDT}
+    {1225612800 -25200 0 MST}
+    {1236502800 -21600 1 MDT}
+    {1257062400 -25200 0 MST}
+    {1268557200 -21600 1 MDT}
+    {1289116800 -25200 0 MST}
+    {1300006800 -21600 1 MDT}
+    {1320566400 -25200 0 MST}
+    {1331456400 -21600 1 MDT}
+    {1352016000 -25200 0 MST}
+    {1362906000 -21600 1 MDT}
+    {1383465600 -25200 0 MST}
+    {1394355600 -21600 1 MDT}
+    {1414915200 -25200 0 MST}
+    {1425805200 -21600 1 MDT}
+    {1446364800 -25200 0 MST}
+    {1457859600 -21600 1 MDT}
+    {1478419200 -25200 0 MST}
+    {1489309200 -21600 1 MDT}
+    {1509868800 -25200 0 MST}
+    {1520758800 -21600 1 MDT}
+    {1541318400 -25200 0 MST}
+    {1552208400 -21600 1 MDT}
+    {1572768000 -25200 0 MST}
+    {1583658000 -21600 1 MDT}
+    {1604217600 -25200 0 MST}
+    {1615712400 -21600 1 MDT}
+    {1636272000 -25200 0 MST}
+    {1647162000 -21600 1 MDT}
+    {1667721600 -25200 0 MST}
+    {1678611600 -21600 1 MDT}
+    {1699171200 -25200 0 MST}
+    {1710061200 -21600 1 MDT}
+    {1730620800 -25200 0 MST}
+    {1741510800 -21600 1 MDT}
+    {1762070400 -25200 0 MST}
+    {1772960400 -21600 1 MDT}
+    {1793520000 -25200 0 MST}
+    {1805014800 -21600 1 MDT}
+    {1825574400 -25200 0 MST}
+    {1836464400 -21600 1 MDT}
+    {1857024000 -25200 0 MST}
+    {1867914000 -21600 1 MDT}
+    {1888473600 -25200 0 MST}
+    {1899363600 -21600 1 MDT}
+    {1919923200 -25200 0 MST}
+    {1930813200 -21600 1 MDT}
+    {1951372800 -25200 0 MST}
+    {1962867600 -21600 1 MDT}
+    {1983427200 -25200 0 MST}
+    {1994317200 -21600 1 MDT}
+    {2014876800 -25200 0 MST}
+    {2025766800 -21600 1 MDT}
+    {2046326400 -25200 0 MST}
+    {2057216400 -21600 1 MDT}
+    {2077776000 -25200 0 MST}
+    {2088666000 -21600 1 MDT}
+    {2109225600 -25200 0 MST}
+    {2120115600 -21600 1 MDT}
+    {2140675200 -25200 0 MST}
+    {2152170000 -21600 1 MDT}
+    {2172729600 -25200 0 MST}
+    {2183619600 -21600 1 MDT}
+    {2204179200 -25200 0 MST}
+    {2215069200 -21600 1 MDT}
+    {2235628800 -25200 0 MST}
+    {2246518800 -21600 1 MDT}
+    {2267078400 -25200 0 MST}
+    {2277968400 -21600 1 MDT}
+    {2298528000 -25200 0 MST}
+    {2309418000 -21600 1 MDT}
+    {2329977600 -25200 0 MST}
+    {2341472400 -21600 1 MDT}
+    {2362032000 -25200 0 MST}
+    {2372922000 -21600 1 MDT}
+    {2393481600 -25200 0 MST}
+    {2404371600 -21600 1 MDT}
+    {2424931200 -25200 0 MST}
+    {2435821200 -21600 1 MDT}
+    {2456380800 -25200 0 MST}
+    {2467270800 -21600 1 MDT}
+    {2487830400 -25200 0 MST}
+    {2499325200 -21600 1 MDT}
+    {2519884800 -25200 0 MST}
+    {2530774800 -21600 1 MDT}
+    {2551334400 -25200 0 MST}
+    {2562224400 -21600 1 MDT}
+    {2582784000 -25200 0 MST}
+    {2593674000 -21600 1 MDT}
+    {2614233600 -25200 0 MST}
+    {2625123600 -21600 1 MDT}
+    {2645683200 -25200 0 MST}
+    {2656573200 -21600 1 MDT}
+    {2677132800 -25200 0 MST}
+    {2688627600 -21600 1 MDT}
+    {2709187200 -25200 0 MST}
+    {2720077200 -21600 1 MDT}
+    {2740636800 -25200 0 MST}
+    {2751526800 -21600 1 MDT}
+    {2772086400 -25200 0 MST}
+    {2782976400 -21600 1 MDT}
+    {2803536000 -25200 0 MST}
+    {2814426000 -21600 1 MDT}
+    {2834985600 -25200 0 MST}
+    {2846480400 -21600 1 MDT}
+    {2867040000 -25200 0 MST}
+    {2877930000 -21600 1 MDT}
+    {2898489600 -25200 0 MST}
+    {2909379600 -21600 1 MDT}
+    {2929939200 -25200 0 MST}
+    {2940829200 -21600 1 MDT}
+    {2961388800 -25200 0 MST}
+    {2972278800 -21600 1 MDT}
+    {2992838400 -25200 0 MST}
+    {3003728400 -21600 1 MDT}
+    {3024288000 -25200 0 MST}
+    {3035782800 -21600 1 MDT}
+    {3056342400 -25200 0 MST}
+    {3067232400 -21600 1 MDT}
+    {3087792000 -25200 0 MST}
+    {3098682000 -21600 1 MDT}
+    {3119241600 -25200 0 MST}
+    {3130131600 -21600 1 MDT}
+    {3150691200 -25200 0 MST}
+    {3161581200 -21600 1 MDT}
+    {3182140800 -25200 0 MST}
+    {3193030800 -21600 1 MDT}
+    {3213590400 -25200 0 MST}
+    {3225085200 -21600 1 MDT}
+    {3245644800 -25200 0 MST}
+    {3256534800 -21600 1 MDT}
+    {3277094400 -25200 0 MST}
+    {3287984400 -21600 1 MDT}
+    {3308544000 -25200 0 MST}
+    {3319434000 -21600 1 MDT}
+    {3339993600 -25200 0 MST}
+    {3350883600 -21600 1 MDT}
+    {3371443200 -25200 0 MST}
+    {3382938000 -21600 1 MDT}
+    {3403497600 -25200 0 MST}
+    {3414387600 -21600 1 MDT}
+    {3434947200 -25200 0 MST}
+    {3445837200 -21600 1 MDT}
+    {3466396800 -25200 0 MST}
+    {3477286800 -21600 1 MDT}
+    {3497846400 -25200 0 MST}
+    {3508736400 -21600 1 MDT}
+    {3529296000 -25200 0 MST}
+    {3540186000 -21600 1 MDT}
+    {3560745600 -25200 0 MST}
+    {3572240400 -21600 1 MDT}
+    {3592800000 -25200 0 MST}
+    {3603690000 -21600 1 MDT}
+    {3624249600 -25200 0 MST}
+    {3635139600 -21600 1 MDT}
+    {3655699200 -25200 0 MST}
+    {3666589200 -21600 1 MDT}
+    {3687148800 -25200 0 MST}
+    {3698038800 -21600 1 MDT}
+    {3718598400 -25200 0 MST}
+    {3730093200 -21600 1 MDT}
+    {3750652800 -25200 0 MST}
+    {3761542800 -21600 1 MDT}
+    {3782102400 -25200 0 MST}
+    {3792992400 -21600 1 MDT}
+    {3813552000 -25200 0 MST}
+    {3824442000 -21600 1 MDT}
+    {3845001600 -25200 0 MST}
+    {3855891600 -21600 1 MDT}
+    {3876451200 -25200 0 MST}
+    {3887341200 -21600 1 MDT}
+    {3907900800 -25200 0 MST}
+    {3919395600 -21600 1 MDT}
+    {3939955200 -25200 0 MST}
+    {3950845200 -21600 1 MDT}
+    {3971404800 -25200 0 MST}
+    {3982294800 -21600 1 MDT}
+    {4002854400 -25200 0 MST}
+    {4013744400 -21600 1 MDT}
+    {4034304000 -25200 0 MST}
+    {4045194000 -21600 1 MDT}
+    {4065753600 -25200 0 MST}
+    {4076643600 -21600 1 MDT}
+    {4097203200 -25200 0 MST}
+}
diff --git a/library/tzdata/America/Detroit b/library/tzdata/America/Detroit
new file mode 100644
index 0000000..696a663
--- /dev/null
+++ b/library/tzdata/America/Detroit
@@ -0,0 +1,272 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Detroit) {
+    {-9223372036854775808 -19931 0 LMT}
+    {-2051202469 -21600 0 CST}
+    {-1724083200 -18000 0 EST}
+    {-883594800 -18000 0 EST}
+    {-880218000 -14400 1 EWT}
+    {-769395600 -14400 1 EPT}
+    {-765396000 -18000 0 EST}
+    {-757364400 -18000 0 EST}
+    {-684349200 -14400 1 EDT}
+    {-671047200 -18000 0 EST}
+    {-80499600 -14400 1 EDT}
+    {-68666400 -18000 0 EST}
+    {94712400 -18000 0 EST}
+    {104914800 -14400 1 EDT}
+    {120636000 -18000 0 EST}
+    {126687600 -14400 1 EDT}
+    {152085600 -18000 0 EST}
+    {157784400 -18000 0 EST}
+    {167814000 -14400 0 EDT}
+    {183535200 -18000 0 EST}
+    {199263600 -14400 1 EDT}
+    {215589600 -18000 0 EST}
+    {230713200 -14400 1 EDT}
+    {247039200 -18000 0 EST}
+    {262767600 -14400 1 EDT}
+    {278488800 -18000 0 EST}
+    {294217200 -14400 1 EDT}
+    {309938400 -18000 0 EST}
+    {325666800 -14400 1 EDT}
+    {341388000 -18000 0 EST}
+    {357116400 -14400 1 EDT}
+    {372837600 -18000 0 EST}
+    {388566000 -14400 1 EDT}
+    {404892000 -18000 0 EST}
+    {420015600 -14400 1 EDT}
+    {436341600 -18000 0 EST}
+    {452070000 -14400 1 EDT}
+    {467791200 -18000 0 EST}
+    {483519600 -14400 1 EDT}
+    {499240800 -18000 0 EST}
+    {514969200 -14400 1 EDT}
+    {530690400 -18000 0 EST}
+    {544604400 -14400 1 EDT}
+    {562140000 -18000 0 EST}
+    {576054000 -14400 1 EDT}
+    {594194400 -18000 0 EST}
+    {607503600 -14400 1 EDT}
+    {625644000 -18000 0 EST}
+    {638953200 -14400 1 EDT}
+    {657093600 -18000 0 EST}
+    {671007600 -14400 1 EDT}
+    {688543200 -18000 0 EST}
+    {702457200 -14400 1 EDT}
+    {719992800 -18000 0 EST}
+    {733906800 -14400 1 EDT}
+    {752047200 -18000 0 EST}
+    {765356400 -14400 1 EDT}
+    {783496800 -18000 0 EST}
+    {796806000 -14400 1 EDT}
+    {814946400 -18000 0 EST}
+    {828860400 -14400 1 EDT}
+    {846396000 -18000 0 EST}
+    {860310000 -14400 1 EDT}
+    {877845600 -18000 0 EST}
+    {891759600 -14400 1 EDT}
+    {909295200 -18000 0 EST}
+    {923209200 -14400 1 EDT}
+    {941349600 -18000 0 EST}
+    {954658800 -14400 1 EDT}
+    {972799200 -18000 0 EST}
+    {986108400 -14400 1 EDT}
+    {1004248800 -18000 0 EST}
+    {1018162800 -14400 1 EDT}
+    {1035698400 -18000 0 EST}
+    {1049612400 -14400 1 EDT}
+    {1067148000 -18000 0 EST}
+    {1081062000 -14400 1 EDT}
+    {1099202400 -18000 0 EST}
+    {1112511600 -14400 1 EDT}
+    {1130652000 -18000 0 EST}
+    {1143961200 -14400 1 EDT}
+    {1162101600 -18000 0 EST}
+    {1173596400 -14400 1 EDT}
+    {1194156000 -18000 0 EST}
+    {1205046000 -14400 1 EDT}
+    {1225605600 -18000 0 EST}
+    {1236495600 -14400 1 EDT}
+    {1257055200 -18000 0 EST}
+    {1268550000 -14400 1 EDT}
+    {1289109600 -18000 0 EST}
+    {1299999600 -14400 1 EDT}
+    {1320559200 -18000 0 EST}
+    {1331449200 -14400 1 EDT}
+    {1352008800 -18000 0 EST}
+    {1362898800 -14400 1 EDT}
+    {1383458400 -18000 0 EST}
+    {1394348400 -14400 1 EDT}
+    {1414908000 -18000 0 EST}
+    {1425798000 -14400 1 EDT}
+    {1446357600 -18000 0 EST}
+    {1457852400 -14400 1 EDT}
+    {1478412000 -18000 0 EST}
+    {1489302000 -14400 1 EDT}
+    {1509861600 -18000 0 EST}
+    {1520751600 -14400 1 EDT}
+    {1541311200 -18000 0 EST}
+    {1552201200 -14400 1 EDT}
+    {1572760800 -18000 0 EST}
+    {1583650800 -14400 1 EDT}
+    {1604210400 -18000 0 EST}
+    {1615705200 -14400 1 EDT}
+    {1636264800 -18000 0 EST}
+    {1647154800 -14400 1 EDT}
+    {1667714400 -18000 0 EST}
+    {1678604400 -14400 1 EDT}
+    {1699164000 -18000 0 EST}
+    {1710054000 -14400 1 EDT}
+    {1730613600 -18000 0 EST}
+    {1741503600 -14400 1 EDT}
+    {1762063200 -18000 0 EST}
+    {1772953200 -14400 1 EDT}
+    {1793512800 -18000 0 EST}
+    {1805007600 -14400 1 EDT}
+    {1825567200 -18000 0 EST}
+    {1836457200 -14400 1 EDT}
+    {1857016800 -18000 0 EST}
+    {1867906800 -14400 1 EDT}
+    {1888466400 -18000 0 EST}
+    {1899356400 -14400 1 EDT}
+    {1919916000 -18000 0 EST}
+    {1930806000 -14400 1 EDT}
+    {1951365600 -18000 0 EST}
+    {1962860400 -14400 1 EDT}
+    {1983420000 -18000 0 EST}
+    {1994310000 -14400 1 EDT}
+    {2014869600 -18000 0 EST}
+    {2025759600 -14400 1 EDT}
+    {2046319200 -18000 0 EST}
+    {2057209200 -14400 1 EDT}
+    {2077768800 -18000 0 EST}
+    {2088658800 -14400 1 EDT}
+    {2109218400 -18000 0 EST}
+    {2120108400 -14400 1 EDT}
+    {2140668000 -18000 0 EST}
+    {2152162800 -14400 1 EDT}
+    {2172722400 -18000 0 EST}
+    {2183612400 -14400 1 EDT}
+    {2204172000 -18000 0 EST}
+    {2215062000 -14400 1 EDT}
+    {2235621600 -18000 0 EST}
+    {2246511600 -14400 1 EDT}
+    {2267071200 -18000 0 EST}
+    {2277961200 -14400 1 EDT}
+    {2298520800 -18000 0 EST}
+    {2309410800 -14400 1 EDT}
+    {2329970400 -18000 0 EST}
+    {2341465200 -14400 1 EDT}
+    {2362024800 -18000 0 EST}
+    {2372914800 -14400 1 EDT}
+    {2393474400 -18000 0 EST}
+    {2404364400 -14400 1 EDT}
+    {2424924000 -18000 0 EST}
+    {2435814000 -14400 1 EDT}
+    {2456373600 -18000 0 EST}
+    {2467263600 -14400 1 EDT}
+    {2487823200 -18000 0 EST}
+    {2499318000 -14400 1 EDT}
+    {2519877600 -18000 0 EST}
+    {2530767600 -14400 1 EDT}
+    {2551327200 -18000 0 EST}
+    {2562217200 -14400 1 EDT}
+    {2582776800 -18000 0 EST}
+    {2593666800 -14400 1 EDT}
+    {2614226400 -18000 0 EST}
+    {2625116400 -14400 1 EDT}
+    {2645676000 -18000 0 EST}
+    {2656566000 -14400 1 EDT}
+    {2677125600 -18000 0 EST}
+    {2688620400 -14400 1 EDT}
+    {2709180000 -18000 0 EST}
+    {2720070000 -14400 1 EDT}
+    {2740629600 -18000 0 EST}
+    {2751519600 -14400 1 EDT}
+    {2772079200 -18000 0 EST}
+    {2782969200 -14400 1 EDT}
+    {2803528800 -18000 0 EST}
+    {2814418800 -14400 1 EDT}
+    {2834978400 -18000 0 EST}
+    {2846473200 -14400 1 EDT}
+    {2867032800 -18000 0 EST}
+    {2877922800 -14400 1 EDT}
+    {2898482400 -18000 0 EST}
+    {2909372400 -14400 1 EDT}
+    {2929932000 -18000 0 EST}
+    {2940822000 -14400 1 EDT}
+    {2961381600 -18000 0 EST}
+    {2972271600 -14400 1 EDT}
+    {2992831200 -18000 0 EST}
+    {3003721200 -14400 1 EDT}
+    {3024280800 -18000 0 EST}
+    {3035775600 -14400 1 EDT}
+    {3056335200 -18000 0 EST}
+    {3067225200 -14400 1 EDT}
+    {3087784800 -18000 0 EST}
+    {3098674800 -14400 1 EDT}
+    {3119234400 -18000 0 EST}
+    {3130124400 -14400 1 EDT}
+    {3150684000 -18000 0 EST}
+    {3161574000 -14400 1 EDT}
+    {3182133600 -18000 0 EST}
+    {3193023600 -14400 1 EDT}
+    {3213583200 -18000 0 EST}
+    {3225078000 -14400 1 EDT}
+    {3245637600 -18000 0 EST}
+    {3256527600 -14400 1 EDT}
+    {3277087200 -18000 0 EST}
+    {3287977200 -14400 1 EDT}
+    {3308536800 -18000 0 EST}
+    {3319426800 -14400 1 EDT}
+    {3339986400 -18000 0 EST}
+    {3350876400 -14400 1 EDT}
+    {3371436000 -18000 0 EST}
+    {3382930800 -14400 1 EDT}
+    {3403490400 -18000 0 EST}
+    {3414380400 -14400 1 EDT}
+    {3434940000 -18000 0 EST}
+    {3445830000 -14400 1 EDT}
+    {3466389600 -18000 0 EST}
+    {3477279600 -14400 1 EDT}
+    {3497839200 -18000 0 EST}
+    {3508729200 -14400 1 EDT}
+    {3529288800 -18000 0 EST}
+    {3540178800 -14400 1 EDT}
+    {3560738400 -18000 0 EST}
+    {3572233200 -14400 1 EDT}
+    {3592792800 -18000 0 EST}
+    {3603682800 -14400 1 EDT}
+    {3624242400 -18000 0 EST}
+    {3635132400 -14400 1 EDT}
+    {3655692000 -18000 0 EST}
+    {3666582000 -14400 1 EDT}
+    {3687141600 -18000 0 EST}
+    {3698031600 -14400 1 EDT}
+    {3718591200 -18000 0 EST}
+    {3730086000 -14400 1 EDT}
+    {3750645600 -18000 0 EST}
+    {3761535600 -14400 1 EDT}
+    {3782095200 -18000 0 EST}
+    {3792985200 -14400 1 EDT}
+    {3813544800 -18000 0 EST}
+    {3824434800 -14400 1 EDT}
+    {3844994400 -18000 0 EST}
+    {3855884400 -14400 1 EDT}
+    {3876444000 -18000 0 EST}
+    {3887334000 -14400 1 EDT}
+    {3907893600 -18000 0 EST}
+    {3919388400 -14400 1 EDT}
+    {3939948000 -18000 0 EST}
+    {3950838000 -14400 1 EDT}
+    {3971397600 -18000 0 EST}
+    {3982287600 -14400 1 EDT}
+    {4002847200 -18000 0 EST}
+    {4013737200 -14400 1 EDT}
+    {4034296800 -18000 0 EST}
+    {4045186800 -14400 1 EDT}
+    {4065746400 -18000 0 EST}
+    {4076636400 -14400 1 EDT}
+    {4097196000 -18000 0 EST}
+}
diff --git a/library/tzdata/America/Dominica b/library/tzdata/America/Dominica
new file mode 100644
index 0000000..b97cb0e
--- /dev/null
+++ b/library/tzdata/America/Dominica
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(America/Port_of_Spain)]} {
+    LoadTimeZoneFile America/Port_of_Spain
+}
+set TZData(:America/Dominica) $TZData(:America/Port_of_Spain)
diff --git a/library/tzdata/America/Edmonton b/library/tzdata/America/Edmonton
new file mode 100644
index 0000000..1ed38be
--- /dev/null
+++ b/library/tzdata/America/Edmonton
@@ -0,0 +1,284 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Edmonton) {
+    {-9223372036854775808 -27232 0 LMT}
+    {-1998663968 -25200 0 MST}
+    {-1632063600 -21600 1 MDT}
+    {-1615132800 -25200 0 MST}
+    {-1600614000 -21600 1 MDT}
+    {-1596816000 -25200 0 MST}
+    {-1567954800 -21600 1 MDT}
+    {-1551628800 -25200 0 MST}
+    {-1536505200 -21600 1 MDT}
+    {-1523203200 -25200 0 MST}
+    {-1504450800 -21600 1 MDT}
+    {-1491753600 -25200 0 MST}
+    {-1473001200 -21600 1 MDT}
+    {-1459699200 -25200 0 MST}
+    {-880210800 -21600 1 MWT}
+    {-769395600 -21600 1 MPT}
+    {-765388800 -25200 0 MST}
+    {-715791600 -21600 1 MDT}
+    {-702489600 -25200 0 MST}
+    {-84380400 -21600 1 MDT}
+    {-68659200 -25200 0 MST}
+    {-21481200 -21600 1 MDT}
+    {-5760000 -25200 0 MST}
+    {73472400 -21600 1 MDT}
+    {89193600 -25200 0 MST}
+    {104922000 -21600 1 MDT}
+    {120643200 -25200 0 MST}
+    {136371600 -21600 1 MDT}
+    {152092800 -25200 0 MST}
+    {167821200 -21600 1 MDT}
+    {183542400 -25200 0 MST}
+    {199270800 -21600 1 MDT}
+    {215596800 -25200 0 MST}
+    {230720400 -21600 1 MDT}
+    {247046400 -25200 0 MST}
+    {262774800 -21600 1 MDT}
+    {278496000 -25200 0 MST}
+    {294224400 -21600 1 MDT}
+    {309945600 -25200 0 MST}
+    {325674000 -21600 1 MDT}
+    {341395200 -25200 0 MST}
+    {357123600 -21600 1 MDT}
+    {372844800 -25200 0 MST}
+    {388573200 -21600 1 MDT}
+    {404899200 -25200 0 MST}
+    {420022800 -21600 1 MDT}
+    {436348800 -25200 0 MST}
+    {452077200 -21600 1 MDT}
+    {467798400 -25200 0 MST}
+    {483526800 -21600 1 MDT}
+    {499248000 -25200 0 MST}
+    {514976400 -21600 1 MDT}
+    {530697600 -25200 0 MST}
+    {536482800 -25200 0 MST}
+    {544611600 -21600 1 MDT}
+    {562147200 -25200 0 MST}
+    {576061200 -21600 1 MDT}
+    {594201600 -25200 0 MST}
+    {607510800 -21600 1 MDT}
+    {625651200 -25200 0 MST}
+    {638960400 -21600 1 MDT}
+    {657100800 -25200 0 MST}
+    {671014800 -21600 1 MDT}
+    {688550400 -25200 0 MST}
+    {702464400 -21600 1 MDT}
+    {720000000 -25200 0 MST}
+    {733914000 -21600 1 MDT}
+    {752054400 -25200 0 MST}
+    {765363600 -21600 1 MDT}
+    {783504000 -25200 0 MST}
+    {796813200 -21600 1 MDT}
+    {814953600 -25200 0 MST}
+    {828867600 -21600 1 MDT}
+    {846403200 -25200 0 MST}
+    {860317200 -21600 1 MDT}
+    {877852800 -25200 0 MST}
+    {891766800 -21600 1 MDT}
+    {909302400 -25200 0 MST}
+    {923216400 -21600 1 MDT}
+    {941356800 -25200 0 MST}
+    {954666000 -21600 1 MDT}
+    {972806400 -25200 0 MST}
+    {986115600 -21600 1 MDT}
+    {1004256000 -25200 0 MST}
+    {1018170000 -21600 1 MDT}
+    {1035705600 -25200 0 MST}
+    {1049619600 -21600 1 MDT}
+    {1067155200 -25200 0 MST}
+    {1081069200 -21600 1 MDT}
+    {1099209600 -25200 0 MST}
+    {1112518800 -21600 1 MDT}
+    {1130659200 -25200 0 MST}
+    {1143968400 -21600 1 MDT}
+    {1162108800 -25200 0 MST}
+    {1173603600 -21600 1 MDT}
+    {1194163200 -25200 0 MST}
+    {1205053200 -21600 1 MDT}
+    {1225612800 -25200 0 MST}
+    {1236502800 -21600 1 MDT}
+    {1257062400 -25200 0 MST}
+    {1268557200 -21600 1 MDT}
+    {1289116800 -25200 0 MST}
+    {1300006800 -21600 1 MDT}
+    {1320566400 -25200 0 MST}
+    {1331456400 -21600 1 MDT}
+    {1352016000 -25200 0 MST}
+    {1362906000 -21600 1 MDT}
+    {1383465600 -25200 0 MST}
+    {1394355600 -21600 1 MDT}
+    {1414915200 -25200 0 MST}
+    {1425805200 -21600 1 MDT}
+    {1446364800 -25200 0 MST}
+    {1457859600 -21600 1 MDT}
+    {1478419200 -25200 0 MST}
+    {1489309200 -21600 1 MDT}
+    {1509868800 -25200 0 MST}
+    {1520758800 -21600 1 MDT}
+    {1541318400 -25200 0 MST}
+    {1552208400 -21600 1 MDT}
+    {1572768000 -25200 0 MST}
+    {1583658000 -21600 1 MDT}
+    {1604217600 -25200 0 MST}
+    {1615712400 -21600 1 MDT}
+    {1636272000 -25200 0 MST}
+    {1647162000 -21600 1 MDT}
+    {1667721600 -25200 0 MST}
+    {1678611600 -21600 1 MDT}
+    {1699171200 -25200 0 MST}
+    {1710061200 -21600 1 MDT}
+    {1730620800 -25200 0 MST}
+    {1741510800 -21600 1 MDT}
+    {1762070400 -25200 0 MST}
+    {1772960400 -21600 1 MDT}
+    {1793520000 -25200 0 MST}
+    {1805014800 -21600 1 MDT}
+    {1825574400 -25200 0 MST}
+    {1836464400 -21600 1 MDT}
+    {1857024000 -25200 0 MST}
+    {1867914000 -21600 1 MDT}
+    {1888473600 -25200 0 MST}
+    {1899363600 -21600 1 MDT}
+    {1919923200 -25200 0 MST}
+    {1930813200 -21600 1 MDT}
+    {1951372800 -25200 0 MST}
+    {1962867600 -21600 1 MDT}
+    {1983427200 -25200 0 MST}
+    {1994317200 -21600 1 MDT}
+    {2014876800 -25200 0 MST}
+    {2025766800 -21600 1 MDT}
+    {2046326400 -25200 0 MST}
+    {2057216400 -21600 1 MDT}
+    {2077776000 -25200 0 MST}
+    {2088666000 -21600 1 MDT}
+    {2109225600 -25200 0 MST}
+    {2120115600 -21600 1 MDT}
+    {2140675200 -25200 0 MST}
+    {2152170000 -21600 1 MDT}
+    {2172729600 -25200 0 MST}
+    {2183619600 -21600 1 MDT}
+    {2204179200 -25200 0 MST}
+    {2215069200 -21600 1 MDT}
+    {2235628800 -25200 0 MST}
+    {2246518800 -21600 1 MDT}
+    {2267078400 -25200 0 MST}
+    {2277968400 -21600 1 MDT}
+    {2298528000 -25200 0 MST}
+    {2309418000 -21600 1 MDT}
+    {2329977600 -25200 0 MST}
+    {2341472400 -21600 1 MDT}
+    {2362032000 -25200 0 MST}
+    {2372922000 -21600 1 MDT}
+    {2393481600 -25200 0 MST}
+    {2404371600 -21600 1 MDT}
+    {2424931200 -25200 0 MST}
+    {2435821200 -21600 1 MDT}
+    {2456380800 -25200 0 MST}
+    {2467270800 -21600 1 MDT}
+    {2487830400 -25200 0 MST}
+    {2499325200 -21600 1 MDT}
+    {2519884800 -25200 0 MST}
+    {2530774800 -21600 1 MDT}
+    {2551334400 -25200 0 MST}
+    {2562224400 -21600 1 MDT}
+    {2582784000 -25200 0 MST}
+    {2593674000 -21600 1 MDT}
+    {2614233600 -25200 0 MST}
+    {2625123600 -21600 1 MDT}
+    {2645683200 -25200 0 MST}
+    {2656573200 -21600 1 MDT}
+    {2677132800 -25200 0 MST}
+    {2688627600 -21600 1 MDT}
+    {2709187200 -25200 0 MST}
+    {2720077200 -21600 1 MDT}
+    {2740636800 -25200 0 MST}
+    {2751526800 -21600 1 MDT}
+    {2772086400 -25200 0 MST}
+    {2782976400 -21600 1 MDT}
+    {2803536000 -25200 0 MST}
+    {2814426000 -21600 1 MDT}
+    {2834985600 -25200 0 MST}
+    {2846480400 -21600 1 MDT}
+    {2867040000 -25200 0 MST}
+    {2877930000 -21600 1 MDT}
+    {2898489600 -25200 0 MST}
+    {2909379600 -21600 1 MDT}
+    {2929939200 -25200 0 MST}
+    {2940829200 -21600 1 MDT}
+    {2961388800 -25200 0 MST}
+    {2972278800 -21600 1 MDT}
+    {2992838400 -25200 0 MST}
+    {3003728400 -21600 1 MDT}
+    {3024288000 -25200 0 MST}
+    {3035782800 -21600 1 MDT}
+    {3056342400 -25200 0 MST}
+    {3067232400 -21600 1 MDT}
+    {3087792000 -25200 0 MST}
+    {3098682000 -21600 1 MDT}
+    {3119241600 -25200 0 MST}
+    {3130131600 -21600 1 MDT}
+    {3150691200 -25200 0 MST}
+    {3161581200 -21600 1 MDT}
+    {3182140800 -25200 0 MST}
+    {3193030800 -21600 1 MDT}
+    {3213590400 -25200 0 MST}
+    {3225085200 -21600 1 MDT}
+    {3245644800 -25200 0 MST}
+    {3256534800 -21600 1 MDT}
+    {3277094400 -25200 0 MST}
+    {3287984400 -21600 1 MDT}
+    {3308544000 -25200 0 MST}
+    {3319434000 -21600 1 MDT}
+    {3339993600 -25200 0 MST}
+    {3350883600 -21600 1 MDT}
+    {3371443200 -25200 0 MST}
+    {3382938000 -21600 1 MDT}
+    {3403497600 -25200 0 MST}
+    {3414387600 -21600 1 MDT}
+    {3434947200 -25200 0 MST}
+    {3445837200 -21600 1 MDT}
+    {3466396800 -25200 0 MST}
+    {3477286800 -21600 1 MDT}
+    {3497846400 -25200 0 MST}
+    {3508736400 -21600 1 MDT}
+    {3529296000 -25200 0 MST}
+    {3540186000 -21600 1 MDT}
+    {3560745600 -25200 0 MST}
+    {3572240400 -21600 1 MDT}
+    {3592800000 -25200 0 MST}
+    {3603690000 -21600 1 MDT}
+    {3624249600 -25200 0 MST}
+    {3635139600 -21600 1 MDT}
+    {3655699200 -25200 0 MST}
+    {3666589200 -21600 1 MDT}
+    {3687148800 -25200 0 MST}
+    {3698038800 -21600 1 MDT}
+    {3718598400 -25200 0 MST}
+    {3730093200 -21600 1 MDT}
+    {3750652800 -25200 0 MST}
+    {3761542800 -21600 1 MDT}
+    {3782102400 -25200 0 MST}
+    {3792992400 -21600 1 MDT}
+    {3813552000 -25200 0 MST}
+    {3824442000 -21600 1 MDT}
+    {3845001600 -25200 0 MST}
+    {3855891600 -21600 1 MDT}
+    {3876451200 -25200 0 MST}
+    {3887341200 -21600 1 MDT}
+    {3907900800 -25200 0 MST}
+    {3919395600 -21600 1 MDT}
+    {3939955200 -25200 0 MST}
+    {3950845200 -21600 1 MDT}
+    {3971404800 -25200 0 MST}
+    {3982294800 -21600 1 MDT}
+    {4002854400 -25200 0 MST}
+    {4013744400 -21600 1 MDT}
+    {4034304000 -25200 0 MST}
+    {4045194000 -21600 1 MDT}
+    {4065753600 -25200 0 MST}
+    {4076643600 -21600 1 MDT}
+    {4097203200 -25200 0 MST}
+}
diff --git a/library/tzdata/America/Eirunepe b/library/tzdata/America/Eirunepe
new file mode 100644
index 0000000..a05631f
--- /dev/null
+++ b/library/tzdata/America/Eirunepe
@@ -0,0 +1,41 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Eirunepe) {
+    {-9223372036854775808 -16768 0 LMT}
+    {-1767208832 -18000 0 ACT}
+    {-1206950400 -14400 1 ACST}
+    {-1191355200 -18000 0 ACT}
+    {-1175367600 -14400 1 ACST}
+    {-1159819200 -18000 0 ACT}
+    {-633812400 -14400 1 ACST}
+    {-622062000 -18000 0 ACT}
+    {-602276400 -14400 1 ACST}
+    {-591825600 -18000 0 ACT}
+    {-570740400 -14400 1 ACST}
+    {-560203200 -18000 0 ACT}
+    {-539118000 -14400 1 ACST}
+    {-531345600 -18000 0 ACT}
+    {-191358000 -14400 1 ACST}
+    {-184190400 -18000 0 ACT}
+    {-155156400 -14400 1 ACST}
+    {-150062400 -18000 0 ACT}
+    {-128890800 -14400 1 ACST}
+    {-121118400 -18000 0 ACT}
+    {-99946800 -14400 1 ACST}
+    {-89582400 -18000 0 ACT}
+    {-68410800 -14400 1 ACST}
+    {-57960000 -18000 0 ACT}
+    {499755600 -14400 1 ACST}
+    {511243200 -18000 0 ACT}
+    {530600400 -14400 1 ACST}
+    {540273600 -18000 0 ACT}
+    {562136400 -14400 1 ACST}
+    {571204800 -18000 0 ACT}
+    {590040000 -18000 0 ACT}
+    {749192400 -18000 0 ACT}
+    {750834000 -14400 1 ACST}
+    {761716800 -18000 0 ACT}
+    {780206400 -18000 0 ACT}
+    {1214283600 -14400 0 AMT}
+    {1384056000 -18000 0 ACT}
+}
diff --git a/library/tzdata/America/El_Salvador b/library/tzdata/America/El_Salvador
new file mode 100644
index 0000000..75d8129
--- /dev/null
+++ b/library/tzdata/America/El_Salvador
@@ -0,0 +1,10 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/El_Salvador) {
+    {-9223372036854775808 -21408 0 LMT}
+    {-1546279392 -21600 0 CST}
+    {547020000 -18000 1 CDT}
+    {559717200 -21600 0 CST}
+    {578469600 -18000 1 CDT}
+    {591166800 -21600 0 CST}
+}
diff --git a/library/tzdata/America/Ensenada b/library/tzdata/America/Ensenada
new file mode 100644
index 0000000..f600305
--- /dev/null
+++ b/library/tzdata/America/Ensenada
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(America/Tijuana)]} {
+    LoadTimeZoneFile America/Tijuana
+}
+set TZData(:America/Ensenada) $TZData(:America/Tijuana)
diff --git a/library/tzdata/America/Fort_Nelson b/library/tzdata/America/Fort_Nelson
new file mode 100644
index 0000000..d819368
--- /dev/null
+++ b/library/tzdata/America/Fort_Nelson
@@ -0,0 +1,151 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Fort_Nelson) {
+    {-9223372036854775808 -29447 0 LMT}
+    {-2713880953 -28800 0 PST}
+    {-1632060000 -25200 1 PDT}
+    {-1615129200 -28800 0 PST}
+    {-880207200 -25200 1 PWT}
+    {-769395600 -25200 1 PPT}
+    {-765385200 -28800 0 PST}
+    {-757353600 -28800 0 PST}
+    {-725817600 -28800 0 PST}
+    {-715788000 -25200 1 PDT}
+    {-702486000 -28800 0 PST}
+    {-684338400 -25200 1 PDT}
+    {-671036400 -28800 0 PST}
+    {-652888800 -25200 1 PDT}
+    {-639586800 -28800 0 PST}
+    {-620834400 -25200 1 PDT}
+    {-608137200 -28800 0 PST}
+    {-589384800 -25200 1 PDT}
+    {-576082800 -28800 0 PST}
+    {-557935200 -25200 1 PDT}
+    {-544633200 -28800 0 PST}
+    {-526485600 -25200 1 PDT}
+    {-513183600 -28800 0 PST}
+    {-495036000 -25200 1 PDT}
+    {-481734000 -28800 0 PST}
+    {-463586400 -25200 1 PDT}
+    {-450284400 -28800 0 PST}
+    {-431532000 -25200 1 PDT}
+    {-418230000 -28800 0 PST}
+    {-400082400 -25200 1 PDT}
+    {-386780400 -28800 0 PST}
+    {-368632800 -25200 1 PDT}
+    {-355330800 -28800 0 PST}
+    {-337183200 -25200 1 PDT}
+    {-323881200 -28800 0 PST}
+    {-305733600 -25200 1 PDT}
+    {-292431600 -28800 0 PST}
+    {-273679200 -25200 1 PDT}
+    {-260982000 -28800 0 PST}
+    {-242229600 -25200 1 PDT}
+    {-226508400 -28800 0 PST}
+    {-210780000 -25200 1 PDT}
+    {-195058800 -28800 0 PST}
+    {-179330400 -25200 1 PDT}
+    {-163609200 -28800 0 PST}
+    {-147880800 -25200 1 PDT}
+    {-131554800 -28800 0 PST}
+    {-116431200 -25200 1 PDT}
+    {-100105200 -28800 0 PST}
+    {-84376800 -25200 1 PDT}
+    {-68655600 -28800 0 PST}
+    {-52927200 -25200 1 PDT}
+    {-37206000 -28800 0 PST}
+    {-21477600 -25200 1 PDT}
+    {-5756400 -28800 0 PST}
+    {9972000 -25200 1 PDT}
+    {25693200 -28800 0 PST}
+    {41421600 -25200 1 PDT}
+    {57747600 -28800 0 PST}
+    {73476000 -25200 1 PDT}
+    {89197200 -28800 0 PST}
+    {104925600 -25200 1 PDT}
+    {120646800 -28800 0 PST}
+    {136375200 -25200 1 PDT}
+    {152096400 -28800 0 PST}
+    {167824800 -25200 1 PDT}
+    {183546000 -28800 0 PST}
+    {199274400 -25200 1 PDT}
+    {215600400 -28800 0 PST}
+    {230724000 -25200 1 PDT}
+    {247050000 -28800 0 PST}
+    {262778400 -25200 1 PDT}
+    {278499600 -28800 0 PST}
+    {294228000 -25200 1 PDT}
+    {309949200 -28800 0 PST}
+    {325677600 -25200 1 PDT}
+    {341398800 -28800 0 PST}
+    {357127200 -25200 1 PDT}
+    {372848400 -28800 0 PST}
+    {388576800 -25200 1 PDT}
+    {404902800 -28800 0 PST}
+    {420026400 -25200 1 PDT}
+    {436352400 -28800 0 PST}
+    {452080800 -25200 1 PDT}
+    {467802000 -28800 0 PST}
+    {483530400 -25200 1 PDT}
+    {499251600 -28800 0 PST}
+    {514980000 -25200 1 PDT}
+    {530701200 -28800 0 PST}
+    {536486400 -28800 0 PST}
+    {544615200 -25200 1 PDT}
+    {562150800 -28800 0 PST}
+    {576064800 -25200 1 PDT}
+    {594205200 -28800 0 PST}
+    {607514400 -25200 1 PDT}
+    {625654800 -28800 0 PST}
+    {638964000 -25200 1 PDT}
+    {657104400 -28800 0 PST}
+    {671018400 -25200 1 PDT}
+    {688554000 -28800 0 PST}
+    {702468000 -25200 1 PDT}
+    {720003600 -28800 0 PST}
+    {733917600 -25200 1 PDT}
+    {752058000 -28800 0 PST}
+    {765367200 -25200 1 PDT}
+    {783507600 -28800 0 PST}
+    {796816800 -25200 1 PDT}
+    {814957200 -28800 0 PST}
+    {828871200 -25200 1 PDT}
+    {846406800 -28800 0 PST}
+    {860320800 -25200 1 PDT}
+    {877856400 -28800 0 PST}
+    {891770400 -25200 1 PDT}
+    {909306000 -28800 0 PST}
+    {923220000 -25200 1 PDT}
+    {941360400 -28800 0 PST}
+    {954669600 -25200 1 PDT}
+    {972810000 -28800 0 PST}
+    {986119200 -25200 1 PDT}
+    {1004259600 -28800 0 PST}
+    {1018173600 -25200 1 PDT}
+    {1035709200 -28800 0 PST}
+    {1049623200 -25200 1 PDT}
+    {1067158800 -28800 0 PST}
+    {1081072800 -25200 1 PDT}
+    {1099213200 -28800 0 PST}
+    {1112522400 -25200 1 PDT}
+    {1130662800 -28800 0 PST}
+    {1143972000 -25200 1 PDT}
+    {1162112400 -28800 0 PST}
+    {1173607200 -25200 1 PDT}
+    {1194166800 -28800 0 PST}
+    {1205056800 -25200 1 PDT}
+    {1225616400 -28800 0 PST}
+    {1236506400 -25200 1 PDT}
+    {1257066000 -28800 0 PST}
+    {1268560800 -25200 1 PDT}
+    {1289120400 -28800 0 PST}
+    {1300010400 -25200 1 PDT}
+    {1320570000 -28800 0 PST}
+    {1331460000 -25200 1 PDT}
+    {1352019600 -28800 0 PST}
+    {1362909600 -25200 1 PDT}
+    {1383469200 -28800 0 PST}
+    {1394359200 -25200 1 PDT}
+    {1414918800 -28800 0 PST}
+    {1425808800 -25200 0 MST}
+}
diff --git a/library/tzdata/America/Fort_Wayne b/library/tzdata/America/Fort_Wayne
new file mode 100644
index 0000000..9514d57
--- /dev/null
+++ b/library/tzdata/America/Fort_Wayne
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(America/Indiana/Indianapolis)]} {
+    LoadTimeZoneFile America/Indiana/Indianapolis
+}
+set TZData(:America/Fort_Wayne) $TZData(:America/Indiana/Indianapolis)
diff --git a/library/tzdata/America/Fortaleza b/library/tzdata/America/Fortaleza
new file mode 100644
index 0000000..581faa5
--- /dev/null
+++ b/library/tzdata/America/Fortaleza
@@ -0,0 +1,48 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Fortaleza) {
+    {-9223372036854775808 -9240 0 LMT}
+    {-1767216360 -10800 0 BRT}
+    {-1206957600 -7200 1 BRST}
+    {-1191362400 -10800 0 BRT}
+    {-1175374800 -7200 1 BRST}
+    {-1159826400 -10800 0 BRT}
+    {-633819600 -7200 1 BRST}
+    {-622069200 -10800 0 BRT}
+    {-602283600 -7200 1 BRST}
+    {-591832800 -10800 0 BRT}
+    {-570747600 -7200 1 BRST}
+    {-560210400 -10800 0 BRT}
+    {-539125200 -7200 1 BRST}
+    {-531352800 -10800 0 BRT}
+    {-191365200 -7200 1 BRST}
+    {-184197600 -10800 0 BRT}
+    {-155163600 -7200 1 BRST}
+    {-150069600 -10800 0 BRT}
+    {-128898000 -7200 1 BRST}
+    {-121125600 -10800 0 BRT}
+    {-99954000 -7200 1 BRST}
+    {-89589600 -10800 0 BRT}
+    {-68418000 -7200 1 BRST}
+    {-57967200 -10800 0 BRT}
+    {499748400 -7200 1 BRST}
+    {511236000 -10800 0 BRT}
+    {530593200 -7200 1 BRST}
+    {540266400 -10800 0 BRT}
+    {562129200 -7200 1 BRST}
+    {571197600 -10800 0 BRT}
+    {592974000 -7200 1 BRST}
+    {602042400 -10800 0 BRT}
+    {624423600 -7200 1 BRST}
+    {634701600 -10800 0 BRT}
+    {653536800 -10800 0 BRT}
+    {938660400 -10800 0 BRT}
+    {938919600 -7200 1 BRST}
+    {951616800 -10800 0 BRT}
+    {970974000 -7200 1 BRST}
+    {972180000 -10800 0 BRT}
+    {1000350000 -10800 0 BRT}
+    {1003028400 -7200 1 BRST}
+    {1013911200 -10800 0 BRT}
+    {1033437600 -10800 0 BRT}
+}
diff --git a/library/tzdata/America/Glace_Bay b/library/tzdata/America/Glace_Bay
new file mode 100644
index 0000000..8ee9eec
--- /dev/null
+++ b/library/tzdata/America/Glace_Bay
@@ -0,0 +1,273 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Glace_Bay) {
+    {-9223372036854775808 -14388 0 LMT}
+    {-2131646412 -14400 0 AST}
+    {-1632074400 -10800 1 ADT}
+    {-1615143600 -14400 0 AST}
+    {-880221600 -10800 1 AWT}
+    {-769395600 -10800 1 APT}
+    {-765399600 -14400 0 AST}
+    {-536443200 -14400 0 AST}
+    {-526500000 -10800 1 ADT}
+    {-513198000 -14400 0 AST}
+    {-504907200 -14400 0 AST}
+    {63086400 -14400 0 AST}
+    {73461600 -10800 1 ADT}
+    {89182800 -14400 0 AST}
+    {104911200 -10800 1 ADT}
+    {120632400 -14400 0 AST}
+    {126244800 -14400 0 AST}
+    {136360800 -10800 1 ADT}
+    {152082000 -14400 0 AST}
+    {167810400 -10800 1 ADT}
+    {183531600 -14400 0 AST}
+    {199260000 -10800 1 ADT}
+    {215586000 -14400 0 AST}
+    {230709600 -10800 1 ADT}
+    {247035600 -14400 0 AST}
+    {262764000 -10800 1 ADT}
+    {278485200 -14400 0 AST}
+    {294213600 -10800 1 ADT}
+    {309934800 -14400 0 AST}
+    {325663200 -10800 1 ADT}
+    {341384400 -14400 0 AST}
+    {357112800 -10800 1 ADT}
+    {372834000 -14400 0 AST}
+    {388562400 -10800 1 ADT}
+    {404888400 -14400 0 AST}
+    {420012000 -10800 1 ADT}
+    {436338000 -14400 0 AST}
+    {452066400 -10800 1 ADT}
+    {467787600 -14400 0 AST}
+    {483516000 -10800 1 ADT}
+    {499237200 -14400 0 AST}
+    {514965600 -10800 1 ADT}
+    {530686800 -14400 0 AST}
+    {544600800 -10800 1 ADT}
+    {562136400 -14400 0 AST}
+    {576050400 -10800 1 ADT}
+    {594190800 -14400 0 AST}
+    {607500000 -10800 1 ADT}
+    {625640400 -14400 0 AST}
+    {638949600 -10800 1 ADT}
+    {657090000 -14400 0 AST}
+    {671004000 -10800 1 ADT}
+    {688539600 -14400 0 AST}
+    {702453600 -10800 1 ADT}
+    {719989200 -14400 0 AST}
+    {733903200 -10800 1 ADT}
+    {752043600 -14400 0 AST}
+    {765352800 -10800 1 ADT}
+    {783493200 -14400 0 AST}
+    {796802400 -10800 1 ADT}
+    {814942800 -14400 0 AST}
+    {828856800 -10800 1 ADT}
+    {846392400 -14400 0 AST}
+    {860306400 -10800 1 ADT}
+    {877842000 -14400 0 AST}
+    {891756000 -10800 1 ADT}
+    {909291600 -14400 0 AST}
+    {923205600 -10800 1 ADT}
+    {941346000 -14400 0 AST}
+    {954655200 -10800 1 ADT}
+    {972795600 -14400 0 AST}
+    {986104800 -10800 1 ADT}
+    {1004245200 -14400 0 AST}
+    {1018159200 -10800 1 ADT}
+    {1035694800 -14400 0 AST}
+    {1049608800 -10800 1 ADT}
+    {1067144400 -14400 0 AST}
+    {1081058400 -10800 1 ADT}
+    {1099198800 -14400 0 AST}
+    {1112508000 -10800 1 ADT}
+    {1130648400 -14400 0 AST}
+    {1143957600 -10800 1 ADT}
+    {1162098000 -14400 0 AST}
+    {1173592800 -10800 1 ADT}
+    {1194152400 -14400 0 AST}
+    {1205042400 -10800 1 ADT}
+    {1225602000 -14400 0 AST}
+    {1236492000 -10800 1 ADT}
+    {1257051600 -14400 0 AST}
+    {1268546400 -10800 1 ADT}
+    {1289106000 -14400 0 AST}
+    {1299996000 -10800 1 ADT}
+    {1320555600 -14400 0 AST}
+    {1331445600 -10800 1 ADT}
+    {1352005200 -14400 0 AST}
+    {1362895200 -10800 1 ADT}
+    {1383454800 -14400 0 AST}
+    {1394344800 -10800 1 ADT}
+    {1414904400 -14400 0 AST}
+    {1425794400 -10800 1 ADT}
+    {1446354000 -14400 0 AST}
+    {1457848800 -10800 1 ADT}
+    {1478408400 -14400 0 AST}
+    {1489298400 -10800 1 ADT}
+    {1509858000 -14400 0 AST}
+    {1520748000 -10800 1 ADT}
+    {1541307600 -14400 0 AST}
+    {1552197600 -10800 1 ADT}
+    {1572757200 -14400 0 AST}
+    {1583647200 -10800 1 ADT}
+    {1604206800 -14400 0 AST}
+    {1615701600 -10800 1 ADT}
+    {1636261200 -14400 0 AST}
+    {1647151200 -10800 1 ADT}
+    {1667710800 -14400 0 AST}
+    {1678600800 -10800 1 ADT}
+    {1699160400 -14400 0 AST}
+    {1710050400 -10800 1 ADT}
+    {1730610000 -14400 0 AST}
+    {1741500000 -10800 1 ADT}
+    {1762059600 -14400 0 AST}
+    {1772949600 -10800 1 ADT}
+    {1793509200 -14400 0 AST}
+    {1805004000 -10800 1 ADT}
+    {1825563600 -14400 0 AST}
+    {1836453600 -10800 1 ADT}
+    {1857013200 -14400 0 AST}
+    {1867903200 -10800 1 ADT}
+    {1888462800 -14400 0 AST}
+    {1899352800 -10800 1 ADT}
+    {1919912400 -14400 0 AST}
+    {1930802400 -10800 1 ADT}
+    {1951362000 -14400 0 AST}
+    {1962856800 -10800 1 ADT}
+    {1983416400 -14400 0 AST}
+    {1994306400 -10800 1 ADT}
+    {2014866000 -14400 0 AST}
+    {2025756000 -10800 1 ADT}
+    {2046315600 -14400 0 AST}
+    {2057205600 -10800 1 ADT}
+    {2077765200 -14400 0 AST}
+    {2088655200 -10800 1 ADT}
+    {2109214800 -14400 0 AST}
+    {2120104800 -10800 1 ADT}
+    {2140664400 -14400 0 AST}
+    {2152159200 -10800 1 ADT}
+    {2172718800 -14400 0 AST}
+    {2183608800 -10800 1 ADT}
+    {2204168400 -14400 0 AST}
+    {2215058400 -10800 1 ADT}
+    {2235618000 -14400 0 AST}
+    {2246508000 -10800 1 ADT}
+    {2267067600 -14400 0 AST}
+    {2277957600 -10800 1 ADT}
+    {2298517200 -14400 0 AST}
+    {2309407200 -10800 1 ADT}
+    {2329966800 -14400 0 AST}
+    {2341461600 -10800 1 ADT}
+    {2362021200 -14400 0 AST}
+    {2372911200 -10800 1 ADT}
+    {2393470800 -14400 0 AST}
+    {2404360800 -10800 1 ADT}
+    {2424920400 -14400 0 AST}
+    {2435810400 -10800 1 ADT}
+    {2456370000 -14400 0 AST}
+    {2467260000 -10800 1 ADT}
+    {2487819600 -14400 0 AST}
+    {2499314400 -10800 1 ADT}
+    {2519874000 -14400 0 AST}
+    {2530764000 -10800 1 ADT}
+    {2551323600 -14400 0 AST}
+    {2562213600 -10800 1 ADT}
+    {2582773200 -14400 0 AST}
+    {2593663200 -10800 1 ADT}
+    {2614222800 -14400 0 AST}
+    {2625112800 -10800 1 ADT}
+    {2645672400 -14400 0 AST}
+    {2656562400 -10800 1 ADT}
+    {2677122000 -14400 0 AST}
+    {2688616800 -10800 1 ADT}
+    {2709176400 -14400 0 AST}
+    {2720066400 -10800 1 ADT}
+    {2740626000 -14400 0 AST}
+    {2751516000 -10800 1 ADT}
+    {2772075600 -14400 0 AST}
+    {2782965600 -10800 1 ADT}
+    {2803525200 -14400 0 AST}
+    {2814415200 -10800 1 ADT}
+    {2834974800 -14400 0 AST}
+    {2846469600 -10800 1 ADT}
+    {2867029200 -14400 0 AST}
+    {2877919200 -10800 1 ADT}
+    {2898478800 -14400 0 AST}
+    {2909368800 -10800 1 ADT}
+    {2929928400 -14400 0 AST}
+    {2940818400 -10800 1 ADT}
+    {2961378000 -14400 0 AST}
+    {2972268000 -10800 1 ADT}
+    {2992827600 -14400 0 AST}
+    {3003717600 -10800 1 ADT}
+    {3024277200 -14400 0 AST}
+    {3035772000 -10800 1 ADT}
+    {3056331600 -14400 0 AST}
+    {3067221600 -10800 1 ADT}
+    {3087781200 -14400 0 AST}
+    {3098671200 -10800 1 ADT}
+    {3119230800 -14400 0 AST}
+    {3130120800 -10800 1 ADT}
+    {3150680400 -14400 0 AST}
+    {3161570400 -10800 1 ADT}
+    {3182130000 -14400 0 AST}
+    {3193020000 -10800 1 ADT}
+    {3213579600 -14400 0 AST}
+    {3225074400 -10800 1 ADT}
+    {3245634000 -14400 0 AST}
+    {3256524000 -10800 1 ADT}
+    {3277083600 -14400 0 AST}
+    {3287973600 -10800 1 ADT}
+    {3308533200 -14400 0 AST}
+    {3319423200 -10800 1 ADT}
+    {3339982800 -14400 0 AST}
+    {3350872800 -10800 1 ADT}
+    {3371432400 -14400 0 AST}
+    {3382927200 -10800 1 ADT}
+    {3403486800 -14400 0 AST}
+    {3414376800 -10800 1 ADT}
+    {3434936400 -14400 0 AST}
+    {3445826400 -10800 1 ADT}
+    {3466386000 -14400 0 AST}
+    {3477276000 -10800 1 ADT}
+    {3497835600 -14400 0 AST}
+    {3508725600 -10800 1 ADT}
+    {3529285200 -14400 0 AST}
+    {3540175200 -10800 1 ADT}
+    {3560734800 -14400 0 AST}
+    {3572229600 -10800 1 ADT}
+    {3592789200 -14400 0 AST}
+    {3603679200 -10800 1 ADT}
+    {3624238800 -14400 0 AST}
+    {3635128800 -10800 1 ADT}
+    {3655688400 -14400 0 AST}
+    {3666578400 -10800 1 ADT}
+    {3687138000 -14400 0 AST}
+    {3698028000 -10800 1 ADT}
+    {3718587600 -14400 0 AST}
+    {3730082400 -10800 1 ADT}
+    {3750642000 -14400 0 AST}
+    {3761532000 -10800 1 ADT}
+    {3782091600 -14400 0 AST}
+    {3792981600 -10800 1 ADT}
+    {3813541200 -14400 0 AST}
+    {3824431200 -10800 1 ADT}
+    {3844990800 -14400 0 AST}
+    {3855880800 -10800 1 ADT}
+    {3876440400 -14400 0 AST}
+    {3887330400 -10800 1 ADT}
+    {3907890000 -14400 0 AST}
+    {3919384800 -10800 1 ADT}
+    {3939944400 -14400 0 AST}
+    {3950834400 -10800 1 ADT}
+    {3971394000 -14400 0 AST}
+    {3982284000 -10800 1 ADT}
+    {4002843600 -14400 0 AST}
+    {4013733600 -10800 1 ADT}
+    {4034293200 -14400 0 AST}
+    {4045183200 -10800 1 ADT}
+    {4065742800 -14400 0 AST}
+    {4076632800 -10800 1 ADT}
+    {4097192400 -14400 0 AST}
+}
diff --git a/library/tzdata/America/Godthab b/library/tzdata/America/Godthab
new file mode 100644
index 0000000..3c003cc
--- /dev/null
+++ b/library/tzdata/America/Godthab
@@ -0,0 +1,246 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Godthab) {
+    {-9223372036854775808 -12416 0 LMT}
+    {-1686083584 -10800 0 WGT}
+    {323845200 -7200 0 WGST}
+    {338950800 -10800 0 WGT}
+    {354675600 -7200 1 WGST}
+    {370400400 -10800 0 WGT}
+    {386125200 -7200 1 WGST}
+    {401850000 -10800 0 WGT}
+    {417574800 -7200 1 WGST}
+    {433299600 -10800 0 WGT}
+    {449024400 -7200 1 WGST}
+    {465354000 -10800 0 WGT}
+    {481078800 -7200 1 WGST}
+    {496803600 -10800 0 WGT}
+    {512528400 -7200 1 WGST}
+    {528253200 -10800 0 WGT}
+    {543978000 -7200 1 WGST}
+    {559702800 -10800 0 WGT}
+    {575427600 -7200 1 WGST}
+    {591152400 -10800 0 WGT}
+    {606877200 -7200 1 WGST}
+    {622602000 -10800 0 WGT}
+    {638326800 -7200 1 WGST}
+    {654656400 -10800 0 WGT}
+    {670381200 -7200 1 WGST}
+    {686106000 -10800 0 WGT}
+    {701830800 -7200 1 WGST}
+    {717555600 -10800 0 WGT}
+    {733280400 -7200 1 WGST}
+    {749005200 -10800 0 WGT}
+    {764730000 -7200 1 WGST}
+    {780454800 -10800 0 WGT}
+    {796179600 -7200 1 WGST}
+    {811904400 -10800 0 WGT}
+    {828234000 -7200 1 WGST}
+    {846378000 -10800 0 WGT}
+    {859683600 -7200 1 WGST}
+    {877827600 -10800 0 WGT}
+    {891133200 -7200 1 WGST}
+    {909277200 -10800 0 WGT}
+    {922582800 -7200 1 WGST}
+    {941331600 -10800 0 WGT}
+    {954032400 -7200 1 WGST}
+    {972781200 -10800 0 WGT}
+    {985482000 -7200 1 WGST}
+    {1004230800 -10800 0 WGT}
+    {1017536400 -7200 1 WGST}
+    {1035680400 -10800 0 WGT}
+    {1048986000 -7200 1 WGST}
+    {1067130000 -10800 0 WGT}
+    {1080435600 -7200 1 WGST}
+    {1099184400 -10800 0 WGT}
+    {1111885200 -7200 1 WGST}
+    {1130634000 -10800 0 WGT}
+    {1143334800 -7200 1 WGST}
+    {1162083600 -10800 0 WGT}
+    {1174784400 -7200 1 WGST}
+    {1193533200 -10800 0 WGT}
+    {1206838800 -7200 1 WGST}
+    {1224982800 -10800 0 WGT}
+    {1238288400 -7200 1 WGST}
+    {1256432400 -10800 0 WGT}
+    {1269738000 -7200 1 WGST}
+    {1288486800 -10800 0 WGT}
+    {1301187600 -7200 1 WGST}
+    {1319936400 -10800 0 WGT}
+    {1332637200 -7200 1 WGST}
+    {1351386000 -10800 0 WGT}
+    {1364691600 -7200 1 WGST}
+    {1382835600 -10800 0 WGT}
+    {1396141200 -7200 1 WGST}
+    {1414285200 -10800 0 WGT}
+    {1427590800 -7200 1 WGST}
+    {1445734800 -10800 0 WGT}
+    {1459040400 -7200 1 WGST}
+    {1477789200 -10800 0 WGT}
+    {1490490000 -7200 1 WGST}
+    {1509238800 -10800 0 WGT}
+    {1521939600 -7200 1 WGST}
+    {1540688400 -10800 0 WGT}
+    {1553994000 -7200 1 WGST}
+    {1572138000 -10800 0 WGT}
+    {1585443600 -7200 1 WGST}
+    {1603587600 -10800 0 WGT}
+    {1616893200 -7200 1 WGST}
+    {1635642000 -10800 0 WGT}
+    {1648342800 -7200 1 WGST}
+    {1667091600 -10800 0 WGT}
+    {1679792400 -7200 1 WGST}
+    {1698541200 -10800 0 WGT}
+    {1711846800 -7200 1 WGST}
+    {1729990800 -10800 0 WGT}
+    {1743296400 -7200 1 WGST}
+    {1761440400 -10800 0 WGT}
+    {1774746000 -7200 1 WGST}
+    {1792890000 -10800 0 WGT}
+    {1806195600 -7200 1 WGST}
+    {1824944400 -10800 0 WGT}
+    {1837645200 -7200 1 WGST}
+    {1856394000 -10800 0 WGT}
+    {1869094800 -7200 1 WGST}
+    {1887843600 -10800 0 WGT}
+    {1901149200 -7200 1 WGST}
+    {1919293200 -10800 0 WGT}
+    {1932598800 -7200 1 WGST}
+    {1950742800 -10800 0 WGT}
+    {1964048400 -7200 1 WGST}
+    {1982797200 -10800 0 WGT}
+    {1995498000 -7200 1 WGST}
+    {2014246800 -10800 0 WGT}
+    {2026947600 -7200 1 WGST}
+    {2045696400 -10800 0 WGT}
+    {2058397200 -7200 1 WGST}
+    {2077146000 -10800 0 WGT}
+    {2090451600 -7200 1 WGST}
+    {2108595600 -10800 0 WGT}
+    {2121901200 -7200 1 WGST}
+    {2140045200 -10800 0 WGT}
+    {2153350800 -7200 1 WGST}
+    {2172099600 -10800 0 WGT}
+    {2184800400 -7200 1 WGST}
+    {2203549200 -10800 0 WGT}
+    {2216250000 -7200 1 WGST}
+    {2234998800 -10800 0 WGT}
+    {2248304400 -7200 1 WGST}
+    {2266448400 -10800 0 WGT}
+    {2279754000 -7200 1 WGST}
+    {2297898000 -10800 0 WGT}
+    {2311203600 -7200 1 WGST}
+    {2329347600 -10800 0 WGT}
+    {2342653200 -7200 1 WGST}
+    {2361402000 -10800 0 WGT}
+    {2374102800 -7200 1 WGST}
+    {2392851600 -10800 0 WGT}
+    {2405552400 -7200 1 WGST}
+    {2424301200 -10800 0 WGT}
+    {2437606800 -7200 1 WGST}
+    {2455750800 -10800 0 WGT}
+    {2469056400 -7200 1 WGST}
+    {2487200400 -10800 0 WGT}
+    {2500506000 -7200 1 WGST}
+    {2519254800 -10800 0 WGT}
+    {2531955600 -7200 1 WGST}
+    {2550704400 -10800 0 WGT}
+    {2563405200 -7200 1 WGST}
+    {2582154000 -10800 0 WGT}
+    {2595459600 -7200 1 WGST}
+    {2613603600 -10800 0 WGT}
+    {2626909200 -7200 1 WGST}
+    {2645053200 -10800 0 WGT}
+    {2658358800 -7200 1 WGST}
+    {2676502800 -10800 0 WGT}
+    {2689808400 -7200 1 WGST}
+    {2708557200 -10800 0 WGT}
+    {2721258000 -7200 1 WGST}
+    {2740006800 -10800 0 WGT}
+    {2752707600 -7200 1 WGST}
+    {2771456400 -10800 0 WGT}
+    {2784762000 -7200 1 WGST}
+    {2802906000 -10800 0 WGT}
+    {2816211600 -7200 1 WGST}
+    {2834355600 -10800 0 WGT}
+    {2847661200 -7200 1 WGST}
+    {2866410000 -10800 0 WGT}
+    {2879110800 -7200 1 WGST}
+    {2897859600 -10800 0 WGT}
+    {2910560400 -7200 1 WGST}
+    {2929309200 -10800 0 WGT}
+    {2942010000 -7200 1 WGST}
+    {2960758800 -10800 0 WGT}
+    {2974064400 -7200 1 WGST}
+    {2992208400 -10800 0 WGT}
+    {3005514000 -7200 1 WGST}
+    {3023658000 -10800 0 WGT}
+    {3036963600 -7200 1 WGST}
+    {3055712400 -10800 0 WGT}
+    {3068413200 -7200 1 WGST}
+    {3087162000 -10800 0 WGT}
+    {3099862800 -7200 1 WGST}
+    {3118611600 -10800 0 WGT}
+    {3131917200 -7200 1 WGST}
+    {3150061200 -10800 0 WGT}
+    {3163366800 -7200 1 WGST}
+    {3181510800 -10800 0 WGT}
+    {3194816400 -7200 1 WGST}
+    {3212960400 -10800 0 WGT}
+    {3226266000 -7200 1 WGST}
+    {3245014800 -10800 0 WGT}
+    {3257715600 -7200 1 WGST}
+    {3276464400 -10800 0 WGT}
+    {3289165200 -7200 1 WGST}
+    {3307914000 -10800 0 WGT}
+    {3321219600 -7200 1 WGST}
+    {3339363600 -10800 0 WGT}
+    {3352669200 -7200 1 WGST}
+    {3370813200 -10800 0 WGT}
+    {3384118800 -7200 1 WGST}
+    {3402867600 -10800 0 WGT}
+    {3415568400 -7200 1 WGST}
+    {3434317200 -10800 0 WGT}
+    {3447018000 -7200 1 WGST}
+    {3465766800 -10800 0 WGT}
+    {3479072400 -7200 1 WGST}
+    {3497216400 -10800 0 WGT}
+    {3510522000 -7200 1 WGST}
+    {3528666000 -10800 0 WGT}
+    {3541971600 -7200 1 WGST}
+    {3560115600 -10800 0 WGT}
+    {3573421200 -7200 1 WGST}
+    {3592170000 -10800 0 WGT}
+    {3604870800 -7200 1 WGST}
+    {3623619600 -10800 0 WGT}
+    {3636320400 -7200 1 WGST}
+    {3655069200 -10800 0 WGT}
+    {3668374800 -7200 1 WGST}
+    {3686518800 -10800 0 WGT}
+    {3699824400 -7200 1 WGST}
+    {3717968400 -10800 0 WGT}
+    {3731274000 -7200 1 WGST}
+    {3750022800 -10800 0 WGT}
+    {3762723600 -7200 1 WGST}
+    {3781472400 -10800 0 WGT}
+    {3794173200 -7200 1 WGST}
+    {3812922000 -10800 0 WGT}
+    {3825622800 -7200 1 WGST}
+    {3844371600 -10800 0 WGT}
+    {3857677200 -7200 1 WGST}
+    {3875821200 -10800 0 WGT}
+    {3889126800 -7200 1 WGST}
+    {3907270800 -10800 0 WGT}
+    {3920576400 -7200 1 WGST}
+    {3939325200 -10800 0 WGT}
+    {3952026000 -7200 1 WGST}
+    {3970774800 -10800 0 WGT}
+    {3983475600 -7200 1 WGST}
+    {4002224400 -10800 0 WGT}
+    {4015530000 -7200 1 WGST}
+    {4033674000 -10800 0 WGT}
+    {4046979600 -7200 1 WGST}
+    {4065123600 -10800 0 WGT}
+    {4078429200 -7200 1 WGST}
+    {4096573200 -10800 0 WGT}
+}
diff --git a/library/tzdata/America/Goose_Bay b/library/tzdata/America/Goose_Bay
new file mode 100644
index 0000000..7b7b3d8
--- /dev/null
+++ b/library/tzdata/America/Goose_Bay
@@ -0,0 +1,338 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Goose_Bay) {
+    {-9223372036854775808 -14500 0 LMT}
+    {-2713895900 -12652 0 NST}
+    {-1640982548 -12652 0 NST}
+    {-1632076148 -9052 1 NDT}
+    {-1615145348 -12652 0 NST}
+    {-1609446548 -12652 0 NST}
+    {-1096921748 -12600 0 NST}
+    {-1072989000 -12600 0 NST}
+    {-1061670600 -9000 1 NDT}
+    {-1048973400 -12600 0 NST}
+    {-1030221000 -9000 1 NDT}
+    {-1017523800 -12600 0 NST}
+    {-998771400 -9000 1 NDT}
+    {-986074200 -12600 0 NST}
+    {-966717000 -9000 1 NDT}
+    {-954624600 -12600 0 NST}
+    {-935267400 -9000 1 NDT}
+    {-922570200 -12600 0 NST}
+    {-903817800 -9000 1 NDT}
+    {-891120600 -12600 0 NST}
+    {-872368200 -9000 0 NWT}
+    {-769395600 -9000 1 NPT}
+    {-765401400 -12600 0 NST}
+    {-757369800 -12600 0 NST}
+    {-746044200 -9000 1 NDT}
+    {-733347000 -12600 0 NST}
+    {-714594600 -9000 1 NDT}
+    {-701897400 -12600 0 NST}
+    {-683145000 -9000 1 NDT}
+    {-670447800 -12600 0 NST}
+    {-651695400 -9000 1 NDT}
+    {-638998200 -12600 0 NST}
+    {-619641000 -9000 1 NDT}
+    {-606943800 -12600 0 NST}
+    {-589401000 -9000 1 NDT}
+    {-576099000 -12600 0 NST}
+    {-557951400 -9000 1 NDT}
+    {-544649400 -12600 0 NST}
+    {-526501800 -9000 1 NDT}
+    {-513199800 -12600 0 NST}
+    {-495052200 -9000 1 NDT}
+    {-481750200 -12600 0 NST}
+    {-463602600 -9000 1 NDT}
+    {-450300600 -12600 0 NST}
+    {-431548200 -9000 1 NDT}
+    {-418246200 -12600 0 NST}
+    {-400098600 -9000 1 NDT}
+    {-386796600 -12600 0 NST}
+    {-368649000 -9000 1 NDT}
+    {-355347000 -12600 0 NST}
+    {-337199400 -9000 1 NDT}
+    {-323897400 -12600 0 NST}
+    {-305749800 -9000 1 NDT}
+    {-289423800 -12600 0 NST}
+    {-273695400 -9000 1 NDT}
+    {-257974200 -12600 0 NST}
+    {-242245800 -9000 1 NDT}
+    {-226524600 -12600 0 NST}
+    {-210796200 -9000 1 NDT}
+    {-195075000 -12600 0 NST}
+    {-179346600 -9000 1 NDT}
+    {-163625400 -12600 0 NST}
+    {-147897000 -9000 1 NDT}
+    {-131571000 -12600 0 NST}
+    {-119903400 -14400 0 AST}
+    {-116445600 -10800 1 ADT}
+    {-100119600 -14400 0 AST}
+    {-84391200 -10800 1 ADT}
+    {-68670000 -14400 0 AST}
+    {-52941600 -10800 1 ADT}
+    {-37220400 -14400 0 AST}
+    {-21492000 -10800 1 ADT}
+    {-5770800 -14400 0 AST}
+    {9957600 -10800 1 ADT}
+    {25678800 -14400 0 AST}
+    {41407200 -10800 1 ADT}
+    {57733200 -14400 0 AST}
+    {73461600 -10800 1 ADT}
+    {89182800 -14400 0 AST}
+    {104911200 -10800 1 ADT}
+    {120632400 -14400 0 AST}
+    {136360800 -10800 1 ADT}
+    {152082000 -14400 0 AST}
+    {167810400 -10800 1 ADT}
+    {183531600 -14400 0 AST}
+    {199260000 -10800 1 ADT}
+    {215586000 -14400 0 AST}
+    {230709600 -10800 1 ADT}
+    {247035600 -14400 0 AST}
+    {262764000 -10800 1 ADT}
+    {278485200 -14400 0 AST}
+    {294213600 -10800 1 ADT}
+    {309934800 -14400 0 AST}
+    {325663200 -10800 1 ADT}
+    {341384400 -14400 0 AST}
+    {357112800 -10800 1 ADT}
+    {372834000 -14400 0 AST}
+    {388562400 -10800 1 ADT}
+    {404888400 -14400 0 AST}
+    {420012000 -10800 1 ADT}
+    {436338000 -14400 0 AST}
+    {452066400 -10800 1 ADT}
+    {467787600 -14400 0 AST}
+    {483516000 -10800 1 ADT}
+    {499237200 -14400 0 AST}
+    {514965600 -10800 1 ADT}
+    {530686800 -14400 0 AST}
+    {544593660 -10800 1 ADT}
+    {562129260 -14400 0 AST}
+    {576043260 -7200 1 ADDT}
+    {594180060 -14400 0 AST}
+    {607492860 -10800 1 ADT}
+    {625633260 -14400 0 AST}
+    {638942460 -10800 1 ADT}
+    {657082860 -14400 0 AST}
+    {670996860 -10800 1 ADT}
+    {688532460 -14400 0 AST}
+    {702446460 -10800 1 ADT}
+    {719982060 -14400 0 AST}
+    {733896060 -10800 1 ADT}
+    {752036460 -14400 0 AST}
+    {765345660 -10800 1 ADT}
+    {783486060 -14400 0 AST}
+    {796795260 -10800 1 ADT}
+    {814935660 -14400 0 AST}
+    {828849660 -10800 1 ADT}
+    {846385260 -14400 0 AST}
+    {860299260 -10800 1 ADT}
+    {877834860 -14400 0 AST}
+    {891748860 -10800 1 ADT}
+    {909284460 -14400 0 AST}
+    {923198460 -10800 1 ADT}
+    {941338860 -14400 0 AST}
+    {954648060 -10800 1 ADT}
+    {972788460 -14400 0 AST}
+    {986097660 -10800 1 ADT}
+    {1004238060 -14400 0 AST}
+    {1018152060 -10800 1 ADT}
+    {1035687660 -14400 0 AST}
+    {1049601660 -10800 1 ADT}
+    {1067137260 -14400 0 AST}
+    {1081051260 -10800 1 ADT}
+    {1099191660 -14400 0 AST}
+    {1112500860 -10800 1 ADT}
+    {1130641260 -14400 0 AST}
+    {1143950460 -10800 1 ADT}
+    {1162090860 -14400 0 AST}
+    {1173585660 -10800 1 ADT}
+    {1194145260 -14400 0 AST}
+    {1205035260 -10800 1 ADT}
+    {1225594860 -14400 0 AST}
+    {1236484860 -10800 1 ADT}
+    {1257044460 -14400 0 AST}
+    {1268539260 -10800 1 ADT}
+    {1289098860 -14400 0 AST}
+    {1299988860 -10800 1 ADT}
+    {1320116400 -10800 0 ADT}
+    {1320555600 -14400 0 AST}
+    {1331445600 -10800 1 ADT}
+    {1352005200 -14400 0 AST}
+    {1362895200 -10800 1 ADT}
+    {1383454800 -14400 0 AST}
+    {1394344800 -10800 1 ADT}
+    {1414904400 -14400 0 AST}
+    {1425794400 -10800 1 ADT}
+    {1446354000 -14400 0 AST}
+    {1457848800 -10800 1 ADT}
+    {1478408400 -14400 0 AST}
+    {1489298400 -10800 1 ADT}
+    {1509858000 -14400 0 AST}
+    {1520748000 -10800 1 ADT}
+    {1541307600 -14400 0 AST}
+    {1552197600 -10800 1 ADT}
+    {1572757200 -14400 0 AST}
+    {1583647200 -10800 1 ADT}
+    {1604206800 -14400 0 AST}
+    {1615701600 -10800 1 ADT}
+    {1636261200 -14400 0 AST}
+    {1647151200 -10800 1 ADT}
+    {1667710800 -14400 0 AST}
+    {1678600800 -10800 1 ADT}
+    {1699160400 -14400 0 AST}
+    {1710050400 -10800 1 ADT}
+    {1730610000 -14400 0 AST}
+    {1741500000 -10800 1 ADT}
+    {1762059600 -14400 0 AST}
+    {1772949600 -10800 1 ADT}
+    {1793509200 -14400 0 AST}
+    {1805004000 -10800 1 ADT}
+    {1825563600 -14400 0 AST}
+    {1836453600 -10800 1 ADT}
+    {1857013200 -14400 0 AST}
+    {1867903200 -10800 1 ADT}
+    {1888462800 -14400 0 AST}
+    {1899352800 -10800 1 ADT}
+    {1919912400 -14400 0 AST}
+    {1930802400 -10800 1 ADT}
+    {1951362000 -14400 0 AST}
+    {1962856800 -10800 1 ADT}
+    {1983416400 -14400 0 AST}
+    {1994306400 -10800 1 ADT}
+    {2014866000 -14400 0 AST}
+    {2025756000 -10800 1 ADT}
+    {2046315600 -14400 0 AST}
+    {2057205600 -10800 1 ADT}
+    {2077765200 -14400 0 AST}
+    {2088655200 -10800 1 ADT}
+    {2109214800 -14400 0 AST}
+    {2120104800 -10800 1 ADT}
+    {2140664400 -14400 0 AST}
+    {2152159200 -10800 1 ADT}
+    {2172718800 -14400 0 AST}
+    {2183608800 -10800 1 ADT}
+    {2204168400 -14400 0 AST}
+    {2215058400 -10800 1 ADT}
+    {2235618000 -14400 0 AST}
+    {2246508000 -10800 1 ADT}
+    {2267067600 -14400 0 AST}
+    {2277957600 -10800 1 ADT}
+    {2298517200 -14400 0 AST}
+    {2309407200 -10800 1 ADT}
+    {2329966800 -14400 0 AST}
+    {2341461600 -10800 1 ADT}
+    {2362021200 -14400 0 AST}
+    {2372911200 -10800 1 ADT}
+    {2393470800 -14400 0 AST}
+    {2404360800 -10800 1 ADT}
+    {2424920400 -14400 0 AST}
+    {2435810400 -10800 1 ADT}
+    {2456370000 -14400 0 AST}
+    {2467260000 -10800 1 ADT}
+    {2487819600 -14400 0 AST}
+    {2499314400 -10800 1 ADT}
+    {2519874000 -14400 0 AST}
+    {2530764000 -10800 1 ADT}
+    {2551323600 -14400 0 AST}
+    {2562213600 -10800 1 ADT}
+    {2582773200 -14400 0 AST}
+    {2593663200 -10800 1 ADT}
+    {2614222800 -14400 0 AST}
+    {2625112800 -10800 1 ADT}
+    {2645672400 -14400 0 AST}
+    {2656562400 -10800 1 ADT}
+    {2677122000 -14400 0 AST}
+    {2688616800 -10800 1 ADT}
+    {2709176400 -14400 0 AST}
+    {2720066400 -10800 1 ADT}
+    {2740626000 -14400 0 AST}
+    {2751516000 -10800 1 ADT}
+    {2772075600 -14400 0 AST}
+    {2782965600 -10800 1 ADT}
+    {2803525200 -14400 0 AST}
+    {2814415200 -10800 1 ADT}
+    {2834974800 -14400 0 AST}
+    {2846469600 -10800 1 ADT}
+    {2867029200 -14400 0 AST}
+    {2877919200 -10800 1 ADT}
+    {2898478800 -14400 0 AST}
+    {2909368800 -10800 1 ADT}
+    {2929928400 -14400 0 AST}
+    {2940818400 -10800 1 ADT}
+    {2961378000 -14400 0 AST}
+    {2972268000 -10800 1 ADT}
+    {2992827600 -14400 0 AST}
+    {3003717600 -10800 1 ADT}
+    {3024277200 -14400 0 AST}
+    {3035772000 -10800 1 ADT}
+    {3056331600 -14400 0 AST}
+    {3067221600 -10800 1 ADT}
+    {3087781200 -14400 0 AST}
+    {3098671200 -10800 1 ADT}
+    {3119230800 -14400 0 AST}
+    {3130120800 -10800 1 ADT}
+    {3150680400 -14400 0 AST}
+    {3161570400 -10800 1 ADT}
+    {3182130000 -14400 0 AST}
+    {3193020000 -10800 1 ADT}
+    {3213579600 -14400 0 AST}
+    {3225074400 -10800 1 ADT}
+    {3245634000 -14400 0 AST}
+    {3256524000 -10800 1 ADT}
+    {3277083600 -14400 0 AST}
+    {3287973600 -10800 1 ADT}
+    {3308533200 -14400 0 AST}
+    {3319423200 -10800 1 ADT}
+    {3339982800 -14400 0 AST}
+    {3350872800 -10800 1 ADT}
+    {3371432400 -14400 0 AST}
+    {3382927200 -10800 1 ADT}
+    {3403486800 -14400 0 AST}
+    {3414376800 -10800 1 ADT}
+    {3434936400 -14400 0 AST}
+    {3445826400 -10800 1 ADT}
+    {3466386000 -14400 0 AST}
+    {3477276000 -10800 1 ADT}
+    {3497835600 -14400 0 AST}
+    {3508725600 -10800 1 ADT}
+    {3529285200 -14400 0 AST}
+    {3540175200 -10800 1 ADT}
+    {3560734800 -14400 0 AST}
+    {3572229600 -10800 1 ADT}
+    {3592789200 -14400 0 AST}
+    {3603679200 -10800 1 ADT}
+    {3624238800 -14400 0 AST}
+    {3635128800 -10800 1 ADT}
+    {3655688400 -14400 0 AST}
+    {3666578400 -10800 1 ADT}
+    {3687138000 -14400 0 AST}
+    {3698028000 -10800 1 ADT}
+    {3718587600 -14400 0 AST}
+    {3730082400 -10800 1 ADT}
+    {3750642000 -14400 0 AST}
+    {3761532000 -10800 1 ADT}
+    {3782091600 -14400 0 AST}
+    {3792981600 -10800 1 ADT}
+    {3813541200 -14400 0 AST}
+    {3824431200 -10800 1 ADT}
+    {3844990800 -14400 0 AST}
+    {3855880800 -10800 1 ADT}
+    {3876440400 -14400 0 AST}
+    {3887330400 -10800 1 ADT}
+    {3907890000 -14400 0 AST}
+    {3919384800 -10800 1 ADT}
+    {3939944400 -14400 0 AST}
+    {3950834400 -10800 1 ADT}
+    {3971394000 -14400 0 AST}
+    {3982284000 -10800 1 ADT}
+    {4002843600 -14400 0 AST}
+    {4013733600 -10800 1 ADT}
+    {4034293200 -14400 0 AST}
+    {4045183200 -10800 1 ADT}
+    {4065742800 -14400 0 AST}
+    {4076632800 -10800 1 ADT}
+    {4097192400 -14400 0 AST}
+}
diff --git a/library/tzdata/America/Grand_Turk b/library/tzdata/America/Grand_Turk
new file mode 100644
index 0000000..0edcf0b
--- /dev/null
+++ b/library/tzdata/America/Grand_Turk
@@ -0,0 +1,82 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Grand_Turk) {
+    {-9223372036854775808 -17072 0 LMT}
+    {-2524504528 -18431 0 KMT}
+    {-1827687169 -18000 0 EST}
+    {284014800 -18000 0 EST}
+    {294217200 -14400 1 EDT}
+    {309938400 -18000 0 EST}
+    {325666800 -14400 1 EDT}
+    {341388000 -18000 0 EST}
+    {357116400 -14400 1 EDT}
+    {372837600 -18000 0 EST}
+    {388566000 -14400 1 EDT}
+    {404892000 -18000 0 EST}
+    {420015600 -14400 1 EDT}
+    {436341600 -18000 0 EST}
+    {452070000 -14400 1 EDT}
+    {467791200 -18000 0 EST}
+    {483519600 -14400 1 EDT}
+    {499240800 -18000 0 EST}
+    {514969200 -14400 1 EDT}
+    {530690400 -18000 0 EST}
+    {544604400 -14400 1 EDT}
+    {562140000 -18000 0 EST}
+    {576054000 -14400 1 EDT}
+    {594194400 -18000 0 EST}
+    {607503600 -14400 1 EDT}
+    {625644000 -18000 0 EST}
+    {638953200 -14400 1 EDT}
+    {657093600 -18000 0 EST}
+    {671007600 -14400 1 EDT}
+    {688543200 -18000 0 EST}
+    {702457200 -14400 1 EDT}
+    {719992800 -18000 0 EST}
+    {733906800 -14400 1 EDT}
+    {752047200 -18000 0 EST}
+    {765356400 -14400 1 EDT}
+    {783496800 -18000 0 EST}
+    {796806000 -14400 1 EDT}
+    {814946400 -18000 0 EST}
+    {828860400 -14400 1 EDT}
+    {846396000 -18000 0 EST}
+    {860310000 -14400 1 EDT}
+    {877845600 -18000 0 EST}
+    {891759600 -14400 1 EDT}
+    {909295200 -18000 0 EST}
+    {923209200 -14400 1 EDT}
+    {941349600 -18000 0 EST}
+    {954658800 -14400 1 EDT}
+    {972799200 -18000 0 EST}
+    {986108400 -14400 1 EDT}
+    {1004248800 -18000 0 EST}
+    {1018162800 -14400 1 EDT}
+    {1035698400 -18000 0 EST}
+    {1049612400 -14400 1 EDT}
+    {1067148000 -18000 0 EST}
+    {1081062000 -14400 1 EDT}
+    {1099202400 -18000 0 EST}
+    {1112511600 -14400 1 EDT}
+    {1130652000 -18000 0 EST}
+    {1143961200 -14400 1 EDT}
+    {1162101600 -18000 0 EST}
+    {1173596400 -14400 1 EDT}
+    {1194156000 -18000 0 EST}
+    {1205046000 -14400 1 EDT}
+    {1225605600 -18000 0 EST}
+    {1236495600 -14400 1 EDT}
+    {1257055200 -18000 0 EST}
+    {1268550000 -14400 1 EDT}
+    {1289109600 -18000 0 EST}
+    {1299999600 -14400 1 EDT}
+    {1320559200 -18000 0 EST}
+    {1331449200 -14400 1 EDT}
+    {1352008800 -18000 0 EST}
+    {1362898800 -14400 1 EDT}
+    {1383458400 -18000 0 EST}
+    {1394348400 -14400 1 EDT}
+    {1414908000 -18000 0 EST}
+    {1425798000 -14400 1 EDT}
+    {1446361200 -14400 0 AST}
+}
diff --git a/library/tzdata/America/Grenada b/library/tzdata/America/Grenada
new file mode 100644
index 0000000..92300c3
--- /dev/null
+++ b/library/tzdata/America/Grenada
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(America/Port_of_Spain)]} {
+    LoadTimeZoneFile America/Port_of_Spain
+}
+set TZData(:America/Grenada) $TZData(:America/Port_of_Spain)
diff --git a/library/tzdata/America/Guadeloupe b/library/tzdata/America/Guadeloupe
new file mode 100644
index 0000000..aba6bd7
--- /dev/null
+++ b/library/tzdata/America/Guadeloupe
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(America/Port_of_Spain)]} {
+    LoadTimeZoneFile America/Port_of_Spain
+}
+set TZData(:America/Guadeloupe) $TZData(:America/Port_of_Spain)
diff --git a/library/tzdata/America/Guatemala b/library/tzdata/America/Guatemala
new file mode 100644
index 0000000..e4db5ac
--- /dev/null
+++ b/library/tzdata/America/Guatemala
@@ -0,0 +1,14 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Guatemala) {
+    {-9223372036854775808 -21724 0 LMT}
+    {-1617040676 -21600 0 CST}
+    {123055200 -18000 1 CDT}
+    {130914000 -21600 0 CST}
+    {422344800 -18000 1 CDT}
+    {433054800 -21600 0 CST}
+    {669708000 -18000 1 CDT}
+    {684219600 -21600 0 CST}
+    {1146376800 -18000 1 CDT}
+    {1159678800 -21600 0 CST}
+}
diff --git a/library/tzdata/America/Guayaquil b/library/tzdata/America/Guayaquil
new file mode 100644
index 0000000..e940a5b
--- /dev/null
+++ b/library/tzdata/America/Guayaquil
@@ -0,0 +1,7 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Guayaquil) {
+    {-9223372036854775808 -19160 0 LMT}
+    {-2524502440 -18840 0 QMT}
+    {-1230749160 -18000 0 ECT}
+}
diff --git a/library/tzdata/America/Guyana b/library/tzdata/America/Guyana
new file mode 100644
index 0000000..c58a989
--- /dev/null
+++ b/library/tzdata/America/Guyana
@@ -0,0 +1,9 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Guyana) {
+    {-9223372036854775808 -13960 0 LMT}
+    {-1730578040 -13500 0 GBGT}
+    {-113688900 -13500 0 GYT}
+    {176010300 -10800 0 GYT}
+    {662698800 -14400 0 GYT}
+}
diff --git a/library/tzdata/America/Halifax b/library/tzdata/America/Halifax
new file mode 100644
index 0000000..08e3754
--- /dev/null
+++ b/library/tzdata/America/Halifax
@@ -0,0 +1,361 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Halifax) {
+    {-9223372036854775808 -15264 0 LMT}
+    {-2131645536 -14400 0 AST}
+    {-1696276800 -10800 1 ADT}
+    {-1680469200 -14400 0 AST}
+    {-1640980800 -14400 0 AST}
+    {-1632074400 -10800 1 ADT}
+    {-1615143600 -14400 0 AST}
+    {-1609444800 -14400 0 AST}
+    {-1566763200 -10800 1 ADT}
+    {-1557090000 -14400 0 AST}
+    {-1535486400 -10800 1 ADT}
+    {-1524949200 -14400 0 AST}
+    {-1504468800 -10800 1 ADT}
+    {-1493413200 -14400 0 AST}
+    {-1472414400 -10800 1 ADT}
+    {-1461963600 -14400 0 AST}
+    {-1440964800 -10800 1 ADT}
+    {-1429390800 -14400 0 AST}
+    {-1409515200 -10800 1 ADT}
+    {-1396731600 -14400 0 AST}
+    {-1376856000 -10800 1 ADT}
+    {-1366491600 -14400 0 AST}
+    {-1346616000 -10800 1 ADT}
+    {-1333832400 -14400 0 AST}
+    {-1313956800 -10800 1 ADT}
+    {-1303678800 -14400 0 AST}
+    {-1282507200 -10800 1 ADT}
+    {-1272661200 -14400 0 AST}
+    {-1251057600 -10800 1 ADT}
+    {-1240088400 -14400 0 AST}
+    {-1219608000 -10800 1 ADT}
+    {-1207429200 -14400 0 AST}
+    {-1188763200 -10800 1 ADT}
+    {-1175979600 -14400 0 AST}
+    {-1157313600 -10800 1 ADT}
+    {-1143925200 -14400 0 AST}
+    {-1124049600 -10800 1 ADT}
+    {-1113771600 -14400 0 AST}
+    {-1091390400 -10800 1 ADT}
+    {-1081026000 -14400 0 AST}
+    {-1059854400 -10800 1 ADT}
+    {-1050786000 -14400 0 AST}
+    {-1030910400 -10800 1 ADT}
+    {-1018126800 -14400 0 AST}
+    {-999460800 -10800 1 ADT}
+    {-986677200 -14400 0 AST}
+    {-965592000 -10800 1 ADT}
+    {-955227600 -14400 0 AST}
+    {-935956800 -10800 1 ADT}
+    {-923173200 -14400 0 AST}
+    {-904507200 -10800 1 ADT}
+    {-891723600 -14400 0 AST}
+    {-880221600 -10800 0 AWT}
+    {-769395600 -10800 1 APT}
+    {-765399600 -14400 0 AST}
+    {-757368000 -14400 0 AST}
+    {-747252000 -10800 1 ADT}
+    {-733950000 -14400 0 AST}
+    {-715802400 -10800 1 ADT}
+    {-702500400 -14400 0 AST}
+    {-684352800 -10800 1 ADT}
+    {-671050800 -14400 0 AST}
+    {-652903200 -10800 1 ADT}
+    {-639601200 -14400 0 AST}
+    {-589399200 -10800 1 ADT}
+    {-576097200 -14400 0 AST}
+    {-557949600 -10800 1 ADT}
+    {-544647600 -14400 0 AST}
+    {-526500000 -10800 1 ADT}
+    {-513198000 -14400 0 AST}
+    {-495050400 -10800 1 ADT}
+    {-481748400 -14400 0 AST}
+    {-431546400 -10800 1 ADT}
+    {-418244400 -14400 0 AST}
+    {-400096800 -10800 1 ADT}
+    {-386794800 -14400 0 AST}
+    {-368647200 -10800 1 ADT}
+    {-355345200 -14400 0 AST}
+    {-337197600 -10800 1 ADT}
+    {-323895600 -14400 0 AST}
+    {-242244000 -10800 1 ADT}
+    {-226522800 -14400 0 AST}
+    {-210794400 -10800 1 ADT}
+    {-195073200 -14400 0 AST}
+    {-179344800 -10800 1 ADT}
+    {-163623600 -14400 0 AST}
+    {-147895200 -10800 1 ADT}
+    {-131569200 -14400 0 AST}
+    {-116445600 -10800 1 ADT}
+    {-100119600 -14400 0 AST}
+    {-84391200 -10800 1 ADT}
+    {-68670000 -14400 0 AST}
+    {-52941600 -10800 1 ADT}
+    {-37220400 -14400 0 AST}
+    {-21492000 -10800 1 ADT}
+    {-5770800 -14400 0 AST}
+    {9957600 -10800 1 ADT}
+    {25678800 -14400 0 AST}
+    {41407200 -10800 1 ADT}
+    {57733200 -14400 0 AST}
+    {73461600 -10800 1 ADT}
+    {89182800 -14400 0 AST}
+    {104911200 -10800 1 ADT}
+    {120632400 -14400 0 AST}
+    {126244800 -14400 0 AST}
+    {136360800 -10800 1 ADT}
+    {152082000 -14400 0 AST}
+    {167810400 -10800 1 ADT}
+    {183531600 -14400 0 AST}
+    {199260000 -10800 1 ADT}
+    {215586000 -14400 0 AST}
+    {230709600 -10800 1 ADT}
+    {247035600 -14400 0 AST}
+    {262764000 -10800 1 ADT}
+    {278485200 -14400 0 AST}
+    {294213600 -10800 1 ADT}
+    {309934800 -14400 0 AST}
+    {325663200 -10800 1 ADT}
+    {341384400 -14400 0 AST}
+    {357112800 -10800 1 ADT}
+    {372834000 -14400 0 AST}
+    {388562400 -10800 1 ADT}
+    {404888400 -14400 0 AST}
+    {420012000 -10800 1 ADT}
+    {436338000 -14400 0 AST}
+    {452066400 -10800 1 ADT}
+    {467787600 -14400 0 AST}
+    {483516000 -10800 1 ADT}
+    {499237200 -14400 0 AST}
+    {514965600 -10800 1 ADT}
+    {530686800 -14400 0 AST}
+    {544600800 -10800 1 ADT}
+    {562136400 -14400 0 AST}
+    {576050400 -10800 1 ADT}
+    {594190800 -14400 0 AST}
+    {607500000 -10800 1 ADT}
+    {625640400 -14400 0 AST}
+    {638949600 -10800 1 ADT}
+    {657090000 -14400 0 AST}
+    {671004000 -10800 1 ADT}
+    {688539600 -14400 0 AST}
+    {702453600 -10800 1 ADT}
+    {719989200 -14400 0 AST}
+    {733903200 -10800 1 ADT}
+    {752043600 -14400 0 AST}
+    {765352800 -10800 1 ADT}
+    {783493200 -14400 0 AST}
+    {796802400 -10800 1 ADT}
+    {814942800 -14400 0 AST}
+    {828856800 -10800 1 ADT}
+    {846392400 -14400 0 AST}
+    {860306400 -10800 1 ADT}
+    {877842000 -14400 0 AST}
+    {891756000 -10800 1 ADT}
+    {909291600 -14400 0 AST}
+    {923205600 -10800 1 ADT}
+    {941346000 -14400 0 AST}
+    {954655200 -10800 1 ADT}
+    {972795600 -14400 0 AST}
+    {986104800 -10800 1 ADT}
+    {1004245200 -14400 0 AST}
+    {1018159200 -10800 1 ADT}
+    {1035694800 -14400 0 AST}
+    {1049608800 -10800 1 ADT}
+    {1067144400 -14400 0 AST}
+    {1081058400 -10800 1 ADT}
+    {1099198800 -14400 0 AST}
+    {1112508000 -10800 1 ADT}
+    {1130648400 -14400 0 AST}
+    {1143957600 -10800 1 ADT}
+    {1162098000 -14400 0 AST}
+    {1173592800 -10800 1 ADT}
+    {1194152400 -14400 0 AST}
+    {1205042400 -10800 1 ADT}
+    {1225602000 -14400 0 AST}
+    {1236492000 -10800 1 ADT}
+    {1257051600 -14400 0 AST}
+    {1268546400 -10800 1 ADT}
+    {1289106000 -14400 0 AST}
+    {1299996000 -10800 1 ADT}
+    {1320555600 -14400 0 AST}
+    {1331445600 -10800 1 ADT}
+    {1352005200 -14400 0 AST}
+    {1362895200 -10800 1 ADT}
+    {1383454800 -14400 0 AST}
+    {1394344800 -10800 1 ADT}
+    {1414904400 -14400 0 AST}
+    {1425794400 -10800 1 ADT}
+    {1446354000 -14400 0 AST}
+    {1457848800 -10800 1 ADT}
+    {1478408400 -14400 0 AST}
+    {1489298400 -10800 1 ADT}
+    {1509858000 -14400 0 AST}
+    {1520748000 -10800 1 ADT}
+    {1541307600 -14400 0 AST}
+    {1552197600 -10800 1 ADT}
+    {1572757200 -14400 0 AST}
+    {1583647200 -10800 1 ADT}
+    {1604206800 -14400 0 AST}
+    {1615701600 -10800 1 ADT}
+    {1636261200 -14400 0 AST}
+    {1647151200 -10800 1 ADT}
+    {1667710800 -14400 0 AST}
+    {1678600800 -10800 1 ADT}
+    {1699160400 -14400 0 AST}
+    {1710050400 -10800 1 ADT}
+    {1730610000 -14400 0 AST}
+    {1741500000 -10800 1 ADT}
+    {1762059600 -14400 0 AST}
+    {1772949600 -10800 1 ADT}
+    {1793509200 -14400 0 AST}
+    {1805004000 -10800 1 ADT}
+    {1825563600 -14400 0 AST}
+    {1836453600 -10800 1 ADT}
+    {1857013200 -14400 0 AST}
+    {1867903200 -10800 1 ADT}
+    {1888462800 -14400 0 AST}
+    {1899352800 -10800 1 ADT}
+    {1919912400 -14400 0 AST}
+    {1930802400 -10800 1 ADT}
+    {1951362000 -14400 0 AST}
+    {1962856800 -10800 1 ADT}
+    {1983416400 -14400 0 AST}
+    {1994306400 -10800 1 ADT}
+    {2014866000 -14400 0 AST}
+    {2025756000 -10800 1 ADT}
+    {2046315600 -14400 0 AST}
+    {2057205600 -10800 1 ADT}
+    {2077765200 -14400 0 AST}
+    {2088655200 -10800 1 ADT}
+    {2109214800 -14400 0 AST}
+    {2120104800 -10800 1 ADT}
+    {2140664400 -14400 0 AST}
+    {2152159200 -10800 1 ADT}
+    {2172718800 -14400 0 AST}
+    {2183608800 -10800 1 ADT}
+    {2204168400 -14400 0 AST}
+    {2215058400 -10800 1 ADT}
+    {2235618000 -14400 0 AST}
+    {2246508000 -10800 1 ADT}
+    {2267067600 -14400 0 AST}
+    {2277957600 -10800 1 ADT}
+    {2298517200 -14400 0 AST}
+    {2309407200 -10800 1 ADT}
+    {2329966800 -14400 0 AST}
+    {2341461600 -10800 1 ADT}
+    {2362021200 -14400 0 AST}
+    {2372911200 -10800 1 ADT}
+    {2393470800 -14400 0 AST}
+    {2404360800 -10800 1 ADT}
+    {2424920400 -14400 0 AST}
+    {2435810400 -10800 1 ADT}
+    {2456370000 -14400 0 AST}
+    {2467260000 -10800 1 ADT}
+    {2487819600 -14400 0 AST}
+    {2499314400 -10800 1 ADT}
+    {2519874000 -14400 0 AST}
+    {2530764000 -10800 1 ADT}
+    {2551323600 -14400 0 AST}
+    {2562213600 -10800 1 ADT}
+    {2582773200 -14400 0 AST}
+    {2593663200 -10800 1 ADT}
+    {2614222800 -14400 0 AST}
+    {2625112800 -10800 1 ADT}
+    {2645672400 -14400 0 AST}
+    {2656562400 -10800 1 ADT}
+    {2677122000 -14400 0 AST}
+    {2688616800 -10800 1 ADT}
+    {2709176400 -14400 0 AST}
+    {2720066400 -10800 1 ADT}
+    {2740626000 -14400 0 AST}
+    {2751516000 -10800 1 ADT}
+    {2772075600 -14400 0 AST}
+    {2782965600 -10800 1 ADT}
+    {2803525200 -14400 0 AST}
+    {2814415200 -10800 1 ADT}
+    {2834974800 -14400 0 AST}
+    {2846469600 -10800 1 ADT}
+    {2867029200 -14400 0 AST}
+    {2877919200 -10800 1 ADT}
+    {2898478800 -14400 0 AST}
+    {2909368800 -10800 1 ADT}
+    {2929928400 -14400 0 AST}
+    {2940818400 -10800 1 ADT}
+    {2961378000 -14400 0 AST}
+    {2972268000 -10800 1 ADT}
+    {2992827600 -14400 0 AST}
+    {3003717600 -10800 1 ADT}
+    {3024277200 -14400 0 AST}
+    {3035772000 -10800 1 ADT}
+    {3056331600 -14400 0 AST}
+    {3067221600 -10800 1 ADT}
+    {3087781200 -14400 0 AST}
+    {3098671200 -10800 1 ADT}
+    {3119230800 -14400 0 AST}
+    {3130120800 -10800 1 ADT}
+    {3150680400 -14400 0 AST}
+    {3161570400 -10800 1 ADT}
+    {3182130000 -14400 0 AST}
+    {3193020000 -10800 1 ADT}
+    {3213579600 -14400 0 AST}
+    {3225074400 -10800 1 ADT}
+    {3245634000 -14400 0 AST}
+    {3256524000 -10800 1 ADT}
+    {3277083600 -14400 0 AST}
+    {3287973600 -10800 1 ADT}
+    {3308533200 -14400 0 AST}
+    {3319423200 -10800 1 ADT}
+    {3339982800 -14400 0 AST}
+    {3350872800 -10800 1 ADT}
+    {3371432400 -14400 0 AST}
+    {3382927200 -10800 1 ADT}
+    {3403486800 -14400 0 AST}
+    {3414376800 -10800 1 ADT}
+    {3434936400 -14400 0 AST}
+    {3445826400 -10800 1 ADT}
+    {3466386000 -14400 0 AST}
+    {3477276000 -10800 1 ADT}
+    {3497835600 -14400 0 AST}
+    {3508725600 -10800 1 ADT}
+    {3529285200 -14400 0 AST}
+    {3540175200 -10800 1 ADT}
+    {3560734800 -14400 0 AST}
+    {3572229600 -10800 1 ADT}
+    {3592789200 -14400 0 AST}
+    {3603679200 -10800 1 ADT}
+    {3624238800 -14400 0 AST}
+    {3635128800 -10800 1 ADT}
+    {3655688400 -14400 0 AST}
+    {3666578400 -10800 1 ADT}
+    {3687138000 -14400 0 AST}
+    {3698028000 -10800 1 ADT}
+    {3718587600 -14400 0 AST}
+    {3730082400 -10800 1 ADT}
+    {3750642000 -14400 0 AST}
+    {3761532000 -10800 1 ADT}
+    {3782091600 -14400 0 AST}
+    {3792981600 -10800 1 ADT}
+    {3813541200 -14400 0 AST}
+    {3824431200 -10800 1 ADT}
+    {3844990800 -14400 0 AST}
+    {3855880800 -10800 1 ADT}
+    {3876440400 -14400 0 AST}
+    {3887330400 -10800 1 ADT}
+    {3907890000 -14400 0 AST}
+    {3919384800 -10800 1 ADT}
+    {3939944400 -14400 0 AST}
+    {3950834400 -10800 1 ADT}
+    {3971394000 -14400 0 AST}
+    {3982284000 -10800 1 ADT}
+    {4002843600 -14400 0 AST}
+    {4013733600 -10800 1 ADT}
+    {4034293200 -14400 0 AST}
+    {4045183200 -10800 1 ADT}
+    {4065742800 -14400 0 AST}
+    {4076632800 -10800 1 ADT}
+    {4097192400 -14400 0 AST}
+}
diff --git a/library/tzdata/America/Havana b/library/tzdata/America/Havana
new file mode 100644
index 0000000..5901dae
--- /dev/null
+++ b/library/tzdata/America/Havana
@@ -0,0 +1,285 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Havana) {
+    {-9223372036854775808 -19768 0 LMT}
+    {-2524501832 -19776 0 HMT}
+    {-1402813824 -18000 0 CST}
+    {-1311534000 -14400 1 CDT}
+    {-1300996800 -18000 0 CST}
+    {-933534000 -14400 1 CDT}
+    {-925675200 -18000 0 CST}
+    {-902084400 -14400 1 CDT}
+    {-893620800 -18000 0 CST}
+    {-870030000 -14400 1 CDT}
+    {-862171200 -18000 0 CST}
+    {-775681200 -14400 1 CDT}
+    {-767822400 -18000 0 CST}
+    {-744231600 -14400 1 CDT}
+    {-736372800 -18000 0 CST}
+    {-144702000 -14400 1 CDT}
+    {-134251200 -18000 0 CST}
+    {-113425200 -14400 1 CDT}
+    {-102542400 -18000 0 CST}
+    {-86295600 -14400 1 CDT}
+    {-72907200 -18000 0 CST}
+    {-54154800 -14400 1 CDT}
+    {-41457600 -18000 0 CST}
+    {-21495600 -14400 1 CDT}
+    {-5774400 -18000 0 CST}
+    {9954000 -14400 1 CDT}
+    {25675200 -18000 0 CST}
+    {41403600 -14400 1 CDT}
+    {57729600 -18000 0 CST}
+    {73458000 -14400 1 CDT}
+    {87364800 -18000 0 CST}
+    {104907600 -14400 1 CDT}
+    {118900800 -18000 0 CST}
+    {136357200 -14400 1 CDT}
+    {150436800 -18000 0 CST}
+    {167806800 -14400 1 CDT}
+    {183528000 -18000 0 CST}
+    {199256400 -14400 1 CDT}
+    {215582400 -18000 0 CST}
+    {230706000 -14400 1 CDT}
+    {247032000 -18000 0 CST}
+    {263365200 -14400 1 CDT}
+    {276667200 -18000 0 CST}
+    {290581200 -14400 1 CDT}
+    {308721600 -18000 0 CST}
+    {322030800 -14400 1 CDT}
+    {340171200 -18000 0 CST}
+    {358318800 -14400 1 CDT}
+    {371620800 -18000 0 CST}
+    {389768400 -14400 1 CDT}
+    {403070400 -18000 0 CST}
+    {421218000 -14400 1 CDT}
+    {434520000 -18000 0 CST}
+    {452667600 -14400 1 CDT}
+    {466574400 -18000 0 CST}
+    {484117200 -14400 1 CDT}
+    {498024000 -18000 0 CST}
+    {511333200 -14400 1 CDT}
+    {529473600 -18000 0 CST}
+    {542782800 -14400 1 CDT}
+    {560923200 -18000 0 CST}
+    {574837200 -14400 1 CDT}
+    {592372800 -18000 0 CST}
+    {606286800 -14400 1 CDT}
+    {623822400 -18000 0 CST}
+    {638946000 -14400 1 CDT}
+    {655876800 -18000 0 CST}
+    {671000400 -14400 1 CDT}
+    {687330000 -18000 0 CST}
+    {702450000 -14400 1 CDT}
+    {718779600 -18000 0 CST}
+    {733899600 -14400 1 CDT}
+    {750229200 -18000 0 CST}
+    {765349200 -14400 1 CDT}
+    {781678800 -18000 0 CST}
+    {796798800 -14400 1 CDT}
+    {813128400 -18000 0 CST}
+    {828853200 -14400 1 CDT}
+    {844578000 -18000 0 CST}
+    {860302800 -14400 1 CDT}
+    {876632400 -18000 0 CST}
+    {891147600 -14400 1 CDT}
+    {909291600 -18000 0 CST}
+    {922597200 -14400 1 CDT}
+    {941346000 -18000 0 CST}
+    {954651600 -14400 1 CDT}
+    {972795600 -18000 0 CST}
+    {986101200 -14400 1 CDT}
+    {1004245200 -18000 0 CST}
+    {1018155600 -14400 1 CDT}
+    {1035694800 -18000 0 CST}
+    {1049605200 -14400 1 CDT}
+    {1067144400 -18000 0 CST}
+    {1080450000 -14400 1 CDT}
+    {1162098000 -18000 0 CST}
+    {1173589200 -14400 1 CDT}
+    {1193547600 -18000 0 CST}
+    {1205643600 -14400 1 CDT}
+    {1224997200 -18000 0 CST}
+    {1236488400 -14400 1 CDT}
+    {1256446800 -18000 0 CST}
+    {1268542800 -14400 1 CDT}
+    {1288501200 -18000 0 CST}
+    {1300597200 -14400 1 CDT}
+    {1321160400 -18000 0 CST}
+    {1333256400 -14400 1 CDT}
+    {1352005200 -18000 0 CST}
+    {1362891600 -14400 1 CDT}
+    {1383454800 -18000 0 CST}
+    {1394341200 -14400 1 CDT}
+    {1414904400 -18000 0 CST}
+    {1425790800 -14400 1 CDT}
+    {1446354000 -18000 0 CST}
+    {1457845200 -14400 1 CDT}
+    {1478408400 -18000 0 CST}
+    {1489294800 -14400 1 CDT}
+    {1509858000 -18000 0 CST}
+    {1520744400 -14400 1 CDT}
+    {1541307600 -18000 0 CST}
+    {1552194000 -14400 1 CDT}
+    {1572757200 -18000 0 CST}
+    {1583643600 -14400 1 CDT}
+    {1604206800 -18000 0 CST}
+    {1615698000 -14400 1 CDT}
+    {1636261200 -18000 0 CST}
+    {1647147600 -14400 1 CDT}
+    {1667710800 -18000 0 CST}
+    {1678597200 -14400 1 CDT}
+    {1699160400 -18000 0 CST}
+    {1710046800 -14400 1 CDT}
+    {1730610000 -18000 0 CST}
+    {1741496400 -14400 1 CDT}
+    {1762059600 -18000 0 CST}
+    {1772946000 -14400 1 CDT}
+    {1793509200 -18000 0 CST}
+    {1805000400 -14400 1 CDT}
+    {1825563600 -18000 0 CST}
+    {1836450000 -14400 1 CDT}
+    {1857013200 -18000 0 CST}
+    {1867899600 -14400 1 CDT}
+    {1888462800 -18000 0 CST}
+    {1899349200 -14400 1 CDT}
+    {1919912400 -18000 0 CST}
+    {1930798800 -14400 1 CDT}
+    {1951362000 -18000 0 CST}
+    {1962853200 -14400 1 CDT}
+    {1983416400 -18000 0 CST}
+    {1994302800 -14400 1 CDT}
+    {2014866000 -18000 0 CST}
+    {2025752400 -14400 1 CDT}
+    {2046315600 -18000 0 CST}
+    {2057202000 -14400 1 CDT}
+    {2077765200 -18000 0 CST}
+    {2088651600 -14400 1 CDT}
+    {2109214800 -18000 0 CST}
+    {2120101200 -14400 1 CDT}
+    {2140664400 -18000 0 CST}
+    {2152155600 -14400 1 CDT}
+    {2172718800 -18000 0 CST}
+    {2183605200 -14400 1 CDT}
+    {2204168400 -18000 0 CST}
+    {2215054800 -14400 1 CDT}
+    {2235618000 -18000 0 CST}
+    {2246504400 -14400 1 CDT}
+    {2267067600 -18000 0 CST}
+    {2277954000 -14400 1 CDT}
+    {2298517200 -18000 0 CST}
+    {2309403600 -14400 1 CDT}
+    {2329966800 -18000 0 CST}
+    {2341458000 -14400 1 CDT}
+    {2362021200 -18000 0 CST}
+    {2372907600 -14400 1 CDT}
+    {2393470800 -18000 0 CST}
+    {2404357200 -14400 1 CDT}
+    {2424920400 -18000 0 CST}
+    {2435806800 -14400 1 CDT}
+    {2456370000 -18000 0 CST}
+    {2467256400 -14400 1 CDT}
+    {2487819600 -18000 0 CST}
+    {2499310800 -14400 1 CDT}
+    {2519874000 -18000 0 CST}
+    {2530760400 -14400 1 CDT}
+    {2551323600 -18000 0 CST}
+    {2562210000 -14400 1 CDT}
+    {2582773200 -18000 0 CST}
+    {2593659600 -14400 1 CDT}
+    {2614222800 -18000 0 CST}
+    {2625109200 -14400 1 CDT}
+    {2645672400 -18000 0 CST}
+    {2656558800 -14400 1 CDT}
+    {2677122000 -18000 0 CST}
+    {2688613200 -14400 1 CDT}
+    {2709176400 -18000 0 CST}
+    {2720062800 -14400 1 CDT}
+    {2740626000 -18000 0 CST}
+    {2751512400 -14400 1 CDT}
+    {2772075600 -18000 0 CST}
+    {2782962000 -14400 1 CDT}
+    {2803525200 -18000 0 CST}
+    {2814411600 -14400 1 CDT}
+    {2834974800 -18000 0 CST}
+    {2846466000 -14400 1 CDT}
+    {2867029200 -18000 0 CST}
+    {2877915600 -14400 1 CDT}
+    {2898478800 -18000 0 CST}
+    {2909365200 -14400 1 CDT}
+    {2929928400 -18000 0 CST}
+    {2940814800 -14400 1 CDT}
+    {2961378000 -18000 0 CST}
+    {2972264400 -14400 1 CDT}
+    {2992827600 -18000 0 CST}
+    {3003714000 -14400 1 CDT}
+    {3024277200 -18000 0 CST}
+    {3035768400 -14400 1 CDT}
+    {3056331600 -18000 0 CST}
+    {3067218000 -14400 1 CDT}
+    {3087781200 -18000 0 CST}
+    {3098667600 -14400 1 CDT}
+    {3119230800 -18000 0 CST}
+    {3130117200 -14400 1 CDT}
+    {3150680400 -18000 0 CST}
+    {3161566800 -14400 1 CDT}
+    {3182130000 -18000 0 CST}
+    {3193016400 -14400 1 CDT}
+    {3213579600 -18000 0 CST}
+    {3225070800 -14400 1 CDT}
+    {3245634000 -18000 0 CST}
+    {3256520400 -14400 1 CDT}
+    {3277083600 -18000 0 CST}
+    {3287970000 -14400 1 CDT}
+    {3308533200 -18000 0 CST}
+    {3319419600 -14400 1 CDT}
+    {3339982800 -18000 0 CST}
+    {3350869200 -14400 1 CDT}
+    {3371432400 -18000 0 CST}
+    {3382923600 -14400 1 CDT}
+    {3403486800 -18000 0 CST}
+    {3414373200 -14400 1 CDT}
+    {3434936400 -18000 0 CST}
+    {3445822800 -14400 1 CDT}
+    {3466386000 -18000 0 CST}
+    {3477272400 -14400 1 CDT}
+    {3497835600 -18000 0 CST}
+    {3508722000 -14400 1 CDT}
+    {3529285200 -18000 0 CST}
+    {3540171600 -14400 1 CDT}
+    {3560734800 -18000 0 CST}
+    {3572226000 -14400 1 CDT}
+    {3592789200 -18000 0 CST}
+    {3603675600 -14400 1 CDT}
+    {3624238800 -18000 0 CST}
+    {3635125200 -14400 1 CDT}
+    {3655688400 -18000 0 CST}
+    {3666574800 -14400 1 CDT}
+    {3687138000 -18000 0 CST}
+    {3698024400 -14400 1 CDT}
+    {3718587600 -18000 0 CST}
+    {3730078800 -14400 1 CDT}
+    {3750642000 -18000 0 CST}
+    {3761528400 -14400 1 CDT}
+    {3782091600 -18000 0 CST}
+    {3792978000 -14400 1 CDT}
+    {3813541200 -18000 0 CST}
+    {3824427600 -14400 1 CDT}
+    {3844990800 -18000 0 CST}
+    {3855877200 -14400 1 CDT}
+    {3876440400 -18000 0 CST}
+    {3887326800 -14400 1 CDT}
+    {3907890000 -18000 0 CST}
+    {3919381200 -14400 1 CDT}
+    {3939944400 -18000 0 CST}
+    {3950830800 -14400 1 CDT}
+    {3971394000 -18000 0 CST}
+    {3982280400 -14400 1 CDT}
+    {4002843600 -18000 0 CST}
+    {4013730000 -14400 1 CDT}
+    {4034293200 -18000 0 CST}
+    {4045179600 -14400 1 CDT}
+    {4065742800 -18000 0 CST}
+    {4076629200 -14400 1 CDT}
+    {4097192400 -18000 0 CST}
+}
diff --git a/library/tzdata/America/Hermosillo b/library/tzdata/America/Hermosillo
new file mode 100644
index 0000000..779020e
--- /dev/null
+++ b/library/tzdata/America/Hermosillo
@@ -0,0 +1,21 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Hermosillo) {
+    {-9223372036854775808 -26632 0 LMT}
+    {-1514739600 -25200 0 MST}
+    {-1343066400 -21600 0 CST}
+    {-1234807200 -25200 0 MST}
+    {-1220292000 -21600 0 CST}
+    {-1207159200 -25200 0 MST}
+    {-1191344400 -21600 0 CST}
+    {-873828000 -25200 0 MST}
+    {-661539600 -28800 0 PST}
+    {28800 -25200 0 MST}
+    {828867600 -21600 1 MDT}
+    {846403200 -25200 0 MST}
+    {860317200 -21600 1 MDT}
+    {877852800 -25200 0 MST}
+    {891766800 -21600 1 MDT}
+    {909302400 -25200 0 MST}
+    {915174000 -25200 0 MST}
+}
diff --git a/library/tzdata/America/Indiana/Indianapolis b/library/tzdata/America/Indiana/Indianapolis
new file mode 100644
index 0000000..63c410c
--- /dev/null
+++ b/library/tzdata/America/Indiana/Indianapolis
@@ -0,0 +1,234 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Indiana/Indianapolis) {
+    {-9223372036854775808 -20678 0 LMT}
+    {-2717647200 -21600 0 CST}
+    {-1633276800 -18000 1 CDT}
+    {-1615136400 -21600 0 CST}
+    {-1601827200 -18000 1 CDT}
+    {-1583686800 -21600 0 CST}
+    {-1577901600 -21600 0 CST}
+    {-900259200 -18000 1 CDT}
+    {-891795600 -21600 0 CST}
+    {-883591200 -21600 0 CST}
+    {-880214400 -18000 1 CWT}
+    {-769395600 -18000 1 CPT}
+    {-765392400 -21600 0 CST}
+    {-757360800 -21600 0 CST}
+    {-747244800 -18000 1 CDT}
+    {-733942800 -21600 0 CST}
+    {-715795200 -18000 1 CDT}
+    {-702493200 -21600 0 CST}
+    {-684345600 -18000 1 CDT}
+    {-671043600 -21600 0 CST}
+    {-652896000 -18000 1 CDT}
+    {-639594000 -21600 0 CST}
+    {-620841600 -18000 1 CDT}
+    {-608144400 -21600 0 CST}
+    {-589392000 -18000 1 CDT}
+    {-576090000 -21600 0 CST}
+    {-557942400 -18000 1 CDT}
+    {-544640400 -21600 0 CST}
+    {-526492800 -18000 1 CDT}
+    {-513190800 -21600 0 CST}
+    {-495043200 -18000 1 CDT}
+    {-481741200 -21600 0 CST}
+    {-463593600 -18000 0 EST}
+    {-386787600 -21600 0 CST}
+    {-368640000 -18000 0 EST}
+    {-31518000 -18000 0 EST}
+    {-21488400 -14400 1 EDT}
+    {-5767200 -18000 0 EST}
+    {9961200 -14400 1 EDT}
+    {25682400 -18000 0 EST}
+    {31554000 -18000 0 EST}
+    {1136091600 -18000 0 EST}
+    {1143961200 -14400 1 EDT}
+    {1162101600 -18000 0 EST}
+    {1173596400 -14400 1 EDT}
+    {1194156000 -18000 0 EST}
+    {1205046000 -14400 1 EDT}
+    {1225605600 -18000 0 EST}
+    {1236495600 -14400 1 EDT}
+    {1257055200 -18000 0 EST}
+    {1268550000 -14400 1 EDT}
+    {1289109600 -18000 0 EST}
+    {1299999600 -14400 1 EDT}
+    {1320559200 -18000 0 EST}
+    {1331449200 -14400 1 EDT}
+    {1352008800 -18000 0 EST}
+    {1362898800 -14400 1 EDT}
+    {1383458400 -18000 0 EST}
+    {1394348400 -14400 1 EDT}
+    {1414908000 -18000 0 EST}
+    {1425798000 -14400 1 EDT}
+    {1446357600 -18000 0 EST}
+    {1457852400 -14400 1 EDT}
+    {1478412000 -18000 0 EST}
+    {1489302000 -14400 1 EDT}
+    {1509861600 -18000 0 EST}
+    {1520751600 -14400 1 EDT}
+    {1541311200 -18000 0 EST}
+    {1552201200 -14400 1 EDT}
+    {1572760800 -18000 0 EST}
+    {1583650800 -14400 1 EDT}
+    {1604210400 -18000 0 EST}
+    {1615705200 -14400 1 EDT}
+    {1636264800 -18000 0 EST}
+    {1647154800 -14400 1 EDT}
+    {1667714400 -18000 0 EST}
+    {1678604400 -14400 1 EDT}
+    {1699164000 -18000 0 EST}
+    {1710054000 -14400 1 EDT}
+    {1730613600 -18000 0 EST}
+    {1741503600 -14400 1 EDT}
+    {1762063200 -18000 0 EST}
+    {1772953200 -14400 1 EDT}
+    {1793512800 -18000 0 EST}
+    {1805007600 -14400 1 EDT}
+    {1825567200 -18000 0 EST}
+    {1836457200 -14400 1 EDT}
+    {1857016800 -18000 0 EST}
+    {1867906800 -14400 1 EDT}
+    {1888466400 -18000 0 EST}
+    {1899356400 -14400 1 EDT}
+    {1919916000 -18000 0 EST}
+    {1930806000 -14400 1 EDT}
+    {1951365600 -18000 0 EST}
+    {1962860400 -14400 1 EDT}
+    {1983420000 -18000 0 EST}
+    {1994310000 -14400 1 EDT}
+    {2014869600 -18000 0 EST}
+    {2025759600 -14400 1 EDT}
+    {2046319200 -18000 0 EST}
+    {2057209200 -14400 1 EDT}
+    {2077768800 -18000 0 EST}
+    {2088658800 -14400 1 EDT}
+    {2109218400 -18000 0 EST}
+    {2120108400 -14400 1 EDT}
+    {2140668000 -18000 0 EST}
+    {2152162800 -14400 1 EDT}
+    {2172722400 -18000 0 EST}
+    {2183612400 -14400 1 EDT}
+    {2204172000 -18000 0 EST}
+    {2215062000 -14400 1 EDT}
+    {2235621600 -18000 0 EST}
+    {2246511600 -14400 1 EDT}
+    {2267071200 -18000 0 EST}
+    {2277961200 -14400 1 EDT}
+    {2298520800 -18000 0 EST}
+    {2309410800 -14400 1 EDT}
+    {2329970400 -18000 0 EST}
+    {2341465200 -14400 1 EDT}
+    {2362024800 -18000 0 EST}
+    {2372914800 -14400 1 EDT}
+    {2393474400 -18000 0 EST}
+    {2404364400 -14400 1 EDT}
+    {2424924000 -18000 0 EST}
+    {2435814000 -14400 1 EDT}
+    {2456373600 -18000 0 EST}
+    {2467263600 -14400 1 EDT}
+    {2487823200 -18000 0 EST}
+    {2499318000 -14400 1 EDT}
+    {2519877600 -18000 0 EST}
+    {2530767600 -14400 1 EDT}
+    {2551327200 -18000 0 EST}
+    {2562217200 -14400 1 EDT}
+    {2582776800 -18000 0 EST}
+    {2593666800 -14400 1 EDT}
+    {2614226400 -18000 0 EST}
+    {2625116400 -14400 1 EDT}
+    {2645676000 -18000 0 EST}
+    {2656566000 -14400 1 EDT}
+    {2677125600 -18000 0 EST}
+    {2688620400 -14400 1 EDT}
+    {2709180000 -18000 0 EST}
+    {2720070000 -14400 1 EDT}
+    {2740629600 -18000 0 EST}
+    {2751519600 -14400 1 EDT}
+    {2772079200 -18000 0 EST}
+    {2782969200 -14400 1 EDT}
+    {2803528800 -18000 0 EST}
+    {2814418800 -14400 1 EDT}
+    {2834978400 -18000 0 EST}
+    {2846473200 -14400 1 EDT}
+    {2867032800 -18000 0 EST}
+    {2877922800 -14400 1 EDT}
+    {2898482400 -18000 0 EST}
+    {2909372400 -14400 1 EDT}
+    {2929932000 -18000 0 EST}
+    {2940822000 -14400 1 EDT}
+    {2961381600 -18000 0 EST}
+    {2972271600 -14400 1 EDT}
+    {2992831200 -18000 0 EST}
+    {3003721200 -14400 1 EDT}
+    {3024280800 -18000 0 EST}
+    {3035775600 -14400 1 EDT}
+    {3056335200 -18000 0 EST}
+    {3067225200 -14400 1 EDT}
+    {3087784800 -18000 0 EST}
+    {3098674800 -14400 1 EDT}
+    {3119234400 -18000 0 EST}
+    {3130124400 -14400 1 EDT}
+    {3150684000 -18000 0 EST}
+    {3161574000 -14400 1 EDT}
+    {3182133600 -18000 0 EST}
+    {3193023600 -14400 1 EDT}
+    {3213583200 -18000 0 EST}
+    {3225078000 -14400 1 EDT}
+    {3245637600 -18000 0 EST}
+    {3256527600 -14400 1 EDT}
+    {3277087200 -18000 0 EST}
+    {3287977200 -14400 1 EDT}
+    {3308536800 -18000 0 EST}
+    {3319426800 -14400 1 EDT}
+    {3339986400 -18000 0 EST}
+    {3350876400 -14400 1 EDT}
+    {3371436000 -18000 0 EST}
+    {3382930800 -14400 1 EDT}
+    {3403490400 -18000 0 EST}
+    {3414380400 -14400 1 EDT}
+    {3434940000 -18000 0 EST}
+    {3445830000 -14400 1 EDT}
+    {3466389600 -18000 0 EST}
+    {3477279600 -14400 1 EDT}
+    {3497839200 -18000 0 EST}
+    {3508729200 -14400 1 EDT}
+    {3529288800 -18000 0 EST}
+    {3540178800 -14400 1 EDT}
+    {3560738400 -18000 0 EST}
+    {3572233200 -14400 1 EDT}
+    {3592792800 -18000 0 EST}
+    {3603682800 -14400 1 EDT}
+    {3624242400 -18000 0 EST}
+    {3635132400 -14400 1 EDT}
+    {3655692000 -18000 0 EST}
+    {3666582000 -14400 1 EDT}
+    {3687141600 -18000 0 EST}
+    {3698031600 -14400 1 EDT}
+    {3718591200 -18000 0 EST}
+    {3730086000 -14400 1 EDT}
+    {3750645600 -18000 0 EST}
+    {3761535600 -14400 1 EDT}
+    {3782095200 -18000 0 EST}
+    {3792985200 -14400 1 EDT}
+    {3813544800 -18000 0 EST}
+    {3824434800 -14400 1 EDT}
+    {3844994400 -18000 0 EST}
+    {3855884400 -14400 1 EDT}
+    {3876444000 -18000 0 EST}
+    {3887334000 -14400 1 EDT}
+    {3907893600 -18000 0 EST}
+    {3919388400 -14400 1 EDT}
+    {3939948000 -18000 0 EST}
+    {3950838000 -14400 1 EDT}
+    {3971397600 -18000 0 EST}
+    {3982287600 -14400 1 EDT}
+    {4002847200 -18000 0 EST}
+    {4013737200 -14400 1 EDT}
+    {4034296800 -18000 0 EST}
+    {4045186800 -14400 1 EDT}
+    {4065746400 -18000 0 EST}
+    {4076636400 -14400 1 EDT}
+    {4097196000 -18000 0 EST}
+}
diff --git a/library/tzdata/America/Indiana/Knox b/library/tzdata/America/Indiana/Knox
new file mode 100644
index 0000000..eee3ff4
--- /dev/null
+++ b/library/tzdata/America/Indiana/Knox
@@ -0,0 +1,285 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Indiana/Knox) {
+    {-9223372036854775808 -20790 0 LMT}
+    {-2717647200 -21600 0 CST}
+    {-1633276800 -18000 1 CDT}
+    {-1615136400 -21600 0 CST}
+    {-1601827200 -18000 1 CDT}
+    {-1583686800 -21600 0 CST}
+    {-880214400 -18000 1 CWT}
+    {-769395600 -18000 1 CPT}
+    {-765392400 -21600 0 CST}
+    {-725824800 -21600 0 CST}
+    {-715795200 -18000 1 CDT}
+    {-702493200 -21600 0 CST}
+    {-684345600 -18000 1 CDT}
+    {-671043600 -21600 0 CST}
+    {-652896000 -18000 1 CDT}
+    {-639594000 -21600 0 CST}
+    {-620841600 -18000 1 CDT}
+    {-608144400 -21600 0 CST}
+    {-589392000 -18000 1 CDT}
+    {-576090000 -21600 0 CST}
+    {-557942400 -18000 1 CDT}
+    {-544640400 -21600 0 CST}
+    {-526492800 -18000 1 CDT}
+    {-513190800 -21600 0 CST}
+    {-495043200 -18000 1 CDT}
+    {-481741200 -21600 0 CST}
+    {-463593600 -18000 1 CDT}
+    {-447267600 -21600 0 CST}
+    {-431539200 -18000 1 CDT}
+    {-415818000 -21600 0 CST}
+    {-400089600 -18000 1 CDT}
+    {-386787600 -21600 0 CST}
+    {-368640000 -18000 1 CDT}
+    {-355338000 -21600 0 CST}
+    {-337190400 -18000 1 CDT}
+    {-321469200 -21600 0 CST}
+    {-305740800 -18000 1 CDT}
+    {-289414800 -21600 0 CST}
+    {-273686400 -18000 1 CDT}
+    {-257965200 -21600 0 CST}
+    {-242236800 -18000 0 EST}
+    {-195066000 -21600 0 CST}
+    {-84384000 -18000 1 CDT}
+    {-68662800 -21600 0 CST}
+    {-52934400 -18000 1 CDT}
+    {-37213200 -21600 0 CST}
+    {-21484800 -18000 1 CDT}
+    {-5763600 -21600 0 CST}
+    {9964800 -18000 1 CDT}
+    {25686000 -21600 0 CST}
+    {41414400 -18000 1 CDT}
+    {57740400 -21600 0 CST}
+    {73468800 -18000 1 CDT}
+    {89190000 -21600 0 CST}
+    {104918400 -18000 1 CDT}
+    {120639600 -21600 0 CST}
+    {126691200 -18000 1 CDT}
+    {152089200 -21600 0 CST}
+    {162374400 -18000 1 CDT}
+    {183538800 -21600 0 CST}
+    {199267200 -18000 1 CDT}
+    {215593200 -21600 0 CST}
+    {230716800 -18000 1 CDT}
+    {247042800 -21600 0 CST}
+    {262771200 -18000 1 CDT}
+    {278492400 -21600 0 CST}
+    {294220800 -18000 1 CDT}
+    {309942000 -21600 0 CST}
+    {325670400 -18000 1 CDT}
+    {341391600 -21600 0 CST}
+    {357120000 -18000 1 CDT}
+    {372841200 -21600 0 CST}
+    {388569600 -18000 1 CDT}
+    {404895600 -21600 0 CST}
+    {420019200 -18000 1 CDT}
+    {436345200 -21600 0 CST}
+    {452073600 -18000 1 CDT}
+    {467794800 -21600 0 CST}
+    {483523200 -18000 1 CDT}
+    {499244400 -21600 0 CST}
+    {514972800 -18000 1 CDT}
+    {530694000 -21600 0 CST}
+    {544608000 -18000 1 CDT}
+    {562143600 -21600 0 CST}
+    {576057600 -18000 1 CDT}
+    {594198000 -21600 0 CST}
+    {607507200 -18000 1 CDT}
+    {625647600 -21600 0 CST}
+    {638956800 -18000 1 CDT}
+    {657097200 -21600 0 CST}
+    {671011200 -18000 1 CDT}
+    {688550400 -18000 0 EST}
+    {1143961200 -21600 0 CST}
+    {1143964800 -18000 1 CDT}
+    {1162105200 -21600 0 CST}
+    {1173600000 -18000 1 CDT}
+    {1194159600 -21600 0 CST}
+    {1205049600 -18000 1 CDT}
+    {1225609200 -21600 0 CST}
+    {1236499200 -18000 1 CDT}
+    {1257058800 -21600 0 CST}
+    {1268553600 -18000 1 CDT}
+    {1289113200 -21600 0 CST}
+    {1300003200 -18000 1 CDT}
+    {1320562800 -21600 0 CST}
+    {1331452800 -18000 1 CDT}
+    {1352012400 -21600 0 CST}
+    {1362902400 -18000 1 CDT}
+    {1383462000 -21600 0 CST}
+    {1394352000 -18000 1 CDT}
+    {1414911600 -21600 0 CST}
+    {1425801600 -18000 1 CDT}
+    {1446361200 -21600 0 CST}
+    {1457856000 -18000 1 CDT}
+    {1478415600 -21600 0 CST}
+    {1489305600 -18000 1 CDT}
+    {1509865200 -21600 0 CST}
+    {1520755200 -18000 1 CDT}
+    {1541314800 -21600 0 CST}
+    {1552204800 -18000 1 CDT}
+    {1572764400 -21600 0 CST}
+    {1583654400 -18000 1 CDT}
+    {1604214000 -21600 0 CST}
+    {1615708800 -18000 1 CDT}
+    {1636268400 -21600 0 CST}
+    {1647158400 -18000 1 CDT}
+    {1667718000 -21600 0 CST}
+    {1678608000 -18000 1 CDT}
+    {1699167600 -21600 0 CST}
+    {1710057600 -18000 1 CDT}
+    {1730617200 -21600 0 CST}
+    {1741507200 -18000 1 CDT}
+    {1762066800 -21600 0 CST}
+    {1772956800 -18000 1 CDT}
+    {1793516400 -21600 0 CST}
+    {1805011200 -18000 1 CDT}
+    {1825570800 -21600 0 CST}
+    {1836460800 -18000 1 CDT}
+    {1857020400 -21600 0 CST}
+    {1867910400 -18000 1 CDT}
+    {1888470000 -21600 0 CST}
+    {1899360000 -18000 1 CDT}
+    {1919919600 -21600 0 CST}
+    {1930809600 -18000 1 CDT}
+    {1951369200 -21600 0 CST}
+    {1962864000 -18000 1 CDT}
+    {1983423600 -21600 0 CST}
+    {1994313600 -18000 1 CDT}
+    {2014873200 -21600 0 CST}
+    {2025763200 -18000 1 CDT}
+    {2046322800 -21600 0 CST}
+    {2057212800 -18000 1 CDT}
+    {2077772400 -21600 0 CST}
+    {2088662400 -18000 1 CDT}
+    {2109222000 -21600 0 CST}
+    {2120112000 -18000 1 CDT}
+    {2140671600 -21600 0 CST}
+    {2152166400 -18000 1 CDT}
+    {2172726000 -21600 0 CST}
+    {2183616000 -18000 1 CDT}
+    {2204175600 -21600 0 CST}
+    {2215065600 -18000 1 CDT}
+    {2235625200 -21600 0 CST}
+    {2246515200 -18000 1 CDT}
+    {2267074800 -21600 0 CST}
+    {2277964800 -18000 1 CDT}
+    {2298524400 -21600 0 CST}
+    {2309414400 -18000 1 CDT}
+    {2329974000 -21600 0 CST}
+    {2341468800 -18000 1 CDT}
+    {2362028400 -21600 0 CST}
+    {2372918400 -18000 1 CDT}
+    {2393478000 -21600 0 CST}
+    {2404368000 -18000 1 CDT}
+    {2424927600 -21600 0 CST}
+    {2435817600 -18000 1 CDT}
+    {2456377200 -21600 0 CST}
+    {2467267200 -18000 1 CDT}
+    {2487826800 -21600 0 CST}
+    {2499321600 -18000 1 CDT}
+    {2519881200 -21600 0 CST}
+    {2530771200 -18000 1 CDT}
+    {2551330800 -21600 0 CST}
+    {2562220800 -18000 1 CDT}
+    {2582780400 -21600 0 CST}
+    {2593670400 -18000 1 CDT}
+    {2614230000 -21600 0 CST}
+    {2625120000 -18000 1 CDT}
+    {2645679600 -21600 0 CST}
+    {2656569600 -18000 1 CDT}
+    {2677129200 -21600 0 CST}
+    {2688624000 -18000 1 CDT}
+    {2709183600 -21600 0 CST}
+    {2720073600 -18000 1 CDT}
+    {2740633200 -21600 0 CST}
+    {2751523200 -18000 1 CDT}
+    {2772082800 -21600 0 CST}
+    {2782972800 -18000 1 CDT}
+    {2803532400 -21600 0 CST}
+    {2814422400 -18000 1 CDT}
+    {2834982000 -21600 0 CST}
+    {2846476800 -18000 1 CDT}
+    {2867036400 -21600 0 CST}
+    {2877926400 -18000 1 CDT}
+    {2898486000 -21600 0 CST}
+    {2909376000 -18000 1 CDT}
+    {2929935600 -21600 0 CST}
+    {2940825600 -18000 1 CDT}
+    {2961385200 -21600 0 CST}
+    {2972275200 -18000 1 CDT}
+    {2992834800 -21600 0 CST}
+    {3003724800 -18000 1 CDT}
+    {3024284400 -21600 0 CST}
+    {3035779200 -18000 1 CDT}
+    {3056338800 -21600 0 CST}
+    {3067228800 -18000 1 CDT}
+    {3087788400 -21600 0 CST}
+    {3098678400 -18000 1 CDT}
+    {3119238000 -21600 0 CST}
+    {3130128000 -18000 1 CDT}
+    {3150687600 -21600 0 CST}
+    {3161577600 -18000 1 CDT}
+    {3182137200 -21600 0 CST}
+    {3193027200 -18000 1 CDT}
+    {3213586800 -21600 0 CST}
+    {3225081600 -18000 1 CDT}
+    {3245641200 -21600 0 CST}
+    {3256531200 -18000 1 CDT}
+    {3277090800 -21600 0 CST}
+    {3287980800 -18000 1 CDT}
+    {3308540400 -21600 0 CST}
+    {3319430400 -18000 1 CDT}
+    {3339990000 -21600 0 CST}
+    {3350880000 -18000 1 CDT}
+    {3371439600 -21600 0 CST}
+    {3382934400 -18000 1 CDT}
+    {3403494000 -21600 0 CST}
+    {3414384000 -18000 1 CDT}
+    {3434943600 -21600 0 CST}
+    {3445833600 -18000 1 CDT}
+    {3466393200 -21600 0 CST}
+    {3477283200 -18000 1 CDT}
+    {3497842800 -21600 0 CST}
+    {3508732800 -18000 1 CDT}
+    {3529292400 -21600 0 CST}
+    {3540182400 -18000 1 CDT}
+    {3560742000 -21600 0 CST}
+    {3572236800 -18000 1 CDT}
+    {3592796400 -21600 0 CST}
+    {3603686400 -18000 1 CDT}
+    {3624246000 -21600 0 CST}
+    {3635136000 -18000 1 CDT}
+    {3655695600 -21600 0 CST}
+    {3666585600 -18000 1 CDT}
+    {3687145200 -21600 0 CST}
+    {3698035200 -18000 1 CDT}
+    {3718594800 -21600 0 CST}
+    {3730089600 -18000 1 CDT}
+    {3750649200 -21600 0 CST}
+    {3761539200 -18000 1 CDT}
+    {3782098800 -21600 0 CST}
+    {3792988800 -18000 1 CDT}
+    {3813548400 -21600 0 CST}
+    {3824438400 -18000 1 CDT}
+    {3844998000 -21600 0 CST}
+    {3855888000 -18000 1 CDT}
+    {3876447600 -21600 0 CST}
+    {3887337600 -18000 1 CDT}
+    {3907897200 -21600 0 CST}
+    {3919392000 -18000 1 CDT}
+    {3939951600 -21600 0 CST}
+    {3950841600 -18000 1 CDT}
+    {3971401200 -21600 0 CST}
+    {3982291200 -18000 1 CDT}
+    {4002850800 -21600 0 CST}
+    {4013740800 -18000 1 CDT}
+    {4034300400 -21600 0 CST}
+    {4045190400 -18000 1 CDT}
+    {4065750000 -21600 0 CST}
+    {4076640000 -18000 1 CDT}
+    {4097199600 -21600 0 CST}
+}
diff --git a/library/tzdata/America/Indiana/Marengo b/library/tzdata/America/Indiana/Marengo
new file mode 100644
index 0000000..3f1d578
--- /dev/null
+++ b/library/tzdata/America/Indiana/Marengo
@@ -0,0 +1,236 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Indiana/Marengo) {
+    {-9223372036854775808 -20723 0 LMT}
+    {-2717647200 -21600 0 CST}
+    {-1633276800 -18000 1 CDT}
+    {-1615136400 -21600 0 CST}
+    {-1601827200 -18000 1 CDT}
+    {-1583686800 -21600 0 CST}
+    {-880214400 -18000 1 CWT}
+    {-769395600 -18000 1 CPT}
+    {-765392400 -21600 0 CST}
+    {-599594400 -21600 0 CST}
+    {-589392000 -18000 1 CDT}
+    {-576090000 -21600 0 CST}
+    {-495043200 -18000 1 CDT}
+    {-481741200 -21600 0 CST}
+    {-463593600 -18000 1 CDT}
+    {-450291600 -21600 0 CST}
+    {-431539200 -18000 1 CDT}
+    {-418237200 -21600 0 CST}
+    {-400089600 -18000 1 CDT}
+    {-386787600 -21600 0 CST}
+    {-368640000 -18000 1 CDT}
+    {-355338000 -21600 0 CST}
+    {-337190400 -18000 1 CDT}
+    {-323888400 -21600 0 CST}
+    {-305740800 -18000 1 CDT}
+    {-292438800 -21600 0 CST}
+    {-273686400 -18000 0 EST}
+    {-31518000 -18000 0 EST}
+    {-21488400 -14400 1 EDT}
+    {-5767200 -18000 0 EST}
+    {9961200 -14400 1 EDT}
+    {25682400 -18000 0 EST}
+    {41410800 -14400 1 EDT}
+    {57736800 -18000 0 EST}
+    {73465200 -14400 1 EDT}
+    {89186400 -18000 0 EST}
+    {104914800 -14400 1 EDT}
+    {120636000 -18000 0 EST}
+    {126687600 -18000 1 CDT}
+    {152089200 -18000 0 EST}
+    {162370800 -14400 1 EDT}
+    {183535200 -18000 0 EST}
+    {189320400 -18000 0 EST}
+    {1136091600 -18000 0 EST}
+    {1143961200 -14400 1 EDT}
+    {1162101600 -18000 0 EST}
+    {1173596400 -14400 1 EDT}
+    {1194156000 -18000 0 EST}
+    {1205046000 -14400 1 EDT}
+    {1225605600 -18000 0 EST}
+    {1236495600 -14400 1 EDT}
+    {1257055200 -18000 0 EST}
+    {1268550000 -14400 1 EDT}
+    {1289109600 -18000 0 EST}
+    {1299999600 -14400 1 EDT}
+    {1320559200 -18000 0 EST}
+    {1331449200 -14400 1 EDT}
+    {1352008800 -18000 0 EST}
+    {1362898800 -14400 1 EDT}
+    {1383458400 -18000 0 EST}
+    {1394348400 -14400 1 EDT}
+    {1414908000 -18000 0 EST}
+    {1425798000 -14400 1 EDT}
+    {1446357600 -18000 0 EST}
+    {1457852400 -14400 1 EDT}
+    {1478412000 -18000 0 EST}
+    {1489302000 -14400 1 EDT}
+    {1509861600 -18000 0 EST}
+    {1520751600 -14400 1 EDT}
+    {1541311200 -18000 0 EST}
+    {1552201200 -14400 1 EDT}
+    {1572760800 -18000 0 EST}
+    {1583650800 -14400 1 EDT}
+    {1604210400 -18000 0 EST}
+    {1615705200 -14400 1 EDT}
+    {1636264800 -18000 0 EST}
+    {1647154800 -14400 1 EDT}
+    {1667714400 -18000 0 EST}
+    {1678604400 -14400 1 EDT}
+    {1699164000 -18000 0 EST}
+    {1710054000 -14400 1 EDT}
+    {1730613600 -18000 0 EST}
+    {1741503600 -14400 1 EDT}
+    {1762063200 -18000 0 EST}
+    {1772953200 -14400 1 EDT}
+    {1793512800 -18000 0 EST}
+    {1805007600 -14400 1 EDT}
+    {1825567200 -18000 0 EST}
+    {1836457200 -14400 1 EDT}
+    {1857016800 -18000 0 EST}
+    {1867906800 -14400 1 EDT}
+    {1888466400 -18000 0 EST}
+    {1899356400 -14400 1 EDT}
+    {1919916000 -18000 0 EST}
+    {1930806000 -14400 1 EDT}
+    {1951365600 -18000 0 EST}
+    {1962860400 -14400 1 EDT}
+    {1983420000 -18000 0 EST}
+    {1994310000 -14400 1 EDT}
+    {2014869600 -18000 0 EST}
+    {2025759600 -14400 1 EDT}
+    {2046319200 -18000 0 EST}
+    {2057209200 -14400 1 EDT}
+    {2077768800 -18000 0 EST}
+    {2088658800 -14400 1 EDT}
+    {2109218400 -18000 0 EST}
+    {2120108400 -14400 1 EDT}
+    {2140668000 -18000 0 EST}
+    {2152162800 -14400 1 EDT}
+    {2172722400 -18000 0 EST}
+    {2183612400 -14400 1 EDT}
+    {2204172000 -18000 0 EST}
+    {2215062000 -14400 1 EDT}
+    {2235621600 -18000 0 EST}
+    {2246511600 -14400 1 EDT}
+    {2267071200 -18000 0 EST}
+    {2277961200 -14400 1 EDT}
+    {2298520800 -18000 0 EST}
+    {2309410800 -14400 1 EDT}
+    {2329970400 -18000 0 EST}
+    {2341465200 -14400 1 EDT}
+    {2362024800 -18000 0 EST}
+    {2372914800 -14400 1 EDT}
+    {2393474400 -18000 0 EST}
+    {2404364400 -14400 1 EDT}
+    {2424924000 -18000 0 EST}
+    {2435814000 -14400 1 EDT}
+    {2456373600 -18000 0 EST}
+    {2467263600 -14400 1 EDT}
+    {2487823200 -18000 0 EST}
+    {2499318000 -14400 1 EDT}
+    {2519877600 -18000 0 EST}
+    {2530767600 -14400 1 EDT}
+    {2551327200 -18000 0 EST}
+    {2562217200 -14400 1 EDT}
+    {2582776800 -18000 0 EST}
+    {2593666800 -14400 1 EDT}
+    {2614226400 -18000 0 EST}
+    {2625116400 -14400 1 EDT}
+    {2645676000 -18000 0 EST}
+    {2656566000 -14400 1 EDT}
+    {2677125600 -18000 0 EST}
+    {2688620400 -14400 1 EDT}
+    {2709180000 -18000 0 EST}
+    {2720070000 -14400 1 EDT}
+    {2740629600 -18000 0 EST}
+    {2751519600 -14400 1 EDT}
+    {2772079200 -18000 0 EST}
+    {2782969200 -14400 1 EDT}
+    {2803528800 -18000 0 EST}
+    {2814418800 -14400 1 EDT}
+    {2834978400 -18000 0 EST}
+    {2846473200 -14400 1 EDT}
+    {2867032800 -18000 0 EST}
+    {2877922800 -14400 1 EDT}
+    {2898482400 -18000 0 EST}
+    {2909372400 -14400 1 EDT}
+    {2929932000 -18000 0 EST}
+    {2940822000 -14400 1 EDT}
+    {2961381600 -18000 0 EST}
+    {2972271600 -14400 1 EDT}
+    {2992831200 -18000 0 EST}
+    {3003721200 -14400 1 EDT}
+    {3024280800 -18000 0 EST}
+    {3035775600 -14400 1 EDT}
+    {3056335200 -18000 0 EST}
+    {3067225200 -14400 1 EDT}
+    {3087784800 -18000 0 EST}
+    {3098674800 -14400 1 EDT}
+    {3119234400 -18000 0 EST}
+    {3130124400 -14400 1 EDT}
+    {3150684000 -18000 0 EST}
+    {3161574000 -14400 1 EDT}
+    {3182133600 -18000 0 EST}
+    {3193023600 -14400 1 EDT}
+    {3213583200 -18000 0 EST}
+    {3225078000 -14400 1 EDT}
+    {3245637600 -18000 0 EST}
+    {3256527600 -14400 1 EDT}
+    {3277087200 -18000 0 EST}
+    {3287977200 -14400 1 EDT}
+    {3308536800 -18000 0 EST}
+    {3319426800 -14400 1 EDT}
+    {3339986400 -18000 0 EST}
+    {3350876400 -14400 1 EDT}
+    {3371436000 -18000 0 EST}
+    {3382930800 -14400 1 EDT}
+    {3403490400 -18000 0 EST}
+    {3414380400 -14400 1 EDT}
+    {3434940000 -18000 0 EST}
+    {3445830000 -14400 1 EDT}
+    {3466389600 -18000 0 EST}
+    {3477279600 -14400 1 EDT}
+    {3497839200 -18000 0 EST}
+    {3508729200 -14400 1 EDT}
+    {3529288800 -18000 0 EST}
+    {3540178800 -14400 1 EDT}
+    {3560738400 -18000 0 EST}
+    {3572233200 -14400 1 EDT}
+    {3592792800 -18000 0 EST}
+    {3603682800 -14400 1 EDT}
+    {3624242400 -18000 0 EST}
+    {3635132400 -14400 1 EDT}
+    {3655692000 -18000 0 EST}
+    {3666582000 -14400 1 EDT}
+    {3687141600 -18000 0 EST}
+    {3698031600 -14400 1 EDT}
+    {3718591200 -18000 0 EST}
+    {3730086000 -14400 1 EDT}
+    {3750645600 -18000 0 EST}
+    {3761535600 -14400 1 EDT}
+    {3782095200 -18000 0 EST}
+    {3792985200 -14400 1 EDT}
+    {3813544800 -18000 0 EST}
+    {3824434800 -14400 1 EDT}
+    {3844994400 -18000 0 EST}
+    {3855884400 -14400 1 EDT}
+    {3876444000 -18000 0 EST}
+    {3887334000 -14400 1 EDT}
+    {3907893600 -18000 0 EST}
+    {3919388400 -14400 1 EDT}
+    {3939948000 -18000 0 EST}
+    {3950838000 -14400 1 EDT}
+    {3971397600 -18000 0 EST}
+    {3982287600 -14400 1 EDT}
+    {4002847200 -18000 0 EST}
+    {4013737200 -14400 1 EDT}
+    {4034296800 -18000 0 EST}
+    {4045186800 -14400 1 EDT}
+    {4065746400 -18000 0 EST}
+    {4076636400 -14400 1 EDT}
+    {4097196000 -18000 0 EST}
+}
diff --git a/library/tzdata/America/Indiana/Petersburg b/library/tzdata/America/Indiana/Petersburg
new file mode 100644
index 0000000..6992bfc
--- /dev/null
+++ b/library/tzdata/America/Indiana/Petersburg
@@ -0,0 +1,247 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Indiana/Petersburg) {
+    {-9223372036854775808 -20947 0 LMT}
+    {-2717647200 -21600 0 CST}
+    {-1633276800 -18000 1 CDT}
+    {-1615136400 -21600 0 CST}
+    {-1601827200 -18000 1 CDT}
+    {-1583686800 -21600 0 CST}
+    {-880214400 -18000 1 CWT}
+    {-769395600 -18000 1 CPT}
+    {-765392400 -21600 0 CST}
+    {-473364000 -21600 0 CST}
+    {-462996000 -18000 1 CDT}
+    {-450291600 -21600 0 CST}
+    {-431539200 -18000 1 CDT}
+    {-418237200 -21600 0 CST}
+    {-400089600 -18000 1 CDT}
+    {-386787600 -21600 0 CST}
+    {-368640000 -18000 1 CDT}
+    {-355338000 -21600 0 CST}
+    {-337190400 -18000 1 CDT}
+    {-323888400 -21600 0 CST}
+    {-305740800 -18000 1 CDT}
+    {-292438800 -21600 0 CST}
+    {-273686400 -18000 1 CDT}
+    {-257965200 -21600 0 CST}
+    {-242236800 -18000 1 CDT}
+    {-226515600 -21600 0 CST}
+    {-210787200 -18000 1 CDT}
+    {-195066000 -21600 0 CST}
+    {-179337600 -18000 1 CDT}
+    {-163616400 -21600 0 CST}
+    {-147888000 -18000 0 EST}
+    {-100112400 -21600 0 CST}
+    {-84384000 -18000 1 CDT}
+    {-68662800 -21600 0 CST}
+    {-52934400 -18000 1 CDT}
+    {-37213200 -21600 0 CST}
+    {-21484800 -18000 1 CDT}
+    {-5763600 -21600 0 CST}
+    {9964800 -18000 1 CDT}
+    {25686000 -21600 0 CST}
+    {41414400 -18000 1 CDT}
+    {57740400 -21600 0 CST}
+    {73468800 -18000 1 CDT}
+    {89190000 -21600 0 CST}
+    {104918400 -18000 1 CDT}
+    {120639600 -21600 0 CST}
+    {126691200 -18000 1 CDT}
+    {152089200 -21600 0 CST}
+    {162374400 -18000 1 CDT}
+    {183538800 -21600 0 CST}
+    {199267200 -18000 1 CDT}
+    {215593200 -21600 0 CST}
+    {230716800 -18000 1 CDT}
+    {247046400 -18000 0 EST}
+    {1143961200 -21600 0 CST}
+    {1143964800 -18000 1 CDT}
+    {1162105200 -21600 0 CST}
+    {1173600000 -18000 1 CDT}
+    {1194163200 -18000 0 EST}
+    {1205046000 -14400 1 EDT}
+    {1225605600 -18000 0 EST}
+    {1236495600 -14400 1 EDT}
+    {1257055200 -18000 0 EST}
+    {1268550000 -14400 1 EDT}
+    {1289109600 -18000 0 EST}
+    {1299999600 -14400 1 EDT}
+    {1320559200 -18000 0 EST}
+    {1331449200 -14400 1 EDT}
+    {1352008800 -18000 0 EST}
+    {1362898800 -14400 1 EDT}
+    {1383458400 -18000 0 EST}
+    {1394348400 -14400 1 EDT}
+    {1414908000 -18000 0 EST}
+    {1425798000 -14400 1 EDT}
+    {1446357600 -18000 0 EST}
+    {1457852400 -14400 1 EDT}
+    {1478412000 -18000 0 EST}
+    {1489302000 -14400 1 EDT}
+    {1509861600 -18000 0 EST}
+    {1520751600 -14400 1 EDT}
+    {1541311200 -18000 0 EST}
+    {1552201200 -14400 1 EDT}
+    {1572760800 -18000 0 EST}
+    {1583650800 -14400 1 EDT}
+    {1604210400 -18000 0 EST}
+    {1615705200 -14400 1 EDT}
+    {1636264800 -18000 0 EST}
+    {1647154800 -14400 1 EDT}
+    {1667714400 -18000 0 EST}
+    {1678604400 -14400 1 EDT}
+    {1699164000 -18000 0 EST}
+    {1710054000 -14400 1 EDT}
+    {1730613600 -18000 0 EST}
+    {1741503600 -14400 1 EDT}
+    {1762063200 -18000 0 EST}
+    {1772953200 -14400 1 EDT}
+    {1793512800 -18000 0 EST}
+    {1805007600 -14400 1 EDT}
+    {1825567200 -18000 0 EST}
+    {1836457200 -14400 1 EDT}
+    {1857016800 -18000 0 EST}
+    {1867906800 -14400 1 EDT}
+    {1888466400 -18000 0 EST}
+    {1899356400 -14400 1 EDT}
+    {1919916000 -18000 0 EST}
+    {1930806000 -14400 1 EDT}
+    {1951365600 -18000 0 EST}
+    {1962860400 -14400 1 EDT}
+    {1983420000 -18000 0 EST}
+    {1994310000 -14400 1 EDT}
+    {2014869600 -18000 0 EST}
+    {2025759600 -14400 1 EDT}
+    {2046319200 -18000 0 EST}
+    {2057209200 -14400 1 EDT}
+    {2077768800 -18000 0 EST}
+    {2088658800 -14400 1 EDT}
+    {2109218400 -18000 0 EST}
+    {2120108400 -14400 1 EDT}
+    {2140668000 -18000 0 EST}
+    {2152162800 -14400 1 EDT}
+    {2172722400 -18000 0 EST}
+    {2183612400 -14400 1 EDT}
+    {2204172000 -18000 0 EST}
+    {2215062000 -14400 1 EDT}
+    {2235621600 -18000 0 EST}
+    {2246511600 -14400 1 EDT}
+    {2267071200 -18000 0 EST}
+    {2277961200 -14400 1 EDT}
+    {2298520800 -18000 0 EST}
+    {2309410800 -14400 1 EDT}
+    {2329970400 -18000 0 EST}
+    {2341465200 -14400 1 EDT}
+    {2362024800 -18000 0 EST}
+    {2372914800 -14400 1 EDT}
+    {2393474400 -18000 0 EST}
+    {2404364400 -14400 1 EDT}
+    {2424924000 -18000 0 EST}
+    {2435814000 -14400 1 EDT}
+    {2456373600 -18000 0 EST}
+    {2467263600 -14400 1 EDT}
+    {2487823200 -18000 0 EST}
+    {2499318000 -14400 1 EDT}
+    {2519877600 -18000 0 EST}
+    {2530767600 -14400 1 EDT}
+    {2551327200 -18000 0 EST}
+    {2562217200 -14400 1 EDT}
+    {2582776800 -18000 0 EST}
+    {2593666800 -14400 1 EDT}
+    {2614226400 -18000 0 EST}
+    {2625116400 -14400 1 EDT}
+    {2645676000 -18000 0 EST}
+    {2656566000 -14400 1 EDT}
+    {2677125600 -18000 0 EST}
+    {2688620400 -14400 1 EDT}
+    {2709180000 -18000 0 EST}
+    {2720070000 -14400 1 EDT}
+    {2740629600 -18000 0 EST}
+    {2751519600 -14400 1 EDT}
+    {2772079200 -18000 0 EST}
+    {2782969200 -14400 1 EDT}
+    {2803528800 -18000 0 EST}
+    {2814418800 -14400 1 EDT}
+    {2834978400 -18000 0 EST}
+    {2846473200 -14400 1 EDT}
+    {2867032800 -18000 0 EST}
+    {2877922800 -14400 1 EDT}
+    {2898482400 -18000 0 EST}
+    {2909372400 -14400 1 EDT}
+    {2929932000 -18000 0 EST}
+    {2940822000 -14400 1 EDT}
+    {2961381600 -18000 0 EST}
+    {2972271600 -14400 1 EDT}
+    {2992831200 -18000 0 EST}
+    {3003721200 -14400 1 EDT}
+    {3024280800 -18000 0 EST}
+    {3035775600 -14400 1 EDT}
+    {3056335200 -18000 0 EST}
+    {3067225200 -14400 1 EDT}
+    {3087784800 -18000 0 EST}
+    {3098674800 -14400 1 EDT}
+    {3119234400 -18000 0 EST}
+    {3130124400 -14400 1 EDT}
+    {3150684000 -18000 0 EST}
+    {3161574000 -14400 1 EDT}
+    {3182133600 -18000 0 EST}
+    {3193023600 -14400 1 EDT}
+    {3213583200 -18000 0 EST}
+    {3225078000 -14400 1 EDT}
+    {3245637600 -18000 0 EST}
+    {3256527600 -14400 1 EDT}
+    {3277087200 -18000 0 EST}
+    {3287977200 -14400 1 EDT}
+    {3308536800 -18000 0 EST}
+    {3319426800 -14400 1 EDT}
+    {3339986400 -18000 0 EST}
+    {3350876400 -14400 1 EDT}
+    {3371436000 -18000 0 EST}
+    {3382930800 -14400 1 EDT}
+    {3403490400 -18000 0 EST}
+    {3414380400 -14400 1 EDT}
+    {3434940000 -18000 0 EST}
+    {3445830000 -14400 1 EDT}
+    {3466389600 -18000 0 EST}
+    {3477279600 -14400 1 EDT}
+    {3497839200 -18000 0 EST}
+    {3508729200 -14400 1 EDT}
+    {3529288800 -18000 0 EST}
+    {3540178800 -14400 1 EDT}
+    {3560738400 -18000 0 EST}
+    {3572233200 -14400 1 EDT}
+    {3592792800 -18000 0 EST}
+    {3603682800 -14400 1 EDT}
+    {3624242400 -18000 0 EST}
+    {3635132400 -14400 1 EDT}
+    {3655692000 -18000 0 EST}
+    {3666582000 -14400 1 EDT}
+    {3687141600 -18000 0 EST}
+    {3698031600 -14400 1 EDT}
+    {3718591200 -18000 0 EST}
+    {3730086000 -14400 1 EDT}
+    {3750645600 -18000 0 EST}
+    {3761535600 -14400 1 EDT}
+    {3782095200 -18000 0 EST}
+    {3792985200 -14400 1 EDT}
+    {3813544800 -18000 0 EST}
+    {3824434800 -14400 1 EDT}
+    {3844994400 -18000 0 EST}
+    {3855884400 -14400 1 EDT}
+    {3876444000 -18000 0 EST}
+    {3887334000 -14400 1 EDT}
+    {3907893600 -18000 0 EST}
+    {3919388400 -14400 1 EDT}
+    {3939948000 -18000 0 EST}
+    {3950838000 -14400 1 EDT}
+    {3971397600 -18000 0 EST}
+    {3982287600 -14400 1 EDT}
+    {4002847200 -18000 0 EST}
+    {4013737200 -14400 1 EDT}
+    {4034296800 -18000 0 EST}
+    {4045186800 -14400 1 EDT}
+    {4065746400 -18000 0 EST}
+    {4076636400 -14400 1 EDT}
+    {4097196000 -18000 0 EST}
+}
diff --git a/library/tzdata/America/Indiana/Tell_City b/library/tzdata/America/Indiana/Tell_City
new file mode 100644
index 0000000..9eebcf7
--- /dev/null
+++ b/library/tzdata/America/Indiana/Tell_City
@@ -0,0 +1,234 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Indiana/Tell_City) {
+    {-9223372036854775808 -20823 0 LMT}
+    {-2717647200 -21600 0 CST}
+    {-1633276800 -18000 1 CDT}
+    {-1615136400 -21600 0 CST}
+    {-1601827200 -18000 1 CDT}
+    {-1583686800 -21600 0 CST}
+    {-880214400 -18000 1 CWT}
+    {-769395600 -18000 1 CPT}
+    {-765392400 -21600 0 CST}
+    {-757360800 -21600 0 CST}
+    {-747244800 -18000 1 CDT}
+    {-733942800 -21600 0 CST}
+    {-526492800 -18000 1 CDT}
+    {-513190800 -21600 0 CST}
+    {-495043200 -18000 1 CDT}
+    {-481741200 -21600 0 CST}
+    {-462996000 -18000 1 CDT}
+    {-450291600 -21600 0 CST}
+    {-431539200 -18000 1 CDT}
+    {-418237200 -21600 0 CST}
+    {-400089600 -18000 1 CDT}
+    {-386787600 -21600 0 CST}
+    {-368640000 -18000 1 CDT}
+    {-355338000 -21600 0 CST}
+    {-337190400 -18000 1 CDT}
+    {-323888400 -21600 0 CST}
+    {-305740800 -18000 1 CDT}
+    {-289414800 -21600 0 CST}
+    {-273686400 -18000 1 CDT}
+    {-260989200 -21600 0 CST}
+    {-242236800 -18000 1 CDT}
+    {-226515600 -21600 0 CST}
+    {-210787200 -18000 1 CDT}
+    {-195066000 -21600 0 CST}
+    {-179337600 -18000 0 EST}
+    {-31518000 -18000 0 EST}
+    {-21488400 -14400 1 EDT}
+    {-5767200 -18000 0 EST}
+    {9961200 -14400 1 EDT}
+    {25682400 -18000 0 EST}
+    {31554000 -18000 0 EST}
+    {1143961200 -21600 0 CST}
+    {1143964800 -18000 1 CDT}
+    {1162105200 -21600 0 CST}
+    {1173600000 -18000 1 CDT}
+    {1194159600 -21600 0 CST}
+    {1205049600 -18000 1 CDT}
+    {1225609200 -21600 0 CST}
+    {1236499200 -18000 1 CDT}
+    {1257058800 -21600 0 CST}
+    {1268553600 -18000 1 CDT}
+    {1289113200 -21600 0 CST}
+    {1300003200 -18000 1 CDT}
+    {1320562800 -21600 0 CST}
+    {1331452800 -18000 1 CDT}
+    {1352012400 -21600 0 CST}
+    {1362902400 -18000 1 CDT}
+    {1383462000 -21600 0 CST}
+    {1394352000 -18000 1 CDT}
+    {1414911600 -21600 0 CST}
+    {1425801600 -18000 1 CDT}
+    {1446361200 -21600 0 CST}
+    {1457856000 -18000 1 CDT}
+    {1478415600 -21600 0 CST}
+    {1489305600 -18000 1 CDT}
+    {1509865200 -21600 0 CST}
+    {1520755200 -18000 1 CDT}
+    {1541314800 -21600 0 CST}
+    {1552204800 -18000 1 CDT}
+    {1572764400 -21600 0 CST}
+    {1583654400 -18000 1 CDT}
+    {1604214000 -21600 0 CST}
+    {1615708800 -18000 1 CDT}
+    {1636268400 -21600 0 CST}
+    {1647158400 -18000 1 CDT}
+    {1667718000 -21600 0 CST}
+    {1678608000 -18000 1 CDT}
+    {1699167600 -21600 0 CST}
+    {1710057600 -18000 1 CDT}
+    {1730617200 -21600 0 CST}
+    {1741507200 -18000 1 CDT}
+    {1762066800 -21600 0 CST}
+    {1772956800 -18000 1 CDT}
+    {1793516400 -21600 0 CST}
+    {1805011200 -18000 1 CDT}
+    {1825570800 -21600 0 CST}
+    {1836460800 -18000 1 CDT}
+    {1857020400 -21600 0 CST}
+    {1867910400 -18000 1 CDT}
+    {1888470000 -21600 0 CST}
+    {1899360000 -18000 1 CDT}
+    {1919919600 -21600 0 CST}
+    {1930809600 -18000 1 CDT}
+    {1951369200 -21600 0 CST}
+    {1962864000 -18000 1 CDT}
+    {1983423600 -21600 0 CST}
+    {1994313600 -18000 1 CDT}
+    {2014873200 -21600 0 CST}
+    {2025763200 -18000 1 CDT}
+    {2046322800 -21600 0 CST}
+    {2057212800 -18000 1 CDT}
+    {2077772400 -21600 0 CST}
+    {2088662400 -18000 1 CDT}
+    {2109222000 -21600 0 CST}
+    {2120112000 -18000 1 CDT}
+    {2140671600 -21600 0 CST}
+    {2152166400 -18000 1 CDT}
+    {2172726000 -21600 0 CST}
+    {2183616000 -18000 1 CDT}
+    {2204175600 -21600 0 CST}
+    {2215065600 -18000 1 CDT}
+    {2235625200 -21600 0 CST}
+    {2246515200 -18000 1 CDT}
+    {2267074800 -21600 0 CST}
+    {2277964800 -18000 1 CDT}
+    {2298524400 -21600 0 CST}
+    {2309414400 -18000 1 CDT}
+    {2329974000 -21600 0 CST}
+    {2341468800 -18000 1 CDT}
+    {2362028400 -21600 0 CST}
+    {2372918400 -18000 1 CDT}
+    {2393478000 -21600 0 CST}
+    {2404368000 -18000 1 CDT}
+    {2424927600 -21600 0 CST}
+    {2435817600 -18000 1 CDT}
+    {2456377200 -21600 0 CST}
+    {2467267200 -18000 1 CDT}
+    {2487826800 -21600 0 CST}
+    {2499321600 -18000 1 CDT}
+    {2519881200 -21600 0 CST}
+    {2530771200 -18000 1 CDT}
+    {2551330800 -21600 0 CST}
+    {2562220800 -18000 1 CDT}
+    {2582780400 -21600 0 CST}
+    {2593670400 -18000 1 CDT}
+    {2614230000 -21600 0 CST}
+    {2625120000 -18000 1 CDT}
+    {2645679600 -21600 0 CST}
+    {2656569600 -18000 1 CDT}
+    {2677129200 -21600 0 CST}
+    {2688624000 -18000 1 CDT}
+    {2709183600 -21600 0 CST}
+    {2720073600 -18000 1 CDT}
+    {2740633200 -21600 0 CST}
+    {2751523200 -18000 1 CDT}
+    {2772082800 -21600 0 CST}
+    {2782972800 -18000 1 CDT}
+    {2803532400 -21600 0 CST}
+    {2814422400 -18000 1 CDT}
+    {2834982000 -21600 0 CST}
+    {2846476800 -18000 1 CDT}
+    {2867036400 -21600 0 CST}
+    {2877926400 -18000 1 CDT}
+    {2898486000 -21600 0 CST}
+    {2909376000 -18000 1 CDT}
+    {2929935600 -21600 0 CST}
+    {2940825600 -18000 1 CDT}
+    {2961385200 -21600 0 CST}
+    {2972275200 -18000 1 CDT}
+    {2992834800 -21600 0 CST}
+    {3003724800 -18000 1 CDT}
+    {3024284400 -21600 0 CST}
+    {3035779200 -18000 1 CDT}
+    {3056338800 -21600 0 CST}
+    {3067228800 -18000 1 CDT}
+    {3087788400 -21600 0 CST}
+    {3098678400 -18000 1 CDT}
+    {3119238000 -21600 0 CST}
+    {3130128000 -18000 1 CDT}
+    {3150687600 -21600 0 CST}
+    {3161577600 -18000 1 CDT}
+    {3182137200 -21600 0 CST}
+    {3193027200 -18000 1 CDT}
+    {3213586800 -21600 0 CST}
+    {3225081600 -18000 1 CDT}
+    {3245641200 -21600 0 CST}
+    {3256531200 -18000 1 CDT}
+    {3277090800 -21600 0 CST}
+    {3287980800 -18000 1 CDT}
+    {3308540400 -21600 0 CST}
+    {3319430400 -18000 1 CDT}
+    {3339990000 -21600 0 CST}
+    {3350880000 -18000 1 CDT}
+    {3371439600 -21600 0 CST}
+    {3382934400 -18000 1 CDT}
+    {3403494000 -21600 0 CST}
+    {3414384000 -18000 1 CDT}
+    {3434943600 -21600 0 CST}
+    {3445833600 -18000 1 CDT}
+    {3466393200 -21600 0 CST}
+    {3477283200 -18000 1 CDT}
+    {3497842800 -21600 0 CST}
+    {3508732800 -18000 1 CDT}
+    {3529292400 -21600 0 CST}
+    {3540182400 -18000 1 CDT}
+    {3560742000 -21600 0 CST}
+    {3572236800 -18000 1 CDT}
+    {3592796400 -21600 0 CST}
+    {3603686400 -18000 1 CDT}
+    {3624246000 -21600 0 CST}
+    {3635136000 -18000 1 CDT}
+    {3655695600 -21600 0 CST}
+    {3666585600 -18000 1 CDT}
+    {3687145200 -21600 0 CST}
+    {3698035200 -18000 1 CDT}
+    {3718594800 -21600 0 CST}
+    {3730089600 -18000 1 CDT}
+    {3750649200 -21600 0 CST}
+    {3761539200 -18000 1 CDT}
+    {3782098800 -21600 0 CST}
+    {3792988800 -18000 1 CDT}
+    {3813548400 -21600 0 CST}
+    {3824438400 -18000 1 CDT}
+    {3844998000 -21600 0 CST}
+    {3855888000 -18000 1 CDT}
+    {3876447600 -21600 0 CST}
+    {3887337600 -18000 1 CDT}
+    {3907897200 -21600 0 CST}
+    {3919392000 -18000 1 CDT}
+    {3939951600 -21600 0 CST}
+    {3950841600 -18000 1 CDT}
+    {3971401200 -21600 0 CST}
+    {3982291200 -18000 1 CDT}
+    {4002850800 -21600 0 CST}
+    {4013740800 -18000 1 CDT}
+    {4034300400 -21600 0 CST}
+    {4045190400 -18000 1 CDT}
+    {4065750000 -21600 0 CST}
+    {4076640000 -18000 1 CDT}
+    {4097199600 -21600 0 CST}
+}
diff --git a/library/tzdata/America/Indiana/Vevay b/library/tzdata/America/Indiana/Vevay
new file mode 100644
index 0000000..8d4157f
--- /dev/null
+++ b/library/tzdata/America/Indiana/Vevay
@@ -0,0 +1,213 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Indiana/Vevay) {
+    {-9223372036854775808 -20416 0 LMT}
+    {-2717647200 -21600 0 CST}
+    {-1633276800 -18000 1 CDT}
+    {-1615136400 -21600 0 CST}
+    {-1601827200 -18000 1 CDT}
+    {-1583686800 -21600 0 CST}
+    {-880214400 -18000 1 CWT}
+    {-769395600 -18000 1 CPT}
+    {-765392400 -21600 0 CST}
+    {-495043200 -18000 0 EST}
+    {-31518000 -18000 0 EST}
+    {-21488400 -14400 1 EDT}
+    {-5767200 -18000 0 EST}
+    {9961200 -14400 1 EDT}
+    {25682400 -18000 0 EST}
+    {41410800 -14400 1 EDT}
+    {57736800 -18000 0 EST}
+    {73465200 -14400 1 EDT}
+    {89186400 -18000 0 EST}
+    {94712400 -18000 0 EST}
+    {1136091600 -18000 0 EST}
+    {1143961200 -14400 1 EDT}
+    {1162101600 -18000 0 EST}
+    {1173596400 -14400 1 EDT}
+    {1194156000 -18000 0 EST}
+    {1205046000 -14400 1 EDT}
+    {1225605600 -18000 0 EST}
+    {1236495600 -14400 1 EDT}
+    {1257055200 -18000 0 EST}
+    {1268550000 -14400 1 EDT}
+    {1289109600 -18000 0 EST}
+    {1299999600 -14400 1 EDT}
+    {1320559200 -18000 0 EST}
+    {1331449200 -14400 1 EDT}
+    {1352008800 -18000 0 EST}
+    {1362898800 -14400 1 EDT}
+    {1383458400 -18000 0 EST}
+    {1394348400 -14400 1 EDT}
+    {1414908000 -18000 0 EST}
+    {1425798000 -14400 1 EDT}
+    {1446357600 -18000 0 EST}
+    {1457852400 -14400 1 EDT}
+    {1478412000 -18000 0 EST}
+    {1489302000 -14400 1 EDT}
+    {1509861600 -18000 0 EST}
+    {1520751600 -14400 1 EDT}
+    {1541311200 -18000 0 EST}
+    {1552201200 -14400 1 EDT}
+    {1572760800 -18000 0 EST}
+    {1583650800 -14400 1 EDT}
+    {1604210400 -18000 0 EST}
+    {1615705200 -14400 1 EDT}
+    {1636264800 -18000 0 EST}
+    {1647154800 -14400 1 EDT}
+    {1667714400 -18000 0 EST}
+    {1678604400 -14400 1 EDT}
+    {1699164000 -18000 0 EST}
+    {1710054000 -14400 1 EDT}
+    {1730613600 -18000 0 EST}
+    {1741503600 -14400 1 EDT}
+    {1762063200 -18000 0 EST}
+    {1772953200 -14400 1 EDT}
+    {1793512800 -18000 0 EST}
+    {1805007600 -14400 1 EDT}
+    {1825567200 -18000 0 EST}
+    {1836457200 -14400 1 EDT}
+    {1857016800 -18000 0 EST}
+    {1867906800 -14400 1 EDT}
+    {1888466400 -18000 0 EST}
+    {1899356400 -14400 1 EDT}
+    {1919916000 -18000 0 EST}
+    {1930806000 -14400 1 EDT}
+    {1951365600 -18000 0 EST}
+    {1962860400 -14400 1 EDT}
+    {1983420000 -18000 0 EST}
+    {1994310000 -14400 1 EDT}
+    {2014869600 -18000 0 EST}
+    {2025759600 -14400 1 EDT}
+    {2046319200 -18000 0 EST}
+    {2057209200 -14400 1 EDT}
+    {2077768800 -18000 0 EST}
+    {2088658800 -14400 1 EDT}
+    {2109218400 -18000 0 EST}
+    {2120108400 -14400 1 EDT}
+    {2140668000 -18000 0 EST}
+    {2152162800 -14400 1 EDT}
+    {2172722400 -18000 0 EST}
+    {2183612400 -14400 1 EDT}
+    {2204172000 -18000 0 EST}
+    {2215062000 -14400 1 EDT}
+    {2235621600 -18000 0 EST}
+    {2246511600 -14400 1 EDT}
+    {2267071200 -18000 0 EST}
+    {2277961200 -14400 1 EDT}
+    {2298520800 -18000 0 EST}
+    {2309410800 -14400 1 EDT}
+    {2329970400 -18000 0 EST}
+    {2341465200 -14400 1 EDT}
+    {2362024800 -18000 0 EST}
+    {2372914800 -14400 1 EDT}
+    {2393474400 -18000 0 EST}
+    {2404364400 -14400 1 EDT}
+    {2424924000 -18000 0 EST}
+    {2435814000 -14400 1 EDT}
+    {2456373600 -18000 0 EST}
+    {2467263600 -14400 1 EDT}
+    {2487823200 -18000 0 EST}
+    {2499318000 -14400 1 EDT}
+    {2519877600 -18000 0 EST}
+    {2530767600 -14400 1 EDT}
+    {2551327200 -18000 0 EST}
+    {2562217200 -14400 1 EDT}
+    {2582776800 -18000 0 EST}
+    {2593666800 -14400 1 EDT}
+    {2614226400 -18000 0 EST}
+    {2625116400 -14400 1 EDT}
+    {2645676000 -18000 0 EST}
+    {2656566000 -14400 1 EDT}
+    {2677125600 -18000 0 EST}
+    {2688620400 -14400 1 EDT}
+    {2709180000 -18000 0 EST}
+    {2720070000 -14400 1 EDT}
+    {2740629600 -18000 0 EST}
+    {2751519600 -14400 1 EDT}
+    {2772079200 -18000 0 EST}
+    {2782969200 -14400 1 EDT}
+    {2803528800 -18000 0 EST}
+    {2814418800 -14400 1 EDT}
+    {2834978400 -18000 0 EST}
+    {2846473200 -14400 1 EDT}
+    {2867032800 -18000 0 EST}
+    {2877922800 -14400 1 EDT}
+    {2898482400 -18000 0 EST}
+    {2909372400 -14400 1 EDT}
+    {2929932000 -18000 0 EST}
+    {2940822000 -14400 1 EDT}
+    {2961381600 -18000 0 EST}
+    {2972271600 -14400 1 EDT}
+    {2992831200 -18000 0 EST}
+    {3003721200 -14400 1 EDT}
+    {3024280800 -18000 0 EST}
+    {3035775600 -14400 1 EDT}
+    {3056335200 -18000 0 EST}
+    {3067225200 -14400 1 EDT}
+    {3087784800 -18000 0 EST}
+    {3098674800 -14400 1 EDT}
+    {3119234400 -18000 0 EST}
+    {3130124400 -14400 1 EDT}
+    {3150684000 -18000 0 EST}
+    {3161574000 -14400 1 EDT}
+    {3182133600 -18000 0 EST}
+    {3193023600 -14400 1 EDT}
+    {3213583200 -18000 0 EST}
+    {3225078000 -14400 1 EDT}
+    {3245637600 -18000 0 EST}
+    {3256527600 -14400 1 EDT}
+    {3277087200 -18000 0 EST}
+    {3287977200 -14400 1 EDT}
+    {3308536800 -18000 0 EST}
+    {3319426800 -14400 1 EDT}
+    {3339986400 -18000 0 EST}
+    {3350876400 -14400 1 EDT}
+    {3371436000 -18000 0 EST}
+    {3382930800 -14400 1 EDT}
+    {3403490400 -18000 0 EST}
+    {3414380400 -14400 1 EDT}
+    {3434940000 -18000 0 EST}
+    {3445830000 -14400 1 EDT}
+    {3466389600 -18000 0 EST}
+    {3477279600 -14400 1 EDT}
+    {3497839200 -18000 0 EST}
+    {3508729200 -14400 1 EDT}
+    {3529288800 -18000 0 EST}
+    {3540178800 -14400 1 EDT}
+    {3560738400 -18000 0 EST}
+    {3572233200 -14400 1 EDT}
+    {3592792800 -18000 0 EST}
+    {3603682800 -14400 1 EDT}
+    {3624242400 -18000 0 EST}
+    {3635132400 -14400 1 EDT}
+    {3655692000 -18000 0 EST}
+    {3666582000 -14400 1 EDT}
+    {3687141600 -18000 0 EST}
+    {3698031600 -14400 1 EDT}
+    {3718591200 -18000 0 EST}
+    {3730086000 -14400 1 EDT}
+    {3750645600 -18000 0 EST}
+    {3761535600 -14400 1 EDT}
+    {3782095200 -18000 0 EST}
+    {3792985200 -14400 1 EDT}
+    {3813544800 -18000 0 EST}
+    {3824434800 -14400 1 EDT}
+    {3844994400 -18000 0 EST}
+    {3855884400 -14400 1 EDT}
+    {3876444000 -18000 0 EST}
+    {3887334000 -14400 1 EDT}
+    {3907893600 -18000 0 EST}
+    {3919388400 -14400 1 EDT}
+    {3939948000 -18000 0 EST}
+    {3950838000 -14400 1 EDT}
+    {3971397600 -18000 0 EST}
+    {3982287600 -14400 1 EDT}
+    {4002847200 -18000 0 EST}
+    {4013737200 -14400 1 EDT}
+    {4034296800 -18000 0 EST}
+    {4045186800 -14400 1 EDT}
+    {4065746400 -18000 0 EST}
+    {4076636400 -14400 1 EDT}
+    {4097196000 -18000 0 EST}
+}
diff --git a/library/tzdata/America/Indiana/Vincennes b/library/tzdata/America/Indiana/Vincennes
new file mode 100644
index 0000000..1af7fc9
--- /dev/null
+++ b/library/tzdata/America/Indiana/Vincennes
@@ -0,0 +1,234 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Indiana/Vincennes) {
+    {-9223372036854775808 -21007 0 LMT}
+    {-2717647200 -21600 0 CST}
+    {-1633276800 -18000 1 CDT}
+    {-1615136400 -21600 0 CST}
+    {-1601827200 -18000 1 CDT}
+    {-1583686800 -21600 0 CST}
+    {-880214400 -18000 1 CWT}
+    {-769395600 -18000 1 CPT}
+    {-765392400 -21600 0 CST}
+    {-757360800 -21600 0 CST}
+    {-747244800 -18000 1 CDT}
+    {-733942800 -21600 0 CST}
+    {-526492800 -18000 1 CDT}
+    {-513190800 -21600 0 CST}
+    {-495043200 -18000 1 CDT}
+    {-481741200 -21600 0 CST}
+    {-462996000 -18000 1 CDT}
+    {-450291600 -21600 0 CST}
+    {-431539200 -18000 1 CDT}
+    {-418237200 -21600 0 CST}
+    {-400089600 -18000 1 CDT}
+    {-386787600 -21600 0 CST}
+    {-368640000 -18000 1 CDT}
+    {-355338000 -21600 0 CST}
+    {-337190400 -18000 1 CDT}
+    {-323888400 -21600 0 CST}
+    {-305740800 -18000 1 CDT}
+    {-289414800 -21600 0 CST}
+    {-273686400 -18000 1 CDT}
+    {-260989200 -21600 0 CST}
+    {-242236800 -18000 1 CDT}
+    {-226515600 -21600 0 CST}
+    {-210787200 -18000 1 CDT}
+    {-195066000 -21600 0 CST}
+    {-179337600 -18000 0 EST}
+    {-31518000 -18000 0 EST}
+    {-21488400 -14400 1 EDT}
+    {-5767200 -18000 0 EST}
+    {9961200 -14400 1 EDT}
+    {25682400 -18000 0 EST}
+    {31554000 -18000 0 EST}
+    {1143961200 -21600 0 CST}
+    {1143964800 -18000 1 CDT}
+    {1162105200 -21600 0 CST}
+    {1173600000 -18000 1 CDT}
+    {1194163200 -18000 0 EST}
+    {1205046000 -14400 1 EDT}
+    {1225605600 -18000 0 EST}
+    {1236495600 -14400 1 EDT}
+    {1257055200 -18000 0 EST}
+    {1268550000 -14400 1 EDT}
+    {1289109600 -18000 0 EST}
+    {1299999600 -14400 1 EDT}
+    {1320559200 -18000 0 EST}
+    {1331449200 -14400 1 EDT}
+    {1352008800 -18000 0 EST}
+    {1362898800 -14400 1 EDT}
+    {1383458400 -18000 0 EST}
+    {1394348400 -14400 1 EDT}
+    {1414908000 -18000 0 EST}
+    {1425798000 -14400 1 EDT}
+    {1446357600 -18000 0 EST}
+    {1457852400 -14400 1 EDT}
+    {1478412000 -18000 0 EST}
+    {1489302000 -14400 1 EDT}
+    {1509861600 -18000 0 EST}
+    {1520751600 -14400 1 EDT}
+    {1541311200 -18000 0 EST}
+    {1552201200 -14400 1 EDT}
+    {1572760800 -18000 0 EST}
+    {1583650800 -14400 1 EDT}
+    {1604210400 -18000 0 EST}
+    {1615705200 -14400 1 EDT}
+    {1636264800 -18000 0 EST}
+    {1647154800 -14400 1 EDT}
+    {1667714400 -18000 0 EST}
+    {1678604400 -14400 1 EDT}
+    {1699164000 -18000 0 EST}
+    {1710054000 -14400 1 EDT}
+    {1730613600 -18000 0 EST}
+    {1741503600 -14400 1 EDT}
+    {1762063200 -18000 0 EST}
+    {1772953200 -14400 1 EDT}
+    {1793512800 -18000 0 EST}
+    {1805007600 -14400 1 EDT}
+    {1825567200 -18000 0 EST}
+    {1836457200 -14400 1 EDT}
+    {1857016800 -18000 0 EST}
+    {1867906800 -14400 1 EDT}
+    {1888466400 -18000 0 EST}
+    {1899356400 -14400 1 EDT}
+    {1919916000 -18000 0 EST}
+    {1930806000 -14400 1 EDT}
+    {1951365600 -18000 0 EST}
+    {1962860400 -14400 1 EDT}
+    {1983420000 -18000 0 EST}
+    {1994310000 -14400 1 EDT}
+    {2014869600 -18000 0 EST}
+    {2025759600 -14400 1 EDT}
+    {2046319200 -18000 0 EST}
+    {2057209200 -14400 1 EDT}
+    {2077768800 -18000 0 EST}
+    {2088658800 -14400 1 EDT}
+    {2109218400 -18000 0 EST}
+    {2120108400 -14400 1 EDT}
+    {2140668000 -18000 0 EST}
+    {2152162800 -14400 1 EDT}
+    {2172722400 -18000 0 EST}
+    {2183612400 -14400 1 EDT}
+    {2204172000 -18000 0 EST}
+    {2215062000 -14400 1 EDT}
+    {2235621600 -18000 0 EST}
+    {2246511600 -14400 1 EDT}
+    {2267071200 -18000 0 EST}
+    {2277961200 -14400 1 EDT}
+    {2298520800 -18000 0 EST}
+    {2309410800 -14400 1 EDT}
+    {2329970400 -18000 0 EST}
+    {2341465200 -14400 1 EDT}
+    {2362024800 -18000 0 EST}
+    {2372914800 -14400 1 EDT}
+    {2393474400 -18000 0 EST}
+    {2404364400 -14400 1 EDT}
+    {2424924000 -18000 0 EST}
+    {2435814000 -14400 1 EDT}
+    {2456373600 -18000 0 EST}
+    {2467263600 -14400 1 EDT}
+    {2487823200 -18000 0 EST}
+    {2499318000 -14400 1 EDT}
+    {2519877600 -18000 0 EST}
+    {2530767600 -14400 1 EDT}
+    {2551327200 -18000 0 EST}
+    {2562217200 -14400 1 EDT}
+    {2582776800 -18000 0 EST}
+    {2593666800 -14400 1 EDT}
+    {2614226400 -18000 0 EST}
+    {2625116400 -14400 1 EDT}
+    {2645676000 -18000 0 EST}
+    {2656566000 -14400 1 EDT}
+    {2677125600 -18000 0 EST}
+    {2688620400 -14400 1 EDT}
+    {2709180000 -18000 0 EST}
+    {2720070000 -14400 1 EDT}
+    {2740629600 -18000 0 EST}
+    {2751519600 -14400 1 EDT}
+    {2772079200 -18000 0 EST}
+    {2782969200 -14400 1 EDT}
+    {2803528800 -18000 0 EST}
+    {2814418800 -14400 1 EDT}
+    {2834978400 -18000 0 EST}
+    {2846473200 -14400 1 EDT}
+    {2867032800 -18000 0 EST}
+    {2877922800 -14400 1 EDT}
+    {2898482400 -18000 0 EST}
+    {2909372400 -14400 1 EDT}
+    {2929932000 -18000 0 EST}
+    {2940822000 -14400 1 EDT}
+    {2961381600 -18000 0 EST}
+    {2972271600 -14400 1 EDT}
+    {2992831200 -18000 0 EST}
+    {3003721200 -14400 1 EDT}
+    {3024280800 -18000 0 EST}
+    {3035775600 -14400 1 EDT}
+    {3056335200 -18000 0 EST}
+    {3067225200 -14400 1 EDT}
+    {3087784800 -18000 0 EST}
+    {3098674800 -14400 1 EDT}
+    {3119234400 -18000 0 EST}
+    {3130124400 -14400 1 EDT}
+    {3150684000 -18000 0 EST}
+    {3161574000 -14400 1 EDT}
+    {3182133600 -18000 0 EST}
+    {3193023600 -14400 1 EDT}
+    {3213583200 -18000 0 EST}
+    {3225078000 -14400 1 EDT}
+    {3245637600 -18000 0 EST}
+    {3256527600 -14400 1 EDT}
+    {3277087200 -18000 0 EST}
+    {3287977200 -14400 1 EDT}
+    {3308536800 -18000 0 EST}
+    {3319426800 -14400 1 EDT}
+    {3339986400 -18000 0 EST}
+    {3350876400 -14400 1 EDT}
+    {3371436000 -18000 0 EST}
+    {3382930800 -14400 1 EDT}
+    {3403490400 -18000 0 EST}
+    {3414380400 -14400 1 EDT}
+    {3434940000 -18000 0 EST}
+    {3445830000 -14400 1 EDT}
+    {3466389600 -18000 0 EST}
+    {3477279600 -14400 1 EDT}
+    {3497839200 -18000 0 EST}
+    {3508729200 -14400 1 EDT}
+    {3529288800 -18000 0 EST}
+    {3540178800 -14400 1 EDT}
+    {3560738400 -18000 0 EST}
+    {3572233200 -14400 1 EDT}
+    {3592792800 -18000 0 EST}
+    {3603682800 -14400 1 EDT}
+    {3624242400 -18000 0 EST}
+    {3635132400 -14400 1 EDT}
+    {3655692000 -18000 0 EST}
+    {3666582000 -14400 1 EDT}
+    {3687141600 -18000 0 EST}
+    {3698031600 -14400 1 EDT}
+    {3718591200 -18000 0 EST}
+    {3730086000 -14400 1 EDT}
+    {3750645600 -18000 0 EST}
+    {3761535600 -14400 1 EDT}
+    {3782095200 -18000 0 EST}
+    {3792985200 -14400 1 EDT}
+    {3813544800 -18000 0 EST}
+    {3824434800 -14400 1 EDT}
+    {3844994400 -18000 0 EST}
+    {3855884400 -14400 1 EDT}
+    {3876444000 -18000 0 EST}
+    {3887334000 -14400 1 EDT}
+    {3907893600 -18000 0 EST}
+    {3919388400 -14400 1 EDT}
+    {3939948000 -18000 0 EST}
+    {3950838000 -14400 1 EDT}
+    {3971397600 -18000 0 EST}
+    {3982287600 -14400 1 EDT}
+    {4002847200 -18000 0 EST}
+    {4013737200 -14400 1 EDT}
+    {4034296800 -18000 0 EST}
+    {4045186800 -14400 1 EDT}
+    {4065746400 -18000 0 EST}
+    {4076636400 -14400 1 EDT}
+    {4097196000 -18000 0 EST}
+}
diff --git a/library/tzdata/America/Indiana/Winamac b/library/tzdata/America/Indiana/Winamac
new file mode 100644
index 0000000..fb6cd37
--- /dev/null
+++ b/library/tzdata/America/Indiana/Winamac
@@ -0,0 +1,240 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Indiana/Winamac) {
+    {-9223372036854775808 -20785 0 LMT}
+    {-2717647200 -21600 0 CST}
+    {-1633276800 -18000 1 CDT}
+    {-1615136400 -21600 0 CST}
+    {-1601827200 -18000 1 CDT}
+    {-1583686800 -21600 0 CST}
+    {-880214400 -18000 1 CWT}
+    {-769395600 -18000 1 CPT}
+    {-765392400 -21600 0 CST}
+    {-757360800 -21600 0 CST}
+    {-747244800 -18000 1 CDT}
+    {-733942800 -21600 0 CST}
+    {-715795200 -18000 1 CDT}
+    {-702493200 -21600 0 CST}
+    {-684345600 -18000 1 CDT}
+    {-671043600 -21600 0 CST}
+    {-652896000 -18000 1 CDT}
+    {-639594000 -21600 0 CST}
+    {-620841600 -18000 1 CDT}
+    {-608144400 -21600 0 CST}
+    {-589392000 -18000 1 CDT}
+    {-576090000 -21600 0 CST}
+    {-557942400 -18000 1 CDT}
+    {-544640400 -21600 0 CST}
+    {-526492800 -18000 1 CDT}
+    {-513190800 -21600 0 CST}
+    {-495043200 -18000 1 CDT}
+    {-481741200 -21600 0 CST}
+    {-463593600 -18000 1 CDT}
+    {-447267600 -21600 0 CST}
+    {-431539200 -18000 1 CDT}
+    {-415818000 -21600 0 CST}
+    {-400089600 -18000 1 CDT}
+    {-386787600 -21600 0 CST}
+    {-368640000 -18000 1 CDT}
+    {-355338000 -21600 0 CST}
+    {-337190400 -18000 1 CDT}
+    {-323888400 -21600 0 CST}
+    {-305740800 -18000 1 CDT}
+    {-292438800 -21600 0 CST}
+    {-273686400 -18000 0 EST}
+    {-31518000 -18000 0 EST}
+    {-21488400 -14400 1 EDT}
+    {-5767200 -18000 0 EST}
+    {9961200 -14400 1 EDT}
+    {25682400 -18000 0 EST}
+    {31554000 -18000 0 EST}
+    {1143961200 -21600 0 CST}
+    {1143964800 -18000 1 CDT}
+    {1162105200 -21600 0 CST}
+    {1173600000 -14400 0 EDT}
+    {1194156000 -18000 0 EST}
+    {1205046000 -14400 1 EDT}
+    {1225605600 -18000 0 EST}
+    {1236495600 -14400 1 EDT}
+    {1257055200 -18000 0 EST}
+    {1268550000 -14400 1 EDT}
+    {1289109600 -18000 0 EST}
+    {1299999600 -14400 1 EDT}
+    {1320559200 -18000 0 EST}
+    {1331449200 -14400 1 EDT}
+    {1352008800 -18000 0 EST}
+    {1362898800 -14400 1 EDT}
+    {1383458400 -18000 0 EST}
+    {1394348400 -14400 1 EDT}
+    {1414908000 -18000 0 EST}
+    {1425798000 -14400 1 EDT}
+    {1446357600 -18000 0 EST}
+    {1457852400 -14400 1 EDT}
+    {1478412000 -18000 0 EST}
+    {1489302000 -14400 1 EDT}
+    {1509861600 -18000 0 EST}
+    {1520751600 -14400 1 EDT}
+    {1541311200 -18000 0 EST}
+    {1552201200 -14400 1 EDT}
+    {1572760800 -18000 0 EST}
+    {1583650800 -14400 1 EDT}
+    {1604210400 -18000 0 EST}
+    {1615705200 -14400 1 EDT}
+    {1636264800 -18000 0 EST}
+    {1647154800 -14400 1 EDT}
+    {1667714400 -18000 0 EST}
+    {1678604400 -14400 1 EDT}
+    {1699164000 -18000 0 EST}
+    {1710054000 -14400 1 EDT}
+    {1730613600 -18000 0 EST}
+    {1741503600 -14400 1 EDT}
+    {1762063200 -18000 0 EST}
+    {1772953200 -14400 1 EDT}
+    {1793512800 -18000 0 EST}
+    {1805007600 -14400 1 EDT}
+    {1825567200 -18000 0 EST}
+    {1836457200 -14400 1 EDT}
+    {1857016800 -18000 0 EST}
+    {1867906800 -14400 1 EDT}
+    {1888466400 -18000 0 EST}
+    {1899356400 -14400 1 EDT}
+    {1919916000 -18000 0 EST}
+    {1930806000 -14400 1 EDT}
+    {1951365600 -18000 0 EST}
+    {1962860400 -14400 1 EDT}
+    {1983420000 -18000 0 EST}
+    {1994310000 -14400 1 EDT}
+    {2014869600 -18000 0 EST}
+    {2025759600 -14400 1 EDT}
+    {2046319200 -18000 0 EST}
+    {2057209200 -14400 1 EDT}
+    {2077768800 -18000 0 EST}
+    {2088658800 -14400 1 EDT}
+    {2109218400 -18000 0 EST}
+    {2120108400 -14400 1 EDT}
+    {2140668000 -18000 0 EST}
+    {2152162800 -14400 1 EDT}
+    {2172722400 -18000 0 EST}
+    {2183612400 -14400 1 EDT}
+    {2204172000 -18000 0 EST}
+    {2215062000 -14400 1 EDT}
+    {2235621600 -18000 0 EST}
+    {2246511600 -14400 1 EDT}
+    {2267071200 -18000 0 EST}
+    {2277961200 -14400 1 EDT}
+    {2298520800 -18000 0 EST}
+    {2309410800 -14400 1 EDT}
+    {2329970400 -18000 0 EST}
+    {2341465200 -14400 1 EDT}
+    {2362024800 -18000 0 EST}
+    {2372914800 -14400 1 EDT}
+    {2393474400 -18000 0 EST}
+    {2404364400 -14400 1 EDT}
+    {2424924000 -18000 0 EST}
+    {2435814000 -14400 1 EDT}
+    {2456373600 -18000 0 EST}
+    {2467263600 -14400 1 EDT}
+    {2487823200 -18000 0 EST}
+    {2499318000 -14400 1 EDT}
+    {2519877600 -18000 0 EST}
+    {2530767600 -14400 1 EDT}
+    {2551327200 -18000 0 EST}
+    {2562217200 -14400 1 EDT}
+    {2582776800 -18000 0 EST}
+    {2593666800 -14400 1 EDT}
+    {2614226400 -18000 0 EST}
+    {2625116400 -14400 1 EDT}
+    {2645676000 -18000 0 EST}
+    {2656566000 -14400 1 EDT}
+    {2677125600 -18000 0 EST}
+    {2688620400 -14400 1 EDT}
+    {2709180000 -18000 0 EST}
+    {2720070000 -14400 1 EDT}
+    {2740629600 -18000 0 EST}
+    {2751519600 -14400 1 EDT}
+    {2772079200 -18000 0 EST}
+    {2782969200 -14400 1 EDT}
+    {2803528800 -18000 0 EST}
+    {2814418800 -14400 1 EDT}
+    {2834978400 -18000 0 EST}
+    {2846473200 -14400 1 EDT}
+    {2867032800 -18000 0 EST}
+    {2877922800 -14400 1 EDT}
+    {2898482400 -18000 0 EST}
+    {2909372400 -14400 1 EDT}
+    {2929932000 -18000 0 EST}
+    {2940822000 -14400 1 EDT}
+    {2961381600 -18000 0 EST}
+    {2972271600 -14400 1 EDT}
+    {2992831200 -18000 0 EST}
+    {3003721200 -14400 1 EDT}
+    {3024280800 -18000 0 EST}
+    {3035775600 -14400 1 EDT}
+    {3056335200 -18000 0 EST}
+    {3067225200 -14400 1 EDT}
+    {3087784800 -18000 0 EST}
+    {3098674800 -14400 1 EDT}
+    {3119234400 -18000 0 EST}
+    {3130124400 -14400 1 EDT}
+    {3150684000 -18000 0 EST}
+    {3161574000 -14400 1 EDT}
+    {3182133600 -18000 0 EST}
+    {3193023600 -14400 1 EDT}
+    {3213583200 -18000 0 EST}
+    {3225078000 -14400 1 EDT}
+    {3245637600 -18000 0 EST}
+    {3256527600 -14400 1 EDT}
+    {3277087200 -18000 0 EST}
+    {3287977200 -14400 1 EDT}
+    {3308536800 -18000 0 EST}
+    {3319426800 -14400 1 EDT}
+    {3339986400 -18000 0 EST}
+    {3350876400 -14400 1 EDT}
+    {3371436000 -18000 0 EST}
+    {3382930800 -14400 1 EDT}
+    {3403490400 -18000 0 EST}
+    {3414380400 -14400 1 EDT}
+    {3434940000 -18000 0 EST}
+    {3445830000 -14400 1 EDT}
+    {3466389600 -18000 0 EST}
+    {3477279600 -14400 1 EDT}
+    {3497839200 -18000 0 EST}
+    {3508729200 -14400 1 EDT}
+    {3529288800 -18000 0 EST}
+    {3540178800 -14400 1 EDT}
+    {3560738400 -18000 0 EST}
+    {3572233200 -14400 1 EDT}
+    {3592792800 -18000 0 EST}
+    {3603682800 -14400 1 EDT}
+    {3624242400 -18000 0 EST}
+    {3635132400 -14400 1 EDT}
+    {3655692000 -18000 0 EST}
+    {3666582000 -14400 1 EDT}
+    {3687141600 -18000 0 EST}
+    {3698031600 -14400 1 EDT}
+    {3718591200 -18000 0 EST}
+    {3730086000 -14400 1 EDT}
+    {3750645600 -18000 0 EST}
+    {3761535600 -14400 1 EDT}
+    {3782095200 -18000 0 EST}
+    {3792985200 -14400 1 EDT}
+    {3813544800 -18000 0 EST}
+    {3824434800 -14400 1 EDT}
+    {3844994400 -18000 0 EST}
+    {3855884400 -14400 1 EDT}
+    {3876444000 -18000 0 EST}
+    {3887334000 -14400 1 EDT}
+    {3907893600 -18000 0 EST}
+    {3919388400 -14400 1 EDT}
+    {3939948000 -18000 0 EST}
+    {3950838000 -14400 1 EDT}
+    {3971397600 -18000 0 EST}
+    {3982287600 -14400 1 EDT}
+    {4002847200 -18000 0 EST}
+    {4013737200 -14400 1 EDT}
+    {4034296800 -18000 0 EST}
+    {4045186800 -14400 1 EDT}
+    {4065746400 -18000 0 EST}
+    {4076636400 -14400 1 EDT}
+    {4097196000 -18000 0 EST}
+}
diff --git a/library/tzdata/America/Indianapolis b/library/tzdata/America/Indianapolis
new file mode 100644
index 0000000..7398545
--- /dev/null
+++ b/library/tzdata/America/Indianapolis
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(America/Indiana/Indianapolis)]} {
+    LoadTimeZoneFile America/Indiana/Indianapolis
+}
+set TZData(:America/Indianapolis) $TZData(:America/Indiana/Indianapolis)
diff --git a/library/tzdata/America/Inuvik b/library/tzdata/America/Inuvik
new file mode 100644
index 0000000..08f0fd6
--- /dev/null
+++ b/library/tzdata/America/Inuvik
@@ -0,0 +1,249 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Inuvik) {
+    {-9223372036854775808 0 0 -00}
+    {-536457600 -28800 0 PST}
+    {-147888000 -21600 1 PDDT}
+    {-131558400 -28800 0 PST}
+    {315558000 -25200 0 MST}
+    {325674000 -21600 1 MDT}
+    {341395200 -25200 0 MST}
+    {357123600 -21600 1 MDT}
+    {372844800 -25200 0 MST}
+    {388573200 -21600 1 MDT}
+    {404899200 -25200 0 MST}
+    {420022800 -21600 1 MDT}
+    {436348800 -25200 0 MST}
+    {452077200 -21600 1 MDT}
+    {467798400 -25200 0 MST}
+    {483526800 -21600 1 MDT}
+    {499248000 -25200 0 MST}
+    {514976400 -21600 1 MDT}
+    {530697600 -25200 0 MST}
+    {544611600 -21600 1 MDT}
+    {562147200 -25200 0 MST}
+    {576061200 -21600 1 MDT}
+    {594201600 -25200 0 MST}
+    {607510800 -21600 1 MDT}
+    {625651200 -25200 0 MST}
+    {638960400 -21600 1 MDT}
+    {657100800 -25200 0 MST}
+    {671014800 -21600 1 MDT}
+    {688550400 -25200 0 MST}
+    {702464400 -21600 1 MDT}
+    {720000000 -25200 0 MST}
+    {733914000 -21600 1 MDT}
+    {752054400 -25200 0 MST}
+    {765363600 -21600 1 MDT}
+    {783504000 -25200 0 MST}
+    {796813200 -21600 1 MDT}
+    {814953600 -25200 0 MST}
+    {828867600 -21600 1 MDT}
+    {846403200 -25200 0 MST}
+    {860317200 -21600 1 MDT}
+    {877852800 -25200 0 MST}
+    {891766800 -21600 1 MDT}
+    {909302400 -25200 0 MST}
+    {923216400 -21600 1 MDT}
+    {941356800 -25200 0 MST}
+    {954666000 -21600 1 MDT}
+    {972806400 -25200 0 MST}
+    {986115600 -21600 1 MDT}
+    {1004256000 -25200 0 MST}
+    {1018170000 -21600 1 MDT}
+    {1035705600 -25200 0 MST}
+    {1049619600 -21600 1 MDT}
+    {1067155200 -25200 0 MST}
+    {1081069200 -21600 1 MDT}
+    {1099209600 -25200 0 MST}
+    {1112518800 -21600 1 MDT}
+    {1130659200 -25200 0 MST}
+    {1143968400 -21600 1 MDT}
+    {1162108800 -25200 0 MST}
+    {1173603600 -21600 1 MDT}
+    {1194163200 -25200 0 MST}
+    {1205053200 -21600 1 MDT}
+    {1225612800 -25200 0 MST}
+    {1236502800 -21600 1 MDT}
+    {1257062400 -25200 0 MST}
+    {1268557200 -21600 1 MDT}
+    {1289116800 -25200 0 MST}
+    {1300006800 -21600 1 MDT}
+    {1320566400 -25200 0 MST}
+    {1331456400 -21600 1 MDT}
+    {1352016000 -25200 0 MST}
+    {1362906000 -21600 1 MDT}
+    {1383465600 -25200 0 MST}
+    {1394355600 -21600 1 MDT}
+    {1414915200 -25200 0 MST}
+    {1425805200 -21600 1 MDT}
+    {1446364800 -25200 0 MST}
+    {1457859600 -21600 1 MDT}
+    {1478419200 -25200 0 MST}
+    {1489309200 -21600 1 MDT}
+    {1509868800 -25200 0 MST}
+    {1520758800 -21600 1 MDT}
+    {1541318400 -25200 0 MST}
+    {1552208400 -21600 1 MDT}
+    {1572768000 -25200 0 MST}
+    {1583658000 -21600 1 MDT}
+    {1604217600 -25200 0 MST}
+    {1615712400 -21600 1 MDT}
+    {1636272000 -25200 0 MST}
+    {1647162000 -21600 1 MDT}
+    {1667721600 -25200 0 MST}
+    {1678611600 -21600 1 MDT}
+    {1699171200 -25200 0 MST}
+    {1710061200 -21600 1 MDT}
+    {1730620800 -25200 0 MST}
+    {1741510800 -21600 1 MDT}
+    {1762070400 -25200 0 MST}
+    {1772960400 -21600 1 MDT}
+    {1793520000 -25200 0 MST}
+    {1805014800 -21600 1 MDT}
+    {1825574400 -25200 0 MST}
+    {1836464400 -21600 1 MDT}
+    {1857024000 -25200 0 MST}
+    {1867914000 -21600 1 MDT}
+    {1888473600 -25200 0 MST}
+    {1899363600 -21600 1 MDT}
+    {1919923200 -25200 0 MST}
+    {1930813200 -21600 1 MDT}
+    {1951372800 -25200 0 MST}
+    {1962867600 -21600 1 MDT}
+    {1983427200 -25200 0 MST}
+    {1994317200 -21600 1 MDT}
+    {2014876800 -25200 0 MST}
+    {2025766800 -21600 1 MDT}
+    {2046326400 -25200 0 MST}
+    {2057216400 -21600 1 MDT}
+    {2077776000 -25200 0 MST}
+    {2088666000 -21600 1 MDT}
+    {2109225600 -25200 0 MST}
+    {2120115600 -21600 1 MDT}
+    {2140675200 -25200 0 MST}
+    {2152170000 -21600 1 MDT}
+    {2172729600 -25200 0 MST}
+    {2183619600 -21600 1 MDT}
+    {2204179200 -25200 0 MST}
+    {2215069200 -21600 1 MDT}
+    {2235628800 -25200 0 MST}
+    {2246518800 -21600 1 MDT}
+    {2267078400 -25200 0 MST}
+    {2277968400 -21600 1 MDT}
+    {2298528000 -25200 0 MST}
+    {2309418000 -21600 1 MDT}
+    {2329977600 -25200 0 MST}
+    {2341472400 -21600 1 MDT}
+    {2362032000 -25200 0 MST}
+    {2372922000 -21600 1 MDT}
+    {2393481600 -25200 0 MST}
+    {2404371600 -21600 1 MDT}
+    {2424931200 -25200 0 MST}
+    {2435821200 -21600 1 MDT}
+    {2456380800 -25200 0 MST}
+    {2467270800 -21600 1 MDT}
+    {2487830400 -25200 0 MST}
+    {2499325200 -21600 1 MDT}
+    {2519884800 -25200 0 MST}
+    {2530774800 -21600 1 MDT}
+    {2551334400 -25200 0 MST}
+    {2562224400 -21600 1 MDT}
+    {2582784000 -25200 0 MST}
+    {2593674000 -21600 1 MDT}
+    {2614233600 -25200 0 MST}
+    {2625123600 -21600 1 MDT}
+    {2645683200 -25200 0 MST}
+    {2656573200 -21600 1 MDT}
+    {2677132800 -25200 0 MST}
+    {2688627600 -21600 1 MDT}
+    {2709187200 -25200 0 MST}
+    {2720077200 -21600 1 MDT}
+    {2740636800 -25200 0 MST}
+    {2751526800 -21600 1 MDT}
+    {2772086400 -25200 0 MST}
+    {2782976400 -21600 1 MDT}
+    {2803536000 -25200 0 MST}
+    {2814426000 -21600 1 MDT}
+    {2834985600 -25200 0 MST}
+    {2846480400 -21600 1 MDT}
+    {2867040000 -25200 0 MST}
+    {2877930000 -21600 1 MDT}
+    {2898489600 -25200 0 MST}
+    {2909379600 -21600 1 MDT}
+    {2929939200 -25200 0 MST}
+    {2940829200 -21600 1 MDT}
+    {2961388800 -25200 0 MST}
+    {2972278800 -21600 1 MDT}
+    {2992838400 -25200 0 MST}
+    {3003728400 -21600 1 MDT}
+    {3024288000 -25200 0 MST}
+    {3035782800 -21600 1 MDT}
+    {3056342400 -25200 0 MST}
+    {3067232400 -21600 1 MDT}
+    {3087792000 -25200 0 MST}
+    {3098682000 -21600 1 MDT}
+    {3119241600 -25200 0 MST}
+    {3130131600 -21600 1 MDT}
+    {3150691200 -25200 0 MST}
+    {3161581200 -21600 1 MDT}
+    {3182140800 -25200 0 MST}
+    {3193030800 -21600 1 MDT}
+    {3213590400 -25200 0 MST}
+    {3225085200 -21600 1 MDT}
+    {3245644800 -25200 0 MST}
+    {3256534800 -21600 1 MDT}
+    {3277094400 -25200 0 MST}
+    {3287984400 -21600 1 MDT}
+    {3308544000 -25200 0 MST}
+    {3319434000 -21600 1 MDT}
+    {3339993600 -25200 0 MST}
+    {3350883600 -21600 1 MDT}
+    {3371443200 -25200 0 MST}
+    {3382938000 -21600 1 MDT}
+    {3403497600 -25200 0 MST}
+    {3414387600 -21600 1 MDT}
+    {3434947200 -25200 0 MST}
+    {3445837200 -21600 1 MDT}
+    {3466396800 -25200 0 MST}
+    {3477286800 -21600 1 MDT}
+    {3497846400 -25200 0 MST}
+    {3508736400 -21600 1 MDT}
+    {3529296000 -25200 0 MST}
+    {3540186000 -21600 1 MDT}
+    {3560745600 -25200 0 MST}
+    {3572240400 -21600 1 MDT}
+    {3592800000 -25200 0 MST}
+    {3603690000 -21600 1 MDT}
+    {3624249600 -25200 0 MST}
+    {3635139600 -21600 1 MDT}
+    {3655699200 -25200 0 MST}
+    {3666589200 -21600 1 MDT}
+    {3687148800 -25200 0 MST}
+    {3698038800 -21600 1 MDT}
+    {3718598400 -25200 0 MST}
+    {3730093200 -21600 1 MDT}
+    {3750652800 -25200 0 MST}
+    {3761542800 -21600 1 MDT}
+    {3782102400 -25200 0 MST}
+    {3792992400 -21600 1 MDT}
+    {3813552000 -25200 0 MST}
+    {3824442000 -21600 1 MDT}
+    {3845001600 -25200 0 MST}
+    {3855891600 -21600 1 MDT}
+    {3876451200 -25200 0 MST}
+    {3887341200 -21600 1 MDT}
+    {3907900800 -25200 0 MST}
+    {3919395600 -21600 1 MDT}
+    {3939955200 -25200 0 MST}
+    {3950845200 -21600 1 MDT}
+    {3971404800 -25200 0 MST}
+    {3982294800 -21600 1 MDT}
+    {4002854400 -25200 0 MST}
+    {4013744400 -21600 1 MDT}
+    {4034304000 -25200 0 MST}
+    {4045194000 -21600 1 MDT}
+    {4065753600 -25200 0 MST}
+    {4076643600 -21600 1 MDT}
+    {4097203200 -25200 0 MST}
+}
diff --git a/library/tzdata/America/Iqaluit b/library/tzdata/America/Iqaluit
new file mode 100644
index 0000000..ff82866
--- /dev/null
+++ b/library/tzdata/America/Iqaluit
@@ -0,0 +1,250 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Iqaluit) {
+    {-9223372036854775808 0 0 -00}
+    {-865296000 -14400 0 EWT}
+    {-769395600 -14400 1 EPT}
+    {-765396000 -18000 0 EST}
+    {-147898800 -10800 1 EDDT}
+    {-131569200 -18000 0 EST}
+    {325666800 -14400 1 EDT}
+    {341388000 -18000 0 EST}
+    {357116400 -14400 1 EDT}
+    {372837600 -18000 0 EST}
+    {388566000 -14400 1 EDT}
+    {404892000 -18000 0 EST}
+    {420015600 -14400 1 EDT}
+    {436341600 -18000 0 EST}
+    {452070000 -14400 1 EDT}
+    {467791200 -18000 0 EST}
+    {483519600 -14400 1 EDT}
+    {499240800 -18000 0 EST}
+    {514969200 -14400 1 EDT}
+    {530690400 -18000 0 EST}
+    {544604400 -14400 1 EDT}
+    {562140000 -18000 0 EST}
+    {576054000 -14400 1 EDT}
+    {594194400 -18000 0 EST}
+    {607503600 -14400 1 EDT}
+    {625644000 -18000 0 EST}
+    {638953200 -14400 1 EDT}
+    {657093600 -18000 0 EST}
+    {671007600 -14400 1 EDT}
+    {688543200 -18000 0 EST}
+    {702457200 -14400 1 EDT}
+    {719992800 -18000 0 EST}
+    {733906800 -14400 1 EDT}
+    {752047200 -18000 0 EST}
+    {765356400 -14400 1 EDT}
+    {783496800 -18000 0 EST}
+    {796806000 -14400 1 EDT}
+    {814946400 -18000 0 EST}
+    {828860400 -14400 1 EDT}
+    {846396000 -18000 0 EST}
+    {860310000 -14400 1 EDT}
+    {877845600 -18000 0 EST}
+    {891759600 -14400 1 EDT}
+    {909295200 -18000 0 EST}
+    {923209200 -14400 1 EDT}
+    {941353200 -21600 0 CST}
+    {954662400 -18000 1 CDT}
+    {972806400 -18000 0 EST}
+    {986108400 -14400 1 EDT}
+    {1004248800 -18000 0 EST}
+    {1018162800 -14400 1 EDT}
+    {1035698400 -18000 0 EST}
+    {1049612400 -14400 1 EDT}
+    {1067148000 -18000 0 EST}
+    {1081062000 -14400 1 EDT}
+    {1099202400 -18000 0 EST}
+    {1112511600 -14400 1 EDT}
+    {1130652000 -18000 0 EST}
+    {1143961200 -14400 1 EDT}
+    {1162101600 -18000 0 EST}
+    {1173596400 -14400 1 EDT}
+    {1194156000 -18000 0 EST}
+    {1205046000 -14400 1 EDT}
+    {1225605600 -18000 0 EST}
+    {1236495600 -14400 1 EDT}
+    {1257055200 -18000 0 EST}
+    {1268550000 -14400 1 EDT}
+    {1289109600 -18000 0 EST}
+    {1299999600 -14400 1 EDT}
+    {1320559200 -18000 0 EST}
+    {1331449200 -14400 1 EDT}
+    {1352008800 -18000 0 EST}
+    {1362898800 -14400 1 EDT}
+    {1383458400 -18000 0 EST}
+    {1394348400 -14400 1 EDT}
+    {1414908000 -18000 0 EST}
+    {1425798000 -14400 1 EDT}
+    {1446357600 -18000 0 EST}
+    {1457852400 -14400 1 EDT}
+    {1478412000 -18000 0 EST}
+    {1489302000 -14400 1 EDT}
+    {1509861600 -18000 0 EST}
+    {1520751600 -14400 1 EDT}
+    {1541311200 -18000 0 EST}
+    {1552201200 -14400 1 EDT}
+    {1572760800 -18000 0 EST}
+    {1583650800 -14400 1 EDT}
+    {1604210400 -18000 0 EST}
+    {1615705200 -14400 1 EDT}
+    {1636264800 -18000 0 EST}
+    {1647154800 -14400 1 EDT}
+    {1667714400 -18000 0 EST}
+    {1678604400 -14400 1 EDT}
+    {1699164000 -18000 0 EST}
+    {1710054000 -14400 1 EDT}
+    {1730613600 -18000 0 EST}
+    {1741503600 -14400 1 EDT}
+    {1762063200 -18000 0 EST}
+    {1772953200 -14400 1 EDT}
+    {1793512800 -18000 0 EST}
+    {1805007600 -14400 1 EDT}
+    {1825567200 -18000 0 EST}
+    {1836457200 -14400 1 EDT}
+    {1857016800 -18000 0 EST}
+    {1867906800 -14400 1 EDT}
+    {1888466400 -18000 0 EST}
+    {1899356400 -14400 1 EDT}
+    {1919916000 -18000 0 EST}
+    {1930806000 -14400 1 EDT}
+    {1951365600 -18000 0 EST}
+    {1962860400 -14400 1 EDT}
+    {1983420000 -18000 0 EST}
+    {1994310000 -14400 1 EDT}
+    {2014869600 -18000 0 EST}
+    {2025759600 -14400 1 EDT}
+    {2046319200 -18000 0 EST}
+    {2057209200 -14400 1 EDT}
+    {2077768800 -18000 0 EST}
+    {2088658800 -14400 1 EDT}
+    {2109218400 -18000 0 EST}
+    {2120108400 -14400 1 EDT}
+    {2140668000 -18000 0 EST}
+    {2152162800 -14400 1 EDT}
+    {2172722400 -18000 0 EST}
+    {2183612400 -14400 1 EDT}
+    {2204172000 -18000 0 EST}
+    {2215062000 -14400 1 EDT}
+    {2235621600 -18000 0 EST}
+    {2246511600 -14400 1 EDT}
+    {2267071200 -18000 0 EST}
+    {2277961200 -14400 1 EDT}
+    {2298520800 -18000 0 EST}
+    {2309410800 -14400 1 EDT}
+    {2329970400 -18000 0 EST}
+    {2341465200 -14400 1 EDT}
+    {2362024800 -18000 0 EST}
+    {2372914800 -14400 1 EDT}
+    {2393474400 -18000 0 EST}
+    {2404364400 -14400 1 EDT}
+    {2424924000 -18000 0 EST}
+    {2435814000 -14400 1 EDT}
+    {2456373600 -18000 0 EST}
+    {2467263600 -14400 1 EDT}
+    {2487823200 -18000 0 EST}
+    {2499318000 -14400 1 EDT}
+    {2519877600 -18000 0 EST}
+    {2530767600 -14400 1 EDT}
+    {2551327200 -18000 0 EST}
+    {2562217200 -14400 1 EDT}
+    {2582776800 -18000 0 EST}
+    {2593666800 -14400 1 EDT}
+    {2614226400 -18000 0 EST}
+    {2625116400 -14400 1 EDT}
+    {2645676000 -18000 0 EST}
+    {2656566000 -14400 1 EDT}
+    {2677125600 -18000 0 EST}
+    {2688620400 -14400 1 EDT}
+    {2709180000 -18000 0 EST}
+    {2720070000 -14400 1 EDT}
+    {2740629600 -18000 0 EST}
+    {2751519600 -14400 1 EDT}
+    {2772079200 -18000 0 EST}
+    {2782969200 -14400 1 EDT}
+    {2803528800 -18000 0 EST}
+    {2814418800 -14400 1 EDT}
+    {2834978400 -18000 0 EST}
+    {2846473200 -14400 1 EDT}
+    {2867032800 -18000 0 EST}
+    {2877922800 -14400 1 EDT}
+    {2898482400 -18000 0 EST}
+    {2909372400 -14400 1 EDT}
+    {2929932000 -18000 0 EST}
+    {2940822000 -14400 1 EDT}
+    {2961381600 -18000 0 EST}
+    {2972271600 -14400 1 EDT}
+    {2992831200 -18000 0 EST}
+    {3003721200 -14400 1 EDT}
+    {3024280800 -18000 0 EST}
+    {3035775600 -14400 1 EDT}
+    {3056335200 -18000 0 EST}
+    {3067225200 -14400 1 EDT}
+    {3087784800 -18000 0 EST}
+    {3098674800 -14400 1 EDT}
+    {3119234400 -18000 0 EST}
+    {3130124400 -14400 1 EDT}
+    {3150684000 -18000 0 EST}
+    {3161574000 -14400 1 EDT}
+    {3182133600 -18000 0 EST}
+    {3193023600 -14400 1 EDT}
+    {3213583200 -18000 0 EST}
+    {3225078000 -14400 1 EDT}
+    {3245637600 -18000 0 EST}
+    {3256527600 -14400 1 EDT}
+    {3277087200 -18000 0 EST}
+    {3287977200 -14400 1 EDT}
+    {3308536800 -18000 0 EST}
+    {3319426800 -14400 1 EDT}
+    {3339986400 -18000 0 EST}
+    {3350876400 -14400 1 EDT}
+    {3371436000 -18000 0 EST}
+    {3382930800 -14400 1 EDT}
+    {3403490400 -18000 0 EST}
+    {3414380400 -14400 1 EDT}
+    {3434940000 -18000 0 EST}
+    {3445830000 -14400 1 EDT}
+    {3466389600 -18000 0 EST}
+    {3477279600 -14400 1 EDT}
+    {3497839200 -18000 0 EST}
+    {3508729200 -14400 1 EDT}
+    {3529288800 -18000 0 EST}
+    {3540178800 -14400 1 EDT}
+    {3560738400 -18000 0 EST}
+    {3572233200 -14400 1 EDT}
+    {3592792800 -18000 0 EST}
+    {3603682800 -14400 1 EDT}
+    {3624242400 -18000 0 EST}
+    {3635132400 -14400 1 EDT}
+    {3655692000 -18000 0 EST}
+    {3666582000 -14400 1 EDT}
+    {3687141600 -18000 0 EST}
+    {3698031600 -14400 1 EDT}
+    {3718591200 -18000 0 EST}
+    {3730086000 -14400 1 EDT}
+    {3750645600 -18000 0 EST}
+    {3761535600 -14400 1 EDT}
+    {3782095200 -18000 0 EST}
+    {3792985200 -14400 1 EDT}
+    {3813544800 -18000 0 EST}
+    {3824434800 -14400 1 EDT}
+    {3844994400 -18000 0 EST}
+    {3855884400 -14400 1 EDT}
+    {3876444000 -18000 0 EST}
+    {3887334000 -14400 1 EDT}
+    {3907893600 -18000 0 EST}
+    {3919388400 -14400 1 EDT}
+    {3939948000 -18000 0 EST}
+    {3950838000 -14400 1 EDT}
+    {3971397600 -18000 0 EST}
+    {3982287600 -14400 1 EDT}
+    {4002847200 -18000 0 EST}
+    {4013737200 -14400 1 EDT}
+    {4034296800 -18000 0 EST}
+    {4045186800 -14400 1 EDT}
+    {4065746400 -18000 0 EST}
+    {4076636400 -14400 1 EDT}
+    {4097196000 -18000 0 EST}
+}
diff --git a/library/tzdata/America/Jamaica b/library/tzdata/America/Jamaica
new file mode 100644
index 0000000..f752842
--- /dev/null
+++ b/library/tzdata/America/Jamaica
@@ -0,0 +1,29 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Jamaica) {
+    {-9223372036854775808 -18431 0 LMT}
+    {-2524503169 -18431 0 KMT}
+    {-1827687169 -18000 0 EST}
+    {126248400 -18000 0 EST}
+    {126687600 -14400 1 EDT}
+    {152085600 -18000 0 EST}
+    {162370800 -14400 1 EDT}
+    {183535200 -18000 0 EST}
+    {199263600 -14400 1 EDT}
+    {215589600 -18000 0 EST}
+    {230713200 -14400 1 EDT}
+    {247039200 -18000 0 EST}
+    {262767600 -14400 1 EDT}
+    {278488800 -18000 0 EST}
+    {294217200 -14400 1 EDT}
+    {309938400 -18000 0 EST}
+    {325666800 -14400 1 EDT}
+    {341388000 -18000 0 EST}
+    {357116400 -14400 1 EDT}
+    {372837600 -18000 0 EST}
+    {388566000 -14400 1 EDT}
+    {404892000 -18000 0 EST}
+    {420015600 -14400 1 EDT}
+    {436341600 -18000 0 EST}
+    {441781200 -18000 0 EST}
+}
diff --git a/library/tzdata/America/Jujuy b/library/tzdata/America/Jujuy
new file mode 100644
index 0000000..b4c5da3
--- /dev/null
+++ b/library/tzdata/America/Jujuy
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(America/Argentina/Jujuy)]} {
+    LoadTimeZoneFile America/Argentina/Jujuy
+}
+set TZData(:America/Jujuy) $TZData(:America/Argentina/Jujuy)
diff --git a/library/tzdata/America/Juneau b/library/tzdata/America/Juneau
new file mode 100644
index 0000000..fead810
--- /dev/null
+++ b/library/tzdata/America/Juneau
@@ -0,0 +1,276 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Juneau) {
+    {-9223372036854775808 54139 0 LMT}
+    {-3225366139 -32261 0 LMT}
+    {-2188954939 -28800 0 PST}
+    {-883584000 -28800 0 PST}
+    {-880207200 -25200 1 PWT}
+    {-769395600 -25200 1 PPT}
+    {-765385200 -28800 0 PST}
+    {-757353600 -28800 0 PST}
+    {-31507200 -28800 0 PST}
+    {-21477600 -25200 1 PDT}
+    {-5756400 -28800 0 PST}
+    {9972000 -25200 1 PDT}
+    {25693200 -28800 0 PST}
+    {41421600 -25200 1 PDT}
+    {57747600 -28800 0 PST}
+    {73476000 -25200 1 PDT}
+    {89197200 -28800 0 PST}
+    {104925600 -25200 1 PDT}
+    {120646800 -28800 0 PST}
+    {126698400 -25200 1 PDT}
+    {152096400 -28800 0 PST}
+    {162381600 -25200 1 PDT}
+    {183546000 -28800 0 PST}
+    {199274400 -25200 1 PDT}
+    {215600400 -28800 0 PST}
+    {230724000 -25200 1 PDT}
+    {247050000 -28800 0 PST}
+    {262778400 -25200 1 PDT}
+    {278499600 -28800 0 PST}
+    {294228000 -25200 1 PDT}
+    {309949200 -28800 0 PST}
+    {325677600 -32400 0 YST}
+    {325681200 -28800 1 YDT}
+    {341406000 -28800 0 PST}
+    {357127200 -25200 1 PDT}
+    {372848400 -28800 0 PST}
+    {388576800 -25200 1 PDT}
+    {404902800 -28800 0 PST}
+    {420026400 -25200 1 PDT}
+    {439030800 -32400 0 AKST}
+    {452084400 -28800 1 AKDT}
+    {467805600 -32400 0 AKST}
+    {483534000 -28800 1 AKDT}
+    {499255200 -32400 0 AKST}
+    {514983600 -28800 1 AKDT}
+    {530704800 -32400 0 AKST}
+    {544618800 -28800 1 AKDT}
+    {562154400 -32400 0 AKST}
+    {576068400 -28800 1 AKDT}
+    {594208800 -32400 0 AKST}
+    {607518000 -28800 1 AKDT}
+    {625658400 -32400 0 AKST}
+    {638967600 -28800 1 AKDT}
+    {657108000 -32400 0 AKST}
+    {671022000 -28800 1 AKDT}
+    {688557600 -32400 0 AKST}
+    {702471600 -28800 1 AKDT}
+    {720007200 -32400 0 AKST}
+    {733921200 -28800 1 AKDT}
+    {752061600 -32400 0 AKST}
+    {765370800 -28800 1 AKDT}
+    {783511200 -32400 0 AKST}
+    {796820400 -28800 1 AKDT}
+    {814960800 -32400 0 AKST}
+    {828874800 -28800 1 AKDT}
+    {846410400 -32400 0 AKST}
+    {860324400 -28800 1 AKDT}
+    {877860000 -32400 0 AKST}
+    {891774000 -28800 1 AKDT}
+    {909309600 -32400 0 AKST}
+    {923223600 -28800 1 AKDT}
+    {941364000 -32400 0 AKST}
+    {954673200 -28800 1 AKDT}
+    {972813600 -32400 0 AKST}
+    {986122800 -28800 1 AKDT}
+    {1004263200 -32400 0 AKST}
+    {1018177200 -28800 1 AKDT}
+    {1035712800 -32400 0 AKST}
+    {1049626800 -28800 1 AKDT}
+    {1067162400 -32400 0 AKST}
+    {1081076400 -28800 1 AKDT}
+    {1099216800 -32400 0 AKST}
+    {1112526000 -28800 1 AKDT}
+    {1130666400 -32400 0 AKST}
+    {1143975600 -28800 1 AKDT}
+    {1162116000 -32400 0 AKST}
+    {1173610800 -28800 1 AKDT}
+    {1194170400 -32400 0 AKST}
+    {1205060400 -28800 1 AKDT}
+    {1225620000 -32400 0 AKST}
+    {1236510000 -28800 1 AKDT}
+    {1257069600 -32400 0 AKST}
+    {1268564400 -28800 1 AKDT}
+    {1289124000 -32400 0 AKST}
+    {1300014000 -28800 1 AKDT}
+    {1320573600 -32400 0 AKST}
+    {1331463600 -28800 1 AKDT}
+    {1352023200 -32400 0 AKST}
+    {1362913200 -28800 1 AKDT}
+    {1383472800 -32400 0 AKST}
+    {1394362800 -28800 1 AKDT}
+    {1414922400 -32400 0 AKST}
+    {1425812400 -28800 1 AKDT}
+    {1446372000 -32400 0 AKST}
+    {1457866800 -28800 1 AKDT}
+    {1478426400 -32400 0 AKST}
+    {1489316400 -28800 1 AKDT}
+    {1509876000 -32400 0 AKST}
+    {1520766000 -28800 1 AKDT}
+    {1541325600 -32400 0 AKST}
+    {1552215600 -28800 1 AKDT}
+    {1572775200 -32400 0 AKST}
+    {1583665200 -28800 1 AKDT}
+    {1604224800 -32400 0 AKST}
+    {1615719600 -28800 1 AKDT}
+    {1636279200 -32400 0 AKST}
+    {1647169200 -28800 1 AKDT}
+    {1667728800 -32400 0 AKST}
+    {1678618800 -28800 1 AKDT}
+    {1699178400 -32400 0 AKST}
+    {1710068400 -28800 1 AKDT}
+    {1730628000 -32400 0 AKST}
+    {1741518000 -28800 1 AKDT}
+    {1762077600 -32400 0 AKST}
+    {1772967600 -28800 1 AKDT}
+    {1793527200 -32400 0 AKST}
+    {1805022000 -28800 1 AKDT}
+    {1825581600 -32400 0 AKST}
+    {1836471600 -28800 1 AKDT}
+    {1857031200 -32400 0 AKST}
+    {1867921200 -28800 1 AKDT}
+    {1888480800 -32400 0 AKST}
+    {1899370800 -28800 1 AKDT}
+    {1919930400 -32400 0 AKST}
+    {1930820400 -28800 1 AKDT}
+    {1951380000 -32400 0 AKST}
+    {1962874800 -28800 1 AKDT}
+    {1983434400 -32400 0 AKST}
+    {1994324400 -28800 1 AKDT}
+    {2014884000 -32400 0 AKST}
+    {2025774000 -28800 1 AKDT}
+    {2046333600 -32400 0 AKST}
+    {2057223600 -28800 1 AKDT}
+    {2077783200 -32400 0 AKST}
+    {2088673200 -28800 1 AKDT}
+    {2109232800 -32400 0 AKST}
+    {2120122800 -28800 1 AKDT}
+    {2140682400 -32400 0 AKST}
+    {2152177200 -28800 1 AKDT}
+    {2172736800 -32400 0 AKST}
+    {2183626800 -28800 1 AKDT}
+    {2204186400 -32400 0 AKST}
+    {2215076400 -28800 1 AKDT}
+    {2235636000 -32400 0 AKST}
+    {2246526000 -28800 1 AKDT}
+    {2267085600 -32400 0 AKST}
+    {2277975600 -28800 1 AKDT}
+    {2298535200 -32400 0 AKST}
+    {2309425200 -28800 1 AKDT}
+    {2329984800 -32400 0 AKST}
+    {2341479600 -28800 1 AKDT}
+    {2362039200 -32400 0 AKST}
+    {2372929200 -28800 1 AKDT}
+    {2393488800 -32400 0 AKST}
+    {2404378800 -28800 1 AKDT}
+    {2424938400 -32400 0 AKST}
+    {2435828400 -28800 1 AKDT}
+    {2456388000 -32400 0 AKST}
+    {2467278000 -28800 1 AKDT}
+    {2487837600 -32400 0 AKST}
+    {2499332400 -28800 1 AKDT}
+    {2519892000 -32400 0 AKST}
+    {2530782000 -28800 1 AKDT}
+    {2551341600 -32400 0 AKST}
+    {2562231600 -28800 1 AKDT}
+    {2582791200 -32400 0 AKST}
+    {2593681200 -28800 1 AKDT}
+    {2614240800 -32400 0 AKST}
+    {2625130800 -28800 1 AKDT}
+    {2645690400 -32400 0 AKST}
+    {2656580400 -28800 1 AKDT}
+    {2677140000 -32400 0 AKST}
+    {2688634800 -28800 1 AKDT}
+    {2709194400 -32400 0 AKST}
+    {2720084400 -28800 1 AKDT}
+    {2740644000 -32400 0 AKST}
+    {2751534000 -28800 1 AKDT}
+    {2772093600 -32400 0 AKST}
+    {2782983600 -28800 1 AKDT}
+    {2803543200 -32400 0 AKST}
+    {2814433200 -28800 1 AKDT}
+    {2834992800 -32400 0 AKST}
+    {2846487600 -28800 1 AKDT}
+    {2867047200 -32400 0 AKST}
+    {2877937200 -28800 1 AKDT}
+    {2898496800 -32400 0 AKST}
+    {2909386800 -28800 1 AKDT}
+    {2929946400 -32400 0 AKST}
+    {2940836400 -28800 1 AKDT}
+    {2961396000 -32400 0 AKST}
+    {2972286000 -28800 1 AKDT}
+    {2992845600 -32400 0 AKST}
+    {3003735600 -28800 1 AKDT}
+    {3024295200 -32400 0 AKST}
+    {3035790000 -28800 1 AKDT}
+    {3056349600 -32400 0 AKST}
+    {3067239600 -28800 1 AKDT}
+    {3087799200 -32400 0 AKST}
+    {3098689200 -28800 1 AKDT}
+    {3119248800 -32400 0 AKST}
+    {3130138800 -28800 1 AKDT}
+    {3150698400 -32400 0 AKST}
+    {3161588400 -28800 1 AKDT}
+    {3182148000 -32400 0 AKST}
+    {3193038000 -28800 1 AKDT}
+    {3213597600 -32400 0 AKST}
+    {3225092400 -28800 1 AKDT}
+    {3245652000 -32400 0 AKST}
+    {3256542000 -28800 1 AKDT}
+    {3277101600 -32400 0 AKST}
+    {3287991600 -28800 1 AKDT}
+    {3308551200 -32400 0 AKST}
+    {3319441200 -28800 1 AKDT}
+    {3340000800 -32400 0 AKST}
+    {3350890800 -28800 1 AKDT}
+    {3371450400 -32400 0 AKST}
+    {3382945200 -28800 1 AKDT}
+    {3403504800 -32400 0 AKST}
+    {3414394800 -28800 1 AKDT}
+    {3434954400 -32400 0 AKST}
+    {3445844400 -28800 1 AKDT}
+    {3466404000 -32400 0 AKST}
+    {3477294000 -28800 1 AKDT}
+    {3497853600 -32400 0 AKST}
+    {3508743600 -28800 1 AKDT}
+    {3529303200 -32400 0 AKST}
+    {3540193200 -28800 1 AKDT}
+    {3560752800 -32400 0 AKST}
+    {3572247600 -28800 1 AKDT}
+    {3592807200 -32400 0 AKST}
+    {3603697200 -28800 1 AKDT}
+    {3624256800 -32400 0 AKST}
+    {3635146800 -28800 1 AKDT}
+    {3655706400 -32400 0 AKST}
+    {3666596400 -28800 1 AKDT}
+    {3687156000 -32400 0 AKST}
+    {3698046000 -28800 1 AKDT}
+    {3718605600 -32400 0 AKST}
+    {3730100400 -28800 1 AKDT}
+    {3750660000 -32400 0 AKST}
+    {3761550000 -28800 1 AKDT}
+    {3782109600 -32400 0 AKST}
+    {3792999600 -28800 1 AKDT}
+    {3813559200 -32400 0 AKST}
+    {3824449200 -28800 1 AKDT}
+    {3845008800 -32400 0 AKST}
+    {3855898800 -28800 1 AKDT}
+    {3876458400 -32400 0 AKST}
+    {3887348400 -28800 1 AKDT}
+    {3907908000 -32400 0 AKST}
+    {3919402800 -28800 1 AKDT}
+    {3939962400 -32400 0 AKST}
+    {3950852400 -28800 1 AKDT}
+    {3971412000 -32400 0 AKST}
+    {3982302000 -28800 1 AKDT}
+    {4002861600 -32400 0 AKST}
+    {4013751600 -28800 1 AKDT}
+    {4034311200 -32400 0 AKST}
+    {4045201200 -28800 1 AKDT}
+    {4065760800 -32400 0 AKST}
+    {4076650800 -28800 1 AKDT}
+    {4097210400 -32400 0 AKST}
+}
diff --git a/library/tzdata/America/Kentucky/Louisville b/library/tzdata/America/Kentucky/Louisville
new file mode 100644
index 0000000..c2aa10c
--- /dev/null
+++ b/library/tzdata/America/Kentucky/Louisville
@@ -0,0 +1,314 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Kentucky/Louisville) {
+    {-9223372036854775808 -20582 0 LMT}
+    {-2717647200 -21600 0 CST}
+    {-1633276800 -18000 1 CDT}
+    {-1615136400 -21600 0 CST}
+    {-1601827200 -18000 1 CDT}
+    {-1583686800 -21600 0 CST}
+    {-1546279200 -21600 0 CST}
+    {-1535904000 -18000 1 CDT}
+    {-1525280400 -21600 0 CST}
+    {-905097600 -18000 1 CDT}
+    {-891795600 -21600 0 CST}
+    {-883591200 -21600 0 CST}
+    {-880214400 -18000 1 CWT}
+    {-769395600 -18000 1 CPT}
+    {-765392400 -21600 0 CST}
+    {-757360800 -21600 0 CST}
+    {-747244800 -18000 1 CDT}
+    {-744224400 -21600 0 CST}
+    {-715795200 -18000 1 CDT}
+    {-684349200 -18000 1 CDT}
+    {-652899600 -18000 1 CDT}
+    {-620845200 -18000 1 CDT}
+    {-608144400 -21600 0 CST}
+    {-589392000 -18000 1 CDT}
+    {-576090000 -21600 0 CST}
+    {-557942400 -18000 1 CDT}
+    {-544640400 -21600 0 CST}
+    {-526492800 -18000 1 CDT}
+    {-513190800 -21600 0 CST}
+    {-495043200 -18000 1 CDT}
+    {-481741200 -21600 0 CST}
+    {-463593600 -18000 1 CDT}
+    {-450291600 -21600 0 CST}
+    {-431539200 -18000 1 CDT}
+    {-415818000 -21600 0 CST}
+    {-400089600 -18000 1 CDT}
+    {-384368400 -21600 0 CST}
+    {-368640000 -18000 1 CDT}
+    {-352918800 -21600 0 CST}
+    {-337190400 -18000 1 CDT}
+    {-321469200 -21600 0 CST}
+    {-305740800 -18000 1 CDT}
+    {-289414800 -21600 0 CST}
+    {-273686400 -18000 1 CDT}
+    {-266432400 -18000 0 EST}
+    {-63140400 -18000 0 EST}
+    {-52938000 -14400 1 EDT}
+    {-37216800 -18000 0 EST}
+    {-21488400 -14400 1 EDT}
+    {-5767200 -18000 0 EST}
+    {9961200 -14400 1 EDT}
+    {25682400 -18000 0 EST}
+    {41410800 -14400 1 EDT}
+    {57736800 -18000 0 EST}
+    {73465200 -14400 1 EDT}
+    {89186400 -18000 0 EST}
+    {104914800 -14400 1 EDT}
+    {120636000 -18000 0 EST}
+    {126687600 -18000 1 CDT}
+    {152089200 -18000 0 EST}
+    {162370800 -14400 1 EDT}
+    {183535200 -18000 0 EST}
+    {199263600 -14400 1 EDT}
+    {215589600 -18000 0 EST}
+    {230713200 -14400 1 EDT}
+    {247039200 -18000 0 EST}
+    {262767600 -14400 1 EDT}
+    {278488800 -18000 0 EST}
+    {294217200 -14400 1 EDT}
+    {309938400 -18000 0 EST}
+    {325666800 -14400 1 EDT}
+    {341388000 -18000 0 EST}
+    {357116400 -14400 1 EDT}
+    {372837600 -18000 0 EST}
+    {388566000 -14400 1 EDT}
+    {404892000 -18000 0 EST}
+    {420015600 -14400 1 EDT}
+    {436341600 -18000 0 EST}
+    {452070000 -14400 1 EDT}
+    {467791200 -18000 0 EST}
+    {483519600 -14400 1 EDT}
+    {499240800 -18000 0 EST}
+    {514969200 -14400 1 EDT}
+    {530690400 -18000 0 EST}
+    {544604400 -14400 1 EDT}
+    {562140000 -18000 0 EST}
+    {576054000 -14400 1 EDT}
+    {594194400 -18000 0 EST}
+    {607503600 -14400 1 EDT}
+    {625644000 -18000 0 EST}
+    {638953200 -14400 1 EDT}
+    {657093600 -18000 0 EST}
+    {671007600 -14400 1 EDT}
+    {688543200 -18000 0 EST}
+    {702457200 -14400 1 EDT}
+    {719992800 -18000 0 EST}
+    {733906800 -14400 1 EDT}
+    {752047200 -18000 0 EST}
+    {765356400 -14400 1 EDT}
+    {783496800 -18000 0 EST}
+    {796806000 -14400 1 EDT}
+    {814946400 -18000 0 EST}
+    {828860400 -14400 1 EDT}
+    {846396000 -18000 0 EST}
+    {860310000 -14400 1 EDT}
+    {877845600 -18000 0 EST}
+    {891759600 -14400 1 EDT}
+    {909295200 -18000 0 EST}
+    {923209200 -14400 1 EDT}
+    {941349600 -18000 0 EST}
+    {954658800 -14400 1 EDT}
+    {972799200 -18000 0 EST}
+    {986108400 -14400 1 EDT}
+    {1004248800 -18000 0 EST}
+    {1018162800 -14400 1 EDT}
+    {1035698400 -18000 0 EST}
+    {1049612400 -14400 1 EDT}
+    {1067148000 -18000 0 EST}
+    {1081062000 -14400 1 EDT}
+    {1099202400 -18000 0 EST}
+    {1112511600 -14400 1 EDT}
+    {1130652000 -18000 0 EST}
+    {1143961200 -14400 1 EDT}
+    {1162101600 -18000 0 EST}
+    {1173596400 -14400 1 EDT}
+    {1194156000 -18000 0 EST}
+    {1205046000 -14400 1 EDT}
+    {1225605600 -18000 0 EST}
+    {1236495600 -14400 1 EDT}
+    {1257055200 -18000 0 EST}
+    {1268550000 -14400 1 EDT}
+    {1289109600 -18000 0 EST}
+    {1299999600 -14400 1 EDT}
+    {1320559200 -18000 0 EST}
+    {1331449200 -14400 1 EDT}
+    {1352008800 -18000 0 EST}
+    {1362898800 -14400 1 EDT}
+    {1383458400 -18000 0 EST}
+    {1394348400 -14400 1 EDT}
+    {1414908000 -18000 0 EST}
+    {1425798000 -14400 1 EDT}
+    {1446357600 -18000 0 EST}
+    {1457852400 -14400 1 EDT}
+    {1478412000 -18000 0 EST}
+    {1489302000 -14400 1 EDT}
+    {1509861600 -18000 0 EST}
+    {1520751600 -14400 1 EDT}
+    {1541311200 -18000 0 EST}
+    {1552201200 -14400 1 EDT}
+    {1572760800 -18000 0 EST}
+    {1583650800 -14400 1 EDT}
+    {1604210400 -18000 0 EST}
+    {1615705200 -14400 1 EDT}
+    {1636264800 -18000 0 EST}
+    {1647154800 -14400 1 EDT}
+    {1667714400 -18000 0 EST}
+    {1678604400 -14400 1 EDT}
+    {1699164000 -18000 0 EST}
+    {1710054000 -14400 1 EDT}
+    {1730613600 -18000 0 EST}
+    {1741503600 -14400 1 EDT}
+    {1762063200 -18000 0 EST}
+    {1772953200 -14400 1 EDT}
+    {1793512800 -18000 0 EST}
+    {1805007600 -14400 1 EDT}
+    {1825567200 -18000 0 EST}
+    {1836457200 -14400 1 EDT}
+    {1857016800 -18000 0 EST}
+    {1867906800 -14400 1 EDT}
+    {1888466400 -18000 0 EST}
+    {1899356400 -14400 1 EDT}
+    {1919916000 -18000 0 EST}
+    {1930806000 -14400 1 EDT}
+    {1951365600 -18000 0 EST}
+    {1962860400 -14400 1 EDT}
+    {1983420000 -18000 0 EST}
+    {1994310000 -14400 1 EDT}
+    {2014869600 -18000 0 EST}
+    {2025759600 -14400 1 EDT}
+    {2046319200 -18000 0 EST}
+    {2057209200 -14400 1 EDT}
+    {2077768800 -18000 0 EST}
+    {2088658800 -14400 1 EDT}
+    {2109218400 -18000 0 EST}
+    {2120108400 -14400 1 EDT}
+    {2140668000 -18000 0 EST}
+    {2152162800 -14400 1 EDT}
+    {2172722400 -18000 0 EST}
+    {2183612400 -14400 1 EDT}
+    {2204172000 -18000 0 EST}
+    {2215062000 -14400 1 EDT}
+    {2235621600 -18000 0 EST}
+    {2246511600 -14400 1 EDT}
+    {2267071200 -18000 0 EST}
+    {2277961200 -14400 1 EDT}
+    {2298520800 -18000 0 EST}
+    {2309410800 -14400 1 EDT}
+    {2329970400 -18000 0 EST}
+    {2341465200 -14400 1 EDT}
+    {2362024800 -18000 0 EST}
+    {2372914800 -14400 1 EDT}
+    {2393474400 -18000 0 EST}
+    {2404364400 -14400 1 EDT}
+    {2424924000 -18000 0 EST}
+    {2435814000 -14400 1 EDT}
+    {2456373600 -18000 0 EST}
+    {2467263600 -14400 1 EDT}
+    {2487823200 -18000 0 EST}
+    {2499318000 -14400 1 EDT}
+    {2519877600 -18000 0 EST}
+    {2530767600 -14400 1 EDT}
+    {2551327200 -18000 0 EST}
+    {2562217200 -14400 1 EDT}
+    {2582776800 -18000 0 EST}
+    {2593666800 -14400 1 EDT}
+    {2614226400 -18000 0 EST}
+    {2625116400 -14400 1 EDT}
+    {2645676000 -18000 0 EST}
+    {2656566000 -14400 1 EDT}
+    {2677125600 -18000 0 EST}
+    {2688620400 -14400 1 EDT}
+    {2709180000 -18000 0 EST}
+    {2720070000 -14400 1 EDT}
+    {2740629600 -18000 0 EST}
+    {2751519600 -14400 1 EDT}
+    {2772079200 -18000 0 EST}
+    {2782969200 -14400 1 EDT}
+    {2803528800 -18000 0 EST}
+    {2814418800 -14400 1 EDT}
+    {2834978400 -18000 0 EST}
+    {2846473200 -14400 1 EDT}
+    {2867032800 -18000 0 EST}
+    {2877922800 -14400 1 EDT}
+    {2898482400 -18000 0 EST}
+    {2909372400 -14400 1 EDT}
+    {2929932000 -18000 0 EST}
+    {2940822000 -14400 1 EDT}
+    {2961381600 -18000 0 EST}
+    {2972271600 -14400 1 EDT}
+    {2992831200 -18000 0 EST}
+    {3003721200 -14400 1 EDT}
+    {3024280800 -18000 0 EST}
+    {3035775600 -14400 1 EDT}
+    {3056335200 -18000 0 EST}
+    {3067225200 -14400 1 EDT}
+    {3087784800 -18000 0 EST}
+    {3098674800 -14400 1 EDT}
+    {3119234400 -18000 0 EST}
+    {3130124400 -14400 1 EDT}
+    {3150684000 -18000 0 EST}
+    {3161574000 -14400 1 EDT}
+    {3182133600 -18000 0 EST}
+    {3193023600 -14400 1 EDT}
+    {3213583200 -18000 0 EST}
+    {3225078000 -14400 1 EDT}
+    {3245637600 -18000 0 EST}
+    {3256527600 -14400 1 EDT}
+    {3277087200 -18000 0 EST}
+    {3287977200 -14400 1 EDT}
+    {3308536800 -18000 0 EST}
+    {3319426800 -14400 1 EDT}
+    {3339986400 -18000 0 EST}
+    {3350876400 -14400 1 EDT}
+    {3371436000 -18000 0 EST}
+    {3382930800 -14400 1 EDT}
+    {3403490400 -18000 0 EST}
+    {3414380400 -14400 1 EDT}
+    {3434940000 -18000 0 EST}
+    {3445830000 -14400 1 EDT}
+    {3466389600 -18000 0 EST}
+    {3477279600 -14400 1 EDT}
+    {3497839200 -18000 0 EST}
+    {3508729200 -14400 1 EDT}
+    {3529288800 -18000 0 EST}
+    {3540178800 -14400 1 EDT}
+    {3560738400 -18000 0 EST}
+    {3572233200 -14400 1 EDT}
+    {3592792800 -18000 0 EST}
+    {3603682800 -14400 1 EDT}
+    {3624242400 -18000 0 EST}
+    {3635132400 -14400 1 EDT}
+    {3655692000 -18000 0 EST}
+    {3666582000 -14400 1 EDT}
+    {3687141600 -18000 0 EST}
+    {3698031600 -14400 1 EDT}
+    {3718591200 -18000 0 EST}
+    {3730086000 -14400 1 EDT}
+    {3750645600 -18000 0 EST}
+    {3761535600 -14400 1 EDT}
+    {3782095200 -18000 0 EST}
+    {3792985200 -14400 1 EDT}
+    {3813544800 -18000 0 EST}
+    {3824434800 -14400 1 EDT}
+    {3844994400 -18000 0 EST}
+    {3855884400 -14400 1 EDT}
+    {3876444000 -18000 0 EST}
+    {3887334000 -14400 1 EDT}
+    {3907893600 -18000 0 EST}
+    {3919388400 -14400 1 EDT}
+    {3939948000 -18000 0 EST}
+    {3950838000 -14400 1 EDT}
+    {3971397600 -18000 0 EST}
+    {3982287600 -14400 1 EDT}
+    {4002847200 -18000 0 EST}
+    {4013737200 -14400 1 EDT}
+    {4034296800 -18000 0 EST}
+    {4045186800 -14400 1 EDT}
+    {4065746400 -18000 0 EST}
+    {4076636400 -14400 1 EDT}
+    {4097196000 -18000 0 EST}
+}
diff --git a/library/tzdata/America/Kentucky/Monticello b/library/tzdata/America/Kentucky/Monticello
new file mode 100644
index 0000000..e523ecb
--- /dev/null
+++ b/library/tzdata/America/Kentucky/Monticello
@@ -0,0 +1,279 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Kentucky/Monticello) {
+    {-9223372036854775808 -20364 0 LMT}
+    {-2717647200 -21600 0 CST}
+    {-1633276800 -18000 1 CDT}
+    {-1615136400 -21600 0 CST}
+    {-1601827200 -18000 1 CDT}
+    {-1583686800 -21600 0 CST}
+    {-880214400 -18000 1 CWT}
+    {-769395600 -18000 1 CPT}
+    {-765392400 -21600 0 CST}
+    {-757360800 -21600 0 CST}
+    {-63136800 -21600 0 CST}
+    {-52934400 -18000 1 CDT}
+    {-37213200 -21600 0 CST}
+    {-21484800 -18000 1 CDT}
+    {-5763600 -21600 0 CST}
+    {9964800 -18000 1 CDT}
+    {25686000 -21600 0 CST}
+    {41414400 -18000 1 CDT}
+    {57740400 -21600 0 CST}
+    {73468800 -18000 1 CDT}
+    {89190000 -21600 0 CST}
+    {104918400 -18000 1 CDT}
+    {120639600 -21600 0 CST}
+    {126691200 -18000 1 CDT}
+    {152089200 -21600 0 CST}
+    {162374400 -18000 1 CDT}
+    {183538800 -21600 0 CST}
+    {199267200 -18000 1 CDT}
+    {215593200 -21600 0 CST}
+    {230716800 -18000 1 CDT}
+    {247042800 -21600 0 CST}
+    {262771200 -18000 1 CDT}
+    {278492400 -21600 0 CST}
+    {294220800 -18000 1 CDT}
+    {309942000 -21600 0 CST}
+    {325670400 -18000 1 CDT}
+    {341391600 -21600 0 CST}
+    {357120000 -18000 1 CDT}
+    {372841200 -21600 0 CST}
+    {388569600 -18000 1 CDT}
+    {404895600 -21600 0 CST}
+    {420019200 -18000 1 CDT}
+    {436345200 -21600 0 CST}
+    {452073600 -18000 1 CDT}
+    {467794800 -21600 0 CST}
+    {483523200 -18000 1 CDT}
+    {499244400 -21600 0 CST}
+    {514972800 -18000 1 CDT}
+    {530694000 -21600 0 CST}
+    {544608000 -18000 1 CDT}
+    {562143600 -21600 0 CST}
+    {576057600 -18000 1 CDT}
+    {594198000 -21600 0 CST}
+    {607507200 -18000 1 CDT}
+    {625647600 -21600 0 CST}
+    {638956800 -18000 1 CDT}
+    {657097200 -21600 0 CST}
+    {671011200 -18000 1 CDT}
+    {688546800 -21600 0 CST}
+    {702460800 -18000 1 CDT}
+    {719996400 -21600 0 CST}
+    {733910400 -18000 1 CDT}
+    {752050800 -21600 0 CST}
+    {765360000 -18000 1 CDT}
+    {783500400 -21600 0 CST}
+    {796809600 -18000 1 CDT}
+    {814950000 -21600 0 CST}
+    {828864000 -18000 1 CDT}
+    {846399600 -21600 0 CST}
+    {860313600 -18000 1 CDT}
+    {877849200 -21600 0 CST}
+    {891763200 -18000 1 CDT}
+    {909298800 -21600 0 CST}
+    {923212800 -18000 1 CDT}
+    {941353200 -21600 0 CST}
+    {954662400 -18000 1 CDT}
+    {972806400 -18000 0 EST}
+    {986108400 -14400 1 EDT}
+    {1004248800 -18000 0 EST}
+    {1018162800 -14400 1 EDT}
+    {1035698400 -18000 0 EST}
+    {1049612400 -14400 1 EDT}
+    {1067148000 -18000 0 EST}
+    {1081062000 -14400 1 EDT}
+    {1099202400 -18000 0 EST}
+    {1112511600 -14400 1 EDT}
+    {1130652000 -18000 0 EST}
+    {1143961200 -14400 1 EDT}
+    {1162101600 -18000 0 EST}
+    {1173596400 -14400 1 EDT}
+    {1194156000 -18000 0 EST}
+    {1205046000 -14400 1 EDT}
+    {1225605600 -18000 0 EST}
+    {1236495600 -14400 1 EDT}
+    {1257055200 -18000 0 EST}
+    {1268550000 -14400 1 EDT}
+    {1289109600 -18000 0 EST}
+    {1299999600 -14400 1 EDT}
+    {1320559200 -18000 0 EST}
+    {1331449200 -14400 1 EDT}
+    {1352008800 -18000 0 EST}
+    {1362898800 -14400 1 EDT}
+    {1383458400 -18000 0 EST}
+    {1394348400 -14400 1 EDT}
+    {1414908000 -18000 0 EST}
+    {1425798000 -14400 1 EDT}
+    {1446357600 -18000 0 EST}
+    {1457852400 -14400 1 EDT}
+    {1478412000 -18000 0 EST}
+    {1489302000 -14400 1 EDT}
+    {1509861600 -18000 0 EST}
+    {1520751600 -14400 1 EDT}
+    {1541311200 -18000 0 EST}
+    {1552201200 -14400 1 EDT}
+    {1572760800 -18000 0 EST}
+    {1583650800 -14400 1 EDT}
+    {1604210400 -18000 0 EST}
+    {1615705200 -14400 1 EDT}
+    {1636264800 -18000 0 EST}
+    {1647154800 -14400 1 EDT}
+    {1667714400 -18000 0 EST}
+    {1678604400 -14400 1 EDT}
+    {1699164000 -18000 0 EST}
+    {1710054000 -14400 1 EDT}
+    {1730613600 -18000 0 EST}
+    {1741503600 -14400 1 EDT}
+    {1762063200 -18000 0 EST}
+    {1772953200 -14400 1 EDT}
+    {1793512800 -18000 0 EST}
+    {1805007600 -14400 1 EDT}
+    {1825567200 -18000 0 EST}
+    {1836457200 -14400 1 EDT}
+    {1857016800 -18000 0 EST}
+    {1867906800 -14400 1 EDT}
+    {1888466400 -18000 0 EST}
+    {1899356400 -14400 1 EDT}
+    {1919916000 -18000 0 EST}
+    {1930806000 -14400 1 EDT}
+    {1951365600 -18000 0 EST}
+    {1962860400 -14400 1 EDT}
+    {1983420000 -18000 0 EST}
+    {1994310000 -14400 1 EDT}
+    {2014869600 -18000 0 EST}
+    {2025759600 -14400 1 EDT}
+    {2046319200 -18000 0 EST}
+    {2057209200 -14400 1 EDT}
+    {2077768800 -18000 0 EST}
+    {2088658800 -14400 1 EDT}
+    {2109218400 -18000 0 EST}
+    {2120108400 -14400 1 EDT}
+    {2140668000 -18000 0 EST}
+    {2152162800 -14400 1 EDT}
+    {2172722400 -18000 0 EST}
+    {2183612400 -14400 1 EDT}
+    {2204172000 -18000 0 EST}
+    {2215062000 -14400 1 EDT}
+    {2235621600 -18000 0 EST}
+    {2246511600 -14400 1 EDT}
+    {2267071200 -18000 0 EST}
+    {2277961200 -14400 1 EDT}
+    {2298520800 -18000 0 EST}
+    {2309410800 -14400 1 EDT}
+    {2329970400 -18000 0 EST}
+    {2341465200 -14400 1 EDT}
+    {2362024800 -18000 0 EST}
+    {2372914800 -14400 1 EDT}
+    {2393474400 -18000 0 EST}
+    {2404364400 -14400 1 EDT}
+    {2424924000 -18000 0 EST}
+    {2435814000 -14400 1 EDT}
+    {2456373600 -18000 0 EST}
+    {2467263600 -14400 1 EDT}
+    {2487823200 -18000 0 EST}
+    {2499318000 -14400 1 EDT}
+    {2519877600 -18000 0 EST}
+    {2530767600 -14400 1 EDT}
+    {2551327200 -18000 0 EST}
+    {2562217200 -14400 1 EDT}
+    {2582776800 -18000 0 EST}
+    {2593666800 -14400 1 EDT}
+    {2614226400 -18000 0 EST}
+    {2625116400 -14400 1 EDT}
+    {2645676000 -18000 0 EST}
+    {2656566000 -14400 1 EDT}
+    {2677125600 -18000 0 EST}
+    {2688620400 -14400 1 EDT}
+    {2709180000 -18000 0 EST}
+    {2720070000 -14400 1 EDT}
+    {2740629600 -18000 0 EST}
+    {2751519600 -14400 1 EDT}
+    {2772079200 -18000 0 EST}
+    {2782969200 -14400 1 EDT}
+    {2803528800 -18000 0 EST}
+    {2814418800 -14400 1 EDT}
+    {2834978400 -18000 0 EST}
+    {2846473200 -14400 1 EDT}
+    {2867032800 -18000 0 EST}
+    {2877922800 -14400 1 EDT}
+    {2898482400 -18000 0 EST}
+    {2909372400 -14400 1 EDT}
+    {2929932000 -18000 0 EST}
+    {2940822000 -14400 1 EDT}
+    {2961381600 -18000 0 EST}
+    {2972271600 -14400 1 EDT}
+    {2992831200 -18000 0 EST}
+    {3003721200 -14400 1 EDT}
+    {3024280800 -18000 0 EST}
+    {3035775600 -14400 1 EDT}
+    {3056335200 -18000 0 EST}
+    {3067225200 -14400 1 EDT}
+    {3087784800 -18000 0 EST}
+    {3098674800 -14400 1 EDT}
+    {3119234400 -18000 0 EST}
+    {3130124400 -14400 1 EDT}
+    {3150684000 -18000 0 EST}
+    {3161574000 -14400 1 EDT}
+    {3182133600 -18000 0 EST}
+    {3193023600 -14400 1 EDT}
+    {3213583200 -18000 0 EST}
+    {3225078000 -14400 1 EDT}
+    {3245637600 -18000 0 EST}
+    {3256527600 -14400 1 EDT}
+    {3277087200 -18000 0 EST}
+    {3287977200 -14400 1 EDT}
+    {3308536800 -18000 0 EST}
+    {3319426800 -14400 1 EDT}
+    {3339986400 -18000 0 EST}
+    {3350876400 -14400 1 EDT}
+    {3371436000 -18000 0 EST}
+    {3382930800 -14400 1 EDT}
+    {3403490400 -18000 0 EST}
+    {3414380400 -14400 1 EDT}
+    {3434940000 -18000 0 EST}
+    {3445830000 -14400 1 EDT}
+    {3466389600 -18000 0 EST}
+    {3477279600 -14400 1 EDT}
+    {3497839200 -18000 0 EST}
+    {3508729200 -14400 1 EDT}
+    {3529288800 -18000 0 EST}
+    {3540178800 -14400 1 EDT}
+    {3560738400 -18000 0 EST}
+    {3572233200 -14400 1 EDT}
+    {3592792800 -18000 0 EST}
+    {3603682800 -14400 1 EDT}
+    {3624242400 -18000 0 EST}
+    {3635132400 -14400 1 EDT}
+    {3655692000 -18000 0 EST}
+    {3666582000 -14400 1 EDT}
+    {3687141600 -18000 0 EST}
+    {3698031600 -14400 1 EDT}
+    {3718591200 -18000 0 EST}
+    {3730086000 -14400 1 EDT}
+    {3750645600 -18000 0 EST}
+    {3761535600 -14400 1 EDT}
+    {3782095200 -18000 0 EST}
+    {3792985200 -14400 1 EDT}
+    {3813544800 -18000 0 EST}
+    {3824434800 -14400 1 EDT}
+    {3844994400 -18000 0 EST}
+    {3855884400 -14400 1 EDT}
+    {3876444000 -18000 0 EST}
+    {3887334000 -14400 1 EDT}
+    {3907893600 -18000 0 EST}
+    {3919388400 -14400 1 EDT}
+    {3939948000 -18000 0 EST}
+    {3950838000 -14400 1 EDT}
+    {3971397600 -18000 0 EST}
+    {3982287600 -14400 1 EDT}
+    {4002847200 -18000 0 EST}
+    {4013737200 -14400 1 EDT}
+    {4034296800 -18000 0 EST}
+    {4045186800 -14400 1 EDT}
+    {4065746400 -18000 0 EST}
+    {4076636400 -14400 1 EDT}
+    {4097196000 -18000 0 EST}
+}
diff --git a/library/tzdata/America/Knox_IN b/library/tzdata/America/Knox_IN
new file mode 100644
index 0000000..00d21c0
--- /dev/null
+++ b/library/tzdata/America/Knox_IN
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(America/Indiana/Knox)]} {
+    LoadTimeZoneFile America/Indiana/Knox
+}
+set TZData(:America/Knox_IN) $TZData(:America/Indiana/Knox)
diff --git a/library/tzdata/America/Kralendijk b/library/tzdata/America/Kralendijk
new file mode 100644
index 0000000..8b6db86
--- /dev/null
+++ b/library/tzdata/America/Kralendijk
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(America/Curacao)]} {
+    LoadTimeZoneFile America/Curacao
+}
+set TZData(:America/Kralendijk) $TZData(:America/Curacao)
diff --git a/library/tzdata/America/La_Paz b/library/tzdata/America/La_Paz
new file mode 100644
index 0000000..38ffbb0
--- /dev/null
+++ b/library/tzdata/America/La_Paz
@@ -0,0 +1,8 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/La_Paz) {
+    {-9223372036854775808 -16356 0 LMT}
+    {-2524505244 -16356 0 CMT}
+    {-1205954844 -12756 1 BOST}
+    {-1192307244 -14400 0 BOT}
+}
diff --git a/library/tzdata/America/Lima b/library/tzdata/America/Lima
new file mode 100644
index 0000000..c6e6ac1
--- /dev/null
+++ b/library/tzdata/America/Lima
@@ -0,0 +1,16 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Lima) {
+    {-9223372036854775808 -18492 0 LMT}
+    {-2524503108 -18516 0 LMT}
+    {-1938538284 -14400 0 PEST}
+    {-1002052800 -18000 0 PET}
+    {-986756400 -14400 1 PEST}
+    {-971035200 -18000 0 PET}
+    {-955306800 -14400 1 PEST}
+    {-939585600 -18000 0 PET}
+    {512712000 -18000 0 PET}
+    {544248000 -18000 0 PET}
+    {638942400 -18000 0 PET}
+    {765172800 -18000 0 PET}
+}
diff --git a/library/tzdata/America/Los_Angeles b/library/tzdata/America/Los_Angeles
new file mode 100644
index 0000000..da6ca99
--- /dev/null
+++ b/library/tzdata/America/Los_Angeles
@@ -0,0 +1,317 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Los_Angeles) {
+    {-9223372036854775808 -28378 0 LMT}
+    {-2717640000 -28800 0 PST}
+    {-1633269600 -25200 1 PDT}
+    {-1615129200 -28800 0 PST}
+    {-1601820000 -25200 1 PDT}
+    {-1583679600 -28800 0 PST}
+    {-880207200 -25200 1 PWT}
+    {-769395600 -25200 1 PPT}
+    {-765385200 -28800 0 PST}
+    {-757353600 -28800 0 PST}
+    {-687967200 -25200 1 PDT}
+    {-662655600 -28800 0 PST}
+    {-620834400 -25200 1 PDT}
+    {-608137200 -28800 0 PST}
+    {-589384800 -25200 1 PDT}
+    {-576082800 -28800 0 PST}
+    {-557935200 -25200 1 PDT}
+    {-544633200 -28800 0 PST}
+    {-526485600 -25200 1 PDT}
+    {-513183600 -28800 0 PST}
+    {-495036000 -25200 1 PDT}
+    {-481734000 -28800 0 PST}
+    {-463586400 -25200 1 PDT}
+    {-450284400 -28800 0 PST}
+    {-431532000 -25200 1 PDT}
+    {-418230000 -28800 0 PST}
+    {-400082400 -25200 1 PDT}
+    {-386780400 -28800 0 PST}
+    {-368632800 -25200 1 PDT}
+    {-355330800 -28800 0 PST}
+    {-337183200 -25200 1 PDT}
+    {-323881200 -28800 0 PST}
+    {-305733600 -25200 1 PDT}
+    {-292431600 -28800 0 PST}
+    {-273679200 -25200 1 PDT}
+    {-260982000 -28800 0 PST}
+    {-242229600 -25200 1 PDT}
+    {-226508400 -28800 0 PST}
+    {-210780000 -25200 1 PDT}
+    {-195058800 -28800 0 PST}
+    {-179330400 -25200 1 PDT}
+    {-163609200 -28800 0 PST}
+    {-147880800 -25200 1 PDT}
+    {-131554800 -28800 0 PST}
+    {-116431200 -25200 1 PDT}
+    {-100105200 -28800 0 PST}
+    {-94665600 -28800 0 PST}
+    {-84376800 -25200 1 PDT}
+    {-68655600 -28800 0 PST}
+    {-52927200 -25200 1 PDT}
+    {-37206000 -28800 0 PST}
+    {-21477600 -25200 1 PDT}
+    {-5756400 -28800 0 PST}
+    {9972000 -25200 1 PDT}
+    {25693200 -28800 0 PST}
+    {41421600 -25200 1 PDT}
+    {57747600 -28800 0 PST}
+    {73476000 -25200 1 PDT}
+    {89197200 -28800 0 PST}
+    {104925600 -25200 1 PDT}
+    {120646800 -28800 0 PST}
+    {126698400 -25200 1 PDT}
+    {152096400 -28800 0 PST}
+    {162381600 -25200 1 PDT}
+    {183546000 -28800 0 PST}
+    {199274400 -25200 1 PDT}
+    {215600400 -28800 0 PST}
+    {230724000 -25200 1 PDT}
+    {247050000 -28800 0 PST}
+    {262778400 -25200 1 PDT}
+    {278499600 -28800 0 PST}
+    {294228000 -25200 1 PDT}
+    {309949200 -28800 0 PST}
+    {325677600 -25200 1 PDT}
+    {341398800 -28800 0 PST}
+    {357127200 -25200 1 PDT}
+    {372848400 -28800 0 PST}
+    {388576800 -25200 1 PDT}
+    {404902800 -28800 0 PST}
+    {420026400 -25200 1 PDT}
+    {436352400 -28800 0 PST}
+    {452080800 -25200 1 PDT}
+    {467802000 -28800 0 PST}
+    {483530400 -25200 1 PDT}
+    {499251600 -28800 0 PST}
+    {514980000 -25200 1 PDT}
+    {530701200 -28800 0 PST}
+    {544615200 -25200 1 PDT}
+    {562150800 -28800 0 PST}
+    {576064800 -25200 1 PDT}
+    {594205200 -28800 0 PST}
+    {607514400 -25200 1 PDT}
+    {625654800 -28800 0 PST}
+    {638964000 -25200 1 PDT}
+    {657104400 -28800 0 PST}
+    {671018400 -25200 1 PDT}
+    {688554000 -28800 0 PST}
+    {702468000 -25200 1 PDT}
+    {720003600 -28800 0 PST}
+    {733917600 -25200 1 PDT}
+    {752058000 -28800 0 PST}
+    {765367200 -25200 1 PDT}
+    {783507600 -28800 0 PST}
+    {796816800 -25200 1 PDT}
+    {814957200 -28800 0 PST}
+    {828871200 -25200 1 PDT}
+    {846406800 -28800 0 PST}
+    {860320800 -25200 1 PDT}
+    {877856400 -28800 0 PST}
+    {891770400 -25200 1 PDT}
+    {909306000 -28800 0 PST}
+    {923220000 -25200 1 PDT}
+    {941360400 -28800 0 PST}
+    {954669600 -25200 1 PDT}
+    {972810000 -28800 0 PST}
+    {986119200 -25200 1 PDT}
+    {1004259600 -28800 0 PST}
+    {1018173600 -25200 1 PDT}
+    {1035709200 -28800 0 PST}
+    {1049623200 -25200 1 PDT}
+    {1067158800 -28800 0 PST}
+    {1081072800 -25200 1 PDT}
+    {1099213200 -28800 0 PST}
+    {1112522400 -25200 1 PDT}
+    {1130662800 -28800 0 PST}
+    {1143972000 -25200 1 PDT}
+    {1162112400 -28800 0 PST}
+    {1173607200 -25200 1 PDT}
+    {1194166800 -28800 0 PST}
+    {1205056800 -25200 1 PDT}
+    {1225616400 -28800 0 PST}
+    {1236506400 -25200 1 PDT}
+    {1257066000 -28800 0 PST}
+    {1268560800 -25200 1 PDT}
+    {1289120400 -28800 0 PST}
+    {1300010400 -25200 1 PDT}
+    {1320570000 -28800 0 PST}
+    {1331460000 -25200 1 PDT}
+    {1352019600 -28800 0 PST}
+    {1362909600 -25200 1 PDT}
+    {1383469200 -28800 0 PST}
+    {1394359200 -25200 1 PDT}
+    {1414918800 -28800 0 PST}
+    {1425808800 -25200 1 PDT}
+    {1446368400 -28800 0 PST}
+    {1457863200 -25200 1 PDT}
+    {1478422800 -28800 0 PST}
+    {1489312800 -25200 1 PDT}
+    {1509872400 -28800 0 PST}
+    {1520762400 -25200 1 PDT}
+    {1541322000 -28800 0 PST}
+    {1552212000 -25200 1 PDT}
+    {1572771600 -28800 0 PST}
+    {1583661600 -25200 1 PDT}
+    {1604221200 -28800 0 PST}
+    {1615716000 -25200 1 PDT}
+    {1636275600 -28800 0 PST}
+    {1647165600 -25200 1 PDT}
+    {1667725200 -28800 0 PST}
+    {1678615200 -25200 1 PDT}
+    {1699174800 -28800 0 PST}
+    {1710064800 -25200 1 PDT}
+    {1730624400 -28800 0 PST}
+    {1741514400 -25200 1 PDT}
+    {1762074000 -28800 0 PST}
+    {1772964000 -25200 1 PDT}
+    {1793523600 -28800 0 PST}
+    {1805018400 -25200 1 PDT}
+    {1825578000 -28800 0 PST}
+    {1836468000 -25200 1 PDT}
+    {1857027600 -28800 0 PST}
+    {1867917600 -25200 1 PDT}
+    {1888477200 -28800 0 PST}
+    {1899367200 -25200 1 PDT}
+    {1919926800 -28800 0 PST}
+    {1930816800 -25200 1 PDT}
+    {1951376400 -28800 0 PST}
+    {1962871200 -25200 1 PDT}
+    {1983430800 -28800 0 PST}
+    {1994320800 -25200 1 PDT}
+    {2014880400 -28800 0 PST}
+    {2025770400 -25200 1 PDT}
+    {2046330000 -28800 0 PST}
+    {2057220000 -25200 1 PDT}
+    {2077779600 -28800 0 PST}
+    {2088669600 -25200 1 PDT}
+    {2109229200 -28800 0 PST}
+    {2120119200 -25200 1 PDT}
+    {2140678800 -28800 0 PST}
+    {2152173600 -25200 1 PDT}
+    {2172733200 -28800 0 PST}
+    {2183623200 -25200 1 PDT}
+    {2204182800 -28800 0 PST}
+    {2215072800 -25200 1 PDT}
+    {2235632400 -28800 0 PST}
+    {2246522400 -25200 1 PDT}
+    {2267082000 -28800 0 PST}
+    {2277972000 -25200 1 PDT}
+    {2298531600 -28800 0 PST}
+    {2309421600 -25200 1 PDT}
+    {2329981200 -28800 0 PST}
+    {2341476000 -25200 1 PDT}
+    {2362035600 -28800 0 PST}
+    {2372925600 -25200 1 PDT}
+    {2393485200 -28800 0 PST}
+    {2404375200 -25200 1 PDT}
+    {2424934800 -28800 0 PST}
+    {2435824800 -25200 1 PDT}
+    {2456384400 -28800 0 PST}
+    {2467274400 -25200 1 PDT}
+    {2487834000 -28800 0 PST}
+    {2499328800 -25200 1 PDT}
+    {2519888400 -28800 0 PST}
+    {2530778400 -25200 1 PDT}
+    {2551338000 -28800 0 PST}
+    {2562228000 -25200 1 PDT}
+    {2582787600 -28800 0 PST}
+    {2593677600 -25200 1 PDT}
+    {2614237200 -28800 0 PST}
+    {2625127200 -25200 1 PDT}
+    {2645686800 -28800 0 PST}
+    {2656576800 -25200 1 PDT}
+    {2677136400 -28800 0 PST}
+    {2688631200 -25200 1 PDT}
+    {2709190800 -28800 0 PST}
+    {2720080800 -25200 1 PDT}
+    {2740640400 -28800 0 PST}
+    {2751530400 -25200 1 PDT}
+    {2772090000 -28800 0 PST}
+    {2782980000 -25200 1 PDT}
+    {2803539600 -28800 0 PST}
+    {2814429600 -25200 1 PDT}
+    {2834989200 -28800 0 PST}
+    {2846484000 -25200 1 PDT}
+    {2867043600 -28800 0 PST}
+    {2877933600 -25200 1 PDT}
+    {2898493200 -28800 0 PST}
+    {2909383200 -25200 1 PDT}
+    {2929942800 -28800 0 PST}
+    {2940832800 -25200 1 PDT}
+    {2961392400 -28800 0 PST}
+    {2972282400 -25200 1 PDT}
+    {2992842000 -28800 0 PST}
+    {3003732000 -25200 1 PDT}
+    {3024291600 -28800 0 PST}
+    {3035786400 -25200 1 PDT}
+    {3056346000 -28800 0 PST}
+    {3067236000 -25200 1 PDT}
+    {3087795600 -28800 0 PST}
+    {3098685600 -25200 1 PDT}
+    {3119245200 -28800 0 PST}
+    {3130135200 -25200 1 PDT}
+    {3150694800 -28800 0 PST}
+    {3161584800 -25200 1 PDT}
+    {3182144400 -28800 0 PST}
+    {3193034400 -25200 1 PDT}
+    {3213594000 -28800 0 PST}
+    {3225088800 -25200 1 PDT}
+    {3245648400 -28800 0 PST}
+    {3256538400 -25200 1 PDT}
+    {3277098000 -28800 0 PST}
+    {3287988000 -25200 1 PDT}
+    {3308547600 -28800 0 PST}
+    {3319437600 -25200 1 PDT}
+    {3339997200 -28800 0 PST}
+    {3350887200 -25200 1 PDT}
+    {3371446800 -28800 0 PST}
+    {3382941600 -25200 1 PDT}
+    {3403501200 -28800 0 PST}
+    {3414391200 -25200 1 PDT}
+    {3434950800 -28800 0 PST}
+    {3445840800 -25200 1 PDT}
+    {3466400400 -28800 0 PST}
+    {3477290400 -25200 1 PDT}
+    {3497850000 -28800 0 PST}
+    {3508740000 -25200 1 PDT}
+    {3529299600 -28800 0 PST}
+    {3540189600 -25200 1 PDT}
+    {3560749200 -28800 0 PST}
+    {3572244000 -25200 1 PDT}
+    {3592803600 -28800 0 PST}
+    {3603693600 -25200 1 PDT}
+    {3624253200 -28800 0 PST}
+    {3635143200 -25200 1 PDT}
+    {3655702800 -28800 0 PST}
+    {3666592800 -25200 1 PDT}
+    {3687152400 -28800 0 PST}
+    {3698042400 -25200 1 PDT}
+    {3718602000 -28800 0 PST}
+    {3730096800 -25200 1 PDT}
+    {3750656400 -28800 0 PST}
+    {3761546400 -25200 1 PDT}
+    {3782106000 -28800 0 PST}
+    {3792996000 -25200 1 PDT}
+    {3813555600 -28800 0 PST}
+    {3824445600 -25200 1 PDT}
+    {3845005200 -28800 0 PST}
+    {3855895200 -25200 1 PDT}
+    {3876454800 -28800 0 PST}
+    {3887344800 -25200 1 PDT}
+    {3907904400 -28800 0 PST}
+    {3919399200 -25200 1 PDT}
+    {3939958800 -28800 0 PST}
+    {3950848800 -25200 1 PDT}
+    {3971408400 -28800 0 PST}
+    {3982298400 -25200 1 PDT}
+    {4002858000 -28800 0 PST}
+    {4013748000 -25200 1 PDT}
+    {4034307600 -28800 0 PST}
+    {4045197600 -25200 1 PDT}
+    {4065757200 -28800 0 PST}
+    {4076647200 -25200 1 PDT}
+    {4097206800 -28800 0 PST}
+}
diff --git a/library/tzdata/America/Louisville b/library/tzdata/America/Louisville
new file mode 100644
index 0000000..c5a3e1c
--- /dev/null
+++ b/library/tzdata/America/Louisville
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(America/Kentucky/Louisville)]} {
+    LoadTimeZoneFile America/Kentucky/Louisville
+}
+set TZData(:America/Louisville) $TZData(:America/Kentucky/Louisville)
diff --git a/library/tzdata/America/Lower_Princes b/library/tzdata/America/Lower_Princes
new file mode 100644
index 0000000..94c9197
--- /dev/null
+++ b/library/tzdata/America/Lower_Princes
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(America/Curacao)]} {
+    LoadTimeZoneFile America/Curacao
+}
+set TZData(:America/Lower_Princes) $TZData(:America/Curacao)
diff --git a/library/tzdata/America/Maceio b/library/tzdata/America/Maceio
new file mode 100644
index 0000000..333b878
--- /dev/null
+++ b/library/tzdata/America/Maceio
@@ -0,0 +1,52 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Maceio) {
+    {-9223372036854775808 -8572 0 LMT}
+    {-1767217028 -10800 0 BRT}
+    {-1206957600 -7200 1 BRST}
+    {-1191362400 -10800 0 BRT}
+    {-1175374800 -7200 1 BRST}
+    {-1159826400 -10800 0 BRT}
+    {-633819600 -7200 1 BRST}
+    {-622069200 -10800 0 BRT}
+    {-602283600 -7200 1 BRST}
+    {-591832800 -10800 0 BRT}
+    {-570747600 -7200 1 BRST}
+    {-560210400 -10800 0 BRT}
+    {-539125200 -7200 1 BRST}
+    {-531352800 -10800 0 BRT}
+    {-191365200 -7200 1 BRST}
+    {-184197600 -10800 0 BRT}
+    {-155163600 -7200 1 BRST}
+    {-150069600 -10800 0 BRT}
+    {-128898000 -7200 1 BRST}
+    {-121125600 -10800 0 BRT}
+    {-99954000 -7200 1 BRST}
+    {-89589600 -10800 0 BRT}
+    {-68418000 -7200 1 BRST}
+    {-57967200 -10800 0 BRT}
+    {499748400 -7200 1 BRST}
+    {511236000 -10800 0 BRT}
+    {530593200 -7200 1 BRST}
+    {540266400 -10800 0 BRT}
+    {562129200 -7200 1 BRST}
+    {571197600 -10800 0 BRT}
+    {592974000 -7200 1 BRST}
+    {602042400 -10800 0 BRT}
+    {624423600 -7200 1 BRST}
+    {634701600 -10800 0 BRT}
+    {653536800 -10800 0 BRT}
+    {813553200 -10800 0 BRT}
+    {813726000 -7200 1 BRST}
+    {824004000 -10800 0 BRT}
+    {841802400 -10800 0 BRT}
+    {938660400 -10800 0 BRT}
+    {938919600 -7200 1 BRST}
+    {951616800 -10800 0 BRT}
+    {970974000 -7200 1 BRST}
+    {972180000 -10800 0 BRT}
+    {1000350000 -10800 0 BRT}
+    {1003028400 -7200 1 BRST}
+    {1013911200 -10800 0 BRT}
+    {1033437600 -10800 0 BRT}
+}
diff --git a/library/tzdata/America/Managua b/library/tzdata/America/Managua
new file mode 100644
index 0000000..f729b8a
--- /dev/null
+++ b/library/tzdata/America/Managua
@@ -0,0 +1,21 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Managua) {
+    {-9223372036854775808 -20708 0 LMT}
+    {-2524500892 -20712 0 MMT}
+    {-1121105688 -21600 0 CST}
+    {105084000 -18000 0 EST}
+    {161758800 -21600 0 CST}
+    {290584800 -18000 1 CDT}
+    {299134800 -21600 0 CST}
+    {322034400 -18000 1 CDT}
+    {330584400 -21600 0 CST}
+    {694260000 -18000 0 EST}
+    {717310800 -21600 0 CST}
+    {725868000 -18000 0 EST}
+    {852094800 -21600 0 CST}
+    {1113112800 -18000 1 CDT}
+    {1128229200 -21600 0 CST}
+    {1146384000 -18000 1 CDT}
+    {1159682400 -21600 0 CST}
+}
diff --git a/library/tzdata/America/Manaus b/library/tzdata/America/Manaus
new file mode 100644
index 0000000..058e0f7
--- /dev/null
+++ b/library/tzdata/America/Manaus
@@ -0,0 +1,39 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Manaus) {
+    {-9223372036854775808 -14404 0 LMT}
+    {-1767211196 -14400 0 AMT}
+    {-1206954000 -10800 1 AMST}
+    {-1191358800 -14400 0 AMT}
+    {-1175371200 -10800 1 AMST}
+    {-1159822800 -14400 0 AMT}
+    {-633816000 -10800 1 AMST}
+    {-622065600 -14400 0 AMT}
+    {-602280000 -10800 1 AMST}
+    {-591829200 -14400 0 AMT}
+    {-570744000 -10800 1 AMST}
+    {-560206800 -14400 0 AMT}
+    {-539121600 -10800 1 AMST}
+    {-531349200 -14400 0 AMT}
+    {-191361600 -10800 1 AMST}
+    {-184194000 -14400 0 AMT}
+    {-155160000 -10800 1 AMST}
+    {-150066000 -14400 0 AMT}
+    {-128894400 -10800 1 AMST}
+    {-121122000 -14400 0 AMT}
+    {-99950400 -10800 1 AMST}
+    {-89586000 -14400 0 AMT}
+    {-68414400 -10800 1 AMST}
+    {-57963600 -14400 0 AMT}
+    {499752000 -10800 1 AMST}
+    {511239600 -14400 0 AMT}
+    {530596800 -10800 1 AMST}
+    {540270000 -14400 0 AMT}
+    {562132800 -10800 1 AMST}
+    {571201200 -14400 0 AMT}
+    {590036400 -14400 0 AMT}
+    {749188800 -14400 0 AMT}
+    {750830400 -10800 1 AMST}
+    {761713200 -14400 0 AMT}
+    {780202800 -14400 0 AMT}
+}
diff --git a/library/tzdata/America/Marigot b/library/tzdata/America/Marigot
new file mode 100644
index 0000000..c2b38730c
--- /dev/null
+++ b/library/tzdata/America/Marigot
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(America/Port_of_Spain)]} {
+    LoadTimeZoneFile America/Port_of_Spain
+}
+set TZData(:America/Marigot) $TZData(:America/Port_of_Spain)
diff --git a/library/tzdata/America/Martinique b/library/tzdata/America/Martinique
new file mode 100644
index 0000000..1f1b491
--- /dev/null
+++ b/library/tzdata/America/Martinique
@@ -0,0 +1,9 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Martinique) {
+    {-9223372036854775808 -14660 0 LMT}
+    {-2524506940 -14660 0 FFMT}
+    {-1851537340 -14400 0 AST}
+    {323841600 -10800 1 ADT}
+    {338958000 -14400 0 AST}
+}
diff --git a/library/tzdata/America/Matamoros b/library/tzdata/America/Matamoros
new file mode 100644
index 0000000..2b98652
--- /dev/null
+++ b/library/tzdata/America/Matamoros
@@ -0,0 +1,219 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Matamoros) {
+    {-9223372036854775808 -24000 0 LMT}
+    {-1514743200 -21600 0 CST}
+    {568015200 -21600 0 CST}
+    {576057600 -18000 1 CDT}
+    {594198000 -21600 0 CST}
+    {599637600 -21600 0 CST}
+    {828864000 -18000 1 CDT}
+    {846399600 -21600 0 CST}
+    {860313600 -18000 1 CDT}
+    {877849200 -21600 0 CST}
+    {891763200 -18000 1 CDT}
+    {909298800 -21600 0 CST}
+    {923212800 -18000 1 CDT}
+    {941353200 -21600 0 CST}
+    {954662400 -18000 1 CDT}
+    {972802800 -21600 0 CST}
+    {989136000 -18000 1 CDT}
+    {1001833200 -21600 0 CST}
+    {1018166400 -18000 1 CDT}
+    {1035702000 -21600 0 CST}
+    {1049616000 -18000 1 CDT}
+    {1067151600 -21600 0 CST}
+    {1081065600 -18000 1 CDT}
+    {1099206000 -21600 0 CST}
+    {1112515200 -18000 1 CDT}
+    {1130655600 -21600 0 CST}
+    {1143964800 -18000 1 CDT}
+    {1162105200 -21600 0 CST}
+    {1175414400 -18000 1 CDT}
+    {1193554800 -21600 0 CST}
+    {1207468800 -18000 1 CDT}
+    {1225004400 -21600 0 CST}
+    {1238918400 -18000 1 CDT}
+    {1256454000 -21600 0 CST}
+    {1262325600 -21600 0 CST}
+    {1268553600 -18000 1 CDT}
+    {1289113200 -21600 0 CST}
+    {1300003200 -18000 1 CDT}
+    {1320562800 -21600 0 CST}
+    {1331452800 -18000 1 CDT}
+    {1352012400 -21600 0 CST}
+    {1362902400 -18000 1 CDT}
+    {1383462000 -21600 0 CST}
+    {1394352000 -18000 1 CDT}
+    {1414911600 -21600 0 CST}
+    {1425801600 -18000 1 CDT}
+    {1446361200 -21600 0 CST}
+    {1457856000 -18000 1 CDT}
+    {1478415600 -21600 0 CST}
+    {1489305600 -18000 1 CDT}
+    {1509865200 -21600 0 CST}
+    {1520755200 -18000 1 CDT}
+    {1541314800 -21600 0 CST}
+    {1552204800 -18000 1 CDT}
+    {1572764400 -21600 0 CST}
+    {1583654400 -18000 1 CDT}
+    {1604214000 -21600 0 CST}
+    {1615708800 -18000 1 CDT}
+    {1636268400 -21600 0 CST}
+    {1647158400 -18000 1 CDT}
+    {1667718000 -21600 0 CST}
+    {1678608000 -18000 1 CDT}
+    {1699167600 -21600 0 CST}
+    {1710057600 -18000 1 CDT}
+    {1730617200 -21600 0 CST}
+    {1741507200 -18000 1 CDT}
+    {1762066800 -21600 0 CST}
+    {1772956800 -18000 1 CDT}
+    {1793516400 -21600 0 CST}
+    {1805011200 -18000 1 CDT}
+    {1825570800 -21600 0 CST}
+    {1836460800 -18000 1 CDT}
+    {1857020400 -21600 0 CST}
+    {1867910400 -18000 1 CDT}
+    {1888470000 -21600 0 CST}
+    {1899360000 -18000 1 CDT}
+    {1919919600 -21600 0 CST}
+    {1930809600 -18000 1 CDT}
+    {1951369200 -21600 0 CST}
+    {1962864000 -18000 1 CDT}
+    {1983423600 -21600 0 CST}
+    {1994313600 -18000 1 CDT}
+    {2014873200 -21600 0 CST}
+    {2025763200 -18000 1 CDT}
+    {2046322800 -21600 0 CST}
+    {2057212800 -18000 1 CDT}
+    {2077772400 -21600 0 CST}
+    {2088662400 -18000 1 CDT}
+    {2109222000 -21600 0 CST}
+    {2120112000 -18000 1 CDT}
+    {2140671600 -21600 0 CST}
+    {2152166400 -18000 1 CDT}
+    {2172726000 -21600 0 CST}
+    {2183616000 -18000 1 CDT}
+    {2204175600 -21600 0 CST}
+    {2215065600 -18000 1 CDT}
+    {2235625200 -21600 0 CST}
+    {2246515200 -18000 1 CDT}
+    {2267074800 -21600 0 CST}
+    {2277964800 -18000 1 CDT}
+    {2298524400 -21600 0 CST}
+    {2309414400 -18000 1 CDT}
+    {2329974000 -21600 0 CST}
+    {2341468800 -18000 1 CDT}
+    {2362028400 -21600 0 CST}
+    {2372918400 -18000 1 CDT}
+    {2393478000 -21600 0 CST}
+    {2404368000 -18000 1 CDT}
+    {2424927600 -21600 0 CST}
+    {2435817600 -18000 1 CDT}
+    {2456377200 -21600 0 CST}
+    {2467267200 -18000 1 CDT}
+    {2487826800 -21600 0 CST}
+    {2499321600 -18000 1 CDT}
+    {2519881200 -21600 0 CST}
+    {2530771200 -18000 1 CDT}
+    {2551330800 -21600 0 CST}
+    {2562220800 -18000 1 CDT}
+    {2582780400 -21600 0 CST}
+    {2593670400 -18000 1 CDT}
+    {2614230000 -21600 0 CST}
+    {2625120000 -18000 1 CDT}
+    {2645679600 -21600 0 CST}
+    {2656569600 -18000 1 CDT}
+    {2677129200 -21600 0 CST}
+    {2688624000 -18000 1 CDT}
+    {2709183600 -21600 0 CST}
+    {2720073600 -18000 1 CDT}
+    {2740633200 -21600 0 CST}
+    {2751523200 -18000 1 CDT}
+    {2772082800 -21600 0 CST}
+    {2782972800 -18000 1 CDT}
+    {2803532400 -21600 0 CST}
+    {2814422400 -18000 1 CDT}
+    {2834982000 -21600 0 CST}
+    {2846476800 -18000 1 CDT}
+    {2867036400 -21600 0 CST}
+    {2877926400 -18000 1 CDT}
+    {2898486000 -21600 0 CST}
+    {2909376000 -18000 1 CDT}
+    {2929935600 -21600 0 CST}
+    {2940825600 -18000 1 CDT}
+    {2961385200 -21600 0 CST}
+    {2972275200 -18000 1 CDT}
+    {2992834800 -21600 0 CST}
+    {3003724800 -18000 1 CDT}
+    {3024284400 -21600 0 CST}
+    {3035779200 -18000 1 CDT}
+    {3056338800 -21600 0 CST}
+    {3067228800 -18000 1 CDT}
+    {3087788400 -21600 0 CST}
+    {3098678400 -18000 1 CDT}
+    {3119238000 -21600 0 CST}
+    {3130128000 -18000 1 CDT}
+    {3150687600 -21600 0 CST}
+    {3161577600 -18000 1 CDT}
+    {3182137200 -21600 0 CST}
+    {3193027200 -18000 1 CDT}
+    {3213586800 -21600 0 CST}
+    {3225081600 -18000 1 CDT}
+    {3245641200 -21600 0 CST}
+    {3256531200 -18000 1 CDT}
+    {3277090800 -21600 0 CST}
+    {3287980800 -18000 1 CDT}
+    {3308540400 -21600 0 CST}
+    {3319430400 -18000 1 CDT}
+    {3339990000 -21600 0 CST}
+    {3350880000 -18000 1 CDT}
+    {3371439600 -21600 0 CST}
+    {3382934400 -18000 1 CDT}
+    {3403494000 -21600 0 CST}
+    {3414384000 -18000 1 CDT}
+    {3434943600 -21600 0 CST}
+    {3445833600 -18000 1 CDT}
+    {3466393200 -21600 0 CST}
+    {3477283200 -18000 1 CDT}
+    {3497842800 -21600 0 CST}
+    {3508732800 -18000 1 CDT}
+    {3529292400 -21600 0 CST}
+    {3540182400 -18000 1 CDT}
+    {3560742000 -21600 0 CST}
+    {3572236800 -18000 1 CDT}
+    {3592796400 -21600 0 CST}
+    {3603686400 -18000 1 CDT}
+    {3624246000 -21600 0 CST}
+    {3635136000 -18000 1 CDT}
+    {3655695600 -21600 0 CST}
+    {3666585600 -18000 1 CDT}
+    {3687145200 -21600 0 CST}
+    {3698035200 -18000 1 CDT}
+    {3718594800 -21600 0 CST}
+    {3730089600 -18000 1 CDT}
+    {3750649200 -21600 0 CST}
+    {3761539200 -18000 1 CDT}
+    {3782098800 -21600 0 CST}
+    {3792988800 -18000 1 CDT}
+    {3813548400 -21600 0 CST}
+    {3824438400 -18000 1 CDT}
+    {3844998000 -21600 0 CST}
+    {3855888000 -18000 1 CDT}
+    {3876447600 -21600 0 CST}
+    {3887337600 -18000 1 CDT}
+    {3907897200 -21600 0 CST}
+    {3919392000 -18000 1 CDT}
+    {3939951600 -21600 0 CST}
+    {3950841600 -18000 1 CDT}
+    {3971401200 -21600 0 CST}
+    {3982291200 -18000 1 CDT}
+    {4002850800 -21600 0 CST}
+    {4013740800 -18000 1 CDT}
+    {4034300400 -21600 0 CST}
+    {4045190400 -18000 1 CDT}
+    {4065750000 -21600 0 CST}
+    {4076640000 -18000 1 CDT}
+    {4097199600 -21600 0 CST}
+}
diff --git a/library/tzdata/America/Mazatlan b/library/tzdata/America/Mazatlan
new file mode 100644
index 0000000..e56d7d0
--- /dev/null
+++ b/library/tzdata/America/Mazatlan
@@ -0,0 +1,222 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Mazatlan) {
+    {-9223372036854775808 -25540 0 LMT}
+    {-1514739600 -25200 0 MST}
+    {-1343066400 -21600 0 CST}
+    {-1234807200 -25200 0 MST}
+    {-1220292000 -21600 0 CST}
+    {-1207159200 -25200 0 MST}
+    {-1191344400 -21600 0 CST}
+    {-873828000 -25200 0 MST}
+    {-661539600 -28800 0 PST}
+    {28800 -25200 0 MST}
+    {828867600 -21600 1 MDT}
+    {846403200 -25200 0 MST}
+    {860317200 -21600 1 MDT}
+    {877852800 -25200 0 MST}
+    {891766800 -21600 1 MDT}
+    {909302400 -25200 0 MST}
+    {923216400 -21600 1 MDT}
+    {941356800 -25200 0 MST}
+    {954666000 -21600 1 MDT}
+    {972806400 -25200 0 MST}
+    {989139600 -21600 1 MDT}
+    {1001836800 -25200 0 MST}
+    {1018170000 -21600 1 MDT}
+    {1035705600 -25200 0 MST}
+    {1049619600 -21600 1 MDT}
+    {1067155200 -25200 0 MST}
+    {1081069200 -21600 1 MDT}
+    {1099209600 -25200 0 MST}
+    {1112518800 -21600 1 MDT}
+    {1130659200 -25200 0 MST}
+    {1143968400 -21600 1 MDT}
+    {1162108800 -25200 0 MST}
+    {1175418000 -21600 1 MDT}
+    {1193558400 -25200 0 MST}
+    {1207472400 -21600 1 MDT}
+    {1225008000 -25200 0 MST}
+    {1238922000 -21600 1 MDT}
+    {1256457600 -25200 0 MST}
+    {1270371600 -21600 1 MDT}
+    {1288512000 -25200 0 MST}
+    {1301821200 -21600 1 MDT}
+    {1319961600 -25200 0 MST}
+    {1333270800 -21600 1 MDT}
+    {1351411200 -25200 0 MST}
+    {1365325200 -21600 1 MDT}
+    {1382860800 -25200 0 MST}
+    {1396774800 -21600 1 MDT}
+    {1414310400 -25200 0 MST}
+    {1428224400 -21600 1 MDT}
+    {1445760000 -25200 0 MST}
+    {1459674000 -21600 1 MDT}
+    {1477814400 -25200 0 MST}
+    {1491123600 -21600 1 MDT}
+    {1509264000 -25200 0 MST}
+    {1522573200 -21600 1 MDT}
+    {1540713600 -25200 0 MST}
+    {1554627600 -21600 1 MDT}
+    {1572163200 -25200 0 MST}
+    {1586077200 -21600 1 MDT}
+    {1603612800 -25200 0 MST}
+    {1617526800 -21600 1 MDT}
+    {1635667200 -25200 0 MST}
+    {1648976400 -21600 1 MDT}
+    {1667116800 -25200 0 MST}
+    {1680426000 -21600 1 MDT}
+    {1698566400 -25200 0 MST}
+    {1712480400 -21600 1 MDT}
+    {1730016000 -25200 0 MST}
+    {1743930000 -21600 1 MDT}
+    {1761465600 -25200 0 MST}
+    {1775379600 -21600 1 MDT}
+    {1792915200 -25200 0 MST}
+    {1806829200 -21600 1 MDT}
+    {1824969600 -25200 0 MST}
+    {1838278800 -21600 1 MDT}
+    {1856419200 -25200 0 MST}
+    {1869728400 -21600 1 MDT}
+    {1887868800 -25200 0 MST}
+    {1901782800 -21600 1 MDT}
+    {1919318400 -25200 0 MST}
+    {1933232400 -21600 1 MDT}
+    {1950768000 -25200 0 MST}
+    {1964682000 -21600 1 MDT}
+    {1982822400 -25200 0 MST}
+    {1996131600 -21600 1 MDT}
+    {2014272000 -25200 0 MST}
+    {2027581200 -21600 1 MDT}
+    {2045721600 -25200 0 MST}
+    {2059030800 -21600 1 MDT}
+    {2077171200 -25200 0 MST}
+    {2091085200 -21600 1 MDT}
+    {2108620800 -25200 0 MST}
+    {2122534800 -21600 1 MDT}
+    {2140070400 -25200 0 MST}
+    {2153984400 -21600 1 MDT}
+    {2172124800 -25200 0 MST}
+    {2185434000 -21600 1 MDT}
+    {2203574400 -25200 0 MST}
+    {2216883600 -21600 1 MDT}
+    {2235024000 -25200 0 MST}
+    {2248938000 -21600 1 MDT}
+    {2266473600 -25200 0 MST}
+    {2280387600 -21600 1 MDT}
+    {2297923200 -25200 0 MST}
+    {2311837200 -21600 1 MDT}
+    {2329372800 -25200 0 MST}
+    {2343286800 -21600 1 MDT}
+    {2361427200 -25200 0 MST}
+    {2374736400 -21600 1 MDT}
+    {2392876800 -25200 0 MST}
+    {2406186000 -21600 1 MDT}
+    {2424326400 -25200 0 MST}
+    {2438240400 -21600 1 MDT}
+    {2455776000 -25200 0 MST}
+    {2469690000 -21600 1 MDT}
+    {2487225600 -25200 0 MST}
+    {2501139600 -21600 1 MDT}
+    {2519280000 -25200 0 MST}
+    {2532589200 -21600 1 MDT}
+    {2550729600 -25200 0 MST}
+    {2564038800 -21600 1 MDT}
+    {2582179200 -25200 0 MST}
+    {2596093200 -21600 1 MDT}
+    {2613628800 -25200 0 MST}
+    {2627542800 -21600 1 MDT}
+    {2645078400 -25200 0 MST}
+    {2658992400 -21600 1 MDT}
+    {2676528000 -25200 0 MST}
+    {2690442000 -21600 1 MDT}
+    {2708582400 -25200 0 MST}
+    {2721891600 -21600 1 MDT}
+    {2740032000 -25200 0 MST}
+    {2753341200 -21600 1 MDT}
+    {2771481600 -25200 0 MST}
+    {2785395600 -21600 1 MDT}
+    {2802931200 -25200 0 MST}
+    {2816845200 -21600 1 MDT}
+    {2834380800 -25200 0 MST}
+    {2848294800 -21600 1 MDT}
+    {2866435200 -25200 0 MST}
+    {2879744400 -21600 1 MDT}
+    {2897884800 -25200 0 MST}
+    {2911194000 -21600 1 MDT}
+    {2929334400 -25200 0 MST}
+    {2942643600 -21600 1 MDT}
+    {2960784000 -25200 0 MST}
+    {2974698000 -21600 1 MDT}
+    {2992233600 -25200 0 MST}
+    {3006147600 -21600 1 MDT}
+    {3023683200 -25200 0 MST}
+    {3037597200 -21600 1 MDT}
+    {3055737600 -25200 0 MST}
+    {3069046800 -21600 1 MDT}
+    {3087187200 -25200 0 MST}
+    {3100496400 -21600 1 MDT}
+    {3118636800 -25200 0 MST}
+    {3132550800 -21600 1 MDT}
+    {3150086400 -25200 0 MST}
+    {3164000400 -21600 1 MDT}
+    {3181536000 -25200 0 MST}
+    {3195450000 -21600 1 MDT}
+    {3212985600 -25200 0 MST}
+    {3226899600 -21600 1 MDT}
+    {3245040000 -25200 0 MST}
+    {3258349200 -21600 1 MDT}
+    {3276489600 -25200 0 MST}
+    {3289798800 -21600 1 MDT}
+    {3307939200 -25200 0 MST}
+    {3321853200 -21600 1 MDT}
+    {3339388800 -25200 0 MST}
+    {3353302800 -21600 1 MDT}
+    {3370838400 -25200 0 MST}
+    {3384752400 -21600 1 MDT}
+    {3402892800 -25200 0 MST}
+    {3416202000 -21600 1 MDT}
+    {3434342400 -25200 0 MST}
+    {3447651600 -21600 1 MDT}
+    {3465792000 -25200 0 MST}
+    {3479706000 -21600 1 MDT}
+    {3497241600 -25200 0 MST}
+    {3511155600 -21600 1 MDT}
+    {3528691200 -25200 0 MST}
+    {3542605200 -21600 1 MDT}
+    {3560140800 -25200 0 MST}
+    {3574054800 -21600 1 MDT}
+    {3592195200 -25200 0 MST}
+    {3605504400 -21600 1 MDT}
+    {3623644800 -25200 0 MST}
+    {3636954000 -21600 1 MDT}
+    {3655094400 -25200 0 MST}
+    {3669008400 -21600 1 MDT}
+    {3686544000 -25200 0 MST}
+    {3700458000 -21600 1 MDT}
+    {3717993600 -25200 0 MST}
+    {3731907600 -21600 1 MDT}
+    {3750048000 -25200 0 MST}
+    {3763357200 -21600 1 MDT}
+    {3781497600 -25200 0 MST}
+    {3794806800 -21600 1 MDT}
+    {3812947200 -25200 0 MST}
+    {3826256400 -21600 1 MDT}
+    {3844396800 -25200 0 MST}
+    {3858310800 -21600 1 MDT}
+    {3875846400 -25200 0 MST}
+    {3889760400 -21600 1 MDT}
+    {3907296000 -25200 0 MST}
+    {3921210000 -21600 1 MDT}
+    {3939350400 -25200 0 MST}
+    {3952659600 -21600 1 MDT}
+    {3970800000 -25200 0 MST}
+    {3984109200 -21600 1 MDT}
+    {4002249600 -25200 0 MST}
+    {4016163600 -21600 1 MDT}
+    {4033699200 -25200 0 MST}
+    {4047613200 -21600 1 MDT}
+    {4065148800 -25200 0 MST}
+    {4079062800 -21600 1 MDT}
+    {4096598400 -25200 0 MST}
+}
diff --git a/library/tzdata/America/Mendoza b/library/tzdata/America/Mendoza
new file mode 100644
index 0000000..511d83e
--- /dev/null
+++ b/library/tzdata/America/Mendoza
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(America/Argentina/Mendoza)]} {
+    LoadTimeZoneFile America/Argentina/Mendoza
+}
+set TZData(:America/Mendoza) $TZData(:America/Argentina/Mendoza)
diff --git a/library/tzdata/America/Menominee b/library/tzdata/America/Menominee
new file mode 100644
index 0000000..382aeda
--- /dev/null
+++ b/library/tzdata/America/Menominee
@@ -0,0 +1,274 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Menominee) {
+    {-9223372036854775808 -21027 0 LMT}
+    {-2659759773 -21600 0 CST}
+    {-1633276800 -18000 1 CDT}
+    {-1615136400 -21600 0 CST}
+    {-1601827200 -18000 1 CDT}
+    {-1583686800 -21600 0 CST}
+    {-880214400 -18000 1 CWT}
+    {-769395600 -18000 1 CPT}
+    {-765392400 -21600 0 CST}
+    {-757360800 -21600 0 CST}
+    {-747244800 -18000 1 CDT}
+    {-733942800 -21600 0 CST}
+    {-116438400 -18000 1 CDT}
+    {-100112400 -21600 0 CST}
+    {-21484800 -18000 0 EST}
+    {104914800 -21600 0 CST}
+    {104918400 -18000 1 CDT}
+    {120639600 -21600 0 CST}
+    {126691200 -18000 1 CDT}
+    {152089200 -21600 0 CST}
+    {162374400 -18000 1 CDT}
+    {183538800 -21600 0 CST}
+    {199267200 -18000 1 CDT}
+    {215593200 -21600 0 CST}
+    {230716800 -18000 1 CDT}
+    {247042800 -21600 0 CST}
+    {262771200 -18000 1 CDT}
+    {278492400 -21600 0 CST}
+    {294220800 -18000 1 CDT}
+    {309942000 -21600 0 CST}
+    {325670400 -18000 1 CDT}
+    {341391600 -21600 0 CST}
+    {357120000 -18000 1 CDT}
+    {372841200 -21600 0 CST}
+    {388569600 -18000 1 CDT}
+    {404895600 -21600 0 CST}
+    {420019200 -18000 1 CDT}
+    {436345200 -21600 0 CST}
+    {452073600 -18000 1 CDT}
+    {467794800 -21600 0 CST}
+    {483523200 -18000 1 CDT}
+    {499244400 -21600 0 CST}
+    {514972800 -18000 1 CDT}
+    {530694000 -21600 0 CST}
+    {544608000 -18000 1 CDT}
+    {562143600 -21600 0 CST}
+    {576057600 -18000 1 CDT}
+    {594198000 -21600 0 CST}
+    {607507200 -18000 1 CDT}
+    {625647600 -21600 0 CST}
+    {638956800 -18000 1 CDT}
+    {657097200 -21600 0 CST}
+    {671011200 -18000 1 CDT}
+    {688546800 -21600 0 CST}
+    {702460800 -18000 1 CDT}
+    {719996400 -21600 0 CST}
+    {733910400 -18000 1 CDT}
+    {752050800 -21600 0 CST}
+    {765360000 -18000 1 CDT}
+    {783500400 -21600 0 CST}
+    {796809600 -18000 1 CDT}
+    {814950000 -21600 0 CST}
+    {828864000 -18000 1 CDT}
+    {846399600 -21600 0 CST}
+    {860313600 -18000 1 CDT}
+    {877849200 -21600 0 CST}
+    {891763200 -18000 1 CDT}
+    {909298800 -21600 0 CST}
+    {923212800 -18000 1 CDT}
+    {941353200 -21600 0 CST}
+    {954662400 -18000 1 CDT}
+    {972802800 -21600 0 CST}
+    {986112000 -18000 1 CDT}
+    {1004252400 -21600 0 CST}
+    {1018166400 -18000 1 CDT}
+    {1035702000 -21600 0 CST}
+    {1049616000 -18000 1 CDT}
+    {1067151600 -21600 0 CST}
+    {1081065600 -18000 1 CDT}
+    {1099206000 -21600 0 CST}
+    {1112515200 -18000 1 CDT}
+    {1130655600 -21600 0 CST}
+    {1143964800 -18000 1 CDT}
+    {1162105200 -21600 0 CST}
+    {1173600000 -18000 1 CDT}
+    {1194159600 -21600 0 CST}
+    {1205049600 -18000 1 CDT}
+    {1225609200 -21600 0 CST}
+    {1236499200 -18000 1 CDT}
+    {1257058800 -21600 0 CST}
+    {1268553600 -18000 1 CDT}
+    {1289113200 -21600 0 CST}
+    {1300003200 -18000 1 CDT}
+    {1320562800 -21600 0 CST}
+    {1331452800 -18000 1 CDT}
+    {1352012400 -21600 0 CST}
+    {1362902400 -18000 1 CDT}
+    {1383462000 -21600 0 CST}
+    {1394352000 -18000 1 CDT}
+    {1414911600 -21600 0 CST}
+    {1425801600 -18000 1 CDT}
+    {1446361200 -21600 0 CST}
+    {1457856000 -18000 1 CDT}
+    {1478415600 -21600 0 CST}
+    {1489305600 -18000 1 CDT}
+    {1509865200 -21600 0 CST}
+    {1520755200 -18000 1 CDT}
+    {1541314800 -21600 0 CST}
+    {1552204800 -18000 1 CDT}
+    {1572764400 -21600 0 CST}
+    {1583654400 -18000 1 CDT}
+    {1604214000 -21600 0 CST}
+    {1615708800 -18000 1 CDT}
+    {1636268400 -21600 0 CST}
+    {1647158400 -18000 1 CDT}
+    {1667718000 -21600 0 CST}
+    {1678608000 -18000 1 CDT}
+    {1699167600 -21600 0 CST}
+    {1710057600 -18000 1 CDT}
+    {1730617200 -21600 0 CST}
+    {1741507200 -18000 1 CDT}
+    {1762066800 -21600 0 CST}
+    {1772956800 -18000 1 CDT}
+    {1793516400 -21600 0 CST}
+    {1805011200 -18000 1 CDT}
+    {1825570800 -21600 0 CST}
+    {1836460800 -18000 1 CDT}
+    {1857020400 -21600 0 CST}
+    {1867910400 -18000 1 CDT}
+    {1888470000 -21600 0 CST}
+    {1899360000 -18000 1 CDT}
+    {1919919600 -21600 0 CST}
+    {1930809600 -18000 1 CDT}
+    {1951369200 -21600 0 CST}
+    {1962864000 -18000 1 CDT}
+    {1983423600 -21600 0 CST}
+    {1994313600 -18000 1 CDT}
+    {2014873200 -21600 0 CST}
+    {2025763200 -18000 1 CDT}
+    {2046322800 -21600 0 CST}
+    {2057212800 -18000 1 CDT}
+    {2077772400 -21600 0 CST}
+    {2088662400 -18000 1 CDT}
+    {2109222000 -21600 0 CST}
+    {2120112000 -18000 1 CDT}
+    {2140671600 -21600 0 CST}
+    {2152166400 -18000 1 CDT}
+    {2172726000 -21600 0 CST}
+    {2183616000 -18000 1 CDT}
+    {2204175600 -21600 0 CST}
+    {2215065600 -18000 1 CDT}
+    {2235625200 -21600 0 CST}
+    {2246515200 -18000 1 CDT}
+    {2267074800 -21600 0 CST}
+    {2277964800 -18000 1 CDT}
+    {2298524400 -21600 0 CST}
+    {2309414400 -18000 1 CDT}
+    {2329974000 -21600 0 CST}
+    {2341468800 -18000 1 CDT}
+    {2362028400 -21600 0 CST}
+    {2372918400 -18000 1 CDT}
+    {2393478000 -21600 0 CST}
+    {2404368000 -18000 1 CDT}
+    {2424927600 -21600 0 CST}
+    {2435817600 -18000 1 CDT}
+    {2456377200 -21600 0 CST}
+    {2467267200 -18000 1 CDT}
+    {2487826800 -21600 0 CST}
+    {2499321600 -18000 1 CDT}
+    {2519881200 -21600 0 CST}
+    {2530771200 -18000 1 CDT}
+    {2551330800 -21600 0 CST}
+    {2562220800 -18000 1 CDT}
+    {2582780400 -21600 0 CST}
+    {2593670400 -18000 1 CDT}
+    {2614230000 -21600 0 CST}
+    {2625120000 -18000 1 CDT}
+    {2645679600 -21600 0 CST}
+    {2656569600 -18000 1 CDT}
+    {2677129200 -21600 0 CST}
+    {2688624000 -18000 1 CDT}
+    {2709183600 -21600 0 CST}
+    {2720073600 -18000 1 CDT}
+    {2740633200 -21600 0 CST}
+    {2751523200 -18000 1 CDT}
+    {2772082800 -21600 0 CST}
+    {2782972800 -18000 1 CDT}
+    {2803532400 -21600 0 CST}
+    {2814422400 -18000 1 CDT}
+    {2834982000 -21600 0 CST}
+    {2846476800 -18000 1 CDT}
+    {2867036400 -21600 0 CST}
+    {2877926400 -18000 1 CDT}
+    {2898486000 -21600 0 CST}
+    {2909376000 -18000 1 CDT}
+    {2929935600 -21600 0 CST}
+    {2940825600 -18000 1 CDT}
+    {2961385200 -21600 0 CST}
+    {2972275200 -18000 1 CDT}
+    {2992834800 -21600 0 CST}
+    {3003724800 -18000 1 CDT}
+    {3024284400 -21600 0 CST}
+    {3035779200 -18000 1 CDT}
+    {3056338800 -21600 0 CST}
+    {3067228800 -18000 1 CDT}
+    {3087788400 -21600 0 CST}
+    {3098678400 -18000 1 CDT}
+    {3119238000 -21600 0 CST}
+    {3130128000 -18000 1 CDT}
+    {3150687600 -21600 0 CST}
+    {3161577600 -18000 1 CDT}
+    {3182137200 -21600 0 CST}
+    {3193027200 -18000 1 CDT}
+    {3213586800 -21600 0 CST}
+    {3225081600 -18000 1 CDT}
+    {3245641200 -21600 0 CST}
+    {3256531200 -18000 1 CDT}
+    {3277090800 -21600 0 CST}
+    {3287980800 -18000 1 CDT}
+    {3308540400 -21600 0 CST}
+    {3319430400 -18000 1 CDT}
+    {3339990000 -21600 0 CST}
+    {3350880000 -18000 1 CDT}
+    {3371439600 -21600 0 CST}
+    {3382934400 -18000 1 CDT}
+    {3403494000 -21600 0 CST}
+    {3414384000 -18000 1 CDT}
+    {3434943600 -21600 0 CST}
+    {3445833600 -18000 1 CDT}
+    {3466393200 -21600 0 CST}
+    {3477283200 -18000 1 CDT}
+    {3497842800 -21600 0 CST}
+    {3508732800 -18000 1 CDT}
+    {3529292400 -21600 0 CST}
+    {3540182400 -18000 1 CDT}
+    {3560742000 -21600 0 CST}
+    {3572236800 -18000 1 CDT}
+    {3592796400 -21600 0 CST}
+    {3603686400 -18000 1 CDT}
+    {3624246000 -21600 0 CST}
+    {3635136000 -18000 1 CDT}
+    {3655695600 -21600 0 CST}
+    {3666585600 -18000 1 CDT}
+    {3687145200 -21600 0 CST}
+    {3698035200 -18000 1 CDT}
+    {3718594800 -21600 0 CST}
+    {3730089600 -18000 1 CDT}
+    {3750649200 -21600 0 CST}
+    {3761539200 -18000 1 CDT}
+    {3782098800 -21600 0 CST}
+    {3792988800 -18000 1 CDT}
+    {3813548400 -21600 0 CST}
+    {3824438400 -18000 1 CDT}
+    {3844998000 -21600 0 CST}
+    {3855888000 -18000 1 CDT}
+    {3876447600 -21600 0 CST}
+    {3887337600 -18000 1 CDT}
+    {3907897200 -21600 0 CST}
+    {3919392000 -18000 1 CDT}
+    {3939951600 -21600 0 CST}
+    {3950841600 -18000 1 CDT}
+    {3971401200 -21600 0 CST}
+    {3982291200 -18000 1 CDT}
+    {4002850800 -21600 0 CST}
+    {4013740800 -18000 1 CDT}
+    {4034300400 -21600 0 CST}
+    {4045190400 -18000 1 CDT}
+    {4065750000 -21600 0 CST}
+    {4076640000 -18000 1 CDT}
+    {4097199600 -21600 0 CST}
+}
diff --git a/library/tzdata/America/Merida b/library/tzdata/America/Merida
new file mode 100644
index 0000000..ebf5927
--- /dev/null
+++ b/library/tzdata/America/Merida
@@ -0,0 +1,216 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Merida) {
+    {-9223372036854775808 -21508 0 LMT}
+    {-1514743200 -21600 0 CST}
+    {377935200 -18000 0 EST}
+    {407653200 -21600 0 CST}
+    {828864000 -18000 1 CDT}
+    {846399600 -21600 0 CST}
+    {860313600 -18000 1 CDT}
+    {877849200 -21600 0 CST}
+    {891763200 -18000 1 CDT}
+    {909298800 -21600 0 CST}
+    {923212800 -18000 1 CDT}
+    {941353200 -21600 0 CST}
+    {954662400 -18000 1 CDT}
+    {972802800 -21600 0 CST}
+    {989136000 -18000 1 CDT}
+    {1001833200 -21600 0 CST}
+    {1018166400 -18000 1 CDT}
+    {1035702000 -21600 0 CST}
+    {1049616000 -18000 1 CDT}
+    {1067151600 -21600 0 CST}
+    {1081065600 -18000 1 CDT}
+    {1099206000 -21600 0 CST}
+    {1112515200 -18000 1 CDT}
+    {1130655600 -21600 0 CST}
+    {1143964800 -18000 1 CDT}
+    {1162105200 -21600 0 CST}
+    {1175414400 -18000 1 CDT}
+    {1193554800 -21600 0 CST}
+    {1207468800 -18000 1 CDT}
+    {1225004400 -21600 0 CST}
+    {1238918400 -18000 1 CDT}
+    {1256454000 -21600 0 CST}
+    {1270368000 -18000 1 CDT}
+    {1288508400 -21600 0 CST}
+    {1301817600 -18000 1 CDT}
+    {1319958000 -21600 0 CST}
+    {1333267200 -18000 1 CDT}
+    {1351407600 -21600 0 CST}
+    {1365321600 -18000 1 CDT}
+    {1382857200 -21600 0 CST}
+    {1396771200 -18000 1 CDT}
+    {1414306800 -21600 0 CST}
+    {1428220800 -18000 1 CDT}
+    {1445756400 -21600 0 CST}
+    {1459670400 -18000 1 CDT}
+    {1477810800 -21600 0 CST}
+    {1491120000 -18000 1 CDT}
+    {1509260400 -21600 0 CST}
+    {1522569600 -18000 1 CDT}
+    {1540710000 -21600 0 CST}
+    {1554624000 -18000 1 CDT}
+    {1572159600 -21600 0 CST}
+    {1586073600 -18000 1 CDT}
+    {1603609200 -21600 0 CST}
+    {1617523200 -18000 1 CDT}
+    {1635663600 -21600 0 CST}
+    {1648972800 -18000 1 CDT}
+    {1667113200 -21600 0 CST}
+    {1680422400 -18000 1 CDT}
+    {1698562800 -21600 0 CST}
+    {1712476800 -18000 1 CDT}
+    {1730012400 -21600 0 CST}
+    {1743926400 -18000 1 CDT}
+    {1761462000 -21600 0 CST}
+    {1775376000 -18000 1 CDT}
+    {1792911600 -21600 0 CST}
+    {1806825600 -18000 1 CDT}
+    {1824966000 -21600 0 CST}
+    {1838275200 -18000 1 CDT}
+    {1856415600 -21600 0 CST}
+    {1869724800 -18000 1 CDT}
+    {1887865200 -21600 0 CST}
+    {1901779200 -18000 1 CDT}
+    {1919314800 -21600 0 CST}
+    {1933228800 -18000 1 CDT}
+    {1950764400 -21600 0 CST}
+    {1964678400 -18000 1 CDT}
+    {1982818800 -21600 0 CST}
+    {1996128000 -18000 1 CDT}
+    {2014268400 -21600 0 CST}
+    {2027577600 -18000 1 CDT}
+    {2045718000 -21600 0 CST}
+    {2059027200 -18000 1 CDT}
+    {2077167600 -21600 0 CST}
+    {2091081600 -18000 1 CDT}
+    {2108617200 -21600 0 CST}
+    {2122531200 -18000 1 CDT}
+    {2140066800 -21600 0 CST}
+    {2153980800 -18000 1 CDT}
+    {2172121200 -21600 0 CST}
+    {2185430400 -18000 1 CDT}
+    {2203570800 -21600 0 CST}
+    {2216880000 -18000 1 CDT}
+    {2235020400 -21600 0 CST}
+    {2248934400 -18000 1 CDT}
+    {2266470000 -21600 0 CST}
+    {2280384000 -18000 1 CDT}
+    {2297919600 -21600 0 CST}
+    {2311833600 -18000 1 CDT}
+    {2329369200 -21600 0 CST}
+    {2343283200 -18000 1 CDT}
+    {2361423600 -21600 0 CST}
+    {2374732800 -18000 1 CDT}
+    {2392873200 -21600 0 CST}
+    {2406182400 -18000 1 CDT}
+    {2424322800 -21600 0 CST}
+    {2438236800 -18000 1 CDT}
+    {2455772400 -21600 0 CST}
+    {2469686400 -18000 1 CDT}
+    {2487222000 -21600 0 CST}
+    {2501136000 -18000 1 CDT}
+    {2519276400 -21600 0 CST}
+    {2532585600 -18000 1 CDT}
+    {2550726000 -21600 0 CST}
+    {2564035200 -18000 1 CDT}
+    {2582175600 -21600 0 CST}
+    {2596089600 -18000 1 CDT}
+    {2613625200 -21600 0 CST}
+    {2627539200 -18000 1 CDT}
+    {2645074800 -21600 0 CST}
+    {2658988800 -18000 1 CDT}
+    {2676524400 -21600 0 CST}
+    {2690438400 -18000 1 CDT}
+    {2708578800 -21600 0 CST}
+    {2721888000 -18000 1 CDT}
+    {2740028400 -21600 0 CST}
+    {2753337600 -18000 1 CDT}
+    {2771478000 -21600 0 CST}
+    {2785392000 -18000 1 CDT}
+    {2802927600 -21600 0 CST}
+    {2816841600 -18000 1 CDT}
+    {2834377200 -21600 0 CST}
+    {2848291200 -18000 1 CDT}
+    {2866431600 -21600 0 CST}
+    {2879740800 -18000 1 CDT}
+    {2897881200 -21600 0 CST}
+    {2911190400 -18000 1 CDT}
+    {2929330800 -21600 0 CST}
+    {2942640000 -18000 1 CDT}
+    {2960780400 -21600 0 CST}
+    {2974694400 -18000 1 CDT}
+    {2992230000 -21600 0 CST}
+    {3006144000 -18000 1 CDT}
+    {3023679600 -21600 0 CST}
+    {3037593600 -18000 1 CDT}
+    {3055734000 -21600 0 CST}
+    {3069043200 -18000 1 CDT}
+    {3087183600 -21600 0 CST}
+    {3100492800 -18000 1 CDT}
+    {3118633200 -21600 0 CST}
+    {3132547200 -18000 1 CDT}
+    {3150082800 -21600 0 CST}
+    {3163996800 -18000 1 CDT}
+    {3181532400 -21600 0 CST}
+    {3195446400 -18000 1 CDT}
+    {3212982000 -21600 0 CST}
+    {3226896000 -18000 1 CDT}
+    {3245036400 -21600 0 CST}
+    {3258345600 -18000 1 CDT}
+    {3276486000 -21600 0 CST}
+    {3289795200 -18000 1 CDT}
+    {3307935600 -21600 0 CST}
+    {3321849600 -18000 1 CDT}
+    {3339385200 -21600 0 CST}
+    {3353299200 -18000 1 CDT}
+    {3370834800 -21600 0 CST}
+    {3384748800 -18000 1 CDT}
+    {3402889200 -21600 0 CST}
+    {3416198400 -18000 1 CDT}
+    {3434338800 -21600 0 CST}
+    {3447648000 -18000 1 CDT}
+    {3465788400 -21600 0 CST}
+    {3479702400 -18000 1 CDT}
+    {3497238000 -21600 0 CST}
+    {3511152000 -18000 1 CDT}
+    {3528687600 -21600 0 CST}
+    {3542601600 -18000 1 CDT}
+    {3560137200 -21600 0 CST}
+    {3574051200 -18000 1 CDT}
+    {3592191600 -21600 0 CST}
+    {3605500800 -18000 1 CDT}
+    {3623641200 -21600 0 CST}
+    {3636950400 -18000 1 CDT}
+    {3655090800 -21600 0 CST}
+    {3669004800 -18000 1 CDT}
+    {3686540400 -21600 0 CST}
+    {3700454400 -18000 1 CDT}
+    {3717990000 -21600 0 CST}
+    {3731904000 -18000 1 CDT}
+    {3750044400 -21600 0 CST}
+    {3763353600 -18000 1 CDT}
+    {3781494000 -21600 0 CST}
+    {3794803200 -18000 1 CDT}
+    {3812943600 -21600 0 CST}
+    {3826252800 -18000 1 CDT}
+    {3844393200 -21600 0 CST}
+    {3858307200 -18000 1 CDT}
+    {3875842800 -21600 0 CST}
+    {3889756800 -18000 1 CDT}
+    {3907292400 -21600 0 CST}
+    {3921206400 -18000 1 CDT}
+    {3939346800 -21600 0 CST}
+    {3952656000 -18000 1 CDT}
+    {3970796400 -21600 0 CST}
+    {3984105600 -18000 1 CDT}
+    {4002246000 -21600 0 CST}
+    {4016160000 -18000 1 CDT}
+    {4033695600 -21600 0 CST}
+    {4047609600 -18000 1 CDT}
+    {4065145200 -21600 0 CST}
+    {4079059200 -18000 1 CDT}
+    {4096594800 -21600 0 CST}
+}
diff --git a/library/tzdata/America/Metlakatla b/library/tzdata/America/Metlakatla
new file mode 100644
index 0000000..407948d
--- /dev/null
+++ b/library/tzdata/America/Metlakatla
@@ -0,0 +1,212 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Metlakatla) {
+    {-9223372036854775808 54822 0 LMT}
+    {-3225366822 -31578 0 LMT}
+    {-2188955622 -28800 0 PST}
+    {-883584000 -28800 0 PST}
+    {-880207200 -25200 1 PWT}
+    {-769395600 -25200 1 PPT}
+    {-765385200 -28800 0 PST}
+    {-757353600 -28800 0 PST}
+    {-31507200 -28800 0 PST}
+    {-21477600 -25200 1 PDT}
+    {-5756400 -28800 0 PST}
+    {9972000 -25200 1 PDT}
+    {25693200 -28800 0 PST}
+    {41421600 -25200 1 PDT}
+    {57747600 -28800 0 PST}
+    {73476000 -25200 1 PDT}
+    {89197200 -28800 0 PST}
+    {104925600 -25200 1 PDT}
+    {120646800 -28800 0 PST}
+    {126698400 -25200 1 PDT}
+    {152096400 -28800 0 PST}
+    {162381600 -25200 1 PDT}
+    {183546000 -28800 0 PST}
+    {199274400 -25200 1 PDT}
+    {215600400 -28800 0 PST}
+    {230724000 -25200 1 PDT}
+    {247050000 -28800 0 PST}
+    {262778400 -25200 1 PDT}
+    {278499600 -28800 0 PST}
+    {294228000 -25200 1 PDT}
+    {309949200 -28800 0 PST}
+    {325677600 -25200 1 PDT}
+    {341398800 -28800 0 PST}
+    {357127200 -25200 1 PDT}
+    {372848400 -28800 0 PST}
+    {388576800 -25200 1 PDT}
+    {404902800 -28800 0 PST}
+    {420026400 -25200 1 PDT}
+    {436356000 -28800 0 PST}
+    {1446372000 -32400 0 AKST}
+    {1457866800 -28800 1 AKDT}
+    {1478426400 -32400 0 AKST}
+    {1489316400 -28800 1 AKDT}
+    {1509876000 -32400 0 AKST}
+    {1520766000 -28800 1 AKDT}
+    {1541325600 -32400 0 AKST}
+    {1552215600 -28800 1 AKDT}
+    {1572775200 -32400 0 AKST}
+    {1583665200 -28800 1 AKDT}
+    {1604224800 -32400 0 AKST}
+    {1615719600 -28800 1 AKDT}
+    {1636279200 -32400 0 AKST}
+    {1647169200 -28800 1 AKDT}
+    {1667728800 -32400 0 AKST}
+    {1678618800 -28800 1 AKDT}
+    {1699178400 -32400 0 AKST}
+    {1710068400 -28800 1 AKDT}
+    {1730628000 -32400 0 AKST}
+    {1741518000 -28800 1 AKDT}
+    {1762077600 -32400 0 AKST}
+    {1772967600 -28800 1 AKDT}
+    {1793527200 -32400 0 AKST}
+    {1805022000 -28800 1 AKDT}
+    {1825581600 -32400 0 AKST}
+    {1836471600 -28800 1 AKDT}
+    {1857031200 -32400 0 AKST}
+    {1867921200 -28800 1 AKDT}
+    {1888480800 -32400 0 AKST}
+    {1899370800 -28800 1 AKDT}
+    {1919930400 -32400 0 AKST}
+    {1930820400 -28800 1 AKDT}
+    {1951380000 -32400 0 AKST}
+    {1962874800 -28800 1 AKDT}
+    {1983434400 -32400 0 AKST}
+    {1994324400 -28800 1 AKDT}
+    {2014884000 -32400 0 AKST}
+    {2025774000 -28800 1 AKDT}
+    {2046333600 -32400 0 AKST}
+    {2057223600 -28800 1 AKDT}
+    {2077783200 -32400 0 AKST}
+    {2088673200 -28800 1 AKDT}
+    {2109232800 -32400 0 AKST}
+    {2120122800 -28800 1 AKDT}
+    {2140682400 -32400 0 AKST}
+    {2152177200 -28800 1 AKDT}
+    {2172736800 -32400 0 AKST}
+    {2183626800 -28800 1 AKDT}
+    {2204186400 -32400 0 AKST}
+    {2215076400 -28800 1 AKDT}
+    {2235636000 -32400 0 AKST}
+    {2246526000 -28800 1 AKDT}
+    {2267085600 -32400 0 AKST}
+    {2277975600 -28800 1 AKDT}
+    {2298535200 -32400 0 AKST}
+    {2309425200 -28800 1 AKDT}
+    {2329984800 -32400 0 AKST}
+    {2341479600 -28800 1 AKDT}
+    {2362039200 -32400 0 AKST}
+    {2372929200 -28800 1 AKDT}
+    {2393488800 -32400 0 AKST}
+    {2404378800 -28800 1 AKDT}
+    {2424938400 -32400 0 AKST}
+    {2435828400 -28800 1 AKDT}
+    {2456388000 -32400 0 AKST}
+    {2467278000 -28800 1 AKDT}
+    {2487837600 -32400 0 AKST}
+    {2499332400 -28800 1 AKDT}
+    {2519892000 -32400 0 AKST}
+    {2530782000 -28800 1 AKDT}
+    {2551341600 -32400 0 AKST}
+    {2562231600 -28800 1 AKDT}
+    {2582791200 -32400 0 AKST}
+    {2593681200 -28800 1 AKDT}
+    {2614240800 -32400 0 AKST}
+    {2625130800 -28800 1 AKDT}
+    {2645690400 -32400 0 AKST}
+    {2656580400 -28800 1 AKDT}
+    {2677140000 -32400 0 AKST}
+    {2688634800 -28800 1 AKDT}
+    {2709194400 -32400 0 AKST}
+    {2720084400 -28800 1 AKDT}
+    {2740644000 -32400 0 AKST}
+    {2751534000 -28800 1 AKDT}
+    {2772093600 -32400 0 AKST}
+    {2782983600 -28800 1 AKDT}
+    {2803543200 -32400 0 AKST}
+    {2814433200 -28800 1 AKDT}
+    {2834992800 -32400 0 AKST}
+    {2846487600 -28800 1 AKDT}
+    {2867047200 -32400 0 AKST}
+    {2877937200 -28800 1 AKDT}
+    {2898496800 -32400 0 AKST}
+    {2909386800 -28800 1 AKDT}
+    {2929946400 -32400 0 AKST}
+    {2940836400 -28800 1 AKDT}
+    {2961396000 -32400 0 AKST}
+    {2972286000 -28800 1 AKDT}
+    {2992845600 -32400 0 AKST}
+    {3003735600 -28800 1 AKDT}
+    {3024295200 -32400 0 AKST}
+    {3035790000 -28800 1 AKDT}
+    {3056349600 -32400 0 AKST}
+    {3067239600 -28800 1 AKDT}
+    {3087799200 -32400 0 AKST}
+    {3098689200 -28800 1 AKDT}
+    {3119248800 -32400 0 AKST}
+    {3130138800 -28800 1 AKDT}
+    {3150698400 -32400 0 AKST}
+    {3161588400 -28800 1 AKDT}
+    {3182148000 -32400 0 AKST}
+    {3193038000 -28800 1 AKDT}
+    {3213597600 -32400 0 AKST}
+    {3225092400 -28800 1 AKDT}
+    {3245652000 -32400 0 AKST}
+    {3256542000 -28800 1 AKDT}
+    {3277101600 -32400 0 AKST}
+    {3287991600 -28800 1 AKDT}
+    {3308551200 -32400 0 AKST}
+    {3319441200 -28800 1 AKDT}
+    {3340000800 -32400 0 AKST}
+    {3350890800 -28800 1 AKDT}
+    {3371450400 -32400 0 AKST}
+    {3382945200 -28800 1 AKDT}
+    {3403504800 -32400 0 AKST}
+    {3414394800 -28800 1 AKDT}
+    {3434954400 -32400 0 AKST}
+    {3445844400 -28800 1 AKDT}
+    {3466404000 -32400 0 AKST}
+    {3477294000 -28800 1 AKDT}
+    {3497853600 -32400 0 AKST}
+    {3508743600 -28800 1 AKDT}
+    {3529303200 -32400 0 AKST}
+    {3540193200 -28800 1 AKDT}
+    {3560752800 -32400 0 AKST}
+    {3572247600 -28800 1 AKDT}
+    {3592807200 -32400 0 AKST}
+    {3603697200 -28800 1 AKDT}
+    {3624256800 -32400 0 AKST}
+    {3635146800 -28800 1 AKDT}
+    {3655706400 -32400 0 AKST}
+    {3666596400 -28800 1 AKDT}
+    {3687156000 -32400 0 AKST}
+    {3698046000 -28800 1 AKDT}
+    {3718605600 -32400 0 AKST}
+    {3730100400 -28800 1 AKDT}
+    {3750660000 -32400 0 AKST}
+    {3761550000 -28800 1 AKDT}
+    {3782109600 -32400 0 AKST}
+    {3792999600 -28800 1 AKDT}
+    {3813559200 -32400 0 AKST}
+    {3824449200 -28800 1 AKDT}
+    {3845008800 -32400 0 AKST}
+    {3855898800 -28800 1 AKDT}
+    {3876458400 -32400 0 AKST}
+    {3887348400 -28800 1 AKDT}
+    {3907908000 -32400 0 AKST}
+    {3919402800 -28800 1 AKDT}
+    {3939962400 -32400 0 AKST}
+    {3950852400 -28800 1 AKDT}
+    {3971412000 -32400 0 AKST}
+    {3982302000 -28800 1 AKDT}
+    {4002861600 -32400 0 AKST}
+    {4013751600 -28800 1 AKDT}
+    {4034311200 -32400 0 AKST}
+    {4045201200 -28800 1 AKDT}
+    {4065760800 -32400 0 AKST}
+    {4076650800 -28800 1 AKDT}
+    {4097210400 -32400 0 AKST}
+}
diff --git a/library/tzdata/America/Mexico_City b/library/tzdata/America/Mexico_City
new file mode 100644
index 0000000..48462e4
--- /dev/null
+++ b/library/tzdata/America/Mexico_City
@@ -0,0 +1,228 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Mexico_City) {
+    {-9223372036854775808 -23796 0 LMT}
+    {-1514739600 -25200 0 MST}
+    {-1343066400 -21600 0 CST}
+    {-1234807200 -25200 0 MST}
+    {-1220292000 -21600 0 CST}
+    {-1207159200 -25200 0 MST}
+    {-1191344400 -21600 0 CST}
+    {-975261600 -18000 1 CDT}
+    {-963169200 -21600 0 CST}
+    {-917114400 -18000 1 CDT}
+    {-907354800 -21600 0 CST}
+    {-821901600 -18000 1 CWT}
+    {-810068400 -21600 0 CST}
+    {-627501600 -18000 1 CDT}
+    {-612990000 -21600 0 CST}
+    {828864000 -18000 1 CDT}
+    {846399600 -21600 0 CST}
+    {860313600 -18000 1 CDT}
+    {877849200 -21600 0 CST}
+    {891763200 -18000 1 CDT}
+    {909298800 -21600 0 CST}
+    {923212800 -18000 1 CDT}
+    {941353200 -21600 0 CST}
+    {954662400 -18000 1 CDT}
+    {972802800 -21600 0 CST}
+    {989136000 -18000 1 CDT}
+    {1001836800 -21600 0 CST}
+    {1014184800 -21600 0 CST}
+    {1018166400 -18000 1 CDT}
+    {1035702000 -21600 0 CST}
+    {1049616000 -18000 1 CDT}
+    {1067151600 -21600 0 CST}
+    {1081065600 -18000 1 CDT}
+    {1099206000 -21600 0 CST}
+    {1112515200 -18000 1 CDT}
+    {1130655600 -21600 0 CST}
+    {1143964800 -18000 1 CDT}
+    {1162105200 -21600 0 CST}
+    {1175414400 -18000 1 CDT}
+    {1193554800 -21600 0 CST}
+    {1207468800 -18000 1 CDT}
+    {1225004400 -21600 0 CST}
+    {1238918400 -18000 1 CDT}
+    {1256454000 -21600 0 CST}
+    {1270368000 -18000 1 CDT}
+    {1288508400 -21600 0 CST}
+    {1301817600 -18000 1 CDT}
+    {1319958000 -21600 0 CST}
+    {1333267200 -18000 1 CDT}
+    {1351407600 -21600 0 CST}
+    {1365321600 -18000 1 CDT}
+    {1382857200 -21600 0 CST}
+    {1396771200 -18000 1 CDT}
+    {1414306800 -21600 0 CST}
+    {1428220800 -18000 1 CDT}
+    {1445756400 -21600 0 CST}
+    {1459670400 -18000 1 CDT}
+    {1477810800 -21600 0 CST}
+    {1491120000 -18000 1 CDT}
+    {1509260400 -21600 0 CST}
+    {1522569600 -18000 1 CDT}
+    {1540710000 -21600 0 CST}
+    {1554624000 -18000 1 CDT}
+    {1572159600 -21600 0 CST}
+    {1586073600 -18000 1 CDT}
+    {1603609200 -21600 0 CST}
+    {1617523200 -18000 1 CDT}
+    {1635663600 -21600 0 CST}
+    {1648972800 -18000 1 CDT}
+    {1667113200 -21600 0 CST}
+    {1680422400 -18000 1 CDT}
+    {1698562800 -21600 0 CST}
+    {1712476800 -18000 1 CDT}
+    {1730012400 -21600 0 CST}
+    {1743926400 -18000 1 CDT}
+    {1761462000 -21600 0 CST}
+    {1775376000 -18000 1 CDT}
+    {1792911600 -21600 0 CST}
+    {1806825600 -18000 1 CDT}
+    {1824966000 -21600 0 CST}
+    {1838275200 -18000 1 CDT}
+    {1856415600 -21600 0 CST}
+    {1869724800 -18000 1 CDT}
+    {1887865200 -21600 0 CST}
+    {1901779200 -18000 1 CDT}
+    {1919314800 -21600 0 CST}
+    {1933228800 -18000 1 CDT}
+    {1950764400 -21600 0 CST}
+    {1964678400 -18000 1 CDT}
+    {1982818800 -21600 0 CST}
+    {1996128000 -18000 1 CDT}
+    {2014268400 -21600 0 CST}
+    {2027577600 -18000 1 CDT}
+    {2045718000 -21600 0 CST}
+    {2059027200 -18000 1 CDT}
+    {2077167600 -21600 0 CST}
+    {2091081600 -18000 1 CDT}
+    {2108617200 -21600 0 CST}
+    {2122531200 -18000 1 CDT}
+    {2140066800 -21600 0 CST}
+    {2153980800 -18000 1 CDT}
+    {2172121200 -21600 0 CST}
+    {2185430400 -18000 1 CDT}
+    {2203570800 -21600 0 CST}
+    {2216880000 -18000 1 CDT}
+    {2235020400 -21600 0 CST}
+    {2248934400 -18000 1 CDT}
+    {2266470000 -21600 0 CST}
+    {2280384000 -18000 1 CDT}
+    {2297919600 -21600 0 CST}
+    {2311833600 -18000 1 CDT}
+    {2329369200 -21600 0 CST}
+    {2343283200 -18000 1 CDT}
+    {2361423600 -21600 0 CST}
+    {2374732800 -18000 1 CDT}
+    {2392873200 -21600 0 CST}
+    {2406182400 -18000 1 CDT}
+    {2424322800 -21600 0 CST}
+    {2438236800 -18000 1 CDT}
+    {2455772400 -21600 0 CST}
+    {2469686400 -18000 1 CDT}
+    {2487222000 -21600 0 CST}
+    {2501136000 -18000 1 CDT}
+    {2519276400 -21600 0 CST}
+    {2532585600 -18000 1 CDT}
+    {2550726000 -21600 0 CST}
+    {2564035200 -18000 1 CDT}
+    {2582175600 -21600 0 CST}
+    {2596089600 -18000 1 CDT}
+    {2613625200 -21600 0 CST}
+    {2627539200 -18000 1 CDT}
+    {2645074800 -21600 0 CST}
+    {2658988800 -18000 1 CDT}
+    {2676524400 -21600 0 CST}
+    {2690438400 -18000 1 CDT}
+    {2708578800 -21600 0 CST}
+    {2721888000 -18000 1 CDT}
+    {2740028400 -21600 0 CST}
+    {2753337600 -18000 1 CDT}
+    {2771478000 -21600 0 CST}
+    {2785392000 -18000 1 CDT}
+    {2802927600 -21600 0 CST}
+    {2816841600 -18000 1 CDT}
+    {2834377200 -21600 0 CST}
+    {2848291200 -18000 1 CDT}
+    {2866431600 -21600 0 CST}
+    {2879740800 -18000 1 CDT}
+    {2897881200 -21600 0 CST}
+    {2911190400 -18000 1 CDT}
+    {2929330800 -21600 0 CST}
+    {2942640000 -18000 1 CDT}
+    {2960780400 -21600 0 CST}
+    {2974694400 -18000 1 CDT}
+    {2992230000 -21600 0 CST}
+    {3006144000 -18000 1 CDT}
+    {3023679600 -21600 0 CST}
+    {3037593600 -18000 1 CDT}
+    {3055734000 -21600 0 CST}
+    {3069043200 -18000 1 CDT}
+    {3087183600 -21600 0 CST}
+    {3100492800 -18000 1 CDT}
+    {3118633200 -21600 0 CST}
+    {3132547200 -18000 1 CDT}
+    {3150082800 -21600 0 CST}
+    {3163996800 -18000 1 CDT}
+    {3181532400 -21600 0 CST}
+    {3195446400 -18000 1 CDT}
+    {3212982000 -21600 0 CST}
+    {3226896000 -18000 1 CDT}
+    {3245036400 -21600 0 CST}
+    {3258345600 -18000 1 CDT}
+    {3276486000 -21600 0 CST}
+    {3289795200 -18000 1 CDT}
+    {3307935600 -21600 0 CST}
+    {3321849600 -18000 1 CDT}
+    {3339385200 -21600 0 CST}
+    {3353299200 -18000 1 CDT}
+    {3370834800 -21600 0 CST}
+    {3384748800 -18000 1 CDT}
+    {3402889200 -21600 0 CST}
+    {3416198400 -18000 1 CDT}
+    {3434338800 -21600 0 CST}
+    {3447648000 -18000 1 CDT}
+    {3465788400 -21600 0 CST}
+    {3479702400 -18000 1 CDT}
+    {3497238000 -21600 0 CST}
+    {3511152000 -18000 1 CDT}
+    {3528687600 -21600 0 CST}
+    {3542601600 -18000 1 CDT}
+    {3560137200 -21600 0 CST}
+    {3574051200 -18000 1 CDT}
+    {3592191600 -21600 0 CST}
+    {3605500800 -18000 1 CDT}
+    {3623641200 -21600 0 CST}
+    {3636950400 -18000 1 CDT}
+    {3655090800 -21600 0 CST}
+    {3669004800 -18000 1 CDT}
+    {3686540400 -21600 0 CST}
+    {3700454400 -18000 1 CDT}
+    {3717990000 -21600 0 CST}
+    {3731904000 -18000 1 CDT}
+    {3750044400 -21600 0 CST}
+    {3763353600 -18000 1 CDT}
+    {3781494000 -21600 0 CST}
+    {3794803200 -18000 1 CDT}
+    {3812943600 -21600 0 CST}
+    {3826252800 -18000 1 CDT}
+    {3844393200 -21600 0 CST}
+    {3858307200 -18000 1 CDT}
+    {3875842800 -21600 0 CST}
+    {3889756800 -18000 1 CDT}
+    {3907292400 -21600 0 CST}
+    {3921206400 -18000 1 CDT}
+    {3939346800 -21600 0 CST}
+    {3952656000 -18000 1 CDT}
+    {3970796400 -21600 0 CST}
+    {3984105600 -18000 1 CDT}
+    {4002246000 -21600 0 CST}
+    {4016160000 -18000 1 CDT}
+    {4033695600 -21600 0 CST}
+    {4047609600 -18000 1 CDT}
+    {4065145200 -21600 0 CST}
+    {4079059200 -18000 1 CDT}
+    {4096594800 -21600 0 CST}
+}
diff --git a/library/tzdata/America/Miquelon b/library/tzdata/America/Miquelon
new file mode 100644
index 0000000..a7410f1
--- /dev/null
+++ b/library/tzdata/America/Miquelon
@@ -0,0 +1,234 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Miquelon) {
+    {-9223372036854775808 -13480 0 LMT}
+    {-1850328920 -14400 0 AST}
+    {326001600 -10800 0 PMST}
+    {536468400 -10800 0 PMST}
+    {544597200 -7200 1 PMDT}
+    {562132800 -10800 0 PMST}
+    {576046800 -7200 1 PMDT}
+    {594187200 -10800 0 PMST}
+    {607496400 -7200 1 PMDT}
+    {625636800 -10800 0 PMST}
+    {638946000 -7200 1 PMDT}
+    {657086400 -10800 0 PMST}
+    {671000400 -7200 1 PMDT}
+    {688536000 -10800 0 PMST}
+    {702450000 -7200 1 PMDT}
+    {719985600 -10800 0 PMST}
+    {733899600 -7200 1 PMDT}
+    {752040000 -10800 0 PMST}
+    {765349200 -7200 1 PMDT}
+    {783489600 -10800 0 PMST}
+    {796798800 -7200 1 PMDT}
+    {814939200 -10800 0 PMST}
+    {828853200 -7200 1 PMDT}
+    {846388800 -10800 0 PMST}
+    {860302800 -7200 1 PMDT}
+    {877838400 -10800 0 PMST}
+    {891752400 -7200 1 PMDT}
+    {909288000 -10800 0 PMST}
+    {923202000 -7200 1 PMDT}
+    {941342400 -10800 0 PMST}
+    {954651600 -7200 1 PMDT}
+    {972792000 -10800 0 PMST}
+    {986101200 -7200 1 PMDT}
+    {1004241600 -10800 0 PMST}
+    {1018155600 -7200 1 PMDT}
+    {1035691200 -10800 0 PMST}
+    {1049605200 -7200 1 PMDT}
+    {1067140800 -10800 0 PMST}
+    {1081054800 -7200 1 PMDT}
+    {1099195200 -10800 0 PMST}
+    {1112504400 -7200 1 PMDT}
+    {1130644800 -10800 0 PMST}
+    {1143954000 -7200 1 PMDT}
+    {1162094400 -10800 0 PMST}
+    {1173589200 -7200 1 PMDT}
+    {1194148800 -10800 0 PMST}
+    {1205038800 -7200 1 PMDT}
+    {1225598400 -10800 0 PMST}
+    {1236488400 -7200 1 PMDT}
+    {1257048000 -10800 0 PMST}
+    {1268542800 -7200 1 PMDT}
+    {1289102400 -10800 0 PMST}
+    {1299992400 -7200 1 PMDT}
+    {1320552000 -10800 0 PMST}
+    {1331442000 -7200 1 PMDT}
+    {1352001600 -10800 0 PMST}
+    {1362891600 -7200 1 PMDT}
+    {1383451200 -10800 0 PMST}
+    {1394341200 -7200 1 PMDT}
+    {1414900800 -10800 0 PMST}
+    {1425790800 -7200 1 PMDT}
+    {1446350400 -10800 0 PMST}
+    {1457845200 -7200 1 PMDT}
+    {1478404800 -10800 0 PMST}
+    {1489294800 -7200 1 PMDT}
+    {1509854400 -10800 0 PMST}
+    {1520744400 -7200 1 PMDT}
+    {1541304000 -10800 0 PMST}
+    {1552194000 -7200 1 PMDT}
+    {1572753600 -10800 0 PMST}
+    {1583643600 -7200 1 PMDT}
+    {1604203200 -10800 0 PMST}
+    {1615698000 -7200 1 PMDT}
+    {1636257600 -10800 0 PMST}
+    {1647147600 -7200 1 PMDT}
+    {1667707200 -10800 0 PMST}
+    {1678597200 -7200 1 PMDT}
+    {1699156800 -10800 0 PMST}
+    {1710046800 -7200 1 PMDT}
+    {1730606400 -10800 0 PMST}
+    {1741496400 -7200 1 PMDT}
+    {1762056000 -10800 0 PMST}
+    {1772946000 -7200 1 PMDT}
+    {1793505600 -10800 0 PMST}
+    {1805000400 -7200 1 PMDT}
+    {1825560000 -10800 0 PMST}
+    {1836450000 -7200 1 PMDT}
+    {1857009600 -10800 0 PMST}
+    {1867899600 -7200 1 PMDT}
+    {1888459200 -10800 0 PMST}
+    {1899349200 -7200 1 PMDT}
+    {1919908800 -10800 0 PMST}
+    {1930798800 -7200 1 PMDT}
+    {1951358400 -10800 0 PMST}
+    {1962853200 -7200 1 PMDT}
+    {1983412800 -10800 0 PMST}
+    {1994302800 -7200 1 PMDT}
+    {2014862400 -10800 0 PMST}
+    {2025752400 -7200 1 PMDT}
+    {2046312000 -10800 0 PMST}
+    {2057202000 -7200 1 PMDT}
+    {2077761600 -10800 0 PMST}
+    {2088651600 -7200 1 PMDT}
+    {2109211200 -10800 0 PMST}
+    {2120101200 -7200 1 PMDT}
+    {2140660800 -10800 0 PMST}
+    {2152155600 -7200 1 PMDT}
+    {2172715200 -10800 0 PMST}
+    {2183605200 -7200 1 PMDT}
+    {2204164800 -10800 0 PMST}
+    {2215054800 -7200 1 PMDT}
+    {2235614400 -10800 0 PMST}
+    {2246504400 -7200 1 PMDT}
+    {2267064000 -10800 0 PMST}
+    {2277954000 -7200 1 PMDT}
+    {2298513600 -10800 0 PMST}
+    {2309403600 -7200 1 PMDT}
+    {2329963200 -10800 0 PMST}
+    {2341458000 -7200 1 PMDT}
+    {2362017600 -10800 0 PMST}
+    {2372907600 -7200 1 PMDT}
+    {2393467200 -10800 0 PMST}
+    {2404357200 -7200 1 PMDT}
+    {2424916800 -10800 0 PMST}
+    {2435806800 -7200 1 PMDT}
+    {2456366400 -10800 0 PMST}
+    {2467256400 -7200 1 PMDT}
+    {2487816000 -10800 0 PMST}
+    {2499310800 -7200 1 PMDT}
+    {2519870400 -10800 0 PMST}
+    {2530760400 -7200 1 PMDT}
+    {2551320000 -10800 0 PMST}
+    {2562210000 -7200 1 PMDT}
+    {2582769600 -10800 0 PMST}
+    {2593659600 -7200 1 PMDT}
+    {2614219200 -10800 0 PMST}
+    {2625109200 -7200 1 PMDT}
+    {2645668800 -10800 0 PMST}
+    {2656558800 -7200 1 PMDT}
+    {2677118400 -10800 0 PMST}
+    {2688613200 -7200 1 PMDT}
+    {2709172800 -10800 0 PMST}
+    {2720062800 -7200 1 PMDT}
+    {2740622400 -10800 0 PMST}
+    {2751512400 -7200 1 PMDT}
+    {2772072000 -10800 0 PMST}
+    {2782962000 -7200 1 PMDT}
+    {2803521600 -10800 0 PMST}
+    {2814411600 -7200 1 PMDT}
+    {2834971200 -10800 0 PMST}
+    {2846466000 -7200 1 PMDT}
+    {2867025600 -10800 0 PMST}
+    {2877915600 -7200 1 PMDT}
+    {2898475200 -10800 0 PMST}
+    {2909365200 -7200 1 PMDT}
+    {2929924800 -10800 0 PMST}
+    {2940814800 -7200 1 PMDT}
+    {2961374400 -10800 0 PMST}
+    {2972264400 -7200 1 PMDT}
+    {2992824000 -10800 0 PMST}
+    {3003714000 -7200 1 PMDT}
+    {3024273600 -10800 0 PMST}
+    {3035768400 -7200 1 PMDT}
+    {3056328000 -10800 0 PMST}
+    {3067218000 -7200 1 PMDT}
+    {3087777600 -10800 0 PMST}
+    {3098667600 -7200 1 PMDT}
+    {3119227200 -10800 0 PMST}
+    {3130117200 -7200 1 PMDT}
+    {3150676800 -10800 0 PMST}
+    {3161566800 -7200 1 PMDT}
+    {3182126400 -10800 0 PMST}
+    {3193016400 -7200 1 PMDT}
+    {3213576000 -10800 0 PMST}
+    {3225070800 -7200 1 PMDT}
+    {3245630400 -10800 0 PMST}
+    {3256520400 -7200 1 PMDT}
+    {3277080000 -10800 0 PMST}
+    {3287970000 -7200 1 PMDT}
+    {3308529600 -10800 0 PMST}
+    {3319419600 -7200 1 PMDT}
+    {3339979200 -10800 0 PMST}
+    {3350869200 -7200 1 PMDT}
+    {3371428800 -10800 0 PMST}
+    {3382923600 -7200 1 PMDT}
+    {3403483200 -10800 0 PMST}
+    {3414373200 -7200 1 PMDT}
+    {3434932800 -10800 0 PMST}
+    {3445822800 -7200 1 PMDT}
+    {3466382400 -10800 0 PMST}
+    {3477272400 -7200 1 PMDT}
+    {3497832000 -10800 0 PMST}
+    {3508722000 -7200 1 PMDT}
+    {3529281600 -10800 0 PMST}
+    {3540171600 -7200 1 PMDT}
+    {3560731200 -10800 0 PMST}
+    {3572226000 -7200 1 PMDT}
+    {3592785600 -10800 0 PMST}
+    {3603675600 -7200 1 PMDT}
+    {3624235200 -10800 0 PMST}
+    {3635125200 -7200 1 PMDT}
+    {3655684800 -10800 0 PMST}
+    {3666574800 -7200 1 PMDT}
+    {3687134400 -10800 0 PMST}
+    {3698024400 -7200 1 PMDT}
+    {3718584000 -10800 0 PMST}
+    {3730078800 -7200 1 PMDT}
+    {3750638400 -10800 0 PMST}
+    {3761528400 -7200 1 PMDT}
+    {3782088000 -10800 0 PMST}
+    {3792978000 -7200 1 PMDT}
+    {3813537600 -10800 0 PMST}
+    {3824427600 -7200 1 PMDT}
+    {3844987200 -10800 0 PMST}
+    {3855877200 -7200 1 PMDT}
+    {3876436800 -10800 0 PMST}
+    {3887326800 -7200 1 PMDT}
+    {3907886400 -10800 0 PMST}
+    {3919381200 -7200 1 PMDT}
+    {3939940800 -10800 0 PMST}
+    {3950830800 -7200 1 PMDT}
+    {3971390400 -10800 0 PMST}
+    {3982280400 -7200 1 PMDT}
+    {4002840000 -10800 0 PMST}
+    {4013730000 -7200 1 PMDT}
+    {4034289600 -10800 0 PMST}
+    {4045179600 -7200 1 PMDT}
+    {4065739200 -10800 0 PMST}
+    {4076629200 -7200 1 PMDT}
+    {4097188800 -10800 0 PMST}
+}
diff --git a/library/tzdata/America/Moncton b/library/tzdata/America/Moncton
new file mode 100644
index 0000000..d286c88
--- /dev/null
+++ b/library/tzdata/America/Moncton
@@ -0,0 +1,342 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Moncton) {
+    {-9223372036854775808 -15548 0 LMT}
+    {-2715882052 -18000 0 EST}
+    {-2131642800 -14400 0 AST}
+    {-1632074400 -10800 1 ADT}
+    {-1615143600 -14400 0 AST}
+    {-1167595200 -14400 0 AST}
+    {-1153681200 -10800 1 ADT}
+    {-1145822400 -14400 0 AST}
+    {-1122231600 -10800 1 ADT}
+    {-1114372800 -14400 0 AST}
+    {-1090782000 -10800 1 ADT}
+    {-1082923200 -14400 0 AST}
+    {-1059332400 -10800 1 ADT}
+    {-1051473600 -14400 0 AST}
+    {-1027882800 -10800 1 ADT}
+    {-1020024000 -14400 0 AST}
+    {-996433200 -10800 1 ADT}
+    {-988574400 -14400 0 AST}
+    {-965674800 -10800 1 ADT}
+    {-955396800 -14400 0 AST}
+    {-934743600 -10800 1 ADT}
+    {-923947200 -14400 0 AST}
+    {-904503600 -10800 1 ADT}
+    {-891892800 -14400 0 AST}
+    {-883598400 -14400 0 AST}
+    {-880221600 -10800 1 AWT}
+    {-769395600 -10800 1 APT}
+    {-765399600 -14400 0 AST}
+    {-757368000 -14400 0 AST}
+    {-747252000 -10800 1 ADT}
+    {-733950000 -14400 0 AST}
+    {-715802400 -10800 1 ADT}
+    {-702500400 -14400 0 AST}
+    {-684352800 -10800 1 ADT}
+    {-671050800 -14400 0 AST}
+    {-652903200 -10800 1 ADT}
+    {-639601200 -14400 0 AST}
+    {-620848800 -10800 1 ADT}
+    {-608151600 -14400 0 AST}
+    {-589399200 -10800 1 ADT}
+    {-576097200 -14400 0 AST}
+    {-557949600 -10800 1 ADT}
+    {-544647600 -14400 0 AST}
+    {-526500000 -10800 1 ADT}
+    {-513198000 -14400 0 AST}
+    {-495050400 -10800 1 ADT}
+    {-481748400 -14400 0 AST}
+    {-463600800 -10800 1 ADT}
+    {-450298800 -14400 0 AST}
+    {-431546400 -10800 1 ADT}
+    {-418244400 -14400 0 AST}
+    {-400096800 -10800 1 ADT}
+    {-384375600 -14400 0 AST}
+    {-368647200 -10800 1 ADT}
+    {-352926000 -14400 0 AST}
+    {-337197600 -10800 1 ADT}
+    {-321476400 -14400 0 AST}
+    {-305748000 -10800 1 ADT}
+    {-289422000 -14400 0 AST}
+    {-273693600 -10800 1 ADT}
+    {-257972400 -14400 0 AST}
+    {-242244000 -10800 1 ADT}
+    {-226522800 -14400 0 AST}
+    {-210794400 -10800 1 ADT}
+    {-195073200 -14400 0 AST}
+    {-179344800 -10800 1 ADT}
+    {-163623600 -14400 0 AST}
+    {-147895200 -10800 1 ADT}
+    {-131569200 -14400 0 AST}
+    {-116445600 -10800 1 ADT}
+    {-100119600 -14400 0 AST}
+    {-84391200 -10800 1 ADT}
+    {-68670000 -14400 0 AST}
+    {-52941600 -10800 1 ADT}
+    {-37220400 -14400 0 AST}
+    {-21492000 -10800 1 ADT}
+    {-5770800 -14400 0 AST}
+    {9957600 -10800 1 ADT}
+    {25678800 -14400 0 AST}
+    {41407200 -10800 1 ADT}
+    {57733200 -14400 0 AST}
+    {73461600 -10800 1 ADT}
+    {89182800 -14400 0 AST}
+    {94708800 -14400 0 AST}
+    {136360800 -10800 1 ADT}
+    {152082000 -14400 0 AST}
+    {167810400 -10800 1 ADT}
+    {183531600 -14400 0 AST}
+    {199260000 -10800 1 ADT}
+    {215586000 -14400 0 AST}
+    {230709600 -10800 1 ADT}
+    {247035600 -14400 0 AST}
+    {262764000 -10800 1 ADT}
+    {278485200 -14400 0 AST}
+    {294213600 -10800 1 ADT}
+    {309934800 -14400 0 AST}
+    {325663200 -10800 1 ADT}
+    {341384400 -14400 0 AST}
+    {357112800 -10800 1 ADT}
+    {372834000 -14400 0 AST}
+    {388562400 -10800 1 ADT}
+    {404888400 -14400 0 AST}
+    {420012000 -10800 1 ADT}
+    {436338000 -14400 0 AST}
+    {452066400 -10800 1 ADT}
+    {467787600 -14400 0 AST}
+    {483516000 -10800 1 ADT}
+    {499237200 -14400 0 AST}
+    {514965600 -10800 1 ADT}
+    {530686800 -14400 0 AST}
+    {544600800 -10800 1 ADT}
+    {562136400 -14400 0 AST}
+    {576050400 -10800 1 ADT}
+    {594190800 -14400 0 AST}
+    {607500000 -10800 1 ADT}
+    {625640400 -14400 0 AST}
+    {638949600 -10800 1 ADT}
+    {657090000 -14400 0 AST}
+    {671004000 -10800 1 ADT}
+    {688539600 -14400 0 AST}
+    {702453600 -10800 1 ADT}
+    {719989200 -14400 0 AST}
+    {725860800 -14400 0 AST}
+    {733896060 -10800 1 ADT}
+    {752036460 -14400 0 AST}
+    {765345660 -10800 1 ADT}
+    {783486060 -14400 0 AST}
+    {796795260 -10800 1 ADT}
+    {814935660 -14400 0 AST}
+    {828849660 -10800 1 ADT}
+    {846385260 -14400 0 AST}
+    {860299260 -10800 1 ADT}
+    {877834860 -14400 0 AST}
+    {891748860 -10800 1 ADT}
+    {909284460 -14400 0 AST}
+    {923198460 -10800 1 ADT}
+    {941338860 -14400 0 AST}
+    {954648060 -10800 1 ADT}
+    {972788460 -14400 0 AST}
+    {986097660 -10800 1 ADT}
+    {1004238060 -14400 0 AST}
+    {1018152060 -10800 1 ADT}
+    {1035687660 -14400 0 AST}
+    {1049601660 -10800 1 ADT}
+    {1067137260 -14400 0 AST}
+    {1081051260 -10800 1 ADT}
+    {1099191660 -14400 0 AST}
+    {1112500860 -10800 1 ADT}
+    {1130641260 -14400 0 AST}
+    {1143950460 -10800 1 ADT}
+    {1162090860 -14400 0 AST}
+    {1167624000 -14400 0 AST}
+    {1173592800 -10800 1 ADT}
+    {1194152400 -14400 0 AST}
+    {1205042400 -10800 1 ADT}
+    {1225602000 -14400 0 AST}
+    {1236492000 -10800 1 ADT}
+    {1257051600 -14400 0 AST}
+    {1268546400 -10800 1 ADT}
+    {1289106000 -14400 0 AST}
+    {1299996000 -10800 1 ADT}
+    {1320555600 -14400 0 AST}
+    {1331445600 -10800 1 ADT}
+    {1352005200 -14400 0 AST}
+    {1362895200 -10800 1 ADT}
+    {1383454800 -14400 0 AST}
+    {1394344800 -10800 1 ADT}
+    {1414904400 -14400 0 AST}
+    {1425794400 -10800 1 ADT}
+    {1446354000 -14400 0 AST}
+    {1457848800 -10800 1 ADT}
+    {1478408400 -14400 0 AST}
+    {1489298400 -10800 1 ADT}
+    {1509858000 -14400 0 AST}
+    {1520748000 -10800 1 ADT}
+    {1541307600 -14400 0 AST}
+    {1552197600 -10800 1 ADT}
+    {1572757200 -14400 0 AST}
+    {1583647200 -10800 1 ADT}
+    {1604206800 -14400 0 AST}
+    {1615701600 -10800 1 ADT}
+    {1636261200 -14400 0 AST}
+    {1647151200 -10800 1 ADT}
+    {1667710800 -14400 0 AST}
+    {1678600800 -10800 1 ADT}
+    {1699160400 -14400 0 AST}
+    {1710050400 -10800 1 ADT}
+    {1730610000 -14400 0 AST}
+    {1741500000 -10800 1 ADT}
+    {1762059600 -14400 0 AST}
+    {1772949600 -10800 1 ADT}
+    {1793509200 -14400 0 AST}
+    {1805004000 -10800 1 ADT}
+    {1825563600 -14400 0 AST}
+    {1836453600 -10800 1 ADT}
+    {1857013200 -14400 0 AST}
+    {1867903200 -10800 1 ADT}
+    {1888462800 -14400 0 AST}
+    {1899352800 -10800 1 ADT}
+    {1919912400 -14400 0 AST}
+    {1930802400 -10800 1 ADT}
+    {1951362000 -14400 0 AST}
+    {1962856800 -10800 1 ADT}
+    {1983416400 -14400 0 AST}
+    {1994306400 -10800 1 ADT}
+    {2014866000 -14400 0 AST}
+    {2025756000 -10800 1 ADT}
+    {2046315600 -14400 0 AST}
+    {2057205600 -10800 1 ADT}
+    {2077765200 -14400 0 AST}
+    {2088655200 -10800 1 ADT}
+    {2109214800 -14400 0 AST}
+    {2120104800 -10800 1 ADT}
+    {2140664400 -14400 0 AST}
+    {2152159200 -10800 1 ADT}
+    {2172718800 -14400 0 AST}
+    {2183608800 -10800 1 ADT}
+    {2204168400 -14400 0 AST}
+    {2215058400 -10800 1 ADT}
+    {2235618000 -14400 0 AST}
+    {2246508000 -10800 1 ADT}
+    {2267067600 -14400 0 AST}
+    {2277957600 -10800 1 ADT}
+    {2298517200 -14400 0 AST}
+    {2309407200 -10800 1 ADT}
+    {2329966800 -14400 0 AST}
+    {2341461600 -10800 1 ADT}
+    {2362021200 -14400 0 AST}
+    {2372911200 -10800 1 ADT}
+    {2393470800 -14400 0 AST}
+    {2404360800 -10800 1 ADT}
+    {2424920400 -14400 0 AST}
+    {2435810400 -10800 1 ADT}
+    {2456370000 -14400 0 AST}
+    {2467260000 -10800 1 ADT}
+    {2487819600 -14400 0 AST}
+    {2499314400 -10800 1 ADT}
+    {2519874000 -14400 0 AST}
+    {2530764000 -10800 1 ADT}
+    {2551323600 -14400 0 AST}
+    {2562213600 -10800 1 ADT}
+    {2582773200 -14400 0 AST}
+    {2593663200 -10800 1 ADT}
+    {2614222800 -14400 0 AST}
+    {2625112800 -10800 1 ADT}
+    {2645672400 -14400 0 AST}
+    {2656562400 -10800 1 ADT}
+    {2677122000 -14400 0 AST}
+    {2688616800 -10800 1 ADT}
+    {2709176400 -14400 0 AST}
+    {2720066400 -10800 1 ADT}
+    {2740626000 -14400 0 AST}
+    {2751516000 -10800 1 ADT}
+    {2772075600 -14400 0 AST}
+    {2782965600 -10800 1 ADT}
+    {2803525200 -14400 0 AST}
+    {2814415200 -10800 1 ADT}
+    {2834974800 -14400 0 AST}
+    {2846469600 -10800 1 ADT}
+    {2867029200 -14400 0 AST}
+    {2877919200 -10800 1 ADT}
+    {2898478800 -14400 0 AST}
+    {2909368800 -10800 1 ADT}
+    {2929928400 -14400 0 AST}
+    {2940818400 -10800 1 ADT}
+    {2961378000 -14400 0 AST}
+    {2972268000 -10800 1 ADT}
+    {2992827600 -14400 0 AST}
+    {3003717600 -10800 1 ADT}
+    {3024277200 -14400 0 AST}
+    {3035772000 -10800 1 ADT}
+    {3056331600 -14400 0 AST}
+    {3067221600 -10800 1 ADT}
+    {3087781200 -14400 0 AST}
+    {3098671200 -10800 1 ADT}
+    {3119230800 -14400 0 AST}
+    {3130120800 -10800 1 ADT}
+    {3150680400 -14400 0 AST}
+    {3161570400 -10800 1 ADT}
+    {3182130000 -14400 0 AST}
+    {3193020000 -10800 1 ADT}
+    {3213579600 -14400 0 AST}
+    {3225074400 -10800 1 ADT}
+    {3245634000 -14400 0 AST}
+    {3256524000 -10800 1 ADT}
+    {3277083600 -14400 0 AST}
+    {3287973600 -10800 1 ADT}
+    {3308533200 -14400 0 AST}
+    {3319423200 -10800 1 ADT}
+    {3339982800 -14400 0 AST}
+    {3350872800 -10800 1 ADT}
+    {3371432400 -14400 0 AST}
+    {3382927200 -10800 1 ADT}
+    {3403486800 -14400 0 AST}
+    {3414376800 -10800 1 ADT}
+    {3434936400 -14400 0 AST}
+    {3445826400 -10800 1 ADT}
+    {3466386000 -14400 0 AST}
+    {3477276000 -10800 1 ADT}
+    {3497835600 -14400 0 AST}
+    {3508725600 -10800 1 ADT}
+    {3529285200 -14400 0 AST}
+    {3540175200 -10800 1 ADT}
+    {3560734800 -14400 0 AST}
+    {3572229600 -10800 1 ADT}
+    {3592789200 -14400 0 AST}
+    {3603679200 -10800 1 ADT}
+    {3624238800 -14400 0 AST}
+    {3635128800 -10800 1 ADT}
+    {3655688400 -14400 0 AST}
+    {3666578400 -10800 1 ADT}
+    {3687138000 -14400 0 AST}
+    {3698028000 -10800 1 ADT}
+    {3718587600 -14400 0 AST}
+    {3730082400 -10800 1 ADT}
+    {3750642000 -14400 0 AST}
+    {3761532000 -10800 1 ADT}
+    {3782091600 -14400 0 AST}
+    {3792981600 -10800 1 ADT}
+    {3813541200 -14400 0 AST}
+    {3824431200 -10800 1 ADT}
+    {3844990800 -14400 0 AST}
+    {3855880800 -10800 1 ADT}
+    {3876440400 -14400 0 AST}
+    {3887330400 -10800 1 ADT}
+    {3907890000 -14400 0 AST}
+    {3919384800 -10800 1 ADT}
+    {3939944400 -14400 0 AST}
+    {3950834400 -10800 1 ADT}
+    {3971394000 -14400 0 AST}
+    {3982284000 -10800 1 ADT}
+    {4002843600 -14400 0 AST}
+    {4013733600 -10800 1 ADT}
+    {4034293200 -14400 0 AST}
+    {4045183200 -10800 1 ADT}
+    {4065742800 -14400 0 AST}
+    {4076632800 -10800 1 ADT}
+    {4097192400 -14400 0 AST}
+}
diff --git a/library/tzdata/America/Monterrey b/library/tzdata/America/Monterrey
new file mode 100644
index 0000000..4135884
--- /dev/null
+++ b/library/tzdata/America/Monterrey
@@ -0,0 +1,218 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Monterrey) {
+    {-9223372036854775808 -24076 0 LMT}
+    {-1514743200 -21600 0 CST}
+    {568015200 -21600 0 CST}
+    {576057600 -18000 1 CDT}
+    {594198000 -21600 0 CST}
+    {599637600 -21600 0 CST}
+    {828864000 -18000 1 CDT}
+    {846399600 -21600 0 CST}
+    {860313600 -18000 1 CDT}
+    {877849200 -21600 0 CST}
+    {891763200 -18000 1 CDT}
+    {909298800 -21600 0 CST}
+    {923212800 -18000 1 CDT}
+    {941353200 -21600 0 CST}
+    {954662400 -18000 1 CDT}
+    {972802800 -21600 0 CST}
+    {989136000 -18000 1 CDT}
+    {1001833200 -21600 0 CST}
+    {1018166400 -18000 1 CDT}
+    {1035702000 -21600 0 CST}
+    {1049616000 -18000 1 CDT}
+    {1067151600 -21600 0 CST}
+    {1081065600 -18000 1 CDT}
+    {1099206000 -21600 0 CST}
+    {1112515200 -18000 1 CDT}
+    {1130655600 -21600 0 CST}
+    {1143964800 -18000 1 CDT}
+    {1162105200 -21600 0 CST}
+    {1175414400 -18000 1 CDT}
+    {1193554800 -21600 0 CST}
+    {1207468800 -18000 1 CDT}
+    {1225004400 -21600 0 CST}
+    {1238918400 -18000 1 CDT}
+    {1256454000 -21600 0 CST}
+    {1270368000 -18000 1 CDT}
+    {1288508400 -21600 0 CST}
+    {1301817600 -18000 1 CDT}
+    {1319958000 -21600 0 CST}
+    {1333267200 -18000 1 CDT}
+    {1351407600 -21600 0 CST}
+    {1365321600 -18000 1 CDT}
+    {1382857200 -21600 0 CST}
+    {1396771200 -18000 1 CDT}
+    {1414306800 -21600 0 CST}
+    {1428220800 -18000 1 CDT}
+    {1445756400 -21600 0 CST}
+    {1459670400 -18000 1 CDT}
+    {1477810800 -21600 0 CST}
+    {1491120000 -18000 1 CDT}
+    {1509260400 -21600 0 CST}
+    {1522569600 -18000 1 CDT}
+    {1540710000 -21600 0 CST}
+    {1554624000 -18000 1 CDT}
+    {1572159600 -21600 0 CST}
+    {1586073600 -18000 1 CDT}
+    {1603609200 -21600 0 CST}
+    {1617523200 -18000 1 CDT}
+    {1635663600 -21600 0 CST}
+    {1648972800 -18000 1 CDT}
+    {1667113200 -21600 0 CST}
+    {1680422400 -18000 1 CDT}
+    {1698562800 -21600 0 CST}
+    {1712476800 -18000 1 CDT}
+    {1730012400 -21600 0 CST}
+    {1743926400 -18000 1 CDT}
+    {1761462000 -21600 0 CST}
+    {1775376000 -18000 1 CDT}
+    {1792911600 -21600 0 CST}
+    {1806825600 -18000 1 CDT}
+    {1824966000 -21600 0 CST}
+    {1838275200 -18000 1 CDT}
+    {1856415600 -21600 0 CST}
+    {1869724800 -18000 1 CDT}
+    {1887865200 -21600 0 CST}
+    {1901779200 -18000 1 CDT}
+    {1919314800 -21600 0 CST}
+    {1933228800 -18000 1 CDT}
+    {1950764400 -21600 0 CST}
+    {1964678400 -18000 1 CDT}
+    {1982818800 -21600 0 CST}
+    {1996128000 -18000 1 CDT}
+    {2014268400 -21600 0 CST}
+    {2027577600 -18000 1 CDT}
+    {2045718000 -21600 0 CST}
+    {2059027200 -18000 1 CDT}
+    {2077167600 -21600 0 CST}
+    {2091081600 -18000 1 CDT}
+    {2108617200 -21600 0 CST}
+    {2122531200 -18000 1 CDT}
+    {2140066800 -21600 0 CST}
+    {2153980800 -18000 1 CDT}
+    {2172121200 -21600 0 CST}
+    {2185430400 -18000 1 CDT}
+    {2203570800 -21600 0 CST}
+    {2216880000 -18000 1 CDT}
+    {2235020400 -21600 0 CST}
+    {2248934400 -18000 1 CDT}
+    {2266470000 -21600 0 CST}
+    {2280384000 -18000 1 CDT}
+    {2297919600 -21600 0 CST}
+    {2311833600 -18000 1 CDT}
+    {2329369200 -21600 0 CST}
+    {2343283200 -18000 1 CDT}
+    {2361423600 -21600 0 CST}
+    {2374732800 -18000 1 CDT}
+    {2392873200 -21600 0 CST}
+    {2406182400 -18000 1 CDT}
+    {2424322800 -21600 0 CST}
+    {2438236800 -18000 1 CDT}
+    {2455772400 -21600 0 CST}
+    {2469686400 -18000 1 CDT}
+    {2487222000 -21600 0 CST}
+    {2501136000 -18000 1 CDT}
+    {2519276400 -21600 0 CST}
+    {2532585600 -18000 1 CDT}
+    {2550726000 -21600 0 CST}
+    {2564035200 -18000 1 CDT}
+    {2582175600 -21600 0 CST}
+    {2596089600 -18000 1 CDT}
+    {2613625200 -21600 0 CST}
+    {2627539200 -18000 1 CDT}
+    {2645074800 -21600 0 CST}
+    {2658988800 -18000 1 CDT}
+    {2676524400 -21600 0 CST}
+    {2690438400 -18000 1 CDT}
+    {2708578800 -21600 0 CST}
+    {2721888000 -18000 1 CDT}
+    {2740028400 -21600 0 CST}
+    {2753337600 -18000 1 CDT}
+    {2771478000 -21600 0 CST}
+    {2785392000 -18000 1 CDT}
+    {2802927600 -21600 0 CST}
+    {2816841600 -18000 1 CDT}
+    {2834377200 -21600 0 CST}
+    {2848291200 -18000 1 CDT}
+    {2866431600 -21600 0 CST}
+    {2879740800 -18000 1 CDT}
+    {2897881200 -21600 0 CST}
+    {2911190400 -18000 1 CDT}
+    {2929330800 -21600 0 CST}
+    {2942640000 -18000 1 CDT}
+    {2960780400 -21600 0 CST}
+    {2974694400 -18000 1 CDT}
+    {2992230000 -21600 0 CST}
+    {3006144000 -18000 1 CDT}
+    {3023679600 -21600 0 CST}
+    {3037593600 -18000 1 CDT}
+    {3055734000 -21600 0 CST}
+    {3069043200 -18000 1 CDT}
+    {3087183600 -21600 0 CST}
+    {3100492800 -18000 1 CDT}
+    {3118633200 -21600 0 CST}
+    {3132547200 -18000 1 CDT}
+    {3150082800 -21600 0 CST}
+    {3163996800 -18000 1 CDT}
+    {3181532400 -21600 0 CST}
+    {3195446400 -18000 1 CDT}
+    {3212982000 -21600 0 CST}
+    {3226896000 -18000 1 CDT}
+    {3245036400 -21600 0 CST}
+    {3258345600 -18000 1 CDT}
+    {3276486000 -21600 0 CST}
+    {3289795200 -18000 1 CDT}
+    {3307935600 -21600 0 CST}
+    {3321849600 -18000 1 CDT}
+    {3339385200 -21600 0 CST}
+    {3353299200 -18000 1 CDT}
+    {3370834800 -21600 0 CST}
+    {3384748800 -18000 1 CDT}
+    {3402889200 -21600 0 CST}
+    {3416198400 -18000 1 CDT}
+    {3434338800 -21600 0 CST}
+    {3447648000 -18000 1 CDT}
+    {3465788400 -21600 0 CST}
+    {3479702400 -18000 1 CDT}
+    {3497238000 -21600 0 CST}
+    {3511152000 -18000 1 CDT}
+    {3528687600 -21600 0 CST}
+    {3542601600 -18000 1 CDT}
+    {3560137200 -21600 0 CST}
+    {3574051200 -18000 1 CDT}
+    {3592191600 -21600 0 CST}
+    {3605500800 -18000 1 CDT}
+    {3623641200 -21600 0 CST}
+    {3636950400 -18000 1 CDT}
+    {3655090800 -21600 0 CST}
+    {3669004800 -18000 1 CDT}
+    {3686540400 -21600 0 CST}
+    {3700454400 -18000 1 CDT}
+    {3717990000 -21600 0 CST}
+    {3731904000 -18000 1 CDT}
+    {3750044400 -21600 0 CST}
+    {3763353600 -18000 1 CDT}
+    {3781494000 -21600 0 CST}
+    {3794803200 -18000 1 CDT}
+    {3812943600 -21600 0 CST}
+    {3826252800 -18000 1 CDT}
+    {3844393200 -21600 0 CST}
+    {3858307200 -18000 1 CDT}
+    {3875842800 -21600 0 CST}
+    {3889756800 -18000 1 CDT}
+    {3907292400 -21600 0 CST}
+    {3921206400 -18000 1 CDT}
+    {3939346800 -21600 0 CST}
+    {3952656000 -18000 1 CDT}
+    {3970796400 -21600 0 CST}
+    {3984105600 -18000 1 CDT}
+    {4002246000 -21600 0 CST}
+    {4016160000 -18000 1 CDT}
+    {4033695600 -21600 0 CST}
+    {4047609600 -18000 1 CDT}
+    {4065145200 -21600 0 CST}
+    {4079059200 -18000 1 CDT}
+    {4096594800 -21600 0 CST}
+}
diff --git a/library/tzdata/America/Montevideo b/library/tzdata/America/Montevideo
new file mode 100644
index 0000000..91a5117
--- /dev/null
+++ b/library/tzdata/America/Montevideo
@@ -0,0 +1,92 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Montevideo) {
+    {-9223372036854775808 -13484 0 LMT}
+    {-2256668116 -13484 0 MMT}
+    {-1567455316 -12600 0 UYT}
+    {-1459542600 -10800 1 UYHST}
+    {-1443819600 -12600 0 UYT}
+    {-1428006600 -10800 1 UYHST}
+    {-1412283600 -12600 0 UYT}
+    {-1396470600 -10800 1 UYHST}
+    {-1380747600 -12600 0 UYT}
+    {-1141590600 -10800 1 UYHST}
+    {-1128286800 -12600 0 UYT}
+    {-1110141000 -10800 1 UYHST}
+    {-1096837200 -12600 0 UYT}
+    {-1078691400 -10800 1 UYHST}
+    {-1065387600 -12600 0 UYT}
+    {-1046637000 -10800 1 UYHST}
+    {-1033938000 -12600 0 UYT}
+    {-1015187400 -10800 1 UYHST}
+    {-1002488400 -12600 0 UYT}
+    {-983737800 -10800 1 UYHST}
+    {-971038800 -12600 0 UYT}
+    {-952288200 -10800 1 UYHST}
+    {-938984400 -12600 0 UYT}
+    {-920838600 -10800 1 UYHST}
+    {-907534800 -12600 0 UYT}
+    {-896819400 -10800 1 UYHST}
+    {-853623000 -10800 0 UYT}
+    {-853621200 -7200 1 UYST}
+    {-845848800 -10800 0 UYT}
+    {-334789200 -7200 1 UYST}
+    {-319672800 -10800 0 UYT}
+    {-314226000 -7200 1 UYST}
+    {-309996000 -10800 0 UYT}
+    {-149720400 -7200 1 UYST}
+    {-134604000 -10800 0 UYT}
+    {-118270800 -7200 1 UYST}
+    {-100044000 -10800 0 UYT}
+    {-86821200 -7200 1 UYST}
+    {-68508000 -10800 0 UYT}
+    {-50446800 -9000 1 UYHST}
+    {-34119000 -10800 0 UYT}
+    {-18910800 -9000 1 UYHST}
+    {-2583000 -10800 0 UYT}
+    {12625200 -9000 1 UYHST}
+    {28953000 -10800 0 UYT}
+    {72932400 -7200 1 UYST}
+    {82692000 -10800 0 UYT}
+    {132116400 -9000 1 UYHST}
+    {156911400 -7200 1 UYST}
+    {212983200 -10800 0 UYT}
+    {250052400 -7200 1 UYST}
+    {260244000 -10800 0 UYT}
+    {307594800 -7200 1 UYST}
+    {325994400 -10800 0 UYT}
+    {566449200 -7200 1 UYST}
+    {574308000 -10800 0 UYT}
+    {597812400 -7200 1 UYST}
+    {605671200 -10800 0 UYT}
+    {625633200 -7200 1 UYST}
+    {636516000 -10800 0 UYT}
+    {656478000 -7200 1 UYST}
+    {667965600 -10800 0 UYT}
+    {688532400 -7200 1 UYST}
+    {699415200 -10800 0 UYT}
+    {719377200 -7200 1 UYST}
+    {730864800 -10800 0 UYT}
+    {1095562800 -7200 1 UYST}
+    {1111896000 -10800 0 UYT}
+    {1128834000 -7200 1 UYST}
+    {1142136000 -10800 0 UYT}
+    {1159678800 -7200 1 UYST}
+    {1173585600 -10800 0 UYT}
+    {1191733200 -7200 1 UYST}
+    {1205035200 -10800 0 UYT}
+    {1223182800 -7200 1 UYST}
+    {1236484800 -10800 0 UYT}
+    {1254632400 -7200 1 UYST}
+    {1268539200 -10800 0 UYT}
+    {1286082000 -7200 1 UYST}
+    {1299988800 -10800 0 UYT}
+    {1317531600 -7200 1 UYST}
+    {1331438400 -10800 0 UYT}
+    {1349586000 -7200 1 UYST}
+    {1362888000 -10800 0 UYT}
+    {1381035600 -7200 1 UYST}
+    {1394337600 -10800 0 UYT}
+    {1412485200 -7200 1 UYST}
+    {1425787200 -10800 0 UYT}
+}
diff --git a/library/tzdata/America/Montreal b/library/tzdata/America/Montreal
new file mode 100644
index 0000000..0ead8ee
--- /dev/null
+++ b/library/tzdata/America/Montreal
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(America/Toronto)]} {
+    LoadTimeZoneFile America/Toronto
+}
+set TZData(:America/Montreal) $TZData(:America/Toronto)
diff --git a/library/tzdata/America/Montserrat b/library/tzdata/America/Montserrat
new file mode 100644
index 0000000..0a656d3
--- /dev/null
+++ b/library/tzdata/America/Montserrat
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(America/Port_of_Spain)]} {
+    LoadTimeZoneFile America/Port_of_Spain
+}
+set TZData(:America/Montserrat) $TZData(:America/Port_of_Spain)
diff --git a/library/tzdata/America/Nassau b/library/tzdata/America/Nassau
new file mode 100644
index 0000000..1c35e93
--- /dev/null
+++ b/library/tzdata/America/Nassau
@@ -0,0 +1,279 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Nassau) {
+    {-9223372036854775808 -18570 0 LMT}
+    {-1825095030 -18000 0 EST}
+    {-179341200 -14400 1 EDT}
+    {-163620000 -18000 0 EST}
+    {-147891600 -14400 1 EDT}
+    {-131565600 -18000 0 EST}
+    {-116442000 -14400 1 EDT}
+    {-100116000 -18000 0 EST}
+    {-84387600 -14400 1 EDT}
+    {-68666400 -18000 0 EST}
+    {-52938000 -14400 1 EDT}
+    {-37216800 -18000 0 EST}
+    {-21488400 -14400 1 EDT}
+    {-5767200 -18000 0 EST}
+    {9961200 -14400 1 EDT}
+    {25682400 -18000 0 EST}
+    {41410800 -14400 1 EDT}
+    {57736800 -18000 0 EST}
+    {73465200 -14400 1 EDT}
+    {89186400 -18000 0 EST}
+    {104914800 -14400 1 EDT}
+    {120636000 -18000 0 EST}
+    {136364400 -14400 1 EDT}
+    {152085600 -18000 0 EST}
+    {167814000 -14400 1 EDT}
+    {183535200 -18000 0 EST}
+    {189320400 -18000 0 EST}
+    {199263600 -14400 1 EDT}
+    {215589600 -18000 0 EST}
+    {230713200 -14400 1 EDT}
+    {247039200 -18000 0 EST}
+    {262767600 -14400 1 EDT}
+    {278488800 -18000 0 EST}
+    {294217200 -14400 1 EDT}
+    {309938400 -18000 0 EST}
+    {325666800 -14400 1 EDT}
+    {341388000 -18000 0 EST}
+    {357116400 -14400 1 EDT}
+    {372837600 -18000 0 EST}
+    {388566000 -14400 1 EDT}
+    {404892000 -18000 0 EST}
+    {420015600 -14400 1 EDT}
+    {436341600 -18000 0 EST}
+    {452070000 -14400 1 EDT}
+    {467791200 -18000 0 EST}
+    {483519600 -14400 1 EDT}
+    {499240800 -18000 0 EST}
+    {514969200 -14400 1 EDT}
+    {530690400 -18000 0 EST}
+    {544604400 -14400 1 EDT}
+    {562140000 -18000 0 EST}
+    {576054000 -14400 1 EDT}
+    {594194400 -18000 0 EST}
+    {607503600 -14400 1 EDT}
+    {625644000 -18000 0 EST}
+    {638953200 -14400 1 EDT}
+    {657093600 -18000 0 EST}
+    {671007600 -14400 1 EDT}
+    {688543200 -18000 0 EST}
+    {702457200 -14400 1 EDT}
+    {719992800 -18000 0 EST}
+    {733906800 -14400 1 EDT}
+    {752047200 -18000 0 EST}
+    {765356400 -14400 1 EDT}
+    {783496800 -18000 0 EST}
+    {796806000 -14400 1 EDT}
+    {814946400 -18000 0 EST}
+    {828860400 -14400 1 EDT}
+    {846396000 -18000 0 EST}
+    {860310000 -14400 1 EDT}
+    {877845600 -18000 0 EST}
+    {891759600 -14400 1 EDT}
+    {909295200 -18000 0 EST}
+    {923209200 -14400 1 EDT}
+    {941349600 -18000 0 EST}
+    {954658800 -14400 1 EDT}
+    {972799200 -18000 0 EST}
+    {986108400 -14400 1 EDT}
+    {1004248800 -18000 0 EST}
+    {1018162800 -14400 1 EDT}
+    {1035698400 -18000 0 EST}
+    {1049612400 -14400 1 EDT}
+    {1067148000 -18000 0 EST}
+    {1081062000 -14400 1 EDT}
+    {1099202400 -18000 0 EST}
+    {1112511600 -14400 1 EDT}
+    {1130652000 -18000 0 EST}
+    {1143961200 -14400 1 EDT}
+    {1162101600 -18000 0 EST}
+    {1173596400 -14400 1 EDT}
+    {1194156000 -18000 0 EST}
+    {1205046000 -14400 1 EDT}
+    {1225605600 -18000 0 EST}
+    {1236495600 -14400 1 EDT}
+    {1257055200 -18000 0 EST}
+    {1268550000 -14400 1 EDT}
+    {1289109600 -18000 0 EST}
+    {1299999600 -14400 1 EDT}
+    {1320559200 -18000 0 EST}
+    {1331449200 -14400 1 EDT}
+    {1352008800 -18000 0 EST}
+    {1362898800 -14400 1 EDT}
+    {1383458400 -18000 0 EST}
+    {1394348400 -14400 1 EDT}
+    {1414908000 -18000 0 EST}
+    {1425798000 -14400 1 EDT}
+    {1446357600 -18000 0 EST}
+    {1457852400 -14400 1 EDT}
+    {1478412000 -18000 0 EST}
+    {1489302000 -14400 1 EDT}
+    {1509861600 -18000 0 EST}
+    {1520751600 -14400 1 EDT}
+    {1541311200 -18000 0 EST}
+    {1552201200 -14400 1 EDT}
+    {1572760800 -18000 0 EST}
+    {1583650800 -14400 1 EDT}
+    {1604210400 -18000 0 EST}
+    {1615705200 -14400 1 EDT}
+    {1636264800 -18000 0 EST}
+    {1647154800 -14400 1 EDT}
+    {1667714400 -18000 0 EST}
+    {1678604400 -14400 1 EDT}
+    {1699164000 -18000 0 EST}
+    {1710054000 -14400 1 EDT}
+    {1730613600 -18000 0 EST}
+    {1741503600 -14400 1 EDT}
+    {1762063200 -18000 0 EST}
+    {1772953200 -14400 1 EDT}
+    {1793512800 -18000 0 EST}
+    {1805007600 -14400 1 EDT}
+    {1825567200 -18000 0 EST}
+    {1836457200 -14400 1 EDT}
+    {1857016800 -18000 0 EST}
+    {1867906800 -14400 1 EDT}
+    {1888466400 -18000 0 EST}
+    {1899356400 -14400 1 EDT}
+    {1919916000 -18000 0 EST}
+    {1930806000 -14400 1 EDT}
+    {1951365600 -18000 0 EST}
+    {1962860400 -14400 1 EDT}
+    {1983420000 -18000 0 EST}
+    {1994310000 -14400 1 EDT}
+    {2014869600 -18000 0 EST}
+    {2025759600 -14400 1 EDT}
+    {2046319200 -18000 0 EST}
+    {2057209200 -14400 1 EDT}
+    {2077768800 -18000 0 EST}
+    {2088658800 -14400 1 EDT}
+    {2109218400 -18000 0 EST}
+    {2120108400 -14400 1 EDT}
+    {2140668000 -18000 0 EST}
+    {2152162800 -14400 1 EDT}
+    {2172722400 -18000 0 EST}
+    {2183612400 -14400 1 EDT}
+    {2204172000 -18000 0 EST}
+    {2215062000 -14400 1 EDT}
+    {2235621600 -18000 0 EST}
+    {2246511600 -14400 1 EDT}
+    {2267071200 -18000 0 EST}
+    {2277961200 -14400 1 EDT}
+    {2298520800 -18000 0 EST}
+    {2309410800 -14400 1 EDT}
+    {2329970400 -18000 0 EST}
+    {2341465200 -14400 1 EDT}
+    {2362024800 -18000 0 EST}
+    {2372914800 -14400 1 EDT}
+    {2393474400 -18000 0 EST}
+    {2404364400 -14400 1 EDT}
+    {2424924000 -18000 0 EST}
+    {2435814000 -14400 1 EDT}
+    {2456373600 -18000 0 EST}
+    {2467263600 -14400 1 EDT}
+    {2487823200 -18000 0 EST}
+    {2499318000 -14400 1 EDT}
+    {2519877600 -18000 0 EST}
+    {2530767600 -14400 1 EDT}
+    {2551327200 -18000 0 EST}
+    {2562217200 -14400 1 EDT}
+    {2582776800 -18000 0 EST}
+    {2593666800 -14400 1 EDT}
+    {2614226400 -18000 0 EST}
+    {2625116400 -14400 1 EDT}
+    {2645676000 -18000 0 EST}
+    {2656566000 -14400 1 EDT}
+    {2677125600 -18000 0 EST}
+    {2688620400 -14400 1 EDT}
+    {2709180000 -18000 0 EST}
+    {2720070000 -14400 1 EDT}
+    {2740629600 -18000 0 EST}
+    {2751519600 -14400 1 EDT}
+    {2772079200 -18000 0 EST}
+    {2782969200 -14400 1 EDT}
+    {2803528800 -18000 0 EST}
+    {2814418800 -14400 1 EDT}
+    {2834978400 -18000 0 EST}
+    {2846473200 -14400 1 EDT}
+    {2867032800 -18000 0 EST}
+    {2877922800 -14400 1 EDT}
+    {2898482400 -18000 0 EST}
+    {2909372400 -14400 1 EDT}
+    {2929932000 -18000 0 EST}
+    {2940822000 -14400 1 EDT}
+    {2961381600 -18000 0 EST}
+    {2972271600 -14400 1 EDT}
+    {2992831200 -18000 0 EST}
+    {3003721200 -14400 1 EDT}
+    {3024280800 -18000 0 EST}
+    {3035775600 -14400 1 EDT}
+    {3056335200 -18000 0 EST}
+    {3067225200 -14400 1 EDT}
+    {3087784800 -18000 0 EST}
+    {3098674800 -14400 1 EDT}
+    {3119234400 -18000 0 EST}
+    {3130124400 -14400 1 EDT}
+    {3150684000 -18000 0 EST}
+    {3161574000 -14400 1 EDT}
+    {3182133600 -18000 0 EST}
+    {3193023600 -14400 1 EDT}
+    {3213583200 -18000 0 EST}
+    {3225078000 -14400 1 EDT}
+    {3245637600 -18000 0 EST}
+    {3256527600 -14400 1 EDT}
+    {3277087200 -18000 0 EST}
+    {3287977200 -14400 1 EDT}
+    {3308536800 -18000 0 EST}
+    {3319426800 -14400 1 EDT}
+    {3339986400 -18000 0 EST}
+    {3350876400 -14400 1 EDT}
+    {3371436000 -18000 0 EST}
+    {3382930800 -14400 1 EDT}
+    {3403490400 -18000 0 EST}
+    {3414380400 -14400 1 EDT}
+    {3434940000 -18000 0 EST}
+    {3445830000 -14400 1 EDT}
+    {3466389600 -18000 0 EST}
+    {3477279600 -14400 1 EDT}
+    {3497839200 -18000 0 EST}
+    {3508729200 -14400 1 EDT}
+    {3529288800 -18000 0 EST}
+    {3540178800 -14400 1 EDT}
+    {3560738400 -18000 0 EST}
+    {3572233200 -14400 1 EDT}
+    {3592792800 -18000 0 EST}
+    {3603682800 -14400 1 EDT}
+    {3624242400 -18000 0 EST}
+    {3635132400 -14400 1 EDT}
+    {3655692000 -18000 0 EST}
+    {3666582000 -14400 1 EDT}
+    {3687141600 -18000 0 EST}
+    {3698031600 -14400 1 EDT}
+    {3718591200 -18000 0 EST}
+    {3730086000 -14400 1 EDT}
+    {3750645600 -18000 0 EST}
+    {3761535600 -14400 1 EDT}
+    {3782095200 -18000 0 EST}
+    {3792985200 -14400 1 EDT}
+    {3813544800 -18000 0 EST}
+    {3824434800 -14400 1 EDT}
+    {3844994400 -18000 0 EST}
+    {3855884400 -14400 1 EDT}
+    {3876444000 -18000 0 EST}
+    {3887334000 -14400 1 EDT}
+    {3907893600 -18000 0 EST}
+    {3919388400 -14400 1 EDT}
+    {3939948000 -18000 0 EST}
+    {3950838000 -14400 1 EDT}
+    {3971397600 -18000 0 EST}
+    {3982287600 -14400 1 EDT}
+    {4002847200 -18000 0 EST}
+    {4013737200 -14400 1 EDT}
+    {4034296800 -18000 0 EST}
+    {4045186800 -14400 1 EDT}
+    {4065746400 -18000 0 EST}
+    {4076636400 -14400 1 EDT}
+    {4097196000 -18000 0 EST}
+}
diff --git a/library/tzdata/America/New_York b/library/tzdata/America/New_York
new file mode 100644
index 0000000..72f2c96
--- /dev/null
+++ b/library/tzdata/America/New_York
@@ -0,0 +1,369 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/New_York) {
+    {-9223372036854775808 -17762 0 LMT}
+    {-2717650800 -18000 0 EST}
+    {-1633280400 -14400 1 EDT}
+    {-1615140000 -18000 0 EST}
+    {-1601830800 -14400 1 EDT}
+    {-1583690400 -18000 0 EST}
+    {-1577905200 -18000 0 EST}
+    {-1570381200 -14400 1 EDT}
+    {-1551636000 -18000 0 EST}
+    {-1536512400 -14400 1 EDT}
+    {-1523210400 -18000 0 EST}
+    {-1504458000 -14400 1 EDT}
+    {-1491760800 -18000 0 EST}
+    {-1473008400 -14400 1 EDT}
+    {-1459706400 -18000 0 EST}
+    {-1441558800 -14400 1 EDT}
+    {-1428256800 -18000 0 EST}
+    {-1410109200 -14400 1 EDT}
+    {-1396807200 -18000 0 EST}
+    {-1378659600 -14400 1 EDT}
+    {-1365357600 -18000 0 EST}
+    {-1347210000 -14400 1 EDT}
+    {-1333908000 -18000 0 EST}
+    {-1315155600 -14400 1 EDT}
+    {-1301853600 -18000 0 EST}
+    {-1283706000 -14400 1 EDT}
+    {-1270404000 -18000 0 EST}
+    {-1252256400 -14400 1 EDT}
+    {-1238954400 -18000 0 EST}
+    {-1220806800 -14400 1 EDT}
+    {-1207504800 -18000 0 EST}
+    {-1189357200 -14400 1 EDT}
+    {-1176055200 -18000 0 EST}
+    {-1157302800 -14400 1 EDT}
+    {-1144605600 -18000 0 EST}
+    {-1125853200 -14400 1 EDT}
+    {-1112551200 -18000 0 EST}
+    {-1094403600 -14400 1 EDT}
+    {-1081101600 -18000 0 EST}
+    {-1062954000 -14400 1 EDT}
+    {-1049652000 -18000 0 EST}
+    {-1031504400 -14400 1 EDT}
+    {-1018202400 -18000 0 EST}
+    {-1000054800 -14400 1 EDT}
+    {-986752800 -18000 0 EST}
+    {-968000400 -14400 1 EDT}
+    {-955303200 -18000 0 EST}
+    {-936550800 -14400 1 EDT}
+    {-923248800 -18000 0 EST}
+    {-905101200 -14400 1 EDT}
+    {-891799200 -18000 0 EST}
+    {-883594800 -18000 0 EST}
+    {-880218000 -14400 1 EWT}
+    {-769395600 -14400 1 EPT}
+    {-765396000 -18000 0 EST}
+    {-757364400 -18000 0 EST}
+    {-747248400 -14400 1 EDT}
+    {-733946400 -18000 0 EST}
+    {-715798800 -14400 1 EDT}
+    {-702496800 -18000 0 EST}
+    {-684349200 -14400 1 EDT}
+    {-671047200 -18000 0 EST}
+    {-652899600 -14400 1 EDT}
+    {-639597600 -18000 0 EST}
+    {-620845200 -14400 1 EDT}
+    {-608148000 -18000 0 EST}
+    {-589395600 -14400 1 EDT}
+    {-576093600 -18000 0 EST}
+    {-557946000 -14400 1 EDT}
+    {-544644000 -18000 0 EST}
+    {-526496400 -14400 1 EDT}
+    {-513194400 -18000 0 EST}
+    {-495046800 -14400 1 EDT}
+    {-481744800 -18000 0 EST}
+    {-463597200 -14400 1 EDT}
+    {-447271200 -18000 0 EST}
+    {-431542800 -14400 1 EDT}
+    {-415821600 -18000 0 EST}
+    {-400093200 -14400 1 EDT}
+    {-384372000 -18000 0 EST}
+    {-368643600 -14400 1 EDT}
+    {-352922400 -18000 0 EST}
+    {-337194000 -14400 1 EDT}
+    {-321472800 -18000 0 EST}
+    {-305744400 -14400 1 EDT}
+    {-289418400 -18000 0 EST}
+    {-273690000 -14400 1 EDT}
+    {-257968800 -18000 0 EST}
+    {-242240400 -14400 1 EDT}
+    {-226519200 -18000 0 EST}
+    {-210790800 -14400 1 EDT}
+    {-195069600 -18000 0 EST}
+    {-179341200 -14400 1 EDT}
+    {-163620000 -18000 0 EST}
+    {-147891600 -14400 1 EDT}
+    {-131565600 -18000 0 EST}
+    {-116442000 -14400 1 EDT}
+    {-100116000 -18000 0 EST}
+    {-94676400 -18000 0 EST}
+    {-84387600 -14400 1 EDT}
+    {-68666400 -18000 0 EST}
+    {-52938000 -14400 1 EDT}
+    {-37216800 -18000 0 EST}
+    {-21488400 -14400 1 EDT}
+    {-5767200 -18000 0 EST}
+    {9961200 -14400 1 EDT}
+    {25682400 -18000 0 EST}
+    {41410800 -14400 1 EDT}
+    {57736800 -18000 0 EST}
+    {73465200 -14400 1 EDT}
+    {89186400 -18000 0 EST}
+    {104914800 -14400 1 EDT}
+    {120636000 -18000 0 EST}
+    {126687600 -14400 1 EDT}
+    {152085600 -18000 0 EST}
+    {162370800 -14400 1 EDT}
+    {183535200 -18000 0 EST}
+    {199263600 -14400 1 EDT}
+    {215589600 -18000 0 EST}
+    {230713200 -14400 1 EDT}
+    {247039200 -18000 0 EST}
+    {262767600 -14400 1 EDT}
+    {278488800 -18000 0 EST}
+    {294217200 -14400 1 EDT}
+    {309938400 -18000 0 EST}
+    {325666800 -14400 1 EDT}
+    {341388000 -18000 0 EST}
+    {357116400 -14400 1 EDT}
+    {372837600 -18000 0 EST}
+    {388566000 -14400 1 EDT}
+    {404892000 -18000 0 EST}
+    {420015600 -14400 1 EDT}
+    {436341600 -18000 0 EST}
+    {452070000 -14400 1 EDT}
+    {467791200 -18000 0 EST}
+    {483519600 -14400 1 EDT}
+    {499240800 -18000 0 EST}
+    {514969200 -14400 1 EDT}
+    {530690400 -18000 0 EST}
+    {544604400 -14400 1 EDT}
+    {562140000 -18000 0 EST}
+    {576054000 -14400 1 EDT}
+    {594194400 -18000 0 EST}
+    {607503600 -14400 1 EDT}
+    {625644000 -18000 0 EST}
+    {638953200 -14400 1 EDT}
+    {657093600 -18000 0 EST}
+    {671007600 -14400 1 EDT}
+    {688543200 -18000 0 EST}
+    {702457200 -14400 1 EDT}
+    {719992800 -18000 0 EST}
+    {733906800 -14400 1 EDT}
+    {752047200 -18000 0 EST}
+    {765356400 -14400 1 EDT}
+    {783496800 -18000 0 EST}
+    {796806000 -14400 1 EDT}
+    {814946400 -18000 0 EST}
+    {828860400 -14400 1 EDT}
+    {846396000 -18000 0 EST}
+    {860310000 -14400 1 EDT}
+    {877845600 -18000 0 EST}
+    {891759600 -14400 1 EDT}
+    {909295200 -18000 0 EST}
+    {923209200 -14400 1 EDT}
+    {941349600 -18000 0 EST}
+    {954658800 -14400 1 EDT}
+    {972799200 -18000 0 EST}
+    {986108400 -14400 1 EDT}
+    {1004248800 -18000 0 EST}
+    {1018162800 -14400 1 EDT}
+    {1035698400 -18000 0 EST}
+    {1049612400 -14400 1 EDT}
+    {1067148000 -18000 0 EST}
+    {1081062000 -14400 1 EDT}
+    {1099202400 -18000 0 EST}
+    {1112511600 -14400 1 EDT}
+    {1130652000 -18000 0 EST}
+    {1143961200 -14400 1 EDT}
+    {1162101600 -18000 0 EST}
+    {1173596400 -14400 1 EDT}
+    {1194156000 -18000 0 EST}
+    {1205046000 -14400 1 EDT}
+    {1225605600 -18000 0 EST}
+    {1236495600 -14400 1 EDT}
+    {1257055200 -18000 0 EST}
+    {1268550000 -14400 1 EDT}
+    {1289109600 -18000 0 EST}
+    {1299999600 -14400 1 EDT}
+    {1320559200 -18000 0 EST}
+    {1331449200 -14400 1 EDT}
+    {1352008800 -18000 0 EST}
+    {1362898800 -14400 1 EDT}
+    {1383458400 -18000 0 EST}
+    {1394348400 -14400 1 EDT}
+    {1414908000 -18000 0 EST}
+    {1425798000 -14400 1 EDT}
+    {1446357600 -18000 0 EST}
+    {1457852400 -14400 1 EDT}
+    {1478412000 -18000 0 EST}
+    {1489302000 -14400 1 EDT}
+    {1509861600 -18000 0 EST}
+    {1520751600 -14400 1 EDT}
+    {1541311200 -18000 0 EST}
+    {1552201200 -14400 1 EDT}
+    {1572760800 -18000 0 EST}
+    {1583650800 -14400 1 EDT}
+    {1604210400 -18000 0 EST}
+    {1615705200 -14400 1 EDT}
+    {1636264800 -18000 0 EST}
+    {1647154800 -14400 1 EDT}
+    {1667714400 -18000 0 EST}
+    {1678604400 -14400 1 EDT}
+    {1699164000 -18000 0 EST}
+    {1710054000 -14400 1 EDT}
+    {1730613600 -18000 0 EST}
+    {1741503600 -14400 1 EDT}
+    {1762063200 -18000 0 EST}
+    {1772953200 -14400 1 EDT}
+    {1793512800 -18000 0 EST}
+    {1805007600 -14400 1 EDT}
+    {1825567200 -18000 0 EST}
+    {1836457200 -14400 1 EDT}
+    {1857016800 -18000 0 EST}
+    {1867906800 -14400 1 EDT}
+    {1888466400 -18000 0 EST}
+    {1899356400 -14400 1 EDT}
+    {1919916000 -18000 0 EST}
+    {1930806000 -14400 1 EDT}
+    {1951365600 -18000 0 EST}
+    {1962860400 -14400 1 EDT}
+    {1983420000 -18000 0 EST}
+    {1994310000 -14400 1 EDT}
+    {2014869600 -18000 0 EST}
+    {2025759600 -14400 1 EDT}
+    {2046319200 -18000 0 EST}
+    {2057209200 -14400 1 EDT}
+    {2077768800 -18000 0 EST}
+    {2088658800 -14400 1 EDT}
+    {2109218400 -18000 0 EST}
+    {2120108400 -14400 1 EDT}
+    {2140668000 -18000 0 EST}
+    {2152162800 -14400 1 EDT}
+    {2172722400 -18000 0 EST}
+    {2183612400 -14400 1 EDT}
+    {2204172000 -18000 0 EST}
+    {2215062000 -14400 1 EDT}
+    {2235621600 -18000 0 EST}
+    {2246511600 -14400 1 EDT}
+    {2267071200 -18000 0 EST}
+    {2277961200 -14400 1 EDT}
+    {2298520800 -18000 0 EST}
+    {2309410800 -14400 1 EDT}
+    {2329970400 -18000 0 EST}
+    {2341465200 -14400 1 EDT}
+    {2362024800 -18000 0 EST}
+    {2372914800 -14400 1 EDT}
+    {2393474400 -18000 0 EST}
+    {2404364400 -14400 1 EDT}
+    {2424924000 -18000 0 EST}
+    {2435814000 -14400 1 EDT}
+    {2456373600 -18000 0 EST}
+    {2467263600 -14400 1 EDT}
+    {2487823200 -18000 0 EST}
+    {2499318000 -14400 1 EDT}
+    {2519877600 -18000 0 EST}
+    {2530767600 -14400 1 EDT}
+    {2551327200 -18000 0 EST}
+    {2562217200 -14400 1 EDT}
+    {2582776800 -18000 0 EST}
+    {2593666800 -14400 1 EDT}
+    {2614226400 -18000 0 EST}
+    {2625116400 -14400 1 EDT}
+    {2645676000 -18000 0 EST}
+    {2656566000 -14400 1 EDT}
+    {2677125600 -18000 0 EST}
+    {2688620400 -14400 1 EDT}
+    {2709180000 -18000 0 EST}
+    {2720070000 -14400 1 EDT}
+    {2740629600 -18000 0 EST}
+    {2751519600 -14400 1 EDT}
+    {2772079200 -18000 0 EST}
+    {2782969200 -14400 1 EDT}
+    {2803528800 -18000 0 EST}
+    {2814418800 -14400 1 EDT}
+    {2834978400 -18000 0 EST}
+    {2846473200 -14400 1 EDT}
+    {2867032800 -18000 0 EST}
+    {2877922800 -14400 1 EDT}
+    {2898482400 -18000 0 EST}
+    {2909372400 -14400 1 EDT}
+    {2929932000 -18000 0 EST}
+    {2940822000 -14400 1 EDT}
+    {2961381600 -18000 0 EST}
+    {2972271600 -14400 1 EDT}
+    {2992831200 -18000 0 EST}
+    {3003721200 -14400 1 EDT}
+    {3024280800 -18000 0 EST}
+    {3035775600 -14400 1 EDT}
+    {3056335200 -18000 0 EST}
+    {3067225200 -14400 1 EDT}
+    {3087784800 -18000 0 EST}
+    {3098674800 -14400 1 EDT}
+    {3119234400 -18000 0 EST}
+    {3130124400 -14400 1 EDT}
+    {3150684000 -18000 0 EST}
+    {3161574000 -14400 1 EDT}
+    {3182133600 -18000 0 EST}
+    {3193023600 -14400 1 EDT}
+    {3213583200 -18000 0 EST}
+    {3225078000 -14400 1 EDT}
+    {3245637600 -18000 0 EST}
+    {3256527600 -14400 1 EDT}
+    {3277087200 -18000 0 EST}
+    {3287977200 -14400 1 EDT}
+    {3308536800 -18000 0 EST}
+    {3319426800 -14400 1 EDT}
+    {3339986400 -18000 0 EST}
+    {3350876400 -14400 1 EDT}
+    {3371436000 -18000 0 EST}
+    {3382930800 -14400 1 EDT}
+    {3403490400 -18000 0 EST}
+    {3414380400 -14400 1 EDT}
+    {3434940000 -18000 0 EST}
+    {3445830000 -14400 1 EDT}
+    {3466389600 -18000 0 EST}
+    {3477279600 -14400 1 EDT}
+    {3497839200 -18000 0 EST}
+    {3508729200 -14400 1 EDT}
+    {3529288800 -18000 0 EST}
+    {3540178800 -14400 1 EDT}
+    {3560738400 -18000 0 EST}
+    {3572233200 -14400 1 EDT}
+    {3592792800 -18000 0 EST}
+    {3603682800 -14400 1 EDT}
+    {3624242400 -18000 0 EST}
+    {3635132400 -14400 1 EDT}
+    {3655692000 -18000 0 EST}
+    {3666582000 -14400 1 EDT}
+    {3687141600 -18000 0 EST}
+    {3698031600 -14400 1 EDT}
+    {3718591200 -18000 0 EST}
+    {3730086000 -14400 1 EDT}
+    {3750645600 -18000 0 EST}
+    {3761535600 -14400 1 EDT}
+    {3782095200 -18000 0 EST}
+    {3792985200 -14400 1 EDT}
+    {3813544800 -18000 0 EST}
+    {3824434800 -14400 1 EDT}
+    {3844994400 -18000 0 EST}
+    {3855884400 -14400 1 EDT}
+    {3876444000 -18000 0 EST}
+    {3887334000 -14400 1 EDT}
+    {3907893600 -18000 0 EST}
+    {3919388400 -14400 1 EDT}
+    {3939948000 -18000 0 EST}
+    {3950838000 -14400 1 EDT}
+    {3971397600 -18000 0 EST}
+    {3982287600 -14400 1 EDT}
+    {4002847200 -18000 0 EST}
+    {4013737200 -14400 1 EDT}
+    {4034296800 -18000 0 EST}
+    {4045186800 -14400 1 EDT}
+    {4065746400 -18000 0 EST}
+    {4076636400 -14400 1 EDT}
+    {4097196000 -18000 0 EST}
+}
diff --git a/library/tzdata/America/Nipigon b/library/tzdata/America/Nipigon
new file mode 100644
index 0000000..30690aa
--- /dev/null
+++ b/library/tzdata/America/Nipigon
@@ -0,0 +1,264 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Nipigon) {
+    {-9223372036854775808 -21184 0 LMT}
+    {-2366734016 -18000 0 EST}
+    {-1632070800 -14400 1 EDT}
+    {-1615140000 -18000 0 EST}
+    {-923252400 -14400 1 EDT}
+    {-880218000 -14400 0 EWT}
+    {-769395600 -14400 1 EPT}
+    {-765396000 -18000 0 EST}
+    {136364400 -14400 1 EDT}
+    {152085600 -18000 0 EST}
+    {167814000 -14400 1 EDT}
+    {183535200 -18000 0 EST}
+    {199263600 -14400 1 EDT}
+    {215589600 -18000 0 EST}
+    {230713200 -14400 1 EDT}
+    {247039200 -18000 0 EST}
+    {262767600 -14400 1 EDT}
+    {278488800 -18000 0 EST}
+    {294217200 -14400 1 EDT}
+    {309938400 -18000 0 EST}
+    {325666800 -14400 1 EDT}
+    {341388000 -18000 0 EST}
+    {357116400 -14400 1 EDT}
+    {372837600 -18000 0 EST}
+    {388566000 -14400 1 EDT}
+    {404892000 -18000 0 EST}
+    {420015600 -14400 1 EDT}
+    {436341600 -18000 0 EST}
+    {452070000 -14400 1 EDT}
+    {467791200 -18000 0 EST}
+    {483519600 -14400 1 EDT}
+    {499240800 -18000 0 EST}
+    {514969200 -14400 1 EDT}
+    {530690400 -18000 0 EST}
+    {544604400 -14400 1 EDT}
+    {562140000 -18000 0 EST}
+    {576054000 -14400 1 EDT}
+    {594194400 -18000 0 EST}
+    {607503600 -14400 1 EDT}
+    {625644000 -18000 0 EST}
+    {638953200 -14400 1 EDT}
+    {657093600 -18000 0 EST}
+    {671007600 -14400 1 EDT}
+    {688543200 -18000 0 EST}
+    {702457200 -14400 1 EDT}
+    {719992800 -18000 0 EST}
+    {733906800 -14400 1 EDT}
+    {752047200 -18000 0 EST}
+    {765356400 -14400 1 EDT}
+    {783496800 -18000 0 EST}
+    {796806000 -14400 1 EDT}
+    {814946400 -18000 0 EST}
+    {828860400 -14400 1 EDT}
+    {846396000 -18000 0 EST}
+    {860310000 -14400 1 EDT}
+    {877845600 -18000 0 EST}
+    {891759600 -14400 1 EDT}
+    {909295200 -18000 0 EST}
+    {923209200 -14400 1 EDT}
+    {941349600 -18000 0 EST}
+    {954658800 -14400 1 EDT}
+    {972799200 -18000 0 EST}
+    {986108400 -14400 1 EDT}
+    {1004248800 -18000 0 EST}
+    {1018162800 -14400 1 EDT}
+    {1035698400 -18000 0 EST}
+    {1049612400 -14400 1 EDT}
+    {1067148000 -18000 0 EST}
+    {1081062000 -14400 1 EDT}
+    {1099202400 -18000 0 EST}
+    {1112511600 -14400 1 EDT}
+    {1130652000 -18000 0 EST}
+    {1143961200 -14400 1 EDT}
+    {1162101600 -18000 0 EST}
+    {1173596400 -14400 1 EDT}
+    {1194156000 -18000 0 EST}
+    {1205046000 -14400 1 EDT}
+    {1225605600 -18000 0 EST}
+    {1236495600 -14400 1 EDT}
+    {1257055200 -18000 0 EST}
+    {1268550000 -14400 1 EDT}
+    {1289109600 -18000 0 EST}
+    {1299999600 -14400 1 EDT}
+    {1320559200 -18000 0 EST}
+    {1331449200 -14400 1 EDT}
+    {1352008800 -18000 0 EST}
+    {1362898800 -14400 1 EDT}
+    {1383458400 -18000 0 EST}
+    {1394348400 -14400 1 EDT}
+    {1414908000 -18000 0 EST}
+    {1425798000 -14400 1 EDT}
+    {1446357600 -18000 0 EST}
+    {1457852400 -14400 1 EDT}
+    {1478412000 -18000 0 EST}
+    {1489302000 -14400 1 EDT}
+    {1509861600 -18000 0 EST}
+    {1520751600 -14400 1 EDT}
+    {1541311200 -18000 0 EST}
+    {1552201200 -14400 1 EDT}
+    {1572760800 -18000 0 EST}
+    {1583650800 -14400 1 EDT}
+    {1604210400 -18000 0 EST}
+    {1615705200 -14400 1 EDT}
+    {1636264800 -18000 0 EST}
+    {1647154800 -14400 1 EDT}
+    {1667714400 -18000 0 EST}
+    {1678604400 -14400 1 EDT}
+    {1699164000 -18000 0 EST}
+    {1710054000 -14400 1 EDT}
+    {1730613600 -18000 0 EST}
+    {1741503600 -14400 1 EDT}
+    {1762063200 -18000 0 EST}
+    {1772953200 -14400 1 EDT}
+    {1793512800 -18000 0 EST}
+    {1805007600 -14400 1 EDT}
+    {1825567200 -18000 0 EST}
+    {1836457200 -14400 1 EDT}
+    {1857016800 -18000 0 EST}
+    {1867906800 -14400 1 EDT}
+    {1888466400 -18000 0 EST}
+    {1899356400 -14400 1 EDT}
+    {1919916000 -18000 0 EST}
+    {1930806000 -14400 1 EDT}
+    {1951365600 -18000 0 EST}
+    {1962860400 -14400 1 EDT}
+    {1983420000 -18000 0 EST}
+    {1994310000 -14400 1 EDT}
+    {2014869600 -18000 0 EST}
+    {2025759600 -14400 1 EDT}
+    {2046319200 -18000 0 EST}
+    {2057209200 -14400 1 EDT}
+    {2077768800 -18000 0 EST}
+    {2088658800 -14400 1 EDT}
+    {2109218400 -18000 0 EST}
+    {2120108400 -14400 1 EDT}
+    {2140668000 -18000 0 EST}
+    {2152162800 -14400 1 EDT}
+    {2172722400 -18000 0 EST}
+    {2183612400 -14400 1 EDT}
+    {2204172000 -18000 0 EST}
+    {2215062000 -14400 1 EDT}
+    {2235621600 -18000 0 EST}
+    {2246511600 -14400 1 EDT}
+    {2267071200 -18000 0 EST}
+    {2277961200 -14400 1 EDT}
+    {2298520800 -18000 0 EST}
+    {2309410800 -14400 1 EDT}
+    {2329970400 -18000 0 EST}
+    {2341465200 -14400 1 EDT}
+    {2362024800 -18000 0 EST}
+    {2372914800 -14400 1 EDT}
+    {2393474400 -18000 0 EST}
+    {2404364400 -14400 1 EDT}
+    {2424924000 -18000 0 EST}
+    {2435814000 -14400 1 EDT}
+    {2456373600 -18000 0 EST}
+    {2467263600 -14400 1 EDT}
+    {2487823200 -18000 0 EST}
+    {2499318000 -14400 1 EDT}
+    {2519877600 -18000 0 EST}
+    {2530767600 -14400 1 EDT}
+    {2551327200 -18000 0 EST}
+    {2562217200 -14400 1 EDT}
+    {2582776800 -18000 0 EST}
+    {2593666800 -14400 1 EDT}
+    {2614226400 -18000 0 EST}
+    {2625116400 -14400 1 EDT}
+    {2645676000 -18000 0 EST}
+    {2656566000 -14400 1 EDT}
+    {2677125600 -18000 0 EST}
+    {2688620400 -14400 1 EDT}
+    {2709180000 -18000 0 EST}
+    {2720070000 -14400 1 EDT}
+    {2740629600 -18000 0 EST}
+    {2751519600 -14400 1 EDT}
+    {2772079200 -18000 0 EST}
+    {2782969200 -14400 1 EDT}
+    {2803528800 -18000 0 EST}
+    {2814418800 -14400 1 EDT}
+    {2834978400 -18000 0 EST}
+    {2846473200 -14400 1 EDT}
+    {2867032800 -18000 0 EST}
+    {2877922800 -14400 1 EDT}
+    {2898482400 -18000 0 EST}
+    {2909372400 -14400 1 EDT}
+    {2929932000 -18000 0 EST}
+    {2940822000 -14400 1 EDT}
+    {2961381600 -18000 0 EST}
+    {2972271600 -14400 1 EDT}
+    {2992831200 -18000 0 EST}
+    {3003721200 -14400 1 EDT}
+    {3024280800 -18000 0 EST}
+    {3035775600 -14400 1 EDT}
+    {3056335200 -18000 0 EST}
+    {3067225200 -14400 1 EDT}
+    {3087784800 -18000 0 EST}
+    {3098674800 -14400 1 EDT}
+    {3119234400 -18000 0 EST}
+    {3130124400 -14400 1 EDT}
+    {3150684000 -18000 0 EST}
+    {3161574000 -14400 1 EDT}
+    {3182133600 -18000 0 EST}
+    {3193023600 -14400 1 EDT}
+    {3213583200 -18000 0 EST}
+    {3225078000 -14400 1 EDT}
+    {3245637600 -18000 0 EST}
+    {3256527600 -14400 1 EDT}
+    {3277087200 -18000 0 EST}
+    {3287977200 -14400 1 EDT}
+    {3308536800 -18000 0 EST}
+    {3319426800 -14400 1 EDT}
+    {3339986400 -18000 0 EST}
+    {3350876400 -14400 1 EDT}
+    {3371436000 -18000 0 EST}
+    {3382930800 -14400 1 EDT}
+    {3403490400 -18000 0 EST}
+    {3414380400 -14400 1 EDT}
+    {3434940000 -18000 0 EST}
+    {3445830000 -14400 1 EDT}
+    {3466389600 -18000 0 EST}
+    {3477279600 -14400 1 EDT}
+    {3497839200 -18000 0 EST}
+    {3508729200 -14400 1 EDT}
+    {3529288800 -18000 0 EST}
+    {3540178800 -14400 1 EDT}
+    {3560738400 -18000 0 EST}
+    {3572233200 -14400 1 EDT}
+    {3592792800 -18000 0 EST}
+    {3603682800 -14400 1 EDT}
+    {3624242400 -18000 0 EST}
+    {3635132400 -14400 1 EDT}
+    {3655692000 -18000 0 EST}
+    {3666582000 -14400 1 EDT}
+    {3687141600 -18000 0 EST}
+    {3698031600 -14400 1 EDT}
+    {3718591200 -18000 0 EST}
+    {3730086000 -14400 1 EDT}
+    {3750645600 -18000 0 EST}
+    {3761535600 -14400 1 EDT}
+    {3782095200 -18000 0 EST}
+    {3792985200 -14400 1 EDT}
+    {3813544800 -18000 0 EST}
+    {3824434800 -14400 1 EDT}
+    {3844994400 -18000 0 EST}
+    {3855884400 -14400 1 EDT}
+    {3876444000 -18000 0 EST}
+    {3887334000 -14400 1 EDT}
+    {3907893600 -18000 0 EST}
+    {3919388400 -14400 1 EDT}
+    {3939948000 -18000 0 EST}
+    {3950838000 -14400 1 EDT}
+    {3971397600 -18000 0 EST}
+    {3982287600 -14400 1 EDT}
+    {4002847200 -18000 0 EST}
+    {4013737200 -14400 1 EDT}
+    {4034296800 -18000 0 EST}
+    {4045186800 -14400 1 EDT}
+    {4065746400 -18000 0 EST}
+    {4076636400 -14400 1 EDT}
+    {4097196000 -18000 0 EST}
+}
diff --git a/library/tzdata/America/Nome b/library/tzdata/America/Nome
new file mode 100644
index 0000000..c095b79
--- /dev/null
+++ b/library/tzdata/America/Nome
@@ -0,0 +1,276 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Nome) {
+    {-9223372036854775808 46701 0 LMT}
+    {-3225358701 -39698 0 LMT}
+    {-2188947502 -39600 0 NST}
+    {-883573200 -39600 0 NST}
+    {-880196400 -36000 1 NWT}
+    {-769395600 -36000 1 NPT}
+    {-765374400 -39600 0 NST}
+    {-757342800 -39600 0 NST}
+    {-86878800 -39600 0 BST}
+    {-31496400 -39600 0 BST}
+    {-21466800 -36000 1 BDT}
+    {-5745600 -39600 0 BST}
+    {9982800 -36000 1 BDT}
+    {25704000 -39600 0 BST}
+    {41432400 -36000 1 BDT}
+    {57758400 -39600 0 BST}
+    {73486800 -36000 1 BDT}
+    {89208000 -39600 0 BST}
+    {104936400 -36000 1 BDT}
+    {120657600 -39600 0 BST}
+    {126709200 -36000 1 BDT}
+    {152107200 -39600 0 BST}
+    {162392400 -36000 1 BDT}
+    {183556800 -39600 0 BST}
+    {199285200 -36000 1 BDT}
+    {215611200 -39600 0 BST}
+    {230734800 -36000 1 BDT}
+    {247060800 -39600 0 BST}
+    {262789200 -36000 1 BDT}
+    {278510400 -39600 0 BST}
+    {294238800 -36000 1 BDT}
+    {309960000 -39600 0 BST}
+    {325688400 -36000 1 BDT}
+    {341409600 -39600 0 BST}
+    {357138000 -36000 1 BDT}
+    {372859200 -39600 0 BST}
+    {388587600 -36000 1 BDT}
+    {404913600 -39600 0 BST}
+    {420037200 -36000 1 BDT}
+    {439030800 -32400 0 AKST}
+    {452084400 -28800 1 AKDT}
+    {467805600 -32400 0 AKST}
+    {483534000 -28800 1 AKDT}
+    {499255200 -32400 0 AKST}
+    {514983600 -28800 1 AKDT}
+    {530704800 -32400 0 AKST}
+    {544618800 -28800 1 AKDT}
+    {562154400 -32400 0 AKST}
+    {576068400 -28800 1 AKDT}
+    {594208800 -32400 0 AKST}
+    {607518000 -28800 1 AKDT}
+    {625658400 -32400 0 AKST}
+    {638967600 -28800 1 AKDT}
+    {657108000 -32400 0 AKST}
+    {671022000 -28800 1 AKDT}
+    {688557600 -32400 0 AKST}
+    {702471600 -28800 1 AKDT}
+    {720007200 -32400 0 AKST}
+    {733921200 -28800 1 AKDT}
+    {752061600 -32400 0 AKST}
+    {765370800 -28800 1 AKDT}
+    {783511200 -32400 0 AKST}
+    {796820400 -28800 1 AKDT}
+    {814960800 -32400 0 AKST}
+    {828874800 -28800 1 AKDT}
+    {846410400 -32400 0 AKST}
+    {860324400 -28800 1 AKDT}
+    {877860000 -32400 0 AKST}
+    {891774000 -28800 1 AKDT}
+    {909309600 -32400 0 AKST}
+    {923223600 -28800 1 AKDT}
+    {941364000 -32400 0 AKST}
+    {954673200 -28800 1 AKDT}
+    {972813600 -32400 0 AKST}
+    {986122800 -28800 1 AKDT}
+    {1004263200 -32400 0 AKST}
+    {1018177200 -28800 1 AKDT}
+    {1035712800 -32400 0 AKST}
+    {1049626800 -28800 1 AKDT}
+    {1067162400 -32400 0 AKST}
+    {1081076400 -28800 1 AKDT}
+    {1099216800 -32400 0 AKST}
+    {1112526000 -28800 1 AKDT}
+    {1130666400 -32400 0 AKST}
+    {1143975600 -28800 1 AKDT}
+    {1162116000 -32400 0 AKST}
+    {1173610800 -28800 1 AKDT}
+    {1194170400 -32400 0 AKST}
+    {1205060400 -28800 1 AKDT}
+    {1225620000 -32400 0 AKST}
+    {1236510000 -28800 1 AKDT}
+    {1257069600 -32400 0 AKST}
+    {1268564400 -28800 1 AKDT}
+    {1289124000 -32400 0 AKST}
+    {1300014000 -28800 1 AKDT}
+    {1320573600 -32400 0 AKST}
+    {1331463600 -28800 1 AKDT}
+    {1352023200 -32400 0 AKST}
+    {1362913200 -28800 1 AKDT}
+    {1383472800 -32400 0 AKST}
+    {1394362800 -28800 1 AKDT}
+    {1414922400 -32400 0 AKST}
+    {1425812400 -28800 1 AKDT}
+    {1446372000 -32400 0 AKST}
+    {1457866800 -28800 1 AKDT}
+    {1478426400 -32400 0 AKST}
+    {1489316400 -28800 1 AKDT}
+    {1509876000 -32400 0 AKST}
+    {1520766000 -28800 1 AKDT}
+    {1541325600 -32400 0 AKST}
+    {1552215600 -28800 1 AKDT}
+    {1572775200 -32400 0 AKST}
+    {1583665200 -28800 1 AKDT}
+    {1604224800 -32400 0 AKST}
+    {1615719600 -28800 1 AKDT}
+    {1636279200 -32400 0 AKST}
+    {1647169200 -28800 1 AKDT}
+    {1667728800 -32400 0 AKST}
+    {1678618800 -28800 1 AKDT}
+    {1699178400 -32400 0 AKST}
+    {1710068400 -28800 1 AKDT}
+    {1730628000 -32400 0 AKST}
+    {1741518000 -28800 1 AKDT}
+    {1762077600 -32400 0 AKST}
+    {1772967600 -28800 1 AKDT}
+    {1793527200 -32400 0 AKST}
+    {1805022000 -28800 1 AKDT}
+    {1825581600 -32400 0 AKST}
+    {1836471600 -28800 1 AKDT}
+    {1857031200 -32400 0 AKST}
+    {1867921200 -28800 1 AKDT}
+    {1888480800 -32400 0 AKST}
+    {1899370800 -28800 1 AKDT}
+    {1919930400 -32400 0 AKST}
+    {1930820400 -28800 1 AKDT}
+    {1951380000 -32400 0 AKST}
+    {1962874800 -28800 1 AKDT}
+    {1983434400 -32400 0 AKST}
+    {1994324400 -28800 1 AKDT}
+    {2014884000 -32400 0 AKST}
+    {2025774000 -28800 1 AKDT}
+    {2046333600 -32400 0 AKST}
+    {2057223600 -28800 1 AKDT}
+    {2077783200 -32400 0 AKST}
+    {2088673200 -28800 1 AKDT}
+    {2109232800 -32400 0 AKST}
+    {2120122800 -28800 1 AKDT}
+    {2140682400 -32400 0 AKST}
+    {2152177200 -28800 1 AKDT}
+    {2172736800 -32400 0 AKST}
+    {2183626800 -28800 1 AKDT}
+    {2204186400 -32400 0 AKST}
+    {2215076400 -28800 1 AKDT}
+    {2235636000 -32400 0 AKST}
+    {2246526000 -28800 1 AKDT}
+    {2267085600 -32400 0 AKST}
+    {2277975600 -28800 1 AKDT}
+    {2298535200 -32400 0 AKST}
+    {2309425200 -28800 1 AKDT}
+    {2329984800 -32400 0 AKST}
+    {2341479600 -28800 1 AKDT}
+    {2362039200 -32400 0 AKST}
+    {2372929200 -28800 1 AKDT}
+    {2393488800 -32400 0 AKST}
+    {2404378800 -28800 1 AKDT}
+    {2424938400 -32400 0 AKST}
+    {2435828400 -28800 1 AKDT}
+    {2456388000 -32400 0 AKST}
+    {2467278000 -28800 1 AKDT}
+    {2487837600 -32400 0 AKST}
+    {2499332400 -28800 1 AKDT}
+    {2519892000 -32400 0 AKST}
+    {2530782000 -28800 1 AKDT}
+    {2551341600 -32400 0 AKST}
+    {2562231600 -28800 1 AKDT}
+    {2582791200 -32400 0 AKST}
+    {2593681200 -28800 1 AKDT}
+    {2614240800 -32400 0 AKST}
+    {2625130800 -28800 1 AKDT}
+    {2645690400 -32400 0 AKST}
+    {2656580400 -28800 1 AKDT}
+    {2677140000 -32400 0 AKST}
+    {2688634800 -28800 1 AKDT}
+    {2709194400 -32400 0 AKST}
+    {2720084400 -28800 1 AKDT}
+    {2740644000 -32400 0 AKST}
+    {2751534000 -28800 1 AKDT}
+    {2772093600 -32400 0 AKST}
+    {2782983600 -28800 1 AKDT}
+    {2803543200 -32400 0 AKST}
+    {2814433200 -28800 1 AKDT}
+    {2834992800 -32400 0 AKST}
+    {2846487600 -28800 1 AKDT}
+    {2867047200 -32400 0 AKST}
+    {2877937200 -28800 1 AKDT}
+    {2898496800 -32400 0 AKST}
+    {2909386800 -28800 1 AKDT}
+    {2929946400 -32400 0 AKST}
+    {2940836400 -28800 1 AKDT}
+    {2961396000 -32400 0 AKST}
+    {2972286000 -28800 1 AKDT}
+    {2992845600 -32400 0 AKST}
+    {3003735600 -28800 1 AKDT}
+    {3024295200 -32400 0 AKST}
+    {3035790000 -28800 1 AKDT}
+    {3056349600 -32400 0 AKST}
+    {3067239600 -28800 1 AKDT}
+    {3087799200 -32400 0 AKST}
+    {3098689200 -28800 1 AKDT}
+    {3119248800 -32400 0 AKST}
+    {3130138800 -28800 1 AKDT}
+    {3150698400 -32400 0 AKST}
+    {3161588400 -28800 1 AKDT}
+    {3182148000 -32400 0 AKST}
+    {3193038000 -28800 1 AKDT}
+    {3213597600 -32400 0 AKST}
+    {3225092400 -28800 1 AKDT}
+    {3245652000 -32400 0 AKST}
+    {3256542000 -28800 1 AKDT}
+    {3277101600 -32400 0 AKST}
+    {3287991600 -28800 1 AKDT}
+    {3308551200 -32400 0 AKST}
+    {3319441200 -28800 1 AKDT}
+    {3340000800 -32400 0 AKST}
+    {3350890800 -28800 1 AKDT}
+    {3371450400 -32400 0 AKST}
+    {3382945200 -28800 1 AKDT}
+    {3403504800 -32400 0 AKST}
+    {3414394800 -28800 1 AKDT}
+    {3434954400 -32400 0 AKST}
+    {3445844400 -28800 1 AKDT}
+    {3466404000 -32400 0 AKST}
+    {3477294000 -28800 1 AKDT}
+    {3497853600 -32400 0 AKST}
+    {3508743600 -28800 1 AKDT}
+    {3529303200 -32400 0 AKST}
+    {3540193200 -28800 1 AKDT}
+    {3560752800 -32400 0 AKST}
+    {3572247600 -28800 1 AKDT}
+    {3592807200 -32400 0 AKST}
+    {3603697200 -28800 1 AKDT}
+    {3624256800 -32400 0 AKST}
+    {3635146800 -28800 1 AKDT}
+    {3655706400 -32400 0 AKST}
+    {3666596400 -28800 1 AKDT}
+    {3687156000 -32400 0 AKST}
+    {3698046000 -28800 1 AKDT}
+    {3718605600 -32400 0 AKST}
+    {3730100400 -28800 1 AKDT}
+    {3750660000 -32400 0 AKST}
+    {3761550000 -28800 1 AKDT}
+    {3782109600 -32400 0 AKST}
+    {3792999600 -28800 1 AKDT}
+    {3813559200 -32400 0 AKST}
+    {3824449200 -28800 1 AKDT}
+    {3845008800 -32400 0 AKST}
+    {3855898800 -28800 1 AKDT}
+    {3876458400 -32400 0 AKST}
+    {3887348400 -28800 1 AKDT}
+    {3907908000 -32400 0 AKST}
+    {3919402800 -28800 1 AKDT}
+    {3939962400 -32400 0 AKST}
+    {3950852400 -28800 1 AKDT}
+    {3971412000 -32400 0 AKST}
+    {3982302000 -28800 1 AKDT}
+    {4002861600 -32400 0 AKST}
+    {4013751600 -28800 1 AKDT}
+    {4034311200 -32400 0 AKST}
+    {4045201200 -28800 1 AKDT}
+    {4065760800 -32400 0 AKST}
+    {4076650800 -28800 1 AKDT}
+    {4097210400 -32400 0 AKST}
+}
diff --git a/library/tzdata/America/Noronha b/library/tzdata/America/Noronha
new file mode 100644
index 0000000..94d6f42
--- /dev/null
+++ b/library/tzdata/America/Noronha
@@ -0,0 +1,48 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Noronha) {
+    {-9223372036854775808 -7780 0 LMT}
+    {-1767217820 -7200 0 FNT}
+    {-1206961200 -3600 1 FNST}
+    {-1191366000 -7200 0 FNT}
+    {-1175378400 -3600 1 FNST}
+    {-1159830000 -7200 0 FNT}
+    {-633823200 -3600 1 FNST}
+    {-622072800 -7200 0 FNT}
+    {-602287200 -3600 1 FNST}
+    {-591836400 -7200 0 FNT}
+    {-570751200 -3600 1 FNST}
+    {-560214000 -7200 0 FNT}
+    {-539128800 -3600 1 FNST}
+    {-531356400 -7200 0 FNT}
+    {-191368800 -3600 1 FNST}
+    {-184201200 -7200 0 FNT}
+    {-155167200 -3600 1 FNST}
+    {-150073200 -7200 0 FNT}
+    {-128901600 -3600 1 FNST}
+    {-121129200 -7200 0 FNT}
+    {-99957600 -3600 1 FNST}
+    {-89593200 -7200 0 FNT}
+    {-68421600 -3600 1 FNST}
+    {-57970800 -7200 0 FNT}
+    {499744800 -3600 1 FNST}
+    {511232400 -7200 0 FNT}
+    {530589600 -3600 1 FNST}
+    {540262800 -7200 0 FNT}
+    {562125600 -3600 1 FNST}
+    {571194000 -7200 0 FNT}
+    {592970400 -3600 1 FNST}
+    {602038800 -7200 0 FNT}
+    {624420000 -3600 1 FNST}
+    {634698000 -7200 0 FNT}
+    {653533200 -7200 0 FNT}
+    {938656800 -7200 0 FNT}
+    {938916000 -3600 1 FNST}
+    {951613200 -7200 0 FNT}
+    {970970400 -3600 1 FNST}
+    {971571600 -7200 0 FNT}
+    {1000346400 -7200 0 FNT}
+    {1003024800 -3600 1 FNST}
+    {1013907600 -7200 0 FNT}
+    {1033434000 -7200 0 FNT}
+}
diff --git a/library/tzdata/America/North_Dakota/Beulah b/library/tzdata/America/North_Dakota/Beulah
new file mode 100644
index 0000000..95407c6
--- /dev/null
+++ b/library/tzdata/America/North_Dakota/Beulah
@@ -0,0 +1,279 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/North_Dakota/Beulah) {
+    {-9223372036854775808 -24427 0 LMT}
+    {-2717643600 -25200 0 MST}
+    {-1633273200 -21600 1 MDT}
+    {-1615132800 -25200 0 MST}
+    {-1601823600 -21600 1 MDT}
+    {-1583683200 -25200 0 MST}
+    {-880210800 -21600 1 MWT}
+    {-769395600 -21600 1 MPT}
+    {-765388800 -25200 0 MST}
+    {-84380400 -21600 1 MDT}
+    {-68659200 -25200 0 MST}
+    {-52930800 -21600 1 MDT}
+    {-37209600 -25200 0 MST}
+    {-21481200 -21600 1 MDT}
+    {-5760000 -25200 0 MST}
+    {9968400 -21600 1 MDT}
+    {25689600 -25200 0 MST}
+    {41418000 -21600 1 MDT}
+    {57744000 -25200 0 MST}
+    {73472400 -21600 1 MDT}
+    {89193600 -25200 0 MST}
+    {104922000 -21600 1 MDT}
+    {120643200 -25200 0 MST}
+    {126694800 -21600 1 MDT}
+    {152092800 -25200 0 MST}
+    {162378000 -21600 1 MDT}
+    {183542400 -25200 0 MST}
+    {199270800 -21600 1 MDT}
+    {215596800 -25200 0 MST}
+    {230720400 -21600 1 MDT}
+    {247046400 -25200 0 MST}
+    {262774800 -21600 1 MDT}
+    {278496000 -25200 0 MST}
+    {294224400 -21600 1 MDT}
+    {309945600 -25200 0 MST}
+    {325674000 -21600 1 MDT}
+    {341395200 -25200 0 MST}
+    {357123600 -21600 1 MDT}
+    {372844800 -25200 0 MST}
+    {388573200 -21600 1 MDT}
+    {404899200 -25200 0 MST}
+    {420022800 -21600 1 MDT}
+    {436348800 -25200 0 MST}
+    {452077200 -21600 1 MDT}
+    {467798400 -25200 0 MST}
+    {483526800 -21600 1 MDT}
+    {499248000 -25200 0 MST}
+    {514976400 -21600 1 MDT}
+    {530697600 -25200 0 MST}
+    {544611600 -21600 1 MDT}
+    {562147200 -25200 0 MST}
+    {576061200 -21600 1 MDT}
+    {594201600 -25200 0 MST}
+    {607510800 -21600 1 MDT}
+    {625651200 -25200 0 MST}
+    {638960400 -21600 1 MDT}
+    {657100800 -25200 0 MST}
+    {671014800 -21600 1 MDT}
+    {688550400 -25200 0 MST}
+    {702464400 -21600 1 MDT}
+    {720000000 -25200 0 MST}
+    {733914000 -21600 1 MDT}
+    {752054400 -25200 0 MST}
+    {765363600 -21600 1 MDT}
+    {783504000 -25200 0 MST}
+    {796813200 -21600 1 MDT}
+    {814953600 -25200 0 MST}
+    {828867600 -21600 1 MDT}
+    {846403200 -25200 0 MST}
+    {860317200 -21600 1 MDT}
+    {877852800 -25200 0 MST}
+    {891766800 -21600 1 MDT}
+    {909302400 -25200 0 MST}
+    {923216400 -21600 1 MDT}
+    {941356800 -25200 0 MST}
+    {954666000 -21600 1 MDT}
+    {972806400 -25200 0 MST}
+    {986115600 -21600 1 MDT}
+    {1004256000 -25200 0 MST}
+    {1018170000 -21600 1 MDT}
+    {1035705600 -25200 0 MST}
+    {1049619600 -21600 1 MDT}
+    {1067155200 -25200 0 MST}
+    {1081069200 -21600 1 MDT}
+    {1099209600 -25200 0 MST}
+    {1112518800 -21600 1 MDT}
+    {1130659200 -25200 0 MST}
+    {1143968400 -21600 1 MDT}
+    {1162108800 -25200 0 MST}
+    {1173603600 -21600 1 MDT}
+    {1194163200 -25200 0 MST}
+    {1205053200 -21600 1 MDT}
+    {1225612800 -25200 0 MST}
+    {1236502800 -21600 1 MDT}
+    {1257062400 -25200 0 MST}
+    {1268557200 -21600 1 MDT}
+    {1289120400 -21600 0 CST}
+    {1300003200 -18000 1 CDT}
+    {1320562800 -21600 0 CST}
+    {1331452800 -18000 1 CDT}
+    {1352012400 -21600 0 CST}
+    {1362902400 -18000 1 CDT}
+    {1383462000 -21600 0 CST}
+    {1394352000 -18000 1 CDT}
+    {1414911600 -21600 0 CST}
+    {1425801600 -18000 1 CDT}
+    {1446361200 -21600 0 CST}
+    {1457856000 -18000 1 CDT}
+    {1478415600 -21600 0 CST}
+    {1489305600 -18000 1 CDT}
+    {1509865200 -21600 0 CST}
+    {1520755200 -18000 1 CDT}
+    {1541314800 -21600 0 CST}
+    {1552204800 -18000 1 CDT}
+    {1572764400 -21600 0 CST}
+    {1583654400 -18000 1 CDT}
+    {1604214000 -21600 0 CST}
+    {1615708800 -18000 1 CDT}
+    {1636268400 -21600 0 CST}
+    {1647158400 -18000 1 CDT}
+    {1667718000 -21600 0 CST}
+    {1678608000 -18000 1 CDT}
+    {1699167600 -21600 0 CST}
+    {1710057600 -18000 1 CDT}
+    {1730617200 -21600 0 CST}
+    {1741507200 -18000 1 CDT}
+    {1762066800 -21600 0 CST}
+    {1772956800 -18000 1 CDT}
+    {1793516400 -21600 0 CST}
+    {1805011200 -18000 1 CDT}
+    {1825570800 -21600 0 CST}
+    {1836460800 -18000 1 CDT}
+    {1857020400 -21600 0 CST}
+    {1867910400 -18000 1 CDT}
+    {1888470000 -21600 0 CST}
+    {1899360000 -18000 1 CDT}
+    {1919919600 -21600 0 CST}
+    {1930809600 -18000 1 CDT}
+    {1951369200 -21600 0 CST}
+    {1962864000 -18000 1 CDT}
+    {1983423600 -21600 0 CST}
+    {1994313600 -18000 1 CDT}
+    {2014873200 -21600 0 CST}
+    {2025763200 -18000 1 CDT}
+    {2046322800 -21600 0 CST}
+    {2057212800 -18000 1 CDT}
+    {2077772400 -21600 0 CST}
+    {2088662400 -18000 1 CDT}
+    {2109222000 -21600 0 CST}
+    {2120112000 -18000 1 CDT}
+    {2140671600 -21600 0 CST}
+    {2152166400 -18000 1 CDT}
+    {2172726000 -21600 0 CST}
+    {2183616000 -18000 1 CDT}
+    {2204175600 -21600 0 CST}
+    {2215065600 -18000 1 CDT}
+    {2235625200 -21600 0 CST}
+    {2246515200 -18000 1 CDT}
+    {2267074800 -21600 0 CST}
+    {2277964800 -18000 1 CDT}
+    {2298524400 -21600 0 CST}
+    {2309414400 -18000 1 CDT}
+    {2329974000 -21600 0 CST}
+    {2341468800 -18000 1 CDT}
+    {2362028400 -21600 0 CST}
+    {2372918400 -18000 1 CDT}
+    {2393478000 -21600 0 CST}
+    {2404368000 -18000 1 CDT}
+    {2424927600 -21600 0 CST}
+    {2435817600 -18000 1 CDT}
+    {2456377200 -21600 0 CST}
+    {2467267200 -18000 1 CDT}
+    {2487826800 -21600 0 CST}
+    {2499321600 -18000 1 CDT}
+    {2519881200 -21600 0 CST}
+    {2530771200 -18000 1 CDT}
+    {2551330800 -21600 0 CST}
+    {2562220800 -18000 1 CDT}
+    {2582780400 -21600 0 CST}
+    {2593670400 -18000 1 CDT}
+    {2614230000 -21600 0 CST}
+    {2625120000 -18000 1 CDT}
+    {2645679600 -21600 0 CST}
+    {2656569600 -18000 1 CDT}
+    {2677129200 -21600 0 CST}
+    {2688624000 -18000 1 CDT}
+    {2709183600 -21600 0 CST}
+    {2720073600 -18000 1 CDT}
+    {2740633200 -21600 0 CST}
+    {2751523200 -18000 1 CDT}
+    {2772082800 -21600 0 CST}
+    {2782972800 -18000 1 CDT}
+    {2803532400 -21600 0 CST}
+    {2814422400 -18000 1 CDT}
+    {2834982000 -21600 0 CST}
+    {2846476800 -18000 1 CDT}
+    {2867036400 -21600 0 CST}
+    {2877926400 -18000 1 CDT}
+    {2898486000 -21600 0 CST}
+    {2909376000 -18000 1 CDT}
+    {2929935600 -21600 0 CST}
+    {2940825600 -18000 1 CDT}
+    {2961385200 -21600 0 CST}
+    {2972275200 -18000 1 CDT}
+    {2992834800 -21600 0 CST}
+    {3003724800 -18000 1 CDT}
+    {3024284400 -21600 0 CST}
+    {3035779200 -18000 1 CDT}
+    {3056338800 -21600 0 CST}
+    {3067228800 -18000 1 CDT}
+    {3087788400 -21600 0 CST}
+    {3098678400 -18000 1 CDT}
+    {3119238000 -21600 0 CST}
+    {3130128000 -18000 1 CDT}
+    {3150687600 -21600 0 CST}
+    {3161577600 -18000 1 CDT}
+    {3182137200 -21600 0 CST}
+    {3193027200 -18000 1 CDT}
+    {3213586800 -21600 0 CST}
+    {3225081600 -18000 1 CDT}
+    {3245641200 -21600 0 CST}
+    {3256531200 -18000 1 CDT}
+    {3277090800 -21600 0 CST}
+    {3287980800 -18000 1 CDT}
+    {3308540400 -21600 0 CST}
+    {3319430400 -18000 1 CDT}
+    {3339990000 -21600 0 CST}
+    {3350880000 -18000 1 CDT}
+    {3371439600 -21600 0 CST}
+    {3382934400 -18000 1 CDT}
+    {3403494000 -21600 0 CST}
+    {3414384000 -18000 1 CDT}
+    {3434943600 -21600 0 CST}
+    {3445833600 -18000 1 CDT}
+    {3466393200 -21600 0 CST}
+    {3477283200 -18000 1 CDT}
+    {3497842800 -21600 0 CST}
+    {3508732800 -18000 1 CDT}
+    {3529292400 -21600 0 CST}
+    {3540182400 -18000 1 CDT}
+    {3560742000 -21600 0 CST}
+    {3572236800 -18000 1 CDT}
+    {3592796400 -21600 0 CST}
+    {3603686400 -18000 1 CDT}
+    {3624246000 -21600 0 CST}
+    {3635136000 -18000 1 CDT}
+    {3655695600 -21600 0 CST}
+    {3666585600 -18000 1 CDT}
+    {3687145200 -21600 0 CST}
+    {3698035200 -18000 1 CDT}
+    {3718594800 -21600 0 CST}
+    {3730089600 -18000 1 CDT}
+    {3750649200 -21600 0 CST}
+    {3761539200 -18000 1 CDT}
+    {3782098800 -21600 0 CST}
+    {3792988800 -18000 1 CDT}
+    {3813548400 -21600 0 CST}
+    {3824438400 -18000 1 CDT}
+    {3844998000 -21600 0 CST}
+    {3855888000 -18000 1 CDT}
+    {3876447600 -21600 0 CST}
+    {3887337600 -18000 1 CDT}
+    {3907897200 -21600 0 CST}
+    {3919392000 -18000 1 CDT}
+    {3939951600 -21600 0 CST}
+    {3950841600 -18000 1 CDT}
+    {3971401200 -21600 0 CST}
+    {3982291200 -18000 1 CDT}
+    {4002850800 -21600 0 CST}
+    {4013740800 -18000 1 CDT}
+    {4034300400 -21600 0 CST}
+    {4045190400 -18000 1 CDT}
+    {4065750000 -21600 0 CST}
+    {4076640000 -18000 1 CDT}
+    {4097199600 -21600 0 CST}
+}
diff --git a/library/tzdata/America/North_Dakota/Center b/library/tzdata/America/North_Dakota/Center
new file mode 100644
index 0000000..30782f7
--- /dev/null
+++ b/library/tzdata/America/North_Dakota/Center
@@ -0,0 +1,279 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/North_Dakota/Center) {
+    {-9223372036854775808 -24312 0 LMT}
+    {-2717643600 -25200 0 MST}
+    {-1633273200 -21600 1 MDT}
+    {-1615132800 -25200 0 MST}
+    {-1601823600 -21600 1 MDT}
+    {-1583683200 -25200 0 MST}
+    {-880210800 -21600 1 MWT}
+    {-769395600 -21600 1 MPT}
+    {-765388800 -25200 0 MST}
+    {-84380400 -21600 1 MDT}
+    {-68659200 -25200 0 MST}
+    {-52930800 -21600 1 MDT}
+    {-37209600 -25200 0 MST}
+    {-21481200 -21600 1 MDT}
+    {-5760000 -25200 0 MST}
+    {9968400 -21600 1 MDT}
+    {25689600 -25200 0 MST}
+    {41418000 -21600 1 MDT}
+    {57744000 -25200 0 MST}
+    {73472400 -21600 1 MDT}
+    {89193600 -25200 0 MST}
+    {104922000 -21600 1 MDT}
+    {120643200 -25200 0 MST}
+    {126694800 -21600 1 MDT}
+    {152092800 -25200 0 MST}
+    {162378000 -21600 1 MDT}
+    {183542400 -25200 0 MST}
+    {199270800 -21600 1 MDT}
+    {215596800 -25200 0 MST}
+    {230720400 -21600 1 MDT}
+    {247046400 -25200 0 MST}
+    {262774800 -21600 1 MDT}
+    {278496000 -25200 0 MST}
+    {294224400 -21600 1 MDT}
+    {309945600 -25200 0 MST}
+    {325674000 -21600 1 MDT}
+    {341395200 -25200 0 MST}
+    {357123600 -21600 1 MDT}
+    {372844800 -25200 0 MST}
+    {388573200 -21600 1 MDT}
+    {404899200 -25200 0 MST}
+    {420022800 -21600 1 MDT}
+    {436348800 -25200 0 MST}
+    {452077200 -21600 1 MDT}
+    {467798400 -25200 0 MST}
+    {483526800 -21600 1 MDT}
+    {499248000 -25200 0 MST}
+    {514976400 -21600 1 MDT}
+    {530697600 -25200 0 MST}
+    {544611600 -21600 1 MDT}
+    {562147200 -25200 0 MST}
+    {576061200 -21600 1 MDT}
+    {594201600 -25200 0 MST}
+    {607510800 -21600 1 MDT}
+    {625651200 -25200 0 MST}
+    {638960400 -21600 1 MDT}
+    {657100800 -25200 0 MST}
+    {671014800 -21600 1 MDT}
+    {688550400 -25200 0 MST}
+    {702464400 -21600 1 MDT}
+    {720003600 -21600 0 CST}
+    {733910400 -18000 1 CDT}
+    {752050800 -21600 0 CST}
+    {765360000 -18000 1 CDT}
+    {783500400 -21600 0 CST}
+    {796809600 -18000 1 CDT}
+    {814950000 -21600 0 CST}
+    {828864000 -18000 1 CDT}
+    {846399600 -21600 0 CST}
+    {860313600 -18000 1 CDT}
+    {877849200 -21600 0 CST}
+    {891763200 -18000 1 CDT}
+    {909298800 -21600 0 CST}
+    {923212800 -18000 1 CDT}
+    {941353200 -21600 0 CST}
+    {954662400 -18000 1 CDT}
+    {972802800 -21600 0 CST}
+    {986112000 -18000 1 CDT}
+    {1004252400 -21600 0 CST}
+    {1018166400 -18000 1 CDT}
+    {1035702000 -21600 0 CST}
+    {1049616000 -18000 1 CDT}
+    {1067151600 -21600 0 CST}
+    {1081065600 -18000 1 CDT}
+    {1099206000 -21600 0 CST}
+    {1112515200 -18000 1 CDT}
+    {1130655600 -21600 0 CST}
+    {1143964800 -18000 1 CDT}
+    {1162105200 -21600 0 CST}
+    {1173600000 -18000 1 CDT}
+    {1194159600 -21600 0 CST}
+    {1205049600 -18000 1 CDT}
+    {1225609200 -21600 0 CST}
+    {1236499200 -18000 1 CDT}
+    {1257058800 -21600 0 CST}
+    {1268553600 -18000 1 CDT}
+    {1289113200 -21600 0 CST}
+    {1300003200 -18000 1 CDT}
+    {1320562800 -21600 0 CST}
+    {1331452800 -18000 1 CDT}
+    {1352012400 -21600 0 CST}
+    {1362902400 -18000 1 CDT}
+    {1383462000 -21600 0 CST}
+    {1394352000 -18000 1 CDT}
+    {1414911600 -21600 0 CST}
+    {1425801600 -18000 1 CDT}
+    {1446361200 -21600 0 CST}
+    {1457856000 -18000 1 CDT}
+    {1478415600 -21600 0 CST}
+    {1489305600 -18000 1 CDT}
+    {1509865200 -21600 0 CST}
+    {1520755200 -18000 1 CDT}
+    {1541314800 -21600 0 CST}
+    {1552204800 -18000 1 CDT}
+    {1572764400 -21600 0 CST}
+    {1583654400 -18000 1 CDT}
+    {1604214000 -21600 0 CST}
+    {1615708800 -18000 1 CDT}
+    {1636268400 -21600 0 CST}
+    {1647158400 -18000 1 CDT}
+    {1667718000 -21600 0 CST}
+    {1678608000 -18000 1 CDT}
+    {1699167600 -21600 0 CST}
+    {1710057600 -18000 1 CDT}
+    {1730617200 -21600 0 CST}
+    {1741507200 -18000 1 CDT}
+    {1762066800 -21600 0 CST}
+    {1772956800 -18000 1 CDT}
+    {1793516400 -21600 0 CST}
+    {1805011200 -18000 1 CDT}
+    {1825570800 -21600 0 CST}
+    {1836460800 -18000 1 CDT}
+    {1857020400 -21600 0 CST}
+    {1867910400 -18000 1 CDT}
+    {1888470000 -21600 0 CST}
+    {1899360000 -18000 1 CDT}
+    {1919919600 -21600 0 CST}
+    {1930809600 -18000 1 CDT}
+    {1951369200 -21600 0 CST}
+    {1962864000 -18000 1 CDT}
+    {1983423600 -21600 0 CST}
+    {1994313600 -18000 1 CDT}
+    {2014873200 -21600 0 CST}
+    {2025763200 -18000 1 CDT}
+    {2046322800 -21600 0 CST}
+    {2057212800 -18000 1 CDT}
+    {2077772400 -21600 0 CST}
+    {2088662400 -18000 1 CDT}
+    {2109222000 -21600 0 CST}
+    {2120112000 -18000 1 CDT}
+    {2140671600 -21600 0 CST}
+    {2152166400 -18000 1 CDT}
+    {2172726000 -21600 0 CST}
+    {2183616000 -18000 1 CDT}
+    {2204175600 -21600 0 CST}
+    {2215065600 -18000 1 CDT}
+    {2235625200 -21600 0 CST}
+    {2246515200 -18000 1 CDT}
+    {2267074800 -21600 0 CST}
+    {2277964800 -18000 1 CDT}
+    {2298524400 -21600 0 CST}
+    {2309414400 -18000 1 CDT}
+    {2329974000 -21600 0 CST}
+    {2341468800 -18000 1 CDT}
+    {2362028400 -21600 0 CST}
+    {2372918400 -18000 1 CDT}
+    {2393478000 -21600 0 CST}
+    {2404368000 -18000 1 CDT}
+    {2424927600 -21600 0 CST}
+    {2435817600 -18000 1 CDT}
+    {2456377200 -21600 0 CST}
+    {2467267200 -18000 1 CDT}
+    {2487826800 -21600 0 CST}
+    {2499321600 -18000 1 CDT}
+    {2519881200 -21600 0 CST}
+    {2530771200 -18000 1 CDT}
+    {2551330800 -21600 0 CST}
+    {2562220800 -18000 1 CDT}
+    {2582780400 -21600 0 CST}
+    {2593670400 -18000 1 CDT}
+    {2614230000 -21600 0 CST}
+    {2625120000 -18000 1 CDT}
+    {2645679600 -21600 0 CST}
+    {2656569600 -18000 1 CDT}
+    {2677129200 -21600 0 CST}
+    {2688624000 -18000 1 CDT}
+    {2709183600 -21600 0 CST}
+    {2720073600 -18000 1 CDT}
+    {2740633200 -21600 0 CST}
+    {2751523200 -18000 1 CDT}
+    {2772082800 -21600 0 CST}
+    {2782972800 -18000 1 CDT}
+    {2803532400 -21600 0 CST}
+    {2814422400 -18000 1 CDT}
+    {2834982000 -21600 0 CST}
+    {2846476800 -18000 1 CDT}
+    {2867036400 -21600 0 CST}
+    {2877926400 -18000 1 CDT}
+    {2898486000 -21600 0 CST}
+    {2909376000 -18000 1 CDT}
+    {2929935600 -21600 0 CST}
+    {2940825600 -18000 1 CDT}
+    {2961385200 -21600 0 CST}
+    {2972275200 -18000 1 CDT}
+    {2992834800 -21600 0 CST}
+    {3003724800 -18000 1 CDT}
+    {3024284400 -21600 0 CST}
+    {3035779200 -18000 1 CDT}
+    {3056338800 -21600 0 CST}
+    {3067228800 -18000 1 CDT}
+    {3087788400 -21600 0 CST}
+    {3098678400 -18000 1 CDT}
+    {3119238000 -21600 0 CST}
+    {3130128000 -18000 1 CDT}
+    {3150687600 -21600 0 CST}
+    {3161577600 -18000 1 CDT}
+    {3182137200 -21600 0 CST}
+    {3193027200 -18000 1 CDT}
+    {3213586800 -21600 0 CST}
+    {3225081600 -18000 1 CDT}
+    {3245641200 -21600 0 CST}
+    {3256531200 -18000 1 CDT}
+    {3277090800 -21600 0 CST}
+    {3287980800 -18000 1 CDT}
+    {3308540400 -21600 0 CST}
+    {3319430400 -18000 1 CDT}
+    {3339990000 -21600 0 CST}
+    {3350880000 -18000 1 CDT}
+    {3371439600 -21600 0 CST}
+    {3382934400 -18000 1 CDT}
+    {3403494000 -21600 0 CST}
+    {3414384000 -18000 1 CDT}
+    {3434943600 -21600 0 CST}
+    {3445833600 -18000 1 CDT}
+    {3466393200 -21600 0 CST}
+    {3477283200 -18000 1 CDT}
+    {3497842800 -21600 0 CST}
+    {3508732800 -18000 1 CDT}
+    {3529292400 -21600 0 CST}
+    {3540182400 -18000 1 CDT}
+    {3560742000 -21600 0 CST}
+    {3572236800 -18000 1 CDT}
+    {3592796400 -21600 0 CST}
+    {3603686400 -18000 1 CDT}
+    {3624246000 -21600 0 CST}
+    {3635136000 -18000 1 CDT}
+    {3655695600 -21600 0 CST}
+    {3666585600 -18000 1 CDT}
+    {3687145200 -21600 0 CST}
+    {3698035200 -18000 1 CDT}
+    {3718594800 -21600 0 CST}
+    {3730089600 -18000 1 CDT}
+    {3750649200 -21600 0 CST}
+    {3761539200 -18000 1 CDT}
+    {3782098800 -21600 0 CST}
+    {3792988800 -18000 1 CDT}
+    {3813548400 -21600 0 CST}
+    {3824438400 -18000 1 CDT}
+    {3844998000 -21600 0 CST}
+    {3855888000 -18000 1 CDT}
+    {3876447600 -21600 0 CST}
+    {3887337600 -18000 1 CDT}
+    {3907897200 -21600 0 CST}
+    {3919392000 -18000 1 CDT}
+    {3939951600 -21600 0 CST}
+    {3950841600 -18000 1 CDT}
+    {3971401200 -21600 0 CST}
+    {3982291200 -18000 1 CDT}
+    {4002850800 -21600 0 CST}
+    {4013740800 -18000 1 CDT}
+    {4034300400 -21600 0 CST}
+    {4045190400 -18000 1 CDT}
+    {4065750000 -21600 0 CST}
+    {4076640000 -18000 1 CDT}
+    {4097199600 -21600 0 CST}
+}
diff --git a/library/tzdata/America/North_Dakota/New_Salem b/library/tzdata/America/North_Dakota/New_Salem
new file mode 100644
index 0000000..5a9d229
--- /dev/null
+++ b/library/tzdata/America/North_Dakota/New_Salem
@@ -0,0 +1,279 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/North_Dakota/New_Salem) {
+    {-9223372036854775808 -24339 0 LMT}
+    {-2717643600 -25200 0 MST}
+    {-1633273200 -21600 1 MDT}
+    {-1615132800 -25200 0 MST}
+    {-1601823600 -21600 1 MDT}
+    {-1583683200 -25200 0 MST}
+    {-880210800 -21600 1 MWT}
+    {-769395600 -21600 1 MPT}
+    {-765388800 -25200 0 MST}
+    {-84380400 -21600 1 MDT}
+    {-68659200 -25200 0 MST}
+    {-52930800 -21600 1 MDT}
+    {-37209600 -25200 0 MST}
+    {-21481200 -21600 1 MDT}
+    {-5760000 -25200 0 MST}
+    {9968400 -21600 1 MDT}
+    {25689600 -25200 0 MST}
+    {41418000 -21600 1 MDT}
+    {57744000 -25200 0 MST}
+    {73472400 -21600 1 MDT}
+    {89193600 -25200 0 MST}
+    {104922000 -21600 1 MDT}
+    {120643200 -25200 0 MST}
+    {126694800 -21600 1 MDT}
+    {152092800 -25200 0 MST}
+    {162378000 -21600 1 MDT}
+    {183542400 -25200 0 MST}
+    {199270800 -21600 1 MDT}
+    {215596800 -25200 0 MST}
+    {230720400 -21600 1 MDT}
+    {247046400 -25200 0 MST}
+    {262774800 -21600 1 MDT}
+    {278496000 -25200 0 MST}
+    {294224400 -21600 1 MDT}
+    {309945600 -25200 0 MST}
+    {325674000 -21600 1 MDT}
+    {341395200 -25200 0 MST}
+    {357123600 -21600 1 MDT}
+    {372844800 -25200 0 MST}
+    {388573200 -21600 1 MDT}
+    {404899200 -25200 0 MST}
+    {420022800 -21600 1 MDT}
+    {436348800 -25200 0 MST}
+    {452077200 -21600 1 MDT}
+    {467798400 -25200 0 MST}
+    {483526800 -21600 1 MDT}
+    {499248000 -25200 0 MST}
+    {514976400 -21600 1 MDT}
+    {530697600 -25200 0 MST}
+    {544611600 -21600 1 MDT}
+    {562147200 -25200 0 MST}
+    {576061200 -21600 1 MDT}
+    {594201600 -25200 0 MST}
+    {607510800 -21600 1 MDT}
+    {625651200 -25200 0 MST}
+    {638960400 -21600 1 MDT}
+    {657100800 -25200 0 MST}
+    {671014800 -21600 1 MDT}
+    {688550400 -25200 0 MST}
+    {702464400 -21600 1 MDT}
+    {720000000 -25200 0 MST}
+    {733914000 -21600 1 MDT}
+    {752054400 -25200 0 MST}
+    {765363600 -21600 1 MDT}
+    {783504000 -25200 0 MST}
+    {796813200 -21600 1 MDT}
+    {814953600 -25200 0 MST}
+    {828867600 -21600 1 MDT}
+    {846403200 -25200 0 MST}
+    {860317200 -21600 1 MDT}
+    {877852800 -25200 0 MST}
+    {891766800 -21600 1 MDT}
+    {909302400 -25200 0 MST}
+    {923216400 -21600 1 MDT}
+    {941356800 -25200 0 MST}
+    {954666000 -21600 1 MDT}
+    {972806400 -25200 0 MST}
+    {986115600 -21600 1 MDT}
+    {1004256000 -25200 0 MST}
+    {1018170000 -21600 1 MDT}
+    {1035705600 -25200 0 MST}
+    {1049619600 -21600 1 MDT}
+    {1067158800 -21600 0 CST}
+    {1081065600 -18000 1 CDT}
+    {1099206000 -21600 0 CST}
+    {1112515200 -18000 1 CDT}
+    {1130655600 -21600 0 CST}
+    {1143964800 -18000 1 CDT}
+    {1162105200 -21600 0 CST}
+    {1173600000 -18000 1 CDT}
+    {1194159600 -21600 0 CST}
+    {1205049600 -18000 1 CDT}
+    {1225609200 -21600 0 CST}
+    {1236499200 -18000 1 CDT}
+    {1257058800 -21600 0 CST}
+    {1268553600 -18000 1 CDT}
+    {1289113200 -21600 0 CST}
+    {1300003200 -18000 1 CDT}
+    {1320562800 -21600 0 CST}
+    {1331452800 -18000 1 CDT}
+    {1352012400 -21600 0 CST}
+    {1362902400 -18000 1 CDT}
+    {1383462000 -21600 0 CST}
+    {1394352000 -18000 1 CDT}
+    {1414911600 -21600 0 CST}
+    {1425801600 -18000 1 CDT}
+    {1446361200 -21600 0 CST}
+    {1457856000 -18000 1 CDT}
+    {1478415600 -21600 0 CST}
+    {1489305600 -18000 1 CDT}
+    {1509865200 -21600 0 CST}
+    {1520755200 -18000 1 CDT}
+    {1541314800 -21600 0 CST}
+    {1552204800 -18000 1 CDT}
+    {1572764400 -21600 0 CST}
+    {1583654400 -18000 1 CDT}
+    {1604214000 -21600 0 CST}
+    {1615708800 -18000 1 CDT}
+    {1636268400 -21600 0 CST}
+    {1647158400 -18000 1 CDT}
+    {1667718000 -21600 0 CST}
+    {1678608000 -18000 1 CDT}
+    {1699167600 -21600 0 CST}
+    {1710057600 -18000 1 CDT}
+    {1730617200 -21600 0 CST}
+    {1741507200 -18000 1 CDT}
+    {1762066800 -21600 0 CST}
+    {1772956800 -18000 1 CDT}
+    {1793516400 -21600 0 CST}
+    {1805011200 -18000 1 CDT}
+    {1825570800 -21600 0 CST}
+    {1836460800 -18000 1 CDT}
+    {1857020400 -21600 0 CST}
+    {1867910400 -18000 1 CDT}
+    {1888470000 -21600 0 CST}
+    {1899360000 -18000 1 CDT}
+    {1919919600 -21600 0 CST}
+    {1930809600 -18000 1 CDT}
+    {1951369200 -21600 0 CST}
+    {1962864000 -18000 1 CDT}
+    {1983423600 -21600 0 CST}
+    {1994313600 -18000 1 CDT}
+    {2014873200 -21600 0 CST}
+    {2025763200 -18000 1 CDT}
+    {2046322800 -21600 0 CST}
+    {2057212800 -18000 1 CDT}
+    {2077772400 -21600 0 CST}
+    {2088662400 -18000 1 CDT}
+    {2109222000 -21600 0 CST}
+    {2120112000 -18000 1 CDT}
+    {2140671600 -21600 0 CST}
+    {2152166400 -18000 1 CDT}
+    {2172726000 -21600 0 CST}
+    {2183616000 -18000 1 CDT}
+    {2204175600 -21600 0 CST}
+    {2215065600 -18000 1 CDT}
+    {2235625200 -21600 0 CST}
+    {2246515200 -18000 1 CDT}
+    {2267074800 -21600 0 CST}
+    {2277964800 -18000 1 CDT}
+    {2298524400 -21600 0 CST}
+    {2309414400 -18000 1 CDT}
+    {2329974000 -21600 0 CST}
+    {2341468800 -18000 1 CDT}
+    {2362028400 -21600 0 CST}
+    {2372918400 -18000 1 CDT}
+    {2393478000 -21600 0 CST}
+    {2404368000 -18000 1 CDT}
+    {2424927600 -21600 0 CST}
+    {2435817600 -18000 1 CDT}
+    {2456377200 -21600 0 CST}
+    {2467267200 -18000 1 CDT}
+    {2487826800 -21600 0 CST}
+    {2499321600 -18000 1 CDT}
+    {2519881200 -21600 0 CST}
+    {2530771200 -18000 1 CDT}
+    {2551330800 -21600 0 CST}
+    {2562220800 -18000 1 CDT}
+    {2582780400 -21600 0 CST}
+    {2593670400 -18000 1 CDT}
+    {2614230000 -21600 0 CST}
+    {2625120000 -18000 1 CDT}
+    {2645679600 -21600 0 CST}
+    {2656569600 -18000 1 CDT}
+    {2677129200 -21600 0 CST}
+    {2688624000 -18000 1 CDT}
+    {2709183600 -21600 0 CST}
+    {2720073600 -18000 1 CDT}
+    {2740633200 -21600 0 CST}
+    {2751523200 -18000 1 CDT}
+    {2772082800 -21600 0 CST}
+    {2782972800 -18000 1 CDT}
+    {2803532400 -21600 0 CST}
+    {2814422400 -18000 1 CDT}
+    {2834982000 -21600 0 CST}
+    {2846476800 -18000 1 CDT}
+    {2867036400 -21600 0 CST}
+    {2877926400 -18000 1 CDT}
+    {2898486000 -21600 0 CST}
+    {2909376000 -18000 1 CDT}
+    {2929935600 -21600 0 CST}
+    {2940825600 -18000 1 CDT}
+    {2961385200 -21600 0 CST}
+    {2972275200 -18000 1 CDT}
+    {2992834800 -21600 0 CST}
+    {3003724800 -18000 1 CDT}
+    {3024284400 -21600 0 CST}
+    {3035779200 -18000 1 CDT}
+    {3056338800 -21600 0 CST}
+    {3067228800 -18000 1 CDT}
+    {3087788400 -21600 0 CST}
+    {3098678400 -18000 1 CDT}
+    {3119238000 -21600 0 CST}
+    {3130128000 -18000 1 CDT}
+    {3150687600 -21600 0 CST}
+    {3161577600 -18000 1 CDT}
+    {3182137200 -21600 0 CST}
+    {3193027200 -18000 1 CDT}
+    {3213586800 -21600 0 CST}
+    {3225081600 -18000 1 CDT}
+    {3245641200 -21600 0 CST}
+    {3256531200 -18000 1 CDT}
+    {3277090800 -21600 0 CST}
+    {3287980800 -18000 1 CDT}
+    {3308540400 -21600 0 CST}
+    {3319430400 -18000 1 CDT}
+    {3339990000 -21600 0 CST}
+    {3350880000 -18000 1 CDT}
+    {3371439600 -21600 0 CST}
+    {3382934400 -18000 1 CDT}
+    {3403494000 -21600 0 CST}
+    {3414384000 -18000 1 CDT}
+    {3434943600 -21600 0 CST}
+    {3445833600 -18000 1 CDT}
+    {3466393200 -21600 0 CST}
+    {3477283200 -18000 1 CDT}
+    {3497842800 -21600 0 CST}
+    {3508732800 -18000 1 CDT}
+    {3529292400 -21600 0 CST}
+    {3540182400 -18000 1 CDT}
+    {3560742000 -21600 0 CST}
+    {3572236800 -18000 1 CDT}
+    {3592796400 -21600 0 CST}
+    {3603686400 -18000 1 CDT}
+    {3624246000 -21600 0 CST}
+    {3635136000 -18000 1 CDT}
+    {3655695600 -21600 0 CST}
+    {3666585600 -18000 1 CDT}
+    {3687145200 -21600 0 CST}
+    {3698035200 -18000 1 CDT}
+    {3718594800 -21600 0 CST}
+    {3730089600 -18000 1 CDT}
+    {3750649200 -21600 0 CST}
+    {3761539200 -18000 1 CDT}
+    {3782098800 -21600 0 CST}
+    {3792988800 -18000 1 CDT}
+    {3813548400 -21600 0 CST}
+    {3824438400 -18000 1 CDT}
+    {3844998000 -21600 0 CST}
+    {3855888000 -18000 1 CDT}
+    {3876447600 -21600 0 CST}
+    {3887337600 -18000 1 CDT}
+    {3907897200 -21600 0 CST}
+    {3919392000 -18000 1 CDT}
+    {3939951600 -21600 0 CST}
+    {3950841600 -18000 1 CDT}
+    {3971401200 -21600 0 CST}
+    {3982291200 -18000 1 CDT}
+    {4002850800 -21600 0 CST}
+    {4013740800 -18000 1 CDT}
+    {4034300400 -21600 0 CST}
+    {4045190400 -18000 1 CDT}
+    {4065750000 -21600 0 CST}
+    {4076640000 -18000 1 CDT}
+    {4097199600 -21600 0 CST}
+}
diff --git a/library/tzdata/America/Ojinaga b/library/tzdata/America/Ojinaga
new file mode 100644
index 0000000..1172708
--- /dev/null
+++ b/library/tzdata/America/Ojinaga
@@ -0,0 +1,222 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Ojinaga) {
+    {-9223372036854775808 -25060 0 LMT}
+    {-1514739600 -25200 0 MST}
+    {-1343066400 -21600 0 CST}
+    {-1234807200 -25200 0 MST}
+    {-1220292000 -21600 0 CST}
+    {-1207159200 -25200 0 MST}
+    {-1191344400 -21600 0 CST}
+    {820476000 -21600 0 CST}
+    {828864000 -18000 1 CDT}
+    {846399600 -21600 0 CST}
+    {860313600 -18000 1 CDT}
+    {877849200 -21600 0 CST}
+    {883634400 -21600 0 CST}
+    {891766800 -21600 0 MDT}
+    {909302400 -25200 0 MST}
+    {923216400 -21600 1 MDT}
+    {941356800 -25200 0 MST}
+    {954666000 -21600 1 MDT}
+    {972806400 -25200 0 MST}
+    {989139600 -21600 1 MDT}
+    {1001836800 -25200 0 MST}
+    {1018170000 -21600 1 MDT}
+    {1035705600 -25200 0 MST}
+    {1049619600 -21600 1 MDT}
+    {1067155200 -25200 0 MST}
+    {1081069200 -21600 1 MDT}
+    {1099209600 -25200 0 MST}
+    {1112518800 -21600 1 MDT}
+    {1130659200 -25200 0 MST}
+    {1143968400 -21600 1 MDT}
+    {1162108800 -25200 0 MST}
+    {1175418000 -21600 1 MDT}
+    {1193558400 -25200 0 MST}
+    {1207472400 -21600 1 MDT}
+    {1225008000 -25200 0 MST}
+    {1238922000 -21600 1 MDT}
+    {1256457600 -25200 0 MST}
+    {1262329200 -25200 0 MST}
+    {1268557200 -21600 1 MDT}
+    {1289116800 -25200 0 MST}
+    {1300006800 -21600 1 MDT}
+    {1320566400 -25200 0 MST}
+    {1331456400 -21600 1 MDT}
+    {1352016000 -25200 0 MST}
+    {1362906000 -21600 1 MDT}
+    {1383465600 -25200 0 MST}
+    {1394355600 -21600 1 MDT}
+    {1414915200 -25200 0 MST}
+    {1425805200 -21600 1 MDT}
+    {1446364800 -25200 0 MST}
+    {1457859600 -21600 1 MDT}
+    {1478419200 -25200 0 MST}
+    {1489309200 -21600 1 MDT}
+    {1509868800 -25200 0 MST}
+    {1520758800 -21600 1 MDT}
+    {1541318400 -25200 0 MST}
+    {1552208400 -21600 1 MDT}
+    {1572768000 -25200 0 MST}
+    {1583658000 -21600 1 MDT}
+    {1604217600 -25200 0 MST}
+    {1615712400 -21600 1 MDT}
+    {1636272000 -25200 0 MST}
+    {1647162000 -21600 1 MDT}
+    {1667721600 -25200 0 MST}
+    {1678611600 -21600 1 MDT}
+    {1699171200 -25200 0 MST}
+    {1710061200 -21600 1 MDT}
+    {1730620800 -25200 0 MST}
+    {1741510800 -21600 1 MDT}
+    {1762070400 -25200 0 MST}
+    {1772960400 -21600 1 MDT}
+    {1793520000 -25200 0 MST}
+    {1805014800 -21600 1 MDT}
+    {1825574400 -25200 0 MST}
+    {1836464400 -21600 1 MDT}
+    {1857024000 -25200 0 MST}
+    {1867914000 -21600 1 MDT}
+    {1888473600 -25200 0 MST}
+    {1899363600 -21600 1 MDT}
+    {1919923200 -25200 0 MST}
+    {1930813200 -21600 1 MDT}
+    {1951372800 -25200 0 MST}
+    {1962867600 -21600 1 MDT}
+    {1983427200 -25200 0 MST}
+    {1994317200 -21600 1 MDT}
+    {2014876800 -25200 0 MST}
+    {2025766800 -21600 1 MDT}
+    {2046326400 -25200 0 MST}
+    {2057216400 -21600 1 MDT}
+    {2077776000 -25200 0 MST}
+    {2088666000 -21600 1 MDT}
+    {2109225600 -25200 0 MST}
+    {2120115600 -21600 1 MDT}
+    {2140675200 -25200 0 MST}
+    {2152170000 -21600 1 MDT}
+    {2172729600 -25200 0 MST}
+    {2183619600 -21600 1 MDT}
+    {2204179200 -25200 0 MST}
+    {2215069200 -21600 1 MDT}
+    {2235628800 -25200 0 MST}
+    {2246518800 -21600 1 MDT}
+    {2267078400 -25200 0 MST}
+    {2277968400 -21600 1 MDT}
+    {2298528000 -25200 0 MST}
+    {2309418000 -21600 1 MDT}
+    {2329977600 -25200 0 MST}
+    {2341472400 -21600 1 MDT}
+    {2362032000 -25200 0 MST}
+    {2372922000 -21600 1 MDT}
+    {2393481600 -25200 0 MST}
+    {2404371600 -21600 1 MDT}
+    {2424931200 -25200 0 MST}
+    {2435821200 -21600 1 MDT}
+    {2456380800 -25200 0 MST}
+    {2467270800 -21600 1 MDT}
+    {2487830400 -25200 0 MST}
+    {2499325200 -21600 1 MDT}
+    {2519884800 -25200 0 MST}
+    {2530774800 -21600 1 MDT}
+    {2551334400 -25200 0 MST}
+    {2562224400 -21600 1 MDT}
+    {2582784000 -25200 0 MST}
+    {2593674000 -21600 1 MDT}
+    {2614233600 -25200 0 MST}
+    {2625123600 -21600 1 MDT}
+    {2645683200 -25200 0 MST}
+    {2656573200 -21600 1 MDT}
+    {2677132800 -25200 0 MST}
+    {2688627600 -21600 1 MDT}
+    {2709187200 -25200 0 MST}
+    {2720077200 -21600 1 MDT}
+    {2740636800 -25200 0 MST}
+    {2751526800 -21600 1 MDT}
+    {2772086400 -25200 0 MST}
+    {2782976400 -21600 1 MDT}
+    {2803536000 -25200 0 MST}
+    {2814426000 -21600 1 MDT}
+    {2834985600 -25200 0 MST}
+    {2846480400 -21600 1 MDT}
+    {2867040000 -25200 0 MST}
+    {2877930000 -21600 1 MDT}
+    {2898489600 -25200 0 MST}
+    {2909379600 -21600 1 MDT}
+    {2929939200 -25200 0 MST}
+    {2940829200 -21600 1 MDT}
+    {2961388800 -25200 0 MST}
+    {2972278800 -21600 1 MDT}
+    {2992838400 -25200 0 MST}
+    {3003728400 -21600 1 MDT}
+    {3024288000 -25200 0 MST}
+    {3035782800 -21600 1 MDT}
+    {3056342400 -25200 0 MST}
+    {3067232400 -21600 1 MDT}
+    {3087792000 -25200 0 MST}
+    {3098682000 -21600 1 MDT}
+    {3119241600 -25200 0 MST}
+    {3130131600 -21600 1 MDT}
+    {3150691200 -25200 0 MST}
+    {3161581200 -21600 1 MDT}
+    {3182140800 -25200 0 MST}
+    {3193030800 -21600 1 MDT}
+    {3213590400 -25200 0 MST}
+    {3225085200 -21600 1 MDT}
+    {3245644800 -25200 0 MST}
+    {3256534800 -21600 1 MDT}
+    {3277094400 -25200 0 MST}
+    {3287984400 -21600 1 MDT}
+    {3308544000 -25200 0 MST}
+    {3319434000 -21600 1 MDT}
+    {3339993600 -25200 0 MST}
+    {3350883600 -21600 1 MDT}
+    {3371443200 -25200 0 MST}
+    {3382938000 -21600 1 MDT}
+    {3403497600 -25200 0 MST}
+    {3414387600 -21600 1 MDT}
+    {3434947200 -25200 0 MST}
+    {3445837200 -21600 1 MDT}
+    {3466396800 -25200 0 MST}
+    {3477286800 -21600 1 MDT}
+    {3497846400 -25200 0 MST}
+    {3508736400 -21600 1 MDT}
+    {3529296000 -25200 0 MST}
+    {3540186000 -21600 1 MDT}
+    {3560745600 -25200 0 MST}
+    {3572240400 -21600 1 MDT}
+    {3592800000 -25200 0 MST}
+    {3603690000 -21600 1 MDT}
+    {3624249600 -25200 0 MST}
+    {3635139600 -21600 1 MDT}
+    {3655699200 -25200 0 MST}
+    {3666589200 -21600 1 MDT}
+    {3687148800 -25200 0 MST}
+    {3698038800 -21600 1 MDT}
+    {3718598400 -25200 0 MST}
+    {3730093200 -21600 1 MDT}
+    {3750652800 -25200 0 MST}
+    {3761542800 -21600 1 MDT}
+    {3782102400 -25200 0 MST}
+    {3792992400 -21600 1 MDT}
+    {3813552000 -25200 0 MST}
+    {3824442000 -21600 1 MDT}
+    {3845001600 -25200 0 MST}
+    {3855891600 -21600 1 MDT}
+    {3876451200 -25200 0 MST}
+    {3887341200 -21600 1 MDT}
+    {3907900800 -25200 0 MST}
+    {3919395600 -21600 1 MDT}
+    {3939955200 -25200 0 MST}
+    {3950845200 -21600 1 MDT}
+    {3971404800 -25200 0 MST}
+    {3982294800 -21600 1 MDT}
+    {4002854400 -25200 0 MST}
+    {4013744400 -21600 1 MDT}
+    {4034304000 -25200 0 MST}
+    {4045194000 -21600 1 MDT}
+    {4065753600 -25200 0 MST}
+    {4076643600 -21600 1 MDT}
+    {4097203200 -25200 0 MST}
+}
diff --git a/library/tzdata/America/Panama b/library/tzdata/America/Panama
new file mode 100644
index 0000000..3006785
--- /dev/null
+++ b/library/tzdata/America/Panama
@@ -0,0 +1,7 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Panama) {
+    {-9223372036854775808 -19088 0 LMT}
+    {-2524502512 -19176 0 CMT}
+    {-1946918424 -18000 0 EST}
+}
diff --git a/library/tzdata/America/Pangnirtung b/library/tzdata/America/Pangnirtung
new file mode 100644
index 0000000..14d8516
--- /dev/null
+++ b/library/tzdata/America/Pangnirtung
@@ -0,0 +1,252 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Pangnirtung) {
+    {-9223372036854775808 0 0 -00}
+    {-1546300800 -14400 0 AST}
+    {-880221600 -10800 1 AWT}
+    {-769395600 -10800 1 APT}
+    {-765399600 -14400 0 AST}
+    {-147902400 -7200 1 ADDT}
+    {-131572800 -14400 0 AST}
+    {325663200 -10800 1 ADT}
+    {341384400 -14400 0 AST}
+    {357112800 -10800 1 ADT}
+    {372834000 -14400 0 AST}
+    {388562400 -10800 1 ADT}
+    {404888400 -14400 0 AST}
+    {420012000 -10800 1 ADT}
+    {436338000 -14400 0 AST}
+    {452066400 -10800 1 ADT}
+    {467787600 -14400 0 AST}
+    {483516000 -10800 1 ADT}
+    {499237200 -14400 0 AST}
+    {514965600 -10800 1 ADT}
+    {530686800 -14400 0 AST}
+    {544600800 -10800 1 ADT}
+    {562136400 -14400 0 AST}
+    {576050400 -10800 1 ADT}
+    {594190800 -14400 0 AST}
+    {607500000 -10800 1 ADT}
+    {625640400 -14400 0 AST}
+    {638949600 -10800 1 ADT}
+    {657090000 -14400 0 AST}
+    {671004000 -10800 1 ADT}
+    {688539600 -14400 0 AST}
+    {702453600 -10800 1 ADT}
+    {719989200 -14400 0 AST}
+    {733903200 -10800 1 ADT}
+    {752043600 -14400 0 AST}
+    {765352800 -10800 1 ADT}
+    {783493200 -14400 0 AST}
+    {796802400 -18000 0 EST}
+    {796806000 -14400 1 EDT}
+    {814946400 -18000 0 EST}
+    {828860400 -14400 1 EDT}
+    {846396000 -18000 0 EST}
+    {860310000 -14400 1 EDT}
+    {877845600 -18000 0 EST}
+    {891759600 -14400 1 EDT}
+    {909295200 -18000 0 EST}
+    {923209200 -14400 1 EDT}
+    {941353200 -21600 0 CST}
+    {954662400 -18000 1 CDT}
+    {972806400 -18000 0 EST}
+    {986108400 -14400 1 EDT}
+    {1004248800 -18000 0 EST}
+    {1018162800 -14400 1 EDT}
+    {1035698400 -18000 0 EST}
+    {1049612400 -14400 1 EDT}
+    {1067148000 -18000 0 EST}
+    {1081062000 -14400 1 EDT}
+    {1099202400 -18000 0 EST}
+    {1112511600 -14400 1 EDT}
+    {1130652000 -18000 0 EST}
+    {1143961200 -14400 1 EDT}
+    {1162101600 -18000 0 EST}
+    {1173596400 -14400 1 EDT}
+    {1194156000 -18000 0 EST}
+    {1205046000 -14400 1 EDT}
+    {1225605600 -18000 0 EST}
+    {1236495600 -14400 1 EDT}
+    {1257055200 -18000 0 EST}
+    {1268550000 -14400 1 EDT}
+    {1289109600 -18000 0 EST}
+    {1299999600 -14400 1 EDT}
+    {1320559200 -18000 0 EST}
+    {1331449200 -14400 1 EDT}
+    {1352008800 -18000 0 EST}
+    {1362898800 -14400 1 EDT}
+    {1383458400 -18000 0 EST}
+    {1394348400 -14400 1 EDT}
+    {1414908000 -18000 0 EST}
+    {1425798000 -14400 1 EDT}
+    {1446357600 -18000 0 EST}
+    {1457852400 -14400 1 EDT}
+    {1478412000 -18000 0 EST}
+    {1489302000 -14400 1 EDT}
+    {1509861600 -18000 0 EST}
+    {1520751600 -14400 1 EDT}
+    {1541311200 -18000 0 EST}
+    {1552201200 -14400 1 EDT}
+    {1572760800 -18000 0 EST}
+    {1583650800 -14400 1 EDT}
+    {1604210400 -18000 0 EST}
+    {1615705200 -14400 1 EDT}
+    {1636264800 -18000 0 EST}
+    {1647154800 -14400 1 EDT}
+    {1667714400 -18000 0 EST}
+    {1678604400 -14400 1 EDT}
+    {1699164000 -18000 0 EST}
+    {1710054000 -14400 1 EDT}
+    {1730613600 -18000 0 EST}
+    {1741503600 -14400 1 EDT}
+    {1762063200 -18000 0 EST}
+    {1772953200 -14400 1 EDT}
+    {1793512800 -18000 0 EST}
+    {1805007600 -14400 1 EDT}
+    {1825567200 -18000 0 EST}
+    {1836457200 -14400 1 EDT}
+    {1857016800 -18000 0 EST}
+    {1867906800 -14400 1 EDT}
+    {1888466400 -18000 0 EST}
+    {1899356400 -14400 1 EDT}
+    {1919916000 -18000 0 EST}
+    {1930806000 -14400 1 EDT}
+    {1951365600 -18000 0 EST}
+    {1962860400 -14400 1 EDT}
+    {1983420000 -18000 0 EST}
+    {1994310000 -14400 1 EDT}
+    {2014869600 -18000 0 EST}
+    {2025759600 -14400 1 EDT}
+    {2046319200 -18000 0 EST}
+    {2057209200 -14400 1 EDT}
+    {2077768800 -18000 0 EST}
+    {2088658800 -14400 1 EDT}
+    {2109218400 -18000 0 EST}
+    {2120108400 -14400 1 EDT}
+    {2140668000 -18000 0 EST}
+    {2152162800 -14400 1 EDT}
+    {2172722400 -18000 0 EST}
+    {2183612400 -14400 1 EDT}
+    {2204172000 -18000 0 EST}
+    {2215062000 -14400 1 EDT}
+    {2235621600 -18000 0 EST}
+    {2246511600 -14400 1 EDT}
+    {2267071200 -18000 0 EST}
+    {2277961200 -14400 1 EDT}
+    {2298520800 -18000 0 EST}
+    {2309410800 -14400 1 EDT}
+    {2329970400 -18000 0 EST}
+    {2341465200 -14400 1 EDT}
+    {2362024800 -18000 0 EST}
+    {2372914800 -14400 1 EDT}
+    {2393474400 -18000 0 EST}
+    {2404364400 -14400 1 EDT}
+    {2424924000 -18000 0 EST}
+    {2435814000 -14400 1 EDT}
+    {2456373600 -18000 0 EST}
+    {2467263600 -14400 1 EDT}
+    {2487823200 -18000 0 EST}
+    {2499318000 -14400 1 EDT}
+    {2519877600 -18000 0 EST}
+    {2530767600 -14400 1 EDT}
+    {2551327200 -18000 0 EST}
+    {2562217200 -14400 1 EDT}
+    {2582776800 -18000 0 EST}
+    {2593666800 -14400 1 EDT}
+    {2614226400 -18000 0 EST}
+    {2625116400 -14400 1 EDT}
+    {2645676000 -18000 0 EST}
+    {2656566000 -14400 1 EDT}
+    {2677125600 -18000 0 EST}
+    {2688620400 -14400 1 EDT}
+    {2709180000 -18000 0 EST}
+    {2720070000 -14400 1 EDT}
+    {2740629600 -18000 0 EST}
+    {2751519600 -14400 1 EDT}
+    {2772079200 -18000 0 EST}
+    {2782969200 -14400 1 EDT}
+    {2803528800 -18000 0 EST}
+    {2814418800 -14400 1 EDT}
+    {2834978400 -18000 0 EST}
+    {2846473200 -14400 1 EDT}
+    {2867032800 -18000 0 EST}
+    {2877922800 -14400 1 EDT}
+    {2898482400 -18000 0 EST}
+    {2909372400 -14400 1 EDT}
+    {2929932000 -18000 0 EST}
+    {2940822000 -14400 1 EDT}
+    {2961381600 -18000 0 EST}
+    {2972271600 -14400 1 EDT}
+    {2992831200 -18000 0 EST}
+    {3003721200 -14400 1 EDT}
+    {3024280800 -18000 0 EST}
+    {3035775600 -14400 1 EDT}
+    {3056335200 -18000 0 EST}
+    {3067225200 -14400 1 EDT}
+    {3087784800 -18000 0 EST}
+    {3098674800 -14400 1 EDT}
+    {3119234400 -18000 0 EST}
+    {3130124400 -14400 1 EDT}
+    {3150684000 -18000 0 EST}
+    {3161574000 -14400 1 EDT}
+    {3182133600 -18000 0 EST}
+    {3193023600 -14400 1 EDT}
+    {3213583200 -18000 0 EST}
+    {3225078000 -14400 1 EDT}
+    {3245637600 -18000 0 EST}
+    {3256527600 -14400 1 EDT}
+    {3277087200 -18000 0 EST}
+    {3287977200 -14400 1 EDT}
+    {3308536800 -18000 0 EST}
+    {3319426800 -14400 1 EDT}
+    {3339986400 -18000 0 EST}
+    {3350876400 -14400 1 EDT}
+    {3371436000 -18000 0 EST}
+    {3382930800 -14400 1 EDT}
+    {3403490400 -18000 0 EST}
+    {3414380400 -14400 1 EDT}
+    {3434940000 -18000 0 EST}
+    {3445830000 -14400 1 EDT}
+    {3466389600 -18000 0 EST}
+    {3477279600 -14400 1 EDT}
+    {3497839200 -18000 0 EST}
+    {3508729200 -14400 1 EDT}
+    {3529288800 -18000 0 EST}
+    {3540178800 -14400 1 EDT}
+    {3560738400 -18000 0 EST}
+    {3572233200 -14400 1 EDT}
+    {3592792800 -18000 0 EST}
+    {3603682800 -14400 1 EDT}
+    {3624242400 -18000 0 EST}
+    {3635132400 -14400 1 EDT}
+    {3655692000 -18000 0 EST}
+    {3666582000 -14400 1 EDT}
+    {3687141600 -18000 0 EST}
+    {3698031600 -14400 1 EDT}
+    {3718591200 -18000 0 EST}
+    {3730086000 -14400 1 EDT}
+    {3750645600 -18000 0 EST}
+    {3761535600 -14400 1 EDT}
+    {3782095200 -18000 0 EST}
+    {3792985200 -14400 1 EDT}
+    {3813544800 -18000 0 EST}
+    {3824434800 -14400 1 EDT}
+    {3844994400 -18000 0 EST}
+    {3855884400 -14400 1 EDT}
+    {3876444000 -18000 0 EST}
+    {3887334000 -14400 1 EDT}
+    {3907893600 -18000 0 EST}
+    {3919388400 -14400 1 EDT}
+    {3939948000 -18000 0 EST}
+    {3950838000 -14400 1 EDT}
+    {3971397600 -18000 0 EST}
+    {3982287600 -14400 1 EDT}
+    {4002847200 -18000 0 EST}
+    {4013737200 -14400 1 EDT}
+    {4034296800 -18000 0 EST}
+    {4045186800 -14400 1 EDT}
+    {4065746400 -18000 0 EST}
+    {4076636400 -14400 1 EDT}
+    {4097196000 -18000 0 EST}
+}
diff --git a/library/tzdata/America/Paramaribo b/library/tzdata/America/Paramaribo
new file mode 100644
index 0000000..d15f5c7
--- /dev/null
+++ b/library/tzdata/America/Paramaribo
@@ -0,0 +1,10 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Paramaribo) {
+    {-9223372036854775808 -13240 0 LMT}
+    {-1861906760 -13252 0 PMT}
+    {-1104524348 -13236 0 PMT}
+    {-765317964 -12600 0 NEGT}
+    {185686200 -12600 0 SRT}
+    {465449400 -10800 0 SRT}
+}
diff --git a/library/tzdata/America/Phoenix b/library/tzdata/America/Phoenix
new file mode 100644
index 0000000..3d37bb4
--- /dev/null
+++ b/library/tzdata/America/Phoenix
@@ -0,0 +1,17 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Phoenix) {
+    {-9223372036854775808 -26898 0 LMT}
+    {-2717643600 -25200 0 MST}
+    {-1633273200 -21600 1 MDT}
+    {-1615132800 -25200 0 MST}
+    {-1601823600 -21600 1 MDT}
+    {-1583683200 -25200 0 MST}
+    {-880210800 -21600 1 MWT}
+    {-820519140 -25200 0 MST}
+    {-796841940 -25200 0 MST}
+    {-94669200 -25200 0 MST}
+    {-84380400 -21600 1 MDT}
+    {-68659200 -25200 0 MST}
+    {-56221200 -25200 0 MST}
+}
diff --git a/library/tzdata/America/Port-au-Prince b/library/tzdata/America/Port-au-Prince
new file mode 100644
index 0000000..b8b60d6
--- /dev/null
+++ b/library/tzdata/America/Port-au-Prince
@@ -0,0 +1,49 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Port-au-Prince) {
+    {-9223372036854775808 -17360 0 LMT}
+    {-2524504240 -17340 0 PPMT}
+    {-1670483460 -18000 0 EST}
+    {421218000 -14400 1 EDT}
+    {436334400 -18000 0 EST}
+    {452062800 -14400 1 EDT}
+    {467784000 -18000 0 EST}
+    {483512400 -14400 1 EDT}
+    {499233600 -18000 0 EST}
+    {514962000 -14400 1 EDT}
+    {530683200 -18000 0 EST}
+    {546411600 -14400 1 EDT}
+    {562132800 -18000 0 EST}
+    {576050400 -14400 1 EDT}
+    {594194400 -18000 0 EST}
+    {607500000 -14400 1 EDT}
+    {625644000 -18000 0 EST}
+    {638949600 -14400 1 EDT}
+    {657093600 -18000 0 EST}
+    {671004000 -14400 1 EDT}
+    {688543200 -18000 0 EST}
+    {702453600 -14400 1 EDT}
+    {719992800 -18000 0 EST}
+    {733903200 -14400 1 EDT}
+    {752047200 -18000 0 EST}
+    {765352800 -14400 1 EDT}
+    {783496800 -18000 0 EST}
+    {796802400 -14400 1 EDT}
+    {814946400 -18000 0 EST}
+    {828856800 -14400 1 EDT}
+    {846396000 -18000 0 EST}
+    {860306400 -14400 1 EDT}
+    {877845600 -18000 0 EST}
+    {1112504400 -14400 1 EDT}
+    {1130644800 -18000 0 EST}
+    {1143954000 -14400 1 EDT}
+    {1162094400 -18000 0 EST}
+    {1331449200 -14400 1 EDT}
+    {1352008800 -18000 0 EST}
+    {1362898800 -14400 1 EDT}
+    {1383458400 -18000 0 EST}
+    {1394348400 -14400 1 EDT}
+    {1414908000 -18000 0 EST}
+    {1425798000 -14400 1 EDT}
+    {1446357600 -18000 0 EST}
+}
diff --git a/library/tzdata/America/Port_of_Spain b/library/tzdata/America/Port_of_Spain
new file mode 100644
index 0000000..c360c87
--- /dev/null
+++ b/library/tzdata/America/Port_of_Spain
@@ -0,0 +1,6 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Port_of_Spain) {
+    {-9223372036854775808 -14764 0 LMT}
+    {-1825098836 -14400 0 AST}
+}
diff --git a/library/tzdata/America/Porto_Acre b/library/tzdata/America/Porto_Acre
new file mode 100644
index 0000000..0626001
--- /dev/null
+++ b/library/tzdata/America/Porto_Acre
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(America/Rio_Branco)]} {
+    LoadTimeZoneFile America/Rio_Branco
+}
+set TZData(:America/Porto_Acre) $TZData(:America/Rio_Branco)
diff --git a/library/tzdata/America/Porto_Velho b/library/tzdata/America/Porto_Velho
new file mode 100644
index 0000000..ce611d2
--- /dev/null
+++ b/library/tzdata/America/Porto_Velho
@@ -0,0 +1,35 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Porto_Velho) {
+    {-9223372036854775808 -15336 0 LMT}
+    {-1767210264 -14400 0 AMT}
+    {-1206954000 -10800 1 AMST}
+    {-1191358800 -14400 0 AMT}
+    {-1175371200 -10800 1 AMST}
+    {-1159822800 -14400 0 AMT}
+    {-633816000 -10800 1 AMST}
+    {-622065600 -14400 0 AMT}
+    {-602280000 -10800 1 AMST}
+    {-591829200 -14400 0 AMT}
+    {-570744000 -10800 1 AMST}
+    {-560206800 -14400 0 AMT}
+    {-539121600 -10800 1 AMST}
+    {-531349200 -14400 0 AMT}
+    {-191361600 -10800 1 AMST}
+    {-184194000 -14400 0 AMT}
+    {-155160000 -10800 1 AMST}
+    {-150066000 -14400 0 AMT}
+    {-128894400 -10800 1 AMST}
+    {-121122000 -14400 0 AMT}
+    {-99950400 -10800 1 AMST}
+    {-89586000 -14400 0 AMT}
+    {-68414400 -10800 1 AMST}
+    {-57963600 -14400 0 AMT}
+    {499752000 -10800 1 AMST}
+    {511239600 -14400 0 AMT}
+    {530596800 -10800 1 AMST}
+    {540270000 -14400 0 AMT}
+    {562132800 -10800 1 AMST}
+    {571201200 -14400 0 AMT}
+    {590036400 -14400 0 AMT}
+}
diff --git a/library/tzdata/America/Puerto_Rico b/library/tzdata/America/Puerto_Rico
new file mode 100644
index 0000000..0d5c9b4
--- /dev/null
+++ b/library/tzdata/America/Puerto_Rico
@@ -0,0 +1,10 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Puerto_Rico) {
+    {-9223372036854775808 -15865 0 LMT}
+    {-2233035335 -14400 0 AST}
+    {-873057600 -10800 0 AWT}
+    {-769395600 -10800 1 APT}
+    {-765399600 -14400 0 AST}
+    {-757368000 -14400 0 AST}
+}
diff --git a/library/tzdata/America/Rainy_River b/library/tzdata/America/Rainy_River
new file mode 100644
index 0000000..a2b11aa
--- /dev/null
+++ b/library/tzdata/America/Rainy_River
@@ -0,0 +1,264 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Rainy_River) {
+    {-9223372036854775808 -22696 0 LMT}
+    {-2366732504 -21600 0 CST}
+    {-1632067200 -18000 1 CDT}
+    {-1615136400 -21600 0 CST}
+    {-923248800 -18000 1 CDT}
+    {-880214400 -18000 0 CWT}
+    {-769395600 -18000 1 CPT}
+    {-765392400 -21600 0 CST}
+    {136368000 -18000 1 CDT}
+    {152089200 -21600 0 CST}
+    {167817600 -18000 1 CDT}
+    {183538800 -21600 0 CST}
+    {199267200 -18000 1 CDT}
+    {215593200 -21600 0 CST}
+    {230716800 -18000 1 CDT}
+    {247042800 -21600 0 CST}
+    {262771200 -18000 1 CDT}
+    {278492400 -21600 0 CST}
+    {294220800 -18000 1 CDT}
+    {309942000 -21600 0 CST}
+    {325670400 -18000 1 CDT}
+    {341391600 -21600 0 CST}
+    {357120000 -18000 1 CDT}
+    {372841200 -21600 0 CST}
+    {388569600 -18000 1 CDT}
+    {404895600 -21600 0 CST}
+    {420019200 -18000 1 CDT}
+    {436345200 -21600 0 CST}
+    {452073600 -18000 1 CDT}
+    {467794800 -21600 0 CST}
+    {483523200 -18000 1 CDT}
+    {499244400 -21600 0 CST}
+    {514972800 -18000 1 CDT}
+    {530694000 -21600 0 CST}
+    {544608000 -18000 1 CDT}
+    {562143600 -21600 0 CST}
+    {576057600 -18000 1 CDT}
+    {594198000 -21600 0 CST}
+    {607507200 -18000 1 CDT}
+    {625647600 -21600 0 CST}
+    {638956800 -18000 1 CDT}
+    {657097200 -21600 0 CST}
+    {671011200 -18000 1 CDT}
+    {688546800 -21600 0 CST}
+    {702460800 -18000 1 CDT}
+    {719996400 -21600 0 CST}
+    {733910400 -18000 1 CDT}
+    {752050800 -21600 0 CST}
+    {765360000 -18000 1 CDT}
+    {783500400 -21600 0 CST}
+    {796809600 -18000 1 CDT}
+    {814950000 -21600 0 CST}
+    {828864000 -18000 1 CDT}
+    {846399600 -21600 0 CST}
+    {860313600 -18000 1 CDT}
+    {877849200 -21600 0 CST}
+    {891763200 -18000 1 CDT}
+    {909298800 -21600 0 CST}
+    {923212800 -18000 1 CDT}
+    {941353200 -21600 0 CST}
+    {954662400 -18000 1 CDT}
+    {972802800 -21600 0 CST}
+    {986112000 -18000 1 CDT}
+    {1004252400 -21600 0 CST}
+    {1018166400 -18000 1 CDT}
+    {1035702000 -21600 0 CST}
+    {1049616000 -18000 1 CDT}
+    {1067151600 -21600 0 CST}
+    {1081065600 -18000 1 CDT}
+    {1099206000 -21600 0 CST}
+    {1112515200 -18000 1 CDT}
+    {1130655600 -21600 0 CST}
+    {1143964800 -18000 1 CDT}
+    {1162105200 -21600 0 CST}
+    {1173600000 -18000 1 CDT}
+    {1194159600 -21600 0 CST}
+    {1205049600 -18000 1 CDT}
+    {1225609200 -21600 0 CST}
+    {1236499200 -18000 1 CDT}
+    {1257058800 -21600 0 CST}
+    {1268553600 -18000 1 CDT}
+    {1289113200 -21600 0 CST}
+    {1300003200 -18000 1 CDT}
+    {1320562800 -21600 0 CST}
+    {1331452800 -18000 1 CDT}
+    {1352012400 -21600 0 CST}
+    {1362902400 -18000 1 CDT}
+    {1383462000 -21600 0 CST}
+    {1394352000 -18000 1 CDT}
+    {1414911600 -21600 0 CST}
+    {1425801600 -18000 1 CDT}
+    {1446361200 -21600 0 CST}
+    {1457856000 -18000 1 CDT}
+    {1478415600 -21600 0 CST}
+    {1489305600 -18000 1 CDT}
+    {1509865200 -21600 0 CST}
+    {1520755200 -18000 1 CDT}
+    {1541314800 -21600 0 CST}
+    {1552204800 -18000 1 CDT}
+    {1572764400 -21600 0 CST}
+    {1583654400 -18000 1 CDT}
+    {1604214000 -21600 0 CST}
+    {1615708800 -18000 1 CDT}
+    {1636268400 -21600 0 CST}
+    {1647158400 -18000 1 CDT}
+    {1667718000 -21600 0 CST}
+    {1678608000 -18000 1 CDT}
+    {1699167600 -21600 0 CST}
+    {1710057600 -18000 1 CDT}
+    {1730617200 -21600 0 CST}
+    {1741507200 -18000 1 CDT}
+    {1762066800 -21600 0 CST}
+    {1772956800 -18000 1 CDT}
+    {1793516400 -21600 0 CST}
+    {1805011200 -18000 1 CDT}
+    {1825570800 -21600 0 CST}
+    {1836460800 -18000 1 CDT}
+    {1857020400 -21600 0 CST}
+    {1867910400 -18000 1 CDT}
+    {1888470000 -21600 0 CST}
+    {1899360000 -18000 1 CDT}
+    {1919919600 -21600 0 CST}
+    {1930809600 -18000 1 CDT}
+    {1951369200 -21600 0 CST}
+    {1962864000 -18000 1 CDT}
+    {1983423600 -21600 0 CST}
+    {1994313600 -18000 1 CDT}
+    {2014873200 -21600 0 CST}
+    {2025763200 -18000 1 CDT}
+    {2046322800 -21600 0 CST}
+    {2057212800 -18000 1 CDT}
+    {2077772400 -21600 0 CST}
+    {2088662400 -18000 1 CDT}
+    {2109222000 -21600 0 CST}
+    {2120112000 -18000 1 CDT}
+    {2140671600 -21600 0 CST}
+    {2152166400 -18000 1 CDT}
+    {2172726000 -21600 0 CST}
+    {2183616000 -18000 1 CDT}
+    {2204175600 -21600 0 CST}
+    {2215065600 -18000 1 CDT}
+    {2235625200 -21600 0 CST}
+    {2246515200 -18000 1 CDT}
+    {2267074800 -21600 0 CST}
+    {2277964800 -18000 1 CDT}
+    {2298524400 -21600 0 CST}
+    {2309414400 -18000 1 CDT}
+    {2329974000 -21600 0 CST}
+    {2341468800 -18000 1 CDT}
+    {2362028400 -21600 0 CST}
+    {2372918400 -18000 1 CDT}
+    {2393478000 -21600 0 CST}
+    {2404368000 -18000 1 CDT}
+    {2424927600 -21600 0 CST}
+    {2435817600 -18000 1 CDT}
+    {2456377200 -21600 0 CST}
+    {2467267200 -18000 1 CDT}
+    {2487826800 -21600 0 CST}
+    {2499321600 -18000 1 CDT}
+    {2519881200 -21600 0 CST}
+    {2530771200 -18000 1 CDT}
+    {2551330800 -21600 0 CST}
+    {2562220800 -18000 1 CDT}
+    {2582780400 -21600 0 CST}
+    {2593670400 -18000 1 CDT}
+    {2614230000 -21600 0 CST}
+    {2625120000 -18000 1 CDT}
+    {2645679600 -21600 0 CST}
+    {2656569600 -18000 1 CDT}
+    {2677129200 -21600 0 CST}
+    {2688624000 -18000 1 CDT}
+    {2709183600 -21600 0 CST}
+    {2720073600 -18000 1 CDT}
+    {2740633200 -21600 0 CST}
+    {2751523200 -18000 1 CDT}
+    {2772082800 -21600 0 CST}
+    {2782972800 -18000 1 CDT}
+    {2803532400 -21600 0 CST}
+    {2814422400 -18000 1 CDT}
+    {2834982000 -21600 0 CST}
+    {2846476800 -18000 1 CDT}
+    {2867036400 -21600 0 CST}
+    {2877926400 -18000 1 CDT}
+    {2898486000 -21600 0 CST}
+    {2909376000 -18000 1 CDT}
+    {2929935600 -21600 0 CST}
+    {2940825600 -18000 1 CDT}
+    {2961385200 -21600 0 CST}
+    {2972275200 -18000 1 CDT}
+    {2992834800 -21600 0 CST}
+    {3003724800 -18000 1 CDT}
+    {3024284400 -21600 0 CST}
+    {3035779200 -18000 1 CDT}
+    {3056338800 -21600 0 CST}
+    {3067228800 -18000 1 CDT}
+    {3087788400 -21600 0 CST}
+    {3098678400 -18000 1 CDT}
+    {3119238000 -21600 0 CST}
+    {3130128000 -18000 1 CDT}
+    {3150687600 -21600 0 CST}
+    {3161577600 -18000 1 CDT}
+    {3182137200 -21600 0 CST}
+    {3193027200 -18000 1 CDT}
+    {3213586800 -21600 0 CST}
+    {3225081600 -18000 1 CDT}
+    {3245641200 -21600 0 CST}
+    {3256531200 -18000 1 CDT}
+    {3277090800 -21600 0 CST}
+    {3287980800 -18000 1 CDT}
+    {3308540400 -21600 0 CST}
+    {3319430400 -18000 1 CDT}
+    {3339990000 -21600 0 CST}
+    {3350880000 -18000 1 CDT}
+    {3371439600 -21600 0 CST}
+    {3382934400 -18000 1 CDT}
+    {3403494000 -21600 0 CST}
+    {3414384000 -18000 1 CDT}
+    {3434943600 -21600 0 CST}
+    {3445833600 -18000 1 CDT}
+    {3466393200 -21600 0 CST}
+    {3477283200 -18000 1 CDT}
+    {3497842800 -21600 0 CST}
+    {3508732800 -18000 1 CDT}
+    {3529292400 -21600 0 CST}
+    {3540182400 -18000 1 CDT}
+    {3560742000 -21600 0 CST}
+    {3572236800 -18000 1 CDT}
+    {3592796400 -21600 0 CST}
+    {3603686400 -18000 1 CDT}
+    {3624246000 -21600 0 CST}
+    {3635136000 -18000 1 CDT}
+    {3655695600 -21600 0 CST}
+    {3666585600 -18000 1 CDT}
+    {3687145200 -21600 0 CST}
+    {3698035200 -18000 1 CDT}
+    {3718594800 -21600 0 CST}
+    {3730089600 -18000 1 CDT}
+    {3750649200 -21600 0 CST}
+    {3761539200 -18000 1 CDT}
+    {3782098800 -21600 0 CST}
+    {3792988800 -18000 1 CDT}
+    {3813548400 -21600 0 CST}
+    {3824438400 -18000 1 CDT}
+    {3844998000 -21600 0 CST}
+    {3855888000 -18000 1 CDT}
+    {3876447600 -21600 0 CST}
+    {3887337600 -18000 1 CDT}
+    {3907897200 -21600 0 CST}
+    {3919392000 -18000 1 CDT}
+    {3939951600 -21600 0 CST}
+    {3950841600 -18000 1 CDT}
+    {3971401200 -21600 0 CST}
+    {3982291200 -18000 1 CDT}
+    {4002850800 -21600 0 CST}
+    {4013740800 -18000 1 CDT}
+    {4034300400 -21600 0 CST}
+    {4045190400 -18000 1 CDT}
+    {4065750000 -21600 0 CST}
+    {4076640000 -18000 1 CDT}
+    {4097199600 -21600 0 CST}
+}
diff --git a/library/tzdata/America/Rankin_Inlet b/library/tzdata/America/Rankin_Inlet
new file mode 100644
index 0000000..9ce9f8d
--- /dev/null
+++ b/library/tzdata/America/Rankin_Inlet
@@ -0,0 +1,248 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Rankin_Inlet) {
+    {-9223372036854775808 0 0 -00}
+    {-410227200 -21600 0 CST}
+    {-147895200 -14400 1 CDDT}
+    {-131565600 -21600 0 CST}
+    {325670400 -18000 1 CDT}
+    {341391600 -21600 0 CST}
+    {357120000 -18000 1 CDT}
+    {372841200 -21600 0 CST}
+    {388569600 -18000 1 CDT}
+    {404895600 -21600 0 CST}
+    {420019200 -18000 1 CDT}
+    {436345200 -21600 0 CST}
+    {452073600 -18000 1 CDT}
+    {467794800 -21600 0 CST}
+    {483523200 -18000 1 CDT}
+    {499244400 -21600 0 CST}
+    {514972800 -18000 1 CDT}
+    {530694000 -21600 0 CST}
+    {544608000 -18000 1 CDT}
+    {562143600 -21600 0 CST}
+    {576057600 -18000 1 CDT}
+    {594198000 -21600 0 CST}
+    {607507200 -18000 1 CDT}
+    {625647600 -21600 0 CST}
+    {638956800 -18000 1 CDT}
+    {657097200 -21600 0 CST}
+    {671011200 -18000 1 CDT}
+    {688546800 -21600 0 CST}
+    {702460800 -18000 1 CDT}
+    {719996400 -21600 0 CST}
+    {733910400 -18000 1 CDT}
+    {752050800 -21600 0 CST}
+    {765360000 -18000 1 CDT}
+    {783500400 -21600 0 CST}
+    {796809600 -18000 1 CDT}
+    {814950000 -21600 0 CST}
+    {828864000 -18000 1 CDT}
+    {846399600 -21600 0 CST}
+    {860313600 -18000 1 CDT}
+    {877849200 -21600 0 CST}
+    {891763200 -18000 1 CDT}
+    {909298800 -21600 0 CST}
+    {923212800 -18000 1 CDT}
+    {941353200 -21600 0 CST}
+    {954662400 -18000 1 CDT}
+    {972806400 -18000 0 EST}
+    {986112000 -18000 0 CDT}
+    {1004252400 -21600 0 CST}
+    {1018166400 -18000 1 CDT}
+    {1035702000 -21600 0 CST}
+    {1049616000 -18000 1 CDT}
+    {1067151600 -21600 0 CST}
+    {1081065600 -18000 1 CDT}
+    {1099206000 -21600 0 CST}
+    {1112515200 -18000 1 CDT}
+    {1130655600 -21600 0 CST}
+    {1143964800 -18000 1 CDT}
+    {1162105200 -21600 0 CST}
+    {1173600000 -18000 1 CDT}
+    {1194159600 -21600 0 CST}
+    {1205049600 -18000 1 CDT}
+    {1225609200 -21600 0 CST}
+    {1236499200 -18000 1 CDT}
+    {1257058800 -21600 0 CST}
+    {1268553600 -18000 1 CDT}
+    {1289113200 -21600 0 CST}
+    {1300003200 -18000 1 CDT}
+    {1320562800 -21600 0 CST}
+    {1331452800 -18000 1 CDT}
+    {1352012400 -21600 0 CST}
+    {1362902400 -18000 1 CDT}
+    {1383462000 -21600 0 CST}
+    {1394352000 -18000 1 CDT}
+    {1414911600 -21600 0 CST}
+    {1425801600 -18000 1 CDT}
+    {1446361200 -21600 0 CST}
+    {1457856000 -18000 1 CDT}
+    {1478415600 -21600 0 CST}
+    {1489305600 -18000 1 CDT}
+    {1509865200 -21600 0 CST}
+    {1520755200 -18000 1 CDT}
+    {1541314800 -21600 0 CST}
+    {1552204800 -18000 1 CDT}
+    {1572764400 -21600 0 CST}
+    {1583654400 -18000 1 CDT}
+    {1604214000 -21600 0 CST}
+    {1615708800 -18000 1 CDT}
+    {1636268400 -21600 0 CST}
+    {1647158400 -18000 1 CDT}
+    {1667718000 -21600 0 CST}
+    {1678608000 -18000 1 CDT}
+    {1699167600 -21600 0 CST}
+    {1710057600 -18000 1 CDT}
+    {1730617200 -21600 0 CST}
+    {1741507200 -18000 1 CDT}
+    {1762066800 -21600 0 CST}
+    {1772956800 -18000 1 CDT}
+    {1793516400 -21600 0 CST}
+    {1805011200 -18000 1 CDT}
+    {1825570800 -21600 0 CST}
+    {1836460800 -18000 1 CDT}
+    {1857020400 -21600 0 CST}
+    {1867910400 -18000 1 CDT}
+    {1888470000 -21600 0 CST}
+    {1899360000 -18000 1 CDT}
+    {1919919600 -21600 0 CST}
+    {1930809600 -18000 1 CDT}
+    {1951369200 -21600 0 CST}
+    {1962864000 -18000 1 CDT}
+    {1983423600 -21600 0 CST}
+    {1994313600 -18000 1 CDT}
+    {2014873200 -21600 0 CST}
+    {2025763200 -18000 1 CDT}
+    {2046322800 -21600 0 CST}
+    {2057212800 -18000 1 CDT}
+    {2077772400 -21600 0 CST}
+    {2088662400 -18000 1 CDT}
+    {2109222000 -21600 0 CST}
+    {2120112000 -18000 1 CDT}
+    {2140671600 -21600 0 CST}
+    {2152166400 -18000 1 CDT}
+    {2172726000 -21600 0 CST}
+    {2183616000 -18000 1 CDT}
+    {2204175600 -21600 0 CST}
+    {2215065600 -18000 1 CDT}
+    {2235625200 -21600 0 CST}
+    {2246515200 -18000 1 CDT}
+    {2267074800 -21600 0 CST}
+    {2277964800 -18000 1 CDT}
+    {2298524400 -21600 0 CST}
+    {2309414400 -18000 1 CDT}
+    {2329974000 -21600 0 CST}
+    {2341468800 -18000 1 CDT}
+    {2362028400 -21600 0 CST}
+    {2372918400 -18000 1 CDT}
+    {2393478000 -21600 0 CST}
+    {2404368000 -18000 1 CDT}
+    {2424927600 -21600 0 CST}
+    {2435817600 -18000 1 CDT}
+    {2456377200 -21600 0 CST}
+    {2467267200 -18000 1 CDT}
+    {2487826800 -21600 0 CST}
+    {2499321600 -18000 1 CDT}
+    {2519881200 -21600 0 CST}
+    {2530771200 -18000 1 CDT}
+    {2551330800 -21600 0 CST}
+    {2562220800 -18000 1 CDT}
+    {2582780400 -21600 0 CST}
+    {2593670400 -18000 1 CDT}
+    {2614230000 -21600 0 CST}
+    {2625120000 -18000 1 CDT}
+    {2645679600 -21600 0 CST}
+    {2656569600 -18000 1 CDT}
+    {2677129200 -21600 0 CST}
+    {2688624000 -18000 1 CDT}
+    {2709183600 -21600 0 CST}
+    {2720073600 -18000 1 CDT}
+    {2740633200 -21600 0 CST}
+    {2751523200 -18000 1 CDT}
+    {2772082800 -21600 0 CST}
+    {2782972800 -18000 1 CDT}
+    {2803532400 -21600 0 CST}
+    {2814422400 -18000 1 CDT}
+    {2834982000 -21600 0 CST}
+    {2846476800 -18000 1 CDT}
+    {2867036400 -21600 0 CST}
+    {2877926400 -18000 1 CDT}
+    {2898486000 -21600 0 CST}
+    {2909376000 -18000 1 CDT}
+    {2929935600 -21600 0 CST}
+    {2940825600 -18000 1 CDT}
+    {2961385200 -21600 0 CST}
+    {2972275200 -18000 1 CDT}
+    {2992834800 -21600 0 CST}
+    {3003724800 -18000 1 CDT}
+    {3024284400 -21600 0 CST}
+    {3035779200 -18000 1 CDT}
+    {3056338800 -21600 0 CST}
+    {3067228800 -18000 1 CDT}
+    {3087788400 -21600 0 CST}
+    {3098678400 -18000 1 CDT}
+    {3119238000 -21600 0 CST}
+    {3130128000 -18000 1 CDT}
+    {3150687600 -21600 0 CST}
+    {3161577600 -18000 1 CDT}
+    {3182137200 -21600 0 CST}
+    {3193027200 -18000 1 CDT}
+    {3213586800 -21600 0 CST}
+    {3225081600 -18000 1 CDT}
+    {3245641200 -21600 0 CST}
+    {3256531200 -18000 1 CDT}
+    {3277090800 -21600 0 CST}
+    {3287980800 -18000 1 CDT}
+    {3308540400 -21600 0 CST}
+    {3319430400 -18000 1 CDT}
+    {3339990000 -21600 0 CST}
+    {3350880000 -18000 1 CDT}
+    {3371439600 -21600 0 CST}
+    {3382934400 -18000 1 CDT}
+    {3403494000 -21600 0 CST}
+    {3414384000 -18000 1 CDT}
+    {3434943600 -21600 0 CST}
+    {3445833600 -18000 1 CDT}
+    {3466393200 -21600 0 CST}
+    {3477283200 -18000 1 CDT}
+    {3497842800 -21600 0 CST}
+    {3508732800 -18000 1 CDT}
+    {3529292400 -21600 0 CST}
+    {3540182400 -18000 1 CDT}
+    {3560742000 -21600 0 CST}
+    {3572236800 -18000 1 CDT}
+    {3592796400 -21600 0 CST}
+    {3603686400 -18000 1 CDT}
+    {3624246000 -21600 0 CST}
+    {3635136000 -18000 1 CDT}
+    {3655695600 -21600 0 CST}
+    {3666585600 -18000 1 CDT}
+    {3687145200 -21600 0 CST}
+    {3698035200 -18000 1 CDT}
+    {3718594800 -21600 0 CST}
+    {3730089600 -18000 1 CDT}
+    {3750649200 -21600 0 CST}
+    {3761539200 -18000 1 CDT}
+    {3782098800 -21600 0 CST}
+    {3792988800 -18000 1 CDT}
+    {3813548400 -21600 0 CST}
+    {3824438400 -18000 1 CDT}
+    {3844998000 -21600 0 CST}
+    {3855888000 -18000 1 CDT}
+    {3876447600 -21600 0 CST}
+    {3887337600 -18000 1 CDT}
+    {3907897200 -21600 0 CST}
+    {3919392000 -18000 1 CDT}
+    {3939951600 -21600 0 CST}
+    {3950841600 -18000 1 CDT}
+    {3971401200 -21600 0 CST}
+    {3982291200 -18000 1 CDT}
+    {4002850800 -21600 0 CST}
+    {4013740800 -18000 1 CDT}
+    {4034300400 -21600 0 CST}
+    {4045190400 -18000 1 CDT}
+    {4065750000 -21600 0 CST}
+    {4076640000 -18000 1 CDT}
+    {4097199600 -21600 0 CST}
+}
diff --git a/library/tzdata/America/Recife b/library/tzdata/America/Recife
new file mode 100644
index 0000000..f6ae00e
--- /dev/null
+++ b/library/tzdata/America/Recife
@@ -0,0 +1,48 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Recife) {
+    {-9223372036854775808 -8376 0 LMT}
+    {-1767217224 -10800 0 BRT}
+    {-1206957600 -7200 1 BRST}
+    {-1191362400 -10800 0 BRT}
+    {-1175374800 -7200 1 BRST}
+    {-1159826400 -10800 0 BRT}
+    {-633819600 -7200 1 BRST}
+    {-622069200 -10800 0 BRT}
+    {-602283600 -7200 1 BRST}
+    {-591832800 -10800 0 BRT}
+    {-570747600 -7200 1 BRST}
+    {-560210400 -10800 0 BRT}
+    {-539125200 -7200 1 BRST}
+    {-531352800 -10800 0 BRT}
+    {-191365200 -7200 1 BRST}
+    {-184197600 -10800 0 BRT}
+    {-155163600 -7200 1 BRST}
+    {-150069600 -10800 0 BRT}
+    {-128898000 -7200 1 BRST}
+    {-121125600 -10800 0 BRT}
+    {-99954000 -7200 1 BRST}
+    {-89589600 -10800 0 BRT}
+    {-68418000 -7200 1 BRST}
+    {-57967200 -10800 0 BRT}
+    {499748400 -7200 1 BRST}
+    {511236000 -10800 0 BRT}
+    {530593200 -7200 1 BRST}
+    {540266400 -10800 0 BRT}
+    {562129200 -7200 1 BRST}
+    {571197600 -10800 0 BRT}
+    {592974000 -7200 1 BRST}
+    {602042400 -10800 0 BRT}
+    {624423600 -7200 1 BRST}
+    {634701600 -10800 0 BRT}
+    {653536800 -10800 0 BRT}
+    {938660400 -10800 0 BRT}
+    {938919600 -7200 1 BRST}
+    {951616800 -10800 0 BRT}
+    {970974000 -7200 1 BRST}
+    {971575200 -10800 0 BRT}
+    {1000350000 -10800 0 BRT}
+    {1003028400 -7200 1 BRST}
+    {1013911200 -10800 0 BRT}
+    {1033437600 -10800 0 BRT}
+}
diff --git a/library/tzdata/America/Regina b/library/tzdata/America/Regina
new file mode 100644
index 0000000..e42b5be
--- /dev/null
+++ b/library/tzdata/America/Regina
@@ -0,0 +1,58 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Regina) {
+    {-9223372036854775808 -25116 0 LMT}
+    {-2030202084 -25200 0 MST}
+    {-1632063600 -21600 1 MDT}
+    {-1615132800 -25200 0 MST}
+    {-1251651600 -21600 1 MDT}
+    {-1238349600 -25200 0 MST}
+    {-1220202000 -21600 1 MDT}
+    {-1206900000 -25200 0 MST}
+    {-1188752400 -21600 1 MDT}
+    {-1175450400 -25200 0 MST}
+    {-1156698000 -21600 1 MDT}
+    {-1144000800 -25200 0 MST}
+    {-1125248400 -21600 1 MDT}
+    {-1111946400 -25200 0 MST}
+    {-1032714000 -21600 1 MDT}
+    {-1016992800 -25200 0 MST}
+    {-1001264400 -21600 1 MDT}
+    {-986148000 -25200 0 MST}
+    {-969814800 -21600 1 MDT}
+    {-954093600 -25200 0 MST}
+    {-937760400 -21600 1 MDT}
+    {-922039200 -25200 0 MST}
+    {-906310800 -21600 1 MDT}
+    {-890589600 -25200 0 MST}
+    {-880210800 -21600 1 MWT}
+    {-769395600 -21600 1 MPT}
+    {-765388800 -25200 0 MST}
+    {-748450800 -21600 1 MDT}
+    {-732729600 -25200 0 MST}
+    {-715791600 -21600 1 MDT}
+    {-702489600 -25200 0 MST}
+    {-684342000 -21600 1 MDT}
+    {-671040000 -25200 0 MST}
+    {-652892400 -21600 1 MDT}
+    {-639590400 -25200 0 MST}
+    {-620838000 -21600 1 MDT}
+    {-608140800 -25200 0 MST}
+    {-589388400 -21600 1 MDT}
+    {-576086400 -25200 0 MST}
+    {-557938800 -21600 1 MDT}
+    {-544636800 -25200 0 MST}
+    {-526489200 -21600 1 MDT}
+    {-513187200 -25200 0 MST}
+    {-495039600 -21600 1 MDT}
+    {-481737600 -25200 0 MST}
+    {-463590000 -21600 1 MDT}
+    {-450288000 -25200 0 MST}
+    {-431535600 -21600 1 MDT}
+    {-418233600 -25200 0 MST}
+    {-400086000 -21600 1 MDT}
+    {-386784000 -25200 0 MST}
+    {-337186800 -21600 1 MDT}
+    {-321465600 -25200 0 MST}
+    {-305737200 -21600 0 CST}
+}
diff --git a/library/tzdata/America/Resolute b/library/tzdata/America/Resolute
new file mode 100644
index 0000000..a9881b4
--- /dev/null
+++ b/library/tzdata/America/Resolute
@@ -0,0 +1,248 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Resolute) {
+    {-9223372036854775808 0 0 -00}
+    {-704937600 -21600 0 CST}
+    {-147895200 -14400 1 CDDT}
+    {-131565600 -21600 0 CST}
+    {325670400 -18000 1 CDT}
+    {341391600 -21600 0 CST}
+    {357120000 -18000 1 CDT}
+    {372841200 -21600 0 CST}
+    {388569600 -18000 1 CDT}
+    {404895600 -21600 0 CST}
+    {420019200 -18000 1 CDT}
+    {436345200 -21600 0 CST}
+    {452073600 -18000 1 CDT}
+    {467794800 -21600 0 CST}
+    {483523200 -18000 1 CDT}
+    {499244400 -21600 0 CST}
+    {514972800 -18000 1 CDT}
+    {530694000 -21600 0 CST}
+    {544608000 -18000 1 CDT}
+    {562143600 -21600 0 CST}
+    {576057600 -18000 1 CDT}
+    {594198000 -21600 0 CST}
+    {607507200 -18000 1 CDT}
+    {625647600 -21600 0 CST}
+    {638956800 -18000 1 CDT}
+    {657097200 -21600 0 CST}
+    {671011200 -18000 1 CDT}
+    {688546800 -21600 0 CST}
+    {702460800 -18000 1 CDT}
+    {719996400 -21600 0 CST}
+    {733910400 -18000 1 CDT}
+    {752050800 -21600 0 CST}
+    {765360000 -18000 1 CDT}
+    {783500400 -21600 0 CST}
+    {796809600 -18000 1 CDT}
+    {814950000 -21600 0 CST}
+    {828864000 -18000 1 CDT}
+    {846399600 -21600 0 CST}
+    {860313600 -18000 1 CDT}
+    {877849200 -21600 0 CST}
+    {891763200 -18000 1 CDT}
+    {909298800 -21600 0 CST}
+    {923212800 -18000 1 CDT}
+    {941353200 -21600 0 CST}
+    {954662400 -18000 1 CDT}
+    {972806400 -18000 0 EST}
+    {986112000 -18000 0 CDT}
+    {1004252400 -21600 0 CST}
+    {1018166400 -18000 1 CDT}
+    {1035702000 -21600 0 CST}
+    {1049616000 -18000 1 CDT}
+    {1067151600 -21600 0 CST}
+    {1081065600 -18000 1 CDT}
+    {1099206000 -21600 0 CST}
+    {1112515200 -18000 1 CDT}
+    {1130655600 -21600 0 CST}
+    {1143964800 -18000 1 CDT}
+    {1162108800 -18000 0 EST}
+    {1173600000 -18000 0 CDT}
+    {1194159600 -21600 0 CST}
+    {1205049600 -18000 1 CDT}
+    {1225609200 -21600 0 CST}
+    {1236499200 -18000 1 CDT}
+    {1257058800 -21600 0 CST}
+    {1268553600 -18000 1 CDT}
+    {1289113200 -21600 0 CST}
+    {1300003200 -18000 1 CDT}
+    {1320562800 -21600 0 CST}
+    {1331452800 -18000 1 CDT}
+    {1352012400 -21600 0 CST}
+    {1362902400 -18000 1 CDT}
+    {1383462000 -21600 0 CST}
+    {1394352000 -18000 1 CDT}
+    {1414911600 -21600 0 CST}
+    {1425801600 -18000 1 CDT}
+    {1446361200 -21600 0 CST}
+    {1457856000 -18000 1 CDT}
+    {1478415600 -21600 0 CST}
+    {1489305600 -18000 1 CDT}
+    {1509865200 -21600 0 CST}
+    {1520755200 -18000 1 CDT}
+    {1541314800 -21600 0 CST}
+    {1552204800 -18000 1 CDT}
+    {1572764400 -21600 0 CST}
+    {1583654400 -18000 1 CDT}
+    {1604214000 -21600 0 CST}
+    {1615708800 -18000 1 CDT}
+    {1636268400 -21600 0 CST}
+    {1647158400 -18000 1 CDT}
+    {1667718000 -21600 0 CST}
+    {1678608000 -18000 1 CDT}
+    {1699167600 -21600 0 CST}
+    {1710057600 -18000 1 CDT}
+    {1730617200 -21600 0 CST}
+    {1741507200 -18000 1 CDT}
+    {1762066800 -21600 0 CST}
+    {1772956800 -18000 1 CDT}
+    {1793516400 -21600 0 CST}
+    {1805011200 -18000 1 CDT}
+    {1825570800 -21600 0 CST}
+    {1836460800 -18000 1 CDT}
+    {1857020400 -21600 0 CST}
+    {1867910400 -18000 1 CDT}
+    {1888470000 -21600 0 CST}
+    {1899360000 -18000 1 CDT}
+    {1919919600 -21600 0 CST}
+    {1930809600 -18000 1 CDT}
+    {1951369200 -21600 0 CST}
+    {1962864000 -18000 1 CDT}
+    {1983423600 -21600 0 CST}
+    {1994313600 -18000 1 CDT}
+    {2014873200 -21600 0 CST}
+    {2025763200 -18000 1 CDT}
+    {2046322800 -21600 0 CST}
+    {2057212800 -18000 1 CDT}
+    {2077772400 -21600 0 CST}
+    {2088662400 -18000 1 CDT}
+    {2109222000 -21600 0 CST}
+    {2120112000 -18000 1 CDT}
+    {2140671600 -21600 0 CST}
+    {2152166400 -18000 1 CDT}
+    {2172726000 -21600 0 CST}
+    {2183616000 -18000 1 CDT}
+    {2204175600 -21600 0 CST}
+    {2215065600 -18000 1 CDT}
+    {2235625200 -21600 0 CST}
+    {2246515200 -18000 1 CDT}
+    {2267074800 -21600 0 CST}
+    {2277964800 -18000 1 CDT}
+    {2298524400 -21600 0 CST}
+    {2309414400 -18000 1 CDT}
+    {2329974000 -21600 0 CST}
+    {2341468800 -18000 1 CDT}
+    {2362028400 -21600 0 CST}
+    {2372918400 -18000 1 CDT}
+    {2393478000 -21600 0 CST}
+    {2404368000 -18000 1 CDT}
+    {2424927600 -21600 0 CST}
+    {2435817600 -18000 1 CDT}
+    {2456377200 -21600 0 CST}
+    {2467267200 -18000 1 CDT}
+    {2487826800 -21600 0 CST}
+    {2499321600 -18000 1 CDT}
+    {2519881200 -21600 0 CST}
+    {2530771200 -18000 1 CDT}
+    {2551330800 -21600 0 CST}
+    {2562220800 -18000 1 CDT}
+    {2582780400 -21600 0 CST}
+    {2593670400 -18000 1 CDT}
+    {2614230000 -21600 0 CST}
+    {2625120000 -18000 1 CDT}
+    {2645679600 -21600 0 CST}
+    {2656569600 -18000 1 CDT}
+    {2677129200 -21600 0 CST}
+    {2688624000 -18000 1 CDT}
+    {2709183600 -21600 0 CST}
+    {2720073600 -18000 1 CDT}
+    {2740633200 -21600 0 CST}
+    {2751523200 -18000 1 CDT}
+    {2772082800 -21600 0 CST}
+    {2782972800 -18000 1 CDT}
+    {2803532400 -21600 0 CST}
+    {2814422400 -18000 1 CDT}
+    {2834982000 -21600 0 CST}
+    {2846476800 -18000 1 CDT}
+    {2867036400 -21600 0 CST}
+    {2877926400 -18000 1 CDT}
+    {2898486000 -21600 0 CST}
+    {2909376000 -18000 1 CDT}
+    {2929935600 -21600 0 CST}
+    {2940825600 -18000 1 CDT}
+    {2961385200 -21600 0 CST}
+    {2972275200 -18000 1 CDT}
+    {2992834800 -21600 0 CST}
+    {3003724800 -18000 1 CDT}
+    {3024284400 -21600 0 CST}
+    {3035779200 -18000 1 CDT}
+    {3056338800 -21600 0 CST}
+    {3067228800 -18000 1 CDT}
+    {3087788400 -21600 0 CST}
+    {3098678400 -18000 1 CDT}
+    {3119238000 -21600 0 CST}
+    {3130128000 -18000 1 CDT}
+    {3150687600 -21600 0 CST}
+    {3161577600 -18000 1 CDT}
+    {3182137200 -21600 0 CST}
+    {3193027200 -18000 1 CDT}
+    {3213586800 -21600 0 CST}
+    {3225081600 -18000 1 CDT}
+    {3245641200 -21600 0 CST}
+    {3256531200 -18000 1 CDT}
+    {3277090800 -21600 0 CST}
+    {3287980800 -18000 1 CDT}
+    {3308540400 -21600 0 CST}
+    {3319430400 -18000 1 CDT}
+    {3339990000 -21600 0 CST}
+    {3350880000 -18000 1 CDT}
+    {3371439600 -21600 0 CST}
+    {3382934400 -18000 1 CDT}
+    {3403494000 -21600 0 CST}
+    {3414384000 -18000 1 CDT}
+    {3434943600 -21600 0 CST}
+    {3445833600 -18000 1 CDT}
+    {3466393200 -21600 0 CST}
+    {3477283200 -18000 1 CDT}
+    {3497842800 -21600 0 CST}
+    {3508732800 -18000 1 CDT}
+    {3529292400 -21600 0 CST}
+    {3540182400 -18000 1 CDT}
+    {3560742000 -21600 0 CST}
+    {3572236800 -18000 1 CDT}
+    {3592796400 -21600 0 CST}
+    {3603686400 -18000 1 CDT}
+    {3624246000 -21600 0 CST}
+    {3635136000 -18000 1 CDT}
+    {3655695600 -21600 0 CST}
+    {3666585600 -18000 1 CDT}
+    {3687145200 -21600 0 CST}
+    {3698035200 -18000 1 CDT}
+    {3718594800 -21600 0 CST}
+    {3730089600 -18000 1 CDT}
+    {3750649200 -21600 0 CST}
+    {3761539200 -18000 1 CDT}
+    {3782098800 -21600 0 CST}
+    {3792988800 -18000 1 CDT}
+    {3813548400 -21600 0 CST}
+    {3824438400 -18000 1 CDT}
+    {3844998000 -21600 0 CST}
+    {3855888000 -18000 1 CDT}
+    {3876447600 -21600 0 CST}
+    {3887337600 -18000 1 CDT}
+    {3907897200 -21600 0 CST}
+    {3919392000 -18000 1 CDT}
+    {3939951600 -21600 0 CST}
+    {3950841600 -18000 1 CDT}
+    {3971401200 -21600 0 CST}
+    {3982291200 -18000 1 CDT}
+    {4002850800 -21600 0 CST}
+    {4013740800 -18000 1 CDT}
+    {4034300400 -21600 0 CST}
+    {4045190400 -18000 1 CDT}
+    {4065750000 -21600 0 CST}
+    {4076640000 -18000 1 CDT}
+    {4097199600 -21600 0 CST}
+}
diff --git a/library/tzdata/America/Rio_Branco b/library/tzdata/America/Rio_Branco
new file mode 100644
index 0000000..f0ff7fa
--- /dev/null
+++ b/library/tzdata/America/Rio_Branco
@@ -0,0 +1,37 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Rio_Branco) {
+    {-9223372036854775808 -16272 0 LMT}
+    {-1767209328 -18000 0 ACT}
+    {-1206950400 -14400 1 ACST}
+    {-1191355200 -18000 0 ACT}
+    {-1175367600 -14400 1 ACST}
+    {-1159819200 -18000 0 ACT}
+    {-633812400 -14400 1 ACST}
+    {-622062000 -18000 0 ACT}
+    {-602276400 -14400 1 ACST}
+    {-591825600 -18000 0 ACT}
+    {-570740400 -14400 1 ACST}
+    {-560203200 -18000 0 ACT}
+    {-539118000 -14400 1 ACST}
+    {-531345600 -18000 0 ACT}
+    {-191358000 -14400 1 ACST}
+    {-184190400 -18000 0 ACT}
+    {-155156400 -14400 1 ACST}
+    {-150062400 -18000 0 ACT}
+    {-128890800 -14400 1 ACST}
+    {-121118400 -18000 0 ACT}
+    {-99946800 -14400 1 ACST}
+    {-89582400 -18000 0 ACT}
+    {-68410800 -14400 1 ACST}
+    {-57960000 -18000 0 ACT}
+    {499755600 -14400 1 ACST}
+    {511243200 -18000 0 ACT}
+    {530600400 -14400 1 ACST}
+    {540273600 -18000 0 ACT}
+    {562136400 -14400 1 ACST}
+    {571204800 -18000 0 ACT}
+    {590040000 -18000 0 ACT}
+    {1214283600 -14400 0 AMT}
+    {1384056000 -18000 0 ACT}
+}
diff --git a/library/tzdata/America/Rosario b/library/tzdata/America/Rosario
new file mode 100644
index 0000000..6687f88
--- /dev/null
+++ b/library/tzdata/America/Rosario
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(America/Argentina/Cordoba)]} {
+    LoadTimeZoneFile America/Argentina/Cordoba
+}
+set TZData(:America/Rosario) $TZData(:America/Argentina/Cordoba)
diff --git a/library/tzdata/America/Santa_Isabel b/library/tzdata/America/Santa_Isabel
new file mode 100644
index 0000000..a3a3b4f
--- /dev/null
+++ b/library/tzdata/America/Santa_Isabel
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(America/Tijuana)]} {
+    LoadTimeZoneFile America/Tijuana
+}
+set TZData(:America/Santa_Isabel) $TZData(:America/Tijuana)
diff --git a/library/tzdata/America/Santarem b/library/tzdata/America/Santarem
new file mode 100644
index 0000000..b6e9264
--- /dev/null
+++ b/library/tzdata/America/Santarem
@@ -0,0 +1,36 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Santarem) {
+    {-9223372036854775808 -13128 0 LMT}
+    {-1767212472 -14400 0 AMT}
+    {-1206954000 -10800 1 AMST}
+    {-1191358800 -14400 0 AMT}
+    {-1175371200 -10800 1 AMST}
+    {-1159822800 -14400 0 AMT}
+    {-633816000 -10800 1 AMST}
+    {-622065600 -14400 0 AMT}
+    {-602280000 -10800 1 AMST}
+    {-591829200 -14400 0 AMT}
+    {-570744000 -10800 1 AMST}
+    {-560206800 -14400 0 AMT}
+    {-539121600 -10800 1 AMST}
+    {-531349200 -14400 0 AMT}
+    {-191361600 -10800 1 AMST}
+    {-184194000 -14400 0 AMT}
+    {-155160000 -10800 1 AMST}
+    {-150066000 -14400 0 AMT}
+    {-128894400 -10800 1 AMST}
+    {-121122000 -14400 0 AMT}
+    {-99950400 -10800 1 AMST}
+    {-89586000 -14400 0 AMT}
+    {-68414400 -10800 1 AMST}
+    {-57963600 -14400 0 AMT}
+    {499752000 -10800 1 AMST}
+    {511239600 -14400 0 AMT}
+    {530596800 -10800 1 AMST}
+    {540270000 -14400 0 AMT}
+    {562132800 -10800 1 AMST}
+    {571201200 -14400 0 AMT}
+    {590036400 -14400 0 AMT}
+    {1214280000 -10800 0 BRT}
+}
diff --git a/library/tzdata/America/Santiago b/library/tzdata/America/Santiago
new file mode 100644
index 0000000..3a5c0fd
--- /dev/null
+++ b/library/tzdata/America/Santiago
@@ -0,0 +1,289 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Santiago) {
+    {-9223372036854775808 -16966 0 LMT}
+    {-2524504634 -16966 0 SMT}
+    {-1892661434 -18000 0 CLT}
+    {-1688410800 -16966 0 SMT}
+    {-1619205434 -14400 0 CLT}
+    {-1593806400 -16966 0 SMT}
+    {-1335986234 -18000 0 CLT}
+    {-1335985200 -14400 1 CLST}
+    {-1317585600 -18000 0 CLT}
+    {-1304362800 -14400 1 CLST}
+    {-1286049600 -18000 0 CLT}
+    {-1272826800 -14400 1 CLST}
+    {-1254513600 -18000 0 CLT}
+    {-1241290800 -14400 1 CLST}
+    {-1222977600 -18000 0 CLT}
+    {-1209754800 -14400 1 CLST}
+    {-1191355200 -18000 0 CLT}
+    {-1178132400 -14400 0 CLT}
+    {-870552000 -18000 0 CLT}
+    {-865278000 -14400 0 CLT}
+    {-740520000 -10800 1 CLST}
+    {-736376400 -14400 0 CLT}
+    {-718056000 -18000 0 CLT}
+    {-713649600 -14400 0 CLT}
+    {-36619200 -10800 1 CLST}
+    {-23922000 -14400 0 CLT}
+    {-3355200 -10800 1 CLST}
+    {7527600 -14400 0 CLT}
+    {24465600 -10800 1 CLST}
+    {37767600 -14400 0 CLT}
+    {55915200 -10800 1 CLST}
+    {69217200 -14400 0 CLT}
+    {87969600 -10800 1 CLST}
+    {100666800 -14400 0 CLT}
+    {118209600 -10800 1 CLST}
+    {132116400 -14400 0 CLT}
+    {150868800 -10800 1 CLST}
+    {163566000 -14400 0 CLT}
+    {182318400 -10800 1 CLST}
+    {195620400 -14400 0 CLT}
+    {213768000 -10800 1 CLST}
+    {227070000 -14400 0 CLT}
+    {245217600 -10800 1 CLST}
+    {258519600 -14400 0 CLT}
+    {277272000 -10800 1 CLST}
+    {289969200 -14400 0 CLT}
+    {308721600 -10800 1 CLST}
+    {321418800 -14400 0 CLT}
+    {340171200 -10800 1 CLST}
+    {353473200 -14400 0 CLT}
+    {371620800 -10800 1 CLST}
+    {384922800 -14400 0 CLT}
+    {403070400 -10800 1 CLST}
+    {416372400 -14400 0 CLT}
+    {434520000 -10800 1 CLST}
+    {447822000 -14400 0 CLT}
+    {466574400 -10800 1 CLST}
+    {479271600 -14400 0 CLT}
+    {498024000 -10800 1 CLST}
+    {510721200 -14400 0 CLT}
+    {529473600 -10800 1 CLST}
+    {545194800 -14400 0 CLT}
+    {560923200 -10800 1 CLST}
+    {574225200 -14400 0 CLT}
+    {592372800 -10800 1 CLST}
+    {605674800 -14400 0 CLT}
+    {624427200 -10800 1 CLST}
+    {637124400 -14400 0 CLT}
+    {653457600 -10800 1 CLST}
+    {668574000 -14400 0 CLT}
+    {687326400 -10800 1 CLST}
+    {700628400 -14400 0 CLT}
+    {718776000 -10800 1 CLST}
+    {732078000 -14400 0 CLT}
+    {750225600 -10800 1 CLST}
+    {763527600 -14400 0 CLT}
+    {781675200 -10800 1 CLST}
+    {794977200 -14400 0 CLT}
+    {813729600 -10800 1 CLST}
+    {826426800 -14400 0 CLT}
+    {845179200 -10800 1 CLST}
+    {859690800 -14400 0 CLT}
+    {876628800 -10800 1 CLST}
+    {889930800 -14400 0 CLT}
+    {906868800 -10800 1 CLST}
+    {923194800 -14400 0 CLT}
+    {939528000 -10800 1 CLST}
+    {952830000 -14400 0 CLT}
+    {971582400 -10800 1 CLST}
+    {984279600 -14400 0 CLT}
+    {1003032000 -10800 1 CLST}
+    {1015729200 -14400 0 CLT}
+    {1034481600 -10800 1 CLST}
+    {1047178800 -14400 0 CLT}
+    {1065931200 -10800 1 CLST}
+    {1079233200 -14400 0 CLT}
+    {1097380800 -10800 1 CLST}
+    {1110682800 -14400 0 CLT}
+    {1128830400 -10800 1 CLST}
+    {1142132400 -14400 0 CLT}
+    {1160884800 -10800 1 CLST}
+    {1173582000 -14400 0 CLT}
+    {1192334400 -10800 1 CLST}
+    {1206846000 -14400 0 CLT}
+    {1223784000 -10800 1 CLST}
+    {1237086000 -14400 0 CLT}
+    {1255233600 -10800 1 CLST}
+    {1270350000 -14400 0 CLT}
+    {1286683200 -10800 1 CLST}
+    {1304823600 -14400 0 CLT}
+    {1313899200 -10800 1 CLST}
+    {1335668400 -14400 0 CLT}
+    {1346558400 -10800 1 CLST}
+    {1367118000 -14400 0 CLT}
+    {1378612800 -10800 1 CLST}
+    {1398567600 -14400 0 CLT}
+    {1410062400 -10800 1 CLST}
+    {1463281200 -14400 0 CLT}
+    {1471147200 -10800 1 CLST}
+    {1494730800 -14400 0 CLT}
+    {1502596800 -10800 1 CLST}
+    {1526180400 -14400 0 CLT}
+    {1534046400 -10800 1 CLST}
+    {1557630000 -14400 0 CLT}
+    {1565496000 -10800 1 CLST}
+    {1589079600 -14400 0 CLT}
+    {1596945600 -10800 1 CLST}
+    {1620529200 -14400 0 CLT}
+    {1629000000 -10800 1 CLST}
+    {1652583600 -14400 0 CLT}
+    {1660449600 -10800 1 CLST}
+    {1684033200 -14400 0 CLT}
+    {1691899200 -10800 1 CLST}
+    {1715482800 -14400 0 CLT}
+    {1723348800 -10800 1 CLST}
+    {1746932400 -14400 0 CLT}
+    {1754798400 -10800 1 CLST}
+    {1778382000 -14400 0 CLT}
+    {1786248000 -10800 1 CLST}
+    {1809831600 -14400 0 CLT}
+    {1818302400 -10800 1 CLST}
+    {1841886000 -14400 0 CLT}
+    {1849752000 -10800 1 CLST}
+    {1873335600 -14400 0 CLT}
+    {1881201600 -10800 1 CLST}
+    {1904785200 -14400 0 CLT}
+    {1912651200 -10800 1 CLST}
+    {1936234800 -14400 0 CLT}
+    {1944100800 -10800 1 CLST}
+    {1967684400 -14400 0 CLT}
+    {1976155200 -10800 1 CLST}
+    {1999738800 -14400 0 CLT}
+    {2007604800 -10800 1 CLST}
+    {2031188400 -14400 0 CLT}
+    {2039054400 -10800 1 CLST}
+    {2062638000 -14400 0 CLT}
+    {2070504000 -10800 1 CLST}
+    {2094087600 -14400 0 CLT}
+    {2101953600 -10800 1 CLST}
+    {2125537200 -14400 0 CLT}
+    {2133403200 -10800 1 CLST}
+    {2156986800 -14400 0 CLT}
+    {2165457600 -10800 1 CLST}
+    {2189041200 -14400 0 CLT}
+    {2196907200 -10800 1 CLST}
+    {2220490800 -14400 0 CLT}
+    {2228356800 -10800 1 CLST}
+    {2251940400 -14400 0 CLT}
+    {2259806400 -10800 1 CLST}
+    {2283390000 -14400 0 CLT}
+    {2291256000 -10800 1 CLST}
+    {2314839600 -14400 0 CLT}
+    {2322705600 -10800 1 CLST}
+    {2346894000 -14400 0 CLT}
+    {2354760000 -10800 1 CLST}
+    {2378343600 -14400 0 CLT}
+    {2386209600 -10800 1 CLST}
+    {2409793200 -14400 0 CLT}
+    {2417659200 -10800 1 CLST}
+    {2441242800 -14400 0 CLT}
+    {2449108800 -10800 1 CLST}
+    {2472692400 -14400 0 CLT}
+    {2480558400 -10800 1 CLST}
+    {2504142000 -14400 0 CLT}
+    {2512612800 -10800 1 CLST}
+    {2536196400 -14400 0 CLT}
+    {2544062400 -10800 1 CLST}
+    {2567646000 -14400 0 CLT}
+    {2575512000 -10800 1 CLST}
+    {2599095600 -14400 0 CLT}
+    {2606961600 -10800 1 CLST}
+    {2630545200 -14400 0 CLT}
+    {2638411200 -10800 1 CLST}
+    {2661994800 -14400 0 CLT}
+    {2669860800 -10800 1 CLST}
+    {2693444400 -14400 0 CLT}
+    {2701915200 -10800 1 CLST}
+    {2725498800 -14400 0 CLT}
+    {2733364800 -10800 1 CLST}
+    {2756948400 -14400 0 CLT}
+    {2764814400 -10800 1 CLST}
+    {2788398000 -14400 0 CLT}
+    {2796264000 -10800 1 CLST}
+    {2819847600 -14400 0 CLT}
+    {2827713600 -10800 1 CLST}
+    {2851297200 -14400 0 CLT}
+    {2859768000 -10800 1 CLST}
+    {2883351600 -14400 0 CLT}
+    {2891217600 -10800 1 CLST}
+    {2914801200 -14400 0 CLT}
+    {2922667200 -10800 1 CLST}
+    {2946250800 -14400 0 CLT}
+    {2954116800 -10800 1 CLST}
+    {2977700400 -14400 0 CLT}
+    {2985566400 -10800 1 CLST}
+    {3009150000 -14400 0 CLT}
+    {3017016000 -10800 1 CLST}
+    {3040599600 -14400 0 CLT}
+    {3049070400 -10800 1 CLST}
+    {3072654000 -14400 0 CLT}
+    {3080520000 -10800 1 CLST}
+    {3104103600 -14400 0 CLT}
+    {3111969600 -10800 1 CLST}
+    {3135553200 -14400 0 CLT}
+    {3143419200 -10800 1 CLST}
+    {3167002800 -14400 0 CLT}
+    {3174868800 -10800 1 CLST}
+    {3198452400 -14400 0 CLT}
+    {3206318400 -10800 1 CLST}
+    {3230506800 -14400 0 CLT}
+    {3238372800 -10800 1 CLST}
+    {3261956400 -14400 0 CLT}
+    {3269822400 -10800 1 CLST}
+    {3293406000 -14400 0 CLT}
+    {3301272000 -10800 1 CLST}
+    {3324855600 -14400 0 CLT}
+    {3332721600 -10800 1 CLST}
+    {3356305200 -14400 0 CLT}
+    {3364171200 -10800 1 CLST}
+    {3387754800 -14400 0 CLT}
+    {3396225600 -10800 1 CLST}
+    {3419809200 -14400 0 CLT}
+    {3427675200 -10800 1 CLST}
+    {3451258800 -14400 0 CLT}
+    {3459124800 -10800 1 CLST}
+    {3482708400 -14400 0 CLT}
+    {3490574400 -10800 1 CLST}
+    {3514158000 -14400 0 CLT}
+    {3522024000 -10800 1 CLST}
+    {3545607600 -14400 0 CLT}
+    {3553473600 -10800 1 CLST}
+    {3577057200 -14400 0 CLT}
+    {3585528000 -10800 1 CLST}
+    {3609111600 -14400 0 CLT}
+    {3616977600 -10800 1 CLST}
+    {3640561200 -14400 0 CLT}
+    {3648427200 -10800 1 CLST}
+    {3672010800 -14400 0 CLT}
+    {3679876800 -10800 1 CLST}
+    {3703460400 -14400 0 CLT}
+    {3711326400 -10800 1 CLST}
+    {3734910000 -14400 0 CLT}
+    {3743380800 -10800 1 CLST}
+    {3766964400 -14400 0 CLT}
+    {3774830400 -10800 1 CLST}
+    {3798414000 -14400 0 CLT}
+    {3806280000 -10800 1 CLST}
+    {3829863600 -14400 0 CLT}
+    {3837729600 -10800 1 CLST}
+    {3861313200 -14400 0 CLT}
+    {3869179200 -10800 1 CLST}
+    {3892762800 -14400 0 CLT}
+    {3900628800 -10800 1 CLST}
+    {3924212400 -14400 0 CLT}
+    {3932683200 -10800 1 CLST}
+    {3956266800 -14400 0 CLT}
+    {3964132800 -10800 1 CLST}
+    {3987716400 -14400 0 CLT}
+    {3995582400 -10800 1 CLST}
+    {4019166000 -14400 0 CLT}
+    {4027032000 -10800 1 CLST}
+    {4050615600 -14400 0 CLT}
+    {4058481600 -10800 1 CLST}
+    {4082065200 -14400 0 CLT}
+    {4089931200 -10800 1 CLST}
+}
diff --git a/library/tzdata/America/Santo_Domingo b/library/tzdata/America/Santo_Domingo
new file mode 100644
index 0000000..7706918
--- /dev/null
+++ b/library/tzdata/America/Santo_Domingo
@@ -0,0 +1,21 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Santo_Domingo) {
+    {-9223372036854775808 -16776 0 LMT}
+    {-2524504824 -16800 0 SDMT}
+    {-1159773600 -18000 0 EST}
+    {-100119600 -14400 1 EDT}
+    {-89668800 -18000 0 EST}
+    {-5770800 -16200 1 EHDT}
+    {4422600 -18000 0 EST}
+    {25678800 -16200 1 EHDT}
+    {33193800 -18000 0 EST}
+    {57733200 -16200 1 EHDT}
+    {64816200 -18000 0 EST}
+    {89182800 -16200 1 EHDT}
+    {96438600 -18000 0 EST}
+    {120632400 -16200 1 EHDT}
+    {127974600 -18000 0 EST}
+    {152082000 -14400 0 AST}
+    {975823200 -14400 0 AST}
+}
diff --git a/library/tzdata/America/Sao_Paulo b/library/tzdata/America/Sao_Paulo
new file mode 100644
index 0000000..8d70063
--- /dev/null
+++ b/library/tzdata/America/Sao_Paulo
@@ -0,0 +1,258 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Sao_Paulo) {
+    {-9223372036854775808 -11188 0 LMT}
+    {-1767214412 -10800 0 BRT}
+    {-1206957600 -7200 1 BRST}
+    {-1191362400 -10800 0 BRT}
+    {-1175374800 -7200 1 BRST}
+    {-1159826400 -10800 0 BRT}
+    {-633819600 -7200 1 BRST}
+    {-622069200 -10800 0 BRT}
+    {-602283600 -7200 1 BRST}
+    {-591832800 -10800 0 BRT}
+    {-570747600 -7200 1 BRST}
+    {-560210400 -10800 0 BRT}
+    {-539125200 -7200 1 BRST}
+    {-531352800 -10800 0 BRT}
+    {-195429600 -7200 1 BRST}
+    {-189381600 -7200 0 BRT}
+    {-184197600 -10800 0 BRT}
+    {-155163600 -7200 1 BRST}
+    {-150069600 -10800 0 BRT}
+    {-128898000 -7200 1 BRST}
+    {-121125600 -10800 0 BRT}
+    {-99954000 -7200 1 BRST}
+    {-89589600 -10800 0 BRT}
+    {-68418000 -7200 1 BRST}
+    {-57967200 -10800 0 BRT}
+    {499748400 -7200 1 BRST}
+    {511236000 -10800 0 BRT}
+    {530593200 -7200 1 BRST}
+    {540266400 -10800 0 BRT}
+    {562129200 -7200 1 BRST}
+    {571197600 -10800 0 BRT}
+    {592974000 -7200 1 BRST}
+    {602042400 -10800 0 BRT}
+    {624423600 -7200 1 BRST}
+    {634701600 -10800 0 BRT}
+    {656478000 -7200 1 BRST}
+    {666756000 -10800 0 BRT}
+    {687927600 -7200 1 BRST}
+    {697600800 -10800 0 BRT}
+    {719982000 -7200 1 BRST}
+    {728445600 -10800 0 BRT}
+    {750826800 -7200 1 BRST}
+    {761709600 -10800 0 BRT}
+    {782276400 -7200 1 BRST}
+    {793159200 -10800 0 BRT}
+    {813726000 -7200 1 BRST}
+    {824004000 -10800 0 BRT}
+    {844570800 -7200 1 BRST}
+    {856058400 -10800 0 BRT}
+    {876106800 -7200 1 BRST}
+    {888717600 -10800 0 BRT}
+    {908074800 -7200 1 BRST}
+    {919562400 -10800 0 BRT}
+    {938919600 -7200 1 BRST}
+    {951616800 -10800 0 BRT}
+    {970974000 -7200 1 BRST}
+    {982461600 -10800 0 BRT}
+    {1003028400 -7200 1 BRST}
+    {1013911200 -10800 0 BRT}
+    {1036292400 -7200 1 BRST}
+    {1045360800 -10800 0 BRT}
+    {1066532400 -7200 1 BRST}
+    {1076810400 -10800 0 BRT}
+    {1099364400 -7200 1 BRST}
+    {1108864800 -10800 0 BRT}
+    {1129431600 -7200 1 BRST}
+    {1140314400 -10800 0 BRT}
+    {1162695600 -7200 1 BRST}
+    {1172368800 -10800 0 BRT}
+    {1192330800 -7200 1 BRST}
+    {1203213600 -10800 0 BRT}
+    {1224385200 -7200 1 BRST}
+    {1234663200 -10800 0 BRT}
+    {1255834800 -7200 1 BRST}
+    {1266717600 -10800 0 BRT}
+    {1287284400 -7200 1 BRST}
+    {1298167200 -10800 0 BRT}
+    {1318734000 -7200 1 BRST}
+    {1330221600 -10800 0 BRT}
+    {1350788400 -7200 1 BRST}
+    {1361066400 -10800 0 BRT}
+    {1382238000 -7200 1 BRST}
+    {1392516000 -10800 0 BRT}
+    {1413687600 -7200 1 BRST}
+    {1424570400 -10800 0 BRT}
+    {1445137200 -7200 1 BRST}
+    {1456020000 -10800 0 BRT}
+    {1476586800 -7200 1 BRST}
+    {1487469600 -10800 0 BRT}
+    {1508036400 -7200 1 BRST}
+    {1518919200 -10800 0 BRT}
+    {1540090800 -7200 1 BRST}
+    {1550368800 -10800 0 BRT}
+    {1571540400 -7200 1 BRST}
+    {1581818400 -10800 0 BRT}
+    {1602990000 -7200 1 BRST}
+    {1613872800 -10800 0 BRT}
+    {1634439600 -7200 1 BRST}
+    {1645322400 -10800 0 BRT}
+    {1665889200 -7200 1 BRST}
+    {1677376800 -10800 0 BRT}
+    {1697338800 -7200 1 BRST}
+    {1708221600 -10800 0 BRT}
+    {1729393200 -7200 1 BRST}
+    {1739671200 -10800 0 BRT}
+    {1760842800 -7200 1 BRST}
+    {1771725600 -10800 0 BRT}
+    {1792292400 -7200 1 BRST}
+    {1803175200 -10800 0 BRT}
+    {1823742000 -7200 1 BRST}
+    {1834624800 -10800 0 BRT}
+    {1855191600 -7200 1 BRST}
+    {1866074400 -10800 0 BRT}
+    {1887246000 -7200 1 BRST}
+    {1897524000 -10800 0 BRT}
+    {1918695600 -7200 1 BRST}
+    {1928973600 -10800 0 BRT}
+    {1950145200 -7200 1 BRST}
+    {1960423200 -10800 0 BRT}
+    {1981594800 -7200 1 BRST}
+    {1992477600 -10800 0 BRT}
+    {2013044400 -7200 1 BRST}
+    {2024532000 -10800 0 BRT}
+    {2044494000 -7200 1 BRST}
+    {2055376800 -10800 0 BRT}
+    {2076548400 -7200 1 BRST}
+    {2086826400 -10800 0 BRT}
+    {2107998000 -7200 1 BRST}
+    {2118880800 -10800 0 BRT}
+    {2139447600 -7200 1 BRST}
+    {2150330400 -10800 0 BRT}
+    {2170897200 -7200 1 BRST}
+    {2181780000 -10800 0 BRT}
+    {2202346800 -7200 1 BRST}
+    {2213229600 -10800 0 BRT}
+    {2234401200 -7200 1 BRST}
+    {2244679200 -10800 0 BRT}
+    {2265850800 -7200 1 BRST}
+    {2276128800 -10800 0 BRT}
+    {2297300400 -7200 1 BRST}
+    {2307578400 -10800 0 BRT}
+    {2328750000 -7200 1 BRST}
+    {2339632800 -10800 0 BRT}
+    {2360199600 -7200 1 BRST}
+    {2371082400 -10800 0 BRT}
+    {2391649200 -7200 1 BRST}
+    {2402532000 -10800 0 BRT}
+    {2423703600 -7200 1 BRST}
+    {2433981600 -10800 0 BRT}
+    {2455153200 -7200 1 BRST}
+    {2465431200 -10800 0 BRT}
+    {2486602800 -7200 1 BRST}
+    {2497485600 -10800 0 BRT}
+    {2518052400 -7200 1 BRST}
+    {2528935200 -10800 0 BRT}
+    {2549502000 -7200 1 BRST}
+    {2560384800 -10800 0 BRT}
+    {2580951600 -7200 1 BRST}
+    {2591834400 -10800 0 BRT}
+    {2613006000 -7200 1 BRST}
+    {2623284000 -10800 0 BRT}
+    {2644455600 -7200 1 BRST}
+    {2654733600 -10800 0 BRT}
+    {2675905200 -7200 1 BRST}
+    {2686788000 -10800 0 BRT}
+    {2707354800 -7200 1 BRST}
+    {2718237600 -10800 0 BRT}
+    {2738804400 -7200 1 BRST}
+    {2749687200 -10800 0 BRT}
+    {2770858800 -7200 1 BRST}
+    {2781136800 -10800 0 BRT}
+    {2802308400 -7200 1 BRST}
+    {2812586400 -10800 0 BRT}
+    {2833758000 -7200 1 BRST}
+    {2844036000 -10800 0 BRT}
+    {2865207600 -7200 1 BRST}
+    {2876090400 -10800 0 BRT}
+    {2896657200 -7200 1 BRST}
+    {2907540000 -10800 0 BRT}
+    {2928106800 -7200 1 BRST}
+    {2938989600 -10800 0 BRT}
+    {2960161200 -7200 1 BRST}
+    {2970439200 -10800 0 BRT}
+    {2991610800 -7200 1 BRST}
+    {3001888800 -10800 0 BRT}
+    {3023060400 -7200 1 BRST}
+    {3033943200 -10800 0 BRT}
+    {3054510000 -7200 1 BRST}
+    {3065392800 -10800 0 BRT}
+    {3085959600 -7200 1 BRST}
+    {3096842400 -10800 0 BRT}
+    {3118014000 -7200 1 BRST}
+    {3128292000 -10800 0 BRT}
+    {3149463600 -7200 1 BRST}
+    {3159741600 -10800 0 BRT}
+    {3180913200 -7200 1 BRST}
+    {3191191200 -10800 0 BRT}
+    {3212362800 -7200 1 BRST}
+    {3223245600 -10800 0 BRT}
+    {3243812400 -7200 1 BRST}
+    {3254695200 -10800 0 BRT}
+    {3275262000 -7200 1 BRST}
+    {3286144800 -10800 0 BRT}
+    {3307316400 -7200 1 BRST}
+    {3317594400 -10800 0 BRT}
+    {3338766000 -7200 1 BRST}
+    {3349044000 -10800 0 BRT}
+    {3370215600 -7200 1 BRST}
+    {3381098400 -10800 0 BRT}
+    {3401665200 -7200 1 BRST}
+    {3412548000 -10800 0 BRT}
+    {3433114800 -7200 1 BRST}
+    {3443997600 -10800 0 BRT}
+    {3464564400 -7200 1 BRST}
+    {3475447200 -10800 0 BRT}
+    {3496618800 -7200 1 BRST}
+    {3506896800 -10800 0 BRT}
+    {3528068400 -7200 1 BRST}
+    {3538346400 -10800 0 BRT}
+    {3559518000 -7200 1 BRST}
+    {3570400800 -10800 0 BRT}
+    {3590967600 -7200 1 BRST}
+    {3601850400 -10800 0 BRT}
+    {3622417200 -7200 1 BRST}
+    {3633300000 -10800 0 BRT}
+    {3654471600 -7200 1 BRST}
+    {3664749600 -10800 0 BRT}
+    {3685921200 -7200 1 BRST}
+    {3696199200 -10800 0 BRT}
+    {3717370800 -7200 1 BRST}
+    {3727648800 -10800 0 BRT}
+    {3748820400 -7200 1 BRST}
+    {3759703200 -10800 0 BRT}
+    {3780270000 -7200 1 BRST}
+    {3791152800 -10800 0 BRT}
+    {3811719600 -7200 1 BRST}
+    {3822602400 -10800 0 BRT}
+    {3843774000 -7200 1 BRST}
+    {3854052000 -10800 0 BRT}
+    {3875223600 -7200 1 BRST}
+    {3885501600 -10800 0 BRT}
+    {3906673200 -7200 1 BRST}
+    {3917556000 -10800 0 BRT}
+    {3938122800 -7200 1 BRST}
+    {3949005600 -10800 0 BRT}
+    {3969572400 -7200 1 BRST}
+    {3980455200 -10800 0 BRT}
+    {4001626800 -7200 1 BRST}
+    {4011904800 -10800 0 BRT}
+    {4033076400 -7200 1 BRST}
+    {4043354400 -10800 0 BRT}
+    {4064526000 -7200 1 BRST}
+    {4074804000 -10800 0 BRT}
+    {4095975600 -7200 1 BRST}
+}
diff --git a/library/tzdata/America/Scoresbysund b/library/tzdata/America/Scoresbysund
new file mode 100644
index 0000000..74a332c
--- /dev/null
+++ b/library/tzdata/America/Scoresbysund
@@ -0,0 +1,246 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Scoresbysund) {
+    {-9223372036854775808 -5272 0 LMT}
+    {-1686090728 -7200 0 CGT}
+    {323841600 -3600 0 CGST}
+    {338961600 -7200 0 CGT}
+    {354679200 0 0 EGST}
+    {370400400 -3600 0 EGT}
+    {386125200 0 1 EGST}
+    {401850000 -3600 0 EGT}
+    {417574800 0 1 EGST}
+    {433299600 -3600 0 EGT}
+    {449024400 0 1 EGST}
+    {465354000 -3600 0 EGT}
+    {481078800 0 1 EGST}
+    {496803600 -3600 0 EGT}
+    {512528400 0 1 EGST}
+    {528253200 -3600 0 EGT}
+    {543978000 0 1 EGST}
+    {559702800 -3600 0 EGT}
+    {575427600 0 1 EGST}
+    {591152400 -3600 0 EGT}
+    {606877200 0 1 EGST}
+    {622602000 -3600 0 EGT}
+    {638326800 0 1 EGST}
+    {654656400 -3600 0 EGT}
+    {670381200 0 1 EGST}
+    {686106000 -3600 0 EGT}
+    {701830800 0 1 EGST}
+    {717555600 -3600 0 EGT}
+    {733280400 0 1 EGST}
+    {749005200 -3600 0 EGT}
+    {764730000 0 1 EGST}
+    {780454800 -3600 0 EGT}
+    {796179600 0 1 EGST}
+    {811904400 -3600 0 EGT}
+    {828234000 0 1 EGST}
+    {846378000 -3600 0 EGT}
+    {859683600 0 1 EGST}
+    {877827600 -3600 0 EGT}
+    {891133200 0 1 EGST}
+    {909277200 -3600 0 EGT}
+    {922582800 0 1 EGST}
+    {941331600 -3600 0 EGT}
+    {954032400 0 1 EGST}
+    {972781200 -3600 0 EGT}
+    {985482000 0 1 EGST}
+    {1004230800 -3600 0 EGT}
+    {1017536400 0 1 EGST}
+    {1035680400 -3600 0 EGT}
+    {1048986000 0 1 EGST}
+    {1067130000 -3600 0 EGT}
+    {1080435600 0 1 EGST}
+    {1099184400 -3600 0 EGT}
+    {1111885200 0 1 EGST}
+    {1130634000 -3600 0 EGT}
+    {1143334800 0 1 EGST}
+    {1162083600 -3600 0 EGT}
+    {1174784400 0 1 EGST}
+    {1193533200 -3600 0 EGT}
+    {1206838800 0 1 EGST}
+    {1224982800 -3600 0 EGT}
+    {1238288400 0 1 EGST}
+    {1256432400 -3600 0 EGT}
+    {1269738000 0 1 EGST}
+    {1288486800 -3600 0 EGT}
+    {1301187600 0 1 EGST}
+    {1319936400 -3600 0 EGT}
+    {1332637200 0 1 EGST}
+    {1351386000 -3600 0 EGT}
+    {1364691600 0 1 EGST}
+    {1382835600 -3600 0 EGT}
+    {1396141200 0 1 EGST}
+    {1414285200 -3600 0 EGT}
+    {1427590800 0 1 EGST}
+    {1445734800 -3600 0 EGT}
+    {1459040400 0 1 EGST}
+    {1477789200 -3600 0 EGT}
+    {1490490000 0 1 EGST}
+    {1509238800 -3600 0 EGT}
+    {1521939600 0 1 EGST}
+    {1540688400 -3600 0 EGT}
+    {1553994000 0 1 EGST}
+    {1572138000 -3600 0 EGT}
+    {1585443600 0 1 EGST}
+    {1603587600 -3600 0 EGT}
+    {1616893200 0 1 EGST}
+    {1635642000 -3600 0 EGT}
+    {1648342800 0 1 EGST}
+    {1667091600 -3600 0 EGT}
+    {1679792400 0 1 EGST}
+    {1698541200 -3600 0 EGT}
+    {1711846800 0 1 EGST}
+    {1729990800 -3600 0 EGT}
+    {1743296400 0 1 EGST}
+    {1761440400 -3600 0 EGT}
+    {1774746000 0 1 EGST}
+    {1792890000 -3600 0 EGT}
+    {1806195600 0 1 EGST}
+    {1824944400 -3600 0 EGT}
+    {1837645200 0 1 EGST}
+    {1856394000 -3600 0 EGT}
+    {1869094800 0 1 EGST}
+    {1887843600 -3600 0 EGT}
+    {1901149200 0 1 EGST}
+    {1919293200 -3600 0 EGT}
+    {1932598800 0 1 EGST}
+    {1950742800 -3600 0 EGT}
+    {1964048400 0 1 EGST}
+    {1982797200 -3600 0 EGT}
+    {1995498000 0 1 EGST}
+    {2014246800 -3600 0 EGT}
+    {2026947600 0 1 EGST}
+    {2045696400 -3600 0 EGT}
+    {2058397200 0 1 EGST}
+    {2077146000 -3600 0 EGT}
+    {2090451600 0 1 EGST}
+    {2108595600 -3600 0 EGT}
+    {2121901200 0 1 EGST}
+    {2140045200 -3600 0 EGT}
+    {2153350800 0 1 EGST}
+    {2172099600 -3600 0 EGT}
+    {2184800400 0 1 EGST}
+    {2203549200 -3600 0 EGT}
+    {2216250000 0 1 EGST}
+    {2234998800 -3600 0 EGT}
+    {2248304400 0 1 EGST}
+    {2266448400 -3600 0 EGT}
+    {2279754000 0 1 EGST}
+    {2297898000 -3600 0 EGT}
+    {2311203600 0 1 EGST}
+    {2329347600 -3600 0 EGT}
+    {2342653200 0 1 EGST}
+    {2361402000 -3600 0 EGT}
+    {2374102800 0 1 EGST}
+    {2392851600 -3600 0 EGT}
+    {2405552400 0 1 EGST}
+    {2424301200 -3600 0 EGT}
+    {2437606800 0 1 EGST}
+    {2455750800 -3600 0 EGT}
+    {2469056400 0 1 EGST}
+    {2487200400 -3600 0 EGT}
+    {2500506000 0 1 EGST}
+    {2519254800 -3600 0 EGT}
+    {2531955600 0 1 EGST}
+    {2550704400 -3600 0 EGT}
+    {2563405200 0 1 EGST}
+    {2582154000 -3600 0 EGT}
+    {2595459600 0 1 EGST}
+    {2613603600 -3600 0 EGT}
+    {2626909200 0 1 EGST}
+    {2645053200 -3600 0 EGT}
+    {2658358800 0 1 EGST}
+    {2676502800 -3600 0 EGT}
+    {2689808400 0 1 EGST}
+    {2708557200 -3600 0 EGT}
+    {2721258000 0 1 EGST}
+    {2740006800 -3600 0 EGT}
+    {2752707600 0 1 EGST}
+    {2771456400 -3600 0 EGT}
+    {2784762000 0 1 EGST}
+    {2802906000 -3600 0 EGT}
+    {2816211600 0 1 EGST}
+    {2834355600 -3600 0 EGT}
+    {2847661200 0 1 EGST}
+    {2866410000 -3600 0 EGT}
+    {2879110800 0 1 EGST}
+    {2897859600 -3600 0 EGT}
+    {2910560400 0 1 EGST}
+    {2929309200 -3600 0 EGT}
+    {2942010000 0 1 EGST}
+    {2960758800 -3600 0 EGT}
+    {2974064400 0 1 EGST}
+    {2992208400 -3600 0 EGT}
+    {3005514000 0 1 EGST}
+    {3023658000 -3600 0 EGT}
+    {3036963600 0 1 EGST}
+    {3055712400 -3600 0 EGT}
+    {3068413200 0 1 EGST}
+    {3087162000 -3600 0 EGT}
+    {3099862800 0 1 EGST}
+    {3118611600 -3600 0 EGT}
+    {3131917200 0 1 EGST}
+    {3150061200 -3600 0 EGT}
+    {3163366800 0 1 EGST}
+    {3181510800 -3600 0 EGT}
+    {3194816400 0 1 EGST}
+    {3212960400 -3600 0 EGT}
+    {3226266000 0 1 EGST}
+    {3245014800 -3600 0 EGT}
+    {3257715600 0 1 EGST}
+    {3276464400 -3600 0 EGT}
+    {3289165200 0 1 EGST}
+    {3307914000 -3600 0 EGT}
+    {3321219600 0 1 EGST}
+    {3339363600 -3600 0 EGT}
+    {3352669200 0 1 EGST}
+    {3370813200 -3600 0 EGT}
+    {3384118800 0 1 EGST}
+    {3402867600 -3600 0 EGT}
+    {3415568400 0 1 EGST}
+    {3434317200 -3600 0 EGT}
+    {3447018000 0 1 EGST}
+    {3465766800 -3600 0 EGT}
+    {3479072400 0 1 EGST}
+    {3497216400 -3600 0 EGT}
+    {3510522000 0 1 EGST}
+    {3528666000 -3600 0 EGT}
+    {3541971600 0 1 EGST}
+    {3560115600 -3600 0 EGT}
+    {3573421200 0 1 EGST}
+    {3592170000 -3600 0 EGT}
+    {3604870800 0 1 EGST}
+    {3623619600 -3600 0 EGT}
+    {3636320400 0 1 EGST}
+    {3655069200 -3600 0 EGT}
+    {3668374800 0 1 EGST}
+    {3686518800 -3600 0 EGT}
+    {3699824400 0 1 EGST}
+    {3717968400 -3600 0 EGT}
+    {3731274000 0 1 EGST}
+    {3750022800 -3600 0 EGT}
+    {3762723600 0 1 EGST}
+    {3781472400 -3600 0 EGT}
+    {3794173200 0 1 EGST}
+    {3812922000 -3600 0 EGT}
+    {3825622800 0 1 EGST}
+    {3844371600 -3600 0 EGT}
+    {3857677200 0 1 EGST}
+    {3875821200 -3600 0 EGT}
+    {3889126800 0 1 EGST}
+    {3907270800 -3600 0 EGT}
+    {3920576400 0 1 EGST}
+    {3939325200 -3600 0 EGT}
+    {3952026000 0 1 EGST}
+    {3970774800 -3600 0 EGT}
+    {3983475600 0 1 EGST}
+    {4002224400 -3600 0 EGT}
+    {4015530000 0 1 EGST}
+    {4033674000 -3600 0 EGT}
+    {4046979600 0 1 EGST}
+    {4065123600 -3600 0 EGT}
+    {4078429200 0 1 EGST}
+    {4096573200 -3600 0 EGT}
+}
diff --git a/library/tzdata/America/Shiprock b/library/tzdata/America/Shiprock
new file mode 100644
index 0000000..995d25d
--- /dev/null
+++ b/library/tzdata/America/Shiprock
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(America/Denver)]} {
+    LoadTimeZoneFile America/Denver
+}
+set TZData(:America/Shiprock) $TZData(:America/Denver)
diff --git a/library/tzdata/America/Sitka b/library/tzdata/America/Sitka
new file mode 100644
index 0000000..8c53d93
--- /dev/null
+++ b/library/tzdata/America/Sitka
@@ -0,0 +1,275 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Sitka) {
+    {-9223372036854775808 53927 0 LMT}
+    {-3225365927 -32473 0 LMT}
+    {-2188954727 -28800 0 PST}
+    {-883584000 -28800 0 PST}
+    {-880207200 -25200 1 PWT}
+    {-769395600 -25200 1 PPT}
+    {-765385200 -28800 0 PST}
+    {-757353600 -28800 0 PST}
+    {-31507200 -28800 0 PST}
+    {-21477600 -25200 1 PDT}
+    {-5756400 -28800 0 PST}
+    {9972000 -25200 1 PDT}
+    {25693200 -28800 0 PST}
+    {41421600 -25200 1 PDT}
+    {57747600 -28800 0 PST}
+    {73476000 -25200 1 PDT}
+    {89197200 -28800 0 PST}
+    {104925600 -25200 1 PDT}
+    {120646800 -28800 0 PST}
+    {126698400 -25200 1 PDT}
+    {152096400 -28800 0 PST}
+    {162381600 -25200 1 PDT}
+    {183546000 -28800 0 PST}
+    {199274400 -25200 1 PDT}
+    {215600400 -28800 0 PST}
+    {230724000 -25200 1 PDT}
+    {247050000 -28800 0 PST}
+    {262778400 -25200 1 PDT}
+    {278499600 -28800 0 PST}
+    {294228000 -25200 1 PDT}
+    {309949200 -28800 0 PST}
+    {325677600 -25200 1 PDT}
+    {341398800 -28800 0 PST}
+    {357127200 -25200 1 PDT}
+    {372848400 -28800 0 PST}
+    {388576800 -25200 1 PDT}
+    {404902800 -28800 0 PST}
+    {420026400 -25200 1 PDT}
+    {439030800 -32400 0 AKST}
+    {452084400 -28800 1 AKDT}
+    {467805600 -32400 0 AKST}
+    {483534000 -28800 1 AKDT}
+    {499255200 -32400 0 AKST}
+    {514983600 -28800 1 AKDT}
+    {530704800 -32400 0 AKST}
+    {544618800 -28800 1 AKDT}
+    {562154400 -32400 0 AKST}
+    {576068400 -28800 1 AKDT}
+    {594208800 -32400 0 AKST}
+    {607518000 -28800 1 AKDT}
+    {625658400 -32400 0 AKST}
+    {638967600 -28800 1 AKDT}
+    {657108000 -32400 0 AKST}
+    {671022000 -28800 1 AKDT}
+    {688557600 -32400 0 AKST}
+    {702471600 -28800 1 AKDT}
+    {720007200 -32400 0 AKST}
+    {733921200 -28800 1 AKDT}
+    {752061600 -32400 0 AKST}
+    {765370800 -28800 1 AKDT}
+    {783511200 -32400 0 AKST}
+    {796820400 -28800 1 AKDT}
+    {814960800 -32400 0 AKST}
+    {828874800 -28800 1 AKDT}
+    {846410400 -32400 0 AKST}
+    {860324400 -28800 1 AKDT}
+    {877860000 -32400 0 AKST}
+    {891774000 -28800 1 AKDT}
+    {909309600 -32400 0 AKST}
+    {923223600 -28800 1 AKDT}
+    {941364000 -32400 0 AKST}
+    {954673200 -28800 1 AKDT}
+    {972813600 -32400 0 AKST}
+    {986122800 -28800 1 AKDT}
+    {1004263200 -32400 0 AKST}
+    {1018177200 -28800 1 AKDT}
+    {1035712800 -32400 0 AKST}
+    {1049626800 -28800 1 AKDT}
+    {1067162400 -32400 0 AKST}
+    {1081076400 -28800 1 AKDT}
+    {1099216800 -32400 0 AKST}
+    {1112526000 -28800 1 AKDT}
+    {1130666400 -32400 0 AKST}
+    {1143975600 -28800 1 AKDT}
+    {1162116000 -32400 0 AKST}
+    {1173610800 -28800 1 AKDT}
+    {1194170400 -32400 0 AKST}
+    {1205060400 -28800 1 AKDT}
+    {1225620000 -32400 0 AKST}
+    {1236510000 -28800 1 AKDT}
+    {1257069600 -32400 0 AKST}
+    {1268564400 -28800 1 AKDT}
+    {1289124000 -32400 0 AKST}
+    {1300014000 -28800 1 AKDT}
+    {1320573600 -32400 0 AKST}
+    {1331463600 -28800 1 AKDT}
+    {1352023200 -32400 0 AKST}
+    {1362913200 -28800 1 AKDT}
+    {1383472800 -32400 0 AKST}
+    {1394362800 -28800 1 AKDT}
+    {1414922400 -32400 0 AKST}
+    {1425812400 -28800 1 AKDT}
+    {1446372000 -32400 0 AKST}
+    {1457866800 -28800 1 AKDT}
+    {1478426400 -32400 0 AKST}
+    {1489316400 -28800 1 AKDT}
+    {1509876000 -32400 0 AKST}
+    {1520766000 -28800 1 AKDT}
+    {1541325600 -32400 0 AKST}
+    {1552215600 -28800 1 AKDT}
+    {1572775200 -32400 0 AKST}
+    {1583665200 -28800 1 AKDT}
+    {1604224800 -32400 0 AKST}
+    {1615719600 -28800 1 AKDT}
+    {1636279200 -32400 0 AKST}
+    {1647169200 -28800 1 AKDT}
+    {1667728800 -32400 0 AKST}
+    {1678618800 -28800 1 AKDT}
+    {1699178400 -32400 0 AKST}
+    {1710068400 -28800 1 AKDT}
+    {1730628000 -32400 0 AKST}
+    {1741518000 -28800 1 AKDT}
+    {1762077600 -32400 0 AKST}
+    {1772967600 -28800 1 AKDT}
+    {1793527200 -32400 0 AKST}
+    {1805022000 -28800 1 AKDT}
+    {1825581600 -32400 0 AKST}
+    {1836471600 -28800 1 AKDT}
+    {1857031200 -32400 0 AKST}
+    {1867921200 -28800 1 AKDT}
+    {1888480800 -32400 0 AKST}
+    {1899370800 -28800 1 AKDT}
+    {1919930400 -32400 0 AKST}
+    {1930820400 -28800 1 AKDT}
+    {1951380000 -32400 0 AKST}
+    {1962874800 -28800 1 AKDT}
+    {1983434400 -32400 0 AKST}
+    {1994324400 -28800 1 AKDT}
+    {2014884000 -32400 0 AKST}
+    {2025774000 -28800 1 AKDT}
+    {2046333600 -32400 0 AKST}
+    {2057223600 -28800 1 AKDT}
+    {2077783200 -32400 0 AKST}
+    {2088673200 -28800 1 AKDT}
+    {2109232800 -32400 0 AKST}
+    {2120122800 -28800 1 AKDT}
+    {2140682400 -32400 0 AKST}
+    {2152177200 -28800 1 AKDT}
+    {2172736800 -32400 0 AKST}
+    {2183626800 -28800 1 AKDT}
+    {2204186400 -32400 0 AKST}
+    {2215076400 -28800 1 AKDT}
+    {2235636000 -32400 0 AKST}
+    {2246526000 -28800 1 AKDT}
+    {2267085600 -32400 0 AKST}
+    {2277975600 -28800 1 AKDT}
+    {2298535200 -32400 0 AKST}
+    {2309425200 -28800 1 AKDT}
+    {2329984800 -32400 0 AKST}
+    {2341479600 -28800 1 AKDT}
+    {2362039200 -32400 0 AKST}
+    {2372929200 -28800 1 AKDT}
+    {2393488800 -32400 0 AKST}
+    {2404378800 -28800 1 AKDT}
+    {2424938400 -32400 0 AKST}
+    {2435828400 -28800 1 AKDT}
+    {2456388000 -32400 0 AKST}
+    {2467278000 -28800 1 AKDT}
+    {2487837600 -32400 0 AKST}
+    {2499332400 -28800 1 AKDT}
+    {2519892000 -32400 0 AKST}
+    {2530782000 -28800 1 AKDT}
+    {2551341600 -32400 0 AKST}
+    {2562231600 -28800 1 AKDT}
+    {2582791200 -32400 0 AKST}
+    {2593681200 -28800 1 AKDT}
+    {2614240800 -32400 0 AKST}
+    {2625130800 -28800 1 AKDT}
+    {2645690400 -32400 0 AKST}
+    {2656580400 -28800 1 AKDT}
+    {2677140000 -32400 0 AKST}
+    {2688634800 -28800 1 AKDT}
+    {2709194400 -32400 0 AKST}
+    {2720084400 -28800 1 AKDT}
+    {2740644000 -32400 0 AKST}
+    {2751534000 -28800 1 AKDT}
+    {2772093600 -32400 0 AKST}
+    {2782983600 -28800 1 AKDT}
+    {2803543200 -32400 0 AKST}
+    {2814433200 -28800 1 AKDT}
+    {2834992800 -32400 0 AKST}
+    {2846487600 -28800 1 AKDT}
+    {2867047200 -32400 0 AKST}
+    {2877937200 -28800 1 AKDT}
+    {2898496800 -32400 0 AKST}
+    {2909386800 -28800 1 AKDT}
+    {2929946400 -32400 0 AKST}
+    {2940836400 -28800 1 AKDT}
+    {2961396000 -32400 0 AKST}
+    {2972286000 -28800 1 AKDT}
+    {2992845600 -32400 0 AKST}
+    {3003735600 -28800 1 AKDT}
+    {3024295200 -32400 0 AKST}
+    {3035790000 -28800 1 AKDT}
+    {3056349600 -32400 0 AKST}
+    {3067239600 -28800 1 AKDT}
+    {3087799200 -32400 0 AKST}
+    {3098689200 -28800 1 AKDT}
+    {3119248800 -32400 0 AKST}
+    {3130138800 -28800 1 AKDT}
+    {3150698400 -32400 0 AKST}
+    {3161588400 -28800 1 AKDT}
+    {3182148000 -32400 0 AKST}
+    {3193038000 -28800 1 AKDT}
+    {3213597600 -32400 0 AKST}
+    {3225092400 -28800 1 AKDT}
+    {3245652000 -32400 0 AKST}
+    {3256542000 -28800 1 AKDT}
+    {3277101600 -32400 0 AKST}
+    {3287991600 -28800 1 AKDT}
+    {3308551200 -32400 0 AKST}
+    {3319441200 -28800 1 AKDT}
+    {3340000800 -32400 0 AKST}
+    {3350890800 -28800 1 AKDT}
+    {3371450400 -32400 0 AKST}
+    {3382945200 -28800 1 AKDT}
+    {3403504800 -32400 0 AKST}
+    {3414394800 -28800 1 AKDT}
+    {3434954400 -32400 0 AKST}
+    {3445844400 -28800 1 AKDT}
+    {3466404000 -32400 0 AKST}
+    {3477294000 -28800 1 AKDT}
+    {3497853600 -32400 0 AKST}
+    {3508743600 -28800 1 AKDT}
+    {3529303200 -32400 0 AKST}
+    {3540193200 -28800 1 AKDT}
+    {3560752800 -32400 0 AKST}
+    {3572247600 -28800 1 AKDT}
+    {3592807200 -32400 0 AKST}
+    {3603697200 -28800 1 AKDT}
+    {3624256800 -32400 0 AKST}
+    {3635146800 -28800 1 AKDT}
+    {3655706400 -32400 0 AKST}
+    {3666596400 -28800 1 AKDT}
+    {3687156000 -32400 0 AKST}
+    {3698046000 -28800 1 AKDT}
+    {3718605600 -32400 0 AKST}
+    {3730100400 -28800 1 AKDT}
+    {3750660000 -32400 0 AKST}
+    {3761550000 -28800 1 AKDT}
+    {3782109600 -32400 0 AKST}
+    {3792999600 -28800 1 AKDT}
+    {3813559200 -32400 0 AKST}
+    {3824449200 -28800 1 AKDT}
+    {3845008800 -32400 0 AKST}
+    {3855898800 -28800 1 AKDT}
+    {3876458400 -32400 0 AKST}
+    {3887348400 -28800 1 AKDT}
+    {3907908000 -32400 0 AKST}
+    {3919402800 -28800 1 AKDT}
+    {3939962400 -32400 0 AKST}
+    {3950852400 -28800 1 AKDT}
+    {3971412000 -32400 0 AKST}
+    {3982302000 -28800 1 AKDT}
+    {4002861600 -32400 0 AKST}
+    {4013751600 -28800 1 AKDT}
+    {4034311200 -32400 0 AKST}
+    {4045201200 -28800 1 AKDT}
+    {4065760800 -32400 0 AKST}
+    {4076650800 -28800 1 AKDT}
+    {4097210400 -32400 0 AKST}
+}
diff --git a/library/tzdata/America/St_Barthelemy b/library/tzdata/America/St_Barthelemy
new file mode 100644
index 0000000..46bc287
--- /dev/null
+++ b/library/tzdata/America/St_Barthelemy
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(America/Port_of_Spain)]} {
+    LoadTimeZoneFile America/Port_of_Spain
+}
+set TZData(:America/St_Barthelemy) $TZData(:America/Port_of_Spain)
diff --git a/library/tzdata/America/St_Johns b/library/tzdata/America/St_Johns
new file mode 100644
index 0000000..1492961
--- /dev/null
+++ b/library/tzdata/America/St_Johns
@@ -0,0 +1,372 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/St_Johns) {
+    {-9223372036854775808 -12652 0 LMT}
+    {-2713897748 -12652 0 NST}
+    {-1664130548 -9052 1 NDT}
+    {-1650137348 -12652 0 NST}
+    {-1640982548 -12652 0 NST}
+    {-1632076148 -9052 1 NDT}
+    {-1615145348 -12652 0 NST}
+    {-1609446548 -12652 0 NST}
+    {-1598650148 -9052 1 NDT}
+    {-1590100148 -12652 0 NST}
+    {-1567286948 -9052 1 NDT}
+    {-1551565748 -12652 0 NST}
+    {-1535837348 -9052 1 NDT}
+    {-1520116148 -12652 0 NST}
+    {-1503782948 -9052 1 NDT}
+    {-1488666548 -12652 0 NST}
+    {-1472333348 -9052 1 NDT}
+    {-1457216948 -12652 0 NST}
+    {-1440883748 -9052 1 NDT}
+    {-1425767348 -12652 0 NST}
+    {-1409434148 -9052 1 NDT}
+    {-1394317748 -12652 0 NST}
+    {-1377984548 -9052 1 NDT}
+    {-1362263348 -12652 0 NST}
+    {-1346534948 -9052 1 NDT}
+    {-1330813748 -12652 0 NST}
+    {-1314480548 -9052 1 NDT}
+    {-1299364148 -12652 0 NST}
+    {-1283030948 -9052 1 NDT}
+    {-1267914548 -12652 0 NST}
+    {-1251581348 -9052 1 NDT}
+    {-1236464948 -12652 0 NST}
+    {-1220131748 -9052 1 NDT}
+    {-1205015348 -12652 0 NST}
+    {-1188682148 -9052 1 NDT}
+    {-1172960948 -12652 0 NST}
+    {-1156627748 -9052 1 NDT}
+    {-1141511348 -12652 0 NST}
+    {-1125178148 -9052 1 NDT}
+    {-1110061748 -12652 0 NST}
+    {-1096921748 -12600 0 NST}
+    {-1093728600 -9000 1 NDT}
+    {-1078612200 -12600 0 NST}
+    {-1061670600 -9000 1 NDT}
+    {-1048973400 -12600 0 NST}
+    {-1030221000 -9000 1 NDT}
+    {-1017523800 -12600 0 NST}
+    {-998771400 -9000 1 NDT}
+    {-986074200 -12600 0 NST}
+    {-966717000 -9000 1 NDT}
+    {-954624600 -12600 0 NST}
+    {-935267400 -9000 1 NDT}
+    {-922570200 -12600 0 NST}
+    {-903817800 -9000 1 NDT}
+    {-891120600 -12600 0 NST}
+    {-872368200 -9000 0 NWT}
+    {-769395600 -9000 1 NPT}
+    {-765401400 -12600 0 NST}
+    {-757369800 -12600 0 NST}
+    {-746044200 -9000 1 NDT}
+    {-733347000 -12600 0 NST}
+    {-714594600 -9000 1 NDT}
+    {-701897400 -12600 0 NST}
+    {-683145000 -9000 1 NDT}
+    {-670447800 -12600 0 NST}
+    {-651695400 -9000 1 NDT}
+    {-638998200 -12600 0 NST}
+    {-619641000 -9000 1 NDT}
+    {-606943800 -12600 0 NST}
+    {-589401000 -9000 1 NDT}
+    {-576099000 -12600 0 NST}
+    {-557951400 -9000 1 NDT}
+    {-544649400 -12600 0 NST}
+    {-526501800 -9000 1 NDT}
+    {-513199800 -12600 0 NST}
+    {-495052200 -9000 1 NDT}
+    {-481750200 -12600 0 NST}
+    {-463602600 -9000 1 NDT}
+    {-450300600 -12600 0 NST}
+    {-431548200 -9000 1 NDT}
+    {-418246200 -12600 0 NST}
+    {-400098600 -9000 1 NDT}
+    {-386796600 -12600 0 NST}
+    {-368649000 -9000 1 NDT}
+    {-355347000 -12600 0 NST}
+    {-337199400 -9000 1 NDT}
+    {-323897400 -12600 0 NST}
+    {-305749800 -9000 1 NDT}
+    {-289423800 -12600 0 NST}
+    {-273695400 -9000 1 NDT}
+    {-257974200 -12600 0 NST}
+    {-242245800 -9000 1 NDT}
+    {-226524600 -12600 0 NST}
+    {-210796200 -9000 1 NDT}
+    {-195075000 -12600 0 NST}
+    {-179346600 -9000 1 NDT}
+    {-163625400 -12600 0 NST}
+    {-147897000 -9000 1 NDT}
+    {-131571000 -12600 0 NST}
+    {-116447400 -9000 1 NDT}
+    {-100121400 -12600 0 NST}
+    {-84393000 -9000 1 NDT}
+    {-68671800 -12600 0 NST}
+    {-52943400 -9000 1 NDT}
+    {-37222200 -12600 0 NST}
+    {-21493800 -9000 1 NDT}
+    {-5772600 -12600 0 NST}
+    {9955800 -9000 1 NDT}
+    {25677000 -12600 0 NST}
+    {41405400 -9000 1 NDT}
+    {57731400 -12600 0 NST}
+    {73459800 -9000 1 NDT}
+    {89181000 -12600 0 NST}
+    {104909400 -9000 1 NDT}
+    {120630600 -12600 0 NST}
+    {136359000 -9000 1 NDT}
+    {152080200 -12600 0 NST}
+    {167808600 -9000 1 NDT}
+    {183529800 -12600 0 NST}
+    {199258200 -9000 1 NDT}
+    {215584200 -12600 0 NST}
+    {230707800 -9000 1 NDT}
+    {247033800 -12600 0 NST}
+    {262762200 -9000 1 NDT}
+    {278483400 -12600 0 NST}
+    {294211800 -9000 1 NDT}
+    {309933000 -12600 0 NST}
+    {325661400 -9000 1 NDT}
+    {341382600 -12600 0 NST}
+    {357111000 -9000 1 NDT}
+    {372832200 -12600 0 NST}
+    {388560600 -9000 1 NDT}
+    {404886600 -12600 0 NST}
+    {420010200 -9000 1 NDT}
+    {436336200 -12600 0 NST}
+    {452064600 -9000 1 NDT}
+    {467785800 -12600 0 NST}
+    {483514200 -9000 1 NDT}
+    {499235400 -12600 0 NST}
+    {514963800 -9000 1 NDT}
+    {530685000 -12600 0 NST}
+    {544591860 -9000 1 NDT}
+    {562127460 -12600 0 NST}
+    {576041460 -5400 1 NDDT}
+    {594178260 -12600 0 NST}
+    {607491060 -9000 1 NDT}
+    {625631460 -12600 0 NST}
+    {638940660 -9000 1 NDT}
+    {657081060 -12600 0 NST}
+    {670995060 -9000 1 NDT}
+    {688530660 -12600 0 NST}
+    {702444660 -9000 1 NDT}
+    {719980260 -12600 0 NST}
+    {733894260 -9000 1 NDT}
+    {752034660 -12600 0 NST}
+    {765343860 -9000 1 NDT}
+    {783484260 -12600 0 NST}
+    {796793460 -9000 1 NDT}
+    {814933860 -12600 0 NST}
+    {828847860 -9000 1 NDT}
+    {846383460 -12600 0 NST}
+    {860297460 -9000 1 NDT}
+    {877833060 -12600 0 NST}
+    {891747060 -9000 1 NDT}
+    {909282660 -12600 0 NST}
+    {923196660 -9000 1 NDT}
+    {941337060 -12600 0 NST}
+    {954646260 -9000 1 NDT}
+    {972786660 -12600 0 NST}
+    {986095860 -9000 1 NDT}
+    {1004236260 -12600 0 NST}
+    {1018150260 -9000 1 NDT}
+    {1035685860 -12600 0 NST}
+    {1049599860 -9000 1 NDT}
+    {1067135460 -12600 0 NST}
+    {1081049460 -9000 1 NDT}
+    {1099189860 -12600 0 NST}
+    {1112499060 -9000 1 NDT}
+    {1130639460 -12600 0 NST}
+    {1143948660 -9000 1 NDT}
+    {1162089060 -12600 0 NST}
+    {1173583860 -9000 1 NDT}
+    {1194143460 -12600 0 NST}
+    {1205033460 -9000 1 NDT}
+    {1225593060 -12600 0 NST}
+    {1236483060 -9000 1 NDT}
+    {1257042660 -12600 0 NST}
+    {1268537460 -9000 1 NDT}
+    {1289097060 -12600 0 NST}
+    {1299987060 -9000 1 NDT}
+    {1320114600 -9000 0 NDT}
+    {1320553800 -12600 0 NST}
+    {1331443800 -9000 1 NDT}
+    {1352003400 -12600 0 NST}
+    {1362893400 -9000 1 NDT}
+    {1383453000 -12600 0 NST}
+    {1394343000 -9000 1 NDT}
+    {1414902600 -12600 0 NST}
+    {1425792600 -9000 1 NDT}
+    {1446352200 -12600 0 NST}
+    {1457847000 -9000 1 NDT}
+    {1478406600 -12600 0 NST}
+    {1489296600 -9000 1 NDT}
+    {1509856200 -12600 0 NST}
+    {1520746200 -9000 1 NDT}
+    {1541305800 -12600 0 NST}
+    {1552195800 -9000 1 NDT}
+    {1572755400 -12600 0 NST}
+    {1583645400 -9000 1 NDT}
+    {1604205000 -12600 0 NST}
+    {1615699800 -9000 1 NDT}
+    {1636259400 -12600 0 NST}
+    {1647149400 -9000 1 NDT}
+    {1667709000 -12600 0 NST}
+    {1678599000 -9000 1 NDT}
+    {1699158600 -12600 0 NST}
+    {1710048600 -9000 1 NDT}
+    {1730608200 -12600 0 NST}
+    {1741498200 -9000 1 NDT}
+    {1762057800 -12600 0 NST}
+    {1772947800 -9000 1 NDT}
+    {1793507400 -12600 0 NST}
+    {1805002200 -9000 1 NDT}
+    {1825561800 -12600 0 NST}
+    {1836451800 -9000 1 NDT}
+    {1857011400 -12600 0 NST}
+    {1867901400 -9000 1 NDT}
+    {1888461000 -12600 0 NST}
+    {1899351000 -9000 1 NDT}
+    {1919910600 -12600 0 NST}
+    {1930800600 -9000 1 NDT}
+    {1951360200 -12600 0 NST}
+    {1962855000 -9000 1 NDT}
+    {1983414600 -12600 0 NST}
+    {1994304600 -9000 1 NDT}
+    {2014864200 -12600 0 NST}
+    {2025754200 -9000 1 NDT}
+    {2046313800 -12600 0 NST}
+    {2057203800 -9000 1 NDT}
+    {2077763400 -12600 0 NST}
+    {2088653400 -9000 1 NDT}
+    {2109213000 -12600 0 NST}
+    {2120103000 -9000 1 NDT}
+    {2140662600 -12600 0 NST}
+    {2152157400 -9000 1 NDT}
+    {2172717000 -12600 0 NST}
+    {2183607000 -9000 1 NDT}
+    {2204166600 -12600 0 NST}
+    {2215056600 -9000 1 NDT}
+    {2235616200 -12600 0 NST}
+    {2246506200 -9000 1 NDT}
+    {2267065800 -12600 0 NST}
+    {2277955800 -9000 1 NDT}
+    {2298515400 -12600 0 NST}
+    {2309405400 -9000 1 NDT}
+    {2329965000 -12600 0 NST}
+    {2341459800 -9000 1 NDT}
+    {2362019400 -12600 0 NST}
+    {2372909400 -9000 1 NDT}
+    {2393469000 -12600 0 NST}
+    {2404359000 -9000 1 NDT}
+    {2424918600 -12600 0 NST}
+    {2435808600 -9000 1 NDT}
+    {2456368200 -12600 0 NST}
+    {2467258200 -9000 1 NDT}
+    {2487817800 -12600 0 NST}
+    {2499312600 -9000 1 NDT}
+    {2519872200 -12600 0 NST}
+    {2530762200 -9000 1 NDT}
+    {2551321800 -12600 0 NST}
+    {2562211800 -9000 1 NDT}
+    {2582771400 -12600 0 NST}
+    {2593661400 -9000 1 NDT}
+    {2614221000 -12600 0 NST}
+    {2625111000 -9000 1 NDT}
+    {2645670600 -12600 0 NST}
+    {2656560600 -9000 1 NDT}
+    {2677120200 -12600 0 NST}
+    {2688615000 -9000 1 NDT}
+    {2709174600 -12600 0 NST}
+    {2720064600 -9000 1 NDT}
+    {2740624200 -12600 0 NST}
+    {2751514200 -9000 1 NDT}
+    {2772073800 -12600 0 NST}
+    {2782963800 -9000 1 NDT}
+    {2803523400 -12600 0 NST}
+    {2814413400 -9000 1 NDT}
+    {2834973000 -12600 0 NST}
+    {2846467800 -9000 1 NDT}
+    {2867027400 -12600 0 NST}
+    {2877917400 -9000 1 NDT}
+    {2898477000 -12600 0 NST}
+    {2909367000 -9000 1 NDT}
+    {2929926600 -12600 0 NST}
+    {2940816600 -9000 1 NDT}
+    {2961376200 -12600 0 NST}
+    {2972266200 -9000 1 NDT}
+    {2992825800 -12600 0 NST}
+    {3003715800 -9000 1 NDT}
+    {3024275400 -12600 0 NST}
+    {3035770200 -9000 1 NDT}
+    {3056329800 -12600 0 NST}
+    {3067219800 -9000 1 NDT}
+    {3087779400 -12600 0 NST}
+    {3098669400 -9000 1 NDT}
+    {3119229000 -12600 0 NST}
+    {3130119000 -9000 1 NDT}
+    {3150678600 -12600 0 NST}
+    {3161568600 -9000 1 NDT}
+    {3182128200 -12600 0 NST}
+    {3193018200 -9000 1 NDT}
+    {3213577800 -12600 0 NST}
+    {3225072600 -9000 1 NDT}
+    {3245632200 -12600 0 NST}
+    {3256522200 -9000 1 NDT}
+    {3277081800 -12600 0 NST}
+    {3287971800 -9000 1 NDT}
+    {3308531400 -12600 0 NST}
+    {3319421400 -9000 1 NDT}
+    {3339981000 -12600 0 NST}
+    {3350871000 -9000 1 NDT}
+    {3371430600 -12600 0 NST}
+    {3382925400 -9000 1 NDT}
+    {3403485000 -12600 0 NST}
+    {3414375000 -9000 1 NDT}
+    {3434934600 -12600 0 NST}
+    {3445824600 -9000 1 NDT}
+    {3466384200 -12600 0 NST}
+    {3477274200 -9000 1 NDT}
+    {3497833800 -12600 0 NST}
+    {3508723800 -9000 1 NDT}
+    {3529283400 -12600 0 NST}
+    {3540173400 -9000 1 NDT}
+    {3560733000 -12600 0 NST}
+    {3572227800 -9000 1 NDT}
+    {3592787400 -12600 0 NST}
+    {3603677400 -9000 1 NDT}
+    {3624237000 -12600 0 NST}
+    {3635127000 -9000 1 NDT}
+    {3655686600 -12600 0 NST}
+    {3666576600 -9000 1 NDT}
+    {3687136200 -12600 0 NST}
+    {3698026200 -9000 1 NDT}
+    {3718585800 -12600 0 NST}
+    {3730080600 -9000 1 NDT}
+    {3750640200 -12600 0 NST}
+    {3761530200 -9000 1 NDT}
+    {3782089800 -12600 0 NST}
+    {3792979800 -9000 1 NDT}
+    {3813539400 -12600 0 NST}
+    {3824429400 -9000 1 NDT}
+    {3844989000 -12600 0 NST}
+    {3855879000 -9000 1 NDT}
+    {3876438600 -12600 0 NST}
+    {3887328600 -9000 1 NDT}
+    {3907888200 -12600 0 NST}
+    {3919383000 -9000 1 NDT}
+    {3939942600 -12600 0 NST}
+    {3950832600 -9000 1 NDT}
+    {3971392200 -12600 0 NST}
+    {3982282200 -9000 1 NDT}
+    {4002841800 -12600 0 NST}
+    {4013731800 -9000 1 NDT}
+    {4034291400 -12600 0 NST}
+    {4045181400 -9000 1 NDT}
+    {4065741000 -12600 0 NST}
+    {4076631000 -9000 1 NDT}
+    {4097190600 -12600 0 NST}
+}
diff --git a/library/tzdata/America/St_Kitts b/library/tzdata/America/St_Kitts
new file mode 100644
index 0000000..6ad7f04
--- /dev/null
+++ b/library/tzdata/America/St_Kitts
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(America/Port_of_Spain)]} {
+    LoadTimeZoneFile America/Port_of_Spain
+}
+set TZData(:America/St_Kitts) $TZData(:America/Port_of_Spain)
diff --git a/library/tzdata/America/St_Lucia b/library/tzdata/America/St_Lucia
new file mode 100644
index 0000000..e479b31
--- /dev/null
+++ b/library/tzdata/America/St_Lucia
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(America/Port_of_Spain)]} {
+    LoadTimeZoneFile America/Port_of_Spain
+}
+set TZData(:America/St_Lucia) $TZData(:America/Port_of_Spain)
diff --git a/library/tzdata/America/St_Thomas b/library/tzdata/America/St_Thomas
new file mode 100644
index 0000000..24698b8
--- /dev/null
+++ b/library/tzdata/America/St_Thomas
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(America/Port_of_Spain)]} {
+    LoadTimeZoneFile America/Port_of_Spain
+}
+set TZData(:America/St_Thomas) $TZData(:America/Port_of_Spain)
diff --git a/library/tzdata/America/St_Vincent b/library/tzdata/America/St_Vincent
new file mode 100644
index 0000000..e3b32fb
--- /dev/null
+++ b/library/tzdata/America/St_Vincent
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(America/Port_of_Spain)]} {
+    LoadTimeZoneFile America/Port_of_Spain
+}
+set TZData(:America/St_Vincent) $TZData(:America/Port_of_Spain)
diff --git a/library/tzdata/America/Swift_Current b/library/tzdata/America/Swift_Current
new file mode 100644
index 0000000..ad07762
--- /dev/null
+++ b/library/tzdata/America/Swift_Current
@@ -0,0 +1,29 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Swift_Current) {
+    {-9223372036854775808 -25880 0 LMT}
+    {-2030201320 -25200 0 MST}
+    {-1632063600 -21600 1 MDT}
+    {-1615132800 -25200 0 MST}
+    {-880210800 -21600 1 MWT}
+    {-769395600 -21600 1 MPT}
+    {-765388800 -25200 0 MST}
+    {-747241200 -21600 0 MDT}
+    {-732729600 -25200 0 MST}
+    {-715791600 -21600 1 MDT}
+    {-702489600 -25200 0 MST}
+    {-684342000 -21600 1 MDT}
+    {-671040000 -25200 0 MST}
+    {-652892400 -21600 1 MDT}
+    {-639590400 -25200 0 MST}
+    {-631126800 -25200 0 MST}
+    {-400086000 -21600 1 MDT}
+    {-384364800 -25200 0 MST}
+    {-337186800 -21600 1 MDT}
+    {-321465600 -25200 0 MST}
+    {-305737200 -21600 1 MDT}
+    {-292435200 -25200 0 MST}
+    {-273682800 -21600 1 MDT}
+    {-260985600 -25200 0 MST}
+    {73472400 -21600 0 CST}
+}
diff --git a/library/tzdata/America/Tegucigalpa b/library/tzdata/America/Tegucigalpa
new file mode 100644
index 0000000..050661e
--- /dev/null
+++ b/library/tzdata/America/Tegucigalpa
@@ -0,0 +1,12 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Tegucigalpa) {
+    {-9223372036854775808 -20932 0 LMT}
+    {-1538503868 -21600 0 CST}
+    {547020000 -18000 1 CDT}
+    {559717200 -21600 0 CST}
+    {578469600 -18000 1 CDT}
+    {591166800 -21600 0 CST}
+    {1146981600 -18000 1 CDT}
+    {1154926800 -21600 0 CST}
+}
diff --git a/library/tzdata/America/Thule b/library/tzdata/America/Thule
new file mode 100644
index 0000000..0aaf9a1
--- /dev/null
+++ b/library/tzdata/America/Thule
@@ -0,0 +1,224 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Thule) {
+    {-9223372036854775808 -16508 0 LMT}
+    {-1686079492 -14400 0 AST}
+    {670399200 -10800 1 ADT}
+    {686120400 -14400 0 AST}
+    {701848800 -10800 1 ADT}
+    {717570000 -14400 0 AST}
+    {733903200 -10800 1 ADT}
+    {752043600 -14400 0 AST}
+    {765352800 -10800 1 ADT}
+    {783493200 -14400 0 AST}
+    {796802400 -10800 1 ADT}
+    {814942800 -14400 0 AST}
+    {828856800 -10800 1 ADT}
+    {846392400 -14400 0 AST}
+    {860306400 -10800 1 ADT}
+    {877842000 -14400 0 AST}
+    {891756000 -10800 1 ADT}
+    {909291600 -14400 0 AST}
+    {923205600 -10800 1 ADT}
+    {941346000 -14400 0 AST}
+    {954655200 -10800 1 ADT}
+    {972795600 -14400 0 AST}
+    {986104800 -10800 1 ADT}
+    {1004245200 -14400 0 AST}
+    {1018159200 -10800 1 ADT}
+    {1035694800 -14400 0 AST}
+    {1049608800 -10800 1 ADT}
+    {1067144400 -14400 0 AST}
+    {1081058400 -10800 1 ADT}
+    {1099198800 -14400 0 AST}
+    {1112508000 -10800 1 ADT}
+    {1130648400 -14400 0 AST}
+    {1143957600 -10800 1 ADT}
+    {1162098000 -14400 0 AST}
+    {1173592800 -10800 1 ADT}
+    {1194152400 -14400 0 AST}
+    {1205042400 -10800 1 ADT}
+    {1225602000 -14400 0 AST}
+    {1236492000 -10800 1 ADT}
+    {1257051600 -14400 0 AST}
+    {1268546400 -10800 1 ADT}
+    {1289106000 -14400 0 AST}
+    {1299996000 -10800 1 ADT}
+    {1320555600 -14400 0 AST}
+    {1331445600 -10800 1 ADT}
+    {1352005200 -14400 0 AST}
+    {1362895200 -10800 1 ADT}
+    {1383454800 -14400 0 AST}
+    {1394344800 -10800 1 ADT}
+    {1414904400 -14400 0 AST}
+    {1425794400 -10800 1 ADT}
+    {1446354000 -14400 0 AST}
+    {1457848800 -10800 1 ADT}
+    {1478408400 -14400 0 AST}
+    {1489298400 -10800 1 ADT}
+    {1509858000 -14400 0 AST}
+    {1520748000 -10800 1 ADT}
+    {1541307600 -14400 0 AST}
+    {1552197600 -10800 1 ADT}
+    {1572757200 -14400 0 AST}
+    {1583647200 -10800 1 ADT}
+    {1604206800 -14400 0 AST}
+    {1615701600 -10800 1 ADT}
+    {1636261200 -14400 0 AST}
+    {1647151200 -10800 1 ADT}
+    {1667710800 -14400 0 AST}
+    {1678600800 -10800 1 ADT}
+    {1699160400 -14400 0 AST}
+    {1710050400 -10800 1 ADT}
+    {1730610000 -14400 0 AST}
+    {1741500000 -10800 1 ADT}
+    {1762059600 -14400 0 AST}
+    {1772949600 -10800 1 ADT}
+    {1793509200 -14400 0 AST}
+    {1805004000 -10800 1 ADT}
+    {1825563600 -14400 0 AST}
+    {1836453600 -10800 1 ADT}
+    {1857013200 -14400 0 AST}
+    {1867903200 -10800 1 ADT}
+    {1888462800 -14400 0 AST}
+    {1899352800 -10800 1 ADT}
+    {1919912400 -14400 0 AST}
+    {1930802400 -10800 1 ADT}
+    {1951362000 -14400 0 AST}
+    {1962856800 -10800 1 ADT}
+    {1983416400 -14400 0 AST}
+    {1994306400 -10800 1 ADT}
+    {2014866000 -14400 0 AST}
+    {2025756000 -10800 1 ADT}
+    {2046315600 -14400 0 AST}
+    {2057205600 -10800 1 ADT}
+    {2077765200 -14400 0 AST}
+    {2088655200 -10800 1 ADT}
+    {2109214800 -14400 0 AST}
+    {2120104800 -10800 1 ADT}
+    {2140664400 -14400 0 AST}
+    {2152159200 -10800 1 ADT}
+    {2172718800 -14400 0 AST}
+    {2183608800 -10800 1 ADT}
+    {2204168400 -14400 0 AST}
+    {2215058400 -10800 1 ADT}
+    {2235618000 -14400 0 AST}
+    {2246508000 -10800 1 ADT}
+    {2267067600 -14400 0 AST}
+    {2277957600 -10800 1 ADT}
+    {2298517200 -14400 0 AST}
+    {2309407200 -10800 1 ADT}
+    {2329966800 -14400 0 AST}
+    {2341461600 -10800 1 ADT}
+    {2362021200 -14400 0 AST}
+    {2372911200 -10800 1 ADT}
+    {2393470800 -14400 0 AST}
+    {2404360800 -10800 1 ADT}
+    {2424920400 -14400 0 AST}
+    {2435810400 -10800 1 ADT}
+    {2456370000 -14400 0 AST}
+    {2467260000 -10800 1 ADT}
+    {2487819600 -14400 0 AST}
+    {2499314400 -10800 1 ADT}
+    {2519874000 -14400 0 AST}
+    {2530764000 -10800 1 ADT}
+    {2551323600 -14400 0 AST}
+    {2562213600 -10800 1 ADT}
+    {2582773200 -14400 0 AST}
+    {2593663200 -10800 1 ADT}
+    {2614222800 -14400 0 AST}
+    {2625112800 -10800 1 ADT}
+    {2645672400 -14400 0 AST}
+    {2656562400 -10800 1 ADT}
+    {2677122000 -14400 0 AST}
+    {2688616800 -10800 1 ADT}
+    {2709176400 -14400 0 AST}
+    {2720066400 -10800 1 ADT}
+    {2740626000 -14400 0 AST}
+    {2751516000 -10800 1 ADT}
+    {2772075600 -14400 0 AST}
+    {2782965600 -10800 1 ADT}
+    {2803525200 -14400 0 AST}
+    {2814415200 -10800 1 ADT}
+    {2834974800 -14400 0 AST}
+    {2846469600 -10800 1 ADT}
+    {2867029200 -14400 0 AST}
+    {2877919200 -10800 1 ADT}
+    {2898478800 -14400 0 AST}
+    {2909368800 -10800 1 ADT}
+    {2929928400 -14400 0 AST}
+    {2940818400 -10800 1 ADT}
+    {2961378000 -14400 0 AST}
+    {2972268000 -10800 1 ADT}
+    {2992827600 -14400 0 AST}
+    {3003717600 -10800 1 ADT}
+    {3024277200 -14400 0 AST}
+    {3035772000 -10800 1 ADT}
+    {3056331600 -14400 0 AST}
+    {3067221600 -10800 1 ADT}
+    {3087781200 -14400 0 AST}
+    {3098671200 -10800 1 ADT}
+    {3119230800 -14400 0 AST}
+    {3130120800 -10800 1 ADT}
+    {3150680400 -14400 0 AST}
+    {3161570400 -10800 1 ADT}
+    {3182130000 -14400 0 AST}
+    {3193020000 -10800 1 ADT}
+    {3213579600 -14400 0 AST}
+    {3225074400 -10800 1 ADT}
+    {3245634000 -14400 0 AST}
+    {3256524000 -10800 1 ADT}
+    {3277083600 -14400 0 AST}
+    {3287973600 -10800 1 ADT}
+    {3308533200 -14400 0 AST}
+    {3319423200 -10800 1 ADT}
+    {3339982800 -14400 0 AST}
+    {3350872800 -10800 1 ADT}
+    {3371432400 -14400 0 AST}
+    {3382927200 -10800 1 ADT}
+    {3403486800 -14400 0 AST}
+    {3414376800 -10800 1 ADT}
+    {3434936400 -14400 0 AST}
+    {3445826400 -10800 1 ADT}
+    {3466386000 -14400 0 AST}
+    {3477276000 -10800 1 ADT}
+    {3497835600 -14400 0 AST}
+    {3508725600 -10800 1 ADT}
+    {3529285200 -14400 0 AST}
+    {3540175200 -10800 1 ADT}
+    {3560734800 -14400 0 AST}
+    {3572229600 -10800 1 ADT}
+    {3592789200 -14400 0 AST}
+    {3603679200 -10800 1 ADT}
+    {3624238800 -14400 0 AST}
+    {3635128800 -10800 1 ADT}
+    {3655688400 -14400 0 AST}
+    {3666578400 -10800 1 ADT}
+    {3687138000 -14400 0 AST}
+    {3698028000 -10800 1 ADT}
+    {3718587600 -14400 0 AST}
+    {3730082400 -10800 1 ADT}
+    {3750642000 -14400 0 AST}
+    {3761532000 -10800 1 ADT}
+    {3782091600 -14400 0 AST}
+    {3792981600 -10800 1 ADT}
+    {3813541200 -14400 0 AST}
+    {3824431200 -10800 1 ADT}
+    {3844990800 -14400 0 AST}
+    {3855880800 -10800 1 ADT}
+    {3876440400 -14400 0 AST}
+    {3887330400 -10800 1 ADT}
+    {3907890000 -14400 0 AST}
+    {3919384800 -10800 1 ADT}
+    {3939944400 -14400 0 AST}
+    {3950834400 -10800 1 ADT}
+    {3971394000 -14400 0 AST}
+    {3982284000 -10800 1 ADT}
+    {4002843600 -14400 0 AST}
+    {4013733600 -10800 1 ADT}
+    {4034293200 -14400 0 AST}
+    {4045183200 -10800 1 ADT}
+    {4065742800 -14400 0 AST}
+    {4076632800 -10800 1 ADT}
+    {4097192400 -14400 0 AST}
+}
diff --git a/library/tzdata/America/Thunder_Bay b/library/tzdata/America/Thunder_Bay
new file mode 100644
index 0000000..8a454be
--- /dev/null
+++ b/library/tzdata/America/Thunder_Bay
@@ -0,0 +1,272 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Thunder_Bay) {
+    {-9223372036854775808 -21420 0 LMT}
+    {-2366733780 -21600 0 CST}
+    {-1893434400 -18000 0 EST}
+    {-883594800 -18000 0 EST}
+    {-880218000 -14400 1 EWT}
+    {-769395600 -14400 1 EPT}
+    {-765396000 -18000 0 EST}
+    {18000 -18000 0 EST}
+    {9961200 -14400 1 EDT}
+    {25682400 -18000 0 EST}
+    {41410800 -14400 1 EDT}
+    {57736800 -18000 0 EST}
+    {73465200 -14400 1 EDT}
+    {89186400 -18000 0 EST}
+    {94712400 -18000 0 EST}
+    {126248400 -18000 0 EST}
+    {136364400 -14400 1 EDT}
+    {152085600 -18000 0 EST}
+    {167814000 -14400 1 EDT}
+    {183535200 -18000 0 EST}
+    {199263600 -14400 1 EDT}
+    {215589600 -18000 0 EST}
+    {230713200 -14400 1 EDT}
+    {247039200 -18000 0 EST}
+    {262767600 -14400 1 EDT}
+    {278488800 -18000 0 EST}
+    {294217200 -14400 1 EDT}
+    {309938400 -18000 0 EST}
+    {325666800 -14400 1 EDT}
+    {341388000 -18000 0 EST}
+    {357116400 -14400 1 EDT}
+    {372837600 -18000 0 EST}
+    {388566000 -14400 1 EDT}
+    {404892000 -18000 0 EST}
+    {420015600 -14400 1 EDT}
+    {436341600 -18000 0 EST}
+    {452070000 -14400 1 EDT}
+    {467791200 -18000 0 EST}
+    {483519600 -14400 1 EDT}
+    {499240800 -18000 0 EST}
+    {514969200 -14400 1 EDT}
+    {530690400 -18000 0 EST}
+    {544604400 -14400 1 EDT}
+    {562140000 -18000 0 EST}
+    {576054000 -14400 1 EDT}
+    {594194400 -18000 0 EST}
+    {607503600 -14400 1 EDT}
+    {625644000 -18000 0 EST}
+    {638953200 -14400 1 EDT}
+    {657093600 -18000 0 EST}
+    {671007600 -14400 1 EDT}
+    {688543200 -18000 0 EST}
+    {702457200 -14400 1 EDT}
+    {719992800 -18000 0 EST}
+    {733906800 -14400 1 EDT}
+    {752047200 -18000 0 EST}
+    {765356400 -14400 1 EDT}
+    {783496800 -18000 0 EST}
+    {796806000 -14400 1 EDT}
+    {814946400 -18000 0 EST}
+    {828860400 -14400 1 EDT}
+    {846396000 -18000 0 EST}
+    {860310000 -14400 1 EDT}
+    {877845600 -18000 0 EST}
+    {891759600 -14400 1 EDT}
+    {909295200 -18000 0 EST}
+    {923209200 -14400 1 EDT}
+    {941349600 -18000 0 EST}
+    {954658800 -14400 1 EDT}
+    {972799200 -18000 0 EST}
+    {986108400 -14400 1 EDT}
+    {1004248800 -18000 0 EST}
+    {1018162800 -14400 1 EDT}
+    {1035698400 -18000 0 EST}
+    {1049612400 -14400 1 EDT}
+    {1067148000 -18000 0 EST}
+    {1081062000 -14400 1 EDT}
+    {1099202400 -18000 0 EST}
+    {1112511600 -14400 1 EDT}
+    {1130652000 -18000 0 EST}
+    {1143961200 -14400 1 EDT}
+    {1162101600 -18000 0 EST}
+    {1173596400 -14400 1 EDT}
+    {1194156000 -18000 0 EST}
+    {1205046000 -14400 1 EDT}
+    {1225605600 -18000 0 EST}
+    {1236495600 -14400 1 EDT}
+    {1257055200 -18000 0 EST}
+    {1268550000 -14400 1 EDT}
+    {1289109600 -18000 0 EST}
+    {1299999600 -14400 1 EDT}
+    {1320559200 -18000 0 EST}
+    {1331449200 -14400 1 EDT}
+    {1352008800 -18000 0 EST}
+    {1362898800 -14400 1 EDT}
+    {1383458400 -18000 0 EST}
+    {1394348400 -14400 1 EDT}
+    {1414908000 -18000 0 EST}
+    {1425798000 -14400 1 EDT}
+    {1446357600 -18000 0 EST}
+    {1457852400 -14400 1 EDT}
+    {1478412000 -18000 0 EST}
+    {1489302000 -14400 1 EDT}
+    {1509861600 -18000 0 EST}
+    {1520751600 -14400 1 EDT}
+    {1541311200 -18000 0 EST}
+    {1552201200 -14400 1 EDT}
+    {1572760800 -18000 0 EST}
+    {1583650800 -14400 1 EDT}
+    {1604210400 -18000 0 EST}
+    {1615705200 -14400 1 EDT}
+    {1636264800 -18000 0 EST}
+    {1647154800 -14400 1 EDT}
+    {1667714400 -18000 0 EST}
+    {1678604400 -14400 1 EDT}
+    {1699164000 -18000 0 EST}
+    {1710054000 -14400 1 EDT}
+    {1730613600 -18000 0 EST}
+    {1741503600 -14400 1 EDT}
+    {1762063200 -18000 0 EST}
+    {1772953200 -14400 1 EDT}
+    {1793512800 -18000 0 EST}
+    {1805007600 -14400 1 EDT}
+    {1825567200 -18000 0 EST}
+    {1836457200 -14400 1 EDT}
+    {1857016800 -18000 0 EST}
+    {1867906800 -14400 1 EDT}
+    {1888466400 -18000 0 EST}
+    {1899356400 -14400 1 EDT}
+    {1919916000 -18000 0 EST}
+    {1930806000 -14400 1 EDT}
+    {1951365600 -18000 0 EST}
+    {1962860400 -14400 1 EDT}
+    {1983420000 -18000 0 EST}
+    {1994310000 -14400 1 EDT}
+    {2014869600 -18000 0 EST}
+    {2025759600 -14400 1 EDT}
+    {2046319200 -18000 0 EST}
+    {2057209200 -14400 1 EDT}
+    {2077768800 -18000 0 EST}
+    {2088658800 -14400 1 EDT}
+    {2109218400 -18000 0 EST}
+    {2120108400 -14400 1 EDT}
+    {2140668000 -18000 0 EST}
+    {2152162800 -14400 1 EDT}
+    {2172722400 -18000 0 EST}
+    {2183612400 -14400 1 EDT}
+    {2204172000 -18000 0 EST}
+    {2215062000 -14400 1 EDT}
+    {2235621600 -18000 0 EST}
+    {2246511600 -14400 1 EDT}
+    {2267071200 -18000 0 EST}
+    {2277961200 -14400 1 EDT}
+    {2298520800 -18000 0 EST}
+    {2309410800 -14400 1 EDT}
+    {2329970400 -18000 0 EST}
+    {2341465200 -14400 1 EDT}
+    {2362024800 -18000 0 EST}
+    {2372914800 -14400 1 EDT}
+    {2393474400 -18000 0 EST}
+    {2404364400 -14400 1 EDT}
+    {2424924000 -18000 0 EST}
+    {2435814000 -14400 1 EDT}
+    {2456373600 -18000 0 EST}
+    {2467263600 -14400 1 EDT}
+    {2487823200 -18000 0 EST}
+    {2499318000 -14400 1 EDT}
+    {2519877600 -18000 0 EST}
+    {2530767600 -14400 1 EDT}
+    {2551327200 -18000 0 EST}
+    {2562217200 -14400 1 EDT}
+    {2582776800 -18000 0 EST}
+    {2593666800 -14400 1 EDT}
+    {2614226400 -18000 0 EST}
+    {2625116400 -14400 1 EDT}
+    {2645676000 -18000 0 EST}
+    {2656566000 -14400 1 EDT}
+    {2677125600 -18000 0 EST}
+    {2688620400 -14400 1 EDT}
+    {2709180000 -18000 0 EST}
+    {2720070000 -14400 1 EDT}
+    {2740629600 -18000 0 EST}
+    {2751519600 -14400 1 EDT}
+    {2772079200 -18000 0 EST}
+    {2782969200 -14400 1 EDT}
+    {2803528800 -18000 0 EST}
+    {2814418800 -14400 1 EDT}
+    {2834978400 -18000 0 EST}
+    {2846473200 -14400 1 EDT}
+    {2867032800 -18000 0 EST}
+    {2877922800 -14400 1 EDT}
+    {2898482400 -18000 0 EST}
+    {2909372400 -14400 1 EDT}
+    {2929932000 -18000 0 EST}
+    {2940822000 -14400 1 EDT}
+    {2961381600 -18000 0 EST}
+    {2972271600 -14400 1 EDT}
+    {2992831200 -18000 0 EST}
+    {3003721200 -14400 1 EDT}
+    {3024280800 -18000 0 EST}
+    {3035775600 -14400 1 EDT}
+    {3056335200 -18000 0 EST}
+    {3067225200 -14400 1 EDT}
+    {3087784800 -18000 0 EST}
+    {3098674800 -14400 1 EDT}
+    {3119234400 -18000 0 EST}
+    {3130124400 -14400 1 EDT}
+    {3150684000 -18000 0 EST}
+    {3161574000 -14400 1 EDT}
+    {3182133600 -18000 0 EST}
+    {3193023600 -14400 1 EDT}
+    {3213583200 -18000 0 EST}
+    {3225078000 -14400 1 EDT}
+    {3245637600 -18000 0 EST}
+    {3256527600 -14400 1 EDT}
+    {3277087200 -18000 0 EST}
+    {3287977200 -14400 1 EDT}
+    {3308536800 -18000 0 EST}
+    {3319426800 -14400 1 EDT}
+    {3339986400 -18000 0 EST}
+    {3350876400 -14400 1 EDT}
+    {3371436000 -18000 0 EST}
+    {3382930800 -14400 1 EDT}
+    {3403490400 -18000 0 EST}
+    {3414380400 -14400 1 EDT}
+    {3434940000 -18000 0 EST}
+    {3445830000 -14400 1 EDT}
+    {3466389600 -18000 0 EST}
+    {3477279600 -14400 1 EDT}
+    {3497839200 -18000 0 EST}
+    {3508729200 -14400 1 EDT}
+    {3529288800 -18000 0 EST}
+    {3540178800 -14400 1 EDT}
+    {3560738400 -18000 0 EST}
+    {3572233200 -14400 1 EDT}
+    {3592792800 -18000 0 EST}
+    {3603682800 -14400 1 EDT}
+    {3624242400 -18000 0 EST}
+    {3635132400 -14400 1 EDT}
+    {3655692000 -18000 0 EST}
+    {3666582000 -14400 1 EDT}
+    {3687141600 -18000 0 EST}
+    {3698031600 -14400 1 EDT}
+    {3718591200 -18000 0 EST}
+    {3730086000 -14400 1 EDT}
+    {3750645600 -18000 0 EST}
+    {3761535600 -14400 1 EDT}
+    {3782095200 -18000 0 EST}
+    {3792985200 -14400 1 EDT}
+    {3813544800 -18000 0 EST}
+    {3824434800 -14400 1 EDT}
+    {3844994400 -18000 0 EST}
+    {3855884400 -14400 1 EDT}
+    {3876444000 -18000 0 EST}
+    {3887334000 -14400 1 EDT}
+    {3907893600 -18000 0 EST}
+    {3919388400 -14400 1 EDT}
+    {3939948000 -18000 0 EST}
+    {3950838000 -14400 1 EDT}
+    {3971397600 -18000 0 EST}
+    {3982287600 -14400 1 EDT}
+    {4002847200 -18000 0 EST}
+    {4013737200 -14400 1 EDT}
+    {4034296800 -18000 0 EST}
+    {4045186800 -14400 1 EDT}
+    {4065746400 -18000 0 EST}
+    {4076636400 -14400 1 EDT}
+    {4097196000 -18000 0 EST}
+}
diff --git a/library/tzdata/America/Tijuana b/library/tzdata/America/Tijuana
new file mode 100644
index 0000000..6118cde
--- /dev/null
+++ b/library/tzdata/America/Tijuana
@@ -0,0 +1,285 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Tijuana) {
+    {-9223372036854775808 -28084 0 LMT}
+    {-1514736000 -25200 0 MST}
+    {-1451667600 -28800 0 PST}
+    {-1343062800 -25200 0 MST}
+    {-1234803600 -28800 0 PST}
+    {-1222963200 -25200 1 PDT}
+    {-1207242000 -28800 0 PST}
+    {-873820800 -25200 1 PWT}
+    {-769395600 -25200 1 PPT}
+    {-761677200 -28800 0 PST}
+    {-686073600 -25200 1 PDT}
+    {-661539600 -28800 0 PST}
+    {-504892800 -28800 0 PST}
+    {-495036000 -25200 1 PDT}
+    {-481734000 -28800 0 PST}
+    {-463586400 -25200 1 PDT}
+    {-450284400 -28800 0 PST}
+    {-431532000 -25200 1 PDT}
+    {-418230000 -28800 0 PST}
+    {-400082400 -25200 1 PDT}
+    {-386780400 -28800 0 PST}
+    {-368632800 -25200 1 PDT}
+    {-355330800 -28800 0 PST}
+    {-337183200 -25200 1 PDT}
+    {-323881200 -28800 0 PST}
+    {-305733600 -25200 1 PDT}
+    {-292431600 -28800 0 PST}
+    {-283968000 -28800 0 PST}
+    {189331200 -28800 0 PST}
+    {199274400 -25200 1 PDT}
+    {215600400 -28800 0 PST}
+    {230724000 -25200 1 PDT}
+    {247050000 -28800 0 PST}
+    {262778400 -25200 1 PDT}
+    {278499600 -28800 0 PST}
+    {294228000 -25200 1 PDT}
+    {309949200 -28800 0 PST}
+    {325677600 -25200 1 PDT}
+    {341398800 -28800 0 PST}
+    {357127200 -25200 1 PDT}
+    {372848400 -28800 0 PST}
+    {388576800 -25200 1 PDT}
+    {404902800 -28800 0 PST}
+    {420026400 -25200 1 PDT}
+    {436352400 -28800 0 PST}
+    {452080800 -25200 1 PDT}
+    {467802000 -28800 0 PST}
+    {483530400 -25200 1 PDT}
+    {499251600 -28800 0 PST}
+    {514980000 -25200 1 PDT}
+    {530701200 -28800 0 PST}
+    {544615200 -25200 1 PDT}
+    {562150800 -28800 0 PST}
+    {576064800 -25200 1 PDT}
+    {594205200 -28800 0 PST}
+    {607514400 -25200 1 PDT}
+    {625654800 -28800 0 PST}
+    {638964000 -25200 1 PDT}
+    {657104400 -28800 0 PST}
+    {671018400 -25200 1 PDT}
+    {688554000 -28800 0 PST}
+    {702468000 -25200 1 PDT}
+    {720003600 -28800 0 PST}
+    {733917600 -25200 1 PDT}
+    {752058000 -28800 0 PST}
+    {765367200 -25200 1 PDT}
+    {783507600 -28800 0 PST}
+    {796816800 -25200 1 PDT}
+    {814957200 -28800 0 PST}
+    {820483200 -28800 0 PST}
+    {828871200 -25200 1 PDT}
+    {846406800 -28800 0 PST}
+    {860320800 -25200 1 PDT}
+    {877856400 -28800 0 PST}
+    {891770400 -25200 1 PDT}
+    {909306000 -28800 0 PST}
+    {923220000 -25200 1 PDT}
+    {941360400 -28800 0 PST}
+    {954669600 -25200 1 PDT}
+    {972810000 -28800 0 PST}
+    {978336000 -28800 0 PST}
+    {986119200 -25200 1 PDT}
+    {1004259600 -28800 0 PST}
+    {1014192000 -28800 0 PST}
+    {1018173600 -25200 1 PDT}
+    {1035709200 -28800 0 PST}
+    {1049623200 -25200 1 PDT}
+    {1067158800 -28800 0 PST}
+    {1081072800 -25200 1 PDT}
+    {1099213200 -28800 0 PST}
+    {1112522400 -25200 1 PDT}
+    {1130662800 -28800 0 PST}
+    {1143972000 -25200 1 PDT}
+    {1162112400 -28800 0 PST}
+    {1175421600 -25200 1 PDT}
+    {1193562000 -28800 0 PST}
+    {1207476000 -25200 1 PDT}
+    {1225011600 -28800 0 PST}
+    {1238925600 -25200 1 PDT}
+    {1256461200 -28800 0 PST}
+    {1262332800 -28800 0 PST}
+    {1268560800 -25200 1 PDT}
+    {1289120400 -28800 0 PST}
+    {1300010400 -25200 1 PDT}
+    {1320570000 -28800 0 PST}
+    {1331460000 -25200 1 PDT}
+    {1352019600 -28800 0 PST}
+    {1362909600 -25200 1 PDT}
+    {1383469200 -28800 0 PST}
+    {1394359200 -25200 1 PDT}
+    {1414918800 -28800 0 PST}
+    {1425808800 -25200 1 PDT}
+    {1446368400 -28800 0 PST}
+    {1457863200 -25200 1 PDT}
+    {1478422800 -28800 0 PST}
+    {1489312800 -25200 1 PDT}
+    {1509872400 -28800 0 PST}
+    {1520762400 -25200 1 PDT}
+    {1541322000 -28800 0 PST}
+    {1552212000 -25200 1 PDT}
+    {1572771600 -28800 0 PST}
+    {1583661600 -25200 1 PDT}
+    {1604221200 -28800 0 PST}
+    {1615716000 -25200 1 PDT}
+    {1636275600 -28800 0 PST}
+    {1647165600 -25200 1 PDT}
+    {1667725200 -28800 0 PST}
+    {1678615200 -25200 1 PDT}
+    {1699174800 -28800 0 PST}
+    {1710064800 -25200 1 PDT}
+    {1730624400 -28800 0 PST}
+    {1741514400 -25200 1 PDT}
+    {1762074000 -28800 0 PST}
+    {1772964000 -25200 1 PDT}
+    {1793523600 -28800 0 PST}
+    {1805018400 -25200 1 PDT}
+    {1825578000 -28800 0 PST}
+    {1836468000 -25200 1 PDT}
+    {1857027600 -28800 0 PST}
+    {1867917600 -25200 1 PDT}
+    {1888477200 -28800 0 PST}
+    {1899367200 -25200 1 PDT}
+    {1919926800 -28800 0 PST}
+    {1930816800 -25200 1 PDT}
+    {1951376400 -28800 0 PST}
+    {1962871200 -25200 1 PDT}
+    {1983430800 -28800 0 PST}
+    {1994320800 -25200 1 PDT}
+    {2014880400 -28800 0 PST}
+    {2025770400 -25200 1 PDT}
+    {2046330000 -28800 0 PST}
+    {2057220000 -25200 1 PDT}
+    {2077779600 -28800 0 PST}
+    {2088669600 -25200 1 PDT}
+    {2109229200 -28800 0 PST}
+    {2120119200 -25200 1 PDT}
+    {2140678800 -28800 0 PST}
+    {2152173600 -25200 1 PDT}
+    {2172733200 -28800 0 PST}
+    {2183623200 -25200 1 PDT}
+    {2204182800 -28800 0 PST}
+    {2215072800 -25200 1 PDT}
+    {2235632400 -28800 0 PST}
+    {2246522400 -25200 1 PDT}
+    {2267082000 -28800 0 PST}
+    {2277972000 -25200 1 PDT}
+    {2298531600 -28800 0 PST}
+    {2309421600 -25200 1 PDT}
+    {2329981200 -28800 0 PST}
+    {2341476000 -25200 1 PDT}
+    {2362035600 -28800 0 PST}
+    {2372925600 -25200 1 PDT}
+    {2393485200 -28800 0 PST}
+    {2404375200 -25200 1 PDT}
+    {2424934800 -28800 0 PST}
+    {2435824800 -25200 1 PDT}
+    {2456384400 -28800 0 PST}
+    {2467274400 -25200 1 PDT}
+    {2487834000 -28800 0 PST}
+    {2499328800 -25200 1 PDT}
+    {2519888400 -28800 0 PST}
+    {2530778400 -25200 1 PDT}
+    {2551338000 -28800 0 PST}
+    {2562228000 -25200 1 PDT}
+    {2582787600 -28800 0 PST}
+    {2593677600 -25200 1 PDT}
+    {2614237200 -28800 0 PST}
+    {2625127200 -25200 1 PDT}
+    {2645686800 -28800 0 PST}
+    {2656576800 -25200 1 PDT}
+    {2677136400 -28800 0 PST}
+    {2688631200 -25200 1 PDT}
+    {2709190800 -28800 0 PST}
+    {2720080800 -25200 1 PDT}
+    {2740640400 -28800 0 PST}
+    {2751530400 -25200 1 PDT}
+    {2772090000 -28800 0 PST}
+    {2782980000 -25200 1 PDT}
+    {2803539600 -28800 0 PST}
+    {2814429600 -25200 1 PDT}
+    {2834989200 -28800 0 PST}
+    {2846484000 -25200 1 PDT}
+    {2867043600 -28800 0 PST}
+    {2877933600 -25200 1 PDT}
+    {2898493200 -28800 0 PST}
+    {2909383200 -25200 1 PDT}
+    {2929942800 -28800 0 PST}
+    {2940832800 -25200 1 PDT}
+    {2961392400 -28800 0 PST}
+    {2972282400 -25200 1 PDT}
+    {2992842000 -28800 0 PST}
+    {3003732000 -25200 1 PDT}
+    {3024291600 -28800 0 PST}
+    {3035786400 -25200 1 PDT}
+    {3056346000 -28800 0 PST}
+    {3067236000 -25200 1 PDT}
+    {3087795600 -28800 0 PST}
+    {3098685600 -25200 1 PDT}
+    {3119245200 -28800 0 PST}
+    {3130135200 -25200 1 PDT}
+    {3150694800 -28800 0 PST}
+    {3161584800 -25200 1 PDT}
+    {3182144400 -28800 0 PST}
+    {3193034400 -25200 1 PDT}
+    {3213594000 -28800 0 PST}
+    {3225088800 -25200 1 PDT}
+    {3245648400 -28800 0 PST}
+    {3256538400 -25200 1 PDT}
+    {3277098000 -28800 0 PST}
+    {3287988000 -25200 1 PDT}
+    {3308547600 -28800 0 PST}
+    {3319437600 -25200 1 PDT}
+    {3339997200 -28800 0 PST}
+    {3350887200 -25200 1 PDT}
+    {3371446800 -28800 0 PST}
+    {3382941600 -25200 1 PDT}
+    {3403501200 -28800 0 PST}
+    {3414391200 -25200 1 PDT}
+    {3434950800 -28800 0 PST}
+    {3445840800 -25200 1 PDT}
+    {3466400400 -28800 0 PST}
+    {3477290400 -25200 1 PDT}
+    {3497850000 -28800 0 PST}
+    {3508740000 -25200 1 PDT}
+    {3529299600 -28800 0 PST}
+    {3540189600 -25200 1 PDT}
+    {3560749200 -28800 0 PST}
+    {3572244000 -25200 1 PDT}
+    {3592803600 -28800 0 PST}
+    {3603693600 -25200 1 PDT}
+    {3624253200 -28800 0 PST}
+    {3635143200 -25200 1 PDT}
+    {3655702800 -28800 0 PST}
+    {3666592800 -25200 1 PDT}
+    {3687152400 -28800 0 PST}
+    {3698042400 -25200 1 PDT}
+    {3718602000 -28800 0 PST}
+    {3730096800 -25200 1 PDT}
+    {3750656400 -28800 0 PST}
+    {3761546400 -25200 1 PDT}
+    {3782106000 -28800 0 PST}
+    {3792996000 -25200 1 PDT}
+    {3813555600 -28800 0 PST}
+    {3824445600 -25200 1 PDT}
+    {3845005200 -28800 0 PST}
+    {3855895200 -25200 1 PDT}
+    {3876454800 -28800 0 PST}
+    {3887344800 -25200 1 PDT}
+    {3907904400 -28800 0 PST}
+    {3919399200 -25200 1 PDT}
+    {3939958800 -28800 0 PST}
+    {3950848800 -25200 1 PDT}
+    {3971408400 -28800 0 PST}
+    {3982298400 -25200 1 PDT}
+    {4002858000 -28800 0 PST}
+    {4013748000 -25200 1 PDT}
+    {4034307600 -28800 0 PST}
+    {4045197600 -25200 1 PDT}
+    {4065757200 -28800 0 PST}
+    {4076647200 -25200 1 PDT}
+    {4097206800 -28800 0 PST}
+}
diff --git a/library/tzdata/America/Toronto b/library/tzdata/America/Toronto
new file mode 100644
index 0000000..09bf786
--- /dev/null
+++ b/library/tzdata/America/Toronto
@@ -0,0 +1,365 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Toronto) {
+    {-9223372036854775808 -19052 0 LMT}
+    {-2366736148 -18000 0 EST}
+    {-1632070800 -14400 1 EDT}
+    {-1615140000 -18000 0 EST}
+    {-1609441200 -18000 0 EST}
+    {-1601753400 -14400 1 EDT}
+    {-1583697600 -18000 0 EST}
+    {-1567357200 -14400 1 EDT}
+    {-1554667200 -18000 0 EST}
+    {-1534698000 -14400 1 EDT}
+    {-1524074400 -18000 0 EST}
+    {-1503248400 -14400 1 EDT}
+    {-1492365600 -18000 0 EST}
+    {-1471798800 -14400 1 EDT}
+    {-1460916000 -18000 0 EST}
+    {-1440954000 -14400 1 EDT}
+    {-1428861600 -18000 0 EST}
+    {-1409504400 -14400 1 EDT}
+    {-1397412000 -18000 0 EST}
+    {-1378054800 -14400 1 EDT}
+    {-1365962400 -18000 0 EST}
+    {-1346605200 -14400 1 EDT}
+    {-1333908000 -18000 0 EST}
+    {-1315155600 -14400 1 EDT}
+    {-1301853600 -18000 0 EST}
+    {-1283706000 -14400 1 EDT}
+    {-1270404000 -18000 0 EST}
+    {-1252256400 -14400 1 EDT}
+    {-1238954400 -18000 0 EST}
+    {-1220806800 -14400 1 EDT}
+    {-1207504800 -18000 0 EST}
+    {-1188752400 -14400 1 EDT}
+    {-1176055200 -18000 0 EST}
+    {-1157302800 -14400 1 EDT}
+    {-1144000800 -18000 0 EST}
+    {-1125853200 -14400 1 EDT}
+    {-1112551200 -18000 0 EST}
+    {-1094403600 -14400 1 EDT}
+    {-1081101600 -18000 0 EST}
+    {-1062954000 -14400 1 EDT}
+    {-1049652000 -18000 0 EST}
+    {-1031504400 -14400 1 EDT}
+    {-1018202400 -18000 0 EST}
+    {-1000054800 -14400 1 EDT}
+    {-986752800 -18000 0 EST}
+    {-968000400 -14400 1 EDT}
+    {-955303200 -18000 0 EST}
+    {-936550800 -14400 1 EDT}
+    {-880218000 -14400 0 EWT}
+    {-769395600 -14400 1 EPT}
+    {-765396000 -18000 0 EST}
+    {-757364400 -18000 0 EST}
+    {-747248400 -14400 1 EDT}
+    {-733946400 -18000 0 EST}
+    {-715806000 -14400 1 EDT}
+    {-702504000 -18000 0 EST}
+    {-684356400 -14400 1 EDT}
+    {-671054400 -18000 0 EST}
+    {-652906800 -14400 1 EDT}
+    {-634161600 -18000 0 EST}
+    {-620845200 -14400 1 EDT}
+    {-602704800 -18000 0 EST}
+    {-589395600 -14400 1 EDT}
+    {-576093600 -18000 0 EST}
+    {-557946000 -14400 1 EDT}
+    {-544644000 -18000 0 EST}
+    {-526496400 -14400 1 EDT}
+    {-513194400 -18000 0 EST}
+    {-495046800 -14400 1 EDT}
+    {-481744800 -18000 0 EST}
+    {-463597200 -14400 1 EDT}
+    {-450295200 -18000 0 EST}
+    {-431542800 -14400 1 EDT}
+    {-418240800 -18000 0 EST}
+    {-400093200 -14400 1 EDT}
+    {-384372000 -18000 0 EST}
+    {-368643600 -14400 1 EDT}
+    {-352922400 -18000 0 EST}
+    {-337194000 -14400 1 EDT}
+    {-321472800 -18000 0 EST}
+    {-305744400 -14400 1 EDT}
+    {-289418400 -18000 0 EST}
+    {-273690000 -14400 1 EDT}
+    {-257968800 -18000 0 EST}
+    {-242240400 -14400 1 EDT}
+    {-226519200 -18000 0 EST}
+    {-210790800 -14400 1 EDT}
+    {-195069600 -18000 0 EST}
+    {-179341200 -14400 1 EDT}
+    {-163620000 -18000 0 EST}
+    {-147891600 -14400 1 EDT}
+    {-131565600 -18000 0 EST}
+    {-116442000 -14400 1 EDT}
+    {-100116000 -18000 0 EST}
+    {-84387600 -14400 1 EDT}
+    {-68666400 -18000 0 EST}
+    {-52938000 -14400 1 EDT}
+    {-37216800 -18000 0 EST}
+    {-21488400 -14400 1 EDT}
+    {-5767200 -18000 0 EST}
+    {9961200 -14400 1 EDT}
+    {25682400 -18000 0 EST}
+    {41410800 -14400 1 EDT}
+    {57736800 -18000 0 EST}
+    {73465200 -14400 1 EDT}
+    {89186400 -18000 0 EST}
+    {104914800 -14400 1 EDT}
+    {120636000 -18000 0 EST}
+    {126248400 -18000 0 EST}
+    {136364400 -14400 1 EDT}
+    {152085600 -18000 0 EST}
+    {167814000 -14400 1 EDT}
+    {183535200 -18000 0 EST}
+    {199263600 -14400 1 EDT}
+    {215589600 -18000 0 EST}
+    {230713200 -14400 1 EDT}
+    {247039200 -18000 0 EST}
+    {262767600 -14400 1 EDT}
+    {278488800 -18000 0 EST}
+    {294217200 -14400 1 EDT}
+    {309938400 -18000 0 EST}
+    {325666800 -14400 1 EDT}
+    {341388000 -18000 0 EST}
+    {357116400 -14400 1 EDT}
+    {372837600 -18000 0 EST}
+    {388566000 -14400 1 EDT}
+    {404892000 -18000 0 EST}
+    {420015600 -14400 1 EDT}
+    {436341600 -18000 0 EST}
+    {452070000 -14400 1 EDT}
+    {467791200 -18000 0 EST}
+    {483519600 -14400 1 EDT}
+    {499240800 -18000 0 EST}
+    {514969200 -14400 1 EDT}
+    {530690400 -18000 0 EST}
+    {544604400 -14400 1 EDT}
+    {562140000 -18000 0 EST}
+    {576054000 -14400 1 EDT}
+    {594194400 -18000 0 EST}
+    {607503600 -14400 1 EDT}
+    {625644000 -18000 0 EST}
+    {638953200 -14400 1 EDT}
+    {657093600 -18000 0 EST}
+    {671007600 -14400 1 EDT}
+    {688543200 -18000 0 EST}
+    {702457200 -14400 1 EDT}
+    {719992800 -18000 0 EST}
+    {733906800 -14400 1 EDT}
+    {752047200 -18000 0 EST}
+    {765356400 -14400 1 EDT}
+    {783496800 -18000 0 EST}
+    {796806000 -14400 1 EDT}
+    {814946400 -18000 0 EST}
+    {828860400 -14400 1 EDT}
+    {846396000 -18000 0 EST}
+    {860310000 -14400 1 EDT}
+    {877845600 -18000 0 EST}
+    {891759600 -14400 1 EDT}
+    {909295200 -18000 0 EST}
+    {923209200 -14400 1 EDT}
+    {941349600 -18000 0 EST}
+    {954658800 -14400 1 EDT}
+    {972799200 -18000 0 EST}
+    {986108400 -14400 1 EDT}
+    {1004248800 -18000 0 EST}
+    {1018162800 -14400 1 EDT}
+    {1035698400 -18000 0 EST}
+    {1049612400 -14400 1 EDT}
+    {1067148000 -18000 0 EST}
+    {1081062000 -14400 1 EDT}
+    {1099202400 -18000 0 EST}
+    {1112511600 -14400 1 EDT}
+    {1130652000 -18000 0 EST}
+    {1143961200 -14400 1 EDT}
+    {1162101600 -18000 0 EST}
+    {1173596400 -14400 1 EDT}
+    {1194156000 -18000 0 EST}
+    {1205046000 -14400 1 EDT}
+    {1225605600 -18000 0 EST}
+    {1236495600 -14400 1 EDT}
+    {1257055200 -18000 0 EST}
+    {1268550000 -14400 1 EDT}
+    {1289109600 -18000 0 EST}
+    {1299999600 -14400 1 EDT}
+    {1320559200 -18000 0 EST}
+    {1331449200 -14400 1 EDT}
+    {1352008800 -18000 0 EST}
+    {1362898800 -14400 1 EDT}
+    {1383458400 -18000 0 EST}
+    {1394348400 -14400 1 EDT}
+    {1414908000 -18000 0 EST}
+    {1425798000 -14400 1 EDT}
+    {1446357600 -18000 0 EST}
+    {1457852400 -14400 1 EDT}
+    {1478412000 -18000 0 EST}
+    {1489302000 -14400 1 EDT}
+    {1509861600 -18000 0 EST}
+    {1520751600 -14400 1 EDT}
+    {1541311200 -18000 0 EST}
+    {1552201200 -14400 1 EDT}
+    {1572760800 -18000 0 EST}
+    {1583650800 -14400 1 EDT}
+    {1604210400 -18000 0 EST}
+    {1615705200 -14400 1 EDT}
+    {1636264800 -18000 0 EST}
+    {1647154800 -14400 1 EDT}
+    {1667714400 -18000 0 EST}
+    {1678604400 -14400 1 EDT}
+    {1699164000 -18000 0 EST}
+    {1710054000 -14400 1 EDT}
+    {1730613600 -18000 0 EST}
+    {1741503600 -14400 1 EDT}
+    {1762063200 -18000 0 EST}
+    {1772953200 -14400 1 EDT}
+    {1793512800 -18000 0 EST}
+    {1805007600 -14400 1 EDT}
+    {1825567200 -18000 0 EST}
+    {1836457200 -14400 1 EDT}
+    {1857016800 -18000 0 EST}
+    {1867906800 -14400 1 EDT}
+    {1888466400 -18000 0 EST}
+    {1899356400 -14400 1 EDT}
+    {1919916000 -18000 0 EST}
+    {1930806000 -14400 1 EDT}
+    {1951365600 -18000 0 EST}
+    {1962860400 -14400 1 EDT}
+    {1983420000 -18000 0 EST}
+    {1994310000 -14400 1 EDT}
+    {2014869600 -18000 0 EST}
+    {2025759600 -14400 1 EDT}
+    {2046319200 -18000 0 EST}
+    {2057209200 -14400 1 EDT}
+    {2077768800 -18000 0 EST}
+    {2088658800 -14400 1 EDT}
+    {2109218400 -18000 0 EST}
+    {2120108400 -14400 1 EDT}
+    {2140668000 -18000 0 EST}
+    {2152162800 -14400 1 EDT}
+    {2172722400 -18000 0 EST}
+    {2183612400 -14400 1 EDT}
+    {2204172000 -18000 0 EST}
+    {2215062000 -14400 1 EDT}
+    {2235621600 -18000 0 EST}
+    {2246511600 -14400 1 EDT}
+    {2267071200 -18000 0 EST}
+    {2277961200 -14400 1 EDT}
+    {2298520800 -18000 0 EST}
+    {2309410800 -14400 1 EDT}
+    {2329970400 -18000 0 EST}
+    {2341465200 -14400 1 EDT}
+    {2362024800 -18000 0 EST}
+    {2372914800 -14400 1 EDT}
+    {2393474400 -18000 0 EST}
+    {2404364400 -14400 1 EDT}
+    {2424924000 -18000 0 EST}
+    {2435814000 -14400 1 EDT}
+    {2456373600 -18000 0 EST}
+    {2467263600 -14400 1 EDT}
+    {2487823200 -18000 0 EST}
+    {2499318000 -14400 1 EDT}
+    {2519877600 -18000 0 EST}
+    {2530767600 -14400 1 EDT}
+    {2551327200 -18000 0 EST}
+    {2562217200 -14400 1 EDT}
+    {2582776800 -18000 0 EST}
+    {2593666800 -14400 1 EDT}
+    {2614226400 -18000 0 EST}
+    {2625116400 -14400 1 EDT}
+    {2645676000 -18000 0 EST}
+    {2656566000 -14400 1 EDT}
+    {2677125600 -18000 0 EST}
+    {2688620400 -14400 1 EDT}
+    {2709180000 -18000 0 EST}
+    {2720070000 -14400 1 EDT}
+    {2740629600 -18000 0 EST}
+    {2751519600 -14400 1 EDT}
+    {2772079200 -18000 0 EST}
+    {2782969200 -14400 1 EDT}
+    {2803528800 -18000 0 EST}
+    {2814418800 -14400 1 EDT}
+    {2834978400 -18000 0 EST}
+    {2846473200 -14400 1 EDT}
+    {2867032800 -18000 0 EST}
+    {2877922800 -14400 1 EDT}
+    {2898482400 -18000 0 EST}
+    {2909372400 -14400 1 EDT}
+    {2929932000 -18000 0 EST}
+    {2940822000 -14400 1 EDT}
+    {2961381600 -18000 0 EST}
+    {2972271600 -14400 1 EDT}
+    {2992831200 -18000 0 EST}
+    {3003721200 -14400 1 EDT}
+    {3024280800 -18000 0 EST}
+    {3035775600 -14400 1 EDT}
+    {3056335200 -18000 0 EST}
+    {3067225200 -14400 1 EDT}
+    {3087784800 -18000 0 EST}
+    {3098674800 -14400 1 EDT}
+    {3119234400 -18000 0 EST}
+    {3130124400 -14400 1 EDT}
+    {3150684000 -18000 0 EST}
+    {3161574000 -14400 1 EDT}
+    {3182133600 -18000 0 EST}
+    {3193023600 -14400 1 EDT}
+    {3213583200 -18000 0 EST}
+    {3225078000 -14400 1 EDT}
+    {3245637600 -18000 0 EST}
+    {3256527600 -14400 1 EDT}
+    {3277087200 -18000 0 EST}
+    {3287977200 -14400 1 EDT}
+    {3308536800 -18000 0 EST}
+    {3319426800 -14400 1 EDT}
+    {3339986400 -18000 0 EST}
+    {3350876400 -14400 1 EDT}
+    {3371436000 -18000 0 EST}
+    {3382930800 -14400 1 EDT}
+    {3403490400 -18000 0 EST}
+    {3414380400 -14400 1 EDT}
+    {3434940000 -18000 0 EST}
+    {3445830000 -14400 1 EDT}
+    {3466389600 -18000 0 EST}
+    {3477279600 -14400 1 EDT}
+    {3497839200 -18000 0 EST}
+    {3508729200 -14400 1 EDT}
+    {3529288800 -18000 0 EST}
+    {3540178800 -14400 1 EDT}
+    {3560738400 -18000 0 EST}
+    {3572233200 -14400 1 EDT}
+    {3592792800 -18000 0 EST}
+    {3603682800 -14400 1 EDT}
+    {3624242400 -18000 0 EST}
+    {3635132400 -14400 1 EDT}
+    {3655692000 -18000 0 EST}
+    {3666582000 -14400 1 EDT}
+    {3687141600 -18000 0 EST}
+    {3698031600 -14400 1 EDT}
+    {3718591200 -18000 0 EST}
+    {3730086000 -14400 1 EDT}
+    {3750645600 -18000 0 EST}
+    {3761535600 -14400 1 EDT}
+    {3782095200 -18000 0 EST}
+    {3792985200 -14400 1 EDT}
+    {3813544800 -18000 0 EST}
+    {3824434800 -14400 1 EDT}
+    {3844994400 -18000 0 EST}
+    {3855884400 -14400 1 EDT}
+    {3876444000 -18000 0 EST}
+    {3887334000 -14400 1 EDT}
+    {3907893600 -18000 0 EST}
+    {3919388400 -14400 1 EDT}
+    {3939948000 -18000 0 EST}
+    {3950838000 -14400 1 EDT}
+    {3971397600 -18000 0 EST}
+    {3982287600 -14400 1 EDT}
+    {4002847200 -18000 0 EST}
+    {4013737200 -14400 1 EDT}
+    {4034296800 -18000 0 EST}
+    {4045186800 -14400 1 EDT}
+    {4065746400 -18000 0 EST}
+    {4076636400 -14400 1 EDT}
+    {4097196000 -18000 0 EST}
+}
diff --git a/library/tzdata/America/Tortola b/library/tzdata/America/Tortola
new file mode 100644
index 0000000..aa6f655
--- /dev/null
+++ b/library/tzdata/America/Tortola
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(America/Port_of_Spain)]} {
+    LoadTimeZoneFile America/Port_of_Spain
+}
+set TZData(:America/Tortola) $TZData(:America/Port_of_Spain)
diff --git a/library/tzdata/America/Vancouver b/library/tzdata/America/Vancouver
new file mode 100644
index 0000000..aef639a
--- /dev/null
+++ b/library/tzdata/America/Vancouver
@@ -0,0 +1,320 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Vancouver) {
+    {-9223372036854775808 -29548 0 LMT}
+    {-2713880852 -28800 0 PST}
+    {-1632060000 -25200 1 PDT}
+    {-1615129200 -28800 0 PST}
+    {-880207200 -25200 1 PWT}
+    {-769395600 -25200 1 PPT}
+    {-765385200 -28800 0 PST}
+    {-747237600 -25200 1 PDT}
+    {-732726000 -28800 0 PST}
+    {-715788000 -25200 1 PDT}
+    {-702486000 -28800 0 PST}
+    {-684338400 -25200 1 PDT}
+    {-671036400 -28800 0 PST}
+    {-652888800 -25200 1 PDT}
+    {-639586800 -28800 0 PST}
+    {-620834400 -25200 1 PDT}
+    {-608137200 -28800 0 PST}
+    {-589384800 -25200 1 PDT}
+    {-576082800 -28800 0 PST}
+    {-557935200 -25200 1 PDT}
+    {-544633200 -28800 0 PST}
+    {-526485600 -25200 1 PDT}
+    {-513183600 -28800 0 PST}
+    {-495036000 -25200 1 PDT}
+    {-481734000 -28800 0 PST}
+    {-463586400 -25200 1 PDT}
+    {-450284400 -28800 0 PST}
+    {-431532000 -25200 1 PDT}
+    {-418230000 -28800 0 PST}
+    {-400082400 -25200 1 PDT}
+    {-386780400 -28800 0 PST}
+    {-368632800 -25200 1 PDT}
+    {-355330800 -28800 0 PST}
+    {-337183200 -25200 1 PDT}
+    {-323881200 -28800 0 PST}
+    {-305733600 -25200 1 PDT}
+    {-292431600 -28800 0 PST}
+    {-273679200 -25200 1 PDT}
+    {-260982000 -28800 0 PST}
+    {-242229600 -25200 1 PDT}
+    {-226508400 -28800 0 PST}
+    {-210780000 -25200 1 PDT}
+    {-195058800 -28800 0 PST}
+    {-179330400 -25200 1 PDT}
+    {-163609200 -28800 0 PST}
+    {-147880800 -25200 1 PDT}
+    {-131554800 -28800 0 PST}
+    {-116431200 -25200 1 PDT}
+    {-100105200 -28800 0 PST}
+    {-84376800 -25200 1 PDT}
+    {-68655600 -28800 0 PST}
+    {-52927200 -25200 1 PDT}
+    {-37206000 -28800 0 PST}
+    {-21477600 -25200 1 PDT}
+    {-5756400 -28800 0 PST}
+    {9972000 -25200 1 PDT}
+    {25693200 -28800 0 PST}
+    {41421600 -25200 1 PDT}
+    {57747600 -28800 0 PST}
+    {73476000 -25200 1 PDT}
+    {89197200 -28800 0 PST}
+    {104925600 -25200 1 PDT}
+    {120646800 -28800 0 PST}
+    {136375200 -25200 1 PDT}
+    {152096400 -28800 0 PST}
+    {167824800 -25200 1 PDT}
+    {183546000 -28800 0 PST}
+    {199274400 -25200 1 PDT}
+    {215600400 -28800 0 PST}
+    {230724000 -25200 1 PDT}
+    {247050000 -28800 0 PST}
+    {262778400 -25200 1 PDT}
+    {278499600 -28800 0 PST}
+    {294228000 -25200 1 PDT}
+    {309949200 -28800 0 PST}
+    {325677600 -25200 1 PDT}
+    {341398800 -28800 0 PST}
+    {357127200 -25200 1 PDT}
+    {372848400 -28800 0 PST}
+    {388576800 -25200 1 PDT}
+    {404902800 -28800 0 PST}
+    {420026400 -25200 1 PDT}
+    {436352400 -28800 0 PST}
+    {452080800 -25200 1 PDT}
+    {467802000 -28800 0 PST}
+    {483530400 -25200 1 PDT}
+    {499251600 -28800 0 PST}
+    {514980000 -25200 1 PDT}
+    {530701200 -28800 0 PST}
+    {536486400 -28800 0 PST}
+    {544615200 -25200 1 PDT}
+    {562150800 -28800 0 PST}
+    {576064800 -25200 1 PDT}
+    {594205200 -28800 0 PST}
+    {607514400 -25200 1 PDT}
+    {625654800 -28800 0 PST}
+    {638964000 -25200 1 PDT}
+    {657104400 -28800 0 PST}
+    {671018400 -25200 1 PDT}
+    {688554000 -28800 0 PST}
+    {702468000 -25200 1 PDT}
+    {720003600 -28800 0 PST}
+    {733917600 -25200 1 PDT}
+    {752058000 -28800 0 PST}
+    {765367200 -25200 1 PDT}
+    {783507600 -28800 0 PST}
+    {796816800 -25200 1 PDT}
+    {814957200 -28800 0 PST}
+    {828871200 -25200 1 PDT}
+    {846406800 -28800 0 PST}
+    {860320800 -25200 1 PDT}
+    {877856400 -28800 0 PST}
+    {891770400 -25200 1 PDT}
+    {909306000 -28800 0 PST}
+    {923220000 -25200 1 PDT}
+    {941360400 -28800 0 PST}
+    {954669600 -25200 1 PDT}
+    {972810000 -28800 0 PST}
+    {986119200 -25200 1 PDT}
+    {1004259600 -28800 0 PST}
+    {1018173600 -25200 1 PDT}
+    {1035709200 -28800 0 PST}
+    {1049623200 -25200 1 PDT}
+    {1067158800 -28800 0 PST}
+    {1081072800 -25200 1 PDT}
+    {1099213200 -28800 0 PST}
+    {1112522400 -25200 1 PDT}
+    {1130662800 -28800 0 PST}
+    {1143972000 -25200 1 PDT}
+    {1162112400 -28800 0 PST}
+    {1173607200 -25200 1 PDT}
+    {1194166800 -28800 0 PST}
+    {1205056800 -25200 1 PDT}
+    {1225616400 -28800 0 PST}
+    {1236506400 -25200 1 PDT}
+    {1257066000 -28800 0 PST}
+    {1268560800 -25200 1 PDT}
+    {1289120400 -28800 0 PST}
+    {1300010400 -25200 1 PDT}
+    {1320570000 -28800 0 PST}
+    {1331460000 -25200 1 PDT}
+    {1352019600 -28800 0 PST}
+    {1362909600 -25200 1 PDT}
+    {1383469200 -28800 0 PST}
+    {1394359200 -25200 1 PDT}
+    {1414918800 -28800 0 PST}
+    {1425808800 -25200 1 PDT}
+    {1446368400 -28800 0 PST}
+    {1457863200 -25200 1 PDT}
+    {1478422800 -28800 0 PST}
+    {1489312800 -25200 1 PDT}
+    {1509872400 -28800 0 PST}
+    {1520762400 -25200 1 PDT}
+    {1541322000 -28800 0 PST}
+    {1552212000 -25200 1 PDT}
+    {1572771600 -28800 0 PST}
+    {1583661600 -25200 1 PDT}
+    {1604221200 -28800 0 PST}
+    {1615716000 -25200 1 PDT}
+    {1636275600 -28800 0 PST}
+    {1647165600 -25200 1 PDT}
+    {1667725200 -28800 0 PST}
+    {1678615200 -25200 1 PDT}
+    {1699174800 -28800 0 PST}
+    {1710064800 -25200 1 PDT}
+    {1730624400 -28800 0 PST}
+    {1741514400 -25200 1 PDT}
+    {1762074000 -28800 0 PST}
+    {1772964000 -25200 1 PDT}
+    {1793523600 -28800 0 PST}
+    {1805018400 -25200 1 PDT}
+    {1825578000 -28800 0 PST}
+    {1836468000 -25200 1 PDT}
+    {1857027600 -28800 0 PST}
+    {1867917600 -25200 1 PDT}
+    {1888477200 -28800 0 PST}
+    {1899367200 -25200 1 PDT}
+    {1919926800 -28800 0 PST}
+    {1930816800 -25200 1 PDT}
+    {1951376400 -28800 0 PST}
+    {1962871200 -25200 1 PDT}
+    {1983430800 -28800 0 PST}
+    {1994320800 -25200 1 PDT}
+    {2014880400 -28800 0 PST}
+    {2025770400 -25200 1 PDT}
+    {2046330000 -28800 0 PST}
+    {2057220000 -25200 1 PDT}
+    {2077779600 -28800 0 PST}
+    {2088669600 -25200 1 PDT}
+    {2109229200 -28800 0 PST}
+    {2120119200 -25200 1 PDT}
+    {2140678800 -28800 0 PST}
+    {2152173600 -25200 1 PDT}
+    {2172733200 -28800 0 PST}
+    {2183623200 -25200 1 PDT}
+    {2204182800 -28800 0 PST}
+    {2215072800 -25200 1 PDT}
+    {2235632400 -28800 0 PST}
+    {2246522400 -25200 1 PDT}
+    {2267082000 -28800 0 PST}
+    {2277972000 -25200 1 PDT}
+    {2298531600 -28800 0 PST}
+    {2309421600 -25200 1 PDT}
+    {2329981200 -28800 0 PST}
+    {2341476000 -25200 1 PDT}
+    {2362035600 -28800 0 PST}
+    {2372925600 -25200 1 PDT}
+    {2393485200 -28800 0 PST}
+    {2404375200 -25200 1 PDT}
+    {2424934800 -28800 0 PST}
+    {2435824800 -25200 1 PDT}
+    {2456384400 -28800 0 PST}
+    {2467274400 -25200 1 PDT}
+    {2487834000 -28800 0 PST}
+    {2499328800 -25200 1 PDT}
+    {2519888400 -28800 0 PST}
+    {2530778400 -25200 1 PDT}
+    {2551338000 -28800 0 PST}
+    {2562228000 -25200 1 PDT}
+    {2582787600 -28800 0 PST}
+    {2593677600 -25200 1 PDT}
+    {2614237200 -28800 0 PST}
+    {2625127200 -25200 1 PDT}
+    {2645686800 -28800 0 PST}
+    {2656576800 -25200 1 PDT}
+    {2677136400 -28800 0 PST}
+    {2688631200 -25200 1 PDT}
+    {2709190800 -28800 0 PST}
+    {2720080800 -25200 1 PDT}
+    {2740640400 -28800 0 PST}
+    {2751530400 -25200 1 PDT}
+    {2772090000 -28800 0 PST}
+    {2782980000 -25200 1 PDT}
+    {2803539600 -28800 0 PST}
+    {2814429600 -25200 1 PDT}
+    {2834989200 -28800 0 PST}
+    {2846484000 -25200 1 PDT}
+    {2867043600 -28800 0 PST}
+    {2877933600 -25200 1 PDT}
+    {2898493200 -28800 0 PST}
+    {2909383200 -25200 1 PDT}
+    {2929942800 -28800 0 PST}
+    {2940832800 -25200 1 PDT}
+    {2961392400 -28800 0 PST}
+    {2972282400 -25200 1 PDT}
+    {2992842000 -28800 0 PST}
+    {3003732000 -25200 1 PDT}
+    {3024291600 -28800 0 PST}
+    {3035786400 -25200 1 PDT}
+    {3056346000 -28800 0 PST}
+    {3067236000 -25200 1 PDT}
+    {3087795600 -28800 0 PST}
+    {3098685600 -25200 1 PDT}
+    {3119245200 -28800 0 PST}
+    {3130135200 -25200 1 PDT}
+    {3150694800 -28800 0 PST}
+    {3161584800 -25200 1 PDT}
+    {3182144400 -28800 0 PST}
+    {3193034400 -25200 1 PDT}
+    {3213594000 -28800 0 PST}
+    {3225088800 -25200 1 PDT}
+    {3245648400 -28800 0 PST}
+    {3256538400 -25200 1 PDT}
+    {3277098000 -28800 0 PST}
+    {3287988000 -25200 1 PDT}
+    {3308547600 -28800 0 PST}
+    {3319437600 -25200 1 PDT}
+    {3339997200 -28800 0 PST}
+    {3350887200 -25200 1 PDT}
+    {3371446800 -28800 0 PST}
+    {3382941600 -25200 1 PDT}
+    {3403501200 -28800 0 PST}
+    {3414391200 -25200 1 PDT}
+    {3434950800 -28800 0 PST}
+    {3445840800 -25200 1 PDT}
+    {3466400400 -28800 0 PST}
+    {3477290400 -25200 1 PDT}
+    {3497850000 -28800 0 PST}
+    {3508740000 -25200 1 PDT}
+    {3529299600 -28800 0 PST}
+    {3540189600 -25200 1 PDT}
+    {3560749200 -28800 0 PST}
+    {3572244000 -25200 1 PDT}
+    {3592803600 -28800 0 PST}
+    {3603693600 -25200 1 PDT}
+    {3624253200 -28800 0 PST}
+    {3635143200 -25200 1 PDT}
+    {3655702800 -28800 0 PST}
+    {3666592800 -25200 1 PDT}
+    {3687152400 -28800 0 PST}
+    {3698042400 -25200 1 PDT}
+    {3718602000 -28800 0 PST}
+    {3730096800 -25200 1 PDT}
+    {3750656400 -28800 0 PST}
+    {3761546400 -25200 1 PDT}
+    {3782106000 -28800 0 PST}
+    {3792996000 -25200 1 PDT}
+    {3813555600 -28800 0 PST}
+    {3824445600 -25200 1 PDT}
+    {3845005200 -28800 0 PST}
+    {3855895200 -25200 1 PDT}
+    {3876454800 -28800 0 PST}
+    {3887344800 -25200 1 PDT}
+    {3907904400 -28800 0 PST}
+    {3919399200 -25200 1 PDT}
+    {3939958800 -28800 0 PST}
+    {3950848800 -25200 1 PDT}
+    {3971408400 -28800 0 PST}
+    {3982298400 -25200 1 PDT}
+    {4002858000 -28800 0 PST}
+    {4013748000 -25200 1 PDT}
+    {4034307600 -28800 0 PST}
+    {4045197600 -25200 1 PDT}
+    {4065757200 -28800 0 PST}
+    {4076647200 -25200 1 PDT}
+    {4097206800 -28800 0 PST}
+}
diff --git a/library/tzdata/America/Virgin b/library/tzdata/America/Virgin
new file mode 100644
index 0000000..c267e5b
--- /dev/null
+++ b/library/tzdata/America/Virgin
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(America/Port_of_Spain)]} {
+    LoadTimeZoneFile America/Port_of_Spain
+}
+set TZData(:America/Virgin) $TZData(:America/Port_of_Spain)
diff --git a/library/tzdata/America/Whitehorse b/library/tzdata/America/Whitehorse
new file mode 100644
index 0000000..1d61093
--- /dev/null
+++ b/library/tzdata/America/Whitehorse
@@ -0,0 +1,256 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Whitehorse) {
+    {-9223372036854775808 -32412 0 LMT}
+    {-2188997988 -32400 0 YST}
+    {-1632056400 -28800 1 YDT}
+    {-1615125600 -32400 0 YST}
+    {-1596978000 -28800 1 YDT}
+    {-1583164800 -32400 0 YST}
+    {-880203600 -28800 1 YWT}
+    {-769395600 -28800 1 YPT}
+    {-765381600 -32400 0 YST}
+    {-147884400 -25200 1 YDDT}
+    {-131554800 -32400 0 YST}
+    {315561600 -28800 0 PST}
+    {325677600 -25200 1 PDT}
+    {341398800 -28800 0 PST}
+    {357127200 -25200 1 PDT}
+    {372848400 -28800 0 PST}
+    {388576800 -25200 1 PDT}
+    {404902800 -28800 0 PST}
+    {420026400 -25200 1 PDT}
+    {436352400 -28800 0 PST}
+    {452080800 -25200 1 PDT}
+    {467802000 -28800 0 PST}
+    {483530400 -25200 1 PDT}
+    {499251600 -28800 0 PST}
+    {514980000 -25200 1 PDT}
+    {530701200 -28800 0 PST}
+    {544615200 -25200 1 PDT}
+    {562150800 -28800 0 PST}
+    {576064800 -25200 1 PDT}
+    {594205200 -28800 0 PST}
+    {607514400 -25200 1 PDT}
+    {625654800 -28800 0 PST}
+    {638964000 -25200 1 PDT}
+    {657104400 -28800 0 PST}
+    {671018400 -25200 1 PDT}
+    {688554000 -28800 0 PST}
+    {702468000 -25200 1 PDT}
+    {720003600 -28800 0 PST}
+    {733917600 -25200 1 PDT}
+    {752058000 -28800 0 PST}
+    {765367200 -25200 1 PDT}
+    {783507600 -28800 0 PST}
+    {796816800 -25200 1 PDT}
+    {814957200 -28800 0 PST}
+    {828871200 -25200 1 PDT}
+    {846406800 -28800 0 PST}
+    {860320800 -25200 1 PDT}
+    {877856400 -28800 0 PST}
+    {891770400 -25200 1 PDT}
+    {909306000 -28800 0 PST}
+    {923220000 -25200 1 PDT}
+    {941360400 -28800 0 PST}
+    {954669600 -25200 1 PDT}
+    {972810000 -28800 0 PST}
+    {986119200 -25200 1 PDT}
+    {1004259600 -28800 0 PST}
+    {1018173600 -25200 1 PDT}
+    {1035709200 -28800 0 PST}
+    {1049623200 -25200 1 PDT}
+    {1067158800 -28800 0 PST}
+    {1081072800 -25200 1 PDT}
+    {1099213200 -28800 0 PST}
+    {1112522400 -25200 1 PDT}
+    {1130662800 -28800 0 PST}
+    {1143972000 -25200 1 PDT}
+    {1162112400 -28800 0 PST}
+    {1173607200 -25200 1 PDT}
+    {1194166800 -28800 0 PST}
+    {1205056800 -25200 1 PDT}
+    {1225616400 -28800 0 PST}
+    {1236506400 -25200 1 PDT}
+    {1257066000 -28800 0 PST}
+    {1268560800 -25200 1 PDT}
+    {1289120400 -28800 0 PST}
+    {1300010400 -25200 1 PDT}
+    {1320570000 -28800 0 PST}
+    {1331460000 -25200 1 PDT}
+    {1352019600 -28800 0 PST}
+    {1362909600 -25200 1 PDT}
+    {1383469200 -28800 0 PST}
+    {1394359200 -25200 1 PDT}
+    {1414918800 -28800 0 PST}
+    {1425808800 -25200 1 PDT}
+    {1446368400 -28800 0 PST}
+    {1457863200 -25200 1 PDT}
+    {1478422800 -28800 0 PST}
+    {1489312800 -25200 1 PDT}
+    {1509872400 -28800 0 PST}
+    {1520762400 -25200 1 PDT}
+    {1541322000 -28800 0 PST}
+    {1552212000 -25200 1 PDT}
+    {1572771600 -28800 0 PST}
+    {1583661600 -25200 1 PDT}
+    {1604221200 -28800 0 PST}
+    {1615716000 -25200 1 PDT}
+    {1636275600 -28800 0 PST}
+    {1647165600 -25200 1 PDT}
+    {1667725200 -28800 0 PST}
+    {1678615200 -25200 1 PDT}
+    {1699174800 -28800 0 PST}
+    {1710064800 -25200 1 PDT}
+    {1730624400 -28800 0 PST}
+    {1741514400 -25200 1 PDT}
+    {1762074000 -28800 0 PST}
+    {1772964000 -25200 1 PDT}
+    {1793523600 -28800 0 PST}
+    {1805018400 -25200 1 PDT}
+    {1825578000 -28800 0 PST}
+    {1836468000 -25200 1 PDT}
+    {1857027600 -28800 0 PST}
+    {1867917600 -25200 1 PDT}
+    {1888477200 -28800 0 PST}
+    {1899367200 -25200 1 PDT}
+    {1919926800 -28800 0 PST}
+    {1930816800 -25200 1 PDT}
+    {1951376400 -28800 0 PST}
+    {1962871200 -25200 1 PDT}
+    {1983430800 -28800 0 PST}
+    {1994320800 -25200 1 PDT}
+    {2014880400 -28800 0 PST}
+    {2025770400 -25200 1 PDT}
+    {2046330000 -28800 0 PST}
+    {2057220000 -25200 1 PDT}
+    {2077779600 -28800 0 PST}
+    {2088669600 -25200 1 PDT}
+    {2109229200 -28800 0 PST}
+    {2120119200 -25200 1 PDT}
+    {2140678800 -28800 0 PST}
+    {2152173600 -25200 1 PDT}
+    {2172733200 -28800 0 PST}
+    {2183623200 -25200 1 PDT}
+    {2204182800 -28800 0 PST}
+    {2215072800 -25200 1 PDT}
+    {2235632400 -28800 0 PST}
+    {2246522400 -25200 1 PDT}
+    {2267082000 -28800 0 PST}
+    {2277972000 -25200 1 PDT}
+    {2298531600 -28800 0 PST}
+    {2309421600 -25200 1 PDT}
+    {2329981200 -28800 0 PST}
+    {2341476000 -25200 1 PDT}
+    {2362035600 -28800 0 PST}
+    {2372925600 -25200 1 PDT}
+    {2393485200 -28800 0 PST}
+    {2404375200 -25200 1 PDT}
+    {2424934800 -28800 0 PST}
+    {2435824800 -25200 1 PDT}
+    {2456384400 -28800 0 PST}
+    {2467274400 -25200 1 PDT}
+    {2487834000 -28800 0 PST}
+    {2499328800 -25200 1 PDT}
+    {2519888400 -28800 0 PST}
+    {2530778400 -25200 1 PDT}
+    {2551338000 -28800 0 PST}
+    {2562228000 -25200 1 PDT}
+    {2582787600 -28800 0 PST}
+    {2593677600 -25200 1 PDT}
+    {2614237200 -28800 0 PST}
+    {2625127200 -25200 1 PDT}
+    {2645686800 -28800 0 PST}
+    {2656576800 -25200 1 PDT}
+    {2677136400 -28800 0 PST}
+    {2688631200 -25200 1 PDT}
+    {2709190800 -28800 0 PST}
+    {2720080800 -25200 1 PDT}
+    {2740640400 -28800 0 PST}
+    {2751530400 -25200 1 PDT}
+    {2772090000 -28800 0 PST}
+    {2782980000 -25200 1 PDT}
+    {2803539600 -28800 0 PST}
+    {2814429600 -25200 1 PDT}
+    {2834989200 -28800 0 PST}
+    {2846484000 -25200 1 PDT}
+    {2867043600 -28800 0 PST}
+    {2877933600 -25200 1 PDT}
+    {2898493200 -28800 0 PST}
+    {2909383200 -25200 1 PDT}
+    {2929942800 -28800 0 PST}
+    {2940832800 -25200 1 PDT}
+    {2961392400 -28800 0 PST}
+    {2972282400 -25200 1 PDT}
+    {2992842000 -28800 0 PST}
+    {3003732000 -25200 1 PDT}
+    {3024291600 -28800 0 PST}
+    {3035786400 -25200 1 PDT}
+    {3056346000 -28800 0 PST}
+    {3067236000 -25200 1 PDT}
+    {3087795600 -28800 0 PST}
+    {3098685600 -25200 1 PDT}
+    {3119245200 -28800 0 PST}
+    {3130135200 -25200 1 PDT}
+    {3150694800 -28800 0 PST}
+    {3161584800 -25200 1 PDT}
+    {3182144400 -28800 0 PST}
+    {3193034400 -25200 1 PDT}
+    {3213594000 -28800 0 PST}
+    {3225088800 -25200 1 PDT}
+    {3245648400 -28800 0 PST}
+    {3256538400 -25200 1 PDT}
+    {3277098000 -28800 0 PST}
+    {3287988000 -25200 1 PDT}
+    {3308547600 -28800 0 PST}
+    {3319437600 -25200 1 PDT}
+    {3339997200 -28800 0 PST}
+    {3350887200 -25200 1 PDT}
+    {3371446800 -28800 0 PST}
+    {3382941600 -25200 1 PDT}
+    {3403501200 -28800 0 PST}
+    {3414391200 -25200 1 PDT}
+    {3434950800 -28800 0 PST}
+    {3445840800 -25200 1 PDT}
+    {3466400400 -28800 0 PST}
+    {3477290400 -25200 1 PDT}
+    {3497850000 -28800 0 PST}
+    {3508740000 -25200 1 PDT}
+    {3529299600 -28800 0 PST}
+    {3540189600 -25200 1 PDT}
+    {3560749200 -28800 0 PST}
+    {3572244000 -25200 1 PDT}
+    {3592803600 -28800 0 PST}
+    {3603693600 -25200 1 PDT}
+    {3624253200 -28800 0 PST}
+    {3635143200 -25200 1 PDT}
+    {3655702800 -28800 0 PST}
+    {3666592800 -25200 1 PDT}
+    {3687152400 -28800 0 PST}
+    {3698042400 -25200 1 PDT}
+    {3718602000 -28800 0 PST}
+    {3730096800 -25200 1 PDT}
+    {3750656400 -28800 0 PST}
+    {3761546400 -25200 1 PDT}
+    {3782106000 -28800 0 PST}
+    {3792996000 -25200 1 PDT}
+    {3813555600 -28800 0 PST}
+    {3824445600 -25200 1 PDT}
+    {3845005200 -28800 0 PST}
+    {3855895200 -25200 1 PDT}
+    {3876454800 -28800 0 PST}
+    {3887344800 -25200 1 PDT}
+    {3907904400 -28800 0 PST}
+    {3919399200 -25200 1 PDT}
+    {3939958800 -28800 0 PST}
+    {3950848800 -25200 1 PDT}
+    {3971408400 -28800 0 PST}
+    {3982298400 -25200 1 PDT}
+    {4002858000 -28800 0 PST}
+    {4013748000 -25200 1 PDT}
+    {4034307600 -28800 0 PST}
+    {4045197600 -25200 1 PDT}
+    {4065757200 -28800 0 PST}
+    {4076647200 -25200 1 PDT}
+    {4097206800 -28800 0 PST}
+}
diff --git a/library/tzdata/America/Winnipeg b/library/tzdata/America/Winnipeg
new file mode 100644
index 0000000..e6efe47
--- /dev/null
+++ b/library/tzdata/America/Winnipeg
@@ -0,0 +1,316 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Winnipeg) {
+    {-9223372036854775808 -23316 0 LMT}
+    {-2602258284 -21600 0 CST}
+    {-1694368800 -18000 1 CDT}
+    {-1681671600 -21600 0 CST}
+    {-1632067200 -18000 1 CDT}
+    {-1615136400 -21600 0 CST}
+    {-1029686400 -18000 1 CDT}
+    {-1018198800 -21600 0 CST}
+    {-880214400 -18000 1 CWT}
+    {-769395600 -18000 1 CPT}
+    {-765392400 -21600 0 CST}
+    {-746035200 -18000 1 CDT}
+    {-732733200 -21600 0 CST}
+    {-715795200 -18000 1 CDT}
+    {-702493200 -21600 0 CST}
+    {-684345600 -18000 1 CDT}
+    {-671043600 -21600 0 CST}
+    {-652896000 -18000 1 CDT}
+    {-639594000 -21600 0 CST}
+    {-620755200 -18000 1 CDT}
+    {-607626000 -21600 0 CST}
+    {-589392000 -18000 1 CDT}
+    {-576090000 -21600 0 CST}
+    {-557942400 -18000 1 CDT}
+    {-544640400 -21600 0 CST}
+    {-526492800 -18000 1 CDT}
+    {-513190800 -21600 0 CST}
+    {-495043200 -18000 1 CDT}
+    {-481741200 -21600 0 CST}
+    {-463593600 -18000 1 CDT}
+    {-450291600 -21600 0 CST}
+    {-431539200 -18000 1 CDT}
+    {-418237200 -21600 0 CST}
+    {-400089600 -18000 1 CDT}
+    {-386787600 -21600 0 CST}
+    {-368640000 -18000 1 CDT}
+    {-355338000 -21600 0 CST}
+    {-337190400 -18000 1 CDT}
+    {-321469200 -21600 0 CST}
+    {-305740800 -18000 1 CDT}
+    {-292438800 -21600 0 CST}
+    {-210787200 -18000 1 CDT}
+    {-198090000 -21600 0 CST}
+    {-116438400 -18000 1 CDT}
+    {-100108800 -21600 0 CST}
+    {-84384000 -18000 1 CDT}
+    {-68659200 -21600 0 CST}
+    {-52934400 -18000 1 CDT}
+    {-37209600 -21600 0 CST}
+    {-21484800 -18000 1 CDT}
+    {-5760000 -21600 0 CST}
+    {9964800 -18000 1 CDT}
+    {25689600 -21600 0 CST}
+    {41414400 -18000 1 CDT}
+    {57744000 -21600 0 CST}
+    {73468800 -18000 1 CDT}
+    {89193600 -21600 0 CST}
+    {104918400 -18000 1 CDT}
+    {120643200 -21600 0 CST}
+    {136368000 -18000 1 CDT}
+    {152092800 -21600 0 CST}
+    {167817600 -18000 1 CDT}
+    {183542400 -21600 0 CST}
+    {199267200 -18000 1 CDT}
+    {215596800 -21600 0 CST}
+    {230716800 -18000 1 CDT}
+    {247046400 -21600 0 CST}
+    {262771200 -18000 1 CDT}
+    {278496000 -21600 0 CST}
+    {294220800 -18000 1 CDT}
+    {309945600 -21600 0 CST}
+    {325670400 -18000 1 CDT}
+    {341395200 -21600 0 CST}
+    {357120000 -18000 1 CDT}
+    {372844800 -21600 0 CST}
+    {388569600 -18000 1 CDT}
+    {404899200 -21600 0 CST}
+    {420019200 -18000 1 CDT}
+    {436348800 -21600 0 CST}
+    {452073600 -18000 1 CDT}
+    {467798400 -21600 0 CST}
+    {483523200 -18000 1 CDT}
+    {499248000 -21600 0 CST}
+    {514972800 -18000 1 CDT}
+    {530697600 -21600 0 CST}
+    {544608000 -18000 1 CDT}
+    {562147200 -21600 0 CST}
+    {576057600 -18000 1 CDT}
+    {594201600 -21600 0 CST}
+    {607507200 -18000 1 CDT}
+    {625651200 -21600 0 CST}
+    {638956800 -18000 1 CDT}
+    {657100800 -21600 0 CST}
+    {671011200 -18000 1 CDT}
+    {688550400 -21600 0 CST}
+    {702460800 -18000 1 CDT}
+    {720000000 -21600 0 CST}
+    {733910400 -18000 1 CDT}
+    {752054400 -21600 0 CST}
+    {765360000 -18000 1 CDT}
+    {783504000 -21600 0 CST}
+    {796809600 -18000 1 CDT}
+    {814953600 -21600 0 CST}
+    {828864000 -18000 1 CDT}
+    {846403200 -21600 0 CST}
+    {860313600 -18000 1 CDT}
+    {877852800 -21600 0 CST}
+    {891763200 -18000 1 CDT}
+    {909302400 -21600 0 CST}
+    {923212800 -18000 1 CDT}
+    {941356800 -21600 0 CST}
+    {954662400 -18000 1 CDT}
+    {972806400 -21600 0 CST}
+    {986112000 -18000 1 CDT}
+    {1004256000 -21600 0 CST}
+    {1018166400 -18000 1 CDT}
+    {1035705600 -21600 0 CST}
+    {1049616000 -18000 1 CDT}
+    {1067155200 -21600 0 CST}
+    {1081065600 -18000 1 CDT}
+    {1099209600 -21600 0 CST}
+    {1112515200 -18000 1 CDT}
+    {1130659200 -21600 0 CST}
+    {1136095200 -21600 0 CST}
+    {1143964800 -18000 1 CDT}
+    {1162105200 -21600 0 CST}
+    {1173600000 -18000 1 CDT}
+    {1194159600 -21600 0 CST}
+    {1205049600 -18000 1 CDT}
+    {1225609200 -21600 0 CST}
+    {1236499200 -18000 1 CDT}
+    {1257058800 -21600 0 CST}
+    {1268553600 -18000 1 CDT}
+    {1289113200 -21600 0 CST}
+    {1300003200 -18000 1 CDT}
+    {1320562800 -21600 0 CST}
+    {1331452800 -18000 1 CDT}
+    {1352012400 -21600 0 CST}
+    {1362902400 -18000 1 CDT}
+    {1383462000 -21600 0 CST}
+    {1394352000 -18000 1 CDT}
+    {1414911600 -21600 0 CST}
+    {1425801600 -18000 1 CDT}
+    {1446361200 -21600 0 CST}
+    {1457856000 -18000 1 CDT}
+    {1478415600 -21600 0 CST}
+    {1489305600 -18000 1 CDT}
+    {1509865200 -21600 0 CST}
+    {1520755200 -18000 1 CDT}
+    {1541314800 -21600 0 CST}
+    {1552204800 -18000 1 CDT}
+    {1572764400 -21600 0 CST}
+    {1583654400 -18000 1 CDT}
+    {1604214000 -21600 0 CST}
+    {1615708800 -18000 1 CDT}
+    {1636268400 -21600 0 CST}
+    {1647158400 -18000 1 CDT}
+    {1667718000 -21600 0 CST}
+    {1678608000 -18000 1 CDT}
+    {1699167600 -21600 0 CST}
+    {1710057600 -18000 1 CDT}
+    {1730617200 -21600 0 CST}
+    {1741507200 -18000 1 CDT}
+    {1762066800 -21600 0 CST}
+    {1772956800 -18000 1 CDT}
+    {1793516400 -21600 0 CST}
+    {1805011200 -18000 1 CDT}
+    {1825570800 -21600 0 CST}
+    {1836460800 -18000 1 CDT}
+    {1857020400 -21600 0 CST}
+    {1867910400 -18000 1 CDT}
+    {1888470000 -21600 0 CST}
+    {1899360000 -18000 1 CDT}
+    {1919919600 -21600 0 CST}
+    {1930809600 -18000 1 CDT}
+    {1951369200 -21600 0 CST}
+    {1962864000 -18000 1 CDT}
+    {1983423600 -21600 0 CST}
+    {1994313600 -18000 1 CDT}
+    {2014873200 -21600 0 CST}
+    {2025763200 -18000 1 CDT}
+    {2046322800 -21600 0 CST}
+    {2057212800 -18000 1 CDT}
+    {2077772400 -21600 0 CST}
+    {2088662400 -18000 1 CDT}
+    {2109222000 -21600 0 CST}
+    {2120112000 -18000 1 CDT}
+    {2140671600 -21600 0 CST}
+    {2152166400 -18000 1 CDT}
+    {2172726000 -21600 0 CST}
+    {2183616000 -18000 1 CDT}
+    {2204175600 -21600 0 CST}
+    {2215065600 -18000 1 CDT}
+    {2235625200 -21600 0 CST}
+    {2246515200 -18000 1 CDT}
+    {2267074800 -21600 0 CST}
+    {2277964800 -18000 1 CDT}
+    {2298524400 -21600 0 CST}
+    {2309414400 -18000 1 CDT}
+    {2329974000 -21600 0 CST}
+    {2341468800 -18000 1 CDT}
+    {2362028400 -21600 0 CST}
+    {2372918400 -18000 1 CDT}
+    {2393478000 -21600 0 CST}
+    {2404368000 -18000 1 CDT}
+    {2424927600 -21600 0 CST}
+    {2435817600 -18000 1 CDT}
+    {2456377200 -21600 0 CST}
+    {2467267200 -18000 1 CDT}
+    {2487826800 -21600 0 CST}
+    {2499321600 -18000 1 CDT}
+    {2519881200 -21600 0 CST}
+    {2530771200 -18000 1 CDT}
+    {2551330800 -21600 0 CST}
+    {2562220800 -18000 1 CDT}
+    {2582780400 -21600 0 CST}
+    {2593670400 -18000 1 CDT}
+    {2614230000 -21600 0 CST}
+    {2625120000 -18000 1 CDT}
+    {2645679600 -21600 0 CST}
+    {2656569600 -18000 1 CDT}
+    {2677129200 -21600 0 CST}
+    {2688624000 -18000 1 CDT}
+    {2709183600 -21600 0 CST}
+    {2720073600 -18000 1 CDT}
+    {2740633200 -21600 0 CST}
+    {2751523200 -18000 1 CDT}
+    {2772082800 -21600 0 CST}
+    {2782972800 -18000 1 CDT}
+    {2803532400 -21600 0 CST}
+    {2814422400 -18000 1 CDT}
+    {2834982000 -21600 0 CST}
+    {2846476800 -18000 1 CDT}
+    {2867036400 -21600 0 CST}
+    {2877926400 -18000 1 CDT}
+    {2898486000 -21600 0 CST}
+    {2909376000 -18000 1 CDT}
+    {2929935600 -21600 0 CST}
+    {2940825600 -18000 1 CDT}
+    {2961385200 -21600 0 CST}
+    {2972275200 -18000 1 CDT}
+    {2992834800 -21600 0 CST}
+    {3003724800 -18000 1 CDT}
+    {3024284400 -21600 0 CST}
+    {3035779200 -18000 1 CDT}
+    {3056338800 -21600 0 CST}
+    {3067228800 -18000 1 CDT}
+    {3087788400 -21600 0 CST}
+    {3098678400 -18000 1 CDT}
+    {3119238000 -21600 0 CST}
+    {3130128000 -18000 1 CDT}
+    {3150687600 -21600 0 CST}
+    {3161577600 -18000 1 CDT}
+    {3182137200 -21600 0 CST}
+    {3193027200 -18000 1 CDT}
+    {3213586800 -21600 0 CST}
+    {3225081600 -18000 1 CDT}
+    {3245641200 -21600 0 CST}
+    {3256531200 -18000 1 CDT}
+    {3277090800 -21600 0 CST}
+    {3287980800 -18000 1 CDT}
+    {3308540400 -21600 0 CST}
+    {3319430400 -18000 1 CDT}
+    {3339990000 -21600 0 CST}
+    {3350880000 -18000 1 CDT}
+    {3371439600 -21600 0 CST}
+    {3382934400 -18000 1 CDT}
+    {3403494000 -21600 0 CST}
+    {3414384000 -18000 1 CDT}
+    {3434943600 -21600 0 CST}
+    {3445833600 -18000 1 CDT}
+    {3466393200 -21600 0 CST}
+    {3477283200 -18000 1 CDT}
+    {3497842800 -21600 0 CST}
+    {3508732800 -18000 1 CDT}
+    {3529292400 -21600 0 CST}
+    {3540182400 -18000 1 CDT}
+    {3560742000 -21600 0 CST}
+    {3572236800 -18000 1 CDT}
+    {3592796400 -21600 0 CST}
+    {3603686400 -18000 1 CDT}
+    {3624246000 -21600 0 CST}
+    {3635136000 -18000 1 CDT}
+    {3655695600 -21600 0 CST}
+    {3666585600 -18000 1 CDT}
+    {3687145200 -21600 0 CST}
+    {3698035200 -18000 1 CDT}
+    {3718594800 -21600 0 CST}
+    {3730089600 -18000 1 CDT}
+    {3750649200 -21600 0 CST}
+    {3761539200 -18000 1 CDT}
+    {3782098800 -21600 0 CST}
+    {3792988800 -18000 1 CDT}
+    {3813548400 -21600 0 CST}
+    {3824438400 -18000 1 CDT}
+    {3844998000 -21600 0 CST}
+    {3855888000 -18000 1 CDT}
+    {3876447600 -21600 0 CST}
+    {3887337600 -18000 1 CDT}
+    {3907897200 -21600 0 CST}
+    {3919392000 -18000 1 CDT}
+    {3939951600 -21600 0 CST}
+    {3950841600 -18000 1 CDT}
+    {3971401200 -21600 0 CST}
+    {3982291200 -18000 1 CDT}
+    {4002850800 -21600 0 CST}
+    {4013740800 -18000 1 CDT}
+    {4034300400 -21600 0 CST}
+    {4045190400 -18000 1 CDT}
+    {4065750000 -21600 0 CST}
+    {4076640000 -18000 1 CDT}
+    {4097199600 -21600 0 CST}
+}
diff --git a/library/tzdata/America/Yakutat b/library/tzdata/America/Yakutat
new file mode 100644
index 0000000..a0420c5
--- /dev/null
+++ b/library/tzdata/America/Yakutat
@@ -0,0 +1,276 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Yakutat) {
+    {-9223372036854775808 52865 0 LMT}
+    {-3225364865 -33535 0 LMT}
+    {-2188953665 -32400 0 YST}
+    {-883580400 -32400 0 YST}
+    {-880203600 -28800 1 YWT}
+    {-769395600 -28800 1 YPT}
+    {-765381600 -32400 0 YST}
+    {-757350000 -32400 0 YST}
+    {-31503600 -32400 0 YST}
+    {-21474000 -28800 1 YDT}
+    {-5752800 -32400 0 YST}
+    {9975600 -28800 1 YDT}
+    {25696800 -32400 0 YST}
+    {41425200 -28800 1 YDT}
+    {57751200 -32400 0 YST}
+    {73479600 -28800 1 YDT}
+    {89200800 -32400 0 YST}
+    {104929200 -28800 1 YDT}
+    {120650400 -32400 0 YST}
+    {126702000 -28800 1 YDT}
+    {152100000 -32400 0 YST}
+    {162385200 -28800 1 YDT}
+    {183549600 -32400 0 YST}
+    {199278000 -28800 1 YDT}
+    {215604000 -32400 0 YST}
+    {230727600 -28800 1 YDT}
+    {247053600 -32400 0 YST}
+    {262782000 -28800 1 YDT}
+    {278503200 -32400 0 YST}
+    {294231600 -28800 1 YDT}
+    {309952800 -32400 0 YST}
+    {325681200 -28800 1 YDT}
+    {341402400 -32400 0 YST}
+    {357130800 -28800 1 YDT}
+    {372852000 -32400 0 YST}
+    {388580400 -28800 1 YDT}
+    {404906400 -32400 0 YST}
+    {420030000 -28800 1 YDT}
+    {436356000 -32400 0 YST}
+    {439030800 -32400 0 AKST}
+    {452084400 -28800 1 AKDT}
+    {467805600 -32400 0 AKST}
+    {483534000 -28800 1 AKDT}
+    {499255200 -32400 0 AKST}
+    {514983600 -28800 1 AKDT}
+    {530704800 -32400 0 AKST}
+    {544618800 -28800 1 AKDT}
+    {562154400 -32400 0 AKST}
+    {576068400 -28800 1 AKDT}
+    {594208800 -32400 0 AKST}
+    {607518000 -28800 1 AKDT}
+    {625658400 -32400 0 AKST}
+    {638967600 -28800 1 AKDT}
+    {657108000 -32400 0 AKST}
+    {671022000 -28800 1 AKDT}
+    {688557600 -32400 0 AKST}
+    {702471600 -28800 1 AKDT}
+    {720007200 -32400 0 AKST}
+    {733921200 -28800 1 AKDT}
+    {752061600 -32400 0 AKST}
+    {765370800 -28800 1 AKDT}
+    {783511200 -32400 0 AKST}
+    {796820400 -28800 1 AKDT}
+    {814960800 -32400 0 AKST}
+    {828874800 -28800 1 AKDT}
+    {846410400 -32400 0 AKST}
+    {860324400 -28800 1 AKDT}
+    {877860000 -32400 0 AKST}
+    {891774000 -28800 1 AKDT}
+    {909309600 -32400 0 AKST}
+    {923223600 -28800 1 AKDT}
+    {941364000 -32400 0 AKST}
+    {954673200 -28800 1 AKDT}
+    {972813600 -32400 0 AKST}
+    {986122800 -28800 1 AKDT}
+    {1004263200 -32400 0 AKST}
+    {1018177200 -28800 1 AKDT}
+    {1035712800 -32400 0 AKST}
+    {1049626800 -28800 1 AKDT}
+    {1067162400 -32400 0 AKST}
+    {1081076400 -28800 1 AKDT}
+    {1099216800 -32400 0 AKST}
+    {1112526000 -28800 1 AKDT}
+    {1130666400 -32400 0 AKST}
+    {1143975600 -28800 1 AKDT}
+    {1162116000 -32400 0 AKST}
+    {1173610800 -28800 1 AKDT}
+    {1194170400 -32400 0 AKST}
+    {1205060400 -28800 1 AKDT}
+    {1225620000 -32400 0 AKST}
+    {1236510000 -28800 1 AKDT}
+    {1257069600 -32400 0 AKST}
+    {1268564400 -28800 1 AKDT}
+    {1289124000 -32400 0 AKST}
+    {1300014000 -28800 1 AKDT}
+    {1320573600 -32400 0 AKST}
+    {1331463600 -28800 1 AKDT}
+    {1352023200 -32400 0 AKST}
+    {1362913200 -28800 1 AKDT}
+    {1383472800 -32400 0 AKST}
+    {1394362800 -28800 1 AKDT}
+    {1414922400 -32400 0 AKST}
+    {1425812400 -28800 1 AKDT}
+    {1446372000 -32400 0 AKST}
+    {1457866800 -28800 1 AKDT}
+    {1478426400 -32400 0 AKST}
+    {1489316400 -28800 1 AKDT}
+    {1509876000 -32400 0 AKST}
+    {1520766000 -28800 1 AKDT}
+    {1541325600 -32400 0 AKST}
+    {1552215600 -28800 1 AKDT}
+    {1572775200 -32400 0 AKST}
+    {1583665200 -28800 1 AKDT}
+    {1604224800 -32400 0 AKST}
+    {1615719600 -28800 1 AKDT}
+    {1636279200 -32400 0 AKST}
+    {1647169200 -28800 1 AKDT}
+    {1667728800 -32400 0 AKST}
+    {1678618800 -28800 1 AKDT}
+    {1699178400 -32400 0 AKST}
+    {1710068400 -28800 1 AKDT}
+    {1730628000 -32400 0 AKST}
+    {1741518000 -28800 1 AKDT}
+    {1762077600 -32400 0 AKST}
+    {1772967600 -28800 1 AKDT}
+    {1793527200 -32400 0 AKST}
+    {1805022000 -28800 1 AKDT}
+    {1825581600 -32400 0 AKST}
+    {1836471600 -28800 1 AKDT}
+    {1857031200 -32400 0 AKST}
+    {1867921200 -28800 1 AKDT}
+    {1888480800 -32400 0 AKST}
+    {1899370800 -28800 1 AKDT}
+    {1919930400 -32400 0 AKST}
+    {1930820400 -28800 1 AKDT}
+    {1951380000 -32400 0 AKST}
+    {1962874800 -28800 1 AKDT}
+    {1983434400 -32400 0 AKST}
+    {1994324400 -28800 1 AKDT}
+    {2014884000 -32400 0 AKST}
+    {2025774000 -28800 1 AKDT}
+    {2046333600 -32400 0 AKST}
+    {2057223600 -28800 1 AKDT}
+    {2077783200 -32400 0 AKST}
+    {2088673200 -28800 1 AKDT}
+    {2109232800 -32400 0 AKST}
+    {2120122800 -28800 1 AKDT}
+    {2140682400 -32400 0 AKST}
+    {2152177200 -28800 1 AKDT}
+    {2172736800 -32400 0 AKST}
+    {2183626800 -28800 1 AKDT}
+    {2204186400 -32400 0 AKST}
+    {2215076400 -28800 1 AKDT}
+    {2235636000 -32400 0 AKST}
+    {2246526000 -28800 1 AKDT}
+    {2267085600 -32400 0 AKST}
+    {2277975600 -28800 1 AKDT}
+    {2298535200 -32400 0 AKST}
+    {2309425200 -28800 1 AKDT}
+    {2329984800 -32400 0 AKST}
+    {2341479600 -28800 1 AKDT}
+    {2362039200 -32400 0 AKST}
+    {2372929200 -28800 1 AKDT}
+    {2393488800 -32400 0 AKST}
+    {2404378800 -28800 1 AKDT}
+    {2424938400 -32400 0 AKST}
+    {2435828400 -28800 1 AKDT}
+    {2456388000 -32400 0 AKST}
+    {2467278000 -28800 1 AKDT}
+    {2487837600 -32400 0 AKST}
+    {2499332400 -28800 1 AKDT}
+    {2519892000 -32400 0 AKST}
+    {2530782000 -28800 1 AKDT}
+    {2551341600 -32400 0 AKST}
+    {2562231600 -28800 1 AKDT}
+    {2582791200 -32400 0 AKST}
+    {2593681200 -28800 1 AKDT}
+    {2614240800 -32400 0 AKST}
+    {2625130800 -28800 1 AKDT}
+    {2645690400 -32400 0 AKST}
+    {2656580400 -28800 1 AKDT}
+    {2677140000 -32400 0 AKST}
+    {2688634800 -28800 1 AKDT}
+    {2709194400 -32400 0 AKST}
+    {2720084400 -28800 1 AKDT}
+    {2740644000 -32400 0 AKST}
+    {2751534000 -28800 1 AKDT}
+    {2772093600 -32400 0 AKST}
+    {2782983600 -28800 1 AKDT}
+    {2803543200 -32400 0 AKST}
+    {2814433200 -28800 1 AKDT}
+    {2834992800 -32400 0 AKST}
+    {2846487600 -28800 1 AKDT}
+    {2867047200 -32400 0 AKST}
+    {2877937200 -28800 1 AKDT}
+    {2898496800 -32400 0 AKST}
+    {2909386800 -28800 1 AKDT}
+    {2929946400 -32400 0 AKST}
+    {2940836400 -28800 1 AKDT}
+    {2961396000 -32400 0 AKST}
+    {2972286000 -28800 1 AKDT}
+    {2992845600 -32400 0 AKST}
+    {3003735600 -28800 1 AKDT}
+    {3024295200 -32400 0 AKST}
+    {3035790000 -28800 1 AKDT}
+    {3056349600 -32400 0 AKST}
+    {3067239600 -28800 1 AKDT}
+    {3087799200 -32400 0 AKST}
+    {3098689200 -28800 1 AKDT}
+    {3119248800 -32400 0 AKST}
+    {3130138800 -28800 1 AKDT}
+    {3150698400 -32400 0 AKST}
+    {3161588400 -28800 1 AKDT}
+    {3182148000 -32400 0 AKST}
+    {3193038000 -28800 1 AKDT}
+    {3213597600 -32400 0 AKST}
+    {3225092400 -28800 1 AKDT}
+    {3245652000 -32400 0 AKST}
+    {3256542000 -28800 1 AKDT}
+    {3277101600 -32400 0 AKST}
+    {3287991600 -28800 1 AKDT}
+    {3308551200 -32400 0 AKST}
+    {3319441200 -28800 1 AKDT}
+    {3340000800 -32400 0 AKST}
+    {3350890800 -28800 1 AKDT}
+    {3371450400 -32400 0 AKST}
+    {3382945200 -28800 1 AKDT}
+    {3403504800 -32400 0 AKST}
+    {3414394800 -28800 1 AKDT}
+    {3434954400 -32400 0 AKST}
+    {3445844400 -28800 1 AKDT}
+    {3466404000 -32400 0 AKST}
+    {3477294000 -28800 1 AKDT}
+    {3497853600 -32400 0 AKST}
+    {3508743600 -28800 1 AKDT}
+    {3529303200 -32400 0 AKST}
+    {3540193200 -28800 1 AKDT}
+    {3560752800 -32400 0 AKST}
+    {3572247600 -28800 1 AKDT}
+    {3592807200 -32400 0 AKST}
+    {3603697200 -28800 1 AKDT}
+    {3624256800 -32400 0 AKST}
+    {3635146800 -28800 1 AKDT}
+    {3655706400 -32400 0 AKST}
+    {3666596400 -28800 1 AKDT}
+    {3687156000 -32400 0 AKST}
+    {3698046000 -28800 1 AKDT}
+    {3718605600 -32400 0 AKST}
+    {3730100400 -28800 1 AKDT}
+    {3750660000 -32400 0 AKST}
+    {3761550000 -28800 1 AKDT}
+    {3782109600 -32400 0 AKST}
+    {3792999600 -28800 1 AKDT}
+    {3813559200 -32400 0 AKST}
+    {3824449200 -28800 1 AKDT}
+    {3845008800 -32400 0 AKST}
+    {3855898800 -28800 1 AKDT}
+    {3876458400 -32400 0 AKST}
+    {3887348400 -28800 1 AKDT}
+    {3907908000 -32400 0 AKST}
+    {3919402800 -28800 1 AKDT}
+    {3939962400 -32400 0 AKST}
+    {3950852400 -28800 1 AKDT}
+    {3971412000 -32400 0 AKST}
+    {3982302000 -28800 1 AKDT}
+    {4002861600 -32400 0 AKST}
+    {4013751600 -28800 1 AKDT}
+    {4034311200 -32400 0 AKST}
+    {4045201200 -28800 1 AKDT}
+    {4065760800 -32400 0 AKST}
+    {4076650800 -28800 1 AKDT}
+    {4097210400 -32400 0 AKST}
+}
diff --git a/library/tzdata/America/Yellowknife b/library/tzdata/America/Yellowknife
new file mode 100644
index 0000000..c6c4ed5
--- /dev/null
+++ b/library/tzdata/America/Yellowknife
@@ -0,0 +1,252 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:America/Yellowknife) {
+    {-9223372036854775808 0 0 -00}
+    {-1104537600 -25200 0 MST}
+    {-880210800 -21600 1 MWT}
+    {-769395600 -21600 1 MPT}
+    {-765388800 -25200 0 MST}
+    {-147891600 -18000 1 MDDT}
+    {-131562000 -25200 0 MST}
+    {315558000 -25200 0 MST}
+    {325674000 -21600 1 MDT}
+    {341395200 -25200 0 MST}
+    {357123600 -21600 1 MDT}
+    {372844800 -25200 0 MST}
+    {388573200 -21600 1 MDT}
+    {404899200 -25200 0 MST}
+    {420022800 -21600 1 MDT}
+    {436348800 -25200 0 MST}
+    {452077200 -21600 1 MDT}
+    {467798400 -25200 0 MST}
+    {483526800 -21600 1 MDT}
+    {499248000 -25200 0 MST}
+    {514976400 -21600 1 MDT}
+    {530697600 -25200 0 MST}
+    {544611600 -21600 1 MDT}
+    {562147200 -25200 0 MST}
+    {576061200 -21600 1 MDT}
+    {594201600 -25200 0 MST}
+    {607510800 -21600 1 MDT}
+    {625651200 -25200 0 MST}
+    {638960400 -21600 1 MDT}
+    {657100800 -25200 0 MST}
+    {671014800 -21600 1 MDT}
+    {688550400 -25200 0 MST}
+    {702464400 -21600 1 MDT}
+    {720000000 -25200 0 MST}
+    {733914000 -21600 1 MDT}
+    {752054400 -25200 0 MST}
+    {765363600 -21600 1 MDT}
+    {783504000 -25200 0 MST}
+    {796813200 -21600 1 MDT}
+    {814953600 -25200 0 MST}
+    {828867600 -21600 1 MDT}
+    {846403200 -25200 0 MST}
+    {860317200 -21600 1 MDT}
+    {877852800 -25200 0 MST}
+    {891766800 -21600 1 MDT}
+    {909302400 -25200 0 MST}
+    {923216400 -21600 1 MDT}
+    {941356800 -25200 0 MST}
+    {954666000 -21600 1 MDT}
+    {972806400 -25200 0 MST}
+    {986115600 -21600 1 MDT}
+    {1004256000 -25200 0 MST}
+    {1018170000 -21600 1 MDT}
+    {1035705600 -25200 0 MST}
+    {1049619600 -21600 1 MDT}
+    {1067155200 -25200 0 MST}
+    {1081069200 -21600 1 MDT}
+    {1099209600 -25200 0 MST}
+    {1112518800 -21600 1 MDT}
+    {1130659200 -25200 0 MST}
+    {1143968400 -21600 1 MDT}
+    {1162108800 -25200 0 MST}
+    {1173603600 -21600 1 MDT}
+    {1194163200 -25200 0 MST}
+    {1205053200 -21600 1 MDT}
+    {1225612800 -25200 0 MST}
+    {1236502800 -21600 1 MDT}
+    {1257062400 -25200 0 MST}
+    {1268557200 -21600 1 MDT}
+    {1289116800 -25200 0 MST}
+    {1300006800 -21600 1 MDT}
+    {1320566400 -25200 0 MST}
+    {1331456400 -21600 1 MDT}
+    {1352016000 -25200 0 MST}
+    {1362906000 -21600 1 MDT}
+    {1383465600 -25200 0 MST}
+    {1394355600 -21600 1 MDT}
+    {1414915200 -25200 0 MST}
+    {1425805200 -21600 1 MDT}
+    {1446364800 -25200 0 MST}
+    {1457859600 -21600 1 MDT}
+    {1478419200 -25200 0 MST}
+    {1489309200 -21600 1 MDT}
+    {1509868800 -25200 0 MST}
+    {1520758800 -21600 1 MDT}
+    {1541318400 -25200 0 MST}
+    {1552208400 -21600 1 MDT}
+    {1572768000 -25200 0 MST}
+    {1583658000 -21600 1 MDT}
+    {1604217600 -25200 0 MST}
+    {1615712400 -21600 1 MDT}
+    {1636272000 -25200 0 MST}
+    {1647162000 -21600 1 MDT}
+    {1667721600 -25200 0 MST}
+    {1678611600 -21600 1 MDT}
+    {1699171200 -25200 0 MST}
+    {1710061200 -21600 1 MDT}
+    {1730620800 -25200 0 MST}
+    {1741510800 -21600 1 MDT}
+    {1762070400 -25200 0 MST}
+    {1772960400 -21600 1 MDT}
+    {1793520000 -25200 0 MST}
+    {1805014800 -21600 1 MDT}
+    {1825574400 -25200 0 MST}
+    {1836464400 -21600 1 MDT}
+    {1857024000 -25200 0 MST}
+    {1867914000 -21600 1 MDT}
+    {1888473600 -25200 0 MST}
+    {1899363600 -21600 1 MDT}
+    {1919923200 -25200 0 MST}
+    {1930813200 -21600 1 MDT}
+    {1951372800 -25200 0 MST}
+    {1962867600 -21600 1 MDT}
+    {1983427200 -25200 0 MST}
+    {1994317200 -21600 1 MDT}
+    {2014876800 -25200 0 MST}
+    {2025766800 -21600 1 MDT}
+    {2046326400 -25200 0 MST}
+    {2057216400 -21600 1 MDT}
+    {2077776000 -25200 0 MST}
+    {2088666000 -21600 1 MDT}
+    {2109225600 -25200 0 MST}
+    {2120115600 -21600 1 MDT}
+    {2140675200 -25200 0 MST}
+    {2152170000 -21600 1 MDT}
+    {2172729600 -25200 0 MST}
+    {2183619600 -21600 1 MDT}
+    {2204179200 -25200 0 MST}
+    {2215069200 -21600 1 MDT}
+    {2235628800 -25200 0 MST}
+    {2246518800 -21600 1 MDT}
+    {2267078400 -25200 0 MST}
+    {2277968400 -21600 1 MDT}
+    {2298528000 -25200 0 MST}
+    {2309418000 -21600 1 MDT}
+    {2329977600 -25200 0 MST}
+    {2341472400 -21600 1 MDT}
+    {2362032000 -25200 0 MST}
+    {2372922000 -21600 1 MDT}
+    {2393481600 -25200 0 MST}
+    {2404371600 -21600 1 MDT}
+    {2424931200 -25200 0 MST}
+    {2435821200 -21600 1 MDT}
+    {2456380800 -25200 0 MST}
+    {2467270800 -21600 1 MDT}
+    {2487830400 -25200 0 MST}
+    {2499325200 -21600 1 MDT}
+    {2519884800 -25200 0 MST}
+    {2530774800 -21600 1 MDT}
+    {2551334400 -25200 0 MST}
+    {2562224400 -21600 1 MDT}
+    {2582784000 -25200 0 MST}
+    {2593674000 -21600 1 MDT}
+    {2614233600 -25200 0 MST}
+    {2625123600 -21600 1 MDT}
+    {2645683200 -25200 0 MST}
+    {2656573200 -21600 1 MDT}
+    {2677132800 -25200 0 MST}
+    {2688627600 -21600 1 MDT}
+    {2709187200 -25200 0 MST}
+    {2720077200 -21600 1 MDT}
+    {2740636800 -25200 0 MST}
+    {2751526800 -21600 1 MDT}
+    {2772086400 -25200 0 MST}
+    {2782976400 -21600 1 MDT}
+    {2803536000 -25200 0 MST}
+    {2814426000 -21600 1 MDT}
+    {2834985600 -25200 0 MST}
+    {2846480400 -21600 1 MDT}
+    {2867040000 -25200 0 MST}
+    {2877930000 -21600 1 MDT}
+    {2898489600 -25200 0 MST}
+    {2909379600 -21600 1 MDT}
+    {2929939200 -25200 0 MST}
+    {2940829200 -21600 1 MDT}
+    {2961388800 -25200 0 MST}
+    {2972278800 -21600 1 MDT}
+    {2992838400 -25200 0 MST}
+    {3003728400 -21600 1 MDT}
+    {3024288000 -25200 0 MST}
+    {3035782800 -21600 1 MDT}
+    {3056342400 -25200 0 MST}
+    {3067232400 -21600 1 MDT}
+    {3087792000 -25200 0 MST}
+    {3098682000 -21600 1 MDT}
+    {3119241600 -25200 0 MST}
+    {3130131600 -21600 1 MDT}
+    {3150691200 -25200 0 MST}
+    {3161581200 -21600 1 MDT}
+    {3182140800 -25200 0 MST}
+    {3193030800 -21600 1 MDT}
+    {3213590400 -25200 0 MST}
+    {3225085200 -21600 1 MDT}
+    {3245644800 -25200 0 MST}
+    {3256534800 -21600 1 MDT}
+    {3277094400 -25200 0 MST}
+    {3287984400 -21600 1 MDT}
+    {3308544000 -25200 0 MST}
+    {3319434000 -21600 1 MDT}
+    {3339993600 -25200 0 MST}
+    {3350883600 -21600 1 MDT}
+    {3371443200 -25200 0 MST}
+    {3382938000 -21600 1 MDT}
+    {3403497600 -25200 0 MST}
+    {3414387600 -21600 1 MDT}
+    {3434947200 -25200 0 MST}
+    {3445837200 -21600 1 MDT}
+    {3466396800 -25200 0 MST}
+    {3477286800 -21600 1 MDT}
+    {3497846400 -25200 0 MST}
+    {3508736400 -21600 1 MDT}
+    {3529296000 -25200 0 MST}
+    {3540186000 -21600 1 MDT}
+    {3560745600 -25200 0 MST}
+    {3572240400 -21600 1 MDT}
+    {3592800000 -25200 0 MST}
+    {3603690000 -21600 1 MDT}
+    {3624249600 -25200 0 MST}
+    {3635139600 -21600 1 MDT}
+    {3655699200 -25200 0 MST}
+    {3666589200 -21600 1 MDT}
+    {3687148800 -25200 0 MST}
+    {3698038800 -21600 1 MDT}
+    {3718598400 -25200 0 MST}
+    {3730093200 -21600 1 MDT}
+    {3750652800 -25200 0 MST}
+    {3761542800 -21600 1 MDT}
+    {3782102400 -25200 0 MST}
+    {3792992400 -21600 1 MDT}
+    {3813552000 -25200 0 MST}
+    {3824442000 -21600 1 MDT}
+    {3845001600 -25200 0 MST}
+    {3855891600 -21600 1 MDT}
+    {3876451200 -25200 0 MST}
+    {3887341200 -21600 1 MDT}
+    {3907900800 -25200 0 MST}
+    {3919395600 -21600 1 MDT}
+    {3939955200 -25200 0 MST}
+    {3950845200 -21600 1 MDT}
+    {3971404800 -25200 0 MST}
+    {3982294800 -21600 1 MDT}
+    {4002854400 -25200 0 MST}
+    {4013744400 -21600 1 MDT}
+    {4034304000 -25200 0 MST}
+    {4045194000 -21600 1 MDT}
+    {4065753600 -25200 0 MST}
+    {4076643600 -21600 1 MDT}
+    {4097203200 -25200 0 MST}
+}
diff --git a/library/tzdata/Antarctica/Casey b/library/tzdata/Antarctica/Casey
new file mode 100644
index 0000000..2573dac
--- /dev/null
+++ b/library/tzdata/Antarctica/Casey
@@ -0,0 +1,10 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Antarctica/Casey) {
+    {-9223372036854775808 0 0 -00}
+    {-31536000 28800 0 AWST}
+    {1255802400 39600 0 CAST}
+    {1267714800 28800 0 AWST}
+    {1319738400 39600 0 CAST}
+    {1329843600 28800 0 AWST}
+}
diff --git a/library/tzdata/Antarctica/Davis b/library/tzdata/Antarctica/Davis
new file mode 100644
index 0000000..c98be2f
--- /dev/null
+++ b/library/tzdata/Antarctica/Davis
@@ -0,0 +1,12 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Antarctica/Davis) {
+    {-9223372036854775808 0 0 -00}
+    {-409190400 25200 0 DAVT}
+    {-163062000 0 0 -00}
+    {-28857600 25200 0 DAVT}
+    {1255806000 18000 0 DAVT}
+    {1268251200 25200 0 DAVT}
+    {1319742000 18000 0 DAVT}
+    {1329854400 25200 0 DAVT}
+}
diff --git a/library/tzdata/Antarctica/DumontDUrville b/library/tzdata/Antarctica/DumontDUrville
new file mode 100644
index 0000000..8d21d45
--- /dev/null
+++ b/library/tzdata/Antarctica/DumontDUrville
@@ -0,0 +1,8 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Antarctica/DumontDUrville) {
+    {-9223372036854775808 0 0 -00}
+    {-725846400 36000 0 PMT}
+    {-566992800 0 0 -00}
+    {-415497600 36000 0 DDUT}
+}
diff --git a/library/tzdata/Antarctica/Macquarie b/library/tzdata/Antarctica/Macquarie
new file mode 100644
index 0000000..9ed0630
--- /dev/null
+++ b/library/tzdata/Antarctica/Macquarie
@@ -0,0 +1,97 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Antarctica/Macquarie) {
+    {-9223372036854775808 0 0 -00}
+    {-2214259200 36000 0 AEST}
+    {-1680508800 39600 1 AEDT}
+    {-1669892400 39600 0 AEDT}
+    {-1665392400 36000 0 AEST}
+    {-1601719200 0 0 -00}
+    {-94730400 36000 0 AEST}
+    {-71136000 39600 1 AEDT}
+    {-55411200 36000 0 AEST}
+    {-37267200 39600 1 AEDT}
+    {-25776000 36000 0 AEST}
+    {-5817600 39600 1 AEDT}
+    {5673600 36000 0 AEST}
+    {25632000 39600 1 AEDT}
+    {37728000 36000 0 AEST}
+    {57686400 39600 1 AEDT}
+    {67968000 36000 0 AEST}
+    {89136000 39600 1 AEDT}
+    {100022400 36000 0 AEST}
+    {120585600 39600 1 AEDT}
+    {131472000 36000 0 AEST}
+    {152035200 39600 1 AEDT}
+    {162921600 36000 0 AEST}
+    {183484800 39600 1 AEDT}
+    {194976000 36000 0 AEST}
+    {215539200 39600 1 AEDT}
+    {226425600 36000 0 AEST}
+    {246988800 39600 1 AEDT}
+    {257875200 36000 0 AEST}
+    {278438400 39600 1 AEDT}
+    {289324800 36000 0 AEST}
+    {309888000 39600 1 AEDT}
+    {320774400 36000 0 AEST}
+    {341337600 39600 1 AEDT}
+    {352224000 36000 0 AEST}
+    {372787200 39600 1 AEDT}
+    {386092800 36000 0 AEST}
+    {404841600 39600 1 AEDT}
+    {417542400 36000 0 AEST}
+    {436291200 39600 1 AEDT}
+    {447177600 36000 0 AEST}
+    {467740800 39600 1 AEDT}
+    {478627200 36000 0 AEST}
+    {499190400 39600 1 AEDT}
+    {510076800 36000 0 AEST}
+    {530035200 39600 1 AEDT}
+    {542736000 36000 0 AEST}
+    {562089600 39600 1 AEDT}
+    {574790400 36000 0 AEST}
+    {594144000 39600 1 AEDT}
+    {606240000 36000 0 AEST}
+    {625593600 39600 1 AEDT}
+    {637689600 36000 0 AEST}
+    {657043200 39600 1 AEDT}
+    {670348800 36000 0 AEST}
+    {686678400 39600 1 AEDT}
+    {701798400 36000 0 AEST}
+    {718128000 39600 1 AEDT}
+    {733248000 36000 0 AEST}
+    {749577600 39600 1 AEDT}
+    {764697600 36000 0 AEST}
+    {781027200 39600 1 AEDT}
+    {796147200 36000 0 AEST}
+    {812476800 39600 1 AEDT}
+    {828201600 36000 0 AEST}
+    {844531200 39600 1 AEDT}
+    {859651200 36000 0 AEST}
+    {875980800 39600 1 AEDT}
+    {891100800 36000 0 AEST}
+    {907430400 39600 1 AEDT}
+    {922550400 36000 0 AEST}
+    {938880000 39600 1 AEDT}
+    {954000000 36000 0 AEST}
+    {967305600 39600 1 AEDT}
+    {985449600 36000 0 AEST}
+    {1002384000 39600 1 AEDT}
+    {1017504000 36000 0 AEST}
+    {1033833600 39600 1 AEDT}
+    {1048953600 36000 0 AEST}
+    {1065283200 39600 1 AEDT}
+    {1080403200 36000 0 AEST}
+    {1096732800 39600 1 AEDT}
+    {1111852800 36000 0 AEST}
+    {1128182400 39600 1 AEDT}
+    {1143907200 36000 0 AEST}
+    {1159632000 39600 1 AEDT}
+    {1174752000 36000 0 AEST}
+    {1191686400 39600 1 AEDT}
+    {1207411200 36000 0 AEST}
+    {1223136000 39600 1 AEDT}
+    {1238860800 36000 0 AEST}
+    {1254585600 39600 1 AEDT}
+    {1270310400 39600 0 MIST}
+}
diff --git a/library/tzdata/Antarctica/Mawson b/library/tzdata/Antarctica/Mawson
new file mode 100644
index 0000000..e50aa07
--- /dev/null
+++ b/library/tzdata/Antarctica/Mawson
@@ -0,0 +1,7 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Antarctica/Mawson) {
+    {-9223372036854775808 0 0 -00}
+    {-501206400 21600 0 MAWT}
+    {1255809600 18000 0 MAWT}
+}
diff --git a/library/tzdata/Antarctica/McMurdo b/library/tzdata/Antarctica/McMurdo
new file mode 100644
index 0000000..3b29ba1
--- /dev/null
+++ b/library/tzdata/Antarctica/McMurdo
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Pacific/Auckland)]} {
+    LoadTimeZoneFile Pacific/Auckland
+}
+set TZData(:Antarctica/McMurdo) $TZData(:Pacific/Auckland)
diff --git a/library/tzdata/Antarctica/Palmer b/library/tzdata/Antarctica/Palmer
new file mode 100644
index 0000000..62b17e1
--- /dev/null
+++ b/library/tzdata/Antarctica/Palmer
@@ -0,0 +1,252 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Antarctica/Palmer) {
+    {-9223372036854775808 0 0 -00}
+    {-157766400 -14400 0 ART}
+    {-152654400 -14400 0 ART}
+    {-132955200 -10800 1 ARST}
+    {-121122000 -14400 0 ART}
+    {-101419200 -10800 1 ARST}
+    {-86821200 -14400 0 ART}
+    {-71092800 -10800 1 ARST}
+    {-54766800 -14400 0 ART}
+    {-39038400 -10800 1 ARST}
+    {-23317200 -14400 0 ART}
+    {-7588800 -10800 0 ART}
+    {128142000 -7200 1 ARST}
+    {136605600 -10800 0 ART}
+    {389070000 -14400 0 CLT}
+    {403070400 -10800 1 CLST}
+    {416372400 -14400 0 CLT}
+    {434520000 -10800 1 CLST}
+    {447822000 -14400 0 CLT}
+    {466574400 -10800 1 CLST}
+    {479271600 -14400 0 CLT}
+    {498024000 -10800 1 CLST}
+    {510721200 -14400 0 CLT}
+    {529473600 -10800 1 CLST}
+    {545194800 -14400 0 CLT}
+    {560923200 -10800 1 CLST}
+    {574225200 -14400 0 CLT}
+    {592372800 -10800 1 CLST}
+    {605674800 -14400 0 CLT}
+    {624427200 -10800 1 CLST}
+    {637124400 -14400 0 CLT}
+    {653457600 -10800 1 CLST}
+    {668574000 -14400 0 CLT}
+    {687326400 -10800 1 CLST}
+    {700628400 -14400 0 CLT}
+    {718776000 -10800 1 CLST}
+    {732078000 -14400 0 CLT}
+    {750225600 -10800 1 CLST}
+    {763527600 -14400 0 CLT}
+    {781675200 -10800 1 CLST}
+    {794977200 -14400 0 CLT}
+    {813729600 -10800 1 CLST}
+    {826426800 -14400 0 CLT}
+    {845179200 -10800 1 CLST}
+    {859690800 -14400 0 CLT}
+    {876628800 -10800 1 CLST}
+    {889930800 -14400 0 CLT}
+    {906868800 -10800 1 CLST}
+    {923194800 -14400 0 CLT}
+    {939528000 -10800 1 CLST}
+    {952830000 -14400 0 CLT}
+    {971582400 -10800 1 CLST}
+    {984279600 -14400 0 CLT}
+    {1003032000 -10800 1 CLST}
+    {1015729200 -14400 0 CLT}
+    {1034481600 -10800 1 CLST}
+    {1047178800 -14400 0 CLT}
+    {1065931200 -10800 1 CLST}
+    {1079233200 -14400 0 CLT}
+    {1097380800 -10800 1 CLST}
+    {1110682800 -14400 0 CLT}
+    {1128830400 -10800 1 CLST}
+    {1142132400 -14400 0 CLT}
+    {1160884800 -10800 1 CLST}
+    {1173582000 -14400 0 CLT}
+    {1192334400 -10800 1 CLST}
+    {1206846000 -14400 0 CLT}
+    {1223784000 -10800 1 CLST}
+    {1237086000 -14400 0 CLT}
+    {1255233600 -10800 1 CLST}
+    {1270350000 -14400 0 CLT}
+    {1286683200 -10800 1 CLST}
+    {1304823600 -14400 0 CLT}
+    {1313899200 -10800 1 CLST}
+    {1335668400 -14400 0 CLT}
+    {1346558400 -10800 1 CLST}
+    {1367118000 -14400 0 CLT}
+    {1378612800 -10800 1 CLST}
+    {1398567600 -14400 0 CLT}
+    {1410062400 -10800 1 CLST}
+    {1463281200 -14400 0 CLT}
+    {1471147200 -10800 1 CLST}
+    {1494730800 -14400 0 CLT}
+    {1502596800 -10800 1 CLST}
+    {1526180400 -14400 0 CLT}
+    {1534046400 -10800 1 CLST}
+    {1557630000 -14400 0 CLT}
+    {1565496000 -10800 1 CLST}
+    {1589079600 -14400 0 CLT}
+    {1596945600 -10800 1 CLST}
+    {1620529200 -14400 0 CLT}
+    {1629000000 -10800 1 CLST}
+    {1652583600 -14400 0 CLT}
+    {1660449600 -10800 1 CLST}
+    {1684033200 -14400 0 CLT}
+    {1691899200 -10800 1 CLST}
+    {1715482800 -14400 0 CLT}
+    {1723348800 -10800 1 CLST}
+    {1746932400 -14400 0 CLT}
+    {1754798400 -10800 1 CLST}
+    {1778382000 -14400 0 CLT}
+    {1786248000 -10800 1 CLST}
+    {1809831600 -14400 0 CLT}
+    {1818302400 -10800 1 CLST}
+    {1841886000 -14400 0 CLT}
+    {1849752000 -10800 1 CLST}
+    {1873335600 -14400 0 CLT}
+    {1881201600 -10800 1 CLST}
+    {1904785200 -14400 0 CLT}
+    {1912651200 -10800 1 CLST}
+    {1936234800 -14400 0 CLT}
+    {1944100800 -10800 1 CLST}
+    {1967684400 -14400 0 CLT}
+    {1976155200 -10800 1 CLST}
+    {1999738800 -14400 0 CLT}
+    {2007604800 -10800 1 CLST}
+    {2031188400 -14400 0 CLT}
+    {2039054400 -10800 1 CLST}
+    {2062638000 -14400 0 CLT}
+    {2070504000 -10800 1 CLST}
+    {2094087600 -14400 0 CLT}
+    {2101953600 -10800 1 CLST}
+    {2125537200 -14400 0 CLT}
+    {2133403200 -10800 1 CLST}
+    {2156986800 -14400 0 CLT}
+    {2165457600 -10800 1 CLST}
+    {2189041200 -14400 0 CLT}
+    {2196907200 -10800 1 CLST}
+    {2220490800 -14400 0 CLT}
+    {2228356800 -10800 1 CLST}
+    {2251940400 -14400 0 CLT}
+    {2259806400 -10800 1 CLST}
+    {2283390000 -14400 0 CLT}
+    {2291256000 -10800 1 CLST}
+    {2314839600 -14400 0 CLT}
+    {2322705600 -10800 1 CLST}
+    {2346894000 -14400 0 CLT}
+    {2354760000 -10800 1 CLST}
+    {2378343600 -14400 0 CLT}
+    {2386209600 -10800 1 CLST}
+    {2409793200 -14400 0 CLT}
+    {2417659200 -10800 1 CLST}
+    {2441242800 -14400 0 CLT}
+    {2449108800 -10800 1 CLST}
+    {2472692400 -14400 0 CLT}
+    {2480558400 -10800 1 CLST}
+    {2504142000 -14400 0 CLT}
+    {2512612800 -10800 1 CLST}
+    {2536196400 -14400 0 CLT}
+    {2544062400 -10800 1 CLST}
+    {2567646000 -14400 0 CLT}
+    {2575512000 -10800 1 CLST}
+    {2599095600 -14400 0 CLT}
+    {2606961600 -10800 1 CLST}
+    {2630545200 -14400 0 CLT}
+    {2638411200 -10800 1 CLST}
+    {2661994800 -14400 0 CLT}
+    {2669860800 -10800 1 CLST}
+    {2693444400 -14400 0 CLT}
+    {2701915200 -10800 1 CLST}
+    {2725498800 -14400 0 CLT}
+    {2733364800 -10800 1 CLST}
+    {2756948400 -14400 0 CLT}
+    {2764814400 -10800 1 CLST}
+    {2788398000 -14400 0 CLT}
+    {2796264000 -10800 1 CLST}
+    {2819847600 -14400 0 CLT}
+    {2827713600 -10800 1 CLST}
+    {2851297200 -14400 0 CLT}
+    {2859768000 -10800 1 CLST}
+    {2883351600 -14400 0 CLT}
+    {2891217600 -10800 1 CLST}
+    {2914801200 -14400 0 CLT}
+    {2922667200 -10800 1 CLST}
+    {2946250800 -14400 0 CLT}
+    {2954116800 -10800 1 CLST}
+    {2977700400 -14400 0 CLT}
+    {2985566400 -10800 1 CLST}
+    {3009150000 -14400 0 CLT}
+    {3017016000 -10800 1 CLST}
+    {3040599600 -14400 0 CLT}
+    {3049070400 -10800 1 CLST}
+    {3072654000 -14400 0 CLT}
+    {3080520000 -10800 1 CLST}
+    {3104103600 -14400 0 CLT}
+    {3111969600 -10800 1 CLST}
+    {3135553200 -14400 0 CLT}
+    {3143419200 -10800 1 CLST}
+    {3167002800 -14400 0 CLT}
+    {3174868800 -10800 1 CLST}
+    {3198452400 -14400 0 CLT}
+    {3206318400 -10800 1 CLST}
+    {3230506800 -14400 0 CLT}
+    {3238372800 -10800 1 CLST}
+    {3261956400 -14400 0 CLT}
+    {3269822400 -10800 1 CLST}
+    {3293406000 -14400 0 CLT}
+    {3301272000 -10800 1 CLST}
+    {3324855600 -14400 0 CLT}
+    {3332721600 -10800 1 CLST}
+    {3356305200 -14400 0 CLT}
+    {3364171200 -10800 1 CLST}
+    {3387754800 -14400 0 CLT}
+    {3396225600 -10800 1 CLST}
+    {3419809200 -14400 0 CLT}
+    {3427675200 -10800 1 CLST}
+    {3451258800 -14400 0 CLT}
+    {3459124800 -10800 1 CLST}
+    {3482708400 -14400 0 CLT}
+    {3490574400 -10800 1 CLST}
+    {3514158000 -14400 0 CLT}
+    {3522024000 -10800 1 CLST}
+    {3545607600 -14400 0 CLT}
+    {3553473600 -10800 1 CLST}
+    {3577057200 -14400 0 CLT}
+    {3585528000 -10800 1 CLST}
+    {3609111600 -14400 0 CLT}
+    {3616977600 -10800 1 CLST}
+    {3640561200 -14400 0 CLT}
+    {3648427200 -10800 1 CLST}
+    {3672010800 -14400 0 CLT}
+    {3679876800 -10800 1 CLST}
+    {3703460400 -14400 0 CLT}
+    {3711326400 -10800 1 CLST}
+    {3734910000 -14400 0 CLT}
+    {3743380800 -10800 1 CLST}
+    {3766964400 -14400 0 CLT}
+    {3774830400 -10800 1 CLST}
+    {3798414000 -14400 0 CLT}
+    {3806280000 -10800 1 CLST}
+    {3829863600 -14400 0 CLT}
+    {3837729600 -10800 1 CLST}
+    {3861313200 -14400 0 CLT}
+    {3869179200 -10800 1 CLST}
+    {3892762800 -14400 0 CLT}
+    {3900628800 -10800 1 CLST}
+    {3924212400 -14400 0 CLT}
+    {3932683200 -10800 1 CLST}
+    {3956266800 -14400 0 CLT}
+    {3964132800 -10800 1 CLST}
+    {3987716400 -14400 0 CLT}
+    {3995582400 -10800 1 CLST}
+    {4019166000 -14400 0 CLT}
+    {4027032000 -10800 1 CLST}
+    {4050615600 -14400 0 CLT}
+    {4058481600 -10800 1 CLST}
+    {4082065200 -14400 0 CLT}
+    {4089931200 -10800 1 CLST}
+}
diff --git a/library/tzdata/Antarctica/Rothera b/library/tzdata/Antarctica/Rothera
new file mode 100644
index 0000000..3a219c7
--- /dev/null
+++ b/library/tzdata/Antarctica/Rothera
@@ -0,0 +1,6 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Antarctica/Rothera) {
+    {-9223372036854775808 0 0 -00}
+    {218246400 -10800 0 ROTT}
+}
diff --git a/library/tzdata/Antarctica/South_Pole b/library/tzdata/Antarctica/South_Pole
new file mode 100644
index 0000000..544bde4
--- /dev/null
+++ b/library/tzdata/Antarctica/South_Pole
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Pacific/Auckland)]} {
+    LoadTimeZoneFile Pacific/Auckland
+}
+set TZData(:Antarctica/South_Pole) $TZData(:Pacific/Auckland)
diff --git a/library/tzdata/Antarctica/Syowa b/library/tzdata/Antarctica/Syowa
new file mode 100644
index 0000000..1fe030a
--- /dev/null
+++ b/library/tzdata/Antarctica/Syowa
@@ -0,0 +1,6 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Antarctica/Syowa) {
+    {-9223372036854775808 0 0 -00}
+    {-407808000 10800 0 SYOT}
+}
diff --git a/library/tzdata/Antarctica/Troll b/library/tzdata/Antarctica/Troll
new file mode 100644
index 0000000..09727a8
--- /dev/null
+++ b/library/tzdata/Antarctica/Troll
@@ -0,0 +1,196 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Antarctica/Troll) {
+    {-9223372036854775808 0 0 -00}
+    {1108166400 0 0 UTC}
+    {1111885200 7200 1 CEST}
+    {1130634000 0 0 UTC}
+    {1143334800 7200 1 CEST}
+    {1162083600 0 0 UTC}
+    {1174784400 7200 1 CEST}
+    {1193533200 0 0 UTC}
+    {1206838800 7200 1 CEST}
+    {1224982800 0 0 UTC}
+    {1238288400 7200 1 CEST}
+    {1256432400 0 0 UTC}
+    {1269738000 7200 1 CEST}
+    {1288486800 0 0 UTC}
+    {1301187600 7200 1 CEST}
+    {1319936400 0 0 UTC}
+    {1332637200 7200 1 CEST}
+    {1351386000 0 0 UTC}
+    {1364691600 7200 1 CEST}
+    {1382835600 0 0 UTC}
+    {1396141200 7200 1 CEST}
+    {1414285200 0 0 UTC}
+    {1427590800 7200 1 CEST}
+    {1445734800 0 0 UTC}
+    {1459040400 7200 1 CEST}
+    {1477789200 0 0 UTC}
+    {1490490000 7200 1 CEST}
+    {1509238800 0 0 UTC}
+    {1521939600 7200 1 CEST}
+    {1540688400 0 0 UTC}
+    {1553994000 7200 1 CEST}
+    {1572138000 0 0 UTC}
+    {1585443600 7200 1 CEST}
+    {1603587600 0 0 UTC}
+    {1616893200 7200 1 CEST}
+    {1635642000 0 0 UTC}
+    {1648342800 7200 1 CEST}
+    {1667091600 0 0 UTC}
+    {1679792400 7200 1 CEST}
+    {1698541200 0 0 UTC}
+    {1711846800 7200 1 CEST}
+    {1729990800 0 0 UTC}
+    {1743296400 7200 1 CEST}
+    {1761440400 0 0 UTC}
+    {1774746000 7200 1 CEST}
+    {1792890000 0 0 UTC}
+    {1806195600 7200 1 CEST}
+    {1824944400 0 0 UTC}
+    {1837645200 7200 1 CEST}
+    {1856394000 0 0 UTC}
+    {1869094800 7200 1 CEST}
+    {1887843600 0 0 UTC}
+    {1901149200 7200 1 CEST}
+    {1919293200 0 0 UTC}
+    {1932598800 7200 1 CEST}
+    {1950742800 0 0 UTC}
+    {1964048400 7200 1 CEST}
+    {1982797200 0 0 UTC}
+    {1995498000 7200 1 CEST}
+    {2014246800 0 0 UTC}
+    {2026947600 7200 1 CEST}
+    {2045696400 0 0 UTC}
+    {2058397200 7200 1 CEST}
+    {2077146000 0 0 UTC}
+    {2090451600 7200 1 CEST}
+    {2108595600 0 0 UTC}
+    {2121901200 7200 1 CEST}
+    {2140045200 0 0 UTC}
+    {2153350800 7200 1 CEST}
+    {2172099600 0 0 UTC}
+    {2184800400 7200 1 CEST}
+    {2203549200 0 0 UTC}
+    {2216250000 7200 1 CEST}
+    {2234998800 0 0 UTC}
+    {2248304400 7200 1 CEST}
+    {2266448400 0 0 UTC}
+    {2279754000 7200 1 CEST}
+    {2297898000 0 0 UTC}
+    {2311203600 7200 1 CEST}
+    {2329347600 0 0 UTC}
+    {2342653200 7200 1 CEST}
+    {2361402000 0 0 UTC}
+    {2374102800 7200 1 CEST}
+    {2392851600 0 0 UTC}
+    {2405552400 7200 1 CEST}
+    {2424301200 0 0 UTC}
+    {2437606800 7200 1 CEST}
+    {2455750800 0 0 UTC}
+    {2469056400 7200 1 CEST}
+    {2487200400 0 0 UTC}
+    {2500506000 7200 1 CEST}
+    {2519254800 0 0 UTC}
+    {2531955600 7200 1 CEST}
+    {2550704400 0 0 UTC}
+    {2563405200 7200 1 CEST}
+    {2582154000 0 0 UTC}
+    {2595459600 7200 1 CEST}
+    {2613603600 0 0 UTC}
+    {2626909200 7200 1 CEST}
+    {2645053200 0 0 UTC}
+    {2658358800 7200 1 CEST}
+    {2676502800 0 0 UTC}
+    {2689808400 7200 1 CEST}
+    {2708557200 0 0 UTC}
+    {2721258000 7200 1 CEST}
+    {2740006800 0 0 UTC}
+    {2752707600 7200 1 CEST}
+    {2771456400 0 0 UTC}
+    {2784762000 7200 1 CEST}
+    {2802906000 0 0 UTC}
+    {2816211600 7200 1 CEST}
+    {2834355600 0 0 UTC}
+    {2847661200 7200 1 CEST}
+    {2866410000 0 0 UTC}
+    {2879110800 7200 1 CEST}
+    {2897859600 0 0 UTC}
+    {2910560400 7200 1 CEST}
+    {2929309200 0 0 UTC}
+    {2942010000 7200 1 CEST}
+    {2960758800 0 0 UTC}
+    {2974064400 7200 1 CEST}
+    {2992208400 0 0 UTC}
+    {3005514000 7200 1 CEST}
+    {3023658000 0 0 UTC}
+    {3036963600 7200 1 CEST}
+    {3055712400 0 0 UTC}
+    {3068413200 7200 1 CEST}
+    {3087162000 0 0 UTC}
+    {3099862800 7200 1 CEST}
+    {3118611600 0 0 UTC}
+    {3131917200 7200 1 CEST}
+    {3150061200 0 0 UTC}
+    {3163366800 7200 1 CEST}
+    {3181510800 0 0 UTC}
+    {3194816400 7200 1 CEST}
+    {3212960400 0 0 UTC}
+    {3226266000 7200 1 CEST}
+    {3245014800 0 0 UTC}
+    {3257715600 7200 1 CEST}
+    {3276464400 0 0 UTC}
+    {3289165200 7200 1 CEST}
+    {3307914000 0 0 UTC}
+    {3321219600 7200 1 CEST}
+    {3339363600 0 0 UTC}
+    {3352669200 7200 1 CEST}
+    {3370813200 0 0 UTC}
+    {3384118800 7200 1 CEST}
+    {3402867600 0 0 UTC}
+    {3415568400 7200 1 CEST}
+    {3434317200 0 0 UTC}
+    {3447018000 7200 1 CEST}
+    {3465766800 0 0 UTC}
+    {3479072400 7200 1 CEST}
+    {3497216400 0 0 UTC}
+    {3510522000 7200 1 CEST}
+    {3528666000 0 0 UTC}
+    {3541971600 7200 1 CEST}
+    {3560115600 0 0 UTC}
+    {3573421200 7200 1 CEST}
+    {3592170000 0 0 UTC}
+    {3604870800 7200 1 CEST}
+    {3623619600 0 0 UTC}
+    {3636320400 7200 1 CEST}
+    {3655069200 0 0 UTC}
+    {3668374800 7200 1 CEST}
+    {3686518800 0 0 UTC}
+    {3699824400 7200 1 CEST}
+    {3717968400 0 0 UTC}
+    {3731274000 7200 1 CEST}
+    {3750022800 0 0 UTC}
+    {3762723600 7200 1 CEST}
+    {3781472400 0 0 UTC}
+    {3794173200 7200 1 CEST}
+    {3812922000 0 0 UTC}
+    {3825622800 7200 1 CEST}
+    {3844371600 0 0 UTC}
+    {3857677200 7200 1 CEST}
+    {3875821200 0 0 UTC}
+    {3889126800 7200 1 CEST}
+    {3907270800 0 0 UTC}
+    {3920576400 7200 1 CEST}
+    {3939325200 0 0 UTC}
+    {3952026000 7200 1 CEST}
+    {3970774800 0 0 UTC}
+    {3983475600 7200 1 CEST}
+    {4002224400 0 0 UTC}
+    {4015530000 7200 1 CEST}
+    {4033674000 0 0 UTC}
+    {4046979600 7200 1 CEST}
+    {4065123600 0 0 UTC}
+    {4078429200 7200 1 CEST}
+    {4096573200 0 0 UTC}
+}
diff --git a/library/tzdata/Antarctica/Vostok b/library/tzdata/Antarctica/Vostok
new file mode 100644
index 0000000..a59868b
--- /dev/null
+++ b/library/tzdata/Antarctica/Vostok
@@ -0,0 +1,6 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Antarctica/Vostok) {
+    {-9223372036854775808 0 0 -00}
+    {-380073600 21600 0 VOST}
+}
diff --git a/library/tzdata/Arctic/Longyearbyen b/library/tzdata/Arctic/Longyearbyen
new file mode 100644
index 0000000..51f83dc
--- /dev/null
+++ b/library/tzdata/Arctic/Longyearbyen
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Europe/Oslo)]} {
+    LoadTimeZoneFile Europe/Oslo
+}
+set TZData(:Arctic/Longyearbyen) $TZData(:Europe/Oslo)
diff --git a/library/tzdata/Asia/Aden b/library/tzdata/Asia/Aden
new file mode 100644
index 0000000..5c5515e
--- /dev/null
+++ b/library/tzdata/Asia/Aden
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Asia/Riyadh)]} {
+    LoadTimeZoneFile Asia/Riyadh
+}
+set TZData(:Asia/Aden) $TZData(:Asia/Riyadh)
diff --git a/library/tzdata/Asia/Almaty b/library/tzdata/Asia/Almaty
new file mode 100644
index 0000000..2b83197
--- /dev/null
+++ b/library/tzdata/Asia/Almaty
@@ -0,0 +1,57 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Asia/Almaty) {
+    {-9223372036854775808 18468 0 LMT}
+    {-1441170468 18000 0 +05}
+    {-1247547600 21600 0 +06}
+    {354909600 25200 1 +07}
+    {370717200 21600 0 +06}
+    {386445600 25200 1 +07}
+    {402253200 21600 0 +06}
+    {417981600 25200 1 +07}
+    {433789200 21600 0 +06}
+    {449604000 25200 1 +07}
+    {465336000 21600 0 +06}
+    {481060800 25200 1 +07}
+    {496785600 21600 0 +06}
+    {512510400 25200 1 +07}
+    {528235200 21600 0 +06}
+    {543960000 25200 1 +07}
+    {559684800 21600 0 +06}
+    {575409600 25200 1 +07}
+    {591134400 21600 0 +06}
+    {606859200 25200 1 +07}
+    {622584000 21600 0 +06}
+    {638308800 25200 1 +07}
+    {654638400 21600 0 +06}
+    {670363200 18000 0 +05}
+    {670366800 21600 1 +06}
+    {686091600 18000 0 +05}
+    {695768400 21600 0 +06}
+    {701812800 25200 1 +07}
+    {717537600 21600 0 +06}
+    {733262400 25200 1 +07}
+    {748987200 21600 0 +06}
+    {764712000 25200 1 +07}
+    {780436800 21600 0 +06}
+    {796161600 25200 1 +07}
+    {811886400 21600 0 +06}
+    {828216000 25200 1 +07}
+    {846360000 21600 0 +06}
+    {859665600 25200 1 +07}
+    {877809600 21600 0 +06}
+    {891115200 25200 1 +07}
+    {909259200 21600 0 +06}
+    {922564800 25200 1 +07}
+    {941313600 21600 0 +06}
+    {954014400 25200 1 +07}
+    {972763200 21600 0 +06}
+    {985464000 25200 1 +07}
+    {1004212800 21600 0 +06}
+    {1017518400 25200 1 +07}
+    {1035662400 21600 0 +06}
+    {1048968000 25200 1 +07}
+    {1067112000 21600 0 +06}
+    {1080417600 25200 1 +07}
+    {1099166400 21600 0 +06}
+}
diff --git a/library/tzdata/Asia/Amman b/library/tzdata/Asia/Amman
new file mode 100644
index 0000000..c2f6904
--- /dev/null
+++ b/library/tzdata/Asia/Amman
@@ -0,0 +1,246 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Asia/Amman) {
+    {-9223372036854775808 8624 0 LMT}
+    {-1230776624 7200 0 EET}
+    {108165600 10800 1 EEST}
+    {118270800 7200 0 EET}
+    {136591200 10800 1 EEST}
+    {149806800 7200 0 EET}
+    {168127200 10800 1 EEST}
+    {181342800 7200 0 EET}
+    {199749600 10800 1 EEST}
+    {215643600 7200 0 EET}
+    {231285600 10800 1 EEST}
+    {244501200 7200 0 EET}
+    {262735200 10800 1 EEST}
+    {275950800 7200 0 EET}
+    {481154400 10800 1 EEST}
+    {496962000 7200 0 EET}
+    {512949600 10800 1 EEST}
+    {528670800 7200 0 EET}
+    {544399200 10800 1 EEST}
+    {560120400 7200 0 EET}
+    {575848800 10800 1 EEST}
+    {592174800 7200 0 EET}
+    {610581600 10800 1 EEST}
+    {623624400 7200 0 EET}
+    {641167200 10800 1 EEST}
+    {655074000 7200 0 EET}
+    {671839200 10800 1 EEST}
+    {685918800 7200 0 EET}
+    {702856800 10800 1 EEST}
+    {717973200 7200 0 EET}
+    {733701600 10800 1 EEST}
+    {749422800 7200 0 EET}
+    {765151200 10800 1 EEST}
+    {779662800 7200 0 EET}
+    {797205600 10800 1 EEST}
+    {811116000 7200 0 EET}
+    {828655200 10800 1 EEST}
+    {843170400 7200 0 EET}
+    {860104800 10800 1 EEST}
+    {874620000 7200 0 EET}
+    {891554400 10800 1 EEST}
+    {906069600 7200 0 EET}
+    {930780000 10800 1 EEST}
+    {938124000 7200 0 EET}
+    {954367200 10800 1 EEST}
+    {970178400 7200 0 EET}
+    {985816800 10800 1 EEST}
+    {1001628000 7200 0 EET}
+    {1017352800 10800 1 EEST}
+    {1033077600 7200 0 EET}
+    {1048802400 10800 1 EEST}
+    {1066946400 7200 0 EET}
+    {1080252000 10800 1 EEST}
+    {1097791200 7200 0 EET}
+    {1112306400 10800 1 EEST}
+    {1128031200 7200 0 EET}
+    {1143756000 10800 1 EEST}
+    {1161900000 7200 0 EET}
+    {1175205600 10800 1 EEST}
+    {1193349600 7200 0 EET}
+    {1206655200 10800 1 EEST}
+    {1225404000 7200 0 EET}
+    {1238104800 10800 1 EEST}
+    {1256853600 7200 0 EET}
+    {1269554400 10800 1 EEST}
+    {1288303200 7200 0 EET}
+    {1301608800 10800 1 EEST}
+    {1319752800 7200 0 EET}
+    {1333058400 10800 1 EEST}
+    {1387486800 7200 0 EET}
+    {1395957600 10800 1 EEST}
+    {1414706400 7200 0 EET}
+    {1427407200 10800 1 EEST}
+    {1446156000 7200 0 EET}
+    {1459461600 10800 1 EEST}
+    {1477605600 7200 0 EET}
+    {1490911200 10800 1 EEST}
+    {1509055200 7200 0 EET}
+    {1522360800 10800 1 EEST}
+    {1540504800 7200 0 EET}
+    {1553810400 10800 1 EEST}
+    {1571954400 7200 0 EET}
+    {1585260000 10800 1 EEST}
+    {1604008800 7200 0 EET}
+    {1616709600 10800 1 EEST}
+    {1635458400 7200 0 EET}
+    {1648764000 10800 1 EEST}
+    {1666908000 7200 0 EET}
+    {1680213600 10800 1 EEST}
+    {1698357600 7200 0 EET}
+    {1711663200 10800 1 EEST}
+    {1729807200 7200 0 EET}
+    {1743112800 10800 1 EEST}
+    {1761861600 7200 0 EET}
+    {1774562400 10800 1 EEST}
+    {1793311200 7200 0 EET}
+    {1806012000 10800 1 EEST}
+    {1824760800 7200 0 EET}
+    {1838066400 10800 1 EEST}
+    {1856210400 7200 0 EET}
+    {1869516000 10800 1 EEST}
+    {1887660000 7200 0 EET}
+    {1900965600 10800 1 EEST}
+    {1919109600 7200 0 EET}
+    {1932415200 10800 1 EEST}
+    {1951164000 7200 0 EET}
+    {1963864800 10800 1 EEST}
+    {1982613600 7200 0 EET}
+    {1995919200 10800 1 EEST}
+    {2014063200 7200 0 EET}
+    {2027368800 10800 1 EEST}
+    {2045512800 7200 0 EET}
+    {2058818400 10800 1 EEST}
+    {2076962400 7200 0 EET}
+    {2090268000 10800 1 EEST}
+    {2109016800 7200 0 EET}
+    {2121717600 10800 1 EEST}
+    {2140466400 7200 0 EET}
+    {2153167200 10800 1 EEST}
+    {2171916000 7200 0 EET}
+    {2185221600 10800 1 EEST}
+    {2203365600 7200 0 EET}
+    {2216671200 10800 1 EEST}
+    {2234815200 7200 0 EET}
+    {2248120800 10800 1 EEST}
+    {2266264800 7200 0 EET}
+    {2279570400 10800 1 EEST}
+    {2298319200 7200 0 EET}
+    {2311020000 10800 1 EEST}
+    {2329768800 7200 0 EET}
+    {2343074400 10800 1 EEST}
+    {2361218400 7200 0 EET}
+    {2374524000 10800 1 EEST}
+    {2392668000 7200 0 EET}
+    {2405973600 10800 1 EEST}
+    {2424117600 7200 0 EET}
+    {2437423200 10800 1 EEST}
+    {2455567200 7200 0 EET}
+    {2468872800 10800 1 EEST}
+    {2487621600 7200 0 EET}
+    {2500322400 10800 1 EEST}
+    {2519071200 7200 0 EET}
+    {2532376800 10800 1 EEST}
+    {2550520800 7200 0 EET}
+    {2563826400 10800 1 EEST}
+    {2581970400 7200 0 EET}
+    {2595276000 10800 1 EEST}
+    {2613420000 7200 0 EET}
+    {2626725600 10800 1 EEST}
+    {2645474400 7200 0 EET}
+    {2658175200 10800 1 EEST}
+    {2676924000 7200 0 EET}
+    {2689624800 10800 1 EEST}
+    {2708373600 7200 0 EET}
+    {2721679200 10800 1 EEST}
+    {2739823200 7200 0 EET}
+    {2753128800 10800 1 EEST}
+    {2771272800 7200 0 EET}
+    {2784578400 10800 1 EEST}
+    {2802722400 7200 0 EET}
+    {2816028000 10800 1 EEST}
+    {2834776800 7200 0 EET}
+    {2847477600 10800 1 EEST}
+    {2866226400 7200 0 EET}
+    {2879532000 10800 1 EEST}
+    {2897676000 7200 0 EET}
+    {2910981600 10800 1 EEST}
+    {2929125600 7200 0 EET}
+    {2942431200 10800 1 EEST}
+    {2960575200 7200 0 EET}
+    {2973880800 10800 1 EEST}
+    {2992629600 7200 0 EET}
+    {3005330400 10800 1 EEST}
+    {3024079200 7200 0 EET}
+    {3036780000 10800 1 EEST}
+    {3055528800 7200 0 EET}
+    {3068834400 10800 1 EEST}
+    {3086978400 7200 0 EET}
+    {3100284000 10800 1 EEST}
+    {3118428000 7200 0 EET}
+    {3131733600 10800 1 EEST}
+    {3149877600 7200 0 EET}
+    {3163183200 10800 1 EEST}
+    {3181932000 7200 0 EET}
+    {3194632800 10800 1 EEST}
+    {3213381600 7200 0 EET}
+    {3226687200 10800 1 EEST}
+    {3244831200 7200 0 EET}
+    {3258136800 10800 1 EEST}
+    {3276280800 7200 0 EET}
+    {3289586400 10800 1 EEST}
+    {3307730400 7200 0 EET}
+    {3321036000 10800 1 EEST}
+    {3339180000 7200 0 EET}
+    {3352485600 10800 1 EEST}
+    {3371234400 7200 0 EET}
+    {3383935200 10800 1 EEST}
+    {3402684000 7200 0 EET}
+    {3415989600 10800 1 EEST}
+    {3434133600 7200 0 EET}
+    {3447439200 10800 1 EEST}
+    {3465583200 7200 0 EET}
+    {3478888800 10800 1 EEST}
+    {3497032800 7200 0 EET}
+    {3510338400 10800 1 EEST}
+    {3529087200 7200 0 EET}
+    {3541788000 10800 1 EEST}
+    {3560536800 7200 0 EET}
+    {3573237600 10800 1 EEST}
+    {3591986400 7200 0 EET}
+    {3605292000 10800 1 EEST}
+    {3623436000 7200 0 EET}
+    {3636741600 10800 1 EEST}
+    {3654885600 7200 0 EET}
+    {3668191200 10800 1 EEST}
+    {3686335200 7200 0 EET}
+    {3699640800 10800 1 EEST}
+    {3718389600 7200 0 EET}
+    {3731090400 10800 1 EEST}
+    {3749839200 7200 0 EET}
+    {3763144800 10800 1 EEST}
+    {3781288800 7200 0 EET}
+    {3794594400 10800 1 EEST}
+    {3812738400 7200 0 EET}
+    {3826044000 10800 1 EEST}
+    {3844188000 7200 0 EET}
+    {3857493600 10800 1 EEST}
+    {3876242400 7200 0 EET}
+    {3888943200 10800 1 EEST}
+    {3907692000 7200 0 EET}
+    {3920392800 10800 1 EEST}
+    {3939141600 7200 0 EET}
+    {3952447200 10800 1 EEST}
+    {3970591200 7200 0 EET}
+    {3983896800 10800 1 EEST}
+    {4002040800 7200 0 EET}
+    {4015346400 10800 1 EEST}
+    {4033490400 7200 0 EET}
+    {4046796000 10800 1 EEST}
+    {4065544800 7200 0 EET}
+    {4078245600 10800 1 EEST}
+    {4096994400 7200 0 EET}
+}
diff --git a/library/tzdata/Asia/Anadyr b/library/tzdata/Asia/Anadyr
new file mode 100644
index 0000000..2e8ffc7
--- /dev/null
+++ b/library/tzdata/Asia/Anadyr
@@ -0,0 +1,72 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Asia/Anadyr) {
+    {-9223372036854775808 42596 0 LMT}
+    {-1441194596 43200 0 ANAT}
+    {-1247572800 46800 0 ANAMMTT}
+    {354884400 50400 1 ANAST}
+    {370692000 46800 0 ANAT}
+    {386420400 43200 0 ANAMMTT}
+    {386424000 46800 1 ANAST}
+    {402231600 43200 0 ANAT}
+    {417960000 46800 1 ANAST}
+    {433767600 43200 0 ANAT}
+    {449582400 46800 1 ANAST}
+    {465314400 43200 0 ANAT}
+    {481039200 46800 1 ANAST}
+    {496764000 43200 0 ANAT}
+    {512488800 46800 1 ANAST}
+    {528213600 43200 0 ANAT}
+    {543938400 46800 1 ANAST}
+    {559663200 43200 0 ANAT}
+    {575388000 46800 1 ANAST}
+    {591112800 43200 0 ANAT}
+    {606837600 46800 1 ANAST}
+    {622562400 43200 0 ANAT}
+    {638287200 46800 1 ANAST}
+    {654616800 43200 0 ANAT}
+    {670341600 39600 0 ANAMMTT}
+    {670345200 43200 1 ANAST}
+    {686070000 39600 0 ANAT}
+    {695746800 43200 0 ANAMMTT}
+    {701791200 46800 1 ANAST}
+    {717516000 43200 0 ANAT}
+    {733240800 46800 1 ANAST}
+    {748965600 43200 0 ANAT}
+    {764690400 46800 1 ANAST}
+    {780415200 43200 0 ANAT}
+    {796140000 46800 1 ANAST}
+    {811864800 43200 0 ANAT}
+    {828194400 46800 1 ANAST}
+    {846338400 43200 0 ANAT}
+    {859644000 46800 1 ANAST}
+    {877788000 43200 0 ANAT}
+    {891093600 46800 1 ANAST}
+    {909237600 43200 0 ANAT}
+    {922543200 46800 1 ANAST}
+    {941292000 43200 0 ANAT}
+    {953992800 46800 1 ANAST}
+    {972741600 43200 0 ANAT}
+    {985442400 46800 1 ANAST}
+    {1004191200 43200 0 ANAT}
+    {1017496800 46800 1 ANAST}
+    {1035640800 43200 0 ANAT}
+    {1048946400 46800 1 ANAST}
+    {1067090400 43200 0 ANAT}
+    {1080396000 46800 1 ANAST}
+    {1099144800 43200 0 ANAT}
+    {1111845600 46800 1 ANAST}
+    {1130594400 43200 0 ANAT}
+    {1143295200 46800 1 ANAST}
+    {1162044000 43200 0 ANAT}
+    {1174744800 46800 1 ANAST}
+    {1193493600 43200 0 ANAT}
+    {1206799200 46800 1 ANAST}
+    {1224943200 43200 0 ANAT}
+    {1238248800 46800 1 ANAST}
+    {1256392800 43200 0 ANAT}
+    {1269698400 39600 0 ANAMMTT}
+    {1269702000 43200 1 ANAST}
+    {1288450800 39600 0 ANAT}
+    {1301151600 43200 0 ANAT}
+}
diff --git a/library/tzdata/Asia/Aqtau b/library/tzdata/Asia/Aqtau
new file mode 100644
index 0000000..90cc94d
--- /dev/null
+++ b/library/tzdata/Asia/Aqtau
@@ -0,0 +1,59 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Asia/Aqtau) {
+    {-9223372036854775808 12064 0 LMT}
+    {-1441164064 14400 0 +04}
+    {-1247544000 18000 0 +05}
+    {-220942800 18000 0 +05}
+    {370724400 21600 0 +06}
+    {386445600 18000 0 +05}
+    {386449200 21600 1 +06}
+    {402256800 18000 0 +05}
+    {417985200 21600 1 +06}
+    {433792800 18000 0 +05}
+    {449607600 21600 1 +06}
+    {465339600 18000 0 +05}
+    {481064400 21600 1 +06}
+    {496789200 18000 0 +05}
+    {512514000 21600 1 +06}
+    {528238800 18000 0 +05}
+    {543963600 21600 1 +06}
+    {559688400 18000 0 +05}
+    {575413200 21600 1 +06}
+    {591138000 18000 0 +05}
+    {606862800 21600 1 +06}
+    {622587600 18000 0 +05}
+    {638312400 21600 1 +06}
+    {654642000 18000 0 +05}
+    {670366800 14400 0 +04}
+    {670370400 18000 1 +05}
+    {686095200 14400 0 +04}
+    {695772000 18000 0 +05}
+    {701816400 21600 1 +06}
+    {717541200 18000 0 +05}
+    {733266000 21600 1 +06}
+    {748990800 18000 0 +05}
+    {764715600 21600 1 +06}
+    {780440400 18000 0 +05}
+    {780444000 14400 0 +04}
+    {796168800 18000 1 +05}
+    {811893600 14400 0 +04}
+    {828223200 18000 1 +05}
+    {846367200 14400 0 +04}
+    {859672800 18000 1 +05}
+    {877816800 14400 0 +04}
+    {891122400 18000 1 +05}
+    {909266400 14400 0 +04}
+    {922572000 18000 1 +05}
+    {941320800 14400 0 +04}
+    {954021600 18000 1 +05}
+    {972770400 14400 0 +04}
+    {985471200 18000 1 +05}
+    {1004220000 14400 0 +04}
+    {1017525600 18000 1 +05}
+    {1035669600 14400 0 +04}
+    {1048975200 18000 1 +05}
+    {1067119200 14400 0 +04}
+    {1080424800 18000 1 +05}
+    {1099173600 18000 0 +05}
+}
diff --git a/library/tzdata/Asia/Aqtobe b/library/tzdata/Asia/Aqtobe
new file mode 100644
index 0000000..55ef556
--- /dev/null
+++ b/library/tzdata/Asia/Aqtobe
@@ -0,0 +1,58 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Asia/Aqtobe) {
+    {-9223372036854775808 13720 0 LMT}
+    {-1441165720 14400 0 +04}
+    {-1247544000 18000 0 +05}
+    {354913200 21600 1 +06}
+    {370720800 21600 0 +06}
+    {386445600 18000 0 +05}
+    {386449200 21600 1 +06}
+    {402256800 18000 0 +05}
+    {417985200 21600 1 +06}
+    {433792800 18000 0 +05}
+    {449607600 21600 1 +06}
+    {465339600 18000 0 +05}
+    {481064400 21600 1 +06}
+    {496789200 18000 0 +05}
+    {512514000 21600 1 +06}
+    {528238800 18000 0 +05}
+    {543963600 21600 1 +06}
+    {559688400 18000 0 +05}
+    {575413200 21600 1 +06}
+    {591138000 18000 0 +05}
+    {606862800 21600 1 +06}
+    {622587600 18000 0 +05}
+    {638312400 21600 1 +06}
+    {654642000 18000 0 +05}
+    {670366800 14400 0 +04}
+    {670370400 18000 1 +05}
+    {686095200 14400 0 +04}
+    {695772000 18000 0 +05}
+    {701816400 21600 1 +06}
+    {717541200 18000 0 +05}
+    {733266000 21600 1 +06}
+    {748990800 18000 0 +05}
+    {764715600 21600 1 +06}
+    {780440400 18000 0 +05}
+    {796165200 21600 1 +06}
+    {811890000 18000 0 +05}
+    {828219600 21600 1 +06}
+    {846363600 18000 0 +05}
+    {859669200 21600 1 +06}
+    {877813200 18000 0 +05}
+    {891118800 21600 1 +06}
+    {909262800 18000 0 +05}
+    {922568400 21600 1 +06}
+    {941317200 18000 0 +05}
+    {954018000 21600 1 +06}
+    {972766800 18000 0 +05}
+    {985467600 21600 1 +06}
+    {1004216400 18000 0 +05}
+    {1017522000 21600 1 +06}
+    {1035666000 18000 0 +05}
+    {1048971600 21600 1 +06}
+    {1067115600 18000 0 +05}
+    {1080421200 21600 1 +06}
+    {1099170000 18000 0 +05}
+}
diff --git a/library/tzdata/Asia/Ashgabat b/library/tzdata/Asia/Ashgabat
new file mode 100644
index 0000000..64bdb3a
--- /dev/null
+++ b/library/tzdata/Asia/Ashgabat
@@ -0,0 +1,31 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Asia/Ashgabat) {
+    {-9223372036854775808 14012 0 LMT}
+    {-1441166012 14400 0 ASHT}
+    {-1247544000 18000 0 ASHT}
+    {354913200 21600 1 ASHST}
+    {370720800 18000 0 ASHT}
+    {386449200 21600 1 ASHST}
+    {402256800 18000 0 ASHT}
+    {417985200 21600 1 ASHST}
+    {433792800 18000 0 ASHT}
+    {449607600 21600 1 ASHST}
+    {465339600 18000 0 ASHT}
+    {481064400 21600 1 ASHST}
+    {496789200 18000 0 ASHT}
+    {512514000 21600 1 ASHST}
+    {528238800 18000 0 ASHT}
+    {543963600 21600 1 ASHST}
+    {559688400 18000 0 ASHT}
+    {575413200 21600 1 ASHST}
+    {591138000 18000 0 ASHT}
+    {606862800 21600 1 ASHST}
+    {622587600 18000 0 ASHT}
+    {638312400 21600 1 ASHST}
+    {654642000 18000 0 ASHT}
+    {670366800 14400 0 ASHT}
+    {670370400 18000 1 ASHST}
+    {686095200 14400 0 ASHT}
+    {695772000 18000 0 TMT}
+}
diff --git a/library/tzdata/Asia/Ashkhabad b/library/tzdata/Asia/Ashkhabad
new file mode 100644
index 0000000..3000c94
--- /dev/null
+++ b/library/tzdata/Asia/Ashkhabad
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Asia/Ashgabat)]} {
+    LoadTimeZoneFile Asia/Ashgabat
+}
+set TZData(:Asia/Ashkhabad) $TZData(:Asia/Ashgabat)
diff --git a/library/tzdata/Asia/Baghdad b/library/tzdata/Asia/Baghdad
new file mode 100644
index 0000000..c1058cb
--- /dev/null
+++ b/library/tzdata/Asia/Baghdad
@@ -0,0 +1,59 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Asia/Baghdad) {
+    {-9223372036854775808 10660 0 LMT}
+    {-2524532260 10656 0 BMT}
+    {-1641005856 10800 0 AST}
+    {389048400 14400 0 ADT}
+    {402264000 10800 0 AST}
+    {417906000 14400 1 ADT}
+    {433800000 10800 0 AST}
+    {449614800 14400 1 ADT}
+    {465422400 10800 0 AST}
+    {481150800 14400 1 ADT}
+    {496792800 10800 0 AST}
+    {512517600 14400 1 ADT}
+    {528242400 10800 0 AST}
+    {543967200 14400 1 ADT}
+    {559692000 10800 0 AST}
+    {575416800 14400 1 ADT}
+    {591141600 10800 0 AST}
+    {606866400 14400 1 ADT}
+    {622591200 10800 0 AST}
+    {638316000 14400 1 ADT}
+    {654645600 10800 0 AST}
+    {670464000 14400 1 ADT}
+    {686275200 10800 0 AST}
+    {702086400 14400 1 ADT}
+    {717897600 10800 0 AST}
+    {733622400 14400 1 ADT}
+    {749433600 10800 0 AST}
+    {765158400 14400 1 ADT}
+    {780969600 10800 0 AST}
+    {796694400 14400 1 ADT}
+    {812505600 10800 0 AST}
+    {828316800 14400 1 ADT}
+    {844128000 10800 0 AST}
+    {859852800 14400 1 ADT}
+    {875664000 10800 0 AST}
+    {891388800 14400 1 ADT}
+    {907200000 10800 0 AST}
+    {922924800 14400 1 ADT}
+    {938736000 10800 0 AST}
+    {954547200 14400 1 ADT}
+    {970358400 10800 0 AST}
+    {986083200 14400 1 ADT}
+    {1001894400 10800 0 AST}
+    {1017619200 14400 1 ADT}
+    {1033430400 10800 0 AST}
+    {1049155200 14400 1 ADT}
+    {1064966400 10800 0 AST}
+    {1080777600 14400 1 ADT}
+    {1096588800 10800 0 AST}
+    {1112313600 14400 1 ADT}
+    {1128124800 10800 0 AST}
+    {1143849600 14400 1 ADT}
+    {1159660800 10800 0 AST}
+    {1175385600 14400 1 ADT}
+    {1191196800 10800 0 AST}
+}
diff --git a/library/tzdata/Asia/Bahrain b/library/tzdata/Asia/Bahrain
new file mode 100644
index 0000000..aab5b7d
--- /dev/null
+++ b/library/tzdata/Asia/Bahrain
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Asia/Qatar)]} {
+    LoadTimeZoneFile Asia/Qatar
+}
+set TZData(:Asia/Bahrain) $TZData(:Asia/Qatar)
diff --git a/library/tzdata/Asia/Baku b/library/tzdata/Asia/Baku
new file mode 100644
index 0000000..e9ee835
--- /dev/null
+++ b/library/tzdata/Asia/Baku
@@ -0,0 +1,74 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Asia/Baku) {
+    {-9223372036854775808 11964 0 LMT}
+    {-1441163964 10800 0 BAKT}
+    {-405140400 14400 0 BAKT}
+    {354916800 18000 1 BAKST}
+    {370724400 14400 0 BAKT}
+    {386452800 18000 1 BAKST}
+    {402260400 14400 0 BAKT}
+    {417988800 18000 1 BAKST}
+    {433796400 14400 0 BAKT}
+    {449611200 18000 1 BAKST}
+    {465343200 14400 0 BAKT}
+    {481068000 18000 1 BAKST}
+    {496792800 14400 0 BAKT}
+    {512517600 18000 1 BAKST}
+    {528242400 14400 0 BAKT}
+    {543967200 18000 1 BAKST}
+    {559692000 14400 0 BAKT}
+    {575416800 18000 1 BAKST}
+    {591141600 14400 0 BAKT}
+    {606866400 18000 1 BAKST}
+    {622591200 14400 0 BAKT}
+    {638316000 18000 1 BAKST}
+    {654645600 14400 0 BAKT}
+    {670370400 14400 1 BAKST}
+    {683496000 14400 0 AZST}
+    {686098800 10800 0 AZT}
+    {701823600 14400 1 AZST}
+    {717548400 14400 0 AZT}
+    {820440000 14400 0 AZT}
+    {828234000 18000 1 AZST}
+    {846378000 14400 0 AZT}
+    {852062400 14400 0 AZT}
+    {859680000 18000 1 AZST}
+    {877824000 14400 0 AZT}
+    {891129600 18000 1 AZST}
+    {909273600 14400 0 AZT}
+    {922579200 18000 1 AZST}
+    {941328000 14400 0 AZT}
+    {954028800 18000 1 AZST}
+    {972777600 14400 0 AZT}
+    {985478400 18000 1 AZST}
+    {1004227200 14400 0 AZT}
+    {1017532800 18000 1 AZST}
+    {1035676800 14400 0 AZT}
+    {1048982400 18000 1 AZST}
+    {1067126400 14400 0 AZT}
+    {1080432000 18000 1 AZST}
+    {1099180800 14400 0 AZT}
+    {1111881600 18000 1 AZST}
+    {1130630400 14400 0 AZT}
+    {1143331200 18000 1 AZST}
+    {1162080000 14400 0 AZT}
+    {1174780800 18000 1 AZST}
+    {1193529600 14400 0 AZT}
+    {1206835200 18000 1 AZST}
+    {1224979200 14400 0 AZT}
+    {1238284800 18000 1 AZST}
+    {1256428800 14400 0 AZT}
+    {1269734400 18000 1 AZST}
+    {1288483200 14400 0 AZT}
+    {1301184000 18000 1 AZST}
+    {1319932800 14400 0 AZT}
+    {1332633600 18000 1 AZST}
+    {1351382400 14400 0 AZT}
+    {1364688000 18000 1 AZST}
+    {1382832000 14400 0 AZT}
+    {1396137600 18000 1 AZST}
+    {1414281600 14400 0 AZT}
+    {1427587200 18000 1 AZST}
+    {1445731200 14400 0 AZT}
+}
diff --git a/library/tzdata/Asia/Bangkok b/library/tzdata/Asia/Bangkok
new file mode 100644
index 0000000..6df7680
--- /dev/null
+++ b/library/tzdata/Asia/Bangkok
@@ -0,0 +1,7 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Asia/Bangkok) {
+    {-9223372036854775808 24124 0 LMT}
+    {-2840164924 24124 0 BMT}
+    {-1570084924 25200 0 ICT}
+}
diff --git a/library/tzdata/Asia/Barnaul b/library/tzdata/Asia/Barnaul
new file mode 100644
index 0000000..bf6abbf
--- /dev/null
+++ b/library/tzdata/Asia/Barnaul
@@ -0,0 +1,73 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Asia/Barnaul) {
+    {-9223372036854775808 20100 0 LMT}
+    {-1579844100 21600 0 +06}
+    {-1247551200 25200 0 +08}
+    {354906000 28800 1 +08}
+    {370713600 25200 0 +07}
+    {386442000 28800 1 +08}
+    {402249600 25200 0 +07}
+    {417978000 28800 1 +08}
+    {433785600 25200 0 +07}
+    {449600400 28800 1 +08}
+    {465332400 25200 0 +07}
+    {481057200 28800 1 +08}
+    {496782000 25200 0 +07}
+    {512506800 28800 1 +08}
+    {528231600 25200 0 +07}
+    {543956400 28800 1 +08}
+    {559681200 25200 0 +07}
+    {575406000 28800 1 +08}
+    {591130800 25200 0 +07}
+    {606855600 28800 1 +08}
+    {622580400 25200 0 +07}
+    {638305200 28800 1 +08}
+    {654634800 25200 0 +07}
+    {670359600 21600 0 +07}
+    {670363200 25200 1 +07}
+    {686088000 21600 0 +06}
+    {695764800 25200 0 +08}
+    {701809200 28800 1 +08}
+    {717534000 25200 0 +07}
+    {733258800 28800 1 +08}
+    {748983600 25200 0 +07}
+    {764708400 28800 1 +08}
+    {780433200 25200 0 +07}
+    {796158000 28800 1 +08}
+    {801594000 25200 0 +07}
+    {811886400 21600 0 +06}
+    {828216000 25200 1 +07}
+    {846360000 21600 0 +06}
+    {859665600 25200 1 +07}
+    {877809600 21600 0 +06}
+    {891115200 25200 1 +07}
+    {909259200 21600 0 +06}
+    {922564800 25200 1 +07}
+    {941313600 21600 0 +06}
+    {954014400 25200 1 +07}
+    {972763200 21600 0 +06}
+    {985464000 25200 1 +07}
+    {1004212800 21600 0 +06}
+    {1017518400 25200 1 +07}
+    {1035662400 21600 0 +06}
+    {1048968000 25200 1 +07}
+    {1067112000 21600 0 +06}
+    {1080417600 25200 1 +07}
+    {1099166400 21600 0 +06}
+    {1111867200 25200 1 +07}
+    {1130616000 21600 0 +06}
+    {1143316800 25200 1 +07}
+    {1162065600 21600 0 +06}
+    {1174766400 25200 1 +07}
+    {1193515200 21600 0 +06}
+    {1206820800 25200 1 +07}
+    {1224964800 21600 0 +06}
+    {1238270400 25200 1 +07}
+    {1256414400 21600 0 +06}
+    {1269720000 25200 1 +07}
+    {1288468800 21600 0 +06}
+    {1301169600 25200 0 +07}
+    {1414263600 21600 0 +06}
+    {1459022400 25200 0 +07}
+}
diff --git a/library/tzdata/Asia/Beirut b/library/tzdata/Asia/Beirut
new file mode 100644
index 0000000..ac0a64e
--- /dev/null
+++ b/library/tzdata/Asia/Beirut
@@ -0,0 +1,270 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Asia/Beirut) {
+    {-9223372036854775808 8520 0 LMT}
+    {-2840149320 7200 0 EET}
+    {-1570413600 10800 1 EEST}
+    {-1552186800 7200 0 EET}
+    {-1538359200 10800 1 EEST}
+    {-1522551600 7200 0 EET}
+    {-1507514400 10800 1 EEST}
+    {-1490583600 7200 0 EET}
+    {-1473645600 10800 1 EEST}
+    {-1460948400 7200 0 EET}
+    {-399866400 10800 1 EEST}
+    {-386650800 7200 0 EET}
+    {-368330400 10800 1 EEST}
+    {-355114800 7200 0 EET}
+    {-336794400 10800 1 EEST}
+    {-323578800 7200 0 EET}
+    {-305172000 10800 1 EEST}
+    {-291956400 7200 0 EET}
+    {-273636000 10800 1 EEST}
+    {-260420400 7200 0 EET}
+    {78012000 10800 1 EEST}
+    {86734800 7200 0 EET}
+    {105055200 10800 1 EEST}
+    {118270800 7200 0 EET}
+    {136591200 10800 1 EEST}
+    {149806800 7200 0 EET}
+    {168127200 10800 1 EEST}
+    {181342800 7200 0 EET}
+    {199749600 10800 1 EEST}
+    {212965200 7200 0 EET}
+    {231285600 10800 1 EEST}
+    {244501200 7200 0 EET}
+    {262735200 10800 1 EEST}
+    {275950800 7200 0 EET}
+    {452210400 10800 1 EEST}
+    {466722000 7200 0 EET}
+    {483746400 10800 1 EEST}
+    {498258000 7200 0 EET}
+    {515282400 10800 1 EEST}
+    {529794000 7200 0 EET}
+    {546818400 10800 1 EEST}
+    {561330000 7200 0 EET}
+    {581119200 10800 1 EEST}
+    {592952400 7200 0 EET}
+    {610754400 10800 1 EEST}
+    {624488400 7200 0 EET}
+    {641512800 10800 1 EEST}
+    {656024400 7200 0 EET}
+    {673048800 10800 1 EEST}
+    {687560400 7200 0 EET}
+    {704671200 10800 1 EEST}
+    {718146000 7200 0 EET}
+    {733269600 10800 1 EEST}
+    {748990800 7200 0 EET}
+    {764719200 10800 1 EEST}
+    {780440400 7200 0 EET}
+    {796168800 10800 1 EEST}
+    {811890000 7200 0 EET}
+    {828223200 10800 1 EEST}
+    {843944400 7200 0 EET}
+    {859672800 10800 1 EEST}
+    {875394000 7200 0 EET}
+    {891122400 10800 1 EEST}
+    {906843600 7200 0 EET}
+    {922572000 10800 1 EEST}
+    {941317200 7200 0 EET}
+    {954021600 10800 1 EEST}
+    {972766800 7200 0 EET}
+    {985471200 10800 1 EEST}
+    {1004216400 7200 0 EET}
+    {1017525600 10800 1 EEST}
+    {1035666000 7200 0 EET}
+    {1048975200 10800 1 EEST}
+    {1067115600 7200 0 EET}
+    {1080424800 10800 1 EEST}
+    {1099170000 7200 0 EET}
+    {1111874400 10800 1 EEST}
+    {1130619600 7200 0 EET}
+    {1143324000 10800 1 EEST}
+    {1162069200 7200 0 EET}
+    {1174773600 10800 1 EEST}
+    {1193518800 7200 0 EET}
+    {1206828000 10800 1 EEST}
+    {1224968400 7200 0 EET}
+    {1238277600 10800 1 EEST}
+    {1256418000 7200 0 EET}
+    {1269727200 10800 1 EEST}
+    {1288472400 7200 0 EET}
+    {1301176800 10800 1 EEST}
+    {1319922000 7200 0 EET}
+    {1332626400 10800 1 EEST}
+    {1351371600 7200 0 EET}
+    {1364680800 10800 1 EEST}
+    {1382821200 7200 0 EET}
+    {1396130400 10800 1 EEST}
+    {1414270800 7200 0 EET}
+    {1427580000 10800 1 EEST}
+    {1445720400 7200 0 EET}
+    {1459029600 10800 1 EEST}
+    {1477774800 7200 0 EET}
+    {1490479200 10800 1 EEST}
+    {1509224400 7200 0 EET}
+    {1521928800 10800 1 EEST}
+    {1540674000 7200 0 EET}
+    {1553983200 10800 1 EEST}
+    {1572123600 7200 0 EET}
+    {1585432800 10800 1 EEST}
+    {1603573200 7200 0 EET}
+    {1616882400 10800 1 EEST}
+    {1635627600 7200 0 EET}
+    {1648332000 10800 1 EEST}
+    {1667077200 7200 0 EET}
+    {1679781600 10800 1 EEST}
+    {1698526800 7200 0 EET}
+    {1711836000 10800 1 EEST}
+    {1729976400 7200 0 EET}
+    {1743285600 10800 1 EEST}
+    {1761426000 7200 0 EET}
+    {1774735200 10800 1 EEST}
+    {1792875600 7200 0 EET}
+    {1806184800 10800 1 EEST}
+    {1824930000 7200 0 EET}
+    {1837634400 10800 1 EEST}
+    {1856379600 7200 0 EET}
+    {1869084000 10800 1 EEST}
+    {1887829200 7200 0 EET}
+    {1901138400 10800 1 EEST}
+    {1919278800 7200 0 EET}
+    {1932588000 10800 1 EEST}
+    {1950728400 7200 0 EET}
+    {1964037600 10800 1 EEST}
+    {1982782800 7200 0 EET}
+    {1995487200 10800 1 EEST}
+    {2014232400 7200 0 EET}
+    {2026936800 10800 1 EEST}
+    {2045682000 7200 0 EET}
+    {2058386400 10800 1 EEST}
+    {2077131600 7200 0 EET}
+    {2090440800 10800 1 EEST}
+    {2108581200 7200 0 EET}
+    {2121890400 10800 1 EEST}
+    {2140030800 7200 0 EET}
+    {2153340000 10800 1 EEST}
+    {2172085200 7200 0 EET}
+    {2184789600 10800 1 EEST}
+    {2203534800 7200 0 EET}
+    {2216239200 10800 1 EEST}
+    {2234984400 7200 0 EET}
+    {2248293600 10800 1 EEST}
+    {2266434000 7200 0 EET}
+    {2279743200 10800 1 EEST}
+    {2297883600 7200 0 EET}
+    {2311192800 10800 1 EEST}
+    {2329333200 7200 0 EET}
+    {2342642400 10800 1 EEST}
+    {2361387600 7200 0 EET}
+    {2374092000 10800 1 EEST}
+    {2392837200 7200 0 EET}
+    {2405541600 10800 1 EEST}
+    {2424286800 7200 0 EET}
+    {2437596000 10800 1 EEST}
+    {2455736400 7200 0 EET}
+    {2469045600 10800 1 EEST}
+    {2487186000 7200 0 EET}
+    {2500495200 10800 1 EEST}
+    {2519240400 7200 0 EET}
+    {2531944800 10800 1 EEST}
+    {2550690000 7200 0 EET}
+    {2563394400 10800 1 EEST}
+    {2582139600 7200 0 EET}
+    {2595448800 10800 1 EEST}
+    {2613589200 7200 0 EET}
+    {2626898400 10800 1 EEST}
+    {2645038800 7200 0 EET}
+    {2658348000 10800 1 EEST}
+    {2676488400 7200 0 EET}
+    {2689797600 10800 1 EEST}
+    {2708542800 7200 0 EET}
+    {2721247200 10800 1 EEST}
+    {2739992400 7200 0 EET}
+    {2752696800 10800 1 EEST}
+    {2771442000 7200 0 EET}
+    {2784751200 10800 1 EEST}
+    {2802891600 7200 0 EET}
+    {2816200800 10800 1 EEST}
+    {2834341200 7200 0 EET}
+    {2847650400 10800 1 EEST}
+    {2866395600 7200 0 EET}
+    {2879100000 10800 1 EEST}
+    {2897845200 7200 0 EET}
+    {2910549600 10800 1 EEST}
+    {2929294800 7200 0 EET}
+    {2941999200 10800 1 EEST}
+    {2960744400 7200 0 EET}
+    {2974053600 10800 1 EEST}
+    {2992194000 7200 0 EET}
+    {3005503200 10800 1 EEST}
+    {3023643600 7200 0 EET}
+    {3036952800 10800 1 EEST}
+    {3055698000 7200 0 EET}
+    {3068402400 10800 1 EEST}
+    {3087147600 7200 0 EET}
+    {3099852000 10800 1 EEST}
+    {3118597200 7200 0 EET}
+    {3131906400 10800 1 EEST}
+    {3150046800 7200 0 EET}
+    {3163356000 10800 1 EEST}
+    {3181496400 7200 0 EET}
+    {3194805600 10800 1 EEST}
+    {3212946000 7200 0 EET}
+    {3226255200 10800 1 EEST}
+    {3245000400 7200 0 EET}
+    {3257704800 10800 1 EEST}
+    {3276450000 7200 0 EET}
+    {3289154400 10800 1 EEST}
+    {3307899600 7200 0 EET}
+    {3321208800 10800 1 EEST}
+    {3339349200 7200 0 EET}
+    {3352658400 10800 1 EEST}
+    {3370798800 7200 0 EET}
+    {3384108000 10800 1 EEST}
+    {3402853200 7200 0 EET}
+    {3415557600 10800 1 EEST}
+    {3434302800 7200 0 EET}
+    {3447007200 10800 1 EEST}
+    {3465752400 7200 0 EET}
+    {3479061600 10800 1 EEST}
+    {3497202000 7200 0 EET}
+    {3510511200 10800 1 EEST}
+    {3528651600 7200 0 EET}
+    {3541960800 10800 1 EEST}
+    {3560101200 7200 0 EET}
+    {3573410400 10800 1 EEST}
+    {3592155600 7200 0 EET}
+    {3604860000 10800 1 EEST}
+    {3623605200 7200 0 EET}
+    {3636309600 10800 1 EEST}
+    {3655054800 7200 0 EET}
+    {3668364000 10800 1 EEST}
+    {3686504400 7200 0 EET}
+    {3699813600 10800 1 EEST}
+    {3717954000 7200 0 EET}
+    {3731263200 10800 1 EEST}
+    {3750008400 7200 0 EET}
+    {3762712800 10800 1 EEST}
+    {3781458000 7200 0 EET}
+    {3794162400 10800 1 EEST}
+    {3812907600 7200 0 EET}
+    {3825612000 10800 1 EEST}
+    {3844357200 7200 0 EET}
+    {3857666400 10800 1 EEST}
+    {3875806800 7200 0 EET}
+    {3889116000 10800 1 EEST}
+    {3907256400 7200 0 EET}
+    {3920565600 10800 1 EEST}
+    {3939310800 7200 0 EET}
+    {3952015200 10800 1 EEST}
+    {3970760400 7200 0 EET}
+    {3983464800 10800 1 EEST}
+    {4002210000 7200 0 EET}
+    {4015519200 10800 1 EEST}
+    {4033659600 7200 0 EET}
+    {4046968800 10800 1 EEST}
+    {4065109200 7200 0 EET}
+    {4078418400 10800 1 EEST}
+    {4096558800 7200 0 EET}
+}
diff --git a/library/tzdata/Asia/Bishkek b/library/tzdata/Asia/Bishkek
new file mode 100644
index 0000000..6ba3896
--- /dev/null
+++ b/library/tzdata/Asia/Bishkek
@@ -0,0 +1,57 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Asia/Bishkek) {
+    {-9223372036854775808 17904 0 LMT}
+    {-1441169904 18000 0 FRUT}
+    {-1247547600 21600 0 FRUT}
+    {354909600 25200 1 FRUST}
+    {370717200 21600 0 FRUT}
+    {386445600 25200 1 FRUST}
+    {402253200 21600 0 FRUT}
+    {417981600 25200 1 FRUST}
+    {433789200 21600 0 FRUT}
+    {449604000 25200 1 FRUST}
+    {465336000 21600 0 FRUT}
+    {481060800 25200 1 FRUST}
+    {496785600 21600 0 FRUT}
+    {512510400 25200 1 FRUST}
+    {528235200 21600 0 FRUT}
+    {543960000 25200 1 FRUST}
+    {559684800 21600 0 FRUT}
+    {575409600 25200 1 FRUST}
+    {591134400 21600 0 FRUT}
+    {606859200 25200 1 FRUST}
+    {622584000 21600 0 FRUT}
+    {638308800 25200 1 FRUST}
+    {654638400 21600 0 FRUT}
+    {670363200 21600 1 FRUST}
+    {683582400 21600 0 KGT}
+    {703018800 21600 1 KGST}
+    {717530400 18000 0 KGT}
+    {734468400 21600 1 KGST}
+    {748980000 18000 0 KGT}
+    {765918000 21600 1 KGST}
+    {780429600 18000 0 KGT}
+    {797367600 21600 1 KGST}
+    {811879200 18000 0 KGT}
+    {828817200 21600 1 KGST}
+    {843933600 18000 0 KGT}
+    {859671000 21600 1 KGST}
+    {877811400 18000 0 KGT}
+    {891120600 21600 1 KGST}
+    {909261000 18000 0 KGT}
+    {922570200 21600 1 KGST}
+    {941315400 18000 0 KGT}
+    {954019800 21600 1 KGST}
+    {972765000 18000 0 KGT}
+    {985469400 21600 1 KGST}
+    {1004214600 18000 0 KGT}
+    {1017523800 21600 1 KGST}
+    {1035664200 18000 0 KGT}
+    {1048973400 21600 1 KGST}
+    {1067113800 18000 0 KGT}
+    {1080423000 21600 1 KGST}
+    {1099168200 18000 0 KGT}
+    {1111872600 21600 1 KGST}
+    {1123783200 21600 0 KGT}
+}
diff --git a/library/tzdata/Asia/Brunei b/library/tzdata/Asia/Brunei
new file mode 100644
index 0000000..63d380b
--- /dev/null
+++ b/library/tzdata/Asia/Brunei
@@ -0,0 +1,7 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Asia/Brunei) {
+    {-9223372036854775808 27580 0 LMT}
+    {-1383464380 27000 0 BNT}
+    {-1167636600 28800 0 BNT}
+}
diff --git a/library/tzdata/Asia/Calcutta b/library/tzdata/Asia/Calcutta
new file mode 100644
index 0000000..7243ef8
--- /dev/null
+++ b/library/tzdata/Asia/Calcutta
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Asia/Kolkata)]} {
+    LoadTimeZoneFile Asia/Kolkata
+}
+set TZData(:Asia/Calcutta) $TZData(:Asia/Kolkata)
diff --git a/library/tzdata/Asia/Chita b/library/tzdata/Asia/Chita
new file mode 100644
index 0000000..2517beb
--- /dev/null
+++ b/library/tzdata/Asia/Chita
@@ -0,0 +1,72 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Asia/Chita) {
+    {-9223372036854775808 27232 0 LMT}
+    {-1579419232 28800 0 YAKT}
+    {-1247558400 32400 0 YAKMMTT}
+    {354898800 36000 1 YAKST}
+    {370706400 32400 0 YAKT}
+    {386434800 36000 1 YAKST}
+    {402242400 32400 0 YAKT}
+    {417970800 36000 1 YAKST}
+    {433778400 32400 0 YAKT}
+    {449593200 36000 1 YAKST}
+    {465325200 32400 0 YAKT}
+    {481050000 36000 1 YAKST}
+    {496774800 32400 0 YAKT}
+    {512499600 36000 1 YAKST}
+    {528224400 32400 0 YAKT}
+    {543949200 36000 1 YAKST}
+    {559674000 32400 0 YAKT}
+    {575398800 36000 1 YAKST}
+    {591123600 32400 0 YAKT}
+    {606848400 36000 1 YAKST}
+    {622573200 32400 0 YAKT}
+    {638298000 36000 1 YAKST}
+    {654627600 32400 0 YAKT}
+    {670352400 28800 0 YAKMMTT}
+    {670356000 32400 1 YAKST}
+    {686080800 28800 0 YAKT}
+    {695757600 32400 0 YAKMMTT}
+    {701802000 36000 1 YAKST}
+    {717526800 32400 0 YAKT}
+    {733251600 36000 1 YAKST}
+    {748976400 32400 0 YAKT}
+    {764701200 36000 1 YAKST}
+    {780426000 32400 0 YAKT}
+    {796150800 36000 1 YAKST}
+    {811875600 32400 0 YAKT}
+    {828205200 36000 1 YAKST}
+    {846349200 32400 0 YAKT}
+    {859654800 36000 1 YAKST}
+    {877798800 32400 0 YAKT}
+    {891104400 36000 1 YAKST}
+    {909248400 32400 0 YAKT}
+    {922554000 36000 1 YAKST}
+    {941302800 32400 0 YAKT}
+    {954003600 36000 1 YAKST}
+    {972752400 32400 0 YAKT}
+    {985453200 36000 1 YAKST}
+    {1004202000 32400 0 YAKT}
+    {1017507600 36000 1 YAKST}
+    {1035651600 32400 0 YAKT}
+    {1048957200 36000 1 YAKST}
+    {1067101200 32400 0 YAKT}
+    {1080406800 36000 1 YAKST}
+    {1099155600 32400 0 YAKT}
+    {1111856400 36000 1 YAKST}
+    {1130605200 32400 0 YAKT}
+    {1143306000 36000 1 YAKST}
+    {1162054800 32400 0 YAKT}
+    {1174755600 36000 1 YAKST}
+    {1193504400 32400 0 YAKT}
+    {1206810000 36000 1 YAKST}
+    {1224954000 32400 0 YAKT}
+    {1238259600 36000 1 YAKST}
+    {1256403600 32400 0 YAKT}
+    {1269709200 36000 1 YAKST}
+    {1288458000 32400 0 YAKT}
+    {1301158800 36000 0 YAKT}
+    {1414252800 28800 0 IRKT}
+    {1459015200 32400 0 YAKT}
+}
diff --git a/library/tzdata/Asia/Choibalsan b/library/tzdata/Asia/Choibalsan
new file mode 100644
index 0000000..2bcf7f7
--- /dev/null
+++ b/library/tzdata/Asia/Choibalsan
@@ -0,0 +1,222 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Asia/Choibalsan) {
+    {-9223372036854775808 27480 0 LMT}
+    {-2032933080 25200 0 ULAT}
+    {252435600 28800 0 ULAT}
+    {417974400 36000 0 CHOST}
+    {433778400 32400 0 CHOT}
+    {449593200 36000 1 CHOST}
+    {465314400 32400 0 CHOT}
+    {481042800 36000 1 CHOST}
+    {496764000 32400 0 CHOT}
+    {512492400 36000 1 CHOST}
+    {528213600 32400 0 CHOT}
+    {543942000 36000 1 CHOST}
+    {559663200 32400 0 CHOT}
+    {575391600 36000 1 CHOST}
+    {591112800 32400 0 CHOT}
+    {606841200 36000 1 CHOST}
+    {622562400 32400 0 CHOT}
+    {638290800 36000 1 CHOST}
+    {654616800 32400 0 CHOT}
+    {670345200 36000 1 CHOST}
+    {686066400 32400 0 CHOT}
+    {701794800 36000 1 CHOST}
+    {717516000 32400 0 CHOT}
+    {733244400 36000 1 CHOST}
+    {748965600 32400 0 CHOT}
+    {764694000 36000 1 CHOST}
+    {780415200 32400 0 CHOT}
+    {796143600 36000 1 CHOST}
+    {811864800 32400 0 CHOT}
+    {828198000 36000 1 CHOST}
+    {843919200 32400 0 CHOT}
+    {859647600 36000 1 CHOST}
+    {875368800 32400 0 CHOT}
+    {891097200 36000 1 CHOST}
+    {906818400 32400 0 CHOT}
+    {988390800 36000 1 CHOST}
+    {1001692800 32400 0 CHOT}
+    {1017421200 36000 1 CHOST}
+    {1033142400 32400 0 CHOT}
+    {1048870800 36000 1 CHOST}
+    {1064592000 32400 0 CHOT}
+    {1080320400 36000 1 CHOST}
+    {1096041600 32400 0 CHOT}
+    {1111770000 36000 1 CHOST}
+    {1127491200 32400 0 CHOT}
+    {1143219600 36000 1 CHOST}
+    {1159545600 32400 0 CHOT}
+    {1206889200 28800 0 CHOT}
+    {1427479200 32400 1 CHOST}
+    {1443193200 28800 0 CHOT}
+    {1458928800 32400 1 CHOST}
+    {1474642800 28800 0 CHOT}
+    {1490378400 32400 1 CHOST}
+    {1506697200 28800 0 CHOT}
+    {1522432800 32400 1 CHOST}
+    {1538146800 28800 0 CHOT}
+    {1553882400 32400 1 CHOST}
+    {1569596400 28800 0 CHOT}
+    {1585332000 32400 1 CHOST}
+    {1601046000 28800 0 CHOT}
+    {1616781600 32400 1 CHOST}
+    {1632495600 28800 0 CHOT}
+    {1648231200 32400 1 CHOST}
+    {1663945200 28800 0 CHOT}
+    {1679680800 32400 1 CHOST}
+    {1695999600 28800 0 CHOT}
+    {1711735200 32400 1 CHOST}
+    {1727449200 28800 0 CHOT}
+    {1743184800 32400 1 CHOST}
+    {1758898800 28800 0 CHOT}
+    {1774634400 32400 1 CHOST}
+    {1790348400 28800 0 CHOT}
+    {1806084000 32400 1 CHOST}
+    {1821798000 28800 0 CHOT}
+    {1837533600 32400 1 CHOST}
+    {1853852400 28800 0 CHOT}
+    {1869588000 32400 1 CHOST}
+    {1885302000 28800 0 CHOT}
+    {1901037600 32400 1 CHOST}
+    {1916751600 28800 0 CHOT}
+    {1932487200 32400 1 CHOST}
+    {1948201200 28800 0 CHOT}
+    {1963936800 32400 1 CHOST}
+    {1979650800 28800 0 CHOT}
+    {1995386400 32400 1 CHOST}
+    {2011100400 28800 0 CHOT}
+    {2026836000 32400 1 CHOST}
+    {2043154800 28800 0 CHOT}
+    {2058890400 32400 1 CHOST}
+    {2074604400 28800 0 CHOT}
+    {2090340000 32400 1 CHOST}
+    {2106054000 28800 0 CHOT}
+    {2121789600 32400 1 CHOST}
+    {2137503600 28800 0 CHOT}
+    {2153239200 32400 1 CHOST}
+    {2168953200 28800 0 CHOT}
+    {2184688800 32400 1 CHOST}
+    {2200402800 28800 0 CHOT}
+    {2216743200 32400 1 CHOST}
+    {2232457200 28800 0 CHOT}
+    {2248192800 32400 1 CHOST}
+    {2263906800 28800 0 CHOT}
+    {2279642400 32400 1 CHOST}
+    {2295356400 28800 0 CHOT}
+    {2311092000 32400 1 CHOST}
+    {2326806000 28800 0 CHOT}
+    {2342541600 32400 1 CHOST}
+    {2358255600 28800 0 CHOT}
+    {2373991200 32400 1 CHOST}
+    {2390310000 28800 0 CHOT}
+    {2406045600 32400 1 CHOST}
+    {2421759600 28800 0 CHOT}
+    {2437495200 32400 1 CHOST}
+    {2453209200 28800 0 CHOT}
+    {2468944800 32400 1 CHOST}
+    {2484658800 28800 0 CHOT}
+    {2500394400 32400 1 CHOST}
+    {2516108400 28800 0 CHOT}
+    {2531844000 32400 1 CHOST}
+    {2547558000 28800 0 CHOT}
+    {2563293600 32400 1 CHOST}
+    {2579612400 28800 0 CHOT}
+    {2595348000 32400 1 CHOST}
+    {2611062000 28800 0 CHOT}
+    {2626797600 32400 1 CHOST}
+    {2642511600 28800 0 CHOT}
+    {2658247200 32400 1 CHOST}
+    {2673961200 28800 0 CHOT}
+    {2689696800 32400 1 CHOST}
+    {2705410800 28800 0 CHOT}
+    {2721146400 32400 1 CHOST}
+    {2737465200 28800 0 CHOT}
+    {2753200800 32400 1 CHOST}
+    {2768914800 28800 0 CHOT}
+    {2784650400 32400 1 CHOST}
+    {2800364400 28800 0 CHOT}
+    {2816100000 32400 1 CHOST}
+    {2831814000 28800 0 CHOT}
+    {2847549600 32400 1 CHOST}
+    {2863263600 28800 0 CHOT}
+    {2878999200 32400 1 CHOST}
+    {2894713200 28800 0 CHOT}
+    {2910448800 32400 1 CHOST}
+    {2926767600 28800 0 CHOT}
+    {2942503200 32400 1 CHOST}
+    {2958217200 28800 0 CHOT}
+    {2973952800 32400 1 CHOST}
+    {2989666800 28800 0 CHOT}
+    {3005402400 32400 1 CHOST}
+    {3021116400 28800 0 CHOT}
+    {3036852000 32400 1 CHOST}
+    {3052566000 28800 0 CHOT}
+    {3068301600 32400 1 CHOST}
+    {3084015600 28800 0 CHOT}
+    {3100356000 32400 1 CHOST}
+    {3116070000 28800 0 CHOT}
+    {3131805600 32400 1 CHOST}
+    {3147519600 28800 0 CHOT}
+    {3163255200 32400 1 CHOST}
+    {3178969200 28800 0 CHOT}
+    {3194704800 32400 1 CHOST}
+    {3210418800 28800 0 CHOT}
+    {3226154400 32400 1 CHOST}
+    {3241868400 28800 0 CHOT}
+    {3257604000 32400 1 CHOST}
+    {3273922800 28800 0 CHOT}
+    {3289658400 32400 1 CHOST}
+    {3305372400 28800 0 CHOT}
+    {3321108000 32400 1 CHOST}
+    {3336822000 28800 0 CHOT}
+    {3352557600 32400 1 CHOST}
+    {3368271600 28800 0 CHOT}
+    {3384007200 32400 1 CHOST}
+    {3399721200 28800 0 CHOT}
+    {3415456800 32400 1 CHOST}
+    {3431170800 28800 0 CHOT}
+    {3446906400 32400 1 CHOST}
+    {3463225200 28800 0 CHOT}
+    {3478960800 32400 1 CHOST}
+    {3494674800 28800 0 CHOT}
+    {3510410400 32400 1 CHOST}
+    {3526124400 28800 0 CHOT}
+    {3541860000 32400 1 CHOST}
+    {3557574000 28800 0 CHOT}
+    {3573309600 32400 1 CHOST}
+    {3589023600 28800 0 CHOT}
+    {3604759200 32400 1 CHOST}
+    {3621078000 28800 0 CHOT}
+    {3636813600 32400 1 CHOST}
+    {3652527600 28800 0 CHOT}
+    {3668263200 32400 1 CHOST}
+    {3683977200 28800 0 CHOT}
+    {3699712800 32400 1 CHOST}
+    {3715426800 28800 0 CHOT}
+    {3731162400 32400 1 CHOST}
+    {3746876400 28800 0 CHOT}
+    {3762612000 32400 1 CHOST}
+    {3778326000 28800 0 CHOT}
+    {3794061600 32400 1 CHOST}
+    {3810380400 28800 0 CHOT}
+    {3826116000 32400 1 CHOST}
+    {3841830000 28800 0 CHOT}
+    {3857565600 32400 1 CHOST}
+    {3873279600 28800 0 CHOT}
+    {3889015200 32400 1 CHOST}
+    {3904729200 28800 0 CHOT}
+    {3920464800 32400 1 CHOST}
+    {3936178800 28800 0 CHOT}
+    {3951914400 32400 1 CHOST}
+    {3967628400 28800 0 CHOT}
+    {3983968800 32400 1 CHOST}
+    {3999682800 28800 0 CHOT}
+    {4015418400 32400 1 CHOST}
+    {4031132400 28800 0 CHOT}
+    {4046868000 32400 1 CHOST}
+    {4062582000 28800 0 CHOT}
+    {4078317600 32400 1 CHOST}
+    {4094031600 28800 0 CHOT}
+}
diff --git a/library/tzdata/Asia/Chongqing b/library/tzdata/Asia/Chongqing
new file mode 100644
index 0000000..ba515fe
--- /dev/null
+++ b/library/tzdata/Asia/Chongqing
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Asia/Shanghai)]} {
+    LoadTimeZoneFile Asia/Shanghai
+}
+set TZData(:Asia/Chongqing) $TZData(:Asia/Shanghai)
diff --git a/library/tzdata/Asia/Chungking b/library/tzdata/Asia/Chungking
new file mode 100644
index 0000000..fa857dd
--- /dev/null
+++ b/library/tzdata/Asia/Chungking
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Asia/Shanghai)]} {
+    LoadTimeZoneFile Asia/Shanghai
+}
+set TZData(:Asia/Chungking) $TZData(:Asia/Shanghai)
diff --git a/library/tzdata/Asia/Colombo b/library/tzdata/Asia/Colombo
new file mode 100644
index 0000000..ca7bffc
--- /dev/null
+++ b/library/tzdata/Asia/Colombo
@@ -0,0 +1,13 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Asia/Colombo) {
+    {-9223372036854775808 19164 0 LMT}
+    {-2840159964 19172 0 MMT}
+    {-2019705572 19800 0 IST}
+    {-883287000 21600 1 IHST}
+    {-862639200 23400 1 IST}
+    {-764051400 19800 0 IST}
+    {832962600 23400 0 LKT}
+    {846266400 21600 0 LKT}
+    {1145039400 19800 0 IST}
+}
diff --git a/library/tzdata/Asia/Dacca b/library/tzdata/Asia/Dacca
new file mode 100644
index 0000000..b91d7fa
--- /dev/null
+++ b/library/tzdata/Asia/Dacca
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Asia/Dhaka)]} {
+    LoadTimeZoneFile Asia/Dhaka
+}
+set TZData(:Asia/Dacca) $TZData(:Asia/Dhaka)
diff --git a/library/tzdata/Asia/Damascus b/library/tzdata/Asia/Damascus
new file mode 100644
index 0000000..fafef49
--- /dev/null
+++ b/library/tzdata/Asia/Damascus
@@ -0,0 +1,280 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Asia/Damascus) {
+    {-9223372036854775808 8712 0 LMT}
+    {-1577931912 7200 0 EET}
+    {-1568592000 10800 1 EEST}
+    {-1554080400 7200 0 EET}
+    {-1537142400 10800 1 EEST}
+    {-1522630800 7200 0 EET}
+    {-1505692800 10800 1 EEST}
+    {-1491181200 7200 0 EET}
+    {-1474243200 10800 1 EEST}
+    {-1459126800 7200 0 EET}
+    {-242265600 10800 1 EEST}
+    {-228877200 7200 0 EET}
+    {-210556800 10800 1 EEST}
+    {-197427600 7200 0 EET}
+    {-178934400 10800 1 EEST}
+    {-165718800 7200 0 EET}
+    {-147398400 10800 1 EEST}
+    {-134269200 7200 0 EET}
+    {-116467200 10800 1 EEST}
+    {-102646800 7200 0 EET}
+    {-84326400 10800 1 EEST}
+    {-71110800 7200 0 EET}
+    {-52704000 10800 1 EEST}
+    {-39488400 7200 0 EET}
+    {-21168000 10800 1 EEST}
+    {-7952400 7200 0 EET}
+    {10368000 10800 1 EEST}
+    {23583600 7200 0 EET}
+    {41904000 10800 1 EEST}
+    {55119600 7200 0 EET}
+    {73526400 10800 1 EEST}
+    {86742000 7200 0 EET}
+    {105062400 10800 1 EEST}
+    {118278000 7200 0 EET}
+    {136598400 10800 1 EEST}
+    {149814000 7200 0 EET}
+    {168134400 10800 1 EEST}
+    {181350000 7200 0 EET}
+    {199756800 10800 1 EEST}
+    {212972400 7200 0 EET}
+    {231292800 10800 1 EEST}
+    {241916400 7200 0 EET}
+    {262828800 10800 1 EEST}
+    {273452400 7200 0 EET}
+    {418694400 10800 1 EEST}
+    {433810800 7200 0 EET}
+    {450316800 10800 1 EEST}
+    {465433200 7200 0 EET}
+    {508896000 10800 1 EEST}
+    {529196400 7200 0 EET}
+    {541555200 10800 1 EEST}
+    {562633200 7200 0 EET}
+    {574387200 10800 1 EEST}
+    {594255600 7200 0 EET}
+    {607305600 10800 1 EEST}
+    {623199600 7200 0 EET}
+    {638928000 10800 1 EEST}
+    {654649200 7200 0 EET}
+    {670456800 10800 1 EEST}
+    {686264400 7200 0 EET}
+    {702684000 10800 1 EEST}
+    {717886800 7200 0 EET}
+    {733096800 10800 1 EEST}
+    {748904400 7200 0 EET}
+    {765151200 10800 1 EEST}
+    {780958800 7200 0 EET}
+    {796687200 10800 1 EEST}
+    {812494800 7200 0 EET}
+    {828309600 10800 1 EEST}
+    {844117200 7200 0 EET}
+    {859759200 10800 1 EEST}
+    {875653200 7200 0 EET}
+    {891208800 10800 1 EEST}
+    {907189200 7200 0 EET}
+    {922917600 10800 1 EEST}
+    {938725200 7200 0 EET}
+    {954540000 10800 1 EEST}
+    {970347600 7200 0 EET}
+    {986076000 10800 1 EEST}
+    {1001883600 7200 0 EET}
+    {1017612000 10800 1 EEST}
+    {1033419600 7200 0 EET}
+    {1049148000 10800 1 EEST}
+    {1064955600 7200 0 EET}
+    {1080770400 10800 1 EEST}
+    {1096578000 7200 0 EET}
+    {1112306400 10800 1 EEST}
+    {1128114000 7200 0 EET}
+    {1143842400 10800 1 EEST}
+    {1158872400 7200 0 EET}
+    {1175205600 10800 1 EEST}
+    {1193950800 7200 0 EET}
+    {1207260000 10800 1 EEST}
+    {1225486800 7200 0 EET}
+    {1238104800 10800 1 EEST}
+    {1256850000 7200 0 EET}
+    {1270159200 10800 1 EEST}
+    {1288299600 7200 0 EET}
+    {1301608800 10800 1 EEST}
+    {1319749200 7200 0 EET}
+    {1333058400 10800 1 EEST}
+    {1351198800 7200 0 EET}
+    {1364508000 10800 1 EEST}
+    {1382648400 7200 0 EET}
+    {1395957600 10800 1 EEST}
+    {1414702800 7200 0 EET}
+    {1427407200 10800 1 EEST}
+    {1446152400 7200 0 EET}
+    {1458856800 10800 1 EEST}
+    {1477602000 7200 0 EET}
+    {1490911200 10800 1 EEST}
+    {1509051600 7200 0 EET}
+    {1522360800 10800 1 EEST}
+    {1540501200 7200 0 EET}
+    {1553810400 10800 1 EEST}
+    {1571950800 7200 0 EET}
+    {1585260000 10800 1 EEST}
+    {1604005200 7200 0 EET}
+    {1616709600 10800 1 EEST}
+    {1635454800 7200 0 EET}
+    {1648159200 10800 1 EEST}
+    {1666904400 7200 0 EET}
+    {1680213600 10800 1 EEST}
+    {1698354000 7200 0 EET}
+    {1711663200 10800 1 EEST}
+    {1729803600 7200 0 EET}
+    {1743112800 10800 1 EEST}
+    {1761858000 7200 0 EET}
+    {1774562400 10800 1 EEST}
+    {1793307600 7200 0 EET}
+    {1806012000 10800 1 EEST}
+    {1824757200 7200 0 EET}
+    {1838066400 10800 1 EEST}
+    {1856206800 7200 0 EET}
+    {1869516000 10800 1 EEST}
+    {1887656400 7200 0 EET}
+    {1900965600 10800 1 EEST}
+    {1919106000 7200 0 EET}
+    {1932415200 10800 1 EEST}
+    {1951160400 7200 0 EET}
+    {1963864800 10800 1 EEST}
+    {1982610000 7200 0 EET}
+    {1995314400 10800 1 EEST}
+    {2014059600 7200 0 EET}
+    {2027368800 10800 1 EEST}
+    {2045509200 7200 0 EET}
+    {2058818400 10800 1 EEST}
+    {2076958800 7200 0 EET}
+    {2090268000 10800 1 EEST}
+    {2109013200 7200 0 EET}
+    {2121717600 10800 1 EEST}
+    {2140462800 7200 0 EET}
+    {2153167200 10800 1 EEST}
+    {2171912400 7200 0 EET}
+    {2184616800 10800 1 EEST}
+    {2203362000 7200 0 EET}
+    {2216671200 10800 1 EEST}
+    {2234811600 7200 0 EET}
+    {2248120800 10800 1 EEST}
+    {2266261200 7200 0 EET}
+    {2279570400 10800 1 EEST}
+    {2298315600 7200 0 EET}
+    {2311020000 10800 1 EEST}
+    {2329765200 7200 0 EET}
+    {2342469600 10800 1 EEST}
+    {2361214800 7200 0 EET}
+    {2374524000 10800 1 EEST}
+    {2392664400 7200 0 EET}
+    {2405973600 10800 1 EEST}
+    {2424114000 7200 0 EET}
+    {2437423200 10800 1 EEST}
+    {2455563600 7200 0 EET}
+    {2468872800 10800 1 EEST}
+    {2487618000 7200 0 EET}
+    {2500322400 10800 1 EEST}
+    {2519067600 7200 0 EET}
+    {2531772000 10800 1 EEST}
+    {2550517200 7200 0 EET}
+    {2563826400 10800 1 EEST}
+    {2581966800 7200 0 EET}
+    {2595276000 10800 1 EEST}
+    {2613416400 7200 0 EET}
+    {2626725600 10800 1 EEST}
+    {2645470800 7200 0 EET}
+    {2658175200 10800 1 EEST}
+    {2676920400 7200 0 EET}
+    {2689624800 10800 1 EEST}
+    {2708370000 7200 0 EET}
+    {2721679200 10800 1 EEST}
+    {2739819600 7200 0 EET}
+    {2753128800 10800 1 EEST}
+    {2771269200 7200 0 EET}
+    {2784578400 10800 1 EEST}
+    {2802718800 7200 0 EET}
+    {2816028000 10800 1 EEST}
+    {2834773200 7200 0 EET}
+    {2847477600 10800 1 EEST}
+    {2866222800 7200 0 EET}
+    {2878927200 10800 1 EEST}
+    {2897672400 7200 0 EET}
+    {2910981600 10800 1 EEST}
+    {2929122000 7200 0 EET}
+    {2942431200 10800 1 EEST}
+    {2960571600 7200 0 EET}
+    {2973880800 10800 1 EEST}
+    {2992626000 7200 0 EET}
+    {3005330400 10800 1 EEST}
+    {3024075600 7200 0 EET}
+    {3036780000 10800 1 EEST}
+    {3055525200 7200 0 EET}
+    {3068229600 10800 1 EEST}
+    {3086974800 7200 0 EET}
+    {3100284000 10800 1 EEST}
+    {3118424400 7200 0 EET}
+    {3131733600 10800 1 EEST}
+    {3149874000 7200 0 EET}
+    {3163183200 10800 1 EEST}
+    {3181928400 7200 0 EET}
+    {3194632800 10800 1 EEST}
+    {3213378000 7200 0 EET}
+    {3226082400 10800 1 EEST}
+    {3244827600 7200 0 EET}
+    {3258136800 10800 1 EEST}
+    {3276277200 7200 0 EET}
+    {3289586400 10800 1 EEST}
+    {3307726800 7200 0 EET}
+    {3321036000 10800 1 EEST}
+    {3339176400 7200 0 EET}
+    {3352485600 10800 1 EEST}
+    {3371230800 7200 0 EET}
+    {3383935200 10800 1 EEST}
+    {3402680400 7200 0 EET}
+    {3415384800 10800 1 EEST}
+    {3434130000 7200 0 EET}
+    {3447439200 10800 1 EEST}
+    {3465579600 7200 0 EET}
+    {3478888800 10800 1 EEST}
+    {3497029200 7200 0 EET}
+    {3510338400 10800 1 EEST}
+    {3529083600 7200 0 EET}
+    {3541788000 10800 1 EEST}
+    {3560533200 7200 0 EET}
+    {3573237600 10800 1 EEST}
+    {3591982800 7200 0 EET}
+    {3605292000 10800 1 EEST}
+    {3623432400 7200 0 EET}
+    {3636741600 10800 1 EEST}
+    {3654882000 7200 0 EET}
+    {3668191200 10800 1 EEST}
+    {3686331600 7200 0 EET}
+    {3699640800 10800 1 EEST}
+    {3718386000 7200 0 EET}
+    {3731090400 10800 1 EEST}
+    {3749835600 7200 0 EET}
+    {3762540000 10800 1 EEST}
+    {3781285200 7200 0 EET}
+    {3794594400 10800 1 EEST}
+    {3812734800 7200 0 EET}
+    {3826044000 10800 1 EEST}
+    {3844184400 7200 0 EET}
+    {3857493600 10800 1 EEST}
+    {3876238800 7200 0 EET}
+    {3888943200 10800 1 EEST}
+    {3907688400 7200 0 EET}
+    {3920392800 10800 1 EEST}
+    {3939138000 7200 0 EET}
+    {3951842400 10800 1 EEST}
+    {3970587600 7200 0 EET}
+    {3983896800 10800 1 EEST}
+    {4002037200 7200 0 EET}
+    {4015346400 10800 1 EEST}
+    {4033486800 7200 0 EET}
+    {4046796000 10800 1 EEST}
+    {4065541200 7200 0 EET}
+    {4078245600 10800 1 EEST}
+    {4096990800 7200 0 EET}
+}
diff --git a/library/tzdata/Asia/Dhaka b/library/tzdata/Asia/Dhaka
new file mode 100644
index 0000000..6e8a334
--- /dev/null
+++ b/library/tzdata/Asia/Dhaka
@@ -0,0 +1,14 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Asia/Dhaka) {
+    {-9223372036854775808 21700 0 LMT}
+    {-2524543300 21200 0 HMT}
+    {-891582800 23400 0 BURT}
+    {-872058600 19800 0 IST}
+    {-862637400 23400 0 BURT}
+    {-576138600 21600 0 DACT}
+    {38772000 21600 0 BDT}
+    {1230746400 21600 0 BDT}
+    {1245430800 25200 1 BDST}
+    {1262278800 21600 0 BDT}
+}
diff --git a/library/tzdata/Asia/Dili b/library/tzdata/Asia/Dili
new file mode 100644
index 0000000..f783557
--- /dev/null
+++ b/library/tzdata/Asia/Dili
@@ -0,0 +1,10 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Asia/Dili) {
+    {-9223372036854775808 30140 0 LMT}
+    {-1830414140 28800 0 TLT}
+    {-879152400 32400 0 JST}
+    {-766054800 32400 0 TLT}
+    {199897200 28800 0 WITA}
+    {969120000 32400 0 TLT}
+}
diff --git a/library/tzdata/Asia/Dubai b/library/tzdata/Asia/Dubai
new file mode 100644
index 0000000..b8730e5
--- /dev/null
+++ b/library/tzdata/Asia/Dubai
@@ -0,0 +1,6 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Asia/Dubai) {
+    {-9223372036854775808 13272 0 LMT}
+    {-1577936472 14400 0 GST}
+}
diff --git a/library/tzdata/Asia/Dushanbe b/library/tzdata/Asia/Dushanbe
new file mode 100644
index 0000000..59f8cb6
--- /dev/null
+++ b/library/tzdata/Asia/Dushanbe
@@ -0,0 +1,29 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Asia/Dushanbe) {
+    {-9223372036854775808 16512 0 LMT}
+    {-1441168512 18000 0 DUST}
+    {-1247547600 21600 0 DUST}
+    {354909600 25200 1 DUSST}
+    {370717200 21600 0 DUST}
+    {386445600 25200 1 DUSST}
+    {402253200 21600 0 DUST}
+    {417981600 25200 1 DUSST}
+    {433789200 21600 0 DUST}
+    {449604000 25200 1 DUSST}
+    {465336000 21600 0 DUST}
+    {481060800 25200 1 DUSST}
+    {496785600 21600 0 DUST}
+    {512510400 25200 1 DUSST}
+    {528235200 21600 0 DUST}
+    {543960000 25200 1 DUSST}
+    {559684800 21600 0 DUST}
+    {575409600 25200 1 DUSST}
+    {591134400 21600 0 DUST}
+    {606859200 25200 1 DUSST}
+    {622584000 21600 0 DUST}
+    {638308800 25200 1 DUSST}
+    {654638400 21600 0 DUST}
+    {670363200 21600 1 DUSST}
+    {684363600 18000 0 TJT}
+}
diff --git a/library/tzdata/Asia/Gaza b/library/tzdata/Asia/Gaza
new file mode 100644
index 0000000..6adfe6d
--- /dev/null
+++ b/library/tzdata/Asia/Gaza
@@ -0,0 +1,278 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Asia/Gaza) {
+    {-9223372036854775808 8272 0 LMT}
+    {-2185409872 7200 0 EET}
+    {-933645600 10800 1 EET}
+    {-857358000 7200 0 EET}
+    {-844300800 10800 1 EET}
+    {-825822000 7200 0 EET}
+    {-812685600 10800 1 EET}
+    {-794199600 7200 0 EET}
+    {-779853600 10800 1 EET}
+    {-762656400 7200 0 EET}
+    {-748310400 10800 1 EET}
+    {-731127600 7200 0 EET}
+    {-682653600 7200 0 EET}
+    {-399088800 10800 1 EEST}
+    {-386650800 7200 0 EET}
+    {-368330400 10800 1 EEST}
+    {-355114800 7200 0 EET}
+    {-336790800 10800 1 EEST}
+    {-323654400 7200 0 EET}
+    {-305168400 10800 1 EEST}
+    {-292032000 7200 0 EET}
+    {-273632400 10800 1 EEST}
+    {-260496000 7200 0 EET}
+    {-242096400 10800 1 EEST}
+    {-228960000 7200 0 EET}
+    {-210560400 10800 1 EEST}
+    {-197424000 7200 0 EET}
+    {-178938000 10800 1 EEST}
+    {-165801600 7200 0 EET}
+    {-147402000 10800 1 EEST}
+    {-134265600 7200 0 EET}
+    {-115866000 10800 1 EEST}
+    {-102643200 7200 0 EET}
+    {-84330000 10800 1 EEST}
+    {-81313200 10800 0 IST}
+    {142376400 10800 1 IDT}
+    {150843600 7200 0 IST}
+    {167176800 10800 1 IDT}
+    {178664400 7200 0 IST}
+    {482277600 10800 1 IDT}
+    {495579600 7200 0 IST}
+    {516751200 10800 1 IDT}
+    {526424400 7200 0 IST}
+    {545436000 10800 1 IDT}
+    {558478800 7200 0 IST}
+    {576626400 10800 1 IDT}
+    {589323600 7200 0 IST}
+    {609890400 10800 1 IDT}
+    {620773200 7200 0 IST}
+    {638316000 10800 1 IDT}
+    {651618000 7200 0 IST}
+    {669765600 10800 1 IDT}
+    {683672400 7200 0 IST}
+    {701820000 10800 1 IDT}
+    {715726800 7200 0 IST}
+    {733701600 10800 1 IDT}
+    {747176400 7200 0 IST}
+    {765151200 10800 1 IDT}
+    {778021200 7200 0 IST}
+    {796600800 10800 1 IDT}
+    {810075600 7200 0 IST}
+    {820447200 7200 0 EET}
+    {828655200 10800 1 EEST}
+    {843170400 7200 0 EET}
+    {860104800 10800 1 EEST}
+    {874620000 7200 0 EET}
+    {891554400 10800 1 EEST}
+    {906069600 7200 0 EET}
+    {915141600 7200 0 EET}
+    {924213600 10800 1 EEST}
+    {939934800 7200 0 EET}
+    {956268000 10800 1 EEST}
+    {971989200 7200 0 EET}
+    {987717600 10800 1 EEST}
+    {1003438800 7200 0 EET}
+    {1019167200 10800 1 EEST}
+    {1034888400 7200 0 EET}
+    {1050616800 10800 1 EEST}
+    {1066338000 7200 0 EET}
+    {1082066400 10800 1 EEST}
+    {1096581600 7200 0 EET}
+    {1113516000 10800 1 EEST}
+    {1128380400 7200 0 EET}
+    {1143842400 10800 1 EEST}
+    {1158872400 7200 0 EET}
+    {1175378400 10800 1 EEST}
+    {1189638000 7200 0 EET}
+    {1206655200 10800 1 EEST}
+    {1219960800 7200 0 EET}
+    {1220220000 7200 0 EET}
+    {1238104800 10800 1 EEST}
+    {1252015200 7200 0 EET}
+    {1262296800 7200 0 EET}
+    {1269640860 10800 0 EEST}
+    {1281474000 7200 0 EET}
+    {1301608860 10800 1 EEST}
+    {1312149600 7200 0 EET}
+    {1325368800 7200 0 EET}
+    {1333058400 10800 1 EEST}
+    {1348178400 7200 0 EET}
+    {1364508000 10800 1 EEST}
+    {1380229200 7200 0 EET}
+    {1395957600 10800 1 EEST}
+    {1414098000 7200 0 EET}
+    {1427493600 10800 1 EEST}
+    {1445547600 7200 0 EET}
+    {1458946800 10800 1 EEST}
+    {1476997200 7200 0 EET}
+    {1490396400 10800 1 EEST}
+    {1509051600 7200 0 EET}
+    {1522450800 10800 1 EEST}
+    {1540501200 7200 0 EET}
+    {1553900400 10800 1 EEST}
+    {1571950800 7200 0 EET}
+    {1585350000 10800 1 EEST}
+    {1603400400 7200 0 EET}
+    {1616799600 10800 1 EEST}
+    {1634850000 7200 0 EET}
+    {1648249200 10800 1 EEST}
+    {1666299600 7200 0 EET}
+    {1679698800 10800 1 EEST}
+    {1698354000 7200 0 EET}
+    {1711753200 10800 1 EEST}
+    {1729803600 7200 0 EET}
+    {1743202800 10800 1 EEST}
+    {1761253200 7200 0 EET}
+    {1774652400 10800 1 EEST}
+    {1792702800 7200 0 EET}
+    {1806102000 10800 1 EEST}
+    {1824152400 7200 0 EET}
+    {1837551600 10800 1 EEST}
+    {1856206800 7200 0 EET}
+    {1869606000 10800 1 EEST}
+    {1887656400 7200 0 EET}
+    {1901055600 10800 1 EEST}
+    {1919106000 7200 0 EET}
+    {1932505200 10800 1 EEST}
+    {1950555600 7200 0 EET}
+    {1963954800 10800 1 EEST}
+    {1982005200 7200 0 EET}
+    {1995404400 10800 1 EEST}
+    {2013454800 7200 0 EET}
+    {2026854000 10800 1 EEST}
+    {2045509200 7200 0 EET}
+    {2058908400 10800 1 EEST}
+    {2076958800 7200 0 EET}
+    {2090358000 10800 1 EEST}
+    {2108408400 7200 0 EET}
+    {2121807600 10800 1 EEST}
+    {2139858000 7200 0 EET}
+    {2153257200 10800 1 EEST}
+    {2171307600 7200 0 EET}
+    {2184706800 10800 1 EEST}
+    {2202757200 7200 0 EET}
+    {2216761200 10800 1 EEST}
+    {2234811600 7200 0 EET}
+    {2248210800 10800 1 EEST}
+    {2266261200 7200 0 EET}
+    {2279660400 10800 1 EEST}
+    {2297710800 7200 0 EET}
+    {2311110000 10800 1 EEST}
+    {2329160400 7200 0 EET}
+    {2342559600 10800 1 EEST}
+    {2360610000 7200 0 EET}
+    {2374009200 10800 1 EEST}
+    {2392664400 7200 0 EET}
+    {2406063600 10800 1 EEST}
+    {2424114000 7200 0 EET}
+    {2437513200 10800 1 EEST}
+    {2455563600 7200 0 EET}
+    {2468962800 10800 1 EEST}
+    {2487013200 7200 0 EET}
+    {2500412400 10800 1 EEST}
+    {2518462800 7200 0 EET}
+    {2531862000 10800 1 EEST}
+    {2549912400 7200 0 EET}
+    {2563311600 10800 1 EEST}
+    {2581966800 7200 0 EET}
+    {2595366000 10800 1 EEST}
+    {2613416400 7200 0 EET}
+    {2626815600 10800 1 EEST}
+    {2644866000 7200 0 EET}
+    {2658265200 10800 1 EEST}
+    {2676315600 7200 0 EET}
+    {2689714800 10800 1 EEST}
+    {2707765200 7200 0 EET}
+    {2721164400 10800 1 EEST}
+    {2739819600 7200 0 EET}
+    {2753218800 10800 1 EEST}
+    {2771269200 7200 0 EET}
+    {2784668400 10800 1 EEST}
+    {2802718800 7200 0 EET}
+    {2816118000 10800 1 EEST}
+    {2834168400 7200 0 EET}
+    {2847567600 10800 1 EEST}
+    {2865618000 7200 0 EET}
+    {2879017200 10800 1 EEST}
+    {2897067600 7200 0 EET}
+    {2910466800 10800 1 EEST}
+    {2929122000 7200 0 EET}
+    {2942521200 10800 1 EEST}
+    {2960571600 7200 0 EET}
+    {2973970800 10800 1 EEST}
+    {2992021200 7200 0 EET}
+    {3005420400 10800 1 EEST}
+    {3023470800 7200 0 EET}
+    {3036870000 10800 1 EEST}
+    {3054920400 7200 0 EET}
+    {3068319600 10800 1 EEST}
+    {3086370000 7200 0 EET}
+    {3100374000 10800 1 EEST}
+    {3118424400 7200 0 EET}
+    {3131823600 10800 1 EEST}
+    {3149874000 7200 0 EET}
+    {3163273200 10800 1 EEST}
+    {3181323600 7200 0 EET}
+    {3194722800 10800 1 EEST}
+    {3212773200 7200 0 EET}
+    {3226172400 10800 1 EEST}
+    {3244222800 7200 0 EET}
+    {3257622000 10800 1 EEST}
+    {3276277200 7200 0 EET}
+    {3289676400 10800 1 EEST}
+    {3307726800 7200 0 EET}
+    {3321126000 10800 1 EEST}
+    {3339176400 7200 0 EET}
+    {3352575600 10800 1 EEST}
+    {3370626000 7200 0 EET}
+    {3384025200 10800 1 EEST}
+    {3402075600 7200 0 EET}
+    {3415474800 10800 1 EEST}
+    {3433525200 7200 0 EET}
+    {3446924400 10800 1 EEST}
+    {3465579600 7200 0 EET}
+    {3478978800 10800 1 EEST}
+    {3497029200 7200 0 EET}
+    {3510428400 10800 1 EEST}
+    {3528478800 7200 0 EET}
+    {3541878000 10800 1 EEST}
+    {3559928400 7200 0 EET}
+    {3573327600 10800 1 EEST}
+    {3591378000 7200 0 EET}
+    {3604777200 10800 1 EEST}
+    {3623432400 7200 0 EET}
+    {3636831600 10800 1 EEST}
+    {3654882000 7200 0 EET}
+    {3668281200 10800 1 EEST}
+    {3686331600 7200 0 EET}
+    {3699730800 10800 1 EEST}
+    {3717781200 7200 0 EET}
+    {3731180400 10800 1 EEST}
+    {3749230800 7200 0 EET}
+    {3762630000 10800 1 EEST}
+    {3780680400 7200 0 EET}
+    {3794079600 10800 1 EEST}
+    {3812734800 7200 0 EET}
+    {3826134000 10800 1 EEST}
+    {3844184400 7200 0 EET}
+    {3857583600 10800 1 EEST}
+    {3875634000 7200 0 EET}
+    {3889033200 10800 1 EEST}
+    {3907083600 7200 0 EET}
+    {3920482800 10800 1 EEST}
+    {3938533200 7200 0 EET}
+    {3951932400 10800 1 EEST}
+    {3969982800 7200 0 EET}
+    {3983986800 10800 1 EEST}
+    {4002037200 7200 0 EET}
+    {4015436400 10800 1 EEST}
+    {4033486800 7200 0 EET}
+    {4046886000 10800 1 EEST}
+    {4064936400 7200 0 EET}
+    {4078335600 10800 1 EEST}
+    {4096386000 7200 0 EET}
+}
diff --git a/library/tzdata/Asia/Harbin b/library/tzdata/Asia/Harbin
new file mode 100644
index 0000000..dfcb549
--- /dev/null
+++ b/library/tzdata/Asia/Harbin
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Asia/Shanghai)]} {
+    LoadTimeZoneFile Asia/Shanghai
+}
+set TZData(:Asia/Harbin) $TZData(:Asia/Shanghai)
diff --git a/library/tzdata/Asia/Hebron b/library/tzdata/Asia/Hebron
new file mode 100644
index 0000000..2db45f2
--- /dev/null
+++ b/library/tzdata/Asia/Hebron
@@ -0,0 +1,277 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Asia/Hebron) {
+    {-9223372036854775808 8423 0 LMT}
+    {-2185410023 7200 0 EET}
+    {-933645600 10800 1 EET}
+    {-857358000 7200 0 EET}
+    {-844300800 10800 1 EET}
+    {-825822000 7200 0 EET}
+    {-812685600 10800 1 EET}
+    {-794199600 7200 0 EET}
+    {-779853600 10800 1 EET}
+    {-762656400 7200 0 EET}
+    {-748310400 10800 1 EET}
+    {-731127600 7200 0 EET}
+    {-682653600 7200 0 EET}
+    {-399088800 10800 1 EEST}
+    {-386650800 7200 0 EET}
+    {-368330400 10800 1 EEST}
+    {-355114800 7200 0 EET}
+    {-336790800 10800 1 EEST}
+    {-323654400 7200 0 EET}
+    {-305168400 10800 1 EEST}
+    {-292032000 7200 0 EET}
+    {-273632400 10800 1 EEST}
+    {-260496000 7200 0 EET}
+    {-242096400 10800 1 EEST}
+    {-228960000 7200 0 EET}
+    {-210560400 10800 1 EEST}
+    {-197424000 7200 0 EET}
+    {-178938000 10800 1 EEST}
+    {-165801600 7200 0 EET}
+    {-147402000 10800 1 EEST}
+    {-134265600 7200 0 EET}
+    {-115866000 10800 1 EEST}
+    {-102643200 7200 0 EET}
+    {-84330000 10800 1 EEST}
+    {-81313200 10800 0 IST}
+    {142376400 10800 1 IDT}
+    {150843600 7200 0 IST}
+    {167176800 10800 1 IDT}
+    {178664400 7200 0 IST}
+    {482277600 10800 1 IDT}
+    {495579600 7200 0 IST}
+    {516751200 10800 1 IDT}
+    {526424400 7200 0 IST}
+    {545436000 10800 1 IDT}
+    {558478800 7200 0 IST}
+    {576626400 10800 1 IDT}
+    {589323600 7200 0 IST}
+    {609890400 10800 1 IDT}
+    {620773200 7200 0 IST}
+    {638316000 10800 1 IDT}
+    {651618000 7200 0 IST}
+    {669765600 10800 1 IDT}
+    {683672400 7200 0 IST}
+    {701820000 10800 1 IDT}
+    {715726800 7200 0 IST}
+    {733701600 10800 1 IDT}
+    {747176400 7200 0 IST}
+    {765151200 10800 1 IDT}
+    {778021200 7200 0 IST}
+    {796600800 10800 1 IDT}
+    {810075600 7200 0 IST}
+    {820447200 7200 0 EET}
+    {828655200 10800 1 EEST}
+    {843170400 7200 0 EET}
+    {860104800 10800 1 EEST}
+    {874620000 7200 0 EET}
+    {891554400 10800 1 EEST}
+    {906069600 7200 0 EET}
+    {915141600 7200 0 EET}
+    {924213600 10800 1 EEST}
+    {939934800 7200 0 EET}
+    {956268000 10800 1 EEST}
+    {971989200 7200 0 EET}
+    {987717600 10800 1 EEST}
+    {1003438800 7200 0 EET}
+    {1019167200 10800 1 EEST}
+    {1034888400 7200 0 EET}
+    {1050616800 10800 1 EEST}
+    {1066338000 7200 0 EET}
+    {1082066400 10800 1 EEST}
+    {1096581600 7200 0 EET}
+    {1113516000 10800 1 EEST}
+    {1128380400 7200 0 EET}
+    {1143842400 10800 1 EEST}
+    {1158872400 7200 0 EET}
+    {1175378400 10800 1 EEST}
+    {1189638000 7200 0 EET}
+    {1206655200 10800 1 EEST}
+    {1220216400 7200 0 EET}
+    {1238104800 10800 1 EEST}
+    {1252015200 7200 0 EET}
+    {1269554400 10800 1 EEST}
+    {1281474000 7200 0 EET}
+    {1301608860 10800 1 EEST}
+    {1312146000 7200 0 EET}
+    {1314655200 10800 1 EEST}
+    {1317330000 7200 0 EET}
+    {1333058400 10800 1 EEST}
+    {1348178400 7200 0 EET}
+    {1364508000 10800 1 EEST}
+    {1380229200 7200 0 EET}
+    {1395957600 10800 1 EEST}
+    {1414098000 7200 0 EET}
+    {1427493600 10800 1 EEST}
+    {1445547600 7200 0 EET}
+    {1458946800 10800 1 EEST}
+    {1476997200 7200 0 EET}
+    {1490396400 10800 1 EEST}
+    {1509051600 7200 0 EET}
+    {1522450800 10800 1 EEST}
+    {1540501200 7200 0 EET}
+    {1553900400 10800 1 EEST}
+    {1571950800 7200 0 EET}
+    {1585350000 10800 1 EEST}
+    {1603400400 7200 0 EET}
+    {1616799600 10800 1 EEST}
+    {1634850000 7200 0 EET}
+    {1648249200 10800 1 EEST}
+    {1666299600 7200 0 EET}
+    {1679698800 10800 1 EEST}
+    {1698354000 7200 0 EET}
+    {1711753200 10800 1 EEST}
+    {1729803600 7200 0 EET}
+    {1743202800 10800 1 EEST}
+    {1761253200 7200 0 EET}
+    {1774652400 10800 1 EEST}
+    {1792702800 7200 0 EET}
+    {1806102000 10800 1 EEST}
+    {1824152400 7200 0 EET}
+    {1837551600 10800 1 EEST}
+    {1856206800 7200 0 EET}
+    {1869606000 10800 1 EEST}
+    {1887656400 7200 0 EET}
+    {1901055600 10800 1 EEST}
+    {1919106000 7200 0 EET}
+    {1932505200 10800 1 EEST}
+    {1950555600 7200 0 EET}
+    {1963954800 10800 1 EEST}
+    {1982005200 7200 0 EET}
+    {1995404400 10800 1 EEST}
+    {2013454800 7200 0 EET}
+    {2026854000 10800 1 EEST}
+    {2045509200 7200 0 EET}
+    {2058908400 10800 1 EEST}
+    {2076958800 7200 0 EET}
+    {2090358000 10800 1 EEST}
+    {2108408400 7200 0 EET}
+    {2121807600 10800 1 EEST}
+    {2139858000 7200 0 EET}
+    {2153257200 10800 1 EEST}
+    {2171307600 7200 0 EET}
+    {2184706800 10800 1 EEST}
+    {2202757200 7200 0 EET}
+    {2216761200 10800 1 EEST}
+    {2234811600 7200 0 EET}
+    {2248210800 10800 1 EEST}
+    {2266261200 7200 0 EET}
+    {2279660400 10800 1 EEST}
+    {2297710800 7200 0 EET}
+    {2311110000 10800 1 EEST}
+    {2329160400 7200 0 EET}
+    {2342559600 10800 1 EEST}
+    {2360610000 7200 0 EET}
+    {2374009200 10800 1 EEST}
+    {2392664400 7200 0 EET}
+    {2406063600 10800 1 EEST}
+    {2424114000 7200 0 EET}
+    {2437513200 10800 1 EEST}
+    {2455563600 7200 0 EET}
+    {2468962800 10800 1 EEST}
+    {2487013200 7200 0 EET}
+    {2500412400 10800 1 EEST}
+    {2518462800 7200 0 EET}
+    {2531862000 10800 1 EEST}
+    {2549912400 7200 0 EET}
+    {2563311600 10800 1 EEST}
+    {2581966800 7200 0 EET}
+    {2595366000 10800 1 EEST}
+    {2613416400 7200 0 EET}
+    {2626815600 10800 1 EEST}
+    {2644866000 7200 0 EET}
+    {2658265200 10800 1 EEST}
+    {2676315600 7200 0 EET}
+    {2689714800 10800 1 EEST}
+    {2707765200 7200 0 EET}
+    {2721164400 10800 1 EEST}
+    {2739819600 7200 0 EET}
+    {2753218800 10800 1 EEST}
+    {2771269200 7200 0 EET}
+    {2784668400 10800 1 EEST}
+    {2802718800 7200 0 EET}
+    {2816118000 10800 1 EEST}
+    {2834168400 7200 0 EET}
+    {2847567600 10800 1 EEST}
+    {2865618000 7200 0 EET}
+    {2879017200 10800 1 EEST}
+    {2897067600 7200 0 EET}
+    {2910466800 10800 1 EEST}
+    {2929122000 7200 0 EET}
+    {2942521200 10800 1 EEST}
+    {2960571600 7200 0 EET}
+    {2973970800 10800 1 EEST}
+    {2992021200 7200 0 EET}
+    {3005420400 10800 1 EEST}
+    {3023470800 7200 0 EET}
+    {3036870000 10800 1 EEST}
+    {3054920400 7200 0 EET}
+    {3068319600 10800 1 EEST}
+    {3086370000 7200 0 EET}
+    {3100374000 10800 1 EEST}
+    {3118424400 7200 0 EET}
+    {3131823600 10800 1 EEST}
+    {3149874000 7200 0 EET}
+    {3163273200 10800 1 EEST}
+    {3181323600 7200 0 EET}
+    {3194722800 10800 1 EEST}
+    {3212773200 7200 0 EET}
+    {3226172400 10800 1 EEST}
+    {3244222800 7200 0 EET}
+    {3257622000 10800 1 EEST}
+    {3276277200 7200 0 EET}
+    {3289676400 10800 1 EEST}
+    {3307726800 7200 0 EET}
+    {3321126000 10800 1 EEST}
+    {3339176400 7200 0 EET}
+    {3352575600 10800 1 EEST}
+    {3370626000 7200 0 EET}
+    {3384025200 10800 1 EEST}
+    {3402075600 7200 0 EET}
+    {3415474800 10800 1 EEST}
+    {3433525200 7200 0 EET}
+    {3446924400 10800 1 EEST}
+    {3465579600 7200 0 EET}
+    {3478978800 10800 1 EEST}
+    {3497029200 7200 0 EET}
+    {3510428400 10800 1 EEST}
+    {3528478800 7200 0 EET}
+    {3541878000 10800 1 EEST}
+    {3559928400 7200 0 EET}
+    {3573327600 10800 1 EEST}
+    {3591378000 7200 0 EET}
+    {3604777200 10800 1 EEST}
+    {3623432400 7200 0 EET}
+    {3636831600 10800 1 EEST}
+    {3654882000 7200 0 EET}
+    {3668281200 10800 1 EEST}
+    {3686331600 7200 0 EET}
+    {3699730800 10800 1 EEST}
+    {3717781200 7200 0 EET}
+    {3731180400 10800 1 EEST}
+    {3749230800 7200 0 EET}
+    {3762630000 10800 1 EEST}
+    {3780680400 7200 0 EET}
+    {3794079600 10800 1 EEST}
+    {3812734800 7200 0 EET}
+    {3826134000 10800 1 EEST}
+    {3844184400 7200 0 EET}
+    {3857583600 10800 1 EEST}
+    {3875634000 7200 0 EET}
+    {3889033200 10800 1 EEST}
+    {3907083600 7200 0 EET}
+    {3920482800 10800 1 EEST}
+    {3938533200 7200 0 EET}
+    {3951932400 10800 1 EEST}
+    {3969982800 7200 0 EET}
+    {3983986800 10800 1 EEST}
+    {4002037200 7200 0 EET}
+    {4015436400 10800 1 EEST}
+    {4033486800 7200 0 EET}
+    {4046886000 10800 1 EEST}
+    {4064936400 7200 0 EET}
+    {4078335600 10800 1 EEST}
+    {4096386000 7200 0 EET}
+}
diff --git a/library/tzdata/Asia/Ho_Chi_Minh b/library/tzdata/Asia/Ho_Chi_Minh
new file mode 100644
index 0000000..9da89f4
--- /dev/null
+++ b/library/tzdata/Asia/Ho_Chi_Minh
@@ -0,0 +1,14 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Asia/Ho_Chi_Minh) {
+    {-9223372036854775808 25600 0 LMT}
+    {-2004073600 25590 0 PLMT}
+    {-1851577590 25200 0 ICT}
+    {-852105600 28800 0 IDT}
+    {-782643600 32400 0 JST}
+    {-767869200 25200 0 ICT}
+    {-718095600 28800 0 IDT}
+    {-457776000 25200 0 ICT}
+    {-315648000 28800 0 IDT}
+    {171820800 25200 0 ICT}
+}
diff --git a/library/tzdata/Asia/Hong_Kong b/library/tzdata/Asia/Hong_Kong
new file mode 100644
index 0000000..fcf98a6
--- /dev/null
+++ b/library/tzdata/Asia/Hong_Kong
@@ -0,0 +1,75 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Asia/Hong_Kong) {
+    {-9223372036854775808 27402 0 LMT}
+    {-2056693002 28800 0 HKT}
+    {-907389000 32400 1 HKST}
+    {-891667800 28800 0 HKT}
+    {-884246400 32400 0 JST}
+    {-766746000 28800 0 HKT}
+    {-747981000 32400 1 HKST}
+    {-728544600 28800 0 HKT}
+    {-717049800 32400 1 HKST}
+    {-694503000 28800 0 HKT}
+    {-683785800 32400 1 HKST}
+    {-668064600 28800 0 HKT}
+    {-654755400 32400 1 HKST}
+    {-636615000 28800 0 HKT}
+    {-623305800 32400 1 HKST}
+    {-605165400 28800 0 HKT}
+    {-591856200 32400 1 HKST}
+    {-573715800 28800 0 HKT}
+    {-559801800 32400 1 HKST}
+    {-542352600 28800 0 HKT}
+    {-528352200 32400 1 HKST}
+    {-510211800 28800 0 HKT}
+    {-498112200 32400 1 HKST}
+    {-478762200 28800 0 HKT}
+    {-466662600 32400 1 HKST}
+    {-446707800 28800 0 HKT}
+    {-435213000 32400 1 HKST}
+    {-415258200 28800 0 HKT}
+    {-403158600 32400 1 HKST}
+    {-383808600 28800 0 HKT}
+    {-371709000 32400 1 HKST}
+    {-352359000 28800 0 HKT}
+    {-340259400 32400 1 HKST}
+    {-320909400 28800 0 HKT}
+    {-308809800 32400 1 HKST}
+    {-288855000 28800 0 HKT}
+    {-277360200 32400 1 HKST}
+    {-257405400 28800 0 HKT}
+    {-245910600 32400 1 HKST}
+    {-225955800 28800 0 HKT}
+    {-213856200 32400 1 HKST}
+    {-194506200 28800 0 HKT}
+    {-182406600 32400 1 HKST}
+    {-163056600 28800 0 HKT}
+    {-148537800 32400 1 HKST}
+    {-132816600 28800 0 HKT}
+    {-117088200 32400 1 HKST}
+    {-101367000 28800 0 HKT}
+    {-85638600 32400 1 HKST}
+    {-69312600 28800 0 HKT}
+    {-53584200 32400 1 HKST}
+    {-37863000 28800 0 HKT}
+    {-22134600 32400 1 HKST}
+    {-6413400 28800 0 HKT}
+    {9315000 32400 1 HKST}
+    {25036200 28800 0 HKT}
+    {40764600 32400 1 HKST}
+    {56485800 28800 0 HKT}
+    {72214200 32400 1 HKST}
+    {88540200 28800 0 HKT}
+    {104268600 32400 1 HKST}
+    {119989800 28800 0 HKT}
+    {126041400 32400 1 HKST}
+    {135714600 32400 1 HKST}
+    {151439400 28800 0 HKT}
+    {167167800 32400 1 HKST}
+    {182889000 28800 0 HKT}
+    {198617400 32400 1 HKST}
+    {214338600 28800 0 HKT}
+    {295385400 32400 1 HKST}
+    {309292200 28800 0 HKT}
+}
diff --git a/library/tzdata/Asia/Hovd b/library/tzdata/Asia/Hovd
new file mode 100644
index 0000000..3d200a6
--- /dev/null
+++ b/library/tzdata/Asia/Hovd
@@ -0,0 +1,221 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Asia/Hovd) {
+    {-9223372036854775808 21996 0 LMT}
+    {-2032927596 21600 0 HOVT}
+    {252439200 25200 0 HOVT}
+    {417978000 28800 1 HOVST}
+    {433785600 25200 0 HOVT}
+    {449600400 28800 1 HOVST}
+    {465321600 25200 0 HOVT}
+    {481050000 28800 1 HOVST}
+    {496771200 25200 0 HOVT}
+    {512499600 28800 1 HOVST}
+    {528220800 25200 0 HOVT}
+    {543949200 28800 1 HOVST}
+    {559670400 25200 0 HOVT}
+    {575398800 28800 1 HOVST}
+    {591120000 25200 0 HOVT}
+    {606848400 28800 1 HOVST}
+    {622569600 25200 0 HOVT}
+    {638298000 28800 1 HOVST}
+    {654624000 25200 0 HOVT}
+    {670352400 28800 1 HOVST}
+    {686073600 25200 0 HOVT}
+    {701802000 28800 1 HOVST}
+    {717523200 25200 0 HOVT}
+    {733251600 28800 1 HOVST}
+    {748972800 25200 0 HOVT}
+    {764701200 28800 1 HOVST}
+    {780422400 25200 0 HOVT}
+    {796150800 28800 1 HOVST}
+    {811872000 25200 0 HOVT}
+    {828205200 28800 1 HOVST}
+    {843926400 25200 0 HOVT}
+    {859654800 28800 1 HOVST}
+    {875376000 25200 0 HOVT}
+    {891104400 28800 1 HOVST}
+    {906825600 25200 0 HOVT}
+    {988398000 28800 1 HOVST}
+    {1001700000 25200 0 HOVT}
+    {1017428400 28800 1 HOVST}
+    {1033149600 25200 0 HOVT}
+    {1048878000 28800 1 HOVST}
+    {1064599200 25200 0 HOVT}
+    {1080327600 28800 1 HOVST}
+    {1096048800 25200 0 HOVT}
+    {1111777200 28800 1 HOVST}
+    {1127498400 25200 0 HOVT}
+    {1143226800 28800 1 HOVST}
+    {1159552800 25200 0 HOVT}
+    {1427482800 28800 1 HOVST}
+    {1443196800 25200 0 HOVT}
+    {1458932400 28800 1 HOVST}
+    {1474646400 25200 0 HOVT}
+    {1490382000 28800 1 HOVST}
+    {1506700800 25200 0 HOVT}
+    {1522436400 28800 1 HOVST}
+    {1538150400 25200 0 HOVT}
+    {1553886000 28800 1 HOVST}
+    {1569600000 25200 0 HOVT}
+    {1585335600 28800 1 HOVST}
+    {1601049600 25200 0 HOVT}
+    {1616785200 28800 1 HOVST}
+    {1632499200 25200 0 HOVT}
+    {1648234800 28800 1 HOVST}
+    {1663948800 25200 0 HOVT}
+    {1679684400 28800 1 HOVST}
+    {1696003200 25200 0 HOVT}
+    {1711738800 28800 1 HOVST}
+    {1727452800 25200 0 HOVT}
+    {1743188400 28800 1 HOVST}
+    {1758902400 25200 0 HOVT}
+    {1774638000 28800 1 HOVST}
+    {1790352000 25200 0 HOVT}
+    {1806087600 28800 1 HOVST}
+    {1821801600 25200 0 HOVT}
+    {1837537200 28800 1 HOVST}
+    {1853856000 25200 0 HOVT}
+    {1869591600 28800 1 HOVST}
+    {1885305600 25200 0 HOVT}
+    {1901041200 28800 1 HOVST}
+    {1916755200 25200 0 HOVT}
+    {1932490800 28800 1 HOVST}
+    {1948204800 25200 0 HOVT}
+    {1963940400 28800 1 HOVST}
+    {1979654400 25200 0 HOVT}
+    {1995390000 28800 1 HOVST}
+    {2011104000 25200 0 HOVT}
+    {2026839600 28800 1 HOVST}
+    {2043158400 25200 0 HOVT}
+    {2058894000 28800 1 HOVST}
+    {2074608000 25200 0 HOVT}
+    {2090343600 28800 1 HOVST}
+    {2106057600 25200 0 HOVT}
+    {2121793200 28800 1 HOVST}
+    {2137507200 25200 0 HOVT}
+    {2153242800 28800 1 HOVST}
+    {2168956800 25200 0 HOVT}
+    {2184692400 28800 1 HOVST}
+    {2200406400 25200 0 HOVT}
+    {2216746800 28800 1 HOVST}
+    {2232460800 25200 0 HOVT}
+    {2248196400 28800 1 HOVST}
+    {2263910400 25200 0 HOVT}
+    {2279646000 28800 1 HOVST}
+    {2295360000 25200 0 HOVT}
+    {2311095600 28800 1 HOVST}
+    {2326809600 25200 0 HOVT}
+    {2342545200 28800 1 HOVST}
+    {2358259200 25200 0 HOVT}
+    {2373994800 28800 1 HOVST}
+    {2390313600 25200 0 HOVT}
+    {2406049200 28800 1 HOVST}
+    {2421763200 25200 0 HOVT}
+    {2437498800 28800 1 HOVST}
+    {2453212800 25200 0 HOVT}
+    {2468948400 28800 1 HOVST}
+    {2484662400 25200 0 HOVT}
+    {2500398000 28800 1 HOVST}
+    {2516112000 25200 0 HOVT}
+    {2531847600 28800 1 HOVST}
+    {2547561600 25200 0 HOVT}
+    {2563297200 28800 1 HOVST}
+    {2579616000 25200 0 HOVT}
+    {2595351600 28800 1 HOVST}
+    {2611065600 25200 0 HOVT}
+    {2626801200 28800 1 HOVST}
+    {2642515200 25200 0 HOVT}
+    {2658250800 28800 1 HOVST}
+    {2673964800 25200 0 HOVT}
+    {2689700400 28800 1 HOVST}
+    {2705414400 25200 0 HOVT}
+    {2721150000 28800 1 HOVST}
+    {2737468800 25200 0 HOVT}
+    {2753204400 28800 1 HOVST}
+    {2768918400 25200 0 HOVT}
+    {2784654000 28800 1 HOVST}
+    {2800368000 25200 0 HOVT}
+    {2816103600 28800 1 HOVST}
+    {2831817600 25200 0 HOVT}
+    {2847553200 28800 1 HOVST}
+    {2863267200 25200 0 HOVT}
+    {2879002800 28800 1 HOVST}
+    {2894716800 25200 0 HOVT}
+    {2910452400 28800 1 HOVST}
+    {2926771200 25200 0 HOVT}
+    {2942506800 28800 1 HOVST}
+    {2958220800 25200 0 HOVT}
+    {2973956400 28800 1 HOVST}
+    {2989670400 25200 0 HOVT}
+    {3005406000 28800 1 HOVST}
+    {3021120000 25200 0 HOVT}
+    {3036855600 28800 1 HOVST}
+    {3052569600 25200 0 HOVT}
+    {3068305200 28800 1 HOVST}
+    {3084019200 25200 0 HOVT}
+    {3100359600 28800 1 HOVST}
+    {3116073600 25200 0 HOVT}
+    {3131809200 28800 1 HOVST}
+    {3147523200 25200 0 HOVT}
+    {3163258800 28800 1 HOVST}
+    {3178972800 25200 0 HOVT}
+    {3194708400 28800 1 HOVST}
+    {3210422400 25200 0 HOVT}
+    {3226158000 28800 1 HOVST}
+    {3241872000 25200 0 HOVT}
+    {3257607600 28800 1 HOVST}
+    {3273926400 25200 0 HOVT}
+    {3289662000 28800 1 HOVST}
+    {3305376000 25200 0 HOVT}
+    {3321111600 28800 1 HOVST}
+    {3336825600 25200 0 HOVT}
+    {3352561200 28800 1 HOVST}
+    {3368275200 25200 0 HOVT}
+    {3384010800 28800 1 HOVST}
+    {3399724800 25200 0 HOVT}
+    {3415460400 28800 1 HOVST}
+    {3431174400 25200 0 HOVT}
+    {3446910000 28800 1 HOVST}
+    {3463228800 25200 0 HOVT}
+    {3478964400 28800 1 HOVST}
+    {3494678400 25200 0 HOVT}
+    {3510414000 28800 1 HOVST}
+    {3526128000 25200 0 HOVT}
+    {3541863600 28800 1 HOVST}
+    {3557577600 25200 0 HOVT}
+    {3573313200 28800 1 HOVST}
+    {3589027200 25200 0 HOVT}
+    {3604762800 28800 1 HOVST}
+    {3621081600 25200 0 HOVT}
+    {3636817200 28800 1 HOVST}
+    {3652531200 25200 0 HOVT}
+    {3668266800 28800 1 HOVST}
+    {3683980800 25200 0 HOVT}
+    {3699716400 28800 1 HOVST}
+    {3715430400 25200 0 HOVT}
+    {3731166000 28800 1 HOVST}
+    {3746880000 25200 0 HOVT}
+    {3762615600 28800 1 HOVST}
+    {3778329600 25200 0 HOVT}
+    {3794065200 28800 1 HOVST}
+    {3810384000 25200 0 HOVT}
+    {3826119600 28800 1 HOVST}
+    {3841833600 25200 0 HOVT}
+    {3857569200 28800 1 HOVST}
+    {3873283200 25200 0 HOVT}
+    {3889018800 28800 1 HOVST}
+    {3904732800 25200 0 HOVT}
+    {3920468400 28800 1 HOVST}
+    {3936182400 25200 0 HOVT}
+    {3951918000 28800 1 HOVST}
+    {3967632000 25200 0 HOVT}
+    {3983972400 28800 1 HOVST}
+    {3999686400 25200 0 HOVT}
+    {4015422000 28800 1 HOVST}
+    {4031136000 25200 0 HOVT}
+    {4046871600 28800 1 HOVST}
+    {4062585600 25200 0 HOVT}
+    {4078321200 28800 1 HOVST}
+    {4094035200 25200 0 HOVT}
+}
diff --git a/library/tzdata/Asia/Irkutsk b/library/tzdata/Asia/Irkutsk
new file mode 100644
index 0000000..ebe00c3
--- /dev/null
+++ b/library/tzdata/Asia/Irkutsk
@@ -0,0 +1,72 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Asia/Irkutsk) {
+    {-9223372036854775808 25025 0 LMT}
+    {-2840165825 25025 0 IMT}
+    {-1575874625 25200 0 IRKT}
+    {-1247554800 28800 0 IRKMMTT}
+    {354902400 32400 1 IRKST}
+    {370710000 28800 0 IRKT}
+    {386438400 32400 1 IRKST}
+    {402246000 28800 0 IRKT}
+    {417974400 32400 1 IRKST}
+    {433782000 28800 0 IRKT}
+    {449596800 32400 1 IRKST}
+    {465328800 28800 0 IRKT}
+    {481053600 32400 1 IRKST}
+    {496778400 28800 0 IRKT}
+    {512503200 32400 1 IRKST}
+    {528228000 28800 0 IRKT}
+    {543952800 32400 1 IRKST}
+    {559677600 28800 0 IRKT}
+    {575402400 32400 1 IRKST}
+    {591127200 28800 0 IRKT}
+    {606852000 32400 1 IRKST}
+    {622576800 28800 0 IRKT}
+    {638301600 32400 1 IRKST}
+    {654631200 28800 0 IRKT}
+    {670356000 25200 0 IRKMMTT}
+    {670359600 28800 1 IRKST}
+    {686084400 25200 0 IRKT}
+    {695761200 28800 0 IRKMMTT}
+    {701805600 32400 1 IRKST}
+    {717530400 28800 0 IRKT}
+    {733255200 32400 1 IRKST}
+    {748980000 28800 0 IRKT}
+    {764704800 32400 1 IRKST}
+    {780429600 28800 0 IRKT}
+    {796154400 32400 1 IRKST}
+    {811879200 28800 0 IRKT}
+    {828208800 32400 1 IRKST}
+    {846352800 28800 0 IRKT}
+    {859658400 32400 1 IRKST}
+    {877802400 28800 0 IRKT}
+    {891108000 32400 1 IRKST}
+    {909252000 28800 0 IRKT}
+    {922557600 32400 1 IRKST}
+    {941306400 28800 0 IRKT}
+    {954007200 32400 1 IRKST}
+    {972756000 28800 0 IRKT}
+    {985456800 32400 1 IRKST}
+    {1004205600 28800 0 IRKT}
+    {1017511200 32400 1 IRKST}
+    {1035655200 28800 0 IRKT}
+    {1048960800 32400 1 IRKST}
+    {1067104800 28800 0 IRKT}
+    {1080410400 32400 1 IRKST}
+    {1099159200 28800 0 IRKT}
+    {1111860000 32400 1 IRKST}
+    {1130608800 28800 0 IRKT}
+    {1143309600 32400 1 IRKST}
+    {1162058400 28800 0 IRKT}
+    {1174759200 32400 1 IRKST}
+    {1193508000 28800 0 IRKT}
+    {1206813600 32400 1 IRKST}
+    {1224957600 28800 0 IRKT}
+    {1238263200 32400 1 IRKST}
+    {1256407200 28800 0 IRKT}
+    {1269712800 32400 1 IRKST}
+    {1288461600 28800 0 IRKT}
+    {1301162400 32400 0 IRKT}
+    {1414256400 28800 0 IRKT}
+}
diff --git a/library/tzdata/Asia/Istanbul b/library/tzdata/Asia/Istanbul
new file mode 100644
index 0000000..85b3fc2
--- /dev/null
+++ b/library/tzdata/Asia/Istanbul
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Europe/Istanbul)]} {
+    LoadTimeZoneFile Europe/Istanbul
+}
+set TZData(:Asia/Istanbul) $TZData(:Europe/Istanbul)
diff --git a/library/tzdata/Asia/Jakarta b/library/tzdata/Asia/Jakarta
new file mode 100644
index 0000000..75cd659
--- /dev/null
+++ b/library/tzdata/Asia/Jakarta
@@ -0,0 +1,13 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Asia/Jakarta) {
+    {-9223372036854775808 25632 0 LMT}
+    {-3231299232 25632 0 BMT}
+    {-1451719200 26400 0 JAVT}
+    {-1172906400 27000 0 WIB}
+    {-876641400 32400 0 JST}
+    {-766054800 27000 0 WIB}
+    {-683883000 28800 0 WIB}
+    {-620812800 27000 0 WIB}
+    {-189415800 25200 0 WIB}
+}
diff --git a/library/tzdata/Asia/Jayapura b/library/tzdata/Asia/Jayapura
new file mode 100644
index 0000000..f3a4c44
--- /dev/null
+++ b/library/tzdata/Asia/Jayapura
@@ -0,0 +1,8 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Asia/Jayapura) {
+    {-9223372036854775808 33768 0 LMT}
+    {-1172913768 32400 0 WIT}
+    {-799491600 34200 0 ACST}
+    {-189423000 32400 0 WIT}
+}
diff --git a/library/tzdata/Asia/Jerusalem b/library/tzdata/Asia/Jerusalem
new file mode 100644
index 0000000..2714963
--- /dev/null
+++ b/library/tzdata/Asia/Jerusalem
@@ -0,0 +1,272 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Asia/Jerusalem) {
+    {-9223372036854775808 8454 0 LMT}
+    {-2840149254 8440 0 JMT}
+    {-1641003640 7200 0 IST}
+    {-933645600 10800 1 IDT}
+    {-857358000 7200 0 IST}
+    {-844300800 10800 1 IDT}
+    {-825822000 7200 0 IST}
+    {-812685600 10800 1 IDT}
+    {-794199600 7200 0 IST}
+    {-779853600 10800 1 IDT}
+    {-762656400 7200 0 IST}
+    {-748310400 10800 1 IDT}
+    {-731127600 7200 0 IST}
+    {-681962400 14400 1 IDDT}
+    {-673243200 10800 1 IDT}
+    {-667962000 7200 0 IST}
+    {-652327200 10800 1 IDT}
+    {-636426000 7200 0 IST}
+    {-622087200 10800 1 IDT}
+    {-608947200 7200 0 IST}
+    {-591847200 10800 1 IDT}
+    {-572486400 7200 0 IST}
+    {-558576000 10800 1 IDT}
+    {-542851200 7200 0 IST}
+    {-527731200 10800 1 IDT}
+    {-514425600 7200 0 IST}
+    {-490845600 10800 1 IDT}
+    {-482986800 7200 0 IST}
+    {-459475200 10800 1 IDT}
+    {-451537200 7200 0 IST}
+    {-428551200 10800 1 IDT}
+    {-418262400 7200 0 IST}
+    {-400032000 10800 1 IDT}
+    {-387428400 7200 0 IST}
+    {142380000 10800 1 IDT}
+    {150843600 7200 0 IST}
+    {167176800 10800 1 IDT}
+    {178664400 7200 0 IST}
+    {482277600 10800 1 IDT}
+    {495579600 7200 0 IST}
+    {516751200 10800 1 IDT}
+    {526424400 7200 0 IST}
+    {545436000 10800 1 IDT}
+    {558478800 7200 0 IST}
+    {576626400 10800 1 IDT}
+    {589323600 7200 0 IST}
+    {609890400 10800 1 IDT}
+    {620773200 7200 0 IST}
+    {638316000 10800 1 IDT}
+    {651618000 7200 0 IST}
+    {669765600 10800 1 IDT}
+    {683672400 7200 0 IST}
+    {701820000 10800 1 IDT}
+    {715726800 7200 0 IST}
+    {733701600 10800 1 IDT}
+    {747176400 7200 0 IST}
+    {765151200 10800 1 IDT}
+    {778021200 7200 0 IST}
+    {796600800 10800 1 IDT}
+    {810075600 7200 0 IST}
+    {826840800 10800 1 IDT}
+    {842821200 7200 0 IST}
+    {858895200 10800 1 IDT}
+    {874184400 7200 0 IST}
+    {890344800 10800 1 IDT}
+    {905029200 7200 0 IST}
+    {923011200 10800 1 IDT}
+    {936313200 7200 0 IST}
+    {955670400 10800 1 IDT}
+    {970783200 7200 0 IST}
+    {986770800 10800 1 IDT}
+    {1001282400 7200 0 IST}
+    {1017356400 10800 1 IDT}
+    {1033941600 7200 0 IST}
+    {1048806000 10800 1 IDT}
+    {1065132000 7200 0 IST}
+    {1081292400 10800 1 IDT}
+    {1095804000 7200 0 IST}
+    {1112313600 10800 1 IDT}
+    {1128812400 7200 0 IST}
+    {1143763200 10800 1 IDT}
+    {1159657200 7200 0 IST}
+    {1175212800 10800 1 IDT}
+    {1189897200 7200 0 IST}
+    {1206662400 10800 1 IDT}
+    {1223161200 7200 0 IST}
+    {1238112000 10800 1 IDT}
+    {1254006000 7200 0 IST}
+    {1269561600 10800 1 IDT}
+    {1284246000 7200 0 IST}
+    {1301616000 10800 1 IDT}
+    {1317510000 7200 0 IST}
+    {1333065600 10800 1 IDT}
+    {1348354800 7200 0 IST}
+    {1364515200 10800 1 IDT}
+    {1382828400 7200 0 IST}
+    {1395964800 10800 1 IDT}
+    {1414278000 7200 0 IST}
+    {1427414400 10800 1 IDT}
+    {1445727600 7200 0 IST}
+    {1458864000 10800 1 IDT}
+    {1477782000 7200 0 IST}
+    {1490313600 10800 1 IDT}
+    {1509231600 7200 0 IST}
+    {1521763200 10800 1 IDT}
+    {1540681200 7200 0 IST}
+    {1553817600 10800 1 IDT}
+    {1572130800 7200 0 IST}
+    {1585267200 10800 1 IDT}
+    {1603580400 7200 0 IST}
+    {1616716800 10800 1 IDT}
+    {1635634800 7200 0 IST}
+    {1648166400 10800 1 IDT}
+    {1667084400 7200 0 IST}
+    {1679616000 10800 1 IDT}
+    {1698534000 7200 0 IST}
+    {1711670400 10800 1 IDT}
+    {1729983600 7200 0 IST}
+    {1743120000 10800 1 IDT}
+    {1761433200 7200 0 IST}
+    {1774569600 10800 1 IDT}
+    {1792882800 7200 0 IST}
+    {1806019200 10800 1 IDT}
+    {1824937200 7200 0 IST}
+    {1837468800 10800 1 IDT}
+    {1856386800 7200 0 IST}
+    {1868918400 10800 1 IDT}
+    {1887836400 7200 0 IST}
+    {1900972800 10800 1 IDT}
+    {1919286000 7200 0 IST}
+    {1932422400 10800 1 IDT}
+    {1950735600 7200 0 IST}
+    {1963872000 10800 1 IDT}
+    {1982790000 7200 0 IST}
+    {1995321600 10800 1 IDT}
+    {2014239600 7200 0 IST}
+    {2026771200 10800 1 IDT}
+    {2045689200 7200 0 IST}
+    {2058220800 10800 1 IDT}
+    {2077138800 7200 0 IST}
+    {2090275200 10800 1 IDT}
+    {2108588400 7200 0 IST}
+    {2121724800 10800 1 IDT}
+    {2140038000 7200 0 IST}
+    {2153174400 10800 1 IDT}
+    {2172092400 7200 0 IST}
+    {2184624000 10800 1 IDT}
+    {2203542000 7200 0 IST}
+    {2216073600 10800 1 IDT}
+    {2234991600 7200 0 IST}
+    {2248128000 10800 1 IDT}
+    {2266441200 7200 0 IST}
+    {2279577600 10800 1 IDT}
+    {2297890800 7200 0 IST}
+    {2311027200 10800 1 IDT}
+    {2329340400 7200 0 IST}
+    {2342476800 10800 1 IDT}
+    {2361394800 7200 0 IST}
+    {2373926400 10800 1 IDT}
+    {2392844400 7200 0 IST}
+    {2405376000 10800 1 IDT}
+    {2424294000 7200 0 IST}
+    {2437430400 10800 1 IDT}
+    {2455743600 7200 0 IST}
+    {2468880000 10800 1 IDT}
+    {2487193200 7200 0 IST}
+    {2500329600 10800 1 IDT}
+    {2519247600 7200 0 IST}
+    {2531779200 10800 1 IDT}
+    {2550697200 7200 0 IST}
+    {2563228800 10800 1 IDT}
+    {2582146800 7200 0 IST}
+    {2595283200 10800 1 IDT}
+    {2613596400 7200 0 IST}
+    {2626732800 10800 1 IDT}
+    {2645046000 7200 0 IST}
+    {2658182400 10800 1 IDT}
+    {2676495600 7200 0 IST}
+    {2689632000 10800 1 IDT}
+    {2708550000 7200 0 IST}
+    {2721081600 10800 1 IDT}
+    {2739999600 7200 0 IST}
+    {2752531200 10800 1 IDT}
+    {2771449200 7200 0 IST}
+    {2784585600 10800 1 IDT}
+    {2802898800 7200 0 IST}
+    {2816035200 10800 1 IDT}
+    {2834348400 7200 0 IST}
+    {2847484800 10800 1 IDT}
+    {2866402800 7200 0 IST}
+    {2878934400 10800 1 IDT}
+    {2897852400 7200 0 IST}
+    {2910384000 10800 1 IDT}
+    {2929302000 7200 0 IST}
+    {2941833600 10800 1 IDT}
+    {2960751600 7200 0 IST}
+    {2973888000 10800 1 IDT}
+    {2992201200 7200 0 IST}
+    {3005337600 10800 1 IDT}
+    {3023650800 7200 0 IST}
+    {3036787200 10800 1 IDT}
+    {3055705200 7200 0 IST}
+    {3068236800 10800 1 IDT}
+    {3087154800 7200 0 IST}
+    {3099686400 10800 1 IDT}
+    {3118604400 7200 0 IST}
+    {3131740800 10800 1 IDT}
+    {3150054000 7200 0 IST}
+    {3163190400 10800 1 IDT}
+    {3181503600 7200 0 IST}
+    {3194640000 10800 1 IDT}
+    {3212953200 7200 0 IST}
+    {3226089600 10800 1 IDT}
+    {3245007600 7200 0 IST}
+    {3257539200 10800 1 IDT}
+    {3276457200 7200 0 IST}
+    {3288988800 10800 1 IDT}
+    {3307906800 7200 0 IST}
+    {3321043200 10800 1 IDT}
+    {3339356400 7200 0 IST}
+    {3352492800 10800 1 IDT}
+    {3370806000 7200 0 IST}
+    {3383942400 10800 1 IDT}
+    {3402860400 7200 0 IST}
+    {3415392000 10800 1 IDT}
+    {3434310000 7200 0 IST}
+    {3446841600 10800 1 IDT}
+    {3465759600 7200 0 IST}
+    {3478896000 10800 1 IDT}
+    {3497209200 7200 0 IST}
+    {3510345600 10800 1 IDT}
+    {3528658800 7200 0 IST}
+    {3541795200 10800 1 IDT}
+    {3560108400 7200 0 IST}
+    {3573244800 10800 1 IDT}
+    {3592162800 7200 0 IST}
+    {3604694400 10800 1 IDT}
+    {3623612400 7200 0 IST}
+    {3636144000 10800 1 IDT}
+    {3655062000 7200 0 IST}
+    {3668198400 10800 1 IDT}
+    {3686511600 7200 0 IST}
+    {3699648000 10800 1 IDT}
+    {3717961200 7200 0 IST}
+    {3731097600 10800 1 IDT}
+    {3750015600 7200 0 IST}
+    {3762547200 10800 1 IDT}
+    {3781465200 7200 0 IST}
+    {3793996800 10800 1 IDT}
+    {3812914800 7200 0 IST}
+    {3825446400 10800 1 IDT}
+    {3844364400 7200 0 IST}
+    {3857500800 10800 1 IDT}
+    {3875814000 7200 0 IST}
+    {3888950400 10800 1 IDT}
+    {3907263600 7200 0 IST}
+    {3920400000 10800 1 IDT}
+    {3939318000 7200 0 IST}
+    {3951849600 10800 1 IDT}
+    {3970767600 7200 0 IST}
+    {3983299200 10800 1 IDT}
+    {4002217200 7200 0 IST}
+    {4015353600 10800 1 IDT}
+    {4033666800 7200 0 IST}
+    {4046803200 10800 1 IDT}
+    {4065116400 7200 0 IST}
+    {4078252800 10800 1 IDT}
+    {4096566000 7200 0 IST}
+}
diff --git a/library/tzdata/Asia/Kabul b/library/tzdata/Asia/Kabul
new file mode 100644
index 0000000..33d7282
--- /dev/null
+++ b/library/tzdata/Asia/Kabul
@@ -0,0 +1,7 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Asia/Kabul) {
+    {-9223372036854775808 16608 0 LMT}
+    {-2524538208 14400 0 AFT}
+    {-788932800 16200 0 AFT}
+}
diff --git a/library/tzdata/Asia/Kamchatka b/library/tzdata/Asia/Kamchatka
new file mode 100644
index 0000000..2b77154
--- /dev/null
+++ b/library/tzdata/Asia/Kamchatka
@@ -0,0 +1,71 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Asia/Kamchatka) {
+    {-9223372036854775808 38076 0 LMT}
+    {-1487759676 39600 0 PETT}
+    {-1247569200 43200 0 PETMMTT}
+    {354888000 46800 1 PETST}
+    {370695600 43200 0 PETT}
+    {386424000 46800 1 PETST}
+    {402231600 43200 0 PETT}
+    {417960000 46800 1 PETST}
+    {433767600 43200 0 PETT}
+    {449582400 46800 1 PETST}
+    {465314400 43200 0 PETT}
+    {481039200 46800 1 PETST}
+    {496764000 43200 0 PETT}
+    {512488800 46800 1 PETST}
+    {528213600 43200 0 PETT}
+    {543938400 46800 1 PETST}
+    {559663200 43200 0 PETT}
+    {575388000 46800 1 PETST}
+    {591112800 43200 0 PETT}
+    {606837600 46800 1 PETST}
+    {622562400 43200 0 PETT}
+    {638287200 46800 1 PETST}
+    {654616800 43200 0 PETT}
+    {670341600 39600 0 PETMMTT}
+    {670345200 43200 1 PETST}
+    {686070000 39600 0 PETT}
+    {695746800 43200 0 PETMMTT}
+    {701791200 46800 1 PETST}
+    {717516000 43200 0 PETT}
+    {733240800 46800 1 PETST}
+    {748965600 43200 0 PETT}
+    {764690400 46800 1 PETST}
+    {780415200 43200 0 PETT}
+    {796140000 46800 1 PETST}
+    {811864800 43200 0 PETT}
+    {828194400 46800 1 PETST}
+    {846338400 43200 0 PETT}
+    {859644000 46800 1 PETST}
+    {877788000 43200 0 PETT}
+    {891093600 46800 1 PETST}
+    {909237600 43200 0 PETT}
+    {922543200 46800 1 PETST}
+    {941292000 43200 0 PETT}
+    {953992800 46800 1 PETST}
+    {972741600 43200 0 PETT}
+    {985442400 46800 1 PETST}
+    {1004191200 43200 0 PETT}
+    {1017496800 46800 1 PETST}
+    {1035640800 43200 0 PETT}
+    {1048946400 46800 1 PETST}
+    {1067090400 43200 0 PETT}
+    {1080396000 46800 1 PETST}
+    {1099144800 43200 0 PETT}
+    {1111845600 46800 1 PETST}
+    {1130594400 43200 0 PETT}
+    {1143295200 46800 1 PETST}
+    {1162044000 43200 0 PETT}
+    {1174744800 46800 1 PETST}
+    {1193493600 43200 0 PETT}
+    {1206799200 46800 1 PETST}
+    {1224943200 43200 0 PETT}
+    {1238248800 46800 1 PETST}
+    {1256392800 43200 0 PETT}
+    {1269698400 39600 0 PETMMTT}
+    {1269702000 43200 1 PETST}
+    {1288450800 39600 0 PETT}
+    {1301151600 43200 0 PETT}
+}
diff --git a/library/tzdata/Asia/Karachi b/library/tzdata/Asia/Karachi
new file mode 100644
index 0000000..669c11a
--- /dev/null
+++ b/library/tzdata/Asia/Karachi
@@ -0,0 +1,16 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Asia/Karachi) {
+    {-9223372036854775808 16092 0 LMT}
+    {-1988166492 19800 0 IST}
+    {-862637400 23400 1 IST}
+    {-764145000 19800 0 IST}
+    {-576135000 18000 0 KART}
+    {38775600 18000 0 PKT}
+    {1018119600 21600 1 PKST}
+    {1033840800 18000 0 PKT}
+    {1212260400 21600 1 PKST}
+    {1225476000 18000 0 PKT}
+    {1239735600 21600 1 PKST}
+    {1257012000 18000 0 PKT}
+}
diff --git a/library/tzdata/Asia/Kashgar b/library/tzdata/Asia/Kashgar
new file mode 100644
index 0000000..f67cbf1
--- /dev/null
+++ b/library/tzdata/Asia/Kashgar
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Asia/Urumqi)]} {
+    LoadTimeZoneFile Asia/Urumqi
+}
+set TZData(:Asia/Kashgar) $TZData(:Asia/Urumqi)
diff --git a/library/tzdata/Asia/Kathmandu b/library/tzdata/Asia/Kathmandu
new file mode 100644
index 0000000..dbec1f0
--- /dev/null
+++ b/library/tzdata/Asia/Kathmandu
@@ -0,0 +1,7 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Asia/Kathmandu) {
+    {-9223372036854775808 20476 0 LMT}
+    {-1577943676 19800 0 IST}
+    {504901800 20700 0 NPT}
+}
diff --git a/library/tzdata/Asia/Katmandu b/library/tzdata/Asia/Katmandu
new file mode 100644
index 0000000..2d6d060
--- /dev/null
+++ b/library/tzdata/Asia/Katmandu
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Asia/Kathmandu)]} {
+    LoadTimeZoneFile Asia/Kathmandu
+}
+set TZData(:Asia/Katmandu) $TZData(:Asia/Kathmandu)
diff --git a/library/tzdata/Asia/Khandyga b/library/tzdata/Asia/Khandyga
new file mode 100644
index 0000000..b898e0d
--- /dev/null
+++ b/library/tzdata/Asia/Khandyga
@@ -0,0 +1,73 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Asia/Khandyga) {
+    {-9223372036854775808 32533 0 LMT}
+    {-1579424533 28800 0 YAKT}
+    {-1247558400 32400 0 YAKMMTT}
+    {354898800 36000 1 YAKST}
+    {370706400 32400 0 YAKT}
+    {386434800 36000 1 YAKST}
+    {402242400 32400 0 YAKT}
+    {417970800 36000 1 YAKST}
+    {433778400 32400 0 YAKT}
+    {449593200 36000 1 YAKST}
+    {465325200 32400 0 YAKT}
+    {481050000 36000 1 YAKST}
+    {496774800 32400 0 YAKT}
+    {512499600 36000 1 YAKST}
+    {528224400 32400 0 YAKT}
+    {543949200 36000 1 YAKST}
+    {559674000 32400 0 YAKT}
+    {575398800 36000 1 YAKST}
+    {591123600 32400 0 YAKT}
+    {606848400 36000 1 YAKST}
+    {622573200 32400 0 YAKT}
+    {638298000 36000 1 YAKST}
+    {654627600 32400 0 YAKT}
+    {670352400 28800 0 YAKMMTT}
+    {670356000 32400 1 YAKST}
+    {686080800 28800 0 YAKT}
+    {695757600 32400 0 YAKMMTT}
+    {701802000 36000 1 YAKST}
+    {717526800 32400 0 YAKT}
+    {733251600 36000 1 YAKST}
+    {748976400 32400 0 YAKT}
+    {764701200 36000 1 YAKST}
+    {780426000 32400 0 YAKT}
+    {796150800 36000 1 YAKST}
+    {811875600 32400 0 YAKT}
+    {828205200 36000 1 YAKST}
+    {846349200 32400 0 YAKT}
+    {859654800 36000 1 YAKST}
+    {877798800 32400 0 YAKT}
+    {891104400 36000 1 YAKST}
+    {909248400 32400 0 YAKT}
+    {922554000 36000 1 YAKST}
+    {941302800 32400 0 YAKT}
+    {954003600 36000 1 YAKST}
+    {972752400 32400 0 YAKT}
+    {985453200 36000 1 YAKST}
+    {1004202000 32400 0 YAKT}
+    {1017507600 36000 1 YAKST}
+    {1035651600 32400 0 YAKT}
+    {1048957200 36000 1 YAKST}
+    {1067101200 32400 0 YAKT}
+    {1072882800 36000 0 VLAMMTT}
+    {1080403200 39600 1 VLAST}
+    {1099152000 36000 0 VLAT}
+    {1111852800 39600 1 VLAST}
+    {1130601600 36000 0 VLAT}
+    {1143302400 39600 1 VLAST}
+    {1162051200 36000 0 VLAT}
+    {1174752000 39600 1 VLAST}
+    {1193500800 36000 0 VLAT}
+    {1206806400 39600 1 VLAST}
+    {1224950400 36000 0 VLAT}
+    {1238256000 39600 1 VLAST}
+    {1256400000 36000 0 VLAT}
+    {1269705600 39600 1 VLAST}
+    {1288454400 36000 0 VLAT}
+    {1301155200 39600 0 VLAT}
+    {1315832400 36000 0 YAKT}
+    {1414252800 32400 0 YAKT}
+}
diff --git a/library/tzdata/Asia/Kolkata b/library/tzdata/Asia/Kolkata
new file mode 100644
index 0000000..a87bf31
--- /dev/null
+++ b/library/tzdata/Asia/Kolkata
@@ -0,0 +1,10 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Asia/Kolkata) {
+    {-9223372036854775808 21208 0 LMT}
+    {-2840162008 21200 0 HMT}
+    {-891582800 23400 0 BURT}
+    {-872058600 19800 0 IST}
+    {-862637400 23400 1 IST}
+    {-764145000 19800 0 IST}
+}
diff --git a/library/tzdata/Asia/Krasnoyarsk b/library/tzdata/Asia/Krasnoyarsk
new file mode 100644
index 0000000..3c6285e
--- /dev/null
+++ b/library/tzdata/Asia/Krasnoyarsk
@@ -0,0 +1,71 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Asia/Krasnoyarsk) {
+    {-9223372036854775808 22286 0 LMT}
+    {-1577513486 21600 0 KRAT}
+    {-1247551200 25200 0 KRAMMTT}
+    {354906000 28800 1 KRAST}
+    {370713600 25200 0 KRAT}
+    {386442000 28800 1 KRAST}
+    {402249600 25200 0 KRAT}
+    {417978000 28800 1 KRAST}
+    {433785600 25200 0 KRAT}
+    {449600400 28800 1 KRAST}
+    {465332400 25200 0 KRAT}
+    {481057200 28800 1 KRAST}
+    {496782000 25200 0 KRAT}
+    {512506800 28800 1 KRAST}
+    {528231600 25200 0 KRAT}
+    {543956400 28800 1 KRAST}
+    {559681200 25200 0 KRAT}
+    {575406000 28800 1 KRAST}
+    {591130800 25200 0 KRAT}
+    {606855600 28800 1 KRAST}
+    {622580400 25200 0 KRAT}
+    {638305200 28800 1 KRAST}
+    {654634800 25200 0 KRAT}
+    {670359600 21600 0 KRAMMTT}
+    {670363200 25200 1 KRAST}
+    {686088000 21600 0 KRAT}
+    {695764800 25200 0 KRAMMTT}
+    {701809200 28800 1 KRAST}
+    {717534000 25200 0 KRAT}
+    {733258800 28800 1 KRAST}
+    {748983600 25200 0 KRAT}
+    {764708400 28800 1 KRAST}
+    {780433200 25200 0 KRAT}
+    {796158000 28800 1 KRAST}
+    {811882800 25200 0 KRAT}
+    {828212400 28800 1 KRAST}
+    {846356400 25200 0 KRAT}
+    {859662000 28800 1 KRAST}
+    {877806000 25200 0 KRAT}
+    {891111600 28800 1 KRAST}
+    {909255600 25200 0 KRAT}
+    {922561200 28800 1 KRAST}
+    {941310000 25200 0 KRAT}
+    {954010800 28800 1 KRAST}
+    {972759600 25200 0 KRAT}
+    {985460400 28800 1 KRAST}
+    {1004209200 25200 0 KRAT}
+    {1017514800 28800 1 KRAST}
+    {1035658800 25200 0 KRAT}
+    {1048964400 28800 1 KRAST}
+    {1067108400 25200 0 KRAT}
+    {1080414000 28800 1 KRAST}
+    {1099162800 25200 0 KRAT}
+    {1111863600 28800 1 KRAST}
+    {1130612400 25200 0 KRAT}
+    {1143313200 28800 1 KRAST}
+    {1162062000 25200 0 KRAT}
+    {1174762800 28800 1 KRAST}
+    {1193511600 25200 0 KRAT}
+    {1206817200 28800 1 KRAST}
+    {1224961200 25200 0 KRAT}
+    {1238266800 28800 1 KRAST}
+    {1256410800 25200 0 KRAT}
+    {1269716400 28800 1 KRAST}
+    {1288465200 25200 0 KRAT}
+    {1301166000 28800 0 KRAT}
+    {1414260000 25200 0 KRAT}
+}
diff --git a/library/tzdata/Asia/Kuala_Lumpur b/library/tzdata/Asia/Kuala_Lumpur
new file mode 100644
index 0000000..7a54bd6
--- /dev/null
+++ b/library/tzdata/Asia/Kuala_Lumpur
@@ -0,0 +1,13 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Asia/Kuala_Lumpur) {
+    {-9223372036854775808 24406 0 LMT}
+    {-2177477206 24925 0 SMT}
+    {-2038200925 25200 0 MALT}
+    {-1167634800 26400 1 MALST}
+    {-1073028000 26400 0 MALT}
+    {-894180000 27000 0 MALT}
+    {-879665400 32400 0 JST}
+    {-767005200 27000 0 MALT}
+    {378664200 28800 0 MYT}
+}
diff --git a/library/tzdata/Asia/Kuching b/library/tzdata/Asia/Kuching
new file mode 100644
index 0000000..0f9110c
--- /dev/null
+++ b/library/tzdata/Asia/Kuching
@@ -0,0 +1,24 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Asia/Kuching) {
+    {-9223372036854775808 26480 0 LMT}
+    {-1383463280 27000 0 BORT}
+    {-1167636600 28800 0 BORT}
+    {-1082448000 30000 1 BORTST}
+    {-1074586800 28800 0 BORT}
+    {-1050825600 30000 1 BORTST}
+    {-1042964400 28800 0 BORT}
+    {-1019289600 30000 1 BORTST}
+    {-1011428400 28800 0 BORT}
+    {-987753600 30000 1 BORTST}
+    {-979892400 28800 0 BORT}
+    {-956217600 30000 1 BORTST}
+    {-948356400 28800 0 BORT}
+    {-924595200 30000 1 BORTST}
+    {-916734000 28800 0 BORT}
+    {-893059200 30000 1 BORTST}
+    {-885198000 28800 0 BORT}
+    {-879667200 32400 0 JST}
+    {-767005200 28800 0 BORT}
+    {378662400 28800 0 MYT}
+}
diff --git a/library/tzdata/Asia/Kuwait b/library/tzdata/Asia/Kuwait
new file mode 100644
index 0000000..e618c56
--- /dev/null
+++ b/library/tzdata/Asia/Kuwait
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Asia/Riyadh)]} {
+    LoadTimeZoneFile Asia/Riyadh
+}
+set TZData(:Asia/Kuwait) $TZData(:Asia/Riyadh)
diff --git a/library/tzdata/Asia/Macao b/library/tzdata/Asia/Macao
new file mode 100644
index 0000000..6e972ff
--- /dev/null
+++ b/library/tzdata/Asia/Macao
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Asia/Macau)]} {
+    LoadTimeZoneFile Asia/Macau
+}
+set TZData(:Asia/Macao) $TZData(:Asia/Macau)
diff --git a/library/tzdata/Asia/Macau b/library/tzdata/Asia/Macau
new file mode 100644
index 0000000..9d4abfe
--- /dev/null
+++ b/library/tzdata/Asia/Macau
@@ -0,0 +1,46 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Asia/Macau) {
+    {-9223372036854775808 27260 0 LMT}
+    {-1830411260 28800 0 MOT}
+    {-277360200 32400 1 MOST}
+    {-257405400 28800 0 MOT}
+    {-245910600 32400 1 MOST}
+    {-225955800 28800 0 MOT}
+    {-214473600 32400 1 MOST}
+    {-194506200 28800 0 MOT}
+    {-182406600 32400 1 MOST}
+    {-163056600 28800 0 MOT}
+    {-150969600 32400 1 MOST}
+    {-131619600 28800 0 MOT}
+    {-117088200 32400 1 MOST}
+    {-101367000 28800 0 MOT}
+    {-85638600 32400 1 MOST}
+    {-69312600 28800 0 MOT}
+    {-53584200 32400 1 MOST}
+    {-37863000 28800 0 MOT}
+    {-22134600 32400 1 MOST}
+    {-6413400 28800 0 MOT}
+    {9315000 32400 1 MOST}
+    {25036200 28800 0 MOT}
+    {40764600 32400 1 MOST}
+    {56485800 28800 0 MOT}
+    {72201600 32400 1 MOST}
+    {87922800 28800 0 MOT}
+    {103651200 32400 1 MOST}
+    {119977200 28800 0 MOT}
+    {135705600 32400 1 MOST}
+    {151439400 28800 0 MOT}
+    {167167800 32400 1 MOST}
+    {182889000 28800 0 MOT}
+    {198617400 32400 1 MOST}
+    {214338600 28800 0 MOT}
+    {230067000 32400 1 MOST}
+    {245788200 28800 0 MOT}
+    {261504000 32400 1 MOST}
+    {277225200 28800 0 MOT}
+    {292953600 32400 1 MOST}
+    {309279600 28800 0 MOT}
+    {325008000 32400 1 MOST}
+    {340729200 28800 0 MOT}
+}
diff --git a/library/tzdata/Asia/Magadan b/library/tzdata/Asia/Magadan
new file mode 100644
index 0000000..afe78da
--- /dev/null
+++ b/library/tzdata/Asia/Magadan
@@ -0,0 +1,72 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Asia/Magadan) {
+    {-9223372036854775808 36192 0 LMT}
+    {-1441188192 36000 0 MAGT}
+    {-1247565600 39600 0 MAGMMTT}
+    {354891600 43200 1 MAGST}
+    {370699200 39600 0 MAGT}
+    {386427600 43200 1 MAGST}
+    {402235200 39600 0 MAGT}
+    {417963600 43200 1 MAGST}
+    {433771200 39600 0 MAGT}
+    {449586000 43200 1 MAGST}
+    {465318000 39600 0 MAGT}
+    {481042800 43200 1 MAGST}
+    {496767600 39600 0 MAGT}
+    {512492400 43200 1 MAGST}
+    {528217200 39600 0 MAGT}
+    {543942000 43200 1 MAGST}
+    {559666800 39600 0 MAGT}
+    {575391600 43200 1 MAGST}
+    {591116400 39600 0 MAGT}
+    {606841200 43200 1 MAGST}
+    {622566000 39600 0 MAGT}
+    {638290800 43200 1 MAGST}
+    {654620400 39600 0 MAGT}
+    {670345200 36000 0 MAGMMTT}
+    {670348800 39600 1 MAGST}
+    {686073600 36000 0 MAGT}
+    {695750400 39600 0 MAGMMTT}
+    {701794800 43200 1 MAGST}
+    {717519600 39600 0 MAGT}
+    {733244400 43200 1 MAGST}
+    {748969200 39600 0 MAGT}
+    {764694000 43200 1 MAGST}
+    {780418800 39600 0 MAGT}
+    {796143600 43200 1 MAGST}
+    {811868400 39600 0 MAGT}
+    {828198000 43200 1 MAGST}
+    {846342000 39600 0 MAGT}
+    {859647600 43200 1 MAGST}
+    {877791600 39600 0 MAGT}
+    {891097200 43200 1 MAGST}
+    {909241200 39600 0 MAGT}
+    {922546800 43200 1 MAGST}
+    {941295600 39600 0 MAGT}
+    {953996400 43200 1 MAGST}
+    {972745200 39600 0 MAGT}
+    {985446000 43200 1 MAGST}
+    {1004194800 39600 0 MAGT}
+    {1017500400 43200 1 MAGST}
+    {1035644400 39600 0 MAGT}
+    {1048950000 43200 1 MAGST}
+    {1067094000 39600 0 MAGT}
+    {1080399600 43200 1 MAGST}
+    {1099148400 39600 0 MAGT}
+    {1111849200 43200 1 MAGST}
+    {1130598000 39600 0 MAGT}
+    {1143298800 43200 1 MAGST}
+    {1162047600 39600 0 MAGT}
+    {1174748400 43200 1 MAGST}
+    {1193497200 39600 0 MAGT}
+    {1206802800 43200 1 MAGST}
+    {1224946800 39600 0 MAGT}
+    {1238252400 43200 1 MAGST}
+    {1256396400 39600 0 MAGT}
+    {1269702000 43200 1 MAGST}
+    {1288450800 39600 0 MAGT}
+    {1301151600 43200 0 MAGT}
+    {1414245600 36000 0 MAGT}
+    {1461427200 39600 0 MAGT}
+}
diff --git a/library/tzdata/Asia/Makassar b/library/tzdata/Asia/Makassar
new file mode 100644
index 0000000..be947f3
--- /dev/null
+++ b/library/tzdata/Asia/Makassar
@@ -0,0 +1,9 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Asia/Makassar) {
+    {-9223372036854775808 28656 0 LMT}
+    {-1577951856 28656 0 MMT}
+    {-1172908656 28800 0 WITA}
+    {-880272000 32400 0 JST}
+    {-766054800 28800 0 WITA}
+}
diff --git a/library/tzdata/Asia/Manila b/library/tzdata/Asia/Manila
new file mode 100644
index 0000000..9cc25e8
--- /dev/null
+++ b/library/tzdata/Asia/Manila
@@ -0,0 +1,15 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Asia/Manila) {
+    {-9223372036854775808 -57360 0 LMT}
+    {-3944621040 29040 0 LMT}
+    {-2229321840 28800 0 PHT}
+    {-1046678400 32400 1 PHST}
+    {-1038733200 28800 0 PHT}
+    {-873273600 32400 0 JST}
+    {-794221200 28800 0 PHT}
+    {-496224000 32400 1 PHST}
+    {-489315600 28800 0 PHT}
+    {259344000 32400 1 PHST}
+    {275151600 28800 0 PHT}
+}
diff --git a/library/tzdata/Asia/Muscat b/library/tzdata/Asia/Muscat
new file mode 100644
index 0000000..fdd34c1
--- /dev/null
+++ b/library/tzdata/Asia/Muscat
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Asia/Dubai)]} {
+    LoadTimeZoneFile Asia/Dubai
+}
+set TZData(:Asia/Muscat) $TZData(:Asia/Dubai)
diff --git a/library/tzdata/Asia/Nicosia b/library/tzdata/Asia/Nicosia
new file mode 100644
index 0000000..73a7b4c
--- /dev/null
+++ b/library/tzdata/Asia/Nicosia
@@ -0,0 +1,257 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Asia/Nicosia) {
+    {-9223372036854775808 8008 0 LMT}
+    {-1518920008 7200 0 EET}
+    {166572000 10800 1 EEST}
+    {182293200 7200 0 EET}
+    {200959200 10800 1 EEST}
+    {213829200 7200 0 EET}
+    {228866400 10800 1 EEST}
+    {243982800 7200 0 EET}
+    {260316000 10800 1 EEST}
+    {276123600 7200 0 EET}
+    {291765600 10800 1 EEST}
+    {307486800 7200 0 EET}
+    {323820000 10800 1 EEST}
+    {338936400 7200 0 EET}
+    {354664800 10800 1 EEST}
+    {370386000 7200 0 EET}
+    {386114400 10800 1 EEST}
+    {401835600 7200 0 EET}
+    {417564000 10800 1 EEST}
+    {433285200 7200 0 EET}
+    {449013600 10800 1 EEST}
+    {465339600 7200 0 EET}
+    {481068000 10800 1 EEST}
+    {496789200 7200 0 EET}
+    {512517600 10800 1 EEST}
+    {528238800 7200 0 EET}
+    {543967200 10800 1 EEST}
+    {559688400 7200 0 EET}
+    {575416800 10800 1 EEST}
+    {591138000 7200 0 EET}
+    {606866400 10800 1 EEST}
+    {622587600 7200 0 EET}
+    {638316000 10800 1 EEST}
+    {654642000 7200 0 EET}
+    {670370400 10800 1 EEST}
+    {686091600 7200 0 EET}
+    {701820000 10800 1 EEST}
+    {717541200 7200 0 EET}
+    {733269600 10800 1 EEST}
+    {748990800 7200 0 EET}
+    {764719200 10800 1 EEST}
+    {780440400 7200 0 EET}
+    {796168800 10800 1 EEST}
+    {811890000 7200 0 EET}
+    {828223200 10800 1 EEST}
+    {843944400 7200 0 EET}
+    {859672800 10800 1 EEST}
+    {875394000 7200 0 EET}
+    {891122400 10800 1 EEST}
+    {904597200 10800 0 EEST}
+    {909277200 7200 0 EET}
+    {922582800 10800 1 EEST}
+    {941331600 7200 0 EET}
+    {954032400 10800 1 EEST}
+    {972781200 7200 0 EET}
+    {985482000 10800 1 EEST}
+    {1004230800 7200 0 EET}
+    {1017536400 10800 1 EEST}
+    {1035680400 7200 0 EET}
+    {1048986000 10800 1 EEST}
+    {1067130000 7200 0 EET}
+    {1080435600 10800 1 EEST}
+    {1099184400 7200 0 EET}
+    {1111885200 10800 1 EEST}
+    {1130634000 7200 0 EET}
+    {1143334800 10800 1 EEST}
+    {1162083600 7200 0 EET}
+    {1174784400 10800 1 EEST}
+    {1193533200 7200 0 EET}
+    {1206838800 10800 1 EEST}
+    {1224982800 7200 0 EET}
+    {1238288400 10800 1 EEST}
+    {1256432400 7200 0 EET}
+    {1269738000 10800 1 EEST}
+    {1288486800 7200 0 EET}
+    {1301187600 10800 1 EEST}
+    {1319936400 7200 0 EET}
+    {1332637200 10800 1 EEST}
+    {1351386000 7200 0 EET}
+    {1364691600 10800 1 EEST}
+    {1382835600 7200 0 EET}
+    {1396141200 10800 1 EEST}
+    {1414285200 7200 0 EET}
+    {1427590800 10800 1 EEST}
+    {1445734800 7200 0 EET}
+    {1459040400 10800 1 EEST}
+    {1477789200 7200 0 EET}
+    {1490490000 10800 1 EEST}
+    {1509238800 7200 0 EET}
+    {1521939600 10800 1 EEST}
+    {1540688400 7200 0 EET}
+    {1553994000 10800 1 EEST}
+    {1572138000 7200 0 EET}
+    {1585443600 10800 1 EEST}
+    {1603587600 7200 0 EET}
+    {1616893200 10800 1 EEST}
+    {1635642000 7200 0 EET}
+    {1648342800 10800 1 EEST}
+    {1667091600 7200 0 EET}
+    {1679792400 10800 1 EEST}
+    {1698541200 7200 0 EET}
+    {1711846800 10800 1 EEST}
+    {1729990800 7200 0 EET}
+    {1743296400 10800 1 EEST}
+    {1761440400 7200 0 EET}
+    {1774746000 10800 1 EEST}
+    {1792890000 7200 0 EET}
+    {1806195600 10800 1 EEST}
+    {1824944400 7200 0 EET}
+    {1837645200 10800 1 EEST}
+    {1856394000 7200 0 EET}
+    {1869094800 10800 1 EEST}
+    {1887843600 7200 0 EET}
+    {1901149200 10800 1 EEST}
+    {1919293200 7200 0 EET}
+    {1932598800 10800 1 EEST}
+    {1950742800 7200 0 EET}
+    {1964048400 10800 1 EEST}
+    {1982797200 7200 0 EET}
+    {1995498000 10800 1 EEST}
+    {2014246800 7200 0 EET}
+    {2026947600 10800 1 EEST}
+    {2045696400 7200 0 EET}
+    {2058397200 10800 1 EEST}
+    {2077146000 7200 0 EET}
+    {2090451600 10800 1 EEST}
+    {2108595600 7200 0 EET}
+    {2121901200 10800 1 EEST}
+    {2140045200 7200 0 EET}
+    {2153350800 10800 1 EEST}
+    {2172099600 7200 0 EET}
+    {2184800400 10800 1 EEST}
+    {2203549200 7200 0 EET}
+    {2216250000 10800 1 EEST}
+    {2234998800 7200 0 EET}
+    {2248304400 10800 1 EEST}
+    {2266448400 7200 0 EET}
+    {2279754000 10800 1 EEST}
+    {2297898000 7200 0 EET}
+    {2311203600 10800 1 EEST}
+    {2329347600 7200 0 EET}
+    {2342653200 10800 1 EEST}
+    {2361402000 7200 0 EET}
+    {2374102800 10800 1 EEST}
+    {2392851600 7200 0 EET}
+    {2405552400 10800 1 EEST}
+    {2424301200 7200 0 EET}
+    {2437606800 10800 1 EEST}
+    {2455750800 7200 0 EET}
+    {2469056400 10800 1 EEST}
+    {2487200400 7200 0 EET}
+    {2500506000 10800 1 EEST}
+    {2519254800 7200 0 EET}
+    {2531955600 10800 1 EEST}
+    {2550704400 7200 0 EET}
+    {2563405200 10800 1 EEST}
+    {2582154000 7200 0 EET}
+    {2595459600 10800 1 EEST}
+    {2613603600 7200 0 EET}
+    {2626909200 10800 1 EEST}
+    {2645053200 7200 0 EET}
+    {2658358800 10800 1 EEST}
+    {2676502800 7200 0 EET}
+    {2689808400 10800 1 EEST}
+    {2708557200 7200 0 EET}
+    {2721258000 10800 1 EEST}
+    {2740006800 7200 0 EET}
+    {2752707600 10800 1 EEST}
+    {2771456400 7200 0 EET}
+    {2784762000 10800 1 EEST}
+    {2802906000 7200 0 EET}
+    {2816211600 10800 1 EEST}
+    {2834355600 7200 0 EET}
+    {2847661200 10800 1 EEST}
+    {2866410000 7200 0 EET}
+    {2879110800 10800 1 EEST}
+    {2897859600 7200 0 EET}
+    {2910560400 10800 1 EEST}
+    {2929309200 7200 0 EET}
+    {2942010000 10800 1 EEST}
+    {2960758800 7200 0 EET}
+    {2974064400 10800 1 EEST}
+    {2992208400 7200 0 EET}
+    {3005514000 10800 1 EEST}
+    {3023658000 7200 0 EET}
+    {3036963600 10800 1 EEST}
+    {3055712400 7200 0 EET}
+    {3068413200 10800 1 EEST}
+    {3087162000 7200 0 EET}
+    {3099862800 10800 1 EEST}
+    {3118611600 7200 0 EET}
+    {3131917200 10800 1 EEST}
+    {3150061200 7200 0 EET}
+    {3163366800 10800 1 EEST}
+    {3181510800 7200 0 EET}
+    {3194816400 10800 1 EEST}
+    {3212960400 7200 0 EET}
+    {3226266000 10800 1 EEST}
+    {3245014800 7200 0 EET}
+    {3257715600 10800 1 EEST}
+    {3276464400 7200 0 EET}
+    {3289165200 10800 1 EEST}
+    {3307914000 7200 0 EET}
+    {3321219600 10800 1 EEST}
+    {3339363600 7200 0 EET}
+    {3352669200 10800 1 EEST}
+    {3370813200 7200 0 EET}
+    {3384118800 10800 1 EEST}
+    {3402867600 7200 0 EET}
+    {3415568400 10800 1 EEST}
+    {3434317200 7200 0 EET}
+    {3447018000 10800 1 EEST}
+    {3465766800 7200 0 EET}
+    {3479072400 10800 1 EEST}
+    {3497216400 7200 0 EET}
+    {3510522000 10800 1 EEST}
+    {3528666000 7200 0 EET}
+    {3541971600 10800 1 EEST}
+    {3560115600 7200 0 EET}
+    {3573421200 10800 1 EEST}
+    {3592170000 7200 0 EET}
+    {3604870800 10800 1 EEST}
+    {3623619600 7200 0 EET}
+    {3636320400 10800 1 EEST}
+    {3655069200 7200 0 EET}
+    {3668374800 10800 1 EEST}
+    {3686518800 7200 0 EET}
+    {3699824400 10800 1 EEST}
+    {3717968400 7200 0 EET}
+    {3731274000 10800 1 EEST}
+    {3750022800 7200 0 EET}
+    {3762723600 10800 1 EEST}
+    {3781472400 7200 0 EET}
+    {3794173200 10800 1 EEST}
+    {3812922000 7200 0 EET}
+    {3825622800 10800 1 EEST}
+    {3844371600 7200 0 EET}
+    {3857677200 10800 1 EEST}
+    {3875821200 7200 0 EET}
+    {3889126800 10800 1 EEST}
+    {3907270800 7200 0 EET}
+    {3920576400 10800 1 EEST}
+    {3939325200 7200 0 EET}
+    {3952026000 10800 1 EEST}
+    {3970774800 7200 0 EET}
+    {3983475600 10800 1 EEST}
+    {4002224400 7200 0 EET}
+    {4015530000 10800 1 EEST}
+    {4033674000 7200 0 EET}
+    {4046979600 10800 1 EEST}
+    {4065123600 7200 0 EET}
+    {4078429200 10800 1 EEST}
+    {4096573200 7200 0 EET}
+}
diff --git a/library/tzdata/Asia/Novokuznetsk b/library/tzdata/Asia/Novokuznetsk
new file mode 100644
index 0000000..a43a984
--- /dev/null
+++ b/library/tzdata/Asia/Novokuznetsk
@@ -0,0 +1,71 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Asia/Novokuznetsk) {
+    {-9223372036854775808 20928 0 LMT}
+    {-1441259328 21600 0 +06}
+    {-1247551200 25200 0 +08}
+    {354906000 28800 1 +08}
+    {370713600 25200 0 +07}
+    {386442000 28800 1 +08}
+    {402249600 25200 0 +07}
+    {417978000 28800 1 +08}
+    {433785600 25200 0 +07}
+    {449600400 28800 1 +08}
+    {465332400 25200 0 +07}
+    {481057200 28800 1 +08}
+    {496782000 25200 0 +07}
+    {512506800 28800 1 +08}
+    {528231600 25200 0 +07}
+    {543956400 28800 1 +08}
+    {559681200 25200 0 +07}
+    {575406000 28800 1 +08}
+    {591130800 25200 0 +07}
+    {606855600 28800 1 +08}
+    {622580400 25200 0 +07}
+    {638305200 28800 1 +08}
+    {654634800 25200 0 +07}
+    {670359600 21600 0 +07}
+    {670363200 25200 1 +07}
+    {686088000 21600 0 +06}
+    {695764800 25200 0 +08}
+    {701809200 28800 1 +08}
+    {717534000 25200 0 +07}
+    {733258800 28800 1 +08}
+    {748983600 25200 0 +07}
+    {764708400 28800 1 +08}
+    {780433200 25200 0 +07}
+    {796158000 28800 1 +08}
+    {811882800 25200 0 +07}
+    {828212400 28800 1 +08}
+    {846356400 25200 0 +07}
+    {859662000 28800 1 +08}
+    {877806000 25200 0 +07}
+    {891111600 28800 1 +08}
+    {909255600 25200 0 +07}
+    {922561200 28800 1 +08}
+    {941310000 25200 0 +07}
+    {954010800 28800 1 +08}
+    {972759600 25200 0 +07}
+    {985460400 28800 1 +08}
+    {1004209200 25200 0 +07}
+    {1017514800 28800 1 +08}
+    {1035658800 25200 0 +07}
+    {1048964400 28800 1 +08}
+    {1067108400 25200 0 +07}
+    {1080414000 28800 1 +08}
+    {1099162800 25200 0 +07}
+    {1111863600 28800 1 +08}
+    {1130612400 25200 0 +07}
+    {1143313200 28800 1 +08}
+    {1162062000 25200 0 +07}
+    {1174762800 28800 1 +08}
+    {1193511600 25200 0 +07}
+    {1206817200 28800 1 +08}
+    {1224961200 25200 0 +07}
+    {1238266800 28800 1 +08}
+    {1256410800 25200 0 +07}
+    {1269716400 21600 0 +07}
+    {1269720000 25200 1 +07}
+    {1288468800 21600 0 +06}
+    {1301169600 25200 0 +07}
+}
diff --git a/library/tzdata/Asia/Novosibirsk b/library/tzdata/Asia/Novosibirsk
new file mode 100644
index 0000000..21f5c00
--- /dev/null
+++ b/library/tzdata/Asia/Novosibirsk
@@ -0,0 +1,73 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Asia/Novosibirsk) {
+    {-9223372036854775808 19900 0 LMT}
+    {-1579476700 21600 0 +06}
+    {-1247551200 25200 0 +08}
+    {354906000 28800 1 +08}
+    {370713600 25200 0 +07}
+    {386442000 28800 1 +08}
+    {402249600 25200 0 +07}
+    {417978000 28800 1 +08}
+    {433785600 25200 0 +07}
+    {449600400 28800 1 +08}
+    {465332400 25200 0 +07}
+    {481057200 28800 1 +08}
+    {496782000 25200 0 +07}
+    {512506800 28800 1 +08}
+    {528231600 25200 0 +07}
+    {543956400 28800 1 +08}
+    {559681200 25200 0 +07}
+    {575406000 28800 1 +08}
+    {591130800 25200 0 +07}
+    {606855600 28800 1 +08}
+    {622580400 25200 0 +07}
+    {638305200 28800 1 +08}
+    {654634800 25200 0 +07}
+    {670359600 21600 0 +07}
+    {670363200 25200 1 +07}
+    {686088000 21600 0 +06}
+    {695764800 25200 0 +08}
+    {701809200 28800 1 +08}
+    {717534000 25200 0 +07}
+    {733258800 28800 1 +08}
+    {738090000 25200 0 +07}
+    {748987200 21600 0 +06}
+    {764712000 25200 1 +07}
+    {780436800 21600 0 +06}
+    {796161600 25200 1 +07}
+    {811886400 21600 0 +06}
+    {828216000 25200 1 +07}
+    {846360000 21600 0 +06}
+    {859665600 25200 1 +07}
+    {877809600 21600 0 +06}
+    {891115200 25200 1 +07}
+    {909259200 21600 0 +06}
+    {922564800 25200 1 +07}
+    {941313600 21600 0 +06}
+    {954014400 25200 1 +07}
+    {972763200 21600 0 +06}
+    {985464000 25200 1 +07}
+    {1004212800 21600 0 +06}
+    {1017518400 25200 1 +07}
+    {1035662400 21600 0 +06}
+    {1048968000 25200 1 +07}
+    {1067112000 21600 0 +06}
+    {1080417600 25200 1 +07}
+    {1099166400 21600 0 +06}
+    {1111867200 25200 1 +07}
+    {1130616000 21600 0 +06}
+    {1143316800 25200 1 +07}
+    {1162065600 21600 0 +06}
+    {1174766400 25200 1 +07}
+    {1193515200 21600 0 +06}
+    {1206820800 25200 1 +07}
+    {1224964800 21600 0 +06}
+    {1238270400 25200 1 +07}
+    {1256414400 21600 0 +06}
+    {1269720000 25200 1 +07}
+    {1288468800 21600 0 +06}
+    {1301169600 25200 0 +07}
+    {1414263600 21600 0 +06}
+    {1469304000 25200 0 +07}
+}
diff --git a/library/tzdata/Asia/Omsk b/library/tzdata/Asia/Omsk
new file mode 100644
index 0000000..a6fa180
--- /dev/null
+++ b/library/tzdata/Asia/Omsk
@@ -0,0 +1,71 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Asia/Omsk) {
+    {-9223372036854775808 17610 0 LMT}
+    {-1582088010 18000 0 OMST}
+    {-1247547600 21600 0 OMSMMTT}
+    {354909600 25200 1 OMSST}
+    {370717200 21600 0 OMST}
+    {386445600 25200 1 OMSST}
+    {402253200 21600 0 OMST}
+    {417981600 25200 1 OMSST}
+    {433789200 21600 0 OMST}
+    {449604000 25200 1 OMSST}
+    {465336000 21600 0 OMST}
+    {481060800 25200 1 OMSST}
+    {496785600 21600 0 OMST}
+    {512510400 25200 1 OMSST}
+    {528235200 21600 0 OMST}
+    {543960000 25200 1 OMSST}
+    {559684800 21600 0 OMST}
+    {575409600 25200 1 OMSST}
+    {591134400 21600 0 OMST}
+    {606859200 25200 1 OMSST}
+    {622584000 21600 0 OMST}
+    {638308800 25200 1 OMSST}
+    {654638400 21600 0 OMST}
+    {670363200 18000 0 OMSMMTT}
+    {670366800 21600 1 OMSST}
+    {686091600 18000 0 OMST}
+    {695768400 21600 0 OMSMMTT}
+    {701812800 25200 1 OMSST}
+    {717537600 21600 0 OMST}
+    {733262400 25200 1 OMSST}
+    {748987200 21600 0 OMST}
+    {764712000 25200 1 OMSST}
+    {780436800 21600 0 OMST}
+    {796161600 25200 1 OMSST}
+    {811886400 21600 0 OMST}
+    {828216000 25200 1 OMSST}
+    {846360000 21600 0 OMST}
+    {859665600 25200 1 OMSST}
+    {877809600 21600 0 OMST}
+    {891115200 25200 1 OMSST}
+    {909259200 21600 0 OMST}
+    {922564800 25200 1 OMSST}
+    {941313600 21600 0 OMST}
+    {954014400 25200 1 OMSST}
+    {972763200 21600 0 OMST}
+    {985464000 25200 1 OMSST}
+    {1004212800 21600 0 OMST}
+    {1017518400 25200 1 OMSST}
+    {1035662400 21600 0 OMST}
+    {1048968000 25200 1 OMSST}
+    {1067112000 21600 0 OMST}
+    {1080417600 25200 1 OMSST}
+    {1099166400 21600 0 OMST}
+    {1111867200 25200 1 OMSST}
+    {1130616000 21600 0 OMST}
+    {1143316800 25200 1 OMSST}
+    {1162065600 21600 0 OMST}
+    {1174766400 25200 1 OMSST}
+    {1193515200 21600 0 OMST}
+    {1206820800 25200 1 OMSST}
+    {1224964800 21600 0 OMST}
+    {1238270400 25200 1 OMSST}
+    {1256414400 21600 0 OMST}
+    {1269720000 25200 1 OMSST}
+    {1288468800 21600 0 OMST}
+    {1301169600 25200 0 OMST}
+    {1414263600 21600 0 OMST}
+}
diff --git a/library/tzdata/Asia/Oral b/library/tzdata/Asia/Oral
new file mode 100644
index 0000000..962111b
--- /dev/null
+++ b/library/tzdata/Asia/Oral
@@ -0,0 +1,58 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Asia/Oral) {
+    {-9223372036854775808 12324 0 LMT}
+    {-1441164324 14400 0 +04}
+    {-1247544000 18000 0 +05}
+    {354913200 21600 1 +06}
+    {370720800 21600 0 +06}
+    {386445600 18000 0 +05}
+    {386449200 21600 1 +06}
+    {402256800 18000 0 +05}
+    {417985200 21600 1 +06}
+    {433792800 18000 0 +05}
+    {449607600 21600 1 +06}
+    {465339600 18000 0 +05}
+    {481064400 21600 1 +06}
+    {496789200 18000 0 +05}
+    {512514000 21600 1 +06}
+    {528238800 18000 0 +05}
+    {543963600 21600 1 +06}
+    {559688400 18000 0 +05}
+    {575413200 21600 1 +06}
+    {591138000 18000 0 +05}
+    {606862800 14400 0 +04}
+    {606866400 18000 1 +05}
+    {622591200 14400 0 +04}
+    {638316000 18000 1 +05}
+    {654645600 14400 0 +04}
+    {670370400 18000 1 +05}
+    {686095200 14400 0 +04}
+    {701816400 14400 0 +04}
+    {701820000 18000 1 +05}
+    {717544800 14400 0 +04}
+    {733269600 18000 1 +05}
+    {748994400 14400 0 +04}
+    {764719200 18000 1 +05}
+    {780444000 14400 0 +04}
+    {796168800 18000 1 +05}
+    {811893600 14400 0 +04}
+    {828223200 18000 1 +05}
+    {846367200 14400 0 +04}
+    {859672800 18000 1 +05}
+    {877816800 14400 0 +04}
+    {891122400 18000 1 +05}
+    {909266400 14400 0 +04}
+    {922572000 18000 1 +05}
+    {941320800 14400 0 +04}
+    {954021600 18000 1 +05}
+    {972770400 14400 0 +04}
+    {985471200 18000 1 +05}
+    {1004220000 14400 0 +04}
+    {1017525600 18000 1 +05}
+    {1035669600 14400 0 +04}
+    {1048975200 18000 1 +05}
+    {1067119200 14400 0 +04}
+    {1080424800 18000 1 +05}
+    {1099173600 18000 0 +05}
+}
diff --git a/library/tzdata/Asia/Phnom_Penh b/library/tzdata/Asia/Phnom_Penh
new file mode 100644
index 0000000..114c786
--- /dev/null
+++ b/library/tzdata/Asia/Phnom_Penh
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Asia/Bangkok)]} {
+    LoadTimeZoneFile Asia/Bangkok
+}
+set TZData(:Asia/Phnom_Penh) $TZData(:Asia/Bangkok)
diff --git a/library/tzdata/Asia/Pontianak b/library/tzdata/Asia/Pontianak
new file mode 100644
index 0000000..728b552
--- /dev/null
+++ b/library/tzdata/Asia/Pontianak
@@ -0,0 +1,13 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Asia/Pontianak) {
+    {-9223372036854775808 26240 0 LMT}
+    {-1946186240 26240 0 PMT}
+    {-1172906240 27000 0 WIB}
+    {-881220600 32400 0 JST}
+    {-766054800 27000 0 WIB}
+    {-683883000 28800 0 WIB}
+    {-620812800 27000 0 WIB}
+    {-189415800 28800 0 WITA}
+    {567964800 25200 0 WIB}
+}
diff --git a/library/tzdata/Asia/Pyongyang b/library/tzdata/Asia/Pyongyang
new file mode 100644
index 0000000..4ade8e6
--- /dev/null
+++ b/library/tzdata/Asia/Pyongyang
@@ -0,0 +1,10 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Asia/Pyongyang) {
+    {-9223372036854775808 30180 0 LMT}
+    {-1948782180 30600 0 KST}
+    {-1830414600 32400 0 JCST}
+    {-1017824400 32400 0 JST}
+    {-768646800 32400 0 KST}
+    {1439564400 30600 0 KST}
+}
diff --git a/library/tzdata/Asia/Qatar b/library/tzdata/Asia/Qatar
new file mode 100644
index 0000000..bfb4eb4
--- /dev/null
+++ b/library/tzdata/Asia/Qatar
@@ -0,0 +1,7 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Asia/Qatar) {
+    {-9223372036854775808 12368 0 LMT}
+    {-1577935568 14400 0 GST}
+    {76190400 10800 0 AST}
+}
diff --git a/library/tzdata/Asia/Qyzylorda b/library/tzdata/Asia/Qyzylorda
new file mode 100644
index 0000000..b2e9472
--- /dev/null
+++ b/library/tzdata/Asia/Qyzylorda
@@ -0,0 +1,57 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Asia/Qyzylorda) {
+    {-9223372036854775808 15712 0 LMT}
+    {-1441167712 14400 0 +04}
+    {-1247544000 18000 0 +05}
+    {354913200 21600 1 +06}
+    {370720800 21600 0 +06}
+    {386445600 18000 0 +05}
+    {386449200 21600 1 +06}
+    {402256800 18000 0 +05}
+    {417985200 21600 1 +06}
+    {433792800 18000 0 +05}
+    {449607600 21600 1 +06}
+    {465339600 18000 0 +05}
+    {481064400 21600 1 +06}
+    {496789200 18000 0 +05}
+    {512514000 21600 1 +06}
+    {528238800 18000 0 +05}
+    {543963600 21600 1 +06}
+    {559688400 18000 0 +05}
+    {575413200 21600 1 +06}
+    {591138000 18000 0 +05}
+    {606862800 21600 1 +06}
+    {622587600 18000 0 +05}
+    {638312400 21600 1 +06}
+    {654642000 18000 0 +05}
+    {670366800 14400 0 +04}
+    {670370400 18000 1 +05}
+    {701812800 18000 0 +05}
+    {701816400 21600 1 +06}
+    {717541200 18000 0 +05}
+    {733266000 21600 1 +06}
+    {748990800 18000 0 +05}
+    {764715600 21600 1 +06}
+    {780440400 18000 0 +05}
+    {796165200 21600 1 +06}
+    {811890000 18000 0 +05}
+    {828219600 21600 1 +06}
+    {846363600 18000 0 +05}
+    {859669200 21600 1 +06}
+    {877813200 18000 0 +05}
+    {891118800 21600 1 +06}
+    {909262800 18000 0 +05}
+    {922568400 21600 1 +06}
+    {941317200 18000 0 +05}
+    {954018000 21600 1 +06}
+    {972766800 18000 0 +05}
+    {985467600 21600 1 +06}
+    {1004216400 18000 0 +05}
+    {1017522000 21600 1 +06}
+    {1035666000 18000 0 +05}
+    {1048971600 21600 1 +06}
+    {1067115600 18000 0 +05}
+    {1080421200 21600 1 +06}
+    {1099170000 21600 0 +06}
+}
diff --git a/library/tzdata/Asia/Rangoon b/library/tzdata/Asia/Rangoon
new file mode 100644
index 0000000..4f3ac02
--- /dev/null
+++ b/library/tzdata/Asia/Rangoon
@@ -0,0 +1,9 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Asia/Rangoon) {
+    {-9223372036854775808 23080 0 LMT}
+    {-2840163880 23080 0 RMT}
+    {-1577946280 23400 0 BURT}
+    {-873268200 32400 0 JST}
+    {-778410000 23400 0 MMT}
+}
diff --git a/library/tzdata/Asia/Riyadh b/library/tzdata/Asia/Riyadh
new file mode 100644
index 0000000..12c9e24
--- /dev/null
+++ b/library/tzdata/Asia/Riyadh
@@ -0,0 +1,6 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Asia/Riyadh) {
+    {-9223372036854775808 11212 0 LMT}
+    {-719636812 10800 0 AST}
+}
diff --git a/library/tzdata/Asia/Saigon b/library/tzdata/Asia/Saigon
new file mode 100644
index 0000000..1e42eed
--- /dev/null
+++ b/library/tzdata/Asia/Saigon
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Asia/Ho_Chi_Minh)]} {
+    LoadTimeZoneFile Asia/Ho_Chi_Minh
+}
+set TZData(:Asia/Saigon) $TZData(:Asia/Ho_Chi_Minh)
diff --git a/library/tzdata/Asia/Sakhalin b/library/tzdata/Asia/Sakhalin
new file mode 100644
index 0000000..1de22f4
--- /dev/null
+++ b/library/tzdata/Asia/Sakhalin
@@ -0,0 +1,74 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Asia/Sakhalin) {
+    {-9223372036854775808 34248 0 LMT}
+    {-2031039048 32400 0 JCST}
+    {-1017824400 32400 0 JST}
+    {-768560400 39600 0 SAKMMTT}
+    {354891600 43200 1 SAKST}
+    {370699200 39600 0 SAKT}
+    {386427600 43200 1 SAKST}
+    {402235200 39600 0 SAKT}
+    {417963600 43200 1 SAKST}
+    {433771200 39600 0 SAKT}
+    {449586000 43200 1 SAKST}
+    {465318000 39600 0 SAKT}
+    {481042800 43200 1 SAKST}
+    {496767600 39600 0 SAKT}
+    {512492400 43200 1 SAKST}
+    {528217200 39600 0 SAKT}
+    {543942000 43200 1 SAKST}
+    {559666800 39600 0 SAKT}
+    {575391600 43200 1 SAKST}
+    {591116400 39600 0 SAKT}
+    {606841200 43200 1 SAKST}
+    {622566000 39600 0 SAKT}
+    {638290800 43200 1 SAKST}
+    {654620400 39600 0 SAKT}
+    {670345200 36000 0 SAKMMTT}
+    {670348800 39600 1 SAKST}
+    {686073600 36000 0 SAKT}
+    {695750400 39600 0 SAKMMTT}
+    {701794800 43200 1 SAKST}
+    {717519600 39600 0 SAKT}
+    {733244400 43200 1 SAKST}
+    {748969200 39600 0 SAKT}
+    {764694000 43200 1 SAKST}
+    {780418800 39600 0 SAKT}
+    {796143600 43200 1 SAKST}
+    {811868400 39600 0 SAKT}
+    {828198000 43200 1 SAKST}
+    {846342000 39600 0 SAKT}
+    {859647600 36000 0 SAKMMTT}
+    {859651200 39600 1 SAKST}
+    {877795200 36000 0 SAKT}
+    {891100800 39600 1 SAKST}
+    {909244800 36000 0 SAKT}
+    {922550400 39600 1 SAKST}
+    {941299200 36000 0 SAKT}
+    {954000000 39600 1 SAKST}
+    {972748800 36000 0 SAKT}
+    {985449600 39600 1 SAKST}
+    {1004198400 36000 0 SAKT}
+    {1017504000 39600 1 SAKST}
+    {1035648000 36000 0 SAKT}
+    {1048953600 39600 1 SAKST}
+    {1067097600 36000 0 SAKT}
+    {1080403200 39600 1 SAKST}
+    {1099152000 36000 0 SAKT}
+    {1111852800 39600 1 SAKST}
+    {1130601600 36000 0 SAKT}
+    {1143302400 39600 1 SAKST}
+    {1162051200 36000 0 SAKT}
+    {1174752000 39600 1 SAKST}
+    {1193500800 36000 0 SAKT}
+    {1206806400 39600 1 SAKST}
+    {1224950400 36000 0 SAKT}
+    {1238256000 39600 1 SAKST}
+    {1256400000 36000 0 SAKT}
+    {1269705600 39600 1 SAKST}
+    {1288454400 36000 0 SAKT}
+    {1301155200 39600 0 SAKT}
+    {1414249200 36000 0 SAKT}
+    {1459008000 39600 0 SAKT}
+}
diff --git a/library/tzdata/Asia/Samarkand b/library/tzdata/Asia/Samarkand
new file mode 100644
index 0000000..4b3b49f
--- /dev/null
+++ b/library/tzdata/Asia/Samarkand
@@ -0,0 +1,32 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Asia/Samarkand) {
+    {-9223372036854775808 16073 0 LMT}
+    {-1441168073 14400 0 SAMT}
+    {-1247544000 18000 0 SAMT}
+    {354913200 21600 1 SAMST}
+    {370720800 21600 0 TAST}
+    {386445600 18000 0 SAMT}
+    {386449200 21600 1 SAMST}
+    {402256800 18000 0 SAMT}
+    {417985200 21600 1 SAMST}
+    {433792800 18000 0 SAMT}
+    {449607600 21600 1 SAMST}
+    {465339600 18000 0 SAMT}
+    {481064400 21600 1 SAMST}
+    {496789200 18000 0 SAMT}
+    {512514000 21600 1 SAMST}
+    {528238800 18000 0 SAMT}
+    {543963600 21600 1 SAMST}
+    {559688400 18000 0 SAMT}
+    {575413200 21600 1 SAMST}
+    {591138000 18000 0 SAMT}
+    {606862800 21600 1 SAMST}
+    {622587600 18000 0 SAMT}
+    {638312400 21600 1 SAMST}
+    {654642000 18000 0 SAMT}
+    {670366800 21600 1 SAMST}
+    {683665200 21600 0 UZST}
+    {686091600 18000 0 UZT}
+    {694206000 18000 0 UZT}
+}
diff --git a/library/tzdata/Asia/Seoul b/library/tzdata/Asia/Seoul
new file mode 100644
index 0000000..c24a1d8
--- /dev/null
+++ b/library/tzdata/Asia/Seoul
@@ -0,0 +1,27 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Asia/Seoul) {
+    {-9223372036854775808 30472 0 LMT}
+    {-1948782472 30600 0 KST}
+    {-1830414600 32400 0 JCST}
+    {-1017824400 32400 0 JST}
+    {-767350800 32400 0 KST}
+    {-498128400 30600 0 KST}
+    {-462702600 34200 1 KDT}
+    {-451733400 30600 0 KST}
+    {-429784200 34200 1 KDT}
+    {-418296600 30600 0 KST}
+    {-399544200 34200 1 KDT}
+    {-387451800 30600 0 KST}
+    {-368094600 34200 1 KDT}
+    {-356002200 30600 0 KST}
+    {-336645000 34200 1 KDT}
+    {-324552600 30600 0 KST}
+    {-305195400 34200 1 KDT}
+    {-293103000 30600 0 KST}
+    {-264933000 32400 0 KST}
+    {547578000 36000 1 KDT}
+    {560883600 32400 0 KST}
+    {579027600 36000 1 KDT}
+    {592333200 32400 0 KST}
+}
diff --git a/library/tzdata/Asia/Shanghai b/library/tzdata/Asia/Shanghai
new file mode 100644
index 0000000..ff2d2b5
--- /dev/null
+++ b/library/tzdata/Asia/Shanghai
@@ -0,0 +1,23 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Asia/Shanghai) {
+    {-9223372036854775808 29143 0 LMT}
+    {-2177481943 28800 0 CST}
+    {-933494400 32400 1 CDT}
+    {-923130000 28800 0 CST}
+    {-908784000 32400 1 CDT}
+    {-891594000 28800 0 CST}
+    {-662716800 28800 0 CST}
+    {515520000 32400 1 CDT}
+    {527007600 28800 0 CST}
+    {545155200 32400 1 CDT}
+    {558457200 28800 0 CST}
+    {576604800 32400 1 CDT}
+    {589906800 28800 0 CST}
+    {608659200 32400 1 CDT}
+    {621961200 28800 0 CST}
+    {640108800 32400 1 CDT}
+    {653410800 28800 0 CST}
+    {671558400 32400 1 CDT}
+    {684860400 28800 0 CST}
+}
diff --git a/library/tzdata/Asia/Singapore b/library/tzdata/Asia/Singapore
new file mode 100644
index 0000000..e2f226e
--- /dev/null
+++ b/library/tzdata/Asia/Singapore
@@ -0,0 +1,14 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Asia/Singapore) {
+    {-9223372036854775808 24925 0 LMT}
+    {-2177477725 24925 0 SMT}
+    {-2038200925 25200 0 MALT}
+    {-1167634800 26400 1 MALST}
+    {-1073028000 26400 0 MALT}
+    {-894180000 27000 0 MALT}
+    {-879665400 32400 0 JST}
+    {-767005200 27000 0 MALT}
+    {-138785400 27000 0 SGT}
+    {378664200 28800 0 SGT}
+}
diff --git a/library/tzdata/Asia/Srednekolymsk b/library/tzdata/Asia/Srednekolymsk
new file mode 100644
index 0000000..a0586aa
--- /dev/null
+++ b/library/tzdata/Asia/Srednekolymsk
@@ -0,0 +1,71 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Asia/Srednekolymsk) {
+    {-9223372036854775808 36892 0 LMT}
+    {-1441188892 36000 0 MAGT}
+    {-1247565600 39600 0 MAGMMTT}
+    {354891600 43200 1 MAGST}
+    {370699200 39600 0 MAGT}
+    {386427600 43200 1 MAGST}
+    {402235200 39600 0 MAGT}
+    {417963600 43200 1 MAGST}
+    {433771200 39600 0 MAGT}
+    {449586000 43200 1 MAGST}
+    {465318000 39600 0 MAGT}
+    {481042800 43200 1 MAGST}
+    {496767600 39600 0 MAGT}
+    {512492400 43200 1 MAGST}
+    {528217200 39600 0 MAGT}
+    {543942000 43200 1 MAGST}
+    {559666800 39600 0 MAGT}
+    {575391600 43200 1 MAGST}
+    {591116400 39600 0 MAGT}
+    {606841200 43200 1 MAGST}
+    {622566000 39600 0 MAGT}
+    {638290800 43200 1 MAGST}
+    {654620400 39600 0 MAGT}
+    {670345200 36000 0 MAGMMTT}
+    {670348800 39600 1 MAGST}
+    {686073600 36000 0 MAGT}
+    {695750400 39600 0 MAGMMTT}
+    {701794800 43200 1 MAGST}
+    {717519600 39600 0 MAGT}
+    {733244400 43200 1 MAGST}
+    {748969200 39600 0 MAGT}
+    {764694000 43200 1 MAGST}
+    {780418800 39600 0 MAGT}
+    {796143600 43200 1 MAGST}
+    {811868400 39600 0 MAGT}
+    {828198000 43200 1 MAGST}
+    {846342000 39600 0 MAGT}
+    {859647600 43200 1 MAGST}
+    {877791600 39600 0 MAGT}
+    {891097200 43200 1 MAGST}
+    {909241200 39600 0 MAGT}
+    {922546800 43200 1 MAGST}
+    {941295600 39600 0 MAGT}
+    {953996400 43200 1 MAGST}
+    {972745200 39600 0 MAGT}
+    {985446000 43200 1 MAGST}
+    {1004194800 39600 0 MAGT}
+    {1017500400 43200 1 MAGST}
+    {1035644400 39600 0 MAGT}
+    {1048950000 43200 1 MAGST}
+    {1067094000 39600 0 MAGT}
+    {1080399600 43200 1 MAGST}
+    {1099148400 39600 0 MAGT}
+    {1111849200 43200 1 MAGST}
+    {1130598000 39600 0 MAGT}
+    {1143298800 43200 1 MAGST}
+    {1162047600 39600 0 MAGT}
+    {1174748400 43200 1 MAGST}
+    {1193497200 39600 0 MAGT}
+    {1206802800 43200 1 MAGST}
+    {1224946800 39600 0 MAGT}
+    {1238252400 43200 1 MAGST}
+    {1256396400 39600 0 MAGT}
+    {1269702000 43200 1 MAGST}
+    {1288450800 39600 0 MAGT}
+    {1301151600 43200 0 MAGT}
+    {1414245600 39600 0 SRET}
+}
diff --git a/library/tzdata/Asia/Taipei b/library/tzdata/Asia/Taipei
new file mode 100644
index 0000000..61c77ef
--- /dev/null
+++ b/library/tzdata/Asia/Taipei
@@ -0,0 +1,46 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Asia/Taipei) {
+    {-9223372036854775808 29160 0 LMT}
+    {-2335248360 28800 0 JWST}
+    {-1017820800 32400 0 JST}
+    {-766224000 28800 0 CST}
+    {-745833600 32400 1 CDT}
+    {-733827600 28800 0 CST}
+    {-716889600 32400 1 CDT}
+    {-699613200 28800 0 CST}
+    {-683884800 32400 1 CDT}
+    {-670669200 28800 0 CST}
+    {-652348800 32400 1 CDT}
+    {-639133200 28800 0 CST}
+    {-620812800 32400 1 CDT}
+    {-607597200 28800 0 CST}
+    {-589276800 32400 1 CDT}
+    {-576061200 28800 0 CST}
+    {-562924800 32400 1 CDT}
+    {-541760400 28800 0 CST}
+    {-528710400 32400 1 CDT}
+    {-510224400 28800 0 CST}
+    {-497174400 32400 1 CDT}
+    {-478688400 28800 0 CST}
+    {-465638400 32400 1 CDT}
+    {-449830800 28800 0 CST}
+    {-434016000 32400 1 CDT}
+    {-418208400 28800 0 CST}
+    {-402480000 32400 1 CDT}
+    {-386672400 28800 0 CST}
+    {-370944000 32400 1 CDT}
+    {-355136400 28800 0 CST}
+    {-339408000 32400 1 CDT}
+    {-323600400 28800 0 CST}
+    {-302515200 32400 1 CDT}
+    {-291978000 28800 0 CST}
+    {-270979200 32400 1 CDT}
+    {-260442000 28800 0 CST}
+    {133977600 32400 1 CDT}
+    {149785200 28800 0 CST}
+    {165513600 32400 1 CDT}
+    {181321200 28800 0 CST}
+    {299606400 32400 1 CDT}
+    {307551600 28800 0 CST}
+}
diff --git a/library/tzdata/Asia/Tashkent b/library/tzdata/Asia/Tashkent
new file mode 100644
index 0000000..1477376
--- /dev/null
+++ b/library/tzdata/Asia/Tashkent
@@ -0,0 +1,32 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Asia/Tashkent) {
+    {-9223372036854775808 16631 0 LMT}
+    {-1441168631 18000 0 TAST}
+    {-1247547600 21600 0 TAST}
+    {354909600 25200 1 TASST}
+    {370717200 21600 0 TAST}
+    {386445600 25200 1 TASST}
+    {402253200 21600 0 TAST}
+    {417981600 25200 1 TASST}
+    {433789200 21600 0 TAST}
+    {449604000 25200 1 TASST}
+    {465336000 21600 0 TAST}
+    {481060800 25200 1 TASST}
+    {496785600 21600 0 TAST}
+    {512510400 25200 1 TASST}
+    {528235200 21600 0 TAST}
+    {543960000 25200 1 TASST}
+    {559684800 21600 0 TAST}
+    {575409600 25200 1 TASST}
+    {591134400 21600 0 TAST}
+    {606859200 25200 1 TASST}
+    {622584000 21600 0 TAST}
+    {638308800 25200 1 TASST}
+    {654638400 21600 0 TAST}
+    {670363200 18000 0 TAST}
+    {670366800 21600 1 TASST}
+    {683665200 21600 0 UZST}
+    {686091600 18000 0 UZT}
+    {694206000 18000 0 UZT}
+}
diff --git a/library/tzdata/Asia/Tbilisi b/library/tzdata/Asia/Tbilisi
new file mode 100644
index 0000000..54b278a
--- /dev/null
+++ b/library/tzdata/Asia/Tbilisi
@@ -0,0 +1,60 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Asia/Tbilisi) {
+    {-9223372036854775808 10751 0 LMT}
+    {-2840151551 10751 0 TBMT}
+    {-1441162751 10800 0 TBIT}
+    {-405140400 14400 0 TBIT}
+    {354916800 18000 1 TBIST}
+    {370724400 14400 0 TBIT}
+    {386452800 18000 1 TBIST}
+    {402260400 14400 0 TBIT}
+    {417988800 18000 1 TBIST}
+    {433796400 14400 0 TBIT}
+    {449611200 18000 1 TBIST}
+    {465343200 14400 0 TBIT}
+    {481068000 18000 1 TBIST}
+    {496792800 14400 0 TBIT}
+    {512517600 18000 1 TBIST}
+    {528242400 14400 0 TBIT}
+    {543967200 18000 1 TBIST}
+    {559692000 14400 0 TBIT}
+    {575416800 18000 1 TBIST}
+    {591141600 14400 0 TBIT}
+    {606866400 18000 1 TBIST}
+    {622591200 14400 0 TBIT}
+    {638316000 18000 1 TBIST}
+    {654645600 14400 0 TBIT}
+    {670370400 14400 1 TBIST}
+    {671140800 14400 0 GEST}
+    {686098800 10800 0 GET}
+    {694213200 10800 0 GET}
+    {701816400 14400 1 GEST}
+    {717537600 10800 0 GET}
+    {733266000 14400 1 GEST}
+    {748987200 10800 0 GET}
+    {764715600 14400 1 GEST}
+    {780440400 14400 0 GET}
+    {796161600 18000 1 GEST}
+    {811882800 14400 0 GET}
+    {828216000 18000 1 GEST}
+    {846360000 18000 1 GEST}
+    {859662000 18000 0 GEST}
+    {877806000 14400 0 GET}
+    {891115200 18000 1 GEST}
+    {909255600 14400 0 GET}
+    {922564800 18000 1 GEST}
+    {941310000 14400 0 GET}
+    {954014400 18000 1 GEST}
+    {972759600 14400 0 GET}
+    {985464000 18000 1 GEST}
+    {1004209200 14400 0 GET}
+    {1017518400 18000 1 GEST}
+    {1035658800 14400 0 GET}
+    {1048968000 18000 1 GEST}
+    {1067108400 14400 0 GET}
+    {1080417600 18000 1 GEST}
+    {1088280000 14400 0 GEST}
+    {1099177200 10800 0 GET}
+    {1111878000 14400 0 GET}
+}
diff --git a/library/tzdata/Asia/Tehran b/library/tzdata/Asia/Tehran
new file mode 100644
index 0000000..5fd840d
--- /dev/null
+++ b/library/tzdata/Asia/Tehran
@@ -0,0 +1,229 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Asia/Tehran) {
+    {-9223372036854775808 12344 0 LMT}
+    {-1704165944 12344 0 TMT}
+    {-757394744 12600 0 IRST}
+    {247177800 14400 0 IRST}
+    {259272000 18000 1 IRDT}
+    {277758000 14400 0 IRST}
+    {283982400 12600 0 IRST}
+    {290809800 16200 1 IRDT}
+    {306531000 12600 0 IRST}
+    {322432200 16200 1 IRDT}
+    {338499000 12600 0 IRST}
+    {673216200 16200 1 IRDT}
+    {685481400 12600 0 IRST}
+    {701209800 16200 1 IRDT}
+    {717103800 12600 0 IRST}
+    {732745800 16200 1 IRDT}
+    {748639800 12600 0 IRST}
+    {764281800 16200 1 IRDT}
+    {780175800 12600 0 IRST}
+    {795817800 16200 1 IRDT}
+    {811711800 12600 0 IRST}
+    {827353800 16200 1 IRDT}
+    {843247800 12600 0 IRST}
+    {858976200 16200 1 IRDT}
+    {874870200 12600 0 IRST}
+    {890512200 16200 1 IRDT}
+    {906406200 12600 0 IRST}
+    {922048200 16200 1 IRDT}
+    {937942200 12600 0 IRST}
+    {953584200 16200 1 IRDT}
+    {969478200 12600 0 IRST}
+    {985206600 16200 1 IRDT}
+    {1001100600 12600 0 IRST}
+    {1016742600 16200 1 IRDT}
+    {1032636600 12600 0 IRST}
+    {1048278600 16200 1 IRDT}
+    {1064172600 12600 0 IRST}
+    {1079814600 16200 1 IRDT}
+    {1095708600 12600 0 IRST}
+    {1111437000 16200 1 IRDT}
+    {1127331000 12600 0 IRST}
+    {1206045000 16200 1 IRDT}
+    {1221939000 12600 0 IRST}
+    {1237667400 16200 1 IRDT}
+    {1253561400 12600 0 IRST}
+    {1269203400 16200 1 IRDT}
+    {1285097400 12600 0 IRST}
+    {1300739400 16200 1 IRDT}
+    {1316633400 12600 0 IRST}
+    {1332275400 16200 1 IRDT}
+    {1348169400 12600 0 IRST}
+    {1363897800 16200 1 IRDT}
+    {1379791800 12600 0 IRST}
+    {1395433800 16200 1 IRDT}
+    {1411327800 12600 0 IRST}
+    {1426969800 16200 1 IRDT}
+    {1442863800 12600 0 IRST}
+    {1458505800 16200 1 IRDT}
+    {1474399800 12600 0 IRST}
+    {1490128200 16200 1 IRDT}
+    {1506022200 12600 0 IRST}
+    {1521664200 16200 1 IRDT}
+    {1537558200 12600 0 IRST}
+    {1553200200 16200 1 IRDT}
+    {1569094200 12600 0 IRST}
+    {1584736200 16200 1 IRDT}
+    {1600630200 12600 0 IRST}
+    {1616358600 16200 1 IRDT}
+    {1632252600 12600 0 IRST}
+    {1647894600 16200 1 IRDT}
+    {1663788600 12600 0 IRST}
+    {1679430600 16200 1 IRDT}
+    {1695324600 12600 0 IRST}
+    {1710966600 16200 1 IRDT}
+    {1726860600 12600 0 IRST}
+    {1742589000 16200 1 IRDT}
+    {1758483000 12600 0 IRST}
+    {1774125000 16200 1 IRDT}
+    {1790019000 12600 0 IRST}
+    {1805661000 16200 1 IRDT}
+    {1821555000 12600 0 IRST}
+    {1837197000 16200 1 IRDT}
+    {1853091000 12600 0 IRST}
+    {1868733000 16200 1 IRDT}
+    {1884627000 12600 0 IRST}
+    {1900355400 16200 1 IRDT}
+    {1916249400 12600 0 IRST}
+    {1931891400 16200 1 IRDT}
+    {1947785400 12600 0 IRST}
+    {1963427400 16200 1 IRDT}
+    {1979321400 12600 0 IRST}
+    {1994963400 16200 1 IRDT}
+    {2010857400 12600 0 IRST}
+    {2026585800 16200 1 IRDT}
+    {2042479800 12600 0 IRST}
+    {2058121800 16200 1 IRDT}
+    {2074015800 12600 0 IRST}
+    {2089657800 16200 1 IRDT}
+    {2105551800 12600 0 IRST}
+    {2121193800 16200 1 IRDT}
+    {2137087800 12600 0 IRST}
+    {2152729800 16200 1 IRDT}
+    {2168623800 12600 0 IRST}
+    {2184265800 16200 1 IRDT}
+    {2200159800 12600 0 IRST}
+    {2215888200 16200 1 IRDT}
+    {2231782200 12600 0 IRST}
+    {2247424200 16200 1 IRDT}
+    {2263318200 12600 0 IRST}
+    {2278960200 16200 1 IRDT}
+    {2294854200 12600 0 IRST}
+    {2310496200 16200 1 IRDT}
+    {2326390200 12600 0 IRST}
+    {2342118600 16200 1 IRDT}
+    {2358012600 12600 0 IRST}
+    {2373654600 16200 1 IRDT}
+    {2389548600 12600 0 IRST}
+    {2405190600 16200 1 IRDT}
+    {2421084600 12600 0 IRST}
+    {2436726600 16200 1 IRDT}
+    {2452620600 12600 0 IRST}
+    {2468349000 16200 1 IRDT}
+    {2484243000 12600 0 IRST}
+    {2499885000 16200 1 IRDT}
+    {2515779000 12600 0 IRST}
+    {2531421000 16200 1 IRDT}
+    {2547315000 12600 0 IRST}
+    {2562957000 16200 1 IRDT}
+    {2578851000 12600 0 IRST}
+    {2594579400 16200 1 IRDT}
+    {2610473400 12600 0 IRST}
+    {2626115400 16200 1 IRDT}
+    {2642009400 12600 0 IRST}
+    {2657651400 16200 1 IRDT}
+    {2673545400 12600 0 IRST}
+    {2689187400 16200 1 IRDT}
+    {2705081400 12600 0 IRST}
+    {2720809800 16200 1 IRDT}
+    {2736703800 12600 0 IRST}
+    {2752345800 16200 1 IRDT}
+    {2768239800 12600 0 IRST}
+    {2783881800 16200 1 IRDT}
+    {2799775800 12600 0 IRST}
+    {2815417800 16200 1 IRDT}
+    {2831311800 12600 0 IRST}
+    {2847040200 16200 1 IRDT}
+    {2862934200 12600 0 IRST}
+    {2878576200 16200 1 IRDT}
+    {2894470200 12600 0 IRST}
+    {2910112200 16200 1 IRDT}
+    {2926006200 12600 0 IRST}
+    {2941648200 16200 1 IRDT}
+    {2957542200 12600 0 IRST}
+    {2973270600 16200 1 IRDT}
+    {2989164600 12600 0 IRST}
+    {3004806600 16200 1 IRDT}
+    {3020700600 12600 0 IRST}
+    {3036342600 16200 1 IRDT}
+    {3052236600 12600 0 IRST}
+    {3067878600 16200 1 IRDT}
+    {3083772600 12600 0 IRST}
+    {3099501000 16200 1 IRDT}
+    {3115395000 12600 0 IRST}
+    {3131037000 16200 1 IRDT}
+    {3146931000 12600 0 IRST}
+    {3162573000 16200 1 IRDT}
+    {3178467000 12600 0 IRST}
+    {3194109000 16200 1 IRDT}
+    {3210003000 12600 0 IRST}
+    {3225731400 16200 1 IRDT}
+    {3241625400 12600 0 IRST}
+    {3257267400 16200 1 IRDT}
+    {3273161400 12600 0 IRST}
+    {3288803400 16200 1 IRDT}
+    {3304697400 12600 0 IRST}
+    {3320339400 16200 1 IRDT}
+    {3336233400 12600 0 IRST}
+    {3351961800 16200 1 IRDT}
+    {3367855800 12600 0 IRST}
+    {3383497800 16200 1 IRDT}
+    {3399391800 12600 0 IRST}
+    {3415033800 16200 1 IRDT}
+    {3430927800 12600 0 IRST}
+    {3446569800 16200 1 IRDT}
+    {3462463800 12600 0 IRST}
+    {3478192200 16200 1 IRDT}
+    {3494086200 12600 0 IRST}
+    {3509728200 16200 1 IRDT}
+    {3525622200 12600 0 IRST}
+    {3541264200 16200 1 IRDT}
+    {3557158200 12600 0 IRST}
+    {3572800200 16200 1 IRDT}
+    {3588694200 12600 0 IRST}
+    {3604422600 16200 1 IRDT}
+    {3620316600 12600 0 IRST}
+    {3635958600 16200 1 IRDT}
+    {3651852600 12600 0 IRST}
+    {3667494600 16200 1 IRDT}
+    {3683388600 12600 0 IRST}
+    {3699030600 16200 1 IRDT}
+    {3714924600 12600 0 IRST}
+    {3730653000 16200 1 IRDT}
+    {3746547000 12600 0 IRST}
+    {3762189000 16200 1 IRDT}
+    {3778083000 12600 0 IRST}
+    {3793725000 16200 1 IRDT}
+    {3809619000 12600 0 IRST}
+    {3825261000 16200 1 IRDT}
+    {3841155000 12600 0 IRST}
+    {3856883400 16200 1 IRDT}
+    {3872777400 12600 0 IRST}
+    {3888419400 16200 1 IRDT}
+    {3904313400 12600 0 IRST}
+    {3919955400 16200 1 IRDT}
+    {3935849400 12600 0 IRST}
+    {3951491400 16200 1 IRDT}
+    {3967385400 12600 0 IRST}
+    {3983113800 16200 1 IRDT}
+    {3999007800 12600 0 IRST}
+    {4014649800 16200 1 IRDT}
+    {4030543800 12600 0 IRST}
+    {4046185800 16200 1 IRDT}
+    {4062079800 12600 0 IRST}
+    {4077721800 16200 1 IRDT}
+    {4093615800 12600 0 IRST}
+}
diff --git a/library/tzdata/Asia/Tel_Aviv b/library/tzdata/Asia/Tel_Aviv
new file mode 100644
index 0000000..3e7278d
--- /dev/null
+++ b/library/tzdata/Asia/Tel_Aviv
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Asia/Jerusalem)]} {
+    LoadTimeZoneFile Asia/Jerusalem
+}
+set TZData(:Asia/Tel_Aviv) $TZData(:Asia/Jerusalem)
diff --git a/library/tzdata/Asia/Thimbu b/library/tzdata/Asia/Thimbu
new file mode 100644
index 0000000..94b0846
--- /dev/null
+++ b/library/tzdata/Asia/Thimbu
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Asia/Thimphu)]} {
+    LoadTimeZoneFile Asia/Thimphu
+}
+set TZData(:Asia/Thimbu) $TZData(:Asia/Thimphu)
diff --git a/library/tzdata/Asia/Thimphu b/library/tzdata/Asia/Thimphu
new file mode 100644
index 0000000..8c981de
--- /dev/null
+++ b/library/tzdata/Asia/Thimphu
@@ -0,0 +1,7 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Asia/Thimphu) {
+    {-9223372036854775808 21516 0 LMT}
+    {-706341516 19800 0 IST}
+    {560025000 21600 0 BTT}
+}
diff --git a/library/tzdata/Asia/Tokyo b/library/tzdata/Asia/Tokyo
new file mode 100644
index 0000000..5bfc75c
--- /dev/null
+++ b/library/tzdata/Asia/Tokyo
@@ -0,0 +1,16 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Asia/Tokyo) {
+    {-9223372036854775808 33539 0 LMT}
+    {-2587712400 32400 0 JST}
+    {-2335251600 32400 0 JCST}
+    {-1017824400 32400 0 JST}
+    {-683794800 36000 1 JDT}
+    {-672393600 32400 0 JST}
+    {-654764400 36000 1 JDT}
+    {-640944000 32400 0 JST}
+    {-620290800 36000 1 JDT}
+    {-609494400 32400 0 JST}
+    {-588841200 36000 1 JDT}
+    {-578044800 32400 0 JST}
+}
diff --git a/library/tzdata/Asia/Tomsk b/library/tzdata/Asia/Tomsk
new file mode 100644
index 0000000..0694d01
--- /dev/null
+++ b/library/tzdata/Asia/Tomsk
@@ -0,0 +1,73 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Asia/Tomsk) {
+    {-9223372036854775808 20391 0 LMT}
+    {-1578807591 21600 0 +06}
+    {-1247551200 25200 0 +08}
+    {354906000 28800 1 +08}
+    {370713600 25200 0 +07}
+    {386442000 28800 1 +08}
+    {402249600 25200 0 +07}
+    {417978000 28800 1 +08}
+    {433785600 25200 0 +07}
+    {449600400 28800 1 +08}
+    {465332400 25200 0 +07}
+    {481057200 28800 1 +08}
+    {496782000 25200 0 +07}
+    {512506800 28800 1 +08}
+    {528231600 25200 0 +07}
+    {543956400 28800 1 +08}
+    {559681200 25200 0 +07}
+    {575406000 28800 1 +08}
+    {591130800 25200 0 +07}
+    {606855600 28800 1 +08}
+    {622580400 25200 0 +07}
+    {638305200 28800 1 +08}
+    {654634800 25200 0 +07}
+    {670359600 21600 0 +07}
+    {670363200 25200 1 +07}
+    {686088000 21600 0 +06}
+    {695764800 25200 0 +08}
+    {701809200 28800 1 +08}
+    {717534000 25200 0 +07}
+    {733258800 28800 1 +08}
+    {748983600 25200 0 +07}
+    {764708400 28800 1 +08}
+    {780433200 25200 0 +07}
+    {796158000 28800 1 +08}
+    {811882800 25200 0 +07}
+    {828212400 28800 1 +08}
+    {846356400 25200 0 +07}
+    {859662000 28800 1 +08}
+    {877806000 25200 0 +07}
+    {891111600 28800 1 +08}
+    {909255600 25200 0 +07}
+    {922561200 28800 1 +08}
+    {941310000 25200 0 +07}
+    {954010800 28800 1 +08}
+    {972759600 25200 0 +07}
+    {985460400 28800 1 +08}
+    {1004209200 25200 0 +07}
+    {1017514800 28800 1 +08}
+    {1020196800 25200 0 +07}
+    {1035662400 21600 0 +06}
+    {1048968000 25200 1 +07}
+    {1067112000 21600 0 +06}
+    {1080417600 25200 1 +07}
+    {1099166400 21600 0 +06}
+    {1111867200 25200 1 +07}
+    {1130616000 21600 0 +06}
+    {1143316800 25200 1 +07}
+    {1162065600 21600 0 +06}
+    {1174766400 25200 1 +07}
+    {1193515200 21600 0 +06}
+    {1206820800 25200 1 +07}
+    {1224964800 21600 0 +06}
+    {1238270400 25200 1 +07}
+    {1256414400 21600 0 +06}
+    {1269720000 25200 1 +07}
+    {1288468800 21600 0 +06}
+    {1301169600 25200 0 +07}
+    {1414263600 21600 0 +06}
+    {1464465600 25200 0 +07}
+}
diff --git a/library/tzdata/Asia/Ujung_Pandang b/library/tzdata/Asia/Ujung_Pandang
new file mode 100644
index 0000000..abe142e
--- /dev/null
+++ b/library/tzdata/Asia/Ujung_Pandang
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Asia/Makassar)]} {
+    LoadTimeZoneFile Asia/Makassar
+}
+set TZData(:Asia/Ujung_Pandang) $TZData(:Asia/Makassar)
diff --git a/library/tzdata/Asia/Ulaanbaatar b/library/tzdata/Asia/Ulaanbaatar
new file mode 100644
index 0000000..93e066c
--- /dev/null
+++ b/library/tzdata/Asia/Ulaanbaatar
@@ -0,0 +1,221 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Asia/Ulaanbaatar) {
+    {-9223372036854775808 25652 0 LMT}
+    {-2032931252 25200 0 ULAT}
+    {252435600 28800 0 ULAT}
+    {417974400 32400 1 ULAST}
+    {433782000 28800 0 ULAT}
+    {449596800 32400 1 ULAST}
+    {465318000 28800 0 ULAT}
+    {481046400 32400 1 ULAST}
+    {496767600 28800 0 ULAT}
+    {512496000 32400 1 ULAST}
+    {528217200 28800 0 ULAT}
+    {543945600 32400 1 ULAST}
+    {559666800 28800 0 ULAT}
+    {575395200 32400 1 ULAST}
+    {591116400 28800 0 ULAT}
+    {606844800 32400 1 ULAST}
+    {622566000 28800 0 ULAT}
+    {638294400 32400 1 ULAST}
+    {654620400 28800 0 ULAT}
+    {670348800 32400 1 ULAST}
+    {686070000 28800 0 ULAT}
+    {701798400 32400 1 ULAST}
+    {717519600 28800 0 ULAT}
+    {733248000 32400 1 ULAST}
+    {748969200 28800 0 ULAT}
+    {764697600 32400 1 ULAST}
+    {780418800 28800 0 ULAT}
+    {796147200 32400 1 ULAST}
+    {811868400 28800 0 ULAT}
+    {828201600 32400 1 ULAST}
+    {843922800 28800 0 ULAT}
+    {859651200 32400 1 ULAST}
+    {875372400 28800 0 ULAT}
+    {891100800 32400 1 ULAST}
+    {906822000 28800 0 ULAT}
+    {988394400 32400 1 ULAST}
+    {1001696400 28800 0 ULAT}
+    {1017424800 32400 1 ULAST}
+    {1033146000 28800 0 ULAT}
+    {1048874400 32400 1 ULAST}
+    {1064595600 28800 0 ULAT}
+    {1080324000 32400 1 ULAST}
+    {1096045200 28800 0 ULAT}
+    {1111773600 32400 1 ULAST}
+    {1127494800 28800 0 ULAT}
+    {1143223200 32400 1 ULAST}
+    {1159549200 28800 0 ULAT}
+    {1427479200 32400 1 ULAST}
+    {1443193200 28800 0 ULAT}
+    {1458928800 32400 1 ULAST}
+    {1474642800 28800 0 ULAT}
+    {1490378400 32400 1 ULAST}
+    {1506697200 28800 0 ULAT}
+    {1522432800 32400 1 ULAST}
+    {1538146800 28800 0 ULAT}
+    {1553882400 32400 1 ULAST}
+    {1569596400 28800 0 ULAT}
+    {1585332000 32400 1 ULAST}
+    {1601046000 28800 0 ULAT}
+    {1616781600 32400 1 ULAST}
+    {1632495600 28800 0 ULAT}
+    {1648231200 32400 1 ULAST}
+    {1663945200 28800 0 ULAT}
+    {1679680800 32400 1 ULAST}
+    {1695999600 28800 0 ULAT}
+    {1711735200 32400 1 ULAST}
+    {1727449200 28800 0 ULAT}
+    {1743184800 32400 1 ULAST}
+    {1758898800 28800 0 ULAT}
+    {1774634400 32400 1 ULAST}
+    {1790348400 28800 0 ULAT}
+    {1806084000 32400 1 ULAST}
+    {1821798000 28800 0 ULAT}
+    {1837533600 32400 1 ULAST}
+    {1853852400 28800 0 ULAT}
+    {1869588000 32400 1 ULAST}
+    {1885302000 28800 0 ULAT}
+    {1901037600 32400 1 ULAST}
+    {1916751600 28800 0 ULAT}
+    {1932487200 32400 1 ULAST}
+    {1948201200 28800 0 ULAT}
+    {1963936800 32400 1 ULAST}
+    {1979650800 28800 0 ULAT}
+    {1995386400 32400 1 ULAST}
+    {2011100400 28800 0 ULAT}
+    {2026836000 32400 1 ULAST}
+    {2043154800 28800 0 ULAT}
+    {2058890400 32400 1 ULAST}
+    {2074604400 28800 0 ULAT}
+    {2090340000 32400 1 ULAST}
+    {2106054000 28800 0 ULAT}
+    {2121789600 32400 1 ULAST}
+    {2137503600 28800 0 ULAT}
+    {2153239200 32400 1 ULAST}
+    {2168953200 28800 0 ULAT}
+    {2184688800 32400 1 ULAST}
+    {2200402800 28800 0 ULAT}
+    {2216743200 32400 1 ULAST}
+    {2232457200 28800 0 ULAT}
+    {2248192800 32400 1 ULAST}
+    {2263906800 28800 0 ULAT}
+    {2279642400 32400 1 ULAST}
+    {2295356400 28800 0 ULAT}
+    {2311092000 32400 1 ULAST}
+    {2326806000 28800 0 ULAT}
+    {2342541600 32400 1 ULAST}
+    {2358255600 28800 0 ULAT}
+    {2373991200 32400 1 ULAST}
+    {2390310000 28800 0 ULAT}
+    {2406045600 32400 1 ULAST}
+    {2421759600 28800 0 ULAT}
+    {2437495200 32400 1 ULAST}
+    {2453209200 28800 0 ULAT}
+    {2468944800 32400 1 ULAST}
+    {2484658800 28800 0 ULAT}
+    {2500394400 32400 1 ULAST}
+    {2516108400 28800 0 ULAT}
+    {2531844000 32400 1 ULAST}
+    {2547558000 28800 0 ULAT}
+    {2563293600 32400 1 ULAST}
+    {2579612400 28800 0 ULAT}
+    {2595348000 32400 1 ULAST}
+    {2611062000 28800 0 ULAT}
+    {2626797600 32400 1 ULAST}
+    {2642511600 28800 0 ULAT}
+    {2658247200 32400 1 ULAST}
+    {2673961200 28800 0 ULAT}
+    {2689696800 32400 1 ULAST}
+    {2705410800 28800 0 ULAT}
+    {2721146400 32400 1 ULAST}
+    {2737465200 28800 0 ULAT}
+    {2753200800 32400 1 ULAST}
+    {2768914800 28800 0 ULAT}
+    {2784650400 32400 1 ULAST}
+    {2800364400 28800 0 ULAT}
+    {2816100000 32400 1 ULAST}
+    {2831814000 28800 0 ULAT}
+    {2847549600 32400 1 ULAST}
+    {2863263600 28800 0 ULAT}
+    {2878999200 32400 1 ULAST}
+    {2894713200 28800 0 ULAT}
+    {2910448800 32400 1 ULAST}
+    {2926767600 28800 0 ULAT}
+    {2942503200 32400 1 ULAST}
+    {2958217200 28800 0 ULAT}
+    {2973952800 32400 1 ULAST}
+    {2989666800 28800 0 ULAT}
+    {3005402400 32400 1 ULAST}
+    {3021116400 28800 0 ULAT}
+    {3036852000 32400 1 ULAST}
+    {3052566000 28800 0 ULAT}
+    {3068301600 32400 1 ULAST}
+    {3084015600 28800 0 ULAT}
+    {3100356000 32400 1 ULAST}
+    {3116070000 28800 0 ULAT}
+    {3131805600 32400 1 ULAST}
+    {3147519600 28800 0 ULAT}
+    {3163255200 32400 1 ULAST}
+    {3178969200 28800 0 ULAT}
+    {3194704800 32400 1 ULAST}
+    {3210418800 28800 0 ULAT}
+    {3226154400 32400 1 ULAST}
+    {3241868400 28800 0 ULAT}
+    {3257604000 32400 1 ULAST}
+    {3273922800 28800 0 ULAT}
+    {3289658400 32400 1 ULAST}
+    {3305372400 28800 0 ULAT}
+    {3321108000 32400 1 ULAST}
+    {3336822000 28800 0 ULAT}
+    {3352557600 32400 1 ULAST}
+    {3368271600 28800 0 ULAT}
+    {3384007200 32400 1 ULAST}
+    {3399721200 28800 0 ULAT}
+    {3415456800 32400 1 ULAST}
+    {3431170800 28800 0 ULAT}
+    {3446906400 32400 1 ULAST}
+    {3463225200 28800 0 ULAT}
+    {3478960800 32400 1 ULAST}
+    {3494674800 28800 0 ULAT}
+    {3510410400 32400 1 ULAST}
+    {3526124400 28800 0 ULAT}
+    {3541860000 32400 1 ULAST}
+    {3557574000 28800 0 ULAT}
+    {3573309600 32400 1 ULAST}
+    {3589023600 28800 0 ULAT}
+    {3604759200 32400 1 ULAST}
+    {3621078000 28800 0 ULAT}
+    {3636813600 32400 1 ULAST}
+    {3652527600 28800 0 ULAT}
+    {3668263200 32400 1 ULAST}
+    {3683977200 28800 0 ULAT}
+    {3699712800 32400 1 ULAST}
+    {3715426800 28800 0 ULAT}
+    {3731162400 32400 1 ULAST}
+    {3746876400 28800 0 ULAT}
+    {3762612000 32400 1 ULAST}
+    {3778326000 28800 0 ULAT}
+    {3794061600 32400 1 ULAST}
+    {3810380400 28800 0 ULAT}
+    {3826116000 32400 1 ULAST}
+    {3841830000 28800 0 ULAT}
+    {3857565600 32400 1 ULAST}
+    {3873279600 28800 0 ULAT}
+    {3889015200 32400 1 ULAST}
+    {3904729200 28800 0 ULAT}
+    {3920464800 32400 1 ULAST}
+    {3936178800 28800 0 ULAT}
+    {3951914400 32400 1 ULAST}
+    {3967628400 28800 0 ULAT}
+    {3983968800 32400 1 ULAST}
+    {3999682800 28800 0 ULAT}
+    {4015418400 32400 1 ULAST}
+    {4031132400 28800 0 ULAT}
+    {4046868000 32400 1 ULAST}
+    {4062582000 28800 0 ULAT}
+    {4078317600 32400 1 ULAST}
+    {4094031600 28800 0 ULAT}
+}
diff --git a/library/tzdata/Asia/Ulan_Bator b/library/tzdata/Asia/Ulan_Bator
new file mode 100644
index 0000000..3215ee7
--- /dev/null
+++ b/library/tzdata/Asia/Ulan_Bator
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Asia/Ulaanbaatar)]} {
+    LoadTimeZoneFile Asia/Ulaanbaatar
+}
+set TZData(:Asia/Ulan_Bator) $TZData(:Asia/Ulaanbaatar)
diff --git a/library/tzdata/Asia/Urumqi b/library/tzdata/Asia/Urumqi
new file mode 100644
index 0000000..4f3cd67
--- /dev/null
+++ b/library/tzdata/Asia/Urumqi
@@ -0,0 +1,6 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Asia/Urumqi) {
+    {-9223372036854775808 21020 0 LMT}
+    {-1325483420 21600 0 XJT}
+}
diff --git a/library/tzdata/Asia/Ust-Nera b/library/tzdata/Asia/Ust-Nera
new file mode 100644
index 0000000..3380b7b
--- /dev/null
+++ b/library/tzdata/Asia/Ust-Nera
@@ -0,0 +1,71 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Asia/Ust-Nera) {
+    {-9223372036854775808 34374 0 LMT}
+    {-1579426374 28800 0 YAKT}
+    {354898800 43200 0 MAGST}
+    {370699200 39600 0 MAGT}
+    {386427600 43200 1 MAGST}
+    {402235200 39600 0 MAGT}
+    {417963600 43200 1 MAGST}
+    {433771200 39600 0 MAGT}
+    {449586000 43200 1 MAGST}
+    {465318000 39600 0 MAGT}
+    {481042800 43200 1 MAGST}
+    {496767600 39600 0 MAGT}
+    {512492400 43200 1 MAGST}
+    {528217200 39600 0 MAGT}
+    {543942000 43200 1 MAGST}
+    {559666800 39600 0 MAGT}
+    {575391600 43200 1 MAGST}
+    {591116400 39600 0 MAGT}
+    {606841200 43200 1 MAGST}
+    {622566000 39600 0 MAGT}
+    {638290800 43200 1 MAGST}
+    {654620400 39600 0 MAGT}
+    {670345200 36000 0 MAGMMTT}
+    {670348800 39600 1 MAGST}
+    {686073600 36000 0 MAGT}
+    {695750400 39600 0 MAGMMTT}
+    {701794800 43200 1 MAGST}
+    {717519600 39600 0 MAGT}
+    {733244400 43200 1 MAGST}
+    {748969200 39600 0 MAGT}
+    {764694000 43200 1 MAGST}
+    {780418800 39600 0 MAGT}
+    {796143600 43200 1 MAGST}
+    {811868400 39600 0 MAGT}
+    {828198000 43200 1 MAGST}
+    {846342000 39600 0 MAGT}
+    {859647600 43200 1 MAGST}
+    {877791600 39600 0 MAGT}
+    {891097200 43200 1 MAGST}
+    {909241200 39600 0 MAGT}
+    {922546800 43200 1 MAGST}
+    {941295600 39600 0 MAGT}
+    {953996400 43200 1 MAGST}
+    {972745200 39600 0 MAGT}
+    {985446000 43200 1 MAGST}
+    {1004194800 39600 0 MAGT}
+    {1017500400 43200 1 MAGST}
+    {1035644400 39600 0 MAGT}
+    {1048950000 43200 1 MAGST}
+    {1067094000 39600 0 MAGT}
+    {1080399600 43200 1 MAGST}
+    {1099148400 39600 0 MAGT}
+    {1111849200 43200 1 MAGST}
+    {1130598000 39600 0 MAGT}
+    {1143298800 43200 1 MAGST}
+    {1162047600 39600 0 MAGT}
+    {1174748400 43200 1 MAGST}
+    {1193497200 39600 0 MAGT}
+    {1206802800 43200 1 MAGST}
+    {1224946800 39600 0 MAGT}
+    {1238252400 43200 1 MAGST}
+    {1256396400 39600 0 MAGT}
+    {1269702000 43200 1 MAGST}
+    {1288450800 39600 0 MAGT}
+    {1301151600 43200 0 MAGT}
+    {1315828800 39600 0 VLAT}
+    {1414249200 36000 0 VLAT}
+}
diff --git a/library/tzdata/Asia/Vientiane b/library/tzdata/Asia/Vientiane
new file mode 100644
index 0000000..27b20ce
--- /dev/null
+++ b/library/tzdata/Asia/Vientiane
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Asia/Bangkok)]} {
+    LoadTimeZoneFile Asia/Bangkok
+}
+set TZData(:Asia/Vientiane) $TZData(:Asia/Bangkok)
diff --git a/library/tzdata/Asia/Vladivostok b/library/tzdata/Asia/Vladivostok
new file mode 100644
index 0000000..b279d1c
--- /dev/null
+++ b/library/tzdata/Asia/Vladivostok
@@ -0,0 +1,71 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Asia/Vladivostok) {
+    {-9223372036854775808 31651 0 LMT}
+    {-1487321251 32400 0 VLAT}
+    {-1247562000 36000 0 VLAMMTT}
+    {354895200 39600 1 VLAST}
+    {370702800 36000 0 VLAT}
+    {386431200 39600 1 VLAST}
+    {402238800 36000 0 VLAT}
+    {417967200 39600 1 VLAST}
+    {433774800 36000 0 VLAT}
+    {449589600 39600 1 VLAST}
+    {465321600 36000 0 VLAT}
+    {481046400 39600 1 VLAST}
+    {496771200 36000 0 VLAT}
+    {512496000 39600 1 VLAST}
+    {528220800 36000 0 VLAT}
+    {543945600 39600 1 VLAST}
+    {559670400 36000 0 VLAT}
+    {575395200 39600 1 VLAST}
+    {591120000 36000 0 VLAT}
+    {606844800 39600 1 VLAST}
+    {622569600 36000 0 VLAT}
+    {638294400 39600 1 VLAST}
+    {654624000 36000 0 VLAT}
+    {670348800 32400 0 VLAMMTT}
+    {670352400 36000 1 VLAST}
+    {686077200 32400 0 VLAT}
+    {695754000 36000 0 VLAMMTT}
+    {701798400 39600 1 VLAST}
+    {717523200 36000 0 VLAT}
+    {733248000 39600 1 VLAST}
+    {748972800 36000 0 VLAT}
+    {764697600 39600 1 VLAST}
+    {780422400 36000 0 VLAT}
+    {796147200 39600 1 VLAST}
+    {811872000 36000 0 VLAT}
+    {828201600 39600 1 VLAST}
+    {846345600 36000 0 VLAT}
+    {859651200 39600 1 VLAST}
+    {877795200 36000 0 VLAT}
+    {891100800 39600 1 VLAST}
+    {909244800 36000 0 VLAT}
+    {922550400 39600 1 VLAST}
+    {941299200 36000 0 VLAT}
+    {954000000 39600 1 VLAST}
+    {972748800 36000 0 VLAT}
+    {985449600 39600 1 VLAST}
+    {1004198400 36000 0 VLAT}
+    {1017504000 39600 1 VLAST}
+    {1035648000 36000 0 VLAT}
+    {1048953600 39600 1 VLAST}
+    {1067097600 36000 0 VLAT}
+    {1080403200 39600 1 VLAST}
+    {1099152000 36000 0 VLAT}
+    {1111852800 39600 1 VLAST}
+    {1130601600 36000 0 VLAT}
+    {1143302400 39600 1 VLAST}
+    {1162051200 36000 0 VLAT}
+    {1174752000 39600 1 VLAST}
+    {1193500800 36000 0 VLAT}
+    {1206806400 39600 1 VLAST}
+    {1224950400 36000 0 VLAT}
+    {1238256000 39600 1 VLAST}
+    {1256400000 36000 0 VLAT}
+    {1269705600 39600 1 VLAST}
+    {1288454400 36000 0 VLAT}
+    {1301155200 39600 0 VLAT}
+    {1414249200 36000 0 VLAT}
+}
diff --git a/library/tzdata/Asia/Yakutsk b/library/tzdata/Asia/Yakutsk
new file mode 100644
index 0000000..0074379
--- /dev/null
+++ b/library/tzdata/Asia/Yakutsk
@@ -0,0 +1,71 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Asia/Yakutsk) {
+    {-9223372036854775808 31138 0 LMT}
+    {-1579423138 28800 0 YAKT}
+    {-1247558400 32400 0 YAKMMTT}
+    {354898800 36000 1 YAKST}
+    {370706400 32400 0 YAKT}
+    {386434800 36000 1 YAKST}
+    {402242400 32400 0 YAKT}
+    {417970800 36000 1 YAKST}
+    {433778400 32400 0 YAKT}
+    {449593200 36000 1 YAKST}
+    {465325200 32400 0 YAKT}
+    {481050000 36000 1 YAKST}
+    {496774800 32400 0 YAKT}
+    {512499600 36000 1 YAKST}
+    {528224400 32400 0 YAKT}
+    {543949200 36000 1 YAKST}
+    {559674000 32400 0 YAKT}
+    {575398800 36000 1 YAKST}
+    {591123600 32400 0 YAKT}
+    {606848400 36000 1 YAKST}
+    {622573200 32400 0 YAKT}
+    {638298000 36000 1 YAKST}
+    {654627600 32400 0 YAKT}
+    {670352400 28800 0 YAKMMTT}
+    {670356000 32400 1 YAKST}
+    {686080800 28800 0 YAKT}
+    {695757600 32400 0 YAKMMTT}
+    {701802000 36000 1 YAKST}
+    {717526800 32400 0 YAKT}
+    {733251600 36000 1 YAKST}
+    {748976400 32400 0 YAKT}
+    {764701200 36000 1 YAKST}
+    {780426000 32400 0 YAKT}
+    {796150800 36000 1 YAKST}
+    {811875600 32400 0 YAKT}
+    {828205200 36000 1 YAKST}
+    {846349200 32400 0 YAKT}
+    {859654800 36000 1 YAKST}
+    {877798800 32400 0 YAKT}
+    {891104400 36000 1 YAKST}
+    {909248400 32400 0 YAKT}
+    {922554000 36000 1 YAKST}
+    {941302800 32400 0 YAKT}
+    {954003600 36000 1 YAKST}
+    {972752400 32400 0 YAKT}
+    {985453200 36000 1 YAKST}
+    {1004202000 32400 0 YAKT}
+    {1017507600 36000 1 YAKST}
+    {1035651600 32400 0 YAKT}
+    {1048957200 36000 1 YAKST}
+    {1067101200 32400 0 YAKT}
+    {1080406800 36000 1 YAKST}
+    {1099155600 32400 0 YAKT}
+    {1111856400 36000 1 YAKST}
+    {1130605200 32400 0 YAKT}
+    {1143306000 36000 1 YAKST}
+    {1162054800 32400 0 YAKT}
+    {1174755600 36000 1 YAKST}
+    {1193504400 32400 0 YAKT}
+    {1206810000 36000 1 YAKST}
+    {1224954000 32400 0 YAKT}
+    {1238259600 36000 1 YAKST}
+    {1256403600 32400 0 YAKT}
+    {1269709200 36000 1 YAKST}
+    {1288458000 32400 0 YAKT}
+    {1301158800 36000 0 YAKT}
+    {1414252800 32400 0 YAKT}
+}
diff --git a/library/tzdata/Asia/Yekaterinburg b/library/tzdata/Asia/Yekaterinburg
new file mode 100644
index 0000000..fdd89b0
--- /dev/null
+++ b/library/tzdata/Asia/Yekaterinburg
@@ -0,0 +1,72 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Asia/Yekaterinburg) {
+    {-9223372036854775808 14553 0 LMT}
+    {-1688270553 13505 0 PMT}
+    {-1592610305 14400 0 SVET}
+    {-1247544000 18000 0 SVEMMTT}
+    {354913200 21600 1 SVEST}
+    {370720800 18000 0 SVET}
+    {386449200 21600 1 SVEST}
+    {402256800 18000 0 SVET}
+    {417985200 21600 1 SVEST}
+    {433792800 18000 0 SVET}
+    {449607600 21600 1 SVEST}
+    {465339600 18000 0 SVET}
+    {481064400 21600 1 SVEST}
+    {496789200 18000 0 SVET}
+    {512514000 21600 1 SVEST}
+    {528238800 18000 0 SVET}
+    {543963600 21600 1 SVEST}
+    {559688400 18000 0 SVET}
+    {575413200 21600 1 SVEST}
+    {591138000 18000 0 SVET}
+    {606862800 21600 1 SVEST}
+    {622587600 18000 0 SVET}
+    {638312400 21600 1 SVEST}
+    {654642000 18000 0 SVET}
+    {670366800 14400 0 SVEMMTT}
+    {670370400 18000 1 SVEST}
+    {686095200 14400 0 SVET}
+    {695772000 18000 0 YEKMMTT}
+    {701816400 21600 1 YEKST}
+    {717541200 18000 0 YEKT}
+    {733266000 21600 1 YEKST}
+    {748990800 18000 0 YEKT}
+    {764715600 21600 1 YEKST}
+    {780440400 18000 0 YEKT}
+    {796165200 21600 1 YEKST}
+    {811890000 18000 0 YEKT}
+    {828219600 21600 1 YEKST}
+    {846363600 18000 0 YEKT}
+    {859669200 21600 1 YEKST}
+    {877813200 18000 0 YEKT}
+    {891118800 21600 1 YEKST}
+    {909262800 18000 0 YEKT}
+    {922568400 21600 1 YEKST}
+    {941317200 18000 0 YEKT}
+    {954018000 21600 1 YEKST}
+    {972766800 18000 0 YEKT}
+    {985467600 21600 1 YEKST}
+    {1004216400 18000 0 YEKT}
+    {1017522000 21600 1 YEKST}
+    {1035666000 18000 0 YEKT}
+    {1048971600 21600 1 YEKST}
+    {1067115600 18000 0 YEKT}
+    {1080421200 21600 1 YEKST}
+    {1099170000 18000 0 YEKT}
+    {1111870800 21600 1 YEKST}
+    {1130619600 18000 0 YEKT}
+    {1143320400 21600 1 YEKST}
+    {1162069200 18000 0 YEKT}
+    {1174770000 21600 1 YEKST}
+    {1193518800 18000 0 YEKT}
+    {1206824400 21600 1 YEKST}
+    {1224968400 18000 0 YEKT}
+    {1238274000 21600 1 YEKST}
+    {1256418000 18000 0 YEKT}
+    {1269723600 21600 1 YEKST}
+    {1288472400 18000 0 YEKT}
+    {1301173200 21600 0 YEKT}
+    {1414267200 18000 0 YEKT}
+}
diff --git a/library/tzdata/Asia/Yerevan b/library/tzdata/Asia/Yerevan
new file mode 100644
index 0000000..c552403
--- /dev/null
+++ b/library/tzdata/Asia/Yerevan
@@ -0,0 +1,70 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Asia/Yerevan) {
+    {-9223372036854775808 10680 0 LMT}
+    {-1441162680 10800 0 YERT}
+    {-405140400 14400 0 YERT}
+    {354916800 18000 1 YERST}
+    {370724400 14400 0 YERT}
+    {386452800 18000 1 YERST}
+    {402260400 14400 0 YERT}
+    {417988800 18000 1 YERST}
+    {433796400 14400 0 YERT}
+    {449611200 18000 1 YERST}
+    {465343200 14400 0 YERT}
+    {481068000 18000 1 YERST}
+    {496792800 14400 0 YERT}
+    {512517600 18000 1 YERST}
+    {528242400 14400 0 YERT}
+    {543967200 18000 1 YERST}
+    {559692000 14400 0 YERT}
+    {575416800 18000 1 YERST}
+    {591141600 14400 0 YERT}
+    {606866400 18000 1 YERST}
+    {622591200 14400 0 YERT}
+    {638316000 18000 1 YERST}
+    {654645600 14400 0 YERT}
+    {670370400 14400 1 YERST}
+    {685569600 14400 0 AMST}
+    {686098800 10800 0 AMT}
+    {701823600 14400 1 AMST}
+    {717548400 10800 0 AMT}
+    {733273200 14400 1 AMST}
+    {748998000 10800 0 AMT}
+    {764722800 14400 1 AMST}
+    {780447600 10800 0 AMT}
+    {796172400 14400 1 AMST}
+    {811897200 14400 0 AMT}
+    {852062400 14400 0 AMT}
+    {859672800 18000 1 AMST}
+    {877816800 14400 0 AMT}
+    {891122400 18000 1 AMST}
+    {909266400 14400 0 AMT}
+    {922572000 18000 1 AMST}
+    {941320800 14400 0 AMT}
+    {954021600 18000 1 AMST}
+    {972770400 14400 0 AMT}
+    {985471200 18000 1 AMST}
+    {1004220000 14400 0 AMT}
+    {1017525600 18000 1 AMST}
+    {1035669600 14400 0 AMT}
+    {1048975200 18000 1 AMST}
+    {1067119200 14400 0 AMT}
+    {1080424800 18000 1 AMST}
+    {1099173600 14400 0 AMT}
+    {1111874400 18000 1 AMST}
+    {1130623200 14400 0 AMT}
+    {1143324000 18000 1 AMST}
+    {1162072800 14400 0 AMT}
+    {1174773600 18000 1 AMST}
+    {1193522400 14400 0 AMT}
+    {1206828000 18000 1 AMST}
+    {1224972000 14400 0 AMT}
+    {1238277600 18000 1 AMST}
+    {1256421600 14400 0 AMT}
+    {1269727200 18000 1 AMST}
+    {1288476000 14400 0 AMT}
+    {1301176800 18000 1 AMST}
+    {1319925600 14400 0 AMT}
+    {1328731200 14400 0 AMT}
+}
diff --git a/library/tzdata/Atlantic/Azores b/library/tzdata/Atlantic/Azores
new file mode 100644
index 0000000..fd47ba5
--- /dev/null
+++ b/library/tzdata/Atlantic/Azores
@@ -0,0 +1,349 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Atlantic/Azores) {
+    {-9223372036854775808 -6160 0 LMT}
+    {-2713904240 -6872 0 HMT}
+    {-1830377128 -7200 0 AZOT}
+    {-1689548400 -3600 1 AZOST}
+    {-1677794400 -7200 0 AZOT}
+    {-1667430000 -3600 1 AZOST}
+    {-1647730800 -7200 0 AZOT}
+    {-1635807600 -3600 1 AZOST}
+    {-1616194800 -7200 0 AZOT}
+    {-1604358000 -3600 1 AZOST}
+    {-1584658800 -7200 0 AZOT}
+    {-1572735600 -3600 1 AZOST}
+    {-1553036400 -7200 0 AZOT}
+    {-1541199600 -3600 1 AZOST}
+    {-1521500400 -7200 0 AZOT}
+    {-1442444400 -3600 1 AZOST}
+    {-1426806000 -7200 0 AZOT}
+    {-1379286000 -3600 1 AZOST}
+    {-1364770800 -7200 0 AZOT}
+    {-1348441200 -3600 1 AZOST}
+    {-1333321200 -7200 0 AZOT}
+    {-1316386800 -3600 1 AZOST}
+    {-1301266800 -7200 0 AZOT}
+    {-1284332400 -3600 1 AZOST}
+    {-1269817200 -7200 0 AZOT}
+    {-1221433200 -3600 1 AZOST}
+    {-1206918000 -7200 0 AZOT}
+    {-1191193200 -3600 1 AZOST}
+    {-1175468400 -7200 0 AZOT}
+    {-1127689200 -3600 1 AZOST}
+    {-1111964400 -7200 0 AZOT}
+    {-1096844400 -3600 1 AZOST}
+    {-1080514800 -7200 0 AZOT}
+    {-1063580400 -3600 1 AZOST}
+    {-1049065200 -7200 0 AZOT}
+    {-1033340400 -3600 1 AZOST}
+    {-1017615600 -7200 0 AZOT}
+    {-1002495600 -3600 1 AZOST}
+    {-986166000 -7200 0 AZOT}
+    {-969231600 -3600 1 AZOST}
+    {-950482800 -7200 0 AZOT}
+    {-942015600 -3600 1 AZOST}
+    {-922662000 -7200 0 AZOT}
+    {-906937200 -3600 1 AZOST}
+    {-891126000 -7200 0 AZOT}
+    {-877302000 -3600 1 AZOST}
+    {-873676800 0 1 AZOMT}
+    {-864000000 -3600 1 AZOST}
+    {-857948400 -7200 0 AZOT}
+    {-845852400 -3600 1 AZOST}
+    {-842832000 0 1 AZOMT}
+    {-831340800 -3600 1 AZOST}
+    {-825894000 -7200 0 AZOT}
+    {-814402800 -3600 1 AZOST}
+    {-810777600 0 1 AZOMT}
+    {-799891200 -3600 1 AZOST}
+    {-794444400 -7200 0 AZOT}
+    {-782953200 -3600 1 AZOST}
+    {-779328000 0 1 AZOMT}
+    {-768441600 -3600 1 AZOST}
+    {-762994800 -7200 0 AZOT}
+    {-749084400 -3600 1 AZOST}
+    {-733359600 -7200 0 AZOT}
+    {-717624000 -3600 1 AZOST}
+    {-701899200 -7200 0 AZOT}
+    {-686174400 -3600 1 AZOST}
+    {-670449600 -7200 0 AZOT}
+    {-654724800 -3600 1 AZOST}
+    {-639000000 -7200 0 AZOT}
+    {-591825600 -3600 1 AZOST}
+    {-575496000 -7200 0 AZOT}
+    {-559771200 -3600 1 AZOST}
+    {-544046400 -7200 0 AZOT}
+    {-528321600 -3600 1 AZOST}
+    {-512596800 -7200 0 AZOT}
+    {-496872000 -3600 1 AZOST}
+    {-481147200 -7200 0 AZOT}
+    {-465422400 -3600 1 AZOST}
+    {-449697600 -7200 0 AZOT}
+    {-433972800 -3600 1 AZOST}
+    {-417643200 -7200 0 AZOT}
+    {-401918400 -3600 1 AZOST}
+    {-386193600 -7200 0 AZOT}
+    {-370468800 -3600 1 AZOST}
+    {-354744000 -7200 0 AZOT}
+    {-339019200 -3600 1 AZOST}
+    {-323294400 -7200 0 AZOT}
+    {-307569600 -3600 1 AZOST}
+    {-291844800 -7200 0 AZOT}
+    {-276120000 -3600 1 AZOST}
+    {-260395200 -7200 0 AZOT}
+    {-244670400 -3600 1 AZOST}
+    {-228340800 -7200 0 AZOT}
+    {-212616000 -3600 1 AZOST}
+    {-196891200 -7200 0 AZOT}
+    {-181166400 -3600 1 AZOST}
+    {-165441600 -7200 0 AZOT}
+    {-149716800 -3600 1 AZOST}
+    {-133992000 -7200 0 AZOT}
+    {-118267200 -3600 0 AZOT}
+    {228272400 0 1 AZOST}
+    {243997200 -3600 0 AZOT}
+    {260326800 0 1 AZOST}
+    {276051600 -3600 0 AZOT}
+    {291776400 0 1 AZOST}
+    {307504800 -3600 0 AZOT}
+    {323226000 0 1 AZOST}
+    {338954400 -3600 0 AZOT}
+    {354679200 0 1 AZOST}
+    {370404000 -3600 0 AZOT}
+    {386128800 0 1 AZOST}
+    {401853600 -3600 0 AZOT}
+    {417582000 0 1 AZOST}
+    {433303200 -3600 0 AZOT}
+    {449028000 0 1 AZOST}
+    {465357600 -3600 0 AZOT}
+    {481082400 0 1 AZOST}
+    {496807200 -3600 0 AZOT}
+    {512532000 0 1 AZOST}
+    {528256800 -3600 0 AZOT}
+    {543981600 0 1 AZOST}
+    {559706400 -3600 0 AZOT}
+    {575431200 0 1 AZOST}
+    {591156000 -3600 0 AZOT}
+    {606880800 0 1 AZOST}
+    {622605600 -3600 0 AZOT}
+    {638330400 0 1 AZOST}
+    {654660000 -3600 0 AZOT}
+    {670384800 0 1 AZOST}
+    {686109600 -3600 0 AZOT}
+    {701834400 0 1 AZOST}
+    {733280400 0 0 AZOST}
+    {749005200 -3600 0 AZOT}
+    {764730000 0 1 AZOST}
+    {780454800 -3600 0 AZOT}
+    {796179600 0 1 AZOST}
+    {811904400 -3600 0 AZOT}
+    {828234000 0 1 AZOST}
+    {846378000 -3600 0 AZOT}
+    {859683600 0 1 AZOST}
+    {877827600 -3600 0 AZOT}
+    {891133200 0 1 AZOST}
+    {909277200 -3600 0 AZOT}
+    {922582800 0 1 AZOST}
+    {941331600 -3600 0 AZOT}
+    {954032400 0 1 AZOST}
+    {972781200 -3600 0 AZOT}
+    {985482000 0 1 AZOST}
+    {1004230800 -3600 0 AZOT}
+    {1017536400 0 1 AZOST}
+    {1035680400 -3600 0 AZOT}
+    {1048986000 0 1 AZOST}
+    {1067130000 -3600 0 AZOT}
+    {1080435600 0 1 AZOST}
+    {1099184400 -3600 0 AZOT}
+    {1111885200 0 1 AZOST}
+    {1130634000 -3600 0 AZOT}
+    {1143334800 0 1 AZOST}
+    {1162083600 -3600 0 AZOT}
+    {1174784400 0 1 AZOST}
+    {1193533200 -3600 0 AZOT}
+    {1206838800 0 1 AZOST}
+    {1224982800 -3600 0 AZOT}
+    {1238288400 0 1 AZOST}
+    {1256432400 -3600 0 AZOT}
+    {1269738000 0 1 AZOST}
+    {1288486800 -3600 0 AZOT}
+    {1301187600 0 1 AZOST}
+    {1319936400 -3600 0 AZOT}
+    {1332637200 0 1 AZOST}
+    {1351386000 -3600 0 AZOT}
+    {1364691600 0 1 AZOST}
+    {1382835600 -3600 0 AZOT}
+    {1396141200 0 1 AZOST}
+    {1414285200 -3600 0 AZOT}
+    {1427590800 0 1 AZOST}
+    {1445734800 -3600 0 AZOT}
+    {1459040400 0 1 AZOST}
+    {1477789200 -3600 0 AZOT}
+    {1490490000 0 1 AZOST}
+    {1509238800 -3600 0 AZOT}
+    {1521939600 0 1 AZOST}
+    {1540688400 -3600 0 AZOT}
+    {1553994000 0 1 AZOST}
+    {1572138000 -3600 0 AZOT}
+    {1585443600 0 1 AZOST}
+    {1603587600 -3600 0 AZOT}
+    {1616893200 0 1 AZOST}
+    {1635642000 -3600 0 AZOT}
+    {1648342800 0 1 AZOST}
+    {1667091600 -3600 0 AZOT}
+    {1679792400 0 1 AZOST}
+    {1698541200 -3600 0 AZOT}
+    {1711846800 0 1 AZOST}
+    {1729990800 -3600 0 AZOT}
+    {1743296400 0 1 AZOST}
+    {1761440400 -3600 0 AZOT}
+    {1774746000 0 1 AZOST}
+    {1792890000 -3600 0 AZOT}
+    {1806195600 0 1 AZOST}
+    {1824944400 -3600 0 AZOT}
+    {1837645200 0 1 AZOST}
+    {1856394000 -3600 0 AZOT}
+    {1869094800 0 1 AZOST}
+    {1887843600 -3600 0 AZOT}
+    {1901149200 0 1 AZOST}
+    {1919293200 -3600 0 AZOT}
+    {1932598800 0 1 AZOST}
+    {1950742800 -3600 0 AZOT}
+    {1964048400 0 1 AZOST}
+    {1982797200 -3600 0 AZOT}
+    {1995498000 0 1 AZOST}
+    {2014246800 -3600 0 AZOT}
+    {2026947600 0 1 AZOST}
+    {2045696400 -3600 0 AZOT}
+    {2058397200 0 1 AZOST}
+    {2077146000 -3600 0 AZOT}
+    {2090451600 0 1 AZOST}
+    {2108595600 -3600 0 AZOT}
+    {2121901200 0 1 AZOST}
+    {2140045200 -3600 0 AZOT}
+    {2153350800 0 1 AZOST}
+    {2172099600 -3600 0 AZOT}
+    {2184800400 0 1 AZOST}
+    {2203549200 -3600 0 AZOT}
+    {2216250000 0 1 AZOST}
+    {2234998800 -3600 0 AZOT}
+    {2248304400 0 1 AZOST}
+    {2266448400 -3600 0 AZOT}
+    {2279754000 0 1 AZOST}
+    {2297898000 -3600 0 AZOT}
+    {2311203600 0 1 AZOST}
+    {2329347600 -3600 0 AZOT}
+    {2342653200 0 1 AZOST}
+    {2361402000 -3600 0 AZOT}
+    {2374102800 0 1 AZOST}
+    {2392851600 -3600 0 AZOT}
+    {2405552400 0 1 AZOST}
+    {2424301200 -3600 0 AZOT}
+    {2437606800 0 1 AZOST}
+    {2455750800 -3600 0 AZOT}
+    {2469056400 0 1 AZOST}
+    {2487200400 -3600 0 AZOT}
+    {2500506000 0 1 AZOST}
+    {2519254800 -3600 0 AZOT}
+    {2531955600 0 1 AZOST}
+    {2550704400 -3600 0 AZOT}
+    {2563405200 0 1 AZOST}
+    {2582154000 -3600 0 AZOT}
+    {2595459600 0 1 AZOST}
+    {2613603600 -3600 0 AZOT}
+    {2626909200 0 1 AZOST}
+    {2645053200 -3600 0 AZOT}
+    {2658358800 0 1 AZOST}
+    {2676502800 -3600 0 AZOT}
+    {2689808400 0 1 AZOST}
+    {2708557200 -3600 0 AZOT}
+    {2721258000 0 1 AZOST}
+    {2740006800 -3600 0 AZOT}
+    {2752707600 0 1 AZOST}
+    {2771456400 -3600 0 AZOT}
+    {2784762000 0 1 AZOST}
+    {2802906000 -3600 0 AZOT}
+    {2816211600 0 1 AZOST}
+    {2834355600 -3600 0 AZOT}
+    {2847661200 0 1 AZOST}
+    {2866410000 -3600 0 AZOT}
+    {2879110800 0 1 AZOST}
+    {2897859600 -3600 0 AZOT}
+    {2910560400 0 1 AZOST}
+    {2929309200 -3600 0 AZOT}
+    {2942010000 0 1 AZOST}
+    {2960758800 -3600 0 AZOT}
+    {2974064400 0 1 AZOST}
+    {2992208400 -3600 0 AZOT}
+    {3005514000 0 1 AZOST}
+    {3023658000 -3600 0 AZOT}
+    {3036963600 0 1 AZOST}
+    {3055712400 -3600 0 AZOT}
+    {3068413200 0 1 AZOST}
+    {3087162000 -3600 0 AZOT}
+    {3099862800 0 1 AZOST}
+    {3118611600 -3600 0 AZOT}
+    {3131917200 0 1 AZOST}
+    {3150061200 -3600 0 AZOT}
+    {3163366800 0 1 AZOST}
+    {3181510800 -3600 0 AZOT}
+    {3194816400 0 1 AZOST}
+    {3212960400 -3600 0 AZOT}
+    {3226266000 0 1 AZOST}
+    {3245014800 -3600 0 AZOT}
+    {3257715600 0 1 AZOST}
+    {3276464400 -3600 0 AZOT}
+    {3289165200 0 1 AZOST}
+    {3307914000 -3600 0 AZOT}
+    {3321219600 0 1 AZOST}
+    {3339363600 -3600 0 AZOT}
+    {3352669200 0 1 AZOST}
+    {3370813200 -3600 0 AZOT}
+    {3384118800 0 1 AZOST}
+    {3402867600 -3600 0 AZOT}
+    {3415568400 0 1 AZOST}
+    {3434317200 -3600 0 AZOT}
+    {3447018000 0 1 AZOST}
+    {3465766800 -3600 0 AZOT}
+    {3479072400 0 1 AZOST}
+    {3497216400 -3600 0 AZOT}
+    {3510522000 0 1 AZOST}
+    {3528666000 -3600 0 AZOT}
+    {3541971600 0 1 AZOST}
+    {3560115600 -3600 0 AZOT}
+    {3573421200 0 1 AZOST}
+    {3592170000 -3600 0 AZOT}
+    {3604870800 0 1 AZOST}
+    {3623619600 -3600 0 AZOT}
+    {3636320400 0 1 AZOST}
+    {3655069200 -3600 0 AZOT}
+    {3668374800 0 1 AZOST}
+    {3686518800 -3600 0 AZOT}
+    {3699824400 0 1 AZOST}
+    {3717968400 -3600 0 AZOT}
+    {3731274000 0 1 AZOST}
+    {3750022800 -3600 0 AZOT}
+    {3762723600 0 1 AZOST}
+    {3781472400 -3600 0 AZOT}
+    {3794173200 0 1 AZOST}
+    {3812922000 -3600 0 AZOT}
+    {3825622800 0 1 AZOST}
+    {3844371600 -3600 0 AZOT}
+    {3857677200 0 1 AZOST}
+    {3875821200 -3600 0 AZOT}
+    {3889126800 0 1 AZOST}
+    {3907270800 -3600 0 AZOT}
+    {3920576400 0 1 AZOST}
+    {3939325200 -3600 0 AZOT}
+    {3952026000 0 1 AZOST}
+    {3970774800 -3600 0 AZOT}
+    {3983475600 0 1 AZOST}
+    {4002224400 -3600 0 AZOT}
+    {4015530000 0 1 AZOST}
+    {4033674000 -3600 0 AZOT}
+    {4046979600 0 1 AZOST}
+    {4065123600 -3600 0 AZOT}
+    {4078429200 0 1 AZOST}
+    {4096573200 -3600 0 AZOT}
+}
diff --git a/library/tzdata/Atlantic/Bermuda b/library/tzdata/Atlantic/Bermuda
new file mode 100644
index 0000000..2d4d983
--- /dev/null
+++ b/library/tzdata/Atlantic/Bermuda
@@ -0,0 +1,259 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Atlantic/Bermuda) {
+    {-9223372036854775808 -15558 0 LMT}
+    {-1262281242 -14400 0 AST}
+    {136360800 -10800 0 ADT}
+    {152082000 -14400 0 AST}
+    {167810400 -10800 1 ADT}
+    {183531600 -14400 0 AST}
+    {189316800 -14400 0 AST}
+    {199260000 -10800 1 ADT}
+    {215586000 -14400 0 AST}
+    {230709600 -10800 1 ADT}
+    {247035600 -14400 0 AST}
+    {262764000 -10800 1 ADT}
+    {278485200 -14400 0 AST}
+    {294213600 -10800 1 ADT}
+    {309934800 -14400 0 AST}
+    {325663200 -10800 1 ADT}
+    {341384400 -14400 0 AST}
+    {357112800 -10800 1 ADT}
+    {372834000 -14400 0 AST}
+    {388562400 -10800 1 ADT}
+    {404888400 -14400 0 AST}
+    {420012000 -10800 1 ADT}
+    {436338000 -14400 0 AST}
+    {452066400 -10800 1 ADT}
+    {467787600 -14400 0 AST}
+    {483516000 -10800 1 ADT}
+    {499237200 -14400 0 AST}
+    {514965600 -10800 1 ADT}
+    {530686800 -14400 0 AST}
+    {544600800 -10800 1 ADT}
+    {562136400 -14400 0 AST}
+    {576050400 -10800 1 ADT}
+    {594190800 -14400 0 AST}
+    {607500000 -10800 1 ADT}
+    {625640400 -14400 0 AST}
+    {638949600 -10800 1 ADT}
+    {657090000 -14400 0 AST}
+    {671004000 -10800 1 ADT}
+    {688539600 -14400 0 AST}
+    {702453600 -10800 1 ADT}
+    {719989200 -14400 0 AST}
+    {733903200 -10800 1 ADT}
+    {752043600 -14400 0 AST}
+    {765352800 -10800 1 ADT}
+    {783493200 -14400 0 AST}
+    {796802400 -10800 1 ADT}
+    {814942800 -14400 0 AST}
+    {828856800 -10800 1 ADT}
+    {846392400 -14400 0 AST}
+    {860306400 -10800 1 ADT}
+    {877842000 -14400 0 AST}
+    {891756000 -10800 1 ADT}
+    {909291600 -14400 0 AST}
+    {923205600 -10800 1 ADT}
+    {941346000 -14400 0 AST}
+    {954655200 -10800 1 ADT}
+    {972795600 -14400 0 AST}
+    {986104800 -10800 1 ADT}
+    {1004245200 -14400 0 AST}
+    {1018159200 -10800 1 ADT}
+    {1035694800 -14400 0 AST}
+    {1049608800 -10800 1 ADT}
+    {1067144400 -14400 0 AST}
+    {1081058400 -10800 1 ADT}
+    {1099198800 -14400 0 AST}
+    {1112508000 -10800 1 ADT}
+    {1130648400 -14400 0 AST}
+    {1143957600 -10800 1 ADT}
+    {1162098000 -14400 0 AST}
+    {1173592800 -10800 1 ADT}
+    {1194152400 -14400 0 AST}
+    {1205042400 -10800 1 ADT}
+    {1225602000 -14400 0 AST}
+    {1236492000 -10800 1 ADT}
+    {1257051600 -14400 0 AST}
+    {1268546400 -10800 1 ADT}
+    {1289106000 -14400 0 AST}
+    {1299996000 -10800 1 ADT}
+    {1320555600 -14400 0 AST}
+    {1331445600 -10800 1 ADT}
+    {1352005200 -14400 0 AST}
+    {1362895200 -10800 1 ADT}
+    {1383454800 -14400 0 AST}
+    {1394344800 -10800 1 ADT}
+    {1414904400 -14400 0 AST}
+    {1425794400 -10800 1 ADT}
+    {1446354000 -14400 0 AST}
+    {1457848800 -10800 1 ADT}
+    {1478408400 -14400 0 AST}
+    {1489298400 -10800 1 ADT}
+    {1509858000 -14400 0 AST}
+    {1520748000 -10800 1 ADT}
+    {1541307600 -14400 0 AST}
+    {1552197600 -10800 1 ADT}
+    {1572757200 -14400 0 AST}
+    {1583647200 -10800 1 ADT}
+    {1604206800 -14400 0 AST}
+    {1615701600 -10800 1 ADT}
+    {1636261200 -14400 0 AST}
+    {1647151200 -10800 1 ADT}
+    {1667710800 -14400 0 AST}
+    {1678600800 -10800 1 ADT}
+    {1699160400 -14400 0 AST}
+    {1710050400 -10800 1 ADT}
+    {1730610000 -14400 0 AST}
+    {1741500000 -10800 1 ADT}
+    {1762059600 -14400 0 AST}
+    {1772949600 -10800 1 ADT}
+    {1793509200 -14400 0 AST}
+    {1805004000 -10800 1 ADT}
+    {1825563600 -14400 0 AST}
+    {1836453600 -10800 1 ADT}
+    {1857013200 -14400 0 AST}
+    {1867903200 -10800 1 ADT}
+    {1888462800 -14400 0 AST}
+    {1899352800 -10800 1 ADT}
+    {1919912400 -14400 0 AST}
+    {1930802400 -10800 1 ADT}
+    {1951362000 -14400 0 AST}
+    {1962856800 -10800 1 ADT}
+    {1983416400 -14400 0 AST}
+    {1994306400 -10800 1 ADT}
+    {2014866000 -14400 0 AST}
+    {2025756000 -10800 1 ADT}
+    {2046315600 -14400 0 AST}
+    {2057205600 -10800 1 ADT}
+    {2077765200 -14400 0 AST}
+    {2088655200 -10800 1 ADT}
+    {2109214800 -14400 0 AST}
+    {2120104800 -10800 1 ADT}
+    {2140664400 -14400 0 AST}
+    {2152159200 -10800 1 ADT}
+    {2172718800 -14400 0 AST}
+    {2183608800 -10800 1 ADT}
+    {2204168400 -14400 0 AST}
+    {2215058400 -10800 1 ADT}
+    {2235618000 -14400 0 AST}
+    {2246508000 -10800 1 ADT}
+    {2267067600 -14400 0 AST}
+    {2277957600 -10800 1 ADT}
+    {2298517200 -14400 0 AST}
+    {2309407200 -10800 1 ADT}
+    {2329966800 -14400 0 AST}
+    {2341461600 -10800 1 ADT}
+    {2362021200 -14400 0 AST}
+    {2372911200 -10800 1 ADT}
+    {2393470800 -14400 0 AST}
+    {2404360800 -10800 1 ADT}
+    {2424920400 -14400 0 AST}
+    {2435810400 -10800 1 ADT}
+    {2456370000 -14400 0 AST}
+    {2467260000 -10800 1 ADT}
+    {2487819600 -14400 0 AST}
+    {2499314400 -10800 1 ADT}
+    {2519874000 -14400 0 AST}
+    {2530764000 -10800 1 ADT}
+    {2551323600 -14400 0 AST}
+    {2562213600 -10800 1 ADT}
+    {2582773200 -14400 0 AST}
+    {2593663200 -10800 1 ADT}
+    {2614222800 -14400 0 AST}
+    {2625112800 -10800 1 ADT}
+    {2645672400 -14400 0 AST}
+    {2656562400 -10800 1 ADT}
+    {2677122000 -14400 0 AST}
+    {2688616800 -10800 1 ADT}
+    {2709176400 -14400 0 AST}
+    {2720066400 -10800 1 ADT}
+    {2740626000 -14400 0 AST}
+    {2751516000 -10800 1 ADT}
+    {2772075600 -14400 0 AST}
+    {2782965600 -10800 1 ADT}
+    {2803525200 -14400 0 AST}
+    {2814415200 -10800 1 ADT}
+    {2834974800 -14400 0 AST}
+    {2846469600 -10800 1 ADT}
+    {2867029200 -14400 0 AST}
+    {2877919200 -10800 1 ADT}
+    {2898478800 -14400 0 AST}
+    {2909368800 -10800 1 ADT}
+    {2929928400 -14400 0 AST}
+    {2940818400 -10800 1 ADT}
+    {2961378000 -14400 0 AST}
+    {2972268000 -10800 1 ADT}
+    {2992827600 -14400 0 AST}
+    {3003717600 -10800 1 ADT}
+    {3024277200 -14400 0 AST}
+    {3035772000 -10800 1 ADT}
+    {3056331600 -14400 0 AST}
+    {3067221600 -10800 1 ADT}
+    {3087781200 -14400 0 AST}
+    {3098671200 -10800 1 ADT}
+    {3119230800 -14400 0 AST}
+    {3130120800 -10800 1 ADT}
+    {3150680400 -14400 0 AST}
+    {3161570400 -10800 1 ADT}
+    {3182130000 -14400 0 AST}
+    {3193020000 -10800 1 ADT}
+    {3213579600 -14400 0 AST}
+    {3225074400 -10800 1 ADT}
+    {3245634000 -14400 0 AST}
+    {3256524000 -10800 1 ADT}
+    {3277083600 -14400 0 AST}
+    {3287973600 -10800 1 ADT}
+    {3308533200 -14400 0 AST}
+    {3319423200 -10800 1 ADT}
+    {3339982800 -14400 0 AST}
+    {3350872800 -10800 1 ADT}
+    {3371432400 -14400 0 AST}
+    {3382927200 -10800 1 ADT}
+    {3403486800 -14400 0 AST}
+    {3414376800 -10800 1 ADT}
+    {3434936400 -14400 0 AST}
+    {3445826400 -10800 1 ADT}
+    {3466386000 -14400 0 AST}
+    {3477276000 -10800 1 ADT}
+    {3497835600 -14400 0 AST}
+    {3508725600 -10800 1 ADT}
+    {3529285200 -14400 0 AST}
+    {3540175200 -10800 1 ADT}
+    {3560734800 -14400 0 AST}
+    {3572229600 -10800 1 ADT}
+    {3592789200 -14400 0 AST}
+    {3603679200 -10800 1 ADT}
+    {3624238800 -14400 0 AST}
+    {3635128800 -10800 1 ADT}
+    {3655688400 -14400 0 AST}
+    {3666578400 -10800 1 ADT}
+    {3687138000 -14400 0 AST}
+    {3698028000 -10800 1 ADT}
+    {3718587600 -14400 0 AST}
+    {3730082400 -10800 1 ADT}
+    {3750642000 -14400 0 AST}
+    {3761532000 -10800 1 ADT}
+    {3782091600 -14400 0 AST}
+    {3792981600 -10800 1 ADT}
+    {3813541200 -14400 0 AST}
+    {3824431200 -10800 1 ADT}
+    {3844990800 -14400 0 AST}
+    {3855880800 -10800 1 ADT}
+    {3876440400 -14400 0 AST}
+    {3887330400 -10800 1 ADT}
+    {3907890000 -14400 0 AST}
+    {3919384800 -10800 1 ADT}
+    {3939944400 -14400 0 AST}
+    {3950834400 -10800 1 ADT}
+    {3971394000 -14400 0 AST}
+    {3982284000 -10800 1 ADT}
+    {4002843600 -14400 0 AST}
+    {4013733600 -10800 1 ADT}
+    {4034293200 -14400 0 AST}
+    {4045183200 -10800 1 ADT}
+    {4065742800 -14400 0 AST}
+    {4076632800 -10800 1 ADT}
+    {4097192400 -14400 0 AST}
+}
diff --git a/library/tzdata/Atlantic/Canary b/library/tzdata/Atlantic/Canary
new file mode 100644
index 0000000..dcfba83
--- /dev/null
+++ b/library/tzdata/Atlantic/Canary
@@ -0,0 +1,247 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Atlantic/Canary) {
+    {-9223372036854775808 -3696 0 LMT}
+    {-1509663504 -3600 0 CANT}
+    {-733874400 0 0 WET}
+    {323827200 3600 1 WEST}
+    {338950800 0 0 WET}
+    {354675600 3600 1 WEST}
+    {370400400 0 0 WET}
+    {386125200 3600 1 WEST}
+    {401850000 0 0 WET}
+    {417574800 3600 1 WEST}
+    {433299600 0 0 WET}
+    {449024400 3600 1 WEST}
+    {465354000 0 0 WET}
+    {481078800 3600 1 WEST}
+    {496803600 0 0 WET}
+    {512528400 3600 1 WEST}
+    {528253200 0 0 WET}
+    {543978000 3600 1 WEST}
+    {559702800 0 0 WET}
+    {575427600 3600 1 WEST}
+    {591152400 0 0 WET}
+    {606877200 3600 1 WEST}
+    {622602000 0 0 WET}
+    {638326800 3600 1 WEST}
+    {654656400 0 0 WET}
+    {670381200 3600 1 WEST}
+    {686106000 0 0 WET}
+    {701830800 3600 1 WEST}
+    {717555600 0 0 WET}
+    {733280400 3600 1 WEST}
+    {749005200 0 0 WET}
+    {764730000 3600 1 WEST}
+    {780454800 0 0 WET}
+    {796179600 3600 1 WEST}
+    {811904400 0 0 WET}
+    {828234000 3600 1 WEST}
+    {846378000 0 0 WET}
+    {859683600 3600 1 WEST}
+    {877827600 0 0 WET}
+    {891133200 3600 1 WEST}
+    {909277200 0 0 WET}
+    {922582800 3600 1 WEST}
+    {941331600 0 0 WET}
+    {954032400 3600 1 WEST}
+    {972781200 0 0 WET}
+    {985482000 3600 1 WEST}
+    {1004230800 0 0 WET}
+    {1017536400 3600 1 WEST}
+    {1035680400 0 0 WET}
+    {1048986000 3600 1 WEST}
+    {1067130000 0 0 WET}
+    {1080435600 3600 1 WEST}
+    {1099184400 0 0 WET}
+    {1111885200 3600 1 WEST}
+    {1130634000 0 0 WET}
+    {1143334800 3600 1 WEST}
+    {1162083600 0 0 WET}
+    {1174784400 3600 1 WEST}
+    {1193533200 0 0 WET}
+    {1206838800 3600 1 WEST}
+    {1224982800 0 0 WET}
+    {1238288400 3600 1 WEST}
+    {1256432400 0 0 WET}
+    {1269738000 3600 1 WEST}
+    {1288486800 0 0 WET}
+    {1301187600 3600 1 WEST}
+    {1319936400 0 0 WET}
+    {1332637200 3600 1 WEST}
+    {1351386000 0 0 WET}
+    {1364691600 3600 1 WEST}
+    {1382835600 0 0 WET}
+    {1396141200 3600 1 WEST}
+    {1414285200 0 0 WET}
+    {1427590800 3600 1 WEST}
+    {1445734800 0 0 WET}
+    {1459040400 3600 1 WEST}
+    {1477789200 0 0 WET}
+    {1490490000 3600 1 WEST}
+    {1509238800 0 0 WET}
+    {1521939600 3600 1 WEST}
+    {1540688400 0 0 WET}
+    {1553994000 3600 1 WEST}
+    {1572138000 0 0 WET}
+    {1585443600 3600 1 WEST}
+    {1603587600 0 0 WET}
+    {1616893200 3600 1 WEST}
+    {1635642000 0 0 WET}
+    {1648342800 3600 1 WEST}
+    {1667091600 0 0 WET}
+    {1679792400 3600 1 WEST}
+    {1698541200 0 0 WET}
+    {1711846800 3600 1 WEST}
+    {1729990800 0 0 WET}
+    {1743296400 3600 1 WEST}
+    {1761440400 0 0 WET}
+    {1774746000 3600 1 WEST}
+    {1792890000 0 0 WET}
+    {1806195600 3600 1 WEST}
+    {1824944400 0 0 WET}
+    {1837645200 3600 1 WEST}
+    {1856394000 0 0 WET}
+    {1869094800 3600 1 WEST}
+    {1887843600 0 0 WET}
+    {1901149200 3600 1 WEST}
+    {1919293200 0 0 WET}
+    {1932598800 3600 1 WEST}
+    {1950742800 0 0 WET}
+    {1964048400 3600 1 WEST}
+    {1982797200 0 0 WET}
+    {1995498000 3600 1 WEST}
+    {2014246800 0 0 WET}
+    {2026947600 3600 1 WEST}
+    {2045696400 0 0 WET}
+    {2058397200 3600 1 WEST}
+    {2077146000 0 0 WET}
+    {2090451600 3600 1 WEST}
+    {2108595600 0 0 WET}
+    {2121901200 3600 1 WEST}
+    {2140045200 0 0 WET}
+    {2153350800 3600 1 WEST}
+    {2172099600 0 0 WET}
+    {2184800400 3600 1 WEST}
+    {2203549200 0 0 WET}
+    {2216250000 3600 1 WEST}
+    {2234998800 0 0 WET}
+    {2248304400 3600 1 WEST}
+    {2266448400 0 0 WET}
+    {2279754000 3600 1 WEST}
+    {2297898000 0 0 WET}
+    {2311203600 3600 1 WEST}
+    {2329347600 0 0 WET}
+    {2342653200 3600 1 WEST}
+    {2361402000 0 0 WET}
+    {2374102800 3600 1 WEST}
+    {2392851600 0 0 WET}
+    {2405552400 3600 1 WEST}
+    {2424301200 0 0 WET}
+    {2437606800 3600 1 WEST}
+    {2455750800 0 0 WET}
+    {2469056400 3600 1 WEST}
+    {2487200400 0 0 WET}
+    {2500506000 3600 1 WEST}
+    {2519254800 0 0 WET}
+    {2531955600 3600 1 WEST}
+    {2550704400 0 0 WET}
+    {2563405200 3600 1 WEST}
+    {2582154000 0 0 WET}
+    {2595459600 3600 1 WEST}
+    {2613603600 0 0 WET}
+    {2626909200 3600 1 WEST}
+    {2645053200 0 0 WET}
+    {2658358800 3600 1 WEST}
+    {2676502800 0 0 WET}
+    {2689808400 3600 1 WEST}
+    {2708557200 0 0 WET}
+    {2721258000 3600 1 WEST}
+    {2740006800 0 0 WET}
+    {2752707600 3600 1 WEST}
+    {2771456400 0 0 WET}
+    {2784762000 3600 1 WEST}
+    {2802906000 0 0 WET}
+    {2816211600 3600 1 WEST}
+    {2834355600 0 0 WET}
+    {2847661200 3600 1 WEST}
+    {2866410000 0 0 WET}
+    {2879110800 3600 1 WEST}
+    {2897859600 0 0 WET}
+    {2910560400 3600 1 WEST}
+    {2929309200 0 0 WET}
+    {2942010000 3600 1 WEST}
+    {2960758800 0 0 WET}
+    {2974064400 3600 1 WEST}
+    {2992208400 0 0 WET}
+    {3005514000 3600 1 WEST}
+    {3023658000 0 0 WET}
+    {3036963600 3600 1 WEST}
+    {3055712400 0 0 WET}
+    {3068413200 3600 1 WEST}
+    {3087162000 0 0 WET}
+    {3099862800 3600 1 WEST}
+    {3118611600 0 0 WET}
+    {3131917200 3600 1 WEST}
+    {3150061200 0 0 WET}
+    {3163366800 3600 1 WEST}
+    {3181510800 0 0 WET}
+    {3194816400 3600 1 WEST}
+    {3212960400 0 0 WET}
+    {3226266000 3600 1 WEST}
+    {3245014800 0 0 WET}
+    {3257715600 3600 1 WEST}
+    {3276464400 0 0 WET}
+    {3289165200 3600 1 WEST}
+    {3307914000 0 0 WET}
+    {3321219600 3600 1 WEST}
+    {3339363600 0 0 WET}
+    {3352669200 3600 1 WEST}
+    {3370813200 0 0 WET}
+    {3384118800 3600 1 WEST}
+    {3402867600 0 0 WET}
+    {3415568400 3600 1 WEST}
+    {3434317200 0 0 WET}
+    {3447018000 3600 1 WEST}
+    {3465766800 0 0 WET}
+    {3479072400 3600 1 WEST}
+    {3497216400 0 0 WET}
+    {3510522000 3600 1 WEST}
+    {3528666000 0 0 WET}
+    {3541971600 3600 1 WEST}
+    {3560115600 0 0 WET}
+    {3573421200 3600 1 WEST}
+    {3592170000 0 0 WET}
+    {3604870800 3600 1 WEST}
+    {3623619600 0 0 WET}
+    {3636320400 3600 1 WEST}
+    {3655069200 0 0 WET}
+    {3668374800 3600 1 WEST}
+    {3686518800 0 0 WET}
+    {3699824400 3600 1 WEST}
+    {3717968400 0 0 WET}
+    {3731274000 3600 1 WEST}
+    {3750022800 0 0 WET}
+    {3762723600 3600 1 WEST}
+    {3781472400 0 0 WET}
+    {3794173200 3600 1 WEST}
+    {3812922000 0 0 WET}
+    {3825622800 3600 1 WEST}
+    {3844371600 0 0 WET}
+    {3857677200 3600 1 WEST}
+    {3875821200 0 0 WET}
+    {3889126800 3600 1 WEST}
+    {3907270800 0 0 WET}
+    {3920576400 3600 1 WEST}
+    {3939325200 0 0 WET}
+    {3952026000 3600 1 WEST}
+    {3970774800 0 0 WET}
+    {3983475600 3600 1 WEST}
+    {4002224400 0 0 WET}
+    {4015530000 3600 1 WEST}
+    {4033674000 0 0 WET}
+    {4046979600 3600 1 WEST}
+    {4065123600 0 0 WET}
+    {4078429200 3600 1 WEST}
+    {4096573200 0 0 WET}
+}
diff --git a/library/tzdata/Atlantic/Cape_Verde b/library/tzdata/Atlantic/Cape_Verde
new file mode 100644
index 0000000..f0bb79f
--- /dev/null
+++ b/library/tzdata/Atlantic/Cape_Verde
@@ -0,0 +1,9 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Atlantic/Cape_Verde) {
+    {-9223372036854775808 -5644 0 LMT}
+    {-1988144756 -7200 0 CVT}
+    {-862610400 -3600 1 CVST}
+    {-764118000 -7200 0 CVT}
+    {186120000 -3600 0 CVT}
+}
diff --git a/library/tzdata/Atlantic/Faeroe b/library/tzdata/Atlantic/Faeroe
new file mode 100644
index 0000000..4cafc34
--- /dev/null
+++ b/library/tzdata/Atlantic/Faeroe
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Atlantic/Faroe)]} {
+    LoadTimeZoneFile Atlantic/Faroe
+}
+set TZData(:Atlantic/Faeroe) $TZData(:Atlantic/Faroe)
diff --git a/library/tzdata/Atlantic/Faroe b/library/tzdata/Atlantic/Faroe
new file mode 100644
index 0000000..d2c314a
--- /dev/null
+++ b/library/tzdata/Atlantic/Faroe
@@ -0,0 +1,245 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Atlantic/Faroe) {
+    {-9223372036854775808 -1624 0 LMT}
+    {-1955748776 0 0 WET}
+    {347155200 0 0 WET}
+    {354675600 3600 1 WEST}
+    {370400400 0 0 WET}
+    {386125200 3600 1 WEST}
+    {401850000 0 0 WET}
+    {417574800 3600 1 WEST}
+    {433299600 0 0 WET}
+    {449024400 3600 1 WEST}
+    {465354000 0 0 WET}
+    {481078800 3600 1 WEST}
+    {496803600 0 0 WET}
+    {512528400 3600 1 WEST}
+    {528253200 0 0 WET}
+    {543978000 3600 1 WEST}
+    {559702800 0 0 WET}
+    {575427600 3600 1 WEST}
+    {591152400 0 0 WET}
+    {606877200 3600 1 WEST}
+    {622602000 0 0 WET}
+    {638326800 3600 1 WEST}
+    {654656400 0 0 WET}
+    {670381200 3600 1 WEST}
+    {686106000 0 0 WET}
+    {701830800 3600 1 WEST}
+    {717555600 0 0 WET}
+    {733280400 3600 1 WEST}
+    {749005200 0 0 WET}
+    {764730000 3600 1 WEST}
+    {780454800 0 0 WET}
+    {796179600 3600 1 WEST}
+    {811904400 0 0 WET}
+    {828234000 3600 1 WEST}
+    {846378000 0 0 WET}
+    {859683600 3600 1 WEST}
+    {877827600 0 0 WET}
+    {891133200 3600 1 WEST}
+    {909277200 0 0 WET}
+    {922582800 3600 1 WEST}
+    {941331600 0 0 WET}
+    {954032400 3600 1 WEST}
+    {972781200 0 0 WET}
+    {985482000 3600 1 WEST}
+    {1004230800 0 0 WET}
+    {1017536400 3600 1 WEST}
+    {1035680400 0 0 WET}
+    {1048986000 3600 1 WEST}
+    {1067130000 0 0 WET}
+    {1080435600 3600 1 WEST}
+    {1099184400 0 0 WET}
+    {1111885200 3600 1 WEST}
+    {1130634000 0 0 WET}
+    {1143334800 3600 1 WEST}
+    {1162083600 0 0 WET}
+    {1174784400 3600 1 WEST}
+    {1193533200 0 0 WET}
+    {1206838800 3600 1 WEST}
+    {1224982800 0 0 WET}
+    {1238288400 3600 1 WEST}
+    {1256432400 0 0 WET}
+    {1269738000 3600 1 WEST}
+    {1288486800 0 0 WET}
+    {1301187600 3600 1 WEST}
+    {1319936400 0 0 WET}
+    {1332637200 3600 1 WEST}
+    {1351386000 0 0 WET}
+    {1364691600 3600 1 WEST}
+    {1382835600 0 0 WET}
+    {1396141200 3600 1 WEST}
+    {1414285200 0 0 WET}
+    {1427590800 3600 1 WEST}
+    {1445734800 0 0 WET}
+    {1459040400 3600 1 WEST}
+    {1477789200 0 0 WET}
+    {1490490000 3600 1 WEST}
+    {1509238800 0 0 WET}
+    {1521939600 3600 1 WEST}
+    {1540688400 0 0 WET}
+    {1553994000 3600 1 WEST}
+    {1572138000 0 0 WET}
+    {1585443600 3600 1 WEST}
+    {1603587600 0 0 WET}
+    {1616893200 3600 1 WEST}
+    {1635642000 0 0 WET}
+    {1648342800 3600 1 WEST}
+    {1667091600 0 0 WET}
+    {1679792400 3600 1 WEST}
+    {1698541200 0 0 WET}
+    {1711846800 3600 1 WEST}
+    {1729990800 0 0 WET}
+    {1743296400 3600 1 WEST}
+    {1761440400 0 0 WET}
+    {1774746000 3600 1 WEST}
+    {1792890000 0 0 WET}
+    {1806195600 3600 1 WEST}
+    {1824944400 0 0 WET}
+    {1837645200 3600 1 WEST}
+    {1856394000 0 0 WET}
+    {1869094800 3600 1 WEST}
+    {1887843600 0 0 WET}
+    {1901149200 3600 1 WEST}
+    {1919293200 0 0 WET}
+    {1932598800 3600 1 WEST}
+    {1950742800 0 0 WET}
+    {1964048400 3600 1 WEST}
+    {1982797200 0 0 WET}
+    {1995498000 3600 1 WEST}
+    {2014246800 0 0 WET}
+    {2026947600 3600 1 WEST}
+    {2045696400 0 0 WET}
+    {2058397200 3600 1 WEST}
+    {2077146000 0 0 WET}
+    {2090451600 3600 1 WEST}
+    {2108595600 0 0 WET}
+    {2121901200 3600 1 WEST}
+    {2140045200 0 0 WET}
+    {2153350800 3600 1 WEST}
+    {2172099600 0 0 WET}
+    {2184800400 3600 1 WEST}
+    {2203549200 0 0 WET}
+    {2216250000 3600 1 WEST}
+    {2234998800 0 0 WET}
+    {2248304400 3600 1 WEST}
+    {2266448400 0 0 WET}
+    {2279754000 3600 1 WEST}
+    {2297898000 0 0 WET}
+    {2311203600 3600 1 WEST}
+    {2329347600 0 0 WET}
+    {2342653200 3600 1 WEST}
+    {2361402000 0 0 WET}
+    {2374102800 3600 1 WEST}
+    {2392851600 0 0 WET}
+    {2405552400 3600 1 WEST}
+    {2424301200 0 0 WET}
+    {2437606800 3600 1 WEST}
+    {2455750800 0 0 WET}
+    {2469056400 3600 1 WEST}
+    {2487200400 0 0 WET}
+    {2500506000 3600 1 WEST}
+    {2519254800 0 0 WET}
+    {2531955600 3600 1 WEST}
+    {2550704400 0 0 WET}
+    {2563405200 3600 1 WEST}
+    {2582154000 0 0 WET}
+    {2595459600 3600 1 WEST}
+    {2613603600 0 0 WET}
+    {2626909200 3600 1 WEST}
+    {2645053200 0 0 WET}
+    {2658358800 3600 1 WEST}
+    {2676502800 0 0 WET}
+    {2689808400 3600 1 WEST}
+    {2708557200 0 0 WET}
+    {2721258000 3600 1 WEST}
+    {2740006800 0 0 WET}
+    {2752707600 3600 1 WEST}
+    {2771456400 0 0 WET}
+    {2784762000 3600 1 WEST}
+    {2802906000 0 0 WET}
+    {2816211600 3600 1 WEST}
+    {2834355600 0 0 WET}
+    {2847661200 3600 1 WEST}
+    {2866410000 0 0 WET}
+    {2879110800 3600 1 WEST}
+    {2897859600 0 0 WET}
+    {2910560400 3600 1 WEST}
+    {2929309200 0 0 WET}
+    {2942010000 3600 1 WEST}
+    {2960758800 0 0 WET}
+    {2974064400 3600 1 WEST}
+    {2992208400 0 0 WET}
+    {3005514000 3600 1 WEST}
+    {3023658000 0 0 WET}
+    {3036963600 3600 1 WEST}
+    {3055712400 0 0 WET}
+    {3068413200 3600 1 WEST}
+    {3087162000 0 0 WET}
+    {3099862800 3600 1 WEST}
+    {3118611600 0 0 WET}
+    {3131917200 3600 1 WEST}
+    {3150061200 0 0 WET}
+    {3163366800 3600 1 WEST}
+    {3181510800 0 0 WET}
+    {3194816400 3600 1 WEST}
+    {3212960400 0 0 WET}
+    {3226266000 3600 1 WEST}
+    {3245014800 0 0 WET}
+    {3257715600 3600 1 WEST}
+    {3276464400 0 0 WET}
+    {3289165200 3600 1 WEST}
+    {3307914000 0 0 WET}
+    {3321219600 3600 1 WEST}
+    {3339363600 0 0 WET}
+    {3352669200 3600 1 WEST}
+    {3370813200 0 0 WET}
+    {3384118800 3600 1 WEST}
+    {3402867600 0 0 WET}
+    {3415568400 3600 1 WEST}
+    {3434317200 0 0 WET}
+    {3447018000 3600 1 WEST}
+    {3465766800 0 0 WET}
+    {3479072400 3600 1 WEST}
+    {3497216400 0 0 WET}
+    {3510522000 3600 1 WEST}
+    {3528666000 0 0 WET}
+    {3541971600 3600 1 WEST}
+    {3560115600 0 0 WET}
+    {3573421200 3600 1 WEST}
+    {3592170000 0 0 WET}
+    {3604870800 3600 1 WEST}
+    {3623619600 0 0 WET}
+    {3636320400 3600 1 WEST}
+    {3655069200 0 0 WET}
+    {3668374800 3600 1 WEST}
+    {3686518800 0 0 WET}
+    {3699824400 3600 1 WEST}
+    {3717968400 0 0 WET}
+    {3731274000 3600 1 WEST}
+    {3750022800 0 0 WET}
+    {3762723600 3600 1 WEST}
+    {3781472400 0 0 WET}
+    {3794173200 3600 1 WEST}
+    {3812922000 0 0 WET}
+    {3825622800 3600 1 WEST}
+    {3844371600 0 0 WET}
+    {3857677200 3600 1 WEST}
+    {3875821200 0 0 WET}
+    {3889126800 3600 1 WEST}
+    {3907270800 0 0 WET}
+    {3920576400 3600 1 WEST}
+    {3939325200 0 0 WET}
+    {3952026000 3600 1 WEST}
+    {3970774800 0 0 WET}
+    {3983475600 3600 1 WEST}
+    {4002224400 0 0 WET}
+    {4015530000 3600 1 WEST}
+    {4033674000 0 0 WET}
+    {4046979600 3600 1 WEST}
+    {4065123600 0 0 WET}
+    {4078429200 3600 1 WEST}
+    {4096573200 0 0 WET}
+}
diff --git a/library/tzdata/Atlantic/Jan_Mayen b/library/tzdata/Atlantic/Jan_Mayen
new file mode 100644
index 0000000..e592187
--- /dev/null
+++ b/library/tzdata/Atlantic/Jan_Mayen
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Europe/Oslo)]} {
+    LoadTimeZoneFile Europe/Oslo
+}
+set TZData(:Atlantic/Jan_Mayen) $TZData(:Europe/Oslo)
diff --git a/library/tzdata/Atlantic/Madeira b/library/tzdata/Atlantic/Madeira
new file mode 100644
index 0000000..fac7f92
--- /dev/null
+++ b/library/tzdata/Atlantic/Madeira
@@ -0,0 +1,350 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Atlantic/Madeira) {
+    {-9223372036854775808 -4056 0 LMT}
+    {-2713906344 -4056 0 FMT}
+    {-1830379944 -3600 0 MADT}
+    {-1689552000 0 1 MADST}
+    {-1677798000 -3600 0 MADT}
+    {-1667433600 0 1 MADST}
+    {-1647734400 -3600 0 MADT}
+    {-1635811200 0 1 MADST}
+    {-1616198400 -3600 0 MADT}
+    {-1604361600 0 1 MADST}
+    {-1584662400 -3600 0 MADT}
+    {-1572739200 0 1 MADST}
+    {-1553040000 -3600 0 MADT}
+    {-1541203200 0 1 MADST}
+    {-1521504000 -3600 0 MADT}
+    {-1442448000 0 1 MADST}
+    {-1426809600 -3600 0 MADT}
+    {-1379289600 0 1 MADST}
+    {-1364774400 -3600 0 MADT}
+    {-1348444800 0 1 MADST}
+    {-1333324800 -3600 0 MADT}
+    {-1316390400 0 1 MADST}
+    {-1301270400 -3600 0 MADT}
+    {-1284336000 0 1 MADST}
+    {-1269820800 -3600 0 MADT}
+    {-1221436800 0 1 MADST}
+    {-1206921600 -3600 0 MADT}
+    {-1191196800 0 1 MADST}
+    {-1175472000 -3600 0 MADT}
+    {-1127692800 0 1 MADST}
+    {-1111968000 -3600 0 MADT}
+    {-1096848000 0 1 MADST}
+    {-1080518400 -3600 0 MADT}
+    {-1063584000 0 1 MADST}
+    {-1049068800 -3600 0 MADT}
+    {-1033344000 0 1 MADST}
+    {-1017619200 -3600 0 MADT}
+    {-1002499200 0 1 MADST}
+    {-986169600 -3600 0 MADT}
+    {-969235200 0 1 MADST}
+    {-950486400 -3600 0 MADT}
+    {-942019200 0 1 MADST}
+    {-922665600 -3600 0 MADT}
+    {-906940800 0 1 MADST}
+    {-891129600 -3600 0 MADT}
+    {-877305600 0 1 MADST}
+    {-873680400 3600 1 MADMT}
+    {-864003600 0 1 MADST}
+    {-857952000 -3600 0 MADT}
+    {-845856000 0 1 MADST}
+    {-842835600 3600 1 MADMT}
+    {-831344400 0 1 MADST}
+    {-825897600 -3600 0 MADT}
+    {-814406400 0 1 MADST}
+    {-810781200 3600 1 MADMT}
+    {-799894800 0 1 MADST}
+    {-794448000 -3600 0 MADT}
+    {-782956800 0 1 MADST}
+    {-779331600 3600 1 MADMT}
+    {-768445200 0 1 MADST}
+    {-762998400 -3600 0 MADT}
+    {-749088000 0 1 MADST}
+    {-733363200 -3600 0 MADT}
+    {-717627600 0 1 MADST}
+    {-701902800 -3600 0 MADT}
+    {-686178000 0 1 MADST}
+    {-670453200 -3600 0 MADT}
+    {-654728400 0 1 MADST}
+    {-639003600 -3600 0 MADT}
+    {-591829200 0 1 MADST}
+    {-575499600 -3600 0 MADT}
+    {-559774800 0 1 MADST}
+    {-544050000 -3600 0 MADT}
+    {-528325200 0 1 MADST}
+    {-512600400 -3600 0 MADT}
+    {-496875600 0 1 MADST}
+    {-481150800 -3600 0 MADT}
+    {-465426000 0 1 MADST}
+    {-449701200 -3600 0 MADT}
+    {-433976400 0 1 MADST}
+    {-417646800 -3600 0 MADT}
+    {-401922000 0 1 MADST}
+    {-386197200 -3600 0 MADT}
+    {-370472400 0 1 MADST}
+    {-354747600 -3600 0 MADT}
+    {-339022800 0 1 MADST}
+    {-323298000 -3600 0 MADT}
+    {-307573200 0 1 MADST}
+    {-291848400 -3600 0 MADT}
+    {-276123600 0 1 MADST}
+    {-260398800 -3600 0 MADT}
+    {-244674000 0 1 MADST}
+    {-228344400 -3600 0 MADT}
+    {-212619600 0 1 MADST}
+    {-196894800 -3600 0 MADT}
+    {-181170000 0 1 MADST}
+    {-165445200 -3600 0 MADT}
+    {-149720400 0 1 MADST}
+    {-133995600 -3600 0 MADT}
+    {-118270800 0 0 WET}
+    {228268800 3600 1 WEST}
+    {243993600 0 0 WET}
+    {260323200 3600 1 WEST}
+    {276048000 0 0 WET}
+    {291772800 3600 1 WEST}
+    {307501200 0 0 WET}
+    {323222400 3600 1 WEST}
+    {338950800 0 0 WET}
+    {354675600 3600 1 WEST}
+    {370400400 0 0 WET}
+    {386125200 3600 1 WEST}
+    {401850000 0 0 WET}
+    {417578400 3600 1 WEST}
+    {433299600 0 0 WET}
+    {449024400 3600 1 WEST}
+    {465354000 0 0 WET}
+    {481078800 3600 1 WEST}
+    {496803600 0 0 WET}
+    {512528400 3600 1 WEST}
+    {528253200 0 0 WET}
+    {543978000 3600 1 WEST}
+    {559702800 0 0 WET}
+    {575427600 3600 1 WEST}
+    {591152400 0 0 WET}
+    {606877200 3600 1 WEST}
+    {622602000 0 0 WET}
+    {638326800 3600 1 WEST}
+    {654656400 0 0 WET}
+    {670381200 3600 1 WEST}
+    {686106000 0 0 WET}
+    {701830800 3600 1 WEST}
+    {717555600 0 0 WET}
+    {733280400 3600 1 WEST}
+    {749005200 0 0 WET}
+    {764730000 3600 1 WEST}
+    {780454800 0 0 WET}
+    {796179600 3600 1 WEST}
+    {811904400 0 0 WET}
+    {828234000 3600 1 WEST}
+    {846378000 0 0 WET}
+    {859683600 3600 1 WEST}
+    {877827600 0 0 WET}
+    {891133200 3600 1 WEST}
+    {909277200 0 0 WET}
+    {922582800 3600 1 WEST}
+    {941331600 0 0 WET}
+    {954032400 3600 1 WEST}
+    {972781200 0 0 WET}
+    {985482000 3600 1 WEST}
+    {1004230800 0 0 WET}
+    {1017536400 3600 1 WEST}
+    {1035680400 0 0 WET}
+    {1048986000 3600 1 WEST}
+    {1067130000 0 0 WET}
+    {1080435600 3600 1 WEST}
+    {1099184400 0 0 WET}
+    {1111885200 3600 1 WEST}
+    {1130634000 0 0 WET}
+    {1143334800 3600 1 WEST}
+    {1162083600 0 0 WET}
+    {1174784400 3600 1 WEST}
+    {1193533200 0 0 WET}
+    {1206838800 3600 1 WEST}
+    {1224982800 0 0 WET}
+    {1238288400 3600 1 WEST}
+    {1256432400 0 0 WET}
+    {1269738000 3600 1 WEST}
+    {1288486800 0 0 WET}
+    {1301187600 3600 1 WEST}
+    {1319936400 0 0 WET}
+    {1332637200 3600 1 WEST}
+    {1351386000 0 0 WET}
+    {1364691600 3600 1 WEST}
+    {1382835600 0 0 WET}
+    {1396141200 3600 1 WEST}
+    {1414285200 0 0 WET}
+    {1427590800 3600 1 WEST}
+    {1445734800 0 0 WET}
+    {1459040400 3600 1 WEST}
+    {1477789200 0 0 WET}
+    {1490490000 3600 1 WEST}
+    {1509238800 0 0 WET}
+    {1521939600 3600 1 WEST}
+    {1540688400 0 0 WET}
+    {1553994000 3600 1 WEST}
+    {1572138000 0 0 WET}
+    {1585443600 3600 1 WEST}
+    {1603587600 0 0 WET}
+    {1616893200 3600 1 WEST}
+    {1635642000 0 0 WET}
+    {1648342800 3600 1 WEST}
+    {1667091600 0 0 WET}
+    {1679792400 3600 1 WEST}
+    {1698541200 0 0 WET}
+    {1711846800 3600 1 WEST}
+    {1729990800 0 0 WET}
+    {1743296400 3600 1 WEST}
+    {1761440400 0 0 WET}
+    {1774746000 3600 1 WEST}
+    {1792890000 0 0 WET}
+    {1806195600 3600 1 WEST}
+    {1824944400 0 0 WET}
+    {1837645200 3600 1 WEST}
+    {1856394000 0 0 WET}
+    {1869094800 3600 1 WEST}
+    {1887843600 0 0 WET}
+    {1901149200 3600 1 WEST}
+    {1919293200 0 0 WET}
+    {1932598800 3600 1 WEST}
+    {1950742800 0 0 WET}
+    {1964048400 3600 1 WEST}
+    {1982797200 0 0 WET}
+    {1995498000 3600 1 WEST}
+    {2014246800 0 0 WET}
+    {2026947600 3600 1 WEST}
+    {2045696400 0 0 WET}
+    {2058397200 3600 1 WEST}
+    {2077146000 0 0 WET}
+    {2090451600 3600 1 WEST}
+    {2108595600 0 0 WET}
+    {2121901200 3600 1 WEST}
+    {2140045200 0 0 WET}
+    {2153350800 3600 1 WEST}
+    {2172099600 0 0 WET}
+    {2184800400 3600 1 WEST}
+    {2203549200 0 0 WET}
+    {2216250000 3600 1 WEST}
+    {2234998800 0 0 WET}
+    {2248304400 3600 1 WEST}
+    {2266448400 0 0 WET}
+    {2279754000 3600 1 WEST}
+    {2297898000 0 0 WET}
+    {2311203600 3600 1 WEST}
+    {2329347600 0 0 WET}
+    {2342653200 3600 1 WEST}
+    {2361402000 0 0 WET}
+    {2374102800 3600 1 WEST}
+    {2392851600 0 0 WET}
+    {2405552400 3600 1 WEST}
+    {2424301200 0 0 WET}
+    {2437606800 3600 1 WEST}
+    {2455750800 0 0 WET}
+    {2469056400 3600 1 WEST}
+    {2487200400 0 0 WET}
+    {2500506000 3600 1 WEST}
+    {2519254800 0 0 WET}
+    {2531955600 3600 1 WEST}
+    {2550704400 0 0 WET}
+    {2563405200 3600 1 WEST}
+    {2582154000 0 0 WET}
+    {2595459600 3600 1 WEST}
+    {2613603600 0 0 WET}
+    {2626909200 3600 1 WEST}
+    {2645053200 0 0 WET}
+    {2658358800 3600 1 WEST}
+    {2676502800 0 0 WET}
+    {2689808400 3600 1 WEST}
+    {2708557200 0 0 WET}
+    {2721258000 3600 1 WEST}
+    {2740006800 0 0 WET}
+    {2752707600 3600 1 WEST}
+    {2771456400 0 0 WET}
+    {2784762000 3600 1 WEST}
+    {2802906000 0 0 WET}
+    {2816211600 3600 1 WEST}
+    {2834355600 0 0 WET}
+    {2847661200 3600 1 WEST}
+    {2866410000 0 0 WET}
+    {2879110800 3600 1 WEST}
+    {2897859600 0 0 WET}
+    {2910560400 3600 1 WEST}
+    {2929309200 0 0 WET}
+    {2942010000 3600 1 WEST}
+    {2960758800 0 0 WET}
+    {2974064400 3600 1 WEST}
+    {2992208400 0 0 WET}
+    {3005514000 3600 1 WEST}
+    {3023658000 0 0 WET}
+    {3036963600 3600 1 WEST}
+    {3055712400 0 0 WET}
+    {3068413200 3600 1 WEST}
+    {3087162000 0 0 WET}
+    {3099862800 3600 1 WEST}
+    {3118611600 0 0 WET}
+    {3131917200 3600 1 WEST}
+    {3150061200 0 0 WET}
+    {3163366800 3600 1 WEST}
+    {3181510800 0 0 WET}
+    {3194816400 3600 1 WEST}
+    {3212960400 0 0 WET}
+    {3226266000 3600 1 WEST}
+    {3245014800 0 0 WET}
+    {3257715600 3600 1 WEST}
+    {3276464400 0 0 WET}
+    {3289165200 3600 1 WEST}
+    {3307914000 0 0 WET}
+    {3321219600 3600 1 WEST}
+    {3339363600 0 0 WET}
+    {3352669200 3600 1 WEST}
+    {3370813200 0 0 WET}
+    {3384118800 3600 1 WEST}
+    {3402867600 0 0 WET}
+    {3415568400 3600 1 WEST}
+    {3434317200 0 0 WET}
+    {3447018000 3600 1 WEST}
+    {3465766800 0 0 WET}
+    {3479072400 3600 1 WEST}
+    {3497216400 0 0 WET}
+    {3510522000 3600 1 WEST}
+    {3528666000 0 0 WET}
+    {3541971600 3600 1 WEST}
+    {3560115600 0 0 WET}
+    {3573421200 3600 1 WEST}
+    {3592170000 0 0 WET}
+    {3604870800 3600 1 WEST}
+    {3623619600 0 0 WET}
+    {3636320400 3600 1 WEST}
+    {3655069200 0 0 WET}
+    {3668374800 3600 1 WEST}
+    {3686518800 0 0 WET}
+    {3699824400 3600 1 WEST}
+    {3717968400 0 0 WET}
+    {3731274000 3600 1 WEST}
+    {3750022800 0 0 WET}
+    {3762723600 3600 1 WEST}
+    {3781472400 0 0 WET}
+    {3794173200 3600 1 WEST}
+    {3812922000 0 0 WET}
+    {3825622800 3600 1 WEST}
+    {3844371600 0 0 WET}
+    {3857677200 3600 1 WEST}
+    {3875821200 0 0 WET}
+    {3889126800 3600 1 WEST}
+    {3907270800 0 0 WET}
+    {3920576400 3600 1 WEST}
+    {3939325200 0 0 WET}
+    {3952026000 3600 1 WEST}
+    {3970774800 0 0 WET}
+    {3983475600 3600 1 WEST}
+    {4002224400 0 0 WET}
+    {4015530000 3600 1 WEST}
+    {4033674000 0 0 WET}
+    {4046979600 3600 1 WEST}
+    {4065123600 0 0 WET}
+    {4078429200 3600 1 WEST}
+    {4096573200 0 0 WET}
+}
diff --git a/library/tzdata/Atlantic/Reykjavik b/library/tzdata/Atlantic/Reykjavik
new file mode 100644
index 0000000..ad7f0db
--- /dev/null
+++ b/library/tzdata/Atlantic/Reykjavik
@@ -0,0 +1,73 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Atlantic/Reykjavik) {
+    {-9223372036854775808 -5280 0 LMT}
+    {-1956609120 -3600 0 IST}
+    {-1668211200 0 1 ISST}
+    {-1647212400 -3600 0 IST}
+    {-1636675200 0 1 ISST}
+    {-1613430000 -3600 0 IST}
+    {-1605139200 0 1 ISST}
+    {-1581894000 -3600 0 IST}
+    {-1539561600 0 1 ISST}
+    {-1531350000 -3600 0 IST}
+    {-968025600 0 1 ISST}
+    {-952293600 -3600 0 IST}
+    {-942008400 0 1 ISST}
+    {-920239200 -3600 0 IST}
+    {-909957600 0 1 ISST}
+    {-888789600 -3600 0 IST}
+    {-877903200 0 1 ISST}
+    {-857944800 -3600 0 IST}
+    {-846453600 0 1 ISST}
+    {-826495200 -3600 0 IST}
+    {-815004000 0 1 ISST}
+    {-795045600 -3600 0 IST}
+    {-783554400 0 1 ISST}
+    {-762991200 -3600 0 IST}
+    {-752104800 0 1 ISST}
+    {-731541600 -3600 0 IST}
+    {-717631200 0 1 ISST}
+    {-700092000 -3600 0 IST}
+    {-686181600 0 1 ISST}
+    {-668642400 -3600 0 IST}
+    {-654732000 0 1 ISST}
+    {-636588000 -3600 0 IST}
+    {-623282400 0 1 ISST}
+    {-605743200 -3600 0 IST}
+    {-591832800 0 1 ISST}
+    {-573688800 -3600 0 IST}
+    {-559778400 0 1 ISST}
+    {-542239200 -3600 0 IST}
+    {-528328800 0 1 ISST}
+    {-510789600 -3600 0 IST}
+    {-496879200 0 1 ISST}
+    {-479340000 -3600 0 IST}
+    {-465429600 0 1 ISST}
+    {-447890400 -3600 0 IST}
+    {-433980000 0 1 ISST}
+    {-415836000 -3600 0 IST}
+    {-401925600 0 1 ISST}
+    {-384386400 -3600 0 IST}
+    {-370476000 0 1 ISST}
+    {-352936800 -3600 0 IST}
+    {-339026400 0 1 ISST}
+    {-321487200 -3600 0 IST}
+    {-307576800 0 1 ISST}
+    {-290037600 -3600 0 IST}
+    {-276127200 0 1 ISST}
+    {-258588000 -3600 0 IST}
+    {-244677600 0 1 ISST}
+    {-226533600 -3600 0 IST}
+    {-212623200 0 1 ISST}
+    {-195084000 -3600 0 IST}
+    {-181173600 0 1 ISST}
+    {-163634400 -3600 0 IST}
+    {-149724000 0 1 ISST}
+    {-132184800 -3600 0 IST}
+    {-118274400 0 1 ISST}
+    {-100735200 -3600 0 IST}
+    {-86824800 0 1 ISST}
+    {-68680800 -3600 0 IST}
+    {-54770400 0 0 GMT}
+}
diff --git a/library/tzdata/Atlantic/South_Georgia b/library/tzdata/Atlantic/South_Georgia
new file mode 100644
index 0000000..cbfc826
--- /dev/null
+++ b/library/tzdata/Atlantic/South_Georgia
@@ -0,0 +1,6 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Atlantic/South_Georgia) {
+    {-9223372036854775808 -8768 0 LMT}
+    {-2524512832 -7200 0 GST}
+}
diff --git a/library/tzdata/Atlantic/St_Helena b/library/tzdata/Atlantic/St_Helena
new file mode 100644
index 0000000..bf36c6a
--- /dev/null
+++ b/library/tzdata/Atlantic/St_Helena
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Africa/Abidjan)]} {
+    LoadTimeZoneFile Africa/Abidjan
+}
+set TZData(:Atlantic/St_Helena) $TZData(:Africa/Abidjan)
diff --git a/library/tzdata/Atlantic/Stanley b/library/tzdata/Atlantic/Stanley
new file mode 100644
index 0000000..c287238
--- /dev/null
+++ b/library/tzdata/Atlantic/Stanley
@@ -0,0 +1,75 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Atlantic/Stanley) {
+    {-9223372036854775808 -13884 0 LMT}
+    {-2524507716 -13884 0 SMT}
+    {-1824235716 -14400 0 FKT}
+    {-1018209600 -10800 1 FKST}
+    {-1003093200 -14400 0 FKT}
+    {-986760000 -10800 1 FKST}
+    {-971643600 -14400 0 FKT}
+    {-954705600 -10800 1 FKST}
+    {-939589200 -14400 0 FKT}
+    {-923256000 -10800 1 FKST}
+    {-908139600 -14400 0 FKT}
+    {-891806400 -10800 1 FKST}
+    {-876690000 -14400 0 FKT}
+    {-860356800 -10800 1 FKST}
+    {420606000 -7200 0 FKT}
+    {433303200 -7200 1 FKST}
+    {452052000 -10800 0 FKT}
+    {464151600 -7200 1 FKST}
+    {483501600 -10800 0 FKT}
+    {495597600 -14400 0 FKT}
+    {495604800 -10800 1 FKST}
+    {514350000 -14400 0 FKT}
+    {527054400 -10800 1 FKST}
+    {545799600 -14400 0 FKT}
+    {558504000 -10800 1 FKST}
+    {577249200 -14400 0 FKT}
+    {589953600 -10800 1 FKST}
+    {608698800 -14400 0 FKT}
+    {621403200 -10800 1 FKST}
+    {640753200 -14400 0 FKT}
+    {652852800 -10800 1 FKST}
+    {672202800 -14400 0 FKT}
+    {684907200 -10800 1 FKST}
+    {703652400 -14400 0 FKT}
+    {716356800 -10800 1 FKST}
+    {735102000 -14400 0 FKT}
+    {747806400 -10800 1 FKST}
+    {766551600 -14400 0 FKT}
+    {779256000 -10800 1 FKST}
+    {798001200 -14400 0 FKT}
+    {810705600 -10800 1 FKST}
+    {830055600 -14400 0 FKT}
+    {842760000 -10800 1 FKST}
+    {861505200 -14400 0 FKT}
+    {874209600 -10800 1 FKST}
+    {892954800 -14400 0 FKT}
+    {905659200 -10800 1 FKST}
+    {924404400 -14400 0 FKT}
+    {937108800 -10800 1 FKST}
+    {955854000 -14400 0 FKT}
+    {968558400 -10800 1 FKST}
+    {987310800 -14400 0 FKT}
+    {999410400 -10800 1 FKST}
+    {1019365200 -14400 0 FKT}
+    {1030860000 -10800 1 FKST}
+    {1050814800 -14400 0 FKT}
+    {1062914400 -10800 1 FKST}
+    {1082264400 -14400 0 FKT}
+    {1094364000 -10800 1 FKST}
+    {1113714000 -14400 0 FKT}
+    {1125813600 -10800 1 FKST}
+    {1145163600 -14400 0 FKT}
+    {1157263200 -10800 1 FKST}
+    {1176613200 -14400 0 FKT}
+    {1188712800 -10800 1 FKST}
+    {1208667600 -14400 0 FKT}
+    {1220767200 -10800 1 FKST}
+    {1240117200 -14400 0 FKT}
+    {1252216800 -10800 1 FKST}
+    {1271566800 -14400 0 FKT}
+    {1283662800 -10800 0 FKST}
+}
diff --git a/library/tzdata/Australia/ACT b/library/tzdata/Australia/ACT
new file mode 100644
index 0000000..f7da281
--- /dev/null
+++ b/library/tzdata/Australia/ACT
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Australia/Sydney)]} {
+    LoadTimeZoneFile Australia/Sydney
+}
+set TZData(:Australia/ACT) $TZData(:Australia/Sydney)
diff --git a/library/tzdata/Australia/Adelaide b/library/tzdata/Australia/Adelaide
new file mode 100644
index 0000000..7e1b04e
--- /dev/null
+++ b/library/tzdata/Australia/Adelaide
@@ -0,0 +1,273 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Australia/Adelaide) {
+    {-9223372036854775808 33260 0 LMT}
+    {-2364110060 32400 0 ACST}
+    {-2230189200 34200 0 ACST}
+    {-1672565340 37800 1 ACDT}
+    {-1665390600 34200 0 ACST}
+    {-883639800 37800 1 ACDT}
+    {-876126600 34200 0 ACST}
+    {-860398200 37800 1 ACDT}
+    {-844677000 34200 0 ACST}
+    {-828343800 37800 1 ACDT}
+    {-813227400 34200 0 ACST}
+    {31501800 34200 0 ACST}
+    {57688200 37800 1 ACDT}
+    {67969800 34200 0 ACST}
+    {89137800 37800 1 ACDT}
+    {100024200 34200 0 ACST}
+    {120587400 37800 1 ACDT}
+    {131473800 34200 0 ACST}
+    {152037000 37800 1 ACDT}
+    {162923400 34200 0 ACST}
+    {183486600 37800 1 ACDT}
+    {194977800 34200 0 ACST}
+    {215541000 37800 1 ACDT}
+    {226427400 34200 0 ACST}
+    {246990600 37800 1 ACDT}
+    {257877000 34200 0 ACST}
+    {278440200 37800 1 ACDT}
+    {289326600 34200 0 ACST}
+    {309889800 37800 1 ACDT}
+    {320776200 34200 0 ACST}
+    {341339400 37800 1 ACDT}
+    {352225800 34200 0 ACST}
+    {372789000 37800 1 ACDT}
+    {384280200 34200 0 ACST}
+    {404843400 37800 1 ACDT}
+    {415729800 34200 0 ACST}
+    {436293000 37800 1 ACDT}
+    {447179400 34200 0 ACST}
+    {467742600 37800 1 ACDT}
+    {478629000 34200 0 ACST}
+    {499192200 37800 1 ACDT}
+    {511288200 34200 0 ACST}
+    {530037000 37800 1 ACDT}
+    {542737800 34200 0 ACST}
+    {562091400 37800 1 ACDT}
+    {574792200 34200 0 ACST}
+    {594145800 37800 1 ACDT}
+    {606241800 34200 0 ACST}
+    {625595400 37800 1 ACDT}
+    {637691400 34200 0 ACST}
+    {657045000 37800 1 ACDT}
+    {667931400 34200 0 ACST}
+    {688494600 37800 1 ACDT}
+    {701195400 34200 0 ACST}
+    {719944200 37800 1 ACDT}
+    {731435400 34200 0 ACST}
+    {751998600 37800 1 ACDT}
+    {764094600 34200 0 ACST}
+    {783448200 37800 1 ACDT}
+    {796149000 34200 0 ACST}
+    {814897800 37800 1 ACDT}
+    {828203400 34200 0 ACST}
+    {846347400 37800 1 ACDT}
+    {859653000 34200 0 ACST}
+    {877797000 37800 1 ACDT}
+    {891102600 34200 0 ACST}
+    {909246600 37800 1 ACDT}
+    {922552200 34200 0 ACST}
+    {941301000 37800 1 ACDT}
+    {954001800 34200 0 ACST}
+    {972750600 37800 1 ACDT}
+    {985451400 34200 0 ACST}
+    {1004200200 37800 1 ACDT}
+    {1017505800 34200 0 ACST}
+    {1035649800 37800 1 ACDT}
+    {1048955400 34200 0 ACST}
+    {1067099400 37800 1 ACDT}
+    {1080405000 34200 0 ACST}
+    {1099153800 37800 1 ACDT}
+    {1111854600 34200 0 ACST}
+    {1130603400 37800 1 ACDT}
+    {1143909000 34200 0 ACST}
+    {1162053000 37800 1 ACDT}
+    {1174753800 34200 0 ACST}
+    {1193502600 37800 1 ACDT}
+    {1207413000 34200 0 ACST}
+    {1223137800 37800 1 ACDT}
+    {1238862600 34200 0 ACST}
+    {1254587400 37800 1 ACDT}
+    {1270312200 34200 0 ACST}
+    {1286037000 37800 1 ACDT}
+    {1301761800 34200 0 ACST}
+    {1317486600 37800 1 ACDT}
+    {1333211400 34200 0 ACST}
+    {1349541000 37800 1 ACDT}
+    {1365265800 34200 0 ACST}
+    {1380990600 37800 1 ACDT}
+    {1396715400 34200 0 ACST}
+    {1412440200 37800 1 ACDT}
+    {1428165000 34200 0 ACST}
+    {1443889800 37800 1 ACDT}
+    {1459614600 34200 0 ACST}
+    {1475339400 37800 1 ACDT}
+    {1491064200 34200 0 ACST}
+    {1506789000 37800 1 ACDT}
+    {1522513800 34200 0 ACST}
+    {1538843400 37800 1 ACDT}
+    {1554568200 34200 0 ACST}
+    {1570293000 37800 1 ACDT}
+    {1586017800 34200 0 ACST}
+    {1601742600 37800 1 ACDT}
+    {1617467400 34200 0 ACST}
+    {1633192200 37800 1 ACDT}
+    {1648917000 34200 0 ACST}
+    {1664641800 37800 1 ACDT}
+    {1680366600 34200 0 ACST}
+    {1696091400 37800 1 ACDT}
+    {1712421000 34200 0 ACST}
+    {1728145800 37800 1 ACDT}
+    {1743870600 34200 0 ACST}
+    {1759595400 37800 1 ACDT}
+    {1775320200 34200 0 ACST}
+    {1791045000 37800 1 ACDT}
+    {1806769800 34200 0 ACST}
+    {1822494600 37800 1 ACDT}
+    {1838219400 34200 0 ACST}
+    {1853944200 37800 1 ACDT}
+    {1869669000 34200 0 ACST}
+    {1885998600 37800 1 ACDT}
+    {1901723400 34200 0 ACST}
+    {1917448200 37800 1 ACDT}
+    {1933173000 34200 0 ACST}
+    {1948897800 37800 1 ACDT}
+    {1964622600 34200 0 ACST}
+    {1980347400 37800 1 ACDT}
+    {1996072200 34200 0 ACST}
+    {2011797000 37800 1 ACDT}
+    {2027521800 34200 0 ACST}
+    {2043246600 37800 1 ACDT}
+    {2058971400 34200 0 ACST}
+    {2075301000 37800 1 ACDT}
+    {2091025800 34200 0 ACST}
+    {2106750600 37800 1 ACDT}
+    {2122475400 34200 0 ACST}
+    {2138200200 37800 1 ACDT}
+    {2153925000 34200 0 ACST}
+    {2169649800 37800 1 ACDT}
+    {2185374600 34200 0 ACST}
+    {2201099400 37800 1 ACDT}
+    {2216824200 34200 0 ACST}
+    {2233153800 37800 1 ACDT}
+    {2248878600 34200 0 ACST}
+    {2264603400 37800 1 ACDT}
+    {2280328200 34200 0 ACST}
+    {2296053000 37800 1 ACDT}
+    {2311777800 34200 0 ACST}
+    {2327502600 37800 1 ACDT}
+    {2343227400 34200 0 ACST}
+    {2358952200 37800 1 ACDT}
+    {2374677000 34200 0 ACST}
+    {2390401800 37800 1 ACDT}
+    {2406126600 34200 0 ACST}
+    {2422456200 37800 1 ACDT}
+    {2438181000 34200 0 ACST}
+    {2453905800 37800 1 ACDT}
+    {2469630600 34200 0 ACST}
+    {2485355400 37800 1 ACDT}
+    {2501080200 34200 0 ACST}
+    {2516805000 37800 1 ACDT}
+    {2532529800 34200 0 ACST}
+    {2548254600 37800 1 ACDT}
+    {2563979400 34200 0 ACST}
+    {2579704200 37800 1 ACDT}
+    {2596033800 34200 0 ACST}
+    {2611758600 37800 1 ACDT}
+    {2627483400 34200 0 ACST}
+    {2643208200 37800 1 ACDT}
+    {2658933000 34200 0 ACST}
+    {2674657800 37800 1 ACDT}
+    {2690382600 34200 0 ACST}
+    {2706107400 37800 1 ACDT}
+    {2721832200 34200 0 ACST}
+    {2737557000 37800 1 ACDT}
+    {2753281800 34200 0 ACST}
+    {2769611400 37800 1 ACDT}
+    {2785336200 34200 0 ACST}
+    {2801061000 37800 1 ACDT}
+    {2816785800 34200 0 ACST}
+    {2832510600 37800 1 ACDT}
+    {2848235400 34200 0 ACST}
+    {2863960200 37800 1 ACDT}
+    {2879685000 34200 0 ACST}
+    {2895409800 37800 1 ACDT}
+    {2911134600 34200 0 ACST}
+    {2926859400 37800 1 ACDT}
+    {2942584200 34200 0 ACST}
+    {2958913800 37800 1 ACDT}
+    {2974638600 34200 0 ACST}
+    {2990363400 37800 1 ACDT}
+    {3006088200 34200 0 ACST}
+    {3021813000 37800 1 ACDT}
+    {3037537800 34200 0 ACST}
+    {3053262600 37800 1 ACDT}
+    {3068987400 34200 0 ACST}
+    {3084712200 37800 1 ACDT}
+    {3100437000 34200 0 ACST}
+    {3116766600 37800 1 ACDT}
+    {3132491400 34200 0 ACST}
+    {3148216200 37800 1 ACDT}
+    {3163941000 34200 0 ACST}
+    {3179665800 37800 1 ACDT}
+    {3195390600 34200 0 ACST}
+    {3211115400 37800 1 ACDT}
+    {3226840200 34200 0 ACST}
+    {3242565000 37800 1 ACDT}
+    {3258289800 34200 0 ACST}
+    {3274014600 37800 1 ACDT}
+    {3289739400 34200 0 ACST}
+    {3306069000 37800 1 ACDT}
+    {3321793800 34200 0 ACST}
+    {3337518600 37800 1 ACDT}
+    {3353243400 34200 0 ACST}
+    {3368968200 37800 1 ACDT}
+    {3384693000 34200 0 ACST}
+    {3400417800 37800 1 ACDT}
+    {3416142600 34200 0 ACST}
+    {3431867400 37800 1 ACDT}
+    {3447592200 34200 0 ACST}
+    {3463317000 37800 1 ACDT}
+    {3479646600 34200 0 ACST}
+    {3495371400 37800 1 ACDT}
+    {3511096200 34200 0 ACST}
+    {3526821000 37800 1 ACDT}
+    {3542545800 34200 0 ACST}
+    {3558270600 37800 1 ACDT}
+    {3573995400 34200 0 ACST}
+    {3589720200 37800 1 ACDT}
+    {3605445000 34200 0 ACST}
+    {3621169800 37800 1 ACDT}
+    {3636894600 34200 0 ACST}
+    {3653224200 37800 1 ACDT}
+    {3668949000 34200 0 ACST}
+    {3684673800 37800 1 ACDT}
+    {3700398600 34200 0 ACST}
+    {3716123400 37800 1 ACDT}
+    {3731848200 34200 0 ACST}
+    {3747573000 37800 1 ACDT}
+    {3763297800 34200 0 ACST}
+    {3779022600 37800 1 ACDT}
+    {3794747400 34200 0 ACST}
+    {3810472200 37800 1 ACDT}
+    {3826197000 34200 0 ACST}
+    {3842526600 37800 1 ACDT}
+    {3858251400 34200 0 ACST}
+    {3873976200 37800 1 ACDT}
+    {3889701000 34200 0 ACST}
+    {3905425800 37800 1 ACDT}
+    {3921150600 34200 0 ACST}
+    {3936875400 37800 1 ACDT}
+    {3952600200 34200 0 ACST}
+    {3968325000 37800 1 ACDT}
+    {3984049800 34200 0 ACST}
+    {4000379400 37800 1 ACDT}
+    {4016104200 34200 0 ACST}
+    {4031829000 37800 1 ACDT}
+    {4047553800 34200 0 ACST}
+    {4063278600 37800 1 ACDT}
+    {4079003400 34200 0 ACST}
+    {4094728200 37800 1 ACDT}
+}
diff --git a/library/tzdata/Australia/Brisbane b/library/tzdata/Australia/Brisbane
new file mode 100644
index 0000000..8422ae6
--- /dev/null
+++ b/library/tzdata/Australia/Brisbane
@@ -0,0 +1,23 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Australia/Brisbane) {
+    {-9223372036854775808 36728 0 LMT}
+    {-2366791928 36000 0 AEST}
+    {-1672567140 39600 1 AEDT}
+    {-1665392400 36000 0 AEST}
+    {-883641600 39600 1 AEDT}
+    {-876128400 36000 0 AEST}
+    {-860400000 39600 1 AEDT}
+    {-844678800 36000 0 AEST}
+    {-828345600 39600 1 AEDT}
+    {-813229200 36000 0 AEST}
+    {31500000 36000 0 AEST}
+    {57686400 39600 1 AEDT}
+    {67968000 36000 0 AEST}
+    {625593600 39600 1 AEDT}
+    {636480000 36000 0 AEST}
+    {657043200 39600 1 AEDT}
+    {667929600 36000 0 AEST}
+    {688492800 39600 1 AEDT}
+    {699379200 36000 0 AEST}
+}
diff --git a/library/tzdata/Australia/Broken_Hill b/library/tzdata/Australia/Broken_Hill
new file mode 100644
index 0000000..c428061
--- /dev/null
+++ b/library/tzdata/Australia/Broken_Hill
@@ -0,0 +1,275 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Australia/Broken_Hill) {
+    {-9223372036854775808 33948 0 LMT}
+    {-2364110748 36000 0 AEST}
+    {-2314951200 32400 0 ACST}
+    {-2230189200 34200 0 ACST}
+    {-1672565340 37800 1 ACDT}
+    {-1665390600 34200 0 ACST}
+    {-883639800 37800 1 ACDT}
+    {-876126600 34200 0 ACST}
+    {-860398200 37800 1 ACDT}
+    {-844677000 34200 0 ACST}
+    {-828343800 37800 1 ACDT}
+    {-813227400 34200 0 ACST}
+    {31501800 34200 0 ACST}
+    {57688200 37800 1 ACDT}
+    {67969800 34200 0 ACST}
+    {89137800 37800 1 ACDT}
+    {100024200 34200 0 ACST}
+    {120587400 37800 1 ACDT}
+    {131473800 34200 0 ACST}
+    {152037000 37800 1 ACDT}
+    {162923400 34200 0 ACST}
+    {183486600 37800 1 ACDT}
+    {194977800 34200 0 ACST}
+    {215541000 37800 1 ACDT}
+    {226427400 34200 0 ACST}
+    {246990600 37800 1 ACDT}
+    {257877000 34200 0 ACST}
+    {278440200 37800 1 ACDT}
+    {289326600 34200 0 ACST}
+    {309889800 37800 1 ACDT}
+    {320776200 34200 0 ACST}
+    {341339400 37800 1 ACDT}
+    {352225800 34200 0 ACST}
+    {372789000 37800 1 ACDT}
+    {386699400 34200 0 ACST}
+    {404843400 37800 1 ACDT}
+    {415729800 34200 0 ACST}
+    {436293000 37800 1 ACDT}
+    {447179400 34200 0 ACST}
+    {467742600 37800 1 ACDT}
+    {478629000 34200 0 ACST}
+    {499192200 37800 1 ACDT}
+    {511288200 34200 0 ACST}
+    {530037000 37800 1 ACDT}
+    {542737800 34200 0 ACST}
+    {562091400 37800 1 ACDT}
+    {574792200 34200 0 ACST}
+    {594145800 37800 1 ACDT}
+    {606241800 34200 0 ACST}
+    {625595400 37800 1 ACDT}
+    {636481800 34200 0 ACST}
+    {657045000 37800 1 ACDT}
+    {667931400 34200 0 ACST}
+    {688494600 37800 1 ACDT}
+    {699381000 34200 0 ACST}
+    {719944200 37800 1 ACDT}
+    {731435400 34200 0 ACST}
+    {751998600 37800 1 ACDT}
+    {762885000 34200 0 ACST}
+    {783448200 37800 1 ACDT}
+    {794334600 34200 0 ACST}
+    {814897800 37800 1 ACDT}
+    {828203400 34200 0 ACST}
+    {846347400 37800 1 ACDT}
+    {859653000 34200 0 ACST}
+    {877797000 37800 1 ACDT}
+    {891102600 34200 0 ACST}
+    {909246600 37800 1 ACDT}
+    {922552200 34200 0 ACST}
+    {941301000 37800 1 ACDT}
+    {946647000 37800 0 ACST}
+    {954001800 34200 0 ACST}
+    {972750600 37800 1 ACDT}
+    {985451400 34200 0 ACST}
+    {1004200200 37800 1 ACDT}
+    {1017505800 34200 0 ACST}
+    {1035649800 37800 1 ACDT}
+    {1048955400 34200 0 ACST}
+    {1067099400 37800 1 ACDT}
+    {1080405000 34200 0 ACST}
+    {1099153800 37800 1 ACDT}
+    {1111854600 34200 0 ACST}
+    {1130603400 37800 1 ACDT}
+    {1143909000 34200 0 ACST}
+    {1162053000 37800 1 ACDT}
+    {1174753800 34200 0 ACST}
+    {1193502600 37800 1 ACDT}
+    {1207413000 34200 0 ACST}
+    {1223137800 37800 1 ACDT}
+    {1238862600 34200 0 ACST}
+    {1254587400 37800 1 ACDT}
+    {1270312200 34200 0 ACST}
+    {1286037000 37800 1 ACDT}
+    {1301761800 34200 0 ACST}
+    {1317486600 37800 1 ACDT}
+    {1333211400 34200 0 ACST}
+    {1349541000 37800 1 ACDT}
+    {1365265800 34200 0 ACST}
+    {1380990600 37800 1 ACDT}
+    {1396715400 34200 0 ACST}
+    {1412440200 37800 1 ACDT}
+    {1428165000 34200 0 ACST}
+    {1443889800 37800 1 ACDT}
+    {1459614600 34200 0 ACST}
+    {1475339400 37800 1 ACDT}
+    {1491064200 34200 0 ACST}
+    {1506789000 37800 1 ACDT}
+    {1522513800 34200 0 ACST}
+    {1538843400 37800 1 ACDT}
+    {1554568200 34200 0 ACST}
+    {1570293000 37800 1 ACDT}
+    {1586017800 34200 0 ACST}
+    {1601742600 37800 1 ACDT}
+    {1617467400 34200 0 ACST}
+    {1633192200 37800 1 ACDT}
+    {1648917000 34200 0 ACST}
+    {1664641800 37800 1 ACDT}
+    {1680366600 34200 0 ACST}
+    {1696091400 37800 1 ACDT}
+    {1712421000 34200 0 ACST}
+    {1728145800 37800 1 ACDT}
+    {1743870600 34200 0 ACST}
+    {1759595400 37800 1 ACDT}
+    {1775320200 34200 0 ACST}
+    {1791045000 37800 1 ACDT}
+    {1806769800 34200 0 ACST}
+    {1822494600 37800 1 ACDT}
+    {1838219400 34200 0 ACST}
+    {1853944200 37800 1 ACDT}
+    {1869669000 34200 0 ACST}
+    {1885998600 37800 1 ACDT}
+    {1901723400 34200 0 ACST}
+    {1917448200 37800 1 ACDT}
+    {1933173000 34200 0 ACST}
+    {1948897800 37800 1 ACDT}
+    {1964622600 34200 0 ACST}
+    {1980347400 37800 1 ACDT}
+    {1996072200 34200 0 ACST}
+    {2011797000 37800 1 ACDT}
+    {2027521800 34200 0 ACST}
+    {2043246600 37800 1 ACDT}
+    {2058971400 34200 0 ACST}
+    {2075301000 37800 1 ACDT}
+    {2091025800 34200 0 ACST}
+    {2106750600 37800 1 ACDT}
+    {2122475400 34200 0 ACST}
+    {2138200200 37800 1 ACDT}
+    {2153925000 34200 0 ACST}
+    {2169649800 37800 1 ACDT}
+    {2185374600 34200 0 ACST}
+    {2201099400 37800 1 ACDT}
+    {2216824200 34200 0 ACST}
+    {2233153800 37800 1 ACDT}
+    {2248878600 34200 0 ACST}
+    {2264603400 37800 1 ACDT}
+    {2280328200 34200 0 ACST}
+    {2296053000 37800 1 ACDT}
+    {2311777800 34200 0 ACST}
+    {2327502600 37800 1 ACDT}
+    {2343227400 34200 0 ACST}
+    {2358952200 37800 1 ACDT}
+    {2374677000 34200 0 ACST}
+    {2390401800 37800 1 ACDT}
+    {2406126600 34200 0 ACST}
+    {2422456200 37800 1 ACDT}
+    {2438181000 34200 0 ACST}
+    {2453905800 37800 1 ACDT}
+    {2469630600 34200 0 ACST}
+    {2485355400 37800 1 ACDT}
+    {2501080200 34200 0 ACST}
+    {2516805000 37800 1 ACDT}
+    {2532529800 34200 0 ACST}
+    {2548254600 37800 1 ACDT}
+    {2563979400 34200 0 ACST}
+    {2579704200 37800 1 ACDT}
+    {2596033800 34200 0 ACST}
+    {2611758600 37800 1 ACDT}
+    {2627483400 34200 0 ACST}
+    {2643208200 37800 1 ACDT}
+    {2658933000 34200 0 ACST}
+    {2674657800 37800 1 ACDT}
+    {2690382600 34200 0 ACST}
+    {2706107400 37800 1 ACDT}
+    {2721832200 34200 0 ACST}
+    {2737557000 37800 1 ACDT}
+    {2753281800 34200 0 ACST}
+    {2769611400 37800 1 ACDT}
+    {2785336200 34200 0 ACST}
+    {2801061000 37800 1 ACDT}
+    {2816785800 34200 0 ACST}
+    {2832510600 37800 1 ACDT}
+    {2848235400 34200 0 ACST}
+    {2863960200 37800 1 ACDT}
+    {2879685000 34200 0 ACST}
+    {2895409800 37800 1 ACDT}
+    {2911134600 34200 0 ACST}
+    {2926859400 37800 1 ACDT}
+    {2942584200 34200 0 ACST}
+    {2958913800 37800 1 ACDT}
+    {2974638600 34200 0 ACST}
+    {2990363400 37800 1 ACDT}
+    {3006088200 34200 0 ACST}
+    {3021813000 37800 1 ACDT}
+    {3037537800 34200 0 ACST}
+    {3053262600 37800 1 ACDT}
+    {3068987400 34200 0 ACST}
+    {3084712200 37800 1 ACDT}
+    {3100437000 34200 0 ACST}
+    {3116766600 37800 1 ACDT}
+    {3132491400 34200 0 ACST}
+    {3148216200 37800 1 ACDT}
+    {3163941000 34200 0 ACST}
+    {3179665800 37800 1 ACDT}
+    {3195390600 34200 0 ACST}
+    {3211115400 37800 1 ACDT}
+    {3226840200 34200 0 ACST}
+    {3242565000 37800 1 ACDT}
+    {3258289800 34200 0 ACST}
+    {3274014600 37800 1 ACDT}
+    {3289739400 34200 0 ACST}
+    {3306069000 37800 1 ACDT}
+    {3321793800 34200 0 ACST}
+    {3337518600 37800 1 ACDT}
+    {3353243400 34200 0 ACST}
+    {3368968200 37800 1 ACDT}
+    {3384693000 34200 0 ACST}
+    {3400417800 37800 1 ACDT}
+    {3416142600 34200 0 ACST}
+    {3431867400 37800 1 ACDT}
+    {3447592200 34200 0 ACST}
+    {3463317000 37800 1 ACDT}
+    {3479646600 34200 0 ACST}
+    {3495371400 37800 1 ACDT}
+    {3511096200 34200 0 ACST}
+    {3526821000 37800 1 ACDT}
+    {3542545800 34200 0 ACST}
+    {3558270600 37800 1 ACDT}
+    {3573995400 34200 0 ACST}
+    {3589720200 37800 1 ACDT}
+    {3605445000 34200 0 ACST}
+    {3621169800 37800 1 ACDT}
+    {3636894600 34200 0 ACST}
+    {3653224200 37800 1 ACDT}
+    {3668949000 34200 0 ACST}
+    {3684673800 37800 1 ACDT}
+    {3700398600 34200 0 ACST}
+    {3716123400 37800 1 ACDT}
+    {3731848200 34200 0 ACST}
+    {3747573000 37800 1 ACDT}
+    {3763297800 34200 0 ACST}
+    {3779022600 37800 1 ACDT}
+    {3794747400 34200 0 ACST}
+    {3810472200 37800 1 ACDT}
+    {3826197000 34200 0 ACST}
+    {3842526600 37800 1 ACDT}
+    {3858251400 34200 0 ACST}
+    {3873976200 37800 1 ACDT}
+    {3889701000 34200 0 ACST}
+    {3905425800 37800 1 ACDT}
+    {3921150600 34200 0 ACST}
+    {3936875400 37800 1 ACDT}
+    {3952600200 34200 0 ACST}
+    {3968325000 37800 1 ACDT}
+    {3984049800 34200 0 ACST}
+    {4000379400 37800 1 ACDT}
+    {4016104200 34200 0 ACST}
+    {4031829000 37800 1 ACDT}
+    {4047553800 34200 0 ACST}
+    {4063278600 37800 1 ACDT}
+    {4079003400 34200 0 ACST}
+    {4094728200 37800 1 ACDT}
+}
diff --git a/library/tzdata/Australia/Canberra b/library/tzdata/Australia/Canberra
new file mode 100644
index 0000000..0b7b9ca
--- /dev/null
+++ b/library/tzdata/Australia/Canberra
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Australia/Sydney)]} {
+    LoadTimeZoneFile Australia/Sydney
+}
+set TZData(:Australia/Canberra) $TZData(:Australia/Sydney)
diff --git a/library/tzdata/Australia/Currie b/library/tzdata/Australia/Currie
new file mode 100644
index 0000000..936327b
--- /dev/null
+++ b/library/tzdata/Australia/Currie
@@ -0,0 +1,273 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Australia/Currie) {
+    {-9223372036854775808 34528 0 LMT}
+    {-2345794528 36000 0 AEST}
+    {-1680508800 39600 1 AEDT}
+    {-1669892400 39600 0 AEDT}
+    {-1665392400 36000 0 AEST}
+    {-883641600 39600 1 AEDT}
+    {-876128400 36000 0 AEST}
+    {-860400000 39600 1 AEDT}
+    {-844678800 36000 0 AEST}
+    {-828345600 39600 1 AEDT}
+    {-813229200 36000 0 AEST}
+    {47138400 36000 0 AEST}
+    {57686400 39600 1 AEDT}
+    {67968000 36000 0 AEST}
+    {89136000 39600 1 AEDT}
+    {100022400 36000 0 AEST}
+    {120585600 39600 1 AEDT}
+    {131472000 36000 0 AEST}
+    {152035200 39600 1 AEDT}
+    {162921600 36000 0 AEST}
+    {183484800 39600 1 AEDT}
+    {194976000 36000 0 AEST}
+    {215539200 39600 1 AEDT}
+    {226425600 36000 0 AEST}
+    {246988800 39600 1 AEDT}
+    {257875200 36000 0 AEST}
+    {278438400 39600 1 AEDT}
+    {289324800 36000 0 AEST}
+    {309888000 39600 1 AEDT}
+    {320774400 36000 0 AEST}
+    {341337600 39600 1 AEDT}
+    {352224000 36000 0 AEST}
+    {372787200 39600 1 AEDT}
+    {386092800 36000 0 AEST}
+    {404841600 39600 1 AEDT}
+    {417542400 36000 0 AEST}
+    {436291200 39600 1 AEDT}
+    {447177600 36000 0 AEST}
+    {467740800 39600 1 AEDT}
+    {478627200 36000 0 AEST}
+    {499190400 39600 1 AEDT}
+    {510076800 36000 0 AEST}
+    {530035200 39600 1 AEDT}
+    {542736000 36000 0 AEST}
+    {562089600 39600 1 AEDT}
+    {574790400 36000 0 AEST}
+    {594144000 39600 1 AEDT}
+    {606240000 36000 0 AEST}
+    {625593600 39600 1 AEDT}
+    {637689600 36000 0 AEST}
+    {657043200 39600 1 AEDT}
+    {670348800 36000 0 AEST}
+    {686678400 39600 1 AEDT}
+    {701798400 36000 0 AEST}
+    {718128000 39600 1 AEDT}
+    {733248000 36000 0 AEST}
+    {749577600 39600 1 AEDT}
+    {764697600 36000 0 AEST}
+    {781027200 39600 1 AEDT}
+    {796147200 36000 0 AEST}
+    {812476800 39600 1 AEDT}
+    {828201600 36000 0 AEST}
+    {844531200 39600 1 AEDT}
+    {859651200 36000 0 AEST}
+    {875980800 39600 1 AEDT}
+    {891100800 36000 0 AEST}
+    {907430400 39600 1 AEDT}
+    {922550400 36000 0 AEST}
+    {938880000 39600 1 AEDT}
+    {954000000 36000 0 AEST}
+    {967305600 39600 1 AEDT}
+    {985449600 36000 0 AEST}
+    {1002384000 39600 1 AEDT}
+    {1017504000 36000 0 AEST}
+    {1033833600 39600 1 AEDT}
+    {1048953600 36000 0 AEST}
+    {1065283200 39600 1 AEDT}
+    {1080403200 36000 0 AEST}
+    {1096732800 39600 1 AEDT}
+    {1111852800 36000 0 AEST}
+    {1128182400 39600 1 AEDT}
+    {1143907200 36000 0 AEST}
+    {1159632000 39600 1 AEDT}
+    {1174752000 36000 0 AEST}
+    {1191686400 39600 1 AEDT}
+    {1207411200 36000 0 AEST}
+    {1223136000 39600 1 AEDT}
+    {1238860800 36000 0 AEST}
+    {1254585600 39600 1 AEDT}
+    {1270310400 36000 0 AEST}
+    {1286035200 39600 1 AEDT}
+    {1301760000 36000 0 AEST}
+    {1317484800 39600 1 AEDT}
+    {1333209600 36000 0 AEST}
+    {1349539200 39600 1 AEDT}
+    {1365264000 36000 0 AEST}
+    {1380988800 39600 1 AEDT}
+    {1396713600 36000 0 AEST}
+    {1412438400 39600 1 AEDT}
+    {1428163200 36000 0 AEST}
+    {1443888000 39600 1 AEDT}
+    {1459612800 36000 0 AEST}
+    {1475337600 39600 1 AEDT}
+    {1491062400 36000 0 AEST}
+    {1506787200 39600 1 AEDT}
+    {1522512000 36000 0 AEST}
+    {1538841600 39600 1 AEDT}
+    {1554566400 36000 0 AEST}
+    {1570291200 39600 1 AEDT}
+    {1586016000 36000 0 AEST}
+    {1601740800 39600 1 AEDT}
+    {1617465600 36000 0 AEST}
+    {1633190400 39600 1 AEDT}
+    {1648915200 36000 0 AEST}
+    {1664640000 39600 1 AEDT}
+    {1680364800 36000 0 AEST}
+    {1696089600 39600 1 AEDT}
+    {1712419200 36000 0 AEST}
+    {1728144000 39600 1 AEDT}
+    {1743868800 36000 0 AEST}
+    {1759593600 39600 1 AEDT}
+    {1775318400 36000 0 AEST}
+    {1791043200 39600 1 AEDT}
+    {1806768000 36000 0 AEST}
+    {1822492800 39600 1 AEDT}
+    {1838217600 36000 0 AEST}
+    {1853942400 39600 1 AEDT}
+    {1869667200 36000 0 AEST}
+    {1885996800 39600 1 AEDT}
+    {1901721600 36000 0 AEST}
+    {1917446400 39600 1 AEDT}
+    {1933171200 36000 0 AEST}
+    {1948896000 39600 1 AEDT}
+    {1964620800 36000 0 AEST}
+    {1980345600 39600 1 AEDT}
+    {1996070400 36000 0 AEST}
+    {2011795200 39600 1 AEDT}
+    {2027520000 36000 0 AEST}
+    {2043244800 39600 1 AEDT}
+    {2058969600 36000 0 AEST}
+    {2075299200 39600 1 AEDT}
+    {2091024000 36000 0 AEST}
+    {2106748800 39600 1 AEDT}
+    {2122473600 36000 0 AEST}
+    {2138198400 39600 1 AEDT}
+    {2153923200 36000 0 AEST}
+    {2169648000 39600 1 AEDT}
+    {2185372800 36000 0 AEST}
+    {2201097600 39600 1 AEDT}
+    {2216822400 36000 0 AEST}
+    {2233152000 39600 1 AEDT}
+    {2248876800 36000 0 AEST}
+    {2264601600 39600 1 AEDT}
+    {2280326400 36000 0 AEST}
+    {2296051200 39600 1 AEDT}
+    {2311776000 36000 0 AEST}
+    {2327500800 39600 1 AEDT}
+    {2343225600 36000 0 AEST}
+    {2358950400 39600 1 AEDT}
+    {2374675200 36000 0 AEST}
+    {2390400000 39600 1 AEDT}
+    {2406124800 36000 0 AEST}
+    {2422454400 39600 1 AEDT}
+    {2438179200 36000 0 AEST}
+    {2453904000 39600 1 AEDT}
+    {2469628800 36000 0 AEST}
+    {2485353600 39600 1 AEDT}
+    {2501078400 36000 0 AEST}
+    {2516803200 39600 1 AEDT}
+    {2532528000 36000 0 AEST}
+    {2548252800 39600 1 AEDT}
+    {2563977600 36000 0 AEST}
+    {2579702400 39600 1 AEDT}
+    {2596032000 36000 0 AEST}
+    {2611756800 39600 1 AEDT}
+    {2627481600 36000 0 AEST}
+    {2643206400 39600 1 AEDT}
+    {2658931200 36000 0 AEST}
+    {2674656000 39600 1 AEDT}
+    {2690380800 36000 0 AEST}
+    {2706105600 39600 1 AEDT}
+    {2721830400 36000 0 AEST}
+    {2737555200 39600 1 AEDT}
+    {2753280000 36000 0 AEST}
+    {2769609600 39600 1 AEDT}
+    {2785334400 36000 0 AEST}
+    {2801059200 39600 1 AEDT}
+    {2816784000 36000 0 AEST}
+    {2832508800 39600 1 AEDT}
+    {2848233600 36000 0 AEST}
+    {2863958400 39600 1 AEDT}
+    {2879683200 36000 0 AEST}
+    {2895408000 39600 1 AEDT}
+    {2911132800 36000 0 AEST}
+    {2926857600 39600 1 AEDT}
+    {2942582400 36000 0 AEST}
+    {2958912000 39600 1 AEDT}
+    {2974636800 36000 0 AEST}
+    {2990361600 39600 1 AEDT}
+    {3006086400 36000 0 AEST}
+    {3021811200 39600 1 AEDT}
+    {3037536000 36000 0 AEST}
+    {3053260800 39600 1 AEDT}
+    {3068985600 36000 0 AEST}
+    {3084710400 39600 1 AEDT}
+    {3100435200 36000 0 AEST}
+    {3116764800 39600 1 AEDT}
+    {3132489600 36000 0 AEST}
+    {3148214400 39600 1 AEDT}
+    {3163939200 36000 0 AEST}
+    {3179664000 39600 1 AEDT}
+    {3195388800 36000 0 AEST}
+    {3211113600 39600 1 AEDT}
+    {3226838400 36000 0 AEST}
+    {3242563200 39600 1 AEDT}
+    {3258288000 36000 0 AEST}
+    {3274012800 39600 1 AEDT}
+    {3289737600 36000 0 AEST}
+    {3306067200 39600 1 AEDT}
+    {3321792000 36000 0 AEST}
+    {3337516800 39600 1 AEDT}
+    {3353241600 36000 0 AEST}
+    {3368966400 39600 1 AEDT}
+    {3384691200 36000 0 AEST}
+    {3400416000 39600 1 AEDT}
+    {3416140800 36000 0 AEST}
+    {3431865600 39600 1 AEDT}
+    {3447590400 36000 0 AEST}
+    {3463315200 39600 1 AEDT}
+    {3479644800 36000 0 AEST}
+    {3495369600 39600 1 AEDT}
+    {3511094400 36000 0 AEST}
+    {3526819200 39600 1 AEDT}
+    {3542544000 36000 0 AEST}
+    {3558268800 39600 1 AEDT}
+    {3573993600 36000 0 AEST}
+    {3589718400 39600 1 AEDT}
+    {3605443200 36000 0 AEST}
+    {3621168000 39600 1 AEDT}
+    {3636892800 36000 0 AEST}
+    {3653222400 39600 1 AEDT}
+    {3668947200 36000 0 AEST}
+    {3684672000 39600 1 AEDT}
+    {3700396800 36000 0 AEST}
+    {3716121600 39600 1 AEDT}
+    {3731846400 36000 0 AEST}
+    {3747571200 39600 1 AEDT}
+    {3763296000 36000 0 AEST}
+    {3779020800 39600 1 AEDT}
+    {3794745600 36000 0 AEST}
+    {3810470400 39600 1 AEDT}
+    {3826195200 36000 0 AEST}
+    {3842524800 39600 1 AEDT}
+    {3858249600 36000 0 AEST}
+    {3873974400 39600 1 AEDT}
+    {3889699200 36000 0 AEST}
+    {3905424000 39600 1 AEDT}
+    {3921148800 36000 0 AEST}
+    {3936873600 39600 1 AEDT}
+    {3952598400 36000 0 AEST}
+    {3968323200 39600 1 AEDT}
+    {3984048000 36000 0 AEST}
+    {4000377600 39600 1 AEDT}
+    {4016102400 36000 0 AEST}
+    {4031827200 39600 1 AEDT}
+    {4047552000 36000 0 AEST}
+    {4063276800 39600 1 AEDT}
+    {4079001600 36000 0 AEST}
+    {4094726400 39600 1 AEDT}
+}
diff --git a/library/tzdata/Australia/Darwin b/library/tzdata/Australia/Darwin
new file mode 100644
index 0000000..e77605d
--- /dev/null
+++ b/library/tzdata/Australia/Darwin
@@ -0,0 +1,15 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Australia/Darwin) {
+    {-9223372036854775808 31400 0 LMT}
+    {-2364108200 32400 0 ACST}
+    {-2230189200 34200 0 ACST}
+    {-1672565340 37800 1 ACDT}
+    {-1665390600 34200 0 ACST}
+    {-883639800 37800 1 ACDT}
+    {-876126600 34200 0 ACST}
+    {-860398200 37800 1 ACDT}
+    {-844677000 34200 0 ACST}
+    {-828343800 37800 1 ACDT}
+    {-813227400 34200 0 ACST}
+}
diff --git a/library/tzdata/Australia/Eucla b/library/tzdata/Australia/Eucla
new file mode 100644
index 0000000..08a1948
--- /dev/null
+++ b/library/tzdata/Australia/Eucla
@@ -0,0 +1,25 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Australia/Eucla) {
+    {-9223372036854775808 30928 0 LMT}
+    {-2337928528 31500 0 ACWST}
+    {-1672562640 35100 1 ACWDT}
+    {-1665387900 31500 0 ACWST}
+    {-883637100 35100 1 ACWDT}
+    {-876123900 31500 0 ACWST}
+    {-860395500 35100 1 ACWDT}
+    {-844674300 31500 0 ACWST}
+    {-836473500 35100 0 ACWST}
+    {152039700 35100 1 ACWDT}
+    {162926100 31500 0 ACWST}
+    {436295700 35100 1 ACWDT}
+    {447182100 31500 0 ACWST}
+    {690311700 35100 1 ACWDT}
+    {699383700 31500 0 ACWST}
+    {1165079700 35100 1 ACWDT}
+    {1174756500 31500 0 ACWST}
+    {1193505300 35100 1 ACWDT}
+    {1206810900 31500 0 ACWST}
+    {1224954900 35100 1 ACWDT}
+    {1238260500 31500 0 ACWST}
+}
diff --git a/library/tzdata/Australia/Hobart b/library/tzdata/Australia/Hobart
new file mode 100644
index 0000000..bf5adf0
--- /dev/null
+++ b/library/tzdata/Australia/Hobart
@@ -0,0 +1,281 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Australia/Hobart) {
+    {-9223372036854775808 35356 0 LMT}
+    {-2345795356 36000 0 AEST}
+    {-1680508800 39600 1 AEDT}
+    {-1669892400 39600 0 AEDT}
+    {-1665392400 36000 0 AEST}
+    {-883641600 39600 1 AEDT}
+    {-876128400 36000 0 AEST}
+    {-860400000 39600 1 AEDT}
+    {-844678800 36000 0 AEST}
+    {-828345600 39600 1 AEDT}
+    {-813229200 36000 0 AEST}
+    {-94730400 36000 0 AEST}
+    {-71136000 39600 1 AEDT}
+    {-55411200 36000 0 AEST}
+    {-37267200 39600 1 AEDT}
+    {-25776000 36000 0 AEST}
+    {-5817600 39600 1 AEDT}
+    {5673600 36000 0 AEST}
+    {25632000 39600 1 AEDT}
+    {37728000 36000 0 AEST}
+    {57686400 39600 1 AEDT}
+    {67968000 36000 0 AEST}
+    {89136000 39600 1 AEDT}
+    {100022400 36000 0 AEST}
+    {120585600 39600 1 AEDT}
+    {131472000 36000 0 AEST}
+    {152035200 39600 1 AEDT}
+    {162921600 36000 0 AEST}
+    {183484800 39600 1 AEDT}
+    {194976000 36000 0 AEST}
+    {215539200 39600 1 AEDT}
+    {226425600 36000 0 AEST}
+    {246988800 39600 1 AEDT}
+    {257875200 36000 0 AEST}
+    {278438400 39600 1 AEDT}
+    {289324800 36000 0 AEST}
+    {309888000 39600 1 AEDT}
+    {320774400 36000 0 AEST}
+    {341337600 39600 1 AEDT}
+    {352224000 36000 0 AEST}
+    {372787200 39600 1 AEDT}
+    {386092800 36000 0 AEST}
+    {404841600 39600 1 AEDT}
+    {417542400 36000 0 AEST}
+    {436291200 39600 1 AEDT}
+    {447177600 36000 0 AEST}
+    {467740800 39600 1 AEDT}
+    {478627200 36000 0 AEST}
+    {499190400 39600 1 AEDT}
+    {510076800 36000 0 AEST}
+    {530035200 39600 1 AEDT}
+    {542736000 36000 0 AEST}
+    {562089600 39600 1 AEDT}
+    {574790400 36000 0 AEST}
+    {594144000 39600 1 AEDT}
+    {606240000 36000 0 AEST}
+    {625593600 39600 1 AEDT}
+    {637689600 36000 0 AEST}
+    {657043200 39600 1 AEDT}
+    {670348800 36000 0 AEST}
+    {686678400 39600 1 AEDT}
+    {701798400 36000 0 AEST}
+    {718128000 39600 1 AEDT}
+    {733248000 36000 0 AEST}
+    {749577600 39600 1 AEDT}
+    {764697600 36000 0 AEST}
+    {781027200 39600 1 AEDT}
+    {796147200 36000 0 AEST}
+    {812476800 39600 1 AEDT}
+    {828201600 36000 0 AEST}
+    {844531200 39600 1 AEDT}
+    {859651200 36000 0 AEST}
+    {875980800 39600 1 AEDT}
+    {891100800 36000 0 AEST}
+    {907430400 39600 1 AEDT}
+    {922550400 36000 0 AEST}
+    {938880000 39600 1 AEDT}
+    {954000000 36000 0 AEST}
+    {967305600 39600 1 AEDT}
+    {985449600 36000 0 AEST}
+    {1002384000 39600 1 AEDT}
+    {1017504000 36000 0 AEST}
+    {1033833600 39600 1 AEDT}
+    {1048953600 36000 0 AEST}
+    {1065283200 39600 1 AEDT}
+    {1080403200 36000 0 AEST}
+    {1096732800 39600 1 AEDT}
+    {1111852800 36000 0 AEST}
+    {1128182400 39600 1 AEDT}
+    {1143907200 36000 0 AEST}
+    {1159632000 39600 1 AEDT}
+    {1174752000 36000 0 AEST}
+    {1191686400 39600 1 AEDT}
+    {1207411200 36000 0 AEST}
+    {1223136000 39600 1 AEDT}
+    {1238860800 36000 0 AEST}
+    {1254585600 39600 1 AEDT}
+    {1270310400 36000 0 AEST}
+    {1286035200 39600 1 AEDT}
+    {1301760000 36000 0 AEST}
+    {1317484800 39600 1 AEDT}
+    {1333209600 36000 0 AEST}
+    {1349539200 39600 1 AEDT}
+    {1365264000 36000 0 AEST}
+    {1380988800 39600 1 AEDT}
+    {1396713600 36000 0 AEST}
+    {1412438400 39600 1 AEDT}
+    {1428163200 36000 0 AEST}
+    {1443888000 39600 1 AEDT}
+    {1459612800 36000 0 AEST}
+    {1475337600 39600 1 AEDT}
+    {1491062400 36000 0 AEST}
+    {1506787200 39600 1 AEDT}
+    {1522512000 36000 0 AEST}
+    {1538841600 39600 1 AEDT}
+    {1554566400 36000 0 AEST}
+    {1570291200 39600 1 AEDT}
+    {1586016000 36000 0 AEST}
+    {1601740800 39600 1 AEDT}
+    {1617465600 36000 0 AEST}
+    {1633190400 39600 1 AEDT}
+    {1648915200 36000 0 AEST}
+    {1664640000 39600 1 AEDT}
+    {1680364800 36000 0 AEST}
+    {1696089600 39600 1 AEDT}
+    {1712419200 36000 0 AEST}
+    {1728144000 39600 1 AEDT}
+    {1743868800 36000 0 AEST}
+    {1759593600 39600 1 AEDT}
+    {1775318400 36000 0 AEST}
+    {1791043200 39600 1 AEDT}
+    {1806768000 36000 0 AEST}
+    {1822492800 39600 1 AEDT}
+    {1838217600 36000 0 AEST}
+    {1853942400 39600 1 AEDT}
+    {1869667200 36000 0 AEST}
+    {1885996800 39600 1 AEDT}
+    {1901721600 36000 0 AEST}
+    {1917446400 39600 1 AEDT}
+    {1933171200 36000 0 AEST}
+    {1948896000 39600 1 AEDT}
+    {1964620800 36000 0 AEST}
+    {1980345600 39600 1 AEDT}
+    {1996070400 36000 0 AEST}
+    {2011795200 39600 1 AEDT}
+    {2027520000 36000 0 AEST}
+    {2043244800 39600 1 AEDT}
+    {2058969600 36000 0 AEST}
+    {2075299200 39600 1 AEDT}
+    {2091024000 36000 0 AEST}
+    {2106748800 39600 1 AEDT}
+    {2122473600 36000 0 AEST}
+    {2138198400 39600 1 AEDT}
+    {2153923200 36000 0 AEST}
+    {2169648000 39600 1 AEDT}
+    {2185372800 36000 0 AEST}
+    {2201097600 39600 1 AEDT}
+    {2216822400 36000 0 AEST}
+    {2233152000 39600 1 AEDT}
+    {2248876800 36000 0 AEST}
+    {2264601600 39600 1 AEDT}
+    {2280326400 36000 0 AEST}
+    {2296051200 39600 1 AEDT}
+    {2311776000 36000 0 AEST}
+    {2327500800 39600 1 AEDT}
+    {2343225600 36000 0 AEST}
+    {2358950400 39600 1 AEDT}
+    {2374675200 36000 0 AEST}
+    {2390400000 39600 1 AEDT}
+    {2406124800 36000 0 AEST}
+    {2422454400 39600 1 AEDT}
+    {2438179200 36000 0 AEST}
+    {2453904000 39600 1 AEDT}
+    {2469628800 36000 0 AEST}
+    {2485353600 39600 1 AEDT}
+    {2501078400 36000 0 AEST}
+    {2516803200 39600 1 AEDT}
+    {2532528000 36000 0 AEST}
+    {2548252800 39600 1 AEDT}
+    {2563977600 36000 0 AEST}
+    {2579702400 39600 1 AEDT}
+    {2596032000 36000 0 AEST}
+    {2611756800 39600 1 AEDT}
+    {2627481600 36000 0 AEST}
+    {2643206400 39600 1 AEDT}
+    {2658931200 36000 0 AEST}
+    {2674656000 39600 1 AEDT}
+    {2690380800 36000 0 AEST}
+    {2706105600 39600 1 AEDT}
+    {2721830400 36000 0 AEST}
+    {2737555200 39600 1 AEDT}
+    {2753280000 36000 0 AEST}
+    {2769609600 39600 1 AEDT}
+    {2785334400 36000 0 AEST}
+    {2801059200 39600 1 AEDT}
+    {2816784000 36000 0 AEST}
+    {2832508800 39600 1 AEDT}
+    {2848233600 36000 0 AEST}
+    {2863958400 39600 1 AEDT}
+    {2879683200 36000 0 AEST}
+    {2895408000 39600 1 AEDT}
+    {2911132800 36000 0 AEST}
+    {2926857600 39600 1 AEDT}
+    {2942582400 36000 0 AEST}
+    {2958912000 39600 1 AEDT}
+    {2974636800 36000 0 AEST}
+    {2990361600 39600 1 AEDT}
+    {3006086400 36000 0 AEST}
+    {3021811200 39600 1 AEDT}
+    {3037536000 36000 0 AEST}
+    {3053260800 39600 1 AEDT}
+    {3068985600 36000 0 AEST}
+    {3084710400 39600 1 AEDT}
+    {3100435200 36000 0 AEST}
+    {3116764800 39600 1 AEDT}
+    {3132489600 36000 0 AEST}
+    {3148214400 39600 1 AEDT}
+    {3163939200 36000 0 AEST}
+    {3179664000 39600 1 AEDT}
+    {3195388800 36000 0 AEST}
+    {3211113600 39600 1 AEDT}
+    {3226838400 36000 0 AEST}
+    {3242563200 39600 1 AEDT}
+    {3258288000 36000 0 AEST}
+    {3274012800 39600 1 AEDT}
+    {3289737600 36000 0 AEST}
+    {3306067200 39600 1 AEDT}
+    {3321792000 36000 0 AEST}
+    {3337516800 39600 1 AEDT}
+    {3353241600 36000 0 AEST}
+    {3368966400 39600 1 AEDT}
+    {3384691200 36000 0 AEST}
+    {3400416000 39600 1 AEDT}
+    {3416140800 36000 0 AEST}
+    {3431865600 39600 1 AEDT}
+    {3447590400 36000 0 AEST}
+    {3463315200 39600 1 AEDT}
+    {3479644800 36000 0 AEST}
+    {3495369600 39600 1 AEDT}
+    {3511094400 36000 0 AEST}
+    {3526819200 39600 1 AEDT}
+    {3542544000 36000 0 AEST}
+    {3558268800 39600 1 AEDT}
+    {3573993600 36000 0 AEST}
+    {3589718400 39600 1 AEDT}
+    {3605443200 36000 0 AEST}
+    {3621168000 39600 1 AEDT}
+    {3636892800 36000 0 AEST}
+    {3653222400 39600 1 AEDT}
+    {3668947200 36000 0 AEST}
+    {3684672000 39600 1 AEDT}
+    {3700396800 36000 0 AEST}
+    {3716121600 39600 1 AEDT}
+    {3731846400 36000 0 AEST}
+    {3747571200 39600 1 AEDT}
+    {3763296000 36000 0 AEST}
+    {3779020800 39600 1 AEDT}
+    {3794745600 36000 0 AEST}
+    {3810470400 39600 1 AEDT}
+    {3826195200 36000 0 AEST}
+    {3842524800 39600 1 AEDT}
+    {3858249600 36000 0 AEST}
+    {3873974400 39600 1 AEDT}
+    {3889699200 36000 0 AEST}
+    {3905424000 39600 1 AEDT}
+    {3921148800 36000 0 AEST}
+    {3936873600 39600 1 AEDT}
+    {3952598400 36000 0 AEST}
+    {3968323200 39600 1 AEDT}
+    {3984048000 36000 0 AEST}
+    {4000377600 39600 1 AEDT}
+    {4016102400 36000 0 AEST}
+    {4031827200 39600 1 AEDT}
+    {4047552000 36000 0 AEST}
+    {4063276800 39600 1 AEDT}
+    {4079001600 36000 0 AEST}
+    {4094726400 39600 1 AEDT}
+}
diff --git a/library/tzdata/Australia/LHI b/library/tzdata/Australia/LHI
new file mode 100644
index 0000000..ddc79ce
--- /dev/null
+++ b/library/tzdata/Australia/LHI
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Australia/Lord_Howe)]} {
+    LoadTimeZoneFile Australia/Lord_Howe
+}
+set TZData(:Australia/LHI) $TZData(:Australia/Lord_Howe)
diff --git a/library/tzdata/Australia/Lindeman b/library/tzdata/Australia/Lindeman
new file mode 100644
index 0000000..91ad0a6
--- /dev/null
+++ b/library/tzdata/Australia/Lindeman
@@ -0,0 +1,28 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Australia/Lindeman) {
+    {-9223372036854775808 35756 0 LMT}
+    {-2366790956 36000 0 AEST}
+    {-1672567140 39600 1 AEDT}
+    {-1665392400 36000 0 AEST}
+    {-883641600 39600 1 AEDT}
+    {-876128400 36000 0 AEST}
+    {-860400000 39600 1 AEDT}
+    {-844678800 36000 0 AEST}
+    {-828345600 39600 1 AEDT}
+    {-813229200 36000 0 AEST}
+    {31500000 36000 0 AEST}
+    {57686400 39600 1 AEDT}
+    {67968000 36000 0 AEST}
+    {625593600 39600 1 AEDT}
+    {636480000 36000 0 AEST}
+    {657043200 39600 1 AEDT}
+    {667929600 36000 0 AEST}
+    {688492800 39600 1 AEDT}
+    {699379200 36000 0 AEST}
+    {709912800 36000 0 AEST}
+    {719942400 39600 1 AEDT}
+    {731433600 36000 0 AEST}
+    {751996800 39600 1 AEDT}
+    {762883200 36000 0 AEST}
+}
diff --git a/library/tzdata/Australia/Lord_Howe b/library/tzdata/Australia/Lord_Howe
new file mode 100644
index 0000000..a8ff80e
--- /dev/null
+++ b/library/tzdata/Australia/Lord_Howe
@@ -0,0 +1,244 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Australia/Lord_Howe) {
+    {-9223372036854775808 38180 0 LMT}
+    {-2364114980 36000 0 AEST}
+    {352216800 37800 0 LHST}
+    {372785400 41400 1 LHDT}
+    {384273000 37800 0 LHST}
+    {404839800 41400 1 LHDT}
+    {415722600 37800 0 LHST}
+    {436289400 41400 1 LHDT}
+    {447172200 37800 0 LHST}
+    {467739000 41400 1 LHDT}
+    {478621800 37800 0 LHST}
+    {499188600 39600 1 LHDT}
+    {511282800 37800 0 LHST}
+    {530033400 39600 1 LHDT}
+    {542732400 37800 0 LHST}
+    {562087800 39600 1 LHDT}
+    {574786800 37800 0 LHST}
+    {594142200 39600 1 LHDT}
+    {606236400 37800 0 LHST}
+    {625591800 39600 1 LHDT}
+    {636476400 37800 0 LHST}
+    {657041400 39600 1 LHDT}
+    {667926000 37800 0 LHST}
+    {688491000 39600 1 LHDT}
+    {699375600 37800 0 LHST}
+    {719940600 39600 1 LHDT}
+    {731430000 37800 0 LHST}
+    {751995000 39600 1 LHDT}
+    {762879600 37800 0 LHST}
+    {783444600 39600 1 LHDT}
+    {794329200 37800 0 LHST}
+    {814894200 39600 1 LHDT}
+    {828198000 37800 0 LHST}
+    {846343800 39600 1 LHDT}
+    {859647600 37800 0 LHST}
+    {877793400 39600 1 LHDT}
+    {891097200 37800 0 LHST}
+    {909243000 39600 1 LHDT}
+    {922546800 37800 0 LHST}
+    {941297400 39600 1 LHDT}
+    {953996400 37800 0 LHST}
+    {967303800 39600 1 LHDT}
+    {985446000 37800 0 LHST}
+    {1004196600 39600 1 LHDT}
+    {1017500400 37800 0 LHST}
+    {1035646200 39600 1 LHDT}
+    {1048950000 37800 0 LHST}
+    {1067095800 39600 1 LHDT}
+    {1080399600 37800 0 LHST}
+    {1099150200 39600 1 LHDT}
+    {1111849200 37800 0 LHST}
+    {1130599800 39600 1 LHDT}
+    {1143903600 37800 0 LHST}
+    {1162049400 39600 1 LHDT}
+    {1174748400 37800 0 LHST}
+    {1193499000 39600 1 LHDT}
+    {1207407600 37800 0 LHST}
+    {1223134200 39600 1 LHDT}
+    {1238857200 37800 0 LHST}
+    {1254583800 39600 1 LHDT}
+    {1270306800 37800 0 LHST}
+    {1286033400 39600 1 LHDT}
+    {1301756400 37800 0 LHST}
+    {1317483000 39600 1 LHDT}
+    {1333206000 37800 0 LHST}
+    {1349537400 39600 1 LHDT}
+    {1365260400 37800 0 LHST}
+    {1380987000 39600 1 LHDT}
+    {1396710000 37800 0 LHST}
+    {1412436600 39600 1 LHDT}
+    {1428159600 37800 0 LHST}
+    {1443886200 39600 1 LHDT}
+    {1459609200 37800 0 LHST}
+    {1475335800 39600 1 LHDT}
+    {1491058800 37800 0 LHST}
+    {1506785400 39600 1 LHDT}
+    {1522508400 37800 0 LHST}
+    {1538839800 39600 1 LHDT}
+    {1554562800 37800 0 LHST}
+    {1570289400 39600 1 LHDT}
+    {1586012400 37800 0 LHST}
+    {1601739000 39600 1 LHDT}
+    {1617462000 37800 0 LHST}
+    {1633188600 39600 1 LHDT}
+    {1648911600 37800 0 LHST}
+    {1664638200 39600 1 LHDT}
+    {1680361200 37800 0 LHST}
+    {1696087800 39600 1 LHDT}
+    {1712415600 37800 0 LHST}
+    {1728142200 39600 1 LHDT}
+    {1743865200 37800 0 LHST}
+    {1759591800 39600 1 LHDT}
+    {1775314800 37800 0 LHST}
+    {1791041400 39600 1 LHDT}
+    {1806764400 37800 0 LHST}
+    {1822491000 39600 1 LHDT}
+    {1838214000 37800 0 LHST}
+    {1853940600 39600 1 LHDT}
+    {1869663600 37800 0 LHST}
+    {1885995000 39600 1 LHDT}
+    {1901718000 37800 0 LHST}
+    {1917444600 39600 1 LHDT}
+    {1933167600 37800 0 LHST}
+    {1948894200 39600 1 LHDT}
+    {1964617200 37800 0 LHST}
+    {1980343800 39600 1 LHDT}
+    {1996066800 37800 0 LHST}
+    {2011793400 39600 1 LHDT}
+    {2027516400 37800 0 LHST}
+    {2043243000 39600 1 LHDT}
+    {2058966000 37800 0 LHST}
+    {2075297400 39600 1 LHDT}
+    {2091020400 37800 0 LHST}
+    {2106747000 39600 1 LHDT}
+    {2122470000 37800 0 LHST}
+    {2138196600 39600 1 LHDT}
+    {2153919600 37800 0 LHST}
+    {2169646200 39600 1 LHDT}
+    {2185369200 37800 0 LHST}
+    {2201095800 39600 1 LHDT}
+    {2216818800 37800 0 LHST}
+    {2233150200 39600 1 LHDT}
+    {2248873200 37800 0 LHST}
+    {2264599800 39600 1 LHDT}
+    {2280322800 37800 0 LHST}
+    {2296049400 39600 1 LHDT}
+    {2311772400 37800 0 LHST}
+    {2327499000 39600 1 LHDT}
+    {2343222000 37800 0 LHST}
+    {2358948600 39600 1 LHDT}
+    {2374671600 37800 0 LHST}
+    {2390398200 39600 1 LHDT}
+    {2406121200 37800 0 LHST}
+    {2422452600 39600 1 LHDT}
+    {2438175600 37800 0 LHST}
+    {2453902200 39600 1 LHDT}
+    {2469625200 37800 0 LHST}
+    {2485351800 39600 1 LHDT}
+    {2501074800 37800 0 LHST}
+    {2516801400 39600 1 LHDT}
+    {2532524400 37800 0 LHST}
+    {2548251000 39600 1 LHDT}
+    {2563974000 37800 0 LHST}
+    {2579700600 39600 1 LHDT}
+    {2596028400 37800 0 LHST}
+    {2611755000 39600 1 LHDT}
+    {2627478000 37800 0 LHST}
+    {2643204600 39600 1 LHDT}
+    {2658927600 37800 0 LHST}
+    {2674654200 39600 1 LHDT}
+    {2690377200 37800 0 LHST}
+    {2706103800 39600 1 LHDT}
+    {2721826800 37800 0 LHST}
+    {2737553400 39600 1 LHDT}
+    {2753276400 37800 0 LHST}
+    {2769607800 39600 1 LHDT}
+    {2785330800 37800 0 LHST}
+    {2801057400 39600 1 LHDT}
+    {2816780400 37800 0 LHST}
+    {2832507000 39600 1 LHDT}
+    {2848230000 37800 0 LHST}
+    {2863956600 39600 1 LHDT}
+    {2879679600 37800 0 LHST}
+    {2895406200 39600 1 LHDT}
+    {2911129200 37800 0 LHST}
+    {2926855800 39600 1 LHDT}
+    {2942578800 37800 0 LHST}
+    {2958910200 39600 1 LHDT}
+    {2974633200 37800 0 LHST}
+    {2990359800 39600 1 LHDT}
+    {3006082800 37800 0 LHST}
+    {3021809400 39600 1 LHDT}
+    {3037532400 37800 0 LHST}
+    {3053259000 39600 1 LHDT}
+    {3068982000 37800 0 LHST}
+    {3084708600 39600 1 LHDT}
+    {3100431600 37800 0 LHST}
+    {3116763000 39600 1 LHDT}
+    {3132486000 37800 0 LHST}
+    {3148212600 39600 1 LHDT}
+    {3163935600 37800 0 LHST}
+    {3179662200 39600 1 LHDT}
+    {3195385200 37800 0 LHST}
+    {3211111800 39600 1 LHDT}
+    {3226834800 37800 0 LHST}
+    {3242561400 39600 1 LHDT}
+    {3258284400 37800 0 LHST}
+    {3274011000 39600 1 LHDT}
+    {3289734000 37800 0 LHST}
+    {3306065400 39600 1 LHDT}
+    {3321788400 37800 0 LHST}
+    {3337515000 39600 1 LHDT}
+    {3353238000 37800 0 LHST}
+    {3368964600 39600 1 LHDT}
+    {3384687600 37800 0 LHST}
+    {3400414200 39600 1 LHDT}
+    {3416137200 37800 0 LHST}
+    {3431863800 39600 1 LHDT}
+    {3447586800 37800 0 LHST}
+    {3463313400 39600 1 LHDT}
+    {3479641200 37800 0 LHST}
+    {3495367800 39600 1 LHDT}
+    {3511090800 37800 0 LHST}
+    {3526817400 39600 1 LHDT}
+    {3542540400 37800 0 LHST}
+    {3558267000 39600 1 LHDT}
+    {3573990000 37800 0 LHST}
+    {3589716600 39600 1 LHDT}
+    {3605439600 37800 0 LHST}
+    {3621166200 39600 1 LHDT}
+    {3636889200 37800 0 LHST}
+    {3653220600 39600 1 LHDT}
+    {3668943600 37800 0 LHST}
+    {3684670200 39600 1 LHDT}
+    {3700393200 37800 0 LHST}
+    {3716119800 39600 1 LHDT}
+    {3731842800 37800 0 LHST}
+    {3747569400 39600 1 LHDT}
+    {3763292400 37800 0 LHST}
+    {3779019000 39600 1 LHDT}
+    {3794742000 37800 0 LHST}
+    {3810468600 39600 1 LHDT}
+    {3826191600 37800 0 LHST}
+    {3842523000 39600 1 LHDT}
+    {3858246000 37800 0 LHST}
+    {3873972600 39600 1 LHDT}
+    {3889695600 37800 0 LHST}
+    {3905422200 39600 1 LHDT}
+    {3921145200 37800 0 LHST}
+    {3936871800 39600 1 LHDT}
+    {3952594800 37800 0 LHST}
+    {3968321400 39600 1 LHDT}
+    {3984044400 37800 0 LHST}
+    {4000375800 39600 1 LHDT}
+    {4016098800 37800 0 LHST}
+    {4031825400 39600 1 LHDT}
+    {4047548400 37800 0 LHST}
+    {4063275000 39600 1 LHDT}
+    {4078998000 37800 0 LHST}
+    {4094724600 39600 1 LHDT}
+}
diff --git a/library/tzdata/Australia/Melbourne b/library/tzdata/Australia/Melbourne
new file mode 100644
index 0000000..81777df
--- /dev/null
+++ b/library/tzdata/Australia/Melbourne
@@ -0,0 +1,272 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Australia/Melbourne) {
+    {-9223372036854775808 34792 0 LMT}
+    {-2364111592 36000 0 AEST}
+    {-1672567140 39600 1 AEDT}
+    {-1665392400 36000 0 AEST}
+    {-883641600 39600 1 AEDT}
+    {-876128400 36000 0 AEST}
+    {-860400000 39600 1 AEDT}
+    {-844678800 36000 0 AEST}
+    {-828345600 39600 1 AEDT}
+    {-813229200 36000 0 AEST}
+    {31500000 36000 0 AEST}
+    {57686400 39600 1 AEDT}
+    {67968000 36000 0 AEST}
+    {89136000 39600 1 AEDT}
+    {100022400 36000 0 AEST}
+    {120585600 39600 1 AEDT}
+    {131472000 36000 0 AEST}
+    {152035200 39600 1 AEDT}
+    {162921600 36000 0 AEST}
+    {183484800 39600 1 AEDT}
+    {194976000 36000 0 AEST}
+    {215539200 39600 1 AEDT}
+    {226425600 36000 0 AEST}
+    {246988800 39600 1 AEDT}
+    {257875200 36000 0 AEST}
+    {278438400 39600 1 AEDT}
+    {289324800 36000 0 AEST}
+    {309888000 39600 1 AEDT}
+    {320774400 36000 0 AEST}
+    {341337600 39600 1 AEDT}
+    {352224000 36000 0 AEST}
+    {372787200 39600 1 AEDT}
+    {384278400 36000 0 AEST}
+    {404841600 39600 1 AEDT}
+    {415728000 36000 0 AEST}
+    {436291200 39600 1 AEDT}
+    {447177600 36000 0 AEST}
+    {467740800 39600 1 AEDT}
+    {478627200 36000 0 AEST}
+    {499190400 39600 1 AEDT}
+    {511286400 36000 0 AEST}
+    {530035200 39600 1 AEDT}
+    {542736000 36000 0 AEST}
+    {561484800 39600 1 AEDT}
+    {574790400 36000 0 AEST}
+    {594144000 39600 1 AEDT}
+    {606240000 36000 0 AEST}
+    {625593600 39600 1 AEDT}
+    {637689600 36000 0 AEST}
+    {657043200 39600 1 AEDT}
+    {667929600 36000 0 AEST}
+    {688492800 39600 1 AEDT}
+    {699379200 36000 0 AEST}
+    {719942400 39600 1 AEDT}
+    {731433600 36000 0 AEST}
+    {751996800 39600 1 AEDT}
+    {762883200 36000 0 AEST}
+    {783446400 39600 1 AEDT}
+    {796147200 36000 0 AEST}
+    {814896000 39600 1 AEDT}
+    {828201600 36000 0 AEST}
+    {846345600 39600 1 AEDT}
+    {859651200 36000 0 AEST}
+    {877795200 39600 1 AEDT}
+    {891100800 36000 0 AEST}
+    {909244800 39600 1 AEDT}
+    {922550400 36000 0 AEST}
+    {941299200 39600 1 AEDT}
+    {954000000 36000 0 AEST}
+    {967305600 39600 1 AEDT}
+    {985449600 36000 0 AEST}
+    {1004198400 39600 1 AEDT}
+    {1017504000 36000 0 AEST}
+    {1035648000 39600 1 AEDT}
+    {1048953600 36000 0 AEST}
+    {1067097600 39600 1 AEDT}
+    {1080403200 36000 0 AEST}
+    {1099152000 39600 1 AEDT}
+    {1111852800 36000 0 AEST}
+    {1130601600 39600 1 AEDT}
+    {1143907200 36000 0 AEST}
+    {1162051200 39600 1 AEDT}
+    {1174752000 36000 0 AEST}
+    {1193500800 39600 1 AEDT}
+    {1207411200 36000 0 AEST}
+    {1223136000 39600 1 AEDT}
+    {1238860800 36000 0 AEST}
+    {1254585600 39600 1 AEDT}
+    {1270310400 36000 0 AEST}
+    {1286035200 39600 1 AEDT}
+    {1301760000 36000 0 AEST}
+    {1317484800 39600 1 AEDT}
+    {1333209600 36000 0 AEST}
+    {1349539200 39600 1 AEDT}
+    {1365264000 36000 0 AEST}
+    {1380988800 39600 1 AEDT}
+    {1396713600 36000 0 AEST}
+    {1412438400 39600 1 AEDT}
+    {1428163200 36000 0 AEST}
+    {1443888000 39600 1 AEDT}
+    {1459612800 36000 0 AEST}
+    {1475337600 39600 1 AEDT}
+    {1491062400 36000 0 AEST}
+    {1506787200 39600 1 AEDT}
+    {1522512000 36000 0 AEST}
+    {1538841600 39600 1 AEDT}
+    {1554566400 36000 0 AEST}
+    {1570291200 39600 1 AEDT}
+    {1586016000 36000 0 AEST}
+    {1601740800 39600 1 AEDT}
+    {1617465600 36000 0 AEST}
+    {1633190400 39600 1 AEDT}
+    {1648915200 36000 0 AEST}
+    {1664640000 39600 1 AEDT}
+    {1680364800 36000 0 AEST}
+    {1696089600 39600 1 AEDT}
+    {1712419200 36000 0 AEST}
+    {1728144000 39600 1 AEDT}
+    {1743868800 36000 0 AEST}
+    {1759593600 39600 1 AEDT}
+    {1775318400 36000 0 AEST}
+    {1791043200 39600 1 AEDT}
+    {1806768000 36000 0 AEST}
+    {1822492800 39600 1 AEDT}
+    {1838217600 36000 0 AEST}
+    {1853942400 39600 1 AEDT}
+    {1869667200 36000 0 AEST}
+    {1885996800 39600 1 AEDT}
+    {1901721600 36000 0 AEST}
+    {1917446400 39600 1 AEDT}
+    {1933171200 36000 0 AEST}
+    {1948896000 39600 1 AEDT}
+    {1964620800 36000 0 AEST}
+    {1980345600 39600 1 AEDT}
+    {1996070400 36000 0 AEST}
+    {2011795200 39600 1 AEDT}
+    {2027520000 36000 0 AEST}
+    {2043244800 39600 1 AEDT}
+    {2058969600 36000 0 AEST}
+    {2075299200 39600 1 AEDT}
+    {2091024000 36000 0 AEST}
+    {2106748800 39600 1 AEDT}
+    {2122473600 36000 0 AEST}
+    {2138198400 39600 1 AEDT}
+    {2153923200 36000 0 AEST}
+    {2169648000 39600 1 AEDT}
+    {2185372800 36000 0 AEST}
+    {2201097600 39600 1 AEDT}
+    {2216822400 36000 0 AEST}
+    {2233152000 39600 1 AEDT}
+    {2248876800 36000 0 AEST}
+    {2264601600 39600 1 AEDT}
+    {2280326400 36000 0 AEST}
+    {2296051200 39600 1 AEDT}
+    {2311776000 36000 0 AEST}
+    {2327500800 39600 1 AEDT}
+    {2343225600 36000 0 AEST}
+    {2358950400 39600 1 AEDT}
+    {2374675200 36000 0 AEST}
+    {2390400000 39600 1 AEDT}
+    {2406124800 36000 0 AEST}
+    {2422454400 39600 1 AEDT}
+    {2438179200 36000 0 AEST}
+    {2453904000 39600 1 AEDT}
+    {2469628800 36000 0 AEST}
+    {2485353600 39600 1 AEDT}
+    {2501078400 36000 0 AEST}
+    {2516803200 39600 1 AEDT}
+    {2532528000 36000 0 AEST}
+    {2548252800 39600 1 AEDT}
+    {2563977600 36000 0 AEST}
+    {2579702400 39600 1 AEDT}
+    {2596032000 36000 0 AEST}
+    {2611756800 39600 1 AEDT}
+    {2627481600 36000 0 AEST}
+    {2643206400 39600 1 AEDT}
+    {2658931200 36000 0 AEST}
+    {2674656000 39600 1 AEDT}
+    {2690380800 36000 0 AEST}
+    {2706105600 39600 1 AEDT}
+    {2721830400 36000 0 AEST}
+    {2737555200 39600 1 AEDT}
+    {2753280000 36000 0 AEST}
+    {2769609600 39600 1 AEDT}
+    {2785334400 36000 0 AEST}
+    {2801059200 39600 1 AEDT}
+    {2816784000 36000 0 AEST}
+    {2832508800 39600 1 AEDT}
+    {2848233600 36000 0 AEST}
+    {2863958400 39600 1 AEDT}
+    {2879683200 36000 0 AEST}
+    {2895408000 39600 1 AEDT}
+    {2911132800 36000 0 AEST}
+    {2926857600 39600 1 AEDT}
+    {2942582400 36000 0 AEST}
+    {2958912000 39600 1 AEDT}
+    {2974636800 36000 0 AEST}
+    {2990361600 39600 1 AEDT}
+    {3006086400 36000 0 AEST}
+    {3021811200 39600 1 AEDT}
+    {3037536000 36000 0 AEST}
+    {3053260800 39600 1 AEDT}
+    {3068985600 36000 0 AEST}
+    {3084710400 39600 1 AEDT}
+    {3100435200 36000 0 AEST}
+    {3116764800 39600 1 AEDT}
+    {3132489600 36000 0 AEST}
+    {3148214400 39600 1 AEDT}
+    {3163939200 36000 0 AEST}
+    {3179664000 39600 1 AEDT}
+    {3195388800 36000 0 AEST}
+    {3211113600 39600 1 AEDT}
+    {3226838400 36000 0 AEST}
+    {3242563200 39600 1 AEDT}
+    {3258288000 36000 0 AEST}
+    {3274012800 39600 1 AEDT}
+    {3289737600 36000 0 AEST}
+    {3306067200 39600 1 AEDT}
+    {3321792000 36000 0 AEST}
+    {3337516800 39600 1 AEDT}
+    {3353241600 36000 0 AEST}
+    {3368966400 39600 1 AEDT}
+    {3384691200 36000 0 AEST}
+    {3400416000 39600 1 AEDT}
+    {3416140800 36000 0 AEST}
+    {3431865600 39600 1 AEDT}
+    {3447590400 36000 0 AEST}
+    {3463315200 39600 1 AEDT}
+    {3479644800 36000 0 AEST}
+    {3495369600 39600 1 AEDT}
+    {3511094400 36000 0 AEST}
+    {3526819200 39600 1 AEDT}
+    {3542544000 36000 0 AEST}
+    {3558268800 39600 1 AEDT}
+    {3573993600 36000 0 AEST}
+    {3589718400 39600 1 AEDT}
+    {3605443200 36000 0 AEST}
+    {3621168000 39600 1 AEDT}
+    {3636892800 36000 0 AEST}
+    {3653222400 39600 1 AEDT}
+    {3668947200 36000 0 AEST}
+    {3684672000 39600 1 AEDT}
+    {3700396800 36000 0 AEST}
+    {3716121600 39600 1 AEDT}
+    {3731846400 36000 0 AEST}
+    {3747571200 39600 1 AEDT}
+    {3763296000 36000 0 AEST}
+    {3779020800 39600 1 AEDT}
+    {3794745600 36000 0 AEST}
+    {3810470400 39600 1 AEDT}
+    {3826195200 36000 0 AEST}
+    {3842524800 39600 1 AEDT}
+    {3858249600 36000 0 AEST}
+    {3873974400 39600 1 AEDT}
+    {3889699200 36000 0 AEST}
+    {3905424000 39600 1 AEDT}
+    {3921148800 36000 0 AEST}
+    {3936873600 39600 1 AEDT}
+    {3952598400 36000 0 AEST}
+    {3968323200 39600 1 AEDT}
+    {3984048000 36000 0 AEST}
+    {4000377600 39600 1 AEDT}
+    {4016102400 36000 0 AEST}
+    {4031827200 39600 1 AEDT}
+    {4047552000 36000 0 AEST}
+    {4063276800 39600 1 AEDT}
+    {4079001600 36000 0 AEST}
+    {4094726400 39600 1 AEDT}
+}
diff --git a/library/tzdata/Australia/NSW b/library/tzdata/Australia/NSW
new file mode 100644
index 0000000..905bdfe
--- /dev/null
+++ b/library/tzdata/Australia/NSW
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Australia/Sydney)]} {
+    LoadTimeZoneFile Australia/Sydney
+}
+set TZData(:Australia/NSW) $TZData(:Australia/Sydney)
diff --git a/library/tzdata/Australia/North b/library/tzdata/Australia/North
new file mode 100644
index 0000000..950c88c
--- /dev/null
+++ b/library/tzdata/Australia/North
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Australia/Darwin)]} {
+    LoadTimeZoneFile Australia/Darwin
+}
+set TZData(:Australia/North) $TZData(:Australia/Darwin)
diff --git a/library/tzdata/Australia/Perth b/library/tzdata/Australia/Perth
new file mode 100644
index 0000000..6ccbca8
--- /dev/null
+++ b/library/tzdata/Australia/Perth
@@ -0,0 +1,25 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Australia/Perth) {
+    {-9223372036854775808 27804 0 LMT}
+    {-2337925404 28800 0 AWST}
+    {-1672559940 32400 1 AWDT}
+    {-1665385200 28800 0 AWST}
+    {-883634400 32400 1 AWDT}
+    {-876121200 28800 0 AWST}
+    {-860392800 32400 1 AWDT}
+    {-844671600 28800 0 AWST}
+    {-836470800 32400 0 AWST}
+    {152042400 32400 1 AWDT}
+    {162928800 28800 0 AWST}
+    {436298400 32400 1 AWDT}
+    {447184800 28800 0 AWST}
+    {690314400 32400 1 AWDT}
+    {699386400 28800 0 AWST}
+    {1165082400 32400 1 AWDT}
+    {1174759200 28800 0 AWST}
+    {1193508000 32400 1 AWDT}
+    {1206813600 28800 0 AWST}
+    {1224957600 32400 1 AWDT}
+    {1238263200 28800 0 AWST}
+}
diff --git a/library/tzdata/Australia/Queensland b/library/tzdata/Australia/Queensland
new file mode 100644
index 0000000..6246e92
--- /dev/null
+++ b/library/tzdata/Australia/Queensland
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Australia/Brisbane)]} {
+    LoadTimeZoneFile Australia/Brisbane
+}
+set TZData(:Australia/Queensland) $TZData(:Australia/Brisbane)
diff --git a/library/tzdata/Australia/South b/library/tzdata/Australia/South
new file mode 100644
index 0000000..9c7dd95
--- /dev/null
+++ b/library/tzdata/Australia/South
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Australia/Adelaide)]} {
+    LoadTimeZoneFile Australia/Adelaide
+}
+set TZData(:Australia/South) $TZData(:Australia/Adelaide)
diff --git a/library/tzdata/Australia/Sydney b/library/tzdata/Australia/Sydney
new file mode 100644
index 0000000..b1c4411
--- /dev/null
+++ b/library/tzdata/Australia/Sydney
@@ -0,0 +1,272 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Australia/Sydney) {
+    {-9223372036854775808 36292 0 LMT}
+    {-2364113092 36000 0 AEST}
+    {-1672567140 39600 1 AEDT}
+    {-1665392400 36000 0 AEST}
+    {-883641600 39600 1 AEDT}
+    {-876128400 36000 0 AEST}
+    {-860400000 39600 1 AEDT}
+    {-844678800 36000 0 AEST}
+    {-828345600 39600 1 AEDT}
+    {-813229200 36000 0 AEST}
+    {31500000 36000 0 AEST}
+    {57686400 39600 1 AEDT}
+    {67968000 36000 0 AEST}
+    {89136000 39600 1 AEDT}
+    {100022400 36000 0 AEST}
+    {120585600 39600 1 AEDT}
+    {131472000 36000 0 AEST}
+    {152035200 39600 1 AEDT}
+    {162921600 36000 0 AEST}
+    {183484800 39600 1 AEDT}
+    {194976000 36000 0 AEST}
+    {215539200 39600 1 AEDT}
+    {226425600 36000 0 AEST}
+    {246988800 39600 1 AEDT}
+    {257875200 36000 0 AEST}
+    {278438400 39600 1 AEDT}
+    {289324800 36000 0 AEST}
+    {309888000 39600 1 AEDT}
+    {320774400 36000 0 AEST}
+    {341337600 39600 1 AEDT}
+    {352224000 36000 0 AEST}
+    {372787200 39600 1 AEDT}
+    {386697600 36000 0 AEST}
+    {404841600 39600 1 AEDT}
+    {415728000 36000 0 AEST}
+    {436291200 39600 1 AEDT}
+    {447177600 36000 0 AEST}
+    {467740800 39600 1 AEDT}
+    {478627200 36000 0 AEST}
+    {499190400 39600 1 AEDT}
+    {511286400 36000 0 AEST}
+    {530035200 39600 1 AEDT}
+    {542736000 36000 0 AEST}
+    {562089600 39600 1 AEDT}
+    {574790400 36000 0 AEST}
+    {594144000 39600 1 AEDT}
+    {606240000 36000 0 AEST}
+    {625593600 39600 1 AEDT}
+    {636480000 36000 0 AEST}
+    {657043200 39600 1 AEDT}
+    {667929600 36000 0 AEST}
+    {688492800 39600 1 AEDT}
+    {699379200 36000 0 AEST}
+    {719942400 39600 1 AEDT}
+    {731433600 36000 0 AEST}
+    {751996800 39600 1 AEDT}
+    {762883200 36000 0 AEST}
+    {783446400 39600 1 AEDT}
+    {794332800 36000 0 AEST}
+    {814896000 39600 1 AEDT}
+    {828201600 36000 0 AEST}
+    {846345600 39600 1 AEDT}
+    {859651200 36000 0 AEST}
+    {877795200 39600 1 AEDT}
+    {891100800 36000 0 AEST}
+    {909244800 39600 1 AEDT}
+    {922550400 36000 0 AEST}
+    {941299200 39600 1 AEDT}
+    {954000000 36000 0 AEST}
+    {967305600 39600 1 AEDT}
+    {985449600 36000 0 AEST}
+    {1004198400 39600 1 AEDT}
+    {1017504000 36000 0 AEST}
+    {1035648000 39600 1 AEDT}
+    {1048953600 36000 0 AEST}
+    {1067097600 39600 1 AEDT}
+    {1080403200 36000 0 AEST}
+    {1099152000 39600 1 AEDT}
+    {1111852800 36000 0 AEST}
+    {1130601600 39600 1 AEDT}
+    {1143907200 36000 0 AEST}
+    {1162051200 39600 1 AEDT}
+    {1174752000 36000 0 AEST}
+    {1193500800 39600 1 AEDT}
+    {1207411200 36000 0 AEST}
+    {1223136000 39600 1 AEDT}
+    {1238860800 36000 0 AEST}
+    {1254585600 39600 1 AEDT}
+    {1270310400 36000 0 AEST}
+    {1286035200 39600 1 AEDT}
+    {1301760000 36000 0 AEST}
+    {1317484800 39600 1 AEDT}
+    {1333209600 36000 0 AEST}
+    {1349539200 39600 1 AEDT}
+    {1365264000 36000 0 AEST}
+    {1380988800 39600 1 AEDT}
+    {1396713600 36000 0 AEST}
+    {1412438400 39600 1 AEDT}
+    {1428163200 36000 0 AEST}
+    {1443888000 39600 1 AEDT}
+    {1459612800 36000 0 AEST}
+    {1475337600 39600 1 AEDT}
+    {1491062400 36000 0 AEST}
+    {1506787200 39600 1 AEDT}
+    {1522512000 36000 0 AEST}
+    {1538841600 39600 1 AEDT}
+    {1554566400 36000 0 AEST}
+    {1570291200 39600 1 AEDT}
+    {1586016000 36000 0 AEST}
+    {1601740800 39600 1 AEDT}
+    {1617465600 36000 0 AEST}
+    {1633190400 39600 1 AEDT}
+    {1648915200 36000 0 AEST}
+    {1664640000 39600 1 AEDT}
+    {1680364800 36000 0 AEST}
+    {1696089600 39600 1 AEDT}
+    {1712419200 36000 0 AEST}
+    {1728144000 39600 1 AEDT}
+    {1743868800 36000 0 AEST}
+    {1759593600 39600 1 AEDT}
+    {1775318400 36000 0 AEST}
+    {1791043200 39600 1 AEDT}
+    {1806768000 36000 0 AEST}
+    {1822492800 39600 1 AEDT}
+    {1838217600 36000 0 AEST}
+    {1853942400 39600 1 AEDT}
+    {1869667200 36000 0 AEST}
+    {1885996800 39600 1 AEDT}
+    {1901721600 36000 0 AEST}
+    {1917446400 39600 1 AEDT}
+    {1933171200 36000 0 AEST}
+    {1948896000 39600 1 AEDT}
+    {1964620800 36000 0 AEST}
+    {1980345600 39600 1 AEDT}
+    {1996070400 36000 0 AEST}
+    {2011795200 39600 1 AEDT}
+    {2027520000 36000 0 AEST}
+    {2043244800 39600 1 AEDT}
+    {2058969600 36000 0 AEST}
+    {2075299200 39600 1 AEDT}
+    {2091024000 36000 0 AEST}
+    {2106748800 39600 1 AEDT}
+    {2122473600 36000 0 AEST}
+    {2138198400 39600 1 AEDT}
+    {2153923200 36000 0 AEST}
+    {2169648000 39600 1 AEDT}
+    {2185372800 36000 0 AEST}
+    {2201097600 39600 1 AEDT}
+    {2216822400 36000 0 AEST}
+    {2233152000 39600 1 AEDT}
+    {2248876800 36000 0 AEST}
+    {2264601600 39600 1 AEDT}
+    {2280326400 36000 0 AEST}
+    {2296051200 39600 1 AEDT}
+    {2311776000 36000 0 AEST}
+    {2327500800 39600 1 AEDT}
+    {2343225600 36000 0 AEST}
+    {2358950400 39600 1 AEDT}
+    {2374675200 36000 0 AEST}
+    {2390400000 39600 1 AEDT}
+    {2406124800 36000 0 AEST}
+    {2422454400 39600 1 AEDT}
+    {2438179200 36000 0 AEST}
+    {2453904000 39600 1 AEDT}
+    {2469628800 36000 0 AEST}
+    {2485353600 39600 1 AEDT}
+    {2501078400 36000 0 AEST}
+    {2516803200 39600 1 AEDT}
+    {2532528000 36000 0 AEST}
+    {2548252800 39600 1 AEDT}
+    {2563977600 36000 0 AEST}
+    {2579702400 39600 1 AEDT}
+    {2596032000 36000 0 AEST}
+    {2611756800 39600 1 AEDT}
+    {2627481600 36000 0 AEST}
+    {2643206400 39600 1 AEDT}
+    {2658931200 36000 0 AEST}
+    {2674656000 39600 1 AEDT}
+    {2690380800 36000 0 AEST}
+    {2706105600 39600 1 AEDT}
+    {2721830400 36000 0 AEST}
+    {2737555200 39600 1 AEDT}
+    {2753280000 36000 0 AEST}
+    {2769609600 39600 1 AEDT}
+    {2785334400 36000 0 AEST}
+    {2801059200 39600 1 AEDT}
+    {2816784000 36000 0 AEST}
+    {2832508800 39600 1 AEDT}
+    {2848233600 36000 0 AEST}
+    {2863958400 39600 1 AEDT}
+    {2879683200 36000 0 AEST}
+    {2895408000 39600 1 AEDT}
+    {2911132800 36000 0 AEST}
+    {2926857600 39600 1 AEDT}
+    {2942582400 36000 0 AEST}
+    {2958912000 39600 1 AEDT}
+    {2974636800 36000 0 AEST}
+    {2990361600 39600 1 AEDT}
+    {3006086400 36000 0 AEST}
+    {3021811200 39600 1 AEDT}
+    {3037536000 36000 0 AEST}
+    {3053260800 39600 1 AEDT}
+    {3068985600 36000 0 AEST}
+    {3084710400 39600 1 AEDT}
+    {3100435200 36000 0 AEST}
+    {3116764800 39600 1 AEDT}
+    {3132489600 36000 0 AEST}
+    {3148214400 39600 1 AEDT}
+    {3163939200 36000 0 AEST}
+    {3179664000 39600 1 AEDT}
+    {3195388800 36000 0 AEST}
+    {3211113600 39600 1 AEDT}
+    {3226838400 36000 0 AEST}
+    {3242563200 39600 1 AEDT}
+    {3258288000 36000 0 AEST}
+    {3274012800 39600 1 AEDT}
+    {3289737600 36000 0 AEST}
+    {3306067200 39600 1 AEDT}
+    {3321792000 36000 0 AEST}
+    {3337516800 39600 1 AEDT}
+    {3353241600 36000 0 AEST}
+    {3368966400 39600 1 AEDT}
+    {3384691200 36000 0 AEST}
+    {3400416000 39600 1 AEDT}
+    {3416140800 36000 0 AEST}
+    {3431865600 39600 1 AEDT}
+    {3447590400 36000 0 AEST}
+    {3463315200 39600 1 AEDT}
+    {3479644800 36000 0 AEST}
+    {3495369600 39600 1 AEDT}
+    {3511094400 36000 0 AEST}
+    {3526819200 39600 1 AEDT}
+    {3542544000 36000 0 AEST}
+    {3558268800 39600 1 AEDT}
+    {3573993600 36000 0 AEST}
+    {3589718400 39600 1 AEDT}
+    {3605443200 36000 0 AEST}
+    {3621168000 39600 1 AEDT}
+    {3636892800 36000 0 AEST}
+    {3653222400 39600 1 AEDT}
+    {3668947200 36000 0 AEST}
+    {3684672000 39600 1 AEDT}
+    {3700396800 36000 0 AEST}
+    {3716121600 39600 1 AEDT}
+    {3731846400 36000 0 AEST}
+    {3747571200 39600 1 AEDT}
+    {3763296000 36000 0 AEST}
+    {3779020800 39600 1 AEDT}
+    {3794745600 36000 0 AEST}
+    {3810470400 39600 1 AEDT}
+    {3826195200 36000 0 AEST}
+    {3842524800 39600 1 AEDT}
+    {3858249600 36000 0 AEST}
+    {3873974400 39600 1 AEDT}
+    {3889699200 36000 0 AEST}
+    {3905424000 39600 1 AEDT}
+    {3921148800 36000 0 AEST}
+    {3936873600 39600 1 AEDT}
+    {3952598400 36000 0 AEST}
+    {3968323200 39600 1 AEDT}
+    {3984048000 36000 0 AEST}
+    {4000377600 39600 1 AEDT}
+    {4016102400 36000 0 AEST}
+    {4031827200 39600 1 AEDT}
+    {4047552000 36000 0 AEST}
+    {4063276800 39600 1 AEDT}
+    {4079001600 36000 0 AEST}
+    {4094726400 39600 1 AEDT}
+}
diff --git a/library/tzdata/Australia/Tasmania b/library/tzdata/Australia/Tasmania
new file mode 100644
index 0000000..1849bde
--- /dev/null
+++ b/library/tzdata/Australia/Tasmania
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Australia/Hobart)]} {
+    LoadTimeZoneFile Australia/Hobart
+}
+set TZData(:Australia/Tasmania) $TZData(:Australia/Hobart)
diff --git a/library/tzdata/Australia/Victoria b/library/tzdata/Australia/Victoria
new file mode 100644
index 0000000..037bfeb
--- /dev/null
+++ b/library/tzdata/Australia/Victoria
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Australia/Melbourne)]} {
+    LoadTimeZoneFile Australia/Melbourne
+}
+set TZData(:Australia/Victoria) $TZData(:Australia/Melbourne)
diff --git a/library/tzdata/Australia/West b/library/tzdata/Australia/West
new file mode 100644
index 0000000..4689f7e
--- /dev/null
+++ b/library/tzdata/Australia/West
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Australia/Perth)]} {
+    LoadTimeZoneFile Australia/Perth
+}
+set TZData(:Australia/West) $TZData(:Australia/Perth)
diff --git a/library/tzdata/Australia/Yancowinna b/library/tzdata/Australia/Yancowinna
new file mode 100644
index 0000000..b7d668d
--- /dev/null
+++ b/library/tzdata/Australia/Yancowinna
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Australia/Broken_Hill)]} {
+    LoadTimeZoneFile Australia/Broken_Hill
+}
+set TZData(:Australia/Yancowinna) $TZData(:Australia/Broken_Hill)
diff --git a/library/tzdata/Brazil/Acre b/library/tzdata/Brazil/Acre
new file mode 100644
index 0000000..abb0b98
--- /dev/null
+++ b/library/tzdata/Brazil/Acre
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(America/Rio_Branco)]} {
+    LoadTimeZoneFile America/Rio_Branco
+}
+set TZData(:Brazil/Acre) $TZData(:America/Rio_Branco)
diff --git a/library/tzdata/Brazil/DeNoronha b/library/tzdata/Brazil/DeNoronha
new file mode 100644
index 0000000..53accb4
--- /dev/null
+++ b/library/tzdata/Brazil/DeNoronha
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(America/Noronha)]} {
+    LoadTimeZoneFile America/Noronha
+}
+set TZData(:Brazil/DeNoronha) $TZData(:America/Noronha)
diff --git a/library/tzdata/Brazil/East b/library/tzdata/Brazil/East
new file mode 100644
index 0000000..f684633
--- /dev/null
+++ b/library/tzdata/Brazil/East
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(America/Sao_Paulo)]} {
+    LoadTimeZoneFile America/Sao_Paulo
+}
+set TZData(:Brazil/East) $TZData(:America/Sao_Paulo)
diff --git a/library/tzdata/Brazil/West b/library/tzdata/Brazil/West
new file mode 100644
index 0000000..67676d9
--- /dev/null
+++ b/library/tzdata/Brazil/West
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(America/Manaus)]} {
+    LoadTimeZoneFile America/Manaus
+}
+set TZData(:Brazil/West) $TZData(:America/Manaus)
diff --git a/library/tzdata/CET b/library/tzdata/CET
new file mode 100644
index 0000000..b08750a
--- /dev/null
+++ b/library/tzdata/CET
@@ -0,0 +1,265 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:CET) {
+    {-9223372036854775808 3600 0 CET}
+    {-1693706400 7200 1 CEST}
+    {-1680483600 3600 0 CET}
+    {-1663455600 7200 1 CEST}
+    {-1650150000 3600 0 CET}
+    {-1632006000 7200 1 CEST}
+    {-1618700400 3600 0 CET}
+    {-938905200 7200 1 CEST}
+    {-857257200 3600 0 CET}
+    {-844556400 7200 1 CEST}
+    {-828226800 3600 0 CET}
+    {-812502000 7200 1 CEST}
+    {-796777200 3600 0 CET}
+    {-781052400 7200 1 CEST}
+    {-766623600 3600 0 CET}
+    {228877200 7200 1 CEST}
+    {243997200 3600 0 CET}
+    {260326800 7200 1 CEST}
+    {276051600 3600 0 CET}
+    {291776400 7200 1 CEST}
+    {307501200 3600 0 CET}
+    {323830800 7200 1 CEST}
+    {338950800 3600 0 CET}
+    {354675600 7200 1 CEST}
+    {370400400 3600 0 CET}
+    {386125200 7200 1 CEST}
+    {401850000 3600 0 CET}
+    {417574800 7200 1 CEST}
+    {433299600 3600 0 CET}
+    {449024400 7200 1 CEST}
+    {465354000 3600 0 CET}
+    {481078800 7200 1 CEST}
+    {496803600 3600 0 CET}
+    {512528400 7200 1 CEST}
+    {528253200 3600 0 CET}
+    {543978000 7200 1 CEST}
+    {559702800 3600 0 CET}
+    {575427600 7200 1 CEST}
+    {591152400 3600 0 CET}
+    {606877200 7200 1 CEST}
+    {622602000 3600 0 CET}
+    {638326800 7200 1 CEST}
+    {654656400 3600 0 CET}
+    {670381200 7200 1 CEST}
+    {686106000 3600 0 CET}
+    {701830800 7200 1 CEST}
+    {717555600 3600 0 CET}
+    {733280400 7200 1 CEST}
+    {749005200 3600 0 CET}
+    {764730000 7200 1 CEST}
+    {780454800 3600 0 CET}
+    {796179600 7200 1 CEST}
+    {811904400 3600 0 CET}
+    {828234000 7200 1 CEST}
+    {846378000 3600 0 CET}
+    {859683600 7200 1 CEST}
+    {877827600 3600 0 CET}
+    {891133200 7200 1 CEST}
+    {909277200 3600 0 CET}
+    {922582800 7200 1 CEST}
+    {941331600 3600 0 CET}
+    {954032400 7200 1 CEST}
+    {972781200 3600 0 CET}
+    {985482000 7200 1 CEST}
+    {1004230800 3600 0 CET}
+    {1017536400 7200 1 CEST}
+    {1035680400 3600 0 CET}
+    {1048986000 7200 1 CEST}
+    {1067130000 3600 0 CET}
+    {1080435600 7200 1 CEST}
+    {1099184400 3600 0 CET}
+    {1111885200 7200 1 CEST}
+    {1130634000 3600 0 CET}
+    {1143334800 7200 1 CEST}
+    {1162083600 3600 0 CET}
+    {1174784400 7200 1 CEST}
+    {1193533200 3600 0 CET}
+    {1206838800 7200 1 CEST}
+    {1224982800 3600 0 CET}
+    {1238288400 7200 1 CEST}
+    {1256432400 3600 0 CET}
+    {1269738000 7200 1 CEST}
+    {1288486800 3600 0 CET}
+    {1301187600 7200 1 CEST}
+    {1319936400 3600 0 CET}
+    {1332637200 7200 1 CEST}
+    {1351386000 3600 0 CET}
+    {1364691600 7200 1 CEST}
+    {1382835600 3600 0 CET}
+    {1396141200 7200 1 CEST}
+    {1414285200 3600 0 CET}
+    {1427590800 7200 1 CEST}
+    {1445734800 3600 0 CET}
+    {1459040400 7200 1 CEST}
+    {1477789200 3600 0 CET}
+    {1490490000 7200 1 CEST}
+    {1509238800 3600 0 CET}
+    {1521939600 7200 1 CEST}
+    {1540688400 3600 0 CET}
+    {1553994000 7200 1 CEST}
+    {1572138000 3600 0 CET}
+    {1585443600 7200 1 CEST}
+    {1603587600 3600 0 CET}
+    {1616893200 7200 1 CEST}
+    {1635642000 3600 0 CET}
+    {1648342800 7200 1 CEST}
+    {1667091600 3600 0 CET}
+    {1679792400 7200 1 CEST}
+    {1698541200 3600 0 CET}
+    {1711846800 7200 1 CEST}
+    {1729990800 3600 0 CET}
+    {1743296400 7200 1 CEST}
+    {1761440400 3600 0 CET}
+    {1774746000 7200 1 CEST}
+    {1792890000 3600 0 CET}
+    {1806195600 7200 1 CEST}
+    {1824944400 3600 0 CET}
+    {1837645200 7200 1 CEST}
+    {1856394000 3600 0 CET}
+    {1869094800 7200 1 CEST}
+    {1887843600 3600 0 CET}
+    {1901149200 7200 1 CEST}
+    {1919293200 3600 0 CET}
+    {1932598800 7200 1 CEST}
+    {1950742800 3600 0 CET}
+    {1964048400 7200 1 CEST}
+    {1982797200 3600 0 CET}
+    {1995498000 7200 1 CEST}
+    {2014246800 3600 0 CET}
+    {2026947600 7200 1 CEST}
+    {2045696400 3600 0 CET}
+    {2058397200 7200 1 CEST}
+    {2077146000 3600 0 CET}
+    {2090451600 7200 1 CEST}
+    {2108595600 3600 0 CET}
+    {2121901200 7200 1 CEST}
+    {2140045200 3600 0 CET}
+    {2153350800 7200 1 CEST}
+    {2172099600 3600 0 CET}
+    {2184800400 7200 1 CEST}
+    {2203549200 3600 0 CET}
+    {2216250000 7200 1 CEST}
+    {2234998800 3600 0 CET}
+    {2248304400 7200 1 CEST}
+    {2266448400 3600 0 CET}
+    {2279754000 7200 1 CEST}
+    {2297898000 3600 0 CET}
+    {2311203600 7200 1 CEST}
+    {2329347600 3600 0 CET}
+    {2342653200 7200 1 CEST}
+    {2361402000 3600 0 CET}
+    {2374102800 7200 1 CEST}
+    {2392851600 3600 0 CET}
+    {2405552400 7200 1 CEST}
+    {2424301200 3600 0 CET}
+    {2437606800 7200 1 CEST}
+    {2455750800 3600 0 CET}
+    {2469056400 7200 1 CEST}
+    {2487200400 3600 0 CET}
+    {2500506000 7200 1 CEST}
+    {2519254800 3600 0 CET}
+    {2531955600 7200 1 CEST}
+    {2550704400 3600 0 CET}
+    {2563405200 7200 1 CEST}
+    {2582154000 3600 0 CET}
+    {2595459600 7200 1 CEST}
+    {2613603600 3600 0 CET}
+    {2626909200 7200 1 CEST}
+    {2645053200 3600 0 CET}
+    {2658358800 7200 1 CEST}
+    {2676502800 3600 0 CET}
+    {2689808400 7200 1 CEST}
+    {2708557200 3600 0 CET}
+    {2721258000 7200 1 CEST}
+    {2740006800 3600 0 CET}
+    {2752707600 7200 1 CEST}
+    {2771456400 3600 0 CET}
+    {2784762000 7200 1 CEST}
+    {2802906000 3600 0 CET}
+    {2816211600 7200 1 CEST}
+    {2834355600 3600 0 CET}
+    {2847661200 7200 1 CEST}
+    {2866410000 3600 0 CET}
+    {2879110800 7200 1 CEST}
+    {2897859600 3600 0 CET}
+    {2910560400 7200 1 CEST}
+    {2929309200 3600 0 CET}
+    {2942010000 7200 1 CEST}
+    {2960758800 3600 0 CET}
+    {2974064400 7200 1 CEST}
+    {2992208400 3600 0 CET}
+    {3005514000 7200 1 CEST}
+    {3023658000 3600 0 CET}
+    {3036963600 7200 1 CEST}
+    {3055712400 3600 0 CET}
+    {3068413200 7200 1 CEST}
+    {3087162000 3600 0 CET}
+    {3099862800 7200 1 CEST}
+    {3118611600 3600 0 CET}
+    {3131917200 7200 1 CEST}
+    {3150061200 3600 0 CET}
+    {3163366800 7200 1 CEST}
+    {3181510800 3600 0 CET}
+    {3194816400 7200 1 CEST}
+    {3212960400 3600 0 CET}
+    {3226266000 7200 1 CEST}
+    {3245014800 3600 0 CET}
+    {3257715600 7200 1 CEST}
+    {3276464400 3600 0 CET}
+    {3289165200 7200 1 CEST}
+    {3307914000 3600 0 CET}
+    {3321219600 7200 1 CEST}
+    {3339363600 3600 0 CET}
+    {3352669200 7200 1 CEST}
+    {3370813200 3600 0 CET}
+    {3384118800 7200 1 CEST}
+    {3402867600 3600 0 CET}
+    {3415568400 7200 1 CEST}
+    {3434317200 3600 0 CET}
+    {3447018000 7200 1 CEST}
+    {3465766800 3600 0 CET}
+    {3479072400 7200 1 CEST}
+    {3497216400 3600 0 CET}
+    {3510522000 7200 1 CEST}
+    {3528666000 3600 0 CET}
+    {3541971600 7200 1 CEST}
+    {3560115600 3600 0 CET}
+    {3573421200 7200 1 CEST}
+    {3592170000 3600 0 CET}
+    {3604870800 7200 1 CEST}
+    {3623619600 3600 0 CET}
+    {3636320400 7200 1 CEST}
+    {3655069200 3600 0 CET}
+    {3668374800 7200 1 CEST}
+    {3686518800 3600 0 CET}
+    {3699824400 7200 1 CEST}
+    {3717968400 3600 0 CET}
+    {3731274000 7200 1 CEST}
+    {3750022800 3600 0 CET}
+    {3762723600 7200 1 CEST}
+    {3781472400 3600 0 CET}
+    {3794173200 7200 1 CEST}
+    {3812922000 3600 0 CET}
+    {3825622800 7200 1 CEST}
+    {3844371600 3600 0 CET}
+    {3857677200 7200 1 CEST}
+    {3875821200 3600 0 CET}
+    {3889126800 7200 1 CEST}
+    {3907270800 3600 0 CET}
+    {3920576400 7200 1 CEST}
+    {3939325200 3600 0 CET}
+    {3952026000 7200 1 CEST}
+    {3970774800 3600 0 CET}
+    {3983475600 7200 1 CEST}
+    {4002224400 3600 0 CET}
+    {4015530000 7200 1 CEST}
+    {4033674000 3600 0 CET}
+    {4046979600 7200 1 CEST}
+    {4065123600 3600 0 CET}
+    {4078429200 7200 1 CEST}
+    {4096573200 3600 0 CET}
+}
diff --git a/library/tzdata/CST6CDT b/library/tzdata/CST6CDT
new file mode 100644
index 0000000..11e45f0
--- /dev/null
+++ b/library/tzdata/CST6CDT
@@ -0,0 +1,278 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:CST6CDT) {
+    {-9223372036854775808 -21600 0 CST}
+    {-1633276800 -18000 1 CDT}
+    {-1615136400 -21600 0 CST}
+    {-1601827200 -18000 1 CDT}
+    {-1583686800 -21600 0 CST}
+    {-880214400 -18000 1 CWT}
+    {-769395600 -18000 1 CPT}
+    {-765392400 -21600 0 CST}
+    {-84384000 -18000 1 CDT}
+    {-68662800 -21600 0 CST}
+    {-52934400 -18000 1 CDT}
+    {-37213200 -21600 0 CST}
+    {-21484800 -18000 1 CDT}
+    {-5763600 -21600 0 CST}
+    {9964800 -18000 1 CDT}
+    {25686000 -21600 0 CST}
+    {41414400 -18000 1 CDT}
+    {57740400 -21600 0 CST}
+    {73468800 -18000 1 CDT}
+    {89190000 -21600 0 CST}
+    {104918400 -18000 1 CDT}
+    {120639600 -21600 0 CST}
+    {126691200 -18000 1 CDT}
+    {152089200 -21600 0 CST}
+    {162374400 -18000 1 CDT}
+    {183538800 -21600 0 CST}
+    {199267200 -18000 1 CDT}
+    {215593200 -21600 0 CST}
+    {230716800 -18000 1 CDT}
+    {247042800 -21600 0 CST}
+    {262771200 -18000 1 CDT}
+    {278492400 -21600 0 CST}
+    {294220800 -18000 1 CDT}
+    {309942000 -21600 0 CST}
+    {325670400 -18000 1 CDT}
+    {341391600 -21600 0 CST}
+    {357120000 -18000 1 CDT}
+    {372841200 -21600 0 CST}
+    {388569600 -18000 1 CDT}
+    {404895600 -21600 0 CST}
+    {420019200 -18000 1 CDT}
+    {436345200 -21600 0 CST}
+    {452073600 -18000 1 CDT}
+    {467794800 -21600 0 CST}
+    {483523200 -18000 1 CDT}
+    {499244400 -21600 0 CST}
+    {514972800 -18000 1 CDT}
+    {530694000 -21600 0 CST}
+    {544608000 -18000 1 CDT}
+    {562143600 -21600 0 CST}
+    {576057600 -18000 1 CDT}
+    {594198000 -21600 0 CST}
+    {607507200 -18000 1 CDT}
+    {625647600 -21600 0 CST}
+    {638956800 -18000 1 CDT}
+    {657097200 -21600 0 CST}
+    {671011200 -18000 1 CDT}
+    {688546800 -21600 0 CST}
+    {702460800 -18000 1 CDT}
+    {719996400 -21600 0 CST}
+    {733910400 -18000 1 CDT}
+    {752050800 -21600 0 CST}
+    {765360000 -18000 1 CDT}
+    {783500400 -21600 0 CST}
+    {796809600 -18000 1 CDT}
+    {814950000 -21600 0 CST}
+    {828864000 -18000 1 CDT}
+    {846399600 -21600 0 CST}
+    {860313600 -18000 1 CDT}
+    {877849200 -21600 0 CST}
+    {891763200 -18000 1 CDT}
+    {909298800 -21600 0 CST}
+    {923212800 -18000 1 CDT}
+    {941353200 -21600 0 CST}
+    {954662400 -18000 1 CDT}
+    {972802800 -21600 0 CST}
+    {986112000 -18000 1 CDT}
+    {1004252400 -21600 0 CST}
+    {1018166400 -18000 1 CDT}
+    {1035702000 -21600 0 CST}
+    {1049616000 -18000 1 CDT}
+    {1067151600 -21600 0 CST}
+    {1081065600 -18000 1 CDT}
+    {1099206000 -21600 0 CST}
+    {1112515200 -18000 1 CDT}
+    {1130655600 -21600 0 CST}
+    {1143964800 -18000 1 CDT}
+    {1162105200 -21600 0 CST}
+    {1173600000 -18000 1 CDT}
+    {1194159600 -21600 0 CST}
+    {1205049600 -18000 1 CDT}
+    {1225609200 -21600 0 CST}
+    {1236499200 -18000 1 CDT}
+    {1257058800 -21600 0 CST}
+    {1268553600 -18000 1 CDT}
+    {1289113200 -21600 0 CST}
+    {1300003200 -18000 1 CDT}
+    {1320562800 -21600 0 CST}
+    {1331452800 -18000 1 CDT}
+    {1352012400 -21600 0 CST}
+    {1362902400 -18000 1 CDT}
+    {1383462000 -21600 0 CST}
+    {1394352000 -18000 1 CDT}
+    {1414911600 -21600 0 CST}
+    {1425801600 -18000 1 CDT}
+    {1446361200 -21600 0 CST}
+    {1457856000 -18000 1 CDT}
+    {1478415600 -21600 0 CST}
+    {1489305600 -18000 1 CDT}
+    {1509865200 -21600 0 CST}
+    {1520755200 -18000 1 CDT}
+    {1541314800 -21600 0 CST}
+    {1552204800 -18000 1 CDT}
+    {1572764400 -21600 0 CST}
+    {1583654400 -18000 1 CDT}
+    {1604214000 -21600 0 CST}
+    {1615708800 -18000 1 CDT}
+    {1636268400 -21600 0 CST}
+    {1647158400 -18000 1 CDT}
+    {1667718000 -21600 0 CST}
+    {1678608000 -18000 1 CDT}
+    {1699167600 -21600 0 CST}
+    {1710057600 -18000 1 CDT}
+    {1730617200 -21600 0 CST}
+    {1741507200 -18000 1 CDT}
+    {1762066800 -21600 0 CST}
+    {1772956800 -18000 1 CDT}
+    {1793516400 -21600 0 CST}
+    {1805011200 -18000 1 CDT}
+    {1825570800 -21600 0 CST}
+    {1836460800 -18000 1 CDT}
+    {1857020400 -21600 0 CST}
+    {1867910400 -18000 1 CDT}
+    {1888470000 -21600 0 CST}
+    {1899360000 -18000 1 CDT}
+    {1919919600 -21600 0 CST}
+    {1930809600 -18000 1 CDT}
+    {1951369200 -21600 0 CST}
+    {1962864000 -18000 1 CDT}
+    {1983423600 -21600 0 CST}
+    {1994313600 -18000 1 CDT}
+    {2014873200 -21600 0 CST}
+    {2025763200 -18000 1 CDT}
+    {2046322800 -21600 0 CST}
+    {2057212800 -18000 1 CDT}
+    {2077772400 -21600 0 CST}
+    {2088662400 -18000 1 CDT}
+    {2109222000 -21600 0 CST}
+    {2120112000 -18000 1 CDT}
+    {2140671600 -21600 0 CST}
+    {2152166400 -18000 1 CDT}
+    {2172726000 -21600 0 CST}
+    {2183616000 -18000 1 CDT}
+    {2204175600 -21600 0 CST}
+    {2215065600 -18000 1 CDT}
+    {2235625200 -21600 0 CST}
+    {2246515200 -18000 1 CDT}
+    {2267074800 -21600 0 CST}
+    {2277964800 -18000 1 CDT}
+    {2298524400 -21600 0 CST}
+    {2309414400 -18000 1 CDT}
+    {2329974000 -21600 0 CST}
+    {2341468800 -18000 1 CDT}
+    {2362028400 -21600 0 CST}
+    {2372918400 -18000 1 CDT}
+    {2393478000 -21600 0 CST}
+    {2404368000 -18000 1 CDT}
+    {2424927600 -21600 0 CST}
+    {2435817600 -18000 1 CDT}
+    {2456377200 -21600 0 CST}
+    {2467267200 -18000 1 CDT}
+    {2487826800 -21600 0 CST}
+    {2499321600 -18000 1 CDT}
+    {2519881200 -21600 0 CST}
+    {2530771200 -18000 1 CDT}
+    {2551330800 -21600 0 CST}
+    {2562220800 -18000 1 CDT}
+    {2582780400 -21600 0 CST}
+    {2593670400 -18000 1 CDT}
+    {2614230000 -21600 0 CST}
+    {2625120000 -18000 1 CDT}
+    {2645679600 -21600 0 CST}
+    {2656569600 -18000 1 CDT}
+    {2677129200 -21600 0 CST}
+    {2688624000 -18000 1 CDT}
+    {2709183600 -21600 0 CST}
+    {2720073600 -18000 1 CDT}
+    {2740633200 -21600 0 CST}
+    {2751523200 -18000 1 CDT}
+    {2772082800 -21600 0 CST}
+    {2782972800 -18000 1 CDT}
+    {2803532400 -21600 0 CST}
+    {2814422400 -18000 1 CDT}
+    {2834982000 -21600 0 CST}
+    {2846476800 -18000 1 CDT}
+    {2867036400 -21600 0 CST}
+    {2877926400 -18000 1 CDT}
+    {2898486000 -21600 0 CST}
+    {2909376000 -18000 1 CDT}
+    {2929935600 -21600 0 CST}
+    {2940825600 -18000 1 CDT}
+    {2961385200 -21600 0 CST}
+    {2972275200 -18000 1 CDT}
+    {2992834800 -21600 0 CST}
+    {3003724800 -18000 1 CDT}
+    {3024284400 -21600 0 CST}
+    {3035779200 -18000 1 CDT}
+    {3056338800 -21600 0 CST}
+    {3067228800 -18000 1 CDT}
+    {3087788400 -21600 0 CST}
+    {3098678400 -18000 1 CDT}
+    {3119238000 -21600 0 CST}
+    {3130128000 -18000 1 CDT}
+    {3150687600 -21600 0 CST}
+    {3161577600 -18000 1 CDT}
+    {3182137200 -21600 0 CST}
+    {3193027200 -18000 1 CDT}
+    {3213586800 -21600 0 CST}
+    {3225081600 -18000 1 CDT}
+    {3245641200 -21600 0 CST}
+    {3256531200 -18000 1 CDT}
+    {3277090800 -21600 0 CST}
+    {3287980800 -18000 1 CDT}
+    {3308540400 -21600 0 CST}
+    {3319430400 -18000 1 CDT}
+    {3339990000 -21600 0 CST}
+    {3350880000 -18000 1 CDT}
+    {3371439600 -21600 0 CST}
+    {3382934400 -18000 1 CDT}
+    {3403494000 -21600 0 CST}
+    {3414384000 -18000 1 CDT}
+    {3434943600 -21600 0 CST}
+    {3445833600 -18000 1 CDT}
+    {3466393200 -21600 0 CST}
+    {3477283200 -18000 1 CDT}
+    {3497842800 -21600 0 CST}
+    {3508732800 -18000 1 CDT}
+    {3529292400 -21600 0 CST}
+    {3540182400 -18000 1 CDT}
+    {3560742000 -21600 0 CST}
+    {3572236800 -18000 1 CDT}
+    {3592796400 -21600 0 CST}
+    {3603686400 -18000 1 CDT}
+    {3624246000 -21600 0 CST}
+    {3635136000 -18000 1 CDT}
+    {3655695600 -21600 0 CST}
+    {3666585600 -18000 1 CDT}
+    {3687145200 -21600 0 CST}
+    {3698035200 -18000 1 CDT}
+    {3718594800 -21600 0 CST}
+    {3730089600 -18000 1 CDT}
+    {3750649200 -21600 0 CST}
+    {3761539200 -18000 1 CDT}
+    {3782098800 -21600 0 CST}
+    {3792988800 -18000 1 CDT}
+    {3813548400 -21600 0 CST}
+    {3824438400 -18000 1 CDT}
+    {3844998000 -21600 0 CST}
+    {3855888000 -18000 1 CDT}
+    {3876447600 -21600 0 CST}
+    {3887337600 -18000 1 CDT}
+    {3907897200 -21600 0 CST}
+    {3919392000 -18000 1 CDT}
+    {3939951600 -21600 0 CST}
+    {3950841600 -18000 1 CDT}
+    {3971401200 -21600 0 CST}
+    {3982291200 -18000 1 CDT}
+    {4002850800 -21600 0 CST}
+    {4013740800 -18000 1 CDT}
+    {4034300400 -21600 0 CST}
+    {4045190400 -18000 1 CDT}
+    {4065750000 -21600 0 CST}
+    {4076640000 -18000 1 CDT}
+    {4097199600 -21600 0 CST}
+}
diff --git a/library/tzdata/Canada/Atlantic b/library/tzdata/Canada/Atlantic
new file mode 100644
index 0000000..d1478d9
--- /dev/null
+++ b/library/tzdata/Canada/Atlantic
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(America/Halifax)]} {
+    LoadTimeZoneFile America/Halifax
+}
+set TZData(:Canada/Atlantic) $TZData(:America/Halifax)
diff --git a/library/tzdata/Canada/Central b/library/tzdata/Canada/Central
new file mode 100644
index 0000000..b04bef9
--- /dev/null
+++ b/library/tzdata/Canada/Central
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(America/Winnipeg)]} {
+    LoadTimeZoneFile America/Winnipeg
+}
+set TZData(:Canada/Central) $TZData(:America/Winnipeg)
diff --git a/library/tzdata/Canada/East-Saskatchewan b/library/tzdata/Canada/East-Saskatchewan
new file mode 100644
index 0000000..f7e500c
--- /dev/null
+++ b/library/tzdata/Canada/East-Saskatchewan
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(America/Regina)]} {
+    LoadTimeZoneFile America/Regina
+}
+set TZData(:Canada/East-Saskatchewan) $TZData(:America/Regina)
diff --git a/library/tzdata/Canada/Eastern b/library/tzdata/Canada/Eastern
new file mode 100644
index 0000000..74528eb
--- /dev/null
+++ b/library/tzdata/Canada/Eastern
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(America/Toronto)]} {
+    LoadTimeZoneFile America/Toronto
+}
+set TZData(:Canada/Eastern) $TZData(:America/Toronto)
diff --git a/library/tzdata/Canada/Mountain b/library/tzdata/Canada/Mountain
new file mode 100644
index 0000000..8c6458d
--- /dev/null
+++ b/library/tzdata/Canada/Mountain
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(America/Edmonton)]} {
+    LoadTimeZoneFile America/Edmonton
+}
+set TZData(:Canada/Mountain) $TZData(:America/Edmonton)
diff --git a/library/tzdata/Canada/Newfoundland b/library/tzdata/Canada/Newfoundland
new file mode 100644
index 0000000..6904cde
--- /dev/null
+++ b/library/tzdata/Canada/Newfoundland
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(America/St_Johns)]} {
+    LoadTimeZoneFile America/St_Johns
+}
+set TZData(:Canada/Newfoundland) $TZData(:America/St_Johns)
diff --git a/library/tzdata/Canada/Pacific b/library/tzdata/Canada/Pacific
new file mode 100644
index 0000000..4d70342
--- /dev/null
+++ b/library/tzdata/Canada/Pacific
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(America/Vancouver)]} {
+    LoadTimeZoneFile America/Vancouver
+}
+set TZData(:Canada/Pacific) $TZData(:America/Vancouver)
diff --git a/library/tzdata/Canada/Saskatchewan b/library/tzdata/Canada/Saskatchewan
new file mode 100644
index 0000000..cd56446
--- /dev/null
+++ b/library/tzdata/Canada/Saskatchewan
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(America/Regina)]} {
+    LoadTimeZoneFile America/Regina
+}
+set TZData(:Canada/Saskatchewan) $TZData(:America/Regina)
diff --git a/library/tzdata/Canada/Yukon b/library/tzdata/Canada/Yukon
new file mode 100644
index 0000000..04b8368
--- /dev/null
+++ b/library/tzdata/Canada/Yukon
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(America/Whitehorse)]} {
+    LoadTimeZoneFile America/Whitehorse
+}
+set TZData(:Canada/Yukon) $TZData(:America/Whitehorse)
diff --git a/library/tzdata/Chile/Continental b/library/tzdata/Chile/Continental
new file mode 100644
index 0000000..0f858a3
--- /dev/null
+++ b/library/tzdata/Chile/Continental
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(America/Santiago)]} {
+    LoadTimeZoneFile America/Santiago
+}
+set TZData(:Chile/Continental) $TZData(:America/Santiago)
diff --git a/library/tzdata/Chile/EasterIsland b/library/tzdata/Chile/EasterIsland
new file mode 100644
index 0000000..4edc034
--- /dev/null
+++ b/library/tzdata/Chile/EasterIsland
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Pacific/Easter)]} {
+    LoadTimeZoneFile Pacific/Easter
+}
+set TZData(:Chile/EasterIsland) $TZData(:Pacific/Easter)
diff --git a/library/tzdata/Cuba b/library/tzdata/Cuba
new file mode 100644
index 0000000..17f7b45
--- /dev/null
+++ b/library/tzdata/Cuba
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(America/Havana)]} {
+    LoadTimeZoneFile America/Havana
+}
+set TZData(:Cuba) $TZData(:America/Havana)
diff --git a/library/tzdata/EET b/library/tzdata/EET
new file mode 100644
index 0000000..e7c102a
--- /dev/null
+++ b/library/tzdata/EET
@@ -0,0 +1,251 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:EET) {
+    {-9223372036854775808 7200 0 EET}
+    {228877200 10800 1 EEST}
+    {243997200 7200 0 EET}
+    {260326800 10800 1 EEST}
+    {276051600 7200 0 EET}
+    {291776400 10800 1 EEST}
+    {307501200 7200 0 EET}
+    {323830800 10800 1 EEST}
+    {338950800 7200 0 EET}
+    {354675600 10800 1 EEST}
+    {370400400 7200 0 EET}
+    {386125200 10800 1 EEST}
+    {401850000 7200 0 EET}
+    {417574800 10800 1 EEST}
+    {433299600 7200 0 EET}
+    {449024400 10800 1 EEST}
+    {465354000 7200 0 EET}
+    {481078800 10800 1 EEST}
+    {496803600 7200 0 EET}
+    {512528400 10800 1 EEST}
+    {528253200 7200 0 EET}
+    {543978000 10800 1 EEST}
+    {559702800 7200 0 EET}
+    {575427600 10800 1 EEST}
+    {591152400 7200 0 EET}
+    {606877200 10800 1 EEST}
+    {622602000 7200 0 EET}
+    {638326800 10800 1 EEST}
+    {654656400 7200 0 EET}
+    {670381200 10800 1 EEST}
+    {686106000 7200 0 EET}
+    {701830800 10800 1 EEST}
+    {717555600 7200 0 EET}
+    {733280400 10800 1 EEST}
+    {749005200 7200 0 EET}
+    {764730000 10800 1 EEST}
+    {780454800 7200 0 EET}
+    {796179600 10800 1 EEST}
+    {811904400 7200 0 EET}
+    {828234000 10800 1 EEST}
+    {846378000 7200 0 EET}
+    {859683600 10800 1 EEST}
+    {877827600 7200 0 EET}
+    {891133200 10800 1 EEST}
+    {909277200 7200 0 EET}
+    {922582800 10800 1 EEST}
+    {941331600 7200 0 EET}
+    {954032400 10800 1 EEST}
+    {972781200 7200 0 EET}
+    {985482000 10800 1 EEST}
+    {1004230800 7200 0 EET}
+    {1017536400 10800 1 EEST}
+    {1035680400 7200 0 EET}
+    {1048986000 10800 1 EEST}
+    {1067130000 7200 0 EET}
+    {1080435600 10800 1 EEST}
+    {1099184400 7200 0 EET}
+    {1111885200 10800 1 EEST}
+    {1130634000 7200 0 EET}
+    {1143334800 10800 1 EEST}
+    {1162083600 7200 0 EET}
+    {1174784400 10800 1 EEST}
+    {1193533200 7200 0 EET}
+    {1206838800 10800 1 EEST}
+    {1224982800 7200 0 EET}
+    {1238288400 10800 1 EEST}
+    {1256432400 7200 0 EET}
+    {1269738000 10800 1 EEST}
+    {1288486800 7200 0 EET}
+    {1301187600 10800 1 EEST}
+    {1319936400 7200 0 EET}
+    {1332637200 10800 1 EEST}
+    {1351386000 7200 0 EET}
+    {1364691600 10800 1 EEST}
+    {1382835600 7200 0 EET}
+    {1396141200 10800 1 EEST}
+    {1414285200 7200 0 EET}
+    {1427590800 10800 1 EEST}
+    {1445734800 7200 0 EET}
+    {1459040400 10800 1 EEST}
+    {1477789200 7200 0 EET}
+    {1490490000 10800 1 EEST}
+    {1509238800 7200 0 EET}
+    {1521939600 10800 1 EEST}
+    {1540688400 7200 0 EET}
+    {1553994000 10800 1 EEST}
+    {1572138000 7200 0 EET}
+    {1585443600 10800 1 EEST}
+    {1603587600 7200 0 EET}
+    {1616893200 10800 1 EEST}
+    {1635642000 7200 0 EET}
+    {1648342800 10800 1 EEST}
+    {1667091600 7200 0 EET}
+    {1679792400 10800 1 EEST}
+    {1698541200 7200 0 EET}
+    {1711846800 10800 1 EEST}
+    {1729990800 7200 0 EET}
+    {1743296400 10800 1 EEST}
+    {1761440400 7200 0 EET}
+    {1774746000 10800 1 EEST}
+    {1792890000 7200 0 EET}
+    {1806195600 10800 1 EEST}
+    {1824944400 7200 0 EET}
+    {1837645200 10800 1 EEST}
+    {1856394000 7200 0 EET}
+    {1869094800 10800 1 EEST}
+    {1887843600 7200 0 EET}
+    {1901149200 10800 1 EEST}
+    {1919293200 7200 0 EET}
+    {1932598800 10800 1 EEST}
+    {1950742800 7200 0 EET}
+    {1964048400 10800 1 EEST}
+    {1982797200 7200 0 EET}
+    {1995498000 10800 1 EEST}
+    {2014246800 7200 0 EET}
+    {2026947600 10800 1 EEST}
+    {2045696400 7200 0 EET}
+    {2058397200 10800 1 EEST}
+    {2077146000 7200 0 EET}
+    {2090451600 10800 1 EEST}
+    {2108595600 7200 0 EET}
+    {2121901200 10800 1 EEST}
+    {2140045200 7200 0 EET}
+    {2153350800 10800 1 EEST}
+    {2172099600 7200 0 EET}
+    {2184800400 10800 1 EEST}
+    {2203549200 7200 0 EET}
+    {2216250000 10800 1 EEST}
+    {2234998800 7200 0 EET}
+    {2248304400 10800 1 EEST}
+    {2266448400 7200 0 EET}
+    {2279754000 10800 1 EEST}
+    {2297898000 7200 0 EET}
+    {2311203600 10800 1 EEST}
+    {2329347600 7200 0 EET}
+    {2342653200 10800 1 EEST}
+    {2361402000 7200 0 EET}
+    {2374102800 10800 1 EEST}
+    {2392851600 7200 0 EET}
+    {2405552400 10800 1 EEST}
+    {2424301200 7200 0 EET}
+    {2437606800 10800 1 EEST}
+    {2455750800 7200 0 EET}
+    {2469056400 10800 1 EEST}
+    {2487200400 7200 0 EET}
+    {2500506000 10800 1 EEST}
+    {2519254800 7200 0 EET}
+    {2531955600 10800 1 EEST}
+    {2550704400 7200 0 EET}
+    {2563405200 10800 1 EEST}
+    {2582154000 7200 0 EET}
+    {2595459600 10800 1 EEST}
+    {2613603600 7200 0 EET}
+    {2626909200 10800 1 EEST}
+    {2645053200 7200 0 EET}
+    {2658358800 10800 1 EEST}
+    {2676502800 7200 0 EET}
+    {2689808400 10800 1 EEST}
+    {2708557200 7200 0 EET}
+    {2721258000 10800 1 EEST}
+    {2740006800 7200 0 EET}
+    {2752707600 10800 1 EEST}
+    {2771456400 7200 0 EET}
+    {2784762000 10800 1 EEST}
+    {2802906000 7200 0 EET}
+    {2816211600 10800 1 EEST}
+    {2834355600 7200 0 EET}
+    {2847661200 10800 1 EEST}
+    {2866410000 7200 0 EET}
+    {2879110800 10800 1 EEST}
+    {2897859600 7200 0 EET}
+    {2910560400 10800 1 EEST}
+    {2929309200 7200 0 EET}
+    {2942010000 10800 1 EEST}
+    {2960758800 7200 0 EET}
+    {2974064400 10800 1 EEST}
+    {2992208400 7200 0 EET}
+    {3005514000 10800 1 EEST}
+    {3023658000 7200 0 EET}
+    {3036963600 10800 1 EEST}
+    {3055712400 7200 0 EET}
+    {3068413200 10800 1 EEST}
+    {3087162000 7200 0 EET}
+    {3099862800 10800 1 EEST}
+    {3118611600 7200 0 EET}
+    {3131917200 10800 1 EEST}
+    {3150061200 7200 0 EET}
+    {3163366800 10800 1 EEST}
+    {3181510800 7200 0 EET}
+    {3194816400 10800 1 EEST}
+    {3212960400 7200 0 EET}
+    {3226266000 10800 1 EEST}
+    {3245014800 7200 0 EET}
+    {3257715600 10800 1 EEST}
+    {3276464400 7200 0 EET}
+    {3289165200 10800 1 EEST}
+    {3307914000 7200 0 EET}
+    {3321219600 10800 1 EEST}
+    {3339363600 7200 0 EET}
+    {3352669200 10800 1 EEST}
+    {3370813200 7200 0 EET}
+    {3384118800 10800 1 EEST}
+    {3402867600 7200 0 EET}
+    {3415568400 10800 1 EEST}
+    {3434317200 7200 0 EET}
+    {3447018000 10800 1 EEST}
+    {3465766800 7200 0 EET}
+    {3479072400 10800 1 EEST}
+    {3497216400 7200 0 EET}
+    {3510522000 10800 1 EEST}
+    {3528666000 7200 0 EET}
+    {3541971600 10800 1 EEST}
+    {3560115600 7200 0 EET}
+    {3573421200 10800 1 EEST}
+    {3592170000 7200 0 EET}
+    {3604870800 10800 1 EEST}
+    {3623619600 7200 0 EET}
+    {3636320400 10800 1 EEST}
+    {3655069200 7200 0 EET}
+    {3668374800 10800 1 EEST}
+    {3686518800 7200 0 EET}
+    {3699824400 10800 1 EEST}
+    {3717968400 7200 0 EET}
+    {3731274000 10800 1 EEST}
+    {3750022800 7200 0 EET}
+    {3762723600 10800 1 EEST}
+    {3781472400 7200 0 EET}
+    {3794173200 10800 1 EEST}
+    {3812922000 7200 0 EET}
+    {3825622800 10800 1 EEST}
+    {3844371600 7200 0 EET}
+    {3857677200 10800 1 EEST}
+    {3875821200 7200 0 EET}
+    {3889126800 10800 1 EEST}
+    {3907270800 7200 0 EET}
+    {3920576400 10800 1 EEST}
+    {3939325200 7200 0 EET}
+    {3952026000 10800 1 EEST}
+    {3970774800 7200 0 EET}
+    {3983475600 10800 1 EEST}
+    {4002224400 7200 0 EET}
+    {4015530000 10800 1 EEST}
+    {4033674000 7200 0 EET}
+    {4046979600 10800 1 EEST}
+    {4065123600 7200 0 EET}
+    {4078429200 10800 1 EEST}
+    {4096573200 7200 0 EET}
+}
diff --git a/library/tzdata/EST b/library/tzdata/EST
new file mode 100644
index 0000000..72c5b17
--- /dev/null
+++ b/library/tzdata/EST
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:EST) {
+    {-9223372036854775808 -18000 0 EST}
+}
diff --git a/library/tzdata/EST5EDT b/library/tzdata/EST5EDT
new file mode 100644
index 0000000..968833e
--- /dev/null
+++ b/library/tzdata/EST5EDT
@@ -0,0 +1,278 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:EST5EDT) {
+    {-9223372036854775808 -18000 0 EST}
+    {-1633280400 -14400 1 EDT}
+    {-1615140000 -18000 0 EST}
+    {-1601830800 -14400 1 EDT}
+    {-1583690400 -18000 0 EST}
+    {-880218000 -14400 1 EWT}
+    {-769395600 -14400 1 EPT}
+    {-765396000 -18000 0 EST}
+    {-84387600 -14400 1 EDT}
+    {-68666400 -18000 0 EST}
+    {-52938000 -14400 1 EDT}
+    {-37216800 -18000 0 EST}
+    {-21488400 -14400 1 EDT}
+    {-5767200 -18000 0 EST}
+    {9961200 -14400 1 EDT}
+    {25682400 -18000 0 EST}
+    {41410800 -14400 1 EDT}
+    {57736800 -18000 0 EST}
+    {73465200 -14400 1 EDT}
+    {89186400 -18000 0 EST}
+    {104914800 -14400 1 EDT}
+    {120636000 -18000 0 EST}
+    {126687600 -14400 1 EDT}
+    {152085600 -18000 0 EST}
+    {162370800 -14400 1 EDT}
+    {183535200 -18000 0 EST}
+    {199263600 -14400 1 EDT}
+    {215589600 -18000 0 EST}
+    {230713200 -14400 1 EDT}
+    {247039200 -18000 0 EST}
+    {262767600 -14400 1 EDT}
+    {278488800 -18000 0 EST}
+    {294217200 -14400 1 EDT}
+    {309938400 -18000 0 EST}
+    {325666800 -14400 1 EDT}
+    {341388000 -18000 0 EST}
+    {357116400 -14400 1 EDT}
+    {372837600 -18000 0 EST}
+    {388566000 -14400 1 EDT}
+    {404892000 -18000 0 EST}
+    {420015600 -14400 1 EDT}
+    {436341600 -18000 0 EST}
+    {452070000 -14400 1 EDT}
+    {467791200 -18000 0 EST}
+    {483519600 -14400 1 EDT}
+    {499240800 -18000 0 EST}
+    {514969200 -14400 1 EDT}
+    {530690400 -18000 0 EST}
+    {544604400 -14400 1 EDT}
+    {562140000 -18000 0 EST}
+    {576054000 -14400 1 EDT}
+    {594194400 -18000 0 EST}
+    {607503600 -14400 1 EDT}
+    {625644000 -18000 0 EST}
+    {638953200 -14400 1 EDT}
+    {657093600 -18000 0 EST}
+    {671007600 -14400 1 EDT}
+    {688543200 -18000 0 EST}
+    {702457200 -14400 1 EDT}
+    {719992800 -18000 0 EST}
+    {733906800 -14400 1 EDT}
+    {752047200 -18000 0 EST}
+    {765356400 -14400 1 EDT}
+    {783496800 -18000 0 EST}
+    {796806000 -14400 1 EDT}
+    {814946400 -18000 0 EST}
+    {828860400 -14400 1 EDT}
+    {846396000 -18000 0 EST}
+    {860310000 -14400 1 EDT}
+    {877845600 -18000 0 EST}
+    {891759600 -14400 1 EDT}
+    {909295200 -18000 0 EST}
+    {923209200 -14400 1 EDT}
+    {941349600 -18000 0 EST}
+    {954658800 -14400 1 EDT}
+    {972799200 -18000 0 EST}
+    {986108400 -14400 1 EDT}
+    {1004248800 -18000 0 EST}
+    {1018162800 -14400 1 EDT}
+    {1035698400 -18000 0 EST}
+    {1049612400 -14400 1 EDT}
+    {1067148000 -18000 0 EST}
+    {1081062000 -14400 1 EDT}
+    {1099202400 -18000 0 EST}
+    {1112511600 -14400 1 EDT}
+    {1130652000 -18000 0 EST}
+    {1143961200 -14400 1 EDT}
+    {1162101600 -18000 0 EST}
+    {1173596400 -14400 1 EDT}
+    {1194156000 -18000 0 EST}
+    {1205046000 -14400 1 EDT}
+    {1225605600 -18000 0 EST}
+    {1236495600 -14400 1 EDT}
+    {1257055200 -18000 0 EST}
+    {1268550000 -14400 1 EDT}
+    {1289109600 -18000 0 EST}
+    {1299999600 -14400 1 EDT}
+    {1320559200 -18000 0 EST}
+    {1331449200 -14400 1 EDT}
+    {1352008800 -18000 0 EST}
+    {1362898800 -14400 1 EDT}
+    {1383458400 -18000 0 EST}
+    {1394348400 -14400 1 EDT}
+    {1414908000 -18000 0 EST}
+    {1425798000 -14400 1 EDT}
+    {1446357600 -18000 0 EST}
+    {1457852400 -14400 1 EDT}
+    {1478412000 -18000 0 EST}
+    {1489302000 -14400 1 EDT}
+    {1509861600 -18000 0 EST}
+    {1520751600 -14400 1 EDT}
+    {1541311200 -18000 0 EST}
+    {1552201200 -14400 1 EDT}
+    {1572760800 -18000 0 EST}
+    {1583650800 -14400 1 EDT}
+    {1604210400 -18000 0 EST}
+    {1615705200 -14400 1 EDT}
+    {1636264800 -18000 0 EST}
+    {1647154800 -14400 1 EDT}
+    {1667714400 -18000 0 EST}
+    {1678604400 -14400 1 EDT}
+    {1699164000 -18000 0 EST}
+    {1710054000 -14400 1 EDT}
+    {1730613600 -18000 0 EST}
+    {1741503600 -14400 1 EDT}
+    {1762063200 -18000 0 EST}
+    {1772953200 -14400 1 EDT}
+    {1793512800 -18000 0 EST}
+    {1805007600 -14400 1 EDT}
+    {1825567200 -18000 0 EST}
+    {1836457200 -14400 1 EDT}
+    {1857016800 -18000 0 EST}
+    {1867906800 -14400 1 EDT}
+    {1888466400 -18000 0 EST}
+    {1899356400 -14400 1 EDT}
+    {1919916000 -18000 0 EST}
+    {1930806000 -14400 1 EDT}
+    {1951365600 -18000 0 EST}
+    {1962860400 -14400 1 EDT}
+    {1983420000 -18000 0 EST}
+    {1994310000 -14400 1 EDT}
+    {2014869600 -18000 0 EST}
+    {2025759600 -14400 1 EDT}
+    {2046319200 -18000 0 EST}
+    {2057209200 -14400 1 EDT}
+    {2077768800 -18000 0 EST}
+    {2088658800 -14400 1 EDT}
+    {2109218400 -18000 0 EST}
+    {2120108400 -14400 1 EDT}
+    {2140668000 -18000 0 EST}
+    {2152162800 -14400 1 EDT}
+    {2172722400 -18000 0 EST}
+    {2183612400 -14400 1 EDT}
+    {2204172000 -18000 0 EST}
+    {2215062000 -14400 1 EDT}
+    {2235621600 -18000 0 EST}
+    {2246511600 -14400 1 EDT}
+    {2267071200 -18000 0 EST}
+    {2277961200 -14400 1 EDT}
+    {2298520800 -18000 0 EST}
+    {2309410800 -14400 1 EDT}
+    {2329970400 -18000 0 EST}
+    {2341465200 -14400 1 EDT}
+    {2362024800 -18000 0 EST}
+    {2372914800 -14400 1 EDT}
+    {2393474400 -18000 0 EST}
+    {2404364400 -14400 1 EDT}
+    {2424924000 -18000 0 EST}
+    {2435814000 -14400 1 EDT}
+    {2456373600 -18000 0 EST}
+    {2467263600 -14400 1 EDT}
+    {2487823200 -18000 0 EST}
+    {2499318000 -14400 1 EDT}
+    {2519877600 -18000 0 EST}
+    {2530767600 -14400 1 EDT}
+    {2551327200 -18000 0 EST}
+    {2562217200 -14400 1 EDT}
+    {2582776800 -18000 0 EST}
+    {2593666800 -14400 1 EDT}
+    {2614226400 -18000 0 EST}
+    {2625116400 -14400 1 EDT}
+    {2645676000 -18000 0 EST}
+    {2656566000 -14400 1 EDT}
+    {2677125600 -18000 0 EST}
+    {2688620400 -14400 1 EDT}
+    {2709180000 -18000 0 EST}
+    {2720070000 -14400 1 EDT}
+    {2740629600 -18000 0 EST}
+    {2751519600 -14400 1 EDT}
+    {2772079200 -18000 0 EST}
+    {2782969200 -14400 1 EDT}
+    {2803528800 -18000 0 EST}
+    {2814418800 -14400 1 EDT}
+    {2834978400 -18000 0 EST}
+    {2846473200 -14400 1 EDT}
+    {2867032800 -18000 0 EST}
+    {2877922800 -14400 1 EDT}
+    {2898482400 -18000 0 EST}
+    {2909372400 -14400 1 EDT}
+    {2929932000 -18000 0 EST}
+    {2940822000 -14400 1 EDT}
+    {2961381600 -18000 0 EST}
+    {2972271600 -14400 1 EDT}
+    {2992831200 -18000 0 EST}
+    {3003721200 -14400 1 EDT}
+    {3024280800 -18000 0 EST}
+    {3035775600 -14400 1 EDT}
+    {3056335200 -18000 0 EST}
+    {3067225200 -14400 1 EDT}
+    {3087784800 -18000 0 EST}
+    {3098674800 -14400 1 EDT}
+    {3119234400 -18000 0 EST}
+    {3130124400 -14400 1 EDT}
+    {3150684000 -18000 0 EST}
+    {3161574000 -14400 1 EDT}
+    {3182133600 -18000 0 EST}
+    {3193023600 -14400 1 EDT}
+    {3213583200 -18000 0 EST}
+    {3225078000 -14400 1 EDT}
+    {3245637600 -18000 0 EST}
+    {3256527600 -14400 1 EDT}
+    {3277087200 -18000 0 EST}
+    {3287977200 -14400 1 EDT}
+    {3308536800 -18000 0 EST}
+    {3319426800 -14400 1 EDT}
+    {3339986400 -18000 0 EST}
+    {3350876400 -14400 1 EDT}
+    {3371436000 -18000 0 EST}
+    {3382930800 -14400 1 EDT}
+    {3403490400 -18000 0 EST}
+    {3414380400 -14400 1 EDT}
+    {3434940000 -18000 0 EST}
+    {3445830000 -14400 1 EDT}
+    {3466389600 -18000 0 EST}
+    {3477279600 -14400 1 EDT}
+    {3497839200 -18000 0 EST}
+    {3508729200 -14400 1 EDT}
+    {3529288800 -18000 0 EST}
+    {3540178800 -14400 1 EDT}
+    {3560738400 -18000 0 EST}
+    {3572233200 -14400 1 EDT}
+    {3592792800 -18000 0 EST}
+    {3603682800 -14400 1 EDT}
+    {3624242400 -18000 0 EST}
+    {3635132400 -14400 1 EDT}
+    {3655692000 -18000 0 EST}
+    {3666582000 -14400 1 EDT}
+    {3687141600 -18000 0 EST}
+    {3698031600 -14400 1 EDT}
+    {3718591200 -18000 0 EST}
+    {3730086000 -14400 1 EDT}
+    {3750645600 -18000 0 EST}
+    {3761535600 -14400 1 EDT}
+    {3782095200 -18000 0 EST}
+    {3792985200 -14400 1 EDT}
+    {3813544800 -18000 0 EST}
+    {3824434800 -14400 1 EDT}
+    {3844994400 -18000 0 EST}
+    {3855884400 -14400 1 EDT}
+    {3876444000 -18000 0 EST}
+    {3887334000 -14400 1 EDT}
+    {3907893600 -18000 0 EST}
+    {3919388400 -14400 1 EDT}
+    {3939948000 -18000 0 EST}
+    {3950838000 -14400 1 EDT}
+    {3971397600 -18000 0 EST}
+    {3982287600 -14400 1 EDT}
+    {4002847200 -18000 0 EST}
+    {4013737200 -14400 1 EDT}
+    {4034296800 -18000 0 EST}
+    {4045186800 -14400 1 EDT}
+    {4065746400 -18000 0 EST}
+    {4076636400 -14400 1 EDT}
+    {4097196000 -18000 0 EST}
+}
diff --git a/library/tzdata/Egypt b/library/tzdata/Egypt
new file mode 100644
index 0000000..63341bc
--- /dev/null
+++ b/library/tzdata/Egypt
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Africa/Cairo)]} {
+    LoadTimeZoneFile Africa/Cairo
+}
+set TZData(:Egypt) $TZData(:Africa/Cairo)
diff --git a/library/tzdata/Eire b/library/tzdata/Eire
new file mode 100644
index 0000000..c86c91c
--- /dev/null
+++ b/library/tzdata/Eire
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Europe/Dublin)]} {
+    LoadTimeZoneFile Europe/Dublin
+}
+set TZData(:Eire) $TZData(:Europe/Dublin)
diff --git a/library/tzdata/Etc/GMT b/library/tzdata/Etc/GMT
new file mode 100644
index 0000000..7454fd5
--- /dev/null
+++ b/library/tzdata/Etc/GMT
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Etc/GMT) {
+    {-9223372036854775808 0 0 GMT}
+}
diff --git a/library/tzdata/Etc/GMT+0 b/library/tzdata/Etc/GMT+0
new file mode 100644
index 0000000..017dee1
--- /dev/null
+++ b/library/tzdata/Etc/GMT+0
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Etc/GMT)]} {
+    LoadTimeZoneFile Etc/GMT
+}
+set TZData(:Etc/GMT+0) $TZData(:Etc/GMT)
diff --git a/library/tzdata/Etc/GMT+1 b/library/tzdata/Etc/GMT+1
new file mode 100644
index 0000000..12f97ba
--- /dev/null
+++ b/library/tzdata/Etc/GMT+1
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Etc/GMT+1) {
+    {-9223372036854775808 -3600 0 GMT+1}
+}
diff --git a/library/tzdata/Etc/GMT+10 b/library/tzdata/Etc/GMT+10
new file mode 100644
index 0000000..6ea50bb
--- /dev/null
+++ b/library/tzdata/Etc/GMT+10
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Etc/GMT+10) {
+    {-9223372036854775808 -36000 0 GMT+10}
+}
diff --git a/library/tzdata/Etc/GMT+11 b/library/tzdata/Etc/GMT+11
new file mode 100644
index 0000000..c91b169
--- /dev/null
+++ b/library/tzdata/Etc/GMT+11
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Etc/GMT+11) {
+    {-9223372036854775808 -39600 0 GMT+11}
+}
diff --git a/library/tzdata/Etc/GMT+12 b/library/tzdata/Etc/GMT+12
new file mode 100644
index 0000000..29a4cee
--- /dev/null
+++ b/library/tzdata/Etc/GMT+12
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Etc/GMT+12) {
+    {-9223372036854775808 -43200 0 GMT+12}
+}
diff --git a/library/tzdata/Etc/GMT+2 b/library/tzdata/Etc/GMT+2
new file mode 100644
index 0000000..8c6b526
--- /dev/null
+++ b/library/tzdata/Etc/GMT+2
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Etc/GMT+2) {
+    {-9223372036854775808 -7200 0 GMT+2}
+}
diff --git a/library/tzdata/Etc/GMT+3 b/library/tzdata/Etc/GMT+3
new file mode 100644
index 0000000..862571d
--- /dev/null
+++ b/library/tzdata/Etc/GMT+3
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Etc/GMT+3) {
+    {-9223372036854775808 -10800 0 GMT+3}
+}
diff --git a/library/tzdata/Etc/GMT+4 b/library/tzdata/Etc/GMT+4
new file mode 100644
index 0000000..a933bbc
--- /dev/null
+++ b/library/tzdata/Etc/GMT+4
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Etc/GMT+4) {
+    {-9223372036854775808 -14400 0 GMT+4}
+}
diff --git a/library/tzdata/Etc/GMT+5 b/library/tzdata/Etc/GMT+5
new file mode 100644
index 0000000..80cc25c
--- /dev/null
+++ b/library/tzdata/Etc/GMT+5
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Etc/GMT+5) {
+    {-9223372036854775808 -18000 0 GMT+5}
+}
diff --git a/library/tzdata/Etc/GMT+6 b/library/tzdata/Etc/GMT+6
new file mode 100644
index 0000000..bc57bd6
--- /dev/null
+++ b/library/tzdata/Etc/GMT+6
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Etc/GMT+6) {
+    {-9223372036854775808 -21600 0 GMT+6}
+}
diff --git a/library/tzdata/Etc/GMT+7 b/library/tzdata/Etc/GMT+7
new file mode 100644
index 0000000..d419eb9
--- /dev/null
+++ b/library/tzdata/Etc/GMT+7
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Etc/GMT+7) {
+    {-9223372036854775808 -25200 0 GMT+7}
+}
diff --git a/library/tzdata/Etc/GMT+8 b/library/tzdata/Etc/GMT+8
new file mode 100644
index 0000000..705ad40
--- /dev/null
+++ b/library/tzdata/Etc/GMT+8
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Etc/GMT+8) {
+    {-9223372036854775808 -28800 0 GMT+8}
+}
diff --git a/library/tzdata/Etc/GMT+9 b/library/tzdata/Etc/GMT+9
new file mode 100644
index 0000000..4086639
--- /dev/null
+++ b/library/tzdata/Etc/GMT+9
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Etc/GMT+9) {
+    {-9223372036854775808 -32400 0 GMT+9}
+}
diff --git a/library/tzdata/Etc/GMT-0 b/library/tzdata/Etc/GMT-0
new file mode 100644
index 0000000..d8913d5
--- /dev/null
+++ b/library/tzdata/Etc/GMT-0
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Etc/GMT)]} {
+    LoadTimeZoneFile Etc/GMT
+}
+set TZData(:Etc/GMT-0) $TZData(:Etc/GMT)
diff --git a/library/tzdata/Etc/GMT-1 b/library/tzdata/Etc/GMT-1
new file mode 100644
index 0000000..a44dd1f
--- /dev/null
+++ b/library/tzdata/Etc/GMT-1
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Etc/GMT-1) {
+    {-9223372036854775808 3600 0 GMT-1}
+}
diff --git a/library/tzdata/Etc/GMT-10 b/library/tzdata/Etc/GMT-10
new file mode 100644
index 0000000..1c50d01
--- /dev/null
+++ b/library/tzdata/Etc/GMT-10
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Etc/GMT-10) {
+    {-9223372036854775808 36000 0 GMT-10}
+}
diff --git a/library/tzdata/Etc/GMT-11 b/library/tzdata/Etc/GMT-11
new file mode 100644
index 0000000..d07710f
--- /dev/null
+++ b/library/tzdata/Etc/GMT-11
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Etc/GMT-11) {
+    {-9223372036854775808 39600 0 GMT-11}
+}
diff --git a/library/tzdata/Etc/GMT-12 b/library/tzdata/Etc/GMT-12
new file mode 100644
index 0000000..a23b98d
--- /dev/null
+++ b/library/tzdata/Etc/GMT-12
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Etc/GMT-12) {
+    {-9223372036854775808 43200 0 GMT-12}
+}
diff --git a/library/tzdata/Etc/GMT-13 b/library/tzdata/Etc/GMT-13
new file mode 100644
index 0000000..1a6700a
--- /dev/null
+++ b/library/tzdata/Etc/GMT-13
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Etc/GMT-13) {
+    {-9223372036854775808 46800 0 GMT-13}
+}
diff --git a/library/tzdata/Etc/GMT-14 b/library/tzdata/Etc/GMT-14
new file mode 100644
index 0000000..3707e21
--- /dev/null
+++ b/library/tzdata/Etc/GMT-14
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Etc/GMT-14) {
+    {-9223372036854775808 50400 0 GMT-14}
+}
diff --git a/library/tzdata/Etc/GMT-2 b/library/tzdata/Etc/GMT-2
new file mode 100644
index 0000000..f9dea16
--- /dev/null
+++ b/library/tzdata/Etc/GMT-2
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Etc/GMT-2) {
+    {-9223372036854775808 7200 0 GMT-2}
+}
diff --git a/library/tzdata/Etc/GMT-3 b/library/tzdata/Etc/GMT-3
new file mode 100644
index 0000000..99145b8
--- /dev/null
+++ b/library/tzdata/Etc/GMT-3
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Etc/GMT-3) {
+    {-9223372036854775808 10800 0 GMT-3}
+}
diff --git a/library/tzdata/Etc/GMT-4 b/library/tzdata/Etc/GMT-4
new file mode 100644
index 0000000..27b4fec
--- /dev/null
+++ b/library/tzdata/Etc/GMT-4
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Etc/GMT-4) {
+    {-9223372036854775808 14400 0 GMT-4}
+}
diff --git a/library/tzdata/Etc/GMT-5 b/library/tzdata/Etc/GMT-5
new file mode 100644
index 0000000..dbe3df7
--- /dev/null
+++ b/library/tzdata/Etc/GMT-5
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Etc/GMT-5) {
+    {-9223372036854775808 18000 0 GMT-5}
+}
diff --git a/library/tzdata/Etc/GMT-6 b/library/tzdata/Etc/GMT-6
new file mode 100644
index 0000000..414dbfa
--- /dev/null
+++ b/library/tzdata/Etc/GMT-6
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Etc/GMT-6) {
+    {-9223372036854775808 21600 0 GMT-6}
+}
diff --git a/library/tzdata/Etc/GMT-7 b/library/tzdata/Etc/GMT-7
new file mode 100644
index 0000000..2bd59db
--- /dev/null
+++ b/library/tzdata/Etc/GMT-7
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Etc/GMT-7) {
+    {-9223372036854775808 25200 0 GMT-7}
+}
diff --git a/library/tzdata/Etc/GMT-8 b/library/tzdata/Etc/GMT-8
new file mode 100644
index 0000000..7303721
--- /dev/null
+++ b/library/tzdata/Etc/GMT-8
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Etc/GMT-8) {
+    {-9223372036854775808 28800 0 GMT-8}
+}
diff --git a/library/tzdata/Etc/GMT-9 b/library/tzdata/Etc/GMT-9
new file mode 100644
index 0000000..46e6878
--- /dev/null
+++ b/library/tzdata/Etc/GMT-9
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Etc/GMT-9) {
+    {-9223372036854775808 32400 0 GMT-9}
+}
diff --git a/library/tzdata/Etc/GMT0 b/library/tzdata/Etc/GMT0
new file mode 100644
index 0000000..dba1fe9
--- /dev/null
+++ b/library/tzdata/Etc/GMT0
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Etc/GMT)]} {
+    LoadTimeZoneFile Etc/GMT
+}
+set TZData(:Etc/GMT0) $TZData(:Etc/GMT)
diff --git a/library/tzdata/Etc/Greenwich b/library/tzdata/Etc/Greenwich
new file mode 100644
index 0000000..53acea0
--- /dev/null
+++ b/library/tzdata/Etc/Greenwich
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Etc/GMT)]} {
+    LoadTimeZoneFile Etc/GMT
+}
+set TZData(:Etc/Greenwich) $TZData(:Etc/GMT)
diff --git a/library/tzdata/Etc/UCT b/library/tzdata/Etc/UCT
new file mode 100644
index 0000000..f7d795e
--- /dev/null
+++ b/library/tzdata/Etc/UCT
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Etc/UCT) {
+    {-9223372036854775808 0 0 UCT}
+}
diff --git a/library/tzdata/Etc/UTC b/library/tzdata/Etc/UTC
new file mode 100644
index 0000000..db5954b
--- /dev/null
+++ b/library/tzdata/Etc/UTC
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Etc/UTC) {
+    {-9223372036854775808 0 0 UTC}
+}
diff --git a/library/tzdata/Etc/Universal b/library/tzdata/Etc/Universal
new file mode 100644
index 0000000..a3b7547
--- /dev/null
+++ b/library/tzdata/Etc/Universal
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Etc/UTC)]} {
+    LoadTimeZoneFile Etc/UTC
+}
+set TZData(:Etc/Universal) $TZData(:Etc/UTC)
diff --git a/library/tzdata/Etc/Zulu b/library/tzdata/Etc/Zulu
new file mode 100644
index 0000000..f643db9
--- /dev/null
+++ b/library/tzdata/Etc/Zulu
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Etc/UTC)]} {
+    LoadTimeZoneFile Etc/UTC
+}
+set TZData(:Etc/Zulu) $TZData(:Etc/UTC)
diff --git a/library/tzdata/Europe/Amsterdam b/library/tzdata/Europe/Amsterdam
new file mode 100644
index 0000000..bd89127
--- /dev/null
+++ b/library/tzdata/Europe/Amsterdam
@@ -0,0 +1,310 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Europe/Amsterdam) {
+    {-9223372036854775808 1172 0 LMT}
+    {-4260212372 1172 0 AMT}
+    {-1693700372 4772 1 NST}
+    {-1680484772 1172 0 AMT}
+    {-1663453172 4772 1 NST}
+    {-1650147572 1172 0 AMT}
+    {-1633213172 4772 1 NST}
+    {-1617488372 1172 0 AMT}
+    {-1601158772 4772 1 NST}
+    {-1586038772 1172 0 AMT}
+    {-1569709172 4772 1 NST}
+    {-1554589172 1172 0 AMT}
+    {-1538259572 4772 1 NST}
+    {-1523139572 1172 0 AMT}
+    {-1507501172 4772 1 NST}
+    {-1490566772 1172 0 AMT}
+    {-1470176372 4772 1 NST}
+    {-1459117172 1172 0 AMT}
+    {-1443997172 4772 1 NST}
+    {-1427667572 1172 0 AMT}
+    {-1406672372 4772 1 NST}
+    {-1396217972 1172 0 AMT}
+    {-1376950772 4772 1 NST}
+    {-1364768372 1172 0 AMT}
+    {-1345414772 4772 1 NST}
+    {-1333318772 1172 0 AMT}
+    {-1313792372 4772 1 NST}
+    {-1301264372 1172 0 AMT}
+    {-1282256372 4772 1 NST}
+    {-1269814772 1172 0 AMT}
+    {-1250720372 4772 1 NST}
+    {-1238365172 1172 0 AMT}
+    {-1219184372 4772 1 NST}
+    {-1206915572 1172 0 AMT}
+    {-1186957172 4772 1 NST}
+    {-1175465972 1172 0 AMT}
+    {-1156025972 4772 1 NST}
+    {-1143411572 1172 0 AMT}
+    {-1124489972 4772 1 NST}
+    {-1111961972 1172 0 AMT}
+    {-1092953972 4772 1 NST}
+    {-1080512372 1172 0 AMT}
+    {-1061331572 4772 1 NST}
+    {-1049062772 1172 0 AMT}
+    {-1029190772 4772 1 NST}
+    {-1025741972 4800 0 NEST}
+    {-1017613200 1200 0 NET}
+    {-998259600 4800 1 NEST}
+    {-986163600 1200 0 NET}
+    {-966723600 4800 1 NEST}
+    {-954109200 1200 0 NET}
+    {-935022000 7200 0 CEST}
+    {-857257200 3600 0 CET}
+    {-844556400 7200 1 CEST}
+    {-828226800 3600 0 CET}
+    {-812502000 7200 1 CEST}
+    {-796777200 3600 0 CET}
+    {-781052400 7200 0 CEST}
+    {-766623600 3600 0 CET}
+    {220921200 3600 0 CET}
+    {228877200 7200 1 CEST}
+    {243997200 3600 0 CET}
+    {260326800 7200 1 CEST}
+    {276051600 3600 0 CET}
+    {291776400 7200 1 CEST}
+    {307501200 3600 0 CET}
+    {323830800 7200 1 CEST}
+    {338950800 3600 0 CET}
+    {354675600 7200 1 CEST}
+    {370400400 3600 0 CET}
+    {386125200 7200 1 CEST}
+    {401850000 3600 0 CET}
+    {417574800 7200 1 CEST}
+    {433299600 3600 0 CET}
+    {449024400 7200 1 CEST}
+    {465354000 3600 0 CET}
+    {481078800 7200 1 CEST}
+    {496803600 3600 0 CET}
+    {512528400 7200 1 CEST}
+    {528253200 3600 0 CET}
+    {543978000 7200 1 CEST}
+    {559702800 3600 0 CET}
+    {575427600 7200 1 CEST}
+    {591152400 3600 0 CET}
+    {606877200 7200 1 CEST}
+    {622602000 3600 0 CET}
+    {638326800 7200 1 CEST}
+    {654656400 3600 0 CET}
+    {670381200 7200 1 CEST}
+    {686106000 3600 0 CET}
+    {701830800 7200 1 CEST}
+    {717555600 3600 0 CET}
+    {733280400 7200 1 CEST}
+    {749005200 3600 0 CET}
+    {764730000 7200 1 CEST}
+    {780454800 3600 0 CET}
+    {796179600 7200 1 CEST}
+    {811904400 3600 0 CET}
+    {828234000 7200 1 CEST}
+    {846378000 3600 0 CET}
+    {859683600 7200 1 CEST}
+    {877827600 3600 0 CET}
+    {891133200 7200 1 CEST}
+    {909277200 3600 0 CET}
+    {922582800 7200 1 CEST}
+    {941331600 3600 0 CET}
+    {954032400 7200 1 CEST}
+    {972781200 3600 0 CET}
+    {985482000 7200 1 CEST}
+    {1004230800 3600 0 CET}
+    {1017536400 7200 1 CEST}
+    {1035680400 3600 0 CET}
+    {1048986000 7200 1 CEST}
+    {1067130000 3600 0 CET}
+    {1080435600 7200 1 CEST}
+    {1099184400 3600 0 CET}
+    {1111885200 7200 1 CEST}
+    {1130634000 3600 0 CET}
+    {1143334800 7200 1 CEST}
+    {1162083600 3600 0 CET}
+    {1174784400 7200 1 CEST}
+    {1193533200 3600 0 CET}
+    {1206838800 7200 1 CEST}
+    {1224982800 3600 0 CET}
+    {1238288400 7200 1 CEST}
+    {1256432400 3600 0 CET}
+    {1269738000 7200 1 CEST}
+    {1288486800 3600 0 CET}
+    {1301187600 7200 1 CEST}
+    {1319936400 3600 0 CET}
+    {1332637200 7200 1 CEST}
+    {1351386000 3600 0 CET}
+    {1364691600 7200 1 CEST}
+    {1382835600 3600 0 CET}
+    {1396141200 7200 1 CEST}
+    {1414285200 3600 0 CET}
+    {1427590800 7200 1 CEST}
+    {1445734800 3600 0 CET}
+    {1459040400 7200 1 CEST}
+    {1477789200 3600 0 CET}
+    {1490490000 7200 1 CEST}
+    {1509238800 3600 0 CET}
+    {1521939600 7200 1 CEST}
+    {1540688400 3600 0 CET}
+    {1553994000 7200 1 CEST}
+    {1572138000 3600 0 CET}
+    {1585443600 7200 1 CEST}
+    {1603587600 3600 0 CET}
+    {1616893200 7200 1 CEST}
+    {1635642000 3600 0 CET}
+    {1648342800 7200 1 CEST}
+    {1667091600 3600 0 CET}
+    {1679792400 7200 1 CEST}
+    {1698541200 3600 0 CET}
+    {1711846800 7200 1 CEST}
+    {1729990800 3600 0 CET}
+    {1743296400 7200 1 CEST}
+    {1761440400 3600 0 CET}
+    {1774746000 7200 1 CEST}
+    {1792890000 3600 0 CET}
+    {1806195600 7200 1 CEST}
+    {1824944400 3600 0 CET}
+    {1837645200 7200 1 CEST}
+    {1856394000 3600 0 CET}
+    {1869094800 7200 1 CEST}
+    {1887843600 3600 0 CET}
+    {1901149200 7200 1 CEST}
+    {1919293200 3600 0 CET}
+    {1932598800 7200 1 CEST}
+    {1950742800 3600 0 CET}
+    {1964048400 7200 1 CEST}
+    {1982797200 3600 0 CET}
+    {1995498000 7200 1 CEST}
+    {2014246800 3600 0 CET}
+    {2026947600 7200 1 CEST}
+    {2045696400 3600 0 CET}
+    {2058397200 7200 1 CEST}
+    {2077146000 3600 0 CET}
+    {2090451600 7200 1 CEST}
+    {2108595600 3600 0 CET}
+    {2121901200 7200 1 CEST}
+    {2140045200 3600 0 CET}
+    {2153350800 7200 1 CEST}
+    {2172099600 3600 0 CET}
+    {2184800400 7200 1 CEST}
+    {2203549200 3600 0 CET}
+    {2216250000 7200 1 CEST}
+    {2234998800 3600 0 CET}
+    {2248304400 7200 1 CEST}
+    {2266448400 3600 0 CET}
+    {2279754000 7200 1 CEST}
+    {2297898000 3600 0 CET}
+    {2311203600 7200 1 CEST}
+    {2329347600 3600 0 CET}
+    {2342653200 7200 1 CEST}
+    {2361402000 3600 0 CET}
+    {2374102800 7200 1 CEST}
+    {2392851600 3600 0 CET}
+    {2405552400 7200 1 CEST}
+    {2424301200 3600 0 CET}
+    {2437606800 7200 1 CEST}
+    {2455750800 3600 0 CET}
+    {2469056400 7200 1 CEST}
+    {2487200400 3600 0 CET}
+    {2500506000 7200 1 CEST}
+    {2519254800 3600 0 CET}
+    {2531955600 7200 1 CEST}
+    {2550704400 3600 0 CET}
+    {2563405200 7200 1 CEST}
+    {2582154000 3600 0 CET}
+    {2595459600 7200 1 CEST}
+    {2613603600 3600 0 CET}
+    {2626909200 7200 1 CEST}
+    {2645053200 3600 0 CET}
+    {2658358800 7200 1 CEST}
+    {2676502800 3600 0 CET}
+    {2689808400 7200 1 CEST}
+    {2708557200 3600 0 CET}
+    {2721258000 7200 1 CEST}
+    {2740006800 3600 0 CET}
+    {2752707600 7200 1 CEST}
+    {2771456400 3600 0 CET}
+    {2784762000 7200 1 CEST}
+    {2802906000 3600 0 CET}
+    {2816211600 7200 1 CEST}
+    {2834355600 3600 0 CET}
+    {2847661200 7200 1 CEST}
+    {2866410000 3600 0 CET}
+    {2879110800 7200 1 CEST}
+    {2897859600 3600 0 CET}
+    {2910560400 7200 1 CEST}
+    {2929309200 3600 0 CET}
+    {2942010000 7200 1 CEST}
+    {2960758800 3600 0 CET}
+    {2974064400 7200 1 CEST}
+    {2992208400 3600 0 CET}
+    {3005514000 7200 1 CEST}
+    {3023658000 3600 0 CET}
+    {3036963600 7200 1 CEST}
+    {3055712400 3600 0 CET}
+    {3068413200 7200 1 CEST}
+    {3087162000 3600 0 CET}
+    {3099862800 7200 1 CEST}
+    {3118611600 3600 0 CET}
+    {3131917200 7200 1 CEST}
+    {3150061200 3600 0 CET}
+    {3163366800 7200 1 CEST}
+    {3181510800 3600 0 CET}
+    {3194816400 7200 1 CEST}
+    {3212960400 3600 0 CET}
+    {3226266000 7200 1 CEST}
+    {3245014800 3600 0 CET}
+    {3257715600 7200 1 CEST}
+    {3276464400 3600 0 CET}
+    {3289165200 7200 1 CEST}
+    {3307914000 3600 0 CET}
+    {3321219600 7200 1 CEST}
+    {3339363600 3600 0 CET}
+    {3352669200 7200 1 CEST}
+    {3370813200 3600 0 CET}
+    {3384118800 7200 1 CEST}
+    {3402867600 3600 0 CET}
+    {3415568400 7200 1 CEST}
+    {3434317200 3600 0 CET}
+    {3447018000 7200 1 CEST}
+    {3465766800 3600 0 CET}
+    {3479072400 7200 1 CEST}
+    {3497216400 3600 0 CET}
+    {3510522000 7200 1 CEST}
+    {3528666000 3600 0 CET}
+    {3541971600 7200 1 CEST}
+    {3560115600 3600 0 CET}
+    {3573421200 7200 1 CEST}
+    {3592170000 3600 0 CET}
+    {3604870800 7200 1 CEST}
+    {3623619600 3600 0 CET}
+    {3636320400 7200 1 CEST}
+    {3655069200 3600 0 CET}
+    {3668374800 7200 1 CEST}
+    {3686518800 3600 0 CET}
+    {3699824400 7200 1 CEST}
+    {3717968400 3600 0 CET}
+    {3731274000 7200 1 CEST}
+    {3750022800 3600 0 CET}
+    {3762723600 7200 1 CEST}
+    {3781472400 3600 0 CET}
+    {3794173200 7200 1 CEST}
+    {3812922000 3600 0 CET}
+    {3825622800 7200 1 CEST}
+    {3844371600 3600 0 CET}
+    {3857677200 7200 1 CEST}
+    {3875821200 3600 0 CET}
+    {3889126800 7200 1 CEST}
+    {3907270800 3600 0 CET}
+    {3920576400 7200 1 CEST}
+    {3939325200 3600 0 CET}
+    {3952026000 7200 1 CEST}
+    {3970774800 3600 0 CET}
+    {3983475600 7200 1 CEST}
+    {4002224400 3600 0 CET}
+    {4015530000 7200 1 CEST}
+    {4033674000 3600 0 CET}
+    {4046979600 7200 1 CEST}
+    {4065123600 3600 0 CET}
+    {4078429200 7200 1 CEST}
+    {4096573200 3600 0 CET}
+}
diff --git a/library/tzdata/Europe/Andorra b/library/tzdata/Europe/Andorra
new file mode 100644
index 0000000..89233fe
--- /dev/null
+++ b/library/tzdata/Europe/Andorra
@@ -0,0 +1,237 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Europe/Andorra) {
+    {-9223372036854775808 364 0 LMT}
+    {-2177453164 0 0 WET}
+    {-733881600 3600 0 CET}
+    {481078800 7200 0 CEST}
+    {496803600 3600 0 CET}
+    {512528400 7200 1 CEST}
+    {528253200 3600 0 CET}
+    {543978000 7200 1 CEST}
+    {559702800 3600 0 CET}
+    {575427600 7200 1 CEST}
+    {591152400 3600 0 CET}
+    {606877200 7200 1 CEST}
+    {622602000 3600 0 CET}
+    {638326800 7200 1 CEST}
+    {654656400 3600 0 CET}
+    {670381200 7200 1 CEST}
+    {686106000 3600 0 CET}
+    {701830800 7200 1 CEST}
+    {717555600 3600 0 CET}
+    {733280400 7200 1 CEST}
+    {749005200 3600 0 CET}
+    {764730000 7200 1 CEST}
+    {780454800 3600 0 CET}
+    {796179600 7200 1 CEST}
+    {811904400 3600 0 CET}
+    {828234000 7200 1 CEST}
+    {846378000 3600 0 CET}
+    {859683600 7200 1 CEST}
+    {877827600 3600 0 CET}
+    {891133200 7200 1 CEST}
+    {909277200 3600 0 CET}
+    {922582800 7200 1 CEST}
+    {941331600 3600 0 CET}
+    {954032400 7200 1 CEST}
+    {972781200 3600 0 CET}
+    {985482000 7200 1 CEST}
+    {1004230800 3600 0 CET}
+    {1017536400 7200 1 CEST}
+    {1035680400 3600 0 CET}
+    {1048986000 7200 1 CEST}
+    {1067130000 3600 0 CET}
+    {1080435600 7200 1 CEST}
+    {1099184400 3600 0 CET}
+    {1111885200 7200 1 CEST}
+    {1130634000 3600 0 CET}
+    {1143334800 7200 1 CEST}
+    {1162083600 3600 0 CET}
+    {1174784400 7200 1 CEST}
+    {1193533200 3600 0 CET}
+    {1206838800 7200 1 CEST}
+    {1224982800 3600 0 CET}
+    {1238288400 7200 1 CEST}
+    {1256432400 3600 0 CET}
+    {1269738000 7200 1 CEST}
+    {1288486800 3600 0 CET}
+    {1301187600 7200 1 CEST}
+    {1319936400 3600 0 CET}
+    {1332637200 7200 1 CEST}
+    {1351386000 3600 0 CET}
+    {1364691600 7200 1 CEST}
+    {1382835600 3600 0 CET}
+    {1396141200 7200 1 CEST}
+    {1414285200 3600 0 CET}
+    {1427590800 7200 1 CEST}
+    {1445734800 3600 0 CET}
+    {1459040400 7200 1 CEST}
+    {1477789200 3600 0 CET}
+    {1490490000 7200 1 CEST}
+    {1509238800 3600 0 CET}
+    {1521939600 7200 1 CEST}
+    {1540688400 3600 0 CET}
+    {1553994000 7200 1 CEST}
+    {1572138000 3600 0 CET}
+    {1585443600 7200 1 CEST}
+    {1603587600 3600 0 CET}
+    {1616893200 7200 1 CEST}
+    {1635642000 3600 0 CET}
+    {1648342800 7200 1 CEST}
+    {1667091600 3600 0 CET}
+    {1679792400 7200 1 CEST}
+    {1698541200 3600 0 CET}
+    {1711846800 7200 1 CEST}
+    {1729990800 3600 0 CET}
+    {1743296400 7200 1 CEST}
+    {1761440400 3600 0 CET}
+    {1774746000 7200 1 CEST}
+    {1792890000 3600 0 CET}
+    {1806195600 7200 1 CEST}
+    {1824944400 3600 0 CET}
+    {1837645200 7200 1 CEST}
+    {1856394000 3600 0 CET}
+    {1869094800 7200 1 CEST}
+    {1887843600 3600 0 CET}
+    {1901149200 7200 1 CEST}
+    {1919293200 3600 0 CET}
+    {1932598800 7200 1 CEST}
+    {1950742800 3600 0 CET}
+    {1964048400 7200 1 CEST}
+    {1982797200 3600 0 CET}
+    {1995498000 7200 1 CEST}
+    {2014246800 3600 0 CET}
+    {2026947600 7200 1 CEST}
+    {2045696400 3600 0 CET}
+    {2058397200 7200 1 CEST}
+    {2077146000 3600 0 CET}
+    {2090451600 7200 1 CEST}
+    {2108595600 3600 0 CET}
+    {2121901200 7200 1 CEST}
+    {2140045200 3600 0 CET}
+    {2153350800 7200 1 CEST}
+    {2172099600 3600 0 CET}
+    {2184800400 7200 1 CEST}
+    {2203549200 3600 0 CET}
+    {2216250000 7200 1 CEST}
+    {2234998800 3600 0 CET}
+    {2248304400 7200 1 CEST}
+    {2266448400 3600 0 CET}
+    {2279754000 7200 1 CEST}
+    {2297898000 3600 0 CET}
+    {2311203600 7200 1 CEST}
+    {2329347600 3600 0 CET}
+    {2342653200 7200 1 CEST}
+    {2361402000 3600 0 CET}
+    {2374102800 7200 1 CEST}
+    {2392851600 3600 0 CET}
+    {2405552400 7200 1 CEST}
+    {2424301200 3600 0 CET}
+    {2437606800 7200 1 CEST}
+    {2455750800 3600 0 CET}
+    {2469056400 7200 1 CEST}
+    {2487200400 3600 0 CET}
+    {2500506000 7200 1 CEST}
+    {2519254800 3600 0 CET}
+    {2531955600 7200 1 CEST}
+    {2550704400 3600 0 CET}
+    {2563405200 7200 1 CEST}
+    {2582154000 3600 0 CET}
+    {2595459600 7200 1 CEST}
+    {2613603600 3600 0 CET}
+    {2626909200 7200 1 CEST}
+    {2645053200 3600 0 CET}
+    {2658358800 7200 1 CEST}
+    {2676502800 3600 0 CET}
+    {2689808400 7200 1 CEST}
+    {2708557200 3600 0 CET}
+    {2721258000 7200 1 CEST}
+    {2740006800 3600 0 CET}
+    {2752707600 7200 1 CEST}
+    {2771456400 3600 0 CET}
+    {2784762000 7200 1 CEST}
+    {2802906000 3600 0 CET}
+    {2816211600 7200 1 CEST}
+    {2834355600 3600 0 CET}
+    {2847661200 7200 1 CEST}
+    {2866410000 3600 0 CET}
+    {2879110800 7200 1 CEST}
+    {2897859600 3600 0 CET}
+    {2910560400 7200 1 CEST}
+    {2929309200 3600 0 CET}
+    {2942010000 7200 1 CEST}
+    {2960758800 3600 0 CET}
+    {2974064400 7200 1 CEST}
+    {2992208400 3600 0 CET}
+    {3005514000 7200 1 CEST}
+    {3023658000 3600 0 CET}
+    {3036963600 7200 1 CEST}
+    {3055712400 3600 0 CET}
+    {3068413200 7200 1 CEST}
+    {3087162000 3600 0 CET}
+    {3099862800 7200 1 CEST}
+    {3118611600 3600 0 CET}
+    {3131917200 7200 1 CEST}
+    {3150061200 3600 0 CET}
+    {3163366800 7200 1 CEST}
+    {3181510800 3600 0 CET}
+    {3194816400 7200 1 CEST}
+    {3212960400 3600 0 CET}
+    {3226266000 7200 1 CEST}
+    {3245014800 3600 0 CET}
+    {3257715600 7200 1 CEST}
+    {3276464400 3600 0 CET}
+    {3289165200 7200 1 CEST}
+    {3307914000 3600 0 CET}
+    {3321219600 7200 1 CEST}
+    {3339363600 3600 0 CET}
+    {3352669200 7200 1 CEST}
+    {3370813200 3600 0 CET}
+    {3384118800 7200 1 CEST}
+    {3402867600 3600 0 CET}
+    {3415568400 7200 1 CEST}
+    {3434317200 3600 0 CET}
+    {3447018000 7200 1 CEST}
+    {3465766800 3600 0 CET}
+    {3479072400 7200 1 CEST}
+    {3497216400 3600 0 CET}
+    {3510522000 7200 1 CEST}
+    {3528666000 3600 0 CET}
+    {3541971600 7200 1 CEST}
+    {3560115600 3600 0 CET}
+    {3573421200 7200 1 CEST}
+    {3592170000 3600 0 CET}
+    {3604870800 7200 1 CEST}
+    {3623619600 3600 0 CET}
+    {3636320400 7200 1 CEST}
+    {3655069200 3600 0 CET}
+    {3668374800 7200 1 CEST}
+    {3686518800 3600 0 CET}
+    {3699824400 7200 1 CEST}
+    {3717968400 3600 0 CET}
+    {3731274000 7200 1 CEST}
+    {3750022800 3600 0 CET}
+    {3762723600 7200 1 CEST}
+    {3781472400 3600 0 CET}
+    {3794173200 7200 1 CEST}
+    {3812922000 3600 0 CET}
+    {3825622800 7200 1 CEST}
+    {3844371600 3600 0 CET}
+    {3857677200 7200 1 CEST}
+    {3875821200 3600 0 CET}
+    {3889126800 7200 1 CEST}
+    {3907270800 3600 0 CET}
+    {3920576400 7200 1 CEST}
+    {3939325200 3600 0 CET}
+    {3952026000 7200 1 CEST}
+    {3970774800 3600 0 CET}
+    {3983475600 7200 1 CEST}
+    {4002224400 3600 0 CET}
+    {4015530000 7200 1 CEST}
+    {4033674000 3600 0 CET}
+    {4046979600 7200 1 CEST}
+    {4065123600 3600 0 CET}
+    {4078429200 7200 1 CEST}
+    {4096573200 3600 0 CET}
+}
diff --git a/library/tzdata/Europe/Astrakhan b/library/tzdata/Europe/Astrakhan
new file mode 100644
index 0000000..9881bb8
--- /dev/null
+++ b/library/tzdata/Europe/Astrakhan
@@ -0,0 +1,71 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Europe/Astrakhan) {
+    {-9223372036854775808 11532 0 LMT}
+    {-1441249932 10800 0 +03}
+    {-1247540400 14400 0 +05}
+    {354916800 18000 1 +05}
+    {370724400 14400 0 +04}
+    {386452800 18000 1 +05}
+    {402260400 14400 0 +04}
+    {417988800 18000 1 +05}
+    {433796400 14400 0 +04}
+    {449611200 18000 1 +05}
+    {465343200 14400 0 +04}
+    {481068000 18000 1 +05}
+    {496792800 14400 0 +04}
+    {512517600 18000 1 +05}
+    {528242400 14400 0 +04}
+    {543967200 18000 1 +05}
+    {559692000 14400 0 +04}
+    {575416800 18000 1 +05}
+    {591141600 14400 0 +04}
+    {606866400 10800 0 +04}
+    {606870000 14400 1 +04}
+    {622594800 10800 0 +03}
+    {638319600 14400 1 +04}
+    {654649200 10800 0 +03}
+    {670374000 14400 0 +04}
+    {701820000 10800 0 +04}
+    {701823600 14400 1 +04}
+    {717548400 10800 0 +03}
+    {733273200 14400 1 +04}
+    {748998000 10800 0 +03}
+    {764722800 14400 1 +04}
+    {780447600 10800 0 +03}
+    {796172400 14400 1 +04}
+    {811897200 10800 0 +03}
+    {828226800 14400 1 +04}
+    {846370800 10800 0 +03}
+    {859676400 14400 1 +04}
+    {877820400 10800 0 +03}
+    {891126000 14400 1 +04}
+    {909270000 10800 0 +03}
+    {922575600 14400 1 +04}
+    {941324400 10800 0 +03}
+    {954025200 14400 1 +04}
+    {972774000 10800 0 +03}
+    {985474800 14400 1 +04}
+    {1004223600 10800 0 +03}
+    {1017529200 14400 1 +04}
+    {1035673200 10800 0 +03}
+    {1048978800 14400 1 +04}
+    {1067122800 10800 0 +03}
+    {1080428400 14400 1 +04}
+    {1099177200 10800 0 +03}
+    {1111878000 14400 1 +04}
+    {1130626800 10800 0 +03}
+    {1143327600 14400 1 +04}
+    {1162076400 10800 0 +03}
+    {1174777200 14400 1 +04}
+    {1193526000 10800 0 +03}
+    {1206831600 14400 1 +04}
+    {1224975600 10800 0 +03}
+    {1238281200 14400 1 +04}
+    {1256425200 10800 0 +03}
+    {1269730800 14400 1 +04}
+    {1288479600 10800 0 +03}
+    {1301180400 14400 0 +04}
+    {1414274400 10800 0 +03}
+    {1459033200 14400 0 +04}
+}
diff --git a/library/tzdata/Europe/Athens b/library/tzdata/Europe/Athens
new file mode 100644
index 0000000..f8df408
--- /dev/null
+++ b/library/tzdata/Europe/Athens
@@ -0,0 +1,268 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Europe/Athens) {
+    {-9223372036854775808 5692 0 LMT}
+    {-2344642492 5692 0 AMT}
+    {-1686101632 7200 0 EET}
+    {-1182996000 10800 1 EEST}
+    {-1178161200 7200 0 EET}
+    {-906861600 10800 1 EEST}
+    {-904878000 7200 0 CEST}
+    {-857257200 3600 0 CET}
+    {-844477200 7200 1 CEST}
+    {-828237600 3600 0 CET}
+    {-812422800 7200 0 EET}
+    {-552362400 10800 1 EEST}
+    {-541652400 7200 0 EET}
+    {166485600 10800 1 EEST}
+    {186184800 7200 0 EET}
+    {198028800 10800 1 EEST}
+    {213753600 7200 0 EET}
+    {228873600 10800 1 EEST}
+    {244080000 7200 0 EET}
+    {260323200 10800 1 EEST}
+    {275446800 7200 0 EET}
+    {291798000 10800 1 EEST}
+    {307407600 7200 0 EET}
+    {323388000 10800 1 EEST}
+    {338936400 7200 0 EET}
+    {347148000 7200 0 EET}
+    {354675600 10800 1 EEST}
+    {370400400 7200 0 EET}
+    {386125200 10800 1 EEST}
+    {401850000 7200 0 EET}
+    {417574800 10800 1 EEST}
+    {433299600 7200 0 EET}
+    {449024400 10800 1 EEST}
+    {465354000 7200 0 EET}
+    {481078800 10800 1 EEST}
+    {496803600 7200 0 EET}
+    {512528400 10800 1 EEST}
+    {528253200 7200 0 EET}
+    {543978000 10800 1 EEST}
+    {559702800 7200 0 EET}
+    {575427600 10800 1 EEST}
+    {591152400 7200 0 EET}
+    {606877200 10800 1 EEST}
+    {622602000 7200 0 EET}
+    {638326800 10800 1 EEST}
+    {654656400 7200 0 EET}
+    {670381200 10800 1 EEST}
+    {686106000 7200 0 EET}
+    {701830800 10800 1 EEST}
+    {717555600 7200 0 EET}
+    {733280400 10800 1 EEST}
+    {749005200 7200 0 EET}
+    {764730000 10800 1 EEST}
+    {780454800 7200 0 EET}
+    {796179600 10800 1 EEST}
+    {811904400 7200 0 EET}
+    {828234000 10800 1 EEST}
+    {846378000 7200 0 EET}
+    {859683600 10800 1 EEST}
+    {877827600 7200 0 EET}
+    {891133200 10800 1 EEST}
+    {909277200 7200 0 EET}
+    {922582800 10800 1 EEST}
+    {941331600 7200 0 EET}
+    {954032400 10800 1 EEST}
+    {972781200 7200 0 EET}
+    {985482000 10800 1 EEST}
+    {1004230800 7200 0 EET}
+    {1017536400 10800 1 EEST}
+    {1035680400 7200 0 EET}
+    {1048986000 10800 1 EEST}
+    {1067130000 7200 0 EET}
+    {1080435600 10800 1 EEST}
+    {1099184400 7200 0 EET}
+    {1111885200 10800 1 EEST}
+    {1130634000 7200 0 EET}
+    {1143334800 10800 1 EEST}
+    {1162083600 7200 0 EET}
+    {1174784400 10800 1 EEST}
+    {1193533200 7200 0 EET}
+    {1206838800 10800 1 EEST}
+    {1224982800 7200 0 EET}
+    {1238288400 10800 1 EEST}
+    {1256432400 7200 0 EET}
+    {1269738000 10800 1 EEST}
+    {1288486800 7200 0 EET}
+    {1301187600 10800 1 EEST}
+    {1319936400 7200 0 EET}
+    {1332637200 10800 1 EEST}
+    {1351386000 7200 0 EET}
+    {1364691600 10800 1 EEST}
+    {1382835600 7200 0 EET}
+    {1396141200 10800 1 EEST}
+    {1414285200 7200 0 EET}
+    {1427590800 10800 1 EEST}
+    {1445734800 7200 0 EET}
+    {1459040400 10800 1 EEST}
+    {1477789200 7200 0 EET}
+    {1490490000 10800 1 EEST}
+    {1509238800 7200 0 EET}
+    {1521939600 10800 1 EEST}
+    {1540688400 7200 0 EET}
+    {1553994000 10800 1 EEST}
+    {1572138000 7200 0 EET}
+    {1585443600 10800 1 EEST}
+    {1603587600 7200 0 EET}
+    {1616893200 10800 1 EEST}
+    {1635642000 7200 0 EET}
+    {1648342800 10800 1 EEST}
+    {1667091600 7200 0 EET}
+    {1679792400 10800 1 EEST}
+    {1698541200 7200 0 EET}
+    {1711846800 10800 1 EEST}
+    {1729990800 7200 0 EET}
+    {1743296400 10800 1 EEST}
+    {1761440400 7200 0 EET}
+    {1774746000 10800 1 EEST}
+    {1792890000 7200 0 EET}
+    {1806195600 10800 1 EEST}
+    {1824944400 7200 0 EET}
+    {1837645200 10800 1 EEST}
+    {1856394000 7200 0 EET}
+    {1869094800 10800 1 EEST}
+    {1887843600 7200 0 EET}
+    {1901149200 10800 1 EEST}
+    {1919293200 7200 0 EET}
+    {1932598800 10800 1 EEST}
+    {1950742800 7200 0 EET}
+    {1964048400 10800 1 EEST}
+    {1982797200 7200 0 EET}
+    {1995498000 10800 1 EEST}
+    {2014246800 7200 0 EET}
+    {2026947600 10800 1 EEST}
+    {2045696400 7200 0 EET}
+    {2058397200 10800 1 EEST}
+    {2077146000 7200 0 EET}
+    {2090451600 10800 1 EEST}
+    {2108595600 7200 0 EET}
+    {2121901200 10800 1 EEST}
+    {2140045200 7200 0 EET}
+    {2153350800 10800 1 EEST}
+    {2172099600 7200 0 EET}
+    {2184800400 10800 1 EEST}
+    {2203549200 7200 0 EET}
+    {2216250000 10800 1 EEST}
+    {2234998800 7200 0 EET}
+    {2248304400 10800 1 EEST}
+    {2266448400 7200 0 EET}
+    {2279754000 10800 1 EEST}
+    {2297898000 7200 0 EET}
+    {2311203600 10800 1 EEST}
+    {2329347600 7200 0 EET}
+    {2342653200 10800 1 EEST}
+    {2361402000 7200 0 EET}
+    {2374102800 10800 1 EEST}
+    {2392851600 7200 0 EET}
+    {2405552400 10800 1 EEST}
+    {2424301200 7200 0 EET}
+    {2437606800 10800 1 EEST}
+    {2455750800 7200 0 EET}
+    {2469056400 10800 1 EEST}
+    {2487200400 7200 0 EET}
+    {2500506000 10800 1 EEST}
+    {2519254800 7200 0 EET}
+    {2531955600 10800 1 EEST}
+    {2550704400 7200 0 EET}
+    {2563405200 10800 1 EEST}
+    {2582154000 7200 0 EET}
+    {2595459600 10800 1 EEST}
+    {2613603600 7200 0 EET}
+    {2626909200 10800 1 EEST}
+    {2645053200 7200 0 EET}
+    {2658358800 10800 1 EEST}
+    {2676502800 7200 0 EET}
+    {2689808400 10800 1 EEST}
+    {2708557200 7200 0 EET}
+    {2721258000 10800 1 EEST}
+    {2740006800 7200 0 EET}
+    {2752707600 10800 1 EEST}
+    {2771456400 7200 0 EET}
+    {2784762000 10800 1 EEST}
+    {2802906000 7200 0 EET}
+    {2816211600 10800 1 EEST}
+    {2834355600 7200 0 EET}
+    {2847661200 10800 1 EEST}
+    {2866410000 7200 0 EET}
+    {2879110800 10800 1 EEST}
+    {2897859600 7200 0 EET}
+    {2910560400 10800 1 EEST}
+    {2929309200 7200 0 EET}
+    {2942010000 10800 1 EEST}
+    {2960758800 7200 0 EET}
+    {2974064400 10800 1 EEST}
+    {2992208400 7200 0 EET}
+    {3005514000 10800 1 EEST}
+    {3023658000 7200 0 EET}
+    {3036963600 10800 1 EEST}
+    {3055712400 7200 0 EET}
+    {3068413200 10800 1 EEST}
+    {3087162000 7200 0 EET}
+    {3099862800 10800 1 EEST}
+    {3118611600 7200 0 EET}
+    {3131917200 10800 1 EEST}
+    {3150061200 7200 0 EET}
+    {3163366800 10800 1 EEST}
+    {3181510800 7200 0 EET}
+    {3194816400 10800 1 EEST}
+    {3212960400 7200 0 EET}
+    {3226266000 10800 1 EEST}
+    {3245014800 7200 0 EET}
+    {3257715600 10800 1 EEST}
+    {3276464400 7200 0 EET}
+    {3289165200 10800 1 EEST}
+    {3307914000 7200 0 EET}
+    {3321219600 10800 1 EEST}
+    {3339363600 7200 0 EET}
+    {3352669200 10800 1 EEST}
+    {3370813200 7200 0 EET}
+    {3384118800 10800 1 EEST}
+    {3402867600 7200 0 EET}
+    {3415568400 10800 1 EEST}
+    {3434317200 7200 0 EET}
+    {3447018000 10800 1 EEST}
+    {3465766800 7200 0 EET}
+    {3479072400 10800 1 EEST}
+    {3497216400 7200 0 EET}
+    {3510522000 10800 1 EEST}
+    {3528666000 7200 0 EET}
+    {3541971600 10800 1 EEST}
+    {3560115600 7200 0 EET}
+    {3573421200 10800 1 EEST}
+    {3592170000 7200 0 EET}
+    {3604870800 10800 1 EEST}
+    {3623619600 7200 0 EET}
+    {3636320400 10800 1 EEST}
+    {3655069200 7200 0 EET}
+    {3668374800 10800 1 EEST}
+    {3686518800 7200 0 EET}
+    {3699824400 10800 1 EEST}
+    {3717968400 7200 0 EET}
+    {3731274000 10800 1 EEST}
+    {3750022800 7200 0 EET}
+    {3762723600 10800 1 EEST}
+    {3781472400 7200 0 EET}
+    {3794173200 10800 1 EEST}
+    {3812922000 7200 0 EET}
+    {3825622800 10800 1 EEST}
+    {3844371600 7200 0 EET}
+    {3857677200 10800 1 EEST}
+    {3875821200 7200 0 EET}
+    {3889126800 10800 1 EEST}
+    {3907270800 7200 0 EET}
+    {3920576400 10800 1 EEST}
+    {3939325200 7200 0 EET}
+    {3952026000 10800 1 EEST}
+    {3970774800 7200 0 EET}
+    {3983475600 10800 1 EEST}
+    {4002224400 7200 0 EET}
+    {4015530000 10800 1 EEST}
+    {4033674000 7200 0 EET}
+    {4046979600 10800 1 EEST}
+    {4065123600 7200 0 EET}
+    {4078429200 10800 1 EEST}
+    {4096573200 7200 0 EET}
+}
diff --git a/library/tzdata/Europe/Belfast b/library/tzdata/Europe/Belfast
new file mode 100644
index 0000000..51cd3ce
--- /dev/null
+++ b/library/tzdata/Europe/Belfast
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Europe/London)]} {
+    LoadTimeZoneFile Europe/London
+}
+set TZData(:Europe/Belfast) $TZData(:Europe/London)
diff --git a/library/tzdata/Europe/Belgrade b/library/tzdata/Europe/Belgrade
new file mode 100644
index 0000000..b11f7b3
--- /dev/null
+++ b/library/tzdata/Europe/Belgrade
@@ -0,0 +1,250 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Europe/Belgrade) {
+    {-9223372036854775808 4920 0 LMT}
+    {-2713915320 3600 0 CET}
+    {-905824800 3600 0 CET}
+    {-857257200 3600 0 CET}
+    {-844556400 7200 1 CEST}
+    {-828226800 3600 0 CET}
+    {-812502000 7200 1 CEST}
+    {-796777200 3600 0 CET}
+    {-788922000 3600 0 CET}
+    {-777942000 7200 1 CEST}
+    {-766623600 3600 0 CET}
+    {407199600 3600 0 CET}
+    {417574800 7200 1 CEST}
+    {433299600 3600 0 CET}
+    {449024400 7200 1 CEST}
+    {465354000 3600 0 CET}
+    {481078800 7200 1 CEST}
+    {496803600 3600 0 CET}
+    {512528400 7200 1 CEST}
+    {528253200 3600 0 CET}
+    {543978000 7200 1 CEST}
+    {559702800 3600 0 CET}
+    {575427600 7200 1 CEST}
+    {591152400 3600 0 CET}
+    {606877200 7200 1 CEST}
+    {622602000 3600 0 CET}
+    {638326800 7200 1 CEST}
+    {654656400 3600 0 CET}
+    {670381200 7200 1 CEST}
+    {686106000 3600 0 CET}
+    {701830800 7200 1 CEST}
+    {717555600 3600 0 CET}
+    {733280400 7200 1 CEST}
+    {749005200 3600 0 CET}
+    {764730000 7200 1 CEST}
+    {780454800 3600 0 CET}
+    {796179600 7200 1 CEST}
+    {811904400 3600 0 CET}
+    {828234000 7200 1 CEST}
+    {846378000 3600 0 CET}
+    {859683600 7200 1 CEST}
+    {877827600 3600 0 CET}
+    {891133200 7200 1 CEST}
+    {909277200 3600 0 CET}
+    {922582800 7200 1 CEST}
+    {941331600 3600 0 CET}
+    {954032400 7200 1 CEST}
+    {972781200 3600 0 CET}
+    {985482000 7200 1 CEST}
+    {1004230800 3600 0 CET}
+    {1017536400 7200 1 CEST}
+    {1035680400 3600 0 CET}
+    {1048986000 7200 1 CEST}
+    {1067130000 3600 0 CET}
+    {1080435600 7200 1 CEST}
+    {1099184400 3600 0 CET}
+    {1111885200 7200 1 CEST}
+    {1130634000 3600 0 CET}
+    {1143334800 7200 1 CEST}
+    {1162083600 3600 0 CET}
+    {1174784400 7200 1 CEST}
+    {1193533200 3600 0 CET}
+    {1206838800 7200 1 CEST}
+    {1224982800 3600 0 CET}
+    {1238288400 7200 1 CEST}
+    {1256432400 3600 0 CET}
+    {1269738000 7200 1 CEST}
+    {1288486800 3600 0 CET}
+    {1301187600 7200 1 CEST}
+    {1319936400 3600 0 CET}
+    {1332637200 7200 1 CEST}
+    {1351386000 3600 0 CET}
+    {1364691600 7200 1 CEST}
+    {1382835600 3600 0 CET}
+    {1396141200 7200 1 CEST}
+    {1414285200 3600 0 CET}
+    {1427590800 7200 1 CEST}
+    {1445734800 3600 0 CET}
+    {1459040400 7200 1 CEST}
+    {1477789200 3600 0 CET}
+    {1490490000 7200 1 CEST}
+    {1509238800 3600 0 CET}
+    {1521939600 7200 1 CEST}
+    {1540688400 3600 0 CET}
+    {1553994000 7200 1 CEST}
+    {1572138000 3600 0 CET}
+    {1585443600 7200 1 CEST}
+    {1603587600 3600 0 CET}
+    {1616893200 7200 1 CEST}
+    {1635642000 3600 0 CET}
+    {1648342800 7200 1 CEST}
+    {1667091600 3600 0 CET}
+    {1679792400 7200 1 CEST}
+    {1698541200 3600 0 CET}
+    {1711846800 7200 1 CEST}
+    {1729990800 3600 0 CET}
+    {1743296400 7200 1 CEST}
+    {1761440400 3600 0 CET}
+    {1774746000 7200 1 CEST}
+    {1792890000 3600 0 CET}
+    {1806195600 7200 1 CEST}
+    {1824944400 3600 0 CET}
+    {1837645200 7200 1 CEST}
+    {1856394000 3600 0 CET}
+    {1869094800 7200 1 CEST}
+    {1887843600 3600 0 CET}
+    {1901149200 7200 1 CEST}
+    {1919293200 3600 0 CET}
+    {1932598800 7200 1 CEST}
+    {1950742800 3600 0 CET}
+    {1964048400 7200 1 CEST}
+    {1982797200 3600 0 CET}
+    {1995498000 7200 1 CEST}
+    {2014246800 3600 0 CET}
+    {2026947600 7200 1 CEST}
+    {2045696400 3600 0 CET}
+    {2058397200 7200 1 CEST}
+    {2077146000 3600 0 CET}
+    {2090451600 7200 1 CEST}
+    {2108595600 3600 0 CET}
+    {2121901200 7200 1 CEST}
+    {2140045200 3600 0 CET}
+    {2153350800 7200 1 CEST}
+    {2172099600 3600 0 CET}
+    {2184800400 7200 1 CEST}
+    {2203549200 3600 0 CET}
+    {2216250000 7200 1 CEST}
+    {2234998800 3600 0 CET}
+    {2248304400 7200 1 CEST}
+    {2266448400 3600 0 CET}
+    {2279754000 7200 1 CEST}
+    {2297898000 3600 0 CET}
+    {2311203600 7200 1 CEST}
+    {2329347600 3600 0 CET}
+    {2342653200 7200 1 CEST}
+    {2361402000 3600 0 CET}
+    {2374102800 7200 1 CEST}
+    {2392851600 3600 0 CET}
+    {2405552400 7200 1 CEST}
+    {2424301200 3600 0 CET}
+    {2437606800 7200 1 CEST}
+    {2455750800 3600 0 CET}
+    {2469056400 7200 1 CEST}
+    {2487200400 3600 0 CET}
+    {2500506000 7200 1 CEST}
+    {2519254800 3600 0 CET}
+    {2531955600 7200 1 CEST}
+    {2550704400 3600 0 CET}
+    {2563405200 7200 1 CEST}
+    {2582154000 3600 0 CET}
+    {2595459600 7200 1 CEST}
+    {2613603600 3600 0 CET}
+    {2626909200 7200 1 CEST}
+    {2645053200 3600 0 CET}
+    {2658358800 7200 1 CEST}
+    {2676502800 3600 0 CET}
+    {2689808400 7200 1 CEST}
+    {2708557200 3600 0 CET}
+    {2721258000 7200 1 CEST}
+    {2740006800 3600 0 CET}
+    {2752707600 7200 1 CEST}
+    {2771456400 3600 0 CET}
+    {2784762000 7200 1 CEST}
+    {2802906000 3600 0 CET}
+    {2816211600 7200 1 CEST}
+    {2834355600 3600 0 CET}
+    {2847661200 7200 1 CEST}
+    {2866410000 3600 0 CET}
+    {2879110800 7200 1 CEST}
+    {2897859600 3600 0 CET}
+    {2910560400 7200 1 CEST}
+    {2929309200 3600 0 CET}
+    {2942010000 7200 1 CEST}
+    {2960758800 3600 0 CET}
+    {2974064400 7200 1 CEST}
+    {2992208400 3600 0 CET}
+    {3005514000 7200 1 CEST}
+    {3023658000 3600 0 CET}
+    {3036963600 7200 1 CEST}
+    {3055712400 3600 0 CET}
+    {3068413200 7200 1 CEST}
+    {3087162000 3600 0 CET}
+    {3099862800 7200 1 CEST}
+    {3118611600 3600 0 CET}
+    {3131917200 7200 1 CEST}
+    {3150061200 3600 0 CET}
+    {3163366800 7200 1 CEST}
+    {3181510800 3600 0 CET}
+    {3194816400 7200 1 CEST}
+    {3212960400 3600 0 CET}
+    {3226266000 7200 1 CEST}
+    {3245014800 3600 0 CET}
+    {3257715600 7200 1 CEST}
+    {3276464400 3600 0 CET}
+    {3289165200 7200 1 CEST}
+    {3307914000 3600 0 CET}
+    {3321219600 7200 1 CEST}
+    {3339363600 3600 0 CET}
+    {3352669200 7200 1 CEST}
+    {3370813200 3600 0 CET}
+    {3384118800 7200 1 CEST}
+    {3402867600 3600 0 CET}
+    {3415568400 7200 1 CEST}
+    {3434317200 3600 0 CET}
+    {3447018000 7200 1 CEST}
+    {3465766800 3600 0 CET}
+    {3479072400 7200 1 CEST}
+    {3497216400 3600 0 CET}
+    {3510522000 7200 1 CEST}
+    {3528666000 3600 0 CET}
+    {3541971600 7200 1 CEST}
+    {3560115600 3600 0 CET}
+    {3573421200 7200 1 CEST}
+    {3592170000 3600 0 CET}
+    {3604870800 7200 1 CEST}
+    {3623619600 3600 0 CET}
+    {3636320400 7200 1 CEST}
+    {3655069200 3600 0 CET}
+    {3668374800 7200 1 CEST}
+    {3686518800 3600 0 CET}
+    {3699824400 7200 1 CEST}
+    {3717968400 3600 0 CET}
+    {3731274000 7200 1 CEST}
+    {3750022800 3600 0 CET}
+    {3762723600 7200 1 CEST}
+    {3781472400 3600 0 CET}
+    {3794173200 7200 1 CEST}
+    {3812922000 3600 0 CET}
+    {3825622800 7200 1 CEST}
+    {3844371600 3600 0 CET}
+    {3857677200 7200 1 CEST}
+    {3875821200 3600 0 CET}
+    {3889126800 7200 1 CEST}
+    {3907270800 3600 0 CET}
+    {3920576400 7200 1 CEST}
+    {3939325200 3600 0 CET}
+    {3952026000 7200 1 CEST}
+    {3970774800 3600 0 CET}
+    {3983475600 7200 1 CEST}
+    {4002224400 3600 0 CET}
+    {4015530000 7200 1 CEST}
+    {4033674000 3600 0 CET}
+    {4046979600 7200 1 CEST}
+    {4065123600 3600 0 CET}
+    {4078429200 7200 1 CEST}
+    {4096573200 3600 0 CET}
+}
diff --git a/library/tzdata/Europe/Berlin b/library/tzdata/Europe/Berlin
new file mode 100644
index 0000000..5469cf6
--- /dev/null
+++ b/library/tzdata/Europe/Berlin
@@ -0,0 +1,274 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Europe/Berlin) {
+    {-9223372036854775808 3208 0 LMT}
+    {-2422054408 3600 0 CET}
+    {-1693706400 7200 1 CEST}
+    {-1680483600 3600 0 CET}
+    {-1663455600 7200 1 CEST}
+    {-1650150000 3600 0 CET}
+    {-1632006000 7200 1 CEST}
+    {-1618700400 3600 0 CET}
+    {-938905200 7200 1 CEST}
+    {-857257200 3600 0 CET}
+    {-844556400 7200 1 CEST}
+    {-828226800 3600 0 CET}
+    {-812502000 7200 1 CEST}
+    {-796777200 3600 0 CET}
+    {-781052400 7200 1 CEST}
+    {-776559600 10800 0 CEMT}
+    {-765936000 7200 1 CEST}
+    {-761180400 3600 0 CET}
+    {-757386000 3600 0 CET}
+    {-748479600 7200 1 CEST}
+    {-733273200 3600 0 CET}
+    {-717631200 7200 1 CEST}
+    {-714610800 10800 1 CEMT}
+    {-710380800 7200 1 CEST}
+    {-701910000 3600 0 CET}
+    {-684975600 7200 1 CEST}
+    {-670460400 3600 0 CET}
+    {-654130800 7200 1 CEST}
+    {-639010800 3600 0 CET}
+    {315529200 3600 0 CET}
+    {323830800 7200 1 CEST}
+    {338950800 3600 0 CET}
+    {354675600 7200 1 CEST}
+    {370400400 3600 0 CET}
+    {386125200 7200 1 CEST}
+    {401850000 3600 0 CET}
+    {417574800 7200 1 CEST}
+    {433299600 3600 0 CET}
+    {449024400 7200 1 CEST}
+    {465354000 3600 0 CET}
+    {481078800 7200 1 CEST}
+    {496803600 3600 0 CET}
+    {512528400 7200 1 CEST}
+    {528253200 3600 0 CET}
+    {543978000 7200 1 CEST}
+    {559702800 3600 0 CET}
+    {575427600 7200 1 CEST}
+    {591152400 3600 0 CET}
+    {606877200 7200 1 CEST}
+    {622602000 3600 0 CET}
+    {638326800 7200 1 CEST}
+    {654656400 3600 0 CET}
+    {670381200 7200 1 CEST}
+    {686106000 3600 0 CET}
+    {701830800 7200 1 CEST}
+    {717555600 3600 0 CET}
+    {733280400 7200 1 CEST}
+    {749005200 3600 0 CET}
+    {764730000 7200 1 CEST}
+    {780454800 3600 0 CET}
+    {796179600 7200 1 CEST}
+    {811904400 3600 0 CET}
+    {828234000 7200 1 CEST}
+    {846378000 3600 0 CET}
+    {859683600 7200 1 CEST}
+    {877827600 3600 0 CET}
+    {891133200 7200 1 CEST}
+    {909277200 3600 0 CET}
+    {922582800 7200 1 CEST}
+    {941331600 3600 0 CET}
+    {954032400 7200 1 CEST}
+    {972781200 3600 0 CET}
+    {985482000 7200 1 CEST}
+    {1004230800 3600 0 CET}
+    {1017536400 7200 1 CEST}
+    {1035680400 3600 0 CET}
+    {1048986000 7200 1 CEST}
+    {1067130000 3600 0 CET}
+    {1080435600 7200 1 CEST}
+    {1099184400 3600 0 CET}
+    {1111885200 7200 1 CEST}
+    {1130634000 3600 0 CET}
+    {1143334800 7200 1 CEST}
+    {1162083600 3600 0 CET}
+    {1174784400 7200 1 CEST}
+    {1193533200 3600 0 CET}
+    {1206838800 7200 1 CEST}
+    {1224982800 3600 0 CET}
+    {1238288400 7200 1 CEST}
+    {1256432400 3600 0 CET}
+    {1269738000 7200 1 CEST}
+    {1288486800 3600 0 CET}
+    {1301187600 7200 1 CEST}
+    {1319936400 3600 0 CET}
+    {1332637200 7200 1 CEST}
+    {1351386000 3600 0 CET}
+    {1364691600 7200 1 CEST}
+    {1382835600 3600 0 CET}
+    {1396141200 7200 1 CEST}
+    {1414285200 3600 0 CET}
+    {1427590800 7200 1 CEST}
+    {1445734800 3600 0 CET}
+    {1459040400 7200 1 CEST}
+    {1477789200 3600 0 CET}
+    {1490490000 7200 1 CEST}
+    {1509238800 3600 0 CET}
+    {1521939600 7200 1 CEST}
+    {1540688400 3600 0 CET}
+    {1553994000 7200 1 CEST}
+    {1572138000 3600 0 CET}
+    {1585443600 7200 1 CEST}
+    {1603587600 3600 0 CET}
+    {1616893200 7200 1 CEST}
+    {1635642000 3600 0 CET}
+    {1648342800 7200 1 CEST}
+    {1667091600 3600 0 CET}
+    {1679792400 7200 1 CEST}
+    {1698541200 3600 0 CET}
+    {1711846800 7200 1 CEST}
+    {1729990800 3600 0 CET}
+    {1743296400 7200 1 CEST}
+    {1761440400 3600 0 CET}
+    {1774746000 7200 1 CEST}
+    {1792890000 3600 0 CET}
+    {1806195600 7200 1 CEST}
+    {1824944400 3600 0 CET}
+    {1837645200 7200 1 CEST}
+    {1856394000 3600 0 CET}
+    {1869094800 7200 1 CEST}
+    {1887843600 3600 0 CET}
+    {1901149200 7200 1 CEST}
+    {1919293200 3600 0 CET}
+    {1932598800 7200 1 CEST}
+    {1950742800 3600 0 CET}
+    {1964048400 7200 1 CEST}
+    {1982797200 3600 0 CET}
+    {1995498000 7200 1 CEST}
+    {2014246800 3600 0 CET}
+    {2026947600 7200 1 CEST}
+    {2045696400 3600 0 CET}
+    {2058397200 7200 1 CEST}
+    {2077146000 3600 0 CET}
+    {2090451600 7200 1 CEST}
+    {2108595600 3600 0 CET}
+    {2121901200 7200 1 CEST}
+    {2140045200 3600 0 CET}
+    {2153350800 7200 1 CEST}
+    {2172099600 3600 0 CET}
+    {2184800400 7200 1 CEST}
+    {2203549200 3600 0 CET}
+    {2216250000 7200 1 CEST}
+    {2234998800 3600 0 CET}
+    {2248304400 7200 1 CEST}
+    {2266448400 3600 0 CET}
+    {2279754000 7200 1 CEST}
+    {2297898000 3600 0 CET}
+    {2311203600 7200 1 CEST}
+    {2329347600 3600 0 CET}
+    {2342653200 7200 1 CEST}
+    {2361402000 3600 0 CET}
+    {2374102800 7200 1 CEST}
+    {2392851600 3600 0 CET}
+    {2405552400 7200 1 CEST}
+    {2424301200 3600 0 CET}
+    {2437606800 7200 1 CEST}
+    {2455750800 3600 0 CET}
+    {2469056400 7200 1 CEST}
+    {2487200400 3600 0 CET}
+    {2500506000 7200 1 CEST}
+    {2519254800 3600 0 CET}
+    {2531955600 7200 1 CEST}
+    {2550704400 3600 0 CET}
+    {2563405200 7200 1 CEST}
+    {2582154000 3600 0 CET}
+    {2595459600 7200 1 CEST}
+    {2613603600 3600 0 CET}
+    {2626909200 7200 1 CEST}
+    {2645053200 3600 0 CET}
+    {2658358800 7200 1 CEST}
+    {2676502800 3600 0 CET}
+    {2689808400 7200 1 CEST}
+    {2708557200 3600 0 CET}
+    {2721258000 7200 1 CEST}
+    {2740006800 3600 0 CET}
+    {2752707600 7200 1 CEST}
+    {2771456400 3600 0 CET}
+    {2784762000 7200 1 CEST}
+    {2802906000 3600 0 CET}
+    {2816211600 7200 1 CEST}
+    {2834355600 3600 0 CET}
+    {2847661200 7200 1 CEST}
+    {2866410000 3600 0 CET}
+    {2879110800 7200 1 CEST}
+    {2897859600 3600 0 CET}
+    {2910560400 7200 1 CEST}
+    {2929309200 3600 0 CET}
+    {2942010000 7200 1 CEST}
+    {2960758800 3600 0 CET}
+    {2974064400 7200 1 CEST}
+    {2992208400 3600 0 CET}
+    {3005514000 7200 1 CEST}
+    {3023658000 3600 0 CET}
+    {3036963600 7200 1 CEST}
+    {3055712400 3600 0 CET}
+    {3068413200 7200 1 CEST}
+    {3087162000 3600 0 CET}
+    {3099862800 7200 1 CEST}
+    {3118611600 3600 0 CET}
+    {3131917200 7200 1 CEST}
+    {3150061200 3600 0 CET}
+    {3163366800 7200 1 CEST}
+    {3181510800 3600 0 CET}
+    {3194816400 7200 1 CEST}
+    {3212960400 3600 0 CET}
+    {3226266000 7200 1 CEST}
+    {3245014800 3600 0 CET}
+    {3257715600 7200 1 CEST}
+    {3276464400 3600 0 CET}
+    {3289165200 7200 1 CEST}
+    {3307914000 3600 0 CET}
+    {3321219600 7200 1 CEST}
+    {3339363600 3600 0 CET}
+    {3352669200 7200 1 CEST}
+    {3370813200 3600 0 CET}
+    {3384118800 7200 1 CEST}
+    {3402867600 3600 0 CET}
+    {3415568400 7200 1 CEST}
+    {3434317200 3600 0 CET}
+    {3447018000 7200 1 CEST}
+    {3465766800 3600 0 CET}
+    {3479072400 7200 1 CEST}
+    {3497216400 3600 0 CET}
+    {3510522000 7200 1 CEST}
+    {3528666000 3600 0 CET}
+    {3541971600 7200 1 CEST}
+    {3560115600 3600 0 CET}
+    {3573421200 7200 1 CEST}
+    {3592170000 3600 0 CET}
+    {3604870800 7200 1 CEST}
+    {3623619600 3600 0 CET}
+    {3636320400 7200 1 CEST}
+    {3655069200 3600 0 CET}
+    {3668374800 7200 1 CEST}
+    {3686518800 3600 0 CET}
+    {3699824400 7200 1 CEST}
+    {3717968400 3600 0 CET}
+    {3731274000 7200 1 CEST}
+    {3750022800 3600 0 CET}
+    {3762723600 7200 1 CEST}
+    {3781472400 3600 0 CET}
+    {3794173200 7200 1 CEST}
+    {3812922000 3600 0 CET}
+    {3825622800 7200 1 CEST}
+    {3844371600 3600 0 CET}
+    {3857677200 7200 1 CEST}
+    {3875821200 3600 0 CET}
+    {3889126800 7200 1 CEST}
+    {3907270800 3600 0 CET}
+    {3920576400 7200 1 CEST}
+    {3939325200 3600 0 CET}
+    {3952026000 7200 1 CEST}
+    {3970774800 3600 0 CET}
+    {3983475600 7200 1 CEST}
+    {4002224400 3600 0 CET}
+    {4015530000 7200 1 CEST}
+    {4033674000 3600 0 CET}
+    {4046979600 7200 1 CEST}
+    {4065123600 3600 0 CET}
+    {4078429200 7200 1 CEST}
+    {4096573200 3600 0 CET}
+}
diff --git a/library/tzdata/Europe/Bratislava b/library/tzdata/Europe/Bratislava
new file mode 100644
index 0000000..d65ea5a
--- /dev/null
+++ b/library/tzdata/Europe/Bratislava
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Europe/Prague)]} {
+    LoadTimeZoneFile Europe/Prague
+}
+set TZData(:Europe/Bratislava) $TZData(:Europe/Prague)
diff --git a/library/tzdata/Europe/Brussels b/library/tzdata/Europe/Brussels
new file mode 100644
index 0000000..3cb9b14
--- /dev/null
+++ b/library/tzdata/Europe/Brussels
@@ -0,0 +1,316 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Europe/Brussels) {
+    {-9223372036854775808 1050 0 LMT}
+    {-2840141850 1050 0 BMT}
+    {-2450953050 0 0 WET}
+    {-1740355200 3600 0 CET}
+    {-1693702800 7200 0 CEST}
+    {-1680483600 3600 0 CET}
+    {-1663455600 7200 1 CEST}
+    {-1650150000 3600 0 CET}
+    {-1632006000 7200 1 CEST}
+    {-1618700400 3600 0 CET}
+    {-1613826000 0 0 WET}
+    {-1604278800 3600 1 WEST}
+    {-1585530000 0 0 WET}
+    {-1574038800 3600 1 WEST}
+    {-1552266000 0 0 WET}
+    {-1539997200 3600 1 WEST}
+    {-1520557200 0 0 WET}
+    {-1507510800 3600 1 WEST}
+    {-1490576400 0 0 WET}
+    {-1473642000 3600 1 WEST}
+    {-1459126800 0 0 WET}
+    {-1444006800 3600 1 WEST}
+    {-1427677200 0 0 WET}
+    {-1411952400 3600 1 WEST}
+    {-1396227600 0 0 WET}
+    {-1379293200 3600 1 WEST}
+    {-1364778000 0 0 WET}
+    {-1348448400 3600 1 WEST}
+    {-1333328400 0 0 WET}
+    {-1316394000 3600 1 WEST}
+    {-1301263200 0 0 WET}
+    {-1284328800 3600 1 WEST}
+    {-1269813600 0 0 WET}
+    {-1253484000 3600 1 WEST}
+    {-1238364000 0 0 WET}
+    {-1221429600 3600 1 WEST}
+    {-1206914400 0 0 WET}
+    {-1191189600 3600 1 WEST}
+    {-1175464800 0 0 WET}
+    {-1160344800 3600 1 WEST}
+    {-1143410400 0 0 WET}
+    {-1127685600 3600 1 WEST}
+    {-1111960800 0 0 WET}
+    {-1096840800 3600 1 WEST}
+    {-1080511200 0 0 WET}
+    {-1063576800 3600 1 WEST}
+    {-1049061600 0 0 WET}
+    {-1033336800 3600 1 WEST}
+    {-1017612000 0 0 WET}
+    {-1002492000 3600 1 WEST}
+    {-986162400 0 0 WET}
+    {-969228000 3600 1 WEST}
+    {-950479200 0 0 WET}
+    {-942012000 3600 1 WEST}
+    {-934668000 7200 0 CEST}
+    {-857257200 3600 0 CET}
+    {-844556400 7200 1 CEST}
+    {-828226800 3600 0 CET}
+    {-812502000 7200 1 CEST}
+    {-799290000 3600 0 CET}
+    {-798073200 3600 0 CET}
+    {-781052400 7200 1 CEST}
+    {-766623600 3600 0 CET}
+    {-745455600 7200 1 CEST}
+    {-733273200 3600 0 CET}
+    {220921200 3600 0 CET}
+    {228877200 7200 1 CEST}
+    {243997200 3600 0 CET}
+    {260326800 7200 1 CEST}
+    {276051600 3600 0 CET}
+    {291776400 7200 1 CEST}
+    {307501200 3600 0 CET}
+    {323830800 7200 1 CEST}
+    {338950800 3600 0 CET}
+    {354675600 7200 1 CEST}
+    {370400400 3600 0 CET}
+    {386125200 7200 1 CEST}
+    {401850000 3600 0 CET}
+    {417574800 7200 1 CEST}
+    {433299600 3600 0 CET}
+    {449024400 7200 1 CEST}
+    {465354000 3600 0 CET}
+    {481078800 7200 1 CEST}
+    {496803600 3600 0 CET}
+    {512528400 7200 1 CEST}
+    {528253200 3600 0 CET}
+    {543978000 7200 1 CEST}
+    {559702800 3600 0 CET}
+    {575427600 7200 1 CEST}
+    {591152400 3600 0 CET}
+    {606877200 7200 1 CEST}
+    {622602000 3600 0 CET}
+    {638326800 7200 1 CEST}
+    {654656400 3600 0 CET}
+    {670381200 7200 1 CEST}
+    {686106000 3600 0 CET}
+    {701830800 7200 1 CEST}
+    {717555600 3600 0 CET}
+    {733280400 7200 1 CEST}
+    {749005200 3600 0 CET}
+    {764730000 7200 1 CEST}
+    {780454800 3600 0 CET}
+    {796179600 7200 1 CEST}
+    {811904400 3600 0 CET}
+    {828234000 7200 1 CEST}
+    {846378000 3600 0 CET}
+    {859683600 7200 1 CEST}
+    {877827600 3600 0 CET}
+    {891133200 7200 1 CEST}
+    {909277200 3600 0 CET}
+    {922582800 7200 1 CEST}
+    {941331600 3600 0 CET}
+    {954032400 7200 1 CEST}
+    {972781200 3600 0 CET}
+    {985482000 7200 1 CEST}
+    {1004230800 3600 0 CET}
+    {1017536400 7200 1 CEST}
+    {1035680400 3600 0 CET}
+    {1048986000 7200 1 CEST}
+    {1067130000 3600 0 CET}
+    {1080435600 7200 1 CEST}
+    {1099184400 3600 0 CET}
+    {1111885200 7200 1 CEST}
+    {1130634000 3600 0 CET}
+    {1143334800 7200 1 CEST}
+    {1162083600 3600 0 CET}
+    {1174784400 7200 1 CEST}
+    {1193533200 3600 0 CET}
+    {1206838800 7200 1 CEST}
+    {1224982800 3600 0 CET}
+    {1238288400 7200 1 CEST}
+    {1256432400 3600 0 CET}
+    {1269738000 7200 1 CEST}
+    {1288486800 3600 0 CET}
+    {1301187600 7200 1 CEST}
+    {1319936400 3600 0 CET}
+    {1332637200 7200 1 CEST}
+    {1351386000 3600 0 CET}
+    {1364691600 7200 1 CEST}
+    {1382835600 3600 0 CET}
+    {1396141200 7200 1 CEST}
+    {1414285200 3600 0 CET}
+    {1427590800 7200 1 CEST}
+    {1445734800 3600 0 CET}
+    {1459040400 7200 1 CEST}
+    {1477789200 3600 0 CET}
+    {1490490000 7200 1 CEST}
+    {1509238800 3600 0 CET}
+    {1521939600 7200 1 CEST}
+    {1540688400 3600 0 CET}
+    {1553994000 7200 1 CEST}
+    {1572138000 3600 0 CET}
+    {1585443600 7200 1 CEST}
+    {1603587600 3600 0 CET}
+    {1616893200 7200 1 CEST}
+    {1635642000 3600 0 CET}
+    {1648342800 7200 1 CEST}
+    {1667091600 3600 0 CET}
+    {1679792400 7200 1 CEST}
+    {1698541200 3600 0 CET}
+    {1711846800 7200 1 CEST}
+    {1729990800 3600 0 CET}
+    {1743296400 7200 1 CEST}
+    {1761440400 3600 0 CET}
+    {1774746000 7200 1 CEST}
+    {1792890000 3600 0 CET}
+    {1806195600 7200 1 CEST}
+    {1824944400 3600 0 CET}
+    {1837645200 7200 1 CEST}
+    {1856394000 3600 0 CET}
+    {1869094800 7200 1 CEST}
+    {1887843600 3600 0 CET}
+    {1901149200 7200 1 CEST}
+    {1919293200 3600 0 CET}
+    {1932598800 7200 1 CEST}
+    {1950742800 3600 0 CET}
+    {1964048400 7200 1 CEST}
+    {1982797200 3600 0 CET}
+    {1995498000 7200 1 CEST}
+    {2014246800 3600 0 CET}
+    {2026947600 7200 1 CEST}
+    {2045696400 3600 0 CET}
+    {2058397200 7200 1 CEST}
+    {2077146000 3600 0 CET}
+    {2090451600 7200 1 CEST}
+    {2108595600 3600 0 CET}
+    {2121901200 7200 1 CEST}
+    {2140045200 3600 0 CET}
+    {2153350800 7200 1 CEST}
+    {2172099600 3600 0 CET}
+    {2184800400 7200 1 CEST}
+    {2203549200 3600 0 CET}
+    {2216250000 7200 1 CEST}
+    {2234998800 3600 0 CET}
+    {2248304400 7200 1 CEST}
+    {2266448400 3600 0 CET}
+    {2279754000 7200 1 CEST}
+    {2297898000 3600 0 CET}
+    {2311203600 7200 1 CEST}
+    {2329347600 3600 0 CET}
+    {2342653200 7200 1 CEST}
+    {2361402000 3600 0 CET}
+    {2374102800 7200 1 CEST}
+    {2392851600 3600 0 CET}
+    {2405552400 7200 1 CEST}
+    {2424301200 3600 0 CET}
+    {2437606800 7200 1 CEST}
+    {2455750800 3600 0 CET}
+    {2469056400 7200 1 CEST}
+    {2487200400 3600 0 CET}
+    {2500506000 7200 1 CEST}
+    {2519254800 3600 0 CET}
+    {2531955600 7200 1 CEST}
+    {2550704400 3600 0 CET}
+    {2563405200 7200 1 CEST}
+    {2582154000 3600 0 CET}
+    {2595459600 7200 1 CEST}
+    {2613603600 3600 0 CET}
+    {2626909200 7200 1 CEST}
+    {2645053200 3600 0 CET}
+    {2658358800 7200 1 CEST}
+    {2676502800 3600 0 CET}
+    {2689808400 7200 1 CEST}
+    {2708557200 3600 0 CET}
+    {2721258000 7200 1 CEST}
+    {2740006800 3600 0 CET}
+    {2752707600 7200 1 CEST}
+    {2771456400 3600 0 CET}
+    {2784762000 7200 1 CEST}
+    {2802906000 3600 0 CET}
+    {2816211600 7200 1 CEST}
+    {2834355600 3600 0 CET}
+    {2847661200 7200 1 CEST}
+    {2866410000 3600 0 CET}
+    {2879110800 7200 1 CEST}
+    {2897859600 3600 0 CET}
+    {2910560400 7200 1 CEST}
+    {2929309200 3600 0 CET}
+    {2942010000 7200 1 CEST}
+    {2960758800 3600 0 CET}
+    {2974064400 7200 1 CEST}
+    {2992208400 3600 0 CET}
+    {3005514000 7200 1 CEST}
+    {3023658000 3600 0 CET}
+    {3036963600 7200 1 CEST}
+    {3055712400 3600 0 CET}
+    {3068413200 7200 1 CEST}
+    {3087162000 3600 0 CET}
+    {3099862800 7200 1 CEST}
+    {3118611600 3600 0 CET}
+    {3131917200 7200 1 CEST}
+    {3150061200 3600 0 CET}
+    {3163366800 7200 1 CEST}
+    {3181510800 3600 0 CET}
+    {3194816400 7200 1 CEST}
+    {3212960400 3600 0 CET}
+    {3226266000 7200 1 CEST}
+    {3245014800 3600 0 CET}
+    {3257715600 7200 1 CEST}
+    {3276464400 3600 0 CET}
+    {3289165200 7200 1 CEST}
+    {3307914000 3600 0 CET}
+    {3321219600 7200 1 CEST}
+    {3339363600 3600 0 CET}
+    {3352669200 7200 1 CEST}
+    {3370813200 3600 0 CET}
+    {3384118800 7200 1 CEST}
+    {3402867600 3600 0 CET}
+    {3415568400 7200 1 CEST}
+    {3434317200 3600 0 CET}
+    {3447018000 7200 1 CEST}
+    {3465766800 3600 0 CET}
+    {3479072400 7200 1 CEST}
+    {3497216400 3600 0 CET}
+    {3510522000 7200 1 CEST}
+    {3528666000 3600 0 CET}
+    {3541971600 7200 1 CEST}
+    {3560115600 3600 0 CET}
+    {3573421200 7200 1 CEST}
+    {3592170000 3600 0 CET}
+    {3604870800 7200 1 CEST}
+    {3623619600 3600 0 CET}
+    {3636320400 7200 1 CEST}
+    {3655069200 3600 0 CET}
+    {3668374800 7200 1 CEST}
+    {3686518800 3600 0 CET}
+    {3699824400 7200 1 CEST}
+    {3717968400 3600 0 CET}
+    {3731274000 7200 1 CEST}
+    {3750022800 3600 0 CET}
+    {3762723600 7200 1 CEST}
+    {3781472400 3600 0 CET}
+    {3794173200 7200 1 CEST}
+    {3812922000 3600 0 CET}
+    {3825622800 7200 1 CEST}
+    {3844371600 3600 0 CET}
+    {3857677200 7200 1 CEST}
+    {3875821200 3600 0 CET}
+    {3889126800 7200 1 CEST}
+    {3907270800 3600 0 CET}
+    {3920576400 7200 1 CEST}
+    {3939325200 3600 0 CET}
+    {3952026000 7200 1 CEST}
+    {3970774800 3600 0 CET}
+    {3983475600 7200 1 CEST}
+    {4002224400 3600 0 CET}
+    {4015530000 7200 1 CEST}
+    {4033674000 3600 0 CET}
+    {4046979600 7200 1 CEST}
+    {4065123600 3600 0 CET}
+    {4078429200 7200 1 CEST}
+    {4096573200 3600 0 CET}
+}
diff --git a/library/tzdata/Europe/Bucharest b/library/tzdata/Europe/Bucharest
new file mode 100644
index 0000000..7b3bed4
--- /dev/null
+++ b/library/tzdata/Europe/Bucharest
@@ -0,0 +1,268 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Europe/Bucharest) {
+    {-9223372036854775808 6264 0 LMT}
+    {-2469404664 6264 0 BMT}
+    {-1213148664 7200 0 EET}
+    {-1187056800 10800 1 EEST}
+    {-1175479200 7200 0 EET}
+    {-1159754400 10800 1 EEST}
+    {-1144029600 7200 0 EET}
+    {-1127700000 10800 1 EEST}
+    {-1111975200 7200 0 EET}
+    {-1096250400 10800 1 EEST}
+    {-1080525600 7200 0 EET}
+    {-1064800800 10800 1 EEST}
+    {-1049076000 7200 0 EET}
+    {-1033351200 10800 1 EEST}
+    {-1017626400 7200 0 EET}
+    {-1001901600 10800 1 EEST}
+    {-986176800 7200 0 EET}
+    {-970452000 10800 1 EEST}
+    {-954727200 7200 0 EET}
+    {296604000 10800 1 EEST}
+    {307486800 7200 0 EET}
+    {323816400 10800 1 EEST}
+    {338940000 7200 0 EET}
+    {354672000 10800 0 EEST}
+    {370396800 7200 0 EET}
+    {386121600 10800 1 EEST}
+    {401846400 7200 0 EET}
+    {417571200 10800 1 EEST}
+    {433296000 7200 0 EET}
+    {449020800 10800 1 EEST}
+    {465350400 7200 0 EET}
+    {481075200 10800 1 EEST}
+    {496800000 7200 0 EET}
+    {512524800 10800 1 EEST}
+    {528249600 7200 0 EET}
+    {543974400 10800 1 EEST}
+    {559699200 7200 0 EET}
+    {575424000 10800 1 EEST}
+    {591148800 7200 0 EET}
+    {606873600 10800 1 EEST}
+    {622598400 7200 0 EET}
+    {638323200 10800 1 EEST}
+    {654652800 7200 0 EET}
+    {662680800 7200 0 EET}
+    {670370400 10800 1 EEST}
+    {686095200 7200 0 EET}
+    {701820000 10800 1 EEST}
+    {717544800 7200 0 EET}
+    {733269600 10800 1 EEST}
+    {748994400 7200 0 EET}
+    {757375200 7200 0 EET}
+    {764719200 10800 1 EEST}
+    {780440400 7200 0 EET}
+    {796168800 10800 1 EEST}
+    {811890000 7200 0 EET}
+    {828223200 10800 1 EEST}
+    {846363600 7200 0 EET}
+    {852069600 7200 0 EET}
+    {859683600 10800 1 EEST}
+    {877827600 7200 0 EET}
+    {891133200 10800 1 EEST}
+    {909277200 7200 0 EET}
+    {922582800 10800 1 EEST}
+    {941331600 7200 0 EET}
+    {954032400 10800 1 EEST}
+    {972781200 7200 0 EET}
+    {985482000 10800 1 EEST}
+    {1004230800 7200 0 EET}
+    {1017536400 10800 1 EEST}
+    {1035680400 7200 0 EET}
+    {1048986000 10800 1 EEST}
+    {1067130000 7200 0 EET}
+    {1080435600 10800 1 EEST}
+    {1099184400 7200 0 EET}
+    {1111885200 10800 1 EEST}
+    {1130634000 7200 0 EET}
+    {1143334800 10800 1 EEST}
+    {1162083600 7200 0 EET}
+    {1174784400 10800 1 EEST}
+    {1193533200 7200 0 EET}
+    {1206838800 10800 1 EEST}
+    {1224982800 7200 0 EET}
+    {1238288400 10800 1 EEST}
+    {1256432400 7200 0 EET}
+    {1269738000 10800 1 EEST}
+    {1288486800 7200 0 EET}
+    {1301187600 10800 1 EEST}
+    {1319936400 7200 0 EET}
+    {1332637200 10800 1 EEST}
+    {1351386000 7200 0 EET}
+    {1364691600 10800 1 EEST}
+    {1382835600 7200 0 EET}
+    {1396141200 10800 1 EEST}
+    {1414285200 7200 0 EET}
+    {1427590800 10800 1 EEST}
+    {1445734800 7200 0 EET}
+    {1459040400 10800 1 EEST}
+    {1477789200 7200 0 EET}
+    {1490490000 10800 1 EEST}
+    {1509238800 7200 0 EET}
+    {1521939600 10800 1 EEST}
+    {1540688400 7200 0 EET}
+    {1553994000 10800 1 EEST}
+    {1572138000 7200 0 EET}
+    {1585443600 10800 1 EEST}
+    {1603587600 7200 0 EET}
+    {1616893200 10800 1 EEST}
+    {1635642000 7200 0 EET}
+    {1648342800 10800 1 EEST}
+    {1667091600 7200 0 EET}
+    {1679792400 10800 1 EEST}
+    {1698541200 7200 0 EET}
+    {1711846800 10800 1 EEST}
+    {1729990800 7200 0 EET}
+    {1743296400 10800 1 EEST}
+    {1761440400 7200 0 EET}
+    {1774746000 10800 1 EEST}
+    {1792890000 7200 0 EET}
+    {1806195600 10800 1 EEST}
+    {1824944400 7200 0 EET}
+    {1837645200 10800 1 EEST}
+    {1856394000 7200 0 EET}
+    {1869094800 10800 1 EEST}
+    {1887843600 7200 0 EET}
+    {1901149200 10800 1 EEST}
+    {1919293200 7200 0 EET}
+    {1932598800 10800 1 EEST}
+    {1950742800 7200 0 EET}
+    {1964048400 10800 1 EEST}
+    {1982797200 7200 0 EET}
+    {1995498000 10800 1 EEST}
+    {2014246800 7200 0 EET}
+    {2026947600 10800 1 EEST}
+    {2045696400 7200 0 EET}
+    {2058397200 10800 1 EEST}
+    {2077146000 7200 0 EET}
+    {2090451600 10800 1 EEST}
+    {2108595600 7200 0 EET}
+    {2121901200 10800 1 EEST}
+    {2140045200 7200 0 EET}
+    {2153350800 10800 1 EEST}
+    {2172099600 7200 0 EET}
+    {2184800400 10800 1 EEST}
+    {2203549200 7200 0 EET}
+    {2216250000 10800 1 EEST}
+    {2234998800 7200 0 EET}
+    {2248304400 10800 1 EEST}
+    {2266448400 7200 0 EET}
+    {2279754000 10800 1 EEST}
+    {2297898000 7200 0 EET}
+    {2311203600 10800 1 EEST}
+    {2329347600 7200 0 EET}
+    {2342653200 10800 1 EEST}
+    {2361402000 7200 0 EET}
+    {2374102800 10800 1 EEST}
+    {2392851600 7200 0 EET}
+    {2405552400 10800 1 EEST}
+    {2424301200 7200 0 EET}
+    {2437606800 10800 1 EEST}
+    {2455750800 7200 0 EET}
+    {2469056400 10800 1 EEST}
+    {2487200400 7200 0 EET}
+    {2500506000 10800 1 EEST}
+    {2519254800 7200 0 EET}
+    {2531955600 10800 1 EEST}
+    {2550704400 7200 0 EET}
+    {2563405200 10800 1 EEST}
+    {2582154000 7200 0 EET}
+    {2595459600 10800 1 EEST}
+    {2613603600 7200 0 EET}
+    {2626909200 10800 1 EEST}
+    {2645053200 7200 0 EET}
+    {2658358800 10800 1 EEST}
+    {2676502800 7200 0 EET}
+    {2689808400 10800 1 EEST}
+    {2708557200 7200 0 EET}
+    {2721258000 10800 1 EEST}
+    {2740006800 7200 0 EET}
+    {2752707600 10800 1 EEST}
+    {2771456400 7200 0 EET}
+    {2784762000 10800 1 EEST}
+    {2802906000 7200 0 EET}
+    {2816211600 10800 1 EEST}
+    {2834355600 7200 0 EET}
+    {2847661200 10800 1 EEST}
+    {2866410000 7200 0 EET}
+    {2879110800 10800 1 EEST}
+    {2897859600 7200 0 EET}
+    {2910560400 10800 1 EEST}
+    {2929309200 7200 0 EET}
+    {2942010000 10800 1 EEST}
+    {2960758800 7200 0 EET}
+    {2974064400 10800 1 EEST}
+    {2992208400 7200 0 EET}
+    {3005514000 10800 1 EEST}
+    {3023658000 7200 0 EET}
+    {3036963600 10800 1 EEST}
+    {3055712400 7200 0 EET}
+    {3068413200 10800 1 EEST}
+    {3087162000 7200 0 EET}
+    {3099862800 10800 1 EEST}
+    {3118611600 7200 0 EET}
+    {3131917200 10800 1 EEST}
+    {3150061200 7200 0 EET}
+    {3163366800 10800 1 EEST}
+    {3181510800 7200 0 EET}
+    {3194816400 10800 1 EEST}
+    {3212960400 7200 0 EET}
+    {3226266000 10800 1 EEST}
+    {3245014800 7200 0 EET}
+    {3257715600 10800 1 EEST}
+    {3276464400 7200 0 EET}
+    {3289165200 10800 1 EEST}
+    {3307914000 7200 0 EET}
+    {3321219600 10800 1 EEST}
+    {3339363600 7200 0 EET}
+    {3352669200 10800 1 EEST}
+    {3370813200 7200 0 EET}
+    {3384118800 10800 1 EEST}
+    {3402867600 7200 0 EET}
+    {3415568400 10800 1 EEST}
+    {3434317200 7200 0 EET}
+    {3447018000 10800 1 EEST}
+    {3465766800 7200 0 EET}
+    {3479072400 10800 1 EEST}
+    {3497216400 7200 0 EET}
+    {3510522000 10800 1 EEST}
+    {3528666000 7200 0 EET}
+    {3541971600 10800 1 EEST}
+    {3560115600 7200 0 EET}
+    {3573421200 10800 1 EEST}
+    {3592170000 7200 0 EET}
+    {3604870800 10800 1 EEST}
+    {3623619600 7200 0 EET}
+    {3636320400 10800 1 EEST}
+    {3655069200 7200 0 EET}
+    {3668374800 10800 1 EEST}
+    {3686518800 7200 0 EET}
+    {3699824400 10800 1 EEST}
+    {3717968400 7200 0 EET}
+    {3731274000 10800 1 EEST}
+    {3750022800 7200 0 EET}
+    {3762723600 10800 1 EEST}
+    {3781472400 7200 0 EET}
+    {3794173200 10800 1 EEST}
+    {3812922000 7200 0 EET}
+    {3825622800 10800 1 EEST}
+    {3844371600 7200 0 EET}
+    {3857677200 10800 1 EEST}
+    {3875821200 7200 0 EET}
+    {3889126800 10800 1 EEST}
+    {3907270800 7200 0 EET}
+    {3920576400 10800 1 EEST}
+    {3939325200 7200 0 EET}
+    {3952026000 10800 1 EEST}
+    {3970774800 7200 0 EET}
+    {3983475600 10800 1 EEST}
+    {4002224400 7200 0 EET}
+    {4015530000 10800 1 EEST}
+    {4033674000 7200 0 EET}
+    {4046979600 10800 1 EEST}
+    {4065123600 7200 0 EET}
+    {4078429200 10800 1 EEST}
+    {4096573200 7200 0 EET}
+}
diff --git a/library/tzdata/Europe/Budapest b/library/tzdata/Europe/Budapest
new file mode 100644
index 0000000..e660ad1
--- /dev/null
+++ b/library/tzdata/Europe/Budapest
@@ -0,0 +1,282 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Europe/Budapest) {
+    {-9223372036854775808 4580 0 LMT}
+    {-2500938980 3600 0 CET}
+    {-1693706400 7200 1 CEST}
+    {-1680483600 3600 0 CET}
+    {-1663455600 7200 1 CEST}
+    {-1650150000 3600 0 CET}
+    {-1640998800 3600 0 CET}
+    {-1633212000 7200 1 CEST}
+    {-1618700400 3600 0 CET}
+    {-1600466400 7200 1 CEST}
+    {-1581202800 3600 0 CET}
+    {-906771600 3600 0 CET}
+    {-857257200 3600 0 CET}
+    {-844556400 7200 1 CEST}
+    {-828226800 3600 0 CET}
+    {-812502000 7200 1 CEST}
+    {-796777200 3600 0 CET}
+    {-788922000 3600 0 CET}
+    {-778471200 7200 1 CEST}
+    {-762660000 3600 0 CET}
+    {-749689200 7200 1 CEST}
+    {-733359600 3600 0 CET}
+    {-717634800 7200 1 CEST}
+    {-701910000 3600 0 CET}
+    {-686185200 7200 1 CEST}
+    {-670460400 3600 0 CET}
+    {-654130800 7200 1 CEST}
+    {-639010800 3600 0 CET}
+    {-621990000 7200 1 CEST}
+    {-605660400 3600 0 CET}
+    {-492656400 7200 1 CEST}
+    {-481168800 3600 0 CET}
+    {-461120400 7200 1 CEST}
+    {-449632800 3600 0 CET}
+    {-428547600 7200 1 CEST}
+    {-418269600 3600 0 CET}
+    {-397094400 7200 1 CEST}
+    {-386809200 3600 0 CET}
+    {323827200 7200 1 CEST}
+    {338950800 3600 0 CET}
+    {354675600 7200 1 CEST}
+    {370400400 3600 0 CET}
+    {386125200 7200 1 CEST}
+    {401850000 3600 0 CET}
+    {417574800 7200 1 CEST}
+    {433299600 3600 0 CET}
+    {449024400 7200 1 CEST}
+    {465354000 3600 0 CET}
+    {481078800 7200 1 CEST}
+    {496803600 3600 0 CET}
+    {512528400 7200 1 CEST}
+    {528253200 3600 0 CET}
+    {543978000 7200 1 CEST}
+    {559702800 3600 0 CET}
+    {575427600 7200 1 CEST}
+    {591152400 3600 0 CET}
+    {606877200 7200 1 CEST}
+    {622602000 3600 0 CET}
+    {638326800 7200 1 CEST}
+    {654656400 3600 0 CET}
+    {670381200 7200 1 CEST}
+    {686106000 3600 0 CET}
+    {701830800 7200 1 CEST}
+    {717555600 3600 0 CET}
+    {733280400 7200 1 CEST}
+    {749005200 3600 0 CET}
+    {764730000 7200 1 CEST}
+    {780454800 3600 0 CET}
+    {796179600 7200 1 CEST}
+    {811904400 3600 0 CET}
+    {828234000 7200 1 CEST}
+    {846378000 3600 0 CET}
+    {859683600 7200 1 CEST}
+    {877827600 3600 0 CET}
+    {891133200 7200 1 CEST}
+    {909277200 3600 0 CET}
+    {922582800 7200 1 CEST}
+    {941331600 3600 0 CET}
+    {954032400 7200 1 CEST}
+    {972781200 3600 0 CET}
+    {985482000 7200 1 CEST}
+    {1004230800 3600 0 CET}
+    {1017536400 7200 1 CEST}
+    {1035680400 3600 0 CET}
+    {1048986000 7200 1 CEST}
+    {1067130000 3600 0 CET}
+    {1080435600 7200 1 CEST}
+    {1099184400 3600 0 CET}
+    {1111885200 7200 1 CEST}
+    {1130634000 3600 0 CET}
+    {1143334800 7200 1 CEST}
+    {1162083600 3600 0 CET}
+    {1174784400 7200 1 CEST}
+    {1193533200 3600 0 CET}
+    {1206838800 7200 1 CEST}
+    {1224982800 3600 0 CET}
+    {1238288400 7200 1 CEST}
+    {1256432400 3600 0 CET}
+    {1269738000 7200 1 CEST}
+    {1288486800 3600 0 CET}
+    {1301187600 7200 1 CEST}
+    {1319936400 3600 0 CET}
+    {1332637200 7200 1 CEST}
+    {1351386000 3600 0 CET}
+    {1364691600 7200 1 CEST}
+    {1382835600 3600 0 CET}
+    {1396141200 7200 1 CEST}
+    {1414285200 3600 0 CET}
+    {1427590800 7200 1 CEST}
+    {1445734800 3600 0 CET}
+    {1459040400 7200 1 CEST}
+    {1477789200 3600 0 CET}
+    {1490490000 7200 1 CEST}
+    {1509238800 3600 0 CET}
+    {1521939600 7200 1 CEST}
+    {1540688400 3600 0 CET}
+    {1553994000 7200 1 CEST}
+    {1572138000 3600 0 CET}
+    {1585443600 7200 1 CEST}
+    {1603587600 3600 0 CET}
+    {1616893200 7200 1 CEST}
+    {1635642000 3600 0 CET}
+    {1648342800 7200 1 CEST}
+    {1667091600 3600 0 CET}
+    {1679792400 7200 1 CEST}
+    {1698541200 3600 0 CET}
+    {1711846800 7200 1 CEST}
+    {1729990800 3600 0 CET}
+    {1743296400 7200 1 CEST}
+    {1761440400 3600 0 CET}
+    {1774746000 7200 1 CEST}
+    {1792890000 3600 0 CET}
+    {1806195600 7200 1 CEST}
+    {1824944400 3600 0 CET}
+    {1837645200 7200 1 CEST}
+    {1856394000 3600 0 CET}
+    {1869094800 7200 1 CEST}
+    {1887843600 3600 0 CET}
+    {1901149200 7200 1 CEST}
+    {1919293200 3600 0 CET}
+    {1932598800 7200 1 CEST}
+    {1950742800 3600 0 CET}
+    {1964048400 7200 1 CEST}
+    {1982797200 3600 0 CET}
+    {1995498000 7200 1 CEST}
+    {2014246800 3600 0 CET}
+    {2026947600 7200 1 CEST}
+    {2045696400 3600 0 CET}
+    {2058397200 7200 1 CEST}
+    {2077146000 3600 0 CET}
+    {2090451600 7200 1 CEST}
+    {2108595600 3600 0 CET}
+    {2121901200 7200 1 CEST}
+    {2140045200 3600 0 CET}
+    {2153350800 7200 1 CEST}
+    {2172099600 3600 0 CET}
+    {2184800400 7200 1 CEST}
+    {2203549200 3600 0 CET}
+    {2216250000 7200 1 CEST}
+    {2234998800 3600 0 CET}
+    {2248304400 7200 1 CEST}
+    {2266448400 3600 0 CET}
+    {2279754000 7200 1 CEST}
+    {2297898000 3600 0 CET}
+    {2311203600 7200 1 CEST}
+    {2329347600 3600 0 CET}
+    {2342653200 7200 1 CEST}
+    {2361402000 3600 0 CET}
+    {2374102800 7200 1 CEST}
+    {2392851600 3600 0 CET}
+    {2405552400 7200 1 CEST}
+    {2424301200 3600 0 CET}
+    {2437606800 7200 1 CEST}
+    {2455750800 3600 0 CET}
+    {2469056400 7200 1 CEST}
+    {2487200400 3600 0 CET}
+    {2500506000 7200 1 CEST}
+    {2519254800 3600 0 CET}
+    {2531955600 7200 1 CEST}
+    {2550704400 3600 0 CET}
+    {2563405200 7200 1 CEST}
+    {2582154000 3600 0 CET}
+    {2595459600 7200 1 CEST}
+    {2613603600 3600 0 CET}
+    {2626909200 7200 1 CEST}
+    {2645053200 3600 0 CET}
+    {2658358800 7200 1 CEST}
+    {2676502800 3600 0 CET}
+    {2689808400 7200 1 CEST}
+    {2708557200 3600 0 CET}
+    {2721258000 7200 1 CEST}
+    {2740006800 3600 0 CET}
+    {2752707600 7200 1 CEST}
+    {2771456400 3600 0 CET}
+    {2784762000 7200 1 CEST}
+    {2802906000 3600 0 CET}
+    {2816211600 7200 1 CEST}
+    {2834355600 3600 0 CET}
+    {2847661200 7200 1 CEST}
+    {2866410000 3600 0 CET}
+    {2879110800 7200 1 CEST}
+    {2897859600 3600 0 CET}
+    {2910560400 7200 1 CEST}
+    {2929309200 3600 0 CET}
+    {2942010000 7200 1 CEST}
+    {2960758800 3600 0 CET}
+    {2974064400 7200 1 CEST}
+    {2992208400 3600 0 CET}
+    {3005514000 7200 1 CEST}
+    {3023658000 3600 0 CET}
+    {3036963600 7200 1 CEST}
+    {3055712400 3600 0 CET}
+    {3068413200 7200 1 CEST}
+    {3087162000 3600 0 CET}
+    {3099862800 7200 1 CEST}
+    {3118611600 3600 0 CET}
+    {3131917200 7200 1 CEST}
+    {3150061200 3600 0 CET}
+    {3163366800 7200 1 CEST}
+    {3181510800 3600 0 CET}
+    {3194816400 7200 1 CEST}
+    {3212960400 3600 0 CET}
+    {3226266000 7200 1 CEST}
+    {3245014800 3600 0 CET}
+    {3257715600 7200 1 CEST}
+    {3276464400 3600 0 CET}
+    {3289165200 7200 1 CEST}
+    {3307914000 3600 0 CET}
+    {3321219600 7200 1 CEST}
+    {3339363600 3600 0 CET}
+    {3352669200 7200 1 CEST}
+    {3370813200 3600 0 CET}
+    {3384118800 7200 1 CEST}
+    {3402867600 3600 0 CET}
+    {3415568400 7200 1 CEST}
+    {3434317200 3600 0 CET}
+    {3447018000 7200 1 CEST}
+    {3465766800 3600 0 CET}
+    {3479072400 7200 1 CEST}
+    {3497216400 3600 0 CET}
+    {3510522000 7200 1 CEST}
+    {3528666000 3600 0 CET}
+    {3541971600 7200 1 CEST}
+    {3560115600 3600 0 CET}
+    {3573421200 7200 1 CEST}
+    {3592170000 3600 0 CET}
+    {3604870800 7200 1 CEST}
+    {3623619600 3600 0 CET}
+    {3636320400 7200 1 CEST}
+    {3655069200 3600 0 CET}
+    {3668374800 7200 1 CEST}
+    {3686518800 3600 0 CET}
+    {3699824400 7200 1 CEST}
+    {3717968400 3600 0 CET}
+    {3731274000 7200 1 CEST}
+    {3750022800 3600 0 CET}
+    {3762723600 7200 1 CEST}
+    {3781472400 3600 0 CET}
+    {3794173200 7200 1 CEST}
+    {3812922000 3600 0 CET}
+    {3825622800 7200 1 CEST}
+    {3844371600 3600 0 CET}
+    {3857677200 7200 1 CEST}
+    {3875821200 3600 0 CET}
+    {3889126800 7200 1 CEST}
+    {3907270800 3600 0 CET}
+    {3920576400 7200 1 CEST}
+    {3939325200 3600 0 CET}
+    {3952026000 7200 1 CEST}
+    {3970774800 3600 0 CET}
+    {3983475600 7200 1 CEST}
+    {4002224400 3600 0 CET}
+    {4015530000 7200 1 CEST}
+    {4033674000 3600 0 CET}
+    {4046979600 7200 1 CEST}
+    {4065123600 3600 0 CET}
+    {4078429200 7200 1 CEST}
+    {4096573200 3600 0 CET}
+}
diff --git a/library/tzdata/Europe/Busingen b/library/tzdata/Europe/Busingen
new file mode 100644
index 0000000..62abc29
--- /dev/null
+++ b/library/tzdata/Europe/Busingen
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Europe/Zurich)]} {
+    LoadTimeZoneFile Europe/Zurich
+}
+set TZData(:Europe/Busingen) $TZData(:Europe/Zurich)
diff --git a/library/tzdata/Europe/Chisinau b/library/tzdata/Europe/Chisinau
new file mode 100644
index 0000000..db4c6db
--- /dev/null
+++ b/library/tzdata/Europe/Chisinau
@@ -0,0 +1,272 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Europe/Chisinau) {
+    {-9223372036854775808 6920 0 LMT}
+    {-2840147720 6900 0 CMT}
+    {-1637114100 6264 0 BMT}
+    {-1213148664 7200 0 EET}
+    {-1187056800 10800 1 EEST}
+    {-1175479200 7200 0 EET}
+    {-1159754400 10800 1 EEST}
+    {-1144029600 7200 0 EET}
+    {-1127700000 10800 1 EEST}
+    {-1111975200 7200 0 EET}
+    {-1096250400 10800 1 EEST}
+    {-1080525600 7200 0 EET}
+    {-1064800800 10800 1 EEST}
+    {-1049076000 7200 0 EET}
+    {-1033351200 10800 1 EEST}
+    {-1017626400 7200 0 EET}
+    {-1001901600 10800 1 EEST}
+    {-986176800 7200 0 EET}
+    {-970452000 10800 1 EEST}
+    {-954727200 7200 0 EET}
+    {-927165600 10800 1 EEST}
+    {-898138800 7200 0 CET}
+    {-857257200 3600 0 CET}
+    {-844556400 7200 1 CEST}
+    {-828226800 3600 0 CET}
+    {-812502000 7200 1 CEST}
+    {-800154000 10800 0 MSD}
+    {354920400 14400 1 MSD}
+    {370728000 10800 0 MSK}
+    {386456400 14400 1 MSD}
+    {402264000 10800 0 MSK}
+    {417992400 14400 1 MSD}
+    {433800000 10800 0 MSK}
+    {449614800 14400 1 MSD}
+    {465346800 10800 0 MSK}
+    {481071600 14400 1 MSD}
+    {496796400 10800 0 MSK}
+    {512521200 14400 1 MSD}
+    {528246000 10800 0 MSK}
+    {543970800 14400 1 MSD}
+    {559695600 10800 0 MSK}
+    {575420400 14400 1 MSD}
+    {591145200 10800 0 MSK}
+    {606870000 14400 1 MSD}
+    {622594800 10800 0 MSK}
+    {638319600 14400 1 MSD}
+    {641948400 10800 0 EEST}
+    {654652800 7200 0 EET}
+    {670377600 10800 1 EEST}
+    {686102400 7200 0 EET}
+    {694216800 7200 0 EET}
+    {701820000 10800 1 EEST}
+    {717541200 7200 0 EET}
+    {733269600 10800 1 EEST}
+    {748990800 7200 0 EET}
+    {764719200 10800 1 EEST}
+    {780440400 7200 0 EET}
+    {796168800 10800 1 EEST}
+    {811890000 7200 0 EET}
+    {828223200 10800 1 EEST}
+    {846363600 7200 0 EET}
+    {852069600 7200 0 EET}
+    {859680000 10800 1 EEST}
+    {877824000 7200 0 EET}
+    {891129600 10800 1 EEST}
+    {909273600 7200 0 EET}
+    {922579200 10800 1 EEST}
+    {941328000 7200 0 EET}
+    {954028800 10800 1 EEST}
+    {972777600 7200 0 EET}
+    {985478400 10800 1 EEST}
+    {1004227200 7200 0 EET}
+    {1017532800 10800 1 EEST}
+    {1035676800 7200 0 EET}
+    {1048982400 10800 1 EEST}
+    {1067126400 7200 0 EET}
+    {1080432000 10800 1 EEST}
+    {1099180800 7200 0 EET}
+    {1111881600 10800 1 EEST}
+    {1130630400 7200 0 EET}
+    {1143331200 10800 1 EEST}
+    {1162080000 7200 0 EET}
+    {1174780800 10800 1 EEST}
+    {1193529600 7200 0 EET}
+    {1206835200 10800 1 EEST}
+    {1224979200 7200 0 EET}
+    {1238284800 10800 1 EEST}
+    {1256428800 7200 0 EET}
+    {1269734400 10800 1 EEST}
+    {1288483200 7200 0 EET}
+    {1301184000 10800 1 EEST}
+    {1319932800 7200 0 EET}
+    {1332633600 10800 1 EEST}
+    {1351382400 7200 0 EET}
+    {1364688000 10800 1 EEST}
+    {1382832000 7200 0 EET}
+    {1396137600 10800 1 EEST}
+    {1414281600 7200 0 EET}
+    {1427587200 10800 1 EEST}
+    {1445731200 7200 0 EET}
+    {1459036800 10800 1 EEST}
+    {1477785600 7200 0 EET}
+    {1490486400 10800 1 EEST}
+    {1509235200 7200 0 EET}
+    {1521936000 10800 1 EEST}
+    {1540684800 7200 0 EET}
+    {1553990400 10800 1 EEST}
+    {1572134400 7200 0 EET}
+    {1585440000 10800 1 EEST}
+    {1603584000 7200 0 EET}
+    {1616889600 10800 1 EEST}
+    {1635638400 7200 0 EET}
+    {1648339200 10800 1 EEST}
+    {1667088000 7200 0 EET}
+    {1679788800 10800 1 EEST}
+    {1698537600 7200 0 EET}
+    {1711843200 10800 1 EEST}
+    {1729987200 7200 0 EET}
+    {1743292800 10800 1 EEST}
+    {1761436800 7200 0 EET}
+    {1774742400 10800 1 EEST}
+    {1792886400 7200 0 EET}
+    {1806192000 10800 1 EEST}
+    {1824940800 7200 0 EET}
+    {1837641600 10800 1 EEST}
+    {1856390400 7200 0 EET}
+    {1869091200 10800 1 EEST}
+    {1887840000 7200 0 EET}
+    {1901145600 10800 1 EEST}
+    {1919289600 7200 0 EET}
+    {1932595200 10800 1 EEST}
+    {1950739200 7200 0 EET}
+    {1964044800 10800 1 EEST}
+    {1982793600 7200 0 EET}
+    {1995494400 10800 1 EEST}
+    {2014243200 7200 0 EET}
+    {2026944000 10800 1 EEST}
+    {2045692800 7200 0 EET}
+    {2058393600 10800 1 EEST}
+    {2077142400 7200 0 EET}
+    {2090448000 10800 1 EEST}
+    {2108592000 7200 0 EET}
+    {2121897600 10800 1 EEST}
+    {2140041600 7200 0 EET}
+    {2153347200 10800 1 EEST}
+    {2172096000 7200 0 EET}
+    {2184796800 10800 1 EEST}
+    {2203545600 7200 0 EET}
+    {2216246400 10800 1 EEST}
+    {2234995200 7200 0 EET}
+    {2248300800 10800 1 EEST}
+    {2266444800 7200 0 EET}
+    {2279750400 10800 1 EEST}
+    {2297894400 7200 0 EET}
+    {2311200000 10800 1 EEST}
+    {2329344000 7200 0 EET}
+    {2342649600 10800 1 EEST}
+    {2361398400 7200 0 EET}
+    {2374099200 10800 1 EEST}
+    {2392848000 7200 0 EET}
+    {2405548800 10800 1 EEST}
+    {2424297600 7200 0 EET}
+    {2437603200 10800 1 EEST}
+    {2455747200 7200 0 EET}
+    {2469052800 10800 1 EEST}
+    {2487196800 7200 0 EET}
+    {2500502400 10800 1 EEST}
+    {2519251200 7200 0 EET}
+    {2531952000 10800 1 EEST}
+    {2550700800 7200 0 EET}
+    {2563401600 10800 1 EEST}
+    {2582150400 7200 0 EET}
+    {2595456000 10800 1 EEST}
+    {2613600000 7200 0 EET}
+    {2626905600 10800 1 EEST}
+    {2645049600 7200 0 EET}
+    {2658355200 10800 1 EEST}
+    {2676499200 7200 0 EET}
+    {2689804800 10800 1 EEST}
+    {2708553600 7200 0 EET}
+    {2721254400 10800 1 EEST}
+    {2740003200 7200 0 EET}
+    {2752704000 10800 1 EEST}
+    {2771452800 7200 0 EET}
+    {2784758400 10800 1 EEST}
+    {2802902400 7200 0 EET}
+    {2816208000 10800 1 EEST}
+    {2834352000 7200 0 EET}
+    {2847657600 10800 1 EEST}
+    {2866406400 7200 0 EET}
+    {2879107200 10800 1 EEST}
+    {2897856000 7200 0 EET}
+    {2910556800 10800 1 EEST}
+    {2929305600 7200 0 EET}
+    {2942006400 10800 1 EEST}
+    {2960755200 7200 0 EET}
+    {2974060800 10800 1 EEST}
+    {2992204800 7200 0 EET}
+    {3005510400 10800 1 EEST}
+    {3023654400 7200 0 EET}
+    {3036960000 10800 1 EEST}
+    {3055708800 7200 0 EET}
+    {3068409600 10800 1 EEST}
+    {3087158400 7200 0 EET}
+    {3099859200 10800 1 EEST}
+    {3118608000 7200 0 EET}
+    {3131913600 10800 1 EEST}
+    {3150057600 7200 0 EET}
+    {3163363200 10800 1 EEST}
+    {3181507200 7200 0 EET}
+    {3194812800 10800 1 EEST}
+    {3212956800 7200 0 EET}
+    {3226262400 10800 1 EEST}
+    {3245011200 7200 0 EET}
+    {3257712000 10800 1 EEST}
+    {3276460800 7200 0 EET}
+    {3289161600 10800 1 EEST}
+    {3307910400 7200 0 EET}
+    {3321216000 10800 1 EEST}
+    {3339360000 7200 0 EET}
+    {3352665600 10800 1 EEST}
+    {3370809600 7200 0 EET}
+    {3384115200 10800 1 EEST}
+    {3402864000 7200 0 EET}
+    {3415564800 10800 1 EEST}
+    {3434313600 7200 0 EET}
+    {3447014400 10800 1 EEST}
+    {3465763200 7200 0 EET}
+    {3479068800 10800 1 EEST}
+    {3497212800 7200 0 EET}
+    {3510518400 10800 1 EEST}
+    {3528662400 7200 0 EET}
+    {3541968000 10800 1 EEST}
+    {3560112000 7200 0 EET}
+    {3573417600 10800 1 EEST}
+    {3592166400 7200 0 EET}
+    {3604867200 10800 1 EEST}
+    {3623616000 7200 0 EET}
+    {3636316800 10800 1 EEST}
+    {3655065600 7200 0 EET}
+    {3668371200 10800 1 EEST}
+    {3686515200 7200 0 EET}
+    {3699820800 10800 1 EEST}
+    {3717964800 7200 0 EET}
+    {3731270400 10800 1 EEST}
+    {3750019200 7200 0 EET}
+    {3762720000 10800 1 EEST}
+    {3781468800 7200 0 EET}
+    {3794169600 10800 1 EEST}
+    {3812918400 7200 0 EET}
+    {3825619200 10800 1 EEST}
+    {3844368000 7200 0 EET}
+    {3857673600 10800 1 EEST}
+    {3875817600 7200 0 EET}
+    {3889123200 10800 1 EEST}
+    {3907267200 7200 0 EET}
+    {3920572800 10800 1 EEST}
+    {3939321600 7200 0 EET}
+    {3952022400 10800 1 EEST}
+    {3970771200 7200 0 EET}
+    {3983472000 10800 1 EEST}
+    {4002220800 7200 0 EET}
+    {4015526400 10800 1 EEST}
+    {4033670400 7200 0 EET}
+    {4046976000 10800 1 EEST}
+    {4065120000 7200 0 EET}
+    {4078425600 10800 1 EEST}
+    {4096569600 7200 0 EET}
+}
diff --git a/library/tzdata/Europe/Copenhagen b/library/tzdata/Europe/Copenhagen
new file mode 100644
index 0000000..c747e58
--- /dev/null
+++ b/library/tzdata/Europe/Copenhagen
@@ -0,0 +1,264 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Europe/Copenhagen) {
+    {-9223372036854775808 3020 0 LMT}
+    {-2524524620 3020 0 CMT}
+    {-2398294220 3600 0 CET}
+    {-1692496800 7200 1 CEST}
+    {-1680490800 3600 0 CET}
+    {-935110800 7200 1 CEST}
+    {-857257200 3600 0 CET}
+    {-844556400 7200 1 CEST}
+    {-828226800 3600 0 CET}
+    {-812502000 7200 1 CEST}
+    {-796777200 3600 0 CET}
+    {-781052400 7200 0 CEST}
+    {-769388400 3600 0 CET}
+    {-747010800 7200 1 CEST}
+    {-736383600 3600 0 CET}
+    {-715215600 7200 1 CEST}
+    {-706748400 3600 0 CET}
+    {-683161200 7200 1 CEST}
+    {-675298800 3600 0 CET}
+    {315529200 3600 0 CET}
+    {323830800 7200 1 CEST}
+    {338950800 3600 0 CET}
+    {354675600 7200 1 CEST}
+    {370400400 3600 0 CET}
+    {386125200 7200 1 CEST}
+    {401850000 3600 0 CET}
+    {417574800 7200 1 CEST}
+    {433299600 3600 0 CET}
+    {449024400 7200 1 CEST}
+    {465354000 3600 0 CET}
+    {481078800 7200 1 CEST}
+    {496803600 3600 0 CET}
+    {512528400 7200 1 CEST}
+    {528253200 3600 0 CET}
+    {543978000 7200 1 CEST}
+    {559702800 3600 0 CET}
+    {575427600 7200 1 CEST}
+    {591152400 3600 0 CET}
+    {606877200 7200 1 CEST}
+    {622602000 3600 0 CET}
+    {638326800 7200 1 CEST}
+    {654656400 3600 0 CET}
+    {670381200 7200 1 CEST}
+    {686106000 3600 0 CET}
+    {701830800 7200 1 CEST}
+    {717555600 3600 0 CET}
+    {733280400 7200 1 CEST}
+    {749005200 3600 0 CET}
+    {764730000 7200 1 CEST}
+    {780454800 3600 0 CET}
+    {796179600 7200 1 CEST}
+    {811904400 3600 0 CET}
+    {828234000 7200 1 CEST}
+    {846378000 3600 0 CET}
+    {859683600 7200 1 CEST}
+    {877827600 3600 0 CET}
+    {891133200 7200 1 CEST}
+    {909277200 3600 0 CET}
+    {922582800 7200 1 CEST}
+    {941331600 3600 0 CET}
+    {954032400 7200 1 CEST}
+    {972781200 3600 0 CET}
+    {985482000 7200 1 CEST}
+    {1004230800 3600 0 CET}
+    {1017536400 7200 1 CEST}
+    {1035680400 3600 0 CET}
+    {1048986000 7200 1 CEST}
+    {1067130000 3600 0 CET}
+    {1080435600 7200 1 CEST}
+    {1099184400 3600 0 CET}
+    {1111885200 7200 1 CEST}
+    {1130634000 3600 0 CET}
+    {1143334800 7200 1 CEST}
+    {1162083600 3600 0 CET}
+    {1174784400 7200 1 CEST}
+    {1193533200 3600 0 CET}
+    {1206838800 7200 1 CEST}
+    {1224982800 3600 0 CET}
+    {1238288400 7200 1 CEST}
+    {1256432400 3600 0 CET}
+    {1269738000 7200 1 CEST}
+    {1288486800 3600 0 CET}
+    {1301187600 7200 1 CEST}
+    {1319936400 3600 0 CET}
+    {1332637200 7200 1 CEST}
+    {1351386000 3600 0 CET}
+    {1364691600 7200 1 CEST}
+    {1382835600 3600 0 CET}
+    {1396141200 7200 1 CEST}
+    {1414285200 3600 0 CET}
+    {1427590800 7200 1 CEST}
+    {1445734800 3600 0 CET}
+    {1459040400 7200 1 CEST}
+    {1477789200 3600 0 CET}
+    {1490490000 7200 1 CEST}
+    {1509238800 3600 0 CET}
+    {1521939600 7200 1 CEST}
+    {1540688400 3600 0 CET}
+    {1553994000 7200 1 CEST}
+    {1572138000 3600 0 CET}
+    {1585443600 7200 1 CEST}
+    {1603587600 3600 0 CET}
+    {1616893200 7200 1 CEST}
+    {1635642000 3600 0 CET}
+    {1648342800 7200 1 CEST}
+    {1667091600 3600 0 CET}
+    {1679792400 7200 1 CEST}
+    {1698541200 3600 0 CET}
+    {1711846800 7200 1 CEST}
+    {1729990800 3600 0 CET}
+    {1743296400 7200 1 CEST}
+    {1761440400 3600 0 CET}
+    {1774746000 7200 1 CEST}
+    {1792890000 3600 0 CET}
+    {1806195600 7200 1 CEST}
+    {1824944400 3600 0 CET}
+    {1837645200 7200 1 CEST}
+    {1856394000 3600 0 CET}
+    {1869094800 7200 1 CEST}
+    {1887843600 3600 0 CET}
+    {1901149200 7200 1 CEST}
+    {1919293200 3600 0 CET}
+    {1932598800 7200 1 CEST}
+    {1950742800 3600 0 CET}
+    {1964048400 7200 1 CEST}
+    {1982797200 3600 0 CET}
+    {1995498000 7200 1 CEST}
+    {2014246800 3600 0 CET}
+    {2026947600 7200 1 CEST}
+    {2045696400 3600 0 CET}
+    {2058397200 7200 1 CEST}
+    {2077146000 3600 0 CET}
+    {2090451600 7200 1 CEST}
+    {2108595600 3600 0 CET}
+    {2121901200 7200 1 CEST}
+    {2140045200 3600 0 CET}
+    {2153350800 7200 1 CEST}
+    {2172099600 3600 0 CET}
+    {2184800400 7200 1 CEST}
+    {2203549200 3600 0 CET}
+    {2216250000 7200 1 CEST}
+    {2234998800 3600 0 CET}
+    {2248304400 7200 1 CEST}
+    {2266448400 3600 0 CET}
+    {2279754000 7200 1 CEST}
+    {2297898000 3600 0 CET}
+    {2311203600 7200 1 CEST}
+    {2329347600 3600 0 CET}
+    {2342653200 7200 1 CEST}
+    {2361402000 3600 0 CET}
+    {2374102800 7200 1 CEST}
+    {2392851600 3600 0 CET}
+    {2405552400 7200 1 CEST}
+    {2424301200 3600 0 CET}
+    {2437606800 7200 1 CEST}
+    {2455750800 3600 0 CET}
+    {2469056400 7200 1 CEST}
+    {2487200400 3600 0 CET}
+    {2500506000 7200 1 CEST}
+    {2519254800 3600 0 CET}
+    {2531955600 7200 1 CEST}
+    {2550704400 3600 0 CET}
+    {2563405200 7200 1 CEST}
+    {2582154000 3600 0 CET}
+    {2595459600 7200 1 CEST}
+    {2613603600 3600 0 CET}
+    {2626909200 7200 1 CEST}
+    {2645053200 3600 0 CET}
+    {2658358800 7200 1 CEST}
+    {2676502800 3600 0 CET}
+    {2689808400 7200 1 CEST}
+    {2708557200 3600 0 CET}
+    {2721258000 7200 1 CEST}
+    {2740006800 3600 0 CET}
+    {2752707600 7200 1 CEST}
+    {2771456400 3600 0 CET}
+    {2784762000 7200 1 CEST}
+    {2802906000 3600 0 CET}
+    {2816211600 7200 1 CEST}
+    {2834355600 3600 0 CET}
+    {2847661200 7200 1 CEST}
+    {2866410000 3600 0 CET}
+    {2879110800 7200 1 CEST}
+    {2897859600 3600 0 CET}
+    {2910560400 7200 1 CEST}
+    {2929309200 3600 0 CET}
+    {2942010000 7200 1 CEST}
+    {2960758800 3600 0 CET}
+    {2974064400 7200 1 CEST}
+    {2992208400 3600 0 CET}
+    {3005514000 7200 1 CEST}
+    {3023658000 3600 0 CET}
+    {3036963600 7200 1 CEST}
+    {3055712400 3600 0 CET}
+    {3068413200 7200 1 CEST}
+    {3087162000 3600 0 CET}
+    {3099862800 7200 1 CEST}
+    {3118611600 3600 0 CET}
+    {3131917200 7200 1 CEST}
+    {3150061200 3600 0 CET}
+    {3163366800 7200 1 CEST}
+    {3181510800 3600 0 CET}
+    {3194816400 7200 1 CEST}
+    {3212960400 3600 0 CET}
+    {3226266000 7200 1 CEST}
+    {3245014800 3600 0 CET}
+    {3257715600 7200 1 CEST}
+    {3276464400 3600 0 CET}
+    {3289165200 7200 1 CEST}
+    {3307914000 3600 0 CET}
+    {3321219600 7200 1 CEST}
+    {3339363600 3600 0 CET}
+    {3352669200 7200 1 CEST}
+    {3370813200 3600 0 CET}
+    {3384118800 7200 1 CEST}
+    {3402867600 3600 0 CET}
+    {3415568400 7200 1 CEST}
+    {3434317200 3600 0 CET}
+    {3447018000 7200 1 CEST}
+    {3465766800 3600 0 CET}
+    {3479072400 7200 1 CEST}
+    {3497216400 3600 0 CET}
+    {3510522000 7200 1 CEST}
+    {3528666000 3600 0 CET}
+    {3541971600 7200 1 CEST}
+    {3560115600 3600 0 CET}
+    {3573421200 7200 1 CEST}
+    {3592170000 3600 0 CET}
+    {3604870800 7200 1 CEST}
+    {3623619600 3600 0 CET}
+    {3636320400 7200 1 CEST}
+    {3655069200 3600 0 CET}
+    {3668374800 7200 1 CEST}
+    {3686518800 3600 0 CET}
+    {3699824400 7200 1 CEST}
+    {3717968400 3600 0 CET}
+    {3731274000 7200 1 CEST}
+    {3750022800 3600 0 CET}
+    {3762723600 7200 1 CEST}
+    {3781472400 3600 0 CET}
+    {3794173200 7200 1 CEST}
+    {3812922000 3600 0 CET}
+    {3825622800 7200 1 CEST}
+    {3844371600 3600 0 CET}
+    {3857677200 7200 1 CEST}
+    {3875821200 3600 0 CET}
+    {3889126800 7200 1 CEST}
+    {3907270800 3600 0 CET}
+    {3920576400 7200 1 CEST}
+    {3939325200 3600 0 CET}
+    {3952026000 7200 1 CEST}
+    {3970774800 3600 0 CET}
+    {3983475600 7200 1 CEST}
+    {4002224400 3600 0 CET}
+    {4015530000 7200 1 CEST}
+    {4033674000 3600 0 CET}
+    {4046979600 7200 1 CEST}
+    {4065123600 3600 0 CET}
+    {4078429200 7200 1 CEST}
+    {4096573200 3600 0 CET}
+}
diff --git a/library/tzdata/Europe/Dublin b/library/tzdata/Europe/Dublin
new file mode 100644
index 0000000..4b43bc0
--- /dev/null
+++ b/library/tzdata/Europe/Dublin
@@ -0,0 +1,359 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Europe/Dublin) {
+    {-9223372036854775808 -1500 0 LMT}
+    {-2821649700 -1521 0 DMT}
+    {-1691962479 2079 1 IST}
+    {-1680471279 0 0 GMT}
+    {-1664143200 3600 1 BST}
+    {-1650146400 0 0 GMT}
+    {-1633903200 3600 1 BST}
+    {-1617487200 0 0 GMT}
+    {-1601848800 3600 1 BST}
+    {-1586037600 0 0 GMT}
+    {-1570399200 3600 1 BST}
+    {-1552168800 0 0 GMT}
+    {-1538344800 3600 1 BST}
+    {-1522533600 0 0 GMT}
+    {-1517011200 0 0 IST}
+    {-1507500000 3600 1 IST}
+    {-1490565600 0 0 IST}
+    {-1473631200 3600 1 IST}
+    {-1460930400 0 0 IST}
+    {-1442786400 3600 1 IST}
+    {-1428876000 0 0 IST}
+    {-1410732000 3600 1 IST}
+    {-1396216800 0 0 IST}
+    {-1379282400 3600 1 IST}
+    {-1364767200 0 0 IST}
+    {-1348437600 3600 1 IST}
+    {-1333317600 0 0 IST}
+    {-1315778400 3600 1 IST}
+    {-1301263200 0 0 IST}
+    {-1284328800 3600 1 IST}
+    {-1269813600 0 0 IST}
+    {-1253484000 3600 1 IST}
+    {-1238364000 0 0 IST}
+    {-1221429600 3600 1 IST}
+    {-1206914400 0 0 IST}
+    {-1189980000 3600 1 IST}
+    {-1175464800 0 0 IST}
+    {-1159135200 3600 1 IST}
+    {-1143410400 0 0 IST}
+    {-1126476000 3600 1 IST}
+    {-1111960800 0 0 IST}
+    {-1095631200 3600 1 IST}
+    {-1080511200 0 0 IST}
+    {-1063576800 3600 1 IST}
+    {-1049061600 0 0 IST}
+    {-1032127200 3600 1 IST}
+    {-1017612000 0 0 IST}
+    {-1001282400 3600 1 IST}
+    {-986162400 0 0 IST}
+    {-969228000 3600 1 IST}
+    {-950479200 0 0 IST}
+    {-942015600 3600 1 IST}
+    {-733359600 0 0 GMT}
+    {-719445600 3600 1 IST}
+    {-699490800 0 0 GMT}
+    {-684972000 3600 0 IST}
+    {-668037600 0 0 IST}
+    {-654732000 3600 1 IST}
+    {-636588000 0 0 IST}
+    {-622072800 3600 1 IST}
+    {-605743200 0 0 IST}
+    {-590623200 3600 1 IST}
+    {-574293600 0 0 IST}
+    {-558568800 3600 1 IST}
+    {-542239200 0 0 IST}
+    {-527119200 3600 1 IST}
+    {-512604000 0 0 IST}
+    {-496274400 3600 1 IST}
+    {-481154400 0 0 IST}
+    {-464220000 3600 1 IST}
+    {-449704800 0 0 IST}
+    {-432165600 3600 1 IST}
+    {-417650400 0 0 IST}
+    {-401320800 3600 1 IST}
+    {-386200800 0 0 IST}
+    {-369266400 3600 1 IST}
+    {-354751200 0 0 IST}
+    {-337816800 3600 1 IST}
+    {-323301600 0 0 IST}
+    {-306972000 3600 1 IST}
+    {-291852000 0 0 IST}
+    {-276732000 3600 1 IST}
+    {-257983200 0 0 IST}
+    {-245282400 3600 1 IST}
+    {-226533600 0 0 IST}
+    {-213228000 3600 1 IST}
+    {-195084000 0 0 IST}
+    {-182383200 3600 1 IST}
+    {-163634400 0 0 IST}
+    {-150933600 3600 1 IST}
+    {-132184800 0 0 IST}
+    {-119484000 3600 1 IST}
+    {-100735200 0 0 IST}
+    {-88034400 3600 1 IST}
+    {-68680800 0 0 IST}
+    {-59004000 3600 1 IST}
+    {-37238400 3600 0 IST}
+    {57722400 0 0 IST}
+    {69818400 3600 1 IST}
+    {89172000 0 0 IST}
+    {101268000 3600 1 IST}
+    {120621600 0 0 IST}
+    {132717600 3600 1 IST}
+    {152071200 0 0 IST}
+    {164167200 3600 1 IST}
+    {183520800 0 0 IST}
+    {196221600 3600 1 IST}
+    {214970400 0 0 IST}
+    {227671200 3600 1 IST}
+    {246420000 0 0 IST}
+    {259120800 3600 1 IST}
+    {278474400 0 0 IST}
+    {290570400 3600 1 IST}
+    {309924000 0 0 IST}
+    {322020000 3600 1 IST}
+    {341373600 0 0 IST}
+    {354675600 3600 1 IST}
+    {372819600 0 0 IST}
+    {386125200 3600 1 IST}
+    {404269200 0 0 IST}
+    {417574800 3600 1 IST}
+    {435718800 0 0 IST}
+    {449024400 3600 1 IST}
+    {467773200 0 0 IST}
+    {481078800 3600 1 IST}
+    {499222800 0 0 IST}
+    {512528400 3600 1 IST}
+    {530672400 0 0 IST}
+    {543978000 3600 1 IST}
+    {562122000 0 0 IST}
+    {575427600 3600 1 IST}
+    {593571600 0 0 IST}
+    {606877200 3600 1 IST}
+    {625626000 0 0 IST}
+    {638326800 3600 1 IST}
+    {657075600 0 0 IST}
+    {670381200 3600 1 IST}
+    {688525200 0 0 IST}
+    {701830800 3600 1 IST}
+    {719974800 0 0 IST}
+    {733280400 3600 1 IST}
+    {751424400 0 0 IST}
+    {764730000 3600 1 IST}
+    {782874000 0 0 IST}
+    {796179600 3600 1 IST}
+    {814323600 0 0 IST}
+    {820454400 0 0 GMT}
+    {828234000 3600 1 IST}
+    {846378000 0 0 GMT}
+    {859683600 3600 1 IST}
+    {877827600 0 0 GMT}
+    {891133200 3600 1 IST}
+    {909277200 0 0 GMT}
+    {922582800 3600 1 IST}
+    {941331600 0 0 GMT}
+    {954032400 3600 1 IST}
+    {972781200 0 0 GMT}
+    {985482000 3600 1 IST}
+    {1004230800 0 0 GMT}
+    {1017536400 3600 1 IST}
+    {1035680400 0 0 GMT}
+    {1048986000 3600 1 IST}
+    {1067130000 0 0 GMT}
+    {1080435600 3600 1 IST}
+    {1099184400 0 0 GMT}
+    {1111885200 3600 1 IST}
+    {1130634000 0 0 GMT}
+    {1143334800 3600 1 IST}
+    {1162083600 0 0 GMT}
+    {1174784400 3600 1 IST}
+    {1193533200 0 0 GMT}
+    {1206838800 3600 1 IST}
+    {1224982800 0 0 GMT}
+    {1238288400 3600 1 IST}
+    {1256432400 0 0 GMT}
+    {1269738000 3600 1 IST}
+    {1288486800 0 0 GMT}
+    {1301187600 3600 1 IST}
+    {1319936400 0 0 GMT}
+    {1332637200 3600 1 IST}
+    {1351386000 0 0 GMT}
+    {1364691600 3600 1 IST}
+    {1382835600 0 0 GMT}
+    {1396141200 3600 1 IST}
+    {1414285200 0 0 GMT}
+    {1427590800 3600 1 IST}
+    {1445734800 0 0 GMT}
+    {1459040400 3600 1 IST}
+    {1477789200 0 0 GMT}
+    {1490490000 3600 1 IST}
+    {1509238800 0 0 GMT}
+    {1521939600 3600 1 IST}
+    {1540688400 0 0 GMT}
+    {1553994000 3600 1 IST}
+    {1572138000 0 0 GMT}
+    {1585443600 3600 1 IST}
+    {1603587600 0 0 GMT}
+    {1616893200 3600 1 IST}
+    {1635642000 0 0 GMT}
+    {1648342800 3600 1 IST}
+    {1667091600 0 0 GMT}
+    {1679792400 3600 1 IST}
+    {1698541200 0 0 GMT}
+    {1711846800 3600 1 IST}
+    {1729990800 0 0 GMT}
+    {1743296400 3600 1 IST}
+    {1761440400 0 0 GMT}
+    {1774746000 3600 1 IST}
+    {1792890000 0 0 GMT}
+    {1806195600 3600 1 IST}
+    {1824944400 0 0 GMT}
+    {1837645200 3600 1 IST}
+    {1856394000 0 0 GMT}
+    {1869094800 3600 1 IST}
+    {1887843600 0 0 GMT}
+    {1901149200 3600 1 IST}
+    {1919293200 0 0 GMT}
+    {1932598800 3600 1 IST}
+    {1950742800 0 0 GMT}
+    {1964048400 3600 1 IST}
+    {1982797200 0 0 GMT}
+    {1995498000 3600 1 IST}
+    {2014246800 0 0 GMT}
+    {2026947600 3600 1 IST}
+    {2045696400 0 0 GMT}
+    {2058397200 3600 1 IST}
+    {2077146000 0 0 GMT}
+    {2090451600 3600 1 IST}
+    {2108595600 0 0 GMT}
+    {2121901200 3600 1 IST}
+    {2140045200 0 0 GMT}
+    {2153350800 3600 1 IST}
+    {2172099600 0 0 GMT}
+    {2184800400 3600 1 IST}
+    {2203549200 0 0 GMT}
+    {2216250000 3600 1 IST}
+    {2234998800 0 0 GMT}
+    {2248304400 3600 1 IST}
+    {2266448400 0 0 GMT}
+    {2279754000 3600 1 IST}
+    {2297898000 0 0 GMT}
+    {2311203600 3600 1 IST}
+    {2329347600 0 0 GMT}
+    {2342653200 3600 1 IST}
+    {2361402000 0 0 GMT}
+    {2374102800 3600 1 IST}
+    {2392851600 0 0 GMT}
+    {2405552400 3600 1 IST}
+    {2424301200 0 0 GMT}
+    {2437606800 3600 1 IST}
+    {2455750800 0 0 GMT}
+    {2469056400 3600 1 IST}
+    {2487200400 0 0 GMT}
+    {2500506000 3600 1 IST}
+    {2519254800 0 0 GMT}
+    {2531955600 3600 1 IST}
+    {2550704400 0 0 GMT}
+    {2563405200 3600 1 IST}
+    {2582154000 0 0 GMT}
+    {2595459600 3600 1 IST}
+    {2613603600 0 0 GMT}
+    {2626909200 3600 1 IST}
+    {2645053200 0 0 GMT}
+    {2658358800 3600 1 IST}
+    {2676502800 0 0 GMT}
+    {2689808400 3600 1 IST}
+    {2708557200 0 0 GMT}
+    {2721258000 3600 1 IST}
+    {2740006800 0 0 GMT}
+    {2752707600 3600 1 IST}
+    {2771456400 0 0 GMT}
+    {2784762000 3600 1 IST}
+    {2802906000 0 0 GMT}
+    {2816211600 3600 1 IST}
+    {2834355600 0 0 GMT}
+    {2847661200 3600 1 IST}
+    {2866410000 0 0 GMT}
+    {2879110800 3600 1 IST}
+    {2897859600 0 0 GMT}
+    {2910560400 3600 1 IST}
+    {2929309200 0 0 GMT}
+    {2942010000 3600 1 IST}
+    {2960758800 0 0 GMT}
+    {2974064400 3600 1 IST}
+    {2992208400 0 0 GMT}
+    {3005514000 3600 1 IST}
+    {3023658000 0 0 GMT}
+    {3036963600 3600 1 IST}
+    {3055712400 0 0 GMT}
+    {3068413200 3600 1 IST}
+    {3087162000 0 0 GMT}
+    {3099862800 3600 1 IST}
+    {3118611600 0 0 GMT}
+    {3131917200 3600 1 IST}
+    {3150061200 0 0 GMT}
+    {3163366800 3600 1 IST}
+    {3181510800 0 0 GMT}
+    {3194816400 3600 1 IST}
+    {3212960400 0 0 GMT}
+    {3226266000 3600 1 IST}
+    {3245014800 0 0 GMT}
+    {3257715600 3600 1 IST}
+    {3276464400 0 0 GMT}
+    {3289165200 3600 1 IST}
+    {3307914000 0 0 GMT}
+    {3321219600 3600 1 IST}
+    {3339363600 0 0 GMT}
+    {3352669200 3600 1 IST}
+    {3370813200 0 0 GMT}
+    {3384118800 3600 1 IST}
+    {3402867600 0 0 GMT}
+    {3415568400 3600 1 IST}
+    {3434317200 0 0 GMT}
+    {3447018000 3600 1 IST}
+    {3465766800 0 0 GMT}
+    {3479072400 3600 1 IST}
+    {3497216400 0 0 GMT}
+    {3510522000 3600 1 IST}
+    {3528666000 0 0 GMT}
+    {3541971600 3600 1 IST}
+    {3560115600 0 0 GMT}
+    {3573421200 3600 1 IST}
+    {3592170000 0 0 GMT}
+    {3604870800 3600 1 IST}
+    {3623619600 0 0 GMT}
+    {3636320400 3600 1 IST}
+    {3655069200 0 0 GMT}
+    {3668374800 3600 1 IST}
+    {3686518800 0 0 GMT}
+    {3699824400 3600 1 IST}
+    {3717968400 0 0 GMT}
+    {3731274000 3600 1 IST}
+    {3750022800 0 0 GMT}
+    {3762723600 3600 1 IST}
+    {3781472400 0 0 GMT}
+    {3794173200 3600 1 IST}
+    {3812922000 0 0 GMT}
+    {3825622800 3600 1 IST}
+    {3844371600 0 0 GMT}
+    {3857677200 3600 1 IST}
+    {3875821200 0 0 GMT}
+    {3889126800 3600 1 IST}
+    {3907270800 0 0 GMT}
+    {3920576400 3600 1 IST}
+    {3939325200 0 0 GMT}
+    {3952026000 3600 1 IST}
+    {3970774800 0 0 GMT}
+    {3983475600 3600 1 IST}
+    {4002224400 0 0 GMT}
+    {4015530000 3600 1 IST}
+    {4033674000 0 0 GMT}
+    {4046979600 3600 1 IST}
+    {4065123600 0 0 GMT}
+    {4078429200 3600 1 IST}
+    {4096573200 0 0 GMT}
+}
diff --git a/library/tzdata/Europe/Gibraltar b/library/tzdata/Europe/Gibraltar
new file mode 100644
index 0000000..de29c03
--- /dev/null
+++ b/library/tzdata/Europe/Gibraltar
@@ -0,0 +1,328 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Europe/Gibraltar) {
+    {-9223372036854775808 -1284 0 LMT}
+    {-2821649916 0 0 GMT}
+    {-1691964000 3600 1 BST}
+    {-1680472800 0 0 GMT}
+    {-1664143200 3600 1 BST}
+    {-1650146400 0 0 GMT}
+    {-1633903200 3600 1 BST}
+    {-1617487200 0 0 GMT}
+    {-1601848800 3600 1 BST}
+    {-1586037600 0 0 GMT}
+    {-1570399200 3600 1 BST}
+    {-1552168800 0 0 GMT}
+    {-1538344800 3600 1 BST}
+    {-1522533600 0 0 GMT}
+    {-1507500000 3600 1 BST}
+    {-1490565600 0 0 GMT}
+    {-1473631200 3600 1 BST}
+    {-1460930400 0 0 GMT}
+    {-1442786400 3600 1 BST}
+    {-1428876000 0 0 GMT}
+    {-1410732000 3600 1 BST}
+    {-1396216800 0 0 GMT}
+    {-1379282400 3600 1 BST}
+    {-1364767200 0 0 GMT}
+    {-1348437600 3600 1 BST}
+    {-1333317600 0 0 GMT}
+    {-1315778400 3600 1 BST}
+    {-1301263200 0 0 GMT}
+    {-1284328800 3600 1 BST}
+    {-1269813600 0 0 GMT}
+    {-1253484000 3600 1 BST}
+    {-1238364000 0 0 GMT}
+    {-1221429600 3600 1 BST}
+    {-1206914400 0 0 GMT}
+    {-1189980000 3600 1 BST}
+    {-1175464800 0 0 GMT}
+    {-1159135200 3600 1 BST}
+    {-1143410400 0 0 GMT}
+    {-1126476000 3600 1 BST}
+    {-1111960800 0 0 GMT}
+    {-1095631200 3600 1 BST}
+    {-1080511200 0 0 GMT}
+    {-1063576800 3600 1 BST}
+    {-1049061600 0 0 GMT}
+    {-1032127200 3600 1 BST}
+    {-1017612000 0 0 GMT}
+    {-1001282400 3600 1 BST}
+    {-986162400 0 0 GMT}
+    {-969228000 3600 1 BST}
+    {-950479200 0 0 GMT}
+    {-942012000 3600 1 BST}
+    {-904518000 7200 1 BDST}
+    {-896050800 3600 1 BST}
+    {-875487600 7200 1 BDST}
+    {-864601200 3600 1 BST}
+    {-844038000 7200 1 BDST}
+    {-832546800 3600 1 BST}
+    {-812588400 7200 1 BDST}
+    {-798073200 3600 1 BST}
+    {-781052400 7200 1 BDST}
+    {-772066800 3600 1 BST}
+    {-764805600 0 0 GMT}
+    {-748476000 3600 1 BST}
+    {-733356000 0 0 GMT}
+    {-719445600 3600 1 BST}
+    {-717030000 7200 1 BDST}
+    {-706748400 3600 1 BST}
+    {-699487200 0 0 GMT}
+    {-687996000 3600 1 BST}
+    {-668037600 0 0 GMT}
+    {-654732000 3600 1 BST}
+    {-636588000 0 0 GMT}
+    {-622072800 3600 1 BST}
+    {-605743200 0 0 GMT}
+    {-590623200 3600 1 BST}
+    {-574293600 0 0 GMT}
+    {-558568800 3600 1 BST}
+    {-542239200 0 0 GMT}
+    {-527119200 3600 1 BST}
+    {-512604000 0 0 GMT}
+    {-496274400 3600 1 BST}
+    {-481154400 0 0 GMT}
+    {-464220000 3600 1 BST}
+    {-449704800 0 0 GMT}
+    {-432165600 3600 1 BST}
+    {-417650400 0 0 GMT}
+    {-401320800 3600 0 CET}
+    {378687600 3600 0 CET}
+    {386125200 7200 1 CEST}
+    {401850000 3600 0 CET}
+    {417574800 7200 1 CEST}
+    {433299600 3600 0 CET}
+    {449024400 7200 1 CEST}
+    {465354000 3600 0 CET}
+    {481078800 7200 1 CEST}
+    {496803600 3600 0 CET}
+    {512528400 7200 1 CEST}
+    {528253200 3600 0 CET}
+    {543978000 7200 1 CEST}
+    {559702800 3600 0 CET}
+    {575427600 7200 1 CEST}
+    {591152400 3600 0 CET}
+    {606877200 7200 1 CEST}
+    {622602000 3600 0 CET}
+    {638326800 7200 1 CEST}
+    {654656400 3600 0 CET}
+    {670381200 7200 1 CEST}
+    {686106000 3600 0 CET}
+    {701830800 7200 1 CEST}
+    {717555600 3600 0 CET}
+    {733280400 7200 1 CEST}
+    {749005200 3600 0 CET}
+    {764730000 7200 1 CEST}
+    {780454800 3600 0 CET}
+    {796179600 7200 1 CEST}
+    {811904400 3600 0 CET}
+    {828234000 7200 1 CEST}
+    {846378000 3600 0 CET}
+    {859683600 7200 1 CEST}
+    {877827600 3600 0 CET}
+    {891133200 7200 1 CEST}
+    {909277200 3600 0 CET}
+    {922582800 7200 1 CEST}
+    {941331600 3600 0 CET}
+    {954032400 7200 1 CEST}
+    {972781200 3600 0 CET}
+    {985482000 7200 1 CEST}
+    {1004230800 3600 0 CET}
+    {1017536400 7200 1 CEST}
+    {1035680400 3600 0 CET}
+    {1048986000 7200 1 CEST}
+    {1067130000 3600 0 CET}
+    {1080435600 7200 1 CEST}
+    {1099184400 3600 0 CET}
+    {1111885200 7200 1 CEST}
+    {1130634000 3600 0 CET}
+    {1143334800 7200 1 CEST}
+    {1162083600 3600 0 CET}
+    {1174784400 7200 1 CEST}
+    {1193533200 3600 0 CET}
+    {1206838800 7200 1 CEST}
+    {1224982800 3600 0 CET}
+    {1238288400 7200 1 CEST}
+    {1256432400 3600 0 CET}
+    {1269738000 7200 1 CEST}
+    {1288486800 3600 0 CET}
+    {1301187600 7200 1 CEST}
+    {1319936400 3600 0 CET}
+    {1332637200 7200 1 CEST}
+    {1351386000 3600 0 CET}
+    {1364691600 7200 1 CEST}
+    {1382835600 3600 0 CET}
+    {1396141200 7200 1 CEST}
+    {1414285200 3600 0 CET}
+    {1427590800 7200 1 CEST}
+    {1445734800 3600 0 CET}
+    {1459040400 7200 1 CEST}
+    {1477789200 3600 0 CET}
+    {1490490000 7200 1 CEST}
+    {1509238800 3600 0 CET}
+    {1521939600 7200 1 CEST}
+    {1540688400 3600 0 CET}
+    {1553994000 7200 1 CEST}
+    {1572138000 3600 0 CET}
+    {1585443600 7200 1 CEST}
+    {1603587600 3600 0 CET}
+    {1616893200 7200 1 CEST}
+    {1635642000 3600 0 CET}
+    {1648342800 7200 1 CEST}
+    {1667091600 3600 0 CET}
+    {1679792400 7200 1 CEST}
+    {1698541200 3600 0 CET}
+    {1711846800 7200 1 CEST}
+    {1729990800 3600 0 CET}
+    {1743296400 7200 1 CEST}
+    {1761440400 3600 0 CET}
+    {1774746000 7200 1 CEST}
+    {1792890000 3600 0 CET}
+    {1806195600 7200 1 CEST}
+    {1824944400 3600 0 CET}
+    {1837645200 7200 1 CEST}
+    {1856394000 3600 0 CET}
+    {1869094800 7200 1 CEST}
+    {1887843600 3600 0 CET}
+    {1901149200 7200 1 CEST}
+    {1919293200 3600 0 CET}
+    {1932598800 7200 1 CEST}
+    {1950742800 3600 0 CET}
+    {1964048400 7200 1 CEST}
+    {1982797200 3600 0 CET}
+    {1995498000 7200 1 CEST}
+    {2014246800 3600 0 CET}
+    {2026947600 7200 1 CEST}
+    {2045696400 3600 0 CET}
+    {2058397200 7200 1 CEST}
+    {2077146000 3600 0 CET}
+    {2090451600 7200 1 CEST}
+    {2108595600 3600 0 CET}
+    {2121901200 7200 1 CEST}
+    {2140045200 3600 0 CET}
+    {2153350800 7200 1 CEST}
+    {2172099600 3600 0 CET}
+    {2184800400 7200 1 CEST}
+    {2203549200 3600 0 CET}
+    {2216250000 7200 1 CEST}
+    {2234998800 3600 0 CET}
+    {2248304400 7200 1 CEST}
+    {2266448400 3600 0 CET}
+    {2279754000 7200 1 CEST}
+    {2297898000 3600 0 CET}
+    {2311203600 7200 1 CEST}
+    {2329347600 3600 0 CET}
+    {2342653200 7200 1 CEST}
+    {2361402000 3600 0 CET}
+    {2374102800 7200 1 CEST}
+    {2392851600 3600 0 CET}
+    {2405552400 7200 1 CEST}
+    {2424301200 3600 0 CET}
+    {2437606800 7200 1 CEST}
+    {2455750800 3600 0 CET}
+    {2469056400 7200 1 CEST}
+    {2487200400 3600 0 CET}
+    {2500506000 7200 1 CEST}
+    {2519254800 3600 0 CET}
+    {2531955600 7200 1 CEST}
+    {2550704400 3600 0 CET}
+    {2563405200 7200 1 CEST}
+    {2582154000 3600 0 CET}
+    {2595459600 7200 1 CEST}
+    {2613603600 3600 0 CET}
+    {2626909200 7200 1 CEST}
+    {2645053200 3600 0 CET}
+    {2658358800 7200 1 CEST}
+    {2676502800 3600 0 CET}
+    {2689808400 7200 1 CEST}
+    {2708557200 3600 0 CET}
+    {2721258000 7200 1 CEST}
+    {2740006800 3600 0 CET}
+    {2752707600 7200 1 CEST}
+    {2771456400 3600 0 CET}
+    {2784762000 7200 1 CEST}
+    {2802906000 3600 0 CET}
+    {2816211600 7200 1 CEST}
+    {2834355600 3600 0 CET}
+    {2847661200 7200 1 CEST}
+    {2866410000 3600 0 CET}
+    {2879110800 7200 1 CEST}
+    {2897859600 3600 0 CET}
+    {2910560400 7200 1 CEST}
+    {2929309200 3600 0 CET}
+    {2942010000 7200 1 CEST}
+    {2960758800 3600 0 CET}
+    {2974064400 7200 1 CEST}
+    {2992208400 3600 0 CET}
+    {3005514000 7200 1 CEST}
+    {3023658000 3600 0 CET}
+    {3036963600 7200 1 CEST}
+    {3055712400 3600 0 CET}
+    {3068413200 7200 1 CEST}
+    {3087162000 3600 0 CET}
+    {3099862800 7200 1 CEST}
+    {3118611600 3600 0 CET}
+    {3131917200 7200 1 CEST}
+    {3150061200 3600 0 CET}
+    {3163366800 7200 1 CEST}
+    {3181510800 3600 0 CET}
+    {3194816400 7200 1 CEST}
+    {3212960400 3600 0 CET}
+    {3226266000 7200 1 CEST}
+    {3245014800 3600 0 CET}
+    {3257715600 7200 1 CEST}
+    {3276464400 3600 0 CET}
+    {3289165200 7200 1 CEST}
+    {3307914000 3600 0 CET}
+    {3321219600 7200 1 CEST}
+    {3339363600 3600 0 CET}
+    {3352669200 7200 1 CEST}
+    {3370813200 3600 0 CET}
+    {3384118800 7200 1 CEST}
+    {3402867600 3600 0 CET}
+    {3415568400 7200 1 CEST}
+    {3434317200 3600 0 CET}
+    {3447018000 7200 1 CEST}
+    {3465766800 3600 0 CET}
+    {3479072400 7200 1 CEST}
+    {3497216400 3600 0 CET}
+    {3510522000 7200 1 CEST}
+    {3528666000 3600 0 CET}
+    {3541971600 7200 1 CEST}
+    {3560115600 3600 0 CET}
+    {3573421200 7200 1 CEST}
+    {3592170000 3600 0 CET}
+    {3604870800 7200 1 CEST}
+    {3623619600 3600 0 CET}
+    {3636320400 7200 1 CEST}
+    {3655069200 3600 0 CET}
+    {3668374800 7200 1 CEST}
+    {3686518800 3600 0 CET}
+    {3699824400 7200 1 CEST}
+    {3717968400 3600 0 CET}
+    {3731274000 7200 1 CEST}
+    {3750022800 3600 0 CET}
+    {3762723600 7200 1 CEST}
+    {3781472400 3600 0 CET}
+    {3794173200 7200 1 CEST}
+    {3812922000 3600 0 CET}
+    {3825622800 7200 1 CEST}
+    {3844371600 3600 0 CET}
+    {3857677200 7200 1 CEST}
+    {3875821200 3600 0 CET}
+    {3889126800 7200 1 CEST}
+    {3907270800 3600 0 CET}
+    {3920576400 7200 1 CEST}
+    {3939325200 3600 0 CET}
+    {3952026000 7200 1 CEST}
+    {3970774800 3600 0 CET}
+    {3983475600 7200 1 CEST}
+    {4002224400 3600 0 CET}
+    {4015530000 7200 1 CEST}
+    {4033674000 3600 0 CET}
+    {4046979600 7200 1 CEST}
+    {4065123600 3600 0 CET}
+    {4078429200 7200 1 CEST}
+    {4096573200 3600 0 CET}
+}
diff --git a/library/tzdata/Europe/Guernsey b/library/tzdata/Europe/Guernsey
new file mode 100644
index 0000000..4372c64
--- /dev/null
+++ b/library/tzdata/Europe/Guernsey
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Europe/London)]} {
+    LoadTimeZoneFile Europe/London
+}
+set TZData(:Europe/Guernsey) $TZData(:Europe/London)
diff --git a/library/tzdata/Europe/Helsinki b/library/tzdata/Europe/Helsinki
new file mode 100644
index 0000000..39c5e78
--- /dev/null
+++ b/library/tzdata/Europe/Helsinki
@@ -0,0 +1,248 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Europe/Helsinki) {
+    {-9223372036854775808 5989 0 LMT}
+    {-2890258789 5989 0 HMT}
+    {-1535938789 7200 0 EET}
+    {-875671200 10800 1 EEST}
+    {-859773600 7200 0 EET}
+    {354672000 10800 1 EEST}
+    {370396800 7200 0 EET}
+    {386121600 10800 1 EEST}
+    {401846400 7200 0 EET}
+    {410220000 7200 0 EET}
+    {417574800 10800 1 EEST}
+    {433299600 7200 0 EET}
+    {449024400 10800 1 EEST}
+    {465354000 7200 0 EET}
+    {481078800 10800 1 EEST}
+    {496803600 7200 0 EET}
+    {512528400 10800 1 EEST}
+    {528253200 7200 0 EET}
+    {543978000 10800 1 EEST}
+    {559702800 7200 0 EET}
+    {575427600 10800 1 EEST}
+    {591152400 7200 0 EET}
+    {606877200 10800 1 EEST}
+    {622602000 7200 0 EET}
+    {638326800 10800 1 EEST}
+    {654656400 7200 0 EET}
+    {670381200 10800 1 EEST}
+    {686106000 7200 0 EET}
+    {701830800 10800 1 EEST}
+    {717555600 7200 0 EET}
+    {733280400 10800 1 EEST}
+    {749005200 7200 0 EET}
+    {764730000 10800 1 EEST}
+    {780454800 7200 0 EET}
+    {796179600 10800 1 EEST}
+    {811904400 7200 0 EET}
+    {828234000 10800 1 EEST}
+    {846378000 7200 0 EET}
+    {859683600 10800 1 EEST}
+    {877827600 7200 0 EET}
+    {891133200 10800 1 EEST}
+    {909277200 7200 0 EET}
+    {922582800 10800 1 EEST}
+    {941331600 7200 0 EET}
+    {954032400 10800 1 EEST}
+    {972781200 7200 0 EET}
+    {985482000 10800 1 EEST}
+    {1004230800 7200 0 EET}
+    {1017536400 10800 1 EEST}
+    {1035680400 7200 0 EET}
+    {1048986000 10800 1 EEST}
+    {1067130000 7200 0 EET}
+    {1080435600 10800 1 EEST}
+    {1099184400 7200 0 EET}
+    {1111885200 10800 1 EEST}
+    {1130634000 7200 0 EET}
+    {1143334800 10800 1 EEST}
+    {1162083600 7200 0 EET}
+    {1174784400 10800 1 EEST}
+    {1193533200 7200 0 EET}
+    {1206838800 10800 1 EEST}
+    {1224982800 7200 0 EET}
+    {1238288400 10800 1 EEST}
+    {1256432400 7200 0 EET}
+    {1269738000 10800 1 EEST}
+    {1288486800 7200 0 EET}
+    {1301187600 10800 1 EEST}
+    {1319936400 7200 0 EET}
+    {1332637200 10800 1 EEST}
+    {1351386000 7200 0 EET}
+    {1364691600 10800 1 EEST}
+    {1382835600 7200 0 EET}
+    {1396141200 10800 1 EEST}
+    {1414285200 7200 0 EET}
+    {1427590800 10800 1 EEST}
+    {1445734800 7200 0 EET}
+    {1459040400 10800 1 EEST}
+    {1477789200 7200 0 EET}
+    {1490490000 10800 1 EEST}
+    {1509238800 7200 0 EET}
+    {1521939600 10800 1 EEST}
+    {1540688400 7200 0 EET}
+    {1553994000 10800 1 EEST}
+    {1572138000 7200 0 EET}
+    {1585443600 10800 1 EEST}
+    {1603587600 7200 0 EET}
+    {1616893200 10800 1 EEST}
+    {1635642000 7200 0 EET}
+    {1648342800 10800 1 EEST}
+    {1667091600 7200 0 EET}
+    {1679792400 10800 1 EEST}
+    {1698541200 7200 0 EET}
+    {1711846800 10800 1 EEST}
+    {1729990800 7200 0 EET}
+    {1743296400 10800 1 EEST}
+    {1761440400 7200 0 EET}
+    {1774746000 10800 1 EEST}
+    {1792890000 7200 0 EET}
+    {1806195600 10800 1 EEST}
+    {1824944400 7200 0 EET}
+    {1837645200 10800 1 EEST}
+    {1856394000 7200 0 EET}
+    {1869094800 10800 1 EEST}
+    {1887843600 7200 0 EET}
+    {1901149200 10800 1 EEST}
+    {1919293200 7200 0 EET}
+    {1932598800 10800 1 EEST}
+    {1950742800 7200 0 EET}
+    {1964048400 10800 1 EEST}
+    {1982797200 7200 0 EET}
+    {1995498000 10800 1 EEST}
+    {2014246800 7200 0 EET}
+    {2026947600 10800 1 EEST}
+    {2045696400 7200 0 EET}
+    {2058397200 10800 1 EEST}
+    {2077146000 7200 0 EET}
+    {2090451600 10800 1 EEST}
+    {2108595600 7200 0 EET}
+    {2121901200 10800 1 EEST}
+    {2140045200 7200 0 EET}
+    {2153350800 10800 1 EEST}
+    {2172099600 7200 0 EET}
+    {2184800400 10800 1 EEST}
+    {2203549200 7200 0 EET}
+    {2216250000 10800 1 EEST}
+    {2234998800 7200 0 EET}
+    {2248304400 10800 1 EEST}
+    {2266448400 7200 0 EET}
+    {2279754000 10800 1 EEST}
+    {2297898000 7200 0 EET}
+    {2311203600 10800 1 EEST}
+    {2329347600 7200 0 EET}
+    {2342653200 10800 1 EEST}
+    {2361402000 7200 0 EET}
+    {2374102800 10800 1 EEST}
+    {2392851600 7200 0 EET}
+    {2405552400 10800 1 EEST}
+    {2424301200 7200 0 EET}
+    {2437606800 10800 1 EEST}
+    {2455750800 7200 0 EET}
+    {2469056400 10800 1 EEST}
+    {2487200400 7200 0 EET}
+    {2500506000 10800 1 EEST}
+    {2519254800 7200 0 EET}
+    {2531955600 10800 1 EEST}
+    {2550704400 7200 0 EET}
+    {2563405200 10800 1 EEST}
+    {2582154000 7200 0 EET}
+    {2595459600 10800 1 EEST}
+    {2613603600 7200 0 EET}
+    {2626909200 10800 1 EEST}
+    {2645053200 7200 0 EET}
+    {2658358800 10800 1 EEST}
+    {2676502800 7200 0 EET}
+    {2689808400 10800 1 EEST}
+    {2708557200 7200 0 EET}
+    {2721258000 10800 1 EEST}
+    {2740006800 7200 0 EET}
+    {2752707600 10800 1 EEST}
+    {2771456400 7200 0 EET}
+    {2784762000 10800 1 EEST}
+    {2802906000 7200 0 EET}
+    {2816211600 10800 1 EEST}
+    {2834355600 7200 0 EET}
+    {2847661200 10800 1 EEST}
+    {2866410000 7200 0 EET}
+    {2879110800 10800 1 EEST}
+    {2897859600 7200 0 EET}
+    {2910560400 10800 1 EEST}
+    {2929309200 7200 0 EET}
+    {2942010000 10800 1 EEST}
+    {2960758800 7200 0 EET}
+    {2974064400 10800 1 EEST}
+    {2992208400 7200 0 EET}
+    {3005514000 10800 1 EEST}
+    {3023658000 7200 0 EET}
+    {3036963600 10800 1 EEST}
+    {3055712400 7200 0 EET}
+    {3068413200 10800 1 EEST}
+    {3087162000 7200 0 EET}
+    {3099862800 10800 1 EEST}
+    {3118611600 7200 0 EET}
+    {3131917200 10800 1 EEST}
+    {3150061200 7200 0 EET}
+    {3163366800 10800 1 EEST}
+    {3181510800 7200 0 EET}
+    {3194816400 10800 1 EEST}
+    {3212960400 7200 0 EET}
+    {3226266000 10800 1 EEST}
+    {3245014800 7200 0 EET}
+    {3257715600 10800 1 EEST}
+    {3276464400 7200 0 EET}
+    {3289165200 10800 1 EEST}
+    {3307914000 7200 0 EET}
+    {3321219600 10800 1 EEST}
+    {3339363600 7200 0 EET}
+    {3352669200 10800 1 EEST}
+    {3370813200 7200 0 EET}
+    {3384118800 10800 1 EEST}
+    {3402867600 7200 0 EET}
+    {3415568400 10800 1 EEST}
+    {3434317200 7200 0 EET}
+    {3447018000 10800 1 EEST}
+    {3465766800 7200 0 EET}
+    {3479072400 10800 1 EEST}
+    {3497216400 7200 0 EET}
+    {3510522000 10800 1 EEST}
+    {3528666000 7200 0 EET}
+    {3541971600 10800 1 EEST}
+    {3560115600 7200 0 EET}
+    {3573421200 10800 1 EEST}
+    {3592170000 7200 0 EET}
+    {3604870800 10800 1 EEST}
+    {3623619600 7200 0 EET}
+    {3636320400 10800 1 EEST}
+    {3655069200 7200 0 EET}
+    {3668374800 10800 1 EEST}
+    {3686518800 7200 0 EET}
+    {3699824400 10800 1 EEST}
+    {3717968400 7200 0 EET}
+    {3731274000 10800 1 EEST}
+    {3750022800 7200 0 EET}
+    {3762723600 10800 1 EEST}
+    {3781472400 7200 0 EET}
+    {3794173200 10800 1 EEST}
+    {3812922000 7200 0 EET}
+    {3825622800 10800 1 EEST}
+    {3844371600 7200 0 EET}
+    {3857677200 10800 1 EEST}
+    {3875821200 7200 0 EET}
+    {3889126800 10800 1 EEST}
+    {3907270800 7200 0 EET}
+    {3920576400 10800 1 EEST}
+    {3939325200 7200 0 EET}
+    {3952026000 10800 1 EEST}
+    {3970774800 7200 0 EET}
+    {3983475600 10800 1 EEST}
+    {4002224400 7200 0 EET}
+    {4015530000 10800 1 EEST}
+    {4033674000 7200 0 EET}
+    {4046979600 10800 1 EEST}
+    {4065123600 7200 0 EET}
+    {4078429200 10800 1 EEST}
+    {4096573200 7200 0 EET}
+}
diff --git a/library/tzdata/Europe/Isle_of_Man b/library/tzdata/Europe/Isle_of_Man
new file mode 100644
index 0000000..870ac45
--- /dev/null
+++ b/library/tzdata/Europe/Isle_of_Man
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Europe/London)]} {
+    LoadTimeZoneFile Europe/London
+}
+set TZData(:Europe/Isle_of_Man) $TZData(:Europe/London)
diff --git a/library/tzdata/Europe/Istanbul b/library/tzdata/Europe/Istanbul
new file mode 100644
index 0000000..8eadbc3
--- /dev/null
+++ b/library/tzdata/Europe/Istanbul
@@ -0,0 +1,306 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Europe/Istanbul) {
+    {-9223372036854775808 6952 0 LMT}
+    {-2840147752 7016 0 IMT}
+    {-1869875816 7200 0 EET}
+    {-1693706400 10800 1 EEST}
+    {-1680490800 7200 0 EET}
+    {-1570413600 10800 1 EEST}
+    {-1552186800 7200 0 EET}
+    {-1538359200 10800 1 EEST}
+    {-1522551600 7200 0 EET}
+    {-1507514400 10800 1 EEST}
+    {-1490583600 7200 0 EET}
+    {-1440208800 10800 1 EEST}
+    {-1428030000 7200 0 EET}
+    {-1409709600 10800 1 EEST}
+    {-1396494000 7200 0 EET}
+    {-931140000 10800 1 EEST}
+    {-922762800 7200 0 EET}
+    {-917834400 10800 1 EEST}
+    {-892436400 7200 0 EET}
+    {-875844000 10800 1 EEST}
+    {-857358000 7200 0 EET}
+    {-781063200 10800 1 EEST}
+    {-764737200 7200 0 EET}
+    {-744343200 10800 1 EEST}
+    {-733806000 7200 0 EET}
+    {-716436000 10800 1 EEST}
+    {-701924400 7200 0 EET}
+    {-684986400 10800 1 EEST}
+    {-670474800 7200 0 EET}
+    {-654141600 10800 1 EEST}
+    {-639025200 7200 0 EET}
+    {-621828000 10800 1 EEST}
+    {-606970800 7200 0 EET}
+    {-590032800 10800 1 EEST}
+    {-575434800 7200 0 EET}
+    {-235620000 10800 1 EEST}
+    {-228279600 7200 0 EET}
+    {-177732000 10800 1 EEST}
+    {-165726000 7200 0 EET}
+    {10533600 10800 1 EEST}
+    {23835600 7200 0 EET}
+    {41983200 10800 1 EEST}
+    {55285200 7200 0 EET}
+    {74037600 10800 1 EEST}
+    {87339600 7200 0 EET}
+    {107910000 10800 1 EEST}
+    {121219200 7200 0 EET}
+    {133920000 10800 1 EEST}
+    {152676000 7200 0 EET}
+    {165362400 10800 1 EEST}
+    {183502800 7200 0 EET}
+    {202428000 10800 1 EEST}
+    {215557200 7200 0 EET}
+    {228866400 10800 1 EEST}
+    {245797200 7200 0 EET}
+    {260316000 10800 1 EEST}
+    {277246800 14400 0 TRST}
+    {291769200 14400 1 TRST}
+    {308779200 10800 0 TRT}
+    {323827200 14400 1 TRST}
+    {340228800 10800 0 TRT}
+    {354672000 14400 1 TRST}
+    {371678400 10800 0 TRT}
+    {386121600 14400 1 TRST}
+    {403128000 10800 0 TRT}
+    {428446800 14400 1 TRST}
+    {433886400 10800 0 TRT}
+    {482792400 7200 0 EET}
+    {482796000 10800 1 EEST}
+    {496702800 7200 0 EET}
+    {512524800 10800 1 EEST}
+    {528249600 7200 0 EET}
+    {543974400 10800 1 EEST}
+    {559699200 7200 0 EET}
+    {575424000 10800 1 EEST}
+    {591148800 7200 0 EET}
+    {606873600 10800 1 EEST}
+    {622598400 7200 0 EET}
+    {638323200 10800 1 EEST}
+    {654652800 7200 0 EET}
+    {670374000 10800 1 EEST}
+    {686098800 7200 0 EET}
+    {701823600 10800 1 EEST}
+    {717548400 7200 0 EET}
+    {733273200 10800 1 EEST}
+    {748998000 7200 0 EET}
+    {764722800 10800 1 EEST}
+    {780447600 7200 0 EET}
+    {796172400 10800 1 EEST}
+    {811897200 7200 0 EET}
+    {828226800 10800 1 EEST}
+    {846370800 7200 0 EET}
+    {859676400 10800 1 EEST}
+    {877820400 7200 0 EET}
+    {891126000 10800 1 EEST}
+    {909270000 7200 0 EET}
+    {922575600 10800 1 EEST}
+    {941324400 7200 0 EET}
+    {954025200 10800 1 EEST}
+    {972774000 7200 0 EET}
+    {985474800 10800 1 EEST}
+    {1004223600 7200 0 EET}
+    {1017529200 10800 1 EEST}
+    {1035673200 7200 0 EET}
+    {1048978800 10800 1 EEST}
+    {1067122800 7200 0 EET}
+    {1080428400 10800 1 EEST}
+    {1099177200 7200 0 EET}
+    {1111878000 10800 1 EEST}
+    {1130626800 7200 0 EET}
+    {1143327600 10800 1 EEST}
+    {1162076400 7200 0 EET}
+    {1167602400 7200 0 EET}
+    {1174784400 10800 1 EEST}
+    {1193533200 7200 0 EET}
+    {1206838800 10800 1 EEST}
+    {1224982800 7200 0 EET}
+    {1238288400 10800 1 EEST}
+    {1256432400 7200 0 EET}
+    {1269738000 10800 1 EEST}
+    {1288486800 7200 0 EET}
+    {1301187600 7200 0 EET}
+    {1301274000 10800 0 EEST}
+    {1319936400 7200 0 EET}
+    {1332637200 10800 1 EEST}
+    {1351386000 7200 0 EET}
+    {1364691600 10800 1 EEST}
+    {1382835600 7200 0 EET}
+    {1396141200 7200 0 EET}
+    {1396227600 10800 0 EEST}
+    {1414285200 7200 0 EET}
+    {1427590800 10800 1 EEST}
+    {1445734800 10800 1 EEST}
+    {1446944400 7200 0 EET}
+    {1459040400 10800 1 EEST}
+    {1477789200 7200 0 EET}
+    {1490490000 10800 1 EEST}
+    {1509238800 7200 0 EET}
+    {1521939600 10800 1 EEST}
+    {1540688400 7200 0 EET}
+    {1553994000 10800 1 EEST}
+    {1572138000 7200 0 EET}
+    {1585443600 10800 1 EEST}
+    {1603587600 7200 0 EET}
+    {1616893200 10800 1 EEST}
+    {1635642000 7200 0 EET}
+    {1648342800 10800 1 EEST}
+    {1667091600 7200 0 EET}
+    {1679792400 10800 1 EEST}
+    {1698541200 7200 0 EET}
+    {1711846800 10800 1 EEST}
+    {1729990800 7200 0 EET}
+    {1743296400 10800 1 EEST}
+    {1761440400 7200 0 EET}
+    {1774746000 10800 1 EEST}
+    {1792890000 7200 0 EET}
+    {1806195600 10800 1 EEST}
+    {1824944400 7200 0 EET}
+    {1837645200 10800 1 EEST}
+    {1856394000 7200 0 EET}
+    {1869094800 10800 1 EEST}
+    {1887843600 7200 0 EET}
+    {1901149200 10800 1 EEST}
+    {1919293200 7200 0 EET}
+    {1932598800 10800 1 EEST}
+    {1950742800 7200 0 EET}
+    {1964048400 10800 1 EEST}
+    {1982797200 7200 0 EET}
+    {1995498000 10800 1 EEST}
+    {2014246800 7200 0 EET}
+    {2026947600 10800 1 EEST}
+    {2045696400 7200 0 EET}
+    {2058397200 10800 1 EEST}
+    {2077146000 7200 0 EET}
+    {2090451600 10800 1 EEST}
+    {2108595600 7200 0 EET}
+    {2121901200 10800 1 EEST}
+    {2140045200 7200 0 EET}
+    {2153350800 10800 1 EEST}
+    {2172099600 7200 0 EET}
+    {2184800400 10800 1 EEST}
+    {2203549200 7200 0 EET}
+    {2216250000 10800 1 EEST}
+    {2234998800 7200 0 EET}
+    {2248304400 10800 1 EEST}
+    {2266448400 7200 0 EET}
+    {2279754000 10800 1 EEST}
+    {2297898000 7200 0 EET}
+    {2311203600 10800 1 EEST}
+    {2329347600 7200 0 EET}
+    {2342653200 10800 1 EEST}
+    {2361402000 7200 0 EET}
+    {2374102800 10800 1 EEST}
+    {2392851600 7200 0 EET}
+    {2405552400 10800 1 EEST}
+    {2424301200 7200 0 EET}
+    {2437606800 10800 1 EEST}
+    {2455750800 7200 0 EET}
+    {2469056400 10800 1 EEST}
+    {2487200400 7200 0 EET}
+    {2500506000 10800 1 EEST}
+    {2519254800 7200 0 EET}
+    {2531955600 10800 1 EEST}
+    {2550704400 7200 0 EET}
+    {2563405200 10800 1 EEST}
+    {2582154000 7200 0 EET}
+    {2595459600 10800 1 EEST}
+    {2613603600 7200 0 EET}
+    {2626909200 10800 1 EEST}
+    {2645053200 7200 0 EET}
+    {2658358800 10800 1 EEST}
+    {2676502800 7200 0 EET}
+    {2689808400 10800 1 EEST}
+    {2708557200 7200 0 EET}
+    {2721258000 10800 1 EEST}
+    {2740006800 7200 0 EET}
+    {2752707600 10800 1 EEST}
+    {2771456400 7200 0 EET}
+    {2784762000 10800 1 EEST}
+    {2802906000 7200 0 EET}
+    {2816211600 10800 1 EEST}
+    {2834355600 7200 0 EET}
+    {2847661200 10800 1 EEST}
+    {2866410000 7200 0 EET}
+    {2879110800 10800 1 EEST}
+    {2897859600 7200 0 EET}
+    {2910560400 10800 1 EEST}
+    {2929309200 7200 0 EET}
+    {2942010000 10800 1 EEST}
+    {2960758800 7200 0 EET}
+    {2974064400 10800 1 EEST}
+    {2992208400 7200 0 EET}
+    {3005514000 10800 1 EEST}
+    {3023658000 7200 0 EET}
+    {3036963600 10800 1 EEST}
+    {3055712400 7200 0 EET}
+    {3068413200 10800 1 EEST}
+    {3087162000 7200 0 EET}
+    {3099862800 10800 1 EEST}
+    {3118611600 7200 0 EET}
+    {3131917200 10800 1 EEST}
+    {3150061200 7200 0 EET}
+    {3163366800 10800 1 EEST}
+    {3181510800 7200 0 EET}
+    {3194816400 10800 1 EEST}
+    {3212960400 7200 0 EET}
+    {3226266000 10800 1 EEST}
+    {3245014800 7200 0 EET}
+    {3257715600 10800 1 EEST}
+    {3276464400 7200 0 EET}
+    {3289165200 10800 1 EEST}
+    {3307914000 7200 0 EET}
+    {3321219600 10800 1 EEST}
+    {3339363600 7200 0 EET}
+    {3352669200 10800 1 EEST}
+    {3370813200 7200 0 EET}
+    {3384118800 10800 1 EEST}
+    {3402867600 7200 0 EET}
+    {3415568400 10800 1 EEST}
+    {3434317200 7200 0 EET}
+    {3447018000 10800 1 EEST}
+    {3465766800 7200 0 EET}
+    {3479072400 10800 1 EEST}
+    {3497216400 7200 0 EET}
+    {3510522000 10800 1 EEST}
+    {3528666000 7200 0 EET}
+    {3541971600 10800 1 EEST}
+    {3560115600 7200 0 EET}
+    {3573421200 10800 1 EEST}
+    {3592170000 7200 0 EET}
+    {3604870800 10800 1 EEST}
+    {3623619600 7200 0 EET}
+    {3636320400 10800 1 EEST}
+    {3655069200 7200 0 EET}
+    {3668374800 10800 1 EEST}
+    {3686518800 7200 0 EET}
+    {3699824400 10800 1 EEST}
+    {3717968400 7200 0 EET}
+    {3731274000 10800 1 EEST}
+    {3750022800 7200 0 EET}
+    {3762723600 10800 1 EEST}
+    {3781472400 7200 0 EET}
+    {3794173200 10800 1 EEST}
+    {3812922000 7200 0 EET}
+    {3825622800 10800 1 EEST}
+    {3844371600 7200 0 EET}
+    {3857677200 10800 1 EEST}
+    {3875821200 7200 0 EET}
+    {3889126800 10800 1 EEST}
+    {3907270800 7200 0 EET}
+    {3920576400 10800 1 EEST}
+    {3939325200 7200 0 EET}
+    {3952026000 10800 1 EEST}
+    {3970774800 7200 0 EET}
+    {3983475600 10800 1 EEST}
+    {4002224400 7200 0 EET}
+    {4015530000 10800 1 EEST}
+    {4033674000 7200 0 EET}
+    {4046979600 10800 1 EEST}
+    {4065123600 7200 0 EET}
+    {4078429200 10800 1 EEST}
+    {4096573200 7200 0 EET}
+}
diff --git a/library/tzdata/Europe/Jersey b/library/tzdata/Europe/Jersey
new file mode 100644
index 0000000..e4da512
--- /dev/null
+++ b/library/tzdata/Europe/Jersey
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Europe/London)]} {
+    LoadTimeZoneFile Europe/London
+}
+set TZData(:Europe/Jersey) $TZData(:Europe/London)
diff --git a/library/tzdata/Europe/Kaliningrad b/library/tzdata/Europe/Kaliningrad
new file mode 100644
index 0000000..85add82
--- /dev/null
+++ b/library/tzdata/Europe/Kaliningrad
@@ -0,0 +1,85 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Europe/Kaliningrad) {
+    {-9223372036854775808 4920 0 LMT}
+    {-2422056120 3600 0 CET}
+    {-1693706400 7200 1 CEST}
+    {-1680483600 3600 0 CET}
+    {-1663455600 7200 1 CEST}
+    {-1650150000 3600 0 CET}
+    {-1632006000 7200 1 CEST}
+    {-1618700400 3600 0 CET}
+    {-938905200 7200 1 CEST}
+    {-857257200 3600 0 CET}
+    {-844556400 7200 1 CEST}
+    {-828226800 3600 0 CET}
+    {-812502000 7200 1 CEST}
+    {-796777200 3600 0 CET}
+    {-788922000 7200 0 CET}
+    {-778730400 10800 1 CEST}
+    {-762663600 7200 0 CET}
+    {-757389600 10800 0 MSD}
+    {354920400 14400 1 MSD}
+    {370728000 10800 0 MSK}
+    {386456400 14400 1 MSD}
+    {402264000 10800 0 MSK}
+    {417992400 14400 1 MSD}
+    {433800000 10800 0 MSK}
+    {449614800 14400 1 MSD}
+    {465346800 10800 0 MSK}
+    {481071600 14400 1 MSD}
+    {496796400 10800 0 MSK}
+    {512521200 14400 1 MSD}
+    {528246000 10800 0 MSK}
+    {543970800 14400 1 MSD}
+    {559695600 10800 0 MSK}
+    {575420400 14400 1 MSD}
+    {591145200 10800 0 MSK}
+    {606870000 7200 0 EEMMTT}
+    {606873600 10800 1 EEST}
+    {622598400 7200 0 EET}
+    {638323200 10800 1 EEST}
+    {654652800 7200 0 EET}
+    {670377600 10800 1 EEST}
+    {686102400 7200 0 EET}
+    {701827200 10800 1 EEST}
+    {717552000 7200 0 EET}
+    {733276800 10800 1 EEST}
+    {749001600 7200 0 EET}
+    {764726400 10800 1 EEST}
+    {780451200 7200 0 EET}
+    {796176000 10800 1 EEST}
+    {811900800 7200 0 EET}
+    {828230400 10800 1 EEST}
+    {846374400 7200 0 EET}
+    {859680000 10800 1 EEST}
+    {877824000 7200 0 EET}
+    {891129600 10800 1 EEST}
+    {909273600 7200 0 EET}
+    {922579200 10800 1 EEST}
+    {941328000 7200 0 EET}
+    {954028800 10800 1 EEST}
+    {972777600 7200 0 EET}
+    {985478400 10800 1 EEST}
+    {1004227200 7200 0 EET}
+    {1017532800 10800 1 EEST}
+    {1035676800 7200 0 EET}
+    {1048982400 10800 1 EEST}
+    {1067126400 7200 0 EET}
+    {1080432000 10800 1 EEST}
+    {1099180800 7200 0 EET}
+    {1111881600 10800 1 EEST}
+    {1130630400 7200 0 EET}
+    {1143331200 10800 1 EEST}
+    {1162080000 7200 0 EET}
+    {1174780800 10800 1 EEST}
+    {1193529600 7200 0 EET}
+    {1206835200 10800 1 EEST}
+    {1224979200 7200 0 EET}
+    {1238284800 10800 1 EEST}
+    {1256428800 7200 0 EET}
+    {1269734400 10800 1 EEST}
+    {1288483200 7200 0 EET}
+    {1301184000 10800 0 FET}
+    {1414278000 7200 0 EET}
+}
diff --git a/library/tzdata/Europe/Kiev b/library/tzdata/Europe/Kiev
new file mode 100644
index 0000000..55015fa
--- /dev/null
+++ b/library/tzdata/Europe/Kiev
@@ -0,0 +1,251 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Europe/Kiev) {
+    {-9223372036854775808 7324 0 LMT}
+    {-2840148124 7324 0 KMT}
+    {-1441159324 7200 0 EET}
+    {-1247536800 10800 0 MSK}
+    {-892522800 3600 0 CET}
+    {-857257200 3600 0 CET}
+    {-844556400 7200 1 CEST}
+    {-828226800 3600 0 CET}
+    {-825382800 10800 0 MSD}
+    {354920400 14400 1 MSD}
+    {370728000 10800 0 MSK}
+    {386456400 14400 1 MSD}
+    {402264000 10800 0 MSK}
+    {417992400 14400 1 MSD}
+    {433800000 10800 0 MSK}
+    {449614800 14400 1 MSD}
+    {465346800 10800 0 MSK}
+    {481071600 14400 1 MSD}
+    {496796400 10800 0 MSK}
+    {512521200 14400 1 MSD}
+    {528246000 10800 0 MSK}
+    {543970800 14400 1 MSD}
+    {559695600 10800 0 MSK}
+    {575420400 14400 1 MSD}
+    {591145200 10800 0 MSK}
+    {606870000 14400 1 MSD}
+    {622594800 10800 0 MSK}
+    {638319600 14400 1 MSD}
+    {646786800 10800 1 EEST}
+    {686102400 7200 0 EET}
+    {701820000 10800 1 EEST}
+    {717541200 7200 0 EET}
+    {733269600 10800 1 EEST}
+    {748990800 7200 0 EET}
+    {764719200 10800 1 EEST}
+    {780440400 7200 0 EET}
+    {788911200 7200 0 EET}
+    {796179600 10800 1 EEST}
+    {811904400 7200 0 EET}
+    {828234000 10800 1 EEST}
+    {846378000 7200 0 EET}
+    {859683600 10800 1 EEST}
+    {877827600 7200 0 EET}
+    {891133200 10800 1 EEST}
+    {909277200 7200 0 EET}
+    {922582800 10800 1 EEST}
+    {941331600 7200 0 EET}
+    {954032400 10800 1 EEST}
+    {972781200 7200 0 EET}
+    {985482000 10800 1 EEST}
+    {1004230800 7200 0 EET}
+    {1017536400 10800 1 EEST}
+    {1035680400 7200 0 EET}
+    {1048986000 10800 1 EEST}
+    {1067130000 7200 0 EET}
+    {1080435600 10800 1 EEST}
+    {1099184400 7200 0 EET}
+    {1111885200 10800 1 EEST}
+    {1130634000 7200 0 EET}
+    {1143334800 10800 1 EEST}
+    {1162083600 7200 0 EET}
+    {1174784400 10800 1 EEST}
+    {1193533200 7200 0 EET}
+    {1206838800 10800 1 EEST}
+    {1224982800 7200 0 EET}
+    {1238288400 10800 1 EEST}
+    {1256432400 7200 0 EET}
+    {1269738000 10800 1 EEST}
+    {1288486800 7200 0 EET}
+    {1301187600 10800 1 EEST}
+    {1319936400 7200 0 EET}
+    {1332637200 10800 1 EEST}
+    {1351386000 7200 0 EET}
+    {1364691600 10800 1 EEST}
+    {1382835600 7200 0 EET}
+    {1396141200 10800 1 EEST}
+    {1414285200 7200 0 EET}
+    {1427590800 10800 1 EEST}
+    {1445734800 7200 0 EET}
+    {1459040400 10800 1 EEST}
+    {1477789200 7200 0 EET}
+    {1490490000 10800 1 EEST}
+    {1509238800 7200 0 EET}
+    {1521939600 10800 1 EEST}
+    {1540688400 7200 0 EET}
+    {1553994000 10800 1 EEST}
+    {1572138000 7200 0 EET}
+    {1585443600 10800 1 EEST}
+    {1603587600 7200 0 EET}
+    {1616893200 10800 1 EEST}
+    {1635642000 7200 0 EET}
+    {1648342800 10800 1 EEST}
+    {1667091600 7200 0 EET}
+    {1679792400 10800 1 EEST}
+    {1698541200 7200 0 EET}
+    {1711846800 10800 1 EEST}
+    {1729990800 7200 0 EET}
+    {1743296400 10800 1 EEST}
+    {1761440400 7200 0 EET}
+    {1774746000 10800 1 EEST}
+    {1792890000 7200 0 EET}
+    {1806195600 10800 1 EEST}
+    {1824944400 7200 0 EET}
+    {1837645200 10800 1 EEST}
+    {1856394000 7200 0 EET}
+    {1869094800 10800 1 EEST}
+    {1887843600 7200 0 EET}
+    {1901149200 10800 1 EEST}
+    {1919293200 7200 0 EET}
+    {1932598800 10800 1 EEST}
+    {1950742800 7200 0 EET}
+    {1964048400 10800 1 EEST}
+    {1982797200 7200 0 EET}
+    {1995498000 10800 1 EEST}
+    {2014246800 7200 0 EET}
+    {2026947600 10800 1 EEST}
+    {2045696400 7200 0 EET}
+    {2058397200 10800 1 EEST}
+    {2077146000 7200 0 EET}
+    {2090451600 10800 1 EEST}
+    {2108595600 7200 0 EET}
+    {2121901200 10800 1 EEST}
+    {2140045200 7200 0 EET}
+    {2153350800 10800 1 EEST}
+    {2172099600 7200 0 EET}
+    {2184800400 10800 1 EEST}
+    {2203549200 7200 0 EET}
+    {2216250000 10800 1 EEST}
+    {2234998800 7200 0 EET}
+    {2248304400 10800 1 EEST}
+    {2266448400 7200 0 EET}
+    {2279754000 10800 1 EEST}
+    {2297898000 7200 0 EET}
+    {2311203600 10800 1 EEST}
+    {2329347600 7200 0 EET}
+    {2342653200 10800 1 EEST}
+    {2361402000 7200 0 EET}
+    {2374102800 10800 1 EEST}
+    {2392851600 7200 0 EET}
+    {2405552400 10800 1 EEST}
+    {2424301200 7200 0 EET}
+    {2437606800 10800 1 EEST}
+    {2455750800 7200 0 EET}
+    {2469056400 10800 1 EEST}
+    {2487200400 7200 0 EET}
+    {2500506000 10800 1 EEST}
+    {2519254800 7200 0 EET}
+    {2531955600 10800 1 EEST}
+    {2550704400 7200 0 EET}
+    {2563405200 10800 1 EEST}
+    {2582154000 7200 0 EET}
+    {2595459600 10800 1 EEST}
+    {2613603600 7200 0 EET}
+    {2626909200 10800 1 EEST}
+    {2645053200 7200 0 EET}
+    {2658358800 10800 1 EEST}
+    {2676502800 7200 0 EET}
+    {2689808400 10800 1 EEST}
+    {2708557200 7200 0 EET}
+    {2721258000 10800 1 EEST}
+    {2740006800 7200 0 EET}
+    {2752707600 10800 1 EEST}
+    {2771456400 7200 0 EET}
+    {2784762000 10800 1 EEST}
+    {2802906000 7200 0 EET}
+    {2816211600 10800 1 EEST}
+    {2834355600 7200 0 EET}
+    {2847661200 10800 1 EEST}
+    {2866410000 7200 0 EET}
+    {2879110800 10800 1 EEST}
+    {2897859600 7200 0 EET}
+    {2910560400 10800 1 EEST}
+    {2929309200 7200 0 EET}
+    {2942010000 10800 1 EEST}
+    {2960758800 7200 0 EET}
+    {2974064400 10800 1 EEST}
+    {2992208400 7200 0 EET}
+    {3005514000 10800 1 EEST}
+    {3023658000 7200 0 EET}
+    {3036963600 10800 1 EEST}
+    {3055712400 7200 0 EET}
+    {3068413200 10800 1 EEST}
+    {3087162000 7200 0 EET}
+    {3099862800 10800 1 EEST}
+    {3118611600 7200 0 EET}
+    {3131917200 10800 1 EEST}
+    {3150061200 7200 0 EET}
+    {3163366800 10800 1 EEST}
+    {3181510800 7200 0 EET}
+    {3194816400 10800 1 EEST}
+    {3212960400 7200 0 EET}
+    {3226266000 10800 1 EEST}
+    {3245014800 7200 0 EET}
+    {3257715600 10800 1 EEST}
+    {3276464400 7200 0 EET}
+    {3289165200 10800 1 EEST}
+    {3307914000 7200 0 EET}
+    {3321219600 10800 1 EEST}
+    {3339363600 7200 0 EET}
+    {3352669200 10800 1 EEST}
+    {3370813200 7200 0 EET}
+    {3384118800 10800 1 EEST}
+    {3402867600 7200 0 EET}
+    {3415568400 10800 1 EEST}
+    {3434317200 7200 0 EET}
+    {3447018000 10800 1 EEST}
+    {3465766800 7200 0 EET}
+    {3479072400 10800 1 EEST}
+    {3497216400 7200 0 EET}
+    {3510522000 10800 1 EEST}
+    {3528666000 7200 0 EET}
+    {3541971600 10800 1 EEST}
+    {3560115600 7200 0 EET}
+    {3573421200 10800 1 EEST}
+    {3592170000 7200 0 EET}
+    {3604870800 10800 1 EEST}
+    {3623619600 7200 0 EET}
+    {3636320400 10800 1 EEST}
+    {3655069200 7200 0 EET}
+    {3668374800 10800 1 EEST}
+    {3686518800 7200 0 EET}
+    {3699824400 10800 1 EEST}
+    {3717968400 7200 0 EET}
+    {3731274000 10800 1 EEST}
+    {3750022800 7200 0 EET}
+    {3762723600 10800 1 EEST}
+    {3781472400 7200 0 EET}
+    {3794173200 10800 1 EEST}
+    {3812922000 7200 0 EET}
+    {3825622800 10800 1 EEST}
+    {3844371600 7200 0 EET}
+    {3857677200 10800 1 EEST}
+    {3875821200 7200 0 EET}
+    {3889126800 10800 1 EEST}
+    {3907270800 7200 0 EET}
+    {3920576400 10800 1 EEST}
+    {3939325200 7200 0 EET}
+    {3952026000 10800 1 EEST}
+    {3970774800 7200 0 EET}
+    {3983475600 10800 1 EEST}
+    {4002224400 7200 0 EET}
+    {4015530000 10800 1 EEST}
+    {4033674000 7200 0 EET}
+    {4046979600 10800 1 EEST}
+    {4065123600 7200 0 EET}
+    {4078429200 10800 1 EEST}
+    {4096573200 7200 0 EET}
+}
diff --git a/library/tzdata/Europe/Kirov b/library/tzdata/Europe/Kirov
new file mode 100644
index 0000000..82ffc9e
--- /dev/null
+++ b/library/tzdata/Europe/Kirov
@@ -0,0 +1,70 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Europe/Kirov) {
+    {-9223372036854775808 11928 0 LMT}
+    {-1593825528 10800 0 +03}
+    {-1247540400 14400 0 +05}
+    {354916800 18000 1 +05}
+    {370724400 14400 0 +04}
+    {386452800 18000 1 +05}
+    {402260400 14400 0 +04}
+    {417988800 18000 1 +05}
+    {433796400 14400 0 +04}
+    {449611200 18000 1 +05}
+    {465343200 14400 0 +04}
+    {481068000 18000 1 +05}
+    {496792800 14400 0 +04}
+    {512517600 18000 1 +05}
+    {528242400 14400 0 +04}
+    {543967200 18000 1 +05}
+    {559692000 14400 0 +04}
+    {575416800 18000 1 +05}
+    {591141600 14400 0 +04}
+    {606866400 10800 0 +04}
+    {606870000 14400 1 +04}
+    {622594800 10800 0 +03}
+    {638319600 14400 1 +04}
+    {654649200 10800 0 +03}
+    {670374000 14400 0 +04}
+    {701820000 10800 0 +04}
+    {701823600 14400 1 +04}
+    {717548400 10800 0 +03}
+    {733273200 14400 1 +04}
+    {748998000 10800 0 +03}
+    {764722800 14400 1 +04}
+    {780447600 10800 0 +03}
+    {796172400 14400 1 +04}
+    {811897200 10800 0 +03}
+    {828226800 14400 1 +04}
+    {846370800 10800 0 +03}
+    {859676400 14400 1 +04}
+    {877820400 10800 0 +03}
+    {891126000 14400 1 +04}
+    {909270000 10800 0 +03}
+    {922575600 14400 1 +04}
+    {941324400 10800 0 +03}
+    {954025200 14400 1 +04}
+    {972774000 10800 0 +03}
+    {985474800 14400 1 +04}
+    {1004223600 10800 0 +03}
+    {1017529200 14400 1 +04}
+    {1035673200 10800 0 +03}
+    {1048978800 14400 1 +04}
+    {1067122800 10800 0 +03}
+    {1080428400 14400 1 +04}
+    {1099177200 10800 0 +03}
+    {1111878000 14400 1 +04}
+    {1130626800 10800 0 +03}
+    {1143327600 14400 1 +04}
+    {1162076400 10800 0 +03}
+    {1174777200 14400 1 +04}
+    {1193526000 10800 0 +03}
+    {1206831600 14400 1 +04}
+    {1224975600 10800 0 +03}
+    {1238281200 14400 1 +04}
+    {1256425200 10800 0 +03}
+    {1269730800 14400 1 +04}
+    {1288479600 10800 0 +03}
+    {1301180400 14400 0 +04}
+    {1414274400 10800 0 +03}
+}
diff --git a/library/tzdata/Europe/Lisbon b/library/tzdata/Europe/Lisbon
new file mode 100644
index 0000000..7168f96
--- /dev/null
+++ b/library/tzdata/Europe/Lisbon
@@ -0,0 +1,351 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Europe/Lisbon) {
+    {-9223372036854775808 -2205 0 LMT}
+    {-2713908195 -2205 0 LMT}
+    {-1830381795 0 0 WET}
+    {-1689555600 3600 1 WEST}
+    {-1677801600 0 0 WET}
+    {-1667437200 3600 1 WEST}
+    {-1647738000 0 0 WET}
+    {-1635814800 3600 1 WEST}
+    {-1616202000 0 0 WET}
+    {-1604365200 3600 1 WEST}
+    {-1584666000 0 0 WET}
+    {-1572742800 3600 1 WEST}
+    {-1553043600 0 0 WET}
+    {-1541206800 3600 1 WEST}
+    {-1521507600 0 0 WET}
+    {-1442451600 3600 1 WEST}
+    {-1426813200 0 0 WET}
+    {-1379293200 3600 1 WEST}
+    {-1364778000 0 0 WET}
+    {-1348448400 3600 1 WEST}
+    {-1333328400 0 0 WET}
+    {-1316394000 3600 1 WEST}
+    {-1301274000 0 0 WET}
+    {-1284339600 3600 1 WEST}
+    {-1269824400 0 0 WET}
+    {-1221440400 3600 1 WEST}
+    {-1206925200 0 0 WET}
+    {-1191200400 3600 1 WEST}
+    {-1175475600 0 0 WET}
+    {-1127696400 3600 1 WEST}
+    {-1111971600 0 0 WET}
+    {-1096851600 3600 1 WEST}
+    {-1080522000 0 0 WET}
+    {-1063587600 3600 1 WEST}
+    {-1049072400 0 0 WET}
+    {-1033347600 3600 1 WEST}
+    {-1017622800 0 0 WET}
+    {-1002502800 3600 1 WEST}
+    {-986173200 0 0 WET}
+    {-969238800 3600 1 WEST}
+    {-950490000 0 0 WET}
+    {-942022800 3600 1 WEST}
+    {-922669200 0 0 WET}
+    {-906944400 3600 1 WEST}
+    {-891133200 0 0 WET}
+    {-877309200 3600 1 WEST}
+    {-873684000 7200 1 WEMT}
+    {-864007200 3600 1 WEST}
+    {-857955600 0 0 WET}
+    {-845859600 3600 1 WEST}
+    {-842839200 7200 1 WEMT}
+    {-831348000 3600 1 WEST}
+    {-825901200 0 0 WET}
+    {-814410000 3600 1 WEST}
+    {-810784800 7200 1 WEMT}
+    {-799898400 3600 1 WEST}
+    {-794451600 0 0 WET}
+    {-782960400 3600 1 WEST}
+    {-779335200 7200 1 WEMT}
+    {-768448800 3600 1 WEST}
+    {-763002000 0 0 WET}
+    {-749091600 3600 1 WEST}
+    {-733366800 0 0 WET}
+    {-717631200 3600 1 WEST}
+    {-701906400 0 0 WET}
+    {-686181600 3600 1 WEST}
+    {-670456800 0 0 WET}
+    {-654732000 3600 1 WEST}
+    {-639007200 0 0 WET}
+    {-591832800 3600 1 WEST}
+    {-575503200 0 0 WET}
+    {-559778400 3600 1 WEST}
+    {-544053600 0 0 WET}
+    {-528328800 3600 1 WEST}
+    {-512604000 0 0 WET}
+    {-496879200 3600 1 WEST}
+    {-481154400 0 0 WET}
+    {-465429600 3600 1 WEST}
+    {-449704800 0 0 WET}
+    {-433980000 3600 1 WEST}
+    {-417650400 0 0 WET}
+    {-401925600 3600 1 WEST}
+    {-386200800 0 0 WET}
+    {-370476000 3600 1 WEST}
+    {-354751200 0 0 WET}
+    {-339026400 3600 1 WEST}
+    {-323301600 0 0 WET}
+    {-307576800 3600 1 WEST}
+    {-291852000 0 0 WET}
+    {-276127200 3600 1 WEST}
+    {-260402400 0 0 WET}
+    {-244677600 3600 1 WEST}
+    {-228348000 0 0 WET}
+    {-212623200 3600 1 WEST}
+    {-196898400 0 0 WET}
+    {-181173600 3600 1 WEST}
+    {-165448800 0 0 WET}
+    {-149724000 3600 1 WEST}
+    {-133999200 0 0 WET}
+    {-118274400 3600 0 CET}
+    {212544000 0 0 WET}
+    {228268800 3600 1 WEST}
+    {243993600 0 0 WET}
+    {260323200 3600 1 WEST}
+    {276048000 0 0 WET}
+    {291772800 3600 1 WEST}
+    {307501200 0 0 WET}
+    {323222400 3600 1 WEST}
+    {338950800 0 0 WET}
+    {354675600 3600 1 WEST}
+    {370400400 0 0 WET}
+    {386125200 3600 1 WEST}
+    {401850000 0 0 WET}
+    {417578400 3600 1 WEST}
+    {433299600 0 0 WET}
+    {449024400 3600 1 WEST}
+    {465354000 0 0 WET}
+    {481078800 3600 1 WEST}
+    {496803600 0 0 WET}
+    {512528400 3600 1 WEST}
+    {528253200 0 0 WET}
+    {543978000 3600 1 WEST}
+    {559702800 0 0 WET}
+    {575427600 3600 1 WEST}
+    {591152400 0 0 WET}
+    {606877200 3600 1 WEST}
+    {622602000 0 0 WET}
+    {638326800 3600 1 WEST}
+    {654656400 0 0 WET}
+    {670381200 3600 1 WEST}
+    {686106000 0 0 WET}
+    {701830800 3600 1 WEST}
+    {717555600 3600 0 CET}
+    {733280400 7200 1 CEST}
+    {749005200 3600 0 CET}
+    {764730000 7200 1 CEST}
+    {780454800 3600 0 CET}
+    {796179600 7200 1 CEST}
+    {811904400 3600 0 CET}
+    {828234000 3600 0 WEST}
+    {846378000 0 0 WET}
+    {859683600 3600 1 WEST}
+    {877827600 0 0 WET}
+    {891133200 3600 1 WEST}
+    {909277200 0 0 WET}
+    {922582800 3600 1 WEST}
+    {941331600 0 0 WET}
+    {954032400 3600 1 WEST}
+    {972781200 0 0 WET}
+    {985482000 3600 1 WEST}
+    {1004230800 0 0 WET}
+    {1017536400 3600 1 WEST}
+    {1035680400 0 0 WET}
+    {1048986000 3600 1 WEST}
+    {1067130000 0 0 WET}
+    {1080435600 3600 1 WEST}
+    {1099184400 0 0 WET}
+    {1111885200 3600 1 WEST}
+    {1130634000 0 0 WET}
+    {1143334800 3600 1 WEST}
+    {1162083600 0 0 WET}
+    {1174784400 3600 1 WEST}
+    {1193533200 0 0 WET}
+    {1206838800 3600 1 WEST}
+    {1224982800 0 0 WET}
+    {1238288400 3600 1 WEST}
+    {1256432400 0 0 WET}
+    {1269738000 3600 1 WEST}
+    {1288486800 0 0 WET}
+    {1301187600 3600 1 WEST}
+    {1319936400 0 0 WET}
+    {1332637200 3600 1 WEST}
+    {1351386000 0 0 WET}
+    {1364691600 3600 1 WEST}
+    {1382835600 0 0 WET}
+    {1396141200 3600 1 WEST}
+    {1414285200 0 0 WET}
+    {1427590800 3600 1 WEST}
+    {1445734800 0 0 WET}
+    {1459040400 3600 1 WEST}
+    {1477789200 0 0 WET}
+    {1490490000 3600 1 WEST}
+    {1509238800 0 0 WET}
+    {1521939600 3600 1 WEST}
+    {1540688400 0 0 WET}
+    {1553994000 3600 1 WEST}
+    {1572138000 0 0 WET}
+    {1585443600 3600 1 WEST}
+    {1603587600 0 0 WET}
+    {1616893200 3600 1 WEST}
+    {1635642000 0 0 WET}
+    {1648342800 3600 1 WEST}
+    {1667091600 0 0 WET}
+    {1679792400 3600 1 WEST}
+    {1698541200 0 0 WET}
+    {1711846800 3600 1 WEST}
+    {1729990800 0 0 WET}
+    {1743296400 3600 1 WEST}
+    {1761440400 0 0 WET}
+    {1774746000 3600 1 WEST}
+    {1792890000 0 0 WET}
+    {1806195600 3600 1 WEST}
+    {1824944400 0 0 WET}
+    {1837645200 3600 1 WEST}
+    {1856394000 0 0 WET}
+    {1869094800 3600 1 WEST}
+    {1887843600 0 0 WET}
+    {1901149200 3600 1 WEST}
+    {1919293200 0 0 WET}
+    {1932598800 3600 1 WEST}
+    {1950742800 0 0 WET}
+    {1964048400 3600 1 WEST}
+    {1982797200 0 0 WET}
+    {1995498000 3600 1 WEST}
+    {2014246800 0 0 WET}
+    {2026947600 3600 1 WEST}
+    {2045696400 0 0 WET}
+    {2058397200 3600 1 WEST}
+    {2077146000 0 0 WET}
+    {2090451600 3600 1 WEST}
+    {2108595600 0 0 WET}
+    {2121901200 3600 1 WEST}
+    {2140045200 0 0 WET}
+    {2153350800 3600 1 WEST}
+    {2172099600 0 0 WET}
+    {2184800400 3600 1 WEST}
+    {2203549200 0 0 WET}
+    {2216250000 3600 1 WEST}
+    {2234998800 0 0 WET}
+    {2248304400 3600 1 WEST}
+    {2266448400 0 0 WET}
+    {2279754000 3600 1 WEST}
+    {2297898000 0 0 WET}
+    {2311203600 3600 1 WEST}
+    {2329347600 0 0 WET}
+    {2342653200 3600 1 WEST}
+    {2361402000 0 0 WET}
+    {2374102800 3600 1 WEST}
+    {2392851600 0 0 WET}
+    {2405552400 3600 1 WEST}
+    {2424301200 0 0 WET}
+    {2437606800 3600 1 WEST}
+    {2455750800 0 0 WET}
+    {2469056400 3600 1 WEST}
+    {2487200400 0 0 WET}
+    {2500506000 3600 1 WEST}
+    {2519254800 0 0 WET}
+    {2531955600 3600 1 WEST}
+    {2550704400 0 0 WET}
+    {2563405200 3600 1 WEST}
+    {2582154000 0 0 WET}
+    {2595459600 3600 1 WEST}
+    {2613603600 0 0 WET}
+    {2626909200 3600 1 WEST}
+    {2645053200 0 0 WET}
+    {2658358800 3600 1 WEST}
+    {2676502800 0 0 WET}
+    {2689808400 3600 1 WEST}
+    {2708557200 0 0 WET}
+    {2721258000 3600 1 WEST}
+    {2740006800 0 0 WET}
+    {2752707600 3600 1 WEST}
+    {2771456400 0 0 WET}
+    {2784762000 3600 1 WEST}
+    {2802906000 0 0 WET}
+    {2816211600 3600 1 WEST}
+    {2834355600 0 0 WET}
+    {2847661200 3600 1 WEST}
+    {2866410000 0 0 WET}
+    {2879110800 3600 1 WEST}
+    {2897859600 0 0 WET}
+    {2910560400 3600 1 WEST}
+    {2929309200 0 0 WET}
+    {2942010000 3600 1 WEST}
+    {2960758800 0 0 WET}
+    {2974064400 3600 1 WEST}
+    {2992208400 0 0 WET}
+    {3005514000 3600 1 WEST}
+    {3023658000 0 0 WET}
+    {3036963600 3600 1 WEST}
+    {3055712400 0 0 WET}
+    {3068413200 3600 1 WEST}
+    {3087162000 0 0 WET}
+    {3099862800 3600 1 WEST}
+    {3118611600 0 0 WET}
+    {3131917200 3600 1 WEST}
+    {3150061200 0 0 WET}
+    {3163366800 3600 1 WEST}
+    {3181510800 0 0 WET}
+    {3194816400 3600 1 WEST}
+    {3212960400 0 0 WET}
+    {3226266000 3600 1 WEST}
+    {3245014800 0 0 WET}
+    {3257715600 3600 1 WEST}
+    {3276464400 0 0 WET}
+    {3289165200 3600 1 WEST}
+    {3307914000 0 0 WET}
+    {3321219600 3600 1 WEST}
+    {3339363600 0 0 WET}
+    {3352669200 3600 1 WEST}
+    {3370813200 0 0 WET}
+    {3384118800 3600 1 WEST}
+    {3402867600 0 0 WET}
+    {3415568400 3600 1 WEST}
+    {3434317200 0 0 WET}
+    {3447018000 3600 1 WEST}
+    {3465766800 0 0 WET}
+    {3479072400 3600 1 WEST}
+    {3497216400 0 0 WET}
+    {3510522000 3600 1 WEST}
+    {3528666000 0 0 WET}
+    {3541971600 3600 1 WEST}
+    {3560115600 0 0 WET}
+    {3573421200 3600 1 WEST}
+    {3592170000 0 0 WET}
+    {3604870800 3600 1 WEST}
+    {3623619600 0 0 WET}
+    {3636320400 3600 1 WEST}
+    {3655069200 0 0 WET}
+    {3668374800 3600 1 WEST}
+    {3686518800 0 0 WET}
+    {3699824400 3600 1 WEST}
+    {3717968400 0 0 WET}
+    {3731274000 3600 1 WEST}
+    {3750022800 0 0 WET}
+    {3762723600 3600 1 WEST}
+    {3781472400 0 0 WET}
+    {3794173200 3600 1 WEST}
+    {3812922000 0 0 WET}
+    {3825622800 3600 1 WEST}
+    {3844371600 0 0 WET}
+    {3857677200 3600 1 WEST}
+    {3875821200 0 0 WET}
+    {3889126800 3600 1 WEST}
+    {3907270800 0 0 WET}
+    {3920576400 3600 1 WEST}
+    {3939325200 0 0 WET}
+    {3952026000 3600 1 WEST}
+    {3970774800 0 0 WET}
+    {3983475600 3600 1 WEST}
+    {4002224400 0 0 WET}
+    {4015530000 3600 1 WEST}
+    {4033674000 0 0 WET}
+    {4046979600 3600 1 WEST}
+    {4065123600 0 0 WET}
+    {4078429200 3600 1 WEST}
+    {4096573200 0 0 WET}
+}
diff --git a/library/tzdata/Europe/Ljubljana b/library/tzdata/Europe/Ljubljana
new file mode 100644
index 0000000..42c7df4
--- /dev/null
+++ b/library/tzdata/Europe/Ljubljana
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Europe/Belgrade)]} {
+    LoadTimeZoneFile Europe/Belgrade
+}
+set TZData(:Europe/Ljubljana) $TZData(:Europe/Belgrade)
diff --git a/library/tzdata/Europe/London b/library/tzdata/Europe/London
new file mode 100644
index 0000000..2014e00
--- /dev/null
+++ b/library/tzdata/Europe/London
@@ -0,0 +1,372 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Europe/London) {
+    {-9223372036854775808 -75 0 LMT}
+    {-3852662325 0 0 GMT}
+    {-1691964000 3600 1 BST}
+    {-1680472800 0 0 GMT}
+    {-1664143200 3600 1 BST}
+    {-1650146400 0 0 GMT}
+    {-1633903200 3600 1 BST}
+    {-1617487200 0 0 GMT}
+    {-1601848800 3600 1 BST}
+    {-1586037600 0 0 GMT}
+    {-1570399200 3600 1 BST}
+    {-1552168800 0 0 GMT}
+    {-1538344800 3600 1 BST}
+    {-1522533600 0 0 GMT}
+    {-1507500000 3600 1 BST}
+    {-1490565600 0 0 GMT}
+    {-1473631200 3600 1 BST}
+    {-1460930400 0 0 GMT}
+    {-1442786400 3600 1 BST}
+    {-1428876000 0 0 GMT}
+    {-1410732000 3600 1 BST}
+    {-1396216800 0 0 GMT}
+    {-1379282400 3600 1 BST}
+    {-1364767200 0 0 GMT}
+    {-1348437600 3600 1 BST}
+    {-1333317600 0 0 GMT}
+    {-1315778400 3600 1 BST}
+    {-1301263200 0 0 GMT}
+    {-1284328800 3600 1 BST}
+    {-1269813600 0 0 GMT}
+    {-1253484000 3600 1 BST}
+    {-1238364000 0 0 GMT}
+    {-1221429600 3600 1 BST}
+    {-1206914400 0 0 GMT}
+    {-1189980000 3600 1 BST}
+    {-1175464800 0 0 GMT}
+    {-1159135200 3600 1 BST}
+    {-1143410400 0 0 GMT}
+    {-1126476000 3600 1 BST}
+    {-1111960800 0 0 GMT}
+    {-1095631200 3600 1 BST}
+    {-1080511200 0 0 GMT}
+    {-1063576800 3600 1 BST}
+    {-1049061600 0 0 GMT}
+    {-1032127200 3600 1 BST}
+    {-1017612000 0 0 GMT}
+    {-1001282400 3600 1 BST}
+    {-986162400 0 0 GMT}
+    {-969228000 3600 1 BST}
+    {-950479200 0 0 GMT}
+    {-942012000 3600 1 BST}
+    {-904518000 7200 1 BDST}
+    {-896050800 3600 1 BST}
+    {-875487600 7200 1 BDST}
+    {-864601200 3600 1 BST}
+    {-844038000 7200 1 BDST}
+    {-832546800 3600 1 BST}
+    {-812588400 7200 1 BDST}
+    {-798073200 3600 1 BST}
+    {-781052400 7200 1 BDST}
+    {-772066800 3600 1 BST}
+    {-764805600 0 0 GMT}
+    {-748476000 3600 1 BST}
+    {-733356000 0 0 GMT}
+    {-719445600 3600 1 BST}
+    {-717030000 7200 1 BDST}
+    {-706748400 3600 1 BST}
+    {-699487200 0 0 GMT}
+    {-687996000 3600 1 BST}
+    {-668037600 0 0 GMT}
+    {-654732000 3600 1 BST}
+    {-636588000 0 0 GMT}
+    {-622072800 3600 1 BST}
+    {-605743200 0 0 GMT}
+    {-590623200 3600 1 BST}
+    {-574293600 0 0 GMT}
+    {-558568800 3600 1 BST}
+    {-542239200 0 0 GMT}
+    {-527119200 3600 1 BST}
+    {-512604000 0 0 GMT}
+    {-496274400 3600 1 BST}
+    {-481154400 0 0 GMT}
+    {-464220000 3600 1 BST}
+    {-449704800 0 0 GMT}
+    {-432165600 3600 1 BST}
+    {-417650400 0 0 GMT}
+    {-401320800 3600 1 BST}
+    {-386200800 0 0 GMT}
+    {-369266400 3600 1 BST}
+    {-354751200 0 0 GMT}
+    {-337816800 3600 1 BST}
+    {-323301600 0 0 GMT}
+    {-306972000 3600 1 BST}
+    {-291852000 0 0 GMT}
+    {-276732000 3600 1 BST}
+    {-257983200 0 0 GMT}
+    {-245282400 3600 1 BST}
+    {-226533600 0 0 GMT}
+    {-213228000 3600 1 BST}
+    {-195084000 0 0 GMT}
+    {-182383200 3600 1 BST}
+    {-163634400 0 0 GMT}
+    {-150933600 3600 1 BST}
+    {-132184800 0 0 GMT}
+    {-119484000 3600 1 BST}
+    {-100735200 0 0 GMT}
+    {-88034400 3600 1 BST}
+    {-68680800 0 0 GMT}
+    {-59004000 3600 1 BST}
+    {-37238400 3600 0 BST}
+    {57722400 0 0 GMT}
+    {69818400 3600 1 BST}
+    {89172000 0 0 GMT}
+    {101268000 3600 1 BST}
+    {120621600 0 0 GMT}
+    {132717600 3600 1 BST}
+    {152071200 0 0 GMT}
+    {164167200 3600 1 BST}
+    {183520800 0 0 GMT}
+    {196221600 3600 1 BST}
+    {214970400 0 0 GMT}
+    {227671200 3600 1 BST}
+    {246420000 0 0 GMT}
+    {259120800 3600 1 BST}
+    {278474400 0 0 GMT}
+    {290570400 3600 1 BST}
+    {309924000 0 0 GMT}
+    {322020000 3600 1 BST}
+    {341373600 0 0 GMT}
+    {354675600 3600 1 BST}
+    {372819600 0 0 GMT}
+    {386125200 3600 1 BST}
+    {404269200 0 0 GMT}
+    {417574800 3600 1 BST}
+    {435718800 0 0 GMT}
+    {449024400 3600 1 BST}
+    {467773200 0 0 GMT}
+    {481078800 3600 1 BST}
+    {499222800 0 0 GMT}
+    {512528400 3600 1 BST}
+    {530672400 0 0 GMT}
+    {543978000 3600 1 BST}
+    {562122000 0 0 GMT}
+    {575427600 3600 1 BST}
+    {593571600 0 0 GMT}
+    {606877200 3600 1 BST}
+    {625626000 0 0 GMT}
+    {638326800 3600 1 BST}
+    {657075600 0 0 GMT}
+    {670381200 3600 1 BST}
+    {688525200 0 0 GMT}
+    {701830800 3600 1 BST}
+    {719974800 0 0 GMT}
+    {733280400 3600 1 BST}
+    {751424400 0 0 GMT}
+    {764730000 3600 1 BST}
+    {782874000 0 0 GMT}
+    {796179600 3600 1 BST}
+    {814323600 0 0 GMT}
+    {820454400 0 0 GMT}
+    {828234000 3600 1 BST}
+    {846378000 0 0 GMT}
+    {859683600 3600 1 BST}
+    {877827600 0 0 GMT}
+    {891133200 3600 1 BST}
+    {909277200 0 0 GMT}
+    {922582800 3600 1 BST}
+    {941331600 0 0 GMT}
+    {954032400 3600 1 BST}
+    {972781200 0 0 GMT}
+    {985482000 3600 1 BST}
+    {1004230800 0 0 GMT}
+    {1017536400 3600 1 BST}
+    {1035680400 0 0 GMT}
+    {1048986000 3600 1 BST}
+    {1067130000 0 0 GMT}
+    {1080435600 3600 1 BST}
+    {1099184400 0 0 GMT}
+    {1111885200 3600 1 BST}
+    {1130634000 0 0 GMT}
+    {1143334800 3600 1 BST}
+    {1162083600 0 0 GMT}
+    {1174784400 3600 1 BST}
+    {1193533200 0 0 GMT}
+    {1206838800 3600 1 BST}
+    {1224982800 0 0 GMT}
+    {1238288400 3600 1 BST}
+    {1256432400 0 0 GMT}
+    {1269738000 3600 1 BST}
+    {1288486800 0 0 GMT}
+    {1301187600 3600 1 BST}
+    {1319936400 0 0 GMT}
+    {1332637200 3600 1 BST}
+    {1351386000 0 0 GMT}
+    {1364691600 3600 1 BST}
+    {1382835600 0 0 GMT}
+    {1396141200 3600 1 BST}
+    {1414285200 0 0 GMT}
+    {1427590800 3600 1 BST}
+    {1445734800 0 0 GMT}
+    {1459040400 3600 1 BST}
+    {1477789200 0 0 GMT}
+    {1490490000 3600 1 BST}
+    {1509238800 0 0 GMT}
+    {1521939600 3600 1 BST}
+    {1540688400 0 0 GMT}
+    {1553994000 3600 1 BST}
+    {1572138000 0 0 GMT}
+    {1585443600 3600 1 BST}
+    {1603587600 0 0 GMT}
+    {1616893200 3600 1 BST}
+    {1635642000 0 0 GMT}
+    {1648342800 3600 1 BST}
+    {1667091600 0 0 GMT}
+    {1679792400 3600 1 BST}
+    {1698541200 0 0 GMT}
+    {1711846800 3600 1 BST}
+    {1729990800 0 0 GMT}
+    {1743296400 3600 1 BST}
+    {1761440400 0 0 GMT}
+    {1774746000 3600 1 BST}
+    {1792890000 0 0 GMT}
+    {1806195600 3600 1 BST}
+    {1824944400 0 0 GMT}
+    {1837645200 3600 1 BST}
+    {1856394000 0 0 GMT}
+    {1869094800 3600 1 BST}
+    {1887843600 0 0 GMT}
+    {1901149200 3600 1 BST}
+    {1919293200 0 0 GMT}
+    {1932598800 3600 1 BST}
+    {1950742800 0 0 GMT}
+    {1964048400 3600 1 BST}
+    {1982797200 0 0 GMT}
+    {1995498000 3600 1 BST}
+    {2014246800 0 0 GMT}
+    {2026947600 3600 1 BST}
+    {2045696400 0 0 GMT}
+    {2058397200 3600 1 BST}
+    {2077146000 0 0 GMT}
+    {2090451600 3600 1 BST}
+    {2108595600 0 0 GMT}
+    {2121901200 3600 1 BST}
+    {2140045200 0 0 GMT}
+    {2153350800 3600 1 BST}
+    {2172099600 0 0 GMT}
+    {2184800400 3600 1 BST}
+    {2203549200 0 0 GMT}
+    {2216250000 3600 1 BST}
+    {2234998800 0 0 GMT}
+    {2248304400 3600 1 BST}
+    {2266448400 0 0 GMT}
+    {2279754000 3600 1 BST}
+    {2297898000 0 0 GMT}
+    {2311203600 3600 1 BST}
+    {2329347600 0 0 GMT}
+    {2342653200 3600 1 BST}
+    {2361402000 0 0 GMT}
+    {2374102800 3600 1 BST}
+    {2392851600 0 0 GMT}
+    {2405552400 3600 1 BST}
+    {2424301200 0 0 GMT}
+    {2437606800 3600 1 BST}
+    {2455750800 0 0 GMT}
+    {2469056400 3600 1 BST}
+    {2487200400 0 0 GMT}
+    {2500506000 3600 1 BST}
+    {2519254800 0 0 GMT}
+    {2531955600 3600 1 BST}
+    {2550704400 0 0 GMT}
+    {2563405200 3600 1 BST}
+    {2582154000 0 0 GMT}
+    {2595459600 3600 1 BST}
+    {2613603600 0 0 GMT}
+    {2626909200 3600 1 BST}
+    {2645053200 0 0 GMT}
+    {2658358800 3600 1 BST}
+    {2676502800 0 0 GMT}
+    {2689808400 3600 1 BST}
+    {2708557200 0 0 GMT}
+    {2721258000 3600 1 BST}
+    {2740006800 0 0 GMT}
+    {2752707600 3600 1 BST}
+    {2771456400 0 0 GMT}
+    {2784762000 3600 1 BST}
+    {2802906000 0 0 GMT}
+    {2816211600 3600 1 BST}
+    {2834355600 0 0 GMT}
+    {2847661200 3600 1 BST}
+    {2866410000 0 0 GMT}
+    {2879110800 3600 1 BST}
+    {2897859600 0 0 GMT}
+    {2910560400 3600 1 BST}
+    {2929309200 0 0 GMT}
+    {2942010000 3600 1 BST}
+    {2960758800 0 0 GMT}
+    {2974064400 3600 1 BST}
+    {2992208400 0 0 GMT}
+    {3005514000 3600 1 BST}
+    {3023658000 0 0 GMT}
+    {3036963600 3600 1 BST}
+    {3055712400 0 0 GMT}
+    {3068413200 3600 1 BST}
+    {3087162000 0 0 GMT}
+    {3099862800 3600 1 BST}
+    {3118611600 0 0 GMT}
+    {3131917200 3600 1 BST}
+    {3150061200 0 0 GMT}
+    {3163366800 3600 1 BST}
+    {3181510800 0 0 GMT}
+    {3194816400 3600 1 BST}
+    {3212960400 0 0 GMT}
+    {3226266000 3600 1 BST}
+    {3245014800 0 0 GMT}
+    {3257715600 3600 1 BST}
+    {3276464400 0 0 GMT}
+    {3289165200 3600 1 BST}
+    {3307914000 0 0 GMT}
+    {3321219600 3600 1 BST}
+    {3339363600 0 0 GMT}
+    {3352669200 3600 1 BST}
+    {3370813200 0 0 GMT}
+    {3384118800 3600 1 BST}
+    {3402867600 0 0 GMT}
+    {3415568400 3600 1 BST}
+    {3434317200 0 0 GMT}
+    {3447018000 3600 1 BST}
+    {3465766800 0 0 GMT}
+    {3479072400 3600 1 BST}
+    {3497216400 0 0 GMT}
+    {3510522000 3600 1 BST}
+    {3528666000 0 0 GMT}
+    {3541971600 3600 1 BST}
+    {3560115600 0 0 GMT}
+    {3573421200 3600 1 BST}
+    {3592170000 0 0 GMT}
+    {3604870800 3600 1 BST}
+    {3623619600 0 0 GMT}
+    {3636320400 3600 1 BST}
+    {3655069200 0 0 GMT}
+    {3668374800 3600 1 BST}
+    {3686518800 0 0 GMT}
+    {3699824400 3600 1 BST}
+    {3717968400 0 0 GMT}
+    {3731274000 3600 1 BST}
+    {3750022800 0 0 GMT}
+    {3762723600 3600 1 BST}
+    {3781472400 0 0 GMT}
+    {3794173200 3600 1 BST}
+    {3812922000 0 0 GMT}
+    {3825622800 3600 1 BST}
+    {3844371600 0 0 GMT}
+    {3857677200 3600 1 BST}
+    {3875821200 0 0 GMT}
+    {3889126800 3600 1 BST}
+    {3907270800 0 0 GMT}
+    {3920576400 3600 1 BST}
+    {3939325200 0 0 GMT}
+    {3952026000 3600 1 BST}
+    {3970774800 0 0 GMT}
+    {3983475600 3600 1 BST}
+    {4002224400 0 0 GMT}
+    {4015530000 3600 1 BST}
+    {4033674000 0 0 GMT}
+    {4046979600 3600 1 BST}
+    {4065123600 0 0 GMT}
+    {4078429200 3600 1 BST}
+    {4096573200 0 0 GMT}
+}
diff --git a/library/tzdata/Europe/Luxembourg b/library/tzdata/Europe/Luxembourg
new file mode 100644
index 0000000..2a88c4b
--- /dev/null
+++ b/library/tzdata/Europe/Luxembourg
@@ -0,0 +1,313 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Europe/Luxembourg) {
+    {-9223372036854775808 1476 0 LMT}
+    {-2069713476 3600 0 CET}
+    {-1692496800 7200 1 CEST}
+    {-1680483600 3600 0 CET}
+    {-1662343200 7200 1 CEST}
+    {-1650157200 3600 0 CET}
+    {-1632006000 7200 1 CEST}
+    {-1618700400 3600 0 CET}
+    {-1612659600 0 0 WET}
+    {-1604278800 3600 1 WEST}
+    {-1585519200 0 0 WET}
+    {-1574038800 3600 1 WEST}
+    {-1552258800 0 0 WET}
+    {-1539997200 3600 1 WEST}
+    {-1520550000 0 0 WET}
+    {-1507510800 3600 1 WEST}
+    {-1490572800 0 0 WET}
+    {-1473642000 3600 1 WEST}
+    {-1459119600 0 0 WET}
+    {-1444006800 3600 1 WEST}
+    {-1427673600 0 0 WET}
+    {-1411866000 3600 1 WEST}
+    {-1396224000 0 0 WET}
+    {-1379293200 3600 1 WEST}
+    {-1364774400 0 0 WET}
+    {-1348448400 3600 1 WEST}
+    {-1333324800 0 0 WET}
+    {-1316394000 3600 1 WEST}
+    {-1301270400 0 0 WET}
+    {-1284339600 3600 1 WEST}
+    {-1269813600 0 0 WET}
+    {-1253484000 3600 1 WEST}
+    {-1238364000 0 0 WET}
+    {-1221429600 3600 1 WEST}
+    {-1206914400 0 0 WET}
+    {-1191189600 3600 1 WEST}
+    {-1175464800 0 0 WET}
+    {-1160344800 3600 1 WEST}
+    {-1143410400 0 0 WET}
+    {-1127685600 3600 1 WEST}
+    {-1111960800 0 0 WET}
+    {-1096840800 3600 1 WEST}
+    {-1080511200 0 0 WET}
+    {-1063576800 3600 1 WEST}
+    {-1049061600 0 0 WET}
+    {-1033336800 3600 1 WEST}
+    {-1017612000 0 0 WET}
+    {-1002492000 3600 1 WEST}
+    {-986162400 0 0 WET}
+    {-969228000 3600 1 WEST}
+    {-950479200 0 0 WET}
+    {-942012000 3600 1 WEST}
+    {-935186400 7200 0 WEST}
+    {-857257200 3600 0 WET}
+    {-844556400 7200 1 WEST}
+    {-828226800 3600 0 WET}
+    {-812502000 7200 1 WEST}
+    {-797983200 3600 0 CET}
+    {-781052400 7200 1 CEST}
+    {-766623600 3600 0 CET}
+    {-745455600 7200 1 CEST}
+    {-733273200 3600 0 CET}
+    {220921200 3600 0 CET}
+    {228877200 7200 1 CEST}
+    {243997200 3600 0 CET}
+    {260326800 7200 1 CEST}
+    {276051600 3600 0 CET}
+    {291776400 7200 1 CEST}
+    {307501200 3600 0 CET}
+    {323830800 7200 1 CEST}
+    {338950800 3600 0 CET}
+    {354675600 7200 1 CEST}
+    {370400400 3600 0 CET}
+    {386125200 7200 1 CEST}
+    {401850000 3600 0 CET}
+    {417574800 7200 1 CEST}
+    {433299600 3600 0 CET}
+    {449024400 7200 1 CEST}
+    {465354000 3600 0 CET}
+    {481078800 7200 1 CEST}
+    {496803600 3600 0 CET}
+    {512528400 7200 1 CEST}
+    {528253200 3600 0 CET}
+    {543978000 7200 1 CEST}
+    {559702800 3600 0 CET}
+    {575427600 7200 1 CEST}
+    {591152400 3600 0 CET}
+    {606877200 7200 1 CEST}
+    {622602000 3600 0 CET}
+    {638326800 7200 1 CEST}
+    {654656400 3600 0 CET}
+    {670381200 7200 1 CEST}
+    {686106000 3600 0 CET}
+    {701830800 7200 1 CEST}
+    {717555600 3600 0 CET}
+    {733280400 7200 1 CEST}
+    {749005200 3600 0 CET}
+    {764730000 7200 1 CEST}
+    {780454800 3600 0 CET}
+    {796179600 7200 1 CEST}
+    {811904400 3600 0 CET}
+    {828234000 7200 1 CEST}
+    {846378000 3600 0 CET}
+    {859683600 7200 1 CEST}
+    {877827600 3600 0 CET}
+    {891133200 7200 1 CEST}
+    {909277200 3600 0 CET}
+    {922582800 7200 1 CEST}
+    {941331600 3600 0 CET}
+    {954032400 7200 1 CEST}
+    {972781200 3600 0 CET}
+    {985482000 7200 1 CEST}
+    {1004230800 3600 0 CET}
+    {1017536400 7200 1 CEST}
+    {1035680400 3600 0 CET}
+    {1048986000 7200 1 CEST}
+    {1067130000 3600 0 CET}
+    {1080435600 7200 1 CEST}
+    {1099184400 3600 0 CET}
+    {1111885200 7200 1 CEST}
+    {1130634000 3600 0 CET}
+    {1143334800 7200 1 CEST}
+    {1162083600 3600 0 CET}
+    {1174784400 7200 1 CEST}
+    {1193533200 3600 0 CET}
+    {1206838800 7200 1 CEST}
+    {1224982800 3600 0 CET}
+    {1238288400 7200 1 CEST}
+    {1256432400 3600 0 CET}
+    {1269738000 7200 1 CEST}
+    {1288486800 3600 0 CET}
+    {1301187600 7200 1 CEST}
+    {1319936400 3600 0 CET}
+    {1332637200 7200 1 CEST}
+    {1351386000 3600 0 CET}
+    {1364691600 7200 1 CEST}
+    {1382835600 3600 0 CET}
+    {1396141200 7200 1 CEST}
+    {1414285200 3600 0 CET}
+    {1427590800 7200 1 CEST}
+    {1445734800 3600 0 CET}
+    {1459040400 7200 1 CEST}
+    {1477789200 3600 0 CET}
+    {1490490000 7200 1 CEST}
+    {1509238800 3600 0 CET}
+    {1521939600 7200 1 CEST}
+    {1540688400 3600 0 CET}
+    {1553994000 7200 1 CEST}
+    {1572138000 3600 0 CET}
+    {1585443600 7200 1 CEST}
+    {1603587600 3600 0 CET}
+    {1616893200 7200 1 CEST}
+    {1635642000 3600 0 CET}
+    {1648342800 7200 1 CEST}
+    {1667091600 3600 0 CET}
+    {1679792400 7200 1 CEST}
+    {1698541200 3600 0 CET}
+    {1711846800 7200 1 CEST}
+    {1729990800 3600 0 CET}
+    {1743296400 7200 1 CEST}
+    {1761440400 3600 0 CET}
+    {1774746000 7200 1 CEST}
+    {1792890000 3600 0 CET}
+    {1806195600 7200 1 CEST}
+    {1824944400 3600 0 CET}
+    {1837645200 7200 1 CEST}
+    {1856394000 3600 0 CET}
+    {1869094800 7200 1 CEST}
+    {1887843600 3600 0 CET}
+    {1901149200 7200 1 CEST}
+    {1919293200 3600 0 CET}
+    {1932598800 7200 1 CEST}
+    {1950742800 3600 0 CET}
+    {1964048400 7200 1 CEST}
+    {1982797200 3600 0 CET}
+    {1995498000 7200 1 CEST}
+    {2014246800 3600 0 CET}
+    {2026947600 7200 1 CEST}
+    {2045696400 3600 0 CET}
+    {2058397200 7200 1 CEST}
+    {2077146000 3600 0 CET}
+    {2090451600 7200 1 CEST}
+    {2108595600 3600 0 CET}
+    {2121901200 7200 1 CEST}
+    {2140045200 3600 0 CET}
+    {2153350800 7200 1 CEST}
+    {2172099600 3600 0 CET}
+    {2184800400 7200 1 CEST}
+    {2203549200 3600 0 CET}
+    {2216250000 7200 1 CEST}
+    {2234998800 3600 0 CET}
+    {2248304400 7200 1 CEST}
+    {2266448400 3600 0 CET}
+    {2279754000 7200 1 CEST}
+    {2297898000 3600 0 CET}
+    {2311203600 7200 1 CEST}
+    {2329347600 3600 0 CET}
+    {2342653200 7200 1 CEST}
+    {2361402000 3600 0 CET}
+    {2374102800 7200 1 CEST}
+    {2392851600 3600 0 CET}
+    {2405552400 7200 1 CEST}
+    {2424301200 3600 0 CET}
+    {2437606800 7200 1 CEST}
+    {2455750800 3600 0 CET}
+    {2469056400 7200 1 CEST}
+    {2487200400 3600 0 CET}
+    {2500506000 7200 1 CEST}
+    {2519254800 3600 0 CET}
+    {2531955600 7200 1 CEST}
+    {2550704400 3600 0 CET}
+    {2563405200 7200 1 CEST}
+    {2582154000 3600 0 CET}
+    {2595459600 7200 1 CEST}
+    {2613603600 3600 0 CET}
+    {2626909200 7200 1 CEST}
+    {2645053200 3600 0 CET}
+    {2658358800 7200 1 CEST}
+    {2676502800 3600 0 CET}
+    {2689808400 7200 1 CEST}
+    {2708557200 3600 0 CET}
+    {2721258000 7200 1 CEST}
+    {2740006800 3600 0 CET}
+    {2752707600 7200 1 CEST}
+    {2771456400 3600 0 CET}
+    {2784762000 7200 1 CEST}
+    {2802906000 3600 0 CET}
+    {2816211600 7200 1 CEST}
+    {2834355600 3600 0 CET}
+    {2847661200 7200 1 CEST}
+    {2866410000 3600 0 CET}
+    {2879110800 7200 1 CEST}
+    {2897859600 3600 0 CET}
+    {2910560400 7200 1 CEST}
+    {2929309200 3600 0 CET}
+    {2942010000 7200 1 CEST}
+    {2960758800 3600 0 CET}
+    {2974064400 7200 1 CEST}
+    {2992208400 3600 0 CET}
+    {3005514000 7200 1 CEST}
+    {3023658000 3600 0 CET}
+    {3036963600 7200 1 CEST}
+    {3055712400 3600 0 CET}
+    {3068413200 7200 1 CEST}
+    {3087162000 3600 0 CET}
+    {3099862800 7200 1 CEST}
+    {3118611600 3600 0 CET}
+    {3131917200 7200 1 CEST}
+    {3150061200 3600 0 CET}
+    {3163366800 7200 1 CEST}
+    {3181510800 3600 0 CET}
+    {3194816400 7200 1 CEST}
+    {3212960400 3600 0 CET}
+    {3226266000 7200 1 CEST}
+    {3245014800 3600 0 CET}
+    {3257715600 7200 1 CEST}
+    {3276464400 3600 0 CET}
+    {3289165200 7200 1 CEST}
+    {3307914000 3600 0 CET}
+    {3321219600 7200 1 CEST}
+    {3339363600 3600 0 CET}
+    {3352669200 7200 1 CEST}
+    {3370813200 3600 0 CET}
+    {3384118800 7200 1 CEST}
+    {3402867600 3600 0 CET}
+    {3415568400 7200 1 CEST}
+    {3434317200 3600 0 CET}
+    {3447018000 7200 1 CEST}
+    {3465766800 3600 0 CET}
+    {3479072400 7200 1 CEST}
+    {3497216400 3600 0 CET}
+    {3510522000 7200 1 CEST}
+    {3528666000 3600 0 CET}
+    {3541971600 7200 1 CEST}
+    {3560115600 3600 0 CET}
+    {3573421200 7200 1 CEST}
+    {3592170000 3600 0 CET}
+    {3604870800 7200 1 CEST}
+    {3623619600 3600 0 CET}
+    {3636320400 7200 1 CEST}
+    {3655069200 3600 0 CET}
+    {3668374800 7200 1 CEST}
+    {3686518800 3600 0 CET}
+    {3699824400 7200 1 CEST}
+    {3717968400 3600 0 CET}
+    {3731274000 7200 1 CEST}
+    {3750022800 3600 0 CET}
+    {3762723600 7200 1 CEST}
+    {3781472400 3600 0 CET}
+    {3794173200 7200 1 CEST}
+    {3812922000 3600 0 CET}
+    {3825622800 7200 1 CEST}
+    {3844371600 3600 0 CET}
+    {3857677200 7200 1 CEST}
+    {3875821200 3600 0 CET}
+    {3889126800 7200 1 CEST}
+    {3907270800 3600 0 CET}
+    {3920576400 7200 1 CEST}
+    {3939325200 3600 0 CET}
+    {3952026000 7200 1 CEST}
+    {3970774800 3600 0 CET}
+    {3983475600 7200 1 CEST}
+    {4002224400 3600 0 CET}
+    {4015530000 7200 1 CEST}
+    {4033674000 3600 0 CET}
+    {4046979600 7200 1 CEST}
+    {4065123600 3600 0 CET}
+    {4078429200 7200 1 CEST}
+    {4096573200 3600 0 CET}
+}
diff --git a/library/tzdata/Europe/Madrid b/library/tzdata/Europe/Madrid
new file mode 100644
index 0000000..50de14f
--- /dev/null
+++ b/library/tzdata/Europe/Madrid
@@ -0,0 +1,294 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Europe/Madrid) {
+    {-9223372036854775808 -884 0 LMT}
+    {-2177451916 0 0 WET}
+    {-1661734800 3600 1 WEST}
+    {-1648429200 0 0 WET}
+    {-1631926800 3600 1 WEST}
+    {-1616893200 0 0 WET}
+    {-1601254800 3600 1 WEST}
+    {-1585357200 0 0 WET}
+    {-1442451600 3600 1 WEST}
+    {-1427677200 0 0 WET}
+    {-1379293200 3600 1 WEST}
+    {-1364778000 0 0 WET}
+    {-1348448400 3600 1 WEST}
+    {-1333328400 0 0 WET}
+    {-1316394000 3600 1 WEST}
+    {-1301274000 0 0 WET}
+    {-1284339600 3600 1 WEST}
+    {-1269824400 0 0 WET}
+    {-1029114000 3600 1 WEST}
+    {-1017622800 0 0 WET}
+    {-1002848400 3600 1 WEST}
+    {-986173200 0 0 WET}
+    {-969238800 3600 1 WEST}
+    {-954118800 0 0 WET}
+    {-940208400 3600 1 WEST}
+    {-873079200 7200 1 WEMT}
+    {-862538400 3600 1 WEST}
+    {-842839200 7200 1 WEMT}
+    {-828237600 3600 1 WEST}
+    {-811389600 7200 1 WEMT}
+    {-796010400 3600 1 WEST}
+    {-779940000 7200 1 WEMT}
+    {-765421200 3600 1 WEST}
+    {-748490400 7200 1 WEMT}
+    {-733881600 3600 0 CET}
+    {-652327200 7200 1 CEST}
+    {-639190800 3600 0 CET}
+    {135122400 7200 1 CEST}
+    {150246000 3600 0 CET}
+    {167176800 7200 1 CEST}
+    {181695600 3600 0 CET}
+    {196812000 7200 1 CEST}
+    {212540400 3600 0 CET}
+    {228866400 7200 1 CEST}
+    {243990000 3600 0 CET}
+    {260402400 7200 1 CEST}
+    {276044400 3600 0 CET}
+    {283993200 3600 0 CET}
+    {291776400 7200 1 CEST}
+    {307501200 3600 0 CET}
+    {323830800 7200 1 CEST}
+    {338950800 3600 0 CET}
+    {354675600 7200 1 CEST}
+    {370400400 3600 0 CET}
+    {386125200 7200 1 CEST}
+    {401850000 3600 0 CET}
+    {417574800 7200 1 CEST}
+    {433299600 3600 0 CET}
+    {449024400 7200 1 CEST}
+    {465354000 3600 0 CET}
+    {481078800 7200 1 CEST}
+    {496803600 3600 0 CET}
+    {512528400 7200 1 CEST}
+    {528253200 3600 0 CET}
+    {543978000 7200 1 CEST}
+    {559702800 3600 0 CET}
+    {575427600 7200 1 CEST}
+    {591152400 3600 0 CET}
+    {606877200 7200 1 CEST}
+    {622602000 3600 0 CET}
+    {638326800 7200 1 CEST}
+    {654656400 3600 0 CET}
+    {670381200 7200 1 CEST}
+    {686106000 3600 0 CET}
+    {701830800 7200 1 CEST}
+    {717555600 3600 0 CET}
+    {733280400 7200 1 CEST}
+    {749005200 3600 0 CET}
+    {764730000 7200 1 CEST}
+    {780454800 3600 0 CET}
+    {796179600 7200 1 CEST}
+    {811904400 3600 0 CET}
+    {828234000 7200 1 CEST}
+    {846378000 3600 0 CET}
+    {859683600 7200 1 CEST}
+    {877827600 3600 0 CET}
+    {891133200 7200 1 CEST}
+    {909277200 3600 0 CET}
+    {922582800 7200 1 CEST}
+    {941331600 3600 0 CET}
+    {954032400 7200 1 CEST}
+    {972781200 3600 0 CET}
+    {985482000 7200 1 CEST}
+    {1004230800 3600 0 CET}
+    {1017536400 7200 1 CEST}
+    {1035680400 3600 0 CET}
+    {1048986000 7200 1 CEST}
+    {1067130000 3600 0 CET}
+    {1080435600 7200 1 CEST}
+    {1099184400 3600 0 CET}
+    {1111885200 7200 1 CEST}
+    {1130634000 3600 0 CET}
+    {1143334800 7200 1 CEST}
+    {1162083600 3600 0 CET}
+    {1174784400 7200 1 CEST}
+    {1193533200 3600 0 CET}
+    {1206838800 7200 1 CEST}
+    {1224982800 3600 0 CET}
+    {1238288400 7200 1 CEST}
+    {1256432400 3600 0 CET}
+    {1269738000 7200 1 CEST}
+    {1288486800 3600 0 CET}
+    {1301187600 7200 1 CEST}
+    {1319936400 3600 0 CET}
+    {1332637200 7200 1 CEST}
+    {1351386000 3600 0 CET}
+    {1364691600 7200 1 CEST}
+    {1382835600 3600 0 CET}
+    {1396141200 7200 1 CEST}
+    {1414285200 3600 0 CET}
+    {1427590800 7200 1 CEST}
+    {1445734800 3600 0 CET}
+    {1459040400 7200 1 CEST}
+    {1477789200 3600 0 CET}
+    {1490490000 7200 1 CEST}
+    {1509238800 3600 0 CET}
+    {1521939600 7200 1 CEST}
+    {1540688400 3600 0 CET}
+    {1553994000 7200 1 CEST}
+    {1572138000 3600 0 CET}
+    {1585443600 7200 1 CEST}
+    {1603587600 3600 0 CET}
+    {1616893200 7200 1 CEST}
+    {1635642000 3600 0 CET}
+    {1648342800 7200 1 CEST}
+    {1667091600 3600 0 CET}
+    {1679792400 7200 1 CEST}
+    {1698541200 3600 0 CET}
+    {1711846800 7200 1 CEST}
+    {1729990800 3600 0 CET}
+    {1743296400 7200 1 CEST}
+    {1761440400 3600 0 CET}
+    {1774746000 7200 1 CEST}
+    {1792890000 3600 0 CET}
+    {1806195600 7200 1 CEST}
+    {1824944400 3600 0 CET}
+    {1837645200 7200 1 CEST}
+    {1856394000 3600 0 CET}
+    {1869094800 7200 1 CEST}
+    {1887843600 3600 0 CET}
+    {1901149200 7200 1 CEST}
+    {1919293200 3600 0 CET}
+    {1932598800 7200 1 CEST}
+    {1950742800 3600 0 CET}
+    {1964048400 7200 1 CEST}
+    {1982797200 3600 0 CET}
+    {1995498000 7200 1 CEST}
+    {2014246800 3600 0 CET}
+    {2026947600 7200 1 CEST}
+    {2045696400 3600 0 CET}
+    {2058397200 7200 1 CEST}
+    {2077146000 3600 0 CET}
+    {2090451600 7200 1 CEST}
+    {2108595600 3600 0 CET}
+    {2121901200 7200 1 CEST}
+    {2140045200 3600 0 CET}
+    {2153350800 7200 1 CEST}
+    {2172099600 3600 0 CET}
+    {2184800400 7200 1 CEST}
+    {2203549200 3600 0 CET}
+    {2216250000 7200 1 CEST}
+    {2234998800 3600 0 CET}
+    {2248304400 7200 1 CEST}
+    {2266448400 3600 0 CET}
+    {2279754000 7200 1 CEST}
+    {2297898000 3600 0 CET}
+    {2311203600 7200 1 CEST}
+    {2329347600 3600 0 CET}
+    {2342653200 7200 1 CEST}
+    {2361402000 3600 0 CET}
+    {2374102800 7200 1 CEST}
+    {2392851600 3600 0 CET}
+    {2405552400 7200 1 CEST}
+    {2424301200 3600 0 CET}
+    {2437606800 7200 1 CEST}
+    {2455750800 3600 0 CET}
+    {2469056400 7200 1 CEST}
+    {2487200400 3600 0 CET}
+    {2500506000 7200 1 CEST}
+    {2519254800 3600 0 CET}
+    {2531955600 7200 1 CEST}
+    {2550704400 3600 0 CET}
+    {2563405200 7200 1 CEST}
+    {2582154000 3600 0 CET}
+    {2595459600 7200 1 CEST}
+    {2613603600 3600 0 CET}
+    {2626909200 7200 1 CEST}
+    {2645053200 3600 0 CET}
+    {2658358800 7200 1 CEST}
+    {2676502800 3600 0 CET}
+    {2689808400 7200 1 CEST}
+    {2708557200 3600 0 CET}
+    {2721258000 7200 1 CEST}
+    {2740006800 3600 0 CET}
+    {2752707600 7200 1 CEST}
+    {2771456400 3600 0 CET}
+    {2784762000 7200 1 CEST}
+    {2802906000 3600 0 CET}
+    {2816211600 7200 1 CEST}
+    {2834355600 3600 0 CET}
+    {2847661200 7200 1 CEST}
+    {2866410000 3600 0 CET}
+    {2879110800 7200 1 CEST}
+    {2897859600 3600 0 CET}
+    {2910560400 7200 1 CEST}
+    {2929309200 3600 0 CET}
+    {2942010000 7200 1 CEST}
+    {2960758800 3600 0 CET}
+    {2974064400 7200 1 CEST}
+    {2992208400 3600 0 CET}
+    {3005514000 7200 1 CEST}
+    {3023658000 3600 0 CET}
+    {3036963600 7200 1 CEST}
+    {3055712400 3600 0 CET}
+    {3068413200 7200 1 CEST}
+    {3087162000 3600 0 CET}
+    {3099862800 7200 1 CEST}
+    {3118611600 3600 0 CET}
+    {3131917200 7200 1 CEST}
+    {3150061200 3600 0 CET}
+    {3163366800 7200 1 CEST}
+    {3181510800 3600 0 CET}
+    {3194816400 7200 1 CEST}
+    {3212960400 3600 0 CET}
+    {3226266000 7200 1 CEST}
+    {3245014800 3600 0 CET}
+    {3257715600 7200 1 CEST}
+    {3276464400 3600 0 CET}
+    {3289165200 7200 1 CEST}
+    {3307914000 3600 0 CET}
+    {3321219600 7200 1 CEST}
+    {3339363600 3600 0 CET}
+    {3352669200 7200 1 CEST}
+    {3370813200 3600 0 CET}
+    {3384118800 7200 1 CEST}
+    {3402867600 3600 0 CET}
+    {3415568400 7200 1 CEST}
+    {3434317200 3600 0 CET}
+    {3447018000 7200 1 CEST}
+    {3465766800 3600 0 CET}
+    {3479072400 7200 1 CEST}
+    {3497216400 3600 0 CET}
+    {3510522000 7200 1 CEST}
+    {3528666000 3600 0 CET}
+    {3541971600 7200 1 CEST}
+    {3560115600 3600 0 CET}
+    {3573421200 7200 1 CEST}
+    {3592170000 3600 0 CET}
+    {3604870800 7200 1 CEST}
+    {3623619600 3600 0 CET}
+    {3636320400 7200 1 CEST}
+    {3655069200 3600 0 CET}
+    {3668374800 7200 1 CEST}
+    {3686518800 3600 0 CET}
+    {3699824400 7200 1 CEST}
+    {3717968400 3600 0 CET}
+    {3731274000 7200 1 CEST}
+    {3750022800 3600 0 CET}
+    {3762723600 7200 1 CEST}
+    {3781472400 3600 0 CET}
+    {3794173200 7200 1 CEST}
+    {3812922000 3600 0 CET}
+    {3825622800 7200 1 CEST}
+    {3844371600 3600 0 CET}
+    {3857677200 7200 1 CEST}
+    {3875821200 3600 0 CET}
+    {3889126800 7200 1 CEST}
+    {3907270800 3600 0 CET}
+    {3920576400 7200 1 CEST}
+    {3939325200 3600 0 CET}
+    {3952026000 7200 1 CEST}
+    {3970774800 3600 0 CET}
+    {3983475600 7200 1 CEST}
+    {4002224400 3600 0 CET}
+    {4015530000 7200 1 CEST}
+    {4033674000 3600 0 CET}
+    {4046979600 7200 1 CEST}
+    {4065123600 3600 0 CET}
+    {4078429200 7200 1 CEST}
+    {4096573200 3600 0 CET}
+}
diff --git a/library/tzdata/Europe/Malta b/library/tzdata/Europe/Malta
new file mode 100644
index 0000000..b84f68e
--- /dev/null
+++ b/library/tzdata/Europe/Malta
@@ -0,0 +1,299 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Europe/Malta) {
+    {-9223372036854775808 3484 0 LMT}
+    {-2403478684 3600 0 CET}
+    {-1690851600 7200 1 CEST}
+    {-1680483600 3600 0 CET}
+    {-1664758800 7200 1 CEST}
+    {-1649034000 3600 0 CET}
+    {-1635123600 7200 1 CEST}
+    {-1616979600 3600 0 CET}
+    {-1604278800 7200 1 CEST}
+    {-1585530000 3600 0 CET}
+    {-1571014800 7200 1 CEST}
+    {-1555290000 3600 0 CET}
+    {-932432400 7200 1 CEST}
+    {-857257200 3600 0 CET}
+    {-844556400 7200 1 CEST}
+    {-828226800 3600 0 CET}
+    {-812502000 7200 1 CEST}
+    {-796777200 3600 0 CET}
+    {-781052400 7200 0 CEST}
+    {-766717200 3600 0 CET}
+    {-750898800 7200 1 CEST}
+    {-733359600 3600 0 CET}
+    {-719456400 7200 1 CEST}
+    {-701917200 3600 0 CET}
+    {-689209200 7200 1 CEST}
+    {-670460400 3600 0 CET}
+    {-114051600 7200 1 CEST}
+    {-103168800 3600 0 CET}
+    {-81997200 7200 1 CEST}
+    {-71719200 3600 0 CET}
+    {-50547600 7200 1 CEST}
+    {-40269600 3600 0 CET}
+    {-18493200 7200 1 CEST}
+    {-8215200 3600 0 CET}
+    {12956400 7200 1 CEST}
+    {23234400 3600 0 CET}
+    {43801200 7200 1 CEST}
+    {54687600 3600 0 CET}
+    {75855600 7200 1 CEST}
+    {86738400 3600 0 CET}
+    {102380400 7200 0 CEST}
+    {118105200 3600 0 CET}
+    {135730800 7200 1 CEST}
+    {148518000 3600 0 CET}
+    {167187600 7200 1 CEST}
+    {180489600 3600 0 CET}
+    {198637200 7200 1 CEST}
+    {211939200 3600 0 CET}
+    {230086800 7200 1 CEST}
+    {243388800 3600 0 CET}
+    {261536400 7200 1 CEST}
+    {274838400 3600 0 CET}
+    {292986000 7200 1 CEST}
+    {306288000 3600 0 CET}
+    {323312400 7200 1 CEST}
+    {338342400 3600 0 CET}
+    {347151600 3600 0 CET}
+    {354675600 7200 1 CEST}
+    {370400400 3600 0 CET}
+    {386125200 7200 1 CEST}
+    {401850000 3600 0 CET}
+    {417574800 7200 1 CEST}
+    {433299600 3600 0 CET}
+    {449024400 7200 1 CEST}
+    {465354000 3600 0 CET}
+    {481078800 7200 1 CEST}
+    {496803600 3600 0 CET}
+    {512528400 7200 1 CEST}
+    {528253200 3600 0 CET}
+    {543978000 7200 1 CEST}
+    {559702800 3600 0 CET}
+    {575427600 7200 1 CEST}
+    {591152400 3600 0 CET}
+    {606877200 7200 1 CEST}
+    {622602000 3600 0 CET}
+    {638326800 7200 1 CEST}
+    {654656400 3600 0 CET}
+    {670381200 7200 1 CEST}
+    {686106000 3600 0 CET}
+    {701830800 7200 1 CEST}
+    {717555600 3600 0 CET}
+    {733280400 7200 1 CEST}
+    {749005200 3600 0 CET}
+    {764730000 7200 1 CEST}
+    {780454800 3600 0 CET}
+    {796179600 7200 1 CEST}
+    {811904400 3600 0 CET}
+    {828234000 7200 1 CEST}
+    {846378000 3600 0 CET}
+    {859683600 7200 1 CEST}
+    {877827600 3600 0 CET}
+    {891133200 7200 1 CEST}
+    {909277200 3600 0 CET}
+    {922582800 7200 1 CEST}
+    {941331600 3600 0 CET}
+    {954032400 7200 1 CEST}
+    {972781200 3600 0 CET}
+    {985482000 7200 1 CEST}
+    {1004230800 3600 0 CET}
+    {1017536400 7200 1 CEST}
+    {1035680400 3600 0 CET}
+    {1048986000 7200 1 CEST}
+    {1067130000 3600 0 CET}
+    {1080435600 7200 1 CEST}
+    {1099184400 3600 0 CET}
+    {1111885200 7200 1 CEST}
+    {1130634000 3600 0 CET}
+    {1143334800 7200 1 CEST}
+    {1162083600 3600 0 CET}
+    {1174784400 7200 1 CEST}
+    {1193533200 3600 0 CET}
+    {1206838800 7200 1 CEST}
+    {1224982800 3600 0 CET}
+    {1238288400 7200 1 CEST}
+    {1256432400 3600 0 CET}
+    {1269738000 7200 1 CEST}
+    {1288486800 3600 0 CET}
+    {1301187600 7200 1 CEST}
+    {1319936400 3600 0 CET}
+    {1332637200 7200 1 CEST}
+    {1351386000 3600 0 CET}
+    {1364691600 7200 1 CEST}
+    {1382835600 3600 0 CET}
+    {1396141200 7200 1 CEST}
+    {1414285200 3600 0 CET}
+    {1427590800 7200 1 CEST}
+    {1445734800 3600 0 CET}
+    {1459040400 7200 1 CEST}
+    {1477789200 3600 0 CET}
+    {1490490000 7200 1 CEST}
+    {1509238800 3600 0 CET}
+    {1521939600 7200 1 CEST}
+    {1540688400 3600 0 CET}
+    {1553994000 7200 1 CEST}
+    {1572138000 3600 0 CET}
+    {1585443600 7200 1 CEST}
+    {1603587600 3600 0 CET}
+    {1616893200 7200 1 CEST}
+    {1635642000 3600 0 CET}
+    {1648342800 7200 1 CEST}
+    {1667091600 3600 0 CET}
+    {1679792400 7200 1 CEST}
+    {1698541200 3600 0 CET}
+    {1711846800 7200 1 CEST}
+    {1729990800 3600 0 CET}
+    {1743296400 7200 1 CEST}
+    {1761440400 3600 0 CET}
+    {1774746000 7200 1 CEST}
+    {1792890000 3600 0 CET}
+    {1806195600 7200 1 CEST}
+    {1824944400 3600 0 CET}
+    {1837645200 7200 1 CEST}
+    {1856394000 3600 0 CET}
+    {1869094800 7200 1 CEST}
+    {1887843600 3600 0 CET}
+    {1901149200 7200 1 CEST}
+    {1919293200 3600 0 CET}
+    {1932598800 7200 1 CEST}
+    {1950742800 3600 0 CET}
+    {1964048400 7200 1 CEST}
+    {1982797200 3600 0 CET}
+    {1995498000 7200 1 CEST}
+    {2014246800 3600 0 CET}
+    {2026947600 7200 1 CEST}
+    {2045696400 3600 0 CET}
+    {2058397200 7200 1 CEST}
+    {2077146000 3600 0 CET}
+    {2090451600 7200 1 CEST}
+    {2108595600 3600 0 CET}
+    {2121901200 7200 1 CEST}
+    {2140045200 3600 0 CET}
+    {2153350800 7200 1 CEST}
+    {2172099600 3600 0 CET}
+    {2184800400 7200 1 CEST}
+    {2203549200 3600 0 CET}
+    {2216250000 7200 1 CEST}
+    {2234998800 3600 0 CET}
+    {2248304400 7200 1 CEST}
+    {2266448400 3600 0 CET}
+    {2279754000 7200 1 CEST}
+    {2297898000 3600 0 CET}
+    {2311203600 7200 1 CEST}
+    {2329347600 3600 0 CET}
+    {2342653200 7200 1 CEST}
+    {2361402000 3600 0 CET}
+    {2374102800 7200 1 CEST}
+    {2392851600 3600 0 CET}
+    {2405552400 7200 1 CEST}
+    {2424301200 3600 0 CET}
+    {2437606800 7200 1 CEST}
+    {2455750800 3600 0 CET}
+    {2469056400 7200 1 CEST}
+    {2487200400 3600 0 CET}
+    {2500506000 7200 1 CEST}
+    {2519254800 3600 0 CET}
+    {2531955600 7200 1 CEST}
+    {2550704400 3600 0 CET}
+    {2563405200 7200 1 CEST}
+    {2582154000 3600 0 CET}
+    {2595459600 7200 1 CEST}
+    {2613603600 3600 0 CET}
+    {2626909200 7200 1 CEST}
+    {2645053200 3600 0 CET}
+    {2658358800 7200 1 CEST}
+    {2676502800 3600 0 CET}
+    {2689808400 7200 1 CEST}
+    {2708557200 3600 0 CET}
+    {2721258000 7200 1 CEST}
+    {2740006800 3600 0 CET}
+    {2752707600 7200 1 CEST}
+    {2771456400 3600 0 CET}
+    {2784762000 7200 1 CEST}
+    {2802906000 3600 0 CET}
+    {2816211600 7200 1 CEST}
+    {2834355600 3600 0 CET}
+    {2847661200 7200 1 CEST}
+    {2866410000 3600 0 CET}
+    {2879110800 7200 1 CEST}
+    {2897859600 3600 0 CET}
+    {2910560400 7200 1 CEST}
+    {2929309200 3600 0 CET}
+    {2942010000 7200 1 CEST}
+    {2960758800 3600 0 CET}
+    {2974064400 7200 1 CEST}
+    {2992208400 3600 0 CET}
+    {3005514000 7200 1 CEST}
+    {3023658000 3600 0 CET}
+    {3036963600 7200 1 CEST}
+    {3055712400 3600 0 CET}
+    {3068413200 7200 1 CEST}
+    {3087162000 3600 0 CET}
+    {3099862800 7200 1 CEST}
+    {3118611600 3600 0 CET}
+    {3131917200 7200 1 CEST}
+    {3150061200 3600 0 CET}
+    {3163366800 7200 1 CEST}
+    {3181510800 3600 0 CET}
+    {3194816400 7200 1 CEST}
+    {3212960400 3600 0 CET}
+    {3226266000 7200 1 CEST}
+    {3245014800 3600 0 CET}
+    {3257715600 7200 1 CEST}
+    {3276464400 3600 0 CET}
+    {3289165200 7200 1 CEST}
+    {3307914000 3600 0 CET}
+    {3321219600 7200 1 CEST}
+    {3339363600 3600 0 CET}
+    {3352669200 7200 1 CEST}
+    {3370813200 3600 0 CET}
+    {3384118800 7200 1 CEST}
+    {3402867600 3600 0 CET}
+    {3415568400 7200 1 CEST}
+    {3434317200 3600 0 CET}
+    {3447018000 7200 1 CEST}
+    {3465766800 3600 0 CET}
+    {3479072400 7200 1 CEST}
+    {3497216400 3600 0 CET}
+    {3510522000 7200 1 CEST}
+    {3528666000 3600 0 CET}
+    {3541971600 7200 1 CEST}
+    {3560115600 3600 0 CET}
+    {3573421200 7200 1 CEST}
+    {3592170000 3600 0 CET}
+    {3604870800 7200 1 CEST}
+    {3623619600 3600 0 CET}
+    {3636320400 7200 1 CEST}
+    {3655069200 3600 0 CET}
+    {3668374800 7200 1 CEST}
+    {3686518800 3600 0 CET}
+    {3699824400 7200 1 CEST}
+    {3717968400 3600 0 CET}
+    {3731274000 7200 1 CEST}
+    {3750022800 3600 0 CET}
+    {3762723600 7200 1 CEST}
+    {3781472400 3600 0 CET}
+    {3794173200 7200 1 CEST}
+    {3812922000 3600 0 CET}
+    {3825622800 7200 1 CEST}
+    {3844371600 3600 0 CET}
+    {3857677200 7200 1 CEST}
+    {3875821200 3600 0 CET}
+    {3889126800 7200 1 CEST}
+    {3907270800 3600 0 CET}
+    {3920576400 7200 1 CEST}
+    {3939325200 3600 0 CET}
+    {3952026000 7200 1 CEST}
+    {3970774800 3600 0 CET}
+    {3983475600 7200 1 CEST}
+    {4002224400 3600 0 CET}
+    {4015530000 7200 1 CEST}
+    {4033674000 3600 0 CET}
+    {4046979600 7200 1 CEST}
+    {4065123600 3600 0 CET}
+    {4078429200 7200 1 CEST}
+    {4096573200 3600 0 CET}
+}
diff --git a/library/tzdata/Europe/Mariehamn b/library/tzdata/Europe/Mariehamn
new file mode 100644
index 0000000..26d9177
--- /dev/null
+++ b/library/tzdata/Europe/Mariehamn
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Europe/Helsinki)]} {
+    LoadTimeZoneFile Europe/Helsinki
+}
+set TZData(:Europe/Mariehamn) $TZData(:Europe/Helsinki)
diff --git a/library/tzdata/Europe/Minsk b/library/tzdata/Europe/Minsk
new file mode 100644
index 0000000..2857e5b
--- /dev/null
+++ b/library/tzdata/Europe/Minsk
@@ -0,0 +1,76 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Europe/Minsk) {
+    {-9223372036854775808 6616 0 LMT}
+    {-2840147416 6600 0 MMT}
+    {-1441158600 7200 0 EET}
+    {-1247536800 10800 0 MSK}
+    {-899780400 3600 0 CET}
+    {-857257200 3600 0 CET}
+    {-844556400 7200 1 CEST}
+    {-828226800 3600 0 CET}
+    {-812502000 7200 1 CEST}
+    {-804646800 10800 0 MSD}
+    {354920400 14400 1 MSD}
+    {370728000 10800 0 MSK}
+    {386456400 14400 1 MSD}
+    {402264000 10800 0 MSK}
+    {417992400 14400 1 MSD}
+    {433800000 10800 0 MSK}
+    {449614800 14400 1 MSD}
+    {465346800 10800 0 MSK}
+    {481071600 14400 1 MSD}
+    {496796400 10800 0 MSK}
+    {512521200 14400 1 MSD}
+    {528246000 10800 0 MSK}
+    {543970800 14400 1 MSD}
+    {559695600 10800 0 MSK}
+    {575420400 14400 1 MSD}
+    {591145200 10800 0 MSK}
+    {606870000 14400 1 MSD}
+    {622594800 10800 0 MSK}
+    {631141200 10800 0 MSK}
+    {670374000 7200 0 EEMMTT}
+    {670377600 10800 1 EEST}
+    {686102400 7200 0 EET}
+    {701827200 10800 1 EEST}
+    {717552000 7200 0 EET}
+    {733276800 10800 1 EEST}
+    {749001600 7200 0 EET}
+    {764726400 10800 1 EEST}
+    {780451200 7200 0 EET}
+    {796176000 10800 1 EEST}
+    {811900800 7200 0 EET}
+    {828230400 10800 1 EEST}
+    {846374400 7200 0 EET}
+    {859680000 10800 1 EEST}
+    {877824000 7200 0 EET}
+    {891129600 10800 1 EEST}
+    {909273600 7200 0 EET}
+    {922579200 10800 1 EEST}
+    {941328000 7200 0 EET}
+    {954028800 10800 1 EEST}
+    {972777600 7200 0 EET}
+    {985478400 10800 1 EEST}
+    {1004227200 7200 0 EET}
+    {1017532800 10800 1 EEST}
+    {1035676800 7200 0 EET}
+    {1048982400 10800 1 EEST}
+    {1067126400 7200 0 EET}
+    {1080432000 10800 1 EEST}
+    {1099180800 7200 0 EET}
+    {1111881600 10800 1 EEST}
+    {1130630400 7200 0 EET}
+    {1143331200 10800 1 EEST}
+    {1162080000 7200 0 EET}
+    {1174780800 10800 1 EEST}
+    {1193529600 7200 0 EET}
+    {1206835200 10800 1 EEST}
+    {1224979200 7200 0 EET}
+    {1238284800 10800 1 EEST}
+    {1256428800 7200 0 EET}
+    {1269734400 10800 1 EEST}
+    {1288483200 7200 0 EET}
+    {1301184000 10800 0 FET}
+    {1414274400 10800 0 MSK}
+}
diff --git a/library/tzdata/Europe/Monaco b/library/tzdata/Europe/Monaco
new file mode 100644
index 0000000..f887b0b
--- /dev/null
+++ b/library/tzdata/Europe/Monaco
@@ -0,0 +1,315 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Europe/Monaco) {
+    {-9223372036854775808 1772 0 LMT}
+    {-2486680172 561 0 PMT}
+    {-1855958961 0 0 WET}
+    {-1689814800 3600 1 WEST}
+    {-1680397200 0 0 WET}
+    {-1665363600 3600 1 WEST}
+    {-1648342800 0 0 WET}
+    {-1635123600 3600 1 WEST}
+    {-1616893200 0 0 WET}
+    {-1604278800 3600 1 WEST}
+    {-1585443600 0 0 WET}
+    {-1574038800 3600 1 WEST}
+    {-1552266000 0 0 WET}
+    {-1539997200 3600 1 WEST}
+    {-1520557200 0 0 WET}
+    {-1507510800 3600 1 WEST}
+    {-1490576400 0 0 WET}
+    {-1470618000 3600 1 WEST}
+    {-1459126800 0 0 WET}
+    {-1444006800 3600 1 WEST}
+    {-1427677200 0 0 WET}
+    {-1411952400 3600 1 WEST}
+    {-1396227600 0 0 WET}
+    {-1379293200 3600 1 WEST}
+    {-1364778000 0 0 WET}
+    {-1348448400 3600 1 WEST}
+    {-1333328400 0 0 WET}
+    {-1316394000 3600 1 WEST}
+    {-1301274000 0 0 WET}
+    {-1284339600 3600 1 WEST}
+    {-1269824400 0 0 WET}
+    {-1253494800 3600 1 WEST}
+    {-1238374800 0 0 WET}
+    {-1221440400 3600 1 WEST}
+    {-1206925200 0 0 WET}
+    {-1191200400 3600 1 WEST}
+    {-1175475600 0 0 WET}
+    {-1160355600 3600 1 WEST}
+    {-1143421200 0 0 WET}
+    {-1127696400 3600 1 WEST}
+    {-1111971600 0 0 WET}
+    {-1096851600 3600 1 WEST}
+    {-1080522000 0 0 WET}
+    {-1063587600 3600 1 WEST}
+    {-1049072400 0 0 WET}
+    {-1033347600 3600 1 WEST}
+    {-1017622800 0 0 WET}
+    {-1002502800 3600 1 WEST}
+    {-986173200 0 0 WET}
+    {-969238800 3600 1 WEST}
+    {-950490000 0 0 WET}
+    {-942012000 3600 1 WEST}
+    {-904438800 7200 1 WEMT}
+    {-891136800 3600 1 WEST}
+    {-877827600 7200 1 WEMT}
+    {-857257200 3600 1 WEST}
+    {-844556400 7200 1 WEMT}
+    {-828226800 3600 1 WEST}
+    {-812502000 7200 1 WEMT}
+    {-796266000 3600 1 WEST}
+    {-781052400 7200 1 WEMT}
+    {-766616400 3600 0 CET}
+    {196819200 7200 1 CEST}
+    {212540400 3600 0 CET}
+    {220921200 3600 0 CET}
+    {228877200 7200 1 CEST}
+    {243997200 3600 0 CET}
+    {260326800 7200 1 CEST}
+    {276051600 3600 0 CET}
+    {291776400 7200 1 CEST}
+    {307501200 3600 0 CET}
+    {323830800 7200 1 CEST}
+    {338950800 3600 0 CET}
+    {354675600 7200 1 CEST}
+    {370400400 3600 0 CET}
+    {386125200 7200 1 CEST}
+    {401850000 3600 0 CET}
+    {417574800 7200 1 CEST}
+    {433299600 3600 0 CET}
+    {449024400 7200 1 CEST}
+    {465354000 3600 0 CET}
+    {481078800 7200 1 CEST}
+    {496803600 3600 0 CET}
+    {512528400 7200 1 CEST}
+    {528253200 3600 0 CET}
+    {543978000 7200 1 CEST}
+    {559702800 3600 0 CET}
+    {575427600 7200 1 CEST}
+    {591152400 3600 0 CET}
+    {606877200 7200 1 CEST}
+    {622602000 3600 0 CET}
+    {638326800 7200 1 CEST}
+    {654656400 3600 0 CET}
+    {670381200 7200 1 CEST}
+    {686106000 3600 0 CET}
+    {701830800 7200 1 CEST}
+    {717555600 3600 0 CET}
+    {733280400 7200 1 CEST}
+    {749005200 3600 0 CET}
+    {764730000 7200 1 CEST}
+    {780454800 3600 0 CET}
+    {796179600 7200 1 CEST}
+    {811904400 3600 0 CET}
+    {828234000 7200 1 CEST}
+    {846378000 3600 0 CET}
+    {859683600 7200 1 CEST}
+    {877827600 3600 0 CET}
+    {891133200 7200 1 CEST}
+    {909277200 3600 0 CET}
+    {922582800 7200 1 CEST}
+    {941331600 3600 0 CET}
+    {954032400 7200 1 CEST}
+    {972781200 3600 0 CET}
+    {985482000 7200 1 CEST}
+    {1004230800 3600 0 CET}
+    {1017536400 7200 1 CEST}
+    {1035680400 3600 0 CET}
+    {1048986000 7200 1 CEST}
+    {1067130000 3600 0 CET}
+    {1080435600 7200 1 CEST}
+    {1099184400 3600 0 CET}
+    {1111885200 7200 1 CEST}
+    {1130634000 3600 0 CET}
+    {1143334800 7200 1 CEST}
+    {1162083600 3600 0 CET}
+    {1174784400 7200 1 CEST}
+    {1193533200 3600 0 CET}
+    {1206838800 7200 1 CEST}
+    {1224982800 3600 0 CET}
+    {1238288400 7200 1 CEST}
+    {1256432400 3600 0 CET}
+    {1269738000 7200 1 CEST}
+    {1288486800 3600 0 CET}
+    {1301187600 7200 1 CEST}
+    {1319936400 3600 0 CET}
+    {1332637200 7200 1 CEST}
+    {1351386000 3600 0 CET}
+    {1364691600 7200 1 CEST}
+    {1382835600 3600 0 CET}
+    {1396141200 7200 1 CEST}
+    {1414285200 3600 0 CET}
+    {1427590800 7200 1 CEST}
+    {1445734800 3600 0 CET}
+    {1459040400 7200 1 CEST}
+    {1477789200 3600 0 CET}
+    {1490490000 7200 1 CEST}
+    {1509238800 3600 0 CET}
+    {1521939600 7200 1 CEST}
+    {1540688400 3600 0 CET}
+    {1553994000 7200 1 CEST}
+    {1572138000 3600 0 CET}
+    {1585443600 7200 1 CEST}
+    {1603587600 3600 0 CET}
+    {1616893200 7200 1 CEST}
+    {1635642000 3600 0 CET}
+    {1648342800 7200 1 CEST}
+    {1667091600 3600 0 CET}
+    {1679792400 7200 1 CEST}
+    {1698541200 3600 0 CET}
+    {1711846800 7200 1 CEST}
+    {1729990800 3600 0 CET}
+    {1743296400 7200 1 CEST}
+    {1761440400 3600 0 CET}
+    {1774746000 7200 1 CEST}
+    {1792890000 3600 0 CET}
+    {1806195600 7200 1 CEST}
+    {1824944400 3600 0 CET}
+    {1837645200 7200 1 CEST}
+    {1856394000 3600 0 CET}
+    {1869094800 7200 1 CEST}
+    {1887843600 3600 0 CET}
+    {1901149200 7200 1 CEST}
+    {1919293200 3600 0 CET}
+    {1932598800 7200 1 CEST}
+    {1950742800 3600 0 CET}
+    {1964048400 7200 1 CEST}
+    {1982797200 3600 0 CET}
+    {1995498000 7200 1 CEST}
+    {2014246800 3600 0 CET}
+    {2026947600 7200 1 CEST}
+    {2045696400 3600 0 CET}
+    {2058397200 7200 1 CEST}
+    {2077146000 3600 0 CET}
+    {2090451600 7200 1 CEST}
+    {2108595600 3600 0 CET}
+    {2121901200 7200 1 CEST}
+    {2140045200 3600 0 CET}
+    {2153350800 7200 1 CEST}
+    {2172099600 3600 0 CET}
+    {2184800400 7200 1 CEST}
+    {2203549200 3600 0 CET}
+    {2216250000 7200 1 CEST}
+    {2234998800 3600 0 CET}
+    {2248304400 7200 1 CEST}
+    {2266448400 3600 0 CET}
+    {2279754000 7200 1 CEST}
+    {2297898000 3600 0 CET}
+    {2311203600 7200 1 CEST}
+    {2329347600 3600 0 CET}
+    {2342653200 7200 1 CEST}
+    {2361402000 3600 0 CET}
+    {2374102800 7200 1 CEST}
+    {2392851600 3600 0 CET}
+    {2405552400 7200 1 CEST}
+    {2424301200 3600 0 CET}
+    {2437606800 7200 1 CEST}
+    {2455750800 3600 0 CET}
+    {2469056400 7200 1 CEST}
+    {2487200400 3600 0 CET}
+    {2500506000 7200 1 CEST}
+    {2519254800 3600 0 CET}
+    {2531955600 7200 1 CEST}
+    {2550704400 3600 0 CET}
+    {2563405200 7200 1 CEST}
+    {2582154000 3600 0 CET}
+    {2595459600 7200 1 CEST}
+    {2613603600 3600 0 CET}
+    {2626909200 7200 1 CEST}
+    {2645053200 3600 0 CET}
+    {2658358800 7200 1 CEST}
+    {2676502800 3600 0 CET}
+    {2689808400 7200 1 CEST}
+    {2708557200 3600 0 CET}
+    {2721258000 7200 1 CEST}
+    {2740006800 3600 0 CET}
+    {2752707600 7200 1 CEST}
+    {2771456400 3600 0 CET}
+    {2784762000 7200 1 CEST}
+    {2802906000 3600 0 CET}
+    {2816211600 7200 1 CEST}
+    {2834355600 3600 0 CET}
+    {2847661200 7200 1 CEST}
+    {2866410000 3600 0 CET}
+    {2879110800 7200 1 CEST}
+    {2897859600 3600 0 CET}
+    {2910560400 7200 1 CEST}
+    {2929309200 3600 0 CET}
+    {2942010000 7200 1 CEST}
+    {2960758800 3600 0 CET}
+    {2974064400 7200 1 CEST}
+    {2992208400 3600 0 CET}
+    {3005514000 7200 1 CEST}
+    {3023658000 3600 0 CET}
+    {3036963600 7200 1 CEST}
+    {3055712400 3600 0 CET}
+    {3068413200 7200 1 CEST}
+    {3087162000 3600 0 CET}
+    {3099862800 7200 1 CEST}
+    {3118611600 3600 0 CET}
+    {3131917200 7200 1 CEST}
+    {3150061200 3600 0 CET}
+    {3163366800 7200 1 CEST}
+    {3181510800 3600 0 CET}
+    {3194816400 7200 1 CEST}
+    {3212960400 3600 0 CET}
+    {3226266000 7200 1 CEST}
+    {3245014800 3600 0 CET}
+    {3257715600 7200 1 CEST}
+    {3276464400 3600 0 CET}
+    {3289165200 7200 1 CEST}
+    {3307914000 3600 0 CET}
+    {3321219600 7200 1 CEST}
+    {3339363600 3600 0 CET}
+    {3352669200 7200 1 CEST}
+    {3370813200 3600 0 CET}
+    {3384118800 7200 1 CEST}
+    {3402867600 3600 0 CET}
+    {3415568400 7200 1 CEST}
+    {3434317200 3600 0 CET}
+    {3447018000 7200 1 CEST}
+    {3465766800 3600 0 CET}
+    {3479072400 7200 1 CEST}
+    {3497216400 3600 0 CET}
+    {3510522000 7200 1 CEST}
+    {3528666000 3600 0 CET}
+    {3541971600 7200 1 CEST}
+    {3560115600 3600 0 CET}
+    {3573421200 7200 1 CEST}
+    {3592170000 3600 0 CET}
+    {3604870800 7200 1 CEST}
+    {3623619600 3600 0 CET}
+    {3636320400 7200 1 CEST}
+    {3655069200 3600 0 CET}
+    {3668374800 7200 1 CEST}
+    {3686518800 3600 0 CET}
+    {3699824400 7200 1 CEST}
+    {3717968400 3600 0 CET}
+    {3731274000 7200 1 CEST}
+    {3750022800 3600 0 CET}
+    {3762723600 7200 1 CEST}
+    {3781472400 3600 0 CET}
+    {3794173200 7200 1 CEST}
+    {3812922000 3600 0 CET}
+    {3825622800 7200 1 CEST}
+    {3844371600 3600 0 CET}
+    {3857677200 7200 1 CEST}
+    {3875821200 3600 0 CET}
+    {3889126800 7200 1 CEST}
+    {3907270800 3600 0 CET}
+    {3920576400 7200 1 CEST}
+    {3939325200 3600 0 CET}
+    {3952026000 7200 1 CEST}
+    {3970774800 3600 0 CET}
+    {3983475600 7200 1 CEST}
+    {4002224400 3600 0 CET}
+    {4015530000 7200 1 CEST}
+    {4033674000 3600 0 CET}
+    {4046979600 7200 1 CEST}
+    {4065123600 3600 0 CET}
+    {4078429200 7200 1 CEST}
+    {4096573200 3600 0 CET}
+}
diff --git a/library/tzdata/Europe/Moscow b/library/tzdata/Europe/Moscow
new file mode 100644
index 0000000..1e2f45b
--- /dev/null
+++ b/library/tzdata/Europe/Moscow
@@ -0,0 +1,83 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Europe/Moscow) {
+    {-9223372036854775808 9017 0 LMT}
+    {-2840149817 9017 0 MMT}
+    {-1688265017 9079 0 MMT}
+    {-1656819079 12679 1 MST}
+    {-1641353479 9079 0 MMT}
+    {-1627965079 16279 1 MDST}
+    {-1618716679 12679 1 MST}
+    {-1596429079 16279 1 MDST}
+    {-1593822679 14400 0 MSD}
+    {-1589860800 10800 0 MSK}
+    {-1542427200 14400 1 MSD}
+    {-1539493200 18000 1 MSM}
+    {-1525323600 14400 1 MSD}
+    {-1491188400 7200 0 EET}
+    {-1247536800 10800 0 MSD}
+    {354920400 14400 1 MSD}
+    {370728000 10800 0 MSK}
+    {386456400 14400 1 MSD}
+    {402264000 10800 0 MSK}
+    {417992400 14400 1 MSD}
+    {433800000 10800 0 MSK}
+    {449614800 14400 1 MSD}
+    {465346800 10800 0 MSK}
+    {481071600 14400 1 MSD}
+    {496796400 10800 0 MSK}
+    {512521200 14400 1 MSD}
+    {528246000 10800 0 MSK}
+    {543970800 14400 1 MSD}
+    {559695600 10800 0 MSK}
+    {575420400 14400 1 MSD}
+    {591145200 10800 0 MSK}
+    {606870000 14400 1 MSD}
+    {622594800 10800 0 MSK}
+    {638319600 14400 1 MSD}
+    {654649200 10800 0 MSK}
+    {670374000 7200 0 EEMMTT}
+    {670377600 10800 1 EEST}
+    {686102400 7200 0 EET}
+    {695779200 10800 0 MSD}
+    {701823600 14400 1 MSD}
+    {717548400 10800 0 MSK}
+    {733273200 14400 1 MSD}
+    {748998000 10800 0 MSK}
+    {764722800 14400 1 MSD}
+    {780447600 10800 0 MSK}
+    {796172400 14400 1 MSD}
+    {811897200 10800 0 MSK}
+    {828226800 14400 1 MSD}
+    {846370800 10800 0 MSK}
+    {859676400 14400 1 MSD}
+    {877820400 10800 0 MSK}
+    {891126000 14400 1 MSD}
+    {909270000 10800 0 MSK}
+    {922575600 14400 1 MSD}
+    {941324400 10800 0 MSK}
+    {954025200 14400 1 MSD}
+    {972774000 10800 0 MSK}
+    {985474800 14400 1 MSD}
+    {1004223600 10800 0 MSK}
+    {1017529200 14400 1 MSD}
+    {1035673200 10800 0 MSK}
+    {1048978800 14400 1 MSD}
+    {1067122800 10800 0 MSK}
+    {1080428400 14400 1 MSD}
+    {1099177200 10800 0 MSK}
+    {1111878000 14400 1 MSD}
+    {1130626800 10800 0 MSK}
+    {1143327600 14400 1 MSD}
+    {1162076400 10800 0 MSK}
+    {1174777200 14400 1 MSD}
+    {1193526000 10800 0 MSK}
+    {1206831600 14400 1 MSD}
+    {1224975600 10800 0 MSK}
+    {1238281200 14400 1 MSD}
+    {1256425200 10800 0 MSK}
+    {1269730800 14400 1 MSD}
+    {1288479600 10800 0 MSK}
+    {1301180400 14400 0 MSK}
+    {1414274400 10800 0 MSK}
+}
diff --git a/library/tzdata/Europe/Nicosia b/library/tzdata/Europe/Nicosia
new file mode 100644
index 0000000..2d58355
--- /dev/null
+++ b/library/tzdata/Europe/Nicosia
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Asia/Nicosia)]} {
+    LoadTimeZoneFile Asia/Nicosia
+}
+set TZData(:Europe/Nicosia) $TZData(:Asia/Nicosia)
diff --git a/library/tzdata/Europe/Oslo b/library/tzdata/Europe/Oslo
new file mode 100644
index 0000000..6787c1e
--- /dev/null
+++ b/library/tzdata/Europe/Oslo
@@ -0,0 +1,271 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Europe/Oslo) {
+    {-9223372036854775808 2580 0 LMT}
+    {-2366757780 3600 0 CET}
+    {-1691884800 7200 1 CEST}
+    {-1680573600 3600 0 CET}
+    {-927511200 7200 0 CEST}
+    {-857257200 3600 0 CET}
+    {-844556400 7200 1 CEST}
+    {-828226800 3600 0 CET}
+    {-812502000 7200 1 CEST}
+    {-796777200 3600 0 CET}
+    {-781052400 7200 0 CEST}
+    {-765327600 3600 0 CET}
+    {-340844400 7200 1 CEST}
+    {-324514800 3600 0 CET}
+    {-308790000 7200 1 CEST}
+    {-293065200 3600 0 CET}
+    {-277340400 7200 1 CEST}
+    {-261615600 3600 0 CET}
+    {-245890800 7200 1 CEST}
+    {-230166000 3600 0 CET}
+    {-214441200 7200 1 CEST}
+    {-198716400 3600 0 CET}
+    {-182991600 7200 1 CEST}
+    {-166662000 3600 0 CET}
+    {-147913200 7200 1 CEST}
+    {-135212400 3600 0 CET}
+    {315529200 3600 0 CET}
+    {323830800 7200 1 CEST}
+    {338950800 3600 0 CET}
+    {354675600 7200 1 CEST}
+    {370400400 3600 0 CET}
+    {386125200 7200 1 CEST}
+    {401850000 3600 0 CET}
+    {417574800 7200 1 CEST}
+    {433299600 3600 0 CET}
+    {449024400 7200 1 CEST}
+    {465354000 3600 0 CET}
+    {481078800 7200 1 CEST}
+    {496803600 3600 0 CET}
+    {512528400 7200 1 CEST}
+    {528253200 3600 0 CET}
+    {543978000 7200 1 CEST}
+    {559702800 3600 0 CET}
+    {575427600 7200 1 CEST}
+    {591152400 3600 0 CET}
+    {606877200 7200 1 CEST}
+    {622602000 3600 0 CET}
+    {638326800 7200 1 CEST}
+    {654656400 3600 0 CET}
+    {670381200 7200 1 CEST}
+    {686106000 3600 0 CET}
+    {701830800 7200 1 CEST}
+    {717555600 3600 0 CET}
+    {733280400 7200 1 CEST}
+    {749005200 3600 0 CET}
+    {764730000 7200 1 CEST}
+    {780454800 3600 0 CET}
+    {796179600 7200 1 CEST}
+    {811904400 3600 0 CET}
+    {828234000 7200 1 CEST}
+    {846378000 3600 0 CET}
+    {859683600 7200 1 CEST}
+    {877827600 3600 0 CET}
+    {891133200 7200 1 CEST}
+    {909277200 3600 0 CET}
+    {922582800 7200 1 CEST}
+    {941331600 3600 0 CET}
+    {954032400 7200 1 CEST}
+    {972781200 3600 0 CET}
+    {985482000 7200 1 CEST}
+    {1004230800 3600 0 CET}
+    {1017536400 7200 1 CEST}
+    {1035680400 3600 0 CET}
+    {1048986000 7200 1 CEST}
+    {1067130000 3600 0 CET}
+    {1080435600 7200 1 CEST}
+    {1099184400 3600 0 CET}
+    {1111885200 7200 1 CEST}
+    {1130634000 3600 0 CET}
+    {1143334800 7200 1 CEST}
+    {1162083600 3600 0 CET}
+    {1174784400 7200 1 CEST}
+    {1193533200 3600 0 CET}
+    {1206838800 7200 1 CEST}
+    {1224982800 3600 0 CET}
+    {1238288400 7200 1 CEST}
+    {1256432400 3600 0 CET}
+    {1269738000 7200 1 CEST}
+    {1288486800 3600 0 CET}
+    {1301187600 7200 1 CEST}
+    {1319936400 3600 0 CET}
+    {1332637200 7200 1 CEST}
+    {1351386000 3600 0 CET}
+    {1364691600 7200 1 CEST}
+    {1382835600 3600 0 CET}
+    {1396141200 7200 1 CEST}
+    {1414285200 3600 0 CET}
+    {1427590800 7200 1 CEST}
+    {1445734800 3600 0 CET}
+    {1459040400 7200 1 CEST}
+    {1477789200 3600 0 CET}
+    {1490490000 7200 1 CEST}
+    {1509238800 3600 0 CET}
+    {1521939600 7200 1 CEST}
+    {1540688400 3600 0 CET}
+    {1553994000 7200 1 CEST}
+    {1572138000 3600 0 CET}
+    {1585443600 7200 1 CEST}
+    {1603587600 3600 0 CET}
+    {1616893200 7200 1 CEST}
+    {1635642000 3600 0 CET}
+    {1648342800 7200 1 CEST}
+    {1667091600 3600 0 CET}
+    {1679792400 7200 1 CEST}
+    {1698541200 3600 0 CET}
+    {1711846800 7200 1 CEST}
+    {1729990800 3600 0 CET}
+    {1743296400 7200 1 CEST}
+    {1761440400 3600 0 CET}
+    {1774746000 7200 1 CEST}
+    {1792890000 3600 0 CET}
+    {1806195600 7200 1 CEST}
+    {1824944400 3600 0 CET}
+    {1837645200 7200 1 CEST}
+    {1856394000 3600 0 CET}
+    {1869094800 7200 1 CEST}
+    {1887843600 3600 0 CET}
+    {1901149200 7200 1 CEST}
+    {1919293200 3600 0 CET}
+    {1932598800 7200 1 CEST}
+    {1950742800 3600 0 CET}
+    {1964048400 7200 1 CEST}
+    {1982797200 3600 0 CET}
+    {1995498000 7200 1 CEST}
+    {2014246800 3600 0 CET}
+    {2026947600 7200 1 CEST}
+    {2045696400 3600 0 CET}
+    {2058397200 7200 1 CEST}
+    {2077146000 3600 0 CET}
+    {2090451600 7200 1 CEST}
+    {2108595600 3600 0 CET}
+    {2121901200 7200 1 CEST}
+    {2140045200 3600 0 CET}
+    {2153350800 7200 1 CEST}
+    {2172099600 3600 0 CET}
+    {2184800400 7200 1 CEST}
+    {2203549200 3600 0 CET}
+    {2216250000 7200 1 CEST}
+    {2234998800 3600 0 CET}
+    {2248304400 7200 1 CEST}
+    {2266448400 3600 0 CET}
+    {2279754000 7200 1 CEST}
+    {2297898000 3600 0 CET}
+    {2311203600 7200 1 CEST}
+    {2329347600 3600 0 CET}
+    {2342653200 7200 1 CEST}
+    {2361402000 3600 0 CET}
+    {2374102800 7200 1 CEST}
+    {2392851600 3600 0 CET}
+    {2405552400 7200 1 CEST}
+    {2424301200 3600 0 CET}
+    {2437606800 7200 1 CEST}
+    {2455750800 3600 0 CET}
+    {2469056400 7200 1 CEST}
+    {2487200400 3600 0 CET}
+    {2500506000 7200 1 CEST}
+    {2519254800 3600 0 CET}
+    {2531955600 7200 1 CEST}
+    {2550704400 3600 0 CET}
+    {2563405200 7200 1 CEST}
+    {2582154000 3600 0 CET}
+    {2595459600 7200 1 CEST}
+    {2613603600 3600 0 CET}
+    {2626909200 7200 1 CEST}
+    {2645053200 3600 0 CET}
+    {2658358800 7200 1 CEST}
+    {2676502800 3600 0 CET}
+    {2689808400 7200 1 CEST}
+    {2708557200 3600 0 CET}
+    {2721258000 7200 1 CEST}
+    {2740006800 3600 0 CET}
+    {2752707600 7200 1 CEST}
+    {2771456400 3600 0 CET}
+    {2784762000 7200 1 CEST}
+    {2802906000 3600 0 CET}
+    {2816211600 7200 1 CEST}
+    {2834355600 3600 0 CET}
+    {2847661200 7200 1 CEST}
+    {2866410000 3600 0 CET}
+    {2879110800 7200 1 CEST}
+    {2897859600 3600 0 CET}
+    {2910560400 7200 1 CEST}
+    {2929309200 3600 0 CET}
+    {2942010000 7200 1 CEST}
+    {2960758800 3600 0 CET}
+    {2974064400 7200 1 CEST}
+    {2992208400 3600 0 CET}
+    {3005514000 7200 1 CEST}
+    {3023658000 3600 0 CET}
+    {3036963600 7200 1 CEST}
+    {3055712400 3600 0 CET}
+    {3068413200 7200 1 CEST}
+    {3087162000 3600 0 CET}
+    {3099862800 7200 1 CEST}
+    {3118611600 3600 0 CET}
+    {3131917200 7200 1 CEST}
+    {3150061200 3600 0 CET}
+    {3163366800 7200 1 CEST}
+    {3181510800 3600 0 CET}
+    {3194816400 7200 1 CEST}
+    {3212960400 3600 0 CET}
+    {3226266000 7200 1 CEST}
+    {3245014800 3600 0 CET}
+    {3257715600 7200 1 CEST}
+    {3276464400 3600 0 CET}
+    {3289165200 7200 1 CEST}
+    {3307914000 3600 0 CET}
+    {3321219600 7200 1 CEST}
+    {3339363600 3600 0 CET}
+    {3352669200 7200 1 CEST}
+    {3370813200 3600 0 CET}
+    {3384118800 7200 1 CEST}
+    {3402867600 3600 0 CET}
+    {3415568400 7200 1 CEST}
+    {3434317200 3600 0 CET}
+    {3447018000 7200 1 CEST}
+    {3465766800 3600 0 CET}
+    {3479072400 7200 1 CEST}
+    {3497216400 3600 0 CET}
+    {3510522000 7200 1 CEST}
+    {3528666000 3600 0 CET}
+    {3541971600 7200 1 CEST}
+    {3560115600 3600 0 CET}
+    {3573421200 7200 1 CEST}
+    {3592170000 3600 0 CET}
+    {3604870800 7200 1 CEST}
+    {3623619600 3600 0 CET}
+    {3636320400 7200 1 CEST}
+    {3655069200 3600 0 CET}
+    {3668374800 7200 1 CEST}
+    {3686518800 3600 0 CET}
+    {3699824400 7200 1 CEST}
+    {3717968400 3600 0 CET}
+    {3731274000 7200 1 CEST}
+    {3750022800 3600 0 CET}
+    {3762723600 7200 1 CEST}
+    {3781472400 3600 0 CET}
+    {3794173200 7200 1 CEST}
+    {3812922000 3600 0 CET}
+    {3825622800 7200 1 CEST}
+    {3844371600 3600 0 CET}
+    {3857677200 7200 1 CEST}
+    {3875821200 3600 0 CET}
+    {3889126800 7200 1 CEST}
+    {3907270800 3600 0 CET}
+    {3920576400 7200 1 CEST}
+    {3939325200 3600 0 CET}
+    {3952026000 7200 1 CEST}
+    {3970774800 3600 0 CET}
+    {3983475600 7200 1 CEST}
+    {4002224400 3600 0 CET}
+    {4015530000 7200 1 CEST}
+    {4033674000 3600 0 CET}
+    {4046979600 7200 1 CEST}
+    {4065123600 3600 0 CET}
+    {4078429200 7200 1 CEST}
+    {4096573200 3600 0 CET}
+}
diff --git a/library/tzdata/Europe/Paris b/library/tzdata/Europe/Paris
new file mode 100644
index 0000000..4b22a09
--- /dev/null
+++ b/library/tzdata/Europe/Paris
@@ -0,0 +1,314 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Europe/Paris) {
+    {-9223372036854775808 561 0 LMT}
+    {-2486678901 561 0 PMT}
+    {-1855958901 0 0 WET}
+    {-1689814800 3600 1 WEST}
+    {-1680397200 0 0 WET}
+    {-1665363600 3600 1 WEST}
+    {-1648342800 0 0 WET}
+    {-1635123600 3600 1 WEST}
+    {-1616893200 0 0 WET}
+    {-1604278800 3600 1 WEST}
+    {-1585443600 0 0 WET}
+    {-1574038800 3600 1 WEST}
+    {-1552266000 0 0 WET}
+    {-1539997200 3600 1 WEST}
+    {-1520557200 0 0 WET}
+    {-1507510800 3600 1 WEST}
+    {-1490576400 0 0 WET}
+    {-1470618000 3600 1 WEST}
+    {-1459126800 0 0 WET}
+    {-1444006800 3600 1 WEST}
+    {-1427677200 0 0 WET}
+    {-1411952400 3600 1 WEST}
+    {-1396227600 0 0 WET}
+    {-1379293200 3600 1 WEST}
+    {-1364778000 0 0 WET}
+    {-1348448400 3600 1 WEST}
+    {-1333328400 0 0 WET}
+    {-1316394000 3600 1 WEST}
+    {-1301274000 0 0 WET}
+    {-1284339600 3600 1 WEST}
+    {-1269824400 0 0 WET}
+    {-1253494800 3600 1 WEST}
+    {-1238374800 0 0 WET}
+    {-1221440400 3600 1 WEST}
+    {-1206925200 0 0 WET}
+    {-1191200400 3600 1 WEST}
+    {-1175475600 0 0 WET}
+    {-1160355600 3600 1 WEST}
+    {-1143421200 0 0 WET}
+    {-1127696400 3600 1 WEST}
+    {-1111971600 0 0 WET}
+    {-1096851600 3600 1 WEST}
+    {-1080522000 0 0 WET}
+    {-1063587600 3600 1 WEST}
+    {-1049072400 0 0 WET}
+    {-1033347600 3600 1 WEST}
+    {-1017622800 0 0 WET}
+    {-1002502800 3600 1 WEST}
+    {-986173200 0 0 WET}
+    {-969238800 3600 1 WEST}
+    {-950490000 0 0 WET}
+    {-942012000 3600 1 WEST}
+    {-932436000 7200 0 CEST}
+    {-857257200 3600 0 CET}
+    {-844556400 7200 1 CEST}
+    {-828226800 3600 0 CET}
+    {-812502000 7200 1 CEST}
+    {-800067600 7200 0 WEMT}
+    {-796266000 3600 1 WEST}
+    {-781052400 7200 1 WEMT}
+    {-766616400 3600 0 CET}
+    {196819200 7200 1 CEST}
+    {212540400 3600 0 CET}
+    {220921200 3600 0 CET}
+    {228877200 7200 1 CEST}
+    {243997200 3600 0 CET}
+    {260326800 7200 1 CEST}
+    {276051600 3600 0 CET}
+    {291776400 7200 1 CEST}
+    {307501200 3600 0 CET}
+    {323830800 7200 1 CEST}
+    {338950800 3600 0 CET}
+    {354675600 7200 1 CEST}
+    {370400400 3600 0 CET}
+    {386125200 7200 1 CEST}
+    {401850000 3600 0 CET}
+    {417574800 7200 1 CEST}
+    {433299600 3600 0 CET}
+    {449024400 7200 1 CEST}
+    {465354000 3600 0 CET}
+    {481078800 7200 1 CEST}
+    {496803600 3600 0 CET}
+    {512528400 7200 1 CEST}
+    {528253200 3600 0 CET}
+    {543978000 7200 1 CEST}
+    {559702800 3600 0 CET}
+    {575427600 7200 1 CEST}
+    {591152400 3600 0 CET}
+    {606877200 7200 1 CEST}
+    {622602000 3600 0 CET}
+    {638326800 7200 1 CEST}
+    {654656400 3600 0 CET}
+    {670381200 7200 1 CEST}
+    {686106000 3600 0 CET}
+    {701830800 7200 1 CEST}
+    {717555600 3600 0 CET}
+    {733280400 7200 1 CEST}
+    {749005200 3600 0 CET}
+    {764730000 7200 1 CEST}
+    {780454800 3600 0 CET}
+    {796179600 7200 1 CEST}
+    {811904400 3600 0 CET}
+    {828234000 7200 1 CEST}
+    {846378000 3600 0 CET}
+    {859683600 7200 1 CEST}
+    {877827600 3600 0 CET}
+    {891133200 7200 1 CEST}
+    {909277200 3600 0 CET}
+    {922582800 7200 1 CEST}
+    {941331600 3600 0 CET}
+    {954032400 7200 1 CEST}
+    {972781200 3600 0 CET}
+    {985482000 7200 1 CEST}
+    {1004230800 3600 0 CET}
+    {1017536400 7200 1 CEST}
+    {1035680400 3600 0 CET}
+    {1048986000 7200 1 CEST}
+    {1067130000 3600 0 CET}
+    {1080435600 7200 1 CEST}
+    {1099184400 3600 0 CET}
+    {1111885200 7200 1 CEST}
+    {1130634000 3600 0 CET}
+    {1143334800 7200 1 CEST}
+    {1162083600 3600 0 CET}
+    {1174784400 7200 1 CEST}
+    {1193533200 3600 0 CET}
+    {1206838800 7200 1 CEST}
+    {1224982800 3600 0 CET}
+    {1238288400 7200 1 CEST}
+    {1256432400 3600 0 CET}
+    {1269738000 7200 1 CEST}
+    {1288486800 3600 0 CET}
+    {1301187600 7200 1 CEST}
+    {1319936400 3600 0 CET}
+    {1332637200 7200 1 CEST}
+    {1351386000 3600 0 CET}
+    {1364691600 7200 1 CEST}
+    {1382835600 3600 0 CET}
+    {1396141200 7200 1 CEST}
+    {1414285200 3600 0 CET}
+    {1427590800 7200 1 CEST}
+    {1445734800 3600 0 CET}
+    {1459040400 7200 1 CEST}
+    {1477789200 3600 0 CET}
+    {1490490000 7200 1 CEST}
+    {1509238800 3600 0 CET}
+    {1521939600 7200 1 CEST}
+    {1540688400 3600 0 CET}
+    {1553994000 7200 1 CEST}
+    {1572138000 3600 0 CET}
+    {1585443600 7200 1 CEST}
+    {1603587600 3600 0 CET}
+    {1616893200 7200 1 CEST}
+    {1635642000 3600 0 CET}
+    {1648342800 7200 1 CEST}
+    {1667091600 3600 0 CET}
+    {1679792400 7200 1 CEST}
+    {1698541200 3600 0 CET}
+    {1711846800 7200 1 CEST}
+    {1729990800 3600 0 CET}
+    {1743296400 7200 1 CEST}
+    {1761440400 3600 0 CET}
+    {1774746000 7200 1 CEST}
+    {1792890000 3600 0 CET}
+    {1806195600 7200 1 CEST}
+    {1824944400 3600 0 CET}
+    {1837645200 7200 1 CEST}
+    {1856394000 3600 0 CET}
+    {1869094800 7200 1 CEST}
+    {1887843600 3600 0 CET}
+    {1901149200 7200 1 CEST}
+    {1919293200 3600 0 CET}
+    {1932598800 7200 1 CEST}
+    {1950742800 3600 0 CET}
+    {1964048400 7200 1 CEST}
+    {1982797200 3600 0 CET}
+    {1995498000 7200 1 CEST}
+    {2014246800 3600 0 CET}
+    {2026947600 7200 1 CEST}
+    {2045696400 3600 0 CET}
+    {2058397200 7200 1 CEST}
+    {2077146000 3600 0 CET}
+    {2090451600 7200 1 CEST}
+    {2108595600 3600 0 CET}
+    {2121901200 7200 1 CEST}
+    {2140045200 3600 0 CET}
+    {2153350800 7200 1 CEST}
+    {2172099600 3600 0 CET}
+    {2184800400 7200 1 CEST}
+    {2203549200 3600 0 CET}
+    {2216250000 7200 1 CEST}
+    {2234998800 3600 0 CET}
+    {2248304400 7200 1 CEST}
+    {2266448400 3600 0 CET}
+    {2279754000 7200 1 CEST}
+    {2297898000 3600 0 CET}
+    {2311203600 7200 1 CEST}
+    {2329347600 3600 0 CET}
+    {2342653200 7200 1 CEST}
+    {2361402000 3600 0 CET}
+    {2374102800 7200 1 CEST}
+    {2392851600 3600 0 CET}
+    {2405552400 7200 1 CEST}
+    {2424301200 3600 0 CET}
+    {2437606800 7200 1 CEST}
+    {2455750800 3600 0 CET}
+    {2469056400 7200 1 CEST}
+    {2487200400 3600 0 CET}
+    {2500506000 7200 1 CEST}
+    {2519254800 3600 0 CET}
+    {2531955600 7200 1 CEST}
+    {2550704400 3600 0 CET}
+    {2563405200 7200 1 CEST}
+    {2582154000 3600 0 CET}
+    {2595459600 7200 1 CEST}
+    {2613603600 3600 0 CET}
+    {2626909200 7200 1 CEST}
+    {2645053200 3600 0 CET}
+    {2658358800 7200 1 CEST}
+    {2676502800 3600 0 CET}
+    {2689808400 7200 1 CEST}
+    {2708557200 3600 0 CET}
+    {2721258000 7200 1 CEST}
+    {2740006800 3600 0 CET}
+    {2752707600 7200 1 CEST}
+    {2771456400 3600 0 CET}
+    {2784762000 7200 1 CEST}
+    {2802906000 3600 0 CET}
+    {2816211600 7200 1 CEST}
+    {2834355600 3600 0 CET}
+    {2847661200 7200 1 CEST}
+    {2866410000 3600 0 CET}
+    {2879110800 7200 1 CEST}
+    {2897859600 3600 0 CET}
+    {2910560400 7200 1 CEST}
+    {2929309200 3600 0 CET}
+    {2942010000 7200 1 CEST}
+    {2960758800 3600 0 CET}
+    {2974064400 7200 1 CEST}
+    {2992208400 3600 0 CET}
+    {3005514000 7200 1 CEST}
+    {3023658000 3600 0 CET}
+    {3036963600 7200 1 CEST}
+    {3055712400 3600 0 CET}
+    {3068413200 7200 1 CEST}
+    {3087162000 3600 0 CET}
+    {3099862800 7200 1 CEST}
+    {3118611600 3600 0 CET}
+    {3131917200 7200 1 CEST}
+    {3150061200 3600 0 CET}
+    {3163366800 7200 1 CEST}
+    {3181510800 3600 0 CET}
+    {3194816400 7200 1 CEST}
+    {3212960400 3600 0 CET}
+    {3226266000 7200 1 CEST}
+    {3245014800 3600 0 CET}
+    {3257715600 7200 1 CEST}
+    {3276464400 3600 0 CET}
+    {3289165200 7200 1 CEST}
+    {3307914000 3600 0 CET}
+    {3321219600 7200 1 CEST}
+    {3339363600 3600 0 CET}
+    {3352669200 7200 1 CEST}
+    {3370813200 3600 0 CET}
+    {3384118800 7200 1 CEST}
+    {3402867600 3600 0 CET}
+    {3415568400 7200 1 CEST}
+    {3434317200 3600 0 CET}
+    {3447018000 7200 1 CEST}
+    {3465766800 3600 0 CET}
+    {3479072400 7200 1 CEST}
+    {3497216400 3600 0 CET}
+    {3510522000 7200 1 CEST}
+    {3528666000 3600 0 CET}
+    {3541971600 7200 1 CEST}
+    {3560115600 3600 0 CET}
+    {3573421200 7200 1 CEST}
+    {3592170000 3600 0 CET}
+    {3604870800 7200 1 CEST}
+    {3623619600 3600 0 CET}
+    {3636320400 7200 1 CEST}
+    {3655069200 3600 0 CET}
+    {3668374800 7200 1 CEST}
+    {3686518800 3600 0 CET}
+    {3699824400 7200 1 CEST}
+    {3717968400 3600 0 CET}
+    {3731274000 7200 1 CEST}
+    {3750022800 3600 0 CET}
+    {3762723600 7200 1 CEST}
+    {3781472400 3600 0 CET}
+    {3794173200 7200 1 CEST}
+    {3812922000 3600 0 CET}
+    {3825622800 7200 1 CEST}
+    {3844371600 3600 0 CET}
+    {3857677200 7200 1 CEST}
+    {3875821200 3600 0 CET}
+    {3889126800 7200 1 CEST}
+    {3907270800 3600 0 CET}
+    {3920576400 7200 1 CEST}
+    {3939325200 3600 0 CET}
+    {3952026000 7200 1 CEST}
+    {3970774800 3600 0 CET}
+    {3983475600 7200 1 CEST}
+    {4002224400 3600 0 CET}
+    {4015530000 7200 1 CEST}
+    {4033674000 3600 0 CET}
+    {4046979600 7200 1 CEST}
+    {4065123600 3600 0 CET}
+    {4078429200 7200 1 CEST}
+    {4096573200 3600 0 CET}
+}
diff --git a/library/tzdata/Europe/Podgorica b/library/tzdata/Europe/Podgorica
new file mode 100644
index 0000000..f4f9066
--- /dev/null
+++ b/library/tzdata/Europe/Podgorica
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Europe/Belgrade)]} {
+    LoadTimeZoneFile Europe/Belgrade
+}
+set TZData(:Europe/Podgorica) $TZData(:Europe/Belgrade)
diff --git a/library/tzdata/Europe/Prague b/library/tzdata/Europe/Prague
new file mode 100644
index 0000000..222b1ae
--- /dev/null
+++ b/library/tzdata/Europe/Prague
@@ -0,0 +1,272 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Europe/Prague) {
+    {-9223372036854775808 3464 0 LMT}
+    {-3786829064 3464 0 PMT}
+    {-2469401864 3600 0 CET}
+    {-1693706400 7200 1 CEST}
+    {-1680483600 3600 0 CET}
+    {-1663455600 7200 1 CEST}
+    {-1650150000 3600 0 CET}
+    {-1632006000 7200 1 CEST}
+    {-1618700400 3600 0 CET}
+    {-938905200 7200 1 CEST}
+    {-857257200 3600 0 CET}
+    {-844556400 7200 1 CEST}
+    {-828226800 3600 0 CET}
+    {-812502000 7200 1 CEST}
+    {-798073200 3600 0 CET}
+    {-780534000 7200 1 CEST}
+    {-761180400 3600 0 CET}
+    {-746578800 7200 1 CEST}
+    {-733359600 3600 0 CET}
+    {-716425200 7200 1 CEST}
+    {-701910000 3600 0 CET}
+    {-684975600 7200 1 CEST}
+    {-670460400 3600 0 CET}
+    {-654217200 7200 1 CEST}
+    {-639010800 3600 0 CET}
+    {283993200 3600 0 CET}
+    {291776400 7200 1 CEST}
+    {307501200 3600 0 CET}
+    {323830800 7200 1 CEST}
+    {338950800 3600 0 CET}
+    {354675600 7200 1 CEST}
+    {370400400 3600 0 CET}
+    {386125200 7200 1 CEST}
+    {401850000 3600 0 CET}
+    {417574800 7200 1 CEST}
+    {433299600 3600 0 CET}
+    {449024400 7200 1 CEST}
+    {465354000 3600 0 CET}
+    {481078800 7200 1 CEST}
+    {496803600 3600 0 CET}
+    {512528400 7200 1 CEST}
+    {528253200 3600 0 CET}
+    {543978000 7200 1 CEST}
+    {559702800 3600 0 CET}
+    {575427600 7200 1 CEST}
+    {591152400 3600 0 CET}
+    {606877200 7200 1 CEST}
+    {622602000 3600 0 CET}
+    {638326800 7200 1 CEST}
+    {654656400 3600 0 CET}
+    {670381200 7200 1 CEST}
+    {686106000 3600 0 CET}
+    {701830800 7200 1 CEST}
+    {717555600 3600 0 CET}
+    {733280400 7200 1 CEST}
+    {749005200 3600 0 CET}
+    {764730000 7200 1 CEST}
+    {780454800 3600 0 CET}
+    {796179600 7200 1 CEST}
+    {811904400 3600 0 CET}
+    {828234000 7200 1 CEST}
+    {846378000 3600 0 CET}
+    {859683600 7200 1 CEST}
+    {877827600 3600 0 CET}
+    {891133200 7200 1 CEST}
+    {909277200 3600 0 CET}
+    {922582800 7200 1 CEST}
+    {941331600 3600 0 CET}
+    {954032400 7200 1 CEST}
+    {972781200 3600 0 CET}
+    {985482000 7200 1 CEST}
+    {1004230800 3600 0 CET}
+    {1017536400 7200 1 CEST}
+    {1035680400 3600 0 CET}
+    {1048986000 7200 1 CEST}
+    {1067130000 3600 0 CET}
+    {1080435600 7200 1 CEST}
+    {1099184400 3600 0 CET}
+    {1111885200 7200 1 CEST}
+    {1130634000 3600 0 CET}
+    {1143334800 7200 1 CEST}
+    {1162083600 3600 0 CET}
+    {1174784400 7200 1 CEST}
+    {1193533200 3600 0 CET}
+    {1206838800 7200 1 CEST}
+    {1224982800 3600 0 CET}
+    {1238288400 7200 1 CEST}
+    {1256432400 3600 0 CET}
+    {1269738000 7200 1 CEST}
+    {1288486800 3600 0 CET}
+    {1301187600 7200 1 CEST}
+    {1319936400 3600 0 CET}
+    {1332637200 7200 1 CEST}
+    {1351386000 3600 0 CET}
+    {1364691600 7200 1 CEST}
+    {1382835600 3600 0 CET}
+    {1396141200 7200 1 CEST}
+    {1414285200 3600 0 CET}
+    {1427590800 7200 1 CEST}
+    {1445734800 3600 0 CET}
+    {1459040400 7200 1 CEST}
+    {1477789200 3600 0 CET}
+    {1490490000 7200 1 CEST}
+    {1509238800 3600 0 CET}
+    {1521939600 7200 1 CEST}
+    {1540688400 3600 0 CET}
+    {1553994000 7200 1 CEST}
+    {1572138000 3600 0 CET}
+    {1585443600 7200 1 CEST}
+    {1603587600 3600 0 CET}
+    {1616893200 7200 1 CEST}
+    {1635642000 3600 0 CET}
+    {1648342800 7200 1 CEST}
+    {1667091600 3600 0 CET}
+    {1679792400 7200 1 CEST}
+    {1698541200 3600 0 CET}
+    {1711846800 7200 1 CEST}
+    {1729990800 3600 0 CET}
+    {1743296400 7200 1 CEST}
+    {1761440400 3600 0 CET}
+    {1774746000 7200 1 CEST}
+    {1792890000 3600 0 CET}
+    {1806195600 7200 1 CEST}
+    {1824944400 3600 0 CET}
+    {1837645200 7200 1 CEST}
+    {1856394000 3600 0 CET}
+    {1869094800 7200 1 CEST}
+    {1887843600 3600 0 CET}
+    {1901149200 7200 1 CEST}
+    {1919293200 3600 0 CET}
+    {1932598800 7200 1 CEST}
+    {1950742800 3600 0 CET}
+    {1964048400 7200 1 CEST}
+    {1982797200 3600 0 CET}
+    {1995498000 7200 1 CEST}
+    {2014246800 3600 0 CET}
+    {2026947600 7200 1 CEST}
+    {2045696400 3600 0 CET}
+    {2058397200 7200 1 CEST}
+    {2077146000 3600 0 CET}
+    {2090451600 7200 1 CEST}
+    {2108595600 3600 0 CET}
+    {2121901200 7200 1 CEST}
+    {2140045200 3600 0 CET}
+    {2153350800 7200 1 CEST}
+    {2172099600 3600 0 CET}
+    {2184800400 7200 1 CEST}
+    {2203549200 3600 0 CET}
+    {2216250000 7200 1 CEST}
+    {2234998800 3600 0 CET}
+    {2248304400 7200 1 CEST}
+    {2266448400 3600 0 CET}
+    {2279754000 7200 1 CEST}
+    {2297898000 3600 0 CET}
+    {2311203600 7200 1 CEST}
+    {2329347600 3600 0 CET}
+    {2342653200 7200 1 CEST}
+    {2361402000 3600 0 CET}
+    {2374102800 7200 1 CEST}
+    {2392851600 3600 0 CET}
+    {2405552400 7200 1 CEST}
+    {2424301200 3600 0 CET}
+    {2437606800 7200 1 CEST}
+    {2455750800 3600 0 CET}
+    {2469056400 7200 1 CEST}
+    {2487200400 3600 0 CET}
+    {2500506000 7200 1 CEST}
+    {2519254800 3600 0 CET}
+    {2531955600 7200 1 CEST}
+    {2550704400 3600 0 CET}
+    {2563405200 7200 1 CEST}
+    {2582154000 3600 0 CET}
+    {2595459600 7200 1 CEST}
+    {2613603600 3600 0 CET}
+    {2626909200 7200 1 CEST}
+    {2645053200 3600 0 CET}
+    {2658358800 7200 1 CEST}
+    {2676502800 3600 0 CET}
+    {2689808400 7200 1 CEST}
+    {2708557200 3600 0 CET}
+    {2721258000 7200 1 CEST}
+    {2740006800 3600 0 CET}
+    {2752707600 7200 1 CEST}
+    {2771456400 3600 0 CET}
+    {2784762000 7200 1 CEST}
+    {2802906000 3600 0 CET}
+    {2816211600 7200 1 CEST}
+    {2834355600 3600 0 CET}
+    {2847661200 7200 1 CEST}
+    {2866410000 3600 0 CET}
+    {2879110800 7200 1 CEST}
+    {2897859600 3600 0 CET}
+    {2910560400 7200 1 CEST}
+    {2929309200 3600 0 CET}
+    {2942010000 7200 1 CEST}
+    {2960758800 3600 0 CET}
+    {2974064400 7200 1 CEST}
+    {2992208400 3600 0 CET}
+    {3005514000 7200 1 CEST}
+    {3023658000 3600 0 CET}
+    {3036963600 7200 1 CEST}
+    {3055712400 3600 0 CET}
+    {3068413200 7200 1 CEST}
+    {3087162000 3600 0 CET}
+    {3099862800 7200 1 CEST}
+    {3118611600 3600 0 CET}
+    {3131917200 7200 1 CEST}
+    {3150061200 3600 0 CET}
+    {3163366800 7200 1 CEST}
+    {3181510800 3600 0 CET}
+    {3194816400 7200 1 CEST}
+    {3212960400 3600 0 CET}
+    {3226266000 7200 1 CEST}
+    {3245014800 3600 0 CET}
+    {3257715600 7200 1 CEST}
+    {3276464400 3600 0 CET}
+    {3289165200 7200 1 CEST}
+    {3307914000 3600 0 CET}
+    {3321219600 7200 1 CEST}
+    {3339363600 3600 0 CET}
+    {3352669200 7200 1 CEST}
+    {3370813200 3600 0 CET}
+    {3384118800 7200 1 CEST}
+    {3402867600 3600 0 CET}
+    {3415568400 7200 1 CEST}
+    {3434317200 3600 0 CET}
+    {3447018000 7200 1 CEST}
+    {3465766800 3600 0 CET}
+    {3479072400 7200 1 CEST}
+    {3497216400 3600 0 CET}
+    {3510522000 7200 1 CEST}
+    {3528666000 3600 0 CET}
+    {3541971600 7200 1 CEST}
+    {3560115600 3600 0 CET}
+    {3573421200 7200 1 CEST}
+    {3592170000 3600 0 CET}
+    {3604870800 7200 1 CEST}
+    {3623619600 3600 0 CET}
+    {3636320400 7200 1 CEST}
+    {3655069200 3600 0 CET}
+    {3668374800 7200 1 CEST}
+    {3686518800 3600 0 CET}
+    {3699824400 7200 1 CEST}
+    {3717968400 3600 0 CET}
+    {3731274000 7200 1 CEST}
+    {3750022800 3600 0 CET}
+    {3762723600 7200 1 CEST}
+    {3781472400 3600 0 CET}
+    {3794173200 7200 1 CEST}
+    {3812922000 3600 0 CET}
+    {3825622800 7200 1 CEST}
+    {3844371600 3600 0 CET}
+    {3857677200 7200 1 CEST}
+    {3875821200 3600 0 CET}
+    {3889126800 7200 1 CEST}
+    {3907270800 3600 0 CET}
+    {3920576400 7200 1 CEST}
+    {3939325200 3600 0 CET}
+    {3952026000 7200 1 CEST}
+    {3970774800 3600 0 CET}
+    {3983475600 7200 1 CEST}
+    {4002224400 3600 0 CET}
+    {4015530000 7200 1 CEST}
+    {4033674000 3600 0 CET}
+    {4046979600 7200 1 CEST}
+    {4065123600 3600 0 CET}
+    {4078429200 7200 1 CEST}
+    {4096573200 3600 0 CET}
+}
diff --git a/library/tzdata/Europe/Riga b/library/tzdata/Europe/Riga
new file mode 100644
index 0000000..c829ffb
--- /dev/null
+++ b/library/tzdata/Europe/Riga
@@ -0,0 +1,258 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Europe/Riga) {
+    {-9223372036854775808 5794 0 LMT}
+    {-2840146594 5794 0 RMT}
+    {-1632008194 9394 1 LST}
+    {-1618702594 5794 0 RMT}
+    {-1601681794 9394 1 LST}
+    {-1597275394 5794 0 RMT}
+    {-1377308194 7200 0 EET}
+    {-928029600 10800 0 MSK}
+    {-899521200 3600 0 CET}
+    {-857257200 3600 0 CET}
+    {-844556400 7200 1 CEST}
+    {-828226800 3600 0 CET}
+    {-812502000 7200 1 CEST}
+    {-796777200 3600 0 CET}
+    {-795834000 10800 0 MSD}
+    {354920400 14400 1 MSD}
+    {370728000 10800 0 MSK}
+    {386456400 14400 1 MSD}
+    {402264000 10800 0 MSK}
+    {417992400 14400 1 MSD}
+    {433800000 10800 0 MSK}
+    {449614800 14400 1 MSD}
+    {465346800 10800 0 MSK}
+    {481071600 14400 1 MSD}
+    {496796400 10800 0 MSK}
+    {512521200 14400 1 MSD}
+    {528246000 10800 0 MSK}
+    {543970800 14400 1 MSD}
+    {559695600 10800 0 MSK}
+    {575420400 14400 1 MSD}
+    {591145200 10800 0 MSK}
+    {606870000 10800 1 EEST}
+    {622598400 7200 0 EET}
+    {638323200 10800 1 EEST}
+    {654652800 7200 0 EET}
+    {670377600 10800 1 EEST}
+    {686102400 7200 0 EET}
+    {701827200 10800 1 EEST}
+    {717552000 7200 0 EET}
+    {733276800 10800 1 EEST}
+    {749001600 7200 0 EET}
+    {764726400 10800 1 EEST}
+    {780451200 7200 0 EET}
+    {796176000 10800 1 EEST}
+    {811900800 7200 0 EET}
+    {828230400 10800 1 EEST}
+    {843955200 7200 0 EET}
+    {853797600 7200 0 EET}
+    {859683600 10800 1 EEST}
+    {877827600 7200 0 EET}
+    {891133200 10800 1 EEST}
+    {909277200 7200 0 EET}
+    {922582800 10800 1 EEST}
+    {941331600 7200 0 EET}
+    {951775200 7200 0 EET}
+    {978386400 7200 0 EET}
+    {985482000 10800 1 EEST}
+    {1004230800 7200 0 EET}
+    {1017536400 10800 1 EEST}
+    {1035680400 7200 0 EET}
+    {1048986000 10800 1 EEST}
+    {1067130000 7200 0 EET}
+    {1080435600 10800 1 EEST}
+    {1099184400 7200 0 EET}
+    {1111885200 10800 1 EEST}
+    {1130634000 7200 0 EET}
+    {1143334800 10800 1 EEST}
+    {1162083600 7200 0 EET}
+    {1174784400 10800 1 EEST}
+    {1193533200 7200 0 EET}
+    {1206838800 10800 1 EEST}
+    {1224982800 7200 0 EET}
+    {1238288400 10800 1 EEST}
+    {1256432400 7200 0 EET}
+    {1269738000 10800 1 EEST}
+    {1288486800 7200 0 EET}
+    {1301187600 10800 1 EEST}
+    {1319936400 7200 0 EET}
+    {1332637200 10800 1 EEST}
+    {1351386000 7200 0 EET}
+    {1364691600 10800 1 EEST}
+    {1382835600 7200 0 EET}
+    {1396141200 10800 1 EEST}
+    {1414285200 7200 0 EET}
+    {1427590800 10800 1 EEST}
+    {1445734800 7200 0 EET}
+    {1459040400 10800 1 EEST}
+    {1477789200 7200 0 EET}
+    {1490490000 10800 1 EEST}
+    {1509238800 7200 0 EET}
+    {1521939600 10800 1 EEST}
+    {1540688400 7200 0 EET}
+    {1553994000 10800 1 EEST}
+    {1572138000 7200 0 EET}
+    {1585443600 10800 1 EEST}
+    {1603587600 7200 0 EET}
+    {1616893200 10800 1 EEST}
+    {1635642000 7200 0 EET}
+    {1648342800 10800 1 EEST}
+    {1667091600 7200 0 EET}
+    {1679792400 10800 1 EEST}
+    {1698541200 7200 0 EET}
+    {1711846800 10800 1 EEST}
+    {1729990800 7200 0 EET}
+    {1743296400 10800 1 EEST}
+    {1761440400 7200 0 EET}
+    {1774746000 10800 1 EEST}
+    {1792890000 7200 0 EET}
+    {1806195600 10800 1 EEST}
+    {1824944400 7200 0 EET}
+    {1837645200 10800 1 EEST}
+    {1856394000 7200 0 EET}
+    {1869094800 10800 1 EEST}
+    {1887843600 7200 0 EET}
+    {1901149200 10800 1 EEST}
+    {1919293200 7200 0 EET}
+    {1932598800 10800 1 EEST}
+    {1950742800 7200 0 EET}
+    {1964048400 10800 1 EEST}
+    {1982797200 7200 0 EET}
+    {1995498000 10800 1 EEST}
+    {2014246800 7200 0 EET}
+    {2026947600 10800 1 EEST}
+    {2045696400 7200 0 EET}
+    {2058397200 10800 1 EEST}
+    {2077146000 7200 0 EET}
+    {2090451600 10800 1 EEST}
+    {2108595600 7200 0 EET}
+    {2121901200 10800 1 EEST}
+    {2140045200 7200 0 EET}
+    {2153350800 10800 1 EEST}
+    {2172099600 7200 0 EET}
+    {2184800400 10800 1 EEST}
+    {2203549200 7200 0 EET}
+    {2216250000 10800 1 EEST}
+    {2234998800 7200 0 EET}
+    {2248304400 10800 1 EEST}
+    {2266448400 7200 0 EET}
+    {2279754000 10800 1 EEST}
+    {2297898000 7200 0 EET}
+    {2311203600 10800 1 EEST}
+    {2329347600 7200 0 EET}
+    {2342653200 10800 1 EEST}
+    {2361402000 7200 0 EET}
+    {2374102800 10800 1 EEST}
+    {2392851600 7200 0 EET}
+    {2405552400 10800 1 EEST}
+    {2424301200 7200 0 EET}
+    {2437606800 10800 1 EEST}
+    {2455750800 7200 0 EET}
+    {2469056400 10800 1 EEST}
+    {2487200400 7200 0 EET}
+    {2500506000 10800 1 EEST}
+    {2519254800 7200 0 EET}
+    {2531955600 10800 1 EEST}
+    {2550704400 7200 0 EET}
+    {2563405200 10800 1 EEST}
+    {2582154000 7200 0 EET}
+    {2595459600 10800 1 EEST}
+    {2613603600 7200 0 EET}
+    {2626909200 10800 1 EEST}
+    {2645053200 7200 0 EET}
+    {2658358800 10800 1 EEST}
+    {2676502800 7200 0 EET}
+    {2689808400 10800 1 EEST}
+    {2708557200 7200 0 EET}
+    {2721258000 10800 1 EEST}
+    {2740006800 7200 0 EET}
+    {2752707600 10800 1 EEST}
+    {2771456400 7200 0 EET}
+    {2784762000 10800 1 EEST}
+    {2802906000 7200 0 EET}
+    {2816211600 10800 1 EEST}
+    {2834355600 7200 0 EET}
+    {2847661200 10800 1 EEST}
+    {2866410000 7200 0 EET}
+    {2879110800 10800 1 EEST}
+    {2897859600 7200 0 EET}
+    {2910560400 10800 1 EEST}
+    {2929309200 7200 0 EET}
+    {2942010000 10800 1 EEST}
+    {2960758800 7200 0 EET}
+    {2974064400 10800 1 EEST}
+    {2992208400 7200 0 EET}
+    {3005514000 10800 1 EEST}
+    {3023658000 7200 0 EET}
+    {3036963600 10800 1 EEST}
+    {3055712400 7200 0 EET}
+    {3068413200 10800 1 EEST}
+    {3087162000 7200 0 EET}
+    {3099862800 10800 1 EEST}
+    {3118611600 7200 0 EET}
+    {3131917200 10800 1 EEST}
+    {3150061200 7200 0 EET}
+    {3163366800 10800 1 EEST}
+    {3181510800 7200 0 EET}
+    {3194816400 10800 1 EEST}
+    {3212960400 7200 0 EET}
+    {3226266000 10800 1 EEST}
+    {3245014800 7200 0 EET}
+    {3257715600 10800 1 EEST}
+    {3276464400 7200 0 EET}
+    {3289165200 10800 1 EEST}
+    {3307914000 7200 0 EET}
+    {3321219600 10800 1 EEST}
+    {3339363600 7200 0 EET}
+    {3352669200 10800 1 EEST}
+    {3370813200 7200 0 EET}
+    {3384118800 10800 1 EEST}
+    {3402867600 7200 0 EET}
+    {3415568400 10800 1 EEST}
+    {3434317200 7200 0 EET}
+    {3447018000 10800 1 EEST}
+    {3465766800 7200 0 EET}
+    {3479072400 10800 1 EEST}
+    {3497216400 7200 0 EET}
+    {3510522000 10800 1 EEST}
+    {3528666000 7200 0 EET}
+    {3541971600 10800 1 EEST}
+    {3560115600 7200 0 EET}
+    {3573421200 10800 1 EEST}
+    {3592170000 7200 0 EET}
+    {3604870800 10800 1 EEST}
+    {3623619600 7200 0 EET}
+    {3636320400 10800 1 EEST}
+    {3655069200 7200 0 EET}
+    {3668374800 10800 1 EEST}
+    {3686518800 7200 0 EET}
+    {3699824400 10800 1 EEST}
+    {3717968400 7200 0 EET}
+    {3731274000 10800 1 EEST}
+    {3750022800 7200 0 EET}
+    {3762723600 10800 1 EEST}
+    {3781472400 7200 0 EET}
+    {3794173200 10800 1 EEST}
+    {3812922000 7200 0 EET}
+    {3825622800 10800 1 EEST}
+    {3844371600 7200 0 EET}
+    {3857677200 10800 1 EEST}
+    {3875821200 7200 0 EET}
+    {3889126800 10800 1 EEST}
+    {3907270800 7200 0 EET}
+    {3920576400 10800 1 EEST}
+    {3939325200 7200 0 EET}
+    {3952026000 10800 1 EEST}
+    {3970774800 7200 0 EET}
+    {3983475600 10800 1 EEST}
+    {4002224400 7200 0 EET}
+    {4015530000 10800 1 EEST}
+    {4033674000 7200 0 EET}
+    {4046979600 10800 1 EEST}
+    {4065123600 7200 0 EET}
+    {4078429200 10800 1 EEST}
+    {4096573200 7200 0 EET}
+}
diff --git a/library/tzdata/Europe/Rome b/library/tzdata/Europe/Rome
new file mode 100644
index 0000000..64948b8
--- /dev/null
+++ b/library/tzdata/Europe/Rome
@@ -0,0 +1,301 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Europe/Rome) {
+    {-9223372036854775808 2996 0 LMT}
+    {-3259097396 2996 0 RMT}
+    {-2403564596 3600 0 CET}
+    {-1690851600 7200 1 CEST}
+    {-1680483600 3600 0 CET}
+    {-1664758800 7200 1 CEST}
+    {-1649034000 3600 0 CET}
+    {-1635123600 7200 1 CEST}
+    {-1616979600 3600 0 CET}
+    {-1604278800 7200 1 CEST}
+    {-1585530000 3600 0 CET}
+    {-1571014800 7200 1 CEST}
+    {-1555290000 3600 0 CET}
+    {-932432400 7200 1 CEST}
+    {-857257200 3600 0 CET}
+    {-844556400 7200 1 CEST}
+    {-828226800 3600 0 CET}
+    {-812502000 7200 1 CEST}
+    {-804819600 3600 0 CET}
+    {-798080400 3600 0 CET}
+    {-781052400 7200 1 CEST}
+    {-766717200 3600 0 CET}
+    {-750898800 7200 1 CEST}
+    {-733359600 3600 0 CET}
+    {-719456400 7200 1 CEST}
+    {-701917200 3600 0 CET}
+    {-689209200 7200 1 CEST}
+    {-670460400 3600 0 CET}
+    {-114051600 7200 1 CEST}
+    {-103168800 3600 0 CET}
+    {-81997200 7200 1 CEST}
+    {-71719200 3600 0 CET}
+    {-50547600 7200 1 CEST}
+    {-40269600 3600 0 CET}
+    {-18493200 7200 1 CEST}
+    {-8215200 3600 0 CET}
+    {12956400 7200 1 CEST}
+    {23234400 3600 0 CET}
+    {43801200 7200 1 CEST}
+    {54687600 3600 0 CET}
+    {75855600 7200 1 CEST}
+    {86738400 3600 0 CET}
+    {107910000 7200 1 CEST}
+    {118188000 3600 0 CET}
+    {138754800 7200 1 CEST}
+    {149637600 3600 0 CET}
+    {170809200 7200 1 CEST}
+    {181090800 3600 0 CET}
+    {202258800 7200 1 CEST}
+    {212540400 3600 0 CET}
+    {233103600 7200 1 CEST}
+    {243990000 3600 0 CET}
+    {265158000 7200 1 CEST}
+    {276044400 3600 0 CET}
+    {296607600 7200 1 CEST}
+    {307494000 3600 0 CET}
+    {315529200 3600 0 CET}
+    {323830800 7200 1 CEST}
+    {338950800 3600 0 CET}
+    {354675600 7200 1 CEST}
+    {370400400 3600 0 CET}
+    {386125200 7200 1 CEST}
+    {401850000 3600 0 CET}
+    {417574800 7200 1 CEST}
+    {433299600 3600 0 CET}
+    {449024400 7200 1 CEST}
+    {465354000 3600 0 CET}
+    {481078800 7200 1 CEST}
+    {496803600 3600 0 CET}
+    {512528400 7200 1 CEST}
+    {528253200 3600 0 CET}
+    {543978000 7200 1 CEST}
+    {559702800 3600 0 CET}
+    {575427600 7200 1 CEST}
+    {591152400 3600 0 CET}
+    {606877200 7200 1 CEST}
+    {622602000 3600 0 CET}
+    {638326800 7200 1 CEST}
+    {654656400 3600 0 CET}
+    {670381200 7200 1 CEST}
+    {686106000 3600 0 CET}
+    {701830800 7200 1 CEST}
+    {717555600 3600 0 CET}
+    {733280400 7200 1 CEST}
+    {749005200 3600 0 CET}
+    {764730000 7200 1 CEST}
+    {780454800 3600 0 CET}
+    {796179600 7200 1 CEST}
+    {811904400 3600 0 CET}
+    {828234000 7200 1 CEST}
+    {846378000 3600 0 CET}
+    {859683600 7200 1 CEST}
+    {877827600 3600 0 CET}
+    {891133200 7200 1 CEST}
+    {909277200 3600 0 CET}
+    {922582800 7200 1 CEST}
+    {941331600 3600 0 CET}
+    {954032400 7200 1 CEST}
+    {972781200 3600 0 CET}
+    {985482000 7200 1 CEST}
+    {1004230800 3600 0 CET}
+    {1017536400 7200 1 CEST}
+    {1035680400 3600 0 CET}
+    {1048986000 7200 1 CEST}
+    {1067130000 3600 0 CET}
+    {1080435600 7200 1 CEST}
+    {1099184400 3600 0 CET}
+    {1111885200 7200 1 CEST}
+    {1130634000 3600 0 CET}
+    {1143334800 7200 1 CEST}
+    {1162083600 3600 0 CET}
+    {1174784400 7200 1 CEST}
+    {1193533200 3600 0 CET}
+    {1206838800 7200 1 CEST}
+    {1224982800 3600 0 CET}
+    {1238288400 7200 1 CEST}
+    {1256432400 3600 0 CET}
+    {1269738000 7200 1 CEST}
+    {1288486800 3600 0 CET}
+    {1301187600 7200 1 CEST}
+    {1319936400 3600 0 CET}
+    {1332637200 7200 1 CEST}
+    {1351386000 3600 0 CET}
+    {1364691600 7200 1 CEST}
+    {1382835600 3600 0 CET}
+    {1396141200 7200 1 CEST}
+    {1414285200 3600 0 CET}
+    {1427590800 7200 1 CEST}
+    {1445734800 3600 0 CET}
+    {1459040400 7200 1 CEST}
+    {1477789200 3600 0 CET}
+    {1490490000 7200 1 CEST}
+    {1509238800 3600 0 CET}
+    {1521939600 7200 1 CEST}
+    {1540688400 3600 0 CET}
+    {1553994000 7200 1 CEST}
+    {1572138000 3600 0 CET}
+    {1585443600 7200 1 CEST}
+    {1603587600 3600 0 CET}
+    {1616893200 7200 1 CEST}
+    {1635642000 3600 0 CET}
+    {1648342800 7200 1 CEST}
+    {1667091600 3600 0 CET}
+    {1679792400 7200 1 CEST}
+    {1698541200 3600 0 CET}
+    {1711846800 7200 1 CEST}
+    {1729990800 3600 0 CET}
+    {1743296400 7200 1 CEST}
+    {1761440400 3600 0 CET}
+    {1774746000 7200 1 CEST}
+    {1792890000 3600 0 CET}
+    {1806195600 7200 1 CEST}
+    {1824944400 3600 0 CET}
+    {1837645200 7200 1 CEST}
+    {1856394000 3600 0 CET}
+    {1869094800 7200 1 CEST}
+    {1887843600 3600 0 CET}
+    {1901149200 7200 1 CEST}
+    {1919293200 3600 0 CET}
+    {1932598800 7200 1 CEST}
+    {1950742800 3600 0 CET}
+    {1964048400 7200 1 CEST}
+    {1982797200 3600 0 CET}
+    {1995498000 7200 1 CEST}
+    {2014246800 3600 0 CET}
+    {2026947600 7200 1 CEST}
+    {2045696400 3600 0 CET}
+    {2058397200 7200 1 CEST}
+    {2077146000 3600 0 CET}
+    {2090451600 7200 1 CEST}
+    {2108595600 3600 0 CET}
+    {2121901200 7200 1 CEST}
+    {2140045200 3600 0 CET}
+    {2153350800 7200 1 CEST}
+    {2172099600 3600 0 CET}
+    {2184800400 7200 1 CEST}
+    {2203549200 3600 0 CET}
+    {2216250000 7200 1 CEST}
+    {2234998800 3600 0 CET}
+    {2248304400 7200 1 CEST}
+    {2266448400 3600 0 CET}
+    {2279754000 7200 1 CEST}
+    {2297898000 3600 0 CET}
+    {2311203600 7200 1 CEST}
+    {2329347600 3600 0 CET}
+    {2342653200 7200 1 CEST}
+    {2361402000 3600 0 CET}
+    {2374102800 7200 1 CEST}
+    {2392851600 3600 0 CET}
+    {2405552400 7200 1 CEST}
+    {2424301200 3600 0 CET}
+    {2437606800 7200 1 CEST}
+    {2455750800 3600 0 CET}
+    {2469056400 7200 1 CEST}
+    {2487200400 3600 0 CET}
+    {2500506000 7200 1 CEST}
+    {2519254800 3600 0 CET}
+    {2531955600 7200 1 CEST}
+    {2550704400 3600 0 CET}
+    {2563405200 7200 1 CEST}
+    {2582154000 3600 0 CET}
+    {2595459600 7200 1 CEST}
+    {2613603600 3600 0 CET}
+    {2626909200 7200 1 CEST}
+    {2645053200 3600 0 CET}
+    {2658358800 7200 1 CEST}
+    {2676502800 3600 0 CET}
+    {2689808400 7200 1 CEST}
+    {2708557200 3600 0 CET}
+    {2721258000 7200 1 CEST}
+    {2740006800 3600 0 CET}
+    {2752707600 7200 1 CEST}
+    {2771456400 3600 0 CET}
+    {2784762000 7200 1 CEST}
+    {2802906000 3600 0 CET}
+    {2816211600 7200 1 CEST}
+    {2834355600 3600 0 CET}
+    {2847661200 7200 1 CEST}
+    {2866410000 3600 0 CET}
+    {2879110800 7200 1 CEST}
+    {2897859600 3600 0 CET}
+    {2910560400 7200 1 CEST}
+    {2929309200 3600 0 CET}
+    {2942010000 7200 1 CEST}
+    {2960758800 3600 0 CET}
+    {2974064400 7200 1 CEST}
+    {2992208400 3600 0 CET}
+    {3005514000 7200 1 CEST}
+    {3023658000 3600 0 CET}
+    {3036963600 7200 1 CEST}
+    {3055712400 3600 0 CET}
+    {3068413200 7200 1 CEST}
+    {3087162000 3600 0 CET}
+    {3099862800 7200 1 CEST}
+    {3118611600 3600 0 CET}
+    {3131917200 7200 1 CEST}
+    {3150061200 3600 0 CET}
+    {3163366800 7200 1 CEST}
+    {3181510800 3600 0 CET}
+    {3194816400 7200 1 CEST}
+    {3212960400 3600 0 CET}
+    {3226266000 7200 1 CEST}
+    {3245014800 3600 0 CET}
+    {3257715600 7200 1 CEST}
+    {3276464400 3600 0 CET}
+    {3289165200 7200 1 CEST}
+    {3307914000 3600 0 CET}
+    {3321219600 7200 1 CEST}
+    {3339363600 3600 0 CET}
+    {3352669200 7200 1 CEST}
+    {3370813200 3600 0 CET}
+    {3384118800 7200 1 CEST}
+    {3402867600 3600 0 CET}
+    {3415568400 7200 1 CEST}
+    {3434317200 3600 0 CET}
+    {3447018000 7200 1 CEST}
+    {3465766800 3600 0 CET}
+    {3479072400 7200 1 CEST}
+    {3497216400 3600 0 CET}
+    {3510522000 7200 1 CEST}
+    {3528666000 3600 0 CET}
+    {3541971600 7200 1 CEST}
+    {3560115600 3600 0 CET}
+    {3573421200 7200 1 CEST}
+    {3592170000 3600 0 CET}
+    {3604870800 7200 1 CEST}
+    {3623619600 3600 0 CET}
+    {3636320400 7200 1 CEST}
+    {3655069200 3600 0 CET}
+    {3668374800 7200 1 CEST}
+    {3686518800 3600 0 CET}
+    {3699824400 7200 1 CEST}
+    {3717968400 3600 0 CET}
+    {3731274000 7200 1 CEST}
+    {3750022800 3600 0 CET}
+    {3762723600 7200 1 CEST}
+    {3781472400 3600 0 CET}
+    {3794173200 7200 1 CEST}
+    {3812922000 3600 0 CET}
+    {3825622800 7200 1 CEST}
+    {3844371600 3600 0 CET}
+    {3857677200 7200 1 CEST}
+    {3875821200 3600 0 CET}
+    {3889126800 7200 1 CEST}
+    {3907270800 3600 0 CET}
+    {3920576400 7200 1 CEST}
+    {3939325200 3600 0 CET}
+    {3952026000 7200 1 CEST}
+    {3970774800 3600 0 CET}
+    {3983475600 7200 1 CEST}
+    {4002224400 3600 0 CET}
+    {4015530000 7200 1 CEST}
+    {4033674000 3600 0 CET}
+    {4046979600 7200 1 CEST}
+    {4065123600 3600 0 CET}
+    {4078429200 7200 1 CEST}
+    {4096573200 3600 0 CET}
+}
diff --git a/library/tzdata/Europe/Samara b/library/tzdata/Europe/Samara
new file mode 100644
index 0000000..08203c0
--- /dev/null
+++ b/library/tzdata/Europe/Samara
@@ -0,0 +1,73 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Europe/Samara) {
+    {-9223372036854775808 12020 0 LMT}
+    {-1593825620 10800 0 SAMT}
+    {-1247540400 14400 0 SAMT}
+    {-1102305600 14400 0 KUYMMTT}
+    {354916800 18000 1 KUYST}
+    {370724400 14400 0 KUYT}
+    {386452800 18000 1 KUYST}
+    {402260400 14400 0 KUYT}
+    {417988800 18000 1 KUYST}
+    {433796400 14400 0 KUYT}
+    {449611200 18000 1 KUYST}
+    {465343200 14400 0 KUYT}
+    {481068000 18000 1 KUYST}
+    {496792800 14400 0 KUYT}
+    {512517600 18000 1 KUYST}
+    {528242400 14400 0 KUYT}
+    {543967200 18000 1 KUYST}
+    {559692000 14400 0 KUYT}
+    {575416800 18000 1 KUYST}
+    {591141600 14400 0 KUYT}
+    {606866400 10800 0 MSD}
+    {606870000 14400 1 MSD}
+    {622594800 10800 0 MSK}
+    {638319600 14400 1 MSD}
+    {654649200 10800 0 MSK}
+    {670374000 7200 0 EEMMTT}
+    {670377600 10800 1 EEST}
+    {686102400 10800 0 SAMT}
+    {687916800 14400 0 SAMT}
+    {701820000 18000 1 SAMST}
+    {717544800 14400 0 SAMT}
+    {733269600 18000 1 SAMST}
+    {748994400 14400 0 SAMT}
+    {764719200 18000 1 SAMST}
+    {780444000 14400 0 SAMT}
+    {796168800 18000 1 SAMST}
+    {811893600 14400 0 SAMT}
+    {828223200 18000 1 SAMST}
+    {846367200 14400 0 SAMT}
+    {859672800 18000 1 SAMST}
+    {877816800 14400 0 SAMT}
+    {891122400 18000 1 SAMST}
+    {909266400 14400 0 SAMT}
+    {922572000 18000 1 SAMST}
+    {941320800 14400 0 SAMT}
+    {954021600 18000 1 SAMST}
+    {972770400 14400 0 SAMT}
+    {985471200 18000 1 SAMST}
+    {1004220000 14400 0 SAMT}
+    {1017525600 18000 1 SAMST}
+    {1035669600 14400 0 SAMT}
+    {1048975200 18000 1 SAMST}
+    {1067119200 14400 0 SAMT}
+    {1080424800 18000 1 SAMST}
+    {1099173600 14400 0 SAMT}
+    {1111874400 18000 1 SAMST}
+    {1130623200 14400 0 SAMT}
+    {1143324000 18000 1 SAMST}
+    {1162072800 14400 0 SAMT}
+    {1174773600 18000 1 SAMST}
+    {1193522400 14400 0 SAMT}
+    {1206828000 18000 1 SAMST}
+    {1224972000 14400 0 SAMT}
+    {1238277600 18000 1 SAMST}
+    {1256421600 14400 0 SAMT}
+    {1269727200 10800 0 SAMMMTT}
+    {1269730800 14400 1 SAMST}
+    {1288479600 10800 0 SAMT}
+    {1301180400 14400 0 SAMT}
+}
diff --git a/library/tzdata/Europe/San_Marino b/library/tzdata/Europe/San_Marino
new file mode 100644
index 0000000..927ad29
--- /dev/null
+++ b/library/tzdata/Europe/San_Marino
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Europe/Rome)]} {
+    LoadTimeZoneFile Europe/Rome
+}
+set TZData(:Europe/San_Marino) $TZData(:Europe/Rome)
diff --git a/library/tzdata/Europe/Sarajevo b/library/tzdata/Europe/Sarajevo
new file mode 100644
index 0000000..1b14286
--- /dev/null
+++ b/library/tzdata/Europe/Sarajevo
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Europe/Belgrade)]} {
+    LoadTimeZoneFile Europe/Belgrade
+}
+set TZData(:Europe/Sarajevo) $TZData(:Europe/Belgrade)
diff --git a/library/tzdata/Europe/Simferopol b/library/tzdata/Europe/Simferopol
new file mode 100644
index 0000000..3e4b60a
--- /dev/null
+++ b/library/tzdata/Europe/Simferopol
@@ -0,0 +1,82 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Europe/Simferopol) {
+    {-9223372036854775808 8184 0 LMT}
+    {-2840148984 8160 0 SMT}
+    {-1441160160 7200 0 EET}
+    {-1247536800 10800 0 MSK}
+    {-888894000 3600 0 CET}
+    {-857257200 3600 0 CET}
+    {-844556400 7200 1 CEST}
+    {-828226800 3600 0 CET}
+    {-812502000 7200 1 CEST}
+    {-811645200 10800 0 MSD}
+    {354920400 14400 1 MSD}
+    {370728000 10800 0 MSK}
+    {386456400 14400 1 MSD}
+    {402264000 10800 0 MSK}
+    {417992400 14400 1 MSD}
+    {433800000 10800 0 MSK}
+    {449614800 14400 1 MSD}
+    {465346800 10800 0 MSK}
+    {481071600 14400 1 MSD}
+    {496796400 10800 0 MSK}
+    {512521200 14400 1 MSD}
+    {528246000 10800 0 MSK}
+    {543970800 14400 1 MSD}
+    {559695600 10800 0 MSK}
+    {575420400 14400 1 MSD}
+    {591145200 10800 0 MSK}
+    {606870000 14400 1 MSD}
+    {622594800 10800 0 MSK}
+    {631141200 10800 0 MSK}
+    {646786800 7200 0 EET}
+    {694216800 7200 0 EET}
+    {701820000 10800 1 EEST}
+    {717541200 7200 0 EET}
+    {733269600 10800 1 EEST}
+    {748990800 7200 0 EET}
+    {764719200 10800 1 EEST}
+    {767743200 14400 0 MSD}
+    {780436800 10800 0 MSK}
+    {796165200 14400 1 MSD}
+    {811886400 10800 0 MSK}
+    {828219600 14400 1 MSD}
+    {852066000 10800 0 MSK}
+    {859683600 10800 0 EEST}
+    {877827600 7200 0 EET}
+    {891133200 10800 1 EEST}
+    {909277200 7200 0 EET}
+    {922582800 10800 1 EEST}
+    {941331600 7200 0 EET}
+    {954032400 10800 1 EEST}
+    {972781200 7200 0 EET}
+    {985482000 10800 1 EEST}
+    {1004230800 7200 0 EET}
+    {1017536400 10800 1 EEST}
+    {1035680400 7200 0 EET}
+    {1048986000 10800 1 EEST}
+    {1067130000 7200 0 EET}
+    {1080435600 10800 1 EEST}
+    {1099184400 7200 0 EET}
+    {1111885200 10800 1 EEST}
+    {1130634000 7200 0 EET}
+    {1143334800 10800 1 EEST}
+    {1162083600 7200 0 EET}
+    {1174784400 10800 1 EEST}
+    {1193533200 7200 0 EET}
+    {1206838800 10800 1 EEST}
+    {1224982800 7200 0 EET}
+    {1238288400 10800 1 EEST}
+    {1256432400 7200 0 EET}
+    {1269738000 10800 1 EEST}
+    {1288486800 7200 0 EET}
+    {1301187600 10800 1 EEST}
+    {1319936400 7200 0 EET}
+    {1332637200 10800 1 EEST}
+    {1351386000 7200 0 EET}
+    {1364691600 10800 1 EEST}
+    {1382835600 7200 0 EET}
+    {1396137600 14400 0 MSK}
+    {1414274400 10800 0 MSK}
+}
diff --git a/library/tzdata/Europe/Skopje b/library/tzdata/Europe/Skopje
new file mode 100644
index 0000000..07eedbe
--- /dev/null
+++ b/library/tzdata/Europe/Skopje
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Europe/Belgrade)]} {
+    LoadTimeZoneFile Europe/Belgrade
+}
+set TZData(:Europe/Skopje) $TZData(:Europe/Belgrade)
diff --git a/library/tzdata/Europe/Sofia b/library/tzdata/Europe/Sofia
new file mode 100644
index 0000000..a07f3bc
--- /dev/null
+++ b/library/tzdata/Europe/Sofia
@@ -0,0 +1,258 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Europe/Sofia) {
+    {-9223372036854775808 5596 0 LMT}
+    {-2840146396 7016 0 IMT}
+    {-2369527016 7200 0 EET}
+    {-857257200 3600 0 CET}
+    {-844556400 7200 1 CEST}
+    {-828226800 3600 0 CET}
+    {-812502000 7200 1 CEST}
+    {-796777200 3600 0 CET}
+    {-788922000 3600 0 CET}
+    {-781048800 7200 0 EET}
+    {291762000 10800 0 EEST}
+    {307576800 7200 0 EET}
+    {323816400 10800 1 EEST}
+    {339026400 7200 0 EET}
+    {355266000 10800 1 EEST}
+    {370393200 7200 0 EET}
+    {386715600 10800 1 EEST}
+    {401846400 7200 0 EET}
+    {417571200 10800 1 EEST}
+    {433296000 7200 0 EET}
+    {449020800 10800 1 EEST}
+    {465350400 7200 0 EET}
+    {481075200 10800 1 EEST}
+    {496800000 7200 0 EET}
+    {512524800 10800 1 EEST}
+    {528249600 7200 0 EET}
+    {543974400 10800 1 EEST}
+    {559699200 7200 0 EET}
+    {575424000 10800 1 EEST}
+    {591148800 7200 0 EET}
+    {606873600 10800 1 EEST}
+    {622598400 7200 0 EET}
+    {638323200 10800 1 EEST}
+    {654652800 7200 0 EET}
+    {662680800 7200 0 EET}
+    {670370400 10800 1 EEST}
+    {686091600 7200 0 EET}
+    {701820000 10800 1 EEST}
+    {717541200 7200 0 EET}
+    {733269600 10800 1 EEST}
+    {748990800 7200 0 EET}
+    {764719200 10800 1 EEST}
+    {780440400 7200 0 EET}
+    {796168800 10800 1 EEST}
+    {811890000 7200 0 EET}
+    {828223200 10800 1 EEST}
+    {846363600 7200 0 EET}
+    {852069600 7200 0 EET}
+    {859683600 10800 1 EEST}
+    {877827600 7200 0 EET}
+    {891133200 10800 1 EEST}
+    {909277200 7200 0 EET}
+    {922582800 10800 1 EEST}
+    {941331600 7200 0 EET}
+    {954032400 10800 1 EEST}
+    {972781200 7200 0 EET}
+    {985482000 10800 1 EEST}
+    {1004230800 7200 0 EET}
+    {1017536400 10800 1 EEST}
+    {1035680400 7200 0 EET}
+    {1048986000 10800 1 EEST}
+    {1067130000 7200 0 EET}
+    {1080435600 10800 1 EEST}
+    {1099184400 7200 0 EET}
+    {1111885200 10800 1 EEST}
+    {1130634000 7200 0 EET}
+    {1143334800 10800 1 EEST}
+    {1162083600 7200 0 EET}
+    {1174784400 10800 1 EEST}
+    {1193533200 7200 0 EET}
+    {1206838800 10800 1 EEST}
+    {1224982800 7200 0 EET}
+    {1238288400 10800 1 EEST}
+    {1256432400 7200 0 EET}
+    {1269738000 10800 1 EEST}
+    {1288486800 7200 0 EET}
+    {1301187600 10800 1 EEST}
+    {1319936400 7200 0 EET}
+    {1332637200 10800 1 EEST}
+    {1351386000 7200 0 EET}
+    {1364691600 10800 1 EEST}
+    {1382835600 7200 0 EET}
+    {1396141200 10800 1 EEST}
+    {1414285200 7200 0 EET}
+    {1427590800 10800 1 EEST}
+    {1445734800 7200 0 EET}
+    {1459040400 10800 1 EEST}
+    {1477789200 7200 0 EET}
+    {1490490000 10800 1 EEST}
+    {1509238800 7200 0 EET}
+    {1521939600 10800 1 EEST}
+    {1540688400 7200 0 EET}
+    {1553994000 10800 1 EEST}
+    {1572138000 7200 0 EET}
+    {1585443600 10800 1 EEST}
+    {1603587600 7200 0 EET}
+    {1616893200 10800 1 EEST}
+    {1635642000 7200 0 EET}
+    {1648342800 10800 1 EEST}
+    {1667091600 7200 0 EET}
+    {1679792400 10800 1 EEST}
+    {1698541200 7200 0 EET}
+    {1711846800 10800 1 EEST}
+    {1729990800 7200 0 EET}
+    {1743296400 10800 1 EEST}
+    {1761440400 7200 0 EET}
+    {1774746000 10800 1 EEST}
+    {1792890000 7200 0 EET}
+    {1806195600 10800 1 EEST}
+    {1824944400 7200 0 EET}
+    {1837645200 10800 1 EEST}
+    {1856394000 7200 0 EET}
+    {1869094800 10800 1 EEST}
+    {1887843600 7200 0 EET}
+    {1901149200 10800 1 EEST}
+    {1919293200 7200 0 EET}
+    {1932598800 10800 1 EEST}
+    {1950742800 7200 0 EET}
+    {1964048400 10800 1 EEST}
+    {1982797200 7200 0 EET}
+    {1995498000 10800 1 EEST}
+    {2014246800 7200 0 EET}
+    {2026947600 10800 1 EEST}
+    {2045696400 7200 0 EET}
+    {2058397200 10800 1 EEST}
+    {2077146000 7200 0 EET}
+    {2090451600 10800 1 EEST}
+    {2108595600 7200 0 EET}
+    {2121901200 10800 1 EEST}
+    {2140045200 7200 0 EET}
+    {2153350800 10800 1 EEST}
+    {2172099600 7200 0 EET}
+    {2184800400 10800 1 EEST}
+    {2203549200 7200 0 EET}
+    {2216250000 10800 1 EEST}
+    {2234998800 7200 0 EET}
+    {2248304400 10800 1 EEST}
+    {2266448400 7200 0 EET}
+    {2279754000 10800 1 EEST}
+    {2297898000 7200 0 EET}
+    {2311203600 10800 1 EEST}
+    {2329347600 7200 0 EET}
+    {2342653200 10800 1 EEST}
+    {2361402000 7200 0 EET}
+    {2374102800 10800 1 EEST}
+    {2392851600 7200 0 EET}
+    {2405552400 10800 1 EEST}
+    {2424301200 7200 0 EET}
+    {2437606800 10800 1 EEST}
+    {2455750800 7200 0 EET}
+    {2469056400 10800 1 EEST}
+    {2487200400 7200 0 EET}
+    {2500506000 10800 1 EEST}
+    {2519254800 7200 0 EET}
+    {2531955600 10800 1 EEST}
+    {2550704400 7200 0 EET}
+    {2563405200 10800 1 EEST}
+    {2582154000 7200 0 EET}
+    {2595459600 10800 1 EEST}
+    {2613603600 7200 0 EET}
+    {2626909200 10800 1 EEST}
+    {2645053200 7200 0 EET}
+    {2658358800 10800 1 EEST}
+    {2676502800 7200 0 EET}
+    {2689808400 10800 1 EEST}
+    {2708557200 7200 0 EET}
+    {2721258000 10800 1 EEST}
+    {2740006800 7200 0 EET}
+    {2752707600 10800 1 EEST}
+    {2771456400 7200 0 EET}
+    {2784762000 10800 1 EEST}
+    {2802906000 7200 0 EET}
+    {2816211600 10800 1 EEST}
+    {2834355600 7200 0 EET}
+    {2847661200 10800 1 EEST}
+    {2866410000 7200 0 EET}
+    {2879110800 10800 1 EEST}
+    {2897859600 7200 0 EET}
+    {2910560400 10800 1 EEST}
+    {2929309200 7200 0 EET}
+    {2942010000 10800 1 EEST}
+    {2960758800 7200 0 EET}
+    {2974064400 10800 1 EEST}
+    {2992208400 7200 0 EET}
+    {3005514000 10800 1 EEST}
+    {3023658000 7200 0 EET}
+    {3036963600 10800 1 EEST}
+    {3055712400 7200 0 EET}
+    {3068413200 10800 1 EEST}
+    {3087162000 7200 0 EET}
+    {3099862800 10800 1 EEST}
+    {3118611600 7200 0 EET}
+    {3131917200 10800 1 EEST}
+    {3150061200 7200 0 EET}
+    {3163366800 10800 1 EEST}
+    {3181510800 7200 0 EET}
+    {3194816400 10800 1 EEST}
+    {3212960400 7200 0 EET}
+    {3226266000 10800 1 EEST}
+    {3245014800 7200 0 EET}
+    {3257715600 10800 1 EEST}
+    {3276464400 7200 0 EET}
+    {3289165200 10800 1 EEST}
+    {3307914000 7200 0 EET}
+    {3321219600 10800 1 EEST}
+    {3339363600 7200 0 EET}
+    {3352669200 10800 1 EEST}
+    {3370813200 7200 0 EET}
+    {3384118800 10800 1 EEST}
+    {3402867600 7200 0 EET}
+    {3415568400 10800 1 EEST}
+    {3434317200 7200 0 EET}
+    {3447018000 10800 1 EEST}
+    {3465766800 7200 0 EET}
+    {3479072400 10800 1 EEST}
+    {3497216400 7200 0 EET}
+    {3510522000 10800 1 EEST}
+    {3528666000 7200 0 EET}
+    {3541971600 10800 1 EEST}
+    {3560115600 7200 0 EET}
+    {3573421200 10800 1 EEST}
+    {3592170000 7200 0 EET}
+    {3604870800 10800 1 EEST}
+    {3623619600 7200 0 EET}
+    {3636320400 10800 1 EEST}
+    {3655069200 7200 0 EET}
+    {3668374800 10800 1 EEST}
+    {3686518800 7200 0 EET}
+    {3699824400 10800 1 EEST}
+    {3717968400 7200 0 EET}
+    {3731274000 10800 1 EEST}
+    {3750022800 7200 0 EET}
+    {3762723600 10800 1 EEST}
+    {3781472400 7200 0 EET}
+    {3794173200 10800 1 EEST}
+    {3812922000 7200 0 EET}
+    {3825622800 10800 1 EEST}
+    {3844371600 7200 0 EET}
+    {3857677200 10800 1 EEST}
+    {3875821200 7200 0 EET}
+    {3889126800 10800 1 EEST}
+    {3907270800 7200 0 EET}
+    {3920576400 10800 1 EEST}
+    {3939325200 7200 0 EET}
+    {3952026000 10800 1 EEST}
+    {3970774800 7200 0 EET}
+    {3983475600 10800 1 EEST}
+    {4002224400 7200 0 EET}
+    {4015530000 10800 1 EEST}
+    {4033674000 7200 0 EET}
+    {4046979600 10800 1 EEST}
+    {4065123600 7200 0 EET}
+    {4078429200 10800 1 EEST}
+    {4096573200 7200 0 EET}
+}
diff --git a/library/tzdata/Europe/Stockholm b/library/tzdata/Europe/Stockholm
new file mode 100644
index 0000000..b74d327
--- /dev/null
+++ b/library/tzdata/Europe/Stockholm
@@ -0,0 +1,250 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Europe/Stockholm) {
+    {-9223372036854775808 4332 0 LMT}
+    {-2871681132 3614 0 SET}
+    {-2208992414 3600 0 CET}
+    {-1692496800 7200 1 CEST}
+    {-1680483600 3600 0 CET}
+    {315529200 3600 0 CET}
+    {323830800 7200 1 CEST}
+    {338950800 3600 0 CET}
+    {354675600 7200 1 CEST}
+    {370400400 3600 0 CET}
+    {386125200 7200 1 CEST}
+    {401850000 3600 0 CET}
+    {417574800 7200 1 CEST}
+    {433299600 3600 0 CET}
+    {449024400 7200 1 CEST}
+    {465354000 3600 0 CET}
+    {481078800 7200 1 CEST}
+    {496803600 3600 0 CET}
+    {512528400 7200 1 CEST}
+    {528253200 3600 0 CET}
+    {543978000 7200 1 CEST}
+    {559702800 3600 0 CET}
+    {575427600 7200 1 CEST}
+    {591152400 3600 0 CET}
+    {606877200 7200 1 CEST}
+    {622602000 3600 0 CET}
+    {638326800 7200 1 CEST}
+    {654656400 3600 0 CET}
+    {670381200 7200 1 CEST}
+    {686106000 3600 0 CET}
+    {701830800 7200 1 CEST}
+    {717555600 3600 0 CET}
+    {733280400 7200 1 CEST}
+    {749005200 3600 0 CET}
+    {764730000 7200 1 CEST}
+    {780454800 3600 0 CET}
+    {796179600 7200 1 CEST}
+    {811904400 3600 0 CET}
+    {828234000 7200 1 CEST}
+    {846378000 3600 0 CET}
+    {859683600 7200 1 CEST}
+    {877827600 3600 0 CET}
+    {891133200 7200 1 CEST}
+    {909277200 3600 0 CET}
+    {922582800 7200 1 CEST}
+    {941331600 3600 0 CET}
+    {954032400 7200 1 CEST}
+    {972781200 3600 0 CET}
+    {985482000 7200 1 CEST}
+    {1004230800 3600 0 CET}
+    {1017536400 7200 1 CEST}
+    {1035680400 3600 0 CET}
+    {1048986000 7200 1 CEST}
+    {1067130000 3600 0 CET}
+    {1080435600 7200 1 CEST}
+    {1099184400 3600 0 CET}
+    {1111885200 7200 1 CEST}
+    {1130634000 3600 0 CET}
+    {1143334800 7200 1 CEST}
+    {1162083600 3600 0 CET}
+    {1174784400 7200 1 CEST}
+    {1193533200 3600 0 CET}
+    {1206838800 7200 1 CEST}
+    {1224982800 3600 0 CET}
+    {1238288400 7200 1 CEST}
+    {1256432400 3600 0 CET}
+    {1269738000 7200 1 CEST}
+    {1288486800 3600 0 CET}
+    {1301187600 7200 1 CEST}
+    {1319936400 3600 0 CET}
+    {1332637200 7200 1 CEST}
+    {1351386000 3600 0 CET}
+    {1364691600 7200 1 CEST}
+    {1382835600 3600 0 CET}
+    {1396141200 7200 1 CEST}
+    {1414285200 3600 0 CET}
+    {1427590800 7200 1 CEST}
+    {1445734800 3600 0 CET}
+    {1459040400 7200 1 CEST}
+    {1477789200 3600 0 CET}
+    {1490490000 7200 1 CEST}
+    {1509238800 3600 0 CET}
+    {1521939600 7200 1 CEST}
+    {1540688400 3600 0 CET}
+    {1553994000 7200 1 CEST}
+    {1572138000 3600 0 CET}
+    {1585443600 7200 1 CEST}
+    {1603587600 3600 0 CET}
+    {1616893200 7200 1 CEST}
+    {1635642000 3600 0 CET}
+    {1648342800 7200 1 CEST}
+    {1667091600 3600 0 CET}
+    {1679792400 7200 1 CEST}
+    {1698541200 3600 0 CET}
+    {1711846800 7200 1 CEST}
+    {1729990800 3600 0 CET}
+    {1743296400 7200 1 CEST}
+    {1761440400 3600 0 CET}
+    {1774746000 7200 1 CEST}
+    {1792890000 3600 0 CET}
+    {1806195600 7200 1 CEST}
+    {1824944400 3600 0 CET}
+    {1837645200 7200 1 CEST}
+    {1856394000 3600 0 CET}
+    {1869094800 7200 1 CEST}
+    {1887843600 3600 0 CET}
+    {1901149200 7200 1 CEST}
+    {1919293200 3600 0 CET}
+    {1932598800 7200 1 CEST}
+    {1950742800 3600 0 CET}
+    {1964048400 7200 1 CEST}
+    {1982797200 3600 0 CET}
+    {1995498000 7200 1 CEST}
+    {2014246800 3600 0 CET}
+    {2026947600 7200 1 CEST}
+    {2045696400 3600 0 CET}
+    {2058397200 7200 1 CEST}
+    {2077146000 3600 0 CET}
+    {2090451600 7200 1 CEST}
+    {2108595600 3600 0 CET}
+    {2121901200 7200 1 CEST}
+    {2140045200 3600 0 CET}
+    {2153350800 7200 1 CEST}
+    {2172099600 3600 0 CET}
+    {2184800400 7200 1 CEST}
+    {2203549200 3600 0 CET}
+    {2216250000 7200 1 CEST}
+    {2234998800 3600 0 CET}
+    {2248304400 7200 1 CEST}
+    {2266448400 3600 0 CET}
+    {2279754000 7200 1 CEST}
+    {2297898000 3600 0 CET}
+    {2311203600 7200 1 CEST}
+    {2329347600 3600 0 CET}
+    {2342653200 7200 1 CEST}
+    {2361402000 3600 0 CET}
+    {2374102800 7200 1 CEST}
+    {2392851600 3600 0 CET}
+    {2405552400 7200 1 CEST}
+    {2424301200 3600 0 CET}
+    {2437606800 7200 1 CEST}
+    {2455750800 3600 0 CET}
+    {2469056400 7200 1 CEST}
+    {2487200400 3600 0 CET}
+    {2500506000 7200 1 CEST}
+    {2519254800 3600 0 CET}
+    {2531955600 7200 1 CEST}
+    {2550704400 3600 0 CET}
+    {2563405200 7200 1 CEST}
+    {2582154000 3600 0 CET}
+    {2595459600 7200 1 CEST}
+    {2613603600 3600 0 CET}
+    {2626909200 7200 1 CEST}
+    {2645053200 3600 0 CET}
+    {2658358800 7200 1 CEST}
+    {2676502800 3600 0 CET}
+    {2689808400 7200 1 CEST}
+    {2708557200 3600 0 CET}
+    {2721258000 7200 1 CEST}
+    {2740006800 3600 0 CET}
+    {2752707600 7200 1 CEST}
+    {2771456400 3600 0 CET}
+    {2784762000 7200 1 CEST}
+    {2802906000 3600 0 CET}
+    {2816211600 7200 1 CEST}
+    {2834355600 3600 0 CET}
+    {2847661200 7200 1 CEST}
+    {2866410000 3600 0 CET}
+    {2879110800 7200 1 CEST}
+    {2897859600 3600 0 CET}
+    {2910560400 7200 1 CEST}
+    {2929309200 3600 0 CET}
+    {2942010000 7200 1 CEST}
+    {2960758800 3600 0 CET}
+    {2974064400 7200 1 CEST}
+    {2992208400 3600 0 CET}
+    {3005514000 7200 1 CEST}
+    {3023658000 3600 0 CET}
+    {3036963600 7200 1 CEST}
+    {3055712400 3600 0 CET}
+    {3068413200 7200 1 CEST}
+    {3087162000 3600 0 CET}
+    {3099862800 7200 1 CEST}
+    {3118611600 3600 0 CET}
+    {3131917200 7200 1 CEST}
+    {3150061200 3600 0 CET}
+    {3163366800 7200 1 CEST}
+    {3181510800 3600 0 CET}
+    {3194816400 7200 1 CEST}
+    {3212960400 3600 0 CET}
+    {3226266000 7200 1 CEST}
+    {3245014800 3600 0 CET}
+    {3257715600 7200 1 CEST}
+    {3276464400 3600 0 CET}
+    {3289165200 7200 1 CEST}
+    {3307914000 3600 0 CET}
+    {3321219600 7200 1 CEST}
+    {3339363600 3600 0 CET}
+    {3352669200 7200 1 CEST}
+    {3370813200 3600 0 CET}
+    {3384118800 7200 1 CEST}
+    {3402867600 3600 0 CET}
+    {3415568400 7200 1 CEST}
+    {3434317200 3600 0 CET}
+    {3447018000 7200 1 CEST}
+    {3465766800 3600 0 CET}
+    {3479072400 7200 1 CEST}
+    {3497216400 3600 0 CET}
+    {3510522000 7200 1 CEST}
+    {3528666000 3600 0 CET}
+    {3541971600 7200 1 CEST}
+    {3560115600 3600 0 CET}
+    {3573421200 7200 1 CEST}
+    {3592170000 3600 0 CET}
+    {3604870800 7200 1 CEST}
+    {3623619600 3600 0 CET}
+    {3636320400 7200 1 CEST}
+    {3655069200 3600 0 CET}
+    {3668374800 7200 1 CEST}
+    {3686518800 3600 0 CET}
+    {3699824400 7200 1 CEST}
+    {3717968400 3600 0 CET}
+    {3731274000 7200 1 CEST}
+    {3750022800 3600 0 CET}
+    {3762723600 7200 1 CEST}
+    {3781472400 3600 0 CET}
+    {3794173200 7200 1 CEST}
+    {3812922000 3600 0 CET}
+    {3825622800 7200 1 CEST}
+    {3844371600 3600 0 CET}
+    {3857677200 7200 1 CEST}
+    {3875821200 3600 0 CET}
+    {3889126800 7200 1 CEST}
+    {3907270800 3600 0 CET}
+    {3920576400 7200 1 CEST}
+    {3939325200 3600 0 CET}
+    {3952026000 7200 1 CEST}
+    {3970774800 3600 0 CET}
+    {3983475600 7200 1 CEST}
+    {4002224400 3600 0 CET}
+    {4015530000 7200 1 CEST}
+    {4033674000 3600 0 CET}
+    {4046979600 7200 1 CEST}
+    {4065123600 3600 0 CET}
+    {4078429200 7200 1 CEST}
+    {4096573200 3600 0 CET}
+}
diff --git a/library/tzdata/Europe/Tallinn b/library/tzdata/Europe/Tallinn
new file mode 100644
index 0000000..e0f22a5
--- /dev/null
+++ b/library/tzdata/Europe/Tallinn
@@ -0,0 +1,254 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Europe/Tallinn) {
+    {-9223372036854775808 5940 0 LMT}
+    {-2840146740 5940 0 TMT}
+    {-1638322740 3600 0 CET}
+    {-1632006000 7200 1 CEST}
+    {-1618700400 3600 0 CET}
+    {-1593824400 5940 0 TMT}
+    {-1535938740 7200 0 EET}
+    {-927943200 10800 0 MSK}
+    {-892954800 3600 0 CET}
+    {-857257200 3600 0 CET}
+    {-844556400 7200 1 CEST}
+    {-828226800 3600 0 CET}
+    {-812502000 7200 1 CEST}
+    {-797648400 10800 0 MSD}
+    {354920400 14400 1 MSD}
+    {370728000 10800 0 MSK}
+    {386456400 14400 1 MSD}
+    {402264000 10800 0 MSK}
+    {417992400 14400 1 MSD}
+    {433800000 10800 0 MSK}
+    {449614800 14400 1 MSD}
+    {465346800 10800 0 MSK}
+    {481071600 14400 1 MSD}
+    {496796400 10800 0 MSK}
+    {512521200 14400 1 MSD}
+    {528246000 10800 0 MSK}
+    {543970800 14400 1 MSD}
+    {559695600 10800 0 MSK}
+    {575420400 14400 1 MSD}
+    {591145200 10800 0 MSK}
+    {606870000 10800 1 EEST}
+    {622598400 7200 0 EET}
+    {638323200 10800 1 EEST}
+    {654652800 7200 0 EET}
+    {670377600 10800 1 EEST}
+    {686102400 7200 0 EET}
+    {701827200 10800 1 EEST}
+    {717552000 7200 0 EET}
+    {733276800 10800 1 EEST}
+    {749001600 7200 0 EET}
+    {764726400 10800 1 EEST}
+    {780451200 7200 0 EET}
+    {796176000 10800 1 EEST}
+    {811900800 7200 0 EET}
+    {828230400 10800 1 EEST}
+    {846374400 7200 0 EET}
+    {859680000 10800 1 EEST}
+    {877824000 7200 0 EET}
+    {891129600 10800 1 EEST}
+    {906415200 10800 0 EEST}
+    {909277200 7200 0 EET}
+    {922582800 10800 1 EEST}
+    {941335200 7200 0 EET}
+    {1014242400 7200 0 EET}
+    {1017536400 10800 1 EEST}
+    {1035680400 7200 0 EET}
+    {1048986000 10800 1 EEST}
+    {1067130000 7200 0 EET}
+    {1080435600 10800 1 EEST}
+    {1099184400 7200 0 EET}
+    {1111885200 10800 1 EEST}
+    {1130634000 7200 0 EET}
+    {1143334800 10800 1 EEST}
+    {1162083600 7200 0 EET}
+    {1174784400 10800 1 EEST}
+    {1193533200 7200 0 EET}
+    {1206838800 10800 1 EEST}
+    {1224982800 7200 0 EET}
+    {1238288400 10800 1 EEST}
+    {1256432400 7200 0 EET}
+    {1269738000 10800 1 EEST}
+    {1288486800 7200 0 EET}
+    {1301187600 10800 1 EEST}
+    {1319936400 7200 0 EET}
+    {1332637200 10800 1 EEST}
+    {1351386000 7200 0 EET}
+    {1364691600 10800 1 EEST}
+    {1382835600 7200 0 EET}
+    {1396141200 10800 1 EEST}
+    {1414285200 7200 0 EET}
+    {1427590800 10800 1 EEST}
+    {1445734800 7200 0 EET}
+    {1459040400 10800 1 EEST}
+    {1477789200 7200 0 EET}
+    {1490490000 10800 1 EEST}
+    {1509238800 7200 0 EET}
+    {1521939600 10800 1 EEST}
+    {1540688400 7200 0 EET}
+    {1553994000 10800 1 EEST}
+    {1572138000 7200 0 EET}
+    {1585443600 10800 1 EEST}
+    {1603587600 7200 0 EET}
+    {1616893200 10800 1 EEST}
+    {1635642000 7200 0 EET}
+    {1648342800 10800 1 EEST}
+    {1667091600 7200 0 EET}
+    {1679792400 10800 1 EEST}
+    {1698541200 7200 0 EET}
+    {1711846800 10800 1 EEST}
+    {1729990800 7200 0 EET}
+    {1743296400 10800 1 EEST}
+    {1761440400 7200 0 EET}
+    {1774746000 10800 1 EEST}
+    {1792890000 7200 0 EET}
+    {1806195600 10800 1 EEST}
+    {1824944400 7200 0 EET}
+    {1837645200 10800 1 EEST}
+    {1856394000 7200 0 EET}
+    {1869094800 10800 1 EEST}
+    {1887843600 7200 0 EET}
+    {1901149200 10800 1 EEST}
+    {1919293200 7200 0 EET}
+    {1932598800 10800 1 EEST}
+    {1950742800 7200 0 EET}
+    {1964048400 10800 1 EEST}
+    {1982797200 7200 0 EET}
+    {1995498000 10800 1 EEST}
+    {2014246800 7200 0 EET}
+    {2026947600 10800 1 EEST}
+    {2045696400 7200 0 EET}
+    {2058397200 10800 1 EEST}
+    {2077146000 7200 0 EET}
+    {2090451600 10800 1 EEST}
+    {2108595600 7200 0 EET}
+    {2121901200 10800 1 EEST}
+    {2140045200 7200 0 EET}
+    {2153350800 10800 1 EEST}
+    {2172099600 7200 0 EET}
+    {2184800400 10800 1 EEST}
+    {2203549200 7200 0 EET}
+    {2216250000 10800 1 EEST}
+    {2234998800 7200 0 EET}
+    {2248304400 10800 1 EEST}
+    {2266448400 7200 0 EET}
+    {2279754000 10800 1 EEST}
+    {2297898000 7200 0 EET}
+    {2311203600 10800 1 EEST}
+    {2329347600 7200 0 EET}
+    {2342653200 10800 1 EEST}
+    {2361402000 7200 0 EET}
+    {2374102800 10800 1 EEST}
+    {2392851600 7200 0 EET}
+    {2405552400 10800 1 EEST}
+    {2424301200 7200 0 EET}
+    {2437606800 10800 1 EEST}
+    {2455750800 7200 0 EET}
+    {2469056400 10800 1 EEST}
+    {2487200400 7200 0 EET}
+    {2500506000 10800 1 EEST}
+    {2519254800 7200 0 EET}
+    {2531955600 10800 1 EEST}
+    {2550704400 7200 0 EET}
+    {2563405200 10800 1 EEST}
+    {2582154000 7200 0 EET}
+    {2595459600 10800 1 EEST}
+    {2613603600 7200 0 EET}
+    {2626909200 10800 1 EEST}
+    {2645053200 7200 0 EET}
+    {2658358800 10800 1 EEST}
+    {2676502800 7200 0 EET}
+    {2689808400 10800 1 EEST}
+    {2708557200 7200 0 EET}
+    {2721258000 10800 1 EEST}
+    {2740006800 7200 0 EET}
+    {2752707600 10800 1 EEST}
+    {2771456400 7200 0 EET}
+    {2784762000 10800 1 EEST}
+    {2802906000 7200 0 EET}
+    {2816211600 10800 1 EEST}
+    {2834355600 7200 0 EET}
+    {2847661200 10800 1 EEST}
+    {2866410000 7200 0 EET}
+    {2879110800 10800 1 EEST}
+    {2897859600 7200 0 EET}
+    {2910560400 10800 1 EEST}
+    {2929309200 7200 0 EET}
+    {2942010000 10800 1 EEST}
+    {2960758800 7200 0 EET}
+    {2974064400 10800 1 EEST}
+    {2992208400 7200 0 EET}
+    {3005514000 10800 1 EEST}
+    {3023658000 7200 0 EET}
+    {3036963600 10800 1 EEST}
+    {3055712400 7200 0 EET}
+    {3068413200 10800 1 EEST}
+    {3087162000 7200 0 EET}
+    {3099862800 10800 1 EEST}
+    {3118611600 7200 0 EET}
+    {3131917200 10800 1 EEST}
+    {3150061200 7200 0 EET}
+    {3163366800 10800 1 EEST}
+    {3181510800 7200 0 EET}
+    {3194816400 10800 1 EEST}
+    {3212960400 7200 0 EET}
+    {3226266000 10800 1 EEST}
+    {3245014800 7200 0 EET}
+    {3257715600 10800 1 EEST}
+    {3276464400 7200 0 EET}
+    {3289165200 10800 1 EEST}
+    {3307914000 7200 0 EET}
+    {3321219600 10800 1 EEST}
+    {3339363600 7200 0 EET}
+    {3352669200 10800 1 EEST}
+    {3370813200 7200 0 EET}
+    {3384118800 10800 1 EEST}
+    {3402867600 7200 0 EET}
+    {3415568400 10800 1 EEST}
+    {3434317200 7200 0 EET}
+    {3447018000 10800 1 EEST}
+    {3465766800 7200 0 EET}
+    {3479072400 10800 1 EEST}
+    {3497216400 7200 0 EET}
+    {3510522000 10800 1 EEST}
+    {3528666000 7200 0 EET}
+    {3541971600 10800 1 EEST}
+    {3560115600 7200 0 EET}
+    {3573421200 10800 1 EEST}
+    {3592170000 7200 0 EET}
+    {3604870800 10800 1 EEST}
+    {3623619600 7200 0 EET}
+    {3636320400 10800 1 EEST}
+    {3655069200 7200 0 EET}
+    {3668374800 10800 1 EEST}
+    {3686518800 7200 0 EET}
+    {3699824400 10800 1 EEST}
+    {3717968400 7200 0 EET}
+    {3731274000 10800 1 EEST}
+    {3750022800 7200 0 EET}
+    {3762723600 10800 1 EEST}
+    {3781472400 7200 0 EET}
+    {3794173200 10800 1 EEST}
+    {3812922000 7200 0 EET}
+    {3825622800 10800 1 EEST}
+    {3844371600 7200 0 EET}
+    {3857677200 10800 1 EEST}
+    {3875821200 7200 0 EET}
+    {3889126800 10800 1 EEST}
+    {3907270800 7200 0 EET}
+    {3920576400 10800 1 EEST}
+    {3939325200 7200 0 EET}
+    {3952026000 10800 1 EEST}
+    {3970774800 7200 0 EET}
+    {3983475600 10800 1 EEST}
+    {4002224400 7200 0 EET}
+    {4015530000 10800 1 EEST}
+    {4033674000 7200 0 EET}
+    {4046979600 10800 1 EEST}
+    {4065123600 7200 0 EET}
+    {4078429200 10800 1 EEST}
+    {4096573200 7200 0 EET}
+}
diff --git a/library/tzdata/Europe/Tirane b/library/tzdata/Europe/Tirane
new file mode 100644
index 0000000..14ace2e
--- /dev/null
+++ b/library/tzdata/Europe/Tirane
@@ -0,0 +1,263 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Europe/Tirane) {
+    {-9223372036854775808 4760 0 LMT}
+    {-1767230360 3600 0 CET}
+    {-932346000 7200 0 CEST}
+    {-857257200 3600 0 CET}
+    {-844556400 7200 1 CEST}
+    {-843519600 3600 0 CET}
+    {136854000 7200 1 CEST}
+    {149896800 3600 0 CET}
+    {168130800 7200 1 CEST}
+    {181432800 3600 0 CET}
+    {199839600 7200 1 CEST}
+    {213141600 3600 0 CET}
+    {231894000 7200 1 CEST}
+    {244591200 3600 0 CET}
+    {263257200 7200 1 CEST}
+    {276040800 3600 0 CET}
+    {294706800 7200 1 CEST}
+    {307490400 3600 0 CET}
+    {326156400 7200 1 CEST}
+    {339458400 3600 0 CET}
+    {357087600 7200 1 CEST}
+    {370389600 3600 0 CET}
+    {389142000 7200 1 CEST}
+    {402444000 3600 0 CET}
+    {419468400 7200 1 CEST}
+    {433807200 3600 0 CET}
+    {449622000 7200 1 CEST}
+    {457480800 7200 0 CEST}
+    {465354000 3600 0 CET}
+    {481078800 7200 1 CEST}
+    {496803600 3600 0 CET}
+    {512528400 7200 1 CEST}
+    {528253200 3600 0 CET}
+    {543978000 7200 1 CEST}
+    {559702800 3600 0 CET}
+    {575427600 7200 1 CEST}
+    {591152400 3600 0 CET}
+    {606877200 7200 1 CEST}
+    {622602000 3600 0 CET}
+    {638326800 7200 1 CEST}
+    {654656400 3600 0 CET}
+    {670381200 7200 1 CEST}
+    {686106000 3600 0 CET}
+    {701830800 7200 1 CEST}
+    {717555600 3600 0 CET}
+    {733280400 7200 1 CEST}
+    {749005200 3600 0 CET}
+    {764730000 7200 1 CEST}
+    {780454800 3600 0 CET}
+    {796179600 7200 1 CEST}
+    {811904400 3600 0 CET}
+    {828234000 7200 1 CEST}
+    {846378000 3600 0 CET}
+    {859683600 7200 1 CEST}
+    {877827600 3600 0 CET}
+    {891133200 7200 1 CEST}
+    {909277200 3600 0 CET}
+    {922582800 7200 1 CEST}
+    {941331600 3600 0 CET}
+    {954032400 7200 1 CEST}
+    {972781200 3600 0 CET}
+    {985482000 7200 1 CEST}
+    {1004230800 3600 0 CET}
+    {1017536400 7200 1 CEST}
+    {1035680400 3600 0 CET}
+    {1048986000 7200 1 CEST}
+    {1067130000 3600 0 CET}
+    {1080435600 7200 1 CEST}
+    {1099184400 3600 0 CET}
+    {1111885200 7200 1 CEST}
+    {1130634000 3600 0 CET}
+    {1143334800 7200 1 CEST}
+    {1162083600 3600 0 CET}
+    {1174784400 7200 1 CEST}
+    {1193533200 3600 0 CET}
+    {1206838800 7200 1 CEST}
+    {1224982800 3600 0 CET}
+    {1238288400 7200 1 CEST}
+    {1256432400 3600 0 CET}
+    {1269738000 7200 1 CEST}
+    {1288486800 3600 0 CET}
+    {1301187600 7200 1 CEST}
+    {1319936400 3600 0 CET}
+    {1332637200 7200 1 CEST}
+    {1351386000 3600 0 CET}
+    {1364691600 7200 1 CEST}
+    {1382835600 3600 0 CET}
+    {1396141200 7200 1 CEST}
+    {1414285200 3600 0 CET}
+    {1427590800 7200 1 CEST}
+    {1445734800 3600 0 CET}
+    {1459040400 7200 1 CEST}
+    {1477789200 3600 0 CET}
+    {1490490000 7200 1 CEST}
+    {1509238800 3600 0 CET}
+    {1521939600 7200 1 CEST}
+    {1540688400 3600 0 CET}
+    {1553994000 7200 1 CEST}
+    {1572138000 3600 0 CET}
+    {1585443600 7200 1 CEST}
+    {1603587600 3600 0 CET}
+    {1616893200 7200 1 CEST}
+    {1635642000 3600 0 CET}
+    {1648342800 7200 1 CEST}
+    {1667091600 3600 0 CET}
+    {1679792400 7200 1 CEST}
+    {1698541200 3600 0 CET}
+    {1711846800 7200 1 CEST}
+    {1729990800 3600 0 CET}
+    {1743296400 7200 1 CEST}
+    {1761440400 3600 0 CET}
+    {1774746000 7200 1 CEST}
+    {1792890000 3600 0 CET}
+    {1806195600 7200 1 CEST}
+    {1824944400 3600 0 CET}
+    {1837645200 7200 1 CEST}
+    {1856394000 3600 0 CET}
+    {1869094800 7200 1 CEST}
+    {1887843600 3600 0 CET}
+    {1901149200 7200 1 CEST}
+    {1919293200 3600 0 CET}
+    {1932598800 7200 1 CEST}
+    {1950742800 3600 0 CET}
+    {1964048400 7200 1 CEST}
+    {1982797200 3600 0 CET}
+    {1995498000 7200 1 CEST}
+    {2014246800 3600 0 CET}
+    {2026947600 7200 1 CEST}
+    {2045696400 3600 0 CET}
+    {2058397200 7200 1 CEST}
+    {2077146000 3600 0 CET}
+    {2090451600 7200 1 CEST}
+    {2108595600 3600 0 CET}
+    {2121901200 7200 1 CEST}
+    {2140045200 3600 0 CET}
+    {2153350800 7200 1 CEST}
+    {2172099600 3600 0 CET}
+    {2184800400 7200 1 CEST}
+    {2203549200 3600 0 CET}
+    {2216250000 7200 1 CEST}
+    {2234998800 3600 0 CET}
+    {2248304400 7200 1 CEST}
+    {2266448400 3600 0 CET}
+    {2279754000 7200 1 CEST}
+    {2297898000 3600 0 CET}
+    {2311203600 7200 1 CEST}
+    {2329347600 3600 0 CET}
+    {2342653200 7200 1 CEST}
+    {2361402000 3600 0 CET}
+    {2374102800 7200 1 CEST}
+    {2392851600 3600 0 CET}
+    {2405552400 7200 1 CEST}
+    {2424301200 3600 0 CET}
+    {2437606800 7200 1 CEST}
+    {2455750800 3600 0 CET}
+    {2469056400 7200 1 CEST}
+    {2487200400 3600 0 CET}
+    {2500506000 7200 1 CEST}
+    {2519254800 3600 0 CET}
+    {2531955600 7200 1 CEST}
+    {2550704400 3600 0 CET}
+    {2563405200 7200 1 CEST}
+    {2582154000 3600 0 CET}
+    {2595459600 7200 1 CEST}
+    {2613603600 3600 0 CET}
+    {2626909200 7200 1 CEST}
+    {2645053200 3600 0 CET}
+    {2658358800 7200 1 CEST}
+    {2676502800 3600 0 CET}
+    {2689808400 7200 1 CEST}
+    {2708557200 3600 0 CET}
+    {2721258000 7200 1 CEST}
+    {2740006800 3600 0 CET}
+    {2752707600 7200 1 CEST}
+    {2771456400 3600 0 CET}
+    {2784762000 7200 1 CEST}
+    {2802906000 3600 0 CET}
+    {2816211600 7200 1 CEST}
+    {2834355600 3600 0 CET}
+    {2847661200 7200 1 CEST}
+    {2866410000 3600 0 CET}
+    {2879110800 7200 1 CEST}
+    {2897859600 3600 0 CET}
+    {2910560400 7200 1 CEST}
+    {2929309200 3600 0 CET}
+    {2942010000 7200 1 CEST}
+    {2960758800 3600 0 CET}
+    {2974064400 7200 1 CEST}
+    {2992208400 3600 0 CET}
+    {3005514000 7200 1 CEST}
+    {3023658000 3600 0 CET}
+    {3036963600 7200 1 CEST}
+    {3055712400 3600 0 CET}
+    {3068413200 7200 1 CEST}
+    {3087162000 3600 0 CET}
+    {3099862800 7200 1 CEST}
+    {3118611600 3600 0 CET}
+    {3131917200 7200 1 CEST}
+    {3150061200 3600 0 CET}
+    {3163366800 7200 1 CEST}
+    {3181510800 3600 0 CET}
+    {3194816400 7200 1 CEST}
+    {3212960400 3600 0 CET}
+    {3226266000 7200 1 CEST}
+    {3245014800 3600 0 CET}
+    {3257715600 7200 1 CEST}
+    {3276464400 3600 0 CET}
+    {3289165200 7200 1 CEST}
+    {3307914000 3600 0 CET}
+    {3321219600 7200 1 CEST}
+    {3339363600 3600 0 CET}
+    {3352669200 7200 1 CEST}
+    {3370813200 3600 0 CET}
+    {3384118800 7200 1 CEST}
+    {3402867600 3600 0 CET}
+    {3415568400 7200 1 CEST}
+    {3434317200 3600 0 CET}
+    {3447018000 7200 1 CEST}
+    {3465766800 3600 0 CET}
+    {3479072400 7200 1 CEST}
+    {3497216400 3600 0 CET}
+    {3510522000 7200 1 CEST}
+    {3528666000 3600 0 CET}
+    {3541971600 7200 1 CEST}
+    {3560115600 3600 0 CET}
+    {3573421200 7200 1 CEST}
+    {3592170000 3600 0 CET}
+    {3604870800 7200 1 CEST}
+    {3623619600 3600 0 CET}
+    {3636320400 7200 1 CEST}
+    {3655069200 3600 0 CET}
+    {3668374800 7200 1 CEST}
+    {3686518800 3600 0 CET}
+    {3699824400 7200 1 CEST}
+    {3717968400 3600 0 CET}
+    {3731274000 7200 1 CEST}
+    {3750022800 3600 0 CET}
+    {3762723600 7200 1 CEST}
+    {3781472400 3600 0 CET}
+    {3794173200 7200 1 CEST}
+    {3812922000 3600 0 CET}
+    {3825622800 7200 1 CEST}
+    {3844371600 3600 0 CET}
+    {3857677200 7200 1 CEST}
+    {3875821200 3600 0 CET}
+    {3889126800 7200 1 CEST}
+    {3907270800 3600 0 CET}
+    {3920576400 7200 1 CEST}
+    {3939325200 3600 0 CET}
+    {3952026000 7200 1 CEST}
+    {3970774800 3600 0 CET}
+    {3983475600 7200 1 CEST}
+    {4002224400 3600 0 CET}
+    {4015530000 7200 1 CEST}
+    {4033674000 3600 0 CET}
+    {4046979600 7200 1 CEST}
+    {4065123600 3600 0 CET}
+    {4078429200 7200 1 CEST}
+    {4096573200 3600 0 CET}
+}
diff --git a/library/tzdata/Europe/Tiraspol b/library/tzdata/Europe/Tiraspol
new file mode 100644
index 0000000..ea8f671
--- /dev/null
+++ b/library/tzdata/Europe/Tiraspol
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Europe/Chisinau)]} {
+    LoadTimeZoneFile Europe/Chisinau
+}
+set TZData(:Europe/Tiraspol) $TZData(:Europe/Chisinau)
diff --git a/library/tzdata/Europe/Ulyanovsk b/library/tzdata/Europe/Ulyanovsk
new file mode 100644
index 0000000..d5c33b5
--- /dev/null
+++ b/library/tzdata/Europe/Ulyanovsk
@@ -0,0 +1,73 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Europe/Ulyanovsk) {
+    {-9223372036854775808 11616 0 LMT}
+    {-1593825216 10800 0 +03}
+    {-1247540400 14400 0 +05}
+    {354916800 18000 1 +05}
+    {370724400 14400 0 +04}
+    {386452800 18000 1 +05}
+    {402260400 14400 0 +04}
+    {417988800 18000 1 +05}
+    {433796400 14400 0 +04}
+    {449611200 18000 1 +05}
+    {465343200 14400 0 +04}
+    {481068000 18000 1 +05}
+    {496792800 14400 0 +04}
+    {512517600 18000 1 +05}
+    {528242400 14400 0 +04}
+    {543967200 18000 1 +05}
+    {559692000 14400 0 +04}
+    {575416800 18000 1 +05}
+    {591141600 14400 0 +04}
+    {606866400 10800 0 +04}
+    {606870000 14400 1 +04}
+    {622594800 10800 0 +03}
+    {638319600 14400 1 +04}
+    {654649200 10800 0 +03}
+    {670374000 7200 0 +03}
+    {670377600 10800 1 +03}
+    {686102400 7200 0 +02}
+    {695779200 10800 0 +04}
+    {701823600 14400 1 +04}
+    {717548400 10800 0 +03}
+    {733273200 14400 1 +04}
+    {748998000 10800 0 +03}
+    {764722800 14400 1 +04}
+    {780447600 10800 0 +03}
+    {796172400 14400 1 +04}
+    {811897200 10800 0 +03}
+    {828226800 14400 1 +04}
+    {846370800 10800 0 +03}
+    {859676400 14400 1 +04}
+    {877820400 10800 0 +03}
+    {891126000 14400 1 +04}
+    {909270000 10800 0 +03}
+    {922575600 14400 1 +04}
+    {941324400 10800 0 +03}
+    {954025200 14400 1 +04}
+    {972774000 10800 0 +03}
+    {985474800 14400 1 +04}
+    {1004223600 10800 0 +03}
+    {1017529200 14400 1 +04}
+    {1035673200 10800 0 +03}
+    {1048978800 14400 1 +04}
+    {1067122800 10800 0 +03}
+    {1080428400 14400 1 +04}
+    {1099177200 10800 0 +03}
+    {1111878000 14400 1 +04}
+    {1130626800 10800 0 +03}
+    {1143327600 14400 1 +04}
+    {1162076400 10800 0 +03}
+    {1174777200 14400 1 +04}
+    {1193526000 10800 0 +03}
+    {1206831600 14400 1 +04}
+    {1224975600 10800 0 +03}
+    {1238281200 14400 1 +04}
+    {1256425200 10800 0 +03}
+    {1269730800 14400 1 +04}
+    {1288479600 10800 0 +03}
+    {1301180400 14400 0 +04}
+    {1414274400 10800 0 +03}
+    {1459033200 14400 0 +04}
+}
diff --git a/library/tzdata/Europe/Uzhgorod b/library/tzdata/Europe/Uzhgorod
new file mode 100644
index 0000000..f6e580b
--- /dev/null
+++ b/library/tzdata/Europe/Uzhgorod
@@ -0,0 +1,254 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Europe/Uzhgorod) {
+    {-9223372036854775808 5352 0 LMT}
+    {-2500939752 3600 0 CET}
+    {-946774800 3600 0 CET}
+    {-938905200 7200 1 CEST}
+    {-857257200 3600 0 CET}
+    {-844556400 7200 1 CEST}
+    {-828226800 3600 0 CET}
+    {-812502000 7200 1 CEST}
+    {-796870800 7200 1 CEST}
+    {-794714400 3600 0 CET}
+    {-773456400 10800 0 MSD}
+    {354920400 14400 1 MSD}
+    {370728000 10800 0 MSK}
+    {386456400 14400 1 MSD}
+    {402264000 10800 0 MSK}
+    {417992400 14400 1 MSD}
+    {433800000 10800 0 MSK}
+    {449614800 14400 1 MSD}
+    {465346800 10800 0 MSK}
+    {481071600 14400 1 MSD}
+    {496796400 10800 0 MSK}
+    {512521200 14400 1 MSD}
+    {528246000 10800 0 MSK}
+    {543970800 14400 1 MSD}
+    {559695600 10800 0 MSK}
+    {575420400 14400 1 MSD}
+    {591145200 10800 0 MSK}
+    {606870000 14400 1 MSD}
+    {622594800 10800 0 MSK}
+    {631141200 10800 0 MSK}
+    {646786800 3600 0 CET}
+    {670384800 7200 0 EET}
+    {694216800 7200 0 EET}
+    {701820000 10800 1 EEST}
+    {717541200 7200 0 EET}
+    {733269600 10800 1 EEST}
+    {748990800 7200 0 EET}
+    {764719200 10800 1 EEST}
+    {780440400 7200 0 EET}
+    {788911200 7200 0 EET}
+    {796179600 10800 1 EEST}
+    {811904400 7200 0 EET}
+    {828234000 10800 1 EEST}
+    {846378000 7200 0 EET}
+    {859683600 10800 1 EEST}
+    {877827600 7200 0 EET}
+    {891133200 10800 1 EEST}
+    {909277200 7200 0 EET}
+    {922582800 10800 1 EEST}
+    {941331600 7200 0 EET}
+    {954032400 10800 1 EEST}
+    {972781200 7200 0 EET}
+    {985482000 10800 1 EEST}
+    {1004230800 7200 0 EET}
+    {1017536400 10800 1 EEST}
+    {1035680400 7200 0 EET}
+    {1048986000 10800 1 EEST}
+    {1067130000 7200 0 EET}
+    {1080435600 10800 1 EEST}
+    {1099184400 7200 0 EET}
+    {1111885200 10800 1 EEST}
+    {1130634000 7200 0 EET}
+    {1143334800 10800 1 EEST}
+    {1162083600 7200 0 EET}
+    {1174784400 10800 1 EEST}
+    {1193533200 7200 0 EET}
+    {1206838800 10800 1 EEST}
+    {1224982800 7200 0 EET}
+    {1238288400 10800 1 EEST}
+    {1256432400 7200 0 EET}
+    {1269738000 10800 1 EEST}
+    {1288486800 7200 0 EET}
+    {1301187600 10800 1 EEST}
+    {1319936400 7200 0 EET}
+    {1332637200 10800 1 EEST}
+    {1351386000 7200 0 EET}
+    {1364691600 10800 1 EEST}
+    {1382835600 7200 0 EET}
+    {1396141200 10800 1 EEST}
+    {1414285200 7200 0 EET}
+    {1427590800 10800 1 EEST}
+    {1445734800 7200 0 EET}
+    {1459040400 10800 1 EEST}
+    {1477789200 7200 0 EET}
+    {1490490000 10800 1 EEST}
+    {1509238800 7200 0 EET}
+    {1521939600 10800 1 EEST}
+    {1540688400 7200 0 EET}
+    {1553994000 10800 1 EEST}
+    {1572138000 7200 0 EET}
+    {1585443600 10800 1 EEST}
+    {1603587600 7200 0 EET}
+    {1616893200 10800 1 EEST}
+    {1635642000 7200 0 EET}
+    {1648342800 10800 1 EEST}
+    {1667091600 7200 0 EET}
+    {1679792400 10800 1 EEST}
+    {1698541200 7200 0 EET}
+    {1711846800 10800 1 EEST}
+    {1729990800 7200 0 EET}
+    {1743296400 10800 1 EEST}
+    {1761440400 7200 0 EET}
+    {1774746000 10800 1 EEST}
+    {1792890000 7200 0 EET}
+    {1806195600 10800 1 EEST}
+    {1824944400 7200 0 EET}
+    {1837645200 10800 1 EEST}
+    {1856394000 7200 0 EET}
+    {1869094800 10800 1 EEST}
+    {1887843600 7200 0 EET}
+    {1901149200 10800 1 EEST}
+    {1919293200 7200 0 EET}
+    {1932598800 10800 1 EEST}
+    {1950742800 7200 0 EET}
+    {1964048400 10800 1 EEST}
+    {1982797200 7200 0 EET}
+    {1995498000 10800 1 EEST}
+    {2014246800 7200 0 EET}
+    {2026947600 10800 1 EEST}
+    {2045696400 7200 0 EET}
+    {2058397200 10800 1 EEST}
+    {2077146000 7200 0 EET}
+    {2090451600 10800 1 EEST}
+    {2108595600 7200 0 EET}
+    {2121901200 10800 1 EEST}
+    {2140045200 7200 0 EET}
+    {2153350800 10800 1 EEST}
+    {2172099600 7200 0 EET}
+    {2184800400 10800 1 EEST}
+    {2203549200 7200 0 EET}
+    {2216250000 10800 1 EEST}
+    {2234998800 7200 0 EET}
+    {2248304400 10800 1 EEST}
+    {2266448400 7200 0 EET}
+    {2279754000 10800 1 EEST}
+    {2297898000 7200 0 EET}
+    {2311203600 10800 1 EEST}
+    {2329347600 7200 0 EET}
+    {2342653200 10800 1 EEST}
+    {2361402000 7200 0 EET}
+    {2374102800 10800 1 EEST}
+    {2392851600 7200 0 EET}
+    {2405552400 10800 1 EEST}
+    {2424301200 7200 0 EET}
+    {2437606800 10800 1 EEST}
+    {2455750800 7200 0 EET}
+    {2469056400 10800 1 EEST}
+    {2487200400 7200 0 EET}
+    {2500506000 10800 1 EEST}
+    {2519254800 7200 0 EET}
+    {2531955600 10800 1 EEST}
+    {2550704400 7200 0 EET}
+    {2563405200 10800 1 EEST}
+    {2582154000 7200 0 EET}
+    {2595459600 10800 1 EEST}
+    {2613603600 7200 0 EET}
+    {2626909200 10800 1 EEST}
+    {2645053200 7200 0 EET}
+    {2658358800 10800 1 EEST}
+    {2676502800 7200 0 EET}
+    {2689808400 10800 1 EEST}
+    {2708557200 7200 0 EET}
+    {2721258000 10800 1 EEST}
+    {2740006800 7200 0 EET}
+    {2752707600 10800 1 EEST}
+    {2771456400 7200 0 EET}
+    {2784762000 10800 1 EEST}
+    {2802906000 7200 0 EET}
+    {2816211600 10800 1 EEST}
+    {2834355600 7200 0 EET}
+    {2847661200 10800 1 EEST}
+    {2866410000 7200 0 EET}
+    {2879110800 10800 1 EEST}
+    {2897859600 7200 0 EET}
+    {2910560400 10800 1 EEST}
+    {2929309200 7200 0 EET}
+    {2942010000 10800 1 EEST}
+    {2960758800 7200 0 EET}
+    {2974064400 10800 1 EEST}
+    {2992208400 7200 0 EET}
+    {3005514000 10800 1 EEST}
+    {3023658000 7200 0 EET}
+    {3036963600 10800 1 EEST}
+    {3055712400 7200 0 EET}
+    {3068413200 10800 1 EEST}
+    {3087162000 7200 0 EET}
+    {3099862800 10800 1 EEST}
+    {3118611600 7200 0 EET}
+    {3131917200 10800 1 EEST}
+    {3150061200 7200 0 EET}
+    {3163366800 10800 1 EEST}
+    {3181510800 7200 0 EET}
+    {3194816400 10800 1 EEST}
+    {3212960400 7200 0 EET}
+    {3226266000 10800 1 EEST}
+    {3245014800 7200 0 EET}
+    {3257715600 10800 1 EEST}
+    {3276464400 7200 0 EET}
+    {3289165200 10800 1 EEST}
+    {3307914000 7200 0 EET}
+    {3321219600 10800 1 EEST}
+    {3339363600 7200 0 EET}
+    {3352669200 10800 1 EEST}
+    {3370813200 7200 0 EET}
+    {3384118800 10800 1 EEST}
+    {3402867600 7200 0 EET}
+    {3415568400 10800 1 EEST}
+    {3434317200 7200 0 EET}
+    {3447018000 10800 1 EEST}
+    {3465766800 7200 0 EET}
+    {3479072400 10800 1 EEST}
+    {3497216400 7200 0 EET}
+    {3510522000 10800 1 EEST}
+    {3528666000 7200 0 EET}
+    {3541971600 10800 1 EEST}
+    {3560115600 7200 0 EET}
+    {3573421200 10800 1 EEST}
+    {3592170000 7200 0 EET}
+    {3604870800 10800 1 EEST}
+    {3623619600 7200 0 EET}
+    {3636320400 10800 1 EEST}
+    {3655069200 7200 0 EET}
+    {3668374800 10800 1 EEST}
+    {3686518800 7200 0 EET}
+    {3699824400 10800 1 EEST}
+    {3717968400 7200 0 EET}
+    {3731274000 10800 1 EEST}
+    {3750022800 7200 0 EET}
+    {3762723600 10800 1 EEST}
+    {3781472400 7200 0 EET}
+    {3794173200 10800 1 EEST}
+    {3812922000 7200 0 EET}
+    {3825622800 10800 1 EEST}
+    {3844371600 7200 0 EET}
+    {3857677200 10800 1 EEST}
+    {3875821200 7200 0 EET}
+    {3889126800 10800 1 EEST}
+    {3907270800 7200 0 EET}
+    {3920576400 10800 1 EEST}
+    {3939325200 7200 0 EET}
+    {3952026000 10800 1 EEST}
+    {3970774800 7200 0 EET}
+    {3983475600 10800 1 EEST}
+    {4002224400 7200 0 EET}
+    {4015530000 10800 1 EEST}
+    {4033674000 7200 0 EET}
+    {4046979600 10800 1 EEST}
+    {4065123600 7200 0 EET}
+    {4078429200 10800 1 EEST}
+    {4096573200 7200 0 EET}
+}
diff --git a/library/tzdata/Europe/Vaduz b/library/tzdata/Europe/Vaduz
new file mode 100644
index 0000000..095e018
--- /dev/null
+++ b/library/tzdata/Europe/Vaduz
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Europe/Zurich)]} {
+    LoadTimeZoneFile Europe/Zurich
+}
+set TZData(:Europe/Vaduz) $TZData(:Europe/Zurich)
diff --git a/library/tzdata/Europe/Vatican b/library/tzdata/Europe/Vatican
new file mode 100644
index 0000000..fe50765
--- /dev/null
+++ b/library/tzdata/Europe/Vatican
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Europe/Rome)]} {
+    LoadTimeZoneFile Europe/Rome
+}
+set TZData(:Europe/Vatican) $TZData(:Europe/Rome)
diff --git a/library/tzdata/Europe/Vienna b/library/tzdata/Europe/Vienna
new file mode 100644
index 0000000..95283eb
--- /dev/null
+++ b/library/tzdata/Europe/Vienna
@@ -0,0 +1,271 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Europe/Vienna) {
+    {-9223372036854775808 3921 0 LMT}
+    {-2422055121 3600 0 CET}
+    {-1693706400 7200 1 CEST}
+    {-1680483600 3600 0 CET}
+    {-1663455600 7200 1 CEST}
+    {-1650150000 3600 0 CET}
+    {-1632006000 7200 1 CEST}
+    {-1618700400 3600 0 CET}
+    {-1577926800 3600 0 CET}
+    {-1569711600 7200 1 CEST}
+    {-1555801200 3600 0 CET}
+    {-938905200 7200 0 CEST}
+    {-857257200 3600 0 CET}
+    {-844556400 7200 1 CEST}
+    {-828226800 3600 0 CET}
+    {-812502000 7200 1 CEST}
+    {-796777200 3600 0 CET}
+    {-781052400 7200 1 CEST}
+    {-780188400 3600 0 CET}
+    {-757386000 3600 0 CET}
+    {-748479600 7200 1 CEST}
+    {-733359600 3600 0 CET}
+    {-717634800 7200 1 CEST}
+    {-701910000 3600 0 CET}
+    {-684975600 7200 1 CEST}
+    {-670460400 3600 0 CET}
+    {323823600 7200 1 CEST}
+    {338940000 3600 0 CET}
+    {347151600 3600 0 CET}
+    {354675600 7200 1 CEST}
+    {370400400 3600 0 CET}
+    {386125200 7200 1 CEST}
+    {401850000 3600 0 CET}
+    {417574800 7200 1 CEST}
+    {433299600 3600 0 CET}
+    {449024400 7200 1 CEST}
+    {465354000 3600 0 CET}
+    {481078800 7200 1 CEST}
+    {496803600 3600 0 CET}
+    {512528400 7200 1 CEST}
+    {528253200 3600 0 CET}
+    {543978000 7200 1 CEST}
+    {559702800 3600 0 CET}
+    {575427600 7200 1 CEST}
+    {591152400 3600 0 CET}
+    {606877200 7200 1 CEST}
+    {622602000 3600 0 CET}
+    {638326800 7200 1 CEST}
+    {654656400 3600 0 CET}
+    {670381200 7200 1 CEST}
+    {686106000 3600 0 CET}
+    {701830800 7200 1 CEST}
+    {717555600 3600 0 CET}
+    {733280400 7200 1 CEST}
+    {749005200 3600 0 CET}
+    {764730000 7200 1 CEST}
+    {780454800 3600 0 CET}
+    {796179600 7200 1 CEST}
+    {811904400 3600 0 CET}
+    {828234000 7200 1 CEST}
+    {846378000 3600 0 CET}
+    {859683600 7200 1 CEST}
+    {877827600 3600 0 CET}
+    {891133200 7200 1 CEST}
+    {909277200 3600 0 CET}
+    {922582800 7200 1 CEST}
+    {941331600 3600 0 CET}
+    {954032400 7200 1 CEST}
+    {972781200 3600 0 CET}
+    {985482000 7200 1 CEST}
+    {1004230800 3600 0 CET}
+    {1017536400 7200 1 CEST}
+    {1035680400 3600 0 CET}
+    {1048986000 7200 1 CEST}
+    {1067130000 3600 0 CET}
+    {1080435600 7200 1 CEST}
+    {1099184400 3600 0 CET}
+    {1111885200 7200 1 CEST}
+    {1130634000 3600 0 CET}
+    {1143334800 7200 1 CEST}
+    {1162083600 3600 0 CET}
+    {1174784400 7200 1 CEST}
+    {1193533200 3600 0 CET}
+    {1206838800 7200 1 CEST}
+    {1224982800 3600 0 CET}
+    {1238288400 7200 1 CEST}
+    {1256432400 3600 0 CET}
+    {1269738000 7200 1 CEST}
+    {1288486800 3600 0 CET}
+    {1301187600 7200 1 CEST}
+    {1319936400 3600 0 CET}
+    {1332637200 7200 1 CEST}
+    {1351386000 3600 0 CET}
+    {1364691600 7200 1 CEST}
+    {1382835600 3600 0 CET}
+    {1396141200 7200 1 CEST}
+    {1414285200 3600 0 CET}
+    {1427590800 7200 1 CEST}
+    {1445734800 3600 0 CET}
+    {1459040400 7200 1 CEST}
+    {1477789200 3600 0 CET}
+    {1490490000 7200 1 CEST}
+    {1509238800 3600 0 CET}
+    {1521939600 7200 1 CEST}
+    {1540688400 3600 0 CET}
+    {1553994000 7200 1 CEST}
+    {1572138000 3600 0 CET}
+    {1585443600 7200 1 CEST}
+    {1603587600 3600 0 CET}
+    {1616893200 7200 1 CEST}
+    {1635642000 3600 0 CET}
+    {1648342800 7200 1 CEST}
+    {1667091600 3600 0 CET}
+    {1679792400 7200 1 CEST}
+    {1698541200 3600 0 CET}
+    {1711846800 7200 1 CEST}
+    {1729990800 3600 0 CET}
+    {1743296400 7200 1 CEST}
+    {1761440400 3600 0 CET}
+    {1774746000 7200 1 CEST}
+    {1792890000 3600 0 CET}
+    {1806195600 7200 1 CEST}
+    {1824944400 3600 0 CET}
+    {1837645200 7200 1 CEST}
+    {1856394000 3600 0 CET}
+    {1869094800 7200 1 CEST}
+    {1887843600 3600 0 CET}
+    {1901149200 7200 1 CEST}
+    {1919293200 3600 0 CET}
+    {1932598800 7200 1 CEST}
+    {1950742800 3600 0 CET}
+    {1964048400 7200 1 CEST}
+    {1982797200 3600 0 CET}
+    {1995498000 7200 1 CEST}
+    {2014246800 3600 0 CET}
+    {2026947600 7200 1 CEST}
+    {2045696400 3600 0 CET}
+    {2058397200 7200 1 CEST}
+    {2077146000 3600 0 CET}
+    {2090451600 7200 1 CEST}
+    {2108595600 3600 0 CET}
+    {2121901200 7200 1 CEST}
+    {2140045200 3600 0 CET}
+    {2153350800 7200 1 CEST}
+    {2172099600 3600 0 CET}
+    {2184800400 7200 1 CEST}
+    {2203549200 3600 0 CET}
+    {2216250000 7200 1 CEST}
+    {2234998800 3600 0 CET}
+    {2248304400 7200 1 CEST}
+    {2266448400 3600 0 CET}
+    {2279754000 7200 1 CEST}
+    {2297898000 3600 0 CET}
+    {2311203600 7200 1 CEST}
+    {2329347600 3600 0 CET}
+    {2342653200 7200 1 CEST}
+    {2361402000 3600 0 CET}
+    {2374102800 7200 1 CEST}
+    {2392851600 3600 0 CET}
+    {2405552400 7200 1 CEST}
+    {2424301200 3600 0 CET}
+    {2437606800 7200 1 CEST}
+    {2455750800 3600 0 CET}
+    {2469056400 7200 1 CEST}
+    {2487200400 3600 0 CET}
+    {2500506000 7200 1 CEST}
+    {2519254800 3600 0 CET}
+    {2531955600 7200 1 CEST}
+    {2550704400 3600 0 CET}
+    {2563405200 7200 1 CEST}
+    {2582154000 3600 0 CET}
+    {2595459600 7200 1 CEST}
+    {2613603600 3600 0 CET}
+    {2626909200 7200 1 CEST}
+    {2645053200 3600 0 CET}
+    {2658358800 7200 1 CEST}
+    {2676502800 3600 0 CET}
+    {2689808400 7200 1 CEST}
+    {2708557200 3600 0 CET}
+    {2721258000 7200 1 CEST}
+    {2740006800 3600 0 CET}
+    {2752707600 7200 1 CEST}
+    {2771456400 3600 0 CET}
+    {2784762000 7200 1 CEST}
+    {2802906000 3600 0 CET}
+    {2816211600 7200 1 CEST}
+    {2834355600 3600 0 CET}
+    {2847661200 7200 1 CEST}
+    {2866410000 3600 0 CET}
+    {2879110800 7200 1 CEST}
+    {2897859600 3600 0 CET}
+    {2910560400 7200 1 CEST}
+    {2929309200 3600 0 CET}
+    {2942010000 7200 1 CEST}
+    {2960758800 3600 0 CET}
+    {2974064400 7200 1 CEST}
+    {2992208400 3600 0 CET}
+    {3005514000 7200 1 CEST}
+    {3023658000 3600 0 CET}
+    {3036963600 7200 1 CEST}
+    {3055712400 3600 0 CET}
+    {3068413200 7200 1 CEST}
+    {3087162000 3600 0 CET}
+    {3099862800 7200 1 CEST}
+    {3118611600 3600 0 CET}
+    {3131917200 7200 1 CEST}
+    {3150061200 3600 0 CET}
+    {3163366800 7200 1 CEST}
+    {3181510800 3600 0 CET}
+    {3194816400 7200 1 CEST}
+    {3212960400 3600 0 CET}
+    {3226266000 7200 1 CEST}
+    {3245014800 3600 0 CET}
+    {3257715600 7200 1 CEST}
+    {3276464400 3600 0 CET}
+    {3289165200 7200 1 CEST}
+    {3307914000 3600 0 CET}
+    {3321219600 7200 1 CEST}
+    {3339363600 3600 0 CET}
+    {3352669200 7200 1 CEST}
+    {3370813200 3600 0 CET}
+    {3384118800 7200 1 CEST}
+    {3402867600 3600 0 CET}
+    {3415568400 7200 1 CEST}
+    {3434317200 3600 0 CET}
+    {3447018000 7200 1 CEST}
+    {3465766800 3600 0 CET}
+    {3479072400 7200 1 CEST}
+    {3497216400 3600 0 CET}
+    {3510522000 7200 1 CEST}
+    {3528666000 3600 0 CET}
+    {3541971600 7200 1 CEST}
+    {3560115600 3600 0 CET}
+    {3573421200 7200 1 CEST}
+    {3592170000 3600 0 CET}
+    {3604870800 7200 1 CEST}
+    {3623619600 3600 0 CET}
+    {3636320400 7200 1 CEST}
+    {3655069200 3600 0 CET}
+    {3668374800 7200 1 CEST}
+    {3686518800 3600 0 CET}
+    {3699824400 7200 1 CEST}
+    {3717968400 3600 0 CET}
+    {3731274000 7200 1 CEST}
+    {3750022800 3600 0 CET}
+    {3762723600 7200 1 CEST}
+    {3781472400 3600 0 CET}
+    {3794173200 7200 1 CEST}
+    {3812922000 3600 0 CET}
+    {3825622800 7200 1 CEST}
+    {3844371600 3600 0 CET}
+    {3857677200 7200 1 CEST}
+    {3875821200 3600 0 CET}
+    {3889126800 7200 1 CEST}
+    {3907270800 3600 0 CET}
+    {3920576400 7200 1 CEST}
+    {3939325200 3600 0 CET}
+    {3952026000 7200 1 CEST}
+    {3970774800 3600 0 CET}
+    {3983475600 7200 1 CEST}
+    {4002224400 3600 0 CET}
+    {4015530000 7200 1 CEST}
+    {4033674000 3600 0 CET}
+    {4046979600 7200 1 CEST}
+    {4065123600 3600 0 CET}
+    {4078429200 7200 1 CEST}
+    {4096573200 3600 0 CET}
+}
diff --git a/library/tzdata/Europe/Vilnius b/library/tzdata/Europe/Vilnius
new file mode 100644
index 0000000..5e73150
--- /dev/null
+++ b/library/tzdata/Europe/Vilnius
@@ -0,0 +1,252 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Europe/Vilnius) {
+    {-9223372036854775808 6076 0 LMT}
+    {-2840146876 5040 0 WMT}
+    {-1672536240 5736 0 KMT}
+    {-1585100136 3600 0 CET}
+    {-1561251600 7200 0 EET}
+    {-1553565600 3600 0 CET}
+    {-928198800 10800 0 MSK}
+    {-900126000 3600 0 CET}
+    {-857257200 3600 0 CET}
+    {-844556400 7200 1 CEST}
+    {-828226800 3600 0 CET}
+    {-812502000 7200 1 CEST}
+    {-802141200 10800 0 MSD}
+    {354920400 14400 1 MSD}
+    {370728000 10800 0 MSK}
+    {386456400 14400 1 MSD}
+    {402264000 10800 0 MSK}
+    {417992400 14400 1 MSD}
+    {433800000 10800 0 MSK}
+    {449614800 14400 1 MSD}
+    {465346800 10800 0 MSK}
+    {481071600 14400 1 MSD}
+    {496796400 10800 0 MSK}
+    {512521200 14400 1 MSD}
+    {528246000 10800 0 MSK}
+    {543970800 14400 1 MSD}
+    {559695600 10800 0 MSK}
+    {575420400 14400 1 MSD}
+    {591145200 10800 0 MSK}
+    {606870000 7200 0 EEMMTT}
+    {606873600 10800 1 EEST}
+    {622598400 7200 0 EET}
+    {638323200 10800 1 EEST}
+    {654652800 7200 0 EET}
+    {670377600 10800 1 EEST}
+    {686102400 7200 0 EET}
+    {701827200 10800 1 EEST}
+    {717552000 7200 0 EET}
+    {733276800 10800 1 EEST}
+    {749001600 7200 0 EET}
+    {764726400 10800 1 EEST}
+    {780451200 7200 0 EET}
+    {796176000 10800 1 EEST}
+    {811900800 7200 0 EET}
+    {828230400 10800 1 EEST}
+    {846374400 7200 0 EET}
+    {859680000 10800 1 EEST}
+    {877824000 7200 0 EET}
+    {883605600 7200 0 EET}
+    {891133200 7200 0 CEST}
+    {909277200 3600 0 CET}
+    {922582800 7200 1 CEST}
+    {941331600 7200 0 EET}
+    {1041372000 7200 0 EET}
+    {1048986000 10800 1 EEST}
+    {1067130000 7200 0 EET}
+    {1080435600 10800 1 EEST}
+    {1099184400 7200 0 EET}
+    {1111885200 10800 1 EEST}
+    {1130634000 7200 0 EET}
+    {1143334800 10800 1 EEST}
+    {1162083600 7200 0 EET}
+    {1174784400 10800 1 EEST}
+    {1193533200 7200 0 EET}
+    {1206838800 10800 1 EEST}
+    {1224982800 7200 0 EET}
+    {1238288400 10800 1 EEST}
+    {1256432400 7200 0 EET}
+    {1269738000 10800 1 EEST}
+    {1288486800 7200 0 EET}
+    {1301187600 10800 1 EEST}
+    {1319936400 7200 0 EET}
+    {1332637200 10800 1 EEST}
+    {1351386000 7200 0 EET}
+    {1364691600 10800 1 EEST}
+    {1382835600 7200 0 EET}
+    {1396141200 10800 1 EEST}
+    {1414285200 7200 0 EET}
+    {1427590800 10800 1 EEST}
+    {1445734800 7200 0 EET}
+    {1459040400 10800 1 EEST}
+    {1477789200 7200 0 EET}
+    {1490490000 10800 1 EEST}
+    {1509238800 7200 0 EET}
+    {1521939600 10800 1 EEST}
+    {1540688400 7200 0 EET}
+    {1553994000 10800 1 EEST}
+    {1572138000 7200 0 EET}
+    {1585443600 10800 1 EEST}
+    {1603587600 7200 0 EET}
+    {1616893200 10800 1 EEST}
+    {1635642000 7200 0 EET}
+    {1648342800 10800 1 EEST}
+    {1667091600 7200 0 EET}
+    {1679792400 10800 1 EEST}
+    {1698541200 7200 0 EET}
+    {1711846800 10800 1 EEST}
+    {1729990800 7200 0 EET}
+    {1743296400 10800 1 EEST}
+    {1761440400 7200 0 EET}
+    {1774746000 10800 1 EEST}
+    {1792890000 7200 0 EET}
+    {1806195600 10800 1 EEST}
+    {1824944400 7200 0 EET}
+    {1837645200 10800 1 EEST}
+    {1856394000 7200 0 EET}
+    {1869094800 10800 1 EEST}
+    {1887843600 7200 0 EET}
+    {1901149200 10800 1 EEST}
+    {1919293200 7200 0 EET}
+    {1932598800 10800 1 EEST}
+    {1950742800 7200 0 EET}
+    {1964048400 10800 1 EEST}
+    {1982797200 7200 0 EET}
+    {1995498000 10800 1 EEST}
+    {2014246800 7200 0 EET}
+    {2026947600 10800 1 EEST}
+    {2045696400 7200 0 EET}
+    {2058397200 10800 1 EEST}
+    {2077146000 7200 0 EET}
+    {2090451600 10800 1 EEST}
+    {2108595600 7200 0 EET}
+    {2121901200 10800 1 EEST}
+    {2140045200 7200 0 EET}
+    {2153350800 10800 1 EEST}
+    {2172099600 7200 0 EET}
+    {2184800400 10800 1 EEST}
+    {2203549200 7200 0 EET}
+    {2216250000 10800 1 EEST}
+    {2234998800 7200 0 EET}
+    {2248304400 10800 1 EEST}
+    {2266448400 7200 0 EET}
+    {2279754000 10800 1 EEST}
+    {2297898000 7200 0 EET}
+    {2311203600 10800 1 EEST}
+    {2329347600 7200 0 EET}
+    {2342653200 10800 1 EEST}
+    {2361402000 7200 0 EET}
+    {2374102800 10800 1 EEST}
+    {2392851600 7200 0 EET}
+    {2405552400 10800 1 EEST}
+    {2424301200 7200 0 EET}
+    {2437606800 10800 1 EEST}
+    {2455750800 7200 0 EET}
+    {2469056400 10800 1 EEST}
+    {2487200400 7200 0 EET}
+    {2500506000 10800 1 EEST}
+    {2519254800 7200 0 EET}
+    {2531955600 10800 1 EEST}
+    {2550704400 7200 0 EET}
+    {2563405200 10800 1 EEST}
+    {2582154000 7200 0 EET}
+    {2595459600 10800 1 EEST}
+    {2613603600 7200 0 EET}
+    {2626909200 10800 1 EEST}
+    {2645053200 7200 0 EET}
+    {2658358800 10800 1 EEST}
+    {2676502800 7200 0 EET}
+    {2689808400 10800 1 EEST}
+    {2708557200 7200 0 EET}
+    {2721258000 10800 1 EEST}
+    {2740006800 7200 0 EET}
+    {2752707600 10800 1 EEST}
+    {2771456400 7200 0 EET}
+    {2784762000 10800 1 EEST}
+    {2802906000 7200 0 EET}
+    {2816211600 10800 1 EEST}
+    {2834355600 7200 0 EET}
+    {2847661200 10800 1 EEST}
+    {2866410000 7200 0 EET}
+    {2879110800 10800 1 EEST}
+    {2897859600 7200 0 EET}
+    {2910560400 10800 1 EEST}
+    {2929309200 7200 0 EET}
+    {2942010000 10800 1 EEST}
+    {2960758800 7200 0 EET}
+    {2974064400 10800 1 EEST}
+    {2992208400 7200 0 EET}
+    {3005514000 10800 1 EEST}
+    {3023658000 7200 0 EET}
+    {3036963600 10800 1 EEST}
+    {3055712400 7200 0 EET}
+    {3068413200 10800 1 EEST}
+    {3087162000 7200 0 EET}
+    {3099862800 10800 1 EEST}
+    {3118611600 7200 0 EET}
+    {3131917200 10800 1 EEST}
+    {3150061200 7200 0 EET}
+    {3163366800 10800 1 EEST}
+    {3181510800 7200 0 EET}
+    {3194816400 10800 1 EEST}
+    {3212960400 7200 0 EET}
+    {3226266000 10800 1 EEST}
+    {3245014800 7200 0 EET}
+    {3257715600 10800 1 EEST}
+    {3276464400 7200 0 EET}
+    {3289165200 10800 1 EEST}
+    {3307914000 7200 0 EET}
+    {3321219600 10800 1 EEST}
+    {3339363600 7200 0 EET}
+    {3352669200 10800 1 EEST}
+    {3370813200 7200 0 EET}
+    {3384118800 10800 1 EEST}
+    {3402867600 7200 0 EET}
+    {3415568400 10800 1 EEST}
+    {3434317200 7200 0 EET}
+    {3447018000 10800 1 EEST}
+    {3465766800 7200 0 EET}
+    {3479072400 10800 1 EEST}
+    {3497216400 7200 0 EET}
+    {3510522000 10800 1 EEST}
+    {3528666000 7200 0 EET}
+    {3541971600 10800 1 EEST}
+    {3560115600 7200 0 EET}
+    {3573421200 10800 1 EEST}
+    {3592170000 7200 0 EET}
+    {3604870800 10800 1 EEST}
+    {3623619600 7200 0 EET}
+    {3636320400 10800 1 EEST}
+    {3655069200 7200 0 EET}
+    {3668374800 10800 1 EEST}
+    {3686518800 7200 0 EET}
+    {3699824400 10800 1 EEST}
+    {3717968400 7200 0 EET}
+    {3731274000 10800 1 EEST}
+    {3750022800 7200 0 EET}
+    {3762723600 10800 1 EEST}
+    {3781472400 7200 0 EET}
+    {3794173200 10800 1 EEST}
+    {3812922000 7200 0 EET}
+    {3825622800 10800 1 EEST}
+    {3844371600 7200 0 EET}
+    {3857677200 10800 1 EEST}
+    {3875821200 7200 0 EET}
+    {3889126800 10800 1 EEST}
+    {3907270800 7200 0 EET}
+    {3920576400 10800 1 EEST}
+    {3939325200 7200 0 EET}
+    {3952026000 10800 1 EEST}
+    {3970774800 7200 0 EET}
+    {3983475600 10800 1 EEST}
+    {4002224400 7200 0 EET}
+    {4015530000 10800 1 EEST}
+    {4033674000 7200 0 EET}
+    {4046979600 10800 1 EEST}
+    {4065123600 7200 0 EET}
+    {4078429200 10800 1 EEST}
+    {4096573200 7200 0 EET}
+}
diff --git a/library/tzdata/Europe/Volgograd b/library/tzdata/Europe/Volgograd
new file mode 100644
index 0000000..83996b0
--- /dev/null
+++ b/library/tzdata/Europe/Volgograd
@@ -0,0 +1,72 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Europe/Volgograd) {
+    {-9223372036854775808 10660 0 LMT}
+    {-1577761060 10800 0 TSAT}
+    {-1411873200 10800 0 STAT}
+    {-1247540400 14400 0 STAT}
+    {-256881600 14400 0 VOLMMTT}
+    {354916800 18000 1 VOLST}
+    {370724400 14400 0 VOLT}
+    {386452800 18000 1 VOLST}
+    {402260400 14400 0 VOLT}
+    {417988800 18000 1 VOLST}
+    {433796400 14400 0 VOLT}
+    {449611200 18000 1 VOLST}
+    {465343200 14400 0 VOLT}
+    {481068000 18000 1 VOLST}
+    {496792800 14400 0 VOLT}
+    {512517600 18000 1 VOLST}
+    {528242400 14400 0 VOLT}
+    {543967200 18000 1 VOLST}
+    {559692000 14400 0 VOLT}
+    {575416800 10800 0 VOLMMTT}
+    {575420400 14400 1 VOLST}
+    {591145200 10800 0 VOLT}
+    {606870000 14400 1 VOLST}
+    {622594800 10800 0 VOLT}
+    {638319600 14400 1 VOLST}
+    {654649200 10800 0 VOLT}
+    {670374000 14400 0 VOLT}
+    {701820000 10800 0 MSD}
+    {701823600 14400 1 MSD}
+    {717548400 10800 0 MSK}
+    {733273200 14400 1 MSD}
+    {748998000 10800 0 MSK}
+    {764722800 14400 1 MSD}
+    {780447600 10800 0 MSK}
+    {796172400 14400 1 MSD}
+    {811897200 10800 0 MSK}
+    {828226800 14400 1 MSD}
+    {846370800 10800 0 MSK}
+    {859676400 14400 1 MSD}
+    {877820400 10800 0 MSK}
+    {891126000 14400 1 MSD}
+    {909270000 10800 0 MSK}
+    {922575600 14400 1 MSD}
+    {941324400 10800 0 MSK}
+    {954025200 14400 1 MSD}
+    {972774000 10800 0 MSK}
+    {985474800 14400 1 MSD}
+    {1004223600 10800 0 MSK}
+    {1017529200 14400 1 MSD}
+    {1035673200 10800 0 MSK}
+    {1048978800 14400 1 MSD}
+    {1067122800 10800 0 MSK}
+    {1080428400 14400 1 MSD}
+    {1099177200 10800 0 MSK}
+    {1111878000 14400 1 MSD}
+    {1130626800 10800 0 MSK}
+    {1143327600 14400 1 MSD}
+    {1162076400 10800 0 MSK}
+    {1174777200 14400 1 MSD}
+    {1193526000 10800 0 MSK}
+    {1206831600 14400 1 MSD}
+    {1224975600 10800 0 MSK}
+    {1238281200 14400 1 MSD}
+    {1256425200 10800 0 MSK}
+    {1269730800 14400 1 MSD}
+    {1288479600 10800 0 MSK}
+    {1301180400 14400 0 MSK}
+    {1414274400 10800 0 MSK}
+}
diff --git a/library/tzdata/Europe/Warsaw b/library/tzdata/Europe/Warsaw
new file mode 100644
index 0000000..6288a8a
--- /dev/null
+++ b/library/tzdata/Europe/Warsaw
@@ -0,0 +1,296 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Europe/Warsaw) {
+    {-9223372036854775808 5040 0 LMT}
+    {-2840145840 5040 0 WMT}
+    {-1717032240 3600 0 CET}
+    {-1693706400 7200 1 CEST}
+    {-1680483600 3600 0 CET}
+    {-1663455600 7200 1 CEST}
+    {-1650150000 3600 0 CET}
+    {-1632006000 7200 1 CEST}
+    {-1618696800 7200 0 EET}
+    {-1600473600 10800 1 EEST}
+    {-1587168000 7200 0 EET}
+    {-931734000 7200 0 CEST}
+    {-857257200 3600 0 CET}
+    {-844556400 7200 1 CEST}
+    {-828226800 3600 0 CET}
+    {-812502000 7200 1 CEST}
+    {-796870800 7200 0 CEST}
+    {-796608000 3600 0 CET}
+    {-778726800 7200 1 CEST}
+    {-762660000 3600 0 CET}
+    {-748486800 7200 1 CEST}
+    {-733273200 3600 0 CET}
+    {-715215600 7200 1 CEST}
+    {-701910000 3600 0 CET}
+    {-684975600 7200 1 CEST}
+    {-670460400 3600 0 CET}
+    {-654130800 7200 1 CEST}
+    {-639010800 3600 0 CET}
+    {-397094400 7200 1 CEST}
+    {-386812800 3600 0 CET}
+    {-371088000 7200 1 CEST}
+    {-355363200 3600 0 CET}
+    {-334195200 7200 1 CEST}
+    {-323308800 3600 0 CET}
+    {-307584000 7200 1 CEST}
+    {-291859200 3600 0 CET}
+    {-271296000 7200 1 CEST}
+    {-260409600 3600 0 CET}
+    {-239846400 7200 1 CEST}
+    {-228960000 3600 0 CET}
+    {-208396800 7200 1 CEST}
+    {-197510400 3600 0 CET}
+    {-176342400 7200 1 CEST}
+    {-166060800 3600 0 CET}
+    {220921200 3600 0 CET}
+    {228873600 7200 1 CEST}
+    {243993600 3600 0 CET}
+    {260323200 7200 1 CEST}
+    {276048000 3600 0 CET}
+    {291772800 7200 1 CEST}
+    {307497600 3600 0 CET}
+    {323827200 7200 1 CEST}
+    {338947200 3600 0 CET}
+    {354672000 7200 1 CEST}
+    {370396800 3600 0 CET}
+    {386121600 7200 1 CEST}
+    {401846400 3600 0 CET}
+    {417571200 7200 1 CEST}
+    {433296000 3600 0 CET}
+    {449020800 7200 1 CEST}
+    {465350400 3600 0 CET}
+    {481075200 7200 1 CEST}
+    {496800000 3600 0 CET}
+    {512524800 7200 1 CEST}
+    {528249600 3600 0 CET}
+    {543974400 7200 1 CEST}
+    {559699200 3600 0 CET}
+    {567990000 3600 0 CET}
+    {575427600 7200 1 CEST}
+    {591152400 3600 0 CET}
+    {606877200 7200 1 CEST}
+    {622602000 3600 0 CET}
+    {638326800 7200 1 CEST}
+    {654656400 3600 0 CET}
+    {670381200 7200 1 CEST}
+    {686106000 3600 0 CET}
+    {701830800 7200 1 CEST}
+    {717555600 3600 0 CET}
+    {733280400 7200 1 CEST}
+    {749005200 3600 0 CET}
+    {764730000 7200 1 CEST}
+    {780454800 3600 0 CET}
+    {796179600 7200 1 CEST}
+    {811904400 3600 0 CET}
+    {828234000 7200 1 CEST}
+    {846378000 3600 0 CET}
+    {859683600 7200 1 CEST}
+    {877827600 3600 0 CET}
+    {891133200 7200 1 CEST}
+    {909277200 3600 0 CET}
+    {922582800 7200 1 CEST}
+    {941331600 3600 0 CET}
+    {954032400 7200 1 CEST}
+    {972781200 3600 0 CET}
+    {985482000 7200 1 CEST}
+    {1004230800 3600 0 CET}
+    {1017536400 7200 1 CEST}
+    {1035680400 3600 0 CET}
+    {1048986000 7200 1 CEST}
+    {1067130000 3600 0 CET}
+    {1080435600 7200 1 CEST}
+    {1099184400 3600 0 CET}
+    {1111885200 7200 1 CEST}
+    {1130634000 3600 0 CET}
+    {1143334800 7200 1 CEST}
+    {1162083600 3600 0 CET}
+    {1174784400 7200 1 CEST}
+    {1193533200 3600 0 CET}
+    {1206838800 7200 1 CEST}
+    {1224982800 3600 0 CET}
+    {1238288400 7200 1 CEST}
+    {1256432400 3600 0 CET}
+    {1269738000 7200 1 CEST}
+    {1288486800 3600 0 CET}
+    {1301187600 7200 1 CEST}
+    {1319936400 3600 0 CET}
+    {1332637200 7200 1 CEST}
+    {1351386000 3600 0 CET}
+    {1364691600 7200 1 CEST}
+    {1382835600 3600 0 CET}
+    {1396141200 7200 1 CEST}
+    {1414285200 3600 0 CET}
+    {1427590800 7200 1 CEST}
+    {1445734800 3600 0 CET}
+    {1459040400 7200 1 CEST}
+    {1477789200 3600 0 CET}
+    {1490490000 7200 1 CEST}
+    {1509238800 3600 0 CET}
+    {1521939600 7200 1 CEST}
+    {1540688400 3600 0 CET}
+    {1553994000 7200 1 CEST}
+    {1572138000 3600 0 CET}
+    {1585443600 7200 1 CEST}
+    {1603587600 3600 0 CET}
+    {1616893200 7200 1 CEST}
+    {1635642000 3600 0 CET}
+    {1648342800 7200 1 CEST}
+    {1667091600 3600 0 CET}
+    {1679792400 7200 1 CEST}
+    {1698541200 3600 0 CET}
+    {1711846800 7200 1 CEST}
+    {1729990800 3600 0 CET}
+    {1743296400 7200 1 CEST}
+    {1761440400 3600 0 CET}
+    {1774746000 7200 1 CEST}
+    {1792890000 3600 0 CET}
+    {1806195600 7200 1 CEST}
+    {1824944400 3600 0 CET}
+    {1837645200 7200 1 CEST}
+    {1856394000 3600 0 CET}
+    {1869094800 7200 1 CEST}
+    {1887843600 3600 0 CET}
+    {1901149200 7200 1 CEST}
+    {1919293200 3600 0 CET}
+    {1932598800 7200 1 CEST}
+    {1950742800 3600 0 CET}
+    {1964048400 7200 1 CEST}
+    {1982797200 3600 0 CET}
+    {1995498000 7200 1 CEST}
+    {2014246800 3600 0 CET}
+    {2026947600 7200 1 CEST}
+    {2045696400 3600 0 CET}
+    {2058397200 7200 1 CEST}
+    {2077146000 3600 0 CET}
+    {2090451600 7200 1 CEST}
+    {2108595600 3600 0 CET}
+    {2121901200 7200 1 CEST}
+    {2140045200 3600 0 CET}
+    {2153350800 7200 1 CEST}
+    {2172099600 3600 0 CET}
+    {2184800400 7200 1 CEST}
+    {2203549200 3600 0 CET}
+    {2216250000 7200 1 CEST}
+    {2234998800 3600 0 CET}
+    {2248304400 7200 1 CEST}
+    {2266448400 3600 0 CET}
+    {2279754000 7200 1 CEST}
+    {2297898000 3600 0 CET}
+    {2311203600 7200 1 CEST}
+    {2329347600 3600 0 CET}
+    {2342653200 7200 1 CEST}
+    {2361402000 3600 0 CET}
+    {2374102800 7200 1 CEST}
+    {2392851600 3600 0 CET}
+    {2405552400 7200 1 CEST}
+    {2424301200 3600 0 CET}
+    {2437606800 7200 1 CEST}
+    {2455750800 3600 0 CET}
+    {2469056400 7200 1 CEST}
+    {2487200400 3600 0 CET}
+    {2500506000 7200 1 CEST}
+    {2519254800 3600 0 CET}
+    {2531955600 7200 1 CEST}
+    {2550704400 3600 0 CET}
+    {2563405200 7200 1 CEST}
+    {2582154000 3600 0 CET}
+    {2595459600 7200 1 CEST}
+    {2613603600 3600 0 CET}
+    {2626909200 7200 1 CEST}
+    {2645053200 3600 0 CET}
+    {2658358800 7200 1 CEST}
+    {2676502800 3600 0 CET}
+    {2689808400 7200 1 CEST}
+    {2708557200 3600 0 CET}
+    {2721258000 7200 1 CEST}
+    {2740006800 3600 0 CET}
+    {2752707600 7200 1 CEST}
+    {2771456400 3600 0 CET}
+    {2784762000 7200 1 CEST}
+    {2802906000 3600 0 CET}
+    {2816211600 7200 1 CEST}
+    {2834355600 3600 0 CET}
+    {2847661200 7200 1 CEST}
+    {2866410000 3600 0 CET}
+    {2879110800 7200 1 CEST}
+    {2897859600 3600 0 CET}
+    {2910560400 7200 1 CEST}
+    {2929309200 3600 0 CET}
+    {2942010000 7200 1 CEST}
+    {2960758800 3600 0 CET}
+    {2974064400 7200 1 CEST}
+    {2992208400 3600 0 CET}
+    {3005514000 7200 1 CEST}
+    {3023658000 3600 0 CET}
+    {3036963600 7200 1 CEST}
+    {3055712400 3600 0 CET}
+    {3068413200 7200 1 CEST}
+    {3087162000 3600 0 CET}
+    {3099862800 7200 1 CEST}
+    {3118611600 3600 0 CET}
+    {3131917200 7200 1 CEST}
+    {3150061200 3600 0 CET}
+    {3163366800 7200 1 CEST}
+    {3181510800 3600 0 CET}
+    {3194816400 7200 1 CEST}
+    {3212960400 3600 0 CET}
+    {3226266000 7200 1 CEST}
+    {3245014800 3600 0 CET}
+    {3257715600 7200 1 CEST}
+    {3276464400 3600 0 CET}
+    {3289165200 7200 1 CEST}
+    {3307914000 3600 0 CET}
+    {3321219600 7200 1 CEST}
+    {3339363600 3600 0 CET}
+    {3352669200 7200 1 CEST}
+    {3370813200 3600 0 CET}
+    {3384118800 7200 1 CEST}
+    {3402867600 3600 0 CET}
+    {3415568400 7200 1 CEST}
+    {3434317200 3600 0 CET}
+    {3447018000 7200 1 CEST}
+    {3465766800 3600 0 CET}
+    {3479072400 7200 1 CEST}
+    {3497216400 3600 0 CET}
+    {3510522000 7200 1 CEST}
+    {3528666000 3600 0 CET}
+    {3541971600 7200 1 CEST}
+    {3560115600 3600 0 CET}
+    {3573421200 7200 1 CEST}
+    {3592170000 3600 0 CET}
+    {3604870800 7200 1 CEST}
+    {3623619600 3600 0 CET}
+    {3636320400 7200 1 CEST}
+    {3655069200 3600 0 CET}
+    {3668374800 7200 1 CEST}
+    {3686518800 3600 0 CET}
+    {3699824400 7200 1 CEST}
+    {3717968400 3600 0 CET}
+    {3731274000 7200 1 CEST}
+    {3750022800 3600 0 CET}
+    {3762723600 7200 1 CEST}
+    {3781472400 3600 0 CET}
+    {3794173200 7200 1 CEST}
+    {3812922000 3600 0 CET}
+    {3825622800 7200 1 CEST}
+    {3844371600 3600 0 CET}
+    {3857677200 7200 1 CEST}
+    {3875821200 3600 0 CET}
+    {3889126800 7200 1 CEST}
+    {3907270800 3600 0 CET}
+    {3920576400 7200 1 CEST}
+    {3939325200 3600 0 CET}
+    {3952026000 7200 1 CEST}
+    {3970774800 3600 0 CET}
+    {3983475600 7200 1 CEST}
+    {4002224400 3600 0 CET}
+    {4015530000 7200 1 CEST}
+    {4033674000 3600 0 CET}
+    {4046979600 7200 1 CEST}
+    {4065123600 3600 0 CET}
+    {4078429200 7200 1 CEST}
+    {4096573200 3600 0 CET}
+}
diff --git a/library/tzdata/Europe/Zagreb b/library/tzdata/Europe/Zagreb
new file mode 100644
index 0000000..46319a4
--- /dev/null
+++ b/library/tzdata/Europe/Zagreb
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Europe/Belgrade)]} {
+    LoadTimeZoneFile Europe/Belgrade
+}
+set TZData(:Europe/Zagreb) $TZData(:Europe/Belgrade)
diff --git a/library/tzdata/Europe/Zaporozhye b/library/tzdata/Europe/Zaporozhye
new file mode 100644
index 0000000..01418cd
--- /dev/null
+++ b/library/tzdata/Europe/Zaporozhye
@@ -0,0 +1,252 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Europe/Zaporozhye) {
+    {-9223372036854775808 8440 0 LMT}
+    {-2840149240 8400 0 CUT}
+    {-1441160400 7200 0 EET}
+    {-1247536800 10800 0 MSK}
+    {-894769200 3600 0 CET}
+    {-857257200 3600 0 CET}
+    {-844556400 7200 1 CEST}
+    {-828226800 3600 0 CET}
+    {-826419600 10800 0 MSD}
+    {354920400 14400 1 MSD}
+    {370728000 10800 0 MSK}
+    {386456400 14400 1 MSD}
+    {402264000 10800 0 MSK}
+    {417992400 14400 1 MSD}
+    {433800000 10800 0 MSK}
+    {449614800 14400 1 MSD}
+    {465346800 10800 0 MSK}
+    {481071600 14400 1 MSD}
+    {496796400 10800 0 MSK}
+    {512521200 14400 1 MSD}
+    {528246000 10800 0 MSK}
+    {543970800 14400 1 MSD}
+    {559695600 10800 0 MSK}
+    {575420400 14400 1 MSD}
+    {591145200 10800 0 MSK}
+    {606870000 14400 1 MSD}
+    {622594800 10800 0 MSK}
+    {638319600 14400 1 MSD}
+    {654649200 10800 0 MSK}
+    {670374000 10800 0 EEST}
+    {686091600 7200 0 EET}
+    {701820000 10800 1 EEST}
+    {717541200 7200 0 EET}
+    {733269600 10800 1 EEST}
+    {748990800 7200 0 EET}
+    {764719200 10800 1 EEST}
+    {780440400 7200 0 EET}
+    {788911200 7200 0 EET}
+    {796179600 10800 1 EEST}
+    {811904400 7200 0 EET}
+    {828234000 10800 1 EEST}
+    {846378000 7200 0 EET}
+    {859683600 10800 1 EEST}
+    {877827600 7200 0 EET}
+    {891133200 10800 1 EEST}
+    {909277200 7200 0 EET}
+    {922582800 10800 1 EEST}
+    {941331600 7200 0 EET}
+    {954032400 10800 1 EEST}
+    {972781200 7200 0 EET}
+    {985482000 10800 1 EEST}
+    {1004230800 7200 0 EET}
+    {1017536400 10800 1 EEST}
+    {1035680400 7200 0 EET}
+    {1048986000 10800 1 EEST}
+    {1067130000 7200 0 EET}
+    {1080435600 10800 1 EEST}
+    {1099184400 7200 0 EET}
+    {1111885200 10800 1 EEST}
+    {1130634000 7200 0 EET}
+    {1143334800 10800 1 EEST}
+    {1162083600 7200 0 EET}
+    {1174784400 10800 1 EEST}
+    {1193533200 7200 0 EET}
+    {1206838800 10800 1 EEST}
+    {1224982800 7200 0 EET}
+    {1238288400 10800 1 EEST}
+    {1256432400 7200 0 EET}
+    {1269738000 10800 1 EEST}
+    {1288486800 7200 0 EET}
+    {1301187600 10800 1 EEST}
+    {1319936400 7200 0 EET}
+    {1332637200 10800 1 EEST}
+    {1351386000 7200 0 EET}
+    {1364691600 10800 1 EEST}
+    {1382835600 7200 0 EET}
+    {1396141200 10800 1 EEST}
+    {1414285200 7200 0 EET}
+    {1427590800 10800 1 EEST}
+    {1445734800 7200 0 EET}
+    {1459040400 10800 1 EEST}
+    {1477789200 7200 0 EET}
+    {1490490000 10800 1 EEST}
+    {1509238800 7200 0 EET}
+    {1521939600 10800 1 EEST}
+    {1540688400 7200 0 EET}
+    {1553994000 10800 1 EEST}
+    {1572138000 7200 0 EET}
+    {1585443600 10800 1 EEST}
+    {1603587600 7200 0 EET}
+    {1616893200 10800 1 EEST}
+    {1635642000 7200 0 EET}
+    {1648342800 10800 1 EEST}
+    {1667091600 7200 0 EET}
+    {1679792400 10800 1 EEST}
+    {1698541200 7200 0 EET}
+    {1711846800 10800 1 EEST}
+    {1729990800 7200 0 EET}
+    {1743296400 10800 1 EEST}
+    {1761440400 7200 0 EET}
+    {1774746000 10800 1 EEST}
+    {1792890000 7200 0 EET}
+    {1806195600 10800 1 EEST}
+    {1824944400 7200 0 EET}
+    {1837645200 10800 1 EEST}
+    {1856394000 7200 0 EET}
+    {1869094800 10800 1 EEST}
+    {1887843600 7200 0 EET}
+    {1901149200 10800 1 EEST}
+    {1919293200 7200 0 EET}
+    {1932598800 10800 1 EEST}
+    {1950742800 7200 0 EET}
+    {1964048400 10800 1 EEST}
+    {1982797200 7200 0 EET}
+    {1995498000 10800 1 EEST}
+    {2014246800 7200 0 EET}
+    {2026947600 10800 1 EEST}
+    {2045696400 7200 0 EET}
+    {2058397200 10800 1 EEST}
+    {2077146000 7200 0 EET}
+    {2090451600 10800 1 EEST}
+    {2108595600 7200 0 EET}
+    {2121901200 10800 1 EEST}
+    {2140045200 7200 0 EET}
+    {2153350800 10800 1 EEST}
+    {2172099600 7200 0 EET}
+    {2184800400 10800 1 EEST}
+    {2203549200 7200 0 EET}
+    {2216250000 10800 1 EEST}
+    {2234998800 7200 0 EET}
+    {2248304400 10800 1 EEST}
+    {2266448400 7200 0 EET}
+    {2279754000 10800 1 EEST}
+    {2297898000 7200 0 EET}
+    {2311203600 10800 1 EEST}
+    {2329347600 7200 0 EET}
+    {2342653200 10800 1 EEST}
+    {2361402000 7200 0 EET}
+    {2374102800 10800 1 EEST}
+    {2392851600 7200 0 EET}
+    {2405552400 10800 1 EEST}
+    {2424301200 7200 0 EET}
+    {2437606800 10800 1 EEST}
+    {2455750800 7200 0 EET}
+    {2469056400 10800 1 EEST}
+    {2487200400 7200 0 EET}
+    {2500506000 10800 1 EEST}
+    {2519254800 7200 0 EET}
+    {2531955600 10800 1 EEST}
+    {2550704400 7200 0 EET}
+    {2563405200 10800 1 EEST}
+    {2582154000 7200 0 EET}
+    {2595459600 10800 1 EEST}
+    {2613603600 7200 0 EET}
+    {2626909200 10800 1 EEST}
+    {2645053200 7200 0 EET}
+    {2658358800 10800 1 EEST}
+    {2676502800 7200 0 EET}
+    {2689808400 10800 1 EEST}
+    {2708557200 7200 0 EET}
+    {2721258000 10800 1 EEST}
+    {2740006800 7200 0 EET}
+    {2752707600 10800 1 EEST}
+    {2771456400 7200 0 EET}
+    {2784762000 10800 1 EEST}
+    {2802906000 7200 0 EET}
+    {2816211600 10800 1 EEST}
+    {2834355600 7200 0 EET}
+    {2847661200 10800 1 EEST}
+    {2866410000 7200 0 EET}
+    {2879110800 10800 1 EEST}
+    {2897859600 7200 0 EET}
+    {2910560400 10800 1 EEST}
+    {2929309200 7200 0 EET}
+    {2942010000 10800 1 EEST}
+    {2960758800 7200 0 EET}
+    {2974064400 10800 1 EEST}
+    {2992208400 7200 0 EET}
+    {3005514000 10800 1 EEST}
+    {3023658000 7200 0 EET}
+    {3036963600 10800 1 EEST}
+    {3055712400 7200 0 EET}
+    {3068413200 10800 1 EEST}
+    {3087162000 7200 0 EET}
+    {3099862800 10800 1 EEST}
+    {3118611600 7200 0 EET}
+    {3131917200 10800 1 EEST}
+    {3150061200 7200 0 EET}
+    {3163366800 10800 1 EEST}
+    {3181510800 7200 0 EET}
+    {3194816400 10800 1 EEST}
+    {3212960400 7200 0 EET}
+    {3226266000 10800 1 EEST}
+    {3245014800 7200 0 EET}
+    {3257715600 10800 1 EEST}
+    {3276464400 7200 0 EET}
+    {3289165200 10800 1 EEST}
+    {3307914000 7200 0 EET}
+    {3321219600 10800 1 EEST}
+    {3339363600 7200 0 EET}
+    {3352669200 10800 1 EEST}
+    {3370813200 7200 0 EET}
+    {3384118800 10800 1 EEST}
+    {3402867600 7200 0 EET}
+    {3415568400 10800 1 EEST}
+    {3434317200 7200 0 EET}
+    {3447018000 10800 1 EEST}
+    {3465766800 7200 0 EET}
+    {3479072400 10800 1 EEST}
+    {3497216400 7200 0 EET}
+    {3510522000 10800 1 EEST}
+    {3528666000 7200 0 EET}
+    {3541971600 10800 1 EEST}
+    {3560115600 7200 0 EET}
+    {3573421200 10800 1 EEST}
+    {3592170000 7200 0 EET}
+    {3604870800 10800 1 EEST}
+    {3623619600 7200 0 EET}
+    {3636320400 10800 1 EEST}
+    {3655069200 7200 0 EET}
+    {3668374800 10800 1 EEST}
+    {3686518800 7200 0 EET}
+    {3699824400 10800 1 EEST}
+    {3717968400 7200 0 EET}
+    {3731274000 10800 1 EEST}
+    {3750022800 7200 0 EET}
+    {3762723600 10800 1 EEST}
+    {3781472400 7200 0 EET}
+    {3794173200 10800 1 EEST}
+    {3812922000 7200 0 EET}
+    {3825622800 10800 1 EEST}
+    {3844371600 7200 0 EET}
+    {3857677200 10800 1 EEST}
+    {3875821200 7200 0 EET}
+    {3889126800 10800 1 EEST}
+    {3907270800 7200 0 EET}
+    {3920576400 10800 1 EEST}
+    {3939325200 7200 0 EET}
+    {3952026000 10800 1 EEST}
+    {3970774800 7200 0 EET}
+    {3983475600 10800 1 EEST}
+    {4002224400 7200 0 EET}
+    {4015530000 10800 1 EEST}
+    {4033674000 7200 0 EET}
+    {4046979600 10800 1 EEST}
+    {4065123600 7200 0 EET}
+    {4078429200 10800 1 EEST}
+    {4096573200 7200 0 EET}
+}
diff --git a/library/tzdata/Europe/Zurich b/library/tzdata/Europe/Zurich
new file mode 100644
index 0000000..87a20db
--- /dev/null
+++ b/library/tzdata/Europe/Zurich
@@ -0,0 +1,250 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Europe/Zurich) {
+    {-9223372036854775808 2048 0 LMT}
+    {-3675198848 1786 0 BMT}
+    {-2385246586 3600 0 CET}
+    {-904435200 7200 1 CEST}
+    {-891129600 3600 0 CET}
+    {-872985600 7200 1 CEST}
+    {-859680000 3600 0 CET}
+    {347151600 3600 0 CET}
+    {354675600 7200 1 CEST}
+    {370400400 3600 0 CET}
+    {386125200 7200 1 CEST}
+    {401850000 3600 0 CET}
+    {417574800 7200 1 CEST}
+    {433299600 3600 0 CET}
+    {449024400 7200 1 CEST}
+    {465354000 3600 0 CET}
+    {481078800 7200 1 CEST}
+    {496803600 3600 0 CET}
+    {512528400 7200 1 CEST}
+    {528253200 3600 0 CET}
+    {543978000 7200 1 CEST}
+    {559702800 3600 0 CET}
+    {575427600 7200 1 CEST}
+    {591152400 3600 0 CET}
+    {606877200 7200 1 CEST}
+    {622602000 3600 0 CET}
+    {638326800 7200 1 CEST}
+    {654656400 3600 0 CET}
+    {670381200 7200 1 CEST}
+    {686106000 3600 0 CET}
+    {701830800 7200 1 CEST}
+    {717555600 3600 0 CET}
+    {733280400 7200 1 CEST}
+    {749005200 3600 0 CET}
+    {764730000 7200 1 CEST}
+    {780454800 3600 0 CET}
+    {796179600 7200 1 CEST}
+    {811904400 3600 0 CET}
+    {828234000 7200 1 CEST}
+    {846378000 3600 0 CET}
+    {859683600 7200 1 CEST}
+    {877827600 3600 0 CET}
+    {891133200 7200 1 CEST}
+    {909277200 3600 0 CET}
+    {922582800 7200 1 CEST}
+    {941331600 3600 0 CET}
+    {954032400 7200 1 CEST}
+    {972781200 3600 0 CET}
+    {985482000 7200 1 CEST}
+    {1004230800 3600 0 CET}
+    {1017536400 7200 1 CEST}
+    {1035680400 3600 0 CET}
+    {1048986000 7200 1 CEST}
+    {1067130000 3600 0 CET}
+    {1080435600 7200 1 CEST}
+    {1099184400 3600 0 CET}
+    {1111885200 7200 1 CEST}
+    {1130634000 3600 0 CET}
+    {1143334800 7200 1 CEST}
+    {1162083600 3600 0 CET}
+    {1174784400 7200 1 CEST}
+    {1193533200 3600 0 CET}
+    {1206838800 7200 1 CEST}
+    {1224982800 3600 0 CET}
+    {1238288400 7200 1 CEST}
+    {1256432400 3600 0 CET}
+    {1269738000 7200 1 CEST}
+    {1288486800 3600 0 CET}
+    {1301187600 7200 1 CEST}
+    {1319936400 3600 0 CET}
+    {1332637200 7200 1 CEST}
+    {1351386000 3600 0 CET}
+    {1364691600 7200 1 CEST}
+    {1382835600 3600 0 CET}
+    {1396141200 7200 1 CEST}
+    {1414285200 3600 0 CET}
+    {1427590800 7200 1 CEST}
+    {1445734800 3600 0 CET}
+    {1459040400 7200 1 CEST}
+    {1477789200 3600 0 CET}
+    {1490490000 7200 1 CEST}
+    {1509238800 3600 0 CET}
+    {1521939600 7200 1 CEST}
+    {1540688400 3600 0 CET}
+    {1553994000 7200 1 CEST}
+    {1572138000 3600 0 CET}
+    {1585443600 7200 1 CEST}
+    {1603587600 3600 0 CET}
+    {1616893200 7200 1 CEST}
+    {1635642000 3600 0 CET}
+    {1648342800 7200 1 CEST}
+    {1667091600 3600 0 CET}
+    {1679792400 7200 1 CEST}
+    {1698541200 3600 0 CET}
+    {1711846800 7200 1 CEST}
+    {1729990800 3600 0 CET}
+    {1743296400 7200 1 CEST}
+    {1761440400 3600 0 CET}
+    {1774746000 7200 1 CEST}
+    {1792890000 3600 0 CET}
+    {1806195600 7200 1 CEST}
+    {1824944400 3600 0 CET}
+    {1837645200 7200 1 CEST}
+    {1856394000 3600 0 CET}
+    {1869094800 7200 1 CEST}
+    {1887843600 3600 0 CET}
+    {1901149200 7200 1 CEST}
+    {1919293200 3600 0 CET}
+    {1932598800 7200 1 CEST}
+    {1950742800 3600 0 CET}
+    {1964048400 7200 1 CEST}
+    {1982797200 3600 0 CET}
+    {1995498000 7200 1 CEST}
+    {2014246800 3600 0 CET}
+    {2026947600 7200 1 CEST}
+    {2045696400 3600 0 CET}
+    {2058397200 7200 1 CEST}
+    {2077146000 3600 0 CET}
+    {2090451600 7200 1 CEST}
+    {2108595600 3600 0 CET}
+    {2121901200 7200 1 CEST}
+    {2140045200 3600 0 CET}
+    {2153350800 7200 1 CEST}
+    {2172099600 3600 0 CET}
+    {2184800400 7200 1 CEST}
+    {2203549200 3600 0 CET}
+    {2216250000 7200 1 CEST}
+    {2234998800 3600 0 CET}
+    {2248304400 7200 1 CEST}
+    {2266448400 3600 0 CET}
+    {2279754000 7200 1 CEST}
+    {2297898000 3600 0 CET}
+    {2311203600 7200 1 CEST}
+    {2329347600 3600 0 CET}
+    {2342653200 7200 1 CEST}
+    {2361402000 3600 0 CET}
+    {2374102800 7200 1 CEST}
+    {2392851600 3600 0 CET}
+    {2405552400 7200 1 CEST}
+    {2424301200 3600 0 CET}
+    {2437606800 7200 1 CEST}
+    {2455750800 3600 0 CET}
+    {2469056400 7200 1 CEST}
+    {2487200400 3600 0 CET}
+    {2500506000 7200 1 CEST}
+    {2519254800 3600 0 CET}
+    {2531955600 7200 1 CEST}
+    {2550704400 3600 0 CET}
+    {2563405200 7200 1 CEST}
+    {2582154000 3600 0 CET}
+    {2595459600 7200 1 CEST}
+    {2613603600 3600 0 CET}
+    {2626909200 7200 1 CEST}
+    {2645053200 3600 0 CET}
+    {2658358800 7200 1 CEST}
+    {2676502800 3600 0 CET}
+    {2689808400 7200 1 CEST}
+    {2708557200 3600 0 CET}
+    {2721258000 7200 1 CEST}
+    {2740006800 3600 0 CET}
+    {2752707600 7200 1 CEST}
+    {2771456400 3600 0 CET}
+    {2784762000 7200 1 CEST}
+    {2802906000 3600 0 CET}
+    {2816211600 7200 1 CEST}
+    {2834355600 3600 0 CET}
+    {2847661200 7200 1 CEST}
+    {2866410000 3600 0 CET}
+    {2879110800 7200 1 CEST}
+    {2897859600 3600 0 CET}
+    {2910560400 7200 1 CEST}
+    {2929309200 3600 0 CET}
+    {2942010000 7200 1 CEST}
+    {2960758800 3600 0 CET}
+    {2974064400 7200 1 CEST}
+    {2992208400 3600 0 CET}
+    {3005514000 7200 1 CEST}
+    {3023658000 3600 0 CET}
+    {3036963600 7200 1 CEST}
+    {3055712400 3600 0 CET}
+    {3068413200 7200 1 CEST}
+    {3087162000 3600 0 CET}
+    {3099862800 7200 1 CEST}
+    {3118611600 3600 0 CET}
+    {3131917200 7200 1 CEST}
+    {3150061200 3600 0 CET}
+    {3163366800 7200 1 CEST}
+    {3181510800 3600 0 CET}
+    {3194816400 7200 1 CEST}
+    {3212960400 3600 0 CET}
+    {3226266000 7200 1 CEST}
+    {3245014800 3600 0 CET}
+    {3257715600 7200 1 CEST}
+    {3276464400 3600 0 CET}
+    {3289165200 7200 1 CEST}
+    {3307914000 3600 0 CET}
+    {3321219600 7200 1 CEST}
+    {3339363600 3600 0 CET}
+    {3352669200 7200 1 CEST}
+    {3370813200 3600 0 CET}
+    {3384118800 7200 1 CEST}
+    {3402867600 3600 0 CET}
+    {3415568400 7200 1 CEST}
+    {3434317200 3600 0 CET}
+    {3447018000 7200 1 CEST}
+    {3465766800 3600 0 CET}
+    {3479072400 7200 1 CEST}
+    {3497216400 3600 0 CET}
+    {3510522000 7200 1 CEST}
+    {3528666000 3600 0 CET}
+    {3541971600 7200 1 CEST}
+    {3560115600 3600 0 CET}
+    {3573421200 7200 1 CEST}
+    {3592170000 3600 0 CET}
+    {3604870800 7200 1 CEST}
+    {3623619600 3600 0 CET}
+    {3636320400 7200 1 CEST}
+    {3655069200 3600 0 CET}
+    {3668374800 7200 1 CEST}
+    {3686518800 3600 0 CET}
+    {3699824400 7200 1 CEST}
+    {3717968400 3600 0 CET}
+    {3731274000 7200 1 CEST}
+    {3750022800 3600 0 CET}
+    {3762723600 7200 1 CEST}
+    {3781472400 3600 0 CET}
+    {3794173200 7200 1 CEST}
+    {3812922000 3600 0 CET}
+    {3825622800 7200 1 CEST}
+    {3844371600 3600 0 CET}
+    {3857677200 7200 1 CEST}
+    {3875821200 3600 0 CET}
+    {3889126800 7200 1 CEST}
+    {3907270800 3600 0 CET}
+    {3920576400 7200 1 CEST}
+    {3939325200 3600 0 CET}
+    {3952026000 7200 1 CEST}
+    {3970774800 3600 0 CET}
+    {3983475600 7200 1 CEST}
+    {4002224400 3600 0 CET}
+    {4015530000 7200 1 CEST}
+    {4033674000 3600 0 CET}
+    {4046979600 7200 1 CEST}
+    {4065123600 3600 0 CET}
+    {4078429200 7200 1 CEST}
+    {4096573200 3600 0 CET}
+}
diff --git a/library/tzdata/GB b/library/tzdata/GB
new file mode 100644
index 0000000..72d77ee
--- /dev/null
+++ b/library/tzdata/GB
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Europe/London)]} {
+    LoadTimeZoneFile Europe/London
+}
+set TZData(:GB) $TZData(:Europe/London)
diff --git a/library/tzdata/GB-Eire b/library/tzdata/GB-Eire
new file mode 100644
index 0000000..1622417
--- /dev/null
+++ b/library/tzdata/GB-Eire
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Europe/London)]} {
+    LoadTimeZoneFile Europe/London
+}
+set TZData(:GB-Eire) $TZData(:Europe/London)
diff --git a/library/tzdata/GMT b/library/tzdata/GMT
new file mode 100644
index 0000000..4258564
--- /dev/null
+++ b/library/tzdata/GMT
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Etc/GMT)]} {
+    LoadTimeZoneFile Etc/GMT
+}
+set TZData(:GMT) $TZData(:Etc/GMT)
diff --git a/library/tzdata/GMT+0 b/library/tzdata/GMT+0
new file mode 100644
index 0000000..a1e8126
--- /dev/null
+++ b/library/tzdata/GMT+0
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Etc/GMT)]} {
+    LoadTimeZoneFile Etc/GMT
+}
+set TZData(:GMT+0) $TZData(:Etc/GMT)
diff --git a/library/tzdata/GMT-0 b/library/tzdata/GMT-0
new file mode 100644
index 0000000..04ccafe
--- /dev/null
+++ b/library/tzdata/GMT-0
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Etc/GMT)]} {
+    LoadTimeZoneFile Etc/GMT
+}
+set TZData(:GMT-0) $TZData(:Etc/GMT)
diff --git a/library/tzdata/GMT0 b/library/tzdata/GMT0
new file mode 100644
index 0000000..92e95a3
--- /dev/null
+++ b/library/tzdata/GMT0
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Etc/GMT)]} {
+    LoadTimeZoneFile Etc/GMT
+}
+set TZData(:GMT0) $TZData(:Etc/GMT)
diff --git a/library/tzdata/Greenwich b/library/tzdata/Greenwich
new file mode 100644
index 0000000..6115233
--- /dev/null
+++ b/library/tzdata/Greenwich
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Etc/GMT)]} {
+    LoadTimeZoneFile Etc/GMT
+}
+set TZData(:Greenwich) $TZData(:Etc/GMT)
diff --git a/library/tzdata/HST b/library/tzdata/HST
new file mode 100644
index 0000000..fea7f14
--- /dev/null
+++ b/library/tzdata/HST
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:HST) {
+    {-9223372036854775808 -36000 0 HST}
+}
diff --git a/library/tzdata/Hongkong b/library/tzdata/Hongkong
new file mode 100644
index 0000000..f9d4dac
--- /dev/null
+++ b/library/tzdata/Hongkong
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Asia/Hong_Kong)]} {
+    LoadTimeZoneFile Asia/Hong_Kong
+}
+set TZData(:Hongkong) $TZData(:Asia/Hong_Kong)
diff --git a/library/tzdata/Iceland b/library/tzdata/Iceland
new file mode 100644
index 0000000..eb3f3eb
--- /dev/null
+++ b/library/tzdata/Iceland
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Atlantic/Reykjavik)]} {
+    LoadTimeZoneFile Atlantic/Reykjavik
+}
+set TZData(:Iceland) $TZData(:Atlantic/Reykjavik)
diff --git a/library/tzdata/Indian/Antananarivo b/library/tzdata/Indian/Antananarivo
new file mode 100644
index 0000000..c56a893
--- /dev/null
+++ b/library/tzdata/Indian/Antananarivo
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Africa/Nairobi)]} {
+    LoadTimeZoneFile Africa/Nairobi
+}
+set TZData(:Indian/Antananarivo) $TZData(:Africa/Nairobi)
diff --git a/library/tzdata/Indian/Chagos b/library/tzdata/Indian/Chagos
new file mode 100644
index 0000000..a5cec61
--- /dev/null
+++ b/library/tzdata/Indian/Chagos
@@ -0,0 +1,7 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Indian/Chagos) {
+    {-9223372036854775808 17380 0 LMT}
+    {-1988167780 18000 0 IOT}
+    {820436400 21600 0 IOT}
+}
diff --git a/library/tzdata/Indian/Christmas b/library/tzdata/Indian/Christmas
new file mode 100644
index 0000000..c36e973
--- /dev/null
+++ b/library/tzdata/Indian/Christmas
@@ -0,0 +1,6 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Indian/Christmas) {
+    {-9223372036854775808 25372 0 LMT}
+    {-2364102172 25200 0 CXT}
+}
diff --git a/library/tzdata/Indian/Cocos b/library/tzdata/Indian/Cocos
new file mode 100644
index 0000000..a63ae68
--- /dev/null
+++ b/library/tzdata/Indian/Cocos
@@ -0,0 +1,6 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Indian/Cocos) {
+    {-9223372036854775808 23260 0 LMT}
+    {-2209012060 23400 0 CCT}
+}
diff --git a/library/tzdata/Indian/Comoro b/library/tzdata/Indian/Comoro
new file mode 100644
index 0000000..06071de
--- /dev/null
+++ b/library/tzdata/Indian/Comoro
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Africa/Nairobi)]} {
+    LoadTimeZoneFile Africa/Nairobi
+}
+set TZData(:Indian/Comoro) $TZData(:Africa/Nairobi)
diff --git a/library/tzdata/Indian/Kerguelen b/library/tzdata/Indian/Kerguelen
new file mode 100644
index 0000000..8820010
--- /dev/null
+++ b/library/tzdata/Indian/Kerguelen
@@ -0,0 +1,6 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Indian/Kerguelen) {
+    {-9223372036854775808 0 0 -00}
+    {-631152000 18000 0 TFT}
+}
diff --git a/library/tzdata/Indian/Mahe b/library/tzdata/Indian/Mahe
new file mode 100644
index 0000000..c88a24b
--- /dev/null
+++ b/library/tzdata/Indian/Mahe
@@ -0,0 +1,6 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Indian/Mahe) {
+    {-9223372036854775808 13308 0 LMT}
+    {-2006653308 14400 0 SCT}
+}
diff --git a/library/tzdata/Indian/Maldives b/library/tzdata/Indian/Maldives
new file mode 100644
index 0000000..2c2c739
--- /dev/null
+++ b/library/tzdata/Indian/Maldives
@@ -0,0 +1,7 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Indian/Maldives) {
+    {-9223372036854775808 17640 0 LMT}
+    {-2840158440 17640 0 MMT}
+    {-315636840 18000 0 MVT}
+}
diff --git a/library/tzdata/Indian/Mauritius b/library/tzdata/Indian/Mauritius
new file mode 100644
index 0000000..a9c07eb
--- /dev/null
+++ b/library/tzdata/Indian/Mauritius
@@ -0,0 +1,10 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Indian/Mauritius) {
+    {-9223372036854775808 13800 0 LMT}
+    {-1988164200 14400 0 MUT}
+    {403041600 18000 1 MUST}
+    {417034800 14400 0 MUT}
+    {1224972000 18000 1 MUST}
+    {1238274000 14400 0 MUT}
+}
diff --git a/library/tzdata/Indian/Mayotte b/library/tzdata/Indian/Mayotte
new file mode 100644
index 0000000..da55521
--- /dev/null
+++ b/library/tzdata/Indian/Mayotte
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Africa/Nairobi)]} {
+    LoadTimeZoneFile Africa/Nairobi
+}
+set TZData(:Indian/Mayotte) $TZData(:Africa/Nairobi)
diff --git a/library/tzdata/Indian/Reunion b/library/tzdata/Indian/Reunion
new file mode 100644
index 0000000..de2dd60
--- /dev/null
+++ b/library/tzdata/Indian/Reunion
@@ -0,0 +1,6 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Indian/Reunion) {
+    {-9223372036854775808 13312 0 LMT}
+    {-1848886912 14400 0 RET}
+}
diff --git a/library/tzdata/Iran b/library/tzdata/Iran
new file mode 100644
index 0000000..e200b4d
--- /dev/null
+++ b/library/tzdata/Iran
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Asia/Tehran)]} {
+    LoadTimeZoneFile Asia/Tehran
+}
+set TZData(:Iran) $TZData(:Asia/Tehran)
diff --git a/library/tzdata/Israel b/library/tzdata/Israel
new file mode 100644
index 0000000..af521f5
--- /dev/null
+++ b/library/tzdata/Israel
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Asia/Jerusalem)]} {
+    LoadTimeZoneFile Asia/Jerusalem
+}
+set TZData(:Israel) $TZData(:Asia/Jerusalem)
diff --git a/library/tzdata/Jamaica b/library/tzdata/Jamaica
new file mode 100644
index 0000000..ddb5d45
--- /dev/null
+++ b/library/tzdata/Jamaica
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(America/Jamaica)]} {
+    LoadTimeZoneFile America/Jamaica
+}
+set TZData(:Jamaica) $TZData(:America/Jamaica)
diff --git a/library/tzdata/Japan b/library/tzdata/Japan
new file mode 100644
index 0000000..428a79f
--- /dev/null
+++ b/library/tzdata/Japan
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Asia/Tokyo)]} {
+    LoadTimeZoneFile Asia/Tokyo
+}
+set TZData(:Japan) $TZData(:Asia/Tokyo)
diff --git a/library/tzdata/Kwajalein b/library/tzdata/Kwajalein
new file mode 100644
index 0000000..586db6d
--- /dev/null
+++ b/library/tzdata/Kwajalein
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Pacific/Kwajalein)]} {
+    LoadTimeZoneFile Pacific/Kwajalein
+}
+set TZData(:Kwajalein) $TZData(:Pacific/Kwajalein)
diff --git a/library/tzdata/Libya b/library/tzdata/Libya
new file mode 100644
index 0000000..6cd77e1
--- /dev/null
+++ b/library/tzdata/Libya
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Africa/Tripoli)]} {
+    LoadTimeZoneFile Africa/Tripoli
+}
+set TZData(:Libya) $TZData(:Africa/Tripoli)
diff --git a/library/tzdata/MET b/library/tzdata/MET
new file mode 100644
index 0000000..8789c97
--- /dev/null
+++ b/library/tzdata/MET
@@ -0,0 +1,265 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:MET) {
+    {-9223372036854775808 3600 0 MET}
+    {-1693706400 7200 1 MEST}
+    {-1680483600 3600 0 MET}
+    {-1663455600 7200 1 MEST}
+    {-1650150000 3600 0 MET}
+    {-1632006000 7200 1 MEST}
+    {-1618700400 3600 0 MET}
+    {-938905200 7200 1 MEST}
+    {-857257200 3600 0 MET}
+    {-844556400 7200 1 MEST}
+    {-828226800 3600 0 MET}
+    {-812502000 7200 1 MEST}
+    {-796777200 3600 0 MET}
+    {-781052400 7200 1 MEST}
+    {-766623600 3600 0 MET}
+    {228877200 7200 1 MEST}
+    {243997200 3600 0 MET}
+    {260326800 7200 1 MEST}
+    {276051600 3600 0 MET}
+    {291776400 7200 1 MEST}
+    {307501200 3600 0 MET}
+    {323830800 7200 1 MEST}
+    {338950800 3600 0 MET}
+    {354675600 7200 1 MEST}
+    {370400400 3600 0 MET}
+    {386125200 7200 1 MEST}
+    {401850000 3600 0 MET}
+    {417574800 7200 1 MEST}
+    {433299600 3600 0 MET}
+    {449024400 7200 1 MEST}
+    {465354000 3600 0 MET}
+    {481078800 7200 1 MEST}
+    {496803600 3600 0 MET}
+    {512528400 7200 1 MEST}
+    {528253200 3600 0 MET}
+    {543978000 7200 1 MEST}
+    {559702800 3600 0 MET}
+    {575427600 7200 1 MEST}
+    {591152400 3600 0 MET}
+    {606877200 7200 1 MEST}
+    {622602000 3600 0 MET}
+    {638326800 7200 1 MEST}
+    {654656400 3600 0 MET}
+    {670381200 7200 1 MEST}
+    {686106000 3600 0 MET}
+    {701830800 7200 1 MEST}
+    {717555600 3600 0 MET}
+    {733280400 7200 1 MEST}
+    {749005200 3600 0 MET}
+    {764730000 7200 1 MEST}
+    {780454800 3600 0 MET}
+    {796179600 7200 1 MEST}
+    {811904400 3600 0 MET}
+    {828234000 7200 1 MEST}
+    {846378000 3600 0 MET}
+    {859683600 7200 1 MEST}
+    {877827600 3600 0 MET}
+    {891133200 7200 1 MEST}
+    {909277200 3600 0 MET}
+    {922582800 7200 1 MEST}
+    {941331600 3600 0 MET}
+    {954032400 7200 1 MEST}
+    {972781200 3600 0 MET}
+    {985482000 7200 1 MEST}
+    {1004230800 3600 0 MET}
+    {1017536400 7200 1 MEST}
+    {1035680400 3600 0 MET}
+    {1048986000 7200 1 MEST}
+    {1067130000 3600 0 MET}
+    {1080435600 7200 1 MEST}
+    {1099184400 3600 0 MET}
+    {1111885200 7200 1 MEST}
+    {1130634000 3600 0 MET}
+    {1143334800 7200 1 MEST}
+    {1162083600 3600 0 MET}
+    {1174784400 7200 1 MEST}
+    {1193533200 3600 0 MET}
+    {1206838800 7200 1 MEST}
+    {1224982800 3600 0 MET}
+    {1238288400 7200 1 MEST}
+    {1256432400 3600 0 MET}
+    {1269738000 7200 1 MEST}
+    {1288486800 3600 0 MET}
+    {1301187600 7200 1 MEST}
+    {1319936400 3600 0 MET}
+    {1332637200 7200 1 MEST}
+    {1351386000 3600 0 MET}
+    {1364691600 7200 1 MEST}
+    {1382835600 3600 0 MET}
+    {1396141200 7200 1 MEST}
+    {1414285200 3600 0 MET}
+    {1427590800 7200 1 MEST}
+    {1445734800 3600 0 MET}
+    {1459040400 7200 1 MEST}
+    {1477789200 3600 0 MET}
+    {1490490000 7200 1 MEST}
+    {1509238800 3600 0 MET}
+    {1521939600 7200 1 MEST}
+    {1540688400 3600 0 MET}
+    {1553994000 7200 1 MEST}
+    {1572138000 3600 0 MET}
+    {1585443600 7200 1 MEST}
+    {1603587600 3600 0 MET}
+    {1616893200 7200 1 MEST}
+    {1635642000 3600 0 MET}
+    {1648342800 7200 1 MEST}
+    {1667091600 3600 0 MET}
+    {1679792400 7200 1 MEST}
+    {1698541200 3600 0 MET}
+    {1711846800 7200 1 MEST}
+    {1729990800 3600 0 MET}
+    {1743296400 7200 1 MEST}
+    {1761440400 3600 0 MET}
+    {1774746000 7200 1 MEST}
+    {1792890000 3600 0 MET}
+    {1806195600 7200 1 MEST}
+    {1824944400 3600 0 MET}
+    {1837645200 7200 1 MEST}
+    {1856394000 3600 0 MET}
+    {1869094800 7200 1 MEST}
+    {1887843600 3600 0 MET}
+    {1901149200 7200 1 MEST}
+    {1919293200 3600 0 MET}
+    {1932598800 7200 1 MEST}
+    {1950742800 3600 0 MET}
+    {1964048400 7200 1 MEST}
+    {1982797200 3600 0 MET}
+    {1995498000 7200 1 MEST}
+    {2014246800 3600 0 MET}
+    {2026947600 7200 1 MEST}
+    {2045696400 3600 0 MET}
+    {2058397200 7200 1 MEST}
+    {2077146000 3600 0 MET}
+    {2090451600 7200 1 MEST}
+    {2108595600 3600 0 MET}
+    {2121901200 7200 1 MEST}
+    {2140045200 3600 0 MET}
+    {2153350800 7200 1 MEST}
+    {2172099600 3600 0 MET}
+    {2184800400 7200 1 MEST}
+    {2203549200 3600 0 MET}
+    {2216250000 7200 1 MEST}
+    {2234998800 3600 0 MET}
+    {2248304400 7200 1 MEST}
+    {2266448400 3600 0 MET}
+    {2279754000 7200 1 MEST}
+    {2297898000 3600 0 MET}
+    {2311203600 7200 1 MEST}
+    {2329347600 3600 0 MET}
+    {2342653200 7200 1 MEST}
+    {2361402000 3600 0 MET}
+    {2374102800 7200 1 MEST}
+    {2392851600 3600 0 MET}
+    {2405552400 7200 1 MEST}
+    {2424301200 3600 0 MET}
+    {2437606800 7200 1 MEST}
+    {2455750800 3600 0 MET}
+    {2469056400 7200 1 MEST}
+    {2487200400 3600 0 MET}
+    {2500506000 7200 1 MEST}
+    {2519254800 3600 0 MET}
+    {2531955600 7200 1 MEST}
+    {2550704400 3600 0 MET}
+    {2563405200 7200 1 MEST}
+    {2582154000 3600 0 MET}
+    {2595459600 7200 1 MEST}
+    {2613603600 3600 0 MET}
+    {2626909200 7200 1 MEST}
+    {2645053200 3600 0 MET}
+    {2658358800 7200 1 MEST}
+    {2676502800 3600 0 MET}
+    {2689808400 7200 1 MEST}
+    {2708557200 3600 0 MET}
+    {2721258000 7200 1 MEST}
+    {2740006800 3600 0 MET}
+    {2752707600 7200 1 MEST}
+    {2771456400 3600 0 MET}
+    {2784762000 7200 1 MEST}
+    {2802906000 3600 0 MET}
+    {2816211600 7200 1 MEST}
+    {2834355600 3600 0 MET}
+    {2847661200 7200 1 MEST}
+    {2866410000 3600 0 MET}
+    {2879110800 7200 1 MEST}
+    {2897859600 3600 0 MET}
+    {2910560400 7200 1 MEST}
+    {2929309200 3600 0 MET}
+    {2942010000 7200 1 MEST}
+    {2960758800 3600 0 MET}
+    {2974064400 7200 1 MEST}
+    {2992208400 3600 0 MET}
+    {3005514000 7200 1 MEST}
+    {3023658000 3600 0 MET}
+    {3036963600 7200 1 MEST}
+    {3055712400 3600 0 MET}
+    {3068413200 7200 1 MEST}
+    {3087162000 3600 0 MET}
+    {3099862800 7200 1 MEST}
+    {3118611600 3600 0 MET}
+    {3131917200 7200 1 MEST}
+    {3150061200 3600 0 MET}
+    {3163366800 7200 1 MEST}
+    {3181510800 3600 0 MET}
+    {3194816400 7200 1 MEST}
+    {3212960400 3600 0 MET}
+    {3226266000 7200 1 MEST}
+    {3245014800 3600 0 MET}
+    {3257715600 7200 1 MEST}
+    {3276464400 3600 0 MET}
+    {3289165200 7200 1 MEST}
+    {3307914000 3600 0 MET}
+    {3321219600 7200 1 MEST}
+    {3339363600 3600 0 MET}
+    {3352669200 7200 1 MEST}
+    {3370813200 3600 0 MET}
+    {3384118800 7200 1 MEST}
+    {3402867600 3600 0 MET}
+    {3415568400 7200 1 MEST}
+    {3434317200 3600 0 MET}
+    {3447018000 7200 1 MEST}
+    {3465766800 3600 0 MET}
+    {3479072400 7200 1 MEST}
+    {3497216400 3600 0 MET}
+    {3510522000 7200 1 MEST}
+    {3528666000 3600 0 MET}
+    {3541971600 7200 1 MEST}
+    {3560115600 3600 0 MET}
+    {3573421200 7200 1 MEST}
+    {3592170000 3600 0 MET}
+    {3604870800 7200 1 MEST}
+    {3623619600 3600 0 MET}
+    {3636320400 7200 1 MEST}
+    {3655069200 3600 0 MET}
+    {3668374800 7200 1 MEST}
+    {3686518800 3600 0 MET}
+    {3699824400 7200 1 MEST}
+    {3717968400 3600 0 MET}
+    {3731274000 7200 1 MEST}
+    {3750022800 3600 0 MET}
+    {3762723600 7200 1 MEST}
+    {3781472400 3600 0 MET}
+    {3794173200 7200 1 MEST}
+    {3812922000 3600 0 MET}
+    {3825622800 7200 1 MEST}
+    {3844371600 3600 0 MET}
+    {3857677200 7200 1 MEST}
+    {3875821200 3600 0 MET}
+    {3889126800 7200 1 MEST}
+    {3907270800 3600 0 MET}
+    {3920576400 7200 1 MEST}
+    {3939325200 3600 0 MET}
+    {3952026000 7200 1 MEST}
+    {3970774800 3600 0 MET}
+    {3983475600 7200 1 MEST}
+    {4002224400 3600 0 MET}
+    {4015530000 7200 1 MEST}
+    {4033674000 3600 0 MET}
+    {4046979600 7200 1 MEST}
+    {4065123600 3600 0 MET}
+    {4078429200 7200 1 MEST}
+    {4096573200 3600 0 MET}
+}
diff --git a/library/tzdata/MST b/library/tzdata/MST
new file mode 100644
index 0000000..8c967ab
--- /dev/null
+++ b/library/tzdata/MST
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:MST) {
+    {-9223372036854775808 -25200 0 MST}
+}
diff --git a/library/tzdata/MST7MDT b/library/tzdata/MST7MDT
new file mode 100644
index 0000000..ff52048
--- /dev/null
+++ b/library/tzdata/MST7MDT
@@ -0,0 +1,278 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:MST7MDT) {
+    {-9223372036854775808 -25200 0 MST}
+    {-1633273200 -21600 1 MDT}
+    {-1615132800 -25200 0 MST}
+    {-1601823600 -21600 1 MDT}
+    {-1583683200 -25200 0 MST}
+    {-880210800 -21600 1 MWT}
+    {-769395600 -21600 1 MPT}
+    {-765388800 -25200 0 MST}
+    {-84380400 -21600 1 MDT}
+    {-68659200 -25200 0 MST}
+    {-52930800 -21600 1 MDT}
+    {-37209600 -25200 0 MST}
+    {-21481200 -21600 1 MDT}
+    {-5760000 -25200 0 MST}
+    {9968400 -21600 1 MDT}
+    {25689600 -25200 0 MST}
+    {41418000 -21600 1 MDT}
+    {57744000 -25200 0 MST}
+    {73472400 -21600 1 MDT}
+    {89193600 -25200 0 MST}
+    {104922000 -21600 1 MDT}
+    {120643200 -25200 0 MST}
+    {126694800 -21600 1 MDT}
+    {152092800 -25200 0 MST}
+    {162378000 -21600 1 MDT}
+    {183542400 -25200 0 MST}
+    {199270800 -21600 1 MDT}
+    {215596800 -25200 0 MST}
+    {230720400 -21600 1 MDT}
+    {247046400 -25200 0 MST}
+    {262774800 -21600 1 MDT}
+    {278496000 -25200 0 MST}
+    {294224400 -21600 1 MDT}
+    {309945600 -25200 0 MST}
+    {325674000 -21600 1 MDT}
+    {341395200 -25200 0 MST}
+    {357123600 -21600 1 MDT}
+    {372844800 -25200 0 MST}
+    {388573200 -21600 1 MDT}
+    {404899200 -25200 0 MST}
+    {420022800 -21600 1 MDT}
+    {436348800 -25200 0 MST}
+    {452077200 -21600 1 MDT}
+    {467798400 -25200 0 MST}
+    {483526800 -21600 1 MDT}
+    {499248000 -25200 0 MST}
+    {514976400 -21600 1 MDT}
+    {530697600 -25200 0 MST}
+    {544611600 -21600 1 MDT}
+    {562147200 -25200 0 MST}
+    {576061200 -21600 1 MDT}
+    {594201600 -25200 0 MST}
+    {607510800 -21600 1 MDT}
+    {625651200 -25200 0 MST}
+    {638960400 -21600 1 MDT}
+    {657100800 -25200 0 MST}
+    {671014800 -21600 1 MDT}
+    {688550400 -25200 0 MST}
+    {702464400 -21600 1 MDT}
+    {720000000 -25200 0 MST}
+    {733914000 -21600 1 MDT}
+    {752054400 -25200 0 MST}
+    {765363600 -21600 1 MDT}
+    {783504000 -25200 0 MST}
+    {796813200 -21600 1 MDT}
+    {814953600 -25200 0 MST}
+    {828867600 -21600 1 MDT}
+    {846403200 -25200 0 MST}
+    {860317200 -21600 1 MDT}
+    {877852800 -25200 0 MST}
+    {891766800 -21600 1 MDT}
+    {909302400 -25200 0 MST}
+    {923216400 -21600 1 MDT}
+    {941356800 -25200 0 MST}
+    {954666000 -21600 1 MDT}
+    {972806400 -25200 0 MST}
+    {986115600 -21600 1 MDT}
+    {1004256000 -25200 0 MST}
+    {1018170000 -21600 1 MDT}
+    {1035705600 -25200 0 MST}
+    {1049619600 -21600 1 MDT}
+    {1067155200 -25200 0 MST}
+    {1081069200 -21600 1 MDT}
+    {1099209600 -25200 0 MST}
+    {1112518800 -21600 1 MDT}
+    {1130659200 -25200 0 MST}
+    {1143968400 -21600 1 MDT}
+    {1162108800 -25200 0 MST}
+    {1173603600 -21600 1 MDT}
+    {1194163200 -25200 0 MST}
+    {1205053200 -21600 1 MDT}
+    {1225612800 -25200 0 MST}
+    {1236502800 -21600 1 MDT}
+    {1257062400 -25200 0 MST}
+    {1268557200 -21600 1 MDT}
+    {1289116800 -25200 0 MST}
+    {1300006800 -21600 1 MDT}
+    {1320566400 -25200 0 MST}
+    {1331456400 -21600 1 MDT}
+    {1352016000 -25200 0 MST}
+    {1362906000 -21600 1 MDT}
+    {1383465600 -25200 0 MST}
+    {1394355600 -21600 1 MDT}
+    {1414915200 -25200 0 MST}
+    {1425805200 -21600 1 MDT}
+    {1446364800 -25200 0 MST}
+    {1457859600 -21600 1 MDT}
+    {1478419200 -25200 0 MST}
+    {1489309200 -21600 1 MDT}
+    {1509868800 -25200 0 MST}
+    {1520758800 -21600 1 MDT}
+    {1541318400 -25200 0 MST}
+    {1552208400 -21600 1 MDT}
+    {1572768000 -25200 0 MST}
+    {1583658000 -21600 1 MDT}
+    {1604217600 -25200 0 MST}
+    {1615712400 -21600 1 MDT}
+    {1636272000 -25200 0 MST}
+    {1647162000 -21600 1 MDT}
+    {1667721600 -25200 0 MST}
+    {1678611600 -21600 1 MDT}
+    {1699171200 -25200 0 MST}
+    {1710061200 -21600 1 MDT}
+    {1730620800 -25200 0 MST}
+    {1741510800 -21600 1 MDT}
+    {1762070400 -25200 0 MST}
+    {1772960400 -21600 1 MDT}
+    {1793520000 -25200 0 MST}
+    {1805014800 -21600 1 MDT}
+    {1825574400 -25200 0 MST}
+    {1836464400 -21600 1 MDT}
+    {1857024000 -25200 0 MST}
+    {1867914000 -21600 1 MDT}
+    {1888473600 -25200 0 MST}
+    {1899363600 -21600 1 MDT}
+    {1919923200 -25200 0 MST}
+    {1930813200 -21600 1 MDT}
+    {1951372800 -25200 0 MST}
+    {1962867600 -21600 1 MDT}
+    {1983427200 -25200 0 MST}
+    {1994317200 -21600 1 MDT}
+    {2014876800 -25200 0 MST}
+    {2025766800 -21600 1 MDT}
+    {2046326400 -25200 0 MST}
+    {2057216400 -21600 1 MDT}
+    {2077776000 -25200 0 MST}
+    {2088666000 -21600 1 MDT}
+    {2109225600 -25200 0 MST}
+    {2120115600 -21600 1 MDT}
+    {2140675200 -25200 0 MST}
+    {2152170000 -21600 1 MDT}
+    {2172729600 -25200 0 MST}
+    {2183619600 -21600 1 MDT}
+    {2204179200 -25200 0 MST}
+    {2215069200 -21600 1 MDT}
+    {2235628800 -25200 0 MST}
+    {2246518800 -21600 1 MDT}
+    {2267078400 -25200 0 MST}
+    {2277968400 -21600 1 MDT}
+    {2298528000 -25200 0 MST}
+    {2309418000 -21600 1 MDT}
+    {2329977600 -25200 0 MST}
+    {2341472400 -21600 1 MDT}
+    {2362032000 -25200 0 MST}
+    {2372922000 -21600 1 MDT}
+    {2393481600 -25200 0 MST}
+    {2404371600 -21600 1 MDT}
+    {2424931200 -25200 0 MST}
+    {2435821200 -21600 1 MDT}
+    {2456380800 -25200 0 MST}
+    {2467270800 -21600 1 MDT}
+    {2487830400 -25200 0 MST}
+    {2499325200 -21600 1 MDT}
+    {2519884800 -25200 0 MST}
+    {2530774800 -21600 1 MDT}
+    {2551334400 -25200 0 MST}
+    {2562224400 -21600 1 MDT}
+    {2582784000 -25200 0 MST}
+    {2593674000 -21600 1 MDT}
+    {2614233600 -25200 0 MST}
+    {2625123600 -21600 1 MDT}
+    {2645683200 -25200 0 MST}
+    {2656573200 -21600 1 MDT}
+    {2677132800 -25200 0 MST}
+    {2688627600 -21600 1 MDT}
+    {2709187200 -25200 0 MST}
+    {2720077200 -21600 1 MDT}
+    {2740636800 -25200 0 MST}
+    {2751526800 -21600 1 MDT}
+    {2772086400 -25200 0 MST}
+    {2782976400 -21600 1 MDT}
+    {2803536000 -25200 0 MST}
+    {2814426000 -21600 1 MDT}
+    {2834985600 -25200 0 MST}
+    {2846480400 -21600 1 MDT}
+    {2867040000 -25200 0 MST}
+    {2877930000 -21600 1 MDT}
+    {2898489600 -25200 0 MST}
+    {2909379600 -21600 1 MDT}
+    {2929939200 -25200 0 MST}
+    {2940829200 -21600 1 MDT}
+    {2961388800 -25200 0 MST}
+    {2972278800 -21600 1 MDT}
+    {2992838400 -25200 0 MST}
+    {3003728400 -21600 1 MDT}
+    {3024288000 -25200 0 MST}
+    {3035782800 -21600 1 MDT}
+    {3056342400 -25200 0 MST}
+    {3067232400 -21600 1 MDT}
+    {3087792000 -25200 0 MST}
+    {3098682000 -21600 1 MDT}
+    {3119241600 -25200 0 MST}
+    {3130131600 -21600 1 MDT}
+    {3150691200 -25200 0 MST}
+    {3161581200 -21600 1 MDT}
+    {3182140800 -25200 0 MST}
+    {3193030800 -21600 1 MDT}
+    {3213590400 -25200 0 MST}
+    {3225085200 -21600 1 MDT}
+    {3245644800 -25200 0 MST}
+    {3256534800 -21600 1 MDT}
+    {3277094400 -25200 0 MST}
+    {3287984400 -21600 1 MDT}
+    {3308544000 -25200 0 MST}
+    {3319434000 -21600 1 MDT}
+    {3339993600 -25200 0 MST}
+    {3350883600 -21600 1 MDT}
+    {3371443200 -25200 0 MST}
+    {3382938000 -21600 1 MDT}
+    {3403497600 -25200 0 MST}
+    {3414387600 -21600 1 MDT}
+    {3434947200 -25200 0 MST}
+    {3445837200 -21600 1 MDT}
+    {3466396800 -25200 0 MST}
+    {3477286800 -21600 1 MDT}
+    {3497846400 -25200 0 MST}
+    {3508736400 -21600 1 MDT}
+    {3529296000 -25200 0 MST}
+    {3540186000 -21600 1 MDT}
+    {3560745600 -25200 0 MST}
+    {3572240400 -21600 1 MDT}
+    {3592800000 -25200 0 MST}
+    {3603690000 -21600 1 MDT}
+    {3624249600 -25200 0 MST}
+    {3635139600 -21600 1 MDT}
+    {3655699200 -25200 0 MST}
+    {3666589200 -21600 1 MDT}
+    {3687148800 -25200 0 MST}
+    {3698038800 -21600 1 MDT}
+    {3718598400 -25200 0 MST}
+    {3730093200 -21600 1 MDT}
+    {3750652800 -25200 0 MST}
+    {3761542800 -21600 1 MDT}
+    {3782102400 -25200 0 MST}
+    {3792992400 -21600 1 MDT}
+    {3813552000 -25200 0 MST}
+    {3824442000 -21600 1 MDT}
+    {3845001600 -25200 0 MST}
+    {3855891600 -21600 1 MDT}
+    {3876451200 -25200 0 MST}
+    {3887341200 -21600 1 MDT}
+    {3907900800 -25200 0 MST}
+    {3919395600 -21600 1 MDT}
+    {3939955200 -25200 0 MST}
+    {3950845200 -21600 1 MDT}
+    {3971404800 -25200 0 MST}
+    {3982294800 -21600 1 MDT}
+    {4002854400 -25200 0 MST}
+    {4013744400 -21600 1 MDT}
+    {4034304000 -25200 0 MST}
+    {4045194000 -21600 1 MDT}
+    {4065753600 -25200 0 MST}
+    {4076643600 -21600 1 MDT}
+    {4097203200 -25200 0 MST}
+}
diff --git a/library/tzdata/Mexico/BajaNorte b/library/tzdata/Mexico/BajaNorte
new file mode 100644
index 0000000..8f6f459
--- /dev/null
+++ b/library/tzdata/Mexico/BajaNorte
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(America/Tijuana)]} {
+    LoadTimeZoneFile America/Tijuana
+}
+set TZData(:Mexico/BajaNorte) $TZData(:America/Tijuana)
diff --git a/library/tzdata/Mexico/BajaSur b/library/tzdata/Mexico/BajaSur
new file mode 100644
index 0000000..6d335a1
--- /dev/null
+++ b/library/tzdata/Mexico/BajaSur
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(America/Mazatlan)]} {
+    LoadTimeZoneFile America/Mazatlan
+}
+set TZData(:Mexico/BajaSur) $TZData(:America/Mazatlan)
diff --git a/library/tzdata/Mexico/General b/library/tzdata/Mexico/General
new file mode 100644
index 0000000..0cac92f
--- /dev/null
+++ b/library/tzdata/Mexico/General
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(America/Mexico_City)]} {
+    LoadTimeZoneFile America/Mexico_City
+}
+set TZData(:Mexico/General) $TZData(:America/Mexico_City)
diff --git a/library/tzdata/NZ b/library/tzdata/NZ
new file mode 100644
index 0000000..36d22a7
--- /dev/null
+++ b/library/tzdata/NZ
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Pacific/Auckland)]} {
+    LoadTimeZoneFile Pacific/Auckland
+}
+set TZData(:NZ) $TZData(:Pacific/Auckland)
diff --git a/library/tzdata/NZ-CHAT b/library/tzdata/NZ-CHAT
new file mode 100644
index 0000000..7f7c918
--- /dev/null
+++ b/library/tzdata/NZ-CHAT
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Pacific/Chatham)]} {
+    LoadTimeZoneFile Pacific/Chatham
+}
+set TZData(:NZ-CHAT) $TZData(:Pacific/Chatham)
diff --git a/library/tzdata/Navajo b/library/tzdata/Navajo
new file mode 100644
index 0000000..78cc2e2
--- /dev/null
+++ b/library/tzdata/Navajo
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(America/Denver)]} {
+    LoadTimeZoneFile America/Denver
+}
+set TZData(:Navajo) $TZData(:America/Denver)
diff --git a/library/tzdata/PRC b/library/tzdata/PRC
new file mode 100644
index 0000000..1d8bb7c
--- /dev/null
+++ b/library/tzdata/PRC
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Asia/Shanghai)]} {
+    LoadTimeZoneFile Asia/Shanghai
+}
+set TZData(:PRC) $TZData(:Asia/Shanghai)
diff --git a/library/tzdata/PST8PDT b/library/tzdata/PST8PDT
new file mode 100644
index 0000000..87a94da
--- /dev/null
+++ b/library/tzdata/PST8PDT
@@ -0,0 +1,278 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:PST8PDT) {
+    {-9223372036854775808 -28800 0 PST}
+    {-1633269600 -25200 1 PDT}
+    {-1615129200 -28800 0 PST}
+    {-1601820000 -25200 1 PDT}
+    {-1583679600 -28800 0 PST}
+    {-880207200 -25200 1 PWT}
+    {-769395600 -25200 1 PPT}
+    {-765385200 -28800 0 PST}
+    {-84376800 -25200 1 PDT}
+    {-68655600 -28800 0 PST}
+    {-52927200 -25200 1 PDT}
+    {-37206000 -28800 0 PST}
+    {-21477600 -25200 1 PDT}
+    {-5756400 -28800 0 PST}
+    {9972000 -25200 1 PDT}
+    {25693200 -28800 0 PST}
+    {41421600 -25200 1 PDT}
+    {57747600 -28800 0 PST}
+    {73476000 -25200 1 PDT}
+    {89197200 -28800 0 PST}
+    {104925600 -25200 1 PDT}
+    {120646800 -28800 0 PST}
+    {126698400 -25200 1 PDT}
+    {152096400 -28800 0 PST}
+    {162381600 -25200 1 PDT}
+    {183546000 -28800 0 PST}
+    {199274400 -25200 1 PDT}
+    {215600400 -28800 0 PST}
+    {230724000 -25200 1 PDT}
+    {247050000 -28800 0 PST}
+    {262778400 -25200 1 PDT}
+    {278499600 -28800 0 PST}
+    {294228000 -25200 1 PDT}
+    {309949200 -28800 0 PST}
+    {325677600 -25200 1 PDT}
+    {341398800 -28800 0 PST}
+    {357127200 -25200 1 PDT}
+    {372848400 -28800 0 PST}
+    {388576800 -25200 1 PDT}
+    {404902800 -28800 0 PST}
+    {420026400 -25200 1 PDT}
+    {436352400 -28800 0 PST}
+    {452080800 -25200 1 PDT}
+    {467802000 -28800 0 PST}
+    {483530400 -25200 1 PDT}
+    {499251600 -28800 0 PST}
+    {514980000 -25200 1 PDT}
+    {530701200 -28800 0 PST}
+    {544615200 -25200 1 PDT}
+    {562150800 -28800 0 PST}
+    {576064800 -25200 1 PDT}
+    {594205200 -28800 0 PST}
+    {607514400 -25200 1 PDT}
+    {625654800 -28800 0 PST}
+    {638964000 -25200 1 PDT}
+    {657104400 -28800 0 PST}
+    {671018400 -25200 1 PDT}
+    {688554000 -28800 0 PST}
+    {702468000 -25200 1 PDT}
+    {720003600 -28800 0 PST}
+    {733917600 -25200 1 PDT}
+    {752058000 -28800 0 PST}
+    {765367200 -25200 1 PDT}
+    {783507600 -28800 0 PST}
+    {796816800 -25200 1 PDT}
+    {814957200 -28800 0 PST}
+    {828871200 -25200 1 PDT}
+    {846406800 -28800 0 PST}
+    {860320800 -25200 1 PDT}
+    {877856400 -28800 0 PST}
+    {891770400 -25200 1 PDT}
+    {909306000 -28800 0 PST}
+    {923220000 -25200 1 PDT}
+    {941360400 -28800 0 PST}
+    {954669600 -25200 1 PDT}
+    {972810000 -28800 0 PST}
+    {986119200 -25200 1 PDT}
+    {1004259600 -28800 0 PST}
+    {1018173600 -25200 1 PDT}
+    {1035709200 -28800 0 PST}
+    {1049623200 -25200 1 PDT}
+    {1067158800 -28800 0 PST}
+    {1081072800 -25200 1 PDT}
+    {1099213200 -28800 0 PST}
+    {1112522400 -25200 1 PDT}
+    {1130662800 -28800 0 PST}
+    {1143972000 -25200 1 PDT}
+    {1162112400 -28800 0 PST}
+    {1173607200 -25200 1 PDT}
+    {1194166800 -28800 0 PST}
+    {1205056800 -25200 1 PDT}
+    {1225616400 -28800 0 PST}
+    {1236506400 -25200 1 PDT}
+    {1257066000 -28800 0 PST}
+    {1268560800 -25200 1 PDT}
+    {1289120400 -28800 0 PST}
+    {1300010400 -25200 1 PDT}
+    {1320570000 -28800 0 PST}
+    {1331460000 -25200 1 PDT}
+    {1352019600 -28800 0 PST}
+    {1362909600 -25200 1 PDT}
+    {1383469200 -28800 0 PST}
+    {1394359200 -25200 1 PDT}
+    {1414918800 -28800 0 PST}
+    {1425808800 -25200 1 PDT}
+    {1446368400 -28800 0 PST}
+    {1457863200 -25200 1 PDT}
+    {1478422800 -28800 0 PST}
+    {1489312800 -25200 1 PDT}
+    {1509872400 -28800 0 PST}
+    {1520762400 -25200 1 PDT}
+    {1541322000 -28800 0 PST}
+    {1552212000 -25200 1 PDT}
+    {1572771600 -28800 0 PST}
+    {1583661600 -25200 1 PDT}
+    {1604221200 -28800 0 PST}
+    {1615716000 -25200 1 PDT}
+    {1636275600 -28800 0 PST}
+    {1647165600 -25200 1 PDT}
+    {1667725200 -28800 0 PST}
+    {1678615200 -25200 1 PDT}
+    {1699174800 -28800 0 PST}
+    {1710064800 -25200 1 PDT}
+    {1730624400 -28800 0 PST}
+    {1741514400 -25200 1 PDT}
+    {1762074000 -28800 0 PST}
+    {1772964000 -25200 1 PDT}
+    {1793523600 -28800 0 PST}
+    {1805018400 -25200 1 PDT}
+    {1825578000 -28800 0 PST}
+    {1836468000 -25200 1 PDT}
+    {1857027600 -28800 0 PST}
+    {1867917600 -25200 1 PDT}
+    {1888477200 -28800 0 PST}
+    {1899367200 -25200 1 PDT}
+    {1919926800 -28800 0 PST}
+    {1930816800 -25200 1 PDT}
+    {1951376400 -28800 0 PST}
+    {1962871200 -25200 1 PDT}
+    {1983430800 -28800 0 PST}
+    {1994320800 -25200 1 PDT}
+    {2014880400 -28800 0 PST}
+    {2025770400 -25200 1 PDT}
+    {2046330000 -28800 0 PST}
+    {2057220000 -25200 1 PDT}
+    {2077779600 -28800 0 PST}
+    {2088669600 -25200 1 PDT}
+    {2109229200 -28800 0 PST}
+    {2120119200 -25200 1 PDT}
+    {2140678800 -28800 0 PST}
+    {2152173600 -25200 1 PDT}
+    {2172733200 -28800 0 PST}
+    {2183623200 -25200 1 PDT}
+    {2204182800 -28800 0 PST}
+    {2215072800 -25200 1 PDT}
+    {2235632400 -28800 0 PST}
+    {2246522400 -25200 1 PDT}
+    {2267082000 -28800 0 PST}
+    {2277972000 -25200 1 PDT}
+    {2298531600 -28800 0 PST}
+    {2309421600 -25200 1 PDT}
+    {2329981200 -28800 0 PST}
+    {2341476000 -25200 1 PDT}
+    {2362035600 -28800 0 PST}
+    {2372925600 -25200 1 PDT}
+    {2393485200 -28800 0 PST}
+    {2404375200 -25200 1 PDT}
+    {2424934800 -28800 0 PST}
+    {2435824800 -25200 1 PDT}
+    {2456384400 -28800 0 PST}
+    {2467274400 -25200 1 PDT}
+    {2487834000 -28800 0 PST}
+    {2499328800 -25200 1 PDT}
+    {2519888400 -28800 0 PST}
+    {2530778400 -25200 1 PDT}
+    {2551338000 -28800 0 PST}
+    {2562228000 -25200 1 PDT}
+    {2582787600 -28800 0 PST}
+    {2593677600 -25200 1 PDT}
+    {2614237200 -28800 0 PST}
+    {2625127200 -25200 1 PDT}
+    {2645686800 -28800 0 PST}
+    {2656576800 -25200 1 PDT}
+    {2677136400 -28800 0 PST}
+    {2688631200 -25200 1 PDT}
+    {2709190800 -28800 0 PST}
+    {2720080800 -25200 1 PDT}
+    {2740640400 -28800 0 PST}
+    {2751530400 -25200 1 PDT}
+    {2772090000 -28800 0 PST}
+    {2782980000 -25200 1 PDT}
+    {2803539600 -28800 0 PST}
+    {2814429600 -25200 1 PDT}
+    {2834989200 -28800 0 PST}
+    {2846484000 -25200 1 PDT}
+    {2867043600 -28800 0 PST}
+    {2877933600 -25200 1 PDT}
+    {2898493200 -28800 0 PST}
+    {2909383200 -25200 1 PDT}
+    {2929942800 -28800 0 PST}
+    {2940832800 -25200 1 PDT}
+    {2961392400 -28800 0 PST}
+    {2972282400 -25200 1 PDT}
+    {2992842000 -28800 0 PST}
+    {3003732000 -25200 1 PDT}
+    {3024291600 -28800 0 PST}
+    {3035786400 -25200 1 PDT}
+    {3056346000 -28800 0 PST}
+    {3067236000 -25200 1 PDT}
+    {3087795600 -28800 0 PST}
+    {3098685600 -25200 1 PDT}
+    {3119245200 -28800 0 PST}
+    {3130135200 -25200 1 PDT}
+    {3150694800 -28800 0 PST}
+    {3161584800 -25200 1 PDT}
+    {3182144400 -28800 0 PST}
+    {3193034400 -25200 1 PDT}
+    {3213594000 -28800 0 PST}
+    {3225088800 -25200 1 PDT}
+    {3245648400 -28800 0 PST}
+    {3256538400 -25200 1 PDT}
+    {3277098000 -28800 0 PST}
+    {3287988000 -25200 1 PDT}
+    {3308547600 -28800 0 PST}
+    {3319437600 -25200 1 PDT}
+    {3339997200 -28800 0 PST}
+    {3350887200 -25200 1 PDT}
+    {3371446800 -28800 0 PST}
+    {3382941600 -25200 1 PDT}
+    {3403501200 -28800 0 PST}
+    {3414391200 -25200 1 PDT}
+    {3434950800 -28800 0 PST}
+    {3445840800 -25200 1 PDT}
+    {3466400400 -28800 0 PST}
+    {3477290400 -25200 1 PDT}
+    {3497850000 -28800 0 PST}
+    {3508740000 -25200 1 PDT}
+    {3529299600 -28800 0 PST}
+    {3540189600 -25200 1 PDT}
+    {3560749200 -28800 0 PST}
+    {3572244000 -25200 1 PDT}
+    {3592803600 -28800 0 PST}
+    {3603693600 -25200 1 PDT}
+    {3624253200 -28800 0 PST}
+    {3635143200 -25200 1 PDT}
+    {3655702800 -28800 0 PST}
+    {3666592800 -25200 1 PDT}
+    {3687152400 -28800 0 PST}
+    {3698042400 -25200 1 PDT}
+    {3718602000 -28800 0 PST}
+    {3730096800 -25200 1 PDT}
+    {3750656400 -28800 0 PST}
+    {3761546400 -25200 1 PDT}
+    {3782106000 -28800 0 PST}
+    {3792996000 -25200 1 PDT}
+    {3813555600 -28800 0 PST}
+    {3824445600 -25200 1 PDT}
+    {3845005200 -28800 0 PST}
+    {3855895200 -25200 1 PDT}
+    {3876454800 -28800 0 PST}
+    {3887344800 -25200 1 PDT}
+    {3907904400 -28800 0 PST}
+    {3919399200 -25200 1 PDT}
+    {3939958800 -28800 0 PST}
+    {3950848800 -25200 1 PDT}
+    {3971408400 -28800 0 PST}
+    {3982298400 -25200 1 PDT}
+    {4002858000 -28800 0 PST}
+    {4013748000 -25200 1 PDT}
+    {4034307600 -28800 0 PST}
+    {4045197600 -25200 1 PDT}
+    {4065757200 -28800 0 PST}
+    {4076647200 -25200 1 PDT}
+    {4097206800 -28800 0 PST}
+}
diff --git a/library/tzdata/Pacific/Apia b/library/tzdata/Pacific/Apia
new file mode 100644
index 0000000..21d6669
--- /dev/null
+++ b/library/tzdata/Pacific/Apia
@@ -0,0 +1,188 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Pacific/Apia) {
+    {-9223372036854775808 45184 0 LMT}
+    {-2855737984 -41216 0 LMT}
+    {-1861878784 -41400 0 WSST}
+    {-631110600 -39600 0 SST}
+    {1285498800 -36000 1 SDT}
+    {1301752800 -39600 0 SST}
+    {1316872800 -36000 1 SDT}
+    {1325239200 50400 0 WSDT}
+    {1333202400 46800 0 WSST}
+    {1348927200 50400 1 WSDT}
+    {1365256800 46800 0 WSST}
+    {1380376800 50400 1 WSDT}
+    {1396706400 46800 0 WSST}
+    {1411826400 50400 1 WSDT}
+    {1428156000 46800 0 WSST}
+    {1443276000 50400 1 WSDT}
+    {1459605600 46800 0 WSST}
+    {1474725600 50400 1 WSDT}
+    {1491055200 46800 0 WSST}
+    {1506175200 50400 1 WSDT}
+    {1522504800 46800 0 WSST}
+    {1538229600 50400 1 WSDT}
+    {1554559200 46800 0 WSST}
+    {1569679200 50400 1 WSDT}
+    {1586008800 46800 0 WSST}
+    {1601128800 50400 1 WSDT}
+    {1617458400 46800 0 WSST}
+    {1632578400 50400 1 WSDT}
+    {1648908000 46800 0 WSST}
+    {1664028000 50400 1 WSDT}
+    {1680357600 46800 0 WSST}
+    {1695477600 50400 1 WSDT}
+    {1712412000 46800 0 WSST}
+    {1727532000 50400 1 WSDT}
+    {1743861600 46800 0 WSST}
+    {1758981600 50400 1 WSDT}
+    {1775311200 46800 0 WSST}
+    {1790431200 50400 1 WSDT}
+    {1806760800 46800 0 WSST}
+    {1821880800 50400 1 WSDT}
+    {1838210400 46800 0 WSST}
+    {1853330400 50400 1 WSDT}
+    {1869660000 46800 0 WSST}
+    {1885384800 50400 1 WSDT}
+    {1901714400 46800 0 WSST}
+    {1916834400 50400 1 WSDT}
+    {1933164000 46800 0 WSST}
+    {1948284000 50400 1 WSDT}
+    {1964613600 46800 0 WSST}
+    {1979733600 50400 1 WSDT}
+    {1996063200 46800 0 WSST}
+    {2011183200 50400 1 WSDT}
+    {2027512800 46800 0 WSST}
+    {2042632800 50400 1 WSDT}
+    {2058962400 46800 0 WSST}
+    {2074687200 50400 1 WSDT}
+    {2091016800 46800 0 WSST}
+    {2106136800 50400 1 WSDT}
+    {2122466400 46800 0 WSST}
+    {2137586400 50400 1 WSDT}
+    {2153916000 46800 0 WSST}
+    {2169036000 50400 1 WSDT}
+    {2185365600 46800 0 WSST}
+    {2200485600 50400 1 WSDT}
+    {2216815200 46800 0 WSST}
+    {2232540000 50400 1 WSDT}
+    {2248869600 46800 0 WSST}
+    {2263989600 50400 1 WSDT}
+    {2280319200 46800 0 WSST}
+    {2295439200 50400 1 WSDT}
+    {2311768800 46800 0 WSST}
+    {2326888800 50400 1 WSDT}
+    {2343218400 46800 0 WSST}
+    {2358338400 50400 1 WSDT}
+    {2374668000 46800 0 WSST}
+    {2389788000 50400 1 WSDT}
+    {2406117600 46800 0 WSST}
+    {2421842400 50400 1 WSDT}
+    {2438172000 46800 0 WSST}
+    {2453292000 50400 1 WSDT}
+    {2469621600 46800 0 WSST}
+    {2484741600 50400 1 WSDT}
+    {2501071200 46800 0 WSST}
+    {2516191200 50400 1 WSDT}
+    {2532520800 46800 0 WSST}
+    {2547640800 50400 1 WSDT}
+    {2563970400 46800 0 WSST}
+    {2579090400 50400 1 WSDT}
+    {2596024800 46800 0 WSST}
+    {2611144800 50400 1 WSDT}
+    {2627474400 46800 0 WSST}
+    {2642594400 50400 1 WSDT}
+    {2658924000 46800 0 WSST}
+    {2674044000 50400 1 WSDT}
+    {2690373600 46800 0 WSST}
+    {2705493600 50400 1 WSDT}
+    {2721823200 46800 0 WSST}
+    {2736943200 50400 1 WSDT}
+    {2753272800 46800 0 WSST}
+    {2768997600 50400 1 WSDT}
+    {2785327200 46800 0 WSST}
+    {2800447200 50400 1 WSDT}
+    {2816776800 46800 0 WSST}
+    {2831896800 50400 1 WSDT}
+    {2848226400 46800 0 WSST}
+    {2863346400 50400 1 WSDT}
+    {2879676000 46800 0 WSST}
+    {2894796000 50400 1 WSDT}
+    {2911125600 46800 0 WSST}
+    {2926245600 50400 1 WSDT}
+    {2942575200 46800 0 WSST}
+    {2958300000 50400 1 WSDT}
+    {2974629600 46800 0 WSST}
+    {2989749600 50400 1 WSDT}
+    {3006079200 46800 0 WSST}
+    {3021199200 50400 1 WSDT}
+    {3037528800 46800 0 WSST}
+    {3052648800 50400 1 WSDT}
+    {3068978400 46800 0 WSST}
+    {3084098400 50400 1 WSDT}
+    {3100428000 46800 0 WSST}
+    {3116152800 50400 1 WSDT}
+    {3132482400 46800 0 WSST}
+    {3147602400 50400 1 WSDT}
+    {3163932000 46800 0 WSST}
+    {3179052000 50400 1 WSDT}
+    {3195381600 46800 0 WSST}
+    {3210501600 50400 1 WSDT}
+    {3226831200 46800 0 WSST}
+    {3241951200 50400 1 WSDT}
+    {3258280800 46800 0 WSST}
+    {3273400800 50400 1 WSDT}
+    {3289730400 46800 0 WSST}
+    {3305455200 50400 1 WSDT}
+    {3321784800 46800 0 WSST}
+    {3336904800 50400 1 WSDT}
+    {3353234400 46800 0 WSST}
+    {3368354400 50400 1 WSDT}
+    {3384684000 46800 0 WSST}
+    {3399804000 50400 1 WSDT}
+    {3416133600 46800 0 WSST}
+    {3431253600 50400 1 WSDT}
+    {3447583200 46800 0 WSST}
+    {3462703200 50400 1 WSDT}
+    {3479637600 46800 0 WSST}
+    {3494757600 50400 1 WSDT}
+    {3511087200 46800 0 WSST}
+    {3526207200 50400 1 WSDT}
+    {3542536800 46800 0 WSST}
+    {3557656800 50400 1 WSDT}
+    {3573986400 46800 0 WSST}
+    {3589106400 50400 1 WSDT}
+    {3605436000 46800 0 WSST}
+    {3620556000 50400 1 WSDT}
+    {3636885600 46800 0 WSST}
+    {3652610400 50400 1 WSDT}
+    {3668940000 46800 0 WSST}
+    {3684060000 50400 1 WSDT}
+    {3700389600 46800 0 WSST}
+    {3715509600 50400 1 WSDT}
+    {3731839200 46800 0 WSST}
+    {3746959200 50400 1 WSDT}
+    {3763288800 46800 0 WSST}
+    {3778408800 50400 1 WSDT}
+    {3794738400 46800 0 WSST}
+    {3809858400 50400 1 WSDT}
+    {3826188000 46800 0 WSST}
+    {3841912800 50400 1 WSDT}
+    {3858242400 46800 0 WSST}
+    {3873362400 50400 1 WSDT}
+    {3889692000 46800 0 WSST}
+    {3904812000 50400 1 WSDT}
+    {3921141600 46800 0 WSST}
+    {3936261600 50400 1 WSDT}
+    {3952591200 46800 0 WSST}
+    {3967711200 50400 1 WSDT}
+    {3984040800 46800 0 WSST}
+    {3999765600 50400 1 WSDT}
+    {4016095200 46800 0 WSST}
+    {4031215200 50400 1 WSDT}
+    {4047544800 46800 0 WSST}
+    {4062664800 50400 1 WSDT}
+    {4078994400 46800 0 WSST}
+    {4094114400 50400 1 WSDT}
+}
diff --git a/library/tzdata/Pacific/Auckland b/library/tzdata/Pacific/Auckland
new file mode 100644
index 0000000..5f7e238
--- /dev/null
+++ b/library/tzdata/Pacific/Auckland
@@ -0,0 +1,285 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Pacific/Auckland) {
+    {-9223372036854775808 41944 0 LMT}
+    {-3192435544 41400 0 NZMT}
+    {-1330335000 45000 1 NZST}
+    {-1320057000 41400 0 NZMT}
+    {-1300699800 43200 1 NZST}
+    {-1287396000 41400 0 NZMT}
+    {-1269250200 43200 1 NZST}
+    {-1255946400 41400 0 NZMT}
+    {-1237800600 43200 1 NZST}
+    {-1224496800 41400 0 NZMT}
+    {-1206351000 43200 1 NZST}
+    {-1192442400 41400 0 NZMT}
+    {-1174901400 43200 1 NZST}
+    {-1160992800 41400 0 NZMT}
+    {-1143451800 43200 1 NZST}
+    {-1125914400 41400 0 NZMT}
+    {-1112607000 43200 1 NZST}
+    {-1094464800 41400 0 NZMT}
+    {-1081157400 43200 1 NZST}
+    {-1063015200 41400 0 NZMT}
+    {-1049707800 43200 1 NZST}
+    {-1031565600 41400 0 NZMT}
+    {-1018258200 43200 1 NZST}
+    {-1000116000 41400 0 NZMT}
+    {-986808600 43200 1 NZST}
+    {-968061600 41400 0 NZMT}
+    {-955359000 43200 1 NZST}
+    {-936612000 41400 0 NZMT}
+    {-923304600 43200 1 NZST}
+    {-757425600 43200 0 NZST}
+    {152632800 46800 1 NZDT}
+    {162309600 43200 0 NZST}
+    {183477600 46800 1 NZDT}
+    {194968800 43200 0 NZST}
+    {215532000 46800 1 NZDT}
+    {226418400 43200 0 NZST}
+    {246981600 46800 1 NZDT}
+    {257868000 43200 0 NZST}
+    {278431200 46800 1 NZDT}
+    {289317600 43200 0 NZST}
+    {309880800 46800 1 NZDT}
+    {320767200 43200 0 NZST}
+    {341330400 46800 1 NZDT}
+    {352216800 43200 0 NZST}
+    {372780000 46800 1 NZDT}
+    {384271200 43200 0 NZST}
+    {404834400 46800 1 NZDT}
+    {415720800 43200 0 NZST}
+    {436284000 46800 1 NZDT}
+    {447170400 43200 0 NZST}
+    {467733600 46800 1 NZDT}
+    {478620000 43200 0 NZST}
+    {499183200 46800 1 NZDT}
+    {510069600 43200 0 NZST}
+    {530632800 46800 1 NZDT}
+    {541519200 43200 0 NZST}
+    {562082400 46800 1 NZDT}
+    {573573600 43200 0 NZST}
+    {594136800 46800 1 NZDT}
+    {605023200 43200 0 NZST}
+    {623772000 46800 1 NZDT}
+    {637682400 43200 0 NZST}
+    {655221600 46800 1 NZDT}
+    {669132000 43200 0 NZST}
+    {686671200 46800 1 NZDT}
+    {700581600 43200 0 NZST}
+    {718120800 46800 1 NZDT}
+    {732636000 43200 0 NZST}
+    {749570400 46800 1 NZDT}
+    {764085600 43200 0 NZST}
+    {781020000 46800 1 NZDT}
+    {795535200 43200 0 NZST}
+    {812469600 46800 1 NZDT}
+    {826984800 43200 0 NZST}
+    {844524000 46800 1 NZDT}
+    {858434400 43200 0 NZST}
+    {875973600 46800 1 NZDT}
+    {889884000 43200 0 NZST}
+    {907423200 46800 1 NZDT}
+    {921938400 43200 0 NZST}
+    {938872800 46800 1 NZDT}
+    {953388000 43200 0 NZST}
+    {970322400 46800 1 NZDT}
+    {984837600 43200 0 NZST}
+    {1002376800 46800 1 NZDT}
+    {1016287200 43200 0 NZST}
+    {1033826400 46800 1 NZDT}
+    {1047736800 43200 0 NZST}
+    {1065276000 46800 1 NZDT}
+    {1079791200 43200 0 NZST}
+    {1096725600 46800 1 NZDT}
+    {1111240800 43200 0 NZST}
+    {1128175200 46800 1 NZDT}
+    {1142690400 43200 0 NZST}
+    {1159624800 46800 1 NZDT}
+    {1174140000 43200 0 NZST}
+    {1191074400 46800 1 NZDT}
+    {1207404000 43200 0 NZST}
+    {1222524000 46800 1 NZDT}
+    {1238853600 43200 0 NZST}
+    {1253973600 46800 1 NZDT}
+    {1270303200 43200 0 NZST}
+    {1285423200 46800 1 NZDT}
+    {1301752800 43200 0 NZST}
+    {1316872800 46800 1 NZDT}
+    {1333202400 43200 0 NZST}
+    {1348927200 46800 1 NZDT}
+    {1365256800 43200 0 NZST}
+    {1380376800 46800 1 NZDT}
+    {1396706400 43200 0 NZST}
+    {1411826400 46800 1 NZDT}
+    {1428156000 43200 0 NZST}
+    {1443276000 46800 1 NZDT}
+    {1459605600 43200 0 NZST}
+    {1474725600 46800 1 NZDT}
+    {1491055200 43200 0 NZST}
+    {1506175200 46800 1 NZDT}
+    {1522504800 43200 0 NZST}
+    {1538229600 46800 1 NZDT}
+    {1554559200 43200 0 NZST}
+    {1569679200 46800 1 NZDT}
+    {1586008800 43200 0 NZST}
+    {1601128800 46800 1 NZDT}
+    {1617458400 43200 0 NZST}
+    {1632578400 46800 1 NZDT}
+    {1648908000 43200 0 NZST}
+    {1664028000 46800 1 NZDT}
+    {1680357600 43200 0 NZST}
+    {1695477600 46800 1 NZDT}
+    {1712412000 43200 0 NZST}
+    {1727532000 46800 1 NZDT}
+    {1743861600 43200 0 NZST}
+    {1758981600 46800 1 NZDT}
+    {1775311200 43200 0 NZST}
+    {1790431200 46800 1 NZDT}
+    {1806760800 43200 0 NZST}
+    {1821880800 46800 1 NZDT}
+    {1838210400 43200 0 NZST}
+    {1853330400 46800 1 NZDT}
+    {1869660000 43200 0 NZST}
+    {1885384800 46800 1 NZDT}
+    {1901714400 43200 0 NZST}
+    {1916834400 46800 1 NZDT}
+    {1933164000 43200 0 NZST}
+    {1948284000 46800 1 NZDT}
+    {1964613600 43200 0 NZST}
+    {1979733600 46800 1 NZDT}
+    {1996063200 43200 0 NZST}
+    {2011183200 46800 1 NZDT}
+    {2027512800 43200 0 NZST}
+    {2042632800 46800 1 NZDT}
+    {2058962400 43200 0 NZST}
+    {2074687200 46800 1 NZDT}
+    {2091016800 43200 0 NZST}
+    {2106136800 46800 1 NZDT}
+    {2122466400 43200 0 NZST}
+    {2137586400 46800 1 NZDT}
+    {2153916000 43200 0 NZST}
+    {2169036000 46800 1 NZDT}
+    {2185365600 43200 0 NZST}
+    {2200485600 46800 1 NZDT}
+    {2216815200 43200 0 NZST}
+    {2232540000 46800 1 NZDT}
+    {2248869600 43200 0 NZST}
+    {2263989600 46800 1 NZDT}
+    {2280319200 43200 0 NZST}
+    {2295439200 46800 1 NZDT}
+    {2311768800 43200 0 NZST}
+    {2326888800 46800 1 NZDT}
+    {2343218400 43200 0 NZST}
+    {2358338400 46800 1 NZDT}
+    {2374668000 43200 0 NZST}
+    {2389788000 46800 1 NZDT}
+    {2406117600 43200 0 NZST}
+    {2421842400 46800 1 NZDT}
+    {2438172000 43200 0 NZST}
+    {2453292000 46800 1 NZDT}
+    {2469621600 43200 0 NZST}
+    {2484741600 46800 1 NZDT}
+    {2501071200 43200 0 NZST}
+    {2516191200 46800 1 NZDT}
+    {2532520800 43200 0 NZST}
+    {2547640800 46800 1 NZDT}
+    {2563970400 43200 0 NZST}
+    {2579090400 46800 1 NZDT}
+    {2596024800 43200 0 NZST}
+    {2611144800 46800 1 NZDT}
+    {2627474400 43200 0 NZST}
+    {2642594400 46800 1 NZDT}
+    {2658924000 43200 0 NZST}
+    {2674044000 46800 1 NZDT}
+    {2690373600 43200 0 NZST}
+    {2705493600 46800 1 NZDT}
+    {2721823200 43200 0 NZST}
+    {2736943200 46800 1 NZDT}
+    {2753272800 43200 0 NZST}
+    {2768997600 46800 1 NZDT}
+    {2785327200 43200 0 NZST}
+    {2800447200 46800 1 NZDT}
+    {2816776800 43200 0 NZST}
+    {2831896800 46800 1 NZDT}
+    {2848226400 43200 0 NZST}
+    {2863346400 46800 1 NZDT}
+    {2879676000 43200 0 NZST}
+    {2894796000 46800 1 NZDT}
+    {2911125600 43200 0 NZST}
+    {2926245600 46800 1 NZDT}
+    {2942575200 43200 0 NZST}
+    {2958300000 46800 1 NZDT}
+    {2974629600 43200 0 NZST}
+    {2989749600 46800 1 NZDT}
+    {3006079200 43200 0 NZST}
+    {3021199200 46800 1 NZDT}
+    {3037528800 43200 0 NZST}
+    {3052648800 46800 1 NZDT}
+    {3068978400 43200 0 NZST}
+    {3084098400 46800 1 NZDT}
+    {3100428000 43200 0 NZST}
+    {3116152800 46800 1 NZDT}
+    {3132482400 43200 0 NZST}
+    {3147602400 46800 1 NZDT}
+    {3163932000 43200 0 NZST}
+    {3179052000 46800 1 NZDT}
+    {3195381600 43200 0 NZST}
+    {3210501600 46800 1 NZDT}
+    {3226831200 43200 0 NZST}
+    {3241951200 46800 1 NZDT}
+    {3258280800 43200 0 NZST}
+    {3273400800 46800 1 NZDT}
+    {3289730400 43200 0 NZST}
+    {3305455200 46800 1 NZDT}
+    {3321784800 43200 0 NZST}
+    {3336904800 46800 1 NZDT}
+    {3353234400 43200 0 NZST}
+    {3368354400 46800 1 NZDT}
+    {3384684000 43200 0 NZST}
+    {3399804000 46800 1 NZDT}
+    {3416133600 43200 0 NZST}
+    {3431253600 46800 1 NZDT}
+    {3447583200 43200 0 NZST}
+    {3462703200 46800 1 NZDT}
+    {3479637600 43200 0 NZST}
+    {3494757600 46800 1 NZDT}
+    {3511087200 43200 0 NZST}
+    {3526207200 46800 1 NZDT}
+    {3542536800 43200 0 NZST}
+    {3557656800 46800 1 NZDT}
+    {3573986400 43200 0 NZST}
+    {3589106400 46800 1 NZDT}
+    {3605436000 43200 0 NZST}
+    {3620556000 46800 1 NZDT}
+    {3636885600 43200 0 NZST}
+    {3652610400 46800 1 NZDT}
+    {3668940000 43200 0 NZST}
+    {3684060000 46800 1 NZDT}
+    {3700389600 43200 0 NZST}
+    {3715509600 46800 1 NZDT}
+    {3731839200 43200 0 NZST}
+    {3746959200 46800 1 NZDT}
+    {3763288800 43200 0 NZST}
+    {3778408800 46800 1 NZDT}
+    {3794738400 43200 0 NZST}
+    {3809858400 46800 1 NZDT}
+    {3826188000 43200 0 NZST}
+    {3841912800 46800 1 NZDT}
+    {3858242400 43200 0 NZST}
+    {3873362400 46800 1 NZDT}
+    {3889692000 43200 0 NZST}
+    {3904812000 46800 1 NZDT}
+    {3921141600 43200 0 NZST}
+    {3936261600 46800 1 NZDT}
+    {3952591200 43200 0 NZST}
+    {3967711200 46800 1 NZDT}
+    {3984040800 43200 0 NZST}
+    {3999765600 46800 1 NZDT}
+    {4016095200 43200 0 NZST}
+    {4031215200 46800 1 NZDT}
+    {4047544800 43200 0 NZST}
+    {4062664800 46800 1 NZDT}
+    {4078994400 43200 0 NZST}
+    {4094114400 46800 1 NZDT}
+}
diff --git a/library/tzdata/Pacific/Bougainville b/library/tzdata/Pacific/Bougainville
new file mode 100644
index 0000000..06996f9
--- /dev/null
+++ b/library/tzdata/Pacific/Bougainville
@@ -0,0 +1,10 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Pacific/Bougainville) {
+    {-9223372036854775808 37336 0 LMT}
+    {-2840178136 35312 0 PMMT}
+    {-2366790512 36000 0 PGT}
+    {-868010400 32400 0 JST}
+    {-768906000 36000 0 PGT}
+    {1419696000 39600 0 BST}
+}
diff --git a/library/tzdata/Pacific/Chatham b/library/tzdata/Pacific/Chatham
new file mode 100644
index 0000000..94a5512
--- /dev/null
+++ b/library/tzdata/Pacific/Chatham
@@ -0,0 +1,258 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Pacific/Chatham) {
+    {-9223372036854775808 44028 0 LMT}
+    {-3192437628 44100 0 CHAST}
+    {-757426500 45900 0 CHAST}
+    {152632800 49500 1 CHADT}
+    {162309600 45900 0 CHAST}
+    {183477600 49500 1 CHADT}
+    {194968800 45900 0 CHAST}
+    {215532000 49500 1 CHADT}
+    {226418400 45900 0 CHAST}
+    {246981600 49500 1 CHADT}
+    {257868000 45900 0 CHAST}
+    {278431200 49500 1 CHADT}
+    {289317600 45900 0 CHAST}
+    {309880800 49500 1 CHADT}
+    {320767200 45900 0 CHAST}
+    {341330400 49500 1 CHADT}
+    {352216800 45900 0 CHAST}
+    {372780000 49500 1 CHADT}
+    {384271200 45900 0 CHAST}
+    {404834400 49500 1 CHADT}
+    {415720800 45900 0 CHAST}
+    {436284000 49500 1 CHADT}
+    {447170400 45900 0 CHAST}
+    {467733600 49500 1 CHADT}
+    {478620000 45900 0 CHAST}
+    {499183200 49500 1 CHADT}
+    {510069600 45900 0 CHAST}
+    {530632800 49500 1 CHADT}
+    {541519200 45900 0 CHAST}
+    {562082400 49500 1 CHADT}
+    {573573600 45900 0 CHAST}
+    {594136800 49500 1 CHADT}
+    {605023200 45900 0 CHAST}
+    {623772000 49500 1 CHADT}
+    {637682400 45900 0 CHAST}
+    {655221600 49500 1 CHADT}
+    {669132000 45900 0 CHAST}
+    {686671200 49500 1 CHADT}
+    {700581600 45900 0 CHAST}
+    {718120800 49500 1 CHADT}
+    {732636000 45900 0 CHAST}
+    {749570400 49500 1 CHADT}
+    {764085600 45900 0 CHAST}
+    {781020000 49500 1 CHADT}
+    {795535200 45900 0 CHAST}
+    {812469600 49500 1 CHADT}
+    {826984800 45900 0 CHAST}
+    {844524000 49500 1 CHADT}
+    {858434400 45900 0 CHAST}
+    {875973600 49500 1 CHADT}
+    {889884000 45900 0 CHAST}
+    {907423200 49500 1 CHADT}
+    {921938400 45900 0 CHAST}
+    {938872800 49500 1 CHADT}
+    {953388000 45900 0 CHAST}
+    {970322400 49500 1 CHADT}
+    {984837600 45900 0 CHAST}
+    {1002376800 49500 1 CHADT}
+    {1016287200 45900 0 CHAST}
+    {1033826400 49500 1 CHADT}
+    {1047736800 45900 0 CHAST}
+    {1065276000 49500 1 CHADT}
+    {1079791200 45900 0 CHAST}
+    {1096725600 49500 1 CHADT}
+    {1111240800 45900 0 CHAST}
+    {1128175200 49500 1 CHADT}
+    {1142690400 45900 0 CHAST}
+    {1159624800 49500 1 CHADT}
+    {1174140000 45900 0 CHAST}
+    {1191074400 49500 1 CHADT}
+    {1207404000 45900 0 CHAST}
+    {1222524000 49500 1 CHADT}
+    {1238853600 45900 0 CHAST}
+    {1253973600 49500 1 CHADT}
+    {1270303200 45900 0 CHAST}
+    {1285423200 49500 1 CHADT}
+    {1301752800 45900 0 CHAST}
+    {1316872800 49500 1 CHADT}
+    {1333202400 45900 0 CHAST}
+    {1348927200 49500 1 CHADT}
+    {1365256800 45900 0 CHAST}
+    {1380376800 49500 1 CHADT}
+    {1396706400 45900 0 CHAST}
+    {1411826400 49500 1 CHADT}
+    {1428156000 45900 0 CHAST}
+    {1443276000 49500 1 CHADT}
+    {1459605600 45900 0 CHAST}
+    {1474725600 49500 1 CHADT}
+    {1491055200 45900 0 CHAST}
+    {1506175200 49500 1 CHADT}
+    {1522504800 45900 0 CHAST}
+    {1538229600 49500 1 CHADT}
+    {1554559200 45900 0 CHAST}
+    {1569679200 49500 1 CHADT}
+    {1586008800 45900 0 CHAST}
+    {1601128800 49500 1 CHADT}
+    {1617458400 45900 0 CHAST}
+    {1632578400 49500 1 CHADT}
+    {1648908000 45900 0 CHAST}
+    {1664028000 49500 1 CHADT}
+    {1680357600 45900 0 CHAST}
+    {1695477600 49500 1 CHADT}
+    {1712412000 45900 0 CHAST}
+    {1727532000 49500 1 CHADT}
+    {1743861600 45900 0 CHAST}
+    {1758981600 49500 1 CHADT}
+    {1775311200 45900 0 CHAST}
+    {1790431200 49500 1 CHADT}
+    {1806760800 45900 0 CHAST}
+    {1821880800 49500 1 CHADT}
+    {1838210400 45900 0 CHAST}
+    {1853330400 49500 1 CHADT}
+    {1869660000 45900 0 CHAST}
+    {1885384800 49500 1 CHADT}
+    {1901714400 45900 0 CHAST}
+    {1916834400 49500 1 CHADT}
+    {1933164000 45900 0 CHAST}
+    {1948284000 49500 1 CHADT}
+    {1964613600 45900 0 CHAST}
+    {1979733600 49500 1 CHADT}
+    {1996063200 45900 0 CHAST}
+    {2011183200 49500 1 CHADT}
+    {2027512800 45900 0 CHAST}
+    {2042632800 49500 1 CHADT}
+    {2058962400 45900 0 CHAST}
+    {2074687200 49500 1 CHADT}
+    {2091016800 45900 0 CHAST}
+    {2106136800 49500 1 CHADT}
+    {2122466400 45900 0 CHAST}
+    {2137586400 49500 1 CHADT}
+    {2153916000 45900 0 CHAST}
+    {2169036000 49500 1 CHADT}
+    {2185365600 45900 0 CHAST}
+    {2200485600 49500 1 CHADT}
+    {2216815200 45900 0 CHAST}
+    {2232540000 49500 1 CHADT}
+    {2248869600 45900 0 CHAST}
+    {2263989600 49500 1 CHADT}
+    {2280319200 45900 0 CHAST}
+    {2295439200 49500 1 CHADT}
+    {2311768800 45900 0 CHAST}
+    {2326888800 49500 1 CHADT}
+    {2343218400 45900 0 CHAST}
+    {2358338400 49500 1 CHADT}
+    {2374668000 45900 0 CHAST}
+    {2389788000 49500 1 CHADT}
+    {2406117600 45900 0 CHAST}
+    {2421842400 49500 1 CHADT}
+    {2438172000 45900 0 CHAST}
+    {2453292000 49500 1 CHADT}
+    {2469621600 45900 0 CHAST}
+    {2484741600 49500 1 CHADT}
+    {2501071200 45900 0 CHAST}
+    {2516191200 49500 1 CHADT}
+    {2532520800 45900 0 CHAST}
+    {2547640800 49500 1 CHADT}
+    {2563970400 45900 0 CHAST}
+    {2579090400 49500 1 CHADT}
+    {2596024800 45900 0 CHAST}
+    {2611144800 49500 1 CHADT}
+    {2627474400 45900 0 CHAST}
+    {2642594400 49500 1 CHADT}
+    {2658924000 45900 0 CHAST}
+    {2674044000 49500 1 CHADT}
+    {2690373600 45900 0 CHAST}
+    {2705493600 49500 1 CHADT}
+    {2721823200 45900 0 CHAST}
+    {2736943200 49500 1 CHADT}
+    {2753272800 45900 0 CHAST}
+    {2768997600 49500 1 CHADT}
+    {2785327200 45900 0 CHAST}
+    {2800447200 49500 1 CHADT}
+    {2816776800 45900 0 CHAST}
+    {2831896800 49500 1 CHADT}
+    {2848226400 45900 0 CHAST}
+    {2863346400 49500 1 CHADT}
+    {2879676000 45900 0 CHAST}
+    {2894796000 49500 1 CHADT}
+    {2911125600 45900 0 CHAST}
+    {2926245600 49500 1 CHADT}
+    {2942575200 45900 0 CHAST}
+    {2958300000 49500 1 CHADT}
+    {2974629600 45900 0 CHAST}
+    {2989749600 49500 1 CHADT}
+    {3006079200 45900 0 CHAST}
+    {3021199200 49500 1 CHADT}
+    {3037528800 45900 0 CHAST}
+    {3052648800 49500 1 CHADT}
+    {3068978400 45900 0 CHAST}
+    {3084098400 49500 1 CHADT}
+    {3100428000 45900 0 CHAST}
+    {3116152800 49500 1 CHADT}
+    {3132482400 45900 0 CHAST}
+    {3147602400 49500 1 CHADT}
+    {3163932000 45900 0 CHAST}
+    {3179052000 49500 1 CHADT}
+    {3195381600 45900 0 CHAST}
+    {3210501600 49500 1 CHADT}
+    {3226831200 45900 0 CHAST}
+    {3241951200 49500 1 CHADT}
+    {3258280800 45900 0 CHAST}
+    {3273400800 49500 1 CHADT}
+    {3289730400 45900 0 CHAST}
+    {3305455200 49500 1 CHADT}
+    {3321784800 45900 0 CHAST}
+    {3336904800 49500 1 CHADT}
+    {3353234400 45900 0 CHAST}
+    {3368354400 49500 1 CHADT}
+    {3384684000 45900 0 CHAST}
+    {3399804000 49500 1 CHADT}
+    {3416133600 45900 0 CHAST}
+    {3431253600 49500 1 CHADT}
+    {3447583200 45900 0 CHAST}
+    {3462703200 49500 1 CHADT}
+    {3479637600 45900 0 CHAST}
+    {3494757600 49500 1 CHADT}
+    {3511087200 45900 0 CHAST}
+    {3526207200 49500 1 CHADT}
+    {3542536800 45900 0 CHAST}
+    {3557656800 49500 1 CHADT}
+    {3573986400 45900 0 CHAST}
+    {3589106400 49500 1 CHADT}
+    {3605436000 45900 0 CHAST}
+    {3620556000 49500 1 CHADT}
+    {3636885600 45900 0 CHAST}
+    {3652610400 49500 1 CHADT}
+    {3668940000 45900 0 CHAST}
+    {3684060000 49500 1 CHADT}
+    {3700389600 45900 0 CHAST}
+    {3715509600 49500 1 CHADT}
+    {3731839200 45900 0 CHAST}
+    {3746959200 49500 1 CHADT}
+    {3763288800 45900 0 CHAST}
+    {3778408800 49500 1 CHADT}
+    {3794738400 45900 0 CHAST}
+    {3809858400 49500 1 CHADT}
+    {3826188000 45900 0 CHAST}
+    {3841912800 49500 1 CHADT}
+    {3858242400 45900 0 CHAST}
+    {3873362400 49500 1 CHADT}
+    {3889692000 45900 0 CHAST}
+    {3904812000 49500 1 CHADT}
+    {3921141600 45900 0 CHAST}
+    {3936261600 49500 1 CHADT}
+    {3952591200 45900 0 CHAST}
+    {3967711200 49500 1 CHADT}
+    {3984040800 45900 0 CHAST}
+    {3999765600 49500 1 CHADT}
+    {4016095200 45900 0 CHAST}
+    {4031215200 49500 1 CHADT}
+    {4047544800 45900 0 CHAST}
+    {4062664800 49500 1 CHADT}
+    {4078994400 45900 0 CHAST}
+    {4094114400 49500 1 CHADT}
+}
diff --git a/library/tzdata/Pacific/Chuuk b/library/tzdata/Pacific/Chuuk
new file mode 100644
index 0000000..70b14b2
--- /dev/null
+++ b/library/tzdata/Pacific/Chuuk
@@ -0,0 +1,6 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Pacific/Chuuk) {
+    {-9223372036854775808 36428 0 LMT}
+    {-2177489228 36000 0 CHUT}
+}
diff --git a/library/tzdata/Pacific/Easter b/library/tzdata/Pacific/Easter
new file mode 100644
index 0000000..ef0f2d5
--- /dev/null
+++ b/library/tzdata/Pacific/Easter
@@ -0,0 +1,268 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Pacific/Easter) {
+    {-9223372036854775808 -26248 0 LMT}
+    {-2524495352 -26248 0 EMT}
+    {-1178124152 -25200 0 EAST}
+    {-36619200 -21600 1 EASST}
+    {-23922000 -25200 0 EAST}
+    {-3355200 -21600 1 EASST}
+    {7527600 -25200 0 EAST}
+    {24465600 -21600 1 EASST}
+    {37767600 -25200 0 EAST}
+    {55915200 -21600 1 EASST}
+    {69217200 -25200 0 EAST}
+    {87969600 -21600 1 EASST}
+    {100666800 -25200 0 EAST}
+    {118209600 -21600 1 EASST}
+    {132116400 -25200 0 EAST}
+    {150868800 -21600 1 EASST}
+    {163566000 -25200 0 EAST}
+    {182318400 -21600 1 EASST}
+    {195620400 -25200 0 EAST}
+    {213768000 -21600 1 EASST}
+    {227070000 -25200 0 EAST}
+    {245217600 -21600 1 EASST}
+    {258519600 -25200 0 EAST}
+    {277272000 -21600 1 EASST}
+    {289969200 -25200 0 EAST}
+    {308721600 -21600 1 EASST}
+    {321418800 -25200 0 EAST}
+    {340171200 -21600 1 EASST}
+    {353473200 -25200 0 EAST}
+    {371620800 -21600 1 EASST}
+    {384922800 -21600 0 EAST}
+    {403070400 -18000 1 EASST}
+    {416372400 -21600 0 EAST}
+    {434520000 -18000 1 EASST}
+    {447822000 -21600 0 EAST}
+    {466574400 -18000 1 EASST}
+    {479271600 -21600 0 EAST}
+    {498024000 -18000 1 EASST}
+    {510721200 -21600 0 EAST}
+    {529473600 -18000 1 EASST}
+    {545194800 -21600 0 EAST}
+    {560923200 -18000 1 EASST}
+    {574225200 -21600 0 EAST}
+    {592372800 -18000 1 EASST}
+    {605674800 -21600 0 EAST}
+    {624427200 -18000 1 EASST}
+    {637124400 -21600 0 EAST}
+    {653457600 -18000 1 EASST}
+    {668574000 -21600 0 EAST}
+    {687326400 -18000 1 EASST}
+    {700628400 -21600 0 EAST}
+    {718776000 -18000 1 EASST}
+    {732078000 -21600 0 EAST}
+    {750225600 -18000 1 EASST}
+    {763527600 -21600 0 EAST}
+    {781675200 -18000 1 EASST}
+    {794977200 -21600 0 EAST}
+    {813729600 -18000 1 EASST}
+    {826426800 -21600 0 EAST}
+    {845179200 -18000 1 EASST}
+    {859690800 -21600 0 EAST}
+    {876628800 -18000 1 EASST}
+    {889930800 -21600 0 EAST}
+    {906868800 -18000 1 EASST}
+    {923194800 -21600 0 EAST}
+    {939528000 -18000 1 EASST}
+    {952830000 -21600 0 EAST}
+    {971582400 -18000 1 EASST}
+    {984279600 -21600 0 EAST}
+    {1003032000 -18000 1 EASST}
+    {1015729200 -21600 0 EAST}
+    {1034481600 -18000 1 EASST}
+    {1047178800 -21600 0 EAST}
+    {1065931200 -18000 1 EASST}
+    {1079233200 -21600 0 EAST}
+    {1097380800 -18000 1 EASST}
+    {1110682800 -21600 0 EAST}
+    {1128830400 -18000 1 EASST}
+    {1142132400 -21600 0 EAST}
+    {1160884800 -18000 1 EASST}
+    {1173582000 -21600 0 EAST}
+    {1192334400 -18000 1 EASST}
+    {1206846000 -21600 0 EAST}
+    {1223784000 -18000 1 EASST}
+    {1237086000 -21600 0 EAST}
+    {1255233600 -18000 1 EASST}
+    {1270350000 -21600 0 EAST}
+    {1286683200 -18000 1 EASST}
+    {1304823600 -21600 0 EAST}
+    {1313899200 -18000 1 EASST}
+    {1335668400 -21600 0 EAST}
+    {1346558400 -18000 1 EASST}
+    {1367118000 -21600 0 EAST}
+    {1378612800 -18000 1 EASST}
+    {1398567600 -21600 0 EAST}
+    {1410062400 -18000 1 EASST}
+    {1463281200 -21600 0 EAST}
+    {1471147200 -18000 1 EASST}
+    {1494730800 -21600 0 EAST}
+    {1502596800 -18000 1 EASST}
+    {1526180400 -21600 0 EAST}
+    {1534046400 -18000 1 EASST}
+    {1557630000 -21600 0 EAST}
+    {1565496000 -18000 1 EASST}
+    {1589079600 -21600 0 EAST}
+    {1596945600 -18000 1 EASST}
+    {1620529200 -21600 0 EAST}
+    {1629000000 -18000 1 EASST}
+    {1652583600 -21600 0 EAST}
+    {1660449600 -18000 1 EASST}
+    {1684033200 -21600 0 EAST}
+    {1691899200 -18000 1 EASST}
+    {1715482800 -21600 0 EAST}
+    {1723348800 -18000 1 EASST}
+    {1746932400 -21600 0 EAST}
+    {1754798400 -18000 1 EASST}
+    {1778382000 -21600 0 EAST}
+    {1786248000 -18000 1 EASST}
+    {1809831600 -21600 0 EAST}
+    {1818302400 -18000 1 EASST}
+    {1841886000 -21600 0 EAST}
+    {1849752000 -18000 1 EASST}
+    {1873335600 -21600 0 EAST}
+    {1881201600 -18000 1 EASST}
+    {1904785200 -21600 0 EAST}
+    {1912651200 -18000 1 EASST}
+    {1936234800 -21600 0 EAST}
+    {1944100800 -18000 1 EASST}
+    {1967684400 -21600 0 EAST}
+    {1976155200 -18000 1 EASST}
+    {1999738800 -21600 0 EAST}
+    {2007604800 -18000 1 EASST}
+    {2031188400 -21600 0 EAST}
+    {2039054400 -18000 1 EASST}
+    {2062638000 -21600 0 EAST}
+    {2070504000 -18000 1 EASST}
+    {2094087600 -21600 0 EAST}
+    {2101953600 -18000 1 EASST}
+    {2125537200 -21600 0 EAST}
+    {2133403200 -18000 1 EASST}
+    {2156986800 -21600 0 EAST}
+    {2165457600 -18000 1 EASST}
+    {2189041200 -21600 0 EAST}
+    {2196907200 -18000 1 EASST}
+    {2220490800 -21600 0 EAST}
+    {2228356800 -18000 1 EASST}
+    {2251940400 -21600 0 EAST}
+    {2259806400 -18000 1 EASST}
+    {2283390000 -21600 0 EAST}
+    {2291256000 -18000 1 EASST}
+    {2314839600 -21600 0 EAST}
+    {2322705600 -18000 1 EASST}
+    {2346894000 -21600 0 EAST}
+    {2354760000 -18000 1 EASST}
+    {2378343600 -21600 0 EAST}
+    {2386209600 -18000 1 EASST}
+    {2409793200 -21600 0 EAST}
+    {2417659200 -18000 1 EASST}
+    {2441242800 -21600 0 EAST}
+    {2449108800 -18000 1 EASST}
+    {2472692400 -21600 0 EAST}
+    {2480558400 -18000 1 EASST}
+    {2504142000 -21600 0 EAST}
+    {2512612800 -18000 1 EASST}
+    {2536196400 -21600 0 EAST}
+    {2544062400 -18000 1 EASST}
+    {2567646000 -21600 0 EAST}
+    {2575512000 -18000 1 EASST}
+    {2599095600 -21600 0 EAST}
+    {2606961600 -18000 1 EASST}
+    {2630545200 -21600 0 EAST}
+    {2638411200 -18000 1 EASST}
+    {2661994800 -21600 0 EAST}
+    {2669860800 -18000 1 EASST}
+    {2693444400 -21600 0 EAST}
+    {2701915200 -18000 1 EASST}
+    {2725498800 -21600 0 EAST}
+    {2733364800 -18000 1 EASST}
+    {2756948400 -21600 0 EAST}
+    {2764814400 -18000 1 EASST}
+    {2788398000 -21600 0 EAST}
+    {2796264000 -18000 1 EASST}
+    {2819847600 -21600 0 EAST}
+    {2827713600 -18000 1 EASST}
+    {2851297200 -21600 0 EAST}
+    {2859768000 -18000 1 EASST}
+    {2883351600 -21600 0 EAST}
+    {2891217600 -18000 1 EASST}
+    {2914801200 -21600 0 EAST}
+    {2922667200 -18000 1 EASST}
+    {2946250800 -21600 0 EAST}
+    {2954116800 -18000 1 EASST}
+    {2977700400 -21600 0 EAST}
+    {2985566400 -18000 1 EASST}
+    {3009150000 -21600 0 EAST}
+    {3017016000 -18000 1 EASST}
+    {3040599600 -21600 0 EAST}
+    {3049070400 -18000 1 EASST}
+    {3072654000 -21600 0 EAST}
+    {3080520000 -18000 1 EASST}
+    {3104103600 -21600 0 EAST}
+    {3111969600 -18000 1 EASST}
+    {3135553200 -21600 0 EAST}
+    {3143419200 -18000 1 EASST}
+    {3167002800 -21600 0 EAST}
+    {3174868800 -18000 1 EASST}
+    {3198452400 -21600 0 EAST}
+    {3206318400 -18000 1 EASST}
+    {3230506800 -21600 0 EAST}
+    {3238372800 -18000 1 EASST}
+    {3261956400 -21600 0 EAST}
+    {3269822400 -18000 1 EASST}
+    {3293406000 -21600 0 EAST}
+    {3301272000 -18000 1 EASST}
+    {3324855600 -21600 0 EAST}
+    {3332721600 -18000 1 EASST}
+    {3356305200 -21600 0 EAST}
+    {3364171200 -18000 1 EASST}
+    {3387754800 -21600 0 EAST}
+    {3396225600 -18000 1 EASST}
+    {3419809200 -21600 0 EAST}
+    {3427675200 -18000 1 EASST}
+    {3451258800 -21600 0 EAST}
+    {3459124800 -18000 1 EASST}
+    {3482708400 -21600 0 EAST}
+    {3490574400 -18000 1 EASST}
+    {3514158000 -21600 0 EAST}
+    {3522024000 -18000 1 EASST}
+    {3545607600 -21600 0 EAST}
+    {3553473600 -18000 1 EASST}
+    {3577057200 -21600 0 EAST}
+    {3585528000 -18000 1 EASST}
+    {3609111600 -21600 0 EAST}
+    {3616977600 -18000 1 EASST}
+    {3640561200 -21600 0 EAST}
+    {3648427200 -18000 1 EASST}
+    {3672010800 -21600 0 EAST}
+    {3679876800 -18000 1 EASST}
+    {3703460400 -21600 0 EAST}
+    {3711326400 -18000 1 EASST}
+    {3734910000 -21600 0 EAST}
+    {3743380800 -18000 1 EASST}
+    {3766964400 -21600 0 EAST}
+    {3774830400 -18000 1 EASST}
+    {3798414000 -21600 0 EAST}
+    {3806280000 -18000 1 EASST}
+    {3829863600 -21600 0 EAST}
+    {3837729600 -18000 1 EASST}
+    {3861313200 -21600 0 EAST}
+    {3869179200 -18000 1 EASST}
+    {3892762800 -21600 0 EAST}
+    {3900628800 -18000 1 EASST}
+    {3924212400 -21600 0 EAST}
+    {3932683200 -18000 1 EASST}
+    {3956266800 -21600 0 EAST}
+    {3964132800 -18000 1 EASST}
+    {3987716400 -21600 0 EAST}
+    {3995582400 -18000 1 EASST}
+    {4019166000 -21600 0 EAST}
+    {4027032000 -18000 1 EASST}
+    {4050615600 -21600 0 EAST}
+    {4058481600 -18000 1 EASST}
+    {4082065200 -21600 0 EAST}
+    {4089931200 -18000 1 EASST}
+}
diff --git a/library/tzdata/Pacific/Efate b/library/tzdata/Pacific/Efate
new file mode 100644
index 0000000..18db6de
--- /dev/null
+++ b/library/tzdata/Pacific/Efate
@@ -0,0 +1,26 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Pacific/Efate) {
+    {-9223372036854775808 40396 0 LMT}
+    {-1829387596 39600 0 VUT}
+    {433256400 43200 1 VUST}
+    {448977600 39600 0 VUT}
+    {467298000 43200 1 VUST}
+    {480427200 39600 0 VUT}
+    {496760400 43200 1 VUST}
+    {511876800 39600 0 VUT}
+    {528210000 43200 1 VUST}
+    {543931200 39600 0 VUT}
+    {559659600 43200 1 VUST}
+    {575380800 39600 0 VUT}
+    {591109200 43200 1 VUST}
+    {606830400 39600 0 VUT}
+    {622558800 43200 1 VUST}
+    {638280000 39600 0 VUT}
+    {654008400 43200 1 VUST}
+    {669729600 39600 0 VUT}
+    {686062800 43200 1 VUST}
+    {696340800 39600 0 VUT}
+    {719931600 43200 1 VUST}
+    {727790400 39600 0 VUT}
+}
diff --git a/library/tzdata/Pacific/Enderbury b/library/tzdata/Pacific/Enderbury
new file mode 100644
index 0000000..55784c4
--- /dev/null
+++ b/library/tzdata/Pacific/Enderbury
@@ -0,0 +1,8 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Pacific/Enderbury) {
+    {-9223372036854775808 -41060 0 LMT}
+    {-2177411740 -43200 0 PHOT}
+    {307627200 -39600 0 PHOT}
+    {788958000 46800 0 PHOT}
+}
diff --git a/library/tzdata/Pacific/Fakaofo b/library/tzdata/Pacific/Fakaofo
new file mode 100644
index 0000000..6ec98eb
--- /dev/null
+++ b/library/tzdata/Pacific/Fakaofo
@@ -0,0 +1,7 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Pacific/Fakaofo) {
+    {-9223372036854775808 -41096 0 LMT}
+    {-2177411704 -39600 0 TKT}
+    {1325242800 46800 0 TKT}
+}
diff --git a/library/tzdata/Pacific/Fiji b/library/tzdata/Pacific/Fiji
new file mode 100644
index 0000000..8f8b12f
--- /dev/null
+++ b/library/tzdata/Pacific/Fiji
@@ -0,0 +1,191 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Pacific/Fiji) {
+    {-9223372036854775808 42944 0 LMT}
+    {-1709985344 43200 0 FJT}
+    {909842400 46800 1 FJST}
+    {920124000 43200 0 FJT}
+    {941896800 46800 1 FJST}
+    {951573600 43200 0 FJT}
+    {1259416800 46800 1 FJST}
+    {1269698400 43200 0 FJT}
+    {1287842400 46800 1 FJST}
+    {1299333600 43200 0 FJT}
+    {1319292000 46800 1 FJST}
+    {1327154400 43200 0 FJT}
+    {1350741600 46800 1 FJST}
+    {1358604000 43200 0 FJT}
+    {1382796000 46800 1 FJST}
+    {1390050000 43200 0 FJT}
+    {1414850400 46800 1 FJST}
+    {1421503200 43200 0 FJT}
+    {1446300000 46800 1 FJST}
+    {1452952800 43200 0 FJT}
+    {1478354400 46800 1 FJST}
+    {1484402400 43200 0 FJT}
+    {1509804000 46800 1 FJST}
+    {1516456800 43200 0 FJT}
+    {1541253600 46800 1 FJST}
+    {1547906400 43200 0 FJT}
+    {1572703200 46800 1 FJST}
+    {1579356000 43200 0 FJT}
+    {1604152800 46800 1 FJST}
+    {1610805600 43200 0 FJT}
+    {1636207200 46800 1 FJST}
+    {1642255200 43200 0 FJT}
+    {1667656800 46800 1 FJST}
+    {1673704800 43200 0 FJT}
+    {1699106400 46800 1 FJST}
+    {1705759200 43200 0 FJT}
+    {1730556000 46800 1 FJST}
+    {1737208800 43200 0 FJT}
+    {1762005600 46800 1 FJST}
+    {1768658400 43200 0 FJT}
+    {1793455200 46800 1 FJST}
+    {1800108000 43200 0 FJT}
+    {1825509600 46800 1 FJST}
+    {1831557600 43200 0 FJT}
+    {1856959200 46800 1 FJST}
+    {1863612000 43200 0 FJT}
+    {1888408800 46800 1 FJST}
+    {1895061600 43200 0 FJT}
+    {1919858400 46800 1 FJST}
+    {1926511200 43200 0 FJT}
+    {1951308000 46800 1 FJST}
+    {1957960800 43200 0 FJT}
+    {1983362400 46800 1 FJST}
+    {1989410400 43200 0 FJT}
+    {2014812000 46800 1 FJST}
+    {2020860000 43200 0 FJT}
+    {2046261600 46800 1 FJST}
+    {2052914400 43200 0 FJT}
+    {2077711200 46800 1 FJST}
+    {2084364000 43200 0 FJT}
+    {2109160800 46800 1 FJST}
+    {2115813600 43200 0 FJT}
+    {2140610400 46800 1 FJST}
+    {2147263200 43200 0 FJT}
+    {2172664800 46800 1 FJST}
+    {2178712800 43200 0 FJT}
+    {2204114400 46800 1 FJST}
+    {2210162400 43200 0 FJT}
+    {2235564000 46800 1 FJST}
+    {2242216800 43200 0 FJT}
+    {2267013600 46800 1 FJST}
+    {2273666400 43200 0 FJT}
+    {2298463200 46800 1 FJST}
+    {2305116000 43200 0 FJT}
+    {2329912800 46800 1 FJST}
+    {2336565600 43200 0 FJT}
+    {2361967200 46800 1 FJST}
+    {2368015200 43200 0 FJT}
+    {2393416800 46800 1 FJST}
+    {2400069600 43200 0 FJT}
+    {2424866400 46800 1 FJST}
+    {2431519200 43200 0 FJT}
+    {2456316000 46800 1 FJST}
+    {2462968800 43200 0 FJT}
+    {2487765600 46800 1 FJST}
+    {2494418400 43200 0 FJT}
+    {2519820000 46800 1 FJST}
+    {2525868000 43200 0 FJT}
+    {2551269600 46800 1 FJST}
+    {2557317600 43200 0 FJT}
+    {2582719200 46800 1 FJST}
+    {2589372000 43200 0 FJT}
+    {2614168800 46800 1 FJST}
+    {2620821600 43200 0 FJT}
+    {2645618400 46800 1 FJST}
+    {2652271200 43200 0 FJT}
+    {2677068000 46800 1 FJST}
+    {2683720800 43200 0 FJT}
+    {2709122400 46800 1 FJST}
+    {2715170400 43200 0 FJT}
+    {2740572000 46800 1 FJST}
+    {2747224800 43200 0 FJT}
+    {2772021600 46800 1 FJST}
+    {2778674400 43200 0 FJT}
+    {2803471200 46800 1 FJST}
+    {2810124000 43200 0 FJT}
+    {2834920800 46800 1 FJST}
+    {2841573600 43200 0 FJT}
+    {2866975200 46800 1 FJST}
+    {2873023200 43200 0 FJT}
+    {2898424800 46800 1 FJST}
+    {2904472800 43200 0 FJT}
+    {2929874400 46800 1 FJST}
+    {2936527200 43200 0 FJT}
+    {2961324000 46800 1 FJST}
+    {2967976800 43200 0 FJT}
+    {2992773600 46800 1 FJST}
+    {2999426400 43200 0 FJT}
+    {3024223200 46800 1 FJST}
+    {3030876000 43200 0 FJT}
+    {3056277600 46800 1 FJST}
+    {3062325600 43200 0 FJT}
+    {3087727200 46800 1 FJST}
+    {3093775200 43200 0 FJT}
+    {3119176800 46800 1 FJST}
+    {3125829600 43200 0 FJT}
+    {3150626400 46800 1 FJST}
+    {3157279200 43200 0 FJT}
+    {3182076000 46800 1 FJST}
+    {3188728800 43200 0 FJT}
+    {3213525600 46800 1 FJST}
+    {3220178400 43200 0 FJT}
+    {3245580000 46800 1 FJST}
+    {3251628000 43200 0 FJT}
+    {3277029600 46800 1 FJST}
+    {3283682400 43200 0 FJT}
+    {3308479200 46800 1 FJST}
+    {3315132000 43200 0 FJT}
+    {3339928800 46800 1 FJST}
+    {3346581600 43200 0 FJT}
+    {3371378400 46800 1 FJST}
+    {3378031200 43200 0 FJT}
+    {3403432800 46800 1 FJST}
+    {3409480800 43200 0 FJT}
+    {3434882400 46800 1 FJST}
+    {3440930400 43200 0 FJT}
+    {3466332000 46800 1 FJST}
+    {3472984800 43200 0 FJT}
+    {3497781600 46800 1 FJST}
+    {3504434400 43200 0 FJT}
+    {3529231200 46800 1 FJST}
+    {3535884000 43200 0 FJT}
+    {3560680800 46800 1 FJST}
+    {3567333600 43200 0 FJT}
+    {3592735200 46800 1 FJST}
+    {3598783200 43200 0 FJT}
+    {3624184800 46800 1 FJST}
+    {3630837600 43200 0 FJT}
+    {3655634400 46800 1 FJST}
+    {3662287200 43200 0 FJT}
+    {3687084000 46800 1 FJST}
+    {3693736800 43200 0 FJT}
+    {3718533600 46800 1 FJST}
+    {3725186400 43200 0 FJT}
+    {3750588000 46800 1 FJST}
+    {3756636000 43200 0 FJT}
+    {3782037600 46800 1 FJST}
+    {3788085600 43200 0 FJT}
+    {3813487200 46800 1 FJST}
+    {3820140000 43200 0 FJT}
+    {3844936800 46800 1 FJST}
+    {3851589600 43200 0 FJT}
+    {3876386400 46800 1 FJST}
+    {3883039200 43200 0 FJT}
+    {3907836000 46800 1 FJST}
+    {3914488800 43200 0 FJT}
+    {3939890400 46800 1 FJST}
+    {3945938400 43200 0 FJT}
+    {3971340000 46800 1 FJST}
+    {3977388000 43200 0 FJT}
+    {4002789600 46800 1 FJST}
+    {4009442400 43200 0 FJT}
+    {4034239200 46800 1 FJST}
+    {4040892000 43200 0 FJT}
+    {4065688800 46800 1 FJST}
+    {4072341600 43200 0 FJT}
+    {4097138400 46800 1 FJST}
+}
diff --git a/library/tzdata/Pacific/Funafuti b/library/tzdata/Pacific/Funafuti
new file mode 100644
index 0000000..b94e4fb
--- /dev/null
+++ b/library/tzdata/Pacific/Funafuti
@@ -0,0 +1,6 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Pacific/Funafuti) {
+    {-9223372036854775808 43012 0 LMT}
+    {-2177495812 43200 0 TVT}
+}
diff --git a/library/tzdata/Pacific/Galapagos b/library/tzdata/Pacific/Galapagos
new file mode 100644
index 0000000..d8c80e8
--- /dev/null
+++ b/library/tzdata/Pacific/Galapagos
@@ -0,0 +1,7 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Pacific/Galapagos) {
+    {-9223372036854775808 -21504 0 LMT}
+    {-1230746496 -18000 0 ECT}
+    {504939600 -21600 0 GALT}
+}
diff --git a/library/tzdata/Pacific/Gambier b/library/tzdata/Pacific/Gambier
new file mode 100644
index 0000000..d69f99a
--- /dev/null
+++ b/library/tzdata/Pacific/Gambier
@@ -0,0 +1,6 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Pacific/Gambier) {
+    {-9223372036854775808 -32388 0 LMT}
+    {-1806678012 -32400 0 GAMT}
+}
diff --git a/library/tzdata/Pacific/Guadalcanal b/library/tzdata/Pacific/Guadalcanal
new file mode 100644
index 0000000..09a67dd
--- /dev/null
+++ b/library/tzdata/Pacific/Guadalcanal
@@ -0,0 +1,6 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Pacific/Guadalcanal) {
+    {-9223372036854775808 38388 0 LMT}
+    {-1806748788 39600 0 SBT}
+}
diff --git a/library/tzdata/Pacific/Guam b/library/tzdata/Pacific/Guam
new file mode 100644
index 0000000..79cca80
--- /dev/null
+++ b/library/tzdata/Pacific/Guam
@@ -0,0 +1,8 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Pacific/Guam) {
+    {-9223372036854775808 -51660 0 LMT}
+    {-3944626740 34740 0 LMT}
+    {-2177487540 36000 0 GST}
+    {977493600 36000 0 ChST}
+}
diff --git a/library/tzdata/Pacific/Honolulu b/library/tzdata/Pacific/Honolulu
new file mode 100644
index 0000000..5e70598
--- /dev/null
+++ b/library/tzdata/Pacific/Honolulu
@@ -0,0 +1,11 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Pacific/Honolulu) {
+    {-9223372036854775808 -37886 0 LMT}
+    {-2334101314 -37800 0 HST}
+    {-1157283000 -34200 1 HDT}
+    {-1155436200 -37800 0 HST}
+    {-880198200 -34200 1 HDT}
+    {-765376200 -37800 0 HST}
+    {-712150200 -36000 0 HST}
+}
diff --git a/library/tzdata/Pacific/Johnston b/library/tzdata/Pacific/Johnston
new file mode 100644
index 0000000..21ab39a
--- /dev/null
+++ b/library/tzdata/Pacific/Johnston
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Pacific/Honolulu)]} {
+    LoadTimeZoneFile Pacific/Honolulu
+}
+set TZData(:Pacific/Johnston) $TZData(:Pacific/Honolulu)
diff --git a/library/tzdata/Pacific/Kiritimati b/library/tzdata/Pacific/Kiritimati
new file mode 100644
index 0000000..06b695b
--- /dev/null
+++ b/library/tzdata/Pacific/Kiritimati
@@ -0,0 +1,8 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Pacific/Kiritimati) {
+    {-9223372036854775808 -37760 0 LMT}
+    {-2177415040 -38400 0 LINT}
+    {307622400 -36000 0 LINT}
+    {788954400 50400 0 LINT}
+}
diff --git a/library/tzdata/Pacific/Kosrae b/library/tzdata/Pacific/Kosrae
new file mode 100644
index 0000000..a16b19d
--- /dev/null
+++ b/library/tzdata/Pacific/Kosrae
@@ -0,0 +1,8 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Pacific/Kosrae) {
+    {-9223372036854775808 39116 0 LMT}
+    {-2177491916 39600 0 KOST}
+    {-7988400 43200 0 KOST}
+    {915105600 39600 0 KOST}
+}
diff --git a/library/tzdata/Pacific/Kwajalein b/library/tzdata/Pacific/Kwajalein
new file mode 100644
index 0000000..8600b3b
--- /dev/null
+++ b/library/tzdata/Pacific/Kwajalein
@@ -0,0 +1,8 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Pacific/Kwajalein) {
+    {-9223372036854775808 40160 0 LMT}
+    {-2177492960 39600 0 MHT}
+    {-7988400 -43200 0 KWAT}
+    {745848000 43200 0 MHT}
+}
diff --git a/library/tzdata/Pacific/Majuro b/library/tzdata/Pacific/Majuro
new file mode 100644
index 0000000..468baab
--- /dev/null
+++ b/library/tzdata/Pacific/Majuro
@@ -0,0 +1,7 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Pacific/Majuro) {
+    {-9223372036854775808 41088 0 LMT}
+    {-2177493888 39600 0 MHT}
+    {-7988400 43200 0 MHT}
+}
diff --git a/library/tzdata/Pacific/Marquesas b/library/tzdata/Pacific/Marquesas
new file mode 100644
index 0000000..9bb508f
--- /dev/null
+++ b/library/tzdata/Pacific/Marquesas
@@ -0,0 +1,6 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Pacific/Marquesas) {
+    {-9223372036854775808 -33480 0 LMT}
+    {-1806676920 -34200 0 MART}
+}
diff --git a/library/tzdata/Pacific/Midway b/library/tzdata/Pacific/Midway
new file mode 100644
index 0000000..d044569
--- /dev/null
+++ b/library/tzdata/Pacific/Midway
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Pacific/Pago_Pago)]} {
+    LoadTimeZoneFile Pacific/Pago_Pago
+}
+set TZData(:Pacific/Midway) $TZData(:Pacific/Pago_Pago)
diff --git a/library/tzdata/Pacific/Nauru b/library/tzdata/Pacific/Nauru
new file mode 100644
index 0000000..2da1e25
--- /dev/null
+++ b/library/tzdata/Pacific/Nauru
@@ -0,0 +1,9 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Pacific/Nauru) {
+    {-9223372036854775808 40060 0 LMT}
+    {-1545131260 41400 0 NRT}
+    {-877347000 32400 0 JST}
+    {-800960400 41400 0 NRT}
+    {294323400 43200 0 NRT}
+}
diff --git a/library/tzdata/Pacific/Niue b/library/tzdata/Pacific/Niue
new file mode 100644
index 0000000..cf149fc
--- /dev/null
+++ b/library/tzdata/Pacific/Niue
@@ -0,0 +1,8 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Pacific/Niue) {
+    {-9223372036854775808 -40780 0 LMT}
+    {-2177412020 -40800 0 NUT}
+    {-599575200 -41400 0 NUT}
+    {276089400 -39600 0 NUT}
+}
diff --git a/library/tzdata/Pacific/Norfolk b/library/tzdata/Pacific/Norfolk
new file mode 100644
index 0000000..b12ab8c
--- /dev/null
+++ b/library/tzdata/Pacific/Norfolk
@@ -0,0 +1,10 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Pacific/Norfolk) {
+    {-9223372036854775808 40312 0 LMT}
+    {-2177493112 40320 0 NMT}
+    {-599656320 41400 0 NFT}
+    {152029800 45000 1 NFST}
+    {162912600 41400 0 NFT}
+    {1443882600 39600 0 NFT}
+}
diff --git a/library/tzdata/Pacific/Noumea b/library/tzdata/Pacific/Noumea
new file mode 100644
index 0000000..db1eeae
--- /dev/null
+++ b/library/tzdata/Pacific/Noumea
@@ -0,0 +1,12 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Pacific/Noumea) {
+    {-9223372036854775808 39948 0 LMT}
+    {-1829387148 39600 0 NCT}
+    {250002000 43200 1 NCST}
+    {257342400 39600 0 NCT}
+    {281451600 43200 1 NCST}
+    {288878400 39600 0 NCT}
+    {849366000 43200 1 NCST}
+    {857228400 39600 0 NCT}
+}
diff --git a/library/tzdata/Pacific/Pago_Pago b/library/tzdata/Pacific/Pago_Pago
new file mode 100644
index 0000000..ca261d0
--- /dev/null
+++ b/library/tzdata/Pacific/Pago_Pago
@@ -0,0 +1,9 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Pacific/Pago_Pago) {
+    {-9223372036854775808 45432 0 LMT}
+    {-2855738232 -40968 0 LMT}
+    {-1861879032 -39600 0 NST}
+    {-86878800 -39600 0 BST}
+    {439038000 -39600 0 SST}
+}
diff --git a/library/tzdata/Pacific/Palau b/library/tzdata/Pacific/Palau
new file mode 100644
index 0000000..ee0606d
--- /dev/null
+++ b/library/tzdata/Pacific/Palau
@@ -0,0 +1,6 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Pacific/Palau) {
+    {-9223372036854775808 32276 0 LMT}
+    {-2177485076 32400 0 PWT}
+}
diff --git a/library/tzdata/Pacific/Pitcairn b/library/tzdata/Pacific/Pitcairn
new file mode 100644
index 0000000..d62644e
--- /dev/null
+++ b/library/tzdata/Pacific/Pitcairn
@@ -0,0 +1,7 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Pacific/Pitcairn) {
+    {-9223372036854775808 -31220 0 LMT}
+    {-2177421580 -30600 0 PNT}
+    {893665800 -28800 0 PST}
+}
diff --git a/library/tzdata/Pacific/Pohnpei b/library/tzdata/Pacific/Pohnpei
new file mode 100644
index 0000000..58978da
--- /dev/null
+++ b/library/tzdata/Pacific/Pohnpei
@@ -0,0 +1,6 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Pacific/Pohnpei) {
+    {-9223372036854775808 37972 0 LMT}
+    {-2177490772 39600 0 PONT}
+}
diff --git a/library/tzdata/Pacific/Ponape b/library/tzdata/Pacific/Ponape
new file mode 100644
index 0000000..89644f7
--- /dev/null
+++ b/library/tzdata/Pacific/Ponape
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Pacific/Pohnpei)]} {
+    LoadTimeZoneFile Pacific/Pohnpei
+}
+set TZData(:Pacific/Ponape) $TZData(:Pacific/Pohnpei)
diff --git a/library/tzdata/Pacific/Port_Moresby b/library/tzdata/Pacific/Port_Moresby
new file mode 100644
index 0000000..65eb533
--- /dev/null
+++ b/library/tzdata/Pacific/Port_Moresby
@@ -0,0 +1,7 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Pacific/Port_Moresby) {
+    {-9223372036854775808 35320 0 LMT}
+    {-2840176120 35312 0 PMMT}
+    {-2366790512 36000 0 PGT}
+}
diff --git a/library/tzdata/Pacific/Rarotonga b/library/tzdata/Pacific/Rarotonga
new file mode 100644
index 0000000..a4ecf8d
--- /dev/null
+++ b/library/tzdata/Pacific/Rarotonga
@@ -0,0 +1,32 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Pacific/Rarotonga) {
+    {-9223372036854775808 -38344 0 LMT}
+    {-2177414456 -37800 0 CKT}
+    {279714600 -34200 0 CKHST}
+    {289387800 -36000 0 CKT}
+    {309952800 -34200 1 CKHST}
+    {320837400 -36000 0 CKT}
+    {341402400 -34200 1 CKHST}
+    {352287000 -36000 0 CKT}
+    {372852000 -34200 1 CKHST}
+    {384341400 -36000 0 CKT}
+    {404906400 -34200 1 CKHST}
+    {415791000 -36000 0 CKT}
+    {436356000 -34200 1 CKHST}
+    {447240600 -36000 0 CKT}
+    {467805600 -34200 1 CKHST}
+    {478690200 -36000 0 CKT}
+    {499255200 -34200 1 CKHST}
+    {510139800 -36000 0 CKT}
+    {530704800 -34200 1 CKHST}
+    {541589400 -36000 0 CKT}
+    {562154400 -34200 1 CKHST}
+    {573643800 -36000 0 CKT}
+    {594208800 -34200 1 CKHST}
+    {605093400 -36000 0 CKT}
+    {625658400 -34200 1 CKHST}
+    {636543000 -36000 0 CKT}
+    {657108000 -34200 1 CKHST}
+    {667992600 -36000 0 CKT}
+}
diff --git a/library/tzdata/Pacific/Saipan b/library/tzdata/Pacific/Saipan
new file mode 100644
index 0000000..4e769cd
--- /dev/null
+++ b/library/tzdata/Pacific/Saipan
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Pacific/Guam)]} {
+    LoadTimeZoneFile Pacific/Guam
+}
+set TZData(:Pacific/Saipan) $TZData(:Pacific/Guam)
diff --git a/library/tzdata/Pacific/Samoa b/library/tzdata/Pacific/Samoa
new file mode 100644
index 0000000..686eb34
--- /dev/null
+++ b/library/tzdata/Pacific/Samoa
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Pacific/Pago_Pago)]} {
+    LoadTimeZoneFile Pacific/Pago_Pago
+}
+set TZData(:Pacific/Samoa) $TZData(:Pacific/Pago_Pago)
diff --git a/library/tzdata/Pacific/Tahiti b/library/tzdata/Pacific/Tahiti
new file mode 100644
index 0000000..f739223
--- /dev/null
+++ b/library/tzdata/Pacific/Tahiti
@@ -0,0 +1,6 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Pacific/Tahiti) {
+    {-9223372036854775808 -35896 0 LMT}
+    {-1806674504 -36000 0 TAHT}
+}
diff --git a/library/tzdata/Pacific/Tarawa b/library/tzdata/Pacific/Tarawa
new file mode 100644
index 0000000..2dab5a2
--- /dev/null
+++ b/library/tzdata/Pacific/Tarawa
@@ -0,0 +1,6 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Pacific/Tarawa) {
+    {-9223372036854775808 41524 0 LMT}
+    {-2177494324 43200 0 GILT}
+}
diff --git a/library/tzdata/Pacific/Tongatapu b/library/tzdata/Pacific/Tongatapu
new file mode 100644
index 0000000..da9f857
--- /dev/null
+++ b/library/tzdata/Pacific/Tongatapu
@@ -0,0 +1,14 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Pacific/Tongatapu) {
+    {-9223372036854775808 44360 0 LMT}
+    {-2177497160 44400 0 TOT}
+    {-915193200 46800 0 TOT}
+    {915102000 46800 0 TOT}
+    {939214800 50400 1 TOST}
+    {953384400 46800 0 TOT}
+    {973342800 50400 1 TOST}
+    {980596800 46800 0 TOT}
+    {1004792400 50400 1 TOST}
+    {1012046400 46800 0 TOT}
+}
diff --git a/library/tzdata/Pacific/Truk b/library/tzdata/Pacific/Truk
new file mode 100644
index 0000000..c9b1894
--- /dev/null
+++ b/library/tzdata/Pacific/Truk
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Pacific/Chuuk)]} {
+    LoadTimeZoneFile Pacific/Chuuk
+}
+set TZData(:Pacific/Truk) $TZData(:Pacific/Chuuk)
diff --git a/library/tzdata/Pacific/Wake b/library/tzdata/Pacific/Wake
new file mode 100644
index 0000000..5afedf5
--- /dev/null
+++ b/library/tzdata/Pacific/Wake
@@ -0,0 +1,6 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Pacific/Wake) {
+    {-9223372036854775808 39988 0 LMT}
+    {-2177492788 43200 0 WAKT}
+}
diff --git a/library/tzdata/Pacific/Wallis b/library/tzdata/Pacific/Wallis
new file mode 100644
index 0000000..7bdd964
--- /dev/null
+++ b/library/tzdata/Pacific/Wallis
@@ -0,0 +1,6 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:Pacific/Wallis) {
+    {-9223372036854775808 44120 0 LMT}
+    {-2177496920 43200 0 WFT}
+}
diff --git a/library/tzdata/Pacific/Yap b/library/tzdata/Pacific/Yap
new file mode 100644
index 0000000..4931030
--- /dev/null
+++ b/library/tzdata/Pacific/Yap
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Pacific/Chuuk)]} {
+    LoadTimeZoneFile Pacific/Chuuk
+}
+set TZData(:Pacific/Yap) $TZData(:Pacific/Chuuk)
diff --git a/library/tzdata/Poland b/library/tzdata/Poland
new file mode 100644
index 0000000..bd24028
--- /dev/null
+++ b/library/tzdata/Poland
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Europe/Warsaw)]} {
+    LoadTimeZoneFile Europe/Warsaw
+}
+set TZData(:Poland) $TZData(:Europe/Warsaw)
diff --git a/library/tzdata/Portugal b/library/tzdata/Portugal
new file mode 100644
index 0000000..d1ffd9f
--- /dev/null
+++ b/library/tzdata/Portugal
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Europe/Lisbon)]} {
+    LoadTimeZoneFile Europe/Lisbon
+}
+set TZData(:Portugal) $TZData(:Europe/Lisbon)
diff --git a/library/tzdata/ROC b/library/tzdata/ROC
new file mode 100644
index 0000000..5dd196d
--- /dev/null
+++ b/library/tzdata/ROC
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Asia/Taipei)]} {
+    LoadTimeZoneFile Asia/Taipei
+}
+set TZData(:ROC) $TZData(:Asia/Taipei)
diff --git a/library/tzdata/ROK b/library/tzdata/ROK
new file mode 100644
index 0000000..1162ce4
--- /dev/null
+++ b/library/tzdata/ROK
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Asia/Seoul)]} {
+    LoadTimeZoneFile Asia/Seoul
+}
+set TZData(:ROK) $TZData(:Asia/Seoul)
diff --git a/library/tzdata/Singapore b/library/tzdata/Singapore
new file mode 100644
index 0000000..1584b35
--- /dev/null
+++ b/library/tzdata/Singapore
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Asia/Singapore)]} {
+    LoadTimeZoneFile Asia/Singapore
+}
+set TZData(:Singapore) $TZData(:Asia/Singapore)
diff --git a/library/tzdata/SystemV/AST4 b/library/tzdata/SystemV/AST4
new file mode 100644
index 0000000..eced0d2
--- /dev/null
+++ b/library/tzdata/SystemV/AST4
@@ -0,0 +1,5 @@
+# created by ../tools/tclZIC.tcl - do not edit
+if {![info exists TZData(America/Puerto_Rico)]} {
+    LoadTimeZoneFile America/Puerto_Rico
+}
+set TZData(:SystemV/AST4) $TZData(:America/Puerto_Rico)
diff --git a/library/tzdata/SystemV/AST4ADT b/library/tzdata/SystemV/AST4ADT
new file mode 100644
index 0000000..c24308f
--- /dev/null
+++ b/library/tzdata/SystemV/AST4ADT
@@ -0,0 +1,5 @@
+# created by ../tools/tclZIC.tcl - do not edit
+if {![info exists TZData(America/Halifax)]} {
+    LoadTimeZoneFile America/Halifax
+}
+set TZData(:SystemV/AST4ADT) $TZData(:America/Halifax)
diff --git a/library/tzdata/SystemV/CST6 b/library/tzdata/SystemV/CST6
new file mode 100644
index 0000000..d46c015
--- /dev/null
+++ b/library/tzdata/SystemV/CST6
@@ -0,0 +1,5 @@
+# created by ../tools/tclZIC.tcl - do not edit
+if {![info exists TZData(America/Regina)]} {
+    LoadTimeZoneFile America/Regina
+}
+set TZData(:SystemV/CST6) $TZData(:America/Regina)
diff --git a/library/tzdata/SystemV/CST6CDT b/library/tzdata/SystemV/CST6CDT
new file mode 100644
index 0000000..234af89
--- /dev/null
+++ b/library/tzdata/SystemV/CST6CDT
@@ -0,0 +1,5 @@
+# created by ../tools/tclZIC.tcl - do not edit
+if {![info exists TZData(America/Chicago)]} {
+    LoadTimeZoneFile America/Chicago
+}
+set TZData(:SystemV/CST6CDT) $TZData(:America/Chicago)
diff --git a/library/tzdata/SystemV/EST5 b/library/tzdata/SystemV/EST5
new file mode 100644
index 0000000..52818c1
--- /dev/null
+++ b/library/tzdata/SystemV/EST5
@@ -0,0 +1,5 @@
+# created by ../tools/tclZIC.tcl - do not edit
+if {![info exists TZData(America/Indianapolis)]} {
+    LoadTimeZoneFile America/Indianapolis
+}
+set TZData(:SystemV/EST5) $TZData(:America/Indianapolis)
diff --git a/library/tzdata/SystemV/EST5EDT b/library/tzdata/SystemV/EST5EDT
new file mode 100644
index 0000000..6cf2743
--- /dev/null
+++ b/library/tzdata/SystemV/EST5EDT
@@ -0,0 +1,5 @@
+# created by ../tools/tclZIC.tcl - do not edit
+if {![info exists TZData(America/New_York)]} {
+    LoadTimeZoneFile America/New_York
+}
+set TZData(:SystemV/EST5EDT) $TZData(:America/New_York)
diff --git a/library/tzdata/SystemV/HST10 b/library/tzdata/SystemV/HST10
new file mode 100644
index 0000000..a4316af
--- /dev/null
+++ b/library/tzdata/SystemV/HST10
@@ -0,0 +1,5 @@
+# created by ../tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Pacific/Honolulu)]} {
+    LoadTimeZoneFile Pacific/Honolulu
+}
+set TZData(:SystemV/HST10) $TZData(:Pacific/Honolulu)
diff --git a/library/tzdata/SystemV/MST7 b/library/tzdata/SystemV/MST7
new file mode 100644
index 0000000..e67a781
--- /dev/null
+++ b/library/tzdata/SystemV/MST7
@@ -0,0 +1,5 @@
+# created by ../tools/tclZIC.tcl - do not edit
+if {![info exists TZData(America/Phoenix)]} {
+    LoadTimeZoneFile America/Phoenix
+}
+set TZData(:SystemV/MST7) $TZData(:America/Phoenix)
diff --git a/library/tzdata/SystemV/MST7MDT b/library/tzdata/SystemV/MST7MDT
new file mode 100644
index 0000000..fda5bf1
--- /dev/null
+++ b/library/tzdata/SystemV/MST7MDT
@@ -0,0 +1,5 @@
+# created by ../tools/tclZIC.tcl - do not edit
+if {![info exists TZData(America/Denver)]} {
+    LoadTimeZoneFile America/Denver
+}
+set TZData(:SystemV/MST7MDT) $TZData(:America/Denver)
diff --git a/library/tzdata/SystemV/PST8 b/library/tzdata/SystemV/PST8
new file mode 100644
index 0000000..8e30bb8
--- /dev/null
+++ b/library/tzdata/SystemV/PST8
@@ -0,0 +1,5 @@
+# created by ../tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Pacific/Pitcairn)]} {
+    LoadTimeZoneFile Pacific/Pitcairn
+}
+set TZData(:SystemV/PST8) $TZData(:Pacific/Pitcairn)
diff --git a/library/tzdata/SystemV/PST8PDT b/library/tzdata/SystemV/PST8PDT
new file mode 100644
index 0000000..8281a9a
--- /dev/null
+++ b/library/tzdata/SystemV/PST8PDT
@@ -0,0 +1,5 @@
+# created by ../tools/tclZIC.tcl - do not edit
+if {![info exists TZData(America/Los_Angeles)]} {
+    LoadTimeZoneFile America/Los_Angeles
+}
+set TZData(:SystemV/PST8PDT) $TZData(:America/Los_Angeles)
diff --git a/library/tzdata/SystemV/YST9 b/library/tzdata/SystemV/YST9
new file mode 100644
index 0000000..32d3717
--- /dev/null
+++ b/library/tzdata/SystemV/YST9
@@ -0,0 +1,5 @@
+# created by ../tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Pacific/Gambier)]} {
+    LoadTimeZoneFile Pacific/Gambier
+}
+set TZData(:SystemV/YST9) $TZData(:Pacific/Gambier)
diff --git a/library/tzdata/SystemV/YST9YDT b/library/tzdata/SystemV/YST9YDT
new file mode 100644
index 0000000..fba405f
--- /dev/null
+++ b/library/tzdata/SystemV/YST9YDT
@@ -0,0 +1,5 @@
+# created by ../tools/tclZIC.tcl - do not edit
+if {![info exists TZData(America/Anchorage)]} {
+    LoadTimeZoneFile America/Anchorage
+}
+set TZData(:SystemV/YST9YDT) $TZData(:America/Anchorage)
diff --git a/library/tzdata/Turkey b/library/tzdata/Turkey
new file mode 100644
index 0000000..e20a7a5
--- /dev/null
+++ b/library/tzdata/Turkey
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Europe/Istanbul)]} {
+    LoadTimeZoneFile Europe/Istanbul
+}
+set TZData(:Turkey) $TZData(:Europe/Istanbul)
diff --git a/library/tzdata/UCT b/library/tzdata/UCT
new file mode 100644
index 0000000..8449328
--- /dev/null
+++ b/library/tzdata/UCT
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Etc/UCT)]} {
+    LoadTimeZoneFile Etc/UCT
+}
+set TZData(:UCT) $TZData(:Etc/UCT)
diff --git a/library/tzdata/US/Alaska b/library/tzdata/US/Alaska
new file mode 100644
index 0000000..69a3899
--- /dev/null
+++ b/library/tzdata/US/Alaska
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(America/Anchorage)]} {
+    LoadTimeZoneFile America/Anchorage
+}
+set TZData(:US/Alaska) $TZData(:America/Anchorage)
diff --git a/library/tzdata/US/Aleutian b/library/tzdata/US/Aleutian
new file mode 100644
index 0000000..024e70b
--- /dev/null
+++ b/library/tzdata/US/Aleutian
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(America/Adak)]} {
+    LoadTimeZoneFile America/Adak
+}
+set TZData(:US/Aleutian) $TZData(:America/Adak)
diff --git a/library/tzdata/US/Arizona b/library/tzdata/US/Arizona
new file mode 100644
index 0000000..8eaa961
--- /dev/null
+++ b/library/tzdata/US/Arizona
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(America/Phoenix)]} {
+    LoadTimeZoneFile America/Phoenix
+}
+set TZData(:US/Arizona) $TZData(:America/Phoenix)
diff --git a/library/tzdata/US/Central b/library/tzdata/US/Central
new file mode 100644
index 0000000..2aab66e
--- /dev/null
+++ b/library/tzdata/US/Central
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(America/Chicago)]} {
+    LoadTimeZoneFile America/Chicago
+}
+set TZData(:US/Central) $TZData(:America/Chicago)
diff --git a/library/tzdata/US/East-Indiana b/library/tzdata/US/East-Indiana
new file mode 100644
index 0000000..2035a06
--- /dev/null
+++ b/library/tzdata/US/East-Indiana
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(America/Indiana/Indianapolis)]} {
+    LoadTimeZoneFile America/Indiana/Indianapolis
+}
+set TZData(:US/East-Indiana) $TZData(:America/Indiana/Indianapolis)
diff --git a/library/tzdata/US/Eastern b/library/tzdata/US/Eastern
new file mode 100644
index 0000000..3cf2651
--- /dev/null
+++ b/library/tzdata/US/Eastern
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(America/New_York)]} {
+    LoadTimeZoneFile America/New_York
+}
+set TZData(:US/Eastern) $TZData(:America/New_York)
diff --git a/library/tzdata/US/Hawaii b/library/tzdata/US/Hawaii
new file mode 100644
index 0000000..6d1af65
--- /dev/null
+++ b/library/tzdata/US/Hawaii
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Pacific/Honolulu)]} {
+    LoadTimeZoneFile Pacific/Honolulu
+}
+set TZData(:US/Hawaii) $TZData(:Pacific/Honolulu)
diff --git a/library/tzdata/US/Indiana-Starke b/library/tzdata/US/Indiana-Starke
new file mode 100644
index 0000000..6ffe0e2
--- /dev/null
+++ b/library/tzdata/US/Indiana-Starke
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(America/Indiana/Knox)]} {
+    LoadTimeZoneFile America/Indiana/Knox
+}
+set TZData(:US/Indiana-Starke) $TZData(:America/Indiana/Knox)
diff --git a/library/tzdata/US/Michigan b/library/tzdata/US/Michigan
new file mode 100644
index 0000000..b15035c
--- /dev/null
+++ b/library/tzdata/US/Michigan
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(America/Detroit)]} {
+    LoadTimeZoneFile America/Detroit
+}
+set TZData(:US/Michigan) $TZData(:America/Detroit)
diff --git a/library/tzdata/US/Mountain b/library/tzdata/US/Mountain
new file mode 100644
index 0000000..b54235f
--- /dev/null
+++ b/library/tzdata/US/Mountain
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(America/Denver)]} {
+    LoadTimeZoneFile America/Denver
+}
+set TZData(:US/Mountain) $TZData(:America/Denver)
diff --git a/library/tzdata/US/Pacific b/library/tzdata/US/Pacific
new file mode 100644
index 0000000..7232215
--- /dev/null
+++ b/library/tzdata/US/Pacific
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(America/Los_Angeles)]} {
+    LoadTimeZoneFile America/Los_Angeles
+}
+set TZData(:US/Pacific) $TZData(:America/Los_Angeles)
diff --git a/library/tzdata/US/Pacific-New b/library/tzdata/US/Pacific-New
new file mode 100644
index 0000000..2eb30f8
--- /dev/null
+++ b/library/tzdata/US/Pacific-New
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(America/Los_Angeles)]} {
+    LoadTimeZoneFile America/Los_Angeles
+}
+set TZData(:US/Pacific-New) $TZData(:America/Los_Angeles)
diff --git a/library/tzdata/US/Samoa b/library/tzdata/US/Samoa
new file mode 100644
index 0000000..ad86b4f
--- /dev/null
+++ b/library/tzdata/US/Samoa
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Pacific/Pago_Pago)]} {
+    LoadTimeZoneFile Pacific/Pago_Pago
+}
+set TZData(:US/Samoa) $TZData(:Pacific/Pago_Pago)
diff --git a/library/tzdata/UTC b/library/tzdata/UTC
new file mode 100644
index 0000000..6d04d96
--- /dev/null
+++ b/library/tzdata/UTC
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Etc/UTC)]} {
+    LoadTimeZoneFile Etc/UTC
+}
+set TZData(:UTC) $TZData(:Etc/UTC)
diff --git a/library/tzdata/Universal b/library/tzdata/Universal
new file mode 100644
index 0000000..4a9ed5e
--- /dev/null
+++ b/library/tzdata/Universal
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Etc/UTC)]} {
+    LoadTimeZoneFile Etc/UTC
+}
+set TZData(:Universal) $TZData(:Etc/UTC)
diff --git a/library/tzdata/W-SU b/library/tzdata/W-SU
new file mode 100644
index 0000000..7e1f613
--- /dev/null
+++ b/library/tzdata/W-SU
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Europe/Moscow)]} {
+    LoadTimeZoneFile Europe/Moscow
+}
+set TZData(:W-SU) $TZData(:Europe/Moscow)
diff --git a/library/tzdata/WET b/library/tzdata/WET
new file mode 100644
index 0000000..60366a3
--- /dev/null
+++ b/library/tzdata/WET
@@ -0,0 +1,251 @@
+# created by tools/tclZIC.tcl - do not edit
+
+set TZData(:WET) {
+    {-9223372036854775808 0 0 WET}
+    {228877200 3600 1 WEST}
+    {243997200 0 0 WET}
+    {260326800 3600 1 WEST}
+    {276051600 0 0 WET}
+    {291776400 3600 1 WEST}
+    {307501200 0 0 WET}
+    {323830800 3600 1 WEST}
+    {338950800 0 0 WET}
+    {354675600 3600 1 WEST}
+    {370400400 0 0 WET}
+    {386125200 3600 1 WEST}
+    {401850000 0 0 WET}
+    {417574800 3600 1 WEST}
+    {433299600 0 0 WET}
+    {449024400 3600 1 WEST}
+    {465354000 0 0 WET}
+    {481078800 3600 1 WEST}
+    {496803600 0 0 WET}
+    {512528400 3600 1 WEST}
+    {528253200 0 0 WET}
+    {543978000 3600 1 WEST}
+    {559702800 0 0 WET}
+    {575427600 3600 1 WEST}
+    {591152400 0 0 WET}
+    {606877200 3600 1 WEST}
+    {622602000 0 0 WET}
+    {638326800 3600 1 WEST}
+    {654656400 0 0 WET}
+    {670381200 3600 1 WEST}
+    {686106000 0 0 WET}
+    {701830800 3600 1 WEST}
+    {717555600 0 0 WET}
+    {733280400 3600 1 WEST}
+    {749005200 0 0 WET}
+    {764730000 3600 1 WEST}
+    {780454800 0 0 WET}
+    {796179600 3600 1 WEST}
+    {811904400 0 0 WET}
+    {828234000 3600 1 WEST}
+    {846378000 0 0 WET}
+    {859683600 3600 1 WEST}
+    {877827600 0 0 WET}
+    {891133200 3600 1 WEST}
+    {909277200 0 0 WET}
+    {922582800 3600 1 WEST}
+    {941331600 0 0 WET}
+    {954032400 3600 1 WEST}
+    {972781200 0 0 WET}
+    {985482000 3600 1 WEST}
+    {1004230800 0 0 WET}
+    {1017536400 3600 1 WEST}
+    {1035680400 0 0 WET}
+    {1048986000 3600 1 WEST}
+    {1067130000 0 0 WET}
+    {1080435600 3600 1 WEST}
+    {1099184400 0 0 WET}
+    {1111885200 3600 1 WEST}
+    {1130634000 0 0 WET}
+    {1143334800 3600 1 WEST}
+    {1162083600 0 0 WET}
+    {1174784400 3600 1 WEST}
+    {1193533200 0 0 WET}
+    {1206838800 3600 1 WEST}
+    {1224982800 0 0 WET}
+    {1238288400 3600 1 WEST}
+    {1256432400 0 0 WET}
+    {1269738000 3600 1 WEST}
+    {1288486800 0 0 WET}
+    {1301187600 3600 1 WEST}
+    {1319936400 0 0 WET}
+    {1332637200 3600 1 WEST}
+    {1351386000 0 0 WET}
+    {1364691600 3600 1 WEST}
+    {1382835600 0 0 WET}
+    {1396141200 3600 1 WEST}
+    {1414285200 0 0 WET}
+    {1427590800 3600 1 WEST}
+    {1445734800 0 0 WET}
+    {1459040400 3600 1 WEST}
+    {1477789200 0 0 WET}
+    {1490490000 3600 1 WEST}
+    {1509238800 0 0 WET}
+    {1521939600 3600 1 WEST}
+    {1540688400 0 0 WET}
+    {1553994000 3600 1 WEST}
+    {1572138000 0 0 WET}
+    {1585443600 3600 1 WEST}
+    {1603587600 0 0 WET}
+    {1616893200 3600 1 WEST}
+    {1635642000 0 0 WET}
+    {1648342800 3600 1 WEST}
+    {1667091600 0 0 WET}
+    {1679792400 3600 1 WEST}
+    {1698541200 0 0 WET}
+    {1711846800 3600 1 WEST}
+    {1729990800 0 0 WET}
+    {1743296400 3600 1 WEST}
+    {1761440400 0 0 WET}
+    {1774746000 3600 1 WEST}
+    {1792890000 0 0 WET}
+    {1806195600 3600 1 WEST}
+    {1824944400 0 0 WET}
+    {1837645200 3600 1 WEST}
+    {1856394000 0 0 WET}
+    {1869094800 3600 1 WEST}
+    {1887843600 0 0 WET}
+    {1901149200 3600 1 WEST}
+    {1919293200 0 0 WET}
+    {1932598800 3600 1 WEST}
+    {1950742800 0 0 WET}
+    {1964048400 3600 1 WEST}
+    {1982797200 0 0 WET}
+    {1995498000 3600 1 WEST}
+    {2014246800 0 0 WET}
+    {2026947600 3600 1 WEST}
+    {2045696400 0 0 WET}
+    {2058397200 3600 1 WEST}
+    {2077146000 0 0 WET}
+    {2090451600 3600 1 WEST}
+    {2108595600 0 0 WET}
+    {2121901200 3600 1 WEST}
+    {2140045200 0 0 WET}
+    {2153350800 3600 1 WEST}
+    {2172099600 0 0 WET}
+    {2184800400 3600 1 WEST}
+    {2203549200 0 0 WET}
+    {2216250000 3600 1 WEST}
+    {2234998800 0 0 WET}
+    {2248304400 3600 1 WEST}
+    {2266448400 0 0 WET}
+    {2279754000 3600 1 WEST}
+    {2297898000 0 0 WET}
+    {2311203600 3600 1 WEST}
+    {2329347600 0 0 WET}
+    {2342653200 3600 1 WEST}
+    {2361402000 0 0 WET}
+    {2374102800 3600 1 WEST}
+    {2392851600 0 0 WET}
+    {2405552400 3600 1 WEST}
+    {2424301200 0 0 WET}
+    {2437606800 3600 1 WEST}
+    {2455750800 0 0 WET}
+    {2469056400 3600 1 WEST}
+    {2487200400 0 0 WET}
+    {2500506000 3600 1 WEST}
+    {2519254800 0 0 WET}
+    {2531955600 3600 1 WEST}
+    {2550704400 0 0 WET}
+    {2563405200 3600 1 WEST}
+    {2582154000 0 0 WET}
+    {2595459600 3600 1 WEST}
+    {2613603600 0 0 WET}
+    {2626909200 3600 1 WEST}
+    {2645053200 0 0 WET}
+    {2658358800 3600 1 WEST}
+    {2676502800 0 0 WET}
+    {2689808400 3600 1 WEST}
+    {2708557200 0 0 WET}
+    {2721258000 3600 1 WEST}
+    {2740006800 0 0 WET}
+    {2752707600 3600 1 WEST}
+    {2771456400 0 0 WET}
+    {2784762000 3600 1 WEST}
+    {2802906000 0 0 WET}
+    {2816211600 3600 1 WEST}
+    {2834355600 0 0 WET}
+    {2847661200 3600 1 WEST}
+    {2866410000 0 0 WET}
+    {2879110800 3600 1 WEST}
+    {2897859600 0 0 WET}
+    {2910560400 3600 1 WEST}
+    {2929309200 0 0 WET}
+    {2942010000 3600 1 WEST}
+    {2960758800 0 0 WET}
+    {2974064400 3600 1 WEST}
+    {2992208400 0 0 WET}
+    {3005514000 3600 1 WEST}
+    {3023658000 0 0 WET}
+    {3036963600 3600 1 WEST}
+    {3055712400 0 0 WET}
+    {3068413200 3600 1 WEST}
+    {3087162000 0 0 WET}
+    {3099862800 3600 1 WEST}
+    {3118611600 0 0 WET}
+    {3131917200 3600 1 WEST}
+    {3150061200 0 0 WET}
+    {3163366800 3600 1 WEST}
+    {3181510800 0 0 WET}
+    {3194816400 3600 1 WEST}
+    {3212960400 0 0 WET}
+    {3226266000 3600 1 WEST}
+    {3245014800 0 0 WET}
+    {3257715600 3600 1 WEST}
+    {3276464400 0 0 WET}
+    {3289165200 3600 1 WEST}
+    {3307914000 0 0 WET}
+    {3321219600 3600 1 WEST}
+    {3339363600 0 0 WET}
+    {3352669200 3600 1 WEST}
+    {3370813200 0 0 WET}
+    {3384118800 3600 1 WEST}
+    {3402867600 0 0 WET}
+    {3415568400 3600 1 WEST}
+    {3434317200 0 0 WET}
+    {3447018000 3600 1 WEST}
+    {3465766800 0 0 WET}
+    {3479072400 3600 1 WEST}
+    {3497216400 0 0 WET}
+    {3510522000 3600 1 WEST}
+    {3528666000 0 0 WET}
+    {3541971600 3600 1 WEST}
+    {3560115600 0 0 WET}
+    {3573421200 3600 1 WEST}
+    {3592170000 0 0 WET}
+    {3604870800 3600 1 WEST}
+    {3623619600 0 0 WET}
+    {3636320400 3600 1 WEST}
+    {3655069200 0 0 WET}
+    {3668374800 3600 1 WEST}
+    {3686518800 0 0 WET}
+    {3699824400 3600 1 WEST}
+    {3717968400 0 0 WET}
+    {3731274000 3600 1 WEST}
+    {3750022800 0 0 WET}
+    {3762723600 3600 1 WEST}
+    {3781472400 0 0 WET}
+    {3794173200 3600 1 WEST}
+    {3812922000 0 0 WET}
+    {3825622800 3600 1 WEST}
+    {3844371600 0 0 WET}
+    {3857677200 3600 1 WEST}
+    {3875821200 0 0 WET}
+    {3889126800 3600 1 WEST}
+    {3907270800 0 0 WET}
+    {3920576400 3600 1 WEST}
+    {3939325200 0 0 WET}
+    {3952026000 3600 1 WEST}
+    {3970774800 0 0 WET}
+    {3983475600 3600 1 WEST}
+    {4002224400 0 0 WET}
+    {4015530000 3600 1 WEST}
+    {4033674000 0 0 WET}
+    {4046979600 3600 1 WEST}
+    {4065123600 0 0 WET}
+    {4078429200 3600 1 WEST}
+    {4096573200 0 0 WET}
+}
diff --git a/library/tzdata/Zulu b/library/tzdata/Zulu
new file mode 100644
index 0000000..e9748e4
--- /dev/null
+++ b/library/tzdata/Zulu
@@ -0,0 +1,5 @@
+# created by tools/tclZIC.tcl - do not edit
+if {![info exists TZData(Etc/UTC)]} {
+    LoadTimeZoneFile Etc/UTC
+}
+set TZData(:Zulu) $TZData(:Etc/UTC)
diff --git a/library/word.tcl b/library/word.tcl
new file mode 100644
index 0000000..3e4bc3a
--- /dev/null
+++ b/library/word.tcl
@@ -0,0 +1,152 @@
+# word.tcl --
+#
+# This file defines various procedures for computing word boundaries in
+# strings. This file is primarily needed so Tk text and entry widgets behave
+# properly for different platforms.
+#
+# Copyright (c) 1996 by Sun Microsystems, Inc.
+# Copyright (c) 1998 by Scritpics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+# The following variables are used to determine which characters are
+# interpreted as white space.
+
+if {$::tcl_platform(platform) eq "windows"} {
+    # Windows style - any but a unicode space char
+    if {![info exists ::tcl_wordchars]} {
+	set ::tcl_wordchars {\S}
+    }
+    if {![info exists ::tcl_nonwordchars]} {
+	set ::tcl_nonwordchars {\s}
+    }
+} else {
+    # Motif style - any unicode word char (number, letter, or underscore)
+    if {![info exists ::tcl_wordchars]} {
+	set ::tcl_wordchars {\w}
+    }
+    if {![info exists ::tcl_nonwordchars]} {
+	set ::tcl_nonwordchars {\W}
+    }
+}
+
+# Arrange for caches of the real matcher REs to be kept, which enables the REs
+# themselves to be cached for greater performance (and somewhat greater
+# clarity too).
+
+namespace eval ::tcl {
+    variable WordBreakRE
+    array set WordBreakRE {}
+
+    proc UpdateWordBreakREs args {
+	# Ignores the arguments
+	global tcl_wordchars tcl_nonwordchars
+	variable WordBreakRE
+
+	# To keep the RE strings short...
+	set letter $tcl_wordchars
+	set space $tcl_nonwordchars
+
+	set WordBreakRE(after)		"$letter$space|$space$letter"
+	set WordBreakRE(before)		"^.*($letter$space|$space$letter)"
+	set WordBreakRE(end)		"$space*$letter+$space"
+	set WordBreakRE(next)		"$letter*$space+$letter"
+	set WordBreakRE(previous)	"$space*($letter+)$space*\$"
+    }
+
+    # Initialize the cache
+    UpdateWordBreakREs
+    trace add variable ::tcl_wordchars write ::tcl::UpdateWordBreakREs
+    trace add variable ::tcl_nonwordchars write ::tcl::UpdateWordBreakREs
+}
+
+# tcl_wordBreakAfter --
+#
+# This procedure returns the index of the first word boundary after the
+# starting point in the given string, or -1 if there are no more boundaries in
+# the given string. The index returned refers to the first character of the
+# pair that comprises a boundary.
+#
+# Arguments:
+# str -		String to search.
+# start -	Index into string specifying starting point.
+
+proc tcl_wordBreakAfter {str start} {
+    variable ::tcl::WordBreakRE
+    set result {-1 -1}
+    regexp -indices -start $start -- $WordBreakRE(after) $str result
+    return [lindex $result 1]
+}
+
+# tcl_wordBreakBefore --
+#
+# This procedure returns the index of the first word boundary before the
+# starting point in the given string, or -1 if there are no more boundaries in
+# the given string. The index returned refers to the second character of the
+# pair that comprises a boundary.
+#
+# Arguments:
+# str -		String to search.
+# start -	Index into string specifying starting point.
+
+proc tcl_wordBreakBefore {str start} {
+    variable ::tcl::WordBreakRE
+    set result {-1 -1}
+    regexp -indices -- $WordBreakRE(before) [string range $str 0 $start] result
+    return [lindex $result 1]
+}
+
+# tcl_endOfWord --
+#
+# This procedure returns the index of the first end-of-word location after a
+# starting index in the given string. An end-of-word location is defined to be
+# the first whitespace character following the first non-whitespace character
+# after the starting point. Returns -1 if there are no more words after the
+# starting point.
+#
+# Arguments:
+# str -		String to search.
+# start -	Index into string specifying starting point.
+
+proc tcl_endOfWord {str start} {
+    variable ::tcl::WordBreakRE
+    set result {-1 -1}
+    regexp -indices -start $start -- $WordBreakRE(end) $str result
+    return [lindex $result 1]
+}
+
+# tcl_startOfNextWord --
+#
+# This procedure returns the index of the first start-of-word location after a
+# starting index in the given string. A start-of-word location is defined to
+# be a non-whitespace character following a whitespace character. Returns -1
+# if there are no more start-of-word locations after the starting point.
+#
+# Arguments:
+# str -		String to search.
+# start -	Index into string specifying starting point.
+
+proc tcl_startOfNextWord {str start} {
+    variable ::tcl::WordBreakRE
+    set result {-1 -1}
+    regexp -indices -start $start -- $WordBreakRE(next) $str result
+    return [lindex $result 1]
+}
+
+# tcl_startOfPreviousWord --
+#
+# This procedure returns the index of the first start-of-word location before
+# a starting index in the given string.
+#
+# Arguments:
+# str -		String to search.
+# start -	Index into string specifying starting point.
+
+proc tcl_startOfPreviousWord {str start} {
+    variable ::tcl::WordBreakRE
+    set word {-1 -1}
+    regexp -indices -- $WordBreakRE(previous) [string range $str 0 $start-1] \
+	    result word
+    return [lindex $word 0]
+}
diff --git a/libtommath/LICENSE b/libtommath/LICENSE
new file mode 100644
index 0000000..5baa792
--- /dev/null
+++ b/libtommath/LICENSE
@@ -0,0 +1,4 @@
+LibTomMath is hereby released into the Public Domain.  
+
+-- Tom St Denis
+
diff --git a/libtommath/bn.ilg b/libtommath/bn.ilg
new file mode 100644
index 0000000..3c859f0
--- /dev/null
+++ b/libtommath/bn.ilg
@@ -0,0 +1,6 @@
+This is makeindex, version 2.14 [02-Oct-2002] (kpathsea + Thai support).
+Scanning input file bn.idx....done (79 entries accepted, 0 rejected).
+Sorting entries....done (511 comparisons).
+Generating output file bn.ind....done (82 lines written, 0 warnings).
+Output written in bn.ind.
+Transcript written in bn.ilg.
diff --git a/libtommath/bn.ind b/libtommath/bn.ind
new file mode 100644
index 0000000..e5f7d4a
--- /dev/null
+++ b/libtommath/bn.ind
@@ -0,0 +1,82 @@
+\begin{theindex}
+
+  \item mp\_add, \hyperpage{29}
+  \item mp\_add\_d, \hyperpage{52}
+  \item mp\_and, \hyperpage{29}
+  \item mp\_clear, \hyperpage{11}
+  \item mp\_clear\_multi, \hyperpage{12}
+  \item mp\_cmp, \hyperpage{24}
+  \item mp\_cmp\_d, \hyperpage{25}
+  \item mp\_cmp\_mag, \hyperpage{23}
+  \item mp\_div, \hyperpage{30}
+  \item mp\_div\_2, \hyperpage{26}
+  \item mp\_div\_2d, \hyperpage{28}
+  \item mp\_div\_d, \hyperpage{52}
+  \item mp\_dr\_reduce, \hyperpage{40}
+  \item mp\_dr\_setup, \hyperpage{40}
+  \item MP\_EQ, \hyperpage{22}
+  \item mp\_error\_to\_string, \hyperpage{10}
+  \item mp\_expt\_d, \hyperpage{43}
+  \item mp\_exptmod, \hyperpage{43}
+  \item mp\_exteuclid, \hyperpage{51}
+  \item mp\_gcd, \hyperpage{51}
+  \item mp\_get\_int, \hyperpage{20}
+  \item mp\_grow, \hyperpage{16}
+  \item MP\_GT, \hyperpage{22}
+  \item mp\_init, \hyperpage{11}
+  \item mp\_init\_copy, \hyperpage{13}
+  \item mp\_init\_multi, \hyperpage{12}
+  \item mp\_init\_set, \hyperpage{21}
+  \item mp\_init\_set\_int, \hyperpage{21}
+  \item mp\_init\_size, \hyperpage{14}
+  \item mp\_int, \hyperpage{10}
+  \item mp\_invmod, \hyperpage{52}
+  \item mp\_jacobi, \hyperpage{52}
+  \item mp\_lcm, \hyperpage{51}
+  \item mp\_lshd, \hyperpage{28}
+  \item MP\_LT, \hyperpage{22}
+  \item MP\_MEM, \hyperpage{9}
+  \item mp\_mod, \hyperpage{35}
+  \item mp\_mod\_d, \hyperpage{52}
+  \item mp\_montgomery\_calc\_normalization, \hyperpage{38}
+  \item mp\_montgomery\_reduce, \hyperpage{37}
+  \item mp\_montgomery\_setup, \hyperpage{37}
+  \item mp\_mul, \hyperpage{31}
+  \item mp\_mul\_2, \hyperpage{26}
+  \item mp\_mul\_2d, \hyperpage{28}
+  \item mp\_mul\_d, \hyperpage{52}
+  \item mp\_n\_root, \hyperpage{44}
+  \item mp\_neg, \hyperpage{29}
+  \item MP\_NO, \hyperpage{9}
+  \item MP\_OKAY, \hyperpage{9}
+  \item mp\_or, \hyperpage{29}
+  \item mp\_prime\_fermat, \hyperpage{45}
+  \item mp\_prime\_is\_divisible, \hyperpage{45}
+  \item mp\_prime\_is\_prime, \hyperpage{46}
+  \item mp\_prime\_miller\_rabin, \hyperpage{45}
+  \item mp\_prime\_next\_prime, \hyperpage{46}
+  \item mp\_prime\_rabin\_miller\_trials, \hyperpage{46}
+  \item mp\_prime\_random, \hyperpage{47}
+  \item mp\_prime\_random\_ex, \hyperpage{47}
+  \item mp\_radix\_size, \hyperpage{49}
+  \item mp\_read\_radix, \hyperpage{49}
+  \item mp\_read\_unsigned\_bin, \hyperpage{50}
+  \item mp\_reduce, \hyperpage{36}
+  \item mp\_reduce\_2k, \hyperpage{41}
+  \item mp\_reduce\_2k\_setup, \hyperpage{41}
+  \item mp\_reduce\_setup, \hyperpage{36}
+  \item mp\_rshd, \hyperpage{28}
+  \item mp\_set, \hyperpage{19}
+  \item mp\_set\_int, \hyperpage{20}
+  \item mp\_shrink, \hyperpage{15}
+  \item mp\_sqr, \hyperpage{33}
+  \item mp\_sub, \hyperpage{29}
+  \item mp\_sub\_d, \hyperpage{52}
+  \item mp\_to\_unsigned\_bin, \hyperpage{50}
+  \item mp\_toradix, \hyperpage{49}
+  \item mp\_unsigned\_bin\_size, \hyperpage{50}
+  \item MP\_VAL, \hyperpage{9}
+  \item mp\_xor, \hyperpage{29}
+  \item MP\_YES, \hyperpage{9}
+
+\end{theindex}
diff --git a/libtommath/bn.pdf b/libtommath/bn.pdf
new file mode 100644
index 0000000..392b649
Binary files /dev/null and b/libtommath/bn.pdf differ
diff --git a/libtommath/bn.tex b/libtommath/bn.tex
new file mode 100644
index 0000000..e8eb994
--- /dev/null
+++ b/libtommath/bn.tex
@@ -0,0 +1,1835 @@
+\documentclass[b5paper]{book}
+\usepackage{hyperref}
+\usepackage{makeidx}
+\usepackage{amssymb}
+\usepackage{color}
+\usepackage{alltt}
+\usepackage{graphicx}
+\usepackage{layout}
+\def\union{\cup}
+\def\intersect{\cap}
+\def\getsrandom{\stackrel{\rm R}{\gets}}
+\def\cross{\times}
+\def\cat{\hspace{0.5em} \| \hspace{0.5em}}
+\def\catn{$\|$}
+\def\divides{\hspace{0.3em} | \hspace{0.3em}}
+\def\nequiv{\not\equiv}
+\def\approx{\raisebox{0.2ex}{\mbox{\small $\sim$}}}
+\def\lcm{{\rm lcm}}
+\def\gcd{{\rm gcd}}
+\def\log{{\rm log}}
+\def\ord{{\rm ord}}
+\def\abs{{\mathit abs}}
+\def\rep{{\mathit rep}}
+\def\mod{{\mathit\ mod\ }}
+\renewcommand{\pmod}[1]{\ ({\rm mod\ }{#1})}
+\newcommand{\floor}[1]{\left\lfloor{#1}\right\rfloor}
+\newcommand{\ceil}[1]{\left\lceil{#1}\right\rceil}
+\def\Or{{\rm\ or\ }}
+\def\And{{\rm\ and\ }}
+\def\iff{\hspace{1em}\Longleftrightarrow\hspace{1em}}
+\def\implies{\Rightarrow}
+\def\undefined{{\rm ``undefined"}}
+\def\Proof{\vspace{1ex}\noindent {\bf Proof:}\hspace{1em}}
+\let\oldphi\phi
+\def\phi{\varphi}
+\def\Pr{{\rm Pr}}
+\newcommand{\str}[1]{{\mathbf{#1}}}
+\def\F{{\mathbb F}}
+\def\N{{\mathbb N}}
+\def\Z{{\mathbb Z}}
+\def\R{{\mathbb R}}
+\def\C{{\mathbb C}}
+\def\Q{{\mathbb Q}}
+\definecolor{DGray}{gray}{0.5}
+\newcommand{\emailaddr}[1]{\mbox{$<${#1}$>$}}
+\def\twiddle{\raisebox{0.3ex}{\mbox{\tiny $\sim$}}}
+\def\gap{\vspace{0.5ex}}
+\makeindex
+\begin{document}
+\frontmatter
+\pagestyle{empty}
+\title{LibTomMath User Manual \\ v0.39}
+\author{Tom St Denis \\ tomstdenis@iahu.ca}
+\maketitle
+This text, the library and the accompanying textbook are all hereby placed in the public domain.  This book has been 
+formatted for B5 [176x250] paper using the \LaTeX{} {\em book} macro package.
+
+\vspace{10cm}
+
+\begin{flushright}Open Source.  Open Academia.  Open Minds.
+
+\mbox{ }
+
+Tom St Denis,
+
+Ontario, Canada
+\end{flushright}
+
+\tableofcontents
+\listoffigures
+\mainmatter
+\pagestyle{headings}
+\chapter{Introduction}
+\section{What is LibTomMath?}
+LibTomMath is a library of source code which provides a series of efficient and carefully written functions for manipulating
+large integer numbers.  It was written in portable ISO C source code so that it will build on any platform with a conforming
+C compiler.  
+
+In a nutshell the library was written from scratch with verbose comments to help instruct computer science students how
+to implement ``bignum'' math.  However, the resulting code has proven to be very useful.  It has been used by numerous 
+universities, commercial and open source software developers.  It has been used on a variety of platforms ranging from
+Linux and Windows based x86 to ARM based Gameboys and PPC based MacOS machines.  
+
+\section{License}
+As of the v0.25 the library source code has been placed in the public domain with every new release.  As of the v0.28
+release the textbook ``Implementing Multiple Precision Arithmetic'' has been placed in the public domain with every new
+release as well.  This textbook is meant to compliment the project by providing a more solid walkthrough of the development
+algorithms used in the library.
+
+Since both\footnote{Note that the MPI files under mtest/ are copyrighted by Michael Fromberger.  They are not required to use LibTomMath.} are in the 
+public domain everyone is entitled to do with them as they see fit.
+
+\section{Building LibTomMath}
+
+LibTomMath is meant to be very ``GCC friendly'' as it comes with a makefile well suited for GCC.  However, the library will
+also build in MSVC, Borland C out of the box.  For any other ISO C compiler a makefile will have to be made by the end
+developer.  
+
+\subsection{Static Libraries}
+To build as a static library for GCC issue the following
+\begin{alltt}
+make
+\end{alltt}
+
+command.  This will build the library and archive the object files in ``libtommath.a''.  Now you link against 
+that and include ``tommath.h'' within your programs.  Alternatively to build with MSVC issue the following
+\begin{alltt}
+nmake -f makefile.msvc
+\end{alltt}
+
+This will build the library and archive the object files in ``tommath.lib''.  This has been tested with MSVC 
+version 6.00 with service pack 5.  
+
+\subsection{Shared Libraries}
+To build as a shared library for GCC issue the following
+\begin{alltt}
+make -f makefile.shared
+\end{alltt}
+This requires the ``libtool'' package (common on most Linux/BSD systems).  It will build LibTomMath as both shared
+and static then install (by default) into /usr/lib as well as install the header files in /usr/include.  The shared 
+library (resource) will be called ``libtommath.la'' while the static library called ``libtommath.a''.  Generally 
+you use libtool to link your application against the shared object.  
+
+There is limited support for making a ``DLL'' in windows via the ``makefile.cygwin\_dll'' makefile.  It requires 
+Cygwin to work with since it requires the auto-export/import functionality.  The resulting DLL and import library 
+``libtommath.dll.a'' can be used to link LibTomMath dynamically to any Windows program using Cygwin.
+
+\subsection{Testing}
+To build the library and the test harness type
+
+\begin{alltt}
+make test
+\end{alltt}
+
+This will build the library, ``test'' and ``mtest/mtest''.  The ``test'' program will accept test vectors and verify the
+results.  ``mtest/mtest'' will generate test vectors using the MPI library by Michael Fromberger\footnote{A copy of MPI
+is included in the package}.  Simply pipe mtest into test using
+
+\begin{alltt}
+mtest/mtest | test
+\end{alltt}
+
+If you do not have a ``/dev/urandom'' style RNG source you will have to write your own PRNG and simply pipe that into 
+mtest.  For example, if your PRNG program is called ``myprng'' simply invoke
+
+\begin{alltt}
+myprng | mtest/mtest | test
+\end{alltt}
+
+This will output a row of numbers that are increasing.  Each column is a different test (such as addition, multiplication, etc)
+that is being performed.  The numbers represent how many times the test was invoked.  If an error is detected the program
+will exit with a dump of the relevent numbers it was working with.
+
+\section{Build Configuration}
+LibTomMath can configured at build time in three phases we shall call ``depends'', ``tweaks'' and ``trims''.  
+Each phase changes how the library is built and they are applied one after another respectively.  
+
+To make the system more powerful you can tweak the build process.  Classes are defined in the file
+``tommath\_superclass.h''.  By default, the symbol ``LTM\_ALL'' shall be defined which simply 
+instructs the system to build all of the functions.  This is how LibTomMath used to be packaged.  This will give you 
+access to every function LibTomMath offers.
+
+However, there are cases where such a build is not optional.  For instance, you want to perform RSA operations.  You 
+don't need the vast majority of the library to perform these operations.  Aside from LTM\_ALL there is 
+another pre--defined class ``SC\_RSA\_1'' which works in conjunction with the RSA from LibTomCrypt.  Additional 
+classes can be defined base on the need of the user.
+
+\subsection{Build Depends}
+In the file tommath\_class.h you will see a large list of C ``defines'' followed by a series of ``ifdefs''
+which further define symbols.  All of the symbols (technically they're macros $\ldots$) represent a given C source
+file.  For instance, BN\_MP\_ADD\_C represents the file ``bn\_mp\_add.c''.  When a define has been enabled the
+function in the respective file will be compiled and linked into the library.  Accordingly when the define
+is absent the file will not be compiled and not contribute any size to the library.
+
+You will also note that the header tommath\_class.h is actually recursively included (it includes itself twice).  
+This is to help resolve as many dependencies as possible.  In the last pass the symbol LTM\_LAST will be defined.  
+This is useful for ``trims''.
+
+\subsection{Build Tweaks}
+A tweak is an algorithm ``alternative''.  For example, to provide tradeoffs (usually between size and space).
+They can be enabled at any pass of the configuration phase.
+
+\begin{small}
+\begin{center}
+\begin{tabular}{|l|l|}
+\hline \textbf{Define} & \textbf{Purpose} \\
+\hline BN\_MP\_DIV\_SMALL & Enables a slower, smaller and equally \\
+                          & functional mp\_div() function \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+
+\subsection{Build Trims}
+A trim is a manner of removing functionality from a function that is not required.  For instance, to perform
+RSA cryptography you only require exponentiation with odd moduli so even moduli support can be safely removed.  
+Build trims are meant to be defined on the last pass of the configuration which means they are to be defined
+only if LTM\_LAST has been defined.
+
+\subsubsection{Moduli Related}
+\begin{small}
+\begin{center}
+\begin{tabular}{|l|l|}
+\hline \textbf{Restriction} & \textbf{Undefine} \\
+\hline Exponentiation with odd moduli only & BN\_S\_MP\_EXPTMOD\_C \\
+                                           & BN\_MP\_REDUCE\_C \\
+                                           & BN\_MP\_REDUCE\_SETUP\_C \\
+                                           & BN\_S\_MP\_MUL\_HIGH\_DIGS\_C \\
+                                           & BN\_FAST\_S\_MP\_MUL\_HIGH\_DIGS\_C \\
+\hline Exponentiation with random odd moduli & (The above plus the following) \\
+                                           & BN\_MP\_REDUCE\_2K\_C \\
+                                           & BN\_MP\_REDUCE\_2K\_SETUP\_C \\
+                                           & BN\_MP\_REDUCE\_IS\_2K\_C \\
+                                           & BN\_MP\_DR\_IS\_MODULUS\_C \\
+                                           & BN\_MP\_DR\_REDUCE\_C \\
+                                           & BN\_MP\_DR\_SETUP\_C \\
+\hline Modular inverse odd moduli only     & BN\_MP\_INVMOD\_SLOW\_C \\
+\hline Modular inverse (both, smaller/slower) & BN\_FAST\_MP\_INVMOD\_C \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+
+\subsubsection{Operand Size Related}
+\begin{small}
+\begin{center}
+\begin{tabular}{|l|l|}
+\hline \textbf{Restriction} & \textbf{Undefine} \\
+\hline Moduli $\le 2560$ bits              & BN\_MP\_MONTGOMERY\_REDUCE\_C \\
+                                           & BN\_S\_MP\_MUL\_DIGS\_C \\
+                                           & BN\_S\_MP\_MUL\_HIGH\_DIGS\_C \\
+                                           & BN\_S\_MP\_SQR\_C \\
+\hline Polynomial Schmolynomial            & BN\_MP\_KARATSUBA\_MUL\_C \\
+                                           & BN\_MP\_KARATSUBA\_SQR\_C \\
+                                           & BN\_MP\_TOOM\_MUL\_C \\ 
+                                           & BN\_MP\_TOOM\_SQR\_C \\
+
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+
+
+\section{Purpose of LibTomMath}
+Unlike  GNU MP (GMP) Library, LIP, OpenSSL or various other commercial kits (Miracl), LibTomMath was not written with 
+bleeding edge performance in mind.  First and foremost LibTomMath was written to be entirely open.  Not only is the 
+source code public domain (unlike various other GPL/etc licensed code), not only is the code freely downloadable but the
+source code is also accessible for computer science students attempting to learn ``BigNum'' or multiple precision
+arithmetic techniques. 
+
+LibTomMath was written to be an instructive collection of source code.  This is why there are many comments, only one
+function per source file and often I use a ``middle-road'' approach where I don't cut corners for an extra 2\% speed
+increase.
+
+Source code alone cannot really teach how the algorithms work which is why I also wrote a textbook that accompanies
+the library (beat that!).
+
+So you may be thinking ``should I use LibTomMath?'' and the answer is a definite maybe.  Let me tabulate what I think
+are the pros and cons of LibTomMath by comparing it to the math routines from GnuPG\footnote{GnuPG v1.2.3 versus LibTomMath v0.28}.
+
+\newpage\begin{figure}[here]
+\begin{small}
+\begin{center}
+\begin{tabular}{|l|c|c|l|}
+\hline \textbf{Criteria} & \textbf{Pro} & \textbf{Con} & \textbf{Notes} \\
+\hline Few lines of code per file & X & & GnuPG $ = 300.9$, LibTomMath  $ = 71.97$ \\
+\hline Commented function prototypes & X && GnuPG function names are cryptic. \\
+\hline Speed && X & LibTomMath is slower.  \\
+\hline Totally free & X & & GPL has unfavourable restrictions.\\
+\hline Large function base & X & & GnuPG is barebones. \\
+\hline Five modular reduction algorithms & X & & Faster modular exponentiation for a variety of moduli. \\
+\hline Portable & X & & GnuPG requires configuration to build. \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{LibTomMath Valuation}
+\end{figure}
+
+It may seem odd to compare LibTomMath to GnuPG since the math in GnuPG is only a small portion of the entire application. 
+However, LibTomMath was written with cryptography in mind.  It provides essentially all of the functions a cryptosystem
+would require when working with large integers.  
+
+So it may feel tempting to just rip the math code out of GnuPG (or GnuMP where it was taken from originally) in your
+own application but I think there are reasons not to.  While LibTomMath is slower than libraries such as GnuMP it is
+not normally significantly slower.  On x86 machines the difference is normally a factor of two when performing modular
+exponentiations.  It depends largely on the processor, compiler and the moduli being used.
+
+Essentially the only time you wouldn't use LibTomMath is when blazing speed is the primary concern.  However,
+on the other side of the coin LibTomMath offers you a totally free (public domain) well structured math library
+that is very flexible, complete and performs well in resource contrained environments.  Fast RSA for example can
+be performed with as little as 8KB of ram for data (again depending on build options).  
+
+\chapter{Getting Started with LibTomMath}
+\section{Building Programs}
+In order to use LibTomMath you must include ``tommath.h'' and link against the appropriate library file (typically 
+libtommath.a).  There is no library initialization required and the entire library is thread safe.
+
+\section{Return Codes}
+There are three possible return codes a function may return.
+
+\index{MP\_OKAY}\index{MP\_YES}\index{MP\_NO}\index{MP\_VAL}\index{MP\_MEM}
+\begin{figure}[here!]
+\begin{center}
+\begin{small}
+\begin{tabular}{|l|l|}
+\hline \textbf{Code} & \textbf{Meaning} \\
+\hline MP\_OKAY & The function succeeded. \\
+\hline MP\_VAL  & The function input was invalid. \\
+\hline MP\_MEM  & Heap memory exhausted. \\
+\hline &\\
+\hline MP\_YES  & Response is yes. \\
+\hline MP\_NO   & Response is no. \\
+\hline
+\end{tabular}
+\end{small}
+\end{center}
+\caption{Return Codes}
+\end{figure}
+
+The last two codes listed are not actually ``return'ed'' by a function.  They are placed in an integer (the caller must
+provide the address of an integer it can store to) which the caller can access.  To convert one of the three return codes
+to a string use the following function.
+
+\index{mp\_error\_to\_string}
+\begin{alltt}
+char *mp_error_to_string(int code);
+\end{alltt}
+
+This will return a pointer to a string which describes the given error code.  It will not work for the return codes 
+MP\_YES and MP\_NO.  
+
+\section{Data Types}
+The basic ``multiple precision integer'' type is known as the ``mp\_int'' within LibTomMath.  This data type is used to
+organize all of the data required to manipulate the integer it represents.  Within LibTomMath it has been prototyped
+as the following.
+
+\index{mp\_int}
+\begin{alltt}
+typedef struct  \{
+    int used, alloc, sign;
+    mp_digit *dp;
+\} mp_int;
+\end{alltt}
+
+Where ``mp\_digit'' is a data type that represents individual digits of the integer.  By default, an mp\_digit is the
+ISO C ``unsigned long'' data type and each digit is $28-$bits long.  The mp\_digit type can be configured to suit other
+platforms by defining the appropriate macros.  
+
+All LTM functions that use the mp\_int type will expect a pointer to mp\_int structure.  You must allocate memory to
+hold the structure itself by yourself (whether off stack or heap it doesn't matter).  The very first thing that must be
+done to use an mp\_int is that it must be initialized.
+
+\section{Function Organization}
+
+The arithmetic functions of the library are all organized to have the same style prototype.  That is source operands
+are passed on the left and the destination is on the right.  For instance,
+
+\begin{alltt}
+mp_add(&a, &b, &c);       /* c = a + b */
+mp_mul(&a, &a, &c);       /* c = a * a */
+mp_div(&a, &b, &c, &d);   /* c = [a/b], d = a mod b */
+\end{alltt}
+
+Another feature of the way the functions have been implemented is that source operands can be destination operands as well.
+For instance,
+
+\begin{alltt}
+mp_add(&a, &b, &b);       /* b = a + b */
+mp_div(&a, &b, &a, &c);   /* a = [a/b], c = a mod b */
+\end{alltt}
+
+This allows operands to be re-used which can make programming simpler.
+
+\section{Initialization}
+\subsection{Single Initialization}
+A single mp\_int can be initialized with the ``mp\_init'' function. 
+
+\index{mp\_init}
+\begin{alltt}
+int mp_init (mp_int * a);
+\end{alltt}
+
+This function expects a pointer to an mp\_int structure and will initialize the members of the structure so the mp\_int
+represents the default integer which is zero.  If the functions returns MP\_OKAY then the mp\_int is ready to be used
+by the other LibTomMath functions.
+
+\begin{small} \begin{alltt}
+int main(void)
+\{
+   mp_int number;
+   int result;
+
+   if ((result = mp_init(&number)) != MP_OKAY) \{
+      printf("Error initializing the number.  \%s", 
+             mp_error_to_string(result));
+      return EXIT_FAILURE;
+   \}
+ 
+   /* use the number */
+
+   return EXIT_SUCCESS;
+\}
+\end{alltt} \end{small}
+
+\subsection{Single Free}
+When you are finished with an mp\_int it is ideal to return the heap it used back to the system.  The following function 
+provides this functionality.
+
+\index{mp\_clear}
+\begin{alltt}
+void mp_clear (mp_int * a);
+\end{alltt}
+
+The function expects a pointer to a previously initialized mp\_int structure and frees the heap it uses.  It sets the 
+pointer\footnote{The ``dp'' member.} within the mp\_int to \textbf{NULL} which is used to prevent double free situations. 
+Is is legal to call mp\_clear() twice on the same mp\_int in a row.  
+
+\begin{small} \begin{alltt}
+int main(void)
+\{
+   mp_int number;
+   int result;
+
+   if ((result = mp_init(&number)) != MP_OKAY) \{
+      printf("Error initializing the number.  \%s", 
+             mp_error_to_string(result));
+      return EXIT_FAILURE;
+   \}
+ 
+   /* use the number */
+
+   /* We're done with it. */
+   mp_clear(&number);
+
+   return EXIT_SUCCESS;
+\}
+\end{alltt} \end{small}
+
+\subsection{Multiple Initializations}
+Certain algorithms require more than one large integer.  In these instances it is ideal to initialize all of the mp\_int
+variables in an ``all or nothing'' fashion.  That is, they are either all initialized successfully or they are all
+not initialized.
+
+The  mp\_init\_multi() function provides this functionality.
+
+\index{mp\_init\_multi} \index{mp\_clear\_multi}
+\begin{alltt}
+int mp_init_multi(mp_int *mp, ...);
+\end{alltt}
+
+It accepts a \textbf{NULL} terminated list of pointers to mp\_int structures.  It will attempt to initialize them all
+at once.  If the function returns MP\_OKAY then all of the mp\_int variables are ready to use, otherwise none of them
+are available for use.  A complementary mp\_clear\_multi() function allows multiple mp\_int variables to be free'd 
+from the heap at the same time.  
+
+\begin{small} \begin{alltt}
+int main(void)
+\{
+   mp_int num1, num2, num3;
+   int result;
+
+   if ((result = mp_init_multi(&num1, 
+                               &num2,
+                               &num3, NULL)) != MP\_OKAY) \{      
+      printf("Error initializing the numbers.  \%s", 
+             mp_error_to_string(result));
+      return EXIT_FAILURE;
+   \}
+ 
+   /* use the numbers */
+
+   /* We're done with them. */
+   mp_clear_multi(&num1, &num2, &num3, NULL);
+
+   return EXIT_SUCCESS;
+\}
+\end{alltt} \end{small}
+
+\subsection{Other Initializers}
+To initialized and make a copy of an mp\_int the mp\_init\_copy() function has been provided.  
+
+\index{mp\_init\_copy}
+\begin{alltt}
+int mp_init_copy (mp_int * a, mp_int * b);
+\end{alltt}
+
+This function will initialize $a$ and make it a copy of $b$ if all goes well.
+
+\begin{small} \begin{alltt}
+int main(void)
+\{
+   mp_int num1, num2;
+   int result;
+
+   /* initialize and do work on num1 ... */
+
+   /* We want a copy of num1 in num2 now */
+   if ((result = mp_init_copy(&num2, &num1)) != MP_OKAY) \{
+     printf("Error initializing the copy.  \%s", 
+             mp_error_to_string(result));
+      return EXIT_FAILURE;
+   \}
+ 
+   /* now num2 is ready and contains a copy of num1 */
+
+   /* We're done with them. */
+   mp_clear_multi(&num1, &num2, NULL);
+
+   return EXIT_SUCCESS;
+\}
+\end{alltt} \end{small}
+
+Another less common initializer is mp\_init\_size() which allows the user to initialize an mp\_int with a given
+default number of digits.  By default, all initializers allocate \textbf{MP\_PREC} digits.  This function lets
+you override this behaviour.
+
+\index{mp\_init\_size}
+\begin{alltt}
+int mp_init_size (mp_int * a, int size);
+\end{alltt}
+
+The $size$ parameter must be greater than zero.  If the function succeeds the mp\_int $a$ will be initialized
+to have $size$ digits (which are all initially zero).  
+
+\begin{small} \begin{alltt}
+int main(void)
+\{
+   mp_int number;
+   int result;
+
+   /* we need a 60-digit number */
+   if ((result = mp_init_size(&number, 60)) != MP_OKAY) \{
+      printf("Error initializing the number.  \%s", 
+             mp_error_to_string(result));
+      return EXIT_FAILURE;
+   \}
+ 
+   /* use the number */
+
+   return EXIT_SUCCESS;
+\}
+\end{alltt} \end{small}
+
+\section{Maintenance Functions}
+
+\subsection{Reducing Memory Usage}
+When an mp\_int is in a state where it won't be changed again\footnote{A Diffie-Hellman modulus for instance.} excess
+digits can be removed to return memory to the heap with the mp\_shrink() function.
+
+\index{mp\_shrink}
+\begin{alltt}
+int mp_shrink (mp_int * a);
+\end{alltt}
+
+This will remove excess digits of the mp\_int $a$.  If the operation fails the mp\_int should be intact without the
+excess digits being removed.  Note that you can use a shrunk mp\_int in further computations, however, such operations
+will require heap operations which can be slow.  It is not ideal to shrink mp\_int variables that you will further
+modify in the system (unless you are seriously low on memory).  
+
+\begin{small} \begin{alltt}
+int main(void)
+\{
+   mp_int number;
+   int result;
+
+   if ((result = mp_init(&number)) != MP_OKAY) \{
+      printf("Error initializing the number.  \%s", 
+             mp_error_to_string(result));
+      return EXIT_FAILURE;
+   \}
+ 
+   /* use the number [e.g. pre-computation]  */
+
+   /* We're done with it for now. */
+   if ((result = mp_shrink(&number)) != MP_OKAY) \{
+      printf("Error shrinking the number.  \%s", 
+             mp_error_to_string(result));
+      return EXIT_FAILURE;
+   \}
+
+   /* use it .... */
+
+
+   /* we're done with it. */ 
+   mp_clear(&number);
+
+   return EXIT_SUCCESS;
+\}
+\end{alltt} \end{small}
+
+\subsection{Adding additional digits}
+
+Within the mp\_int structure are two parameters which control the limitations of the array of digits that represent
+the integer the mp\_int is meant to equal.   The \textit{used} parameter dictates how many digits are significant, that is,
+contribute to the value of the mp\_int.  The \textit{alloc} parameter dictates how many digits are currently available in
+the array.  If you need to perform an operation that requires more digits you will have to mp\_grow() the mp\_int to
+your desired size.  
+
+\index{mp\_grow}
+\begin{alltt}
+int mp_grow (mp_int * a, int size);
+\end{alltt}
+
+This will grow the array of digits of $a$ to $size$.  If the \textit{alloc} parameter is already bigger than
+$size$ the function will not do anything.
+
+\begin{small} \begin{alltt}
+int main(void)
+\{
+   mp_int number;
+   int result;
+
+   if ((result = mp_init(&number)) != MP_OKAY) \{
+      printf("Error initializing the number.  \%s", 
+             mp_error_to_string(result));
+      return EXIT_FAILURE;
+   \}
+ 
+   /* use the number */
+
+   /* We need to add 20 digits to the number  */
+   if ((result = mp_grow(&number, number.alloc + 20)) != MP_OKAY) \{
+      printf("Error growing the number.  \%s", 
+             mp_error_to_string(result));
+      return EXIT_FAILURE;
+   \}
+
+
+   /* use the number */
+
+   /* we're done with it. */ 
+   mp_clear(&number);
+
+   return EXIT_SUCCESS;
+\}
+\end{alltt} \end{small}
+
+\chapter{Basic Operations}
+\section{Small Constants}
+Setting mp\_ints to small constants is a relatively common operation.  To accomodate these instances there are two
+small constant assignment functions.  The first function is used to set a single digit constant while the second sets
+an ISO C style ``unsigned long'' constant.  The reason for both functions is efficiency.  Setting a single digit is quick but the
+domain of a digit can change (it's always at least $0 \ldots 127$).  
+
+\subsection{Single Digit}
+
+Setting a single digit can be accomplished with the following function.
+
+\index{mp\_set}
+\begin{alltt}
+void mp_set (mp_int * a, mp_digit b);
+\end{alltt}
+
+This will zero the contents of $a$ and make it represent an integer equal to the value of $b$.  Note that this
+function has a return type of \textbf{void}.  It cannot cause an error so it is safe to assume the function
+succeeded.
+
+\begin{small} \begin{alltt}
+int main(void)
+\{
+   mp_int number;
+   int result;
+
+   if ((result = mp_init(&number)) != MP_OKAY) \{
+      printf("Error initializing the number.  \%s", 
+             mp_error_to_string(result));
+      return EXIT_FAILURE;
+   \}
+ 
+   /* set the number to 5 */
+   mp_set(&number, 5);
+
+   /* we're done with it. */ 
+   mp_clear(&number);
+
+   return EXIT_SUCCESS;
+\}
+\end{alltt} \end{small}
+
+\subsection{Long Constants}
+
+To set a constant that is the size of an ISO C ``unsigned long'' and larger than a single digit the following function 
+can be used.
+
+\index{mp\_set\_int}
+\begin{alltt}
+int mp_set_int (mp_int * a, unsigned long b);
+\end{alltt}
+
+This will assign the value of the 32-bit variable $b$ to the mp\_int $a$.  Unlike mp\_set() this function will always
+accept a 32-bit input regardless of the size of a single digit.  However, since the value may span several digits 
+this function can fail if it runs out of heap memory.
+
+To get the ``unsigned long'' copy of an mp\_int the following function can be used.
+
+\index{mp\_get\_int}
+\begin{alltt}
+unsigned long mp_get_int (mp_int * a);
+\end{alltt}
+
+This will return the 32 least significant bits of the mp\_int $a$.  
+
+\begin{small} \begin{alltt}
+int main(void)
+\{
+   mp_int number;
+   int result;
+
+   if ((result = mp_init(&number)) != MP_OKAY) \{
+      printf("Error initializing the number.  \%s", 
+             mp_error_to_string(result));
+      return EXIT_FAILURE;
+   \}
+ 
+   /* set the number to 654321 (note this is bigger than 127) */
+   if ((result = mp_set_int(&number, 654321)) != MP_OKAY) \{
+      printf("Error setting the value of the number.  \%s", 
+             mp_error_to_string(result));
+      return EXIT_FAILURE;
+   \}
+
+   printf("number == \%lu", mp_get_int(&number));
+
+   /* we're done with it. */ 
+   mp_clear(&number);
+
+   return EXIT_SUCCESS;
+\}
+\end{alltt} \end{small}
+
+This should output the following if the program succeeds.
+
+\begin{alltt}
+number == 654321
+\end{alltt}
+
+\subsection{Initialize and Setting Constants}
+To both initialize and set small constants the following two functions are available.
+\index{mp\_init\_set} \index{mp\_init\_set\_int}
+\begin{alltt}
+int mp_init_set (mp_int * a, mp_digit b);
+int mp_init_set_int (mp_int * a, unsigned long b);
+\end{alltt}
+
+Both functions work like the previous counterparts except they first mp\_init $a$ before setting the values.  
+
+\begin{alltt}
+int main(void)
+\{
+   mp_int number1, number2;
+   int    result;
+
+   /* initialize and set a single digit */
+   if ((result = mp_init_set(&number1, 100)) != MP_OKAY) \{
+      printf("Error setting number1: \%s", 
+             mp_error_to_string(result));
+      return EXIT_FAILURE;
+   \}             
+
+   /* initialize and set a long */
+   if ((result = mp_init_set_int(&number2, 1023)) != MP_OKAY) \{
+      printf("Error setting number2: \%s", 
+             mp_error_to_string(result));
+      return EXIT_FAILURE;
+   \}
+
+   /* display */
+   printf("Number1, Number2 == \%lu, \%lu",
+          mp_get_int(&number1), mp_get_int(&number2));
+
+   /* clear */
+   mp_clear_multi(&number1, &number2, NULL);
+
+   return EXIT_SUCCESS;
+\}
+\end{alltt}
+
+If this program succeeds it shall output.
+\begin{alltt}
+Number1, Number2 == 100, 1023
+\end{alltt}
+
+\section{Comparisons}
+
+Comparisons in LibTomMath are always performed in a ``left to right'' fashion.  There are three possible return codes
+for any comparison.
+
+\index{MP\_GT} \index{MP\_EQ} \index{MP\_LT}
+\begin{figure}[here]
+\begin{center}
+\begin{tabular}{|c|c|}
+\hline \textbf{Result Code} & \textbf{Meaning} \\
+\hline MP\_GT & $a > b$ \\
+\hline MP\_EQ & $a = b$ \\
+\hline MP\_LT & $a < b$ \\
+\hline
+\end{tabular}
+\end{center}
+\caption{Comparison Codes for $a, b$}
+\label{fig:CMP}
+\end{figure}
+
+In figure \ref{fig:CMP} two integers $a$ and $b$ are being compared.  In this case $a$ is said to be ``to the left'' of 
+$b$.  
+
+\subsection{Unsigned comparison}
+
+An unsigned comparison considers only the digits themselves and not the associated \textit{sign} flag of the 
+mp\_int structures.  This is analogous to an absolute comparison.  The function mp\_cmp\_mag() will compare two
+mp\_int variables based on their digits only. 
+
+\index{mp\_cmp\_mag}
+\begin{alltt}
+int mp_cmp_mag(mp_int * a, mp_int * b);
+\end{alltt}
+This will compare $a$ to $b$ placing $a$ to the left of $b$.  This function cannot fail and will return one of the
+three compare codes listed in figure \ref{fig:CMP}.
+
+\begin{small} \begin{alltt}
+int main(void)
+\{
+   mp_int number1, number2;
+   int result;
+
+   if ((result = mp_init_multi(&number1, &number2, NULL)) != MP_OKAY) \{
+      printf("Error initializing the numbers.  \%s", 
+             mp_error_to_string(result));
+      return EXIT_FAILURE;
+   \}
+ 
+   /* set the number1 to 5 */
+   mp_set(&number1, 5);
+  
+   /* set the number2 to -6 */
+   mp_set(&number2, 6);
+   if ((result = mp_neg(&number2, &number2)) != MP_OKAY) \{
+      printf("Error negating number2.  \%s", 
+             mp_error_to_string(result));
+      return EXIT_FAILURE;
+   \}
+
+   switch(mp_cmp_mag(&number1, &number2)) \{
+       case MP_GT:  printf("|number1| > |number2|"); break;
+       case MP_EQ:  printf("|number1| = |number2|"); break;
+       case MP_LT:  printf("|number1| < |number2|"); break;
+   \}
+
+   /* we're done with it. */ 
+   mp_clear_multi(&number1, &number2, NULL);
+
+   return EXIT_SUCCESS;
+\}
+\end{alltt} \end{small}
+
+If this program\footnote{This function uses the mp\_neg() function which is discussed in section \ref{sec:NEG}.} completes 
+successfully it should print the following.
+
+\begin{alltt}
+|number1| < |number2|
+\end{alltt}
+
+This is because $\vert -6 \vert = 6$ and obviously $5 < 6$.
+
+\subsection{Signed comparison}
+
+To compare two mp\_int variables based on their signed value the mp\_cmp() function is provided.
+
+\index{mp\_cmp}
+\begin{alltt}
+int mp_cmp(mp_int * a, mp_int * b);
+\end{alltt}
+
+This will compare $a$ to the left of $b$.  It will first compare the signs of the two mp\_int variables.  If they
+differ it will return immediately based on their signs.  If the signs are equal then it will compare the digits
+individually.  This function will return one of the compare conditions codes listed in figure \ref{fig:CMP}.
+
+\begin{small} \begin{alltt}
+int main(void)
+\{
+   mp_int number1, number2;
+   int result;
+
+   if ((result = mp_init_multi(&number1, &number2, NULL)) != MP_OKAY) \{
+      printf("Error initializing the numbers.  \%s", 
+             mp_error_to_string(result));
+      return EXIT_FAILURE;
+   \}
+ 
+   /* set the number1 to 5 */
+   mp_set(&number1, 5);
+  
+   /* set the number2 to -6 */
+   mp_set(&number2, 6);
+   if ((result = mp_neg(&number2, &number2)) != MP_OKAY) \{
+      printf("Error negating number2.  \%s", 
+             mp_error_to_string(result));
+      return EXIT_FAILURE;
+   \}
+
+   switch(mp_cmp(&number1, &number2)) \{
+       case MP_GT:  printf("number1 > number2"); break;
+       case MP_EQ:  printf("number1 = number2"); break;
+       case MP_LT:  printf("number1 < number2"); break;
+   \}
+
+   /* we're done with it. */ 
+   mp_clear_multi(&number1, &number2, NULL);
+
+   return EXIT_SUCCESS;
+\}
+\end{alltt} \end{small}
+
+If this program\footnote{This function uses the mp\_neg() function which is discussed in section \ref{sec:NEG}.} completes 
+successfully it should print the following.
+
+\begin{alltt}
+number1 > number2
+\end{alltt}
+
+\subsection{Single Digit}
+
+To compare a single digit against an mp\_int the following function has been provided.
+
+\index{mp\_cmp\_d}
+\begin{alltt}
+int mp_cmp_d(mp_int * a, mp_digit b);
+\end{alltt}
+
+This will compare $a$ to the left of $b$ using a signed comparison.  Note that it will always treat $b$ as 
+positive.  This function is rather handy when you have to compare against small values such as $1$ (which often
+comes up in cryptography).  The function cannot fail and will return one of the tree compare condition codes
+listed in figure \ref{fig:CMP}.
+
+
+\begin{small} \begin{alltt}
+int main(void)
+\{
+   mp_int number;
+   int result;
+
+   if ((result = mp_init(&number)) != MP_OKAY) \{
+      printf("Error initializing the number.  \%s", 
+             mp_error_to_string(result));
+      return EXIT_FAILURE;
+   \}
+ 
+   /* set the number to 5 */
+   mp_set(&number, 5);
+
+   switch(mp_cmp_d(&number, 7)) \{
+       case MP_GT:  printf("number > 7"); break;
+       case MP_EQ:  printf("number = 7"); break;
+       case MP_LT:  printf("number < 7"); break;
+   \}
+
+   /* we're done with it. */ 
+   mp_clear(&number);
+
+   return EXIT_SUCCESS;
+\}
+\end{alltt} \end{small}
+
+If this program functions properly it will print out the following.
+
+\begin{alltt}
+number < 7
+\end{alltt}
+
+\section{Logical Operations}
+
+Logical operations are operations that can be performed either with simple shifts or boolean operators such as
+AND, XOR and OR directly.  These operations are very quick.
+
+\subsection{Multiplication by two}
+
+Multiplications and divisions by any power of two can be performed with quick logical shifts either left or
+right depending on the operation.  
+
+When multiplying or dividing by two a special case routine can be used which are as follows.
+\index{mp\_mul\_2} \index{mp\_div\_2}
+\begin{alltt}
+int mp_mul_2(mp_int * a, mp_int * b);
+int mp_div_2(mp_int * a, mp_int * b);
+\end{alltt}
+
+The former will assign twice $a$ to $b$ while the latter will assign half $a$ to $b$.  These functions are fast
+since the shift counts and maskes are hardcoded into the routines.
+
+\begin{small} \begin{alltt}
+int main(void)
+\{
+   mp_int number;
+   int result;
+
+   if ((result = mp_init(&number)) != MP_OKAY) \{
+      printf("Error initializing the number.  \%s", 
+             mp_error_to_string(result));
+      return EXIT_FAILURE;
+   \}
+ 
+   /* set the number to 5 */
+   mp_set(&number, 5);
+
+   /* multiply by two */
+   if ((result = mp\_mul\_2(&number, &number)) != MP_OKAY) \{
+      printf("Error multiplying the number.  \%s", 
+             mp_error_to_string(result));
+      return EXIT_FAILURE;
+   \}
+   switch(mp_cmp_d(&number, 7)) \{
+       case MP_GT:  printf("2*number > 7"); break;
+       case MP_EQ:  printf("2*number = 7"); break;
+       case MP_LT:  printf("2*number < 7"); break;
+   \}
+
+   /* now divide by two */
+   if ((result = mp\_div\_2(&number, &number)) != MP_OKAY) \{
+      printf("Error dividing the number.  \%s", 
+             mp_error_to_string(result));
+      return EXIT_FAILURE;
+   \}
+   switch(mp_cmp_d(&number, 7)) \{
+       case MP_GT:  printf("2*number/2 > 7"); break;
+       case MP_EQ:  printf("2*number/2 = 7"); break;
+       case MP_LT:  printf("2*number/2 < 7"); break;
+   \}
+
+   /* we're done with it. */ 
+   mp_clear(&number);
+
+   return EXIT_SUCCESS;
+\}
+\end{alltt} \end{small}
+
+If this program is successful it will print out the following text.
+
+\begin{alltt}
+2*number > 7
+2*number/2 < 7
+\end{alltt}
+
+Since $10 > 7$ and $5 < 7$.  To multiply by a power of two the following function can be used.
+
+\index{mp\_mul\_2d}
+\begin{alltt}
+int mp_mul_2d(mp_int * a, int b, mp_int * c);
+\end{alltt}
+
+This will multiply $a$ by $2^b$ and store the result in ``c''.  If the value of $b$ is less than or equal to 
+zero the function will copy $a$ to ``c'' without performing any further actions.  
+
+To divide by a power of two use the following.
+
+\index{mp\_div\_2d}
+\begin{alltt}
+int mp_div_2d (mp_int * a, int b, mp_int * c, mp_int * d);
+\end{alltt}
+Which will divide $a$ by $2^b$, store the quotient in ``c'' and the remainder in ``d'.  If $b \le 0$ then the
+function simply copies $a$ over to ``c'' and zeroes $d$.  The variable $d$ may be passed as a \textbf{NULL}
+value to signal that the remainder is not desired.
+
+\subsection{Polynomial Basis Operations}
+
+Strictly speaking the organization of the integers within the mp\_int structures is what is known as a 
+``polynomial basis''.  This simply means a field element is stored by divisions of a radix.  For example, if
+$f(x) = \sum_{i=0}^{k} y_ix^k$ for any vector $\vec y$ then the array of digits in $\vec y$ are said to be 
+the polynomial basis representation of $z$ if $f(\beta) = z$ for a given radix $\beta$.  
+
+To multiply by the polynomial $g(x) = x$ all you have todo is shift the digits of the basis left one place.  The
+following function provides this operation.
+
+\index{mp\_lshd}
+\begin{alltt}
+int mp_lshd (mp_int * a, int b);
+\end{alltt}
+
+This will multiply $a$ in place by $x^b$ which is equivalent to shifting the digits left $b$ places and inserting zeroes
+in the least significant digits.  Similarly to divide by a power of $x$ the following function is provided.
+
+\index{mp\_rshd}
+\begin{alltt}
+void mp_rshd (mp_int * a, int b)
+\end{alltt}
+This will divide $a$ in place by $x^b$ and discard the remainder.  This function cannot fail as it performs the operations
+in place and no new digits are required to complete it.
+
+\subsection{AND, OR and XOR Operations}
+
+While AND, OR and XOR operations are not typical ``bignum functions'' they can be useful in several instances.  The
+three functions are prototyped as follows.
+
+\index{mp\_or} \index{mp\_and} \index{mp\_xor}
+\begin{alltt}
+int mp_or  (mp_int * a, mp_int * b, mp_int * c);
+int mp_and (mp_int * a, mp_int * b, mp_int * c);
+int mp_xor (mp_int * a, mp_int * b, mp_int * c);
+\end{alltt}
+
+Which compute $c = a \odot b$ where $\odot$ is one of OR, AND or XOR.  
+
+\section{Addition and Subtraction}
+
+To compute an addition or subtraction the following two functions can be used.
+
+\index{mp\_add} \index{mp\_sub}
+\begin{alltt}
+int mp_add (mp_int * a, mp_int * b, mp_int * c);
+int mp_sub (mp_int * a, mp_int * b, mp_int * c)
+\end{alltt}
+
+Which perform $c = a \odot b$ where $\odot$ is one of signed addition or subtraction.  The operations are fully sign
+aware.
+
+\section{Sign Manipulation}
+\subsection{Negation}
+\label{sec:NEG}
+Simple integer negation can be performed with the following.
+
+\index{mp\_neg}
+\begin{alltt}
+int mp_neg (mp_int * a, mp_int * b);
+\end{alltt}
+
+Which assigns $-a$ to $b$.  
+
+\subsection{Absolute}
+Simple integer absolutes can be performed with the following.
+
+\index{mp\_neg}
+\begin{alltt}
+int mp_abs (mp_int * a, mp_int * b);
+\end{alltt}
+
+Which assigns $\vert a \vert$ to $b$.  
+
+\section{Integer Division and Remainder}
+To perform a complete and general integer division with remainder use the following function.
+
+\index{mp\_div}
+\begin{alltt}
+int mp_div (mp_int * a, mp_int * b, mp_int * c, mp_int * d);
+\end{alltt}
+                                                        
+This divides $a$ by $b$ and stores the quotient in $c$ and $d$.  The signed quotient is computed such that 
+$bc + d = a$.  Note that either of $c$ or $d$ can be set to \textbf{NULL} if their value is not required.  If 
+$b$ is zero the function returns \textbf{MP\_VAL}.  
+
+
+\chapter{Multiplication and Squaring}
+\section{Multiplication}
+A full signed integer multiplication can be performed with the following.
+\index{mp\_mul}
+\begin{alltt}
+int mp_mul (mp_int * a, mp_int * b, mp_int * c);
+\end{alltt}
+Which assigns the full signed product $ab$ to $c$.  This function actually breaks into one of four cases which are 
+specific multiplication routines optimized for given parameters.  First there are the Toom-Cook multiplications which
+should only be used with very large inputs.  This is followed by the Karatsuba multiplications which are for moderate
+sized inputs.  Then followed by the Comba and baseline multipliers.
+
+Fortunately for the developer you don't really need to know this unless you really want to fine tune the system.  mp\_mul()
+will determine on its own\footnote{Some tweaking may be required.} what routine to use automatically when it is called.
+
+\begin{alltt}
+int main(void)
+\{
+   mp_int number1, number2;
+   int result;
+
+   /* Initialize the numbers */
+   if ((result = mp_init_multi(&number1, 
+                               &number2, NULL)) != MP_OKAY) \{
+      printf("Error initializing the numbers.  \%s", 
+             mp_error_to_string(result));
+      return EXIT_FAILURE;
+   \}
+
+   /* set the terms */
+   if ((result = mp_set_int(&number, 257)) != MP_OKAY) \{
+      printf("Error setting number1.  \%s", 
+             mp_error_to_string(result));
+      return EXIT_FAILURE;
+   \}
+ 
+   if ((result = mp_set_int(&number2, 1023)) != MP_OKAY) \{
+      printf("Error setting number2.  \%s", 
+             mp_error_to_string(result));
+      return EXIT_FAILURE;
+   \}
+
+   /* multiply them */
+   if ((result = mp_mul(&number1, &number2,
+                        &number1)) != MP_OKAY) \{
+      printf("Error multiplying terms.  \%s", 
+             mp_error_to_string(result));
+      return EXIT_FAILURE;
+   \}
+
+   /* display */
+   printf("number1 * number2 == \%lu", mp_get_int(&number1));
+
+   /* free terms and return */
+   mp_clear_multi(&number1, &number2, NULL);
+
+   return EXIT_SUCCESS;
+\}
+\end{alltt}   
+
+If this program succeeds it shall output the following.
+
+\begin{alltt}
+number1 * number2 == 262911
+\end{alltt}
+
+\section{Squaring}
+Since squaring can be performed faster than multiplication it is performed it's own function instead of just using
+mp\_mul().
+
+\index{mp\_sqr}
+\begin{alltt}
+int mp_sqr (mp_int * a, mp_int * b);
+\end{alltt}
+
+Will square $a$ and store it in $b$.  Like the case of multiplication there are four different squaring
+algorithms all which can be called from mp\_sqr().  It is ideal to use mp\_sqr over mp\_mul when squaring terms because
+of the speed difference.  
+
+\section{Tuning Polynomial Basis Routines}
+
+Both of the Toom-Cook and Karatsuba multiplication algorithms are faster than the traditional $O(n^2)$ approach that
+the Comba and baseline algorithms use.  At $O(n^{1.464973})$ and $O(n^{1.584962})$ running times respectively they require 
+considerably less work.  For example, a 10000-digit multiplication would take roughly 724,000 single precision
+multiplications with Toom-Cook or 100,000,000 single precision multiplications with the standard Comba (a factor
+of 138).
+
+So why not always use Karatsuba or Toom-Cook?   The simple answer is that they have so much overhead that they're not
+actually faster than Comba until you hit distinct  ``cutoff'' points.  For Karatsuba with the default configuration, 
+GCC 3.3.1 and an Athlon XP processor the cutoff point is roughly 110 digits (about 70 for the Intel P4).  That is, at 
+110 digits Karatsuba and Comba multiplications just about break even and for 110+ digits Karatsuba is faster.
+
+Toom-Cook has incredible overhead and is probably only useful for very large inputs.  So far no known cutoff points 
+exist and for the most part I just set the cutoff points very high to make sure they're not called.
+
+A demo program in the ``etc/'' directory of the project called ``tune.c'' can be used to find the cutoff points.  This
+can be built with GCC as follows
+
+\begin{alltt}
+make XXX
+\end{alltt}
+Where ``XXX'' is one of the following entries from the table \ref{fig:tuning}.
+
+\begin{figure}[here]
+\begin{center}
+\begin{small}
+\begin{tabular}{|l|l|}
+\hline \textbf{Value of XXX} & \textbf{Meaning} \\
+\hline tune & Builds portable tuning application \\
+\hline tune86 & Builds x86 (pentium and up) program for COFF \\
+\hline tune86c & Builds x86 program for Cygwin \\
+\hline tune86l & Builds x86 program for Linux (ELF format) \\
+\hline
+\end{tabular}
+\end{small}
+\end{center}
+\caption{Build Names for Tuning Programs}
+\label{fig:tuning}
+\end{figure}
+
+When the program is running it will output a series of measurements for different cutoff points.  It will first find
+good Karatsuba squaring and multiplication points.  Then it proceeds to find Toom-Cook points.  Note that the Toom-Cook
+tuning takes a very long time as the cutoff points are likely to be very high.
+
+\chapter{Modular Reduction}
+
+Modular reduction is process of taking the remainder of one quantity divided by another.  Expressed 
+as (\ref{eqn:mod}) the modular reduction is equivalent to the remainder of $b$ divided by $c$.  
+
+\begin{equation}
+a \equiv b \mbox{ (mod }c\mbox{)}
+\label{eqn:mod}
+\end{equation}
+
+Of particular interest to cryptography are reductions where $b$ is limited to the range $0 \le b < c^2$ since particularly 
+fast reduction algorithms can be written for the limited range.  
+
+Note that one of the four optimized reduction algorithms are automatically chosen in the modular exponentiation
+algorithm mp\_exptmod when an appropriate modulus is detected.  
+
+\section{Straight Division}
+In order to effect an arbitrary modular reduction the following algorithm is provided.
+
+\index{mp\_mod}
+\begin{alltt}
+int mp_mod(mp_int *a, mp_int *b, mp_int *c);
+\end{alltt}
+
+This reduces $a$ modulo $b$ and stores the result in $c$.  The sign of $c$ shall agree with the sign 
+of $b$.  This algorithm accepts an input $a$ of any range and is not limited by $0 \le a < b^2$.
+
+\section{Barrett Reduction}
+
+Barrett reduction is a generic optimized reduction algorithm that requires pre--computation to achieve
+a decent speedup over straight division.  First a $\mu$ value must be precomputed with the following function.
+
+\index{mp\_reduce\_setup}
+\begin{alltt}
+int mp_reduce_setup(mp_int *a, mp_int *b);
+\end{alltt}
+
+Given a modulus in $b$ this produces the required $\mu$ value in $a$.  For any given modulus this only has to
+be computed once.  Modular reduction can now be performed with the following.
+
+\index{mp\_reduce}
+\begin{alltt}
+int mp_reduce(mp_int *a, mp_int *b, mp_int *c);
+\end{alltt}
+
+This will reduce $a$ in place modulo $b$ with the precomputed $\mu$ value in $c$.  $a$ must be in the range
+$0 \le a < b^2$.
+
+\begin{alltt}
+int main(void)
+\{
+   mp_int   a, b, c, mu;
+   int      result;
+
+   /* initialize a,b to desired values, mp_init mu, 
+    * c and set c to 1...we want to compute a^3 mod b 
+    */
+
+   /* get mu value */
+   if ((result = mp_reduce_setup(&mu, b)) != MP_OKAY) \{
+      printf("Error getting mu.  \%s", 
+             mp_error_to_string(result));
+      return EXIT_FAILURE;
+   \}
+
+   /* square a to get c = a^2 */
+   if ((result = mp_sqr(&a, &c)) != MP_OKAY) \{
+      printf("Error squaring.  \%s", 
+             mp_error_to_string(result));
+      return EXIT_FAILURE;
+   \}
+
+   /* now reduce `c' modulo b */
+   if ((result = mp_reduce(&c, &b, &mu)) != MP_OKAY) \{
+      printf("Error reducing.  \%s", 
+             mp_error_to_string(result));
+      return EXIT_FAILURE;
+   \}
+   
+   /* multiply a to get c = a^3 */
+   if ((result = mp_mul(&a, &c, &c)) != MP_OKAY) \{
+      printf("Error reducing.  \%s", 
+             mp_error_to_string(result));
+      return EXIT_FAILURE;
+   \}
+
+   /* now reduce `c' modulo b  */
+   if ((result = mp_reduce(&c, &b, &mu)) != MP_OKAY) \{
+      printf("Error reducing.  \%s", 
+             mp_error_to_string(result));
+      return EXIT_FAILURE;
+   \}
+  
+   /* c now equals a^3 mod b */
+
+   return EXIT_SUCCESS;
+\}
+\end{alltt} 
+
+This program will calculate $a^3 \mbox{ mod }b$ if all the functions succeed.  
+
+\section{Montgomery Reduction}
+
+Montgomery is a specialized reduction algorithm for any odd moduli.  Like Barrett reduction a pre--computation
+step is required.  This is accomplished with the following.
+
+\index{mp\_montgomery\_setup}
+\begin{alltt}
+int mp_montgomery_setup(mp_int *a, mp_digit *mp);
+\end{alltt}
+
+For the given odd moduli $a$ the precomputation value is placed in $mp$.  The reduction is computed with the 
+following.
+
+\index{mp\_montgomery\_reduce}
+\begin{alltt}
+int mp_montgomery_reduce(mp_int *a, mp_int *m, mp_digit mp);
+\end{alltt}
+This reduces $a$ in place modulo $m$ with the pre--computed value $mp$.   $a$ must be in the range
+$0 \le a < b^2$.
+
+Montgomery reduction is faster than Barrett reduction for moduli smaller than the ``comba'' limit.  With the default
+setup for instance, the limit is $127$ digits ($3556$--bits).   Note that this function is not limited to
+$127$ digits just that it falls back to a baseline algorithm after that point.  
+
+An important observation is that this reduction does not return $a \mbox{ mod }m$ but $aR^{-1} \mbox{ mod }m$ 
+where $R = \beta^n$, $n$ is the n number of digits in $m$ and $\beta$ is radix used (default is $2^{28}$).  
+
+To quickly calculate $R$ the following function was provided.
+
+\index{mp\_montgomery\_calc\_normalization}
+\begin{alltt}
+int mp_montgomery_calc_normalization(mp_int *a, mp_int *b);
+\end{alltt}
+Which calculates $a = R$ for the odd moduli $b$ without using multiplication or division.  
+
+The normal modus operandi for Montgomery reductions is to normalize the integers before entering the system.  For
+example, to calculate $a^3 \mbox { mod }b$ using Montgomery reduction the value of $a$ can be normalized by
+multiplying it by $R$.  Consider the following code snippet.
+
+\begin{alltt}
+int main(void)
+\{
+   mp_int   a, b, c, R;
+   mp_digit mp;
+   int      result;
+
+   /* initialize a,b to desired values, 
+    * mp_init R, c and set c to 1.... 
+    */
+
+   /* get normalization */
+   if ((result = mp_montgomery_calc_normalization(&R, b)) != MP_OKAY) \{
+      printf("Error getting norm.  \%s", 
+             mp_error_to_string(result));
+      return EXIT_FAILURE;
+   \}
+
+   /* get mp value */
+   if ((result = mp_montgomery_setup(&c, &mp)) != MP_OKAY) \{
+      printf("Error setting up montgomery.  \%s", 
+             mp_error_to_string(result));
+      return EXIT_FAILURE;
+   \}
+
+   /* normalize `a' so now a is equal to aR */
+   if ((result = mp_mulmod(&a, &R, &b, &a)) != MP_OKAY) \{
+      printf("Error computing aR.  \%s", 
+             mp_error_to_string(result));
+      return EXIT_FAILURE;
+   \}
+
+   /* square a to get c = a^2R^2 */
+   if ((result = mp_sqr(&a, &c)) != MP_OKAY) \{
+      printf("Error squaring.  \%s", 
+             mp_error_to_string(result));
+      return EXIT_FAILURE;
+   \}
+
+   /* now reduce `c' back down to c = a^2R^2 * R^-1 == a^2R */
+   if ((result = mp_montgomery_reduce(&c, &b, mp)) != MP_OKAY) \{
+      printf("Error reducing.  \%s", 
+             mp_error_to_string(result));
+      return EXIT_FAILURE;
+   \}
+   
+   /* multiply a to get c = a^3R^2 */
+   if ((result = mp_mul(&a, &c, &c)) != MP_OKAY) \{
+      printf("Error reducing.  \%s", 
+             mp_error_to_string(result));
+      return EXIT_FAILURE;
+   \}
+
+   /* now reduce `c' back down to c = a^3R^2 * R^-1 == a^3R */
+   if ((result = mp_montgomery_reduce(&c, &b, mp)) != MP_OKAY) \{
+      printf("Error reducing.  \%s", 
+             mp_error_to_string(result));
+      return EXIT_FAILURE;
+   \}
+   
+   /* now reduce (again) `c' back down to c = a^3R * R^-1 == a^3 */
+   if ((result = mp_montgomery_reduce(&c, &b, mp)) != MP_OKAY) \{
+      printf("Error reducing.  \%s", 
+             mp_error_to_string(result));
+      return EXIT_FAILURE;
+   \}
+
+   /* c now equals a^3 mod b */
+
+   return EXIT_SUCCESS;
+\}
+\end{alltt} 
+
+This particular example does not look too efficient but it demonstrates the point of the algorithm.  By 
+normalizing the inputs the reduced results are always of the form $aR$ for some variable $a$.  This allows
+a single final reduction to correct for the normalization and the fast reduction used within the algorithm.
+
+For more details consider examining the file \textit{bn\_mp\_exptmod\_fast.c}.
+
+\section{Restricted Dimminished Radix}
+
+``Dimminished Radix'' reduction refers to reduction with respect to moduli that are ameniable to simple
+digit shifting and small multiplications.  In this case the ``restricted'' variant refers to moduli of the
+form $\beta^k - p$ for some $k \ge 0$ and $0 < p < \beta$ where $\beta$ is the radix (default to $2^{28}$).  
+
+As in the case of Montgomery reduction there is a pre--computation phase required for a given modulus.
+
+\index{mp\_dr\_setup}
+\begin{alltt}
+void mp_dr_setup(mp_int *a, mp_digit *d);
+\end{alltt}
+
+This computes the value required for the modulus $a$ and stores it in $d$.  This function cannot fail
+and does not return any error codes.  After the pre--computation a reduction can be performed with the
+following.
+
+\index{mp\_dr\_reduce}
+\begin{alltt}
+int mp_dr_reduce(mp_int *a, mp_int *b, mp_digit mp);
+\end{alltt}
+
+This reduces $a$ in place modulo $b$ with the pre--computed value $mp$.  $b$ must be of a restricted
+dimminished radix form and $a$ must be in the range $0 \le a < b^2$.  Dimminished radix reductions are 
+much faster than both Barrett and Montgomery reductions as they have a much lower asymtotic running time.  
+
+Since the moduli are restricted this algorithm is not particularly useful for something like Rabin, RSA or
+BBS cryptographic purposes.  This reduction algorithm is useful for Diffie-Hellman and ECC where fixed
+primes are acceptable.  
+
+Note that unlike Montgomery reduction there is no normalization process.  The result of this function is
+equal to the correct residue.
+
+\section{Unrestricted Dimminshed Radix}
+
+Unrestricted reductions work much like the restricted counterparts except in this case the moduli is of the 
+form $2^k - p$ for $0 < p < \beta$.  In this sense the unrestricted reductions are more flexible as they 
+can be applied to a wider range of numbers.  
+
+\index{mp\_reduce\_2k\_setup}
+\begin{alltt}
+int mp_reduce_2k_setup(mp_int *a, mp_digit *d);
+\end{alltt}
+
+This will compute the required $d$ value for the given moduli $a$.  
+
+\index{mp\_reduce\_2k}
+\begin{alltt}
+int mp_reduce_2k(mp_int *a, mp_int *n, mp_digit d);
+\end{alltt}
+
+This will reduce $a$ in place modulo $n$ with the pre--computed value $d$.  From my experience this routine is 
+slower than mp\_dr\_reduce but faster for most moduli sizes than the Montgomery reduction.  
+
+\chapter{Exponentiation}
+\section{Single Digit Exponentiation}
+\index{mp\_expt\_d}
+\begin{alltt}
+int mp_expt_d (mp_int * a, mp_digit b, mp_int * c)
+\end{alltt}
+This computes $c = a^b$ using a simple binary left-to-right algorithm.  It is faster than repeated multiplications by 
+$a$ for all values of $b$ greater than three.  
+
+\section{Modular Exponentiation}
+\index{mp\_exptmod}
+\begin{alltt}
+int mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y)
+\end{alltt}
+This computes $Y \equiv G^X \mbox{ (mod }P\mbox{)}$ using a variable width sliding window algorithm.  This function
+will automatically detect the fastest modular reduction technique to use during the operation.  For negative values of 
+$X$ the operation is performed as $Y \equiv (G^{-1} \mbox{ mod }P)^{\vert X \vert} \mbox{ (mod }P\mbox{)}$ provided that 
+$gcd(G, P) = 1$.
+
+This function is actually a shell around the two internal exponentiation functions.  This routine will automatically
+detect when Barrett, Montgomery, Restricted and Unrestricted Dimminished Radix based exponentiation can be used.  Generally
+moduli of the a ``restricted dimminished radix'' form lead to the fastest modular exponentiations.  Followed by Montgomery
+and the other two algorithms.
+
+\section{Root Finding}
+\index{mp\_n\_root}
+\begin{alltt}
+int mp_n_root (mp_int * a, mp_digit b, mp_int * c)
+\end{alltt}
+This computes $c = a^{1/b}$ such that $c^b \le a$ and $(c+1)^b > a$.  The implementation of this function is not 
+ideal for values of $b$ greater than three.  It will work but become very slow.  So unless you are working with very small
+numbers (less than 1000 bits) I'd avoid $b > 3$ situations.  Will return a positive root only for even roots and return
+a root with the sign of the input for odd roots.  For example, performing $4^{1/2}$ will return $2$ whereas $(-8)^{1/3}$ 
+will return $-2$.  
+
+This algorithm uses the ``Newton Approximation'' method and will converge on the correct root fairly quickly.  Since
+the algorithm requires raising $a$ to the power of $b$ it is not ideal to attempt to find roots for large
+values of $b$.  If particularly large roots are required then a factor method could be used instead.  For example,
+$a^{1/16}$ is equivalent to $\left (a^{1/4} \right)^{1/4}$ or simply 
+$\left ( \left ( \left ( a^{1/2} \right )^{1/2} \right )^{1/2} \right )^{1/2}$
+
+\chapter{Prime Numbers}
+\section{Trial Division}
+\index{mp\_prime\_is\_divisible}
+\begin{alltt}
+int mp_prime_is_divisible (mp_int * a, int *result)
+\end{alltt}
+This will attempt to evenly divide $a$ by a list of primes\footnote{Default is the first 256 primes.} and store the 
+outcome in ``result''.  That is if $result = 0$ then $a$ is not divisible by the primes, otherwise it is.  Note that 
+if the function does not return \textbf{MP\_OKAY} the value in ``result'' should be considered undefined\footnote{Currently
+the default is to set it to zero first.}.
+
+\section{Fermat Test}
+\index{mp\_prime\_fermat}
+\begin{alltt}
+int mp_prime_fermat (mp_int * a, mp_int * b, int *result)
+\end{alltt}
+Performs a Fermat primality test to the base $b$.  That is it computes $b^a \mbox{ mod }a$ and tests whether the value is
+equal to $b$ or not.  If the values are equal then $a$ is probably prime and $result$ is set to one.  Otherwise $result$
+is set to zero.
+
+\section{Miller-Rabin Test}
+\index{mp\_prime\_miller\_rabin}
+\begin{alltt}
+int mp_prime_miller_rabin (mp_int * a, mp_int * b, int *result)
+\end{alltt}
+Performs a Miller-Rabin test to the base $b$ of $a$.  This test is much stronger than the Fermat test and is very hard to
+fool (besides with Carmichael numbers).  If $a$ passes the test (therefore is probably prime) $result$ is set to one.  
+Otherwise $result$ is set to zero.  
+
+Note that is suggested that you use the Miller-Rabin test instead of the Fermat test since all of the failures of 
+Miller-Rabin are a subset of the failures of the Fermat test.
+
+\subsection{Required Number of Tests}
+Generally to ensure a number is very likely to be prime you have to perform the Miller-Rabin with at least a half-dozen
+or so unique bases.  However, it has been proven that the probability of failure goes down as the size of the input goes up.
+This is why a simple function has been provided to help out.
+
+\index{mp\_prime\_rabin\_miller\_trials}
+\begin{alltt}
+int mp_prime_rabin_miller_trials(int size)
+\end{alltt}
+This returns the number of trials required for a $2^{-96}$ (or lower) probability of failure for a given ``size'' expressed
+in bits.  This comes in handy specially since larger numbers are slower to test.  For example, a 512-bit number would
+require ten tests whereas a 1024-bit number would only require four tests. 
+
+You should always still perform a trial division before a Miller-Rabin test though.
+
+\section{Primality Testing}
+\index{mp\_prime\_is\_prime}
+\begin{alltt}
+int mp_prime_is_prime (mp_int * a, int t, int *result)
+\end{alltt}
+This will perform a trial division followed by $t$ rounds of Miller-Rabin tests on $a$ and store the result in $result$.  
+If $a$ passes all of the tests $result$ is set to one, otherwise it is set to zero.  Note that $t$ is bounded by 
+$1 \le t < PRIME\_SIZE$ where $PRIME\_SIZE$ is the number of primes in the prime number table (by default this is $256$).
+
+\section{Next Prime}
+\index{mp\_prime\_next\_prime}
+\begin{alltt}
+int mp_prime_next_prime(mp_int *a, int t, int bbs_style)
+\end{alltt}
+This finds the next prime after $a$ that passes mp\_prime\_is\_prime() with $t$ tests.  Set $bbs\_style$ to one if you 
+want only the next prime congruent to $3 \mbox{ mod } 4$, otherwise set it to zero to find any next prime.  
+
+\section{Random Primes}
+\index{mp\_prime\_random}
+\begin{alltt}
+int mp_prime_random(mp_int *a, int t, int size, int bbs, 
+                    ltm_prime_callback cb, void *dat)
+\end{alltt}
+This will find a prime greater than $256^{size}$ which can be ``bbs\_style'' or not depending on $bbs$ and must pass
+$t$ rounds of tests.  The ``ltm\_prime\_callback'' is a typedef for 
+
+\begin{alltt}
+typedef int ltm_prime_callback(unsigned char *dst, int len, void *dat);
+\end{alltt}
+
+Which is a function that must read $len$ bytes (and return the amount stored) into $dst$.  The $dat$ variable is simply
+copied from the original input.  It can be used to pass RNG context data to the callback.  The function 
+mp\_prime\_random() is more suitable for generating primes which must be secret (as in the case of RSA) since there 
+is no skew on the least significant bits.
+
+\textit{Note:}  As of v0.30 of the LibTomMath library this function has been deprecated.  It is still available
+but users are encouraged to use the new mp\_prime\_random\_ex() function instead.
+
+\subsection{Extended Generation}
+\index{mp\_prime\_random\_ex}
+\begin{alltt}
+int mp_prime_random_ex(mp_int *a,    int t, 
+                       int     size, int flags, 
+                       ltm_prime_callback cb, void *dat);
+\end{alltt}
+This will generate a prime in $a$ using $t$ tests of the primality testing algorithms.  The variable $size$
+specifies the bit length of the prime desired.  The variable $flags$ specifies one of several options available
+(see fig. \ref{fig:primeopts}) which can be OR'ed together.  The callback parameters are used as in 
+mp\_prime\_random().
+
+\begin{figure}[here]
+\begin{center}
+\begin{small}
+\begin{tabular}{|r|l|}
+\hline \textbf{Flag}         & \textbf{Meaning} \\
+\hline LTM\_PRIME\_BBS       & Make the prime congruent to $3$ modulo $4$ \\
+\hline LTM\_PRIME\_SAFE      & Make a prime $p$ such that $(p - 1)/2$ is also prime. \\
+                             & This option implies LTM\_PRIME\_BBS as well. \\
+\hline LTM\_PRIME\_2MSB\_OFF & Makes sure that the bit adjacent to the most significant bit \\
+                             & Is forced to zero.  \\
+\hline LTM\_PRIME\_2MSB\_ON  & Makes sure that the bit adjacent to the most significant bit \\
+                             & Is forced to one. \\
+\hline
+\end{tabular}
+\end{small}
+\end{center}
+\caption{Primality Generation Options}
+\label{fig:primeopts}
+\end{figure}
+
+\chapter{Input and Output}
+\section{ASCII Conversions}
+\subsection{To ASCII}
+\index{mp\_toradix}
+\begin{alltt}
+int mp_toradix (mp_int * a, char *str, int radix);
+\end{alltt}
+This still store $a$ in ``str'' as a base-``radix'' string of ASCII chars.  This function appends a NUL character
+to terminate the string.  Valid values of ``radix'' line in the range $[2, 64]$.  To determine the size (exact) required
+by the conversion before storing any data use the following function.
+
+\index{mp\_radix\_size}
+\begin{alltt}
+int mp_radix_size (mp_int * a, int radix, int *size)
+\end{alltt}
+This stores in ``size'' the number of characters (including space for the NUL terminator) required.  Upon error this 
+function returns an error code and ``size'' will be zero.  
+
+\subsection{From ASCII}
+\index{mp\_read\_radix}
+\begin{alltt}
+int mp_read_radix (mp_int * a, char *str, int radix);
+\end{alltt}
+This will read the base-``radix'' NUL terminated string from ``str'' into $a$.  It will stop reading when it reads a
+character it does not recognize (which happens to include th NUL char... imagine that...).  A single leading $-$ sign
+can be used to denote a negative number.
+
+\section{Binary Conversions}
+
+Converting an mp\_int to and from binary is another keen idea.
+
+\index{mp\_unsigned\_bin\_size}
+\begin{alltt}
+int mp_unsigned_bin_size(mp_int *a);
+\end{alltt}
+
+This will return the number of bytes (octets) required to store the unsigned copy of the integer $a$.
+
+\index{mp\_to\_unsigned\_bin}
+\begin{alltt}
+int mp_to_unsigned_bin(mp_int *a, unsigned char *b);
+\end{alltt}
+This will store $a$ into the buffer $b$ in big--endian format.  Fortunately this is exactly what DER (or is it ASN?)
+requires.  It does not store the sign of the integer.
+
+\index{mp\_read\_unsigned\_bin}
+\begin{alltt}
+int mp_read_unsigned_bin(mp_int *a, unsigned char *b, int c);
+\end{alltt}
+This will read in an unsigned big--endian array of bytes (octets) from $b$ of length $c$ into $a$.  The resulting
+integer $a$ will always be positive.
+
+For those who acknowledge the existence of negative numbers (heretic!) there are ``signed'' versions of the
+previous functions.
+
+\begin{alltt}
+int mp_signed_bin_size(mp_int *a);
+int mp_read_signed_bin(mp_int *a, unsigned char *b, int c);
+int mp_to_signed_bin(mp_int *a, unsigned char *b);
+\end{alltt}
+They operate essentially the same as the unsigned copies except they prefix the data with zero or non--zero
+byte depending on the sign.  If the sign is zpos (e.g. not negative) the prefix is zero, otherwise the prefix
+is non--zero.  
+
+\chapter{Algebraic Functions}
+\section{Extended Euclidean Algorithm}
+\index{mp\_exteuclid}
+\begin{alltt}
+int mp_exteuclid(mp_int *a, mp_int *b, 
+                 mp_int *U1, mp_int *U2, mp_int *U3);
+\end{alltt}
+
+This finds the triple U1/U2/U3 using the Extended Euclidean algorithm such that the following equation holds.
+
+\begin{equation}
+a \cdot U1 + b \cdot U2 = U3
+\end{equation}
+
+Any of the U1/U2/U3 paramters can be set to \textbf{NULL} if they are not desired.  
+
+\section{Greatest Common Divisor}
+\index{mp\_gcd}
+\begin{alltt}
+int mp_gcd (mp_int * a, mp_int * b, mp_int * c)
+\end{alltt}
+This will compute the greatest common divisor of $a$ and $b$ and store it in $c$.
+
+\section{Least Common Multiple}
+\index{mp\_lcm}
+\begin{alltt}
+int mp_lcm (mp_int * a, mp_int * b, mp_int * c)
+\end{alltt}
+This will compute the least common multiple of $a$ and $b$ and store it in $c$.
+
+\section{Jacobi Symbol}
+\index{mp\_jacobi}
+\begin{alltt}
+int mp_jacobi (mp_int * a, mp_int * p, int *c)
+\end{alltt}
+This will compute the Jacobi symbol for $a$ with respect to $p$.  If $p$ is prime this essentially computes the Legendre
+symbol.  The result is stored in $c$ and can take on one of three values $\lbrace -1, 0, 1 \rbrace$.  If $p$ is prime
+then the result will be $-1$ when $a$ is not a quadratic residue modulo $p$.  The result will be $0$ if $a$ divides $p$
+and the result will be $1$ if $a$ is a quadratic residue modulo $p$.  
+
+\section{Modular Inverse}
+\index{mp\_invmod}
+\begin{alltt}
+int mp_invmod (mp_int * a, mp_int * b, mp_int * c)
+\end{alltt}
+Computes the multiplicative inverse of $a$ modulo $b$ and stores the result in $c$ such that $ac \equiv 1 \mbox{ (mod }b\mbox{)}$.
+
+\section{Single Digit Functions}
+
+For those using small numbers (\textit{snicker snicker}) there are several ``helper'' functions
+
+\index{mp\_add\_d} \index{mp\_sub\_d} \index{mp\_mul\_d} \index{mp\_div\_d} \index{mp\_mod\_d}
+\begin{alltt}
+int mp_add_d(mp_int *a, mp_digit b, mp_int *c);
+int mp_sub_d(mp_int *a, mp_digit b, mp_int *c);
+int mp_mul_d(mp_int *a, mp_digit b, mp_int *c);
+int mp_div_d(mp_int *a, mp_digit b, mp_int *c, mp_digit *d);
+int mp_mod_d(mp_int *a, mp_digit b, mp_digit *c);
+\end{alltt}
+
+These work like the full mp\_int capable variants except the second parameter $b$ is a mp\_digit.  These
+functions fairly handy if you have to work with relatively small numbers since you will not have to allocate
+an entire mp\_int to store a number like $1$ or $2$.
+
+\input{bn.ind}
+
+\end{document}
diff --git a/libtommath/bn_error.c b/libtommath/bn_error.c
new file mode 100644
index 0000000..6393bb0
--- /dev/null
+++ b/libtommath/bn_error.c
@@ -0,0 +1,43 @@
+#include <tommath.h>
+#ifdef BN_ERROR_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+static const struct {
+     int code;
+     char *msg;
+} msgs[] = {
+     { MP_OKAY, "Successful" },
+     { MP_MEM,  "Out of heap" },
+     { MP_VAL,  "Value out of range" }
+};
+
+/* return a char * string for a given code */
+char *mp_error_to_string(int code)
+{
+   int x;
+
+   /* scan the lookup table for the given message */
+   for (x = 0; x < (int)(sizeof(msgs) / sizeof(msgs[0])); x++) {
+       if (msgs[x].code == code) {
+          return msgs[x].msg;
+       }
+   }
+
+   /* generic reply for invalid code */
+   return "Invalid error code";
+}
+
+#endif
diff --git a/libtommath/bn_fast_mp_invmod.c b/libtommath/bn_fast_mp_invmod.c
new file mode 100644
index 0000000..fafd9dc
--- /dev/null
+++ b/libtommath/bn_fast_mp_invmod.c
@@ -0,0 +1,144 @@
+#include <tommath.h>
+#ifdef BN_FAST_MP_INVMOD_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* computes the modular inverse via binary extended euclidean algorithm, 
+ * that is c = 1/a mod b 
+ *
+ * Based on slow invmod except this is optimized for the case where b is 
+ * odd as per HAC Note 14.64 on pp. 610
+ */
+int fast_mp_invmod (mp_int * a, mp_int * b, mp_int * c)
+{
+  mp_int  x, y, u, v, B, D;
+  int     res, neg;
+
+  /* 2. [modified] b must be odd   */
+  if (mp_iseven (b) == 1) {
+    return MP_VAL;
+  }
+
+  /* init all our temps */
+  if ((res = mp_init_multi(&x, &y, &u, &v, &B, &D, NULL)) != MP_OKAY) {
+     return res;
+  }
+
+  /* x == modulus, y == value to invert */
+  if ((res = mp_copy (b, &x)) != MP_OKAY) {
+    goto LBL_ERR;
+  }
+
+  /* we need y = |a| */
+  if ((res = mp_mod (a, b, &y)) != MP_OKAY) {
+    goto LBL_ERR;
+  }
+
+  /* 3. u=x, v=y, A=1, B=0, C=0,D=1 */
+  if ((res = mp_copy (&x, &u)) != MP_OKAY) {
+    goto LBL_ERR;
+  }
+  if ((res = mp_copy (&y, &v)) != MP_OKAY) {
+    goto LBL_ERR;
+  }
+  mp_set (&D, 1);
+
+top:
+  /* 4.  while u is even do */
+  while (mp_iseven (&u) == 1) {
+    /* 4.1 u = u/2 */
+    if ((res = mp_div_2 (&u, &u)) != MP_OKAY) {
+      goto LBL_ERR;
+    }
+    /* 4.2 if B is odd then */
+    if (mp_isodd (&B) == 1) {
+      if ((res = mp_sub (&B, &x, &B)) != MP_OKAY) {
+        goto LBL_ERR;
+      }
+    }
+    /* B = B/2 */
+    if ((res = mp_div_2 (&B, &B)) != MP_OKAY) {
+      goto LBL_ERR;
+    }
+  }
+
+  /* 5.  while v is even do */
+  while (mp_iseven (&v) == 1) {
+    /* 5.1 v = v/2 */
+    if ((res = mp_div_2 (&v, &v)) != MP_OKAY) {
+      goto LBL_ERR;
+    }
+    /* 5.2 if D is odd then */
+    if (mp_isodd (&D) == 1) {
+      /* D = (D-x)/2 */
+      if ((res = mp_sub (&D, &x, &D)) != MP_OKAY) {
+        goto LBL_ERR;
+      }
+    }
+    /* D = D/2 */
+    if ((res = mp_div_2 (&D, &D)) != MP_OKAY) {
+      goto LBL_ERR;
+    }
+  }
+
+  /* 6.  if u >= v then */
+  if (mp_cmp (&u, &v) != MP_LT) {
+    /* u = u - v, B = B - D */
+    if ((res = mp_sub (&u, &v, &u)) != MP_OKAY) {
+      goto LBL_ERR;
+    }
+
+    if ((res = mp_sub (&B, &D, &B)) != MP_OKAY) {
+      goto LBL_ERR;
+    }
+  } else {
+    /* v - v - u, D = D - B */
+    if ((res = mp_sub (&v, &u, &v)) != MP_OKAY) {
+      goto LBL_ERR;
+    }
+
+    if ((res = mp_sub (&D, &B, &D)) != MP_OKAY) {
+      goto LBL_ERR;
+    }
+  }
+
+  /* if not zero goto step 4 */
+  if (mp_iszero (&u) == 0) {
+    goto top;
+  }
+
+  /* now a = C, b = D, gcd == g*v */
+
+  /* if v != 1 then there is no inverse */
+  if (mp_cmp_d (&v, 1) != MP_EQ) {
+    res = MP_VAL;
+    goto LBL_ERR;
+  }
+
+  /* b is now the inverse */
+  neg = a->sign;
+  while (D.sign == MP_NEG) {
+    if ((res = mp_add (&D, b, &D)) != MP_OKAY) {
+      goto LBL_ERR;
+    }
+  }
+  mp_exch (&D, c);
+  c->sign = neg;
+  res = MP_OKAY;
+
+LBL_ERR:mp_clear_multi (&x, &y, &u, &v, &B, &D, NULL);
+  return res;
+}
+#endif
diff --git a/libtommath/bn_fast_mp_montgomery_reduce.c b/libtommath/bn_fast_mp_montgomery_reduce.c
new file mode 100644
index 0000000..e941dc2
--- /dev/null
+++ b/libtommath/bn_fast_mp_montgomery_reduce.c
@@ -0,0 +1,168 @@
+#include <tommath.h>
+#ifdef BN_FAST_MP_MONTGOMERY_REDUCE_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* computes xR**-1 == x (mod N) via Montgomery Reduction
+ *
+ * This is an optimized implementation of montgomery_reduce
+ * which uses the comba method to quickly calculate the columns of the
+ * reduction.
+ *
+ * Based on Algorithm 14.32 on pp.601 of HAC.
+*/
+int fast_mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho)
+{
+  int     ix, res, olduse;
+  mp_word W[MP_WARRAY];
+
+  /* get old used count */
+  olduse = x->used;
+
+  /* grow a as required */
+  if (x->alloc < n->used + 1) {
+    if ((res = mp_grow (x, n->used + 1)) != MP_OKAY) {
+      return res;
+    }
+  }
+
+  /* first we have to get the digits of the input into
+   * an array of double precision words W[...]
+   */
+  {
+    register mp_word *_W;
+    register mp_digit *tmpx;
+
+    /* alias for the W[] array */
+    _W   = W;
+
+    /* alias for the digits of  x*/
+    tmpx = x->dp;
+
+    /* copy the digits of a into W[0..a->used-1] */
+    for (ix = 0; ix < x->used; ix++) {
+      *_W++ = *tmpx++;
+    }
+
+    /* zero the high words of W[a->used..m->used*2] */
+    for (; ix < n->used * 2 + 1; ix++) {
+      *_W++ = 0;
+    }
+  }
+
+  /* now we proceed to zero successive digits
+   * from the least significant upwards
+   */
+  for (ix = 0; ix < n->used; ix++) {
+    /* mu = ai * m' mod b
+     *
+     * We avoid a double precision multiplication (which isn't required)
+     * by casting the value down to a mp_digit.  Note this requires
+     * that W[ix-1] have  the carry cleared (see after the inner loop)
+     */
+    register mp_digit mu;
+    mu = (mp_digit) (((W[ix] & MP_MASK) * rho) & MP_MASK);
+
+    /* a = a + mu * m * b**i
+     *
+     * This is computed in place and on the fly.  The multiplication
+     * by b**i is handled by offseting which columns the results
+     * are added to.
+     *
+     * Note the comba method normally doesn't handle carries in the
+     * inner loop In this case we fix the carry from the previous
+     * column since the Montgomery reduction requires digits of the
+     * result (so far) [see above] to work.  This is
+     * handled by fixing up one carry after the inner loop.  The
+     * carry fixups are done in order so after these loops the
+     * first m->used words of W[] have the carries fixed
+     */
+    {
+      register int iy;
+      register mp_digit *tmpn;
+      register mp_word *_W;
+
+      /* alias for the digits of the modulus */
+      tmpn = n->dp;
+
+      /* Alias for the columns set by an offset of ix */
+      _W = W + ix;
+
+      /* inner loop */
+      for (iy = 0; iy < n->used; iy++) {
+          *_W++ += ((mp_word)mu) * ((mp_word)*tmpn++);
+      }
+    }
+
+    /* now fix carry for next digit, W[ix+1] */
+    W[ix + 1] += W[ix] >> ((mp_word) DIGIT_BIT);
+  }
+
+  /* now we have to propagate the carries and
+   * shift the words downward [all those least
+   * significant digits we zeroed].
+   */
+  {
+    register mp_digit *tmpx;
+    register mp_word *_W, *_W1;
+
+    /* nox fix rest of carries */
+
+    /* alias for current word */
+    _W1 = W + ix;
+
+    /* alias for next word, where the carry goes */
+    _W = W + ++ix;
+
+    for (; ix <= n->used * 2 + 1; ix++) {
+      *_W++ += *_W1++ >> ((mp_word) DIGIT_BIT);
+    }
+
+    /* copy out, A = A/b**n
+     *
+     * The result is A/b**n but instead of converting from an
+     * array of mp_word to mp_digit than calling mp_rshd
+     * we just copy them in the right order
+     */
+
+    /* alias for destination word */
+    tmpx = x->dp;
+
+    /* alias for shifted double precision result */
+    _W = W + n->used;
+
+    for (ix = 0; ix < n->used + 1; ix++) {
+      *tmpx++ = (mp_digit)(*_W++ & ((mp_word) MP_MASK));
+    }
+
+    /* zero oldused digits, if the input a was larger than
+     * m->used+1 we'll have to clear the digits
+     */
+    for (; ix < olduse; ix++) {
+      *tmpx++ = 0;
+    }
+  }
+
+  /* set the max used and clamp */
+  x->used = n->used + 1;
+  mp_clamp (x);
+
+  /* if A >= m then A = A - m */
+  if (mp_cmp_mag (x, n) != MP_LT) {
+    return s_mp_sub (x, n, x);
+  }
+  return MP_OKAY;
+}
+#endif
diff --git a/libtommath/bn_fast_s_mp_mul_digs.c b/libtommath/bn_fast_s_mp_mul_digs.c
new file mode 100644
index 0000000..ab157b9
--- /dev/null
+++ b/libtommath/bn_fast_s_mp_mul_digs.c
@@ -0,0 +1,103 @@
+#include <tommath.h>
+#ifdef BN_FAST_S_MP_MUL_DIGS_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* Fast (comba) multiplier
+ *
+ * This is the fast column-array [comba] multiplier.  It is 
+ * designed to compute the columns of the product first 
+ * then handle the carries afterwards.  This has the effect 
+ * of making the nested loops that compute the columns very
+ * simple and schedulable on super-scalar processors.
+ *
+ * This has been modified to produce a variable number of 
+ * digits of output so if say only a half-product is required 
+ * you don't have to compute the upper half (a feature 
+ * required for fast Barrett reduction).
+ *
+ * Based on Algorithm 14.12 on pp.595 of HAC.
+ *
+ */
+int fast_s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs)
+{
+  int     olduse, res, pa, ix, iz;
+  mp_digit W[MP_WARRAY];
+  register mp_word  _W;
+
+  /* grow the destination as required */
+  if (c->alloc < digs) {
+    if ((res = mp_grow (c, digs)) != MP_OKAY) {
+      return res;
+    }
+  }
+
+  /* number of output digits to produce */
+  pa = MIN(digs, a->used + b->used);
+
+  /* clear the carry */
+  _W = 0;
+  for (ix = 0; ix < pa; ix++) { 
+      int      tx, ty;
+      int      iy;
+      mp_digit *tmpx, *tmpy;
+
+      /* get offsets into the two bignums */
+      ty = MIN(b->used-1, ix);
+      tx = ix - ty;
+
+      /* setup temp aliases */
+      tmpx = a->dp + tx;
+      tmpy = b->dp + ty;
+
+      /* this is the number of times the loop will iterrate, essentially 
+         while (tx++ < a->used && ty-- >= 0) { ... }
+       */
+      iy = MIN(a->used-tx, ty+1);
+
+      /* execute loop */
+      for (iz = 0; iz < iy; ++iz) {
+         _W += ((mp_word)*tmpx++)*((mp_word)*tmpy--);
+
+      }
+
+      /* store term */
+      W[ix] = ((mp_digit)_W) & MP_MASK;
+
+      /* make next carry */
+      _W = _W >> ((mp_word)DIGIT_BIT);
+ }
+
+  /* setup dest */
+  olduse  = c->used;
+  c->used = pa;
+
+  {
+    register mp_digit *tmpc;
+    tmpc = c->dp;
+    for (ix = 0; ix < pa+1; ix++) {
+      /* now extract the previous digit [below the carry] */
+      *tmpc++ = W[ix];
+    }
+
+    /* clear unused digits [that existed in the old copy of c] */
+    for (; ix < olduse; ix++) {
+      *tmpc++ = 0;
+    }
+  }
+  mp_clamp (c);
+  return MP_OKAY;
+}
+#endif
diff --git a/libtommath/bn_fast_s_mp_mul_high_digs.c b/libtommath/bn_fast_s_mp_mul_high_digs.c
new file mode 100644
index 0000000..ec9f58a
--- /dev/null
+++ b/libtommath/bn_fast_s_mp_mul_high_digs.c
@@ -0,0 +1,94 @@
+#include <tommath.h>
+#ifdef BN_FAST_S_MP_MUL_HIGH_DIGS_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* this is a modified version of fast_s_mul_digs that only produces
+ * output digits *above* digs.  See the comments for fast_s_mul_digs
+ * to see how it works.
+ *
+ * This is used in the Barrett reduction since for one of the multiplications
+ * only the higher digits were needed.  This essentially halves the work.
+ *
+ * Based on Algorithm 14.12 on pp.595 of HAC.
+ */
+int fast_s_mp_mul_high_digs (mp_int * a, mp_int * b, mp_int * c, int digs)
+{
+  int     olduse, res, pa, ix, iz;
+  mp_digit W[MP_WARRAY];
+  mp_word  _W;
+
+  /* grow the destination as required */
+  pa = a->used + b->used;
+  if (c->alloc < pa) {
+    if ((res = mp_grow (c, pa)) != MP_OKAY) {
+      return res;
+    }
+  }
+
+  /* number of output digits to produce */
+  pa = a->used + b->used;
+  _W = 0;
+  for (ix = digs; ix < pa; ix++) { 
+      int      tx, ty, iy;
+      mp_digit *tmpx, *tmpy;
+
+      /* get offsets into the two bignums */
+      ty = MIN(b->used-1, ix);
+      tx = ix - ty;
+
+      /* setup temp aliases */
+      tmpx = a->dp + tx;
+      tmpy = b->dp + ty;
+
+      /* this is the number of times the loop will iterrate, essentially its 
+         while (tx++ < a->used && ty-- >= 0) { ... }
+       */
+      iy = MIN(a->used-tx, ty+1);
+
+      /* execute loop */
+      for (iz = 0; iz < iy; iz++) {
+         _W += ((mp_word)*tmpx++)*((mp_word)*tmpy--);
+      }
+
+      /* store term */
+      W[ix] = ((mp_digit)_W) & MP_MASK;
+
+      /* make next carry */
+      _W = _W >> ((mp_word)DIGIT_BIT);
+  }
+  
+  /* setup dest */
+  olduse  = c->used;
+  c->used = pa;
+
+  {
+    register mp_digit *tmpc;
+
+    tmpc = c->dp + digs;
+    for (ix = digs; ix < pa; ix++) {
+      /* now extract the previous digit [below the carry] */
+      *tmpc++ = W[ix];
+    }
+
+    /* clear unused digits [that existed in the old copy of c] */
+    for (; ix < olduse; ix++) {
+      *tmpc++ = 0;
+    }
+  }
+  mp_clamp (c);
+  return MP_OKAY;
+}
+#endif
diff --git a/libtommath/bn_fast_s_mp_sqr.c b/libtommath/bn_fast_s_mp_sqr.c
new file mode 100644
index 0000000..1abf24b
--- /dev/null
+++ b/libtommath/bn_fast_s_mp_sqr.c
@@ -0,0 +1,110 @@
+#include <tommath.h>
+#ifdef BN_FAST_S_MP_SQR_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* the jist of squaring...
+ * you do like mult except the offset of the tmpx [one that 
+ * starts closer to zero] can't equal the offset of tmpy.  
+ * So basically you set up iy like before then you min it with
+ * (ty-tx) so that it never happens.  You double all those 
+ * you add in the inner loop
+
+After that loop you do the squares and add them in.
+*/
+
+int fast_s_mp_sqr (mp_int * a, mp_int * b)
+{
+  int       olduse, res, pa, ix, iz;
+  mp_digit   W[MP_WARRAY], *tmpx;
+  mp_word   W1;
+
+  /* grow the destination as required */
+  pa = a->used + a->used;
+  if (b->alloc < pa) {
+    if ((res = mp_grow (b, pa)) != MP_OKAY) {
+      return res;
+    }
+  }
+
+  /* number of output digits to produce */
+  W1 = 0;
+  for (ix = 0; ix < pa; ix++) { 
+      int      tx, ty, iy;
+      mp_word  _W;
+      mp_digit *tmpy;
+
+      /* clear counter */
+      _W = 0;
+
+      /* get offsets into the two bignums */
+      ty = MIN(a->used-1, ix);
+      tx = ix - ty;
+
+      /* setup temp aliases */
+      tmpx = a->dp + tx;
+      tmpy = a->dp + ty;
+
+      /* this is the number of times the loop will iterrate, essentially
+         while (tx++ < a->used && ty-- >= 0) { ... }
+       */
+      iy = MIN(a->used-tx, ty+1);
+
+      /* now for squaring tx can never equal ty 
+       * we halve the distance since they approach at a rate of 2x
+       * and we have to round because odd cases need to be executed
+       */
+      iy = MIN(iy, (ty-tx+1)>>1);
+
+      /* execute loop */
+      for (iz = 0; iz < iy; iz++) {
+         _W += ((mp_word)*tmpx++)*((mp_word)*tmpy--);
+      }
+
+      /* double the inner product and add carry */
+      _W = _W + _W + W1;
+
+      /* even columns have the square term in them */
+      if ((ix&1) == 0) {
+         _W += ((mp_word)a->dp[ix>>1])*((mp_word)a->dp[ix>>1]);
+      }
+
+      /* store it */
+      W[ix] = (mp_digit)(_W & MP_MASK);
+
+      /* make next carry */
+      W1 = _W >> ((mp_word)DIGIT_BIT);
+  }
+
+  /* setup dest */
+  olduse  = b->used;
+  b->used = a->used+a->used;
+
+  {
+    mp_digit *tmpb;
+    tmpb = b->dp;
+    for (ix = 0; ix < pa; ix++) {
+      *tmpb++ = W[ix] & MP_MASK;
+    }
+
+    /* clear unused digits [that existed in the old copy of c] */
+    for (; ix < olduse; ix++) {
+      *tmpb++ = 0;
+    }
+  }
+  mp_clamp (b);
+  return MP_OKAY;
+}
+#endif
diff --git a/libtommath/bn_mp_2expt.c b/libtommath/bn_mp_2expt.c
new file mode 100644
index 0000000..a32572d
--- /dev/null
+++ b/libtommath/bn_mp_2expt.c
@@ -0,0 +1,44 @@
+#include <tommath.h>
+#ifdef BN_MP_2EXPT_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* computes a = 2**b 
+ *
+ * Simple algorithm which zeroes the int, grows it then just sets one bit
+ * as required.
+ */
+int
+mp_2expt (mp_int * a, int b)
+{
+  int     res;
+
+  /* zero a as per default */
+  mp_zero (a);
+
+  /* grow a to accomodate the single bit */
+  if ((res = mp_grow (a, b / DIGIT_BIT + 1)) != MP_OKAY) {
+    return res;
+  }
+
+  /* set the used count of where the bit will go */
+  a->used = b / DIGIT_BIT + 1;
+
+  /* put the single bit in its place */
+  a->dp[b / DIGIT_BIT] = ((mp_digit)1) << (b % DIGIT_BIT);
+
+  return MP_OKAY;
+}
+#endif
diff --git a/libtommath/bn_mp_abs.c b/libtommath/bn_mp_abs.c
new file mode 100644
index 0000000..dc51884
--- /dev/null
+++ b/libtommath/bn_mp_abs.c
@@ -0,0 +1,39 @@
+#include <tommath.h>
+#ifdef BN_MP_ABS_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* b = |a| 
+ *
+ * Simple function copies the input and fixes the sign to positive
+ */
+int
+mp_abs (mp_int * a, mp_int * b)
+{
+  int     res;
+
+  /* copy a to b */
+  if (a != b) {
+     if ((res = mp_copy (a, b)) != MP_OKAY) {
+       return res;
+     }
+  }
+
+  /* force the sign of b to positive */
+  b->sign = MP_ZPOS;
+
+  return MP_OKAY;
+}
+#endif
diff --git a/libtommath/bn_mp_add.c b/libtommath/bn_mp_add.c
new file mode 100644
index 0000000..d9b8fa5
--- /dev/null
+++ b/libtommath/bn_mp_add.c
@@ -0,0 +1,49 @@
+#include <tommath.h>
+#ifdef BN_MP_ADD_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* high level addition (handles signs) */
+int mp_add (mp_int * a, mp_int * b, mp_int * c)
+{
+  int     sa, sb, res;
+
+  /* get sign of both inputs */
+  sa = a->sign;
+  sb = b->sign;
+
+  /* handle two cases, not four */
+  if (sa == sb) {
+    /* both positive or both negative */
+    /* add their magnitudes, copy the sign */
+    c->sign = sa;
+    res = s_mp_add (a, b, c);
+  } else {
+    /* one positive, the other negative */
+    /* subtract the one with the greater magnitude from */
+    /* the one of the lesser magnitude.  The result gets */
+    /* the sign of the one with the greater magnitude. */
+    if (mp_cmp_mag (a, b) == MP_LT) {
+      c->sign = sb;
+      res = s_mp_sub (b, a, c);
+    } else {
+      c->sign = sa;
+      res = s_mp_sub (a, b, c);
+    }
+  }
+  return res;
+}
+
+#endif
diff --git a/libtommath/bn_mp_add_d.c b/libtommath/bn_mp_add_d.c
new file mode 100644
index 0000000..5281ad4
--- /dev/null
+++ b/libtommath/bn_mp_add_d.c
@@ -0,0 +1,109 @@
+#include <tommath.h>
+#ifdef BN_MP_ADD_D_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* single digit addition */
+int
+mp_add_d (mp_int * a, mp_digit b, mp_int * c)
+{
+  int     res, ix, oldused;
+  mp_digit *tmpa, *tmpc, mu;
+
+  /* grow c as required */
+  if (c->alloc < a->used + 1) {
+     if ((res = mp_grow(c, a->used + 1)) != MP_OKAY) {
+        return res;
+     }
+  }
+
+  /* if a is negative and |a| >= b, call c = |a| - b */
+  if (a->sign == MP_NEG && (a->used > 1 || a->dp[0] >= b)) {
+     /* temporarily fix sign of a */
+     a->sign = MP_ZPOS;
+
+     /* c = |a| - b */
+     res = mp_sub_d(a, b, c);
+
+     /* fix signs  */
+     a->sign = MP_NEG;
+     c->sign = (c->used) ? MP_NEG : MP_ZPOS;
+
+     /* clamp */
+     mp_clamp(c);
+
+     return res;
+  }
+
+  /* old number of used digits in c */
+  oldused = c->used;
+
+  /* sign always positive */
+  c->sign = MP_ZPOS;
+
+  /* source alias */
+  tmpa    = a->dp;
+
+  /* destination alias */
+  tmpc    = c->dp;
+
+  /* if a is positive */
+  if (a->sign == MP_ZPOS) {
+     /* add digit, after this we're propagating
+      * the carry.
+      */
+     *tmpc   = *tmpa++ + b;
+     mu      = *tmpc >> DIGIT_BIT;
+     *tmpc++ &= MP_MASK;
+
+     /* now handle rest of the digits */
+     for (ix = 1; ix < a->used; ix++) {
+        *tmpc   = *tmpa++ + mu;
+        mu      = *tmpc >> DIGIT_BIT;
+        *tmpc++ &= MP_MASK;
+     }
+     /* set final carry */
+     ix++;
+     *tmpc++  = mu;
+
+     /* setup size */
+     c->used = a->used + 1;
+  } else {
+     /* a was negative and |a| < b */
+     c->used  = 1;
+
+     /* the result is a single digit */
+     if (a->used == 1) {
+        *tmpc++  =  b - a->dp[0];
+     } else {
+        *tmpc++  =  b;
+     }
+
+     /* setup count so the clearing of oldused
+      * can fall through correctly
+      */
+     ix       = 1;
+  }
+
+  /* now zero to oldused */
+  while (ix++ < oldused) {
+     *tmpc++ = 0;
+  }
+  mp_clamp(c);
+
+  return MP_OKAY;
+}
+
+#endif
diff --git a/libtommath/bn_mp_addmod.c b/libtommath/bn_mp_addmod.c
new file mode 100644
index 0000000..bff193f
--- /dev/null
+++ b/libtommath/bn_mp_addmod.c
@@ -0,0 +1,37 @@
+#include <tommath.h>
+#ifdef BN_MP_ADDMOD_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* d = a + b (mod c) */
+int
+mp_addmod (mp_int * a, mp_int * b, mp_int * c, mp_int * d)
+{
+  int     res;
+  mp_int  t;
+
+  if ((res = mp_init (&t)) != MP_OKAY) {
+    return res;
+  }
+
+  if ((res = mp_add (a, b, &t)) != MP_OKAY) {
+    mp_clear (&t);
+    return res;
+  }
+  res = mp_mod (&t, c, d);
+  mp_clear (&t);
+  return res;
+}
+#endif
diff --git a/libtommath/bn_mp_and.c b/libtommath/bn_mp_and.c
new file mode 100644
index 0000000..02bef18
--- /dev/null
+++ b/libtommath/bn_mp_and.c
@@ -0,0 +1,53 @@
+#include <tommath.h>
+#ifdef BN_MP_AND_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* AND two ints together */
+int
+mp_and (mp_int * a, mp_int * b, mp_int * c)
+{
+  int     res, ix, px;
+  mp_int  t, *x;
+
+  if (a->used > b->used) {
+    if ((res = mp_init_copy (&t, a)) != MP_OKAY) {
+      return res;
+    }
+    px = b->used;
+    x = b;
+  } else {
+    if ((res = mp_init_copy (&t, b)) != MP_OKAY) {
+      return res;
+    }
+    px = a->used;
+    x = a;
+  }
+
+  for (ix = 0; ix < px; ix++) {
+    t.dp[ix] &= x->dp[ix];
+  }
+
+  /* zero digits above the last from the smallest mp_int */
+  for (; ix < t.used; ix++) {
+    t.dp[ix] = 0;
+  }
+
+  mp_clamp (&t);
+  mp_exch (c, &t);
+  mp_clear (&t);
+  return MP_OKAY;
+}
+#endif
diff --git a/libtommath/bn_mp_clamp.c b/libtommath/bn_mp_clamp.c
new file mode 100644
index 0000000..74887bb
--- /dev/null
+++ b/libtommath/bn_mp_clamp.c
@@ -0,0 +1,40 @@
+#include <tommath.h>
+#ifdef BN_MP_CLAMP_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* trim unused digits 
+ *
+ * This is used to ensure that leading zero digits are
+ * trimed and the leading "used" digit will be non-zero
+ * Typically very fast.  Also fixes the sign if there
+ * are no more leading digits
+ */
+void
+mp_clamp (mp_int * a)
+{
+  /* decrease used while the most significant digit is
+   * zero.
+   */
+  while (a->used > 0 && a->dp[a->used - 1] == 0) {
+    --(a->used);
+  }
+
+  /* reset the sign flag if used == 0 */
+  if (a->used == 0) {
+    a->sign = MP_ZPOS;
+  }
+}
+#endif
diff --git a/libtommath/bn_mp_clear.c b/libtommath/bn_mp_clear.c
new file mode 100644
index 0000000..bd07e76
--- /dev/null
+++ b/libtommath/bn_mp_clear.c
@@ -0,0 +1,40 @@
+#include <tommath.h>
+#ifdef BN_MP_CLEAR_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* clear one (frees)  */
+void
+mp_clear (mp_int * a)
+{
+  int i;
+
+  /* only do anything if a hasn't been freed previously */
+  if (a->dp != NULL) {
+    /* first zero the digits */
+    for (i = 0; i < a->used; i++) {
+        a->dp[i] = 0;
+    }
+
+    /* free ram */
+    XFREE(a->dp);
+
+    /* reset members to make debugging easier */
+    a->dp    = NULL;
+    a->alloc = a->used = 0;
+    a->sign  = MP_ZPOS;
+  }
+}
+#endif
diff --git a/libtommath/bn_mp_clear_multi.c b/libtommath/bn_mp_clear_multi.c
new file mode 100644
index 0000000..c3ad7a8
--- /dev/null
+++ b/libtommath/bn_mp_clear_multi.c
@@ -0,0 +1,30 @@
+#include <tommath.h>
+#ifdef BN_MP_CLEAR_MULTI_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+#include <stdarg.h>
+
+void mp_clear_multi(mp_int *mp, ...) 
+{
+    mp_int* next_mp = mp;
+    va_list args;
+    va_start(args, mp);
+    while (next_mp != NULL) {
+        mp_clear(next_mp);
+        next_mp = va_arg(args, mp_int*);
+    }
+    va_end(args);
+}
+#endif
diff --git a/libtommath/bn_mp_cmp.c b/libtommath/bn_mp_cmp.c
new file mode 100644
index 0000000..943249d
--- /dev/null
+++ b/libtommath/bn_mp_cmp.c
@@ -0,0 +1,39 @@
+#include <tommath.h>
+#ifdef BN_MP_CMP_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* compare two ints (signed)*/
+int
+mp_cmp (const mp_int * a, const mp_int * b)
+{
+  /* compare based on sign */
+  if (a->sign != b->sign) {
+     if (a->sign == MP_NEG) {
+        return MP_LT;
+     } else {
+        return MP_GT;
+     }
+  }
+  
+  /* compare digits */
+  if (a->sign == MP_NEG) {
+     /* if negative compare opposite direction */
+     return mp_cmp_mag(b, a);
+  } else {
+     return mp_cmp_mag(a, b);
+  }
+}
+#endif
diff --git a/libtommath/bn_mp_cmp_d.c b/libtommath/bn_mp_cmp_d.c
new file mode 100644
index 0000000..ecec091
--- /dev/null
+++ b/libtommath/bn_mp_cmp_d.c
@@ -0,0 +1,40 @@
+#include <tommath.h>
+#ifdef BN_MP_CMP_D_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* compare a digit */
+int mp_cmp_d(const mp_int * a, mp_digit b)
+{
+  /* compare based on sign */
+  if (a->sign == MP_NEG) {
+    return MP_LT;
+  }
+
+  /* compare based on magnitude */
+  if (a->used > 1) {
+    return MP_GT;
+  }
+
+  /* compare the only digit of a to b */
+  if (a->dp[0] > b) {
+    return MP_GT;
+  } else if (a->dp[0] < b) {
+    return MP_LT;
+  } else {
+    return MP_EQ;
+  }
+}
+#endif
diff --git a/libtommath/bn_mp_cmp_mag.c b/libtommath/bn_mp_cmp_mag.c
new file mode 100644
index 0000000..b23a191
--- /dev/null
+++ b/libtommath/bn_mp_cmp_mag.c
@@ -0,0 +1,51 @@
+#include <tommath.h>
+#ifdef BN_MP_CMP_MAG_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* compare maginitude of two ints (unsigned) */
+int mp_cmp_mag (const mp_int * a, const mp_int * b)
+{
+  int     n;
+  mp_digit *tmpa, *tmpb;
+
+  /* compare based on # of non-zero digits */
+  if (a->used > b->used) {
+    return MP_GT;
+  }
+  
+  if (a->used < b->used) {
+    return MP_LT;
+  }
+
+  /* alias for a */
+  tmpa = a->dp + (a->used - 1);
+
+  /* alias for b */
+  tmpb = b->dp + (a->used - 1);
+
+  /* compare based on digits  */
+  for (n = 0; n < a->used; ++n, --tmpa, --tmpb) {
+    if (*tmpa > *tmpb) {
+      return MP_GT;
+    }
+
+    if (*tmpa < *tmpb) {
+      return MP_LT;
+    }
+  }
+  return MP_EQ;
+}
+#endif
diff --git a/libtommath/bn_mp_cnt_lsb.c b/libtommath/bn_mp_cnt_lsb.c
new file mode 100644
index 0000000..f205e8c
--- /dev/null
+++ b/libtommath/bn_mp_cnt_lsb.c
@@ -0,0 +1,49 @@
+#include <tommath.h>
+#ifdef BN_MP_CNT_LSB_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+static const int lnz[16] = { 
+   4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0
+};
+
+/* Counts the number of lsbs which are zero before the first zero bit */
+int mp_cnt_lsb(const mp_int *a)
+{
+   int x;
+   mp_digit q, qq;
+
+   /* easy out */
+   if (mp_iszero(a) == 1) {
+      return 0;
+   }
+
+   /* scan lower digits until non-zero */
+   for (x = 0; x < a->used && a->dp[x] == 0; x++);
+   q = a->dp[x];
+   x *= DIGIT_BIT;
+
+   /* now scan this digit until a 1 is found */
+   if ((q & 1) == 0) {
+      do {
+         qq  = q & 15;
+         x  += lnz[qq];
+         q >>= 4;
+      } while (qq == 0);
+   }
+   return x;
+}
+
+#endif
diff --git a/libtommath/bn_mp_copy.c b/libtommath/bn_mp_copy.c
new file mode 100644
index 0000000..ffbc0d4
--- /dev/null
+++ b/libtommath/bn_mp_copy.c
@@ -0,0 +1,64 @@
+#include <tommath.h>
+#ifdef BN_MP_COPY_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* copy, b = a */
+int
+mp_copy (const mp_int * a, mp_int * b)
+{
+  int     res, n;
+
+  /* if dst == src do nothing */
+  if (a == b) {
+    return MP_OKAY;
+  }
+
+  /* grow dest */
+  if (b->alloc < a->used) {
+     if ((res = mp_grow (b, a->used)) != MP_OKAY) {
+        return res;
+     }
+  }
+
+  /* zero b and copy the parameters over */
+  {
+    register mp_digit *tmpa, *tmpb;
+
+    /* pointer aliases */
+
+    /* source */
+    tmpa = a->dp;
+
+    /* destination */
+    tmpb = b->dp;
+
+    /* copy all the digits */
+    for (n = 0; n < a->used; n++) {
+      *tmpb++ = *tmpa++;
+    }
+
+    /* clear high digits */
+    for (; n < b->used; n++) {
+      *tmpb++ = 0;
+    }
+  }
+
+  /* copy used count and sign */
+  b->used = a->used;
+  b->sign = a->sign;
+  return MP_OKAY;
+}
+#endif
diff --git a/libtommath/bn_mp_count_bits.c b/libtommath/bn_mp_count_bits.c
new file mode 100644
index 0000000..00d364e
--- /dev/null
+++ b/libtommath/bn_mp_count_bits.c
@@ -0,0 +1,41 @@
+#include <tommath.h>
+#ifdef BN_MP_COUNT_BITS_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* returns the number of bits in an int */
+int
+mp_count_bits (const mp_int * a)
+{
+  int     r;
+  mp_digit q;
+
+  /* shortcut */
+  if (a->used == 0) {
+    return 0;
+  }
+
+  /* get number of digits and add that */
+  r = (a->used - 1) * DIGIT_BIT;
+  
+  /* take the last digit and count the bits in it */
+  q = a->dp[a->used - 1];
+  while (q > ((mp_digit) 0)) {
+    ++r;
+    q >>= ((mp_digit) 1);
+  }
+  return r;
+}
+#endif
diff --git a/libtommath/bn_mp_div.c b/libtommath/bn_mp_div.c
new file mode 100644
index 0000000..de4ca04
--- /dev/null
+++ b/libtommath/bn_mp_div.c
@@ -0,0 +1,288 @@
+#include <tommath.h>
+#ifdef BN_MP_DIV_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+#ifdef BN_MP_DIV_SMALL
+
+/* slower bit-bang division... also smaller */
+int mp_div(mp_int * a, mp_int * b, mp_int * c, mp_int * d)
+{
+   mp_int ta, tb, tq, q;
+   int    res, n, n2;
+
+  /* is divisor zero ? */
+  if (mp_iszero (b) == 1) {
+    return MP_VAL;
+  }
+
+  /* if a < b then q=0, r = a */
+  if (mp_cmp_mag (a, b) == MP_LT) {
+    if (d != NULL) {
+      res = mp_copy (a, d);
+    } else {
+      res = MP_OKAY;
+    }
+    if (c != NULL) {
+      mp_zero (c);
+    }
+    return res;
+  }
+	
+  /* init our temps */
+  if ((res = mp_init_multi(&ta, &tb, &tq, &q, NULL) != MP_OKAY)) {
+     return res;
+  }
+
+
+  mp_set(&tq, 1);
+  n = mp_count_bits(a) - mp_count_bits(b);
+  if (((res = mp_abs(a, &ta)) != MP_OKAY) ||
+      ((res = mp_abs(b, &tb)) != MP_OKAY) || 
+      ((res = mp_mul_2d(&tb, n, &tb)) != MP_OKAY) ||
+      ((res = mp_mul_2d(&tq, n, &tq)) != MP_OKAY)) {
+      goto LBL_ERR;
+  }
+
+  while (n-- >= 0) {
+     if (mp_cmp(&tb, &ta) != MP_GT) {
+        if (((res = mp_sub(&ta, &tb, &ta)) != MP_OKAY) ||
+            ((res = mp_add(&q, &tq, &q)) != MP_OKAY)) {
+           goto LBL_ERR;
+        }
+     }
+     if (((res = mp_div_2d(&tb, 1, &tb, NULL)) != MP_OKAY) ||
+         ((res = mp_div_2d(&tq, 1, &tq, NULL)) != MP_OKAY)) {
+           goto LBL_ERR;
+     }
+  }
+
+  /* now q == quotient and ta == remainder */
+  n  = a->sign;
+  n2 = (a->sign == b->sign ? MP_ZPOS : MP_NEG);
+  if (c != NULL) {
+     mp_exch(c, &q);
+     c->sign  = (mp_iszero(c) == MP_YES) ? MP_ZPOS : n2;
+  }
+  if (d != NULL) {
+     mp_exch(d, &ta);
+     d->sign = (mp_iszero(d) == MP_YES) ? MP_ZPOS : n;
+  }
+LBL_ERR:
+   mp_clear_multi(&ta, &tb, &tq, &q, NULL);
+   return res;
+}
+
+#else
+
+/* integer signed division. 
+ * c*b + d == a [e.g. a/b, c=quotient, d=remainder]
+ * HAC pp.598 Algorithm 14.20
+ *
+ * Note that the description in HAC is horribly 
+ * incomplete.  For example, it doesn't consider 
+ * the case where digits are removed from 'x' in 
+ * the inner loop.  It also doesn't consider the 
+ * case that y has fewer than three digits, etc..
+ *
+ * The overall algorithm is as described as 
+ * 14.20 from HAC but fixed to treat these cases.
+*/
+int mp_div (mp_int * a, mp_int * b, mp_int * c, mp_int * d)
+{
+  mp_int  q, x, y, t1, t2;
+  int     res, n, t, i, norm, neg;
+
+  /* is divisor zero ? */
+  if (mp_iszero (b) == 1) {
+    return MP_VAL;
+  }
+
+  /* if a < b then q=0, r = a */
+  if (mp_cmp_mag (a, b) == MP_LT) {
+    if (d != NULL) {
+      res = mp_copy (a, d);
+    } else {
+      res = MP_OKAY;
+    }
+    if (c != NULL) {
+      mp_zero (c);
+    }
+    return res;
+  }
+
+  if ((res = mp_init_size (&q, a->used + 2)) != MP_OKAY) {
+    return res;
+  }
+  q.used = a->used + 2;
+
+  if ((res = mp_init (&t1)) != MP_OKAY) {
+    goto LBL_Q;
+  }
+
+  if ((res = mp_init (&t2)) != MP_OKAY) {
+    goto LBL_T1;
+  }
+
+  if ((res = mp_init_copy (&x, a)) != MP_OKAY) {
+    goto LBL_T2;
+  }
+
+  if ((res = mp_init_copy (&y, b)) != MP_OKAY) {
+    goto LBL_X;
+  }
+
+  /* fix the sign */
+  neg = (a->sign == b->sign) ? MP_ZPOS : MP_NEG;
+  x.sign = y.sign = MP_ZPOS;
+
+  /* normalize both x and y, ensure that y >= b/2, [b == 2**DIGIT_BIT] */
+  norm = mp_count_bits(&y) % DIGIT_BIT;
+  if (norm < (int)(DIGIT_BIT-1)) {
+     norm = (DIGIT_BIT-1) - norm;
+     if ((res = mp_mul_2d (&x, norm, &x)) != MP_OKAY) {
+       goto LBL_Y;
+     }
+     if ((res = mp_mul_2d (&y, norm, &y)) != MP_OKAY) {
+       goto LBL_Y;
+     }
+  } else {
+     norm = 0;
+  }
+
+  /* note hac does 0 based, so if used==5 then its 0,1,2,3,4, e.g. use 4 */
+  n = x.used - 1;
+  t = y.used - 1;
+
+  /* while (x >= y*b**n-t) do { q[n-t] += 1; x -= y*b**{n-t} } */
+  if ((res = mp_lshd (&y, n - t)) != MP_OKAY) { /* y = y*b**{n-t} */
+    goto LBL_Y;
+  }
+
+  while (mp_cmp (&x, &y) != MP_LT) {
+    ++(q.dp[n - t]);
+    if ((res = mp_sub (&x, &y, &x)) != MP_OKAY) {
+      goto LBL_Y;
+    }
+  }
+
+  /* reset y by shifting it back down */
+  mp_rshd (&y, n - t);
+
+  /* step 3. for i from n down to (t + 1) */
+  for (i = n; i >= (t + 1); i--) {
+    if (i > x.used) {
+      continue;
+    }
+
+    /* step 3.1 if xi == yt then set q{i-t-1} to b-1, 
+     * otherwise set q{i-t-1} to (xi*b + x{i-1})/yt */
+    if (x.dp[i] == y.dp[t]) {
+      q.dp[i - t - 1] = ((((mp_digit)1) << DIGIT_BIT) - 1);
+    } else {
+      mp_word tmp;
+      tmp = ((mp_word) x.dp[i]) << ((mp_word) DIGIT_BIT);
+      tmp |= ((mp_word) x.dp[i - 1]);
+      tmp /= ((mp_word) y.dp[t]);
+      if (tmp > (mp_word) MP_MASK)
+        tmp = MP_MASK;
+      q.dp[i - t - 1] = (mp_digit) (tmp & (mp_word) (MP_MASK));
+    }
+
+    /* while (q{i-t-1} * (yt * b + y{t-1})) > 
+             xi * b**2 + xi-1 * b + xi-2 
+     
+       do q{i-t-1} -= 1; 
+    */
+    q.dp[i - t - 1] = (q.dp[i - t - 1] + 1) & MP_MASK;
+    do {
+      q.dp[i - t - 1] = (q.dp[i - t - 1] - 1) & MP_MASK;
+
+      /* find left hand */
+      mp_zero (&t1);
+      t1.dp[0] = (t - 1 < 0) ? 0 : y.dp[t - 1];
+      t1.dp[1] = y.dp[t];
+      t1.used = 2;
+      if ((res = mp_mul_d (&t1, q.dp[i - t - 1], &t1)) != MP_OKAY) {
+        goto LBL_Y;
+      }
+
+      /* find right hand */
+      t2.dp[0] = (i - 2 < 0) ? 0 : x.dp[i - 2];
+      t2.dp[1] = (i - 1 < 0) ? 0 : x.dp[i - 1];
+      t2.dp[2] = x.dp[i];
+      t2.used = 3;
+    } while (mp_cmp_mag(&t1, &t2) == MP_GT);
+
+    /* step 3.3 x = x - q{i-t-1} * y * b**{i-t-1} */
+    if ((res = mp_mul_d (&y, q.dp[i - t - 1], &t1)) != MP_OKAY) {
+      goto LBL_Y;
+    }
+
+    if ((res = mp_lshd (&t1, i - t - 1)) != MP_OKAY) {
+      goto LBL_Y;
+    }
+
+    if ((res = mp_sub (&x, &t1, &x)) != MP_OKAY) {
+      goto LBL_Y;
+    }
+
+    /* if x < 0 then { x = x + y*b**{i-t-1}; q{i-t-1} -= 1; } */
+    if (x.sign == MP_NEG) {
+      if ((res = mp_copy (&y, &t1)) != MP_OKAY) {
+        goto LBL_Y;
+      }
+      if ((res = mp_lshd (&t1, i - t - 1)) != MP_OKAY) {
+        goto LBL_Y;
+      }
+      if ((res = mp_add (&x, &t1, &x)) != MP_OKAY) {
+        goto LBL_Y;
+      }
+
+      q.dp[i - t - 1] = (q.dp[i - t - 1] - 1UL) & MP_MASK;
+    }
+  }
+
+  /* now q is the quotient and x is the remainder 
+   * [which we have to normalize] 
+   */
+  
+  /* get sign before writing to c */
+  x.sign = x.used == 0 ? MP_ZPOS : a->sign;
+
+  if (c != NULL) {
+    mp_clamp (&q);
+    mp_exch (&q, c);
+    c->sign = neg;
+  }
+
+  if (d != NULL) {
+    mp_div_2d (&x, norm, &x, NULL);
+    mp_exch (&x, d);
+  }
+
+  res = MP_OKAY;
+
+LBL_Y:mp_clear (&y);
+LBL_X:mp_clear (&x);
+LBL_T2:mp_clear (&t2);
+LBL_T1:mp_clear (&t1);
+LBL_Q:mp_clear (&q);
+  return res;
+}
+
+#endif
+
+#endif
diff --git a/libtommath/bn_mp_div_2.c b/libtommath/bn_mp_div_2.c
new file mode 100644
index 0000000..186a959
--- /dev/null
+++ b/libtommath/bn_mp_div_2.c
@@ -0,0 +1,64 @@
+#include <tommath.h>
+#ifdef BN_MP_DIV_2_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* b = a/2 */
+int mp_div_2(mp_int * a, mp_int * b)
+{
+  int     x, res, oldused;
+
+  /* copy */
+  if (b->alloc < a->used) {
+    if ((res = mp_grow (b, a->used)) != MP_OKAY) {
+      return res;
+    }
+  }
+
+  oldused = b->used;
+  b->used = a->used;
+  {
+    register mp_digit r, rr, *tmpa, *tmpb;
+
+    /* source alias */
+    tmpa = a->dp + b->used - 1;
+
+    /* dest alias */
+    tmpb = b->dp + b->used - 1;
+
+    /* carry */
+    r = 0;
+    for (x = b->used - 1; x >= 0; x--) {
+      /* get the carry for the next iteration */
+      rr = *tmpa & 1;
+
+      /* shift the current digit, add in carry and store */
+      *tmpb-- = (*tmpa-- >> 1) | (r << (DIGIT_BIT - 1));
+
+      /* forward carry to next iteration */
+      r = rr;
+    }
+
+    /* zero excess digits */
+    tmpb = b->dp + b->used;
+    for (x = b->used; x < oldused; x++) {
+      *tmpb++ = 0;
+    }
+  }
+  b->sign = a->sign;
+  mp_clamp (b);
+  return MP_OKAY;
+}
+#endif
diff --git a/libtommath/bn_mp_div_2d.c b/libtommath/bn_mp_div_2d.c
new file mode 100644
index 0000000..d7b7e05
--- /dev/null
+++ b/libtommath/bn_mp_div_2d.c
@@ -0,0 +1,93 @@
+#include <tommath.h>
+#ifdef BN_MP_DIV_2D_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* shift right by a certain bit count (store quotient in c, optional remainder in d) */
+int mp_div_2d (const mp_int * a, int b, mp_int * c, mp_int * d)
+{
+  mp_digit D, r, rr;
+  int     x, res;
+  mp_int  t;
+
+
+  /* if the shift count is <= 0 then we do no work */
+  if (b <= 0) {
+    res = mp_copy (a, c);
+    if (d != NULL) {
+      mp_zero (d);
+    }
+    return res;
+  }
+
+  if ((res = mp_init (&t)) != MP_OKAY) {
+    return res;
+  }
+
+  /* get the remainder */
+  if (d != NULL) {
+    if ((res = mp_mod_2d (a, b, &t)) != MP_OKAY) {
+      mp_clear (&t);
+      return res;
+    }
+  }
+
+  /* copy */
+  if ((res = mp_copy (a, c)) != MP_OKAY) {
+    mp_clear (&t);
+    return res;
+  }
+
+  /* shift by as many digits in the bit count */
+  if (b >= (int)DIGIT_BIT) {
+    mp_rshd (c, b / DIGIT_BIT);
+  }
+
+  /* shift any bit count < DIGIT_BIT */
+  D = (mp_digit) (b % DIGIT_BIT);
+  if (D != 0) {
+    register mp_digit *tmpc, mask, shift;
+
+    /* mask */
+    mask = (((mp_digit)1) << D) - 1;
+
+    /* shift for lsb */
+    shift = DIGIT_BIT - D;
+
+    /* alias */
+    tmpc = c->dp + (c->used - 1);
+
+    /* carry */
+    r = 0;
+    for (x = c->used - 1; x >= 0; x--) {
+      /* get the lower  bits of this word in a temp */
+      rr = *tmpc & mask;
+
+      /* shift the current word and mix in the carry bits from the previous word */
+      *tmpc = (*tmpc >> D) | (r << shift);
+      --tmpc;
+
+      /* set the carry to the carry bits of the current word found above */
+      r = rr;
+    }
+  }
+  mp_clamp (c);
+  if (d != NULL) {
+    mp_exch (&t, d);
+  }
+  mp_clear (&t);
+  return MP_OKAY;
+}
+#endif
diff --git a/libtommath/bn_mp_div_3.c b/libtommath/bn_mp_div_3.c
new file mode 100644
index 0000000..79a9816
--- /dev/null
+++ b/libtommath/bn_mp_div_3.c
@@ -0,0 +1,75 @@
+#include <tommath.h>
+#ifdef BN_MP_DIV_3_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* divide by three (based on routine from MPI and the GMP manual) */
+int
+mp_div_3 (mp_int * a, mp_int *c, mp_digit * d)
+{
+  mp_int   q;
+  mp_word  w, t;
+  mp_digit b;
+  int      res, ix;
+  
+  /* b = 2**DIGIT_BIT / 3 */
+  b = (((mp_word)1) << ((mp_word)DIGIT_BIT)) / ((mp_word)3);
+
+  if ((res = mp_init_size(&q, a->used)) != MP_OKAY) {
+     return res;
+  }
+  
+  q.used = a->used;
+  q.sign = a->sign;
+  w = 0;
+  for (ix = a->used - 1; ix >= 0; ix--) {
+     w = (w << ((mp_word)DIGIT_BIT)) | ((mp_word)a->dp[ix]);
+
+     if (w >= 3) {
+        /* multiply w by [1/3] */
+        t = (w * ((mp_word)b)) >> ((mp_word)DIGIT_BIT);
+
+        /* now subtract 3 * [w/3] from w, to get the remainder */
+        w -= t+t+t;
+
+        /* fixup the remainder as required since
+         * the optimization is not exact.
+         */
+        while (w >= 3) {
+           t += 1;
+           w -= 3;
+        }
+      } else {
+        t = 0;
+      }
+      q.dp[ix] = (mp_digit)t;
+  }
+
+  /* [optional] store the remainder */
+  if (d != NULL) {
+     *d = (mp_digit)w;
+  }
+
+  /* [optional] store the quotient */
+  if (c != NULL) {
+     mp_clamp(&q);
+     mp_exch(&q, c);
+  }
+  mp_clear(&q);
+  
+  return res;
+}
+
+#endif
diff --git a/libtommath/bn_mp_div_d.c b/libtommath/bn_mp_div_d.c
new file mode 100644
index 0000000..af18d0a
--- /dev/null
+++ b/libtommath/bn_mp_div_d.c
@@ -0,0 +1,110 @@
+#include <tommath.h>
+#ifdef BN_MP_DIV_D_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+static int s_is_power_of_two(mp_digit b, int *p)
+{
+   int x;
+
+   /* quick out - if (b & (b-1)) isn't zero, b isn't a power of two */
+   if ((b==0) || (b & (b-1))) {
+       return 0;
+   }
+   for (x = 1; x < DIGIT_BIT; x++) {
+      if (b == (((mp_digit)1)<<x)) {
+         *p = x;
+         return 1;
+      }
+   }
+   return 0;
+}
+
+/* single digit division (based on routine from MPI) */
+int mp_div_d (mp_int * a, mp_digit b, mp_int * c, mp_digit * d)
+{
+  mp_int  q;
+  mp_word w;
+  mp_digit t;
+  int     res, ix;
+
+  /* cannot divide by zero */
+  if (b == 0) {
+     return MP_VAL;
+  }
+
+  /* quick outs */
+  if (b == 1 || mp_iszero(a) == 1) {
+     if (d != NULL) {
+        *d = 0;
+     }
+     if (c != NULL) {
+        return mp_copy(a, c);
+     }
+     return MP_OKAY;
+  }
+
+  /* power of two ? */
+  if (s_is_power_of_two(b, &ix) == 1) {
+     if (d != NULL) {
+        *d = a->dp[0] & ((((mp_digit)1)<<ix) - 1);
+     }
+     if (c != NULL) {
+        return mp_div_2d(a, ix, c, NULL);
+     }
+     return MP_OKAY;
+  }
+
+#ifdef BN_MP_DIV_3_C
+  /* three? */
+  if (b == 3) {
+     return mp_div_3(a, c, d);
+  }
+#endif
+
+  /* no easy answer [c'est la vie].  Just division */
+  if ((res = mp_init_size(&q, a->used)) != MP_OKAY) {
+     return res;
+  }
+  
+  q.used = a->used;
+  q.sign = a->sign;
+  w = 0;
+  for (ix = a->used - 1; ix >= 0; ix--) {
+     w = (w << ((mp_word)DIGIT_BIT)) | ((mp_word)a->dp[ix]);
+     
+     if (w >= b) {
+        t = (mp_digit)(w / b);
+        w -= ((mp_word)t) * ((mp_word)b);
+      } else {
+        t = 0;
+      }
+      q.dp[ix] = (mp_digit)t;
+  }
+  
+  if (d != NULL) {
+     *d = (mp_digit)w;
+  }
+  
+  if (c != NULL) {
+     mp_clamp(&q);
+     mp_exch(&q, c);
+  }
+  mp_clear(&q);
+  
+  return res;
+}
+
+#endif
diff --git a/libtommath/bn_mp_dr_is_modulus.c b/libtommath/bn_mp_dr_is_modulus.c
new file mode 100644
index 0000000..8ad31dc
--- /dev/null
+++ b/libtommath/bn_mp_dr_is_modulus.c
@@ -0,0 +1,39 @@
+#include <tommath.h>
+#ifdef BN_MP_DR_IS_MODULUS_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* determines if a number is a valid DR modulus */
+int mp_dr_is_modulus(mp_int *a)
+{
+   int ix;
+
+   /* must be at least two digits */
+   if (a->used < 2) {
+      return 0;
+   }
+
+   /* must be of the form b**k - a [a <= b] so all
+    * but the first digit must be equal to -1 (mod b).
+    */
+   for (ix = 1; ix < a->used; ix++) {
+       if (a->dp[ix] != MP_MASK) {
+          return 0;
+       }
+   }
+   return 1;
+}
+
+#endif
diff --git a/libtommath/bn_mp_dr_reduce.c b/libtommath/bn_mp_dr_reduce.c
new file mode 100644
index 0000000..8337591
--- /dev/null
+++ b/libtommath/bn_mp_dr_reduce.c
@@ -0,0 +1,90 @@
+#include <tommath.h>
+#ifdef BN_MP_DR_REDUCE_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* reduce "x" in place modulo "n" using the Diminished Radix algorithm.
+ *
+ * Based on algorithm from the paper
+ *
+ * "Generating Efficient Primes for Discrete Log Cryptosystems"
+ *                 Chae Hoon Lim, Pil Joong Lee,
+ *          POSTECH Information Research Laboratories
+ *
+ * The modulus must be of a special format [see manual]
+ *
+ * Has been modified to use algorithm 7.10 from the LTM book instead
+ *
+ * Input x must be in the range 0 <= x <= (n-1)**2
+ */
+int
+mp_dr_reduce (mp_int * x, mp_int * n, mp_digit k)
+{
+  int      err, i, m;
+  mp_word  r;
+  mp_digit mu, *tmpx1, *tmpx2;
+
+  /* m = digits in modulus */
+  m = n->used;
+
+  /* ensure that "x" has at least 2m digits */
+  if (x->alloc < m + m) {
+    if ((err = mp_grow (x, m + m)) != MP_OKAY) {
+      return err;
+    }
+  }
+
+/* top of loop, this is where the code resumes if
+ * another reduction pass is required.
+ */
+top:
+  /* aliases for digits */
+  /* alias for lower half of x */
+  tmpx1 = x->dp;
+
+  /* alias for upper half of x, or x/B**m */
+  tmpx2 = x->dp + m;
+
+  /* set carry to zero */
+  mu = 0;
+
+  /* compute (x mod B**m) + k * [x/B**m] inline and inplace */
+  for (i = 0; i < m; i++) {
+      r         = ((mp_word)*tmpx2++) * ((mp_word)k) + *tmpx1 + mu;
+      *tmpx1++  = (mp_digit)(r & MP_MASK);
+      mu        = (mp_digit)(r >> ((mp_word)DIGIT_BIT));
+  }
+
+  /* set final carry */
+  *tmpx1++ = mu;
+
+  /* zero words above m */
+  for (i = m + 1; i < x->used; i++) {
+      *tmpx1++ = 0;
+  }
+
+  /* clamp, sub and return */
+  mp_clamp (x);
+
+  /* if x >= n then subtract and reduce again
+   * Each successive "recursion" makes the input smaller and smaller.
+   */
+  if (mp_cmp_mag (x, n) != MP_LT) {
+    s_mp_sub(x, n, x);
+    goto top;
+  }
+  return MP_OKAY;
+}
+#endif
diff --git a/libtommath/bn_mp_dr_setup.c b/libtommath/bn_mp_dr_setup.c
new file mode 100644
index 0000000..de00e2d
--- /dev/null
+++ b/libtommath/bn_mp_dr_setup.c
@@ -0,0 +1,28 @@
+#include <tommath.h>
+#ifdef BN_MP_DR_SETUP_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* determines the setup value */
+void mp_dr_setup(mp_int *a, mp_digit *d)
+{
+   /* the casts are required if DIGIT_BIT is one less than
+    * the number of bits in a mp_digit [e.g. DIGIT_BIT==31]
+    */
+   *d = (mp_digit)((((mp_word)1) << ((mp_word)DIGIT_BIT)) - 
+        ((mp_word)a->dp[0]));
+}
+
+#endif
diff --git a/libtommath/bn_mp_exch.c b/libtommath/bn_mp_exch.c
new file mode 100644
index 0000000..b7bd186
--- /dev/null
+++ b/libtommath/bn_mp_exch.c
@@ -0,0 +1,30 @@
+#include <tommath.h>
+#ifdef BN_MP_EXCH_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* swap the elements of two integers, for cases where you can't simply swap the 
+ * mp_int pointers around
+ */
+void
+mp_exch (mp_int * a, mp_int * b)
+{
+  mp_int  t;
+
+  t  = *a;
+  *a = *b;
+  *b = t;
+}
+#endif
diff --git a/libtommath/bn_mp_expt_d.c b/libtommath/bn_mp_expt_d.c
new file mode 100644
index 0000000..132f480
--- /dev/null
+++ b/libtommath/bn_mp_expt_d.c
@@ -0,0 +1,53 @@
+#include <tommath.h>
+#ifdef BN_MP_EXPT_D_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* calculate c = a**b  using a square-multiply algorithm */
+int mp_expt_d (mp_int * a, mp_digit b, mp_int * c)
+{
+  int     res, x;
+  mp_int  g;
+
+  if ((res = mp_init_copy (&g, a)) != MP_OKAY) {
+    return res;
+  }
+
+  /* set initial result */
+  mp_set (c, 1);
+
+  for (x = 0; x < (int) DIGIT_BIT; x++) {
+    /* square */
+    if ((res = mp_sqr (c, c)) != MP_OKAY) {
+      mp_clear (&g);
+      return res;
+    }
+
+    /* if the bit is set multiply */
+    if ((b & (mp_digit) (((mp_digit)1) << (DIGIT_BIT - 1))) != 0) {
+      if ((res = mp_mul (c, &g, c)) != MP_OKAY) {
+         mp_clear (&g);
+         return res;
+      }
+    }
+
+    /* shift to next bit */
+    b <<= 1;
+  }
+
+  mp_clear (&g);
+  return MP_OKAY;
+}
+#endif
diff --git a/libtommath/bn_mp_exptmod.c b/libtommath/bn_mp_exptmod.c
new file mode 100644
index 0000000..b7d9fb7
--- /dev/null
+++ b/libtommath/bn_mp_exptmod.c
@@ -0,0 +1,108 @@
+#include <tommath.h>
+#ifdef BN_MP_EXPTMOD_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+
+/* this is a shell function that calls either the normal or Montgomery
+ * exptmod functions.  Originally the call to the montgomery code was
+ * embedded in the normal function but that wasted alot of stack space
+ * for nothing (since 99% of the time the Montgomery code would be called)
+ */
+int mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y)
+{
+  int dr;
+
+  /* modulus P must be positive */
+  if (P->sign == MP_NEG) {
+     return MP_VAL;
+  }
+
+  /* if exponent X is negative we have to recurse */
+  if (X->sign == MP_NEG) {
+#ifdef BN_MP_INVMOD_C
+     mp_int tmpG, tmpX;
+     int err;
+
+     /* first compute 1/G mod P */
+     if ((err = mp_init(&tmpG)) != MP_OKAY) {
+        return err;
+     }
+     if ((err = mp_invmod(G, P, &tmpG)) != MP_OKAY) {
+        mp_clear(&tmpG);
+        return err;
+     }
+
+     /* now get |X| */
+     if ((err = mp_init(&tmpX)) != MP_OKAY) {
+        mp_clear(&tmpG);
+        return err;
+     }
+     if ((err = mp_abs(X, &tmpX)) != MP_OKAY) {
+        mp_clear_multi(&tmpG, &tmpX, NULL);
+        return err;
+     }
+
+     /* and now compute (1/G)**|X| instead of G**X [X < 0] */
+     err = mp_exptmod(&tmpG, &tmpX, P, Y);
+     mp_clear_multi(&tmpG, &tmpX, NULL);
+     return err;
+#else 
+     /* no invmod */
+     return MP_VAL;
+#endif
+  }
+
+/* modified diminished radix reduction */
+#if defined(BN_MP_REDUCE_IS_2K_L_C) && defined(BN_MP_REDUCE_2K_L_C) && defined(BN_S_MP_EXPTMOD_C)
+  if (mp_reduce_is_2k_l(P) == MP_YES) {
+     return s_mp_exptmod(G, X, P, Y, 1);
+  }
+#endif
+
+#ifdef BN_MP_DR_IS_MODULUS_C
+  /* is it a DR modulus? */
+  dr = mp_dr_is_modulus(P);
+#else
+  /* default to no */
+  dr = 0;
+#endif
+
+#ifdef BN_MP_REDUCE_IS_2K_C
+  /* if not, is it a unrestricted DR modulus? */
+  if (dr == 0) {
+     dr = mp_reduce_is_2k(P) << 1;
+  }
+#endif
+    
+  /* if the modulus is odd or dr != 0 use the montgomery method */
+#ifdef BN_MP_EXPTMOD_FAST_C
+  if (mp_isodd (P) == 1 || dr !=  0) {
+    return mp_exptmod_fast (G, X, P, Y, dr);
+  } else {
+#endif
+#ifdef BN_S_MP_EXPTMOD_C
+    /* otherwise use the generic Barrett reduction technique */
+    return s_mp_exptmod (G, X, P, Y, 0);
+#else
+    /* no exptmod for evens */
+    return MP_VAL;
+#endif
+#ifdef BN_MP_EXPTMOD_FAST_C
+  }
+#endif
+}
+
+#endif
diff --git a/libtommath/bn_mp_exptmod_fast.c b/libtommath/bn_mp_exptmod_fast.c
new file mode 100644
index 0000000..1902e79
--- /dev/null
+++ b/libtommath/bn_mp_exptmod_fast.c
@@ -0,0 +1,316 @@
+#include <tommath.h>
+#ifdef BN_MP_EXPTMOD_FAST_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* computes Y == G**X mod P, HAC pp.616, Algorithm 14.85
+ *
+ * Uses a left-to-right k-ary sliding window to compute the modular exponentiation.
+ * The value of k changes based on the size of the exponent.
+ *
+ * Uses Montgomery or Diminished Radix reduction [whichever appropriate]
+ */
+
+#ifdef MP_LOW_MEM
+   #define TAB_SIZE 32
+#else
+   #define TAB_SIZE 256
+#endif
+
+int mp_exptmod_fast (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int redmode)
+{
+  mp_int  M[TAB_SIZE], res;
+  mp_digit buf, mp;
+  int     err, bitbuf, bitcpy, bitcnt, mode, digidx, x, y, winsize;
+
+  /* use a pointer to the reduction algorithm.  This allows us to use
+   * one of many reduction algorithms without modding the guts of
+   * the code with if statements everywhere.
+   */
+  int     (*redux)(mp_int*,mp_int*,mp_digit);
+
+  /* find window size */
+  x = mp_count_bits (X);
+  if (x <= 7) {
+    winsize = 2;
+  } else if (x <= 36) {
+    winsize = 3;
+  } else if (x <= 140) {
+    winsize = 4;
+  } else if (x <= 450) {
+    winsize = 5;
+  } else if (x <= 1303) {
+    winsize = 6;
+  } else if (x <= 3529) {
+    winsize = 7;
+  } else {
+    winsize = 8;
+  }
+
+#ifdef MP_LOW_MEM
+  if (winsize > 5) {
+     winsize = 5;
+  }
+#endif
+
+  /* init M array */
+  /* init first cell */
+  if ((err = mp_init(&M[1])) != MP_OKAY) {
+     return err;
+  }
+
+  /* now init the second half of the array */
+  for (x = 1<<(winsize-1); x < (1 << winsize); x++) {
+    if ((err = mp_init(&M[x])) != MP_OKAY) {
+      for (y = 1<<(winsize-1); y < x; y++) {
+        mp_clear (&M[y]);
+      }
+      mp_clear(&M[1]);
+      return err;
+    }
+  }
+
+  /* determine and setup reduction code */
+  if (redmode == 0) {
+#ifdef BN_MP_MONTGOMERY_SETUP_C     
+     /* now setup montgomery  */
+     if ((err = mp_montgomery_setup (P, &mp)) != MP_OKAY) {
+        goto LBL_M;
+     }
+#else
+     err = MP_VAL;
+     goto LBL_M;
+#endif
+
+     /* automatically pick the comba one if available (saves quite a few calls/ifs) */
+#ifdef BN_FAST_MP_MONTGOMERY_REDUCE_C
+     if (((P->used * 2 + 1) < MP_WARRAY) &&
+          P->used < (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) {
+        redux = fast_mp_montgomery_reduce;
+     } else 
+#endif
+     {
+#ifdef BN_MP_MONTGOMERY_REDUCE_C
+        /* use slower baseline Montgomery method */
+        redux = mp_montgomery_reduce;
+#else
+        err = MP_VAL;
+        goto LBL_M;
+#endif
+     }
+  } else if (redmode == 1) {
+#if defined(BN_MP_DR_SETUP_C) && defined(BN_MP_DR_REDUCE_C)
+     /* setup DR reduction for moduli of the form B**k - b */
+     mp_dr_setup(P, &mp);
+     redux = mp_dr_reduce;
+#else
+     err = MP_VAL;
+     goto LBL_M;
+#endif
+  } else {
+#if defined(BN_MP_REDUCE_2K_SETUP_C) && defined(BN_MP_REDUCE_2K_C)
+     /* setup DR reduction for moduli of the form 2**k - b */
+     if ((err = mp_reduce_2k_setup(P, &mp)) != MP_OKAY) {
+        goto LBL_M;
+     }
+     redux = mp_reduce_2k;
+#else
+     err = MP_VAL;
+     goto LBL_M;
+#endif
+  }
+
+  /* setup result */
+  if ((err = mp_init (&res)) != MP_OKAY) {
+    goto LBL_M;
+  }
+
+  /* create M table
+   *
+
+   *
+   * The first half of the table is not computed though accept for M[0] and M[1]
+   */
+
+  if (redmode == 0) {
+#ifdef BN_MP_MONTGOMERY_CALC_NORMALIZATION_C
+     /* now we need R mod m */
+     if ((err = mp_montgomery_calc_normalization (&res, P)) != MP_OKAY) {
+       goto LBL_RES;
+     }
+#else 
+     err = MP_VAL;
+     goto LBL_RES;
+#endif
+
+     /* now set M[1] to G * R mod m */
+     if ((err = mp_mulmod (G, &res, P, &M[1])) != MP_OKAY) {
+       goto LBL_RES;
+     }
+  } else {
+     mp_set(&res, 1);
+     if ((err = mp_mod(G, P, &M[1])) != MP_OKAY) {
+        goto LBL_RES;
+     }
+  }
+
+  /* compute the value at M[1<<(winsize-1)] by squaring M[1] (winsize-1) times */
+  if ((err = mp_copy (&M[1], &M[1 << (winsize - 1)])) != MP_OKAY) {
+    goto LBL_RES;
+  }
+
+  for (x = 0; x < (winsize - 1); x++) {
+    if ((err = mp_sqr (&M[1 << (winsize - 1)], &M[1 << (winsize - 1)])) != MP_OKAY) {
+      goto LBL_RES;
+    }
+    if ((err = redux (&M[1 << (winsize - 1)], P, mp)) != MP_OKAY) {
+      goto LBL_RES;
+    }
+  }
+
+  /* create upper table */
+  for (x = (1 << (winsize - 1)) + 1; x < (1 << winsize); x++) {
+    if ((err = mp_mul (&M[x - 1], &M[1], &M[x])) != MP_OKAY) {
+      goto LBL_RES;
+    }
+    if ((err = redux (&M[x], P, mp)) != MP_OKAY) {
+      goto LBL_RES;
+    }
+  }
+
+  /* set initial mode and bit cnt */
+  mode   = 0;
+  bitcnt = 1;
+  buf    = 0;
+  digidx = X->used - 1;
+  bitcpy = 0;
+  bitbuf = 0;
+
+  for (;;) {
+    /* grab next digit as required */
+    if (--bitcnt == 0) {
+      /* if digidx == -1 we are out of digits so break */
+      if (digidx == -1) {
+        break;
+      }
+      /* read next digit and reset bitcnt */
+      buf    = X->dp[digidx--];
+      bitcnt = (int)DIGIT_BIT;
+    }
+
+    /* grab the next msb from the exponent */
+    y     = (mp_digit)(buf >> (DIGIT_BIT - 1)) & 1;
+    buf <<= (mp_digit)1;
+
+    /* if the bit is zero and mode == 0 then we ignore it
+     * These represent the leading zero bits before the first 1 bit
+     * in the exponent.  Technically this opt is not required but it
+     * does lower the # of trivial squaring/reductions used
+     */
+    if (mode == 0 && y == 0) {
+      continue;
+    }
+
+    /* if the bit is zero and mode == 1 then we square */
+    if (mode == 1 && y == 0) {
+      if ((err = mp_sqr (&res, &res)) != MP_OKAY) {
+        goto LBL_RES;
+      }
+      if ((err = redux (&res, P, mp)) != MP_OKAY) {
+        goto LBL_RES;
+      }
+      continue;
+    }
+
+    /* else we add it to the window */
+    bitbuf |= (y << (winsize - ++bitcpy));
+    mode    = 2;
+
+    if (bitcpy == winsize) {
+      /* ok window is filled so square as required and multiply  */
+      /* square first */
+      for (x = 0; x < winsize; x++) {
+        if ((err = mp_sqr (&res, &res)) != MP_OKAY) {
+          goto LBL_RES;
+        }
+        if ((err = redux (&res, P, mp)) != MP_OKAY) {
+          goto LBL_RES;
+        }
+      }
+
+      /* then multiply */
+      if ((err = mp_mul (&res, &M[bitbuf], &res)) != MP_OKAY) {
+        goto LBL_RES;
+      }
+      if ((err = redux (&res, P, mp)) != MP_OKAY) {
+        goto LBL_RES;
+      }
+
+      /* empty window and reset */
+      bitcpy = 0;
+      bitbuf = 0;
+      mode   = 1;
+    }
+  }
+
+  /* if bits remain then square/multiply */
+  if (mode == 2 && bitcpy > 0) {
+    /* square then multiply if the bit is set */
+    for (x = 0; x < bitcpy; x++) {
+      if ((err = mp_sqr (&res, &res)) != MP_OKAY) {
+        goto LBL_RES;
+      }
+      if ((err = redux (&res, P, mp)) != MP_OKAY) {
+        goto LBL_RES;
+      }
+
+      /* get next bit of the window */
+      bitbuf <<= 1;
+      if ((bitbuf & (1 << winsize)) != 0) {
+        /* then multiply */
+        if ((err = mp_mul (&res, &M[1], &res)) != MP_OKAY) {
+          goto LBL_RES;
+        }
+        if ((err = redux (&res, P, mp)) != MP_OKAY) {
+          goto LBL_RES;
+        }
+      }
+    }
+  }
+
+  if (redmode == 0) {
+     /* fixup result if Montgomery reduction is used
+      * recall that any value in a Montgomery system is
+      * actually multiplied by R mod n.  So we have
+      * to reduce one more time to cancel out the factor
+      * of R.
+      */
+     if ((err = redux(&res, P, mp)) != MP_OKAY) {
+       goto LBL_RES;
+     }
+  }
+
+  /* swap res with Y */
+  mp_exch (&res, Y);
+  err = MP_OKAY;
+LBL_RES:mp_clear (&res);
+LBL_M:
+  mp_clear(&M[1]);
+  for (x = 1<<(winsize-1); x < (1 << winsize); x++) {
+    mp_clear (&M[x]);
+  }
+  return err;
+}
+#endif
diff --git a/libtommath/bn_mp_exteuclid.c b/libtommath/bn_mp_exteuclid.c
new file mode 100644
index 0000000..2e69ce1
--- /dev/null
+++ b/libtommath/bn_mp_exteuclid.c
@@ -0,0 +1,78 @@
+#include <tommath.h>
+#ifdef BN_MP_EXTEUCLID_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* Extended euclidean algorithm of (a, b) produces 
+   a*u1 + b*u2 = u3
+ */
+int mp_exteuclid(mp_int *a, mp_int *b, mp_int *U1, mp_int *U2, mp_int *U3)
+{
+   mp_int u1,u2,u3,v1,v2,v3,t1,t2,t3,q,tmp;
+   int err;
+
+   if ((err = mp_init_multi(&u1, &u2, &u3, &v1, &v2, &v3, &t1, &t2, &t3, &q, &tmp, NULL)) != MP_OKAY) {
+      return err;
+   }
+
+   /* initialize, (u1,u2,u3) = (1,0,a) */
+   mp_set(&u1, 1);
+   if ((err = mp_copy(a, &u3)) != MP_OKAY)                                        { goto _ERR; }
+
+   /* initialize, (v1,v2,v3) = (0,1,b) */
+   mp_set(&v2, 1);
+   if ((err = mp_copy(b, &v3)) != MP_OKAY)                                        { goto _ERR; }
+
+   /* loop while v3 != 0 */
+   while (mp_iszero(&v3) == MP_NO) {
+       /* q = u3/v3 */
+       if ((err = mp_div(&u3, &v3, &q, NULL)) != MP_OKAY)                         { goto _ERR; }
+
+       /* (t1,t2,t3) = (u1,u2,u3) - (v1,v2,v3)q */
+       if ((err = mp_mul(&v1, &q, &tmp)) != MP_OKAY)                              { goto _ERR; }
+       if ((err = mp_sub(&u1, &tmp, &t1)) != MP_OKAY)                             { goto _ERR; }
+       if ((err = mp_mul(&v2, &q, &tmp)) != MP_OKAY)                              { goto _ERR; }
+       if ((err = mp_sub(&u2, &tmp, &t2)) != MP_OKAY)                             { goto _ERR; }
+       if ((err = mp_mul(&v3, &q, &tmp)) != MP_OKAY)                              { goto _ERR; }
+       if ((err = mp_sub(&u3, &tmp, &t3)) != MP_OKAY)                             { goto _ERR; }
+
+       /* (u1,u2,u3) = (v1,v2,v3) */
+       if ((err = mp_copy(&v1, &u1)) != MP_OKAY)                                  { goto _ERR; }
+       if ((err = mp_copy(&v2, &u2)) != MP_OKAY)                                  { goto _ERR; }
+       if ((err = mp_copy(&v3, &u3)) != MP_OKAY)                                  { goto _ERR; }
+
+       /* (v1,v2,v3) = (t1,t2,t3) */
+       if ((err = mp_copy(&t1, &v1)) != MP_OKAY)                                  { goto _ERR; }
+       if ((err = mp_copy(&t2, &v2)) != MP_OKAY)                                  { goto _ERR; }
+       if ((err = mp_copy(&t3, &v3)) != MP_OKAY)                                  { goto _ERR; }
+   }
+
+   /* make sure U3 >= 0 */
+   if (u3.sign == MP_NEG) {
+      mp_neg(&u1, &u1);
+      mp_neg(&u2, &u2);
+      mp_neg(&u3, &u3);
+   }
+
+   /* copy result out */
+   if (U1 != NULL) { mp_exch(U1, &u1); }
+   if (U2 != NULL) { mp_exch(U2, &u2); }
+   if (U3 != NULL) { mp_exch(U3, &u3); }
+
+   err = MP_OKAY;
+_ERR: mp_clear_multi(&u1, &u2, &u3, &v1, &v2, &v3, &t1, &t2, &t3, &q, &tmp, NULL);
+   return err;
+}
+#endif
diff --git a/libtommath/bn_mp_fread.c b/libtommath/bn_mp_fread.c
new file mode 100644
index 0000000..44e1ea8
--- /dev/null
+++ b/libtommath/bn_mp_fread.c
@@ -0,0 +1,63 @@
+#include <tommath.h>
+#ifdef BN_MP_FREAD_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* read a bigint from a file stream in ASCII */
+int mp_fread(mp_int *a, int radix, FILE *stream)
+{
+   int err, ch, neg, y;
+   
+   /* clear a */
+   mp_zero(a);
+   
+   /* if first digit is - then set negative */
+   ch = fgetc(stream);
+   if (ch == '-') {
+      neg = MP_NEG;
+      ch = fgetc(stream);
+   } else {
+      neg = MP_ZPOS;
+   }
+   
+   for (;;) {
+      /* find y in the radix map */
+      for (y = 0; y < radix; y++) {
+          if (mp_s_rmap[y] == ch) {
+             break;
+          }
+      }
+      if (y == radix) {
+         break;
+      }
+      
+      /* shift up and add */
+      if ((err = mp_mul_d(a, radix, a)) != MP_OKAY) {
+         return err;
+      }
+      if ((err = mp_add_d(a, y, a)) != MP_OKAY) {
+         return err;
+      }
+      
+      ch = fgetc(stream);
+   }
+   if (mp_cmp_d(a, 0) != MP_EQ) {
+      a->sign = neg;
+   }
+   
+   return MP_OKAY;
+}
+
+#endif
diff --git a/libtommath/bn_mp_fwrite.c b/libtommath/bn_mp_fwrite.c
new file mode 100644
index 0000000..b0ec29e
--- /dev/null
+++ b/libtommath/bn_mp_fwrite.c
@@ -0,0 +1,48 @@
+#include <tommath.h>
+#ifdef BN_MP_FWRITE_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+int mp_fwrite(mp_int *a, int radix, FILE *stream)
+{
+   char *buf;
+   int err, len, x;
+   
+   if ((err = mp_radix_size(a, radix, &len)) != MP_OKAY) {
+      return err;
+   }
+
+   buf = OPT_CAST(char) XMALLOC (len);
+   if (buf == NULL) {
+      return MP_MEM;
+   }
+   
+   if ((err = mp_toradix(a, buf, radix)) != MP_OKAY) {
+      XFREE (buf);
+      return err;
+   }
+   
+   for (x = 0; x < len; x++) {
+       if (fputc(buf[x], stream) == EOF) {
+          XFREE (buf);
+          return MP_VAL;
+       }
+   }
+   
+   XFREE (buf);
+   return MP_OKAY;
+}
+
+#endif
diff --git a/libtommath/bn_mp_gcd.c b/libtommath/bn_mp_gcd.c
new file mode 100644
index 0000000..68cfa03
--- /dev/null
+++ b/libtommath/bn_mp_gcd.c
@@ -0,0 +1,101 @@
+#include <tommath.h>
+#ifdef BN_MP_GCD_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* Greatest Common Divisor using the binary method */
+int mp_gcd (mp_int * a, mp_int * b, mp_int * c)
+{
+  mp_int  u, v;
+  int     k, u_lsb, v_lsb, res;
+
+  /* either zero than gcd is the largest */
+  if (mp_iszero (a) == MP_YES) {
+    return mp_abs (b, c);
+  }
+  if (mp_iszero (b) == MP_YES) {
+    return mp_abs (a, c);
+  }
+
+  /* get copies of a and b we can modify */
+  if ((res = mp_init_copy (&u, a)) != MP_OKAY) {
+    return res;
+  }
+
+  if ((res = mp_init_copy (&v, b)) != MP_OKAY) {
+    goto LBL_U;
+  }
+
+  /* must be positive for the remainder of the algorithm */
+  u.sign = v.sign = MP_ZPOS;
+
+  /* B1.  Find the common power of two for u and v */
+  u_lsb = mp_cnt_lsb(&u);
+  v_lsb = mp_cnt_lsb(&v);
+  k     = MIN(u_lsb, v_lsb);
+
+  if (k > 0) {
+     /* divide the power of two out */
+     if ((res = mp_div_2d(&u, k, &u, NULL)) != MP_OKAY) {
+        goto LBL_V;
+     }
+
+     if ((res = mp_div_2d(&v, k, &v, NULL)) != MP_OKAY) {
+        goto LBL_V;
+     }
+  }
+
+  /* divide any remaining factors of two out */
+  if (u_lsb != k) {
+     if ((res = mp_div_2d(&u, u_lsb - k, &u, NULL)) != MP_OKAY) {
+        goto LBL_V;
+     }
+  }
+
+  if (v_lsb != k) {
+     if ((res = mp_div_2d(&v, v_lsb - k, &v, NULL)) != MP_OKAY) {
+        goto LBL_V;
+     }
+  }
+
+  while (mp_iszero(&v) == 0) {
+     /* make sure v is the largest */
+     if (mp_cmp_mag(&u, &v) == MP_GT) {
+        /* swap u and v to make sure v is >= u */
+        mp_exch(&u, &v);
+     }
+     
+     /* subtract smallest from largest */
+     if ((res = s_mp_sub(&v, &u, &v)) != MP_OKAY) {
+        goto LBL_V;
+     }
+     
+     /* Divide out all factors of two */
+     if ((res = mp_div_2d(&v, mp_cnt_lsb(&v), &v, NULL)) != MP_OKAY) {
+        goto LBL_V;
+     } 
+  } 
+
+  /* multiply by 2**k which we divided out at the beginning */
+  if ((res = mp_mul_2d (&u, k, c)) != MP_OKAY) {
+     goto LBL_V;
+  }
+  c->sign = MP_ZPOS;
+  res = MP_OKAY;
+LBL_V:mp_clear (&u);
+LBL_U:mp_clear (&v);
+  return res;
+}
+#endif
diff --git a/libtommath/bn_mp_get_int.c b/libtommath/bn_mp_get_int.c
new file mode 100644
index 0000000..762cb23
--- /dev/null
+++ b/libtommath/bn_mp_get_int.c
@@ -0,0 +1,41 @@
+#include <tommath.h>
+#ifdef BN_MP_GET_INT_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* get the lower 32-bits of an mp_int */
+unsigned long mp_get_int(mp_int * a) 
+{
+  int i;
+  unsigned long res;
+
+  if (a->used == 0) {
+     return 0;
+  }
+
+  /* get number of digits of the lsb we have to read */
+  i = MIN(a->used,(int)((sizeof(unsigned long)*CHAR_BIT+DIGIT_BIT-1)/DIGIT_BIT))-1;
+
+  /* get most significant digit of result */
+  res = DIGIT(a,i);
+   
+  while (--i >= 0) {
+    res = (res << DIGIT_BIT) | DIGIT(a,i);
+  }
+
+  /* force result to 32-bits always so it is consistent on non 32-bit platforms */
+  return res & 0xFFFFFFFFUL;
+}
+#endif
diff --git a/libtommath/bn_mp_grow.c b/libtommath/bn_mp_grow.c
new file mode 100644
index 0000000..b5b2407
--- /dev/null
+++ b/libtommath/bn_mp_grow.c
@@ -0,0 +1,53 @@
+#include <tommath.h>
+#ifdef BN_MP_GROW_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* grow as required */
+int mp_grow (mp_int * a, int size)
+{
+  int     i;
+  mp_digit *tmp;
+
+  /* if the alloc size is smaller alloc more ram */
+  if (a->alloc < size) {
+    /* ensure there are always at least MP_PREC digits extra on top */
+    size += (MP_PREC * 2) - (size % MP_PREC);
+
+    /* reallocate the array a->dp
+     *
+     * We store the return in a temporary variable
+     * in case the operation failed we don't want
+     * to overwrite the dp member of a.
+     */
+    tmp = OPT_CAST(mp_digit) XREALLOC (a->dp, sizeof (mp_digit) * size);
+    if (tmp == NULL) {
+      /* reallocation failed but "a" is still valid [can be freed] */
+      return MP_MEM;
+    }
+
+    /* reallocation succeeded so set a->dp */
+    a->dp = tmp;
+
+    /* zero excess digits */
+    i        = a->alloc;
+    a->alloc = size;
+    for (; i < a->alloc; i++) {
+      a->dp[i] = 0;
+    }
+  }
+  return MP_OKAY;
+}
+#endif
diff --git a/libtommath/bn_mp_init.c b/libtommath/bn_mp_init.c
new file mode 100644
index 0000000..ddb2d07
--- /dev/null
+++ b/libtommath/bn_mp_init.c
@@ -0,0 +1,42 @@
+#include <tommath.h>
+#ifdef BN_MP_INIT_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* init a new mp_int */
+int mp_init (mp_int * a)
+{
+  int i;
+
+  /* allocate memory required and clear it */
+  a->dp = OPT_CAST(mp_digit) XMALLOC (sizeof (mp_digit) * MP_PREC);
+  if (a->dp == NULL) {
+    return MP_MEM;
+  }
+
+  /* set the digits to zero */
+  for (i = 0; i < MP_PREC; i++) {
+      a->dp[i] = 0;
+  }
+
+  /* set the used to zero, allocated digits to the default precision
+   * and sign to positive */
+  a->used  = 0;
+  a->alloc = MP_PREC;
+  a->sign  = MP_ZPOS;
+
+  return MP_OKAY;
+}
+#endif
diff --git a/libtommath/bn_mp_init_copy.c b/libtommath/bn_mp_init_copy.c
new file mode 100644
index 0000000..2410a9f
--- /dev/null
+++ b/libtommath/bn_mp_init_copy.c
@@ -0,0 +1,28 @@
+#include <tommath.h>
+#ifdef BN_MP_INIT_COPY_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* creates "a" then copies b into it */
+int mp_init_copy (mp_int * a, mp_int * b)
+{
+  int     res;
+
+  if ((res = mp_init (a)) != MP_OKAY) {
+    return res;
+  }
+  return mp_copy (b, a);
+}
+#endif
diff --git a/libtommath/bn_mp_init_multi.c b/libtommath/bn_mp_init_multi.c
new file mode 100644
index 0000000..44e3fe6
--- /dev/null
+++ b/libtommath/bn_mp_init_multi.c
@@ -0,0 +1,55 @@
+#include <tommath.h>
+#ifdef BN_MP_INIT_MULTI_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+#include <stdarg.h>
+
+int mp_init_multi(mp_int *mp, ...) 
+{
+    mp_err res = MP_OKAY;      /* Assume ok until proven otherwise */
+    int n = 0;                 /* Number of ok inits */
+    mp_int* cur_arg = mp;
+    va_list args;
+
+    va_start(args, mp);        /* init args to next argument from caller */
+    while (cur_arg != NULL) {
+        if (mp_init(cur_arg) != MP_OKAY) {
+            /* Oops - error! Back-track and mp_clear what we already
+               succeeded in init-ing, then return error.
+            */
+            va_list clean_args;
+            
+            /* end the current list */
+            va_end(args);
+            
+            /* now start cleaning up */            
+            cur_arg = mp;
+            va_start(clean_args, mp);
+            while (n--) {
+                mp_clear(cur_arg);
+                cur_arg = va_arg(clean_args, mp_int*);
+            }
+            va_end(clean_args);
+            res = MP_MEM;
+            break;
+        }
+        n++;
+        cur_arg = va_arg(args, mp_int*);
+    }
+    va_end(args);
+    return res;                /* Assumed ok, if error flagged above. */
+}
+
+#endif
diff --git a/libtommath/bn_mp_init_set.c b/libtommath/bn_mp_init_set.c
new file mode 100644
index 0000000..dc08867
--- /dev/null
+++ b/libtommath/bn_mp_init_set.c
@@ -0,0 +1,28 @@
+#include <tommath.h>
+#ifdef BN_MP_INIT_SET_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* initialize and set a digit */
+int mp_init_set (mp_int * a, mp_digit b)
+{
+  int err;
+  if ((err = mp_init(a)) != MP_OKAY) {
+     return err;
+  }
+  mp_set(a, b);
+  return err;
+}
+#endif
diff --git a/libtommath/bn_mp_init_set_int.c b/libtommath/bn_mp_init_set_int.c
new file mode 100644
index 0000000..56b27e0
--- /dev/null
+++ b/libtommath/bn_mp_init_set_int.c
@@ -0,0 +1,27 @@
+#include <tommath.h>
+#ifdef BN_MP_INIT_SET_INT_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* initialize and set a digit */
+int mp_init_set_int (mp_int * a, unsigned long b)
+{
+  int err;
+  if ((err = mp_init(a)) != MP_OKAY) {
+     return err;
+  }
+  return mp_set_int(a, b);
+}
+#endif
diff --git a/libtommath/bn_mp_init_size.c b/libtommath/bn_mp_init_size.c
new file mode 100644
index 0000000..8ed2c2a
--- /dev/null
+++ b/libtommath/bn_mp_init_size.c
@@ -0,0 +1,44 @@
+#include <tommath.h>
+#ifdef BN_MP_INIT_SIZE_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* init an mp_init for a given size */
+int mp_init_size (mp_int * a, int size)
+{
+  int x;
+
+  /* pad size so there are always extra digits */
+  size += (MP_PREC * 2) - (size % MP_PREC);	
+  
+  /* alloc mem */
+  a->dp = OPT_CAST(mp_digit) XMALLOC (sizeof (mp_digit) * size);
+  if (a->dp == NULL) {
+    return MP_MEM;
+  }
+
+  /* set the members */
+  a->used  = 0;
+  a->alloc = size;
+  a->sign  = MP_ZPOS;
+
+  /* zero the digits */
+  for (x = 0; x < size; x++) {
+      a->dp[x] = 0;
+  }
+
+  return MP_OKAY;
+}
+#endif
diff --git a/libtommath/bn_mp_invmod.c b/libtommath/bn_mp_invmod.c
new file mode 100644
index 0000000..fdb6c88
--- /dev/null
+++ b/libtommath/bn_mp_invmod.c
@@ -0,0 +1,39 @@
+#include <tommath.h>
+#ifdef BN_MP_INVMOD_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* hac 14.61, pp608 */
+int mp_invmod (mp_int * a, mp_int * b, mp_int * c)
+{
+  /* b cannot be negative */
+  if (b->sign == MP_NEG || mp_iszero(b) == 1) {
+    return MP_VAL;
+  }
+
+#ifdef BN_FAST_MP_INVMOD_C
+  /* if the modulus is odd we can use a faster routine instead */
+  if (mp_isodd (b) == 1) {
+    return fast_mp_invmod (a, b, c);
+  }
+#endif
+
+#ifdef BN_MP_INVMOD_SLOW_C
+  return mp_invmod_slow(a, b, c);
+#endif
+
+  return MP_VAL;
+}
+#endif
diff --git a/libtommath/bn_mp_invmod_slow.c b/libtommath/bn_mp_invmod_slow.c
new file mode 100644
index 0000000..e079819
--- /dev/null
+++ b/libtommath/bn_mp_invmod_slow.c
@@ -0,0 +1,171 @@
+#include <tommath.h>
+#ifdef BN_MP_INVMOD_SLOW_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* hac 14.61, pp608 */
+int mp_invmod_slow (mp_int * a, mp_int * b, mp_int * c)
+{
+  mp_int  x, y, u, v, A, B, C, D;
+  int     res;
+
+  /* b cannot be negative */
+  if (b->sign == MP_NEG || mp_iszero(b) == 1) {
+    return MP_VAL;
+  }
+
+  /* init temps */
+  if ((res = mp_init_multi(&x, &y, &u, &v, 
+                           &A, &B, &C, &D, NULL)) != MP_OKAY) {
+     return res;
+  }
+
+  /* x = a, y = b */
+  if ((res = mp_mod(a, b, &x)) != MP_OKAY) {
+      goto LBL_ERR;
+  }
+  if ((res = mp_copy (b, &y)) != MP_OKAY) {
+    goto LBL_ERR;
+  }
+
+  /* 2. [modified] if x,y are both even then return an error! */
+  if (mp_iseven (&x) == 1 && mp_iseven (&y) == 1) {
+    res = MP_VAL;
+    goto LBL_ERR;
+  }
+
+  /* 3. u=x, v=y, A=1, B=0, C=0,D=1 */
+  if ((res = mp_copy (&x, &u)) != MP_OKAY) {
+    goto LBL_ERR;
+  }
+  if ((res = mp_copy (&y, &v)) != MP_OKAY) {
+    goto LBL_ERR;
+  }
+  mp_set (&A, 1);
+  mp_set (&D, 1);
+
+top:
+  /* 4.  while u is even do */
+  while (mp_iseven (&u) == 1) {
+    /* 4.1 u = u/2 */
+    if ((res = mp_div_2 (&u, &u)) != MP_OKAY) {
+      goto LBL_ERR;
+    }
+    /* 4.2 if A or B is odd then */
+    if (mp_isodd (&A) == 1 || mp_isodd (&B) == 1) {
+      /* A = (A+y)/2, B = (B-x)/2 */
+      if ((res = mp_add (&A, &y, &A)) != MP_OKAY) {
+         goto LBL_ERR;
+      }
+      if ((res = mp_sub (&B, &x, &B)) != MP_OKAY) {
+         goto LBL_ERR;
+      }
+    }
+    /* A = A/2, B = B/2 */
+    if ((res = mp_div_2 (&A, &A)) != MP_OKAY) {
+      goto LBL_ERR;
+    }
+    if ((res = mp_div_2 (&B, &B)) != MP_OKAY) {
+      goto LBL_ERR;
+    }
+  }
+
+  /* 5.  while v is even do */
+  while (mp_iseven (&v) == 1) {
+    /* 5.1 v = v/2 */
+    if ((res = mp_div_2 (&v, &v)) != MP_OKAY) {
+      goto LBL_ERR;
+    }
+    /* 5.2 if C or D is odd then */
+    if (mp_isodd (&C) == 1 || mp_isodd (&D) == 1) {
+      /* C = (C+y)/2, D = (D-x)/2 */
+      if ((res = mp_add (&C, &y, &C)) != MP_OKAY) {
+         goto LBL_ERR;
+      }
+      if ((res = mp_sub (&D, &x, &D)) != MP_OKAY) {
+         goto LBL_ERR;
+      }
+    }
+    /* C = C/2, D = D/2 */
+    if ((res = mp_div_2 (&C, &C)) != MP_OKAY) {
+      goto LBL_ERR;
+    }
+    if ((res = mp_div_2 (&D, &D)) != MP_OKAY) {
+      goto LBL_ERR;
+    }
+  }
+
+  /* 6.  if u >= v then */
+  if (mp_cmp (&u, &v) != MP_LT) {
+    /* u = u - v, A = A - C, B = B - D */
+    if ((res = mp_sub (&u, &v, &u)) != MP_OKAY) {
+      goto LBL_ERR;
+    }
+
+    if ((res = mp_sub (&A, &C, &A)) != MP_OKAY) {
+      goto LBL_ERR;
+    }
+
+    if ((res = mp_sub (&B, &D, &B)) != MP_OKAY) {
+      goto LBL_ERR;
+    }
+  } else {
+    /* v - v - u, C = C - A, D = D - B */
+    if ((res = mp_sub (&v, &u, &v)) != MP_OKAY) {
+      goto LBL_ERR;
+    }
+
+    if ((res = mp_sub (&C, &A, &C)) != MP_OKAY) {
+      goto LBL_ERR;
+    }
+
+    if ((res = mp_sub (&D, &B, &D)) != MP_OKAY) {
+      goto LBL_ERR;
+    }
+  }
+
+  /* if not zero goto step 4 */
+  if (mp_iszero (&u) == 0)
+    goto top;
+
+  /* now a = C, b = D, gcd == g*v */
+
+  /* if v != 1 then there is no inverse */
+  if (mp_cmp_d (&v, 1) != MP_EQ) {
+    res = MP_VAL;
+    goto LBL_ERR;
+  }
+
+  /* if its too low */
+  while (mp_cmp_d(&C, 0) == MP_LT) {
+      if ((res = mp_add(&C, b, &C)) != MP_OKAY) {
+         goto LBL_ERR;
+      }
+  }
+  
+  /* too big */
+  while (mp_cmp_mag(&C, b) != MP_LT) {
+      if ((res = mp_sub(&C, b, &C)) != MP_OKAY) {
+         goto LBL_ERR;
+      }
+  }
+  
+  /* C is now the inverse */
+  mp_exch (&C, c);
+  res = MP_OKAY;
+LBL_ERR:mp_clear_multi (&x, &y, &u, &v, &A, &B, &C, &D, NULL);
+  return res;
+}
+#endif
diff --git a/libtommath/bn_mp_is_square.c b/libtommath/bn_mp_is_square.c
new file mode 100644
index 0000000..926b449
--- /dev/null
+++ b/libtommath/bn_mp_is_square.c
@@ -0,0 +1,105 @@
+#include <tommath.h>
+#ifdef BN_MP_IS_SQUARE_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* Check if remainders are possible squares - fast exclude non-squares */
+static const char rem_128[128] = {
+ 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
+ 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
+ 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
+ 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
+ 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
+ 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
+ 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
+ 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1
+};
+
+static const char rem_105[105] = {
+ 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1,
+ 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1,
+ 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1,
+ 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1,
+ 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1,
+ 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1,
+ 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1
+};
+
+/* Store non-zero to ret if arg is square, and zero if not */
+int mp_is_square(mp_int *arg,int *ret) 
+{
+  int           res;
+  mp_digit      c;
+  mp_int        t;
+  unsigned long r;
+
+  /* Default to Non-square :) */
+  *ret = MP_NO; 
+
+  if (arg->sign == MP_NEG) {
+    return MP_VAL;
+  }
+
+  /* digits used?  (TSD) */
+  if (arg->used == 0) {
+     return MP_OKAY;
+  }
+
+  /* First check mod 128 (suppose that DIGIT_BIT is at least 7) */
+  if (rem_128[127 & DIGIT(arg,0)] == 1) {
+     return MP_OKAY;
+  }
+
+  /* Next check mod 105 (3*5*7) */
+  if ((res = mp_mod_d(arg,105,&c)) != MP_OKAY) {
+     return res;
+  }
+  if (rem_105[c] == 1) {
+     return MP_OKAY;
+  }
+
+
+  if ((res = mp_init_set_int(&t,11L*13L*17L*19L*23L*29L*31L)) != MP_OKAY) {
+     return res;
+  }
+  if ((res = mp_mod(arg,&t,&t)) != MP_OKAY) {
+     goto ERR;
+  }
+  r = mp_get_int(&t);
+  /* Check for other prime modules, note it's not an ERROR but we must
+   * free "t" so the easiest way is to goto ERR.  We know that res
+   * is already equal to MP_OKAY from the mp_mod call 
+   */ 
+  if ( (1L<<(r%11)) & 0x5C4L )             goto ERR;
+  if ( (1L<<(r%13)) & 0x9E4L )             goto ERR;
+  if ( (1L<<(r%17)) & 0x5CE8L )            goto ERR;
+  if ( (1L<<(r%19)) & 0x4F50CL )           goto ERR;
+  if ( (1L<<(r%23)) & 0x7ACCA0L )          goto ERR;
+  if ( (1L<<(r%29)) & 0xC2EDD0CL )         goto ERR;
+  if ( (1L<<(r%31)) & 0x6DE2B848L )        goto ERR;
+
+  /* Final check - is sqr(sqrt(arg)) == arg ? */
+  if ((res = mp_sqrt(arg,&t)) != MP_OKAY) {
+     goto ERR;
+  }
+  if ((res = mp_sqr(&t,&t)) != MP_OKAY) {
+     goto ERR;
+  }
+
+  *ret = (mp_cmp_mag(&t,arg) == MP_EQ) ? MP_YES : MP_NO;
+ERR:mp_clear(&t);
+  return res;
+}
+#endif
diff --git a/libtommath/bn_mp_jacobi.c b/libtommath/bn_mp_jacobi.c
new file mode 100644
index 0000000..1644698
--- /dev/null
+++ b/libtommath/bn_mp_jacobi.c
@@ -0,0 +1,101 @@
+#include <tommath.h>
+#ifdef BN_MP_JACOBI_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* computes the jacobi c = (a | n) (or Legendre if n is prime)
+ * HAC pp. 73 Algorithm 2.149
+ */
+int mp_jacobi (mp_int * a, mp_int * p, int *c)
+{
+  mp_int  a1, p1;
+  int     k, s, r, res;
+  mp_digit residue;
+
+  /* if p <= 0 return MP_VAL */
+  if (mp_cmp_d(p, 0) != MP_GT) {
+     return MP_VAL;
+  }
+
+  /* step 1.  if a == 0, return 0 */
+  if (mp_iszero (a) == 1) {
+    *c = 0;
+    return MP_OKAY;
+  }
+
+  /* step 2.  if a == 1, return 1 */
+  if (mp_cmp_d (a, 1) == MP_EQ) {
+    *c = 1;
+    return MP_OKAY;
+  }
+
+  /* default */
+  s = 0;
+
+  /* step 3.  write a = a1 * 2**k  */
+  if ((res = mp_init_copy (&a1, a)) != MP_OKAY) {
+    return res;
+  }
+
+  if ((res = mp_init (&p1)) != MP_OKAY) {
+    goto LBL_A1;
+  }
+
+  /* divide out larger power of two */
+  k = mp_cnt_lsb(&a1);
+  if ((res = mp_div_2d(&a1, k, &a1, NULL)) != MP_OKAY) {
+     goto LBL_P1;
+  }
+
+  /* step 4.  if e is even set s=1 */
+  if ((k & 1) == 0) {
+    s = 1;
+  } else {
+    /* else set s=1 if p = 1/7 (mod 8) or s=-1 if p = 3/5 (mod 8) */
+    residue = p->dp[0] & 7;
+
+    if (residue == 1 || residue == 7) {
+      s = 1;
+    } else if (residue == 3 || residue == 5) {
+      s = -1;
+    }
+  }
+
+  /* step 5.  if p == 3 (mod 4) *and* a1 == 3 (mod 4) then s = -s */
+  if ( ((p->dp[0] & 3) == 3) && ((a1.dp[0] & 3) == 3)) {
+    s = -s;
+  }
+
+  /* if a1 == 1 we're done */
+  if (mp_cmp_d (&a1, 1) == MP_EQ) {
+    *c = s;
+  } else {
+    /* n1 = n mod a1 */
+    if ((res = mp_mod (p, &a1, &p1)) != MP_OKAY) {
+      goto LBL_P1;
+    }
+    if ((res = mp_jacobi (&p1, &a1, &r)) != MP_OKAY) {
+      goto LBL_P1;
+    }
+    *c = s * r;
+  }
+
+  /* done */
+  res = MP_OKAY;
+LBL_P1:mp_clear (&p1);
+LBL_A1:mp_clear (&a1);
+  return res;
+}
+#endif
diff --git a/libtommath/bn_mp_karatsuba_mul.c b/libtommath/bn_mp_karatsuba_mul.c
new file mode 100644
index 0000000..0d62b9b
--- /dev/null
+++ b/libtommath/bn_mp_karatsuba_mul.c
@@ -0,0 +1,163 @@
+#include <tommath.h>
+#ifdef BN_MP_KARATSUBA_MUL_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* c = |a| * |b| using Karatsuba Multiplication using 
+ * three half size multiplications
+ *
+ * Let B represent the radix [e.g. 2**DIGIT_BIT] and 
+ * let n represent half of the number of digits in 
+ * the min(a,b)
+ *
+ * a = a1 * B**n + a0
+ * b = b1 * B**n + b0
+ *
+ * Then, a * b => 
+   a1b1 * B**2n + ((a1 + a0)(b1 + b0) - (a0b0 + a1b1)) * B + a0b0
+ *
+ * Note that a1b1 and a0b0 are used twice and only need to be 
+ * computed once.  So in total three half size (half # of 
+ * digit) multiplications are performed, a0b0, a1b1 and 
+ * (a1+b1)(a0+b0)
+ *
+ * Note that a multiplication of half the digits requires
+ * 1/4th the number of single precision multiplications so in 
+ * total after one call 25% of the single precision multiplications 
+ * are saved.  Note also that the call to mp_mul can end up back 
+ * in this function if the a0, a1, b0, or b1 are above the threshold.  
+ * This is known as divide-and-conquer and leads to the famous 
+ * O(N**lg(3)) or O(N**1.584) work which is asymptopically lower than 
+ * the standard O(N**2) that the baseline/comba methods use.  
+ * Generally though the overhead of this method doesn't pay off 
+ * until a certain size (N ~ 80) is reached.
+ */
+int mp_karatsuba_mul (mp_int * a, mp_int * b, mp_int * c)
+{
+  mp_int  x0, x1, y0, y1, t1, x0y0, x1y1;
+  int     B, err;
+
+  /* default the return code to an error */
+  err = MP_MEM;
+
+  /* min # of digits */
+  B = MIN (a->used, b->used);
+
+  /* now divide in two */
+  B = B >> 1;
+
+  /* init copy all the temps */
+  if (mp_init_size (&x0, B) != MP_OKAY)
+    goto ERR;
+  if (mp_init_size (&x1, a->used - B) != MP_OKAY)
+    goto X0;
+  if (mp_init_size (&y0, B) != MP_OKAY)
+    goto X1;
+  if (mp_init_size (&y1, b->used - B) != MP_OKAY)
+    goto Y0;
+
+  /* init temps */
+  if (mp_init_size (&t1, B * 2) != MP_OKAY)
+    goto Y1;
+  if (mp_init_size (&x0y0, B * 2) != MP_OKAY)
+    goto T1;
+  if (mp_init_size (&x1y1, B * 2) != MP_OKAY)
+    goto X0Y0;
+
+  /* now shift the digits */
+  x0.used = y0.used = B;
+  x1.used = a->used - B;
+  y1.used = b->used - B;
+
+  {
+    register int x;
+    register mp_digit *tmpa, *tmpb, *tmpx, *tmpy;
+
+    /* we copy the digits directly instead of using higher level functions
+     * since we also need to shift the digits
+     */
+    tmpa = a->dp;
+    tmpb = b->dp;
+
+    tmpx = x0.dp;
+    tmpy = y0.dp;
+    for (x = 0; x < B; x++) {
+      *tmpx++ = *tmpa++;
+      *tmpy++ = *tmpb++;
+    }
+
+    tmpx = x1.dp;
+    for (x = B; x < a->used; x++) {
+      *tmpx++ = *tmpa++;
+    }
+
+    tmpy = y1.dp;
+    for (x = B; x < b->used; x++) {
+      *tmpy++ = *tmpb++;
+    }
+  }
+
+  /* only need to clamp the lower words since by definition the 
+   * upper words x1/y1 must have a known number of digits
+   */
+  mp_clamp (&x0);
+  mp_clamp (&y0);
+
+  /* now calc the products x0y0 and x1y1 */
+  /* after this x0 is no longer required, free temp [x0==t2]! */
+  if (mp_mul (&x0, &y0, &x0y0) != MP_OKAY)  
+    goto X1Y1;          /* x0y0 = x0*y0 */
+  if (mp_mul (&x1, &y1, &x1y1) != MP_OKAY)
+    goto X1Y1;          /* x1y1 = x1*y1 */
+
+  /* now calc x1+x0 and y1+y0 */
+  if (s_mp_add (&x1, &x0, &t1) != MP_OKAY)
+    goto X1Y1;          /* t1 = x1 - x0 */
+  if (s_mp_add (&y1, &y0, &x0) != MP_OKAY)
+    goto X1Y1;          /* t2 = y1 - y0 */
+  if (mp_mul (&t1, &x0, &t1) != MP_OKAY)
+    goto X1Y1;          /* t1 = (x1 + x0) * (y1 + y0) */
+
+  /* add x0y0 */
+  if (mp_add (&x0y0, &x1y1, &x0) != MP_OKAY)
+    goto X1Y1;          /* t2 = x0y0 + x1y1 */
+  if (s_mp_sub (&t1, &x0, &t1) != MP_OKAY)
+    goto X1Y1;          /* t1 = (x1+x0)*(y1+y0) - (x1y1 + x0y0) */
+
+  /* shift by B */
+  if (mp_lshd (&t1, B) != MP_OKAY)
+    goto X1Y1;          /* t1 = (x0y0 + x1y1 - (x1-x0)*(y1-y0))<<B */
+  if (mp_lshd (&x1y1, B * 2) != MP_OKAY)
+    goto X1Y1;          /* x1y1 = x1y1 << 2*B */
+
+  if (mp_add (&x0y0, &t1, &t1) != MP_OKAY)
+    goto X1Y1;          /* t1 = x0y0 + t1 */
+  if (mp_add (&t1, &x1y1, c) != MP_OKAY)
+    goto X1Y1;          /* t1 = x0y0 + t1 + x1y1 */
+
+  /* Algorithm succeeded set the return code to MP_OKAY */
+  err = MP_OKAY;
+
+X1Y1:mp_clear (&x1y1);
+X0Y0:mp_clear (&x0y0);
+T1:mp_clear (&t1);
+Y1:mp_clear (&y1);
+Y0:mp_clear (&y0);
+X1:mp_clear (&x1);
+X0:mp_clear (&x0);
+ERR:
+  return err;
+}
+#endif
diff --git a/libtommath/bn_mp_karatsuba_sqr.c b/libtommath/bn_mp_karatsuba_sqr.c
new file mode 100644
index 0000000..829405a
--- /dev/null
+++ b/libtommath/bn_mp_karatsuba_sqr.c
@@ -0,0 +1,117 @@
+#include <tommath.h>
+#ifdef BN_MP_KARATSUBA_SQR_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* Karatsuba squaring, computes b = a*a using three 
+ * half size squarings
+ *
+ * See comments of karatsuba_mul for details.  It 
+ * is essentially the same algorithm but merely 
+ * tuned to perform recursive squarings.
+ */
+int mp_karatsuba_sqr (mp_int * a, mp_int * b)
+{
+  mp_int  x0, x1, t1, t2, x0x0, x1x1;
+  int     B, err;
+
+  err = MP_MEM;
+
+  /* min # of digits */
+  B = a->used;
+
+  /* now divide in two */
+  B = B >> 1;
+
+  /* init copy all the temps */
+  if (mp_init_size (&x0, B) != MP_OKAY)
+    goto ERR;
+  if (mp_init_size (&x1, a->used - B) != MP_OKAY)
+    goto X0;
+
+  /* init temps */
+  if (mp_init_size (&t1, a->used * 2) != MP_OKAY)
+    goto X1;
+  if (mp_init_size (&t2, a->used * 2) != MP_OKAY)
+    goto T1;
+  if (mp_init_size (&x0x0, B * 2) != MP_OKAY)
+    goto T2;
+  if (mp_init_size (&x1x1, (a->used - B) * 2) != MP_OKAY)
+    goto X0X0;
+
+  {
+    register int x;
+    register mp_digit *dst, *src;
+
+    src = a->dp;
+
+    /* now shift the digits */
+    dst = x0.dp;
+    for (x = 0; x < B; x++) {
+      *dst++ = *src++;
+    }
+
+    dst = x1.dp;
+    for (x = B; x < a->used; x++) {
+      *dst++ = *src++;
+    }
+  }
+
+  x0.used = B;
+  x1.used = a->used - B;
+
+  mp_clamp (&x0);
+
+  /* now calc the products x0*x0 and x1*x1 */
+  if (mp_sqr (&x0, &x0x0) != MP_OKAY)
+    goto X1X1;           /* x0x0 = x0*x0 */
+  if (mp_sqr (&x1, &x1x1) != MP_OKAY)
+    goto X1X1;           /* x1x1 = x1*x1 */
+
+  /* now calc (x1+x0)**2 */
+  if (s_mp_add (&x1, &x0, &t1) != MP_OKAY)
+    goto X1X1;           /* t1 = x1 - x0 */
+  if (mp_sqr (&t1, &t1) != MP_OKAY)
+    goto X1X1;           /* t1 = (x1 - x0) * (x1 - x0) */
+
+  /* add x0y0 */
+  if (s_mp_add (&x0x0, &x1x1, &t2) != MP_OKAY)
+    goto X1X1;           /* t2 = x0x0 + x1x1 */
+  if (s_mp_sub (&t1, &t2, &t1) != MP_OKAY)
+    goto X1X1;           /* t1 = (x1+x0)**2 - (x0x0 + x1x1) */
+
+  /* shift by B */
+  if (mp_lshd (&t1, B) != MP_OKAY)
+    goto X1X1;           /* t1 = (x0x0 + x1x1 - (x1-x0)*(x1-x0))<<B */
+  if (mp_lshd (&x1x1, B * 2) != MP_OKAY)
+    goto X1X1;           /* x1x1 = x1x1 << 2*B */
+
+  if (mp_add (&x0x0, &t1, &t1) != MP_OKAY)
+    goto X1X1;           /* t1 = x0x0 + t1 */
+  if (mp_add (&t1, &x1x1, b) != MP_OKAY)
+    goto X1X1;           /* t1 = x0x0 + t1 + x1x1 */
+
+  err = MP_OKAY;
+
+X1X1:mp_clear (&x1x1);
+X0X0:mp_clear (&x0x0);
+T2:mp_clear (&t2);
+T1:mp_clear (&t1);
+X1:mp_clear (&x1);
+X0:mp_clear (&x0);
+ERR:
+  return err;
+}
+#endif
diff --git a/libtommath/bn_mp_lcm.c b/libtommath/bn_mp_lcm.c
new file mode 100644
index 0000000..1d53921
--- /dev/null
+++ b/libtommath/bn_mp_lcm.c
@@ -0,0 +1,56 @@
+#include <tommath.h>
+#ifdef BN_MP_LCM_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* computes least common multiple as |a*b|/(a, b) */
+int mp_lcm (mp_int * a, mp_int * b, mp_int * c)
+{
+  int     res;
+  mp_int  t1, t2;
+
+
+  if ((res = mp_init_multi (&t1, &t2, NULL)) != MP_OKAY) {
+    return res;
+  }
+
+  /* t1 = get the GCD of the two inputs */
+  if ((res = mp_gcd (a, b, &t1)) != MP_OKAY) {
+    goto LBL_T;
+  }
+
+  /* divide the smallest by the GCD */
+  if (mp_cmp_mag(a, b) == MP_LT) {
+     /* store quotient in t2 such that t2 * b is the LCM */
+     if ((res = mp_div(a, &t1, &t2, NULL)) != MP_OKAY) {
+        goto LBL_T;
+     }
+     res = mp_mul(b, &t2, c);
+  } else {
+     /* store quotient in t2 such that t2 * a is the LCM */
+     if ((res = mp_div(b, &t1, &t2, NULL)) != MP_OKAY) {
+        goto LBL_T;
+     }
+     res = mp_mul(a, &t2, c);
+  }
+
+  /* fix the sign to positive */
+  c->sign = MP_ZPOS;
+
+LBL_T:
+  mp_clear_multi (&t1, &t2, NULL);
+  return res;
+}
+#endif
diff --git a/libtommath/bn_mp_lshd.c b/libtommath/bn_mp_lshd.c
new file mode 100644
index 0000000..ce1e63b
--- /dev/null
+++ b/libtommath/bn_mp_lshd.c
@@ -0,0 +1,63 @@
+#include <tommath.h>
+#ifdef BN_MP_LSHD_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* shift left a certain amount of digits */
+int mp_lshd (mp_int * a, int b)
+{
+  int     x, res;
+
+  /* if its less than zero return */
+  if (b <= 0) {
+    return MP_OKAY;
+  }
+
+  /* grow to fit the new digits */
+  if (a->alloc < a->used + b) {
+     if ((res = mp_grow (a, a->used + b)) != MP_OKAY) {
+       return res;
+     }
+  }
+
+  {
+    register mp_digit *top, *bottom;
+
+    /* increment the used by the shift amount then copy upwards */
+    a->used += b;
+
+    /* top */
+    top = a->dp + a->used - 1;
+
+    /* base */
+    bottom = a->dp + a->used - 1 - b;
+
+    /* much like mp_rshd this is implemented using a sliding window
+     * except the window goes the otherway around.  Copying from
+     * the bottom to the top.  see bn_mp_rshd.c for more info.
+     */
+    for (x = a->used - 1; x >= b; x--) {
+      *top-- = *bottom--;
+    }
+
+    /* zero the lower digits */
+    top = a->dp;
+    for (x = 0; x < b; x++) {
+      *top++ = 0;
+    }
+  }
+  return MP_OKAY;
+}
+#endif
diff --git a/libtommath/bn_mp_mod.c b/libtommath/bn_mp_mod.c
new file mode 100644
index 0000000..98e155e
--- /dev/null
+++ b/libtommath/bn_mp_mod.c
@@ -0,0 +1,44 @@
+#include <tommath.h>
+#ifdef BN_MP_MOD_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* c = a mod b, 0 <= c < b */
+int
+mp_mod (mp_int * a, mp_int * b, mp_int * c)
+{
+  mp_int  t;
+  int     res;
+
+  if ((res = mp_init (&t)) != MP_OKAY) {
+    return res;
+  }
+
+  if ((res = mp_div (a, b, NULL, &t)) != MP_OKAY) {
+    mp_clear (&t);
+    return res;
+  }
+
+  if (t.sign != b->sign) {
+    res = mp_add (b, &t, c);
+  } else {
+    res = MP_OKAY;
+    mp_exch (&t, c);
+  }
+
+  mp_clear (&t);
+  return res;
+}
+#endif
diff --git a/libtommath/bn_mp_mod_2d.c b/libtommath/bn_mp_mod_2d.c
new file mode 100644
index 0000000..0170f65
--- /dev/null
+++ b/libtommath/bn_mp_mod_2d.c
@@ -0,0 +1,51 @@
+#include <tommath.h>
+#ifdef BN_MP_MOD_2D_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* calc a value mod 2**b */
+int
+mp_mod_2d (const mp_int * a, int b, mp_int * c)
+{
+  int     x, res;
+
+  /* if b is <= 0 then zero the int */
+  if (b <= 0) {
+    mp_zero (c);
+    return MP_OKAY;
+  }
+
+  /* if the modulus is larger than the value than return */
+  if (b >= (int) (a->used * DIGIT_BIT)) {
+    res = mp_copy (a, c);
+    return res;
+  }
+
+  /* copy */
+  if ((res = mp_copy (a, c)) != MP_OKAY) {
+    return res;
+  }
+
+  /* zero digits above the last digit of the modulus */
+  for (x = (b / DIGIT_BIT) + ((b % DIGIT_BIT) == 0 ? 0 : 1); x < c->used; x++) {
+    c->dp[x] = 0;
+  }
+  /* clear the digit that is not completely outside/inside the modulus */
+  c->dp[b / DIGIT_BIT] &=
+    (mp_digit) ((((mp_digit) 1) << (((mp_digit) b) % DIGIT_BIT)) - ((mp_digit) 1));
+  mp_clamp (c);
+  return MP_OKAY;
+}
+#endif
diff --git a/libtommath/bn_mp_mod_d.c b/libtommath/bn_mp_mod_d.c
new file mode 100644
index 0000000..f642ee8
--- /dev/null
+++ b/libtommath/bn_mp_mod_d.c
@@ -0,0 +1,23 @@
+#include <tommath.h>
+#ifdef BN_MP_MOD_D_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+int
+mp_mod_d (mp_int * a, mp_digit b, mp_digit * c)
+{
+  return mp_div_d(a, b, NULL, c);
+}
+#endif
diff --git a/libtommath/bn_mp_montgomery_calc_normalization.c b/libtommath/bn_mp_montgomery_calc_normalization.c
new file mode 100644
index 0000000..0748762
--- /dev/null
+++ b/libtommath/bn_mp_montgomery_calc_normalization.c
@@ -0,0 +1,55 @@
+#include <tommath.h>
+#ifdef BN_MP_MONTGOMERY_CALC_NORMALIZATION_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/*
+ * shifts with subtractions when the result is greater than b.
+ *
+ * The method is slightly modified to shift B unconditionally upto just under
+ * the leading bit of b.  This saves alot of multiple precision shifting.
+ */
+int mp_montgomery_calc_normalization (mp_int * a, mp_int * b)
+{
+  int     x, bits, res;
+
+  /* how many bits of last digit does b use */
+  bits = mp_count_bits (b) % DIGIT_BIT;
+
+  if (b->used > 1) {
+     if ((res = mp_2expt (a, (b->used - 1) * DIGIT_BIT + bits - 1)) != MP_OKAY) {
+        return res;
+     }
+  } else {
+     mp_set(a, 1);
+     bits = 1;
+  }
+
+
+  /* now compute C = A * B mod b */
+  for (x = bits - 1; x < (int)DIGIT_BIT; x++) {
+    if ((res = mp_mul_2 (a, a)) != MP_OKAY) {
+      return res;
+    }
+    if (mp_cmp_mag (a, b) != MP_LT) {
+      if ((res = s_mp_sub (a, b, a)) != MP_OKAY) {
+        return res;
+      }
+    }
+  }
+
+  return MP_OKAY;
+}
+#endif
diff --git a/libtommath/bn_mp_montgomery_reduce.c b/libtommath/bn_mp_montgomery_reduce.c
new file mode 100644
index 0000000..bc6abb8
--- /dev/null
+++ b/libtommath/bn_mp_montgomery_reduce.c
@@ -0,0 +1,114 @@
+#include <tommath.h>
+#ifdef BN_MP_MONTGOMERY_REDUCE_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* computes xR**-1 == x (mod N) via Montgomery Reduction */
+int
+mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho)
+{
+  int     ix, res, digs;
+  mp_digit mu;
+
+  /* can the fast reduction [comba] method be used?
+   *
+   * Note that unlike in mul you're safely allowed *less*
+   * than the available columns [255 per default] since carries
+   * are fixed up in the inner loop.
+   */
+  digs = n->used * 2 + 1;
+  if ((digs < MP_WARRAY) &&
+      n->used <
+      (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) {
+    return fast_mp_montgomery_reduce (x, n, rho);
+  }
+
+  /* grow the input as required */
+  if (x->alloc < digs) {
+    if ((res = mp_grow (x, digs)) != MP_OKAY) {
+      return res;
+    }
+  }
+  x->used = digs;
+
+  for (ix = 0; ix < n->used; ix++) {
+    /* mu = ai * rho mod b
+     *
+     * The value of rho must be precalculated via
+     * montgomery_setup() such that
+     * it equals -1/n0 mod b this allows the
+     * following inner loop to reduce the
+     * input one digit at a time
+     */
+    mu = (mp_digit) (((mp_word)x->dp[ix]) * ((mp_word)rho) & MP_MASK);
+
+    /* a = a + mu * m * b**i */
+    {
+      register int iy;
+      register mp_digit *tmpn, *tmpx, u;
+      register mp_word r;
+
+      /* alias for digits of the modulus */
+      tmpn = n->dp;
+
+      /* alias for the digits of x [the input] */
+      tmpx = x->dp + ix;
+
+      /* set the carry to zero */
+      u = 0;
+
+      /* Multiply and add in place */
+      for (iy = 0; iy < n->used; iy++) {
+        /* compute product and sum */
+        r       = ((mp_word)mu) * ((mp_word)*tmpn++) +
+                  ((mp_word) u) + ((mp_word) * tmpx);
+
+        /* get carry */
+        u       = (mp_digit)(r >> ((mp_word) DIGIT_BIT));
+
+        /* fix digit */
+        *tmpx++ = (mp_digit)(r & ((mp_word) MP_MASK));
+      }
+      /* At this point the ix'th digit of x should be zero */
+
+
+      /* propagate carries upwards as required*/
+      while (u) {
+        *tmpx   += u;
+        u        = *tmpx >> DIGIT_BIT;
+        *tmpx++ &= MP_MASK;
+      }
+    }
+  }
+
+  /* at this point the n.used'th least
+   * significant digits of x are all zero
+   * which means we can shift x to the
+   * right by n.used digits and the
+   * residue is unchanged.
+   */
+
+  /* x = x/b**n.used */
+  mp_clamp(x);
+  mp_rshd (x, n->used);
+
+  /* if x >= n then x = x - n */
+  if (mp_cmp_mag (x, n) != MP_LT) {
+    return s_mp_sub (x, n, x);
+  }
+
+  return MP_OKAY;
+}
+#endif
diff --git a/libtommath/bn_mp_montgomery_setup.c b/libtommath/bn_mp_montgomery_setup.c
new file mode 100644
index 0000000..b8e1887
--- /dev/null
+++ b/libtommath/bn_mp_montgomery_setup.c
@@ -0,0 +1,55 @@
+#include <tommath.h>
+#ifdef BN_MP_MONTGOMERY_SETUP_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* setups the montgomery reduction stuff */
+int
+mp_montgomery_setup (mp_int * n, mp_digit * rho)
+{
+  mp_digit x, b;
+
+/* fast inversion mod 2**k
+ *
+ * Based on the fact that
+ *
+ * XA = 1 (mod 2**n)  =>  (X(2-XA)) A = 1 (mod 2**2n)
+ *                    =>  2*X*A - X*X*A*A = 1
+ *                    =>  2*(1) - (1)     = 1
+ */
+  b = n->dp[0];
+
+  if ((b & 1) == 0) {
+    return MP_VAL;
+  }
+
+  x = (((b + 2) & 4) << 1) + b; /* here x*a==1 mod 2**4 */
+  x *= 2 - b * x;               /* here x*a==1 mod 2**8 */
+#if !defined(MP_8BIT)
+  x *= 2 - b * x;               /* here x*a==1 mod 2**16 */
+#endif
+#if defined(MP_64BIT) || !(defined(MP_8BIT) || defined(MP_16BIT))
+  x *= 2 - b * x;               /* here x*a==1 mod 2**32 */
+#endif
+#ifdef MP_64BIT
+  x *= 2 - b * x;               /* here x*a==1 mod 2**64 */
+#endif
+
+  /* rho = -1/m mod b */
+  *rho = (unsigned long)(((mp_word)1 << ((mp_word) DIGIT_BIT)) - x) & MP_MASK;
+
+  return MP_OKAY;
+}
+#endif
diff --git a/libtommath/bn_mp_mul.c b/libtommath/bn_mp_mul.c
new file mode 100644
index 0000000..fc024be
--- /dev/null
+++ b/libtommath/bn_mp_mul.c
@@ -0,0 +1,62 @@
+#include <tommath.h>
+#ifdef BN_MP_MUL_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* high level multiplication (handles sign) */
+int mp_mul (mp_int * a, mp_int * b, mp_int * c)
+{
+  int     res, neg;
+  neg = (a->sign == b->sign) ? MP_ZPOS : MP_NEG;
+
+  /* use Toom-Cook? */
+#ifdef BN_MP_TOOM_MUL_C
+  if (MIN (a->used, b->used) >= TOOM_MUL_CUTOFF) {
+    res = mp_toom_mul(a, b, c);
+  } else 
+#endif
+#ifdef BN_MP_KARATSUBA_MUL_C
+  /* use Karatsuba? */
+  if (MIN (a->used, b->used) >= KARATSUBA_MUL_CUTOFF) {
+    res = mp_karatsuba_mul (a, b, c);
+  } else 
+#endif
+  {
+    /* can we use the fast multiplier?
+     *
+     * The fast multiplier can be used if the output will 
+     * have less than MP_WARRAY digits and the number of 
+     * digits won't affect carry propagation
+     */
+    int     digs = a->used + b->used + 1;
+
+#ifdef BN_FAST_S_MP_MUL_DIGS_C
+    if ((digs < MP_WARRAY) &&
+        MIN(a->used, b->used) <= 
+        (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) {
+      res = fast_s_mp_mul_digs (a, b, c, digs);
+    } else 
+#endif
+#ifdef BN_S_MP_MUL_DIGS_C
+      res = s_mp_mul (a, b, c); /* uses s_mp_mul_digs */
+#else
+      res = MP_VAL;
+#endif
+
+  }
+  c->sign = (c->used > 0) ? neg : MP_ZPOS;
+  return res;
+}
+#endif
diff --git a/libtommath/bn_mp_mul_2.c b/libtommath/bn_mp_mul_2.c
new file mode 100644
index 0000000..2ca6022
--- /dev/null
+++ b/libtommath/bn_mp_mul_2.c
@@ -0,0 +1,78 @@
+#include <tommath.h>
+#ifdef BN_MP_MUL_2_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* b = a*2 */
+int mp_mul_2(mp_int * a, mp_int * b)
+{
+  int     x, res, oldused;
+
+  /* grow to accomodate result */
+  if (b->alloc < a->used + 1) {
+    if ((res = mp_grow (b, a->used + 1)) != MP_OKAY) {
+      return res;
+    }
+  }
+
+  oldused = b->used;
+  b->used = a->used;
+
+  {
+    register mp_digit r, rr, *tmpa, *tmpb;
+
+    /* alias for source */
+    tmpa = a->dp;
+    
+    /* alias for dest */
+    tmpb = b->dp;
+
+    /* carry */
+    r = 0;
+    for (x = 0; x < a->used; x++) {
+    
+      /* get what will be the *next* carry bit from the 
+       * MSB of the current digit 
+       */
+      rr = *tmpa >> ((mp_digit)(DIGIT_BIT - 1));
+      
+      /* now shift up this digit, add in the carry [from the previous] */
+      *tmpb++ = ((*tmpa++ << ((mp_digit)1)) | r) & MP_MASK;
+      
+      /* copy the carry that would be from the source 
+       * digit into the next iteration 
+       */
+      r = rr;
+    }
+
+    /* new leading digit? */
+    if (r != 0) {
+      /* add a MSB which is always 1 at this point */
+      *tmpb = 1;
+      ++(b->used);
+    }
+
+    /* now zero any excess digits on the destination 
+     * that we didn't write to 
+     */
+    tmpb = b->dp + b->used;
+    for (x = b->used; x < oldused; x++) {
+      *tmpb++ = 0;
+    }
+  }
+  b->sign = a->sign;
+  return MP_OKAY;
+}
+#endif
diff --git a/libtommath/bn_mp_mul_2d.c b/libtommath/bn_mp_mul_2d.c
new file mode 100644
index 0000000..4ac2e4e
--- /dev/null
+++ b/libtommath/bn_mp_mul_2d.c
@@ -0,0 +1,81 @@
+#include <tommath.h>
+#ifdef BN_MP_MUL_2D_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* shift left by a certain bit count */
+int mp_mul_2d (const mp_int * a, int b, mp_int * c)
+{
+  mp_digit d;
+  int      res;
+
+  /* copy */
+  if (a != c) {
+     if ((res = mp_copy (a, c)) != MP_OKAY) {
+       return res;
+     }
+  }
+
+  if (c->alloc < (int)(c->used + b/DIGIT_BIT + 1)) {
+     if ((res = mp_grow (c, c->used + b / DIGIT_BIT + 1)) != MP_OKAY) {
+       return res;
+     }
+  }
+
+  /* shift by as many digits in the bit count */
+  if (b >= (int)DIGIT_BIT) {
+    if ((res = mp_lshd (c, b / DIGIT_BIT)) != MP_OKAY) {
+      return res;
+    }
+  }
+
+  /* shift any bit count < DIGIT_BIT */
+  d = (mp_digit) (b % DIGIT_BIT);
+  if (d != 0) {
+    register mp_digit *tmpc, shift, mask, r, rr;
+    register int x;
+
+    /* bitmask for carries */
+    mask = (((mp_digit)1) << d) - 1;
+
+    /* shift for msbs */
+    shift = DIGIT_BIT - d;
+
+    /* alias */
+    tmpc = c->dp;
+
+    /* carry */
+    r    = 0;
+    for (x = 0; x < c->used; x++) {
+      /* get the higher bits of the current word */
+      rr = (*tmpc >> shift) & mask;
+
+      /* shift the current word and OR in the carry */
+      *tmpc = ((*tmpc << d) | r) & MP_MASK;
+      ++tmpc;
+
+      /* set the carry to the carry bits of the current word */
+      r = rr;
+    }
+    
+    /* set final carry */
+    if (r != 0) {
+       c->dp[(c->used)++] = r;
+    }
+  }
+  mp_clamp (c);
+  return MP_OKAY;
+}
+#endif
diff --git a/libtommath/bn_mp_mul_d.c b/libtommath/bn_mp_mul_d.c
new file mode 100644
index 0000000..ba45a0c
--- /dev/null
+++ b/libtommath/bn_mp_mul_d.c
@@ -0,0 +1,75 @@
+#include <tommath.h>
+#ifdef BN_MP_MUL_D_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* multiply by a digit */
+int
+mp_mul_d (mp_int * a, mp_digit b, mp_int * c)
+{
+  mp_digit u, *tmpa, *tmpc;
+  mp_word  r;
+  int      ix, res, olduse;
+
+  /* make sure c is big enough to hold a*b */
+  if (c->alloc < a->used + 1) {
+    if ((res = mp_grow (c, a->used + 1)) != MP_OKAY) {
+      return res;
+    }
+  }
+
+  /* get the original destinations used count */
+  olduse = c->used;
+
+  /* set the sign */
+  c->sign = a->sign;
+
+  /* alias for a->dp [source] */
+  tmpa = a->dp;
+
+  /* alias for c->dp [dest] */
+  tmpc = c->dp;
+
+  /* zero carry */
+  u = 0;
+
+  /* compute columns */
+  for (ix = 0; ix < a->used; ix++) {
+    /* compute product and carry sum for this term */
+    r       = ((mp_word) u) + ((mp_word)*tmpa++) * ((mp_word)b);
+
+    /* mask off higher bits to get a single digit */
+    *tmpc++ = (mp_digit) (r & ((mp_word) MP_MASK));
+
+    /* send carry into next iteration */
+    u       = (mp_digit) (r >> ((mp_word) DIGIT_BIT));
+  }
+
+  /* store final carry [if any] and increment ix offset  */
+  *tmpc++ = u;
+  ++ix;
+
+  /* now zero digits above the top */
+  while (ix++ < olduse) {
+     *tmpc++ = 0;
+  }
+
+  /* set used count */
+  c->used = a->used + 1;
+  mp_clamp(c);
+
+  return MP_OKAY;
+}
+#endif
diff --git a/libtommath/bn_mp_mulmod.c b/libtommath/bn_mp_mulmod.c
new file mode 100644
index 0000000..649b717
--- /dev/null
+++ b/libtommath/bn_mp_mulmod.c
@@ -0,0 +1,36 @@
+#include <tommath.h>
+#ifdef BN_MP_MULMOD_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* d = a * b (mod c) */
+int mp_mulmod (mp_int * a, mp_int * b, mp_int * c, mp_int * d)
+{
+  int     res;
+  mp_int  t;
+
+  if ((res = mp_init (&t)) != MP_OKAY) {
+    return res;
+  }
+
+  if ((res = mp_mul (a, b, &t)) != MP_OKAY) {
+    mp_clear (&t);
+    return res;
+  }
+  res = mp_mod (&t, c, d);
+  mp_clear (&t);
+  return res;
+}
+#endif
diff --git a/libtommath/bn_mp_n_root.c b/libtommath/bn_mp_n_root.c
new file mode 100644
index 0000000..b2700a8
--- /dev/null
+++ b/libtommath/bn_mp_n_root.c
@@ -0,0 +1,128 @@
+#include <tommath.h>
+#ifdef BN_MP_N_ROOT_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* find the n'th root of an integer 
+ *
+ * Result found such that (c)**b <= a and (c+1)**b > a 
+ *
+ * This algorithm uses Newton's approximation 
+ * x[i+1] = x[i] - f(x[i])/f'(x[i]) 
+ * which will find the root in log(N) time where 
+ * each step involves a fair bit.  This is not meant to 
+ * find huge roots [square and cube, etc].
+ */
+int mp_n_root (mp_int * a, mp_digit b, mp_int * c)
+{
+  mp_int  t1, t2, t3;
+  int     res, neg;
+
+  /* input must be positive if b is even */
+  if ((b & 1) == 0 && a->sign == MP_NEG) {
+    return MP_VAL;
+  }
+
+  if ((res = mp_init (&t1)) != MP_OKAY) {
+    return res;
+  }
+
+  if ((res = mp_init (&t2)) != MP_OKAY) {
+    goto LBL_T1;
+  }
+
+  if ((res = mp_init (&t3)) != MP_OKAY) {
+    goto LBL_T2;
+  }
+
+  /* if a is negative fudge the sign but keep track */
+  neg     = a->sign;
+  a->sign = MP_ZPOS;
+
+  /* t2 = 2 */
+  mp_set (&t2, 2);
+
+  do {
+    /* t1 = t2 */
+    if ((res = mp_copy (&t2, &t1)) != MP_OKAY) {
+      goto LBL_T3;
+    }
+
+    /* t2 = t1 - ((t1**b - a) / (b * t1**(b-1))) */
+    
+    /* t3 = t1**(b-1) */
+    if ((res = mp_expt_d (&t1, b - 1, &t3)) != MP_OKAY) {   
+      goto LBL_T3;
+    }
+
+    /* numerator */
+    /* t2 = t1**b */
+    if ((res = mp_mul (&t3, &t1, &t2)) != MP_OKAY) {    
+      goto LBL_T3;
+    }
+
+    /* t2 = t1**b - a */
+    if ((res = mp_sub (&t2, a, &t2)) != MP_OKAY) {  
+      goto LBL_T3;
+    }
+
+    /* denominator */
+    /* t3 = t1**(b-1) * b  */
+    if ((res = mp_mul_d (&t3, b, &t3)) != MP_OKAY) {    
+      goto LBL_T3;
+    }
+
+    /* t3 = (t1**b - a)/(b * t1**(b-1)) */
+    if ((res = mp_div (&t2, &t3, &t3, NULL)) != MP_OKAY) {  
+      goto LBL_T3;
+    }
+
+    if ((res = mp_sub (&t1, &t3, &t2)) != MP_OKAY) {
+      goto LBL_T3;
+    }
+  }  while (mp_cmp (&t1, &t2) != MP_EQ);
+
+  /* result can be off by a few so check */
+  for (;;) {
+    if ((res = mp_expt_d (&t1, b, &t2)) != MP_OKAY) {
+      goto LBL_T3;
+    }
+
+    if (mp_cmp (&t2, a) == MP_GT) {
+      if ((res = mp_sub_d (&t1, 1, &t1)) != MP_OKAY) {
+         goto LBL_T3;
+      }
+    } else {
+      break;
+    }
+  }
+
+  /* reset the sign of a first */
+  a->sign = neg;
+
+  /* set the result */
+  mp_exch (&t1, c);
+
+  /* set the sign of the result */
+  c->sign = neg;
+
+  res = MP_OKAY;
+
+LBL_T3:mp_clear (&t3);
+LBL_T2:mp_clear (&t2);
+LBL_T1:mp_clear (&t1);
+  return res;
+}
+#endif
diff --git a/libtommath/bn_mp_neg.c b/libtommath/bn_mp_neg.c
new file mode 100644
index 0000000..07fb148
--- /dev/null
+++ b/libtommath/bn_mp_neg.c
@@ -0,0 +1,36 @@
+#include <tommath.h>
+#ifdef BN_MP_NEG_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* b = -a */
+int mp_neg (const mp_int * a, mp_int * b)
+{
+  int     res;
+  if (a != b) {
+     if ((res = mp_copy (a, b)) != MP_OKAY) {
+        return res;
+     }
+  }
+
+  if (mp_iszero(b) != MP_YES) {
+     b->sign = (a->sign == MP_ZPOS) ? MP_NEG : MP_ZPOS;
+  } else {
+     b->sign = MP_ZPOS;
+  }
+
+  return MP_OKAY;
+}
+#endif
diff --git a/libtommath/bn_mp_or.c b/libtommath/bn_mp_or.c
new file mode 100644
index 0000000..aa5b1bd
--- /dev/null
+++ b/libtommath/bn_mp_or.c
@@ -0,0 +1,46 @@
+#include <tommath.h>
+#ifdef BN_MP_OR_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* OR two ints together */
+int mp_or (mp_int * a, mp_int * b, mp_int * c)
+{
+  int     res, ix, px;
+  mp_int  t, *x;
+
+  if (a->used > b->used) {
+    if ((res = mp_init_copy (&t, a)) != MP_OKAY) {
+      return res;
+    }
+    px = b->used;
+    x = b;
+  } else {
+    if ((res = mp_init_copy (&t, b)) != MP_OKAY) {
+      return res;
+    }
+    px = a->used;
+    x = a;
+  }
+
+  for (ix = 0; ix < px; ix++) {
+    t.dp[ix] |= x->dp[ix];
+  }
+  mp_clamp (&t);
+  mp_exch (c, &t);
+  mp_clear (&t);
+  return MP_OKAY;
+}
+#endif
diff --git a/libtommath/bn_mp_prime_fermat.c b/libtommath/bn_mp_prime_fermat.c
new file mode 100644
index 0000000..7b9b12e
--- /dev/null
+++ b/libtommath/bn_mp_prime_fermat.c
@@ -0,0 +1,58 @@
+#include <tommath.h>
+#ifdef BN_MP_PRIME_FERMAT_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* performs one Fermat test.
+ * 
+ * If "a" were prime then b**a == b (mod a) since the order of
+ * the multiplicative sub-group would be phi(a) = a-1.  That means
+ * it would be the same as b**(a mod (a-1)) == b**1 == b (mod a).
+ *
+ * Sets result to 1 if the congruence holds, or zero otherwise.
+ */
+int mp_prime_fermat (mp_int * a, mp_int * b, int *result)
+{
+  mp_int  t;
+  int     err;
+
+  /* default to composite  */
+  *result = MP_NO;
+
+  /* ensure b > 1 */
+  if (mp_cmp_d(b, 1) != MP_GT) {
+     return MP_VAL;
+  }
+
+  /* init t */
+  if ((err = mp_init (&t)) != MP_OKAY) {
+    return err;
+  }
+
+  /* compute t = b**a mod a */
+  if ((err = mp_exptmod (b, a, a, &t)) != MP_OKAY) {
+    goto LBL_T;
+  }
+
+  /* is it equal to b? */
+  if (mp_cmp (&t, b) == MP_EQ) {
+    *result = MP_YES;
+  }
+
+  err = MP_OKAY;
+LBL_T:mp_clear (&t);
+  return err;
+}
+#endif
diff --git a/libtommath/bn_mp_prime_is_divisible.c b/libtommath/bn_mp_prime_is_divisible.c
new file mode 100644
index 0000000..710c967
--- /dev/null
+++ b/libtommath/bn_mp_prime_is_divisible.c
@@ -0,0 +1,46 @@
+#include <tommath.h>
+#ifdef BN_MP_PRIME_IS_DIVISIBLE_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* determines if an integers is divisible by one 
+ * of the first PRIME_SIZE primes or not
+ *
+ * sets result to 0 if not, 1 if yes
+ */
+int mp_prime_is_divisible (mp_int * a, int *result)
+{
+  int     err, ix;
+  mp_digit res;
+
+  /* default to not */
+  *result = MP_NO;
+
+  for (ix = 0; ix < PRIME_SIZE; ix++) {
+    /* what is a mod LBL_prime_tab[ix] */
+    if ((err = mp_mod_d (a, ltm_prime_tab[ix], &res)) != MP_OKAY) {
+      return err;
+    }
+
+    /* is the residue zero? */
+    if (res == 0) {
+      *result = MP_YES;
+      return MP_OKAY;
+    }
+  }
+
+  return MP_OKAY;
+}
+#endif
diff --git a/libtommath/bn_mp_prime_is_prime.c b/libtommath/bn_mp_prime_is_prime.c
new file mode 100644
index 0000000..ce225a3
--- /dev/null
+++ b/libtommath/bn_mp_prime_is_prime.c
@@ -0,0 +1,79 @@
+#include <tommath.h>
+#ifdef BN_MP_PRIME_IS_PRIME_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* performs a variable number of rounds of Miller-Rabin
+ *
+ * Probability of error after t rounds is no more than
+
+ *
+ * Sets result to 1 if probably prime, 0 otherwise
+ */
+int mp_prime_is_prime (mp_int * a, int t, int *result)
+{
+  mp_int  b;
+  int     ix, err, res;
+
+  /* default to no */
+  *result = MP_NO;
+
+  /* valid value of t? */
+  if (t <= 0 || t > PRIME_SIZE) {
+    return MP_VAL;
+  }
+
+  /* is the input equal to one of the primes in the table? */
+  for (ix = 0; ix < PRIME_SIZE; ix++) {
+      if (mp_cmp_d(a, ltm_prime_tab[ix]) == MP_EQ) {
+         *result = 1;
+         return MP_OKAY;
+      }
+  }
+
+  /* first perform trial division */
+  if ((err = mp_prime_is_divisible (a, &res)) != MP_OKAY) {
+    return err;
+  }
+
+  /* return if it was trivially divisible */
+  if (res == MP_YES) {
+    return MP_OKAY;
+  }
+
+  /* now perform the miller-rabin rounds */
+  if ((err = mp_init (&b)) != MP_OKAY) {
+    return err;
+  }
+
+  for (ix = 0; ix < t; ix++) {
+    /* set the prime */
+    mp_set (&b, ltm_prime_tab[ix]);
+
+    if ((err = mp_prime_miller_rabin (a, &b, &res)) != MP_OKAY) {
+      goto LBL_B;
+    }
+
+    if (res == MP_NO) {
+      goto LBL_B;
+    }
+  }
+
+  /* passed the test */
+  *result = MP_YES;
+LBL_B:mp_clear (&b);
+  return err;
+}
+#endif
diff --git a/libtommath/bn_mp_prime_miller_rabin.c b/libtommath/bn_mp_prime_miller_rabin.c
new file mode 100644
index 0000000..c5185b8
--- /dev/null
+++ b/libtommath/bn_mp_prime_miller_rabin.c
@@ -0,0 +1,99 @@
+#include <tommath.h>
+#ifdef BN_MP_PRIME_MILLER_RABIN_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* Miller-Rabin test of "a" to the base of "b" as described in 
+ * HAC pp. 139 Algorithm 4.24
+ *
+ * Sets result to 0 if definitely composite or 1 if probably prime.
+ * Randomly the chance of error is no more than 1/4 and often 
+ * very much lower.
+ */
+int mp_prime_miller_rabin (mp_int * a, mp_int * b, int *result)
+{
+  mp_int  n1, y, r;
+  int     s, j, err;
+
+  /* default */
+  *result = MP_NO;
+
+  /* ensure b > 1 */
+  if (mp_cmp_d(b, 1) != MP_GT) {
+     return MP_VAL;
+  }     
+
+  /* get n1 = a - 1 */
+  if ((err = mp_init_copy (&n1, a)) != MP_OKAY) {
+    return err;
+  }
+  if ((err = mp_sub_d (&n1, 1, &n1)) != MP_OKAY) {
+    goto LBL_N1;
+  }
+
+  /* set 2**s * r = n1 */
+  if ((err = mp_init_copy (&r, &n1)) != MP_OKAY) {
+    goto LBL_N1;
+  }
+
+  /* count the number of least significant bits
+   * which are zero
+   */
+  s = mp_cnt_lsb(&r);
+
+  /* now divide n - 1 by 2**s */
+  if ((err = mp_div_2d (&r, s, &r, NULL)) != MP_OKAY) {
+    goto LBL_R;
+  }
+
+  /* compute y = b**r mod a */
+  if ((err = mp_init (&y)) != MP_OKAY) {
+    goto LBL_R;
+  }
+  if ((err = mp_exptmod (b, &r, a, &y)) != MP_OKAY) {
+    goto LBL_Y;
+  }
+
+  /* if y != 1 and y != n1 do */
+  if (mp_cmp_d (&y, 1) != MP_EQ && mp_cmp (&y, &n1) != MP_EQ) {
+    j = 1;
+    /* while j <= s-1 and y != n1 */
+    while ((j <= (s - 1)) && mp_cmp (&y, &n1) != MP_EQ) {
+      if ((err = mp_sqrmod (&y, a, &y)) != MP_OKAY) {
+         goto LBL_Y;
+      }
+
+      /* if y == 1 then composite */
+      if (mp_cmp_d (&y, 1) == MP_EQ) {
+         goto LBL_Y;
+      }
+
+      ++j;
+    }
+
+    /* if y != n1 then composite */
+    if (mp_cmp (&y, &n1) != MP_EQ) {
+      goto LBL_Y;
+    }
+  }
+
+  /* probably prime now */
+  *result = MP_YES;
+LBL_Y:mp_clear (&y);
+LBL_R:mp_clear (&r);
+LBL_N1:mp_clear (&n1);
+  return err;
+}
+#endif
diff --git a/libtommath/bn_mp_prime_next_prime.c b/libtommath/bn_mp_prime_next_prime.c
new file mode 100644
index 0000000..2433e8c
--- /dev/null
+++ b/libtommath/bn_mp_prime_next_prime.c
@@ -0,0 +1,166 @@
+#include <tommath.h>
+#ifdef BN_MP_PRIME_NEXT_PRIME_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* finds the next prime after the number "a" using "t" trials
+ * of Miller-Rabin.
+ *
+ * bbs_style = 1 means the prime must be congruent to 3 mod 4
+ */
+int mp_prime_next_prime(mp_int *a, int t, int bbs_style)
+{
+   int      err, res, x, y;
+   mp_digit res_tab[PRIME_SIZE], step, kstep;
+   mp_int   b;
+
+   /* ensure t is valid */
+   if (t <= 0 || t > PRIME_SIZE) {
+      return MP_VAL;
+   }
+
+   /* force positive */
+   a->sign = MP_ZPOS;
+
+   /* simple algo if a is less than the largest prime in the table */
+   if (mp_cmp_d(a, ltm_prime_tab[PRIME_SIZE-1]) == MP_LT) {
+      /* find which prime it is bigger than */
+      for (x = PRIME_SIZE - 2; x >= 0; x--) {
+          if (mp_cmp_d(a, ltm_prime_tab[x]) != MP_LT) {
+             if (bbs_style == 1) {
+                /* ok we found a prime smaller or
+                 * equal [so the next is larger]
+                 *
+                 * however, the prime must be
+                 * congruent to 3 mod 4
+                 */
+                if ((ltm_prime_tab[x + 1] & 3) != 3) {
+                   /* scan upwards for a prime congruent to 3 mod 4 */
+                   for (y = x + 1; y < PRIME_SIZE; y++) {
+                       if ((ltm_prime_tab[y] & 3) == 3) {
+                          mp_set(a, ltm_prime_tab[y]);
+                          return MP_OKAY;
+                       }
+                   }
+                }
+             } else {
+                mp_set(a, ltm_prime_tab[x + 1]);
+                return MP_OKAY;
+             }
+          }
+      }
+      /* at this point a maybe 1 */
+      if (mp_cmp_d(a, 1) == MP_EQ) {
+         mp_set(a, 2);
+         return MP_OKAY;
+      }
+      /* fall through to the sieve */
+   }
+
+   /* generate a prime congruent to 3 mod 4 or 1/3 mod 4? */
+   if (bbs_style == 1) {
+      kstep   = 4;
+   } else {
+      kstep   = 2;
+   }
+
+   /* at this point we will use a combination of a sieve and Miller-Rabin */
+
+   if (bbs_style == 1) {
+      /* if a mod 4 != 3 subtract the correct value to make it so */
+      if ((a->dp[0] & 3) != 3) {
+         if ((err = mp_sub_d(a, (a->dp[0] & 3) + 1, a)) != MP_OKAY) { return err; };
+      }
+   } else {
+      if (mp_iseven(a) == 1) {
+         /* force odd */
+         if ((err = mp_sub_d(a, 1, a)) != MP_OKAY) {
+            return err;
+         }
+      }
+   }
+
+   /* generate the restable */
+   for (x = 1; x < PRIME_SIZE; x++) {
+      if ((err = mp_mod_d(a, ltm_prime_tab[x], res_tab + x)) != MP_OKAY) {
+         return err;
+      }
+   }
+
+   /* init temp used for Miller-Rabin Testing */
+   if ((err = mp_init(&b)) != MP_OKAY) {
+      return err;
+   }
+
+   for (;;) {
+      /* skip to the next non-trivially divisible candidate */
+      step = 0;
+      do {
+         /* y == 1 if any residue was zero [e.g. cannot be prime] */
+         y     =  0;
+
+         /* increase step to next candidate */
+         step += kstep;
+
+         /* compute the new residue without using division */
+         for (x = 1; x < PRIME_SIZE; x++) {
+             /* add the step to each residue */
+             res_tab[x] += kstep;
+
+             /* subtract the modulus [instead of using division] */
+             if (res_tab[x] >= ltm_prime_tab[x]) {
+                res_tab[x]  -= ltm_prime_tab[x];
+             }
+
+             /* set flag if zero */
+             if (res_tab[x] == 0) {
+                y = 1;
+             }
+         }
+      } while (y == 1 && step < ((((mp_digit)1)<<DIGIT_BIT) - kstep));
+
+      /* add the step */
+      if ((err = mp_add_d(a, step, a)) != MP_OKAY) {
+         goto LBL_ERR;
+      }
+
+      /* if didn't pass sieve and step == MAX then skip test */
+      if (y == 1 && step >= ((((mp_digit)1)<<DIGIT_BIT) - kstep)) {
+         continue;
+      }
+
+      /* is this prime? */
+      for (x = 0; x < t; x++) {
+          mp_set(&b, ltm_prime_tab[x]);
+          if ((err = mp_prime_miller_rabin(a, &b, &res)) != MP_OKAY) {
+             goto LBL_ERR;
+          }
+          if (res == MP_NO) {
+             break;
+          }
+      }
+
+      if (res == MP_YES) {
+         break;
+      }
+   }
+
+   err = MP_OKAY;
+LBL_ERR:
+   mp_clear(&b);
+   return err;
+}
+
+#endif
diff --git a/libtommath/bn_mp_prime_rabin_miller_trials.c b/libtommath/bn_mp_prime_rabin_miller_trials.c
new file mode 100644
index 0000000..e57a43c
--- /dev/null
+++ b/libtommath/bn_mp_prime_rabin_miller_trials.c
@@ -0,0 +1,48 @@
+#include <tommath.h>
+#ifdef BN_MP_PRIME_RABIN_MILLER_TRIALS_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+
+static const struct {
+   int k, t;
+} sizes[] = {
+{   128,    28 },
+{   256,    16 },
+{   384,    10 },
+{   512,     7 },
+{   640,     6 },
+{   768,     5 },
+{   896,     4 },
+{  1024,     4 }
+};
+
+/* returns # of RM trials required for a given bit size */
+int mp_prime_rabin_miller_trials(int size)
+{
+   int x;
+
+   for (x = 0; x < (int)(sizeof(sizes)/(sizeof(sizes[0]))); x++) {
+       if (sizes[x].k == size) {
+          return sizes[x].t;
+       } else if (sizes[x].k > size) {
+          return (x == 0) ? sizes[0].t : sizes[x - 1].t;
+       }
+   }
+   return sizes[x-1].t + 1;
+}
+
+
+#endif
diff --git a/libtommath/bn_mp_prime_random_ex.c b/libtommath/bn_mp_prime_random_ex.c
new file mode 100644
index 0000000..a37477e
--- /dev/null
+++ b/libtommath/bn_mp_prime_random_ex.c
@@ -0,0 +1,121 @@
+#include <tommath.h>
+#ifdef BN_MP_PRIME_RANDOM_EX_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* makes a truly random prime of a given size (bits),
+ *
+ * Flags are as follows:
+ * 
+ *   LTM_PRIME_BBS      - make prime congruent to 3 mod 4
+ *   LTM_PRIME_SAFE     - make sure (p-1)/2 is prime as well (implies LTM_PRIME_BBS)
+ *   LTM_PRIME_2MSB_OFF - make the 2nd highest bit zero
+ *   LTM_PRIME_2MSB_ON  - make the 2nd highest bit one
+ *
+ * You have to supply a callback which fills in a buffer with random bytes.  "dat" is a parameter you can
+ * have passed to the callback (e.g. a state or something).  This function doesn't use "dat" itself
+ * so it can be NULL
+ *
+ */
+
+/* This is possibly the mother of all prime generation functions, muahahahahaha! */
+int mp_prime_random_ex(mp_int *a, int t, int size, int flags, ltm_prime_callback cb, void *dat)
+{
+   unsigned char *tmp, maskAND, maskOR_msb, maskOR_lsb;
+   int res, err, bsize, maskOR_msb_offset;
+
+   /* sanity check the input */
+   if (size <= 1 || t <= 0) {
+      return MP_VAL;
+   }
+
+   /* LTM_PRIME_SAFE implies LTM_PRIME_BBS */
+   if (flags & LTM_PRIME_SAFE) {
+      flags |= LTM_PRIME_BBS;
+   }
+
+   /* calc the byte size */
+   bsize = (size>>3) + ((size&7)?1:0);
+
+   /* we need a buffer of bsize bytes */
+   tmp = OPT_CAST(unsigned char) XMALLOC(bsize);
+   if (tmp == NULL) {
+      return MP_MEM;
+   }
+
+   /* calc the maskAND value for the MSbyte*/
+   maskAND = ((size&7) == 0) ? 0xFF : (0xFF >> (8 - (size & 7)));
+
+   /* calc the maskOR_msb */
+   maskOR_msb        = 0;
+   maskOR_msb_offset = ((size & 7) == 1) ? 1 : 0;
+   if (flags & LTM_PRIME_2MSB_ON) {
+      maskOR_msb       |= 0x80 >> ((9 - size) & 7);
+   }  
+
+   /* get the maskOR_lsb */
+   maskOR_lsb         = 1;
+   if (flags & LTM_PRIME_BBS) {
+      maskOR_lsb     |= 3;
+   }
+
+   do {
+      /* read the bytes */
+      if (cb(tmp, bsize, dat) != bsize) {
+         err = MP_VAL;
+         goto error;
+      }
+ 
+      /* work over the MSbyte */
+      tmp[0]    &= maskAND;
+      tmp[0]    |= 1 << ((size - 1) & 7);
+
+      /* mix in the maskORs */
+      tmp[maskOR_msb_offset]   |= maskOR_msb;
+      tmp[bsize-1]             |= maskOR_lsb;
+
+      /* read it in */
+      if ((err = mp_read_unsigned_bin(a, tmp, bsize)) != MP_OKAY)     { goto error; }
+
+      /* is it prime? */
+      if ((err = mp_prime_is_prime(a, t, &res)) != MP_OKAY)           { goto error; }
+      if (res == MP_NO) {  
+         continue;
+      }
+
+      if (flags & LTM_PRIME_SAFE) {
+         /* see if (a-1)/2 is prime */
+         if ((err = mp_sub_d(a, 1, a)) != MP_OKAY)                    { goto error; }
+         if ((err = mp_div_2(a, a)) != MP_OKAY)                       { goto error; }
+ 
+         /* is it prime? */
+         if ((err = mp_prime_is_prime(a, t, &res)) != MP_OKAY)        { goto error; }
+      }
+   } while (res == MP_NO);
+
+   if (flags & LTM_PRIME_SAFE) {
+      /* restore a to the original value */
+      if ((err = mp_mul_2(a, a)) != MP_OKAY)                          { goto error; }
+      if ((err = mp_add_d(a, 1, a)) != MP_OKAY)                       { goto error; }
+   }
+
+   err = MP_OKAY;
+error:
+   XFREE(tmp);
+   return err;
+}
+
+
+#endif
diff --git a/libtommath/bn_mp_radix_size.c b/libtommath/bn_mp_radix_size.c
new file mode 100644
index 0000000..40c4d04
--- /dev/null
+++ b/libtommath/bn_mp_radix_size.c
@@ -0,0 +1,83 @@
+#include <tommath.h>
+#ifdef BN_MP_RADIX_SIZE_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* returns size of ASCII reprensentation */
+int mp_radix_size (mp_int * a, int radix, int *size)
+{
+  int     res, digs;
+  mp_int  t;
+  mp_digit d;
+
+  *size = 0;
+
+  /* special case for binary */
+  if (radix == 2) {
+    *size = mp_count_bits (a) + (a->sign == MP_NEG ? 1 : 0) + 1;
+    return MP_OKAY;
+  }
+
+  /* make sure the radix is in range */
+  if (radix < 2 || radix > 64) {
+    return MP_VAL;
+  }
+
+  if (mp_iszero(a) == MP_YES) {
+    *size = 2;
+    return MP_OKAY;
+  }
+
+  /* digs is the digit count */
+  digs = 0;
+
+  /* if it's negative add one for the sign */
+  if (a->sign == MP_NEG) {
+    ++digs;
+  }
+
+  /* init a copy of the input */
+  if ((res = mp_init_copy (&t, a)) != MP_OKAY) {
+    return res;
+  }
+
+  /* force temp to positive */
+  t.sign = MP_ZPOS; 
+
+  /* fetch out all of the digits */
+  while (mp_iszero (&t) == MP_NO) {
+    if ((res = mp_div_d (&t, (mp_digit) radix, &t, &d)) != MP_OKAY) {
+      mp_clear (&t);
+      return res;
+    }
+    ++digs;
+  }
+  mp_clear (&t);
+
+  /* 
+   * return digs + 1, the 1 is for the NULL byte that would be required.
+   * mp_toradix_n requires a minimum of 3 bytes, so never report less than
+   * that.
+   */
+
+  if ( digs >= 2 ) {
+      *size = digs + 1;
+  } else {
+      *size = 3;
+  }
+  return MP_OKAY;
+}
+
+#endif
diff --git a/libtommath/bn_mp_radix_smap.c b/libtommath/bn_mp_radix_smap.c
new file mode 100644
index 0000000..7aeb375
--- /dev/null
+++ b/libtommath/bn_mp_radix_smap.c
@@ -0,0 +1,20 @@
+#include <tommath.h>
+#ifdef BN_MP_RADIX_SMAP_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* chars used in radix conversions */
+const char *mp_s_rmap = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/";
+#endif
diff --git a/libtommath/bn_mp_rand.c b/libtommath/bn_mp_rand.c
new file mode 100644
index 0000000..17c1fbe
--- /dev/null
+++ b/libtommath/bn_mp_rand.c
@@ -0,0 +1,51 @@
+#include <tommath.h>
+#ifdef BN_MP_RAND_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* makes a pseudo-random int of a given size */
+int
+mp_rand (mp_int * a, int digits)
+{
+  int     res;
+  mp_digit d;
+
+  mp_zero (a);
+  if (digits <= 0) {
+    return MP_OKAY;
+  }
+
+  /* first place a random non-zero digit */
+  do {
+    d = ((mp_digit) abs (rand ())) & MP_MASK;
+  } while (d == 0);
+
+  if ((res = mp_add_d (a, d, a)) != MP_OKAY) {
+    return res;
+  }
+
+  while (--digits > 0) {
+    if ((res = mp_lshd (a, 1)) != MP_OKAY) {
+      return res;
+    }
+
+    if ((res = mp_add_d (a, ((mp_digit) abs (rand ())), a)) != MP_OKAY) {
+      return res;
+    }
+  }
+
+  return MP_OKAY;
+}
+#endif
diff --git a/libtommath/bn_mp_read_radix.c b/libtommath/bn_mp_read_radix.c
new file mode 100644
index 0000000..4b92589
--- /dev/null
+++ b/libtommath/bn_mp_read_radix.c
@@ -0,0 +1,88 @@
+#include <tommath.h>
+#ifdef BN_MP_READ_RADIX_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* read a string [ASCII] in a given radix */
+int mp_read_radix (mp_int * a, const char *str, int radix)
+{
+  int     y, res, neg;
+  char    ch;
+
+  /* zero the digit bignum */
+  mp_zero(a);
+
+  /* make sure the radix is ok */
+  if (radix < 2 || radix > 64) {
+    return MP_VAL;
+  }
+
+  /* if the leading digit is a 
+   * minus set the sign to negative. 
+   */
+  if (*str == '-') {
+    ++str;
+    neg = MP_NEG;
+  } else {
+    neg = MP_ZPOS;
+  }
+
+  /* set the integer to the default of zero */
+  mp_zero (a);
+  
+  /* process each digit of the string */
+  while (*str) {
+    /* if the radix < 36 the conversion is case insensitive
+     * this allows numbers like 1AB and 1ab to represent the same  value
+     * [e.g. in hex]
+     */
+    ch = (char) ((radix < 36) ? toupper ((unsigned char) *str) : *str);
+    for (y = 0; y < 64; y++) {
+      if (ch == mp_s_rmap[y]) {
+         break;
+      }
+    }
+
+    /* if the char was found in the map 
+     * and is less than the given radix add it
+     * to the number, otherwise exit the loop. 
+     */
+    if (y < radix) {
+      if ((res = mp_mul_d (a, (mp_digit) radix, a)) != MP_OKAY) {
+         return res;
+      }
+      if ((res = mp_add_d (a, (mp_digit) y, a)) != MP_OKAY) {
+         return res;
+      }
+    } else {
+      break;
+    }
+    ++str;
+  }
+  
+  /* if an illegal character was found, fail. */
+
+  if ( *str != '\0' ) {
+      mp_zero( a );
+      return MP_VAL;
+  }
+
+  /* set the sign only if a != 0 */
+  if (mp_iszero(a) != 1) {
+     a->sign = neg;
+  }
+  return MP_OKAY;
+}
+#endif
diff --git a/libtommath/bn_mp_read_signed_bin.c b/libtommath/bn_mp_read_signed_bin.c
new file mode 100644
index 0000000..3ee8556
--- /dev/null
+++ b/libtommath/bn_mp_read_signed_bin.c
@@ -0,0 +1,37 @@
+#include <tommath.h>
+#ifdef BN_MP_READ_SIGNED_BIN_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* read signed bin, big endian, first byte is 0==positive or 1==negative */
+int mp_read_signed_bin (mp_int * a, const unsigned char *b, int c)
+{
+  int     res;
+
+  /* read magnitude */
+  if ((res = mp_read_unsigned_bin (a, b + 1, c - 1)) != MP_OKAY) {
+    return res;
+  }
+
+  /* first byte is 0 for positive, non-zero for negative */
+  if (b[0] == 0) {
+     a->sign = MP_ZPOS;
+  } else {
+     a->sign = MP_NEG;
+  }
+
+  return MP_OKAY;
+}
+#endif
diff --git a/libtommath/bn_mp_read_unsigned_bin.c b/libtommath/bn_mp_read_unsigned_bin.c
new file mode 100644
index 0000000..caf5be0
--- /dev/null
+++ b/libtommath/bn_mp_read_unsigned_bin.c
@@ -0,0 +1,51 @@
+#include <tommath.h>
+#ifdef BN_MP_READ_UNSIGNED_BIN_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* reads a unsigned char array, assumes the msb is stored first [big endian] */
+int mp_read_unsigned_bin (mp_int * a, const unsigned char *b, int c)
+{
+  int     res;
+
+  /* make sure there are at least two digits */
+  if (a->alloc < 2) {
+     if ((res = mp_grow(a, 2)) != MP_OKAY) {
+        return res;
+     }
+  }
+
+  /* zero the int */
+  mp_zero (a);
+
+  /* read the bytes in */
+  while (c-- > 0) {
+    if ((res = mp_mul_2d (a, 8, a)) != MP_OKAY) {
+      return res;
+    }
+
+#ifndef MP_8BIT
+      a->dp[0] |= *b++;
+      a->used += 1;
+#else
+      a->dp[0] = (*b & MP_MASK);
+      a->dp[1] |= ((*b++ >> 7U) & 1);
+      a->used += 2;
+#endif
+  }
+  mp_clamp (a);
+  return MP_OKAY;
+}
+#endif
diff --git a/libtommath/bn_mp_reduce.c b/libtommath/bn_mp_reduce.c
new file mode 100644
index 0000000..4375e4e
--- /dev/null
+++ b/libtommath/bn_mp_reduce.c
@@ -0,0 +1,96 @@
+#include <tommath.h>
+#ifdef BN_MP_REDUCE_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* reduces x mod m, assumes 0 < x < m**2, mu is 
+ * precomputed via mp_reduce_setup.
+ * From HAC pp.604 Algorithm 14.42
+ */
+int mp_reduce (mp_int * x, mp_int * m, mp_int * mu)
+{
+  mp_int  q;
+  int     res, um = m->used;
+
+  /* q = x */
+  if ((res = mp_init_copy (&q, x)) != MP_OKAY) {
+    return res;
+  }
+
+  /* q1 = x / b**(k-1)  */
+  mp_rshd (&q, um - 1);         
+
+  /* according to HAC this optimization is ok */
+  if (((unsigned long) um) > (((mp_digit)1) << (DIGIT_BIT - 1))) {
+    if ((res = mp_mul (&q, mu, &q)) != MP_OKAY) {
+      goto CLEANUP;
+    }
+  } else {
+#ifdef BN_S_MP_MUL_HIGH_DIGS_C
+    if ((res = s_mp_mul_high_digs (&q, mu, &q, um)) != MP_OKAY) {
+      goto CLEANUP;
+    }
+#elif defined(BN_FAST_S_MP_MUL_HIGH_DIGS_C)
+    if ((res = fast_s_mp_mul_high_digs (&q, mu, &q, um)) != MP_OKAY) {
+      goto CLEANUP;
+    }
+#else 
+    { 
+      res = MP_VAL;
+      goto CLEANUP;
+    }
+#endif
+  }
+
+  /* q3 = q2 / b**(k+1) */
+  mp_rshd (&q, um + 1);         
+
+  /* x = x mod b**(k+1), quick (no division) */
+  if ((res = mp_mod_2d (x, DIGIT_BIT * (um + 1), x)) != MP_OKAY) {
+    goto CLEANUP;
+  }
+
+  /* q = q * m mod b**(k+1), quick (no division) */
+  if ((res = s_mp_mul_digs (&q, m, &q, um + 1)) != MP_OKAY) {
+    goto CLEANUP;
+  }
+
+  /* x = x - q */
+  if ((res = mp_sub (x, &q, x)) != MP_OKAY) {
+    goto CLEANUP;
+  }
+
+  /* If x < 0, add b**(k+1) to it */
+  if (mp_cmp_d (x, 0) == MP_LT) {
+    mp_set (&q, 1);
+    if ((res = mp_lshd (&q, um + 1)) != MP_OKAY)
+      goto CLEANUP;
+    if ((res = mp_add (x, &q, x)) != MP_OKAY)
+      goto CLEANUP;
+  }
+
+  /* Back off if it's too big */
+  while (mp_cmp (x, m) != MP_LT) {
+    if ((res = s_mp_sub (x, m, x)) != MP_OKAY) {
+      goto CLEANUP;
+    }
+  }
+  
+CLEANUP:
+  mp_clear (&q);
+
+  return res;
+}
+#endif
diff --git a/libtommath/bn_mp_reduce_2k.c b/libtommath/bn_mp_reduce_2k.c
new file mode 100644
index 0000000..428f2ff
--- /dev/null
+++ b/libtommath/bn_mp_reduce_2k.c
@@ -0,0 +1,57 @@
+#include <tommath.h>
+#ifdef BN_MP_REDUCE_2K_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* reduces a modulo n where n is of the form 2**p - d */
+int mp_reduce_2k(mp_int *a, mp_int *n, mp_digit d)
+{
+   mp_int q;
+   int    p, res;
+   
+   if ((res = mp_init(&q)) != MP_OKAY) {
+      return res;
+   }
+   
+   p = mp_count_bits(n);    
+top:
+   /* q = a/2**p, a = a mod 2**p */
+   if ((res = mp_div_2d(a, p, &q, a)) != MP_OKAY) {
+      goto ERR;
+   }
+   
+   if (d != 1) {
+      /* q = q * d */
+      if ((res = mp_mul_d(&q, d, &q)) != MP_OKAY) { 
+         goto ERR;
+      }
+   }
+   
+   /* a = a + q */
+   if ((res = s_mp_add(a, &q, a)) != MP_OKAY) {
+      goto ERR;
+   }
+   
+   if (mp_cmp_mag(a, n) != MP_LT) {
+      s_mp_sub(a, n, a);
+      goto top;
+   }
+   
+ERR:
+   mp_clear(&q);
+   return res;
+}
+
+#endif
diff --git a/libtommath/bn_mp_reduce_2k_l.c b/libtommath/bn_mp_reduce_2k_l.c
new file mode 100644
index 0000000..8e52efa
--- /dev/null
+++ b/libtommath/bn_mp_reduce_2k_l.c
@@ -0,0 +1,58 @@
+#include <tommath.h>
+#ifdef BN_MP_REDUCE_2K_L_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* reduces a modulo n where n is of the form 2**p - d 
+   This differs from reduce_2k since "d" can be larger
+   than a single digit.
+*/
+int mp_reduce_2k_l(mp_int *a, mp_int *n, mp_int *d)
+{
+   mp_int q;
+   int    p, res;
+   
+   if ((res = mp_init(&q)) != MP_OKAY) {
+      return res;
+   }
+   
+   p = mp_count_bits(n);    
+top:
+   /* q = a/2**p, a = a mod 2**p */
+   if ((res = mp_div_2d(a, p, &q, a)) != MP_OKAY) {
+      goto ERR;
+   }
+   
+   /* q = q * d */
+   if ((res = mp_mul(&q, d, &q)) != MP_OKAY) { 
+      goto ERR;
+   }
+   
+   /* a = a + q */
+   if ((res = s_mp_add(a, &q, a)) != MP_OKAY) {
+      goto ERR;
+   }
+   
+   if (mp_cmp_mag(a, n) != MP_LT) {
+      s_mp_sub(a, n, a);
+      goto top;
+   }
+   
+ERR:
+   mp_clear(&q);
+   return res;
+}
+
+#endif
diff --git a/libtommath/bn_mp_reduce_2k_setup.c b/libtommath/bn_mp_reduce_2k_setup.c
new file mode 100644
index 0000000..ac043f6
--- /dev/null
+++ b/libtommath/bn_mp_reduce_2k_setup.c
@@ -0,0 +1,43 @@
+#include <tommath.h>
+#ifdef BN_MP_REDUCE_2K_SETUP_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* determines the setup value */
+int mp_reduce_2k_setup(mp_int *a, mp_digit *d)
+{
+   int res, p;
+   mp_int tmp;
+   
+   if ((res = mp_init(&tmp)) != MP_OKAY) {
+      return res;
+   }
+   
+   p = mp_count_bits(a);
+   if ((res = mp_2expt(&tmp, p)) != MP_OKAY) {
+      mp_clear(&tmp);
+      return res;
+   }
+   
+   if ((res = s_mp_sub(&tmp, a, &tmp)) != MP_OKAY) {
+      mp_clear(&tmp);
+      return res;
+   }
+   
+   *d = tmp.dp[0];
+   mp_clear(&tmp);
+   return MP_OKAY;
+}
+#endif
diff --git a/libtommath/bn_mp_reduce_2k_setup_l.c b/libtommath/bn_mp_reduce_2k_setup_l.c
new file mode 100644
index 0000000..b59a1ed
--- /dev/null
+++ b/libtommath/bn_mp_reduce_2k_setup_l.c
@@ -0,0 +1,40 @@
+#include <tommath.h>
+#ifdef BN_MP_REDUCE_2K_SETUP_L_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* determines the setup value */
+int mp_reduce_2k_setup_l(mp_int *a, mp_int *d)
+{
+   int    res;
+   mp_int tmp;
+   
+   if ((res = mp_init(&tmp)) != MP_OKAY) {
+      return res;
+   }
+   
+   if ((res = mp_2expt(&tmp, mp_count_bits(a))) != MP_OKAY) {
+      goto ERR;
+   }
+   
+   if ((res = s_mp_sub(&tmp, a, d)) != MP_OKAY) {
+      goto ERR;
+   }
+   
+ERR:
+   mp_clear(&tmp);
+   return res;
+}
+#endif
diff --git a/libtommath/bn_mp_reduce_is_2k.c b/libtommath/bn_mp_reduce_is_2k.c
new file mode 100644
index 0000000..4655fcf
--- /dev/null
+++ b/libtommath/bn_mp_reduce_is_2k.c
@@ -0,0 +1,48 @@
+#include <tommath.h>
+#ifdef BN_MP_REDUCE_IS_2K_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* determines if mp_reduce_2k can be used */
+int mp_reduce_is_2k(mp_int *a)
+{
+   int ix, iy, iw;
+   mp_digit iz;
+   
+   if (a->used == 0) {
+      return MP_NO;
+   } else if (a->used == 1) {
+      return MP_YES;
+   } else if (a->used > 1) {
+      iy = mp_count_bits(a);
+      iz = 1;
+      iw = 1;
+    
+      /* Test every bit from the second digit up, must be 1 */
+      for (ix = DIGIT_BIT; ix < iy; ix++) {
+          if ((a->dp[iw] & iz) == 0) {
+             return MP_NO;
+          }
+          iz <<= 1;
+          if (iz > (mp_digit)MP_MASK) {
+             ++iw;
+             iz = 1;
+          }
+      }
+   }
+   return MP_YES;
+}
+
+#endif
diff --git a/libtommath/bn_mp_reduce_is_2k_l.c b/libtommath/bn_mp_reduce_is_2k_l.c
new file mode 100644
index 0000000..7b57865
--- /dev/null
+++ b/libtommath/bn_mp_reduce_is_2k_l.c
@@ -0,0 +1,40 @@
+#include <tommath.h>
+#ifdef BN_MP_REDUCE_IS_2K_L_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* determines if reduce_2k_l can be used */
+int mp_reduce_is_2k_l(mp_int *a)
+{
+   int ix, iy;
+   
+   if (a->used == 0) {
+      return MP_NO;
+   } else if (a->used == 1) {
+      return MP_YES;
+   } else if (a->used > 1) {
+      /* if more than half of the digits are -1 we're sold */
+      for (iy = ix = 0; ix < a->used; ix++) {
+          if (a->dp[ix] == MP_MASK) {
+              ++iy;
+          }
+      }
+      return (iy >= (a->used/2)) ? MP_YES : MP_NO;
+      
+   }
+   return MP_NO;
+}
+
+#endif
diff --git a/libtommath/bn_mp_reduce_setup.c b/libtommath/bn_mp_reduce_setup.c
new file mode 100644
index 0000000..d8cefd9
--- /dev/null
+++ b/libtommath/bn_mp_reduce_setup.c
@@ -0,0 +1,30 @@
+#include <tommath.h>
+#ifdef BN_MP_REDUCE_SETUP_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* pre-calculate the value required for Barrett reduction
+ * For a given modulus "b" it calulates the value required in "a"
+ */
+int mp_reduce_setup (mp_int * a, mp_int * b)
+{
+  int     res;
+  
+  if ((res = mp_2expt (a, b->used * 2 * DIGIT_BIT)) != MP_OKAY) {
+    return res;
+  }
+  return mp_div (a, b, a, NULL);
+}
+#endif
diff --git a/libtommath/bn_mp_rshd.c b/libtommath/bn_mp_rshd.c
new file mode 100644
index 0000000..e6095b3
--- /dev/null
+++ b/libtommath/bn_mp_rshd.c
@@ -0,0 +1,68 @@
+#include <tommath.h>
+#ifdef BN_MP_RSHD_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* shift right a certain amount of digits */
+void mp_rshd (mp_int * a, int b)
+{
+  int     x;
+
+  /* if b <= 0 then ignore it */
+  if (b <= 0) {
+    return;
+  }
+
+  /* if b > used then simply zero it and return */
+  if (a->used <= b) {
+    mp_zero (a);
+    return;
+  }
+
+  {
+    register mp_digit *bottom, *top;
+
+    /* shift the digits down */
+
+    /* bottom */
+    bottom = a->dp;
+
+    /* top [offset into digits] */
+    top = a->dp + b;
+
+    /* this is implemented as a sliding window where 
+     * the window is b-digits long and digits from 
+     * the top of the window are copied to the bottom
+     *
+     * e.g.
+
+     b-2 | b-1 | b0 | b1 | b2 | ... | bb |   ---->
+                 /\                   |      ---->
+                  \-------------------/      ---->
+     */
+    for (x = 0; x < (a->used - b); x++) {
+      *bottom++ = *top++;
+    }
+
+    /* zero the top digits */
+    for (; x < a->used; x++) {
+      *bottom++ = 0;
+    }
+  }
+  
+  /* remove excess digits */
+  a->used -= b;
+}
+#endif
diff --git a/libtommath/bn_mp_set.c b/libtommath/bn_mp_set.c
new file mode 100644
index 0000000..c32fc42
--- /dev/null
+++ b/libtommath/bn_mp_set.c
@@ -0,0 +1,25 @@
+#include <tommath.h>
+#ifdef BN_MP_SET_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* set to a digit */
+void mp_set (mp_int * a, mp_digit b)
+{
+  mp_zero (a);
+  a->dp[0] = b & MP_MASK;
+  a->used  = (a->dp[0] != 0) ? 1 : 0;
+}
+#endif
diff --git a/libtommath/bn_mp_set_int.c b/libtommath/bn_mp_set_int.c
new file mode 100644
index 0000000..b0fc344
--- /dev/null
+++ b/libtommath/bn_mp_set_int.c
@@ -0,0 +1,44 @@
+#include <tommath.h>
+#ifdef BN_MP_SET_INT_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* set a 32-bit const */
+int mp_set_int (mp_int * a, unsigned long b)
+{
+  int     x, res;
+
+  mp_zero (a);
+  
+  /* set four bits at a time */
+  for (x = 0; x < 8; x++) {
+    /* shift the number up four bits */
+    if ((res = mp_mul_2d (a, 4, a)) != MP_OKAY) {
+      return res;
+    }
+
+    /* OR in the top four bits of the source */
+    a->dp[0] |= (b >> 28) & 15;
+
+    /* shift the source up to the next four bits */
+    b <<= 4;
+
+    /* ensure that digits are not clamped off */
+    a->used += 1;
+  }
+  mp_clamp (a);
+  return MP_OKAY;
+}
+#endif
diff --git a/libtommath/bn_mp_shrink.c b/libtommath/bn_mp_shrink.c
new file mode 100644
index 0000000..bfdf93a
--- /dev/null
+++ b/libtommath/bn_mp_shrink.c
@@ -0,0 +1,36 @@
+#include <tommath.h>
+#ifdef BN_MP_SHRINK_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* shrink a bignum */
+int mp_shrink (mp_int * a)
+{
+  mp_digit *tmp;
+  int used = 1;
+  
+  if(a->used > 0)
+    used = a->used;
+  
+  if (a->alloc != used) {
+    if ((tmp = OPT_CAST(mp_digit) XREALLOC (a->dp, sizeof (mp_digit) * used)) == NULL) {
+      return MP_MEM;
+    }
+    a->dp    = tmp;
+    a->alloc = used;
+  }
+  return MP_OKAY;
+}
+#endif
diff --git a/libtommath/bn_mp_signed_bin_size.c b/libtommath/bn_mp_signed_bin_size.c
new file mode 100644
index 0000000..8f88e76
--- /dev/null
+++ b/libtommath/bn_mp_signed_bin_size.c
@@ -0,0 +1,23 @@
+#include <tommath.h>
+#ifdef BN_MP_SIGNED_BIN_SIZE_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* get the size for an signed equivalent */
+int mp_signed_bin_size (mp_int * a)
+{
+  return 1 + mp_unsigned_bin_size (a);
+}
+#endif
diff --git a/libtommath/bn_mp_sqr.c b/libtommath/bn_mp_sqr.c
new file mode 100644
index 0000000..3938537
--- /dev/null
+++ b/libtommath/bn_mp_sqr.c
@@ -0,0 +1,54 @@
+#include <tommath.h>
+#ifdef BN_MP_SQR_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* computes b = a*a */
+int
+mp_sqr (mp_int * a, mp_int * b)
+{
+  int     res;
+
+#ifdef BN_MP_TOOM_SQR_C
+  /* use Toom-Cook? */
+  if (a->used >= TOOM_SQR_CUTOFF) {
+    res = mp_toom_sqr(a, b);
+  /* Karatsuba? */
+  } else 
+#endif
+#ifdef BN_MP_KARATSUBA_SQR_C
+if (a->used >= KARATSUBA_SQR_CUTOFF) {
+    res = mp_karatsuba_sqr (a, b);
+  } else 
+#endif
+  {
+#ifdef BN_FAST_S_MP_SQR_C
+    /* can we use the fast comba multiplier? */
+    if ((a->used * 2 + 1) < MP_WARRAY && 
+         a->used < 
+         (1 << (sizeof(mp_word) * CHAR_BIT - 2*DIGIT_BIT - 1))) {
+      res = fast_s_mp_sqr (a, b);
+    } else
+#endif
+#ifdef BN_S_MP_SQR_C
+      res = s_mp_sqr (a, b);
+#else
+      res = MP_VAL;
+#endif
+  }
+  b->sign = MP_ZPOS;
+  return res;
+}
+#endif
diff --git a/libtommath/bn_mp_sqrmod.c b/libtommath/bn_mp_sqrmod.c
new file mode 100644
index 0000000..6f90772
--- /dev/null
+++ b/libtommath/bn_mp_sqrmod.c
@@ -0,0 +1,37 @@
+#include <tommath.h>
+#ifdef BN_MP_SQRMOD_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* c = a * a (mod b) */
+int
+mp_sqrmod (mp_int * a, mp_int * b, mp_int * c)
+{
+  int     res;
+  mp_int  t;
+
+  if ((res = mp_init (&t)) != MP_OKAY) {
+    return res;
+  }
+
+  if ((res = mp_sqr (a, &t)) != MP_OKAY) {
+    mp_clear (&t);
+    return res;
+  }
+  res = mp_mod (&t, b, c);
+  mp_clear (&t);
+  return res;
+}
+#endif
diff --git a/libtommath/bn_mp_sqrt.c b/libtommath/bn_mp_sqrt.c
new file mode 100644
index 0000000..016b8ba
--- /dev/null
+++ b/libtommath/bn_mp_sqrt.c
@@ -0,0 +1,142 @@
+#include <tommath.h>
+
+#ifdef BN_MP_SQRT_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+#ifndef NO_FLOATING_POINT
+#include <math.h>
+#endif
+
+/* this function is less generic than mp_n_root, simpler and faster */
+int mp_sqrt(mp_int *arg, mp_int *ret) 
+{
+  int res;
+  mp_int t1,t2;
+  int i, j, k;
+#ifndef NO_FLOATING_POINT
+  volatile double d;
+  mp_digit dig;
+#endif
+
+  /* must be positive */
+  if (arg->sign == MP_NEG) {
+    return MP_VAL;
+  }
+
+  /* easy out */
+  if (mp_iszero(arg) == MP_YES) {
+    mp_zero(ret);
+    return MP_OKAY;
+  }
+  
+  i = (arg->used / 2) - 1;
+  j = 2 * i;
+  if ((res = mp_init_size(&t1, i+2)) != MP_OKAY) {
+      return res;
+  }
+  
+  if ((res = mp_init(&t2)) != MP_OKAY) {
+    goto E2;
+  }
+
+  for (k = 0; k < i; ++k) {
+      t1.dp[k] = (mp_digit) 0;
+  }
+      
+#ifndef NO_FLOATING_POINT
+
+  /* Estimate the square root using the hardware floating point unit. */
+
+  d = 0.0;
+  for (k = arg->used-1; k >= j; --k) {
+      d = ldexp(d, DIGIT_BIT) + (double) (arg->dp[k]);
+  }
+
+  /* 
+   * At this point, d is the nearest floating point number to the most
+   * significant 1 or 2 mp_digits of arg. Extract its square root.
+   */
+     
+  d = sqrt(d);
+
+  /* dig is the most significant mp_digit of the square root */
+
+  dig = (mp_digit) ldexp(d, -DIGIT_BIT);
+
+  /* 
+   * If the most significant digit is nonzero, find the next digit down
+   * by subtracting DIGIT_BIT times thie most significant digit. 
+   * Subtract one from the result so that our initial estimate is always
+   * low.
+   */
+
+  if (dig) {
+      t1.used = i+2;
+      d -= ldexp((double) dig, DIGIT_BIT);
+      if (d >= 1.0) {
+	  t1.dp[i+1] = dig;
+	  t1.dp[i] = ((mp_digit) d) - 1;
+      } else {
+	  t1.dp[i+1] = dig-1;
+	  t1.dp[i] = MP_DIGIT_MAX;
+      }
+  } else {
+      t1.used = i+1;
+      t1.dp[i] = ((mp_digit) d) - 1;
+  }
+
+#else
+
+  /* Estimate the square root as having 1 in the most significant place. */
+
+  t1.used = i + 2;
+  t1.dp[i+1] = (mp_digit) 1;
+  t1.dp[i] = (mp_digit) 0;
+
+#endif
+
+  /* t1 > 0  */ 
+  if ((res = mp_div(arg,&t1,&t2,NULL)) != MP_OKAY) {
+    goto E1;
+  }
+  if ((res = mp_add(&t1,&t2,&t1)) != MP_OKAY) {
+    goto E1;
+  }
+  if ((res = mp_div_2(&t1,&t1)) != MP_OKAY) {
+    goto E1;
+  }
+  /* And now t1 > sqrt(arg) */
+  do { 
+    if ((res = mp_div(arg,&t1,&t2,NULL)) != MP_OKAY) {
+      goto E1;
+    }
+    if ((res = mp_add(&t1,&t2,&t1)) != MP_OKAY) {
+      goto E1;
+    }
+    if ((res = mp_div_2(&t1,&t1)) != MP_OKAY) {
+      goto E1;
+    }
+    /* t1 >= sqrt(arg) >= t2 at this point */
+  } while (mp_cmp_mag(&t1,&t2) == MP_GT);
+
+  mp_exch(&t1,ret);
+
+E1: mp_clear(&t2);
+E2: mp_clear(&t1);
+  return res;
+}
+
+#endif
diff --git a/libtommath/bn_mp_sub.c b/libtommath/bn_mp_sub.c
new file mode 100644
index 0000000..13cb43e
--- /dev/null
+++ b/libtommath/bn_mp_sub.c
@@ -0,0 +1,55 @@
+#include <tommath.h>
+#ifdef BN_MP_SUB_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* high level subtraction (handles signs) */
+int
+mp_sub (mp_int * a, mp_int * b, mp_int * c)
+{
+  int     sa, sb, res;
+
+  sa = a->sign;
+  sb = b->sign;
+
+  if (sa != sb) {
+    /* subtract a negative from a positive, OR */
+    /* subtract a positive from a negative. */
+    /* In either case, ADD their magnitudes, */
+    /* and use the sign of the first number. */
+    c->sign = sa;
+    res = s_mp_add (a, b, c);
+  } else {
+    /* subtract a positive from a positive, OR */
+    /* subtract a negative from a negative. */
+    /* First, take the difference between their */
+    /* magnitudes, then... */
+    if (mp_cmp_mag (a, b) != MP_LT) {
+      /* Copy the sign from the first */
+      c->sign = sa;
+      /* The first has a larger or equal magnitude */
+      res = s_mp_sub (a, b, c);
+    } else {
+      /* The result has the *opposite* sign from */
+      /* the first number. */
+      c->sign = (sa == MP_ZPOS) ? MP_NEG : MP_ZPOS;
+      /* The second has a larger magnitude */
+      res = s_mp_sub (b, a, c);
+    }
+  }
+  return res;
+}
+
+#endif
diff --git a/libtommath/bn_mp_sub_d.c b/libtommath/bn_mp_sub_d.c
new file mode 100644
index 0000000..b1e4e3f
--- /dev/null
+++ b/libtommath/bn_mp_sub_d.c
@@ -0,0 +1,89 @@
+#include <tommath.h>
+#ifdef BN_MP_SUB_D_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* single digit subtraction */
+int
+mp_sub_d (mp_int * a, mp_digit b, mp_int * c)
+{
+  mp_digit *tmpa, *tmpc, mu;
+  int       res, ix, oldused;
+
+  /* grow c as required */
+  if (c->alloc < a->used + 1) {
+     if ((res = mp_grow(c, a->used + 1)) != MP_OKAY) {
+        return res;
+     }
+  }
+
+  /* if a is negative just do an unsigned
+   * addition [with fudged signs]
+   */
+  if (a->sign == MP_NEG) {
+     a->sign = MP_ZPOS;
+     res     = mp_add_d(a, b, c);
+     a->sign = c->sign = MP_NEG;
+
+     /* clamp */
+     mp_clamp(c);
+
+     return res;
+  }
+
+  /* setup regs */
+  oldused = c->used;
+  tmpa    = a->dp;
+  tmpc    = c->dp;
+
+  /* if a <= b simply fix the single digit */
+  if ((a->used == 1 && a->dp[0] <= b) || a->used == 0) {
+     if (a->used == 1) {
+        *tmpc++ = b - *tmpa;
+     } else {
+        *tmpc++ = b;
+     }
+     ix      = 1;
+
+     /* negative/1digit */
+     c->sign = MP_NEG;
+     c->used = 1;
+  } else {
+     /* positive/size */
+     c->sign = MP_ZPOS;
+     c->used = a->used;
+
+     /* subtract first digit */
+     *tmpc    = *tmpa++ - b;
+     mu       = *tmpc >> (sizeof(mp_digit) * CHAR_BIT - 1);
+     *tmpc++ &= MP_MASK;
+
+     /* handle rest of the digits */
+     for (ix = 1; ix < a->used; ix++) {
+        *tmpc    = *tmpa++ - mu;
+        mu       = *tmpc >> (sizeof(mp_digit) * CHAR_BIT - 1);
+        *tmpc++ &= MP_MASK;
+     }
+  }
+
+  /* zero excess digits */
+  while (ix++ < oldused) {
+     *tmpc++ = 0;
+  }
+  mp_clamp(c);
+  return MP_OKAY;
+}
+
+#endif
diff --git a/libtommath/bn_mp_submod.c b/libtommath/bn_mp_submod.c
new file mode 100644
index 0000000..7461678
--- /dev/null
+++ b/libtommath/bn_mp_submod.c
@@ -0,0 +1,38 @@
+#include <tommath.h>
+#ifdef BN_MP_SUBMOD_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* d = a - b (mod c) */
+int
+mp_submod (mp_int * a, mp_int * b, mp_int * c, mp_int * d)
+{
+  int     res;
+  mp_int  t;
+
+
+  if ((res = mp_init (&t)) != MP_OKAY) {
+    return res;
+  }
+
+  if ((res = mp_sub (a, b, &t)) != MP_OKAY) {
+    mp_clear (&t);
+    return res;
+  }
+  res = mp_mod (&t, c, d);
+  mp_clear (&t);
+  return res;
+}
+#endif
diff --git a/libtommath/bn_mp_to_signed_bin.c b/libtommath/bn_mp_to_signed_bin.c
new file mode 100644
index 0000000..7871921
--- /dev/null
+++ b/libtommath/bn_mp_to_signed_bin.c
@@ -0,0 +1,29 @@
+#include <tommath.h>
+#ifdef BN_MP_TO_SIGNED_BIN_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* store in signed [big endian] format */
+int mp_to_signed_bin (mp_int * a, unsigned char *b)
+{
+  int     res;
+
+  if ((res = mp_to_unsigned_bin (a, b + 1)) != MP_OKAY) {
+    return res;
+  }
+  b[0] = (unsigned char) ((a->sign == MP_ZPOS) ? 0 : 1);
+  return MP_OKAY;
+}
+#endif
diff --git a/libtommath/bn_mp_to_signed_bin_n.c b/libtommath/bn_mp_to_signed_bin_n.c
new file mode 100644
index 0000000..8da9961
--- /dev/null
+++ b/libtommath/bn_mp_to_signed_bin_n.c
@@ -0,0 +1,27 @@
+#include <tommath.h>
+#ifdef BN_MP_TO_SIGNED_BIN_N_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* store in signed [big endian] format */
+int mp_to_signed_bin_n (mp_int * a, unsigned char *b, unsigned long *outlen)
+{
+   if (*outlen < (unsigned long)mp_signed_bin_size(a)) {
+      return MP_VAL;
+   }
+   *outlen = mp_signed_bin_size(a);
+   return mp_to_signed_bin(a, b);
+}
+#endif
diff --git a/libtommath/bn_mp_to_unsigned_bin.c b/libtommath/bn_mp_to_unsigned_bin.c
new file mode 100644
index 0000000..9496398
--- /dev/null
+++ b/libtommath/bn_mp_to_unsigned_bin.c
@@ -0,0 +1,44 @@
+#include <tommath.h>
+#ifdef BN_MP_TO_UNSIGNED_BIN_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* store in unsigned [big endian] format */
+int mp_to_unsigned_bin (mp_int * a, unsigned char *b)
+{
+  int     x, res;
+  mp_int  t;
+
+  if ((res = mp_init_copy (&t, a)) != MP_OKAY) {
+    return res;
+  }
+
+  x = 0;
+  while (mp_iszero (&t) == 0) {
+#ifndef MP_8BIT
+      b[x++] = (unsigned char) (t.dp[0] & 255);
+#else
+      b[x++] = (unsigned char) (t.dp[0] | ((t.dp[1] & 0x01) << 7));
+#endif
+    if ((res = mp_div_2d (&t, 8, &t, NULL)) != MP_OKAY) {
+      mp_clear (&t);
+      return res;
+    }
+  }
+  bn_reverse (b, x);
+  mp_clear (&t);
+  return MP_OKAY;
+}
+#endif
diff --git a/libtommath/bn_mp_to_unsigned_bin_n.c b/libtommath/bn_mp_to_unsigned_bin_n.c
new file mode 100644
index 0000000..4f2a31d
--- /dev/null
+++ b/libtommath/bn_mp_to_unsigned_bin_n.c
@@ -0,0 +1,27 @@
+#include <tommath.h>
+#ifdef BN_MP_TO_UNSIGNED_BIN_N_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* store in unsigned [big endian] format */
+int mp_to_unsigned_bin_n (mp_int * a, unsigned char *b, unsigned long *outlen)
+{
+   if (*outlen < (unsigned long)mp_unsigned_bin_size(a)) {
+      return MP_VAL;
+   }
+   *outlen = mp_unsigned_bin_size(a);
+   return mp_to_unsigned_bin(a, b);
+}
+#endif
diff --git a/libtommath/bn_mp_toom_mul.c b/libtommath/bn_mp_toom_mul.c
new file mode 100644
index 0000000..9daefbd
--- /dev/null
+++ b/libtommath/bn_mp_toom_mul.c
@@ -0,0 +1,280 @@
+#include <tommath.h>
+#ifdef BN_MP_TOOM_MUL_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* multiplication using the Toom-Cook 3-way algorithm 
+ *
+ * Much more complicated than Karatsuba but has a lower 
+ * asymptotic running time of O(N**1.464).  This algorithm is 
+ * only particularly useful on VERY large inputs 
+ * (we're talking 1000s of digits here...).
+*/
+int mp_toom_mul(mp_int *a, mp_int *b, mp_int *c)
+{
+    mp_int w0, w1, w2, w3, w4, tmp1, tmp2, a0, a1, a2, b0, b1, b2;
+    int res, B;
+        
+    /* init temps */
+    if ((res = mp_init_multi(&w0, &w1, &w2, &w3, &w4, 
+                             &a0, &a1, &a2, &b0, &b1, 
+                             &b2, &tmp1, &tmp2, NULL)) != MP_OKAY) {
+       return res;
+    }
+    
+    /* B */
+    B = MIN(a->used, b->used) / 3;
+    
+    /* a = a2 * B**2 + a1 * B + a0 */
+    if ((res = mp_mod_2d(a, DIGIT_BIT * B, &a0)) != MP_OKAY) {
+       goto ERR;
+    }
+
+    if ((res = mp_copy(a, &a1)) != MP_OKAY) {
+       goto ERR;
+    }
+    mp_rshd(&a1, B);
+    mp_mod_2d(&a1, DIGIT_BIT * B, &a1);
+
+    if ((res = mp_copy(a, &a2)) != MP_OKAY) {
+       goto ERR;
+    }
+    mp_rshd(&a2, B*2);
+    
+    /* b = b2 * B**2 + b1 * B + b0 */
+    if ((res = mp_mod_2d(b, DIGIT_BIT * B, &b0)) != MP_OKAY) {
+       goto ERR;
+    }
+
+    if ((res = mp_copy(b, &b1)) != MP_OKAY) {
+       goto ERR;
+    }
+    mp_rshd(&b1, B);
+    mp_mod_2d(&b1, DIGIT_BIT * B, &b1);
+
+    if ((res = mp_copy(b, &b2)) != MP_OKAY) {
+       goto ERR;
+    }
+    mp_rshd(&b2, B*2);
+    
+    /* w0 = a0*b0 */
+    if ((res = mp_mul(&a0, &b0, &w0)) != MP_OKAY) {
+       goto ERR;
+    }
+    
+    /* w4 = a2 * b2 */
+    if ((res = mp_mul(&a2, &b2, &w4)) != MP_OKAY) {
+       goto ERR;
+    }
+    
+    /* w1 = (a2 + 2(a1 + 2a0))(b2 + 2(b1 + 2b0)) */
+    if ((res = mp_mul_2(&a0, &tmp1)) != MP_OKAY) {
+       goto ERR;
+    }
+    if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) {
+       goto ERR;
+    }
+    if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) {
+       goto ERR;
+    }
+    if ((res = mp_add(&tmp1, &a2, &tmp1)) != MP_OKAY) {
+       goto ERR;
+    }
+    
+    if ((res = mp_mul_2(&b0, &tmp2)) != MP_OKAY) {
+       goto ERR;
+    }
+    if ((res = mp_add(&tmp2, &b1, &tmp2)) != MP_OKAY) {
+       goto ERR;
+    }
+    if ((res = mp_mul_2(&tmp2, &tmp2)) != MP_OKAY) {
+       goto ERR;
+    }
+    if ((res = mp_add(&tmp2, &b2, &tmp2)) != MP_OKAY) {
+       goto ERR;
+    }
+    
+    if ((res = mp_mul(&tmp1, &tmp2, &w1)) != MP_OKAY) {
+       goto ERR;
+    }
+    
+    /* w3 = (a0 + 2(a1 + 2a2))(b0 + 2(b1 + 2b2)) */
+    if ((res = mp_mul_2(&a2, &tmp1)) != MP_OKAY) {
+       goto ERR;
+    }
+    if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) {
+       goto ERR;
+    }
+    if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) {
+       goto ERR;
+    }
+    if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) {
+       goto ERR;
+    }
+    
+    if ((res = mp_mul_2(&b2, &tmp2)) != MP_OKAY) {
+       goto ERR;
+    }
+    if ((res = mp_add(&tmp2, &b1, &tmp2)) != MP_OKAY) {
+       goto ERR;
+    }
+    if ((res = mp_mul_2(&tmp2, &tmp2)) != MP_OKAY) {
+       goto ERR;
+    }
+    if ((res = mp_add(&tmp2, &b0, &tmp2)) != MP_OKAY) {
+       goto ERR;
+    }
+    
+    if ((res = mp_mul(&tmp1, &tmp2, &w3)) != MP_OKAY) {
+       goto ERR;
+    }
+    
+
+    /* w2 = (a2 + a1 + a0)(b2 + b1 + b0) */
+    if ((res = mp_add(&a2, &a1, &tmp1)) != MP_OKAY) {
+       goto ERR;
+    }
+    if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) {
+       goto ERR;
+    }
+    if ((res = mp_add(&b2, &b1, &tmp2)) != MP_OKAY) {
+       goto ERR;
+    }
+    if ((res = mp_add(&tmp2, &b0, &tmp2)) != MP_OKAY) {
+       goto ERR;
+    }
+    if ((res = mp_mul(&tmp1, &tmp2, &w2)) != MP_OKAY) {
+       goto ERR;
+    }
+    
+    /* now solve the matrix 
+    
+       0  0  0  0  1
+       1  2  4  8  16
+       1  1  1  1  1
+       16 8  4  2  1
+       1  0  0  0  0
+       
+       using 12 subtractions, 4 shifts, 
+              2 small divisions and 1 small multiplication 
+     */
+     
+     /* r1 - r4 */
+     if ((res = mp_sub(&w1, &w4, &w1)) != MP_OKAY) {
+        goto ERR;
+     }
+     /* r3 - r0 */
+     if ((res = mp_sub(&w3, &w0, &w3)) != MP_OKAY) {
+        goto ERR;
+     }
+     /* r1/2 */
+     if ((res = mp_div_2(&w1, &w1)) != MP_OKAY) {
+        goto ERR;
+     }
+     /* r3/2 */
+     if ((res = mp_div_2(&w3, &w3)) != MP_OKAY) {
+        goto ERR;
+     }
+     /* r2 - r0 - r4 */
+     if ((res = mp_sub(&w2, &w0, &w2)) != MP_OKAY) {
+        goto ERR;
+     }
+     if ((res = mp_sub(&w2, &w4, &w2)) != MP_OKAY) {
+        goto ERR;
+     }
+     /* r1 - r2 */
+     if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) {
+        goto ERR;
+     }
+     /* r3 - r2 */
+     if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) {
+        goto ERR;
+     }
+     /* r1 - 8r0 */
+     if ((res = mp_mul_2d(&w0, 3, &tmp1)) != MP_OKAY) {
+        goto ERR;
+     }
+     if ((res = mp_sub(&w1, &tmp1, &w1)) != MP_OKAY) {
+        goto ERR;
+     }
+     /* r3 - 8r4 */
+     if ((res = mp_mul_2d(&w4, 3, &tmp1)) != MP_OKAY) {
+        goto ERR;
+     }
+     if ((res = mp_sub(&w3, &tmp1, &w3)) != MP_OKAY) {
+        goto ERR;
+     }
+     /* 3r2 - r1 - r3 */
+     if ((res = mp_mul_d(&w2, 3, &w2)) != MP_OKAY) {
+        goto ERR;
+     }
+     if ((res = mp_sub(&w2, &w1, &w2)) != MP_OKAY) {
+        goto ERR;
+     }
+     if ((res = mp_sub(&w2, &w3, &w2)) != MP_OKAY) {
+        goto ERR;
+     }
+     /* r1 - r2 */
+     if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) {
+        goto ERR;
+     }
+     /* r3 - r2 */
+     if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) {
+        goto ERR;
+     }
+     /* r1/3 */
+     if ((res = mp_div_3(&w1, &w1, NULL)) != MP_OKAY) {
+        goto ERR;
+     }
+     /* r3/3 */
+     if ((res = mp_div_3(&w3, &w3, NULL)) != MP_OKAY) {
+        goto ERR;
+     }
+     
+     /* at this point shift W[n] by B*n */
+     if ((res = mp_lshd(&w1, 1*B)) != MP_OKAY) {
+        goto ERR;
+     }
+     if ((res = mp_lshd(&w2, 2*B)) != MP_OKAY) {
+        goto ERR;
+     }
+     if ((res = mp_lshd(&w3, 3*B)) != MP_OKAY) {
+        goto ERR;
+     }
+     if ((res = mp_lshd(&w4, 4*B)) != MP_OKAY) {
+        goto ERR;
+     }     
+     
+     if ((res = mp_add(&w0, &w1, c)) != MP_OKAY) {
+        goto ERR;
+     }
+     if ((res = mp_add(&w2, &w3, &tmp1)) != MP_OKAY) {
+        goto ERR;
+     }
+     if ((res = mp_add(&w4, &tmp1, &tmp1)) != MP_OKAY) {
+        goto ERR;
+     }
+     if ((res = mp_add(&tmp1, c, c)) != MP_OKAY) {
+        goto ERR;
+     }     
+     
+ERR:
+     mp_clear_multi(&w0, &w1, &w2, &w3, &w4, 
+                    &a0, &a1, &a2, &b0, &b1, 
+                    &b2, &tmp1, &tmp2, NULL);
+     return res;
+}     
+     
+#endif
diff --git a/libtommath/bn_mp_toom_sqr.c b/libtommath/bn_mp_toom_sqr.c
new file mode 100644
index 0000000..9e3f79c
--- /dev/null
+++ b/libtommath/bn_mp_toom_sqr.c
@@ -0,0 +1,222 @@
+#include <tommath.h>
+#ifdef BN_MP_TOOM_SQR_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* squaring using Toom-Cook 3-way algorithm */
+int
+mp_toom_sqr(mp_int *a, mp_int *b)
+{
+    mp_int w0, w1, w2, w3, w4, tmp1, a0, a1, a2;
+    int res, B;
+
+    /* init temps */
+    if ((res = mp_init_multi(&w0, &w1, &w2, &w3, &w4, &a0, &a1, &a2, &tmp1, NULL)) != MP_OKAY) {
+       return res;
+    }
+
+    /* B */
+    B = a->used / 3;
+
+    /* a = a2 * B**2 + a1 * B + a0 */
+    if ((res = mp_mod_2d(a, DIGIT_BIT * B, &a0)) != MP_OKAY) {
+       goto ERR;
+    }
+
+    if ((res = mp_copy(a, &a1)) != MP_OKAY) {
+       goto ERR;
+    }
+    mp_rshd(&a1, B);
+    mp_mod_2d(&a1, DIGIT_BIT * B, &a1);
+
+    if ((res = mp_copy(a, &a2)) != MP_OKAY) {
+       goto ERR;
+    }
+    mp_rshd(&a2, B*2);
+
+    /* w0 = a0*a0 */
+    if ((res = mp_sqr(&a0, &w0)) != MP_OKAY) {
+       goto ERR;
+    }
+
+    /* w4 = a2 * a2 */
+    if ((res = mp_sqr(&a2, &w4)) != MP_OKAY) {
+       goto ERR;
+    }
+
+    /* w1 = (a2 + 2(a1 + 2a0))**2 */
+    if ((res = mp_mul_2(&a0, &tmp1)) != MP_OKAY) {
+       goto ERR;
+    }
+    if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) {
+       goto ERR;
+    }
+    if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) {
+       goto ERR;
+    }
+    if ((res = mp_add(&tmp1, &a2, &tmp1)) != MP_OKAY) {
+       goto ERR;
+    }
+
+    if ((res = mp_sqr(&tmp1, &w1)) != MP_OKAY) {
+       goto ERR;
+    }
+
+    /* w3 = (a0 + 2(a1 + 2a2))**2 */
+    if ((res = mp_mul_2(&a2, &tmp1)) != MP_OKAY) {
+       goto ERR;
+    }
+    if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) {
+       goto ERR;
+    }
+    if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) {
+       goto ERR;
+    }
+    if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) {
+       goto ERR;
+    }
+
+    if ((res = mp_sqr(&tmp1, &w3)) != MP_OKAY) {
+       goto ERR;
+    }
+
+
+    /* w2 = (a2 + a1 + a0)**2 */
+    if ((res = mp_add(&a2, &a1, &tmp1)) != MP_OKAY) {
+       goto ERR;
+    }
+    if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) {
+       goto ERR;
+    }
+    if ((res = mp_sqr(&tmp1, &w2)) != MP_OKAY) {
+       goto ERR;
+    }
+
+    /* now solve the matrix
+
+       0  0  0  0  1
+       1  2  4  8  16
+       1  1  1  1  1
+       16 8  4  2  1
+       1  0  0  0  0
+
+       using 12 subtractions, 4 shifts, 2 small divisions and 1 small multiplication.
+     */
+
+     /* r1 - r4 */
+     if ((res = mp_sub(&w1, &w4, &w1)) != MP_OKAY) {
+        goto ERR;
+     }
+     /* r3 - r0 */
+     if ((res = mp_sub(&w3, &w0, &w3)) != MP_OKAY) {
+        goto ERR;
+     }
+     /* r1/2 */
+     if ((res = mp_div_2(&w1, &w1)) != MP_OKAY) {
+        goto ERR;
+     }
+     /* r3/2 */
+     if ((res = mp_div_2(&w3, &w3)) != MP_OKAY) {
+        goto ERR;
+     }
+     /* r2 - r0 - r4 */
+     if ((res = mp_sub(&w2, &w0, &w2)) != MP_OKAY) {
+        goto ERR;
+     }
+     if ((res = mp_sub(&w2, &w4, &w2)) != MP_OKAY) {
+        goto ERR;
+     }
+     /* r1 - r2 */
+     if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) {
+        goto ERR;
+     }
+     /* r3 - r2 */
+     if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) {
+        goto ERR;
+     }
+     /* r1 - 8r0 */
+     if ((res = mp_mul_2d(&w0, 3, &tmp1)) != MP_OKAY) {
+        goto ERR;
+     }
+     if ((res = mp_sub(&w1, &tmp1, &w1)) != MP_OKAY) {
+        goto ERR;
+     }
+     /* r3 - 8r4 */
+     if ((res = mp_mul_2d(&w4, 3, &tmp1)) != MP_OKAY) {
+        goto ERR;
+     }
+     if ((res = mp_sub(&w3, &tmp1, &w3)) != MP_OKAY) {
+        goto ERR;
+     }
+     /* 3r2 - r1 - r3 */
+     if ((res = mp_mul_d(&w2, 3, &w2)) != MP_OKAY) {
+        goto ERR;
+     }
+     if ((res = mp_sub(&w2, &w1, &w2)) != MP_OKAY) {
+        goto ERR;
+     }
+     if ((res = mp_sub(&w2, &w3, &w2)) != MP_OKAY) {
+        goto ERR;
+     }
+     /* r1 - r2 */
+     if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) {
+        goto ERR;
+     }
+     /* r3 - r2 */
+     if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) {
+        goto ERR;
+     }
+     /* r1/3 */
+     if ((res = mp_div_3(&w1, &w1, NULL)) != MP_OKAY) {
+        goto ERR;
+     }
+     /* r3/3 */
+     if ((res = mp_div_3(&w3, &w3, NULL)) != MP_OKAY) {
+        goto ERR;
+     }
+
+     /* at this point shift W[n] by B*n */
+     if ((res = mp_lshd(&w1, 1*B)) != MP_OKAY) {
+        goto ERR;
+     }
+     if ((res = mp_lshd(&w2, 2*B)) != MP_OKAY) {
+        goto ERR;
+     }
+     if ((res = mp_lshd(&w3, 3*B)) != MP_OKAY) {
+        goto ERR;
+     }
+     if ((res = mp_lshd(&w4, 4*B)) != MP_OKAY) {
+        goto ERR;
+     }
+
+     if ((res = mp_add(&w0, &w1, b)) != MP_OKAY) {
+        goto ERR;
+     }
+     if ((res = mp_add(&w2, &w3, &tmp1)) != MP_OKAY) {
+        goto ERR;
+     }
+     if ((res = mp_add(&w4, &tmp1, &tmp1)) != MP_OKAY) {
+        goto ERR;
+     }
+     if ((res = mp_add(&tmp1, b, b)) != MP_OKAY) {
+        goto ERR;
+     }
+
+ERR:
+     mp_clear_multi(&w0, &w1, &w2, &w3, &w4, &a0, &a1, &a2, &tmp1, NULL);
+     return res;
+}
+
+#endif
diff --git a/libtommath/bn_mp_toradix.c b/libtommath/bn_mp_toradix.c
new file mode 100644
index 0000000..132743e
--- /dev/null
+++ b/libtommath/bn_mp_toradix.c
@@ -0,0 +1,71 @@
+#include <tommath.h>
+#ifdef BN_MP_TORADIX_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* stores a bignum as a ASCII string in a given radix (2..64) */
+int mp_toradix (mp_int * a, char *str, int radix)
+{
+  int     res, digs;
+  mp_int  t;
+  mp_digit d;
+  char   *_s = str;
+
+  /* check range of the radix */
+  if (radix < 2 || radix > 64) {
+    return MP_VAL;
+  }
+
+  /* quick out if its zero */
+  if (mp_iszero(a) == 1) {
+     *str++ = '0';
+     *str = '\0';
+     return MP_OKAY;
+  }
+
+  if ((res = mp_init_copy (&t, a)) != MP_OKAY) {
+    return res;
+  }
+
+  /* if it is negative output a - */
+  if (t.sign == MP_NEG) {
+    ++_s;
+    *str++ = '-';
+    t.sign = MP_ZPOS;
+  }
+
+  digs = 0;
+  while (mp_iszero (&t) == 0) {
+    if ((res = mp_div_d (&t, (mp_digit) radix, &t, &d)) != MP_OKAY) {
+      mp_clear (&t);
+      return res;
+    }
+    *str++ = mp_s_rmap[d];
+    ++digs;
+  }
+
+  /* reverse the digits of the string.  In this case _s points
+   * to the first digit [exluding the sign] of the number]
+   */
+  bn_reverse ((unsigned char *)_s, digs);
+
+  /* append a NULL so the string is properly terminated */
+  *str = '\0';
+
+  mp_clear (&t);
+  return MP_OKAY;
+}
+
+#endif
diff --git a/libtommath/bn_mp_toradix_n.c b/libtommath/bn_mp_toradix_n.c
new file mode 100644
index 0000000..dedce71
--- /dev/null
+++ b/libtommath/bn_mp_toradix_n.c
@@ -0,0 +1,84 @@
+#include <tommath.h>
+#ifdef BN_MP_TORADIX_N_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* stores a bignum as a ASCII string in a given radix (2..64) 
+ *
+ * Stores upto maxlen-1 chars and always a NULL byte 
+ */
+int mp_toradix_n(mp_int * a, char *str, int radix, int maxlen)
+{
+  int     res, digs;
+  mp_int  t;
+  mp_digit d;
+  char   *_s = str;
+
+  /* check range of the maxlen, radix */
+  if (maxlen < 2 || radix < 2 || radix > 64) {
+    return MP_VAL;
+  }
+
+  /* quick out if its zero */
+  if (mp_iszero(a) == MP_YES) {
+     *str++ = '0';
+     *str = '\0';
+     return MP_OKAY;
+  }
+
+  if ((res = mp_init_copy (&t, a)) != MP_OKAY) {
+    return res;
+  }
+
+  /* if it is negative output a - */
+  if (t.sign == MP_NEG) {
+    /* we have to reverse our digits later... but not the - sign!! */
+    ++_s;
+
+    /* store the flag and mark the number as positive */
+    *str++ = '-';
+    t.sign = MP_ZPOS;
+ 
+    /* subtract a char */
+    --maxlen;
+  }
+
+  digs = 0;
+  while (mp_iszero (&t) == 0) {
+    if (--maxlen < 1) {
+       /* no more room */
+       break;
+    }
+    if ((res = mp_div_d (&t, (mp_digit) radix, &t, &d)) != MP_OKAY) {
+      mp_clear (&t);
+      return res;
+    }
+    *str++ = mp_s_rmap[d];
+    ++digs;
+  }
+
+  /* reverse the digits of the string.  In this case _s points
+   * to the first digit [exluding the sign] of the number
+   */
+  bn_reverse ((unsigned char *)_s, digs);
+
+  /* append a NULL so the string is properly terminated */
+  *str = '\0';
+
+  mp_clear (&t);
+  return MP_OKAY;
+}
+
+#endif
diff --git a/libtommath/bn_mp_unsigned_bin_size.c b/libtommath/bn_mp_unsigned_bin_size.c
new file mode 100644
index 0000000..58c18fb
--- /dev/null
+++ b/libtommath/bn_mp_unsigned_bin_size.c
@@ -0,0 +1,24 @@
+#include <tommath.h>
+#ifdef BN_MP_UNSIGNED_BIN_SIZE_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* get the size for an unsigned equivalent */
+int mp_unsigned_bin_size (mp_int * a)
+{
+  int     size = mp_count_bits (a);
+  return (size / 8 + ((size & 7) != 0 ? 1 : 0));
+}
+#endif
diff --git a/libtommath/bn_mp_xor.c b/libtommath/bn_mp_xor.c
new file mode 100644
index 0000000..432f42e
--- /dev/null
+++ b/libtommath/bn_mp_xor.c
@@ -0,0 +1,47 @@
+#include <tommath.h>
+#ifdef BN_MP_XOR_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* XOR two ints together */
+int
+mp_xor (mp_int * a, mp_int * b, mp_int * c)
+{
+  int     res, ix, px;
+  mp_int  t, *x;
+
+  if (a->used > b->used) {
+    if ((res = mp_init_copy (&t, a)) != MP_OKAY) {
+      return res;
+    }
+    px = b->used;
+    x = b;
+  } else {
+    if ((res = mp_init_copy (&t, b)) != MP_OKAY) {
+      return res;
+    }
+    px = a->used;
+    x = a;
+  }
+
+  for (ix = 0; ix < px; ix++) {
+     t.dp[ix] ^= x->dp[ix];
+  }
+  mp_clamp (&t);
+  mp_exch (c, &t);
+  mp_clear (&t);
+  return MP_OKAY;
+}
+#endif
diff --git a/libtommath/bn_mp_zero.c b/libtommath/bn_mp_zero.c
new file mode 100644
index 0000000..d697a60
--- /dev/null
+++ b/libtommath/bn_mp_zero.c
@@ -0,0 +1,32 @@
+#include <tommath.h>
+#ifdef BN_MP_ZERO_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* set to zero */
+void mp_zero (mp_int * a)
+{
+  int       n;
+  mp_digit *tmp;
+
+  a->sign = MP_ZPOS;
+  a->used = 0;
+
+  tmp = a->dp;
+  for (n = 0; n < a->alloc; n++) {
+     *tmp++ = 0;
+  }
+}
+#endif
diff --git a/libtommath/bn_prime_tab.c b/libtommath/bn_prime_tab.c
new file mode 100644
index 0000000..c47c8bd
--- /dev/null
+++ b/libtommath/bn_prime_tab.c
@@ -0,0 +1,57 @@
+#include <tommath.h>
+#ifdef BN_PRIME_TAB_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+const mp_digit ltm_prime_tab[] = {
+  0x0002, 0x0003, 0x0005, 0x0007, 0x000B, 0x000D, 0x0011, 0x0013,
+  0x0017, 0x001D, 0x001F, 0x0025, 0x0029, 0x002B, 0x002F, 0x0035,
+  0x003B, 0x003D, 0x0043, 0x0047, 0x0049, 0x004F, 0x0053, 0x0059,
+  0x0061, 0x0065, 0x0067, 0x006B, 0x006D, 0x0071, 0x007F,
+#ifndef MP_8BIT
+  0x0083,
+  0x0089, 0x008B, 0x0095, 0x0097, 0x009D, 0x00A3, 0x00A7, 0x00AD,
+  0x00B3, 0x00B5, 0x00BF, 0x00C1, 0x00C5, 0x00C7, 0x00D3, 0x00DF,
+  0x00E3, 0x00E5, 0x00E9, 0x00EF, 0x00F1, 0x00FB, 0x0101, 0x0107,
+  0x010D, 0x010F, 0x0115, 0x0119, 0x011B, 0x0125, 0x0133, 0x0137,
+
+  0x0139, 0x013D, 0x014B, 0x0151, 0x015B, 0x015D, 0x0161, 0x0167,
+  0x016F, 0x0175, 0x017B, 0x017F, 0x0185, 0x018D, 0x0191, 0x0199,
+  0x01A3, 0x01A5, 0x01AF, 0x01B1, 0x01B7, 0x01BB, 0x01C1, 0x01C9,
+  0x01CD, 0x01CF, 0x01D3, 0x01DF, 0x01E7, 0x01EB, 0x01F3, 0x01F7,
+  0x01FD, 0x0209, 0x020B, 0x021D, 0x0223, 0x022D, 0x0233, 0x0239,
+  0x023B, 0x0241, 0x024B, 0x0251, 0x0257, 0x0259, 0x025F, 0x0265,
+  0x0269, 0x026B, 0x0277, 0x0281, 0x0283, 0x0287, 0x028D, 0x0293,
+  0x0295, 0x02A1, 0x02A5, 0x02AB, 0x02B3, 0x02BD, 0x02C5, 0x02CF,
+
+  0x02D7, 0x02DD, 0x02E3, 0x02E7, 0x02EF, 0x02F5, 0x02F9, 0x0301,
+  0x0305, 0x0313, 0x031D, 0x0329, 0x032B, 0x0335, 0x0337, 0x033B,
+  0x033D, 0x0347, 0x0355, 0x0359, 0x035B, 0x035F, 0x036D, 0x0371,
+  0x0373, 0x0377, 0x038B, 0x038F, 0x0397, 0x03A1, 0x03A9, 0x03AD,
+  0x03B3, 0x03B9, 0x03C7, 0x03CB, 0x03D1, 0x03D7, 0x03DF, 0x03E5,
+  0x03F1, 0x03F5, 0x03FB, 0x03FD, 0x0407, 0x0409, 0x040F, 0x0419,
+  0x041B, 0x0425, 0x0427, 0x042D, 0x043F, 0x0443, 0x0445, 0x0449,
+  0x044F, 0x0455, 0x045D, 0x0463, 0x0469, 0x047F, 0x0481, 0x048B,
+
+  0x0493, 0x049D, 0x04A3, 0x04A9, 0x04B1, 0x04BD, 0x04C1, 0x04C7,
+  0x04CD, 0x04CF, 0x04D5, 0x04E1, 0x04EB, 0x04FD, 0x04FF, 0x0503,
+  0x0509, 0x050B, 0x0511, 0x0515, 0x0517, 0x051B, 0x0527, 0x0529,
+  0x052F, 0x0551, 0x0557, 0x055D, 0x0565, 0x0577, 0x0581, 0x058F,
+  0x0593, 0x0595, 0x0599, 0x059F, 0x05A7, 0x05AB, 0x05AD, 0x05B3,
+  0x05BF, 0x05C9, 0x05CB, 0x05CF, 0x05D1, 0x05D5, 0x05DB, 0x05E7,
+  0x05F3, 0x05FB, 0x0607, 0x060D, 0x0611, 0x0617, 0x061F, 0x0623,
+  0x062B, 0x062F, 0x063D, 0x0641, 0x0647, 0x0649, 0x064D, 0x0653
+#endif
+};
+#endif
diff --git a/libtommath/bn_reverse.c b/libtommath/bn_reverse.c
new file mode 100644
index 0000000..9d7fd29
--- /dev/null
+++ b/libtommath/bn_reverse.c
@@ -0,0 +1,35 @@
+#include <tommath.h>
+#ifdef BN_REVERSE_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* reverse an array, used for radix code */
+void
+bn_reverse (unsigned char *s, int len)
+{
+  int     ix, iy;
+  unsigned char t;
+
+  ix = 0;
+  iy = len - 1;
+  while (ix < iy) {
+    t     = s[ix];
+    s[ix] = s[iy];
+    s[iy] = t;
+    ++ix;
+    --iy;
+  }
+}
+#endif
diff --git a/libtommath/bn_s_mp_add.c b/libtommath/bn_s_mp_add.c
new file mode 100644
index 0000000..7527bf8
--- /dev/null
+++ b/libtommath/bn_s_mp_add.c
@@ -0,0 +1,105 @@
+#include <tommath.h>
+#ifdef BN_S_MP_ADD_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* low level addition, based on HAC pp.594, Algorithm 14.7 */
+int
+s_mp_add (mp_int * a, mp_int * b, mp_int * c)
+{
+  mp_int *x;
+  int     olduse, res, min, max;
+
+  /* find sizes, we let |a| <= |b| which means we have to sort
+   * them.  "x" will point to the input with the most digits
+   */
+  if (a->used > b->used) {
+    min = b->used;
+    max = a->used;
+    x = a;
+  } else {
+    min = a->used;
+    max = b->used;
+    x = b;
+  }
+
+  /* init result */
+  if (c->alloc < max + 1) {
+    if ((res = mp_grow (c, max + 1)) != MP_OKAY) {
+      return res;
+    }
+  }
+
+  /* get old used digit count and set new one */
+  olduse = c->used;
+  c->used = max + 1;
+
+  {
+    register mp_digit u, *tmpa, *tmpb, *tmpc;
+    register int i;
+
+    /* alias for digit pointers */
+
+    /* first input */
+    tmpa = a->dp;
+
+    /* second input */
+    tmpb = b->dp;
+
+    /* destination */
+    tmpc = c->dp;
+
+    /* zero the carry */
+    u = 0;
+    for (i = 0; i < min; i++) {
+      /* Compute the sum at one digit, T[i] = A[i] + B[i] + U */
+      *tmpc = *tmpa++ + *tmpb++ + u;
+
+      /* U = carry bit of T[i] */
+      u = *tmpc >> ((mp_digit)DIGIT_BIT);
+
+      /* take away carry bit from T[i] */
+      *tmpc++ &= MP_MASK;
+    }
+
+    /* now copy higher words if any, that is in A+B 
+     * if A or B has more digits add those in 
+     */
+    if (min != max) {
+      for (; i < max; i++) {
+        /* T[i] = X[i] + U */
+        *tmpc = x->dp[i] + u;
+
+        /* U = carry bit of T[i] */
+        u = *tmpc >> ((mp_digit)DIGIT_BIT);
+
+        /* take away carry bit from T[i] */
+        *tmpc++ &= MP_MASK;
+      }
+    }
+
+    /* add carry */
+    *tmpc++ = u;
+
+    /* clear digits above oldused */
+    for (i = c->used; i < olduse; i++) {
+      *tmpc++ = 0;
+    }
+  }
+
+  mp_clamp (c);
+  return MP_OKAY;
+}
+#endif
diff --git a/libtommath/bn_s_mp_exptmod.c b/libtommath/bn_s_mp_exptmod.c
new file mode 100644
index 0000000..ff6bd54
--- /dev/null
+++ b/libtommath/bn_s_mp_exptmod.c
@@ -0,0 +1,248 @@
+#include <tommath.h>
+#ifdef BN_S_MP_EXPTMOD_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+#ifdef MP_LOW_MEM
+   #define TAB_SIZE 32
+#else
+   #define TAB_SIZE 256
+#endif
+
+int s_mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int redmode)
+{
+  mp_int  M[TAB_SIZE], res, mu;
+  mp_digit buf;
+  int     err, bitbuf, bitcpy, bitcnt, mode, digidx, x, y, winsize;
+  int (*redux)(mp_int*,mp_int*,mp_int*);
+
+  /* find window size */
+  x = mp_count_bits (X);
+  if (x <= 7) {
+    winsize = 2;
+  } else if (x <= 36) {
+    winsize = 3;
+  } else if (x <= 140) {
+    winsize = 4;
+  } else if (x <= 450) {
+    winsize = 5;
+  } else if (x <= 1303) {
+    winsize = 6;
+  } else if (x <= 3529) {
+    winsize = 7;
+  } else {
+    winsize = 8;
+  }
+
+#ifdef MP_LOW_MEM
+    if (winsize > 5) {
+       winsize = 5;
+    }
+#endif
+
+  /* init M array */
+  /* init first cell */
+  if ((err = mp_init(&M[1])) != MP_OKAY) {
+     return err; 
+  }
+
+  /* now init the second half of the array */
+  for (x = 1<<(winsize-1); x < (1 << winsize); x++) {
+    if ((err = mp_init(&M[x])) != MP_OKAY) {
+      for (y = 1<<(winsize-1); y < x; y++) {
+        mp_clear (&M[y]);
+      }
+      mp_clear(&M[1]);
+      return err;
+    }
+  }
+
+  /* create mu, used for Barrett reduction */
+  if ((err = mp_init (&mu)) != MP_OKAY) {
+    goto LBL_M;
+  }
+  
+  if (redmode == 0) {
+     if ((err = mp_reduce_setup (&mu, P)) != MP_OKAY) {
+        goto LBL_MU;
+     }
+     redux = mp_reduce;
+  } else {
+     if ((err = mp_reduce_2k_setup_l (P, &mu)) != MP_OKAY) {
+        goto LBL_MU;
+     }
+     redux = mp_reduce_2k_l;
+  }    
+
+  /* create M table
+   *
+   * The M table contains powers of the base, 
+   * e.g. M[x] = G**x mod P
+   *
+   * The first half of the table is not 
+   * computed though accept for M[0] and M[1]
+   */
+  if ((err = mp_mod (G, P, &M[1])) != MP_OKAY) {
+    goto LBL_MU;
+  }
+
+  /* compute the value at M[1<<(winsize-1)] by squaring 
+   * M[1] (winsize-1) times 
+   */
+  if ((err = mp_copy (&M[1], &M[1 << (winsize - 1)])) != MP_OKAY) {
+    goto LBL_MU;
+  }
+
+  for (x = 0; x < (winsize - 1); x++) {
+    /* square it */
+    if ((err = mp_sqr (&M[1 << (winsize - 1)], 
+                       &M[1 << (winsize - 1)])) != MP_OKAY) {
+      goto LBL_MU;
+    }
+
+    /* reduce modulo P */
+    if ((err = redux (&M[1 << (winsize - 1)], P, &mu)) != MP_OKAY) {
+      goto LBL_MU;
+    }
+  }
+
+  /* create upper table, that is M[x] = M[x-1] * M[1] (mod P)
+   * for x = (2**(winsize - 1) + 1) to (2**winsize - 1)
+   */
+  for (x = (1 << (winsize - 1)) + 1; x < (1 << winsize); x++) {
+    if ((err = mp_mul (&M[x - 1], &M[1], &M[x])) != MP_OKAY) {
+      goto LBL_MU;
+    }
+    if ((err = redux (&M[x], P, &mu)) != MP_OKAY) {
+      goto LBL_MU;
+    }
+  }
+
+  /* setup result */
+  if ((err = mp_init (&res)) != MP_OKAY) {
+    goto LBL_MU;
+  }
+  mp_set (&res, 1);
+
+  /* set initial mode and bit cnt */
+  mode   = 0;
+  bitcnt = 1;
+  buf    = 0;
+  digidx = X->used - 1;
+  bitcpy = 0;
+  bitbuf = 0;
+
+  for (;;) {
+    /* grab next digit as required */
+    if (--bitcnt == 0) {
+      /* if digidx == -1 we are out of digits */
+      if (digidx == -1) {
+        break;
+      }
+      /* read next digit and reset the bitcnt */
+      buf    = X->dp[digidx--];
+      bitcnt = (int) DIGIT_BIT;
+    }
+
+    /* grab the next msb from the exponent */
+    y     = (buf >> (mp_digit)(DIGIT_BIT - 1)) & 1;
+    buf <<= (mp_digit)1;
+
+    /* if the bit is zero and mode == 0 then we ignore it
+     * These represent the leading zero bits before the first 1 bit
+     * in the exponent.  Technically this opt is not required but it
+     * does lower the # of trivial squaring/reductions used
+     */
+    if (mode == 0 && y == 0) {
+      continue;
+    }
+
+    /* if the bit is zero and mode == 1 then we square */
+    if (mode == 1 && y == 0) {
+      if ((err = mp_sqr (&res, &res)) != MP_OKAY) {
+        goto LBL_RES;
+      }
+      if ((err = redux (&res, P, &mu)) != MP_OKAY) {
+        goto LBL_RES;
+      }
+      continue;
+    }
+
+    /* else we add it to the window */
+    bitbuf |= (y << (winsize - ++bitcpy));
+    mode    = 2;
+
+    if (bitcpy == winsize) {
+      /* ok window is filled so square as required and multiply  */
+      /* square first */
+      for (x = 0; x < winsize; x++) {
+        if ((err = mp_sqr (&res, &res)) != MP_OKAY) {
+          goto LBL_RES;
+        }
+        if ((err = redux (&res, P, &mu)) != MP_OKAY) {
+          goto LBL_RES;
+        }
+      }
+
+      /* then multiply */
+      if ((err = mp_mul (&res, &M[bitbuf], &res)) != MP_OKAY) {
+        goto LBL_RES;
+      }
+      if ((err = redux (&res, P, &mu)) != MP_OKAY) {
+        goto LBL_RES;
+      }
+
+      /* empty window and reset */
+      bitcpy = 0;
+      bitbuf = 0;
+      mode   = 1;
+    }
+  }
+
+  /* if bits remain then square/multiply */
+  if (mode == 2 && bitcpy > 0) {
+    /* square then multiply if the bit is set */
+    for (x = 0; x < bitcpy; x++) {
+      if ((err = mp_sqr (&res, &res)) != MP_OKAY) {
+        goto LBL_RES;
+      }
+      if ((err = redux (&res, P, &mu)) != MP_OKAY) {
+        goto LBL_RES;
+      }
+
+      bitbuf <<= 1;
+      if ((bitbuf & (1 << winsize)) != 0) {
+        /* then multiply */
+        if ((err = mp_mul (&res, &M[1], &res)) != MP_OKAY) {
+          goto LBL_RES;
+        }
+        if ((err = redux (&res, P, &mu)) != MP_OKAY) {
+          goto LBL_RES;
+        }
+      }
+    }
+  }
+
+  mp_exch (&res, Y);
+  err = MP_OKAY;
+LBL_RES:mp_clear (&res);
+LBL_MU:mp_clear (&mu);
+LBL_M:
+  mp_clear(&M[1]);
+  for (x = 1<<(winsize-1); x < (1 << winsize); x++) {
+    mp_clear (&M[x]);
+  }
+  return err;
+}
+#endif
diff --git a/libtommath/bn_s_mp_mul_digs.c b/libtommath/bn_s_mp_mul_digs.c
new file mode 100644
index 0000000..401f32e
--- /dev/null
+++ b/libtommath/bn_s_mp_mul_digs.c
@@ -0,0 +1,86 @@
+#include <tommath.h>
+#ifdef BN_S_MP_MUL_DIGS_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* multiplies |a| * |b| and only computes upto digs digits of result
+ * HAC pp. 595, Algorithm 14.12  Modified so you can control how 
+ * many digits of output are created.
+ */
+int s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs)
+{
+  mp_int  t;
+  int     res, pa, pb, ix, iy;
+  mp_digit u;
+  mp_word r;
+  mp_digit tmpx, *tmpt, *tmpy;
+
+  /* can we use the fast multiplier? */
+  if (((digs) < MP_WARRAY) &&
+      MIN (a->used, b->used) < 
+          (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) {
+    return fast_s_mp_mul_digs (a, b, c, digs);
+  }
+
+  if ((res = mp_init_size (&t, digs)) != MP_OKAY) {
+    return res;
+  }
+  t.used = digs;
+
+  /* compute the digits of the product directly */
+  pa = a->used;
+  for (ix = 0; ix < pa; ix++) {
+    /* set the carry to zero */
+    u = 0;
+
+    /* limit ourselves to making digs digits of output */
+    pb = MIN (b->used, digs - ix);
+
+    /* setup some aliases */
+    /* copy of the digit from a used within the nested loop */
+    tmpx = a->dp[ix];
+    
+    /* an alias for the destination shifted ix places */
+    tmpt = t.dp + ix;
+    
+    /* an alias for the digits of b */
+    tmpy = b->dp;
+
+    /* compute the columns of the output and propagate the carry */
+    for (iy = 0; iy < pb; iy++) {
+      /* compute the column as a mp_word */
+      r       = ((mp_word)*tmpt) +
+                ((mp_word)tmpx) * ((mp_word)*tmpy++) +
+                ((mp_word) u);
+
+      /* the new column is the lower part of the result */
+      *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK));
+
+      /* get the carry word from the result */
+      u       = (mp_digit) (r >> ((mp_word) DIGIT_BIT));
+    }
+    /* set carry if it is placed below digs */
+    if (ix + iy < digs) {
+      *tmpt = u;
+    }
+  }
+
+  mp_clamp (&t);
+  mp_exch (&t, c);
+
+  mp_clear (&t);
+  return MP_OKAY;
+}
+#endif
diff --git a/libtommath/bn_s_mp_mul_high_digs.c b/libtommath/bn_s_mp_mul_high_digs.c
new file mode 100644
index 0000000..f4dca76
--- /dev/null
+++ b/libtommath/bn_s_mp_mul_high_digs.c
@@ -0,0 +1,77 @@
+#include <tommath.h>
+#ifdef BN_S_MP_MUL_HIGH_DIGS_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* multiplies |a| * |b| and does not compute the lower digs digits
+ * [meant to get the higher part of the product]
+ */
+int
+s_mp_mul_high_digs (mp_int * a, mp_int * b, mp_int * c, int digs)
+{
+  mp_int  t;
+  int     res, pa, pb, ix, iy;
+  mp_digit u;
+  mp_word r;
+  mp_digit tmpx, *tmpt, *tmpy;
+
+  /* can we use the fast multiplier? */
+#ifdef BN_FAST_S_MP_MUL_HIGH_DIGS_C
+  if (((a->used + b->used + 1) < MP_WARRAY)
+      && MIN (a->used, b->used) < (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) {
+    return fast_s_mp_mul_high_digs (a, b, c, digs);
+  }
+#endif
+
+  if ((res = mp_init_size (&t, a->used + b->used + 1)) != MP_OKAY) {
+    return res;
+  }
+  t.used = a->used + b->used + 1;
+
+  pa = a->used;
+  pb = b->used;
+  for (ix = 0; ix < pa; ix++) {
+    /* clear the carry */
+    u = 0;
+
+    /* left hand side of A[ix] * B[iy] */
+    tmpx = a->dp[ix];
+
+    /* alias to the address of where the digits will be stored */
+    tmpt = &(t.dp[digs]);
+
+    /* alias for where to read the right hand side from */
+    tmpy = b->dp + (digs - ix);
+
+    for (iy = digs - ix; iy < pb; iy++) {
+      /* calculate the double precision result */
+      r       = ((mp_word)*tmpt) +
+                ((mp_word)tmpx) * ((mp_word)*tmpy++) +
+                ((mp_word) u);
+
+      /* get the lower part */
+      *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK));
+
+      /* carry the carry */
+      u       = (mp_digit) (r >> ((mp_word) DIGIT_BIT));
+    }
+    *tmpt = u;
+  }
+  mp_clamp (&t);
+  mp_exch (&t, c);
+  mp_clear (&t);
+  return MP_OKAY;
+}
+#endif
diff --git a/libtommath/bn_s_mp_sqr.c b/libtommath/bn_s_mp_sqr.c
new file mode 100644
index 0000000..464663f
--- /dev/null
+++ b/libtommath/bn_s_mp_sqr.c
@@ -0,0 +1,80 @@
+#include <tommath.h>
+#ifdef BN_S_MP_SQR_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* low level squaring, b = a*a, HAC pp.596-597, Algorithm 14.16 */
+int s_mp_sqr (mp_int * a, mp_int * b)
+{
+  mp_int  t;
+  int     res, ix, iy, pa;
+  mp_word r;
+  mp_digit u, tmpx, *tmpt;
+
+  pa = a->used;
+  if ((res = mp_init_size (&t, 2*pa + 1)) != MP_OKAY) {
+    return res;
+  }
+
+  /* default used is maximum possible size */
+  t.used = 2*pa + 1;
+
+  for (ix = 0; ix < pa; ix++) {
+    /* first calculate the digit at 2*ix */
+    /* calculate double precision result */
+    r = ((mp_word) t.dp[2*ix]) +
+        ((mp_word)a->dp[ix])*((mp_word)a->dp[ix]);
+
+    /* store lower part in result */
+    t.dp[ix+ix] = (mp_digit) (r & ((mp_word) MP_MASK));
+
+    /* get the carry */
+    u           = (mp_digit)(r >> ((mp_word) DIGIT_BIT));
+
+    /* left hand side of A[ix] * A[iy] */
+    tmpx        = a->dp[ix];
+
+    /* alias for where to store the results */
+    tmpt        = t.dp + (2*ix + 1);
+    
+    for (iy = ix + 1; iy < pa; iy++) {
+      /* first calculate the product */
+      r       = ((mp_word)tmpx) * ((mp_word)a->dp[iy]);
+
+      /* now calculate the double precision result, note we use
+       * addition instead of *2 since it's easier to optimize
+       */
+      r       = ((mp_word) *tmpt) + r + r + ((mp_word) u);
+
+      /* store lower part */
+      *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK));
+
+      /* get carry */
+      u       = (mp_digit)(r >> ((mp_word) DIGIT_BIT));
+    }
+    /* propagate upwards */
+    while (u != ((mp_digit) 0)) {
+      r       = ((mp_word) *tmpt) + ((mp_word) u);
+      *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK));
+      u       = (mp_digit)(r >> ((mp_word) DIGIT_BIT));
+    }
+  }
+
+  mp_clamp (&t);
+  mp_exch (&t, b);
+  mp_clear (&t);
+  return MP_OKAY;
+}
+#endif
diff --git a/libtommath/bn_s_mp_sub.c b/libtommath/bn_s_mp_sub.c
new file mode 100644
index 0000000..328c9e5
--- /dev/null
+++ b/libtommath/bn_s_mp_sub.c
@@ -0,0 +1,85 @@
+#include <tommath.h>
+#ifdef BN_S_MP_SUB_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* low level subtraction (assumes |a| > |b|), HAC pp.595 Algorithm 14.9 */
+int
+s_mp_sub (mp_int * a, mp_int * b, mp_int * c)
+{
+  int     olduse, res, min, max;
+
+  /* find sizes */
+  min = b->used;
+  max = a->used;
+
+  /* init result */
+  if (c->alloc < max) {
+    if ((res = mp_grow (c, max)) != MP_OKAY) {
+      return res;
+    }
+  }
+  olduse = c->used;
+  c->used = max;
+
+  {
+    register mp_digit u, *tmpa, *tmpb, *tmpc;
+    register int i;
+
+    /* alias for digit pointers */
+    tmpa = a->dp;
+    tmpb = b->dp;
+    tmpc = c->dp;
+
+    /* set carry to zero */
+    u = 0;
+    for (i = 0; i < min; i++) {
+      /* T[i] = A[i] - B[i] - U */
+      *tmpc = *tmpa++ - *tmpb++ - u;
+
+      /* U = carry bit of T[i]
+       * Note this saves performing an AND operation since
+       * if a carry does occur it will propagate all the way to the
+       * MSB.  As a result a single shift is enough to get the carry
+       */
+      u = *tmpc >> ((mp_digit)(CHAR_BIT * sizeof (mp_digit) - 1));
+
+      /* Clear carry from T[i] */
+      *tmpc++ &= MP_MASK;
+    }
+
+    /* now copy higher words if any, e.g. if A has more digits than B  */
+    for (; i < max; i++) {
+      /* T[i] = A[i] - U */
+      *tmpc = *tmpa++ - u;
+
+      /* U = carry bit of T[i] */
+      u = *tmpc >> ((mp_digit)(CHAR_BIT * sizeof (mp_digit) - 1));
+
+      /* Clear carry from T[i] */
+      *tmpc++ &= MP_MASK;
+    }
+
+    /* clear digits above used (since we may not have grown result above) */
+    for (i = c->used; i < olduse; i++) {
+      *tmpc++ = 0;
+    }
+  }
+
+  mp_clamp (c);
+  return MP_OKAY;
+}
+
+#endif
diff --git a/libtommath/bncore.c b/libtommath/bncore.c
new file mode 100644
index 0000000..eb95a2e
--- /dev/null
+++ b/libtommath/bncore.c
@@ -0,0 +1,32 @@
+#include <tommath.h>
+#ifdef BNCORE_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* Known optimal configurations
+
+ CPU                    /Compiler     /MUL CUTOFF/SQR CUTOFF
+-------------------------------------------------------------
+ Intel P4 Northwood     /GCC v3.4.1   /        88/       128/LTM 0.32 ;-)
+ AMD Athlon64           /GCC v3.4.4   /        80/       120/LTM 0.35
+ 
+*/
+
+int     KARATSUBA_MUL_CUTOFF = 80,      /* Min. number of digits before Karatsuba multiplication is used. */
+        KARATSUBA_SQR_CUTOFF = 120,     /* Min. number of digits before Karatsuba squaring is used. */
+        
+        TOOM_MUL_CUTOFF      = 350,      /* no optimal values of these are known yet so set em high */
+        TOOM_SQR_CUTOFF      = 400; 
+#endif
diff --git a/libtommath/booker.pl b/libtommath/booker.pl
new file mode 100644
index 0000000..df8b30d
--- /dev/null
+++ b/libtommath/booker.pl
@@ -0,0 +1,265 @@
+#!/bin/perl
+#
+#Used to prepare the book "tommath.src" for LaTeX by pre-processing it into a .tex file
+#
+#Essentially you write the "tommath.src" as normal LaTex except where you want code snippets you put
+#
+#EXAM,file
+#
+#This preprocessor will then open "file" and insert it as a verbatim copy.
+#
+#Tom St Denis
+
+#get graphics type
+if (shift =~ /PDF/) {
+   $graph = "";
+} else {
+   $graph = ".ps";
+}   
+
+open(IN,"<tommath.src") or die "Can't open source file";
+open(OUT,">tommath.tex") or die "Can't open destination file";
+
+print "Scanning for sections\n";
+$chapter = $section = $subsection = 0;
+$x = 0;
+while (<IN>) {
+   print ".";
+   if (!(++$x % 80)) { print "\n"; }
+   #update the headings 
+   if (~($_ =~ /\*/)) {
+      if ($_ =~ /\\chapter{.+}/) {
+          ++$chapter;
+          $section = $subsection = 0;
+      } elsif ($_ =~ /\\section{.+}/) {
+          ++$section;
+          $subsection = 0;
+      } elsif ($_ =~ /\\subsection{.+}/) {
+          ++$subsection;
+      }
+   }      
+
+   if ($_ =~ m/MARK/) {
+      @m = split(",",$_);
+      chomp(@m[1]);
+      $index1{@m[1]} = $chapter;
+      $index2{@m[1]} = $section;
+      $index3{@m[1]} = $subsection;
+   }
+}
+close(IN);
+
+open(IN,"<tommath.src") or die "Can't open source file";
+$readline = $wroteline = 0;
+$srcline = 0;
+
+while (<IN>) {
+   ++$readline;
+   ++$srcline;
+   
+   if ($_ =~ m/MARK/) {
+   } elsif ($_ =~ m/EXAM/ || $_ =~ m/LIST/) {
+      if ($_ =~ m/EXAM/) {
+         $skipheader = 1;
+      } else {
+         $skipheader = 0;
+      }
+      
+      # EXAM,file
+      chomp($_);
+      @m = split(",",$_);
+      open(SRC,"<$m[1]") or die "Error:$srcline:Can't open source file $m[1]";
+      
+      print "$srcline:Inserting $m[1]:";
+      
+      $line = 0;
+      $tmp = $m[1];
+      $tmp =~ s/_/"\\_"/ge;
+      print OUT "\\vspace{+3mm}\\begin{small}\n\\hspace{-5.1mm}{\\bf File}: $tmp\n\\vspace{-3mm}\n\\begin{alltt}\n";
+      $wroteline += 5;
+      
+      if ($skipheader == 1) {
+         # scan till next end of comment, e.g. skip license 
+         while (<SRC>) {
+            $text[$line++] = $_;
+            last if ($_ =~ /math\.libtomcrypt\.org/);
+         }
+         <SRC>;   
+      }
+      
+      $inline = 0;
+      while (<SRC>) {
+      next if ($_ =~ /\$Source/);
+      next if ($_ =~ /\$Revision/);
+      next if ($_ =~ /\$Date/);
+         $text[$line++] = $_;
+         ++$inline;
+         chomp($_);
+         $_ =~ s/\t/"    "/ge;
+         $_ =~ s/{/"^{"/ge;
+         $_ =~ s/}/"^}"/ge;
+         $_ =~ s/\\/'\symbol{92}'/ge;
+         $_ =~ s/\^/"\\"/ge;
+           
+         printf OUT ("%03d   ", $line);
+         for ($x = 0; $x < length($_); $x++) {
+             print OUT chr(vec($_, $x, 8));
+             if ($x == 75) { 
+                 print OUT "\n      ";
+                 ++$wroteline;
+             }
+         }
+         print OUT "\n";
+         ++$wroteline;
+      }
+      $totlines = $line;
+      print OUT "\\end{alltt}\n\\end{small}\n";
+      close(SRC);
+      print "$inline lines\n";
+      $wroteline += 2;
+   } elsif ($_ =~ m/@\d+,.+@/) {
+     # line contains [number,text]
+     # e.g. @14,for (ix = 0)@
+     $txt = $_;
+     while ($txt =~ m/@\d+,.+@/) {
+        @m = split("@",$txt);      # splits into text, one, two
+        @parms = split(",",$m[1]);  # splits one,two into two elements 
+                
+        # now search from $parms[0] down for $parms[1] 
+        $found1 = 0;
+        $found2 = 0;
+        for ($i = $parms[0]; $i < $totlines && $found1 == 0; $i++) {
+           if ($text[$i] =~ m/\Q$parms[1]\E/) {
+              $foundline1 = $i + 1;
+              $found1 = 1;
+           }
+        }
+        
+        # now search backwards
+        for ($i = $parms[0] - 1; $i >= 0 && $found2 == 0; $i--) {
+           if ($text[$i] =~ m/\Q$parms[1]\E/) {
+              $foundline2 = $i + 1;
+              $found2 = 1;
+           }
+        }
+        
+        # now use the closest match or the first if tied
+        if ($found1 == 1 && $found2 == 0) {
+           $found = 1;
+           $foundline = $foundline1;
+        } elsif ($found1 == 0 && $found2 == 1) {
+           $found = 1;
+           $foundline = $foundline2;
+        } elsif ($found1 == 1 && $found2 == 1) {
+           $found = 1;
+           if (($foundline1 - $parms[0]) <= ($parms[0] - $foundline2)) {
+              $foundline = $foundline1;
+           } else {
+              $foundline = $foundline2;
+           }
+        } else {
+           $found = 0;
+        }
+                      
+        # if found replace 
+        if ($found == 1) {
+           $delta = $parms[0] - $foundline;
+           print "Found replacement tag for \"$parms[1]\" on line $srcline which refers to line $foundline (delta $delta)\n";
+           $_ =~ s/@\Q$m[1]\E@/$foundline/;
+        } else {
+           print "ERROR:  The tag \"$parms[1]\" on line $srcline was not found in the most recently parsed source!\n";
+        }
+        
+        # remake the rest of the line 
+        $cnt = @m;
+        $txt = "";
+        for ($i = 2; $i < $cnt; $i++) {
+            $txt = $txt . $m[$i] . "@";
+        }
+     }
+     print OUT $_;
+     ++$wroteline;
+   } elsif ($_ =~ /~.+~/) {
+      # line contains a ~text~ pair used to refer to indexing :-)
+      $txt = $_;
+      while ($txt =~ /~.+~/) {
+         @m = split("~", $txt);
+         
+         # word is the second position
+         $word = @m[1];
+         $a = $index1{$word};
+         $b = $index2{$word};
+         $c = $index3{$word};
+         
+         # if chapter (a) is zero it wasn't found
+         if ($a == 0) {
+            print "ERROR: the tag \"$word\" on line $srcline was not found previously marked.\n";
+         } else {
+            # format the tag as x, x.y or x.y.z depending on the values
+            $str = $a;
+            $str = $str . ".$b" if ($b != 0);
+            $str = $str . ".$c" if ($c != 0);
+            
+            if ($b == 0 && $c == 0) {
+               # its a chapter
+               if ($a <= 10) {
+                  if ($a == 1) {
+                     $str = "chapter one";
+                  } elsif ($a == 2) {
+                     $str = "chapter two";
+                  } elsif ($a == 3) {
+                     $str = "chapter three";
+                  } elsif ($a == 4) {
+                     $str = "chapter four";
+                  } elsif ($a == 5) {
+                     $str = "chapter five";
+                  } elsif ($a == 6) {
+                     $str = "chapter six";
+                  } elsif ($a == 7) {
+                     $str = "chapter seven";
+                  } elsif ($a == 8) {
+                     $str = "chapter eight";
+                  } elsif ($a == 9) {
+                     $str = "chapter nine";
+                  } elsif ($a == 10) {
+                     $str = "chapter ten";
+                  }
+               } else {
+                  $str = "chapter " . $str;
+               }
+            } else {
+               $str = "section " . $str     if ($b != 0 && $c == 0);            
+               $str = "sub-section " . $str if ($b != 0 && $c != 0);
+            }
+            
+            #substitute
+            $_ =~ s/~\Q$word\E~/$str/;
+            
+            print "Found replacement tag for marker \"$word\" on line $srcline which refers to $str\n";
+         }
+         
+         # remake rest of the line
+         $cnt = @m;
+         $txt = "";
+         for ($i = 2; $i < $cnt; $i++) {
+             $txt = $txt . $m[$i] . "~";
+         }
+      }
+      print OUT $_;
+      ++$wroteline;
+   } elsif ($_ =~ m/FIGU/) {
+      # FIGU,file,caption
+      chomp($_);
+      @m = split(",", $_);
+      print OUT "\\begin{center}\n\\begin{figure}[here]\n\\includegraphics{pics/$m[1]$graph}\n";
+      print OUT "\\caption{$m[2]}\n\\label{pic:$m[1]}\n\\end{figure}\n\\end{center}\n";
+      $wroteline += 4;
+   } else {
+      print OUT $_;
+      ++$wroteline;
+   }
+}
+print "Read $readline lines, wrote $wroteline lines\n";
+
+close (OUT);
+close (IN);
diff --git a/libtommath/callgraph.txt b/libtommath/callgraph.txt
new file mode 100644
index 0000000..2efcf24
--- /dev/null
+++ b/libtommath/callgraph.txt
@@ -0,0 +1,11913 @@
+BN_PRIME_TAB_C
+
+
+BN_MP_SQRT_C
++--->BN_MP_N_ROOT_C
+|   +--->BN_MP_INIT_C
+|   +--->BN_MP_SET_C
+|   |   +--->BN_MP_ZERO_C
+|   +--->BN_MP_COPY_C
+|   |   +--->BN_MP_GROW_C
+|   +--->BN_MP_EXPT_D_C
+|   |   +--->BN_MP_INIT_COPY_C
+|   |   +--->BN_MP_SQR_C
+|   |   |   +--->BN_MP_TOOM_SQR_C
+|   |   |   |   +--->BN_MP_INIT_MULTI_C
+|   |   |   |   |   +--->BN_MP_CLEAR_C
+|   |   |   |   +--->BN_MP_MOD_2D_C
+|   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   +--->BN_MP_MUL_2_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_DIV_2_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_MUL_2D_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_MUL_D_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_DIV_3_C
+|   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   |   +--->BN_MP_CLEAR_C
+|   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLEAR_MULTI_C
+|   |   |   |   |   +--->BN_MP_CLEAR_C
+|   |   |   +--->BN_MP_KARATSUBA_SQR_C
+|   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLEAR_C
+|   |   |   +--->BN_FAST_S_MP_SQR_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_S_MP_SQR_C
+|   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   +--->BN_MP_CLEAR_C
+|   |   +--->BN_MP_CLEAR_C
+|   |   +--->BN_MP_MUL_C
+|   |   |   +--->BN_MP_TOOM_MUL_C
+|   |   |   |   +--->BN_MP_INIT_MULTI_C
+|   |   |   |   +--->BN_MP_MOD_2D_C
+|   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   +--->BN_MP_MUL_2_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_DIV_2_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_MUL_2D_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_MUL_D_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_DIV_3_C
+|   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLEAR_MULTI_C
+|   |   |   +--->BN_MP_KARATSUBA_MUL_C
+|   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   +--->BN_FAST_S_MP_MUL_DIGS_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_S_MP_MUL_DIGS_C
+|   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_EXCH_C
+|   +--->BN_MP_MUL_C
+|   |   +--->BN_MP_TOOM_MUL_C
+|   |   |   +--->BN_MP_INIT_MULTI_C
+|   |   |   |   +--->BN_MP_CLEAR_C
+|   |   |   +--->BN_MP_MOD_2D_C
+|   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   +--->BN_MP_MUL_2_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_ADD_C
+|   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_SUB_C
+|   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_DIV_2_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_MUL_2D_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_MUL_D_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_DIV_3_C
+|   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   +--->BN_MP_CLEAR_C
+|   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLEAR_MULTI_C
+|   |   |   |   +--->BN_MP_CLEAR_C
+|   |   +--->BN_MP_KARATSUBA_MUL_C
+|   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_SUB_C
+|   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_ADD_C
+|   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   +--->BN_MP_CLEAR_C
+|   |   +--->BN_FAST_S_MP_MUL_DIGS_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_S_MP_MUL_DIGS_C
+|   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_EXCH_C
+|   |   |   +--->BN_MP_CLEAR_C
+|   +--->BN_MP_SUB_C
+|   |   +--->BN_S_MP_ADD_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_CMP_MAG_C
+|   |   +--->BN_S_MP_SUB_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_MUL_D_C
+|   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_DIV_C
+|   |   +--->BN_MP_CMP_MAG_C
+|   |   +--->BN_MP_ZERO_C
+|   |   +--->BN_MP_INIT_MULTI_C
+|   |   |   +--->BN_MP_CLEAR_C
+|   |   +--->BN_MP_COUNT_BITS_C
+|   |   +--->BN_MP_ABS_C
+|   |   +--->BN_MP_MUL_2D_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_CMP_C
+|   |   +--->BN_MP_ADD_C
+|   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_DIV_2D_C
+|   |   |   +--->BN_MP_MOD_2D_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_CLEAR_C
+|   |   |   +--->BN_MP_RSHD_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_EXCH_C
+|   |   +--->BN_MP_EXCH_C
+|   |   +--->BN_MP_CLEAR_MULTI_C
+|   |   |   +--->BN_MP_CLEAR_C
+|   |   +--->BN_MP_INIT_SIZE_C
+|   |   +--->BN_MP_INIT_COPY_C
+|   |   +--->BN_MP_LSHD_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_RSHD_C
+|   |   +--->BN_MP_RSHD_C
+|   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_CLEAR_C
+|   +--->BN_MP_CMP_C
+|   |   +--->BN_MP_CMP_MAG_C
+|   +--->BN_MP_SUB_D_C
+|   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_ADD_D_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_EXCH_C
+|   +--->BN_MP_CLEAR_C
++--->BN_MP_ZERO_C
++--->BN_MP_INIT_COPY_C
+|   +--->BN_MP_COPY_C
+|   |   +--->BN_MP_GROW_C
++--->BN_MP_RSHD_C
++--->BN_MP_DIV_C
+|   +--->BN_MP_CMP_MAG_C
+|   +--->BN_MP_COPY_C
+|   |   +--->BN_MP_GROW_C
+|   +--->BN_MP_INIT_MULTI_C
+|   |   +--->BN_MP_CLEAR_C
+|   +--->BN_MP_SET_C
+|   +--->BN_MP_COUNT_BITS_C
+|   +--->BN_MP_ABS_C
+|   +--->BN_MP_MUL_2D_C
+|   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_LSHD_C
+|   |   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_CMP_C
+|   +--->BN_MP_SUB_C
+|   |   +--->BN_S_MP_ADD_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_S_MP_SUB_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_ADD_C
+|   |   +--->BN_S_MP_ADD_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_S_MP_SUB_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_DIV_2D_C
+|   |   +--->BN_MP_MOD_2D_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_CLEAR_C
+|   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_EXCH_C
+|   +--->BN_MP_EXCH_C
+|   +--->BN_MP_CLEAR_MULTI_C
+|   |   +--->BN_MP_CLEAR_C
+|   +--->BN_MP_INIT_SIZE_C
+|   +--->BN_MP_LSHD_C
+|   |   +--->BN_MP_GROW_C
+|   +--->BN_MP_MUL_D_C
+|   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_CLEAR_C
++--->BN_MP_ADD_C
+|   +--->BN_S_MP_ADD_C
+|   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_CMP_MAG_C
+|   +--->BN_S_MP_SUB_C
+|   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_CLAMP_C
++--->BN_MP_DIV_2_C
+|   +--->BN_MP_GROW_C
+|   +--->BN_MP_CLAMP_C
++--->BN_MP_CMP_MAG_C
++--->BN_MP_EXCH_C
++--->BN_MP_CLEAR_C
+
+
+BN_MP_CMP_D_C
+
+
+BN_MP_EXCH_C
+
+
+BN_MP_IS_SQUARE_C
++--->BN_MP_MOD_D_C
+|   +--->BN_MP_DIV_D_C
+|   |   +--->BN_MP_COPY_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_DIV_2D_C
+|   |   |   +--->BN_MP_ZERO_C
+|   |   |   +--->BN_MP_INIT_C
+|   |   |   +--->BN_MP_MOD_2D_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_CLEAR_C
+|   |   |   +--->BN_MP_RSHD_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_EXCH_C
+|   |   +--->BN_MP_DIV_3_C
+|   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   +--->BN_MP_INIT_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_EXCH_C
+|   |   |   +--->BN_MP_CLEAR_C
+|   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   +--->BN_MP_INIT_C
+|   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_EXCH_C
+|   |   +--->BN_MP_CLEAR_C
++--->BN_MP_INIT_SET_INT_C
+|   +--->BN_MP_INIT_C
+|   +--->BN_MP_SET_INT_C
+|   |   +--->BN_MP_ZERO_C
+|   |   +--->BN_MP_MUL_2D_C
+|   |   |   +--->BN_MP_COPY_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_CLAMP_C
++--->BN_MP_MOD_C
+|   +--->BN_MP_INIT_C
+|   +--->BN_MP_DIV_C
+|   |   +--->BN_MP_CMP_MAG_C
+|   |   +--->BN_MP_COPY_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_ZERO_C
+|   |   +--->BN_MP_INIT_MULTI_C
+|   |   |   +--->BN_MP_CLEAR_C
+|   |   +--->BN_MP_SET_C
+|   |   +--->BN_MP_COUNT_BITS_C
+|   |   +--->BN_MP_ABS_C
+|   |   +--->BN_MP_MUL_2D_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_CMP_C
+|   |   +--->BN_MP_SUB_C
+|   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_ADD_C
+|   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_DIV_2D_C
+|   |   |   +--->BN_MP_MOD_2D_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_CLEAR_C
+|   |   |   +--->BN_MP_RSHD_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_EXCH_C
+|   |   +--->BN_MP_EXCH_C
+|   |   +--->BN_MP_CLEAR_MULTI_C
+|   |   |   +--->BN_MP_CLEAR_C
+|   |   +--->BN_MP_INIT_SIZE_C
+|   |   +--->BN_MP_INIT_COPY_C
+|   |   +--->BN_MP_LSHD_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_RSHD_C
+|   |   +--->BN_MP_RSHD_C
+|   |   +--->BN_MP_MUL_D_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_CLEAR_C
+|   +--->BN_MP_CLEAR_C
+|   +--->BN_MP_ADD_C
+|   |   +--->BN_S_MP_ADD_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_CMP_MAG_C
+|   |   +--->BN_S_MP_SUB_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_EXCH_C
++--->BN_MP_GET_INT_C
++--->BN_MP_SQRT_C
+|   +--->BN_MP_N_ROOT_C
+|   |   +--->BN_MP_INIT_C
+|   |   +--->BN_MP_SET_C
+|   |   |   +--->BN_MP_ZERO_C
+|   |   +--->BN_MP_COPY_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_EXPT_D_C
+|   |   |   +--->BN_MP_INIT_COPY_C
+|   |   |   +--->BN_MP_SQR_C
+|   |   |   |   +--->BN_MP_TOOM_SQR_C
+|   |   |   |   |   +--->BN_MP_INIT_MULTI_C
+|   |   |   |   |   |   +--->BN_MP_CLEAR_C
+|   |   |   |   |   +--->BN_MP_MOD_2D_C
+|   |   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   +--->BN_MP_MUL_2_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_DIV_2_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_MUL_2D_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_MUL_D_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_DIV_3_C
+|   |   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   |   |   +--->BN_MP_CLEAR_C
+|   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLEAR_MULTI_C
+|   |   |   |   |   |   +--->BN_MP_CLEAR_C
+|   |   |   |   +--->BN_MP_KARATSUBA_SQR_C
+|   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLEAR_C
+|   |   |   |   +--->BN_FAST_S_MP_SQR_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_S_MP_SQR_C
+|   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   |   +--->BN_MP_CLEAR_C
+|   |   |   +--->BN_MP_CLEAR_C
+|   |   |   +--->BN_MP_MUL_C
+|   |   |   |   +--->BN_MP_TOOM_MUL_C
+|   |   |   |   |   +--->BN_MP_INIT_MULTI_C
+|   |   |   |   |   +--->BN_MP_MOD_2D_C
+|   |   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   +--->BN_MP_MUL_2_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_DIV_2_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_MUL_2D_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_MUL_D_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_DIV_3_C
+|   |   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLEAR_MULTI_C
+|   |   |   |   +--->BN_MP_KARATSUBA_MUL_C
+|   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   +--->BN_FAST_S_MP_MUL_DIGS_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_S_MP_MUL_DIGS_C
+|   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   +--->BN_MP_MUL_C
+|   |   |   +--->BN_MP_TOOM_MUL_C
+|   |   |   |   +--->BN_MP_INIT_MULTI_C
+|   |   |   |   |   +--->BN_MP_CLEAR_C
+|   |   |   |   +--->BN_MP_MOD_2D_C
+|   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   +--->BN_MP_MUL_2_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_DIV_2_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_MUL_2D_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_MUL_D_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_DIV_3_C
+|   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   |   +--->BN_MP_CLEAR_C
+|   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLEAR_MULTI_C
+|   |   |   |   |   +--->BN_MP_CLEAR_C
+|   |   |   +--->BN_MP_KARATSUBA_MUL_C
+|   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   +--->BN_MP_CLEAR_C
+|   |   |   +--->BN_FAST_S_MP_MUL_DIGS_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_S_MP_MUL_DIGS_C
+|   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   +--->BN_MP_CLEAR_C
+|   |   +--->BN_MP_SUB_C
+|   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_MUL_D_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_DIV_C
+|   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   +--->BN_MP_ZERO_C
+|   |   |   +--->BN_MP_INIT_MULTI_C
+|   |   |   |   +--->BN_MP_CLEAR_C
+|   |   |   +--->BN_MP_COUNT_BITS_C
+|   |   |   +--->BN_MP_ABS_C
+|   |   |   +--->BN_MP_MUL_2D_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_CMP_C
+|   |   |   +--->BN_MP_ADD_C
+|   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_DIV_2D_C
+|   |   |   |   +--->BN_MP_MOD_2D_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_CLEAR_C
+|   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   +--->BN_MP_EXCH_C
+|   |   |   +--->BN_MP_CLEAR_MULTI_C
+|   |   |   |   +--->BN_MP_CLEAR_C
+|   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   +--->BN_MP_INIT_COPY_C
+|   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   +--->BN_MP_RSHD_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_CLEAR_C
+|   |   +--->BN_MP_CMP_C
+|   |   |   +--->BN_MP_CMP_MAG_C
+|   |   +--->BN_MP_SUB_D_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_ADD_D_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_EXCH_C
+|   |   +--->BN_MP_CLEAR_C
+|   +--->BN_MP_ZERO_C
+|   +--->BN_MP_INIT_COPY_C
+|   |   +--->BN_MP_COPY_C
+|   |   |   +--->BN_MP_GROW_C
+|   +--->BN_MP_RSHD_C
+|   +--->BN_MP_DIV_C
+|   |   +--->BN_MP_CMP_MAG_C
+|   |   +--->BN_MP_COPY_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_INIT_MULTI_C
+|   |   |   +--->BN_MP_CLEAR_C
+|   |   +--->BN_MP_SET_C
+|   |   +--->BN_MP_COUNT_BITS_C
+|   |   +--->BN_MP_ABS_C
+|   |   +--->BN_MP_MUL_2D_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_LSHD_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_CMP_C
+|   |   +--->BN_MP_SUB_C
+|   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_ADD_C
+|   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_DIV_2D_C
+|   |   |   +--->BN_MP_MOD_2D_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_CLEAR_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_EXCH_C
+|   |   +--->BN_MP_EXCH_C
+|   |   +--->BN_MP_CLEAR_MULTI_C
+|   |   |   +--->BN_MP_CLEAR_C
+|   |   +--->BN_MP_INIT_SIZE_C
+|   |   +--->BN_MP_LSHD_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_MUL_D_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_CLEAR_C
+|   +--->BN_MP_ADD_C
+|   |   +--->BN_S_MP_ADD_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_CMP_MAG_C
+|   |   +--->BN_S_MP_SUB_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_DIV_2_C
+|   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_CMP_MAG_C
+|   +--->BN_MP_EXCH_C
+|   +--->BN_MP_CLEAR_C
++--->BN_MP_SQR_C
+|   +--->BN_MP_TOOM_SQR_C
+|   |   +--->BN_MP_INIT_MULTI_C
+|   |   |   +--->BN_MP_INIT_C
+|   |   |   +--->BN_MP_CLEAR_C
+|   |   +--->BN_MP_MOD_2D_C
+|   |   |   +--->BN_MP_ZERO_C
+|   |   |   +--->BN_MP_COPY_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_COPY_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_RSHD_C
+|   |   |   +--->BN_MP_ZERO_C
+|   |   +--->BN_MP_MUL_2_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_ADD_C
+|   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_SUB_C
+|   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_DIV_2_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_MUL_2D_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_LSHD_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_MUL_D_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_DIV_3_C
+|   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   +--->BN_MP_INIT_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_EXCH_C
+|   |   |   +--->BN_MP_CLEAR_C
+|   |   +--->BN_MP_LSHD_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_CLEAR_MULTI_C
+|   |   |   +--->BN_MP_CLEAR_C
+|   +--->BN_MP_KARATSUBA_SQR_C
+|   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   +--->BN_MP_INIT_C
+|   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_SUB_C
+|   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_S_MP_ADD_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_LSHD_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   +--->BN_MP_ZERO_C
+|   |   +--->BN_MP_ADD_C
+|   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_CLEAR_C
+|   +--->BN_FAST_S_MP_SQR_C
+|   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_CLAMP_C
+|   +--->BN_S_MP_SQR_C
+|   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   +--->BN_MP_INIT_C
+|   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_EXCH_C
+|   |   +--->BN_MP_CLEAR_C
++--->BN_MP_CMP_MAG_C
++--->BN_MP_CLEAR_C
+
+
+BN_MP_NEG_C
++--->BN_MP_COPY_C
+|   +--->BN_MP_GROW_C
+
+
+BN_MP_EXPTMOD_C
++--->BN_MP_INIT_C
++--->BN_MP_INVMOD_C
+|   +--->BN_FAST_MP_INVMOD_C
+|   |   +--->BN_MP_INIT_MULTI_C
+|   |   |   +--->BN_MP_CLEAR_C
+|   |   +--->BN_MP_COPY_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_MOD_C
+|   |   |   +--->BN_MP_DIV_C
+|   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   +--->BN_MP_SET_C
+|   |   |   |   +--->BN_MP_COUNT_BITS_C
+|   |   |   |   +--->BN_MP_ABS_C
+|   |   |   |   +--->BN_MP_MUL_2D_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_CMP_C
+|   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_DIV_2D_C
+|   |   |   |   |   +--->BN_MP_MOD_2D_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_CLEAR_C
+|   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   +--->BN_MP_CLEAR_MULTI_C
+|   |   |   |   |   +--->BN_MP_CLEAR_C
+|   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   +--->BN_MP_INIT_COPY_C
+|   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   +--->BN_MP_MUL_D_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_CLEAR_C
+|   |   |   +--->BN_MP_CLEAR_C
+|   |   |   +--->BN_MP_ADD_C
+|   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_EXCH_C
+|   |   +--->BN_MP_SET_C
+|   |   |   +--->BN_MP_ZERO_C
+|   |   +--->BN_MP_DIV_2_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_SUB_C
+|   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_CMP_C
+|   |   |   +--->BN_MP_CMP_MAG_C
+|   |   +--->BN_MP_CMP_D_C
+|   |   +--->BN_MP_ADD_C
+|   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_EXCH_C
+|   |   +--->BN_MP_CLEAR_MULTI_C
+|   |   |   +--->BN_MP_CLEAR_C
+|   +--->BN_MP_INVMOD_SLOW_C
+|   |   +--->BN_MP_INIT_MULTI_C
+|   |   |   +--->BN_MP_CLEAR_C
+|   |   +--->BN_MP_MOD_C
+|   |   |   +--->BN_MP_DIV_C
+|   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   +--->BN_MP_COPY_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   +--->BN_MP_SET_C
+|   |   |   |   +--->BN_MP_COUNT_BITS_C
+|   |   |   |   +--->BN_MP_ABS_C
+|   |   |   |   +--->BN_MP_MUL_2D_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_CMP_C
+|   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_DIV_2D_C
+|   |   |   |   |   +--->BN_MP_MOD_2D_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_CLEAR_C
+|   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   +--->BN_MP_CLEAR_MULTI_C
+|   |   |   |   |   +--->BN_MP_CLEAR_C
+|   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   +--->BN_MP_INIT_COPY_C
+|   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   +--->BN_MP_MUL_D_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_CLEAR_C
+|   |   |   +--->BN_MP_CLEAR_C
+|   |   |   +--->BN_MP_ADD_C
+|   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_EXCH_C
+|   |   +--->BN_MP_COPY_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_SET_C
+|   |   |   +--->BN_MP_ZERO_C
+|   |   +--->BN_MP_DIV_2_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_ADD_C
+|   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_SUB_C
+|   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_CMP_C
+|   |   |   +--->BN_MP_CMP_MAG_C
+|   |   +--->BN_MP_CMP_D_C
+|   |   +--->BN_MP_CMP_MAG_C
+|   |   +--->BN_MP_EXCH_C
+|   |   +--->BN_MP_CLEAR_MULTI_C
+|   |   |   +--->BN_MP_CLEAR_C
++--->BN_MP_CLEAR_C
++--->BN_MP_ABS_C
+|   +--->BN_MP_COPY_C
+|   |   +--->BN_MP_GROW_C
++--->BN_MP_CLEAR_MULTI_C
++--->BN_MP_REDUCE_IS_2K_L_C
++--->BN_S_MP_EXPTMOD_C
+|   +--->BN_MP_COUNT_BITS_C
+|   +--->BN_MP_REDUCE_SETUP_C
+|   |   +--->BN_MP_2EXPT_C
+|   |   |   +--->BN_MP_ZERO_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_DIV_C
+|   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   +--->BN_MP_COPY_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_ZERO_C
+|   |   |   +--->BN_MP_INIT_MULTI_C
+|   |   |   +--->BN_MP_SET_C
+|   |   |   +--->BN_MP_MUL_2D_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_CMP_C
+|   |   |   +--->BN_MP_SUB_C
+|   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_ADD_C
+|   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_DIV_2D_C
+|   |   |   |   +--->BN_MP_MOD_2D_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   +--->BN_MP_EXCH_C
+|   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   +--->BN_MP_INIT_COPY_C
+|   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   +--->BN_MP_RSHD_C
+|   |   |   +--->BN_MP_MUL_D_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_REDUCE_C
+|   |   +--->BN_MP_INIT_COPY_C
+|   |   |   +--->BN_MP_COPY_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_RSHD_C
+|   |   |   +--->BN_MP_ZERO_C
+|   |   +--->BN_MP_MUL_C
+|   |   |   +--->BN_MP_TOOM_MUL_C
+|   |   |   |   +--->BN_MP_INIT_MULTI_C
+|   |   |   |   +--->BN_MP_MOD_2D_C
+|   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   +--->BN_MP_COPY_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_COPY_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_MUL_2_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_DIV_2_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_MUL_2D_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_MUL_D_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_DIV_3_C
+|   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_KARATSUBA_MUL_C
+|   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_FAST_S_MP_MUL_DIGS_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_S_MP_MUL_DIGS_C
+|   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_EXCH_C
+|   |   +--->BN_S_MP_MUL_HIGH_DIGS_C
+|   |   |   +--->BN_FAST_S_MP_MUL_HIGH_DIGS_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_EXCH_C
+|   |   +--->BN_FAST_S_MP_MUL_HIGH_DIGS_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_MOD_2D_C
+|   |   |   +--->BN_MP_ZERO_C
+|   |   |   +--->BN_MP_COPY_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_S_MP_MUL_DIGS_C
+|   |   |   +--->BN_FAST_S_MP_MUL_DIGS_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_EXCH_C
+|   |   +--->BN_MP_SUB_C
+|   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_CMP_D_C
+|   |   +--->BN_MP_SET_C
+|   |   |   +--->BN_MP_ZERO_C
+|   |   +--->BN_MP_LSHD_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_ADD_C
+|   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_CMP_C
+|   |   |   +--->BN_MP_CMP_MAG_C
+|   |   +--->BN_S_MP_SUB_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_REDUCE_2K_SETUP_L_C
+|   |   +--->BN_MP_2EXPT_C
+|   |   |   +--->BN_MP_ZERO_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_S_MP_SUB_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_REDUCE_2K_L_C
+|   |   +--->BN_MP_DIV_2D_C
+|   |   |   +--->BN_MP_COPY_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_ZERO_C
+|   |   |   +--->BN_MP_MOD_2D_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_RSHD_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_EXCH_C
+|   |   +--->BN_MP_MUL_C
+|   |   |   +--->BN_MP_TOOM_MUL_C
+|   |   |   |   +--->BN_MP_INIT_MULTI_C
+|   |   |   |   +--->BN_MP_MOD_2D_C
+|   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   +--->BN_MP_COPY_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_COPY_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   +--->BN_MP_MUL_2_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_DIV_2_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_MUL_2D_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_MUL_D_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_DIV_3_C
+|   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_KARATSUBA_MUL_C
+|   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   +--->BN_FAST_S_MP_MUL_DIGS_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_S_MP_MUL_DIGS_C
+|   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_EXCH_C
+|   |   +--->BN_S_MP_ADD_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_CMP_MAG_C
+|   |   +--->BN_S_MP_SUB_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_MOD_C
+|   |   +--->BN_MP_DIV_C
+|   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   +--->BN_MP_COPY_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_ZERO_C
+|   |   |   +--->BN_MP_INIT_MULTI_C
+|   |   |   +--->BN_MP_SET_C
+|   |   |   +--->BN_MP_MUL_2D_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_CMP_C
+|   |   |   +--->BN_MP_SUB_C
+|   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_ADD_C
+|   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_DIV_2D_C
+|   |   |   |   +--->BN_MP_MOD_2D_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   +--->BN_MP_EXCH_C
+|   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   +--->BN_MP_INIT_COPY_C
+|   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   +--->BN_MP_RSHD_C
+|   |   |   +--->BN_MP_MUL_D_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_ADD_C
+|   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_EXCH_C
+|   +--->BN_MP_COPY_C
+|   |   +--->BN_MP_GROW_C
+|   +--->BN_MP_SQR_C
+|   |   +--->BN_MP_TOOM_SQR_C
+|   |   |   +--->BN_MP_INIT_MULTI_C
+|   |   |   +--->BN_MP_MOD_2D_C
+|   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   +--->BN_MP_MUL_2_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_ADD_C
+|   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_SUB_C
+|   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_DIV_2_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_MUL_2D_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_MUL_D_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_DIV_3_C
+|   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_KARATSUBA_SQR_C
+|   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_SUB_C
+|   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   +--->BN_MP_ADD_C
+|   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_FAST_S_MP_SQR_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_S_MP_SQR_C
+|   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_EXCH_C
+|   +--->BN_MP_MUL_C
+|   |   +--->BN_MP_TOOM_MUL_C
+|   |   |   +--->BN_MP_INIT_MULTI_C
+|   |   |   +--->BN_MP_MOD_2D_C
+|   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   +--->BN_MP_MUL_2_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_ADD_C
+|   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_SUB_C
+|   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_DIV_2_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_MUL_2D_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_MUL_D_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_DIV_3_C
+|   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_KARATSUBA_MUL_C
+|   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_SUB_C
+|   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_ADD_C
+|   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   +--->BN_FAST_S_MP_MUL_DIGS_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_S_MP_MUL_DIGS_C
+|   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_EXCH_C
+|   +--->BN_MP_SET_C
+|   |   +--->BN_MP_ZERO_C
+|   +--->BN_MP_EXCH_C
++--->BN_MP_DR_IS_MODULUS_C
++--->BN_MP_REDUCE_IS_2K_C
+|   +--->BN_MP_REDUCE_2K_C
+|   |   +--->BN_MP_COUNT_BITS_C
+|   |   +--->BN_MP_DIV_2D_C
+|   |   |   +--->BN_MP_COPY_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_ZERO_C
+|   |   |   +--->BN_MP_MOD_2D_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_RSHD_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_EXCH_C
+|   |   +--->BN_MP_MUL_D_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_S_MP_ADD_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_CMP_MAG_C
+|   |   +--->BN_S_MP_SUB_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_COUNT_BITS_C
++--->BN_MP_EXPTMOD_FAST_C
+|   +--->BN_MP_COUNT_BITS_C
+|   +--->BN_MP_MONTGOMERY_SETUP_C
+|   +--->BN_FAST_MP_MONTGOMERY_REDUCE_C
+|   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_RSHD_C
+|   |   |   +--->BN_MP_ZERO_C
+|   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_CMP_MAG_C
+|   |   +--->BN_S_MP_SUB_C
+|   +--->BN_MP_MONTGOMERY_REDUCE_C
+|   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_RSHD_C
+|   |   |   +--->BN_MP_ZERO_C
+|   |   +--->BN_MP_CMP_MAG_C
+|   |   +--->BN_S_MP_SUB_C
+|   +--->BN_MP_DR_SETUP_C
+|   +--->BN_MP_DR_REDUCE_C
+|   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_CMP_MAG_C
+|   |   +--->BN_S_MP_SUB_C
+|   +--->BN_MP_REDUCE_2K_SETUP_C
+|   |   +--->BN_MP_2EXPT_C
+|   |   |   +--->BN_MP_ZERO_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_S_MP_SUB_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_REDUCE_2K_C
+|   |   +--->BN_MP_DIV_2D_C
+|   |   |   +--->BN_MP_COPY_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_ZERO_C
+|   |   |   +--->BN_MP_MOD_2D_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_RSHD_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_EXCH_C
+|   |   +--->BN_MP_MUL_D_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_S_MP_ADD_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_CMP_MAG_C
+|   |   +--->BN_S_MP_SUB_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_MONTGOMERY_CALC_NORMALIZATION_C
+|   |   +--->BN_MP_2EXPT_C
+|   |   |   +--->BN_MP_ZERO_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_SET_C
+|   |   |   +--->BN_MP_ZERO_C
+|   |   +--->BN_MP_MUL_2_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_CMP_MAG_C
+|   |   +--->BN_S_MP_SUB_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_MULMOD_C
+|   |   +--->BN_MP_MUL_C
+|   |   |   +--->BN_MP_TOOM_MUL_C
+|   |   |   |   +--->BN_MP_INIT_MULTI_C
+|   |   |   |   +--->BN_MP_MOD_2D_C
+|   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   +--->BN_MP_COPY_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_COPY_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   +--->BN_MP_MUL_2_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_DIV_2_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_MUL_2D_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_MUL_D_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_DIV_3_C
+|   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_KARATSUBA_MUL_C
+|   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   +--->BN_FAST_S_MP_MUL_DIGS_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_S_MP_MUL_DIGS_C
+|   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_EXCH_C
+|   |   +--->BN_MP_MOD_C
+|   |   |   +--->BN_MP_DIV_C
+|   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   +--->BN_MP_COPY_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   +--->BN_MP_INIT_MULTI_C
+|   |   |   |   +--->BN_MP_SET_C
+|   |   |   |   +--->BN_MP_MUL_2D_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_CMP_C
+|   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_DIV_2D_C
+|   |   |   |   |   +--->BN_MP_MOD_2D_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   +--->BN_MP_INIT_COPY_C
+|   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   +--->BN_MP_MUL_D_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_ADD_C
+|   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_EXCH_C
+|   +--->BN_MP_SET_C
+|   |   +--->BN_MP_ZERO_C
+|   +--->BN_MP_MOD_C
+|   |   +--->BN_MP_DIV_C
+|   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   +--->BN_MP_COPY_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_ZERO_C
+|   |   |   +--->BN_MP_INIT_MULTI_C
+|   |   |   +--->BN_MP_MUL_2D_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_CMP_C
+|   |   |   +--->BN_MP_SUB_C
+|   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_ADD_C
+|   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_DIV_2D_C
+|   |   |   |   +--->BN_MP_MOD_2D_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   +--->BN_MP_EXCH_C
+|   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   +--->BN_MP_INIT_COPY_C
+|   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   +--->BN_MP_RSHD_C
+|   |   |   +--->BN_MP_MUL_D_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_ADD_C
+|   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_EXCH_C
+|   +--->BN_MP_COPY_C
+|   |   +--->BN_MP_GROW_C
+|   +--->BN_MP_SQR_C
+|   |   +--->BN_MP_TOOM_SQR_C
+|   |   |   +--->BN_MP_INIT_MULTI_C
+|   |   |   +--->BN_MP_MOD_2D_C
+|   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   +--->BN_MP_MUL_2_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_ADD_C
+|   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_SUB_C
+|   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_DIV_2_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_MUL_2D_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_MUL_D_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_DIV_3_C
+|   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_KARATSUBA_SQR_C
+|   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_SUB_C
+|   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   +--->BN_MP_ADD_C
+|   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_FAST_S_MP_SQR_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_S_MP_SQR_C
+|   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_EXCH_C
+|   +--->BN_MP_MUL_C
+|   |   +--->BN_MP_TOOM_MUL_C
+|   |   |   +--->BN_MP_INIT_MULTI_C
+|   |   |   +--->BN_MP_MOD_2D_C
+|   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   +--->BN_MP_MUL_2_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_ADD_C
+|   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_SUB_C
+|   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_DIV_2_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_MUL_2D_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_MUL_D_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_DIV_3_C
+|   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_KARATSUBA_MUL_C
+|   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_SUB_C
+|   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_ADD_C
+|   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   +--->BN_FAST_S_MP_MUL_DIGS_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_S_MP_MUL_DIGS_C
+|   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_EXCH_C
+|   +--->BN_MP_EXCH_C
+
+
+BN_MP_OR_C
++--->BN_MP_INIT_COPY_C
+|   +--->BN_MP_COPY_C
+|   |   +--->BN_MP_GROW_C
++--->BN_MP_CLAMP_C
++--->BN_MP_EXCH_C
++--->BN_MP_CLEAR_C
+
+
+BN_MP_ZERO_C
+
+
+BN_MP_GROW_C
+
+
+BN_MP_COUNT_BITS_C
+
+
+BN_MP_PRIME_FERMAT_C
++--->BN_MP_CMP_D_C
++--->BN_MP_INIT_C
++--->BN_MP_EXPTMOD_C
+|   +--->BN_MP_INVMOD_C
+|   |   +--->BN_FAST_MP_INVMOD_C
+|   |   |   +--->BN_MP_INIT_MULTI_C
+|   |   |   |   +--->BN_MP_CLEAR_C
+|   |   |   +--->BN_MP_COPY_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_MOD_C
+|   |   |   |   +--->BN_MP_DIV_C
+|   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   +--->BN_MP_SET_C
+|   |   |   |   |   +--->BN_MP_COUNT_BITS_C
+|   |   |   |   |   +--->BN_MP_ABS_C
+|   |   |   |   |   +--->BN_MP_MUL_2D_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_CMP_C
+|   |   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_DIV_2D_C
+|   |   |   |   |   |   +--->BN_MP_MOD_2D_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_CLEAR_C
+|   |   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   |   +--->BN_MP_CLEAR_MULTI_C
+|   |   |   |   |   |   +--->BN_MP_CLEAR_C
+|   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   +--->BN_MP_INIT_COPY_C
+|   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   +--->BN_MP_MUL_D_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_CLEAR_C
+|   |   |   |   +--->BN_MP_CLEAR_C
+|   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   +--->BN_MP_SET_C
+|   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   +--->BN_MP_DIV_2_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_SUB_C
+|   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_CMP_C
+|   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   +--->BN_MP_ADD_C
+|   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_EXCH_C
+|   |   |   +--->BN_MP_CLEAR_MULTI_C
+|   |   |   |   +--->BN_MP_CLEAR_C
+|   |   +--->BN_MP_INVMOD_SLOW_C
+|   |   |   +--->BN_MP_INIT_MULTI_C
+|   |   |   |   +--->BN_MP_CLEAR_C
+|   |   |   +--->BN_MP_MOD_C
+|   |   |   |   +--->BN_MP_DIV_C
+|   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   +--->BN_MP_COPY_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   +--->BN_MP_SET_C
+|   |   |   |   |   +--->BN_MP_COUNT_BITS_C
+|   |   |   |   |   +--->BN_MP_ABS_C
+|   |   |   |   |   +--->BN_MP_MUL_2D_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_CMP_C
+|   |   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_DIV_2D_C
+|   |   |   |   |   |   +--->BN_MP_MOD_2D_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_CLEAR_C
+|   |   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   |   +--->BN_MP_CLEAR_MULTI_C
+|   |   |   |   |   |   +--->BN_MP_CLEAR_C
+|   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   +--->BN_MP_INIT_COPY_C
+|   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   +--->BN_MP_MUL_D_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_CLEAR_C
+|   |   |   |   +--->BN_MP_CLEAR_C
+|   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   +--->BN_MP_COPY_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_SET_C
+|   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   +--->BN_MP_DIV_2_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_ADD_C
+|   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_SUB_C
+|   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_CMP_C
+|   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   +--->BN_MP_EXCH_C
+|   |   |   +--->BN_MP_CLEAR_MULTI_C
+|   |   |   |   +--->BN_MP_CLEAR_C
+|   +--->BN_MP_CLEAR_C
+|   +--->BN_MP_ABS_C
+|   |   +--->BN_MP_COPY_C
+|   |   |   +--->BN_MP_GROW_C
+|   +--->BN_MP_CLEAR_MULTI_C
+|   +--->BN_MP_REDUCE_IS_2K_L_C
+|   +--->BN_S_MP_EXPTMOD_C
+|   |   +--->BN_MP_COUNT_BITS_C
+|   |   +--->BN_MP_REDUCE_SETUP_C
+|   |   |   +--->BN_MP_2EXPT_C
+|   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_DIV_C
+|   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   +--->BN_MP_COPY_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   +--->BN_MP_INIT_MULTI_C
+|   |   |   |   +--->BN_MP_SET_C
+|   |   |   |   +--->BN_MP_MUL_2D_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_CMP_C
+|   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_DIV_2D_C
+|   |   |   |   |   +--->BN_MP_MOD_2D_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   +--->BN_MP_INIT_COPY_C
+|   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   +--->BN_MP_MUL_D_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_REDUCE_C
+|   |   |   +--->BN_MP_INIT_COPY_C
+|   |   |   |   +--->BN_MP_COPY_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   +--->BN_MP_MUL_C
+|   |   |   |   +--->BN_MP_TOOM_MUL_C
+|   |   |   |   |   +--->BN_MP_INIT_MULTI_C
+|   |   |   |   |   +--->BN_MP_MOD_2D_C
+|   |   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   |   +--->BN_MP_COPY_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_COPY_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_MUL_2_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_DIV_2_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_MUL_2D_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_MUL_D_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_DIV_3_C
+|   |   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_KARATSUBA_MUL_C
+|   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_FAST_S_MP_MUL_DIGS_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_S_MP_MUL_DIGS_C
+|   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   +--->BN_S_MP_MUL_HIGH_DIGS_C
+|   |   |   |   +--->BN_FAST_S_MP_MUL_HIGH_DIGS_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   +--->BN_FAST_S_MP_MUL_HIGH_DIGS_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_MOD_2D_C
+|   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   +--->BN_MP_COPY_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_S_MP_MUL_DIGS_C
+|   |   |   |   +--->BN_FAST_S_MP_MUL_DIGS_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   +--->BN_MP_SUB_C
+|   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_SET_C
+|   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_ADD_C
+|   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_CMP_C
+|   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_REDUCE_2K_SETUP_L_C
+|   |   |   +--->BN_MP_2EXPT_C
+|   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_REDUCE_2K_L_C
+|   |   |   +--->BN_MP_DIV_2D_C
+|   |   |   |   +--->BN_MP_COPY_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   +--->BN_MP_MOD_2D_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   +--->BN_MP_MUL_C
+|   |   |   |   +--->BN_MP_TOOM_MUL_C
+|   |   |   |   |   +--->BN_MP_INIT_MULTI_C
+|   |   |   |   |   +--->BN_MP_MOD_2D_C
+|   |   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   |   +--->BN_MP_COPY_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_COPY_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   +--->BN_MP_MUL_2_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_DIV_2_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_MUL_2D_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_MUL_D_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_DIV_3_C
+|   |   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_KARATSUBA_MUL_C
+|   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   +--->BN_FAST_S_MP_MUL_DIGS_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_S_MP_MUL_DIGS_C
+|   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_MOD_C
+|   |   |   +--->BN_MP_DIV_C
+|   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   +--->BN_MP_COPY_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   +--->BN_MP_INIT_MULTI_C
+|   |   |   |   +--->BN_MP_SET_C
+|   |   |   |   +--->BN_MP_MUL_2D_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_CMP_C
+|   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_DIV_2D_C
+|   |   |   |   |   +--->BN_MP_MOD_2D_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   +--->BN_MP_INIT_COPY_C
+|   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   +--->BN_MP_MUL_D_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_ADD_C
+|   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_EXCH_C
+|   |   +--->BN_MP_COPY_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_SQR_C
+|   |   |   +--->BN_MP_TOOM_SQR_C
+|   |   |   |   +--->BN_MP_INIT_MULTI_C
+|   |   |   |   +--->BN_MP_MOD_2D_C
+|   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   +--->BN_MP_MUL_2_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_DIV_2_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_MUL_2D_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_MUL_D_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_DIV_3_C
+|   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_KARATSUBA_SQR_C
+|   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_FAST_S_MP_SQR_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_S_MP_SQR_C
+|   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_EXCH_C
+|   |   +--->BN_MP_MUL_C
+|   |   |   +--->BN_MP_TOOM_MUL_C
+|   |   |   |   +--->BN_MP_INIT_MULTI_C
+|   |   |   |   +--->BN_MP_MOD_2D_C
+|   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   +--->BN_MP_MUL_2_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_DIV_2_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_MUL_2D_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_MUL_D_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_DIV_3_C
+|   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_KARATSUBA_MUL_C
+|   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   +--->BN_FAST_S_MP_MUL_DIGS_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_S_MP_MUL_DIGS_C
+|   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_EXCH_C
+|   |   +--->BN_MP_SET_C
+|   |   |   +--->BN_MP_ZERO_C
+|   |   +--->BN_MP_EXCH_C
+|   +--->BN_MP_DR_IS_MODULUS_C
+|   +--->BN_MP_REDUCE_IS_2K_C
+|   |   +--->BN_MP_REDUCE_2K_C
+|   |   |   +--->BN_MP_COUNT_BITS_C
+|   |   |   +--->BN_MP_DIV_2D_C
+|   |   |   |   +--->BN_MP_COPY_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   +--->BN_MP_MOD_2D_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   +--->BN_MP_MUL_D_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_COUNT_BITS_C
+|   +--->BN_MP_EXPTMOD_FAST_C
+|   |   +--->BN_MP_COUNT_BITS_C
+|   |   +--->BN_MP_MONTGOMERY_SETUP_C
+|   |   +--->BN_FAST_MP_MONTGOMERY_REDUCE_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   +--->BN_MP_MONTGOMERY_REDUCE_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   +--->BN_MP_DR_SETUP_C
+|   |   +--->BN_MP_DR_REDUCE_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   +--->BN_MP_REDUCE_2K_SETUP_C
+|   |   |   +--->BN_MP_2EXPT_C
+|   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_REDUCE_2K_C
+|   |   |   +--->BN_MP_DIV_2D_C
+|   |   |   |   +--->BN_MP_COPY_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   +--->BN_MP_MOD_2D_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   +--->BN_MP_MUL_D_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_MONTGOMERY_CALC_NORMALIZATION_C
+|   |   |   +--->BN_MP_2EXPT_C
+|   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_SET_C
+|   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   +--->BN_MP_MUL_2_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_MULMOD_C
+|   |   |   +--->BN_MP_MUL_C
+|   |   |   |   +--->BN_MP_TOOM_MUL_C
+|   |   |   |   |   +--->BN_MP_INIT_MULTI_C
+|   |   |   |   |   +--->BN_MP_MOD_2D_C
+|   |   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   |   +--->BN_MP_COPY_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_COPY_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   +--->BN_MP_MUL_2_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_DIV_2_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_MUL_2D_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_MUL_D_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_DIV_3_C
+|   |   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_KARATSUBA_MUL_C
+|   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   +--->BN_FAST_S_MP_MUL_DIGS_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_S_MP_MUL_DIGS_C
+|   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   +--->BN_MP_MOD_C
+|   |   |   |   +--->BN_MP_DIV_C
+|   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   +--->BN_MP_COPY_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   +--->BN_MP_INIT_MULTI_C
+|   |   |   |   |   +--->BN_MP_SET_C
+|   |   |   |   |   +--->BN_MP_MUL_2D_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_CMP_C
+|   |   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_DIV_2D_C
+|   |   |   |   |   |   +--->BN_MP_MOD_2D_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   +--->BN_MP_INIT_COPY_C
+|   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   +--->BN_MP_MUL_D_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_EXCH_C
+|   |   +--->BN_MP_SET_C
+|   |   |   +--->BN_MP_ZERO_C
+|   |   +--->BN_MP_MOD_C
+|   |   |   +--->BN_MP_DIV_C
+|   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   +--->BN_MP_COPY_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   +--->BN_MP_INIT_MULTI_C
+|   |   |   |   +--->BN_MP_MUL_2D_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_CMP_C
+|   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_DIV_2D_C
+|   |   |   |   |   +--->BN_MP_MOD_2D_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   +--->BN_MP_INIT_COPY_C
+|   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   +--->BN_MP_MUL_D_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_ADD_C
+|   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_EXCH_C
+|   |   +--->BN_MP_COPY_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_SQR_C
+|   |   |   +--->BN_MP_TOOM_SQR_C
+|   |   |   |   +--->BN_MP_INIT_MULTI_C
+|   |   |   |   +--->BN_MP_MOD_2D_C
+|   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   +--->BN_MP_MUL_2_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_DIV_2_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_MUL_2D_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_MUL_D_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_DIV_3_C
+|   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_KARATSUBA_SQR_C
+|   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_FAST_S_MP_SQR_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_S_MP_SQR_C
+|   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_EXCH_C
+|   |   +--->BN_MP_MUL_C
+|   |   |   +--->BN_MP_TOOM_MUL_C
+|   |   |   |   +--->BN_MP_INIT_MULTI_C
+|   |   |   |   +--->BN_MP_MOD_2D_C
+|   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   +--->BN_MP_MUL_2_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_DIV_2_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_MUL_2D_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_MUL_D_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_DIV_3_C
+|   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_KARATSUBA_MUL_C
+|   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   +--->BN_FAST_S_MP_MUL_DIGS_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_S_MP_MUL_DIGS_C
+|   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_EXCH_C
+|   |   +--->BN_MP_EXCH_C
++--->BN_MP_CMP_C
+|   +--->BN_MP_CMP_MAG_C
++--->BN_MP_CLEAR_C
+
+
+BN_MP_SUBMOD_C
++--->BN_MP_INIT_C
++--->BN_MP_SUB_C
+|   +--->BN_S_MP_ADD_C
+|   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_CMP_MAG_C
+|   +--->BN_S_MP_SUB_C
+|   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_CLAMP_C
++--->BN_MP_CLEAR_C
++--->BN_MP_MOD_C
+|   +--->BN_MP_DIV_C
+|   |   +--->BN_MP_CMP_MAG_C
+|   |   +--->BN_MP_COPY_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_ZERO_C
+|   |   +--->BN_MP_INIT_MULTI_C
+|   |   +--->BN_MP_SET_C
+|   |   +--->BN_MP_COUNT_BITS_C
+|   |   +--->BN_MP_ABS_C
+|   |   +--->BN_MP_MUL_2D_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_CMP_C
+|   |   +--->BN_MP_ADD_C
+|   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_DIV_2D_C
+|   |   |   +--->BN_MP_MOD_2D_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_RSHD_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_EXCH_C
+|   |   +--->BN_MP_EXCH_C
+|   |   +--->BN_MP_CLEAR_MULTI_C
+|   |   +--->BN_MP_INIT_SIZE_C
+|   |   +--->BN_MP_INIT_COPY_C
+|   |   +--->BN_MP_LSHD_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_RSHD_C
+|   |   +--->BN_MP_RSHD_C
+|   |   +--->BN_MP_MUL_D_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_ADD_C
+|   |   +--->BN_S_MP_ADD_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_CMP_MAG_C
+|   |   +--->BN_S_MP_SUB_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_EXCH_C
+
+
+BN_MP_MOD_2D_C
++--->BN_MP_ZERO_C
++--->BN_MP_COPY_C
+|   +--->BN_MP_GROW_C
++--->BN_MP_CLAMP_C
+
+
+BN_MP_TORADIX_N_C
++--->BN_MP_INIT_COPY_C
+|   +--->BN_MP_COPY_C
+|   |   +--->BN_MP_GROW_C
++--->BN_MP_DIV_D_C
+|   +--->BN_MP_COPY_C
+|   |   +--->BN_MP_GROW_C
+|   +--->BN_MP_DIV_2D_C
+|   |   +--->BN_MP_ZERO_C
+|   |   +--->BN_MP_MOD_2D_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_CLEAR_C
+|   |   +--->BN_MP_RSHD_C
+|   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_EXCH_C
+|   +--->BN_MP_DIV_3_C
+|   |   +--->BN_MP_INIT_SIZE_C
+|   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_EXCH_C
+|   |   +--->BN_MP_CLEAR_C
+|   +--->BN_MP_INIT_SIZE_C
+|   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_EXCH_C
+|   +--->BN_MP_CLEAR_C
++--->BN_MP_CLEAR_C
+
+
+BN_MP_CMP_C
++--->BN_MP_CMP_MAG_C
+
+
+BNCORE_C
+
+
+BN_MP_TORADIX_C
++--->BN_MP_INIT_COPY_C
+|   +--->BN_MP_COPY_C
+|   |   +--->BN_MP_GROW_C
++--->BN_MP_DIV_D_C
+|   +--->BN_MP_COPY_C
+|   |   +--->BN_MP_GROW_C
+|   +--->BN_MP_DIV_2D_C
+|   |   +--->BN_MP_ZERO_C
+|   |   +--->BN_MP_MOD_2D_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_CLEAR_C
+|   |   +--->BN_MP_RSHD_C
+|   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_EXCH_C
+|   +--->BN_MP_DIV_3_C
+|   |   +--->BN_MP_INIT_SIZE_C
+|   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_EXCH_C
+|   |   +--->BN_MP_CLEAR_C
+|   +--->BN_MP_INIT_SIZE_C
+|   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_EXCH_C
+|   +--->BN_MP_CLEAR_C
++--->BN_MP_CLEAR_C
+
+
+BN_MP_ADD_D_C
++--->BN_MP_GROW_C
++--->BN_MP_SUB_D_C
+|   +--->BN_MP_CLAMP_C
++--->BN_MP_CLAMP_C
+
+
+BN_MP_DIV_3_C
++--->BN_MP_INIT_SIZE_C
+|   +--->BN_MP_INIT_C
++--->BN_MP_CLAMP_C
++--->BN_MP_EXCH_C
++--->BN_MP_CLEAR_C
+
+
+BN_FAST_S_MP_MUL_DIGS_C
++--->BN_MP_GROW_C
++--->BN_MP_CLAMP_C
+
+
+BN_MP_SQRMOD_C
++--->BN_MP_INIT_C
++--->BN_MP_SQR_C
+|   +--->BN_MP_TOOM_SQR_C
+|   |   +--->BN_MP_INIT_MULTI_C
+|   |   |   +--->BN_MP_CLEAR_C
+|   |   +--->BN_MP_MOD_2D_C
+|   |   |   +--->BN_MP_ZERO_C
+|   |   |   +--->BN_MP_COPY_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_COPY_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_RSHD_C
+|   |   |   +--->BN_MP_ZERO_C
+|   |   +--->BN_MP_MUL_2_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_ADD_C
+|   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_SUB_C
+|   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_DIV_2_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_MUL_2D_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_LSHD_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_MUL_D_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_DIV_3_C
+|   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_EXCH_C
+|   |   |   +--->BN_MP_CLEAR_C
+|   |   +--->BN_MP_LSHD_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_CLEAR_MULTI_C
+|   |   |   +--->BN_MP_CLEAR_C
+|   +--->BN_MP_KARATSUBA_SQR_C
+|   |   +--->BN_MP_INIT_SIZE_C
+|   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_SUB_C
+|   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_S_MP_ADD_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_LSHD_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   +--->BN_MP_ZERO_C
+|   |   +--->BN_MP_ADD_C
+|   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_CLEAR_C
+|   +--->BN_FAST_S_MP_SQR_C
+|   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_CLAMP_C
+|   +--->BN_S_MP_SQR_C
+|   |   +--->BN_MP_INIT_SIZE_C
+|   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_EXCH_C
+|   |   +--->BN_MP_CLEAR_C
++--->BN_MP_CLEAR_C
++--->BN_MP_MOD_C
+|   +--->BN_MP_DIV_C
+|   |   +--->BN_MP_CMP_MAG_C
+|   |   +--->BN_MP_COPY_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_ZERO_C
+|   |   +--->BN_MP_INIT_MULTI_C
+|   |   +--->BN_MP_SET_C
+|   |   +--->BN_MP_COUNT_BITS_C
+|   |   +--->BN_MP_ABS_C
+|   |   +--->BN_MP_MUL_2D_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_CMP_C
+|   |   +--->BN_MP_SUB_C
+|   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_ADD_C
+|   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_DIV_2D_C
+|   |   |   +--->BN_MP_MOD_2D_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_RSHD_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_EXCH_C
+|   |   +--->BN_MP_EXCH_C
+|   |   +--->BN_MP_CLEAR_MULTI_C
+|   |   +--->BN_MP_INIT_SIZE_C
+|   |   +--->BN_MP_INIT_COPY_C
+|   |   +--->BN_MP_LSHD_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_RSHD_C
+|   |   +--->BN_MP_RSHD_C
+|   |   +--->BN_MP_MUL_D_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_ADD_C
+|   |   +--->BN_S_MP_ADD_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_CMP_MAG_C
+|   |   +--->BN_S_MP_SUB_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_EXCH_C
+
+
+BN_MP_INVMOD_C
++--->BN_FAST_MP_INVMOD_C
+|   +--->BN_MP_INIT_MULTI_C
+|   |   +--->BN_MP_INIT_C
+|   |   +--->BN_MP_CLEAR_C
+|   +--->BN_MP_COPY_C
+|   |   +--->BN_MP_GROW_C
+|   +--->BN_MP_MOD_C
+|   |   +--->BN_MP_INIT_C
+|   |   +--->BN_MP_DIV_C
+|   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   +--->BN_MP_ZERO_C
+|   |   |   +--->BN_MP_SET_C
+|   |   |   +--->BN_MP_COUNT_BITS_C
+|   |   |   +--->BN_MP_ABS_C
+|   |   |   +--->BN_MP_MUL_2D_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_CMP_C
+|   |   |   +--->BN_MP_SUB_C
+|   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_ADD_C
+|   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_DIV_2D_C
+|   |   |   |   +--->BN_MP_MOD_2D_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_CLEAR_C
+|   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   +--->BN_MP_EXCH_C
+|   |   |   +--->BN_MP_CLEAR_MULTI_C
+|   |   |   |   +--->BN_MP_CLEAR_C
+|   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   +--->BN_MP_INIT_COPY_C
+|   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   +--->BN_MP_RSHD_C
+|   |   |   +--->BN_MP_MUL_D_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_CLEAR_C
+|   |   +--->BN_MP_CLEAR_C
+|   |   +--->BN_MP_ADD_C
+|   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_EXCH_C
+|   +--->BN_MP_SET_C
+|   |   +--->BN_MP_ZERO_C
+|   +--->BN_MP_DIV_2_C
+|   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_SUB_C
+|   |   +--->BN_S_MP_ADD_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_CMP_MAG_C
+|   |   +--->BN_S_MP_SUB_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_CMP_C
+|   |   +--->BN_MP_CMP_MAG_C
+|   +--->BN_MP_CMP_D_C
+|   +--->BN_MP_ADD_C
+|   |   +--->BN_S_MP_ADD_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_CMP_MAG_C
+|   |   +--->BN_S_MP_SUB_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_EXCH_C
+|   +--->BN_MP_CLEAR_MULTI_C
+|   |   +--->BN_MP_CLEAR_C
++--->BN_MP_INVMOD_SLOW_C
+|   +--->BN_MP_INIT_MULTI_C
+|   |   +--->BN_MP_INIT_C
+|   |   +--->BN_MP_CLEAR_C
+|   +--->BN_MP_MOD_C
+|   |   +--->BN_MP_INIT_C
+|   |   +--->BN_MP_DIV_C
+|   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   +--->BN_MP_COPY_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_ZERO_C
+|   |   |   +--->BN_MP_SET_C
+|   |   |   +--->BN_MP_COUNT_BITS_C
+|   |   |   +--->BN_MP_ABS_C
+|   |   |   +--->BN_MP_MUL_2D_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_CMP_C
+|   |   |   +--->BN_MP_SUB_C
+|   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_ADD_C
+|   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_DIV_2D_C
+|   |   |   |   +--->BN_MP_MOD_2D_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_CLEAR_C
+|   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   +--->BN_MP_EXCH_C
+|   |   |   +--->BN_MP_CLEAR_MULTI_C
+|   |   |   |   +--->BN_MP_CLEAR_C
+|   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   +--->BN_MP_INIT_COPY_C
+|   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   +--->BN_MP_RSHD_C
+|   |   |   +--->BN_MP_MUL_D_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_CLEAR_C
+|   |   +--->BN_MP_CLEAR_C
+|   |   +--->BN_MP_ADD_C
+|   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_EXCH_C
+|   +--->BN_MP_COPY_C
+|   |   +--->BN_MP_GROW_C
+|   +--->BN_MP_SET_C
+|   |   +--->BN_MP_ZERO_C
+|   +--->BN_MP_DIV_2_C
+|   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_ADD_C
+|   |   +--->BN_S_MP_ADD_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_CMP_MAG_C
+|   |   +--->BN_S_MP_SUB_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_SUB_C
+|   |   +--->BN_S_MP_ADD_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_CMP_MAG_C
+|   |   +--->BN_S_MP_SUB_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_CMP_C
+|   |   +--->BN_MP_CMP_MAG_C
+|   +--->BN_MP_CMP_D_C
+|   +--->BN_MP_CMP_MAG_C
+|   +--->BN_MP_EXCH_C
+|   +--->BN_MP_CLEAR_MULTI_C
+|   |   +--->BN_MP_CLEAR_C
+
+
+BN_MP_AND_C
++--->BN_MP_INIT_COPY_C
+|   +--->BN_MP_COPY_C
+|   |   +--->BN_MP_GROW_C
++--->BN_MP_CLAMP_C
++--->BN_MP_EXCH_C
++--->BN_MP_CLEAR_C
+
+
+BN_MP_MUL_D_C
++--->BN_MP_GROW_C
++--->BN_MP_CLAMP_C
+
+
+BN_FAST_MP_INVMOD_C
++--->BN_MP_INIT_MULTI_C
+|   +--->BN_MP_INIT_C
+|   +--->BN_MP_CLEAR_C
++--->BN_MP_COPY_C
+|   +--->BN_MP_GROW_C
++--->BN_MP_MOD_C
+|   +--->BN_MP_INIT_C
+|   +--->BN_MP_DIV_C
+|   |   +--->BN_MP_CMP_MAG_C
+|   |   +--->BN_MP_ZERO_C
+|   |   +--->BN_MP_SET_C
+|   |   +--->BN_MP_COUNT_BITS_C
+|   |   +--->BN_MP_ABS_C
+|   |   +--->BN_MP_MUL_2D_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_CMP_C
+|   |   +--->BN_MP_SUB_C
+|   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_ADD_C
+|   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_DIV_2D_C
+|   |   |   +--->BN_MP_MOD_2D_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_CLEAR_C
+|   |   |   +--->BN_MP_RSHD_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_EXCH_C
+|   |   +--->BN_MP_EXCH_C
+|   |   +--->BN_MP_CLEAR_MULTI_C
+|   |   |   +--->BN_MP_CLEAR_C
+|   |   +--->BN_MP_INIT_SIZE_C
+|   |   +--->BN_MP_INIT_COPY_C
+|   |   +--->BN_MP_LSHD_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_RSHD_C
+|   |   +--->BN_MP_RSHD_C
+|   |   +--->BN_MP_MUL_D_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_CLEAR_C
+|   +--->BN_MP_CLEAR_C
+|   +--->BN_MP_ADD_C
+|   |   +--->BN_S_MP_ADD_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_CMP_MAG_C
+|   |   +--->BN_S_MP_SUB_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_EXCH_C
++--->BN_MP_SET_C
+|   +--->BN_MP_ZERO_C
++--->BN_MP_DIV_2_C
+|   +--->BN_MP_GROW_C
+|   +--->BN_MP_CLAMP_C
++--->BN_MP_SUB_C
+|   +--->BN_S_MP_ADD_C
+|   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_CMP_MAG_C
+|   +--->BN_S_MP_SUB_C
+|   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_CLAMP_C
++--->BN_MP_CMP_C
+|   +--->BN_MP_CMP_MAG_C
++--->BN_MP_CMP_D_C
++--->BN_MP_ADD_C
+|   +--->BN_S_MP_ADD_C
+|   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_CMP_MAG_C
+|   +--->BN_S_MP_SUB_C
+|   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_CLAMP_C
++--->BN_MP_EXCH_C
++--->BN_MP_CLEAR_MULTI_C
+|   +--->BN_MP_CLEAR_C
+
+
+BN_MP_FWRITE_C
++--->BN_MP_RADIX_SIZE_C
+|   +--->BN_MP_COUNT_BITS_C
+|   +--->BN_MP_INIT_COPY_C
+|   |   +--->BN_MP_COPY_C
+|   |   |   +--->BN_MP_GROW_C
+|   +--->BN_MP_DIV_D_C
+|   |   +--->BN_MP_COPY_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_DIV_2D_C
+|   |   |   +--->BN_MP_ZERO_C
+|   |   |   +--->BN_MP_MOD_2D_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_CLEAR_C
+|   |   |   +--->BN_MP_RSHD_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_EXCH_C
+|   |   +--->BN_MP_DIV_3_C
+|   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_EXCH_C
+|   |   |   +--->BN_MP_CLEAR_C
+|   |   +--->BN_MP_INIT_SIZE_C
+|   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_EXCH_C
+|   |   +--->BN_MP_CLEAR_C
+|   +--->BN_MP_CLEAR_C
++--->BN_MP_TORADIX_C
+|   +--->BN_MP_INIT_COPY_C
+|   |   +--->BN_MP_COPY_C
+|   |   |   +--->BN_MP_GROW_C
+|   +--->BN_MP_DIV_D_C
+|   |   +--->BN_MP_COPY_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_DIV_2D_C
+|   |   |   +--->BN_MP_ZERO_C
+|   |   |   +--->BN_MP_MOD_2D_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_CLEAR_C
+|   |   |   +--->BN_MP_RSHD_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_EXCH_C
+|   |   +--->BN_MP_DIV_3_C
+|   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_EXCH_C
+|   |   |   +--->BN_MP_CLEAR_C
+|   |   +--->BN_MP_INIT_SIZE_C
+|   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_EXCH_C
+|   |   +--->BN_MP_CLEAR_C
+|   +--->BN_MP_CLEAR_C
+
+
+BN_S_MP_SQR_C
++--->BN_MP_INIT_SIZE_C
+|   +--->BN_MP_INIT_C
++--->BN_MP_CLAMP_C
++--->BN_MP_EXCH_C
++--->BN_MP_CLEAR_C
+
+
+BN_MP_N_ROOT_C
++--->BN_MP_INIT_C
++--->BN_MP_SET_C
+|   +--->BN_MP_ZERO_C
++--->BN_MP_COPY_C
+|   +--->BN_MP_GROW_C
++--->BN_MP_EXPT_D_C
+|   +--->BN_MP_INIT_COPY_C
+|   +--->BN_MP_SQR_C
+|   |   +--->BN_MP_TOOM_SQR_C
+|   |   |   +--->BN_MP_INIT_MULTI_C
+|   |   |   |   +--->BN_MP_CLEAR_C
+|   |   |   +--->BN_MP_MOD_2D_C
+|   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   +--->BN_MP_MUL_2_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_ADD_C
+|   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_SUB_C
+|   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_DIV_2_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_MUL_2D_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_MUL_D_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_DIV_3_C
+|   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   +--->BN_MP_CLEAR_C
+|   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLEAR_MULTI_C
+|   |   |   |   +--->BN_MP_CLEAR_C
+|   |   +--->BN_MP_KARATSUBA_SQR_C
+|   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_SUB_C
+|   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   +--->BN_MP_ADD_C
+|   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLEAR_C
+|   |   +--->BN_FAST_S_MP_SQR_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_S_MP_SQR_C
+|   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_EXCH_C
+|   |   |   +--->BN_MP_CLEAR_C
+|   +--->BN_MP_CLEAR_C
+|   +--->BN_MP_MUL_C
+|   |   +--->BN_MP_TOOM_MUL_C
+|   |   |   +--->BN_MP_INIT_MULTI_C
+|   |   |   +--->BN_MP_MOD_2D_C
+|   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   +--->BN_MP_MUL_2_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_ADD_C
+|   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_SUB_C
+|   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_DIV_2_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_MUL_2D_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_MUL_D_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_DIV_3_C
+|   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLEAR_MULTI_C
+|   |   +--->BN_MP_KARATSUBA_MUL_C
+|   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_SUB_C
+|   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_ADD_C
+|   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   +--->BN_FAST_S_MP_MUL_DIGS_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_S_MP_MUL_DIGS_C
+|   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_EXCH_C
++--->BN_MP_MUL_C
+|   +--->BN_MP_TOOM_MUL_C
+|   |   +--->BN_MP_INIT_MULTI_C
+|   |   |   +--->BN_MP_CLEAR_C
+|   |   +--->BN_MP_MOD_2D_C
+|   |   |   +--->BN_MP_ZERO_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_RSHD_C
+|   |   |   +--->BN_MP_ZERO_C
+|   |   +--->BN_MP_MUL_2_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_ADD_C
+|   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_SUB_C
+|   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_DIV_2_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_MUL_2D_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_LSHD_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_MUL_D_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_DIV_3_C
+|   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_EXCH_C
+|   |   |   +--->BN_MP_CLEAR_C
+|   |   +--->BN_MP_LSHD_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_CLEAR_MULTI_C
+|   |   |   +--->BN_MP_CLEAR_C
+|   +--->BN_MP_KARATSUBA_MUL_C
+|   |   +--->BN_MP_INIT_SIZE_C
+|   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_SUB_C
+|   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_ADD_C
+|   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_LSHD_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   +--->BN_MP_ZERO_C
+|   |   +--->BN_MP_CLEAR_C
+|   +--->BN_FAST_S_MP_MUL_DIGS_C
+|   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_CLAMP_C
+|   +--->BN_S_MP_MUL_DIGS_C
+|   |   +--->BN_MP_INIT_SIZE_C
+|   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_EXCH_C
+|   |   +--->BN_MP_CLEAR_C
++--->BN_MP_SUB_C
+|   +--->BN_S_MP_ADD_C
+|   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_CMP_MAG_C
+|   +--->BN_S_MP_SUB_C
+|   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_CLAMP_C
++--->BN_MP_MUL_D_C
+|   +--->BN_MP_GROW_C
+|   +--->BN_MP_CLAMP_C
++--->BN_MP_DIV_C
+|   +--->BN_MP_CMP_MAG_C
+|   +--->BN_MP_ZERO_C
+|   +--->BN_MP_INIT_MULTI_C
+|   |   +--->BN_MP_CLEAR_C
+|   +--->BN_MP_COUNT_BITS_C
+|   +--->BN_MP_ABS_C
+|   +--->BN_MP_MUL_2D_C
+|   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_LSHD_C
+|   |   |   +--->BN_MP_RSHD_C
+|   |   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_CMP_C
+|   +--->BN_MP_ADD_C
+|   |   +--->BN_S_MP_ADD_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_S_MP_SUB_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_DIV_2D_C
+|   |   +--->BN_MP_MOD_2D_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_CLEAR_C
+|   |   +--->BN_MP_RSHD_C
+|   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_EXCH_C
+|   +--->BN_MP_EXCH_C
+|   +--->BN_MP_CLEAR_MULTI_C
+|   |   +--->BN_MP_CLEAR_C
+|   +--->BN_MP_INIT_SIZE_C
+|   +--->BN_MP_INIT_COPY_C
+|   +--->BN_MP_LSHD_C
+|   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_RSHD_C
+|   +--->BN_MP_RSHD_C
+|   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_CLEAR_C
++--->BN_MP_CMP_C
+|   +--->BN_MP_CMP_MAG_C
++--->BN_MP_SUB_D_C
+|   +--->BN_MP_GROW_C
+|   +--->BN_MP_ADD_D_C
+|   |   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_CLAMP_C
++--->BN_MP_EXCH_C
++--->BN_MP_CLEAR_C
+
+
+BN_MP_PRIME_RABIN_MILLER_TRIALS_C
+
+
+BN_MP_RADIX_SIZE_C
++--->BN_MP_COUNT_BITS_C
++--->BN_MP_INIT_COPY_C
+|   +--->BN_MP_COPY_C
+|   |   +--->BN_MP_GROW_C
++--->BN_MP_DIV_D_C
+|   +--->BN_MP_COPY_C
+|   |   +--->BN_MP_GROW_C
+|   +--->BN_MP_DIV_2D_C
+|   |   +--->BN_MP_ZERO_C
+|   |   +--->BN_MP_MOD_2D_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_CLEAR_C
+|   |   +--->BN_MP_RSHD_C
+|   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_EXCH_C
+|   +--->BN_MP_DIV_3_C
+|   |   +--->BN_MP_INIT_SIZE_C
+|   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_EXCH_C
+|   |   +--->BN_MP_CLEAR_C
+|   +--->BN_MP_INIT_SIZE_C
+|   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_EXCH_C
+|   +--->BN_MP_CLEAR_C
++--->BN_MP_CLEAR_C
+
+
+BN_MP_READ_SIGNED_BIN_C
++--->BN_MP_READ_UNSIGNED_BIN_C
+|   +--->BN_MP_GROW_C
+|   +--->BN_MP_ZERO_C
+|   +--->BN_MP_MUL_2D_C
+|   |   +--->BN_MP_COPY_C
+|   |   +--->BN_MP_LSHD_C
+|   |   |   +--->BN_MP_RSHD_C
+|   |   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_CLAMP_C
+
+
+BN_MP_PRIME_RANDOM_EX_C
++--->BN_MP_READ_UNSIGNED_BIN_C
+|   +--->BN_MP_GROW_C
+|   +--->BN_MP_ZERO_C
+|   +--->BN_MP_MUL_2D_C
+|   |   +--->BN_MP_COPY_C
+|   |   +--->BN_MP_LSHD_C
+|   |   |   +--->BN_MP_RSHD_C
+|   |   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_CLAMP_C
++--->BN_MP_PRIME_IS_PRIME_C
+|   +--->BN_MP_CMP_D_C
+|   +--->BN_MP_PRIME_IS_DIVISIBLE_C
+|   |   +--->BN_MP_MOD_D_C
+|   |   |   +--->BN_MP_DIV_D_C
+|   |   |   |   +--->BN_MP_COPY_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_DIV_2D_C
+|   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   +--->BN_MP_INIT_C
+|   |   |   |   |   +--->BN_MP_MOD_2D_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_CLEAR_C
+|   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   +--->BN_MP_DIV_3_C
+|   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   |   +--->BN_MP_INIT_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   |   +--->BN_MP_CLEAR_C
+|   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   +--->BN_MP_INIT_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   +--->BN_MP_CLEAR_C
+|   +--->BN_MP_INIT_C
+|   +--->BN_MP_SET_C
+|   |   +--->BN_MP_ZERO_C
+|   +--->BN_MP_PRIME_MILLER_RABIN_C
+|   |   +--->BN_MP_INIT_COPY_C
+|   |   |   +--->BN_MP_COPY_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_SUB_D_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_ADD_D_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_CNT_LSB_C
+|   |   +--->BN_MP_DIV_2D_C
+|   |   |   +--->BN_MP_COPY_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_ZERO_C
+|   |   |   +--->BN_MP_MOD_2D_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_CLEAR_C
+|   |   |   +--->BN_MP_RSHD_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_EXCH_C
+|   |   +--->BN_MP_EXPTMOD_C
+|   |   |   +--->BN_MP_INVMOD_C
+|   |   |   |   +--->BN_FAST_MP_INVMOD_C
+|   |   |   |   |   +--->BN_MP_INIT_MULTI_C
+|   |   |   |   |   |   +--->BN_MP_CLEAR_C
+|   |   |   |   |   +--->BN_MP_COPY_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_MOD_C
+|   |   |   |   |   |   +--->BN_MP_DIV_C
+|   |   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   |   |   +--->BN_MP_COUNT_BITS_C
+|   |   |   |   |   |   |   +--->BN_MP_ABS_C
+|   |   |   |   |   |   |   +--->BN_MP_MUL_2D_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   |   +--->BN_MP_CMP_C
+|   |   |   |   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   |   |   |   +--->BN_MP_CLEAR_MULTI_C
+|   |   |   |   |   |   |   |   +--->BN_MP_CLEAR_C
+|   |   |   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   |   |   +--->BN_MP_MUL_D_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   |   +--->BN_MP_CLEAR_C
+|   |   |   |   |   |   +--->BN_MP_CLEAR_C
+|   |   |   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   |   +--->BN_MP_DIV_2_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_CMP_C
+|   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   |   +--->BN_MP_CLEAR_MULTI_C
+|   |   |   |   |   |   +--->BN_MP_CLEAR_C
+|   |   |   |   +--->BN_MP_INVMOD_SLOW_C
+|   |   |   |   |   +--->BN_MP_INIT_MULTI_C
+|   |   |   |   |   |   +--->BN_MP_CLEAR_C
+|   |   |   |   |   +--->BN_MP_MOD_C
+|   |   |   |   |   |   +--->BN_MP_DIV_C
+|   |   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   |   +--->BN_MP_COPY_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   |   |   +--->BN_MP_COUNT_BITS_C
+|   |   |   |   |   |   |   +--->BN_MP_ABS_C
+|   |   |   |   |   |   |   +--->BN_MP_MUL_2D_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   |   +--->BN_MP_CMP_C
+|   |   |   |   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   |   |   |   +--->BN_MP_CLEAR_MULTI_C
+|   |   |   |   |   |   |   |   +--->BN_MP_CLEAR_C
+|   |   |   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   |   |   +--->BN_MP_MUL_D_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   |   +--->BN_MP_CLEAR_C
+|   |   |   |   |   |   +--->BN_MP_CLEAR_C
+|   |   |   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   |   +--->BN_MP_COPY_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_DIV_2_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_CMP_C
+|   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   |   +--->BN_MP_CLEAR_MULTI_C
+|   |   |   |   |   |   +--->BN_MP_CLEAR_C
+|   |   |   +--->BN_MP_CLEAR_C
+|   |   |   +--->BN_MP_ABS_C
+|   |   |   |   +--->BN_MP_COPY_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLEAR_MULTI_C
+|   |   |   +--->BN_MP_REDUCE_IS_2K_L_C
+|   |   |   +--->BN_S_MP_EXPTMOD_C
+|   |   |   |   +--->BN_MP_COUNT_BITS_C
+|   |   |   |   +--->BN_MP_REDUCE_SETUP_C
+|   |   |   |   |   +--->BN_MP_2EXPT_C
+|   |   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_DIV_C
+|   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   +--->BN_MP_COPY_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   |   +--->BN_MP_INIT_MULTI_C
+|   |   |   |   |   |   +--->BN_MP_MUL_2D_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_CMP_C
+|   |   |   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   |   +--->BN_MP_MUL_D_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_REDUCE_C
+|   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   +--->BN_MP_MUL_C
+|   |   |   |   |   |   +--->BN_MP_TOOM_MUL_C
+|   |   |   |   |   |   |   +--->BN_MP_INIT_MULTI_C
+|   |   |   |   |   |   |   +--->BN_MP_MOD_2D_C
+|   |   |   |   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   |   |   |   +--->BN_MP_COPY_C
+|   |   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   |   +--->BN_MP_COPY_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_MUL_2_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   |   +--->BN_MP_DIV_2_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   |   +--->BN_MP_MUL_2D_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   |   +--->BN_MP_MUL_D_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   |   +--->BN_MP_DIV_3_C
+|   |   |   |   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_KARATSUBA_MUL_C
+|   |   |   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_FAST_S_MP_MUL_DIGS_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_S_MP_MUL_DIGS_C
+|   |   |   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   |   +--->BN_S_MP_MUL_HIGH_DIGS_C
+|   |   |   |   |   |   +--->BN_FAST_S_MP_MUL_HIGH_DIGS_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   |   +--->BN_FAST_S_MP_MUL_HIGH_DIGS_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_MOD_2D_C
+|   |   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   |   +--->BN_MP_COPY_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_S_MP_MUL_DIGS_C
+|   |   |   |   |   |   +--->BN_FAST_S_MP_MUL_DIGS_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_CMP_C
+|   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_REDUCE_2K_SETUP_L_C
+|   |   |   |   |   +--->BN_MP_2EXPT_C
+|   |   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_REDUCE_2K_L_C
+|   |   |   |   |   +--->BN_MP_MUL_C
+|   |   |   |   |   |   +--->BN_MP_TOOM_MUL_C
+|   |   |   |   |   |   |   +--->BN_MP_INIT_MULTI_C
+|   |   |   |   |   |   |   +--->BN_MP_MOD_2D_C
+|   |   |   |   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   |   |   |   +--->BN_MP_COPY_C
+|   |   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   |   +--->BN_MP_COPY_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   |   |   +--->BN_MP_MUL_2_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   |   +--->BN_MP_DIV_2_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   |   +--->BN_MP_MUL_2D_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   |   +--->BN_MP_MUL_D_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   |   +--->BN_MP_DIV_3_C
+|   |   |   |   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_KARATSUBA_MUL_C
+|   |   |   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   |   +--->BN_FAST_S_MP_MUL_DIGS_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_S_MP_MUL_DIGS_C
+|   |   |   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_MOD_C
+|   |   |   |   |   +--->BN_MP_DIV_C
+|   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   +--->BN_MP_COPY_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   |   +--->BN_MP_INIT_MULTI_C
+|   |   |   |   |   |   +--->BN_MP_MUL_2D_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_CMP_C
+|   |   |   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   |   +--->BN_MP_MUL_D_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   +--->BN_MP_COPY_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_SQR_C
+|   |   |   |   |   +--->BN_MP_TOOM_SQR_C
+|   |   |   |   |   |   +--->BN_MP_INIT_MULTI_C
+|   |   |   |   |   |   +--->BN_MP_MOD_2D_C
+|   |   |   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   |   +--->BN_MP_MUL_2_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_DIV_2_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_MUL_2D_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_MUL_D_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_DIV_3_C
+|   |   |   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_KARATSUBA_SQR_C
+|   |   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_FAST_S_MP_SQR_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_S_MP_SQR_C
+|   |   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   +--->BN_MP_MUL_C
+|   |   |   |   |   +--->BN_MP_TOOM_MUL_C
+|   |   |   |   |   |   +--->BN_MP_INIT_MULTI_C
+|   |   |   |   |   |   +--->BN_MP_MOD_2D_C
+|   |   |   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   |   +--->BN_MP_MUL_2_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_DIV_2_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_MUL_2D_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_MUL_D_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_DIV_3_C
+|   |   |   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_KARATSUBA_MUL_C
+|   |   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   +--->BN_FAST_S_MP_MUL_DIGS_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_S_MP_MUL_DIGS_C
+|   |   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   +--->BN_MP_DR_IS_MODULUS_C
+|   |   |   +--->BN_MP_REDUCE_IS_2K_C
+|   |   |   |   +--->BN_MP_REDUCE_2K_C
+|   |   |   |   |   +--->BN_MP_COUNT_BITS_C
+|   |   |   |   |   +--->BN_MP_MUL_D_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_COUNT_BITS_C
+|   |   |   +--->BN_MP_EXPTMOD_FAST_C
+|   |   |   |   +--->BN_MP_COUNT_BITS_C
+|   |   |   |   +--->BN_MP_MONTGOMERY_SETUP_C
+|   |   |   |   +--->BN_FAST_MP_MONTGOMERY_REDUCE_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   +--->BN_MP_MONTGOMERY_REDUCE_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   +--->BN_MP_DR_SETUP_C
+|   |   |   |   +--->BN_MP_DR_REDUCE_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   +--->BN_MP_REDUCE_2K_SETUP_C
+|   |   |   |   |   +--->BN_MP_2EXPT_C
+|   |   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_REDUCE_2K_C
+|   |   |   |   |   +--->BN_MP_MUL_D_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_MONTGOMERY_CALC_NORMALIZATION_C
+|   |   |   |   |   +--->BN_MP_2EXPT_C
+|   |   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_MUL_2_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_MULMOD_C
+|   |   |   |   |   +--->BN_MP_MUL_C
+|   |   |   |   |   |   +--->BN_MP_TOOM_MUL_C
+|   |   |   |   |   |   |   +--->BN_MP_INIT_MULTI_C
+|   |   |   |   |   |   |   +--->BN_MP_MOD_2D_C
+|   |   |   |   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   |   |   |   +--->BN_MP_COPY_C
+|   |   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   |   +--->BN_MP_COPY_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   |   |   +--->BN_MP_MUL_2_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   |   +--->BN_MP_DIV_2_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   |   +--->BN_MP_MUL_2D_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   |   +--->BN_MP_MUL_D_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   |   +--->BN_MP_DIV_3_C
+|   |   |   |   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_KARATSUBA_MUL_C
+|   |   |   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   |   +--->BN_FAST_S_MP_MUL_DIGS_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_S_MP_MUL_DIGS_C
+|   |   |   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   |   +--->BN_MP_MOD_C
+|   |   |   |   |   |   +--->BN_MP_DIV_C
+|   |   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   |   +--->BN_MP_COPY_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   |   |   +--->BN_MP_INIT_MULTI_C
+|   |   |   |   |   |   |   +--->BN_MP_MUL_2D_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   |   +--->BN_MP_CMP_C
+|   |   |   |   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   |   |   +--->BN_MP_MUL_D_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   +--->BN_MP_MOD_C
+|   |   |   |   |   +--->BN_MP_DIV_C
+|   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   +--->BN_MP_COPY_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   |   +--->BN_MP_INIT_MULTI_C
+|   |   |   |   |   |   +--->BN_MP_MUL_2D_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_CMP_C
+|   |   |   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   |   +--->BN_MP_MUL_D_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   +--->BN_MP_COPY_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_SQR_C
+|   |   |   |   |   +--->BN_MP_TOOM_SQR_C
+|   |   |   |   |   |   +--->BN_MP_INIT_MULTI_C
+|   |   |   |   |   |   +--->BN_MP_MOD_2D_C
+|   |   |   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   |   +--->BN_MP_MUL_2_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_DIV_2_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_MUL_2D_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_MUL_D_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_DIV_3_C
+|   |   |   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_KARATSUBA_SQR_C
+|   |   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_FAST_S_MP_SQR_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_S_MP_SQR_C
+|   |   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   +--->BN_MP_MUL_C
+|   |   |   |   |   +--->BN_MP_TOOM_MUL_C
+|   |   |   |   |   |   +--->BN_MP_INIT_MULTI_C
+|   |   |   |   |   |   +--->BN_MP_MOD_2D_C
+|   |   |   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   |   +--->BN_MP_MUL_2_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_DIV_2_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_MUL_2D_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_MUL_D_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_DIV_3_C
+|   |   |   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_KARATSUBA_MUL_C
+|   |   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   +--->BN_FAST_S_MP_MUL_DIGS_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_S_MP_MUL_DIGS_C
+|   |   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   +--->BN_MP_EXCH_C
+|   |   +--->BN_MP_CMP_C
+|   |   |   +--->BN_MP_CMP_MAG_C
+|   |   +--->BN_MP_SQRMOD_C
+|   |   |   +--->BN_MP_SQR_C
+|   |   |   |   +--->BN_MP_TOOM_SQR_C
+|   |   |   |   |   +--->BN_MP_INIT_MULTI_C
+|   |   |   |   |   |   +--->BN_MP_CLEAR_C
+|   |   |   |   |   +--->BN_MP_MOD_2D_C
+|   |   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   |   +--->BN_MP_COPY_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_COPY_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   +--->BN_MP_MUL_2_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_DIV_2_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_MUL_2D_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_MUL_D_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_DIV_3_C
+|   |   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   |   |   +--->BN_MP_CLEAR_C
+|   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLEAR_MULTI_C
+|   |   |   |   |   |   +--->BN_MP_CLEAR_C
+|   |   |   |   +--->BN_MP_KARATSUBA_SQR_C
+|   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLEAR_C
+|   |   |   |   +--->BN_FAST_S_MP_SQR_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_S_MP_SQR_C
+|   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   |   +--->BN_MP_CLEAR_C
+|   |   |   +--->BN_MP_CLEAR_C
+|   |   |   +--->BN_MP_MOD_C
+|   |   |   |   +--->BN_MP_DIV_C
+|   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   +--->BN_MP_COPY_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   +--->BN_MP_INIT_MULTI_C
+|   |   |   |   |   +--->BN_MP_COUNT_BITS_C
+|   |   |   |   |   +--->BN_MP_ABS_C
+|   |   |   |   |   +--->BN_MP_MUL_2D_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   |   +--->BN_MP_CLEAR_MULTI_C
+|   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   +--->BN_MP_MUL_D_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_EXCH_C
+|   |   +--->BN_MP_CLEAR_C
+|   +--->BN_MP_CLEAR_C
++--->BN_MP_SUB_D_C
+|   +--->BN_MP_GROW_C
+|   +--->BN_MP_ADD_D_C
+|   |   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_CLAMP_C
++--->BN_MP_DIV_2_C
+|   +--->BN_MP_GROW_C
+|   +--->BN_MP_CLAMP_C
++--->BN_MP_MUL_2_C
+|   +--->BN_MP_GROW_C
++--->BN_MP_ADD_D_C
+|   +--->BN_MP_GROW_C
+|   +--->BN_MP_CLAMP_C
+
+
+BN_MP_KARATSUBA_SQR_C
++--->BN_MP_INIT_SIZE_C
+|   +--->BN_MP_INIT_C
++--->BN_MP_CLAMP_C
++--->BN_MP_SQR_C
+|   +--->BN_MP_TOOM_SQR_C
+|   |   +--->BN_MP_INIT_MULTI_C
+|   |   |   +--->BN_MP_INIT_C
+|   |   |   +--->BN_MP_CLEAR_C
+|   |   +--->BN_MP_MOD_2D_C
+|   |   |   +--->BN_MP_ZERO_C
+|   |   |   +--->BN_MP_COPY_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_COPY_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_RSHD_C
+|   |   |   +--->BN_MP_ZERO_C
+|   |   +--->BN_MP_MUL_2_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_ADD_C
+|   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_SUB_C
+|   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_DIV_2_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_MUL_2D_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_LSHD_C
+|   |   +--->BN_MP_MUL_D_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_DIV_3_C
+|   |   |   +--->BN_MP_EXCH_C
+|   |   |   +--->BN_MP_CLEAR_C
+|   |   +--->BN_MP_LSHD_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_CLEAR_MULTI_C
+|   |   |   +--->BN_MP_CLEAR_C
+|   +--->BN_FAST_S_MP_SQR_C
+|   |   +--->BN_MP_GROW_C
+|   +--->BN_S_MP_SQR_C
+|   |   +--->BN_MP_EXCH_C
+|   |   +--->BN_MP_CLEAR_C
++--->BN_MP_SUB_C
+|   +--->BN_S_MP_ADD_C
+|   |   +--->BN_MP_GROW_C
+|   +--->BN_MP_CMP_MAG_C
+|   +--->BN_S_MP_SUB_C
+|   |   +--->BN_MP_GROW_C
++--->BN_S_MP_ADD_C
+|   +--->BN_MP_GROW_C
++--->BN_MP_LSHD_C
+|   +--->BN_MP_GROW_C
+|   +--->BN_MP_RSHD_C
+|   |   +--->BN_MP_ZERO_C
++--->BN_MP_ADD_C
+|   +--->BN_MP_CMP_MAG_C
+|   +--->BN_S_MP_SUB_C
+|   |   +--->BN_MP_GROW_C
++--->BN_MP_CLEAR_C
+
+
+BN_MP_INIT_COPY_C
++--->BN_MP_COPY_C
+|   +--->BN_MP_GROW_C
+
+
+BN_MP_CLAMP_C
+
+
+BN_MP_TOOM_SQR_C
++--->BN_MP_INIT_MULTI_C
+|   +--->BN_MP_INIT_C
+|   +--->BN_MP_CLEAR_C
++--->BN_MP_MOD_2D_C
+|   +--->BN_MP_ZERO_C
+|   +--->BN_MP_COPY_C
+|   |   +--->BN_MP_GROW_C
+|   +--->BN_MP_CLAMP_C
++--->BN_MP_COPY_C
+|   +--->BN_MP_GROW_C
++--->BN_MP_RSHD_C
+|   +--->BN_MP_ZERO_C
++--->BN_MP_SQR_C
+|   +--->BN_MP_KARATSUBA_SQR_C
+|   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   +--->BN_MP_INIT_C
+|   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_SUB_C
+|   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_S_MP_ADD_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_LSHD_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_ADD_C
+|   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_CLEAR_C
+|   +--->BN_FAST_S_MP_SQR_C
+|   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_CLAMP_C
+|   +--->BN_S_MP_SQR_C
+|   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   +--->BN_MP_INIT_C
+|   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_EXCH_C
+|   |   +--->BN_MP_CLEAR_C
++--->BN_MP_MUL_2_C
+|   +--->BN_MP_GROW_C
++--->BN_MP_ADD_C
+|   +--->BN_S_MP_ADD_C
+|   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_CMP_MAG_C
+|   +--->BN_S_MP_SUB_C
+|   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_CLAMP_C
++--->BN_MP_SUB_C
+|   +--->BN_S_MP_ADD_C
+|   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_CMP_MAG_C
+|   +--->BN_S_MP_SUB_C
+|   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_CLAMP_C
++--->BN_MP_DIV_2_C
+|   +--->BN_MP_GROW_C
+|   +--->BN_MP_CLAMP_C
++--->BN_MP_MUL_2D_C
+|   +--->BN_MP_GROW_C
+|   +--->BN_MP_LSHD_C
+|   +--->BN_MP_CLAMP_C
++--->BN_MP_MUL_D_C
+|   +--->BN_MP_GROW_C
+|   +--->BN_MP_CLAMP_C
++--->BN_MP_DIV_3_C
+|   +--->BN_MP_INIT_SIZE_C
+|   |   +--->BN_MP_INIT_C
+|   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_EXCH_C
+|   +--->BN_MP_CLEAR_C
++--->BN_MP_LSHD_C
+|   +--->BN_MP_GROW_C
++--->BN_MP_CLEAR_MULTI_C
+|   +--->BN_MP_CLEAR_C
+
+
+BN_MP_MOD_C
++--->BN_MP_INIT_C
++--->BN_MP_DIV_C
+|   +--->BN_MP_CMP_MAG_C
+|   +--->BN_MP_COPY_C
+|   |   +--->BN_MP_GROW_C
+|   +--->BN_MP_ZERO_C
+|   +--->BN_MP_INIT_MULTI_C
+|   |   +--->BN_MP_CLEAR_C
+|   +--->BN_MP_SET_C
+|   +--->BN_MP_COUNT_BITS_C
+|   +--->BN_MP_ABS_C
+|   +--->BN_MP_MUL_2D_C
+|   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_LSHD_C
+|   |   |   +--->BN_MP_RSHD_C
+|   |   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_CMP_C
+|   +--->BN_MP_SUB_C
+|   |   +--->BN_S_MP_ADD_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_S_MP_SUB_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_ADD_C
+|   |   +--->BN_S_MP_ADD_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_S_MP_SUB_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_DIV_2D_C
+|   |   +--->BN_MP_MOD_2D_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_CLEAR_C
+|   |   +--->BN_MP_RSHD_C
+|   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_EXCH_C
+|   +--->BN_MP_EXCH_C
+|   +--->BN_MP_CLEAR_MULTI_C
+|   |   +--->BN_MP_CLEAR_C
+|   +--->BN_MP_INIT_SIZE_C
+|   +--->BN_MP_INIT_COPY_C
+|   +--->BN_MP_LSHD_C
+|   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_RSHD_C
+|   +--->BN_MP_RSHD_C
+|   +--->BN_MP_MUL_D_C
+|   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_CLEAR_C
++--->BN_MP_CLEAR_C
++--->BN_MP_ADD_C
+|   +--->BN_S_MP_ADD_C
+|   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_CMP_MAG_C
+|   +--->BN_S_MP_SUB_C
+|   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_CLAMP_C
++--->BN_MP_EXCH_C
+
+
+BN_MP_INIT_C
+
+
+BN_MP_TOOM_MUL_C
++--->BN_MP_INIT_MULTI_C
+|   +--->BN_MP_INIT_C
+|   +--->BN_MP_CLEAR_C
++--->BN_MP_MOD_2D_C
+|   +--->BN_MP_ZERO_C
+|   +--->BN_MP_COPY_C
+|   |   +--->BN_MP_GROW_C
+|   +--->BN_MP_CLAMP_C
++--->BN_MP_COPY_C
+|   +--->BN_MP_GROW_C
++--->BN_MP_RSHD_C
+|   +--->BN_MP_ZERO_C
++--->BN_MP_MUL_C
+|   +--->BN_MP_KARATSUBA_MUL_C
+|   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   +--->BN_MP_INIT_C
+|   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_SUB_C
+|   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_ADD_C
+|   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_LSHD_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_CLEAR_C
+|   +--->BN_FAST_S_MP_MUL_DIGS_C
+|   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_CLAMP_C
+|   +--->BN_S_MP_MUL_DIGS_C
+|   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   +--->BN_MP_INIT_C
+|   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_EXCH_C
+|   |   +--->BN_MP_CLEAR_C
++--->BN_MP_MUL_2_C
+|   +--->BN_MP_GROW_C
++--->BN_MP_ADD_C
+|   +--->BN_S_MP_ADD_C
+|   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_CMP_MAG_C
+|   +--->BN_S_MP_SUB_C
+|   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_CLAMP_C
++--->BN_MP_SUB_C
+|   +--->BN_S_MP_ADD_C
+|   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_CMP_MAG_C
+|   +--->BN_S_MP_SUB_C
+|   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_CLAMP_C
++--->BN_MP_DIV_2_C
+|   +--->BN_MP_GROW_C
+|   +--->BN_MP_CLAMP_C
++--->BN_MP_MUL_2D_C
+|   +--->BN_MP_GROW_C
+|   +--->BN_MP_LSHD_C
+|   +--->BN_MP_CLAMP_C
++--->BN_MP_MUL_D_C
+|   +--->BN_MP_GROW_C
+|   +--->BN_MP_CLAMP_C
++--->BN_MP_DIV_3_C
+|   +--->BN_MP_INIT_SIZE_C
+|   |   +--->BN_MP_INIT_C
+|   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_EXCH_C
+|   +--->BN_MP_CLEAR_C
++--->BN_MP_LSHD_C
+|   +--->BN_MP_GROW_C
++--->BN_MP_CLEAR_MULTI_C
+|   +--->BN_MP_CLEAR_C
+
+
+BN_MP_PRIME_IS_PRIME_C
++--->BN_MP_CMP_D_C
++--->BN_MP_PRIME_IS_DIVISIBLE_C
+|   +--->BN_MP_MOD_D_C
+|   |   +--->BN_MP_DIV_D_C
+|   |   |   +--->BN_MP_COPY_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_DIV_2D_C
+|   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   +--->BN_MP_INIT_C
+|   |   |   |   +--->BN_MP_MOD_2D_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_CLEAR_C
+|   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   +--->BN_MP_DIV_3_C
+|   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   +--->BN_MP_INIT_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   +--->BN_MP_CLEAR_C
+|   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   +--->BN_MP_INIT_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_EXCH_C
+|   |   |   +--->BN_MP_CLEAR_C
++--->BN_MP_INIT_C
++--->BN_MP_SET_C
+|   +--->BN_MP_ZERO_C
++--->BN_MP_PRIME_MILLER_RABIN_C
+|   +--->BN_MP_INIT_COPY_C
+|   |   +--->BN_MP_COPY_C
+|   |   |   +--->BN_MP_GROW_C
+|   +--->BN_MP_SUB_D_C
+|   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_ADD_D_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_CNT_LSB_C
+|   +--->BN_MP_DIV_2D_C
+|   |   +--->BN_MP_COPY_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_ZERO_C
+|   |   +--->BN_MP_MOD_2D_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_CLEAR_C
+|   |   +--->BN_MP_RSHD_C
+|   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_EXCH_C
+|   +--->BN_MP_EXPTMOD_C
+|   |   +--->BN_MP_INVMOD_C
+|   |   |   +--->BN_FAST_MP_INVMOD_C
+|   |   |   |   +--->BN_MP_INIT_MULTI_C
+|   |   |   |   |   +--->BN_MP_CLEAR_C
+|   |   |   |   +--->BN_MP_COPY_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_MOD_C
+|   |   |   |   |   +--->BN_MP_DIV_C
+|   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   |   +--->BN_MP_COUNT_BITS_C
+|   |   |   |   |   |   +--->BN_MP_ABS_C
+|   |   |   |   |   |   +--->BN_MP_MUL_2D_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_CMP_C
+|   |   |   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   |   |   +--->BN_MP_CLEAR_MULTI_C
+|   |   |   |   |   |   |   +--->BN_MP_CLEAR_C
+|   |   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   |   +--->BN_MP_MUL_D_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_CLEAR_C
+|   |   |   |   |   +--->BN_MP_CLEAR_C
+|   |   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   +--->BN_MP_DIV_2_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_CMP_C
+|   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   +--->BN_MP_CLEAR_MULTI_C
+|   |   |   |   |   +--->BN_MP_CLEAR_C
+|   |   |   +--->BN_MP_INVMOD_SLOW_C
+|   |   |   |   +--->BN_MP_INIT_MULTI_C
+|   |   |   |   |   +--->BN_MP_CLEAR_C
+|   |   |   |   +--->BN_MP_MOD_C
+|   |   |   |   |   +--->BN_MP_DIV_C
+|   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   +--->BN_MP_COPY_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   |   +--->BN_MP_COUNT_BITS_C
+|   |   |   |   |   |   +--->BN_MP_ABS_C
+|   |   |   |   |   |   +--->BN_MP_MUL_2D_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_CMP_C
+|   |   |   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   |   |   +--->BN_MP_CLEAR_MULTI_C
+|   |   |   |   |   |   |   +--->BN_MP_CLEAR_C
+|   |   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   |   +--->BN_MP_MUL_D_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_CLEAR_C
+|   |   |   |   |   +--->BN_MP_CLEAR_C
+|   |   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   +--->BN_MP_COPY_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_DIV_2_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_CMP_C
+|   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   +--->BN_MP_CLEAR_MULTI_C
+|   |   |   |   |   +--->BN_MP_CLEAR_C
+|   |   +--->BN_MP_CLEAR_C
+|   |   +--->BN_MP_ABS_C
+|   |   |   +--->BN_MP_COPY_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_CLEAR_MULTI_C
+|   |   +--->BN_MP_REDUCE_IS_2K_L_C
+|   |   +--->BN_S_MP_EXPTMOD_C
+|   |   |   +--->BN_MP_COUNT_BITS_C
+|   |   |   +--->BN_MP_REDUCE_SETUP_C
+|   |   |   |   +--->BN_MP_2EXPT_C
+|   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_DIV_C
+|   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   +--->BN_MP_COPY_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   +--->BN_MP_INIT_MULTI_C
+|   |   |   |   |   +--->BN_MP_MUL_2D_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_CMP_C
+|   |   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   +--->BN_MP_MUL_D_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_REDUCE_C
+|   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   +--->BN_MP_MUL_C
+|   |   |   |   |   +--->BN_MP_TOOM_MUL_C
+|   |   |   |   |   |   +--->BN_MP_INIT_MULTI_C
+|   |   |   |   |   |   +--->BN_MP_MOD_2D_C
+|   |   |   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   |   |   +--->BN_MP_COPY_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_COPY_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_MUL_2_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_DIV_2_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_MUL_2D_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_MUL_D_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_DIV_3_C
+|   |   |   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_KARATSUBA_MUL_C
+|   |   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_FAST_S_MP_MUL_DIGS_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_S_MP_MUL_DIGS_C
+|   |   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   +--->BN_S_MP_MUL_HIGH_DIGS_C
+|   |   |   |   |   +--->BN_FAST_S_MP_MUL_HIGH_DIGS_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   +--->BN_FAST_S_MP_MUL_HIGH_DIGS_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_MOD_2D_C
+|   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   +--->BN_MP_COPY_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_S_MP_MUL_DIGS_C
+|   |   |   |   |   +--->BN_FAST_S_MP_MUL_DIGS_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_CMP_C
+|   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_REDUCE_2K_SETUP_L_C
+|   |   |   |   +--->BN_MP_2EXPT_C
+|   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_REDUCE_2K_L_C
+|   |   |   |   +--->BN_MP_MUL_C
+|   |   |   |   |   +--->BN_MP_TOOM_MUL_C
+|   |   |   |   |   |   +--->BN_MP_INIT_MULTI_C
+|   |   |   |   |   |   +--->BN_MP_MOD_2D_C
+|   |   |   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   |   |   +--->BN_MP_COPY_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_COPY_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   |   +--->BN_MP_MUL_2_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_DIV_2_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_MUL_2D_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_MUL_D_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_DIV_3_C
+|   |   |   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_KARATSUBA_MUL_C
+|   |   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   +--->BN_FAST_S_MP_MUL_DIGS_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_S_MP_MUL_DIGS_C
+|   |   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_MOD_C
+|   |   |   |   +--->BN_MP_DIV_C
+|   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   +--->BN_MP_COPY_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   +--->BN_MP_INIT_MULTI_C
+|   |   |   |   |   +--->BN_MP_MUL_2D_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_CMP_C
+|   |   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   +--->BN_MP_MUL_D_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   +--->BN_MP_COPY_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_SQR_C
+|   |   |   |   +--->BN_MP_TOOM_SQR_C
+|   |   |   |   |   +--->BN_MP_INIT_MULTI_C
+|   |   |   |   |   +--->BN_MP_MOD_2D_C
+|   |   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   +--->BN_MP_MUL_2_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_DIV_2_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_MUL_2D_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_MUL_D_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_DIV_3_C
+|   |   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_KARATSUBA_SQR_C
+|   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_FAST_S_MP_SQR_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_S_MP_SQR_C
+|   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   +--->BN_MP_MUL_C
+|   |   |   |   +--->BN_MP_TOOM_MUL_C
+|   |   |   |   |   +--->BN_MP_INIT_MULTI_C
+|   |   |   |   |   +--->BN_MP_MOD_2D_C
+|   |   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   +--->BN_MP_MUL_2_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_DIV_2_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_MUL_2D_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_MUL_D_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_DIV_3_C
+|   |   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_KARATSUBA_MUL_C
+|   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   +--->BN_FAST_S_MP_MUL_DIGS_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_S_MP_MUL_DIGS_C
+|   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   +--->BN_MP_EXCH_C
+|   |   +--->BN_MP_DR_IS_MODULUS_C
+|   |   +--->BN_MP_REDUCE_IS_2K_C
+|   |   |   +--->BN_MP_REDUCE_2K_C
+|   |   |   |   +--->BN_MP_COUNT_BITS_C
+|   |   |   |   +--->BN_MP_MUL_D_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_COUNT_BITS_C
+|   |   +--->BN_MP_EXPTMOD_FAST_C
+|   |   |   +--->BN_MP_COUNT_BITS_C
+|   |   |   +--->BN_MP_MONTGOMERY_SETUP_C
+|   |   |   +--->BN_FAST_MP_MONTGOMERY_REDUCE_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   +--->BN_MP_MONTGOMERY_REDUCE_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   +--->BN_MP_DR_SETUP_C
+|   |   |   +--->BN_MP_DR_REDUCE_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   +--->BN_MP_REDUCE_2K_SETUP_C
+|   |   |   |   +--->BN_MP_2EXPT_C
+|   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_REDUCE_2K_C
+|   |   |   |   +--->BN_MP_MUL_D_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_MONTGOMERY_CALC_NORMALIZATION_C
+|   |   |   |   +--->BN_MP_2EXPT_C
+|   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_MUL_2_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_MULMOD_C
+|   |   |   |   +--->BN_MP_MUL_C
+|   |   |   |   |   +--->BN_MP_TOOM_MUL_C
+|   |   |   |   |   |   +--->BN_MP_INIT_MULTI_C
+|   |   |   |   |   |   +--->BN_MP_MOD_2D_C
+|   |   |   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   |   |   +--->BN_MP_COPY_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_COPY_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   |   +--->BN_MP_MUL_2_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_DIV_2_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_MUL_2D_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_MUL_D_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_DIV_3_C
+|   |   |   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_KARATSUBA_MUL_C
+|   |   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   +--->BN_FAST_S_MP_MUL_DIGS_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_S_MP_MUL_DIGS_C
+|   |   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   +--->BN_MP_MOD_C
+|   |   |   |   |   +--->BN_MP_DIV_C
+|   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   +--->BN_MP_COPY_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   |   +--->BN_MP_INIT_MULTI_C
+|   |   |   |   |   |   +--->BN_MP_MUL_2D_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_CMP_C
+|   |   |   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   |   +--->BN_MP_MUL_D_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   +--->BN_MP_MOD_C
+|   |   |   |   +--->BN_MP_DIV_C
+|   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   +--->BN_MP_COPY_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   +--->BN_MP_INIT_MULTI_C
+|   |   |   |   |   +--->BN_MP_MUL_2D_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_CMP_C
+|   |   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   +--->BN_MP_MUL_D_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   +--->BN_MP_COPY_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_SQR_C
+|   |   |   |   +--->BN_MP_TOOM_SQR_C
+|   |   |   |   |   +--->BN_MP_INIT_MULTI_C
+|   |   |   |   |   +--->BN_MP_MOD_2D_C
+|   |   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   +--->BN_MP_MUL_2_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_DIV_2_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_MUL_2D_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_MUL_D_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_DIV_3_C
+|   |   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_KARATSUBA_SQR_C
+|   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_FAST_S_MP_SQR_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_S_MP_SQR_C
+|   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   +--->BN_MP_MUL_C
+|   |   |   |   +--->BN_MP_TOOM_MUL_C
+|   |   |   |   |   +--->BN_MP_INIT_MULTI_C
+|   |   |   |   |   +--->BN_MP_MOD_2D_C
+|   |   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   +--->BN_MP_MUL_2_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_DIV_2_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_MUL_2D_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_MUL_D_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_DIV_3_C
+|   |   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_KARATSUBA_MUL_C
+|   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   +--->BN_FAST_S_MP_MUL_DIGS_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_S_MP_MUL_DIGS_C
+|   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   +--->BN_MP_EXCH_C
+|   +--->BN_MP_CMP_C
+|   |   +--->BN_MP_CMP_MAG_C
+|   +--->BN_MP_SQRMOD_C
+|   |   +--->BN_MP_SQR_C
+|   |   |   +--->BN_MP_TOOM_SQR_C
+|   |   |   |   +--->BN_MP_INIT_MULTI_C
+|   |   |   |   |   +--->BN_MP_CLEAR_C
+|   |   |   |   +--->BN_MP_MOD_2D_C
+|   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   +--->BN_MP_COPY_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_COPY_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   +--->BN_MP_MUL_2_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_DIV_2_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_MUL_2D_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_MUL_D_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_DIV_3_C
+|   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   |   +--->BN_MP_CLEAR_C
+|   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLEAR_MULTI_C
+|   |   |   |   |   +--->BN_MP_CLEAR_C
+|   |   |   +--->BN_MP_KARATSUBA_SQR_C
+|   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLEAR_C
+|   |   |   +--->BN_FAST_S_MP_SQR_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_S_MP_SQR_C
+|   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   +--->BN_MP_CLEAR_C
+|   |   +--->BN_MP_CLEAR_C
+|   |   +--->BN_MP_MOD_C
+|   |   |   +--->BN_MP_DIV_C
+|   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   +--->BN_MP_COPY_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   +--->BN_MP_INIT_MULTI_C
+|   |   |   |   +--->BN_MP_COUNT_BITS_C
+|   |   |   |   +--->BN_MP_ABS_C
+|   |   |   |   +--->BN_MP_MUL_2D_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   +--->BN_MP_CLEAR_MULTI_C
+|   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   +--->BN_MP_MUL_D_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_ADD_C
+|   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_EXCH_C
+|   +--->BN_MP_CLEAR_C
++--->BN_MP_CLEAR_C
+
+
+BN_MP_COPY_C
++--->BN_MP_GROW_C
+
+
+BN_S_MP_SUB_C
++--->BN_MP_GROW_C
++--->BN_MP_CLAMP_C
+
+
+BN_MP_READ_UNSIGNED_BIN_C
++--->BN_MP_GROW_C
++--->BN_MP_ZERO_C
++--->BN_MP_MUL_2D_C
+|   +--->BN_MP_COPY_C
+|   +--->BN_MP_LSHD_C
+|   |   +--->BN_MP_RSHD_C
+|   +--->BN_MP_CLAMP_C
++--->BN_MP_CLAMP_C
+
+
+BN_MP_EXPTMOD_FAST_C
++--->BN_MP_COUNT_BITS_C
++--->BN_MP_INIT_C
++--->BN_MP_CLEAR_C
++--->BN_MP_MONTGOMERY_SETUP_C
++--->BN_FAST_MP_MONTGOMERY_REDUCE_C
+|   +--->BN_MP_GROW_C
+|   +--->BN_MP_RSHD_C
+|   |   +--->BN_MP_ZERO_C
+|   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_CMP_MAG_C
+|   +--->BN_S_MP_SUB_C
++--->BN_MP_MONTGOMERY_REDUCE_C
+|   +--->BN_MP_GROW_C
+|   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_RSHD_C
+|   |   +--->BN_MP_ZERO_C
+|   +--->BN_MP_CMP_MAG_C
+|   +--->BN_S_MP_SUB_C
++--->BN_MP_DR_SETUP_C
++--->BN_MP_DR_REDUCE_C
+|   +--->BN_MP_GROW_C
+|   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_CMP_MAG_C
+|   +--->BN_S_MP_SUB_C
++--->BN_MP_REDUCE_2K_SETUP_C
+|   +--->BN_MP_2EXPT_C
+|   |   +--->BN_MP_ZERO_C
+|   |   +--->BN_MP_GROW_C
+|   +--->BN_S_MP_SUB_C
+|   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_CLAMP_C
++--->BN_MP_REDUCE_2K_C
+|   +--->BN_MP_DIV_2D_C
+|   |   +--->BN_MP_COPY_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_ZERO_C
+|   |   +--->BN_MP_MOD_2D_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_RSHD_C
+|   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_EXCH_C
+|   +--->BN_MP_MUL_D_C
+|   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_CLAMP_C
+|   +--->BN_S_MP_ADD_C
+|   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_CMP_MAG_C
+|   +--->BN_S_MP_SUB_C
+|   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_CLAMP_C
++--->BN_MP_MONTGOMERY_CALC_NORMALIZATION_C
+|   +--->BN_MP_2EXPT_C
+|   |   +--->BN_MP_ZERO_C
+|   |   +--->BN_MP_GROW_C
+|   +--->BN_MP_SET_C
+|   |   +--->BN_MP_ZERO_C
+|   +--->BN_MP_MUL_2_C
+|   |   +--->BN_MP_GROW_C
+|   +--->BN_MP_CMP_MAG_C
+|   +--->BN_S_MP_SUB_C
+|   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_CLAMP_C
++--->BN_MP_MULMOD_C
+|   +--->BN_MP_MUL_C
+|   |   +--->BN_MP_TOOM_MUL_C
+|   |   |   +--->BN_MP_INIT_MULTI_C
+|   |   |   +--->BN_MP_MOD_2D_C
+|   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   +--->BN_MP_COPY_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_COPY_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   +--->BN_MP_MUL_2_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_ADD_C
+|   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_SUB_C
+|   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_DIV_2_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_MUL_2D_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_MUL_D_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_DIV_3_C
+|   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLEAR_MULTI_C
+|   |   +--->BN_MP_KARATSUBA_MUL_C
+|   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_SUB_C
+|   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_ADD_C
+|   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   +--->BN_FAST_S_MP_MUL_DIGS_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_S_MP_MUL_DIGS_C
+|   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_EXCH_C
+|   +--->BN_MP_MOD_C
+|   |   +--->BN_MP_DIV_C
+|   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   +--->BN_MP_COPY_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_ZERO_C
+|   |   |   +--->BN_MP_INIT_MULTI_C
+|   |   |   +--->BN_MP_SET_C
+|   |   |   +--->BN_MP_ABS_C
+|   |   |   +--->BN_MP_MUL_2D_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_CMP_C
+|   |   |   +--->BN_MP_SUB_C
+|   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_ADD_C
+|   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_DIV_2D_C
+|   |   |   |   +--->BN_MP_MOD_2D_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   +--->BN_MP_EXCH_C
+|   |   |   +--->BN_MP_CLEAR_MULTI_C
+|   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   +--->BN_MP_INIT_COPY_C
+|   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   +--->BN_MP_RSHD_C
+|   |   |   +--->BN_MP_MUL_D_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_ADD_C
+|   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_EXCH_C
++--->BN_MP_SET_C
+|   +--->BN_MP_ZERO_C
++--->BN_MP_MOD_C
+|   +--->BN_MP_DIV_C
+|   |   +--->BN_MP_CMP_MAG_C
+|   |   +--->BN_MP_COPY_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_ZERO_C
+|   |   +--->BN_MP_INIT_MULTI_C
+|   |   +--->BN_MP_ABS_C
+|   |   +--->BN_MP_MUL_2D_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_CMP_C
+|   |   +--->BN_MP_SUB_C
+|   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_ADD_C
+|   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_DIV_2D_C
+|   |   |   +--->BN_MP_MOD_2D_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_RSHD_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_EXCH_C
+|   |   +--->BN_MP_EXCH_C
+|   |   +--->BN_MP_CLEAR_MULTI_C
+|   |   +--->BN_MP_INIT_SIZE_C
+|   |   +--->BN_MP_INIT_COPY_C
+|   |   +--->BN_MP_LSHD_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_RSHD_C
+|   |   +--->BN_MP_RSHD_C
+|   |   +--->BN_MP_MUL_D_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_ADD_C
+|   |   +--->BN_S_MP_ADD_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_CMP_MAG_C
+|   |   +--->BN_S_MP_SUB_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_EXCH_C
++--->BN_MP_COPY_C
+|   +--->BN_MP_GROW_C
++--->BN_MP_SQR_C
+|   +--->BN_MP_TOOM_SQR_C
+|   |   +--->BN_MP_INIT_MULTI_C
+|   |   +--->BN_MP_MOD_2D_C
+|   |   |   +--->BN_MP_ZERO_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_RSHD_C
+|   |   |   +--->BN_MP_ZERO_C
+|   |   +--->BN_MP_MUL_2_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_ADD_C
+|   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_SUB_C
+|   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_DIV_2_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_MUL_2D_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_LSHD_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_MUL_D_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_DIV_3_C
+|   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_EXCH_C
+|   |   +--->BN_MP_LSHD_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_CLEAR_MULTI_C
+|   +--->BN_MP_KARATSUBA_SQR_C
+|   |   +--->BN_MP_INIT_SIZE_C
+|   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_SUB_C
+|   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_S_MP_ADD_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_LSHD_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   +--->BN_MP_ZERO_C
+|   |   +--->BN_MP_ADD_C
+|   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   +--->BN_FAST_S_MP_SQR_C
+|   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_CLAMP_C
+|   +--->BN_S_MP_SQR_C
+|   |   +--->BN_MP_INIT_SIZE_C
+|   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_EXCH_C
++--->BN_MP_MUL_C
+|   +--->BN_MP_TOOM_MUL_C
+|   |   +--->BN_MP_INIT_MULTI_C
+|   |   +--->BN_MP_MOD_2D_C
+|   |   |   +--->BN_MP_ZERO_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_RSHD_C
+|   |   |   +--->BN_MP_ZERO_C
+|   |   +--->BN_MP_MUL_2_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_ADD_C
+|   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_SUB_C
+|   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_DIV_2_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_MUL_2D_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_LSHD_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_MUL_D_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_DIV_3_C
+|   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_EXCH_C
+|   |   +--->BN_MP_LSHD_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_CLEAR_MULTI_C
+|   +--->BN_MP_KARATSUBA_MUL_C
+|   |   +--->BN_MP_INIT_SIZE_C
+|   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_SUB_C
+|   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_ADD_C
+|   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_LSHD_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   +--->BN_MP_ZERO_C
+|   +--->BN_FAST_S_MP_MUL_DIGS_C
+|   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_CLAMP_C
+|   +--->BN_S_MP_MUL_DIGS_C
+|   |   +--->BN_MP_INIT_SIZE_C
+|   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_EXCH_C
++--->BN_MP_EXCH_C
+
+
+BN_MP_TO_UNSIGNED_BIN_C
++--->BN_MP_INIT_COPY_C
+|   +--->BN_MP_COPY_C
+|   |   +--->BN_MP_GROW_C
++--->BN_MP_DIV_2D_C
+|   +--->BN_MP_COPY_C
+|   |   +--->BN_MP_GROW_C
+|   +--->BN_MP_ZERO_C
+|   +--->BN_MP_MOD_2D_C
+|   |   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_CLEAR_C
+|   +--->BN_MP_RSHD_C
+|   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_EXCH_C
++--->BN_MP_CLEAR_C
+
+
+BN_MP_SET_INT_C
++--->BN_MP_ZERO_C
++--->BN_MP_MUL_2D_C
+|   +--->BN_MP_COPY_C
+|   |   +--->BN_MP_GROW_C
+|   +--->BN_MP_GROW_C
+|   +--->BN_MP_LSHD_C
+|   |   +--->BN_MP_RSHD_C
+|   +--->BN_MP_CLAMP_C
++--->BN_MP_CLAMP_C
+
+
+BN_MP_MOD_D_C
++--->BN_MP_DIV_D_C
+|   +--->BN_MP_COPY_C
+|   |   +--->BN_MP_GROW_C
+|   +--->BN_MP_DIV_2D_C
+|   |   +--->BN_MP_ZERO_C
+|   |   +--->BN_MP_INIT_C
+|   |   +--->BN_MP_MOD_2D_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_CLEAR_C
+|   |   +--->BN_MP_RSHD_C
+|   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_EXCH_C
+|   +--->BN_MP_DIV_3_C
+|   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   +--->BN_MP_INIT_C
+|   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_EXCH_C
+|   |   +--->BN_MP_CLEAR_C
+|   +--->BN_MP_INIT_SIZE_C
+|   |   +--->BN_MP_INIT_C
+|   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_EXCH_C
+|   +--->BN_MP_CLEAR_C
+
+
+BN_MP_SQR_C
++--->BN_MP_TOOM_SQR_C
+|   +--->BN_MP_INIT_MULTI_C
+|   |   +--->BN_MP_INIT_C
+|   |   +--->BN_MP_CLEAR_C
+|   +--->BN_MP_MOD_2D_C
+|   |   +--->BN_MP_ZERO_C
+|   |   +--->BN_MP_COPY_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_COPY_C
+|   |   +--->BN_MP_GROW_C
+|   +--->BN_MP_RSHD_C
+|   |   +--->BN_MP_ZERO_C
+|   +--->BN_MP_MUL_2_C
+|   |   +--->BN_MP_GROW_C
+|   +--->BN_MP_ADD_C
+|   |   +--->BN_S_MP_ADD_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_CMP_MAG_C
+|   |   +--->BN_S_MP_SUB_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_SUB_C
+|   |   +--->BN_S_MP_ADD_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_CMP_MAG_C
+|   |   +--->BN_S_MP_SUB_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_DIV_2_C
+|   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_MUL_2D_C
+|   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_LSHD_C
+|   |   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_MUL_D_C
+|   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_DIV_3_C
+|   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   +--->BN_MP_INIT_C
+|   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_EXCH_C
+|   |   +--->BN_MP_CLEAR_C
+|   +--->BN_MP_LSHD_C
+|   |   +--->BN_MP_GROW_C
+|   +--->BN_MP_CLEAR_MULTI_C
+|   |   +--->BN_MP_CLEAR_C
++--->BN_MP_KARATSUBA_SQR_C
+|   +--->BN_MP_INIT_SIZE_C
+|   |   +--->BN_MP_INIT_C
+|   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_SUB_C
+|   |   +--->BN_S_MP_ADD_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_CMP_MAG_C
+|   |   +--->BN_S_MP_SUB_C
+|   |   |   +--->BN_MP_GROW_C
+|   +--->BN_S_MP_ADD_C
+|   |   +--->BN_MP_GROW_C
+|   +--->BN_MP_LSHD_C
+|   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_RSHD_C
+|   |   |   +--->BN_MP_ZERO_C
+|   +--->BN_MP_ADD_C
+|   |   +--->BN_MP_CMP_MAG_C
+|   |   +--->BN_S_MP_SUB_C
+|   |   |   +--->BN_MP_GROW_C
+|   +--->BN_MP_CLEAR_C
++--->BN_FAST_S_MP_SQR_C
+|   +--->BN_MP_GROW_C
+|   +--->BN_MP_CLAMP_C
++--->BN_S_MP_SQR_C
+|   +--->BN_MP_INIT_SIZE_C
+|   |   +--->BN_MP_INIT_C
+|   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_EXCH_C
+|   +--->BN_MP_CLEAR_C
+
+
+BN_MP_MULMOD_C
++--->BN_MP_INIT_C
++--->BN_MP_MUL_C
+|   +--->BN_MP_TOOM_MUL_C
+|   |   +--->BN_MP_INIT_MULTI_C
+|   |   |   +--->BN_MP_CLEAR_C
+|   |   +--->BN_MP_MOD_2D_C
+|   |   |   +--->BN_MP_ZERO_C
+|   |   |   +--->BN_MP_COPY_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_COPY_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_RSHD_C
+|   |   |   +--->BN_MP_ZERO_C
+|   |   +--->BN_MP_MUL_2_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_ADD_C
+|   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_SUB_C
+|   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_DIV_2_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_MUL_2D_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_LSHD_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_MUL_D_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_DIV_3_C
+|   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_EXCH_C
+|   |   |   +--->BN_MP_CLEAR_C
+|   |   +--->BN_MP_LSHD_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_CLEAR_MULTI_C
+|   |   |   +--->BN_MP_CLEAR_C
+|   +--->BN_MP_KARATSUBA_MUL_C
+|   |   +--->BN_MP_INIT_SIZE_C
+|   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_SUB_C
+|   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_ADD_C
+|   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_LSHD_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   +--->BN_MP_ZERO_C
+|   |   +--->BN_MP_CLEAR_C
+|   +--->BN_FAST_S_MP_MUL_DIGS_C
+|   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_CLAMP_C
+|   +--->BN_S_MP_MUL_DIGS_C
+|   |   +--->BN_MP_INIT_SIZE_C
+|   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_EXCH_C
+|   |   +--->BN_MP_CLEAR_C
++--->BN_MP_CLEAR_C
++--->BN_MP_MOD_C
+|   +--->BN_MP_DIV_C
+|   |   +--->BN_MP_CMP_MAG_C
+|   |   +--->BN_MP_COPY_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_ZERO_C
+|   |   +--->BN_MP_INIT_MULTI_C
+|   |   +--->BN_MP_SET_C
+|   |   +--->BN_MP_COUNT_BITS_C
+|   |   +--->BN_MP_ABS_C
+|   |   +--->BN_MP_MUL_2D_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_CMP_C
+|   |   +--->BN_MP_SUB_C
+|   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_ADD_C
+|   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_DIV_2D_C
+|   |   |   +--->BN_MP_MOD_2D_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_RSHD_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_EXCH_C
+|   |   +--->BN_MP_EXCH_C
+|   |   +--->BN_MP_CLEAR_MULTI_C
+|   |   +--->BN_MP_INIT_SIZE_C
+|   |   +--->BN_MP_INIT_COPY_C
+|   |   +--->BN_MP_LSHD_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_RSHD_C
+|   |   +--->BN_MP_RSHD_C
+|   |   +--->BN_MP_MUL_D_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_ADD_C
+|   |   +--->BN_S_MP_ADD_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_CMP_MAG_C
+|   |   +--->BN_S_MP_SUB_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_EXCH_C
+
+
+BN_MP_DIV_2D_C
++--->BN_MP_COPY_C
+|   +--->BN_MP_GROW_C
++--->BN_MP_ZERO_C
++--->BN_MP_INIT_C
++--->BN_MP_MOD_2D_C
+|   +--->BN_MP_CLAMP_C
++--->BN_MP_CLEAR_C
++--->BN_MP_RSHD_C
++--->BN_MP_CLAMP_C
++--->BN_MP_EXCH_C
+
+
+BN_S_MP_ADD_C
++--->BN_MP_GROW_C
++--->BN_MP_CLAMP_C
+
+
+BN_FAST_S_MP_SQR_C
++--->BN_MP_GROW_C
++--->BN_MP_CLAMP_C
+
+
+BN_S_MP_MUL_DIGS_C
++--->BN_FAST_S_MP_MUL_DIGS_C
+|   +--->BN_MP_GROW_C
+|   +--->BN_MP_CLAMP_C
++--->BN_MP_INIT_SIZE_C
+|   +--->BN_MP_INIT_C
++--->BN_MP_CLAMP_C
++--->BN_MP_EXCH_C
++--->BN_MP_CLEAR_C
+
+
+BN_MP_XOR_C
++--->BN_MP_INIT_COPY_C
+|   +--->BN_MP_COPY_C
+|   |   +--->BN_MP_GROW_C
++--->BN_MP_CLAMP_C
++--->BN_MP_EXCH_C
++--->BN_MP_CLEAR_C
+
+
+BN_MP_RADIX_SMAP_C
+
+
+BN_MP_DR_IS_MODULUS_C
+
+
+BN_MP_MONTGOMERY_CALC_NORMALIZATION_C
++--->BN_MP_COUNT_BITS_C
++--->BN_MP_2EXPT_C
+|   +--->BN_MP_ZERO_C
+|   +--->BN_MP_GROW_C
++--->BN_MP_SET_C
+|   +--->BN_MP_ZERO_C
++--->BN_MP_MUL_2_C
+|   +--->BN_MP_GROW_C
++--->BN_MP_CMP_MAG_C
++--->BN_S_MP_SUB_C
+|   +--->BN_MP_GROW_C
+|   +--->BN_MP_CLAMP_C
+
+
+BN_MP_SUB_C
++--->BN_S_MP_ADD_C
+|   +--->BN_MP_GROW_C
+|   +--->BN_MP_CLAMP_C
++--->BN_MP_CMP_MAG_C
++--->BN_S_MP_SUB_C
+|   +--->BN_MP_GROW_C
+|   +--->BN_MP_CLAMP_C
+
+
+BN_MP_INIT_MULTI_C
++--->BN_MP_INIT_C
++--->BN_MP_CLEAR_C
+
+
+BN_S_MP_MUL_HIGH_DIGS_C
++--->BN_FAST_S_MP_MUL_HIGH_DIGS_C
+|   +--->BN_MP_GROW_C
+|   +--->BN_MP_CLAMP_C
++--->BN_MP_INIT_SIZE_C
+|   +--->BN_MP_INIT_C
++--->BN_MP_CLAMP_C
++--->BN_MP_EXCH_C
++--->BN_MP_CLEAR_C
+
+
+BN_MP_PRIME_NEXT_PRIME_C
++--->BN_MP_CMP_D_C
++--->BN_MP_SET_C
+|   +--->BN_MP_ZERO_C
++--->BN_MP_SUB_D_C
+|   +--->BN_MP_GROW_C
+|   +--->BN_MP_ADD_D_C
+|   |   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_CLAMP_C
++--->BN_MP_MOD_D_C
+|   +--->BN_MP_DIV_D_C
+|   |   +--->BN_MP_COPY_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_DIV_2D_C
+|   |   |   +--->BN_MP_ZERO_C
+|   |   |   +--->BN_MP_INIT_C
+|   |   |   +--->BN_MP_MOD_2D_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_CLEAR_C
+|   |   |   +--->BN_MP_RSHD_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_EXCH_C
+|   |   +--->BN_MP_DIV_3_C
+|   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   +--->BN_MP_INIT_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_EXCH_C
+|   |   |   +--->BN_MP_CLEAR_C
+|   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   +--->BN_MP_INIT_C
+|   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_EXCH_C
+|   |   +--->BN_MP_CLEAR_C
++--->BN_MP_INIT_C
++--->BN_MP_ADD_D_C
+|   +--->BN_MP_GROW_C
+|   +--->BN_MP_CLAMP_C
++--->BN_MP_PRIME_MILLER_RABIN_C
+|   +--->BN_MP_INIT_COPY_C
+|   |   +--->BN_MP_COPY_C
+|   |   |   +--->BN_MP_GROW_C
+|   +--->BN_MP_CNT_LSB_C
+|   +--->BN_MP_DIV_2D_C
+|   |   +--->BN_MP_COPY_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_ZERO_C
+|   |   +--->BN_MP_MOD_2D_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_CLEAR_C
+|   |   +--->BN_MP_RSHD_C
+|   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_EXCH_C
+|   +--->BN_MP_EXPTMOD_C
+|   |   +--->BN_MP_INVMOD_C
+|   |   |   +--->BN_FAST_MP_INVMOD_C
+|   |   |   |   +--->BN_MP_INIT_MULTI_C
+|   |   |   |   |   +--->BN_MP_CLEAR_C
+|   |   |   |   +--->BN_MP_COPY_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_MOD_C
+|   |   |   |   |   +--->BN_MP_DIV_C
+|   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   |   +--->BN_MP_COUNT_BITS_C
+|   |   |   |   |   |   +--->BN_MP_ABS_C
+|   |   |   |   |   |   +--->BN_MP_MUL_2D_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_CMP_C
+|   |   |   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   |   |   +--->BN_MP_CLEAR_MULTI_C
+|   |   |   |   |   |   |   +--->BN_MP_CLEAR_C
+|   |   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   |   +--->BN_MP_MUL_D_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_CLEAR_C
+|   |   |   |   |   +--->BN_MP_CLEAR_C
+|   |   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   +--->BN_MP_DIV_2_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_CMP_C
+|   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   +--->BN_MP_CLEAR_MULTI_C
+|   |   |   |   |   +--->BN_MP_CLEAR_C
+|   |   |   +--->BN_MP_INVMOD_SLOW_C
+|   |   |   |   +--->BN_MP_INIT_MULTI_C
+|   |   |   |   |   +--->BN_MP_CLEAR_C
+|   |   |   |   +--->BN_MP_MOD_C
+|   |   |   |   |   +--->BN_MP_DIV_C
+|   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   +--->BN_MP_COPY_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   |   +--->BN_MP_COUNT_BITS_C
+|   |   |   |   |   |   +--->BN_MP_ABS_C
+|   |   |   |   |   |   +--->BN_MP_MUL_2D_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_CMP_C
+|   |   |   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   |   |   +--->BN_MP_CLEAR_MULTI_C
+|   |   |   |   |   |   |   +--->BN_MP_CLEAR_C
+|   |   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   |   +--->BN_MP_MUL_D_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_CLEAR_C
+|   |   |   |   |   +--->BN_MP_CLEAR_C
+|   |   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   +--->BN_MP_COPY_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_DIV_2_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_CMP_C
+|   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   +--->BN_MP_CLEAR_MULTI_C
+|   |   |   |   |   +--->BN_MP_CLEAR_C
+|   |   +--->BN_MP_CLEAR_C
+|   |   +--->BN_MP_ABS_C
+|   |   |   +--->BN_MP_COPY_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_CLEAR_MULTI_C
+|   |   +--->BN_MP_REDUCE_IS_2K_L_C
+|   |   +--->BN_S_MP_EXPTMOD_C
+|   |   |   +--->BN_MP_COUNT_BITS_C
+|   |   |   +--->BN_MP_REDUCE_SETUP_C
+|   |   |   |   +--->BN_MP_2EXPT_C
+|   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_DIV_C
+|   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   +--->BN_MP_COPY_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   +--->BN_MP_INIT_MULTI_C
+|   |   |   |   |   +--->BN_MP_MUL_2D_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_CMP_C
+|   |   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   +--->BN_MP_MUL_D_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_REDUCE_C
+|   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   +--->BN_MP_MUL_C
+|   |   |   |   |   +--->BN_MP_TOOM_MUL_C
+|   |   |   |   |   |   +--->BN_MP_INIT_MULTI_C
+|   |   |   |   |   |   +--->BN_MP_MOD_2D_C
+|   |   |   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   |   |   +--->BN_MP_COPY_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_COPY_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_MUL_2_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_DIV_2_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_MUL_2D_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_MUL_D_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_DIV_3_C
+|   |   |   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_KARATSUBA_MUL_C
+|   |   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_FAST_S_MP_MUL_DIGS_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_S_MP_MUL_DIGS_C
+|   |   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   +--->BN_S_MP_MUL_HIGH_DIGS_C
+|   |   |   |   |   +--->BN_FAST_S_MP_MUL_HIGH_DIGS_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   +--->BN_FAST_S_MP_MUL_HIGH_DIGS_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_MOD_2D_C
+|   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   +--->BN_MP_COPY_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_S_MP_MUL_DIGS_C
+|   |   |   |   |   +--->BN_FAST_S_MP_MUL_DIGS_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_CMP_C
+|   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_REDUCE_2K_SETUP_L_C
+|   |   |   |   +--->BN_MP_2EXPT_C
+|   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_REDUCE_2K_L_C
+|   |   |   |   +--->BN_MP_MUL_C
+|   |   |   |   |   +--->BN_MP_TOOM_MUL_C
+|   |   |   |   |   |   +--->BN_MP_INIT_MULTI_C
+|   |   |   |   |   |   +--->BN_MP_MOD_2D_C
+|   |   |   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   |   |   +--->BN_MP_COPY_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_COPY_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   |   +--->BN_MP_MUL_2_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_DIV_2_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_MUL_2D_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_MUL_D_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_DIV_3_C
+|   |   |   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_KARATSUBA_MUL_C
+|   |   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   +--->BN_FAST_S_MP_MUL_DIGS_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_S_MP_MUL_DIGS_C
+|   |   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_MOD_C
+|   |   |   |   +--->BN_MP_DIV_C
+|   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   +--->BN_MP_COPY_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   +--->BN_MP_INIT_MULTI_C
+|   |   |   |   |   +--->BN_MP_MUL_2D_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_CMP_C
+|   |   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   +--->BN_MP_MUL_D_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   +--->BN_MP_COPY_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_SQR_C
+|   |   |   |   +--->BN_MP_TOOM_SQR_C
+|   |   |   |   |   +--->BN_MP_INIT_MULTI_C
+|   |   |   |   |   +--->BN_MP_MOD_2D_C
+|   |   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   +--->BN_MP_MUL_2_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_DIV_2_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_MUL_2D_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_MUL_D_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_DIV_3_C
+|   |   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_KARATSUBA_SQR_C
+|   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_FAST_S_MP_SQR_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_S_MP_SQR_C
+|   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   +--->BN_MP_MUL_C
+|   |   |   |   +--->BN_MP_TOOM_MUL_C
+|   |   |   |   |   +--->BN_MP_INIT_MULTI_C
+|   |   |   |   |   +--->BN_MP_MOD_2D_C
+|   |   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   +--->BN_MP_MUL_2_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_DIV_2_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_MUL_2D_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_MUL_D_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_DIV_3_C
+|   |   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_KARATSUBA_MUL_C
+|   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   +--->BN_FAST_S_MP_MUL_DIGS_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_S_MP_MUL_DIGS_C
+|   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   +--->BN_MP_EXCH_C
+|   |   +--->BN_MP_DR_IS_MODULUS_C
+|   |   +--->BN_MP_REDUCE_IS_2K_C
+|   |   |   +--->BN_MP_REDUCE_2K_C
+|   |   |   |   +--->BN_MP_COUNT_BITS_C
+|   |   |   |   +--->BN_MP_MUL_D_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_COUNT_BITS_C
+|   |   +--->BN_MP_EXPTMOD_FAST_C
+|   |   |   +--->BN_MP_COUNT_BITS_C
+|   |   |   +--->BN_MP_MONTGOMERY_SETUP_C
+|   |   |   +--->BN_FAST_MP_MONTGOMERY_REDUCE_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   +--->BN_MP_MONTGOMERY_REDUCE_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   +--->BN_MP_DR_SETUP_C
+|   |   |   +--->BN_MP_DR_REDUCE_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   +--->BN_MP_REDUCE_2K_SETUP_C
+|   |   |   |   +--->BN_MP_2EXPT_C
+|   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_REDUCE_2K_C
+|   |   |   |   +--->BN_MP_MUL_D_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_MONTGOMERY_CALC_NORMALIZATION_C
+|   |   |   |   +--->BN_MP_2EXPT_C
+|   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_MUL_2_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_MULMOD_C
+|   |   |   |   +--->BN_MP_MUL_C
+|   |   |   |   |   +--->BN_MP_TOOM_MUL_C
+|   |   |   |   |   |   +--->BN_MP_INIT_MULTI_C
+|   |   |   |   |   |   +--->BN_MP_MOD_2D_C
+|   |   |   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   |   |   +--->BN_MP_COPY_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_COPY_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   |   +--->BN_MP_MUL_2_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_DIV_2_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_MUL_2D_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_MUL_D_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_DIV_3_C
+|   |   |   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_KARATSUBA_MUL_C
+|   |   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   +--->BN_FAST_S_MP_MUL_DIGS_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_S_MP_MUL_DIGS_C
+|   |   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   +--->BN_MP_MOD_C
+|   |   |   |   |   +--->BN_MP_DIV_C
+|   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   +--->BN_MP_COPY_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   |   +--->BN_MP_INIT_MULTI_C
+|   |   |   |   |   |   +--->BN_MP_MUL_2D_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_CMP_C
+|   |   |   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   |   +--->BN_MP_MUL_D_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   +--->BN_MP_MOD_C
+|   |   |   |   +--->BN_MP_DIV_C
+|   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   +--->BN_MP_COPY_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   +--->BN_MP_INIT_MULTI_C
+|   |   |   |   |   +--->BN_MP_MUL_2D_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_CMP_C
+|   |   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   +--->BN_MP_MUL_D_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   +--->BN_MP_COPY_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_SQR_C
+|   |   |   |   +--->BN_MP_TOOM_SQR_C
+|   |   |   |   |   +--->BN_MP_INIT_MULTI_C
+|   |   |   |   |   +--->BN_MP_MOD_2D_C
+|   |   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   +--->BN_MP_MUL_2_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_DIV_2_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_MUL_2D_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_MUL_D_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_DIV_3_C
+|   |   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_KARATSUBA_SQR_C
+|   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_FAST_S_MP_SQR_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_S_MP_SQR_C
+|   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   +--->BN_MP_MUL_C
+|   |   |   |   +--->BN_MP_TOOM_MUL_C
+|   |   |   |   |   +--->BN_MP_INIT_MULTI_C
+|   |   |   |   |   +--->BN_MP_MOD_2D_C
+|   |   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   +--->BN_MP_MUL_2_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_DIV_2_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_MUL_2D_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_MUL_D_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_DIV_3_C
+|   |   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_KARATSUBA_MUL_C
+|   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   +--->BN_FAST_S_MP_MUL_DIGS_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_S_MP_MUL_DIGS_C
+|   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   +--->BN_MP_EXCH_C
+|   +--->BN_MP_CMP_C
+|   |   +--->BN_MP_CMP_MAG_C
+|   +--->BN_MP_SQRMOD_C
+|   |   +--->BN_MP_SQR_C
+|   |   |   +--->BN_MP_TOOM_SQR_C
+|   |   |   |   +--->BN_MP_INIT_MULTI_C
+|   |   |   |   |   +--->BN_MP_CLEAR_C
+|   |   |   |   +--->BN_MP_MOD_2D_C
+|   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   +--->BN_MP_COPY_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_COPY_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   +--->BN_MP_MUL_2_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_DIV_2_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_MUL_2D_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_MUL_D_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_DIV_3_C
+|   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   |   +--->BN_MP_CLEAR_C
+|   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLEAR_MULTI_C
+|   |   |   |   |   +--->BN_MP_CLEAR_C
+|   |   |   +--->BN_MP_KARATSUBA_SQR_C
+|   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLEAR_C
+|   |   |   +--->BN_FAST_S_MP_SQR_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_S_MP_SQR_C
+|   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   +--->BN_MP_CLEAR_C
+|   |   +--->BN_MP_CLEAR_C
+|   |   +--->BN_MP_MOD_C
+|   |   |   +--->BN_MP_DIV_C
+|   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   +--->BN_MP_COPY_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   +--->BN_MP_INIT_MULTI_C
+|   |   |   |   +--->BN_MP_COUNT_BITS_C
+|   |   |   |   +--->BN_MP_ABS_C
+|   |   |   |   +--->BN_MP_MUL_2D_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   +--->BN_MP_CLEAR_MULTI_C
+|   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   +--->BN_MP_MUL_D_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_ADD_C
+|   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_EXCH_C
+|   +--->BN_MP_CLEAR_C
++--->BN_MP_CLEAR_C
+
+
+BN_MP_SIGNED_BIN_SIZE_C
++--->BN_MP_UNSIGNED_BIN_SIZE_C
+|   +--->BN_MP_COUNT_BITS_C
+
+
+BN_MP_INVMOD_SLOW_C
++--->BN_MP_INIT_MULTI_C
+|   +--->BN_MP_INIT_C
+|   +--->BN_MP_CLEAR_C
++--->BN_MP_MOD_C
+|   +--->BN_MP_INIT_C
+|   +--->BN_MP_DIV_C
+|   |   +--->BN_MP_CMP_MAG_C
+|   |   +--->BN_MP_COPY_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_ZERO_C
+|   |   +--->BN_MP_SET_C
+|   |   +--->BN_MP_COUNT_BITS_C
+|   |   +--->BN_MP_ABS_C
+|   |   +--->BN_MP_MUL_2D_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_CMP_C
+|   |   +--->BN_MP_SUB_C
+|   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_ADD_C
+|   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_DIV_2D_C
+|   |   |   +--->BN_MP_MOD_2D_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_CLEAR_C
+|   |   |   +--->BN_MP_RSHD_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_EXCH_C
+|   |   +--->BN_MP_EXCH_C
+|   |   +--->BN_MP_CLEAR_MULTI_C
+|   |   |   +--->BN_MP_CLEAR_C
+|   |   +--->BN_MP_INIT_SIZE_C
+|   |   +--->BN_MP_INIT_COPY_C
+|   |   +--->BN_MP_LSHD_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_RSHD_C
+|   |   +--->BN_MP_RSHD_C
+|   |   +--->BN_MP_MUL_D_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_CLEAR_C
+|   +--->BN_MP_CLEAR_C
+|   +--->BN_MP_ADD_C
+|   |   +--->BN_S_MP_ADD_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_CMP_MAG_C
+|   |   +--->BN_S_MP_SUB_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_EXCH_C
++--->BN_MP_COPY_C
+|   +--->BN_MP_GROW_C
++--->BN_MP_SET_C
+|   +--->BN_MP_ZERO_C
++--->BN_MP_DIV_2_C
+|   +--->BN_MP_GROW_C
+|   +--->BN_MP_CLAMP_C
++--->BN_MP_ADD_C
+|   +--->BN_S_MP_ADD_C
+|   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_CMP_MAG_C
+|   +--->BN_S_MP_SUB_C
+|   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_CLAMP_C
++--->BN_MP_SUB_C
+|   +--->BN_S_MP_ADD_C
+|   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_CMP_MAG_C
+|   +--->BN_S_MP_SUB_C
+|   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_CLAMP_C
++--->BN_MP_CMP_C
+|   +--->BN_MP_CMP_MAG_C
++--->BN_MP_CMP_D_C
++--->BN_MP_CMP_MAG_C
++--->BN_MP_EXCH_C
++--->BN_MP_CLEAR_MULTI_C
+|   +--->BN_MP_CLEAR_C
+
+
+BN_MP_LCM_C
++--->BN_MP_INIT_MULTI_C
+|   +--->BN_MP_INIT_C
+|   +--->BN_MP_CLEAR_C
++--->BN_MP_GCD_C
+|   +--->BN_MP_ABS_C
+|   |   +--->BN_MP_COPY_C
+|   |   |   +--->BN_MP_GROW_C
+|   +--->BN_MP_ZERO_C
+|   +--->BN_MP_INIT_COPY_C
+|   |   +--->BN_MP_COPY_C
+|   |   |   +--->BN_MP_GROW_C
+|   +--->BN_MP_CNT_LSB_C
+|   +--->BN_MP_DIV_2D_C
+|   |   +--->BN_MP_COPY_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_MOD_2D_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_CLEAR_C
+|   |   +--->BN_MP_RSHD_C
+|   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_EXCH_C
+|   +--->BN_MP_CMP_MAG_C
+|   +--->BN_MP_EXCH_C
+|   +--->BN_S_MP_SUB_C
+|   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_MUL_2D_C
+|   |   +--->BN_MP_COPY_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_LSHD_C
+|   |   |   +--->BN_MP_RSHD_C
+|   |   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_CLEAR_C
++--->BN_MP_CMP_MAG_C
++--->BN_MP_DIV_C
+|   +--->BN_MP_COPY_C
+|   |   +--->BN_MP_GROW_C
+|   +--->BN_MP_ZERO_C
+|   +--->BN_MP_SET_C
+|   +--->BN_MP_COUNT_BITS_C
+|   +--->BN_MP_ABS_C
+|   +--->BN_MP_MUL_2D_C
+|   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_LSHD_C
+|   |   |   +--->BN_MP_RSHD_C
+|   |   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_CMP_C
+|   +--->BN_MP_SUB_C
+|   |   +--->BN_S_MP_ADD_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_S_MP_SUB_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_ADD_C
+|   |   +--->BN_S_MP_ADD_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_S_MP_SUB_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_DIV_2D_C
+|   |   +--->BN_MP_INIT_C
+|   |   +--->BN_MP_MOD_2D_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_CLEAR_C
+|   |   +--->BN_MP_RSHD_C
+|   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_EXCH_C
+|   +--->BN_MP_EXCH_C
+|   +--->BN_MP_CLEAR_MULTI_C
+|   |   +--->BN_MP_CLEAR_C
+|   +--->BN_MP_INIT_SIZE_C
+|   |   +--->BN_MP_INIT_C
+|   +--->BN_MP_INIT_C
+|   +--->BN_MP_INIT_COPY_C
+|   +--->BN_MP_LSHD_C
+|   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_RSHD_C
+|   +--->BN_MP_RSHD_C
+|   +--->BN_MP_MUL_D_C
+|   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_CLEAR_C
++--->BN_MP_MUL_C
+|   +--->BN_MP_TOOM_MUL_C
+|   |   +--->BN_MP_MOD_2D_C
+|   |   |   +--->BN_MP_ZERO_C
+|   |   |   +--->BN_MP_COPY_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_COPY_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_RSHD_C
+|   |   |   +--->BN_MP_ZERO_C
+|   |   +--->BN_MP_MUL_2_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_ADD_C
+|   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_SUB_C
+|   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_DIV_2_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_MUL_2D_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_LSHD_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_MUL_D_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_DIV_3_C
+|   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   +--->BN_MP_INIT_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_EXCH_C
+|   |   |   +--->BN_MP_CLEAR_C
+|   |   +--->BN_MP_LSHD_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_CLEAR_MULTI_C
+|   |   |   +--->BN_MP_CLEAR_C
+|   +--->BN_MP_KARATSUBA_MUL_C
+|   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   +--->BN_MP_INIT_C
+|   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_SUB_C
+|   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_ADD_C
+|   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_LSHD_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   +--->BN_MP_ZERO_C
+|   |   +--->BN_MP_CLEAR_C
+|   +--->BN_FAST_S_MP_MUL_DIGS_C
+|   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_CLAMP_C
+|   +--->BN_S_MP_MUL_DIGS_C
+|   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   +--->BN_MP_INIT_C
+|   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_EXCH_C
+|   |   +--->BN_MP_CLEAR_C
++--->BN_MP_CLEAR_MULTI_C
+|   +--->BN_MP_CLEAR_C
+
+
+BN_MP_REDUCE_2K_L_C
++--->BN_MP_INIT_C
++--->BN_MP_COUNT_BITS_C
++--->BN_MP_DIV_2D_C
+|   +--->BN_MP_COPY_C
+|   |   +--->BN_MP_GROW_C
+|   +--->BN_MP_ZERO_C
+|   +--->BN_MP_MOD_2D_C
+|   |   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_CLEAR_C
+|   +--->BN_MP_RSHD_C
+|   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_EXCH_C
++--->BN_MP_MUL_C
+|   +--->BN_MP_TOOM_MUL_C
+|   |   +--->BN_MP_INIT_MULTI_C
+|   |   |   +--->BN_MP_CLEAR_C
+|   |   +--->BN_MP_MOD_2D_C
+|   |   |   +--->BN_MP_ZERO_C
+|   |   |   +--->BN_MP_COPY_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_COPY_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_RSHD_C
+|   |   |   +--->BN_MP_ZERO_C
+|   |   +--->BN_MP_MUL_2_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_ADD_C
+|   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_SUB_C
+|   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_DIV_2_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_MUL_2D_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_LSHD_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_MUL_D_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_DIV_3_C
+|   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_EXCH_C
+|   |   |   +--->BN_MP_CLEAR_C
+|   |   +--->BN_MP_LSHD_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_CLEAR_MULTI_C
+|   |   |   +--->BN_MP_CLEAR_C
+|   +--->BN_MP_KARATSUBA_MUL_C
+|   |   +--->BN_MP_INIT_SIZE_C
+|   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_SUB_C
+|   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_ADD_C
+|   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_LSHD_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   +--->BN_MP_ZERO_C
+|   |   +--->BN_MP_CLEAR_C
+|   +--->BN_FAST_S_MP_MUL_DIGS_C
+|   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_CLAMP_C
+|   +--->BN_S_MP_MUL_DIGS_C
+|   |   +--->BN_MP_INIT_SIZE_C
+|   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_EXCH_C
+|   |   +--->BN_MP_CLEAR_C
++--->BN_S_MP_ADD_C
+|   +--->BN_MP_GROW_C
+|   +--->BN_MP_CLAMP_C
++--->BN_MP_CMP_MAG_C
++--->BN_S_MP_SUB_C
+|   +--->BN_MP_GROW_C
+|   +--->BN_MP_CLAMP_C
++--->BN_MP_CLEAR_C
+
+
+BN_REVERSE_C
+
+
+BN_MP_PRIME_IS_DIVISIBLE_C
++--->BN_MP_MOD_D_C
+|   +--->BN_MP_DIV_D_C
+|   |   +--->BN_MP_COPY_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_DIV_2D_C
+|   |   |   +--->BN_MP_ZERO_C
+|   |   |   +--->BN_MP_INIT_C
+|   |   |   +--->BN_MP_MOD_2D_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_CLEAR_C
+|   |   |   +--->BN_MP_RSHD_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_EXCH_C
+|   |   +--->BN_MP_DIV_3_C
+|   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   +--->BN_MP_INIT_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_EXCH_C
+|   |   |   +--->BN_MP_CLEAR_C
+|   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   +--->BN_MP_INIT_C
+|   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_EXCH_C
+|   |   +--->BN_MP_CLEAR_C
+
+
+BN_MP_SET_C
++--->BN_MP_ZERO_C
+
+
+BN_MP_GCD_C
++--->BN_MP_ABS_C
+|   +--->BN_MP_COPY_C
+|   |   +--->BN_MP_GROW_C
++--->BN_MP_ZERO_C
++--->BN_MP_INIT_COPY_C
+|   +--->BN_MP_COPY_C
+|   |   +--->BN_MP_GROW_C
++--->BN_MP_CNT_LSB_C
++--->BN_MP_DIV_2D_C
+|   +--->BN_MP_COPY_C
+|   |   +--->BN_MP_GROW_C
+|   +--->BN_MP_MOD_2D_C
+|   |   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_CLEAR_C
+|   +--->BN_MP_RSHD_C
+|   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_EXCH_C
++--->BN_MP_CMP_MAG_C
++--->BN_MP_EXCH_C
++--->BN_S_MP_SUB_C
+|   +--->BN_MP_GROW_C
+|   +--->BN_MP_CLAMP_C
++--->BN_MP_MUL_2D_C
+|   +--->BN_MP_COPY_C
+|   |   +--->BN_MP_GROW_C
+|   +--->BN_MP_GROW_C
+|   +--->BN_MP_LSHD_C
+|   |   +--->BN_MP_RSHD_C
+|   +--->BN_MP_CLAMP_C
++--->BN_MP_CLEAR_C
+
+
+BN_MP_REDUCE_2K_SETUP_L_C
++--->BN_MP_INIT_C
++--->BN_MP_2EXPT_C
+|   +--->BN_MP_ZERO_C
+|   +--->BN_MP_GROW_C
++--->BN_MP_COUNT_BITS_C
++--->BN_S_MP_SUB_C
+|   +--->BN_MP_GROW_C
+|   +--->BN_MP_CLAMP_C
++--->BN_MP_CLEAR_C
+
+
+BN_MP_READ_RADIX_C
++--->BN_MP_ZERO_C
++--->BN_MP_MUL_D_C
+|   +--->BN_MP_GROW_C
+|   +--->BN_MP_CLAMP_C
++--->BN_MP_ADD_D_C
+|   +--->BN_MP_GROW_C
+|   +--->BN_MP_SUB_D_C
+|   |   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_CLAMP_C
+
+
+BN_FAST_S_MP_MUL_HIGH_DIGS_C
++--->BN_MP_GROW_C
++--->BN_MP_CLAMP_C
+
+
+BN_FAST_MP_MONTGOMERY_REDUCE_C
++--->BN_MP_GROW_C
++--->BN_MP_RSHD_C
+|   +--->BN_MP_ZERO_C
++--->BN_MP_CLAMP_C
++--->BN_MP_CMP_MAG_C
++--->BN_S_MP_SUB_C
+
+
+BN_MP_DIV_D_C
++--->BN_MP_COPY_C
+|   +--->BN_MP_GROW_C
++--->BN_MP_DIV_2D_C
+|   +--->BN_MP_ZERO_C
+|   +--->BN_MP_INIT_C
+|   +--->BN_MP_MOD_2D_C
+|   |   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_CLEAR_C
+|   +--->BN_MP_RSHD_C
+|   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_EXCH_C
++--->BN_MP_DIV_3_C
+|   +--->BN_MP_INIT_SIZE_C
+|   |   +--->BN_MP_INIT_C
+|   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_EXCH_C
+|   +--->BN_MP_CLEAR_C
++--->BN_MP_INIT_SIZE_C
+|   +--->BN_MP_INIT_C
++--->BN_MP_CLAMP_C
++--->BN_MP_EXCH_C
++--->BN_MP_CLEAR_C
+
+
+BN_MP_REDUCE_2K_SETUP_C
++--->BN_MP_INIT_C
++--->BN_MP_COUNT_BITS_C
++--->BN_MP_2EXPT_C
+|   +--->BN_MP_ZERO_C
+|   +--->BN_MP_GROW_C
++--->BN_MP_CLEAR_C
++--->BN_S_MP_SUB_C
+|   +--->BN_MP_GROW_C
+|   +--->BN_MP_CLAMP_C
+
+
+BN_MP_INIT_SET_C
++--->BN_MP_INIT_C
++--->BN_MP_SET_C
+|   +--->BN_MP_ZERO_C
+
+
+BN_MP_REDUCE_2K_C
++--->BN_MP_INIT_C
++--->BN_MP_COUNT_BITS_C
++--->BN_MP_DIV_2D_C
+|   +--->BN_MP_COPY_C
+|   |   +--->BN_MP_GROW_C
+|   +--->BN_MP_ZERO_C
+|   +--->BN_MP_MOD_2D_C
+|   |   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_CLEAR_C
+|   +--->BN_MP_RSHD_C
+|   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_EXCH_C
++--->BN_MP_MUL_D_C
+|   +--->BN_MP_GROW_C
+|   +--->BN_MP_CLAMP_C
++--->BN_S_MP_ADD_C
+|   +--->BN_MP_GROW_C
+|   +--->BN_MP_CLAMP_C
++--->BN_MP_CMP_MAG_C
++--->BN_S_MP_SUB_C
+|   +--->BN_MP_GROW_C
+|   +--->BN_MP_CLAMP_C
++--->BN_MP_CLEAR_C
+
+
+BN_ERROR_C
+
+
+BN_MP_EXPT_D_C
++--->BN_MP_INIT_COPY_C
+|   +--->BN_MP_COPY_C
+|   |   +--->BN_MP_GROW_C
++--->BN_MP_SET_C
+|   +--->BN_MP_ZERO_C
++--->BN_MP_SQR_C
+|   +--->BN_MP_TOOM_SQR_C
+|   |   +--->BN_MP_INIT_MULTI_C
+|   |   |   +--->BN_MP_CLEAR_C
+|   |   +--->BN_MP_MOD_2D_C
+|   |   |   +--->BN_MP_ZERO_C
+|   |   |   +--->BN_MP_COPY_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_COPY_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_RSHD_C
+|   |   |   +--->BN_MP_ZERO_C
+|   |   +--->BN_MP_MUL_2_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_ADD_C
+|   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_SUB_C
+|   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_DIV_2_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_MUL_2D_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_LSHD_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_MUL_D_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_DIV_3_C
+|   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_EXCH_C
+|   |   |   +--->BN_MP_CLEAR_C
+|   |   +--->BN_MP_LSHD_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_CLEAR_MULTI_C
+|   |   |   +--->BN_MP_CLEAR_C
+|   +--->BN_MP_KARATSUBA_SQR_C
+|   |   +--->BN_MP_INIT_SIZE_C
+|   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_SUB_C
+|   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_S_MP_ADD_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_LSHD_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   +--->BN_MP_ZERO_C
+|   |   +--->BN_MP_ADD_C
+|   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_CLEAR_C
+|   +--->BN_FAST_S_MP_SQR_C
+|   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_CLAMP_C
+|   +--->BN_S_MP_SQR_C
+|   |   +--->BN_MP_INIT_SIZE_C
+|   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_EXCH_C
+|   |   +--->BN_MP_CLEAR_C
++--->BN_MP_CLEAR_C
++--->BN_MP_MUL_C
+|   +--->BN_MP_TOOM_MUL_C
+|   |   +--->BN_MP_INIT_MULTI_C
+|   |   +--->BN_MP_MOD_2D_C
+|   |   |   +--->BN_MP_ZERO_C
+|   |   |   +--->BN_MP_COPY_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_COPY_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_RSHD_C
+|   |   |   +--->BN_MP_ZERO_C
+|   |   +--->BN_MP_MUL_2_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_ADD_C
+|   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_SUB_C
+|   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_DIV_2_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_MUL_2D_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_LSHD_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_MUL_D_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_DIV_3_C
+|   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_EXCH_C
+|   |   +--->BN_MP_LSHD_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_CLEAR_MULTI_C
+|   +--->BN_MP_KARATSUBA_MUL_C
+|   |   +--->BN_MP_INIT_SIZE_C
+|   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_SUB_C
+|   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_ADD_C
+|   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_LSHD_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   +--->BN_MP_ZERO_C
+|   +--->BN_FAST_S_MP_MUL_DIGS_C
+|   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_CLAMP_C
+|   +--->BN_S_MP_MUL_DIGS_C
+|   |   +--->BN_MP_INIT_SIZE_C
+|   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_EXCH_C
+
+
+BN_S_MP_EXPTMOD_C
++--->BN_MP_COUNT_BITS_C
++--->BN_MP_INIT_C
++--->BN_MP_CLEAR_C
++--->BN_MP_REDUCE_SETUP_C
+|   +--->BN_MP_2EXPT_C
+|   |   +--->BN_MP_ZERO_C
+|   |   +--->BN_MP_GROW_C
+|   +--->BN_MP_DIV_C
+|   |   +--->BN_MP_CMP_MAG_C
+|   |   +--->BN_MP_COPY_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_ZERO_C
+|   |   +--->BN_MP_INIT_MULTI_C
+|   |   +--->BN_MP_SET_C
+|   |   +--->BN_MP_ABS_C
+|   |   +--->BN_MP_MUL_2D_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_CMP_C
+|   |   +--->BN_MP_SUB_C
+|   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_ADD_C
+|   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_DIV_2D_C
+|   |   |   +--->BN_MP_MOD_2D_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_RSHD_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_EXCH_C
+|   |   +--->BN_MP_EXCH_C
+|   |   +--->BN_MP_CLEAR_MULTI_C
+|   |   +--->BN_MP_INIT_SIZE_C
+|   |   +--->BN_MP_INIT_COPY_C
+|   |   +--->BN_MP_LSHD_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_RSHD_C
+|   |   +--->BN_MP_RSHD_C
+|   |   +--->BN_MP_MUL_D_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_CLAMP_C
++--->BN_MP_REDUCE_C
+|   +--->BN_MP_INIT_COPY_C
+|   |   +--->BN_MP_COPY_C
+|   |   |   +--->BN_MP_GROW_C
+|   +--->BN_MP_RSHD_C
+|   |   +--->BN_MP_ZERO_C
+|   +--->BN_MP_MUL_C
+|   |   +--->BN_MP_TOOM_MUL_C
+|   |   |   +--->BN_MP_INIT_MULTI_C
+|   |   |   +--->BN_MP_MOD_2D_C
+|   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   +--->BN_MP_COPY_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_COPY_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_MUL_2_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_ADD_C
+|   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_SUB_C
+|   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_DIV_2_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_MUL_2D_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_MUL_D_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_DIV_3_C
+|   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLEAR_MULTI_C
+|   |   +--->BN_MP_KARATSUBA_MUL_C
+|   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_SUB_C
+|   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_ADD_C
+|   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_FAST_S_MP_MUL_DIGS_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_S_MP_MUL_DIGS_C
+|   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_EXCH_C
+|   +--->BN_S_MP_MUL_HIGH_DIGS_C
+|   |   +--->BN_FAST_S_MP_MUL_HIGH_DIGS_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_INIT_SIZE_C
+|   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_EXCH_C
+|   +--->BN_FAST_S_MP_MUL_HIGH_DIGS_C
+|   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_MOD_2D_C
+|   |   +--->BN_MP_ZERO_C
+|   |   +--->BN_MP_COPY_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_CLAMP_C
+|   +--->BN_S_MP_MUL_DIGS_C
+|   |   +--->BN_FAST_S_MP_MUL_DIGS_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_INIT_SIZE_C
+|   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_EXCH_C
+|   +--->BN_MP_SUB_C
+|   |   +--->BN_S_MP_ADD_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_CMP_MAG_C
+|   |   +--->BN_S_MP_SUB_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_CMP_D_C
+|   +--->BN_MP_SET_C
+|   |   +--->BN_MP_ZERO_C
+|   +--->BN_MP_LSHD_C
+|   |   +--->BN_MP_GROW_C
+|   +--->BN_MP_ADD_C
+|   |   +--->BN_S_MP_ADD_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_CMP_MAG_C
+|   |   +--->BN_S_MP_SUB_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_CMP_C
+|   |   +--->BN_MP_CMP_MAG_C
+|   +--->BN_S_MP_SUB_C
+|   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_CLAMP_C
++--->BN_MP_REDUCE_2K_SETUP_L_C
+|   +--->BN_MP_2EXPT_C
+|   |   +--->BN_MP_ZERO_C
+|   |   +--->BN_MP_GROW_C
+|   +--->BN_S_MP_SUB_C
+|   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_CLAMP_C
++--->BN_MP_REDUCE_2K_L_C
+|   +--->BN_MP_DIV_2D_C
+|   |   +--->BN_MP_COPY_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_ZERO_C
+|   |   +--->BN_MP_MOD_2D_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_RSHD_C
+|   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_EXCH_C
+|   +--->BN_MP_MUL_C
+|   |   +--->BN_MP_TOOM_MUL_C
+|   |   |   +--->BN_MP_INIT_MULTI_C
+|   |   |   +--->BN_MP_MOD_2D_C
+|   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   +--->BN_MP_COPY_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_COPY_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   +--->BN_MP_MUL_2_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_ADD_C
+|   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_SUB_C
+|   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_DIV_2_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_MUL_2D_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_MUL_D_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_DIV_3_C
+|   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLEAR_MULTI_C
+|   |   +--->BN_MP_KARATSUBA_MUL_C
+|   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_SUB_C
+|   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_ADD_C
+|   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   +--->BN_FAST_S_MP_MUL_DIGS_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_S_MP_MUL_DIGS_C
+|   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_EXCH_C
+|   +--->BN_S_MP_ADD_C
+|   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_CMP_MAG_C
+|   +--->BN_S_MP_SUB_C
+|   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_CLAMP_C
++--->BN_MP_MOD_C
+|   +--->BN_MP_DIV_C
+|   |   +--->BN_MP_CMP_MAG_C
+|   |   +--->BN_MP_COPY_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_ZERO_C
+|   |   +--->BN_MP_INIT_MULTI_C
+|   |   +--->BN_MP_SET_C
+|   |   +--->BN_MP_ABS_C
+|   |   +--->BN_MP_MUL_2D_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_CMP_C
+|   |   +--->BN_MP_SUB_C
+|   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_ADD_C
+|   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_DIV_2D_C
+|   |   |   +--->BN_MP_MOD_2D_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_RSHD_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_EXCH_C
+|   |   +--->BN_MP_EXCH_C
+|   |   +--->BN_MP_CLEAR_MULTI_C
+|   |   +--->BN_MP_INIT_SIZE_C
+|   |   +--->BN_MP_INIT_COPY_C
+|   |   +--->BN_MP_LSHD_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_RSHD_C
+|   |   +--->BN_MP_RSHD_C
+|   |   +--->BN_MP_MUL_D_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_ADD_C
+|   |   +--->BN_S_MP_ADD_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_CMP_MAG_C
+|   |   +--->BN_S_MP_SUB_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_EXCH_C
++--->BN_MP_COPY_C
+|   +--->BN_MP_GROW_C
++--->BN_MP_SQR_C
+|   +--->BN_MP_TOOM_SQR_C
+|   |   +--->BN_MP_INIT_MULTI_C
+|   |   +--->BN_MP_MOD_2D_C
+|   |   |   +--->BN_MP_ZERO_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_RSHD_C
+|   |   |   +--->BN_MP_ZERO_C
+|   |   +--->BN_MP_MUL_2_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_ADD_C
+|   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_SUB_C
+|   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_DIV_2_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_MUL_2D_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_LSHD_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_MUL_D_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_DIV_3_C
+|   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_EXCH_C
+|   |   +--->BN_MP_LSHD_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_CLEAR_MULTI_C
+|   +--->BN_MP_KARATSUBA_SQR_C
+|   |   +--->BN_MP_INIT_SIZE_C
+|   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_SUB_C
+|   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_S_MP_ADD_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_LSHD_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   +--->BN_MP_ZERO_C
+|   |   +--->BN_MP_ADD_C
+|   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   +--->BN_FAST_S_MP_SQR_C
+|   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_CLAMP_C
+|   +--->BN_S_MP_SQR_C
+|   |   +--->BN_MP_INIT_SIZE_C
+|   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_EXCH_C
++--->BN_MP_MUL_C
+|   +--->BN_MP_TOOM_MUL_C
+|   |   +--->BN_MP_INIT_MULTI_C
+|   |   +--->BN_MP_MOD_2D_C
+|   |   |   +--->BN_MP_ZERO_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_RSHD_C
+|   |   |   +--->BN_MP_ZERO_C
+|   |   +--->BN_MP_MUL_2_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_ADD_C
+|   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_SUB_C
+|   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_DIV_2_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_MUL_2D_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_LSHD_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_MUL_D_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_DIV_3_C
+|   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_EXCH_C
+|   |   +--->BN_MP_LSHD_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_CLEAR_MULTI_C
+|   +--->BN_MP_KARATSUBA_MUL_C
+|   |   +--->BN_MP_INIT_SIZE_C
+|   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_SUB_C
+|   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_ADD_C
+|   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_LSHD_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   +--->BN_MP_ZERO_C
+|   +--->BN_FAST_S_MP_MUL_DIGS_C
+|   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_CLAMP_C
+|   +--->BN_S_MP_MUL_DIGS_C
+|   |   +--->BN_MP_INIT_SIZE_C
+|   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_EXCH_C
++--->BN_MP_SET_C
+|   +--->BN_MP_ZERO_C
++--->BN_MP_EXCH_C
+
+
+BN_MP_ABS_C
++--->BN_MP_COPY_C
+|   +--->BN_MP_GROW_C
+
+
+BN_MP_INIT_SET_INT_C
++--->BN_MP_INIT_C
++--->BN_MP_SET_INT_C
+|   +--->BN_MP_ZERO_C
+|   +--->BN_MP_MUL_2D_C
+|   |   +--->BN_MP_COPY_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_LSHD_C
+|   |   |   +--->BN_MP_RSHD_C
+|   |   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_CLAMP_C
+
+
+BN_MP_SUB_D_C
++--->BN_MP_GROW_C
++--->BN_MP_ADD_D_C
+|   +--->BN_MP_CLAMP_C
++--->BN_MP_CLAMP_C
+
+
+BN_MP_TO_SIGNED_BIN_C
++--->BN_MP_TO_UNSIGNED_BIN_C
+|   +--->BN_MP_INIT_COPY_C
+|   |   +--->BN_MP_COPY_C
+|   |   |   +--->BN_MP_GROW_C
+|   +--->BN_MP_DIV_2D_C
+|   |   +--->BN_MP_COPY_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_ZERO_C
+|   |   +--->BN_MP_MOD_2D_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_CLEAR_C
+|   |   +--->BN_MP_RSHD_C
+|   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_EXCH_C
+|   +--->BN_MP_CLEAR_C
+
+
+BN_MP_DIV_2_C
++--->BN_MP_GROW_C
++--->BN_MP_CLAMP_C
+
+
+BN_MP_REDUCE_IS_2K_C
++--->BN_MP_REDUCE_2K_C
+|   +--->BN_MP_INIT_C
+|   +--->BN_MP_COUNT_BITS_C
+|   +--->BN_MP_DIV_2D_C
+|   |   +--->BN_MP_COPY_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_ZERO_C
+|   |   +--->BN_MP_MOD_2D_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_CLEAR_C
+|   |   +--->BN_MP_RSHD_C
+|   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_EXCH_C
+|   +--->BN_MP_MUL_D_C
+|   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_CLAMP_C
+|   +--->BN_S_MP_ADD_C
+|   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_CMP_MAG_C
+|   +--->BN_S_MP_SUB_C
+|   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_CLEAR_C
++--->BN_MP_COUNT_BITS_C
+
+
+BN_MP_INIT_SIZE_C
++--->BN_MP_INIT_C
+
+
+BN_MP_DIV_C
++--->BN_MP_CMP_MAG_C
++--->BN_MP_COPY_C
+|   +--->BN_MP_GROW_C
++--->BN_MP_ZERO_C
++--->BN_MP_INIT_MULTI_C
+|   +--->BN_MP_INIT_C
+|   +--->BN_MP_CLEAR_C
++--->BN_MP_SET_C
++--->BN_MP_COUNT_BITS_C
++--->BN_MP_ABS_C
++--->BN_MP_MUL_2D_C
+|   +--->BN_MP_GROW_C
+|   +--->BN_MP_LSHD_C
+|   |   +--->BN_MP_RSHD_C
+|   +--->BN_MP_CLAMP_C
++--->BN_MP_CMP_C
++--->BN_MP_SUB_C
+|   +--->BN_S_MP_ADD_C
+|   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_CLAMP_C
+|   +--->BN_S_MP_SUB_C
+|   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_CLAMP_C
++--->BN_MP_ADD_C
+|   +--->BN_S_MP_ADD_C
+|   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_CLAMP_C
+|   +--->BN_S_MP_SUB_C
+|   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_CLAMP_C
++--->BN_MP_DIV_2D_C
+|   +--->BN_MP_INIT_C
+|   +--->BN_MP_MOD_2D_C
+|   |   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_CLEAR_C
+|   +--->BN_MP_RSHD_C
+|   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_EXCH_C
++--->BN_MP_EXCH_C
++--->BN_MP_CLEAR_MULTI_C
+|   +--->BN_MP_CLEAR_C
++--->BN_MP_INIT_SIZE_C
+|   +--->BN_MP_INIT_C
++--->BN_MP_INIT_C
++--->BN_MP_INIT_COPY_C
++--->BN_MP_LSHD_C
+|   +--->BN_MP_GROW_C
+|   +--->BN_MP_RSHD_C
++--->BN_MP_RSHD_C
++--->BN_MP_MUL_D_C
+|   +--->BN_MP_GROW_C
+|   +--->BN_MP_CLAMP_C
++--->BN_MP_CLAMP_C
++--->BN_MP_CLEAR_C
+
+
+BN_MP_CLEAR_C
+
+
+BN_MP_MONTGOMERY_REDUCE_C
++--->BN_FAST_MP_MONTGOMERY_REDUCE_C
+|   +--->BN_MP_GROW_C
+|   +--->BN_MP_RSHD_C
+|   |   +--->BN_MP_ZERO_C
+|   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_CMP_MAG_C
+|   +--->BN_S_MP_SUB_C
++--->BN_MP_GROW_C
++--->BN_MP_CLAMP_C
++--->BN_MP_RSHD_C
+|   +--->BN_MP_ZERO_C
++--->BN_MP_CMP_MAG_C
++--->BN_S_MP_SUB_C
+
+
+BN_MP_MUL_2_C
++--->BN_MP_GROW_C
+
+
+BN_MP_UNSIGNED_BIN_SIZE_C
++--->BN_MP_COUNT_BITS_C
+
+
+BN_MP_ADDMOD_C
++--->BN_MP_INIT_C
++--->BN_MP_ADD_C
+|   +--->BN_S_MP_ADD_C
+|   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_CMP_MAG_C
+|   +--->BN_S_MP_SUB_C
+|   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_CLAMP_C
++--->BN_MP_CLEAR_C
++--->BN_MP_MOD_C
+|   +--->BN_MP_DIV_C
+|   |   +--->BN_MP_CMP_MAG_C
+|   |   +--->BN_MP_COPY_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_ZERO_C
+|   |   +--->BN_MP_INIT_MULTI_C
+|   |   +--->BN_MP_SET_C
+|   |   +--->BN_MP_COUNT_BITS_C
+|   |   +--->BN_MP_ABS_C
+|   |   +--->BN_MP_MUL_2D_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_CMP_C
+|   |   +--->BN_MP_SUB_C
+|   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_DIV_2D_C
+|   |   |   +--->BN_MP_MOD_2D_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_RSHD_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_EXCH_C
+|   |   +--->BN_MP_EXCH_C
+|   |   +--->BN_MP_CLEAR_MULTI_C
+|   |   +--->BN_MP_INIT_SIZE_C
+|   |   +--->BN_MP_INIT_COPY_C
+|   |   +--->BN_MP_LSHD_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_RSHD_C
+|   |   +--->BN_MP_RSHD_C
+|   |   +--->BN_MP_MUL_D_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_EXCH_C
+
+
+BN_MP_ADD_C
++--->BN_S_MP_ADD_C
+|   +--->BN_MP_GROW_C
+|   +--->BN_MP_CLAMP_C
++--->BN_MP_CMP_MAG_C
++--->BN_S_MP_SUB_C
+|   +--->BN_MP_GROW_C
+|   +--->BN_MP_CLAMP_C
+
+
+BN_MP_TO_SIGNED_BIN_N_C
++--->BN_MP_SIGNED_BIN_SIZE_C
+|   +--->BN_MP_UNSIGNED_BIN_SIZE_C
+|   |   +--->BN_MP_COUNT_BITS_C
++--->BN_MP_TO_SIGNED_BIN_C
+|   +--->BN_MP_TO_UNSIGNED_BIN_C
+|   |   +--->BN_MP_INIT_COPY_C
+|   |   |   +--->BN_MP_COPY_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_DIV_2D_C
+|   |   |   +--->BN_MP_COPY_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_ZERO_C
+|   |   |   +--->BN_MP_MOD_2D_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_CLEAR_C
+|   |   |   +--->BN_MP_RSHD_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_EXCH_C
+|   |   +--->BN_MP_CLEAR_C
+
+
+BN_MP_REDUCE_IS_2K_L_C
+
+
+BN_MP_RAND_C
++--->BN_MP_ZERO_C
++--->BN_MP_ADD_D_C
+|   +--->BN_MP_GROW_C
+|   +--->BN_MP_SUB_D_C
+|   |   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_CLAMP_C
++--->BN_MP_LSHD_C
+|   +--->BN_MP_GROW_C
+|   +--->BN_MP_RSHD_C
+
+
+BN_MP_CNT_LSB_C
+
+
+BN_MP_2EXPT_C
++--->BN_MP_ZERO_C
++--->BN_MP_GROW_C
+
+
+BN_MP_RSHD_C
++--->BN_MP_ZERO_C
+
+
+BN_MP_SHRINK_C
+
+
+BN_MP_TO_UNSIGNED_BIN_N_C
++--->BN_MP_UNSIGNED_BIN_SIZE_C
+|   +--->BN_MP_COUNT_BITS_C
++--->BN_MP_TO_UNSIGNED_BIN_C
+|   +--->BN_MP_INIT_COPY_C
+|   |   +--->BN_MP_COPY_C
+|   |   |   +--->BN_MP_GROW_C
+|   +--->BN_MP_DIV_2D_C
+|   |   +--->BN_MP_COPY_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_ZERO_C
+|   |   +--->BN_MP_MOD_2D_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_CLEAR_C
+|   |   +--->BN_MP_RSHD_C
+|   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_EXCH_C
+|   +--->BN_MP_CLEAR_C
+
+
+BN_MP_REDUCE_C
++--->BN_MP_REDUCE_SETUP_C
+|   +--->BN_MP_2EXPT_C
+|   |   +--->BN_MP_ZERO_C
+|   |   +--->BN_MP_GROW_C
+|   +--->BN_MP_DIV_C
+|   |   +--->BN_MP_CMP_MAG_C
+|   |   +--->BN_MP_COPY_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_ZERO_C
+|   |   +--->BN_MP_INIT_MULTI_C
+|   |   |   +--->BN_MP_INIT_C
+|   |   |   +--->BN_MP_CLEAR_C
+|   |   +--->BN_MP_SET_C
+|   |   +--->BN_MP_COUNT_BITS_C
+|   |   +--->BN_MP_ABS_C
+|   |   +--->BN_MP_MUL_2D_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_CMP_C
+|   |   +--->BN_MP_SUB_C
+|   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_ADD_C
+|   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_DIV_2D_C
+|   |   |   +--->BN_MP_INIT_C
+|   |   |   +--->BN_MP_MOD_2D_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_CLEAR_C
+|   |   |   +--->BN_MP_RSHD_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_EXCH_C
+|   |   +--->BN_MP_EXCH_C
+|   |   +--->BN_MP_CLEAR_MULTI_C
+|   |   |   +--->BN_MP_CLEAR_C
+|   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   +--->BN_MP_INIT_C
+|   |   +--->BN_MP_INIT_C
+|   |   +--->BN_MP_INIT_COPY_C
+|   |   +--->BN_MP_LSHD_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_RSHD_C
+|   |   +--->BN_MP_RSHD_C
+|   |   +--->BN_MP_MUL_D_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_CLEAR_C
++--->BN_MP_INIT_COPY_C
+|   +--->BN_MP_COPY_C
+|   |   +--->BN_MP_GROW_C
++--->BN_MP_RSHD_C
+|   +--->BN_MP_ZERO_C
++--->BN_MP_MUL_C
+|   +--->BN_MP_TOOM_MUL_C
+|   |   +--->BN_MP_INIT_MULTI_C
+|   |   |   +--->BN_MP_CLEAR_C
+|   |   +--->BN_MP_MOD_2D_C
+|   |   |   +--->BN_MP_ZERO_C
+|   |   |   +--->BN_MP_COPY_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_COPY_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_MUL_2_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_ADD_C
+|   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_SUB_C
+|   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_DIV_2_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_MUL_2D_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_LSHD_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_MUL_D_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_DIV_3_C
+|   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_EXCH_C
+|   |   |   +--->BN_MP_CLEAR_C
+|   |   +--->BN_MP_LSHD_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_CLEAR_MULTI_C
+|   |   |   +--->BN_MP_CLEAR_C
+|   +--->BN_MP_KARATSUBA_MUL_C
+|   |   +--->BN_MP_INIT_SIZE_C
+|   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_SUB_C
+|   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_ADD_C
+|   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_LSHD_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_CLEAR_C
+|   +--->BN_FAST_S_MP_MUL_DIGS_C
+|   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_CLAMP_C
+|   +--->BN_S_MP_MUL_DIGS_C
+|   |   +--->BN_MP_INIT_SIZE_C
+|   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_EXCH_C
+|   |   +--->BN_MP_CLEAR_C
++--->BN_S_MP_MUL_HIGH_DIGS_C
+|   +--->BN_FAST_S_MP_MUL_HIGH_DIGS_C
+|   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_INIT_SIZE_C
+|   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_EXCH_C
+|   +--->BN_MP_CLEAR_C
++--->BN_FAST_S_MP_MUL_HIGH_DIGS_C
+|   +--->BN_MP_GROW_C
+|   +--->BN_MP_CLAMP_C
++--->BN_MP_MOD_2D_C
+|   +--->BN_MP_ZERO_C
+|   +--->BN_MP_COPY_C
+|   |   +--->BN_MP_GROW_C
+|   +--->BN_MP_CLAMP_C
++--->BN_S_MP_MUL_DIGS_C
+|   +--->BN_FAST_S_MP_MUL_DIGS_C
+|   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_INIT_SIZE_C
+|   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_EXCH_C
+|   +--->BN_MP_CLEAR_C
++--->BN_MP_SUB_C
+|   +--->BN_S_MP_ADD_C
+|   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_CMP_MAG_C
+|   +--->BN_S_MP_SUB_C
+|   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_CLAMP_C
++--->BN_MP_CMP_D_C
++--->BN_MP_SET_C
+|   +--->BN_MP_ZERO_C
++--->BN_MP_LSHD_C
+|   +--->BN_MP_GROW_C
++--->BN_MP_ADD_C
+|   +--->BN_S_MP_ADD_C
+|   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_CMP_MAG_C
+|   +--->BN_S_MP_SUB_C
+|   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_CLAMP_C
++--->BN_MP_CMP_C
+|   +--->BN_MP_CMP_MAG_C
++--->BN_S_MP_SUB_C
+|   +--->BN_MP_GROW_C
+|   +--->BN_MP_CLAMP_C
++--->BN_MP_CLEAR_C
+
+
+BN_MP_MUL_2D_C
++--->BN_MP_COPY_C
+|   +--->BN_MP_GROW_C
++--->BN_MP_GROW_C
++--->BN_MP_LSHD_C
+|   +--->BN_MP_RSHD_C
+|   |   +--->BN_MP_ZERO_C
++--->BN_MP_CLAMP_C
+
+
+BN_MP_GET_INT_C
+
+
+BN_MP_JACOBI_C
++--->BN_MP_CMP_D_C
++--->BN_MP_INIT_COPY_C
+|   +--->BN_MP_COPY_C
+|   |   +--->BN_MP_GROW_C
++--->BN_MP_CNT_LSB_C
++--->BN_MP_DIV_2D_C
+|   +--->BN_MP_COPY_C
+|   |   +--->BN_MP_GROW_C
+|   +--->BN_MP_ZERO_C
+|   +--->BN_MP_MOD_2D_C
+|   |   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_CLEAR_C
+|   +--->BN_MP_RSHD_C
+|   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_EXCH_C
++--->BN_MP_MOD_C
+|   +--->BN_MP_DIV_C
+|   |   +--->BN_MP_CMP_MAG_C
+|   |   +--->BN_MP_COPY_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_ZERO_C
+|   |   +--->BN_MP_INIT_MULTI_C
+|   |   |   +--->BN_MP_CLEAR_C
+|   |   +--->BN_MP_SET_C
+|   |   +--->BN_MP_COUNT_BITS_C
+|   |   +--->BN_MP_ABS_C
+|   |   +--->BN_MP_MUL_2D_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_CMP_C
+|   |   +--->BN_MP_SUB_C
+|   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_ADD_C
+|   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_EXCH_C
+|   |   +--->BN_MP_CLEAR_MULTI_C
+|   |   |   +--->BN_MP_CLEAR_C
+|   |   +--->BN_MP_INIT_SIZE_C
+|   |   +--->BN_MP_LSHD_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_RSHD_C
+|   |   +--->BN_MP_RSHD_C
+|   |   +--->BN_MP_MUL_D_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_CLEAR_C
+|   +--->BN_MP_CLEAR_C
+|   +--->BN_MP_ADD_C
+|   |   +--->BN_S_MP_ADD_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_CMP_MAG_C
+|   |   +--->BN_S_MP_SUB_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_EXCH_C
++--->BN_MP_CLEAR_C
+
+
+BN_MP_CLEAR_MULTI_C
++--->BN_MP_CLEAR_C
+
+
+BN_MP_MUL_C
++--->BN_MP_TOOM_MUL_C
+|   +--->BN_MP_INIT_MULTI_C
+|   |   +--->BN_MP_INIT_C
+|   |   +--->BN_MP_CLEAR_C
+|   +--->BN_MP_MOD_2D_C
+|   |   +--->BN_MP_ZERO_C
+|   |   +--->BN_MP_COPY_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_COPY_C
+|   |   +--->BN_MP_GROW_C
+|   +--->BN_MP_RSHD_C
+|   |   +--->BN_MP_ZERO_C
+|   +--->BN_MP_MUL_2_C
+|   |   +--->BN_MP_GROW_C
+|   +--->BN_MP_ADD_C
+|   |   +--->BN_S_MP_ADD_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_CMP_MAG_C
+|   |   +--->BN_S_MP_SUB_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_SUB_C
+|   |   +--->BN_S_MP_ADD_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_CMP_MAG_C
+|   |   +--->BN_S_MP_SUB_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_DIV_2_C
+|   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_MUL_2D_C
+|   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_LSHD_C
+|   |   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_MUL_D_C
+|   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_DIV_3_C
+|   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   +--->BN_MP_INIT_C
+|   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_EXCH_C
+|   |   +--->BN_MP_CLEAR_C
+|   +--->BN_MP_LSHD_C
+|   |   +--->BN_MP_GROW_C
+|   +--->BN_MP_CLEAR_MULTI_C
+|   |   +--->BN_MP_CLEAR_C
++--->BN_MP_KARATSUBA_MUL_C
+|   +--->BN_MP_INIT_SIZE_C
+|   |   +--->BN_MP_INIT_C
+|   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_SUB_C
+|   |   +--->BN_S_MP_ADD_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_CMP_MAG_C
+|   |   +--->BN_S_MP_SUB_C
+|   |   |   +--->BN_MP_GROW_C
+|   +--->BN_MP_ADD_C
+|   |   +--->BN_S_MP_ADD_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_CMP_MAG_C
+|   |   +--->BN_S_MP_SUB_C
+|   |   |   +--->BN_MP_GROW_C
+|   +--->BN_MP_LSHD_C
+|   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_RSHD_C
+|   |   |   +--->BN_MP_ZERO_C
+|   +--->BN_MP_CLEAR_C
++--->BN_FAST_S_MP_MUL_DIGS_C
+|   +--->BN_MP_GROW_C
+|   +--->BN_MP_CLAMP_C
++--->BN_S_MP_MUL_DIGS_C
+|   +--->BN_MP_INIT_SIZE_C
+|   |   +--->BN_MP_INIT_C
+|   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_EXCH_C
+|   +--->BN_MP_CLEAR_C
+
+
+BN_MP_EXTEUCLID_C
++--->BN_MP_INIT_MULTI_C
+|   +--->BN_MP_INIT_C
+|   +--->BN_MP_CLEAR_C
++--->BN_MP_SET_C
+|   +--->BN_MP_ZERO_C
++--->BN_MP_COPY_C
+|   +--->BN_MP_GROW_C
++--->BN_MP_DIV_C
+|   +--->BN_MP_CMP_MAG_C
+|   +--->BN_MP_ZERO_C
+|   +--->BN_MP_COUNT_BITS_C
+|   +--->BN_MP_ABS_C
+|   +--->BN_MP_MUL_2D_C
+|   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_LSHD_C
+|   |   |   +--->BN_MP_RSHD_C
+|   |   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_CMP_C
+|   +--->BN_MP_SUB_C
+|   |   +--->BN_S_MP_ADD_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_S_MP_SUB_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_ADD_C
+|   |   +--->BN_S_MP_ADD_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_S_MP_SUB_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_DIV_2D_C
+|   |   +--->BN_MP_INIT_C
+|   |   +--->BN_MP_MOD_2D_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_CLEAR_C
+|   |   +--->BN_MP_RSHD_C
+|   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_EXCH_C
+|   +--->BN_MP_EXCH_C
+|   +--->BN_MP_CLEAR_MULTI_C
+|   |   +--->BN_MP_CLEAR_C
+|   +--->BN_MP_INIT_SIZE_C
+|   |   +--->BN_MP_INIT_C
+|   +--->BN_MP_INIT_C
+|   +--->BN_MP_INIT_COPY_C
+|   +--->BN_MP_LSHD_C
+|   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_RSHD_C
+|   +--->BN_MP_RSHD_C
+|   +--->BN_MP_MUL_D_C
+|   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_CLEAR_C
++--->BN_MP_MUL_C
+|   +--->BN_MP_TOOM_MUL_C
+|   |   +--->BN_MP_MOD_2D_C
+|   |   |   +--->BN_MP_ZERO_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_RSHD_C
+|   |   |   +--->BN_MP_ZERO_C
+|   |   +--->BN_MP_MUL_2_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_ADD_C
+|   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_SUB_C
+|   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_DIV_2_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_MUL_2D_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_LSHD_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_MUL_D_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_DIV_3_C
+|   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   +--->BN_MP_INIT_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_EXCH_C
+|   |   |   +--->BN_MP_CLEAR_C
+|   |   +--->BN_MP_LSHD_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_CLEAR_MULTI_C
+|   |   |   +--->BN_MP_CLEAR_C
+|   +--->BN_MP_KARATSUBA_MUL_C
+|   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   +--->BN_MP_INIT_C
+|   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_SUB_C
+|   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_ADD_C
+|   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_LSHD_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   +--->BN_MP_ZERO_C
+|   |   +--->BN_MP_CLEAR_C
+|   +--->BN_FAST_S_MP_MUL_DIGS_C
+|   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_CLAMP_C
+|   +--->BN_S_MP_MUL_DIGS_C
+|   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   +--->BN_MP_INIT_C
+|   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_EXCH_C
+|   |   +--->BN_MP_CLEAR_C
++--->BN_MP_SUB_C
+|   +--->BN_S_MP_ADD_C
+|   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_CMP_MAG_C
+|   +--->BN_S_MP_SUB_C
+|   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_CLAMP_C
++--->BN_MP_NEG_C
++--->BN_MP_EXCH_C
++--->BN_MP_CLEAR_MULTI_C
+|   +--->BN_MP_CLEAR_C
+
+
+BN_MP_DR_REDUCE_C
++--->BN_MP_GROW_C
++--->BN_MP_CLAMP_C
++--->BN_MP_CMP_MAG_C
++--->BN_S_MP_SUB_C
+
+
+BN_MP_FREAD_C
++--->BN_MP_ZERO_C
++--->BN_MP_MUL_D_C
+|   +--->BN_MP_GROW_C
+|   +--->BN_MP_CLAMP_C
++--->BN_MP_ADD_D_C
+|   +--->BN_MP_GROW_C
+|   +--->BN_MP_SUB_D_C
+|   |   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_CLAMP_C
++--->BN_MP_CMP_D_C
+
+
+BN_MP_REDUCE_SETUP_C
++--->BN_MP_2EXPT_C
+|   +--->BN_MP_ZERO_C
+|   +--->BN_MP_GROW_C
++--->BN_MP_DIV_C
+|   +--->BN_MP_CMP_MAG_C
+|   +--->BN_MP_COPY_C
+|   |   +--->BN_MP_GROW_C
+|   +--->BN_MP_ZERO_C
+|   +--->BN_MP_INIT_MULTI_C
+|   |   +--->BN_MP_INIT_C
+|   |   +--->BN_MP_CLEAR_C
+|   +--->BN_MP_SET_C
+|   +--->BN_MP_COUNT_BITS_C
+|   +--->BN_MP_ABS_C
+|   +--->BN_MP_MUL_2D_C
+|   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_LSHD_C
+|   |   |   +--->BN_MP_RSHD_C
+|   |   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_CMP_C
+|   +--->BN_MP_SUB_C
+|   |   +--->BN_S_MP_ADD_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_S_MP_SUB_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_ADD_C
+|   |   +--->BN_S_MP_ADD_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_S_MP_SUB_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_DIV_2D_C
+|   |   +--->BN_MP_INIT_C
+|   |   +--->BN_MP_MOD_2D_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_CLEAR_C
+|   |   +--->BN_MP_RSHD_C
+|   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_EXCH_C
+|   +--->BN_MP_EXCH_C
+|   +--->BN_MP_CLEAR_MULTI_C
+|   |   +--->BN_MP_CLEAR_C
+|   +--->BN_MP_INIT_SIZE_C
+|   |   +--->BN_MP_INIT_C
+|   +--->BN_MP_INIT_C
+|   +--->BN_MP_INIT_COPY_C
+|   +--->BN_MP_LSHD_C
+|   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_RSHD_C
+|   +--->BN_MP_RSHD_C
+|   +--->BN_MP_MUL_D_C
+|   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_CLEAR_C
+
+
+BN_MP_MONTGOMERY_SETUP_C
+
+
+BN_MP_KARATSUBA_MUL_C
++--->BN_MP_MUL_C
+|   +--->BN_MP_TOOM_MUL_C
+|   |   +--->BN_MP_INIT_MULTI_C
+|   |   |   +--->BN_MP_INIT_C
+|   |   |   +--->BN_MP_CLEAR_C
+|   |   +--->BN_MP_MOD_2D_C
+|   |   |   +--->BN_MP_ZERO_C
+|   |   |   +--->BN_MP_COPY_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_COPY_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_RSHD_C
+|   |   |   +--->BN_MP_ZERO_C
+|   |   +--->BN_MP_MUL_2_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_ADD_C
+|   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_SUB_C
+|   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_DIV_2_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_MUL_2D_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_LSHD_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_MUL_D_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_DIV_3_C
+|   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   +--->BN_MP_INIT_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_EXCH_C
+|   |   |   +--->BN_MP_CLEAR_C
+|   |   +--->BN_MP_LSHD_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_CLEAR_MULTI_C
+|   |   |   +--->BN_MP_CLEAR_C
+|   +--->BN_FAST_S_MP_MUL_DIGS_C
+|   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_CLAMP_C
+|   +--->BN_S_MP_MUL_DIGS_C
+|   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   +--->BN_MP_INIT_C
+|   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_EXCH_C
+|   |   +--->BN_MP_CLEAR_C
++--->BN_MP_INIT_SIZE_C
+|   +--->BN_MP_INIT_C
++--->BN_MP_CLAMP_C
++--->BN_MP_SUB_C
+|   +--->BN_S_MP_ADD_C
+|   |   +--->BN_MP_GROW_C
+|   +--->BN_MP_CMP_MAG_C
+|   +--->BN_S_MP_SUB_C
+|   |   +--->BN_MP_GROW_C
++--->BN_MP_ADD_C
+|   +--->BN_S_MP_ADD_C
+|   |   +--->BN_MP_GROW_C
+|   +--->BN_MP_CMP_MAG_C
+|   +--->BN_S_MP_SUB_C
+|   |   +--->BN_MP_GROW_C
++--->BN_MP_LSHD_C
+|   +--->BN_MP_GROW_C
+|   +--->BN_MP_RSHD_C
+|   |   +--->BN_MP_ZERO_C
++--->BN_MP_CLEAR_C
+
+
+BN_MP_LSHD_C
++--->BN_MP_GROW_C
++--->BN_MP_RSHD_C
+|   +--->BN_MP_ZERO_C
+
+
+BN_MP_PRIME_MILLER_RABIN_C
++--->BN_MP_CMP_D_C
++--->BN_MP_INIT_COPY_C
+|   +--->BN_MP_COPY_C
+|   |   +--->BN_MP_GROW_C
++--->BN_MP_SUB_D_C
+|   +--->BN_MP_GROW_C
+|   +--->BN_MP_ADD_D_C
+|   |   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_CLAMP_C
++--->BN_MP_CNT_LSB_C
++--->BN_MP_DIV_2D_C
+|   +--->BN_MP_COPY_C
+|   |   +--->BN_MP_GROW_C
+|   +--->BN_MP_ZERO_C
+|   +--->BN_MP_MOD_2D_C
+|   |   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_CLEAR_C
+|   +--->BN_MP_RSHD_C
+|   +--->BN_MP_CLAMP_C
+|   +--->BN_MP_EXCH_C
++--->BN_MP_EXPTMOD_C
+|   +--->BN_MP_INVMOD_C
+|   |   +--->BN_FAST_MP_INVMOD_C
+|   |   |   +--->BN_MP_INIT_MULTI_C
+|   |   |   |   +--->BN_MP_CLEAR_C
+|   |   |   +--->BN_MP_COPY_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_MOD_C
+|   |   |   |   +--->BN_MP_DIV_C
+|   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   +--->BN_MP_SET_C
+|   |   |   |   |   +--->BN_MP_COUNT_BITS_C
+|   |   |   |   |   +--->BN_MP_ABS_C
+|   |   |   |   |   +--->BN_MP_MUL_2D_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_CMP_C
+|   |   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   |   +--->BN_MP_CLEAR_MULTI_C
+|   |   |   |   |   |   +--->BN_MP_CLEAR_C
+|   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   +--->BN_MP_MUL_D_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_CLEAR_C
+|   |   |   |   +--->BN_MP_CLEAR_C
+|   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   +--->BN_MP_SET_C
+|   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   +--->BN_MP_DIV_2_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_SUB_C
+|   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_CMP_C
+|   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   +--->BN_MP_ADD_C
+|   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_EXCH_C
+|   |   |   +--->BN_MP_CLEAR_MULTI_C
+|   |   |   |   +--->BN_MP_CLEAR_C
+|   |   +--->BN_MP_INVMOD_SLOW_C
+|   |   |   +--->BN_MP_INIT_MULTI_C
+|   |   |   |   +--->BN_MP_CLEAR_C
+|   |   |   +--->BN_MP_MOD_C
+|   |   |   |   +--->BN_MP_DIV_C
+|   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   +--->BN_MP_COPY_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   +--->BN_MP_SET_C
+|   |   |   |   |   +--->BN_MP_COUNT_BITS_C
+|   |   |   |   |   +--->BN_MP_ABS_C
+|   |   |   |   |   +--->BN_MP_MUL_2D_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_CMP_C
+|   |   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   |   +--->BN_MP_CLEAR_MULTI_C
+|   |   |   |   |   |   +--->BN_MP_CLEAR_C
+|   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   +--->BN_MP_MUL_D_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_CLEAR_C
+|   |   |   |   +--->BN_MP_CLEAR_C
+|   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   +--->BN_MP_COPY_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_SET_C
+|   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   +--->BN_MP_DIV_2_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_ADD_C
+|   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_SUB_C
+|   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_CMP_C
+|   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   +--->BN_MP_EXCH_C
+|   |   |   +--->BN_MP_CLEAR_MULTI_C
+|   |   |   |   +--->BN_MP_CLEAR_C
+|   +--->BN_MP_CLEAR_C
+|   +--->BN_MP_ABS_C
+|   |   +--->BN_MP_COPY_C
+|   |   |   +--->BN_MP_GROW_C
+|   +--->BN_MP_CLEAR_MULTI_C
+|   +--->BN_MP_REDUCE_IS_2K_L_C
+|   +--->BN_S_MP_EXPTMOD_C
+|   |   +--->BN_MP_COUNT_BITS_C
+|   |   +--->BN_MP_REDUCE_SETUP_C
+|   |   |   +--->BN_MP_2EXPT_C
+|   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_DIV_C
+|   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   +--->BN_MP_COPY_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   +--->BN_MP_INIT_MULTI_C
+|   |   |   |   +--->BN_MP_SET_C
+|   |   |   |   +--->BN_MP_MUL_2D_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_CMP_C
+|   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   +--->BN_MP_MUL_D_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_REDUCE_C
+|   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   +--->BN_MP_MUL_C
+|   |   |   |   +--->BN_MP_TOOM_MUL_C
+|   |   |   |   |   +--->BN_MP_INIT_MULTI_C
+|   |   |   |   |   +--->BN_MP_MOD_2D_C
+|   |   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   |   +--->BN_MP_COPY_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_COPY_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_MUL_2_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_DIV_2_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_MUL_2D_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_MUL_D_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_DIV_3_C
+|   |   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_KARATSUBA_MUL_C
+|   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_FAST_S_MP_MUL_DIGS_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_S_MP_MUL_DIGS_C
+|   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   +--->BN_S_MP_MUL_HIGH_DIGS_C
+|   |   |   |   +--->BN_FAST_S_MP_MUL_HIGH_DIGS_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   +--->BN_FAST_S_MP_MUL_HIGH_DIGS_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_MOD_2D_C
+|   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   +--->BN_MP_COPY_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_S_MP_MUL_DIGS_C
+|   |   |   |   +--->BN_FAST_S_MP_MUL_DIGS_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   +--->BN_MP_SUB_C
+|   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_SET_C
+|   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_ADD_C
+|   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_CMP_C
+|   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_REDUCE_2K_SETUP_L_C
+|   |   |   +--->BN_MP_2EXPT_C
+|   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_REDUCE_2K_L_C
+|   |   |   +--->BN_MP_MUL_C
+|   |   |   |   +--->BN_MP_TOOM_MUL_C
+|   |   |   |   |   +--->BN_MP_INIT_MULTI_C
+|   |   |   |   |   +--->BN_MP_MOD_2D_C
+|   |   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   |   +--->BN_MP_COPY_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_COPY_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   +--->BN_MP_MUL_2_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_DIV_2_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_MUL_2D_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_MUL_D_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_DIV_3_C
+|   |   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_KARATSUBA_MUL_C
+|   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   +--->BN_FAST_S_MP_MUL_DIGS_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_S_MP_MUL_DIGS_C
+|   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_MOD_C
+|   |   |   +--->BN_MP_DIV_C
+|   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   +--->BN_MP_COPY_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   +--->BN_MP_INIT_MULTI_C
+|   |   |   |   +--->BN_MP_SET_C
+|   |   |   |   +--->BN_MP_MUL_2D_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_CMP_C
+|   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   +--->BN_MP_MUL_D_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_ADD_C
+|   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_EXCH_C
+|   |   +--->BN_MP_COPY_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_SQR_C
+|   |   |   +--->BN_MP_TOOM_SQR_C
+|   |   |   |   +--->BN_MP_INIT_MULTI_C
+|   |   |   |   +--->BN_MP_MOD_2D_C
+|   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   +--->BN_MP_MUL_2_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_DIV_2_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_MUL_2D_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_MUL_D_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_DIV_3_C
+|   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_KARATSUBA_SQR_C
+|   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_FAST_S_MP_SQR_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_S_MP_SQR_C
+|   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_EXCH_C
+|   |   +--->BN_MP_MUL_C
+|   |   |   +--->BN_MP_TOOM_MUL_C
+|   |   |   |   +--->BN_MP_INIT_MULTI_C
+|   |   |   |   +--->BN_MP_MOD_2D_C
+|   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   +--->BN_MP_MUL_2_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_DIV_2_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_MUL_2D_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_MUL_D_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_DIV_3_C
+|   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_KARATSUBA_MUL_C
+|   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   +--->BN_FAST_S_MP_MUL_DIGS_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_S_MP_MUL_DIGS_C
+|   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_EXCH_C
+|   |   +--->BN_MP_SET_C
+|   |   |   +--->BN_MP_ZERO_C
+|   |   +--->BN_MP_EXCH_C
+|   +--->BN_MP_DR_IS_MODULUS_C
+|   +--->BN_MP_REDUCE_IS_2K_C
+|   |   +--->BN_MP_REDUCE_2K_C
+|   |   |   +--->BN_MP_COUNT_BITS_C
+|   |   |   +--->BN_MP_MUL_D_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_COUNT_BITS_C
+|   +--->BN_MP_EXPTMOD_FAST_C
+|   |   +--->BN_MP_COUNT_BITS_C
+|   |   +--->BN_MP_MONTGOMERY_SETUP_C
+|   |   +--->BN_FAST_MP_MONTGOMERY_REDUCE_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   +--->BN_MP_MONTGOMERY_REDUCE_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   +--->BN_MP_DR_SETUP_C
+|   |   +--->BN_MP_DR_REDUCE_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   +--->BN_MP_REDUCE_2K_SETUP_C
+|   |   |   +--->BN_MP_2EXPT_C
+|   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_REDUCE_2K_C
+|   |   |   +--->BN_MP_MUL_D_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_MONTGOMERY_CALC_NORMALIZATION_C
+|   |   |   +--->BN_MP_2EXPT_C
+|   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_SET_C
+|   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   +--->BN_MP_MUL_2_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_MULMOD_C
+|   |   |   +--->BN_MP_MUL_C
+|   |   |   |   +--->BN_MP_TOOM_MUL_C
+|   |   |   |   |   +--->BN_MP_INIT_MULTI_C
+|   |   |   |   |   +--->BN_MP_MOD_2D_C
+|   |   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   |   +--->BN_MP_COPY_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_COPY_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   +--->BN_MP_MUL_2_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_DIV_2_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_MUL_2D_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_MUL_D_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_DIV_3_C
+|   |   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_KARATSUBA_MUL_C
+|   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   +--->BN_FAST_S_MP_MUL_DIGS_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_S_MP_MUL_DIGS_C
+|   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   +--->BN_MP_MOD_C
+|   |   |   |   +--->BN_MP_DIV_C
+|   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   +--->BN_MP_COPY_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   +--->BN_MP_INIT_MULTI_C
+|   |   |   |   |   +--->BN_MP_SET_C
+|   |   |   |   |   +--->BN_MP_MUL_2D_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_CMP_C
+|   |   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   +--->BN_MP_MUL_D_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_EXCH_C
+|   |   +--->BN_MP_SET_C
+|   |   |   +--->BN_MP_ZERO_C
+|   |   +--->BN_MP_MOD_C
+|   |   |   +--->BN_MP_DIV_C
+|   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   +--->BN_MP_COPY_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   +--->BN_MP_INIT_MULTI_C
+|   |   |   |   +--->BN_MP_MUL_2D_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_CMP_C
+|   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   +--->BN_MP_MUL_D_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_ADD_C
+|   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_EXCH_C
+|   |   +--->BN_MP_COPY_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   +--->BN_MP_SQR_C
+|   |   |   +--->BN_MP_TOOM_SQR_C
+|   |   |   |   +--->BN_MP_INIT_MULTI_C
+|   |   |   |   +--->BN_MP_MOD_2D_C
+|   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   +--->BN_MP_MUL_2_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_DIV_2_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_MUL_2D_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_MUL_D_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_DIV_3_C
+|   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_KARATSUBA_SQR_C
+|   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_FAST_S_MP_SQR_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_S_MP_SQR_C
+|   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_EXCH_C
+|   |   +--->BN_MP_MUL_C
+|   |   |   +--->BN_MP_TOOM_MUL_C
+|   |   |   |   +--->BN_MP_INIT_MULTI_C
+|   |   |   |   +--->BN_MP_MOD_2D_C
+|   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   +--->BN_MP_MUL_2_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_DIV_2_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_MUL_2D_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_MUL_D_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_DIV_3_C
+|   |   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_KARATSUBA_MUL_C
+|   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_SUB_C
+|   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_ADD_C
+|   |   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   +--->BN_FAST_S_MP_MUL_DIGS_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_S_MP_MUL_DIGS_C
+|   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_EXCH_C
+|   |   +--->BN_MP_EXCH_C
++--->BN_MP_CMP_C
+|   +--->BN_MP_CMP_MAG_C
++--->BN_MP_SQRMOD_C
+|   +--->BN_MP_SQR_C
+|   |   +--->BN_MP_TOOM_SQR_C
+|   |   |   +--->BN_MP_INIT_MULTI_C
+|   |   |   |   +--->BN_MP_CLEAR_C
+|   |   |   +--->BN_MP_MOD_2D_C
+|   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   |   +--->BN_MP_COPY_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_COPY_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   +--->BN_MP_MUL_2_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_ADD_C
+|   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_SUB_C
+|   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_DIV_2_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_MUL_2D_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_MUL_D_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_DIV_3_C
+|   |   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_MP_EXCH_C
+|   |   |   |   +--->BN_MP_CLEAR_C
+|   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLEAR_MULTI_C
+|   |   |   |   +--->BN_MP_CLEAR_C
+|   |   +--->BN_MP_KARATSUBA_SQR_C
+|   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_SUB_C
+|   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   |   +--->BN_MP_ZERO_C
+|   |   |   +--->BN_MP_ADD_C
+|   |   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLEAR_C
+|   |   +--->BN_FAST_S_MP_SQR_C
+|   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_S_MP_SQR_C
+|   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_EXCH_C
+|   |   |   +--->BN_MP_CLEAR_C
+|   +--->BN_MP_CLEAR_C
+|   +--->BN_MP_MOD_C
+|   |   +--->BN_MP_DIV_C
+|   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   +--->BN_MP_COPY_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   +--->BN_MP_ZERO_C
+|   |   |   +--->BN_MP_INIT_MULTI_C
+|   |   |   +--->BN_MP_SET_C
+|   |   |   +--->BN_MP_COUNT_BITS_C
+|   |   |   +--->BN_MP_ABS_C
+|   |   |   +--->BN_MP_MUL_2D_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_SUB_C
+|   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_ADD_C
+|   |   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_EXCH_C
+|   |   |   +--->BN_MP_CLEAR_MULTI_C
+|   |   |   +--->BN_MP_INIT_SIZE_C
+|   |   |   +--->BN_MP_LSHD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_RSHD_C
+|   |   |   +--->BN_MP_RSHD_C
+|   |   |   +--->BN_MP_MUL_D_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_ADD_C
+|   |   |   +--->BN_S_MP_ADD_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   |   +--->BN_MP_CMP_MAG_C
+|   |   |   +--->BN_S_MP_SUB_C
+|   |   |   |   +--->BN_MP_GROW_C
+|   |   |   |   +--->BN_MP_CLAMP_C
+|   |   +--->BN_MP_EXCH_C
++--->BN_MP_CLEAR_C
+
+
+BN_MP_DR_SETUP_C
+
+
+BN_MP_CMP_MAG_C
+
+
diff --git a/libtommath/changes.txt b/libtommath/changes.txt
new file mode 100644
index 0000000..4fc0913
--- /dev/null
+++ b/libtommath/changes.txt
@@ -0,0 +1,403 @@
+July 23rd, 2010
+v0.42.0
+       -- Fix for mp_prime_next_prime() bug when checking generated prime
+       -- allow mp_shrink to shrink initialized, but empty MPI's
+       -- Added project and solution files for Visual Studio 2005 and Visual Studio 2008. 
+
+March 10th, 2007
+v0.41  -- Wolfgang Ehrhardt suggested a quick fix to mp_div_d() which makes the detection of powers of two quicker. 
+       -- [CRI] Added libtommath.dsp for Visual C++ users.
+
+December 24th, 2006
+v0.40  -- Updated makefile to properly support LIBNAME
+       -- Fixed bug in fast_s_mp_mul_high_digs() which overflowed (line 83), thanks Valgrind!
+
+April 4th, 2006
+v0.39  -- Jim Wigginton pointed out my Montgomery examples in figures 6.4 and 6.6 were off by one, k should be 9 not 8
+       -- Bruce Guenter suggested I use --tag=CC for libtool builds where the compiler may think it's C++.
+       -- "mm" from sci.crypt pointed out that my mp_gcd was sub-optimal (I also updated and corrected the book)
+       -- updated some of the @@ tags in tommath.src to reflect source changes.
+       -- updated email and url info in all source files
+
+Jan 26th, 2006
+v0.38  -- broken makefile.shared fixed
+       -- removed some carry stores that were not required [updated text]
+       
+November 18th, 2005
+v0.37  -- [Don Porter] reported on a TCL list [HEY SEND ME BUGREPORTS ALREADY!!!] that mp_add_d() would compute -0 with some inputs.  Fixed.
+       -- [rinick@gmail.com] reported the makefile.bcc was messed up.  Fixed.
+       -- [Kevin Kenny] reported some issues with mp_toradix_n().  Now it doesn't require a min of 3 chars of output.  
+       -- Made the make command renamable.  Wee
+
+August 1st, 2005
+v0.36  -- LTM_PRIME_2MSB_ON was fixed and the "OFF" flag was removed.
+       -- [Peter LaDow] found a typo in the XREALLOC macro
+       -- [Peter LaDow] pointed out that mp_read_(un)signed_bin should have "const" on the input
+       -- Ported LTC patch to fix the prime_random_ex() function to get the bitsize correct [and the maskOR flags]
+       -- Kevin Kenny pointed out a stray //
+       -- David Hulton pointed out a typo in the textbook [mp_montgomery_setup() pseudo-code]
+       -- Neal Hamilton (Elliptic Semiconductor) pointed out that my Karatsuba notation was backwards and that I could use 
+          unsigned operations in the routine.  
+       -- Paul Schmidt pointed out a linking error in mp_exptmod() when BN_S_MP_EXPTMOD_C is undefined (and another for read_radix)
+       -- Updated makefiles to be way more flexible
+
+March 12th, 2005
+v0.35  -- Stupid XOR function missing line again... oops.
+       -- Fixed bug in invmod not handling negative inputs correctly [Wolfgang Ehrhardt]
+       -- Made exteuclid always give positive u3 output...[ Wolfgang Ehrhardt ]
+       -- [Wolfgang Ehrhardt] Suggested a fix for mp_reduce() which avoided underruns.  ;-)
+       -- mp_rand() would emit one too many digits and it was possible to get a 0 out of it ... oops
+       -- Added montgomery to the testing to make sure it handles 1..10 digit moduli correctly
+       -- Fixed bug in comba that would lead to possible erroneous outputs when "pa < digs" 
+       -- Fixed bug in mp_toradix_size for "0" [Kevin Kenny]
+       -- Updated chapters 1-5 of the textbook ;-) It now talks about the new comba code!
+
+February 12th, 2005
+v0.34  -- Fixed two more small errors in mp_prime_random_ex()
+       -- Fixed overflow in mp_mul_d() [Kevin Kenny]
+       -- Added mp_to_(un)signed_bin_n() functions which do bounds checking for ya [and report the size]
+       -- Added "large" diminished radix support.  Speeds up things like DSA where the moduli is of the form 2^k - P for some P < 2^(k/2) or so
+          Actually is faster than Montgomery on my AMD64 (and probably much faster on a P4)
+       -- Updated the manual a bit
+       -- Ok so I haven't done the textbook work yet... My current freelance gig has landed me in France till the 
+          end of Feb/05.  Once I get back I'll have tons of free time and I plan to go to town on the book.
+          As of this release the API will freeze.  At least until the book catches up with all the changes.  I welcome
+          bug reports but new algorithms will have to wait.
+
+December 23rd, 2004
+v0.33  -- Fixed "small" variant for mp_div() which would munge with negative dividends...
+       -- Fixed bug in mp_prime_random_ex() which would set the most significant byte to zero when
+          no special flags were set
+       -- Fixed overflow [minor] bug in fast_s_mp_sqr()
+       -- Made the makefiles easier to configure the group/user that ltm will install as
+       -- Fixed "final carry" bug in comba multipliers. (Volkan Ceylan)
+       -- Matt Johnston pointed out a missing semi-colon in mp_exptmod
+
+October 29th, 2004
+v0.32  -- Added "makefile.shared" for shared object support
+       -- Added more to the build options/configs in the manual
+       -- Started the Depends framework, wrote dep.pl to scan deps and 
+          produce "callgraph.txt" ;-)
+       -- Wrote SC_RSA_1 which will enable close to the minimum required to perform
+          RSA on 32-bit [or 64-bit] platforms with LibTomCrypt
+       -- Merged in the small/slower mp_div replacement.  You can now toggle which
+          you want to use as your mp_div() at build time.  Saves roughly 8KB or so.
+       -- Renamed a few files and changed some comments to make depends system work better.
+          (No changes to function names)
+       -- Merged in new Combas that perform 2 reads per inner loop instead of the older 
+          3reads/2writes per inner loop of the old code.  Really though if you want speed
+          learn to use TomsFastMath ;-)
+
+August 9th, 2004
+v0.31  -- "profiled" builds now :-) new timings for Intel Northwoods
+       -- Added "pretty" build target
+       -- Update mp_init() to actually assign 0's instead of relying on calloc()
+       -- "Wolfgang Ehrhardt" <Wolfgang.Ehrhardt@munich.netsurf.de> found a bug in mp_mul() where if
+          you multiply a negative by zero you get negative zero as the result.  Oops.
+       -- J Harper from PeerSec let me toy with his AMD64 and I got 60-bit digits working properly
+          [this also means that I fixed a bug where if sizeof(int) < sizeof(mp_digit) it would bug]
+
+April 11th, 2004
+v0.30  -- Added "mp_toradix_n" which stores upto "n-1" least significant digits of an mp_int
+       -- Johan Lindh sent a patch so MSVC wouldn't whine about redefining malloc [in weird dll modes]
+       -- Henrik Goldman spotted a missing OPT_CAST in mp_fwrite()
+       -- Tuned tommath.h so that when MP_LOW_MEM is defined MP_PREC shall be reduced.
+          [I also allow MP_PREC to be externally defined now]
+       -- Sped up mp_cnt_lsb() by using a 4x4 table [e.g. 4x speedup]
+       -- Added mp_prime_random_ex() which is a more versatile prime generator accurate to
+          exact bit lengths (unlike the deprecated but still available mp_prime_random() which
+          is only accurate to byte lengths).  See the new LTM_PRIME_* flags ;-)
+       -- Alex Polushin contributed an optimized mp_sqrt() as well as mp_get_int() and mp_is_square().
+          I've cleaned them all up to be a little more consistent [along with one bug fix] for this release.
+       -- Added mp_init_set and mp_init_set_int to initialize and set small constants with one function
+          call.
+       -- Removed /etclib directory [um LibTomPoly deprecates this].
+       -- Fixed mp_mod() so the sign of the result agrees with the sign of the modulus.
+       ++ N.B.  My semester is almost up so expect updates to the textbook to be posted to the libtomcrypt.org 
+          website.  
+
+Jan 25th, 2004
+v0.29  ++ Note: "Henrik" from the v0.28 changelog refers to Henrik Goldman ;-)
+       -- Added fix to mp_shrink to prevent a realloc when used == 0 [e.g. realloc zero bytes???]
+       -- Made the mp_prime_rabin_miller_trials() function internal table smaller and also
+          set the minimum number of tests to two (sounds a bit safer).
+       -- Added a mp_exteuclid() which computes the extended euclidean algorithm.
+       -- Fixed a memory leak in s_mp_exptmod() [called when Barrett reduction is to be used] which would arise
+          if a multiplication or subsequent reduction failed [would not free the temp result].
+       -- Made an API change to mp_radix_size().  It now returns an error code and stores the required size
+          through an "int star" passed to it.
+
+Dec 24th, 2003
+v0.28  -- Henrik Goldman suggested I add casts to the montomgery code [stores into mu...] so compilers wouldn't
+          spew [erroneous] diagnostics... fixed.
+       -- Henrik Goldman also spotted two typos.  One in mp_radix_size() and another in mp_toradix().
+       -- Added fix to mp_shrink() to avoid a memory leak.
+       -- Added mp_prime_random() which requires a callback to make truly random primes of a given nature
+          (idea from chat with Niels Ferguson at Crypto'03)
+       -- Picked up a second wind.  I'm filled with Gooo.  Mission Gooo!
+       -- Removed divisions from mp_reduce_is_2k()
+       -- Sped up mp_div_d() [general case] to use only one division per digit instead of two.
+       -- Added the heap macros from LTC to LTM.  Now you can easily [by editing four lines of tommath.h]
+          change the name of the heap functions used in LTM [also compatible with LTC via MPI mode]
+       -- Added bn_prime_rabin_miller_trials() which gives the number of Rabin-Miller trials to achieve
+          a failure rate of less than 2^-96
+       -- fixed bug in fast_mp_invmod().  The initial testing logic was wrong.  An invalid input is not when
+          "a" and "b" are even it's when "b" is even [the algo is for odd moduli only].
+       -- Started a new manual [finally].  It is incomplete and will be finished as time goes on.  I had to stop
+          adding full demos around half way in chapter three so I could at least get a good portion of the
+          manual done.   If you really need help using the library you can always email me!
+       -- My Textbook is now included as part of the package [all Public Domain]
+
+Sept 19th, 2003
+v0.27  -- Removed changes.txt~ which was made by accident since "kate" decided it was
+          a good time to re-enable backups... [kde is fun!]
+       -- In mp_grow() "a->dp" is not overwritten by realloc call [re: memory leak]
+          Now if mp_grow() fails the mp_int is still valid and can be cleared via
+          mp_clear() to reclaim the memory.
+       -- Henrik Goldman found a buffer overflow bug in mp_add_d().  Fixed.
+       -- Cleaned up mp_mul_d() to be much easier to read and follow.
+
+Aug 29th, 2003
+v0.26  -- Fixed typo that caused warning with GCC 3.2
+       -- Martin Marcel noticed a bug in mp_neg() that allowed negative zeroes.
+          Also, Martin is the fellow who noted the bugs in mp_gcd() of 0.24/0.25.
+       -- Martin Marcel noticed an optimization [and slight bug] in mp_lcm().
+       -- Added fix to mp_read_unsigned_bin to prevent a buffer overflow.
+       -- Beefed up the comments in the baseline multipliers [and montgomery]
+       -- Added "mont" demo to the makefile.msvc in etc/
+       -- Optimized sign compares in mp_cmp from 4 to 2 cases.
+
+Aug 4th, 2003
+v0.25  -- Fix to mp_gcd again... oops (0,-a) == (-a, 0) == a
+       -- Fix to mp_clear which didn't reset the sign  [Greg Rose]
+       -- Added mp_error_to_string() to convert return codes to strings.  [Greg Rose]
+       -- Optimized fast_mp_invmod() to do the test for invalid inputs [both even]
+          first so temps don't have to be initialized if it's going to fail.
+       -- Optimized mp_gcd() by removing mp_div_2d calls for when one of the inputs
+          is odd.
+       -- Tons of new comments, some indentation fixups, etc.
+       -- mp_jacobi() returns MP_VAL if the modulus is less than or equal to zero.
+       -- fixed two typos in the header of each file :-)
+       -- LibTomMath is officially Public Domain [see LICENSE]
+
+July 15th, 2003
+v0.24  -- Optimized mp_add_d and mp_sub_d to not allocate temporary variables
+       -- Fixed mp_gcd() so the gcd of 0,0 is 0.  Allows the gcd operation to be chained
+          e.g. (0,0,a) == a [instead of 1]
+       -- Should be one of the last release for a while.  Working on LibTomMath book now.
+       -- optimized the pprime demo [/etc/pprime.c] to first make a huge table of single
+          digit primes then it reads them randomly instead of randomly choosing/testing single
+          digit primes.
+
+July 12th, 2003
+v0.23  -- Optimized mp_prime_next_prime() to not use mp_mod [via is_divisible()] in each
+          iteration.  Instead now a smaller table is kept of the residues which can be updated
+          without division.
+       -- Fixed a bug in next_prime() where an input of zero would be treated as odd and
+          have two added to it [to move to the next odd].
+       -- fixed a bug in prime_fermat() and prime_miller_rabin() which allowed the base
+          to be negative, zero or one.  Normally the test is only valid if the base is
+          greater than one.
+       -- changed the next_prime() prototype to accept a new parameter "bbs_style" which
+          will find the next prime congruent to 3 mod 4.  The default [bbs_style==0] will
+          make primes which are either congruent to 1 or 3 mod 4.
+       -- fixed mp_read_unsigned_bin() so that it doesn't include both code for
+          the case DIGIT_BIT < 8 and >= 8
+       -- optimized div_d() to easy out on division by 1 [or if a == 0] and use
+          logical shifts if the divisor is a power of two.
+       -- the default DIGIT_BIT type was not int for non-default builds.  Fixed.
+
+July 2nd, 2003
+v0.22  -- Fixed up mp_invmod so the result is properly in range now [was always congruent to the inverse...]
+       -- Fixed up s_mp_exptmod and mp_exptmod_fast so the lower half of the pre-computed table isn't allocated
+          which makes the algorithm use half as much ram.
+       -- Fixed the install script not to make the book :-) [which isn't included anyways]
+       -- added mp_cnt_lsb() which counts how many of the lsbs are zero
+       -- optimized mp_gcd() to use the new mp_cnt_lsb() to replace multiple divisions by two by a single division.
+       -- applied similar optimization to mp_prime_miller_rabin().
+       -- Fixed a bug in both mp_invmod() and fast_mp_invmod() which tested for odd
+          via "mp_iseven() == 0" which is not valid [since zero is not even either].
+
+June 19th, 2003
+v0.21  -- Fixed bug in mp_mul_d which would not handle sign correctly [would not always forward it]
+       -- Removed the #line lines from gen.pl [was in violation of ISO C]
+
+June 8th, 2003
+v0.20  -- Removed the book from the package.  Added the TDCAL license document.
+       -- This release is officially pure-bred TDCAL again [last officially TDCAL based release was v0.16]
+
+June 6th, 2003
+v0.19  -- Fixed a bug in mp_montgomery_reduce() which was introduced when I tweaked mp_rshd() in the previous release.
+          Essentially the digits were not trimmed before the compare which cause a subtraction to occur all the time.
+       -- Fixed up etc/tune.c a bit to stop testing new cutoffs after 16 failures [to find more optimal points].
+          Brute force ho!
+
+
+May 29th, 2003
+v0.18  -- Fixed a bug in s_mp_sqr which would handle carries properly just not very elegantly.
+          (e.g. correct result, just bad looking code)
+       -- Fixed bug in mp_sqr which still had a 512 constant instead of MP_WARRAY
+       -- Added Toom-Cook multipliers [needs tuning!]
+       -- Added efficient divide by 3 algorithm mp_div_3
+       -- Re-wrote mp_div_d to be faster than calling mp_div
+       -- Added in a donated BCC makefile and a single page LTM poster (ahalhabsi@sbcglobal.net)
+       -- Added mp_reduce_2k which reduces an input modulo n = 2**p - k for any single digit k
+       -- Made the exptmod system be aware of the 2k reduction algorithms.
+       -- Rewrote mp_dr_reduce to be smaller, simpler and easier to understand.
+
+May 17th, 2003
+v0.17  -- Benjamin Goldberg submitted optimized mp_add and mp_sub routines.  A new gen.pl as well
+          as several smaller suggestions.  Thanks!
+       -- removed call to mp_cmp in inner loop of mp_div and put mp_cmp_mag in its place :-)
+       -- Fixed bug in mp_exptmod that would cause it to fail for odd moduli when DIGIT_BIT != 28
+       -- mp_exptmod now also returns errors if the modulus is negative and will handle negative exponents
+       -- mp_prime_is_prime will now return true if the input is one of the primes in the prime table
+       -- Damian M Gryski (dgryski@uwaterloo.ca) found a index out of bounds error in the
+          mp_fast_s_mp_mul_high_digs function which didn't come up before.  (fixed)
+       -- Refactored the DR reduction code so there is only one function per file.
+       -- Fixed bug in the mp_mul() which would erroneously avoid the faster multiplier [comba] when it was
+          allowed.  The bug would not cause the incorrect value to be produced just less efficient (fixed)
+       -- Fixed similar bug in the Montgomery reduction code.
+       -- Added tons of (mp_digit) casts so the 7/15/28/31 bit digit code will work flawlessly out of the box.
+          Also added limited support for 64-bit machines with a 60-bit digit.  Both thanks to Tom Wu (tom@arcot.com)
+       -- Added new comments here and there, cleaned up some code [style stuff]
+       -- Fixed a lingering typo in mp_exptmod* that would set bitcnt to zero then one.  Very silly stuff :-)
+       -- Fixed up mp_exptmod_fast so it would set "redux" to the comba Montgomery reduction if allowed.  This
+          saves quite a few calls and if statements.
+       -- Added etc/mont.c a test of the Montgomery reduction [assuming all else works :-| ]
+       -- Fixed up etc/tune.c to use a wider test range [more appropriate] also added a x86 based addition which
+          uses RDTSC for high precision timing.
+       -- Updated demo/demo.c to remove MPI stuff [won't work anyways], made the tests run for 2 seconds each so its
+          not so insanely slow.  Also made the output space delimited [and fixed up various errors]
+       -- Added logs directory, logs/graph.dem which will use gnuplot to make a series of PNG files
+          that go with the pre-made index.html.  You have to build [via make timing] and run ltmtest first in the
+          root of the package.
+       -- Fixed a bug in mp_sub and mp_add where "-a - -a" or "-a + a" would produce -0 as the result [obviously invalid].
+       -- Fixed a bug in mp_rshd.  If the count == a.used it should zero/return [instead of shifting]
+       -- Fixed a "off-by-one" bug in mp_mul2d.  The initial size check on alloc would be off by one if the residue
+          shifting caused a carry.
+       -- Fixed a bug where s_mp_mul_digs() would not call the Comba based routine if allowed.  This made Barrett reduction
+          slower than it had to be.
+
+Mar 29th, 2003
+v0.16  -- Sped up mp_div by making normalization one shift call
+       -- Sped up mp_mul_2d/mp_div_2d by aliasing pointers :-)
+       -- Cleaned up mp_gcd to use the macros for odd/even detection
+       -- Added comments here and there, mostly there but occasionally here too.
+
+Mar 22nd, 2003
+v0.15  -- Added series of prime testing routines to lib
+       -- Fixed up etc/tune.c
+       -- Added DR reduction algorithm
+       -- Beefed up the manual more.
+       -- Fixed up demo/demo.c so it doesn't have so many warnings and it does the full series of
+          tests
+       -- Added "pre-gen" directory which will hold a "gen.pl"'ed copy of the entire lib [done at
+          zipup time so its always the latest]
+       -- Added conditional casts for C++ users [boo!]
+
+Mar 15th, 2003
+v0.14  -- Tons of manual updates
+       -- cleaned up the directory
+       -- added MSVC makefiles
+       -- source changes [that I don't recall]
+       -- Fixed up the lshd/rshd code to use pointer aliasing
+       -- Fixed up the mul_2d and div_2d to not call rshd/lshd unless needed
+       -- Fixed up etc/tune.c a tad
+       -- fixed up demo/demo.c to output comma-delimited results of timing
+          also fixed up timing demo to use a finer granularity for various functions
+       -- fixed up demo/demo.c testing to pause during testing so my Duron won't catch on fire
+          [stays around 31-35C during testing :-)]
+
+Feb 13th, 2003
+v0.13  -- tons of minor speed-ups in low level add, sub, mul_2 and div_2 which propagate
+          to other functions like mp_invmod, mp_div, etc...
+       -- Sped up mp_exptmod_fast by using new code to find R mod m [e.g. B^n mod m]
+       -- minor fixes
+
+Jan 17th, 2003
+v0.12  -- re-wrote the majority of the makefile so its more portable and will
+          install via "make install" on most *nix platforms
+       -- Re-packaged all the source as seperate files.  Means the library a single
+          file packagage any more.  Instead of just adding "bn.c" you have to add
+          libtommath.a
+       -- Renamed "bn.h" to "tommath.h"
+       -- Changes to the manual to reflect all of this
+       -- Used GNU Indent to clean up the source
+
+Jan 15th, 2003
+v0.11  -- More subtle fixes
+       -- Moved to gentoo linux [hurrah!] so made *nix specific fixes to the make process
+       -- Sped up the montgomery reduction code quite a bit
+       -- fixed up demo so when building timing for the x86 it assumes ELF format now
+
+Jan 9th, 2003
+v0.10  -- Pekka Riikonen suggested fixes to the radix conversion code.
+       -- Added baseline montgomery and comba montgomery reductions, sped up exptmods
+          [to a point, see bn.h for MONTGOMERY_EXPT_CUTOFF]
+
+Jan 6th, 2003
+v0.09  -- Updated the manual to reflect recent changes.  :-)
+       -- Added Jacobi function (mp_jacobi) to supplement the number theory side of the lib
+       -- Added a Mersenne prime finder demo in ./etc/mersenne.c
+
+Jan 2nd, 2003
+v0.08  -- Sped up the multipliers by moving the inner loop variables into a smaller scope
+       -- Corrected a bunch of small "warnings"
+       -- Added more comments
+       -- Made "mtest" be able to use /dev/random, /dev/urandom or stdin for RNG data
+       -- Corrected some bugs where error messages were potentially ignored
+       -- add etc/pprime.c program which makes numbers which are provably prime.
+
+Jan 1st, 2003
+v0.07  -- Removed alot of heap operations from core functions to speed them up
+       -- Added a root finding function [and mp_sqrt macro like from MPI]
+       -- Added more to manual
+
+Dec 31st, 2002
+v0.06  -- Sped up the s_mp_add, s_mp_sub which inturn sped up mp_invmod, mp_exptmod, etc...
+       -- Cleaned up the header a bit more
+
+Dec 30th, 2002
+v0.05  -- Builds with MSVC out of the box
+       -- Fixed a bug in mp_invmod w.r.t. even moduli
+       -- Made mp_toradix and mp_read_radix use char instead of unsigned char arrays
+       -- Fixed up exptmod to use fewer multiplications
+       -- Fixed up mp_init_size to use only one heap operation
+          -- Note there is a slight "off-by-one" bug in the library somewhere
+             without the padding (see the source for comment) the library
+             crashes in libtomcrypt.  Anyways a reasonable workaround is to pad the
+             numbers which will always correct it since as the numbers grow the padding
+             will still be beyond the end of the number
+       -- Added more to the manual
+
+Dec 29th, 2002
+v0.04  -- Fixed a memory leak in mp_to_unsigned_bin
+       -- optimized invmod code
+       -- Fixed bug in mp_div
+       -- use exchange instead of copy for results
+       -- added a bit more to the manual
+
+Dec 27th, 2002
+v0.03  -- Sped up s_mp_mul_high_digs by not computing the carries of the lower digits
+       -- Fixed a bug where mp_set_int wouldn't zero the value first and set the used member.
+       -- fixed a bug in s_mp_mul_high_digs where the limit placed on the result digits was not calculated properly
+       -- fixed bugs in add/sub/mul/sqr_mod functions where if the modulus and dest were the same it wouldn't work
+       -- fixed a bug in mp_mod and mp_mod_d concerning negative inputs
+       -- mp_mul_d didn't preserve sign
+       -- Many many many many fixes
+       -- Works in LibTomCrypt now :-)
+       -- Added iterations to the timing demos... more accurate.
+       -- Tom needs a job.
+
+Dec 26th, 2002
+v0.02  -- Fixed a few "slips" in the manual.  This is "LibTomMath" afterall :-)
+       -- Added mp_cmp_mag, mp_neg, mp_abs and mp_radix_size that were missing.
+       -- Sped up the fast [comba] multipliers more [yahoo!]
+
+Dec 25th,2002
+v0.01  -- Initial release.  Gimme a break.
+       -- Todo list,
+           add details to manual [e.g. algorithms]
+           more comments in code
+           example programs
diff --git a/libtommath/demo/demo.c b/libtommath/demo/demo.c
new file mode 100644
index 0000000..e1f8a5e
--- /dev/null
+++ b/libtommath/demo/demo.c
@@ -0,0 +1,736 @@
+#include <time.h>
+
+#ifdef IOWNANATHLON
+#include <unistd.h>
+#define SLEEP sleep(4)
+#else
+#define SLEEP
+#endif
+
+#include "tommath.h"
+
+void ndraw(mp_int * a, char *name)
+{
+   char buf[16000];
+
+   printf("%s: ", name);
+   mp_toradix(a, buf, 10);
+   printf("%s\n", buf);
+}
+
+static void draw(mp_int * a)
+{
+   ndraw(a, "");
+}
+
+
+unsigned long lfsr = 0xAAAAAAAAUL;
+
+int lbit(void)
+{
+   if (lfsr & 0x80000000UL) {
+      lfsr = ((lfsr << 1) ^ 0x8000001BUL) & 0xFFFFFFFFUL;
+      return 1;
+   } else {
+      lfsr <<= 1;
+      return 0;
+   }
+}
+
+int myrng(unsigned char *dst, int len, void *dat)
+{
+   int x;
+
+   for (x = 0; x < len; x++)
+      dst[x] = rand() & 0xFF;
+   return len;
+}
+
+
+
+char cmd[4096], buf[4096];
+int main(void)
+{
+   mp_int a, b, c, d, e, f;
+   unsigned long expt_n, add_n, sub_n, mul_n, div_n, sqr_n, mul2d_n, div2d_n,
+      gcd_n, lcm_n, inv_n, div2_n, mul2_n, add_d_n, sub_d_n, t;
+   unsigned rr;
+   int i, n, err, cnt, ix, old_kara_m, old_kara_s;
+   mp_digit mp;
+
+
+   mp_init(&a);
+   mp_init(&b);
+   mp_init(&c);
+   mp_init(&d);
+   mp_init(&e);
+   mp_init(&f);
+
+   srand(time(NULL));
+
+#if 0
+   // test montgomery 
+   printf("Testing montgomery...\n");
+   for (i = 1; i < 10; i++) {
+      printf("Testing digit size: %d\n", i);
+      for (n = 0; n < 1000; n++) {
+         mp_rand(&a, i);
+         a.dp[0] |= 1;
+
+         // let's see if R is right
+         mp_montgomery_calc_normalization(&b, &a);
+         mp_montgomery_setup(&a, &mp);
+
+         // now test a random reduction 
+         for (ix = 0; ix < 100; ix++) {
+             mp_rand(&c, 1 + abs(rand()) % (2*i));
+             mp_copy(&c, &d);
+             mp_copy(&c, &e);
+
+             mp_mod(&d, &a, &d);
+             mp_montgomery_reduce(&c, &a, mp);
+             mp_mulmod(&c, &b, &a, &c);
+
+             if (mp_cmp(&c, &d) != MP_EQ) { 
+printf("d = e mod a, c = e MOD a\n");
+mp_todecimal(&a, buf); printf("a = %s\n", buf);
+mp_todecimal(&e, buf); printf("e = %s\n", buf);
+mp_todecimal(&d, buf); printf("d = %s\n", buf);
+mp_todecimal(&c, buf); printf("c = %s\n", buf);
+printf("compare no compare!\n"); exit(EXIT_FAILURE); }
+         }
+      }
+   }
+   printf("done\n");
+
+   // test mp_get_int
+   printf("Testing: mp_get_int\n");
+   for (i = 0; i < 1000; ++i) {
+      t = ((unsigned long) rand() * rand() + 1) & 0xFFFFFFFF;
+      mp_set_int(&a, t);
+      if (t != mp_get_int(&a)) {
+	 printf("mp_get_int() bad result!\n");
+	 return 1;
+      }
+   }
+   mp_set_int(&a, 0);
+   if (mp_get_int(&a) != 0) {
+      printf("mp_get_int() bad result!\n");
+      return 1;
+   }
+   mp_set_int(&a, 0xffffffff);
+   if (mp_get_int(&a) != 0xffffffff) {
+      printf("mp_get_int() bad result!\n");
+      return 1;
+   }
+   // test mp_sqrt
+   printf("Testing: mp_sqrt\n");
+   for (i = 0; i < 1000; ++i) {
+      printf("%6d\r", i);
+      fflush(stdout);
+      n = (rand() & 15) + 1;
+      mp_rand(&a, n);
+      if (mp_sqrt(&a, &b) != MP_OKAY) {
+	 printf("mp_sqrt() error!\n");
+	 return 1;
+      }
+      mp_n_root(&a, 2, &a);
+      if (mp_cmp_mag(&b, &a) != MP_EQ) {
+	 printf("mp_sqrt() bad result!\n");
+	 return 1;
+      }
+   }
+
+   printf("\nTesting: mp_is_square\n");
+   for (i = 0; i < 1000; ++i) {
+      printf("%6d\r", i);
+      fflush(stdout);
+
+      /* test mp_is_square false negatives */
+      n = (rand() & 7) + 1;
+      mp_rand(&a, n);
+      mp_sqr(&a, &a);
+      if (mp_is_square(&a, &n) != MP_OKAY) {
+	 printf("fn:mp_is_square() error!\n");
+	 return 1;
+      }
+      if (n == 0) {
+	 printf("fn:mp_is_square() bad result!\n");
+	 return 1;
+      }
+
+      /* test for false positives */
+      mp_add_d(&a, 1, &a);
+      if (mp_is_square(&a, &n) != MP_OKAY) {
+	 printf("fp:mp_is_square() error!\n");
+	 return 1;
+      }
+      if (n == 1) {
+	 printf("fp:mp_is_square() bad result!\n");
+	 return 1;
+      }
+
+   }
+   printf("\n\n");
+
+   /* test for size */
+   for (ix = 10; ix < 128; ix++) {
+      printf("Testing (not safe-prime): %9d bits    \r", ix);
+      fflush(stdout);
+      err =
+	 mp_prime_random_ex(&a, 8, ix,
+			    (rand() & 1) ? LTM_PRIME_2MSB_OFF :
+			    LTM_PRIME_2MSB_ON, myrng, NULL);
+      if (err != MP_OKAY) {
+	 printf("failed with err code %d\n", err);
+	 return EXIT_FAILURE;
+      }
+      if (mp_count_bits(&a) != ix) {
+	 printf("Prime is %d not %d bits!!!\n", mp_count_bits(&a), ix);
+	 return EXIT_FAILURE;
+      }
+   }
+
+   for (ix = 16; ix < 128; ix++) {
+      printf("Testing (   safe-prime): %9d bits    \r", ix);
+      fflush(stdout);
+      err =
+	 mp_prime_random_ex(&a, 8, ix,
+			    ((rand() & 1) ? LTM_PRIME_2MSB_OFF :
+			     LTM_PRIME_2MSB_ON) | LTM_PRIME_SAFE, myrng,
+			    NULL);
+      if (err != MP_OKAY) {
+	 printf("failed with err code %d\n", err);
+	 return EXIT_FAILURE;
+      }
+      if (mp_count_bits(&a) != ix) {
+	 printf("Prime is %d not %d bits!!!\n", mp_count_bits(&a), ix);
+	 return EXIT_FAILURE;
+      }
+      /* let's see if it's really a safe prime */
+      mp_sub_d(&a, 1, &a);
+      mp_div_2(&a, &a);
+      mp_prime_is_prime(&a, 8, &cnt);
+      if (cnt != MP_YES) {
+	 printf("sub is not prime!\n");
+	 return EXIT_FAILURE;
+      }
+   }
+
+   printf("\n\n");
+
+   mp_read_radix(&a, "123456", 10);
+   mp_toradix_n(&a, buf, 10, 3);
+   printf("a == %s\n", buf);
+   mp_toradix_n(&a, buf, 10, 4);
+   printf("a == %s\n", buf);
+   mp_toradix_n(&a, buf, 10, 30);
+   printf("a == %s\n", buf);
+
+
+#if 0
+   for (;;) {
+      fgets(buf, sizeof(buf), stdin);
+      mp_read_radix(&a, buf, 10);
+      mp_prime_next_prime(&a, 5, 1);
+      mp_toradix(&a, buf, 10);
+      printf("%s, %lu\n", buf, a.dp[0] & 3);
+   }
+#endif
+
+   /* test mp_cnt_lsb */
+   printf("testing mp_cnt_lsb...\n");
+   mp_set(&a, 1);
+   for (ix = 0; ix < 1024; ix++) {
+      if (mp_cnt_lsb(&a) != ix) {
+	 printf("Failed at %d, %d\n", ix, mp_cnt_lsb(&a));
+	 return 0;
+      }
+      mp_mul_2(&a, &a);
+   }
+
+/* test mp_reduce_2k */
+   printf("Testing mp_reduce_2k...\n");
+   for (cnt = 3; cnt <= 128; ++cnt) {
+      mp_digit tmp;
+
+      mp_2expt(&a, cnt);
+      mp_sub_d(&a, 2, &a);	/* a = 2**cnt - 2 */
+
+
+      printf("\nTesting %4d bits", cnt);
+      printf("(%d)", mp_reduce_is_2k(&a));
+      mp_reduce_2k_setup(&a, &tmp);
+      printf("(%d)", tmp);
+      for (ix = 0; ix < 1000; ix++) {
+	 if (!(ix & 127)) {
+	    printf(".");
+	    fflush(stdout);
+	 }
+	 mp_rand(&b, (cnt / DIGIT_BIT + 1) * 2);
+	 mp_copy(&c, &b);
+	 mp_mod(&c, &a, &c);
+	 mp_reduce_2k(&b, &a, 2);
+	 if (mp_cmp(&c, &b)) {
+	    printf("FAILED\n");
+	    exit(0);
+	 }
+      }
+   }
+
+/* test mp_div_3  */
+   printf("Testing mp_div_3...\n");
+   mp_set(&d, 3);
+   for (cnt = 0; cnt < 10000;) {
+      mp_digit r1, r2;
+
+      if (!(++cnt & 127))
+	 printf("%9d\r", cnt);
+      mp_rand(&a, abs(rand()) % 128 + 1);
+      mp_div(&a, &d, &b, &e);
+      mp_div_3(&a, &c, &r2);
+
+      if (mp_cmp(&b, &c) || mp_cmp_d(&e, r2)) {
+	 printf("\n\nmp_div_3 => Failure\n");
+      }
+   }
+   printf("\n\nPassed div_3 testing\n");
+
+/* test the DR reduction */
+   printf("testing mp_dr_reduce...\n");
+   for (cnt = 2; cnt < 32; cnt++) {
+      printf("%d digit modulus\n", cnt);
+      mp_grow(&a, cnt);
+      mp_zero(&a);
+      for (ix = 1; ix < cnt; ix++) {
+	 a.dp[ix] = MP_MASK;
+      }
+      a.used = cnt;
+      a.dp[0] = 3;
+
+      mp_rand(&b, cnt - 1);
+      mp_copy(&b, &c);
+
+      rr = 0;
+      do {
+	 if (!(rr & 127)) {
+	    printf("%9lu\r", rr);
+	    fflush(stdout);
+	 }
+	 mp_sqr(&b, &b);
+	 mp_add_d(&b, 1, &b);
+	 mp_copy(&b, &c);
+
+	 mp_mod(&b, &a, &b);
+	 mp_dr_reduce(&c, &a, (((mp_digit) 1) << DIGIT_BIT) - a.dp[0]);
+
+	 if (mp_cmp(&b, &c) != MP_EQ) {
+	    printf("Failed on trial %lu\n", rr);
+	    exit(-1);
+
+	 }
+      } while (++rr < 500);
+      printf("Passed DR test for %d digits\n", cnt);
+   }
+
+#endif
+
+/* test the mp_reduce_2k_l code */
+#if 0
+#if 0
+/* first load P with 2^1024 - 0x2A434 B9FDEC95 D8F9D550 FFFFFFFF FFFFFFFF */
+   mp_2expt(&a, 1024);
+   mp_read_radix(&b, "2A434B9FDEC95D8F9D550FFFFFFFFFFFFFFFF", 16);
+   mp_sub(&a, &b, &a);
+#elif 1
+/*  p = 2^2048 - 0x1 00000000 00000000 00000000 00000000 4945DDBF 8EA2A91D 5776399B B83E188F  */
+   mp_2expt(&a, 2048);
+   mp_read_radix(&b,
+		 "1000000000000000000000000000000004945DDBF8EA2A91D5776399BB83E188F",
+		 16);
+   mp_sub(&a, &b, &a);
+#endif
+
+   mp_todecimal(&a, buf);
+   printf("p==%s\n", buf);
+/* now mp_reduce_is_2k_l() should return */
+   if (mp_reduce_is_2k_l(&a) != 1) {
+      printf("mp_reduce_is_2k_l() return 0, should be 1\n");
+      return EXIT_FAILURE;
+   }
+   mp_reduce_2k_setup_l(&a, &d);
+   /* now do a million square+1 to see if it varies */
+   mp_rand(&b, 64);
+   mp_mod(&b, &a, &b);
+   mp_copy(&b, &c);
+   printf("testing mp_reduce_2k_l...");
+   fflush(stdout);
+   for (cnt = 0; cnt < (1UL << 20); cnt++) {
+      mp_sqr(&b, &b);
+      mp_add_d(&b, 1, &b);
+      mp_reduce_2k_l(&b, &a, &d);
+      mp_sqr(&c, &c);
+      mp_add_d(&c, 1, &c);
+      mp_mod(&c, &a, &c);
+      if (mp_cmp(&b, &c) != MP_EQ) {
+	 printf("mp_reduce_2k_l() failed at step %lu\n", cnt);
+	 mp_tohex(&b, buf);
+	 printf("b == %s\n", buf);
+	 mp_tohex(&c, buf);
+	 printf("c == %s\n", buf);
+	 return EXIT_FAILURE;
+      }
+   }
+   printf("...Passed\n");
+#endif
+
+   div2_n = mul2_n = inv_n = expt_n = lcm_n = gcd_n = add_n =
+      sub_n = mul_n = div_n = sqr_n = mul2d_n = div2d_n = cnt = add_d_n =
+      sub_d_n = 0;
+
+   /* force KARA and TOOM to enable despite cutoffs */
+   KARATSUBA_SQR_CUTOFF = KARATSUBA_MUL_CUTOFF = 8;
+   TOOM_SQR_CUTOFF = TOOM_MUL_CUTOFF = 16;
+
+   for (;;) {
+      /* randomly clear and re-init one variable, this has the affect of triming the alloc space */
+      switch (abs(rand()) % 7) {
+      case 0:
+	 mp_clear(&a);
+	 mp_init(&a);
+	 break;
+      case 1:
+	 mp_clear(&b);
+	 mp_init(&b);
+	 break;
+      case 2:
+	 mp_clear(&c);
+	 mp_init(&c);
+	 break;
+      case 3:
+	 mp_clear(&d);
+	 mp_init(&d);
+	 break;
+      case 4:
+	 mp_clear(&e);
+	 mp_init(&e);
+	 break;
+      case 5:
+	 mp_clear(&f);
+	 mp_init(&f);
+	 break;
+      case 6:
+	 break;			/* don't clear any */
+      }
+
+
+      printf
+	 ("%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu/%4lu ",
+	  add_n, sub_n, mul_n, div_n, sqr_n, mul2d_n, div2d_n, gcd_n, lcm_n,
+	  expt_n, inv_n, div2_n, mul2_n, add_d_n, sub_d_n);
+      fgets(cmd, 4095, stdin);
+      cmd[strlen(cmd) - 1] = 0;
+      printf("%s  ]\r", cmd);
+      fflush(stdout);
+      if (!strcmp(cmd, "mul2d")) {
+	 ++mul2d_n;
+	 fgets(buf, 4095, stdin);
+	 mp_read_radix(&a, buf, 64);
+	 fgets(buf, 4095, stdin);
+	 sscanf(buf, "%d", &rr);
+	 fgets(buf, 4095, stdin);
+	 mp_read_radix(&b, buf, 64);
+
+	 mp_mul_2d(&a, rr, &a);
+	 a.sign = b.sign;
+	 if (mp_cmp(&a, &b) != MP_EQ) {
+	    printf("mul2d failed, rr == %d\n", rr);
+	    draw(&a);
+	    draw(&b);
+	    return 0;
+	 }
+      } else if (!strcmp(cmd, "div2d")) {
+	 ++div2d_n;
+	 fgets(buf, 4095, stdin);
+	 mp_read_radix(&a, buf, 64);
+	 fgets(buf, 4095, stdin);
+	 sscanf(buf, "%d", &rr);
+	 fgets(buf, 4095, stdin);
+	 mp_read_radix(&b, buf, 64);
+
+	 mp_div_2d(&a, rr, &a, &e);
+	 a.sign = b.sign;
+	 if (a.used == b.used && a.used == 0) {
+	    a.sign = b.sign = MP_ZPOS;
+	 }
+	 if (mp_cmp(&a, &b) != MP_EQ) {
+	    printf("div2d failed, rr == %d\n", rr);
+	    draw(&a);
+	    draw(&b);
+	    return 0;
+	 }
+      } else if (!strcmp(cmd, "add")) {
+	 ++add_n;
+	 fgets(buf, 4095, stdin);
+	 mp_read_radix(&a, buf, 64);
+	 fgets(buf, 4095, stdin);
+	 mp_read_radix(&b, buf, 64);
+	 fgets(buf, 4095, stdin);
+	 mp_read_radix(&c, buf, 64);
+	 mp_copy(&a, &d);
+	 mp_add(&d, &b, &d);
+	 if (mp_cmp(&c, &d) != MP_EQ) {
+	    printf("add %lu failure!\n", add_n);
+	    draw(&a);
+	    draw(&b);
+	    draw(&c);
+	    draw(&d);
+	    return 0;
+	 }
+
+	 /* test the sign/unsigned storage functions */
+
+	 rr = mp_signed_bin_size(&c);
+	 mp_to_signed_bin(&c, (unsigned char *) cmd);
+	 memset(cmd + rr, rand() & 255, sizeof(cmd) - rr);
+	 mp_read_signed_bin(&d, (unsigned char *) cmd, rr);
+	 if (mp_cmp(&c, &d) != MP_EQ) {
+	    printf("mp_signed_bin failure!\n");
+	    draw(&c);
+	    draw(&d);
+	    return 0;
+	 }
+
+
+	 rr = mp_unsigned_bin_size(&c);
+	 mp_to_unsigned_bin(&c, (unsigned char *) cmd);
+	 memset(cmd + rr, rand() & 255, sizeof(cmd) - rr);
+	 mp_read_unsigned_bin(&d, (unsigned char *) cmd, rr);
+	 if (mp_cmp_mag(&c, &d) != MP_EQ) {
+	    printf("mp_unsigned_bin failure!\n");
+	    draw(&c);
+	    draw(&d);
+	    return 0;
+	 }
+
+      } else if (!strcmp(cmd, "sub")) {
+	 ++sub_n;
+	 fgets(buf, 4095, stdin);
+	 mp_read_radix(&a, buf, 64);
+	 fgets(buf, 4095, stdin);
+	 mp_read_radix(&b, buf, 64);
+	 fgets(buf, 4095, stdin);
+	 mp_read_radix(&c, buf, 64);
+	 mp_copy(&a, &d);
+	 mp_sub(&d, &b, &d);
+	 if (mp_cmp(&c, &d) != MP_EQ) {
+	    printf("sub %lu failure!\n", sub_n);
+	    draw(&a);
+	    draw(&b);
+	    draw(&c);
+	    draw(&d);
+	    return 0;
+	 }
+      } else if (!strcmp(cmd, "mul")) {
+	 ++mul_n;
+	 fgets(buf, 4095, stdin);
+	 mp_read_radix(&a, buf, 64);
+	 fgets(buf, 4095, stdin);
+	 mp_read_radix(&b, buf, 64);
+	 fgets(buf, 4095, stdin);
+	 mp_read_radix(&c, buf, 64);
+	 mp_copy(&a, &d);
+	 mp_mul(&d, &b, &d);
+	 if (mp_cmp(&c, &d) != MP_EQ) {
+	    printf("mul %lu failure!\n", mul_n);
+	    draw(&a);
+	    draw(&b);
+	    draw(&c);
+	    draw(&d);
+	    return 0;
+	 }
+      } else if (!strcmp(cmd, "div")) {
+	 ++div_n;
+	 fgets(buf, 4095, stdin);
+	 mp_read_radix(&a, buf, 64);
+	 fgets(buf, 4095, stdin);
+	 mp_read_radix(&b, buf, 64);
+	 fgets(buf, 4095, stdin);
+	 mp_read_radix(&c, buf, 64);
+	 fgets(buf, 4095, stdin);
+	 mp_read_radix(&d, buf, 64);
+
+	 mp_div(&a, &b, &e, &f);
+	 if (mp_cmp(&c, &e) != MP_EQ || mp_cmp(&d, &f) != MP_EQ) {
+	    printf("div %lu %d, %d, failure!\n", div_n, mp_cmp(&c, &e),
+		   mp_cmp(&d, &f));
+	    draw(&a);
+	    draw(&b);
+	    draw(&c);
+	    draw(&d);
+	    draw(&e);
+	    draw(&f);
+	    return 0;
+	 }
+
+      } else if (!strcmp(cmd, "sqr")) {
+	 ++sqr_n;
+	 fgets(buf, 4095, stdin);
+	 mp_read_radix(&a, buf, 64);
+	 fgets(buf, 4095, stdin);
+	 mp_read_radix(&b, buf, 64);
+	 mp_copy(&a, &c);
+	 mp_sqr(&c, &c);
+	 if (mp_cmp(&b, &c) != MP_EQ) {
+	    printf("sqr %lu failure!\n", sqr_n);
+	    draw(&a);
+	    draw(&b);
+	    draw(&c);
+	    return 0;
+	 }
+      } else if (!strcmp(cmd, "gcd")) {
+	 ++gcd_n;
+	 fgets(buf, 4095, stdin);
+	 mp_read_radix(&a, buf, 64);
+	 fgets(buf, 4095, stdin);
+	 mp_read_radix(&b, buf, 64);
+	 fgets(buf, 4095, stdin);
+	 mp_read_radix(&c, buf, 64);
+	 mp_copy(&a, &d);
+	 mp_gcd(&d, &b, &d);
+	 d.sign = c.sign;
+	 if (mp_cmp(&c, &d) != MP_EQ) {
+	    printf("gcd %lu failure!\n", gcd_n);
+	    draw(&a);
+	    draw(&b);
+	    draw(&c);
+	    draw(&d);
+	    return 0;
+	 }
+      } else if (!strcmp(cmd, "lcm")) {
+	 ++lcm_n;
+	 fgets(buf, 4095, stdin);
+	 mp_read_radix(&a, buf, 64);
+	 fgets(buf, 4095, stdin);
+	 mp_read_radix(&b, buf, 64);
+	 fgets(buf, 4095, stdin);
+	 mp_read_radix(&c, buf, 64);
+	 mp_copy(&a, &d);
+	 mp_lcm(&d, &b, &d);
+	 d.sign = c.sign;
+	 if (mp_cmp(&c, &d) != MP_EQ) {
+	    printf("lcm %lu failure!\n", lcm_n);
+	    draw(&a);
+	    draw(&b);
+	    draw(&c);
+	    draw(&d);
+	    return 0;
+	 }
+      } else if (!strcmp(cmd, "expt")) {
+	 ++expt_n;
+	 fgets(buf, 4095, stdin);
+	 mp_read_radix(&a, buf, 64);
+	 fgets(buf, 4095, stdin);
+	 mp_read_radix(&b, buf, 64);
+	 fgets(buf, 4095, stdin);
+	 mp_read_radix(&c, buf, 64);
+	 fgets(buf, 4095, stdin);
+	 mp_read_radix(&d, buf, 64);
+	 mp_copy(&a, &e);
+	 mp_exptmod(&e, &b, &c, &e);
+	 if (mp_cmp(&d, &e) != MP_EQ) {
+	    printf("expt %lu failure!\n", expt_n);
+	    draw(&a);
+	    draw(&b);
+	    draw(&c);
+	    draw(&d);
+	    draw(&e);
+	    return 0;
+	 }
+      } else if (!strcmp(cmd, "invmod")) {
+	 ++inv_n;
+	 fgets(buf, 4095, stdin);
+	 mp_read_radix(&a, buf, 64);
+	 fgets(buf, 4095, stdin);
+	 mp_read_radix(&b, buf, 64);
+	 fgets(buf, 4095, stdin);
+	 mp_read_radix(&c, buf, 64);
+	 mp_invmod(&a, &b, &d);
+	 mp_mulmod(&d, &a, &b, &e);
+	 if (mp_cmp_d(&e, 1) != MP_EQ) {
+	    printf("inv [wrong value from MPI?!] failure\n");
+	    draw(&a);
+	    draw(&b);
+	    draw(&c);
+	    draw(&d);
+	    mp_gcd(&a, &b, &e);
+	    draw(&e);
+	    return 0;
+	 }
+
+      } else if (!strcmp(cmd, "div2")) {
+	 ++div2_n;
+	 fgets(buf, 4095, stdin);
+	 mp_read_radix(&a, buf, 64);
+	 fgets(buf, 4095, stdin);
+	 mp_read_radix(&b, buf, 64);
+	 mp_div_2(&a, &c);
+	 if (mp_cmp(&c, &b) != MP_EQ) {
+	    printf("div_2 %lu failure\n", div2_n);
+	    draw(&a);
+	    draw(&b);
+	    draw(&c);
+	    return 0;
+	 }
+      } else if (!strcmp(cmd, "mul2")) {
+	 ++mul2_n;
+	 fgets(buf, 4095, stdin);
+	 mp_read_radix(&a, buf, 64);
+	 fgets(buf, 4095, stdin);
+	 mp_read_radix(&b, buf, 64);
+	 mp_mul_2(&a, &c);
+	 if (mp_cmp(&c, &b) != MP_EQ) {
+	    printf("mul_2 %lu failure\n", mul2_n);
+	    draw(&a);
+	    draw(&b);
+	    draw(&c);
+	    return 0;
+	 }
+      } else if (!strcmp(cmd, "add_d")) {
+	 ++add_d_n;
+	 fgets(buf, 4095, stdin);
+	 mp_read_radix(&a, buf, 64);
+	 fgets(buf, 4095, stdin);
+	 sscanf(buf, "%d", &ix);
+	 fgets(buf, 4095, stdin);
+	 mp_read_radix(&b, buf, 64);
+	 mp_add_d(&a, ix, &c);
+	 if (mp_cmp(&b, &c) != MP_EQ) {
+	    printf("add_d %lu failure\n", add_d_n);
+	    draw(&a);
+	    draw(&b);
+	    draw(&c);
+	    printf("d == %d\n", ix);
+	    return 0;
+	 }
+      } else if (!strcmp(cmd, "sub_d")) {
+	 ++sub_d_n;
+	 fgets(buf, 4095, stdin);
+	 mp_read_radix(&a, buf, 64);
+	 fgets(buf, 4095, stdin);
+	 sscanf(buf, "%d", &ix);
+	 fgets(buf, 4095, stdin);
+	 mp_read_radix(&b, buf, 64);
+	 mp_sub_d(&a, ix, &c);
+	 if (mp_cmp(&b, &c) != MP_EQ) {
+	    printf("sub_d %lu failure\n", sub_d_n);
+	    draw(&a);
+	    draw(&b);
+	    draw(&c);
+	    printf("d == %d\n", ix);
+	    return 0;
+	 }
+      }
+   }
+   return 0;
+}
diff --git a/libtommath/demo/timing.c b/libtommath/demo/timing.c
new file mode 100644
index 0000000..bb3be52
--- /dev/null
+++ b/libtommath/demo/timing.c
@@ -0,0 +1,315 @@
+#include <tommath.h>
+#include <time.h>
+
+ulong64 _tt;
+
+#ifdef IOWNANATHLON
+#include <unistd.h>
+#define SLEEP sleep(4)
+#else
+#define SLEEP
+#endif
+
+
+void ndraw(mp_int * a, char *name)
+{
+   char buf[4096];
+
+   printf("%s: ", name);
+   mp_toradix(a, buf, 64);
+   printf("%s\n", buf);
+}
+
+static void draw(mp_int * a)
+{
+   ndraw(a, "");
+}
+
+
+unsigned long lfsr = 0xAAAAAAAAUL;
+
+int lbit(void)
+{
+   if (lfsr & 0x80000000UL) {
+      lfsr = ((lfsr << 1) ^ 0x8000001BUL) & 0xFFFFFFFFUL;
+      return 1;
+   } else {
+      lfsr <<= 1;
+      return 0;
+   }
+}
+
+/* RDTSC from Scott Duplichan */
+static ulong64 TIMFUNC(void)
+{
+#if defined __GNUC__
+#if defined(__i386__) || defined(__x86_64__)
+   unsigned long long a;
+   __asm__ __volatile__("rdtsc\nmovl %%eax,%0\nmovl %%edx,4+%0\n"::
+			"m"(a):"%eax", "%edx");
+   return a;
+#else /* gcc-IA64 version */
+   unsigned long result;
+   __asm__ __volatile__("mov %0=ar.itc":"=r"(result)::"memory");
+
+   while (__builtin_expect((int) result == -1, 0))
+      __asm__ __volatile__("mov %0=ar.itc":"=r"(result)::"memory");
+
+   return result;
+#endif
+
+   // Microsoft and Intel Windows compilers
+#elif defined _M_IX86
+   __asm rdtsc
+#elif defined _M_AMD64
+   return __rdtsc();
+#elif defined _M_IA64
+#if defined __INTEL_COMPILER
+#include <ia64intrin.h>
+#endif
+   return __getReg(3116);
+#else
+#error need rdtsc function for this build
+#endif
+}
+
+#define DO(x) x; x;
+//#define DO4(x) DO2(x); DO2(x);
+//#define DO8(x) DO4(x); DO4(x);
+//#define DO(x)  DO8(x); DO8(x);
+
+int main(void)
+{
+   ulong64 tt, gg, CLK_PER_SEC;
+   FILE *log, *logb, *logc, *logd;
+   mp_int a, b, c, d, e, f;
+   int n, cnt, ix, old_kara_m, old_kara_s;
+   unsigned rr;
+
+   mp_init(&a);
+   mp_init(&b);
+   mp_init(&c);
+   mp_init(&d);
+   mp_init(&e);
+   mp_init(&f);
+
+   srand(time(NULL));
+
+
+   /* temp. turn off TOOM */
+   TOOM_MUL_CUTOFF = TOOM_SQR_CUTOFF = 100000;
+
+   CLK_PER_SEC = TIMFUNC();
+   sleep(1);
+   CLK_PER_SEC = TIMFUNC() - CLK_PER_SEC;
+
+   printf("CLK_PER_SEC == %llu\n", CLK_PER_SEC);
+   goto exptmod;
+   log = fopen("logs/add.log", "w");
+   for (cnt = 8; cnt <= 128; cnt += 8) {
+      SLEEP;
+      mp_rand(&a, cnt);
+      mp_rand(&b, cnt);
+      rr = 0;
+      tt = -1;
+      do {
+	 gg = TIMFUNC();
+	 DO(mp_add(&a, &b, &c));
+	 gg = (TIMFUNC() - gg) >> 1;
+	 if (tt > gg)
+	    tt = gg;
+      } while (++rr < 100000);
+      printf("Adding\t\t%4d-bit => %9llu/sec, %9llu cycles\n",
+	     mp_count_bits(&a), CLK_PER_SEC / tt, tt);
+      fprintf(log, "%d %9llu\n", cnt * DIGIT_BIT, tt);
+      fflush(log);
+   }
+   fclose(log);
+
+   log = fopen("logs/sub.log", "w");
+   for (cnt = 8; cnt <= 128; cnt += 8) {
+      SLEEP;
+      mp_rand(&a, cnt);
+      mp_rand(&b, cnt);
+      rr = 0;
+      tt = -1;
+      do {
+	 gg = TIMFUNC();
+	 DO(mp_sub(&a, &b, &c));
+	 gg = (TIMFUNC() - gg) >> 1;
+	 if (tt > gg)
+	    tt = gg;
+      } while (++rr < 100000);
+
+      printf("Subtracting\t\t%4d-bit => %9llu/sec, %9llu cycles\n",
+	     mp_count_bits(&a), CLK_PER_SEC / tt, tt);
+      fprintf(log, "%d %9llu\n", cnt * DIGIT_BIT, tt);
+      fflush(log);
+   }
+   fclose(log);
+
+   /* do mult/square twice, first without karatsuba and second with */
+ multtest:
+   old_kara_m = KARATSUBA_MUL_CUTOFF;
+   old_kara_s = KARATSUBA_SQR_CUTOFF;
+   for (ix = 0; ix < 2; ix++) {
+      printf("With%s Karatsuba\n", (ix == 0) ? "out" : "");
+
+      KARATSUBA_MUL_CUTOFF = (ix == 0) ? 9999 : old_kara_m;
+      KARATSUBA_SQR_CUTOFF = (ix == 0) ? 9999 : old_kara_s;
+
+      log = fopen((ix == 0) ? "logs/mult.log" : "logs/mult_kara.log", "w");
+      for (cnt = 4; cnt <= 10240 / DIGIT_BIT; cnt += 2) {
+	 SLEEP;
+	 mp_rand(&a, cnt);
+	 mp_rand(&b, cnt);
+	 rr = 0;
+	 tt = -1;
+	 do {
+	    gg = TIMFUNC();
+	    DO(mp_mul(&a, &b, &c));
+	    gg = (TIMFUNC() - gg) >> 1;
+	    if (tt > gg)
+	       tt = gg;
+	 } while (++rr < 100);
+	 printf("Multiplying\t%4d-bit => %9llu/sec, %9llu cycles\n",
+		mp_count_bits(&a), CLK_PER_SEC / tt, tt);
+	 fprintf(log, "%d %9llu\n", mp_count_bits(&a), tt);
+	 fflush(log);
+      }
+      fclose(log);
+
+      log = fopen((ix == 0) ? "logs/sqr.log" : "logs/sqr_kara.log", "w");
+      for (cnt = 4; cnt <= 10240 / DIGIT_BIT; cnt += 2) {
+	 SLEEP;
+	 mp_rand(&a, cnt);
+	 rr = 0;
+	 tt = -1;
+	 do {
+	    gg = TIMFUNC();
+	    DO(mp_sqr(&a, &b));
+	    gg = (TIMFUNC() - gg) >> 1;
+	    if (tt > gg)
+	       tt = gg;
+	 } while (++rr < 100);
+	 printf("Squaring\t%4d-bit => %9llu/sec, %9llu cycles\n",
+		mp_count_bits(&a), CLK_PER_SEC / tt, tt);
+	 fprintf(log, "%d %9llu\n", mp_count_bits(&a), tt);
+	 fflush(log);
+      }
+      fclose(log);
+
+   }
+ exptmod:
+
+   {
+      char *primes[] = {
+	 /* 2K large moduli */
+	 "179769313486231590772930519078902473361797697894230657273430081157732675805500963132708477322407536021120113879871393357658789768814416622492847430639474124377767893424865485276302219601246094119453082952085005768838150682342462881473913110540827237163350510684586239334100047359817950870678242457666208137217",
+	 "32317006071311007300714876688669951960444102669715484032130345427524655138867890893197201411522913463688717960921898019494119559150490921095088152386448283120630877367300996091750197750389652106796057638384067568276792218642619756161838094338476170470581645852036305042887575891541065808607552399123930385521914333389668342420684974786564569494856176035326322058077805659331026192708460314150258592864177116725943603718461857357598351152301645904403697613233287231227125684710820209725157101726931323469678542580656697935045997268352998638099733077152121140120031150424541696791951097529546801429027668869927491725169",
+	 "1044388881413152506691752710716624382579964249047383780384233483283953907971557456848826811934997558340890106714439262837987573438185793607263236087851365277945956976543709998340361590134383718314428070011855946226376318839397712745672334684344586617496807908705803704071284048740118609114467977783598029006686938976881787785946905630190260940599579453432823469303026696443059025015972399867714215541693835559885291486318237914434496734087811872639496475100189041349008417061675093668333850551032972088269550769983616369411933015213796825837188091833656751221318492846368125550225998300412344784862595674492194617023806505913245610825731835380087608622102834270197698202313169017678006675195485079921636419370285375124784014907159135459982790513399611551794271106831134090584272884279791554849782954323534517065223269061394905987693002122963395687782878948440616007412945674919823050571642377154816321380631045902916136926708342856440730447899971901781465763473223850267253059899795996090799469201774624817718449867455659250178329070473119433165550807568221846571746373296884912819520317457002440926616910874148385078411929804522981857338977648103126085902995208257421855249796721729039744118165938433694823325696642096892124547425283",
+	 /* 2K moduli mersenne primes */
+	 "6864797660130609714981900799081393217269435300143305409394463459185543183397656052122559640661454554977296311391480858037121987999716643812574028291115057151",
+	 "531137992816767098689588206552468627329593117727031923199444138200403559860852242739162502265229285668889329486246501015346579337652707239409519978766587351943831270835393219031728127",
+	 "10407932194664399081925240327364085538615262247266704805319112350403608059673360298012239441732324184842421613954281007791383566248323464908139906605677320762924129509389220345773183349661583550472959420547689811211693677147548478866962501384438260291732348885311160828538416585028255604666224831890918801847068222203140521026698435488732958028878050869736186900714720710555703168729087",
+	 "1475979915214180235084898622737381736312066145333169775147771216478570297878078949377407337049389289382748507531496480477281264838760259191814463365330269540496961201113430156902396093989090226259326935025281409614983499388222831448598601834318536230923772641390209490231836446899608210795482963763094236630945410832793769905399982457186322944729636418890623372171723742105636440368218459649632948538696905872650486914434637457507280441823676813517852099348660847172579408422316678097670224011990280170474894487426924742108823536808485072502240519452587542875349976558572670229633962575212637477897785501552646522609988869914013540483809865681250419497686697771007",
+	 "259117086013202627776246767922441530941818887553125427303974923161874019266586362086201209516800483406550695241733194177441689509238807017410377709597512042313066624082916353517952311186154862265604547691127595848775610568757931191017711408826252153849035830401185072116424747461823031471398340229288074545677907941037288235820705892351068433882986888616658650280927692080339605869308790500409503709875902119018371991620994002568935113136548829739112656797303241986517250116412703509705427773477972349821676443446668383119322540099648994051790241624056519054483690809616061625743042361721863339415852426431208737266591962061753535748892894599629195183082621860853400937932839420261866586142503251450773096274235376822938649407127700846077124211823080804139298087057504713825264571448379371125032081826126566649084251699453951887789613650248405739378594599444335231188280123660406262468609212150349937584782292237144339628858485938215738821232393687046160677362909315071",
+	 "190797007524439073807468042969529173669356994749940177394741882673528979787005053706368049835514900244303495954950709725762186311224148828811920216904542206960744666169364221195289538436845390250168663932838805192055137154390912666527533007309292687539092257043362517857366624699975402375462954490293259233303137330643531556539739921926201438606439020075174723029056838272505051571967594608350063404495977660656269020823960825567012344189908927956646011998057988548630107637380993519826582389781888135705408653045219655801758081251164080554609057468028203308718724654081055323215860189611391296030471108443146745671967766308925858547271507311563765171008318248647110097614890313562856541784154881743146033909602737947385055355960331855614540900081456378659068370317267696980001187750995491090350108417050917991562167972281070161305972518044872048331306383715094854938415738549894606070722584737978176686422134354526989443028353644037187375385397838259511833166416134323695660367676897722287918773420968982326089026150031515424165462111337527431154890666327374921446276833564519776797633875503548665093914556482031482248883127023777039667707976559857333357013727342079099064400455741830654320379350833236245819348824064783585692924881021978332974949906122664421376034687815350484991",
+
+	 /* DR moduli */
+	 "14059105607947488696282932836518693308967803494693489478439861164411992439598399594747002144074658928593502845729752797260025831423419686528151609940203368612079",
+	 "101745825697019260773923519755878567461315282017759829107608914364075275235254395622580447400994175578963163918967182013639660669771108475957692810857098847138903161308502419410142185759152435680068435915159402496058513611411688900243039",
+	 "736335108039604595805923406147184530889923370574768772191969612422073040099331944991573923112581267542507986451953227192970402893063850485730703075899286013451337291468249027691733891486704001513279827771740183629161065194874727962517148100775228363421083691764065477590823919364012917984605619526140821797602431",
+	 "38564998830736521417281865696453025806593491967131023221754800625044118265468851210705360385717536794615180260494208076605798671660719333199513807806252394423283413430106003596332513246682903994829528690198205120921557533726473585751382193953592127439965050261476810842071573684505878854588706623484573925925903505747545471088867712185004135201289273405614415899438276535626346098904241020877974002916168099951885406379295536200413493190419727789712076165162175783",
+	 "542189391331696172661670440619180536749994166415993334151601745392193484590296600979602378676624808129613777993466242203025054573692562689251250471628358318743978285860720148446448885701001277560572526947619392551574490839286458454994488665744991822837769918095117129546414124448777033941223565831420390846864429504774477949153794689948747680362212954278693335653935890352619041936727463717926744868338358149568368643403037768649616778526013610493696186055899318268339432671541328195724261329606699831016666359440874843103020666106568222401047720269951530296879490444224546654729111504346660859907296364097126834834235287147",
+	 "1487259134814709264092032648525971038895865645148901180585340454985524155135260217788758027400478312256339496385275012465661575576202252063145698732079880294664220579764848767704076761853197216563262660046602703973050798218246170835962005598561669706844469447435461092542265792444947706769615695252256130901271870341005768912974433684521436211263358097522726462083917939091760026658925757076733484173202927141441492573799914240222628795405623953109131594523623353044898339481494120112723445689647986475279242446083151413667587008191682564376412347964146113898565886683139407005941383669325997475076910488086663256335689181157957571445067490187939553165903773554290260531009121879044170766615232300936675369451260747671432073394867530820527479172464106442450727640226503746586340279816318821395210726268291535648506190714616083163403189943334431056876038286530365757187367147446004855912033137386225053275419626102417236133948503",
+	 "1095121115716677802856811290392395128588168592409109494900178008967955253005183831872715423151551999734857184538199864469605657805519106717529655044054833197687459782636297255219742994736751541815269727940751860670268774903340296040006114013971309257028332849679096824800250742691718610670812374272414086863715763724622797509437062518082383056050144624962776302147890521249477060215148275163688301275847155316042279405557632639366066847442861422164832655874655824221577849928863023018366835675399949740429332468186340518172487073360822220449055340582568461568645259954873303616953776393853174845132081121976327462740354930744487429617202585015510744298530101547706821590188733515880733527449780963163909830077616357506845523215289297624086914545378511082534229620116563260168494523906566709418166011112754529766183554579321224940951177394088465596712620076240067370589036924024728375076210477267488679008016579588696191194060127319035195370137160936882402244399699172017835144537488486396906144217720028992863941288217185353914991583400421682751000603596655790990815525126154394344641336397793791497068253936771017031980867706707490224041075826337383538651825493679503771934836094655802776331664261631740148281763487765852746577808019633679",
+
+	 /* generic unrestricted moduli */
+	 "17933601194860113372237070562165128350027320072176844226673287945873370751245439587792371960615073855669274087805055507977323024886880985062002853331424203",
+	 "2893527720709661239493896562339544088620375736490408468011883030469939904368086092336458298221245707898933583190713188177399401852627749210994595974791782790253946539043962213027074922559572312141181787434278708783207966459019479487",
+	 "347743159439876626079252796797422223177535447388206607607181663903045907591201940478223621722118173270898487582987137708656414344685816179420855160986340457973820182883508387588163122354089264395604796675278966117567294812714812796820596564876450716066283126720010859041484786529056457896367683122960411136319",
+	 "47266428956356393164697365098120418976400602706072312735924071745438532218237979333351774907308168340693326687317443721193266215155735814510792148768576498491199122744351399489453533553203833318691678263241941706256996197460424029012419012634671862283532342656309677173602509498417976091509154360039893165037637034737020327399910409885798185771003505320583967737293415979917317338985837385734747478364242020380416892056650841470869294527543597349250299539682430605173321029026555546832473048600327036845781970289288898317888427517364945316709081173840186150794397479045034008257793436817683392375274635794835245695887",
+	 "436463808505957768574894870394349739623346440601945961161254440072143298152040105676491048248110146278752857839930515766167441407021501229924721335644557342265864606569000117714935185566842453630868849121480179691838399545644365571106757731317371758557990781880691336695584799313313687287468894148823761785582982549586183756806449017542622267874275103877481475534991201849912222670102069951687572917937634467778042874315463238062009202992087620963771759666448266532858079402669920025224220613419441069718482837399612644978839925207109870840278194042158748845445131729137117098529028886770063736487420613144045836803985635654192482395882603511950547826439092832800532152534003936926017612446606135655146445620623395788978726744728503058670046885876251527122350275750995227",
+	 "11424167473351836398078306042624362277956429440521137061889702611766348760692206243140413411077394583180726863277012016602279290144126785129569474909173584789822341986742719230331946072730319555984484911716797058875905400999504305877245849119687509023232790273637466821052576859232452982061831009770786031785669030271542286603956118755585683996118896215213488875253101894663403069677745948305893849505434201763745232895780711972432011344857521691017896316861403206449421332243658855453435784006517202894181640562433575390821384210960117518650374602256601091379644034244332285065935413233557998331562749140202965844219336298970011513882564935538704289446968322281451907487362046511461221329799897350993370560697505809686438782036235372137015731304779072430260986460269894522159103008260495503005267165927542949439526272736586626709581721032189532726389643625590680105784844246152702670169304203783072275089194754889511973916207",
+	 "1214855636816562637502584060163403830270705000634713483015101384881871978446801224798536155406895823305035467591632531067547890948695117172076954220727075688048751022421198712032848890056357845974246560748347918630050853933697792254955890439720297560693579400297062396904306270145886830719309296352765295712183040773146419022875165382778007040109957609739589875590885701126197906063620133954893216612678838507540777138437797705602453719559017633986486649523611975865005712371194067612263330335590526176087004421363598470302731349138773205901447704682181517904064735636518462452242791676541725292378925568296858010151852326316777511935037531017413910506921922450666933202278489024521263798482237150056835746454842662048692127173834433089016107854491097456725016327709663199738238442164843147132789153725513257167915555162094970853584447993125488607696008169807374736711297007473812256272245489405898470297178738029484459690836250560495461579533254473316340608217876781986188705928270735695752830825527963838355419762516246028680280988020401914551825487349990306976304093109384451438813251211051597392127491464898797406789175453067960072008590614886532333015881171367104445044718144312416815712216611576221546455968770801413440778423979",
+	 NULL
+      };
+      log = fopen("logs/expt.log", "w");
+      logb = fopen("logs/expt_dr.log", "w");
+      logc = fopen("logs/expt_2k.log", "w");
+      logd = fopen("logs/expt_2kl.log", "w");
+      for (n = 0; primes[n]; n++) {
+	 SLEEP;
+	 mp_read_radix(&a, primes[n], 10);
+	 mp_zero(&b);
+	 for (rr = 0; rr < (unsigned) mp_count_bits(&a); rr++) {
+	    mp_mul_2(&b, &b);
+	    b.dp[0] |= lbit();
+	    b.used += 1;
+	 }
+	 mp_sub_d(&a, 1, &c);
+	 mp_mod(&b, &c, &b);
+	 mp_set(&c, 3);
+	 rr = 0;
+	 tt = -1;
+	 do {
+	    gg = TIMFUNC();
+	    DO(mp_exptmod(&c, &b, &a, &d));
+	    gg = (TIMFUNC() - gg) >> 1;
+	    if (tt > gg)
+	       tt = gg;
+	 } while (++rr < 10);
+	 mp_sub_d(&a, 1, &e);
+	 mp_sub(&e, &b, &b);
+	 mp_exptmod(&c, &b, &a, &e);	/* c^(p-1-b) mod a */
+	 mp_mulmod(&e, &d, &a, &d);	/* c^b * c^(p-1-b) == c^p-1 == 1 */
+	 if (mp_cmp_d(&d, 1)) {
+	    printf("Different (%d)!!!\n", mp_count_bits(&a));
+	    draw(&d);
+	    exit(0);
+	 }
+	 printf("Exponentiating\t%4d-bit => %9llu/sec, %9llu cycles\n",
+		mp_count_bits(&a), CLK_PER_SEC / tt, tt);
+	 fprintf(n < 4 ? logd : (n < 9) ? logc : (n < 16) ? logb : log,
+		 "%d %9llu\n", mp_count_bits(&a), tt);
+      }
+   }
+   fclose(log);
+   fclose(logb);
+   fclose(logc);
+   fclose(logd);
+
+   log = fopen("logs/invmod.log", "w");
+   for (cnt = 4; cnt <= 128; cnt += 4) {
+      SLEEP;
+      mp_rand(&a, cnt);
+      mp_rand(&b, cnt);
+
+      do {
+	 mp_add_d(&b, 1, &b);
+	 mp_gcd(&a, &b, &c);
+      } while (mp_cmp_d(&c, 1) != MP_EQ);
+
+      rr = 0;
+      tt = -1;
+      do {
+	 gg = TIMFUNC();
+	 DO(mp_invmod(&b, &a, &c));
+	 gg = (TIMFUNC() - gg) >> 1;
+	 if (tt > gg)
+	    tt = gg;
+      } while (++rr < 1000);
+      mp_mulmod(&b, &c, &a, &d);
+      if (mp_cmp_d(&d, 1) != MP_EQ) {
+	 printf("Failed to invert\n");
+	 return 0;
+      }
+      printf("Inverting mod\t%4d-bit => %9llu/sec, %9llu cycles\n",
+	     mp_count_bits(&a), CLK_PER_SEC / tt, tt);
+      fprintf(log, "%d %9llu\n", cnt * DIGIT_BIT, tt);
+   }
+   fclose(log);
+
+   return 0;
+}
diff --git a/libtommath/dep.pl b/libtommath/dep.pl
new file mode 100644
index 0000000..c39e27e
--- /dev/null
+++ b/libtommath/dep.pl
@@ -0,0 +1,123 @@
+#!/usr/bin/perl 
+#
+# Walk through source, add labels and make classes
+#
+#use strict;
+
+my %deplist;
+
+#open class file and write preamble 
+open(CLASS, ">tommath_class.h") or die "Couldn't open tommath_class.h for writing\n";
+print CLASS "#if !(defined(LTM1) && defined(LTM2) && defined(LTM3))\n#if defined(LTM2)\n#define LTM3\n#endif\n#if defined(LTM1)\n#define LTM2\n#endif\n#define LTM1\n\n#if defined(LTM_ALL)\n";
+
+foreach my $filename (glob "bn*.c") {
+   my $define = $filename;
+
+print "Processing $filename\n";
+
+   # convert filename to upper case so we can use it as a define 
+   $define =~ tr/[a-z]/[A-Z]/;
+   $define =~ tr/\./_/;
+   print CLASS "#define $define\n";
+
+   # now copy text and apply #ifdef as required 
+   my $apply = 0;
+   open(SRC, "<$filename");
+   open(OUT, ">tmp");
+
+   # first line will be the #ifdef
+   my $line = <SRC>;
+   if ($line =~ /include/) {
+      print OUT $line;
+   } else {
+      print OUT "#include <tommath.h>\n#ifdef $define\n$line";
+      $apply = 1;
+   }
+   while (<SRC>) {
+      if (!($_ =~ /tommath\.h/)) {
+         print OUT $_;
+      }
+   }
+   if ($apply == 1) {
+      print OUT "#endif\n";
+   }
+   close SRC;
+   close OUT;
+
+   unlink($filename);
+   rename("tmp", $filename);
+}
+print CLASS "#endif\n\n";
+
+# now do classes 
+
+foreach my $filename (glob "bn*.c") {
+   open(SRC, "<$filename") or die "Can't open source file!\n"; 
+
+   # convert filename to upper case so we can use it as a define 
+   $filename =~ tr/[a-z]/[A-Z]/;
+   $filename =~ tr/\./_/;
+
+   print CLASS "#if defined($filename)\n";
+   my $list = $filename;
+
+   # scan for mp_* and make classes
+   while (<SRC>) {
+      my $line = $_;
+      while ($line =~ m/(fast_)*(s_)*mp\_[a-z_0-9]*/) {
+          $line = $';
+          # now $& is the match, we want to skip over LTM keywords like
+          # mp_int, mp_word, mp_digit
+          if (!($& eq "mp_digit") && !($& eq "mp_word") && !($& eq "mp_int")) {
+             my $a = $&;
+             $a =~ tr/[a-z]/[A-Z]/;
+             $a = "BN_" . $a . "_C";
+             if (!($list =~ /$a/)) {
+                print CLASS "   #define $a\n";
+             }
+             $list = $list . "," . $a;
+          }
+      }
+   }
+   @deplist{$filename} = $list;
+
+   print CLASS "#endif\n\n";
+   close SRC;
+}
+
+print CLASS "#ifdef LTM3\n#define LTM_LAST\n#endif\n#include <tommath_superclass.h>\n#include <tommath_class.h>\n#else\n#define LTM_LAST\n#endif\n";
+close CLASS;
+
+#now let's make a cool call graph... 
+
+open(OUT,">callgraph.txt");
+$indent = 0;
+foreach (keys %deplist) {
+   $list = "";
+   draw_func(@deplist{$_});
+   print OUT "\n\n";
+}
+close(OUT);
+
+sub draw_func()
+{
+   my @funcs = split(",", $_[0]);
+   if ($list =~ /@funcs[0]/) {
+      return;
+   } else {
+      $list = $list . @funcs[0];
+   }
+   if ($indent == 0) { }
+   elsif ($indent >= 1) { print OUT "|   " x ($indent - 1) . "+--->"; }
+   print OUT @funcs[0] . "\n";   
+   shift @funcs;
+      my $temp = $list;
+   foreach my $i (@funcs) {
+      ++$indent;
+      draw_func(@deplist{$i});
+      --$indent;
+   }
+      $list = $temp;
+}
+
+
diff --git a/libtommath/etc/2kprime.1 b/libtommath/etc/2kprime.1
new file mode 100644
index 0000000..c41ded1
--- /dev/null
+++ b/libtommath/etc/2kprime.1
@@ -0,0 +1,2 @@
+256-bits (k = 36113) = 115792089237316195423570985008687907853269984665640564039457584007913129603823
+512-bits (k = 38117) = 13407807929942597099574024998205846127479365820592393377723561443721764030073546976801874298166903427690031858186486050853753882811946569946433649006045979
diff --git a/libtommath/etc/2kprime.c b/libtommath/etc/2kprime.c
new file mode 100644
index 0000000..67a2777
--- /dev/null
+++ b/libtommath/etc/2kprime.c
@@ -0,0 +1,75 @@
+/* Makes safe primes of a 2k nature */
+#include <tommath.h>
+#include <time.h>
+
+int sizes[] = {256, 512, 768, 1024, 1536, 2048, 3072, 4096};
+
+int main(void)
+{
+   char buf[2000];
+   int x, y;
+   mp_int q, p;
+   FILE *out;
+   clock_t t1;
+   mp_digit z;
+   
+   mp_init_multi(&q, &p, NULL);
+   
+   out = fopen("2kprime.1", "w");
+   for (x = 0; x < (int)(sizeof(sizes) / sizeof(sizes[0])); x++) {
+   top:
+       mp_2expt(&q, sizes[x]);
+       mp_add_d(&q, 3, &q);
+       z = -3;
+       
+       t1 = clock();
+       for(;;) {
+         mp_sub_d(&q, 4, &q);
+         z += 4;
+
+         if (z > MP_MASK) {
+            printf("No primes of size %d found\n", sizes[x]);
+            break;
+         }
+         
+         if (clock() - t1 > CLOCKS_PER_SEC) { 
+            printf("."); fflush(stdout);
+//            sleep((clock() - t1 + CLOCKS_PER_SEC/2)/CLOCKS_PER_SEC);
+            t1 = clock();
+         }
+         
+         /* quick test on q */
+         mp_prime_is_prime(&q, 1, &y);
+         if (y == 0) {
+            continue;
+         }
+
+         /* find (q-1)/2 */
+         mp_sub_d(&q, 1, &p);
+         mp_div_2(&p, &p);
+         mp_prime_is_prime(&p, 3, &y);
+         if (y == 0) {
+            continue;
+         }
+
+         /* test on q */
+         mp_prime_is_prime(&q, 3, &y);
+         if (y == 0) {
+            continue;
+         }
+
+         break;
+       }
+       
+       if (y == 0) {
+          ++sizes[x];
+          goto top;
+       }
+       
+       mp_toradix(&q, buf, 10);
+       printf("\n\n%d-bits (k = %lu) = %s\n", sizes[x], z, buf);
+       fprintf(out, "%d-bits (k = %lu) = %s\n", sizes[x], z, buf); fflush(out);
+   }
+   
+   return 0;
+}   
diff --git a/libtommath/etc/drprime.c b/libtommath/etc/drprime.c
new file mode 100644
index 0000000..0d0fdb9
--- /dev/null
+++ b/libtommath/etc/drprime.c
@@ -0,0 +1,59 @@
+/* Makes safe primes of a DR nature */
+#include <tommath.h>
+
+int sizes[] = { 1+256/DIGIT_BIT, 1+512/DIGIT_BIT, 1+768/DIGIT_BIT, 1+1024/DIGIT_BIT, 1+2048/DIGIT_BIT, 1+4096/DIGIT_BIT };
+int main(void)
+{
+   int res, x, y;
+   char buf[4096];
+   FILE *out;
+   mp_int a, b;
+   
+   mp_init(&a);
+   mp_init(&b);
+   
+   out = fopen("drprimes.txt", "w");
+   for (x = 0; x < (int)(sizeof(sizes)/sizeof(sizes[0])); x++) {
+   top:
+       printf("Seeking a %d-bit safe prime\n", sizes[x] * DIGIT_BIT);
+       mp_grow(&a, sizes[x]);
+       mp_zero(&a);
+       for (y = 1; y < sizes[x]; y++) {
+           a.dp[y] = MP_MASK;
+       }
+       
+       /* make a DR modulus */
+       a.dp[0] = -1;
+       a.used = sizes[x];
+       
+       /* now loop */
+       res = 0;
+       for (;;) { 
+          a.dp[0] += 4;
+          if (a.dp[0] >= MP_MASK) break;
+          mp_prime_is_prime(&a, 1, &res);
+          if (res == 0) continue;
+          printf("."); fflush(stdout);
+          mp_sub_d(&a, 1, &b);
+          mp_div_2(&b, &b);
+          mp_prime_is_prime(&b, 3, &res);  
+          if (res == 0) continue;
+          mp_prime_is_prime(&a, 3, &res);
+          if (res == 1) break;
+	}
+        
+        if (res != 1) {
+           printf("Error not DR modulus\n"); sizes[x] += 1; goto top;
+        } else {
+           mp_toradix(&a, buf, 10);
+           printf("\n\np == %s\n\n", buf);
+           fprintf(out, "%d-bit prime:\np == %s\n\n", mp_count_bits(&a), buf); fflush(out);
+        }           
+   }
+   fclose(out);
+   
+   mp_clear(&a);
+   mp_clear(&b);
+   
+   return 0;
+}
diff --git a/libtommath/etc/drprimes.28 b/libtommath/etc/drprimes.28
new file mode 100644
index 0000000..9d438ad
--- /dev/null
+++ b/libtommath/etc/drprimes.28
@@ -0,0 +1,25 @@
+DR safe primes for 28-bit digits.
+
+224-bit prime:
+p == 26959946667150639794667015087019630673637144422540572481103341844143
+
+532-bit prime:
+p == 14059105607947488696282932836518693308967803494693489478439861164411992439598399594747002144074658928593502845729752797260025831423419686528151609940203368691747
+
+784-bit prime:
+p == 101745825697019260773923519755878567461315282017759829107608914364075275235254395622580447400994175578963163918967182013639660669771108475957692810857098847138903161308502419410142185759152435680068435915159402496058513611411688900243039
+
+1036-bit prime:
+p == 736335108039604595805923406147184530889923370574768772191969612422073040099331944991573923112581267542507986451953227192970402893063850485730703075899286013451337291468249027691733891486704001513279827771740183629161065194874727962517148100775228363421083691764065477590823919364012917984605619526140821798437127
+
+1540-bit prime:
+p == 38564998830736521417281865696453025806593491967131023221754800625044118265468851210705360385717536794615180260494208076605798671660719333199513807806252394423283413430106003596332513246682903994829528690198205120921557533726473585751382193953592127439965050261476810842071573684505878854588706623484573925925903505747545471088867712185004135201289273405614415899438276535626346098904241020877974002916168099951885406379295536200413493190419727789712076165162175783
+
+2072-bit prime:
+p == 542189391331696172661670440619180536749994166415993334151601745392193484590296600979602378676624808129613777993466242203025054573692562689251250471628358318743978285860720148446448885701001277560572526947619392551574490839286458454994488665744991822837769918095117129546414124448777033941223565831420390846864429504774477949153794689948747680362212954278693335653935890352619041936727463717926744868338358149568368643403037768649616778526013610493696186055899318268339432671541328195724261329606699831016666359440874843103020666106568222401047720269951530296879490444224546654729111504346660859907296364097126834834235287147
+
+3080-bit prime:
+p == 1487259134814709264092032648525971038895865645148901180585340454985524155135260217788758027400478312256339496385275012465661575576202252063145698732079880294664220579764848767704076761853197216563262660046602703973050798218246170835962005598561669706844469447435461092542265792444947706769615695252256130901271870341005768912974433684521436211263358097522726462083917939091760026658925757076733484173202927141441492573799914240222628795405623953109131594523623353044898339481494120112723445689647986475279242446083151413667587008191682564376412347964146113898565886683139407005941383669325997475076910488086663256335689181157957571445067490187939553165903773554290260531009121879044170766615232300936675369451260747671432073394867530820527479172464106442450727640226503746586340279816318821395210726268291535648506190714616083163403189943334431056876038286530365757187367147446004855912033137386225053275419626102417236133948503
+
+4116-bit prime:
+p == 1095121115716677802856811290392395128588168592409109494900178008967955253005183831872715423151551999734857184538199864469605657805519106717529655044054833197687459782636297255219742994736751541815269727940751860670268774903340296040006114013971309257028332849679096824800250742691718610670812374272414086863715763724622797509437062518082383056050144624962776302147890521249477060215148275163688301275847155316042279405557632639366066847442861422164832655874655824221577849928863023018366835675399949740429332468186340518172487073360822220449055340582568461568645259954873303616953776393853174845132081121976327462740354930744487429617202585015510744298530101547706821590188733515880733527449780963163909830077616357506845523215289297624086914545378511082534229620116563260168494523906566709418166011112754529766183554579321224940951177394088465596712620076240067370589036924024728375076210477267488679008016579588696191194060127319035195370137160936882402244399699172017835144537488486396906144217720028992863941288217185353914991583400421682751000603596655790990815525126154394344641336397793791497068253936771017031980867706707490224041075826337383538651825493679503771934836094655802776331664261631740148281763487765852746577808019633679
diff --git a/libtommath/etc/drprimes.txt b/libtommath/etc/drprimes.txt
new file mode 100644
index 0000000..7c97f67
--- /dev/null
+++ b/libtommath/etc/drprimes.txt
@@ -0,0 +1,9 @@
+300-bit prime:
+p == 2037035976334486086268445688409378161051468393665936250636140449354381298610415201576637819
+
+540-bit prime:
+p == 3599131035634557106248430806148785487095757694641533306480604458089470064537190296255232548883112685719936728506816716098566612844395439751206810991770626477344739
+
+780-bit prime:
+p == 6359114106063703798370219984742410466332205126109989319225557147754704702203399726411277962562135973685197744935448875852478791860694279747355800678568677946181447581781401213133886609947027230004277244697462656003655947791725966271167
+
diff --git a/libtommath/etc/makefile b/libtommath/etc/makefile
new file mode 100644
index 0000000..99154d8
--- /dev/null
+++ b/libtommath/etc/makefile
@@ -0,0 +1,50 @@
+CFLAGS += -Wall -W -Wshadow -O3 -fomit-frame-pointer -funroll-loops -I../
+
+# default lib name (requires install with root)
+# LIBNAME=-ltommath
+
+# libname when you can't install the lib with install
+LIBNAME=../libtommath.a
+
+#provable primes
+pprime: pprime.o
+	$(CC) pprime.o $(LIBNAME) -o pprime
+
+# portable [well requires clock()] tuning app
+tune: tune.o
+	$(CC) tune.o $(LIBNAME) -o tune
+	
+# same app but using RDTSC for higher precision [requires 80586+], coff based gcc installs [e.g. ming, cygwin, djgpp]
+tune86: tune.c
+	nasm -f coff timer.asm
+	$(CC) -DX86_TIMER $(CFLAGS) tune.c timer.o  $(LIBNAME) -o tune86
+	
+# for cygwin
+tune86c: tune.c
+	nasm -f gnuwin32 timer.asm
+	$(CC) -DX86_TIMER $(CFLAGS) tune.c timer.o  $(LIBNAME) -o tune86
+
+#make tune86 for linux or any ELF format
+tune86l: tune.c
+	nasm -f elf -DUSE_ELF timer.asm
+	$(CC) -DX86_TIMER $(CFLAGS) tune.c timer.o $(LIBNAME) -o tune86l
+        
+# spits out mersenne primes
+mersenne: mersenne.o
+	$(CC) mersenne.o $(LIBNAME) -o mersenne
+
+# fines DR safe primes for the given config
+drprime: drprime.o
+	$(CC) drprime.o $(LIBNAME) -o drprime
+	
+# fines 2k safe primes for the given config
+2kprime: 2kprime.o
+	$(CC) 2kprime.o $(LIBNAME) -o 2kprime
+
+mont: mont.o
+	$(CC) mont.o $(LIBNAME) -o mont
+
+        
+clean:
+	rm -f *.log *.o *.obj *.exe pprime tune mersenne drprime tune86 tune86l mont 2kprime pprime.dat \
+         *.da *.dyn *.dpi *~
diff --git a/libtommath/etc/makefile.icc b/libtommath/etc/makefile.icc
new file mode 100644
index 0000000..8a1ffff
--- /dev/null
+++ b/libtommath/etc/makefile.icc
@@ -0,0 +1,67 @@
+CC = icc
+
+CFLAGS += -I../
+
+# optimize for SPEED
+#
+# -mcpu= can be pentium, pentiumpro (covers PII through PIII) or pentium4
+# -ax?   specifies make code specifically for ? but compatible with IA-32
+# -x?    specifies compile solely for ? [not specifically IA-32 compatible]
+#
+# where ? is 
+#   K - PIII
+#   W - first P4 [Williamette]
+#   N - P4 Northwood
+#   P - P4 Prescott
+#   B - Blend of P4 and PM [mobile]
+#
+# Default to just generic max opts
+CFLAGS += -O3 -xP -ip
+
+# default lib name (requires install with root)
+# LIBNAME=-ltommath
+
+# libname when you can't install the lib with install
+LIBNAME=../libtommath.a
+
+#provable primes
+pprime: pprime.o
+	$(CC) pprime.o $(LIBNAME) -o pprime
+
+# portable [well requires clock()] tuning app
+tune: tune.o
+	$(CC) tune.o $(LIBNAME) -o tune
+	
+# same app but using RDTSC for higher precision [requires 80586+], coff based gcc installs [e.g. ming, cygwin, djgpp]
+tune86: tune.c
+	nasm -f coff timer.asm
+	$(CC) -DX86_TIMER $(CFLAGS) tune.c timer.o  $(LIBNAME) -o tune86
+	
+# for cygwin
+tune86c: tune.c
+	nasm -f gnuwin32 timer.asm
+	$(CC) -DX86_TIMER $(CFLAGS) tune.c timer.o  $(LIBNAME) -o tune86
+
+#make tune86 for linux or any ELF format
+tune86l: tune.c
+	nasm -f elf -DUSE_ELF timer.asm
+	$(CC) -DX86_TIMER $(CFLAGS) tune.c timer.o $(LIBNAME) -o tune86l
+        
+# spits out mersenne primes
+mersenne: mersenne.o
+	$(CC) mersenne.o $(LIBNAME) -o mersenne
+
+# fines DR safe primes for the given config
+drprime: drprime.o
+	$(CC) drprime.o $(LIBNAME) -o drprime
+	
+# fines 2k safe primes for the given config
+2kprime: 2kprime.o
+	$(CC) 2kprime.o $(LIBNAME) -o 2kprime
+
+mont: mont.o
+	$(CC) mont.o $(LIBNAME) -o mont
+
+        
+clean:
+	rm -f *.log *.o *.obj *.exe pprime tune mersenne drprime tune86 tune86l mont 2kprime pprime.dat *.il
diff --git a/libtommath/etc/makefile.msvc b/libtommath/etc/makefile.msvc
new file mode 100644
index 0000000..2833372
--- /dev/null
+++ b/libtommath/etc/makefile.msvc
@@ -0,0 +1,23 @@
+#MSVC Makefile
+#
+#Tom St Denis
+
+CFLAGS = /I../ /Ox /DWIN32 /W3
+
+pprime: pprime.obj
+	cl pprime.obj ../tommath.lib 
+
+mersenne: mersenne.obj
+	cl mersenne.obj ../tommath.lib
+	
+tune: tune.obj
+	cl tune.obj ../tommath.lib
+
+mont: mont.obj
+	cl mont.obj ../tommath.lib
+	
+drprime: drprime.obj
+	cl drprime.obj ../tommath.lib
+
+2kprime: 2kprime.obj
+	cl 2kprime.obj ../tommath.lib
diff --git a/libtommath/etc/mersenne.c b/libtommath/etc/mersenne.c
new file mode 100644
index 0000000..28ac834
--- /dev/null
+++ b/libtommath/etc/mersenne.c
@@ -0,0 +1,140 @@
+/* Finds Mersenne primes using the Lucas-Lehmer test 
+ *
+ * Tom St Denis, tomstdenis@gmail.com
+ */
+#include <time.h>
+#include <tommath.h>
+
+int
+is_mersenne (long s, int *pp)
+{
+  mp_int  n, u;
+  int     res, k;
+  
+  *pp = 0;
+
+  if ((res = mp_init (&n)) != MP_OKAY) {
+    return res;
+  }
+
+  if ((res = mp_init (&u)) != MP_OKAY) {
+    goto LBL_N;
+  }
+
+  /* n = 2^s - 1 */
+  if ((res = mp_2expt(&n, s)) != MP_OKAY) {
+     goto LBL_MU;
+  }
+  if ((res = mp_sub_d (&n, 1, &n)) != MP_OKAY) {
+    goto LBL_MU;
+  }
+
+  /* set u=4 */
+  mp_set (&u, 4);
+
+  /* for k=1 to s-2 do */
+  for (k = 1; k <= s - 2; k++) {
+    /* u = u^2 - 2 mod n */
+    if ((res = mp_sqr (&u, &u)) != MP_OKAY) {
+      goto LBL_MU;
+    }
+    if ((res = mp_sub_d (&u, 2, &u)) != MP_OKAY) {
+      goto LBL_MU;
+    }
+
+    /* make sure u is positive */
+    while (u.sign == MP_NEG) {
+      if ((res = mp_add (&u, &n, &u)) != MP_OKAY) {
+         goto LBL_MU;
+      }
+    }
+
+    /* reduce */
+    if ((res = mp_reduce_2k (&u, &n, 1)) != MP_OKAY) {
+      goto LBL_MU;
+    }
+  }
+
+  /* if u == 0 then its prime */
+  if (mp_iszero (&u) == 1) {
+    mp_prime_is_prime(&n, 8, pp);
+  if (*pp != 1) printf("FAILURE\n");
+  }
+
+  res = MP_OKAY;
+LBL_MU:mp_clear (&u);
+LBL_N:mp_clear (&n);
+  return res;
+}
+
+/* square root of a long < 65536 */
+long
+i_sqrt (long x)
+{
+  long    x1, x2;
+
+  x2 = 16;
+  do {
+    x1 = x2;
+    x2 = x1 - ((x1 * x1) - x) / (2 * x1);
+  } while (x1 != x2);
+
+  if (x1 * x1 > x) {
+    --x1;
+  }
+
+  return x1;
+}
+
+/* is the long prime by brute force */
+int
+isprime (long k)
+{
+  long    y, z;
+
+  y = i_sqrt (k);
+  for (z = 2; z <= y; z++) {
+    if ((k % z) == 0)
+      return 0;
+  }
+  return 1;
+}
+
+
+int
+main (void)
+{
+  int     pp;
+  long    k;
+  clock_t tt;
+
+  k = 3;
+
+  for (;;) {
+    /* start time */
+    tt = clock ();
+
+    /* test if 2^k - 1 is prime */
+    if (is_mersenne (k, &pp) != MP_OKAY) {
+      printf ("Whoa error\n");
+      return -1;
+    }
+
+    if (pp == 1) {
+      /* count time */
+      tt = clock () - tt;
+
+      /* display if prime */
+      printf ("2^%-5ld - 1 is prime, test took %ld ticks\n", k, tt);
+    }
+
+    /* goto next odd exponent */
+    k += 2;
+
+    /* but make sure its prime */
+    while (isprime (k) == 0) {
+      k += 2;
+    }
+  }
+  return 0;
+}
diff --git a/libtommath/etc/mont.c b/libtommath/etc/mont.c
new file mode 100644
index 0000000..7839675
--- /dev/null
+++ b/libtommath/etc/mont.c
@@ -0,0 +1,41 @@
+/* tests the montgomery routines */
+#include <tommath.h>
+
+int main(void)
+{
+   mp_int modulus, R, p, pp;
+   mp_digit mp;
+   long x, y;
+
+   srand(time(NULL));
+   mp_init_multi(&modulus, &R, &p, &pp, NULL);
+
+   /* loop through various sizes */
+   for (x = 4; x < 256; x++) {
+       printf("DIGITS == %3ld...", x); fflush(stdout);
+       
+       /* make up the odd modulus */
+       mp_rand(&modulus, x);
+       modulus.dp[0] |= 1;
+       
+       /* now find the R value */
+       mp_montgomery_calc_normalization(&R, &modulus);
+       mp_montgomery_setup(&modulus, &mp);
+       
+       /* now run through a bunch tests */
+       for (y = 0; y < 1000; y++) {
+           mp_rand(&p, x/2);        /* p = random */
+           mp_mul(&p, &R, &pp);     /* pp = R * p */
+           mp_montgomery_reduce(&pp, &modulus, mp);
+           
+           /* should be equal to p */
+           if (mp_cmp(&pp, &p) != MP_EQ) {
+              printf("FAILURE!\n");
+              exit(-1);
+           }
+       }
+       printf("PASSED\n");
+    }
+    
+    return 0;
+}
diff --git a/libtommath/etc/pprime.c b/libtommath/etc/pprime.c
new file mode 100644
index 0000000..955f19e
--- /dev/null
+++ b/libtommath/etc/pprime.c
@@ -0,0 +1,396 @@
+/* Generates provable primes
+ *
+ * See http://gmail.com:8080/papers/pp.pdf for more info.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://tom.gmail.com
+ */
+#include <time.h>
+#include "tommath.h"
+
+int   n_prime;
+FILE *primes;
+
+/* fast square root */
+static  mp_digit
+i_sqrt (mp_word x)
+{
+  mp_word x1, x2;
+
+  x2 = x;
+  do {
+    x1 = x2;
+    x2 = x1 - ((x1 * x1) - x) / (2 * x1);
+  } while (x1 != x2);
+
+  if (x1 * x1 > x) {
+    --x1;
+  }
+
+  return x1;
+}
+
+
+/* generates a prime digit */
+static void gen_prime (void)
+{
+  mp_digit r, x, y, next;
+  FILE *out;
+
+  out = fopen("pprime.dat", "wb");
+
+  /* write first set of primes */
+  r = 3; fwrite(&r, 1, sizeof(mp_digit), out);
+  r = 5; fwrite(&r, 1, sizeof(mp_digit), out);
+  r = 7; fwrite(&r, 1, sizeof(mp_digit), out);
+  r = 11; fwrite(&r, 1, sizeof(mp_digit), out);
+  r = 13; fwrite(&r, 1, sizeof(mp_digit), out);
+  r = 17; fwrite(&r, 1, sizeof(mp_digit), out);
+  r = 19; fwrite(&r, 1, sizeof(mp_digit), out);
+  r = 23; fwrite(&r, 1, sizeof(mp_digit), out);
+  r = 29; fwrite(&r, 1, sizeof(mp_digit), out);
+  r = 31; fwrite(&r, 1, sizeof(mp_digit), out);
+
+  /* get square root, since if 'r' is composite its factors must be < than this */
+  y = i_sqrt (r);
+  next = (y + 1) * (y + 1);
+
+  for (;;) {
+  do {
+    r += 2;			/* next candidate */
+    r &= MP_MASK;
+    if (r < 31) break;
+
+    /* update sqrt ? */
+    if (next <= r) {
+      ++y;
+      next = (y + 1) * (y + 1);
+    }
+
+    /* loop if divisible by 3,5,7,11,13,17,19,23,29  */
+    if ((r % 3) == 0) {
+      x = 0;
+      continue;
+    }
+    if ((r % 5) == 0) {
+      x = 0;
+      continue;
+    }
+    if ((r % 7) == 0) {
+      x = 0;
+      continue;
+    }
+    if ((r % 11) == 0) {
+      x = 0;
+      continue;
+    }
+    if ((r % 13) == 0) {
+      x = 0;
+      continue;
+    }
+    if ((r % 17) == 0) {
+      x = 0;
+      continue;
+    }
+    if ((r % 19) == 0) {
+      x = 0;
+      continue;
+    }
+    if ((r % 23) == 0) {
+      x = 0;
+      continue;
+    }
+    if ((r % 29) == 0) {
+      x = 0;
+      continue;
+    }
+
+    /* now check if r is divisible by x + k={1,7,11,13,17,19,23,29} */
+    for (x = 30; x <= y; x += 30) {
+      if ((r % (x + 1)) == 0) {
+	x = 0;
+	break;
+      }
+      if ((r % (x + 7)) == 0) {
+	x = 0;
+	break;
+      }
+      if ((r % (x + 11)) == 0) {
+	x = 0;
+	break;
+      }
+      if ((r % (x + 13)) == 0) {
+	x = 0;
+	break;
+      }
+      if ((r % (x + 17)) == 0) {
+	x = 0;
+	break;
+      }
+      if ((r % (x + 19)) == 0) {
+	x = 0;
+	break;
+      }
+      if ((r % (x + 23)) == 0) {
+	x = 0;
+	break;
+      }
+      if ((r % (x + 29)) == 0) {
+	x = 0;
+	break;
+      }
+    }
+  } while (x == 0);
+  if (r > 31) { fwrite(&r, 1, sizeof(mp_digit), out); printf("%9d\r", r); fflush(stdout); }
+  if (r < 31) break;
+  }
+
+  fclose(out);
+}
+
+void load_tab(void)
+{
+   primes = fopen("pprime.dat", "rb");
+   if (primes == NULL) {
+      gen_prime();
+      primes = fopen("pprime.dat", "rb");
+   }
+   fseek(primes, 0, SEEK_END);
+   n_prime = ftell(primes) / sizeof(mp_digit);
+}
+
+mp_digit prime_digit(void)
+{
+   int n;
+   mp_digit d;
+
+   n = abs(rand()) % n_prime;
+   fseek(primes, n * sizeof(mp_digit), SEEK_SET);
+   fread(&d, 1, sizeof(mp_digit), primes);
+   return d;
+}
+
+
+/* makes a prime of at least k bits */
+int
+pprime (int k, int li, mp_int * p, mp_int * q)
+{
+  mp_int  a, b, c, n, x, y, z, v;
+  int     res, ii;
+  static const mp_digit bases[] = { 2, 3, 5, 7, 11, 13, 17, 19 };
+
+  /* single digit ? */
+  if (k <= (int) DIGIT_BIT) {
+    mp_set (p, prime_digit ());
+    return MP_OKAY;
+  }
+
+  if ((res = mp_init (&c)) != MP_OKAY) {
+    return res;
+  }
+
+  if ((res = mp_init (&v)) != MP_OKAY) {
+    goto LBL_C;
+  }
+
+  /* product of first 50 primes */
+  if ((res =
+       mp_read_radix (&v,
+		      "19078266889580195013601891820992757757219839668357012055907516904309700014933909014729740190",
+		      10)) != MP_OKAY) {
+    goto LBL_V;
+  }
+
+  if ((res = mp_init (&a)) != MP_OKAY) {
+    goto LBL_V;
+  }
+
+  /* set the prime */
+  mp_set (&a, prime_digit ());
+
+  if ((res = mp_init (&b)) != MP_OKAY) {
+    goto LBL_A;
+  }
+
+  if ((res = mp_init (&n)) != MP_OKAY) {
+    goto LBL_B;
+  }
+
+  if ((res = mp_init (&x)) != MP_OKAY) {
+    goto LBL_N;
+  }
+
+  if ((res = mp_init (&y)) != MP_OKAY) {
+    goto LBL_X;
+  }
+
+  if ((res = mp_init (&z)) != MP_OKAY) {
+    goto LBL_Y;
+  }
+
+  /* now loop making the single digit */
+  while (mp_count_bits (&a) < k) {
+    fprintf (stderr, "prime has %4d bits left\r", k - mp_count_bits (&a));
+    fflush (stderr);
+  top:
+    mp_set (&b, prime_digit ());
+
+    /* now compute z = a * b * 2 */
+    if ((res = mp_mul (&a, &b, &z)) != MP_OKAY) {	/* z = a * b */
+      goto LBL_Z;
+    }
+
+    if ((res = mp_copy (&z, &c)) != MP_OKAY) {	/* c = a * b */
+      goto LBL_Z;
+    }
+
+    if ((res = mp_mul_2 (&z, &z)) != MP_OKAY) {	/* z = 2 * a * b */
+      goto LBL_Z;
+    }
+
+    /* n = z + 1 */
+    if ((res = mp_add_d (&z, 1, &n)) != MP_OKAY) {	/* n = z + 1 */
+      goto LBL_Z;
+    }
+
+    /* check (n, v) == 1 */
+    if ((res = mp_gcd (&n, &v, &y)) != MP_OKAY) {	/* y = (n, v) */
+      goto LBL_Z;
+    }
+
+    if (mp_cmp_d (&y, 1) != MP_EQ)
+      goto top;
+
+    /* now try base x=bases[ii]  */
+    for (ii = 0; ii < li; ii++) {
+      mp_set (&x, bases[ii]);
+
+      /* compute x^a mod n */
+      if ((res = mp_exptmod (&x, &a, &n, &y)) != MP_OKAY) {	/* y = x^a mod n */
+	goto LBL_Z;
+      }
+
+      /* if y == 1 loop */
+      if (mp_cmp_d (&y, 1) == MP_EQ)
+	continue;
+
+      /* now x^2a mod n */
+      if ((res = mp_sqrmod (&y, &n, &y)) != MP_OKAY) {	/* y = x^2a mod n */
+	goto LBL_Z;
+      }
+
+      if (mp_cmp_d (&y, 1) == MP_EQ)
+	continue;
+
+      /* compute x^b mod n */
+      if ((res = mp_exptmod (&x, &b, &n, &y)) != MP_OKAY) {	/* y = x^b mod n */
+	goto LBL_Z;
+      }
+
+      /* if y == 1 loop */
+      if (mp_cmp_d (&y, 1) == MP_EQ)
+	continue;
+
+      /* now x^2b mod n */
+      if ((res = mp_sqrmod (&y, &n, &y)) != MP_OKAY) {	/* y = x^2b mod n */
+	goto LBL_Z;
+      }
+
+      if (mp_cmp_d (&y, 1) == MP_EQ)
+	continue;
+
+      /* compute x^c mod n == x^ab mod n */
+      if ((res = mp_exptmod (&x, &c, &n, &y)) != MP_OKAY) {	/* y = x^ab mod n */
+	goto LBL_Z;
+      }
+
+      /* if y == 1 loop */
+      if (mp_cmp_d (&y, 1) == MP_EQ)
+	continue;
+
+      /* now compute (x^c mod n)^2 */
+      if ((res = mp_sqrmod (&y, &n, &y)) != MP_OKAY) {	/* y = x^2ab mod n */
+	goto LBL_Z;
+      }
+
+      /* y should be 1 */
+      if (mp_cmp_d (&y, 1) != MP_EQ)
+	continue;
+      break;
+    }
+
+    /* no bases worked? */
+    if (ii == li)
+      goto top;
+
+{
+   char buf[4096];
+
+   mp_toradix(&n, buf, 10);
+   printf("Certificate of primality for:\n%s\n\n", buf);
+   mp_toradix(&a, buf, 10);
+   printf("A == \n%s\n\n", buf);
+   mp_toradix(&b, buf, 10);
+   printf("B == \n%s\n\nG == %d\n", buf, bases[ii]);
+   printf("----------------------------------------------------------------\n");
+}
+
+    /* a = n */
+    mp_copy (&n, &a);
+  }
+
+  /* get q to be the order of the large prime subgroup */
+  mp_sub_d (&n, 1, q);
+  mp_div_2 (q, q);
+  mp_div (q, &b, q, NULL);
+
+  mp_exch (&n, p);
+
+  res = MP_OKAY;
+LBL_Z:mp_clear (&z);
+LBL_Y:mp_clear (&y);
+LBL_X:mp_clear (&x);
+LBL_N:mp_clear (&n);
+LBL_B:mp_clear (&b);
+LBL_A:mp_clear (&a);
+LBL_V:mp_clear (&v);
+LBL_C:mp_clear (&c);
+  return res;
+}
+
+
+int
+main (void)
+{
+  mp_int  p, q;
+  char    buf[4096];
+  int     k, li;
+  clock_t t1;
+
+  srand (time (NULL));
+  load_tab();
+
+  printf ("Enter # of bits: \n");
+  fgets (buf, sizeof (buf), stdin);
+  sscanf (buf, "%d", &k);
+
+  printf ("Enter number of bases to try (1 to 8):\n");
+  fgets (buf, sizeof (buf), stdin);
+  sscanf (buf, "%d", &li);
+
+
+  mp_init (&p);
+  mp_init (&q);
+
+  t1 = clock ();
+  pprime (k, li, &p, &q);
+  t1 = clock () - t1;
+
+  printf ("\n\nTook %ld ticks, %d bits\n", t1, mp_count_bits (&p));
+
+  mp_toradix (&p, buf, 10);
+  printf ("P == %s\n", buf);
+  mp_toradix (&q, buf, 10);
+  printf ("Q == %s\n", buf);
+
+  return 0;
+}
diff --git a/libtommath/etc/prime.1024 b/libtommath/etc/prime.1024
new file mode 100644
index 0000000..5636e2d
--- /dev/null
+++ b/libtommath/etc/prime.1024
@@ -0,0 +1,414 @@
+Enter # of bits: 
+Enter number of bases to try (1 to 8):
+Certificate of primality for:
+36360080703173363
+
+A == 
+89963569
+
+B == 
+202082249
+
+G == 2
+----------------------------------------------------------------
+Certificate of primality for:
+4851595597739856136987139
+
+A == 
+36360080703173363
+
+B == 
+66715963
+
+G == 2
+----------------------------------------------------------------
+Certificate of primality for:
+19550639734462621430325731591027
+
+A == 
+4851595597739856136987139
+
+B == 
+2014867
+
+G == 2
+----------------------------------------------------------------
+Certificate of primality for:
+10409036141344317165691858509923818734539
+
+A == 
+19550639734462621430325731591027
+
+B == 
+266207047
+
+G == 2
+----------------------------------------------------------------
+Certificate of primality for:
+1049829549988285012736475602118094726647504414203
+
+A == 
+10409036141344317165691858509923818734539
+
+B == 
+50428759
+
+G == 2
+----------------------------------------------------------------
+Certificate of primality for:
+77194737385528288387712399596835459931920358844586615003
+
+A == 
+1049829549988285012736475602118094726647504414203
+
+B == 
+36765367
+
+G == 2
+----------------------------------------------------------------
+Certificate of primality for:
+35663756695365208574443215955488689578374232732893628896541201763
+
+A == 
+77194737385528288387712399596835459931920358844586615003
+
+B == 
+230998627
+
+G == 2
+----------------------------------------------------------------
+Certificate of primality for:
+16711831463502165169495622246023119698415848120292671294127567620396469803
+
+A == 
+35663756695365208574443215955488689578374232732893628896541201763
+
+B == 
+234297127
+
+G == 2
+----------------------------------------------------------------
+Certificate of primality for:
+6163534781560285962890718925972249753147470953579266394395432475622345597103528739
+
+A == 
+16711831463502165169495622246023119698415848120292671294127567620396469803
+
+B == 
+184406323
+
+G == 2
+----------------------------------------------------------------
+Certificate of primality for:
+814258256205243497704094951432575867360065658372158511036259934640748088306764553488803787
+
+A == 
+6163534781560285962890718925972249753147470953579266394395432475622345597103528739
+
+B == 
+66054487
+
+G == 2
+----------------------------------------------------------------
+Certificate of primality for:
+176469695533271657902814176811660357049007467856432383037590673407330246967781451723764079581998187
+
+A == 
+814258256205243497704094951432575867360065658372158511036259934640748088306764553488803787
+
+B == 
+108362239
+
+G == 2
+----------------------------------------------------------------
+Certificate of primality for:
+44924492859445516541759485198544012102424796403707253610035148063863073596051272171194806669756971406400419
+
+A == 
+176469695533271657902814176811660357049007467856432383037590673407330246967781451723764079581998187
+
+B == 
+127286707
+
+G == 2
+----------------------------------------------------------------
+Certificate of primality for:
+20600996927219343383225424320134474929609459588323857796871086845924186191561749519858600696159932468024710985371059
+
+A == 
+44924492859445516541759485198544012102424796403707253610035148063863073596051272171194806669756971406400419
+
+B == 
+229284691
+
+G == 2
+----------------------------------------------------------------
+Certificate of primality for:
+6295696427695493110141186605837397185848992307978456138112526915330347715236378041486547994708748840844217371233735072572979
+
+A == 
+20600996927219343383225424320134474929609459588323857796871086845924186191561749519858600696159932468024710985371059
+
+B == 
+152800771
+
+G == 2
+----------------------------------------------------------------
+Certificate of primality for:
+3104984078042317488749073016454213579257792635142218294052134804187631661145261015102617582090263808696699966840735333252107678792123
+
+A == 
+6295696427695493110141186605837397185848992307978456138112526915330347715236378041486547994708748840844217371233735072572979
+
+B == 
+246595759
+
+G == 2
+----------------------------------------------------------------
+Certificate of primality for:
+26405175827665701256325699315126705508919255051121452292124404943796947287968603975320562847910946802396632302209435206627913466015741799499
+
+A == 
+3104984078042317488749073016454213579257792635142218294052134804187631661145261015102617582090263808696699966840735333252107678792123
+
+B == 
+4252063
+
+G == 2
+----------------------------------------------------------------
+Certificate of primality for:
+11122146237908413610034600609460545703591095894418599759742741406628055069007082998134905595800236452010905900391505454890446585211975124558601770163
+
+A == 
+26405175827665701256325699315126705508919255051121452292124404943796947287968603975320562847910946802396632302209435206627913466015741799499
+
+B == 
+210605419
+
+G == 2
+----------------------------------------------------------------
+Certificate of primality for:
+1649861642047798890580354082088712649911849362201343649289384923147797960364736011515757482030049342943790127685185806092659832129486307035500638595572396187
+
+A == 
+11122146237908413610034600609460545703591095894418599759742741406628055069007082998134905595800236452010905900391505454890446585211975124558601770163
+
+B == 
+74170111
+
+G == 2
+----------------------------------------------------------------
+Certificate of primality for:
+857983367126266717607389719637086684134462613006415859877666235955788392464081914127715967940968197765042399904117392707518175220864852816390004264107201177394565363
+
+A == 
+1649861642047798890580354082088712649911849362201343649289384923147797960364736011515757482030049342943790127685185806092659832129486307035500638595572396187
+
+B == 
+260016763
+
+G == 2
+----------------------------------------------------------------
+Certificate of primality for:
+175995909353623703257072120479340610010337144085688850745292031336724691277374210929188442230237711063783727092685448718515661641054886101716698390145283196296702450566161283
+
+A == 
+857983367126266717607389719637086684134462613006415859877666235955788392464081914127715967940968197765042399904117392707518175220864852816390004264107201177394565363
+
+B == 
+102563707
+
+G == 2
+----------------------------------------------------------------
+Certificate of primality for:
+48486002551155667224487059713350447239190772068092630563272168418880661006593537218144160068395218642353495339720640699721703003648144463556291315694787862009052641640656933232794283
+
+A == 
+175995909353623703257072120479340610010337144085688850745292031336724691277374210929188442230237711063783727092685448718515661641054886101716698390145283196296702450566161283
+
+B == 
+137747527
+
+G == 2
+----------------------------------------------------------------
+Certificate of primality for:
+13156468011529105025061495011938518171328604045212410096476697450506055664012861932372156505805788068791146986282263016790631108386790291275939575123375304599622623328517354163964228279867403
+
+A == 
+48486002551155667224487059713350447239190772068092630563272168418880661006593537218144160068395218642353495339720640699721703003648144463556291315694787862009052641640656933232794283
+
+B == 
+135672847
+
+G == 2
+----------------------------------------------------------------
+Certificate of primality for:
+6355194692790533601105154341731997464407930009404822926832136060319955058388106456084549316415200519472481147942263916585428906582726749131479465958107142228236909665306781538860053107680830113869123
+
+A == 
+13156468011529105025061495011938518171328604045212410096476697450506055664012861932372156505805788068791146986282263016790631108386790291275939575123375304599622623328517354163964228279867403
+
+B == 
+241523587
+
+G == 2
+----------------------------------------------------------------
+Certificate of primality for:
+3157116676535430302794438027544146642863331358530722860333745617571010460905857862561870488000265751138954271040017454405707755458702044884023184574412221802502351503929935224995314581932097706874819348858083
+
+A == 
+6355194692790533601105154341731997464407930009404822926832136060319955058388106456084549316415200519472481147942263916585428906582726749131479465958107142228236909665306781538860053107680830113869123
+
+B == 
+248388667
+
+G == 2
+----------------------------------------------------------------
+Certificate of primality for:
+390533129219992506725320633489467713907837370444962163378727819939092929448752905310115311180032249230394348337568973177802874166228132778126338883671958897238722734394783244237133367055422297736215754829839364158067
+
+A == 
+3157116676535430302794438027544146642863331358530722860333745617571010460905857862561870488000265751138954271040017454405707755458702044884023184574412221802502351503929935224995314581932097706874819348858083
+
+B == 
+61849651
+
+G == 2
+----------------------------------------------------------------
+Certificate of primality for:
+48583654555070224891047847050732516652910250240135992225139515777200432486685999462997073444468380434359929499498804723793106565291183220444221080449740542884172281158126259373095216435009661050109711341419005972852770440739
+
+A == 
+390533129219992506725320633489467713907837370444962163378727819939092929448752905310115311180032249230394348337568973177802874166228132778126338883671958897238722734394783244237133367055422297736215754829839364158067
+
+B == 
+62201707
+
+G == 2
+----------------------------------------------------------------
+Certificate of primality for:
+25733035251905120039135866524384525138869748427727001128764704499071378939227862068500633813538831598776578372709963673670934388213622433800015759585470542686333039614931682098922935087822950084908715298627996115185849260703525317419
+
+A == 
+48583654555070224891047847050732516652910250240135992225139515777200432486685999462997073444468380434359929499498804723793106565291183220444221080449740542884172281158126259373095216435009661050109711341419005972852770440739
+
+B == 
+264832231
+
+G == 2
+----------------------------------------------------------------
+Certificate of primality for:
+2804594464939948901906623499531073917980499195397462605359913717827014360538186518540781517129548650937632008683280555602633122170458773895504894807182664540529077836857897972175530148107545939211339044386106111633510166695386323426241809387
+
+A == 
+25733035251905120039135866524384525138869748427727001128764704499071378939227862068500633813538831598776578372709963673670934388213622433800015759585470542686333039614931682098922935087822950084908715298627996115185849260703525317419
+
+B == 
+54494047
+
+G == 2
+----------------------------------------------------------------
+Certificate of primality for:
+738136612083433720096707308165797114449914259256979340471077690416567237592465306112484843530074782721390528773594351482384711900456440808251196845265132086486672447136822046628407467459921823150600138073268385534588238548865012638209515923513516547
+
+A == 
+2804594464939948901906623499531073917980499195397462605359913717827014360538186518540781517129548650937632008683280555602633122170458773895504894807182664540529077836857897972175530148107545939211339044386106111633510166695386323426241809387
+
+B == 
+131594179
+
+G == 2
+----------------------------------------------------------------
+Certificate of primality for:
+392847529056126766528615419937165193421166694172790666626558750047057558168124866940509180171236517681470100877687445134633784815352076138790217228749332398026714192707447855731679485746120589851992221508292976900578299504461333767437280988393026452846013683
+
+A == 
+738136612083433720096707308165797114449914259256979340471077690416567237592465306112484843530074782721390528773594351482384711900456440808251196845265132086486672447136822046628407467459921823150600138073268385534588238548865012638209515923513516547
+
+B == 
+266107603
+
+G == 2
+----------------------------------------------------------------
+Certificate of primality for:
+168459393231883505975876919268398655632763956627405508859662408056221544310200546265681845397346956580604208064328814319465940958080244889692368602591598503944015835190587740756859842792554282496742843600573336023639256008687581291233481455395123454655488735304365627
+
+A == 
+392847529056126766528615419937165193421166694172790666626558750047057558168124866940509180171236517681470100877687445134633784815352076138790217228749332398026714192707447855731679485746120589851992221508292976900578299504461333767437280988393026452846013683
+
+B == 
+214408111
+
+G == 2
+----------------------------------------------------------------
+Certificate of primality for:
+14865774288636941404884923981945833072113667565310054952177860608355263252462409554658728941191929400198053290113492910272458441655458514080123870132092365833472436407455910185221474386718838138135065780840839893113912689594815485706154461164071775481134379794909690501684643
+
+A == 
+168459393231883505975876919268398655632763956627405508859662408056221544310200546265681845397346956580604208064328814319465940958080244889692368602591598503944015835190587740756859842792554282496742843600573336023639256008687581291233481455395123454655488735304365627
+
+B == 
+44122723
+
+G == 2
+----------------------------------------------------------------
+Certificate of primality for:
+1213301773203241614897109856134894783021668292000023984098824423682568173639394290886185366993108292039068940333907505157813934962357206131450244004178619265868614859794316361031904412926604138893775068853175215502104744339658944443630407632290152772487455298652998368296998719996019
+
+A == 
+14865774288636941404884923981945833072113667565310054952177860608355263252462409554658728941191929400198053290113492910272458441655458514080123870132092365833472436407455910185221474386718838138135065780840839893113912689594815485706154461164071775481134379794909690501684643
+
+B == 
+40808563
+
+G == 2
+----------------------------------------------------------------
+Certificate of primality for:
+186935245989515158127969129347464851990429060640910951266513740972248428651109062997368144722015290092846666943896556191257222521203647606911446635194198213436423080005867489516421559330500722264446765608763224572386410155413161172707802334865729654109050873820610813855041667633843601286843
+
+A == 
+1213301773203241614897109856134894783021668292000023984098824423682568173639394290886185366993108292039068940333907505157813934962357206131450244004178619265868614859794316361031904412926604138893775068853175215502104744339658944443630407632290152772487455298652998368296998719996019
+
+B == 
+77035759
+
+G == 2
+----------------------------------------------------------------
+Certificate of primality for:
+83142661079751490510739960019112406284111408348732592580459037404394946037094409915127399165633756159385609671956087845517678367844901424617866988187132480585966721962585586730693443536100138246516868613250009028187662080828012497191775172228832247706080044971423654632146928165751885302331924491683
+
+A == 
+186935245989515158127969129347464851990429060640910951266513740972248428651109062997368144722015290092846666943896556191257222521203647606911446635194198213436423080005867489516421559330500722264446765608763224572386410155413161172707802334865729654109050873820610813855041667633843601286843
+
+B == 
+222383587
+
+G == 2
+----------------------------------------------------------------
+Certificate of primality for:
+3892354773803809855317742245039794448230625839512638747643814927766738642436392673485997449586432241626440927010641564064764336402368634186618250134234189066179771240232458249806850838490410473462391401438160528157981942499581634732706904411807195259620779379274017704050790865030808501633772117217899534443
+
+A == 
+83142661079751490510739960019112406284111408348732592580459037404394946037094409915127399165633756159385609671956087845517678367844901424617866988187132480585966721962585586730693443536100138246516868613250009028187662080828012497191775172228832247706080044971423654632146928165751885302331924491683
+
+B == 
+23407687
+
+G == 2
+----------------------------------------------------------------
+Certificate of primality for:
+1663606652988091811284014366560171522582683318514519379924950390627250155440313691226744227787921928894551755219495501365555370027257568506349958010457682898612082048959464465369892842603765280317696116552850664773291371490339084156052244256635115997453399761029567033971998617303988376172539172702246575225837054723
+
+A == 
+3892354773803809855317742245039794448230625839512638747643814927766738642436392673485997449586432241626440927010641564064764336402368634186618250134234189066179771240232458249806850838490410473462391401438160528157981942499581634732706904411807195259620779379274017704050790865030808501633772117217899534443
+
+B == 
+213701827
+
+G == 2
+----------------------------------------------------------------
+
+
+Took 33057 ticks, 1048 bits
+P == 1663606652988091811284014366560171522582683318514519379924950390627250155440313691226744227787921928894551755219495501365555370027257568506349958010457682898612082048959464465369892842603765280317696116552850664773291371490339084156052244256635115997453399761029567033971998617303988376172539172702246575225837054723
+Q == 3892354773803809855317742245039794448230625839512638747643814927766738642436392673485997449586432241626440927010641564064764336402368634186618250134234189066179771240232458249806850838490410473462391401438160528157981942499581634732706904411807195259620779379274017704050790865030808501633772117217899534443
diff --git a/libtommath/etc/prime.512 b/libtommath/etc/prime.512
new file mode 100644
index 0000000..cb6ec30
--- /dev/null
+++ b/libtommath/etc/prime.512
@@ -0,0 +1,205 @@
+Enter # of bits: 
+Enter number of bases to try (1 to 8):
+Certificate of primality for:
+85933926807634727
+
+A == 
+253758023
+
+B == 
+169322581
+
+G == 5
+----------------------------------------------------------------
+Certificate of primality for:
+23930198825086241462113799
+
+A == 
+85933926807634727
+
+B == 
+139236037
+
+G == 11
+----------------------------------------------------------------
+Certificate of primality for:
+6401844647261612602378676572510019
+
+A == 
+23930198825086241462113799
+
+B == 
+133760791
+
+G == 2
+----------------------------------------------------------------
+Certificate of primality for:
+269731366027728777712034888684015329354259
+
+A == 
+6401844647261612602378676572510019
+
+B == 
+21066691
+
+G == 2
+----------------------------------------------------------------
+Certificate of primality for:
+37942338209025571690075025099189467992329684223707
+
+A == 
+269731366027728777712034888684015329354259
+
+B == 
+70333567
+
+G == 2
+----------------------------------------------------------------
+Certificate of primality for:
+15306904714258982484473490774101705363308327436988160248323
+
+A == 
+37942338209025571690075025099189467992329684223707
+
+B == 
+201712723
+
+G == 2
+----------------------------------------------------------------
+Certificate of primality for:
+1616744757018513392810355191503853040357155275733333124624513530099
+
+A == 
+15306904714258982484473490774101705363308327436988160248323
+
+B == 
+52810963
+
+G == 2
+----------------------------------------------------------------
+Certificate of primality for:
+464222094814208047161771036072622485188658077940154689939306386289983787983
+
+A == 
+1616744757018513392810355191503853040357155275733333124624513530099
+
+B == 
+143566909
+
+G == 5
+----------------------------------------------------------------
+Certificate of primality for:
+187429931674053784626487560729643601208757374994177258429930699354770049369025096447
+
+A == 
+464222094814208047161771036072622485188658077940154689939306386289983787983
+
+B == 
+201875281
+
+G == 5
+----------------------------------------------------------------
+Certificate of primality for:
+100579220846502621074093727119851331775052664444339632682598589456666938521976625305832917563
+
+A == 
+187429931674053784626487560729643601208757374994177258429930699354770049369025096447
+
+B == 
+268311523
+
+G == 2
+----------------------------------------------------------------
+Certificate of primality for:
+1173616081309758475197022137833792133815753368965945885089720153370737965497134878651384030219765163
+
+A == 
+100579220846502621074093727119851331775052664444339632682598589456666938521976625305832917563
+
+B == 
+5834287
+
+G == 2
+----------------------------------------------------------------
+Certificate of primality for:
+191456913489905913185935197655672585713573070349044195411728114905691721186574907738081340754373032735283623
+
+A == 
+1173616081309758475197022137833792133815753368965945885089720153370737965497134878651384030219765163
+
+B == 
+81567097
+
+G == 5
+----------------------------------------------------------------
+Certificate of primality for:
+57856530489201750164178576399448868489243874083056587683743345599898489554401618943240901541005080049321706789987519
+
+A == 
+191456913489905913185935197655672585713573070349044195411728114905691721186574907738081340754373032735283623
+
+B == 
+151095433
+
+G == 7
+----------------------------------------------------------------
+Certificate of primality for:
+13790529750452576698109671710773784949185621244122040804792403407272729038377767162233653248852099545134831722512085881814803
+
+A == 
+57856530489201750164178576399448868489243874083056587683743345599898489554401618943240901541005080049321706789987519
+
+B == 
+119178679
+
+G == 2
+----------------------------------------------------------------
+Certificate of primality for:
+7075985989000817742677547821106534174334812111605018857703825637170140040509067704269696198231266351631132464035671858077052876058979
+
+A == 
+13790529750452576698109671710773784949185621244122040804792403407272729038377767162233653248852099545134831722512085881814803
+
+B == 
+256552363
+
+G == 2
+----------------------------------------------------------------
+Certificate of primality for:
+1227273006232588072907488910282307435921226646895131225407452056677899411162892829564455154080310937471747140942360789623819327234258162420463
+
+A == 
+7075985989000817742677547821106534174334812111605018857703825637170140040509067704269696198231266351631132464035671858077052876058979
+
+B == 
+86720989
+
+G == 5
+----------------------------------------------------------------
+Certificate of primality for:
+446764896913554613686067036908702877942872355053329937790398156069936255759889884246832779737114032666318220500106499161852193765380831330106375235763
+
+A == 
+1227273006232588072907488910282307435921226646895131225407452056677899411162892829564455154080310937471747140942360789623819327234258162420463
+
+B == 
+182015287
+
+G == 2
+----------------------------------------------------------------
+Certificate of primality for:
+5290203010849586596974953717018896543907195901082056939587768479377028575911127944611236020459652034082251335583308070846379514569838984811187823420951275243
+
+A == 
+446764896913554613686067036908702877942872355053329937790398156069936255759889884246832779737114032666318220500106499161852193765380831330106375235763
+
+B == 
+5920567
+
+G == 2
+----------------------------------------------------------------
+
+
+Took 3454 ticks, 521 bits
+P == 5290203010849586596974953717018896543907195901082056939587768479377028575911127944611236020459652034082251335583308070846379514569838984811187823420951275243
+Q == 446764896913554613686067036908702877942872355053329937790398156069936255759889884246832779737114032666318220500106499161852193765380831330106375235763
diff --git a/libtommath/etc/timer.asm b/libtommath/etc/timer.asm
new file mode 100644
index 0000000..326a947
--- /dev/null
+++ b/libtommath/etc/timer.asm
@@ -0,0 +1,37 @@
+; x86 timer in NASM
+;
+; Tom St Denis, tomstdenis@iahu.ca
+[bits 32]
+[section .data]
+time dd 0, 0
+
+[section .text]
+
+%ifdef USE_ELF
+[global t_start]
+t_start:
+%else
+[global _t_start]
+_t_start:
+%endif
+   push edx
+   push eax
+   rdtsc
+   mov [time+0],edx
+   mov [time+4],eax
+   pop eax
+   pop edx
+   ret
+   
+%ifdef USE_ELF
+[global t_read]
+t_read:
+%else
+[global _t_read]
+_t_read:
+%endif
+   rdtsc
+   sub eax,[time+4]
+   sbb edx,[time+0]
+   ret
+   
\ No newline at end of file
diff --git a/libtommath/etc/tune.c b/libtommath/etc/tune.c
new file mode 100644
index 0000000..acb146f
--- /dev/null
+++ b/libtommath/etc/tune.c
@@ -0,0 +1,138 @@
+/* Tune the Karatsuba parameters
+ *
+ * Tom St Denis, tomstdenis@gmail.com
+ */
+#include <tommath.h>
+#include <time.h>
+
+/* how many times todo each size mult.  Depends on your computer.  For slow computers
+ * this can be low like 5 or 10.  For fast [re: Athlon] should be 25 - 50 or so 
+ */
+#define TIMES (1UL<<14UL)
+
+/* RDTSC from Scott Duplichan */
+static ulong64 TIMFUNC (void)
+   {
+   #if defined __GNUC__
+      #if defined(__i386__) || defined(__x86_64__)
+         unsigned long long a;
+         __asm__ __volatile__ ("rdtsc\nmovl %%eax,%0\nmovl %%edx,4+%0\n"::"m"(a):"%eax","%edx");
+         return a;
+      #else /* gcc-IA64 version */
+         unsigned long result;
+         __asm__ __volatile__("mov %0=ar.itc" : "=r"(result) :: "memory");
+         while (__builtin_expect ((int) result == -1, 0))
+         __asm__ __volatile__("mov %0=ar.itc" : "=r"(result) :: "memory");
+         return result;
+      #endif
+
+   // Microsoft and Intel Windows compilers
+   #elif defined _M_IX86
+     __asm rdtsc
+   #elif defined _M_AMD64
+     return __rdtsc ();
+   #elif defined _M_IA64
+     #if defined __INTEL_COMPILER
+       #include <ia64intrin.h>
+     #endif
+      return __getReg (3116);
+   #else
+     #error need rdtsc function for this build
+   #endif
+   }
+
+
+#ifndef X86_TIMER
+
+/* generic ISO C timer */
+ulong64 LBL_T;
+void t_start(void) { LBL_T = TIMFUNC(); }
+ulong64 t_read(void) { return TIMFUNC() - LBL_T; }
+
+#else
+extern void t_start(void);
+extern ulong64 t_read(void);
+#endif
+
+ulong64 time_mult(int size, int s)
+{
+  unsigned long     x;
+  mp_int  a, b, c;
+  ulong64 t1;
+
+  mp_init (&a);
+  mp_init (&b);
+  mp_init (&c);
+
+  mp_rand (&a, size);
+  mp_rand (&b, size);
+
+  if (s == 1) { 
+      KARATSUBA_MUL_CUTOFF = size;
+  } else {
+      KARATSUBA_MUL_CUTOFF = 100000;
+  }
+
+  t_start();
+  for (x = 0; x < TIMES; x++) {
+      mp_mul(&a,&b,&c);
+  }
+  t1 = t_read();
+  mp_clear (&a);
+  mp_clear (&b);
+  mp_clear (&c);
+  return t1;
+}
+
+ulong64 time_sqr(int size, int s)
+{
+  unsigned long     x;
+  mp_int  a, b;
+  ulong64 t1;
+
+  mp_init (&a);
+  mp_init (&b);
+
+  mp_rand (&a, size);
+
+  if (s == 1) { 
+      KARATSUBA_SQR_CUTOFF = size;
+  } else {
+      KARATSUBA_SQR_CUTOFF = 100000;
+  }
+
+  t_start();
+  for (x = 0; x < TIMES; x++) {
+      mp_sqr(&a,&b);
+  }
+  t1 = t_read();
+  mp_clear (&a);
+  mp_clear (&b);
+  return t1;
+}
+
+int
+main (void)
+{
+  ulong64 t1, t2;
+  int x, y;
+
+  for (x = 8; ; x += 2) { 
+     t1 = time_mult(x, 0);
+     t2 = time_mult(x, 1);
+     printf("%d: %9llu %9llu, %9llu\n", x, t1, t2, t2 - t1);
+     if (t2 < t1) break;
+  }
+  y = x;
+
+  for (x = 8; ; x += 2) { 
+     t1 = time_sqr(x, 0);
+     t2 = time_sqr(x, 1);
+     printf("%d: %9llu %9llu, %9llu\n", x, t1, t2, t2 - t1);
+     if (t2 < t1) break;
+  }
+  printf("KARATSUBA_MUL_CUTOFF = %d\n", y);
+  printf("KARATSUBA_SQR_CUTOFF = %d\n", x);
+
+  return 0;
+}
diff --git a/libtommath/gen.pl b/libtommath/gen.pl
new file mode 100644
index 0000000..7236591
--- /dev/null
+++ b/libtommath/gen.pl
@@ -0,0 +1,17 @@
+#!/usr/bin/perl -w
+#
+# Generates a "single file" you can use to quickly
+# add the whole source without any makefile troubles
+#
+use strict;
+
+open( OUT, ">mpi.c" ) or die "Couldn't open mpi.c for writing: $!";
+foreach my $filename (glob "bn*.c") {
+   open( SRC, "<$filename" ) or die "Couldn't open $filename for reading: $!";
+   print OUT "/* Start: $filename */\n";
+   print OUT while <SRC>;
+   print OUT "\n/* End: $filename */\n\n";
+   close SRC or die "Error closing $filename after reading: $!";
+}
+print OUT "\n/* EOF */\n";
+close OUT or die "Error closing mpi.c after writing: $!";
\ No newline at end of file
diff --git a/libtommath/logs/README b/libtommath/logs/README
new file mode 100644
index 0000000..965e7c8
--- /dev/null
+++ b/libtommath/logs/README
@@ -0,0 +1,13 @@
+To use the pretty graphs you have to first build/run the ltmtest from the root directory of the package.  
+Todo this type 
+
+make timing ; ltmtest
+
+in the root.  It will run for a while [about ten minutes on most PCs] and produce a series of .log files in logs/.
+
+After doing that run "gnuplot graphs.dem" to make the PNGs.  If you managed todo that all so far just open index.html to view
+them all :-)
+
+Have fun
+
+Tom
\ No newline at end of file
diff --git a/libtommath/logs/add.log b/libtommath/logs/add.log
new file mode 100644
index 0000000..43503ac
--- /dev/null
+++ b/libtommath/logs/add.log
@@ -0,0 +1,16 @@
+480        87
+960       111
+1440       135
+1920       159
+2400       200
+2880       224
+3360       248
+3840       272
+4320       296
+4800       320
+5280       344
+5760       368
+6240       392
+6720       416
+7200       440
+7680       464
diff --git a/libtommath/logs/addsub.png b/libtommath/logs/addsub.png
new file mode 100644
index 0000000..441c7b2
Binary files /dev/null and b/libtommath/logs/addsub.png differ
diff --git a/libtommath/logs/expt.log b/libtommath/logs/expt.log
new file mode 100644
index 0000000..70932ab
--- /dev/null
+++ b/libtommath/logs/expt.log
@@ -0,0 +1,7 @@
+513   1435869
+769   3544970
+1025   7791638
+2049  46902238
+2561  85334899
+3073 141451412
+4097 308770310
diff --git a/libtommath/logs/expt.png b/libtommath/logs/expt.png
new file mode 100644
index 0000000..d779cc5
Binary files /dev/null and b/libtommath/logs/expt.png differ
diff --git a/libtommath/logs/expt_2k.log b/libtommath/logs/expt_2k.log
new file mode 100644
index 0000000..97d325f
--- /dev/null
+++ b/libtommath/logs/expt_2k.log
@@ -0,0 +1,5 @@
+607   2109225
+1279  10148314
+2203  34126877
+3217  82716424
+4253 161569606
diff --git a/libtommath/logs/expt_2kl.log b/libtommath/logs/expt_2kl.log
new file mode 100644
index 0000000..d9ad4be
--- /dev/null
+++ b/libtommath/logs/expt_2kl.log
@@ -0,0 +1,4 @@
+1024   7705271
+2048  34286851
+4096 165207491
+521   1618631
diff --git a/libtommath/logs/expt_dr.log b/libtommath/logs/expt_dr.log
new file mode 100644
index 0000000..c6bbe07
--- /dev/null
+++ b/libtommath/logs/expt_dr.log
@@ -0,0 +1,7 @@
+532   1928550
+784   3763908
+1036   7564221
+1540  16566059
+2072  32283784
+3080  79851565
+4116 157843530
diff --git a/libtommath/logs/graphs.dem b/libtommath/logs/graphs.dem
new file mode 100644
index 0000000..dfaf613
--- /dev/null
+++ b/libtommath/logs/graphs.dem
@@ -0,0 +1,17 @@
+set terminal png
+set size 1.75
+set ylabel "Cycles per Operation"
+set xlabel "Operand size (bits)"
+
+set output "addsub.png"
+plot 'add.log' smooth bezier title "Addition", 'sub.log' smooth bezier title "Subtraction"
+
+set output "mult.png"
+plot 'sqr.log' smooth bezier title "Squaring (without Karatsuba)", 'sqr_kara.log' smooth bezier title "Squaring (Karatsuba)", 'mult.log' smooth bezier title "Multiplication (without Karatsuba)", 'mult_kara.log' smooth bezier title "Multiplication (Karatsuba)"
+
+set output "expt.png"
+plot 'expt.log' smooth bezier title "Exptmod (Montgomery)", 'expt_dr.log' smooth bezier title "Exptmod (Dimminished Radix)", 'expt_2k.log' smooth bezier title "Exptmod (2k Reduction)"
+
+set output "invmod.png"
+plot 'invmod.log' smooth bezier title "Modular Inverse"
+
diff --git a/libtommath/logs/index.html b/libtommath/logs/index.html
new file mode 100644
index 0000000..8c1ed9d
--- /dev/null
+++ b/libtommath/logs/index.html
@@ -0,0 +1,24 @@
+<html>
+<head>
+<title>LibTomMath Log Plots</title>
+</head>
+<body>
+
+<h1>Addition and Subtraction</h1>
+<center><img src=addsub.png></center>
+<hr>
+
+<h1>Multipliers</h1>
+<center><img src=mult.png></center>
+<hr>
+
+<h1>Exptmod</h1>
+<center><img src=expt.png></center>
+<hr>
+
+<h1>Modular Inverse</h1>
+<center><img src=invmod.png></center>
+<hr>
+
+</body>
+</html>
diff --git a/libtommath/logs/invmod.log b/libtommath/logs/invmod.log
new file mode 100644
index 0000000..e69de29
diff --git a/libtommath/logs/invmod.png b/libtommath/logs/invmod.png
new file mode 100644
index 0000000..9dcd7d8
Binary files /dev/null and b/libtommath/logs/invmod.png differ
diff --git a/libtommath/logs/mult.log b/libtommath/logs/mult.log
new file mode 100644
index 0000000..33563fc
--- /dev/null
+++ b/libtommath/logs/mult.log
@@ -0,0 +1,84 @@
+271       555
+390       855
+508      1161
+631      1605
+749      2117
+871      2687
+991      3329
+1108      4084
+1231      4786
+1351      5624
+1470      6392
+1586      7364
+1710      8218
+1830      9255
+1951     10217
+2067     11461
+2191     12463
+2308     13677
+2430     14800
+2551     16232
+2671     17460
+2791     18899
+2902     20247
+3028     21902
+3151     23240
+3267     24927
+3391     26441
+3511     28277
+3631     29838
+3749     31751
+3869     33673
+3989     35431
+4111     37518
+4231     39426
+4349     41504
+4471     43567
+4591     45786
+4711     47876
+4831     50299
+4951     52427
+5071     54785
+5189     57241
+5307     59730
+5431     62194
+5551     64761
+5670     67322
+5789     70073
+5907     72663
+6030     75437
+6151     78242
+6268     81202
+6389     83948
+6509     86985
+6631     89903
+6747     93184
+6869     96044
+6991     99286
+7109    102395
+7229    105917
+7351    108940
+7470    112490
+7589    115702
+7711    119508
+7831    122632
+7951    126410
+8071    129808
+8190    133895
+8311    137146
+8431    141218
+8549    144732
+8667    149131
+8790    152462
+8911    156754
+9030    160479
+9149    165138
+9271    168601
+9391    173185
+9511    176988
+9627    181976
+9751    185539
+9870    190388
+9991    194335
+10110    199605
+10228    203298
diff --git a/libtommath/logs/mult.png b/libtommath/logs/mult.png
new file mode 100644
index 0000000..d22e8c8
Binary files /dev/null and b/libtommath/logs/mult.png differ
diff --git a/libtommath/logs/mult_kara.log b/libtommath/logs/mult_kara.log
new file mode 100644
index 0000000..7136c79
--- /dev/null
+++ b/libtommath/logs/mult_kara.log
@@ -0,0 +1,84 @@
+271       560
+391       870
+511      1159
+631      1605
+750      2111
+871      2737
+991      3361
+1111      4054
+1231      4778
+1351      5600
+1471      6404
+1591      7323
+1710      8255
+1831      9239
+1948     10257
+2070     11397
+2190     12531
+2308     13665
+2429     14870
+2550     16175
+2671     17539
+2787     18879
+2911     20350
+3031     21807
+3150     23415
+3270     24897
+3388     26567
+3511     28205
+3627     30076
+3751     31744
+3869     33657
+3991     35425
+4111     37522
+4229     39363
+4351     41503
+4470     43491
+4590     45827
+4711     47795
+4828     50166
+4951     52318
+5070     54911
+5191     57036
+5308     58237
+5431     60248
+5551     62678
+5671     64786
+5791     67294
+5908     69343
+6031     71607
+6151     74166
+6271     76590
+6391     78734
+6511     81175
+6631     83742
+6750     86403
+6868     88873
+6990     91150
+7110     94211
+7228     96922
+7351     99445
+7469    102216
+7589    104968
+7711    108113
+7827    110758
+7950    113714
+8071    116511
+8186    119643
+8310    122679
+8425    125581
+8551    128715
+8669    131778
+8788    135116
+8910    138138
+9031    141628
+9148    144754
+9268    148367
+9391    151551
+9511    155033
+9631    158652
+9751    162125
+9871    165248
+9988    168627
+10111    172427
+10231    176412
diff --git a/libtommath/logs/sqr.log b/libtommath/logs/sqr.log
new file mode 100644
index 0000000..cd29fc5
--- /dev/null
+++ b/libtommath/logs/sqr.log
@@ -0,0 +1,84 @@
+265       562
+389       882
+509      1207
+631      1572
+750      1990
+859      2433
+991      2894
+1109      3555
+1230      4228
+1350      5018
+1471      5805
+1591      6579
+1709      7415
+1829      8329
+1949      9225
+2071     10139
+2188     11239
+2309     12178
+2431     13212
+2551     14294
+2671     15551
+2791     16512
+2911     17718
+3030     18876
+3150     20259
+3270     21374
+3391     22650
+3511     23948
+3631     25493
+3750     26756
+3870     28225
+3989     29705
+4110     31409
+4230     32834
+4351     34327
+4471     35818
+4591     37636
+4711     39228
+4830     40868
+4949     42393
+5070     44541
+5191     46269
+5310     48162
+5429     49728
+5548     51985
+5671     53948
+5791     55885
+5910     57584
+6031     60082
+6150     62239
+6270     64309
+6390     66014
+6511     68766
+6631     71012
+6750     73172
+6871     74952
+6991     77909
+7111     80371
+7231     82666
+7351     84531
+7469     87698
+7589     90318
+7711    225384
+7830    232428
+7950    240009
+8070    246522
+8190    253662
+8310    260961
+8431    269253
+8549    275743
+8671    283769
+8789    290811
+8911    300034
+9030    306873
+9149    315085
+9270    323944
+9390    332390
+9508    337519
+9631    348986
+9749    356904
+9871    367013
+9989    373831
+10108    381033
+10230    393475
diff --git a/libtommath/logs/sqr_kara.log b/libtommath/logs/sqr_kara.log
new file mode 100644
index 0000000..06355a7
--- /dev/null
+++ b/libtommath/logs/sqr_kara.log
@@ -0,0 +1,84 @@
+271       560
+388       878
+511      1179
+629      1625
+751      1988
+871      2423
+989      2896
+1111      3561
+1231      4209
+1350      5015
+1470      5804
+1591      6556
+1709      7420
+1831      8263
+1951      9173
+2070     10153
+2191     11229
+2310     12167
+2431     13211
+2550     14309
+2671     15524
+2788     16525
+2910     17712
+3028     18822
+3148     20220
+3271     21343
+3391     22652
+3511     23944
+3630     25485
+3750     26778
+3868     28201
+3990     29653
+4111     31393
+4225     32841
+4350     34328
+4471     35786
+4590     37652
+4711     39245
+4830     40876
+4951     42433
+5068     44547
+5191     46321
+5311     48140
+5430     49727
+5550     52034
+5671     53954
+5791     55921
+5908     57597
+6031     60084
+6148     62226
+6270     64295
+6390     66045
+6511     68779
+6629     71003
+6751     73169
+6871     74992
+6991     77895
+7110     80376
+7231     82628
+7351     84468
+7470     87664
+7591     90284
+7711     91352
+7828     93995
+7950     96276
+8071     98691
+8190    101256
+8308    103631
+8431    105222
+8550    108343
+8671    110281
+8787    112764
+8911    115397
+9031    117690
+9151    120266
+9271    122715
+9391    124624
+9510    127937
+9630    130313
+9750    132914
+9871    136129
+9991    138517
+10108    141525
+10231    144225
diff --git a/libtommath/logs/sub.log b/libtommath/logs/sub.log
new file mode 100644
index 0000000..9f84fa2
--- /dev/null
+++ b/libtommath/logs/sub.log
@@ -0,0 +1,16 @@
+480        94
+960       116
+1440       140
+1920       164
+2400       205
+2880       229
+3360       253
+3840       277
+4320       299
+4800       321
+5280       345
+5760       371
+6240       395
+6720       419
+7200       441
+7680       465
diff --git a/libtommath/makefile b/libtommath/makefile
new file mode 100644
index 0000000..70de306
--- /dev/null
+++ b/libtommath/makefile
@@ -0,0 +1,186 @@
+#Makefile for GCC
+#
+#Tom St Denis
+
+#version of library 
+VERSION=0.42.0
+
+CFLAGS  +=  -I./ -Wall -W -Wshadow -Wsign-compare
+
+ifndef MAKE
+   MAKE=make
+endif
+
+ifndef IGNORE_SPEED
+
+#for speed 
+CFLAGS += -O3 -funroll-loops
+
+#for size 
+#CFLAGS += -Os
+
+#x86 optimizations [should be valid for any GCC install though]
+CFLAGS  += -fomit-frame-pointer
+
+#debug
+#CFLAGS += -g3
+
+endif
+
+#install as this user
+ifndef INSTALL_GROUP
+   GROUP=wheel
+else
+   GROUP=$(INSTALL_GROUP)
+endif
+
+ifndef INSTALL_USER
+   USER=root
+else
+   USER=$(INSTALL_USER)
+endif
+
+#default files to install
+ifndef LIBNAME
+   LIBNAME=libtommath.a
+endif
+
+default: ${LIBNAME}
+
+HEADERS=tommath.h tommath_class.h tommath_superclass.h
+
+#LIBPATH-The directory for libtommath to be installed to.
+#INCPATH-The directory to install the header files for libtommath.
+#DATAPATH-The directory to install the pdf docs.
+DESTDIR=
+LIBPATH=/usr/lib
+INCPATH=/usr/include
+DATAPATH=/usr/share/doc/libtommath/pdf
+
+OBJECTS=bncore.o bn_mp_init.o bn_mp_clear.o bn_mp_exch.o bn_mp_grow.o bn_mp_shrink.o \
+bn_mp_clamp.o bn_mp_zero.o  bn_mp_set.o bn_mp_set_int.o bn_mp_init_size.o bn_mp_copy.o \
+bn_mp_init_copy.o bn_mp_abs.o bn_mp_neg.o bn_mp_cmp_mag.o bn_mp_cmp.o bn_mp_cmp_d.o \
+bn_mp_rshd.o bn_mp_lshd.o bn_mp_mod_2d.o bn_mp_div_2d.o bn_mp_mul_2d.o bn_mp_div_2.o \
+bn_mp_mul_2.o bn_s_mp_add.o bn_s_mp_sub.o bn_fast_s_mp_mul_digs.o bn_s_mp_mul_digs.o \
+bn_fast_s_mp_mul_high_digs.o bn_s_mp_mul_high_digs.o bn_fast_s_mp_sqr.o bn_s_mp_sqr.o \
+bn_mp_add.o bn_mp_sub.o bn_mp_karatsuba_mul.o bn_mp_mul.o bn_mp_karatsuba_sqr.o \
+bn_mp_sqr.o bn_mp_div.o bn_mp_mod.o bn_mp_add_d.o bn_mp_sub_d.o bn_mp_mul_d.o \
+bn_mp_div_d.o bn_mp_mod_d.o bn_mp_expt_d.o bn_mp_addmod.o bn_mp_submod.o \
+bn_mp_mulmod.o bn_mp_sqrmod.o bn_mp_gcd.o bn_mp_lcm.o bn_fast_mp_invmod.o bn_mp_invmod.o \
+bn_mp_reduce.o bn_mp_montgomery_setup.o bn_fast_mp_montgomery_reduce.o bn_mp_montgomery_reduce.o \
+bn_mp_exptmod_fast.o bn_mp_exptmod.o bn_mp_2expt.o bn_mp_n_root.o bn_mp_jacobi.o bn_reverse.o \
+bn_mp_count_bits.o bn_mp_read_unsigned_bin.o bn_mp_read_signed_bin.o bn_mp_to_unsigned_bin.o \
+bn_mp_to_signed_bin.o bn_mp_unsigned_bin_size.o bn_mp_signed_bin_size.o  \
+bn_mp_xor.o bn_mp_and.o bn_mp_or.o bn_mp_rand.o bn_mp_montgomery_calc_normalization.o \
+bn_mp_prime_is_divisible.o bn_prime_tab.o bn_mp_prime_fermat.o bn_mp_prime_miller_rabin.o \
+bn_mp_prime_is_prime.o bn_mp_prime_next_prime.o bn_mp_dr_reduce.o \
+bn_mp_dr_is_modulus.o bn_mp_dr_setup.o bn_mp_reduce_setup.o \
+bn_mp_toom_mul.o bn_mp_toom_sqr.o bn_mp_div_3.o bn_s_mp_exptmod.o \
+bn_mp_reduce_2k.o bn_mp_reduce_is_2k.o bn_mp_reduce_2k_setup.o \
+bn_mp_reduce_2k_l.o bn_mp_reduce_is_2k_l.o bn_mp_reduce_2k_setup_l.o \
+bn_mp_radix_smap.o bn_mp_read_radix.o bn_mp_toradix.o bn_mp_radix_size.o \
+bn_mp_fread.o bn_mp_fwrite.o bn_mp_cnt_lsb.o bn_error.o \
+bn_mp_init_multi.o bn_mp_clear_multi.o bn_mp_exteuclid.o bn_mp_toradix_n.o \
+bn_mp_prime_random_ex.o bn_mp_get_int.o bn_mp_sqrt.o bn_mp_is_square.o bn_mp_init_set.o \
+bn_mp_init_set_int.o bn_mp_invmod_slow.o bn_mp_prime_rabin_miller_trials.o \
+bn_mp_to_signed_bin_n.o bn_mp_to_unsigned_bin_n.o
+
+$(LIBNAME):  $(OBJECTS)
+	$(AR) $(ARFLAGS) $@ $(OBJECTS)
+	ranlib $@
+
+#make a profiled library (takes a while!!!)
+#
+# This will build the library with profile generation
+# then run the test demo and rebuild the library.
+# 
+# So far I've seen improvements in the MP math
+profiled:
+	make CFLAGS="$(CFLAGS) -fprofile-arcs -DTESTING" timing
+	./ltmtest
+	rm -f *.a *.o ltmtest
+	make CFLAGS="$(CFLAGS) -fbranch-probabilities"
+
+#make a single object profiled library 
+profiled_single:
+	perl gen.pl
+	$(CC) $(CFLAGS) -fprofile-arcs -DTESTING -c mpi.c -o mpi.o
+	$(CC) $(CFLAGS) -DTESTING -DTIMER demo/timing.c mpi.o -o ltmtest
+	./ltmtest
+	rm -f *.o ltmtest
+	$(CC) $(CFLAGS) -fbranch-probabilities -DTESTING -c mpi.c -o mpi.o
+	$(AR) $(ARFLAGS) $(LIBNAME) mpi.o
+	ranlib $(LIBNAME)	
+
+install: $(LIBNAME)
+	install -d -g $(GROUP) -o $(USER) $(DESTDIR)$(LIBPATH)
+	install -d -g $(GROUP) -o $(USER) $(DESTDIR)$(INCPATH)
+	install -g $(GROUP) -o $(USER) $(LIBNAME) $(DESTDIR)$(LIBPATH)
+	install -g $(GROUP) -o $(USER) $(HEADERS) $(DESTDIR)$(INCPATH)
+
+test: $(LIBNAME) demo/demo.o
+	$(CC) $(CFLAGS) demo/demo.o $(LIBNAME) -o test
+	
+mtest: test	
+	cd mtest ; $(CC) $(CFLAGS) mtest.c -o mtest
+        
+timing: $(LIBNAME)
+	$(CC) $(CFLAGS) -DTIMER demo/timing.c $(LIBNAME) -o ltmtest
+
+# makes the LTM book DVI file, requires tetex, perl and makeindex [part of tetex I think]
+docdvi: tommath.src
+	cd pics ; MAKE=${MAKE} ${MAKE} 
+	echo "hello" > tommath.ind
+	perl booker.pl
+	latex tommath > /dev/null
+	latex tommath > /dev/null
+	makeindex tommath
+	latex tommath > /dev/null
+
+# poster, makes the single page PDF poster
+poster: poster.tex
+	pdflatex poster
+	rm -f poster.aux poster.log 
+
+# makes the LTM book PDF file, requires tetex, cleans up the LaTeX temp files
+docs:   docdvi
+	dvipdf tommath
+	rm -f tommath.log tommath.aux tommath.dvi tommath.idx tommath.toc tommath.lof tommath.ind tommath.ilg
+	cd pics ; MAKE=${MAKE} ${MAKE} clean
+	
+#LTM user manual
+mandvi: bn.tex
+	echo "hello" > bn.ind
+	latex bn > /dev/null
+	latex bn > /dev/null
+	makeindex bn
+	latex bn > /dev/null
+
+#LTM user manual [pdf]
+manual:	mandvi
+	pdflatex bn >/dev/null
+	rm -f bn.aux bn.dvi bn.log bn.idx bn.lof bn.out bn.toc
+
+pretty: 
+	perl pretty.build
+
+clean:
+	rm -f *.bat *.pdf *.o *.a *.obj *.lib *.exe *.dll etclib/*.o demo/demo.o test ltmtest mpitest mtest/mtest mtest/mtest.exe \
+        *.idx *.toc *.log *.aux *.dvi *.lof *.ind *.ilg *.ps *.log *.s mpi.c *.da *.dyn *.dpi tommath.tex `find . -type f | grep [~] | xargs` *.lo *.la
+	rm -rf .libs
+	cd etc ; MAKE=${MAKE} ${MAKE} clean
+	cd pics ; MAKE=${MAKE} ${MAKE} clean
+
+#zipup the project (take that!)
+no_oops: clean
+	cd .. ; cvs commit 
+	echo Scanning for scratch/dirty files
+	find . -type f | grep -v CVS | xargs -n 1 bash mess.sh
+
+zipup: clean manual poster docs
+	perl gen.pl ; mv mpi.c pre_gen/ ; \
+	cd .. ; rm -rf ltm* libtommath-$(VERSION) ; mkdir libtommath-$(VERSION) ; \
+	cp -R ./libtommath/* ./libtommath-$(VERSION)/ ; \
+	tar -c libtommath-$(VERSION)/* | bzip2 -9vvc > ltm-$(VERSION).tar.bz2 ; \
+	zip -9 -r ltm-$(VERSION).zip libtommath-$(VERSION)/* ; \
+	mv -f ltm* ~ ; rm -rf libtommath-$(VERSION)
diff --git a/libtommath/makefile.bcc b/libtommath/makefile.bcc
new file mode 100644
index 0000000..67743d9
--- /dev/null
+++ b/libtommath/makefile.bcc
@@ -0,0 +1,44 @@
+#
+# Borland C++Builder Makefile (makefile.bcc)
+#
+
+
+LIB = tlib
+CC = bcc32
+CFLAGS = -c -O2 -I.
+
+OBJECTS=bncore.obj bn_mp_init.obj bn_mp_clear.obj bn_mp_exch.obj bn_mp_grow.obj bn_mp_shrink.obj \
+bn_mp_clamp.obj bn_mp_zero.obj  bn_mp_set.obj bn_mp_set_int.obj bn_mp_init_size.obj bn_mp_copy.obj \
+bn_mp_init_copy.obj bn_mp_abs.obj bn_mp_neg.obj bn_mp_cmp_mag.obj bn_mp_cmp.obj bn_mp_cmp_d.obj \
+bn_mp_rshd.obj bn_mp_lshd.obj bn_mp_mod_2d.obj bn_mp_div_2d.obj bn_mp_mul_2d.obj bn_mp_div_2.obj \
+bn_mp_mul_2.obj bn_s_mp_add.obj bn_s_mp_sub.obj bn_fast_s_mp_mul_digs.obj bn_s_mp_mul_digs.obj \
+bn_fast_s_mp_mul_high_digs.obj bn_s_mp_mul_high_digs.obj bn_fast_s_mp_sqr.obj bn_s_mp_sqr.obj \
+bn_mp_add.obj bn_mp_sub.obj bn_mp_karatsuba_mul.obj bn_mp_mul.obj bn_mp_karatsuba_sqr.obj \
+bn_mp_sqr.obj bn_mp_div.obj bn_mp_mod.obj bn_mp_add_d.obj bn_mp_sub_d.obj bn_mp_mul_d.obj \
+bn_mp_div_d.obj bn_mp_mod_d.obj bn_mp_expt_d.obj bn_mp_addmod.obj bn_mp_submod.obj \
+bn_mp_mulmod.obj bn_mp_sqrmod.obj bn_mp_gcd.obj bn_mp_lcm.obj bn_fast_mp_invmod.obj bn_mp_invmod.obj \
+bn_mp_reduce.obj bn_mp_montgomery_setup.obj bn_fast_mp_montgomery_reduce.obj bn_mp_montgomery_reduce.obj \
+bn_mp_exptmod_fast.obj bn_mp_exptmod.obj bn_mp_2expt.obj bn_mp_n_root.obj bn_mp_jacobi.obj bn_reverse.obj \
+bn_mp_count_bits.obj bn_mp_read_unsigned_bin.obj bn_mp_read_signed_bin.obj bn_mp_to_unsigned_bin.obj \
+bn_mp_to_signed_bin.obj bn_mp_unsigned_bin_size.obj bn_mp_signed_bin_size.obj  \
+bn_mp_xor.obj bn_mp_and.obj bn_mp_or.obj bn_mp_rand.obj bn_mp_montgomery_calc_normalization.obj \
+bn_mp_prime_is_divisible.obj bn_prime_tab.obj bn_mp_prime_fermat.obj bn_mp_prime_miller_rabin.obj \
+bn_mp_prime_is_prime.obj bn_mp_prime_next_prime.obj bn_mp_dr_reduce.obj \
+bn_mp_dr_is_modulus.obj bn_mp_dr_setup.obj bn_mp_reduce_setup.obj \
+bn_mp_toom_mul.obj bn_mp_toom_sqr.obj bn_mp_div_3.obj bn_s_mp_exptmod.obj \
+bn_mp_reduce_2k.obj bn_mp_reduce_is_2k.obj bn_mp_reduce_2k_setup.obj \
+bn_mp_reduce_2k_l.obj bn_mp_reduce_is_2k_l.obj bn_mp_reduce_2k_setup_l.obj \
+bn_mp_radix_smap.obj bn_mp_read_radix.obj bn_mp_toradix.obj bn_mp_radix_size.obj \
+bn_mp_fread.obj bn_mp_fwrite.obj bn_mp_cnt_lsb.obj bn_error.obj \
+bn_mp_init_multi.obj bn_mp_clear_multi.obj bn_mp_exteuclid.obj bn_mp_toradix_n.obj \
+bn_mp_prime_random_ex.obj bn_mp_get_int.obj bn_mp_sqrt.obj bn_mp_is_square.obj \
+bn_mp_init_set.obj bn_mp_init_set_int.obj bn_mp_invmod_slow.obj bn_mp_prime_rabin_miller_trials.obj \
+bn_mp_to_signed_bin_n.obj bn_mp_to_unsigned_bin_n.obj
+
+TARGET = libtommath.lib
+
+$(TARGET): $(OBJECTS)
+
+.c.obj:
+	$(CC) $(CFLAGS) $<
+	$(LIB) $(TARGET) -+$@
diff --git a/libtommath/makefile.cygwin_dll b/libtommath/makefile.cygwin_dll
new file mode 100644
index 0000000..85b10c7
--- /dev/null
+++ b/libtommath/makefile.cygwin_dll
@@ -0,0 +1,51 @@
+#Makefile for Cygwin-GCC
+#
+#This makefile will build a Windows DLL [doesn't require cygwin to run] in the file
+#libtommath.dll.  The import library is in libtommath.dll.a.  Remember to add
+#"-Wl,--enable-auto-import" to your client build to avoid the auto-import warnings
+#
+#Tom St Denis
+CFLAGS  +=  -I./ -Wall -W -Wshadow -O3 -funroll-loops -mno-cygwin
+
+#x86 optimizations [should be valid for any GCC install though]
+CFLAGS  += -fomit-frame-pointer 
+
+default: windll
+
+OBJECTS=bncore.o bn_mp_init.o bn_mp_clear.o bn_mp_exch.o bn_mp_grow.o bn_mp_shrink.o \
+bn_mp_clamp.o bn_mp_zero.o  bn_mp_set.o bn_mp_set_int.o bn_mp_init_size.o bn_mp_copy.o \
+bn_mp_init_copy.o bn_mp_abs.o bn_mp_neg.o bn_mp_cmp_mag.o bn_mp_cmp.o bn_mp_cmp_d.o \
+bn_mp_rshd.o bn_mp_lshd.o bn_mp_mod_2d.o bn_mp_div_2d.o bn_mp_mul_2d.o bn_mp_div_2.o \
+bn_mp_mul_2.o bn_s_mp_add.o bn_s_mp_sub.o bn_fast_s_mp_mul_digs.o bn_s_mp_mul_digs.o \
+bn_fast_s_mp_mul_high_digs.o bn_s_mp_mul_high_digs.o bn_fast_s_mp_sqr.o bn_s_mp_sqr.o \
+bn_mp_add.o bn_mp_sub.o bn_mp_karatsuba_mul.o bn_mp_mul.o bn_mp_karatsuba_sqr.o \
+bn_mp_sqr.o bn_mp_div.o bn_mp_mod.o bn_mp_add_d.o bn_mp_sub_d.o bn_mp_mul_d.o \
+bn_mp_div_d.o bn_mp_mod_d.o bn_mp_expt_d.o bn_mp_addmod.o bn_mp_submod.o \
+bn_mp_mulmod.o bn_mp_sqrmod.o bn_mp_gcd.o bn_mp_lcm.o bn_fast_mp_invmod.o bn_mp_invmod.o \
+bn_mp_reduce.o bn_mp_montgomery_setup.o bn_fast_mp_montgomery_reduce.o bn_mp_montgomery_reduce.o \
+bn_mp_exptmod_fast.o bn_mp_exptmod.o bn_mp_2expt.o bn_mp_n_root.o bn_mp_jacobi.o bn_reverse.o \
+bn_mp_count_bits.o bn_mp_read_unsigned_bin.o bn_mp_read_signed_bin.o bn_mp_to_unsigned_bin.o \
+bn_mp_to_signed_bin.o bn_mp_unsigned_bin_size.o bn_mp_signed_bin_size.o  \
+bn_mp_xor.o bn_mp_and.o bn_mp_or.o bn_mp_rand.o bn_mp_montgomery_calc_normalization.o \
+bn_mp_prime_is_divisible.o bn_prime_tab.o bn_mp_prime_fermat.o bn_mp_prime_miller_rabin.o \
+bn_mp_prime_is_prime.o bn_mp_prime_next_prime.o bn_mp_dr_reduce.o \
+bn_mp_dr_is_modulus.o bn_mp_dr_setup.o bn_mp_reduce_setup.o \
+bn_mp_toom_mul.o bn_mp_toom_sqr.o bn_mp_div_3.o bn_s_mp_exptmod.o \
+bn_mp_reduce_2k.o bn_mp_reduce_is_2k.o bn_mp_reduce_2k_setup.o \
+bn_mp_reduce_2k_l.o bn_mp_reduce_is_2k_l.o bn_mp_reduce_2k_setup_l.o \
+bn_mp_radix_smap.o bn_mp_read_radix.o bn_mp_toradix.o bn_mp_radix_size.o \
+bn_mp_fread.o bn_mp_fwrite.o bn_mp_cnt_lsb.o bn_error.o \
+bn_mp_init_multi.o bn_mp_clear_multi.o bn_mp_exteuclid.o bn_mp_toradix_n.o \
+bn_mp_prime_random_ex.o bn_mp_get_int.o bn_mp_sqrt.o bn_mp_is_square.o bn_mp_init_set.o \
+bn_mp_init_set_int.o bn_mp_invmod_slow.o bn_mp_prime_rabin_miller_trials.o \
+bn_mp_to_signed_bin_n.o bn_mp_to_unsigned_bin_n.o
+
+# make a Windows DLL via Cygwin
+windll:  $(OBJECTS)
+	gcc -mno-cygwin -mdll -o libtommath.dll -Wl,--out-implib=libtommath.dll.a -Wl,--export-all-symbols *.o
+	ranlib libtommath.dll.a
+
+# build the test program using the windows DLL
+test: $(OBJECTS) windll
+	gcc $(CFLAGS) demo/demo.c libtommath.dll.a -Wl,--enable-auto-import -o test -s
+	cd mtest ; $(CC) -O3 -fomit-frame-pointer -funroll-loops mtest.c -o mtest -s
diff --git a/libtommath/makefile.icc b/libtommath/makefile.icc
new file mode 100644
index 0000000..cf70ab0
--- /dev/null
+++ b/libtommath/makefile.icc
@@ -0,0 +1,116 @@
+#Makefile for ICC
+#
+#Tom St Denis
+CC=icc
+
+CFLAGS  +=  -I./
+
+# optimize for SPEED
+#
+# -mcpu= can be pentium, pentiumpro (covers PII through PIII) or pentium4
+# -ax?   specifies make code specifically for ? but compatible with IA-32
+# -x?    specifies compile solely for ? [not specifically IA-32 compatible]
+#
+# where ? is 
+#   K - PIII
+#   W - first P4 [Williamette]
+#   N - P4 Northwood
+#   P - P4 Prescott
+#   B - Blend of P4 and PM [mobile]
+#
+# Default to just generic max opts
+CFLAGS += -O3 -xP -ip
+
+#install as this user
+USER=root
+GROUP=root
+
+default: libtommath.a
+
+#default files to install
+LIBNAME=libtommath.a
+HEADERS=tommath.h
+
+#LIBPATH-The directory for libtomcrypt to be installed to.
+#INCPATH-The directory to install the header files for libtommath.
+#DATAPATH-The directory to install the pdf docs.
+DESTDIR=
+LIBPATH=/usr/lib
+INCPATH=/usr/include
+DATAPATH=/usr/share/doc/libtommath/pdf
+
+OBJECTS=bncore.o bn_mp_init.o bn_mp_clear.o bn_mp_exch.o bn_mp_grow.o bn_mp_shrink.o \
+bn_mp_clamp.o bn_mp_zero.o  bn_mp_set.o bn_mp_set_int.o bn_mp_init_size.o bn_mp_copy.o \
+bn_mp_init_copy.o bn_mp_abs.o bn_mp_neg.o bn_mp_cmp_mag.o bn_mp_cmp.o bn_mp_cmp_d.o \
+bn_mp_rshd.o bn_mp_lshd.o bn_mp_mod_2d.o bn_mp_div_2d.o bn_mp_mul_2d.o bn_mp_div_2.o \
+bn_mp_mul_2.o bn_s_mp_add.o bn_s_mp_sub.o bn_fast_s_mp_mul_digs.o bn_s_mp_mul_digs.o \
+bn_fast_s_mp_mul_high_digs.o bn_s_mp_mul_high_digs.o bn_fast_s_mp_sqr.o bn_s_mp_sqr.o \
+bn_mp_add.o bn_mp_sub.o bn_mp_karatsuba_mul.o bn_mp_mul.o bn_mp_karatsuba_sqr.o \
+bn_mp_sqr.o bn_mp_div.o bn_mp_mod.o bn_mp_add_d.o bn_mp_sub_d.o bn_mp_mul_d.o \
+bn_mp_div_d.o bn_mp_mod_d.o bn_mp_expt_d.o bn_mp_addmod.o bn_mp_submod.o \
+bn_mp_mulmod.o bn_mp_sqrmod.o bn_mp_gcd.o bn_mp_lcm.o bn_fast_mp_invmod.o bn_mp_invmod.o \
+bn_mp_reduce.o bn_mp_montgomery_setup.o bn_fast_mp_montgomery_reduce.o bn_mp_montgomery_reduce.o \
+bn_mp_exptmod_fast.o bn_mp_exptmod.o bn_mp_2expt.o bn_mp_n_root.o bn_mp_jacobi.o bn_reverse.o \
+bn_mp_count_bits.o bn_mp_read_unsigned_bin.o bn_mp_read_signed_bin.o bn_mp_to_unsigned_bin.o \
+bn_mp_to_signed_bin.o bn_mp_unsigned_bin_size.o bn_mp_signed_bin_size.o  \
+bn_mp_xor.o bn_mp_and.o bn_mp_or.o bn_mp_rand.o bn_mp_montgomery_calc_normalization.o \
+bn_mp_prime_is_divisible.o bn_prime_tab.o bn_mp_prime_fermat.o bn_mp_prime_miller_rabin.o \
+bn_mp_prime_is_prime.o bn_mp_prime_next_prime.o bn_mp_dr_reduce.o \
+bn_mp_dr_is_modulus.o bn_mp_dr_setup.o bn_mp_reduce_setup.o \
+bn_mp_toom_mul.o bn_mp_toom_sqr.o bn_mp_div_3.o bn_s_mp_exptmod.o \
+bn_mp_reduce_2k.o bn_mp_reduce_is_2k.o bn_mp_reduce_2k_setup.o \
+bn_mp_reduce_2k_l.o bn_mp_reduce_is_2k_l.o bn_mp_reduce_2k_setup_l.o \
+bn_mp_radix_smap.o bn_mp_read_radix.o bn_mp_toradix.o bn_mp_radix_size.o \
+bn_mp_fread.o bn_mp_fwrite.o bn_mp_cnt_lsb.o bn_error.o \
+bn_mp_init_multi.o bn_mp_clear_multi.o bn_mp_exteuclid.o bn_mp_toradix_n.o \
+bn_mp_prime_random_ex.o bn_mp_get_int.o bn_mp_sqrt.o bn_mp_is_square.o bn_mp_init_set.o \
+bn_mp_init_set_int.o bn_mp_invmod_slow.o bn_mp_prime_rabin_miller_trials.o \
+bn_mp_to_signed_bin_n.o bn_mp_to_unsigned_bin_n.o
+
+libtommath.a:  $(OBJECTS)
+	$(AR) $(ARFLAGS) libtommath.a $(OBJECTS)
+	ranlib libtommath.a
+
+#make a profiled library (takes a while!!!)
+#
+# This will build the library with profile generation
+# then run the test demo and rebuild the library.
+# 
+# So far I've seen improvements in the MP math
+profiled:
+	make -f makefile.icc CFLAGS="$(CFLAGS) -prof_gen -DTESTING" timing
+	./ltmtest
+	rm -f *.a *.o ltmtest
+	make -f makefile.icc CFLAGS="$(CFLAGS) -prof_use"
+
+#make a single object profiled library 
+profiled_single:
+	perl gen.pl
+	$(CC) $(CFLAGS) -prof_gen -DTESTING -c mpi.c -o mpi.o
+	$(CC) $(CFLAGS) -DTESTING -DTIMER demo/demo.c mpi.o -o ltmtest
+	./ltmtest
+	rm -f *.o ltmtest
+	$(CC) $(CFLAGS) -prof_use -ip -DTESTING -c mpi.c -o mpi.o
+	$(AR) $(ARFLAGS) libtommath.a mpi.o
+	ranlib libtommath.a	
+
+install: libtommath.a
+	install -d -g $(GROUP) -o $(USER) $(DESTDIR)$(LIBPATH)
+	install -d -g $(GROUP) -o $(USER) $(DESTDIR)$(INCPATH)
+	install -g $(GROUP) -o $(USER) $(LIBNAME) $(DESTDIR)$(LIBPATH)
+	install -g $(GROUP) -o $(USER) $(HEADERS) $(DESTDIR)$(INCPATH)
+
+test: libtommath.a demo/demo.o
+	$(CC) demo/demo.o libtommath.a -o test
+	
+mtest: test	
+	cd mtest ; $(CC) $(CFLAGS) mtest.c -o mtest
+        
+timing: libtommath.a
+	$(CC) $(CFLAGS) -DTIMER demo/timing.c libtommath.a -o ltmtest
+
+clean:
+	rm -f *.bat *.pdf *.o *.a *.obj *.lib *.exe *.dll etclib/*.o demo/demo.o test ltmtest mpitest mtest/mtest mtest/mtest.exe \
+        *.idx *.toc *.log *.aux *.dvi *.lof *.ind *.ilg *.ps *.log *.s mpi.c *.il etc/*.il *.dyn
+	cd etc ; make clean
+	cd pics ; make clean
diff --git a/libtommath/makefile.msvc b/libtommath/makefile.msvc
new file mode 100644
index 0000000..5edebec
--- /dev/null
+++ b/libtommath/makefile.msvc
@@ -0,0 +1,40 @@
+#MSVC Makefile
+#
+#Tom St Denis
+
+CFLAGS = /I. /Ox /DWIN32 /W3 /Fo$@
+
+default: library
+
+OBJECTS=bncore.obj bn_mp_init.obj bn_mp_clear.obj bn_mp_exch.obj bn_mp_grow.obj bn_mp_shrink.obj \
+bn_mp_clamp.obj bn_mp_zero.obj  bn_mp_set.obj bn_mp_set_int.obj bn_mp_init_size.obj bn_mp_copy.obj \
+bn_mp_init_copy.obj bn_mp_abs.obj bn_mp_neg.obj bn_mp_cmp_mag.obj bn_mp_cmp.obj bn_mp_cmp_d.obj \
+bn_mp_rshd.obj bn_mp_lshd.obj bn_mp_mod_2d.obj bn_mp_div_2d.obj bn_mp_mul_2d.obj bn_mp_div_2.obj \
+bn_mp_mul_2.obj bn_s_mp_add.obj bn_s_mp_sub.obj bn_fast_s_mp_mul_digs.obj bn_s_mp_mul_digs.obj \
+bn_fast_s_mp_mul_high_digs.obj bn_s_mp_mul_high_digs.obj bn_fast_s_mp_sqr.obj bn_s_mp_sqr.obj \
+bn_mp_add.obj bn_mp_sub.obj bn_mp_karatsuba_mul.obj bn_mp_mul.obj bn_mp_karatsuba_sqr.obj \
+bn_mp_sqr.obj bn_mp_div.obj bn_mp_mod.obj bn_mp_add_d.obj bn_mp_sub_d.obj bn_mp_mul_d.obj \
+bn_mp_div_d.obj bn_mp_mod_d.obj bn_mp_expt_d.obj bn_mp_addmod.obj bn_mp_submod.obj \
+bn_mp_mulmod.obj bn_mp_sqrmod.obj bn_mp_gcd.obj bn_mp_lcm.obj bn_fast_mp_invmod.obj bn_mp_invmod.obj \
+bn_mp_reduce.obj bn_mp_montgomery_setup.obj bn_fast_mp_montgomery_reduce.obj bn_mp_montgomery_reduce.obj \
+bn_mp_exptmod_fast.obj bn_mp_exptmod.obj bn_mp_2expt.obj bn_mp_n_root.obj bn_mp_jacobi.obj bn_reverse.obj \
+bn_mp_count_bits.obj bn_mp_read_unsigned_bin.obj bn_mp_read_signed_bin.obj bn_mp_to_unsigned_bin.obj \
+bn_mp_to_signed_bin.obj bn_mp_unsigned_bin_size.obj bn_mp_signed_bin_size.obj  \
+bn_mp_xor.obj bn_mp_and.obj bn_mp_or.obj bn_mp_rand.obj bn_mp_montgomery_calc_normalization.obj \
+bn_mp_prime_is_divisible.obj bn_prime_tab.obj bn_mp_prime_fermat.obj bn_mp_prime_miller_rabin.obj \
+bn_mp_prime_is_prime.obj bn_mp_prime_next_prime.obj bn_mp_dr_reduce.obj \
+bn_mp_dr_is_modulus.obj bn_mp_dr_setup.obj bn_mp_reduce_setup.obj \
+bn_mp_toom_mul.obj bn_mp_toom_sqr.obj bn_mp_div_3.obj bn_s_mp_exptmod.obj \
+bn_mp_reduce_2k.obj bn_mp_reduce_is_2k.obj bn_mp_reduce_2k_setup.obj \
+bn_mp_reduce_2k_l.obj bn_mp_reduce_is_2k_l.obj bn_mp_reduce_2k_setup_l.obj \
+bn_mp_radix_smap.obj bn_mp_read_radix.obj bn_mp_toradix.obj bn_mp_radix_size.obj \
+bn_mp_fread.obj bn_mp_fwrite.obj bn_mp_cnt_lsb.obj bn_error.obj \
+bn_mp_init_multi.obj bn_mp_clear_multi.obj bn_mp_exteuclid.obj bn_mp_toradix_n.obj \
+bn_mp_prime_random_ex.obj bn_mp_get_int.obj bn_mp_sqrt.obj bn_mp_is_square.obj \
+bn_mp_init_set.obj bn_mp_init_set_int.obj bn_mp_invmod_slow.obj bn_mp_prime_rabin_miller_trials.obj \
+bn_mp_to_signed_bin_n.obj bn_mp_to_unsigned_bin_n.obj
+
+HEADERS=tommath.h tommath_class.h tommath_superclass.h
+
+library: $(OBJECTS)
+	lib /out:tommath.lib $(OBJECTS)
diff --git a/libtommath/makefile.shared b/libtommath/makefile.shared
new file mode 100644
index 0000000..f17bbbd
--- /dev/null
+++ b/libtommath/makefile.shared
@@ -0,0 +1,102 @@
+#Makefile for GCC
+#
+#Tom St Denis
+VERSION=0:41
+
+CC = libtool --mode=compile --tag=CC gcc
+
+CFLAGS  +=  -I./ -Wall -W -Wshadow -Wsign-compare
+
+ifndef IGNORE_SPEED
+
+#for speed 
+CFLAGS += -O3 -funroll-loops
+
+#for size 
+#CFLAGS += -Os
+
+#x86 optimizations [should be valid for any GCC install though]
+CFLAGS  += -fomit-frame-pointer
+
+endif
+
+#install as this user
+ifndef INSTALL_GROUP
+   GROUP=wheel
+else
+   GROUP=$(INSTALL_GROUP)
+endif
+
+ifndef INSTALL_USER
+   USER=root
+else
+   USER=$(INSTALL_USER)
+endif
+
+default: libtommath.la
+
+#default files to install
+ifndef LIBNAME
+   LIBNAME=libtommath.la
+endif
+ifndef LIBNAME_S
+   LIBNAME_S=libtommath.a
+endif
+HEADERS=tommath.h tommath_class.h tommath_superclass.h
+
+#LIBPATH-The directory for libtommath to be installed to.
+#INCPATH-The directory to install the header files for libtommath.
+#DATAPATH-The directory to install the pdf docs.
+DESTDIR=
+LIBPATH=/usr/lib
+INCPATH=/usr/include
+DATAPATH=/usr/share/doc/libtommath/pdf
+
+OBJECTS=bncore.o bn_mp_init.o bn_mp_clear.o bn_mp_exch.o bn_mp_grow.o bn_mp_shrink.o \
+bn_mp_clamp.o bn_mp_zero.o  bn_mp_set.o bn_mp_set_int.o bn_mp_init_size.o bn_mp_copy.o \
+bn_mp_init_copy.o bn_mp_abs.o bn_mp_neg.o bn_mp_cmp_mag.o bn_mp_cmp.o bn_mp_cmp_d.o \
+bn_mp_rshd.o bn_mp_lshd.o bn_mp_mod_2d.o bn_mp_div_2d.o bn_mp_mul_2d.o bn_mp_div_2.o \
+bn_mp_mul_2.o bn_s_mp_add.o bn_s_mp_sub.o bn_fast_s_mp_mul_digs.o bn_s_mp_mul_digs.o \
+bn_fast_s_mp_mul_high_digs.o bn_s_mp_mul_high_digs.o bn_fast_s_mp_sqr.o bn_s_mp_sqr.o \
+bn_mp_add.o bn_mp_sub.o bn_mp_karatsuba_mul.o bn_mp_mul.o bn_mp_karatsuba_sqr.o \
+bn_mp_sqr.o bn_mp_div.o bn_mp_mod.o bn_mp_add_d.o bn_mp_sub_d.o bn_mp_mul_d.o \
+bn_mp_div_d.o bn_mp_mod_d.o bn_mp_expt_d.o bn_mp_addmod.o bn_mp_submod.o \
+bn_mp_mulmod.o bn_mp_sqrmod.o bn_mp_gcd.o bn_mp_lcm.o bn_fast_mp_invmod.o bn_mp_invmod.o \
+bn_mp_reduce.o bn_mp_montgomery_setup.o bn_fast_mp_montgomery_reduce.o bn_mp_montgomery_reduce.o \
+bn_mp_exptmod_fast.o bn_mp_exptmod.o bn_mp_2expt.o bn_mp_n_root.o bn_mp_jacobi.o bn_reverse.o \
+bn_mp_count_bits.o bn_mp_read_unsigned_bin.o bn_mp_read_signed_bin.o bn_mp_to_unsigned_bin.o \
+bn_mp_to_signed_bin.o bn_mp_unsigned_bin_size.o bn_mp_signed_bin_size.o  \
+bn_mp_xor.o bn_mp_and.o bn_mp_or.o bn_mp_rand.o bn_mp_montgomery_calc_normalization.o \
+bn_mp_prime_is_divisible.o bn_prime_tab.o bn_mp_prime_fermat.o bn_mp_prime_miller_rabin.o \
+bn_mp_prime_is_prime.o bn_mp_prime_next_prime.o bn_mp_dr_reduce.o \
+bn_mp_dr_is_modulus.o bn_mp_dr_setup.o bn_mp_reduce_setup.o \
+bn_mp_toom_mul.o bn_mp_toom_sqr.o bn_mp_div_3.o bn_s_mp_exptmod.o \
+bn_mp_reduce_2k.o bn_mp_reduce_is_2k.o bn_mp_reduce_2k_setup.o \
+bn_mp_reduce_2k_l.o bn_mp_reduce_is_2k_l.o bn_mp_reduce_2k_setup_l.o \
+bn_mp_radix_smap.o bn_mp_read_radix.o bn_mp_toradix.o bn_mp_radix_size.o \
+bn_mp_fread.o bn_mp_fwrite.o bn_mp_cnt_lsb.o bn_error.o \
+bn_mp_init_multi.o bn_mp_clear_multi.o bn_mp_exteuclid.o bn_mp_toradix_n.o \
+bn_mp_prime_random_ex.o bn_mp_get_int.o bn_mp_sqrt.o bn_mp_is_square.o bn_mp_init_set.o \
+bn_mp_init_set_int.o bn_mp_invmod_slow.o bn_mp_prime_rabin_miller_trials.o \
+bn_mp_to_signed_bin_n.o bn_mp_to_unsigned_bin_n.o
+
+objs: $(OBJECTS)
+
+$(LIBNAME):  $(OBJECTS)
+	libtool --mode=link gcc *.lo -o $(LIBNAME) -rpath $(LIBPATH) -version-info $(VERSION)
+
+install: $(LIBNAME)
+	install -d -g $(GROUP) -o $(USER) $(DESTDIR)$(LIBPATH)
+	libtool --mode=install install -c $(LIBNAME) $(DESTDIR)$(LIBPATH)/$(LIBNAME)
+	install -d -g $(GROUP) -o $(USER) $(DESTDIR)$(INCPATH)
+	install -g $(GROUP) -o $(USER) $(HEADERS) $(DESTDIR)$(INCPATH)
+
+test: $(LIBNAME) demo/demo.o
+	gcc $(CFLAGS) -c demo/demo.c -o demo/demo.o
+	libtool --mode=link gcc -o test demo/demo.o $(LIBNAME_S)
+	
+mtest: test	
+	cd mtest ; gcc $(CFLAGS) mtest.c -o mtest
+        
+timing: $(LIBNAME)
+	gcc $(CFLAGS) -DTIMER demo/timing.c $(LIBNAME_S) -o ltmtest
diff --git a/libtommath/mess.sh b/libtommath/mess.sh
new file mode 100644
index 0000000..bf639ce
--- /dev/null
+++ b/libtommath/mess.sh
@@ -0,0 +1,4 @@
+#!/bin/bash
+if cvs log $1 >/dev/null 2>/dev/null; then exit 0; else echo "$1 shouldn't be here" ; exit 1; fi
+
+
diff --git a/libtommath/mtest/logtab.h b/libtommath/mtest/logtab.h
new file mode 100644
index 0000000..addd3ab
--- /dev/null
+++ b/libtommath/mtest/logtab.h
@@ -0,0 +1,19 @@
+const float s_logv_2[] = {
+   0.000000000, 0.000000000, 1.000000000, 0.630929754, 	/*  0  1  2  3 */
+   0.500000000, 0.430676558, 0.386852807, 0.356207187, 	/*  4  5  6  7 */
+   0.333333333, 0.315464877, 0.301029996, 0.289064826, 	/*  8  9 10 11 */
+   0.278942946, 0.270238154, 0.262649535, 0.255958025, 	/* 12 13 14 15 */
+   0.250000000, 0.244650542, 0.239812467, 0.235408913, 	/* 16 17 18 19 */
+   0.231378213, 0.227670249, 0.224243824, 0.221064729, 	/* 20 21 22 23 */
+   0.218104292, 0.215338279, 0.212746054, 0.210309918, 	/* 24 25 26 27 */
+   0.208014598, 0.205846832, 0.203795047, 0.201849087, 	/* 28 29 30 31 */
+   0.200000000, 0.198239863, 0.196561632, 0.194959022, 	/* 32 33 34 35 */
+   0.193426404, 0.191958720, 0.190551412, 0.189200360, 	/* 36 37 38 39 */
+   0.187901825, 0.186652411, 0.185449023, 0.184288833, 	/* 40 41 42 43 */
+   0.183169251, 0.182087900, 0.181042597, 0.180031327, 	/* 44 45 46 47 */
+   0.179052232, 0.178103594, 0.177183820, 0.176291434, 	/* 48 49 50 51 */
+   0.175425064, 0.174583430, 0.173765343, 0.172969690, 	/* 52 53 54 55 */
+   0.172195434, 0.171441601, 0.170707280, 0.169991616, 	/* 56 57 58 59 */
+   0.169293808, 0.168613099, 0.167948779, 0.167300179, 	/* 60 61 62 63 */
+   0.166666667
+};
diff --git a/libtommath/mtest/mpi-config.h b/libtommath/mtest/mpi-config.h
new file mode 100644
index 0000000..a347263
--- /dev/null
+++ b/libtommath/mtest/mpi-config.h
@@ -0,0 +1,85 @@
+/* Default configuration for MPI library */
+
+#ifndef MPI_CONFIG_H_
+#define MPI_CONFIG_H_
+
+/*
+  For boolean options, 
+  0 = no
+  1 = yes
+
+  Other options are documented individually.
+
+ */
+
+#ifndef MP_IOFUNC
+#define MP_IOFUNC     0  /* include mp_print() ?                */
+#endif
+
+#ifndef MP_MODARITH
+#define MP_MODARITH   1  /* include modular arithmetic ?        */
+#endif
+
+#ifndef MP_NUMTH
+#define MP_NUMTH      1  /* include number theoretic functions? */
+#endif
+
+#ifndef MP_LOGTAB
+#define MP_LOGTAB     1  /* use table of logs instead of log()? */
+#endif
+
+#ifndef MP_MEMSET
+#define MP_MEMSET     1  /* use memset() to zero buffers?       */
+#endif
+
+#ifndef MP_MEMCPY
+#define MP_MEMCPY     1  /* use memcpy() to copy buffers?       */
+#endif
+
+#ifndef MP_CRYPTO
+#define MP_CRYPTO     1  /* erase memory on free?               */
+#endif
+
+#ifndef MP_ARGCHK
+/*
+  0 = no parameter checks
+  1 = runtime checks, continue execution and return an error to caller
+  2 = assertions; dump core on parameter errors
+ */
+#define MP_ARGCHK     2  /* how to check input arguments        */
+#endif
+
+#ifndef MP_DEBUG
+#define MP_DEBUG      0  /* print diagnostic output?            */
+#endif
+
+#ifndef MP_DEFPREC
+#define MP_DEFPREC    64 /* default precision, in digits        */
+#endif
+
+#ifndef MP_MACRO
+#define MP_MACRO      1  /* use macros for frequent calls?      */
+#endif
+
+#ifndef MP_SQUARE
+#define MP_SQUARE     1  /* use separate squaring code?         */
+#endif
+
+#ifndef MP_PTAB_SIZE
+/*
+  When building mpprime.c, we build in a table of small prime
+  values to use for primality testing.  The more you include,
+  the more space they take up.  See primes.c for the possible
+  values (currently 16, 32, 64, 128, 256, and 6542)
+ */
+#define MP_PTAB_SIZE  128  /* how many built-in primes?         */
+#endif
+
+#ifndef MP_COMPAT_MACROS
+#define MP_COMPAT_MACROS 1   /* define compatibility macros?    */
+#endif
+
+#endif /* ifndef MPI_CONFIG_H_ */
+
+
+/* crc==3287762869, version==2, Sat Feb 02 06:43:53 2002 */
diff --git a/libtommath/mtest/mpi-types.h b/libtommath/mtest/mpi-types.h
new file mode 100644
index 0000000..42ccfc3
--- /dev/null
+++ b/libtommath/mtest/mpi-types.h
@@ -0,0 +1,15 @@
+/* Type definitions generated by 'types.pl' */
+typedef char               mp_sign;
+typedef unsigned short     mp_digit;  /* 2 byte type */
+typedef unsigned int       mp_word;   /* 4 byte type */
+typedef unsigned int       mp_size;
+typedef int                mp_err;
+
+#define MP_DIGIT_BIT       (CHAR_BIT*sizeof(mp_digit))
+#define MP_DIGIT_MAX       USHRT_MAX
+#define MP_WORD_BIT        (CHAR_BIT*sizeof(mp_word))
+#define MP_WORD_MAX        UINT_MAX
+
+#define MP_DIGIT_SIZE      2
+#define DIGIT_FMT          "%04X"
+#define RADIX              (MP_DIGIT_MAX+1)
diff --git a/libtommath/mtest/mpi.c b/libtommath/mtest/mpi.c
new file mode 100644
index 0000000..4566e89
--- /dev/null
+++ b/libtommath/mtest/mpi.c
@@ -0,0 +1,3979 @@
+/*
+    mpi.c
+
+    by Michael J. Fromberger <sting@linguist.dartmouth.edu>
+    Copyright (C) 1998 Michael J. Fromberger, All Rights Reserved
+
+    Arbitrary precision integer arithmetic library
+ */
+
+#include "mpi.h"
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+
+#if MP_DEBUG
+#include <stdio.h>
+
+#define DIAG(T,V) {fprintf(stderr,T);mp_print(V,stderr);fputc('\n',stderr);}
+#else
+#define DIAG(T,V)
+#endif
+
+/* 
+   If MP_LOGTAB is not defined, use the math library to compute the
+   logarithms on the fly.  Otherwise, use the static table below.
+   Pick which works best for your system.
+ */
+#if MP_LOGTAB
+
+/* {{{ s_logv_2[] - log table for 2 in various bases */
+
+/*
+  A table of the logs of 2 for various bases (the 0 and 1 entries of
+  this table are meaningless and should not be referenced).  
+
+  This table is used to compute output lengths for the mp_toradix()
+  function.  Since a number n in radix r takes up about log_r(n)
+  digits, we estimate the output size by taking the least integer
+  greater than log_r(n), where:
+
+  log_r(n) = log_2(n) * log_r(2)
+
+  This table, therefore, is a table of log_r(2) for 2 <= r <= 36,
+  which are the output bases supported.  
+ */
+
+#include "logtab.h"
+
+/* }}} */
+#define LOG_V_2(R)  s_logv_2[(R)]
+
+#else
+
+#include <math.h>
+#define LOG_V_2(R)  (log(2.0)/log(R))
+
+#endif
+
+/* Default precision for newly created mp_int's      */
+static unsigned int s_mp_defprec = MP_DEFPREC;
+
+/* {{{ Digit arithmetic macros */
+
+/*
+  When adding and multiplying digits, the results can be larger than
+  can be contained in an mp_digit.  Thus, an mp_word is used.  These
+  macros mask off the upper and lower digits of the mp_word (the
+  mp_word may be more than 2 mp_digits wide, but we only concern
+  ourselves with the low-order 2 mp_digits)
+
+  If your mp_word DOES have more than 2 mp_digits, you need to
+  uncomment the first line, and comment out the second.
+ */
+
+/* #define  CARRYOUT(W)  (((W)>>DIGIT_BIT)&MP_DIGIT_MAX) */
+#define  CARRYOUT(W)  ((W)>>DIGIT_BIT)
+#define  ACCUM(W)     ((W)&MP_DIGIT_MAX)
+
+/* }}} */
+
+/* {{{ Comparison constants */
+
+#define  MP_LT       -1
+#define  MP_EQ        0
+#define  MP_GT        1
+
+/* }}} */
+
+/* {{{ Constant strings */
+
+/* Constant strings returned by mp_strerror() */
+static const char *const mp_err_string[] = {
+  "unknown result code",     /* say what?            */
+  "boolean true",            /* MP_OKAY, MP_YES      */
+  "boolean false",           /* MP_NO                */
+  "out of memory",           /* MP_MEM               */
+  "argument out of range",   /* MP_RANGE             */
+  "invalid input parameter", /* MP_BADARG            */
+  "result is undefined"      /* MP_UNDEF             */
+};
+
+/* Value to digit maps for radix conversion   */
+
+/* s_dmap_1 - standard digits and letters */
+static const char *s_dmap_1 = 
+  "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/";
+
+#if 0
+/* s_dmap_2 - base64 ordering for digits  */
+static const char *s_dmap_2 =
+  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+#endif
+
+/* }}} */
+
+/* {{{ Static function declarations */
+
+/* 
+   If MP_MACRO is false, these will be defined as actual functions;
+   otherwise, suitable macro definitions will be used.  This works
+   around the fact that ANSI C89 doesn't support an 'inline' keyword
+   (although I hear C9x will ... about bloody time).  At present, the
+   macro definitions are identical to the function bodies, but they'll
+   expand in place, instead of generating a function call.
+
+   I chose these particular functions to be made into macros because
+   some profiling showed they are called a lot on a typical workload,
+   and yet they are primarily housekeeping.
+ */
+#if MP_MACRO == 0
+ void     s_mp_setz(mp_digit *dp, mp_size count); /* zero digits           */
+ void     s_mp_copy(mp_digit *sp, mp_digit *dp, mp_size count); /* copy    */
+ void    *s_mp_alloc(size_t nb, size_t ni);       /* general allocator     */
+ void     s_mp_free(void *ptr);                   /* general free function */
+#else
+
+ /* Even if these are defined as macros, we need to respect the settings
+    of the MP_MEMSET and MP_MEMCPY configuration options...
+  */
+ #if MP_MEMSET == 0
+  #define  s_mp_setz(dp, count) \
+       {int ix;for(ix=0;ix<(count);ix++)(dp)[ix]=0;}
+ #else
+  #define  s_mp_setz(dp, count) memset(dp, 0, (count) * sizeof(mp_digit))
+ #endif /* MP_MEMSET */
+
+ #if MP_MEMCPY == 0
+  #define  s_mp_copy(sp, dp, count) \
+       {int ix;for(ix=0;ix<(count);ix++)(dp)[ix]=(sp)[ix];}
+ #else
+  #define  s_mp_copy(sp, dp, count) memcpy(dp, sp, (count) * sizeof(mp_digit))
+ #endif /* MP_MEMCPY */
+
+ #define  s_mp_alloc(nb, ni)  calloc(nb, ni)
+ #define  s_mp_free(ptr) {if(ptr) free(ptr);}
+#endif /* MP_MACRO */
+
+mp_err   s_mp_grow(mp_int *mp, mp_size min);   /* increase allocated size */
+mp_err   s_mp_pad(mp_int *mp, mp_size min);    /* left pad with zeroes    */
+
+void     s_mp_clamp(mp_int *mp);               /* clip leading zeroes     */
+
+void     s_mp_exch(mp_int *a, mp_int *b);      /* swap a and b in place   */
+
+mp_err   s_mp_lshd(mp_int *mp, mp_size p);     /* left-shift by p digits  */
+void     s_mp_rshd(mp_int *mp, mp_size p);     /* right-shift by p digits */
+void     s_mp_div_2d(mp_int *mp, mp_digit d);  /* divide by 2^d in place  */
+void     s_mp_mod_2d(mp_int *mp, mp_digit d);  /* modulo 2^d in place     */
+mp_err   s_mp_mul_2d(mp_int *mp, mp_digit d);  /* multiply by 2^d in place*/
+void     s_mp_div_2(mp_int *mp);               /* divide by 2 in place    */
+mp_err   s_mp_mul_2(mp_int *mp);               /* multiply by 2 in place  */
+mp_digit s_mp_norm(mp_int *a, mp_int *b);      /* normalize for division  */
+mp_err   s_mp_add_d(mp_int *mp, mp_digit d);   /* unsigned digit addition */
+mp_err   s_mp_sub_d(mp_int *mp, mp_digit d);   /* unsigned digit subtract */
+mp_err   s_mp_mul_d(mp_int *mp, mp_digit d);   /* unsigned digit multiply */
+mp_err   s_mp_div_d(mp_int *mp, mp_digit d, mp_digit *r);
+		                               /* unsigned digit divide   */
+mp_err   s_mp_reduce(mp_int *x, mp_int *m, mp_int *mu);
+                                               /* Barrett reduction       */
+mp_err   s_mp_add(mp_int *a, mp_int *b);       /* magnitude addition      */
+mp_err   s_mp_sub(mp_int *a, mp_int *b);       /* magnitude subtract      */
+mp_err   s_mp_mul(mp_int *a, mp_int *b);       /* magnitude multiply      */
+#if 0
+void     s_mp_kmul(mp_digit *a, mp_digit *b, mp_digit *out, mp_size len);
+                                               /* multiply buffers in place */
+#endif
+#if MP_SQUARE
+mp_err   s_mp_sqr(mp_int *a);                  /* magnitude square        */
+#else
+#define  s_mp_sqr(a) s_mp_mul(a, a)
+#endif
+mp_err   s_mp_div(mp_int *a, mp_int *b);       /* magnitude divide        */
+mp_err   s_mp_2expt(mp_int *a, mp_digit k);    /* a = 2^k                 */
+int      s_mp_cmp(mp_int *a, mp_int *b);       /* magnitude comparison    */
+int      s_mp_cmp_d(mp_int *a, mp_digit d);    /* magnitude digit compare */
+int      s_mp_ispow2(mp_int *v);               /* is v a power of 2?      */
+int      s_mp_ispow2d(mp_digit d);             /* is d a power of 2?      */
+
+int      s_mp_tovalue(char ch, int r);          /* convert ch to value    */
+char     s_mp_todigit(int val, int r, int low); /* convert val to digit   */
+int      s_mp_outlen(int bits, int r);          /* output length in bytes */
+
+/* }}} */
+
+/* {{{ Default precision manipulation */
+
+unsigned int mp_get_prec(void)
+{
+  return s_mp_defprec;
+
+} /* end mp_get_prec() */
+
+void         mp_set_prec(unsigned int prec)
+{
+  if(prec == 0)
+    s_mp_defprec = MP_DEFPREC;
+  else
+    s_mp_defprec = prec;
+
+} /* end mp_set_prec() */
+
+/* }}} */
+
+/*------------------------------------------------------------------------*/
+/* {{{ mp_init(mp) */
+
+/*
+  mp_init(mp)
+
+  Initialize a new zero-valued mp_int.  Returns MP_OKAY if successful,
+  MP_MEM if memory could not be allocated for the structure.
+ */
+
+mp_err mp_init(mp_int *mp)
+{
+  return mp_init_size(mp, s_mp_defprec);
+
+} /* end mp_init() */
+
+/* }}} */
+
+/* {{{ mp_init_array(mp[], count) */
+
+mp_err mp_init_array(mp_int mp[], int count)
+{
+  mp_err  res;
+  int     pos;
+
+  ARGCHK(mp !=NULL && count > 0, MP_BADARG);
+
+  for(pos = 0; pos < count; ++pos) {
+    if((res = mp_init(&mp[pos])) != MP_OKAY)
+      goto CLEANUP;
+  }
+
+  return MP_OKAY;
+
+ CLEANUP:
+  while(--pos >= 0) 
+    mp_clear(&mp[pos]);
+
+  return res;
+
+} /* end mp_init_array() */
+
+/* }}} */
+
+/* {{{ mp_init_size(mp, prec) */
+
+/*
+  mp_init_size(mp, prec)
+
+  Initialize a new zero-valued mp_int with at least the given
+  precision; returns MP_OKAY if successful, or MP_MEM if memory could
+  not be allocated for the structure.
+ */
+
+mp_err mp_init_size(mp_int *mp, mp_size prec)
+{
+  ARGCHK(mp != NULL && prec > 0, MP_BADARG);
+
+  if((DIGITS(mp) = s_mp_alloc(prec, sizeof(mp_digit))) == NULL)
+    return MP_MEM;
+
+  SIGN(mp) = MP_ZPOS;
+  USED(mp) = 1;
+  ALLOC(mp) = prec;
+
+  return MP_OKAY;
+
+} /* end mp_init_size() */
+
+/* }}} */
+
+/* {{{ mp_init_copy(mp, from) */
+
+/*
+  mp_init_copy(mp, from)
+
+  Initialize mp as an exact copy of from.  Returns MP_OKAY if
+  successful, MP_MEM if memory could not be allocated for the new
+  structure.
+ */
+
+mp_err mp_init_copy(mp_int *mp, mp_int *from)
+{
+  ARGCHK(mp != NULL && from != NULL, MP_BADARG);
+
+  if(mp == from)
+    return MP_OKAY;
+
+  if((DIGITS(mp) = s_mp_alloc(USED(from), sizeof(mp_digit))) == NULL)
+    return MP_MEM;
+
+  s_mp_copy(DIGITS(from), DIGITS(mp), USED(from));
+  USED(mp) = USED(from);
+  ALLOC(mp) = USED(from);
+  SIGN(mp) = SIGN(from);
+
+  return MP_OKAY;
+
+} /* end mp_init_copy() */
+
+/* }}} */
+
+/* {{{ mp_copy(from, to) */
+
+/*
+  mp_copy(from, to)
+
+  Copies the mp_int 'from' to the mp_int 'to'.  It is presumed that
+  'to' has already been initialized (if not, use mp_init_copy()
+  instead). If 'from' and 'to' are identical, nothing happens.
+ */
+
+mp_err mp_copy(mp_int *from, mp_int *to)
+{
+  ARGCHK(from != NULL && to != NULL, MP_BADARG);
+
+  if(from == to)
+    return MP_OKAY;
+
+  { /* copy */
+    mp_digit   *tmp;
+
+    /*
+      If the allocated buffer in 'to' already has enough space to hold
+      all the used digits of 'from', we'll re-use it to avoid hitting
+      the memory allocater more than necessary; otherwise, we'd have
+      to grow anyway, so we just allocate a hunk and make the copy as
+      usual
+     */
+    if(ALLOC(to) >= USED(from)) {
+      s_mp_setz(DIGITS(to) + USED(from), ALLOC(to) - USED(from));
+      s_mp_copy(DIGITS(from), DIGITS(to), USED(from));
+      
+    } else {
+      if((tmp = s_mp_alloc(USED(from), sizeof(mp_digit))) == NULL)
+	return MP_MEM;
+
+      s_mp_copy(DIGITS(from), tmp, USED(from));
+
+      if(DIGITS(to) != NULL) {
+#if MP_CRYPTO
+	s_mp_setz(DIGITS(to), ALLOC(to));
+#endif
+	s_mp_free(DIGITS(to));
+      }
+
+      DIGITS(to) = tmp;
+      ALLOC(to) = USED(from);
+    }
+
+    /* Copy the precision and sign from the original */
+    USED(to) = USED(from);
+    SIGN(to) = SIGN(from);
+  } /* end copy */
+
+  return MP_OKAY;
+
+} /* end mp_copy() */
+
+/* }}} */
+
+/* {{{ mp_exch(mp1, mp2) */
+
+/*
+  mp_exch(mp1, mp2)
+
+  Exchange mp1 and mp2 without allocating any intermediate memory
+  (well, unless you count the stack space needed for this call and the
+  locals it creates...).  This cannot fail.
+ */
+
+void mp_exch(mp_int *mp1, mp_int *mp2)
+{
+#if MP_ARGCHK == 2
+  assert(mp1 != NULL && mp2 != NULL);
+#else
+  if(mp1 == NULL || mp2 == NULL)
+    return;
+#endif
+
+  s_mp_exch(mp1, mp2);
+
+} /* end mp_exch() */
+
+/* }}} */
+
+/* {{{ mp_clear(mp) */
+
+/*
+  mp_clear(mp)
+
+  Release the storage used by an mp_int, and void its fields so that
+  if someone calls mp_clear() again for the same int later, we won't
+  get tollchocked.
+ */
+
+void   mp_clear(mp_int *mp)
+{
+  if(mp == NULL)
+    return;
+
+  if(DIGITS(mp) != NULL) {
+#if MP_CRYPTO
+    s_mp_setz(DIGITS(mp), ALLOC(mp));
+#endif
+    s_mp_free(DIGITS(mp));
+    DIGITS(mp) = NULL;
+  }
+
+  USED(mp) = 0;
+  ALLOC(mp) = 0;
+
+} /* end mp_clear() */
+
+/* }}} */
+
+/* {{{ mp_clear_array(mp[], count) */
+
+void   mp_clear_array(mp_int mp[], int count)
+{
+  ARGCHK(mp != NULL && count > 0, MP_BADARG);
+
+  while(--count >= 0) 
+    mp_clear(&mp[count]);
+
+} /* end mp_clear_array() */
+
+/* }}} */
+
+/* {{{ mp_zero(mp) */
+
+/*
+  mp_zero(mp) 
+
+  Set mp to zero.  Does not change the allocated size of the structure,
+  and therefore cannot fail (except on a bad argument, which we ignore)
+ */
+void   mp_zero(mp_int *mp)
+{
+  if(mp == NULL)
+    return;
+
+  s_mp_setz(DIGITS(mp), ALLOC(mp));
+  USED(mp) = 1;
+  SIGN(mp) = MP_ZPOS;
+
+} /* end mp_zero() */
+
+/* }}} */
+
+/* {{{ mp_set(mp, d) */
+
+void   mp_set(mp_int *mp, mp_digit d)
+{
+  if(mp == NULL)
+    return;
+
+  mp_zero(mp);
+  DIGIT(mp, 0) = d;
+
+} /* end mp_set() */
+
+/* }}} */
+
+/* {{{ mp_set_int(mp, z) */
+
+mp_err mp_set_int(mp_int *mp, long z)
+{
+  int            ix;
+  unsigned long  v = abs(z);
+  mp_err         res;
+
+  ARGCHK(mp != NULL, MP_BADARG);
+
+  mp_zero(mp);
+  if(z == 0)
+    return MP_OKAY;  /* shortcut for zero */
+
+  for(ix = sizeof(long) - 1; ix >= 0; ix--) {
+
+    if((res = s_mp_mul_2d(mp, CHAR_BIT)) != MP_OKAY)
+      return res;
+
+    res = s_mp_add_d(mp, 
+		     (mp_digit)((v >> (ix * CHAR_BIT)) & UCHAR_MAX));
+    if(res != MP_OKAY)
+      return res;
+
+  }
+
+  if(z < 0)
+    SIGN(mp) = MP_NEG;
+
+  return MP_OKAY;
+
+} /* end mp_set_int() */
+
+/* }}} */
+
+/*------------------------------------------------------------------------*/
+/* {{{ Digit arithmetic */
+
+/* {{{ mp_add_d(a, d, b) */
+
+/*
+  mp_add_d(a, d, b)
+
+  Compute the sum b = a + d, for a single digit d.  Respects the sign of
+  its primary addend (single digits are unsigned anyway).
+ */
+
+mp_err mp_add_d(mp_int *a, mp_digit d, mp_int *b)
+{
+  mp_err   res = MP_OKAY;
+
+  ARGCHK(a != NULL && b != NULL, MP_BADARG);
+
+  if((res = mp_copy(a, b)) != MP_OKAY)
+    return res;
+
+  if(SIGN(b) == MP_ZPOS) {
+    res = s_mp_add_d(b, d);
+  } else if(s_mp_cmp_d(b, d) >= 0) {
+    res = s_mp_sub_d(b, d);
+  } else {
+    SIGN(b) = MP_ZPOS;
+
+    DIGIT(b, 0) = d - DIGIT(b, 0);
+  }
+
+  return res;
+
+} /* end mp_add_d() */
+
+/* }}} */
+
+/* {{{ mp_sub_d(a, d, b) */
+
+/*
+  mp_sub_d(a, d, b)
+
+  Compute the difference b = a - d, for a single digit d.  Respects the
+  sign of its subtrahend (single digits are unsigned anyway).
+ */
+
+mp_err mp_sub_d(mp_int *a, mp_digit d, mp_int *b)
+{
+  mp_err   res;
+
+  ARGCHK(a != NULL && b != NULL, MP_BADARG);
+
+  if((res = mp_copy(a, b)) != MP_OKAY)
+    return res;
+
+  if(SIGN(b) == MP_NEG) {
+    if((res = s_mp_add_d(b, d)) != MP_OKAY)
+      return res;
+
+  } else if(s_mp_cmp_d(b, d) >= 0) {
+    if((res = s_mp_sub_d(b, d)) != MP_OKAY)
+      return res;
+
+  } else {
+    mp_neg(b, b);
+
+    DIGIT(b, 0) = d - DIGIT(b, 0);
+    SIGN(b) = MP_NEG;
+  }
+
+  if(s_mp_cmp_d(b, 0) == 0)
+    SIGN(b) = MP_ZPOS;
+
+  return MP_OKAY;
+
+} /* end mp_sub_d() */
+
+/* }}} */
+
+/* {{{ mp_mul_d(a, d, b) */
+
+/*
+  mp_mul_d(a, d, b)
+
+  Compute the product b = a * d, for a single digit d.  Respects the sign
+  of its multiplicand (single digits are unsigned anyway)
+ */
+
+mp_err mp_mul_d(mp_int *a, mp_digit d, mp_int *b)
+{
+  mp_err  res;
+
+  ARGCHK(a != NULL && b != NULL, MP_BADARG);
+
+  if(d == 0) {
+    mp_zero(b);
+    return MP_OKAY;
+  }
+
+  if((res = mp_copy(a, b)) != MP_OKAY)
+    return res;
+
+  res = s_mp_mul_d(b, d);
+
+  return res;
+
+} /* end mp_mul_d() */
+
+/* }}} */
+
+/* {{{ mp_mul_2(a, c) */
+
+mp_err mp_mul_2(mp_int *a, mp_int *c)
+{
+  mp_err  res;
+
+  ARGCHK(a != NULL && c != NULL, MP_BADARG);
+
+  if((res = mp_copy(a, c)) != MP_OKAY)
+    return res;
+
+  return s_mp_mul_2(c);
+
+} /* end mp_mul_2() */
+
+/* }}} */
+
+/* {{{ mp_div_d(a, d, q, r) */
+
+/*
+  mp_div_d(a, d, q, r)
+
+  Compute the quotient q = a / d and remainder r = a mod d, for a
+  single digit d.  Respects the sign of its divisor (single digits are
+  unsigned anyway).
+ */
+
+mp_err mp_div_d(mp_int *a, mp_digit d, mp_int *q, mp_digit *r)
+{
+  mp_err   res;
+  mp_digit rem;
+  int      pow;
+
+  ARGCHK(a != NULL, MP_BADARG);
+
+  if(d == 0)
+    return MP_RANGE;
+
+  /* Shortcut for powers of two ... */
+  if((pow = s_mp_ispow2d(d)) >= 0) {
+    mp_digit  mask;
+
+    mask = (1 << pow) - 1;
+    rem = DIGIT(a, 0) & mask;
+
+    if(q) {
+      mp_copy(a, q);
+      s_mp_div_2d(q, pow);
+    }
+
+    if(r)
+      *r = rem;
+
+    return MP_OKAY;
+  }
+
+  /*
+    If the quotient is actually going to be returned, we'll try to
+    avoid hitting the memory allocator by copying the dividend into it
+    and doing the division there.  This can't be any _worse_ than
+    always copying, and will sometimes be better (since it won't make
+    another copy)
+
+    If it's not going to be returned, we need to allocate a temporary
+    to hold the quotient, which will just be discarded.
+   */
+  if(q) {
+    if((res = mp_copy(a, q)) != MP_OKAY)
+      return res;
+
+    res = s_mp_div_d(q, d, &rem);
+    if(s_mp_cmp_d(q, 0) == MP_EQ)
+      SIGN(q) = MP_ZPOS;
+
+  } else {
+    mp_int  qp;
+
+    if((res = mp_init_copy(&qp, a)) != MP_OKAY)
+      return res;
+
+    res = s_mp_div_d(&qp, d, &rem);
+    if(s_mp_cmp_d(&qp, 0) == 0)
+      SIGN(&qp) = MP_ZPOS;
+
+    mp_clear(&qp);
+  }
+
+  if(r)
+    *r = rem;
+
+  return res;
+
+} /* end mp_div_d() */
+
+/* }}} */
+
+/* {{{ mp_div_2(a, c) */
+
+/*
+  mp_div_2(a, c)
+
+  Compute c = a / 2, disregarding the remainder.
+ */
+
+mp_err mp_div_2(mp_int *a, mp_int *c)
+{
+  mp_err  res;
+
+  ARGCHK(a != NULL && c != NULL, MP_BADARG);
+
+  if((res = mp_copy(a, c)) != MP_OKAY)
+    return res;
+
+  s_mp_div_2(c);
+
+  return MP_OKAY;
+
+} /* end mp_div_2() */
+
+/* }}} */
+
+/* {{{ mp_expt_d(a, d, b) */
+
+mp_err mp_expt_d(mp_int *a, mp_digit d, mp_int *c)
+{
+  mp_int   s, x;
+  mp_err   res;
+
+  ARGCHK(a != NULL && c != NULL, MP_BADARG);
+
+  if((res = mp_init(&s)) != MP_OKAY)
+    return res;
+  if((res = mp_init_copy(&x, a)) != MP_OKAY)
+    goto X;
+
+  DIGIT(&s, 0) = 1;
+
+  while(d != 0) {
+    if(d & 1) {
+      if((res = s_mp_mul(&s, &x)) != MP_OKAY)
+	goto CLEANUP;
+    }
+
+    d >>= 1;
+
+    if((res = s_mp_sqr(&x)) != MP_OKAY)
+      goto CLEANUP;
+  }
+
+  s_mp_exch(&s, c);
+
+CLEANUP:
+  mp_clear(&x);
+X:
+  mp_clear(&s);
+
+  return res;
+
+} /* end mp_expt_d() */
+
+/* }}} */
+
+/* }}} */
+
+/*------------------------------------------------------------------------*/
+/* {{{ Full arithmetic */
+
+/* {{{ mp_abs(a, b) */
+
+/*
+  mp_abs(a, b)
+
+  Compute b = |a|.  'a' and 'b' may be identical.
+ */
+
+mp_err mp_abs(mp_int *a, mp_int *b)
+{
+  mp_err   res;
+
+  ARGCHK(a != NULL && b != NULL, MP_BADARG);
+
+  if((res = mp_copy(a, b)) != MP_OKAY)
+    return res;
+
+  SIGN(b) = MP_ZPOS;
+
+  return MP_OKAY;
+
+} /* end mp_abs() */
+
+/* }}} */
+
+/* {{{ mp_neg(a, b) */
+
+/*
+  mp_neg(a, b)
+
+  Compute b = -a.  'a' and 'b' may be identical.
+ */
+
+mp_err mp_neg(mp_int *a, mp_int *b)
+{
+  mp_err   res;
+
+  ARGCHK(a != NULL && b != NULL, MP_BADARG);
+
+  if((res = mp_copy(a, b)) != MP_OKAY)
+    return res;
+
+  if(s_mp_cmp_d(b, 0) == MP_EQ) 
+    SIGN(b) = MP_ZPOS;
+  else 
+    SIGN(b) = (SIGN(b) == MP_NEG) ? MP_ZPOS : MP_NEG;
+
+  return MP_OKAY;
+
+} /* end mp_neg() */
+
+/* }}} */
+
+/* {{{ mp_add(a, b, c) */
+
+/*
+  mp_add(a, b, c)
+
+  Compute c = a + b.  All parameters may be identical.
+ */
+
+mp_err mp_add(mp_int *a, mp_int *b, mp_int *c)
+{
+  mp_err  res;
+  int     cmp;
+
+  ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);
+
+  if(SIGN(a) == SIGN(b)) { /* same sign:  add values, keep sign */
+
+    /* Commutativity of addition lets us do this in either order,
+       so we avoid having to use a temporary even if the result 
+       is supposed to replace the output
+     */
+    if(c == b) {
+      if((res = s_mp_add(c, a)) != MP_OKAY)
+	return res;
+    } else {
+      if(c != a && (res = mp_copy(a, c)) != MP_OKAY)
+	return res;
+
+      if((res = s_mp_add(c, b)) != MP_OKAY) 
+	return res;
+    }
+
+  } else if((cmp = s_mp_cmp(a, b)) > 0) {  /* different sign: a > b   */
+
+    /* If the output is going to be clobbered, we will use a temporary
+       variable; otherwise, we'll do it without touching the memory 
+       allocator at all, if possible
+     */
+    if(c == b) {
+      mp_int  tmp;
+
+      if((res = mp_init_copy(&tmp, a)) != MP_OKAY)
+	return res;
+      if((res = s_mp_sub(&tmp, b)) != MP_OKAY) {
+	mp_clear(&tmp);
+	return res;
+      }
+
+      s_mp_exch(&tmp, c);
+      mp_clear(&tmp);
+
+    } else {
+
+      if(c != a && (res = mp_copy(a, c)) != MP_OKAY)
+	return res;
+      if((res = s_mp_sub(c, b)) != MP_OKAY)
+	return res;
+
+    }
+
+  } else if(cmp == 0) {             /* different sign, a == b   */
+
+    mp_zero(c);
+    return MP_OKAY;
+
+  } else {                          /* different sign: a < b    */
+
+    /* See above... */
+    if(c == a) {
+      mp_int  tmp;
+
+      if((res = mp_init_copy(&tmp, b)) != MP_OKAY)
+	return res;
+      if((res = s_mp_sub(&tmp, a)) != MP_OKAY) {
+	mp_clear(&tmp);
+	return res;
+      }
+
+      s_mp_exch(&tmp, c);
+      mp_clear(&tmp);
+
+    } else {
+
+      if(c != b && (res = mp_copy(b, c)) != MP_OKAY)
+	return res;
+      if((res = s_mp_sub(c, a)) != MP_OKAY)
+	return res;
+
+    }
+  }
+
+  if(USED(c) == 1 && DIGIT(c, 0) == 0)
+    SIGN(c) = MP_ZPOS;
+
+  return MP_OKAY;
+
+} /* end mp_add() */
+
+/* }}} */
+
+/* {{{ mp_sub(a, b, c) */
+
+/*
+  mp_sub(a, b, c)
+
+  Compute c = a - b.  All parameters may be identical.
+ */
+
+mp_err mp_sub(mp_int *a, mp_int *b, mp_int *c)
+{
+  mp_err  res;
+  int     cmp;
+
+  ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);
+
+  if(SIGN(a) != SIGN(b)) {
+    if(c == a) {
+      if((res = s_mp_add(c, b)) != MP_OKAY)
+	return res;
+    } else {
+      if(c != b && ((res = mp_copy(b, c)) != MP_OKAY))
+	return res;
+      if((res = s_mp_add(c, a)) != MP_OKAY)
+	return res;
+      SIGN(c) = SIGN(a);
+    }
+
+  } else if((cmp = s_mp_cmp(a, b)) > 0) { /* Same sign, a > b */
+    if(c == b) {
+      mp_int  tmp;
+
+      if((res = mp_init_copy(&tmp, a)) != MP_OKAY)
+	return res;
+      if((res = s_mp_sub(&tmp, b)) != MP_OKAY) {
+	mp_clear(&tmp);
+	return res;
+      }
+      s_mp_exch(&tmp, c);
+      mp_clear(&tmp);
+
+    } else {
+      if(c != a && ((res = mp_copy(a, c)) != MP_OKAY))
+	return res;
+
+      if((res = s_mp_sub(c, b)) != MP_OKAY)
+	return res;
+    }
+
+  } else if(cmp == 0) {  /* Same sign, equal magnitude */
+    mp_zero(c);
+    return MP_OKAY;
+
+  } else {               /* Same sign, b > a */
+    if(c == a) {
+      mp_int  tmp;
+
+      if((res = mp_init_copy(&tmp, b)) != MP_OKAY)
+	return res;
+
+      if((res = s_mp_sub(&tmp, a)) != MP_OKAY) {
+	mp_clear(&tmp);
+	return res;
+      }
+      s_mp_exch(&tmp, c);
+      mp_clear(&tmp);
+
+    } else {
+      if(c != b && ((res = mp_copy(b, c)) != MP_OKAY)) 
+	return res;
+
+      if((res = s_mp_sub(c, a)) != MP_OKAY)
+	return res;
+    }
+
+    SIGN(c) = !SIGN(b);
+  }
+
+  if(USED(c) == 1 && DIGIT(c, 0) == 0)
+    SIGN(c) = MP_ZPOS;
+
+  return MP_OKAY;
+
+} /* end mp_sub() */
+
+/* }}} */
+
+/* {{{ mp_mul(a, b, c) */
+
+/*
+  mp_mul(a, b, c)
+
+  Compute c = a * b.  All parameters may be identical.
+ */
+
+mp_err mp_mul(mp_int *a, mp_int *b, mp_int *c)
+{
+  mp_err   res;
+  mp_sign  sgn;
+
+  ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);
+
+  sgn = (SIGN(a) == SIGN(b)) ? MP_ZPOS : MP_NEG;
+
+  if(c == b) {
+    if((res = s_mp_mul(c, a)) != MP_OKAY)
+      return res;
+
+  } else {
+    if((res = mp_copy(a, c)) != MP_OKAY)
+      return res;
+
+    if((res = s_mp_mul(c, b)) != MP_OKAY)
+      return res;
+  }
+  
+  if(sgn == MP_ZPOS || s_mp_cmp_d(c, 0) == MP_EQ)
+    SIGN(c) = MP_ZPOS;
+  else
+    SIGN(c) = sgn;
+  
+  return MP_OKAY;
+
+} /* end mp_mul() */
+
+/* }}} */
+
+/* {{{ mp_mul_2d(a, d, c) */
+
+/*
+  mp_mul_2d(a, d, c)
+
+  Compute c = a * 2^d.  a may be the same as c.
+ */
+
+mp_err mp_mul_2d(mp_int *a, mp_digit d, mp_int *c)
+{
+  mp_err   res;
+
+  ARGCHK(a != NULL && c != NULL, MP_BADARG);
+
+  if((res = mp_copy(a, c)) != MP_OKAY)
+    return res;
+
+  if(d == 0)
+    return MP_OKAY;
+
+  return s_mp_mul_2d(c, d);
+
+} /* end mp_mul() */
+
+/* }}} */
+
+/* {{{ mp_sqr(a, b) */
+
+#if MP_SQUARE
+mp_err mp_sqr(mp_int *a, mp_int *b)
+{
+  mp_err   res;
+
+  ARGCHK(a != NULL && b != NULL, MP_BADARG);
+
+  if((res = mp_copy(a, b)) != MP_OKAY)
+    return res;
+
+  if((res = s_mp_sqr(b)) != MP_OKAY)
+    return res;
+
+  SIGN(b) = MP_ZPOS;
+
+  return MP_OKAY;
+
+} /* end mp_sqr() */
+#endif
+
+/* }}} */
+
+/* {{{ mp_div(a, b, q, r) */
+
+/*
+  mp_div(a, b, q, r)
+
+  Compute q = a / b and r = a mod b.  Input parameters may be re-used
+  as output parameters.  If q or r is NULL, that portion of the
+  computation will be discarded (although it will still be computed)
+
+  Pay no attention to the hacker behind the curtain.
+ */
+
+mp_err mp_div(mp_int *a, mp_int *b, mp_int *q, mp_int *r)
+{
+  mp_err   res;
+  mp_int   qtmp, rtmp;
+  int      cmp;
+
+  ARGCHK(a != NULL && b != NULL, MP_BADARG);
+
+  if(mp_cmp_z(b) == MP_EQ)
+    return MP_RANGE;
+
+  /* If a <= b, we can compute the solution without division, and
+     avoid any memory allocation
+   */
+  if((cmp = s_mp_cmp(a, b)) < 0) {
+    if(r) {
+      if((res = mp_copy(a, r)) != MP_OKAY)
+	return res;
+    }
+
+    if(q) 
+      mp_zero(q);
+
+    return MP_OKAY;
+
+  } else if(cmp == 0) {
+
+    /* Set quotient to 1, with appropriate sign */
+    if(q) {
+      int qneg = (SIGN(a) != SIGN(b));
+
+      mp_set(q, 1);
+      if(qneg)
+	SIGN(q) = MP_NEG;
+    }
+
+    if(r)
+      mp_zero(r);
+
+    return MP_OKAY;
+  }
+
+  /* If we get here, it means we actually have to do some division */
+
+  /* Set up some temporaries... */
+  if((res = mp_init_copy(&qtmp, a)) != MP_OKAY)
+    return res;
+  if((res = mp_init_copy(&rtmp, b)) != MP_OKAY)
+    goto CLEANUP;
+
+  if((res = s_mp_div(&qtmp, &rtmp)) != MP_OKAY)
+    goto CLEANUP;
+
+  /* Compute the signs for the output  */
+  SIGN(&rtmp) = SIGN(a); /* Sr = Sa              */
+  if(SIGN(a) == SIGN(b))
+    SIGN(&qtmp) = MP_ZPOS;  /* Sq = MP_ZPOS if Sa = Sb */
+  else
+    SIGN(&qtmp) = MP_NEG;   /* Sq = MP_NEG if Sa != Sb */
+
+  if(s_mp_cmp_d(&qtmp, 0) == MP_EQ)
+    SIGN(&qtmp) = MP_ZPOS;
+  if(s_mp_cmp_d(&rtmp, 0) == MP_EQ)
+    SIGN(&rtmp) = MP_ZPOS;
+
+  /* Copy output, if it is needed      */
+  if(q) 
+    s_mp_exch(&qtmp, q);
+
+  if(r) 
+    s_mp_exch(&rtmp, r);
+
+CLEANUP:
+  mp_clear(&rtmp);
+  mp_clear(&qtmp);
+
+  return res;
+
+} /* end mp_div() */
+
+/* }}} */
+
+/* {{{ mp_div_2d(a, d, q, r) */
+
+mp_err mp_div_2d(mp_int *a, mp_digit d, mp_int *q, mp_int *r)
+{
+  mp_err  res;
+
+  ARGCHK(a != NULL, MP_BADARG);
+
+  if(q) {
+    if((res = mp_copy(a, q)) != MP_OKAY)
+      return res;
+
+    s_mp_div_2d(q, d);
+  }
+
+  if(r) {
+    if((res = mp_copy(a, r)) != MP_OKAY)
+      return res;
+
+    s_mp_mod_2d(r, d);
+  }
+
+  return MP_OKAY;
+
+} /* end mp_div_2d() */
+
+/* }}} */
+
+/* {{{ mp_expt(a, b, c) */
+
+/*
+  mp_expt(a, b, c)
+
+  Compute c = a ** b, that is, raise a to the b power.  Uses a
+  standard iterative square-and-multiply technique.
+ */
+
+mp_err mp_expt(mp_int *a, mp_int *b, mp_int *c)
+{
+  mp_int   s, x;
+  mp_err   res;
+  mp_digit d;
+  int      dig, bit;
+
+  ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);
+
+  if(mp_cmp_z(b) < 0)
+    return MP_RANGE;
+
+  if((res = mp_init(&s)) != MP_OKAY)
+    return res;
+
+  mp_set(&s, 1);
+
+  if((res = mp_init_copy(&x, a)) != MP_OKAY)
+    goto X;
+
+  /* Loop over low-order digits in ascending order */
+  for(dig = 0; dig < (USED(b) - 1); dig++) {
+    d = DIGIT(b, dig);
+
+    /* Loop over bits of each non-maximal digit */
+    for(bit = 0; bit < DIGIT_BIT; bit++) {
+      if(d & 1) {
+	if((res = s_mp_mul(&s, &x)) != MP_OKAY) 
+	  goto CLEANUP;
+      }
+
+      d >>= 1;
+      
+      if((res = s_mp_sqr(&x)) != MP_OKAY)
+	goto CLEANUP;
+    }
+  }
+
+  /* Consider now the last digit... */
+  d = DIGIT(b, dig);
+
+  while(d) {
+    if(d & 1) {
+      if((res = s_mp_mul(&s, &x)) != MP_OKAY)
+	goto CLEANUP;
+    }
+
+    d >>= 1;
+
+    if((res = s_mp_sqr(&x)) != MP_OKAY)
+      goto CLEANUP;
+  }
+  
+  if(mp_iseven(b))
+    SIGN(&s) = SIGN(a);
+
+  res = mp_copy(&s, c);
+
+CLEANUP:
+  mp_clear(&x);
+X:
+  mp_clear(&s);
+
+  return res;
+
+} /* end mp_expt() */
+
+/* }}} */
+
+/* {{{ mp_2expt(a, k) */
+
+/* Compute a = 2^k */
+
+mp_err mp_2expt(mp_int *a, mp_digit k)
+{
+  ARGCHK(a != NULL, MP_BADARG);
+
+  return s_mp_2expt(a, k);
+
+} /* end mp_2expt() */
+
+/* }}} */
+
+/* {{{ mp_mod(a, m, c) */
+
+/*
+  mp_mod(a, m, c)
+
+  Compute c = a (mod m).  Result will always be 0 <= c < m.
+ */
+
+mp_err mp_mod(mp_int *a, mp_int *m, mp_int *c)
+{
+  mp_err  res;
+  int     mag;
+
+  ARGCHK(a != NULL && m != NULL && c != NULL, MP_BADARG);
+
+  if(SIGN(m) == MP_NEG)
+    return MP_RANGE;
+
+  /*
+     If |a| > m, we need to divide to get the remainder and take the
+     absolute value.  
+
+     If |a| < m, we don't need to do any division, just copy and adjust
+     the sign (if a is negative).
+
+     If |a| == m, we can simply set the result to zero.
+
+     This order is intended to minimize the average path length of the
+     comparison chain on common workloads -- the most frequent cases are
+     that |a| != m, so we do those first.
+   */
+  if((mag = s_mp_cmp(a, m)) > 0) {
+    if((res = mp_div(a, m, NULL, c)) != MP_OKAY)
+      return res;
+    
+    if(SIGN(c) == MP_NEG) {
+      if((res = mp_add(c, m, c)) != MP_OKAY)
+	return res;
+    }
+
+  } else if(mag < 0) {
+    if((res = mp_copy(a, c)) != MP_OKAY)
+      return res;
+
+    if(mp_cmp_z(a) < 0) {
+      if((res = mp_add(c, m, c)) != MP_OKAY)
+	return res;
+
+    }
+    
+  } else {
+    mp_zero(c);
+
+  }
+
+  return MP_OKAY;
+
+} /* end mp_mod() */
+
+/* }}} */
+
+/* {{{ mp_mod_d(a, d, c) */
+
+/*
+  mp_mod_d(a, d, c)
+
+  Compute c = a (mod d).  Result will always be 0 <= c < d
+ */
+mp_err mp_mod_d(mp_int *a, mp_digit d, mp_digit *c)
+{
+  mp_err   res;
+  mp_digit rem;
+
+  ARGCHK(a != NULL && c != NULL, MP_BADARG);
+
+  if(s_mp_cmp_d(a, d) > 0) {
+    if((res = mp_div_d(a, d, NULL, &rem)) != MP_OKAY)
+      return res;
+
+  } else {
+    if(SIGN(a) == MP_NEG)
+      rem = d - DIGIT(a, 0);
+    else
+      rem = DIGIT(a, 0);
+  }
+
+  if(c)
+    *c = rem;
+
+  return MP_OKAY;
+
+} /* end mp_mod_d() */
+
+/* }}} */
+
+/* {{{ mp_sqrt(a, b) */
+
+/*
+  mp_sqrt(a, b)
+
+  Compute the integer square root of a, and store the result in b.
+  Uses an integer-arithmetic version of Newton's iterative linear
+  approximation technique to determine this value; the result has the
+  following two properties:
+
+     b^2 <= a
+     (b+1)^2 >= a
+
+  It is a range error to pass a negative value.
+ */
+mp_err mp_sqrt(mp_int *a, mp_int *b)
+{
+  mp_int   x, t;
+  mp_err   res;
+
+  ARGCHK(a != NULL && b != NULL, MP_BADARG);
+
+  /* Cannot take square root of a negative value */
+  if(SIGN(a) == MP_NEG)
+    return MP_RANGE;
+
+  /* Special cases for zero and one, trivial     */
+  if(mp_cmp_d(a, 0) == MP_EQ || mp_cmp_d(a, 1) == MP_EQ) 
+    return mp_copy(a, b);
+    
+  /* Initialize the temporaries we'll use below  */
+  if((res = mp_init_size(&t, USED(a))) != MP_OKAY)
+    return res;
+
+  /* Compute an initial guess for the iteration as a itself */
+  if((res = mp_init_copy(&x, a)) != MP_OKAY)
+    goto X;
+
+s_mp_rshd(&x, (USED(&x)/2)+1);
+mp_add_d(&x, 1, &x);
+
+  for(;;) {
+    /* t = (x * x) - a */
+    mp_copy(&x, &t);      /* can't fail, t is big enough for original x */
+    if((res = mp_sqr(&t, &t)) != MP_OKAY ||
+       (res = mp_sub(&t, a, &t)) != MP_OKAY)
+      goto CLEANUP;
+
+    /* t = t / 2x       */
+    s_mp_mul_2(&x);
+    if((res = mp_div(&t, &x, &t, NULL)) != MP_OKAY)
+      goto CLEANUP;
+    s_mp_div_2(&x);
+
+    /* Terminate the loop, if the quotient is zero */
+    if(mp_cmp_z(&t) == MP_EQ)
+      break;
+
+    /* x = x - t       */
+    if((res = mp_sub(&x, &t, &x)) != MP_OKAY)
+      goto CLEANUP;
+
+  }
+
+  /* Copy result to output parameter */
+  mp_sub_d(&x, 1, &x);
+  s_mp_exch(&x, b);
+
+ CLEANUP:
+  mp_clear(&x);
+ X:
+  mp_clear(&t); 
+
+  return res;
+
+} /* end mp_sqrt() */
+
+/* }}} */
+
+/* }}} */
+
+/*------------------------------------------------------------------------*/
+/* {{{ Modular arithmetic */
+
+#if MP_MODARITH
+/* {{{ mp_addmod(a, b, m, c) */
+
+/*
+  mp_addmod(a, b, m, c)
+
+  Compute c = (a + b) mod m
+ */
+
+mp_err mp_addmod(mp_int *a, mp_int *b, mp_int *m, mp_int *c)
+{
+  mp_err  res;
+
+  ARGCHK(a != NULL && b != NULL && m != NULL && c != NULL, MP_BADARG);
+
+  if((res = mp_add(a, b, c)) != MP_OKAY)
+    return res;
+  if((res = mp_mod(c, m, c)) != MP_OKAY)
+    return res;
+
+  return MP_OKAY;
+
+}
+
+/* }}} */
+
+/* {{{ mp_submod(a, b, m, c) */
+
+/*
+  mp_submod(a, b, m, c)
+
+  Compute c = (a - b) mod m
+ */
+
+mp_err mp_submod(mp_int *a, mp_int *b, mp_int *m, mp_int *c)
+{
+  mp_err  res;
+
+  ARGCHK(a != NULL && b != NULL && m != NULL && c != NULL, MP_BADARG);
+
+  if((res = mp_sub(a, b, c)) != MP_OKAY)
+    return res;
+  if((res = mp_mod(c, m, c)) != MP_OKAY)
+    return res;
+
+  return MP_OKAY;
+
+}
+
+/* }}} */
+
+/* {{{ mp_mulmod(a, b, m, c) */
+
+/*
+  mp_mulmod(a, b, m, c)
+
+  Compute c = (a * b) mod m
+ */
+
+mp_err mp_mulmod(mp_int *a, mp_int *b, mp_int *m, mp_int *c)
+{
+  mp_err  res;
+
+  ARGCHK(a != NULL && b != NULL && m != NULL && c != NULL, MP_BADARG);
+
+  if((res = mp_mul(a, b, c)) != MP_OKAY)
+    return res;
+  if((res = mp_mod(c, m, c)) != MP_OKAY)
+    return res;
+
+  return MP_OKAY;
+
+}
+
+/* }}} */
+
+/* {{{ mp_sqrmod(a, m, c) */
+
+#if MP_SQUARE
+mp_err mp_sqrmod(mp_int *a, mp_int *m, mp_int *c)
+{
+  mp_err  res;
+
+  ARGCHK(a != NULL && m != NULL && c != NULL, MP_BADARG);
+
+  if((res = mp_sqr(a, c)) != MP_OKAY)
+    return res;
+  if((res = mp_mod(c, m, c)) != MP_OKAY)
+    return res;
+
+  return MP_OKAY;
+
+} /* end mp_sqrmod() */
+#endif
+
+/* }}} */
+
+/* {{{ mp_exptmod(a, b, m, c) */
+
+/*
+  mp_exptmod(a, b, m, c)
+
+  Compute c = (a ** b) mod m.  Uses a standard square-and-multiply
+  method with modular reductions at each step. (This is basically the
+  same code as mp_expt(), except for the addition of the reductions)
+  
+  The modular reductions are done using Barrett's algorithm (see
+  s_mp_reduce() below for details)
+ */
+
+mp_err mp_exptmod(mp_int *a, mp_int *b, mp_int *m, mp_int *c)
+{
+  mp_int   s, x, mu;
+  mp_err   res;
+  mp_digit d, *db = DIGITS(b);
+  mp_size  ub = USED(b);
+  int      dig, bit;
+
+  ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);
+
+  if(mp_cmp_z(b) < 0 || mp_cmp_z(m) <= 0)
+    return MP_RANGE;
+
+  if((res = mp_init(&s)) != MP_OKAY)
+    return res;
+  if((res = mp_init_copy(&x, a)) != MP_OKAY)
+    goto X;
+  if((res = mp_mod(&x, m, &x)) != MP_OKAY ||
+     (res = mp_init(&mu)) != MP_OKAY)
+    goto MU;
+
+  mp_set(&s, 1);
+
+  /* mu = b^2k / m */
+  s_mp_add_d(&mu, 1); 
+  s_mp_lshd(&mu, 2 * USED(m));
+  if((res = mp_div(&mu, m, &mu, NULL)) != MP_OKAY)
+    goto CLEANUP;
+
+  /* Loop over digits of b in ascending order, except highest order */
+  for(dig = 0; dig < (ub - 1); dig++) {
+    d = *db++;
+
+    /* Loop over the bits of the lower-order digits */
+    for(bit = 0; bit < DIGIT_BIT; bit++) {
+      if(d & 1) {
+	if((res = s_mp_mul(&s, &x)) != MP_OKAY)
+	  goto CLEANUP;
+	if((res = s_mp_reduce(&s, m, &mu)) != MP_OKAY)
+	  goto CLEANUP;
+      }
+
+      d >>= 1;
+
+      if((res = s_mp_sqr(&x)) != MP_OKAY)
+	goto CLEANUP;
+      if((res = s_mp_reduce(&x, m, &mu)) != MP_OKAY)
+	goto CLEANUP;
+    }
+  }
+
+  /* Now do the last digit... */
+  d = *db;
+
+  while(d) {
+    if(d & 1) {
+      if((res = s_mp_mul(&s, &x)) != MP_OKAY)
+	goto CLEANUP;
+      if((res = s_mp_reduce(&s, m, &mu)) != MP_OKAY)
+	goto CLEANUP;
+    }
+
+    d >>= 1;
+
+    if((res = s_mp_sqr(&x)) != MP_OKAY)
+      goto CLEANUP;
+    if((res = s_mp_reduce(&x, m, &mu)) != MP_OKAY)
+      goto CLEANUP;
+  }
+
+  s_mp_exch(&s, c);
+
+ CLEANUP:
+  mp_clear(&mu);
+ MU:
+  mp_clear(&x);
+ X:
+  mp_clear(&s);
+
+  return res;
+
+} /* end mp_exptmod() */
+
+/* }}} */
+
+/* {{{ mp_exptmod_d(a, d, m, c) */
+
+mp_err mp_exptmod_d(mp_int *a, mp_digit d, mp_int *m, mp_int *c)
+{
+  mp_int   s, x;
+  mp_err   res;
+
+  ARGCHK(a != NULL && c != NULL, MP_BADARG);
+
+  if((res = mp_init(&s)) != MP_OKAY)
+    return res;
+  if((res = mp_init_copy(&x, a)) != MP_OKAY)
+    goto X;
+
+  mp_set(&s, 1);
+
+  while(d != 0) {
+    if(d & 1) {
+      if((res = s_mp_mul(&s, &x)) != MP_OKAY ||
+	 (res = mp_mod(&s, m, &s)) != MP_OKAY)
+	goto CLEANUP;
+    }
+
+    d /= 2;
+
+    if((res = s_mp_sqr(&x)) != MP_OKAY ||
+       (res = mp_mod(&x, m, &x)) != MP_OKAY)
+      goto CLEANUP;
+  }
+
+  s_mp_exch(&s, c);
+
+CLEANUP:
+  mp_clear(&x);
+X:
+  mp_clear(&s);
+
+  return res;
+
+} /* end mp_exptmod_d() */
+
+/* }}} */
+#endif /* if MP_MODARITH */
+
+/* }}} */
+
+/*------------------------------------------------------------------------*/
+/* {{{ Comparison functions */
+
+/* {{{ mp_cmp_z(a) */
+
+/*
+  mp_cmp_z(a)
+
+  Compare a <=> 0.  Returns <0 if a<0, 0 if a=0, >0 if a>0.
+ */
+
+int    mp_cmp_z(mp_int *a)
+{
+  if(SIGN(a) == MP_NEG)
+    return MP_LT;
+  else if(USED(a) == 1 && DIGIT(a, 0) == 0)
+    return MP_EQ;
+  else
+    return MP_GT;
+
+} /* end mp_cmp_z() */
+
+/* }}} */
+
+/* {{{ mp_cmp_d(a, d) */
+
+/*
+  mp_cmp_d(a, d)
+
+  Compare a <=> d.  Returns <0 if a<d, 0 if a=d, >0 if a>d
+ */
+
+int    mp_cmp_d(mp_int *a, mp_digit d)
+{
+  ARGCHK(a != NULL, MP_EQ);
+
+  if(SIGN(a) == MP_NEG)
+    return MP_LT;
+
+  return s_mp_cmp_d(a, d);
+
+} /* end mp_cmp_d() */
+
+/* }}} */
+
+/* {{{ mp_cmp(a, b) */
+
+int    mp_cmp(mp_int *a, mp_int *b)
+{
+  ARGCHK(a != NULL && b != NULL, MP_EQ);
+
+  if(SIGN(a) == SIGN(b)) {
+    int  mag;
+
+    if((mag = s_mp_cmp(a, b)) == MP_EQ)
+      return MP_EQ;
+
+    if(SIGN(a) == MP_ZPOS)
+      return mag;
+    else
+      return -mag;
+
+  } else if(SIGN(a) == MP_ZPOS) {
+    return MP_GT;
+  } else {
+    return MP_LT;
+  }
+
+} /* end mp_cmp() */
+
+/* }}} */
+
+/* {{{ mp_cmp_mag(a, b) */
+
+/*
+  mp_cmp_mag(a, b)
+
+  Compares |a| <=> |b|, and returns an appropriate comparison result
+ */
+
+int    mp_cmp_mag(mp_int *a, mp_int *b)
+{
+  ARGCHK(a != NULL && b != NULL, MP_EQ);
+
+  return s_mp_cmp(a, b);
+
+} /* end mp_cmp_mag() */
+
+/* }}} */
+
+/* {{{ mp_cmp_int(a, z) */
+
+/*
+  This just converts z to an mp_int, and uses the existing comparison
+  routines.  This is sort of inefficient, but it's not clear to me how
+  frequently this wil get used anyway.  For small positive constants,
+  you can always use mp_cmp_d(), and for zero, there is mp_cmp_z().
+ */
+int    mp_cmp_int(mp_int *a, long z)
+{
+  mp_int  tmp;
+  int     out;
+
+  ARGCHK(a != NULL, MP_EQ);
+  
+  mp_init(&tmp); mp_set_int(&tmp, z);
+  out = mp_cmp(a, &tmp);
+  mp_clear(&tmp);
+
+  return out;
+
+} /* end mp_cmp_int() */
+
+/* }}} */
+
+/* {{{ mp_isodd(a) */
+
+/*
+  mp_isodd(a)
+
+  Returns a true (non-zero) value if a is odd, false (zero) otherwise.
+ */
+int    mp_isodd(mp_int *a)
+{
+  ARGCHK(a != NULL, 0);
+
+  return (DIGIT(a, 0) & 1);
+
+} /* end mp_isodd() */
+
+/* }}} */
+
+/* {{{ mp_iseven(a) */
+
+int    mp_iseven(mp_int *a)
+{
+  return !mp_isodd(a);
+
+} /* end mp_iseven() */
+
+/* }}} */
+
+/* }}} */
+
+/*------------------------------------------------------------------------*/
+/* {{{ Number theoretic functions */
+
+#if MP_NUMTH
+/* {{{ mp_gcd(a, b, c) */
+
+/*
+  Like the old mp_gcd() function, except computes the GCD using the
+  binary algorithm due to Josef Stein in 1961 (via Knuth).
+ */
+mp_err mp_gcd(mp_int *a, mp_int *b, mp_int *c)
+{
+  mp_err   res;
+  mp_int   u, v, t;
+  mp_size  k = 0;
+
+  ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);
+
+  if(mp_cmp_z(a) == MP_EQ && mp_cmp_z(b) == MP_EQ)
+      return MP_RANGE;
+  if(mp_cmp_z(a) == MP_EQ) {
+    return mp_copy(b, c);
+  } else if(mp_cmp_z(b) == MP_EQ) {
+    return mp_copy(a, c);
+  }
+
+  if((res = mp_init(&t)) != MP_OKAY)
+    return res;
+  if((res = mp_init_copy(&u, a)) != MP_OKAY)
+    goto U;
+  if((res = mp_init_copy(&v, b)) != MP_OKAY)
+    goto V;
+
+  SIGN(&u) = MP_ZPOS;
+  SIGN(&v) = MP_ZPOS;
+
+  /* Divide out common factors of 2 until at least 1 of a, b is even */
+  while(mp_iseven(&u) && mp_iseven(&v)) {
+    s_mp_div_2(&u);
+    s_mp_div_2(&v);
+    ++k;
+  }
+
+  /* Initialize t */
+  if(mp_isodd(&u)) {
+    if((res = mp_copy(&v, &t)) != MP_OKAY)
+      goto CLEANUP;
+    
+    /* t = -v */
+    if(SIGN(&v) == MP_ZPOS)
+      SIGN(&t) = MP_NEG;
+    else
+      SIGN(&t) = MP_ZPOS;
+    
+  } else {
+    if((res = mp_copy(&u, &t)) != MP_OKAY)
+      goto CLEANUP;
+
+  }
+
+  for(;;) {
+    while(mp_iseven(&t)) {
+      s_mp_div_2(&t);
+    }
+
+    if(mp_cmp_z(&t) == MP_GT) {
+      if((res = mp_copy(&t, &u)) != MP_OKAY)
+	goto CLEANUP;
+
+    } else {
+      if((res = mp_copy(&t, &v)) != MP_OKAY)
+	goto CLEANUP;
+
+      /* v = -t */
+      if(SIGN(&t) == MP_ZPOS)
+	SIGN(&v) = MP_NEG;
+      else
+	SIGN(&v) = MP_ZPOS;
+    }
+
+    if((res = mp_sub(&u, &v, &t)) != MP_OKAY)
+      goto CLEANUP;
+
+    if(s_mp_cmp_d(&t, 0) == MP_EQ)
+      break;
+  }
+
+  s_mp_2expt(&v, k);       /* v = 2^k   */
+  res = mp_mul(&u, &v, c); /* c = u * v */
+
+ CLEANUP:
+  mp_clear(&v);
+ V:
+  mp_clear(&u);
+ U:
+  mp_clear(&t);
+
+  return res;
+
+} /* end mp_bgcd() */
+
+/* }}} */
+
+/* {{{ mp_lcm(a, b, c) */
+
+/* We compute the least common multiple using the rule:
+
+   ab = [a, b](a, b)
+
+   ... by computing the product, and dividing out the gcd.
+ */
+
+mp_err mp_lcm(mp_int *a, mp_int *b, mp_int *c)
+{
+  mp_int  gcd, prod;
+  mp_err  res;
+
+  ARGCHK(a != NULL && b != NULL && c != NULL, MP_BADARG);
+
+  /* Set up temporaries */
+  if((res = mp_init(&gcd)) != MP_OKAY)
+    return res;
+  if((res = mp_init(&prod)) != MP_OKAY)
+    goto GCD;
+
+  if((res = mp_mul(a, b, &prod)) != MP_OKAY)
+    goto CLEANUP;
+  if((res = mp_gcd(a, b, &gcd)) != MP_OKAY)
+    goto CLEANUP;
+
+  res = mp_div(&prod, &gcd, c, NULL);
+
+ CLEANUP:
+  mp_clear(&prod);
+ GCD:
+  mp_clear(&gcd);
+
+  return res;
+
+} /* end mp_lcm() */
+
+/* }}} */
+
+/* {{{ mp_xgcd(a, b, g, x, y) */
+
+/*
+  mp_xgcd(a, b, g, x, y)
+
+  Compute g = (a, b) and values x and y satisfying Bezout's identity
+  (that is, ax + by = g).  This uses the extended binary GCD algorithm
+  based on the Stein algorithm used for mp_gcd()
+ */
+
+mp_err mp_xgcd(mp_int *a, mp_int *b, mp_int *g, mp_int *x, mp_int *y)
+{
+  mp_int   gx, xc, yc, u, v, A, B, C, D;
+  mp_int  *clean[9];
+  mp_err   res;
+  int      last = -1;
+
+  if(mp_cmp_z(b) == 0)
+    return MP_RANGE;
+
+  /* Initialize all these variables we need */
+  if((res = mp_init(&u)) != MP_OKAY) goto CLEANUP;
+  clean[++last] = &u;
+  if((res = mp_init(&v)) != MP_OKAY) goto CLEANUP;
+  clean[++last] = &v;
+  if((res = mp_init(&gx)) != MP_OKAY) goto CLEANUP;
+  clean[++last] = &gx;
+  if((res = mp_init(&A)) != MP_OKAY) goto CLEANUP;
+  clean[++last] = &A;
+  if((res = mp_init(&B)) != MP_OKAY) goto CLEANUP;
+  clean[++last] = &B;
+  if((res = mp_init(&C)) != MP_OKAY) goto CLEANUP;
+  clean[++last] = &C;
+  if((res = mp_init(&D)) != MP_OKAY) goto CLEANUP;
+  clean[++last] = &D;
+  if((res = mp_init_copy(&xc, a)) != MP_OKAY) goto CLEANUP;
+  clean[++last] = &xc;
+  mp_abs(&xc, &xc);
+  if((res = mp_init_copy(&yc, b)) != MP_OKAY) goto CLEANUP;
+  clean[++last] = &yc;
+  mp_abs(&yc, &yc);
+
+  mp_set(&gx, 1);
+
+  /* Divide by two until at least one of them is even */
+  while(mp_iseven(&xc) && mp_iseven(&yc)) {
+    s_mp_div_2(&xc);
+    s_mp_div_2(&yc);
+    if((res = s_mp_mul_2(&gx)) != MP_OKAY)
+      goto CLEANUP;
+  }
+
+  mp_copy(&xc, &u);
+  mp_copy(&yc, &v);
+  mp_set(&A, 1); mp_set(&D, 1);
+
+  /* Loop through binary GCD algorithm */
+  for(;;) {
+    while(mp_iseven(&u)) {
+      s_mp_div_2(&u);
+
+      if(mp_iseven(&A) && mp_iseven(&B)) {
+	s_mp_div_2(&A); s_mp_div_2(&B);
+      } else {
+	if((res = mp_add(&A, &yc, &A)) != MP_OKAY) goto CLEANUP;
+	s_mp_div_2(&A);
+	if((res = mp_sub(&B, &xc, &B)) != MP_OKAY) goto CLEANUP;
+	s_mp_div_2(&B);
+      }
+    }
+
+    while(mp_iseven(&v)) {
+      s_mp_div_2(&v);
+
+      if(mp_iseven(&C) && mp_iseven(&D)) {
+	s_mp_div_2(&C); s_mp_div_2(&D);
+      } else {
+	if((res = mp_add(&C, &yc, &C)) != MP_OKAY) goto CLEANUP;
+	s_mp_div_2(&C);
+	if((res = mp_sub(&D, &xc, &D)) != MP_OKAY) goto CLEANUP;
+	s_mp_div_2(&D);
+      }
+    }
+
+    if(mp_cmp(&u, &v) >= 0) {
+      if((res = mp_sub(&u, &v, &u)) != MP_OKAY) goto CLEANUP;
+      if((res = mp_sub(&A, &C, &A)) != MP_OKAY) goto CLEANUP;
+      if((res = mp_sub(&B, &D, &B)) != MP_OKAY) goto CLEANUP;
+
+    } else {
+      if((res = mp_sub(&v, &u, &v)) != MP_OKAY) goto CLEANUP;
+      if((res = mp_sub(&C, &A, &C)) != MP_OKAY) goto CLEANUP;
+      if((res = mp_sub(&D, &B, &D)) != MP_OKAY) goto CLEANUP;
+
+    }
+
+    /* If we're done, copy results to output */
+    if(mp_cmp_z(&u) == 0) {
+      if(x)
+	if((res = mp_copy(&C, x)) != MP_OKAY) goto CLEANUP;
+
+      if(y)
+	if((res = mp_copy(&D, y)) != MP_OKAY) goto CLEANUP;
+      
+      if(g)
+	if((res = mp_mul(&gx, &v, g)) != MP_OKAY) goto CLEANUP;
+
+      break;
+    }
+  }
+
+ CLEANUP:
+  while(last >= 0)
+    mp_clear(clean[last--]);
+
+  return res;
+
+} /* end mp_xgcd() */
+
+/* }}} */
+
+/* {{{ mp_invmod(a, m, c) */
+
+/*
+  mp_invmod(a, m, c)
+
+  Compute c = a^-1 (mod m), if there is an inverse for a (mod m).
+  This is equivalent to the question of whether (a, m) = 1.  If not,
+  MP_UNDEF is returned, and there is no inverse.
+ */
+
+mp_err mp_invmod(mp_int *a, mp_int *m, mp_int *c)
+{
+  mp_int  g, x;
+  mp_err  res;
+
+  ARGCHK(a && m && c, MP_BADARG);
+
+  if(mp_cmp_z(a) == 0 || mp_cmp_z(m) == 0)
+    return MP_RANGE;
+
+  if((res = mp_init(&g)) != MP_OKAY)
+    return res;
+  if((res = mp_init(&x)) != MP_OKAY)
+    goto X;
+
+  if((res = mp_xgcd(a, m, &g, &x, NULL)) != MP_OKAY)
+    goto CLEANUP;
+
+  if(mp_cmp_d(&g, 1) != MP_EQ) {
+    res = MP_UNDEF;
+    goto CLEANUP;
+  }
+
+  res = mp_mod(&x, m, c);
+  SIGN(c) = SIGN(a);
+
+CLEANUP:
+  mp_clear(&x);
+X:
+  mp_clear(&g);
+
+  return res;
+
+} /* end mp_invmod() */
+
+/* }}} */
+#endif /* if MP_NUMTH */
+
+/* }}} */
+
+/*------------------------------------------------------------------------*/
+/* {{{ mp_print(mp, ofp) */
+
+#if MP_IOFUNC
+/*
+  mp_print(mp, ofp)
+
+  Print a textual representation of the given mp_int on the output
+  stream 'ofp'.  Output is generated using the internal radix.
+ */
+
+void   mp_print(mp_int *mp, FILE *ofp)
+{
+  int   ix;
+
+  if(mp == NULL || ofp == NULL)
+    return;
+
+  fputc((SIGN(mp) == MP_NEG) ? '-' : '+', ofp);
+
+  for(ix = USED(mp) - 1; ix >= 0; ix--) {
+    fprintf(ofp, DIGIT_FMT, DIGIT(mp, ix));
+  }
+
+} /* end mp_print() */
+
+#endif /* if MP_IOFUNC */
+
+/* }}} */
+
+/*------------------------------------------------------------------------*/
+/* {{{ More I/O Functions */
+
+/* {{{ mp_read_signed_bin(mp, str, len) */
+
+/* 
+   mp_read_signed_bin(mp, str, len)
+
+   Read in a raw value (base 256) into the given mp_int
+ */
+
+mp_err  mp_read_signed_bin(mp_int *mp, unsigned char *str, int len)
+{
+  mp_err         res;
+
+  ARGCHK(mp != NULL && str != NULL && len > 0, MP_BADARG);
+
+  if((res = mp_read_unsigned_bin(mp, str + 1, len - 1)) == MP_OKAY) {
+    /* Get sign from first byte */
+    if(str[0])
+      SIGN(mp) = MP_NEG;
+    else
+      SIGN(mp) = MP_ZPOS;
+  }
+
+  return res;
+
+} /* end mp_read_signed_bin() */
+
+/* }}} */
+
+/* {{{ mp_signed_bin_size(mp) */
+
+int    mp_signed_bin_size(mp_int *mp)
+{
+  ARGCHK(mp != NULL, 0);
+
+  return mp_unsigned_bin_size(mp) + 1;
+
+} /* end mp_signed_bin_size() */
+
+/* }}} */
+
+/* {{{ mp_to_signed_bin(mp, str) */
+
+mp_err mp_to_signed_bin(mp_int *mp, unsigned char *str)
+{
+  ARGCHK(mp != NULL && str != NULL, MP_BADARG);
+
+  /* Caller responsible for allocating enough memory (use mp_raw_size(mp)) */
+  str[0] = (char)SIGN(mp);
+
+  return mp_to_unsigned_bin(mp, str + 1);
+
+} /* end mp_to_signed_bin() */
+
+/* }}} */
+
+/* {{{ mp_read_unsigned_bin(mp, str, len) */
+
+/*
+  mp_read_unsigned_bin(mp, str, len)
+
+  Read in an unsigned value (base 256) into the given mp_int
+ */
+
+mp_err  mp_read_unsigned_bin(mp_int *mp, unsigned char *str, int len)
+{
+  int     ix;
+  mp_err  res;
+
+  ARGCHK(mp != NULL && str != NULL && len > 0, MP_BADARG);
+
+  mp_zero(mp);
+
+  for(ix = 0; ix < len; ix++) {
+    if((res = s_mp_mul_2d(mp, CHAR_BIT)) != MP_OKAY)
+      return res;
+
+    if((res = mp_add_d(mp, str[ix], mp)) != MP_OKAY)
+      return res;
+  }
+  
+  return MP_OKAY;
+  
+} /* end mp_read_unsigned_bin() */
+
+/* }}} */
+
+/* {{{ mp_unsigned_bin_size(mp) */
+
+int     mp_unsigned_bin_size(mp_int *mp) 
+{
+  mp_digit   topdig;
+  int        count;
+
+  ARGCHK(mp != NULL, 0);
+
+  /* Special case for the value zero */
+  if(USED(mp) == 1 && DIGIT(mp, 0) == 0)
+    return 1;
+
+  count = (USED(mp) - 1) * sizeof(mp_digit);
+  topdig = DIGIT(mp, USED(mp) - 1);
+
+  while(topdig != 0) {
+    ++count;
+    topdig >>= CHAR_BIT;
+  }
+
+  return count;
+
+} /* end mp_unsigned_bin_size() */
+
+/* }}} */
+
+/* {{{ mp_to_unsigned_bin(mp, str) */
+
+mp_err mp_to_unsigned_bin(mp_int *mp, unsigned char *str)
+{
+  mp_digit      *dp, *end, d;
+  unsigned char *spos;
+
+  ARGCHK(mp != NULL && str != NULL, MP_BADARG);
+
+  dp = DIGITS(mp);
+  end = dp + USED(mp) - 1;
+  spos = str;
+
+  /* Special case for zero, quick test */
+  if(dp == end && *dp == 0) {
+    *str = '\0';
+    return MP_OKAY;
+  }
+
+  /* Generate digits in reverse order */
+  while(dp < end) {
+    int      ix;
+
+    d = *dp;
+    for(ix = 0; ix < sizeof(mp_digit); ++ix) {
+      *spos = d & UCHAR_MAX;
+      d >>= CHAR_BIT;
+      ++spos;
+    }
+
+    ++dp;
+  }
+
+  /* Now handle last digit specially, high order zeroes are not written */
+  d = *end;
+  while(d != 0) {
+    *spos = d & UCHAR_MAX;
+    d >>= CHAR_BIT;
+    ++spos;
+  }
+
+  /* Reverse everything to get digits in the correct order */
+  while(--spos > str) {
+    unsigned char t = *str;
+    *str = *spos;
+    *spos = t;
+
+    ++str;
+  }
+
+  return MP_OKAY;
+
+} /* end mp_to_unsigned_bin() */
+
+/* }}} */
+
+/* {{{ mp_count_bits(mp) */
+
+int    mp_count_bits(mp_int *mp)
+{
+  int      len;
+  mp_digit d;
+
+  ARGCHK(mp != NULL, MP_BADARG);
+
+  len = DIGIT_BIT * (USED(mp) - 1);
+  d = DIGIT(mp, USED(mp) - 1);
+
+  while(d != 0) {
+    ++len;
+    d >>= 1;
+  }
+
+  return len;
+  
+} /* end mp_count_bits() */
+
+/* }}} */
+
+/* {{{ mp_read_radix(mp, str, radix) */
+
+/*
+  mp_read_radix(mp, str, radix)
+
+  Read an integer from the given string, and set mp to the resulting
+  value.  The input is presumed to be in base 10.  Leading non-digit
+  characters are ignored, and the function reads until a non-digit
+  character or the end of the string.
+ */
+
+mp_err  mp_read_radix(mp_int *mp, unsigned char *str, int radix)
+{
+  int     ix = 0, val = 0;
+  mp_err  res;
+  mp_sign sig = MP_ZPOS;
+
+  ARGCHK(mp != NULL && str != NULL && radix >= 2 && radix <= MAX_RADIX, 
+	 MP_BADARG);
+
+  mp_zero(mp);
+
+  /* Skip leading non-digit characters until a digit or '-' or '+' */
+  while(str[ix] && 
+	(s_mp_tovalue(str[ix], radix) < 0) && 
+	str[ix] != '-' &&
+	str[ix] != '+') {
+    ++ix;
+  }
+
+  if(str[ix] == '-') {
+    sig = MP_NEG;
+    ++ix;
+  } else if(str[ix] == '+') {
+    sig = MP_ZPOS; /* this is the default anyway... */
+    ++ix;
+  }
+
+  while((val = s_mp_tovalue(str[ix], radix)) >= 0) {
+    if((res = s_mp_mul_d(mp, radix)) != MP_OKAY)
+      return res;
+    if((res = s_mp_add_d(mp, val)) != MP_OKAY)
+      return res;
+    ++ix;
+  }
+
+  if(s_mp_cmp_d(mp, 0) == MP_EQ)
+    SIGN(mp) = MP_ZPOS;
+  else
+    SIGN(mp) = sig;
+
+  return MP_OKAY;
+
+} /* end mp_read_radix() */
+
+/* }}} */
+
+/* {{{ mp_radix_size(mp, radix) */
+
+int    mp_radix_size(mp_int *mp, int radix)
+{
+  int  len;
+  ARGCHK(mp != NULL, 0);
+
+  len = s_mp_outlen(mp_count_bits(mp), radix) + 1; /* for NUL terminator */
+
+  if(mp_cmp_z(mp) < 0)
+    ++len; /* for sign */
+
+  return len;
+
+} /* end mp_radix_size() */
+
+/* }}} */
+
+/* {{{ mp_value_radix_size(num, qty, radix) */
+
+/* num = number of digits
+   qty = number of bits per digit
+   radix = target base
+   
+   Return the number of digits in the specified radix that would be
+   needed to express 'num' digits of 'qty' bits each.
+ */
+int    mp_value_radix_size(int num, int qty, int radix)
+{
+  ARGCHK(num >= 0 && qty > 0 && radix >= 2 && radix <= MAX_RADIX, 0);
+
+  return s_mp_outlen(num * qty, radix);
+
+} /* end mp_value_radix_size() */
+
+/* }}} */
+
+/* {{{ mp_toradix(mp, str, radix) */
+
+mp_err mp_toradix(mp_int *mp, unsigned char *str, int radix)
+{
+  int  ix, pos = 0;
+
+  ARGCHK(mp != NULL && str != NULL, MP_BADARG);
+  ARGCHK(radix > 1 && radix <= MAX_RADIX, MP_RANGE);
+
+  if(mp_cmp_z(mp) == MP_EQ) {
+    str[0] = '0';
+    str[1] = '\0';
+  } else {
+    mp_err   res;
+    mp_int   tmp;
+    mp_sign  sgn;
+    mp_digit rem, rdx = (mp_digit)radix;
+    char     ch;
+
+    if((res = mp_init_copy(&tmp, mp)) != MP_OKAY)
+      return res;
+
+    /* Save sign for later, and take absolute value */
+    sgn = SIGN(&tmp); SIGN(&tmp) = MP_ZPOS;
+
+    /* Generate output digits in reverse order      */
+    while(mp_cmp_z(&tmp) != 0) {
+      if((res = s_mp_div_d(&tmp, rdx, &rem)) != MP_OKAY) {
+	mp_clear(&tmp);
+	return res;
+      }
+
+      /* Generate digits, use capital letters */
+      ch = s_mp_todigit(rem, radix, 0);
+
+      str[pos++] = ch;
+    }
+
+    /* Add - sign if original value was negative */
+    if(sgn == MP_NEG)
+      str[pos++] = '-';
+
+    /* Add trailing NUL to end the string        */
+    str[pos--] = '\0';
+
+    /* Reverse the digits and sign indicator     */
+    ix = 0;
+    while(ix < pos) {
+      char tmp = str[ix];
+
+      str[ix] = str[pos];
+      str[pos] = tmp;
+      ++ix;
+      --pos;
+    }
+    
+    mp_clear(&tmp);
+  }
+
+  return MP_OKAY;
+
+} /* end mp_toradix() */
+
+/* }}} */
+
+/* {{{ mp_char2value(ch, r) */
+
+int    mp_char2value(char ch, int r)
+{
+  return s_mp_tovalue(ch, r);
+
+} /* end mp_tovalue() */
+
+/* }}} */
+
+/* }}} */
+
+/* {{{ mp_strerror(ec) */
+
+/*
+  mp_strerror(ec)
+
+  Return a string describing the meaning of error code 'ec'.  The
+  string returned is allocated in static memory, so the caller should
+  not attempt to modify or free the memory associated with this
+  string.
+ */
+const char  *mp_strerror(mp_err ec)
+{
+  int   aec = (ec < 0) ? -ec : ec;
+
+  /* Code values are negative, so the senses of these comparisons
+     are accurate */
+  if(ec < MP_LAST_CODE || ec > MP_OKAY) {
+    return mp_err_string[0];  /* unknown error code */
+  } else {
+    return mp_err_string[aec + 1];
+  }
+
+} /* end mp_strerror() */
+
+/* }}} */
+
+/*========================================================================*/
+/*------------------------------------------------------------------------*/
+/* Static function definitions (internal use only)                        */
+
+/* {{{ Memory management */
+
+/* {{{ s_mp_grow(mp, min) */
+
+/* Make sure there are at least 'min' digits allocated to mp              */
+mp_err   s_mp_grow(mp_int *mp, mp_size min)
+{
+  if(min > ALLOC(mp)) {
+    mp_digit   *tmp;
+
+    /* Set min to next nearest default precision block size */
+    min = ((min + (s_mp_defprec - 1)) / s_mp_defprec) * s_mp_defprec;
+
+    if((tmp = s_mp_alloc(min, sizeof(mp_digit))) == NULL)
+      return MP_MEM;
+
+    s_mp_copy(DIGITS(mp), tmp, USED(mp));
+
+#if MP_CRYPTO
+    s_mp_setz(DIGITS(mp), ALLOC(mp));
+#endif
+    s_mp_free(DIGITS(mp));
+    DIGITS(mp) = tmp;
+    ALLOC(mp) = min;
+  }
+
+  return MP_OKAY;
+
+} /* end s_mp_grow() */
+
+/* }}} */
+
+/* {{{ s_mp_pad(mp, min) */
+
+/* Make sure the used size of mp is at least 'min', growing if needed     */
+mp_err   s_mp_pad(mp_int *mp, mp_size min)
+{
+  if(min > USED(mp)) {
+    mp_err  res;
+
+    /* Make sure there is room to increase precision  */
+    if(min > ALLOC(mp) && (res = s_mp_grow(mp, min)) != MP_OKAY)
+      return res;
+
+    /* Increase precision; should already be 0-filled */
+    USED(mp) = min;
+  }
+
+  return MP_OKAY;
+
+} /* end s_mp_pad() */
+
+/* }}} */
+
+/* {{{ s_mp_setz(dp, count) */
+
+#if MP_MACRO == 0
+/* Set 'count' digits pointed to by dp to be zeroes                       */
+void s_mp_setz(mp_digit *dp, mp_size count)
+{
+#if MP_MEMSET == 0
+  int  ix;
+
+  for(ix = 0; ix < count; ix++)
+    dp[ix] = 0;
+#else
+  memset(dp, 0, count * sizeof(mp_digit));
+#endif
+
+} /* end s_mp_setz() */
+#endif
+
+/* }}} */
+
+/* {{{ s_mp_copy(sp, dp, count) */
+
+#if MP_MACRO == 0
+/* Copy 'count' digits from sp to dp                                      */
+void s_mp_copy(mp_digit *sp, mp_digit *dp, mp_size count)
+{
+#if MP_MEMCPY == 0
+  int  ix;
+
+  for(ix = 0; ix < count; ix++)
+    dp[ix] = sp[ix];
+#else
+  memcpy(dp, sp, count * sizeof(mp_digit));
+#endif
+
+} /* end s_mp_copy() */
+#endif
+
+/* }}} */
+
+/* {{{ s_mp_alloc(nb, ni) */
+
+#if MP_MACRO == 0
+/* Allocate ni records of nb bytes each, and return a pointer to that     */
+void    *s_mp_alloc(size_t nb, size_t ni)
+{
+  return calloc(nb, ni);
+
+} /* end s_mp_alloc() */
+#endif
+
+/* }}} */
+
+/* {{{ s_mp_free(ptr) */
+
+#if MP_MACRO == 0
+/* Free the memory pointed to by ptr                                      */
+void     s_mp_free(void *ptr)
+{
+  if(ptr)
+    free(ptr);
+
+} /* end s_mp_free() */
+#endif
+
+/* }}} */
+
+/* {{{ s_mp_clamp(mp) */
+
+/* Remove leading zeroes from the given value                             */
+void     s_mp_clamp(mp_int *mp)
+{
+  mp_size   du = USED(mp);
+  mp_digit *zp = DIGITS(mp) + du - 1;
+
+  while(du > 1 && !*zp--)
+    --du;
+
+  USED(mp) = du;
+
+} /* end s_mp_clamp() */
+
+
+/* }}} */
+
+/* {{{ s_mp_exch(a, b) */
+
+/* Exchange the data for a and b; (b, a) = (a, b)                         */
+void     s_mp_exch(mp_int *a, mp_int *b)
+{
+  mp_int   tmp;
+
+  tmp = *a;
+  *a = *b;
+  *b = tmp;
+
+} /* end s_mp_exch() */
+
+/* }}} */
+
+/* }}} */
+
+/* {{{ Arithmetic helpers */
+
+/* {{{ s_mp_lshd(mp, p) */
+
+/* 
+   Shift mp leftward by p digits, growing if needed, and zero-filling
+   the in-shifted digits at the right end.  This is a convenient
+   alternative to multiplication by powers of the radix
+ */   
+
+mp_err   s_mp_lshd(mp_int *mp, mp_size p)
+{
+  mp_err   res;
+  mp_size  pos;
+  mp_digit *dp;
+  int     ix;
+
+  if(p == 0)
+    return MP_OKAY;
+
+  if((res = s_mp_pad(mp, USED(mp) + p)) != MP_OKAY)
+    return res;
+
+  pos = USED(mp) - 1;
+  dp = DIGITS(mp);
+
+  /* Shift all the significant figures over as needed */
+  for(ix = pos - p; ix >= 0; ix--) 
+    dp[ix + p] = dp[ix];
+
+  /* Fill the bottom digits with zeroes */
+  for(ix = 0; ix < p; ix++)
+    dp[ix] = 0;
+
+  return MP_OKAY;
+
+} /* end s_mp_lshd() */
+
+/* }}} */
+
+/* {{{ s_mp_rshd(mp, p) */
+
+/* 
+   Shift mp rightward by p digits.  Maintains the invariant that
+   digits above the precision are all zero.  Digits shifted off the
+   end are lost.  Cannot fail.
+ */
+
+void     s_mp_rshd(mp_int *mp, mp_size p)
+{
+  mp_size  ix;
+  mp_digit *dp;
+
+  if(p == 0)
+    return;
+
+  /* Shortcut when all digits are to be shifted off */
+  if(p >= USED(mp)) {
+    s_mp_setz(DIGITS(mp), ALLOC(mp));
+    USED(mp) = 1;
+    SIGN(mp) = MP_ZPOS;
+    return;
+  }
+
+  /* Shift all the significant figures over as needed */
+  dp = DIGITS(mp);
+  for(ix = p; ix < USED(mp); ix++)
+    dp[ix - p] = dp[ix];
+
+  /* Fill the top digits with zeroes */
+  ix -= p;
+  while(ix < USED(mp))
+    dp[ix++] = 0;
+
+  /* Strip off any leading zeroes    */
+  s_mp_clamp(mp);
+
+} /* end s_mp_rshd() */
+
+/* }}} */
+
+/* {{{ s_mp_div_2(mp) */
+
+/* Divide by two -- take advantage of radix properties to do it fast      */
+void     s_mp_div_2(mp_int *mp)
+{
+  s_mp_div_2d(mp, 1);
+
+} /* end s_mp_div_2() */
+
+/* }}} */
+
+/* {{{ s_mp_mul_2(mp) */
+
+mp_err s_mp_mul_2(mp_int *mp)
+{
+  int      ix;
+  mp_digit kin = 0, kout, *dp = DIGITS(mp);
+  mp_err   res;
+
+  /* Shift digits leftward by 1 bit */
+  for(ix = 0; ix < USED(mp); ix++) {
+    kout = (dp[ix] >> (DIGIT_BIT - 1)) & 1;
+    dp[ix] = (dp[ix] << 1) | kin;
+
+    kin = kout;
+  }
+
+  /* Deal with rollover from last digit */
+  if(kin) {
+    if(ix >= ALLOC(mp)) {
+      if((res = s_mp_grow(mp, ALLOC(mp) + 1)) != MP_OKAY)
+	return res;
+      dp = DIGITS(mp);
+    }
+
+    dp[ix] = kin;
+    USED(mp) += 1;
+  }
+
+  return MP_OKAY;
+
+} /* end s_mp_mul_2() */
+
+/* }}} */
+
+/* {{{ s_mp_mod_2d(mp, d) */
+
+/*
+  Remainder the integer by 2^d, where d is a number of bits.  This
+  amounts to a bitwise AND of the value, and does not require the full
+  division code
+ */
+void     s_mp_mod_2d(mp_int *mp, mp_digit d)
+{
+  unsigned int  ndig = (d / DIGIT_BIT), nbit = (d % DIGIT_BIT);
+  unsigned int  ix;
+  mp_digit      dmask, *dp = DIGITS(mp);
+
+  if(ndig >= USED(mp))
+    return;
+
+  /* Flush all the bits above 2^d in its digit */
+  dmask = (1 << nbit) - 1;
+  dp[ndig] &= dmask;
+
+  /* Flush all digits above the one with 2^d in it */
+  for(ix = ndig + 1; ix < USED(mp); ix++)
+    dp[ix] = 0;
+
+  s_mp_clamp(mp);
+
+} /* end s_mp_mod_2d() */
+
+/* }}} */
+
+/* {{{ s_mp_mul_2d(mp, d) */
+
+/*
+  Multiply by the integer 2^d, where d is a number of bits.  This
+  amounts to a bitwise shift of the value, and does not require the
+  full multiplication code.
+ */
+mp_err    s_mp_mul_2d(mp_int *mp, mp_digit d)
+{
+  mp_err   res;
+  mp_digit save, next, mask, *dp;
+  mp_size  used;
+  int      ix;
+
+  if((res = s_mp_lshd(mp, d / DIGIT_BIT)) != MP_OKAY)
+    return res;
+
+  dp = DIGITS(mp); used = USED(mp);
+  d %= DIGIT_BIT;
+
+  mask = (1 << d) - 1;
+
+  /* If the shift requires another digit, make sure we've got one to
+     work with */
+  if((dp[used - 1] >> (DIGIT_BIT - d)) & mask) {
+    if((res = s_mp_grow(mp, used + 1)) != MP_OKAY)
+      return res;
+    dp = DIGITS(mp);
+  }
+
+  /* Do the shifting... */
+  save = 0;
+  for(ix = 0; ix < used; ix++) {
+    next = (dp[ix] >> (DIGIT_BIT - d)) & mask;
+    dp[ix] = (dp[ix] << d) | save;
+    save = next;
+  }
+
+  /* If, at this point, we have a nonzero carryout into the next
+     digit, we'll increase the size by one digit, and store it...
+   */
+  if(save) {
+    dp[used] = save;
+    USED(mp) += 1;
+  }
+
+  s_mp_clamp(mp);
+  return MP_OKAY;
+
+} /* end s_mp_mul_2d() */
+
+/* }}} */
+
+/* {{{ s_mp_div_2d(mp, d) */
+
+/*
+  Divide the integer by 2^d, where d is a number of bits.  This
+  amounts to a bitwise shift of the value, and does not require the
+  full division code (used in Barrett reduction, see below)
+ */
+void     s_mp_div_2d(mp_int *mp, mp_digit d)
+{
+  int       ix;
+  mp_digit  save, next, mask, *dp = DIGITS(mp);
+
+  s_mp_rshd(mp, d / DIGIT_BIT);
+  d %= DIGIT_BIT;
+
+  mask = (1 << d) - 1;
+
+  save = 0;
+  for(ix = USED(mp) - 1; ix >= 0; ix--) {
+    next = dp[ix] & mask;
+    dp[ix] = (dp[ix] >> d) | (save << (DIGIT_BIT - d));
+    save = next;
+  }
+
+  s_mp_clamp(mp);
+
+} /* end s_mp_div_2d() */
+
+/* }}} */
+
+/* {{{ s_mp_norm(a, b) */
+
+/*
+  s_mp_norm(a, b)
+
+  Normalize a and b for division, where b is the divisor.  In order
+  that we might make good guesses for quotient digits, we want the
+  leading digit of b to be at least half the radix, which we
+  accomplish by multiplying a and b by a constant.  This constant is
+  returned (so that it can be divided back out of the remainder at the
+  end of the division process).
+
+  We multiply by the smallest power of 2 that gives us a leading digit
+  at least half the radix.  By choosing a power of 2, we simplify the 
+  multiplication and division steps to simple shifts.
+ */
+mp_digit s_mp_norm(mp_int *a, mp_int *b)
+{
+  mp_digit  t, d = 0;
+
+  t = DIGIT(b, USED(b) - 1);
+  while(t < (RADIX / 2)) {
+    t <<= 1;
+    ++d;
+  }
+    
+  if(d != 0) {
+    s_mp_mul_2d(a, d);
+    s_mp_mul_2d(b, d);
+  }
+
+  return d;
+
+} /* end s_mp_norm() */
+
+/* }}} */
+
+/* }}} */
+
+/* {{{ Primitive digit arithmetic */
+
+/* {{{ s_mp_add_d(mp, d) */
+
+/* Add d to |mp| in place                                                 */
+mp_err   s_mp_add_d(mp_int *mp, mp_digit d)    /* unsigned digit addition */
+{
+  mp_word   w, k = 0;
+  mp_size   ix = 1, used = USED(mp);
+  mp_digit *dp = DIGITS(mp);
+
+  w = dp[0] + d;
+  dp[0] = ACCUM(w);
+  k = CARRYOUT(w);
+
+  while(ix < used && k) {
+    w = dp[ix] + k;
+    dp[ix] = ACCUM(w);
+    k = CARRYOUT(w);
+    ++ix;
+  }
+
+  if(k != 0) {
+    mp_err  res;
+
+    if((res = s_mp_pad(mp, USED(mp) + 1)) != MP_OKAY)
+      return res;
+
+    DIGIT(mp, ix) = k;
+  }
+
+  return MP_OKAY;
+
+} /* end s_mp_add_d() */
+
+/* }}} */
+
+/* {{{ s_mp_sub_d(mp, d) */
+
+/* Subtract d from |mp| in place, assumes |mp| > d                        */
+mp_err   s_mp_sub_d(mp_int *mp, mp_digit d)    /* unsigned digit subtract */
+{
+  mp_word   w, b = 0;
+  mp_size   ix = 1, used = USED(mp);
+  mp_digit *dp = DIGITS(mp);
+
+  /* Compute initial subtraction    */
+  w = (RADIX + dp[0]) - d;
+  b = CARRYOUT(w) ? 0 : 1;
+  dp[0] = ACCUM(w);
+
+  /* Propagate borrows leftward     */
+  while(b && ix < used) {
+    w = (RADIX + dp[ix]) - b;
+    b = CARRYOUT(w) ? 0 : 1;
+    dp[ix] = ACCUM(w);
+    ++ix;
+  }
+
+  /* Remove leading zeroes          */
+  s_mp_clamp(mp);
+
+  /* If we have a borrow out, it's a violation of the input invariant */
+  if(b)
+    return MP_RANGE;
+  else
+    return MP_OKAY;
+
+} /* end s_mp_sub_d() */
+
+/* }}} */
+
+/* {{{ s_mp_mul_d(a, d) */
+
+/* Compute a = a * d, single digit multiplication                         */
+mp_err   s_mp_mul_d(mp_int *a, mp_digit d)
+{
+  mp_word w, k = 0;
+  mp_size ix, max;
+  mp_err  res;
+  mp_digit *dp = DIGITS(a);
+
+  /*
+    Single-digit multiplication will increase the precision of the
+    output by at most one digit.  However, we can detect when this
+    will happen -- if the high-order digit of a, times d, gives a
+    two-digit result, then the precision of the result will increase;
+    otherwise it won't.  We use this fact to avoid calling s_mp_pad()
+    unless absolutely necessary.
+   */
+  max = USED(a);
+  w = dp[max - 1] * d;
+  if(CARRYOUT(w) != 0) {
+    if((res = s_mp_pad(a, max + 1)) != MP_OKAY)
+      return res;
+    dp = DIGITS(a);
+  }
+
+  for(ix = 0; ix < max; ix++) {
+    w = (dp[ix] * d) + k;
+    dp[ix] = ACCUM(w);
+    k = CARRYOUT(w);
+  }
+
+  /* If there is a precision increase, take care of it here; the above
+     test guarantees we have enough storage to do this safely.
+   */
+  if(k) {
+    dp[max] = k; 
+    USED(a) = max + 1;
+  }
+
+  s_mp_clamp(a);
+
+  return MP_OKAY;
+  
+} /* end s_mp_mul_d() */
+
+/* }}} */
+
+/* {{{ s_mp_div_d(mp, d, r) */
+
+/*
+  s_mp_div_d(mp, d, r)
+
+  Compute the quotient mp = mp / d and remainder r = mp mod d, for a
+  single digit d.  If r is null, the remainder will be discarded.
+ */
+
+mp_err   s_mp_div_d(mp_int *mp, mp_digit d, mp_digit *r)
+{
+  mp_word   w = 0, t;
+  mp_int    quot;
+  mp_err    res;
+  mp_digit *dp = DIGITS(mp), *qp;
+  int       ix;
+
+  if(d == 0)
+    return MP_RANGE;
+
+  /* Make room for the quotient */
+  if((res = mp_init_size(&quot, USED(mp))) != MP_OKAY)
+    return res;
+
+  USED(&quot) = USED(mp); /* so clamping will work below */
+  qp = DIGITS(&quot);
+
+  /* Divide without subtraction */
+  for(ix = USED(mp) - 1; ix >= 0; ix--) {
+    w = (w << DIGIT_BIT) | dp[ix];
+
+    if(w >= d) {
+      t = w / d;
+      w = w % d;
+    } else {
+      t = 0;
+    }
+
+    qp[ix] = t;
+  }
+
+  /* Deliver the remainder, if desired */
+  if(r)
+    *r = w;
+
+  s_mp_clamp(&quot);
+  mp_exch(&quot, mp);
+  mp_clear(&quot);
+
+  return MP_OKAY;
+
+} /* end s_mp_div_d() */
+
+/* }}} */
+
+/* }}} */
+
+/* {{{ Primitive full arithmetic */
+
+/* {{{ s_mp_add(a, b) */
+
+/* Compute a = |a| + |b|                                                  */
+mp_err   s_mp_add(mp_int *a, mp_int *b)        /* magnitude addition      */
+{
+  mp_word   w = 0;
+  mp_digit *pa, *pb;
+  mp_size   ix, used = USED(b);
+  mp_err    res;
+
+  /* Make sure a has enough precision for the output value */
+  if((used > USED(a)) && (res = s_mp_pad(a, used)) != MP_OKAY)
+    return res;
+
+  /*
+    Add up all digits up to the precision of b.  If b had initially
+    the same precision as a, or greater, we took care of it by the
+    padding step above, so there is no problem.  If b had initially
+    less precision, we'll have to make sure the carry out is duly
+    propagated upward among the higher-order digits of the sum.
+   */
+  pa = DIGITS(a);
+  pb = DIGITS(b);
+  for(ix = 0; ix < used; ++ix) {
+    w += *pa + *pb++;
+    *pa++ = ACCUM(w);
+    w = CARRYOUT(w);
+  }
+
+  /* If we run out of 'b' digits before we're actually done, make
+     sure the carries get propagated upward...  
+   */
+  used = USED(a);
+  while(w && ix < used) {
+    w += *pa;
+    *pa++ = ACCUM(w);
+    w = CARRYOUT(w);
+    ++ix;
+  }
+
+  /* If there's an overall carry out, increase precision and include
+     it.  We could have done this initially, but why touch the memory
+     allocator unless we're sure we have to?
+   */
+  if(w) {
+    if((res = s_mp_pad(a, used + 1)) != MP_OKAY)
+      return res;
+
+    DIGIT(a, ix) = w;  /* pa may not be valid after s_mp_pad() call */
+  }
+
+  return MP_OKAY;
+
+} /* end s_mp_add() */
+
+/* }}} */
+
+/* {{{ s_mp_sub(a, b) */
+
+/* Compute a = |a| - |b|, assumes |a| >= |b|                              */
+mp_err   s_mp_sub(mp_int *a, mp_int *b)        /* magnitude subtract      */
+{
+  mp_word   w = 0;
+  mp_digit *pa, *pb;
+  mp_size   ix, used = USED(b);
+
+  /*
+    Subtract and propagate borrow.  Up to the precision of b, this
+    accounts for the digits of b; after that, we just make sure the
+    carries get to the right place.  This saves having to pad b out to
+    the precision of a just to make the loops work right...
+   */
+  pa = DIGITS(a);
+  pb = DIGITS(b);
+
+  for(ix = 0; ix < used; ++ix) {
+    w = (RADIX + *pa) - w - *pb++;
+    *pa++ = ACCUM(w);
+    w = CARRYOUT(w) ? 0 : 1;
+  }
+
+  used = USED(a);
+  while(ix < used) {
+    w = RADIX + *pa - w;
+    *pa++ = ACCUM(w);
+    w = CARRYOUT(w) ? 0 : 1;
+    ++ix;
+  }
+
+  /* Clobber any leading zeroes we created    */
+  s_mp_clamp(a);
+
+  /* 
+     If there was a borrow out, then |b| > |a| in violation
+     of our input invariant.  We've already done the work,
+     but we'll at least complain about it...
+   */
+  if(w)
+    return MP_RANGE;
+  else
+    return MP_OKAY;
+
+} /* end s_mp_sub() */
+
+/* }}} */
+
+mp_err   s_mp_reduce(mp_int *x, mp_int *m, mp_int *mu)
+{
+  mp_int   q;
+  mp_err   res;
+  mp_size  um = USED(m);
+
+  if((res = mp_init_copy(&q, x)) != MP_OKAY)
+    return res;
+
+  s_mp_rshd(&q, um - 1);       /* q1 = x / b^(k-1)  */
+  s_mp_mul(&q, mu);            /* q2 = q1 * mu      */
+  s_mp_rshd(&q, um + 1);       /* q3 = q2 / b^(k+1) */
+
+  /* x = x mod b^(k+1), quick (no division) */
+  s_mp_mod_2d(x, (mp_digit)(DIGIT_BIT * (um + 1)));
+
+  /* q = q * m mod b^(k+1), quick (no division), uses the short multiplier */
+#ifndef SHRT_MUL
+  s_mp_mul(&q, m);
+  s_mp_mod_2d(&q, (mp_digit)(DIGIT_BIT * (um + 1)));
+#else
+  s_mp_mul_dig(&q, m, um + 1);
+#endif  
+
+  /* x = x - q */
+  if((res = mp_sub(x, &q, x)) != MP_OKAY)
+    goto CLEANUP;
+
+  /* If x < 0, add b^(k+1) to it */
+  if(mp_cmp_z(x) < 0) {
+    mp_set(&q, 1);
+    if((res = s_mp_lshd(&q, um + 1)) != MP_OKAY)
+      goto CLEANUP;
+    if((res = mp_add(x, &q, x)) != MP_OKAY)
+      goto CLEANUP;
+  }
+
+  /* Back off if it's too big */
+  while(mp_cmp(x, m) >= 0) {
+    if((res = s_mp_sub(x, m)) != MP_OKAY)
+      break;
+  }
+
+ CLEANUP:
+  mp_clear(&q);
+
+  return res;
+
+} /* end s_mp_reduce() */
+
+
+
+/* {{{ s_mp_mul(a, b) */
+
+/* Compute a = |a| * |b|                                                  */
+mp_err   s_mp_mul(mp_int *a, mp_int *b)
+{
+  mp_word   w, k = 0;
+  mp_int    tmp;
+  mp_err    res;
+  mp_size   ix, jx, ua = USED(a), ub = USED(b);
+  mp_digit *pa, *pb, *pt, *pbt;
+
+  if((res = mp_init_size(&tmp, ua + ub)) != MP_OKAY)
+    return res;
+
+  /* This has the effect of left-padding with zeroes... */
+  USED(&tmp) = ua + ub;
+
+  /* We're going to need the base value each iteration */
+  pbt = DIGITS(&tmp);
+
+  /* Outer loop:  Digits of b */
+
+  pb = DIGITS(b);
+  for(ix = 0; ix < ub; ++ix, ++pb) {
+    if(*pb == 0) 
+      continue;
+
+    /* Inner product:  Digits of a */
+    pa = DIGITS(a);
+    for(jx = 0; jx < ua; ++jx, ++pa) {
+      pt = pbt + ix + jx;
+      w = *pb * *pa + k + *pt;
+      *pt = ACCUM(w);
+      k = CARRYOUT(w);
+    }
+
+    pbt[ix + jx] = k;
+    k = 0;
+  }
+
+  s_mp_clamp(&tmp);
+  s_mp_exch(&tmp, a);
+
+  mp_clear(&tmp);
+
+  return MP_OKAY;
+
+} /* end s_mp_mul() */
+
+/* }}} */
+
+/* {{{ s_mp_kmul(a, b, out, len) */
+
+#if 0
+void   s_mp_kmul(mp_digit *a, mp_digit *b, mp_digit *out, mp_size len)
+{
+  mp_word   w, k = 0;
+  mp_size   ix, jx;
+  mp_digit *pa, *pt;
+
+  for(ix = 0; ix < len; ++ix, ++b) {
+    if(*b == 0)
+      continue;
+    
+    pa = a;
+    for(jx = 0; jx < len; ++jx, ++pa) {
+      pt = out + ix + jx;
+      w = *b * *pa + k + *pt;
+      *pt = ACCUM(w);
+      k = CARRYOUT(w);
+    }
+
+    out[ix + jx] = k;
+    k = 0;
+  }
+
+} /* end s_mp_kmul() */
+#endif
+
+/* }}} */
+
+/* {{{ s_mp_sqr(a) */
+
+/*
+  Computes the square of a, in place.  This can be done more
+  efficiently than a general multiplication, because many of the
+  computation steps are redundant when squaring.  The inner product
+  step is a bit more complicated, but we save a fair number of
+  iterations of the multiplication loop.
+ */
+#if MP_SQUARE
+mp_err   s_mp_sqr(mp_int *a)
+{
+  mp_word  w, k = 0;
+  mp_int   tmp;
+  mp_err   res;
+  mp_size  ix, jx, kx, used = USED(a);
+  mp_digit *pa1, *pa2, *pt, *pbt;
+
+  if((res = mp_init_size(&tmp, 2 * used)) != MP_OKAY)
+    return res;
+
+  /* Left-pad with zeroes */
+  USED(&tmp) = 2 * used;
+
+  /* We need the base value each time through the loop */
+  pbt = DIGITS(&tmp);
+
+  pa1 = DIGITS(a);
+  for(ix = 0; ix < used; ++ix, ++pa1) {
+    if(*pa1 == 0)
+      continue;
+
+    w = DIGIT(&tmp, ix + ix) + (*pa1 * *pa1);
+
+    pbt[ix + ix] = ACCUM(w);
+    k = CARRYOUT(w);
+
+    /*
+      The inner product is computed as:
+
+         (C, S) = t[i,j] + 2 a[i] a[j] + C
+
+      This can overflow what can be represented in an mp_word, and
+      since C arithmetic does not provide any way to check for
+      overflow, we have to check explicitly for overflow conditions
+      before they happen.
+     */
+    for(jx = ix + 1, pa2 = DIGITS(a) + jx; jx < used; ++jx, ++pa2) {
+      mp_word  u = 0, v;
+      
+      /* Store this in a temporary to avoid indirections later */
+      pt = pbt + ix + jx;
+
+      /* Compute the multiplicative step */
+      w = *pa1 * *pa2;
+
+      /* If w is more than half MP_WORD_MAX, the doubling will
+	 overflow, and we need to record a carry out into the next
+	 word */
+      u = (w >> (MP_WORD_BIT - 1)) & 1;
+
+      /* Double what we've got, overflow will be ignored as defined
+	 for C arithmetic (we've already noted if it is to occur)
+       */
+      w *= 2;
+
+      /* Compute the additive step */
+      v = *pt + k;
+
+      /* If we do not already have an overflow carry, check to see
+	 if the addition will cause one, and set the carry out if so 
+       */
+      u |= ((MP_WORD_MAX - v) < w);
+
+      /* Add in the rest, again ignoring overflow */
+      w += v;
+
+      /* Set the i,j digit of the output */
+      *pt = ACCUM(w);
+
+      /* Save carry information for the next iteration of the loop.
+	 This is why k must be an mp_word, instead of an mp_digit */
+      k = CARRYOUT(w) | (u << DIGIT_BIT);
+
+    } /* for(jx ...) */
+
+    /* Set the last digit in the cycle and reset the carry */
+    k = DIGIT(&tmp, ix + jx) + k;
+    pbt[ix + jx] = ACCUM(k);
+    k = CARRYOUT(k);
+
+    /* If we are carrying out, propagate the carry to the next digit
+       in the output.  This may cascade, so we have to be somewhat
+       circumspect -- but we will have enough precision in the output
+       that we won't overflow 
+     */
+    kx = 1;
+    while(k) {
+      k = pbt[ix + jx + kx] + 1;
+      pbt[ix + jx + kx] = ACCUM(k);
+      k = CARRYOUT(k);
+      ++kx;
+    }
+  } /* for(ix ...) */
+
+  s_mp_clamp(&tmp);
+  s_mp_exch(&tmp, a);
+
+  mp_clear(&tmp);
+
+  return MP_OKAY;
+
+} /* end s_mp_sqr() */
+#endif
+
+/* }}} */
+
+/* {{{ s_mp_div(a, b) */
+
+/*
+  s_mp_div(a, b)
+
+  Compute a = a / b and b = a mod b.  Assumes b > a.
+ */
+
+mp_err   s_mp_div(mp_int *a, mp_int *b)
+{
+  mp_int   quot, rem, t;
+  mp_word  q;
+  mp_err   res;
+  mp_digit d;
+  int      ix;
+
+  if(mp_cmp_z(b) == 0)
+    return MP_RANGE;
+
+  /* Shortcut if b is power of two */
+  if((ix = s_mp_ispow2(b)) >= 0) {
+    mp_copy(a, b);  /* need this for remainder */
+    s_mp_div_2d(a, (mp_digit)ix);
+    s_mp_mod_2d(b, (mp_digit)ix);
+
+    return MP_OKAY;
+  }
+
+  /* Allocate space to store the quotient */
+  if((res = mp_init_size(&quot, USED(a))) != MP_OKAY)
+    return res;
+
+  /* A working temporary for division     */
+  if((res = mp_init_size(&t, USED(a))) != MP_OKAY)
+    goto T;
+
+  /* Allocate space for the remainder     */
+  if((res = mp_init_size(&rem, USED(a))) != MP_OKAY)
+    goto REM;
+
+  /* Normalize to optimize guessing       */
+  d = s_mp_norm(a, b);
+
+  /* Perform the division itself...woo!   */
+  ix = USED(a) - 1;
+
+  while(ix >= 0) {
+    /* Find a partial substring of a which is at least b */
+    while(s_mp_cmp(&rem, b) < 0 && ix >= 0) {
+      if((res = s_mp_lshd(&rem, 1)) != MP_OKAY) 
+	goto CLEANUP;
+
+      if((res = s_mp_lshd(&quot, 1)) != MP_OKAY)
+	goto CLEANUP;
+
+      DIGIT(&rem, 0) = DIGIT(a, ix);
+      s_mp_clamp(&rem);
+      --ix;
+    }
+
+    /* If we didn't find one, we're finished dividing    */
+    if(s_mp_cmp(&rem, b) < 0) 
+      break;    
+
+    /* Compute a guess for the next quotient digit       */
+    q = DIGIT(&rem, USED(&rem) - 1);
+    if(q <= DIGIT(b, USED(b) - 1) && USED(&rem) > 1)
+      q = (q << DIGIT_BIT) | DIGIT(&rem, USED(&rem) - 2);
+
+    q /= DIGIT(b, USED(b) - 1);
+
+    /* The guess can be as much as RADIX + 1 */
+    if(q >= RADIX)
+      q = RADIX - 1;
+
+    /* See what that multiplies out to                   */
+    mp_copy(b, &t);
+    if((res = s_mp_mul_d(&t, q)) != MP_OKAY)
+      goto CLEANUP;
+
+    /* 
+       If it's too big, back it off.  We should not have to do this
+       more than once, or, in rare cases, twice.  Knuth describes a
+       method by which this could be reduced to a maximum of once, but
+       I didn't implement that here.
+     */
+    while(s_mp_cmp(&t, &rem) > 0) {
+      --q;
+      s_mp_sub(&t, b);
+    }
+
+    /* At this point, q should be the right next digit   */
+    if((res = s_mp_sub(&rem, &t)) != MP_OKAY)
+      goto CLEANUP;
+
+    /*
+      Include the digit in the quotient.  We allocated enough memory
+      for any quotient we could ever possibly get, so we should not
+      have to check for failures here
+     */
+    DIGIT(&quot, 0) = q;
+  }
+
+  /* Denormalize remainder                */
+  if(d != 0) 
+    s_mp_div_2d(&rem, d);
+
+  s_mp_clamp(&quot);
+  s_mp_clamp(&rem);
+
+  /* Copy quotient back to output         */
+  s_mp_exch(&quot, a);
+  
+  /* Copy remainder back to output        */
+  s_mp_exch(&rem, b);
+
+CLEANUP:
+  mp_clear(&rem);
+REM:
+  mp_clear(&t);
+T:
+  mp_clear(&quot);
+
+  return res;
+
+} /* end s_mp_div() */
+
+/* }}} */
+
+/* {{{ s_mp_2expt(a, k) */
+
+mp_err   s_mp_2expt(mp_int *a, mp_digit k)
+{
+  mp_err    res;
+  mp_size   dig, bit;
+
+  dig = k / DIGIT_BIT;
+  bit = k % DIGIT_BIT;
+
+  mp_zero(a);
+  if((res = s_mp_pad(a, dig + 1)) != MP_OKAY)
+    return res;
+  
+  DIGIT(a, dig) |= (1 << bit);
+
+  return MP_OKAY;
+
+} /* end s_mp_2expt() */
+
+/* }}} */
+
+
+/* }}} */
+
+/* }}} */
+
+/* {{{ Primitive comparisons */
+
+/* {{{ s_mp_cmp(a, b) */
+
+/* Compare |a| <=> |b|, return 0 if equal, <0 if a<b, >0 if a>b           */
+int      s_mp_cmp(mp_int *a, mp_int *b)
+{
+  mp_size   ua = USED(a), ub = USED(b);
+
+  if(ua > ub)
+    return MP_GT;
+  else if(ua < ub)
+    return MP_LT;
+  else {
+    int      ix = ua - 1;
+    mp_digit *ap = DIGITS(a) + ix, *bp = DIGITS(b) + ix;
+
+    while(ix >= 0) {
+      if(*ap > *bp)
+	return MP_GT;
+      else if(*ap < *bp)
+	return MP_LT;
+
+      --ap; --bp; --ix;
+    }
+
+    return MP_EQ;
+  }
+
+} /* end s_mp_cmp() */
+
+/* }}} */
+
+/* {{{ s_mp_cmp_d(a, d) */
+
+/* Compare |a| <=> d, return 0 if equal, <0 if a<d, >0 if a>d             */
+int      s_mp_cmp_d(mp_int *a, mp_digit d)
+{
+  mp_size  ua = USED(a);
+  mp_digit *ap = DIGITS(a);
+
+  if(ua > 1)
+    return MP_GT;
+
+  if(*ap < d) 
+    return MP_LT;
+  else if(*ap > d)
+    return MP_GT;
+  else
+    return MP_EQ;
+
+} /* end s_mp_cmp_d() */
+
+/* }}} */
+
+/* {{{ s_mp_ispow2(v) */
+
+/*
+  Returns -1 if the value is not a power of two; otherwise, it returns
+  k such that v = 2^k, i.e. lg(v).
+ */
+int      s_mp_ispow2(mp_int *v)
+{
+  mp_digit d, *dp;
+  mp_size  uv = USED(v);
+  int      extra = 0, ix;
+
+  d = DIGIT(v, uv - 1); /* most significant digit of v */
+
+  while(d && ((d & 1) == 0)) {
+    d >>= 1;
+    ++extra;
+  }
+
+  if(d == 1) {
+    ix = uv - 2;
+    dp = DIGITS(v) + ix;
+
+    while(ix >= 0) {
+      if(*dp)
+	return -1; /* not a power of two */
+
+      --dp; --ix;
+    }
+
+    return ((uv - 1) * DIGIT_BIT) + extra;
+  } 
+
+  return -1;
+
+} /* end s_mp_ispow2() */
+
+/* }}} */
+
+/* {{{ s_mp_ispow2d(d) */
+
+int      s_mp_ispow2d(mp_digit d)
+{
+  int   pow = 0;
+
+  while((d & 1) == 0) {
+    ++pow; d >>= 1;
+  }
+
+  if(d == 1)
+    return pow;
+
+  return -1;
+
+} /* end s_mp_ispow2d() */
+
+/* }}} */
+
+/* }}} */
+
+/* {{{ Primitive I/O helpers */
+
+/* {{{ s_mp_tovalue(ch, r) */
+
+/*
+  Convert the given character to its digit value, in the given radix.
+  If the given character is not understood in the given radix, -1 is
+  returned.  Otherwise the digit's numeric value is returned.
+
+  The results will be odd if you use a radix < 2 or > 62, you are
+  expected to know what you're up to.
+ */
+int      s_mp_tovalue(char ch, int r)
+{
+  int    val, xch;
+  
+  if(r > 36)
+    xch = ch;
+  else
+    xch = toupper(ch);
+
+  if(isdigit(xch))
+    val = xch - '0';
+  else if(isupper(xch))
+    val = xch - 'A' + 10;
+  else if(islower(xch))
+    val = xch - 'a' + 36;
+  else if(xch == '+')
+    val = 62;
+  else if(xch == '/')
+    val = 63;
+  else 
+    return -1;
+
+  if(val < 0 || val >= r)
+    return -1;
+
+  return val;
+
+} /* end s_mp_tovalue() */
+
+/* }}} */
+
+/* {{{ s_mp_todigit(val, r, low) */
+
+/*
+  Convert val to a radix-r digit, if possible.  If val is out of range
+  for r, returns zero.  Otherwise, returns an ASCII character denoting
+  the value in the given radix.
+
+  The results may be odd if you use a radix < 2 or > 64, you are
+  expected to know what you're doing.
+ */
+  
+char     s_mp_todigit(int val, int r, int low)
+{
+  char   ch;
+
+  if(val < 0 || val >= r)
+    return 0;
+
+  ch = s_dmap_1[val];
+
+  if(r <= 36 && low)
+    ch = tolower(ch);
+
+  return ch;
+
+} /* end s_mp_todigit() */
+
+/* }}} */
+
+/* {{{ s_mp_outlen(bits, radix) */
+
+/* 
+   Return an estimate for how long a string is needed to hold a radix
+   r representation of a number with 'bits' significant bits.
+
+   Does not include space for a sign or a NUL terminator.
+ */
+int      s_mp_outlen(int bits, int r)
+{
+  return (int)((double)bits * LOG_V_2(r));
+
+} /* end s_mp_outlen() */
+
+/* }}} */
+
+/* }}} */
+
+/*------------------------------------------------------------------------*/
+/* HERE THERE BE DRAGONS                                                  */
+/* crc==4242132123, version==2, Sat Feb 02 06:43:52 2002 */
diff --git a/libtommath/mtest/mpi.h b/libtommath/mtest/mpi.h
new file mode 100644
index 0000000..211421f
--- /dev/null
+++ b/libtommath/mtest/mpi.h
@@ -0,0 +1,225 @@
+/*
+    mpi.h
+
+    by Michael J. Fromberger <sting@linguist.dartmouth.edu>
+    Copyright (C) 1998 Michael J. Fromberger, All Rights Reserved
+
+    Arbitrary precision integer arithmetic library
+ */
+
+#ifndef _H_MPI_
+#define _H_MPI_
+
+#include "mpi-config.h"
+
+#define  MP_LT       -1
+#define  MP_EQ        0
+#define  MP_GT        1
+
+#if MP_DEBUG
+#undef MP_IOFUNC
+#define MP_IOFUNC 1
+#endif
+
+#if MP_IOFUNC
+#include <stdio.h>
+#include <ctype.h>
+#endif
+
+#include <limits.h>
+
+#define  MP_NEG  1
+#define  MP_ZPOS 0
+
+/* Included for compatibility... */
+#define  NEG     MP_NEG
+#define  ZPOS    MP_ZPOS
+
+#define  MP_OKAY          0 /* no error, all is well */
+#define  MP_YES           0 /* yes (boolean result)  */
+#define  MP_NO           -1 /* no (boolean result)   */
+#define  MP_MEM          -2 /* out of memory         */
+#define  MP_RANGE        -3 /* argument out of range */
+#define  MP_BADARG       -4 /* invalid parameter     */
+#define  MP_UNDEF        -5 /* answer is undefined   */
+#define  MP_LAST_CODE    MP_UNDEF
+
+#include "mpi-types.h"
+
+/* Included for compatibility... */
+#define DIGIT_BIT         MP_DIGIT_BIT
+#define DIGIT_MAX         MP_DIGIT_MAX
+
+/* Macros for accessing the mp_int internals           */
+#define  SIGN(MP)     ((MP)->sign)
+#define  USED(MP)     ((MP)->used)
+#define  ALLOC(MP)    ((MP)->alloc)
+#define  DIGITS(MP)   ((MP)->dp)
+#define  DIGIT(MP,N)  (MP)->dp[(N)]
+
+#if MP_ARGCHK == 1
+#define  ARGCHK(X,Y)  {if(!(X)){return (Y);}}
+#elif MP_ARGCHK == 2
+#include <assert.h>
+#define  ARGCHK(X,Y)  assert(X)
+#else
+#define  ARGCHK(X,Y)  /*  */
+#endif
+
+/* This defines the maximum I/O base (minimum is 2)   */
+#define MAX_RADIX         64
+
+typedef struct {
+  mp_sign       sign;    /* sign of this quantity      */
+  mp_size       alloc;   /* how many digits allocated  */
+  mp_size       used;    /* how many digits used       */
+  mp_digit     *dp;      /* the digits themselves      */
+} mp_int;
+
+/*------------------------------------------------------------------------*/
+/* Default precision                                                      */
+
+unsigned int mp_get_prec(void);
+void         mp_set_prec(unsigned int prec);
+
+/*------------------------------------------------------------------------*/
+/* Memory management                                                      */
+
+mp_err mp_init(mp_int *mp);
+mp_err mp_init_array(mp_int mp[], int count);
+mp_err mp_init_size(mp_int *mp, mp_size prec);
+mp_err mp_init_copy(mp_int *mp, mp_int *from);
+mp_err mp_copy(mp_int *from, mp_int *to);
+void   mp_exch(mp_int *mp1, mp_int *mp2);
+void   mp_clear(mp_int *mp);
+void   mp_clear_array(mp_int mp[], int count);
+void   mp_zero(mp_int *mp);
+void   mp_set(mp_int *mp, mp_digit d);
+mp_err mp_set_int(mp_int *mp, long z);
+mp_err mp_shrink(mp_int *a);
+
+
+/*------------------------------------------------------------------------*/
+/* Single digit arithmetic                                                */
+
+mp_err mp_add_d(mp_int *a, mp_digit d, mp_int *b);
+mp_err mp_sub_d(mp_int *a, mp_digit d, mp_int *b);
+mp_err mp_mul_d(mp_int *a, mp_digit d, mp_int *b);
+mp_err mp_mul_2(mp_int *a, mp_int *c);
+mp_err mp_div_d(mp_int *a, mp_digit d, mp_int *q, mp_digit *r);
+mp_err mp_div_2(mp_int *a, mp_int *c);
+mp_err mp_expt_d(mp_int *a, mp_digit d, mp_int *c);
+
+/*------------------------------------------------------------------------*/
+/* Sign manipulations                                                     */
+
+mp_err mp_abs(mp_int *a, mp_int *b);
+mp_err mp_neg(mp_int *a, mp_int *b);
+
+/*------------------------------------------------------------------------*/
+/* Full arithmetic                                                        */
+
+mp_err mp_add(mp_int *a, mp_int *b, mp_int *c);
+mp_err mp_sub(mp_int *a, mp_int *b, mp_int *c);
+mp_err mp_mul(mp_int *a, mp_int *b, mp_int *c);
+mp_err mp_mul_2d(mp_int *a, mp_digit d, mp_int *c);
+#if MP_SQUARE
+mp_err mp_sqr(mp_int *a, mp_int *b);
+#else
+#define mp_sqr(a, b) mp_mul(a, a, b)
+#endif
+mp_err mp_div(mp_int *a, mp_int *b, mp_int *q, mp_int *r);
+mp_err mp_div_2d(mp_int *a, mp_digit d, mp_int *q, mp_int *r);
+mp_err mp_expt(mp_int *a, mp_int *b, mp_int *c);
+mp_err mp_2expt(mp_int *a, mp_digit k);
+mp_err mp_sqrt(mp_int *a, mp_int *b);
+
+/*------------------------------------------------------------------------*/
+/* Modular arithmetic                                                     */
+
+#if MP_MODARITH
+mp_err mp_mod(mp_int *a, mp_int *m, mp_int *c);
+mp_err mp_mod_d(mp_int *a, mp_digit d, mp_digit *c);
+mp_err mp_addmod(mp_int *a, mp_int *b, mp_int *m, mp_int *c);
+mp_err mp_submod(mp_int *a, mp_int *b, mp_int *m, mp_int *c);
+mp_err mp_mulmod(mp_int *a, mp_int *b, mp_int *m, mp_int *c);
+#if MP_SQUARE
+mp_err mp_sqrmod(mp_int *a, mp_int *m, mp_int *c);
+#else
+#define mp_sqrmod(a, m, c) mp_mulmod(a, a, m, c)
+#endif
+mp_err mp_exptmod(mp_int *a, mp_int *b, mp_int *m, mp_int *c);
+mp_err mp_exptmod_d(mp_int *a, mp_digit d, mp_int *m, mp_int *c);
+#endif /* MP_MODARITH */
+
+/*------------------------------------------------------------------------*/
+/* Comparisons                                                            */
+
+int    mp_cmp_z(mp_int *a);
+int    mp_cmp_d(mp_int *a, mp_digit d);
+int    mp_cmp(mp_int *a, mp_int *b);
+int    mp_cmp_mag(mp_int *a, mp_int *b);
+int    mp_cmp_int(mp_int *a, long z);
+int    mp_isodd(mp_int *a);
+int    mp_iseven(mp_int *a);
+
+/*------------------------------------------------------------------------*/
+/* Number theoretic                                                       */
+
+#if MP_NUMTH
+mp_err mp_gcd(mp_int *a, mp_int *b, mp_int *c);
+mp_err mp_lcm(mp_int *a, mp_int *b, mp_int *c);
+mp_err mp_xgcd(mp_int *a, mp_int *b, mp_int *g, mp_int *x, mp_int *y);
+mp_err mp_invmod(mp_int *a, mp_int *m, mp_int *c);
+#endif /* end MP_NUMTH */
+
+/*------------------------------------------------------------------------*/
+/* Input and output                                                       */
+
+#if MP_IOFUNC
+void   mp_print(mp_int *mp, FILE *ofp);
+#endif /* end MP_IOFUNC */
+
+/*------------------------------------------------------------------------*/
+/* Base conversion                                                        */
+
+#define BITS     1
+#define BYTES    CHAR_BIT
+
+mp_err mp_read_signed_bin(mp_int *mp, unsigned char *str, int len);
+int    mp_signed_bin_size(mp_int *mp);
+mp_err mp_to_signed_bin(mp_int *mp, unsigned char *str);
+
+mp_err mp_read_unsigned_bin(mp_int *mp, unsigned char *str, int len);
+int    mp_unsigned_bin_size(mp_int *mp);
+mp_err mp_to_unsigned_bin(mp_int *mp, unsigned char *str);
+
+int    mp_count_bits(mp_int *mp);
+
+#if MP_COMPAT_MACROS
+#define mp_read_raw(mp, str, len) mp_read_signed_bin((mp), (str), (len))
+#define mp_raw_size(mp)           mp_signed_bin_size(mp)
+#define mp_toraw(mp, str)         mp_to_signed_bin((mp), (str))
+#define mp_read_mag(mp, str, len) mp_read_unsigned_bin((mp), (str), (len))
+#define mp_mag_size(mp)           mp_unsigned_bin_size(mp)
+#define mp_tomag(mp, str)         mp_to_unsigned_bin((mp), (str))
+#endif
+
+mp_err mp_read_radix(mp_int *mp, unsigned char *str, int radix);
+int    mp_radix_size(mp_int *mp, int radix);
+int    mp_value_radix_size(int num, int qty, int radix);
+mp_err mp_toradix(mp_int *mp, unsigned char *str, int radix);
+
+int    mp_char2value(char ch, int r);
+
+#define mp_tobinary(M, S)  mp_toradix((M), (S), 2)
+#define mp_tooctal(M, S)   mp_toradix((M), (S), 8)
+#define mp_todecimal(M, S) mp_toradix((M), (S), 10)
+#define mp_tohex(M, S)     mp_toradix((M), (S), 16)
+
+/*------------------------------------------------------------------------*/
+/* Error strings                                                          */
+
+const  char  *mp_strerror(mp_err ec);
+
+#endif /* end _H_MPI_ */
diff --git a/libtommath/mtest/mtest.c b/libtommath/mtest/mtest.c
new file mode 100644
index 0000000..d46f456
--- /dev/null
+++ b/libtommath/mtest/mtest.c
@@ -0,0 +1,304 @@
+/* makes a bignum test harness with NUM tests per operation
+ *
+ * the output is made in the following format [one parameter per line]
+
+operation
+operand1
+operand2
+[... operandN]
+result1
+result2
+[... resultN]
+
+So for example "a * b mod n" would be
+
+mulmod
+a
+b
+n
+a*b mod n
+
+e.g. if a=3, b=4 n=11 then
+
+mulmod
+3
+4
+11
+1
+
+ */
+
+#ifdef MP_8BIT
+#define THE_MASK 127
+#else
+#define THE_MASK 32767
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include "mpi.c"
+
+FILE *rng;
+
+void rand_num(mp_int *a)
+{
+   int n, size;
+   unsigned char buf[2048];
+
+   size = 1 + ((fgetc(rng)<<8) + fgetc(rng)) % 101;
+   buf[0] = (fgetc(rng)&1)?1:0;
+   fread(buf+1, 1, size, rng);
+   while (buf[1] == 0) buf[1] = fgetc(rng);
+   mp_read_raw(a, buf, 1+size);
+}
+
+void rand_num2(mp_int *a)
+{
+   int n, size;
+   unsigned char buf[2048];
+
+   size = 10 + ((fgetc(rng)<<8) + fgetc(rng)) % 101;
+   buf[0] = (fgetc(rng)&1)?1:0;
+   fread(buf+1, 1, size, rng);
+   while (buf[1] == 0) buf[1] = fgetc(rng);
+   mp_read_raw(a, buf, 1+size);
+}
+
+#define mp_to64(a, b) mp_toradix(a, b, 64)
+
+int main(void)
+{
+   int n, tmp;
+   mp_int a, b, c, d, e;
+   clock_t t1;
+   char buf[4096];
+
+   mp_init(&a);
+   mp_init(&b);
+   mp_init(&c);
+   mp_init(&d);
+   mp_init(&e);
+
+
+   /* initial (2^n - 1)^2 testing, makes sure the comba multiplier works [it has the new carry code] */
+/*
+   mp_set(&a, 1);
+   for (n = 1; n < 8192; n++) {
+       mp_mul(&a, &a, &c);
+       printf("mul\n");
+       mp_to64(&a, buf);
+       printf("%s\n%s\n", buf, buf);
+       mp_to64(&c, buf);
+       printf("%s\n", buf);
+
+       mp_add_d(&a, 1, &a);
+       mp_mul_2(&a, &a);
+       mp_sub_d(&a, 1, &a);
+   }
+*/
+
+   rng = fopen("/dev/urandom", "rb");
+   if (rng == NULL) {
+      rng = fopen("/dev/random", "rb");
+      if (rng == NULL) {
+         fprintf(stderr, "\nWarning:  stdin used as random source\n\n");
+         rng = stdin;
+      }
+   }
+
+   t1 = clock();
+   for (;;) {
+#if 0
+      if (clock() - t1 > CLOCKS_PER_SEC) {
+         sleep(2);
+         t1 = clock();
+      }
+#endif
+       n = fgetc(rng) % 15;
+
+   if (n == 0) {
+       /* add tests */
+       rand_num(&a);
+       rand_num(&b);
+       mp_add(&a, &b, &c);
+       printf("add\n");
+       mp_to64(&a, buf);
+       printf("%s\n", buf);
+       mp_to64(&b, buf);
+       printf("%s\n", buf);
+       mp_to64(&c, buf);
+       printf("%s\n", buf);
+   } else if (n == 1) {
+      /* sub tests */
+       rand_num(&a);
+       rand_num(&b);
+       mp_sub(&a, &b, &c);
+       printf("sub\n");
+       mp_to64(&a, buf);
+       printf("%s\n", buf);
+       mp_to64(&b, buf);
+       printf("%s\n", buf);
+       mp_to64(&c, buf);
+       printf("%s\n", buf);
+   } else if (n == 2) {
+       /* mul tests */
+       rand_num(&a);
+       rand_num(&b);
+       mp_mul(&a, &b, &c);
+       printf("mul\n");
+       mp_to64(&a, buf);
+       printf("%s\n", buf);
+       mp_to64(&b, buf);
+       printf("%s\n", buf);
+       mp_to64(&c, buf);
+       printf("%s\n", buf);
+   } else if (n == 3) {
+      /* div tests */
+       rand_num(&a);
+       rand_num(&b);
+       mp_div(&a, &b, &c, &d);
+       printf("div\n");
+       mp_to64(&a, buf);
+       printf("%s\n", buf);
+       mp_to64(&b, buf);
+       printf("%s\n", buf);
+       mp_to64(&c, buf);
+       printf("%s\n", buf);
+       mp_to64(&d, buf);
+       printf("%s\n", buf);
+   } else if (n == 4) {
+      /* sqr tests */
+       rand_num(&a);
+       mp_sqr(&a, &b);
+       printf("sqr\n");
+       mp_to64(&a, buf);
+       printf("%s\n", buf);
+       mp_to64(&b, buf);
+       printf("%s\n", buf);
+   } else if (n == 5) {
+      /* mul_2d test */
+      rand_num(&a);
+      mp_copy(&a, &b);
+      n = fgetc(rng) & 63;
+      mp_mul_2d(&b, n, &b);
+      mp_to64(&a, buf);
+      printf("mul2d\n");
+      printf("%s\n", buf);
+      printf("%d\n", n);
+      mp_to64(&b, buf);
+      printf("%s\n", buf);
+   } else if (n == 6) {
+      /* div_2d test */
+      rand_num(&a);
+      mp_copy(&a, &b);
+      n = fgetc(rng) & 63;
+      mp_div_2d(&b, n, &b, NULL);
+      mp_to64(&a, buf);
+      printf("div2d\n");
+      printf("%s\n", buf);
+      printf("%d\n", n);
+      mp_to64(&b, buf);
+      printf("%s\n", buf);
+   } else if (n == 7) {
+      /* gcd test */
+      rand_num(&a);
+      rand_num(&b);
+      a.sign = MP_ZPOS;
+      b.sign = MP_ZPOS;
+      mp_gcd(&a, &b, &c);
+      printf("gcd\n");
+      mp_to64(&a, buf);
+      printf("%s\n", buf);
+      mp_to64(&b, buf);
+      printf("%s\n", buf);
+      mp_to64(&c, buf);
+      printf("%s\n", buf);
+   } else if (n == 8) {
+      /* lcm test */
+      rand_num(&a);
+      rand_num(&b);
+      a.sign = MP_ZPOS;
+      b.sign = MP_ZPOS;
+      mp_lcm(&a, &b, &c);
+      printf("lcm\n");
+      mp_to64(&a, buf);
+      printf("%s\n", buf);
+      mp_to64(&b, buf);
+      printf("%s\n", buf);
+      mp_to64(&c, buf);
+      printf("%s\n", buf);
+   } else if (n == 9) {
+      /* exptmod test */
+      rand_num2(&a);
+      rand_num2(&b);
+      rand_num2(&c);
+//      if (c.dp[0]&1) mp_add_d(&c, 1, &c);
+      a.sign = b.sign = c.sign = 0;
+      mp_exptmod(&a, &b, &c, &d);
+      printf("expt\n");
+      mp_to64(&a, buf);
+      printf("%s\n", buf);
+      mp_to64(&b, buf);
+      printf("%s\n", buf);
+      mp_to64(&c, buf);
+      printf("%s\n", buf);
+      mp_to64(&d, buf);
+      printf("%s\n", buf);
+   } else if (n == 10) {
+      /* invmod test */
+      rand_num2(&a);
+      rand_num2(&b);
+      b.sign = MP_ZPOS;
+      a.sign = MP_ZPOS;
+      mp_gcd(&a, &b, &c);
+      if (mp_cmp_d(&c, 1) != 0) continue;
+      if (mp_cmp_d(&b, 1) == 0) continue;
+      mp_invmod(&a, &b, &c);
+      printf("invmod\n");
+      mp_to64(&a, buf);
+      printf("%s\n", buf);
+      mp_to64(&b, buf);
+      printf("%s\n", buf);
+      mp_to64(&c, buf);
+      printf("%s\n", buf);
+   } else if (n == 11) {
+      rand_num(&a);
+      mp_mul_2(&a, &a);
+      mp_div_2(&a, &b);
+      printf("div2\n");
+      mp_to64(&a, buf);
+      printf("%s\n", buf);
+      mp_to64(&b, buf);
+      printf("%s\n", buf);
+   } else if (n == 12) {
+      rand_num2(&a);
+      mp_mul_2(&a, &b);
+      printf("mul2\n");
+      mp_to64(&a, buf);
+      printf("%s\n", buf);
+      mp_to64(&b, buf);
+      printf("%s\n", buf);
+   } else if (n == 13) {
+      rand_num2(&a);
+      tmp = abs(rand()) & THE_MASK;
+      mp_add_d(&a, tmp, &b);
+      printf("add_d\n");
+      mp_to64(&a, buf);
+      printf("%s\n%d\n", buf, tmp);
+      mp_to64(&b, buf);
+      printf("%s\n", buf);
+   } else if (n == 14) {
+      rand_num2(&a);
+      tmp = abs(rand()) & THE_MASK;
+      mp_sub_d(&a, tmp, &b);
+      printf("sub_d\n");
+      mp_to64(&a, buf);
+      printf("%s\n%d\n", buf, tmp);
+      mp_to64(&b, buf);
+      printf("%s\n", buf);
+   }
+   }
+   fclose(rng);
+   return 0;
+}
diff --git a/libtommath/pics/design_process.sxd b/libtommath/pics/design_process.sxd
new file mode 100644
index 0000000..7414dbb
Binary files /dev/null and b/libtommath/pics/design_process.sxd differ
diff --git a/libtommath/pics/design_process.tif b/libtommath/pics/design_process.tif
new file mode 100644
index 0000000..4a0c012
Binary files /dev/null and b/libtommath/pics/design_process.tif differ
diff --git a/libtommath/pics/expt_state.sxd b/libtommath/pics/expt_state.sxd
new file mode 100644
index 0000000..6518404
Binary files /dev/null and b/libtommath/pics/expt_state.sxd differ
diff --git a/libtommath/pics/expt_state.tif b/libtommath/pics/expt_state.tif
new file mode 100644
index 0000000..0aaee39
Binary files /dev/null and b/libtommath/pics/expt_state.tif differ
diff --git a/libtommath/pics/makefile b/libtommath/pics/makefile
new file mode 100644
index 0000000..3ecb02f
--- /dev/null
+++ b/libtommath/pics/makefile
@@ -0,0 +1,35 @@
+# makes the images... yeah
+
+default:  pses
+
+design_process.ps: design_process.tif
+	tiff2ps -s -e design_process.tif > design_process.ps
+
+sliding_window.ps: sliding_window.tif
+	tiff2ps -s -e sliding_window.tif > sliding_window.ps
+	
+expt_state.ps: expt_state.tif
+	tiff2ps -s -e expt_state.tif > expt_state.ps
+
+primality.ps: primality.tif
+	tiff2ps -s -e primality.tif > primality.ps
+
+design_process.pdf: design_process.ps
+	epstopdf design_process.ps
+
+sliding_window.pdf: sliding_window.ps
+	epstopdf sliding_window.ps
+	
+expt_state.pdf: expt_state.ps
+	epstopdf expt_state.ps
+
+primality.pdf: primality.ps
+	epstopdf primality.ps
+
+
+pses: sliding_window.ps expt_state.ps primality.ps design_process.ps
+pdfes: sliding_window.pdf expt_state.pdf primality.pdf design_process.pdf
+
+clean:
+	rm -rf *.ps *.pdf .xvpics
+   
\ No newline at end of file
diff --git a/libtommath/pics/primality.tif b/libtommath/pics/primality.tif
new file mode 100644
index 0000000..83aafe0
Binary files /dev/null and b/libtommath/pics/primality.tif differ
diff --git a/libtommath/pics/radix.sxd b/libtommath/pics/radix.sxd
new file mode 100644
index 0000000..b9eb9a0
Binary files /dev/null and b/libtommath/pics/radix.sxd differ
diff --git a/libtommath/pics/sliding_window.sxd b/libtommath/pics/sliding_window.sxd
new file mode 100644
index 0000000..91e7c0d
Binary files /dev/null and b/libtommath/pics/sliding_window.sxd differ
diff --git a/libtommath/pics/sliding_window.tif b/libtommath/pics/sliding_window.tif
new file mode 100644
index 0000000..bb4cb96
Binary files /dev/null and b/libtommath/pics/sliding_window.tif differ
diff --git a/libtommath/poster.out b/libtommath/poster.out
new file mode 100644
index 0000000..e69de29
diff --git a/libtommath/poster.pdf b/libtommath/poster.pdf
new file mode 100644
index 0000000..1f705cf
Binary files /dev/null and b/libtommath/poster.pdf differ
diff --git a/libtommath/poster.tex b/libtommath/poster.tex
new file mode 100644
index 0000000..e7388f4
--- /dev/null
+++ b/libtommath/poster.tex
@@ -0,0 +1,35 @@
+\documentclass[landscape,11pt]{article}
+\usepackage{amsmath, amssymb}
+\usepackage{hyperref}
+\begin{document}
+\hspace*{-3in}
+\begin{tabular}{llllll}
+$c = a + b$  & {\tt mp\_add(\&a, \&b, \&c)} & $b = 2a$  & {\tt mp\_mul\_2(\&a, \&b)} & \\
+$c = a - b$  & {\tt mp\_sub(\&a, \&b, \&c)} & $b = a/2$ & {\tt mp\_div\_2(\&a, \&b)} & \\
+$c = ab $   & {\tt mp\_mul(\&a, \&b, \&c)}  & $c = 2^ba$  & {\tt mp\_mul\_2d(\&a, b, \&c)}  \\
+$b = a^2 $  & {\tt mp\_sqr(\&a, \&b)}       & $c = a/2^b, d = a \mod 2^b$ & {\tt mp\_div\_2d(\&a, b, \&c, \&d)} \\
+$c = \lfloor a/b \rfloor, d = a \mod b$ & {\tt mp\_div(\&a, \&b, \&c, \&d)} & $c = a \mod 2^b $  & {\tt mp\_mod\_2d(\&a, b, \&c)}  \\
+ && \\
+$a = b $  & {\tt mp\_set\_int(\&a, b)}  & $c = a \vee b$  & {\tt mp\_or(\&a, \&b, \&c)}  \\
+$b = a $  & {\tt mp\_copy(\&a, \&b)} & $c = a \wedge b$  & {\tt mp\_and(\&a, \&b, \&c)}  \\
+ && $c = a \oplus b$  & {\tt mp\_xor(\&a, \&b, \&c)}  \\
+ & \\
+$b = -a $  & {\tt mp\_neg(\&a, \&b)}  & $d = a + b \mod c$  & {\tt mp\_addmod(\&a, \&b, \&c, \&d)}  \\
+$b = |a| $  & {\tt mp\_abs(\&a, \&b)} & $d = a - b \mod c$  & {\tt mp\_submod(\&a, \&b, \&c, \&d)}  \\
+ && $d = ab \mod c$  & {\tt mp\_mulmod(\&a, \&b, \&c, \&d)}  \\
+Compare $a$ and $b$ & {\tt mp\_cmp(\&a, \&b)} & $c = a^2 \mod b$  & {\tt mp\_sqrmod(\&a, \&b, \&c)}  \\
+Is Zero? & {\tt mp\_iszero(\&a)} & $c = a^{-1} \mod b$  & {\tt mp\_invmod(\&a, \&b, \&c)} \\
+Is Even? & {\tt mp\_iseven(\&a)} & $d = a^b \mod c$ & {\tt mp\_exptmod(\&a, \&b, \&c, \&d)} \\
+Is Odd ? & {\tt mp\_isodd(\&a)} \\
+&\\
+$\vert \vert a \vert \vert$ & {\tt mp\_unsigned\_bin\_size(\&a)} & $res$ = 1 if $a$ prime to $t$ rounds? & {\tt mp\_prime\_is\_prime(\&a, t, \&res)} \\
+$buf \leftarrow a$          & {\tt mp\_to\_unsigned\_bin(\&a, buf)} & Next prime after $a$ to $t$ rounds. & {\tt mp\_prime\_next\_prime(\&a, t, bbs\_style)} \\
+$a \leftarrow buf[0..len-1]$          & {\tt mp\_read\_unsigned\_bin(\&a, buf, len)} \\
+&\\
+$b = \sqrt{a}$ & {\tt mp\_sqrt(\&a, \&b)}  & $c = \mbox{gcd}(a, b)$ & {\tt mp\_gcd(\&a, \&b, \&c)} \\
+$c = a^{1/b}$ & {\tt mp\_n\_root(\&a, b, \&c)} & $c = \mbox{lcm}(a, b)$ & {\tt mp\_lcm(\&a, \&b, \&c)} \\
+&\\
+Greater Than & MP\_GT & Equal To & MP\_EQ \\
+Less Than & MP\_LT & Bits per digit & DIGIT\_BIT \\
+\end{tabular}
+\end{document}
diff --git a/libtommath/pre_gen/mpi.c b/libtommath/pre_gen/mpi.c
new file mode 100644
index 0000000..d2224c0
--- /dev/null
+++ b/libtommath/pre_gen/mpi.c
@@ -0,0 +1,9048 @@
+/* Start: bn_error.c */
+#include <tommath.h>
+#ifdef BN_ERROR_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+static const struct {
+     int code;
+     char *msg;
+} msgs[] = {
+     { MP_OKAY, "Successful" },
+     { MP_MEM,  "Out of heap" },
+     { MP_VAL,  "Value out of range" }
+};
+
+/* return a char * string for a given code */
+char *mp_error_to_string(int code)
+{
+   int x;
+
+   /* scan the lookup table for the given message */
+   for (x = 0; x < (int)(sizeof(msgs) / sizeof(msgs[0])); x++) {
+       if (msgs[x].code == code) {
+          return msgs[x].msg;
+       }
+   }
+
+   /* generic reply for invalid code */
+   return "Invalid error code";
+}
+
+#endif
+
+/* End: bn_error.c */
+
+/* Start: bn_fast_mp_invmod.c */
+#include <tommath.h>
+#ifdef BN_FAST_MP_INVMOD_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* computes the modular inverse via binary extended euclidean algorithm, 
+ * that is c = 1/a mod b 
+ *
+ * Based on slow invmod except this is optimized for the case where b is 
+ * odd as per HAC Note 14.64 on pp. 610
+ */
+int fast_mp_invmod (mp_int * a, mp_int * b, mp_int * c)
+{
+  mp_int  x, y, u, v, B, D;
+  int     res, neg;
+
+  /* 2. [modified] b must be odd   */
+  if (mp_iseven (b) == 1) {
+    return MP_VAL;
+  }
+
+  /* init all our temps */
+  if ((res = mp_init_multi(&x, &y, &u, &v, &B, &D, NULL)) != MP_OKAY) {
+     return res;
+  }
+
+  /* x == modulus, y == value to invert */
+  if ((res = mp_copy (b, &x)) != MP_OKAY) {
+    goto LBL_ERR;
+  }
+
+  /* we need y = |a| */
+  if ((res = mp_mod (a, b, &y)) != MP_OKAY) {
+    goto LBL_ERR;
+  }
+
+  /* 3. u=x, v=y, A=1, B=0, C=0,D=1 */
+  if ((res = mp_copy (&x, &u)) != MP_OKAY) {
+    goto LBL_ERR;
+  }
+  if ((res = mp_copy (&y, &v)) != MP_OKAY) {
+    goto LBL_ERR;
+  }
+  mp_set (&D, 1);
+
+top:
+  /* 4.  while u is even do */
+  while (mp_iseven (&u) == 1) {
+    /* 4.1 u = u/2 */
+    if ((res = mp_div_2 (&u, &u)) != MP_OKAY) {
+      goto LBL_ERR;
+    }
+    /* 4.2 if B is odd then */
+    if (mp_isodd (&B) == 1) {
+      if ((res = mp_sub (&B, &x, &B)) != MP_OKAY) {
+        goto LBL_ERR;
+      }
+    }
+    /* B = B/2 */
+    if ((res = mp_div_2 (&B, &B)) != MP_OKAY) {
+      goto LBL_ERR;
+    }
+  }
+
+  /* 5.  while v is even do */
+  while (mp_iseven (&v) == 1) {
+    /* 5.1 v = v/2 */
+    if ((res = mp_div_2 (&v, &v)) != MP_OKAY) {
+      goto LBL_ERR;
+    }
+    /* 5.2 if D is odd then */
+    if (mp_isodd (&D) == 1) {
+      /* D = (D-x)/2 */
+      if ((res = mp_sub (&D, &x, &D)) != MP_OKAY) {
+        goto LBL_ERR;
+      }
+    }
+    /* D = D/2 */
+    if ((res = mp_div_2 (&D, &D)) != MP_OKAY) {
+      goto LBL_ERR;
+    }
+  }
+
+  /* 6.  if u >= v then */
+  if (mp_cmp (&u, &v) != MP_LT) {
+    /* u = u - v, B = B - D */
+    if ((res = mp_sub (&u, &v, &u)) != MP_OKAY) {
+      goto LBL_ERR;
+    }
+
+    if ((res = mp_sub (&B, &D, &B)) != MP_OKAY) {
+      goto LBL_ERR;
+    }
+  } else {
+    /* v - v - u, D = D - B */
+    if ((res = mp_sub (&v, &u, &v)) != MP_OKAY) {
+      goto LBL_ERR;
+    }
+
+    if ((res = mp_sub (&D, &B, &D)) != MP_OKAY) {
+      goto LBL_ERR;
+    }
+  }
+
+  /* if not zero goto step 4 */
+  if (mp_iszero (&u) == 0) {
+    goto top;
+  }
+
+  /* now a = C, b = D, gcd == g*v */
+
+  /* if v != 1 then there is no inverse */
+  if (mp_cmp_d (&v, 1) != MP_EQ) {
+    res = MP_VAL;
+    goto LBL_ERR;
+  }
+
+  /* b is now the inverse */
+  neg = a->sign;
+  while (D.sign == MP_NEG) {
+    if ((res = mp_add (&D, b, &D)) != MP_OKAY) {
+      goto LBL_ERR;
+    }
+  }
+  mp_exch (&D, c);
+  c->sign = neg;
+  res = MP_OKAY;
+
+LBL_ERR:mp_clear_multi (&x, &y, &u, &v, &B, &D, NULL);
+  return res;
+}
+#endif
+
+/* End: bn_fast_mp_invmod.c */
+
+/* Start: bn_fast_mp_montgomery_reduce.c */
+#include <tommath.h>
+#ifdef BN_FAST_MP_MONTGOMERY_REDUCE_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* computes xR**-1 == x (mod N) via Montgomery Reduction
+ *
+ * This is an optimized implementation of montgomery_reduce
+ * which uses the comba method to quickly calculate the columns of the
+ * reduction.
+ *
+ * Based on Algorithm 14.32 on pp.601 of HAC.
+*/
+int fast_mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho)
+{
+  int     ix, res, olduse;
+  mp_word W[MP_WARRAY];
+
+  /* get old used count */
+  olduse = x->used;
+
+  /* grow a as required */
+  if (x->alloc < n->used + 1) {
+    if ((res = mp_grow (x, n->used + 1)) != MP_OKAY) {
+      return res;
+    }
+  }
+
+  /* first we have to get the digits of the input into
+   * an array of double precision words W[...]
+   */
+  {
+    register mp_word *_W;
+    register mp_digit *tmpx;
+
+    /* alias for the W[] array */
+    _W   = W;
+
+    /* alias for the digits of  x*/
+    tmpx = x->dp;
+
+    /* copy the digits of a into W[0..a->used-1] */
+    for (ix = 0; ix < x->used; ix++) {
+      *_W++ = *tmpx++;
+    }
+
+    /* zero the high words of W[a->used..m->used*2] */
+    for (; ix < n->used * 2 + 1; ix++) {
+      *_W++ = 0;
+    }
+  }
+
+  /* now we proceed to zero successive digits
+   * from the least significant upwards
+   */
+  for (ix = 0; ix < n->used; ix++) {
+    /* mu = ai * m' mod b
+     *
+     * We avoid a double precision multiplication (which isn't required)
+     * by casting the value down to a mp_digit.  Note this requires
+     * that W[ix-1] have  the carry cleared (see after the inner loop)
+     */
+    register mp_digit mu;
+    mu = (mp_digit) (((W[ix] & MP_MASK) * rho) & MP_MASK);
+
+    /* a = a + mu * m * b**i
+     *
+     * This is computed in place and on the fly.  The multiplication
+     * by b**i is handled by offseting which columns the results
+     * are added to.
+     *
+     * Note the comba method normally doesn't handle carries in the
+     * inner loop In this case we fix the carry from the previous
+     * column since the Montgomery reduction requires digits of the
+     * result (so far) [see above] to work.  This is
+     * handled by fixing up one carry after the inner loop.  The
+     * carry fixups are done in order so after these loops the
+     * first m->used words of W[] have the carries fixed
+     */
+    {
+      register int iy;
+      register mp_digit *tmpn;
+      register mp_word *_W;
+
+      /* alias for the digits of the modulus */
+      tmpn = n->dp;
+
+      /* Alias for the columns set by an offset of ix */
+      _W = W + ix;
+
+      /* inner loop */
+      for (iy = 0; iy < n->used; iy++) {
+          *_W++ += ((mp_word)mu) * ((mp_word)*tmpn++);
+      }
+    }
+
+    /* now fix carry for next digit, W[ix+1] */
+    W[ix + 1] += W[ix] >> ((mp_word) DIGIT_BIT);
+  }
+
+  /* now we have to propagate the carries and
+   * shift the words downward [all those least
+   * significant digits we zeroed].
+   */
+  {
+    register mp_digit *tmpx;
+    register mp_word *_W, *_W1;
+
+    /* nox fix rest of carries */
+
+    /* alias for current word */
+    _W1 = W + ix;
+
+    /* alias for next word, where the carry goes */
+    _W = W + ++ix;
+
+    for (; ix <= n->used * 2 + 1; ix++) {
+      *_W++ += *_W1++ >> ((mp_word) DIGIT_BIT);
+    }
+
+    /* copy out, A = A/b**n
+     *
+     * The result is A/b**n but instead of converting from an
+     * array of mp_word to mp_digit than calling mp_rshd
+     * we just copy them in the right order
+     */
+
+    /* alias for destination word */
+    tmpx = x->dp;
+
+    /* alias for shifted double precision result */
+    _W = W + n->used;
+
+    for (ix = 0; ix < n->used + 1; ix++) {
+      *tmpx++ = (mp_digit)(*_W++ & ((mp_word) MP_MASK));
+    }
+
+    /* zero oldused digits, if the input a was larger than
+     * m->used+1 we'll have to clear the digits
+     */
+    for (; ix < olduse; ix++) {
+      *tmpx++ = 0;
+    }
+  }
+
+  /* set the max used and clamp */
+  x->used = n->used + 1;
+  mp_clamp (x);
+
+  /* if A >= m then A = A - m */
+  if (mp_cmp_mag (x, n) != MP_LT) {
+    return s_mp_sub (x, n, x);
+  }
+  return MP_OKAY;
+}
+#endif
+
+/* End: bn_fast_mp_montgomery_reduce.c */
+
+/* Start: bn_fast_s_mp_mul_digs.c */
+#include <tommath.h>
+#ifdef BN_FAST_S_MP_MUL_DIGS_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* Fast (comba) multiplier
+ *
+ * This is the fast column-array [comba] multiplier.  It is 
+ * designed to compute the columns of the product first 
+ * then handle the carries afterwards.  This has the effect 
+ * of making the nested loops that compute the columns very
+ * simple and schedulable on super-scalar processors.
+ *
+ * This has been modified to produce a variable number of 
+ * digits of output so if say only a half-product is required 
+ * you don't have to compute the upper half (a feature 
+ * required for fast Barrett reduction).
+ *
+ * Based on Algorithm 14.12 on pp.595 of HAC.
+ *
+ */
+int fast_s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs)
+{
+  int     olduse, res, pa, ix, iz;
+  mp_digit W[MP_WARRAY];
+  register mp_word  _W;
+
+  /* grow the destination as required */
+  if (c->alloc < digs) {
+    if ((res = mp_grow (c, digs)) != MP_OKAY) {
+      return res;
+    }
+  }
+
+  /* number of output digits to produce */
+  pa = MIN(digs, a->used + b->used);
+
+  /* clear the carry */
+  _W = 0;
+  for (ix = 0; ix < pa; ix++) { 
+      int      tx, ty;
+      int      iy;
+      mp_digit *tmpx, *tmpy;
+
+      /* get offsets into the two bignums */
+      ty = MIN(b->used-1, ix);
+      tx = ix - ty;
+
+      /* setup temp aliases */
+      tmpx = a->dp + tx;
+      tmpy = b->dp + ty;
+
+      /* this is the number of times the loop will iterrate, essentially 
+         while (tx++ < a->used && ty-- >= 0) { ... }
+       */
+      iy = MIN(a->used-tx, ty+1);
+
+      /* execute loop */
+      for (iz = 0; iz < iy; ++iz) {
+         _W += ((mp_word)*tmpx++)*((mp_word)*tmpy--);
+
+      }
+
+      /* store term */
+      W[ix] = ((mp_digit)_W) & MP_MASK;
+
+      /* make next carry */
+      _W = _W >> ((mp_word)DIGIT_BIT);
+ }
+
+  /* setup dest */
+  olduse  = c->used;
+  c->used = pa;
+
+  {
+    register mp_digit *tmpc;
+    tmpc = c->dp;
+    for (ix = 0; ix < pa+1; ix++) {
+      /* now extract the previous digit [below the carry] */
+      *tmpc++ = W[ix];
+    }
+
+    /* clear unused digits [that existed in the old copy of c] */
+    for (; ix < olduse; ix++) {
+      *tmpc++ = 0;
+    }
+  }
+  mp_clamp (c);
+  return MP_OKAY;
+}
+#endif
+
+/* End: bn_fast_s_mp_mul_digs.c */
+
+/* Start: bn_fast_s_mp_mul_high_digs.c */
+#include <tommath.h>
+#ifdef BN_FAST_S_MP_MUL_HIGH_DIGS_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* this is a modified version of fast_s_mul_digs that only produces
+ * output digits *above* digs.  See the comments for fast_s_mul_digs
+ * to see how it works.
+ *
+ * This is used in the Barrett reduction since for one of the multiplications
+ * only the higher digits were needed.  This essentially halves the work.
+ *
+ * Based on Algorithm 14.12 on pp.595 of HAC.
+ */
+int fast_s_mp_mul_high_digs (mp_int * a, mp_int * b, mp_int * c, int digs)
+{
+  int     olduse, res, pa, ix, iz;
+  mp_digit W[MP_WARRAY];
+  mp_word  _W;
+
+  /* grow the destination as required */
+  pa = a->used + b->used;
+  if (c->alloc < pa) {
+    if ((res = mp_grow (c, pa)) != MP_OKAY) {
+      return res;
+    }
+  }
+
+  /* number of output digits to produce */
+  pa = a->used + b->used;
+  _W = 0;
+  for (ix = digs; ix < pa; ix++) { 
+      int      tx, ty, iy;
+      mp_digit *tmpx, *tmpy;
+
+      /* get offsets into the two bignums */
+      ty = MIN(b->used-1, ix);
+      tx = ix - ty;
+
+      /* setup temp aliases */
+      tmpx = a->dp + tx;
+      tmpy = b->dp + ty;
+
+      /* this is the number of times the loop will iterrate, essentially its 
+         while (tx++ < a->used && ty-- >= 0) { ... }
+       */
+      iy = MIN(a->used-tx, ty+1);
+
+      /* execute loop */
+      for (iz = 0; iz < iy; iz++) {
+         _W += ((mp_word)*tmpx++)*((mp_word)*tmpy--);
+      }
+
+      /* store term */
+      W[ix] = ((mp_digit)_W) & MP_MASK;
+
+      /* make next carry */
+      _W = _W >> ((mp_word)DIGIT_BIT);
+  }
+  
+  /* setup dest */
+  olduse  = c->used;
+  c->used = pa;
+
+  {
+    register mp_digit *tmpc;
+
+    tmpc = c->dp + digs;
+    for (ix = digs; ix < pa; ix++) {
+      /* now extract the previous digit [below the carry] */
+      *tmpc++ = W[ix];
+    }
+
+    /* clear unused digits [that existed in the old copy of c] */
+    for (; ix < olduse; ix++) {
+      *tmpc++ = 0;
+    }
+  }
+  mp_clamp (c);
+  return MP_OKAY;
+}
+#endif
+
+/* End: bn_fast_s_mp_mul_high_digs.c */
+
+/* Start: bn_fast_s_mp_sqr.c */
+#include <tommath.h>
+#ifdef BN_FAST_S_MP_SQR_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* the jist of squaring...
+ * you do like mult except the offset of the tmpx [one that 
+ * starts closer to zero] can't equal the offset of tmpy.  
+ * So basically you set up iy like before then you min it with
+ * (ty-tx) so that it never happens.  You double all those 
+ * you add in the inner loop
+
+After that loop you do the squares and add them in.
+*/
+
+int fast_s_mp_sqr (mp_int * a, mp_int * b)
+{
+  int       olduse, res, pa, ix, iz;
+  mp_digit   W[MP_WARRAY], *tmpx;
+  mp_word   W1;
+
+  /* grow the destination as required */
+  pa = a->used + a->used;
+  if (b->alloc < pa) {
+    if ((res = mp_grow (b, pa)) != MP_OKAY) {
+      return res;
+    }
+  }
+
+  /* number of output digits to produce */
+  W1 = 0;
+  for (ix = 0; ix < pa; ix++) { 
+      int      tx, ty, iy;
+      mp_word  _W;
+      mp_digit *tmpy;
+
+      /* clear counter */
+      _W = 0;
+
+      /* get offsets into the two bignums */
+      ty = MIN(a->used-1, ix);
+      tx = ix - ty;
+
+      /* setup temp aliases */
+      tmpx = a->dp + tx;
+      tmpy = a->dp + ty;
+
+      /* this is the number of times the loop will iterrate, essentially
+         while (tx++ < a->used && ty-- >= 0) { ... }
+       */
+      iy = MIN(a->used-tx, ty+1);
+
+      /* now for squaring tx can never equal ty 
+       * we halve the distance since they approach at a rate of 2x
+       * and we have to round because odd cases need to be executed
+       */
+      iy = MIN(iy, (ty-tx+1)>>1);
+
+      /* execute loop */
+      for (iz = 0; iz < iy; iz++) {
+         _W += ((mp_word)*tmpx++)*((mp_word)*tmpy--);
+      }
+
+      /* double the inner product and add carry */
+      _W = _W + _W + W1;
+
+      /* even columns have the square term in them */
+      if ((ix&1) == 0) {
+         _W += ((mp_word)a->dp[ix>>1])*((mp_word)a->dp[ix>>1]);
+      }
+
+      /* store it */
+      W[ix] = (mp_digit)(_W & MP_MASK);
+
+      /* make next carry */
+      W1 = _W >> ((mp_word)DIGIT_BIT);
+  }
+
+  /* setup dest */
+  olduse  = b->used;
+  b->used = a->used+a->used;
+
+  {
+    mp_digit *tmpb;
+    tmpb = b->dp;
+    for (ix = 0; ix < pa; ix++) {
+      *tmpb++ = W[ix] & MP_MASK;
+    }
+
+    /* clear unused digits [that existed in the old copy of c] */
+    for (; ix < olduse; ix++) {
+      *tmpb++ = 0;
+    }
+  }
+  mp_clamp (b);
+  return MP_OKAY;
+}
+#endif
+
+/* End: bn_fast_s_mp_sqr.c */
+
+/* Start: bn_mp_2expt.c */
+#include <tommath.h>
+#ifdef BN_MP_2EXPT_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* computes a = 2**b 
+ *
+ * Simple algorithm which zeroes the int, grows it then just sets one bit
+ * as required.
+ */
+int
+mp_2expt (mp_int * a, int b)
+{
+  int     res;
+
+  /* zero a as per default */
+  mp_zero (a);
+
+  /* grow a to accomodate the single bit */
+  if ((res = mp_grow (a, b / DIGIT_BIT + 1)) != MP_OKAY) {
+    return res;
+  }
+
+  /* set the used count of where the bit will go */
+  a->used = b / DIGIT_BIT + 1;
+
+  /* put the single bit in its place */
+  a->dp[b / DIGIT_BIT] = ((mp_digit)1) << (b % DIGIT_BIT);
+
+  return MP_OKAY;
+}
+#endif
+
+/* End: bn_mp_2expt.c */
+
+/* Start: bn_mp_abs.c */
+#include <tommath.h>
+#ifdef BN_MP_ABS_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* b = |a| 
+ *
+ * Simple function copies the input and fixes the sign to positive
+ */
+int
+mp_abs (mp_int * a, mp_int * b)
+{
+  int     res;
+
+  /* copy a to b */
+  if (a != b) {
+     if ((res = mp_copy (a, b)) != MP_OKAY) {
+       return res;
+     }
+  }
+
+  /* force the sign of b to positive */
+  b->sign = MP_ZPOS;
+
+  return MP_OKAY;
+}
+#endif
+
+/* End: bn_mp_abs.c */
+
+/* Start: bn_mp_add.c */
+#include <tommath.h>
+#ifdef BN_MP_ADD_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* high level addition (handles signs) */
+int mp_add (mp_int * a, mp_int * b, mp_int * c)
+{
+  int     sa, sb, res;
+
+  /* get sign of both inputs */
+  sa = a->sign;
+  sb = b->sign;
+
+  /* handle two cases, not four */
+  if (sa == sb) {
+    /* both positive or both negative */
+    /* add their magnitudes, copy the sign */
+    c->sign = sa;
+    res = s_mp_add (a, b, c);
+  } else {
+    /* one positive, the other negative */
+    /* subtract the one with the greater magnitude from */
+    /* the one of the lesser magnitude.  The result gets */
+    /* the sign of the one with the greater magnitude. */
+    if (mp_cmp_mag (a, b) == MP_LT) {
+      c->sign = sb;
+      res = s_mp_sub (b, a, c);
+    } else {
+      c->sign = sa;
+      res = s_mp_sub (a, b, c);
+    }
+  }
+  return res;
+}
+
+#endif
+
+/* End: bn_mp_add.c */
+
+/* Start: bn_mp_add_d.c */
+#include <tommath.h>
+#ifdef BN_MP_ADD_D_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* single digit addition */
+int
+mp_add_d (mp_int * a, mp_digit b, mp_int * c)
+{
+  int     res, ix, oldused;
+  mp_digit *tmpa, *tmpc, mu;
+
+  /* grow c as required */
+  if (c->alloc < a->used + 1) {
+     if ((res = mp_grow(c, a->used + 1)) != MP_OKAY) {
+        return res;
+     }
+  }
+
+  /* if a is negative and |a| >= b, call c = |a| - b */
+  if (a->sign == MP_NEG && (a->used > 1 || a->dp[0] >= b)) {
+     /* temporarily fix sign of a */
+     a->sign = MP_ZPOS;
+
+     /* c = |a| - b */
+     res = mp_sub_d(a, b, c);
+
+     /* fix sign  */
+     a->sign = c->sign = MP_NEG;
+
+     /* clamp */
+     mp_clamp(c);
+
+     return res;
+  }
+
+  /* old number of used digits in c */
+  oldused = c->used;
+
+  /* sign always positive */
+  c->sign = MP_ZPOS;
+
+  /* source alias */
+  tmpa    = a->dp;
+
+  /* destination alias */
+  tmpc    = c->dp;
+
+  /* if a is positive */
+  if (a->sign == MP_ZPOS) {
+     /* add digit, after this we're propagating
+      * the carry.
+      */
+     *tmpc   = *tmpa++ + b;
+     mu      = *tmpc >> DIGIT_BIT;
+     *tmpc++ &= MP_MASK;
+
+     /* now handle rest of the digits */
+     for (ix = 1; ix < a->used; ix++) {
+        *tmpc   = *tmpa++ + mu;
+        mu      = *tmpc >> DIGIT_BIT;
+        *tmpc++ &= MP_MASK;
+     }
+     /* set final carry */
+     ix++;
+     *tmpc++  = mu;
+
+     /* setup size */
+     c->used = a->used + 1;
+  } else {
+     /* a was negative and |a| < b */
+     c->used  = 1;
+
+     /* the result is a single digit */
+     if (a->used == 1) {
+        *tmpc++  =  b - a->dp[0];
+     } else {
+        *tmpc++  =  b;
+     }
+
+     /* setup count so the clearing of oldused
+      * can fall through correctly
+      */
+     ix       = 1;
+  }
+
+  /* now zero to oldused */
+  while (ix++ < oldused) {
+     *tmpc++ = 0;
+  }
+  mp_clamp(c);
+
+  return MP_OKAY;
+}
+
+#endif
+
+/* End: bn_mp_add_d.c */
+
+/* Start: bn_mp_addmod.c */
+#include <tommath.h>
+#ifdef BN_MP_ADDMOD_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* d = a + b (mod c) */
+int
+mp_addmod (mp_int * a, mp_int * b, mp_int * c, mp_int * d)
+{
+  int     res;
+  mp_int  t;
+
+  if ((res = mp_init (&t)) != MP_OKAY) {
+    return res;
+  }
+
+  if ((res = mp_add (a, b, &t)) != MP_OKAY) {
+    mp_clear (&t);
+    return res;
+  }
+  res = mp_mod (&t, c, d);
+  mp_clear (&t);
+  return res;
+}
+#endif
+
+/* End: bn_mp_addmod.c */
+
+/* Start: bn_mp_and.c */
+#include <tommath.h>
+#ifdef BN_MP_AND_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* AND two ints together */
+int
+mp_and (mp_int * a, mp_int * b, mp_int * c)
+{
+  int     res, ix, px;
+  mp_int  t, *x;
+
+  if (a->used > b->used) {
+    if ((res = mp_init_copy (&t, a)) != MP_OKAY) {
+      return res;
+    }
+    px = b->used;
+    x = b;
+  } else {
+    if ((res = mp_init_copy (&t, b)) != MP_OKAY) {
+      return res;
+    }
+    px = a->used;
+    x = a;
+  }
+
+  for (ix = 0; ix < px; ix++) {
+    t.dp[ix] &= x->dp[ix];
+  }
+
+  /* zero digits above the last from the smallest mp_int */
+  for (; ix < t.used; ix++) {
+    t.dp[ix] = 0;
+  }
+
+  mp_clamp (&t);
+  mp_exch (c, &t);
+  mp_clear (&t);
+  return MP_OKAY;
+}
+#endif
+
+/* End: bn_mp_and.c */
+
+/* Start: bn_mp_clamp.c */
+#include <tommath.h>
+#ifdef BN_MP_CLAMP_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* trim unused digits 
+ *
+ * This is used to ensure that leading zero digits are
+ * trimed and the leading "used" digit will be non-zero
+ * Typically very fast.  Also fixes the sign if there
+ * are no more leading digits
+ */
+void
+mp_clamp (mp_int * a)
+{
+  /* decrease used while the most significant digit is
+   * zero.
+   */
+  while (a->used > 0 && a->dp[a->used - 1] == 0) {
+    --(a->used);
+  }
+
+  /* reset the sign flag if used == 0 */
+  if (a->used == 0) {
+    a->sign = MP_ZPOS;
+  }
+}
+#endif
+
+/* End: bn_mp_clamp.c */
+
+/* Start: bn_mp_clear.c */
+#include <tommath.h>
+#ifdef BN_MP_CLEAR_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* clear one (frees)  */
+void
+mp_clear (mp_int * a)
+{
+  int i;
+
+  /* only do anything if a hasn't been freed previously */
+  if (a->dp != NULL) {
+    /* first zero the digits */
+    for (i = 0; i < a->used; i++) {
+        a->dp[i] = 0;
+    }
+
+    /* free ram */
+    XFREE(a->dp);
+
+    /* reset members to make debugging easier */
+    a->dp    = NULL;
+    a->alloc = a->used = 0;
+    a->sign  = MP_ZPOS;
+  }
+}
+#endif
+
+/* End: bn_mp_clear.c */
+
+/* Start: bn_mp_clear_multi.c */
+#include <tommath.h>
+#ifdef BN_MP_CLEAR_MULTI_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+#include <stdarg.h>
+
+void mp_clear_multi(mp_int *mp, ...) 
+{
+    mp_int* next_mp = mp;
+    va_list args;
+    va_start(args, mp);
+    while (next_mp != NULL) {
+        mp_clear(next_mp);
+        next_mp = va_arg(args, mp_int*);
+    }
+    va_end(args);
+}
+#endif
+
+/* End: bn_mp_clear_multi.c */
+
+/* Start: bn_mp_cmp.c */
+#include <tommath.h>
+#ifdef BN_MP_CMP_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* compare two ints (signed)*/
+int
+mp_cmp (mp_int * a, mp_int * b)
+{
+  /* compare based on sign */
+  if (a->sign != b->sign) {
+     if (a->sign == MP_NEG) {
+        return MP_LT;
+     } else {
+        return MP_GT;
+     }
+  }
+  
+  /* compare digits */
+  if (a->sign == MP_NEG) {
+     /* if negative compare opposite direction */
+     return mp_cmp_mag(b, a);
+  } else {
+     return mp_cmp_mag(a, b);
+  }
+}
+#endif
+
+/* End: bn_mp_cmp.c */
+
+/* Start: bn_mp_cmp_d.c */
+#include <tommath.h>
+#ifdef BN_MP_CMP_D_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* compare a digit */
+int mp_cmp_d(mp_int * a, mp_digit b)
+{
+  /* compare based on sign */
+  if (a->sign == MP_NEG) {
+    return MP_LT;
+  }
+
+  /* compare based on magnitude */
+  if (a->used > 1) {
+    return MP_GT;
+  }
+
+  /* compare the only digit of a to b */
+  if (a->dp[0] > b) {
+    return MP_GT;
+  } else if (a->dp[0] < b) {
+    return MP_LT;
+  } else {
+    return MP_EQ;
+  }
+}
+#endif
+
+/* End: bn_mp_cmp_d.c */
+
+/* Start: bn_mp_cmp_mag.c */
+#include <tommath.h>
+#ifdef BN_MP_CMP_MAG_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* compare maginitude of two ints (unsigned) */
+int mp_cmp_mag (mp_int * a, mp_int * b)
+{
+  int     n;
+  mp_digit *tmpa, *tmpb;
+
+  /* compare based on # of non-zero digits */
+  if (a->used > b->used) {
+    return MP_GT;
+  }
+  
+  if (a->used < b->used) {
+    return MP_LT;
+  }
+
+  /* alias for a */
+  tmpa = a->dp + (a->used - 1);
+
+  /* alias for b */
+  tmpb = b->dp + (a->used - 1);
+
+  /* compare based on digits  */
+  for (n = 0; n < a->used; ++n, --tmpa, --tmpb) {
+    if (*tmpa > *tmpb) {
+      return MP_GT;
+    }
+
+    if (*tmpa < *tmpb) {
+      return MP_LT;
+    }
+  }
+  return MP_EQ;
+}
+#endif
+
+/* End: bn_mp_cmp_mag.c */
+
+/* Start: bn_mp_cnt_lsb.c */
+#include <tommath.h>
+#ifdef BN_MP_CNT_LSB_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+static const int lnz[16] = { 
+   4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0
+};
+
+/* Counts the number of lsbs which are zero before the first zero bit */
+int mp_cnt_lsb(mp_int *a)
+{
+   int x;
+   mp_digit q, qq;
+
+   /* easy out */
+   if (mp_iszero(a) == 1) {
+      return 0;
+   }
+
+   /* scan lower digits until non-zero */
+   for (x = 0; x < a->used && a->dp[x] == 0; x++);
+   q = a->dp[x];
+   x *= DIGIT_BIT;
+
+   /* now scan this digit until a 1 is found */
+   if ((q & 1) == 0) {
+      do {
+         qq  = q & 15;
+         x  += lnz[qq];
+         q >>= 4;
+      } while (qq == 0);
+   }
+   return x;
+}
+
+#endif
+
+/* End: bn_mp_cnt_lsb.c */
+
+/* Start: bn_mp_copy.c */
+#include <tommath.h>
+#ifdef BN_MP_COPY_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* copy, b = a */
+int
+mp_copy (mp_int * a, mp_int * b)
+{
+  int     res, n;
+
+  /* if dst == src do nothing */
+  if (a == b) {
+    return MP_OKAY;
+  }
+
+  /* grow dest */
+  if (b->alloc < a->used) {
+     if ((res = mp_grow (b, a->used)) != MP_OKAY) {
+        return res;
+     }
+  }
+
+  /* zero b and copy the parameters over */
+  {
+    register mp_digit *tmpa, *tmpb;
+
+    /* pointer aliases */
+
+    /* source */
+    tmpa = a->dp;
+
+    /* destination */
+    tmpb = b->dp;
+
+    /* copy all the digits */
+    for (n = 0; n < a->used; n++) {
+      *tmpb++ = *tmpa++;
+    }
+
+    /* clear high digits */
+    for (; n < b->used; n++) {
+      *tmpb++ = 0;
+    }
+  }
+
+  /* copy used count and sign */
+  b->used = a->used;
+  b->sign = a->sign;
+  return MP_OKAY;
+}
+#endif
+
+/* End: bn_mp_copy.c */
+
+/* Start: bn_mp_count_bits.c */
+#include <tommath.h>
+#ifdef BN_MP_COUNT_BITS_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* returns the number of bits in an int */
+int
+mp_count_bits (mp_int * a)
+{
+  int     r;
+  mp_digit q;
+
+  /* shortcut */
+  if (a->used == 0) {
+    return 0;
+  }
+
+  /* get number of digits and add that */
+  r = (a->used - 1) * DIGIT_BIT;
+  
+  /* take the last digit and count the bits in it */
+  q = a->dp[a->used - 1];
+  while (q > ((mp_digit) 0)) {
+    ++r;
+    q >>= ((mp_digit) 1);
+  }
+  return r;
+}
+#endif
+
+/* End: bn_mp_count_bits.c */
+
+/* Start: bn_mp_div.c */
+#include <tommath.h>
+#ifdef BN_MP_DIV_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+#ifdef BN_MP_DIV_SMALL
+
+/* slower bit-bang division... also smaller */
+int mp_div(mp_int * a, mp_int * b, mp_int * c, mp_int * d)
+{
+   mp_int ta, tb, tq, q;
+   int    res, n, n2;
+
+  /* is divisor zero ? */
+  if (mp_iszero (b) == 1) {
+    return MP_VAL;
+  }
+
+  /* if a < b then q=0, r = a */
+  if (mp_cmp_mag (a, b) == MP_LT) {
+    if (d != NULL) {
+      res = mp_copy (a, d);
+    } else {
+      res = MP_OKAY;
+    }
+    if (c != NULL) {
+      mp_zero (c);
+    }
+    return res;
+  }
+	
+  /* init our temps */
+  if ((res = mp_init_multi(&ta, &tb, &tq, &q, NULL) != MP_OKAY)) {
+     return res;
+  }
+
+
+  mp_set(&tq, 1);
+  n = mp_count_bits(a) - mp_count_bits(b);
+  if (((res = mp_abs(a, &ta)) != MP_OKAY) ||
+      ((res = mp_abs(b, &tb)) != MP_OKAY) || 
+      ((res = mp_mul_2d(&tb, n, &tb)) != MP_OKAY) ||
+      ((res = mp_mul_2d(&tq, n, &tq)) != MP_OKAY)) {
+      goto LBL_ERR;
+  }
+
+  while (n-- >= 0) {
+     if (mp_cmp(&tb, &ta) != MP_GT) {
+        if (((res = mp_sub(&ta, &tb, &ta)) != MP_OKAY) ||
+            ((res = mp_add(&q, &tq, &q)) != MP_OKAY)) {
+           goto LBL_ERR;
+        }
+     }
+     if (((res = mp_div_2d(&tb, 1, &tb, NULL)) != MP_OKAY) ||
+         ((res = mp_div_2d(&tq, 1, &tq, NULL)) != MP_OKAY)) {
+           goto LBL_ERR;
+     }
+  }
+
+  /* now q == quotient and ta == remainder */
+  n  = a->sign;
+  n2 = (a->sign == b->sign ? MP_ZPOS : MP_NEG);
+  if (c != NULL) {
+     mp_exch(c, &q);
+     c->sign  = (mp_iszero(c) == MP_YES) ? MP_ZPOS : n2;
+  }
+  if (d != NULL) {
+     mp_exch(d, &ta);
+     d->sign = (mp_iszero(d) == MP_YES) ? MP_ZPOS : n;
+  }
+LBL_ERR:
+   mp_clear_multi(&ta, &tb, &tq, &q, NULL);
+   return res;
+}
+
+#else
+
+/* integer signed division. 
+ * c*b + d == a [e.g. a/b, c=quotient, d=remainder]
+ * HAC pp.598 Algorithm 14.20
+ *
+ * Note that the description in HAC is horribly 
+ * incomplete.  For example, it doesn't consider 
+ * the case where digits are removed from 'x' in 
+ * the inner loop.  It also doesn't consider the 
+ * case that y has fewer than three digits, etc..
+ *
+ * The overall algorithm is as described as 
+ * 14.20 from HAC but fixed to treat these cases.
+*/
+int mp_div (mp_int * a, mp_int * b, mp_int * c, mp_int * d)
+{
+  mp_int  q, x, y, t1, t2;
+  int     res, n, t, i, norm, neg;
+
+  /* is divisor zero ? */
+  if (mp_iszero (b) == 1) {
+    return MP_VAL;
+  }
+
+  /* if a < b then q=0, r = a */
+  if (mp_cmp_mag (a, b) == MP_LT) {
+    if (d != NULL) {
+      res = mp_copy (a, d);
+    } else {
+      res = MP_OKAY;
+    }
+    if (c != NULL) {
+      mp_zero (c);
+    }
+    return res;
+  }
+
+  if ((res = mp_init_size (&q, a->used + 2)) != MP_OKAY) {
+    return res;
+  }
+  q.used = a->used + 2;
+
+  if ((res = mp_init (&t1)) != MP_OKAY) {
+    goto LBL_Q;
+  }
+
+  if ((res = mp_init (&t2)) != MP_OKAY) {
+    goto LBL_T1;
+  }
+
+  if ((res = mp_init_copy (&x, a)) != MP_OKAY) {
+    goto LBL_T2;
+  }
+
+  if ((res = mp_init_copy (&y, b)) != MP_OKAY) {
+    goto LBL_X;
+  }
+
+  /* fix the sign */
+  neg = (a->sign == b->sign) ? MP_ZPOS : MP_NEG;
+  x.sign = y.sign = MP_ZPOS;
+
+  /* normalize both x and y, ensure that y >= b/2, [b == 2**DIGIT_BIT] */
+  norm = mp_count_bits(&y) % DIGIT_BIT;
+  if (norm < (int)(DIGIT_BIT-1)) {
+     norm = (DIGIT_BIT-1) - norm;
+     if ((res = mp_mul_2d (&x, norm, &x)) != MP_OKAY) {
+       goto LBL_Y;
+     }
+     if ((res = mp_mul_2d (&y, norm, &y)) != MP_OKAY) {
+       goto LBL_Y;
+     }
+  } else {
+     norm = 0;
+  }
+
+  /* note hac does 0 based, so if used==5 then its 0,1,2,3,4, e.g. use 4 */
+  n = x.used - 1;
+  t = y.used - 1;
+
+  /* while (x >= y*b**n-t) do { q[n-t] += 1; x -= y*b**{n-t} } */
+  if ((res = mp_lshd (&y, n - t)) != MP_OKAY) { /* y = y*b**{n-t} */
+    goto LBL_Y;
+  }
+
+  while (mp_cmp (&x, &y) != MP_LT) {
+    ++(q.dp[n - t]);
+    if ((res = mp_sub (&x, &y, &x)) != MP_OKAY) {
+      goto LBL_Y;
+    }
+  }
+
+  /* reset y by shifting it back down */
+  mp_rshd (&y, n - t);
+
+  /* step 3. for i from n down to (t + 1) */
+  for (i = n; i >= (t + 1); i--) {
+    if (i > x.used) {
+      continue;
+    }
+
+    /* step 3.1 if xi == yt then set q{i-t-1} to b-1, 
+     * otherwise set q{i-t-1} to (xi*b + x{i-1})/yt */
+    if (x.dp[i] == y.dp[t]) {
+      q.dp[i - t - 1] = ((((mp_digit)1) << DIGIT_BIT) - 1);
+    } else {
+      mp_word tmp;
+      tmp = ((mp_word) x.dp[i]) << ((mp_word) DIGIT_BIT);
+      tmp |= ((mp_word) x.dp[i - 1]);
+      tmp /= ((mp_word) y.dp[t]);
+      if (tmp > (mp_word) MP_MASK)
+        tmp = MP_MASK;
+      q.dp[i - t - 1] = (mp_digit) (tmp & (mp_word) (MP_MASK));
+    }
+
+    /* while (q{i-t-1} * (yt * b + y{t-1})) > 
+             xi * b**2 + xi-1 * b + xi-2 
+     
+       do q{i-t-1} -= 1; 
+    */
+    q.dp[i - t - 1] = (q.dp[i - t - 1] + 1) & MP_MASK;
+    do {
+      q.dp[i - t - 1] = (q.dp[i - t - 1] - 1) & MP_MASK;
+
+      /* find left hand */
+      mp_zero (&t1);
+      t1.dp[0] = (t - 1 < 0) ? 0 : y.dp[t - 1];
+      t1.dp[1] = y.dp[t];
+      t1.used = 2;
+      if ((res = mp_mul_d (&t1, q.dp[i - t - 1], &t1)) != MP_OKAY) {
+        goto LBL_Y;
+      }
+
+      /* find right hand */
+      t2.dp[0] = (i - 2 < 0) ? 0 : x.dp[i - 2];
+      t2.dp[1] = (i - 1 < 0) ? 0 : x.dp[i - 1];
+      t2.dp[2] = x.dp[i];
+      t2.used = 3;
+    } while (mp_cmp_mag(&t1, &t2) == MP_GT);
+
+    /* step 3.3 x = x - q{i-t-1} * y * b**{i-t-1} */
+    if ((res = mp_mul_d (&y, q.dp[i - t - 1], &t1)) != MP_OKAY) {
+      goto LBL_Y;
+    }
+
+    if ((res = mp_lshd (&t1, i - t - 1)) != MP_OKAY) {
+      goto LBL_Y;
+    }
+
+    if ((res = mp_sub (&x, &t1, &x)) != MP_OKAY) {
+      goto LBL_Y;
+    }
+
+    /* if x < 0 then { x = x + y*b**{i-t-1}; q{i-t-1} -= 1; } */
+    if (x.sign == MP_NEG) {
+      if ((res = mp_copy (&y, &t1)) != MP_OKAY) {
+        goto LBL_Y;
+      }
+      if ((res = mp_lshd (&t1, i - t - 1)) != MP_OKAY) {
+        goto LBL_Y;
+      }
+      if ((res = mp_add (&x, &t1, &x)) != MP_OKAY) {
+        goto LBL_Y;
+      }
+
+      q.dp[i - t - 1] = (q.dp[i - t - 1] - 1UL) & MP_MASK;
+    }
+  }
+
+  /* now q is the quotient and x is the remainder 
+   * [which we have to normalize] 
+   */
+  
+  /* get sign before writing to c */
+  x.sign = x.used == 0 ? MP_ZPOS : a->sign;
+
+  if (c != NULL) {
+    mp_clamp (&q);
+    mp_exch (&q, c);
+    c->sign = neg;
+  }
+
+  if (d != NULL) {
+    mp_div_2d (&x, norm, &x, NULL);
+    mp_exch (&x, d);
+  }
+
+  res = MP_OKAY;
+
+LBL_Y:mp_clear (&y);
+LBL_X:mp_clear (&x);
+LBL_T2:mp_clear (&t2);
+LBL_T1:mp_clear (&t1);
+LBL_Q:mp_clear (&q);
+  return res;
+}
+
+#endif
+
+#endif
+
+/* End: bn_mp_div.c */
+
+/* Start: bn_mp_div_2.c */
+#include <tommath.h>
+#ifdef BN_MP_DIV_2_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* b = a/2 */
+int mp_div_2(mp_int * a, mp_int * b)
+{
+  int     x, res, oldused;
+
+  /* copy */
+  if (b->alloc < a->used) {
+    if ((res = mp_grow (b, a->used)) != MP_OKAY) {
+      return res;
+    }
+  }
+
+  oldused = b->used;
+  b->used = a->used;
+  {
+    register mp_digit r, rr, *tmpa, *tmpb;
+
+    /* source alias */
+    tmpa = a->dp + b->used - 1;
+
+    /* dest alias */
+    tmpb = b->dp + b->used - 1;
+
+    /* carry */
+    r = 0;
+    for (x = b->used - 1; x >= 0; x--) {
+      /* get the carry for the next iteration */
+      rr = *tmpa & 1;
+
+      /* shift the current digit, add in carry and store */
+      *tmpb-- = (*tmpa-- >> 1) | (r << (DIGIT_BIT - 1));
+
+      /* forward carry to next iteration */
+      r = rr;
+    }
+
+    /* zero excess digits */
+    tmpb = b->dp + b->used;
+    for (x = b->used; x < oldused; x++) {
+      *tmpb++ = 0;
+    }
+  }
+  b->sign = a->sign;
+  mp_clamp (b);
+  return MP_OKAY;
+}
+#endif
+
+/* End: bn_mp_div_2.c */
+
+/* Start: bn_mp_div_2d.c */
+#include <tommath.h>
+#ifdef BN_MP_DIV_2D_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* shift right by a certain bit count (store quotient in c, optional remainder in d) */
+int mp_div_2d (mp_int * a, int b, mp_int * c, mp_int * d)
+{
+  mp_digit D, r, rr;
+  int     x, res;
+  mp_int  t;
+
+
+  /* if the shift count is <= 0 then we do no work */
+  if (b <= 0) {
+    res = mp_copy (a, c);
+    if (d != NULL) {
+      mp_zero (d);
+    }
+    return res;
+  }
+
+  if ((res = mp_init (&t)) != MP_OKAY) {
+    return res;
+  }
+
+  /* get the remainder */
+  if (d != NULL) {
+    if ((res = mp_mod_2d (a, b, &t)) != MP_OKAY) {
+      mp_clear (&t);
+      return res;
+    }
+  }
+
+  /* copy */
+  if ((res = mp_copy (a, c)) != MP_OKAY) {
+    mp_clear (&t);
+    return res;
+  }
+
+  /* shift by as many digits in the bit count */
+  if (b >= (int)DIGIT_BIT) {
+    mp_rshd (c, b / DIGIT_BIT);
+  }
+
+  /* shift any bit count < DIGIT_BIT */
+  D = (mp_digit) (b % DIGIT_BIT);
+  if (D != 0) {
+    register mp_digit *tmpc, mask, shift;
+
+    /* mask */
+    mask = (((mp_digit)1) << D) - 1;
+
+    /* shift for lsb */
+    shift = DIGIT_BIT - D;
+
+    /* alias */
+    tmpc = c->dp + (c->used - 1);
+
+    /* carry */
+    r = 0;
+    for (x = c->used - 1; x >= 0; x--) {
+      /* get the lower  bits of this word in a temp */
+      rr = *tmpc & mask;
+
+      /* shift the current word and mix in the carry bits from the previous word */
+      *tmpc = (*tmpc >> D) | (r << shift);
+      --tmpc;
+
+      /* set the carry to the carry bits of the current word found above */
+      r = rr;
+    }
+  }
+  mp_clamp (c);
+  if (d != NULL) {
+    mp_exch (&t, d);
+  }
+  mp_clear (&t);
+  return MP_OKAY;
+}
+#endif
+
+/* End: bn_mp_div_2d.c */
+
+/* Start: bn_mp_div_3.c */
+#include <tommath.h>
+#ifdef BN_MP_DIV_3_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* divide by three (based on routine from MPI and the GMP manual) */
+int
+mp_div_3 (mp_int * a, mp_int *c, mp_digit * d)
+{
+  mp_int   q;
+  mp_word  w, t;
+  mp_digit b;
+  int      res, ix;
+  
+  /* b = 2**DIGIT_BIT / 3 */
+  b = (((mp_word)1) << ((mp_word)DIGIT_BIT)) / ((mp_word)3);
+
+  if ((res = mp_init_size(&q, a->used)) != MP_OKAY) {
+     return res;
+  }
+  
+  q.used = a->used;
+  q.sign = a->sign;
+  w = 0;
+  for (ix = a->used - 1; ix >= 0; ix--) {
+     w = (w << ((mp_word)DIGIT_BIT)) | ((mp_word)a->dp[ix]);
+
+     if (w >= 3) {
+        /* multiply w by [1/3] */
+        t = (w * ((mp_word)b)) >> ((mp_word)DIGIT_BIT);
+
+        /* now subtract 3 * [w/3] from w, to get the remainder */
+        w -= t+t+t;
+
+        /* fixup the remainder as required since
+         * the optimization is not exact.
+         */
+        while (w >= 3) {
+           t += 1;
+           w -= 3;
+        }
+      } else {
+        t = 0;
+      }
+      q.dp[ix] = (mp_digit)t;
+  }
+
+  /* [optional] store the remainder */
+  if (d != NULL) {
+     *d = (mp_digit)w;
+  }
+
+  /* [optional] store the quotient */
+  if (c != NULL) {
+     mp_clamp(&q);
+     mp_exch(&q, c);
+  }
+  mp_clear(&q);
+  
+  return res;
+}
+
+#endif
+
+/* End: bn_mp_div_3.c */
+
+/* Start: bn_mp_div_d.c */
+#include <tommath.h>
+#ifdef BN_MP_DIV_D_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+static int s_is_power_of_two(mp_digit b, int *p)
+{
+   int x;
+
+   /* fast return if no power of two */
+   if ((b==0) || (b & (b-1))) {
+      return 0;
+   }
+
+   for (x = 0; x < DIGIT_BIT; x++) {
+      if (b == (((mp_digit)1)<<x)) {
+         *p = x;
+         return 1;
+      }
+   }
+   return 0;
+}
+
+/* single digit division (based on routine from MPI) */
+int mp_div_d (mp_int * a, mp_digit b, mp_int * c, mp_digit * d)
+{
+  mp_int  q;
+  mp_word w;
+  mp_digit t;
+  int     res, ix;
+
+  /* cannot divide by zero */
+  if (b == 0) {
+     return MP_VAL;
+  }
+
+  /* quick outs */
+  if (b == 1 || mp_iszero(a) == 1) {
+     if (d != NULL) {
+        *d = 0;
+     }
+     if (c != NULL) {
+        return mp_copy(a, c);
+     }
+     return MP_OKAY;
+  }
+
+  /* power of two ? */
+  if (s_is_power_of_two(b, &ix) == 1) {
+     if (d != NULL) {
+        *d = a->dp[0] & ((((mp_digit)1)<<ix) - 1);
+     }
+     if (c != NULL) {
+        return mp_div_2d(a, ix, c, NULL);
+     }
+     return MP_OKAY;
+  }
+
+#ifdef BN_MP_DIV_3_C
+  /* three? */
+  if (b == 3) {
+     return mp_div_3(a, c, d);
+  }
+#endif
+
+  /* no easy answer [c'est la vie].  Just division */
+  if ((res = mp_init_size(&q, a->used)) != MP_OKAY) {
+     return res;
+  }
+  
+  q.used = a->used;
+  q.sign = a->sign;
+  w = 0;
+  for (ix = a->used - 1; ix >= 0; ix--) {
+     w = (w << ((mp_word)DIGIT_BIT)) | ((mp_word)a->dp[ix]);
+     
+     if (w >= b) {
+        t = (mp_digit)(w / b);
+        w -= ((mp_word)t) * ((mp_word)b);
+      } else {
+        t = 0;
+      }
+      q.dp[ix] = (mp_digit)t;
+  }
+  
+  if (d != NULL) {
+     *d = (mp_digit)w;
+  }
+  
+  if (c != NULL) {
+     mp_clamp(&q);
+     mp_exch(&q, c);
+  }
+  mp_clear(&q);
+  
+  return res;
+}
+
+#endif
+
+/* End: bn_mp_div_d.c */
+
+/* Start: bn_mp_dr_is_modulus.c */
+#include <tommath.h>
+#ifdef BN_MP_DR_IS_MODULUS_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* determines if a number is a valid DR modulus */
+int mp_dr_is_modulus(mp_int *a)
+{
+   int ix;
+
+   /* must be at least two digits */
+   if (a->used < 2) {
+      return 0;
+   }
+
+   /* must be of the form b**k - a [a <= b] so all
+    * but the first digit must be equal to -1 (mod b).
+    */
+   for (ix = 1; ix < a->used; ix++) {
+       if (a->dp[ix] != MP_MASK) {
+          return 0;
+       }
+   }
+   return 1;
+}
+
+#endif
+
+/* End: bn_mp_dr_is_modulus.c */
+
+/* Start: bn_mp_dr_reduce.c */
+#include <tommath.h>
+#ifdef BN_MP_DR_REDUCE_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* reduce "x" in place modulo "n" using the Diminished Radix algorithm.
+ *
+ * Based on algorithm from the paper
+ *
+ * "Generating Efficient Primes for Discrete Log Cryptosystems"
+ *                 Chae Hoon Lim, Pil Joong Lee,
+ *          POSTECH Information Research Laboratories
+ *
+ * The modulus must be of a special format [see manual]
+ *
+ * Has been modified to use algorithm 7.10 from the LTM book instead
+ *
+ * Input x must be in the range 0 <= x <= (n-1)**2
+ */
+int
+mp_dr_reduce (mp_int * x, mp_int * n, mp_digit k)
+{
+  int      err, i, m;
+  mp_word  r;
+  mp_digit mu, *tmpx1, *tmpx2;
+
+  /* m = digits in modulus */
+  m = n->used;
+
+  /* ensure that "x" has at least 2m digits */
+  if (x->alloc < m + m) {
+    if ((err = mp_grow (x, m + m)) != MP_OKAY) {
+      return err;
+    }
+  }
+
+/* top of loop, this is where the code resumes if
+ * another reduction pass is required.
+ */
+top:
+  /* aliases for digits */
+  /* alias for lower half of x */
+  tmpx1 = x->dp;
+
+  /* alias for upper half of x, or x/B**m */
+  tmpx2 = x->dp + m;
+
+  /* set carry to zero */
+  mu = 0;
+
+  /* compute (x mod B**m) + k * [x/B**m] inline and inplace */
+  for (i = 0; i < m; i++) {
+      r         = ((mp_word)*tmpx2++) * ((mp_word)k) + *tmpx1 + mu;
+      *tmpx1++  = (mp_digit)(r & MP_MASK);
+      mu        = (mp_digit)(r >> ((mp_word)DIGIT_BIT));
+  }
+
+  /* set final carry */
+  *tmpx1++ = mu;
+
+  /* zero words above m */
+  for (i = m + 1; i < x->used; i++) {
+      *tmpx1++ = 0;
+  }
+
+  /* clamp, sub and return */
+  mp_clamp (x);
+
+  /* if x >= n then subtract and reduce again
+   * Each successive "recursion" makes the input smaller and smaller.
+   */
+  if (mp_cmp_mag (x, n) != MP_LT) {
+    s_mp_sub(x, n, x);
+    goto top;
+  }
+  return MP_OKAY;
+}
+#endif
+
+/* End: bn_mp_dr_reduce.c */
+
+/* Start: bn_mp_dr_setup.c */
+#include <tommath.h>
+#ifdef BN_MP_DR_SETUP_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* determines the setup value */
+void mp_dr_setup(mp_int *a, mp_digit *d)
+{
+   /* the casts are required if DIGIT_BIT is one less than
+    * the number of bits in a mp_digit [e.g. DIGIT_BIT==31]
+    */
+   *d = (mp_digit)((((mp_word)1) << ((mp_word)DIGIT_BIT)) - 
+        ((mp_word)a->dp[0]));
+}
+
+#endif
+
+/* End: bn_mp_dr_setup.c */
+
+/* Start: bn_mp_exch.c */
+#include <tommath.h>
+#ifdef BN_MP_EXCH_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* swap the elements of two integers, for cases where you can't simply swap the 
+ * mp_int pointers around
+ */
+void
+mp_exch (mp_int * a, mp_int * b)
+{
+  mp_int  t;
+
+  t  = *a;
+  *a = *b;
+  *b = t;
+}
+#endif
+
+/* End: bn_mp_exch.c */
+
+/* Start: bn_mp_expt_d.c */
+#include <tommath.h>
+#ifdef BN_MP_EXPT_D_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* calculate c = a**b  using a square-multiply algorithm */
+int mp_expt_d (mp_int * a, mp_digit b, mp_int * c)
+{
+  int     res, x;
+  mp_int  g;
+
+  if ((res = mp_init_copy (&g, a)) != MP_OKAY) {
+    return res;
+  }
+
+  /* set initial result */
+  mp_set (c, 1);
+
+  for (x = 0; x < (int) DIGIT_BIT; x++) {
+    /* square */
+    if ((res = mp_sqr (c, c)) != MP_OKAY) {
+      mp_clear (&g);
+      return res;
+    }
+
+    /* if the bit is set multiply */
+    if ((b & (mp_digit) (((mp_digit)1) << (DIGIT_BIT - 1))) != 0) {
+      if ((res = mp_mul (c, &g, c)) != MP_OKAY) {
+         mp_clear (&g);
+         return res;
+      }
+    }
+
+    /* shift to next bit */
+    b <<= 1;
+  }
+
+  mp_clear (&g);
+  return MP_OKAY;
+}
+#endif
+
+/* End: bn_mp_expt_d.c */
+
+/* Start: bn_mp_exptmod.c */
+#include <tommath.h>
+#ifdef BN_MP_EXPTMOD_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+
+/* this is a shell function that calls either the normal or Montgomery
+ * exptmod functions.  Originally the call to the montgomery code was
+ * embedded in the normal function but that wasted alot of stack space
+ * for nothing (since 99% of the time the Montgomery code would be called)
+ */
+int mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y)
+{
+  int dr;
+
+  /* modulus P must be positive */
+  if (P->sign == MP_NEG) {
+     return MP_VAL;
+  }
+
+  /* if exponent X is negative we have to recurse */
+  if (X->sign == MP_NEG) {
+#ifdef BN_MP_INVMOD_C
+     mp_int tmpG, tmpX;
+     int err;
+
+     /* first compute 1/G mod P */
+     if ((err = mp_init(&tmpG)) != MP_OKAY) {
+        return err;
+     }
+     if ((err = mp_invmod(G, P, &tmpG)) != MP_OKAY) {
+        mp_clear(&tmpG);
+        return err;
+     }
+
+     /* now get |X| */
+     if ((err = mp_init(&tmpX)) != MP_OKAY) {
+        mp_clear(&tmpG);
+        return err;
+     }
+     if ((err = mp_abs(X, &tmpX)) != MP_OKAY) {
+        mp_clear_multi(&tmpG, &tmpX, NULL);
+        return err;
+     }
+
+     /* and now compute (1/G)**|X| instead of G**X [X < 0] */
+     err = mp_exptmod(&tmpG, &tmpX, P, Y);
+     mp_clear_multi(&tmpG, &tmpX, NULL);
+     return err;
+#else 
+     /* no invmod */
+     return MP_VAL;
+#endif
+  }
+
+/* modified diminished radix reduction */
+#if defined(BN_MP_REDUCE_IS_2K_L_C) && defined(BN_MP_REDUCE_2K_L_C) && defined(BN_S_MP_EXPTMOD_C)
+  if (mp_reduce_is_2k_l(P) == MP_YES) {
+     return s_mp_exptmod(G, X, P, Y, 1);
+  }
+#endif
+
+#ifdef BN_MP_DR_IS_MODULUS_C
+  /* is it a DR modulus? */
+  dr = mp_dr_is_modulus(P);
+#else
+  /* default to no */
+  dr = 0;
+#endif
+
+#ifdef BN_MP_REDUCE_IS_2K_C
+  /* if not, is it a unrestricted DR modulus? */
+  if (dr == 0) {
+     dr = mp_reduce_is_2k(P) << 1;
+  }
+#endif
+    
+  /* if the modulus is odd or dr != 0 use the montgomery method */
+#ifdef BN_MP_EXPTMOD_FAST_C
+  if (mp_isodd (P) == 1 || dr !=  0) {
+    return mp_exptmod_fast (G, X, P, Y, dr);
+  } else {
+#endif
+#ifdef BN_S_MP_EXPTMOD_C
+    /* otherwise use the generic Barrett reduction technique */
+    return s_mp_exptmod (G, X, P, Y, 0);
+#else
+    /* no exptmod for evens */
+    return MP_VAL;
+#endif
+#ifdef BN_MP_EXPTMOD_FAST_C
+  }
+#endif
+}
+
+#endif
+
+/* End: bn_mp_exptmod.c */
+
+/* Start: bn_mp_exptmod_fast.c */
+#include <tommath.h>
+#ifdef BN_MP_EXPTMOD_FAST_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* computes Y == G**X mod P, HAC pp.616, Algorithm 14.85
+ *
+ * Uses a left-to-right k-ary sliding window to compute the modular exponentiation.
+ * The value of k changes based on the size of the exponent.
+ *
+ * Uses Montgomery or Diminished Radix reduction [whichever appropriate]
+ */
+
+#ifdef MP_LOW_MEM
+   #define TAB_SIZE 32
+#else
+   #define TAB_SIZE 256
+#endif
+
+int mp_exptmod_fast (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int redmode)
+{
+  mp_int  M[TAB_SIZE], res;
+  mp_digit buf, mp;
+  int     err, bitbuf, bitcpy, bitcnt, mode, digidx, x, y, winsize;
+
+  /* use a pointer to the reduction algorithm.  This allows us to use
+   * one of many reduction algorithms without modding the guts of
+   * the code with if statements everywhere.
+   */
+  int     (*redux)(mp_int*,mp_int*,mp_digit);
+
+  /* find window size */
+  x = mp_count_bits (X);
+  if (x <= 7) {
+    winsize = 2;
+  } else if (x <= 36) {
+    winsize = 3;
+  } else if (x <= 140) {
+    winsize = 4;
+  } else if (x <= 450) {
+    winsize = 5;
+  } else if (x <= 1303) {
+    winsize = 6;
+  } else if (x <= 3529) {
+    winsize = 7;
+  } else {
+    winsize = 8;
+  }
+
+#ifdef MP_LOW_MEM
+  if (winsize > 5) {
+     winsize = 5;
+  }
+#endif
+
+  /* init M array */
+  /* init first cell */
+  if ((err = mp_init(&M[1])) != MP_OKAY) {
+     return err;
+  }
+
+  /* now init the second half of the array */
+  for (x = 1<<(winsize-1); x < (1 << winsize); x++) {
+    if ((err = mp_init(&M[x])) != MP_OKAY) {
+      for (y = 1<<(winsize-1); y < x; y++) {
+        mp_clear (&M[y]);
+      }
+      mp_clear(&M[1]);
+      return err;
+    }
+  }
+
+  /* determine and setup reduction code */
+  if (redmode == 0) {
+#ifdef BN_MP_MONTGOMERY_SETUP_C     
+     /* now setup montgomery  */
+     if ((err = mp_montgomery_setup (P, &mp)) != MP_OKAY) {
+        goto LBL_M;
+     }
+#else
+     err = MP_VAL;
+     goto LBL_M;
+#endif
+
+     /* automatically pick the comba one if available (saves quite a few calls/ifs) */
+#ifdef BN_FAST_MP_MONTGOMERY_REDUCE_C
+     if (((P->used * 2 + 1) < MP_WARRAY) &&
+          P->used < (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) {
+        redux = fast_mp_montgomery_reduce;
+     } else 
+#endif
+     {
+#ifdef BN_MP_MONTGOMERY_REDUCE_C
+        /* use slower baseline Montgomery method */
+        redux = mp_montgomery_reduce;
+#else
+        err = MP_VAL;
+        goto LBL_M;
+#endif
+     }
+  } else if (redmode == 1) {
+#if defined(BN_MP_DR_SETUP_C) && defined(BN_MP_DR_REDUCE_C)
+     /* setup DR reduction for moduli of the form B**k - b */
+     mp_dr_setup(P, &mp);
+     redux = mp_dr_reduce;
+#else
+     err = MP_VAL;
+     goto LBL_M;
+#endif
+  } else {
+#if defined(BN_MP_REDUCE_2K_SETUP_C) && defined(BN_MP_REDUCE_2K_C)
+     /* setup DR reduction for moduli of the form 2**k - b */
+     if ((err = mp_reduce_2k_setup(P, &mp)) != MP_OKAY) {
+        goto LBL_M;
+     }
+     redux = mp_reduce_2k;
+#else
+     err = MP_VAL;
+     goto LBL_M;
+#endif
+  }
+
+  /* setup result */
+  if ((err = mp_init (&res)) != MP_OKAY) {
+    goto LBL_M;
+  }
+
+  /* create M table
+   *
+
+   *
+   * The first half of the table is not computed though accept for M[0] and M[1]
+   */
+
+  if (redmode == 0) {
+#ifdef BN_MP_MONTGOMERY_CALC_NORMALIZATION_C
+     /* now we need R mod m */
+     if ((err = mp_montgomery_calc_normalization (&res, P)) != MP_OKAY) {
+       goto LBL_RES;
+     }
+#else 
+     err = MP_VAL;
+     goto LBL_RES;
+#endif
+
+     /* now set M[1] to G * R mod m */
+     if ((err = mp_mulmod (G, &res, P, &M[1])) != MP_OKAY) {
+       goto LBL_RES;
+     }
+  } else {
+     mp_set(&res, 1);
+     if ((err = mp_mod(G, P, &M[1])) != MP_OKAY) {
+        goto LBL_RES;
+     }
+  }
+
+  /* compute the value at M[1<<(winsize-1)] by squaring M[1] (winsize-1) times */
+  if ((err = mp_copy (&M[1], &M[1 << (winsize - 1)])) != MP_OKAY) {
+    goto LBL_RES;
+  }
+
+  for (x = 0; x < (winsize - 1); x++) {
+    if ((err = mp_sqr (&M[1 << (winsize - 1)], &M[1 << (winsize - 1)])) != MP_OKAY) {
+      goto LBL_RES;
+    }
+    if ((err = redux (&M[1 << (winsize - 1)], P, mp)) != MP_OKAY) {
+      goto LBL_RES;
+    }
+  }
+
+  /* create upper table */
+  for (x = (1 << (winsize - 1)) + 1; x < (1 << winsize); x++) {
+    if ((err = mp_mul (&M[x - 1], &M[1], &M[x])) != MP_OKAY) {
+      goto LBL_RES;
+    }
+    if ((err = redux (&M[x], P, mp)) != MP_OKAY) {
+      goto LBL_RES;
+    }
+  }
+
+  /* set initial mode and bit cnt */
+  mode   = 0;
+  bitcnt = 1;
+  buf    = 0;
+  digidx = X->used - 1;
+  bitcpy = 0;
+  bitbuf = 0;
+
+  for (;;) {
+    /* grab next digit as required */
+    if (--bitcnt == 0) {
+      /* if digidx == -1 we are out of digits so break */
+      if (digidx == -1) {
+        break;
+      }
+      /* read next digit and reset bitcnt */
+      buf    = X->dp[digidx--];
+      bitcnt = (int)DIGIT_BIT;
+    }
+
+    /* grab the next msb from the exponent */
+    y     = (mp_digit)(buf >> (DIGIT_BIT - 1)) & 1;
+    buf <<= (mp_digit)1;
+
+    /* if the bit is zero and mode == 0 then we ignore it
+     * These represent the leading zero bits before the first 1 bit
+     * in the exponent.  Technically this opt is not required but it
+     * does lower the # of trivial squaring/reductions used
+     */
+    if (mode == 0 && y == 0) {
+      continue;
+    }
+
+    /* if the bit is zero and mode == 1 then we square */
+    if (mode == 1 && y == 0) {
+      if ((err = mp_sqr (&res, &res)) != MP_OKAY) {
+        goto LBL_RES;
+      }
+      if ((err = redux (&res, P, mp)) != MP_OKAY) {
+        goto LBL_RES;
+      }
+      continue;
+    }
+
+    /* else we add it to the window */
+    bitbuf |= (y << (winsize - ++bitcpy));
+    mode    = 2;
+
+    if (bitcpy == winsize) {
+      /* ok window is filled so square as required and multiply  */
+      /* square first */
+      for (x = 0; x < winsize; x++) {
+        if ((err = mp_sqr (&res, &res)) != MP_OKAY) {
+          goto LBL_RES;
+        }
+        if ((err = redux (&res, P, mp)) != MP_OKAY) {
+          goto LBL_RES;
+        }
+      }
+
+      /* then multiply */
+      if ((err = mp_mul (&res, &M[bitbuf], &res)) != MP_OKAY) {
+        goto LBL_RES;
+      }
+      if ((err = redux (&res, P, mp)) != MP_OKAY) {
+        goto LBL_RES;
+      }
+
+      /* empty window and reset */
+      bitcpy = 0;
+      bitbuf = 0;
+      mode   = 1;
+    }
+  }
+
+  /* if bits remain then square/multiply */
+  if (mode == 2 && bitcpy > 0) {
+    /* square then multiply if the bit is set */
+    for (x = 0; x < bitcpy; x++) {
+      if ((err = mp_sqr (&res, &res)) != MP_OKAY) {
+        goto LBL_RES;
+      }
+      if ((err = redux (&res, P, mp)) != MP_OKAY) {
+        goto LBL_RES;
+      }
+
+      /* get next bit of the window */
+      bitbuf <<= 1;
+      if ((bitbuf & (1 << winsize)) != 0) {
+        /* then multiply */
+        if ((err = mp_mul (&res, &M[1], &res)) != MP_OKAY) {
+          goto LBL_RES;
+        }
+        if ((err = redux (&res, P, mp)) != MP_OKAY) {
+          goto LBL_RES;
+        }
+      }
+    }
+  }
+
+  if (redmode == 0) {
+     /* fixup result if Montgomery reduction is used
+      * recall that any value in a Montgomery system is
+      * actually multiplied by R mod n.  So we have
+      * to reduce one more time to cancel out the factor
+      * of R.
+      */
+     if ((err = redux(&res, P, mp)) != MP_OKAY) {
+       goto LBL_RES;
+     }
+  }
+
+  /* swap res with Y */
+  mp_exch (&res, Y);
+  err = MP_OKAY;
+LBL_RES:mp_clear (&res);
+LBL_M:
+  mp_clear(&M[1]);
+  for (x = 1<<(winsize-1); x < (1 << winsize); x++) {
+    mp_clear (&M[x]);
+  }
+  return err;
+}
+#endif
+
+/* End: bn_mp_exptmod_fast.c */
+
+/* Start: bn_mp_exteuclid.c */
+#include <tommath.h>
+#ifdef BN_MP_EXTEUCLID_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* Extended euclidean algorithm of (a, b) produces 
+   a*u1 + b*u2 = u3
+ */
+int mp_exteuclid(mp_int *a, mp_int *b, mp_int *U1, mp_int *U2, mp_int *U3)
+{
+   mp_int u1,u2,u3,v1,v2,v3,t1,t2,t3,q,tmp;
+   int err;
+
+   if ((err = mp_init_multi(&u1, &u2, &u3, &v1, &v2, &v3, &t1, &t2, &t3, &q, &tmp, NULL)) != MP_OKAY) {
+      return err;
+   }
+
+   /* initialize, (u1,u2,u3) = (1,0,a) */
+   mp_set(&u1, 1);
+   if ((err = mp_copy(a, &u3)) != MP_OKAY)                                        { goto _ERR; }
+
+   /* initialize, (v1,v2,v3) = (0,1,b) */
+   mp_set(&v2, 1);
+   if ((err = mp_copy(b, &v3)) != MP_OKAY)                                        { goto _ERR; }
+
+   /* loop while v3 != 0 */
+   while (mp_iszero(&v3) == MP_NO) {
+       /* q = u3/v3 */
+       if ((err = mp_div(&u3, &v3, &q, NULL)) != MP_OKAY)                         { goto _ERR; }
+
+       /* (t1,t2,t3) = (u1,u2,u3) - (v1,v2,v3)q */
+       if ((err = mp_mul(&v1, &q, &tmp)) != MP_OKAY)                              { goto _ERR; }
+       if ((err = mp_sub(&u1, &tmp, &t1)) != MP_OKAY)                             { goto _ERR; }
+       if ((err = mp_mul(&v2, &q, &tmp)) != MP_OKAY)                              { goto _ERR; }
+       if ((err = mp_sub(&u2, &tmp, &t2)) != MP_OKAY)                             { goto _ERR; }
+       if ((err = mp_mul(&v3, &q, &tmp)) != MP_OKAY)                              { goto _ERR; }
+       if ((err = mp_sub(&u3, &tmp, &t3)) != MP_OKAY)                             { goto _ERR; }
+
+       /* (u1,u2,u3) = (v1,v2,v3) */
+       if ((err = mp_copy(&v1, &u1)) != MP_OKAY)                                  { goto _ERR; }
+       if ((err = mp_copy(&v2, &u2)) != MP_OKAY)                                  { goto _ERR; }
+       if ((err = mp_copy(&v3, &u3)) != MP_OKAY)                                  { goto _ERR; }
+
+       /* (v1,v2,v3) = (t1,t2,t3) */
+       if ((err = mp_copy(&t1, &v1)) != MP_OKAY)                                  { goto _ERR; }
+       if ((err = mp_copy(&t2, &v2)) != MP_OKAY)                                  { goto _ERR; }
+       if ((err = mp_copy(&t3, &v3)) != MP_OKAY)                                  { goto _ERR; }
+   }
+
+   /* make sure U3 >= 0 */
+   if (u3.sign == MP_NEG) {
+      mp_neg(&u1, &u1);
+      mp_neg(&u2, &u2);
+      mp_neg(&u3, &u3);
+   }
+
+   /* copy result out */
+   if (U1 != NULL) { mp_exch(U1, &u1); }
+   if (U2 != NULL) { mp_exch(U2, &u2); }
+   if (U3 != NULL) { mp_exch(U3, &u3); }
+
+   err = MP_OKAY;
+_ERR: mp_clear_multi(&u1, &u2, &u3, &v1, &v2, &v3, &t1, &t2, &t3, &q, &tmp, NULL);
+   return err;
+}
+#endif
+
+/* End: bn_mp_exteuclid.c */
+
+/* Start: bn_mp_fread.c */
+#include <tommath.h>
+#ifdef BN_MP_FREAD_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* read a bigint from a file stream in ASCII */
+int mp_fread(mp_int *a, int radix, FILE *stream)
+{
+   int err, ch, neg, y;
+   
+   /* clear a */
+   mp_zero(a);
+   
+   /* if first digit is - then set negative */
+   ch = fgetc(stream);
+   if (ch == '-') {
+      neg = MP_NEG;
+      ch = fgetc(stream);
+   } else {
+      neg = MP_ZPOS;
+   }
+   
+   for (;;) {
+      /* find y in the radix map */
+      for (y = 0; y < radix; y++) {
+          if (mp_s_rmap[y] == ch) {
+             break;
+          }
+      }
+      if (y == radix) {
+         break;
+      }
+      
+      /* shift up and add */
+      if ((err = mp_mul_d(a, radix, a)) != MP_OKAY) {
+         return err;
+      }
+      if ((err = mp_add_d(a, y, a)) != MP_OKAY) {
+         return err;
+      }
+      
+      ch = fgetc(stream);
+   }
+   if (mp_cmp_d(a, 0) != MP_EQ) {
+      a->sign = neg;
+   }
+   
+   return MP_OKAY;
+}
+
+#endif
+
+/* End: bn_mp_fread.c */
+
+/* Start: bn_mp_fwrite.c */
+#include <tommath.h>
+#ifdef BN_MP_FWRITE_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+int mp_fwrite(mp_int *a, int radix, FILE *stream)
+{
+   char *buf;
+   int err, len, x;
+   
+   if ((err = mp_radix_size(a, radix, &len)) != MP_OKAY) {
+      return err;
+   }
+
+   buf = OPT_CAST(char) XMALLOC (len);
+   if (buf == NULL) {
+      return MP_MEM;
+   }
+   
+   if ((err = mp_toradix(a, buf, radix)) != MP_OKAY) {
+      XFREE (buf);
+      return err;
+   }
+   
+   for (x = 0; x < len; x++) {
+       if (fputc(buf[x], stream) == EOF) {
+          XFREE (buf);
+          return MP_VAL;
+       }
+   }
+   
+   XFREE (buf);
+   return MP_OKAY;
+}
+
+#endif
+
+/* End: bn_mp_fwrite.c */
+
+/* Start: bn_mp_gcd.c */
+#include <tommath.h>
+#ifdef BN_MP_GCD_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* Greatest Common Divisor using the binary method */
+int mp_gcd (mp_int * a, mp_int * b, mp_int * c)
+{
+  mp_int  u, v;
+  int     k, u_lsb, v_lsb, res;
+
+  /* either zero than gcd is the largest */
+  if (mp_iszero (a) == MP_YES) {
+    return mp_abs (b, c);
+  }
+  if (mp_iszero (b) == MP_YES) {
+    return mp_abs (a, c);
+  }
+
+  /* get copies of a and b we can modify */
+  if ((res = mp_init_copy (&u, a)) != MP_OKAY) {
+    return res;
+  }
+
+  if ((res = mp_init_copy (&v, b)) != MP_OKAY) {
+    goto LBL_U;
+  }
+
+  /* must be positive for the remainder of the algorithm */
+  u.sign = v.sign = MP_ZPOS;
+
+  /* B1.  Find the common power of two for u and v */
+  u_lsb = mp_cnt_lsb(&u);
+  v_lsb = mp_cnt_lsb(&v);
+  k     = MIN(u_lsb, v_lsb);
+
+  if (k > 0) {
+     /* divide the power of two out */
+     if ((res = mp_div_2d(&u, k, &u, NULL)) != MP_OKAY) {
+        goto LBL_V;
+     }
+
+     if ((res = mp_div_2d(&v, k, &v, NULL)) != MP_OKAY) {
+        goto LBL_V;
+     }
+  }
+
+  /* divide any remaining factors of two out */
+  if (u_lsb != k) {
+     if ((res = mp_div_2d(&u, u_lsb - k, &u, NULL)) != MP_OKAY) {
+        goto LBL_V;
+     }
+  }
+
+  if (v_lsb != k) {
+     if ((res = mp_div_2d(&v, v_lsb - k, &v, NULL)) != MP_OKAY) {
+        goto LBL_V;
+     }
+  }
+
+  while (mp_iszero(&v) == 0) {
+     /* make sure v is the largest */
+     if (mp_cmp_mag(&u, &v) == MP_GT) {
+        /* swap u and v to make sure v is >= u */
+        mp_exch(&u, &v);
+     }
+     
+     /* subtract smallest from largest */
+     if ((res = s_mp_sub(&v, &u, &v)) != MP_OKAY) {
+        goto LBL_V;
+     }
+     
+     /* Divide out all factors of two */
+     if ((res = mp_div_2d(&v, mp_cnt_lsb(&v), &v, NULL)) != MP_OKAY) {
+        goto LBL_V;
+     } 
+  } 
+
+  /* multiply by 2**k which we divided out at the beginning */
+  if ((res = mp_mul_2d (&u, k, c)) != MP_OKAY) {
+     goto LBL_V;
+  }
+  c->sign = MP_ZPOS;
+  res = MP_OKAY;
+LBL_V:mp_clear (&u);
+LBL_U:mp_clear (&v);
+  return res;
+}
+#endif
+
+/* End: bn_mp_gcd.c */
+
+/* Start: bn_mp_get_int.c */
+#include <tommath.h>
+#ifdef BN_MP_GET_INT_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* get the lower 32-bits of an mp_int */
+unsigned long mp_get_int(mp_int * a) 
+{
+  int i;
+  unsigned long res;
+
+  if (a->used == 0) {
+     return 0;
+  }
+
+  /* get number of digits of the lsb we have to read */
+  i = MIN(a->used,(int)((sizeof(unsigned long)*CHAR_BIT+DIGIT_BIT-1)/DIGIT_BIT))-1;
+
+  /* get most significant digit of result */
+  res = DIGIT(a,i);
+   
+  while (--i >= 0) {
+    res = (res << DIGIT_BIT) | DIGIT(a,i);
+  }
+
+  /* force result to 32-bits always so it is consistent on non 32-bit platforms */
+  return res & 0xFFFFFFFFUL;
+}
+#endif
+
+/* End: bn_mp_get_int.c */
+
+/* Start: bn_mp_grow.c */
+#include <tommath.h>
+#ifdef BN_MP_GROW_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* grow as required */
+int mp_grow (mp_int * a, int size)
+{
+  int     i;
+  mp_digit *tmp;
+
+  /* if the alloc size is smaller alloc more ram */
+  if (a->alloc < size) {
+    /* ensure there are always at least MP_PREC digits extra on top */
+    size += (MP_PREC * 2) - (size % MP_PREC);
+
+    /* reallocate the array a->dp
+     *
+     * We store the return in a temporary variable
+     * in case the operation failed we don't want
+     * to overwrite the dp member of a.
+     */
+    tmp = OPT_CAST(mp_digit) XREALLOC (a->dp, sizeof (mp_digit) * size);
+    if (tmp == NULL) {
+      /* reallocation failed but "a" is still valid [can be freed] */
+      return MP_MEM;
+    }
+
+    /* reallocation succeeded so set a->dp */
+    a->dp = tmp;
+
+    /* zero excess digits */
+    i        = a->alloc;
+    a->alloc = size;
+    for (; i < a->alloc; i++) {
+      a->dp[i] = 0;
+    }
+  }
+  return MP_OKAY;
+}
+#endif
+
+/* End: bn_mp_grow.c */
+
+/* Start: bn_mp_init.c */
+#include <tommath.h>
+#ifdef BN_MP_INIT_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* init a new mp_int */
+int mp_init (mp_int * a)
+{
+  int i;
+
+  /* allocate memory required and clear it */
+  a->dp = OPT_CAST(mp_digit) XMALLOC (sizeof (mp_digit) * MP_PREC);
+  if (a->dp == NULL) {
+    return MP_MEM;
+  }
+
+  /* set the digits to zero */
+  for (i = 0; i < MP_PREC; i++) {
+      a->dp[i] = 0;
+  }
+
+  /* set the used to zero, allocated digits to the default precision
+   * and sign to positive */
+  a->used  = 0;
+  a->alloc = MP_PREC;
+  a->sign  = MP_ZPOS;
+
+  return MP_OKAY;
+}
+#endif
+
+/* End: bn_mp_init.c */
+
+/* Start: bn_mp_init_copy.c */
+#include <tommath.h>
+#ifdef BN_MP_INIT_COPY_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* creates "a" then copies b into it */
+int mp_init_copy (mp_int * a, mp_int * b)
+{
+  int     res;
+
+  if ((res = mp_init (a)) != MP_OKAY) {
+    return res;
+  }
+  return mp_copy (b, a);
+}
+#endif
+
+/* End: bn_mp_init_copy.c */
+
+/* Start: bn_mp_init_multi.c */
+#include <tommath.h>
+#ifdef BN_MP_INIT_MULTI_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+#include <stdarg.h>
+
+int mp_init_multi(mp_int *mp, ...) 
+{
+    mp_err res = MP_OKAY;      /* Assume ok until proven otherwise */
+    int n = 0;                 /* Number of ok inits */
+    mp_int* cur_arg = mp;
+    va_list args;
+
+    va_start(args, mp);        /* init args to next argument from caller */
+    while (cur_arg != NULL) {
+        if (mp_init(cur_arg) != MP_OKAY) {
+            /* Oops - error! Back-track and mp_clear what we already
+               succeeded in init-ing, then return error.
+            */
+            va_list clean_args;
+            
+            /* end the current list */
+            va_end(args);
+            
+            /* now start cleaning up */            
+            cur_arg = mp;
+            va_start(clean_args, mp);
+            while (n--) {
+                mp_clear(cur_arg);
+                cur_arg = va_arg(clean_args, mp_int*);
+            }
+            va_end(clean_args);
+            res = MP_MEM;
+            break;
+        }
+        n++;
+        cur_arg = va_arg(args, mp_int*);
+    }
+    va_end(args);
+    return res;                /* Assumed ok, if error flagged above. */
+}
+
+#endif
+
+/* End: bn_mp_init_multi.c */
+
+/* Start: bn_mp_init_set.c */
+#include <tommath.h>
+#ifdef BN_MP_INIT_SET_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* initialize and set a digit */
+int mp_init_set (mp_int * a, mp_digit b)
+{
+  int err;
+  if ((err = mp_init(a)) != MP_OKAY) {
+     return err;
+  }
+  mp_set(a, b);
+  return err;
+}
+#endif
+
+/* End: bn_mp_init_set.c */
+
+/* Start: bn_mp_init_set_int.c */
+#include <tommath.h>
+#ifdef BN_MP_INIT_SET_INT_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* initialize and set a digit */
+int mp_init_set_int (mp_int * a, unsigned long b)
+{
+  int err;
+  if ((err = mp_init(a)) != MP_OKAY) {
+     return err;
+  }
+  return mp_set_int(a, b);
+}
+#endif
+
+/* End: bn_mp_init_set_int.c */
+
+/* Start: bn_mp_init_size.c */
+#include <tommath.h>
+#ifdef BN_MP_INIT_SIZE_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* init an mp_init for a given size */
+int mp_init_size (mp_int * a, int size)
+{
+  int x;
+
+  /* pad size so there are always extra digits */
+  size += (MP_PREC * 2) - (size % MP_PREC);	
+  
+  /* alloc mem */
+  a->dp = OPT_CAST(mp_digit) XMALLOC (sizeof (mp_digit) * size);
+  if (a->dp == NULL) {
+    return MP_MEM;
+  }
+
+  /* set the members */
+  a->used  = 0;
+  a->alloc = size;
+  a->sign  = MP_ZPOS;
+
+  /* zero the digits */
+  for (x = 0; x < size; x++) {
+      a->dp[x] = 0;
+  }
+
+  return MP_OKAY;
+}
+#endif
+
+/* End: bn_mp_init_size.c */
+
+/* Start: bn_mp_invmod.c */
+#include <tommath.h>
+#ifdef BN_MP_INVMOD_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* hac 14.61, pp608 */
+int mp_invmod (mp_int * a, mp_int * b, mp_int * c)
+{
+  /* b cannot be negative */
+  if (b->sign == MP_NEG || mp_iszero(b) == 1) {
+    return MP_VAL;
+  }
+
+#ifdef BN_FAST_MP_INVMOD_C
+  /* if the modulus is odd we can use a faster routine instead */
+  if (mp_isodd (b) == 1) {
+    return fast_mp_invmod (a, b, c);
+  }
+#endif
+
+#ifdef BN_MP_INVMOD_SLOW_C
+  return mp_invmod_slow(a, b, c);
+#endif
+
+  return MP_VAL;
+}
+#endif
+
+/* End: bn_mp_invmod.c */
+
+/* Start: bn_mp_invmod_slow.c */
+#include <tommath.h>
+#ifdef BN_MP_INVMOD_SLOW_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* hac 14.61, pp608 */
+int mp_invmod_slow (mp_int * a, mp_int * b, mp_int * c)
+{
+  mp_int  x, y, u, v, A, B, C, D;
+  int     res;
+
+  /* b cannot be negative */
+  if (b->sign == MP_NEG || mp_iszero(b) == 1) {
+    return MP_VAL;
+  }
+
+  /* init temps */
+  if ((res = mp_init_multi(&x, &y, &u, &v, 
+                           &A, &B, &C, &D, NULL)) != MP_OKAY) {
+     return res;
+  }
+
+  /* x = a, y = b */
+  if ((res = mp_mod(a, b, &x)) != MP_OKAY) {
+      goto LBL_ERR;
+  }
+  if ((res = mp_copy (b, &y)) != MP_OKAY) {
+    goto LBL_ERR;
+  }
+
+  /* 2. [modified] if x,y are both even then return an error! */
+  if (mp_iseven (&x) == 1 && mp_iseven (&y) == 1) {
+    res = MP_VAL;
+    goto LBL_ERR;
+  }
+
+  /* 3. u=x, v=y, A=1, B=0, C=0,D=1 */
+  if ((res = mp_copy (&x, &u)) != MP_OKAY) {
+    goto LBL_ERR;
+  }
+  if ((res = mp_copy (&y, &v)) != MP_OKAY) {
+    goto LBL_ERR;
+  }
+  mp_set (&A, 1);
+  mp_set (&D, 1);
+
+top:
+  /* 4.  while u is even do */
+  while (mp_iseven (&u) == 1) {
+    /* 4.1 u = u/2 */
+    if ((res = mp_div_2 (&u, &u)) != MP_OKAY) {
+      goto LBL_ERR;
+    }
+    /* 4.2 if A or B is odd then */
+    if (mp_isodd (&A) == 1 || mp_isodd (&B) == 1) {
+      /* A = (A+y)/2, B = (B-x)/2 */
+      if ((res = mp_add (&A, &y, &A)) != MP_OKAY) {
+         goto LBL_ERR;
+      }
+      if ((res = mp_sub (&B, &x, &B)) != MP_OKAY) {
+         goto LBL_ERR;
+      }
+    }
+    /* A = A/2, B = B/2 */
+    if ((res = mp_div_2 (&A, &A)) != MP_OKAY) {
+      goto LBL_ERR;
+    }
+    if ((res = mp_div_2 (&B, &B)) != MP_OKAY) {
+      goto LBL_ERR;
+    }
+  }
+
+  /* 5.  while v is even do */
+  while (mp_iseven (&v) == 1) {
+    /* 5.1 v = v/2 */
+    if ((res = mp_div_2 (&v, &v)) != MP_OKAY) {
+      goto LBL_ERR;
+    }
+    /* 5.2 if C or D is odd then */
+    if (mp_isodd (&C) == 1 || mp_isodd (&D) == 1) {
+      /* C = (C+y)/2, D = (D-x)/2 */
+      if ((res = mp_add (&C, &y, &C)) != MP_OKAY) {
+         goto LBL_ERR;
+      }
+      if ((res = mp_sub (&D, &x, &D)) != MP_OKAY) {
+         goto LBL_ERR;
+      }
+    }
+    /* C = C/2, D = D/2 */
+    if ((res = mp_div_2 (&C, &C)) != MP_OKAY) {
+      goto LBL_ERR;
+    }
+    if ((res = mp_div_2 (&D, &D)) != MP_OKAY) {
+      goto LBL_ERR;
+    }
+  }
+
+  /* 6.  if u >= v then */
+  if (mp_cmp (&u, &v) != MP_LT) {
+    /* u = u - v, A = A - C, B = B - D */
+    if ((res = mp_sub (&u, &v, &u)) != MP_OKAY) {
+      goto LBL_ERR;
+    }
+
+    if ((res = mp_sub (&A, &C, &A)) != MP_OKAY) {
+      goto LBL_ERR;
+    }
+
+    if ((res = mp_sub (&B, &D, &B)) != MP_OKAY) {
+      goto LBL_ERR;
+    }
+  } else {
+    /* v - v - u, C = C - A, D = D - B */
+    if ((res = mp_sub (&v, &u, &v)) != MP_OKAY) {
+      goto LBL_ERR;
+    }
+
+    if ((res = mp_sub (&C, &A, &C)) != MP_OKAY) {
+      goto LBL_ERR;
+    }
+
+    if ((res = mp_sub (&D, &B, &D)) != MP_OKAY) {
+      goto LBL_ERR;
+    }
+  }
+
+  /* if not zero goto step 4 */
+  if (mp_iszero (&u) == 0)
+    goto top;
+
+  /* now a = C, b = D, gcd == g*v */
+
+  /* if v != 1 then there is no inverse */
+  if (mp_cmp_d (&v, 1) != MP_EQ) {
+    res = MP_VAL;
+    goto LBL_ERR;
+  }
+
+  /* if its too low */
+  while (mp_cmp_d(&C, 0) == MP_LT) {
+      if ((res = mp_add(&C, b, &C)) != MP_OKAY) {
+         goto LBL_ERR;
+      }
+  }
+  
+  /* too big */
+  while (mp_cmp_mag(&C, b) != MP_LT) {
+      if ((res = mp_sub(&C, b, &C)) != MP_OKAY) {
+         goto LBL_ERR;
+      }
+  }
+  
+  /* C is now the inverse */
+  mp_exch (&C, c);
+  res = MP_OKAY;
+LBL_ERR:mp_clear_multi (&x, &y, &u, &v, &A, &B, &C, &D, NULL);
+  return res;
+}
+#endif
+
+/* End: bn_mp_invmod_slow.c */
+
+/* Start: bn_mp_is_square.c */
+#include <tommath.h>
+#ifdef BN_MP_IS_SQUARE_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* Check if remainders are possible squares - fast exclude non-squares */
+static const char rem_128[128] = {
+ 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
+ 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
+ 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
+ 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
+ 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
+ 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
+ 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1,
+ 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1
+};
+
+static const char rem_105[105] = {
+ 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1,
+ 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1,
+ 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1,
+ 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1,
+ 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1,
+ 1, 1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 1,
+ 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1
+};
+
+/* Store non-zero to ret if arg is square, and zero if not */
+int mp_is_square(mp_int *arg,int *ret) 
+{
+  int           res;
+  mp_digit      c;
+  mp_int        t;
+  unsigned long r;
+
+  /* Default to Non-square :) */
+  *ret = MP_NO; 
+
+  if (arg->sign == MP_NEG) {
+    return MP_VAL;
+  }
+
+  /* digits used?  (TSD) */
+  if (arg->used == 0) {
+     return MP_OKAY;
+  }
+
+  /* First check mod 128 (suppose that DIGIT_BIT is at least 7) */
+  if (rem_128[127 & DIGIT(arg,0)] == 1) {
+     return MP_OKAY;
+  }
+
+  /* Next check mod 105 (3*5*7) */
+  if ((res = mp_mod_d(arg,105,&c)) != MP_OKAY) {
+     return res;
+  }
+  if (rem_105[c] == 1) {
+     return MP_OKAY;
+  }
+
+
+  if ((res = mp_init_set_int(&t,11L*13L*17L*19L*23L*29L*31L)) != MP_OKAY) {
+     return res;
+  }
+  if ((res = mp_mod(arg,&t,&t)) != MP_OKAY) {
+     goto ERR;
+  }
+  r = mp_get_int(&t);
+  /* Check for other prime modules, note it's not an ERROR but we must
+   * free "t" so the easiest way is to goto ERR.  We know that res
+   * is already equal to MP_OKAY from the mp_mod call 
+   */ 
+  if ( (1L<<(r%11)) & 0x5C4L )             goto ERR;
+  if ( (1L<<(r%13)) & 0x9E4L )             goto ERR;
+  if ( (1L<<(r%17)) & 0x5CE8L )            goto ERR;
+  if ( (1L<<(r%19)) & 0x4F50CL )           goto ERR;
+  if ( (1L<<(r%23)) & 0x7ACCA0L )          goto ERR;
+  if ( (1L<<(r%29)) & 0xC2EDD0CL )         goto ERR;
+  if ( (1L<<(r%31)) & 0x6DE2B848L )        goto ERR;
+
+  /* Final check - is sqr(sqrt(arg)) == arg ? */
+  if ((res = mp_sqrt(arg,&t)) != MP_OKAY) {
+     goto ERR;
+  }
+  if ((res = mp_sqr(&t,&t)) != MP_OKAY) {
+     goto ERR;
+  }
+
+  *ret = (mp_cmp_mag(&t,arg) == MP_EQ) ? MP_YES : MP_NO;
+ERR:mp_clear(&t);
+  return res;
+}
+#endif
+
+/* End: bn_mp_is_square.c */
+
+/* Start: bn_mp_jacobi.c */
+#include <tommath.h>
+#ifdef BN_MP_JACOBI_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* computes the jacobi c = (a | n) (or Legendre if n is prime)
+ * HAC pp. 73 Algorithm 2.149
+ */
+int mp_jacobi (mp_int * a, mp_int * p, int *c)
+{
+  mp_int  a1, p1;
+  int     k, s, r, res;
+  mp_digit residue;
+
+  /* if p <= 0 return MP_VAL */
+  if (mp_cmp_d(p, 0) != MP_GT) {
+     return MP_VAL;
+  }
+
+  /* step 1.  if a == 0, return 0 */
+  if (mp_iszero (a) == 1) {
+    *c = 0;
+    return MP_OKAY;
+  }
+
+  /* step 2.  if a == 1, return 1 */
+  if (mp_cmp_d (a, 1) == MP_EQ) {
+    *c = 1;
+    return MP_OKAY;
+  }
+
+  /* default */
+  s = 0;
+
+  /* step 3.  write a = a1 * 2**k  */
+  if ((res = mp_init_copy (&a1, a)) != MP_OKAY) {
+    return res;
+  }
+
+  if ((res = mp_init (&p1)) != MP_OKAY) {
+    goto LBL_A1;
+  }
+
+  /* divide out larger power of two */
+  k = mp_cnt_lsb(&a1);
+  if ((res = mp_div_2d(&a1, k, &a1, NULL)) != MP_OKAY) {
+     goto LBL_P1;
+  }
+
+  /* step 4.  if e is even set s=1 */
+  if ((k & 1) == 0) {
+    s = 1;
+  } else {
+    /* else set s=1 if p = 1/7 (mod 8) or s=-1 if p = 3/5 (mod 8) */
+    residue = p->dp[0] & 7;
+
+    if (residue == 1 || residue == 7) {
+      s = 1;
+    } else if (residue == 3 || residue == 5) {
+      s = -1;
+    }
+  }
+
+  /* step 5.  if p == 3 (mod 4) *and* a1 == 3 (mod 4) then s = -s */
+  if ( ((p->dp[0] & 3) == 3) && ((a1.dp[0] & 3) == 3)) {
+    s = -s;
+  }
+
+  /* if a1 == 1 we're done */
+  if (mp_cmp_d (&a1, 1) == MP_EQ) {
+    *c = s;
+  } else {
+    /* n1 = n mod a1 */
+    if ((res = mp_mod (p, &a1, &p1)) != MP_OKAY) {
+      goto LBL_P1;
+    }
+    if ((res = mp_jacobi (&p1, &a1, &r)) != MP_OKAY) {
+      goto LBL_P1;
+    }
+    *c = s * r;
+  }
+
+  /* done */
+  res = MP_OKAY;
+LBL_P1:mp_clear (&p1);
+LBL_A1:mp_clear (&a1);
+  return res;
+}
+#endif
+
+/* End: bn_mp_jacobi.c */
+
+/* Start: bn_mp_karatsuba_mul.c */
+#include <tommath.h>
+#ifdef BN_MP_KARATSUBA_MUL_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* c = |a| * |b| using Karatsuba Multiplication using 
+ * three half size multiplications
+ *
+ * Let B represent the radix [e.g. 2**DIGIT_BIT] and 
+ * let n represent half of the number of digits in 
+ * the min(a,b)
+ *
+ * a = a1 * B**n + a0
+ * b = b1 * B**n + b0
+ *
+ * Then, a * b => 
+   a1b1 * B**2n + ((a1 + a0)(b1 + b0) - (a0b0 + a1b1)) * B + a0b0
+ *
+ * Note that a1b1 and a0b0 are used twice and only need to be 
+ * computed once.  So in total three half size (half # of 
+ * digit) multiplications are performed, a0b0, a1b1 and 
+ * (a1+b1)(a0+b0)
+ *
+ * Note that a multiplication of half the digits requires
+ * 1/4th the number of single precision multiplications so in 
+ * total after one call 25% of the single precision multiplications 
+ * are saved.  Note also that the call to mp_mul can end up back 
+ * in this function if the a0, a1, b0, or b1 are above the threshold.  
+ * This is known as divide-and-conquer and leads to the famous 
+ * O(N**lg(3)) or O(N**1.584) work which is asymptopically lower than 
+ * the standard O(N**2) that the baseline/comba methods use.  
+ * Generally though the overhead of this method doesn't pay off 
+ * until a certain size (N ~ 80) is reached.
+ */
+int mp_karatsuba_mul (mp_int * a, mp_int * b, mp_int * c)
+{
+  mp_int  x0, x1, y0, y1, t1, x0y0, x1y1;
+  int     B, err;
+
+  /* default the return code to an error */
+  err = MP_MEM;
+
+  /* min # of digits */
+  B = MIN (a->used, b->used);
+
+  /* now divide in two */
+  B = B >> 1;
+
+  /* init copy all the temps */
+  if (mp_init_size (&x0, B) != MP_OKAY)
+    goto ERR;
+  if (mp_init_size (&x1, a->used - B) != MP_OKAY)
+    goto X0;
+  if (mp_init_size (&y0, B) != MP_OKAY)
+    goto X1;
+  if (mp_init_size (&y1, b->used - B) != MP_OKAY)
+    goto Y0;
+
+  /* init temps */
+  if (mp_init_size (&t1, B * 2) != MP_OKAY)
+    goto Y1;
+  if (mp_init_size (&x0y0, B * 2) != MP_OKAY)
+    goto T1;
+  if (mp_init_size (&x1y1, B * 2) != MP_OKAY)
+    goto X0Y0;
+
+  /* now shift the digits */
+  x0.used = y0.used = B;
+  x1.used = a->used - B;
+  y1.used = b->used - B;
+
+  {
+    register int x;
+    register mp_digit *tmpa, *tmpb, *tmpx, *tmpy;
+
+    /* we copy the digits directly instead of using higher level functions
+     * since we also need to shift the digits
+     */
+    tmpa = a->dp;
+    tmpb = b->dp;
+
+    tmpx = x0.dp;
+    tmpy = y0.dp;
+    for (x = 0; x < B; x++) {
+      *tmpx++ = *tmpa++;
+      *tmpy++ = *tmpb++;
+    }
+
+    tmpx = x1.dp;
+    for (x = B; x < a->used; x++) {
+      *tmpx++ = *tmpa++;
+    }
+
+    tmpy = y1.dp;
+    for (x = B; x < b->used; x++) {
+      *tmpy++ = *tmpb++;
+    }
+  }
+
+  /* only need to clamp the lower words since by definition the 
+   * upper words x1/y1 must have a known number of digits
+   */
+  mp_clamp (&x0);
+  mp_clamp (&y0);
+
+  /* now calc the products x0y0 and x1y1 */
+  /* after this x0 is no longer required, free temp [x0==t2]! */
+  if (mp_mul (&x0, &y0, &x0y0) != MP_OKAY)  
+    goto X1Y1;          /* x0y0 = x0*y0 */
+  if (mp_mul (&x1, &y1, &x1y1) != MP_OKAY)
+    goto X1Y1;          /* x1y1 = x1*y1 */
+
+  /* now calc x1+x0 and y1+y0 */
+  if (s_mp_add (&x1, &x0, &t1) != MP_OKAY)
+    goto X1Y1;          /* t1 = x1 - x0 */
+  if (s_mp_add (&y1, &y0, &x0) != MP_OKAY)
+    goto X1Y1;          /* t2 = y1 - y0 */
+  if (mp_mul (&t1, &x0, &t1) != MP_OKAY)
+    goto X1Y1;          /* t1 = (x1 + x0) * (y1 + y0) */
+
+  /* add x0y0 */
+  if (mp_add (&x0y0, &x1y1, &x0) != MP_OKAY)
+    goto X1Y1;          /* t2 = x0y0 + x1y1 */
+  if (s_mp_sub (&t1, &x0, &t1) != MP_OKAY)
+    goto X1Y1;          /* t1 = (x1+x0)*(y1+y0) - (x1y1 + x0y0) */
+
+  /* shift by B */
+  if (mp_lshd (&t1, B) != MP_OKAY)
+    goto X1Y1;          /* t1 = (x0y0 + x1y1 - (x1-x0)*(y1-y0))<<B */
+  if (mp_lshd (&x1y1, B * 2) != MP_OKAY)
+    goto X1Y1;          /* x1y1 = x1y1 << 2*B */
+
+  if (mp_add (&x0y0, &t1, &t1) != MP_OKAY)
+    goto X1Y1;          /* t1 = x0y0 + t1 */
+  if (mp_add (&t1, &x1y1, c) != MP_OKAY)
+    goto X1Y1;          /* t1 = x0y0 + t1 + x1y1 */
+
+  /* Algorithm succeeded set the return code to MP_OKAY */
+  err = MP_OKAY;
+
+X1Y1:mp_clear (&x1y1);
+X0Y0:mp_clear (&x0y0);
+T1:mp_clear (&t1);
+Y1:mp_clear (&y1);
+Y0:mp_clear (&y0);
+X1:mp_clear (&x1);
+X0:mp_clear (&x0);
+ERR:
+  return err;
+}
+#endif
+
+/* End: bn_mp_karatsuba_mul.c */
+
+/* Start: bn_mp_karatsuba_sqr.c */
+#include <tommath.h>
+#ifdef BN_MP_KARATSUBA_SQR_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* Karatsuba squaring, computes b = a*a using three 
+ * half size squarings
+ *
+ * See comments of karatsuba_mul for details.  It 
+ * is essentially the same algorithm but merely 
+ * tuned to perform recursive squarings.
+ */
+int mp_karatsuba_sqr (mp_int * a, mp_int * b)
+{
+  mp_int  x0, x1, t1, t2, x0x0, x1x1;
+  int     B, err;
+
+  err = MP_MEM;
+
+  /* min # of digits */
+  B = a->used;
+
+  /* now divide in two */
+  B = B >> 1;
+
+  /* init copy all the temps */
+  if (mp_init_size (&x0, B) != MP_OKAY)
+    goto ERR;
+  if (mp_init_size (&x1, a->used - B) != MP_OKAY)
+    goto X0;
+
+  /* init temps */
+  if (mp_init_size (&t1, a->used * 2) != MP_OKAY)
+    goto X1;
+  if (mp_init_size (&t2, a->used * 2) != MP_OKAY)
+    goto T1;
+  if (mp_init_size (&x0x0, B * 2) != MP_OKAY)
+    goto T2;
+  if (mp_init_size (&x1x1, (a->used - B) * 2) != MP_OKAY)
+    goto X0X0;
+
+  {
+    register int x;
+    register mp_digit *dst, *src;
+
+    src = a->dp;
+
+    /* now shift the digits */
+    dst = x0.dp;
+    for (x = 0; x < B; x++) {
+      *dst++ = *src++;
+    }
+
+    dst = x1.dp;
+    for (x = B; x < a->used; x++) {
+      *dst++ = *src++;
+    }
+  }
+
+  x0.used = B;
+  x1.used = a->used - B;
+
+  mp_clamp (&x0);
+
+  /* now calc the products x0*x0 and x1*x1 */
+  if (mp_sqr (&x0, &x0x0) != MP_OKAY)
+    goto X1X1;           /* x0x0 = x0*x0 */
+  if (mp_sqr (&x1, &x1x1) != MP_OKAY)
+    goto X1X1;           /* x1x1 = x1*x1 */
+
+  /* now calc (x1+x0)**2 */
+  if (s_mp_add (&x1, &x0, &t1) != MP_OKAY)
+    goto X1X1;           /* t1 = x1 - x0 */
+  if (mp_sqr (&t1, &t1) != MP_OKAY)
+    goto X1X1;           /* t1 = (x1 - x0) * (x1 - x0) */
+
+  /* add x0y0 */
+  if (s_mp_add (&x0x0, &x1x1, &t2) != MP_OKAY)
+    goto X1X1;           /* t2 = x0x0 + x1x1 */
+  if (s_mp_sub (&t1, &t2, &t1) != MP_OKAY)
+    goto X1X1;           /* t1 = (x1+x0)**2 - (x0x0 + x1x1) */
+
+  /* shift by B */
+  if (mp_lshd (&t1, B) != MP_OKAY)
+    goto X1X1;           /* t1 = (x0x0 + x1x1 - (x1-x0)*(x1-x0))<<B */
+  if (mp_lshd (&x1x1, B * 2) != MP_OKAY)
+    goto X1X1;           /* x1x1 = x1x1 << 2*B */
+
+  if (mp_add (&x0x0, &t1, &t1) != MP_OKAY)
+    goto X1X1;           /* t1 = x0x0 + t1 */
+  if (mp_add (&t1, &x1x1, b) != MP_OKAY)
+    goto X1X1;           /* t1 = x0x0 + t1 + x1x1 */
+
+  err = MP_OKAY;
+
+X1X1:mp_clear (&x1x1);
+X0X0:mp_clear (&x0x0);
+T2:mp_clear (&t2);
+T1:mp_clear (&t1);
+X1:mp_clear (&x1);
+X0:mp_clear (&x0);
+ERR:
+  return err;
+}
+#endif
+
+/* End: bn_mp_karatsuba_sqr.c */
+
+/* Start: bn_mp_lcm.c */
+#include <tommath.h>
+#ifdef BN_MP_LCM_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* computes least common multiple as |a*b|/(a, b) */
+int mp_lcm (mp_int * a, mp_int * b, mp_int * c)
+{
+  int     res;
+  mp_int  t1, t2;
+
+
+  if ((res = mp_init_multi (&t1, &t2, NULL)) != MP_OKAY) {
+    return res;
+  }
+
+  /* t1 = get the GCD of the two inputs */
+  if ((res = mp_gcd (a, b, &t1)) != MP_OKAY) {
+    goto LBL_T;
+  }
+
+  /* divide the smallest by the GCD */
+  if (mp_cmp_mag(a, b) == MP_LT) {
+     /* store quotient in t2 such that t2 * b is the LCM */
+     if ((res = mp_div(a, &t1, &t2, NULL)) != MP_OKAY) {
+        goto LBL_T;
+     }
+     res = mp_mul(b, &t2, c);
+  } else {
+     /* store quotient in t2 such that t2 * a is the LCM */
+     if ((res = mp_div(b, &t1, &t2, NULL)) != MP_OKAY) {
+        goto LBL_T;
+     }
+     res = mp_mul(a, &t2, c);
+  }
+
+  /* fix the sign to positive */
+  c->sign = MP_ZPOS;
+
+LBL_T:
+  mp_clear_multi (&t1, &t2, NULL);
+  return res;
+}
+#endif
+
+/* End: bn_mp_lcm.c */
+
+/* Start: bn_mp_lshd.c */
+#include <tommath.h>
+#ifdef BN_MP_LSHD_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* shift left a certain amount of digits */
+int mp_lshd (mp_int * a, int b)
+{
+  int     x, res;
+
+  /* if its less than zero return */
+  if (b <= 0) {
+    return MP_OKAY;
+  }
+
+  /* grow to fit the new digits */
+  if (a->alloc < a->used + b) {
+     if ((res = mp_grow (a, a->used + b)) != MP_OKAY) {
+       return res;
+     }
+  }
+
+  {
+    register mp_digit *top, *bottom;
+
+    /* increment the used by the shift amount then copy upwards */
+    a->used += b;
+
+    /* top */
+    top = a->dp + a->used - 1;
+
+    /* base */
+    bottom = a->dp + a->used - 1 - b;
+
+    /* much like mp_rshd this is implemented using a sliding window
+     * except the window goes the otherway around.  Copying from
+     * the bottom to the top.  see bn_mp_rshd.c for more info.
+     */
+    for (x = a->used - 1; x >= b; x--) {
+      *top-- = *bottom--;
+    }
+
+    /* zero the lower digits */
+    top = a->dp;
+    for (x = 0; x < b; x++) {
+      *top++ = 0;
+    }
+  }
+  return MP_OKAY;
+}
+#endif
+
+/* End: bn_mp_lshd.c */
+
+/* Start: bn_mp_mod.c */
+#include <tommath.h>
+#ifdef BN_MP_MOD_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* c = a mod b, 0 <= c < b */
+int
+mp_mod (mp_int * a, mp_int * b, mp_int * c)
+{
+  mp_int  t;
+  int     res;
+
+  if ((res = mp_init (&t)) != MP_OKAY) {
+    return res;
+  }
+
+  if ((res = mp_div (a, b, NULL, &t)) != MP_OKAY) {
+    mp_clear (&t);
+    return res;
+  }
+
+  if (t.sign != b->sign) {
+    res = mp_add (b, &t, c);
+  } else {
+    res = MP_OKAY;
+    mp_exch (&t, c);
+  }
+
+  mp_clear (&t);
+  return res;
+}
+#endif
+
+/* End: bn_mp_mod.c */
+
+/* Start: bn_mp_mod_2d.c */
+#include <tommath.h>
+#ifdef BN_MP_MOD_2D_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* calc a value mod 2**b */
+int
+mp_mod_2d (mp_int * a, int b, mp_int * c)
+{
+  int     x, res;
+
+  /* if b is <= 0 then zero the int */
+  if (b <= 0) {
+    mp_zero (c);
+    return MP_OKAY;
+  }
+
+  /* if the modulus is larger than the value than return */
+  if (b >= (int) (a->used * DIGIT_BIT)) {
+    res = mp_copy (a, c);
+    return res;
+  }
+
+  /* copy */
+  if ((res = mp_copy (a, c)) != MP_OKAY) {
+    return res;
+  }
+
+  /* zero digits above the last digit of the modulus */
+  for (x = (b / DIGIT_BIT) + ((b % DIGIT_BIT) == 0 ? 0 : 1); x < c->used; x++) {
+    c->dp[x] = 0;
+  }
+  /* clear the digit that is not completely outside/inside the modulus */
+  c->dp[b / DIGIT_BIT] &=
+    (mp_digit) ((((mp_digit) 1) << (((mp_digit) b) % DIGIT_BIT)) - ((mp_digit) 1));
+  mp_clamp (c);
+  return MP_OKAY;
+}
+#endif
+
+/* End: bn_mp_mod_2d.c */
+
+/* Start: bn_mp_mod_d.c */
+#include <tommath.h>
+#ifdef BN_MP_MOD_D_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+int
+mp_mod_d (mp_int * a, mp_digit b, mp_digit * c)
+{
+  return mp_div_d(a, b, NULL, c);
+}
+#endif
+
+/* End: bn_mp_mod_d.c */
+
+/* Start: bn_mp_montgomery_calc_normalization.c */
+#include <tommath.h>
+#ifdef BN_MP_MONTGOMERY_CALC_NORMALIZATION_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/*
+ * shifts with subtractions when the result is greater than b.
+ *
+ * The method is slightly modified to shift B unconditionally upto just under
+ * the leading bit of b.  This saves alot of multiple precision shifting.
+ */
+int mp_montgomery_calc_normalization (mp_int * a, mp_int * b)
+{
+  int     x, bits, res;
+
+  /* how many bits of last digit does b use */
+  bits = mp_count_bits (b) % DIGIT_BIT;
+
+  if (b->used > 1) {
+     if ((res = mp_2expt (a, (b->used - 1) * DIGIT_BIT + bits - 1)) != MP_OKAY) {
+        return res;
+     }
+  } else {
+     mp_set(a, 1);
+     bits = 1;
+  }
+
+
+  /* now compute C = A * B mod b */
+  for (x = bits - 1; x < (int)DIGIT_BIT; x++) {
+    if ((res = mp_mul_2 (a, a)) != MP_OKAY) {
+      return res;
+    }
+    if (mp_cmp_mag (a, b) != MP_LT) {
+      if ((res = s_mp_sub (a, b, a)) != MP_OKAY) {
+        return res;
+      }
+    }
+  }
+
+  return MP_OKAY;
+}
+#endif
+
+/* End: bn_mp_montgomery_calc_normalization.c */
+
+/* Start: bn_mp_montgomery_reduce.c */
+#include <tommath.h>
+#ifdef BN_MP_MONTGOMERY_REDUCE_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* computes xR**-1 == x (mod N) via Montgomery Reduction */
+int
+mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho)
+{
+  int     ix, res, digs;
+  mp_digit mu;
+
+  /* can the fast reduction [comba] method be used?
+   *
+   * Note that unlike in mul you're safely allowed *less*
+   * than the available columns [255 per default] since carries
+   * are fixed up in the inner loop.
+   */
+  digs = n->used * 2 + 1;
+  if ((digs < MP_WARRAY) &&
+      n->used <
+      (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) {
+    return fast_mp_montgomery_reduce (x, n, rho);
+  }
+
+  /* grow the input as required */
+  if (x->alloc < digs) {
+    if ((res = mp_grow (x, digs)) != MP_OKAY) {
+      return res;
+    }
+  }
+  x->used = digs;
+
+  for (ix = 0; ix < n->used; ix++) {
+    /* mu = ai * rho mod b
+     *
+     * The value of rho must be precalculated via
+     * montgomery_setup() such that
+     * it equals -1/n0 mod b this allows the
+     * following inner loop to reduce the
+     * input one digit at a time
+     */
+    mu = (mp_digit) (((mp_word)x->dp[ix]) * ((mp_word)rho) & MP_MASK);
+
+    /* a = a + mu * m * b**i */
+    {
+      register int iy;
+      register mp_digit *tmpn, *tmpx, u;
+      register mp_word r;
+
+      /* alias for digits of the modulus */
+      tmpn = n->dp;
+
+      /* alias for the digits of x [the input] */
+      tmpx = x->dp + ix;
+
+      /* set the carry to zero */
+      u = 0;
+
+      /* Multiply and add in place */
+      for (iy = 0; iy < n->used; iy++) {
+        /* compute product and sum */
+        r       = ((mp_word)mu) * ((mp_word)*tmpn++) +
+                  ((mp_word) u) + ((mp_word) * tmpx);
+
+        /* get carry */
+        u       = (mp_digit)(r >> ((mp_word) DIGIT_BIT));
+
+        /* fix digit */
+        *tmpx++ = (mp_digit)(r & ((mp_word) MP_MASK));
+      }
+      /* At this point the ix'th digit of x should be zero */
+
+
+      /* propagate carries upwards as required*/
+      while (u) {
+        *tmpx   += u;
+        u        = *tmpx >> DIGIT_BIT;
+        *tmpx++ &= MP_MASK;
+      }
+    }
+  }
+
+  /* at this point the n.used'th least
+   * significant digits of x are all zero
+   * which means we can shift x to the
+   * right by n.used digits and the
+   * residue is unchanged.
+   */
+
+  /* x = x/b**n.used */
+  mp_clamp(x);
+  mp_rshd (x, n->used);
+
+  /* if x >= n then x = x - n */
+  if (mp_cmp_mag (x, n) != MP_LT) {
+    return s_mp_sub (x, n, x);
+  }
+
+  return MP_OKAY;
+}
+#endif
+
+/* End: bn_mp_montgomery_reduce.c */
+
+/* Start: bn_mp_montgomery_setup.c */
+#include <tommath.h>
+#ifdef BN_MP_MONTGOMERY_SETUP_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* setups the montgomery reduction stuff */
+int
+mp_montgomery_setup (mp_int * n, mp_digit * rho)
+{
+  mp_digit x, b;
+
+/* fast inversion mod 2**k
+ *
+ * Based on the fact that
+ *
+ * XA = 1 (mod 2**n)  =>  (X(2-XA)) A = 1 (mod 2**2n)
+ *                    =>  2*X*A - X*X*A*A = 1
+ *                    =>  2*(1) - (1)     = 1
+ */
+  b = n->dp[0];
+
+  if ((b & 1) == 0) {
+    return MP_VAL;
+  }
+
+  x = (((b + 2) & 4) << 1) + b; /* here x*a==1 mod 2**4 */
+  x *= 2 - b * x;               /* here x*a==1 mod 2**8 */
+#if !defined(MP_8BIT)
+  x *= 2 - b * x;               /* here x*a==1 mod 2**16 */
+#endif
+#if defined(MP_64BIT) || !(defined(MP_8BIT) || defined(MP_16BIT))
+  x *= 2 - b * x;               /* here x*a==1 mod 2**32 */
+#endif
+#ifdef MP_64BIT
+  x *= 2 - b * x;               /* here x*a==1 mod 2**64 */
+#endif
+
+  /* rho = -1/m mod b */
+  *rho = (unsigned long)(((mp_word)1 << ((mp_word) DIGIT_BIT)) - x) & MP_MASK;
+
+  return MP_OKAY;
+}
+#endif
+
+/* End: bn_mp_montgomery_setup.c */
+
+/* Start: bn_mp_mul.c */
+#include <tommath.h>
+#ifdef BN_MP_MUL_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* high level multiplication (handles sign) */
+int mp_mul (mp_int * a, mp_int * b, mp_int * c)
+{
+  int     res, neg;
+  neg = (a->sign == b->sign) ? MP_ZPOS : MP_NEG;
+
+  /* use Toom-Cook? */
+#ifdef BN_MP_TOOM_MUL_C
+  if (MIN (a->used, b->used) >= TOOM_MUL_CUTOFF) {
+    res = mp_toom_mul(a, b, c);
+  } else 
+#endif
+#ifdef BN_MP_KARATSUBA_MUL_C
+  /* use Karatsuba? */
+  if (MIN (a->used, b->used) >= KARATSUBA_MUL_CUTOFF) {
+    res = mp_karatsuba_mul (a, b, c);
+  } else 
+#endif
+  {
+    /* can we use the fast multiplier?
+     *
+     * The fast multiplier can be used if the output will 
+     * have less than MP_WARRAY digits and the number of 
+     * digits won't affect carry propagation
+     */
+    int     digs = a->used + b->used + 1;
+
+#ifdef BN_FAST_S_MP_MUL_DIGS_C
+    if ((digs < MP_WARRAY) &&
+        MIN(a->used, b->used) <= 
+        (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) {
+      res = fast_s_mp_mul_digs (a, b, c, digs);
+    } else 
+#endif
+#ifdef BN_S_MP_MUL_DIGS_C
+      res = s_mp_mul (a, b, c); /* uses s_mp_mul_digs */
+#else
+      res = MP_VAL;
+#endif
+
+  }
+  c->sign = (c->used > 0) ? neg : MP_ZPOS;
+  return res;
+}
+#endif
+
+/* End: bn_mp_mul.c */
+
+/* Start: bn_mp_mul_2.c */
+#include <tommath.h>
+#ifdef BN_MP_MUL_2_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* b = a*2 */
+int mp_mul_2(mp_int * a, mp_int * b)
+{
+  int     x, res, oldused;
+
+  /* grow to accomodate result */
+  if (b->alloc < a->used + 1) {
+    if ((res = mp_grow (b, a->used + 1)) != MP_OKAY) {
+      return res;
+    }
+  }
+
+  oldused = b->used;
+  b->used = a->used;
+
+  {
+    register mp_digit r, rr, *tmpa, *tmpb;
+
+    /* alias for source */
+    tmpa = a->dp;
+    
+    /* alias for dest */
+    tmpb = b->dp;
+
+    /* carry */
+    r = 0;
+    for (x = 0; x < a->used; x++) {
+    
+      /* get what will be the *next* carry bit from the 
+       * MSB of the current digit 
+       */
+      rr = *tmpa >> ((mp_digit)(DIGIT_BIT - 1));
+      
+      /* now shift up this digit, add in the carry [from the previous] */
+      *tmpb++ = ((*tmpa++ << ((mp_digit)1)) | r) & MP_MASK;
+      
+      /* copy the carry that would be from the source 
+       * digit into the next iteration 
+       */
+      r = rr;
+    }
+
+    /* new leading digit? */
+    if (r != 0) {
+      /* add a MSB which is always 1 at this point */
+      *tmpb = 1;
+      ++(b->used);
+    }
+
+    /* now zero any excess digits on the destination 
+     * that we didn't write to 
+     */
+    tmpb = b->dp + b->used;
+    for (x = b->used; x < oldused; x++) {
+      *tmpb++ = 0;
+    }
+  }
+  b->sign = a->sign;
+  return MP_OKAY;
+}
+#endif
+
+/* End: bn_mp_mul_2.c */
+
+/* Start: bn_mp_mul_2d.c */
+#include <tommath.h>
+#ifdef BN_MP_MUL_2D_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* shift left by a certain bit count */
+int mp_mul_2d (mp_int * a, int b, mp_int * c)
+{
+  mp_digit d;
+  int      res;
+
+  /* copy */
+  if (a != c) {
+     if ((res = mp_copy (a, c)) != MP_OKAY) {
+       return res;
+     }
+  }
+
+  if (c->alloc < (int)(c->used + b/DIGIT_BIT + 1)) {
+     if ((res = mp_grow (c, c->used + b / DIGIT_BIT + 1)) != MP_OKAY) {
+       return res;
+     }
+  }
+
+  /* shift by as many digits in the bit count */
+  if (b >= (int)DIGIT_BIT) {
+    if ((res = mp_lshd (c, b / DIGIT_BIT)) != MP_OKAY) {
+      return res;
+    }
+  }
+
+  /* shift any bit count < DIGIT_BIT */
+  d = (mp_digit) (b % DIGIT_BIT);
+  if (d != 0) {
+    register mp_digit *tmpc, shift, mask, r, rr;
+    register int x;
+
+    /* bitmask for carries */
+    mask = (((mp_digit)1) << d) - 1;
+
+    /* shift for msbs */
+    shift = DIGIT_BIT - d;
+
+    /* alias */
+    tmpc = c->dp;
+
+    /* carry */
+    r    = 0;
+    for (x = 0; x < c->used; x++) {
+      /* get the higher bits of the current word */
+      rr = (*tmpc >> shift) & mask;
+
+      /* shift the current word and OR in the carry */
+      *tmpc = ((*tmpc << d) | r) & MP_MASK;
+      ++tmpc;
+
+      /* set the carry to the carry bits of the current word */
+      r = rr;
+    }
+    
+    /* set final carry */
+    if (r != 0) {
+       c->dp[(c->used)++] = r;
+    }
+  }
+  mp_clamp (c);
+  return MP_OKAY;
+}
+#endif
+
+/* End: bn_mp_mul_2d.c */
+
+/* Start: bn_mp_mul_d.c */
+#include <tommath.h>
+#ifdef BN_MP_MUL_D_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* multiply by a digit */
+int
+mp_mul_d (mp_int * a, mp_digit b, mp_int * c)
+{
+  mp_digit u, *tmpa, *tmpc;
+  mp_word  r;
+  int      ix, res, olduse;
+
+  /* make sure c is big enough to hold a*b */
+  if (c->alloc < a->used + 1) {
+    if ((res = mp_grow (c, a->used + 1)) != MP_OKAY) {
+      return res;
+    }
+  }
+
+  /* get the original destinations used count */
+  olduse = c->used;
+
+  /* set the sign */
+  c->sign = a->sign;
+
+  /* alias for a->dp [source] */
+  tmpa = a->dp;
+
+  /* alias for c->dp [dest] */
+  tmpc = c->dp;
+
+  /* zero carry */
+  u = 0;
+
+  /* compute columns */
+  for (ix = 0; ix < a->used; ix++) {
+    /* compute product and carry sum for this term */
+    r       = ((mp_word) u) + ((mp_word)*tmpa++) * ((mp_word)b);
+
+    /* mask off higher bits to get a single digit */
+    *tmpc++ = (mp_digit) (r & ((mp_word) MP_MASK));
+
+    /* send carry into next iteration */
+    u       = (mp_digit) (r >> ((mp_word) DIGIT_BIT));
+  }
+
+  /* store final carry [if any] and increment ix offset  */
+  *tmpc++ = u;
+  ++ix;
+
+  /* now zero digits above the top */
+  while (ix++ < olduse) {
+     *tmpc++ = 0;
+  }
+
+  /* set used count */
+  c->used = a->used + 1;
+  mp_clamp(c);
+
+  return MP_OKAY;
+}
+#endif
+
+/* End: bn_mp_mul_d.c */
+
+/* Start: bn_mp_mulmod.c */
+#include <tommath.h>
+#ifdef BN_MP_MULMOD_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* d = a * b (mod c) */
+int mp_mulmod (mp_int * a, mp_int * b, mp_int * c, mp_int * d)
+{
+  int     res;
+  mp_int  t;
+
+  if ((res = mp_init (&t)) != MP_OKAY) {
+    return res;
+  }
+
+  if ((res = mp_mul (a, b, &t)) != MP_OKAY) {
+    mp_clear (&t);
+    return res;
+  }
+  res = mp_mod (&t, c, d);
+  mp_clear (&t);
+  return res;
+}
+#endif
+
+/* End: bn_mp_mulmod.c */
+
+/* Start: bn_mp_n_root.c */
+#include <tommath.h>
+#ifdef BN_MP_N_ROOT_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* find the n'th root of an integer 
+ *
+ * Result found such that (c)**b <= a and (c+1)**b > a 
+ *
+ * This algorithm uses Newton's approximation 
+ * x[i+1] = x[i] - f(x[i])/f'(x[i]) 
+ * which will find the root in log(N) time where 
+ * each step involves a fair bit.  This is not meant to 
+ * find huge roots [square and cube, etc].
+ */
+int mp_n_root (mp_int * a, mp_digit b, mp_int * c)
+{
+  mp_int  t1, t2, t3;
+  int     res, neg;
+
+  /* input must be positive if b is even */
+  if ((b & 1) == 0 && a->sign == MP_NEG) {
+    return MP_VAL;
+  }
+
+  if ((res = mp_init (&t1)) != MP_OKAY) {
+    return res;
+  }
+
+  if ((res = mp_init (&t2)) != MP_OKAY) {
+    goto LBL_T1;
+  }
+
+  if ((res = mp_init (&t3)) != MP_OKAY) {
+    goto LBL_T2;
+  }
+
+  /* if a is negative fudge the sign but keep track */
+  neg     = a->sign;
+  a->sign = MP_ZPOS;
+
+  /* t2 = 2 */
+  mp_set (&t2, 2);
+
+  do {
+    /* t1 = t2 */
+    if ((res = mp_copy (&t2, &t1)) != MP_OKAY) {
+      goto LBL_T3;
+    }
+
+    /* t2 = t1 - ((t1**b - a) / (b * t1**(b-1))) */
+    
+    /* t3 = t1**(b-1) */
+    if ((res = mp_expt_d (&t1, b - 1, &t3)) != MP_OKAY) {   
+      goto LBL_T3;
+    }
+
+    /* numerator */
+    /* t2 = t1**b */
+    if ((res = mp_mul (&t3, &t1, &t2)) != MP_OKAY) {    
+      goto LBL_T3;
+    }
+
+    /* t2 = t1**b - a */
+    if ((res = mp_sub (&t2, a, &t2)) != MP_OKAY) {  
+      goto LBL_T3;
+    }
+
+    /* denominator */
+    /* t3 = t1**(b-1) * b  */
+    if ((res = mp_mul_d (&t3, b, &t3)) != MP_OKAY) {    
+      goto LBL_T3;
+    }
+
+    /* t3 = (t1**b - a)/(b * t1**(b-1)) */
+    if ((res = mp_div (&t2, &t3, &t3, NULL)) != MP_OKAY) {  
+      goto LBL_T3;
+    }
+
+    if ((res = mp_sub (&t1, &t3, &t2)) != MP_OKAY) {
+      goto LBL_T3;
+    }
+  }  while (mp_cmp (&t1, &t2) != MP_EQ);
+
+  /* result can be off by a few so check */
+  for (;;) {
+    if ((res = mp_expt_d (&t1, b, &t2)) != MP_OKAY) {
+      goto LBL_T3;
+    }
+
+    if (mp_cmp (&t2, a) == MP_GT) {
+      if ((res = mp_sub_d (&t1, 1, &t1)) != MP_OKAY) {
+         goto LBL_T3;
+      }
+    } else {
+      break;
+    }
+  }
+
+  /* reset the sign of a first */
+  a->sign = neg;
+
+  /* set the result */
+  mp_exch (&t1, c);
+
+  /* set the sign of the result */
+  c->sign = neg;
+
+  res = MP_OKAY;
+
+LBL_T3:mp_clear (&t3);
+LBL_T2:mp_clear (&t2);
+LBL_T1:mp_clear (&t1);
+  return res;
+}
+#endif
+
+/* End: bn_mp_n_root.c */
+
+/* Start: bn_mp_neg.c */
+#include <tommath.h>
+#ifdef BN_MP_NEG_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* b = -a */
+int mp_neg (mp_int * a, mp_int * b)
+{
+  int     res;
+  if (a != b) {
+     if ((res = mp_copy (a, b)) != MP_OKAY) {
+        return res;
+     }
+  }
+
+  if (mp_iszero(b) != MP_YES) {
+     b->sign = (a->sign == MP_ZPOS) ? MP_NEG : MP_ZPOS;
+  } else {
+     b->sign = MP_ZPOS;
+  }
+
+  return MP_OKAY;
+}
+#endif
+
+/* End: bn_mp_neg.c */
+
+/* Start: bn_mp_or.c */
+#include <tommath.h>
+#ifdef BN_MP_OR_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* OR two ints together */
+int mp_or (mp_int * a, mp_int * b, mp_int * c)
+{
+  int     res, ix, px;
+  mp_int  t, *x;
+
+  if (a->used > b->used) {
+    if ((res = mp_init_copy (&t, a)) != MP_OKAY) {
+      return res;
+    }
+    px = b->used;
+    x = b;
+  } else {
+    if ((res = mp_init_copy (&t, b)) != MP_OKAY) {
+      return res;
+    }
+    px = a->used;
+    x = a;
+  }
+
+  for (ix = 0; ix < px; ix++) {
+    t.dp[ix] |= x->dp[ix];
+  }
+  mp_clamp (&t);
+  mp_exch (c, &t);
+  mp_clear (&t);
+  return MP_OKAY;
+}
+#endif
+
+/* End: bn_mp_or.c */
+
+/* Start: bn_mp_prime_fermat.c */
+#include <tommath.h>
+#ifdef BN_MP_PRIME_FERMAT_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* performs one Fermat test.
+ * 
+ * If "a" were prime then b**a == b (mod a) since the order of
+ * the multiplicative sub-group would be phi(a) = a-1.  That means
+ * it would be the same as b**(a mod (a-1)) == b**1 == b (mod a).
+ *
+ * Sets result to 1 if the congruence holds, or zero otherwise.
+ */
+int mp_prime_fermat (mp_int * a, mp_int * b, int *result)
+{
+  mp_int  t;
+  int     err;
+
+  /* default to composite  */
+  *result = MP_NO;
+
+  /* ensure b > 1 */
+  if (mp_cmp_d(b, 1) != MP_GT) {
+     return MP_VAL;
+  }
+
+  /* init t */
+  if ((err = mp_init (&t)) != MP_OKAY) {
+    return err;
+  }
+
+  /* compute t = b**a mod a */
+  if ((err = mp_exptmod (b, a, a, &t)) != MP_OKAY) {
+    goto LBL_T;
+  }
+
+  /* is it equal to b? */
+  if (mp_cmp (&t, b) == MP_EQ) {
+    *result = MP_YES;
+  }
+
+  err = MP_OKAY;
+LBL_T:mp_clear (&t);
+  return err;
+}
+#endif
+
+/* End: bn_mp_prime_fermat.c */
+
+/* Start: bn_mp_prime_is_divisible.c */
+#include <tommath.h>
+#ifdef BN_MP_PRIME_IS_DIVISIBLE_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* determines if an integers is divisible by one 
+ * of the first PRIME_SIZE primes or not
+ *
+ * sets result to 0 if not, 1 if yes
+ */
+int mp_prime_is_divisible (mp_int * a, int *result)
+{
+  int     err, ix;
+  mp_digit res;
+
+  /* default to not */
+  *result = MP_NO;
+
+  for (ix = 0; ix < PRIME_SIZE; ix++) {
+    /* what is a mod LBL_prime_tab[ix] */
+    if ((err = mp_mod_d (a, ltm_prime_tab[ix], &res)) != MP_OKAY) {
+      return err;
+    }
+
+    /* is the residue zero? */
+    if (res == 0) {
+      *result = MP_YES;
+      return MP_OKAY;
+    }
+  }
+
+  return MP_OKAY;
+}
+#endif
+
+/* End: bn_mp_prime_is_divisible.c */
+
+/* Start: bn_mp_prime_is_prime.c */
+#include <tommath.h>
+#ifdef BN_MP_PRIME_IS_PRIME_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* performs a variable number of rounds of Miller-Rabin
+ *
+ * Probability of error after t rounds is no more than
+
+ *
+ * Sets result to 1 if probably prime, 0 otherwise
+ */
+int mp_prime_is_prime (mp_int * a, int t, int *result)
+{
+  mp_int  b;
+  int     ix, err, res;
+
+  /* default to no */
+  *result = MP_NO;
+
+  /* valid value of t? */
+  if (t <= 0 || t > PRIME_SIZE) {
+    return MP_VAL;
+  }
+
+  /* is the input equal to one of the primes in the table? */
+  for (ix = 0; ix < PRIME_SIZE; ix++) {
+      if (mp_cmp_d(a, ltm_prime_tab[ix]) == MP_EQ) {
+         *result = 1;
+         return MP_OKAY;
+      }
+  }
+
+  /* first perform trial division */
+  if ((err = mp_prime_is_divisible (a, &res)) != MP_OKAY) {
+    return err;
+  }
+
+  /* return if it was trivially divisible */
+  if (res == MP_YES) {
+    return MP_OKAY;
+  }
+
+  /* now perform the miller-rabin rounds */
+  if ((err = mp_init (&b)) != MP_OKAY) {
+    return err;
+  }
+
+  for (ix = 0; ix < t; ix++) {
+    /* set the prime */
+    mp_set (&b, ltm_prime_tab[ix]);
+
+    if ((err = mp_prime_miller_rabin (a, &b, &res)) != MP_OKAY) {
+      goto LBL_B;
+    }
+
+    if (res == MP_NO) {
+      goto LBL_B;
+    }
+  }
+
+  /* passed the test */
+  *result = MP_YES;
+LBL_B:mp_clear (&b);
+  return err;
+}
+#endif
+
+/* End: bn_mp_prime_is_prime.c */
+
+/* Start: bn_mp_prime_miller_rabin.c */
+#include <tommath.h>
+#ifdef BN_MP_PRIME_MILLER_RABIN_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* Miller-Rabin test of "a" to the base of "b" as described in 
+ * HAC pp. 139 Algorithm 4.24
+ *
+ * Sets result to 0 if definitely composite or 1 if probably prime.
+ * Randomly the chance of error is no more than 1/4 and often 
+ * very much lower.
+ */
+int mp_prime_miller_rabin (mp_int * a, mp_int * b, int *result)
+{
+  mp_int  n1, y, r;
+  int     s, j, err;
+
+  /* default */
+  *result = MP_NO;
+
+  /* ensure b > 1 */
+  if (mp_cmp_d(b, 1) != MP_GT) {
+     return MP_VAL;
+  }     
+
+  /* get n1 = a - 1 */
+  if ((err = mp_init_copy (&n1, a)) != MP_OKAY) {
+    return err;
+  }
+  if ((err = mp_sub_d (&n1, 1, &n1)) != MP_OKAY) {
+    goto LBL_N1;
+  }
+
+  /* set 2**s * r = n1 */
+  if ((err = mp_init_copy (&r, &n1)) != MP_OKAY) {
+    goto LBL_N1;
+  }
+
+  /* count the number of least significant bits
+   * which are zero
+   */
+  s = mp_cnt_lsb(&r);
+
+  /* now divide n - 1 by 2**s */
+  if ((err = mp_div_2d (&r, s, &r, NULL)) != MP_OKAY) {
+    goto LBL_R;
+  }
+
+  /* compute y = b**r mod a */
+  if ((err = mp_init (&y)) != MP_OKAY) {
+    goto LBL_R;
+  }
+  if ((err = mp_exptmod (b, &r, a, &y)) != MP_OKAY) {
+    goto LBL_Y;
+  }
+
+  /* if y != 1 and y != n1 do */
+  if (mp_cmp_d (&y, 1) != MP_EQ && mp_cmp (&y, &n1) != MP_EQ) {
+    j = 1;
+    /* while j <= s-1 and y != n1 */
+    while ((j <= (s - 1)) && mp_cmp (&y, &n1) != MP_EQ) {
+      if ((err = mp_sqrmod (&y, a, &y)) != MP_OKAY) {
+         goto LBL_Y;
+      }
+
+      /* if y == 1 then composite */
+      if (mp_cmp_d (&y, 1) == MP_EQ) {
+         goto LBL_Y;
+      }
+
+      ++j;
+    }
+
+    /* if y != n1 then composite */
+    if (mp_cmp (&y, &n1) != MP_EQ) {
+      goto LBL_Y;
+    }
+  }
+
+  /* probably prime now */
+  *result = MP_YES;
+LBL_Y:mp_clear (&y);
+LBL_R:mp_clear (&r);
+LBL_N1:mp_clear (&n1);
+  return err;
+}
+#endif
+
+/* End: bn_mp_prime_miller_rabin.c */
+
+/* Start: bn_mp_prime_next_prime.c */
+#include <tommath.h>
+#ifdef BN_MP_PRIME_NEXT_PRIME_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* finds the next prime after the number "a" using "t" trials
+ * of Miller-Rabin.
+ *
+ * bbs_style = 1 means the prime must be congruent to 3 mod 4
+ */
+int mp_prime_next_prime(mp_int *a, int t, int bbs_style)
+{
+   int      err, res, x, y;
+   mp_digit res_tab[PRIME_SIZE], step, kstep;
+   mp_int   b;
+
+   /* ensure t is valid */
+   if (t <= 0 || t > PRIME_SIZE) {
+      return MP_VAL;
+   }
+
+   /* force positive */
+   a->sign = MP_ZPOS;
+
+   /* simple algo if a is less than the largest prime in the table */
+   if (mp_cmp_d(a, ltm_prime_tab[PRIME_SIZE-1]) == MP_LT) {
+      /* find which prime it is bigger than */
+      for (x = PRIME_SIZE - 2; x >= 0; x--) {
+          if (mp_cmp_d(a, ltm_prime_tab[x]) != MP_LT) {
+             if (bbs_style == 1) {
+                /* ok we found a prime smaller or
+                 * equal [so the next is larger]
+                 *
+                 * however, the prime must be
+                 * congruent to 3 mod 4
+                 */
+                if ((ltm_prime_tab[x + 1] & 3) != 3) {
+                   /* scan upwards for a prime congruent to 3 mod 4 */
+                   for (y = x + 1; y < PRIME_SIZE; y++) {
+                       if ((ltm_prime_tab[y] & 3) == 3) {
+                          mp_set(a, ltm_prime_tab[y]);
+                          return MP_OKAY;
+                       }
+                   }
+                }
+             } else {
+                mp_set(a, ltm_prime_tab[x + 1]);
+                return MP_OKAY;
+             }
+          }
+      }
+      /* at this point a maybe 1 */
+      if (mp_cmp_d(a, 1) == MP_EQ) {
+         mp_set(a, 2);
+         return MP_OKAY;
+      }
+      /* fall through to the sieve */
+   }
+
+   /* generate a prime congruent to 3 mod 4 or 1/3 mod 4? */
+   if (bbs_style == 1) {
+      kstep   = 4;
+   } else {
+      kstep   = 2;
+   }
+
+   /* at this point we will use a combination of a sieve and Miller-Rabin */
+
+   if (bbs_style == 1) {
+      /* if a mod 4 != 3 subtract the correct value to make it so */
+      if ((a->dp[0] & 3) != 3) {
+         if ((err = mp_sub_d(a, (a->dp[0] & 3) + 1, a)) != MP_OKAY) { return err; };
+      }
+   } else {
+      if (mp_iseven(a) == 1) {
+         /* force odd */
+         if ((err = mp_sub_d(a, 1, a)) != MP_OKAY) {
+            return err;
+         }
+      }
+   }
+
+   /* generate the restable */
+   for (x = 1; x < PRIME_SIZE; x++) {
+      if ((err = mp_mod_d(a, ltm_prime_tab[x], res_tab + x)) != MP_OKAY) {
+         return err;
+      }
+   }
+
+   /* init temp used for Miller-Rabin Testing */
+   if ((err = mp_init(&b)) != MP_OKAY) {
+      return err;
+   }
+
+   for (;;) {
+      /* skip to the next non-trivially divisible candidate */
+      step = 0;
+      do {
+         /* y == 1 if any residue was zero [e.g. cannot be prime] */
+         y     =  0;
+
+         /* increase step to next candidate */
+         step += kstep;
+
+         /* compute the new residue without using division */
+         for (x = 1; x < PRIME_SIZE; x++) {
+             /* add the step to each residue */
+             res_tab[x] += kstep;
+
+             /* subtract the modulus [instead of using division] */
+             if (res_tab[x] >= ltm_prime_tab[x]) {
+                res_tab[x]  -= ltm_prime_tab[x];
+             }
+
+             /* set flag if zero */
+             if (res_tab[x] == 0) {
+                y = 1;
+             }
+         }
+      } while (y == 1 && step < ((((mp_digit)1)<<DIGIT_BIT) - kstep));
+
+      /* add the step */
+      if ((err = mp_add_d(a, step, a)) != MP_OKAY) {
+         goto LBL_ERR;
+      }
+
+      /* if didn't pass sieve and step == MAX then skip test */
+      if (y == 1 && step >= ((((mp_digit)1)<<DIGIT_BIT) - kstep)) {
+         continue;
+      }
+
+      /* is this prime? */
+      for (x = 0; x < t; x++) {
+          mp_set(&b, ltm_prime_tab[x]);
+          if ((err = mp_prime_miller_rabin(a, &b, &res)) != MP_OKAY) {
+             goto LBL_ERR;
+          }
+          if (res == MP_NO) {
+             break;
+          }
+      }
+
+      if (res == MP_YES) {
+         break;
+      }
+   }
+
+   err = MP_OKAY;
+LBL_ERR:
+   mp_clear(&b);
+   return err;
+}
+
+#endif
+
+/* End: bn_mp_prime_next_prime.c */
+
+/* Start: bn_mp_prime_rabin_miller_trials.c */
+#include <tommath.h>
+#ifdef BN_MP_PRIME_RABIN_MILLER_TRIALS_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+
+static const struct {
+   int k, t;
+} sizes[] = {
+{   128,    28 },
+{   256,    16 },
+{   384,    10 },
+{   512,     7 },
+{   640,     6 },
+{   768,     5 },
+{   896,     4 },
+{  1024,     4 }
+};
+
+/* returns # of RM trials required for a given bit size */
+int mp_prime_rabin_miller_trials(int size)
+{
+   int x;
+
+   for (x = 0; x < (int)(sizeof(sizes)/(sizeof(sizes[0]))); x++) {
+       if (sizes[x].k == size) {
+          return sizes[x].t;
+       } else if (sizes[x].k > size) {
+          return (x == 0) ? sizes[0].t : sizes[x - 1].t;
+       }
+   }
+   return sizes[x-1].t + 1;
+}
+
+
+#endif
+
+/* End: bn_mp_prime_rabin_miller_trials.c */
+
+/* Start: bn_mp_prime_random_ex.c */
+#include <tommath.h>
+#ifdef BN_MP_PRIME_RANDOM_EX_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* makes a truly random prime of a given size (bits),
+ *
+ * Flags are as follows:
+ * 
+ *   LTM_PRIME_BBS      - make prime congruent to 3 mod 4
+ *   LTM_PRIME_SAFE     - make sure (p-1)/2 is prime as well (implies LTM_PRIME_BBS)
+ *   LTM_PRIME_2MSB_OFF - make the 2nd highest bit zero
+ *   LTM_PRIME_2MSB_ON  - make the 2nd highest bit one
+ *
+ * You have to supply a callback which fills in a buffer with random bytes.  "dat" is a parameter you can
+ * have passed to the callback (e.g. a state or something).  This function doesn't use "dat" itself
+ * so it can be NULL
+ *
+ */
+
+/* This is possibly the mother of all prime generation functions, muahahahahaha! */
+int mp_prime_random_ex(mp_int *a, int t, int size, int flags, ltm_prime_callback cb, void *dat)
+{
+   unsigned char *tmp, maskAND, maskOR_msb, maskOR_lsb;
+   int res, err, bsize, maskOR_msb_offset;
+
+   /* sanity check the input */
+   if (size <= 1 || t <= 0) {
+      return MP_VAL;
+   }
+
+   /* LTM_PRIME_SAFE implies LTM_PRIME_BBS */
+   if (flags & LTM_PRIME_SAFE) {
+      flags |= LTM_PRIME_BBS;
+   }
+
+   /* calc the byte size */
+   bsize = (size>>3) + ((size&7)?1:0);
+
+   /* we need a buffer of bsize bytes */
+   tmp = OPT_CAST(unsigned char) XMALLOC(bsize);
+   if (tmp == NULL) {
+      return MP_MEM;
+   }
+
+   /* calc the maskAND value for the MSbyte*/
+   maskAND = ((size&7) == 0) ? 0xFF : (0xFF >> (8 - (size & 7)));
+
+   /* calc the maskOR_msb */
+   maskOR_msb        = 0;
+   maskOR_msb_offset = ((size & 7) == 1) ? 1 : 0;
+   if (flags & LTM_PRIME_2MSB_ON) {
+      maskOR_msb       |= 0x80 >> ((9 - size) & 7);
+   }  
+
+   /* get the maskOR_lsb */
+   maskOR_lsb         = 1;
+   if (flags & LTM_PRIME_BBS) {
+      maskOR_lsb     |= 3;
+   }
+
+   do {
+      /* read the bytes */
+      if (cb(tmp, bsize, dat) != bsize) {
+         err = MP_VAL;
+         goto error;
+      }
+ 
+      /* work over the MSbyte */
+      tmp[0]    &= maskAND;
+      tmp[0]    |= 1 << ((size - 1) & 7);
+
+      /* mix in the maskORs */
+      tmp[maskOR_msb_offset]   |= maskOR_msb;
+      tmp[bsize-1]             |= maskOR_lsb;
+
+      /* read it in */
+      if ((err = mp_read_unsigned_bin(a, tmp, bsize)) != MP_OKAY)     { goto error; }
+
+      /* is it prime? */
+      if ((err = mp_prime_is_prime(a, t, &res)) != MP_OKAY)           { goto error; }
+      if (res == MP_NO) {  
+         continue;
+      }
+
+      if (flags & LTM_PRIME_SAFE) {
+         /* see if (a-1)/2 is prime */
+         if ((err = mp_sub_d(a, 1, a)) != MP_OKAY)                    { goto error; }
+         if ((err = mp_div_2(a, a)) != MP_OKAY)                       { goto error; }
+ 
+         /* is it prime? */
+         if ((err = mp_prime_is_prime(a, t, &res)) != MP_OKAY)        { goto error; }
+      }
+   } while (res == MP_NO);
+
+   if (flags & LTM_PRIME_SAFE) {
+      /* restore a to the original value */
+      if ((err = mp_mul_2(a, a)) != MP_OKAY)                          { goto error; }
+      if ((err = mp_add_d(a, 1, a)) != MP_OKAY)                       { goto error; }
+   }
+
+   err = MP_OKAY;
+error:
+   XFREE(tmp);
+   return err;
+}
+
+
+#endif
+
+/* End: bn_mp_prime_random_ex.c */
+
+/* Start: bn_mp_radix_size.c */
+#include <tommath.h>
+#ifdef BN_MP_RADIX_SIZE_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* returns size of ASCII reprensentation */
+int mp_radix_size (mp_int * a, int radix, int *size)
+{
+  int     res, digs;
+  mp_int  t;
+  mp_digit d;
+
+  *size = 0;
+
+  /* special case for binary */
+  if (radix == 2) {
+    *size = mp_count_bits (a) + (a->sign == MP_NEG ? 1 : 0) + 1;
+    return MP_OKAY;
+  }
+
+  /* make sure the radix is in range */
+  if (radix < 2 || radix > 64) {
+    return MP_VAL;
+  }
+
+  if (mp_iszero(a) == MP_YES) {
+    *size = 2;
+    return MP_OKAY;
+  }
+
+  /* digs is the digit count */
+  digs = 0;
+
+  /* if it's negative add one for the sign */
+  if (a->sign == MP_NEG) {
+    ++digs;
+  }
+
+  /* init a copy of the input */
+  if ((res = mp_init_copy (&t, a)) != MP_OKAY) {
+    return res;
+  }
+
+  /* force temp to positive */
+  t.sign = MP_ZPOS; 
+
+  /* fetch out all of the digits */
+  while (mp_iszero (&t) == MP_NO) {
+    if ((res = mp_div_d (&t, (mp_digit) radix, &t, &d)) != MP_OKAY) {
+      mp_clear (&t);
+      return res;
+    }
+    ++digs;
+  }
+  mp_clear (&t);
+
+  /* return digs + 1, the 1 is for the NULL byte that would be required. */
+  *size = digs + 1;
+  return MP_OKAY;
+}
+
+#endif
+
+/* End: bn_mp_radix_size.c */
+
+/* Start: bn_mp_radix_smap.c */
+#include <tommath.h>
+#ifdef BN_MP_RADIX_SMAP_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* chars used in radix conversions */
+const char *mp_s_rmap = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz+/";
+#endif
+
+/* End: bn_mp_radix_smap.c */
+
+/* Start: bn_mp_rand.c */
+#include <tommath.h>
+#ifdef BN_MP_RAND_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* makes a pseudo-random int of a given size */
+int
+mp_rand (mp_int * a, int digits)
+{
+  int     res;
+  mp_digit d;
+
+  mp_zero (a);
+  if (digits <= 0) {
+    return MP_OKAY;
+  }
+
+  /* first place a random non-zero digit */
+  do {
+    d = ((mp_digit) abs (rand ())) & MP_MASK;
+  } while (d == 0);
+
+  if ((res = mp_add_d (a, d, a)) != MP_OKAY) {
+    return res;
+  }
+
+  while (--digits > 0) {
+    if ((res = mp_lshd (a, 1)) != MP_OKAY) {
+      return res;
+    }
+
+    if ((res = mp_add_d (a, ((mp_digit) abs (rand ())), a)) != MP_OKAY) {
+      return res;
+    }
+  }
+
+  return MP_OKAY;
+}
+#endif
+
+/* End: bn_mp_rand.c */
+
+/* Start: bn_mp_read_radix.c */
+#include <tommath.h>
+#ifdef BN_MP_READ_RADIX_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* read a string [ASCII] in a given radix */
+int mp_read_radix (mp_int * a, const char *str, int radix)
+{
+  int     y, res, neg;
+  char    ch;
+
+  /* zero the digit bignum */
+  mp_zero(a);
+
+  /* make sure the radix is ok */
+  if (radix < 2 || radix > 64) {
+    return MP_VAL;
+  }
+
+  /* if the leading digit is a 
+   * minus set the sign to negative. 
+   */
+  if (*str == '-') {
+    ++str;
+    neg = MP_NEG;
+  } else {
+    neg = MP_ZPOS;
+  }
+
+  /* set the integer to the default of zero */
+  mp_zero (a);
+  
+  /* process each digit of the string */
+  while (*str) {
+    /* if the radix < 36 the conversion is case insensitive
+     * this allows numbers like 1AB and 1ab to represent the same  value
+     * [e.g. in hex]
+     */
+    ch = (char) ((radix < 36) ? toupper (*str) : *str);
+    for (y = 0; y < 64; y++) {
+      if (ch == mp_s_rmap[y]) {
+         break;
+      }
+    }
+
+    /* if the char was found in the map 
+     * and is less than the given radix add it
+     * to the number, otherwise exit the loop. 
+     */
+    if (y < radix) {
+      if ((res = mp_mul_d (a, (mp_digit) radix, a)) != MP_OKAY) {
+         return res;
+      }
+      if ((res = mp_add_d (a, (mp_digit) y, a)) != MP_OKAY) {
+         return res;
+      }
+    } else {
+      break;
+    }
+    ++str;
+  }
+  
+  /* set the sign only if a != 0 */
+  if (mp_iszero(a) != 1) {
+     a->sign = neg;
+  }
+  return MP_OKAY;
+}
+#endif
+
+/* End: bn_mp_read_radix.c */
+
+/* Start: bn_mp_read_signed_bin.c */
+#include <tommath.h>
+#ifdef BN_MP_READ_SIGNED_BIN_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* read signed bin, big endian, first byte is 0==positive or 1==negative */
+int mp_read_signed_bin (mp_int * a, const unsigned char *b, int c)
+{
+  int     res;
+
+  /* read magnitude */
+  if ((res = mp_read_unsigned_bin (a, b + 1, c - 1)) != MP_OKAY) {
+    return res;
+  }
+
+  /* first byte is 0 for positive, non-zero for negative */
+  if (b[0] == 0) {
+     a->sign = MP_ZPOS;
+  } else {
+     a->sign = MP_NEG;
+  }
+
+  return MP_OKAY;
+}
+#endif
+
+/* End: bn_mp_read_signed_bin.c */
+
+/* Start: bn_mp_read_unsigned_bin.c */
+#include <tommath.h>
+#ifdef BN_MP_READ_UNSIGNED_BIN_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* reads a unsigned char array, assumes the msb is stored first [big endian] */
+int mp_read_unsigned_bin (mp_int * a, const unsigned char *b, int c)
+{
+  int     res;
+
+  /* make sure there are at least two digits */
+  if (a->alloc < 2) {
+     if ((res = mp_grow(a, 2)) != MP_OKAY) {
+        return res;
+     }
+  }
+
+  /* zero the int */
+  mp_zero (a);
+
+  /* read the bytes in */
+  while (c-- > 0) {
+    if ((res = mp_mul_2d (a, 8, a)) != MP_OKAY) {
+      return res;
+    }
+
+#ifndef MP_8BIT
+      a->dp[0] |= *b++;
+      a->used += 1;
+#else
+      a->dp[0] = (*b & MP_MASK);
+      a->dp[1] |= ((*b++ >> 7U) & 1);
+      a->used += 2;
+#endif
+  }
+  mp_clamp (a);
+  return MP_OKAY;
+}
+#endif
+
+/* End: bn_mp_read_unsigned_bin.c */
+
+/* Start: bn_mp_reduce.c */
+#include <tommath.h>
+#ifdef BN_MP_REDUCE_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* reduces x mod m, assumes 0 < x < m**2, mu is 
+ * precomputed via mp_reduce_setup.
+ * From HAC pp.604 Algorithm 14.42
+ */
+int mp_reduce (mp_int * x, mp_int * m, mp_int * mu)
+{
+  mp_int  q;
+  int     res, um = m->used;
+
+  /* q = x */
+  if ((res = mp_init_copy (&q, x)) != MP_OKAY) {
+    return res;
+  }
+
+  /* q1 = x / b**(k-1)  */
+  mp_rshd (&q, um - 1);         
+
+  /* according to HAC this optimization is ok */
+  if (((unsigned long) um) > (((mp_digit)1) << (DIGIT_BIT - 1))) {
+    if ((res = mp_mul (&q, mu, &q)) != MP_OKAY) {
+      goto CLEANUP;
+    }
+  } else {
+#ifdef BN_S_MP_MUL_HIGH_DIGS_C
+    if ((res = s_mp_mul_high_digs (&q, mu, &q, um)) != MP_OKAY) {
+      goto CLEANUP;
+    }
+#elif defined(BN_FAST_S_MP_MUL_HIGH_DIGS_C)
+    if ((res = fast_s_mp_mul_high_digs (&q, mu, &q, um)) != MP_OKAY) {
+      goto CLEANUP;
+    }
+#else 
+    { 
+      res = MP_VAL;
+      goto CLEANUP;
+    }
+#endif
+  }
+
+  /* q3 = q2 / b**(k+1) */
+  mp_rshd (&q, um + 1);         
+
+  /* x = x mod b**(k+1), quick (no division) */
+  if ((res = mp_mod_2d (x, DIGIT_BIT * (um + 1), x)) != MP_OKAY) {
+    goto CLEANUP;
+  }
+
+  /* q = q * m mod b**(k+1), quick (no division) */
+  if ((res = s_mp_mul_digs (&q, m, &q, um + 1)) != MP_OKAY) {
+    goto CLEANUP;
+  }
+
+  /* x = x - q */
+  if ((res = mp_sub (x, &q, x)) != MP_OKAY) {
+    goto CLEANUP;
+  }
+
+  /* If x < 0, add b**(k+1) to it */
+  if (mp_cmp_d (x, 0) == MP_LT) {
+    mp_set (&q, 1);
+    if ((res = mp_lshd (&q, um + 1)) != MP_OKAY)
+      goto CLEANUP;
+    if ((res = mp_add (x, &q, x)) != MP_OKAY)
+      goto CLEANUP;
+  }
+
+  /* Back off if it's too big */
+  while (mp_cmp (x, m) != MP_LT) {
+    if ((res = s_mp_sub (x, m, x)) != MP_OKAY) {
+      goto CLEANUP;
+    }
+  }
+  
+CLEANUP:
+  mp_clear (&q);
+
+  return res;
+}
+#endif
+
+/* End: bn_mp_reduce.c */
+
+/* Start: bn_mp_reduce_2k.c */
+#include <tommath.h>
+#ifdef BN_MP_REDUCE_2K_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* reduces a modulo n where n is of the form 2**p - d */
+int mp_reduce_2k(mp_int *a, mp_int *n, mp_digit d)
+{
+   mp_int q;
+   int    p, res;
+   
+   if ((res = mp_init(&q)) != MP_OKAY) {
+      return res;
+   }
+   
+   p = mp_count_bits(n);    
+top:
+   /* q = a/2**p, a = a mod 2**p */
+   if ((res = mp_div_2d(a, p, &q, a)) != MP_OKAY) {
+      goto ERR;
+   }
+   
+   if (d != 1) {
+      /* q = q * d */
+      if ((res = mp_mul_d(&q, d, &q)) != MP_OKAY) { 
+         goto ERR;
+      }
+   }
+   
+   /* a = a + q */
+   if ((res = s_mp_add(a, &q, a)) != MP_OKAY) {
+      goto ERR;
+   }
+   
+   if (mp_cmp_mag(a, n) != MP_LT) {
+      s_mp_sub(a, n, a);
+      goto top;
+   }
+   
+ERR:
+   mp_clear(&q);
+   return res;
+}
+
+#endif
+
+/* End: bn_mp_reduce_2k.c */
+
+/* Start: bn_mp_reduce_2k_l.c */
+#include <tommath.h>
+#ifdef BN_MP_REDUCE_2K_L_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* reduces a modulo n where n is of the form 2**p - d 
+   This differs from reduce_2k since "d" can be larger
+   than a single digit.
+*/
+int mp_reduce_2k_l(mp_int *a, mp_int *n, mp_int *d)
+{
+   mp_int q;
+   int    p, res;
+   
+   if ((res = mp_init(&q)) != MP_OKAY) {
+      return res;
+   }
+   
+   p = mp_count_bits(n);    
+top:
+   /* q = a/2**p, a = a mod 2**p */
+   if ((res = mp_div_2d(a, p, &q, a)) != MP_OKAY) {
+      goto ERR;
+   }
+   
+   /* q = q * d */
+   if ((res = mp_mul(&q, d, &q)) != MP_OKAY) { 
+      goto ERR;
+   }
+   
+   /* a = a + q */
+   if ((res = s_mp_add(a, &q, a)) != MP_OKAY) {
+      goto ERR;
+   }
+   
+   if (mp_cmp_mag(a, n) != MP_LT) {
+      s_mp_sub(a, n, a);
+      goto top;
+   }
+   
+ERR:
+   mp_clear(&q);
+   return res;
+}
+
+#endif
+
+/* End: bn_mp_reduce_2k_l.c */
+
+/* Start: bn_mp_reduce_2k_setup.c */
+#include <tommath.h>
+#ifdef BN_MP_REDUCE_2K_SETUP_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* determines the setup value */
+int mp_reduce_2k_setup(mp_int *a, mp_digit *d)
+{
+   int res, p;
+   mp_int tmp;
+   
+   if ((res = mp_init(&tmp)) != MP_OKAY) {
+      return res;
+   }
+   
+   p = mp_count_bits(a);
+   if ((res = mp_2expt(&tmp, p)) != MP_OKAY) {
+      mp_clear(&tmp);
+      return res;
+   }
+   
+   if ((res = s_mp_sub(&tmp, a, &tmp)) != MP_OKAY) {
+      mp_clear(&tmp);
+      return res;
+   }
+   
+   *d = tmp.dp[0];
+   mp_clear(&tmp);
+   return MP_OKAY;
+}
+#endif
+
+/* End: bn_mp_reduce_2k_setup.c */
+
+/* Start: bn_mp_reduce_2k_setup_l.c */
+#include <tommath.h>
+#ifdef BN_MP_REDUCE_2K_SETUP_L_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* determines the setup value */
+int mp_reduce_2k_setup_l(mp_int *a, mp_int *d)
+{
+   int    res;
+   mp_int tmp;
+   
+   if ((res = mp_init(&tmp)) != MP_OKAY) {
+      return res;
+   }
+   
+   if ((res = mp_2expt(&tmp, mp_count_bits(a))) != MP_OKAY) {
+      goto ERR;
+   }
+   
+   if ((res = s_mp_sub(&tmp, a, d)) != MP_OKAY) {
+      goto ERR;
+   }
+   
+ERR:
+   mp_clear(&tmp);
+   return res;
+}
+#endif
+
+/* End: bn_mp_reduce_2k_setup_l.c */
+
+/* Start: bn_mp_reduce_is_2k.c */
+#include <tommath.h>
+#ifdef BN_MP_REDUCE_IS_2K_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* determines if mp_reduce_2k can be used */
+int mp_reduce_is_2k(mp_int *a)
+{
+   int ix, iy, iw;
+   mp_digit iz;
+   
+   if (a->used == 0) {
+      return MP_NO;
+   } else if (a->used == 1) {
+      return MP_YES;
+   } else if (a->used > 1) {
+      iy = mp_count_bits(a);
+      iz = 1;
+      iw = 1;
+    
+      /* Test every bit from the second digit up, must be 1 */
+      for (ix = DIGIT_BIT; ix < iy; ix++) {
+          if ((a->dp[iw] & iz) == 0) {
+             return MP_NO;
+          }
+          iz <<= 1;
+          if (iz > (mp_digit)MP_MASK) {
+             ++iw;
+             iz = 1;
+          }
+      }
+   }
+   return MP_YES;
+}
+
+#endif
+
+/* End: bn_mp_reduce_is_2k.c */
+
+/* Start: bn_mp_reduce_is_2k_l.c */
+#include <tommath.h>
+#ifdef BN_MP_REDUCE_IS_2K_L_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* determines if reduce_2k_l can be used */
+int mp_reduce_is_2k_l(mp_int *a)
+{
+   int ix, iy;
+   
+   if (a->used == 0) {
+      return MP_NO;
+   } else if (a->used == 1) {
+      return MP_YES;
+   } else if (a->used > 1) {
+      /* if more than half of the digits are -1 we're sold */
+      for (iy = ix = 0; ix < a->used; ix++) {
+          if (a->dp[ix] == MP_MASK) {
+              ++iy;
+          }
+      }
+      return (iy >= (a->used/2)) ? MP_YES : MP_NO;
+      
+   }
+   return MP_NO;
+}
+
+#endif
+
+/* End: bn_mp_reduce_is_2k_l.c */
+
+/* Start: bn_mp_reduce_setup.c */
+#include <tommath.h>
+#ifdef BN_MP_REDUCE_SETUP_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* pre-calculate the value required for Barrett reduction
+ * For a given modulus "b" it calulates the value required in "a"
+ */
+int mp_reduce_setup (mp_int * a, mp_int * b)
+{
+  int     res;
+  
+  if ((res = mp_2expt (a, b->used * 2 * DIGIT_BIT)) != MP_OKAY) {
+    return res;
+  }
+  return mp_div (a, b, a, NULL);
+}
+#endif
+
+/* End: bn_mp_reduce_setup.c */
+
+/* Start: bn_mp_rshd.c */
+#include <tommath.h>
+#ifdef BN_MP_RSHD_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* shift right a certain amount of digits */
+void mp_rshd (mp_int * a, int b)
+{
+  int     x;
+
+  /* if b <= 0 then ignore it */
+  if (b <= 0) {
+    return;
+  }
+
+  /* if b > used then simply zero it and return */
+  if (a->used <= b) {
+    mp_zero (a);
+    return;
+  }
+
+  {
+    register mp_digit *bottom, *top;
+
+    /* shift the digits down */
+
+    /* bottom */
+    bottom = a->dp;
+
+    /* top [offset into digits] */
+    top = a->dp + b;
+
+    /* this is implemented as a sliding window where 
+     * the window is b-digits long and digits from 
+     * the top of the window are copied to the bottom
+     *
+     * e.g.
+
+     b-2 | b-1 | b0 | b1 | b2 | ... | bb |   ---->
+                 /\                   |      ---->
+                  \-------------------/      ---->
+     */
+    for (x = 0; x < (a->used - b); x++) {
+      *bottom++ = *top++;
+    }
+
+    /* zero the top digits */
+    for (; x < a->used; x++) {
+      *bottom++ = 0;
+    }
+  }
+  
+  /* remove excess digits */
+  a->used -= b;
+}
+#endif
+
+/* End: bn_mp_rshd.c */
+
+/* Start: bn_mp_set.c */
+#include <tommath.h>
+#ifdef BN_MP_SET_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* set to a digit */
+void mp_set (mp_int * a, mp_digit b)
+{
+  mp_zero (a);
+  a->dp[0] = b & MP_MASK;
+  a->used  = (a->dp[0] != 0) ? 1 : 0;
+}
+#endif
+
+/* End: bn_mp_set.c */
+
+/* Start: bn_mp_set_int.c */
+#include <tommath.h>
+#ifdef BN_MP_SET_INT_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* set a 32-bit const */
+int mp_set_int (mp_int * a, unsigned long b)
+{
+  int     x, res;
+
+  mp_zero (a);
+  
+  /* set four bits at a time */
+  for (x = 0; x < 8; x++) {
+    /* shift the number up four bits */
+    if ((res = mp_mul_2d (a, 4, a)) != MP_OKAY) {
+      return res;
+    }
+
+    /* OR in the top four bits of the source */
+    a->dp[0] |= (b >> 28) & 15;
+
+    /* shift the source up to the next four bits */
+    b <<= 4;
+
+    /* ensure that digits are not clamped off */
+    a->used += 1;
+  }
+  mp_clamp (a);
+  return MP_OKAY;
+}
+#endif
+
+/* End: bn_mp_set_int.c */
+
+/* Start: bn_mp_shrink.c */
+#include <tommath.h>
+#ifdef BN_MP_SHRINK_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* shrink a bignum */
+int mp_shrink (mp_int * a)
+{
+  mp_digit *tmp;
+  int used = 1;
+  
+  if(a->used > 0)
+    used = a->used;
+  
+  if (a->alloc != used) {
+    if ((tmp = OPT_CAST(mp_digit) XREALLOC (a->dp, sizeof (mp_digit) * used)) == NULL) {
+      return MP_MEM;
+    }
+    a->dp    = tmp;
+    a->alloc = used;
+  }
+  return MP_OKAY;
+}
+#endif
+
+/* End: bn_mp_shrink.c */
+
+/* Start: bn_mp_signed_bin_size.c */
+#include <tommath.h>
+#ifdef BN_MP_SIGNED_BIN_SIZE_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* get the size for an signed equivalent */
+int mp_signed_bin_size (mp_int * a)
+{
+  return 1 + mp_unsigned_bin_size (a);
+}
+#endif
+
+/* End: bn_mp_signed_bin_size.c */
+
+/* Start: bn_mp_sqr.c */
+#include <tommath.h>
+#ifdef BN_MP_SQR_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* computes b = a*a */
+int
+mp_sqr (mp_int * a, mp_int * b)
+{
+  int     res;
+
+#ifdef BN_MP_TOOM_SQR_C
+  /* use Toom-Cook? */
+  if (a->used >= TOOM_SQR_CUTOFF) {
+    res = mp_toom_sqr(a, b);
+  /* Karatsuba? */
+  } else 
+#endif
+#ifdef BN_MP_KARATSUBA_SQR_C
+if (a->used >= KARATSUBA_SQR_CUTOFF) {
+    res = mp_karatsuba_sqr (a, b);
+  } else 
+#endif
+  {
+#ifdef BN_FAST_S_MP_SQR_C
+    /* can we use the fast comba multiplier? */
+    if ((a->used * 2 + 1) < MP_WARRAY && 
+         a->used < 
+         (1 << (sizeof(mp_word) * CHAR_BIT - 2*DIGIT_BIT - 1))) {
+      res = fast_s_mp_sqr (a, b);
+    } else
+#endif
+#ifdef BN_S_MP_SQR_C
+      res = s_mp_sqr (a, b);
+#else
+      res = MP_VAL;
+#endif
+  }
+  b->sign = MP_ZPOS;
+  return res;
+}
+#endif
+
+/* End: bn_mp_sqr.c */
+
+/* Start: bn_mp_sqrmod.c */
+#include <tommath.h>
+#ifdef BN_MP_SQRMOD_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* c = a * a (mod b) */
+int
+mp_sqrmod (mp_int * a, mp_int * b, mp_int * c)
+{
+  int     res;
+  mp_int  t;
+
+  if ((res = mp_init (&t)) != MP_OKAY) {
+    return res;
+  }
+
+  if ((res = mp_sqr (a, &t)) != MP_OKAY) {
+    mp_clear (&t);
+    return res;
+  }
+  res = mp_mod (&t, b, c);
+  mp_clear (&t);
+  return res;
+}
+#endif
+
+/* End: bn_mp_sqrmod.c */
+
+/* Start: bn_mp_sqrt.c */
+#include <tommath.h>
+
+#ifdef BN_MP_SQRT_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* this function is less generic than mp_n_root, simpler and faster */
+int mp_sqrt(mp_int *arg, mp_int *ret) 
+{
+  int res;
+  mp_int t1,t2;
+
+  /* must be positive */
+  if (arg->sign == MP_NEG) {
+    return MP_VAL;
+  }
+
+  /* easy out */
+  if (mp_iszero(arg) == MP_YES) {
+    mp_zero(ret);
+    return MP_OKAY;
+  }
+
+  if ((res = mp_init_copy(&t1, arg)) != MP_OKAY) {
+    return res;
+  }
+
+  if ((res = mp_init(&t2)) != MP_OKAY) {
+    goto E2;
+  }
+
+  /* First approx. (not very bad for large arg) */
+  mp_rshd (&t1,t1.used/2);
+
+  /* t1 > 0  */ 
+  if ((res = mp_div(arg,&t1,&t2,NULL)) != MP_OKAY) {
+    goto E1;
+  }
+  if ((res = mp_add(&t1,&t2,&t1)) != MP_OKAY) {
+    goto E1;
+  }
+  if ((res = mp_div_2(&t1,&t1)) != MP_OKAY) {
+    goto E1;
+  }
+  /* And now t1 > sqrt(arg) */
+  do { 
+    if ((res = mp_div(arg,&t1,&t2,NULL)) != MP_OKAY) {
+      goto E1;
+    }
+    if ((res = mp_add(&t1,&t2,&t1)) != MP_OKAY) {
+      goto E1;
+    }
+    if ((res = mp_div_2(&t1,&t1)) != MP_OKAY) {
+      goto E1;
+    }
+    /* t1 >= sqrt(arg) >= t2 at this point */
+  } while (mp_cmp_mag(&t1,&t2) == MP_GT);
+
+  mp_exch(&t1,ret);
+
+E1: mp_clear(&t2);
+E2: mp_clear(&t1);
+  return res;
+}
+
+#endif
+
+/* End: bn_mp_sqrt.c */
+
+/* Start: bn_mp_sub.c */
+#include <tommath.h>
+#ifdef BN_MP_SUB_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* high level subtraction (handles signs) */
+int
+mp_sub (mp_int * a, mp_int * b, mp_int * c)
+{
+  int     sa, sb, res;
+
+  sa = a->sign;
+  sb = b->sign;
+
+  if (sa != sb) {
+    /* subtract a negative from a positive, OR */
+    /* subtract a positive from a negative. */
+    /* In either case, ADD their magnitudes, */
+    /* and use the sign of the first number. */
+    c->sign = sa;
+    res = s_mp_add (a, b, c);
+  } else {
+    /* subtract a positive from a positive, OR */
+    /* subtract a negative from a negative. */
+    /* First, take the difference between their */
+    /* magnitudes, then... */
+    if (mp_cmp_mag (a, b) != MP_LT) {
+      /* Copy the sign from the first */
+      c->sign = sa;
+      /* The first has a larger or equal magnitude */
+      res = s_mp_sub (a, b, c);
+    } else {
+      /* The result has the *opposite* sign from */
+      /* the first number. */
+      c->sign = (sa == MP_ZPOS) ? MP_NEG : MP_ZPOS;
+      /* The second has a larger magnitude */
+      res = s_mp_sub (b, a, c);
+    }
+  }
+  return res;
+}
+
+#endif
+
+/* End: bn_mp_sub.c */
+
+/* Start: bn_mp_sub_d.c */
+#include <tommath.h>
+#ifdef BN_MP_SUB_D_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* single digit subtraction */
+int
+mp_sub_d (mp_int * a, mp_digit b, mp_int * c)
+{
+  mp_digit *tmpa, *tmpc, mu;
+  int       res, ix, oldused;
+
+  /* grow c as required */
+  if (c->alloc < a->used + 1) {
+     if ((res = mp_grow(c, a->used + 1)) != MP_OKAY) {
+        return res;
+     }
+  }
+
+  /* if a is negative just do an unsigned
+   * addition [with fudged signs]
+   */
+  if (a->sign == MP_NEG) {
+     a->sign = MP_ZPOS;
+     res     = mp_add_d(a, b, c);
+     a->sign = c->sign = MP_NEG;
+
+     /* clamp */
+     mp_clamp(c);
+
+     return res;
+  }
+
+  /* setup regs */
+  oldused = c->used;
+  tmpa    = a->dp;
+  tmpc    = c->dp;
+
+  /* if a <= b simply fix the single digit */
+  if ((a->used == 1 && a->dp[0] <= b) || a->used == 0) {
+     if (a->used == 1) {
+        *tmpc++ = b - *tmpa;
+     } else {
+        *tmpc++ = b;
+     }
+     ix      = 1;
+
+     /* negative/1digit */
+     c->sign = MP_NEG;
+     c->used = 1;
+  } else {
+     /* positive/size */
+     c->sign = MP_ZPOS;
+     c->used = a->used;
+
+     /* subtract first digit */
+     *tmpc    = *tmpa++ - b;
+     mu       = *tmpc >> (sizeof(mp_digit) * CHAR_BIT - 1);
+     *tmpc++ &= MP_MASK;
+
+     /* handle rest of the digits */
+     for (ix = 1; ix < a->used; ix++) {
+        *tmpc    = *tmpa++ - mu;
+        mu       = *tmpc >> (sizeof(mp_digit) * CHAR_BIT - 1);
+        *tmpc++ &= MP_MASK;
+     }
+  }
+
+  /* zero excess digits */
+  while (ix++ < oldused) {
+     *tmpc++ = 0;
+  }
+  mp_clamp(c);
+  return MP_OKAY;
+}
+
+#endif
+
+/* End: bn_mp_sub_d.c */
+
+/* Start: bn_mp_submod.c */
+#include <tommath.h>
+#ifdef BN_MP_SUBMOD_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* d = a - b (mod c) */
+int
+mp_submod (mp_int * a, mp_int * b, mp_int * c, mp_int * d)
+{
+  int     res;
+  mp_int  t;
+
+
+  if ((res = mp_init (&t)) != MP_OKAY) {
+    return res;
+  }
+
+  if ((res = mp_sub (a, b, &t)) != MP_OKAY) {
+    mp_clear (&t);
+    return res;
+  }
+  res = mp_mod (&t, c, d);
+  mp_clear (&t);
+  return res;
+}
+#endif
+
+/* End: bn_mp_submod.c */
+
+/* Start: bn_mp_to_signed_bin.c */
+#include <tommath.h>
+#ifdef BN_MP_TO_SIGNED_BIN_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* store in signed [big endian] format */
+int mp_to_signed_bin (mp_int * a, unsigned char *b)
+{
+  int     res;
+
+  if ((res = mp_to_unsigned_bin (a, b + 1)) != MP_OKAY) {
+    return res;
+  }
+  b[0] = (unsigned char) ((a->sign == MP_ZPOS) ? 0 : 1);
+  return MP_OKAY;
+}
+#endif
+
+/* End: bn_mp_to_signed_bin.c */
+
+/* Start: bn_mp_to_signed_bin_n.c */
+#include <tommath.h>
+#ifdef BN_MP_TO_SIGNED_BIN_N_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* store in signed [big endian] format */
+int mp_to_signed_bin_n (mp_int * a, unsigned char *b, unsigned long *outlen)
+{
+   if (*outlen < (unsigned long)mp_signed_bin_size(a)) {
+      return MP_VAL;
+   }
+   *outlen = mp_signed_bin_size(a);
+   return mp_to_signed_bin(a, b);
+}
+#endif
+
+/* End: bn_mp_to_signed_bin_n.c */
+
+/* Start: bn_mp_to_unsigned_bin.c */
+#include <tommath.h>
+#ifdef BN_MP_TO_UNSIGNED_BIN_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* store in unsigned [big endian] format */
+int mp_to_unsigned_bin (mp_int * a, unsigned char *b)
+{
+  int     x, res;
+  mp_int  t;
+
+  if ((res = mp_init_copy (&t, a)) != MP_OKAY) {
+    return res;
+  }
+
+  x = 0;
+  while (mp_iszero (&t) == 0) {
+#ifndef MP_8BIT
+      b[x++] = (unsigned char) (t.dp[0] & 255);
+#else
+      b[x++] = (unsigned char) (t.dp[0] | ((t.dp[1] & 0x01) << 7));
+#endif
+    if ((res = mp_div_2d (&t, 8, &t, NULL)) != MP_OKAY) {
+      mp_clear (&t);
+      return res;
+    }
+  }
+  bn_reverse (b, x);
+  mp_clear (&t);
+  return MP_OKAY;
+}
+#endif
+
+/* End: bn_mp_to_unsigned_bin.c */
+
+/* Start: bn_mp_to_unsigned_bin_n.c */
+#include <tommath.h>
+#ifdef BN_MP_TO_UNSIGNED_BIN_N_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* store in unsigned [big endian] format */
+int mp_to_unsigned_bin_n (mp_int * a, unsigned char *b, unsigned long *outlen)
+{
+   if (*outlen < (unsigned long)mp_unsigned_bin_size(a)) {
+      return MP_VAL;
+   }
+   *outlen = mp_unsigned_bin_size(a);
+   return mp_to_unsigned_bin(a, b);
+}
+#endif
+
+/* End: bn_mp_to_unsigned_bin_n.c */
+
+/* Start: bn_mp_toom_mul.c */
+#include <tommath.h>
+#ifdef BN_MP_TOOM_MUL_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* multiplication using the Toom-Cook 3-way algorithm 
+ *
+ * Much more complicated than Karatsuba but has a lower 
+ * asymptotic running time of O(N**1.464).  This algorithm is 
+ * only particularly useful on VERY large inputs 
+ * (we're talking 1000s of digits here...).
+*/
+int mp_toom_mul(mp_int *a, mp_int *b, mp_int *c)
+{
+    mp_int w0, w1, w2, w3, w4, tmp1, tmp2, a0, a1, a2, b0, b1, b2;
+    int res, B;
+        
+    /* init temps */
+    if ((res = mp_init_multi(&w0, &w1, &w2, &w3, &w4, 
+                             &a0, &a1, &a2, &b0, &b1, 
+                             &b2, &tmp1, &tmp2, NULL)) != MP_OKAY) {
+       return res;
+    }
+    
+    /* B */
+    B = MIN(a->used, b->used) / 3;
+    
+    /* a = a2 * B**2 + a1 * B + a0 */
+    if ((res = mp_mod_2d(a, DIGIT_BIT * B, &a0)) != MP_OKAY) {
+       goto ERR;
+    }
+
+    if ((res = mp_copy(a, &a1)) != MP_OKAY) {
+       goto ERR;
+    }
+    mp_rshd(&a1, B);
+    mp_mod_2d(&a1, DIGIT_BIT * B, &a1);
+
+    if ((res = mp_copy(a, &a2)) != MP_OKAY) {
+       goto ERR;
+    }
+    mp_rshd(&a2, B*2);
+    
+    /* b = b2 * B**2 + b1 * B + b0 */
+    if ((res = mp_mod_2d(b, DIGIT_BIT * B, &b0)) != MP_OKAY) {
+       goto ERR;
+    }
+
+    if ((res = mp_copy(b, &b1)) != MP_OKAY) {
+       goto ERR;
+    }
+    mp_rshd(&b1, B);
+    mp_mod_2d(&b1, DIGIT_BIT * B, &b1);
+
+    if ((res = mp_copy(b, &b2)) != MP_OKAY) {
+       goto ERR;
+    }
+    mp_rshd(&b2, B*2);
+    
+    /* w0 = a0*b0 */
+    if ((res = mp_mul(&a0, &b0, &w0)) != MP_OKAY) {
+       goto ERR;
+    }
+    
+    /* w4 = a2 * b2 */
+    if ((res = mp_mul(&a2, &b2, &w4)) != MP_OKAY) {
+       goto ERR;
+    }
+    
+    /* w1 = (a2 + 2(a1 + 2a0))(b2 + 2(b1 + 2b0)) */
+    if ((res = mp_mul_2(&a0, &tmp1)) != MP_OKAY) {
+       goto ERR;
+    }
+    if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) {
+       goto ERR;
+    }
+    if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) {
+       goto ERR;
+    }
+    if ((res = mp_add(&tmp1, &a2, &tmp1)) != MP_OKAY) {
+       goto ERR;
+    }
+    
+    if ((res = mp_mul_2(&b0, &tmp2)) != MP_OKAY) {
+       goto ERR;
+    }
+    if ((res = mp_add(&tmp2, &b1, &tmp2)) != MP_OKAY) {
+       goto ERR;
+    }
+    if ((res = mp_mul_2(&tmp2, &tmp2)) != MP_OKAY) {
+       goto ERR;
+    }
+    if ((res = mp_add(&tmp2, &b2, &tmp2)) != MP_OKAY) {
+       goto ERR;
+    }
+    
+    if ((res = mp_mul(&tmp1, &tmp2, &w1)) != MP_OKAY) {
+       goto ERR;
+    }
+    
+    /* w3 = (a0 + 2(a1 + 2a2))(b0 + 2(b1 + 2b2)) */
+    if ((res = mp_mul_2(&a2, &tmp1)) != MP_OKAY) {
+       goto ERR;
+    }
+    if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) {
+       goto ERR;
+    }
+    if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) {
+       goto ERR;
+    }
+    if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) {
+       goto ERR;
+    }
+    
+    if ((res = mp_mul_2(&b2, &tmp2)) != MP_OKAY) {
+       goto ERR;
+    }
+    if ((res = mp_add(&tmp2, &b1, &tmp2)) != MP_OKAY) {
+       goto ERR;
+    }
+    if ((res = mp_mul_2(&tmp2, &tmp2)) != MP_OKAY) {
+       goto ERR;
+    }
+    if ((res = mp_add(&tmp2, &b0, &tmp2)) != MP_OKAY) {
+       goto ERR;
+    }
+    
+    if ((res = mp_mul(&tmp1, &tmp2, &w3)) != MP_OKAY) {
+       goto ERR;
+    }
+    
+
+    /* w2 = (a2 + a1 + a0)(b2 + b1 + b0) */
+    if ((res = mp_add(&a2, &a1, &tmp1)) != MP_OKAY) {
+       goto ERR;
+    }
+    if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) {
+       goto ERR;
+    }
+    if ((res = mp_add(&b2, &b1, &tmp2)) != MP_OKAY) {
+       goto ERR;
+    }
+    if ((res = mp_add(&tmp2, &b0, &tmp2)) != MP_OKAY) {
+       goto ERR;
+    }
+    if ((res = mp_mul(&tmp1, &tmp2, &w2)) != MP_OKAY) {
+       goto ERR;
+    }
+    
+    /* now solve the matrix 
+    
+       0  0  0  0  1
+       1  2  4  8  16
+       1  1  1  1  1
+       16 8  4  2  1
+       1  0  0  0  0
+       
+       using 12 subtractions, 4 shifts, 
+              2 small divisions and 1 small multiplication 
+     */
+     
+     /* r1 - r4 */
+     if ((res = mp_sub(&w1, &w4, &w1)) != MP_OKAY) {
+        goto ERR;
+     }
+     /* r3 - r0 */
+     if ((res = mp_sub(&w3, &w0, &w3)) != MP_OKAY) {
+        goto ERR;
+     }
+     /* r1/2 */
+     if ((res = mp_div_2(&w1, &w1)) != MP_OKAY) {
+        goto ERR;
+     }
+     /* r3/2 */
+     if ((res = mp_div_2(&w3, &w3)) != MP_OKAY) {
+        goto ERR;
+     }
+     /* r2 - r0 - r4 */
+     if ((res = mp_sub(&w2, &w0, &w2)) != MP_OKAY) {
+        goto ERR;
+     }
+     if ((res = mp_sub(&w2, &w4, &w2)) != MP_OKAY) {
+        goto ERR;
+     }
+     /* r1 - r2 */
+     if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) {
+        goto ERR;
+     }
+     /* r3 - r2 */
+     if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) {
+        goto ERR;
+     }
+     /* r1 - 8r0 */
+     if ((res = mp_mul_2d(&w0, 3, &tmp1)) != MP_OKAY) {
+        goto ERR;
+     }
+     if ((res = mp_sub(&w1, &tmp1, &w1)) != MP_OKAY) {
+        goto ERR;
+     }
+     /* r3 - 8r4 */
+     if ((res = mp_mul_2d(&w4, 3, &tmp1)) != MP_OKAY) {
+        goto ERR;
+     }
+     if ((res = mp_sub(&w3, &tmp1, &w3)) != MP_OKAY) {
+        goto ERR;
+     }
+     /* 3r2 - r1 - r3 */
+     if ((res = mp_mul_d(&w2, 3, &w2)) != MP_OKAY) {
+        goto ERR;
+     }
+     if ((res = mp_sub(&w2, &w1, &w2)) != MP_OKAY) {
+        goto ERR;
+     }
+     if ((res = mp_sub(&w2, &w3, &w2)) != MP_OKAY) {
+        goto ERR;
+     }
+     /* r1 - r2 */
+     if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) {
+        goto ERR;
+     }
+     /* r3 - r2 */
+     if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) {
+        goto ERR;
+     }
+     /* r1/3 */
+     if ((res = mp_div_3(&w1, &w1, NULL)) != MP_OKAY) {
+        goto ERR;
+     }
+     /* r3/3 */
+     if ((res = mp_div_3(&w3, &w3, NULL)) != MP_OKAY) {
+        goto ERR;
+     }
+     
+     /* at this point shift W[n] by B*n */
+     if ((res = mp_lshd(&w1, 1*B)) != MP_OKAY) {
+        goto ERR;
+     }
+     if ((res = mp_lshd(&w2, 2*B)) != MP_OKAY) {
+        goto ERR;
+     }
+     if ((res = mp_lshd(&w3, 3*B)) != MP_OKAY) {
+        goto ERR;
+     }
+     if ((res = mp_lshd(&w4, 4*B)) != MP_OKAY) {
+        goto ERR;
+     }     
+     
+     if ((res = mp_add(&w0, &w1, c)) != MP_OKAY) {
+        goto ERR;
+     }
+     if ((res = mp_add(&w2, &w3, &tmp1)) != MP_OKAY) {
+        goto ERR;
+     }
+     if ((res = mp_add(&w4, &tmp1, &tmp1)) != MP_OKAY) {
+        goto ERR;
+     }
+     if ((res = mp_add(&tmp1, c, c)) != MP_OKAY) {
+        goto ERR;
+     }     
+     
+ERR:
+     mp_clear_multi(&w0, &w1, &w2, &w3, &w4, 
+                    &a0, &a1, &a2, &b0, &b1, 
+                    &b2, &tmp1, &tmp2, NULL);
+     return res;
+}     
+     
+#endif
+
+/* End: bn_mp_toom_mul.c */
+
+/* Start: bn_mp_toom_sqr.c */
+#include <tommath.h>
+#ifdef BN_MP_TOOM_SQR_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* squaring using Toom-Cook 3-way algorithm */
+int
+mp_toom_sqr(mp_int *a, mp_int *b)
+{
+    mp_int w0, w1, w2, w3, w4, tmp1, a0, a1, a2;
+    int res, B;
+
+    /* init temps */
+    if ((res = mp_init_multi(&w0, &w1, &w2, &w3, &w4, &a0, &a1, &a2, &tmp1, NULL)) != MP_OKAY) {
+       return res;
+    }
+
+    /* B */
+    B = a->used / 3;
+
+    /* a = a2 * B**2 + a1 * B + a0 */
+    if ((res = mp_mod_2d(a, DIGIT_BIT * B, &a0)) != MP_OKAY) {
+       goto ERR;
+    }
+
+    if ((res = mp_copy(a, &a1)) != MP_OKAY) {
+       goto ERR;
+    }
+    mp_rshd(&a1, B);
+    mp_mod_2d(&a1, DIGIT_BIT * B, &a1);
+
+    if ((res = mp_copy(a, &a2)) != MP_OKAY) {
+       goto ERR;
+    }
+    mp_rshd(&a2, B*2);
+
+    /* w0 = a0*a0 */
+    if ((res = mp_sqr(&a0, &w0)) != MP_OKAY) {
+       goto ERR;
+    }
+
+    /* w4 = a2 * a2 */
+    if ((res = mp_sqr(&a2, &w4)) != MP_OKAY) {
+       goto ERR;
+    }
+
+    /* w1 = (a2 + 2(a1 + 2a0))**2 */
+    if ((res = mp_mul_2(&a0, &tmp1)) != MP_OKAY) {
+       goto ERR;
+    }
+    if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) {
+       goto ERR;
+    }
+    if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) {
+       goto ERR;
+    }
+    if ((res = mp_add(&tmp1, &a2, &tmp1)) != MP_OKAY) {
+       goto ERR;
+    }
+
+    if ((res = mp_sqr(&tmp1, &w1)) != MP_OKAY) {
+       goto ERR;
+    }
+
+    /* w3 = (a0 + 2(a1 + 2a2))**2 */
+    if ((res = mp_mul_2(&a2, &tmp1)) != MP_OKAY) {
+       goto ERR;
+    }
+    if ((res = mp_add(&tmp1, &a1, &tmp1)) != MP_OKAY) {
+       goto ERR;
+    }
+    if ((res = mp_mul_2(&tmp1, &tmp1)) != MP_OKAY) {
+       goto ERR;
+    }
+    if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) {
+       goto ERR;
+    }
+
+    if ((res = mp_sqr(&tmp1, &w3)) != MP_OKAY) {
+       goto ERR;
+    }
+
+
+    /* w2 = (a2 + a1 + a0)**2 */
+    if ((res = mp_add(&a2, &a1, &tmp1)) != MP_OKAY) {
+       goto ERR;
+    }
+    if ((res = mp_add(&tmp1, &a0, &tmp1)) != MP_OKAY) {
+       goto ERR;
+    }
+    if ((res = mp_sqr(&tmp1, &w2)) != MP_OKAY) {
+       goto ERR;
+    }
+
+    /* now solve the matrix
+
+       0  0  0  0  1
+       1  2  4  8  16
+       1  1  1  1  1
+       16 8  4  2  1
+       1  0  0  0  0
+
+       using 12 subtractions, 4 shifts, 2 small divisions and 1 small multiplication.
+     */
+
+     /* r1 - r4 */
+     if ((res = mp_sub(&w1, &w4, &w1)) != MP_OKAY) {
+        goto ERR;
+     }
+     /* r3 - r0 */
+     if ((res = mp_sub(&w3, &w0, &w3)) != MP_OKAY) {
+        goto ERR;
+     }
+     /* r1/2 */
+     if ((res = mp_div_2(&w1, &w1)) != MP_OKAY) {
+        goto ERR;
+     }
+     /* r3/2 */
+     if ((res = mp_div_2(&w3, &w3)) != MP_OKAY) {
+        goto ERR;
+     }
+     /* r2 - r0 - r4 */
+     if ((res = mp_sub(&w2, &w0, &w2)) != MP_OKAY) {
+        goto ERR;
+     }
+     if ((res = mp_sub(&w2, &w4, &w2)) != MP_OKAY) {
+        goto ERR;
+     }
+     /* r1 - r2 */
+     if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) {
+        goto ERR;
+     }
+     /* r3 - r2 */
+     if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) {
+        goto ERR;
+     }
+     /* r1 - 8r0 */
+     if ((res = mp_mul_2d(&w0, 3, &tmp1)) != MP_OKAY) {
+        goto ERR;
+     }
+     if ((res = mp_sub(&w1, &tmp1, &w1)) != MP_OKAY) {
+        goto ERR;
+     }
+     /* r3 - 8r4 */
+     if ((res = mp_mul_2d(&w4, 3, &tmp1)) != MP_OKAY) {
+        goto ERR;
+     }
+     if ((res = mp_sub(&w3, &tmp1, &w3)) != MP_OKAY) {
+        goto ERR;
+     }
+     /* 3r2 - r1 - r3 */
+     if ((res = mp_mul_d(&w2, 3, &w2)) != MP_OKAY) {
+        goto ERR;
+     }
+     if ((res = mp_sub(&w2, &w1, &w2)) != MP_OKAY) {
+        goto ERR;
+     }
+     if ((res = mp_sub(&w2, &w3, &w2)) != MP_OKAY) {
+        goto ERR;
+     }
+     /* r1 - r2 */
+     if ((res = mp_sub(&w1, &w2, &w1)) != MP_OKAY) {
+        goto ERR;
+     }
+     /* r3 - r2 */
+     if ((res = mp_sub(&w3, &w2, &w3)) != MP_OKAY) {
+        goto ERR;
+     }
+     /* r1/3 */
+     if ((res = mp_div_3(&w1, &w1, NULL)) != MP_OKAY) {
+        goto ERR;
+     }
+     /* r3/3 */
+     if ((res = mp_div_3(&w3, &w3, NULL)) != MP_OKAY) {
+        goto ERR;
+     }
+
+     /* at this point shift W[n] by B*n */
+     if ((res = mp_lshd(&w1, 1*B)) != MP_OKAY) {
+        goto ERR;
+     }
+     if ((res = mp_lshd(&w2, 2*B)) != MP_OKAY) {
+        goto ERR;
+     }
+     if ((res = mp_lshd(&w3, 3*B)) != MP_OKAY) {
+        goto ERR;
+     }
+     if ((res = mp_lshd(&w4, 4*B)) != MP_OKAY) {
+        goto ERR;
+     }
+
+     if ((res = mp_add(&w0, &w1, b)) != MP_OKAY) {
+        goto ERR;
+     }
+     if ((res = mp_add(&w2, &w3, &tmp1)) != MP_OKAY) {
+        goto ERR;
+     }
+     if ((res = mp_add(&w4, &tmp1, &tmp1)) != MP_OKAY) {
+        goto ERR;
+     }
+     if ((res = mp_add(&tmp1, b, b)) != MP_OKAY) {
+        goto ERR;
+     }
+
+ERR:
+     mp_clear_multi(&w0, &w1, &w2, &w3, &w4, &a0, &a1, &a2, &tmp1, NULL);
+     return res;
+}
+
+#endif
+
+/* End: bn_mp_toom_sqr.c */
+
+/* Start: bn_mp_toradix.c */
+#include <tommath.h>
+#ifdef BN_MP_TORADIX_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* stores a bignum as a ASCII string in a given radix (2..64) */
+int mp_toradix (mp_int * a, char *str, int radix)
+{
+  int     res, digs;
+  mp_int  t;
+  mp_digit d;
+  char   *_s = str;
+
+  /* check range of the radix */
+  if (radix < 2 || radix > 64) {
+    return MP_VAL;
+  }
+
+  /* quick out if its zero */
+  if (mp_iszero(a) == 1) {
+     *str++ = '0';
+     *str = '\0';
+     return MP_OKAY;
+  }
+
+  if ((res = mp_init_copy (&t, a)) != MP_OKAY) {
+    return res;
+  }
+
+  /* if it is negative output a - */
+  if (t.sign == MP_NEG) {
+    ++_s;
+    *str++ = '-';
+    t.sign = MP_ZPOS;
+  }
+
+  digs = 0;
+  while (mp_iszero (&t) == 0) {
+    if ((res = mp_div_d (&t, (mp_digit) radix, &t, &d)) != MP_OKAY) {
+      mp_clear (&t);
+      return res;
+    }
+    *str++ = mp_s_rmap[d];
+    ++digs;
+  }
+
+  /* reverse the digits of the string.  In this case _s points
+   * to the first digit [exluding the sign] of the number]
+   */
+  bn_reverse ((unsigned char *)_s, digs);
+
+  /* append a NULL so the string is properly terminated */
+  *str = '\0';
+
+  mp_clear (&t);
+  return MP_OKAY;
+}
+
+#endif
+
+/* End: bn_mp_toradix.c */
+
+/* Start: bn_mp_toradix_n.c */
+#include <tommath.h>
+#ifdef BN_MP_TORADIX_N_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* stores a bignum as a ASCII string in a given radix (2..64) 
+ *
+ * Stores upto maxlen-1 chars and always a NULL byte 
+ */
+int mp_toradix_n(mp_int * a, char *str, int radix, int maxlen)
+{
+  int     res, digs;
+  mp_int  t;
+  mp_digit d;
+  char   *_s = str;
+
+  /* check range of the maxlen, radix */
+  if (maxlen < 2 || radix < 2 || radix > 64) {
+    return MP_VAL;
+  }
+
+  /* quick out if its zero */
+  if (mp_iszero(a) == MP_YES) {
+     *str++ = '0';
+     *str = '\0';
+     return MP_OKAY;
+  }
+
+  if ((res = mp_init_copy (&t, a)) != MP_OKAY) {
+    return res;
+  }
+
+  /* if it is negative output a - */
+  if (t.sign == MP_NEG) {
+    /* we have to reverse our digits later... but not the - sign!! */
+    ++_s;
+
+    /* store the flag and mark the number as positive */
+    *str++ = '-';
+    t.sign = MP_ZPOS;
+ 
+    /* subtract a char */
+    --maxlen;
+  }
+
+  digs = 0;
+  while (mp_iszero (&t) == 0) {
+    if (--maxlen < 1) {
+       /* no more room */
+       break;
+    }
+    if ((res = mp_div_d (&t, (mp_digit) radix, &t, &d)) != MP_OKAY) {
+      mp_clear (&t);
+      return res;
+    }
+    *str++ = mp_s_rmap[d];
+    ++digs;
+  }
+
+  /* reverse the digits of the string.  In this case _s points
+   * to the first digit [exluding the sign] of the number
+   */
+  bn_reverse ((unsigned char *)_s, digs);
+
+  /* append a NULL so the string is properly terminated */
+  *str = '\0';
+
+  mp_clear (&t);
+  return MP_OKAY;
+}
+
+#endif
+
+/* End: bn_mp_toradix_n.c */
+
+/* Start: bn_mp_unsigned_bin_size.c */
+#include <tommath.h>
+#ifdef BN_MP_UNSIGNED_BIN_SIZE_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* get the size for an unsigned equivalent */
+int mp_unsigned_bin_size (mp_int * a)
+{
+  int     size = mp_count_bits (a);
+  return (size / 8 + ((size & 7) != 0 ? 1 : 0));
+}
+#endif
+
+/* End: bn_mp_unsigned_bin_size.c */
+
+/* Start: bn_mp_xor.c */
+#include <tommath.h>
+#ifdef BN_MP_XOR_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* XOR two ints together */
+int
+mp_xor (mp_int * a, mp_int * b, mp_int * c)
+{
+  int     res, ix, px;
+  mp_int  t, *x;
+
+  if (a->used > b->used) {
+    if ((res = mp_init_copy (&t, a)) != MP_OKAY) {
+      return res;
+    }
+    px = b->used;
+    x = b;
+  } else {
+    if ((res = mp_init_copy (&t, b)) != MP_OKAY) {
+      return res;
+    }
+    px = a->used;
+    x = a;
+  }
+
+  for (ix = 0; ix < px; ix++) {
+     t.dp[ix] ^= x->dp[ix];
+  }
+  mp_clamp (&t);
+  mp_exch (c, &t);
+  mp_clear (&t);
+  return MP_OKAY;
+}
+#endif
+
+/* End: bn_mp_xor.c */
+
+/* Start: bn_mp_zero.c */
+#include <tommath.h>
+#ifdef BN_MP_ZERO_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* set to zero */
+void mp_zero (mp_int * a)
+{
+  int       n;
+  mp_digit *tmp;
+
+  a->sign = MP_ZPOS;
+  a->used = 0;
+
+  tmp = a->dp;
+  for (n = 0; n < a->alloc; n++) {
+     *tmp++ = 0;
+  }
+}
+#endif
+
+/* End: bn_mp_zero.c */
+
+/* Start: bn_prime_tab.c */
+#include <tommath.h>
+#ifdef BN_PRIME_TAB_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+const mp_digit ltm_prime_tab[] = {
+  0x0002, 0x0003, 0x0005, 0x0007, 0x000B, 0x000D, 0x0011, 0x0013,
+  0x0017, 0x001D, 0x001F, 0x0025, 0x0029, 0x002B, 0x002F, 0x0035,
+  0x003B, 0x003D, 0x0043, 0x0047, 0x0049, 0x004F, 0x0053, 0x0059,
+  0x0061, 0x0065, 0x0067, 0x006B, 0x006D, 0x0071, 0x007F,
+#ifndef MP_8BIT
+  0x0083,
+  0x0089, 0x008B, 0x0095, 0x0097, 0x009D, 0x00A3, 0x00A7, 0x00AD,
+  0x00B3, 0x00B5, 0x00BF, 0x00C1, 0x00C5, 0x00C7, 0x00D3, 0x00DF,
+  0x00E3, 0x00E5, 0x00E9, 0x00EF, 0x00F1, 0x00FB, 0x0101, 0x0107,
+  0x010D, 0x010F, 0x0115, 0x0119, 0x011B, 0x0125, 0x0133, 0x0137,
+
+  0x0139, 0x013D, 0x014B, 0x0151, 0x015B, 0x015D, 0x0161, 0x0167,
+  0x016F, 0x0175, 0x017B, 0x017F, 0x0185, 0x018D, 0x0191, 0x0199,
+  0x01A3, 0x01A5, 0x01AF, 0x01B1, 0x01B7, 0x01BB, 0x01C1, 0x01C9,
+  0x01CD, 0x01CF, 0x01D3, 0x01DF, 0x01E7, 0x01EB, 0x01F3, 0x01F7,
+  0x01FD, 0x0209, 0x020B, 0x021D, 0x0223, 0x022D, 0x0233, 0x0239,
+  0x023B, 0x0241, 0x024B, 0x0251, 0x0257, 0x0259, 0x025F, 0x0265,
+  0x0269, 0x026B, 0x0277, 0x0281, 0x0283, 0x0287, 0x028D, 0x0293,
+  0x0295, 0x02A1, 0x02A5, 0x02AB, 0x02B3, 0x02BD, 0x02C5, 0x02CF,
+
+  0x02D7, 0x02DD, 0x02E3, 0x02E7, 0x02EF, 0x02F5, 0x02F9, 0x0301,
+  0x0305, 0x0313, 0x031D, 0x0329, 0x032B, 0x0335, 0x0337, 0x033B,
+  0x033D, 0x0347, 0x0355, 0x0359, 0x035B, 0x035F, 0x036D, 0x0371,
+  0x0373, 0x0377, 0x038B, 0x038F, 0x0397, 0x03A1, 0x03A9, 0x03AD,
+  0x03B3, 0x03B9, 0x03C7, 0x03CB, 0x03D1, 0x03D7, 0x03DF, 0x03E5,
+  0x03F1, 0x03F5, 0x03FB, 0x03FD, 0x0407, 0x0409, 0x040F, 0x0419,
+  0x041B, 0x0425, 0x0427, 0x042D, 0x043F, 0x0443, 0x0445, 0x0449,
+  0x044F, 0x0455, 0x045D, 0x0463, 0x0469, 0x047F, 0x0481, 0x048B,
+
+  0x0493, 0x049D, 0x04A3, 0x04A9, 0x04B1, 0x04BD, 0x04C1, 0x04C7,
+  0x04CD, 0x04CF, 0x04D5, 0x04E1, 0x04EB, 0x04FD, 0x04FF, 0x0503,
+  0x0509, 0x050B, 0x0511, 0x0515, 0x0517, 0x051B, 0x0527, 0x0529,
+  0x052F, 0x0551, 0x0557, 0x055D, 0x0565, 0x0577, 0x0581, 0x058F,
+  0x0593, 0x0595, 0x0599, 0x059F, 0x05A7, 0x05AB, 0x05AD, 0x05B3,
+  0x05BF, 0x05C9, 0x05CB, 0x05CF, 0x05D1, 0x05D5, 0x05DB, 0x05E7,
+  0x05F3, 0x05FB, 0x0607, 0x060D, 0x0611, 0x0617, 0x061F, 0x0623,
+  0x062B, 0x062F, 0x063D, 0x0641, 0x0647, 0x0649, 0x064D, 0x0653
+#endif
+};
+#endif
+
+/* End: bn_prime_tab.c */
+
+/* Start: bn_reverse.c */
+#include <tommath.h>
+#ifdef BN_REVERSE_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* reverse an array, used for radix code */
+void
+bn_reverse (unsigned char *s, int len)
+{
+  int     ix, iy;
+  unsigned char t;
+
+  ix = 0;
+  iy = len - 1;
+  while (ix < iy) {
+    t     = s[ix];
+    s[ix] = s[iy];
+    s[iy] = t;
+    ++ix;
+    --iy;
+  }
+}
+#endif
+
+/* End: bn_reverse.c */
+
+/* Start: bn_s_mp_add.c */
+#include <tommath.h>
+#ifdef BN_S_MP_ADD_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* low level addition, based on HAC pp.594, Algorithm 14.7 */
+int
+s_mp_add (mp_int * a, mp_int * b, mp_int * c)
+{
+  mp_int *x;
+  int     olduse, res, min, max;
+
+  /* find sizes, we let |a| <= |b| which means we have to sort
+   * them.  "x" will point to the input with the most digits
+   */
+  if (a->used > b->used) {
+    min = b->used;
+    max = a->used;
+    x = a;
+  } else {
+    min = a->used;
+    max = b->used;
+    x = b;
+  }
+
+  /* init result */
+  if (c->alloc < max + 1) {
+    if ((res = mp_grow (c, max + 1)) != MP_OKAY) {
+      return res;
+    }
+  }
+
+  /* get old used digit count and set new one */
+  olduse = c->used;
+  c->used = max + 1;
+
+  {
+    register mp_digit u, *tmpa, *tmpb, *tmpc;
+    register int i;
+
+    /* alias for digit pointers */
+
+    /* first input */
+    tmpa = a->dp;
+
+    /* second input */
+    tmpb = b->dp;
+
+    /* destination */
+    tmpc = c->dp;
+
+    /* zero the carry */
+    u = 0;
+    for (i = 0; i < min; i++) {
+      /* Compute the sum at one digit, T[i] = A[i] + B[i] + U */
+      *tmpc = *tmpa++ + *tmpb++ + u;
+
+      /* U = carry bit of T[i] */
+      u = *tmpc >> ((mp_digit)DIGIT_BIT);
+
+      /* take away carry bit from T[i] */
+      *tmpc++ &= MP_MASK;
+    }
+
+    /* now copy higher words if any, that is in A+B 
+     * if A or B has more digits add those in 
+     */
+    if (min != max) {
+      for (; i < max; i++) {
+        /* T[i] = X[i] + U */
+        *tmpc = x->dp[i] + u;
+
+        /* U = carry bit of T[i] */
+        u = *tmpc >> ((mp_digit)DIGIT_BIT);
+
+        /* take away carry bit from T[i] */
+        *tmpc++ &= MP_MASK;
+      }
+    }
+
+    /* add carry */
+    *tmpc++ = u;
+
+    /* clear digits above oldused */
+    for (i = c->used; i < olduse; i++) {
+      *tmpc++ = 0;
+    }
+  }
+
+  mp_clamp (c);
+  return MP_OKAY;
+}
+#endif
+
+/* End: bn_s_mp_add.c */
+
+/* Start: bn_s_mp_exptmod.c */
+#include <tommath.h>
+#ifdef BN_S_MP_EXPTMOD_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+#ifdef MP_LOW_MEM
+   #define TAB_SIZE 32
+#else
+   #define TAB_SIZE 256
+#endif
+
+int s_mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int redmode)
+{
+  mp_int  M[TAB_SIZE], res, mu;
+  mp_digit buf;
+  int     err, bitbuf, bitcpy, bitcnt, mode, digidx, x, y, winsize;
+  int (*redux)(mp_int*,mp_int*,mp_int*);
+
+  /* find window size */
+  x = mp_count_bits (X);
+  if (x <= 7) {
+    winsize = 2;
+  } else if (x <= 36) {
+    winsize = 3;
+  } else if (x <= 140) {
+    winsize = 4;
+  } else if (x <= 450) {
+    winsize = 5;
+  } else if (x <= 1303) {
+    winsize = 6;
+  } else if (x <= 3529) {
+    winsize = 7;
+  } else {
+    winsize = 8;
+  }
+
+#ifdef MP_LOW_MEM
+    if (winsize > 5) {
+       winsize = 5;
+    }
+#endif
+
+  /* init M array */
+  /* init first cell */
+  if ((err = mp_init(&M[1])) != MP_OKAY) {
+     return err; 
+  }
+
+  /* now init the second half of the array */
+  for (x = 1<<(winsize-1); x < (1 << winsize); x++) {
+    if ((err = mp_init(&M[x])) != MP_OKAY) {
+      for (y = 1<<(winsize-1); y < x; y++) {
+        mp_clear (&M[y]);
+      }
+      mp_clear(&M[1]);
+      return err;
+    }
+  }
+
+  /* create mu, used for Barrett reduction */
+  if ((err = mp_init (&mu)) != MP_OKAY) {
+    goto LBL_M;
+  }
+  
+  if (redmode == 0) {
+     if ((err = mp_reduce_setup (&mu, P)) != MP_OKAY) {
+        goto LBL_MU;
+     }
+     redux = mp_reduce;
+  } else {
+     if ((err = mp_reduce_2k_setup_l (P, &mu)) != MP_OKAY) {
+        goto LBL_MU;
+     }
+     redux = mp_reduce_2k_l;
+  }    
+
+  /* create M table
+   *
+   * The M table contains powers of the base, 
+   * e.g. M[x] = G**x mod P
+   *
+   * The first half of the table is not 
+   * computed though accept for M[0] and M[1]
+   */
+  if ((err = mp_mod (G, P, &M[1])) != MP_OKAY) {
+    goto LBL_MU;
+  }
+
+  /* compute the value at M[1<<(winsize-1)] by squaring 
+   * M[1] (winsize-1) times 
+   */
+  if ((err = mp_copy (&M[1], &M[1 << (winsize - 1)])) != MP_OKAY) {
+    goto LBL_MU;
+  }
+
+  for (x = 0; x < (winsize - 1); x++) {
+    /* square it */
+    if ((err = mp_sqr (&M[1 << (winsize - 1)], 
+                       &M[1 << (winsize - 1)])) != MP_OKAY) {
+      goto LBL_MU;
+    }
+
+    /* reduce modulo P */
+    if ((err = redux (&M[1 << (winsize - 1)], P, &mu)) != MP_OKAY) {
+      goto LBL_MU;
+    }
+  }
+
+  /* create upper table, that is M[x] = M[x-1] * M[1] (mod P)
+   * for x = (2**(winsize - 1) + 1) to (2**winsize - 1)
+   */
+  for (x = (1 << (winsize - 1)) + 1; x < (1 << winsize); x++) {
+    if ((err = mp_mul (&M[x - 1], &M[1], &M[x])) != MP_OKAY) {
+      goto LBL_MU;
+    }
+    if ((err = redux (&M[x], P, &mu)) != MP_OKAY) {
+      goto LBL_MU;
+    }
+  }
+
+  /* setup result */
+  if ((err = mp_init (&res)) != MP_OKAY) {
+    goto LBL_MU;
+  }
+  mp_set (&res, 1);
+
+  /* set initial mode and bit cnt */
+  mode   = 0;
+  bitcnt = 1;
+  buf    = 0;
+  digidx = X->used - 1;
+  bitcpy = 0;
+  bitbuf = 0;
+
+  for (;;) {
+    /* grab next digit as required */
+    if (--bitcnt == 0) {
+      /* if digidx == -1 we are out of digits */
+      if (digidx == -1) {
+        break;
+      }
+      /* read next digit and reset the bitcnt */
+      buf    = X->dp[digidx--];
+      bitcnt = (int) DIGIT_BIT;
+    }
+
+    /* grab the next msb from the exponent */
+    y     = (buf >> (mp_digit)(DIGIT_BIT - 1)) & 1;
+    buf <<= (mp_digit)1;
+
+    /* if the bit is zero and mode == 0 then we ignore it
+     * These represent the leading zero bits before the first 1 bit
+     * in the exponent.  Technically this opt is not required but it
+     * does lower the # of trivial squaring/reductions used
+     */
+    if (mode == 0 && y == 0) {
+      continue;
+    }
+
+    /* if the bit is zero and mode == 1 then we square */
+    if (mode == 1 && y == 0) {
+      if ((err = mp_sqr (&res, &res)) != MP_OKAY) {
+        goto LBL_RES;
+      }
+      if ((err = redux (&res, P, &mu)) != MP_OKAY) {
+        goto LBL_RES;
+      }
+      continue;
+    }
+
+    /* else we add it to the window */
+    bitbuf |= (y << (winsize - ++bitcpy));
+    mode    = 2;
+
+    if (bitcpy == winsize) {
+      /* ok window is filled so square as required and multiply  */
+      /* square first */
+      for (x = 0; x < winsize; x++) {
+        if ((err = mp_sqr (&res, &res)) != MP_OKAY) {
+          goto LBL_RES;
+        }
+        if ((err = redux (&res, P, &mu)) != MP_OKAY) {
+          goto LBL_RES;
+        }
+      }
+
+      /* then multiply */
+      if ((err = mp_mul (&res, &M[bitbuf], &res)) != MP_OKAY) {
+        goto LBL_RES;
+      }
+      if ((err = redux (&res, P, &mu)) != MP_OKAY) {
+        goto LBL_RES;
+      }
+
+      /* empty window and reset */
+      bitcpy = 0;
+      bitbuf = 0;
+      mode   = 1;
+    }
+  }
+
+  /* if bits remain then square/multiply */
+  if (mode == 2 && bitcpy > 0) {
+    /* square then multiply if the bit is set */
+    for (x = 0; x < bitcpy; x++) {
+      if ((err = mp_sqr (&res, &res)) != MP_OKAY) {
+        goto LBL_RES;
+      }
+      if ((err = redux (&res, P, &mu)) != MP_OKAY) {
+        goto LBL_RES;
+      }
+
+      bitbuf <<= 1;
+      if ((bitbuf & (1 << winsize)) != 0) {
+        /* then multiply */
+        if ((err = mp_mul (&res, &M[1], &res)) != MP_OKAY) {
+          goto LBL_RES;
+        }
+        if ((err = redux (&res, P, &mu)) != MP_OKAY) {
+          goto LBL_RES;
+        }
+      }
+    }
+  }
+
+  mp_exch (&res, Y);
+  err = MP_OKAY;
+LBL_RES:mp_clear (&res);
+LBL_MU:mp_clear (&mu);
+LBL_M:
+  mp_clear(&M[1]);
+  for (x = 1<<(winsize-1); x < (1 << winsize); x++) {
+    mp_clear (&M[x]);
+  }
+  return err;
+}
+#endif
+
+/* End: bn_s_mp_exptmod.c */
+
+/* Start: bn_s_mp_mul_digs.c */
+#include <tommath.h>
+#ifdef BN_S_MP_MUL_DIGS_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* multiplies |a| * |b| and only computes upto digs digits of result
+ * HAC pp. 595, Algorithm 14.12  Modified so you can control how 
+ * many digits of output are created.
+ */
+int s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs)
+{
+  mp_int  t;
+  int     res, pa, pb, ix, iy;
+  mp_digit u;
+  mp_word r;
+  mp_digit tmpx, *tmpt, *tmpy;
+
+  /* can we use the fast multiplier? */
+  if (((digs) < MP_WARRAY) &&
+      MIN (a->used, b->used) < 
+          (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) {
+    return fast_s_mp_mul_digs (a, b, c, digs);
+  }
+
+  if ((res = mp_init_size (&t, digs)) != MP_OKAY) {
+    return res;
+  }
+  t.used = digs;
+
+  /* compute the digits of the product directly */
+  pa = a->used;
+  for (ix = 0; ix < pa; ix++) {
+    /* set the carry to zero */
+    u = 0;
+
+    /* limit ourselves to making digs digits of output */
+    pb = MIN (b->used, digs - ix);
+
+    /* setup some aliases */
+    /* copy of the digit from a used within the nested loop */
+    tmpx = a->dp[ix];
+    
+    /* an alias for the destination shifted ix places */
+    tmpt = t.dp + ix;
+    
+    /* an alias for the digits of b */
+    tmpy = b->dp;
+
+    /* compute the columns of the output and propagate the carry */
+    for (iy = 0; iy < pb; iy++) {
+      /* compute the column as a mp_word */
+      r       = ((mp_word)*tmpt) +
+                ((mp_word)tmpx) * ((mp_word)*tmpy++) +
+                ((mp_word) u);
+
+      /* the new column is the lower part of the result */
+      *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK));
+
+      /* get the carry word from the result */
+      u       = (mp_digit) (r >> ((mp_word) DIGIT_BIT));
+    }
+    /* set carry if it is placed below digs */
+    if (ix + iy < digs) {
+      *tmpt = u;
+    }
+  }
+
+  mp_clamp (&t);
+  mp_exch (&t, c);
+
+  mp_clear (&t);
+  return MP_OKAY;
+}
+#endif
+
+/* End: bn_s_mp_mul_digs.c */
+
+/* Start: bn_s_mp_mul_high_digs.c */
+#include <tommath.h>
+#ifdef BN_S_MP_MUL_HIGH_DIGS_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* multiplies |a| * |b| and does not compute the lower digs digits
+ * [meant to get the higher part of the product]
+ */
+int
+s_mp_mul_high_digs (mp_int * a, mp_int * b, mp_int * c, int digs)
+{
+  mp_int  t;
+  int     res, pa, pb, ix, iy;
+  mp_digit u;
+  mp_word r;
+  mp_digit tmpx, *tmpt, *tmpy;
+
+  /* can we use the fast multiplier? */
+#ifdef BN_FAST_S_MP_MUL_HIGH_DIGS_C
+  if (((a->used + b->used + 1) < MP_WARRAY)
+      && MIN (a->used, b->used) < (1 << ((CHAR_BIT * sizeof (mp_word)) - (2 * DIGIT_BIT)))) {
+    return fast_s_mp_mul_high_digs (a, b, c, digs);
+  }
+#endif
+
+  if ((res = mp_init_size (&t, a->used + b->used + 1)) != MP_OKAY) {
+    return res;
+  }
+  t.used = a->used + b->used + 1;
+
+  pa = a->used;
+  pb = b->used;
+  for (ix = 0; ix < pa; ix++) {
+    /* clear the carry */
+    u = 0;
+
+    /* left hand side of A[ix] * B[iy] */
+    tmpx = a->dp[ix];
+
+    /* alias to the address of where the digits will be stored */
+    tmpt = &(t.dp[digs]);
+
+    /* alias for where to read the right hand side from */
+    tmpy = b->dp + (digs - ix);
+
+    for (iy = digs - ix; iy < pb; iy++) {
+      /* calculate the double precision result */
+      r       = ((mp_word)*tmpt) +
+                ((mp_word)tmpx) * ((mp_word)*tmpy++) +
+                ((mp_word) u);
+
+      /* get the lower part */
+      *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK));
+
+      /* carry the carry */
+      u       = (mp_digit) (r >> ((mp_word) DIGIT_BIT));
+    }
+    *tmpt = u;
+  }
+  mp_clamp (&t);
+  mp_exch (&t, c);
+  mp_clear (&t);
+  return MP_OKAY;
+}
+#endif
+
+/* End: bn_s_mp_mul_high_digs.c */
+
+/* Start: bn_s_mp_sqr.c */
+#include <tommath.h>
+#ifdef BN_S_MP_SQR_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* low level squaring, b = a*a, HAC pp.596-597, Algorithm 14.16 */
+int s_mp_sqr (mp_int * a, mp_int * b)
+{
+  mp_int  t;
+  int     res, ix, iy, pa;
+  mp_word r;
+  mp_digit u, tmpx, *tmpt;
+
+  pa = a->used;
+  if ((res = mp_init_size (&t, 2*pa + 1)) != MP_OKAY) {
+    return res;
+  }
+
+  /* default used is maximum possible size */
+  t.used = 2*pa + 1;
+
+  for (ix = 0; ix < pa; ix++) {
+    /* first calculate the digit at 2*ix */
+    /* calculate double precision result */
+    r = ((mp_word) t.dp[2*ix]) +
+        ((mp_word)a->dp[ix])*((mp_word)a->dp[ix]);
+
+    /* store lower part in result */
+    t.dp[ix+ix] = (mp_digit) (r & ((mp_word) MP_MASK));
+
+    /* get the carry */
+    u           = (mp_digit)(r >> ((mp_word) DIGIT_BIT));
+
+    /* left hand side of A[ix] * A[iy] */
+    tmpx        = a->dp[ix];
+
+    /* alias for where to store the results */
+    tmpt        = t.dp + (2*ix + 1);
+    
+    for (iy = ix + 1; iy < pa; iy++) {
+      /* first calculate the product */
+      r       = ((mp_word)tmpx) * ((mp_word)a->dp[iy]);
+
+      /* now calculate the double precision result, note we use
+       * addition instead of *2 since it's easier to optimize
+       */
+      r       = ((mp_word) *tmpt) + r + r + ((mp_word) u);
+
+      /* store lower part */
+      *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK));
+
+      /* get carry */
+      u       = (mp_digit)(r >> ((mp_word) DIGIT_BIT));
+    }
+    /* propagate upwards */
+    while (u != ((mp_digit) 0)) {
+      r       = ((mp_word) *tmpt) + ((mp_word) u);
+      *tmpt++ = (mp_digit) (r & ((mp_word) MP_MASK));
+      u       = (mp_digit)(r >> ((mp_word) DIGIT_BIT));
+    }
+  }
+
+  mp_clamp (&t);
+  mp_exch (&t, b);
+  mp_clear (&t);
+  return MP_OKAY;
+}
+#endif
+
+/* End: bn_s_mp_sqr.c */
+
+/* Start: bn_s_mp_sub.c */
+#include <tommath.h>
+#ifdef BN_S_MP_SUB_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* low level subtraction (assumes |a| > |b|), HAC pp.595 Algorithm 14.9 */
+int
+s_mp_sub (mp_int * a, mp_int * b, mp_int * c)
+{
+  int     olduse, res, min, max;
+
+  /* find sizes */
+  min = b->used;
+  max = a->used;
+
+  /* init result */
+  if (c->alloc < max) {
+    if ((res = mp_grow (c, max)) != MP_OKAY) {
+      return res;
+    }
+  }
+  olduse = c->used;
+  c->used = max;
+
+  {
+    register mp_digit u, *tmpa, *tmpb, *tmpc;
+    register int i;
+
+    /* alias for digit pointers */
+    tmpa = a->dp;
+    tmpb = b->dp;
+    tmpc = c->dp;
+
+    /* set carry to zero */
+    u = 0;
+    for (i = 0; i < min; i++) {
+      /* T[i] = A[i] - B[i] - U */
+      *tmpc = *tmpa++ - *tmpb++ - u;
+
+      /* U = carry bit of T[i]
+       * Note this saves performing an AND operation since
+       * if a carry does occur it will propagate all the way to the
+       * MSB.  As a result a single shift is enough to get the carry
+       */
+      u = *tmpc >> ((mp_digit)(CHAR_BIT * sizeof (mp_digit) - 1));
+
+      /* Clear carry from T[i] */
+      *tmpc++ &= MP_MASK;
+    }
+
+    /* now copy higher words if any, e.g. if A has more digits than B  */
+    for (; i < max; i++) {
+      /* T[i] = A[i] - U */
+      *tmpc = *tmpa++ - u;
+
+      /* U = carry bit of T[i] */
+      u = *tmpc >> ((mp_digit)(CHAR_BIT * sizeof (mp_digit) - 1));
+
+      /* Clear carry from T[i] */
+      *tmpc++ &= MP_MASK;
+    }
+
+    /* clear digits above used (since we may not have grown result above) */
+    for (i = c->used; i < olduse; i++) {
+      *tmpc++ = 0;
+    }
+  }
+
+  mp_clamp (c);
+  return MP_OKAY;
+}
+
+#endif
+
+/* End: bn_s_mp_sub.c */
+
+/* Start: bncore.c */
+#include <tommath.h>
+#ifdef BNCORE_C
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+
+/* Known optimal configurations
+
+ CPU                    /Compiler     /MUL CUTOFF/SQR CUTOFF
+-------------------------------------------------------------
+ Intel P4 Northwood     /GCC v3.4.1   /        88/       128/LTM 0.32 ;-)
+ AMD Athlon64           /GCC v3.4.4   /        80/       120/LTM 0.35
+ 
+*/
+
+int     KARATSUBA_MUL_CUTOFF = 80,      /* Min. number of digits before Karatsuba multiplication is used. */
+        KARATSUBA_SQR_CUTOFF = 120,     /* Min. number of digits before Karatsuba squaring is used. */
+        
+        TOOM_MUL_CUTOFF      = 350,      /* no optimal values of these are known yet so set em high */
+        TOOM_SQR_CUTOFF      = 400; 
+#endif
+
+/* End: bncore.c */
+
+
+/* EOF */
diff --git a/libtommath/pretty.build b/libtommath/pretty.build
new file mode 100644
index 0000000..a708b8a
--- /dev/null
+++ b/libtommath/pretty.build
@@ -0,0 +1,66 @@
+#!/bin/perl -w
+#
+# Cute little builder for perl 
+# Total waste of development time...
+#
+# This will build all the object files and then the archive .a file
+# requires GCC, GNU make and a sense of humour.
+#
+# Tom St Denis
+use strict;
+
+my $count = 0;
+my $starttime = time;
+my $rate  = 0;
+print "Scanning for source files...\n";
+foreach my $filename (glob "*.c") {
+       ++$count;
+}
+print "Source files to build: $count\nBuilding...\n";
+my $i = 0;
+my $lines = 0;
+my $filesbuilt = 0;
+foreach my $filename (glob "*.c") {
+       printf("Building %3.2f%%, ", (++$i/$count)*100.0);
+       if ($i % 4 == 0) { print "/, "; }
+       if ($i % 4 == 1) { print "-, "; }
+       if ($i % 4 == 2) { print "\\, "; }
+       if ($i % 4 == 3) { print "|, "; }
+       if ($rate > 0) {
+           my $tleft = ($count - $i) / $rate;
+           my $tsec  = $tleft%60;
+           my $tmin  = ($tleft/60)%60;
+           my $thour = ($tleft/3600)%60;
+           printf("%2d:%02d:%02d left, ", $thour, $tmin, $tsec);
+       }
+       my $cnt = ($i/$count)*30.0;
+       my $x   = 0;
+       print "[";
+       for (; $x < $cnt; $x++) { print "#"; }
+       for (; $x < 30; $x++)   { print " "; }
+       print "]\r";
+       my $tmp = $filename;
+       $tmp =~ s/\.c/".o"/ge;
+       if (open(SRC, "<$tmp")) {
+          close SRC;
+       } else {
+          !system("make $tmp > /dev/null 2>/dev/null") or die "\nERROR: Failed to make $tmp!!!\n";
+          open( SRC, "<$filename" ) or die "Couldn't open $filename for reading: $!";
+          ++$lines while (<SRC>);
+          close SRC or die "Error closing $filename after reading: $!";
+          ++$filesbuilt;
+       }      
+
+       # update timer 
+       if (time != $starttime) {
+          my $delay = time - $starttime;
+          $rate = $i/$delay;
+       }
+}
+
+# finish building the library 
+printf("\nFinished building source (%d seconds, %3.2f files per second).\n", time - $starttime, $rate);
+print "Compiled approximately $filesbuilt files and $lines lines of code.\n";
+print "Doing final make (building archive...)\n";
+!system("make > /dev/null 2>/dev/null") or die "\nERROR: Failed to perform last make command!!!\n";
+print "done.\n";
\ No newline at end of file
diff --git a/libtommath/tombc/grammar.txt b/libtommath/tombc/grammar.txt
new file mode 100644
index 0000000..a780e75
--- /dev/null
+++ b/libtommath/tombc/grammar.txt
@@ -0,0 +1,35 @@
+program       := program statement | statement | empty
+statement     := { statement }                                                                              | 
+                 identifier = numexpression;                                                                | 
+                 identifier[numexpression] = numexpression;                                                 |
+                 function(expressionlist);                                                                  | 
+                 for (identifer = numexpression; numexpression; identifier = numexpression) { statement }   |
+                 while (numexpression) { statement }                                                        | 
+                 if (numexpresion) { statement } elif                                                       | 
+                 break;                                                                                     | 
+                 continue;                                                                                  
+                 
+elif          := else statement | empty
+function      := abs | countbits | exptmod | jacobi | print | isprime | nextprime | issquare | readinteger | exit
+expressionlist := expressionlist, expression | expression
+
+// LR(1) !!!?
+expression    := string | numexpression
+numexpression := cmpexpr && cmpexpr | cmpexpr \|\| cmpexpr | cmpexpr
+cmpexpr       := boolexpr  < boolexpr | boolexpr  > boolexpr | boolexpr == boolexpr | 
+                 boolexpr <= boolexpr | boolexpr >= boolexpr | boolexpr
+boolexpr      := shiftexpr & shiftexpr | shiftexpr ^ shiftexpr | shiftexpr \| shiftexpr | shiftexpr
+shiftexpr     := addsubexpr << addsubexpr | addsubexpr >> addsubexpr | addsubexpr
+addsubexpr    := mulexpr + mulexpr | mulexpr - mulexpr | mulexpr
+mulexpr       := expr * expr       | expr / expr | expr % expr | expr
+expr          := -nexpr | nexpr 
+nexpr         := integer | identifier | ( numexpression ) | identifier[numexpression] 
+
+identifier    := identifer digits | identifier alpha | alpha
+alpha         := a ... z | A ... Z
+integer       := hexnumber | digits 
+hexnumber     := 0xhexdigits
+hexdigits     := hexdigits hexdigit | hexdigit
+hexdigit      := 0 ... 9 | a ... f | A ... F
+digits        := digits digit | digit 
+digit         := 0 ... 9
diff --git a/libtommath/tommath.h b/libtommath/tommath.h
new file mode 100644
index 0000000..4b3a76f
--- /dev/null
+++ b/libtommath/tommath.h
@@ -0,0 +1,579 @@
+/* LibTomMath, multiple-precision integer library -- Tom St Denis
+ *
+ * LibTomMath is a library that provides multiple-precision
+ * integer arithmetic as well as number theoretic functionality.
+ *
+ * The library was designed directly after the MPI library by
+ * Michael Fromberger but has been written from scratch with
+ * additional optimizations in place.
+ *
+ * The library is free for all purposes without any express
+ * guarantee it works.
+ *
+ * Tom St Denis, tomstdenis@gmail.com, http://math.libtomcrypt.com
+ */
+#ifndef BN_H_
+#define BN_H_
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <limits.h>
+
+#include <tommath_class.h>
+
+#ifndef MIN
+#   define MIN(x,y) ((x)<(y)?(x):(y))
+#endif
+
+#ifndef MAX
+#   define MAX(x,y) ((x)>(y)?(x):(y))
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+
+/* C++ compilers don't like assigning void * to mp_digit * */
+#define  OPT_CAST(x)  (x *)
+
+#else
+
+/* C on the other hand doesn't care */
+#define  OPT_CAST(x)
+
+#endif
+
+
+/* detect 64-bit mode if possible */
+#if defined(__x86_64__) 
+#   if !(defined(MP_64BIT) && defined(MP_16BIT) && defined(MP_8BIT))
+#	define MP_64BIT
+#   endif
+#endif
+
+/* some default configurations.
+ *
+ * A "mp_digit" must be able to hold DIGIT_BIT + 1 bits
+ * A "mp_word" must be able to hold 2*DIGIT_BIT + 1 bits
+ *
+ * At the very least a mp_digit must be able to hold 7 bits
+ * [any size beyond that is ok provided it doesn't overflow the data type]
+ */
+#ifdef MP_8BIT
+   typedef unsigned char      mp_digit;
+   typedef unsigned short     mp_word;
+#elif defined(MP_16BIT)
+   typedef unsigned short     mp_digit;
+   typedef unsigned long      mp_word;
+#elif defined(MP_64BIT)
+   /* for GCC only on supported platforms */
+#ifndef CRYPT
+   typedef unsigned long long ulong64;
+   typedef signed long long   long64;
+#endif
+
+   typedef unsigned long      mp_digit;
+   typedef unsigned long      mp_word __attribute__ ((mode(TI)));
+
+#  define DIGIT_BIT          60
+#else
+   /* this is the default case, 28-bit digits */
+   
+   /* this is to make porting into LibTomCrypt easier :-) */
+#ifndef CRYPT
+#  if defined(_MSC_VER) || defined(__BORLANDC__)
+      typedef unsigned __int64   ulong64;
+      typedef signed __int64     long64;
+#  else
+      typedef unsigned long long ulong64;
+      typedef signed long long   long64;
+#  endif
+#endif
+
+   typedef unsigned long      mp_digit;
+   typedef ulong64            mp_word;
+
+#ifdef MP_31BIT   
+   /* this is an extension that uses 31-bit digits */
+#  define DIGIT_BIT          31
+#else
+   /* default case is 28-bit digits, defines MP_28BIT as a handy macro to test */
+#  define DIGIT_BIT          28
+#  define MP_28BIT
+#endif   
+#endif
+
+/* define heap macros */
+#ifndef CRYPT
+   /* default to libc stuff */
+#  ifndef XMALLOC
+#     define XMALLOC  malloc
+#     define XFREE    free
+#     define XREALLOC realloc
+#     define XCALLOC  calloc
+#  else
+      /* prototypes for our heap functions */
+      extern void *XMALLOC(size_t n);
+      extern void *XREALLOC(void *p, size_t n);
+      extern void *XCALLOC(size_t n, size_t s);
+      extern void XFREE(void *p);
+#  endif
+#endif
+
+
+/* otherwise the bits per digit is calculated automatically from the size of a mp_digit */
+#ifndef DIGIT_BIT
+#   define DIGIT_BIT     ((int)((CHAR_BIT * sizeof(mp_digit) - 1)))  /* bits per digit */
+#endif
+
+#define MP_DIGIT_BIT     DIGIT_BIT
+#define MP_MASK          ((((mp_digit)1)<<((mp_digit)DIGIT_BIT))-((mp_digit)1))
+#define MP_DIGIT_MAX     MP_MASK
+
+/* equalities */
+#define MP_LT        -1   /* less than */
+#define MP_EQ         0   /* equal to */
+#define MP_GT         1   /* greater than */
+
+#define MP_ZPOS       0   /* positive integer */
+#define MP_NEG        1   /* negative */
+
+#define MP_OKAY       0   /* ok result */
+#define MP_MEM        -2  /* out of mem */
+#define MP_VAL        -3  /* invalid input */
+#define MP_RANGE      MP_VAL
+
+#define MP_YES        1   /* yes response */
+#define MP_NO         0   /* no response */
+
+/* Primality generation flags */
+#define LTM_PRIME_BBS      0x0001 /* BBS style prime */
+#define LTM_PRIME_SAFE     0x0002 /* Safe prime (p-1)/2 == prime */
+#define LTM_PRIME_2MSB_ON  0x0008 /* force 2nd MSB to 1 */
+
+typedef int           mp_err;
+
+/* you'll have to tune these... */
+extern int KARATSUBA_MUL_CUTOFF,
+           KARATSUBA_SQR_CUTOFF,
+           TOOM_MUL_CUTOFF,
+           TOOM_SQR_CUTOFF;
+
+/* define this to use lower memory usage routines (exptmods mostly) */
+/* #define MP_LOW_MEM */
+
+/* default precision */
+#ifndef MP_PREC
+#  ifndef MP_LOW_MEM
+#     define MP_PREC                 32     /* default digits of precision */
+#  else
+#     define MP_PREC                 8      /* default digits of precision */
+#  endif
+#endif
+
+/* size of comba arrays, should be at least 2 * 2**(BITS_PER_WORD - BITS_PER_DIGIT*2) */
+#define MP_WARRAY               (1 << (sizeof(mp_word) * CHAR_BIT - 2 * DIGIT_BIT + 1))
+
+/* the infamous mp_int structure */
+typedef struct  {
+    int used, alloc, sign;
+    mp_digit *dp;
+} mp_int;
+
+/* callback for mp_prime_random, should fill dst with random bytes and return how many read [upto len] */
+typedef int ltm_prime_callback(unsigned char *dst, int len, void *dat);
+
+
+#define USED(m)    ((m)->used)
+#define DIGIT(m,k) ((m)->dp[(k)])
+#define SIGN(m)    ((m)->sign)
+
+/* error code to char* string */
+char *mp_error_to_string(int code);
+
+/* ---> init and deinit bignum functions <--- */
+/* init a bignum */
+int mp_init(mp_int *a);
+
+/* free a bignum */
+void mp_clear(mp_int *a);
+
+/* init a null terminated series of arguments */
+int mp_init_multi(mp_int *mp, ...);
+
+/* clear a null terminated series of arguments */
+void mp_clear_multi(mp_int *mp, ...);
+
+/* exchange two ints */
+void mp_exch(mp_int *a, mp_int *b);
+
+/* shrink ram required for a bignum */
+int mp_shrink(mp_int *a);
+
+/* grow an int to a given size */
+int mp_grow(mp_int *a, int size);
+
+/* init to a given number of digits */
+int mp_init_size(mp_int *a, int size);
+
+/* ---> Basic Manipulations <--- */
+#define mp_iszero(a) (((a)->used == 0) ? MP_YES : MP_NO)
+#define mp_iseven(a) (((a)->used == 0 || (((a)->dp[0] & 1) == 0)) ? MP_YES : MP_NO)
+#define mp_isodd(a)  (((a)->used > 0 && (((a)->dp[0] & 1) == 1)) ? MP_YES : MP_NO)
+
+/* set to zero */
+void mp_zero(mp_int *a);
+
+/* set to a digit */
+void mp_set(mp_int *a, mp_digit b);
+
+/* set a 32-bit const */
+int mp_set_int(mp_int *a, unsigned long b);
+
+/* get a 32-bit value */
+unsigned long mp_get_int(mp_int * a);
+
+/* initialize and set a digit */
+int mp_init_set (mp_int * a, mp_digit b);
+
+/* initialize and set 32-bit value */
+int mp_init_set_int (mp_int * a, unsigned long b);
+
+/* copy, b = a */
+int mp_copy(const mp_int *a, mp_int *b);
+
+/* inits and copies, a = b */
+int mp_init_copy(mp_int *a, mp_int *b);
+
+/* trim unused digits */
+void mp_clamp(mp_int *a);
+
+/* ---> digit manipulation <--- */
+
+/* right shift by "b" digits */
+void mp_rshd(mp_int *a, int b);
+
+/* left shift by "b" digits */
+int mp_lshd(mp_int *a, int b);
+
+/* c = a / 2**b */
+int mp_div_2d(const mp_int *a, int b, mp_int *c, mp_int *d);
+
+/* b = a/2 */
+int mp_div_2(mp_int *a, mp_int *b);
+
+/* c = a * 2**b */
+int mp_mul_2d(const mp_int *a, int b, mp_int *c);
+
+/* b = a*2 */
+int mp_mul_2(mp_int *a, mp_int *b);
+
+/* c = a mod 2**d */
+int mp_mod_2d(const mp_int *a, int b, mp_int *c);
+
+/* computes a = 2**b */
+int mp_2expt(mp_int *a, int b);
+
+/* Counts the number of lsbs which are zero before the first zero bit */
+int mp_cnt_lsb(mp_int *a);
+
+/* I Love Earth! */
+
+/* makes a pseudo-random int of a given size */
+int mp_rand(mp_int *a, int digits);
+
+/* ---> binary operations <--- */
+/* c = a XOR b  */
+int mp_xor(mp_int *a, mp_int *b, mp_int *c);
+
+/* c = a OR b */
+int mp_or(mp_int *a, mp_int *b, mp_int *c);
+
+/* c = a AND b */
+int mp_and(mp_int *a, mp_int *b, mp_int *c);
+
+/* ---> Basic arithmetic <--- */
+
+/* b = -a */
+int mp_neg(const mp_int *a, mp_int *b);
+
+/* b = |a| */
+int mp_abs(mp_int *a, mp_int *b);
+
+/* compare a to b */
+int mp_cmp(const mp_int *a, const mp_int *b);
+
+/* compare |a| to |b| */
+int mp_cmp_mag(const mp_int *a, const mp_int *b);
+
+/* c = a + b */
+int mp_add(mp_int *a, mp_int *b, mp_int *c);
+
+/* c = a - b */
+int mp_sub(mp_int *a, mp_int *b, mp_int *c);
+
+/* c = a * b */
+int mp_mul(mp_int *a, mp_int *b, mp_int *c);
+
+/* b = a*a  */
+int mp_sqr(mp_int *a, mp_int *b);
+
+/* a/b => cb + d == a */
+int mp_div(mp_int *a, mp_int *b, mp_int *c, mp_int *d);
+
+/* c = a mod b, 0 <= c < b  */
+int mp_mod(mp_int *a, mp_int *b, mp_int *c);
+
+/* ---> single digit functions <--- */
+
+/* compare against a single digit */
+int mp_cmp_d(const mp_int *a, mp_digit b);
+
+/* c = a + b */
+int mp_add_d(mp_int *a, mp_digit b, mp_int *c);
+
+/* c = a - b */
+int mp_sub_d(mp_int *a, mp_digit b, mp_int *c);
+
+/* c = a * b */
+int mp_mul_d(mp_int *a, mp_digit b, mp_int *c);
+
+/* a/b => cb + d == a */
+int mp_div_d(mp_int *a, mp_digit b, mp_int *c, mp_digit *d);
+
+/* a/3 => 3c + d == a */
+int mp_div_3(mp_int *a, mp_int *c, mp_digit *d);
+
+/* c = a**b */
+int mp_expt_d(mp_int *a, mp_digit b, mp_int *c);
+
+/* c = a mod b, 0 <= c < b  */
+int mp_mod_d(mp_int *a, mp_digit b, mp_digit *c);
+
+/* ---> number theory <--- */
+
+/* d = a + b (mod c) */
+int mp_addmod(mp_int *a, mp_int *b, mp_int *c, mp_int *d);
+
+/* d = a - b (mod c) */
+int mp_submod(mp_int *a, mp_int *b, mp_int *c, mp_int *d);
+
+/* d = a * b (mod c) */
+int mp_mulmod(mp_int *a, mp_int *b, mp_int *c, mp_int *d);
+
+/* c = a * a (mod b) */
+int mp_sqrmod(mp_int *a, mp_int *b, mp_int *c);
+
+/* c = 1/a (mod b) */
+int mp_invmod(mp_int *a, mp_int *b, mp_int *c);
+
+/* c = (a, b) */
+int mp_gcd(mp_int *a, mp_int *b, mp_int *c);
+
+/* produces value such that U1*a + U2*b = U3 */
+int mp_exteuclid(mp_int *a, mp_int *b, mp_int *U1, mp_int *U2, mp_int *U3);
+
+/* c = [a, b] or (a*b)/(a, b) */
+int mp_lcm(mp_int *a, mp_int *b, mp_int *c);
+
+/* finds one of the b'th root of a, such that |c|**b <= |a|
+ *
+ * returns error if a < 0 and b is even
+ */
+int mp_n_root(mp_int *a, mp_digit b, mp_int *c);
+
+/* special sqrt algo */
+int mp_sqrt(mp_int *arg, mp_int *ret);
+
+/* is number a square? */
+int mp_is_square(mp_int *arg, int *ret);
+
+/* computes the jacobi c = (a | n) (or Legendre if b is prime)  */
+int mp_jacobi(mp_int *a, mp_int *n, int *c);
+
+/* used to setup the Barrett reduction for a given modulus b */
+int mp_reduce_setup(mp_int *a, mp_int *b);
+
+/* Barrett Reduction, computes a (mod b) with a precomputed value c
+ *
+ * Assumes that 0 < a <= b*b, note if 0 > a > -(b*b) then you can merely
+ * compute the reduction as -1 * mp_reduce(mp_abs(a)) [pseudo code].
+ */
+int mp_reduce(mp_int *a, mp_int *b, mp_int *c);
+
+/* setups the montgomery reduction */
+int mp_montgomery_setup(mp_int *a, mp_digit *mp);
+
+/* computes a = B**n mod b without division or multiplication useful for
+ * normalizing numbers in a Montgomery system.
+ */
+int mp_montgomery_calc_normalization(mp_int *a, mp_int *b);
+
+/* computes x/R == x (mod N) via Montgomery Reduction */
+int mp_montgomery_reduce(mp_int *a, mp_int *m, mp_digit mp);
+
+/* returns 1 if a is a valid DR modulus */
+int mp_dr_is_modulus(mp_int *a);
+
+/* sets the value of "d" required for mp_dr_reduce */
+void mp_dr_setup(mp_int *a, mp_digit *d);
+
+/* reduces a modulo b using the Diminished Radix method */
+int mp_dr_reduce(mp_int *a, mp_int *b, mp_digit mp);
+
+/* returns true if a can be reduced with mp_reduce_2k */
+int mp_reduce_is_2k(mp_int *a);
+
+/* determines k value for 2k reduction */
+int mp_reduce_2k_setup(mp_int *a, mp_digit *d);
+
+/* reduces a modulo b where b is of the form 2**p - k [0 <= a] */
+int mp_reduce_2k(mp_int *a, mp_int *n, mp_digit d);
+
+/* returns true if a can be reduced with mp_reduce_2k_l */
+int mp_reduce_is_2k_l(mp_int *a);
+
+/* determines k value for 2k reduction */
+int mp_reduce_2k_setup_l(mp_int *a, mp_int *d);
+
+/* reduces a modulo b where b is of the form 2**p - k [0 <= a] */
+int mp_reduce_2k_l(mp_int *a, mp_int *n, mp_int *d);
+
+/* d = a**b (mod c) */
+int mp_exptmod(mp_int *a, mp_int *b, mp_int *c, mp_int *d);
+
+/* ---> Primes <--- */
+
+/* number of primes */
+#ifdef MP_8BIT
+#  define PRIME_SIZE      31
+#else
+#  define PRIME_SIZE      256
+#endif
+
+/* table of first PRIME_SIZE primes */
+extern const mp_digit ltm_prime_tab[];
+
+/* result=1 if a is divisible by one of the first PRIME_SIZE primes */
+int mp_prime_is_divisible(mp_int *a, int *result);
+
+/* performs one Fermat test of "a" using base "b".
+ * Sets result to 0 if composite or 1 if probable prime
+ */
+int mp_prime_fermat(mp_int *a, mp_int *b, int *result);
+
+/* performs one Miller-Rabin test of "a" using base "b".
+ * Sets result to 0 if composite or 1 if probable prime
+ */
+int mp_prime_miller_rabin(mp_int *a, mp_int *b, int *result);
+
+/* This gives [for a given bit size] the number of trials required
+ * such that Miller-Rabin gives a prob of failure lower than 2^-96 
+ */
+int mp_prime_rabin_miller_trials(int size);
+
+/* performs t rounds of Miller-Rabin on "a" using the first
+ * t prime bases.  Also performs an initial sieve of trial
+ * division.  Determines if "a" is prime with probability
+ * of error no more than (1/4)**t.
+ *
+ * Sets result to 1 if probably prime, 0 otherwise
+ */
+int mp_prime_is_prime(mp_int *a, int t, int *result);
+
+/* finds the next prime after the number "a" using "t" trials
+ * of Miller-Rabin.
+ *
+ * bbs_style = 1 means the prime must be congruent to 3 mod 4
+ */
+int mp_prime_next_prime(mp_int *a, int t, int bbs_style);
+
+/* makes a truly random prime of a given size (bytes),
+ * call with bbs = 1 if you want it to be congruent to 3 mod 4 
+ *
+ * You have to supply a callback which fills in a buffer with random bytes.  "dat" is a parameter you can
+ * have passed to the callback (e.g. a state or something).  This function doesn't use "dat" itself
+ * so it can be NULL
+ *
+ * The prime generated will be larger than 2^(8*size).
+ */
+#define mp_prime_random(a, t, size, bbs, cb, dat) mp_prime_random_ex(a, t, ((size) * 8) + 1, (bbs==1)?LTM_PRIME_BBS:0, cb, dat)
+
+/* makes a truly random prime of a given size (bits),
+ *
+ * Flags are as follows:
+ * 
+ *   LTM_PRIME_BBS      - make prime congruent to 3 mod 4
+ *   LTM_PRIME_SAFE     - make sure (p-1)/2 is prime as well (implies LTM_PRIME_BBS)
+ *   LTM_PRIME_2MSB_OFF - make the 2nd highest bit zero
+ *   LTM_PRIME_2MSB_ON  - make the 2nd highest bit one
+ *
+ * You have to supply a callback which fills in a buffer with random bytes.  "dat" is a parameter you can
+ * have passed to the callback (e.g. a state or something).  This function doesn't use "dat" itself
+ * so it can be NULL
+ *
+ */
+int mp_prime_random_ex(mp_int *a, int t, int size, int flags, ltm_prime_callback cb, void *dat);
+
+/* ---> radix conversion <--- */
+int mp_count_bits(const mp_int *a);
+
+int mp_unsigned_bin_size(mp_int *a);
+int mp_read_unsigned_bin(mp_int *a, const unsigned char *b, int c);
+int mp_to_unsigned_bin(mp_int *a, unsigned char *b);
+int mp_to_unsigned_bin_n (mp_int * a, unsigned char *b, unsigned long *outlen);
+
+int mp_signed_bin_size(mp_int *a);
+int mp_read_signed_bin(mp_int *a, const unsigned char *b, int c);
+int mp_to_signed_bin(mp_int *a,  unsigned char *b);
+int mp_to_signed_bin_n (mp_int * a, unsigned char *b, unsigned long *outlen);
+
+int mp_read_radix(mp_int *a, const char *str, int radix);
+int mp_toradix(mp_int *a, char *str, int radix);
+int mp_toradix_n(mp_int * a, char *str, int radix, int maxlen);
+int mp_radix_size(mp_int *a, int radix, int *size);
+
+int mp_fread(mp_int *a, int radix, FILE *stream);
+int mp_fwrite(mp_int *a, int radix, FILE *stream);
+
+#define mp_read_raw(mp, str, len) mp_read_signed_bin((mp), (str), (len))
+#define mp_raw_size(mp)           mp_signed_bin_size(mp)
+#define mp_toraw(mp, str)         mp_to_signed_bin((mp), (str))
+#define mp_read_mag(mp, str, len) mp_read_unsigned_bin((mp), (str), (len))
+#define mp_mag_size(mp)           mp_unsigned_bin_size(mp)
+#define mp_tomag(mp, str)         mp_to_unsigned_bin((mp), (str))
+
+#define mp_tobinary(M, S)  mp_toradix((M), (S), 2)
+#define mp_tooctal(M, S)   mp_toradix((M), (S), 8)
+#define mp_todecimal(M, S) mp_toradix((M), (S), 10)
+#define mp_tohex(M, S)     mp_toradix((M), (S), 16)
+
+/* lowlevel functions, do not call! */
+int s_mp_add(mp_int *a, mp_int *b, mp_int *c);
+int s_mp_sub(mp_int *a, mp_int *b, mp_int *c);
+#define s_mp_mul(a, b, c) s_mp_mul_digs(a, b, c, (a)->used + (b)->used + 1)
+int fast_s_mp_mul_digs(mp_int *a, mp_int *b, mp_int *c, int digs);
+int s_mp_mul_digs(mp_int *a, mp_int *b, mp_int *c, int digs);
+int fast_s_mp_mul_high_digs(mp_int *a, mp_int *b, mp_int *c, int digs);
+int s_mp_mul_high_digs(mp_int *a, mp_int *b, mp_int *c, int digs);
+int fast_s_mp_sqr(mp_int *a, mp_int *b);
+int s_mp_sqr(mp_int *a, mp_int *b);
+int mp_karatsuba_mul(mp_int *a, mp_int *b, mp_int *c);
+int mp_toom_mul(mp_int *a, mp_int *b, mp_int *c);
+int mp_karatsuba_sqr(mp_int *a, mp_int *b);
+int mp_toom_sqr(mp_int *a, mp_int *b);
+int fast_mp_invmod(mp_int *a, mp_int *b, mp_int *c);
+int mp_invmod_slow (mp_int * a, mp_int * b, mp_int * c);
+int fast_mp_montgomery_reduce(mp_int *a, mp_int *m, mp_digit mp);
+int mp_exptmod_fast(mp_int *G, mp_int *X, mp_int *P, mp_int *Y, int mode);
+int s_mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int mode);
+void bn_reverse(unsigned char *s, int len);
+
+extern const char *mp_s_rmap;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/libtommath/tommath.out b/libtommath/tommath.out
new file mode 100644
index 0000000..9f62617
--- /dev/null
+++ b/libtommath/tommath.out
@@ -0,0 +1,139 @@
+\BOOKMARK [0][-]{chapter.1}{Introduction}{}
+\BOOKMARK [1][-]{section.1.1}{Multiple Precision Arithmetic}{chapter.1}
+\BOOKMARK [2][-]{subsection.1.1.1}{What is Multiple Precision Arithmetic?}{section.1.1}
+\BOOKMARK [2][-]{subsection.1.1.2}{The Need for Multiple Precision Arithmetic}{section.1.1}
+\BOOKMARK [2][-]{subsection.1.1.3}{Benefits of Multiple Precision Arithmetic}{section.1.1}
+\BOOKMARK [1][-]{section.1.2}{Purpose of This Text}{chapter.1}
+\BOOKMARK [1][-]{section.1.3}{Discussion and Notation}{chapter.1}
+\BOOKMARK [2][-]{subsection.1.3.1}{Notation}{section.1.3}
+\BOOKMARK [2][-]{subsection.1.3.2}{Precision Notation}{section.1.3}
+\BOOKMARK [2][-]{subsection.1.3.3}{Algorithm Inputs and Outputs}{section.1.3}
+\BOOKMARK [2][-]{subsection.1.3.4}{Mathematical Expressions}{section.1.3}
+\BOOKMARK [2][-]{subsection.1.3.5}{Work Effort}{section.1.3}
+\BOOKMARK [1][-]{section.1.4}{Exercises}{chapter.1}
+\BOOKMARK [1][-]{section.1.5}{Introduction to LibTomMath}{chapter.1}
+\BOOKMARK [2][-]{subsection.1.5.1}{What is LibTomMath?}{section.1.5}
+\BOOKMARK [2][-]{subsection.1.5.2}{Goals of LibTomMath}{section.1.5}
+\BOOKMARK [1][-]{section.1.6}{Choice of LibTomMath}{chapter.1}
+\BOOKMARK [2][-]{subsection.1.6.1}{Code Base}{section.1.6}
+\BOOKMARK [2][-]{subsection.1.6.2}{API Simplicity}{section.1.6}
+\BOOKMARK [2][-]{subsection.1.6.3}{Optimizations}{section.1.6}
+\BOOKMARK [2][-]{subsection.1.6.4}{Portability and Stability}{section.1.6}
+\BOOKMARK [2][-]{subsection.1.6.5}{Choice}{section.1.6}
+\BOOKMARK [0][-]{chapter.2}{Getting Started}{}
+\BOOKMARK [1][-]{section.2.1}{Library Basics}{chapter.2}
+\BOOKMARK [1][-]{section.2.2}{What is a Multiple Precision Integer?}{chapter.2}
+\BOOKMARK [2][-]{subsection.2.2.1}{The mp\137int Structure}{section.2.2}
+\BOOKMARK [1][-]{section.2.3}{Argument Passing}{chapter.2}
+\BOOKMARK [1][-]{section.2.4}{Return Values}{chapter.2}
+\BOOKMARK [1][-]{section.2.5}{Initialization and Clearing}{chapter.2}
+\BOOKMARK [2][-]{subsection.2.5.1}{Initializing an mp\137int}{section.2.5}
+\BOOKMARK [2][-]{subsection.2.5.2}{Clearing an mp\137int}{section.2.5}
+\BOOKMARK [1][-]{section.2.6}{Maintenance Algorithms}{chapter.2}
+\BOOKMARK [2][-]{subsection.2.6.1}{Augmenting an mp\137int's Precision}{section.2.6}
+\BOOKMARK [2][-]{subsection.2.6.2}{Initializing Variable Precision mp\137ints}{section.2.6}
+\BOOKMARK [2][-]{subsection.2.6.3}{Multiple Integer Initializations and Clearings}{section.2.6}
+\BOOKMARK [2][-]{subsection.2.6.4}{Clamping Excess Digits}{section.2.6}
+\BOOKMARK [0][-]{chapter.3}{Basic Operations}{}
+\BOOKMARK [1][-]{section.3.1}{Introduction}{chapter.3}
+\BOOKMARK [1][-]{section.3.2}{Assigning Values to mp\137int Structures}{chapter.3}
+\BOOKMARK [2][-]{subsection.3.2.1}{Copying an mp\137int}{section.3.2}
+\BOOKMARK [2][-]{subsection.3.2.2}{Creating a Clone}{section.3.2}
+\BOOKMARK [1][-]{section.3.3}{Zeroing an Integer}{chapter.3}
+\BOOKMARK [1][-]{section.3.4}{Sign Manipulation}{chapter.3}
+\BOOKMARK [2][-]{subsection.3.4.1}{Absolute Value}{section.3.4}
+\BOOKMARK [2][-]{subsection.3.4.2}{Integer Negation}{section.3.4}
+\BOOKMARK [1][-]{section.3.5}{Small Constants}{chapter.3}
+\BOOKMARK [2][-]{subsection.3.5.1}{Setting Small Constants}{section.3.5}
+\BOOKMARK [2][-]{subsection.3.5.2}{Setting Large Constants}{section.3.5}
+\BOOKMARK [1][-]{section.3.6}{Comparisons}{chapter.3}
+\BOOKMARK [2][-]{subsection.3.6.1}{Unsigned Comparisions}{section.3.6}
+\BOOKMARK [2][-]{subsection.3.6.2}{Signed Comparisons}{section.3.6}
+\BOOKMARK [0][-]{chapter.4}{Basic Arithmetic}{}
+\BOOKMARK [1][-]{section.4.1}{Introduction}{chapter.4}
+\BOOKMARK [1][-]{section.4.2}{Addition and Subtraction}{chapter.4}
+\BOOKMARK [2][-]{subsection.4.2.1}{Low Level Addition}{section.4.2}
+\BOOKMARK [2][-]{subsection.4.2.2}{Low Level Subtraction}{section.4.2}
+\BOOKMARK [2][-]{subsection.4.2.3}{High Level Addition}{section.4.2}
+\BOOKMARK [2][-]{subsection.4.2.4}{High Level Subtraction}{section.4.2}
+\BOOKMARK [1][-]{section.4.3}{Bit and Digit Shifting}{chapter.4}
+\BOOKMARK [2][-]{subsection.4.3.1}{Multiplication by Two}{section.4.3}
+\BOOKMARK [2][-]{subsection.4.3.2}{Division by Two}{section.4.3}
+\BOOKMARK [1][-]{section.4.4}{Polynomial Basis Operations}{chapter.4}
+\BOOKMARK [2][-]{subsection.4.4.1}{Multiplication by x}{section.4.4}
+\BOOKMARK [2][-]{subsection.4.4.2}{Division by x}{section.4.4}
+\BOOKMARK [1][-]{section.4.5}{Powers of Two}{chapter.4}
+\BOOKMARK [2][-]{subsection.4.5.1}{Multiplication by Power of Two}{section.4.5}
+\BOOKMARK [2][-]{subsection.4.5.2}{Division by Power of Two}{section.4.5}
+\BOOKMARK [2][-]{subsection.4.5.3}{Remainder of Division by Power of Two}{section.4.5}
+\BOOKMARK [0][-]{chapter.5}{Multiplication and Squaring}{}
+\BOOKMARK [1][-]{section.5.1}{The Multipliers}{chapter.5}
+\BOOKMARK [1][-]{section.5.2}{Multiplication}{chapter.5}
+\BOOKMARK [2][-]{subsection.5.2.1}{The Baseline Multiplication}{section.5.2}
+\BOOKMARK [2][-]{subsection.5.2.2}{Faster Multiplication by the ``Comba'' Method}{section.5.2}
+\BOOKMARK [2][-]{subsection.5.2.3}{Polynomial Basis Multiplication}{section.5.2}
+\BOOKMARK [2][-]{subsection.5.2.4}{Karatsuba Multiplication}{section.5.2}
+\BOOKMARK [2][-]{subsection.5.2.5}{Toom-Cook 3-Way Multiplication}{section.5.2}
+\BOOKMARK [2][-]{subsection.5.2.6}{Signed Multiplication}{section.5.2}
+\BOOKMARK [1][-]{section.5.3}{Squaring}{chapter.5}
+\BOOKMARK [2][-]{subsection.5.3.1}{The Baseline Squaring Algorithm}{section.5.3}
+\BOOKMARK [2][-]{subsection.5.3.2}{Faster Squaring by the ``Comba'' Method}{section.5.3}
+\BOOKMARK [2][-]{subsection.5.3.3}{Polynomial Basis Squaring}{section.5.3}
+\BOOKMARK [2][-]{subsection.5.3.4}{Karatsuba Squaring}{section.5.3}
+\BOOKMARK [2][-]{subsection.5.3.5}{Toom-Cook Squaring}{section.5.3}
+\BOOKMARK [2][-]{subsection.5.3.6}{High Level Squaring}{section.5.3}
+\BOOKMARK [0][-]{chapter.6}{Modular Reduction}{}
+\BOOKMARK [1][-]{section.6.1}{Basics of Modular Reduction}{chapter.6}
+\BOOKMARK [1][-]{section.6.2}{The Barrett Reduction}{chapter.6}
+\BOOKMARK [2][-]{subsection.6.2.1}{Fixed Point Arithmetic}{section.6.2}
+\BOOKMARK [2][-]{subsection.6.2.2}{Choosing a Radix Point}{section.6.2}
+\BOOKMARK [2][-]{subsection.6.2.3}{Trimming the Quotient}{section.6.2}
+\BOOKMARK [2][-]{subsection.6.2.4}{Trimming the Residue}{section.6.2}
+\BOOKMARK [2][-]{subsection.6.2.5}{The Barrett Algorithm}{section.6.2}
+\BOOKMARK [2][-]{subsection.6.2.6}{The Barrett Setup Algorithm}{section.6.2}
+\BOOKMARK [1][-]{section.6.3}{The Montgomery Reduction}{chapter.6}
+\BOOKMARK [2][-]{subsection.6.3.1}{Digit Based Montgomery Reduction}{section.6.3}
+\BOOKMARK [2][-]{subsection.6.3.2}{Baseline Montgomery Reduction}{section.6.3}
+\BOOKMARK [2][-]{subsection.6.3.3}{Faster ``Comba'' Montgomery Reduction}{section.6.3}
+\BOOKMARK [2][-]{subsection.6.3.4}{Montgomery Setup}{section.6.3}
+\BOOKMARK [1][-]{section.6.4}{The Diminished Radix Algorithm}{chapter.6}
+\BOOKMARK [2][-]{subsection.6.4.1}{Choice of Moduli}{section.6.4}
+\BOOKMARK [2][-]{subsection.6.4.2}{Choice of k}{section.6.4}
+\BOOKMARK [2][-]{subsection.6.4.3}{Restricted Diminished Radix Reduction}{section.6.4}
+\BOOKMARK [2][-]{subsection.6.4.4}{Unrestricted Diminished Radix Reduction}{section.6.4}
+\BOOKMARK [1][-]{section.6.5}{Algorithm Comparison}{chapter.6}
+\BOOKMARK [0][-]{chapter.7}{Exponentiation}{}
+\BOOKMARK [1][-]{section.7.1}{Exponentiation Basics}{chapter.7}
+\BOOKMARK [2][-]{subsection.7.1.1}{Single Digit Exponentiation}{section.7.1}
+\BOOKMARK [1][-]{section.7.2}{k-ary Exponentiation}{chapter.7}
+\BOOKMARK [2][-]{subsection.7.2.1}{Optimal Values of k}{section.7.2}
+\BOOKMARK [2][-]{subsection.7.2.2}{Sliding-Window Exponentiation}{section.7.2}
+\BOOKMARK [1][-]{section.7.3}{Modular Exponentiation}{chapter.7}
+\BOOKMARK [2][-]{subsection.7.3.1}{Barrett Modular Exponentiation}{section.7.3}
+\BOOKMARK [1][-]{section.7.4}{Quick Power of Two}{chapter.7}
+\BOOKMARK [0][-]{chapter.8}{Higher Level Algorithms}{}
+\BOOKMARK [1][-]{section.8.1}{Integer Division with Remainder}{chapter.8}
+\BOOKMARK [2][-]{subsection.8.1.1}{Quotient Estimation}{section.8.1}
+\BOOKMARK [2][-]{subsection.8.1.2}{Normalized Integers}{section.8.1}
+\BOOKMARK [2][-]{subsection.8.1.3}{Radix- Division with Remainder}{section.8.1}
+\BOOKMARK [1][-]{section.8.2}{Single Digit Helpers}{chapter.8}
+\BOOKMARK [2][-]{subsection.8.2.1}{Single Digit Addition and Subtraction}{section.8.2}
+\BOOKMARK [2][-]{subsection.8.2.2}{Single Digit Multiplication}{section.8.2}
+\BOOKMARK [2][-]{subsection.8.2.3}{Single Digit Division}{section.8.2}
+\BOOKMARK [2][-]{subsection.8.2.4}{Single Digit Root Extraction}{section.8.2}
+\BOOKMARK [1][-]{section.8.3}{Random Number Generation}{chapter.8}
+\BOOKMARK [1][-]{section.8.4}{Formatted Representations}{chapter.8}
+\BOOKMARK [2][-]{subsection.8.4.1}{Reading Radix-n Input}{section.8.4}
+\BOOKMARK [2][-]{subsection.8.4.2}{Generating Radix-n Output}{section.8.4}
+\BOOKMARK [0][-]{chapter.9}{Number Theoretic Algorithms}{}
+\BOOKMARK [1][-]{section.9.1}{Greatest Common Divisor}{chapter.9}
+\BOOKMARK [2][-]{subsection.9.1.1}{Complete Greatest Common Divisor}{section.9.1}
+\BOOKMARK [1][-]{section.9.2}{Least Common Multiple}{chapter.9}
+\BOOKMARK [1][-]{section.9.3}{Jacobi Symbol Computation}{chapter.9}
+\BOOKMARK [2][-]{subsection.9.3.1}{Jacobi Symbol}{section.9.3}
+\BOOKMARK [1][-]{section.9.4}{Modular Inverse}{chapter.9}
+\BOOKMARK [2][-]{subsection.9.4.1}{General Case}{section.9.4}
+\BOOKMARK [1][-]{section.9.5}{Primality Tests}{chapter.9}
+\BOOKMARK [2][-]{subsection.9.5.1}{Trial Division}{section.9.5}
+\BOOKMARK [2][-]{subsection.9.5.2}{The Fermat Test}{section.9.5}
+\BOOKMARK [2][-]{subsection.9.5.3}{The Miller-Rabin Test}{section.9.5}
diff --git a/libtommath/tommath.pdf b/libtommath/tommath.pdf
new file mode 100644
index 0000000..c9571d8
Binary files /dev/null and b/libtommath/tommath.pdf differ
diff --git a/libtommath/tommath.src b/libtommath/tommath.src
new file mode 100644
index 0000000..4065822
--- /dev/null
+++ b/libtommath/tommath.src
@@ -0,0 +1,6350 @@
+\documentclass[b5paper]{book}
+\usepackage{hyperref}
+\usepackage{makeidx}
+\usepackage{amssymb}
+\usepackage{color}
+\usepackage{alltt}
+\usepackage{graphicx}
+\usepackage{layout}
+\def\union{\cup}
+\def\intersect{\cap}
+\def\getsrandom{\stackrel{\rm R}{\gets}}
+\def\cross{\times}
+\def\cat{\hspace{0.5em} \| \hspace{0.5em}}
+\def\catn{$\|$}
+\def\divides{\hspace{0.3em} | \hspace{0.3em}}
+\def\nequiv{\not\equiv}
+\def\approx{\raisebox{0.2ex}{\mbox{\small $\sim$}}}
+\def\lcm{{\rm lcm}}
+\def\gcd{{\rm gcd}}
+\def\log{{\rm log}}
+\def\ord{{\rm ord}}
+\def\abs{{\mathit abs}}
+\def\rep{{\mathit rep}}
+\def\mod{{\mathit\ mod\ }}
+\renewcommand{\pmod}[1]{\ ({\rm mod\ }{#1})}
+\newcommand{\floor}[1]{\left\lfloor{#1}\right\rfloor}
+\newcommand{\ceil}[1]{\left\lceil{#1}\right\rceil}
+\def\Or{{\rm\ or\ }}
+\def\And{{\rm\ and\ }}
+\def\iff{\hspace{1em}\Longleftrightarrow\hspace{1em}}
+\def\implies{\Rightarrow}
+\def\undefined{{\rm ``undefined"}}
+\def\Proof{\vspace{1ex}\noindent {\bf Proof:}\hspace{1em}}
+\let\oldphi\phi
+\def\phi{\varphi}
+\def\Pr{{\rm Pr}}
+\newcommand{\str}[1]{{\mathbf{#1}}}
+\def\F{{\mathbb F}}
+\def\N{{\mathbb N}}
+\def\Z{{\mathbb Z}}
+\def\R{{\mathbb R}}
+\def\C{{\mathbb C}}
+\def\Q{{\mathbb Q}}
+\definecolor{DGray}{gray}{0.5}
+\newcommand{\emailaddr}[1]{\mbox{$<${#1}$>$}}
+\def\twiddle{\raisebox{0.3ex}{\mbox{\tiny $\sim$}}}
+\def\gap{\vspace{0.5ex}}
+\makeindex
+\begin{document}
+\frontmatter
+\pagestyle{empty}
+\title{Multi--Precision Math}
+\author{\mbox{
+%\begin{small}
+\begin{tabular}{c}
+Tom St Denis \\
+Algonquin College \\
+\\
+Mads Rasmussen \\
+Open Communications Security \\
+\\
+Greg Rose \\
+QUALCOMM Australia \\
+\end{tabular}
+%\end{small}
+}
+}
+\maketitle
+This text has been placed in the public domain.  This text corresponds to the v0.39 release of the 
+LibTomMath project.
+
+\begin{alltt}
+Tom St Denis
+111 Banning Rd
+Ottawa, Ontario
+K2L 1C3
+Canada
+
+Phone: 1-613-836-3160
+Email: tomstdenis@gmail.com
+\end{alltt}
+
+This text is formatted to the international B5 paper size of 176mm wide by 250mm tall using the \LaTeX{} 
+{\em book} macro package and the Perl {\em booker} package.
+
+\tableofcontents
+\listoffigures
+\chapter*{Prefaces}
+When I tell people about my LibTom projects and that I release them as public domain they are often puzzled.  
+They ask why I did it and especially why I continue to work on them for free.  The best I can explain it is ``Because I can.''  
+Which seems odd and perhaps too terse for adult conversation. I often qualify it with ``I am able, I am willing.'' which 
+perhaps explains it better.  I am the first to admit there is not anything that special with what I have done.  Perhaps
+others can see that too and then we would have a society to be proud of.  My LibTom projects are what I am doing to give 
+back to society in the form of tools and knowledge that can help others in their endeavours.
+
+I started writing this book because it was the most logical task to further my goal of open academia.  The LibTomMath source
+code itself was written to be easy to follow and learn from.  There are times, however, where pure C source code does not
+explain the algorithms properly.  Hence this book.  The book literally starts with the foundation of the library and works
+itself outwards to the more complicated algorithms.  The use of both pseudo--code and verbatim source code provides a duality
+of ``theory'' and ``practice'' that the computer science students of the world shall appreciate.  I never deviate too far
+from relatively straightforward algebra and I hope that this book can be a valuable learning asset.
+
+This book and indeed much of the LibTom projects would not exist in their current form if it was not for a plethora
+of kind people donating their time, resources and kind words to help support my work.  Writing a text of significant
+length (along with the source code) is a tiresome and lengthy process.  Currently the LibTom project is four years old,
+comprises of literally thousands of users and over 100,000 lines of source code, TeX and other material.  People like Mads and Greg 
+were there at the beginning to encourage me to work well.  It is amazing how timely validation from others can boost morale to 
+continue the project. Definitely my parents were there for me by providing room and board during the many months of work in 2003.  
+
+To my many friends whom I have met through the years I thank you for the good times and the words of encouragement.  I hope I
+honour your kind gestures with this project.
+
+Open Source.  Open Academia.  Open Minds.
+
+\begin{flushright} Tom St Denis \end{flushright}
+
+\newpage
+I found the opportunity to work with Tom appealing for several reasons, not only could I broaden my own horizons, but also 
+contribute to educate others facing the problem of having to handle big number mathematical calculations.
+
+This book is Tom's child and he has been caring and fostering the project ever since the beginning with a clear mind of 
+how he wanted the project to turn out. I have helped by proofreading the text and we have had several discussions about 
+the layout and language used.
+
+I hold a masters degree in cryptography from the University of Southern Denmark and have always been interested in the 
+practical aspects of cryptography. 
+
+Having worked in the security consultancy business for several years in S\~{a}o Paulo, Brazil, I have been in touch with a 
+great deal of work in which multiple precision mathematics was needed. Understanding the possibilities for speeding up 
+multiple precision calculations is often very important since we deal with outdated machine architecture where modular 
+reductions, for example, become painfully slow.
+
+This text is for people who stop and wonder when first examining algorithms such as RSA for the first time and asks 
+themselves, ``You tell me this is only secure for large numbers, fine; but how do you implement these numbers?''
+
+\begin{flushright}
+Mads Rasmussen
+
+S\~{a}o Paulo - SP
+
+Brazil
+\end{flushright}
+
+\newpage
+It's all because I broke my leg. That just happened to be at about the same time that Tom asked for someone to review the section of the book about 
+Karatsuba multiplication. I was laid up, alone and immobile, and thought ``Why not?'' I vaguely knew what Karatsuba multiplication was, but not 
+really, so I thought I could help, learn, and stop myself from watching daytime cable TV, all at once.
+
+At the time of writing this, I've still not met Tom or Mads in meatspace. I've been following Tom's progress since his first splash on the 
+sci.crypt Usenet news group. I watched him go from a clueless newbie, to the cryptographic equivalent of a reformed smoker, to a real
+contributor to the field, over a period of about two years. I've been impressed with his obvious intelligence, and astounded by his productivity. 
+Of course, he's young enough to be my own child, so he doesn't have my problems with staying awake.
+
+When I reviewed that single section of the book, in its very earliest form, I was very pleasantly surprised. So I decided to collaborate more fully, 
+and at least review all of it, and perhaps write some bits too. There's still a long way to go with it, and I have watched a number of close 
+friends go through the mill of publication, so I think that the way to go is longer than Tom thinks it is. Nevertheless, it's a good effort, 
+and I'm pleased to be involved with it.
+
+\begin{flushright}
+Greg Rose, Sydney, Australia, June 2003. 
+\end{flushright}
+
+\mainmatter
+\pagestyle{headings}
+\chapter{Introduction}
+\section{Multiple Precision Arithmetic}
+
+\subsection{What is Multiple Precision Arithmetic?}
+When we think of long-hand arithmetic such as addition or multiplication we rarely consider the fact that we instinctively
+raise or lower the precision of the numbers we are dealing with.  For example, in decimal we almost immediate can 
+reason that $7$ times $6$ is $42$.  However, $42$ has two digits of precision as opposed to one digit we started with.  
+Further multiplications of say $3$ result in a larger precision result $126$.  In these few examples we have multiple 
+precisions for the numbers we are working with.  Despite the various levels of precision a single subset\footnote{With the occasional optimization.}
+ of algorithms can be designed to accomodate them.  
+
+By way of comparison a fixed or single precision operation would lose precision on various operations.  For example, in
+the decimal system with fixed precision $6 \cdot 7 = 2$.
+
+Essentially at the heart of computer based multiple precision arithmetic are the same long-hand algorithms taught in
+schools to manually add, subtract, multiply and divide.  
+
+\subsection{The Need for Multiple Precision Arithmetic}
+The most prevalent need for multiple precision arithmetic, often referred to as ``bignum'' math, is within the implementation
+of public-key cryptography algorithms.   Algorithms such as RSA \cite{RSAREF} and Diffie-Hellman \cite{DHREF} require 
+integers of significant magnitude to resist known cryptanalytic attacks.  For example, at the time of this writing a 
+typical RSA modulus would be at least greater than $10^{309}$.  However, modern programming languages such as ISO C \cite{ISOC} and 
+Java \cite{JAVA} only provide instrinsic support for integers which are relatively small and single precision.
+
+\begin{figure}[!here]
+\begin{center}
+\begin{tabular}{|r|c|}
+\hline \textbf{Data Type} & \textbf{Range} \\
+\hline char  & $-128 \ldots 127$ \\
+\hline short & $-32768 \ldots 32767$ \\
+\hline long  & $-2147483648 \ldots 2147483647$ \\
+\hline long long & $-9223372036854775808 \ldots 9223372036854775807$ \\
+\hline
+\end{tabular}
+\end{center}
+\caption{Typical Data Types for the C Programming Language}
+\label{fig:ISOC}
+\end{figure}
+
+The largest data type guaranteed to be provided by the ISO C programming 
+language\footnote{As per the ISO C standard.  However, each compiler vendor is allowed to augment the precision as they 
+see fit.}  can only represent values up to $10^{19}$ as shown in figure \ref{fig:ISOC}. On its own the C language is 
+insufficient to accomodate the magnitude required for the problem at hand.  An RSA modulus of magnitude $10^{19}$ could be 
+trivially factored\footnote{A Pollard-Rho factoring would take only $2^{16}$ time.} on the average desktop computer, 
+rendering any protocol based on the algorithm insecure.  Multiple precision algorithms solve this very problem by 
+extending the range of representable integers while using single precision data types.
+
+Most advancements in fast multiple precision arithmetic stem from the need for faster and more efficient cryptographic 
+primitives.  Faster modular reduction and exponentiation algorithms such as Barrett's algorithm, which have appeared in 
+various cryptographic journals, can render algorithms such as RSA and Diffie-Hellman more efficient.  In fact, several 
+major companies such as RSA Security, Certicom and Entrust have built entire product lines on the implementation and 
+deployment of efficient algorithms.
+
+However, cryptography is not the only field of study that can benefit from fast multiple precision integer routines.  
+Another auxiliary use of multiple precision integers is high precision floating point data types.  
+The basic IEEE \cite{IEEE} standard floating point type is made up of an integer mantissa $q$, an exponent $e$ and a sign bit $s$.  
+Numbers are given in the form $n = q \cdot b^e \cdot -1^s$ where $b = 2$ is the most common base for IEEE.  Since IEEE 
+floating point is meant to be implemented in hardware the precision of the mantissa is often fairly small 
+(\textit{23, 48 and 64 bits}).  The mantissa is merely an integer and a multiple precision integer could be used to create
+a mantissa of much larger precision than hardware alone can efficiently support.  This approach could be useful where 
+scientific applications must minimize the total output error over long calculations.
+
+Yet another use for large integers is within arithmetic on polynomials of large characteristic (i.e. $GF(p)[x]$ for large $p$).
+In fact the library discussed within this text has already been used to form a polynomial basis library\footnote{See \url{http://poly.libtomcrypt.org} for more details.}.
+
+\subsection{Benefits of Multiple Precision Arithmetic}
+\index{precision}
+The benefit of multiple precision representations over single or fixed precision representations is that 
+no precision is lost while representing the result of an operation which requires excess precision.  For example, 
+the product of two $n$-bit integers requires at least $2n$ bits of precision to be represented faithfully.  A multiple 
+precision algorithm would augment the precision of the destination to accomodate the result while a single precision system 
+would truncate excess bits to maintain a fixed level of precision.
+
+It is possible to implement algorithms which require large integers with fixed precision algorithms.  For example, elliptic
+curve cryptography (\textit{ECC}) is often implemented on smartcards by fixing the precision of the integers to the maximum 
+size the system will ever need.  Such an approach can lead to vastly simpler algorithms which can accomodate the 
+integers required even if the host platform cannot natively accomodate them\footnote{For example, the average smartcard 
+processor has an 8 bit accumulator.}.  However, as efficient as such an approach may be, the resulting source code is not
+normally very flexible.  It cannot, at runtime, accomodate inputs of higher magnitude than the designer anticipated.
+
+Multiple precision algorithms have the most overhead of any style of arithmetic.  For the the most part the 
+overhead can be kept to a minimum with careful planning, but overall, it is not well suited for most memory starved
+platforms.  However, multiple precision algorithms do offer the most flexibility in terms of the magnitude of the 
+inputs.  That is, the same algorithms based on multiple precision integers can accomodate any reasonable size input 
+without the designer's explicit forethought.  This leads to lower cost of ownership for the code as it only has to 
+be written and tested once.
+
+\section{Purpose of This Text}
+The purpose of this text is to instruct the reader regarding how to implement efficient multiple precision algorithms.  
+That is to not only explain a limited subset of the core theory behind the algorithms but also the various ``house keeping'' 
+elements that are neglected by authors of other texts on the subject.  Several well reknowned texts \cite{TAOCPV2,HAC} 
+give considerably detailed explanations of the theoretical aspects of algorithms and often very little information 
+regarding the practical implementation aspects.  
+
+In most cases how an algorithm is explained and how it is actually implemented are two very different concepts.  For 
+example, the Handbook of Applied Cryptography (\textit{HAC}), algorithm 14.7 on page 594, gives a relatively simple 
+algorithm for performing multiple precision integer addition.  However, the description lacks any discussion concerning 
+the fact that the two integer inputs may be of differing magnitudes.  As a result the implementation is not as simple
+as the text would lead people to believe.  Similarly the division routine (\textit{algorithm 14.20, pp. 598}) does not 
+discuss how to handle sign or handle the dividend's decreasing magnitude in the main loop (\textit{step \#3}).
+
+Both texts also do not discuss several key optimal algorithms required such as ``Comba'' and Karatsuba multipliers 
+and fast modular inversion, which we consider practical oversights.  These optimal algorithms are vital to achieve 
+any form of useful performance in non-trivial applications.  
+
+To solve this problem the focus of this text is on the practical aspects of implementing a multiple precision integer
+package.  As a case study the ``LibTomMath''\footnote{Available at \url{http://math.libtomcrypt.com}} package is used 
+to demonstrate algorithms with real implementations\footnote{In the ISO C programming language.} that have been field 
+tested and work very well.  The LibTomMath library is freely available on the Internet for all uses and this text 
+discusses a very large portion of the inner workings of the library.
+
+The algorithms that are presented will always include at least one ``pseudo-code'' description followed 
+by the actual C source code that implements the algorithm.  The pseudo-code can be used to implement the same 
+algorithm in other programming languages as the reader sees fit.  
+
+This text shall also serve as a walkthrough of the creation of multiple precision algorithms from scratch.  Showing
+the reader how the algorithms fit together as well as where to start on various taskings.  
+
+\section{Discussion and Notation}
+\subsection{Notation}
+A multiple precision integer of $n$-digits shall be denoted as $x = (x_{n-1}, \ldots, x_1, x_0)_{ \beta }$ and represent
+the integer $x \equiv \sum_{i=0}^{n-1} x_i\beta^i$.  The elements of the array $x$ are said to be the radix $\beta$ digits 
+of the integer.  For example, $x = (1,2,3)_{10}$ would represent the integer 
+$1\cdot 10^2 + 2\cdot10^1 + 3\cdot10^0 = 123$.  
+
+\index{mp\_int}
+The term ``mp\_int'' shall refer to a composite structure which contains the digits of the integer it represents, as well 
+as auxilary data required to manipulate the data.  These additional members are discussed further in section 
+\ref{sec:MPINT}.  For the purposes of this text a ``multiple precision integer'' and an ``mp\_int'' are assumed to be 
+synonymous.  When an algorithm is specified to accept an mp\_int variable it is assumed the various auxliary data members 
+are present as well.  An expression of the type \textit{variablename.item} implies that it should evaluate to the 
+member named ``item'' of the variable.  For example, a string of characters may have a member ``length'' which would 
+evaluate to the number of characters in the string.  If the string $a$ equals ``hello'' then it follows that 
+$a.length = 5$.  
+
+For certain discussions more generic algorithms are presented to help the reader understand the final algorithm used
+to solve a given problem.  When an algorithm is described as accepting an integer input it is assumed the input is 
+a plain integer with no additional multiple-precision members.  That is, algorithms that use integers as opposed to 
+mp\_ints as inputs do not concern themselves with the housekeeping operations required such as memory management.  These 
+algorithms will be used to establish the relevant theory which will subsequently be used to describe a multiple
+precision algorithm to solve the same problem.  
+
+\subsection{Precision Notation}
+The variable $\beta$ represents the radix of a single digit of a multiple precision integer and 
+must be of the form $q^p$ for $q, p \in \Z^+$.  A single precision variable must be able to represent integers in 
+the range $0 \le x < q \beta$ while a double precision variable must be able to represent integers in the range 
+$0 \le x < q \beta^2$.  The extra radix-$q$ factor allows additions and subtractions to proceed without truncation of the 
+carry.  Since all modern computers are binary, it is assumed that $q$ is two.
+
+\index{mp\_digit} \index{mp\_word}
+Within the source code that will be presented for each algorithm, the data type \textbf{mp\_digit} will represent 
+a single precision integer type, while, the data type \textbf{mp\_word} will represent a double precision integer type.  In 
+several algorithms (notably the Comba routines) temporary results will be stored in arrays of double precision mp\_words.  
+For the purposes of this text $x_j$ will refer to the $j$'th digit of a single precision array and $\hat x_j$ will refer to 
+the $j$'th digit of a double precision array.  Whenever an expression is to be assigned to a double precision
+variable it is assumed that all single precision variables are promoted to double precision during the evaluation.  
+Expressions that are assigned to a single precision variable are truncated to fit within the precision of a single
+precision data type.
+
+For example, if $\beta = 10^2$ a single precision data type may represent a value in the 
+range $0 \le x < 10^3$, while a double precision data type may represent a value in the range $0 \le x < 10^5$.  Let
+$a = 23$ and $b = 49$ represent two single precision variables.  The single precision product shall be written
+as $c \leftarrow a \cdot b$ while the double precision product shall be written as $\hat c \leftarrow a \cdot b$.
+In this particular case, $\hat c = 1127$ and $c = 127$.  The most significant digit of the product would not fit 
+in a single precision data type and as a result $c \ne \hat c$.  
+
+\subsection{Algorithm Inputs and Outputs}
+Within the algorithm descriptions all variables are assumed to be scalars of either single or double precision
+as indicated.  The only exception to this rule is when variables have been indicated to be of type mp\_int.  This 
+distinction is important as scalars are often used as array indicies and various other counters.  
+
+\subsection{Mathematical Expressions}
+The $\lfloor \mbox{ } \rfloor$ brackets imply an expression truncated to an integer not greater than the expression 
+itself.  For example, $\lfloor 5.7 \rfloor = 5$.  Similarly the $\lceil \mbox{ } \rceil$ brackets imply an expression
+rounded to an integer not less than the expression itself.  For example, $\lceil 5.1 \rceil = 6$.  Typically when 
+the $/$ division symbol is used the intention is to perform an integer division with truncation.  For example, 
+$5/2 = 2$ which will often be written as $\lfloor 5/2 \rfloor = 2$ for clarity.  When an expression is written as a 
+fraction a real value division is implied, for example ${5 \over 2} = 2.5$.  
+
+The norm of a multiple precision integer, for example $\vert \vert x \vert \vert$, will be used to represent the number of digits in the representation
+of the integer.  For example, $\vert \vert 123 \vert \vert = 3$ and $\vert \vert 79452 \vert \vert = 5$.  
+
+\subsection{Work Effort}
+\index{big-Oh}
+To measure the efficiency of the specified algorithms, a modified big-Oh notation is used.  In this system all 
+single precision operations are considered to have the same cost\footnote{Except where explicitly noted.}.  
+That is a single precision addition, multiplication and division are assumed to take the same time to 
+complete.  While this is generally not true in practice, it will simplify the discussions considerably.
+
+Some algorithms have slight advantages over others which is why some constants will not be removed in 
+the notation.  For example, a normal baseline multiplication (section \ref{sec:basemult}) requires $O(n^2)$ work while a 
+baseline squaring (section \ref{sec:basesquare}) requires $O({{n^2 + n}\over 2})$ work.  In standard big-Oh notation these 
+would both be said to be equivalent to $O(n^2)$.  However, 
+in the context of the this text this is not the case as the magnitude of the inputs will typically be rather small.  As a 
+result small constant factors in the work effort will make an observable difference in algorithm efficiency.
+
+All of the algorithms presented in this text have a polynomial time work level.  That is, of the form 
+$O(n^k)$ for $n, k \in \Z^{+}$.  This will help make useful comparisons in terms of the speed of the algorithms and how 
+various optimizations will help pay off in the long run.
+
+\section{Exercises}
+Within the more advanced chapters a section will be set aside to give the reader some challenging exercises related to
+the discussion at hand.  These exercises are not designed to be prize winning problems, but instead to be thought 
+provoking.  Wherever possible the problems are forward minded, stating problems that will be answered in subsequent 
+chapters.  The reader is encouraged to finish the exercises as they appear to get a better understanding of the 
+subject material.  
+
+That being said, the problems are designed to affirm knowledge of a particular subject matter.  Students in particular
+are encouraged to verify they can answer the problems correctly before moving on.
+
+Similar to the exercises of \cite[pp. ix]{TAOCPV2} these exercises are given a scoring system based on the difficulty of
+the problem.  However, unlike \cite{TAOCPV2} the problems do not get nearly as hard.  The scoring of these 
+exercises ranges from one (the easiest) to five (the hardest).  The following table sumarizes the 
+scoring system used.
+
+\begin{figure}[here]
+\begin{center}
+\begin{small}
+\begin{tabular}{|c|l|}
+\hline $\left [ 1 \right ]$ & An easy problem that should only take the reader a manner of \\
+                            & minutes to solve.  Usually does not involve much computer time \\
+                            & to solve. \\
+\hline $\left [ 2 \right ]$ & An easy problem that involves a marginal amount of computer \\
+                     & time usage.  Usually requires a program to be written to \\
+                     & solve the problem. \\
+\hline $\left [ 3 \right ]$ & A moderately hard problem that requires a non-trivial amount \\
+                     & of work.  Usually involves trivial research and development of \\
+                     & new theory from the perspective of a student. \\
+\hline $\left [ 4 \right ]$ & A moderately hard problem that involves a non-trivial amount \\
+                     & of work and research, the solution to which will demonstrate \\
+                     & a higher mastery of the subject matter. \\
+\hline $\left [ 5 \right ]$ & A hard problem that involves concepts that are difficult for a \\
+                     & novice to solve.  Solutions to these problems will demonstrate a \\
+                     & complete mastery of the given subject. \\
+\hline
+\end{tabular}
+\end{small}
+\end{center}
+\caption{Exercise Scoring System}
+\end{figure}
+
+Problems at the first level are meant to be simple questions that the reader can answer quickly without programming a solution or
+devising new theory.  These problems are quick tests to see if the material is understood.  Problems at the second level 
+are also designed to be easy but will require a program or algorithm to be implemented to arrive at the answer.  These
+two levels are essentially entry level questions.  
+
+Problems at the third level are meant to be a bit more difficult than the first two levels.  The answer is often 
+fairly obvious but arriving at an exacting solution requires some thought and skill.  These problems will almost always 
+involve devising a new algorithm or implementing a variation of another algorithm previously presented.  Readers who can
+answer these questions will feel comfortable with the concepts behind the topic at hand.
+
+Problems at the fourth level are meant to be similar to those of the level three questions except they will require 
+additional research to be completed.  The reader will most likely not know the answer right away, nor will the text provide 
+the exact details of the answer until a subsequent chapter.  
+
+Problems at the fifth level are meant to be the hardest 
+problems relative to all the other problems in the chapter.  People who can correctly answer fifth level problems have a 
+mastery of the subject matter at hand.
+
+Often problems will be tied together.  The purpose of this is to start a chain of thought that will be discussed in future chapters.  The reader
+is encouraged to answer the follow-up problems and try to draw the relevance of problems.
+
+\section{Introduction to LibTomMath}
+
+\subsection{What is LibTomMath?}
+LibTomMath is a free and open source multiple precision integer library written entirely in portable ISO C.  By portable it 
+is meant that the library does not contain any code that is computer platform dependent or otherwise problematic to use on 
+any given platform.  
+
+The library has been successfully tested under numerous operating systems including Unix\footnote{All of these
+trademarks belong to their respective rightful owners.}, MacOS, Windows, Linux, PalmOS and on standalone hardware such 
+as the Gameboy Advance.  The library is designed to contain enough functionality to be able to develop applications such 
+as public key cryptosystems and still maintain a relatively small footprint.
+
+\subsection{Goals of LibTomMath}
+
+Libraries which obtain the most efficiency are rarely written in a high level programming language such as C.  However, 
+even though this library is written entirely in ISO C, considerable care has been taken to optimize the algorithm implementations within the 
+library.  Specifically the code has been written to work well with the GNU C Compiler (\textit{GCC}) on both x86 and ARM 
+processors.  Wherever possible, highly efficient algorithms, such as Karatsuba multiplication, sliding window 
+exponentiation and Montgomery reduction have been provided to make the library more efficient.  
+
+Even with the nearly optimal and specialized algorithms that have been included the Application Programing Interface 
+(\textit{API}) has been kept as simple as possible.  Often generic place holder routines will make use of specialized 
+algorithms automatically without the developer's specific attention.  One such example is the generic multiplication 
+algorithm \textbf{mp\_mul()} which will automatically use Toom--Cook, Karatsuba, Comba or baseline multiplication 
+based on the magnitude of the inputs and the configuration of the library.  
+
+Making LibTomMath as efficient as possible is not the only goal of the LibTomMath project.  Ideally the library should 
+be source compatible with another popular library which makes it more attractive for developers to use.  In this case the
+MPI library was used as a API template for all the basic functions.  MPI was chosen because it is another library that fits 
+in the same niche as LibTomMath.  Even though LibTomMath uses MPI as the template for the function names and argument 
+passing conventions, it has been written from scratch by Tom St Denis.
+
+The project is also meant to act as a learning tool for students, the logic being that no easy-to-follow ``bignum'' 
+library exists which can be used to teach computer science students how to perform fast and reliable multiple precision 
+integer arithmetic.  To this end the source code has been given quite a few comments and algorithm discussion points.  
+
+\section{Choice of LibTomMath}
+LibTomMath was chosen as the case study of this text not only because the author of both projects is one and the same but
+for more worthy reasons.  Other libraries such as GMP \cite{GMP}, MPI \cite{MPI}, LIP \cite{LIP} and OpenSSL 
+\cite{OPENSSL} have multiple precision integer arithmetic routines but would not be ideal for this text for 
+reasons that will be explained in the following sub-sections.
+
+\subsection{Code Base}
+The LibTomMath code base is all portable ISO C source code.  This means that there are no platform dependent conditional
+segments of code littered throughout the source.  This clean and uncluttered approach to the library means that a
+developer can more readily discern the true intent of a given section of source code without trying to keep track of
+what conditional code will be used.
+
+The code base of LibTomMath is well organized.  Each function is in its own separate source code file 
+which allows the reader to find a given function very quickly.  On average there are $76$ lines of code per source
+file which makes the source very easily to follow.  By comparison MPI and LIP are single file projects making code tracing
+very hard.  GMP has many conditional code segments which also hinder tracing.  
+
+When compiled with GCC for the x86 processor and optimized for speed the entire library is approximately $100$KiB\footnote{The notation ``KiB'' means $2^{10}$ octets, similarly ``MiB'' means $2^{20}$ octets.}
+ which is fairly small compared to GMP (over $250$KiB).  LibTomMath is slightly larger than MPI (which compiles to about 
+$50$KiB) but LibTomMath is also much faster and more complete than MPI.
+
+\subsection{API Simplicity}
+LibTomMath is designed after the MPI library and shares the API design.  Quite often programs that use MPI will build 
+with LibTomMath without change. The function names correlate directly to the action they perform.  Almost all of the 
+functions share the same parameter passing convention.  The learning curve is fairly shallow with the API provided 
+which is an extremely valuable benefit for the student and developer alike.  
+
+The LIP library is an example of a library with an API that is awkward to work with.  LIP uses function names that are often ``compressed'' to 
+illegible short hand.  LibTomMath does not share this characteristic.  
+
+The GMP library also does not return error codes.  Instead it uses a POSIX.1 \cite{POSIX1} signal system where errors
+are signaled to the host application.  This happens to be the fastest approach but definitely not the most versatile.  In
+effect a math error (i.e. invalid input, heap error, etc) can cause a program to stop functioning which is definitely 
+undersireable in many situations.
+
+\subsection{Optimizations}
+While LibTomMath is certainly not the fastest library (GMP often beats LibTomMath by a factor of two) it does
+feature a set of optimal algorithms for tasks such as modular reduction, exponentiation, multiplication and squaring.  GMP 
+and LIP also feature such optimizations while MPI only uses baseline algorithms with no optimizations.  GMP lacks a few
+of the additional modular reduction optimizations that LibTomMath features\footnote{At the time of this writing GMP
+only had Barrett and Montgomery modular reduction algorithms.}.  
+
+LibTomMath is almost always an order of magnitude faster than the MPI library at computationally expensive tasks such as modular
+exponentiation.  In the grand scheme of ``bignum'' libraries LibTomMath is faster than the average library and usually  
+slower than the best libraries such as GMP and OpenSSL by only a small factor.
+
+\subsection{Portability and Stability}
+LibTomMath will build ``out of the box'' on any platform equipped with a modern version of the GNU C Compiler 
+(\textit{GCC}).  This means that without changes the library will build without configuration or setting up any 
+variables.  LIP and MPI will build ``out of the box'' as well but have numerous known bugs.  Most notably the author of 
+MPI has recently stopped working on his library and LIP has long since been discontinued.  
+
+GMP requires a configuration script to run and will not build out of the box.   GMP and LibTomMath are still in active
+development and are very stable across a variety of platforms.
+
+\subsection{Choice}
+LibTomMath is a relatively compact, well documented, highly optimized and portable library which seems only natural for
+the case study of this text.  Various source files from the LibTomMath project will be included within the text.  However, 
+the reader is encouraged to download their own copy of the library to actually be able to work with the library.  
+
+\chapter{Getting Started}
+\section{Library Basics}
+The trick to writing any useful library of source code is to build a solid foundation and work outwards from it.  First, 
+a problem along with allowable solution parameters should be identified and analyzed.  In this particular case the 
+inability to accomodate multiple precision integers is the problem.  Futhermore, the solution must be written
+as portable source code that is reasonably efficient across several different computer platforms.
+
+After a foundation is formed the remainder of the library can be designed and implemented in a hierarchical fashion.  
+That is, to implement the lowest level dependencies first and work towards the most abstract functions last.  For example, 
+before implementing a modular exponentiation algorithm one would implement a modular reduction algorithm.
+By building outwards from a base foundation instead of using a parallel design methodology the resulting project is 
+highly modular.  Being highly modular is a desirable property of any project as it often means the resulting product
+has a small footprint and updates are easy to perform.  
+
+Usually when I start a project I will begin with the header files.  I define the data types I think I will need and 
+prototype the initial functions that are not dependent on other functions (within the library).  After I 
+implement these base functions I prototype more dependent functions and implement them.   The process repeats until
+I implement all of the functions I require.  For example, in the case of LibTomMath I implemented functions such as 
+mp\_init() well before I implemented mp\_mul() and even further before I implemented mp\_exptmod().  As an example as to 
+why this design works note that the Karatsuba and Toom-Cook multipliers were written \textit{after} the 
+dependent function mp\_exptmod() was written.  Adding the new multiplication algorithms did not require changes to the 
+mp\_exptmod() function itself and lowered the total cost of ownership (\textit{so to speak}) and of development 
+for new algorithms.  This methodology allows new algorithms to be tested in a complete framework with relative ease.
+
+FIGU,design_process,Design Flow of the First Few Original LibTomMath Functions.
+
+Only after the majority of the functions were in place did I pursue a less hierarchical approach to auditing and optimizing
+the source code.  For example, one day I may audit the multipliers and the next day the polynomial basis functions.  
+
+It only makes sense to begin the text with the preliminary data types and support algorithms required as well.  
+This chapter discusses the core algorithms of the library which are the dependents for every other algorithm.
+
+\section{What is a Multiple Precision Integer?}
+Recall that most programming languages, in particular ISO C \cite{ISOC}, only have fixed precision data types that on their own cannot 
+be used to represent values larger than their precision will allow. The purpose of multiple precision algorithms is 
+to use fixed precision data types to create and manipulate multiple precision integers which may represent values 
+that are very large.  
+
+As a well known analogy, school children are taught how to form numbers larger than nine by prepending more radix ten digits.  In the decimal system
+the largest single digit value is $9$.  However, by concatenating digits together larger numbers may be represented.  Newly prepended digits 
+(\textit{to the left}) are said to be in a different power of ten column.  That is, the number $123$ can be described as having a $1$ in the hundreds 
+column, $2$ in the tens column and $3$ in the ones column.  Or more formally $123 = 1 \cdot 10^2 + 2 \cdot 10^1 + 3 \cdot 10^0$.  Computer based 
+multiple precision arithmetic is essentially the same concept.  Larger integers are represented by adjoining fixed 
+precision computer words with the exception that a different radix is used.
+
+What most people probably do not think about explicitly are the various other attributes that describe a multiple precision 
+integer.  For example, the integer $154_{10}$ has two immediately obvious properties.  First, the integer is positive, 
+that is the sign of this particular integer is positive as opposed to negative.  Second, the integer has three digits in 
+its representation.  There is an additional property that the integer posesses that does not concern pencil-and-paper 
+arithmetic.  The third property is how many digits placeholders are available to hold the integer.  
+
+The human analogy of this third property is ensuring there is enough space on the paper to write the integer.  For example,
+if one starts writing a large number too far to the right on a piece of paper they will have to erase it and move left.  
+Similarly, computer algorithms must maintain strict control over memory usage to ensure that the digits of an integer
+will not exceed the allowed boundaries.  These three properties make up what is known as a multiple precision 
+integer or mp\_int for short.  
+
+\subsection{The mp\_int Structure}
+\label{sec:MPINT}
+The mp\_int structure is the ISO C based manifestation of what represents a multiple precision integer.  The ISO C standard does not provide for 
+any such data type but it does provide for making composite data types known as structures.  The following is the structure definition 
+used within LibTomMath.
+
+\index{mp\_int}
+\begin{figure}[here]
+\begin{center}
+\begin{small}
+%\begin{verbatim}
+\begin{tabular}{|l|}
+\hline
+typedef struct \{ \\
+\hspace{3mm}int used, alloc, sign;\\
+\hspace{3mm}mp\_digit *dp;\\
+\} \textbf{mp\_int}; \\
+\hline
+\end{tabular}
+%\end{verbatim}
+\end{small}
+\caption{The mp\_int Structure}
+\label{fig:mpint}
+\end{center}
+\end{figure}
+
+The mp\_int structure (fig. \ref{fig:mpint}) can be broken down as follows.
+
+\begin{enumerate}
+\item The \textbf{used} parameter denotes how many digits of the array \textbf{dp} contain the digits used to represent
+a given integer.  The \textbf{used} count must be positive (or zero) and may not exceed the \textbf{alloc} count.  
+
+\item The \textbf{alloc} parameter denotes how 
+many digits are available in the array to use by functions before it has to increase in size.  When the \textbf{used} count 
+of a result would exceed the \textbf{alloc} count all of the algorithms will automatically increase the size of the 
+array to accommodate the precision of the result.  
+
+\item The pointer \textbf{dp} points to a dynamically allocated array of digits that represent the given multiple 
+precision integer.  It is padded with $(\textbf{alloc} - \textbf{used})$ zero digits.  The array is maintained in a least 
+significant digit order.  As a pencil and paper analogy the array is organized such that the right most digits are stored
+first starting at the location indexed by zero\footnote{In C all arrays begin at zero.} in the array.  For example, 
+if \textbf{dp} contains $\lbrace a, b, c, \ldots \rbrace$ where \textbf{dp}$_0 = a$, \textbf{dp}$_1 = b$, \textbf{dp}$_2 = c$, $\ldots$ then 
+it would represent the integer $a + b\beta + c\beta^2 + \ldots$  
+
+\index{MP\_ZPOS} \index{MP\_NEG}
+\item The \textbf{sign} parameter denotes the sign as either zero/positive (\textbf{MP\_ZPOS}) or negative (\textbf{MP\_NEG}).  
+\end{enumerate}
+
+\subsubsection{Valid mp\_int Structures}
+Several rules are placed on the state of an mp\_int structure and are assumed to be followed for reasons of efficiency.  
+The only exceptions are when the structure is passed to initialization functions such as mp\_init() and mp\_init\_copy().
+
+\begin{enumerate}
+\item The value of \textbf{alloc} may not be less than one.  That is \textbf{dp} always points to a previously allocated
+array of digits.
+\item The value of \textbf{used} may not exceed \textbf{alloc} and must be greater than or equal to zero.
+\item The value of \textbf{used} implies the digit at index $(used - 1)$ of the \textbf{dp} array is non-zero.  That is, 
+leading zero digits in the most significant positions must be trimmed.
+   \begin{enumerate}
+   \item Digits in the \textbf{dp} array at and above the \textbf{used} location must be zero.
+   \end{enumerate}
+\item The value of \textbf{sign} must be \textbf{MP\_ZPOS} if \textbf{used} is zero; 
+this represents the mp\_int value of zero.
+\end{enumerate}
+
+\section{Argument Passing}
+A convention of argument passing must be adopted early on in the development of any library.  Making the function 
+prototypes consistent will help eliminate many headaches in the future as the library grows to significant complexity.  
+In LibTomMath the multiple precision integer functions accept parameters from left to right as pointers to mp\_int 
+structures.  That means that the source (input) operands are placed on the left and the destination (output) on the right.   
+Consider the following examples.
+
+\begin{verbatim}
+   mp_mul(&a, &b, &c);   /* c = a * b */
+   mp_add(&a, &b, &a);   /* a = a + b */
+   mp_sqr(&a, &b);       /* b = a * a */
+\end{verbatim}
+
+The left to right order is a fairly natural way to implement the functions since it lets the developer read aloud the
+functions and make sense of them.  For example, the first function would read ``multiply a and b and store in c''.
+
+Certain libraries (\textit{LIP by Lenstra for instance}) accept parameters the other way around, to mimic the order
+of assignment expressions.  That is, the destination (output) is on the left and arguments (inputs) are on the right.  In 
+truth, it is entirely a matter of preference.  In the case of LibTomMath the convention from the MPI library has been 
+adopted.  
+
+Another very useful design consideration, provided for in LibTomMath, is whether to allow argument sources to also be a 
+destination.  For example, the second example (\textit{mp\_add}) adds $a$ to $b$ and stores in $a$.  This is an important 
+feature to implement since it allows the calling functions to cut down on the number of variables it must maintain.  
+However, to implement this feature specific care has to be given to ensure the destination is not modified before the 
+source is fully read.
+
+\section{Return Values}
+A well implemented application, no matter what its purpose, should trap as many runtime errors as possible and return them 
+to the caller.  By catching runtime errors a library can be guaranteed to prevent undefined behaviour.  However, the end 
+developer can still manage to cause a library to crash.  For example, by passing an invalid pointer an application may
+fault by dereferencing memory not owned by the application.
+
+In the case of LibTomMath the only errors that are checked for are related to inappropriate inputs (division by zero for 
+instance) and memory allocation errors.  It will not check that the mp\_int passed to any function is valid nor 
+will it check pointers for validity.  Any function that can cause a runtime error will return an error code as an 
+\textbf{int} data type with one of the following values (fig \ref{fig:errcodes}).
+
+\index{MP\_OKAY} \index{MP\_VAL} \index{MP\_MEM}
+\begin{figure}[here]
+\begin{center}
+\begin{tabular}{|l|l|}
+\hline \textbf{Value} & \textbf{Meaning} \\
+\hline \textbf{MP\_OKAY} & The function was successful \\
+\hline \textbf{MP\_VAL}  & One of the input value(s) was invalid \\
+\hline \textbf{MP\_MEM}  & The function ran out of heap memory \\
+\hline
+\end{tabular}
+\end{center}
+\caption{LibTomMath Error Codes}
+\label{fig:errcodes}
+\end{figure}
+
+When an error is detected within a function it should free any memory it allocated, often during the initialization of
+temporary mp\_ints, and return as soon as possible.  The goal is to leave the system in the same state it was when the 
+function was called.  Error checking with this style of API is fairly simple.
+
+\begin{verbatim}
+   int err;
+   if ((err = mp_add(&a, &b, &c)) != MP_OKAY) {
+      printf("Error: %s\n", mp_error_to_string(err));
+      exit(EXIT_FAILURE);
+   }
+\end{verbatim}
+
+The GMP \cite{GMP} library uses C style \textit{signals} to flag errors which is of questionable use.  Not all errors are fatal 
+and it was not deemed ideal by the author of LibTomMath to force developers to have signal handlers for such cases.
+
+\section{Initialization and Clearing}
+The logical starting point when actually writing multiple precision integer functions is the initialization and 
+clearing of the mp\_int structures.  These two algorithms will be used by the majority of the higher level algorithms.
+
+Given the basic mp\_int structure an initialization routine must first allocate memory to hold the digits of
+the integer.  Often it is optimal to allocate a sufficiently large pre-set number of digits even though
+the initial integer will represent zero.  If only a single digit were allocated quite a few subsequent re-allocations
+would occur when operations are performed on the integers.  There is a tradeoff between how many default digits to allocate
+and how many re-allocations are tolerable.  Obviously allocating an excessive amount of digits initially will waste 
+memory and become unmanageable.  
+
+If the memory for the digits has been successfully allocated then the rest of the members of the structure must
+be initialized.  Since the initial state of an mp\_int is to represent the zero integer, the allocated digits must be set
+to zero.  The \textbf{used} count set to zero and \textbf{sign} set to \textbf{MP\_ZPOS}.
+
+\subsection{Initializing an mp\_int}
+An mp\_int is said to be initialized if it is set to a valid, preferably default, state such that all of the members of the
+structure are set to valid values.  The mp\_init algorithm will perform such an action.
+
+\index{mp\_init}
+\begin{figure}[here]
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{mp\_init}. \\
+\textbf{Input}.   An mp\_int $a$ \\
+\textbf{Output}.  Allocate memory and initialize $a$ to a known valid mp\_int state.  \\
+\hline \\
+1.  Allocate memory for \textbf{MP\_PREC} digits. \\
+2.  If the allocation failed return(\textit{MP\_MEM}) \\
+3.  for $n$ from $0$ to $MP\_PREC - 1$ do  \\
+\hspace{3mm}3.1  $a_n \leftarrow 0$\\
+4.  $a.sign \leftarrow MP\_ZPOS$\\
+5.  $a.used \leftarrow 0$\\
+6.  $a.alloc \leftarrow MP\_PREC$\\
+7.  Return(\textit{MP\_OKAY})\\
+\hline
+\end{tabular}
+\end{center}
+\caption{Algorithm mp\_init}
+\end{figure}
+
+\textbf{Algorithm mp\_init.}
+The purpose of this function is to initialize an mp\_int structure so that the rest of the library can properly
+manipulte it.  It is assumed that the input may not have had any of its members previously initialized which is certainly
+a valid assumption if the input resides on the stack.  
+
+Before any of the members such as \textbf{sign}, \textbf{used} or \textbf{alloc} are initialized the memory for
+the digits is allocated.  If this fails the function returns before setting any of the other members.  The \textbf{MP\_PREC} 
+name represents a constant\footnote{Defined in the ``tommath.h'' header file within LibTomMath.} 
+used to dictate the minimum precision of newly initialized mp\_int integers.  Ideally, it is at least equal to the smallest
+precision number you'll be working with.
+
+Allocating a block of digits at first instead of a single digit has the benefit of lowering the number of usually slow
+heap operations later functions will have to perform in the future.  If \textbf{MP\_PREC} is set correctly the slack 
+memory and the number of heap operations will be trivial.
+
+Once the allocation has been made the digits have to be set to zero as well as the \textbf{used}, \textbf{sign} and
+\textbf{alloc} members initialized.  This ensures that the mp\_int will always represent the default state of zero regardless
+of the original condition of the input.
+
+\textbf{Remark.}
+This function introduces the idiosyncrasy that all iterative loops, commonly initiated with the ``for'' keyword, iterate incrementally
+when the ``to'' keyword is placed between two expressions.  For example, ``for $a$ from $b$ to $c$ do'' means that
+a subsequent expression (or body of expressions) are to be evaluated upto $c - b$ times so long as $b \le c$.  In each
+iteration the variable $a$ is substituted for a new integer that lies inclusively between $b$ and $c$.  If $b > c$ occured
+the loop would not iterate.  By contrast if the ``downto'' keyword were used in place of ``to'' the loop would iterate 
+decrementally.
+
+EXAM,bn_mp_init.c
+
+One immediate observation of this initializtion function is that it does not return a pointer to a mp\_int structure.  It 
+is assumed that the caller has already allocated memory for the mp\_int structure, typically on the application stack.  The 
+call to mp\_init() is used only to initialize the members of the structure to a known default state.  
+
+Here we see (line @23,XMALLOC@) the memory allocation is performed first.  This allows us to exit cleanly and quickly
+if there is an error.  If the allocation fails the routine will return \textbf{MP\_MEM} to the caller to indicate there
+was a memory error.  The function XMALLOC is what actually allocates the memory.  Technically XMALLOC is not a function
+but a macro defined in ``tommath.h``.  By default, XMALLOC will evaluate to malloc() which is the C library's built--in
+memory allocation routine.
+
+In order to assure the mp\_int is in a known state the digits must be set to zero.  On most platforms this could have been
+accomplished by using calloc() instead of malloc().  However,  to correctly initialize a integer type to a given value in a 
+portable fashion you have to actually assign the value.  The for loop (line @28,for@) performs this required
+operation.
+
+After the memory has been successfully initialized the remainder of the members are initialized 
+(lines @29,used@ through @31,sign@) to their respective default states.  At this point the algorithm has succeeded and
+a success code is returned to the calling function.  If this function returns \textbf{MP\_OKAY} it is safe to assume the 
+mp\_int structure has been properly initialized and is safe to use with other functions within the library.  
+
+\subsection{Clearing an mp\_int}
+When an mp\_int is no longer required by the application, the memory that has been allocated for its digits must be 
+returned to the application's memory pool with the mp\_clear algorithm.
+
+\begin{figure}[here]
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{mp\_clear}. \\
+\textbf{Input}.   An mp\_int $a$ \\
+\textbf{Output}.  The memory for $a$ shall be deallocated.  \\
+\hline \\
+1.  If $a$ has been previously freed then return(\textit{MP\_OKAY}). \\
+2.  for $n$ from 0 to $a.used - 1$ do \\
+\hspace{3mm}2.1  $a_n \leftarrow 0$ \\
+3.  Free the memory allocated for the digits of $a$. \\
+4.  $a.used \leftarrow 0$ \\
+5.  $a.alloc \leftarrow 0$ \\
+6.  $a.sign \leftarrow MP\_ZPOS$ \\
+7.  Return(\textit{MP\_OKAY}). \\
+\hline
+\end{tabular}
+\end{center}
+\caption{Algorithm mp\_clear}
+\end{figure}
+
+\textbf{Algorithm mp\_clear.}
+This algorithm accomplishes two goals.  First, it clears the digits and the other mp\_int members.  This ensures that 
+if a developer accidentally re-uses a cleared structure it is less likely to cause problems.  The second goal
+is to free the allocated memory.
+
+The logic behind the algorithm is extended by marking cleared mp\_int structures so that subsequent calls to this
+algorithm will not try to free the memory multiple times.  Cleared mp\_ints are detectable by having a pre-defined invalid 
+digit pointer \textbf{dp} setting.
+
+Once an mp\_int has been cleared the mp\_int structure is no longer in a valid state for any other algorithm
+with the exception of algorithms mp\_init, mp\_init\_copy, mp\_init\_size and mp\_clear.
+
+EXAM,bn_mp_clear.c
+
+The algorithm only operates on the mp\_int if it hasn't been previously cleared.  The if statement (line @23,a->dp != NULL@)
+checks to see if the \textbf{dp} member is not \textbf{NULL}.  If the mp\_int is a valid mp\_int then \textbf{dp} cannot be
+\textbf{NULL} in which case the if statement will evaluate to true.
+
+The digits of the mp\_int are cleared by the for loop (line @25,for@) which assigns a zero to every digit.  Similar to mp\_init()
+the digits are assigned zero instead of using block memory operations (such as memset()) since this is more portable.  
+
+The digits are deallocated off the heap via the XFREE macro.  Similar to XMALLOC the XFREE macro actually evaluates to
+a standard C library function.  In this case the free() function.  Since free() only deallocates the memory the pointer
+still has to be reset to \textbf{NULL} manually (line @33,NULL@).  
+
+Now that the digits have been cleared and deallocated the other members are set to their final values (lines @34,= 0@ and @35,ZPOS@).
+
+\section{Maintenance Algorithms}
+
+The previous sections describes how to initialize and clear an mp\_int structure.  To further support operations
+that are to be performed on mp\_int structures (such as addition and multiplication) the dependent algorithms must be
+able to augment the precision of an mp\_int and 
+initialize mp\_ints with differing initial conditions.  
+
+These algorithms complete the set of low level algorithms required to work with mp\_int structures in the higher level
+algorithms such as addition, multiplication and modular exponentiation.
+
+\subsection{Augmenting an mp\_int's Precision}
+When storing a value in an mp\_int structure, a sufficient number of digits must be available to accomodate the entire 
+result of an operation without loss of precision.  Quite often the size of the array given by the \textbf{alloc} member 
+is large enough to simply increase the \textbf{used} digit count.  However, when the size of the array is too small it 
+must be re-sized appropriately to accomodate the result.  The mp\_grow algorithm will provide this functionality.
+
+\newpage\begin{figure}[here]
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{mp\_grow}. \\
+\textbf{Input}.   An mp\_int $a$ and an integer $b$. \\
+\textbf{Output}.  $a$ is expanded to accomodate $b$ digits. \\
+\hline \\
+1.  if $a.alloc \ge b$ then return(\textit{MP\_OKAY}) \\
+2.  $u \leftarrow b\mbox{ (mod }MP\_PREC\mbox{)}$ \\
+3.  $v \leftarrow b + 2 \cdot MP\_PREC - u$ \\
+4.  Re-allocate the array of digits $a$ to size $v$ \\
+5.  If the allocation failed then return(\textit{MP\_MEM}). \\
+6.  for n from a.alloc to $v - 1$ do  \\
+\hspace{+3mm}6.1  $a_n \leftarrow 0$ \\
+7.  $a.alloc \leftarrow v$ \\
+8.  Return(\textit{MP\_OKAY}) \\
+\hline
+\end{tabular}
+\end{center}
+\caption{Algorithm mp\_grow}
+\end{figure}
+
+\textbf{Algorithm mp\_grow.}
+It is ideal to prevent re-allocations from being performed if they are not required (step one).  This is useful to 
+prevent mp\_ints from growing excessively in code that erroneously calls mp\_grow.  
+
+The requested digit count is padded up to next multiple of \textbf{MP\_PREC} plus an additional \textbf{MP\_PREC} (steps two and three).  
+This helps prevent many trivial reallocations that would grow an mp\_int by trivially small values.  
+
+It is assumed that the reallocation (step four) leaves the lower $a.alloc$ digits of the mp\_int intact.  This is much 
+akin to how the \textit{realloc} function from the standard C library works.  Since the newly allocated digits are 
+assumed to contain undefined values they are initially set to zero.
+
+EXAM,bn_mp_grow.c
+
+A quick optimization is to first determine if a memory re-allocation is required at all.  The if statement (line @24,alloc@) checks
+if the \textbf{alloc} member of the mp\_int is smaller than the requested digit count.  If the count is not larger than \textbf{alloc}
+the function skips the re-allocation part thus saving time.
+
+When a re-allocation is performed it is turned into an optimal request to save time in the future.  The requested digit count is
+padded upwards to 2nd multiple of \textbf{MP\_PREC} larger than \textbf{alloc} (line @25, size@).  The XREALLOC function is used
+to re-allocate the memory.  As per the other functions XREALLOC is actually a macro which evaluates to realloc by default.  The realloc
+function leaves the base of the allocation intact which means the first \textbf{alloc} digits of the mp\_int are the same as before
+the re-allocation.  All	that is left is to clear the newly allocated digits and return.
+
+Note that the re-allocation result is actually stored in a temporary pointer $tmp$.  This is to allow this function to return
+an error with a valid pointer.  Earlier releases of the library stored the result of XREALLOC into the mp\_int $a$.  That would
+result in a memory leak if XREALLOC ever failed.  
+
+\subsection{Initializing Variable Precision mp\_ints}
+Occasionally the number of digits required will be known in advance of an initialization, based on, for example, the size 
+of input mp\_ints to a given algorithm.  The purpose of algorithm mp\_init\_size is similar to mp\_init except that it 
+will allocate \textit{at least} a specified number of digits.  
+
+\begin{figure}[here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{mp\_init\_size}. \\
+\textbf{Input}.   An mp\_int $a$ and the requested number of digits $b$. \\
+\textbf{Output}.  $a$ is initialized to hold at least $b$ digits. \\
+\hline \\
+1.  $u \leftarrow b \mbox{ (mod }MP\_PREC\mbox{)}$ \\
+2.  $v \leftarrow b + 2 \cdot MP\_PREC - u$ \\
+3.  Allocate $v$ digits. \\
+4.  for $n$ from $0$ to $v - 1$ do \\
+\hspace{3mm}4.1  $a_n \leftarrow 0$ \\
+5.  $a.sign \leftarrow MP\_ZPOS$\\
+6.  $a.used \leftarrow 0$\\
+7.  $a.alloc \leftarrow v$\\
+8.  Return(\textit{MP\_OKAY})\\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Algorithm mp\_init\_size}
+\end{figure}
+
+\textbf{Algorithm mp\_init\_size.}
+This algorithm will initialize an mp\_int structure $a$ like algorithm mp\_init with the exception that the number of 
+digits allocated can be controlled by the second input argument $b$.  The input size is padded upwards so it is a 
+multiple of \textbf{MP\_PREC} plus an additional \textbf{MP\_PREC} digits.  This padding is used to prevent trivial 
+allocations from becoming a bottleneck in the rest of the algorithms.
+
+Like algorithm mp\_init, the mp\_int structure is initialized to a default state representing the integer zero.  This 
+particular algorithm is useful if it is known ahead of time the approximate size of the input.  If the approximation is
+correct no further memory re-allocations are required to work with the mp\_int.
+
+EXAM,bn_mp_init_size.c
+
+The number of digits $b$ requested is padded (line @22,MP_PREC@) by first augmenting it to the next multiple of 
+\textbf{MP\_PREC} and then adding \textbf{MP\_PREC} to the result.  If the memory can be successfully allocated the 
+mp\_int is placed in a default state representing the integer zero.  Otherwise, the error code \textbf{MP\_MEM} will be 
+returned (line @27,return@).  
+
+The digits are allocated and set to zero at the same time with the calloc() function (line @25,XCALLOC@).  The 
+\textbf{used} count is set to zero, the \textbf{alloc} count set to the padded digit count and the \textbf{sign} flag set 
+to \textbf{MP\_ZPOS} to achieve a default valid mp\_int state (lines @29,used@, @30,alloc@ and @31,sign@).  If the function 
+returns succesfully then it is correct to assume that the mp\_int structure is in a valid state for the remainder of the 
+functions to work with.
+
+\subsection{Multiple Integer Initializations and Clearings}
+Occasionally a function will require a series of mp\_int data types to be made available simultaneously.  
+The purpose of algorithm mp\_init\_multi is to initialize a variable length array of mp\_int structures in a single
+statement.  It is essentially a shortcut to multiple initializations.
+
+\newpage\begin{figure}[here]
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{mp\_init\_multi}. \\
+\textbf{Input}.   Variable length array $V_k$ of mp\_int variables of length $k$. \\
+\textbf{Output}.  The array is initialized such that each mp\_int of $V_k$ is ready to use. \\
+\hline \\
+1.  for $n$ from 0 to $k - 1$ do \\
+\hspace{+3mm}1.1.  Initialize the mp\_int $V_n$ (\textit{mp\_init}) \\
+\hspace{+3mm}1.2.  If initialization failed then do \\
+\hspace{+6mm}1.2.1.  for $j$ from $0$ to $n$ do \\
+\hspace{+9mm}1.2.1.1.  Free the mp\_int $V_j$ (\textit{mp\_clear}) \\
+\hspace{+6mm}1.2.2.   Return(\textit{MP\_MEM}) \\
+2.  Return(\textit{MP\_OKAY}) \\
+\hline
+\end{tabular}
+\end{center}
+\caption{Algorithm mp\_init\_multi}
+\end{figure}
+
+\textbf{Algorithm mp\_init\_multi.}
+The algorithm will initialize the array of mp\_int variables one at a time.  If a runtime error has been detected 
+(\textit{step 1.2}) all of the previously initialized variables are cleared.  The goal is an ``all or nothing'' 
+initialization which allows for quick recovery from runtime errors.
+
+EXAM,bn_mp_init_multi.c
+
+This function intializes a variable length list of mp\_int structure pointers.  However, instead of having the mp\_int
+structures in an actual C array they are simply passed as arguments to the function.  This function makes use of the 
+``...'' argument syntax of the C programming language.  The list is terminated with a final \textbf{NULL} argument 
+appended on the right.  
+
+The function uses the ``stdarg.h'' \textit{va} functions to step portably through the arguments to the function.  A count
+$n$ of succesfully initialized mp\_int structures is maintained (line @47,n++@) such that if a failure does occur,
+the algorithm can backtrack and free the previously initialized structures (lines @27,if@ to @46,}@).  
+
+
+\subsection{Clamping Excess Digits}
+When a function anticipates a result will be $n$ digits it is simpler to assume this is true within the body of 
+the function instead of checking during the computation.  For example, a multiplication of a $i$ digit number by a 
+$j$ digit produces a result of at most $i + j$ digits.  It is entirely possible that the result is $i + j - 1$ 
+though, with no final carry into the last position.  However, suppose the destination had to be first expanded 
+(\textit{via mp\_grow}) to accomodate $i + j - 1$ digits than further expanded to accomodate the final carry.  
+That would be a considerable waste of time since heap operations are relatively slow.
+
+The ideal solution is to always assume the result is $i + j$ and fix up the \textbf{used} count after the function
+terminates.  This way a single heap operation (\textit{at most}) is required.  However, if the result was not checked
+there would be an excess high order zero digit.  
+
+For example, suppose the product of two integers was $x_n = (0x_{n-1}x_{n-2}...x_0)_{\beta}$.  The leading zero digit 
+will not contribute to the precision of the result.  In fact, through subsequent operations more leading zero digits would
+accumulate to the point the size of the integer would be prohibitive.  As a result even though the precision is very 
+low the representation is excessively large.  
+
+The mp\_clamp algorithm is designed to solve this very problem.  It will trim high-order zeros by decrementing the 
+\textbf{used} count until a non-zero most significant digit is found.  Also in this system, zero is considered to be a 
+positive number which means that if the \textbf{used} count is decremented to zero, the sign must be set to 
+\textbf{MP\_ZPOS}.
+
+\begin{figure}[here]
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{mp\_clamp}. \\
+\textbf{Input}.   An mp\_int $a$ \\
+\textbf{Output}.  Any excess leading zero digits of $a$ are removed \\
+\hline \\
+1.  while $a.used > 0$ and $a_{a.used - 1} = 0$ do \\
+\hspace{+3mm}1.1  $a.used \leftarrow a.used - 1$ \\
+2.  if $a.used = 0$ then do \\
+\hspace{+3mm}2.1  $a.sign \leftarrow MP\_ZPOS$ \\
+\hline \\
+\end{tabular}
+\end{center}
+\caption{Algorithm mp\_clamp}
+\end{figure}
+
+\textbf{Algorithm mp\_clamp.}
+As can be expected this algorithm is very simple.  The loop on step one is expected to iterate only once or twice at
+the most.  For example, this will happen in cases where there is not a carry to fill the last position.  Step two fixes the sign for 
+when all of the digits are zero to ensure that the mp\_int is valid at all times.
+
+EXAM,bn_mp_clamp.c
+
+Note on line @27,while@ how to test for the \textbf{used} count is made on the left of the \&\& operator.  In the C programming
+language the terms to \&\& are evaluated left to right with a boolean short-circuit if any condition fails.  This is 
+important since if the \textbf{used} is zero the test on the right would fetch below the array.  That is obviously 
+undesirable.  The parenthesis on line @28,a->used@ is used to make sure the \textbf{used} count is decremented and not
+the pointer ``a''.  
+
+\section*{Exercises}
+\begin{tabular}{cl}
+$\left [ 1 \right ]$ & Discuss the relevance of the \textbf{used} member of the mp\_int structure. \\
+                     & \\
+$\left [ 1 \right ]$ & Discuss the consequences of not using padding when performing allocations.  \\
+                     & \\
+$\left [ 2 \right ]$ & Estimate an ideal value for \textbf{MP\_PREC} when performing 1024-bit RSA \\
+                     & encryption when $\beta = 2^{28}$.  \\
+                     & \\
+$\left [ 1 \right ]$ & Discuss the relevance of the algorithm mp\_clamp.  What does it prevent? \\
+                     & \\
+$\left [ 1 \right ]$ & Give an example of when the algorithm  mp\_init\_copy might be useful. \\
+                     & \\
+\end{tabular}
+
+
+%%%
+% CHAPTER FOUR
+%%%
+
+\chapter{Basic Operations}
+
+\section{Introduction}
+In the previous chapter a series of low level algorithms were established that dealt with initializing and maintaining
+mp\_int structures.  This chapter will discuss another set of seemingly non-algebraic algorithms which will form the low 
+level basis of the entire library.  While these algorithm are relatively trivial it is important to understand how they
+work before proceeding since these algorithms will be used almost intrinsically in the following chapters.
+
+The algorithms in this chapter deal primarily with more ``programmer'' related tasks such as creating copies of
+mp\_int structures, assigning small values to mp\_int structures and comparisons of the values mp\_int structures
+represent.   
+
+\section{Assigning Values to mp\_int Structures}
+\subsection{Copying an mp\_int}
+Assigning the value that a given mp\_int structure represents to another mp\_int structure shall be known as making
+a copy for the purposes of this text.  The copy of the mp\_int will be a separate entity that represents the same
+value as the mp\_int it was copied from.  The mp\_copy algorithm provides this functionality. 
+
+\newpage\begin{figure}[here]
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{mp\_copy}. \\
+\textbf{Input}.  An mp\_int $a$ and $b$. \\
+\textbf{Output}.  Store a copy of $a$ in $b$. \\
+\hline \\
+1.  If $b.alloc < a.used$ then grow $b$ to $a.used$ digits.  (\textit{mp\_grow}) \\
+2.  for $n$ from 0 to $a.used - 1$ do \\
+\hspace{3mm}2.1  $b_{n} \leftarrow a_{n}$ \\
+3.  for $n$ from $a.used$ to $b.used - 1$ do \\
+\hspace{3mm}3.1  $b_{n} \leftarrow 0$ \\
+4.  $b.used \leftarrow a.used$ \\
+5.  $b.sign \leftarrow a.sign$ \\
+6.  return(\textit{MP\_OKAY}) \\
+\hline
+\end{tabular}
+\end{center}
+\caption{Algorithm mp\_copy}
+\end{figure}
+
+\textbf{Algorithm mp\_copy.}
+This algorithm copies the mp\_int $a$ such that upon succesful termination of the algorithm the mp\_int $b$ will
+represent the same integer as the mp\_int $a$.  The mp\_int $b$ shall be a complete and distinct copy of the 
+mp\_int $a$ meaing that the mp\_int $a$ can be modified and it shall not affect the value of the mp\_int $b$.
+
+If $b$ does not have enough room for the digits of $a$ it must first have its precision augmented via the mp\_grow 
+algorithm.  The digits of $a$ are copied over the digits of $b$ and any excess digits of $b$ are set to zero (step two
+and three).  The \textbf{used} and \textbf{sign} members of $a$ are finally copied over the respective members of
+$b$.
+
+\textbf{Remark.}  This algorithm also introduces a new idiosyncrasy that will be used throughout the rest of the
+text.  The error return codes of other algorithms are not explicitly checked in the pseudo-code presented.  For example, in 
+step one of the mp\_copy algorithm the return of mp\_grow is not explicitly checked to ensure it succeeded.  Text space is 
+limited so it is assumed that if a algorithm fails it will clear all temporarily allocated mp\_ints and return
+the error code itself.  However, the C code presented will demonstrate all of the error handling logic required to 
+implement the pseudo-code.
+
+EXAM,bn_mp_copy.c
+
+Occasionally a dependent algorithm may copy an mp\_int effectively into itself such as when the input and output
+mp\_int structures passed to a function are one and the same.  For this case it is optimal to return immediately without 
+copying digits (line @24,a == b@).  
+
+The mp\_int $b$ must have enough digits to accomodate the used digits of the mp\_int $a$.  If $b.alloc$ is less than
+$a.used$ the algorithm mp\_grow is used to augment the precision of $b$ (lines @29,alloc@ to @33,}@).  In order to
+simplify the inner loop that copies the digits from $a$ to $b$, two aliases $tmpa$ and $tmpb$ point directly at the digits
+of the mp\_ints $a$ and $b$ respectively.  These aliases (lines @42,tmpa@ and @45,tmpb@) allow the compiler to access the digits without first dereferencing the
+mp\_int pointers and then subsequently the pointer to the digits.  
+
+After the aliases are established the digits from $a$ are copied into $b$ (lines @48,for@ to @50,}@) and then the excess 
+digits of $b$ are set to zero (lines @53,for@ to @55,}@).  Both ``for'' loops make use of the pointer aliases and in 
+fact the alias for $b$ is carried through into the second ``for'' loop to clear the excess digits.  This optimization 
+allows the alias to stay in a machine register fairly easy between the two loops.
+
+\textbf{Remarks.}  The use of pointer aliases is an implementation methodology first introduced in this function that will
+be used considerably in other functions.  Technically, a pointer alias is simply a short hand alias used to lower the 
+number of pointer dereferencing operations required to access data.  For example, a for loop may resemble
+
+\begin{alltt}
+for (x = 0; x < 100; x++) \{
+    a->num[4]->dp[x] = 0;
+\}
+\end{alltt}
+
+This could be re-written using aliases as 
+
+\begin{alltt}
+mp_digit *tmpa;
+a = a->num[4]->dp;
+for (x = 0; x < 100; x++) \{
+    *a++ = 0;
+\}
+\end{alltt}
+
+In this case an alias is used to access the 
+array of digits within an mp\_int structure directly.  It may seem that a pointer alias is strictly not required 
+as a compiler may optimize out the redundant pointer operations.  However, there are two dominant reasons to use aliases.
+
+The first reason is that most compilers will not effectively optimize pointer arithmetic.  For example, some optimizations 
+may work for the Microsoft Visual C++ compiler (MSVC) and not for the GNU C Compiler (GCC).  Also some optimizations may 
+work for GCC and not MSVC.  As such it is ideal to find a common ground for as many compilers as possible.  Pointer 
+aliases optimize the code considerably before the compiler even reads the source code which means the end compiled code 
+stands a better chance of being faster.
+
+The second reason is that pointer aliases often can make an algorithm simpler to read.  Consider the first ``for'' 
+loop of the function mp\_copy() re-written to not use pointer aliases.
+
+\begin{alltt}
+    /* copy all the digits */
+    for (n = 0; n < a->used; n++) \{
+      b->dp[n] = a->dp[n];
+    \}
+\end{alltt}
+
+Whether this code is harder to read depends strongly on the individual.  However, it is quantifiably slightly more 
+complicated as there are four variables within the statement instead of just two.
+
+\subsubsection{Nested Statements}
+Another commonly used technique in the source routines is that certain sections of code are nested.  This is used in
+particular with the pointer aliases to highlight code phases.  For example, a Comba multiplier (discussed in chapter six)
+will typically have three different phases.  First the temporaries are initialized, then the columns calculated and 
+finally the carries are propagated.  In this example the middle column production phase will typically be nested as it
+uses temporary variables and aliases the most.
+
+The nesting also simplies the source code as variables that are nested are only valid for their scope.  As a result
+the various temporary variables required do not propagate into other sections of code.
+
+
+\subsection{Creating a Clone}
+Another common operation is to make a local temporary copy of an mp\_int argument.  To initialize an mp\_int 
+and then copy another existing mp\_int into the newly intialized mp\_int will be known as creating a clone.  This is 
+useful within functions that need to modify an argument but do not wish to actually modify the original copy.  The 
+mp\_init\_copy algorithm has been designed to help perform this task.
+
+\begin{figure}[here]
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{mp\_init\_copy}. \\
+\textbf{Input}.   An mp\_int $a$ and $b$\\
+\textbf{Output}.  $a$ is initialized to be a copy of $b$. \\
+\hline \\
+1.  Init $a$.  (\textit{mp\_init}) \\
+2.  Copy $b$ to $a$.  (\textit{mp\_copy}) \\
+3.  Return the status of the copy operation. \\
+\hline
+\end{tabular}
+\end{center}
+\caption{Algorithm mp\_init\_copy}
+\end{figure}
+
+\textbf{Algorithm mp\_init\_copy.}
+This algorithm will initialize an mp\_int variable and copy another previously initialized mp\_int variable into it.  As 
+such this algorithm will perform two operations in one step.  
+
+EXAM,bn_mp_init_copy.c
+
+This will initialize \textbf{a} and make it a verbatim copy of the contents of \textbf{b}.  Note that 
+\textbf{a} will have its own memory allocated which means that \textbf{b} may be cleared after the call
+and \textbf{a} will be left intact.  
+
+\section{Zeroing an Integer}
+Reseting an mp\_int to the default state is a common step in many algorithms.  The mp\_zero algorithm will be the algorithm used to
+perform this task.
+
+\begin{figure}[here]
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{mp\_zero}. \\
+\textbf{Input}.   An mp\_int $a$ \\
+\textbf{Output}.  Zero the contents of $a$ \\
+\hline \\
+1.  $a.used \leftarrow 0$ \\
+2.  $a.sign \leftarrow$ MP\_ZPOS \\
+3.  for $n$ from 0 to $a.alloc - 1$ do \\
+\hspace{3mm}3.1  $a_n \leftarrow 0$ \\
+\hline
+\end{tabular}
+\end{center}
+\caption{Algorithm mp\_zero}
+\end{figure}
+
+\textbf{Algorithm mp\_zero.}
+This algorithm simply resets a mp\_int to the default state.  
+
+EXAM,bn_mp_zero.c
+
+After the function is completed, all of the digits are zeroed, the \textbf{used} count is zeroed and the 
+\textbf{sign} variable is set to \textbf{MP\_ZPOS}.
+
+\section{Sign Manipulation}
+\subsection{Absolute Value}
+With the mp\_int representation of an integer, calculating the absolute value is trivial.  The mp\_abs algorithm will compute
+the absolute value of an mp\_int.
+
+\begin{figure}[here]
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{mp\_abs}. \\
+\textbf{Input}.   An mp\_int $a$ \\
+\textbf{Output}.  Computes $b = \vert a \vert$ \\
+\hline \\
+1.  Copy $a$ to $b$.  (\textit{mp\_copy}) \\
+2.  If the copy failed return(\textit{MP\_MEM}). \\
+3.  $b.sign \leftarrow MP\_ZPOS$ \\
+4.  Return(\textit{MP\_OKAY}) \\
+\hline
+\end{tabular}
+\end{center}
+\caption{Algorithm mp\_abs}
+\end{figure}
+
+\textbf{Algorithm mp\_abs.}
+This algorithm computes the absolute of an mp\_int input.  First it copies $a$ over $b$.  This is an example of an
+algorithm where the check in mp\_copy that determines if the source and destination are equal proves useful.  This allows,
+for instance, the developer to pass the same mp\_int as the source and destination to this function without addition 
+logic to handle it.
+
+EXAM,bn_mp_abs.c
+
+This fairly trivial algorithm first eliminates non--required duplications (line @27,a != b@) and then sets the
+\textbf{sign} flag to \textbf{MP\_ZPOS}.
+
+\subsection{Integer Negation}
+With the mp\_int representation of an integer, calculating the negation is also trivial.  The mp\_neg algorithm will compute
+the negative of an mp\_int input.
+
+\begin{figure}[here]
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{mp\_neg}. \\
+\textbf{Input}.   An mp\_int $a$ \\
+\textbf{Output}.  Computes $b = -a$ \\
+\hline \\
+1.  Copy $a$ to $b$.  (\textit{mp\_copy}) \\
+2.  If the copy failed return(\textit{MP\_MEM}). \\
+3.  If $a.used = 0$ then return(\textit{MP\_OKAY}). \\
+4.  If $a.sign = MP\_ZPOS$ then do \\
+\hspace{3mm}4.1  $b.sign = MP\_NEG$. \\
+5.  else do \\
+\hspace{3mm}5.1  $b.sign = MP\_ZPOS$. \\
+6.  Return(\textit{MP\_OKAY}) \\
+\hline
+\end{tabular}
+\end{center}
+\caption{Algorithm mp\_neg}
+\end{figure}
+
+\textbf{Algorithm mp\_neg.}
+This algorithm computes the negation of an input.  First it copies $a$ over $b$.  If $a$ has no used digits then
+the algorithm returns immediately.  Otherwise it flips the sign flag and stores the result in $b$.  Note that if 
+$a$ had no digits then it must be positive by definition.  Had step three been omitted then the algorithm would return
+zero as negative.
+
+EXAM,bn_mp_neg.c
+
+Like mp\_abs() this function avoids non--required duplications (line @21,a != b@) and then sets the sign.  We
+have to make sure that only non--zero values get a \textbf{sign} of \textbf{MP\_NEG}.  If the mp\_int is zero
+than the \textbf{sign} is hard--coded to \textbf{MP\_ZPOS}.
+
+\section{Small Constants}
+\subsection{Setting Small Constants}
+Often a mp\_int must be set to a relatively small value such as $1$ or $2$.  For these cases the mp\_set algorithm is useful.
+
+\newpage\begin{figure}[here]
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{mp\_set}. \\
+\textbf{Input}.   An mp\_int $a$ and a digit $b$ \\
+\textbf{Output}.  Make $a$ equivalent to $b$ \\
+\hline \\
+1.  Zero $a$ (\textit{mp\_zero}). \\
+2.  $a_0 \leftarrow b \mbox{ (mod }\beta\mbox{)}$ \\
+3.  $a.used \leftarrow  \left \lbrace \begin{array}{ll}
+                              1 &  \mbox{if }a_0 > 0 \\
+                              0 &  \mbox{if }a_0 = 0 
+                              \end{array} \right .$ \\
+\hline                              
+\end{tabular}
+\end{center}
+\caption{Algorithm mp\_set}
+\end{figure}
+
+\textbf{Algorithm mp\_set.}
+This algorithm sets a mp\_int to a small single digit value.  Step number 1 ensures that the integer is reset to the default state.  The
+single digit is set (\textit{modulo $\beta$}) and the \textbf{used} count is adjusted accordingly.
+
+EXAM,bn_mp_set.c
+
+First we zero (line @21,mp_zero@) the mp\_int to make sure that the other members are initialized for a 
+small positive constant.  mp\_zero() ensures that the \textbf{sign} is positive and the \textbf{used} count
+is zero.  Next we set the digit and reduce it modulo $\beta$ (line @22,MP_MASK@).  After this step we have to 
+check if the resulting digit is zero or not.  If it is not then we set the \textbf{used} count to one, otherwise
+to zero.
+
+We can quickly reduce modulo $\beta$ since it is of the form $2^k$ and a quick binary AND operation with 
+$2^k - 1$ will perform the same operation.
+
+One important limitation of this function is that it will only set one digit.  The size of a digit is not fixed, meaning source that uses 
+this function should take that into account.  Only trivially small constants can be set using this function.
+
+\subsection{Setting Large Constants}
+To overcome the limitations of the mp\_set algorithm the mp\_set\_int algorithm is ideal.  It accepts a ``long''
+data type as input and will always treat it as a 32-bit integer.
+
+\begin{figure}[here]
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{mp\_set\_int}. \\
+\textbf{Input}.   An mp\_int $a$ and a ``long'' integer $b$ \\
+\textbf{Output}.  Make $a$ equivalent to $b$ \\
+\hline \\
+1.  Zero $a$ (\textit{mp\_zero}) \\
+2.  for $n$ from 0 to 7 do \\
+\hspace{3mm}2.1  $a \leftarrow a \cdot 16$ (\textit{mp\_mul2d}) \\
+\hspace{3mm}2.2  $u \leftarrow \lfloor b / 2^{4(7 - n)} \rfloor \mbox{ (mod }16\mbox{)}$\\
+\hspace{3mm}2.3  $a_0 \leftarrow a_0 + u$ \\
+\hspace{3mm}2.4  $a.used \leftarrow a.used + 1$ \\
+3.  Clamp excess used digits (\textit{mp\_clamp}) \\
+\hline
+\end{tabular}
+\end{center}
+\caption{Algorithm mp\_set\_int}
+\end{figure}
+
+\textbf{Algorithm mp\_set\_int.}
+The algorithm performs eight iterations of a simple loop where in each iteration four bits from the source are added to the 
+mp\_int.  Step 2.1 will multiply the current result by sixteen making room for four more bits in the less significant positions.  In step 2.2 the
+next four bits from the source are extracted and are added to the mp\_int. The \textbf{used} digit count is 
+incremented to reflect the addition.  The \textbf{used} digit counter is incremented since if any of the leading digits were zero the mp\_int would have
+zero digits used and the newly added four bits would be ignored.
+
+Excess zero digits are trimmed in steps 2.1 and 3 by using higher level algorithms mp\_mul2d and mp\_clamp.
+
+EXAM,bn_mp_set_int.c
+
+This function sets four bits of the number at a time to handle all practical \textbf{DIGIT\_BIT} sizes.  The weird
+addition on line @38,a->used@ ensures that the newly added in bits are added to the number of digits.  While it may not 
+seem obvious as to why the digit counter does not grow exceedingly large it is because of the shift on line @27,mp_mul_2d@ 
+as well as the  call to mp\_clamp() on line @40,mp_clamp@.  Both functions will clamp excess leading digits which keeps 
+the number of used digits low.
+
+\section{Comparisons}
+\subsection{Unsigned Comparisions}
+Comparing a multiple precision integer is performed with the exact same algorithm used to compare two decimal numbers.  For example,
+to compare $1,234$ to $1,264$ the digits are extracted by their positions.  That is we compare $1 \cdot 10^3 + 2 \cdot 10^2 + 3 \cdot 10^1 + 4 \cdot 10^0$
+to $1 \cdot 10^3 + 2 \cdot 10^2 + 6 \cdot 10^1 + 4 \cdot 10^0$ by comparing single digits at a time starting with the highest magnitude 
+positions.  If any leading digit of one integer is greater than a digit in the same position of another integer then obviously it must be greater.  
+
+The first comparision routine that will be developed is the unsigned magnitude compare which will perform a comparison based on the digits of two
+mp\_int variables alone.  It will ignore the sign of the two inputs.  Such a function is useful when an absolute comparison is required or if the 
+signs are known to agree in advance.
+
+To facilitate working with the results of the comparison functions three constants are required.  
+
+\begin{figure}[here]
+\begin{center}
+\begin{tabular}{|r|l|}
+\hline \textbf{Constant} & \textbf{Meaning} \\
+\hline \textbf{MP\_GT} & Greater Than \\
+\hline \textbf{MP\_EQ} & Equal To \\
+\hline \textbf{MP\_LT} & Less Than \\
+\hline
+\end{tabular}
+\end{center}
+\caption{Comparison Return Codes}
+\end{figure}
+
+\begin{figure}[here]
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{mp\_cmp\_mag}. \\
+\textbf{Input}.   Two mp\_ints $a$ and $b$.  \\
+\textbf{Output}.  Unsigned comparison results ($a$ to the left of $b$). \\
+\hline \\
+1.  If $a.used > b.used$ then return(\textit{MP\_GT}) \\
+2.  If $a.used < b.used$ then return(\textit{MP\_LT}) \\
+3.  for n from $a.used - 1$ to 0 do \\
+\hspace{+3mm}3.1  if $a_n > b_n$ then return(\textit{MP\_GT}) \\
+\hspace{+3mm}3.2  if $a_n < b_n$ then return(\textit{MP\_LT}) \\
+4.  Return(\textit{MP\_EQ}) \\
+\hline
+\end{tabular}
+\end{center}
+\caption{Algorithm mp\_cmp\_mag}
+\end{figure}
+
+\textbf{Algorithm mp\_cmp\_mag.}
+By saying ``$a$ to the left of $b$'' it is meant that the comparison is with respect to $a$, that is if $a$ is greater than $b$ it will return
+\textbf{MP\_GT} and similar with respect to when $a = b$ and $a < b$.  The first two steps compare the number of digits used in both $a$ and $b$.  
+Obviously if the digit counts differ there would be an imaginary zero digit in the smaller number where the leading digit of the larger number is.  
+If both have the same number of digits than the actual digits themselves must be compared starting at the leading digit.  
+
+By step three both inputs must have the same number of digits so its safe to start from either $a.used - 1$ or $b.used - 1$ and count down to
+the zero'th digit.  If after all of the digits have been compared, no difference is found, the algorithm returns \textbf{MP\_EQ}.
+
+EXAM,bn_mp_cmp_mag.c
+
+The two if statements (lines @24,if@ and @28,if@) compare the number of digits in the two inputs.  These two are 
+performed before all of the digits are compared since it is a very cheap test to perform and can potentially save 
+considerable time.  The implementation given is also not valid without those two statements.  $b.alloc$ may be 
+smaller than $a.used$, meaning that undefined values will be read from $b$ past the end of the array of digits.
+
+
+
+\subsection{Signed Comparisons}
+Comparing with sign considerations is also fairly critical in several routines (\textit{division for example}).  Based on an unsigned magnitude 
+comparison a trivial signed comparison algorithm can be written.
+
+\begin{figure}[here]
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{mp\_cmp}. \\
+\textbf{Input}.   Two mp\_ints $a$ and $b$ \\
+\textbf{Output}.  Signed Comparison Results ($a$ to the left of $b$) \\
+\hline \\
+1.  if $a.sign = MP\_NEG$ and $b.sign = MP\_ZPOS$ then return(\textit{MP\_LT}) \\
+2.  if $a.sign = MP\_ZPOS$ and $b.sign = MP\_NEG$ then return(\textit{MP\_GT}) \\
+3.  if $a.sign = MP\_NEG$ then \\
+\hspace{+3mm}3.1  Return the unsigned comparison of $b$ and $a$ (\textit{mp\_cmp\_mag}) \\
+4   Otherwise \\
+\hspace{+3mm}4.1  Return the unsigned comparison of $a$ and $b$ \\
+\hline
+\end{tabular}
+\end{center}
+\caption{Algorithm mp\_cmp}
+\end{figure}
+
+\textbf{Algorithm mp\_cmp.}
+The first two steps compare the signs of the two inputs.  If the signs do not agree then it can return right away with the appropriate 
+comparison code.  When the signs are equal the digits of the inputs must be compared to determine the correct result.  In step 
+three the unsigned comparision flips the order of the arguments since they are both negative.  For instance, if $-a > -b$ then 
+$\vert a \vert < \vert b \vert$.  Step number four will compare the two when they are both positive.
+
+EXAM,bn_mp_cmp.c
+
+The two if statements (lines @22,if@ and @26,if@) perform the initial sign comparison.  If the signs are not the equal then which ever
+has the positive sign is larger.   The inputs are compared (line @30,if@) based on magnitudes.  If the signs were both 
+negative then the unsigned comparison is performed in the opposite direction (line @31,mp_cmp_mag@).  Otherwise, the signs are assumed to 
+be both positive and a forward direction unsigned comparison is performed.
+
+\section*{Exercises}
+\begin{tabular}{cl}
+$\left [ 2 \right ]$ & Modify algorithm mp\_set\_int to accept as input a variable length array of bits. \\
+                     & \\
+$\left [ 3 \right ]$ & Give the probability that algorithm mp\_cmp\_mag will have to compare $k$ digits  \\
+                     & of two random digits (of equal magnitude) before a difference is found. \\
+                     & \\
+$\left [ 1 \right ]$ & Suggest a simple method to speed up the implementation of mp\_cmp\_mag based  \\
+                     & on the observations made in the previous problem. \\
+                     &
+\end{tabular}
+
+\chapter{Basic Arithmetic}
+\section{Introduction}
+At this point algorithms for initialization, clearing, zeroing, copying, comparing and setting small constants have been 
+established.  The next logical set of algorithms to develop are addition, subtraction and digit shifting algorithms.  These 
+algorithms make use of the lower level algorithms and are the cruicial building block for the multiplication algorithms.  It is very important 
+that these algorithms are highly optimized.  On their own they are simple $O(n)$ algorithms but they can be called from higher level algorithms 
+which easily places them at $O(n^2)$ or even $O(n^3)$ work levels.  
+
+MARK,SHIFTS
+All of the algorithms within this chapter make use of the logical bit shift operations denoted by $<<$ and $>>$ for left and right 
+logical shifts respectively.  A logical shift is analogous to sliding the decimal point of radix-10 representations.  For example, the real 
+number $0.9345$ is equivalent to $93.45\%$ which is found by sliding the the decimal two places to the right (\textit{multiplying by $\beta^2 = 10^2$}).  
+Algebraically a binary logical shift is equivalent to a division or multiplication by a power of two.  
+For example, $a << k = a \cdot 2^k$ while $a >> k = \lfloor a/2^k \rfloor$.
+
+One significant difference between a logical shift and the way decimals are shifted is that digits below the zero'th position are removed
+from the number.  For example, consider $1101_2 >> 1$ using decimal notation this would produce $110.1_2$.  However, with a logical shift the 
+result is $110_2$.  
+
+\section{Addition and Subtraction}
+In common twos complement fixed precision arithmetic negative numbers are easily represented by subtraction from the modulus.  For example, with 32-bit integers
+$a - b\mbox{ (mod }2^{32}\mbox{)}$ is the same as $a + (2^{32} - b) \mbox{ (mod }2^{32}\mbox{)}$  since $2^{32} \equiv 0 \mbox{ (mod }2^{32}\mbox{)}$.  
+As a result subtraction can be performed with a trivial series of logical operations and an addition.
+
+However, in multiple precision arithmetic negative numbers are not represented in the same way.  Instead a sign flag is used to keep track of the
+sign of the integer.  As a result signed addition and subtraction are actually implemented as conditional usage of lower level addition or 
+subtraction algorithms with the sign fixed up appropriately.
+
+The lower level algorithms will add or subtract integers without regard to the sign flag.  That is they will add or subtract the magnitude of
+the integers respectively.
+
+\subsection{Low Level Addition}
+An unsigned addition of multiple precision integers is performed with the same long-hand algorithm used to add decimal numbers.  That is to add the 
+trailing digits first and propagate the resulting carry upwards.  Since this is a lower level algorithm the name will have a ``s\_'' prefix.  
+Historically that convention stems from the MPI library where ``s\_'' stood for static functions that were hidden from the developer entirely.
+
+\newpage
+\begin{figure}[!here]
+\begin{center}
+\begin{small}
+\begin{tabular}{l}
+\hline Algorithm \textbf{s\_mp\_add}. \\
+\textbf{Input}.   Two mp\_ints $a$ and $b$ \\
+\textbf{Output}.  The unsigned addition $c = \vert a \vert + \vert b \vert$. \\
+\hline \\
+1.  if $a.used > b.used$ then \\
+\hspace{+3mm}1.1  $min \leftarrow b.used$ \\
+\hspace{+3mm}1.2  $max \leftarrow a.used$ \\
+\hspace{+3mm}1.3  $x   \leftarrow a$ \\
+2.  else  \\
+\hspace{+3mm}2.1  $min \leftarrow a.used$ \\
+\hspace{+3mm}2.2  $max \leftarrow b.used$ \\
+\hspace{+3mm}2.3  $x   \leftarrow b$ \\
+3.  If $c.alloc < max + 1$ then grow $c$ to hold at least $max + 1$ digits (\textit{mp\_grow}) \\
+4.  $oldused \leftarrow c.used$ \\
+5.  $c.used \leftarrow max + 1$ \\
+6.  $u \leftarrow 0$ \\
+7.  for $n$ from $0$ to $min - 1$ do \\
+\hspace{+3mm}7.1  $c_n \leftarrow a_n + b_n + u$ \\
+\hspace{+3mm}7.2  $u \leftarrow c_n >> lg(\beta)$ \\
+\hspace{+3mm}7.3  $c_n \leftarrow c_n \mbox{ (mod }\beta\mbox{)}$ \\
+8.  if $min \ne max$ then do \\
+\hspace{+3mm}8.1  for $n$ from $min$ to $max - 1$ do \\
+\hspace{+6mm}8.1.1  $c_n \leftarrow x_n + u$ \\
+\hspace{+6mm}8.1.2  $u \leftarrow c_n >> lg(\beta)$ \\
+\hspace{+6mm}8.1.3  $c_n \leftarrow c_n \mbox{ (mod }\beta\mbox{)}$ \\
+9.  $c_{max} \leftarrow u$ \\
+10.  if $olduse > max$ then \\
+\hspace{+3mm}10.1  for $n$ from $max + 1$ to $oldused - 1$ do \\
+\hspace{+6mm}10.1.1  $c_n \leftarrow 0$ \\
+11.  Clamp excess digits in $c$.  (\textit{mp\_clamp}) \\
+12.  Return(\textit{MP\_OKAY}) \\
+\hline
+\end{tabular}
+\end{small}
+\end{center}
+\caption{Algorithm s\_mp\_add}
+\end{figure}
+
+\textbf{Algorithm s\_mp\_add.}
+This algorithm is loosely based on algorithm 14.7 of HAC \cite[pp. 594]{HAC} but has been extended to allow the inputs to have different magnitudes.  
+Coincidentally the description of algorithm A in Knuth \cite[pp. 266]{TAOCPV2} shares the same deficiency as the algorithm from \cite{HAC}.  Even the 
+MIX pseudo  machine code presented by Knuth \cite[pp. 266-267]{TAOCPV2} is incapable of handling inputs which are of different magnitudes.
+
+The first thing that has to be accomplished is to sort out which of the two inputs is the largest.  The addition logic
+will simply add all of the smallest input to the largest input and store that first part of the result in the
+destination.  Then it will apply a simpler addition loop to excess digits of the larger input.
+
+The first two steps will handle sorting the inputs such that $min$ and $max$ hold the digit counts of the two 
+inputs.  The variable $x$ will be an mp\_int alias for the largest input or the second input $b$ if they have the
+same number of digits.  After the inputs are sorted the destination $c$ is grown as required to accomodate the sum 
+of the two inputs.  The original \textbf{used} count of $c$ is copied and set to the new used count.  
+
+At this point the first addition loop will go through as many digit positions that both inputs have.  The carry
+variable $\mu$ is set to zero outside the loop.  Inside the loop an ``addition'' step requires three statements to produce
+one digit of the summand.  First
+two digits from $a$ and $b$ are added together along with the carry $\mu$.  The carry of this step is extracted and stored
+in $\mu$ and finally the digit of the result $c_n$ is truncated within the range $0 \le c_n < \beta$.
+
+Now all of the digit positions that both inputs have in common have been exhausted.  If $min \ne max$ then $x$ is an alias
+for one of the inputs that has more digits.  A simplified addition loop is then used to essentially copy the remaining digits
+and the carry to the destination.
+
+The final carry is stored in $c_{max}$ and digits above $max$ upto $oldused$ are zeroed which completes the addition.
+
+
+EXAM,bn_s_mp_add.c
+
+We first sort (lines @27,if@ to @35,}@) the inputs based on magnitude and determine the $min$ and $max$ variables.
+Note that $x$ is a pointer to an mp\_int assigned to the largest input, in effect it is a local alias.  Next we
+grow the destination (@37,init@ to @42,}@) ensure that it can accomodate the result of the addition. 
+
+Similar to the implementation of mp\_copy this function uses the braced code and local aliases coding style.  The three aliases that are on 
+lines @56,tmpa@, @59,tmpb@ and @62,tmpc@ represent the two inputs and destination variables respectively.  These aliases are used to ensure the
+compiler does not have to dereference $a$, $b$ or $c$ (respectively) to access the digits of the respective mp\_int.
+
+The initial carry $u$ will be cleared (line @65,u = 0@), note that $u$ is of type mp\_digit which ensures type 
+compatibility within the implementation.  The initial addition (line @66,for@ to @75,}@) adds digits from
+both inputs until the smallest input runs out of digits.  Similarly the conditional addition loop
+(line @81,for@ to @90,}@) adds the remaining digits from the larger of the two inputs.  The addition is finished 
+with the final carry being stored in $tmpc$ (line @94,tmpc++@).  Note the ``++'' operator within the same expression.
+After line @94,tmpc++@, $tmpc$ will point to the $c.used$'th digit of the mp\_int $c$.  This is useful
+for the next loop (line @97,for@ to @99,}@) which set any old upper digits to zero.
+
+\subsection{Low Level Subtraction}
+The low level unsigned subtraction algorithm is very similar to the low level unsigned addition algorithm.  The principle difference is that the
+unsigned subtraction algorithm requires the result to be positive.  That is when computing $a - b$ the condition $\vert a \vert \ge \vert b\vert$ must 
+be met for this algorithm to function properly.  Keep in mind this low level algorithm is not meant to be used in higher level algorithms directly.  
+This algorithm as will be shown can be used to create functional signed addition and subtraction algorithms.
+
+MARK,GAMMA
+
+For this algorithm a new variable is required to make the description simpler.  Recall from section 1.3.1 that a mp\_digit must be able to represent
+the range $0 \le x < 2\beta$ for the algorithms to work correctly.  However, it is allowable that a mp\_digit represent a larger range of values.  For 
+this algorithm we will assume that the variable $\gamma$ represents the number of bits available in a 
+mp\_digit (\textit{this implies $2^{\gamma} > \beta$}).  
+
+For example, the default for LibTomMath is to use a ``unsigned long'' for the mp\_digit ``type'' while $\beta = 2^{28}$.  In ISO C an ``unsigned long''
+data type must be able to represent $0 \le x < 2^{32}$ meaning that in this case $\gamma \ge 32$.
+
+\newpage\begin{figure}[!here]
+\begin{center}
+\begin{small}
+\begin{tabular}{l}
+\hline Algorithm \textbf{s\_mp\_sub}. \\
+\textbf{Input}.   Two mp\_ints $a$ and $b$ ($\vert a \vert \ge \vert b \vert$) \\
+\textbf{Output}.  The unsigned subtraction $c = \vert a \vert - \vert b \vert$. \\
+\hline \\
+1.  $min \leftarrow b.used$ \\
+2.  $max \leftarrow a.used$ \\
+3.  If $c.alloc < max$ then grow $c$ to hold at least $max$ digits.  (\textit{mp\_grow}) \\
+4.  $oldused \leftarrow c.used$ \\ 
+5.  $c.used \leftarrow max$ \\
+6.  $u \leftarrow 0$ \\
+7.  for $n$ from $0$ to $min - 1$ do \\
+\hspace{3mm}7.1  $c_n \leftarrow a_n - b_n - u$ \\
+\hspace{3mm}7.2  $u   \leftarrow c_n >> (\gamma - 1)$ \\
+\hspace{3mm}7.3  $c_n \leftarrow c_n \mbox{ (mod }\beta\mbox{)}$ \\
+8.  if $min < max$ then do \\
+\hspace{3mm}8.1  for $n$ from $min$ to $max - 1$ do \\
+\hspace{6mm}8.1.1  $c_n \leftarrow a_n - u$ \\
+\hspace{6mm}8.1.2  $u   \leftarrow c_n >> (\gamma - 1)$ \\
+\hspace{6mm}8.1.3  $c_n \leftarrow c_n \mbox{ (mod }\beta\mbox{)}$ \\
+9. if $oldused > max$ then do \\
+\hspace{3mm}9.1  for $n$ from $max$ to $oldused - 1$ do \\
+\hspace{6mm}9.1.1  $c_n \leftarrow 0$ \\
+10. Clamp excess digits of $c$.  (\textit{mp\_clamp}). \\
+11. Return(\textit{MP\_OKAY}). \\
+\hline
+\end{tabular}
+\end{small}
+\end{center}
+\caption{Algorithm s\_mp\_sub}
+\end{figure}
+
+\textbf{Algorithm s\_mp\_sub.}
+This algorithm performs the unsigned subtraction of two mp\_int variables under the restriction that the result must be positive.  That is when
+passing variables $a$ and $b$ the condition that $\vert a \vert \ge \vert b \vert$ must be met for the algorithm to function correctly.  This
+algorithm is loosely based on algorithm 14.9 \cite[pp. 595]{HAC} and is similar to algorithm S in \cite[pp. 267]{TAOCPV2} as well.  As was the case
+of the algorithm s\_mp\_add both other references lack discussion concerning various practical details such as when the inputs differ in magnitude.
+
+The initial sorting of the inputs is trivial in this algorithm since $a$ is guaranteed to have at least the same magnitude of $b$.  Steps 1 and 2 
+set the $min$ and $max$ variables.  Unlike the addition routine there is guaranteed to be no carry which means that the final result can be at 
+most $max$ digits in length as opposed to $max + 1$.  Similar to the addition algorithm the \textbf{used} count of $c$ is copied locally and 
+set to the maximal count for the operation.
+
+The subtraction loop that begins on step seven is essentially the same as the addition loop of algorithm s\_mp\_add except single precision 
+subtraction is used instead.  Note the use of the $\gamma$ variable to extract the carry (\textit{also known as the borrow}) within the subtraction 
+loops.  Under the assumption that two's complement single precision arithmetic is used this will successfully extract the desired carry.  
+
+For example, consider subtracting $0101_2$ from $0100_2$ where $\gamma = 4$ and $\beta = 2$.  The least significant bit will force a carry upwards to 
+the third bit which will be set to zero after the borrow.  After the very first bit has been subtracted $4 - 1 \equiv 0011_2$ will remain,  When the 
+third bit of $0101_2$ is subtracted from the result it will cause another carry.  In this case though the carry will be forced to propagate all the 
+way to the most significant bit.  
+
+Recall that $\beta < 2^{\gamma}$.  This means that if a carry does occur just before the $lg(\beta)$'th bit it will propagate all the way to the most 
+significant bit.  Thus, the high order bits of the mp\_digit that are not part of the actual digit will either be all zero, or all one. All that
+is needed is a single zero or one bit for the carry.  Therefore a single logical shift right by $\gamma - 1$ positions is sufficient to extract the 
+carry.  This method of carry extraction may seem awkward but the reason for it becomes apparent when the implementation is discussed.  
+
+If $b$ has a smaller magnitude than $a$ then step 9 will force the carry and copy operation to propagate through the larger input $a$ into $c$.  Step
+10 will ensure that any leading digits of $c$ above the $max$'th position are zeroed.
+
+EXAM,bn_s_mp_sub.c
+
+Like low level addition we ``sort'' the inputs.  Except in this case the sorting is hardcoded 
+(lines @24,min@ and @25,max@).  In reality the $min$ and $max$ variables are only aliases and are only 
+used to make the source code easier to read.  Again the pointer alias optimization is used 
+within this algorithm.  The aliases $tmpa$, $tmpb$ and $tmpc$ are initialized
+(lines @42,tmpa@, @43,tmpb@ and @44,tmpc@) for $a$, $b$ and $c$ respectively.
+
+The first subtraction loop (lines @47,u = 0@ through @61,}@) subtract digits from both inputs until the smaller of
+the two inputs has been exhausted.  As remarked earlier there is an implementation reason for using the ``awkward'' 
+method of extracting the carry (line @57, >>@).  The traditional method for extracting the carry would be to shift 
+by $lg(\beta)$ positions and logically AND the least significant bit.  The AND operation is required because all of 
+the bits above the $\lg(\beta)$'th bit will be set to one after a carry occurs from subtraction.  This carry 
+extraction requires two relatively cheap operations to extract the carry.  The other method is to simply shift the 
+most significant bit to the least significant bit thus extracting the carry with a single cheap operation.  This 
+optimization only works on twos compliment machines which is a safe assumption to make.
+
+If $a$ has a larger magnitude than $b$ an additional loop (lines @64,for@ through @73,}@) is required to propagate 
+the carry through $a$ and copy the result to $c$.  
+
+\subsection{High Level Addition}
+Now that both lower level addition and subtraction algorithms have been established an effective high level signed addition algorithm can be
+established.  This high level addition algorithm will be what other algorithms and developers will use to perform addition of mp\_int data 
+types.  
+
+Recall from section 5.2 that an mp\_int represents an integer with an unsigned mantissa (\textit{the array of digits}) and a \textbf{sign} 
+flag.  A high level addition is actually performed as a series of eight separate cases which can be optimized down to three unique cases.
+
+\begin{figure}[!here]
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{mp\_add}. \\
+\textbf{Input}.   Two mp\_ints $a$ and $b$  \\
+\textbf{Output}.  The signed addition $c = a + b$. \\
+\hline \\
+1.  if $a.sign = b.sign$ then do \\
+\hspace{3mm}1.1  $c.sign \leftarrow a.sign$  \\
+\hspace{3mm}1.2  $c \leftarrow \vert a \vert + \vert b \vert$ (\textit{s\_mp\_add})\\
+2.  else do \\
+\hspace{3mm}2.1  if $\vert a \vert < \vert b \vert$ then do (\textit{mp\_cmp\_mag})  \\
+\hspace{6mm}2.1.1  $c.sign \leftarrow b.sign$ \\
+\hspace{6mm}2.1.2  $c \leftarrow \vert b \vert - \vert a \vert$ (\textit{s\_mp\_sub}) \\
+\hspace{3mm}2.2  else do \\
+\hspace{6mm}2.2.1  $c.sign \leftarrow a.sign$ \\
+\hspace{6mm}2.2.2  $c \leftarrow \vert a \vert - \vert b \vert$ \\
+3.  Return(\textit{MP\_OKAY}). \\
+\hline
+\end{tabular}
+\end{center}
+\caption{Algorithm mp\_add}
+\end{figure}
+
+\textbf{Algorithm mp\_add.}
+This algorithm performs the signed addition of two mp\_int variables.  There is no reference algorithm to draw upon from 
+either \cite{TAOCPV2} or \cite{HAC} since they both only provide unsigned operations.  The algorithm is fairly 
+straightforward but restricted since subtraction can only produce positive results.
+
+\begin{figure}[here]
+\begin{small}
+\begin{center}
+\begin{tabular}{|c|c|c|c|c|}
+\hline \textbf{Sign of $a$} & \textbf{Sign of $b$} & \textbf{$\vert a \vert > \vert b \vert $} & \textbf{Unsigned Operation} & \textbf{Result Sign Flag} \\
+\hline $+$ & $+$ & Yes & $c = a + b$ & $a.sign$ \\
+\hline $+$ & $+$ & No  & $c = a + b$ & $a.sign$ \\
+\hline $-$ & $-$ & Yes & $c = a + b$ & $a.sign$ \\
+\hline $-$ & $-$ & No  & $c = a + b$ & $a.sign$ \\
+\hline &&&&\\
+
+\hline $+$ & $-$ & No  & $c = b - a$ & $b.sign$ \\
+\hline $-$ & $+$ & No  & $c = b - a$ & $b.sign$ \\
+
+\hline &&&&\\
+
+\hline $+$ & $-$ & Yes & $c = a - b$ & $a.sign$ \\
+\hline $-$ & $+$ & Yes & $c = a - b$ & $a.sign$ \\
+
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Addition Guide Chart}
+\label{fig:AddChart}
+\end{figure}
+
+Figure~\ref{fig:AddChart} lists all of the eight possible input combinations and is sorted to show that only three 
+specific cases need to be handled.  The return code of the unsigned operations at step 1.2, 2.1.2 and 2.2.2 are 
+forwarded to step three to check for errors.  This simplifies the description of the algorithm considerably and best 
+follows how the implementation actually was achieved.
+
+Also note how the \textbf{sign} is set before the unsigned addition or subtraction is performed.  Recall from the descriptions of algorithms
+s\_mp\_add and s\_mp\_sub that the mp\_clamp function is used at the end to trim excess digits.  The mp\_clamp algorithm will set the \textbf{sign}
+to \textbf{MP\_ZPOS} when the \textbf{used} digit count reaches zero.
+
+For example, consider performing $-a + a$ with algorithm mp\_add.  By the description of the algorithm the sign is set to \textbf{MP\_NEG} which would
+produce a result of $-0$.  However, since the sign is set first then the unsigned addition is performed the subsequent usage of algorithm mp\_clamp 
+within algorithm s\_mp\_add will force $-0$ to become $0$.  
+
+EXAM,bn_mp_add.c
+
+The source code follows the algorithm fairly closely.  The most notable new source code addition is the usage of the $res$ integer variable which
+is used to pass result of the unsigned operations forward.  Unlike in the algorithm, the variable $res$ is merely returned as is without
+explicitly checking it and returning the constant \textbf{MP\_OKAY}.  The observation is this algorithm will succeed or fail only if the lower
+level functions do so.  Returning their return code is sufficient.
+
+\subsection{High Level Subtraction}
+The high level signed subtraction algorithm is essentially the same as the high level signed addition algorithm.  
+
+\newpage\begin{figure}[!here]
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{mp\_sub}. \\
+\textbf{Input}.   Two mp\_ints $a$ and $b$  \\
+\textbf{Output}.  The signed subtraction $c = a - b$. \\
+\hline \\
+1.  if $a.sign \ne b.sign$ then do \\
+\hspace{3mm}1.1  $c.sign \leftarrow a.sign$ \\
+\hspace{3mm}1.2  $c \leftarrow \vert a \vert + \vert b \vert$ (\textit{s\_mp\_add}) \\
+2.  else do \\
+\hspace{3mm}2.1  if $\vert a \vert \ge \vert b \vert$ then do (\textit{mp\_cmp\_mag}) \\
+\hspace{6mm}2.1.1  $c.sign \leftarrow a.sign$ \\
+\hspace{6mm}2.1.2  $c \leftarrow \vert a \vert  - \vert b \vert$ (\textit{s\_mp\_sub}) \\
+\hspace{3mm}2.2  else do \\
+\hspace{6mm}2.2.1  $c.sign \leftarrow  \left \lbrace \begin{array}{ll}
+                              MP\_ZPOS &  \mbox{if }a.sign = MP\_NEG \\
+                              MP\_NEG  &  \mbox{otherwise} \\
+                              \end{array} \right .$ \\
+\hspace{6mm}2.2.2  $c \leftarrow \vert b \vert  - \vert a \vert$ \\
+3.  Return(\textit{MP\_OKAY}). \\
+\hline
+\end{tabular}
+\end{center}
+\caption{Algorithm mp\_sub}
+\end{figure}
+
+\textbf{Algorithm mp\_sub.}
+This algorithm performs the signed subtraction of two inputs.  Similar to algorithm mp\_add there is no reference in either \cite{TAOCPV2} or 
+\cite{HAC}.  Also this algorithm is restricted by algorithm s\_mp\_sub.  Chart \ref{fig:SubChart} lists the eight possible inputs and
+the operations required.
+
+\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{|c|c|c|c|c|}
+\hline \textbf{Sign of $a$} & \textbf{Sign of $b$} & \textbf{$\vert a \vert \ge \vert b \vert $} & \textbf{Unsigned Operation} & \textbf{Result Sign Flag} \\
+\hline $+$ & $-$ & Yes & $c = a + b$ & $a.sign$ \\
+\hline $+$ & $-$ & No  & $c = a + b$ & $a.sign$ \\
+\hline $-$ & $+$ & Yes & $c = a + b$ & $a.sign$ \\
+\hline $-$ & $+$ & No  & $c = a + b$ & $a.sign$ \\
+\hline &&&& \\
+\hline $+$ & $+$ & Yes & $c = a - b$ & $a.sign$ \\
+\hline $-$ & $-$ & Yes & $c = a - b$ & $a.sign$ \\
+\hline &&&& \\
+\hline $+$ & $+$ & No  & $c = b - a$ & $\mbox{opposite of }a.sign$ \\
+\hline $-$ & $-$ & No  & $c = b - a$ & $\mbox{opposite of }a.sign$ \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Subtraction Guide Chart}
+\label{fig:SubChart}
+\end{figure}
+
+Similar to the case of algorithm mp\_add the \textbf{sign} is set first before the unsigned addition or subtraction.  That is to prevent the 
+algorithm from producing $-a - -a = -0$ as a result.  
+
+EXAM,bn_mp_sub.c
+
+Much like the implementation of algorithm mp\_add the variable $res$ is used to catch the return code of the unsigned addition or subtraction operations
+and forward it to the end of the function.  On line @38, != MP_LT@ the ``not equal to'' \textbf{MP\_LT} expression is used to emulate a 
+``greater than or equal to'' comparison.  
+
+\section{Bit and Digit Shifting}
+MARK,POLY
+It is quite common to think of a multiple precision integer as a polynomial in $x$, that is $y = f(\beta)$ where $f(x) = \sum_{i=0}^{n-1} a_i x^i$.  
+This notation arises within discussion of Montgomery and Diminished Radix Reduction as well as Karatsuba multiplication and squaring.  
+
+In order to facilitate operations on polynomials in $x$ as above a series of simple ``digit'' algorithms have to be established.  That is to shift
+the digits left or right as well to shift individual bits of the digits left and right.  It is important to note that not all ``shift'' operations
+are on radix-$\beta$ digits.  
+
+\subsection{Multiplication by Two}
+
+In a binary system where the radix is a power of two multiplication by two not only arises often in other algorithms it is a fairly efficient 
+operation to perform.  A single precision logical shift left is sufficient to multiply a single digit by two.  
+
+\newpage\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{mp\_mul\_2}. \\
+\textbf{Input}.   One mp\_int $a$ \\
+\textbf{Output}.  $b = 2a$. \\
+\hline \\
+1.  If $b.alloc < a.used + 1$ then grow $b$ to hold $a.used + 1$ digits.  (\textit{mp\_grow}) \\
+2.  $oldused \leftarrow b.used$ \\
+3.  $b.used \leftarrow a.used$ \\
+4.  $r \leftarrow 0$ \\
+5.  for $n$ from 0 to $a.used - 1$ do \\
+\hspace{3mm}5.1  $rr \leftarrow a_n >> (lg(\beta) - 1)$ \\
+\hspace{3mm}5.2  $b_n \leftarrow (a_n << 1) + r \mbox{ (mod }\beta\mbox{)}$ \\
+\hspace{3mm}5.3  $r \leftarrow rr$ \\
+6.  If $r \ne 0$ then do \\
+\hspace{3mm}6.1  $b_{n + 1} \leftarrow r$ \\
+\hspace{3mm}6.2  $b.used \leftarrow b.used + 1$ \\
+7.  If $b.used < oldused - 1$ then do \\
+\hspace{3mm}7.1  for $n$ from $b.used$ to $oldused - 1$ do \\
+\hspace{6mm}7.1.1  $b_n \leftarrow 0$ \\
+8.  $b.sign \leftarrow a.sign$ \\
+9.  Return(\textit{MP\_OKAY}).\\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Algorithm mp\_mul\_2}
+\end{figure}
+
+\textbf{Algorithm mp\_mul\_2.}
+This algorithm will quickly multiply a mp\_int by two provided $\beta$ is a power of two.  Neither \cite{TAOCPV2} nor \cite{HAC} describe such 
+an algorithm despite the fact it arises often in other algorithms.  The algorithm is setup much like the lower level algorithm s\_mp\_add since 
+it is for all intents and purposes equivalent to the operation $b = \vert a \vert + \vert a \vert$.  
+
+Step 1 and 2 grow the input as required to accomodate the maximum number of \textbf{used} digits in the result.  The initial \textbf{used} count
+is set to $a.used$ at step 4.  Only if there is a final carry will the \textbf{used} count require adjustment.
+
+Step 6 is an optimization implementation of the addition loop for this specific case.  That is since the two values being added together 
+are the same there is no need to perform two reads from the digits of $a$.  Step 6.1 performs a single precision shift on the current digit $a_n$ to
+obtain what will be the carry for the next iteration.  Step 6.2 calculates the $n$'th digit of the result as single precision shift of $a_n$ plus
+the previous carry.  Recall from ~SHIFTS~ that $a_n << 1$ is equivalent to $a_n \cdot 2$.  An iteration of the addition loop is finished with 
+forwarding the carry to the next iteration.
+
+Step 7 takes care of any final carry by setting the $a.used$'th digit of the result to the carry and augmenting the \textbf{used} count of $b$.  
+Step 8 clears any leading digits of $b$ in case it originally had a larger magnitude than $a$.
+
+EXAM,bn_mp_mul_2.c
+
+This implementation is essentially an optimized implementation of s\_mp\_add for the case of doubling an input.  The only noteworthy difference
+is the use of the logical shift operator on line @52,<<@ to perform a single precision doubling.  
+
+\subsection{Division by Two}
+A division by two can just as easily be accomplished with a logical shift right as multiplication by two can be with a logical shift left.
+
+\newpage\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{mp\_div\_2}. \\
+\textbf{Input}.   One mp\_int $a$ \\
+\textbf{Output}.  $b = a/2$. \\
+\hline \\
+1.  If $b.alloc < a.used$ then grow $b$ to hold $a.used$ digits.  (\textit{mp\_grow}) \\
+2.  If the reallocation failed return(\textit{MP\_MEM}). \\
+3.  $oldused \leftarrow b.used$ \\
+4.  $b.used \leftarrow a.used$ \\
+5.  $r \leftarrow 0$ \\
+6.  for $n$ from $b.used - 1$ to $0$ do \\
+\hspace{3mm}6.1  $rr \leftarrow a_n \mbox{ (mod }2\mbox{)}$\\
+\hspace{3mm}6.2  $b_n \leftarrow (a_n >> 1) + (r << (lg(\beta) - 1)) \mbox{ (mod }\beta\mbox{)}$ \\
+\hspace{3mm}6.3  $r \leftarrow rr$ \\
+7.  If $b.used < oldused - 1$ then do \\
+\hspace{3mm}7.1  for $n$ from $b.used$ to $oldused - 1$ do \\
+\hspace{6mm}7.1.1  $b_n \leftarrow 0$ \\
+8.  $b.sign \leftarrow a.sign$ \\
+9.  Clamp excess digits of $b$.  (\textit{mp\_clamp}) \\
+10.  Return(\textit{MP\_OKAY}).\\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Algorithm mp\_div\_2}
+\end{figure}
+
+\textbf{Algorithm mp\_div\_2.}
+This algorithm will divide an mp\_int by two using logical shifts to the right.  Like mp\_mul\_2 it uses a modified low level addition
+core as the basis of the algorithm.  Unlike mp\_mul\_2 the shift operations work from the leading digit to the trailing digit.  The algorithm
+could be written to work from the trailing digit to the leading digit however, it would have to stop one short of $a.used - 1$ digits to prevent
+reading past the end of the array of digits.
+
+Essentially the loop at step 6 is similar to that of mp\_mul\_2 except the logical shifts go in the opposite direction and the carry is at the 
+least significant bit not the most significant bit.  
+
+EXAM,bn_mp_div_2.c
+
+\section{Polynomial Basis Operations}
+Recall from ~POLY~ that any integer can be represented as a polynomial in $x$ as $y = f(\beta)$.  Such a representation is also known as
+the polynomial basis \cite[pp. 48]{ROSE}. Given such a notation a multiplication or division by $x$ amounts to shifting whole digits a single 
+place.  The need for such operations arises in several other higher level algorithms such as Barrett and Montgomery reduction, integer
+division and Karatsuba multiplication.  
+
+Converting from an array of digits to polynomial basis is very simple.  Consider the integer $y \equiv (a_2, a_1, a_0)_{\beta}$ and recall that
+$y = \sum_{i=0}^{2} a_i \beta^i$.  Simply replace $\beta$ with $x$ and the expression is in polynomial basis.  For example, $f(x) = 8x + 9$ is the
+polynomial basis representation for $89$ using radix ten.  That is, $f(10) = 8(10) + 9 = 89$.  
+
+\subsection{Multiplication by $x$}
+
+Given a polynomial in $x$ such as $f(x) = a_n x^n + a_{n-1} x^{n-1} + ... + a_0$ multiplying by $x$ amounts to shifting the coefficients up one 
+degree.  In this case $f(x) \cdot x = a_n x^{n+1} + a_{n-1} x^n + ... + a_0 x$.  From a scalar basis point of view multiplying by $x$ is equivalent to
+multiplying by the integer $\beta$.  
+
+\newpage\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{mp\_lshd}. \\
+\textbf{Input}.   One mp\_int $a$ and an integer $b$ \\
+\textbf{Output}.  $a \leftarrow a \cdot \beta^b$ (equivalent to multiplication by $x^b$). \\
+\hline \\
+1.  If $b \le 0$ then return(\textit{MP\_OKAY}). \\
+2.  If $a.alloc < a.used + b$ then grow $a$ to at least $a.used + b$ digits.  (\textit{mp\_grow}). \\
+3.  If the reallocation failed return(\textit{MP\_MEM}). \\
+4.  $a.used \leftarrow a.used + b$ \\
+5.  $i \leftarrow a.used - 1$ \\
+6.  $j \leftarrow a.used - 1 - b$ \\
+7.  for $n$ from $a.used - 1$ to $b$ do \\
+\hspace{3mm}7.1  $a_{i} \leftarrow a_{j}$ \\
+\hspace{3mm}7.2  $i \leftarrow i - 1$ \\
+\hspace{3mm}7.3  $j \leftarrow j - 1$ \\
+8.  for $n$ from 0 to $b - 1$ do \\
+\hspace{3mm}8.1  $a_n \leftarrow 0$ \\
+9.  Return(\textit{MP\_OKAY}). \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Algorithm mp\_lshd}
+\end{figure}
+
+\textbf{Algorithm mp\_lshd.}
+This algorithm multiplies an mp\_int by the $b$'th power of $x$.  This is equivalent to multiplying by $\beta^b$.  The algorithm differs 
+from the other algorithms presented so far as it performs the operation in place instead storing the result in a separate location.  The
+motivation behind this change is due to the way this function is typically used.  Algorithms such as mp\_add store the result in an optionally
+different third mp\_int because the original inputs are often still required.  Algorithm mp\_lshd (\textit{and similarly algorithm mp\_rshd}) is
+typically used on values where the original value is no longer required.  The algorithm will return success immediately if 
+$b \le 0$ since the rest of algorithm is only valid when $b > 0$.  
+
+First the destination $a$ is grown as required to accomodate the result.  The counters $i$ and $j$ are used to form a \textit{sliding window} over
+the digits of $a$ of length $b$.  The head of the sliding window is at $i$ (\textit{the leading digit}) and the tail at $j$ (\textit{the trailing digit}).  
+The loop on step 7 copies the digit from the tail to the head.  In each iteration the window is moved down one digit.   The last loop on 
+step 8 sets the lower $b$ digits to zero.
+
+\newpage
+FIGU,sliding_window,Sliding Window Movement
+
+EXAM,bn_mp_lshd.c
+
+The if statement (line @24,if@) ensures that the $b$ variable is greater than zero since we do not interpret negative
+shift counts properly.  The \textbf{used} count is incremented by $b$ before the copy loop begins.  This elminates 
+the need for an additional variable in the for loop.  The variable $top$ (line @42,top@) is an alias
+for the leading digit while $bottom$ (line @45,bottom@) is an alias for the trailing edge.  The aliases form a 
+window of exactly $b$ digits over the input.  
+
+\subsection{Division by $x$}
+
+Division by powers of $x$ is easily achieved by shifting the digits right and removing any that will end up to the right of the zero'th digit.  
+
+\newpage\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{mp\_rshd}. \\
+\textbf{Input}.   One mp\_int $a$ and an integer $b$ \\
+\textbf{Output}.  $a \leftarrow a / \beta^b$ (Divide by $x^b$). \\
+\hline \\
+1.  If $b \le 0$ then return. \\
+2.  If $a.used \le b$ then do \\
+\hspace{3mm}2.1  Zero $a$.  (\textit{mp\_zero}). \\
+\hspace{3mm}2.2  Return. \\
+3.  $i \leftarrow 0$ \\
+4.  $j \leftarrow b$ \\
+5.  for $n$ from 0 to $a.used - b - 1$ do \\
+\hspace{3mm}5.1  $a_i \leftarrow a_j$ \\
+\hspace{3mm}5.2  $i \leftarrow i + 1$ \\
+\hspace{3mm}5.3  $j \leftarrow j + 1$ \\
+6.  for $n$ from $a.used - b$ to $a.used - 1$ do \\
+\hspace{3mm}6.1  $a_n \leftarrow 0$ \\
+7.  $a.used \leftarrow a.used - b$ \\
+8.  Return. \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Algorithm mp\_rshd}
+\end{figure}
+
+\textbf{Algorithm mp\_rshd.}
+This algorithm divides the input in place by the $b$'th power of $x$.  It is analogous to dividing by a $\beta^b$ but much quicker since
+it does not require single precision division.  This algorithm does not actually return an error code as it cannot fail.  
+
+If the input $b$ is less than one the algorithm quickly returns without performing any work.  If the \textbf{used} count is less than or equal
+to the shift count $b$ then it will simply zero the input and return.
+
+After the trivial cases of inputs have been handled the sliding window is setup.  Much like the case of algorithm mp\_lshd a sliding window that
+is $b$ digits wide is used to copy the digits.  Unlike mp\_lshd the window slides in the opposite direction from the trailing to the leading digit.  
+Also the digits are copied from the leading to the trailing edge.
+
+Once the window copy is complete the upper digits must be zeroed and the \textbf{used} count decremented.
+
+EXAM,bn_mp_rshd.c
+
+The only noteworthy element of this routine is the lack of a return type since it cannot fail.  Like mp\_lshd() we
+form a sliding window except we copy in the other direction.  After the window (line @59,for (;@) we then zero
+the upper digits of the input to make sure the result is correct.
+
+\section{Powers of Two}
+
+Now that algorithms for moving single bits as well as whole digits exist algorithms for moving the ``in between'' distances are required.  For 
+example, to quickly multiply by $2^k$ for any $k$ without using a full multiplier algorithm would prove useful.  Instead of performing single
+shifts $k$ times to achieve a multiplication by $2^{\pm k}$ a mixture of whole digit shifting and partial digit shifting is employed.  
+
+\subsection{Multiplication by Power of Two}
+
+\newpage\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{mp\_mul\_2d}. \\
+\textbf{Input}.   One mp\_int $a$ and an integer $b$ \\
+\textbf{Output}.  $c \leftarrow a \cdot 2^b$. \\
+\hline \\
+1.  $c \leftarrow a$.  (\textit{mp\_copy}) \\
+2.  If $c.alloc < c.used + \lfloor b / lg(\beta) \rfloor + 2$ then grow $c$ accordingly. \\
+3.  If the reallocation failed return(\textit{MP\_MEM}). \\
+4.  If $b \ge lg(\beta)$ then \\
+\hspace{3mm}4.1  $c \leftarrow c \cdot \beta^{\lfloor b / lg(\beta) \rfloor}$ (\textit{mp\_lshd}). \\
+\hspace{3mm}4.2  If step 4.1 failed return(\textit{MP\_MEM}). \\
+5.  $d \leftarrow b \mbox{ (mod }lg(\beta)\mbox{)}$ \\
+6.  If $d \ne 0$ then do \\
+\hspace{3mm}6.1  $mask \leftarrow 2^d$ \\
+\hspace{3mm}6.2  $r \leftarrow 0$ \\
+\hspace{3mm}6.3  for $n$ from $0$ to $c.used - 1$ do \\
+\hspace{6mm}6.3.1  $rr \leftarrow c_n >> (lg(\beta) - d) \mbox{ (mod }mask\mbox{)}$ \\
+\hspace{6mm}6.3.2  $c_n \leftarrow (c_n << d) + r \mbox{ (mod }\beta\mbox{)}$ \\
+\hspace{6mm}6.3.3  $r \leftarrow rr$ \\
+\hspace{3mm}6.4  If $r > 0$ then do \\
+\hspace{6mm}6.4.1  $c_{c.used} \leftarrow r$ \\
+\hspace{6mm}6.4.2  $c.used \leftarrow c.used + 1$ \\
+7.  Return(\textit{MP\_OKAY}). \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Algorithm mp\_mul\_2d}
+\end{figure}
+
+\textbf{Algorithm mp\_mul\_2d.}
+This algorithm multiplies $a$ by $2^b$ and stores the result in $c$.  The algorithm uses algorithm mp\_lshd and a derivative of algorithm mp\_mul\_2 to
+quickly compute the product.
+
+First the algorithm will multiply $a$ by $x^{\lfloor b / lg(\beta) \rfloor}$ which will ensure that the remainder multiplicand is less than 
+$\beta$.  For example, if $b = 37$ and $\beta = 2^{28}$ then this step will multiply by $x$ leaving a multiplication by $2^{37 - 28} = 2^{9}$ 
+left.
+
+After the digits have been shifted appropriately at most $lg(\beta) - 1$ shifts are left to perform.  Step 5 calculates the number of remaining shifts 
+required.  If it is non-zero a modified shift loop is used to calculate the remaining product.  
+Essentially the loop is a generic version of algorithm mp\_mul\_2 designed to handle any shift count in the range $1 \le x < lg(\beta)$.  The $mask$
+variable is used to extract the upper $d$ bits to form the carry for the next iteration.  
+
+This algorithm is loosely measured as a $O(2n)$ algorithm which means that if the input is $n$-digits that it takes $2n$ ``time'' to 
+complete.  It is possible to optimize this algorithm down to a $O(n)$ algorithm at a cost of making the algorithm slightly harder to follow.
+
+EXAM,bn_mp_mul_2d.c
+
+The shifting is performed in--place which means the first step (line @24,a != c@) is to copy the input to the 
+destination.  We avoid calling mp\_copy() by making sure the mp\_ints are different.  The destination then
+has to be grown (line @31,grow@) to accomodate the result.
+
+If the shift count $b$ is larger than $lg(\beta)$ then a call to mp\_lshd() is used to handle all of the multiples 
+of $lg(\beta)$.  Leaving only a remaining shift of $lg(\beta) - 1$ or fewer bits left.  Inside the actual shift 
+loop (lines @45,if@ to @76,}@) we make use of pre--computed values $shift$ and $mask$.   These are used to
+extract the carry bit(s) to pass into the next iteration of the loop.  The $r$ and $rr$ variables form a 
+chain between consecutive iterations to propagate the carry.  
+
+\subsection{Division by Power of Two}
+
+\newpage\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{mp\_div\_2d}. \\
+\textbf{Input}.   One mp\_int $a$ and an integer $b$ \\
+\textbf{Output}.  $c \leftarrow \lfloor a / 2^b \rfloor, d \leftarrow a \mbox{ (mod }2^b\mbox{)}$. \\
+\hline \\
+1.  If $b \le 0$ then do \\
+\hspace{3mm}1.1  $c \leftarrow a$ (\textit{mp\_copy}) \\
+\hspace{3mm}1.2  $d \leftarrow 0$ (\textit{mp\_zero}) \\
+\hspace{3mm}1.3  Return(\textit{MP\_OKAY}). \\
+2.  $c \leftarrow a$ \\
+3.  $d \leftarrow a \mbox{ (mod }2^b\mbox{)}$ (\textit{mp\_mod\_2d}) \\
+4.  If $b \ge lg(\beta)$ then do \\
+\hspace{3mm}4.1  $c \leftarrow \lfloor c/\beta^{\lfloor b/lg(\beta) \rfloor} \rfloor$ (\textit{mp\_rshd}). \\
+5.  $k \leftarrow b \mbox{ (mod }lg(\beta)\mbox{)}$ \\
+6.  If $k \ne 0$ then do \\
+\hspace{3mm}6.1  $mask \leftarrow 2^k$ \\
+\hspace{3mm}6.2  $r \leftarrow 0$ \\
+\hspace{3mm}6.3  for $n$ from $c.used - 1$ to $0$ do \\
+\hspace{6mm}6.3.1  $rr \leftarrow c_n \mbox{ (mod }mask\mbox{)}$ \\
+\hspace{6mm}6.3.2  $c_n \leftarrow (c_n >> k) + (r << (lg(\beta) - k))$ \\
+\hspace{6mm}6.3.3  $r \leftarrow rr$ \\
+7.  Clamp excess digits of $c$.  (\textit{mp\_clamp}) \\
+8.  Return(\textit{MP\_OKAY}). \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Algorithm mp\_div\_2d}
+\end{figure}
+
+\textbf{Algorithm mp\_div\_2d.}
+This algorithm will divide an input $a$ by $2^b$ and produce the quotient and remainder.  The algorithm is designed much like algorithm 
+mp\_mul\_2d by first using whole digit shifts then single precision shifts.  This algorithm will also produce the remainder of the division
+by using algorithm mp\_mod\_2d.
+
+EXAM,bn_mp_div_2d.c
+
+The implementation of algorithm mp\_div\_2d is slightly different than the algorithm specifies.  The remainder $d$ may be optionally 
+ignored by passing \textbf{NULL} as the pointer to the mp\_int variable.    The temporary mp\_int variable $t$ is used to hold the 
+result of the remainder operation until the end.  This allows $d$ and $a$ to represent the same mp\_int without modifying $a$ before
+the quotient is obtained.
+
+The remainder of the source code is essentially the same as the source code for mp\_mul\_2d.  The only significant difference is
+the direction of the shifts.
+
+\subsection{Remainder of Division by Power of Two}
+
+The last algorithm in the series of polynomial basis power of two algorithms is calculating the remainder of division by $2^b$.  This
+algorithm benefits from the fact that in twos complement arithmetic $a \mbox{ (mod }2^b\mbox{)}$ is the same as $a$ AND $2^b - 1$.  
+
+\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{mp\_mod\_2d}. \\
+\textbf{Input}.   One mp\_int $a$ and an integer $b$ \\
+\textbf{Output}.  $c \leftarrow a \mbox{ (mod }2^b\mbox{)}$. \\
+\hline \\
+1.  If $b \le 0$ then do \\
+\hspace{3mm}1.1  $c \leftarrow 0$ (\textit{mp\_zero}) \\
+\hspace{3mm}1.2  Return(\textit{MP\_OKAY}). \\
+2.  If $b > a.used \cdot lg(\beta)$ then do \\
+\hspace{3mm}2.1  $c \leftarrow a$ (\textit{mp\_copy}) \\
+\hspace{3mm}2.2  Return the result of step 2.1. \\
+3.  $c \leftarrow a$ \\
+4.  If step 3 failed return(\textit{MP\_MEM}). \\
+5.  for $n$ from $\lceil b / lg(\beta) \rceil$ to $c.used$ do \\
+\hspace{3mm}5.1  $c_n \leftarrow 0$ \\
+6.  $k \leftarrow b \mbox{ (mod }lg(\beta)\mbox{)}$ \\
+7.  $c_{\lfloor b / lg(\beta) \rfloor} \leftarrow c_{\lfloor b / lg(\beta) \rfloor} \mbox{ (mod }2^{k}\mbox{)}$. \\
+8.  Clamp excess digits of $c$.  (\textit{mp\_clamp}) \\
+9.  Return(\textit{MP\_OKAY}). \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Algorithm mp\_mod\_2d}
+\end{figure}
+
+\textbf{Algorithm mp\_mod\_2d.}
+This algorithm will quickly calculate the value of $a \mbox{ (mod }2^b\mbox{)}$.  First if $b$ is less than or equal to zero the 
+result is set to zero.  If $b$ is greater than the number of bits in $a$ then it simply copies $a$ to $c$ and returns.  Otherwise, $a$ 
+is copied to $b$, leading digits are removed and the remaining leading digit is trimed to the exact bit count.
+
+EXAM,bn_mp_mod_2d.c
+
+We first avoid cases of $b \le 0$ by simply mp\_zero()'ing the destination in such cases.  Next if $2^b$ is larger
+than the input we just mp\_copy() the input and return right away.  After this point we know we must actually
+perform some work to produce the remainder.
+
+Recalling that reducing modulo $2^k$ and a binary ``and'' with $2^k - 1$ are numerically equivalent we can quickly reduce 
+the number.  First we zero any digits above the last digit in $2^b$ (line @41,for@).  Next we reduce the 
+leading digit of both (line @45,&=@) and then mp\_clamp().
+
+\section*{Exercises}
+\begin{tabular}{cl}
+$\left [ 3 \right ] $ & Devise an algorithm that performs $a \cdot 2^b$ for generic values of $b$ \\
+                      & in $O(n)$ time. \\
+                      &\\
+$\left [ 3 \right ] $ & Devise an efficient algorithm to multiply by small low hamming  \\
+                      & weight values such as $3$, $5$ and $9$.  Extend it to handle all values \\
+                      & upto $64$ with a hamming weight less than three. \\
+                      &\\
+$\left [ 2 \right ] $ & Modify the preceding algorithm to handle values of the form \\
+                      & $2^k - 1$ as well. \\
+                      &\\
+$\left [ 3 \right ] $ & Using only algorithms mp\_mul\_2, mp\_div\_2 and mp\_add create an \\
+                      & algorithm to multiply two integers in roughly $O(2n^2)$ time for \\
+                      & any $n$-bit input.  Note that the time of addition is ignored in the \\
+                      & calculation.  \\
+                      & \\
+$\left [ 5 \right ] $ & Improve the previous algorithm to have a working time of at most \\
+                      & $O \left (2^{(k-1)}n + \left ({2n^2 \over k} \right ) \right )$ for an appropriate choice of $k$.  Again ignore \\
+                      & the cost of addition. \\
+                      & \\
+$\left [ 2 \right ] $ & Devise a chart to find optimal values of $k$ for the previous problem \\
+                      & for $n = 64 \ldots 1024$ in steps of $64$. \\
+                      & \\
+$\left [ 2 \right ] $ & Using only algorithms mp\_abs and mp\_sub devise another method for \\
+                      & calculating the result of a signed comparison. \\
+                      &
+\end{tabular}
+
+\chapter{Multiplication and Squaring}
+\section{The Multipliers}
+For most number theoretic problems including certain public key cryptographic algorithms, the ``multipliers'' form the most important subset of 
+algorithms of any multiple precision integer package.  The set of multiplier algorithms include integer multiplication, squaring and modular reduction 
+where in each of the algorithms single precision multiplication is the dominant operation performed.  This chapter will discuss integer multiplication 
+and squaring, leaving modular reductions for the subsequent chapter.  
+
+The importance of the multiplier algorithms is for the most part driven by the fact that certain popular public key algorithms are based on modular 
+exponentiation, that is computing $d \equiv a^b \mbox{ (mod }c\mbox{)}$ for some arbitrary choice of $a$, $b$, $c$ and $d$.  During a modular
+exponentiation the majority\footnote{Roughly speaking a modular exponentiation will spend about 40\% of the time performing modular reductions, 
+35\% of the time performing squaring and 25\% of the time performing multiplications.} of the processor time is spent performing single precision 
+multiplications.
+
+For centuries general purpose multiplication has required a lengthly $O(n^2)$ process, whereby each digit of one multiplicand has to be multiplied 
+against every digit of the other multiplicand.  Traditional long-hand multiplication is based on this process;  while the techniques can differ the 
+overall algorithm used is essentially the same.  Only ``recently'' have faster algorithms been studied.  First Karatsuba multiplication was discovered in 
+1962.  This algorithm can multiply two numbers with considerably fewer single precision multiplications when compared to the long-hand approach.  
+This technique led to the discovery of polynomial basis algorithms (\textit{good reference?}) and subquently Fourier Transform based solutions.  
+
+\section{Multiplication}
+\subsection{The Baseline Multiplication}
+\label{sec:basemult}
+\index{baseline multiplication}
+Computing the product of two integers in software can be achieved using a trivial adaptation of the standard $O(n^2)$ long-hand multiplication
+algorithm that school children are taught.  The algorithm is considered an $O(n^2)$ algorithm since for two $n$-digit inputs $n^2$ single precision 
+multiplications are required.  More specifically for a $m$ and $n$ digit input $m \cdot n$ single precision multiplications are required.  To 
+simplify most discussions, it will be assumed that the inputs have comparable number of digits.  
+
+The ``baseline multiplication'' algorithm is designed to act as the ``catch-all'' algorithm, only to be used when the faster algorithms cannot be 
+used.  This algorithm does not use any particularly interesting optimizations and should ideally be avoided if possible.    One important 
+facet of this algorithm, is that it has been modified to only produce a certain amount of output digits as resolution.  The importance of this 
+modification will become evident during the discussion of Barrett modular reduction.  Recall that for a $n$ and $m$ digit input the product 
+will be at most $n + m$ digits.  Therefore, this algorithm can be reduced to a full multiplier by having it produce $n + m$ digits of the product.  
+
+Recall from ~GAMMA~ the definition of $\gamma$ as the number of bits in the type \textbf{mp\_digit}.  We shall now extend the variable set to 
+include $\alpha$ which shall represent the number of bits in the type \textbf{mp\_word}.  This implies that $2^{\alpha} > 2 \cdot \beta^2$.  The 
+constant $\delta = 2^{\alpha - 2lg(\beta)}$ will represent the maximal weight of any column in a product (\textit{see ~COMBA~ for more information}).
+
+\newpage\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{s\_mp\_mul\_digs}. \\
+\textbf{Input}.   mp\_int $a$, mp\_int $b$ and an integer $digs$ \\
+\textbf{Output}.  $c \leftarrow \vert a \vert \cdot \vert b \vert \mbox{ (mod }\beta^{digs}\mbox{)}$. \\
+\hline \\
+1.  If min$(a.used, b.used) < \delta$ then do \\
+\hspace{3mm}1.1  Calculate $c = \vert a \vert \cdot \vert b \vert$ by the Comba method (\textit{see algorithm~\ref{fig:COMBAMULT}}).  \\
+\hspace{3mm}1.2  Return the result of step 1.1 \\
+\\
+Allocate and initialize a temporary mp\_int. \\
+2.  Init $t$ to be of size $digs$ \\
+3.  If step 2 failed return(\textit{MP\_MEM}). \\
+4.  $t.used \leftarrow digs$ \\
+\\
+Compute the product. \\
+5.  for $ix$ from $0$ to $a.used - 1$ do \\
+\hspace{3mm}5.1  $u \leftarrow 0$ \\
+\hspace{3mm}5.2  $pb \leftarrow \mbox{min}(b.used, digs - ix)$ \\
+\hspace{3mm}5.3  If $pb < 1$ then goto step 6. \\
+\hspace{3mm}5.4  for $iy$ from $0$ to $pb - 1$ do \\
+\hspace{6mm}5.4.1  $\hat r \leftarrow t_{iy + ix} + a_{ix} \cdot b_{iy} + u$ \\
+\hspace{6mm}5.4.2  $t_{iy + ix} \leftarrow \hat r \mbox{ (mod }\beta\mbox{)}$ \\
+\hspace{6mm}5.4.3  $u \leftarrow \lfloor \hat r / \beta \rfloor$ \\
+\hspace{3mm}5.5  if $ix + pb < digs$ then do \\
+\hspace{6mm}5.5.1  $t_{ix + pb} \leftarrow u$ \\
+6.  Clamp excess digits of $t$. \\
+7.  Swap $c$ with $t$ \\
+8.  Clear $t$ \\
+9.  Return(\textit{MP\_OKAY}). \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Algorithm s\_mp\_mul\_digs}
+\end{figure}
+
+\textbf{Algorithm s\_mp\_mul\_digs.}
+This algorithm computes the unsigned product of two inputs $a$ and $b$, limited to an output precision of $digs$ digits.  While it may seem
+a bit awkward to modify the function from its simple $O(n^2)$ description, the usefulness of partial multipliers will arise in a subsequent 
+algorithm.  The algorithm is loosely based on algorithm 14.12 from \cite[pp. 595]{HAC} and is similar to Algorithm M of Knuth \cite[pp. 268]{TAOCPV2}.  
+Algorithm s\_mp\_mul\_digs differs from these cited references since it can produce a variable output precision regardless of the precision of the 
+inputs.
+
+The first thing this algorithm checks for is whether a Comba multiplier can be used instead.   If the minimum digit count of either
+input is less than $\delta$, then the Comba method may be used instead.    After the Comba method is ruled out, the baseline algorithm begins.  A 
+temporary mp\_int variable $t$ is used to hold the intermediate result of the product.  This allows the algorithm to be used to 
+compute products when either $a = c$ or $b = c$ without overwriting the inputs.  
+
+All of step 5 is the infamous $O(n^2)$ multiplication loop slightly modified to only produce upto $digs$ digits of output.  The $pb$ variable
+is given the count of digits to read from $b$ inside the nested loop.  If $pb \le 1$ then no more output digits can be produced and the algorithm
+will exit the loop.  The best way to think of the loops are as a series of $pb \times 1$ multiplications.    That is, in each pass of the 
+innermost loop $a_{ix}$ is multiplied against $b$ and the result is added (\textit{with an appropriate shift}) to $t$.  
+
+For example, consider multiplying $576$ by $241$.  That is equivalent to computing $10^0(1)(576) + 10^1(4)(576) + 10^2(2)(576)$ which is best
+visualized in the following table.
+
+\begin{figure}[here]
+\begin{center}
+\begin{tabular}{|c|c|c|c|c|c|l|}
+\hline   &&          & 5 & 7 & 6 & \\
+\hline   $\times$&&  & 2 & 4 & 1 & \\
+\hline &&&&&&\\
+  &&          & 5 & 7 & 6 & $10^0(1)(576)$ \\
+  &2 &   3    & 6 & 1 & 6 & $10^1(4)(576) + 10^0(1)(576)$ \\
+  1 & 3 & 8 & 8 & 1 & 6 &   $10^2(2)(576) + 10^1(4)(576) + 10^0(1)(576)$ \\
+\hline  
+\end{tabular}
+\end{center}
+\caption{Long-Hand Multiplication Diagram}
+\end{figure}
+
+Each row of the product is added to the result after being shifted to the left (\textit{multiplied by a power of the radix}) by the appropriate 
+count.  That is in pass $ix$ of the inner loop the product is added starting at the $ix$'th digit of the reult.
+
+Step 5.4.1 introduces the hat symbol (\textit{e.g. $\hat r$}) which represents a double precision variable.  The multiplication on that step
+is assumed to be a double wide output single precision multiplication.  That is, two single precision variables are multiplied to produce a
+double precision result.  The step is somewhat optimized from a long-hand multiplication algorithm because the carry from the addition in step
+5.4.1 is propagated through the nested loop.  If the carry was not propagated immediately it would overflow the single precision digit 
+$t_{ix+iy}$ and the result would be lost.  
+
+At step 5.5 the nested loop is finished and any carry that was left over should be forwarded.  The carry does not have to be added to the $ix+pb$'th
+digit since that digit is assumed to be zero at this point.  However, if $ix + pb \ge digs$ the carry is not set as it would make the result
+exceed the precision requested.
+
+EXAM,bn_s_mp_mul_digs.c
+
+First we determine (line @30,if@) if the Comba method can be used first since it's faster.  The conditions for 
+sing the Comba routine are that min$(a.used, b.used) < \delta$ and the number of digits of output is less than 
+\textbf{MP\_WARRAY}.  This new constant is used to control the stack usage in the Comba routines.  By default it is 
+set to $\delta$ but can be reduced when memory is at a premium.
+
+If we cannot use the Comba method we proceed to setup the baseline routine.  We allocate the the destination mp\_int
+$t$ (line @36,init@) to the exact size of the output to avoid further re--allocations.  At this point we now 
+begin the $O(n^2)$ loop.
+
+This implementation of multiplication has the caveat that it can be trimmed to only produce a variable number of
+digits as output.  In each iteration of the outer loop the $pb$ variable is set (line @48,MIN@) to the maximum 
+number of inner loop iterations.  
+
+Inside the inner loop we calculate $\hat r$ as the mp\_word product of the two mp\_digits and the addition of the
+carry from the previous iteration.  A particularly important observation is that most modern optimizing 
+C compilers (GCC for instance) can recognize that a $N \times N \rightarrow 2N$ multiplication is all that 
+is required for the product.  In x86 terms for example, this means using the MUL instruction.
+
+Each digit of the product is stored in turn (line @68,tmpt@) and the carry propagated (line @71,>>@) to the 
+next iteration.
+
+\subsection{Faster Multiplication by the ``Comba'' Method}
+MARK,COMBA
+
+One of the huge drawbacks of the ``baseline'' algorithms is that at the $O(n^2)$ level the carry must be 
+computed and propagated upwards.  This makes the nested loop very sequential and hard to unroll and implement 
+in parallel.  The ``Comba'' \cite{COMBA} method is named after little known (\textit{in cryptographic venues}) Paul G. 
+Comba who described a method of implementing fast multipliers that do not require nested carry fixup operations.  As an 
+interesting aside it seems that Paul Barrett describes a similar technique in his 1986 paper \cite{BARRETT} written 
+five years before.
+
+At the heart of the Comba technique is once again the long-hand algorithm.  Except in this case a slight 
+twist is placed on how the columns of the result are produced.  In the standard long-hand algorithm rows of products 
+are produced then added together to form the final result.  In the baseline algorithm the columns are added together 
+after each iteration to get the result instantaneously.  
+
+In the Comba algorithm the columns of the result are produced entirely independently of each other.  That is at 
+the $O(n^2)$ level a simple multiplication and addition step is performed.  The carries of the columns are propagated 
+after the nested loop to reduce the amount of work requiored. Succintly the first step of the algorithm is to compute 
+the product vector $\vec x$ as follows. 
+
+\begin{equation}
+\vec x_n = \sum_{i+j = n} a_ib_j, \forall n \in \lbrace 0, 1, 2, \ldots, i + j \rbrace
+\end{equation}
+
+Where $\vec x_n$ is the $n'th$ column of the output vector.  Consider the following example which computes the vector $\vec x$ for the multiplication
+of $576$ and $241$.  
+
+\newpage\begin{figure}[here]
+\begin{small}
+\begin{center}
+\begin{tabular}{|c|c|c|c|c|c|}
+  \hline &          & 5 & 7 & 6 & First Input\\
+  \hline $\times$ & & 2 & 4 & 1 & Second Input\\
+\hline            &                        & $1 \cdot 5 = 5$   & $1 \cdot 7 = 7$   & $1 \cdot 6 = 6$ & First pass \\
+                  &  $4 \cdot 5 = 20$      & $4 \cdot 7+5=33$  & $4 \cdot 6+7=31$  & 6               & Second pass \\
+   $2 \cdot 5 = 10$ &  $2 \cdot 7 + 20 = 34$ & $2 \cdot 6+33=45$ & 31                & 6             & Third pass \\
+\hline 10 & 34 & 45 & 31 & 6 & Final Result \\   
+\hline   
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Comba Multiplication Diagram}
+\end{figure}
+
+At this point the vector $x = \left < 10, 34, 45, 31, 6 \right >$ is the result of the first step of the Comba multipler.  
+Now the columns must be fixed by propagating the carry upwards.  The resultant vector will have one extra dimension over the input vector which is
+congruent to adding a leading zero digit.
+
+\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{Comba Fixup}. \\
+\textbf{Input}.   Vector $\vec x$ of dimension $k$ \\
+\textbf{Output}.  Vector $\vec x$ such that the carries have been propagated. \\
+\hline \\
+1.  for $n$ from $0$ to $k - 1$ do \\
+\hspace{3mm}1.1 $\vec x_{n+1} \leftarrow \vec x_{n+1} + \lfloor \vec x_{n}/\beta \rfloor$ \\
+\hspace{3mm}1.2 $\vec x_{n} \leftarrow \vec x_{n} \mbox{ (mod }\beta\mbox{)}$ \\
+2.  Return($\vec x$). \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Algorithm Comba Fixup}
+\end{figure}
+
+With that algorithm and $k = 5$ and $\beta = 10$ the following vector is produced $\vec x= \left < 1, 3, 8, 8, 1, 6 \right >$.  In this case 
+$241 \cdot 576$ is in fact $138816$ and the procedure succeeded.  If the algorithm is correct and as will be demonstrated shortly more
+efficient than the baseline algorithm why not simply always use this algorithm?
+
+\subsubsection{Column Weight.}
+At the nested $O(n^2)$ level the Comba method adds the product of two single precision variables to each column of the output 
+independently.  A serious obstacle is if the carry is lost, due to lack of precision before the algorithm has a chance to fix
+the carries.  For example, in the multiplication of two three-digit numbers the third column of output will be the sum of
+three single precision multiplications.  If the precision of the accumulator for the output digits is less then $3 \cdot (\beta - 1)^2$ then
+an overflow can occur and the carry information will be lost.  For any $m$ and $n$ digit inputs the maximum weight of any column is 
+min$(m, n)$ which is fairly obvious.
+
+The maximum number of terms in any column of a product is known as the ``column weight'' and strictly governs when the algorithm can be used.  Recall
+from earlier that a double precision type has $\alpha$ bits of resolution and a single precision digit has $lg(\beta)$ bits of precision.  Given these
+two quantities we must not violate the following
+
+\begin{equation}
+k \cdot \left (\beta - 1 \right )^2 < 2^{\alpha}
+\end{equation}
+
+Which reduces to 
+
+\begin{equation}
+k \cdot \left ( \beta^2 - 2\beta + 1 \right ) < 2^{\alpha}
+\end{equation}
+
+Let $\rho = lg(\beta)$ represent the number of bits in a single precision digit.  By further re-arrangement of the equation the final solution is
+found.
+
+\begin{equation}
+k  < {{2^{\alpha}} \over {\left (2^{2\rho} - 2^{\rho + 1} + 1 \right )}}
+\end{equation}
+
+The defaults for LibTomMath are $\beta = 2^{28}$ and $\alpha = 2^{64}$ which means that $k$ is bounded by $k < 257$.  In this configuration 
+the smaller input may not have more than $256$ digits if the Comba method is to be used.  This is quite satisfactory for most applications since 
+$256$ digits would allow for numbers in the range of $0 \le x < 2^{7168}$ which, is much larger than most public key cryptographic algorithms require.  
+
+\newpage\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{fast\_s\_mp\_mul\_digs}. \\
+\textbf{Input}.   mp\_int $a$, mp\_int $b$ and an integer $digs$ \\
+\textbf{Output}.  $c \leftarrow \vert a \vert \cdot \vert b \vert \mbox{ (mod }\beta^{digs}\mbox{)}$. \\
+\hline \\
+Place an array of \textbf{MP\_WARRAY} single precision digits named $W$ on the stack. \\
+1.  If $c.alloc < digs$ then grow $c$ to $digs$ digits. (\textit{mp\_grow}) \\
+2.  If step 1 failed return(\textit{MP\_MEM}).\\
+\\
+3.  $pa \leftarrow \mbox{MIN}(digs, a.used + b.used)$ \\
+\\
+4.  $\_ \hat W \leftarrow 0$ \\
+5.  for $ix$ from 0 to $pa - 1$ do \\
+\hspace{3mm}5.1  $ty \leftarrow \mbox{MIN}(b.used - 1, ix)$ \\
+\hspace{3mm}5.2  $tx \leftarrow ix - ty$ \\
+\hspace{3mm}5.3  $iy \leftarrow \mbox{MIN}(a.used - tx, ty + 1)$ \\
+\hspace{3mm}5.4  for $iz$ from 0 to $iy - 1$ do \\
+\hspace{6mm}5.4.1  $\_ \hat W \leftarrow \_ \hat W + a_{tx+iy}b_{ty-iy}$ \\
+\hspace{3mm}5.5  $W_{ix} \leftarrow \_ \hat W (\mbox{mod }\beta)$\\
+\hspace{3mm}5.6  $\_ \hat W \leftarrow \lfloor \_ \hat W / \beta \rfloor$ \\
+\\
+6.  $oldused \leftarrow c.used$ \\
+7.  $c.used \leftarrow digs$ \\
+8.  for $ix$ from $0$ to $pa$ do \\
+\hspace{3mm}8.1  $c_{ix} \leftarrow W_{ix}$ \\
+9.  for $ix$ from $pa + 1$ to $oldused - 1$ do \\
+\hspace{3mm}9.1 $c_{ix} \leftarrow 0$ \\
+\\
+10.  Clamp $c$. \\
+11.  Return MP\_OKAY. \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Algorithm fast\_s\_mp\_mul\_digs}
+\label{fig:COMBAMULT}
+\end{figure}
+
+\textbf{Algorithm fast\_s\_mp\_mul\_digs.}
+This algorithm performs the unsigned multiplication of $a$ and $b$ using the Comba method limited to $digs$ digits of precision.
+
+The outer loop of this algorithm is more complicated than that of the baseline multiplier.  This is because on the inside of the 
+loop we want to produce one column per pass.  This allows the accumulator $\_ \hat W$ to be placed in CPU registers and
+reduce the memory bandwidth to two \textbf{mp\_digit} reads per iteration.
+
+The $ty$ variable is set to the minimum count of $ix$ or the number of digits in $b$.  That way if $a$ has more digits than
+$b$ this will be limited to $b.used - 1$.  The $tx$ variable is set to the to the distance past $b.used$ the variable
+$ix$ is.  This is used for the immediately subsequent statement where we find $iy$.  
+
+The variable $iy$ is the minimum digits we can read from either $a$ or $b$ before running out.  Computing one column at a time
+means we have to scan one integer upwards and the other downwards.  $a$ starts at $tx$ and $b$ starts at $ty$.  In each
+pass we are producing the $ix$'th output column and we note that $tx + ty = ix$.  As we move $tx$ upwards we have to 
+move $ty$ downards so the equality remains valid.  The $iy$ variable is the number of iterations until 
+$tx \ge a.used$ or $ty < 0$ occurs.
+
+After every inner pass we store the lower half of the accumulator into $W_{ix}$ and then propagate the carry of the accumulator
+into the next round by dividing $\_ \hat W$ by $\beta$.
+
+To measure the benefits of the Comba method over the baseline method consider the number of operations that are required.  If the 
+cost in terms of time of a multiply and addition is $p$ and the cost of a carry propagation is $q$ then a baseline multiplication would require 
+$O \left ((p + q)n^2 \right )$ time to multiply two $n$-digit numbers.  The Comba method requires only $O(pn^2 + qn)$ time, however in practice, 
+the speed increase is actually much more.  With $O(n)$ space the algorithm can be reduced to $O(pn + qn)$ time by implementing the $n$ multiply
+and addition operations in the nested loop in parallel.  
+
+EXAM,bn_fast_s_mp_mul_digs.c
+
+As per the pseudo--code we first calculate $pa$ (line @47,MIN@) as the number of digits to output.  Next we begin the outer loop
+to produce the individual columns of the product.  We use the two aliases $tmpx$ and $tmpy$ (lines @61,tmpx@, @62,tmpy@) to point
+inside the two multiplicands quickly.  
+
+The inner loop (lines @70,for@ to @72,}@) of this implementation is where the tradeoff come into play.  Originally this comba 
+implementation was ``row--major'' which means it adds to each of the columns in each pass.  After the outer loop it would then fix 
+the carries.  This was very fast except it had an annoying drawback.  You had to read a mp\_word and two mp\_digits and write 
+one mp\_word per iteration.  On processors such as the Athlon XP and P4 this did not matter much since the cache bandwidth 
+is very high and it can keep the ALU fed with data.  It did, however, matter on older and embedded cpus where cache is often 
+slower and also often doesn't exist.  This new algorithm only performs two reads per iteration under the assumption that the 
+compiler has aliased $\_ \hat W$ to a CPU register.
+
+After the inner loop we store the current accumulator in $W$ and shift $\_ \hat W$ (lines @75,W[ix]@, @78,>>@) to forward it as 
+a carry for the next pass.  After the outer loop we use the final carry (line @82,W[ix]@) as the last digit of the product.  
+
+\subsection{Polynomial Basis Multiplication}
+To break the $O(n^2)$ barrier in multiplication requires a completely different look at integer multiplication.  In the following algorithms
+the use of polynomial basis representation for two integers $a$ and $b$ as $f(x) = \sum_{i=0}^{n} a_i x^i$ and  
+$g(x) = \sum_{i=0}^{n} b_i x^i$ respectively, is required.  In this system both $f(x)$ and $g(x)$ have $n + 1$ terms and are of the $n$'th degree.
+ 
+The product $a \cdot b \equiv f(x)g(x)$ is the polynomial $W(x) = \sum_{i=0}^{2n} w_i x^i$.  The coefficients $w_i$ will
+directly yield the desired product when $\beta$ is substituted for $x$.  The direct solution to solve for the $2n + 1$ coefficients
+requires $O(n^2)$ time and would in practice be slower than the Comba technique.
+
+However, numerical analysis theory indicates that only $2n + 1$ distinct points in $W(x)$ are required to determine the values of the $2n + 1$ unknown 
+coefficients.   This means by finding $\zeta_y = W(y)$ for $2n + 1$ small values of $y$ the coefficients of $W(x)$ can be found with 
+Gaussian elimination.  This technique is also occasionally refered to as the \textit{interpolation technique} (\textit{references please...}) since in 
+effect an interpolation based on $2n + 1$ points will yield a polynomial equivalent to $W(x)$.  
+
+The coefficients of the polynomial $W(x)$ are unknown which makes finding $W(y)$ for any value of $y$ impossible.  However, since 
+$W(x) = f(x)g(x)$ the equivalent $\zeta_y = f(y) g(y)$ can be used in its place.  The benefit of this technique stems from the 
+fact that $f(y)$ and $g(y)$ are much smaller than either $a$ or $b$ respectively.  As a result finding the $2n + 1$ relations required 
+by multiplying $f(y)g(y)$ involves multiplying integers that are much smaller than either of the inputs.
+
+When picking points to gather relations there are always three obvious points to choose, $y = 0, 1$ and $ \infty$.  The $\zeta_0$ term
+is simply the product $W(0) = w_0 = a_0 \cdot b_0$.  The $\zeta_1$ term is the product 
+$W(1) = \left (\sum_{i = 0}^{n} a_i \right ) \left (\sum_{i = 0}^{n} b_i \right )$.  The third point $\zeta_{\infty}$ is less obvious but rather
+simple to explain.  The $2n + 1$'th coefficient of $W(x)$ is numerically equivalent to the most significant column in an integer multiplication.  
+The point at $\infty$ is used symbolically to represent the most significant column, that is $W(\infty) = w_{2n} = a_nb_n$.  Note that the 
+points at $y = 0$ and $\infty$ yield the coefficients $w_0$ and $w_{2n}$ directly.
+
+If more points are required they should be of small values and powers of two such as $2^q$ and the related \textit{mirror points} 
+$\left (2^q \right )^{2n}  \cdot \zeta_{2^{-q}}$ for small values of $q$.  The term ``mirror point'' stems from the fact that 
+$\left (2^q \right )^{2n}  \cdot \zeta_{2^{-q}}$ can be calculated in the exact opposite fashion as $\zeta_{2^q}$.  For
+example, when $n = 2$ and $q = 1$ then following two equations are equivalent to the point $\zeta_{2}$ and its mirror.
+
+\begin{eqnarray}
+\zeta_{2}                  = f(2)g(2) = (4a_2 + 2a_1 + a_0)(4b_2 + 2b_1 + b_0) \nonumber \\
+16 \cdot \zeta_{1 \over 2} = 4f({1\over 2}) \cdot 4g({1 \over 2}) = (a_2 + 2a_1 + 4a_0)(b_2 + 2b_1 + 4b_0)
+\end{eqnarray}
+
+Using such points will allow the values of $f(y)$ and $g(y)$ to be independently calculated using only left shifts.  For example, when $n = 2$ the
+polynomial $f(2^q)$ is equal to $2^q((2^qa_2) + a_1) + a_0$.  This technique of polynomial representation is known as Horner's method.  
+
+As a general rule of the algorithm when the inputs are split into $n$ parts each there are $2n - 1$ multiplications.  Each multiplication is of 
+multiplicands that have $n$ times fewer digits than the inputs.  The asymptotic running time of this algorithm is 
+$O \left ( k^{lg_n(2n - 1)} \right )$ for $k$ digit inputs (\textit{assuming they have the same number of digits}).  Figure~\ref{fig:exponent}
+summarizes the exponents for various values of $n$.
+
+\begin{figure}
+\begin{center}
+\begin{tabular}{|c|c|c|}
+\hline \textbf{Split into $n$ Parts} & \textbf{Exponent}  & \textbf{Notes}\\
+\hline $2$ & $1.584962501$ & This is Karatsuba Multiplication. \\
+\hline $3$ & $1.464973520$ & This is Toom-Cook Multiplication. \\
+\hline $4$ & $1.403677461$ &\\
+\hline $5$ & $1.365212389$ &\\
+\hline $10$ & $1.278753601$ &\\
+\hline $100$ & $1.149426538$ &\\
+\hline $1000$ & $1.100270931$ &\\
+\hline $10000$ & $1.075252070$ &\\
+\hline
+\end{tabular}
+\end{center}
+\caption{Asymptotic Running Time of Polynomial Basis Multiplication}
+\label{fig:exponent}
+\end{figure}
+
+At first it may seem like a good idea to choose $n = 1000$ since the exponent is approximately $1.1$.  However, the overhead
+of solving for the 2001 terms of $W(x)$ will certainly consume any savings the algorithm could offer for all but exceedingly large
+numbers.  
+
+\subsubsection{Cutoff Point}
+The polynomial basis multiplication algorithms all require fewer single precision multiplications than a straight Comba approach.  However, 
+the algorithms incur an overhead (\textit{at the $O(n)$ work level}) since they require a system of equations to be solved.  This makes the
+polynomial basis approach more costly to use with small inputs.
+
+Let $m$ represent the number of digits in the multiplicands (\textit{assume both multiplicands have the same number of digits}).  There exists a 
+point $y$ such that when $m < y$ the polynomial basis algorithms are more costly than Comba, when $m = y$ they are roughly the same cost and 
+when $m > y$ the Comba methods are slower than the polynomial basis algorithms.  
+
+The exact location of $y$ depends on several key architectural elements of the computer platform in question.
+
+\begin{enumerate}
+\item  The ratio of clock cycles for single precision multiplication versus other simpler operations such as addition, shifting, etc.  For example
+on the AMD Athlon the ratio is roughly $17 : 1$ while on the Intel P4 it is $29 : 1$.  The higher the ratio in favour of multiplication the lower
+the cutoff point $y$ will be.  
+
+\item  The complexity of the linear system of equations (\textit{for the coefficients of $W(x)$}) is.  Generally speaking as the number of splits
+grows the complexity grows substantially.  Ideally solving the system will only involve addition, subtraction and shifting of integers.  This
+directly reflects on the ratio previous mentioned.
+
+\item  To a lesser extent memory bandwidth and function call overheads.  Provided the values are in the processor cache this is less of an
+influence over the cutoff point.
+
+\end{enumerate}
+
+A clean cutoff point separation occurs when a point $y$ is found such that all of the cutoff point conditions are met.  For example, if the point
+is too low then there will be values of $m$ such that $m > y$ and the Comba method is still faster.  Finding the cutoff points is fairly simple when
+a high resolution timer is available.  
+
+\subsection{Karatsuba Multiplication}
+Karatsuba \cite{KARA} multiplication when originally proposed in 1962 was among the first set of algorithms to break the $O(n^2)$ barrier for
+general purpose multiplication.  Given two polynomial basis representations $f(x) = ax + b$ and $g(x) = cx + d$, Karatsuba proved with 
+light algebra \cite{KARAP} that the following polynomial is equivalent to multiplication of the two integers the polynomials represent.
+
+\begin{equation}
+f(x) \cdot g(x) = acx^2 + ((a + b)(c + d) - (ac + bd))x + bd
+\end{equation}
+
+Using the observation that $ac$ and $bd$ could be re-used only three half sized multiplications would be required to produce the product.  Applying
+this algorithm recursively, the work factor becomes $O(n^{lg(3)})$ which is substantially better than the work factor $O(n^2)$ of the Comba technique.  It turns 
+out what Karatsuba did not know or at least did not publish was that this is simply polynomial basis multiplication with the points 
+$\zeta_0$, $\zeta_{\infty}$ and $\zeta_{1}$.  Consider the resultant system of equations.
+
+\begin{center}
+\begin{tabular}{rcrcrcrc}
+$\zeta_{0}$ &      $=$ &  &  &  & & $w_0$ \\
+$\zeta_{1}$ &      $=$ & $w_2$ & $+$ & $w_1$ & $+$ & $w_0$ \\
+$\zeta_{\infty}$ & $=$ & $w_2$ &  & &  & \\
+\end{tabular}
+\end{center}
+
+By adding the first and last equation to the equation in the middle the term $w_1$ can be isolated and all three coefficients solved for.  The simplicity
+of this system of equations has made Karatsuba fairly popular.  In fact the cutoff point is often fairly low\footnote{With LibTomMath 0.18 it is 70 and 109 digits for the Intel P4 and AMD Athlon respectively.}
+making it an ideal algorithm to speed up certain public key cryptosystems such as RSA and Diffie-Hellman.  
+
+\newpage\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{mp\_karatsuba\_mul}. \\
+\textbf{Input}.   mp\_int $a$ and mp\_int $b$ \\
+\textbf{Output}.  $c \leftarrow \vert a \vert \cdot \vert b \vert$ \\
+\hline \\
+1.  Init the following mp\_int variables: $x0$, $x1$, $y0$, $y1$, $t1$, $x0y0$, $x1y1$.\\
+2.  If step 2 failed then return(\textit{MP\_MEM}). \\
+\\
+Split the input.  e.g. $a = x1 \cdot \beta^B + x0$ \\
+3.  $B \leftarrow \mbox{min}(a.used, b.used)/2$ \\
+4.  $x0 \leftarrow a \mbox{ (mod }\beta^B\mbox{)}$ (\textit{mp\_mod\_2d}) \\
+5.  $y0 \leftarrow b \mbox{ (mod }\beta^B\mbox{)}$ \\
+6.  $x1 \leftarrow \lfloor a / \beta^B \rfloor$ (\textit{mp\_rshd}) \\
+7.  $y1 \leftarrow \lfloor b / \beta^B \rfloor$ \\
+\\
+Calculate the three products. \\
+8.  $x0y0 \leftarrow x0 \cdot y0$ (\textit{mp\_mul}) \\
+9.  $x1y1 \leftarrow x1 \cdot y1$ \\
+10.  $t1 \leftarrow x1 + x0$ (\textit{mp\_add}) \\
+11.  $x0 \leftarrow y1 + y0$ \\
+12.  $t1 \leftarrow t1 \cdot x0$ \\
+\\
+Calculate the middle term. \\
+13.  $x0 \leftarrow x0y0 + x1y1$ \\
+14.  $t1 \leftarrow t1 - x0$ (\textit{s\_mp\_sub}) \\
+\\
+Calculate the final product. \\
+15.  $t1 \leftarrow t1 \cdot \beta^B$ (\textit{mp\_lshd}) \\
+16.  $x1y1 \leftarrow x1y1 \cdot \beta^{2B}$ \\
+17.  $t1 \leftarrow x0y0 + t1$ \\
+18.  $c \leftarrow t1 + x1y1$ \\
+19.  Clear all of the temporary variables. \\
+20.  Return(\textit{MP\_OKAY}).\\
+\hline 
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Algorithm mp\_karatsuba\_mul}
+\end{figure}
+
+\textbf{Algorithm mp\_karatsuba\_mul.}
+This algorithm computes the unsigned product of two inputs using the Karatsuba multiplication algorithm.  It is loosely based on the description
+from Knuth \cite[pp. 294-295]{TAOCPV2}.  
+
+\index{radix point}
+In order to split the two inputs into their respective halves, a suitable \textit{radix point} must be chosen.  The radix point chosen must
+be used for both of the inputs meaning that it must be smaller than the smallest input.  Step 3 chooses the radix point $B$ as half of the 
+smallest input \textbf{used} count.  After the radix point is chosen the inputs are split into lower and upper halves.  Step 4 and 5 
+compute the lower halves.  Step 6 and 7 computer the upper halves.  
+
+After the halves have been computed the three intermediate half-size products must be computed.  Step 8 and 9 compute the trivial products
+$x0 \cdot y0$ and $x1 \cdot y1$.  The mp\_int $x0$ is used as a temporary variable after $x1 + x0$ has been computed.  By using $x0$ instead
+of an additional temporary variable, the algorithm can avoid an addition memory allocation operation.
+
+The remaining steps 13 through 18 compute the Karatsuba polynomial through a variety of digit shifting and addition operations.
+
+EXAM,bn_mp_karatsuba_mul.c
+
+The new coding element in this routine, not  seen in previous routines, is the usage of goto statements.  The conventional
+wisdom is that goto statements should be avoided.  This is generally true, however when every single function call can fail, it makes sense
+to handle error recovery with a single piece of code.  Lines @61,if@ to @75,if@ handle initializing all of the temporary variables 
+required.  Note how each of the if statements goes to a different label in case of failure.  This allows the routine to correctly free only
+the temporaries that have been successfully allocated so far.
+
+The temporary variables are all initialized using the mp\_init\_size routine since they are expected to be large.  This saves the 
+additional reallocation that would have been necessary.  Also $x0$, $x1$, $y0$ and $y1$ have to be able to hold at least their respective
+number of digits for the next section of code.
+
+The first algebraic portion of the algorithm is to split the two inputs into their halves.  However, instead of using mp\_mod\_2d and mp\_rshd
+to extract the halves, the respective code has been placed inline within the body of the function.  To initialize the halves, the \textbf{used} and 
+\textbf{sign} members are copied first.  The first for loop on line @98,for@ copies the lower halves.  Since they are both the same magnitude it 
+is simpler to calculate both lower halves in a single loop.  The for loop on lines @104,for@ and @109,for@ calculate the upper halves $x1$ and 
+$y1$ respectively.
+
+By inlining the calculation of the halves, the Karatsuba multiplier has a slightly lower overhead and can be used for smaller magnitude inputs.
+
+When line @152,err@ is reached, the algorithm has completed succesfully.  The ``error status'' variable $err$ is set to \textbf{MP\_OKAY} so that
+the same code that handles errors can be used to clear the temporary variables and return.  
+
+\subsection{Toom-Cook $3$-Way Multiplication}
+Toom-Cook $3$-Way \cite{TOOM} multiplication is essentially the polynomial basis algorithm for $n = 2$ except that the points  are 
+chosen such that $\zeta$ is easy to compute and the resulting system of equations easy to reduce.  Here, the points $\zeta_{0}$, 
+$16 \cdot \zeta_{1 \over 2}$, $\zeta_1$, $\zeta_2$ and $\zeta_{\infty}$ make up the five required points to solve for the coefficients 
+of the $W(x)$.
+
+With the five relations that Toom-Cook specifies, the following system of equations is formed.
+
+\begin{center}
+\begin{tabular}{rcrcrcrcrcr}
+$\zeta_0$                    & $=$ & $0w_4$ & $+$ & $0w_3$ & $+$ & $0w_2$ & $+$ & $0w_1$ & $+$ & $1w_0$  \\
+$16 \cdot \zeta_{1 \over 2}$ & $=$ & $1w_4$ & $+$ & $2w_3$ & $+$ & $4w_2$ & $+$ & $8w_1$ & $+$ & $16w_0$  \\
+$\zeta_1$                    & $=$ & $1w_4$ & $+$ & $1w_3$ & $+$ & $1w_2$ & $+$ & $1w_1$ & $+$ & $1w_0$  \\
+$\zeta_2$                    & $=$ & $16w_4$ & $+$ & $8w_3$ & $+$ & $4w_2$ & $+$ & $2w_1$ & $+$ & $1w_0$  \\
+$\zeta_{\infty}$             & $=$ & $1w_4$ & $+$ & $0w_3$ & $+$ & $0w_2$ & $+$ & $0w_1$ & $+$ & $0w_0$  \\
+\end{tabular}
+\end{center}
+
+A trivial solution to this matrix requires $12$ subtractions, two multiplications by a small power of two, two divisions by a small power
+of two, two divisions by three and one multiplication by three.  All of these $19$ sub-operations require less than quadratic time, meaning that
+the algorithm can be faster than a baseline multiplication.  However, the greater complexity of this algorithm places the cutoff point
+(\textbf{TOOM\_MUL\_CUTOFF}) where Toom-Cook becomes more efficient much higher than the Karatsuba cutoff point.  
+
+\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{mp\_toom\_mul}. \\
+\textbf{Input}.   mp\_int $a$ and mp\_int $b$ \\
+\textbf{Output}.  $c \leftarrow  a  \cdot  b $ \\
+\hline \\
+Split $a$ and $b$ into three pieces.  E.g. $a = a_2 \beta^{2k} + a_1 \beta^{k} + a_0$ \\
+1.  $k \leftarrow \lfloor \mbox{min}(a.used, b.used) / 3 \rfloor$ \\
+2.  $a_0 \leftarrow a \mbox{ (mod }\beta^{k}\mbox{)}$ \\
+3.  $a_1 \leftarrow \lfloor a / \beta^k \rfloor$, $a_1 \leftarrow a_1 \mbox{ (mod }\beta^{k}\mbox{)}$ \\
+4.  $a_2 \leftarrow \lfloor a / \beta^{2k} \rfloor$, $a_2 \leftarrow a_2 \mbox{ (mod }\beta^{k}\mbox{)}$ \\
+5.  $b_0 \leftarrow a \mbox{ (mod }\beta^{k}\mbox{)}$ \\
+6.  $b_1 \leftarrow \lfloor a / \beta^k \rfloor$, $b_1 \leftarrow b_1 \mbox{ (mod }\beta^{k}\mbox{)}$ \\
+7.  $b_2 \leftarrow \lfloor a / \beta^{2k} \rfloor$, $b_2 \leftarrow b_2 \mbox{ (mod }\beta^{k}\mbox{)}$ \\
+\\
+Find the five equations for $w_0, w_1, ..., w_4$. \\
+8.  $w_0 \leftarrow a_0 \cdot b_0$ \\
+9.  $w_4 \leftarrow a_2 \cdot b_2$ \\
+10. $tmp_1 \leftarrow 2 \cdot a_0$, $tmp_1 \leftarrow a_1 + tmp_1$, $tmp_1 \leftarrow 2 \cdot tmp_1$, $tmp_1 \leftarrow tmp_1 + a_2$ \\
+11. $tmp_2 \leftarrow 2 \cdot b_0$, $tmp_2 \leftarrow b_1 + tmp_2$, $tmp_2 \leftarrow 2 \cdot tmp_2$, $tmp_2 \leftarrow tmp_2 + b_2$ \\
+12. $w_1 \leftarrow tmp_1 \cdot tmp_2$ \\
+13. $tmp_1 \leftarrow 2 \cdot a_2$, $tmp_1 \leftarrow a_1 + tmp_1$, $tmp_1 \leftarrow 2 \cdot tmp_1$, $tmp_1 \leftarrow tmp_1 + a_0$ \\
+14. $tmp_2 \leftarrow 2 \cdot b_2$, $tmp_2 \leftarrow b_1 + tmp_2$, $tmp_2 \leftarrow 2 \cdot tmp_2$, $tmp_2 \leftarrow tmp_2 + b_0$ \\
+15. $w_3 \leftarrow tmp_1 \cdot tmp_2$ \\
+16. $tmp_1 \leftarrow a_0 + a_1$, $tmp_1 \leftarrow tmp_1 + a_2$, $tmp_2 \leftarrow b_0 + b_1$, $tmp_2 \leftarrow tmp_2 + b_2$ \\
+17. $w_2 \leftarrow tmp_1 \cdot tmp_2$ \\
+\\
+Continued on the next page.\\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Algorithm mp\_toom\_mul}
+\end{figure}
+
+\newpage\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{mp\_toom\_mul} (continued). \\
+\textbf{Input}.   mp\_int $a$ and mp\_int $b$ \\
+\textbf{Output}.  $c \leftarrow a \cdot  b $ \\
+\hline \\
+Now solve the system of equations. \\
+18. $w_1 \leftarrow w_4 - w_1$, $w_3 \leftarrow w_3 - w_0$ \\
+19. $w_1 \leftarrow \lfloor w_1 / 2 \rfloor$, $w_3 \leftarrow \lfloor w_3 / 2 \rfloor$ \\
+20. $w_2 \leftarrow w_2 - w_0$, $w_2 \leftarrow w_2 - w_4$ \\
+21. $w_1 \leftarrow w_1 - w_2$, $w_3 \leftarrow w_3 - w_2$ \\
+22. $tmp_1 \leftarrow 8 \cdot w_0$, $w_1 \leftarrow w_1 - tmp_1$, $tmp_1 \leftarrow 8 \cdot w_4$, $w_3 \leftarrow w_3 - tmp_1$ \\
+23. $w_2 \leftarrow 3 \cdot w_2$, $w_2 \leftarrow w_2 - w_1$, $w_2 \leftarrow w_2 - w_3$ \\
+24. $w_1 \leftarrow w_1 - w_2$, $w_3 \leftarrow w_3 - w_2$ \\
+25. $w_1 \leftarrow \lfloor w_1 / 3 \rfloor, w_3 \leftarrow \lfloor w_3 / 3 \rfloor$ \\
+\\
+Now substitute $\beta^k$ for $x$ by shifting $w_0, w_1, ..., w_4$. \\
+26. for $n$ from $1$ to $4$ do \\
+\hspace{3mm}26.1  $w_n \leftarrow w_n \cdot \beta^{nk}$ \\
+27. $c \leftarrow w_0 + w_1$, $c \leftarrow c + w_2$, $c \leftarrow c + w_3$, $c \leftarrow c + w_4$ \\
+28. Return(\textit{MP\_OKAY}) \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Algorithm mp\_toom\_mul (continued)}
+\end{figure}
+
+\textbf{Algorithm mp\_toom\_mul.}
+This algorithm computes the product of two mp\_int variables $a$ and $b$ using the Toom-Cook approach.  Compared to the Karatsuba multiplication, this 
+algorithm has a lower asymptotic running time of approximately $O(n^{1.464})$ but at an obvious cost in overhead.  In this
+description, several statements have been compounded to save space.  The intention is that the statements are executed from left to right across
+any given step.
+
+The two inputs $a$ and $b$ are first split into three $k$-digit integers $a_0, a_1, a_2$ and $b_0, b_1, b_2$ respectively.  From these smaller
+integers the coefficients of the polynomial basis representations $f(x)$ and $g(x)$ are known and can be used to find the relations required.
+
+The first two relations $w_0$ and $w_4$ are the points $\zeta_{0}$ and $\zeta_{\infty}$ respectively.  The relation $w_1, w_2$ and $w_3$ correspond
+to the points $16 \cdot \zeta_{1 \over 2}, \zeta_{2}$ and $\zeta_{1}$ respectively.  These are found using logical shifts to independently find
+$f(y)$ and $g(y)$ which significantly speeds up the algorithm.
+
+After the five relations $w_0, w_1, \ldots, w_4$ have been computed, the system they represent must be solved in order for the unknown coefficients 
+$w_1, w_2$ and $w_3$ to be isolated.  The steps 18 through 25 perform the system reduction required as previously described.  Each step of
+the reduction represents the comparable matrix operation that would be performed had this been performed by pencil.  For example, step 18 indicates
+that row $1$ must be subtracted from row $4$ and simultaneously row $0$ subtracted from row $3$.  
+
+Once the coeffients have been isolated, the polynomial $W(x) = \sum_{i=0}^{2n} w_i x^i$ is known.  By substituting $\beta^{k}$ for $x$, the integer 
+result $a \cdot b$ is produced.
+
+EXAM,bn_mp_toom_mul.c
+
+The first obvious thing to note is that this algorithm is complicated.  The complexity is worth it if you are multiplying very 
+large numbers.  For example, a 10,000 digit multiplication takes approximaly 99,282,205 fewer single precision multiplications with
+Toom--Cook than a Comba or baseline approach (this is a savings of more than 99$\%$).  For most ``crypto'' sized numbers this
+algorithm is not practical as Karatsuba has a much lower cutoff point.
+
+First we split $a$ and $b$ into three roughly equal portions.  This has been accomplished (lines @40,mod@ to @69,rshd@) with 
+combinations of mp\_rshd() and mp\_mod\_2d() function calls.  At this point $a = a2 \cdot \beta^2 + a1 \cdot \beta + a0$ and similiarly
+for $b$.  
+
+Next we compute the five points $w0, w1, w2, w3$ and $w4$.  Recall that $w0$ and $w4$ can be computed directly from the portions so
+we get those out of the way first (lines @72,mul@ and @77,mul@).  Next we compute $w1, w2$ and $w3$ using Horners method.
+
+After this point we solve for the actual values of $w1, w2$ and $w3$ by reducing the $5 \times 5$ system which is relatively
+straight forward.  
+
+\subsection{Signed Multiplication}
+Now that algorithms to handle multiplications of every useful dimensions have been developed, a rather simple finishing touch is required.  So far all
+of the multiplication algorithms have been unsigned multiplications which leaves only a signed multiplication algorithm to be established.  
+
+\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{mp\_mul}. \\
+\textbf{Input}.   mp\_int $a$ and mp\_int $b$ \\
+\textbf{Output}.  $c \leftarrow a \cdot b$ \\
+\hline \\
+1.  If $a.sign = b.sign$ then \\
+\hspace{3mm}1.1  $sign = MP\_ZPOS$ \\
+2.  else \\
+\hspace{3mm}2.1  $sign = MP\_ZNEG$ \\
+3.  If min$(a.used, b.used) \ge TOOM\_MUL\_CUTOFF$ then  \\
+\hspace{3mm}3.1  $c \leftarrow a \cdot b$ using algorithm mp\_toom\_mul \\
+4.  else if min$(a.used, b.used) \ge KARATSUBA\_MUL\_CUTOFF$ then \\
+\hspace{3mm}4.1  $c \leftarrow a \cdot b$ using algorithm mp\_karatsuba\_mul \\
+5.  else \\
+\hspace{3mm}5.1  $digs \leftarrow a.used + b.used + 1$ \\
+\hspace{3mm}5.2  If $digs < MP\_ARRAY$ and min$(a.used, b.used) \le \delta$ then \\
+\hspace{6mm}5.2.1  $c \leftarrow a \cdot b \mbox{ (mod }\beta^{digs}\mbox{)}$ using algorithm fast\_s\_mp\_mul\_digs.  \\
+\hspace{3mm}5.3  else \\
+\hspace{6mm}5.3.1  $c \leftarrow a \cdot b \mbox{ (mod }\beta^{digs}\mbox{)}$ using algorithm s\_mp\_mul\_digs.  \\
+6.  $c.sign \leftarrow sign$ \\
+7.  Return the result of the unsigned multiplication performed. \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Algorithm mp\_mul}
+\end{figure}
+
+\textbf{Algorithm mp\_mul.}
+This algorithm performs the signed multiplication of two inputs.  It will make use of any of the three unsigned multiplication algorithms 
+available when the input is of appropriate size.  The \textbf{sign} of the result is not set until the end of the algorithm since algorithm
+s\_mp\_mul\_digs will clear it.  
+
+EXAM,bn_mp_mul.c
+
+The implementation is rather simplistic and is not particularly noteworthy.  Line @22,?@ computes the sign of the result using the ``?'' 
+operator from the C programming language.  Line @37,<<@ computes $\delta$ using the fact that $1 << k$ is equal to $2^k$.  
+
+\section{Squaring}
+\label{sec:basesquare}
+
+Squaring is a special case of multiplication where both multiplicands are equal.  At first it may seem like there is no significant optimization
+available but in fact there is.  Consider the multiplication of $576$ against $241$.  In total there will be nine single precision multiplications
+performed which are $1\cdot 6$, $1 \cdot 7$, $1 \cdot 5$, $4 \cdot 6$, $4 \cdot 7$, $4 \cdot 5$, $2 \cdot  6$, $2 \cdot 7$ and $2 \cdot 5$.  Now consider 
+the multiplication of $123$ against $123$.  The nine products are $3 \cdot 3$, $3 \cdot 2$, $3 \cdot 1$, $2 \cdot 3$, $2 \cdot 2$, $2 \cdot 1$, 
+$1 \cdot 3$, $1 \cdot 2$ and $1 \cdot 1$.  On closer inspection some of the products are equivalent.  For example, $3 \cdot 2 = 2 \cdot 3$ 
+and $3 \cdot 1 = 1 \cdot 3$. 
+
+For any $n$-digit input, there are ${{\left (n^2 + n \right)}\over 2}$ possible unique single precision multiplications required compared to the $n^2$
+required for multiplication.  The following diagram gives an example of the operations required.
+
+\begin{figure}[here]
+\begin{center}
+\begin{tabular}{ccccc|c}
+&&1&2&3&\\
+$\times$ &&1&2&3&\\
+\hline && $3 \cdot 1$ & $3 \cdot 2$ & $3 \cdot 3$ & Row 0\\
+       & $2 \cdot 1$  & $2 \cdot 2$ & $2 \cdot 3$ && Row 1 \\
+         $1 \cdot 1$  & $1 \cdot 2$ & $1 \cdot 3$ &&& Row 2 \\
+\end{tabular}
+\end{center}
+\caption{Squaring Optimization Diagram}
+\end{figure}
+
+MARK,SQUARE
+Starting from zero and numbering the columns from right to left a very simple pattern becomes obvious.  For the purposes of this discussion let $x$
+represent the number being squared.  The first observation is that in row $k$ the $2k$'th column of the product has a $\left (x_k \right)^2$ term in it.  
+
+The second observation is that every column $j$ in row $k$ where $j \ne 2k$ is part of a double product.  Every non-square term of a column will
+appear twice hence the name ``double product''.  Every odd column is made up entirely of double products.  In fact every column is made up of double 
+products and at most one square (\textit{see the exercise section}).  
+
+The third and final observation is that for row $k$ the first unique non-square term, that is, one that hasn't already appeared in an earlier row, 
+occurs at column $2k + 1$.  For example, on row $1$ of the previous squaring, column one is part of the double product with column one from row zero. 
+Column two of row one is a square and column three is the first unique column.
+
+\subsection{The Baseline Squaring Algorithm}
+The baseline squaring algorithm is meant to be a catch-all squaring algorithm.  It will handle any of the input sizes that the faster routines
+will not handle.  
+
+\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{s\_mp\_sqr}. \\
+\textbf{Input}.   mp\_int $a$ \\
+\textbf{Output}.  $b \leftarrow a^2$ \\
+\hline \\
+1.  Init a temporary mp\_int of at least $2 \cdot a.used +1$ digits.  (\textit{mp\_init\_size}) \\
+2.  If step 1 failed return(\textit{MP\_MEM}) \\
+3.  $t.used \leftarrow 2 \cdot a.used + 1$ \\
+4.  For $ix$ from 0 to $a.used - 1$ do \\
+\hspace{3mm}Calculate the square. \\
+\hspace{3mm}4.1  $\hat r \leftarrow t_{2ix} + \left (a_{ix} \right )^2$ \\
+\hspace{3mm}4.2  $t_{2ix} \leftarrow \hat r \mbox{ (mod }\beta\mbox{)}$ \\
+\hspace{3mm}Calculate the double products after the square. \\
+\hspace{3mm}4.3  $u \leftarrow \lfloor \hat r / \beta \rfloor$ \\
+\hspace{3mm}4.4  For $iy$ from $ix + 1$ to $a.used - 1$ do \\
+\hspace{6mm}4.4.1  $\hat r \leftarrow 2 \cdot a_{ix}a_{iy} + t_{ix + iy} + u$ \\
+\hspace{6mm}4.4.2  $t_{ix + iy} \leftarrow \hat r \mbox{ (mod }\beta\mbox{)}$ \\
+\hspace{6mm}4.4.3  $u \leftarrow \lfloor \hat r / \beta \rfloor$ \\
+\hspace{3mm}Set the last carry. \\
+\hspace{3mm}4.5  While $u > 0$ do \\
+\hspace{6mm}4.5.1  $iy \leftarrow iy + 1$ \\
+\hspace{6mm}4.5.2  $\hat r \leftarrow t_{ix + iy} + u$ \\
+\hspace{6mm}4.5.3  $t_{ix + iy} \leftarrow \hat r \mbox{ (mod }\beta\mbox{)}$ \\
+\hspace{6mm}4.5.4  $u \leftarrow \lfloor \hat r / \beta \rfloor$ \\
+5.  Clamp excess digits of $t$.  (\textit{mp\_clamp}) \\
+6.  Exchange $b$ and $t$. \\
+7.  Clear $t$ (\textit{mp\_clear}) \\
+8.  Return(\textit{MP\_OKAY}) \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Algorithm s\_mp\_sqr}
+\end{figure}
+
+\textbf{Algorithm s\_mp\_sqr.}
+This algorithm computes the square of an input using the three observations on squaring.  It is based fairly faithfully on  algorithm 14.16 of HAC
+\cite[pp.596-597]{HAC}.  Similar to algorithm s\_mp\_mul\_digs, a temporary mp\_int is allocated to hold the result of the squaring.  This allows the 
+destination mp\_int to be the same as the source mp\_int.
+
+The outer loop of this algorithm begins on step 4. It is best to think of the outer loop as walking down the rows of the partial results, while
+the inner loop computes the columns of the partial result.  Step 4.1 and 4.2 compute the square term for each row, and step 4.3 and 4.4 propagate
+the carry and compute the double products.  
+
+The requirement that a mp\_word be able to represent the range $0 \le x < 2 \beta^2$ arises from this
+very algorithm.  The product $a_{ix}a_{iy}$ will lie in the range $0 \le x \le \beta^2 - 2\beta + 1$ which is obviously less than $\beta^2$ meaning that
+when it is multiplied by two, it can be properly represented by a mp\_word.
+
+Similar to algorithm s\_mp\_mul\_digs, after every pass of the inner loop, the destination is correctly set to the sum of all of the partial 
+results calculated so far.  This involves expensive carry propagation which will be eliminated in the next algorithm.  
+
+EXAM,bn_s_mp_sqr.c
+
+Inside the outer loop (line @32,for@) the square term is calculated on line @35,r =@.  The carry (line @42,>>@) has been
+extracted from the mp\_word accumulator using a right shift.  Aliases for $a_{ix}$ and $t_{ix+iy}$ are initialized 
+(lines @45,tmpx@ and @48,tmpt@) to simplify the inner loop.  The doubling is performed using two
+additions (line @57,r + r@) since it is usually faster than shifting, if not at least as fast.  
+
+The important observation is that the inner loop does not begin at $iy = 0$ like for multiplication.  As such the inner loops
+get progressively shorter as the algorithm proceeds.  This is what leads to the savings compared to using a multiplication to
+square a number. 
+
+\subsection{Faster Squaring by the ``Comba'' Method}
+A major drawback to the baseline method is the requirement for single precision shifting inside the $O(n^2)$ nested loop.  Squaring has an additional
+drawback that it must double the product inside the inner loop as well.  As for multiplication, the Comba technique can be used to eliminate these
+performance hazards.
+
+The first obvious solution is to make an array of mp\_words which will hold all of the columns.  This will indeed eliminate all of the carry
+propagation operations from the inner loop.  However, the inner product must still be doubled $O(n^2)$ times.  The solution stems from the simple fact
+that $2a + 2b + 2c = 2(a + b + c)$.  That is the sum of all of the double products is equal to double the sum of all the products.  For example,
+$ab + ba + ac + ca = 2ab + 2ac = 2(ab + ac)$.  
+
+However, we cannot simply double all of the columns, since the squares appear only once per row.  The most practical solution is to have two 
+mp\_word arrays.  One array will hold the squares and the other array will hold the double products.  With both arrays the doubling and 
+carry propagation can be moved to a $O(n)$ work level outside the $O(n^2)$ level.  In this case, we have an even simpler solution in mind.
+
+\newpage\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{fast\_s\_mp\_sqr}. \\
+\textbf{Input}.   mp\_int $a$ \\
+\textbf{Output}.  $b \leftarrow a^2$ \\
+\hline \\
+Place an array of \textbf{MP\_WARRAY} mp\_digits named $W$ on the stack. \\
+1.  If $b.alloc < 2a.used + 1$ then grow $b$ to $2a.used + 1$ digits.  (\textit{mp\_grow}). \\
+2.  If step 1 failed return(\textit{MP\_MEM}). \\
+\\
+3.  $pa \leftarrow 2 \cdot a.used$ \\
+4.  $\hat W1 \leftarrow 0$ \\
+5.  for $ix$ from $0$ to $pa - 1$ do \\
+\hspace{3mm}5.1  $\_ \hat W \leftarrow 0$ \\
+\hspace{3mm}5.2  $ty \leftarrow \mbox{MIN}(a.used - 1, ix)$ \\
+\hspace{3mm}5.3  $tx \leftarrow ix - ty$ \\
+\hspace{3mm}5.4  $iy \leftarrow \mbox{MIN}(a.used - tx, ty + 1)$ \\
+\hspace{3mm}5.5  $iy \leftarrow \mbox{MIN}(iy, \lfloor \left (ty - tx + 1 \right )/2 \rfloor)$ \\
+\hspace{3mm}5.6  for $iz$ from $0$ to $iz - 1$ do \\
+\hspace{6mm}5.6.1  $\_ \hat W \leftarrow \_ \hat W + a_{tx + iz}a_{ty - iz}$ \\
+\hspace{3mm}5.7  $\_ \hat W \leftarrow 2 \cdot \_ \hat W  + \hat W1$ \\
+\hspace{3mm}5.8  if $ix$ is even then \\
+\hspace{6mm}5.8.1  $\_ \hat W \leftarrow \_ \hat W + \left ( a_{\lfloor ix/2 \rfloor}\right )^2$ \\
+\hspace{3mm}5.9  $W_{ix} \leftarrow \_ \hat W (\mbox{mod }\beta)$ \\
+\hspace{3mm}5.10  $\hat W1 \leftarrow \lfloor \_ \hat W / \beta \rfloor$ \\
+\\
+6.  $oldused \leftarrow b.used$ \\
+7.  $b.used \leftarrow 2 \cdot a.used$ \\
+8.  for $ix$ from $0$ to $pa - 1$ do \\
+\hspace{3mm}8.1  $b_{ix} \leftarrow W_{ix}$ \\
+9.  for $ix$ from $pa$ to $oldused - 1$ do \\
+\hspace{3mm}9.1  $b_{ix} \leftarrow 0$ \\
+10.  Clamp excess digits from $b$.  (\textit{mp\_clamp}) \\
+11.  Return(\textit{MP\_OKAY}). \\ 
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Algorithm fast\_s\_mp\_sqr}
+\end{figure}
+
+\textbf{Algorithm fast\_s\_mp\_sqr.}
+This algorithm computes the square of an input using the Comba technique.  It is designed to be a replacement for algorithm 
+s\_mp\_sqr when the number of input digits is less than \textbf{MP\_WARRAY} and less than $\delta \over 2$.  
+This algorithm is very similar to the Comba multiplier except with a few key differences we shall make note of.
+
+First, we have an accumulator and carry variables $\_ \hat W$ and $\hat W1$ respectively.  This is because the inner loop
+products are to be doubled.  If we had added the previous carry in we would be doubling too much.  Next we perform an
+addition MIN condition on $iy$ (step 5.5) to prevent overlapping digits.  For example, $a_3 \cdot a_5$ is equal
+$a_5 \cdot a_3$.  Whereas in the multiplication case we would have $5 < a.used$ and $3 \ge 0$ is maintained since we double the sum
+of the products just outside the inner loop we have to avoid doing this.  This is also a good thing since we perform
+fewer multiplications and the routine ends up being faster.
+
+Finally the last difference is the addition of the ``square'' term outside the inner loop (step 5.8).  We add in the square
+only to even outputs and it is the square of the term at the $\lfloor ix / 2 \rfloor$ position.
+
+EXAM,bn_fast_s_mp_sqr.c
+
+This implementation is essentially a copy of Comba multiplication with the appropriate changes added to make it faster for 
+the special case of squaring.  
+
+\subsection{Polynomial Basis Squaring}
+The same algorithm that performs optimal polynomial basis multiplication can be used to perform polynomial basis squaring.  The minor exception
+is that $\zeta_y = f(y)g(y)$ is actually equivalent to $\zeta_y = f(y)^2$ since $f(y) = g(y)$.  Instead of performing $2n + 1$
+multiplications to find the $\zeta$ relations, squaring operations are performed instead.  
+
+\subsection{Karatsuba Squaring}
+Let $f(x) = ax + b$ represent the polynomial basis representation of a number to square.  
+Let $h(x) = \left ( f(x) \right )^2$ represent the square of the polynomial.  The Karatsuba equation can be modified to square a 
+number with the following equation.
+
+\begin{equation}
+h(x) = a^2x^2 + \left ((a + b)^2 - (a^2 + b^2) \right )x + b^2
+\end{equation}
+
+Upon closer inspection this equation only requires the calculation of three half-sized squares: $a^2$, $b^2$ and $(a + b)^2$.  As in 
+Karatsuba multiplication, this algorithm can be applied recursively on the input and will achieve an asymptotic running time of 
+$O \left ( n^{lg(3)} \right )$.
+
+If the asymptotic times of Karatsuba squaring and multiplication are the same, why not simply use the multiplication algorithm 
+instead?  The answer to this arises from the cutoff point for squaring.  As in multiplication there exists a cutoff point, at which the 
+time required for a Comba based squaring and a Karatsuba based squaring meet.  Due to the overhead inherent in the Karatsuba method, the cutoff 
+point is fairly high.  For example, on an AMD Athlon XP processor with $\beta = 2^{28}$, the cutoff point is around 127 digits.  
+
+Consider squaring a 200 digit number with this technique.  It will be split into two 100 digit halves which are subsequently squared.  
+The 100 digit halves will not be squared using Karatsuba, but instead using the faster Comba based squaring algorithm.  If Karatsuba multiplication
+were used instead, the 100 digit numbers would be squared with a slower Comba based multiplication.  
+
+\newpage\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{mp\_karatsuba\_sqr}. \\
+\textbf{Input}.   mp\_int $a$ \\
+\textbf{Output}.  $b \leftarrow a^2$ \\
+\hline \\
+1.  Initialize the following temporary mp\_ints:  $x0$, $x1$, $t1$, $t2$, $x0x0$ and $x1x1$. \\
+2.  If any of the initializations on step 1 failed return(\textit{MP\_MEM}). \\
+\\
+Split the input.  e.g. $a = x1\beta^B + x0$ \\
+3.  $B \leftarrow \lfloor a.used / 2 \rfloor$ \\
+4.  $x0 \leftarrow a \mbox{ (mod }\beta^B\mbox{)}$ (\textit{mp\_mod\_2d}) \\
+5.  $x1 \leftarrow \lfloor a / \beta^B \rfloor$ (\textit{mp\_lshd}) \\
+\\
+Calculate the three squares. \\
+6.  $x0x0 \leftarrow x0^2$ (\textit{mp\_sqr}) \\
+7.  $x1x1 \leftarrow x1^2$ \\
+8.  $t1 \leftarrow x1 + x0$ (\textit{s\_mp\_add}) \\
+9.  $t1 \leftarrow t1^2$ \\
+\\
+Compute the middle term. \\
+10.  $t2 \leftarrow x0x0 + x1x1$ (\textit{s\_mp\_add}) \\
+11.  $t1 \leftarrow t1 - t2$ \\
+\\
+Compute final product. \\
+12.  $t1 \leftarrow t1\beta^B$ (\textit{mp\_lshd}) \\
+13.  $x1x1 \leftarrow x1x1\beta^{2B}$ \\
+14.  $t1 \leftarrow t1 + x0x0$ \\
+15.  $b \leftarrow t1 + x1x1$ \\
+16.  Return(\textit{MP\_OKAY}). \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Algorithm mp\_karatsuba\_sqr}
+\end{figure}
+
+\textbf{Algorithm mp\_karatsuba\_sqr.}
+This algorithm computes the square of an input $a$ using the Karatsuba technique.  This algorithm is very similar to the Karatsuba based
+multiplication algorithm with the exception that the three half-size multiplications have been replaced with three half-size squarings.
+
+The radix point for squaring is simply placed exactly in the middle of the digits when the input has an odd number of digits, otherwise it is
+placed just below the middle.  Step 3, 4 and 5 compute the two halves required using $B$
+as the radix point.  The first two squares in steps 6 and 7 are rather straightforward while the last square is of a more compact form.
+
+By expanding $\left (x1 + x0 \right )^2$, the $x1^2$ and $x0^2$ terms in the middle disappear, that is $(x0 - x1)^2 - (x1^2 + x0^2)  = 2 \cdot x0 \cdot x1$.
+Now if $5n$ single precision additions and a squaring of $n$-digits is faster than multiplying two $n$-digit numbers and doubling then
+this method is faster.  Assuming no further recursions occur, the difference can be estimated with the following inequality.
+
+Let $p$ represent the cost of a single precision addition and $q$ the cost of a single precision multiplication both in terms of time\footnote{Or
+machine clock cycles.}. 
+
+\begin{equation}
+5pn +{{q(n^2 + n)} \over 2} \le pn + qn^2
+\end{equation}
+
+For example, on an AMD Athlon XP processor $p = {1 \over 3}$ and $q = 6$.  This implies that the following inequality should hold.
+\begin{center}
+\begin{tabular}{rcl}
+${5n \over 3} + 3n^2 + 3n$     & $<$ & ${n \over 3} + 6n^2$ \\
+${5 \over 3} + 3n + 3$     & $<$ & ${1 \over 3} + 6n$ \\
+${13 \over 9}$     & $<$ & $n$ \\
+\end{tabular}
+\end{center}
+
+This results in a cutoff point around $n = 2$.  As a consequence it is actually faster to compute the middle term the ``long way'' on processors
+where multiplication is substantially slower\footnote{On the Athlon there is a 1:17 ratio between clock cycles for addition and multiplication.  On
+the Intel P4 processor this ratio is 1:29 making this method even more beneficial.  The only common exception is the ARMv4 processor which has a
+ratio of 1:7.  } than simpler operations such as addition.  
+
+EXAM,bn_mp_karatsuba_sqr.c
+
+This implementation is largely based on the implementation of algorithm mp\_karatsuba\_mul.  It uses the same inline style to copy and 
+shift the input into the two halves.  The loop from line @54,{@ to line @70,}@ has been modified since only one input exists.  The \textbf{used}
+count of both $x0$ and $x1$ is fixed up and $x0$ is clamped before the calculations begin.  At this point $x1$ and $x0$ are valid equivalents
+to the respective halves as if mp\_rshd and mp\_mod\_2d had been used.  
+
+By inlining the copy and shift operations the cutoff point for Karatsuba multiplication can be lowered.  On the Athlon the cutoff point
+is exactly at the point where Comba squaring can no longer be used (\textit{128 digits}).  On slower processors such as the Intel P4
+it is actually below the Comba limit (\textit{at 110 digits}).
+
+This routine uses the same error trap coding style as mp\_karatsuba\_sqr.  As the temporary variables are initialized errors are 
+redirected to the error trap higher up.  If the algorithm completes without error the error code is set to \textbf{MP\_OKAY} and 
+mp\_clears are executed normally.
+
+\subsection{Toom-Cook Squaring}
+The Toom-Cook squaring algorithm mp\_toom\_sqr is heavily based on the algorithm mp\_toom\_mul with the exception that squarings are used
+instead of multiplication to find the five relations.  The reader is encouraged to read the description of the latter algorithm and try to 
+derive their own Toom-Cook squaring algorithm.  
+
+\subsection{High Level Squaring}
+\newpage\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{mp\_sqr}. \\
+\textbf{Input}.   mp\_int $a$ \\
+\textbf{Output}.  $b \leftarrow a^2$ \\
+\hline \\
+1.  If $a.used \ge TOOM\_SQR\_CUTOFF$ then  \\
+\hspace{3mm}1.1  $b \leftarrow a^2$ using algorithm mp\_toom\_sqr \\
+2.  else if $a.used \ge KARATSUBA\_SQR\_CUTOFF$ then \\
+\hspace{3mm}2.1  $b \leftarrow a^2$ using algorithm mp\_karatsuba\_sqr \\
+3.  else \\
+\hspace{3mm}3.1  $digs \leftarrow a.used + b.used + 1$ \\
+\hspace{3mm}3.2  If $digs < MP\_ARRAY$ and $a.used \le \delta$ then \\
+\hspace{6mm}3.2.1  $b \leftarrow a^2$ using algorithm fast\_s\_mp\_sqr.  \\
+\hspace{3mm}3.3  else \\
+\hspace{6mm}3.3.1  $b \leftarrow a^2$ using algorithm s\_mp\_sqr.  \\
+4.  $b.sign \leftarrow MP\_ZPOS$ \\
+5.  Return the result of the unsigned squaring performed. \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Algorithm mp\_sqr}
+\end{figure}
+
+\textbf{Algorithm mp\_sqr.}
+This algorithm computes the square of the input using one of four different algorithms.  If the input is very large and has at least
+\textbf{TOOM\_SQR\_CUTOFF} or \textbf{KARATSUBA\_SQR\_CUTOFF} digits then either the Toom-Cook or the Karatsuba Squaring algorithm is used.  If
+neither of the polynomial basis algorithms should be used then either the Comba or baseline algorithm is used.  
+
+EXAM,bn_mp_sqr.c
+
+\section*{Exercises}
+\begin{tabular}{cl}
+$\left [ 3 \right ] $ & Devise an efficient algorithm for selection of the radix point to handle inputs \\
+                      & that have different number of digits in Karatsuba multiplication. \\
+                      & \\
+$\left [ 2 \right ] $ & In ~SQUARE~ the fact that every column of a squaring is made up \\
+                      & of double products and at most one square is stated.  Prove this statement. \\
+                      & \\                      
+$\left [ 3 \right ] $ & Prove the equation for Karatsuba squaring. \\
+                      & \\
+$\left [ 1 \right ] $ & Prove that Karatsuba squaring requires $O \left (n^{lg(3)} \right )$ time. \\
+                      & \\ 
+$\left [ 2 \right ] $ & Determine the minimal ratio between addition and multiplication clock cycles \\
+                      & required for equation $6.7$ to be true.  \\
+                      & \\
+$\left [ 3 \right ] $ & Implement a threaded version of Comba multiplication (and squaring) where you \\
+                      & compute subsets of the columns in each thread.  Determine a cutoff point where \\
+                      & it is effective and add the logic to mp\_mul() and mp\_sqr(). \\
+                      &\\
+$\left [ 4 \right ] $ & Same as the previous but also modify the Karatsuba and Toom-Cook.  You must \\
+                      & increase the throughput of mp\_exptmod() for random odd moduli in the range \\
+                      & $512 \ldots 4096$ bits significantly ($> 2x$) to complete this challenge. \\
+                      & \\
+\end{tabular}
+
+\chapter{Modular Reduction}
+MARK,REDUCTION
+\section{Basics of Modular Reduction}
+\index{modular residue}
+Modular reduction is an operation that arises quite often within public key cryptography algorithms and various number theoretic algorithms, 
+such as factoring.  Modular reduction algorithms are the third class of algorithms of the ``multipliers'' set.  A number $a$ is said to be \textit{reduced}
+modulo another number $b$ by finding the remainder of the division $a/b$.  Full integer division with remainder is a topic to be covered 
+in~\ref{sec:division}.
+
+Modular reduction is equivalent to solving for $r$ in the following equation.  $a = bq + r$ where $q = \lfloor a/b \rfloor$.  The result 
+$r$ is said to be ``congruent to $a$ modulo $b$'' which is also written as $r \equiv a \mbox{ (mod }b\mbox{)}$.  In other vernacular $r$ is known as the 
+``modular residue'' which leads to ``quadratic residue''\footnote{That's fancy talk for $b \equiv a^2 \mbox{ (mod }p\mbox{)}$.} and
+other forms of residues.  
+
+Modular reductions are normally used to create either finite groups, rings or fields.  The most common usage for performance driven modular reductions 
+is in modular exponentiation algorithms.  That is to compute $d = a^b \mbox{ (mod }c\mbox{)}$ as fast as possible.  This operation is used in the 
+RSA and Diffie-Hellman public key algorithms, for example.  Modular multiplication and squaring also appears as a fundamental operation in 
+elliptic curve cryptographic algorithms.  As will be discussed in the subsequent chapter there exist fast algorithms for computing modular 
+exponentiations without having to perform (\textit{in this example}) $b - 1$ multiplications.  These algorithms will produce partial results in the 
+range $0 \le x < c^2$ which can be taken advantage of to create several efficient algorithms.   They have also been used to create redundancy check 
+algorithms known as CRCs, error correction codes such as Reed-Solomon and solve a variety of number theoeretic problems.  
+
+\section{The Barrett Reduction}
+The Barrett reduction algorithm \cite{BARRETT} was inspired by fast division algorithms which multiply by the reciprocal to emulate
+division.  Barretts observation was that the residue $c$ of $a$ modulo $b$ is equal to 
+
+\begin{equation}
+c = a - b \cdot \lfloor a/b \rfloor
+\end{equation}
+
+Since algorithms such as modular exponentiation would be using the same modulus extensively, typical DSP\footnote{It is worth noting that Barrett's paper 
+targeted the DSP56K processor.}  intuition would indicate the next step would be to replace $a/b$ by a multiplication by the reciprocal.  However, 
+DSP intuition on its own will not work as these numbers are considerably larger than the precision of common DSP floating point data types.  
+It would take another common optimization to optimize the algorithm.
+
+\subsection{Fixed Point Arithmetic}
+The trick used to optimize the above equation is based on a technique of emulating floating point data types with fixed precision integers.  Fixed
+point arithmetic would become very popular as it greatly optimize the ``3d-shooter'' genre of games in the mid 1990s when floating point units were 
+fairly slow if not unavailable.   The idea behind fixed point arithmetic is to take a normal $k$-bit integer data type and break it into $p$-bit 
+integer and a $q$-bit fraction part (\textit{where $p+q = k$}).  
+
+In this system a $k$-bit integer $n$ would actually represent $n/2^q$.  For example, with $q = 4$ the integer $n = 37$ would actually represent the
+value $2.3125$.  To multiply two fixed point numbers the integers are multiplied using traditional arithmetic and subsequently normalized by 
+moving the implied decimal point back to where it should be.  For example, with $q = 4$ to multiply the integers $9$ and $5$ they must be converted 
+to fixed point first by multiplying by $2^q$.  Let $a = 9(2^q)$ represent the fixed point representation of $9$ and $b = 5(2^q)$ represent the 
+fixed point representation of $5$.  The product $ab$ is equal to $45(2^{2q})$ which when normalized by dividing by $2^q$ produces $45(2^q)$.  
+
+This technique became popular since a normal integer multiplication and logical shift right are the only required operations to perform a multiplication
+of two fixed point numbers.  Using fixed point arithmetic, division can be easily approximated by multiplying by the reciprocal.  If $2^q$ is 
+equivalent to one than $2^q/b$ is equivalent to the fixed point approximation of $1/b$ using real arithmetic.  Using this fact dividing an integer 
+$a$ by another integer $b$ can be achieved with the following expression.
+
+\begin{equation}
+\lfloor a / b \rfloor \mbox{ }\approx\mbox{ } \lfloor (a \cdot \lfloor 2^q / b \rfloor)/2^q \rfloor
+\end{equation}
+
+The precision of the division is proportional to the value of $q$.  If the divisor $b$ is used frequently as is the case with 
+modular exponentiation pre-computing $2^q/b$ will allow a division to be performed with a multiplication and a right shift.  Both operations
+are considerably faster than division on most processors.  
+
+Consider dividing $19$ by $5$.  The correct result is $\lfloor 19/5 \rfloor = 3$.  With $q = 3$ the reciprocal is $\lfloor 2^q/5 \rfloor = 1$ which
+leads to a product of $19$ which when divided by $2^q$ produces $2$.  However, with $q = 4$ the reciprocal is $\lfloor 2^q/5 \rfloor = 3$ and
+the result of the emulated division is $\lfloor 3 \cdot 19 / 2^q \rfloor = 3$ which is correct.  The value of $2^q$ must be close to or ideally
+larger than the dividend.  In effect if $a$ is the dividend then $q$ should allow $0 \le \lfloor a/2^q \rfloor \le 1$ in order for this approach
+to work correctly.  Plugging this form of divison into the original equation the following modular residue equation arises.
+
+\begin{equation}
+c = a - b \cdot \lfloor (a \cdot \lfloor 2^q / b \rfloor)/2^q \rfloor
+\end{equation}
+
+Using the notation from \cite{BARRETT} the value of $\lfloor 2^q / b \rfloor$ will be represented by the $\mu$ symbol.  Using the $\mu$
+variable also helps re-inforce the idea that it is meant to be computed once and re-used.
+
+\begin{equation}
+c = a - b \cdot \lfloor (a \cdot \mu)/2^q \rfloor
+\end{equation}
+
+Provided that $2^q \ge a$ this algorithm will produce a quotient that is either exactly correct or off by a value of one.  In the context of Barrett
+reduction the value of $a$ is bound by $0 \le a \le (b - 1)^2$ meaning that $2^q \ge b^2$ is sufficient to ensure the reciprocal will have enough
+precision.  
+
+Let $n$ represent the number of digits in $b$.  This algorithm requires approximately $2n^2$ single precision multiplications to produce the quotient and 
+another $n^2$ single precision multiplications to find the residue.  In total $3n^2$ single precision multiplications are required to 
+reduce the number.  
+
+For example, if $b = 1179677$ and $q = 41$ ($2^q > b^2$), then the reciprocal $\mu$ is equal to $\lfloor 2^q / b \rfloor = 1864089$.  Consider reducing
+$a = 180388626447$ modulo $b$ using the above reduction equation.  The quotient using the new formula is $\lfloor (a \cdot \mu) / 2^q \rfloor = 152913$.
+By subtracting $152913b$ from $a$ the correct residue $a \equiv 677346 \mbox{ (mod }b\mbox{)}$ is found.
+
+\subsection{Choosing a Radix Point}
+Using the fixed point representation a modular reduction can be performed with $3n^2$ single precision multiplications.  If that were the best
+that could be achieved a full division\footnote{A division requires approximately $O(2cn^2)$ single precision multiplications for a small value of $c$.  
+See~\ref{sec:division} for further details.} might as well be used in its place.  The key to optimizing the reduction is to reduce the precision of
+the initial multiplication that finds the quotient.  
+
+Let $a$ represent the number of which the residue is sought.  Let $b$ represent the modulus used to find the residue.  Let $m$ represent
+the number of digits in $b$.  For the purposes of this discussion we will assume that the number of digits in $a$ is $2m$, which is generally true if 
+two $m$-digit numbers have been multiplied.  Dividing $a$ by $b$ is the same as dividing a $2m$ digit integer by a $m$ digit integer.  Digits below the 
+$m - 1$'th digit of $a$ will contribute at most a value of $1$ to the quotient because $\beta^k < b$ for any $0 \le k \le m - 1$.  Another way to
+express this is by re-writing $a$ as two parts.  If $a' \equiv a \mbox{ (mod }b^m\mbox{)}$ and $a'' = a - a'$ then 
+${a \over b} \equiv {{a' + a''} \over b}$ which is equivalent to ${a' \over b} + {a'' \over b}$.  Since $a'$ is bound to be less than $b$ the quotient
+is bound by $0 \le {a' \over b} < 1$.
+
+Since the digits of $a'$ do not contribute much to the quotient the observation is that they might as well be zero.  However, if the digits 
+``might as well be zero'' they might as well not be there in the first place.  Let $q_0 = \lfloor a/\beta^{m-1} \rfloor$ represent the input
+with the irrelevant digits trimmed.  Now the modular reduction is trimmed to the almost equivalent equation
+
+\begin{equation}
+c = a - b \cdot \lfloor (q_0 \cdot \mu) / \beta^{m+1} \rfloor
+\end{equation}
+
+Note that the original divisor $2^q$ has been replaced with $\beta^{m+1}$ where in this case $q$ is a multiple of $lg(\beta)$. Also note that the 
+exponent on the divisor when added to the amount $q_0$ was shifted by equals $2m$.  If the optimization had not been performed the divisor 
+would have the exponent $2m$ so in the end the exponents do ``add up''. Using the above equation the quotient 
+$\lfloor (q_0 \cdot \mu) / \beta^{m+1} \rfloor$ can be off from the true quotient by at most two.  The original fixed point quotient can be off
+by as much as one (\textit{provided the radix point is chosen suitably}) and now that the lower irrelevent digits have been trimmed the quotient
+can be off by an additional value of one for a total of at most two.  This implies that 
+$0 \le a - b \cdot \lfloor (q_0 \cdot \mu) / \beta^{m+1} \rfloor < 3b$.  By first subtracting $b$ times the quotient and then conditionally subtracting 
+$b$ once or twice the residue is found.
+
+The quotient is now found using $(m + 1)(m) = m^2 + m$ single precision multiplications and the residue with an additional $m^2$ single
+precision multiplications, ignoring the subtractions required.  In total $2m^2 + m$ single precision multiplications are required to find the residue.  
+This is considerably faster than the original attempt.
+
+For example, let $\beta = 10$ represent the radix of the digits.  Let $b = 9999$ represent the modulus which implies $m = 4$. Let $a = 99929878$ 
+represent the value of which the residue is desired.  In this case $q = 8$ since $10^7 < 9999^2$ meaning that $\mu = \lfloor \beta^{q}/b \rfloor = 10001$.  
+With the new observation the multiplicand for the quotient is equal to $q_0 = \lfloor a / \beta^{m - 1} \rfloor = 99929$.  The quotient is then 
+$\lfloor (q_0 \cdot \mu) / \beta^{m+1} \rfloor = 9993$.  Subtracting $9993b$ from $a$ and the correct residue $a \equiv 9871 \mbox{ (mod }b\mbox{)}$ 
+is found.  
+
+\subsection{Trimming the Quotient}
+So far the reduction algorithm has been optimized from $3m^2$ single precision multiplications down to $2m^2 + m$ single precision multiplications.  As 
+it stands now the algorithm is already fairly fast compared to a full integer division algorithm.  However, there is still room for
+optimization.  
+
+After the first multiplication inside the quotient ($q_0 \cdot \mu$) the value is shifted right by $m + 1$ places effectively nullifying the lower
+half of the product.  It would be nice to be able to remove those digits from the product to effectively cut down the number of single precision 
+multiplications.  If the number of digits in the modulus $m$ is far less than $\beta$ a full product is not required for the algorithm to work properly.  
+In fact the lower $m - 2$ digits will not affect the upper half of the product at all and do not need to be computed.  
+
+The value of $\mu$ is a $m$-digit number and $q_0$ is a $m + 1$ digit number.  Using a full multiplier $(m + 1)(m) = m^2 + m$ single precision
+multiplications would be required.  Using a multiplier that will only produce digits at and above the $m - 1$'th digit reduces the number
+of single precision multiplications to ${m^2 + m} \over 2$ single precision multiplications.  
+
+\subsection{Trimming the Residue}
+After the quotient has been calculated it is used to reduce the input.  As previously noted the algorithm is not exact and it can be off by a small
+multiple of the modulus, that is $0 \le a - b \cdot \lfloor (q_0 \cdot \mu) / \beta^{m+1} \rfloor < 3b$.  If $b$ is $m$ digits than the 
+result of reduction equation is a value of at most $m + 1$ digits (\textit{provided $3 < \beta$}) implying that the upper $m - 1$ digits are
+implicitly zero.  
+
+The next optimization arises from this very fact.  Instead of computing $b \cdot \lfloor (q_0 \cdot \mu) / \beta^{m+1} \rfloor$ using a full
+$O(m^2)$ multiplication algorithm only the lower $m+1$ digits of the product have to be computed.  Similarly the value of $a$ can
+be reduced modulo $\beta^{m+1}$ before the multiple of $b$ is subtracted which simplifes the subtraction as well.  A multiplication that produces 
+only the lower $m+1$ digits requires ${m^2 + 3m - 2} \over 2$ single precision multiplications.  
+
+With both optimizations in place the algorithm is the algorithm Barrett proposed.  It requires $m^2 + 2m - 1$ single precision multiplications which
+is considerably faster than the straightforward $3m^2$ method.  
+
+\subsection{The Barrett Algorithm}
+\newpage\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{mp\_reduce}. \\
+\textbf{Input}.   mp\_int $a$, mp\_int $b$ and $\mu = \lfloor \beta^{2m}/b \rfloor, m = \lceil lg_{\beta}(b) \rceil, (0 \le a < b^2, b > 1)$ \\
+\textbf{Output}.  $a \mbox{ (mod }b\mbox{)}$ \\
+\hline \\
+Let $m$ represent the number of digits in $b$.  \\
+1.  Make a copy of $a$ and store it in $q$.  (\textit{mp\_init\_copy}) \\
+2.  $q \leftarrow \lfloor q / \beta^{m - 1} \rfloor$ (\textit{mp\_rshd}) \\
+\\
+Produce the quotient. \\
+3.  $q \leftarrow q \cdot \mu$  (\textit{note: only produce digits at or above $m-1$}) \\
+4.  $q \leftarrow \lfloor q / \beta^{m + 1} \rfloor$ \\
+\\
+Subtract the multiple of modulus from the input. \\
+5.  $a \leftarrow a \mbox{ (mod }\beta^{m+1}\mbox{)}$ (\textit{mp\_mod\_2d}) \\
+6.  $q \leftarrow q \cdot b \mbox{ (mod }\beta^{m+1}\mbox{)}$ (\textit{s\_mp\_mul\_digs}) \\
+7.  $a \leftarrow a - q$ (\textit{mp\_sub}) \\
+\\
+Add $\beta^{m+1}$ if a carry occured. \\
+8.  If $a < 0$ then (\textit{mp\_cmp\_d}) \\
+\hspace{3mm}8.1  $q \leftarrow 1$ (\textit{mp\_set}) \\
+\hspace{3mm}8.2  $q \leftarrow q \cdot \beta^{m+1}$ (\textit{mp\_lshd}) \\
+\hspace{3mm}8.3  $a \leftarrow a + q$ \\
+\\
+Now subtract the modulus if the residue is too large (e.g. quotient too small). \\
+9.  While $a \ge b$ do (\textit{mp\_cmp}) \\
+\hspace{3mm}9.1  $c \leftarrow a - b$ \\
+10.  Clear $q$. \\
+11.  Return(\textit{MP\_OKAY}) \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Algorithm mp\_reduce}
+\end{figure}
+
+\textbf{Algorithm mp\_reduce.}
+This algorithm will reduce the input $a$ modulo $b$ in place using the Barrett algorithm.  It is loosely based on algorithm 14.42 of HAC
+\cite[pp.  602]{HAC} which is based on the paper from Paul Barrett \cite{BARRETT}.  The algorithm has several restrictions and assumptions which must 
+be adhered to for the algorithm to work.
+
+First the modulus $b$ is assumed to be positive and greater than one.  If the modulus were less than or equal to one than subtracting
+a multiple of it would either accomplish nothing or actually enlarge the input.  The input $a$ must be in the range $0 \le a < b^2$ in order
+for the quotient to have enough precision.  If $a$ is the product of two numbers that were already reduced modulo $b$, this will not be a problem.
+Technically the algorithm will still work if $a \ge b^2$ but it will take much longer to finish.  The value of $\mu$ is passed as an argument to this 
+algorithm and is assumed to be calculated and stored before the algorithm is used.  
+
+Recall that the multiplication for the quotient on step 3 must only produce digits at or above the $m-1$'th position.  An algorithm called 
+$s\_mp\_mul\_high\_digs$ which has not been presented is used to accomplish this task.  The algorithm is based on $s\_mp\_mul\_digs$ except that
+instead of stopping at a given level of precision it starts at a given level of precision.  This optimal algorithm can only be used if the number
+of digits in $b$ is very much smaller than $\beta$.  
+
+While it is known that 
+$a \ge b \cdot \lfloor (q_0 \cdot \mu) / \beta^{m+1} \rfloor$ only the lower $m+1$ digits are being used to compute the residue, so an implied 
+``borrow'' from the higher digits might leave a negative result.  After the multiple of the modulus has been subtracted from $a$ the residue must be 
+fixed up in case it is negative.  The invariant $\beta^{m+1}$ must be added to the residue to make it positive again.  
+
+The while loop at step 9 will subtract $b$ until the residue is less than $b$.  If the algorithm is performed correctly this step is 
+performed at most twice, and on average once. However, if $a \ge b^2$ than it will iterate substantially more times than it should.
+
+EXAM,bn_mp_reduce.c
+
+The first multiplication that determines the quotient can be performed by only producing the digits from $m - 1$ and up.  This essentially halves
+the number of single precision multiplications required.  However, the optimization is only safe if $\beta$ is much larger than the number of digits
+in the modulus.  In the source code this is evaluated on lines @36,if@ to @44,}@ where algorithm s\_mp\_mul\_high\_digs is used when it is
+safe to do so.  
+
+\subsection{The Barrett Setup Algorithm}
+In order to use algorithm mp\_reduce the value of $\mu$ must be calculated in advance.  Ideally this value should be computed once and stored for
+future use so that the Barrett algorithm can be used without delay.  
+
+\newpage\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{mp\_reduce\_setup}. \\
+\textbf{Input}.   mp\_int $a$ ($a > 1$)  \\
+\textbf{Output}.  $\mu \leftarrow \lfloor \beta^{2m}/a \rfloor$ \\
+\hline \\
+1.  $\mu \leftarrow 2^{2 \cdot lg(\beta) \cdot  m}$ (\textit{mp\_2expt}) \\
+2.  $\mu \leftarrow \lfloor \mu / b \rfloor$ (\textit{mp\_div}) \\
+3.  Return(\textit{MP\_OKAY}) \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Algorithm mp\_reduce\_setup}
+\end{figure}
+
+\textbf{Algorithm mp\_reduce\_setup.}
+This algorithm computes the reciprocal $\mu$ required for Barrett reduction.  First $\beta^{2m}$ is calculated as $2^{2 \cdot lg(\beta) \cdot  m}$ which
+is equivalent and much faster.  The final value is computed by taking the integer quotient of $\lfloor \mu / b \rfloor$.
+
+EXAM,bn_mp_reduce_setup.c
+
+This simple routine calculates the reciprocal $\mu$ required by Barrett reduction.  Note the extended usage of algorithm mp\_div where the variable
+which would received the remainder is passed as NULL.  As will be discussed in~\ref{sec:division} the division routine allows both the quotient and the 
+remainder to be passed as NULL meaning to ignore the value.  
+
+\section{The Montgomery Reduction}
+Montgomery reduction\footnote{Thanks to Niels Ferguson for his insightful explanation of the algorithm.} \cite{MONT} is by far the most interesting 
+form of reduction in common use.  It computes a modular residue which is not actually equal to the residue of the input yet instead equal to a 
+residue times a constant.  However, as perplexing as this may sound the algorithm is relatively simple and very efficient.  
+
+Throughout this entire section the variable $n$ will represent the modulus used to form the residue.  As will be discussed shortly the value of
+$n$ must be odd.  The variable $x$ will represent the quantity of which the residue is sought.  Similar to the Barrett algorithm the input
+is restricted to $0 \le x < n^2$.  To begin the description some simple number theory facts must be established.
+
+\textbf{Fact 1.}  Adding $n$ to $x$ does not change the residue since in effect it adds one to the quotient $\lfloor x / n \rfloor$.  Another way
+to explain this is that $n$ is (\textit{or multiples of $n$ are}) congruent to zero modulo $n$.  Adding zero will not change the value of the residue.  
+
+\textbf{Fact 2.}  If $x$ is even then performing a division by two in $\Z$ is congruent to $x \cdot 2^{-1} \mbox{ (mod }n\mbox{)}$.  Actually
+this is an application of the fact that if $x$ is evenly divisible by any $k \in \Z$ then division in $\Z$ will be congruent to 
+multiplication by $k^{-1}$ modulo $n$.  
+
+From these two simple facts the following simple algorithm can be derived.
+
+\newpage\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{Montgomery Reduction}. \\
+\textbf{Input}.   Integer $x$, $n$ and $k$ \\
+\textbf{Output}.  $2^{-k}x \mbox{ (mod }n\mbox{)}$ \\
+\hline \\
+1.  for $t$ from $1$ to $k$ do \\
+\hspace{3mm}1.1  If $x$ is odd then \\
+\hspace{6mm}1.1.1  $x \leftarrow x + n$ \\
+\hspace{3mm}1.2  $x \leftarrow x/2$ \\
+2.  Return $x$. \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Algorithm Montgomery Reduction}
+\end{figure}
+
+The algorithm reduces the input one bit at a time using the two congruencies stated previously.  Inside the loop $n$, which is odd, is
+added to $x$ if $x$ is odd.  This forces $x$ to be even which allows the division by two in $\Z$ to be congruent to a modular division by two.  Since
+$x$ is assumed to be initially much larger than $n$ the addition of $n$ will contribute an insignificant magnitude to $x$.  Let $r$ represent the 
+final result of the Montgomery algorithm.  If $k > lg(n)$ and $0 \le x < n^2$ then the final result is limited to 
+$0 \le r < \lfloor x/2^k \rfloor + n$.  As a result at most a single subtraction is required to get the residue desired.
+
+\begin{figure}[here]
+\begin{small}
+\begin{center}
+\begin{tabular}{|c|l|}
+\hline \textbf{Step number ($t$)} & \textbf{Result ($x$)} \\
+\hline $1$ & $x + n = 5812$, $x/2 = 2906$ \\
+\hline $2$ & $x/2 = 1453$ \\
+\hline $3$ & $x + n = 1710$, $x/2 = 855$ \\
+\hline $4$ & $x + n = 1112$, $x/2 = 556$ \\
+\hline $5$ & $x/2 = 278$ \\
+\hline $6$ & $x/2 = 139$ \\
+\hline $7$ & $x + n = 396$, $x/2 = 198$ \\
+\hline $8$ & $x/2 = 99$ \\
+\hline $9$ & $x + n = 356$, $x/2 = 178$ \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Example of Montgomery Reduction (I)}
+\label{fig:MONT1}
+\end{figure}
+
+Consider the example in figure~\ref{fig:MONT1} which reduces $x = 5555$ modulo $n = 257$ when $k = 9$ (note $\beta^k = 512$ which is larger than $n$).  The result of 
+the algorithm $r = 178$ is congruent to the value of $2^{-9} \cdot 5555 \mbox{ (mod }257\mbox{)}$.  When $r$ is multiplied by $2^9$ modulo $257$ the correct residue 
+$r \equiv 158$ is produced.  
+
+Let $k = \lfloor lg(n) \rfloor + 1$ represent the number of bits in $n$.  The current algorithm requires $2k^2$ single precision shifts
+and $k^2$ single precision additions.  At this rate the algorithm is most certainly slower than Barrett reduction and not terribly useful.  
+Fortunately there exists an alternative representation of the algorithm.
+
+\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{Montgomery Reduction} (modified I). \\
+\textbf{Input}.   Integer $x$, $n$ and $k$ ($2^k > n$) \\
+\textbf{Output}.  $2^{-k}x \mbox{ (mod }n\mbox{)}$ \\
+\hline \\
+1.  for $t$ from $1$ to $k$ do \\
+\hspace{3mm}1.1  If the $t$'th bit of $x$ is one then \\
+\hspace{6mm}1.1.1  $x \leftarrow x + 2^tn$ \\
+2.  Return $x/2^k$. \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Algorithm Montgomery Reduction (modified I)}
+\end{figure}
+
+This algorithm is equivalent since $2^tn$ is a multiple of $n$ and the lower $k$ bits of $x$ are zero by step 2.  The number of single
+precision shifts has now been reduced from $2k^2$ to $k^2 + k$ which is only a small improvement.
+
+\begin{figure}[here]
+\begin{small}
+\begin{center}
+\begin{tabular}{|c|l|r|}
+\hline \textbf{Step number ($t$)} & \textbf{Result ($x$)} & \textbf{Result ($x$) in Binary} \\
+\hline -- & $5555$ & $1010110110011$ \\
+\hline $1$ & $x + 2^{0}n = 5812$ &  $1011010110100$ \\
+\hline $2$ & $5812$ & $1011010110100$ \\
+\hline $3$ & $x + 2^{2}n = 6840$ & $1101010111000$ \\
+\hline $4$ & $x + 2^{3}n = 8896$ & $10001011000000$ \\
+\hline $5$ & $8896$ & $10001011000000$ \\
+\hline $6$ & $8896$ & $10001011000000$ \\
+\hline $7$ & $x + 2^{6}n = 25344$ & $110001100000000$ \\
+\hline $8$ & $25344$ & $110001100000000$ \\
+\hline $9$ & $x + 2^{7}n = 91136$ & $10110010000000000$ \\
+\hline -- & $x/2^k = 178$ & \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Example of Montgomery Reduction (II)}
+\label{fig:MONT2}
+\end{figure}
+
+Figure~\ref{fig:MONT2} demonstrates the modified algorithm reducing $x = 5555$ modulo $n = 257$ with $k = 9$. 
+With this algorithm a single shift right at the end is the only right shift required to reduce the input instead of $k$ right shifts inside the 
+loop.  Note that for the iterations $t = 2, 5, 6$ and $8$ where the result $x$ is not changed.  In those iterations the $t$'th bit of $x$ is 
+zero and the appropriate multiple of $n$ does not need to be added to force the $t$'th bit of the result to zero.  
+
+\subsection{Digit Based Montgomery Reduction}
+Instead of computing the reduction on a bit-by-bit basis it is actually much faster to compute it on digit-by-digit basis.  Consider the
+previous algorithm re-written to compute the Montgomery reduction in this new fashion.
+
+\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{Montgomery Reduction} (modified II). \\
+\textbf{Input}.   Integer $x$, $n$ and $k$ ($\beta^k > n$) \\
+\textbf{Output}.  $\beta^{-k}x \mbox{ (mod }n\mbox{)}$ \\
+\hline \\
+1.  for $t$ from $0$ to $k - 1$ do \\
+\hspace{3mm}1.1  $x \leftarrow x + \mu n \beta^t$ \\
+2.  Return $x/\beta^k$. \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Algorithm Montgomery Reduction (modified II)}
+\end{figure}
+
+The value $\mu n \beta^t$ is a multiple of the modulus $n$ meaning that it will not change the residue.  If the first digit of 
+the value $\mu n \beta^t$ equals the negative (modulo $\beta$) of the $t$'th digit of $x$ then the addition will result in a zero digit.  This
+problem breaks down to solving the following congruency.  
+
+\begin{center}
+\begin{tabular}{rcl}
+$x_t + \mu n_0$ & $\equiv$ & $0 \mbox{ (mod }\beta\mbox{)}$ \\
+$\mu n_0$ & $\equiv$ & $-x_t \mbox{ (mod }\beta\mbox{)}$ \\
+$\mu$ & $\equiv$ & $-x_t/n_0 \mbox{ (mod }\beta\mbox{)}$ \\
+\end{tabular}
+\end{center}
+
+In each iteration of the loop on step 1 a new value of $\mu$ must be calculated.  The value of $-1/n_0 \mbox{ (mod }\beta\mbox{)}$ is used 
+extensively in this algorithm and should be precomputed.  Let $\rho$ represent the negative of the modular inverse of $n_0$ modulo $\beta$.  
+
+For example, let $\beta = 10$ represent the radix.  Let $n = 17$ represent the modulus which implies $k = 2$ and $\rho \equiv 7$.  Let $x = 33$ 
+represent the value to reduce.
+
+\newpage\begin{figure}
+\begin{center}
+\begin{tabular}{|c|c|c|}
+\hline \textbf{Step ($t$)} & \textbf{Value of $x$} & \textbf{Value of $\mu$} \\
+\hline --                 & $33$ & --\\
+\hline $0$                 & $33 + \mu n = 50$ & $1$ \\
+\hline $1$                 & $50 + \mu n \beta = 900$ & $5$ \\
+\hline
+\end{tabular}
+\end{center}
+\caption{Example of Montgomery Reduction}
+\end{figure}
+
+The final result $900$ is then divided by $\beta^k$ to produce the final result $9$.  The first observation is that $9 \nequiv x \mbox{ (mod }n\mbox{)}$ 
+which implies the result is not the modular residue of $x$ modulo $n$.  However, recall that the residue is actually multiplied by $\beta^{-k}$ in
+the algorithm.  To get the true residue the value must be multiplied by $\beta^k$.  In this case $\beta^k \equiv 15 \mbox{ (mod }n\mbox{)}$ and
+the correct residue is $9 \cdot 15 \equiv 16 \mbox{ (mod }n\mbox{)}$.  
+
+\subsection{Baseline Montgomery Reduction}
+The baseline Montgomery reduction algorithm will produce the residue for any size input.  It is designed to be a catch-all algororithm for 
+Montgomery reductions.  
+
+\newpage\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{mp\_montgomery\_reduce}. \\
+\textbf{Input}.   mp\_int $x$, mp\_int $n$ and a digit $\rho \equiv -1/n_0 \mbox{ (mod }n\mbox{)}$. \\
+\hspace{11.5mm}($0 \le x < n^2, n > 1, (n, \beta) = 1, \beta^k > n$) \\
+\textbf{Output}.  $\beta^{-k}x \mbox{ (mod }n\mbox{)}$ \\
+\hline \\
+1.  $digs \leftarrow 2n.used + 1$ \\
+2.  If $digs < MP\_ARRAY$ and $m.used < \delta$ then \\
+\hspace{3mm}2.1  Use algorithm fast\_mp\_montgomery\_reduce instead. \\
+\\
+Setup $x$ for the reduction. \\
+3.  If $x.alloc < digs$ then grow $x$ to $digs$ digits. \\
+4.  $x.used \leftarrow digs$ \\
+\\
+Eliminate the lower $k$ digits. \\
+5.  For $ix$ from $0$ to $k - 1$ do \\
+\hspace{3mm}5.1  $\mu \leftarrow x_{ix} \cdot \rho \mbox{ (mod }\beta\mbox{)}$ \\
+\hspace{3mm}5.2  $u \leftarrow 0$ \\
+\hspace{3mm}5.3  For $iy$ from $0$ to $k - 1$ do \\
+\hspace{6mm}5.3.1  $\hat r \leftarrow \mu n_{iy} + x_{ix + iy} + u$ \\
+\hspace{6mm}5.3.2  $x_{ix + iy} \leftarrow \hat r \mbox{ (mod }\beta\mbox{)}$ \\
+\hspace{6mm}5.3.3  $u \leftarrow \lfloor \hat r / \beta \rfloor$ \\
+\hspace{3mm}5.4  While $u > 0$ do \\
+\hspace{6mm}5.4.1  $iy \leftarrow iy + 1$ \\
+\hspace{6mm}5.4.2  $x_{ix + iy} \leftarrow x_{ix + iy} + u$ \\
+\hspace{6mm}5.4.3  $u \leftarrow \lfloor x_{ix+iy} / \beta \rfloor$ \\
+\hspace{6mm}5.4.4  $x_{ix + iy} \leftarrow x_{ix+iy} \mbox{ (mod }\beta\mbox{)}$ \\
+\\
+Divide by $\beta^k$ and fix up as required. \\
+6.  $x \leftarrow \lfloor x / \beta^k \rfloor$ \\
+7.  If $x \ge n$ then \\
+\hspace{3mm}7.1  $x \leftarrow x - n$ \\
+8.  Return(\textit{MP\_OKAY}). \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Algorithm mp\_montgomery\_reduce}
+\end{figure}
+
+\textbf{Algorithm mp\_montgomery\_reduce.}
+This algorithm reduces the input $x$ modulo $n$ in place using the Montgomery reduction algorithm.  The algorithm is loosely based
+on algorithm 14.32 of \cite[pp.601]{HAC} except it merges the multiplication of $\mu n \beta^t$ with the addition in the inner loop.  The
+restrictions on this algorithm are fairly easy to adapt to.  First $0 \le x < n^2$ bounds the input to numbers in the same range as 
+for the Barrett algorithm.  Additionally if $n > 1$ and $n$ is odd there will exist a modular inverse $\rho$.  $\rho$ must be calculated in
+advance of this algorithm.  Finally the variable $k$ is fixed and a pseudonym for $n.used$.  
+
+Step 2 decides whether a faster Montgomery algorithm can be used.  It is based on the Comba technique meaning that there are limits on
+the size of the input.  This algorithm is discussed in ~COMBARED~.
+
+Step 5 is the main reduction loop of the algorithm.  The value of $\mu$ is calculated once per iteration in the outer loop.  The inner loop
+calculates $x + \mu n \beta^{ix}$ by multiplying $\mu n$ and adding the result to $x$ shifted by $ix$ digits.  Both the addition and
+multiplication are performed in the same loop to save time and memory.  Step 5.4 will handle any additional carries that escape the inner loop.
+
+Using a quick inspection this algorithm requires $n$ single precision multiplications for the outer loop and $n^2$ single precision multiplications 
+in the inner loop.  In total $n^2 + n$ single precision multiplications which compares favourably to Barrett at $n^2 + 2n - 1$ single precision
+multiplications.  
+
+EXAM,bn_mp_montgomery_reduce.c
+
+This is the baseline implementation of the Montgomery reduction algorithm.  Lines @30,digs@ to @35,}@ determine if the Comba based
+routine can be used instead.  Line @47,mu@ computes the value of $\mu$ for that particular iteration of the outer loop.  
+
+The multiplication $\mu n \beta^{ix}$ is performed in one step in the inner loop.  The alias $tmpx$ refers to the $ix$'th digit of $x$ and
+the alias $tmpn$ refers to the modulus $n$.  
+
+\subsection{Faster ``Comba'' Montgomery Reduction}
+MARK,COMBARED
+
+The Montgomery reduction requires fewer single precision multiplications than a Barrett reduction, however it is much slower due to the serial
+nature of the inner loop.  The Barrett reduction algorithm requires two slightly modified multipliers which can be implemented with the Comba
+technique.  The Montgomery reduction algorithm cannot directly use the Comba technique to any significant advantage since the inner loop calculates
+a $k \times 1$ product $k$ times. 
+
+The biggest obstacle is that at the $ix$'th iteration of the outer loop the value of $x_{ix}$ is required to calculate $\mu$.  This means the 
+carries from $0$ to $ix - 1$ must have been propagated upwards to form a valid $ix$'th digit.  The solution as it turns out is very simple.  
+Perform a Comba like multiplier and inside the outer loop just after the inner loop fix up the $ix + 1$'th digit by forwarding the carry.  
+
+With this change in place the Montgomery reduction algorithm can be performed with a Comba style multiplication loop which substantially increases
+the speed of the algorithm.  
+
+\newpage\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{fast\_mp\_montgomery\_reduce}. \\
+\textbf{Input}.   mp\_int $x$, mp\_int $n$ and a digit $\rho \equiv -1/n_0 \mbox{ (mod }n\mbox{)}$. \\
+\hspace{11.5mm}($0 \le x < n^2, n > 1, (n, \beta) = 1, \beta^k > n$) \\
+\textbf{Output}.  $\beta^{-k}x \mbox{ (mod }n\mbox{)}$ \\
+\hline \\
+Place an array of \textbf{MP\_WARRAY} mp\_word variables called $\hat W$ on the stack. \\
+1.  if $x.alloc < n.used + 1$ then grow $x$ to $n.used + 1$ digits. \\
+Copy the digits of $x$ into the array $\hat W$ \\
+2.  For $ix$ from $0$ to $x.used - 1$ do \\
+\hspace{3mm}2.1  $\hat W_{ix} \leftarrow x_{ix}$ \\
+3.  For $ix$ from $x.used$ to $2n.used - 1$ do \\
+\hspace{3mm}3.1  $\hat W_{ix} \leftarrow 0$ \\
+Elimiate the lower $k$ digits. \\
+4.  for $ix$ from $0$ to $n.used - 1$ do \\
+\hspace{3mm}4.1  $\mu \leftarrow \hat W_{ix} \cdot \rho \mbox{ (mod }\beta\mbox{)}$ \\
+\hspace{3mm}4.2  For $iy$ from $0$ to $n.used - 1$ do \\
+\hspace{6mm}4.2.1  $\hat W_{iy + ix} \leftarrow \hat W_{iy + ix} + \mu \cdot n_{iy}$ \\
+\hspace{3mm}4.3  $\hat W_{ix + 1} \leftarrow \hat W_{ix + 1} + \lfloor \hat W_{ix} / \beta \rfloor$ \\
+Propagate carries upwards. \\
+5.  for $ix$ from $n.used$ to $2n.used + 1$ do \\
+\hspace{3mm}5.1  $\hat W_{ix + 1} \leftarrow \hat W_{ix + 1} + \lfloor \hat W_{ix} / \beta \rfloor$ \\
+Shift right and reduce modulo $\beta$ simultaneously. \\
+6.  for $ix$ from $0$ to $n.used + 1$ do \\
+\hspace{3mm}6.1  $x_{ix} \leftarrow \hat W_{ix + n.used} \mbox{ (mod }\beta\mbox{)}$ \\
+Zero excess digits and fixup $x$. \\
+7.  if $x.used > n.used + 1$ then do \\
+\hspace{3mm}7.1  for $ix$ from $n.used + 1$ to $x.used - 1$ do \\
+\hspace{6mm}7.1.1  $x_{ix} \leftarrow 0$ \\
+8.  $x.used \leftarrow n.used + 1$ \\
+9.  Clamp excessive digits of $x$. \\
+10.  If $x \ge n$ then \\
+\hspace{3mm}10.1  $x \leftarrow x - n$ \\
+11.  Return(\textit{MP\_OKAY}). \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Algorithm fast\_mp\_montgomery\_reduce}
+\end{figure}
+
+\textbf{Algorithm fast\_mp\_montgomery\_reduce.}
+This algorithm will compute the Montgomery reduction of $x$ modulo $n$ using the Comba technique.  It is on most computer platforms significantly
+faster than algorithm mp\_montgomery\_reduce and algorithm mp\_reduce (\textit{Barrett reduction}).  The algorithm has the same restrictions
+on the input as the baseline reduction algorithm.  An additional two restrictions are imposed on this algorithm.  The number of digits $k$ in the 
+the modulus $n$ must not violate $MP\_WARRAY > 2k +1$ and $n < \delta$.   When $\beta = 2^{28}$ this algorithm can be used to reduce modulo
+a modulus of at most $3,556$ bits in length.  
+
+As in the other Comba reduction algorithms there is a $\hat W$ array which stores the columns of the product.  It is initially filled with the
+contents of $x$ with the excess digits zeroed.  The reduction loop is very similar the to the baseline loop at heart.  The multiplication on step
+4.1 can be single precision only since $ab \mbox{ (mod }\beta\mbox{)} \equiv (a \mbox{ mod }\beta)(b \mbox{ mod }\beta)$.  Some multipliers such
+as those on the ARM processors take a variable length time to complete depending on the number of bytes of result it must produce.  By performing
+a single precision multiplication instead half the amount of time is spent.
+
+Also note that digit $\hat W_{ix}$ must have the carry from the $ix - 1$'th digit propagated upwards in order for this to work.  That is what step
+4.3 will do.  In effect over the $n.used$ iterations of the outer loop the $n.used$'th lower columns all have the their carries propagated forwards.  Note
+how the upper bits of those same words are not reduced modulo $\beta$.  This is because those values will be discarded shortly and there is no
+point.
+
+Step 5 will propagate the remainder of the carries upwards.  On step 6 the columns are reduced modulo $\beta$ and shifted simultaneously as they are
+stored in the destination $x$.  
+
+EXAM,bn_fast_mp_montgomery_reduce.c
+
+The $\hat W$ array is first filled with digits of $x$ on line @49,for@ then the rest of the digits are zeroed on line @54,for@.  Both loops share
+the same alias variables to make the code easier to read.  
+
+The value of $\mu$ is calculated in an interesting fashion.  First the value $\hat W_{ix}$ is reduced modulo $\beta$ and cast to a mp\_digit.  This
+forces the compiler to use a single precision multiplication and prevents any concerns about loss of precision.   Line @101,>>@ fixes the carry 
+for the next iteration of the loop by propagating the carry from $\hat W_{ix}$ to $\hat W_{ix+1}$.
+
+The for loop on line @113,for@ propagates the rest of the carries upwards through the columns.  The for loop on line @126,for@ reduces the columns
+modulo $\beta$ and shifts them $k$ places at the same time.  The alias $\_ \hat W$ actually refers to the array $\hat W$ starting at the $n.used$'th
+digit, that is $\_ \hat W_{t} = \hat W_{n.used + t}$.  
+
+\subsection{Montgomery Setup}
+To calculate the variable $\rho$ a relatively simple algorithm will be required.  
+
+\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{mp\_montgomery\_setup}. \\
+\textbf{Input}.   mp\_int $n$ ($n > 1$ and $(n, 2) = 1$) \\
+\textbf{Output}.  $\rho \equiv -1/n_0 \mbox{ (mod }\beta\mbox{)}$ \\
+\hline \\
+1.  $b \leftarrow n_0$ \\
+2.  If $b$ is even return(\textit{MP\_VAL}) \\
+3.  $x \leftarrow (((b + 2) \mbox{ AND } 4) << 1) + b$ \\
+4.  for $k$ from 0 to $\lceil lg(lg(\beta)) \rceil - 2$ do \\
+\hspace{3mm}4.1  $x \leftarrow x \cdot (2 - bx)$ \\
+5.  $\rho \leftarrow \beta - x \mbox{ (mod }\beta\mbox{)}$ \\
+6.  Return(\textit{MP\_OKAY}). \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Algorithm mp\_montgomery\_setup} 
+\end{figure}
+
+\textbf{Algorithm mp\_montgomery\_setup.}
+This algorithm will calculate the value of $\rho$ required within the Montgomery reduction algorithms.  It uses a very interesting trick 
+to calculate $1/n_0$ when $\beta$ is a power of two.  
+
+EXAM,bn_mp_montgomery_setup.c
+
+This source code computes the value of $\rho$ required to perform Montgomery reduction.  It has been modified to avoid performing excess
+multiplications when $\beta$ is not the default 28-bits.  
+
+\section{The Diminished Radix Algorithm}
+The Diminished Radix method of modular reduction \cite{DRMET} is a fairly clever technique which can be more efficient than either the Barrett
+or Montgomery methods for certain forms of moduli.  The technique is based on the following simple congruence.
+
+\begin{equation}
+(x \mbox{ mod } n) + k \lfloor x / n \rfloor \equiv x \mbox{ (mod }(n - k)\mbox{)}
+\end{equation}
+
+This observation was used in the MMB \cite{MMB} block cipher to create a diffusion primitive.  It used the fact that if $n = 2^{31}$ and $k=1$ that 
+then a x86 multiplier could produce the 62-bit product and use  the ``shrd'' instruction to perform a double-precision right shift.  The proof
+of the above equation is very simple.  First write $x$ in the product form.
+
+\begin{equation}
+x = qn + r
+\end{equation}
+
+Now reduce both sides modulo $(n - k)$.
+
+\begin{equation}
+x \equiv qk + r  \mbox{ (mod }(n-k)\mbox{)}
+\end{equation}
+
+The variable $n$ reduces modulo $n - k$ to $k$.  By putting $q = \lfloor x/n \rfloor$ and $r = x \mbox{ mod } n$ 
+into the equation the original congruence is reproduced, thus concluding the proof.  The following algorithm is based on this observation.
+
+\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{Diminished Radix Reduction}. \\
+\textbf{Input}.   Integer $x$, $n$, $k$ \\
+\textbf{Output}.  $x \mbox{ mod } (n - k)$ \\
+\hline \\
+1.  $q \leftarrow \lfloor x / n \rfloor$ \\
+2.  $q \leftarrow k \cdot q$ \\
+3.  $x \leftarrow x \mbox{ (mod }n\mbox{)}$ \\
+4.  $x \leftarrow x + q$ \\
+5.  If $x \ge (n - k)$ then \\
+\hspace{3mm}5.1  $x \leftarrow x - (n - k)$ \\
+\hspace{3mm}5.2  Goto step 1. \\
+6.  Return $x$ \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Algorithm Diminished Radix Reduction}
+\label{fig:DR}
+\end{figure}
+
+This algorithm will reduce $x$ modulo $n - k$ and return the residue.  If $0 \le x < (n - k)^2$ then the algorithm will loop almost always
+once or twice and occasionally three times.  For simplicity sake the value of $x$ is bounded by the following simple polynomial.
+
+\begin{equation} 
+0 \le x < n^2 + k^2 - 2nk
+\end{equation}
+
+The true bound is  $0 \le x < (n - k - 1)^2$ but this has quite a few more terms.  The value of $q$ after step 1 is bounded by the following.
+
+\begin{equation}
+q < n - 2k - k^2/n
+\end{equation}
+
+Since $k^2$ is going to be considerably smaller than $n$ that term will always be zero.  The value of $x$ after step 3 is bounded trivially as
+$0 \le x < n$.  By step four the sum $x + q$ is bounded by 
+
+\begin{equation}
+0 \le q + x < (k + 1)n - 2k^2 - 1
+\end{equation}
+
+With a second pass $q$ will be loosely bounded by $0 \le q < k^2$ after step 2 while $x$ will still be loosely bounded by $0 \le x < n$ after step 3.  After the second pass it is highly unlike that the
+sum in step 4 will exceed $n - k$.  In practice fewer than three passes of the algorithm are required to reduce virtually every input in the 
+range $0 \le x < (n - k - 1)^2$.  
+
+\begin{figure}
+\begin{small}
+\begin{center}
+\begin{tabular}{|l|}
+\hline
+$x = 123456789, n = 256, k = 3$ \\
+\hline $q \leftarrow \lfloor x/n \rfloor = 482253$ \\
+$q \leftarrow q*k = 1446759$ \\
+$x \leftarrow x \mbox{ mod } n = 21$ \\
+$x \leftarrow x + q = 1446780$ \\
+$x \leftarrow x - (n - k) = 1446527$ \\
+\hline 
+$q \leftarrow \lfloor x/n \rfloor = 5650$ \\
+$q \leftarrow q*k = 16950$ \\
+$x \leftarrow x \mbox{ mod } n = 127$ \\
+$x \leftarrow x + q = 17077$ \\
+$x \leftarrow x - (n - k) = 16824$ \\
+\hline 
+$q \leftarrow \lfloor x/n \rfloor = 65$ \\
+$q \leftarrow q*k = 195$ \\
+$x \leftarrow x \mbox{ mod } n = 184$ \\
+$x \leftarrow x + q = 379$ \\
+$x \leftarrow x - (n - k) = 126$ \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Example Diminished Radix Reduction}
+\label{fig:EXDR}
+\end{figure}
+
+Figure~\ref{fig:EXDR} demonstrates the reduction of $x = 123456789$ modulo $n - k = 253$ when $n = 256$ and $k = 3$.  Note that even while $x$
+is considerably larger than $(n - k - 1)^2 = 63504$ the algorithm still converges on the modular residue exceedingly fast.  In this case only
+three passes were required to find the residue $x \equiv 126$.
+
+
+\subsection{Choice of Moduli}
+On the surface this algorithm looks like a very expensive algorithm.  It requires a couple of subtractions followed by multiplication and other
+modular reductions.  The usefulness of this algorithm becomes exceedingly clear when an appropriate modulus is chosen.
+
+Division in general is a very expensive operation to perform.  The one exception is when the division is by a power of the radix of representation used.  
+Division by ten for example is simple for pencil and paper mathematics since it amounts to shifting the decimal place to the right.  Similarly division 
+by two (\textit{or powers of two}) is very simple for binary computers to perform.  It would therefore seem logical to choose $n$ of the form $2^p$ 
+which would imply that $\lfloor x / n \rfloor$ is a simple shift of $x$ right $p$ bits.  
+
+However, there is one operation related to division of power of twos that is even faster than this.  If $n = \beta^p$ then the division may be 
+performed by moving whole digits to the right $p$ places.  In practice division by $\beta^p$ is much faster than division by $2^p$ for any $p$.  
+Also with the choice of $n = \beta^p$ reducing $x$ modulo $n$ merely requires zeroing the digits above the $p-1$'th digit of $x$.  
+
+Throughout the next section the term ``restricted modulus'' will refer to a modulus of the form $\beta^p - k$ whereas the term ``unrestricted
+modulus'' will refer to a modulus of the form $2^p - k$.  The word ``restricted'' in this case refers to the fact that it is based on the 
+$2^p$ logic except $p$ must be a multiple of $lg(\beta)$.  
+
+\subsection{Choice of $k$}
+Now that division and reduction (\textit{step 1 and 3 of figure~\ref{fig:DR}}) have been optimized to simple digit operations the multiplication by $k$
+in step 2 is the most expensive operation.  Fortunately the choice of $k$ is not terribly limited.  For all intents and purposes it might
+as well be a single digit.  The smaller the value of $k$ is the faster the algorithm will be.  
+
+\subsection{Restricted Diminished Radix Reduction}
+The restricted Diminished Radix algorithm can quickly reduce an input modulo a modulus of the form $n = \beta^p - k$.  This algorithm can reduce 
+an input $x$ within the range $0 \le x < n^2$ using only a couple passes of the algorithm demonstrated in figure~\ref{fig:DR}.  The implementation
+of this algorithm has been optimized to avoid additional overhead associated with a division by $\beta^p$, the multiplication by $k$ or the addition 
+of $x$ and $q$.  The resulting algorithm is very efficient and can lead to substantial improvements over Barrett and Montgomery reduction when modular 
+exponentiations are performed.
+
+\newpage\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{mp\_dr\_reduce}. \\
+\textbf{Input}.   mp\_int $x$, $n$ and a mp\_digit $k = \beta - n_0$ \\
+\hspace{11.5mm}($0 \le x < n^2$, $n > 1$, $0 < k < \beta$) \\
+\textbf{Output}.  $x \mbox{ mod } n$ \\
+\hline \\
+1.  $m \leftarrow n.used$ \\
+2.  If $x.alloc < 2m$ then grow $x$ to $2m$ digits. \\
+3.  $\mu \leftarrow 0$ \\
+4.  for $i$ from $0$ to $m - 1$ do \\
+\hspace{3mm}4.1  $\hat r \leftarrow k \cdot x_{m+i} + x_{i} + \mu$ \\
+\hspace{3mm}4.2  $x_{i} \leftarrow \hat r \mbox{ (mod }\beta\mbox{)}$ \\
+\hspace{3mm}4.3  $\mu \leftarrow \lfloor \hat r / \beta \rfloor$ \\
+5.  $x_{m} \leftarrow \mu$ \\
+6.  for $i$ from $m + 1$ to $x.used - 1$ do \\
+\hspace{3mm}6.1  $x_{i} \leftarrow 0$ \\
+7.  Clamp excess digits of $x$. \\
+8.  If $x \ge n$ then \\
+\hspace{3mm}8.1  $x \leftarrow x - n$ \\
+\hspace{3mm}8.2  Goto step 3. \\
+9.  Return(\textit{MP\_OKAY}). \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Algorithm mp\_dr\_reduce}
+\end{figure}
+
+\textbf{Algorithm mp\_dr\_reduce.}
+This algorithm will perform the Dimished Radix reduction of $x$ modulo $n$.  It has similar restrictions to that of the Barrett reduction
+with the addition that $n$ must be of the form $n = \beta^m - k$ where $0 < k <\beta$.  
+
+This algorithm essentially implements the pseudo-code in figure~\ref{fig:DR} except with a slight optimization.  The division by $\beta^m$, multiplication by $k$
+and addition of $x \mbox{ mod }\beta^m$ are all performed simultaneously inside the loop on step 4.  The division by $\beta^m$ is emulated by accessing
+the term at the $m+i$'th position which is subsequently multiplied by $k$ and added to the term at the $i$'th position.  After the loop the $m$'th
+digit is set to the carry and the upper digits are zeroed.  Steps 5 and 6 emulate the reduction modulo $\beta^m$ that should have happend to 
+$x$ before the addition of the multiple of the upper half.  
+
+At step 8 if $x$ is still larger than $n$ another pass of the algorithm is required.  First $n$ is subtracted from $x$ and then the algorithm resumes
+at step 3.  
+
+EXAM,bn_mp_dr_reduce.c
+
+The first step is to grow $x$ as required to $2m$ digits since the reduction is performed in place on $x$.  The label on line @49,top:@ is where
+the algorithm will resume if further reduction passes are required.  In theory it could be placed at the top of the function however, the size of
+the modulus and question of whether $x$ is large enough are invariant after the first pass meaning that it would be a waste of time.  
+
+The aliases $tmpx1$ and $tmpx2$ refer to the digits of $x$ where the latter is offset by $m$ digits.  By reading digits from $x$ offset by $m$ digits
+a division by $\beta^m$ can be simulated virtually for free.  The loop on line @61,for@ performs the bulk of the work (\textit{corresponds to step 4 of algorithm 7.11})
+in this algorithm.
+
+By line @68,mu@ the pointer $tmpx1$ points to the $m$'th digit of $x$ which is where the final carry will be placed.  Similarly by line @71,for@ the 
+same pointer will point to the $m+1$'th digit where the zeroes will be placed.  
+
+Since the algorithm is only valid if both $x$ and $n$ are greater than zero an unsigned comparison suffices to determine if another pass is required.  
+With the same logic at line @82,sub@ the value of $x$ is known to be greater than or equal to $n$ meaning that an unsigned subtraction can be used
+as well.  Since the destination of the subtraction is the larger of the inputs the call to algorithm s\_mp\_sub cannot fail and the return code
+does not need to be checked.
+
+\subsubsection{Setup}
+To setup the restricted Diminished Radix algorithm the value $k = \beta - n_0$ is required.  This algorithm is not really complicated but provided for
+completeness.
+
+\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{mp\_dr\_setup}. \\
+\textbf{Input}.   mp\_int $n$ \\
+\textbf{Output}.  $k = \beta - n_0$ \\
+\hline \\
+1.  $k \leftarrow \beta - n_0$ \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Algorithm mp\_dr\_setup}
+\end{figure}
+
+EXAM,bn_mp_dr_setup.c
+
+\subsubsection{Modulus Detection}
+Another algorithm which will be useful is the ability to detect a restricted Diminished Radix modulus.  An integer is said to be
+of restricted Diminished Radix form if all of the digits are equal to $\beta - 1$ except the trailing digit which may be any value.
+
+\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{mp\_dr\_is\_modulus}. \\
+\textbf{Input}.   mp\_int $n$ \\
+\textbf{Output}.  $1$ if $n$ is in D.R form, $0$ otherwise \\
+\hline
+1.  If $n.used < 2$ then return($0$). \\
+2.  for $ix$ from $1$ to $n.used - 1$ do \\
+\hspace{3mm}2.1  If $n_{ix} \ne \beta - 1$ return($0$). \\
+3.  Return($1$). \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Algorithm mp\_dr\_is\_modulus}
+\end{figure}
+
+\textbf{Algorithm mp\_dr\_is\_modulus.}
+This algorithm determines if a value is in Diminished Radix form.  Step 1 rejects obvious cases where fewer than two digits are
+in the mp\_int.  Step 2 tests all but the first digit to see if they are equal to $\beta - 1$.  If the algorithm manages to get to
+step 3 then $n$ must be of Diminished Radix form.
+
+EXAM,bn_mp_dr_is_modulus.c
+
+\subsection{Unrestricted Diminished Radix Reduction}
+The unrestricted Diminished Radix algorithm allows modular reductions to be performed when the modulus is of the form $2^p - k$.  This algorithm
+is a straightforward adaptation of algorithm~\ref{fig:DR}.
+
+In general the restricted Diminished Radix reduction algorithm is much faster since it has considerably lower overhead.  However, this new
+algorithm is much faster than either Montgomery or Barrett reduction when the moduli are of the appropriate form.
+
+\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{mp\_reduce\_2k}. \\
+\textbf{Input}.   mp\_int $a$ and $n$.  mp\_digit $k$  \\
+\hspace{11.5mm}($a \ge 0$, $n > 1$, $0 < k < \beta$, $n + k$ is a power of two) \\
+\textbf{Output}.  $a \mbox{ (mod }n\mbox{)}$ \\
+\hline
+1.  $p \leftarrow \lceil lg(n) \rceil$  (\textit{mp\_count\_bits}) \\
+2.  While $a \ge n$ do \\
+\hspace{3mm}2.1  $q \leftarrow \lfloor a / 2^p \rfloor$ (\textit{mp\_div\_2d}) \\
+\hspace{3mm}2.2  $a \leftarrow a \mbox{ (mod }2^p\mbox{)}$ (\textit{mp\_mod\_2d}) \\
+\hspace{3mm}2.3  $q \leftarrow q \cdot k$ (\textit{mp\_mul\_d}) \\
+\hspace{3mm}2.4  $a \leftarrow a - q$ (\textit{s\_mp\_sub}) \\
+\hspace{3mm}2.5  If $a \ge n$ then do \\
+\hspace{6mm}2.5.1  $a \leftarrow a - n$ \\
+3.  Return(\textit{MP\_OKAY}). \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Algorithm mp\_reduce\_2k}
+\end{figure}
+
+\textbf{Algorithm mp\_reduce\_2k.}
+This algorithm quickly reduces an input $a$ modulo an unrestricted Diminished Radix modulus $n$.  Division by $2^p$ is emulated with a right
+shift which makes the algorithm fairly inexpensive to use.  
+
+EXAM,bn_mp_reduce_2k.c
+
+The algorithm mp\_count\_bits calculates the number of bits in an mp\_int which is used to find the initial value of $p$.  The call to mp\_div\_2d
+on line @31,mp_div_2d@ calculates both the quotient $q$ and the remainder $a$ required.  By doing both in a single function call the code size
+is kept fairly small.  The multiplication by $k$ is only performed if $k > 1$. This allows reductions modulo $2^p - 1$ to be performed without
+any multiplications.  
+
+The unsigned s\_mp\_add, mp\_cmp\_mag and s\_mp\_sub are used in place of their full sign counterparts since the inputs are only valid if they are 
+positive.  By using the unsigned versions the overhead is kept to a minimum.  
+
+\subsubsection{Unrestricted Setup}
+To setup this reduction algorithm the value of $k = 2^p - n$ is required.  
+
+\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{mp\_reduce\_2k\_setup}. \\
+\textbf{Input}.   mp\_int $n$   \\
+\textbf{Output}.  $k = 2^p - n$ \\
+\hline
+1.  $p \leftarrow \lceil lg(n) \rceil$  (\textit{mp\_count\_bits}) \\
+2.  $x \leftarrow 2^p$ (\textit{mp\_2expt}) \\
+3.  $x \leftarrow x - n$ (\textit{mp\_sub}) \\
+4.  $k \leftarrow x_0$ \\
+5.  Return(\textit{MP\_OKAY}). \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Algorithm mp\_reduce\_2k\_setup}
+\end{figure}
+
+\textbf{Algorithm mp\_reduce\_2k\_setup.}
+This algorithm computes the value of $k$ required for the algorithm mp\_reduce\_2k.  By making a temporary variable $x$ equal to $2^p$ a subtraction
+is sufficient to solve for $k$.  Alternatively if $n$ has more than one digit the value of $k$ is simply $\beta - n_0$.  
+
+EXAM,bn_mp_reduce_2k_setup.c
+
+\subsubsection{Unrestricted Detection}
+An integer $n$ is a valid unrestricted Diminished Radix modulus if either of the following are true.
+
+\begin{enumerate}
+\item  The number has only one digit.
+\item  The number has more than one digit and every bit from the $\beta$'th to the most significant is one.
+\end{enumerate}
+
+If either condition is true than there is a power of two $2^p$ such that $0 < 2^p - n < \beta$.   If the input is only
+one digit than it will always be of the correct form.  Otherwise all of the bits above the first digit must be one.  This arises from the fact
+that there will be value of $k$ that when added to the modulus causes a carry in the first digit which propagates all the way to the most
+significant bit.  The resulting sum will be a power of two.
+
+\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{mp\_reduce\_is\_2k}. \\
+\textbf{Input}.   mp\_int $n$   \\
+\textbf{Output}.  $1$ if of proper form, $0$ otherwise \\
+\hline
+1.  If $n.used = 0$ then return($0$). \\
+2.  If $n.used = 1$ then return($1$). \\
+3.  $p \leftarrow \lceil lg(n) \rceil$  (\textit{mp\_count\_bits}) \\
+4.  for $x$ from $lg(\beta)$ to $p$ do \\
+\hspace{3mm}4.1  If the ($x \mbox{ mod }lg(\beta)$)'th bit of the $\lfloor x / lg(\beta) \rfloor$ of $n$ is zero then return($0$). \\
+5.  Return($1$). \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Algorithm mp\_reduce\_is\_2k}
+\end{figure}
+
+\textbf{Algorithm mp\_reduce\_is\_2k.}
+This algorithm quickly determines if a modulus is of the form required for algorithm mp\_reduce\_2k to function properly.  
+
+EXAM,bn_mp_reduce_is_2k.c
+
+
+
+\section{Algorithm Comparison}
+So far three very different algorithms for modular reduction have been discussed.  Each of the algorithms have their own strengths and weaknesses
+that makes having such a selection very useful.  The following table sumarizes the three algorithms along with comparisons of work factors.  Since
+all three algorithms have the restriction that $0 \le x < n^2$ and $n > 1$ those limitations are not included in the table.  
+
+\begin{center}
+\begin{small}
+\begin{tabular}{|c|c|c|c|c|c|}
+\hline \textbf{Method} & \textbf{Work Required} & \textbf{Limitations} & \textbf{$m = 8$} & \textbf{$m = 32$} & \textbf{$m = 64$} \\
+\hline Barrett    & $m^2 + 2m - 1$ & None              & $79$ & $1087$ & $4223$ \\
+\hline Montgomery & $m^2 + m$      & $n$ must be odd   & $72$ & $1056$ & $4160$ \\
+\hline D.R.       & $2m$           & $n = \beta^m - k$ & $16$ & $64$   & $128$  \\
+\hline
+\end{tabular}
+\end{small}
+\end{center}
+
+In theory Montgomery and Barrett reductions would require roughly the same amount of time to complete.  However, in practice since Montgomery
+reduction can be written as a single function with the Comba technique it is much faster.  Barrett reduction suffers from the overhead of
+calling the half precision multipliers, addition and division by $\beta$ algorithms.
+
+For almost every cryptographic algorithm Montgomery reduction is the algorithm of choice.  The one set of algorithms where Diminished Radix reduction truly
+shines are based on the discrete logarithm problem such as Diffie-Hellman \cite{DH} and ElGamal \cite{ELGAMAL}.  In these algorithms
+primes of the form $\beta^m - k$ can be found and shared amongst users.  These primes will allow the Diminished Radix algorithm to be used in
+modular exponentiation to greatly speed up the operation.
+
+
+
+\section*{Exercises}
+\begin{tabular}{cl}
+$\left [ 3 \right ]$ & Prove that the ``trick'' in algorithm mp\_montgomery\_setup actually \\
+                     & calculates the correct value of $\rho$. \\
+                     & \\
+$\left [ 2 \right ]$ & Devise an algorithm to reduce modulo $n + k$ for small $k$ quickly.  \\
+                     & \\
+$\left [ 4 \right ]$ & Prove that the pseudo-code algorithm ``Diminished Radix Reduction'' \\
+                     & (\textit{figure~\ref{fig:DR}}) terminates.  Also prove the probability that it will \\
+                     & terminate within $1 \le k \le 10$ iterations. \\
+                     & \\
+\end{tabular}                     
+
+
+\chapter{Exponentiation}
+Exponentiation is the operation of raising one variable to the power of another, for example, $a^b$.  A variant of exponentiation, computed
+in a finite field or ring, is called modular exponentiation.  This latter style of operation is typically used in public key 
+cryptosystems such as RSA and Diffie-Hellman.  The ability to quickly compute modular exponentiations is of great benefit to any
+such cryptosystem and many methods have been sought to speed it up.
+
+\section{Exponentiation Basics}
+A trivial algorithm would simply multiply $a$ against itself $b - 1$ times to compute the exponentiation desired.  However, as $b$ grows in size
+the number of multiplications becomes prohibitive.  Imagine what would happen if $b$ $\approx$ $2^{1024}$ as is the case when computing an RSA signature
+with a $1024$-bit key.  Such a calculation could never be completed as it would take simply far too long.
+
+Fortunately there is a very simple algorithm based on the laws of exponents.  Recall that $lg_a(a^b) = b$ and that $lg_a(a^ba^c) = b + c$ which
+are two trivial relationships between the base and the exponent.  Let $b_i$ represent the $i$'th bit of $b$ starting from the least 
+significant bit.  If $b$ is a $k$-bit integer than the following equation is true.
+
+\begin{equation}
+a^b = \prod_{i=0}^{k-1} a^{2^i \cdot b_i}
+\end{equation}
+
+By taking the base $a$ logarithm of both sides of the equation the following equation is the result.
+
+\begin{equation}
+b = \sum_{i=0}^{k-1}2^i \cdot b_i
+\end{equation}
+
+The term $a^{2^i}$ can be found from the $i - 1$'th term by squaring the term since $\left ( a^{2^i} \right )^2$ is equal to
+$a^{2^{i+1}}$.  This observation forms the basis of essentially all fast exponentiation algorithms.  It requires $k$ squarings and on average
+$k \over 2$ multiplications to compute the result.  This is indeed quite an improvement over simply multiplying by $a$ a total of $b-1$ times.
+
+While this current method is a considerable speed up there are further improvements to be made.  For example, the $a^{2^i}$ term does not need to 
+be computed in an auxilary variable.  Consider the following equivalent algorithm.
+
+\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{Left to Right Exponentiation}. \\
+\textbf{Input}.   Integer $a$, $b$ and $k$ \\
+\textbf{Output}.  $c = a^b$ \\
+\hline \\
+1.  $c \leftarrow 1$ \\
+2.  for $i$ from $k - 1$ to $0$ do \\
+\hspace{3mm}2.1  $c \leftarrow c^2$ \\
+\hspace{3mm}2.2  $c \leftarrow c \cdot a^{b_i}$ \\
+3.  Return $c$. \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Left to Right Exponentiation}
+\label{fig:LTOR}
+\end{figure}
+
+This algorithm starts from the most significant bit and works towards the least significant bit.  When the $i$'th bit of $b$ is set $a$ is
+multiplied against the current product.  In each iteration the product is squared which doubles the exponent of the individual terms of the
+product.  
+
+For example, let $b = 101100_2 \equiv 44_{10}$.  The following chart demonstrates the actions of the algorithm.
+
+\newpage\begin{figure}
+\begin{center}
+\begin{tabular}{|c|c|}
+\hline \textbf{Value of $i$} & \textbf{Value of $c$} \\
+\hline - & $1$ \\
+\hline $5$ & $a$ \\
+\hline $4$ & $a^2$ \\
+\hline $3$ & $a^4 \cdot a$ \\
+\hline $2$ & $a^8 \cdot a^2 \cdot a$ \\
+\hline $1$ & $a^{16} \cdot a^4 \cdot a^2$ \\
+\hline $0$ & $a^{32} \cdot a^8 \cdot a^4$ \\
+\hline
+\end{tabular}
+\end{center}
+\caption{Example of Left to Right Exponentiation}
+\end{figure}
+
+When the product $a^{32} \cdot a^8 \cdot a^4$ is simplified it is equal $a^{44}$ which is the desired exponentiation.  This particular algorithm is 
+called ``Left to Right'' because it reads the exponent in that order.  All of the exponentiation algorithms that will be presented are of this nature.  
+
+\subsection{Single Digit Exponentiation}
+The first algorithm in the series of exponentiation algorithms will be an unbounded algorithm where the exponent is a single digit.  It is intended 
+to be used when a small power of an input is required (\textit{e.g. $a^5$}).  It is faster than simply multiplying $b - 1$ times for all values of 
+$b$ that are greater than three.  
+
+\newpage\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{mp\_expt\_d}. \\
+\textbf{Input}.   mp\_int $a$ and mp\_digit $b$ \\
+\textbf{Output}.  $c = a^b$ \\
+\hline \\
+1.  $g \leftarrow a$ (\textit{mp\_init\_copy}) \\
+2.  $c \leftarrow 1$ (\textit{mp\_set}) \\
+3.  for $x$ from 1 to $lg(\beta)$ do \\
+\hspace{3mm}3.1  $c \leftarrow c^2$ (\textit{mp\_sqr}) \\
+\hspace{3mm}3.2  If $b$ AND $2^{lg(\beta) - 1} \ne 0$ then \\
+\hspace{6mm}3.2.1  $c \leftarrow c \cdot g$ (\textit{mp\_mul}) \\
+\hspace{3mm}3.3  $b \leftarrow b << 1$ \\
+4.  Clear $g$. \\
+5.  Return(\textit{MP\_OKAY}). \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Algorithm mp\_expt\_d}
+\end{figure}
+
+\textbf{Algorithm mp\_expt\_d.}
+This algorithm computes the value of $a$ raised to the power of a single digit $b$.  It uses the left to right exponentiation algorithm to
+quickly compute the exponentiation.  It is loosely based on algorithm 14.79 of HAC \cite[pp. 615]{HAC} with the difference that the 
+exponent is a fixed width.  
+
+A copy of $a$ is made first to allow destination variable $c$ be the same as the source variable $a$.  The result is set to the initial value of 
+$1$ in the subsequent step.
+
+Inside the loop the exponent is read from the most significant bit first down to the least significant bit.  First $c$ is invariably squared
+on step 3.1.  In the following step if the most significant bit of $b$ is one the copy of $a$ is multiplied against $c$.  The value
+of $b$ is shifted left one bit to make the next bit down from the most signficant bit the new most significant bit.  In effect each
+iteration of the loop moves the bits of the exponent $b$ upwards to the most significant location.
+
+EXAM,bn_mp_expt_d.c
+
+Line @29,mp_set@ sets the initial value of the result to $1$.  Next the loop on line @31,for@ steps through each bit of the exponent starting from
+the most significant down towards the least significant. The invariant squaring operation placed on line @333,mp_sqr@ is performed first.  After 
+the squaring the result $c$ is multiplied by the base $g$ if and only if the most significant bit of the exponent is set.  The shift on line
+@47,<<@ moves all of the bits of the exponent upwards towards the most significant location.  
+
+\section{$k$-ary Exponentiation}
+When calculating an exponentiation the most time consuming bottleneck is the multiplications which are in general a small factor
+slower than squaring.  Recall from the previous algorithm that $b_{i}$ refers to the $i$'th bit of the exponent $b$.  Suppose instead it referred to
+the $i$'th $k$-bit digit of the exponent of $b$.  For $k = 1$ the definitions are synonymous and for $k > 1$ algorithm~\ref{fig:KARY}
+computes the same exponentiation.  A group of $k$ bits from the exponent is called a \textit{window}.  That is it is a small window on only a
+portion of the entire exponent.  Consider the following modification to the basic left to right exponentiation algorithm.
+
+\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{$k$-ary Exponentiation}. \\
+\textbf{Input}.   Integer $a$, $b$, $k$ and $t$ \\
+\textbf{Output}.  $c = a^b$ \\
+\hline \\
+1.  $c \leftarrow 1$ \\
+2.  for $i$ from $t - 1$ to $0$ do \\
+\hspace{3mm}2.1  $c \leftarrow c^{2^k} $ \\
+\hspace{3mm}2.2  Extract the $i$'th $k$-bit word from $b$ and store it in $g$. \\
+\hspace{3mm}2.3  $c \leftarrow c \cdot a^g$ \\
+3.  Return $c$. \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{$k$-ary Exponentiation}
+\label{fig:KARY}
+\end{figure}
+
+The squaring on step 2.1 can be calculated by squaring the value $c$ successively $k$ times.  If the values of $a^g$ for $0 < g < 2^k$ have been
+precomputed this algorithm requires only $t$ multiplications and $tk$ squarings.  The table can be generated with $2^{k - 1} - 1$ squarings and
+$2^{k - 1} + 1$ multiplications.  This algorithm assumes that the number of bits in the exponent is evenly divisible by $k$.  
+However, when it is not the remaining $0 < x \le k - 1$ bits can be handled with algorithm~\ref{fig:LTOR}.
+
+Suppose $k = 4$ and $t = 100$.  This modified algorithm will require $109$ multiplications and $408$ squarings to compute the exponentiation.  The
+original algorithm would on average have required $200$ multiplications and $400$ squrings to compute the same value.  The total number of squarings
+has increased slightly but the number of multiplications has nearly halved.
+
+\subsection{Optimal Values of $k$}
+An optimal value of $k$ will minimize $2^{k} + \lceil n / k \rceil + n - 1$ for a fixed number of bits in the exponent $n$.  The simplest
+approach is to brute force search amongst the values $k = 2, 3, \ldots, 8$ for the lowest result.  Table~\ref{fig:OPTK} lists optimal values of $k$
+for various exponent sizes and compares the number of multiplication and squarings required against algorithm~\ref{fig:LTOR}.  
+
+\begin{figure}[here]
+\begin{center}
+\begin{small}
+\begin{tabular}{|c|c|c|c|c|c|}
+\hline \textbf{Exponent (bits)} & \textbf{Optimal $k$} & \textbf{Work at $k$} & \textbf{Work with ~\ref{fig:LTOR}} \\
+\hline $16$ & $2$ & $27$ & $24$ \\
+\hline $32$ & $3$ & $49$ & $48$ \\
+\hline $64$ & $3$ & $92$ & $96$ \\
+\hline $128$ & $4$ & $175$ & $192$ \\
+\hline $256$ & $4$ & $335$ & $384$ \\
+\hline $512$ & $5$ & $645$ & $768$ \\
+\hline $1024$ & $6$ & $1257$ & $1536$ \\
+\hline $2048$ & $6$ & $2452$ & $3072$ \\
+\hline $4096$ & $7$ & $4808$ & $6144$ \\
+\hline
+\end{tabular}
+\end{small}
+\end{center}
+\caption{Optimal Values of $k$ for $k$-ary Exponentiation}
+\label{fig:OPTK}
+\end{figure}
+
+\subsection{Sliding-Window Exponentiation}
+A simple modification to the previous algorithm is only generate the upper half of the table in the range $2^{k-1} \le g < 2^k$.  Essentially
+this is a table for all values of $g$ where the most significant bit of $g$ is a one.  However, in order for this to be allowed in the 
+algorithm values of $g$ in the range $0 \le g < 2^{k-1}$ must be avoided.  
+
+Table~\ref{fig:OPTK2} lists optimal values of $k$ for various exponent sizes and compares the work required against algorithm~\ref{fig:KARY}.  
+
+\begin{figure}[here]
+\begin{center}
+\begin{small}
+\begin{tabular}{|c|c|c|c|c|c|}
+\hline \textbf{Exponent (bits)} & \textbf{Optimal $k$} & \textbf{Work at $k$} & \textbf{Work with ~\ref{fig:KARY}} \\
+\hline $16$ & $3$ & $24$ & $27$ \\
+\hline $32$ & $3$ & $45$ & $49$ \\
+\hline $64$ & $4$ & $87$ & $92$ \\
+\hline $128$ & $4$ & $167$ & $175$ \\
+\hline $256$ & $5$ & $322$ & $335$ \\
+\hline $512$ & $6$ & $628$ & $645$ \\
+\hline $1024$ & $6$ & $1225$ & $1257$ \\
+\hline $2048$ & $7$ & $2403$ & $2452$ \\
+\hline $4096$ & $8$ & $4735$ & $4808$ \\
+\hline
+\end{tabular}
+\end{small}
+\end{center}
+\caption{Optimal Values of $k$ for Sliding Window Exponentiation}
+\label{fig:OPTK2}
+\end{figure}
+
+\newpage\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{Sliding Window $k$-ary Exponentiation}. \\
+\textbf{Input}.   Integer $a$, $b$, $k$ and $t$ \\
+\textbf{Output}.  $c = a^b$ \\
+\hline \\
+1.  $c \leftarrow 1$ \\
+2.  for $i$ from $t - 1$ to $0$ do \\
+\hspace{3mm}2.1  If the $i$'th bit of $b$ is a zero then \\
+\hspace{6mm}2.1.1   $c \leftarrow c^2$ \\
+\hspace{3mm}2.2  else do \\
+\hspace{6mm}2.2.1  $c \leftarrow c^{2^k}$ \\
+\hspace{6mm}2.2.2  Extract the $k$ bits from $(b_{i}b_{i-1}\ldots b_{i-(k-1)})$ and store it in $g$. \\
+\hspace{6mm}2.2.3  $c \leftarrow c \cdot a^g$ \\
+\hspace{6mm}2.2.4  $i \leftarrow i - k$ \\
+3.  Return $c$. \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Sliding Window $k$-ary Exponentiation}
+\end{figure}
+
+Similar to the previous algorithm this algorithm must have a special handler when fewer than $k$ bits are left in the exponent.  While this
+algorithm requires the same number of squarings it can potentially have fewer multiplications.  The pre-computed table $a^g$ is also half
+the size as the previous table.  
+
+Consider the exponent $b = 111101011001000_2 \equiv 31432_{10}$ with $k = 3$ using both algorithms.  The first algorithm will divide the exponent up as 
+the following five $3$-bit words $b \equiv \left ( 111, 101, 011, 001, 000 \right )_{2}$.  The second algorithm will break the 
+exponent as $b \equiv \left ( 111, 101, 0, 110, 0, 100, 0 \right )_{2}$.  The single digit $0$ in the second representation are where
+a single squaring took place instead of a squaring and multiplication.  In total the first method requires $10$ multiplications and $18$ 
+squarings.  The second method requires $8$ multiplications and $18$ squarings.  
+
+In general the sliding window method is never slower than the generic $k$-ary method and often it is slightly faster.  
+
+\section{Modular Exponentiation}
+
+Modular exponentiation is essentially computing the power of a base within a finite field or ring.  For example, computing 
+$d \equiv a^b \mbox{ (mod }c\mbox{)}$ is a modular exponentiation.  Instead of first computing $a^b$ and then reducing it 
+modulo $c$ the intermediate result is reduced modulo $c$ after every squaring or multiplication operation.  
+
+This guarantees that any intermediate result is bounded by $0 \le d \le c^2 - 2c + 1$ and can be reduced modulo $c$ quickly using
+one of the algorithms presented in ~REDUCTION~.  
+
+Before the actual modular exponentiation algorithm can be written a wrapper algorithm must be written first.  This algorithm
+will allow the exponent $b$ to be negative which is computed as $c \equiv \left (1 / a \right )^{\vert b \vert} \mbox{(mod }d\mbox{)}$. The
+value of $(1/a) \mbox{ mod }c$ is computed using the modular inverse (\textit{see \ref{sec;modinv}}).  If no inverse exists the algorithm
+terminates with an error.  
+
+\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{mp\_exptmod}. \\
+\textbf{Input}.   mp\_int $a$, $b$ and $c$ \\
+\textbf{Output}.  $y \equiv g^x \mbox{ (mod }p\mbox{)}$ \\
+\hline \\
+1.  If $c.sign = MP\_NEG$ return(\textit{MP\_VAL}). \\
+2.  If $b.sign = MP\_NEG$ then \\
+\hspace{3mm}2.1  $g' \leftarrow g^{-1} \mbox{ (mod }c\mbox{)}$ \\
+\hspace{3mm}2.2  $x' \leftarrow \vert x \vert$ \\
+\hspace{3mm}2.3  Compute $d \equiv g'^{x'} \mbox{ (mod }c\mbox{)}$ via recursion. \\
+3.  if $p$ is odd \textbf{OR} $p$ is a D.R. modulus then \\
+\hspace{3mm}3.1  Compute $y \equiv g^{x} \mbox{ (mod }p\mbox{)}$ via algorithm mp\_exptmod\_fast. \\
+4.  else \\
+\hspace{3mm}4.1  Compute $y \equiv g^{x} \mbox{ (mod }p\mbox{)}$ via algorithm s\_mp\_exptmod. \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Algorithm mp\_exptmod}
+\end{figure}
+
+\textbf{Algorithm mp\_exptmod.}
+The first algorithm which actually performs modular exponentiation is algorithm s\_mp\_exptmod.  It is a sliding window $k$-ary algorithm 
+which uses Barrett reduction to reduce the product modulo $p$.  The second algorithm mp\_exptmod\_fast performs the same operation 
+except it uses either Montgomery or Diminished Radix reduction.  The two latter reduction algorithms are clumped in the same exponentiation
+algorithm since their arguments are essentially the same (\textit{two mp\_ints and one mp\_digit}).  
+
+EXAM,bn_mp_exptmod.c
+
+In order to keep the algorithms in a known state the first step on line @29,if@ is to reject any negative modulus as input.  If the exponent is
+negative the algorithm tries to perform a modular exponentiation with the modular inverse of the base $G$.  The temporary variable $tmpG$ is assigned
+the modular inverse of $G$ and $tmpX$ is assigned the absolute value of $X$.  The algorithm will recuse with these new values with a positive
+exponent.
+
+If the exponent is positive the algorithm resumes the exponentiation.  Line @63,dr_@ determines if the modulus is of the restricted Diminished Radix 
+form.  If it is not line @65,reduce@ attempts to determine if it is of a unrestricted Diminished Radix form.  The integer $dr$ will take on one
+of three values.
+
+\begin{enumerate}
+\item $dr = 0$ means that the modulus is not of either restricted or unrestricted Diminished Radix form.
+\item $dr = 1$ means that the modulus is of restricted Diminished Radix form.
+\item $dr = 2$ means that the modulus is of unrestricted Diminished Radix form.
+\end{enumerate}
+
+Line @69,if@ determines if the fast modular exponentiation algorithm can be used.  It is allowed if $dr \ne 0$ or if the modulus is odd.  Otherwise,
+the slower s\_mp\_exptmod algorithm is used which uses Barrett reduction.  
+
+\subsection{Barrett Modular Exponentiation}
+
+\newpage\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{s\_mp\_exptmod}. \\
+\textbf{Input}.   mp\_int $a$, $b$ and $c$ \\
+\textbf{Output}.  $y \equiv g^x \mbox{ (mod }p\mbox{)}$ \\
+\hline \\
+1.  $k \leftarrow lg(x)$ \\
+2.  $winsize \leftarrow  \left \lbrace \begin{array}{ll}
+                              2 &  \mbox{if }k \le 7 \\
+                              3 &  \mbox{if }7 < k \le 36 \\
+                              4 &  \mbox{if }36 < k \le 140 \\
+                              5 &  \mbox{if }140 < k \le 450 \\
+                              6 &  \mbox{if }450 < k \le 1303 \\
+                              7 &  \mbox{if }1303 < k \le 3529 \\
+                              8 &  \mbox{if }3529 < k \\
+                              \end{array} \right .$ \\
+3.  Initialize $2^{winsize}$ mp\_ints in an array named $M$ and one mp\_int named $\mu$ \\
+4.  Calculate the $\mu$ required for Barrett Reduction (\textit{mp\_reduce\_setup}). \\
+5.  $M_1 \leftarrow g \mbox{ (mod }p\mbox{)}$ \\
+\\
+Setup the table of small powers of $g$.  First find $g^{2^{winsize}}$ and then all multiples of it. \\
+6.  $k \leftarrow 2^{winsize - 1}$ \\
+7.  $M_{k} \leftarrow M_1$ \\
+8.  for $ix$ from 0 to $winsize - 2$ do \\
+\hspace{3mm}8.1  $M_k \leftarrow \left ( M_k \right )^2$ (\textit{mp\_sqr})  \\
+\hspace{3mm}8.2  $M_k \leftarrow M_k \mbox{ (mod }p\mbox{)}$ (\textit{mp\_reduce}) \\
+9.  for $ix$ from $2^{winsize - 1} + 1$ to $2^{winsize} - 1$ do \\
+\hspace{3mm}9.1  $M_{ix} \leftarrow M_{ix - 1} \cdot M_{1}$ (\textit{mp\_mul}) \\
+\hspace{3mm}9.2  $M_{ix} \leftarrow M_{ix} \mbox{ (mod }p\mbox{)}$ (\textit{mp\_reduce}) \\
+10.  $res \leftarrow 1$ \\
+\\
+Start Sliding Window. \\
+11.  $mode \leftarrow 0, bitcnt \leftarrow 1, buf \leftarrow 0, digidx \leftarrow x.used - 1, bitcpy \leftarrow 0, bitbuf \leftarrow 0$ \\
+12.  Loop \\
+\hspace{3mm}12.1  $bitcnt \leftarrow bitcnt - 1$ \\
+\hspace{3mm}12.2  If $bitcnt = 0$ then do \\
+\hspace{6mm}12.2.1  If $digidx = -1$ goto step 13. \\
+\hspace{6mm}12.2.2  $buf \leftarrow x_{digidx}$ \\
+\hspace{6mm}12.2.3  $digidx \leftarrow digidx - 1$ \\
+\hspace{6mm}12.2.4  $bitcnt \leftarrow lg(\beta)$ \\
+Continued on next page. \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Algorithm s\_mp\_exptmod}
+\end{figure}
+
+\newpage\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{s\_mp\_exptmod} (\textit{continued}). \\
+\textbf{Input}.   mp\_int $a$, $b$ and $c$ \\
+\textbf{Output}.  $y \equiv g^x \mbox{ (mod }p\mbox{)}$ \\
+\hline \\
+\hspace{3mm}12.3  $y \leftarrow (buf >> (lg(\beta) - 1))$ AND $1$ \\
+\hspace{3mm}12.4  $buf \leftarrow buf << 1$ \\
+\hspace{3mm}12.5  if $mode = 0$ and $y = 0$ then goto step 12. \\
+\hspace{3mm}12.6  if $mode = 1$ and $y = 0$ then do \\
+\hspace{6mm}12.6.1  $res \leftarrow res^2$ \\
+\hspace{6mm}12.6.2  $res \leftarrow res \mbox{ (mod }p\mbox{)}$ \\
+\hspace{6mm}12.6.3  Goto step 12. \\
+\hspace{3mm}12.7  $bitcpy \leftarrow bitcpy + 1$ \\
+\hspace{3mm}12.8  $bitbuf \leftarrow bitbuf + (y << (winsize - bitcpy))$ \\
+\hspace{3mm}12.9  $mode \leftarrow 2$ \\
+\hspace{3mm}12.10  If $bitcpy = winsize$ then do \\
+\hspace{6mm}Window is full so perform the squarings and single multiplication. \\
+\hspace{6mm}12.10.1  for $ix$ from $0$ to $winsize -1$ do \\
+\hspace{9mm}12.10.1.1  $res \leftarrow res^2$ \\
+\hspace{9mm}12.10.1.2  $res \leftarrow res \mbox{ (mod }p\mbox{)}$ \\
+\hspace{6mm}12.10.2  $res \leftarrow res \cdot M_{bitbuf}$ \\
+\hspace{6mm}12.10.3  $res \leftarrow res \mbox{ (mod }p\mbox{)}$ \\
+\hspace{6mm}Reset the window. \\
+\hspace{6mm}12.10.4  $bitcpy \leftarrow 0, bitbuf \leftarrow 0, mode \leftarrow 1$ \\
+\\
+No more windows left.  Check for residual bits of exponent. \\
+13.  If $mode = 2$ and $bitcpy > 0$ then do \\
+\hspace{3mm}13.1  for $ix$ form $0$ to $bitcpy - 1$ do \\
+\hspace{6mm}13.1.1  $res \leftarrow res^2$ \\
+\hspace{6mm}13.1.2  $res \leftarrow res \mbox{ (mod }p\mbox{)}$ \\
+\hspace{6mm}13.1.3  $bitbuf \leftarrow bitbuf << 1$ \\
+\hspace{6mm}13.1.4  If $bitbuf$ AND $2^{winsize} \ne 0$ then do \\
+\hspace{9mm}13.1.4.1  $res \leftarrow res \cdot M_{1}$ \\
+\hspace{9mm}13.1.4.2  $res \leftarrow res \mbox{ (mod }p\mbox{)}$ \\
+14.  $y \leftarrow res$ \\
+15.  Clear $res$, $mu$ and the $M$ array. \\
+16.  Return(\textit{MP\_OKAY}). \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Algorithm s\_mp\_exptmod (continued)}
+\end{figure}
+
+\textbf{Algorithm s\_mp\_exptmod.}
+This algorithm computes the $x$'th power of $g$ modulo $p$ and stores the result in $y$.  It takes advantage of the Barrett reduction
+algorithm to keep the product small throughout the algorithm.
+
+The first two steps determine the optimal window size based on the number of bits in the exponent.  The larger the exponent the 
+larger the window size becomes.  After a window size $winsize$ has been chosen an array of $2^{winsize}$ mp\_int variables is allocated.  This
+table will hold the values of $g^x \mbox{ (mod }p\mbox{)}$ for $2^{winsize - 1} \le x < 2^{winsize}$.  
+
+After the table is allocated the first power of $g$ is found.  Since $g \ge p$ is allowed it must be first reduced modulo $p$ to make
+the rest of the algorithm more efficient.  The first element of the table at $2^{winsize - 1}$ is found by squaring $M_1$ successively $winsize - 2$
+times.  The rest of the table elements are found by multiplying the previous element by $M_1$ modulo $p$.
+
+Now that the table is available the sliding window may begin.  The following list describes the functions of all the variables in the window.
+\begin{enumerate}
+\item The variable $mode$ dictates how the bits of the exponent are interpreted.  
+\begin{enumerate}
+   \item When $mode = 0$ the bits are ignored since no non-zero bit of the exponent has been seen yet.  For example, if the exponent were simply 
+         $1$ then there would be $lg(\beta) - 1$ zero bits before the first non-zero bit.  In this case bits are ignored until a non-zero bit is found.  
+   \item When $mode = 1$ a non-zero bit has been seen before and a new $winsize$-bit window has not been formed yet.  In this mode leading $0$ bits 
+         are read and a single squaring is performed.  If a non-zero bit is read a new window is created.  
+   \item When $mode = 2$ the algorithm is in the middle of forming a window and new bits are appended to the window from the most significant bit
+         downwards.
+\end{enumerate}
+\item The variable $bitcnt$ indicates how many bits are left in the current digit of the exponent left to be read.  When it reaches zero a new digit
+      is fetched from the exponent.
+\item The variable $buf$ holds the currently read digit of the exponent. 
+\item The variable $digidx$ is an index into the exponents digits.  It starts at the leading digit $x.used - 1$ and moves towards the trailing digit.
+\item The variable $bitcpy$ indicates how many bits are in the currently formed window.  When it reaches $winsize$ the window is flushed and
+      the appropriate operations performed.
+\item The variable $bitbuf$ holds the current bits of the window being formed.  
+\end{enumerate}
+
+All of step 12 is the window processing loop.  It will iterate while there are digits available form the exponent to read.  The first step
+inside this loop is to extract a new digit if no more bits are available in the current digit.  If there are no bits left a new digit is
+read and if there are no digits left than the loop terminates.  
+
+After a digit is made available step 12.3 will extract the most significant bit of the current digit and move all other bits in the digit
+upwards.  In effect the digit is read from most significant bit to least significant bit and since the digits are read from leading to 
+trailing edges the entire exponent is read from most significant bit to least significant bit.
+
+At step 12.5 if the $mode$ and currently extracted bit $y$ are both zero the bit is ignored and the next bit is read.  This prevents the 
+algorithm from having to perform trivial squaring and reduction operations before the first non-zero bit is read.  Step 12.6 and 12.7-10 handle
+the two cases of $mode = 1$ and $mode = 2$ respectively.  
+
+FIGU,expt_state,Sliding Window State Diagram
+
+By step 13 there are no more digits left in the exponent.  However, there may be partial bits in the window left.  If $mode = 2$ then 
+a Left-to-Right algorithm is used to process the remaining few bits.  
+
+EXAM,bn_s_mp_exptmod.c
+
+Lines @31,if@ through @45,}@ determine the optimal window size based on the length of the exponent in bits.  The window divisions are sorted
+from smallest to greatest so that in each \textbf{if} statement only one condition must be tested.  For example, by the \textbf{if} statement 
+on line @37,if@ the value of $x$ is already known to be greater than $140$.  
+
+The conditional piece of code beginning on line @42,ifdef@ allows the window size to be restricted to five bits.  This logic is used to ensure
+the table of precomputed powers of $G$ remains relatively small.  
+
+The for loop on line @60,for@ initializes the $M$ array while lines @71,mp_init@ and @75,mp_reduce@ through @85,}@ initialize the reduction
+function that will be used for this modulus.
+
+-- More later.
+
+\section{Quick Power of Two}
+Calculating $b = 2^a$ can be performed much quicker than with any of the previous algorithms.  Recall that a logical shift left $m << k$ is
+equivalent to $m \cdot 2^k$.  By this logic when $m = 1$ a quick power of two can be achieved.
+
+\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{mp\_2expt}. \\
+\textbf{Input}.   integer $b$ \\
+\textbf{Output}.  $a \leftarrow 2^b$ \\
+\hline \\
+1.  $a \leftarrow 0$ \\
+2.  If $a.alloc < \lfloor b / lg(\beta) \rfloor + 1$ then grow $a$ appropriately. \\
+3.  $a.used \leftarrow \lfloor b / lg(\beta) \rfloor + 1$ \\
+4.  $a_{\lfloor b / lg(\beta) \rfloor} \leftarrow 1 << (b \mbox{ mod } lg(\beta))$ \\
+5.  Return(\textit{MP\_OKAY}). \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Algorithm mp\_2expt}
+\end{figure}
+
+\textbf{Algorithm mp\_2expt.}
+
+EXAM,bn_mp_2expt.c
+
+\chapter{Higher Level Algorithms}
+
+This chapter discusses the various higher level algorithms that are required to complete a well rounded multiple precision integer package.  These
+routines are less performance oriented than the algorithms of chapters five, six and seven but are no less important.  
+
+The first section describes a method of integer division with remainder that is universally well known.  It provides the signed division logic
+for the package.  The subsequent section discusses a set of algorithms which allow a single digit to be the 2nd operand for a variety of operations.  
+These algorithms serve mostly to simplify other algorithms where small constants are required.  The last two sections discuss how to manipulate 
+various representations of integers.  For example, converting from an mp\_int to a string of character.
+
+\section{Integer Division with Remainder}
+\label{sec:division}
+
+Integer division aside from modular exponentiation is the most intensive algorithm to compute.  Like addition, subtraction and multiplication
+the basis of this algorithm is the long-hand division algorithm taught to school children.  Throughout this discussion several common variables
+will be used.  Let $x$ represent the divisor and $y$ represent the dividend.  Let $q$ represent the integer quotient $\lfloor y / x \rfloor$ and 
+let $r$ represent the remainder $r = y - x \lfloor y / x \rfloor$.  The following simple algorithm will be used to start the discussion.
+
+\newpage\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{Radix-$\beta$ Integer Division}. \\
+\textbf{Input}.   integer $x$ and $y$ \\
+\textbf{Output}.  $q = \lfloor y/x\rfloor, r = y - xq$ \\
+\hline \\
+1.  $q \leftarrow 0$ \\
+2.  $n \leftarrow \vert \vert y \vert \vert - \vert \vert x \vert \vert$ \\
+3.  for $t$ from $n$ down to $0$ do \\
+\hspace{3mm}3.1  Maximize $k$ such that $kx\beta^t$ is less than or equal to $y$ and $(k + 1)x\beta^t$ is greater. \\
+\hspace{3mm}3.2  $q \leftarrow q + k\beta^t$ \\
+\hspace{3mm}3.3  $y \leftarrow y - kx\beta^t$ \\
+4.  $r \leftarrow y$ \\
+5.  Return($q, r$) \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Algorithm Radix-$\beta$ Integer Division}
+\label{fig:raddiv}
+\end{figure}
+
+As children we are taught this very simple algorithm for the case of $\beta = 10$.  Almost instinctively several optimizations are taught for which
+their reason of existing are never explained.  For this example let $y = 5471$ represent the dividend and $x = 23$ represent the divisor.
+
+To find the first digit of the quotient the value of $k$ must be maximized such that $kx\beta^t$ is less than or equal to $y$ and 
+simultaneously $(k + 1)x\beta^t$ is greater than $y$.  Implicitly $k$ is the maximum value the $t$'th digit of the quotient may have.  The habitual method
+used to find the maximum is to ``eyeball'' the two numbers, typically only the leading digits and quickly estimate a quotient.  By only using leading
+digits a much simpler division may be used to form an educated guess at what the value must be.  In this case $k = \lfloor 54/23\rfloor = 2$ quickly 
+arises as a possible  solution.  Indeed $2x\beta^2 = 4600$ is less than $y = 5471$ and simultaneously $(k + 1)x\beta^2 = 6900$ is larger than $y$.  
+As a  result $k\beta^2$ is added to the quotient which now equals $q = 200$ and $4600$ is subtracted from $y$ to give a remainder of $y = 841$.
+
+Again this process is repeated to produce the quotient digit $k = 3$ which makes the quotient $q = 200 + 3\beta = 230$ and the remainder 
+$y = 841 - 3x\beta = 181$.  Finally the last iteration of the loop produces $k = 7$ which leads to the quotient $q = 230 + 7 = 237$ and the
+remainder $y = 181 - 7x = 20$.  The final quotient and remainder found are $q = 237$ and $r = y = 20$ which are indeed correct since 
+$237 \cdot 23 + 20 = 5471$ is true.  
+
+\subsection{Quotient Estimation}
+\label{sec:divest}
+As alluded to earlier the quotient digit $k$ can be estimated from only the leading digits of both the divisor and dividend.  When $p$ leading
+digits are used from both the divisor and dividend to form an estimation the accuracy of the estimation rises as $p$ grows.  Technically
+speaking the estimation is based on assuming the lower $\vert \vert y \vert \vert - p$ and $\vert \vert x \vert \vert - p$ lower digits of the
+dividend and divisor are zero.  
+
+The value of the estimation may off by a few values in either direction and in general is fairly correct.  A simplification \cite[pp. 271]{TAOCPV2}
+of the estimation technique is to use $t + 1$ digits of the dividend and $t$ digits of the divisor, in particularly when $t = 1$.  The estimate 
+using this technique is never too small.  For the following proof let $t = \vert \vert y \vert \vert - 1$ and $s = \vert \vert x \vert \vert - 1$ 
+represent the most significant digits of the dividend and divisor respectively.
+
+\textbf{Proof.}\textit{  The quotient $\hat k = \lfloor (y_t\beta + y_{t-1}) / x_s \rfloor$ is greater than or equal to 
+$k = \lfloor y / (x \cdot \beta^{\vert \vert y \vert \vert - \vert \vert x \vert \vert - 1}) \rfloor$. }
+The first obvious case is when $\hat k = \beta - 1$ in which case the proof is concluded since the real quotient cannot be larger.  For all other 
+cases $\hat k = \lfloor (y_t\beta + y_{t-1}) / x_s \rfloor$ and $\hat k x_s \ge y_t\beta + y_{t-1} - x_s + 1$.  The latter portion of the inequalility
+$-x_s + 1$ arises from the fact that a truncated integer division will give the same quotient for at most $x_s - 1$ values.  Next a series of 
+inequalities will prove the hypothesis.
+
+\begin{equation}
+y - \hat k x \le y - \hat k x_s\beta^s
+\end{equation}
+
+This is trivially true since $x \ge x_s\beta^s$.  Next we replace $\hat kx_s\beta^s$ by the previous inequality for $\hat kx_s$.  
+
+\begin{equation}
+y - \hat k x \le y_t\beta^t + \ldots + y_0 - (y_t\beta^t + y_{t-1}\beta^{t-1} - x_s\beta^t + \beta^s)
+\end{equation}
+
+By simplifying the previous inequality the following inequality is formed.
+
+\begin{equation}
+y - \hat k x \le y_{t-2}\beta^{t-2} + \ldots + y_0 + x_s\beta^s - \beta^s
+\end{equation}
+
+Subsequently,
+
+\begin{equation}
+y_{t-2}\beta^{t-2} + \ldots +  y_0  + x_s\beta^s - \beta^s < x_s\beta^s \le x
+\end{equation}
+
+Which proves that $y - \hat kx \le x$ and by consequence $\hat k \ge k$ which concludes the proof.  \textbf{QED}
+
+
+\subsection{Normalized Integers}
+For the purposes of division a normalized input is when the divisors leading digit $x_n$ is greater than or equal to $\beta / 2$.  By multiplying both
+$x$ and $y$ by $j = \lfloor (\beta / 2) / x_n \rfloor$ the quotient remains unchanged and the remainder is simply $j$ times the original
+remainder.  The purpose of normalization is to ensure the leading digit of the divisor is sufficiently large such that the estimated quotient will
+lie in the domain of a single digit.  Consider the maximum dividend $(\beta - 1) \cdot \beta + (\beta - 1)$ and the minimum divisor $\beta / 2$.  
+
+\begin{equation} 
+{{\beta^2 - 1} \over { \beta / 2}} \le 2\beta - {2 \over \beta} 
+\end{equation}
+
+At most the quotient approaches $2\beta$, however, in practice this will not occur since that would imply the previous quotient digit was too small.  
+
+\subsection{Radix-$\beta$ Division with Remainder}
+\newpage\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{mp\_div}. \\
+\textbf{Input}.   mp\_int $a, b$ \\
+\textbf{Output}.  $c = \lfloor a/b \rfloor$, $d = a - bc$ \\
+\hline \\
+1.  If $b = 0$ return(\textit{MP\_VAL}). \\
+2.  If $\vert a \vert < \vert b \vert$ then do \\
+\hspace{3mm}2.1  $d \leftarrow a$ \\
+\hspace{3mm}2.2  $c \leftarrow 0$ \\
+\hspace{3mm}2.3  Return(\textit{MP\_OKAY}). \\
+\\
+Setup the quotient to receive the digits. \\
+3.  Grow $q$ to $a.used + 2$ digits. \\
+4.  $q \leftarrow 0$ \\
+5.  $x \leftarrow \vert a \vert , y \leftarrow \vert b \vert$ \\
+6.  $sign \leftarrow  \left \lbrace \begin{array}{ll}
+                              MP\_ZPOS &  \mbox{if }a.sign = b.sign \\
+                              MP\_NEG  &  \mbox{otherwise} \\
+                              \end{array} \right .$ \\
+\\
+Normalize the inputs such that the leading digit of $y$ is greater than or equal to $\beta / 2$. \\
+7.  $norm \leftarrow (lg(\beta) - 1) - (\lceil lg(y) \rceil \mbox{ (mod }lg(\beta)\mbox{)})$ \\
+8.  $x \leftarrow x \cdot 2^{norm}, y \leftarrow y \cdot 2^{norm}$ \\
+\\
+Find the leading digit of the quotient. \\
+9.  $n \leftarrow x.used - 1, t \leftarrow y.used - 1$ \\
+10.  $y \leftarrow y \cdot \beta^{n - t}$ \\
+11.  While ($x \ge y$) do \\
+\hspace{3mm}11.1  $q_{n - t} \leftarrow q_{n - t} + 1$ \\
+\hspace{3mm}11.2  $x \leftarrow x - y$ \\
+12.  $y \leftarrow \lfloor y / \beta^{n-t} \rfloor$ \\
+\\
+Continued on the next page. \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Algorithm mp\_div}
+\end{figure}
+
+\newpage\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{mp\_div} (continued). \\
+\textbf{Input}.   mp\_int $a, b$ \\
+\textbf{Output}.  $c = \lfloor a/b \rfloor$, $d = a - bc$ \\
+\hline \\
+Now find the remainder fo the digits. \\
+13.  for $i$ from $n$ down to $(t + 1)$ do \\
+\hspace{3mm}13.1  If $i > x.used$ then jump to the next iteration of this loop. \\
+\hspace{3mm}13.2  If $x_{i} = y_{t}$ then \\
+\hspace{6mm}13.2.1  $q_{i - t - 1} \leftarrow \beta - 1$ \\
+\hspace{3mm}13.3  else \\
+\hspace{6mm}13.3.1  $\hat r \leftarrow x_{i} \cdot \beta + x_{i - 1}$ \\
+\hspace{6mm}13.3.2  $\hat r \leftarrow \lfloor \hat r / y_{t} \rfloor$ \\
+\hspace{6mm}13.3.3  $q_{i - t - 1} \leftarrow \hat r$ \\
+\hspace{3mm}13.4  $q_{i - t - 1} \leftarrow q_{i - t - 1} + 1$ \\
+\\
+Fixup quotient estimation. \\
+\hspace{3mm}13.5  Loop \\
+\hspace{6mm}13.5.1  $q_{i - t - 1} \leftarrow q_{i - t - 1} - 1$ \\
+\hspace{6mm}13.5.2  t$1 \leftarrow 0$ \\
+\hspace{6mm}13.5.3  t$1_0 \leftarrow y_{t - 1}, $ t$1_1 \leftarrow y_t,$ t$1.used \leftarrow 2$ \\
+\hspace{6mm}13.5.4  $t1 \leftarrow t1 \cdot q_{i - t - 1}$ \\
+\hspace{6mm}13.5.5  t$2_0 \leftarrow x_{i - 2}, $ t$2_1 \leftarrow x_{i - 1}, $ t$2_2 \leftarrow x_i, $ t$2.used \leftarrow 3$ \\
+\hspace{6mm}13.5.6  If $\vert t1 \vert > \vert t2 \vert$ then goto step 13.5. \\
+\hspace{3mm}13.6  t$1 \leftarrow y \cdot q_{i - t - 1}$ \\
+\hspace{3mm}13.7  t$1 \leftarrow $ t$1 \cdot \beta^{i - t - 1}$ \\
+\hspace{3mm}13.8  $x \leftarrow x - $ t$1$ \\
+\hspace{3mm}13.9  If $x.sign = MP\_NEG$ then \\
+\hspace{6mm}13.10  t$1 \leftarrow y$ \\
+\hspace{6mm}13.11  t$1 \leftarrow $ t$1 \cdot \beta^{i - t - 1}$ \\
+\hspace{6mm}13.12  $x \leftarrow x + $ t$1$ \\
+\hspace{6mm}13.13  $q_{i - t - 1} \leftarrow q_{i - t - 1} - 1$ \\
+\\
+Finalize the result. \\
+14.  Clamp excess digits of $q$ \\
+15.  $c \leftarrow q, c.sign \leftarrow sign$ \\
+16.  $x.sign \leftarrow a.sign$ \\
+17.  $d \leftarrow \lfloor x / 2^{norm} \rfloor$ \\
+18.  Return(\textit{MP\_OKAY}). \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Algorithm mp\_div (continued)}
+\end{figure}
+\textbf{Algorithm mp\_div.}
+This algorithm will calculate quotient and remainder from an integer division given a dividend and divisor.  The algorithm is a signed
+division and will produce a fully qualified quotient and remainder.
+
+First the divisor $b$ must be non-zero which is enforced in step one.  If the divisor is larger than the dividend than the quotient is implicitly 
+zero and the remainder is the dividend.  
+
+After the first two trivial cases of inputs are handled the variable $q$ is setup to receive the digits of the quotient.  Two unsigned copies of the
+divisor $y$ and dividend $x$ are made as well.  The core of the division algorithm is an unsigned division and will only work if the values are
+positive.  Now the two values $x$ and $y$ must be normalized such that the leading digit of $y$ is greater than or equal to $\beta / 2$.  
+This is performed by shifting both to the left by enough bits to get the desired normalization.  
+
+At this point the division algorithm can begin producing digits of the quotient.  Recall that maximum value of the estimation used is 
+$2\beta - {2 \over \beta}$ which means that a digit of the quotient must be first produced by another means.  In this case $y$ is shifted
+to the left (\textit{step ten}) so that it has the same number of digits as $x$.  The loop on step eleven will subtract multiples of the 
+shifted copy of $y$ until $x$ is smaller.  Since the leading digit of $y$ is greater than or equal to $\beta/2$ this loop will iterate at most two
+times to produce the desired leading digit of the quotient.  
+
+Now the remainder of the digits can be produced.  The equation $\hat q = \lfloor {{x_i \beta + x_{i-1}}\over y_t} \rfloor$ is used to fairly
+accurately approximate the true quotient digit.  The estimation can in theory produce an estimation as high as $2\beta - {2 \over \beta}$ but by
+induction the upper quotient digit is correct (\textit{as established on step eleven}) and the estimate must be less than $\beta$.  
+
+Recall from section~\ref{sec:divest} that the estimation is never too low but may be too high.  The next step of the estimation process is
+to refine the estimation.  The loop on step 13.5 uses $x_i\beta^2 + x_{i-1}\beta + x_{i-2}$ and $q_{i - t - 1}(y_t\beta + y_{t-1})$ as a higher
+order approximation to adjust the quotient digit.
+
+After both phases of estimation the quotient digit may still be off by a value of one\footnote{This is similar to the error introduced
+by optimizing Barrett reduction.}.  Steps 13.6 and 13.7 subtract the multiple of the divisor from the dividend (\textit{Similar to step 3.3 of
+algorithm~\ref{fig:raddiv}} and then subsequently add a multiple of the divisor if the quotient was too large.  
+
+Now that the quotient has been determine finializing the result is a matter of clamping the quotient, fixing the sizes and de-normalizing the 
+remainder.  An important aspect of this algorithm seemingly overlooked in other descriptions such as that of Algorithm 14.20 HAC \cite[pp. 598]{HAC}
+is that when the estimations are being made (\textit{inside the loop on step 13.5}) that the digits $y_{t-1}$, $x_{i-2}$ and $x_{i-1}$ may lie 
+outside their respective boundaries.  For example, if $t = 0$ or $i \le 1$ then the digits would be undefined.  In those cases the digits should
+respectively be replaced with a zero.  
+
+EXAM,bn_mp_div.c
+
+The implementation of this algorithm differs slightly from the pseudo code presented previously.  In this algorithm either of the quotient $c$ or
+remainder $d$ may be passed as a \textbf{NULL} pointer which indicates their value is not desired.  For example, the C code to call the division
+algorithm with only the quotient is 
+
+\begin{verbatim}
+mp_div(&a, &b, &c, NULL);  /* c = [a/b] */
+\end{verbatim}
+
+Lines @108,if@ and @113,if@ handle the two trivial cases of inputs which are division by zero and dividend smaller than the divisor 
+respectively.  After the two trivial cases all of the temporary variables are initialized.  Line @147,neg@ determines the sign of 
+the quotient and line @148,sign@ ensures that both $x$ and $y$ are positive.  
+
+The number of bits in the leading digit is calculated on line @151,norm@.  Implictly an mp\_int with $r$ digits will require $lg(\beta)(r-1) + k$ bits
+of precision which when reduced modulo $lg(\beta)$ produces the value of $k$.  In this case $k$ is the number of bits in the leading digit which is
+exactly what is required.  For the algorithm to operate $k$ must equal $lg(\beta) - 1$ and when it does not the inputs must be normalized by shifting
+them to the left by $lg(\beta) - 1 - k$ bits.
+
+Throughout the variables $n$ and $t$ will represent the highest digit of $x$ and $y$ respectively.  These are first used to produce the 
+leading digit of the quotient.  The loop beginning on line @184,for@ will produce the remainder of the quotient digits.
+
+The conditional ``continue'' on line @186,continue@ is used to prevent the algorithm from reading past the leading edge of $x$ which can occur when the
+algorithm eliminates multiple non-zero digits in a single iteration.  This ensures that $x_i$ is always non-zero since by definition the digits
+above the $i$'th position $x$ must be zero in order for the quotient to be precise\footnote{Precise as far as integer division is concerned.}.  
+
+Lines @214,t1@, @216,t1@ and @222,t2@ through @225,t2@ manually construct the high accuracy estimations by setting the digits of the two mp\_int 
+variables directly.  
+
+\section{Single Digit Helpers}
+
+This section briefly describes a series of single digit helper algorithms which come in handy when working with small constants.  All of 
+the helper functions assume the single digit input is positive and will treat them as such.
+
+\subsection{Single Digit Addition and Subtraction}
+
+Both addition and subtraction are performed by ``cheating'' and using mp\_set followed by the higher level addition or subtraction 
+algorithms.   As a result these algorithms are subtantially simpler with a slight cost in performance.
+
+\newpage\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{mp\_add\_d}. \\
+\textbf{Input}.   mp\_int $a$ and a mp\_digit $b$ \\
+\textbf{Output}.  $c = a + b$ \\
+\hline \\
+1.  $t \leftarrow b$ (\textit{mp\_set}) \\
+2.  $c \leftarrow a + t$ \\
+3.  Return(\textit{MP\_OKAY}) \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Algorithm mp\_add\_d}
+\end{figure}
+
+\textbf{Algorithm mp\_add\_d.}
+This algorithm initiates a temporary mp\_int with the value of the single digit and uses algorithm mp\_add to add the two values together.
+
+EXAM,bn_mp_add_d.c
+
+Clever use of the letter 't'.
+
+\subsubsection{Subtraction}
+The single digit subtraction algorithm mp\_sub\_d is essentially the same except it uses mp\_sub to subtract the digit from the mp\_int.
+
+\subsection{Single Digit Multiplication}
+Single digit multiplication arises enough in division and radix conversion that it ought to be implement as a special case of the baseline
+multiplication algorithm.  Essentially this algorithm is a modified version of algorithm s\_mp\_mul\_digs where one of the multiplicands
+only has one digit.
+
+\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{mp\_mul\_d}. \\
+\textbf{Input}.   mp\_int $a$ and a mp\_digit $b$ \\
+\textbf{Output}.  $c = ab$ \\
+\hline \\
+1.  $pa \leftarrow a.used$ \\
+2.  Grow $c$ to at least $pa + 1$ digits. \\
+3.  $oldused \leftarrow c.used$ \\
+4.  $c.used \leftarrow pa + 1$ \\
+5.  $c.sign \leftarrow a.sign$ \\
+6.  $\mu \leftarrow 0$ \\
+7.  for $ix$ from $0$ to $pa - 1$ do \\
+\hspace{3mm}7.1  $\hat r \leftarrow \mu + a_{ix}b$ \\
+\hspace{3mm}7.2  $c_{ix} \leftarrow \hat r \mbox{ (mod }\beta\mbox{)}$ \\
+\hspace{3mm}7.3  $\mu \leftarrow \lfloor \hat r / \beta \rfloor$ \\
+8.  $c_{pa} \leftarrow \mu$ \\
+9.  for $ix$ from $pa + 1$ to $oldused$ do \\
+\hspace{3mm}9.1  $c_{ix} \leftarrow 0$ \\
+10.  Clamp excess digits of $c$. \\
+11.  Return(\textit{MP\_OKAY}). \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Algorithm mp\_mul\_d}
+\end{figure}
+\textbf{Algorithm mp\_mul\_d.}
+This algorithm quickly multiplies an mp\_int by a small single digit value.  It is specially tailored to the job and has a minimal of overhead.  
+Unlike the full multiplication algorithms this algorithm does not require any significnat temporary storage or memory allocations.  
+
+EXAM,bn_mp_mul_d.c
+
+In this implementation the destination $c$ may point to the same mp\_int as the source $a$ since the result is written after the digit is 
+read from the source.  This function uses pointer aliases $tmpa$ and $tmpc$ for the digits of $a$ and $c$ respectively.  
+
+\subsection{Single Digit Division}
+Like the single digit multiplication algorithm, single digit division is also a fairly common algorithm used in radix conversion.  Since the
+divisor is only a single digit a specialized variant of the division algorithm can be used to compute the quotient.  
+
+\newpage\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{mp\_div\_d}. \\
+\textbf{Input}.   mp\_int $a$ and a mp\_digit $b$ \\
+\textbf{Output}.  $c = \lfloor a / b \rfloor, d = a - cb$ \\
+\hline \\
+1.  If $b = 0$ then return(\textit{MP\_VAL}).\\
+2.  If $b = 3$ then use algorithm mp\_div\_3 instead. \\
+3.  Init $q$ to $a.used$ digits.  \\
+4.  $q.used \leftarrow a.used$ \\
+5.  $q.sign \leftarrow a.sign$ \\
+6.  $\hat w \leftarrow 0$ \\
+7.  for $ix$ from $a.used - 1$ down to $0$ do \\
+\hspace{3mm}7.1  $\hat w \leftarrow \hat w \beta + a_{ix}$ \\
+\hspace{3mm}7.2  If $\hat w \ge b$ then \\
+\hspace{6mm}7.2.1  $t \leftarrow \lfloor \hat w / b \rfloor$ \\
+\hspace{6mm}7.2.2  $\hat w \leftarrow \hat w \mbox{ (mod }b\mbox{)}$ \\
+\hspace{3mm}7.3  else\\
+\hspace{6mm}7.3.1  $t \leftarrow 0$ \\
+\hspace{3mm}7.4  $q_{ix} \leftarrow t$ \\
+8.  $d \leftarrow \hat w$ \\
+9.  Clamp excess digits of $q$. \\
+10.  $c \leftarrow q$ \\
+11.  Return(\textit{MP\_OKAY}). \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Algorithm mp\_div\_d}
+\end{figure}
+\textbf{Algorithm mp\_div\_d.}
+This algorithm divides the mp\_int $a$ by the single mp\_digit $b$ using an optimized approach.  Essentially in every iteration of the
+algorithm another digit of the dividend is reduced and another digit of quotient produced.  Provided $b < \beta$ the value of $\hat w$
+after step 7.1 will be limited such that $0 \le \lfloor \hat w / b \rfloor < \beta$.  
+
+If the divisor $b$ is equal to three a variant of this algorithm is used which is called mp\_div\_3.  It replaces the division by three with
+a multiplication by $\lfloor \beta / 3 \rfloor$ and the appropriate shift and residual fixup.  In essence it is much like the Barrett reduction
+from chapter seven.  
+
+EXAM,bn_mp_div_d.c
+
+Like the implementation of algorithm mp\_div this algorithm allows either of the quotient or remainder to be passed as a \textbf{NULL} pointer to
+indicate the respective value is not required.  This allows a trivial single digit modular reduction algorithm, mp\_mod\_d to be created.
+
+The division and remainder on lines @44,/@ and @45,%@ can be replaced often by a single division on most processors.  For example, the 32-bit x86 based 
+processors can divide a 64-bit quantity by a 32-bit quantity and produce the quotient and remainder simultaneously.  Unfortunately the GCC 
+compiler does not recognize that optimization and will actually produce two function calls to find the quotient and remainder respectively.  
+
+\subsection{Single Digit Root Extraction}
+
+Finding the $n$'th root of an integer is fairly easy as far as numerical analysis is concerned.  Algorithms such as the Newton-Raphson approximation 
+(\ref{eqn:newton}) series will converge very quickly to a root for any continuous function $f(x)$.  
+
+\begin{equation}
+x_{i+1} = x_i - {f(x_i) \over f'(x_i)}
+\label{eqn:newton}
+\end{equation}
+
+In this case the $n$'th root is desired and $f(x) = x^n - a$ where $a$ is the integer of which the root is desired.  The derivative of $f(x)$ is 
+simply $f'(x) = nx^{n - 1}$.  Of particular importance is that this algorithm will be used over the integers not over the a more continuous domain
+such as the real numbers.  As a result the root found can be above the true root by few and must be manually adjusted.  Ideally at the end of the 
+algorithm the $n$'th root $b$ of an integer $a$ is desired such that $b^n \le a$.  
+
+\newpage\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{mp\_n\_root}. \\
+\textbf{Input}.   mp\_int $a$ and a mp\_digit $b$ \\
+\textbf{Output}.  $c^b \le a$ \\
+\hline \\
+1.  If $b$ is even and $a.sign = MP\_NEG$ return(\textit{MP\_VAL}). \\
+2.  $sign \leftarrow a.sign$ \\
+3.  $a.sign \leftarrow MP\_ZPOS$ \\
+4.  t$2 \leftarrow 2$ \\
+5.  Loop \\
+\hspace{3mm}5.1  t$1 \leftarrow $ t$2$ \\
+\hspace{3mm}5.2  t$3 \leftarrow $ t$1^{b - 1}$ \\
+\hspace{3mm}5.3  t$2 \leftarrow $ t$3 $ $\cdot$ t$1$ \\
+\hspace{3mm}5.4  t$2 \leftarrow $ t$2 - a$ \\
+\hspace{3mm}5.5  t$3 \leftarrow $ t$3 \cdot b$ \\
+\hspace{3mm}5.6  t$3 \leftarrow \lfloor $t$2 / $t$3 \rfloor$ \\
+\hspace{3mm}5.7  t$2 \leftarrow $ t$1 - $ t$3$ \\
+\hspace{3mm}5.8  If t$1 \ne $ t$2$ then goto step 5.  \\
+6.  Loop \\
+\hspace{3mm}6.1  t$2 \leftarrow $ t$1^b$ \\
+\hspace{3mm}6.2  If t$2 > a$ then \\
+\hspace{6mm}6.2.1  t$1 \leftarrow $ t$1 - 1$ \\
+\hspace{6mm}6.2.2  Goto step 6. \\
+7.  $a.sign \leftarrow sign$ \\
+8.  $c \leftarrow $ t$1$ \\
+9.  $c.sign \leftarrow sign$  \\
+10.  Return(\textit{MP\_OKAY}).  \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Algorithm mp\_n\_root}
+\end{figure}
+\textbf{Algorithm mp\_n\_root.}
+This algorithm finds the integer $n$'th root of an input using the Newton-Raphson approach.  It is partially optimized based on the observation
+that the numerator of ${f(x) \over f'(x)}$ can be derived from a partial denominator.  That is at first the denominator is calculated by finding
+$x^{b - 1}$.  This value can then be multiplied by $x$ and have $a$ subtracted from it to find the numerator.  This saves a total of $b - 1$ 
+multiplications by t$1$ inside the loop.  
+
+The initial value of the approximation is t$2 = 2$ which allows the algorithm to start with very small values and quickly converge on the
+root.  Ideally this algorithm is meant to find the $n$'th root of an input where $n$ is bounded by $2 \le n \le 5$.  
+
+EXAM,bn_mp_n_root.c
+
+\section{Random Number Generation}
+
+Random numbers come up in a variety of activities from public key cryptography to simple simulations and various randomized algorithms.  Pollard-Rho 
+factoring for example, can make use of random values as starting points to find factors of a composite integer.  In this case the algorithm presented
+is solely for simulations and not intended for cryptographic use.  
+
+\newpage\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{mp\_rand}. \\
+\textbf{Input}.   An integer $b$ \\
+\textbf{Output}.  A pseudo-random number of $b$ digits \\
+\hline \\
+1.  $a \leftarrow 0$ \\
+2.  If $b \le 0$ return(\textit{MP\_OKAY}) \\
+3.  Pick a non-zero random digit $d$. \\
+4.  $a \leftarrow a + d$ \\
+5.  for $ix$ from 1 to $d - 1$ do \\
+\hspace{3mm}5.1  $a \leftarrow a \cdot \beta$ \\
+\hspace{3mm}5.2  Pick a random digit $d$. \\
+\hspace{3mm}5.3  $a \leftarrow a + d$ \\
+6.  Return(\textit{MP\_OKAY}). \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Algorithm mp\_rand}
+\end{figure}
+\textbf{Algorithm mp\_rand.}
+This algorithm produces a pseudo-random integer of $b$ digits.  By ensuring that the first digit is non-zero the algorithm also guarantees that the
+final result has at least $b$ digits.  It relies heavily on a third-part random number generator which should ideally generate uniformly all of
+the integers from $0$ to $\beta - 1$.  
+
+EXAM,bn_mp_rand.c
+
+\section{Formatted Representations}
+The ability to emit a radix-$n$ textual representation of an integer is useful for interacting with human parties.  For example, the ability to
+be given a string of characters such as ``114585'' and turn it into the radix-$\beta$ equivalent would make it easier to enter numbers
+into a program.
+
+\subsection{Reading Radix-n Input}
+For the purposes of this text we will assume that a simple lower ASCII map (\ref{fig:ASC}) is used for the values of from $0$ to $63$ to 
+printable characters.  For example, when the character ``N'' is read it represents the integer $23$.  The first $16$ characters of the
+map are for the common representations up to hexadecimal.  After that they match the ``base64'' encoding scheme which are suitable chosen
+such that they are printable.  While outputting as base64 may not be too helpful for human operators it does allow communication via non binary
+mediums.
+
+\newpage\begin{figure}[here]
+\begin{center}
+\begin{tabular}{cc|cc|cc|cc}
+\hline \textbf{Value} & \textbf{Char} & \textbf{Value} & \textbf{Char} & \textbf{Value} & \textbf{Char} &  \textbf{Value} & \textbf{Char} \\
+\hline 
+0 & 0 & 1 & 1 & 2 & 2 & 3 & 3 \\
+4 & 4 & 5 & 5 & 6 & 6 & 7 & 7 \\
+8 & 8 & 9 & 9 & 10 & A & 11 & B \\
+12 & C & 13 & D & 14 & E & 15 & F \\
+16 & G & 17 & H & 18 & I & 19 & J \\
+20 & K & 21 & L & 22 & M & 23 & N \\
+24 & O & 25 & P & 26 & Q & 27 & R \\
+28 & S & 29 & T & 30 & U & 31 & V \\
+32 & W & 33 & X & 34 & Y & 35 & Z \\
+36 & a & 37 & b & 38 & c & 39 & d \\
+40 & e & 41 & f & 42 & g & 43 & h \\
+44 & i & 45 & j & 46 & k & 47 & l \\
+48 & m & 49 & n & 50 & o & 51 & p \\
+52 & q & 53 & r & 54 & s & 55 & t \\
+56 & u & 57 & v & 58 & w & 59 & x \\
+60 & y & 61 & z & 62 & $+$ & 63 & $/$ \\
+\hline
+\end{tabular}
+\end{center}
+\caption{Lower ASCII Map}
+\label{fig:ASC}
+\end{figure}
+
+\newpage\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{mp\_read\_radix}. \\
+\textbf{Input}.   A string $str$ of length $sn$ and radix $r$. \\
+\textbf{Output}.  The radix-$\beta$ equivalent mp\_int. \\
+\hline \\
+1.  If $r < 2$ or $r > 64$ return(\textit{MP\_VAL}). \\
+2.  $ix \leftarrow 0$ \\
+3.  If $str_0 =$ ``-'' then do \\
+\hspace{3mm}3.1  $ix \leftarrow ix + 1$ \\
+\hspace{3mm}3.2  $sign \leftarrow MP\_NEG$ \\
+4.  else \\
+\hspace{3mm}4.1  $sign \leftarrow MP\_ZPOS$ \\
+5.  $a \leftarrow 0$ \\
+6.  for $iy$ from $ix$ to $sn - 1$ do \\
+\hspace{3mm}6.1  Let $y$ denote the position in the map of $str_{iy}$. \\
+\hspace{3mm}6.2  If $str_{iy}$ is not in the map or $y \ge r$ then goto step 7. \\
+\hspace{3mm}6.3  $a \leftarrow a \cdot r$ \\
+\hspace{3mm}6.4  $a \leftarrow a + y$ \\
+7.  If $a \ne 0$ then $a.sign \leftarrow sign$ \\
+8.  Return(\textit{MP\_OKAY}). \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Algorithm mp\_read\_radix}
+\end{figure}
+\textbf{Algorithm mp\_read\_radix.}
+This algorithm will read an ASCII string and produce the radix-$\beta$ mp\_int representation of the same integer.  A minus symbol ``-'' may precede the 
+string  to indicate the value is negative, otherwise it is assumed to be positive.  The algorithm will read up to $sn$ characters from the input
+and will stop when it reads a character it cannot map the algorithm stops reading characters from the string.  This allows numbers to be embedded
+as part of larger input without any significant problem.
+
+EXAM,bn_mp_read_radix.c
+
+\subsection{Generating Radix-$n$ Output}
+Generating radix-$n$ output is fairly trivial with a division and remainder algorithm.  
+
+\newpage\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{mp\_toradix}. \\
+\textbf{Input}.   A mp\_int $a$ and an integer $r$\\
+\textbf{Output}.  The radix-$r$ representation of $a$ \\
+\hline \\
+1.  If $r < 2$ or $r > 64$ return(\textit{MP\_VAL}). \\
+2.  If $a = 0$ then $str = $ ``$0$'' and return(\textit{MP\_OKAY}).  \\
+3.  $t \leftarrow a$ \\
+4.  $str \leftarrow$ ``'' \\
+5.  if $t.sign = MP\_NEG$ then \\
+\hspace{3mm}5.1  $str \leftarrow str + $ ``-'' \\
+\hspace{3mm}5.2  $t.sign = MP\_ZPOS$ \\
+6.  While ($t \ne 0$) do \\
+\hspace{3mm}6.1  $d \leftarrow t \mbox{ (mod }r\mbox{)}$ \\
+\hspace{3mm}6.2  $t \leftarrow \lfloor t / r \rfloor$ \\
+\hspace{3mm}6.3  Look up $d$ in the map and store the equivalent character in $y$. \\
+\hspace{3mm}6.4  $str \leftarrow str + y$ \\
+7.  If $str_0 = $``$-$'' then \\
+\hspace{3mm}7.1  Reverse the digits $str_1, str_2, \ldots str_n$. \\
+8.  Otherwise \\
+\hspace{3mm}8.1  Reverse the digits $str_0, str_1, \ldots str_n$. \\
+9.  Return(\textit{MP\_OKAY}).\\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Algorithm mp\_toradix}
+\end{figure}
+\textbf{Algorithm mp\_toradix.}
+This algorithm computes the radix-$r$ representation of an mp\_int $a$.  The ``digits'' of the representation are extracted by reducing 
+successive powers of $\lfloor a / r^k \rfloor$ the input modulo $r$ until $r^k > a$.  Note that instead of actually dividing by $r^k$ in
+each iteration the quotient $\lfloor a / r \rfloor$ is saved for the next iteration.  As a result a series of trivial $n \times 1$ divisions
+are required instead of a series of $n \times k$ divisions.  One design flaw of this approach is that the digits are produced in the reverse order 
+(see~\ref{fig:mpradix}).  To remedy this flaw the digits must be swapped or simply ``reversed''.
+
+\begin{figure}
+\begin{center}
+\begin{tabular}{|c|c|c|}
+\hline \textbf{Value of $a$} & \textbf{Value of $d$} & \textbf{Value of $str$} \\
+\hline $1234$ & -- & -- \\
+\hline $123$  & $4$ & ``4'' \\
+\hline $12$   & $3$ & ``43'' \\
+\hline $1$    & $2$ & ``432'' \\
+\hline $0$    & $1$ & ``4321'' \\
+\hline
+\end{tabular}
+\end{center}
+\caption{Example of Algorithm mp\_toradix.}
+\label{fig:mpradix}
+\end{figure}
+
+EXAM,bn_mp_toradix.c
+
+\chapter{Number Theoretic Algorithms}
+This chapter discusses several fundamental number theoretic algorithms such as the greatest common divisor, least common multiple and Jacobi 
+symbol computation.  These algorithms arise as essential components in several key cryptographic algorithms such as the RSA public key algorithm and
+various Sieve based factoring algorithms.
+
+\section{Greatest Common Divisor}
+The greatest common divisor of two integers $a$ and $b$, often denoted as $(a, b)$ is the largest integer $k$ that is a proper divisor of
+both $a$ and $b$.  That is, $k$ is the largest integer such that $0 \equiv a \mbox{ (mod }k\mbox{)}$ and $0 \equiv b \mbox{ (mod }k\mbox{)}$ occur
+simultaneously.
+
+The most common approach (cite) is to reduce one input modulo another.  That is if $a$ and $b$ are divisible by some integer $k$ and if $qa + r = b$ then
+$r$ is also divisible by $k$.  The reduction pattern follows $\left < a , b \right > \rightarrow \left < b, a \mbox{ mod } b \right >$.  
+
+\newpage\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{Greatest Common Divisor (I)}. \\
+\textbf{Input}.   Two positive integers $a$ and $b$ greater than zero. \\
+\textbf{Output}.  The greatest common divisor $(a, b)$.  \\
+\hline \\
+1.  While ($b > 0$) do \\
+\hspace{3mm}1.1  $r \leftarrow a \mbox{ (mod }b\mbox{)}$ \\
+\hspace{3mm}1.2  $a \leftarrow b$ \\
+\hspace{3mm}1.3  $b \leftarrow r$ \\
+2.  Return($a$). \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Algorithm Greatest Common Divisor (I)}
+\label{fig:gcd1}
+\end{figure}
+
+This algorithm will quickly converge on the greatest common divisor since the residue $r$ tends diminish rapidly.  However, divisions are
+relatively expensive operations to perform and should ideally be avoided.  There is another approach based on a similar relationship of 
+greatest common divisors.  The faster approach is based on the observation that if $k$ divides both $a$ and $b$ it will also divide $a - b$.  
+In particular, we would like $a - b$ to decrease in magnitude which implies that $b \ge a$.  
+
+\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{Greatest Common Divisor (II)}. \\
+\textbf{Input}.   Two positive integers $a$ and $b$ greater than zero. \\
+\textbf{Output}.  The greatest common divisor $(a, b)$.  \\
+\hline \\
+1.  While ($b > 0$) do \\
+\hspace{3mm}1.1  Swap $a$ and $b$ such that $a$ is the smallest of the two. \\
+\hspace{3mm}1.2  $b \leftarrow b - a$ \\
+2.  Return($a$). \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Algorithm Greatest Common Divisor (II)}
+\label{fig:gcd2}
+\end{figure}
+
+\textbf{Proof} \textit{Algorithm~\ref{fig:gcd2} will return the greatest common divisor of $a$ and $b$.}
+The algorithm in figure~\ref{fig:gcd2} will eventually terminate since $b \ge a$ the subtraction in step 1.2 will be a value less than $b$.  In other
+words in every iteration that tuple $\left < a, b \right >$ decrease in magnitude until eventually $a = b$.  Since both $a$ and $b$ are always 
+divisible by the greatest common divisor (\textit{until the last iteration}) and in the last iteration of the algorithm $b = 0$, therefore, in the 
+second to last iteration of the algorithm $b = a$ and clearly $(a, a) = a$ which concludes the proof.  \textbf{QED}.
+
+As a matter of practicality algorithm \ref{fig:gcd1} decreases far too slowly to be useful.  Specially if $b$ is much larger than $a$ such that 
+$b - a$ is still very much larger than $a$.  A simple addition to the algorithm is to divide $b - a$ by a power of some integer $p$ which does
+not divide the greatest common divisor but will divide $b - a$.  In this case ${b - a} \over p$ is also an integer and still divisible by
+the greatest common divisor.
+
+However, instead of factoring $b - a$ to find a suitable value of $p$ the powers of $p$ can be removed from $a$ and $b$ that are in common first.  
+Then inside the loop whenever $b - a$ is divisible by some power of $p$ it can be safely removed.  
+
+\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{Greatest Common Divisor (III)}. \\
+\textbf{Input}.   Two positive integers $a$ and $b$ greater than zero. \\
+\textbf{Output}.  The greatest common divisor $(a, b)$.  \\
+\hline \\
+1.  $k \leftarrow 0$ \\
+2.  While $a$ and $b$ are both divisible by $p$ do \\
+\hspace{3mm}2.1  $a \leftarrow \lfloor a / p \rfloor$ \\
+\hspace{3mm}2.2  $b \leftarrow \lfloor b / p \rfloor$ \\
+\hspace{3mm}2.3  $k \leftarrow k + 1$ \\
+3.  While $a$ is divisible by $p$ do \\
+\hspace{3mm}3.1  $a \leftarrow \lfloor a / p \rfloor$ \\
+4.  While $b$ is divisible by $p$ do \\
+\hspace{3mm}4.1  $b \leftarrow \lfloor b / p \rfloor$ \\
+5.  While ($b > 0$) do \\
+\hspace{3mm}5.1  Swap $a$ and $b$ such that $a$ is the smallest of the two. \\
+\hspace{3mm}5.2  $b \leftarrow b - a$ \\
+\hspace{3mm}5.3  While $b$ is divisible by $p$ do \\
+\hspace{6mm}5.3.1  $b \leftarrow \lfloor b / p \rfloor$ \\
+6.  Return($a \cdot p^k$). \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Algorithm Greatest Common Divisor (III)}
+\label{fig:gcd3}
+\end{figure}
+
+This algorithm is based on the first except it removes powers of $p$ first and inside the main loop to ensure the tuple $\left < a, b \right >$ 
+decreases more rapidly.  The first loop on step two removes powers of $p$ that are in common.  A count, $k$, is kept which will present a common
+divisor of $p^k$.  After step two the remaining common divisor of $a$ and $b$ cannot be divisible by $p$.  This means that $p$ can be safely 
+divided out of the difference $b - a$ so long as the division leaves no remainder.  
+
+In particular the value of $p$ should be chosen such that the division on step 5.3.1 occur often.  It also helps that division by $p$ be easy
+to compute.  The ideal choice of $p$ is two since division by two amounts to a right logical shift.  Another important observation is that by
+step five both $a$ and $b$ are odd.  Therefore, the diffrence $b - a$ must be even which means that each iteration removes one bit from the 
+largest of the pair.
+
+\subsection{Complete Greatest Common Divisor}
+The algorithms presented so far cannot handle inputs which are zero or negative.  The following algorithm can handle all input cases properly
+and will produce the greatest common divisor.
+
+\newpage\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{mp\_gcd}. \\
+\textbf{Input}.   mp\_int $a$ and $b$ \\
+\textbf{Output}.  The greatest common divisor $c = (a, b)$.  \\
+\hline \\
+1.  If $a = 0$ then \\
+\hspace{3mm}1.1  $c \leftarrow \vert b \vert $ \\
+\hspace{3mm}1.2  Return(\textit{MP\_OKAY}). \\
+2.  If $b = 0$ then \\
+\hspace{3mm}2.1  $c \leftarrow \vert a \vert $ \\
+\hspace{3mm}2.2  Return(\textit{MP\_OKAY}). \\
+3.  $u \leftarrow \vert a \vert, v \leftarrow \vert b \vert$ \\
+4.  $k \leftarrow 0$ \\
+5.  While $u.used > 0$ and $v.used > 0$ and $u_0 \equiv v_0 \equiv 0 \mbox{ (mod }2\mbox{)}$ \\
+\hspace{3mm}5.1  $k \leftarrow k + 1$ \\
+\hspace{3mm}5.2  $u \leftarrow \lfloor u / 2 \rfloor$ \\
+\hspace{3mm}5.3  $v \leftarrow \lfloor v / 2 \rfloor$ \\
+6.  While $u.used > 0$ and $u_0 \equiv 0 \mbox{ (mod }2\mbox{)}$ \\
+\hspace{3mm}6.1  $u \leftarrow \lfloor u / 2 \rfloor$ \\
+7.  While $v.used > 0$ and $v_0 \equiv 0 \mbox{ (mod }2\mbox{)}$ \\
+\hspace{3mm}7.1  $v \leftarrow \lfloor v / 2 \rfloor$ \\
+8.  While $v.used > 0$ \\
+\hspace{3mm}8.1  If $\vert u \vert > \vert v \vert$ then \\
+\hspace{6mm}8.1.1  Swap $u$ and $v$. \\
+\hspace{3mm}8.2  $v \leftarrow \vert v \vert - \vert u \vert$ \\
+\hspace{3mm}8.3  While $v.used > 0$ and $v_0 \equiv 0 \mbox{ (mod }2\mbox{)}$ \\
+\hspace{6mm}8.3.1  $v \leftarrow \lfloor v / 2 \rfloor$ \\
+9.  $c \leftarrow u \cdot 2^k$ \\
+10.  Return(\textit{MP\_OKAY}). \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Algorithm mp\_gcd}
+\end{figure}
+\textbf{Algorithm mp\_gcd.}
+This algorithm will produce the greatest common divisor of two mp\_ints $a$ and $b$.  The algorithm was originally based on Algorithm B of
+Knuth \cite[pp. 338]{TAOCPV2} but has been modified to be simpler to explain.  In theory it achieves the same asymptotic working time as
+Algorithm B and in practice this appears to be true.  
+
+The first two steps handle the cases where either one of or both inputs are zero.  If either input is zero the greatest common divisor is the 
+largest input or zero if they are both zero.  If the inputs are not trivial than $u$ and $v$ are assigned the absolute values of 
+$a$ and $b$ respectively and the algorithm will proceed to reduce the pair.
+
+Step five will divide out any common factors of two and keep track of the count in the variable $k$.  After this step, two is no longer a
+factor of the remaining greatest common divisor between $u$ and $v$ and can be safely evenly divided out of either whenever they are even.  Step 
+six and seven ensure that the $u$ and $v$ respectively have no more factors of two.  At most only one of the while--loops will iterate since 
+they cannot both be even.
+
+By step eight both of $u$ and $v$ are odd which is required for the inner logic.  First the pair are swapped such that $v$ is equal to
+or greater than $u$.  This ensures that the subtraction on step 8.2 will always produce a positive and even result.  Step 8.3 removes any
+factors of two from the difference $u$ to ensure that in the next iteration of the loop both are once again odd.
+
+After $v = 0$ occurs the variable $u$ has the greatest common divisor of the pair $\left < u, v \right >$ just after step six.  The result
+must be adjusted by multiplying by the common factors of two ($2^k$) removed earlier.  
+
+EXAM,bn_mp_gcd.c
+
+This function makes use of the macros mp\_iszero and mp\_iseven.  The former evaluates to $1$ if the input mp\_int is equivalent to the 
+integer zero otherwise it evaluates to $0$.  The latter evaluates to $1$ if the input mp\_int represents a non-zero even integer otherwise
+it evaluates to $0$.  Note that just because mp\_iseven may evaluate to $0$ does not mean the input is odd, it could also be zero.  The three 
+trivial cases of inputs are handled on lines @23,zero@ through @29,}@.  After those lines the inputs are assumed to be non-zero.
+
+Lines @32,if@ and @36,if@ make local copies $u$ and $v$ of the inputs $a$ and $b$ respectively.  At this point the common factors of two 
+must be divided out of the two inputs.  The block starting at line @43,common@ removes common factors of two by first counting the number of trailing
+zero bits in both.  The local integer $k$ is used to keep track of how many factors of $2$ are pulled out of both values.  It is assumed that 
+the number of factors will not exceed the maximum value of a C ``int'' data type\footnote{Strictly speaking no array in C may have more than 
+entries than are accessible by an ``int'' so this is not a limitation.}.  
+
+At this point there are no more common factors of two in the two values.  The divisions by a power of two on lines @60,div_2d@ and @67,div_2d@ remove 
+any independent factors of two such that both $u$ and $v$ are guaranteed to be an odd integer before hitting the main body of the algorithm.  The while loop
+on line @72, while@ performs the reduction of the pair until $v$ is equal to zero.  The unsigned comparison and subtraction algorithms are used in
+place of the full signed routines since both values are guaranteed to be positive and the result of the subtraction is guaranteed to be non-negative.
+
+\section{Least Common Multiple}
+The least common multiple of a pair of integers is their product divided by their greatest common divisor.  For two integers $a$ and $b$ the
+least common multiple is normally denoted as $[ a, b ]$ and numerically equivalent to ${ab} \over {(a, b)}$.  For example, if $a = 2 \cdot 2 \cdot 3 = 12$
+and $b = 2 \cdot 3 \cdot 3 \cdot 7 = 126$ the least common multiple is ${126 \over {(12, 126)}} = {126 \over 6} = 21$.
+
+The least common multiple arises often in coding theory as well as number theory.  If two functions have periods of $a$ and $b$ respectively they will
+collide, that is be in synchronous states, after only $[ a, b ]$ iterations.  This is why, for example, random number generators based on 
+Linear Feedback Shift Registers (LFSR) tend to use registers with periods which are co-prime (\textit{e.g. the greatest common divisor is one.}).  
+Similarly in number theory if a composite $n$ has two prime factors $p$ and $q$ then maximal order of any unit of $\Z/n\Z$ will be $[ p - 1, q - 1] $.
+
+\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{mp\_lcm}. \\
+\textbf{Input}.   mp\_int $a$ and $b$ \\
+\textbf{Output}.  The least common multiple $c = [a, b]$.  \\
+\hline \\
+1.  $c \leftarrow (a, b)$ \\
+2.  $t \leftarrow a \cdot b$ \\
+3.  $c \leftarrow \lfloor t / c \rfloor$ \\
+4.  Return(\textit{MP\_OKAY}). \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Algorithm mp\_lcm}
+\end{figure}
+\textbf{Algorithm mp\_lcm.}
+This algorithm computes the least common multiple of two mp\_int inputs $a$ and $b$.  It computes the least common multiple directly by
+dividing the product of the two inputs by their greatest common divisor.
+
+EXAM,bn_mp_lcm.c
+
+\section{Jacobi Symbol Computation}
+To explain the Jacobi Symbol we shall first discuss the Legendre function\footnote{Arrg.  What is the name of this?} off which the Jacobi symbol is 
+defined.  The Legendre function computes whether or not an integer $a$ is a quadratic residue modulo an odd prime $p$.  Numerically it is
+equivalent to equation \ref{eqn:legendre}.
+
+\textit{-- Tom, don't be an ass, cite your source here...!}
+
+\begin{equation}
+a^{(p-1)/2} \equiv \begin{array}{rl}
+                              -1 &  \mbox{if }a\mbox{ is a quadratic non-residue.} \\
+                              0  &  \mbox{if }a\mbox{ divides }p\mbox{.} \\
+                              1  &  \mbox{if }a\mbox{ is a quadratic residue}. 
+                              \end{array} \mbox{ (mod }p\mbox{)}
+\label{eqn:legendre}                              
+\end{equation}
+
+\textbf{Proof.} \textit{Equation \ref{eqn:legendre} correctly identifies the residue status of an integer $a$ modulo a prime $p$.}
+An integer $a$ is a quadratic residue if the following equation has a solution.
+
+\begin{equation}
+x^2 \equiv a \mbox{ (mod }p\mbox{)}
+\label{eqn:root}
+\end{equation}
+
+Consider the following equation.
+
+\begin{equation}
+0 \equiv x^{p-1} - 1 \equiv \left \lbrace \left (x^2 \right )^{(p-1)/2} - a^{(p-1)/2} \right \rbrace + \left ( a^{(p-1)/2} - 1 \right ) \mbox{ (mod }p\mbox{)}
+\label{eqn:rooti}
+\end{equation}
+
+Whether equation \ref{eqn:root} has a solution or not equation \ref{eqn:rooti} is always true.  If $a^{(p-1)/2} - 1 \equiv 0 \mbox{ (mod }p\mbox{)}$
+then the quantity in the braces must be zero.  By reduction,
+
+\begin{eqnarray}
+\left (x^2 \right )^{(p-1)/2} - a^{(p-1)/2} \equiv 0  \nonumber \\
+\left (x^2 \right )^{(p-1)/2} \equiv a^{(p-1)/2} \nonumber \\
+x^2 \equiv a \mbox{ (mod }p\mbox{)} 
+\end{eqnarray}
+
+As a result there must be a solution to the quadratic equation and in turn $a$ must be a quadratic residue.  If $a$ does not divide $p$ and $a$
+is not a quadratic residue then the only other value $a^{(p-1)/2}$ may be congruent to is $-1$ since
+\begin{equation}
+0 \equiv a^{p - 1} - 1 \equiv (a^{(p-1)/2} + 1)(a^{(p-1)/2} - 1) \mbox{ (mod }p\mbox{)}
+\end{equation}
+One of the terms on the right hand side must be zero.  \textbf{QED}
+
+\subsection{Jacobi Symbol}
+The Jacobi symbol is a generalization of the Legendre function for any odd non prime moduli $p$ greater than 2.  If $p = \prod_{i=0}^n p_i$ then
+the Jacobi symbol $\left ( { a \over p } \right )$ is equal to the following equation.
+
+\begin{equation}
+\left ( { a \over p } \right ) = \left ( { a \over p_0} \right ) \left ( { a \over p_1} \right ) \ldots \left ( { a \over p_n} \right )
+\end{equation}
+
+By inspection if $p$ is prime the Jacobi symbol is equivalent to the Legendre function.  The following facts\footnote{See HAC \cite[pp. 72-74]{HAC} for
+further details.} will be used to derive an efficient Jacobi symbol algorithm.  Where $p$ is an odd integer greater than two and $a, b \in \Z$ the
+following are true.  
+
+\begin{enumerate}
+\item $\left ( { a \over p} \right )$ equals $-1$, $0$ or $1$. 
+\item $\left ( { ab \over p} \right ) = \left ( { a \over p} \right )\left ( { b \over p} \right )$.
+\item If $a \equiv b$ then $\left ( { a \over p} \right ) = \left ( { b \over p} \right )$.
+\item $\left ( { 2 \over p} \right )$ equals $1$ if $p \equiv 1$ or $7 \mbox{ (mod }8\mbox{)}$.  Otherwise, it equals $-1$.
+\item $\left ( { a \over p} \right ) \equiv \left ( { p \over a} \right ) \cdot (-1)^{(p-1)(a-1)/4}$.  More specifically 
+$\left ( { a \over p} \right ) = \left ( { p \over a} \right )$ if $p \equiv a \equiv 1 \mbox{ (mod }4\mbox{)}$.  
+\end{enumerate}
+
+Using these facts if $a = 2^k \cdot a'$ then
+
+\begin{eqnarray}
+\left ( { a \over p } \right ) = \left ( {{2^k} \over p } \right ) \left ( {a' \over p} \right ) \nonumber \\
+                               = \left ( {2 \over p } \right )^k \left ( {a' \over p} \right ) 
+\label{eqn:jacobi}
+\end{eqnarray}
+
+By fact five, 
+
+\begin{equation}
+\left ( { a \over p } \right ) = \left ( { p \over a } \right ) \cdot (-1)^{(p-1)(a-1)/4} 
+\end{equation}
+
+Subsequently by fact three since $p \equiv (p \mbox{ mod }a) \mbox{ (mod }a\mbox{)}$ then 
+
+\begin{equation}
+\left ( { a \over p } \right ) = \left ( { {p \mbox{ mod } a} \over a } \right ) \cdot (-1)^{(p-1)(a-1)/4} 
+\end{equation}
+
+By putting both observations into equation \ref{eqn:jacobi} the following simplified equation is formed.
+
+\begin{equation}
+\left ( { a \over p } \right ) = \left ( {2 \over p } \right )^k \left ( {{p\mbox{ mod }a'} \over a'} \right )  \cdot (-1)^{(p-1)(a'-1)/4} 
+\end{equation}
+
+The value of $\left ( {{p \mbox{ mod }a'} \over a'} \right )$ can be found by using the same equation recursively.  The value of 
+$\left ( {2 \over p } \right )^k$ equals $1$ if $k$ is even otherwise it equals $\left ( {2 \over p } \right )$.  Using this approach the 
+factors of $p$ do not have to be known.  Furthermore, if $(a, p) = 1$ then the algorithm will terminate when the recursion requests the 
+Jacobi symbol computation of $\left ( {1 \over a'} \right )$ which is simply $1$.  
+
+\newpage\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{mp\_jacobi}. \\
+\textbf{Input}.   mp\_int $a$ and $p$, $a \ge 0$, $p \ge 3$, $p \equiv 1 \mbox{ (mod }2\mbox{)}$ \\
+\textbf{Output}.  The Jacobi symbol $c = \left ( {a \over p } \right )$. \\
+\hline \\
+1.  If $a = 0$ then \\
+\hspace{3mm}1.1  $c \leftarrow 0$ \\
+\hspace{3mm}1.2  Return(\textit{MP\_OKAY}). \\
+2.  If $a = 1$ then \\
+\hspace{3mm}2.1  $c \leftarrow 1$ \\
+\hspace{3mm}2.2  Return(\textit{MP\_OKAY}). \\
+3.  $a' \leftarrow a$ \\
+4.  $k \leftarrow 0$ \\
+5.  While $a'.used > 0$ and $a'_0 \equiv 0 \mbox{ (mod }2\mbox{)}$ \\
+\hspace{3mm}5.1  $k \leftarrow k + 1$ \\
+\hspace{3mm}5.2  $a' \leftarrow \lfloor a' / 2 \rfloor$ \\
+6.  If $k \equiv 0 \mbox{ (mod }2\mbox{)}$ then \\
+\hspace{3mm}6.1  $s \leftarrow 1$ \\
+7.  else \\
+\hspace{3mm}7.1  $r \leftarrow p_0 \mbox{ (mod }8\mbox{)}$ \\
+\hspace{3mm}7.2  If $r = 1$ or $r = 7$ then \\
+\hspace{6mm}7.2.1  $s \leftarrow 1$ \\
+\hspace{3mm}7.3  else \\
+\hspace{6mm}7.3.1  $s \leftarrow -1$ \\
+8.  If $p_0 \equiv a'_0 \equiv 3 \mbox{ (mod }4\mbox{)}$ then \\
+\hspace{3mm}8.1  $s \leftarrow -s$ \\
+9.  If $a' \ne 1$ then \\
+\hspace{3mm}9.1  $p' \leftarrow p \mbox{ (mod }a'\mbox{)}$ \\
+\hspace{3mm}9.2  $s \leftarrow s \cdot \mbox{mp\_jacobi}(p', a')$ \\
+10.  $c \leftarrow s$ \\
+11.  Return(\textit{MP\_OKAY}). \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Algorithm mp\_jacobi}
+\end{figure}
+\textbf{Algorithm mp\_jacobi.}
+This algorithm computes the Jacobi symbol for an arbitrary positive integer $a$ with respect to an odd integer $p$ greater than three.  The algorithm
+is based on algorithm 2.149 of HAC \cite[pp. 73]{HAC}.  
+
+Step numbers one and two handle the trivial cases of $a = 0$ and $a = 1$ respectively.  Step five determines the number of two factors in the
+input $a$.  If $k$ is even than the term $\left ( { 2 \over p } \right )^k$ must always evaluate to one.  If $k$ is odd than the term evaluates to one 
+if $p_0$ is congruent to one or seven modulo eight, otherwise it evaluates to $-1$. After the the $\left ( { 2 \over p } \right )^k$ term is handled 
+the $(-1)^{(p-1)(a'-1)/4}$ is computed and multiplied against the current product $s$.  The latter term evaluates to one if both $p$ and $a'$ 
+are congruent to one modulo four, otherwise it evaluates to negative one.
+
+By step nine if $a'$ does not equal one a recursion is required.  Step 9.1 computes $p' \equiv p \mbox{ (mod }a'\mbox{)}$ and will recurse to compute
+$\left ( {p' \over a'} \right )$ which is multiplied against the current Jacobi product.
+
+EXAM,bn_mp_jacobi.c
+
+As a matter of practicality the variable $a'$ as per the pseudo-code is reprensented by the variable $a1$ since the $'$ symbol is not valid for a C 
+variable name character. 
+
+The two simple cases of $a = 0$ and $a = 1$ are handled at the very beginning to simplify the algorithm.  If the input is non-trivial the algorithm
+has to proceed compute the Jacobi.  The variable $s$ is used to hold the current Jacobi product.  Note that $s$ is merely a C ``int'' data type since
+the values it may obtain are merely $-1$, $0$ and $1$.  
+
+After a local copy of $a$ is made all of the factors of two are divided out and the total stored in $k$.  Technically only the least significant
+bit of $k$ is required, however, it makes the algorithm simpler to follow to perform an addition. In practice an exclusive-or and addition have the same 
+processor requirements and neither is faster than the other.
+
+Line @59, if@ through @70, }@ determines the value of $\left ( { 2 \over p } \right )^k$.  If the least significant bit of $k$ is zero than
+$k$ is even and the value is one.  Otherwise, the value of $s$ depends on which residue class $p$ belongs to modulo eight.  The value of
+$(-1)^{(p-1)(a'-1)/4}$ is compute and multiplied against $s$ on lines @73, if@ through @75, }@.  
+
+Finally, if $a1$ does not equal one the algorithm must recurse and compute $\left ( {p' \over a'} \right )$.  
+
+\textit{-- Comment about default $s$ and such...}
+
+\section{Modular Inverse}
+\label{sec:modinv}
+The modular inverse of a number actually refers to the modular multiplicative inverse.  Essentially for any integer $a$ such that $(a, p) = 1$ there
+exist another integer $b$ such that $ab \equiv 1 \mbox{ (mod }p\mbox{)}$.  The integer $b$ is called the multiplicative inverse of $a$ which is
+denoted as $b = a^{-1}$.  Technically speaking modular inversion is a well defined operation for any finite ring or field not just for rings and 
+fields of integers.  However, the former will be the matter of discussion.
+
+The simplest approach is to compute the algebraic inverse of the input.  That is to compute $b \equiv a^{\Phi(p) - 1}$.  If $\Phi(p)$ is the 
+order of the multiplicative subgroup modulo $p$ then $b$ must be the multiplicative inverse of $a$.  The proof of which is trivial.
+
+\begin{equation}
+ab \equiv a \left (a^{\Phi(p) - 1} \right ) \equiv a^{\Phi(p)} \equiv a^0 \equiv 1 \mbox{ (mod }p\mbox{)}
+\end{equation}
+
+However, as simple as this approach may be it has two serious flaws.  It requires that the value of $\Phi(p)$ be known which if $p$ is composite 
+requires all of the prime factors.  This approach also is very slow as the size of $p$ grows.  
+
+A simpler approach is based on the observation that solving for the multiplicative inverse is equivalent to solving the linear 
+Diophantine\footnote{See LeVeque \cite[pp. 40-43]{LeVeque} for more information.} equation.
+
+\begin{equation}
+ab + pq = 1
+\end{equation}
+
+Where $a$, $b$, $p$ and $q$ are all integers.  If such a pair of integers $ \left < b, q \right >$ exist than $b$ is the multiplicative inverse of 
+$a$ modulo $p$.  The extended Euclidean algorithm (Knuth \cite[pp. 342]{TAOCPV2}) can be used to solve such equations provided $(a, p) = 1$.  
+However, instead of using that algorithm directly a variant known as the binary Extended Euclidean algorithm will be used in its place.  The
+binary approach is very similar to the binary greatest common divisor algorithm except it will produce a full solution to the Diophantine 
+equation.  
+
+\subsection{General Case}
+\newpage\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{mp\_invmod}. \\
+\textbf{Input}.   mp\_int $a$ and $b$, $(a, b) = 1$, $p \ge 2$, $0 < a < p$.  \\
+\textbf{Output}.  The modular inverse $c \equiv a^{-1} \mbox{ (mod }b\mbox{)}$. \\
+\hline \\
+1.  If $b \le 0$ then return(\textit{MP\_VAL}). \\
+2.  If $b_0 \equiv 1 \mbox{ (mod }2\mbox{)}$ then use algorithm fast\_mp\_invmod. \\
+3.  $x \leftarrow \vert a \vert, y \leftarrow b$ \\
+4.  If $x_0 \equiv y_0  \equiv 0 \mbox{ (mod }2\mbox{)}$ then return(\textit{MP\_VAL}). \\
+5.  $B \leftarrow 0, C \leftarrow 0, A \leftarrow 1, D \leftarrow 1$ \\
+6.  While $u.used > 0$ and $u_0 \equiv 0 \mbox{ (mod }2\mbox{)}$ \\
+\hspace{3mm}6.1  $u \leftarrow \lfloor u / 2 \rfloor$ \\
+\hspace{3mm}6.2  If ($A.used > 0$ and $A_0 \equiv 1 \mbox{ (mod }2\mbox{)}$) or ($B.used > 0$ and $B_0 \equiv 1 \mbox{ (mod }2\mbox{)}$) then \\
+\hspace{6mm}6.2.1  $A \leftarrow A + y$ \\
+\hspace{6mm}6.2.2  $B \leftarrow B - x$ \\
+\hspace{3mm}6.3  $A \leftarrow \lfloor A / 2 \rfloor$ \\
+\hspace{3mm}6.4  $B \leftarrow \lfloor B / 2 \rfloor$ \\
+7.  While $v.used > 0$ and $v_0 \equiv 0 \mbox{ (mod }2\mbox{)}$ \\
+\hspace{3mm}7.1  $v \leftarrow \lfloor v / 2 \rfloor$ \\
+\hspace{3mm}7.2  If ($C.used > 0$ and $C_0 \equiv 1 \mbox{ (mod }2\mbox{)}$) or ($D.used > 0$ and $D_0 \equiv 1 \mbox{ (mod }2\mbox{)}$) then \\
+\hspace{6mm}7.2.1  $C \leftarrow C + y$ \\
+\hspace{6mm}7.2.2  $D \leftarrow D - x$ \\
+\hspace{3mm}7.3  $C \leftarrow \lfloor C / 2 \rfloor$ \\
+\hspace{3mm}7.4  $D \leftarrow \lfloor D / 2 \rfloor$ \\
+8.  If $u \ge v$ then \\
+\hspace{3mm}8.1  $u \leftarrow u - v$ \\
+\hspace{3mm}8.2  $A \leftarrow A - C$ \\
+\hspace{3mm}8.3  $B \leftarrow B - D$ \\
+9.  else \\
+\hspace{3mm}9.1  $v \leftarrow v - u$ \\
+\hspace{3mm}9.2  $C \leftarrow C - A$ \\
+\hspace{3mm}9.3  $D \leftarrow D - B$ \\
+10.  If $u \ne 0$ goto step 6. \\
+11.  If $v \ne 1$ return(\textit{MP\_VAL}). \\
+12.  While $C \le 0$ do \\
+\hspace{3mm}12.1  $C \leftarrow C + b$ \\
+13.  While $C \ge b$ do \\
+\hspace{3mm}13.1  $C \leftarrow C - b$ \\
+14.  $c \leftarrow C$ \\
+15.  Return(\textit{MP\_OKAY}). \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\end{figure}
+\textbf{Algorithm mp\_invmod.}
+This algorithm computes the modular multiplicative inverse of an integer $a$ modulo an integer $b$.  This algorithm is a variation of the 
+extended binary Euclidean algorithm from HAC \cite[pp. 608]{HAC}.  It has been modified to only compute the modular inverse and not a complete
+Diophantine solution.  
+
+If $b \le 0$ than the modulus is invalid and MP\_VAL is returned.  Similarly if both $a$ and $b$ are even then there cannot be a multiplicative
+inverse for $a$ and the error is reported.  
+
+The astute reader will observe that steps seven through nine are very similar to the binary greatest common divisor algorithm mp\_gcd.  In this case
+the other variables to the Diophantine equation are solved.  The algorithm terminates when $u = 0$ in which case the solution is
+
+\begin{equation}
+Ca + Db = v
+\end{equation}
+
+If $v$, the greatest common divisor of $a$ and $b$ is not equal to one then the algorithm will report an error as no inverse exists.  Otherwise, $C$
+is the modular inverse of $a$.  The actual value of $C$ is congruent to, but not necessarily equal to, the ideal modular inverse which should lie 
+within $1 \le a^{-1} < b$.  Step numbers twelve and thirteen adjust the inverse until it is in range.  If the original input $a$ is within $0 < a < p$ 
+then only a couple of additions or subtractions will be required to adjust the inverse.
+
+EXAM,bn_mp_invmod.c
+
+\subsubsection{Odd Moduli}
+
+When the modulus $b$ is odd the variables $A$ and $C$ are fixed and are not required to compute the inverse.  In particular by attempting to solve
+the Diophantine $Cb + Da = 1$ only $B$ and $D$ are required to find the inverse of $a$.  
+
+The algorithm fast\_mp\_invmod is a direct adaptation of algorithm mp\_invmod with all all steps involving either $A$ or $C$ removed.  This 
+optimization will halve the time required to compute the modular inverse.
+
+\section{Primality Tests}
+
+A non-zero integer $a$ is said to be prime if it is not divisible by any other integer excluding one and itself.  For example, $a = 7$ is prime 
+since the integers $2 \ldots 6$ do not evenly divide $a$.  By contrast, $a = 6$ is not prime since $a = 6 = 2 \cdot 3$. 
+
+Prime numbers arise in cryptography considerably as they allow finite fields to be formed.  The ability to determine whether an integer is prime or
+not quickly has been a viable subject in cryptography and number theory for considerable time.  The algorithms that will be presented are all
+probablistic algorithms in that when they report an integer is composite it must be composite.  However, when the algorithms report an integer is
+prime the algorithm may be incorrect.  
+
+As will be discussed it is possible to limit the probability of error so well that for practical purposes the probablity of error might as 
+well be zero.  For the purposes of these discussions let $n$ represent the candidate integer of which the primality is in question.
+
+\subsection{Trial Division}
+
+Trial division means to attempt to evenly divide a candidate integer by small prime integers.  If the candidate can be evenly divided it obviously
+cannot be prime.  By dividing by all primes $1 < p \le \sqrt{n}$ this test can actually prove whether an integer is prime.  However, such a test
+would require a prohibitive amount of time as $n$ grows.
+
+Instead of dividing by every prime, a smaller, more mangeable set of primes may be used instead.  By performing trial division with only a subset
+of the primes less than $\sqrt{n} + 1$ the algorithm cannot prove if a candidate is prime.  However, often it can prove a candidate is not prime.
+
+The benefit of this test is that trial division by small values is fairly efficient.  Specially compared to the other algorithms that will be
+discussed shortly.  The probability that this approach correctly identifies a composite candidate when tested with all primes upto $q$ is given by
+$1 - {1.12 \over ln(q)}$.  The graph (\ref{pic:primality}, will be added later) demonstrates the probability of success for the range 
+$3 \le q \le 100$.  
+
+At approximately $q = 30$ the gain of performing further tests diminishes fairly quickly.  At $q = 90$ further testing is generally not going to 
+be of any practical use.  In the case of LibTomMath the default limit $q = 256$ was chosen since it is not too high and will eliminate 
+approximately $80\%$ of all candidate integers.  The constant \textbf{PRIME\_SIZE} is equal to the number of primes in the test base.  The 
+array \_\_prime\_tab is an array of the first \textbf{PRIME\_SIZE} prime numbers.  
+
+\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{mp\_prime\_is\_divisible}. \\
+\textbf{Input}.   mp\_int $a$ \\
+\textbf{Output}.  $c = 1$ if $n$ is divisible by a small prime, otherwise $c = 0$.  \\
+\hline \\
+1.  for $ix$ from $0$ to $PRIME\_SIZE$ do \\
+\hspace{3mm}1.1  $d \leftarrow n \mbox{ (mod }\_\_prime\_tab_{ix}\mbox{)}$ \\
+\hspace{3mm}1.2  If $d = 0$ then \\
+\hspace{6mm}1.2.1  $c \leftarrow 1$ \\
+\hspace{6mm}1.2.2  Return(\textit{MP\_OKAY}). \\
+2.  $c \leftarrow 0$ \\
+3.  Return(\textit{MP\_OKAY}). \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Algorithm mp\_prime\_is\_divisible}
+\end{figure}
+\textbf{Algorithm mp\_prime\_is\_divisible.}
+This algorithm attempts to determine if a candidate integer $n$ is composite by performing trial divisions.  
+
+EXAM,bn_mp_prime_is_divisible.c
+
+The algorithm defaults to a return of $0$ in case an error occurs.  The values in the prime table are all specified to be in the range of a 
+mp\_digit.  The table \_\_prime\_tab is defined in the following file.
+
+EXAM,bn_prime_tab.c
+
+Note that there are two possible tables.  When an mp\_digit is 7-bits long only the primes upto $127$ may be included, otherwise the primes
+upto $1619$ are used.  Note that the value of \textbf{PRIME\_SIZE} is a constant dependent on the size of a mp\_digit. 
+
+\subsection{The Fermat Test}
+The Fermat test is probably one the oldest tests to have a non-trivial probability of success.  It is based on the fact that if $n$ is in 
+fact prime then $a^{n} \equiv a \mbox{ (mod }n\mbox{)}$ for all $0 < a < n$.  The reason being that if $n$ is prime than the order of
+the multiplicative sub group is $n - 1$.  Any base $a$ must have an order which divides $n - 1$ and as such $a^n$ is equivalent to 
+$a^1 = a$.  
+
+If $n$ is composite then any given base $a$ does not have to have a period which divides $n - 1$.  In which case 
+it is possible that $a^n \nequiv a \mbox{ (mod }n\mbox{)}$.  However, this test is not absolute as it is possible that the order
+of a base will divide $n - 1$ which would then be reported as prime.  Such a base yields what is known as a Fermat pseudo-prime.  Several 
+integers known as Carmichael numbers will be a pseudo-prime to all valid bases.  Fortunately such numbers are extremely rare as $n$ grows
+in size.
+
+\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{mp\_prime\_fermat}. \\
+\textbf{Input}.   mp\_int $a$ and $b$, $a \ge 2$, $0 < b < a$.  \\
+\textbf{Output}.  $c = 1$ if $b^a \equiv b \mbox{ (mod }a\mbox{)}$, otherwise $c = 0$.  \\
+\hline \\
+1.  $t \leftarrow b^a \mbox{ (mod }a\mbox{)}$ \\
+2.  If $t = b$ then \\
+\hspace{3mm}2.1  $c = 1$ \\
+3.  else \\
+\hspace{3mm}3.1  $c = 0$ \\
+4.  Return(\textit{MP\_OKAY}). \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Algorithm mp\_prime\_fermat}
+\end{figure}
+\textbf{Algorithm mp\_prime\_fermat.}
+This algorithm determines whether an mp\_int $a$ is a Fermat prime to the base $b$ or not.  It uses a single modular exponentiation to
+determine the result.  
+
+EXAM,bn_mp_prime_fermat.c
+
+\subsection{The Miller-Rabin Test}
+The Miller-Rabin (citation) test is another primality test which has tighter error bounds than the Fermat test specifically with sequentially chosen 
+candidate  integers.  The algorithm is based on the observation that if $n - 1 = 2^kr$ and if $b^r \nequiv \pm 1$ then after upto $k - 1$ squarings the 
+value must be equal to $-1$.  The squarings are stopped as soon as $-1$ is observed.  If the value of $1$ is observed first it means that
+some value not congruent to $\pm 1$ when squared equals one which cannot occur if $n$ is prime.
+
+\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{mp\_prime\_miller\_rabin}. \\
+\textbf{Input}.   mp\_int $a$ and $b$, $a \ge 2$, $0 < b < a$.  \\
+\textbf{Output}.  $c = 1$ if $a$ is a Miller-Rabin prime to the base $a$, otherwise $c = 0$.  \\
+\hline
+1.  $a' \leftarrow a - 1$ \\
+2.  $r  \leftarrow n1$    \\
+3.  $c \leftarrow 0, s  \leftarrow 0$ \\
+4.  While $r.used > 0$ and $r_0 \equiv 0 \mbox{ (mod }2\mbox{)}$ \\
+\hspace{3mm}4.1  $s \leftarrow s + 1$ \\
+\hspace{3mm}4.2  $r \leftarrow \lfloor r / 2 \rfloor$ \\
+5.  $y \leftarrow b^r \mbox{ (mod }a\mbox{)}$ \\
+6.  If $y \nequiv \pm 1$ then \\
+\hspace{3mm}6.1  $j \leftarrow 1$ \\
+\hspace{3mm}6.2  While $j \le (s - 1)$ and $y \nequiv a'$ \\
+\hspace{6mm}6.2.1  $y \leftarrow y^2 \mbox{ (mod }a\mbox{)}$ \\
+\hspace{6mm}6.2.2  If $y = 1$ then goto step 8. \\
+\hspace{6mm}6.2.3  $j \leftarrow j + 1$ \\
+\hspace{3mm}6.3  If $y \nequiv a'$ goto step 8. \\
+7.  $c \leftarrow 1$\\
+8.  Return(\textit{MP\_OKAY}). \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Algorithm mp\_prime\_miller\_rabin}
+\end{figure}
+\textbf{Algorithm mp\_prime\_miller\_rabin.}
+This algorithm performs one trial round of the Miller-Rabin algorithm to the base $b$.  It will set $c = 1$ if the algorithm cannot determine
+if $b$ is composite or $c = 0$ if $b$ is provably composite.  The values of $s$ and $r$ are computed such that $a' = a - 1 = 2^sr$.  
+
+If the value $y \equiv b^r$ is congruent to $\pm 1$ then the algorithm cannot prove if $a$ is composite or not.  Otherwise, the algorithm will
+square $y$ upto $s - 1$ times stopping only when $y \equiv -1$.  If $y^2 \equiv 1$ and $y \nequiv \pm 1$ then the algorithm can report that $a$
+is provably composite.  If the algorithm performs $s - 1$ squarings and $y \nequiv -1$ then $a$ is provably composite.  If $a$ is not provably 
+composite then it is \textit{probably} prime.
+
+EXAM,bn_mp_prime_miller_rabin.c
+
+
+
+
+\backmatter
+\appendix
+\begin{thebibliography}{ABCDEF}
+\bibitem[1]{TAOCPV2}
+Donald Knuth, \textit{The Art of Computer Programming}, Third Edition, Volume Two, Seminumerical Algorithms, Addison-Wesley, 1998
+
+\bibitem[2]{HAC}
+A. Menezes, P. van Oorschot, S. Vanstone, \textit{Handbook of Applied Cryptography}, CRC Press, 1996
+
+\bibitem[3]{ROSE}
+Michael Rosing, \textit{Implementing Elliptic Curve Cryptography}, Manning Publications, 1999
+
+\bibitem[4]{COMBA}
+Paul G. Comba, \textit{Exponentiation Cryptosystems on the IBM PC}. IBM Systems Journal 29(4): 526-538 (1990)
+
+\bibitem[5]{KARA}
+A. Karatsuba, Doklay Akad. Nauk SSSR 145 (1962), pp.293-294
+
+\bibitem[6]{KARAP}
+Andre Weimerskirch and Christof Paar, \textit{Generalizations of the Karatsuba Algorithm for Polynomial Multiplication}, Submitted to Design, Codes and Cryptography, March 2002
+
+\bibitem[7]{BARRETT}
+Paul Barrett, \textit{Implementing the Rivest Shamir and Adleman Public Key Encryption Algorithm on a Standard Digital Signal Processor}, Advances in Cryptology, Crypto '86, Springer-Verlag.
+
+\bibitem[8]{MONT}
+P.L.Montgomery. \textit{Modular multiplication without trial division}. Mathematics of Computation, 44(170):519-521, April 1985.
+
+\bibitem[9]{DRMET}
+Chae Hoon Lim and Pil Joong Lee, \textit{Generating Efficient Primes for Discrete Log Cryptosystems}, POSTECH Information Research Laboratories
+
+\bibitem[10]{MMB}
+J. Daemen and R. Govaerts and J. Vandewalle, \textit{Block ciphers based on Modular Arithmetic}, State and {P}rogress in the {R}esearch of {C}ryptography, 1993, pp. 80-89
+
+\bibitem[11]{RSAREF}
+R.L. Rivest, A. Shamir, L. Adleman, \textit{A Method for Obtaining Digital Signatures and Public-Key Cryptosystems}
+
+\bibitem[12]{DHREF}
+Whitfield Diffie, Martin E. Hellman, \textit{New Directions in Cryptography}, IEEE Transactions on Information Theory, 1976
+
+\bibitem[13]{IEEE}
+IEEE Standard for Binary Floating-Point Arithmetic (ANSI/IEEE Std 754-1985)
+
+\bibitem[14]{GMP}
+GNU Multiple Precision (GMP), \url{http://www.swox.com/gmp/}
+
+\bibitem[15]{MPI}
+Multiple Precision Integer Library (MPI), Michael Fromberger, \url{http://thayer.dartmouth.edu/~sting/mpi/}
+
+\bibitem[16]{OPENSSL}
+OpenSSL Cryptographic Toolkit, \url{http://openssl.org}
+
+\bibitem[17]{LIP}
+Large Integer Package, \url{http://home.hetnet.nl/~ecstr/LIP.zip}
+
+\bibitem[18]{ISOC}
+JTC1/SC22/WG14, ISO/IEC 9899:1999, ``A draft rationale for the C99 standard.''
+
+\bibitem[19]{JAVA}
+The Sun Java Website, \url{http://java.sun.com/}
+
+\end{thebibliography}
+
+\input{tommath.ind}
+
+\end{document}
diff --git a/libtommath/tommath.tex b/libtommath/tommath.tex
new file mode 100644
index 0000000..c79a537
--- /dev/null
+++ b/libtommath/tommath.tex
@@ -0,0 +1,6691 @@
+\documentclass[b5paper]{book}
+\usepackage{hyperref}
+\usepackage{makeidx}
+\usepackage{amssymb}
+\usepackage{color}
+\usepackage{alltt}
+\usepackage{graphicx}
+\usepackage{layout}
+\def\union{\cup}
+\def\intersect{\cap}
+\def\getsrandom{\stackrel{\rm R}{\gets}}
+\def\cross{\times}
+\def\cat{\hspace{0.5em} \| \hspace{0.5em}}
+\def\catn{$\|$}
+\def\divides{\hspace{0.3em} | \hspace{0.3em}}
+\def\nequiv{\not\equiv}
+\def\approx{\raisebox{0.2ex}{\mbox{\small $\sim$}}}
+\def\lcm{{\rm lcm}}
+\def\gcd{{\rm gcd}}
+\def\log{{\rm log}}
+\def\ord{{\rm ord}}
+\def\abs{{\mathit abs}}
+\def\rep{{\mathit rep}}
+\def\mod{{\mathit\ mod\ }}
+\renewcommand{\pmod}[1]{\ ({\rm mod\ }{#1})}
+\newcommand{\floor}[1]{\left\lfloor{#1}\right\rfloor}
+\newcommand{\ceil}[1]{\left\lceil{#1}\right\rceil}
+\def\Or{{\rm\ or\ }}
+\def\And{{\rm\ and\ }}
+\def\iff{\hspace{1em}\Longleftrightarrow\hspace{1em}}
+\def\implies{\Rightarrow}
+\def\undefined{{\rm ``undefined"}}
+\def\Proof{\vspace{1ex}\noindent {\bf Proof:}\hspace{1em}}
+\let\oldphi\phi
+\def\phi{\varphi}
+\def\Pr{{\rm Pr}}
+\newcommand{\str}[1]{{\mathbf{#1}}}
+\def\F{{\mathbb F}}
+\def\N{{\mathbb N}}
+\def\Z{{\mathbb Z}}
+\def\R{{\mathbb R}}
+\def\C{{\mathbb C}}
+\def\Q{{\mathbb Q}}
+\definecolor{DGray}{gray}{0.5}
+\newcommand{\emailaddr}[1]{\mbox{$<${#1}$>$}}
+\def\twiddle{\raisebox{0.3ex}{\mbox{\tiny $\sim$}}}
+\def\gap{\vspace{0.5ex}}
+\makeindex
+\begin{document}
+\frontmatter
+\pagestyle{empty}
+\title{Multi--Precision Math}
+\author{\mbox{
+%\begin{small}
+\begin{tabular}{c}
+Tom St Denis \\
+Algonquin College \\
+\\
+Mads Rasmussen \\
+Open Communications Security \\
+\\
+Greg Rose \\
+QUALCOMM Australia \\
+\end{tabular}
+%\end{small}
+}
+}
+\maketitle
+This text has been placed in the public domain.  This text corresponds to the v0.39 release of the 
+LibTomMath project.
+
+\begin{alltt}
+Tom St Denis
+111 Banning Rd
+Ottawa, Ontario
+K2L 1C3
+Canada
+
+Phone: 1-613-836-3160
+Email: tomstdenis@gmail.com
+\end{alltt}
+
+This text is formatted to the international B5 paper size of 176mm wide by 250mm tall using the \LaTeX{} 
+{\em book} macro package and the Perl {\em booker} package.
+
+\tableofcontents
+\listoffigures
+\chapter*{Prefaces}
+When I tell people about my LibTom projects and that I release them as public domain they are often puzzled.  
+They ask why I did it and especially why I continue to work on them for free.  The best I can explain it is ``Because I can.''  
+Which seems odd and perhaps too terse for adult conversation. I often qualify it with ``I am able, I am willing.'' which 
+perhaps explains it better.  I am the first to admit there is not anything that special with what I have done.  Perhaps
+others can see that too and then we would have a society to be proud of.  My LibTom projects are what I am doing to give 
+back to society in the form of tools and knowledge that can help others in their endeavours.
+
+I started writing this book because it was the most logical task to further my goal of open academia.  The LibTomMath source
+code itself was written to be easy to follow and learn from.  There are times, however, where pure C source code does not
+explain the algorithms properly.  Hence this book.  The book literally starts with the foundation of the library and works
+itself outwards to the more complicated algorithms.  The use of both pseudo--code and verbatim source code provides a duality
+of ``theory'' and ``practice'' that the computer science students of the world shall appreciate.  I never deviate too far
+from relatively straightforward algebra and I hope that this book can be a valuable learning asset.
+
+This book and indeed much of the LibTom projects would not exist in their current form if it was not for a plethora
+of kind people donating their time, resources and kind words to help support my work.  Writing a text of significant
+length (along with the source code) is a tiresome and lengthy process.  Currently the LibTom project is four years old,
+comprises of literally thousands of users and over 100,000 lines of source code, TeX and other material.  People like Mads and Greg 
+were there at the beginning to encourage me to work well.  It is amazing how timely validation from others can boost morale to 
+continue the project. Definitely my parents were there for me by providing room and board during the many months of work in 2003.  
+
+To my many friends whom I have met through the years I thank you for the good times and the words of encouragement.  I hope I
+honour your kind gestures with this project.
+
+Open Source.  Open Academia.  Open Minds.
+
+\begin{flushright} Tom St Denis \end{flushright}
+
+\newpage
+I found the opportunity to work with Tom appealing for several reasons, not only could I broaden my own horizons, but also 
+contribute to educate others facing the problem of having to handle big number mathematical calculations.
+
+This book is Tom's child and he has been caring and fostering the project ever since the beginning with a clear mind of 
+how he wanted the project to turn out. I have helped by proofreading the text and we have had several discussions about 
+the layout and language used.
+
+I hold a masters degree in cryptography from the University of Southern Denmark and have always been interested in the 
+practical aspects of cryptography. 
+
+Having worked in the security consultancy business for several years in S\~{a}o Paulo, Brazil, I have been in touch with a 
+great deal of work in which multiple precision mathematics was needed. Understanding the possibilities for speeding up 
+multiple precision calculations is often very important since we deal with outdated machine architecture where modular 
+reductions, for example, become painfully slow.
+
+This text is for people who stop and wonder when first examining algorithms such as RSA for the first time and asks 
+themselves, ``You tell me this is only secure for large numbers, fine; but how do you implement these numbers?''
+
+\begin{flushright}
+Mads Rasmussen
+
+S\~{a}o Paulo - SP
+
+Brazil
+\end{flushright}
+
+\newpage
+It's all because I broke my leg. That just happened to be at about the same time that Tom asked for someone to review the section of the book about 
+Karatsuba multiplication. I was laid up, alone and immobile, and thought ``Why not?'' I vaguely knew what Karatsuba multiplication was, but not 
+really, so I thought I could help, learn, and stop myself from watching daytime cable TV, all at once.
+
+At the time of writing this, I've still not met Tom or Mads in meatspace. I've been following Tom's progress since his first splash on the 
+sci.crypt Usenet news group. I watched him go from a clueless newbie, to the cryptographic equivalent of a reformed smoker, to a real
+contributor to the field, over a period of about two years. I've been impressed with his obvious intelligence, and astounded by his productivity. 
+Of course, he's young enough to be my own child, so he doesn't have my problems with staying awake.
+
+When I reviewed that single section of the book, in its very earliest form, I was very pleasantly surprised. So I decided to collaborate more fully, 
+and at least review all of it, and perhaps write some bits too. There's still a long way to go with it, and I have watched a number of close 
+friends go through the mill of publication, so I think that the way to go is longer than Tom thinks it is. Nevertheless, it's a good effort, 
+and I'm pleased to be involved with it.
+
+\begin{flushright}
+Greg Rose, Sydney, Australia, June 2003. 
+\end{flushright}
+
+\mainmatter
+\pagestyle{headings}
+\chapter{Introduction}
+\section{Multiple Precision Arithmetic}
+
+\subsection{What is Multiple Precision Arithmetic?}
+When we think of long-hand arithmetic such as addition or multiplication we rarely consider the fact that we instinctively
+raise or lower the precision of the numbers we are dealing with.  For example, in decimal we almost immediate can 
+reason that $7$ times $6$ is $42$.  However, $42$ has two digits of precision as opposed to one digit we started with.  
+Further multiplications of say $3$ result in a larger precision result $126$.  In these few examples we have multiple 
+precisions for the numbers we are working with.  Despite the various levels of precision a single subset\footnote{With the occasional optimization.}
+ of algorithms can be designed to accomodate them.  
+
+By way of comparison a fixed or single precision operation would lose precision on various operations.  For example, in
+the decimal system with fixed precision $6 \cdot 7 = 2$.
+
+Essentially at the heart of computer based multiple precision arithmetic are the same long-hand algorithms taught in
+schools to manually add, subtract, multiply and divide.  
+
+\subsection{The Need for Multiple Precision Arithmetic}
+The most prevalent need for multiple precision arithmetic, often referred to as ``bignum'' math, is within the implementation
+of public-key cryptography algorithms.   Algorithms such as RSA \cite{RSAREF} and Diffie-Hellman \cite{DHREF} require 
+integers of significant magnitude to resist known cryptanalytic attacks.  For example, at the time of this writing a 
+typical RSA modulus would be at least greater than $10^{309}$.  However, modern programming languages such as ISO C \cite{ISOC} and 
+Java \cite{JAVA} only provide instrinsic support for integers which are relatively small and single precision.
+
+\begin{figure}[!here]
+\begin{center}
+\begin{tabular}{|r|c|}
+\hline \textbf{Data Type} & \textbf{Range} \\
+\hline char  & $-128 \ldots 127$ \\
+\hline short & $-32768 \ldots 32767$ \\
+\hline long  & $-2147483648 \ldots 2147483647$ \\
+\hline long long & $-9223372036854775808 \ldots 9223372036854775807$ \\
+\hline
+\end{tabular}
+\end{center}
+\caption{Typical Data Types for the C Programming Language}
+\label{fig:ISOC}
+\end{figure}
+
+The largest data type guaranteed to be provided by the ISO C programming 
+language\footnote{As per the ISO C standard.  However, each compiler vendor is allowed to augment the precision as they 
+see fit.}  can only represent values up to $10^{19}$ as shown in figure \ref{fig:ISOC}. On its own the C language is 
+insufficient to accomodate the magnitude required for the problem at hand.  An RSA modulus of magnitude $10^{19}$ could be 
+trivially factored\footnote{A Pollard-Rho factoring would take only $2^{16}$ time.} on the average desktop computer, 
+rendering any protocol based on the algorithm insecure.  Multiple precision algorithms solve this very problem by 
+extending the range of representable integers while using single precision data types.
+
+Most advancements in fast multiple precision arithmetic stem from the need for faster and more efficient cryptographic 
+primitives.  Faster modular reduction and exponentiation algorithms such as Barrett's algorithm, which have appeared in 
+various cryptographic journals, can render algorithms such as RSA and Diffie-Hellman more efficient.  In fact, several 
+major companies such as RSA Security, Certicom and Entrust have built entire product lines on the implementation and 
+deployment of efficient algorithms.
+
+However, cryptography is not the only field of study that can benefit from fast multiple precision integer routines.  
+Another auxiliary use of multiple precision integers is high precision floating point data types.  
+The basic IEEE \cite{IEEE} standard floating point type is made up of an integer mantissa $q$, an exponent $e$ and a sign bit $s$.  
+Numbers are given in the form $n = q \cdot b^e \cdot -1^s$ where $b = 2$ is the most common base for IEEE.  Since IEEE 
+floating point is meant to be implemented in hardware the precision of the mantissa is often fairly small 
+(\textit{23, 48 and 64 bits}).  The mantissa is merely an integer and a multiple precision integer could be used to create
+a mantissa of much larger precision than hardware alone can efficiently support.  This approach could be useful where 
+scientific applications must minimize the total output error over long calculations.
+
+Yet another use for large integers is within arithmetic on polynomials of large characteristic (i.e. $GF(p)[x]$ for large $p$).
+In fact the library discussed within this text has already been used to form a polynomial basis library\footnote{See \url{http://poly.libtomcrypt.org} for more details.}.
+
+\subsection{Benefits of Multiple Precision Arithmetic}
+\index{precision}
+The benefit of multiple precision representations over single or fixed precision representations is that 
+no precision is lost while representing the result of an operation which requires excess precision.  For example, 
+the product of two $n$-bit integers requires at least $2n$ bits of precision to be represented faithfully.  A multiple 
+precision algorithm would augment the precision of the destination to accomodate the result while a single precision system 
+would truncate excess bits to maintain a fixed level of precision.
+
+It is possible to implement algorithms which require large integers with fixed precision algorithms.  For example, elliptic
+curve cryptography (\textit{ECC}) is often implemented on smartcards by fixing the precision of the integers to the maximum 
+size the system will ever need.  Such an approach can lead to vastly simpler algorithms which can accomodate the 
+integers required even if the host platform cannot natively accomodate them\footnote{For example, the average smartcard 
+processor has an 8 bit accumulator.}.  However, as efficient as such an approach may be, the resulting source code is not
+normally very flexible.  It cannot, at runtime, accomodate inputs of higher magnitude than the designer anticipated.
+
+Multiple precision algorithms have the most overhead of any style of arithmetic.  For the the most part the 
+overhead can be kept to a minimum with careful planning, but overall, it is not well suited for most memory starved
+platforms.  However, multiple precision algorithms do offer the most flexibility in terms of the magnitude of the 
+inputs.  That is, the same algorithms based on multiple precision integers can accomodate any reasonable size input 
+without the designer's explicit forethought.  This leads to lower cost of ownership for the code as it only has to 
+be written and tested once.
+
+\section{Purpose of This Text}
+The purpose of this text is to instruct the reader regarding how to implement efficient multiple precision algorithms.  
+That is to not only explain a limited subset of the core theory behind the algorithms but also the various ``house keeping'' 
+elements that are neglected by authors of other texts on the subject.  Several well reknowned texts \cite{TAOCPV2,HAC} 
+give considerably detailed explanations of the theoretical aspects of algorithms and often very little information 
+regarding the practical implementation aspects.  
+
+In most cases how an algorithm is explained and how it is actually implemented are two very different concepts.  For 
+example, the Handbook of Applied Cryptography (\textit{HAC}), algorithm 14.7 on page 594, gives a relatively simple 
+algorithm for performing multiple precision integer addition.  However, the description lacks any discussion concerning 
+the fact that the two integer inputs may be of differing magnitudes.  As a result the implementation is not as simple
+as the text would lead people to believe.  Similarly the division routine (\textit{algorithm 14.20, pp. 598}) does not 
+discuss how to handle sign or handle the dividend's decreasing magnitude in the main loop (\textit{step \#3}).
+
+Both texts also do not discuss several key optimal algorithms required such as ``Comba'' and Karatsuba multipliers 
+and fast modular inversion, which we consider practical oversights.  These optimal algorithms are vital to achieve 
+any form of useful performance in non-trivial applications.  
+
+To solve this problem the focus of this text is on the practical aspects of implementing a multiple precision integer
+package.  As a case study the ``LibTomMath''\footnote{Available at \url{http://math.libtomcrypt.com}} package is used 
+to demonstrate algorithms with real implementations\footnote{In the ISO C programming language.} that have been field 
+tested and work very well.  The LibTomMath library is freely available on the Internet for all uses and this text 
+discusses a very large portion of the inner workings of the library.
+
+The algorithms that are presented will always include at least one ``pseudo-code'' description followed 
+by the actual C source code that implements the algorithm.  The pseudo-code can be used to implement the same 
+algorithm in other programming languages as the reader sees fit.  
+
+This text shall also serve as a walkthrough of the creation of multiple precision algorithms from scratch.  Showing
+the reader how the algorithms fit together as well as where to start on various taskings.  
+
+\section{Discussion and Notation}
+\subsection{Notation}
+A multiple precision integer of $n$-digits shall be denoted as $x = (x_{n-1}, \ldots, x_1, x_0)_{ \beta }$ and represent
+the integer $x \equiv \sum_{i=0}^{n-1} x_i\beta^i$.  The elements of the array $x$ are said to be the radix $\beta$ digits 
+of the integer.  For example, $x = (1,2,3)_{10}$ would represent the integer 
+$1\cdot 10^2 + 2\cdot10^1 + 3\cdot10^0 = 123$.  
+
+\index{mp\_int}
+The term ``mp\_int'' shall refer to a composite structure which contains the digits of the integer it represents, as well 
+as auxilary data required to manipulate the data.  These additional members are discussed further in section 
+\ref{sec:MPINT}.  For the purposes of this text a ``multiple precision integer'' and an ``mp\_int'' are assumed to be 
+synonymous.  When an algorithm is specified to accept an mp\_int variable it is assumed the various auxliary data members 
+are present as well.  An expression of the type \textit{variablename.item} implies that it should evaluate to the 
+member named ``item'' of the variable.  For example, a string of characters may have a member ``length'' which would 
+evaluate to the number of characters in the string.  If the string $a$ equals ``hello'' then it follows that 
+$a.length = 5$.  
+
+For certain discussions more generic algorithms are presented to help the reader understand the final algorithm used
+to solve a given problem.  When an algorithm is described as accepting an integer input it is assumed the input is 
+a plain integer with no additional multiple-precision members.  That is, algorithms that use integers as opposed to 
+mp\_ints as inputs do not concern themselves with the housekeeping operations required such as memory management.  These 
+algorithms will be used to establish the relevant theory which will subsequently be used to describe a multiple
+precision algorithm to solve the same problem.  
+
+\subsection{Precision Notation}
+The variable $\beta$ represents the radix of a single digit of a multiple precision integer and 
+must be of the form $q^p$ for $q, p \in \Z^+$.  A single precision variable must be able to represent integers in 
+the range $0 \le x < q \beta$ while a double precision variable must be able to represent integers in the range 
+$0 \le x < q \beta^2$.  The extra radix-$q$ factor allows additions and subtractions to proceed without truncation of the 
+carry.  Since all modern computers are binary, it is assumed that $q$ is two.
+
+\index{mp\_digit} \index{mp\_word}
+Within the source code that will be presented for each algorithm, the data type \textbf{mp\_digit} will represent 
+a single precision integer type, while, the data type \textbf{mp\_word} will represent a double precision integer type.  In 
+several algorithms (notably the Comba routines) temporary results will be stored in arrays of double precision mp\_words.  
+For the purposes of this text $x_j$ will refer to the $j$'th digit of a single precision array and $\hat x_j$ will refer to 
+the $j$'th digit of a double precision array.  Whenever an expression is to be assigned to a double precision
+variable it is assumed that all single precision variables are promoted to double precision during the evaluation.  
+Expressions that are assigned to a single precision variable are truncated to fit within the precision of a single
+precision data type.
+
+For example, if $\beta = 10^2$ a single precision data type may represent a value in the 
+range $0 \le x < 10^3$, while a double precision data type may represent a value in the range $0 \le x < 10^5$.  Let
+$a = 23$ and $b = 49$ represent two single precision variables.  The single precision product shall be written
+as $c \leftarrow a \cdot b$ while the double precision product shall be written as $\hat c \leftarrow a \cdot b$.
+In this particular case, $\hat c = 1127$ and $c = 127$.  The most significant digit of the product would not fit 
+in a single precision data type and as a result $c \ne \hat c$.  
+
+\subsection{Algorithm Inputs and Outputs}
+Within the algorithm descriptions all variables are assumed to be scalars of either single or double precision
+as indicated.  The only exception to this rule is when variables have been indicated to be of type mp\_int.  This 
+distinction is important as scalars are often used as array indicies and various other counters.  
+
+\subsection{Mathematical Expressions}
+The $\lfloor \mbox{ } \rfloor$ brackets imply an expression truncated to an integer not greater than the expression 
+itself.  For example, $\lfloor 5.7 \rfloor = 5$.  Similarly the $\lceil \mbox{ } \rceil$ brackets imply an expression
+rounded to an integer not less than the expression itself.  For example, $\lceil 5.1 \rceil = 6$.  Typically when 
+the $/$ division symbol is used the intention is to perform an integer division with truncation.  For example, 
+$5/2 = 2$ which will often be written as $\lfloor 5/2 \rfloor = 2$ for clarity.  When an expression is written as a 
+fraction a real value division is implied, for example ${5 \over 2} = 2.5$.  
+
+The norm of a multiple precision integer, for example $\vert \vert x \vert \vert$, will be used to represent the number of digits in the representation
+of the integer.  For example, $\vert \vert 123 \vert \vert = 3$ and $\vert \vert 79452 \vert \vert = 5$.  
+
+\subsection{Work Effort}
+\index{big-Oh}
+To measure the efficiency of the specified algorithms, a modified big-Oh notation is used.  In this system all 
+single precision operations are considered to have the same cost\footnote{Except where explicitly noted.}.  
+That is a single precision addition, multiplication and division are assumed to take the same time to 
+complete.  While this is generally not true in practice, it will simplify the discussions considerably.
+
+Some algorithms have slight advantages over others which is why some constants will not be removed in 
+the notation.  For example, a normal baseline multiplication (section \ref{sec:basemult}) requires $O(n^2)$ work while a 
+baseline squaring (section \ref{sec:basesquare}) requires $O({{n^2 + n}\over 2})$ work.  In standard big-Oh notation these 
+would both be said to be equivalent to $O(n^2)$.  However, 
+in the context of the this text this is not the case as the magnitude of the inputs will typically be rather small.  As a 
+result small constant factors in the work effort will make an observable difference in algorithm efficiency.
+
+All of the algorithms presented in this text have a polynomial time work level.  That is, of the form 
+$O(n^k)$ for $n, k \in \Z^{+}$.  This will help make useful comparisons in terms of the speed of the algorithms and how 
+various optimizations will help pay off in the long run.
+
+\section{Exercises}
+Within the more advanced chapters a section will be set aside to give the reader some challenging exercises related to
+the discussion at hand.  These exercises are not designed to be prize winning problems, but instead to be thought 
+provoking.  Wherever possible the problems are forward minded, stating problems that will be answered in subsequent 
+chapters.  The reader is encouraged to finish the exercises as they appear to get a better understanding of the 
+subject material.  
+
+That being said, the problems are designed to affirm knowledge of a particular subject matter.  Students in particular
+are encouraged to verify they can answer the problems correctly before moving on.
+
+Similar to the exercises of \cite[pp. ix]{TAOCPV2} these exercises are given a scoring system based on the difficulty of
+the problem.  However, unlike \cite{TAOCPV2} the problems do not get nearly as hard.  The scoring of these 
+exercises ranges from one (the easiest) to five (the hardest).  The following table sumarizes the 
+scoring system used.
+
+\begin{figure}[here]
+\begin{center}
+\begin{small}
+\begin{tabular}{|c|l|}
+\hline $\left [ 1 \right ]$ & An easy problem that should only take the reader a manner of \\
+                            & minutes to solve.  Usually does not involve much computer time \\
+                            & to solve. \\
+\hline $\left [ 2 \right ]$ & An easy problem that involves a marginal amount of computer \\
+                     & time usage.  Usually requires a program to be written to \\
+                     & solve the problem. \\
+\hline $\left [ 3 \right ]$ & A moderately hard problem that requires a non-trivial amount \\
+                     & of work.  Usually involves trivial research and development of \\
+                     & new theory from the perspective of a student. \\
+\hline $\left [ 4 \right ]$ & A moderately hard problem that involves a non-trivial amount \\
+                     & of work and research, the solution to which will demonstrate \\
+                     & a higher mastery of the subject matter. \\
+\hline $\left [ 5 \right ]$ & A hard problem that involves concepts that are difficult for a \\
+                     & novice to solve.  Solutions to these problems will demonstrate a \\
+                     & complete mastery of the given subject. \\
+\hline
+\end{tabular}
+\end{small}
+\end{center}
+\caption{Exercise Scoring System}
+\end{figure}
+
+Problems at the first level are meant to be simple questions that the reader can answer quickly without programming a solution or
+devising new theory.  These problems are quick tests to see if the material is understood.  Problems at the second level 
+are also designed to be easy but will require a program or algorithm to be implemented to arrive at the answer.  These
+two levels are essentially entry level questions.  
+
+Problems at the third level are meant to be a bit more difficult than the first two levels.  The answer is often 
+fairly obvious but arriving at an exacting solution requires some thought and skill.  These problems will almost always 
+involve devising a new algorithm or implementing a variation of another algorithm previously presented.  Readers who can
+answer these questions will feel comfortable with the concepts behind the topic at hand.
+
+Problems at the fourth level are meant to be similar to those of the level three questions except they will require 
+additional research to be completed.  The reader will most likely not know the answer right away, nor will the text provide 
+the exact details of the answer until a subsequent chapter.  
+
+Problems at the fifth level are meant to be the hardest 
+problems relative to all the other problems in the chapter.  People who can correctly answer fifth level problems have a 
+mastery of the subject matter at hand.
+
+Often problems will be tied together.  The purpose of this is to start a chain of thought that will be discussed in future chapters.  The reader
+is encouraged to answer the follow-up problems and try to draw the relevance of problems.
+
+\section{Introduction to LibTomMath}
+
+\subsection{What is LibTomMath?}
+LibTomMath is a free and open source multiple precision integer library written entirely in portable ISO C.  By portable it 
+is meant that the library does not contain any code that is computer platform dependent or otherwise problematic to use on 
+any given platform.  
+
+The library has been successfully tested under numerous operating systems including Unix\footnote{All of these
+trademarks belong to their respective rightful owners.}, MacOS, Windows, Linux, PalmOS and on standalone hardware such 
+as the Gameboy Advance.  The library is designed to contain enough functionality to be able to develop applications such 
+as public key cryptosystems and still maintain a relatively small footprint.
+
+\subsection{Goals of LibTomMath}
+
+Libraries which obtain the most efficiency are rarely written in a high level programming language such as C.  However, 
+even though this library is written entirely in ISO C, considerable care has been taken to optimize the algorithm implementations within the 
+library.  Specifically the code has been written to work well with the GNU C Compiler (\textit{GCC}) on both x86 and ARM 
+processors.  Wherever possible, highly efficient algorithms, such as Karatsuba multiplication, sliding window 
+exponentiation and Montgomery reduction have been provided to make the library more efficient.  
+
+Even with the nearly optimal and specialized algorithms that have been included the Application Programing Interface 
+(\textit{API}) has been kept as simple as possible.  Often generic place holder routines will make use of specialized 
+algorithms automatically without the developer's specific attention.  One such example is the generic multiplication 
+algorithm \textbf{mp\_mul()} which will automatically use Toom--Cook, Karatsuba, Comba or baseline multiplication 
+based on the magnitude of the inputs and the configuration of the library.  
+
+Making LibTomMath as efficient as possible is not the only goal of the LibTomMath project.  Ideally the library should 
+be source compatible with another popular library which makes it more attractive for developers to use.  In this case the
+MPI library was used as a API template for all the basic functions.  MPI was chosen because it is another library that fits 
+in the same niche as LibTomMath.  Even though LibTomMath uses MPI as the template for the function names and argument 
+passing conventions, it has been written from scratch by Tom St Denis.
+
+The project is also meant to act as a learning tool for students, the logic being that no easy-to-follow ``bignum'' 
+library exists which can be used to teach computer science students how to perform fast and reliable multiple precision 
+integer arithmetic.  To this end the source code has been given quite a few comments and algorithm discussion points.  
+
+\section{Choice of LibTomMath}
+LibTomMath was chosen as the case study of this text not only because the author of both projects is one and the same but
+for more worthy reasons.  Other libraries such as GMP \cite{GMP}, MPI \cite{MPI}, LIP \cite{LIP} and OpenSSL 
+\cite{OPENSSL} have multiple precision integer arithmetic routines but would not be ideal for this text for 
+reasons that will be explained in the following sub-sections.
+
+\subsection{Code Base}
+The LibTomMath code base is all portable ISO C source code.  This means that there are no platform dependent conditional
+segments of code littered throughout the source.  This clean and uncluttered approach to the library means that a
+developer can more readily discern the true intent of a given section of source code without trying to keep track of
+what conditional code will be used.
+
+The code base of LibTomMath is well organized.  Each function is in its own separate source code file 
+which allows the reader to find a given function very quickly.  On average there are $76$ lines of code per source
+file which makes the source very easily to follow.  By comparison MPI and LIP are single file projects making code tracing
+very hard.  GMP has many conditional code segments which also hinder tracing.  
+
+When compiled with GCC for the x86 processor and optimized for speed the entire library is approximately $100$KiB\footnote{The notation ``KiB'' means $2^{10}$ octets, similarly ``MiB'' means $2^{20}$ octets.}
+ which is fairly small compared to GMP (over $250$KiB).  LibTomMath is slightly larger than MPI (which compiles to about 
+$50$KiB) but LibTomMath is also much faster and more complete than MPI.
+
+\subsection{API Simplicity}
+LibTomMath is designed after the MPI library and shares the API design.  Quite often programs that use MPI will build 
+with LibTomMath without change. The function names correlate directly to the action they perform.  Almost all of the 
+functions share the same parameter passing convention.  The learning curve is fairly shallow with the API provided 
+which is an extremely valuable benefit for the student and developer alike.  
+
+The LIP library is an example of a library with an API that is awkward to work with.  LIP uses function names that are often ``compressed'' to 
+illegible short hand.  LibTomMath does not share this characteristic.  
+
+The GMP library also does not return error codes.  Instead it uses a POSIX.1 \cite{POSIX1} signal system where errors
+are signaled to the host application.  This happens to be the fastest approach but definitely not the most versatile.  In
+effect a math error (i.e. invalid input, heap error, etc) can cause a program to stop functioning which is definitely 
+undersireable in many situations.
+
+\subsection{Optimizations}
+While LibTomMath is certainly not the fastest library (GMP often beats LibTomMath by a factor of two) it does
+feature a set of optimal algorithms for tasks such as modular reduction, exponentiation, multiplication and squaring.  GMP 
+and LIP also feature such optimizations while MPI only uses baseline algorithms with no optimizations.  GMP lacks a few
+of the additional modular reduction optimizations that LibTomMath features\footnote{At the time of this writing GMP
+only had Barrett and Montgomery modular reduction algorithms.}.  
+
+LibTomMath is almost always an order of magnitude faster than the MPI library at computationally expensive tasks such as modular
+exponentiation.  In the grand scheme of ``bignum'' libraries LibTomMath is faster than the average library and usually  
+slower than the best libraries such as GMP and OpenSSL by only a small factor.
+
+\subsection{Portability and Stability}
+LibTomMath will build ``out of the box'' on any platform equipped with a modern version of the GNU C Compiler 
+(\textit{GCC}).  This means that without changes the library will build without configuration or setting up any 
+variables.  LIP and MPI will build ``out of the box'' as well but have numerous known bugs.  Most notably the author of 
+MPI has recently stopped working on his library and LIP has long since been discontinued.  
+
+GMP requires a configuration script to run and will not build out of the box.   GMP and LibTomMath are still in active
+development and are very stable across a variety of platforms.
+
+\subsection{Choice}
+LibTomMath is a relatively compact, well documented, highly optimized and portable library which seems only natural for
+the case study of this text.  Various source files from the LibTomMath project will be included within the text.  However, 
+the reader is encouraged to download their own copy of the library to actually be able to work with the library.  
+
+\chapter{Getting Started}
+\section{Library Basics}
+The trick to writing any useful library of source code is to build a solid foundation and work outwards from it.  First, 
+a problem along with allowable solution parameters should be identified and analyzed.  In this particular case the 
+inability to accomodate multiple precision integers is the problem.  Futhermore, the solution must be written
+as portable source code that is reasonably efficient across several different computer platforms.
+
+After a foundation is formed the remainder of the library can be designed and implemented in a hierarchical fashion.  
+That is, to implement the lowest level dependencies first and work towards the most abstract functions last.  For example, 
+before implementing a modular exponentiation algorithm one would implement a modular reduction algorithm.
+By building outwards from a base foundation instead of using a parallel design methodology the resulting project is 
+highly modular.  Being highly modular is a desirable property of any project as it often means the resulting product
+has a small footprint and updates are easy to perform.  
+
+Usually when I start a project I will begin with the header files.  I define the data types I think I will need and 
+prototype the initial functions that are not dependent on other functions (within the library).  After I 
+implement these base functions I prototype more dependent functions and implement them.   The process repeats until
+I implement all of the functions I require.  For example, in the case of LibTomMath I implemented functions such as 
+mp\_init() well before I implemented mp\_mul() and even further before I implemented mp\_exptmod().  As an example as to 
+why this design works note that the Karatsuba and Toom-Cook multipliers were written \textit{after} the 
+dependent function mp\_exptmod() was written.  Adding the new multiplication algorithms did not require changes to the 
+mp\_exptmod() function itself and lowered the total cost of ownership (\textit{so to speak}) and of development 
+for new algorithms.  This methodology allows new algorithms to be tested in a complete framework with relative ease.
+
+\begin{center}
+\begin{figure}[here]
+\includegraphics{pics/design_process.ps}
+\caption{Design Flow of the First Few Original LibTomMath Functions.}
+\label{pic:design_process}
+\end{figure}
+\end{center}
+
+Only after the majority of the functions were in place did I pursue a less hierarchical approach to auditing and optimizing
+the source code.  For example, one day I may audit the multipliers and the next day the polynomial basis functions.  
+
+It only makes sense to begin the text with the preliminary data types and support algorithms required as well.  
+This chapter discusses the core algorithms of the library which are the dependents for every other algorithm.
+
+\section{What is a Multiple Precision Integer?}
+Recall that most programming languages, in particular ISO C \cite{ISOC}, only have fixed precision data types that on their own cannot 
+be used to represent values larger than their precision will allow. The purpose of multiple precision algorithms is 
+to use fixed precision data types to create and manipulate multiple precision integers which may represent values 
+that are very large.  
+
+As a well known analogy, school children are taught how to form numbers larger than nine by prepending more radix ten digits.  In the decimal system
+the largest single digit value is $9$.  However, by concatenating digits together larger numbers may be represented.  Newly prepended digits 
+(\textit{to the left}) are said to be in a different power of ten column.  That is, the number $123$ can be described as having a $1$ in the hundreds 
+column, $2$ in the tens column and $3$ in the ones column.  Or more formally $123 = 1 \cdot 10^2 + 2 \cdot 10^1 + 3 \cdot 10^0$.  Computer based 
+multiple precision arithmetic is essentially the same concept.  Larger integers are represented by adjoining fixed 
+precision computer words with the exception that a different radix is used.
+
+What most people probably do not think about explicitly are the various other attributes that describe a multiple precision 
+integer.  For example, the integer $154_{10}$ has two immediately obvious properties.  First, the integer is positive, 
+that is the sign of this particular integer is positive as opposed to negative.  Second, the integer has three digits in 
+its representation.  There is an additional property that the integer posesses that does not concern pencil-and-paper 
+arithmetic.  The third property is how many digits placeholders are available to hold the integer.  
+
+The human analogy of this third property is ensuring there is enough space on the paper to write the integer.  For example,
+if one starts writing a large number too far to the right on a piece of paper they will have to erase it and move left.  
+Similarly, computer algorithms must maintain strict control over memory usage to ensure that the digits of an integer
+will not exceed the allowed boundaries.  These three properties make up what is known as a multiple precision 
+integer or mp\_int for short.  
+
+\subsection{The mp\_int Structure}
+\label{sec:MPINT}
+The mp\_int structure is the ISO C based manifestation of what represents a multiple precision integer.  The ISO C standard does not provide for 
+any such data type but it does provide for making composite data types known as structures.  The following is the structure definition 
+used within LibTomMath.
+
+\index{mp\_int}
+\begin{figure}[here]
+\begin{center}
+\begin{small}
+%\begin{verbatim}
+\begin{tabular}{|l|}
+\hline
+typedef struct \{ \\
+\hspace{3mm}int used, alloc, sign;\\
+\hspace{3mm}mp\_digit *dp;\\
+\} \textbf{mp\_int}; \\
+\hline
+\end{tabular}
+%\end{verbatim}
+\end{small}
+\caption{The mp\_int Structure}
+\label{fig:mpint}
+\end{center}
+\end{figure}
+
+The mp\_int structure (fig. \ref{fig:mpint}) can be broken down as follows.
+
+\begin{enumerate}
+\item The \textbf{used} parameter denotes how many digits of the array \textbf{dp} contain the digits used to represent
+a given integer.  The \textbf{used} count must be positive (or zero) and may not exceed the \textbf{alloc} count.  
+
+\item The \textbf{alloc} parameter denotes how 
+many digits are available in the array to use by functions before it has to increase in size.  When the \textbf{used} count 
+of a result would exceed the \textbf{alloc} count all of the algorithms will automatically increase the size of the 
+array to accommodate the precision of the result.  
+
+\item The pointer \textbf{dp} points to a dynamically allocated array of digits that represent the given multiple 
+precision integer.  It is padded with $(\textbf{alloc} - \textbf{used})$ zero digits.  The array is maintained in a least 
+significant digit order.  As a pencil and paper analogy the array is organized such that the right most digits are stored
+first starting at the location indexed by zero\footnote{In C all arrays begin at zero.} in the array.  For example, 
+if \textbf{dp} contains $\lbrace a, b, c, \ldots \rbrace$ where \textbf{dp}$_0 = a$, \textbf{dp}$_1 = b$, \textbf{dp}$_2 = c$, $\ldots$ then 
+it would represent the integer $a + b\beta + c\beta^2 + \ldots$  
+
+\index{MP\_ZPOS} \index{MP\_NEG}
+\item The \textbf{sign} parameter denotes the sign as either zero/positive (\textbf{MP\_ZPOS}) or negative (\textbf{MP\_NEG}).  
+\end{enumerate}
+
+\subsubsection{Valid mp\_int Structures}
+Several rules are placed on the state of an mp\_int structure and are assumed to be followed for reasons of efficiency.  
+The only exceptions are when the structure is passed to initialization functions such as mp\_init() and mp\_init\_copy().
+
+\begin{enumerate}
+\item The value of \textbf{alloc} may not be less than one.  That is \textbf{dp} always points to a previously allocated
+array of digits.
+\item The value of \textbf{used} may not exceed \textbf{alloc} and must be greater than or equal to zero.
+\item The value of \textbf{used} implies the digit at index $(used - 1)$ of the \textbf{dp} array is non-zero.  That is, 
+leading zero digits in the most significant positions must be trimmed.
+   \begin{enumerate}
+   \item Digits in the \textbf{dp} array at and above the \textbf{used} location must be zero.
+   \end{enumerate}
+\item The value of \textbf{sign} must be \textbf{MP\_ZPOS} if \textbf{used} is zero; 
+this represents the mp\_int value of zero.
+\end{enumerate}
+
+\section{Argument Passing}
+A convention of argument passing must be adopted early on in the development of any library.  Making the function 
+prototypes consistent will help eliminate many headaches in the future as the library grows to significant complexity.  
+In LibTomMath the multiple precision integer functions accept parameters from left to right as pointers to mp\_int 
+structures.  That means that the source (input) operands are placed on the left and the destination (output) on the right.   
+Consider the following examples.
+
+\begin{verbatim}
+   mp_mul(&a, &b, &c);   /* c = a * b */
+   mp_add(&a, &b, &a);   /* a = a + b */
+   mp_sqr(&a, &b);       /* b = a * a */
+\end{verbatim}
+
+The left to right order is a fairly natural way to implement the functions since it lets the developer read aloud the
+functions and make sense of them.  For example, the first function would read ``multiply a and b and store in c''.
+
+Certain libraries (\textit{LIP by Lenstra for instance}) accept parameters the other way around, to mimic the order
+of assignment expressions.  That is, the destination (output) is on the left and arguments (inputs) are on the right.  In 
+truth, it is entirely a matter of preference.  In the case of LibTomMath the convention from the MPI library has been 
+adopted.  
+
+Another very useful design consideration, provided for in LibTomMath, is whether to allow argument sources to also be a 
+destination.  For example, the second example (\textit{mp\_add}) adds $a$ to $b$ and stores in $a$.  This is an important 
+feature to implement since it allows the calling functions to cut down on the number of variables it must maintain.  
+However, to implement this feature specific care has to be given to ensure the destination is not modified before the 
+source is fully read.
+
+\section{Return Values}
+A well implemented application, no matter what its purpose, should trap as many runtime errors as possible and return them 
+to the caller.  By catching runtime errors a library can be guaranteed to prevent undefined behaviour.  However, the end 
+developer can still manage to cause a library to crash.  For example, by passing an invalid pointer an application may
+fault by dereferencing memory not owned by the application.
+
+In the case of LibTomMath the only errors that are checked for are related to inappropriate inputs (division by zero for 
+instance) and memory allocation errors.  It will not check that the mp\_int passed to any function is valid nor 
+will it check pointers for validity.  Any function that can cause a runtime error will return an error code as an 
+\textbf{int} data type with one of the following values (fig \ref{fig:errcodes}).
+
+\index{MP\_OKAY} \index{MP\_VAL} \index{MP\_MEM}
+\begin{figure}[here]
+\begin{center}
+\begin{tabular}{|l|l|}
+\hline \textbf{Value} & \textbf{Meaning} \\
+\hline \textbf{MP\_OKAY} & The function was successful \\
+\hline \textbf{MP\_VAL}  & One of the input value(s) was invalid \\
+\hline \textbf{MP\_MEM}  & The function ran out of heap memory \\
+\hline
+\end{tabular}
+\end{center}
+\caption{LibTomMath Error Codes}
+\label{fig:errcodes}
+\end{figure}
+
+When an error is detected within a function it should free any memory it allocated, often during the initialization of
+temporary mp\_ints, and return as soon as possible.  The goal is to leave the system in the same state it was when the 
+function was called.  Error checking with this style of API is fairly simple.
+
+\begin{verbatim}
+   int err;
+   if ((err = mp_add(&a, &b, &c)) != MP_OKAY) {
+      printf("Error: %s\n", mp_error_to_string(err));
+      exit(EXIT_FAILURE);
+   }
+\end{verbatim}
+
+The GMP \cite{GMP} library uses C style \textit{signals} to flag errors which is of questionable use.  Not all errors are fatal 
+and it was not deemed ideal by the author of LibTomMath to force developers to have signal handlers for such cases.
+
+\section{Initialization and Clearing}
+The logical starting point when actually writing multiple precision integer functions is the initialization and 
+clearing of the mp\_int structures.  These two algorithms will be used by the majority of the higher level algorithms.
+
+Given the basic mp\_int structure an initialization routine must first allocate memory to hold the digits of
+the integer.  Often it is optimal to allocate a sufficiently large pre-set number of digits even though
+the initial integer will represent zero.  If only a single digit were allocated quite a few subsequent re-allocations
+would occur when operations are performed on the integers.  There is a tradeoff between how many default digits to allocate
+and how many re-allocations are tolerable.  Obviously allocating an excessive amount of digits initially will waste 
+memory and become unmanageable.  
+
+If the memory for the digits has been successfully allocated then the rest of the members of the structure must
+be initialized.  Since the initial state of an mp\_int is to represent the zero integer, the allocated digits must be set
+to zero.  The \textbf{used} count set to zero and \textbf{sign} set to \textbf{MP\_ZPOS}.
+
+\subsection{Initializing an mp\_int}
+An mp\_int is said to be initialized if it is set to a valid, preferably default, state such that all of the members of the
+structure are set to valid values.  The mp\_init algorithm will perform such an action.
+
+\index{mp\_init}
+\begin{figure}[here]
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{mp\_init}. \\
+\textbf{Input}.   An mp\_int $a$ \\
+\textbf{Output}.  Allocate memory and initialize $a$ to a known valid mp\_int state.  \\
+\hline \\
+1.  Allocate memory for \textbf{MP\_PREC} digits. \\
+2.  If the allocation failed return(\textit{MP\_MEM}) \\
+3.  for $n$ from $0$ to $MP\_PREC - 1$ do  \\
+\hspace{3mm}3.1  $a_n \leftarrow 0$\\
+4.  $a.sign \leftarrow MP\_ZPOS$\\
+5.  $a.used \leftarrow 0$\\
+6.  $a.alloc \leftarrow MP\_PREC$\\
+7.  Return(\textit{MP\_OKAY})\\
+\hline
+\end{tabular}
+\end{center}
+\caption{Algorithm mp\_init}
+\end{figure}
+
+\textbf{Algorithm mp\_init.}
+The purpose of this function is to initialize an mp\_int structure so that the rest of the library can properly
+manipulte it.  It is assumed that the input may not have had any of its members previously initialized which is certainly
+a valid assumption if the input resides on the stack.  
+
+Before any of the members such as \textbf{sign}, \textbf{used} or \textbf{alloc} are initialized the memory for
+the digits is allocated.  If this fails the function returns before setting any of the other members.  The \textbf{MP\_PREC} 
+name represents a constant\footnote{Defined in the ``tommath.h'' header file within LibTomMath.} 
+used to dictate the minimum precision of newly initialized mp\_int integers.  Ideally, it is at least equal to the smallest
+precision number you'll be working with.
+
+Allocating a block of digits at first instead of a single digit has the benefit of lowering the number of usually slow
+heap operations later functions will have to perform in the future.  If \textbf{MP\_PREC} is set correctly the slack 
+memory and the number of heap operations will be trivial.
+
+Once the allocation has been made the digits have to be set to zero as well as the \textbf{used}, \textbf{sign} and
+\textbf{alloc} members initialized.  This ensures that the mp\_int will always represent the default state of zero regardless
+of the original condition of the input.
+
+\textbf{Remark.}
+This function introduces the idiosyncrasy that all iterative loops, commonly initiated with the ``for'' keyword, iterate incrementally
+when the ``to'' keyword is placed between two expressions.  For example, ``for $a$ from $b$ to $c$ do'' means that
+a subsequent expression (or body of expressions) are to be evaluated upto $c - b$ times so long as $b \le c$.  In each
+iteration the variable $a$ is substituted for a new integer that lies inclusively between $b$ and $c$.  If $b > c$ occured
+the loop would not iterate.  By contrast if the ``downto'' keyword were used in place of ``to'' the loop would iterate 
+decrementally.
+
+\vspace{+3mm}\begin{small}
+\hspace{-5.1mm}{\bf File}: bn\_mp\_init.c
+\vspace{-3mm}
+\begin{alltt}
+\end{alltt}
+\end{small}
+
+One immediate observation of this initializtion function is that it does not return a pointer to a mp\_int structure.  It 
+is assumed that the caller has already allocated memory for the mp\_int structure, typically on the application stack.  The 
+call to mp\_init() is used only to initialize the members of the structure to a known default state.  
+
+Here we see (line 24) the memory allocation is performed first.  This allows us to exit cleanly and quickly
+if there is an error.  If the allocation fails the routine will return \textbf{MP\_MEM} to the caller to indicate there
+was a memory error.  The function XMALLOC is what actually allocates the memory.  Technically XMALLOC is not a function
+but a macro defined in ``tommath.h``.  By default, XMALLOC will evaluate to malloc() which is the C library's built--in
+memory allocation routine.
+
+In order to assure the mp\_int is in a known state the digits must be set to zero.  On most platforms this could have been
+accomplished by using calloc() instead of malloc().  However,  to correctly initialize a integer type to a given value in a 
+portable fashion you have to actually assign the value.  The for loop (line 30) performs this required
+operation.
+
+After the memory has been successfully initialized the remainder of the members are initialized 
+(lines 34 through 35) to their respective default states.  At this point the algorithm has succeeded and
+a success code is returned to the calling function.  If this function returns \textbf{MP\_OKAY} it is safe to assume the 
+mp\_int structure has been properly initialized and is safe to use with other functions within the library.  
+
+\subsection{Clearing an mp\_int}
+When an mp\_int is no longer required by the application, the memory that has been allocated for its digits must be 
+returned to the application's memory pool with the mp\_clear algorithm.
+
+\begin{figure}[here]
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{mp\_clear}. \\
+\textbf{Input}.   An mp\_int $a$ \\
+\textbf{Output}.  The memory for $a$ shall be deallocated.  \\
+\hline \\
+1.  If $a$ has been previously freed then return(\textit{MP\_OKAY}). \\
+2.  for $n$ from 0 to $a.used - 1$ do \\
+\hspace{3mm}2.1  $a_n \leftarrow 0$ \\
+3.  Free the memory allocated for the digits of $a$. \\
+4.  $a.used \leftarrow 0$ \\
+5.  $a.alloc \leftarrow 0$ \\
+6.  $a.sign \leftarrow MP\_ZPOS$ \\
+7.  Return(\textit{MP\_OKAY}). \\
+\hline
+\end{tabular}
+\end{center}
+\caption{Algorithm mp\_clear}
+\end{figure}
+
+\textbf{Algorithm mp\_clear.}
+This algorithm accomplishes two goals.  First, it clears the digits and the other mp\_int members.  This ensures that 
+if a developer accidentally re-uses a cleared structure it is less likely to cause problems.  The second goal
+is to free the allocated memory.
+
+The logic behind the algorithm is extended by marking cleared mp\_int structures so that subsequent calls to this
+algorithm will not try to free the memory multiple times.  Cleared mp\_ints are detectable by having a pre-defined invalid 
+digit pointer \textbf{dp} setting.
+
+Once an mp\_int has been cleared the mp\_int structure is no longer in a valid state for any other algorithm
+with the exception of algorithms mp\_init, mp\_init\_copy, mp\_init\_size and mp\_clear.
+
+\vspace{+3mm}\begin{small}
+\hspace{-5.1mm}{\bf File}: bn\_mp\_clear.c
+\vspace{-3mm}
+\begin{alltt}
+\end{alltt}
+\end{small}
+
+The algorithm only operates on the mp\_int if it hasn't been previously cleared.  The if statement (line 25)
+checks to see if the \textbf{dp} member is not \textbf{NULL}.  If the mp\_int is a valid mp\_int then \textbf{dp} cannot be
+\textbf{NULL} in which case the if statement will evaluate to true.
+
+The digits of the mp\_int are cleared by the for loop (line 27) which assigns a zero to every digit.  Similar to mp\_init()
+the digits are assigned zero instead of using block memory operations (such as memset()) since this is more portable.  
+
+The digits are deallocated off the heap via the XFREE macro.  Similar to XMALLOC the XFREE macro actually evaluates to
+a standard C library function.  In this case the free() function.  Since free() only deallocates the memory the pointer
+still has to be reset to \textbf{NULL} manually (line 35).  
+
+Now that the digits have been cleared and deallocated the other members are set to their final values (lines 36 and 37).
+
+\section{Maintenance Algorithms}
+
+The previous sections describes how to initialize and clear an mp\_int structure.  To further support operations
+that are to be performed on mp\_int structures (such as addition and multiplication) the dependent algorithms must be
+able to augment the precision of an mp\_int and 
+initialize mp\_ints with differing initial conditions.  
+
+These algorithms complete the set of low level algorithms required to work with mp\_int structures in the higher level
+algorithms such as addition, multiplication and modular exponentiation.
+
+\subsection{Augmenting an mp\_int's Precision}
+When storing a value in an mp\_int structure, a sufficient number of digits must be available to accomodate the entire 
+result of an operation without loss of precision.  Quite often the size of the array given by the \textbf{alloc} member 
+is large enough to simply increase the \textbf{used} digit count.  However, when the size of the array is too small it 
+must be re-sized appropriately to accomodate the result.  The mp\_grow algorithm will provide this functionality.
+
+\newpage\begin{figure}[here]
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{mp\_grow}. \\
+\textbf{Input}.   An mp\_int $a$ and an integer $b$. \\
+\textbf{Output}.  $a$ is expanded to accomodate $b$ digits. \\
+\hline \\
+1.  if $a.alloc \ge b$ then return(\textit{MP\_OKAY}) \\
+2.  $u \leftarrow b\mbox{ (mod }MP\_PREC\mbox{)}$ \\
+3.  $v \leftarrow b + 2 \cdot MP\_PREC - u$ \\
+4.  Re-allocate the array of digits $a$ to size $v$ \\
+5.  If the allocation failed then return(\textit{MP\_MEM}). \\
+6.  for n from a.alloc to $v - 1$ do  \\
+\hspace{+3mm}6.1  $a_n \leftarrow 0$ \\
+7.  $a.alloc \leftarrow v$ \\
+8.  Return(\textit{MP\_OKAY}) \\
+\hline
+\end{tabular}
+\end{center}
+\caption{Algorithm mp\_grow}
+\end{figure}
+
+\textbf{Algorithm mp\_grow.}
+It is ideal to prevent re-allocations from being performed if they are not required (step one).  This is useful to 
+prevent mp\_ints from growing excessively in code that erroneously calls mp\_grow.  
+
+The requested digit count is padded up to next multiple of \textbf{MP\_PREC} plus an additional \textbf{MP\_PREC} (steps two and three).  
+This helps prevent many trivial reallocations that would grow an mp\_int by trivially small values.  
+
+It is assumed that the reallocation (step four) leaves the lower $a.alloc$ digits of the mp\_int intact.  This is much 
+akin to how the \textit{realloc} function from the standard C library works.  Since the newly allocated digits are 
+assumed to contain undefined values they are initially set to zero.
+
+\vspace{+3mm}\begin{small}
+\hspace{-5.1mm}{\bf File}: bn\_mp\_grow.c
+\vspace{-3mm}
+\begin{alltt}
+\end{alltt}
+\end{small}
+
+A quick optimization is to first determine if a memory re-allocation is required at all.  The if statement (line 24) checks
+if the \textbf{alloc} member of the mp\_int is smaller than the requested digit count.  If the count is not larger than \textbf{alloc}
+the function skips the re-allocation part thus saving time.
+
+When a re-allocation is performed it is turned into an optimal request to save time in the future.  The requested digit count is
+padded upwards to 2nd multiple of \textbf{MP\_PREC} larger than \textbf{alloc} (line 25).  The XREALLOC function is used
+to re-allocate the memory.  As per the other functions XREALLOC is actually a macro which evaluates to realloc by default.  The realloc
+function leaves the base of the allocation intact which means the first \textbf{alloc} digits of the mp\_int are the same as before
+the re-allocation.  All	that is left is to clear the newly allocated digits and return.
+
+Note that the re-allocation result is actually stored in a temporary pointer $tmp$.  This is to allow this function to return
+an error with a valid pointer.  Earlier releases of the library stored the result of XREALLOC into the mp\_int $a$.  That would
+result in a memory leak if XREALLOC ever failed.  
+
+\subsection{Initializing Variable Precision mp\_ints}
+Occasionally the number of digits required will be known in advance of an initialization, based on, for example, the size 
+of input mp\_ints to a given algorithm.  The purpose of algorithm mp\_init\_size is similar to mp\_init except that it 
+will allocate \textit{at least} a specified number of digits.  
+
+\begin{figure}[here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{mp\_init\_size}. \\
+\textbf{Input}.   An mp\_int $a$ and the requested number of digits $b$. \\
+\textbf{Output}.  $a$ is initialized to hold at least $b$ digits. \\
+\hline \\
+1.  $u \leftarrow b \mbox{ (mod }MP\_PREC\mbox{)}$ \\
+2.  $v \leftarrow b + 2 \cdot MP\_PREC - u$ \\
+3.  Allocate $v$ digits. \\
+4.  for $n$ from $0$ to $v - 1$ do \\
+\hspace{3mm}4.1  $a_n \leftarrow 0$ \\
+5.  $a.sign \leftarrow MP\_ZPOS$\\
+6.  $a.used \leftarrow 0$\\
+7.  $a.alloc \leftarrow v$\\
+8.  Return(\textit{MP\_OKAY})\\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Algorithm mp\_init\_size}
+\end{figure}
+
+\textbf{Algorithm mp\_init\_size.}
+This algorithm will initialize an mp\_int structure $a$ like algorithm mp\_init with the exception that the number of 
+digits allocated can be controlled by the second input argument $b$.  The input size is padded upwards so it is a 
+multiple of \textbf{MP\_PREC} plus an additional \textbf{MP\_PREC} digits.  This padding is used to prevent trivial 
+allocations from becoming a bottleneck in the rest of the algorithms.
+
+Like algorithm mp\_init, the mp\_int structure is initialized to a default state representing the integer zero.  This 
+particular algorithm is useful if it is known ahead of time the approximate size of the input.  If the approximation is
+correct no further memory re-allocations are required to work with the mp\_int.
+
+\vspace{+3mm}\begin{small}
+\hspace{-5.1mm}{\bf File}: bn\_mp\_init\_size.c
+\vspace{-3mm}
+\begin{alltt}
+\end{alltt}
+\end{small}
+
+The number of digits $b$ requested is padded (line 24) by first augmenting it to the next multiple of 
+\textbf{MP\_PREC} and then adding \textbf{MP\_PREC} to the result.  If the memory can be successfully allocated the 
+mp\_int is placed in a default state representing the integer zero.  Otherwise, the error code \textbf{MP\_MEM} will be 
+returned (line 29).  
+
+The digits are allocated and set to zero at the same time with the calloc() function (line @25,XCALLOC@).  The 
+\textbf{used} count is set to zero, the \textbf{alloc} count set to the padded digit count and the \textbf{sign} flag set 
+to \textbf{MP\_ZPOS} to achieve a default valid mp\_int state (lines 33, 34 and 35).  If the function 
+returns succesfully then it is correct to assume that the mp\_int structure is in a valid state for the remainder of the 
+functions to work with.
+
+\subsection{Multiple Integer Initializations and Clearings}
+Occasionally a function will require a series of mp\_int data types to be made available simultaneously.  
+The purpose of algorithm mp\_init\_multi is to initialize a variable length array of mp\_int structures in a single
+statement.  It is essentially a shortcut to multiple initializations.
+
+\newpage\begin{figure}[here]
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{mp\_init\_multi}. \\
+\textbf{Input}.   Variable length array $V_k$ of mp\_int variables of length $k$. \\
+\textbf{Output}.  The array is initialized such that each mp\_int of $V_k$ is ready to use. \\
+\hline \\
+1.  for $n$ from 0 to $k - 1$ do \\
+\hspace{+3mm}1.1.  Initialize the mp\_int $V_n$ (\textit{mp\_init}) \\
+\hspace{+3mm}1.2.  If initialization failed then do \\
+\hspace{+6mm}1.2.1.  for $j$ from $0$ to $n$ do \\
+\hspace{+9mm}1.2.1.1.  Free the mp\_int $V_j$ (\textit{mp\_clear}) \\
+\hspace{+6mm}1.2.2.   Return(\textit{MP\_MEM}) \\
+2.  Return(\textit{MP\_OKAY}) \\
+\hline
+\end{tabular}
+\end{center}
+\caption{Algorithm mp\_init\_multi}
+\end{figure}
+
+\textbf{Algorithm mp\_init\_multi.}
+The algorithm will initialize the array of mp\_int variables one at a time.  If a runtime error has been detected 
+(\textit{step 1.2}) all of the previously initialized variables are cleared.  The goal is an ``all or nothing'' 
+initialization which allows for quick recovery from runtime errors.
+
+\vspace{+3mm}\begin{small}
+\hspace{-5.1mm}{\bf File}: bn\_mp\_init\_multi.c
+\vspace{-3mm}
+\begin{alltt}
+\end{alltt}
+\end{small}
+
+This function intializes a variable length list of mp\_int structure pointers.  However, instead of having the mp\_int
+structures in an actual C array they are simply passed as arguments to the function.  This function makes use of the 
+``...'' argument syntax of the C programming language.  The list is terminated with a final \textbf{NULL} argument 
+appended on the right.  
+
+The function uses the ``stdarg.h'' \textit{va} functions to step portably through the arguments to the function.  A count
+$n$ of succesfully initialized mp\_int structures is maintained (line 48) such that if a failure does occur,
+the algorithm can backtrack and free the previously initialized structures (lines 28 to 47).  
+
+
+\subsection{Clamping Excess Digits}
+When a function anticipates a result will be $n$ digits it is simpler to assume this is true within the body of 
+the function instead of checking during the computation.  For example, a multiplication of a $i$ digit number by a 
+$j$ digit produces a result of at most $i + j$ digits.  It is entirely possible that the result is $i + j - 1$ 
+though, with no final carry into the last position.  However, suppose the destination had to be first expanded 
+(\textit{via mp\_grow}) to accomodate $i + j - 1$ digits than further expanded to accomodate the final carry.  
+That would be a considerable waste of time since heap operations are relatively slow.
+
+The ideal solution is to always assume the result is $i + j$ and fix up the \textbf{used} count after the function
+terminates.  This way a single heap operation (\textit{at most}) is required.  However, if the result was not checked
+there would be an excess high order zero digit.  
+
+For example, suppose the product of two integers was $x_n = (0x_{n-1}x_{n-2}...x_0)_{\beta}$.  The leading zero digit 
+will not contribute to the precision of the result.  In fact, through subsequent operations more leading zero digits would
+accumulate to the point the size of the integer would be prohibitive.  As a result even though the precision is very 
+low the representation is excessively large.  
+
+The mp\_clamp algorithm is designed to solve this very problem.  It will trim high-order zeros by decrementing the 
+\textbf{used} count until a non-zero most significant digit is found.  Also in this system, zero is considered to be a 
+positive number which means that if the \textbf{used} count is decremented to zero, the sign must be set to 
+\textbf{MP\_ZPOS}.
+
+\begin{figure}[here]
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{mp\_clamp}. \\
+\textbf{Input}.   An mp\_int $a$ \\
+\textbf{Output}.  Any excess leading zero digits of $a$ are removed \\
+\hline \\
+1.  while $a.used > 0$ and $a_{a.used - 1} = 0$ do \\
+\hspace{+3mm}1.1  $a.used \leftarrow a.used - 1$ \\
+2.  if $a.used = 0$ then do \\
+\hspace{+3mm}2.1  $a.sign \leftarrow MP\_ZPOS$ \\
+\hline \\
+\end{tabular}
+\end{center}
+\caption{Algorithm mp\_clamp}
+\end{figure}
+
+\textbf{Algorithm mp\_clamp.}
+As can be expected this algorithm is very simple.  The loop on step one is expected to iterate only once or twice at
+the most.  For example, this will happen in cases where there is not a carry to fill the last position.  Step two fixes the sign for 
+when all of the digits are zero to ensure that the mp\_int is valid at all times.
+
+\vspace{+3mm}\begin{small}
+\hspace{-5.1mm}{\bf File}: bn\_mp\_clamp.c
+\vspace{-3mm}
+\begin{alltt}
+\end{alltt}
+\end{small}
+
+Note on line 28 how to test for the \textbf{used} count is made on the left of the \&\& operator.  In the C programming
+language the terms to \&\& are evaluated left to right with a boolean short-circuit if any condition fails.  This is 
+important since if the \textbf{used} is zero the test on the right would fetch below the array.  That is obviously 
+undesirable.  The parenthesis on line 31 is used to make sure the \textbf{used} count is decremented and not
+the pointer ``a''.  
+
+\section*{Exercises}
+\begin{tabular}{cl}
+$\left [ 1 \right ]$ & Discuss the relevance of the \textbf{used} member of the mp\_int structure. \\
+                     & \\
+$\left [ 1 \right ]$ & Discuss the consequences of not using padding when performing allocations.  \\
+                     & \\
+$\left [ 2 \right ]$ & Estimate an ideal value for \textbf{MP\_PREC} when performing 1024-bit RSA \\
+                     & encryption when $\beta = 2^{28}$.  \\
+                     & \\
+$\left [ 1 \right ]$ & Discuss the relevance of the algorithm mp\_clamp.  What does it prevent? \\
+                     & \\
+$\left [ 1 \right ]$ & Give an example of when the algorithm  mp\_init\_copy might be useful. \\
+                     & \\
+\end{tabular}
+
+
+%%%
+% CHAPTER FOUR
+%%%
+
+\chapter{Basic Operations}
+
+\section{Introduction}
+In the previous chapter a series of low level algorithms were established that dealt with initializing and maintaining
+mp\_int structures.  This chapter will discuss another set of seemingly non-algebraic algorithms which will form the low 
+level basis of the entire library.  While these algorithm are relatively trivial it is important to understand how they
+work before proceeding since these algorithms will be used almost intrinsically in the following chapters.
+
+The algorithms in this chapter deal primarily with more ``programmer'' related tasks such as creating copies of
+mp\_int structures, assigning small values to mp\_int structures and comparisons of the values mp\_int structures
+represent.   
+
+\section{Assigning Values to mp\_int Structures}
+\subsection{Copying an mp\_int}
+Assigning the value that a given mp\_int structure represents to another mp\_int structure shall be known as making
+a copy for the purposes of this text.  The copy of the mp\_int will be a separate entity that represents the same
+value as the mp\_int it was copied from.  The mp\_copy algorithm provides this functionality. 
+
+\newpage\begin{figure}[here]
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{mp\_copy}. \\
+\textbf{Input}.  An mp\_int $a$ and $b$. \\
+\textbf{Output}.  Store a copy of $a$ in $b$. \\
+\hline \\
+1.  If $b.alloc < a.used$ then grow $b$ to $a.used$ digits.  (\textit{mp\_grow}) \\
+2.  for $n$ from 0 to $a.used - 1$ do \\
+\hspace{3mm}2.1  $b_{n} \leftarrow a_{n}$ \\
+3.  for $n$ from $a.used$ to $b.used - 1$ do \\
+\hspace{3mm}3.1  $b_{n} \leftarrow 0$ \\
+4.  $b.used \leftarrow a.used$ \\
+5.  $b.sign \leftarrow a.sign$ \\
+6.  return(\textit{MP\_OKAY}) \\
+\hline
+\end{tabular}
+\end{center}
+\caption{Algorithm mp\_copy}
+\end{figure}
+
+\textbf{Algorithm mp\_copy.}
+This algorithm copies the mp\_int $a$ such that upon succesful termination of the algorithm the mp\_int $b$ will
+represent the same integer as the mp\_int $a$.  The mp\_int $b$ shall be a complete and distinct copy of the 
+mp\_int $a$ meaing that the mp\_int $a$ can be modified and it shall not affect the value of the mp\_int $b$.
+
+If $b$ does not have enough room for the digits of $a$ it must first have its precision augmented via the mp\_grow 
+algorithm.  The digits of $a$ are copied over the digits of $b$ and any excess digits of $b$ are set to zero (step two
+and three).  The \textbf{used} and \textbf{sign} members of $a$ are finally copied over the respective members of
+$b$.
+
+\textbf{Remark.}  This algorithm also introduces a new idiosyncrasy that will be used throughout the rest of the
+text.  The error return codes of other algorithms are not explicitly checked in the pseudo-code presented.  For example, in 
+step one of the mp\_copy algorithm the return of mp\_grow is not explicitly checked to ensure it succeeded.  Text space is 
+limited so it is assumed that if a algorithm fails it will clear all temporarily allocated mp\_ints and return
+the error code itself.  However, the C code presented will demonstrate all of the error handling logic required to 
+implement the pseudo-code.
+
+\vspace{+3mm}\begin{small}
+\hspace{-5.1mm}{\bf File}: bn\_mp\_copy.c
+\vspace{-3mm}
+\begin{alltt}
+\end{alltt}
+\end{small}
+
+Occasionally a dependent algorithm may copy an mp\_int effectively into itself such as when the input and output
+mp\_int structures passed to a function are one and the same.  For this case it is optimal to return immediately without 
+copying digits (line 25).  
+
+The mp\_int $b$ must have enough digits to accomodate the used digits of the mp\_int $a$.  If $b.alloc$ is less than
+$a.used$ the algorithm mp\_grow is used to augment the precision of $b$ (lines 30 to 33).  In order to
+simplify the inner loop that copies the digits from $a$ to $b$, two aliases $tmpa$ and $tmpb$ point directly at the digits
+of the mp\_ints $a$ and $b$ respectively.  These aliases (lines 43 and 46) allow the compiler to access the digits without first dereferencing the
+mp\_int pointers and then subsequently the pointer to the digits.  
+
+After the aliases are established the digits from $a$ are copied into $b$ (lines 49 to 51) and then the excess 
+digits of $b$ are set to zero (lines 54 to 56).  Both ``for'' loops make use of the pointer aliases and in 
+fact the alias for $b$ is carried through into the second ``for'' loop to clear the excess digits.  This optimization 
+allows the alias to stay in a machine register fairly easy between the two loops.
+
+\textbf{Remarks.}  The use of pointer aliases is an implementation methodology first introduced in this function that will
+be used considerably in other functions.  Technically, a pointer alias is simply a short hand alias used to lower the 
+number of pointer dereferencing operations required to access data.  For example, a for loop may resemble
+
+\begin{alltt}
+for (x = 0; x < 100; x++) \{
+    a->num[4]->dp[x] = 0;
+\}
+\end{alltt}
+
+This could be re-written using aliases as 
+
+\begin{alltt}
+mp_digit *tmpa;
+a = a->num[4]->dp;
+for (x = 0; x < 100; x++) \{
+    *a++ = 0;
+\}
+\end{alltt}
+
+In this case an alias is used to access the 
+array of digits within an mp\_int structure directly.  It may seem that a pointer alias is strictly not required 
+as a compiler may optimize out the redundant pointer operations.  However, there are two dominant reasons to use aliases.
+
+The first reason is that most compilers will not effectively optimize pointer arithmetic.  For example, some optimizations 
+may work for the Microsoft Visual C++ compiler (MSVC) and not for the GNU C Compiler (GCC).  Also some optimizations may 
+work for GCC and not MSVC.  As such it is ideal to find a common ground for as many compilers as possible.  Pointer 
+aliases optimize the code considerably before the compiler even reads the source code which means the end compiled code 
+stands a better chance of being faster.
+
+The second reason is that pointer aliases often can make an algorithm simpler to read.  Consider the first ``for'' 
+loop of the function mp\_copy() re-written to not use pointer aliases.
+
+\begin{alltt}
+    /* copy all the digits */
+    for (n = 0; n < a->used; n++) \{
+      b->dp[n] = a->dp[n];
+    \}
+\end{alltt}
+
+Whether this code is harder to read depends strongly on the individual.  However, it is quantifiably slightly more 
+complicated as there are four variables within the statement instead of just two.
+
+\subsubsection{Nested Statements}
+Another commonly used technique in the source routines is that certain sections of code are nested.  This is used in
+particular with the pointer aliases to highlight code phases.  For example, a Comba multiplier (discussed in chapter six)
+will typically have three different phases.  First the temporaries are initialized, then the columns calculated and 
+finally the carries are propagated.  In this example the middle column production phase will typically be nested as it
+uses temporary variables and aliases the most.
+
+The nesting also simplies the source code as variables that are nested are only valid for their scope.  As a result
+the various temporary variables required do not propagate into other sections of code.
+
+
+\subsection{Creating a Clone}
+Another common operation is to make a local temporary copy of an mp\_int argument.  To initialize an mp\_int 
+and then copy another existing mp\_int into the newly intialized mp\_int will be known as creating a clone.  This is 
+useful within functions that need to modify an argument but do not wish to actually modify the original copy.  The 
+mp\_init\_copy algorithm has been designed to help perform this task.
+
+\begin{figure}[here]
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{mp\_init\_copy}. \\
+\textbf{Input}.   An mp\_int $a$ and $b$\\
+\textbf{Output}.  $a$ is initialized to be a copy of $b$. \\
+\hline \\
+1.  Init $a$.  (\textit{mp\_init}) \\
+2.  Copy $b$ to $a$.  (\textit{mp\_copy}) \\
+3.  Return the status of the copy operation. \\
+\hline
+\end{tabular}
+\end{center}
+\caption{Algorithm mp\_init\_copy}
+\end{figure}
+
+\textbf{Algorithm mp\_init\_copy.}
+This algorithm will initialize an mp\_int variable and copy another previously initialized mp\_int variable into it.  As 
+such this algorithm will perform two operations in one step.  
+
+\vspace{+3mm}\begin{small}
+\hspace{-5.1mm}{\bf File}: bn\_mp\_init\_copy.c
+\vspace{-3mm}
+\begin{alltt}
+\end{alltt}
+\end{small}
+
+This will initialize \textbf{a} and make it a verbatim copy of the contents of \textbf{b}.  Note that 
+\textbf{a} will have its own memory allocated which means that \textbf{b} may be cleared after the call
+and \textbf{a} will be left intact.  
+
+\section{Zeroing an Integer}
+Reseting an mp\_int to the default state is a common step in many algorithms.  The mp\_zero algorithm will be the algorithm used to
+perform this task.
+
+\begin{figure}[here]
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{mp\_zero}. \\
+\textbf{Input}.   An mp\_int $a$ \\
+\textbf{Output}.  Zero the contents of $a$ \\
+\hline \\
+1.  $a.used \leftarrow 0$ \\
+2.  $a.sign \leftarrow$ MP\_ZPOS \\
+3.  for $n$ from 0 to $a.alloc - 1$ do \\
+\hspace{3mm}3.1  $a_n \leftarrow 0$ \\
+\hline
+\end{tabular}
+\end{center}
+\caption{Algorithm mp\_zero}
+\end{figure}
+
+\textbf{Algorithm mp\_zero.}
+This algorithm simply resets a mp\_int to the default state.  
+
+\vspace{+3mm}\begin{small}
+\hspace{-5.1mm}{\bf File}: bn\_mp\_zero.c
+\vspace{-3mm}
+\begin{alltt}
+\end{alltt}
+\end{small}
+
+After the function is completed, all of the digits are zeroed, the \textbf{used} count is zeroed and the 
+\textbf{sign} variable is set to \textbf{MP\_ZPOS}.
+
+\section{Sign Manipulation}
+\subsection{Absolute Value}
+With the mp\_int representation of an integer, calculating the absolute value is trivial.  The mp\_abs algorithm will compute
+the absolute value of an mp\_int.
+
+\begin{figure}[here]
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{mp\_abs}. \\
+\textbf{Input}.   An mp\_int $a$ \\
+\textbf{Output}.  Computes $b = \vert a \vert$ \\
+\hline \\
+1.  Copy $a$ to $b$.  (\textit{mp\_copy}) \\
+2.  If the copy failed return(\textit{MP\_MEM}). \\
+3.  $b.sign \leftarrow MP\_ZPOS$ \\
+4.  Return(\textit{MP\_OKAY}) \\
+\hline
+\end{tabular}
+\end{center}
+\caption{Algorithm mp\_abs}
+\end{figure}
+
+\textbf{Algorithm mp\_abs.}
+This algorithm computes the absolute of an mp\_int input.  First it copies $a$ over $b$.  This is an example of an
+algorithm where the check in mp\_copy that determines if the source and destination are equal proves useful.  This allows,
+for instance, the developer to pass the same mp\_int as the source and destination to this function without addition 
+logic to handle it.
+
+\vspace{+3mm}\begin{small}
+\hspace{-5.1mm}{\bf File}: bn\_mp\_abs.c
+\vspace{-3mm}
+\begin{alltt}
+\end{alltt}
+\end{small}
+
+This fairly trivial algorithm first eliminates non--required duplications (line 28) and then sets the
+\textbf{sign} flag to \textbf{MP\_ZPOS}.
+
+\subsection{Integer Negation}
+With the mp\_int representation of an integer, calculating the negation is also trivial.  The mp\_neg algorithm will compute
+the negative of an mp\_int input.
+
+\begin{figure}[here]
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{mp\_neg}. \\
+\textbf{Input}.   An mp\_int $a$ \\
+\textbf{Output}.  Computes $b = -a$ \\
+\hline \\
+1.  Copy $a$ to $b$.  (\textit{mp\_copy}) \\
+2.  If the copy failed return(\textit{MP\_MEM}). \\
+3.  If $a.used = 0$ then return(\textit{MP\_OKAY}). \\
+4.  If $a.sign = MP\_ZPOS$ then do \\
+\hspace{3mm}4.1  $b.sign = MP\_NEG$. \\
+5.  else do \\
+\hspace{3mm}5.1  $b.sign = MP\_ZPOS$. \\
+6.  Return(\textit{MP\_OKAY}) \\
+\hline
+\end{tabular}
+\end{center}
+\caption{Algorithm mp\_neg}
+\end{figure}
+
+\textbf{Algorithm mp\_neg.}
+This algorithm computes the negation of an input.  First it copies $a$ over $b$.  If $a$ has no used digits then
+the algorithm returns immediately.  Otherwise it flips the sign flag and stores the result in $b$.  Note that if 
+$a$ had no digits then it must be positive by definition.  Had step three been omitted then the algorithm would return
+zero as negative.
+
+\vspace{+3mm}\begin{small}
+\hspace{-5.1mm}{\bf File}: bn\_mp\_neg.c
+\vspace{-3mm}
+\begin{alltt}
+\end{alltt}
+\end{small}
+
+Like mp\_abs() this function avoids non--required duplications (line 22) and then sets the sign.  We
+have to make sure that only non--zero values get a \textbf{sign} of \textbf{MP\_NEG}.  If the mp\_int is zero
+than the \textbf{sign} is hard--coded to \textbf{MP\_ZPOS}.
+
+\section{Small Constants}
+\subsection{Setting Small Constants}
+Often a mp\_int must be set to a relatively small value such as $1$ or $2$.  For these cases the mp\_set algorithm is useful.
+
+\newpage\begin{figure}[here]
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{mp\_set}. \\
+\textbf{Input}.   An mp\_int $a$ and a digit $b$ \\
+\textbf{Output}.  Make $a$ equivalent to $b$ \\
+\hline \\
+1.  Zero $a$ (\textit{mp\_zero}). \\
+2.  $a_0 \leftarrow b \mbox{ (mod }\beta\mbox{)}$ \\
+3.  $a.used \leftarrow  \left \lbrace \begin{array}{ll}
+                              1 &  \mbox{if }a_0 > 0 \\
+                              0 &  \mbox{if }a_0 = 0 
+                              \end{array} \right .$ \\
+\hline                              
+\end{tabular}
+\end{center}
+\caption{Algorithm mp\_set}
+\end{figure}
+
+\textbf{Algorithm mp\_set.}
+This algorithm sets a mp\_int to a small single digit value.  Step number 1 ensures that the integer is reset to the default state.  The
+single digit is set (\textit{modulo $\beta$}) and the \textbf{used} count is adjusted accordingly.
+
+\vspace{+3mm}\begin{small}
+\hspace{-5.1mm}{\bf File}: bn\_mp\_set.c
+\vspace{-3mm}
+\begin{alltt}
+\end{alltt}
+\end{small}
+
+First we zero (line 21) the mp\_int to make sure that the other members are initialized for a 
+small positive constant.  mp\_zero() ensures that the \textbf{sign} is positive and the \textbf{used} count
+is zero.  Next we set the digit and reduce it modulo $\beta$ (line 22).  After this step we have to 
+check if the resulting digit is zero or not.  If it is not then we set the \textbf{used} count to one, otherwise
+to zero.
+
+We can quickly reduce modulo $\beta$ since it is of the form $2^k$ and a quick binary AND operation with 
+$2^k - 1$ will perform the same operation.
+
+One important limitation of this function is that it will only set one digit.  The size of a digit is not fixed, meaning source that uses 
+this function should take that into account.  Only trivially small constants can be set using this function.
+
+\subsection{Setting Large Constants}
+To overcome the limitations of the mp\_set algorithm the mp\_set\_int algorithm is ideal.  It accepts a ``long''
+data type as input and will always treat it as a 32-bit integer.
+
+\begin{figure}[here]
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{mp\_set\_int}. \\
+\textbf{Input}.   An mp\_int $a$ and a ``long'' integer $b$ \\
+\textbf{Output}.  Make $a$ equivalent to $b$ \\
+\hline \\
+1.  Zero $a$ (\textit{mp\_zero}) \\
+2.  for $n$ from 0 to 7 do \\
+\hspace{3mm}2.1  $a \leftarrow a \cdot 16$ (\textit{mp\_mul2d}) \\
+\hspace{3mm}2.2  $u \leftarrow \lfloor b / 2^{4(7 - n)} \rfloor \mbox{ (mod }16\mbox{)}$\\
+\hspace{3mm}2.3  $a_0 \leftarrow a_0 + u$ \\
+\hspace{3mm}2.4  $a.used \leftarrow a.used + 1$ \\
+3.  Clamp excess used digits (\textit{mp\_clamp}) \\
+\hline
+\end{tabular}
+\end{center}
+\caption{Algorithm mp\_set\_int}
+\end{figure}
+
+\textbf{Algorithm mp\_set\_int.}
+The algorithm performs eight iterations of a simple loop where in each iteration four bits from the source are added to the 
+mp\_int.  Step 2.1 will multiply the current result by sixteen making room for four more bits in the less significant positions.  In step 2.2 the
+next four bits from the source are extracted and are added to the mp\_int. The \textbf{used} digit count is 
+incremented to reflect the addition.  The \textbf{used} digit counter is incremented since if any of the leading digits were zero the mp\_int would have
+zero digits used and the newly added four bits would be ignored.
+
+Excess zero digits are trimmed in steps 2.1 and 3 by using higher level algorithms mp\_mul2d and mp\_clamp.
+
+\vspace{+3mm}\begin{small}
+\hspace{-5.1mm}{\bf File}: bn\_mp\_set\_int.c
+\vspace{-3mm}
+\begin{alltt}
+\end{alltt}
+\end{small}
+
+This function sets four bits of the number at a time to handle all practical \textbf{DIGIT\_BIT} sizes.  The weird
+addition on line 39 ensures that the newly added in bits are added to the number of digits.  While it may not 
+seem obvious as to why the digit counter does not grow exceedingly large it is because of the shift on line 28 
+as well as the  call to mp\_clamp() on line 41.  Both functions will clamp excess leading digits which keeps 
+the number of used digits low.
+
+\section{Comparisons}
+\subsection{Unsigned Comparisions}
+Comparing a multiple precision integer is performed with the exact same algorithm used to compare two decimal numbers.  For example,
+to compare $1,234$ to $1,264$ the digits are extracted by their positions.  That is we compare $1 \cdot 10^3 + 2 \cdot 10^2 + 3 \cdot 10^1 + 4 \cdot 10^0$
+to $1 \cdot 10^3 + 2 \cdot 10^2 + 6 \cdot 10^1 + 4 \cdot 10^0$ by comparing single digits at a time starting with the highest magnitude 
+positions.  If any leading digit of one integer is greater than a digit in the same position of another integer then obviously it must be greater.  
+
+The first comparision routine that will be developed is the unsigned magnitude compare which will perform a comparison based on the digits of two
+mp\_int variables alone.  It will ignore the sign of the two inputs.  Such a function is useful when an absolute comparison is required or if the 
+signs are known to agree in advance.
+
+To facilitate working with the results of the comparison functions three constants are required.  
+
+\begin{figure}[here]
+\begin{center}
+\begin{tabular}{|r|l|}
+\hline \textbf{Constant} & \textbf{Meaning} \\
+\hline \textbf{MP\_GT} & Greater Than \\
+\hline \textbf{MP\_EQ} & Equal To \\
+\hline \textbf{MP\_LT} & Less Than \\
+\hline
+\end{tabular}
+\end{center}
+\caption{Comparison Return Codes}
+\end{figure}
+
+\begin{figure}[here]
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{mp\_cmp\_mag}. \\
+\textbf{Input}.   Two mp\_ints $a$ and $b$.  \\
+\textbf{Output}.  Unsigned comparison results ($a$ to the left of $b$). \\
+\hline \\
+1.  If $a.used > b.used$ then return(\textit{MP\_GT}) \\
+2.  If $a.used < b.used$ then return(\textit{MP\_LT}) \\
+3.  for n from $a.used - 1$ to 0 do \\
+\hspace{+3mm}3.1  if $a_n > b_n$ then return(\textit{MP\_GT}) \\
+\hspace{+3mm}3.2  if $a_n < b_n$ then return(\textit{MP\_LT}) \\
+4.  Return(\textit{MP\_EQ}) \\
+\hline
+\end{tabular}
+\end{center}
+\caption{Algorithm mp\_cmp\_mag}
+\end{figure}
+
+\textbf{Algorithm mp\_cmp\_mag.}
+By saying ``$a$ to the left of $b$'' it is meant that the comparison is with respect to $a$, that is if $a$ is greater than $b$ it will return
+\textbf{MP\_GT} and similar with respect to when $a = b$ and $a < b$.  The first two steps compare the number of digits used in both $a$ and $b$.  
+Obviously if the digit counts differ there would be an imaginary zero digit in the smaller number where the leading digit of the larger number is.  
+If both have the same number of digits than the actual digits themselves must be compared starting at the leading digit.  
+
+By step three both inputs must have the same number of digits so its safe to start from either $a.used - 1$ or $b.used - 1$ and count down to
+the zero'th digit.  If after all of the digits have been compared, no difference is found, the algorithm returns \textbf{MP\_EQ}.
+
+\vspace{+3mm}\begin{small}
+\hspace{-5.1mm}{\bf File}: bn\_mp\_cmp\_mag.c
+\vspace{-3mm}
+\begin{alltt}
+\end{alltt}
+\end{small}
+
+The two if statements (lines 25 and 29) compare the number of digits in the two inputs.  These two are 
+performed before all of the digits are compared since it is a very cheap test to perform and can potentially save 
+considerable time.  The implementation given is also not valid without those two statements.  $b.alloc$ may be 
+smaller than $a.used$, meaning that undefined values will be read from $b$ past the end of the array of digits.
+
+
+
+\subsection{Signed Comparisons}
+Comparing with sign considerations is also fairly critical in several routines (\textit{division for example}).  Based on an unsigned magnitude 
+comparison a trivial signed comparison algorithm can be written.
+
+\begin{figure}[here]
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{mp\_cmp}. \\
+\textbf{Input}.   Two mp\_ints $a$ and $b$ \\
+\textbf{Output}.  Signed Comparison Results ($a$ to the left of $b$) \\
+\hline \\
+1.  if $a.sign = MP\_NEG$ and $b.sign = MP\_ZPOS$ then return(\textit{MP\_LT}) \\
+2.  if $a.sign = MP\_ZPOS$ and $b.sign = MP\_NEG$ then return(\textit{MP\_GT}) \\
+3.  if $a.sign = MP\_NEG$ then \\
+\hspace{+3mm}3.1  Return the unsigned comparison of $b$ and $a$ (\textit{mp\_cmp\_mag}) \\
+4   Otherwise \\
+\hspace{+3mm}4.1  Return the unsigned comparison of $a$ and $b$ \\
+\hline
+\end{tabular}
+\end{center}
+\caption{Algorithm mp\_cmp}
+\end{figure}
+
+\textbf{Algorithm mp\_cmp.}
+The first two steps compare the signs of the two inputs.  If the signs do not agree then it can return right away with the appropriate 
+comparison code.  When the signs are equal the digits of the inputs must be compared to determine the correct result.  In step 
+three the unsigned comparision flips the order of the arguments since they are both negative.  For instance, if $-a > -b$ then 
+$\vert a \vert < \vert b \vert$.  Step number four will compare the two when they are both positive.
+
+\vspace{+3mm}\begin{small}
+\hspace{-5.1mm}{\bf File}: bn\_mp\_cmp.c
+\vspace{-3mm}
+\begin{alltt}
+\end{alltt}
+\end{small}
+
+The two if statements (lines 23 and 24) perform the initial sign comparison.  If the signs are not the equal then which ever
+has the positive sign is larger.   The inputs are compared (line 32) based on magnitudes.  If the signs were both 
+negative then the unsigned comparison is performed in the opposite direction (line 34).  Otherwise, the signs are assumed to 
+be both positive and a forward direction unsigned comparison is performed.
+
+\section*{Exercises}
+\begin{tabular}{cl}
+$\left [ 2 \right ]$ & Modify algorithm mp\_set\_int to accept as input a variable length array of bits. \\
+                     & \\
+$\left [ 3 \right ]$ & Give the probability that algorithm mp\_cmp\_mag will have to compare $k$ digits  \\
+                     & of two random digits (of equal magnitude) before a difference is found. \\
+                     & \\
+$\left [ 1 \right ]$ & Suggest a simple method to speed up the implementation of mp\_cmp\_mag based  \\
+                     & on the observations made in the previous problem. \\
+                     &
+\end{tabular}
+
+\chapter{Basic Arithmetic}
+\section{Introduction}
+At this point algorithms for initialization, clearing, zeroing, copying, comparing and setting small constants have been 
+established.  The next logical set of algorithms to develop are addition, subtraction and digit shifting algorithms.  These 
+algorithms make use of the lower level algorithms and are the cruicial building block for the multiplication algorithms.  It is very important 
+that these algorithms are highly optimized.  On their own they are simple $O(n)$ algorithms but they can be called from higher level algorithms 
+which easily places them at $O(n^2)$ or even $O(n^3)$ work levels.  
+
+All of the algorithms within this chapter make use of the logical bit shift operations denoted by $<<$ and $>>$ for left and right 
+logical shifts respectively.  A logical shift is analogous to sliding the decimal point of radix-10 representations.  For example, the real 
+number $0.9345$ is equivalent to $93.45\%$ which is found by sliding the the decimal two places to the right (\textit{multiplying by $\beta^2 = 10^2$}).  
+Algebraically a binary logical shift is equivalent to a division or multiplication by a power of two.  
+For example, $a << k = a \cdot 2^k$ while $a >> k = \lfloor a/2^k \rfloor$.
+
+One significant difference between a logical shift and the way decimals are shifted is that digits below the zero'th position are removed
+from the number.  For example, consider $1101_2 >> 1$ using decimal notation this would produce $110.1_2$.  However, with a logical shift the 
+result is $110_2$.  
+
+\section{Addition and Subtraction}
+In common twos complement fixed precision arithmetic negative numbers are easily represented by subtraction from the modulus.  For example, with 32-bit integers
+$a - b\mbox{ (mod }2^{32}\mbox{)}$ is the same as $a + (2^{32} - b) \mbox{ (mod }2^{32}\mbox{)}$  since $2^{32} \equiv 0 \mbox{ (mod }2^{32}\mbox{)}$.  
+As a result subtraction can be performed with a trivial series of logical operations and an addition.
+
+However, in multiple precision arithmetic negative numbers are not represented in the same way.  Instead a sign flag is used to keep track of the
+sign of the integer.  As a result signed addition and subtraction are actually implemented as conditional usage of lower level addition or 
+subtraction algorithms with the sign fixed up appropriately.
+
+The lower level algorithms will add or subtract integers without regard to the sign flag.  That is they will add or subtract the magnitude of
+the integers respectively.
+
+\subsection{Low Level Addition}
+An unsigned addition of multiple precision integers is performed with the same long-hand algorithm used to add decimal numbers.  That is to add the 
+trailing digits first and propagate the resulting carry upwards.  Since this is a lower level algorithm the name will have a ``s\_'' prefix.  
+Historically that convention stems from the MPI library where ``s\_'' stood for static functions that were hidden from the developer entirely.
+
+\newpage
+\begin{figure}[!here]
+\begin{center}
+\begin{small}
+\begin{tabular}{l}
+\hline Algorithm \textbf{s\_mp\_add}. \\
+\textbf{Input}.   Two mp\_ints $a$ and $b$ \\
+\textbf{Output}.  The unsigned addition $c = \vert a \vert + \vert b \vert$. \\
+\hline \\
+1.  if $a.used > b.used$ then \\
+\hspace{+3mm}1.1  $min \leftarrow b.used$ \\
+\hspace{+3mm}1.2  $max \leftarrow a.used$ \\
+\hspace{+3mm}1.3  $x   \leftarrow a$ \\
+2.  else  \\
+\hspace{+3mm}2.1  $min \leftarrow a.used$ \\
+\hspace{+3mm}2.2  $max \leftarrow b.used$ \\
+\hspace{+3mm}2.3  $x   \leftarrow b$ \\
+3.  If $c.alloc < max + 1$ then grow $c$ to hold at least $max + 1$ digits (\textit{mp\_grow}) \\
+4.  $oldused \leftarrow c.used$ \\
+5.  $c.used \leftarrow max + 1$ \\
+6.  $u \leftarrow 0$ \\
+7.  for $n$ from $0$ to $min - 1$ do \\
+\hspace{+3mm}7.1  $c_n \leftarrow a_n + b_n + u$ \\
+\hspace{+3mm}7.2  $u \leftarrow c_n >> lg(\beta)$ \\
+\hspace{+3mm}7.3  $c_n \leftarrow c_n \mbox{ (mod }\beta\mbox{)}$ \\
+8.  if $min \ne max$ then do \\
+\hspace{+3mm}8.1  for $n$ from $min$ to $max - 1$ do \\
+\hspace{+6mm}8.1.1  $c_n \leftarrow x_n + u$ \\
+\hspace{+6mm}8.1.2  $u \leftarrow c_n >> lg(\beta)$ \\
+\hspace{+6mm}8.1.3  $c_n \leftarrow c_n \mbox{ (mod }\beta\mbox{)}$ \\
+9.  $c_{max} \leftarrow u$ \\
+10.  if $olduse > max$ then \\
+\hspace{+3mm}10.1  for $n$ from $max + 1$ to $oldused - 1$ do \\
+\hspace{+6mm}10.1.1  $c_n \leftarrow 0$ \\
+11.  Clamp excess digits in $c$.  (\textit{mp\_clamp}) \\
+12.  Return(\textit{MP\_OKAY}) \\
+\hline
+\end{tabular}
+\end{small}
+\end{center}
+\caption{Algorithm s\_mp\_add}
+\end{figure}
+
+\textbf{Algorithm s\_mp\_add.}
+This algorithm is loosely based on algorithm 14.7 of HAC \cite[pp. 594]{HAC} but has been extended to allow the inputs to have different magnitudes.  
+Coincidentally the description of algorithm A in Knuth \cite[pp. 266]{TAOCPV2} shares the same deficiency as the algorithm from \cite{HAC}.  Even the 
+MIX pseudo  machine code presented by Knuth \cite[pp. 266-267]{TAOCPV2} is incapable of handling inputs which are of different magnitudes.
+
+The first thing that has to be accomplished is to sort out which of the two inputs is the largest.  The addition logic
+will simply add all of the smallest input to the largest input and store that first part of the result in the
+destination.  Then it will apply a simpler addition loop to excess digits of the larger input.
+
+The first two steps will handle sorting the inputs such that $min$ and $max$ hold the digit counts of the two 
+inputs.  The variable $x$ will be an mp\_int alias for the largest input or the second input $b$ if they have the
+same number of digits.  After the inputs are sorted the destination $c$ is grown as required to accomodate the sum 
+of the two inputs.  The original \textbf{used} count of $c$ is copied and set to the new used count.  
+
+At this point the first addition loop will go through as many digit positions that both inputs have.  The carry
+variable $\mu$ is set to zero outside the loop.  Inside the loop an ``addition'' step requires three statements to produce
+one digit of the summand.  First
+two digits from $a$ and $b$ are added together along with the carry $\mu$.  The carry of this step is extracted and stored
+in $\mu$ and finally the digit of the result $c_n$ is truncated within the range $0 \le c_n < \beta$.
+
+Now all of the digit positions that both inputs have in common have been exhausted.  If $min \ne max$ then $x$ is an alias
+for one of the inputs that has more digits.  A simplified addition loop is then used to essentially copy the remaining digits
+and the carry to the destination.
+
+The final carry is stored in $c_{max}$ and digits above $max$ upto $oldused$ are zeroed which completes the addition.
+
+
+\vspace{+3mm}\begin{small}
+\hspace{-5.1mm}{\bf File}: bn\_s\_mp\_add.c
+\vspace{-3mm}
+\begin{alltt}
+\end{alltt}
+\end{small}
+
+We first sort (lines 28 to 36) the inputs based on magnitude and determine the $min$ and $max$ variables.
+Note that $x$ is a pointer to an mp\_int assigned to the largest input, in effect it is a local alias.  Next we
+grow the destination (38 to 42) ensure that it can accomodate the result of the addition. 
+
+Similar to the implementation of mp\_copy this function uses the braced code and local aliases coding style.  The three aliases that are on 
+lines 56, 59 and 62 represent the two inputs and destination variables respectively.  These aliases are used to ensure the
+compiler does not have to dereference $a$, $b$ or $c$ (respectively) to access the digits of the respective mp\_int.
+
+The initial carry $u$ will be cleared (line 65), note that $u$ is of type mp\_digit which ensures type 
+compatibility within the implementation.  The initial addition (line 66 to 75) adds digits from
+both inputs until the smallest input runs out of digits.  Similarly the conditional addition loop
+(line 81 to 90) adds the remaining digits from the larger of the two inputs.  The addition is finished 
+with the final carry being stored in $tmpc$ (line 94).  Note the ``++'' operator within the same expression.
+After line 94, $tmpc$ will point to the $c.used$'th digit of the mp\_int $c$.  This is useful
+for the next loop (line 97 to 99) which set any old upper digits to zero.
+
+\subsection{Low Level Subtraction}
+The low level unsigned subtraction algorithm is very similar to the low level unsigned addition algorithm.  The principle difference is that the
+unsigned subtraction algorithm requires the result to be positive.  That is when computing $a - b$ the condition $\vert a \vert \ge \vert b\vert$ must 
+be met for this algorithm to function properly.  Keep in mind this low level algorithm is not meant to be used in higher level algorithms directly.  
+This algorithm as will be shown can be used to create functional signed addition and subtraction algorithms.
+
+
+For this algorithm a new variable is required to make the description simpler.  Recall from section 1.3.1 that a mp\_digit must be able to represent
+the range $0 \le x < 2\beta$ for the algorithms to work correctly.  However, it is allowable that a mp\_digit represent a larger range of values.  For 
+this algorithm we will assume that the variable $\gamma$ represents the number of bits available in a 
+mp\_digit (\textit{this implies $2^{\gamma} > \beta$}).  
+
+For example, the default for LibTomMath is to use a ``unsigned long'' for the mp\_digit ``type'' while $\beta = 2^{28}$.  In ISO C an ``unsigned long''
+data type must be able to represent $0 \le x < 2^{32}$ meaning that in this case $\gamma \ge 32$.
+
+\newpage\begin{figure}[!here]
+\begin{center}
+\begin{small}
+\begin{tabular}{l}
+\hline Algorithm \textbf{s\_mp\_sub}. \\
+\textbf{Input}.   Two mp\_ints $a$ and $b$ ($\vert a \vert \ge \vert b \vert$) \\
+\textbf{Output}.  The unsigned subtraction $c = \vert a \vert - \vert b \vert$. \\
+\hline \\
+1.  $min \leftarrow b.used$ \\
+2.  $max \leftarrow a.used$ \\
+3.  If $c.alloc < max$ then grow $c$ to hold at least $max$ digits.  (\textit{mp\_grow}) \\
+4.  $oldused \leftarrow c.used$ \\ 
+5.  $c.used \leftarrow max$ \\
+6.  $u \leftarrow 0$ \\
+7.  for $n$ from $0$ to $min - 1$ do \\
+\hspace{3mm}7.1  $c_n \leftarrow a_n - b_n - u$ \\
+\hspace{3mm}7.2  $u   \leftarrow c_n >> (\gamma - 1)$ \\
+\hspace{3mm}7.3  $c_n \leftarrow c_n \mbox{ (mod }\beta\mbox{)}$ \\
+8.  if $min < max$ then do \\
+\hspace{3mm}8.1  for $n$ from $min$ to $max - 1$ do \\
+\hspace{6mm}8.1.1  $c_n \leftarrow a_n - u$ \\
+\hspace{6mm}8.1.2  $u   \leftarrow c_n >> (\gamma - 1)$ \\
+\hspace{6mm}8.1.3  $c_n \leftarrow c_n \mbox{ (mod }\beta\mbox{)}$ \\
+9. if $oldused > max$ then do \\
+\hspace{3mm}9.1  for $n$ from $max$ to $oldused - 1$ do \\
+\hspace{6mm}9.1.1  $c_n \leftarrow 0$ \\
+10. Clamp excess digits of $c$.  (\textit{mp\_clamp}). \\
+11. Return(\textit{MP\_OKAY}). \\
+\hline
+\end{tabular}
+\end{small}
+\end{center}
+\caption{Algorithm s\_mp\_sub}
+\end{figure}
+
+\textbf{Algorithm s\_mp\_sub.}
+This algorithm performs the unsigned subtraction of two mp\_int variables under the restriction that the result must be positive.  That is when
+passing variables $a$ and $b$ the condition that $\vert a \vert \ge \vert b \vert$ must be met for the algorithm to function correctly.  This
+algorithm is loosely based on algorithm 14.9 \cite[pp. 595]{HAC} and is similar to algorithm S in \cite[pp. 267]{TAOCPV2} as well.  As was the case
+of the algorithm s\_mp\_add both other references lack discussion concerning various practical details such as when the inputs differ in magnitude.
+
+The initial sorting of the inputs is trivial in this algorithm since $a$ is guaranteed to have at least the same magnitude of $b$.  Steps 1 and 2 
+set the $min$ and $max$ variables.  Unlike the addition routine there is guaranteed to be no carry which means that the final result can be at 
+most $max$ digits in length as opposed to $max + 1$.  Similar to the addition algorithm the \textbf{used} count of $c$ is copied locally and 
+set to the maximal count for the operation.
+
+The subtraction loop that begins on step seven is essentially the same as the addition loop of algorithm s\_mp\_add except single precision 
+subtraction is used instead.  Note the use of the $\gamma$ variable to extract the carry (\textit{also known as the borrow}) within the subtraction 
+loops.  Under the assumption that two's complement single precision arithmetic is used this will successfully extract the desired carry.  
+
+For example, consider subtracting $0101_2$ from $0100_2$ where $\gamma = 4$ and $\beta = 2$.  The least significant bit will force a carry upwards to 
+the third bit which will be set to zero after the borrow.  After the very first bit has been subtracted $4 - 1 \equiv 0011_2$ will remain,  When the 
+third bit of $0101_2$ is subtracted from the result it will cause another carry.  In this case though the carry will be forced to propagate all the 
+way to the most significant bit.  
+
+Recall that $\beta < 2^{\gamma}$.  This means that if a carry does occur just before the $lg(\beta)$'th bit it will propagate all the way to the most 
+significant bit.  Thus, the high order bits of the mp\_digit that are not part of the actual digit will either be all zero, or all one. All that
+is needed is a single zero or one bit for the carry.  Therefore a single logical shift right by $\gamma - 1$ positions is sufficient to extract the 
+carry.  This method of carry extraction may seem awkward but the reason for it becomes apparent when the implementation is discussed.  
+
+If $b$ has a smaller magnitude than $a$ then step 9 will force the carry and copy operation to propagate through the larger input $a$ into $c$.  Step
+10 will ensure that any leading digits of $c$ above the $max$'th position are zeroed.
+
+\vspace{+3mm}\begin{small}
+\hspace{-5.1mm}{\bf File}: bn\_s\_mp\_sub.c
+\vspace{-3mm}
+\begin{alltt}
+\end{alltt}
+\end{small}
+
+Like low level addition we ``sort'' the inputs.  Except in this case the sorting is hardcoded 
+(lines 25 and 26).  In reality the $min$ and $max$ variables are only aliases and are only 
+used to make the source code easier to read.  Again the pointer alias optimization is used 
+within this algorithm.  The aliases $tmpa$, $tmpb$ and $tmpc$ are initialized
+(lines 42, 43 and 44) for $a$, $b$ and $c$ respectively.
+
+The first subtraction loop (lines 47 through 61) subtract digits from both inputs until the smaller of
+the two inputs has been exhausted.  As remarked earlier there is an implementation reason for using the ``awkward'' 
+method of extracting the carry (line 57).  The traditional method for extracting the carry would be to shift 
+by $lg(\beta)$ positions and logically AND the least significant bit.  The AND operation is required because all of 
+the bits above the $\lg(\beta)$'th bit will be set to one after a carry occurs from subtraction.  This carry 
+extraction requires two relatively cheap operations to extract the carry.  The other method is to simply shift the 
+most significant bit to the least significant bit thus extracting the carry with a single cheap operation.  This 
+optimization only works on twos compliment machines which is a safe assumption to make.
+
+If $a$ has a larger magnitude than $b$ an additional loop (lines 64 through 73) is required to propagate 
+the carry through $a$ and copy the result to $c$.  
+
+\subsection{High Level Addition}
+Now that both lower level addition and subtraction algorithms have been established an effective high level signed addition algorithm can be
+established.  This high level addition algorithm will be what other algorithms and developers will use to perform addition of mp\_int data 
+types.  
+
+Recall from section 5.2 that an mp\_int represents an integer with an unsigned mantissa (\textit{the array of digits}) and a \textbf{sign} 
+flag.  A high level addition is actually performed as a series of eight separate cases which can be optimized down to three unique cases.
+
+\begin{figure}[!here]
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{mp\_add}. \\
+\textbf{Input}.   Two mp\_ints $a$ and $b$  \\
+\textbf{Output}.  The signed addition $c = a + b$. \\
+\hline \\
+1.  if $a.sign = b.sign$ then do \\
+\hspace{3mm}1.1  $c.sign \leftarrow a.sign$  \\
+\hspace{3mm}1.2  $c \leftarrow \vert a \vert + \vert b \vert$ (\textit{s\_mp\_add})\\
+2.  else do \\
+\hspace{3mm}2.1  if $\vert a \vert < \vert b \vert$ then do (\textit{mp\_cmp\_mag})  \\
+\hspace{6mm}2.1.1  $c.sign \leftarrow b.sign$ \\
+\hspace{6mm}2.1.2  $c \leftarrow \vert b \vert - \vert a \vert$ (\textit{s\_mp\_sub}) \\
+\hspace{3mm}2.2  else do \\
+\hspace{6mm}2.2.1  $c.sign \leftarrow a.sign$ \\
+\hspace{6mm}2.2.2  $c \leftarrow \vert a \vert - \vert b \vert$ \\
+3.  Return(\textit{MP\_OKAY}). \\
+\hline
+\end{tabular}
+\end{center}
+\caption{Algorithm mp\_add}
+\end{figure}
+
+\textbf{Algorithm mp\_add.}
+This algorithm performs the signed addition of two mp\_int variables.  There is no reference algorithm to draw upon from 
+either \cite{TAOCPV2} or \cite{HAC} since they both only provide unsigned operations.  The algorithm is fairly 
+straightforward but restricted since subtraction can only produce positive results.
+
+\begin{figure}[here]
+\begin{small}
+\begin{center}
+\begin{tabular}{|c|c|c|c|c|}
+\hline \textbf{Sign of $a$} & \textbf{Sign of $b$} & \textbf{$\vert a \vert > \vert b \vert $} & \textbf{Unsigned Operation} & \textbf{Result Sign Flag} \\
+\hline $+$ & $+$ & Yes & $c = a + b$ & $a.sign$ \\
+\hline $+$ & $+$ & No  & $c = a + b$ & $a.sign$ \\
+\hline $-$ & $-$ & Yes & $c = a + b$ & $a.sign$ \\
+\hline $-$ & $-$ & No  & $c = a + b$ & $a.sign$ \\
+\hline &&&&\\
+
+\hline $+$ & $-$ & No  & $c = b - a$ & $b.sign$ \\
+\hline $-$ & $+$ & No  & $c = b - a$ & $b.sign$ \\
+
+\hline &&&&\\
+
+\hline $+$ & $-$ & Yes & $c = a - b$ & $a.sign$ \\
+\hline $-$ & $+$ & Yes & $c = a - b$ & $a.sign$ \\
+
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Addition Guide Chart}
+\label{fig:AddChart}
+\end{figure}
+
+Figure~\ref{fig:AddChart} lists all of the eight possible input combinations and is sorted to show that only three 
+specific cases need to be handled.  The return code of the unsigned operations at step 1.2, 2.1.2 and 2.2.2 are 
+forwarded to step three to check for errors.  This simplifies the description of the algorithm considerably and best 
+follows how the implementation actually was achieved.
+
+Also note how the \textbf{sign} is set before the unsigned addition or subtraction is performed.  Recall from the descriptions of algorithms
+s\_mp\_add and s\_mp\_sub that the mp\_clamp function is used at the end to trim excess digits.  The mp\_clamp algorithm will set the \textbf{sign}
+to \textbf{MP\_ZPOS} when the \textbf{used} digit count reaches zero.
+
+For example, consider performing $-a + a$ with algorithm mp\_add.  By the description of the algorithm the sign is set to \textbf{MP\_NEG} which would
+produce a result of $-0$.  However, since the sign is set first then the unsigned addition is performed the subsequent usage of algorithm mp\_clamp 
+within algorithm s\_mp\_add will force $-0$ to become $0$.  
+
+\vspace{+3mm}\begin{small}
+\hspace{-5.1mm}{\bf File}: bn\_mp\_add.c
+\vspace{-3mm}
+\begin{alltt}
+\end{alltt}
+\end{small}
+
+The source code follows the algorithm fairly closely.  The most notable new source code addition is the usage of the $res$ integer variable which
+is used to pass result of the unsigned operations forward.  Unlike in the algorithm, the variable $res$ is merely returned as is without
+explicitly checking it and returning the constant \textbf{MP\_OKAY}.  The observation is this algorithm will succeed or fail only if the lower
+level functions do so.  Returning their return code is sufficient.
+
+\subsection{High Level Subtraction}
+The high level signed subtraction algorithm is essentially the same as the high level signed addition algorithm.  
+
+\newpage\begin{figure}[!here]
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{mp\_sub}. \\
+\textbf{Input}.   Two mp\_ints $a$ and $b$  \\
+\textbf{Output}.  The signed subtraction $c = a - b$. \\
+\hline \\
+1.  if $a.sign \ne b.sign$ then do \\
+\hspace{3mm}1.1  $c.sign \leftarrow a.sign$ \\
+\hspace{3mm}1.2  $c \leftarrow \vert a \vert + \vert b \vert$ (\textit{s\_mp\_add}) \\
+2.  else do \\
+\hspace{3mm}2.1  if $\vert a \vert \ge \vert b \vert$ then do (\textit{mp\_cmp\_mag}) \\
+\hspace{6mm}2.1.1  $c.sign \leftarrow a.sign$ \\
+\hspace{6mm}2.1.2  $c \leftarrow \vert a \vert  - \vert b \vert$ (\textit{s\_mp\_sub}) \\
+\hspace{3mm}2.2  else do \\
+\hspace{6mm}2.2.1  $c.sign \leftarrow  \left \lbrace \begin{array}{ll}
+                              MP\_ZPOS &  \mbox{if }a.sign = MP\_NEG \\
+                              MP\_NEG  &  \mbox{otherwise} \\
+                              \end{array} \right .$ \\
+\hspace{6mm}2.2.2  $c \leftarrow \vert b \vert  - \vert a \vert$ \\
+3.  Return(\textit{MP\_OKAY}). \\
+\hline
+\end{tabular}
+\end{center}
+\caption{Algorithm mp\_sub}
+\end{figure}
+
+\textbf{Algorithm mp\_sub.}
+This algorithm performs the signed subtraction of two inputs.  Similar to algorithm mp\_add there is no reference in either \cite{TAOCPV2} or 
+\cite{HAC}.  Also this algorithm is restricted by algorithm s\_mp\_sub.  Chart \ref{fig:SubChart} lists the eight possible inputs and
+the operations required.
+
+\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{|c|c|c|c|c|}
+\hline \textbf{Sign of $a$} & \textbf{Sign of $b$} & \textbf{$\vert a \vert \ge \vert b \vert $} & \textbf{Unsigned Operation} & \textbf{Result Sign Flag} \\
+\hline $+$ & $-$ & Yes & $c = a + b$ & $a.sign$ \\
+\hline $+$ & $-$ & No  & $c = a + b$ & $a.sign$ \\
+\hline $-$ & $+$ & Yes & $c = a + b$ & $a.sign$ \\
+\hline $-$ & $+$ & No  & $c = a + b$ & $a.sign$ \\
+\hline &&&& \\
+\hline $+$ & $+$ & Yes & $c = a - b$ & $a.sign$ \\
+\hline $-$ & $-$ & Yes & $c = a - b$ & $a.sign$ \\
+\hline &&&& \\
+\hline $+$ & $+$ & No  & $c = b - a$ & $\mbox{opposite of }a.sign$ \\
+\hline $-$ & $-$ & No  & $c = b - a$ & $\mbox{opposite of }a.sign$ \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Subtraction Guide Chart}
+\label{fig:SubChart}
+\end{figure}
+
+Similar to the case of algorithm mp\_add the \textbf{sign} is set first before the unsigned addition or subtraction.  That is to prevent the 
+algorithm from producing $-a - -a = -0$ as a result.  
+
+\vspace{+3mm}\begin{small}
+\hspace{-5.1mm}{\bf File}: bn\_mp\_sub.c
+\vspace{-3mm}
+\begin{alltt}
+\end{alltt}
+\end{small}
+
+Much like the implementation of algorithm mp\_add the variable $res$ is used to catch the return code of the unsigned addition or subtraction operations
+and forward it to the end of the function.  On line 39 the ``not equal to'' \textbf{MP\_LT} expression is used to emulate a 
+``greater than or equal to'' comparison.  
+
+\section{Bit and Digit Shifting}
+It is quite common to think of a multiple precision integer as a polynomial in $x$, that is $y = f(\beta)$ where $f(x) = \sum_{i=0}^{n-1} a_i x^i$.  
+This notation arises within discussion of Montgomery and Diminished Radix Reduction as well as Karatsuba multiplication and squaring.  
+
+In order to facilitate operations on polynomials in $x$ as above a series of simple ``digit'' algorithms have to be established.  That is to shift
+the digits left or right as well to shift individual bits of the digits left and right.  It is important to note that not all ``shift'' operations
+are on radix-$\beta$ digits.  
+
+\subsection{Multiplication by Two}
+
+In a binary system where the radix is a power of two multiplication by two not only arises often in other algorithms it is a fairly efficient 
+operation to perform.  A single precision logical shift left is sufficient to multiply a single digit by two.  
+
+\newpage\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{mp\_mul\_2}. \\
+\textbf{Input}.   One mp\_int $a$ \\
+\textbf{Output}.  $b = 2a$. \\
+\hline \\
+1.  If $b.alloc < a.used + 1$ then grow $b$ to hold $a.used + 1$ digits.  (\textit{mp\_grow}) \\
+2.  $oldused \leftarrow b.used$ \\
+3.  $b.used \leftarrow a.used$ \\
+4.  $r \leftarrow 0$ \\
+5.  for $n$ from 0 to $a.used - 1$ do \\
+\hspace{3mm}5.1  $rr \leftarrow a_n >> (lg(\beta) - 1)$ \\
+\hspace{3mm}5.2  $b_n \leftarrow (a_n << 1) + r \mbox{ (mod }\beta\mbox{)}$ \\
+\hspace{3mm}5.3  $r \leftarrow rr$ \\
+6.  If $r \ne 0$ then do \\
+\hspace{3mm}6.1  $b_{n + 1} \leftarrow r$ \\
+\hspace{3mm}6.2  $b.used \leftarrow b.used + 1$ \\
+7.  If $b.used < oldused - 1$ then do \\
+\hspace{3mm}7.1  for $n$ from $b.used$ to $oldused - 1$ do \\
+\hspace{6mm}7.1.1  $b_n \leftarrow 0$ \\
+8.  $b.sign \leftarrow a.sign$ \\
+9.  Return(\textit{MP\_OKAY}).\\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Algorithm mp\_mul\_2}
+\end{figure}
+
+\textbf{Algorithm mp\_mul\_2.}
+This algorithm will quickly multiply a mp\_int by two provided $\beta$ is a power of two.  Neither \cite{TAOCPV2} nor \cite{HAC} describe such 
+an algorithm despite the fact it arises often in other algorithms.  The algorithm is setup much like the lower level algorithm s\_mp\_add since 
+it is for all intents and purposes equivalent to the operation $b = \vert a \vert + \vert a \vert$.  
+
+Step 1 and 2 grow the input as required to accomodate the maximum number of \textbf{used} digits in the result.  The initial \textbf{used} count
+is set to $a.used$ at step 4.  Only if there is a final carry will the \textbf{used} count require adjustment.
+
+Step 6 is an optimization implementation of the addition loop for this specific case.  That is since the two values being added together 
+are the same there is no need to perform two reads from the digits of $a$.  Step 6.1 performs a single precision shift on the current digit $a_n$ to
+obtain what will be the carry for the next iteration.  Step 6.2 calculates the $n$'th digit of the result as single precision shift of $a_n$ plus
+the previous carry.  Recall from section 4.1 that $a_n << 1$ is equivalent to $a_n \cdot 2$.  An iteration of the addition loop is finished with 
+forwarding the carry to the next iteration.
+
+Step 7 takes care of any final carry by setting the $a.used$'th digit of the result to the carry and augmenting the \textbf{used} count of $b$.  
+Step 8 clears any leading digits of $b$ in case it originally had a larger magnitude than $a$.
+
+\vspace{+3mm}\begin{small}
+\hspace{-5.1mm}{\bf File}: bn\_mp\_mul\_2.c
+\vspace{-3mm}
+\begin{alltt}
+\end{alltt}
+\end{small}
+
+This implementation is essentially an optimized implementation of s\_mp\_add for the case of doubling an input.  The only noteworthy difference
+is the use of the logical shift operator on line 52 to perform a single precision doubling.  
+
+\subsection{Division by Two}
+A division by two can just as easily be accomplished with a logical shift right as multiplication by two can be with a logical shift left.
+
+\newpage\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{mp\_div\_2}. \\
+\textbf{Input}.   One mp\_int $a$ \\
+\textbf{Output}.  $b = a/2$. \\
+\hline \\
+1.  If $b.alloc < a.used$ then grow $b$ to hold $a.used$ digits.  (\textit{mp\_grow}) \\
+2.  If the reallocation failed return(\textit{MP\_MEM}). \\
+3.  $oldused \leftarrow b.used$ \\
+4.  $b.used \leftarrow a.used$ \\
+5.  $r \leftarrow 0$ \\
+6.  for $n$ from $b.used - 1$ to $0$ do \\
+\hspace{3mm}6.1  $rr \leftarrow a_n \mbox{ (mod }2\mbox{)}$\\
+\hspace{3mm}6.2  $b_n \leftarrow (a_n >> 1) + (r << (lg(\beta) - 1)) \mbox{ (mod }\beta\mbox{)}$ \\
+\hspace{3mm}6.3  $r \leftarrow rr$ \\
+7.  If $b.used < oldused - 1$ then do \\
+\hspace{3mm}7.1  for $n$ from $b.used$ to $oldused - 1$ do \\
+\hspace{6mm}7.1.1  $b_n \leftarrow 0$ \\
+8.  $b.sign \leftarrow a.sign$ \\
+9.  Clamp excess digits of $b$.  (\textit{mp\_clamp}) \\
+10.  Return(\textit{MP\_OKAY}).\\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Algorithm mp\_div\_2}
+\end{figure}
+
+\textbf{Algorithm mp\_div\_2.}
+This algorithm will divide an mp\_int by two using logical shifts to the right.  Like mp\_mul\_2 it uses a modified low level addition
+core as the basis of the algorithm.  Unlike mp\_mul\_2 the shift operations work from the leading digit to the trailing digit.  The algorithm
+could be written to work from the trailing digit to the leading digit however, it would have to stop one short of $a.used - 1$ digits to prevent
+reading past the end of the array of digits.
+
+Essentially the loop at step 6 is similar to that of mp\_mul\_2 except the logical shifts go in the opposite direction and the carry is at the 
+least significant bit not the most significant bit.  
+
+\vspace{+3mm}\begin{small}
+\hspace{-5.1mm}{\bf File}: bn\_mp\_div\_2.c
+\vspace{-3mm}
+\begin{alltt}
+\end{alltt}
+\end{small}
+
+\section{Polynomial Basis Operations}
+Recall from section 4.3 that any integer can be represented as a polynomial in $x$ as $y = f(\beta)$.  Such a representation is also known as
+the polynomial basis \cite[pp. 48]{ROSE}. Given such a notation a multiplication or division by $x$ amounts to shifting whole digits a single 
+place.  The need for such operations arises in several other higher level algorithms such as Barrett and Montgomery reduction, integer
+division and Karatsuba multiplication.  
+
+Converting from an array of digits to polynomial basis is very simple.  Consider the integer $y \equiv (a_2, a_1, a_0)_{\beta}$ and recall that
+$y = \sum_{i=0}^{2} a_i \beta^i$.  Simply replace $\beta$ with $x$ and the expression is in polynomial basis.  For example, $f(x) = 8x + 9$ is the
+polynomial basis representation for $89$ using radix ten.  That is, $f(10) = 8(10) + 9 = 89$.  
+
+\subsection{Multiplication by $x$}
+
+Given a polynomial in $x$ such as $f(x) = a_n x^n + a_{n-1} x^{n-1} + ... + a_0$ multiplying by $x$ amounts to shifting the coefficients up one 
+degree.  In this case $f(x) \cdot x = a_n x^{n+1} + a_{n-1} x^n + ... + a_0 x$.  From a scalar basis point of view multiplying by $x$ is equivalent to
+multiplying by the integer $\beta$.  
+
+\newpage\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{mp\_lshd}. \\
+\textbf{Input}.   One mp\_int $a$ and an integer $b$ \\
+\textbf{Output}.  $a \leftarrow a \cdot \beta^b$ (equivalent to multiplication by $x^b$). \\
+\hline \\
+1.  If $b \le 0$ then return(\textit{MP\_OKAY}). \\
+2.  If $a.alloc < a.used + b$ then grow $a$ to at least $a.used + b$ digits.  (\textit{mp\_grow}). \\
+3.  If the reallocation failed return(\textit{MP\_MEM}). \\
+4.  $a.used \leftarrow a.used + b$ \\
+5.  $i \leftarrow a.used - 1$ \\
+6.  $j \leftarrow a.used - 1 - b$ \\
+7.  for $n$ from $a.used - 1$ to $b$ do \\
+\hspace{3mm}7.1  $a_{i} \leftarrow a_{j}$ \\
+\hspace{3mm}7.2  $i \leftarrow i - 1$ \\
+\hspace{3mm}7.3  $j \leftarrow j - 1$ \\
+8.  for $n$ from 0 to $b - 1$ do \\
+\hspace{3mm}8.1  $a_n \leftarrow 0$ \\
+9.  Return(\textit{MP\_OKAY}). \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Algorithm mp\_lshd}
+\end{figure}
+
+\textbf{Algorithm mp\_lshd.}
+This algorithm multiplies an mp\_int by the $b$'th power of $x$.  This is equivalent to multiplying by $\beta^b$.  The algorithm differs 
+from the other algorithms presented so far as it performs the operation in place instead storing the result in a separate location.  The
+motivation behind this change is due to the way this function is typically used.  Algorithms such as mp\_add store the result in an optionally
+different third mp\_int because the original inputs are often still required.  Algorithm mp\_lshd (\textit{and similarly algorithm mp\_rshd}) is
+typically used on values where the original value is no longer required.  The algorithm will return success immediately if 
+$b \le 0$ since the rest of algorithm is only valid when $b > 0$.  
+
+First the destination $a$ is grown as required to accomodate the result.  The counters $i$ and $j$ are used to form a \textit{sliding window} over
+the digits of $a$ of length $b$.  The head of the sliding window is at $i$ (\textit{the leading digit}) and the tail at $j$ (\textit{the trailing digit}).  
+The loop on step 7 copies the digit from the tail to the head.  In each iteration the window is moved down one digit.   The last loop on 
+step 8 sets the lower $b$ digits to zero.
+
+\newpage
+\begin{center}
+\begin{figure}[here]
+\includegraphics{pics/sliding_window.ps}
+\caption{Sliding Window Movement}
+\label{pic:sliding_window}
+\end{figure}
+\end{center}
+
+\vspace{+3mm}\begin{small}
+\hspace{-5.1mm}{\bf File}: bn\_mp\_lshd.c
+\vspace{-3mm}
+\begin{alltt}
+\end{alltt}
+\end{small}
+
+The if statement (line 24) ensures that the $b$ variable is greater than zero since we do not interpret negative
+shift counts properly.  The \textbf{used} count is incremented by $b$ before the copy loop begins.  This elminates 
+the need for an additional variable in the for loop.  The variable $top$ (line 42) is an alias
+for the leading digit while $bottom$ (line 45) is an alias for the trailing edge.  The aliases form a 
+window of exactly $b$ digits over the input.  
+
+\subsection{Division by $x$}
+
+Division by powers of $x$ is easily achieved by shifting the digits right and removing any that will end up to the right of the zero'th digit.  
+
+\newpage\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{mp\_rshd}. \\
+\textbf{Input}.   One mp\_int $a$ and an integer $b$ \\
+\textbf{Output}.  $a \leftarrow a / \beta^b$ (Divide by $x^b$). \\
+\hline \\
+1.  If $b \le 0$ then return. \\
+2.  If $a.used \le b$ then do \\
+\hspace{3mm}2.1  Zero $a$.  (\textit{mp\_zero}). \\
+\hspace{3mm}2.2  Return. \\
+3.  $i \leftarrow 0$ \\
+4.  $j \leftarrow b$ \\
+5.  for $n$ from 0 to $a.used - b - 1$ do \\
+\hspace{3mm}5.1  $a_i \leftarrow a_j$ \\
+\hspace{3mm}5.2  $i \leftarrow i + 1$ \\
+\hspace{3mm}5.3  $j \leftarrow j + 1$ \\
+6.  for $n$ from $a.used - b$ to $a.used - 1$ do \\
+\hspace{3mm}6.1  $a_n \leftarrow 0$ \\
+7.  $a.used \leftarrow a.used - b$ \\
+8.  Return. \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Algorithm mp\_rshd}
+\end{figure}
+
+\textbf{Algorithm mp\_rshd.}
+This algorithm divides the input in place by the $b$'th power of $x$.  It is analogous to dividing by a $\beta^b$ but much quicker since
+it does not require single precision division.  This algorithm does not actually return an error code as it cannot fail.  
+
+If the input $b$ is less than one the algorithm quickly returns without performing any work.  If the \textbf{used} count is less than or equal
+to the shift count $b$ then it will simply zero the input and return.
+
+After the trivial cases of inputs have been handled the sliding window is setup.  Much like the case of algorithm mp\_lshd a sliding window that
+is $b$ digits wide is used to copy the digits.  Unlike mp\_lshd the window slides in the opposite direction from the trailing to the leading digit.  
+Also the digits are copied from the leading to the trailing edge.
+
+Once the window copy is complete the upper digits must be zeroed and the \textbf{used} count decremented.
+
+\vspace{+3mm}\begin{small}
+\hspace{-5.1mm}{\bf File}: bn\_mp\_rshd.c
+\vspace{-3mm}
+\begin{alltt}
+\end{alltt}
+\end{small}
+
+The only noteworthy element of this routine is the lack of a return type since it cannot fail.  Like mp\_lshd() we
+form a sliding window except we copy in the other direction.  After the window (line 60) we then zero
+the upper digits of the input to make sure the result is correct.
+
+\section{Powers of Two}
+
+Now that algorithms for moving single bits as well as whole digits exist algorithms for moving the ``in between'' distances are required.  For 
+example, to quickly multiply by $2^k$ for any $k$ without using a full multiplier algorithm would prove useful.  Instead of performing single
+shifts $k$ times to achieve a multiplication by $2^{\pm k}$ a mixture of whole digit shifting and partial digit shifting is employed.  
+
+\subsection{Multiplication by Power of Two}
+
+\newpage\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{mp\_mul\_2d}. \\
+\textbf{Input}.   One mp\_int $a$ and an integer $b$ \\
+\textbf{Output}.  $c \leftarrow a \cdot 2^b$. \\
+\hline \\
+1.  $c \leftarrow a$.  (\textit{mp\_copy}) \\
+2.  If $c.alloc < c.used + \lfloor b / lg(\beta) \rfloor + 2$ then grow $c$ accordingly. \\
+3.  If the reallocation failed return(\textit{MP\_MEM}). \\
+4.  If $b \ge lg(\beta)$ then \\
+\hspace{3mm}4.1  $c \leftarrow c \cdot \beta^{\lfloor b / lg(\beta) \rfloor}$ (\textit{mp\_lshd}). \\
+\hspace{3mm}4.2  If step 4.1 failed return(\textit{MP\_MEM}). \\
+5.  $d \leftarrow b \mbox{ (mod }lg(\beta)\mbox{)}$ \\
+6.  If $d \ne 0$ then do \\
+\hspace{3mm}6.1  $mask \leftarrow 2^d$ \\
+\hspace{3mm}6.2  $r \leftarrow 0$ \\
+\hspace{3mm}6.3  for $n$ from $0$ to $c.used - 1$ do \\
+\hspace{6mm}6.3.1  $rr \leftarrow c_n >> (lg(\beta) - d) \mbox{ (mod }mask\mbox{)}$ \\
+\hspace{6mm}6.3.2  $c_n \leftarrow (c_n << d) + r \mbox{ (mod }\beta\mbox{)}$ \\
+\hspace{6mm}6.3.3  $r \leftarrow rr$ \\
+\hspace{3mm}6.4  If $r > 0$ then do \\
+\hspace{6mm}6.4.1  $c_{c.used} \leftarrow r$ \\
+\hspace{6mm}6.4.2  $c.used \leftarrow c.used + 1$ \\
+7.  Return(\textit{MP\_OKAY}). \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Algorithm mp\_mul\_2d}
+\end{figure}
+
+\textbf{Algorithm mp\_mul\_2d.}
+This algorithm multiplies $a$ by $2^b$ and stores the result in $c$.  The algorithm uses algorithm mp\_lshd and a derivative of algorithm mp\_mul\_2 to
+quickly compute the product.
+
+First the algorithm will multiply $a$ by $x^{\lfloor b / lg(\beta) \rfloor}$ which will ensure that the remainder multiplicand is less than 
+$\beta$.  For example, if $b = 37$ and $\beta = 2^{28}$ then this step will multiply by $x$ leaving a multiplication by $2^{37 - 28} = 2^{9}$ 
+left.
+
+After the digits have been shifted appropriately at most $lg(\beta) - 1$ shifts are left to perform.  Step 5 calculates the number of remaining shifts 
+required.  If it is non-zero a modified shift loop is used to calculate the remaining product.  
+Essentially the loop is a generic version of algorithm mp\_mul\_2 designed to handle any shift count in the range $1 \le x < lg(\beta)$.  The $mask$
+variable is used to extract the upper $d$ bits to form the carry for the next iteration.  
+
+This algorithm is loosely measured as a $O(2n)$ algorithm which means that if the input is $n$-digits that it takes $2n$ ``time'' to 
+complete.  It is possible to optimize this algorithm down to a $O(n)$ algorithm at a cost of making the algorithm slightly harder to follow.
+
+\vspace{+3mm}\begin{small}
+\hspace{-5.1mm}{\bf File}: bn\_mp\_mul\_2d.c
+\vspace{-3mm}
+\begin{alltt}
+\end{alltt}
+\end{small}
+
+The shifting is performed in--place which means the first step (line 25) is to copy the input to the 
+destination.  We avoid calling mp\_copy() by making sure the mp\_ints are different.  The destination then
+has to be grown (line 32) to accomodate the result.
+
+If the shift count $b$ is larger than $lg(\beta)$ then a call to mp\_lshd() is used to handle all of the multiples 
+of $lg(\beta)$.  Leaving only a remaining shift of $lg(\beta) - 1$ or fewer bits left.  Inside the actual shift 
+loop (lines 46 to 76) we make use of pre--computed values $shift$ and $mask$.   These are used to
+extract the carry bit(s) to pass into the next iteration of the loop.  The $r$ and $rr$ variables form a 
+chain between consecutive iterations to propagate the carry.  
+
+\subsection{Division by Power of Two}
+
+\newpage\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{mp\_div\_2d}. \\
+\textbf{Input}.   One mp\_int $a$ and an integer $b$ \\
+\textbf{Output}.  $c \leftarrow \lfloor a / 2^b \rfloor, d \leftarrow a \mbox{ (mod }2^b\mbox{)}$. \\
+\hline \\
+1.  If $b \le 0$ then do \\
+\hspace{3mm}1.1  $c \leftarrow a$ (\textit{mp\_copy}) \\
+\hspace{3mm}1.2  $d \leftarrow 0$ (\textit{mp\_zero}) \\
+\hspace{3mm}1.3  Return(\textit{MP\_OKAY}). \\
+2.  $c \leftarrow a$ \\
+3.  $d \leftarrow a \mbox{ (mod }2^b\mbox{)}$ (\textit{mp\_mod\_2d}) \\
+4.  If $b \ge lg(\beta)$ then do \\
+\hspace{3mm}4.1  $c \leftarrow \lfloor c/\beta^{\lfloor b/lg(\beta) \rfloor} \rfloor$ (\textit{mp\_rshd}). \\
+5.  $k \leftarrow b \mbox{ (mod }lg(\beta)\mbox{)}$ \\
+6.  If $k \ne 0$ then do \\
+\hspace{3mm}6.1  $mask \leftarrow 2^k$ \\
+\hspace{3mm}6.2  $r \leftarrow 0$ \\
+\hspace{3mm}6.3  for $n$ from $c.used - 1$ to $0$ do \\
+\hspace{6mm}6.3.1  $rr \leftarrow c_n \mbox{ (mod }mask\mbox{)}$ \\
+\hspace{6mm}6.3.2  $c_n \leftarrow (c_n >> k) + (r << (lg(\beta) - k))$ \\
+\hspace{6mm}6.3.3  $r \leftarrow rr$ \\
+7.  Clamp excess digits of $c$.  (\textit{mp\_clamp}) \\
+8.  Return(\textit{MP\_OKAY}). \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Algorithm mp\_div\_2d}
+\end{figure}
+
+\textbf{Algorithm mp\_div\_2d.}
+This algorithm will divide an input $a$ by $2^b$ and produce the quotient and remainder.  The algorithm is designed much like algorithm 
+mp\_mul\_2d by first using whole digit shifts then single precision shifts.  This algorithm will also produce the remainder of the division
+by using algorithm mp\_mod\_2d.
+
+\vspace{+3mm}\begin{small}
+\hspace{-5.1mm}{\bf File}: bn\_mp\_div\_2d.c
+\vspace{-3mm}
+\begin{alltt}
+\end{alltt}
+\end{small}
+
+The implementation of algorithm mp\_div\_2d is slightly different than the algorithm specifies.  The remainder $d$ may be optionally 
+ignored by passing \textbf{NULL} as the pointer to the mp\_int variable.    The temporary mp\_int variable $t$ is used to hold the 
+result of the remainder operation until the end.  This allows $d$ and $a$ to represent the same mp\_int without modifying $a$ before
+the quotient is obtained.
+
+The remainder of the source code is essentially the same as the source code for mp\_mul\_2d.  The only significant difference is
+the direction of the shifts.
+
+\subsection{Remainder of Division by Power of Two}
+
+The last algorithm in the series of polynomial basis power of two algorithms is calculating the remainder of division by $2^b$.  This
+algorithm benefits from the fact that in twos complement arithmetic $a \mbox{ (mod }2^b\mbox{)}$ is the same as $a$ AND $2^b - 1$.  
+
+\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{mp\_mod\_2d}. \\
+\textbf{Input}.   One mp\_int $a$ and an integer $b$ \\
+\textbf{Output}.  $c \leftarrow a \mbox{ (mod }2^b\mbox{)}$. \\
+\hline \\
+1.  If $b \le 0$ then do \\
+\hspace{3mm}1.1  $c \leftarrow 0$ (\textit{mp\_zero}) \\
+\hspace{3mm}1.2  Return(\textit{MP\_OKAY}). \\
+2.  If $b > a.used \cdot lg(\beta)$ then do \\
+\hspace{3mm}2.1  $c \leftarrow a$ (\textit{mp\_copy}) \\
+\hspace{3mm}2.2  Return the result of step 2.1. \\
+3.  $c \leftarrow a$ \\
+4.  If step 3 failed return(\textit{MP\_MEM}). \\
+5.  for $n$ from $\lceil b / lg(\beta) \rceil$ to $c.used$ do \\
+\hspace{3mm}5.1  $c_n \leftarrow 0$ \\
+6.  $k \leftarrow b \mbox{ (mod }lg(\beta)\mbox{)}$ \\
+7.  $c_{\lfloor b / lg(\beta) \rfloor} \leftarrow c_{\lfloor b / lg(\beta) \rfloor} \mbox{ (mod }2^{k}\mbox{)}$. \\
+8.  Clamp excess digits of $c$.  (\textit{mp\_clamp}) \\
+9.  Return(\textit{MP\_OKAY}). \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Algorithm mp\_mod\_2d}
+\end{figure}
+
+\textbf{Algorithm mp\_mod\_2d.}
+This algorithm will quickly calculate the value of $a \mbox{ (mod }2^b\mbox{)}$.  First if $b$ is less than or equal to zero the 
+result is set to zero.  If $b$ is greater than the number of bits in $a$ then it simply copies $a$ to $c$ and returns.  Otherwise, $a$ 
+is copied to $b$, leading digits are removed and the remaining leading digit is trimed to the exact bit count.
+
+\vspace{+3mm}\begin{small}
+\hspace{-5.1mm}{\bf File}: bn\_mp\_mod\_2d.c
+\vspace{-3mm}
+\begin{alltt}
+\end{alltt}
+\end{small}
+
+We first avoid cases of $b \le 0$ by simply mp\_zero()'ing the destination in such cases.  Next if $2^b$ is larger
+than the input we just mp\_copy() the input and return right away.  After this point we know we must actually
+perform some work to produce the remainder.
+
+Recalling that reducing modulo $2^k$ and a binary ``and'' with $2^k - 1$ are numerically equivalent we can quickly reduce 
+the number.  First we zero any digits above the last digit in $2^b$ (line 42).  Next we reduce the 
+leading digit of both (line 46) and then mp\_clamp().
+
+\section*{Exercises}
+\begin{tabular}{cl}
+$\left [ 3 \right ] $ & Devise an algorithm that performs $a \cdot 2^b$ for generic values of $b$ \\
+                      & in $O(n)$ time. \\
+                      &\\
+$\left [ 3 \right ] $ & Devise an efficient algorithm to multiply by small low hamming  \\
+                      & weight values such as $3$, $5$ and $9$.  Extend it to handle all values \\
+                      & upto $64$ with a hamming weight less than three. \\
+                      &\\
+$\left [ 2 \right ] $ & Modify the preceding algorithm to handle values of the form \\
+                      & $2^k - 1$ as well. \\
+                      &\\
+$\left [ 3 \right ] $ & Using only algorithms mp\_mul\_2, mp\_div\_2 and mp\_add create an \\
+                      & algorithm to multiply two integers in roughly $O(2n^2)$ time for \\
+                      & any $n$-bit input.  Note that the time of addition is ignored in the \\
+                      & calculation.  \\
+                      & \\
+$\left [ 5 \right ] $ & Improve the previous algorithm to have a working time of at most \\
+                      & $O \left (2^{(k-1)}n + \left ({2n^2 \over k} \right ) \right )$ for an appropriate choice of $k$.  Again ignore \\
+                      & the cost of addition. \\
+                      & \\
+$\left [ 2 \right ] $ & Devise a chart to find optimal values of $k$ for the previous problem \\
+                      & for $n = 64 \ldots 1024$ in steps of $64$. \\
+                      & \\
+$\left [ 2 \right ] $ & Using only algorithms mp\_abs and mp\_sub devise another method for \\
+                      & calculating the result of a signed comparison. \\
+                      &
+\end{tabular}
+
+\chapter{Multiplication and Squaring}
+\section{The Multipliers}
+For most number theoretic problems including certain public key cryptographic algorithms, the ``multipliers'' form the most important subset of 
+algorithms of any multiple precision integer package.  The set of multiplier algorithms include integer multiplication, squaring and modular reduction 
+where in each of the algorithms single precision multiplication is the dominant operation performed.  This chapter will discuss integer multiplication 
+and squaring, leaving modular reductions for the subsequent chapter.  
+
+The importance of the multiplier algorithms is for the most part driven by the fact that certain popular public key algorithms are based on modular 
+exponentiation, that is computing $d \equiv a^b \mbox{ (mod }c\mbox{)}$ for some arbitrary choice of $a$, $b$, $c$ and $d$.  During a modular
+exponentiation the majority\footnote{Roughly speaking a modular exponentiation will spend about 40\% of the time performing modular reductions, 
+35\% of the time performing squaring and 25\% of the time performing multiplications.} of the processor time is spent performing single precision 
+multiplications.
+
+For centuries general purpose multiplication has required a lengthly $O(n^2)$ process, whereby each digit of one multiplicand has to be multiplied 
+against every digit of the other multiplicand.  Traditional long-hand multiplication is based on this process;  while the techniques can differ the 
+overall algorithm used is essentially the same.  Only ``recently'' have faster algorithms been studied.  First Karatsuba multiplication was discovered in 
+1962.  This algorithm can multiply two numbers with considerably fewer single precision multiplications when compared to the long-hand approach.  
+This technique led to the discovery of polynomial basis algorithms (\textit{good reference?}) and subquently Fourier Transform based solutions.  
+
+\section{Multiplication}
+\subsection{The Baseline Multiplication}
+\label{sec:basemult}
+\index{baseline multiplication}
+Computing the product of two integers in software can be achieved using a trivial adaptation of the standard $O(n^2)$ long-hand multiplication
+algorithm that school children are taught.  The algorithm is considered an $O(n^2)$ algorithm since for two $n$-digit inputs $n^2$ single precision 
+multiplications are required.  More specifically for a $m$ and $n$ digit input $m \cdot n$ single precision multiplications are required.  To 
+simplify most discussions, it will be assumed that the inputs have comparable number of digits.  
+
+The ``baseline multiplication'' algorithm is designed to act as the ``catch-all'' algorithm, only to be used when the faster algorithms cannot be 
+used.  This algorithm does not use any particularly interesting optimizations and should ideally be avoided if possible.    One important 
+facet of this algorithm, is that it has been modified to only produce a certain amount of output digits as resolution.  The importance of this 
+modification will become evident during the discussion of Barrett modular reduction.  Recall that for a $n$ and $m$ digit input the product 
+will be at most $n + m$ digits.  Therefore, this algorithm can be reduced to a full multiplier by having it produce $n + m$ digits of the product.  
+
+Recall from sub-section 4.2.2 the definition of $\gamma$ as the number of bits in the type \textbf{mp\_digit}.  We shall now extend the variable set to 
+include $\alpha$ which shall represent the number of bits in the type \textbf{mp\_word}.  This implies that $2^{\alpha} > 2 \cdot \beta^2$.  The 
+constant $\delta = 2^{\alpha - 2lg(\beta)}$ will represent the maximal weight of any column in a product (\textit{see sub-section 5.2.2 for more information}).
+
+\newpage\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{s\_mp\_mul\_digs}. \\
+\textbf{Input}.   mp\_int $a$, mp\_int $b$ and an integer $digs$ \\
+\textbf{Output}.  $c \leftarrow \vert a \vert \cdot \vert b \vert \mbox{ (mod }\beta^{digs}\mbox{)}$. \\
+\hline \\
+1.  If min$(a.used, b.used) < \delta$ then do \\
+\hspace{3mm}1.1  Calculate $c = \vert a \vert \cdot \vert b \vert$ by the Comba method (\textit{see algorithm~\ref{fig:COMBAMULT}}).  \\
+\hspace{3mm}1.2  Return the result of step 1.1 \\
+\\
+Allocate and initialize a temporary mp\_int. \\
+2.  Init $t$ to be of size $digs$ \\
+3.  If step 2 failed return(\textit{MP\_MEM}). \\
+4.  $t.used \leftarrow digs$ \\
+\\
+Compute the product. \\
+5.  for $ix$ from $0$ to $a.used - 1$ do \\
+\hspace{3mm}5.1  $u \leftarrow 0$ \\
+\hspace{3mm}5.2  $pb \leftarrow \mbox{min}(b.used, digs - ix)$ \\
+\hspace{3mm}5.3  If $pb < 1$ then goto step 6. \\
+\hspace{3mm}5.4  for $iy$ from $0$ to $pb - 1$ do \\
+\hspace{6mm}5.4.1  $\hat r \leftarrow t_{iy + ix} + a_{ix} \cdot b_{iy} + u$ \\
+\hspace{6mm}5.4.2  $t_{iy + ix} \leftarrow \hat r \mbox{ (mod }\beta\mbox{)}$ \\
+\hspace{6mm}5.4.3  $u \leftarrow \lfloor \hat r / \beta \rfloor$ \\
+\hspace{3mm}5.5  if $ix + pb < digs$ then do \\
+\hspace{6mm}5.5.1  $t_{ix + pb} \leftarrow u$ \\
+6.  Clamp excess digits of $t$. \\
+7.  Swap $c$ with $t$ \\
+8.  Clear $t$ \\
+9.  Return(\textit{MP\_OKAY}). \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Algorithm s\_mp\_mul\_digs}
+\end{figure}
+
+\textbf{Algorithm s\_mp\_mul\_digs.}
+This algorithm computes the unsigned product of two inputs $a$ and $b$, limited to an output precision of $digs$ digits.  While it may seem
+a bit awkward to modify the function from its simple $O(n^2)$ description, the usefulness of partial multipliers will arise in a subsequent 
+algorithm.  The algorithm is loosely based on algorithm 14.12 from \cite[pp. 595]{HAC} and is similar to Algorithm M of Knuth \cite[pp. 268]{TAOCPV2}.  
+Algorithm s\_mp\_mul\_digs differs from these cited references since it can produce a variable output precision regardless of the precision of the 
+inputs.
+
+The first thing this algorithm checks for is whether a Comba multiplier can be used instead.   If the minimum digit count of either
+input is less than $\delta$, then the Comba method may be used instead.    After the Comba method is ruled out, the baseline algorithm begins.  A 
+temporary mp\_int variable $t$ is used to hold the intermediate result of the product.  This allows the algorithm to be used to 
+compute products when either $a = c$ or $b = c$ without overwriting the inputs.  
+
+All of step 5 is the infamous $O(n^2)$ multiplication loop slightly modified to only produce upto $digs$ digits of output.  The $pb$ variable
+is given the count of digits to read from $b$ inside the nested loop.  If $pb \le 1$ then no more output digits can be produced and the algorithm
+will exit the loop.  The best way to think of the loops are as a series of $pb \times 1$ multiplications.    That is, in each pass of the 
+innermost loop $a_{ix}$ is multiplied against $b$ and the result is added (\textit{with an appropriate shift}) to $t$.  
+
+For example, consider multiplying $576$ by $241$.  That is equivalent to computing $10^0(1)(576) + 10^1(4)(576) + 10^2(2)(576)$ which is best
+visualized in the following table.
+
+\begin{figure}[here]
+\begin{center}
+\begin{tabular}{|c|c|c|c|c|c|l|}
+\hline   &&          & 5 & 7 & 6 & \\
+\hline   $\times$&&  & 2 & 4 & 1 & \\
+\hline &&&&&&\\
+  &&          & 5 & 7 & 6 & $10^0(1)(576)$ \\
+  &2 &   3    & 6 & 1 & 6 & $10^1(4)(576) + 10^0(1)(576)$ \\
+  1 & 3 & 8 & 8 & 1 & 6 &   $10^2(2)(576) + 10^1(4)(576) + 10^0(1)(576)$ \\
+\hline  
+\end{tabular}
+\end{center}
+\caption{Long-Hand Multiplication Diagram}
+\end{figure}
+
+Each row of the product is added to the result after being shifted to the left (\textit{multiplied by a power of the radix}) by the appropriate 
+count.  That is in pass $ix$ of the inner loop the product is added starting at the $ix$'th digit of the reult.
+
+Step 5.4.1 introduces the hat symbol (\textit{e.g. $\hat r$}) which represents a double precision variable.  The multiplication on that step
+is assumed to be a double wide output single precision multiplication.  That is, two single precision variables are multiplied to produce a
+double precision result.  The step is somewhat optimized from a long-hand multiplication algorithm because the carry from the addition in step
+5.4.1 is propagated through the nested loop.  If the carry was not propagated immediately it would overflow the single precision digit 
+$t_{ix+iy}$ and the result would be lost.  
+
+At step 5.5 the nested loop is finished and any carry that was left over should be forwarded.  The carry does not have to be added to the $ix+pb$'th
+digit since that digit is assumed to be zero at this point.  However, if $ix + pb \ge digs$ the carry is not set as it would make the result
+exceed the precision requested.
+
+\vspace{+3mm}\begin{small}
+\hspace{-5.1mm}{\bf File}: bn\_s\_mp\_mul\_digs.c
+\vspace{-3mm}
+\begin{alltt}
+\end{alltt}
+\end{small}
+
+First we determine (line 31) if the Comba method can be used first since it's faster.  The conditions for 
+sing the Comba routine are that min$(a.used, b.used) < \delta$ and the number of digits of output is less than 
+\textbf{MP\_WARRAY}.  This new constant is used to control the stack usage in the Comba routines.  By default it is 
+set to $\delta$ but can be reduced when memory is at a premium.
+
+If we cannot use the Comba method we proceed to setup the baseline routine.  We allocate the the destination mp\_int
+$t$ (line 37) to the exact size of the output to avoid further re--allocations.  At this point we now 
+begin the $O(n^2)$ loop.
+
+This implementation of multiplication has the caveat that it can be trimmed to only produce a variable number of
+digits as output.  In each iteration of the outer loop the $pb$ variable is set (line 49) to the maximum 
+number of inner loop iterations.  
+
+Inside the inner loop we calculate $\hat r$ as the mp\_word product of the two mp\_digits and the addition of the
+carry from the previous iteration.  A particularly important observation is that most modern optimizing 
+C compilers (GCC for instance) can recognize that a $N \times N \rightarrow 2N$ multiplication is all that 
+is required for the product.  In x86 terms for example, this means using the MUL instruction.
+
+Each digit of the product is stored in turn (line 69) and the carry propagated (line 72) to the 
+next iteration.
+
+\subsection{Faster Multiplication by the ``Comba'' Method}
+
+One of the huge drawbacks of the ``baseline'' algorithms is that at the $O(n^2)$ level the carry must be 
+computed and propagated upwards.  This makes the nested loop very sequential and hard to unroll and implement 
+in parallel.  The ``Comba'' \cite{COMBA} method is named after little known (\textit{in cryptographic venues}) Paul G. 
+Comba who described a method of implementing fast multipliers that do not require nested carry fixup operations.  As an 
+interesting aside it seems that Paul Barrett describes a similar technique in his 1986 paper \cite{BARRETT} written 
+five years before.
+
+At the heart of the Comba technique is once again the long-hand algorithm.  Except in this case a slight 
+twist is placed on how the columns of the result are produced.  In the standard long-hand algorithm rows of products 
+are produced then added together to form the final result.  In the baseline algorithm the columns are added together 
+after each iteration to get the result instantaneously.  
+
+In the Comba algorithm the columns of the result are produced entirely independently of each other.  That is at 
+the $O(n^2)$ level a simple multiplication and addition step is performed.  The carries of the columns are propagated 
+after the nested loop to reduce the amount of work requiored. Succintly the first step of the algorithm is to compute 
+the product vector $\vec x$ as follows. 
+
+\begin{equation}
+\vec x_n = \sum_{i+j = n} a_ib_j, \forall n \in \lbrace 0, 1, 2, \ldots, i + j \rbrace
+\end{equation}
+
+Where $\vec x_n$ is the $n'th$ column of the output vector.  Consider the following example which computes the vector $\vec x$ for the multiplication
+of $576$ and $241$.  
+
+\newpage\begin{figure}[here]
+\begin{small}
+\begin{center}
+\begin{tabular}{|c|c|c|c|c|c|}
+  \hline &          & 5 & 7 & 6 & First Input\\
+  \hline $\times$ & & 2 & 4 & 1 & Second Input\\
+\hline            &                        & $1 \cdot 5 = 5$   & $1 \cdot 7 = 7$   & $1 \cdot 6 = 6$ & First pass \\
+                  &  $4 \cdot 5 = 20$      & $4 \cdot 7+5=33$  & $4 \cdot 6+7=31$  & 6               & Second pass \\
+   $2 \cdot 5 = 10$ &  $2 \cdot 7 + 20 = 34$ & $2 \cdot 6+33=45$ & 31                & 6             & Third pass \\
+\hline 10 & 34 & 45 & 31 & 6 & Final Result \\   
+\hline   
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Comba Multiplication Diagram}
+\end{figure}
+
+At this point the vector $x = \left < 10, 34, 45, 31, 6 \right >$ is the result of the first step of the Comba multipler.  
+Now the columns must be fixed by propagating the carry upwards.  The resultant vector will have one extra dimension over the input vector which is
+congruent to adding a leading zero digit.
+
+\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{Comba Fixup}. \\
+\textbf{Input}.   Vector $\vec x$ of dimension $k$ \\
+\textbf{Output}.  Vector $\vec x$ such that the carries have been propagated. \\
+\hline \\
+1.  for $n$ from $0$ to $k - 1$ do \\
+\hspace{3mm}1.1 $\vec x_{n+1} \leftarrow \vec x_{n+1} + \lfloor \vec x_{n}/\beta \rfloor$ \\
+\hspace{3mm}1.2 $\vec x_{n} \leftarrow \vec x_{n} \mbox{ (mod }\beta\mbox{)}$ \\
+2.  Return($\vec x$). \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Algorithm Comba Fixup}
+\end{figure}
+
+With that algorithm and $k = 5$ and $\beta = 10$ the following vector is produced $\vec x= \left < 1, 3, 8, 8, 1, 6 \right >$.  In this case 
+$241 \cdot 576$ is in fact $138816$ and the procedure succeeded.  If the algorithm is correct and as will be demonstrated shortly more
+efficient than the baseline algorithm why not simply always use this algorithm?
+
+\subsubsection{Column Weight.}
+At the nested $O(n^2)$ level the Comba method adds the product of two single precision variables to each column of the output 
+independently.  A serious obstacle is if the carry is lost, due to lack of precision before the algorithm has a chance to fix
+the carries.  For example, in the multiplication of two three-digit numbers the third column of output will be the sum of
+three single precision multiplications.  If the precision of the accumulator for the output digits is less then $3 \cdot (\beta - 1)^2$ then
+an overflow can occur and the carry information will be lost.  For any $m$ and $n$ digit inputs the maximum weight of any column is 
+min$(m, n)$ which is fairly obvious.
+
+The maximum number of terms in any column of a product is known as the ``column weight'' and strictly governs when the algorithm can be used.  Recall
+from earlier that a double precision type has $\alpha$ bits of resolution and a single precision digit has $lg(\beta)$ bits of precision.  Given these
+two quantities we must not violate the following
+
+\begin{equation}
+k \cdot \left (\beta - 1 \right )^2 < 2^{\alpha}
+\end{equation}
+
+Which reduces to 
+
+\begin{equation}
+k \cdot \left ( \beta^2 - 2\beta + 1 \right ) < 2^{\alpha}
+\end{equation}
+
+Let $\rho = lg(\beta)$ represent the number of bits in a single precision digit.  By further re-arrangement of the equation the final solution is
+found.
+
+\begin{equation}
+k  < {{2^{\alpha}} \over {\left (2^{2\rho} - 2^{\rho + 1} + 1 \right )}}
+\end{equation}
+
+The defaults for LibTomMath are $\beta = 2^{28}$ and $\alpha = 2^{64}$ which means that $k$ is bounded by $k < 257$.  In this configuration 
+the smaller input may not have more than $256$ digits if the Comba method is to be used.  This is quite satisfactory for most applications since 
+$256$ digits would allow for numbers in the range of $0 \le x < 2^{7168}$ which, is much larger than most public key cryptographic algorithms require.  
+
+\newpage\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{fast\_s\_mp\_mul\_digs}. \\
+\textbf{Input}.   mp\_int $a$, mp\_int $b$ and an integer $digs$ \\
+\textbf{Output}.  $c \leftarrow \vert a \vert \cdot \vert b \vert \mbox{ (mod }\beta^{digs}\mbox{)}$. \\
+\hline \\
+Place an array of \textbf{MP\_WARRAY} single precision digits named $W$ on the stack. \\
+1.  If $c.alloc < digs$ then grow $c$ to $digs$ digits. (\textit{mp\_grow}) \\
+2.  If step 1 failed return(\textit{MP\_MEM}).\\
+\\
+3.  $pa \leftarrow \mbox{MIN}(digs, a.used + b.used)$ \\
+\\
+4.  $\_ \hat W \leftarrow 0$ \\
+5.  for $ix$ from 0 to $pa - 1$ do \\
+\hspace{3mm}5.1  $ty \leftarrow \mbox{MIN}(b.used - 1, ix)$ \\
+\hspace{3mm}5.2  $tx \leftarrow ix - ty$ \\
+\hspace{3mm}5.3  $iy \leftarrow \mbox{MIN}(a.used - tx, ty + 1)$ \\
+\hspace{3mm}5.4  for $iz$ from 0 to $iy - 1$ do \\
+\hspace{6mm}5.4.1  $\_ \hat W \leftarrow \_ \hat W + a_{tx+iy}b_{ty-iy}$ \\
+\hspace{3mm}5.5  $W_{ix} \leftarrow \_ \hat W (\mbox{mod }\beta)$\\
+\hspace{3mm}5.6  $\_ \hat W \leftarrow \lfloor \_ \hat W / \beta \rfloor$ \\
+\\
+6.  $oldused \leftarrow c.used$ \\
+7.  $c.used \leftarrow digs$ \\
+8.  for $ix$ from $0$ to $pa$ do \\
+\hspace{3mm}8.1  $c_{ix} \leftarrow W_{ix}$ \\
+9.  for $ix$ from $pa + 1$ to $oldused - 1$ do \\
+\hspace{3mm}9.1 $c_{ix} \leftarrow 0$ \\
+\\
+10.  Clamp $c$. \\
+11.  Return MP\_OKAY. \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Algorithm fast\_s\_mp\_mul\_digs}
+\label{fig:COMBAMULT}
+\end{figure}
+
+\textbf{Algorithm fast\_s\_mp\_mul\_digs.}
+This algorithm performs the unsigned multiplication of $a$ and $b$ using the Comba method limited to $digs$ digits of precision.
+
+The outer loop of this algorithm is more complicated than that of the baseline multiplier.  This is because on the inside of the 
+loop we want to produce one column per pass.  This allows the accumulator $\_ \hat W$ to be placed in CPU registers and
+reduce the memory bandwidth to two \textbf{mp\_digit} reads per iteration.
+
+The $ty$ variable is set to the minimum count of $ix$ or the number of digits in $b$.  That way if $a$ has more digits than
+$b$ this will be limited to $b.used - 1$.  The $tx$ variable is set to the to the distance past $b.used$ the variable
+$ix$ is.  This is used for the immediately subsequent statement where we find $iy$.  
+
+The variable $iy$ is the minimum digits we can read from either $a$ or $b$ before running out.  Computing one column at a time
+means we have to scan one integer upwards and the other downwards.  $a$ starts at $tx$ and $b$ starts at $ty$.  In each
+pass we are producing the $ix$'th output column and we note that $tx + ty = ix$.  As we move $tx$ upwards we have to 
+move $ty$ downards so the equality remains valid.  The $iy$ variable is the number of iterations until 
+$tx \ge a.used$ or $ty < 0$ occurs.
+
+After every inner pass we store the lower half of the accumulator into $W_{ix}$ and then propagate the carry of the accumulator
+into the next round by dividing $\_ \hat W$ by $\beta$.
+
+To measure the benefits of the Comba method over the baseline method consider the number of operations that are required.  If the 
+cost in terms of time of a multiply and addition is $p$ and the cost of a carry propagation is $q$ then a baseline multiplication would require 
+$O \left ((p + q)n^2 \right )$ time to multiply two $n$-digit numbers.  The Comba method requires only $O(pn^2 + qn)$ time, however in practice, 
+the speed increase is actually much more.  With $O(n)$ space the algorithm can be reduced to $O(pn + qn)$ time by implementing the $n$ multiply
+and addition operations in the nested loop in parallel.  
+
+\vspace{+3mm}\begin{small}
+\hspace{-5.1mm}{\bf File}: bn\_fast\_s\_mp\_mul\_digs.c
+\vspace{-3mm}
+\begin{alltt}
+\end{alltt}
+\end{small}
+
+As per the pseudo--code we first calculate $pa$ (line 48) as the number of digits to output.  Next we begin the outer loop
+to produce the individual columns of the product.  We use the two aliases $tmpx$ and $tmpy$ (lines 62, 63) to point
+inside the two multiplicands quickly.  
+
+The inner loop (lines 71 to 74) of this implementation is where the tradeoff come into play.  Originally this comba 
+implementation was ``row--major'' which means it adds to each of the columns in each pass.  After the outer loop it would then fix 
+the carries.  This was very fast except it had an annoying drawback.  You had to read a mp\_word and two mp\_digits and write 
+one mp\_word per iteration.  On processors such as the Athlon XP and P4 this did not matter much since the cache bandwidth 
+is very high and it can keep the ALU fed with data.  It did, however, matter on older and embedded cpus where cache is often 
+slower and also often doesn't exist.  This new algorithm only performs two reads per iteration under the assumption that the 
+compiler has aliased $\_ \hat W$ to a CPU register.
+
+After the inner loop we store the current accumulator in $W$ and shift $\_ \hat W$ (lines 77, 80) to forward it as 
+a carry for the next pass.  After the outer loop we use the final carry (line 77) as the last digit of the product.  
+
+\subsection{Polynomial Basis Multiplication}
+To break the $O(n^2)$ barrier in multiplication requires a completely different look at integer multiplication.  In the following algorithms
+the use of polynomial basis representation for two integers $a$ and $b$ as $f(x) = \sum_{i=0}^{n} a_i x^i$ and  
+$g(x) = \sum_{i=0}^{n} b_i x^i$ respectively, is required.  In this system both $f(x)$ and $g(x)$ have $n + 1$ terms and are of the $n$'th degree.
+ 
+The product $a \cdot b \equiv f(x)g(x)$ is the polynomial $W(x) = \sum_{i=0}^{2n} w_i x^i$.  The coefficients $w_i$ will
+directly yield the desired product when $\beta$ is substituted for $x$.  The direct solution to solve for the $2n + 1$ coefficients
+requires $O(n^2)$ time and would in practice be slower than the Comba technique.
+
+However, numerical analysis theory indicates that only $2n + 1$ distinct points in $W(x)$ are required to determine the values of the $2n + 1$ unknown 
+coefficients.   This means by finding $\zeta_y = W(y)$ for $2n + 1$ small values of $y$ the coefficients of $W(x)$ can be found with 
+Gaussian elimination.  This technique is also occasionally refered to as the \textit{interpolation technique} (\textit{references please...}) since in 
+effect an interpolation based on $2n + 1$ points will yield a polynomial equivalent to $W(x)$.  
+
+The coefficients of the polynomial $W(x)$ are unknown which makes finding $W(y)$ for any value of $y$ impossible.  However, since 
+$W(x) = f(x)g(x)$ the equivalent $\zeta_y = f(y) g(y)$ can be used in its place.  The benefit of this technique stems from the 
+fact that $f(y)$ and $g(y)$ are much smaller than either $a$ or $b$ respectively.  As a result finding the $2n + 1$ relations required 
+by multiplying $f(y)g(y)$ involves multiplying integers that are much smaller than either of the inputs.
+
+When picking points to gather relations there are always three obvious points to choose, $y = 0, 1$ and $ \infty$.  The $\zeta_0$ term
+is simply the product $W(0) = w_0 = a_0 \cdot b_0$.  The $\zeta_1$ term is the product 
+$W(1) = \left (\sum_{i = 0}^{n} a_i \right ) \left (\sum_{i = 0}^{n} b_i \right )$.  The third point $\zeta_{\infty}$ is less obvious but rather
+simple to explain.  The $2n + 1$'th coefficient of $W(x)$ is numerically equivalent to the most significant column in an integer multiplication.  
+The point at $\infty$ is used symbolically to represent the most significant column, that is $W(\infty) = w_{2n} = a_nb_n$.  Note that the 
+points at $y = 0$ and $\infty$ yield the coefficients $w_0$ and $w_{2n}$ directly.
+
+If more points are required they should be of small values and powers of two such as $2^q$ and the related \textit{mirror points} 
+$\left (2^q \right )^{2n}  \cdot \zeta_{2^{-q}}$ for small values of $q$.  The term ``mirror point'' stems from the fact that 
+$\left (2^q \right )^{2n}  \cdot \zeta_{2^{-q}}$ can be calculated in the exact opposite fashion as $\zeta_{2^q}$.  For
+example, when $n = 2$ and $q = 1$ then following two equations are equivalent to the point $\zeta_{2}$ and its mirror.
+
+\begin{eqnarray}
+\zeta_{2}                  = f(2)g(2) = (4a_2 + 2a_1 + a_0)(4b_2 + 2b_1 + b_0) \nonumber \\
+16 \cdot \zeta_{1 \over 2} = 4f({1\over 2}) \cdot 4g({1 \over 2}) = (a_2 + 2a_1 + 4a_0)(b_2 + 2b_1 + 4b_0)
+\end{eqnarray}
+
+Using such points will allow the values of $f(y)$ and $g(y)$ to be independently calculated using only left shifts.  For example, when $n = 2$ the
+polynomial $f(2^q)$ is equal to $2^q((2^qa_2) + a_1) + a_0$.  This technique of polynomial representation is known as Horner's method.  
+
+As a general rule of the algorithm when the inputs are split into $n$ parts each there are $2n - 1$ multiplications.  Each multiplication is of 
+multiplicands that have $n$ times fewer digits than the inputs.  The asymptotic running time of this algorithm is 
+$O \left ( k^{lg_n(2n - 1)} \right )$ for $k$ digit inputs (\textit{assuming they have the same number of digits}).  Figure~\ref{fig:exponent}
+summarizes the exponents for various values of $n$.
+
+\begin{figure}
+\begin{center}
+\begin{tabular}{|c|c|c|}
+\hline \textbf{Split into $n$ Parts} & \textbf{Exponent}  & \textbf{Notes}\\
+\hline $2$ & $1.584962501$ & This is Karatsuba Multiplication. \\
+\hline $3$ & $1.464973520$ & This is Toom-Cook Multiplication. \\
+\hline $4$ & $1.403677461$ &\\
+\hline $5$ & $1.365212389$ &\\
+\hline $10$ & $1.278753601$ &\\
+\hline $100$ & $1.149426538$ &\\
+\hline $1000$ & $1.100270931$ &\\
+\hline $10000$ & $1.075252070$ &\\
+\hline
+\end{tabular}
+\end{center}
+\caption{Asymptotic Running Time of Polynomial Basis Multiplication}
+\label{fig:exponent}
+\end{figure}
+
+At first it may seem like a good idea to choose $n = 1000$ since the exponent is approximately $1.1$.  However, the overhead
+of solving for the 2001 terms of $W(x)$ will certainly consume any savings the algorithm could offer for all but exceedingly large
+numbers.  
+
+\subsubsection{Cutoff Point}
+The polynomial basis multiplication algorithms all require fewer single precision multiplications than a straight Comba approach.  However, 
+the algorithms incur an overhead (\textit{at the $O(n)$ work level}) since they require a system of equations to be solved.  This makes the
+polynomial basis approach more costly to use with small inputs.
+
+Let $m$ represent the number of digits in the multiplicands (\textit{assume both multiplicands have the same number of digits}).  There exists a 
+point $y$ such that when $m < y$ the polynomial basis algorithms are more costly than Comba, when $m = y$ they are roughly the same cost and 
+when $m > y$ the Comba methods are slower than the polynomial basis algorithms.  
+
+The exact location of $y$ depends on several key architectural elements of the computer platform in question.
+
+\begin{enumerate}
+\item  The ratio of clock cycles for single precision multiplication versus other simpler operations such as addition, shifting, etc.  For example
+on the AMD Athlon the ratio is roughly $17 : 1$ while on the Intel P4 it is $29 : 1$.  The higher the ratio in favour of multiplication the lower
+the cutoff point $y$ will be.  
+
+\item  The complexity of the linear system of equations (\textit{for the coefficients of $W(x)$}) is.  Generally speaking as the number of splits
+grows the complexity grows substantially.  Ideally solving the system will only involve addition, subtraction and shifting of integers.  This
+directly reflects on the ratio previous mentioned.
+
+\item  To a lesser extent memory bandwidth and function call overheads.  Provided the values are in the processor cache this is less of an
+influence over the cutoff point.
+
+\end{enumerate}
+
+A clean cutoff point separation occurs when a point $y$ is found such that all of the cutoff point conditions are met.  For example, if the point
+is too low then there will be values of $m$ such that $m > y$ and the Comba method is still faster.  Finding the cutoff points is fairly simple when
+a high resolution timer is available.  
+
+\subsection{Karatsuba Multiplication}
+Karatsuba \cite{KARA} multiplication when originally proposed in 1962 was among the first set of algorithms to break the $O(n^2)$ barrier for
+general purpose multiplication.  Given two polynomial basis representations $f(x) = ax + b$ and $g(x) = cx + d$, Karatsuba proved with 
+light algebra \cite{KARAP} that the following polynomial is equivalent to multiplication of the two integers the polynomials represent.
+
+\begin{equation}
+f(x) \cdot g(x) = acx^2 + ((a + b)(c + d) - (ac + bd))x + bd
+\end{equation}
+
+Using the observation that $ac$ and $bd$ could be re-used only three half sized multiplications would be required to produce the product.  Applying
+this algorithm recursively, the work factor becomes $O(n^{lg(3)})$ which is substantially better than the work factor $O(n^2)$ of the Comba technique.  It turns 
+out what Karatsuba did not know or at least did not publish was that this is simply polynomial basis multiplication with the points 
+$\zeta_0$, $\zeta_{\infty}$ and $\zeta_{1}$.  Consider the resultant system of equations.
+
+\begin{center}
+\begin{tabular}{rcrcrcrc}
+$\zeta_{0}$ &      $=$ &  &  &  & & $w_0$ \\
+$\zeta_{1}$ &      $=$ & $w_2$ & $+$ & $w_1$ & $+$ & $w_0$ \\
+$\zeta_{\infty}$ & $=$ & $w_2$ &  & &  & \\
+\end{tabular}
+\end{center}
+
+By adding the first and last equation to the equation in the middle the term $w_1$ can be isolated and all three coefficients solved for.  The simplicity
+of this system of equations has made Karatsuba fairly popular.  In fact the cutoff point is often fairly low\footnote{With LibTomMath 0.18 it is 70 and 109 digits for the Intel P4 and AMD Athlon respectively.}
+making it an ideal algorithm to speed up certain public key cryptosystems such as RSA and Diffie-Hellman.  
+
+\newpage\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{mp\_karatsuba\_mul}. \\
+\textbf{Input}.   mp\_int $a$ and mp\_int $b$ \\
+\textbf{Output}.  $c \leftarrow \vert a \vert \cdot \vert b \vert$ \\
+\hline \\
+1.  Init the following mp\_int variables: $x0$, $x1$, $y0$, $y1$, $t1$, $x0y0$, $x1y1$.\\
+2.  If step 2 failed then return(\textit{MP\_MEM}). \\
+\\
+Split the input.  e.g. $a = x1 \cdot \beta^B + x0$ \\
+3.  $B \leftarrow \mbox{min}(a.used, b.used)/2$ \\
+4.  $x0 \leftarrow a \mbox{ (mod }\beta^B\mbox{)}$ (\textit{mp\_mod\_2d}) \\
+5.  $y0 \leftarrow b \mbox{ (mod }\beta^B\mbox{)}$ \\
+6.  $x1 \leftarrow \lfloor a / \beta^B \rfloor$ (\textit{mp\_rshd}) \\
+7.  $y1 \leftarrow \lfloor b / \beta^B \rfloor$ \\
+\\
+Calculate the three products. \\
+8.  $x0y0 \leftarrow x0 \cdot y0$ (\textit{mp\_mul}) \\
+9.  $x1y1 \leftarrow x1 \cdot y1$ \\
+10.  $t1 \leftarrow x1 + x0$ (\textit{mp\_add}) \\
+11.  $x0 \leftarrow y1 + y0$ \\
+12.  $t1 \leftarrow t1 \cdot x0$ \\
+\\
+Calculate the middle term. \\
+13.  $x0 \leftarrow x0y0 + x1y1$ \\
+14.  $t1 \leftarrow t1 - x0$ (\textit{s\_mp\_sub}) \\
+\\
+Calculate the final product. \\
+15.  $t1 \leftarrow t1 \cdot \beta^B$ (\textit{mp\_lshd}) \\
+16.  $x1y1 \leftarrow x1y1 \cdot \beta^{2B}$ \\
+17.  $t1 \leftarrow x0y0 + t1$ \\
+18.  $c \leftarrow t1 + x1y1$ \\
+19.  Clear all of the temporary variables. \\
+20.  Return(\textit{MP\_OKAY}).\\
+\hline 
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Algorithm mp\_karatsuba\_mul}
+\end{figure}
+
+\textbf{Algorithm mp\_karatsuba\_mul.}
+This algorithm computes the unsigned product of two inputs using the Karatsuba multiplication algorithm.  It is loosely based on the description
+from Knuth \cite[pp. 294-295]{TAOCPV2}.  
+
+\index{radix point}
+In order to split the two inputs into their respective halves, a suitable \textit{radix point} must be chosen.  The radix point chosen must
+be used for both of the inputs meaning that it must be smaller than the smallest input.  Step 3 chooses the radix point $B$ as half of the 
+smallest input \textbf{used} count.  After the radix point is chosen the inputs are split into lower and upper halves.  Step 4 and 5 
+compute the lower halves.  Step 6 and 7 computer the upper halves.  
+
+After the halves have been computed the three intermediate half-size products must be computed.  Step 8 and 9 compute the trivial products
+$x0 \cdot y0$ and $x1 \cdot y1$.  The mp\_int $x0$ is used as a temporary variable after $x1 + x0$ has been computed.  By using $x0$ instead
+of an additional temporary variable, the algorithm can avoid an addition memory allocation operation.
+
+The remaining steps 13 through 18 compute the Karatsuba polynomial through a variety of digit shifting and addition operations.
+
+\vspace{+3mm}\begin{small}
+\hspace{-5.1mm}{\bf File}: bn\_mp\_karatsuba\_mul.c
+\vspace{-3mm}
+\begin{alltt}
+\end{alltt}
+\end{small}
+
+The new coding element in this routine, not  seen in previous routines, is the usage of goto statements.  The conventional
+wisdom is that goto statements should be avoided.  This is generally true, however when every single function call can fail, it makes sense
+to handle error recovery with a single piece of code.  Lines 62 to 76 handle initializing all of the temporary variables 
+required.  Note how each of the if statements goes to a different label in case of failure.  This allows the routine to correctly free only
+the temporaries that have been successfully allocated so far.
+
+The temporary variables are all initialized using the mp\_init\_size routine since they are expected to be large.  This saves the 
+additional reallocation that would have been necessary.  Also $x0$, $x1$, $y0$ and $y1$ have to be able to hold at least their respective
+number of digits for the next section of code.
+
+The first algebraic portion of the algorithm is to split the two inputs into their halves.  However, instead of using mp\_mod\_2d and mp\_rshd
+to extract the halves, the respective code has been placed inline within the body of the function.  To initialize the halves, the \textbf{used} and 
+\textbf{sign} members are copied first.  The first for loop on line 96 copies the lower halves.  Since they are both the same magnitude it 
+is simpler to calculate both lower halves in a single loop.  The for loop on lines 102 and 107 calculate the upper halves $x1$ and 
+$y1$ respectively.
+
+By inlining the calculation of the halves, the Karatsuba multiplier has a slightly lower overhead and can be used for smaller magnitude inputs.
+
+When line 151 is reached, the algorithm has completed succesfully.  The ``error status'' variable $err$ is set to \textbf{MP\_OKAY} so that
+the same code that handles errors can be used to clear the temporary variables and return.  
+
+\subsection{Toom-Cook $3$-Way Multiplication}
+Toom-Cook $3$-Way \cite{TOOM} multiplication is essentially the polynomial basis algorithm for $n = 2$ except that the points  are 
+chosen such that $\zeta$ is easy to compute and the resulting system of equations easy to reduce.  Here, the points $\zeta_{0}$, 
+$16 \cdot \zeta_{1 \over 2}$, $\zeta_1$, $\zeta_2$ and $\zeta_{\infty}$ make up the five required points to solve for the coefficients 
+of the $W(x)$.
+
+With the five relations that Toom-Cook specifies, the following system of equations is formed.
+
+\begin{center}
+\begin{tabular}{rcrcrcrcrcr}
+$\zeta_0$                    & $=$ & $0w_4$ & $+$ & $0w_3$ & $+$ & $0w_2$ & $+$ & $0w_1$ & $+$ & $1w_0$  \\
+$16 \cdot \zeta_{1 \over 2}$ & $=$ & $1w_4$ & $+$ & $2w_3$ & $+$ & $4w_2$ & $+$ & $8w_1$ & $+$ & $16w_0$  \\
+$\zeta_1$                    & $=$ & $1w_4$ & $+$ & $1w_3$ & $+$ & $1w_2$ & $+$ & $1w_1$ & $+$ & $1w_0$  \\
+$\zeta_2$                    & $=$ & $16w_4$ & $+$ & $8w_3$ & $+$ & $4w_2$ & $+$ & $2w_1$ & $+$ & $1w_0$  \\
+$\zeta_{\infty}$             & $=$ & $1w_4$ & $+$ & $0w_3$ & $+$ & $0w_2$ & $+$ & $0w_1$ & $+$ & $0w_0$  \\
+\end{tabular}
+\end{center}
+
+A trivial solution to this matrix requires $12$ subtractions, two multiplications by a small power of two, two divisions by a small power
+of two, two divisions by three and one multiplication by three.  All of these $19$ sub-operations require less than quadratic time, meaning that
+the algorithm can be faster than a baseline multiplication.  However, the greater complexity of this algorithm places the cutoff point
+(\textbf{TOOM\_MUL\_CUTOFF}) where Toom-Cook becomes more efficient much higher than the Karatsuba cutoff point.  
+
+\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{mp\_toom\_mul}. \\
+\textbf{Input}.   mp\_int $a$ and mp\_int $b$ \\
+\textbf{Output}.  $c \leftarrow  a  \cdot  b $ \\
+\hline \\
+Split $a$ and $b$ into three pieces.  E.g. $a = a_2 \beta^{2k} + a_1 \beta^{k} + a_0$ \\
+1.  $k \leftarrow \lfloor \mbox{min}(a.used, b.used) / 3 \rfloor$ \\
+2.  $a_0 \leftarrow a \mbox{ (mod }\beta^{k}\mbox{)}$ \\
+3.  $a_1 \leftarrow \lfloor a / \beta^k \rfloor$, $a_1 \leftarrow a_1 \mbox{ (mod }\beta^{k}\mbox{)}$ \\
+4.  $a_2 \leftarrow \lfloor a / \beta^{2k} \rfloor$, $a_2 \leftarrow a_2 \mbox{ (mod }\beta^{k}\mbox{)}$ \\
+5.  $b_0 \leftarrow a \mbox{ (mod }\beta^{k}\mbox{)}$ \\
+6.  $b_1 \leftarrow \lfloor a / \beta^k \rfloor$, $b_1 \leftarrow b_1 \mbox{ (mod }\beta^{k}\mbox{)}$ \\
+7.  $b_2 \leftarrow \lfloor a / \beta^{2k} \rfloor$, $b_2 \leftarrow b_2 \mbox{ (mod }\beta^{k}\mbox{)}$ \\
+\\
+Find the five equations for $w_0, w_1, ..., w_4$. \\
+8.  $w_0 \leftarrow a_0 \cdot b_0$ \\
+9.  $w_4 \leftarrow a_2 \cdot b_2$ \\
+10. $tmp_1 \leftarrow 2 \cdot a_0$, $tmp_1 \leftarrow a_1 + tmp_1$, $tmp_1 \leftarrow 2 \cdot tmp_1$, $tmp_1 \leftarrow tmp_1 + a_2$ \\
+11. $tmp_2 \leftarrow 2 \cdot b_0$, $tmp_2 \leftarrow b_1 + tmp_2$, $tmp_2 \leftarrow 2 \cdot tmp_2$, $tmp_2 \leftarrow tmp_2 + b_2$ \\
+12. $w_1 \leftarrow tmp_1 \cdot tmp_2$ \\
+13. $tmp_1 \leftarrow 2 \cdot a_2$, $tmp_1 \leftarrow a_1 + tmp_1$, $tmp_1 \leftarrow 2 \cdot tmp_1$, $tmp_1 \leftarrow tmp_1 + a_0$ \\
+14. $tmp_2 \leftarrow 2 \cdot b_2$, $tmp_2 \leftarrow b_1 + tmp_2$, $tmp_2 \leftarrow 2 \cdot tmp_2$, $tmp_2 \leftarrow tmp_2 + b_0$ \\
+15. $w_3 \leftarrow tmp_1 \cdot tmp_2$ \\
+16. $tmp_1 \leftarrow a_0 + a_1$, $tmp_1 \leftarrow tmp_1 + a_2$, $tmp_2 \leftarrow b_0 + b_1$, $tmp_2 \leftarrow tmp_2 + b_2$ \\
+17. $w_2 \leftarrow tmp_1 \cdot tmp_2$ \\
+\\
+Continued on the next page.\\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Algorithm mp\_toom\_mul}
+\end{figure}
+
+\newpage\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{mp\_toom\_mul} (continued). \\
+\textbf{Input}.   mp\_int $a$ and mp\_int $b$ \\
+\textbf{Output}.  $c \leftarrow a \cdot  b $ \\
+\hline \\
+Now solve the system of equations. \\
+18. $w_1 \leftarrow w_4 - w_1$, $w_3 \leftarrow w_3 - w_0$ \\
+19. $w_1 \leftarrow \lfloor w_1 / 2 \rfloor$, $w_3 \leftarrow \lfloor w_3 / 2 \rfloor$ \\
+20. $w_2 \leftarrow w_2 - w_0$, $w_2 \leftarrow w_2 - w_4$ \\
+21. $w_1 \leftarrow w_1 - w_2$, $w_3 \leftarrow w_3 - w_2$ \\
+22. $tmp_1 \leftarrow 8 \cdot w_0$, $w_1 \leftarrow w_1 - tmp_1$, $tmp_1 \leftarrow 8 \cdot w_4$, $w_3 \leftarrow w_3 - tmp_1$ \\
+23. $w_2 \leftarrow 3 \cdot w_2$, $w_2 \leftarrow w_2 - w_1$, $w_2 \leftarrow w_2 - w_3$ \\
+24. $w_1 \leftarrow w_1 - w_2$, $w_3 \leftarrow w_3 - w_2$ \\
+25. $w_1 \leftarrow \lfloor w_1 / 3 \rfloor, w_3 \leftarrow \lfloor w_3 / 3 \rfloor$ \\
+\\
+Now substitute $\beta^k$ for $x$ by shifting $w_0, w_1, ..., w_4$. \\
+26. for $n$ from $1$ to $4$ do \\
+\hspace{3mm}26.1  $w_n \leftarrow w_n \cdot \beta^{nk}$ \\
+27. $c \leftarrow w_0 + w_1$, $c \leftarrow c + w_2$, $c \leftarrow c + w_3$, $c \leftarrow c + w_4$ \\
+28. Return(\textit{MP\_OKAY}) \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Algorithm mp\_toom\_mul (continued)}
+\end{figure}
+
+\textbf{Algorithm mp\_toom\_mul.}
+This algorithm computes the product of two mp\_int variables $a$ and $b$ using the Toom-Cook approach.  Compared to the Karatsuba multiplication, this 
+algorithm has a lower asymptotic running time of approximately $O(n^{1.464})$ but at an obvious cost in overhead.  In this
+description, several statements have been compounded to save space.  The intention is that the statements are executed from left to right across
+any given step.
+
+The two inputs $a$ and $b$ are first split into three $k$-digit integers $a_0, a_1, a_2$ and $b_0, b_1, b_2$ respectively.  From these smaller
+integers the coefficients of the polynomial basis representations $f(x)$ and $g(x)$ are known and can be used to find the relations required.
+
+The first two relations $w_0$ and $w_4$ are the points $\zeta_{0}$ and $\zeta_{\infty}$ respectively.  The relation $w_1, w_2$ and $w_3$ correspond
+to the points $16 \cdot \zeta_{1 \over 2}, \zeta_{2}$ and $\zeta_{1}$ respectively.  These are found using logical shifts to independently find
+$f(y)$ and $g(y)$ which significantly speeds up the algorithm.
+
+After the five relations $w_0, w_1, \ldots, w_4$ have been computed, the system they represent must be solved in order for the unknown coefficients 
+$w_1, w_2$ and $w_3$ to be isolated.  The steps 18 through 25 perform the system reduction required as previously described.  Each step of
+the reduction represents the comparable matrix operation that would be performed had this been performed by pencil.  For example, step 18 indicates
+that row $1$ must be subtracted from row $4$ and simultaneously row $0$ subtracted from row $3$.  
+
+Once the coeffients have been isolated, the polynomial $W(x) = \sum_{i=0}^{2n} w_i x^i$ is known.  By substituting $\beta^{k}$ for $x$, the integer 
+result $a \cdot b$ is produced.
+
+\vspace{+3mm}\begin{small}
+\hspace{-5.1mm}{\bf File}: bn\_mp\_toom\_mul.c
+\vspace{-3mm}
+\begin{alltt}
+\end{alltt}
+\end{small}
+
+The first obvious thing to note is that this algorithm is complicated.  The complexity is worth it if you are multiplying very 
+large numbers.  For example, a 10,000 digit multiplication takes approximaly 99,282,205 fewer single precision multiplications with
+Toom--Cook than a Comba or baseline approach (this is a savings of more than 99$\%$).  For most ``crypto'' sized numbers this
+algorithm is not practical as Karatsuba has a much lower cutoff point.
+
+First we split $a$ and $b$ into three roughly equal portions.  This has been accomplished (lines 41 to 70) with 
+combinations of mp\_rshd() and mp\_mod\_2d() function calls.  At this point $a = a2 \cdot \beta^2 + a1 \cdot \beta + a0$ and similiarly
+for $b$.  
+
+Next we compute the five points $w0, w1, w2, w3$ and $w4$.  Recall that $w0$ and $w4$ can be computed directly from the portions so
+we get those out of the way first (lines 73 and 78).  Next we compute $w1, w2$ and $w3$ using Horners method.
+
+After this point we solve for the actual values of $w1, w2$ and $w3$ by reducing the $5 \times 5$ system which is relatively
+straight forward.  
+
+\subsection{Signed Multiplication}
+Now that algorithms to handle multiplications of every useful dimensions have been developed, a rather simple finishing touch is required.  So far all
+of the multiplication algorithms have been unsigned multiplications which leaves only a signed multiplication algorithm to be established.  
+
+\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{mp\_mul}. \\
+\textbf{Input}.   mp\_int $a$ and mp\_int $b$ \\
+\textbf{Output}.  $c \leftarrow a \cdot b$ \\
+\hline \\
+1.  If $a.sign = b.sign$ then \\
+\hspace{3mm}1.1  $sign = MP\_ZPOS$ \\
+2.  else \\
+\hspace{3mm}2.1  $sign = MP\_ZNEG$ \\
+3.  If min$(a.used, b.used) \ge TOOM\_MUL\_CUTOFF$ then  \\
+\hspace{3mm}3.1  $c \leftarrow a \cdot b$ using algorithm mp\_toom\_mul \\
+4.  else if min$(a.used, b.used) \ge KARATSUBA\_MUL\_CUTOFF$ then \\
+\hspace{3mm}4.1  $c \leftarrow a \cdot b$ using algorithm mp\_karatsuba\_mul \\
+5.  else \\
+\hspace{3mm}5.1  $digs \leftarrow a.used + b.used + 1$ \\
+\hspace{3mm}5.2  If $digs < MP\_ARRAY$ and min$(a.used, b.used) \le \delta$ then \\
+\hspace{6mm}5.2.1  $c \leftarrow a \cdot b \mbox{ (mod }\beta^{digs}\mbox{)}$ using algorithm fast\_s\_mp\_mul\_digs.  \\
+\hspace{3mm}5.3  else \\
+\hspace{6mm}5.3.1  $c \leftarrow a \cdot b \mbox{ (mod }\beta^{digs}\mbox{)}$ using algorithm s\_mp\_mul\_digs.  \\
+6.  $c.sign \leftarrow sign$ \\
+7.  Return the result of the unsigned multiplication performed. \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Algorithm mp\_mul}
+\end{figure}
+
+\textbf{Algorithm mp\_mul.}
+This algorithm performs the signed multiplication of two inputs.  It will make use of any of the three unsigned multiplication algorithms 
+available when the input is of appropriate size.  The \textbf{sign} of the result is not set until the end of the algorithm since algorithm
+s\_mp\_mul\_digs will clear it.  
+
+\vspace{+3mm}\begin{small}
+\hspace{-5.1mm}{\bf File}: bn\_mp\_mul.c
+\vspace{-3mm}
+\begin{alltt}
+\end{alltt}
+\end{small}
+
+The implementation is rather simplistic and is not particularly noteworthy.  Line 22 computes the sign of the result using the ``?'' 
+operator from the C programming language.  Line 48 computes $\delta$ using the fact that $1 << k$ is equal to $2^k$.  
+
+\section{Squaring}
+\label{sec:basesquare}
+
+Squaring is a special case of multiplication where both multiplicands are equal.  At first it may seem like there is no significant optimization
+available but in fact there is.  Consider the multiplication of $576$ against $241$.  In total there will be nine single precision multiplications
+performed which are $1\cdot 6$, $1 \cdot 7$, $1 \cdot 5$, $4 \cdot 6$, $4 \cdot 7$, $4 \cdot 5$, $2 \cdot  6$, $2 \cdot 7$ and $2 \cdot 5$.  Now consider 
+the multiplication of $123$ against $123$.  The nine products are $3 \cdot 3$, $3 \cdot 2$, $3 \cdot 1$, $2 \cdot 3$, $2 \cdot 2$, $2 \cdot 1$, 
+$1 \cdot 3$, $1 \cdot 2$ and $1 \cdot 1$.  On closer inspection some of the products are equivalent.  For example, $3 \cdot 2 = 2 \cdot 3$ 
+and $3 \cdot 1 = 1 \cdot 3$. 
+
+For any $n$-digit input, there are ${{\left (n^2 + n \right)}\over 2}$ possible unique single precision multiplications required compared to the $n^2$
+required for multiplication.  The following diagram gives an example of the operations required.
+
+\begin{figure}[here]
+\begin{center}
+\begin{tabular}{ccccc|c}
+&&1&2&3&\\
+$\times$ &&1&2&3&\\
+\hline && $3 \cdot 1$ & $3 \cdot 2$ & $3 \cdot 3$ & Row 0\\
+       & $2 \cdot 1$  & $2 \cdot 2$ & $2 \cdot 3$ && Row 1 \\
+         $1 \cdot 1$  & $1 \cdot 2$ & $1 \cdot 3$ &&& Row 2 \\
+\end{tabular}
+\end{center}
+\caption{Squaring Optimization Diagram}
+\end{figure}
+
+Starting from zero and numbering the columns from right to left a very simple pattern becomes obvious.  For the purposes of this discussion let $x$
+represent the number being squared.  The first observation is that in row $k$ the $2k$'th column of the product has a $\left (x_k \right)^2$ term in it.  
+
+The second observation is that every column $j$ in row $k$ where $j \ne 2k$ is part of a double product.  Every non-square term of a column will
+appear twice hence the name ``double product''.  Every odd column is made up entirely of double products.  In fact every column is made up of double 
+products and at most one square (\textit{see the exercise section}).  
+
+The third and final observation is that for row $k$ the first unique non-square term, that is, one that hasn't already appeared in an earlier row, 
+occurs at column $2k + 1$.  For example, on row $1$ of the previous squaring, column one is part of the double product with column one from row zero. 
+Column two of row one is a square and column three is the first unique column.
+
+\subsection{The Baseline Squaring Algorithm}
+The baseline squaring algorithm is meant to be a catch-all squaring algorithm.  It will handle any of the input sizes that the faster routines
+will not handle.  
+
+\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{s\_mp\_sqr}. \\
+\textbf{Input}.   mp\_int $a$ \\
+\textbf{Output}.  $b \leftarrow a^2$ \\
+\hline \\
+1.  Init a temporary mp\_int of at least $2 \cdot a.used +1$ digits.  (\textit{mp\_init\_size}) \\
+2.  If step 1 failed return(\textit{MP\_MEM}) \\
+3.  $t.used \leftarrow 2 \cdot a.used + 1$ \\
+4.  For $ix$ from 0 to $a.used - 1$ do \\
+\hspace{3mm}Calculate the square. \\
+\hspace{3mm}4.1  $\hat r \leftarrow t_{2ix} + \left (a_{ix} \right )^2$ \\
+\hspace{3mm}4.2  $t_{2ix} \leftarrow \hat r \mbox{ (mod }\beta\mbox{)}$ \\
+\hspace{3mm}Calculate the double products after the square. \\
+\hspace{3mm}4.3  $u \leftarrow \lfloor \hat r / \beta \rfloor$ \\
+\hspace{3mm}4.4  For $iy$ from $ix + 1$ to $a.used - 1$ do \\
+\hspace{6mm}4.4.1  $\hat r \leftarrow 2 \cdot a_{ix}a_{iy} + t_{ix + iy} + u$ \\
+\hspace{6mm}4.4.2  $t_{ix + iy} \leftarrow \hat r \mbox{ (mod }\beta\mbox{)}$ \\
+\hspace{6mm}4.4.3  $u \leftarrow \lfloor \hat r / \beta \rfloor$ \\
+\hspace{3mm}Set the last carry. \\
+\hspace{3mm}4.5  While $u > 0$ do \\
+\hspace{6mm}4.5.1  $iy \leftarrow iy + 1$ \\
+\hspace{6mm}4.5.2  $\hat r \leftarrow t_{ix + iy} + u$ \\
+\hspace{6mm}4.5.3  $t_{ix + iy} \leftarrow \hat r \mbox{ (mod }\beta\mbox{)}$ \\
+\hspace{6mm}4.5.4  $u \leftarrow \lfloor \hat r / \beta \rfloor$ \\
+5.  Clamp excess digits of $t$.  (\textit{mp\_clamp}) \\
+6.  Exchange $b$ and $t$. \\
+7.  Clear $t$ (\textit{mp\_clear}) \\
+8.  Return(\textit{MP\_OKAY}) \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Algorithm s\_mp\_sqr}
+\end{figure}
+
+\textbf{Algorithm s\_mp\_sqr.}
+This algorithm computes the square of an input using the three observations on squaring.  It is based fairly faithfully on  algorithm 14.16 of HAC
+\cite[pp.596-597]{HAC}.  Similar to algorithm s\_mp\_mul\_digs, a temporary mp\_int is allocated to hold the result of the squaring.  This allows the 
+destination mp\_int to be the same as the source mp\_int.
+
+The outer loop of this algorithm begins on step 4. It is best to think of the outer loop as walking down the rows of the partial results, while
+the inner loop computes the columns of the partial result.  Step 4.1 and 4.2 compute the square term for each row, and step 4.3 and 4.4 propagate
+the carry and compute the double products.  
+
+The requirement that a mp\_word be able to represent the range $0 \le x < 2 \beta^2$ arises from this
+very algorithm.  The product $a_{ix}a_{iy}$ will lie in the range $0 \le x \le \beta^2 - 2\beta + 1$ which is obviously less than $\beta^2$ meaning that
+when it is multiplied by two, it can be properly represented by a mp\_word.
+
+Similar to algorithm s\_mp\_mul\_digs, after every pass of the inner loop, the destination is correctly set to the sum of all of the partial 
+results calculated so far.  This involves expensive carry propagation which will be eliminated in the next algorithm.  
+
+\vspace{+3mm}\begin{small}
+\hspace{-5.1mm}{\bf File}: bn\_s\_mp\_sqr.c
+\vspace{-3mm}
+\begin{alltt}
+\end{alltt}
+\end{small}
+
+Inside the outer loop (line 34) the square term is calculated on line 37.  The carry (line 44) has been
+extracted from the mp\_word accumulator using a right shift.  Aliases for $a_{ix}$ and $t_{ix+iy}$ are initialized 
+(lines 47 and 50) to simplify the inner loop.  The doubling is performed using two
+additions (line 59) since it is usually faster than shifting, if not at least as fast.  
+
+The important observation is that the inner loop does not begin at $iy = 0$ like for multiplication.  As such the inner loops
+get progressively shorter as the algorithm proceeds.  This is what leads to the savings compared to using a multiplication to
+square a number. 
+
+\subsection{Faster Squaring by the ``Comba'' Method}
+A major drawback to the baseline method is the requirement for single precision shifting inside the $O(n^2)$ nested loop.  Squaring has an additional
+drawback that it must double the product inside the inner loop as well.  As for multiplication, the Comba technique can be used to eliminate these
+performance hazards.
+
+The first obvious solution is to make an array of mp\_words which will hold all of the columns.  This will indeed eliminate all of the carry
+propagation operations from the inner loop.  However, the inner product must still be doubled $O(n^2)$ times.  The solution stems from the simple fact
+that $2a + 2b + 2c = 2(a + b + c)$.  That is the sum of all of the double products is equal to double the sum of all the products.  For example,
+$ab + ba + ac + ca = 2ab + 2ac = 2(ab + ac)$.  
+
+However, we cannot simply double all of the columns, since the squares appear only once per row.  The most practical solution is to have two 
+mp\_word arrays.  One array will hold the squares and the other array will hold the double products.  With both arrays the doubling and 
+carry propagation can be moved to a $O(n)$ work level outside the $O(n^2)$ level.  In this case, we have an even simpler solution in mind.
+
+\newpage\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{fast\_s\_mp\_sqr}. \\
+\textbf{Input}.   mp\_int $a$ \\
+\textbf{Output}.  $b \leftarrow a^2$ \\
+\hline \\
+Place an array of \textbf{MP\_WARRAY} mp\_digits named $W$ on the stack. \\
+1.  If $b.alloc < 2a.used + 1$ then grow $b$ to $2a.used + 1$ digits.  (\textit{mp\_grow}). \\
+2.  If step 1 failed return(\textit{MP\_MEM}). \\
+\\
+3.  $pa \leftarrow 2 \cdot a.used$ \\
+4.  $\hat W1 \leftarrow 0$ \\
+5.  for $ix$ from $0$ to $pa - 1$ do \\
+\hspace{3mm}5.1  $\_ \hat W \leftarrow 0$ \\
+\hspace{3mm}5.2  $ty \leftarrow \mbox{MIN}(a.used - 1, ix)$ \\
+\hspace{3mm}5.3  $tx \leftarrow ix - ty$ \\
+\hspace{3mm}5.4  $iy \leftarrow \mbox{MIN}(a.used - tx, ty + 1)$ \\
+\hspace{3mm}5.5  $iy \leftarrow \mbox{MIN}(iy, \lfloor \left (ty - tx + 1 \right )/2 \rfloor)$ \\
+\hspace{3mm}5.6  for $iz$ from $0$ to $iz - 1$ do \\
+\hspace{6mm}5.6.1  $\_ \hat W \leftarrow \_ \hat W + a_{tx + iz}a_{ty - iz}$ \\
+\hspace{3mm}5.7  $\_ \hat W \leftarrow 2 \cdot \_ \hat W  + \hat W1$ \\
+\hspace{3mm}5.8  if $ix$ is even then \\
+\hspace{6mm}5.8.1  $\_ \hat W \leftarrow \_ \hat W + \left ( a_{\lfloor ix/2 \rfloor}\right )^2$ \\
+\hspace{3mm}5.9  $W_{ix} \leftarrow \_ \hat W (\mbox{mod }\beta)$ \\
+\hspace{3mm}5.10  $\hat W1 \leftarrow \lfloor \_ \hat W / \beta \rfloor$ \\
+\\
+6.  $oldused \leftarrow b.used$ \\
+7.  $b.used \leftarrow 2 \cdot a.used$ \\
+8.  for $ix$ from $0$ to $pa - 1$ do \\
+\hspace{3mm}8.1  $b_{ix} \leftarrow W_{ix}$ \\
+9.  for $ix$ from $pa$ to $oldused - 1$ do \\
+\hspace{3mm}9.1  $b_{ix} \leftarrow 0$ \\
+10.  Clamp excess digits from $b$.  (\textit{mp\_clamp}) \\
+11.  Return(\textit{MP\_OKAY}). \\ 
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Algorithm fast\_s\_mp\_sqr}
+\end{figure}
+
+\textbf{Algorithm fast\_s\_mp\_sqr.}
+This algorithm computes the square of an input using the Comba technique.  It is designed to be a replacement for algorithm 
+s\_mp\_sqr when the number of input digits is less than \textbf{MP\_WARRAY} and less than $\delta \over 2$.  
+This algorithm is very similar to the Comba multiplier except with a few key differences we shall make note of.
+
+First, we have an accumulator and carry variables $\_ \hat W$ and $\hat W1$ respectively.  This is because the inner loop
+products are to be doubled.  If we had added the previous carry in we would be doubling too much.  Next we perform an
+addition MIN condition on $iy$ (step 5.5) to prevent overlapping digits.  For example, $a_3 \cdot a_5$ is equal
+$a_5 \cdot a_3$.  Whereas in the multiplication case we would have $5 < a.used$ and $3 \ge 0$ is maintained since we double the sum
+of the products just outside the inner loop we have to avoid doing this.  This is also a good thing since we perform
+fewer multiplications and the routine ends up being faster.
+
+Finally the last difference is the addition of the ``square'' term outside the inner loop (step 5.8).  We add in the square
+only to even outputs and it is the square of the term at the $\lfloor ix / 2 \rfloor$ position.
+
+\vspace{+3mm}\begin{small}
+\hspace{-5.1mm}{\bf File}: bn\_fast\_s\_mp\_sqr.c
+\vspace{-3mm}
+\begin{alltt}
+\end{alltt}
+\end{small}
+
+This implementation is essentially a copy of Comba multiplication with the appropriate changes added to make it faster for 
+the special case of squaring.  
+
+\subsection{Polynomial Basis Squaring}
+The same algorithm that performs optimal polynomial basis multiplication can be used to perform polynomial basis squaring.  The minor exception
+is that $\zeta_y = f(y)g(y)$ is actually equivalent to $\zeta_y = f(y)^2$ since $f(y) = g(y)$.  Instead of performing $2n + 1$
+multiplications to find the $\zeta$ relations, squaring operations are performed instead.  
+
+\subsection{Karatsuba Squaring}
+Let $f(x) = ax + b$ represent the polynomial basis representation of a number to square.  
+Let $h(x) = \left ( f(x) \right )^2$ represent the square of the polynomial.  The Karatsuba equation can be modified to square a 
+number with the following equation.
+
+\begin{equation}
+h(x) = a^2x^2 + \left ((a + b)^2 - (a^2 + b^2) \right )x + b^2
+\end{equation}
+
+Upon closer inspection this equation only requires the calculation of three half-sized squares: $a^2$, $b^2$ and $(a + b)^2$.  As in 
+Karatsuba multiplication, this algorithm can be applied recursively on the input and will achieve an asymptotic running time of 
+$O \left ( n^{lg(3)} \right )$.
+
+If the asymptotic times of Karatsuba squaring and multiplication are the same, why not simply use the multiplication algorithm 
+instead?  The answer to this arises from the cutoff point for squaring.  As in multiplication there exists a cutoff point, at which the 
+time required for a Comba based squaring and a Karatsuba based squaring meet.  Due to the overhead inherent in the Karatsuba method, the cutoff 
+point is fairly high.  For example, on an AMD Athlon XP processor with $\beta = 2^{28}$, the cutoff point is around 127 digits.  
+
+Consider squaring a 200 digit number with this technique.  It will be split into two 100 digit halves which are subsequently squared.  
+The 100 digit halves will not be squared using Karatsuba, but instead using the faster Comba based squaring algorithm.  If Karatsuba multiplication
+were used instead, the 100 digit numbers would be squared with a slower Comba based multiplication.  
+
+\newpage\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{mp\_karatsuba\_sqr}. \\
+\textbf{Input}.   mp\_int $a$ \\
+\textbf{Output}.  $b \leftarrow a^2$ \\
+\hline \\
+1.  Initialize the following temporary mp\_ints:  $x0$, $x1$, $t1$, $t2$, $x0x0$ and $x1x1$. \\
+2.  If any of the initializations on step 1 failed return(\textit{MP\_MEM}). \\
+\\
+Split the input.  e.g. $a = x1\beta^B + x0$ \\
+3.  $B \leftarrow \lfloor a.used / 2 \rfloor$ \\
+4.  $x0 \leftarrow a \mbox{ (mod }\beta^B\mbox{)}$ (\textit{mp\_mod\_2d}) \\
+5.  $x1 \leftarrow \lfloor a / \beta^B \rfloor$ (\textit{mp\_lshd}) \\
+\\
+Calculate the three squares. \\
+6.  $x0x0 \leftarrow x0^2$ (\textit{mp\_sqr}) \\
+7.  $x1x1 \leftarrow x1^2$ \\
+8.  $t1 \leftarrow x1 + x0$ (\textit{s\_mp\_add}) \\
+9.  $t1 \leftarrow t1^2$ \\
+\\
+Compute the middle term. \\
+10.  $t2 \leftarrow x0x0 + x1x1$ (\textit{s\_mp\_add}) \\
+11.  $t1 \leftarrow t1 - t2$ \\
+\\
+Compute final product. \\
+12.  $t1 \leftarrow t1\beta^B$ (\textit{mp\_lshd}) \\
+13.  $x1x1 \leftarrow x1x1\beta^{2B}$ \\
+14.  $t1 \leftarrow t1 + x0x0$ \\
+15.  $b \leftarrow t1 + x1x1$ \\
+16.  Return(\textit{MP\_OKAY}). \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Algorithm mp\_karatsuba\_sqr}
+\end{figure}
+
+\textbf{Algorithm mp\_karatsuba\_sqr.}
+This algorithm computes the square of an input $a$ using the Karatsuba technique.  This algorithm is very similar to the Karatsuba based
+multiplication algorithm with the exception that the three half-size multiplications have been replaced with three half-size squarings.
+
+The radix point for squaring is simply placed exactly in the middle of the digits when the input has an odd number of digits, otherwise it is
+placed just below the middle.  Step 3, 4 and 5 compute the two halves required using $B$
+as the radix point.  The first two squares in steps 6 and 7 are rather straightforward while the last square is of a more compact form.
+
+By expanding $\left (x1 + x0 \right )^2$, the $x1^2$ and $x0^2$ terms in the middle disappear, that is $(x0 - x1)^2 - (x1^2 + x0^2)  = 2 \cdot x0 \cdot x1$.
+Now if $5n$ single precision additions and a squaring of $n$-digits is faster than multiplying two $n$-digit numbers and doubling then
+this method is faster.  Assuming no further recursions occur, the difference can be estimated with the following inequality.
+
+Let $p$ represent the cost of a single precision addition and $q$ the cost of a single precision multiplication both in terms of time\footnote{Or
+machine clock cycles.}. 
+
+\begin{equation}
+5pn +{{q(n^2 + n)} \over 2} \le pn + qn^2
+\end{equation}
+
+For example, on an AMD Athlon XP processor $p = {1 \over 3}$ and $q = 6$.  This implies that the following inequality should hold.
+\begin{center}
+\begin{tabular}{rcl}
+${5n \over 3} + 3n^2 + 3n$     & $<$ & ${n \over 3} + 6n^2$ \\
+${5 \over 3} + 3n + 3$     & $<$ & ${1 \over 3} + 6n$ \\
+${13 \over 9}$     & $<$ & $n$ \\
+\end{tabular}
+\end{center}
+
+This results in a cutoff point around $n = 2$.  As a consequence it is actually faster to compute the middle term the ``long way'' on processors
+where multiplication is substantially slower\footnote{On the Athlon there is a 1:17 ratio between clock cycles for addition and multiplication.  On
+the Intel P4 processor this ratio is 1:29 making this method even more beneficial.  The only common exception is the ARMv4 processor which has a
+ratio of 1:7.  } than simpler operations such as addition.  
+
+\vspace{+3mm}\begin{small}
+\hspace{-5.1mm}{\bf File}: bn\_mp\_karatsuba\_sqr.c
+\vspace{-3mm}
+\begin{alltt}
+\end{alltt}
+\end{small}
+
+This implementation is largely based on the implementation of algorithm mp\_karatsuba\_mul.  It uses the same inline style to copy and 
+shift the input into the two halves.  The loop from line 54 to line 70 has been modified since only one input exists.  The \textbf{used}
+count of both $x0$ and $x1$ is fixed up and $x0$ is clamped before the calculations begin.  At this point $x1$ and $x0$ are valid equivalents
+to the respective halves as if mp\_rshd and mp\_mod\_2d had been used.  
+
+By inlining the copy and shift operations the cutoff point for Karatsuba multiplication can be lowered.  On the Athlon the cutoff point
+is exactly at the point where Comba squaring can no longer be used (\textit{128 digits}).  On slower processors such as the Intel P4
+it is actually below the Comba limit (\textit{at 110 digits}).
+
+This routine uses the same error trap coding style as mp\_karatsuba\_sqr.  As the temporary variables are initialized errors are 
+redirected to the error trap higher up.  If the algorithm completes without error the error code is set to \textbf{MP\_OKAY} and 
+mp\_clears are executed normally.
+
+\subsection{Toom-Cook Squaring}
+The Toom-Cook squaring algorithm mp\_toom\_sqr is heavily based on the algorithm mp\_toom\_mul with the exception that squarings are used
+instead of multiplication to find the five relations.  The reader is encouraged to read the description of the latter algorithm and try to 
+derive their own Toom-Cook squaring algorithm.  
+
+\subsection{High Level Squaring}
+\newpage\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{mp\_sqr}. \\
+\textbf{Input}.   mp\_int $a$ \\
+\textbf{Output}.  $b \leftarrow a^2$ \\
+\hline \\
+1.  If $a.used \ge TOOM\_SQR\_CUTOFF$ then  \\
+\hspace{3mm}1.1  $b \leftarrow a^2$ using algorithm mp\_toom\_sqr \\
+2.  else if $a.used \ge KARATSUBA\_SQR\_CUTOFF$ then \\
+\hspace{3mm}2.1  $b \leftarrow a^2$ using algorithm mp\_karatsuba\_sqr \\
+3.  else \\
+\hspace{3mm}3.1  $digs \leftarrow a.used + b.used + 1$ \\
+\hspace{3mm}3.2  If $digs < MP\_ARRAY$ and $a.used \le \delta$ then \\
+\hspace{6mm}3.2.1  $b \leftarrow a^2$ using algorithm fast\_s\_mp\_sqr.  \\
+\hspace{3mm}3.3  else \\
+\hspace{6mm}3.3.1  $b \leftarrow a^2$ using algorithm s\_mp\_sqr.  \\
+4.  $b.sign \leftarrow MP\_ZPOS$ \\
+5.  Return the result of the unsigned squaring performed. \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Algorithm mp\_sqr}
+\end{figure}
+
+\textbf{Algorithm mp\_sqr.}
+This algorithm computes the square of the input using one of four different algorithms.  If the input is very large and has at least
+\textbf{TOOM\_SQR\_CUTOFF} or \textbf{KARATSUBA\_SQR\_CUTOFF} digits then either the Toom-Cook or the Karatsuba Squaring algorithm is used.  If
+neither of the polynomial basis algorithms should be used then either the Comba or baseline algorithm is used.  
+
+\vspace{+3mm}\begin{small}
+\hspace{-5.1mm}{\bf File}: bn\_mp\_sqr.c
+\vspace{-3mm}
+\begin{alltt}
+\end{alltt}
+\end{small}
+
+\section*{Exercises}
+\begin{tabular}{cl}
+$\left [ 3 \right ] $ & Devise an efficient algorithm for selection of the radix point to handle inputs \\
+                      & that have different number of digits in Karatsuba multiplication. \\
+                      & \\
+$\left [ 2 \right ] $ & In section 5.3 the fact that every column of a squaring is made up \\
+                      & of double products and at most one square is stated.  Prove this statement. \\
+                      & \\                      
+$\left [ 3 \right ] $ & Prove the equation for Karatsuba squaring. \\
+                      & \\
+$\left [ 1 \right ] $ & Prove that Karatsuba squaring requires $O \left (n^{lg(3)} \right )$ time. \\
+                      & \\ 
+$\left [ 2 \right ] $ & Determine the minimal ratio between addition and multiplication clock cycles \\
+                      & required for equation $6.7$ to be true.  \\
+                      & \\
+$\left [ 3 \right ] $ & Implement a threaded version of Comba multiplication (and squaring) where you \\
+                      & compute subsets of the columns in each thread.  Determine a cutoff point where \\
+                      & it is effective and add the logic to mp\_mul() and mp\_sqr(). \\
+                      &\\
+$\left [ 4 \right ] $ & Same as the previous but also modify the Karatsuba and Toom-Cook.  You must \\
+                      & increase the throughput of mp\_exptmod() for random odd moduli in the range \\
+                      & $512 \ldots 4096$ bits significantly ($> 2x$) to complete this challenge. \\
+                      & \\
+\end{tabular}
+
+\chapter{Modular Reduction}
+\section{Basics of Modular Reduction}
+\index{modular residue}
+Modular reduction is an operation that arises quite often within public key cryptography algorithms and various number theoretic algorithms, 
+such as factoring.  Modular reduction algorithms are the third class of algorithms of the ``multipliers'' set.  A number $a$ is said to be \textit{reduced}
+modulo another number $b$ by finding the remainder of the division $a/b$.  Full integer division with remainder is a topic to be covered 
+in~\ref{sec:division}.
+
+Modular reduction is equivalent to solving for $r$ in the following equation.  $a = bq + r$ where $q = \lfloor a/b \rfloor$.  The result 
+$r$ is said to be ``congruent to $a$ modulo $b$'' which is also written as $r \equiv a \mbox{ (mod }b\mbox{)}$.  In other vernacular $r$ is known as the 
+``modular residue'' which leads to ``quadratic residue''\footnote{That's fancy talk for $b \equiv a^2 \mbox{ (mod }p\mbox{)}$.} and
+other forms of residues.  
+
+Modular reductions are normally used to create either finite groups, rings or fields.  The most common usage for performance driven modular reductions 
+is in modular exponentiation algorithms.  That is to compute $d = a^b \mbox{ (mod }c\mbox{)}$ as fast as possible.  This operation is used in the 
+RSA and Diffie-Hellman public key algorithms, for example.  Modular multiplication and squaring also appears as a fundamental operation in 
+elliptic curve cryptographic algorithms.  As will be discussed in the subsequent chapter there exist fast algorithms for computing modular 
+exponentiations without having to perform (\textit{in this example}) $b - 1$ multiplications.  These algorithms will produce partial results in the 
+range $0 \le x < c^2$ which can be taken advantage of to create several efficient algorithms.   They have also been used to create redundancy check 
+algorithms known as CRCs, error correction codes such as Reed-Solomon and solve a variety of number theoeretic problems.  
+
+\section{The Barrett Reduction}
+The Barrett reduction algorithm \cite{BARRETT} was inspired by fast division algorithms which multiply by the reciprocal to emulate
+division.  Barretts observation was that the residue $c$ of $a$ modulo $b$ is equal to 
+
+\begin{equation}
+c = a - b \cdot \lfloor a/b \rfloor
+\end{equation}
+
+Since algorithms such as modular exponentiation would be using the same modulus extensively, typical DSP\footnote{It is worth noting that Barrett's paper 
+targeted the DSP56K processor.}  intuition would indicate the next step would be to replace $a/b$ by a multiplication by the reciprocal.  However, 
+DSP intuition on its own will not work as these numbers are considerably larger than the precision of common DSP floating point data types.  
+It would take another common optimization to optimize the algorithm.
+
+\subsection{Fixed Point Arithmetic}
+The trick used to optimize the above equation is based on a technique of emulating floating point data types with fixed precision integers.  Fixed
+point arithmetic would become very popular as it greatly optimize the ``3d-shooter'' genre of games in the mid 1990s when floating point units were 
+fairly slow if not unavailable.   The idea behind fixed point arithmetic is to take a normal $k$-bit integer data type and break it into $p$-bit 
+integer and a $q$-bit fraction part (\textit{where $p+q = k$}).  
+
+In this system a $k$-bit integer $n$ would actually represent $n/2^q$.  For example, with $q = 4$ the integer $n = 37$ would actually represent the
+value $2.3125$.  To multiply two fixed point numbers the integers are multiplied using traditional arithmetic and subsequently normalized by 
+moving the implied decimal point back to where it should be.  For example, with $q = 4$ to multiply the integers $9$ and $5$ they must be converted 
+to fixed point first by multiplying by $2^q$.  Let $a = 9(2^q)$ represent the fixed point representation of $9$ and $b = 5(2^q)$ represent the 
+fixed point representation of $5$.  The product $ab$ is equal to $45(2^{2q})$ which when normalized by dividing by $2^q$ produces $45(2^q)$.  
+
+This technique became popular since a normal integer multiplication and logical shift right are the only required operations to perform a multiplication
+of two fixed point numbers.  Using fixed point arithmetic, division can be easily approximated by multiplying by the reciprocal.  If $2^q$ is 
+equivalent to one than $2^q/b$ is equivalent to the fixed point approximation of $1/b$ using real arithmetic.  Using this fact dividing an integer 
+$a$ by another integer $b$ can be achieved with the following expression.
+
+\begin{equation}
+\lfloor a / b \rfloor \mbox{ }\approx\mbox{ } \lfloor (a \cdot \lfloor 2^q / b \rfloor)/2^q \rfloor
+\end{equation}
+
+The precision of the division is proportional to the value of $q$.  If the divisor $b$ is used frequently as is the case with 
+modular exponentiation pre-computing $2^q/b$ will allow a division to be performed with a multiplication and a right shift.  Both operations
+are considerably faster than division on most processors.  
+
+Consider dividing $19$ by $5$.  The correct result is $\lfloor 19/5 \rfloor = 3$.  With $q = 3$ the reciprocal is $\lfloor 2^q/5 \rfloor = 1$ which
+leads to a product of $19$ which when divided by $2^q$ produces $2$.  However, with $q = 4$ the reciprocal is $\lfloor 2^q/5 \rfloor = 3$ and
+the result of the emulated division is $\lfloor 3 \cdot 19 / 2^q \rfloor = 3$ which is correct.  The value of $2^q$ must be close to or ideally
+larger than the dividend.  In effect if $a$ is the dividend then $q$ should allow $0 \le \lfloor a/2^q \rfloor \le 1$ in order for this approach
+to work correctly.  Plugging this form of divison into the original equation the following modular residue equation arises.
+
+\begin{equation}
+c = a - b \cdot \lfloor (a \cdot \lfloor 2^q / b \rfloor)/2^q \rfloor
+\end{equation}
+
+Using the notation from \cite{BARRETT} the value of $\lfloor 2^q / b \rfloor$ will be represented by the $\mu$ symbol.  Using the $\mu$
+variable also helps re-inforce the idea that it is meant to be computed once and re-used.
+
+\begin{equation}
+c = a - b \cdot \lfloor (a \cdot \mu)/2^q \rfloor
+\end{equation}
+
+Provided that $2^q \ge a$ this algorithm will produce a quotient that is either exactly correct or off by a value of one.  In the context of Barrett
+reduction the value of $a$ is bound by $0 \le a \le (b - 1)^2$ meaning that $2^q \ge b^2$ is sufficient to ensure the reciprocal will have enough
+precision.  
+
+Let $n$ represent the number of digits in $b$.  This algorithm requires approximately $2n^2$ single precision multiplications to produce the quotient and 
+another $n^2$ single precision multiplications to find the residue.  In total $3n^2$ single precision multiplications are required to 
+reduce the number.  
+
+For example, if $b = 1179677$ and $q = 41$ ($2^q > b^2$), then the reciprocal $\mu$ is equal to $\lfloor 2^q / b \rfloor = 1864089$.  Consider reducing
+$a = 180388626447$ modulo $b$ using the above reduction equation.  The quotient using the new formula is $\lfloor (a \cdot \mu) / 2^q \rfloor = 152913$.
+By subtracting $152913b$ from $a$ the correct residue $a \equiv 677346 \mbox{ (mod }b\mbox{)}$ is found.
+
+\subsection{Choosing a Radix Point}
+Using the fixed point representation a modular reduction can be performed with $3n^2$ single precision multiplications.  If that were the best
+that could be achieved a full division\footnote{A division requires approximately $O(2cn^2)$ single precision multiplications for a small value of $c$.  
+See~\ref{sec:division} for further details.} might as well be used in its place.  The key to optimizing the reduction is to reduce the precision of
+the initial multiplication that finds the quotient.  
+
+Let $a$ represent the number of which the residue is sought.  Let $b$ represent the modulus used to find the residue.  Let $m$ represent
+the number of digits in $b$.  For the purposes of this discussion we will assume that the number of digits in $a$ is $2m$, which is generally true if 
+two $m$-digit numbers have been multiplied.  Dividing $a$ by $b$ is the same as dividing a $2m$ digit integer by a $m$ digit integer.  Digits below the 
+$m - 1$'th digit of $a$ will contribute at most a value of $1$ to the quotient because $\beta^k < b$ for any $0 \le k \le m - 1$.  Another way to
+express this is by re-writing $a$ as two parts.  If $a' \equiv a \mbox{ (mod }b^m\mbox{)}$ and $a'' = a - a'$ then 
+${a \over b} \equiv {{a' + a''} \over b}$ which is equivalent to ${a' \over b} + {a'' \over b}$.  Since $a'$ is bound to be less than $b$ the quotient
+is bound by $0 \le {a' \over b} < 1$.
+
+Since the digits of $a'$ do not contribute much to the quotient the observation is that they might as well be zero.  However, if the digits 
+``might as well be zero'' they might as well not be there in the first place.  Let $q_0 = \lfloor a/\beta^{m-1} \rfloor$ represent the input
+with the irrelevant digits trimmed.  Now the modular reduction is trimmed to the almost equivalent equation
+
+\begin{equation}
+c = a - b \cdot \lfloor (q_0 \cdot \mu) / \beta^{m+1} \rfloor
+\end{equation}
+
+Note that the original divisor $2^q$ has been replaced with $\beta^{m+1}$ where in this case $q$ is a multiple of $lg(\beta)$. Also note that the 
+exponent on the divisor when added to the amount $q_0$ was shifted by equals $2m$.  If the optimization had not been performed the divisor 
+would have the exponent $2m$ so in the end the exponents do ``add up''. Using the above equation the quotient 
+$\lfloor (q_0 \cdot \mu) / \beta^{m+1} \rfloor$ can be off from the true quotient by at most two.  The original fixed point quotient can be off
+by as much as one (\textit{provided the radix point is chosen suitably}) and now that the lower irrelevent digits have been trimmed the quotient
+can be off by an additional value of one for a total of at most two.  This implies that 
+$0 \le a - b \cdot \lfloor (q_0 \cdot \mu) / \beta^{m+1} \rfloor < 3b$.  By first subtracting $b$ times the quotient and then conditionally subtracting 
+$b$ once or twice the residue is found.
+
+The quotient is now found using $(m + 1)(m) = m^2 + m$ single precision multiplications and the residue with an additional $m^2$ single
+precision multiplications, ignoring the subtractions required.  In total $2m^2 + m$ single precision multiplications are required to find the residue.  
+This is considerably faster than the original attempt.
+
+For example, let $\beta = 10$ represent the radix of the digits.  Let $b = 9999$ represent the modulus which implies $m = 4$. Let $a = 99929878$ 
+represent the value of which the residue is desired.  In this case $q = 8$ since $10^7 < 9999^2$ meaning that $\mu = \lfloor \beta^{q}/b \rfloor = 10001$.  
+With the new observation the multiplicand for the quotient is equal to $q_0 = \lfloor a / \beta^{m - 1} \rfloor = 99929$.  The quotient is then 
+$\lfloor (q_0 \cdot \mu) / \beta^{m+1} \rfloor = 9993$.  Subtracting $9993b$ from $a$ and the correct residue $a \equiv 9871 \mbox{ (mod }b\mbox{)}$ 
+is found.  
+
+\subsection{Trimming the Quotient}
+So far the reduction algorithm has been optimized from $3m^2$ single precision multiplications down to $2m^2 + m$ single precision multiplications.  As 
+it stands now the algorithm is already fairly fast compared to a full integer division algorithm.  However, there is still room for
+optimization.  
+
+After the first multiplication inside the quotient ($q_0 \cdot \mu$) the value is shifted right by $m + 1$ places effectively nullifying the lower
+half of the product.  It would be nice to be able to remove those digits from the product to effectively cut down the number of single precision 
+multiplications.  If the number of digits in the modulus $m$ is far less than $\beta$ a full product is not required for the algorithm to work properly.  
+In fact the lower $m - 2$ digits will not affect the upper half of the product at all and do not need to be computed.  
+
+The value of $\mu$ is a $m$-digit number and $q_0$ is a $m + 1$ digit number.  Using a full multiplier $(m + 1)(m) = m^2 + m$ single precision
+multiplications would be required.  Using a multiplier that will only produce digits at and above the $m - 1$'th digit reduces the number
+of single precision multiplications to ${m^2 + m} \over 2$ single precision multiplications.  
+
+\subsection{Trimming the Residue}
+After the quotient has been calculated it is used to reduce the input.  As previously noted the algorithm is not exact and it can be off by a small
+multiple of the modulus, that is $0 \le a - b \cdot \lfloor (q_0 \cdot \mu) / \beta^{m+1} \rfloor < 3b$.  If $b$ is $m$ digits than the 
+result of reduction equation is a value of at most $m + 1$ digits (\textit{provided $3 < \beta$}) implying that the upper $m - 1$ digits are
+implicitly zero.  
+
+The next optimization arises from this very fact.  Instead of computing $b \cdot \lfloor (q_0 \cdot \mu) / \beta^{m+1} \rfloor$ using a full
+$O(m^2)$ multiplication algorithm only the lower $m+1$ digits of the product have to be computed.  Similarly the value of $a$ can
+be reduced modulo $\beta^{m+1}$ before the multiple of $b$ is subtracted which simplifes the subtraction as well.  A multiplication that produces 
+only the lower $m+1$ digits requires ${m^2 + 3m - 2} \over 2$ single precision multiplications.  
+
+With both optimizations in place the algorithm is the algorithm Barrett proposed.  It requires $m^2 + 2m - 1$ single precision multiplications which
+is considerably faster than the straightforward $3m^2$ method.  
+
+\subsection{The Barrett Algorithm}
+\newpage\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{mp\_reduce}. \\
+\textbf{Input}.   mp\_int $a$, mp\_int $b$ and $\mu = \lfloor \beta^{2m}/b \rfloor, m = \lceil lg_{\beta}(b) \rceil, (0 \le a < b^2, b > 1)$ \\
+\textbf{Output}.  $a \mbox{ (mod }b\mbox{)}$ \\
+\hline \\
+Let $m$ represent the number of digits in $b$.  \\
+1.  Make a copy of $a$ and store it in $q$.  (\textit{mp\_init\_copy}) \\
+2.  $q \leftarrow \lfloor q / \beta^{m - 1} \rfloor$ (\textit{mp\_rshd}) \\
+\\
+Produce the quotient. \\
+3.  $q \leftarrow q \cdot \mu$  (\textit{note: only produce digits at or above $m-1$}) \\
+4.  $q \leftarrow \lfloor q / \beta^{m + 1} \rfloor$ \\
+\\
+Subtract the multiple of modulus from the input. \\
+5.  $a \leftarrow a \mbox{ (mod }\beta^{m+1}\mbox{)}$ (\textit{mp\_mod\_2d}) \\
+6.  $q \leftarrow q \cdot b \mbox{ (mod }\beta^{m+1}\mbox{)}$ (\textit{s\_mp\_mul\_digs}) \\
+7.  $a \leftarrow a - q$ (\textit{mp\_sub}) \\
+\\
+Add $\beta^{m+1}$ if a carry occured. \\
+8.  If $a < 0$ then (\textit{mp\_cmp\_d}) \\
+\hspace{3mm}8.1  $q \leftarrow 1$ (\textit{mp\_set}) \\
+\hspace{3mm}8.2  $q \leftarrow q \cdot \beta^{m+1}$ (\textit{mp\_lshd}) \\
+\hspace{3mm}8.3  $a \leftarrow a + q$ \\
+\\
+Now subtract the modulus if the residue is too large (e.g. quotient too small). \\
+9.  While $a \ge b$ do (\textit{mp\_cmp}) \\
+\hspace{3mm}9.1  $c \leftarrow a - b$ \\
+10.  Clear $q$. \\
+11.  Return(\textit{MP\_OKAY}) \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Algorithm mp\_reduce}
+\end{figure}
+
+\textbf{Algorithm mp\_reduce.}
+This algorithm will reduce the input $a$ modulo $b$ in place using the Barrett algorithm.  It is loosely based on algorithm 14.42 of HAC
+\cite[pp.  602]{HAC} which is based on the paper from Paul Barrett \cite{BARRETT}.  The algorithm has several restrictions and assumptions which must 
+be adhered to for the algorithm to work.
+
+First the modulus $b$ is assumed to be positive and greater than one.  If the modulus were less than or equal to one than subtracting
+a multiple of it would either accomplish nothing or actually enlarge the input.  The input $a$ must be in the range $0 \le a < b^2$ in order
+for the quotient to have enough precision.  If $a$ is the product of two numbers that were already reduced modulo $b$, this will not be a problem.
+Technically the algorithm will still work if $a \ge b^2$ but it will take much longer to finish.  The value of $\mu$ is passed as an argument to this 
+algorithm and is assumed to be calculated and stored before the algorithm is used.  
+
+Recall that the multiplication for the quotient on step 3 must only produce digits at or above the $m-1$'th position.  An algorithm called 
+$s\_mp\_mul\_high\_digs$ which has not been presented is used to accomplish this task.  The algorithm is based on $s\_mp\_mul\_digs$ except that
+instead of stopping at a given level of precision it starts at a given level of precision.  This optimal algorithm can only be used if the number
+of digits in $b$ is very much smaller than $\beta$.  
+
+While it is known that 
+$a \ge b \cdot \lfloor (q_0 \cdot \mu) / \beta^{m+1} \rfloor$ only the lower $m+1$ digits are being used to compute the residue, so an implied 
+``borrow'' from the higher digits might leave a negative result.  After the multiple of the modulus has been subtracted from $a$ the residue must be 
+fixed up in case it is negative.  The invariant $\beta^{m+1}$ must be added to the residue to make it positive again.  
+
+The while loop at step 9 will subtract $b$ until the residue is less than $b$.  If the algorithm is performed correctly this step is 
+performed at most twice, and on average once. However, if $a \ge b^2$ than it will iterate substantially more times than it should.
+
+\vspace{+3mm}\begin{small}
+\hspace{-5.1mm}{\bf File}: bn\_mp\_reduce.c
+\vspace{-3mm}
+\begin{alltt}
+\end{alltt}
+\end{small}
+
+The first multiplication that determines the quotient can be performed by only producing the digits from $m - 1$ and up.  This essentially halves
+the number of single precision multiplications required.  However, the optimization is only safe if $\beta$ is much larger than the number of digits
+in the modulus.  In the source code this is evaluated on lines 36 to 44 where algorithm s\_mp\_mul\_high\_digs is used when it is
+safe to do so.  
+
+\subsection{The Barrett Setup Algorithm}
+In order to use algorithm mp\_reduce the value of $\mu$ must be calculated in advance.  Ideally this value should be computed once and stored for
+future use so that the Barrett algorithm can be used without delay.  
+
+\newpage\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{mp\_reduce\_setup}. \\
+\textbf{Input}.   mp\_int $a$ ($a > 1$)  \\
+\textbf{Output}.  $\mu \leftarrow \lfloor \beta^{2m}/a \rfloor$ \\
+\hline \\
+1.  $\mu \leftarrow 2^{2 \cdot lg(\beta) \cdot  m}$ (\textit{mp\_2expt}) \\
+2.  $\mu \leftarrow \lfloor \mu / b \rfloor$ (\textit{mp\_div}) \\
+3.  Return(\textit{MP\_OKAY}) \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Algorithm mp\_reduce\_setup}
+\end{figure}
+
+\textbf{Algorithm mp\_reduce\_setup.}
+This algorithm computes the reciprocal $\mu$ required for Barrett reduction.  First $\beta^{2m}$ is calculated as $2^{2 \cdot lg(\beta) \cdot  m}$ which
+is equivalent and much faster.  The final value is computed by taking the integer quotient of $\lfloor \mu / b \rfloor$.
+
+\vspace{+3mm}\begin{small}
+\hspace{-5.1mm}{\bf File}: bn\_mp\_reduce\_setup.c
+\vspace{-3mm}
+\begin{alltt}
+\end{alltt}
+\end{small}
+
+This simple routine calculates the reciprocal $\mu$ required by Barrett reduction.  Note the extended usage of algorithm mp\_div where the variable
+which would received the remainder is passed as NULL.  As will be discussed in~\ref{sec:division} the division routine allows both the quotient and the 
+remainder to be passed as NULL meaning to ignore the value.  
+
+\section{The Montgomery Reduction}
+Montgomery reduction\footnote{Thanks to Niels Ferguson for his insightful explanation of the algorithm.} \cite{MONT} is by far the most interesting 
+form of reduction in common use.  It computes a modular residue which is not actually equal to the residue of the input yet instead equal to a 
+residue times a constant.  However, as perplexing as this may sound the algorithm is relatively simple and very efficient.  
+
+Throughout this entire section the variable $n$ will represent the modulus used to form the residue.  As will be discussed shortly the value of
+$n$ must be odd.  The variable $x$ will represent the quantity of which the residue is sought.  Similar to the Barrett algorithm the input
+is restricted to $0 \le x < n^2$.  To begin the description some simple number theory facts must be established.
+
+\textbf{Fact 1.}  Adding $n$ to $x$ does not change the residue since in effect it adds one to the quotient $\lfloor x / n \rfloor$.  Another way
+to explain this is that $n$ is (\textit{or multiples of $n$ are}) congruent to zero modulo $n$.  Adding zero will not change the value of the residue.  
+
+\textbf{Fact 2.}  If $x$ is even then performing a division by two in $\Z$ is congruent to $x \cdot 2^{-1} \mbox{ (mod }n\mbox{)}$.  Actually
+this is an application of the fact that if $x$ is evenly divisible by any $k \in \Z$ then division in $\Z$ will be congruent to 
+multiplication by $k^{-1}$ modulo $n$.  
+
+From these two simple facts the following simple algorithm can be derived.
+
+\newpage\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{Montgomery Reduction}. \\
+\textbf{Input}.   Integer $x$, $n$ and $k$ \\
+\textbf{Output}.  $2^{-k}x \mbox{ (mod }n\mbox{)}$ \\
+\hline \\
+1.  for $t$ from $1$ to $k$ do \\
+\hspace{3mm}1.1  If $x$ is odd then \\
+\hspace{6mm}1.1.1  $x \leftarrow x + n$ \\
+\hspace{3mm}1.2  $x \leftarrow x/2$ \\
+2.  Return $x$. \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Algorithm Montgomery Reduction}
+\end{figure}
+
+The algorithm reduces the input one bit at a time using the two congruencies stated previously.  Inside the loop $n$, which is odd, is
+added to $x$ if $x$ is odd.  This forces $x$ to be even which allows the division by two in $\Z$ to be congruent to a modular division by two.  Since
+$x$ is assumed to be initially much larger than $n$ the addition of $n$ will contribute an insignificant magnitude to $x$.  Let $r$ represent the 
+final result of the Montgomery algorithm.  If $k > lg(n)$ and $0 \le x < n^2$ then the final result is limited to 
+$0 \le r < \lfloor x/2^k \rfloor + n$.  As a result at most a single subtraction is required to get the residue desired.
+
+\begin{figure}[here]
+\begin{small}
+\begin{center}
+\begin{tabular}{|c|l|}
+\hline \textbf{Step number ($t$)} & \textbf{Result ($x$)} \\
+\hline $1$ & $x + n = 5812$, $x/2 = 2906$ \\
+\hline $2$ & $x/2 = 1453$ \\
+\hline $3$ & $x + n = 1710$, $x/2 = 855$ \\
+\hline $4$ & $x + n = 1112$, $x/2 = 556$ \\
+\hline $5$ & $x/2 = 278$ \\
+\hline $6$ & $x/2 = 139$ \\
+\hline $7$ & $x + n = 396$, $x/2 = 198$ \\
+\hline $8$ & $x/2 = 99$ \\
+\hline $9$ & $x + n = 356$, $x/2 = 178$ \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Example of Montgomery Reduction (I)}
+\label{fig:MONT1}
+\end{figure}
+
+Consider the example in figure~\ref{fig:MONT1} which reduces $x = 5555$ modulo $n = 257$ when $k = 9$ (note $\beta^k = 512$ which is larger than $n$).  The result of 
+the algorithm $r = 178$ is congruent to the value of $2^{-9} \cdot 5555 \mbox{ (mod }257\mbox{)}$.  When $r$ is multiplied by $2^9$ modulo $257$ the correct residue 
+$r \equiv 158$ is produced.  
+
+Let $k = \lfloor lg(n) \rfloor + 1$ represent the number of bits in $n$.  The current algorithm requires $2k^2$ single precision shifts
+and $k^2$ single precision additions.  At this rate the algorithm is most certainly slower than Barrett reduction and not terribly useful.  
+Fortunately there exists an alternative representation of the algorithm.
+
+\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{Montgomery Reduction} (modified I). \\
+\textbf{Input}.   Integer $x$, $n$ and $k$ ($2^k > n$) \\
+\textbf{Output}.  $2^{-k}x \mbox{ (mod }n\mbox{)}$ \\
+\hline \\
+1.  for $t$ from $1$ to $k$ do \\
+\hspace{3mm}1.1  If the $t$'th bit of $x$ is one then \\
+\hspace{6mm}1.1.1  $x \leftarrow x + 2^tn$ \\
+2.  Return $x/2^k$. \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Algorithm Montgomery Reduction (modified I)}
+\end{figure}
+
+This algorithm is equivalent since $2^tn$ is a multiple of $n$ and the lower $k$ bits of $x$ are zero by step 2.  The number of single
+precision shifts has now been reduced from $2k^2$ to $k^2 + k$ which is only a small improvement.
+
+\begin{figure}[here]
+\begin{small}
+\begin{center}
+\begin{tabular}{|c|l|r|}
+\hline \textbf{Step number ($t$)} & \textbf{Result ($x$)} & \textbf{Result ($x$) in Binary} \\
+\hline -- & $5555$ & $1010110110011$ \\
+\hline $1$ & $x + 2^{0}n = 5812$ &  $1011010110100$ \\
+\hline $2$ & $5812$ & $1011010110100$ \\
+\hline $3$ & $x + 2^{2}n = 6840$ & $1101010111000$ \\
+\hline $4$ & $x + 2^{3}n = 8896$ & $10001011000000$ \\
+\hline $5$ & $8896$ & $10001011000000$ \\
+\hline $6$ & $8896$ & $10001011000000$ \\
+\hline $7$ & $x + 2^{6}n = 25344$ & $110001100000000$ \\
+\hline $8$ & $25344$ & $110001100000000$ \\
+\hline $9$ & $x + 2^{7}n = 91136$ & $10110010000000000$ \\
+\hline -- & $x/2^k = 178$ & \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Example of Montgomery Reduction (II)}
+\label{fig:MONT2}
+\end{figure}
+
+Figure~\ref{fig:MONT2} demonstrates the modified algorithm reducing $x = 5555$ modulo $n = 257$ with $k = 9$. 
+With this algorithm a single shift right at the end is the only right shift required to reduce the input instead of $k$ right shifts inside the 
+loop.  Note that for the iterations $t = 2, 5, 6$ and $8$ where the result $x$ is not changed.  In those iterations the $t$'th bit of $x$ is 
+zero and the appropriate multiple of $n$ does not need to be added to force the $t$'th bit of the result to zero.  
+
+\subsection{Digit Based Montgomery Reduction}
+Instead of computing the reduction on a bit-by-bit basis it is actually much faster to compute it on digit-by-digit basis.  Consider the
+previous algorithm re-written to compute the Montgomery reduction in this new fashion.
+
+\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{Montgomery Reduction} (modified II). \\
+\textbf{Input}.   Integer $x$, $n$ and $k$ ($\beta^k > n$) \\
+\textbf{Output}.  $\beta^{-k}x \mbox{ (mod }n\mbox{)}$ \\
+\hline \\
+1.  for $t$ from $0$ to $k - 1$ do \\
+\hspace{3mm}1.1  $x \leftarrow x + \mu n \beta^t$ \\
+2.  Return $x/\beta^k$. \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Algorithm Montgomery Reduction (modified II)}
+\end{figure}
+
+The value $\mu n \beta^t$ is a multiple of the modulus $n$ meaning that it will not change the residue.  If the first digit of 
+the value $\mu n \beta^t$ equals the negative (modulo $\beta$) of the $t$'th digit of $x$ then the addition will result in a zero digit.  This
+problem breaks down to solving the following congruency.  
+
+\begin{center}
+\begin{tabular}{rcl}
+$x_t + \mu n_0$ & $\equiv$ & $0 \mbox{ (mod }\beta\mbox{)}$ \\
+$\mu n_0$ & $\equiv$ & $-x_t \mbox{ (mod }\beta\mbox{)}$ \\
+$\mu$ & $\equiv$ & $-x_t/n_0 \mbox{ (mod }\beta\mbox{)}$ \\
+\end{tabular}
+\end{center}
+
+In each iteration of the loop on step 1 a new value of $\mu$ must be calculated.  The value of $-1/n_0 \mbox{ (mod }\beta\mbox{)}$ is used 
+extensively in this algorithm and should be precomputed.  Let $\rho$ represent the negative of the modular inverse of $n_0$ modulo $\beta$.  
+
+For example, let $\beta = 10$ represent the radix.  Let $n = 17$ represent the modulus which implies $k = 2$ and $\rho \equiv 7$.  Let $x = 33$ 
+represent the value to reduce.
+
+\newpage\begin{figure}
+\begin{center}
+\begin{tabular}{|c|c|c|}
+\hline \textbf{Step ($t$)} & \textbf{Value of $x$} & \textbf{Value of $\mu$} \\
+\hline --                 & $33$ & --\\
+\hline $0$                 & $33 + \mu n = 50$ & $1$ \\
+\hline $1$                 & $50 + \mu n \beta = 900$ & $5$ \\
+\hline
+\end{tabular}
+\end{center}
+\caption{Example of Montgomery Reduction}
+\end{figure}
+
+The final result $900$ is then divided by $\beta^k$ to produce the final result $9$.  The first observation is that $9 \nequiv x \mbox{ (mod }n\mbox{)}$ 
+which implies the result is not the modular residue of $x$ modulo $n$.  However, recall that the residue is actually multiplied by $\beta^{-k}$ in
+the algorithm.  To get the true residue the value must be multiplied by $\beta^k$.  In this case $\beta^k \equiv 15 \mbox{ (mod }n\mbox{)}$ and
+the correct residue is $9 \cdot 15 \equiv 16 \mbox{ (mod }n\mbox{)}$.  
+
+\subsection{Baseline Montgomery Reduction}
+The baseline Montgomery reduction algorithm will produce the residue for any size input.  It is designed to be a catch-all algororithm for 
+Montgomery reductions.  
+
+\newpage\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{mp\_montgomery\_reduce}. \\
+\textbf{Input}.   mp\_int $x$, mp\_int $n$ and a digit $\rho \equiv -1/n_0 \mbox{ (mod }n\mbox{)}$. \\
+\hspace{11.5mm}($0 \le x < n^2, n > 1, (n, \beta) = 1, \beta^k > n$) \\
+\textbf{Output}.  $\beta^{-k}x \mbox{ (mod }n\mbox{)}$ \\
+\hline \\
+1.  $digs \leftarrow 2n.used + 1$ \\
+2.  If $digs < MP\_ARRAY$ and $m.used < \delta$ then \\
+\hspace{3mm}2.1  Use algorithm fast\_mp\_montgomery\_reduce instead. \\
+\\
+Setup $x$ for the reduction. \\
+3.  If $x.alloc < digs$ then grow $x$ to $digs$ digits. \\
+4.  $x.used \leftarrow digs$ \\
+\\
+Eliminate the lower $k$ digits. \\
+5.  For $ix$ from $0$ to $k - 1$ do \\
+\hspace{3mm}5.1  $\mu \leftarrow x_{ix} \cdot \rho \mbox{ (mod }\beta\mbox{)}$ \\
+\hspace{3mm}5.2  $u \leftarrow 0$ \\
+\hspace{3mm}5.3  For $iy$ from $0$ to $k - 1$ do \\
+\hspace{6mm}5.3.1  $\hat r \leftarrow \mu n_{iy} + x_{ix + iy} + u$ \\
+\hspace{6mm}5.3.2  $x_{ix + iy} \leftarrow \hat r \mbox{ (mod }\beta\mbox{)}$ \\
+\hspace{6mm}5.3.3  $u \leftarrow \lfloor \hat r / \beta \rfloor$ \\
+\hspace{3mm}5.4  While $u > 0$ do \\
+\hspace{6mm}5.4.1  $iy \leftarrow iy + 1$ \\
+\hspace{6mm}5.4.2  $x_{ix + iy} \leftarrow x_{ix + iy} + u$ \\
+\hspace{6mm}5.4.3  $u \leftarrow \lfloor x_{ix+iy} / \beta \rfloor$ \\
+\hspace{6mm}5.4.4  $x_{ix + iy} \leftarrow x_{ix+iy} \mbox{ (mod }\beta\mbox{)}$ \\
+\\
+Divide by $\beta^k$ and fix up as required. \\
+6.  $x \leftarrow \lfloor x / \beta^k \rfloor$ \\
+7.  If $x \ge n$ then \\
+\hspace{3mm}7.1  $x \leftarrow x - n$ \\
+8.  Return(\textit{MP\_OKAY}). \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Algorithm mp\_montgomery\_reduce}
+\end{figure}
+
+\textbf{Algorithm mp\_montgomery\_reduce.}
+This algorithm reduces the input $x$ modulo $n$ in place using the Montgomery reduction algorithm.  The algorithm is loosely based
+on algorithm 14.32 of \cite[pp.601]{HAC} except it merges the multiplication of $\mu n \beta^t$ with the addition in the inner loop.  The
+restrictions on this algorithm are fairly easy to adapt to.  First $0 \le x < n^2$ bounds the input to numbers in the same range as 
+for the Barrett algorithm.  Additionally if $n > 1$ and $n$ is odd there will exist a modular inverse $\rho$.  $\rho$ must be calculated in
+advance of this algorithm.  Finally the variable $k$ is fixed and a pseudonym for $n.used$.  
+
+Step 2 decides whether a faster Montgomery algorithm can be used.  It is based on the Comba technique meaning that there are limits on
+the size of the input.  This algorithm is discussed in sub-section 6.3.3.
+
+Step 5 is the main reduction loop of the algorithm.  The value of $\mu$ is calculated once per iteration in the outer loop.  The inner loop
+calculates $x + \mu n \beta^{ix}$ by multiplying $\mu n$ and adding the result to $x$ shifted by $ix$ digits.  Both the addition and
+multiplication are performed in the same loop to save time and memory.  Step 5.4 will handle any additional carries that escape the inner loop.
+
+Using a quick inspection this algorithm requires $n$ single precision multiplications for the outer loop and $n^2$ single precision multiplications 
+in the inner loop.  In total $n^2 + n$ single precision multiplications which compares favourably to Barrett at $n^2 + 2n - 1$ single precision
+multiplications.  
+
+\vspace{+3mm}\begin{small}
+\hspace{-5.1mm}{\bf File}: bn\_mp\_montgomery\_reduce.c
+\vspace{-3mm}
+\begin{alltt}
+\end{alltt}
+\end{small}
+
+This is the baseline implementation of the Montgomery reduction algorithm.  Lines 31 to 36 determine if the Comba based
+routine can be used instead.  Line 47 computes the value of $\mu$ for that particular iteration of the outer loop.  
+
+The multiplication $\mu n \beta^{ix}$ is performed in one step in the inner loop.  The alias $tmpx$ refers to the $ix$'th digit of $x$ and
+the alias $tmpn$ refers to the modulus $n$.  
+
+\subsection{Faster ``Comba'' Montgomery Reduction}
+
+The Montgomery reduction requires fewer single precision multiplications than a Barrett reduction, however it is much slower due to the serial
+nature of the inner loop.  The Barrett reduction algorithm requires two slightly modified multipliers which can be implemented with the Comba
+technique.  The Montgomery reduction algorithm cannot directly use the Comba technique to any significant advantage since the inner loop calculates
+a $k \times 1$ product $k$ times. 
+
+The biggest obstacle is that at the $ix$'th iteration of the outer loop the value of $x_{ix}$ is required to calculate $\mu$.  This means the 
+carries from $0$ to $ix - 1$ must have been propagated upwards to form a valid $ix$'th digit.  The solution as it turns out is very simple.  
+Perform a Comba like multiplier and inside the outer loop just after the inner loop fix up the $ix + 1$'th digit by forwarding the carry.  
+
+With this change in place the Montgomery reduction algorithm can be performed with a Comba style multiplication loop which substantially increases
+the speed of the algorithm.  
+
+\newpage\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{fast\_mp\_montgomery\_reduce}. \\
+\textbf{Input}.   mp\_int $x$, mp\_int $n$ and a digit $\rho \equiv -1/n_0 \mbox{ (mod }n\mbox{)}$. \\
+\hspace{11.5mm}($0 \le x < n^2, n > 1, (n, \beta) = 1, \beta^k > n$) \\
+\textbf{Output}.  $\beta^{-k}x \mbox{ (mod }n\mbox{)}$ \\
+\hline \\
+Place an array of \textbf{MP\_WARRAY} mp\_word variables called $\hat W$ on the stack. \\
+1.  if $x.alloc < n.used + 1$ then grow $x$ to $n.used + 1$ digits. \\
+Copy the digits of $x$ into the array $\hat W$ \\
+2.  For $ix$ from $0$ to $x.used - 1$ do \\
+\hspace{3mm}2.1  $\hat W_{ix} \leftarrow x_{ix}$ \\
+3.  For $ix$ from $x.used$ to $2n.used - 1$ do \\
+\hspace{3mm}3.1  $\hat W_{ix} \leftarrow 0$ \\
+Elimiate the lower $k$ digits. \\
+4.  for $ix$ from $0$ to $n.used - 1$ do \\
+\hspace{3mm}4.1  $\mu \leftarrow \hat W_{ix} \cdot \rho \mbox{ (mod }\beta\mbox{)}$ \\
+\hspace{3mm}4.2  For $iy$ from $0$ to $n.used - 1$ do \\
+\hspace{6mm}4.2.1  $\hat W_{iy + ix} \leftarrow \hat W_{iy + ix} + \mu \cdot n_{iy}$ \\
+\hspace{3mm}4.3  $\hat W_{ix + 1} \leftarrow \hat W_{ix + 1} + \lfloor \hat W_{ix} / \beta \rfloor$ \\
+Propagate carries upwards. \\
+5.  for $ix$ from $n.used$ to $2n.used + 1$ do \\
+\hspace{3mm}5.1  $\hat W_{ix + 1} \leftarrow \hat W_{ix + 1} + \lfloor \hat W_{ix} / \beta \rfloor$ \\
+Shift right and reduce modulo $\beta$ simultaneously. \\
+6.  for $ix$ from $0$ to $n.used + 1$ do \\
+\hspace{3mm}6.1  $x_{ix} \leftarrow \hat W_{ix + n.used} \mbox{ (mod }\beta\mbox{)}$ \\
+Zero excess digits and fixup $x$. \\
+7.  if $x.used > n.used + 1$ then do \\
+\hspace{3mm}7.1  for $ix$ from $n.used + 1$ to $x.used - 1$ do \\
+\hspace{6mm}7.1.1  $x_{ix} \leftarrow 0$ \\
+8.  $x.used \leftarrow n.used + 1$ \\
+9.  Clamp excessive digits of $x$. \\
+10.  If $x \ge n$ then \\
+\hspace{3mm}10.1  $x \leftarrow x - n$ \\
+11.  Return(\textit{MP\_OKAY}). \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Algorithm fast\_mp\_montgomery\_reduce}
+\end{figure}
+
+\textbf{Algorithm fast\_mp\_montgomery\_reduce.}
+This algorithm will compute the Montgomery reduction of $x$ modulo $n$ using the Comba technique.  It is on most computer platforms significantly
+faster than algorithm mp\_montgomery\_reduce and algorithm mp\_reduce (\textit{Barrett reduction}).  The algorithm has the same restrictions
+on the input as the baseline reduction algorithm.  An additional two restrictions are imposed on this algorithm.  The number of digits $k$ in the 
+the modulus $n$ must not violate $MP\_WARRAY > 2k +1$ and $n < \delta$.   When $\beta = 2^{28}$ this algorithm can be used to reduce modulo
+a modulus of at most $3,556$ bits in length.  
+
+As in the other Comba reduction algorithms there is a $\hat W$ array which stores the columns of the product.  It is initially filled with the
+contents of $x$ with the excess digits zeroed.  The reduction loop is very similar the to the baseline loop at heart.  The multiplication on step
+4.1 can be single precision only since $ab \mbox{ (mod }\beta\mbox{)} \equiv (a \mbox{ mod }\beta)(b \mbox{ mod }\beta)$.  Some multipliers such
+as those on the ARM processors take a variable length time to complete depending on the number of bytes of result it must produce.  By performing
+a single precision multiplication instead half the amount of time is spent.
+
+Also note that digit $\hat W_{ix}$ must have the carry from the $ix - 1$'th digit propagated upwards in order for this to work.  That is what step
+4.3 will do.  In effect over the $n.used$ iterations of the outer loop the $n.used$'th lower columns all have the their carries propagated forwards.  Note
+how the upper bits of those same words are not reduced modulo $\beta$.  This is because those values will be discarded shortly and there is no
+point.
+
+Step 5 will propagate the remainder of the carries upwards.  On step 6 the columns are reduced modulo $\beta$ and shifted simultaneously as they are
+stored in the destination $x$.  
+
+\vspace{+3mm}\begin{small}
+\hspace{-5.1mm}{\bf File}: bn\_fast\_mp\_montgomery\_reduce.c
+\vspace{-3mm}
+\begin{alltt}
+\end{alltt}
+\end{small}
+
+The $\hat W$ array is first filled with digits of $x$ on line 48 then the rest of the digits are zeroed on line 55.  Both loops share
+the same alias variables to make the code easier to read.  
+
+The value of $\mu$ is calculated in an interesting fashion.  First the value $\hat W_{ix}$ is reduced modulo $\beta$ and cast to a mp\_digit.  This
+forces the compiler to use a single precision multiplication and prevents any concerns about loss of precision.   Line 110 fixes the carry 
+for the next iteration of the loop by propagating the carry from $\hat W_{ix}$ to $\hat W_{ix+1}$.
+
+The for loop on line 109 propagates the rest of the carries upwards through the columns.  The for loop on line 126 reduces the columns
+modulo $\beta$ and shifts them $k$ places at the same time.  The alias $\_ \hat W$ actually refers to the array $\hat W$ starting at the $n.used$'th
+digit, that is $\_ \hat W_{t} = \hat W_{n.used + t}$.  
+
+\subsection{Montgomery Setup}
+To calculate the variable $\rho$ a relatively simple algorithm will be required.  
+
+\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{mp\_montgomery\_setup}. \\
+\textbf{Input}.   mp\_int $n$ ($n > 1$ and $(n, 2) = 1$) \\
+\textbf{Output}.  $\rho \equiv -1/n_0 \mbox{ (mod }\beta\mbox{)}$ \\
+\hline \\
+1.  $b \leftarrow n_0$ \\
+2.  If $b$ is even return(\textit{MP\_VAL}) \\
+3.  $x \leftarrow (((b + 2) \mbox{ AND } 4) << 1) + b$ \\
+4.  for $k$ from 0 to $\lceil lg(lg(\beta)) \rceil - 2$ do \\
+\hspace{3mm}4.1  $x \leftarrow x \cdot (2 - bx)$ \\
+5.  $\rho \leftarrow \beta - x \mbox{ (mod }\beta\mbox{)}$ \\
+6.  Return(\textit{MP\_OKAY}). \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Algorithm mp\_montgomery\_setup} 
+\end{figure}
+
+\textbf{Algorithm mp\_montgomery\_setup.}
+This algorithm will calculate the value of $\rho$ required within the Montgomery reduction algorithms.  It uses a very interesting trick 
+to calculate $1/n_0$ when $\beta$ is a power of two.  
+
+\vspace{+3mm}\begin{small}
+\hspace{-5.1mm}{\bf File}: bn\_mp\_montgomery\_setup.c
+\vspace{-3mm}
+\begin{alltt}
+\end{alltt}
+\end{small}
+
+This source code computes the value of $\rho$ required to perform Montgomery reduction.  It has been modified to avoid performing excess
+multiplications when $\beta$ is not the default 28-bits.  
+
+\section{The Diminished Radix Algorithm}
+The Diminished Radix method of modular reduction \cite{DRMET} is a fairly clever technique which can be more efficient than either the Barrett
+or Montgomery methods for certain forms of moduli.  The technique is based on the following simple congruence.
+
+\begin{equation}
+(x \mbox{ mod } n) + k \lfloor x / n \rfloor \equiv x \mbox{ (mod }(n - k)\mbox{)}
+\end{equation}
+
+This observation was used in the MMB \cite{MMB} block cipher to create a diffusion primitive.  It used the fact that if $n = 2^{31}$ and $k=1$ that 
+then a x86 multiplier could produce the 62-bit product and use  the ``shrd'' instruction to perform a double-precision right shift.  The proof
+of the above equation is very simple.  First write $x$ in the product form.
+
+\begin{equation}
+x = qn + r
+\end{equation}
+
+Now reduce both sides modulo $(n - k)$.
+
+\begin{equation}
+x \equiv qk + r  \mbox{ (mod }(n-k)\mbox{)}
+\end{equation}
+
+The variable $n$ reduces modulo $n - k$ to $k$.  By putting $q = \lfloor x/n \rfloor$ and $r = x \mbox{ mod } n$ 
+into the equation the original congruence is reproduced, thus concluding the proof.  The following algorithm is based on this observation.
+
+\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{Diminished Radix Reduction}. \\
+\textbf{Input}.   Integer $x$, $n$, $k$ \\
+\textbf{Output}.  $x \mbox{ mod } (n - k)$ \\
+\hline \\
+1.  $q \leftarrow \lfloor x / n \rfloor$ \\
+2.  $q \leftarrow k \cdot q$ \\
+3.  $x \leftarrow x \mbox{ (mod }n\mbox{)}$ \\
+4.  $x \leftarrow x + q$ \\
+5.  If $x \ge (n - k)$ then \\
+\hspace{3mm}5.1  $x \leftarrow x - (n - k)$ \\
+\hspace{3mm}5.2  Goto step 1. \\
+6.  Return $x$ \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Algorithm Diminished Radix Reduction}
+\label{fig:DR}
+\end{figure}
+
+This algorithm will reduce $x$ modulo $n - k$ and return the residue.  If $0 \le x < (n - k)^2$ then the algorithm will loop almost always
+once or twice and occasionally three times.  For simplicity sake the value of $x$ is bounded by the following simple polynomial.
+
+\begin{equation} 
+0 \le x < n^2 + k^2 - 2nk
+\end{equation}
+
+The true bound is  $0 \le x < (n - k - 1)^2$ but this has quite a few more terms.  The value of $q$ after step 1 is bounded by the following.
+
+\begin{equation}
+q < n - 2k - k^2/n
+\end{equation}
+
+Since $k^2$ is going to be considerably smaller than $n$ that term will always be zero.  The value of $x$ after step 3 is bounded trivially as
+$0 \le x < n$.  By step four the sum $x + q$ is bounded by 
+
+\begin{equation}
+0 \le q + x < (k + 1)n - 2k^2 - 1
+\end{equation}
+
+With a second pass $q$ will be loosely bounded by $0 \le q < k^2$ after step 2 while $x$ will still be loosely bounded by $0 \le x < n$ after step 3.  After the second pass it is highly unlike that the
+sum in step 4 will exceed $n - k$.  In practice fewer than three passes of the algorithm are required to reduce virtually every input in the 
+range $0 \le x < (n - k - 1)^2$.  
+
+\begin{figure}
+\begin{small}
+\begin{center}
+\begin{tabular}{|l|}
+\hline
+$x = 123456789, n = 256, k = 3$ \\
+\hline $q \leftarrow \lfloor x/n \rfloor = 482253$ \\
+$q \leftarrow q*k = 1446759$ \\
+$x \leftarrow x \mbox{ mod } n = 21$ \\
+$x \leftarrow x + q = 1446780$ \\
+$x \leftarrow x - (n - k) = 1446527$ \\
+\hline 
+$q \leftarrow \lfloor x/n \rfloor = 5650$ \\
+$q \leftarrow q*k = 16950$ \\
+$x \leftarrow x \mbox{ mod } n = 127$ \\
+$x \leftarrow x + q = 17077$ \\
+$x \leftarrow x - (n - k) = 16824$ \\
+\hline 
+$q \leftarrow \lfloor x/n \rfloor = 65$ \\
+$q \leftarrow q*k = 195$ \\
+$x \leftarrow x \mbox{ mod } n = 184$ \\
+$x \leftarrow x + q = 379$ \\
+$x \leftarrow x - (n - k) = 126$ \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Example Diminished Radix Reduction}
+\label{fig:EXDR}
+\end{figure}
+
+Figure~\ref{fig:EXDR} demonstrates the reduction of $x = 123456789$ modulo $n - k = 253$ when $n = 256$ and $k = 3$.  Note that even while $x$
+is considerably larger than $(n - k - 1)^2 = 63504$ the algorithm still converges on the modular residue exceedingly fast.  In this case only
+three passes were required to find the residue $x \equiv 126$.
+
+
+\subsection{Choice of Moduli}
+On the surface this algorithm looks like a very expensive algorithm.  It requires a couple of subtractions followed by multiplication and other
+modular reductions.  The usefulness of this algorithm becomes exceedingly clear when an appropriate modulus is chosen.
+
+Division in general is a very expensive operation to perform.  The one exception is when the division is by a power of the radix of representation used.  
+Division by ten for example is simple for pencil and paper mathematics since it amounts to shifting the decimal place to the right.  Similarly division 
+by two (\textit{or powers of two}) is very simple for binary computers to perform.  It would therefore seem logical to choose $n$ of the form $2^p$ 
+which would imply that $\lfloor x / n \rfloor$ is a simple shift of $x$ right $p$ bits.  
+
+However, there is one operation related to division of power of twos that is even faster than this.  If $n = \beta^p$ then the division may be 
+performed by moving whole digits to the right $p$ places.  In practice division by $\beta^p$ is much faster than division by $2^p$ for any $p$.  
+Also with the choice of $n = \beta^p$ reducing $x$ modulo $n$ merely requires zeroing the digits above the $p-1$'th digit of $x$.  
+
+Throughout the next section the term ``restricted modulus'' will refer to a modulus of the form $\beta^p - k$ whereas the term ``unrestricted
+modulus'' will refer to a modulus of the form $2^p - k$.  The word ``restricted'' in this case refers to the fact that it is based on the 
+$2^p$ logic except $p$ must be a multiple of $lg(\beta)$.  
+
+\subsection{Choice of $k$}
+Now that division and reduction (\textit{step 1 and 3 of figure~\ref{fig:DR}}) have been optimized to simple digit operations the multiplication by $k$
+in step 2 is the most expensive operation.  Fortunately the choice of $k$ is not terribly limited.  For all intents and purposes it might
+as well be a single digit.  The smaller the value of $k$ is the faster the algorithm will be.  
+
+\subsection{Restricted Diminished Radix Reduction}
+The restricted Diminished Radix algorithm can quickly reduce an input modulo a modulus of the form $n = \beta^p - k$.  This algorithm can reduce 
+an input $x$ within the range $0 \le x < n^2$ using only a couple passes of the algorithm demonstrated in figure~\ref{fig:DR}.  The implementation
+of this algorithm has been optimized to avoid additional overhead associated with a division by $\beta^p$, the multiplication by $k$ or the addition 
+of $x$ and $q$.  The resulting algorithm is very efficient and can lead to substantial improvements over Barrett and Montgomery reduction when modular 
+exponentiations are performed.
+
+\newpage\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{mp\_dr\_reduce}. \\
+\textbf{Input}.   mp\_int $x$, $n$ and a mp\_digit $k = \beta - n_0$ \\
+\hspace{11.5mm}($0 \le x < n^2$, $n > 1$, $0 < k < \beta$) \\
+\textbf{Output}.  $x \mbox{ mod } n$ \\
+\hline \\
+1.  $m \leftarrow n.used$ \\
+2.  If $x.alloc < 2m$ then grow $x$ to $2m$ digits. \\
+3.  $\mu \leftarrow 0$ \\
+4.  for $i$ from $0$ to $m - 1$ do \\
+\hspace{3mm}4.1  $\hat r \leftarrow k \cdot x_{m+i} + x_{i} + \mu$ \\
+\hspace{3mm}4.2  $x_{i} \leftarrow \hat r \mbox{ (mod }\beta\mbox{)}$ \\
+\hspace{3mm}4.3  $\mu \leftarrow \lfloor \hat r / \beta \rfloor$ \\
+5.  $x_{m} \leftarrow \mu$ \\
+6.  for $i$ from $m + 1$ to $x.used - 1$ do \\
+\hspace{3mm}6.1  $x_{i} \leftarrow 0$ \\
+7.  Clamp excess digits of $x$. \\
+8.  If $x \ge n$ then \\
+\hspace{3mm}8.1  $x \leftarrow x - n$ \\
+\hspace{3mm}8.2  Goto step 3. \\
+9.  Return(\textit{MP\_OKAY}). \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Algorithm mp\_dr\_reduce}
+\end{figure}
+
+\textbf{Algorithm mp\_dr\_reduce.}
+This algorithm will perform the Dimished Radix reduction of $x$ modulo $n$.  It has similar restrictions to that of the Barrett reduction
+with the addition that $n$ must be of the form $n = \beta^m - k$ where $0 < k <\beta$.  
+
+This algorithm essentially implements the pseudo-code in figure~\ref{fig:DR} except with a slight optimization.  The division by $\beta^m$, multiplication by $k$
+and addition of $x \mbox{ mod }\beta^m$ are all performed simultaneously inside the loop on step 4.  The division by $\beta^m$ is emulated by accessing
+the term at the $m+i$'th position which is subsequently multiplied by $k$ and added to the term at the $i$'th position.  After the loop the $m$'th
+digit is set to the carry and the upper digits are zeroed.  Steps 5 and 6 emulate the reduction modulo $\beta^m$ that should have happend to 
+$x$ before the addition of the multiple of the upper half.  
+
+At step 8 if $x$ is still larger than $n$ another pass of the algorithm is required.  First $n$ is subtracted from $x$ and then the algorithm resumes
+at step 3.  
+
+\vspace{+3mm}\begin{small}
+\hspace{-5.1mm}{\bf File}: bn\_mp\_dr\_reduce.c
+\vspace{-3mm}
+\begin{alltt}
+\end{alltt}
+\end{small}
+
+The first step is to grow $x$ as required to $2m$ digits since the reduction is performed in place on $x$.  The label on line 52 is where
+the algorithm will resume if further reduction passes are required.  In theory it could be placed at the top of the function however, the size of
+the modulus and question of whether $x$ is large enough are invariant after the first pass meaning that it would be a waste of time.  
+
+The aliases $tmpx1$ and $tmpx2$ refer to the digits of $x$ where the latter is offset by $m$ digits.  By reading digits from $x$ offset by $m$ digits
+a division by $\beta^m$ can be simulated virtually for free.  The loop on line 64 performs the bulk of the work (\textit{corresponds to step 4 of algorithm 7.11})
+in this algorithm.
+
+By line 67 the pointer $tmpx1$ points to the $m$'th digit of $x$ which is where the final carry will be placed.  Similarly by line 74 the 
+same pointer will point to the $m+1$'th digit where the zeroes will be placed.  
+
+Since the algorithm is only valid if both $x$ and $n$ are greater than zero an unsigned comparison suffices to determine if another pass is required.  
+With the same logic at line 81 the value of $x$ is known to be greater than or equal to $n$ meaning that an unsigned subtraction can be used
+as well.  Since the destination of the subtraction is the larger of the inputs the call to algorithm s\_mp\_sub cannot fail and the return code
+does not need to be checked.
+
+\subsubsection{Setup}
+To setup the restricted Diminished Radix algorithm the value $k = \beta - n_0$ is required.  This algorithm is not really complicated but provided for
+completeness.
+
+\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{mp\_dr\_setup}. \\
+\textbf{Input}.   mp\_int $n$ \\
+\textbf{Output}.  $k = \beta - n_0$ \\
+\hline \\
+1.  $k \leftarrow \beta - n_0$ \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Algorithm mp\_dr\_setup}
+\end{figure}
+
+\vspace{+3mm}\begin{small}
+\hspace{-5.1mm}{\bf File}: bn\_mp\_dr\_setup.c
+\vspace{-3mm}
+\begin{alltt}
+\end{alltt}
+\end{small}
+
+\subsubsection{Modulus Detection}
+Another algorithm which will be useful is the ability to detect a restricted Diminished Radix modulus.  An integer is said to be
+of restricted Diminished Radix form if all of the digits are equal to $\beta - 1$ except the trailing digit which may be any value.
+
+\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{mp\_dr\_is\_modulus}. \\
+\textbf{Input}.   mp\_int $n$ \\
+\textbf{Output}.  $1$ if $n$ is in D.R form, $0$ otherwise \\
+\hline
+1.  If $n.used < 2$ then return($0$). \\
+2.  for $ix$ from $1$ to $n.used - 1$ do \\
+\hspace{3mm}2.1  If $n_{ix} \ne \beta - 1$ return($0$). \\
+3.  Return($1$). \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Algorithm mp\_dr\_is\_modulus}
+\end{figure}
+
+\textbf{Algorithm mp\_dr\_is\_modulus.}
+This algorithm determines if a value is in Diminished Radix form.  Step 1 rejects obvious cases where fewer than two digits are
+in the mp\_int.  Step 2 tests all but the first digit to see if they are equal to $\beta - 1$.  If the algorithm manages to get to
+step 3 then $n$ must be of Diminished Radix form.
+
+\vspace{+3mm}\begin{small}
+\hspace{-5.1mm}{\bf File}: bn\_mp\_dr\_is\_modulus.c
+\vspace{-3mm}
+\begin{alltt}
+\end{alltt}
+\end{small}
+
+\subsection{Unrestricted Diminished Radix Reduction}
+The unrestricted Diminished Radix algorithm allows modular reductions to be performed when the modulus is of the form $2^p - k$.  This algorithm
+is a straightforward adaptation of algorithm~\ref{fig:DR}.
+
+In general the restricted Diminished Radix reduction algorithm is much faster since it has considerably lower overhead.  However, this new
+algorithm is much faster than either Montgomery or Barrett reduction when the moduli are of the appropriate form.
+
+\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{mp\_reduce\_2k}. \\
+\textbf{Input}.   mp\_int $a$ and $n$.  mp\_digit $k$  \\
+\hspace{11.5mm}($a \ge 0$, $n > 1$, $0 < k < \beta$, $n + k$ is a power of two) \\
+\textbf{Output}.  $a \mbox{ (mod }n\mbox{)}$ \\
+\hline
+1.  $p \leftarrow \lceil lg(n) \rceil$  (\textit{mp\_count\_bits}) \\
+2.  While $a \ge n$ do \\
+\hspace{3mm}2.1  $q \leftarrow \lfloor a / 2^p \rfloor$ (\textit{mp\_div\_2d}) \\
+\hspace{3mm}2.2  $a \leftarrow a \mbox{ (mod }2^p\mbox{)}$ (\textit{mp\_mod\_2d}) \\
+\hspace{3mm}2.3  $q \leftarrow q \cdot k$ (\textit{mp\_mul\_d}) \\
+\hspace{3mm}2.4  $a \leftarrow a - q$ (\textit{s\_mp\_sub}) \\
+\hspace{3mm}2.5  If $a \ge n$ then do \\
+\hspace{6mm}2.5.1  $a \leftarrow a - n$ \\
+3.  Return(\textit{MP\_OKAY}). \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Algorithm mp\_reduce\_2k}
+\end{figure}
+
+\textbf{Algorithm mp\_reduce\_2k.}
+This algorithm quickly reduces an input $a$ modulo an unrestricted Diminished Radix modulus $n$.  Division by $2^p$ is emulated with a right
+shift which makes the algorithm fairly inexpensive to use.  
+
+\vspace{+3mm}\begin{small}
+\hspace{-5.1mm}{\bf File}: bn\_mp\_reduce\_2k.c
+\vspace{-3mm}
+\begin{alltt}
+\end{alltt}
+\end{small}
+
+The algorithm mp\_count\_bits calculates the number of bits in an mp\_int which is used to find the initial value of $p$.  The call to mp\_div\_2d
+on line 31 calculates both the quotient $q$ and the remainder $a$ required.  By doing both in a single function call the code size
+is kept fairly small.  The multiplication by $k$ is only performed if $k > 1$. This allows reductions modulo $2^p - 1$ to be performed without
+any multiplications.  
+
+The unsigned s\_mp\_add, mp\_cmp\_mag and s\_mp\_sub are used in place of their full sign counterparts since the inputs are only valid if they are 
+positive.  By using the unsigned versions the overhead is kept to a minimum.  
+
+\subsubsection{Unrestricted Setup}
+To setup this reduction algorithm the value of $k = 2^p - n$ is required.  
+
+\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{mp\_reduce\_2k\_setup}. \\
+\textbf{Input}.   mp\_int $n$   \\
+\textbf{Output}.  $k = 2^p - n$ \\
+\hline
+1.  $p \leftarrow \lceil lg(n) \rceil$  (\textit{mp\_count\_bits}) \\
+2.  $x \leftarrow 2^p$ (\textit{mp\_2expt}) \\
+3.  $x \leftarrow x - n$ (\textit{mp\_sub}) \\
+4.  $k \leftarrow x_0$ \\
+5.  Return(\textit{MP\_OKAY}). \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Algorithm mp\_reduce\_2k\_setup}
+\end{figure}
+
+\textbf{Algorithm mp\_reduce\_2k\_setup.}
+This algorithm computes the value of $k$ required for the algorithm mp\_reduce\_2k.  By making a temporary variable $x$ equal to $2^p$ a subtraction
+is sufficient to solve for $k$.  Alternatively if $n$ has more than one digit the value of $k$ is simply $\beta - n_0$.  
+
+\vspace{+3mm}\begin{small}
+\hspace{-5.1mm}{\bf File}: bn\_mp\_reduce\_2k\_setup.c
+\vspace{-3mm}
+\begin{alltt}
+\end{alltt}
+\end{small}
+
+\subsubsection{Unrestricted Detection}
+An integer $n$ is a valid unrestricted Diminished Radix modulus if either of the following are true.
+
+\begin{enumerate}
+\item  The number has only one digit.
+\item  The number has more than one digit and every bit from the $\beta$'th to the most significant is one.
+\end{enumerate}
+
+If either condition is true than there is a power of two $2^p$ such that $0 < 2^p - n < \beta$.   If the input is only
+one digit than it will always be of the correct form.  Otherwise all of the bits above the first digit must be one.  This arises from the fact
+that there will be value of $k$ that when added to the modulus causes a carry in the first digit which propagates all the way to the most
+significant bit.  The resulting sum will be a power of two.
+
+\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{mp\_reduce\_is\_2k}. \\
+\textbf{Input}.   mp\_int $n$   \\
+\textbf{Output}.  $1$ if of proper form, $0$ otherwise \\
+\hline
+1.  If $n.used = 0$ then return($0$). \\
+2.  If $n.used = 1$ then return($1$). \\
+3.  $p \leftarrow \lceil lg(n) \rceil$  (\textit{mp\_count\_bits}) \\
+4.  for $x$ from $lg(\beta)$ to $p$ do \\
+\hspace{3mm}4.1  If the ($x \mbox{ mod }lg(\beta)$)'th bit of the $\lfloor x / lg(\beta) \rfloor$ of $n$ is zero then return($0$). \\
+5.  Return($1$). \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Algorithm mp\_reduce\_is\_2k}
+\end{figure}
+
+\textbf{Algorithm mp\_reduce\_is\_2k.}
+This algorithm quickly determines if a modulus is of the form required for algorithm mp\_reduce\_2k to function properly.  
+
+\vspace{+3mm}\begin{small}
+\hspace{-5.1mm}{\bf File}: bn\_mp\_reduce\_is\_2k.c
+\vspace{-3mm}
+\begin{alltt}
+\end{alltt}
+\end{small}
+
+
+
+\section{Algorithm Comparison}
+So far three very different algorithms for modular reduction have been discussed.  Each of the algorithms have their own strengths and weaknesses
+that makes having such a selection very useful.  The following table sumarizes the three algorithms along with comparisons of work factors.  Since
+all three algorithms have the restriction that $0 \le x < n^2$ and $n > 1$ those limitations are not included in the table.  
+
+\begin{center}
+\begin{small}
+\begin{tabular}{|c|c|c|c|c|c|}
+\hline \textbf{Method} & \textbf{Work Required} & \textbf{Limitations} & \textbf{$m = 8$} & \textbf{$m = 32$} & \textbf{$m = 64$} \\
+\hline Barrett    & $m^2 + 2m - 1$ & None              & $79$ & $1087$ & $4223$ \\
+\hline Montgomery & $m^2 + m$      & $n$ must be odd   & $72$ & $1056$ & $4160$ \\
+\hline D.R.       & $2m$           & $n = \beta^m - k$ & $16$ & $64$   & $128$  \\
+\hline
+\end{tabular}
+\end{small}
+\end{center}
+
+In theory Montgomery and Barrett reductions would require roughly the same amount of time to complete.  However, in practice since Montgomery
+reduction can be written as a single function with the Comba technique it is much faster.  Barrett reduction suffers from the overhead of
+calling the half precision multipliers, addition and division by $\beta$ algorithms.
+
+For almost every cryptographic algorithm Montgomery reduction is the algorithm of choice.  The one set of algorithms where Diminished Radix reduction truly
+shines are based on the discrete logarithm problem such as Diffie-Hellman \cite{DH} and ElGamal \cite{ELGAMAL}.  In these algorithms
+primes of the form $\beta^m - k$ can be found and shared amongst users.  These primes will allow the Diminished Radix algorithm to be used in
+modular exponentiation to greatly speed up the operation.
+
+
+
+\section*{Exercises}
+\begin{tabular}{cl}
+$\left [ 3 \right ]$ & Prove that the ``trick'' in algorithm mp\_montgomery\_setup actually \\
+                     & calculates the correct value of $\rho$. \\
+                     & \\
+$\left [ 2 \right ]$ & Devise an algorithm to reduce modulo $n + k$ for small $k$ quickly.  \\
+                     & \\
+$\left [ 4 \right ]$ & Prove that the pseudo-code algorithm ``Diminished Radix Reduction'' \\
+                     & (\textit{figure~\ref{fig:DR}}) terminates.  Also prove the probability that it will \\
+                     & terminate within $1 \le k \le 10$ iterations. \\
+                     & \\
+\end{tabular}                     
+
+
+\chapter{Exponentiation}
+Exponentiation is the operation of raising one variable to the power of another, for example, $a^b$.  A variant of exponentiation, computed
+in a finite field or ring, is called modular exponentiation.  This latter style of operation is typically used in public key 
+cryptosystems such as RSA and Diffie-Hellman.  The ability to quickly compute modular exponentiations is of great benefit to any
+such cryptosystem and many methods have been sought to speed it up.
+
+\section{Exponentiation Basics}
+A trivial algorithm would simply multiply $a$ against itself $b - 1$ times to compute the exponentiation desired.  However, as $b$ grows in size
+the number of multiplications becomes prohibitive.  Imagine what would happen if $b$ $\approx$ $2^{1024}$ as is the case when computing an RSA signature
+with a $1024$-bit key.  Such a calculation could never be completed as it would take simply far too long.
+
+Fortunately there is a very simple algorithm based on the laws of exponents.  Recall that $lg_a(a^b) = b$ and that $lg_a(a^ba^c) = b + c$ which
+are two trivial relationships between the base and the exponent.  Let $b_i$ represent the $i$'th bit of $b$ starting from the least 
+significant bit.  If $b$ is a $k$-bit integer than the following equation is true.
+
+\begin{equation}
+a^b = \prod_{i=0}^{k-1} a^{2^i \cdot b_i}
+\end{equation}
+
+By taking the base $a$ logarithm of both sides of the equation the following equation is the result.
+
+\begin{equation}
+b = \sum_{i=0}^{k-1}2^i \cdot b_i
+\end{equation}
+
+The term $a^{2^i}$ can be found from the $i - 1$'th term by squaring the term since $\left ( a^{2^i} \right )^2$ is equal to
+$a^{2^{i+1}}$.  This observation forms the basis of essentially all fast exponentiation algorithms.  It requires $k$ squarings and on average
+$k \over 2$ multiplications to compute the result.  This is indeed quite an improvement over simply multiplying by $a$ a total of $b-1$ times.
+
+While this current method is a considerable speed up there are further improvements to be made.  For example, the $a^{2^i}$ term does not need to 
+be computed in an auxilary variable.  Consider the following equivalent algorithm.
+
+\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{Left to Right Exponentiation}. \\
+\textbf{Input}.   Integer $a$, $b$ and $k$ \\
+\textbf{Output}.  $c = a^b$ \\
+\hline \\
+1.  $c \leftarrow 1$ \\
+2.  for $i$ from $k - 1$ to $0$ do \\
+\hspace{3mm}2.1  $c \leftarrow c^2$ \\
+\hspace{3mm}2.2  $c \leftarrow c \cdot a^{b_i}$ \\
+3.  Return $c$. \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Left to Right Exponentiation}
+\label{fig:LTOR}
+\end{figure}
+
+This algorithm starts from the most significant bit and works towards the least significant bit.  When the $i$'th bit of $b$ is set $a$ is
+multiplied against the current product.  In each iteration the product is squared which doubles the exponent of the individual terms of the
+product.  
+
+For example, let $b = 101100_2 \equiv 44_{10}$.  The following chart demonstrates the actions of the algorithm.
+
+\newpage\begin{figure}
+\begin{center}
+\begin{tabular}{|c|c|}
+\hline \textbf{Value of $i$} & \textbf{Value of $c$} \\
+\hline - & $1$ \\
+\hline $5$ & $a$ \\
+\hline $4$ & $a^2$ \\
+\hline $3$ & $a^4 \cdot a$ \\
+\hline $2$ & $a^8 \cdot a^2 \cdot a$ \\
+\hline $1$ & $a^{16} \cdot a^4 \cdot a^2$ \\
+\hline $0$ & $a^{32} \cdot a^8 \cdot a^4$ \\
+\hline
+\end{tabular}
+\end{center}
+\caption{Example of Left to Right Exponentiation}
+\end{figure}
+
+When the product $a^{32} \cdot a^8 \cdot a^4$ is simplified it is equal $a^{44}$ which is the desired exponentiation.  This particular algorithm is 
+called ``Left to Right'' because it reads the exponent in that order.  All of the exponentiation algorithms that will be presented are of this nature.  
+
+\subsection{Single Digit Exponentiation}
+The first algorithm in the series of exponentiation algorithms will be an unbounded algorithm where the exponent is a single digit.  It is intended 
+to be used when a small power of an input is required (\textit{e.g. $a^5$}).  It is faster than simply multiplying $b - 1$ times for all values of 
+$b$ that are greater than three.  
+
+\newpage\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{mp\_expt\_d}. \\
+\textbf{Input}.   mp\_int $a$ and mp\_digit $b$ \\
+\textbf{Output}.  $c = a^b$ \\
+\hline \\
+1.  $g \leftarrow a$ (\textit{mp\_init\_copy}) \\
+2.  $c \leftarrow 1$ (\textit{mp\_set}) \\
+3.  for $x$ from 1 to $lg(\beta)$ do \\
+\hspace{3mm}3.1  $c \leftarrow c^2$ (\textit{mp\_sqr}) \\
+\hspace{3mm}3.2  If $b$ AND $2^{lg(\beta) - 1} \ne 0$ then \\
+\hspace{6mm}3.2.1  $c \leftarrow c \cdot g$ (\textit{mp\_mul}) \\
+\hspace{3mm}3.3  $b \leftarrow b << 1$ \\
+4.  Clear $g$. \\
+5.  Return(\textit{MP\_OKAY}). \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Algorithm mp\_expt\_d}
+\end{figure}
+
+\textbf{Algorithm mp\_expt\_d.}
+This algorithm computes the value of $a$ raised to the power of a single digit $b$.  It uses the left to right exponentiation algorithm to
+quickly compute the exponentiation.  It is loosely based on algorithm 14.79 of HAC \cite[pp. 615]{HAC} with the difference that the 
+exponent is a fixed width.  
+
+A copy of $a$ is made first to allow destination variable $c$ be the same as the source variable $a$.  The result is set to the initial value of 
+$1$ in the subsequent step.
+
+Inside the loop the exponent is read from the most significant bit first down to the least significant bit.  First $c$ is invariably squared
+on step 3.1.  In the following step if the most significant bit of $b$ is one the copy of $a$ is multiplied against $c$.  The value
+of $b$ is shifted left one bit to make the next bit down from the most signficant bit the new most significant bit.  In effect each
+iteration of the loop moves the bits of the exponent $b$ upwards to the most significant location.
+
+\vspace{+3mm}\begin{small}
+\hspace{-5.1mm}{\bf File}: bn\_mp\_expt\_d.c
+\vspace{-3mm}
+\begin{alltt}
+\end{alltt}
+\end{small}
+
+Line 29 sets the initial value of the result to $1$.  Next the loop on line 31 steps through each bit of the exponent starting from
+the most significant down towards the least significant. The invariant squaring operation placed on line 33 is performed first.  After 
+the squaring the result $c$ is multiplied by the base $g$ if and only if the most significant bit of the exponent is set.  The shift on line
+47 moves all of the bits of the exponent upwards towards the most significant location.  
+
+\section{$k$-ary Exponentiation}
+When calculating an exponentiation the most time consuming bottleneck is the multiplications which are in general a small factor
+slower than squaring.  Recall from the previous algorithm that $b_{i}$ refers to the $i$'th bit of the exponent $b$.  Suppose instead it referred to
+the $i$'th $k$-bit digit of the exponent of $b$.  For $k = 1$ the definitions are synonymous and for $k > 1$ algorithm~\ref{fig:KARY}
+computes the same exponentiation.  A group of $k$ bits from the exponent is called a \textit{window}.  That is it is a small window on only a
+portion of the entire exponent.  Consider the following modification to the basic left to right exponentiation algorithm.
+
+\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{$k$-ary Exponentiation}. \\
+\textbf{Input}.   Integer $a$, $b$, $k$ and $t$ \\
+\textbf{Output}.  $c = a^b$ \\
+\hline \\
+1.  $c \leftarrow 1$ \\
+2.  for $i$ from $t - 1$ to $0$ do \\
+\hspace{3mm}2.1  $c \leftarrow c^{2^k} $ \\
+\hspace{3mm}2.2  Extract the $i$'th $k$-bit word from $b$ and store it in $g$. \\
+\hspace{3mm}2.3  $c \leftarrow c \cdot a^g$ \\
+3.  Return $c$. \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{$k$-ary Exponentiation}
+\label{fig:KARY}
+\end{figure}
+
+The squaring on step 2.1 can be calculated by squaring the value $c$ successively $k$ times.  If the values of $a^g$ for $0 < g < 2^k$ have been
+precomputed this algorithm requires only $t$ multiplications and $tk$ squarings.  The table can be generated with $2^{k - 1} - 1$ squarings and
+$2^{k - 1} + 1$ multiplications.  This algorithm assumes that the number of bits in the exponent is evenly divisible by $k$.  
+However, when it is not the remaining $0 < x \le k - 1$ bits can be handled with algorithm~\ref{fig:LTOR}.
+
+Suppose $k = 4$ and $t = 100$.  This modified algorithm will require $109$ multiplications and $408$ squarings to compute the exponentiation.  The
+original algorithm would on average have required $200$ multiplications and $400$ squrings to compute the same value.  The total number of squarings
+has increased slightly but the number of multiplications has nearly halved.
+
+\subsection{Optimal Values of $k$}
+An optimal value of $k$ will minimize $2^{k} + \lceil n / k \rceil + n - 1$ for a fixed number of bits in the exponent $n$.  The simplest
+approach is to brute force search amongst the values $k = 2, 3, \ldots, 8$ for the lowest result.  Table~\ref{fig:OPTK} lists optimal values of $k$
+for various exponent sizes and compares the number of multiplication and squarings required against algorithm~\ref{fig:LTOR}.  
+
+\begin{figure}[here]
+\begin{center}
+\begin{small}
+\begin{tabular}{|c|c|c|c|c|c|}
+\hline \textbf{Exponent (bits)} & \textbf{Optimal $k$} & \textbf{Work at $k$} & \textbf{Work with ~\ref{fig:LTOR}} \\
+\hline $16$ & $2$ & $27$ & $24$ \\
+\hline $32$ & $3$ & $49$ & $48$ \\
+\hline $64$ & $3$ & $92$ & $96$ \\
+\hline $128$ & $4$ & $175$ & $192$ \\
+\hline $256$ & $4$ & $335$ & $384$ \\
+\hline $512$ & $5$ & $645$ & $768$ \\
+\hline $1024$ & $6$ & $1257$ & $1536$ \\
+\hline $2048$ & $6$ & $2452$ & $3072$ \\
+\hline $4096$ & $7$ & $4808$ & $6144$ \\
+\hline
+\end{tabular}
+\end{small}
+\end{center}
+\caption{Optimal Values of $k$ for $k$-ary Exponentiation}
+\label{fig:OPTK}
+\end{figure}
+
+\subsection{Sliding-Window Exponentiation}
+A simple modification to the previous algorithm is only generate the upper half of the table in the range $2^{k-1} \le g < 2^k$.  Essentially
+this is a table for all values of $g$ where the most significant bit of $g$ is a one.  However, in order for this to be allowed in the 
+algorithm values of $g$ in the range $0 \le g < 2^{k-1}$ must be avoided.  
+
+Table~\ref{fig:OPTK2} lists optimal values of $k$ for various exponent sizes and compares the work required against algorithm~\ref{fig:KARY}.  
+
+\begin{figure}[here]
+\begin{center}
+\begin{small}
+\begin{tabular}{|c|c|c|c|c|c|}
+\hline \textbf{Exponent (bits)} & \textbf{Optimal $k$} & \textbf{Work at $k$} & \textbf{Work with ~\ref{fig:KARY}} \\
+\hline $16$ & $3$ & $24$ & $27$ \\
+\hline $32$ & $3$ & $45$ & $49$ \\
+\hline $64$ & $4$ & $87$ & $92$ \\
+\hline $128$ & $4$ & $167$ & $175$ \\
+\hline $256$ & $5$ & $322$ & $335$ \\
+\hline $512$ & $6$ & $628$ & $645$ \\
+\hline $1024$ & $6$ & $1225$ & $1257$ \\
+\hline $2048$ & $7$ & $2403$ & $2452$ \\
+\hline $4096$ & $8$ & $4735$ & $4808$ \\
+\hline
+\end{tabular}
+\end{small}
+\end{center}
+\caption{Optimal Values of $k$ for Sliding Window Exponentiation}
+\label{fig:OPTK2}
+\end{figure}
+
+\newpage\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{Sliding Window $k$-ary Exponentiation}. \\
+\textbf{Input}.   Integer $a$, $b$, $k$ and $t$ \\
+\textbf{Output}.  $c = a^b$ \\
+\hline \\
+1.  $c \leftarrow 1$ \\
+2.  for $i$ from $t - 1$ to $0$ do \\
+\hspace{3mm}2.1  If the $i$'th bit of $b$ is a zero then \\
+\hspace{6mm}2.1.1   $c \leftarrow c^2$ \\
+\hspace{3mm}2.2  else do \\
+\hspace{6mm}2.2.1  $c \leftarrow c^{2^k}$ \\
+\hspace{6mm}2.2.2  Extract the $k$ bits from $(b_{i}b_{i-1}\ldots b_{i-(k-1)})$ and store it in $g$. \\
+\hspace{6mm}2.2.3  $c \leftarrow c \cdot a^g$ \\
+\hspace{6mm}2.2.4  $i \leftarrow i - k$ \\
+3.  Return $c$. \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Sliding Window $k$-ary Exponentiation}
+\end{figure}
+
+Similar to the previous algorithm this algorithm must have a special handler when fewer than $k$ bits are left in the exponent.  While this
+algorithm requires the same number of squarings it can potentially have fewer multiplications.  The pre-computed table $a^g$ is also half
+the size as the previous table.  
+
+Consider the exponent $b = 111101011001000_2 \equiv 31432_{10}$ with $k = 3$ using both algorithms.  The first algorithm will divide the exponent up as 
+the following five $3$-bit words $b \equiv \left ( 111, 101, 011, 001, 000 \right )_{2}$.  The second algorithm will break the 
+exponent as $b \equiv \left ( 111, 101, 0, 110, 0, 100, 0 \right )_{2}$.  The single digit $0$ in the second representation are where
+a single squaring took place instead of a squaring and multiplication.  In total the first method requires $10$ multiplications and $18$ 
+squarings.  The second method requires $8$ multiplications and $18$ squarings.  
+
+In general the sliding window method is never slower than the generic $k$-ary method and often it is slightly faster.  
+
+\section{Modular Exponentiation}
+
+Modular exponentiation is essentially computing the power of a base within a finite field or ring.  For example, computing 
+$d \equiv a^b \mbox{ (mod }c\mbox{)}$ is a modular exponentiation.  Instead of first computing $a^b$ and then reducing it 
+modulo $c$ the intermediate result is reduced modulo $c$ after every squaring or multiplication operation.  
+
+This guarantees that any intermediate result is bounded by $0 \le d \le c^2 - 2c + 1$ and can be reduced modulo $c$ quickly using
+one of the algorithms presented in chapter six.  
+
+Before the actual modular exponentiation algorithm can be written a wrapper algorithm must be written first.  This algorithm
+will allow the exponent $b$ to be negative which is computed as $c \equiv \left (1 / a \right )^{\vert b \vert} \mbox{(mod }d\mbox{)}$. The
+value of $(1/a) \mbox{ mod }c$ is computed using the modular inverse (\textit{see \ref{sec;modinv}}).  If no inverse exists the algorithm
+terminates with an error.  
+
+\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{mp\_exptmod}. \\
+\textbf{Input}.   mp\_int $a$, $b$ and $c$ \\
+\textbf{Output}.  $y \equiv g^x \mbox{ (mod }p\mbox{)}$ \\
+\hline \\
+1.  If $c.sign = MP\_NEG$ return(\textit{MP\_VAL}). \\
+2.  If $b.sign = MP\_NEG$ then \\
+\hspace{3mm}2.1  $g' \leftarrow g^{-1} \mbox{ (mod }c\mbox{)}$ \\
+\hspace{3mm}2.2  $x' \leftarrow \vert x \vert$ \\
+\hspace{3mm}2.3  Compute $d \equiv g'^{x'} \mbox{ (mod }c\mbox{)}$ via recursion. \\
+3.  if $p$ is odd \textbf{OR} $p$ is a D.R. modulus then \\
+\hspace{3mm}3.1  Compute $y \equiv g^{x} \mbox{ (mod }p\mbox{)}$ via algorithm mp\_exptmod\_fast. \\
+4.  else \\
+\hspace{3mm}4.1  Compute $y \equiv g^{x} \mbox{ (mod }p\mbox{)}$ via algorithm s\_mp\_exptmod. \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Algorithm mp\_exptmod}
+\end{figure}
+
+\textbf{Algorithm mp\_exptmod.}
+The first algorithm which actually performs modular exponentiation is algorithm s\_mp\_exptmod.  It is a sliding window $k$-ary algorithm 
+which uses Barrett reduction to reduce the product modulo $p$.  The second algorithm mp\_exptmod\_fast performs the same operation 
+except it uses either Montgomery or Diminished Radix reduction.  The two latter reduction algorithms are clumped in the same exponentiation
+algorithm since their arguments are essentially the same (\textit{two mp\_ints and one mp\_digit}).  
+
+\vspace{+3mm}\begin{small}
+\hspace{-5.1mm}{\bf File}: bn\_mp\_exptmod.c
+\vspace{-3mm}
+\begin{alltt}
+\end{alltt}
+\end{small}
+
+In order to keep the algorithms in a known state the first step on line 29 is to reject any negative modulus as input.  If the exponent is
+negative the algorithm tries to perform a modular exponentiation with the modular inverse of the base $G$.  The temporary variable $tmpG$ is assigned
+the modular inverse of $G$ and $tmpX$ is assigned the absolute value of $X$.  The algorithm will recuse with these new values with a positive
+exponent.
+
+If the exponent is positive the algorithm resumes the exponentiation.  Line 77 determines if the modulus is of the restricted Diminished Radix 
+form.  If it is not line 70 attempts to determine if it is of a unrestricted Diminished Radix form.  The integer $dr$ will take on one
+of three values.
+
+\begin{enumerate}
+\item $dr = 0$ means that the modulus is not of either restricted or unrestricted Diminished Radix form.
+\item $dr = 1$ means that the modulus is of restricted Diminished Radix form.
+\item $dr = 2$ means that the modulus is of unrestricted Diminished Radix form.
+\end{enumerate}
+
+Line 69 determines if the fast modular exponentiation algorithm can be used.  It is allowed if $dr \ne 0$ or if the modulus is odd.  Otherwise,
+the slower s\_mp\_exptmod algorithm is used which uses Barrett reduction.  
+
+\subsection{Barrett Modular Exponentiation}
+
+\newpage\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{s\_mp\_exptmod}. \\
+\textbf{Input}.   mp\_int $a$, $b$ and $c$ \\
+\textbf{Output}.  $y \equiv g^x \mbox{ (mod }p\mbox{)}$ \\
+\hline \\
+1.  $k \leftarrow lg(x)$ \\
+2.  $winsize \leftarrow  \left \lbrace \begin{array}{ll}
+                              2 &  \mbox{if }k \le 7 \\
+                              3 &  \mbox{if }7 < k \le 36 \\
+                              4 &  \mbox{if }36 < k \le 140 \\
+                              5 &  \mbox{if }140 < k \le 450 \\
+                              6 &  \mbox{if }450 < k \le 1303 \\
+                              7 &  \mbox{if }1303 < k \le 3529 \\
+                              8 &  \mbox{if }3529 < k \\
+                              \end{array} \right .$ \\
+3.  Initialize $2^{winsize}$ mp\_ints in an array named $M$ and one mp\_int named $\mu$ \\
+4.  Calculate the $\mu$ required for Barrett Reduction (\textit{mp\_reduce\_setup}). \\
+5.  $M_1 \leftarrow g \mbox{ (mod }p\mbox{)}$ \\
+\\
+Setup the table of small powers of $g$.  First find $g^{2^{winsize}}$ and then all multiples of it. \\
+6.  $k \leftarrow 2^{winsize - 1}$ \\
+7.  $M_{k} \leftarrow M_1$ \\
+8.  for $ix$ from 0 to $winsize - 2$ do \\
+\hspace{3mm}8.1  $M_k \leftarrow \left ( M_k \right )^2$ (\textit{mp\_sqr})  \\
+\hspace{3mm}8.2  $M_k \leftarrow M_k \mbox{ (mod }p\mbox{)}$ (\textit{mp\_reduce}) \\
+9.  for $ix$ from $2^{winsize - 1} + 1$ to $2^{winsize} - 1$ do \\
+\hspace{3mm}9.1  $M_{ix} \leftarrow M_{ix - 1} \cdot M_{1}$ (\textit{mp\_mul}) \\
+\hspace{3mm}9.2  $M_{ix} \leftarrow M_{ix} \mbox{ (mod }p\mbox{)}$ (\textit{mp\_reduce}) \\
+10.  $res \leftarrow 1$ \\
+\\
+Start Sliding Window. \\
+11.  $mode \leftarrow 0, bitcnt \leftarrow 1, buf \leftarrow 0, digidx \leftarrow x.used - 1, bitcpy \leftarrow 0, bitbuf \leftarrow 0$ \\
+12.  Loop \\
+\hspace{3mm}12.1  $bitcnt \leftarrow bitcnt - 1$ \\
+\hspace{3mm}12.2  If $bitcnt = 0$ then do \\
+\hspace{6mm}12.2.1  If $digidx = -1$ goto step 13. \\
+\hspace{6mm}12.2.2  $buf \leftarrow x_{digidx}$ \\
+\hspace{6mm}12.2.3  $digidx \leftarrow digidx - 1$ \\
+\hspace{6mm}12.2.4  $bitcnt \leftarrow lg(\beta)$ \\
+Continued on next page. \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Algorithm s\_mp\_exptmod}
+\end{figure}
+
+\newpage\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{s\_mp\_exptmod} (\textit{continued}). \\
+\textbf{Input}.   mp\_int $a$, $b$ and $c$ \\
+\textbf{Output}.  $y \equiv g^x \mbox{ (mod }p\mbox{)}$ \\
+\hline \\
+\hspace{3mm}12.3  $y \leftarrow (buf >> (lg(\beta) - 1))$ AND $1$ \\
+\hspace{3mm}12.4  $buf \leftarrow buf << 1$ \\
+\hspace{3mm}12.5  if $mode = 0$ and $y = 0$ then goto step 12. \\
+\hspace{3mm}12.6  if $mode = 1$ and $y = 0$ then do \\
+\hspace{6mm}12.6.1  $res \leftarrow res^2$ \\
+\hspace{6mm}12.6.2  $res \leftarrow res \mbox{ (mod }p\mbox{)}$ \\
+\hspace{6mm}12.6.3  Goto step 12. \\
+\hspace{3mm}12.7  $bitcpy \leftarrow bitcpy + 1$ \\
+\hspace{3mm}12.8  $bitbuf \leftarrow bitbuf + (y << (winsize - bitcpy))$ \\
+\hspace{3mm}12.9  $mode \leftarrow 2$ \\
+\hspace{3mm}12.10  If $bitcpy = winsize$ then do \\
+\hspace{6mm}Window is full so perform the squarings and single multiplication. \\
+\hspace{6mm}12.10.1  for $ix$ from $0$ to $winsize -1$ do \\
+\hspace{9mm}12.10.1.1  $res \leftarrow res^2$ \\
+\hspace{9mm}12.10.1.2  $res \leftarrow res \mbox{ (mod }p\mbox{)}$ \\
+\hspace{6mm}12.10.2  $res \leftarrow res \cdot M_{bitbuf}$ \\
+\hspace{6mm}12.10.3  $res \leftarrow res \mbox{ (mod }p\mbox{)}$ \\
+\hspace{6mm}Reset the window. \\
+\hspace{6mm}12.10.4  $bitcpy \leftarrow 0, bitbuf \leftarrow 0, mode \leftarrow 1$ \\
+\\
+No more windows left.  Check for residual bits of exponent. \\
+13.  If $mode = 2$ and $bitcpy > 0$ then do \\
+\hspace{3mm}13.1  for $ix$ form $0$ to $bitcpy - 1$ do \\
+\hspace{6mm}13.1.1  $res \leftarrow res^2$ \\
+\hspace{6mm}13.1.2  $res \leftarrow res \mbox{ (mod }p\mbox{)}$ \\
+\hspace{6mm}13.1.3  $bitbuf \leftarrow bitbuf << 1$ \\
+\hspace{6mm}13.1.4  If $bitbuf$ AND $2^{winsize} \ne 0$ then do \\
+\hspace{9mm}13.1.4.1  $res \leftarrow res \cdot M_{1}$ \\
+\hspace{9mm}13.1.4.2  $res \leftarrow res \mbox{ (mod }p\mbox{)}$ \\
+14.  $y \leftarrow res$ \\
+15.  Clear $res$, $mu$ and the $M$ array. \\
+16.  Return(\textit{MP\_OKAY}). \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Algorithm s\_mp\_exptmod (continued)}
+\end{figure}
+
+\textbf{Algorithm s\_mp\_exptmod.}
+This algorithm computes the $x$'th power of $g$ modulo $p$ and stores the result in $y$.  It takes advantage of the Barrett reduction
+algorithm to keep the product small throughout the algorithm.
+
+The first two steps determine the optimal window size based on the number of bits in the exponent.  The larger the exponent the 
+larger the window size becomes.  After a window size $winsize$ has been chosen an array of $2^{winsize}$ mp\_int variables is allocated.  This
+table will hold the values of $g^x \mbox{ (mod }p\mbox{)}$ for $2^{winsize - 1} \le x < 2^{winsize}$.  
+
+After the table is allocated the first power of $g$ is found.  Since $g \ge p$ is allowed it must be first reduced modulo $p$ to make
+the rest of the algorithm more efficient.  The first element of the table at $2^{winsize - 1}$ is found by squaring $M_1$ successively $winsize - 2$
+times.  The rest of the table elements are found by multiplying the previous element by $M_1$ modulo $p$.
+
+Now that the table is available the sliding window may begin.  The following list describes the functions of all the variables in the window.
+\begin{enumerate}
+\item The variable $mode$ dictates how the bits of the exponent are interpreted.  
+\begin{enumerate}
+   \item When $mode = 0$ the bits are ignored since no non-zero bit of the exponent has been seen yet.  For example, if the exponent were simply 
+         $1$ then there would be $lg(\beta) - 1$ zero bits before the first non-zero bit.  In this case bits are ignored until a non-zero bit is found.  
+   \item When $mode = 1$ a non-zero bit has been seen before and a new $winsize$-bit window has not been formed yet.  In this mode leading $0$ bits 
+         are read and a single squaring is performed.  If a non-zero bit is read a new window is created.  
+   \item When $mode = 2$ the algorithm is in the middle of forming a window and new bits are appended to the window from the most significant bit
+         downwards.
+\end{enumerate}
+\item The variable $bitcnt$ indicates how many bits are left in the current digit of the exponent left to be read.  When it reaches zero a new digit
+      is fetched from the exponent.
+\item The variable $buf$ holds the currently read digit of the exponent. 
+\item The variable $digidx$ is an index into the exponents digits.  It starts at the leading digit $x.used - 1$ and moves towards the trailing digit.
+\item The variable $bitcpy$ indicates how many bits are in the currently formed window.  When it reaches $winsize$ the window is flushed and
+      the appropriate operations performed.
+\item The variable $bitbuf$ holds the current bits of the window being formed.  
+\end{enumerate}
+
+All of step 12 is the window processing loop.  It will iterate while there are digits available form the exponent to read.  The first step
+inside this loop is to extract a new digit if no more bits are available in the current digit.  If there are no bits left a new digit is
+read and if there are no digits left than the loop terminates.  
+
+After a digit is made available step 12.3 will extract the most significant bit of the current digit and move all other bits in the digit
+upwards.  In effect the digit is read from most significant bit to least significant bit and since the digits are read from leading to 
+trailing edges the entire exponent is read from most significant bit to least significant bit.
+
+At step 12.5 if the $mode$ and currently extracted bit $y$ are both zero the bit is ignored and the next bit is read.  This prevents the 
+algorithm from having to perform trivial squaring and reduction operations before the first non-zero bit is read.  Step 12.6 and 12.7-10 handle
+the two cases of $mode = 1$ and $mode = 2$ respectively.  
+
+\begin{center}
+\begin{figure}[here]
+\includegraphics{pics/expt_state.ps}
+\caption{Sliding Window State Diagram}
+\label{pic:expt_state}
+\end{figure}
+\end{center}
+
+By step 13 there are no more digits left in the exponent.  However, there may be partial bits in the window left.  If $mode = 2$ then 
+a Left-to-Right algorithm is used to process the remaining few bits.  
+
+\vspace{+3mm}\begin{small}
+\hspace{-5.1mm}{\bf File}: bn\_s\_mp\_exptmod.c
+\vspace{-3mm}
+\begin{alltt}
+\end{alltt}
+\end{small}
+
+Lines 32 through 46 determine the optimal window size based on the length of the exponent in bits.  The window divisions are sorted
+from smallest to greatest so that in each \textbf{if} statement only one condition must be tested.  For example, by the \textbf{if} statement 
+on line 38 the value of $x$ is already known to be greater than $140$.  
+
+The conditional piece of code beginning on line 48 allows the window size to be restricted to five bits.  This logic is used to ensure
+the table of precomputed powers of $G$ remains relatively small.  
+
+The for loop on line 61 initializes the $M$ array while lines 72 and 77 through 86 initialize the reduction
+function that will be used for this modulus.
+
+-- More later.
+
+\section{Quick Power of Two}
+Calculating $b = 2^a$ can be performed much quicker than with any of the previous algorithms.  Recall that a logical shift left $m << k$ is
+equivalent to $m \cdot 2^k$.  By this logic when $m = 1$ a quick power of two can be achieved.
+
+\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{mp\_2expt}. \\
+\textbf{Input}.   integer $b$ \\
+\textbf{Output}.  $a \leftarrow 2^b$ \\
+\hline \\
+1.  $a \leftarrow 0$ \\
+2.  If $a.alloc < \lfloor b / lg(\beta) \rfloor + 1$ then grow $a$ appropriately. \\
+3.  $a.used \leftarrow \lfloor b / lg(\beta) \rfloor + 1$ \\
+4.  $a_{\lfloor b / lg(\beta) \rfloor} \leftarrow 1 << (b \mbox{ mod } lg(\beta))$ \\
+5.  Return(\textit{MP\_OKAY}). \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Algorithm mp\_2expt}
+\end{figure}
+
+\textbf{Algorithm mp\_2expt.}
+
+\vspace{+3mm}\begin{small}
+\hspace{-5.1mm}{\bf File}: bn\_mp\_2expt.c
+\vspace{-3mm}
+\begin{alltt}
+\end{alltt}
+\end{small}
+
+\chapter{Higher Level Algorithms}
+
+This chapter discusses the various higher level algorithms that are required to complete a well rounded multiple precision integer package.  These
+routines are less performance oriented than the algorithms of chapters five, six and seven but are no less important.  
+
+The first section describes a method of integer division with remainder that is universally well known.  It provides the signed division logic
+for the package.  The subsequent section discusses a set of algorithms which allow a single digit to be the 2nd operand for a variety of operations.  
+These algorithms serve mostly to simplify other algorithms where small constants are required.  The last two sections discuss how to manipulate 
+various representations of integers.  For example, converting from an mp\_int to a string of character.
+
+\section{Integer Division with Remainder}
+\label{sec:division}
+
+Integer division aside from modular exponentiation is the most intensive algorithm to compute.  Like addition, subtraction and multiplication
+the basis of this algorithm is the long-hand division algorithm taught to school children.  Throughout this discussion several common variables
+will be used.  Let $x$ represent the divisor and $y$ represent the dividend.  Let $q$ represent the integer quotient $\lfloor y / x \rfloor$ and 
+let $r$ represent the remainder $r = y - x \lfloor y / x \rfloor$.  The following simple algorithm will be used to start the discussion.
+
+\newpage\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{Radix-$\beta$ Integer Division}. \\
+\textbf{Input}.   integer $x$ and $y$ \\
+\textbf{Output}.  $q = \lfloor y/x\rfloor, r = y - xq$ \\
+\hline \\
+1.  $q \leftarrow 0$ \\
+2.  $n \leftarrow \vert \vert y \vert \vert - \vert \vert x \vert \vert$ \\
+3.  for $t$ from $n$ down to $0$ do \\
+\hspace{3mm}3.1  Maximize $k$ such that $kx\beta^t$ is less than or equal to $y$ and $(k + 1)x\beta^t$ is greater. \\
+\hspace{3mm}3.2  $q \leftarrow q + k\beta^t$ \\
+\hspace{3mm}3.3  $y \leftarrow y - kx\beta^t$ \\
+4.  $r \leftarrow y$ \\
+5.  Return($q, r$) \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Algorithm Radix-$\beta$ Integer Division}
+\label{fig:raddiv}
+\end{figure}
+
+As children we are taught this very simple algorithm for the case of $\beta = 10$.  Almost instinctively several optimizations are taught for which
+their reason of existing are never explained.  For this example let $y = 5471$ represent the dividend and $x = 23$ represent the divisor.
+
+To find the first digit of the quotient the value of $k$ must be maximized such that $kx\beta^t$ is less than or equal to $y$ and 
+simultaneously $(k + 1)x\beta^t$ is greater than $y$.  Implicitly $k$ is the maximum value the $t$'th digit of the quotient may have.  The habitual method
+used to find the maximum is to ``eyeball'' the two numbers, typically only the leading digits and quickly estimate a quotient.  By only using leading
+digits a much simpler division may be used to form an educated guess at what the value must be.  In this case $k = \lfloor 54/23\rfloor = 2$ quickly 
+arises as a possible  solution.  Indeed $2x\beta^2 = 4600$ is less than $y = 5471$ and simultaneously $(k + 1)x\beta^2 = 6900$ is larger than $y$.  
+As a  result $k\beta^2$ is added to the quotient which now equals $q = 200$ and $4600$ is subtracted from $y$ to give a remainder of $y = 841$.
+
+Again this process is repeated to produce the quotient digit $k = 3$ which makes the quotient $q = 200 + 3\beta = 230$ and the remainder 
+$y = 841 - 3x\beta = 181$.  Finally the last iteration of the loop produces $k = 7$ which leads to the quotient $q = 230 + 7 = 237$ and the
+remainder $y = 181 - 7x = 20$.  The final quotient and remainder found are $q = 237$ and $r = y = 20$ which are indeed correct since 
+$237 \cdot 23 + 20 = 5471$ is true.  
+
+\subsection{Quotient Estimation}
+\label{sec:divest}
+As alluded to earlier the quotient digit $k$ can be estimated from only the leading digits of both the divisor and dividend.  When $p$ leading
+digits are used from both the divisor and dividend to form an estimation the accuracy of the estimation rises as $p$ grows.  Technically
+speaking the estimation is based on assuming the lower $\vert \vert y \vert \vert - p$ and $\vert \vert x \vert \vert - p$ lower digits of the
+dividend and divisor are zero.  
+
+The value of the estimation may off by a few values in either direction and in general is fairly correct.  A simplification \cite[pp. 271]{TAOCPV2}
+of the estimation technique is to use $t + 1$ digits of the dividend and $t$ digits of the divisor, in particularly when $t = 1$.  The estimate 
+using this technique is never too small.  For the following proof let $t = \vert \vert y \vert \vert - 1$ and $s = \vert \vert x \vert \vert - 1$ 
+represent the most significant digits of the dividend and divisor respectively.
+
+\textbf{Proof.}\textit{  The quotient $\hat k = \lfloor (y_t\beta + y_{t-1}) / x_s \rfloor$ is greater than or equal to 
+$k = \lfloor y / (x \cdot \beta^{\vert \vert y \vert \vert - \vert \vert x \vert \vert - 1}) \rfloor$. }
+The first obvious case is when $\hat k = \beta - 1$ in which case the proof is concluded since the real quotient cannot be larger.  For all other 
+cases $\hat k = \lfloor (y_t\beta + y_{t-1}) / x_s \rfloor$ and $\hat k x_s \ge y_t\beta + y_{t-1} - x_s + 1$.  The latter portion of the inequalility
+$-x_s + 1$ arises from the fact that a truncated integer division will give the same quotient for at most $x_s - 1$ values.  Next a series of 
+inequalities will prove the hypothesis.
+
+\begin{equation}
+y - \hat k x \le y - \hat k x_s\beta^s
+\end{equation}
+
+This is trivially true since $x \ge x_s\beta^s$.  Next we replace $\hat kx_s\beta^s$ by the previous inequality for $\hat kx_s$.  
+
+\begin{equation}
+y - \hat k x \le y_t\beta^t + \ldots + y_0 - (y_t\beta^t + y_{t-1}\beta^{t-1} - x_s\beta^t + \beta^s)
+\end{equation}
+
+By simplifying the previous inequality the following inequality is formed.
+
+\begin{equation}
+y - \hat k x \le y_{t-2}\beta^{t-2} + \ldots + y_0 + x_s\beta^s - \beta^s
+\end{equation}
+
+Subsequently,
+
+\begin{equation}
+y_{t-2}\beta^{t-2} + \ldots +  y_0  + x_s\beta^s - \beta^s < x_s\beta^s \le x
+\end{equation}
+
+Which proves that $y - \hat kx \le x$ and by consequence $\hat k \ge k$ which concludes the proof.  \textbf{QED}
+
+
+\subsection{Normalized Integers}
+For the purposes of division a normalized input is when the divisors leading digit $x_n$ is greater than or equal to $\beta / 2$.  By multiplying both
+$x$ and $y$ by $j = \lfloor (\beta / 2) / x_n \rfloor$ the quotient remains unchanged and the remainder is simply $j$ times the original
+remainder.  The purpose of normalization is to ensure the leading digit of the divisor is sufficiently large such that the estimated quotient will
+lie in the domain of a single digit.  Consider the maximum dividend $(\beta - 1) \cdot \beta + (\beta - 1)$ and the minimum divisor $\beta / 2$.  
+
+\begin{equation} 
+{{\beta^2 - 1} \over { \beta / 2}} \le 2\beta - {2 \over \beta} 
+\end{equation}
+
+At most the quotient approaches $2\beta$, however, in practice this will not occur since that would imply the previous quotient digit was too small.  
+
+\subsection{Radix-$\beta$ Division with Remainder}
+\newpage\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{mp\_div}. \\
+\textbf{Input}.   mp\_int $a, b$ \\
+\textbf{Output}.  $c = \lfloor a/b \rfloor$, $d = a - bc$ \\
+\hline \\
+1.  If $b = 0$ return(\textit{MP\_VAL}). \\
+2.  If $\vert a \vert < \vert b \vert$ then do \\
+\hspace{3mm}2.1  $d \leftarrow a$ \\
+\hspace{3mm}2.2  $c \leftarrow 0$ \\
+\hspace{3mm}2.3  Return(\textit{MP\_OKAY}). \\
+\\
+Setup the quotient to receive the digits. \\
+3.  Grow $q$ to $a.used + 2$ digits. \\
+4.  $q \leftarrow 0$ \\
+5.  $x \leftarrow \vert a \vert , y \leftarrow \vert b \vert$ \\
+6.  $sign \leftarrow  \left \lbrace \begin{array}{ll}
+                              MP\_ZPOS &  \mbox{if }a.sign = b.sign \\
+                              MP\_NEG  &  \mbox{otherwise} \\
+                              \end{array} \right .$ \\
+\\
+Normalize the inputs such that the leading digit of $y$ is greater than or equal to $\beta / 2$. \\
+7.  $norm \leftarrow (lg(\beta) - 1) - (\lceil lg(y) \rceil \mbox{ (mod }lg(\beta)\mbox{)})$ \\
+8.  $x \leftarrow x \cdot 2^{norm}, y \leftarrow y \cdot 2^{norm}$ \\
+\\
+Find the leading digit of the quotient. \\
+9.  $n \leftarrow x.used - 1, t \leftarrow y.used - 1$ \\
+10.  $y \leftarrow y \cdot \beta^{n - t}$ \\
+11.  While ($x \ge y$) do \\
+\hspace{3mm}11.1  $q_{n - t} \leftarrow q_{n - t} + 1$ \\
+\hspace{3mm}11.2  $x \leftarrow x - y$ \\
+12.  $y \leftarrow \lfloor y / \beta^{n-t} \rfloor$ \\
+\\
+Continued on the next page. \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Algorithm mp\_div}
+\end{figure}
+
+\newpage\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{mp\_div} (continued). \\
+\textbf{Input}.   mp\_int $a, b$ \\
+\textbf{Output}.  $c = \lfloor a/b \rfloor$, $d = a - bc$ \\
+\hline \\
+Now find the remainder fo the digits. \\
+13.  for $i$ from $n$ down to $(t + 1)$ do \\
+\hspace{3mm}13.1  If $i > x.used$ then jump to the next iteration of this loop. \\
+\hspace{3mm}13.2  If $x_{i} = y_{t}$ then \\
+\hspace{6mm}13.2.1  $q_{i - t - 1} \leftarrow \beta - 1$ \\
+\hspace{3mm}13.3  else \\
+\hspace{6mm}13.3.1  $\hat r \leftarrow x_{i} \cdot \beta + x_{i - 1}$ \\
+\hspace{6mm}13.3.2  $\hat r \leftarrow \lfloor \hat r / y_{t} \rfloor$ \\
+\hspace{6mm}13.3.3  $q_{i - t - 1} \leftarrow \hat r$ \\
+\hspace{3mm}13.4  $q_{i - t - 1} \leftarrow q_{i - t - 1} + 1$ \\
+\\
+Fixup quotient estimation. \\
+\hspace{3mm}13.5  Loop \\
+\hspace{6mm}13.5.1  $q_{i - t - 1} \leftarrow q_{i - t - 1} - 1$ \\
+\hspace{6mm}13.5.2  t$1 \leftarrow 0$ \\
+\hspace{6mm}13.5.3  t$1_0 \leftarrow y_{t - 1}, $ t$1_1 \leftarrow y_t,$ t$1.used \leftarrow 2$ \\
+\hspace{6mm}13.5.4  $t1 \leftarrow t1 \cdot q_{i - t - 1}$ \\
+\hspace{6mm}13.5.5  t$2_0 \leftarrow x_{i - 2}, $ t$2_1 \leftarrow x_{i - 1}, $ t$2_2 \leftarrow x_i, $ t$2.used \leftarrow 3$ \\
+\hspace{6mm}13.5.6  If $\vert t1 \vert > \vert t2 \vert$ then goto step 13.5. \\
+\hspace{3mm}13.6  t$1 \leftarrow y \cdot q_{i - t - 1}$ \\
+\hspace{3mm}13.7  t$1 \leftarrow $ t$1 \cdot \beta^{i - t - 1}$ \\
+\hspace{3mm}13.8  $x \leftarrow x - $ t$1$ \\
+\hspace{3mm}13.9  If $x.sign = MP\_NEG$ then \\
+\hspace{6mm}13.10  t$1 \leftarrow y$ \\
+\hspace{6mm}13.11  t$1 \leftarrow $ t$1 \cdot \beta^{i - t - 1}$ \\
+\hspace{6mm}13.12  $x \leftarrow x + $ t$1$ \\
+\hspace{6mm}13.13  $q_{i - t - 1} \leftarrow q_{i - t - 1} - 1$ \\
+\\
+Finalize the result. \\
+14.  Clamp excess digits of $q$ \\
+15.  $c \leftarrow q, c.sign \leftarrow sign$ \\
+16.  $x.sign \leftarrow a.sign$ \\
+17.  $d \leftarrow \lfloor x / 2^{norm} \rfloor$ \\
+18.  Return(\textit{MP\_OKAY}). \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Algorithm mp\_div (continued)}
+\end{figure}
+\textbf{Algorithm mp\_div.}
+This algorithm will calculate quotient and remainder from an integer division given a dividend and divisor.  The algorithm is a signed
+division and will produce a fully qualified quotient and remainder.
+
+First the divisor $b$ must be non-zero which is enforced in step one.  If the divisor is larger than the dividend than the quotient is implicitly 
+zero and the remainder is the dividend.  
+
+After the first two trivial cases of inputs are handled the variable $q$ is setup to receive the digits of the quotient.  Two unsigned copies of the
+divisor $y$ and dividend $x$ are made as well.  The core of the division algorithm is an unsigned division and will only work if the values are
+positive.  Now the two values $x$ and $y$ must be normalized such that the leading digit of $y$ is greater than or equal to $\beta / 2$.  
+This is performed by shifting both to the left by enough bits to get the desired normalization.  
+
+At this point the division algorithm can begin producing digits of the quotient.  Recall that maximum value of the estimation used is 
+$2\beta - {2 \over \beta}$ which means that a digit of the quotient must be first produced by another means.  In this case $y$ is shifted
+to the left (\textit{step ten}) so that it has the same number of digits as $x$.  The loop on step eleven will subtract multiples of the 
+shifted copy of $y$ until $x$ is smaller.  Since the leading digit of $y$ is greater than or equal to $\beta/2$ this loop will iterate at most two
+times to produce the desired leading digit of the quotient.  
+
+Now the remainder of the digits can be produced.  The equation $\hat q = \lfloor {{x_i \beta + x_{i-1}}\over y_t} \rfloor$ is used to fairly
+accurately approximate the true quotient digit.  The estimation can in theory produce an estimation as high as $2\beta - {2 \over \beta}$ but by
+induction the upper quotient digit is correct (\textit{as established on step eleven}) and the estimate must be less than $\beta$.  
+
+Recall from section~\ref{sec:divest} that the estimation is never too low but may be too high.  The next step of the estimation process is
+to refine the estimation.  The loop on step 13.5 uses $x_i\beta^2 + x_{i-1}\beta + x_{i-2}$ and $q_{i - t - 1}(y_t\beta + y_{t-1})$ as a higher
+order approximation to adjust the quotient digit.
+
+After both phases of estimation the quotient digit may still be off by a value of one\footnote{This is similar to the error introduced
+by optimizing Barrett reduction.}.  Steps 13.6 and 13.7 subtract the multiple of the divisor from the dividend (\textit{Similar to step 3.3 of
+algorithm~\ref{fig:raddiv}} and then subsequently add a multiple of the divisor if the quotient was too large.  
+
+Now that the quotient has been determine finializing the result is a matter of clamping the quotient, fixing the sizes and de-normalizing the 
+remainder.  An important aspect of this algorithm seemingly overlooked in other descriptions such as that of Algorithm 14.20 HAC \cite[pp. 598]{HAC}
+is that when the estimations are being made (\textit{inside the loop on step 13.5}) that the digits $y_{t-1}$, $x_{i-2}$ and $x_{i-1}$ may lie 
+outside their respective boundaries.  For example, if $t = 0$ or $i \le 1$ then the digits would be undefined.  In those cases the digits should
+respectively be replaced with a zero.  
+
+\vspace{+3mm}\begin{small}
+\hspace{-5.1mm}{\bf File}: bn\_mp\_div.c
+\vspace{-3mm}
+\begin{alltt}
+\end{alltt}
+\end{small}
+
+The implementation of this algorithm differs slightly from the pseudo code presented previously.  In this algorithm either of the quotient $c$ or
+remainder $d$ may be passed as a \textbf{NULL} pointer which indicates their value is not desired.  For example, the C code to call the division
+algorithm with only the quotient is 
+
+\begin{verbatim}
+mp_div(&a, &b, &c, NULL);  /* c = [a/b] */
+\end{verbatim}
+
+Lines 109 and 113 handle the two trivial cases of inputs which are division by zero and dividend smaller than the divisor 
+respectively.  After the two trivial cases all of the temporary variables are initialized.  Line 148 determines the sign of 
+the quotient and line 148 ensures that both $x$ and $y$ are positive.  
+
+The number of bits in the leading digit is calculated on line 151.  Implictly an mp\_int with $r$ digits will require $lg(\beta)(r-1) + k$ bits
+of precision which when reduced modulo $lg(\beta)$ produces the value of $k$.  In this case $k$ is the number of bits in the leading digit which is
+exactly what is required.  For the algorithm to operate $k$ must equal $lg(\beta) - 1$ and when it does not the inputs must be normalized by shifting
+them to the left by $lg(\beta) - 1 - k$ bits.
+
+Throughout the variables $n$ and $t$ will represent the highest digit of $x$ and $y$ respectively.  These are first used to produce the 
+leading digit of the quotient.  The loop beginning on line 184 will produce the remainder of the quotient digits.
+
+The conditional ``continue'' on line 187 is used to prevent the algorithm from reading past the leading edge of $x$ which can occur when the
+algorithm eliminates multiple non-zero digits in a single iteration.  This ensures that $x_i$ is always non-zero since by definition the digits
+above the $i$'th position $x$ must be zero in order for the quotient to be precise\footnote{Precise as far as integer division is concerned.}.  
+
+Lines 214, 216 and 223 through 225 manually construct the high accuracy estimations by setting the digits of the two mp\_int 
+variables directly.  
+
+\section{Single Digit Helpers}
+
+This section briefly describes a series of single digit helper algorithms which come in handy when working with small constants.  All of 
+the helper functions assume the single digit input is positive and will treat them as such.
+
+\subsection{Single Digit Addition and Subtraction}
+
+Both addition and subtraction are performed by ``cheating'' and using mp\_set followed by the higher level addition or subtraction 
+algorithms.   As a result these algorithms are subtantially simpler with a slight cost in performance.
+
+\newpage\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{mp\_add\_d}. \\
+\textbf{Input}.   mp\_int $a$ and a mp\_digit $b$ \\
+\textbf{Output}.  $c = a + b$ \\
+\hline \\
+1.  $t \leftarrow b$ (\textit{mp\_set}) \\
+2.  $c \leftarrow a + t$ \\
+3.  Return(\textit{MP\_OKAY}) \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Algorithm mp\_add\_d}
+\end{figure}
+
+\textbf{Algorithm mp\_add\_d.}
+This algorithm initiates a temporary mp\_int with the value of the single digit and uses algorithm mp\_add to add the two values together.
+
+\vspace{+3mm}\begin{small}
+\hspace{-5.1mm}{\bf File}: bn\_mp\_add\_d.c
+\vspace{-3mm}
+\begin{alltt}
+\end{alltt}
+\end{small}
+
+Clever use of the letter 't'.
+
+\subsubsection{Subtraction}
+The single digit subtraction algorithm mp\_sub\_d is essentially the same except it uses mp\_sub to subtract the digit from the mp\_int.
+
+\subsection{Single Digit Multiplication}
+Single digit multiplication arises enough in division and radix conversion that it ought to be implement as a special case of the baseline
+multiplication algorithm.  Essentially this algorithm is a modified version of algorithm s\_mp\_mul\_digs where one of the multiplicands
+only has one digit.
+
+\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{mp\_mul\_d}. \\
+\textbf{Input}.   mp\_int $a$ and a mp\_digit $b$ \\
+\textbf{Output}.  $c = ab$ \\
+\hline \\
+1.  $pa \leftarrow a.used$ \\
+2.  Grow $c$ to at least $pa + 1$ digits. \\
+3.  $oldused \leftarrow c.used$ \\
+4.  $c.used \leftarrow pa + 1$ \\
+5.  $c.sign \leftarrow a.sign$ \\
+6.  $\mu \leftarrow 0$ \\
+7.  for $ix$ from $0$ to $pa - 1$ do \\
+\hspace{3mm}7.1  $\hat r \leftarrow \mu + a_{ix}b$ \\
+\hspace{3mm}7.2  $c_{ix} \leftarrow \hat r \mbox{ (mod }\beta\mbox{)}$ \\
+\hspace{3mm}7.3  $\mu \leftarrow \lfloor \hat r / \beta \rfloor$ \\
+8.  $c_{pa} \leftarrow \mu$ \\
+9.  for $ix$ from $pa + 1$ to $oldused$ do \\
+\hspace{3mm}9.1  $c_{ix} \leftarrow 0$ \\
+10.  Clamp excess digits of $c$. \\
+11.  Return(\textit{MP\_OKAY}). \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Algorithm mp\_mul\_d}
+\end{figure}
+\textbf{Algorithm mp\_mul\_d.}
+This algorithm quickly multiplies an mp\_int by a small single digit value.  It is specially tailored to the job and has a minimal of overhead.  
+Unlike the full multiplication algorithms this algorithm does not require any significnat temporary storage or memory allocations.  
+
+\vspace{+3mm}\begin{small}
+\hspace{-5.1mm}{\bf File}: bn\_mp\_mul\_d.c
+\vspace{-3mm}
+\begin{alltt}
+\end{alltt}
+\end{small}
+
+In this implementation the destination $c$ may point to the same mp\_int as the source $a$ since the result is written after the digit is 
+read from the source.  This function uses pointer aliases $tmpa$ and $tmpc$ for the digits of $a$ and $c$ respectively.  
+
+\subsection{Single Digit Division}
+Like the single digit multiplication algorithm, single digit division is also a fairly common algorithm used in radix conversion.  Since the
+divisor is only a single digit a specialized variant of the division algorithm can be used to compute the quotient.  
+
+\newpage\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{mp\_div\_d}. \\
+\textbf{Input}.   mp\_int $a$ and a mp\_digit $b$ \\
+\textbf{Output}.  $c = \lfloor a / b \rfloor, d = a - cb$ \\
+\hline \\
+1.  If $b = 0$ then return(\textit{MP\_VAL}).\\
+2.  If $b = 3$ then use algorithm mp\_div\_3 instead. \\
+3.  Init $q$ to $a.used$ digits.  \\
+4.  $q.used \leftarrow a.used$ \\
+5.  $q.sign \leftarrow a.sign$ \\
+6.  $\hat w \leftarrow 0$ \\
+7.  for $ix$ from $a.used - 1$ down to $0$ do \\
+\hspace{3mm}7.1  $\hat w \leftarrow \hat w \beta + a_{ix}$ \\
+\hspace{3mm}7.2  If $\hat w \ge b$ then \\
+\hspace{6mm}7.2.1  $t \leftarrow \lfloor \hat w / b \rfloor$ \\
+\hspace{6mm}7.2.2  $\hat w \leftarrow \hat w \mbox{ (mod }b\mbox{)}$ \\
+\hspace{3mm}7.3  else\\
+\hspace{6mm}7.3.1  $t \leftarrow 0$ \\
+\hspace{3mm}7.4  $q_{ix} \leftarrow t$ \\
+8.  $d \leftarrow \hat w$ \\
+9.  Clamp excess digits of $q$. \\
+10.  $c \leftarrow q$ \\
+11.  Return(\textit{MP\_OKAY}). \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Algorithm mp\_div\_d}
+\end{figure}
+\textbf{Algorithm mp\_div\_d.}
+This algorithm divides the mp\_int $a$ by the single mp\_digit $b$ using an optimized approach.  Essentially in every iteration of the
+algorithm another digit of the dividend is reduced and another digit of quotient produced.  Provided $b < \beta$ the value of $\hat w$
+after step 7.1 will be limited such that $0 \le \lfloor \hat w / b \rfloor < \beta$.  
+
+If the divisor $b$ is equal to three a variant of this algorithm is used which is called mp\_div\_3.  It replaces the division by three with
+a multiplication by $\lfloor \beta / 3 \rfloor$ and the appropriate shift and residual fixup.  In essence it is much like the Barrett reduction
+from chapter seven.  
+
+\vspace{+3mm}\begin{small}
+\hspace{-5.1mm}{\bf File}: bn\_mp\_div\_d.c
+\vspace{-3mm}
+\begin{alltt}
+\end{alltt}
+\end{small}
+
+Like the implementation of algorithm mp\_div this algorithm allows either of the quotient or remainder to be passed as a \textbf{NULL} pointer to
+indicate the respective value is not required.  This allows a trivial single digit modular reduction algorithm, mp\_mod\_d to be created.
+
+The division and remainder on lines 44 and @45,%@ can be replaced often by a single division on most processors.  For example, the 32-bit x86 based 
+processors can divide a 64-bit quantity by a 32-bit quantity and produce the quotient and remainder simultaneously.  Unfortunately the GCC 
+compiler does not recognize that optimization and will actually produce two function calls to find the quotient and remainder respectively.  
+
+\subsection{Single Digit Root Extraction}
+
+Finding the $n$'th root of an integer is fairly easy as far as numerical analysis is concerned.  Algorithms such as the Newton-Raphson approximation 
+(\ref{eqn:newton}) series will converge very quickly to a root for any continuous function $f(x)$.  
+
+\begin{equation}
+x_{i+1} = x_i - {f(x_i) \over f'(x_i)}
+\label{eqn:newton}
+\end{equation}
+
+In this case the $n$'th root is desired and $f(x) = x^n - a$ where $a$ is the integer of which the root is desired.  The derivative of $f(x)$ is 
+simply $f'(x) = nx^{n - 1}$.  Of particular importance is that this algorithm will be used over the integers not over the a more continuous domain
+such as the real numbers.  As a result the root found can be above the true root by few and must be manually adjusted.  Ideally at the end of the 
+algorithm the $n$'th root $b$ of an integer $a$ is desired such that $b^n \le a$.  
+
+\newpage\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{mp\_n\_root}. \\
+\textbf{Input}.   mp\_int $a$ and a mp\_digit $b$ \\
+\textbf{Output}.  $c^b \le a$ \\
+\hline \\
+1.  If $b$ is even and $a.sign = MP\_NEG$ return(\textit{MP\_VAL}). \\
+2.  $sign \leftarrow a.sign$ \\
+3.  $a.sign \leftarrow MP\_ZPOS$ \\
+4.  t$2 \leftarrow 2$ \\
+5.  Loop \\
+\hspace{3mm}5.1  t$1 \leftarrow $ t$2$ \\
+\hspace{3mm}5.2  t$3 \leftarrow $ t$1^{b - 1}$ \\
+\hspace{3mm}5.3  t$2 \leftarrow $ t$3 $ $\cdot$ t$1$ \\
+\hspace{3mm}5.4  t$2 \leftarrow $ t$2 - a$ \\
+\hspace{3mm}5.5  t$3 \leftarrow $ t$3 \cdot b$ \\
+\hspace{3mm}5.6  t$3 \leftarrow \lfloor $t$2 / $t$3 \rfloor$ \\
+\hspace{3mm}5.7  t$2 \leftarrow $ t$1 - $ t$3$ \\
+\hspace{3mm}5.8  If t$1 \ne $ t$2$ then goto step 5.  \\
+6.  Loop \\
+\hspace{3mm}6.1  t$2 \leftarrow $ t$1^b$ \\
+\hspace{3mm}6.2  If t$2 > a$ then \\
+\hspace{6mm}6.2.1  t$1 \leftarrow $ t$1 - 1$ \\
+\hspace{6mm}6.2.2  Goto step 6. \\
+7.  $a.sign \leftarrow sign$ \\
+8.  $c \leftarrow $ t$1$ \\
+9.  $c.sign \leftarrow sign$  \\
+10.  Return(\textit{MP\_OKAY}).  \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Algorithm mp\_n\_root}
+\end{figure}
+\textbf{Algorithm mp\_n\_root.}
+This algorithm finds the integer $n$'th root of an input using the Newton-Raphson approach.  It is partially optimized based on the observation
+that the numerator of ${f(x) \over f'(x)}$ can be derived from a partial denominator.  That is at first the denominator is calculated by finding
+$x^{b - 1}$.  This value can then be multiplied by $x$ and have $a$ subtracted from it to find the numerator.  This saves a total of $b - 1$ 
+multiplications by t$1$ inside the loop.  
+
+The initial value of the approximation is t$2 = 2$ which allows the algorithm to start with very small values and quickly converge on the
+root.  Ideally this algorithm is meant to find the $n$'th root of an input where $n$ is bounded by $2 \le n \le 5$.  
+
+\vspace{+3mm}\begin{small}
+\hspace{-5.1mm}{\bf File}: bn\_mp\_n\_root.c
+\vspace{-3mm}
+\begin{alltt}
+\end{alltt}
+\end{small}
+
+\section{Random Number Generation}
+
+Random numbers come up in a variety of activities from public key cryptography to simple simulations and various randomized algorithms.  Pollard-Rho 
+factoring for example, can make use of random values as starting points to find factors of a composite integer.  In this case the algorithm presented
+is solely for simulations and not intended for cryptographic use.  
+
+\newpage\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{mp\_rand}. \\
+\textbf{Input}.   An integer $b$ \\
+\textbf{Output}.  A pseudo-random number of $b$ digits \\
+\hline \\
+1.  $a \leftarrow 0$ \\
+2.  If $b \le 0$ return(\textit{MP\_OKAY}) \\
+3.  Pick a non-zero random digit $d$. \\
+4.  $a \leftarrow a + d$ \\
+5.  for $ix$ from 1 to $d - 1$ do \\
+\hspace{3mm}5.1  $a \leftarrow a \cdot \beta$ \\
+\hspace{3mm}5.2  Pick a random digit $d$. \\
+\hspace{3mm}5.3  $a \leftarrow a + d$ \\
+6.  Return(\textit{MP\_OKAY}). \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Algorithm mp\_rand}
+\end{figure}
+\textbf{Algorithm mp\_rand.}
+This algorithm produces a pseudo-random integer of $b$ digits.  By ensuring that the first digit is non-zero the algorithm also guarantees that the
+final result has at least $b$ digits.  It relies heavily on a third-part random number generator which should ideally generate uniformly all of
+the integers from $0$ to $\beta - 1$.  
+
+\vspace{+3mm}\begin{small}
+\hspace{-5.1mm}{\bf File}: bn\_mp\_rand.c
+\vspace{-3mm}
+\begin{alltt}
+\end{alltt}
+\end{small}
+
+\section{Formatted Representations}
+The ability to emit a radix-$n$ textual representation of an integer is useful for interacting with human parties.  For example, the ability to
+be given a string of characters such as ``114585'' and turn it into the radix-$\beta$ equivalent would make it easier to enter numbers
+into a program.
+
+\subsection{Reading Radix-n Input}
+For the purposes of this text we will assume that a simple lower ASCII map (\ref{fig:ASC}) is used for the values of from $0$ to $63$ to 
+printable characters.  For example, when the character ``N'' is read it represents the integer $23$.  The first $16$ characters of the
+map are for the common representations up to hexadecimal.  After that they match the ``base64'' encoding scheme which are suitable chosen
+such that they are printable.  While outputting as base64 may not be too helpful for human operators it does allow communication via non binary
+mediums.
+
+\newpage\begin{figure}[here]
+\begin{center}
+\begin{tabular}{cc|cc|cc|cc}
+\hline \textbf{Value} & \textbf{Char} & \textbf{Value} & \textbf{Char} & \textbf{Value} & \textbf{Char} &  \textbf{Value} & \textbf{Char} \\
+\hline 
+0 & 0 & 1 & 1 & 2 & 2 & 3 & 3 \\
+4 & 4 & 5 & 5 & 6 & 6 & 7 & 7 \\
+8 & 8 & 9 & 9 & 10 & A & 11 & B \\
+12 & C & 13 & D & 14 & E & 15 & F \\
+16 & G & 17 & H & 18 & I & 19 & J \\
+20 & K & 21 & L & 22 & M & 23 & N \\
+24 & O & 25 & P & 26 & Q & 27 & R \\
+28 & S & 29 & T & 30 & U & 31 & V \\
+32 & W & 33 & X & 34 & Y & 35 & Z \\
+36 & a & 37 & b & 38 & c & 39 & d \\
+40 & e & 41 & f & 42 & g & 43 & h \\
+44 & i & 45 & j & 46 & k & 47 & l \\
+48 & m & 49 & n & 50 & o & 51 & p \\
+52 & q & 53 & r & 54 & s & 55 & t \\
+56 & u & 57 & v & 58 & w & 59 & x \\
+60 & y & 61 & z & 62 & $+$ & 63 & $/$ \\
+\hline
+\end{tabular}
+\end{center}
+\caption{Lower ASCII Map}
+\label{fig:ASC}
+\end{figure}
+
+\newpage\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{mp\_read\_radix}. \\
+\textbf{Input}.   A string $str$ of length $sn$ and radix $r$. \\
+\textbf{Output}.  The radix-$\beta$ equivalent mp\_int. \\
+\hline \\
+1.  If $r < 2$ or $r > 64$ return(\textit{MP\_VAL}). \\
+2.  $ix \leftarrow 0$ \\
+3.  If $str_0 =$ ``-'' then do \\
+\hspace{3mm}3.1  $ix \leftarrow ix + 1$ \\
+\hspace{3mm}3.2  $sign \leftarrow MP\_NEG$ \\
+4.  else \\
+\hspace{3mm}4.1  $sign \leftarrow MP\_ZPOS$ \\
+5.  $a \leftarrow 0$ \\
+6.  for $iy$ from $ix$ to $sn - 1$ do \\
+\hspace{3mm}6.1  Let $y$ denote the position in the map of $str_{iy}$. \\
+\hspace{3mm}6.2  If $str_{iy}$ is not in the map or $y \ge r$ then goto step 7. \\
+\hspace{3mm}6.3  $a \leftarrow a \cdot r$ \\
+\hspace{3mm}6.4  $a \leftarrow a + y$ \\
+7.  If $a \ne 0$ then $a.sign \leftarrow sign$ \\
+8.  Return(\textit{MP\_OKAY}). \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Algorithm mp\_read\_radix}
+\end{figure}
+\textbf{Algorithm mp\_read\_radix.}
+This algorithm will read an ASCII string and produce the radix-$\beta$ mp\_int representation of the same integer.  A minus symbol ``-'' may precede the 
+string  to indicate the value is negative, otherwise it is assumed to be positive.  The algorithm will read up to $sn$ characters from the input
+and will stop when it reads a character it cannot map the algorithm stops reading characters from the string.  This allows numbers to be embedded
+as part of larger input without any significant problem.
+
+\vspace{+3mm}\begin{small}
+\hspace{-5.1mm}{\bf File}: bn\_mp\_read\_radix.c
+\vspace{-3mm}
+\begin{alltt}
+\end{alltt}
+\end{small}
+
+\subsection{Generating Radix-$n$ Output}
+Generating radix-$n$ output is fairly trivial with a division and remainder algorithm.  
+
+\newpage\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{mp\_toradix}. \\
+\textbf{Input}.   A mp\_int $a$ and an integer $r$\\
+\textbf{Output}.  The radix-$r$ representation of $a$ \\
+\hline \\
+1.  If $r < 2$ or $r > 64$ return(\textit{MP\_VAL}). \\
+2.  If $a = 0$ then $str = $ ``$0$'' and return(\textit{MP\_OKAY}).  \\
+3.  $t \leftarrow a$ \\
+4.  $str \leftarrow$ ``'' \\
+5.  if $t.sign = MP\_NEG$ then \\
+\hspace{3mm}5.1  $str \leftarrow str + $ ``-'' \\
+\hspace{3mm}5.2  $t.sign = MP\_ZPOS$ \\
+6.  While ($t \ne 0$) do \\
+\hspace{3mm}6.1  $d \leftarrow t \mbox{ (mod }r\mbox{)}$ \\
+\hspace{3mm}6.2  $t \leftarrow \lfloor t / r \rfloor$ \\
+\hspace{3mm}6.3  Look up $d$ in the map and store the equivalent character in $y$. \\
+\hspace{3mm}6.4  $str \leftarrow str + y$ \\
+7.  If $str_0 = $``$-$'' then \\
+\hspace{3mm}7.1  Reverse the digits $str_1, str_2, \ldots str_n$. \\
+8.  Otherwise \\
+\hspace{3mm}8.1  Reverse the digits $str_0, str_1, \ldots str_n$. \\
+9.  Return(\textit{MP\_OKAY}).\\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Algorithm mp\_toradix}
+\end{figure}
+\textbf{Algorithm mp\_toradix.}
+This algorithm computes the radix-$r$ representation of an mp\_int $a$.  The ``digits'' of the representation are extracted by reducing 
+successive powers of $\lfloor a / r^k \rfloor$ the input modulo $r$ until $r^k > a$.  Note that instead of actually dividing by $r^k$ in
+each iteration the quotient $\lfloor a / r \rfloor$ is saved for the next iteration.  As a result a series of trivial $n \times 1$ divisions
+are required instead of a series of $n \times k$ divisions.  One design flaw of this approach is that the digits are produced in the reverse order 
+(see~\ref{fig:mpradix}).  To remedy this flaw the digits must be swapped or simply ``reversed''.
+
+\begin{figure}
+\begin{center}
+\begin{tabular}{|c|c|c|}
+\hline \textbf{Value of $a$} & \textbf{Value of $d$} & \textbf{Value of $str$} \\
+\hline $1234$ & -- & -- \\
+\hline $123$  & $4$ & ``4'' \\
+\hline $12$   & $3$ & ``43'' \\
+\hline $1$    & $2$ & ``432'' \\
+\hline $0$    & $1$ & ``4321'' \\
+\hline
+\end{tabular}
+\end{center}
+\caption{Example of Algorithm mp\_toradix.}
+\label{fig:mpradix}
+\end{figure}
+
+\vspace{+3mm}\begin{small}
+\hspace{-5.1mm}{\bf File}: bn\_mp\_toradix.c
+\vspace{-3mm}
+\begin{alltt}
+\end{alltt}
+\end{small}
+
+\chapter{Number Theoretic Algorithms}
+This chapter discusses several fundamental number theoretic algorithms such as the greatest common divisor, least common multiple and Jacobi 
+symbol computation.  These algorithms arise as essential components in several key cryptographic algorithms such as the RSA public key algorithm and
+various Sieve based factoring algorithms.
+
+\section{Greatest Common Divisor}
+The greatest common divisor of two integers $a$ and $b$, often denoted as $(a, b)$ is the largest integer $k$ that is a proper divisor of
+both $a$ and $b$.  That is, $k$ is the largest integer such that $0 \equiv a \mbox{ (mod }k\mbox{)}$ and $0 \equiv b \mbox{ (mod }k\mbox{)}$ occur
+simultaneously.
+
+The most common approach (cite) is to reduce one input modulo another.  That is if $a$ and $b$ are divisible by some integer $k$ and if $qa + r = b$ then
+$r$ is also divisible by $k$.  The reduction pattern follows $\left < a , b \right > \rightarrow \left < b, a \mbox{ mod } b \right >$.  
+
+\newpage\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{Greatest Common Divisor (I)}. \\
+\textbf{Input}.   Two positive integers $a$ and $b$ greater than zero. \\
+\textbf{Output}.  The greatest common divisor $(a, b)$.  \\
+\hline \\
+1.  While ($b > 0$) do \\
+\hspace{3mm}1.1  $r \leftarrow a \mbox{ (mod }b\mbox{)}$ \\
+\hspace{3mm}1.2  $a \leftarrow b$ \\
+\hspace{3mm}1.3  $b \leftarrow r$ \\
+2.  Return($a$). \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Algorithm Greatest Common Divisor (I)}
+\label{fig:gcd1}
+\end{figure}
+
+This algorithm will quickly converge on the greatest common divisor since the residue $r$ tends diminish rapidly.  However, divisions are
+relatively expensive operations to perform and should ideally be avoided.  There is another approach based on a similar relationship of 
+greatest common divisors.  The faster approach is based on the observation that if $k$ divides both $a$ and $b$ it will also divide $a - b$.  
+In particular, we would like $a - b$ to decrease in magnitude which implies that $b \ge a$.  
+
+\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{Greatest Common Divisor (II)}. \\
+\textbf{Input}.   Two positive integers $a$ and $b$ greater than zero. \\
+\textbf{Output}.  The greatest common divisor $(a, b)$.  \\
+\hline \\
+1.  While ($b > 0$) do \\
+\hspace{3mm}1.1  Swap $a$ and $b$ such that $a$ is the smallest of the two. \\
+\hspace{3mm}1.2  $b \leftarrow b - a$ \\
+2.  Return($a$). \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Algorithm Greatest Common Divisor (II)}
+\label{fig:gcd2}
+\end{figure}
+
+\textbf{Proof} \textit{Algorithm~\ref{fig:gcd2} will return the greatest common divisor of $a$ and $b$.}
+The algorithm in figure~\ref{fig:gcd2} will eventually terminate since $b \ge a$ the subtraction in step 1.2 will be a value less than $b$.  In other
+words in every iteration that tuple $\left < a, b \right >$ decrease in magnitude until eventually $a = b$.  Since both $a$ and $b$ are always 
+divisible by the greatest common divisor (\textit{until the last iteration}) and in the last iteration of the algorithm $b = 0$, therefore, in the 
+second to last iteration of the algorithm $b = a$ and clearly $(a, a) = a$ which concludes the proof.  \textbf{QED}.
+
+As a matter of practicality algorithm \ref{fig:gcd1} decreases far too slowly to be useful.  Specially if $b$ is much larger than $a$ such that 
+$b - a$ is still very much larger than $a$.  A simple addition to the algorithm is to divide $b - a$ by a power of some integer $p$ which does
+not divide the greatest common divisor but will divide $b - a$.  In this case ${b - a} \over p$ is also an integer and still divisible by
+the greatest common divisor.
+
+However, instead of factoring $b - a$ to find a suitable value of $p$ the powers of $p$ can be removed from $a$ and $b$ that are in common first.  
+Then inside the loop whenever $b - a$ is divisible by some power of $p$ it can be safely removed.  
+
+\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{Greatest Common Divisor (III)}. \\
+\textbf{Input}.   Two positive integers $a$ and $b$ greater than zero. \\
+\textbf{Output}.  The greatest common divisor $(a, b)$.  \\
+\hline \\
+1.  $k \leftarrow 0$ \\
+2.  While $a$ and $b$ are both divisible by $p$ do \\
+\hspace{3mm}2.1  $a \leftarrow \lfloor a / p \rfloor$ \\
+\hspace{3mm}2.2  $b \leftarrow \lfloor b / p \rfloor$ \\
+\hspace{3mm}2.3  $k \leftarrow k + 1$ \\
+3.  While $a$ is divisible by $p$ do \\
+\hspace{3mm}3.1  $a \leftarrow \lfloor a / p \rfloor$ \\
+4.  While $b$ is divisible by $p$ do \\
+\hspace{3mm}4.1  $b \leftarrow \lfloor b / p \rfloor$ \\
+5.  While ($b > 0$) do \\
+\hspace{3mm}5.1  Swap $a$ and $b$ such that $a$ is the smallest of the two. \\
+\hspace{3mm}5.2  $b \leftarrow b - a$ \\
+\hspace{3mm}5.3  While $b$ is divisible by $p$ do \\
+\hspace{6mm}5.3.1  $b \leftarrow \lfloor b / p \rfloor$ \\
+6.  Return($a \cdot p^k$). \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Algorithm Greatest Common Divisor (III)}
+\label{fig:gcd3}
+\end{figure}
+
+This algorithm is based on the first except it removes powers of $p$ first and inside the main loop to ensure the tuple $\left < a, b \right >$ 
+decreases more rapidly.  The first loop on step two removes powers of $p$ that are in common.  A count, $k$, is kept which will present a common
+divisor of $p^k$.  After step two the remaining common divisor of $a$ and $b$ cannot be divisible by $p$.  This means that $p$ can be safely 
+divided out of the difference $b - a$ so long as the division leaves no remainder.  
+
+In particular the value of $p$ should be chosen such that the division on step 5.3.1 occur often.  It also helps that division by $p$ be easy
+to compute.  The ideal choice of $p$ is two since division by two amounts to a right logical shift.  Another important observation is that by
+step five both $a$ and $b$ are odd.  Therefore, the diffrence $b - a$ must be even which means that each iteration removes one bit from the 
+largest of the pair.
+
+\subsection{Complete Greatest Common Divisor}
+The algorithms presented so far cannot handle inputs which are zero or negative.  The following algorithm can handle all input cases properly
+and will produce the greatest common divisor.
+
+\newpage\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{mp\_gcd}. \\
+\textbf{Input}.   mp\_int $a$ and $b$ \\
+\textbf{Output}.  The greatest common divisor $c = (a, b)$.  \\
+\hline \\
+1.  If $a = 0$ then \\
+\hspace{3mm}1.1  $c \leftarrow \vert b \vert $ \\
+\hspace{3mm}1.2  Return(\textit{MP\_OKAY}). \\
+2.  If $b = 0$ then \\
+\hspace{3mm}2.1  $c \leftarrow \vert a \vert $ \\
+\hspace{3mm}2.2  Return(\textit{MP\_OKAY}). \\
+3.  $u \leftarrow \vert a \vert, v \leftarrow \vert b \vert$ \\
+4.  $k \leftarrow 0$ \\
+5.  While $u.used > 0$ and $v.used > 0$ and $u_0 \equiv v_0 \equiv 0 \mbox{ (mod }2\mbox{)}$ \\
+\hspace{3mm}5.1  $k \leftarrow k + 1$ \\
+\hspace{3mm}5.2  $u \leftarrow \lfloor u / 2 \rfloor$ \\
+\hspace{3mm}5.3  $v \leftarrow \lfloor v / 2 \rfloor$ \\
+6.  While $u.used > 0$ and $u_0 \equiv 0 \mbox{ (mod }2\mbox{)}$ \\
+\hspace{3mm}6.1  $u \leftarrow \lfloor u / 2 \rfloor$ \\
+7.  While $v.used > 0$ and $v_0 \equiv 0 \mbox{ (mod }2\mbox{)}$ \\
+\hspace{3mm}7.1  $v \leftarrow \lfloor v / 2 \rfloor$ \\
+8.  While $v.used > 0$ \\
+\hspace{3mm}8.1  If $\vert u \vert > \vert v \vert$ then \\
+\hspace{6mm}8.1.1  Swap $u$ and $v$. \\
+\hspace{3mm}8.2  $v \leftarrow \vert v \vert - \vert u \vert$ \\
+\hspace{3mm}8.3  While $v.used > 0$ and $v_0 \equiv 0 \mbox{ (mod }2\mbox{)}$ \\
+\hspace{6mm}8.3.1  $v \leftarrow \lfloor v / 2 \rfloor$ \\
+9.  $c \leftarrow u \cdot 2^k$ \\
+10.  Return(\textit{MP\_OKAY}). \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Algorithm mp\_gcd}
+\end{figure}
+\textbf{Algorithm mp\_gcd.}
+This algorithm will produce the greatest common divisor of two mp\_ints $a$ and $b$.  The algorithm was originally based on Algorithm B of
+Knuth \cite[pp. 338]{TAOCPV2} but has been modified to be simpler to explain.  In theory it achieves the same asymptotic working time as
+Algorithm B and in practice this appears to be true.  
+
+The first two steps handle the cases where either one of or both inputs are zero.  If either input is zero the greatest common divisor is the 
+largest input or zero if they are both zero.  If the inputs are not trivial than $u$ and $v$ are assigned the absolute values of 
+$a$ and $b$ respectively and the algorithm will proceed to reduce the pair.
+
+Step five will divide out any common factors of two and keep track of the count in the variable $k$.  After this step, two is no longer a
+factor of the remaining greatest common divisor between $u$ and $v$ and can be safely evenly divided out of either whenever they are even.  Step 
+six and seven ensure that the $u$ and $v$ respectively have no more factors of two.  At most only one of the while--loops will iterate since 
+they cannot both be even.
+
+By step eight both of $u$ and $v$ are odd which is required for the inner logic.  First the pair are swapped such that $v$ is equal to
+or greater than $u$.  This ensures that the subtraction on step 8.2 will always produce a positive and even result.  Step 8.3 removes any
+factors of two from the difference $u$ to ensure that in the next iteration of the loop both are once again odd.
+
+After $v = 0$ occurs the variable $u$ has the greatest common divisor of the pair $\left < u, v \right >$ just after step six.  The result
+must be adjusted by multiplying by the common factors of two ($2^k$) removed earlier.  
+
+\vspace{+3mm}\begin{small}
+\hspace{-5.1mm}{\bf File}: bn\_mp\_gcd.c
+\vspace{-3mm}
+\begin{alltt}
+\end{alltt}
+\end{small}
+
+This function makes use of the macros mp\_iszero and mp\_iseven.  The former evaluates to $1$ if the input mp\_int is equivalent to the 
+integer zero otherwise it evaluates to $0$.  The latter evaluates to $1$ if the input mp\_int represents a non-zero even integer otherwise
+it evaluates to $0$.  Note that just because mp\_iseven may evaluate to $0$ does not mean the input is odd, it could also be zero.  The three 
+trivial cases of inputs are handled on lines 24 through 30.  After those lines the inputs are assumed to be non-zero.
+
+Lines 32 and 37 make local copies $u$ and $v$ of the inputs $a$ and $b$ respectively.  At this point the common factors of two 
+must be divided out of the two inputs.  The block starting at line 44 removes common factors of two by first counting the number of trailing
+zero bits in both.  The local integer $k$ is used to keep track of how many factors of $2$ are pulled out of both values.  It is assumed that 
+the number of factors will not exceed the maximum value of a C ``int'' data type\footnote{Strictly speaking no array in C may have more than 
+entries than are accessible by an ``int'' so this is not a limitation.}.  
+
+At this point there are no more common factors of two in the two values.  The divisions by a power of two on lines 62 and 68 remove 
+any independent factors of two such that both $u$ and $v$ are guaranteed to be an odd integer before hitting the main body of the algorithm.  The while loop
+on line 73 performs the reduction of the pair until $v$ is equal to zero.  The unsigned comparison and subtraction algorithms are used in
+place of the full signed routines since both values are guaranteed to be positive and the result of the subtraction is guaranteed to be non-negative.
+
+\section{Least Common Multiple}
+The least common multiple of a pair of integers is their product divided by their greatest common divisor.  For two integers $a$ and $b$ the
+least common multiple is normally denoted as $[ a, b ]$ and numerically equivalent to ${ab} \over {(a, b)}$.  For example, if $a = 2 \cdot 2 \cdot 3 = 12$
+and $b = 2 \cdot 3 \cdot 3 \cdot 7 = 126$ the least common multiple is ${126 \over {(12, 126)}} = {126 \over 6} = 21$.
+
+The least common multiple arises often in coding theory as well as number theory.  If two functions have periods of $a$ and $b$ respectively they will
+collide, that is be in synchronous states, after only $[ a, b ]$ iterations.  This is why, for example, random number generators based on 
+Linear Feedback Shift Registers (LFSR) tend to use registers with periods which are co-prime (\textit{e.g. the greatest common divisor is one.}).  
+Similarly in number theory if a composite $n$ has two prime factors $p$ and $q$ then maximal order of any unit of $\Z/n\Z$ will be $[ p - 1, q - 1] $.
+
+\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{mp\_lcm}. \\
+\textbf{Input}.   mp\_int $a$ and $b$ \\
+\textbf{Output}.  The least common multiple $c = [a, b]$.  \\
+\hline \\
+1.  $c \leftarrow (a, b)$ \\
+2.  $t \leftarrow a \cdot b$ \\
+3.  $c \leftarrow \lfloor t / c \rfloor$ \\
+4.  Return(\textit{MP\_OKAY}). \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Algorithm mp\_lcm}
+\end{figure}
+\textbf{Algorithm mp\_lcm.}
+This algorithm computes the least common multiple of two mp\_int inputs $a$ and $b$.  It computes the least common multiple directly by
+dividing the product of the two inputs by their greatest common divisor.
+
+\vspace{+3mm}\begin{small}
+\hspace{-5.1mm}{\bf File}: bn\_mp\_lcm.c
+\vspace{-3mm}
+\begin{alltt}
+\end{alltt}
+\end{small}
+
+\section{Jacobi Symbol Computation}
+To explain the Jacobi Symbol we shall first discuss the Legendre function\footnote{Arrg.  What is the name of this?} off which the Jacobi symbol is 
+defined.  The Legendre function computes whether or not an integer $a$ is a quadratic residue modulo an odd prime $p$.  Numerically it is
+equivalent to equation \ref{eqn:legendre}.
+
+\textit{-- Tom, don't be an ass, cite your source here...!}
+
+\begin{equation}
+a^{(p-1)/2} \equiv \begin{array}{rl}
+                              -1 &  \mbox{if }a\mbox{ is a quadratic non-residue.} \\
+                              0  &  \mbox{if }a\mbox{ divides }p\mbox{.} \\
+                              1  &  \mbox{if }a\mbox{ is a quadratic residue}. 
+                              \end{array} \mbox{ (mod }p\mbox{)}
+\label{eqn:legendre}                              
+\end{equation}
+
+\textbf{Proof.} \textit{Equation \ref{eqn:legendre} correctly identifies the residue status of an integer $a$ modulo a prime $p$.}
+An integer $a$ is a quadratic residue if the following equation has a solution.
+
+\begin{equation}
+x^2 \equiv a \mbox{ (mod }p\mbox{)}
+\label{eqn:root}
+\end{equation}
+
+Consider the following equation.
+
+\begin{equation}
+0 \equiv x^{p-1} - 1 \equiv \left \lbrace \left (x^2 \right )^{(p-1)/2} - a^{(p-1)/2} \right \rbrace + \left ( a^{(p-1)/2} - 1 \right ) \mbox{ (mod }p\mbox{)}
+\label{eqn:rooti}
+\end{equation}
+
+Whether equation \ref{eqn:root} has a solution or not equation \ref{eqn:rooti} is always true.  If $a^{(p-1)/2} - 1 \equiv 0 \mbox{ (mod }p\mbox{)}$
+then the quantity in the braces must be zero.  By reduction,
+
+\begin{eqnarray}
+\left (x^2 \right )^{(p-1)/2} - a^{(p-1)/2} \equiv 0  \nonumber \\
+\left (x^2 \right )^{(p-1)/2} \equiv a^{(p-1)/2} \nonumber \\
+x^2 \equiv a \mbox{ (mod }p\mbox{)} 
+\end{eqnarray}
+
+As a result there must be a solution to the quadratic equation and in turn $a$ must be a quadratic residue.  If $a$ does not divide $p$ and $a$
+is not a quadratic residue then the only other value $a^{(p-1)/2}$ may be congruent to is $-1$ since
+\begin{equation}
+0 \equiv a^{p - 1} - 1 \equiv (a^{(p-1)/2} + 1)(a^{(p-1)/2} - 1) \mbox{ (mod }p\mbox{)}
+\end{equation}
+One of the terms on the right hand side must be zero.  \textbf{QED}
+
+\subsection{Jacobi Symbol}
+The Jacobi symbol is a generalization of the Legendre function for any odd non prime moduli $p$ greater than 2.  If $p = \prod_{i=0}^n p_i$ then
+the Jacobi symbol $\left ( { a \over p } \right )$ is equal to the following equation.
+
+\begin{equation}
+\left ( { a \over p } \right ) = \left ( { a \over p_0} \right ) \left ( { a \over p_1} \right ) \ldots \left ( { a \over p_n} \right )
+\end{equation}
+
+By inspection if $p$ is prime the Jacobi symbol is equivalent to the Legendre function.  The following facts\footnote{See HAC \cite[pp. 72-74]{HAC} for
+further details.} will be used to derive an efficient Jacobi symbol algorithm.  Where $p$ is an odd integer greater than two and $a, b \in \Z$ the
+following are true.  
+
+\begin{enumerate}
+\item $\left ( { a \over p} \right )$ equals $-1$, $0$ or $1$. 
+\item $\left ( { ab \over p} \right ) = \left ( { a \over p} \right )\left ( { b \over p} \right )$.
+\item If $a \equiv b$ then $\left ( { a \over p} \right ) = \left ( { b \over p} \right )$.
+\item $\left ( { 2 \over p} \right )$ equals $1$ if $p \equiv 1$ or $7 \mbox{ (mod }8\mbox{)}$.  Otherwise, it equals $-1$.
+\item $\left ( { a \over p} \right ) \equiv \left ( { p \over a} \right ) \cdot (-1)^{(p-1)(a-1)/4}$.  More specifically 
+$\left ( { a \over p} \right ) = \left ( { p \over a} \right )$ if $p \equiv a \equiv 1 \mbox{ (mod }4\mbox{)}$.  
+\end{enumerate}
+
+Using these facts if $a = 2^k \cdot a'$ then
+
+\begin{eqnarray}
+\left ( { a \over p } \right ) = \left ( {{2^k} \over p } \right ) \left ( {a' \over p} \right ) \nonumber \\
+                               = \left ( {2 \over p } \right )^k \left ( {a' \over p} \right ) 
+\label{eqn:jacobi}
+\end{eqnarray}
+
+By fact five, 
+
+\begin{equation}
+\left ( { a \over p } \right ) = \left ( { p \over a } \right ) \cdot (-1)^{(p-1)(a-1)/4} 
+\end{equation}
+
+Subsequently by fact three since $p \equiv (p \mbox{ mod }a) \mbox{ (mod }a\mbox{)}$ then 
+
+\begin{equation}
+\left ( { a \over p } \right ) = \left ( { {p \mbox{ mod } a} \over a } \right ) \cdot (-1)^{(p-1)(a-1)/4} 
+\end{equation}
+
+By putting both observations into equation \ref{eqn:jacobi} the following simplified equation is formed.
+
+\begin{equation}
+\left ( { a \over p } \right ) = \left ( {2 \over p } \right )^k \left ( {{p\mbox{ mod }a'} \over a'} \right )  \cdot (-1)^{(p-1)(a'-1)/4} 
+\end{equation}
+
+The value of $\left ( {{p \mbox{ mod }a'} \over a'} \right )$ can be found by using the same equation recursively.  The value of 
+$\left ( {2 \over p } \right )^k$ equals $1$ if $k$ is even otherwise it equals $\left ( {2 \over p } \right )$.  Using this approach the 
+factors of $p$ do not have to be known.  Furthermore, if $(a, p) = 1$ then the algorithm will terminate when the recursion requests the 
+Jacobi symbol computation of $\left ( {1 \over a'} \right )$ which is simply $1$.  
+
+\newpage\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{mp\_jacobi}. \\
+\textbf{Input}.   mp\_int $a$ and $p$, $a \ge 0$, $p \ge 3$, $p \equiv 1 \mbox{ (mod }2\mbox{)}$ \\
+\textbf{Output}.  The Jacobi symbol $c = \left ( {a \over p } \right )$. \\
+\hline \\
+1.  If $a = 0$ then \\
+\hspace{3mm}1.1  $c \leftarrow 0$ \\
+\hspace{3mm}1.2  Return(\textit{MP\_OKAY}). \\
+2.  If $a = 1$ then \\
+\hspace{3mm}2.1  $c \leftarrow 1$ \\
+\hspace{3mm}2.2  Return(\textit{MP\_OKAY}). \\
+3.  $a' \leftarrow a$ \\
+4.  $k \leftarrow 0$ \\
+5.  While $a'.used > 0$ and $a'_0 \equiv 0 \mbox{ (mod }2\mbox{)}$ \\
+\hspace{3mm}5.1  $k \leftarrow k + 1$ \\
+\hspace{3mm}5.2  $a' \leftarrow \lfloor a' / 2 \rfloor$ \\
+6.  If $k \equiv 0 \mbox{ (mod }2\mbox{)}$ then \\
+\hspace{3mm}6.1  $s \leftarrow 1$ \\
+7.  else \\
+\hspace{3mm}7.1  $r \leftarrow p_0 \mbox{ (mod }8\mbox{)}$ \\
+\hspace{3mm}7.2  If $r = 1$ or $r = 7$ then \\
+\hspace{6mm}7.2.1  $s \leftarrow 1$ \\
+\hspace{3mm}7.3  else \\
+\hspace{6mm}7.3.1  $s \leftarrow -1$ \\
+8.  If $p_0 \equiv a'_0 \equiv 3 \mbox{ (mod }4\mbox{)}$ then \\
+\hspace{3mm}8.1  $s \leftarrow -s$ \\
+9.  If $a' \ne 1$ then \\
+\hspace{3mm}9.1  $p' \leftarrow p \mbox{ (mod }a'\mbox{)}$ \\
+\hspace{3mm}9.2  $s \leftarrow s \cdot \mbox{mp\_jacobi}(p', a')$ \\
+10.  $c \leftarrow s$ \\
+11.  Return(\textit{MP\_OKAY}). \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Algorithm mp\_jacobi}
+\end{figure}
+\textbf{Algorithm mp\_jacobi.}
+This algorithm computes the Jacobi symbol for an arbitrary positive integer $a$ with respect to an odd integer $p$ greater than three.  The algorithm
+is based on algorithm 2.149 of HAC \cite[pp. 73]{HAC}.  
+
+Step numbers one and two handle the trivial cases of $a = 0$ and $a = 1$ respectively.  Step five determines the number of two factors in the
+input $a$.  If $k$ is even than the term $\left ( { 2 \over p } \right )^k$ must always evaluate to one.  If $k$ is odd than the term evaluates to one 
+if $p_0$ is congruent to one or seven modulo eight, otherwise it evaluates to $-1$. After the the $\left ( { 2 \over p } \right )^k$ term is handled 
+the $(-1)^{(p-1)(a'-1)/4}$ is computed and multiplied against the current product $s$.  The latter term evaluates to one if both $p$ and $a'$ 
+are congruent to one modulo four, otherwise it evaluates to negative one.
+
+By step nine if $a'$ does not equal one a recursion is required.  Step 9.1 computes $p' \equiv p \mbox{ (mod }a'\mbox{)}$ and will recurse to compute
+$\left ( {p' \over a'} \right )$ which is multiplied against the current Jacobi product.
+
+\vspace{+3mm}\begin{small}
+\hspace{-5.1mm}{\bf File}: bn\_mp\_jacobi.c
+\vspace{-3mm}
+\begin{alltt}
+\end{alltt}
+\end{small}
+
+As a matter of practicality the variable $a'$ as per the pseudo-code is reprensented by the variable $a1$ since the $'$ symbol is not valid for a C 
+variable name character. 
+
+The two simple cases of $a = 0$ and $a = 1$ are handled at the very beginning to simplify the algorithm.  If the input is non-trivial the algorithm
+has to proceed compute the Jacobi.  The variable $s$ is used to hold the current Jacobi product.  Note that $s$ is merely a C ``int'' data type since
+the values it may obtain are merely $-1$, $0$ and $1$.  
+
+After a local copy of $a$ is made all of the factors of two are divided out and the total stored in $k$.  Technically only the least significant
+bit of $k$ is required, however, it makes the algorithm simpler to follow to perform an addition. In practice an exclusive-or and addition have the same 
+processor requirements and neither is faster than the other.
+
+Line 58 through 71 determines the value of $\left ( { 2 \over p } \right )^k$.  If the least significant bit of $k$ is zero than
+$k$ is even and the value is one.  Otherwise, the value of $s$ depends on which residue class $p$ belongs to modulo eight.  The value of
+$(-1)^{(p-1)(a'-1)/4}$ is compute and multiplied against $s$ on lines 71 through 74.  
+
+Finally, if $a1$ does not equal one the algorithm must recurse and compute $\left ( {p' \over a'} \right )$.  
+
+\textit{-- Comment about default $s$ and such...}
+
+\section{Modular Inverse}
+\label{sec:modinv}
+The modular inverse of a number actually refers to the modular multiplicative inverse.  Essentially for any integer $a$ such that $(a, p) = 1$ there
+exist another integer $b$ such that $ab \equiv 1 \mbox{ (mod }p\mbox{)}$.  The integer $b$ is called the multiplicative inverse of $a$ which is
+denoted as $b = a^{-1}$.  Technically speaking modular inversion is a well defined operation for any finite ring or field not just for rings and 
+fields of integers.  However, the former will be the matter of discussion.
+
+The simplest approach is to compute the algebraic inverse of the input.  That is to compute $b \equiv a^{\Phi(p) - 1}$.  If $\Phi(p)$ is the 
+order of the multiplicative subgroup modulo $p$ then $b$ must be the multiplicative inverse of $a$.  The proof of which is trivial.
+
+\begin{equation}
+ab \equiv a \left (a^{\Phi(p) - 1} \right ) \equiv a^{\Phi(p)} \equiv a^0 \equiv 1 \mbox{ (mod }p\mbox{)}
+\end{equation}
+
+However, as simple as this approach may be it has two serious flaws.  It requires that the value of $\Phi(p)$ be known which if $p$ is composite 
+requires all of the prime factors.  This approach also is very slow as the size of $p$ grows.  
+
+A simpler approach is based on the observation that solving for the multiplicative inverse is equivalent to solving the linear 
+Diophantine\footnote{See LeVeque \cite[pp. 40-43]{LeVeque} for more information.} equation.
+
+\begin{equation}
+ab + pq = 1
+\end{equation}
+
+Where $a$, $b$, $p$ and $q$ are all integers.  If such a pair of integers $ \left < b, q \right >$ exist than $b$ is the multiplicative inverse of 
+$a$ modulo $p$.  The extended Euclidean algorithm (Knuth \cite[pp. 342]{TAOCPV2}) can be used to solve such equations provided $(a, p) = 1$.  
+However, instead of using that algorithm directly a variant known as the binary Extended Euclidean algorithm will be used in its place.  The
+binary approach is very similar to the binary greatest common divisor algorithm except it will produce a full solution to the Diophantine 
+equation.  
+
+\subsection{General Case}
+\newpage\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{mp\_invmod}. \\
+\textbf{Input}.   mp\_int $a$ and $b$, $(a, b) = 1$, $p \ge 2$, $0 < a < p$.  \\
+\textbf{Output}.  The modular inverse $c \equiv a^{-1} \mbox{ (mod }b\mbox{)}$. \\
+\hline \\
+1.  If $b \le 0$ then return(\textit{MP\_VAL}). \\
+2.  If $b_0 \equiv 1 \mbox{ (mod }2\mbox{)}$ then use algorithm fast\_mp\_invmod. \\
+3.  $x \leftarrow \vert a \vert, y \leftarrow b$ \\
+4.  If $x_0 \equiv y_0  \equiv 0 \mbox{ (mod }2\mbox{)}$ then return(\textit{MP\_VAL}). \\
+5.  $B \leftarrow 0, C \leftarrow 0, A \leftarrow 1, D \leftarrow 1$ \\
+6.  While $u.used > 0$ and $u_0 \equiv 0 \mbox{ (mod }2\mbox{)}$ \\
+\hspace{3mm}6.1  $u \leftarrow \lfloor u / 2 \rfloor$ \\
+\hspace{3mm}6.2  If ($A.used > 0$ and $A_0 \equiv 1 \mbox{ (mod }2\mbox{)}$) or ($B.used > 0$ and $B_0 \equiv 1 \mbox{ (mod }2\mbox{)}$) then \\
+\hspace{6mm}6.2.1  $A \leftarrow A + y$ \\
+\hspace{6mm}6.2.2  $B \leftarrow B - x$ \\
+\hspace{3mm}6.3  $A \leftarrow \lfloor A / 2 \rfloor$ \\
+\hspace{3mm}6.4  $B \leftarrow \lfloor B / 2 \rfloor$ \\
+7.  While $v.used > 0$ and $v_0 \equiv 0 \mbox{ (mod }2\mbox{)}$ \\
+\hspace{3mm}7.1  $v \leftarrow \lfloor v / 2 \rfloor$ \\
+\hspace{3mm}7.2  If ($C.used > 0$ and $C_0 \equiv 1 \mbox{ (mod }2\mbox{)}$) or ($D.used > 0$ and $D_0 \equiv 1 \mbox{ (mod }2\mbox{)}$) then \\
+\hspace{6mm}7.2.1  $C \leftarrow C + y$ \\
+\hspace{6mm}7.2.2  $D \leftarrow D - x$ \\
+\hspace{3mm}7.3  $C \leftarrow \lfloor C / 2 \rfloor$ \\
+\hspace{3mm}7.4  $D \leftarrow \lfloor D / 2 \rfloor$ \\
+8.  If $u \ge v$ then \\
+\hspace{3mm}8.1  $u \leftarrow u - v$ \\
+\hspace{3mm}8.2  $A \leftarrow A - C$ \\
+\hspace{3mm}8.3  $B \leftarrow B - D$ \\
+9.  else \\
+\hspace{3mm}9.1  $v \leftarrow v - u$ \\
+\hspace{3mm}9.2  $C \leftarrow C - A$ \\
+\hspace{3mm}9.3  $D \leftarrow D - B$ \\
+10.  If $u \ne 0$ goto step 6. \\
+11.  If $v \ne 1$ return(\textit{MP\_VAL}). \\
+12.  While $C \le 0$ do \\
+\hspace{3mm}12.1  $C \leftarrow C + b$ \\
+13.  While $C \ge b$ do \\
+\hspace{3mm}13.1  $C \leftarrow C - b$ \\
+14.  $c \leftarrow C$ \\
+15.  Return(\textit{MP\_OKAY}). \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\end{figure}
+\textbf{Algorithm mp\_invmod.}
+This algorithm computes the modular multiplicative inverse of an integer $a$ modulo an integer $b$.  This algorithm is a variation of the 
+extended binary Euclidean algorithm from HAC \cite[pp. 608]{HAC}.  It has been modified to only compute the modular inverse and not a complete
+Diophantine solution.  
+
+If $b \le 0$ than the modulus is invalid and MP\_VAL is returned.  Similarly if both $a$ and $b$ are even then there cannot be a multiplicative
+inverse for $a$ and the error is reported.  
+
+The astute reader will observe that steps seven through nine are very similar to the binary greatest common divisor algorithm mp\_gcd.  In this case
+the other variables to the Diophantine equation are solved.  The algorithm terminates when $u = 0$ in which case the solution is
+
+\begin{equation}
+Ca + Db = v
+\end{equation}
+
+If $v$, the greatest common divisor of $a$ and $b$ is not equal to one then the algorithm will report an error as no inverse exists.  Otherwise, $C$
+is the modular inverse of $a$.  The actual value of $C$ is congruent to, but not necessarily equal to, the ideal modular inverse which should lie 
+within $1 \le a^{-1} < b$.  Step numbers twelve and thirteen adjust the inverse until it is in range.  If the original input $a$ is within $0 < a < p$ 
+then only a couple of additions or subtractions will be required to adjust the inverse.
+
+\vspace{+3mm}\begin{small}
+\hspace{-5.1mm}{\bf File}: bn\_mp\_invmod.c
+\vspace{-3mm}
+\begin{alltt}
+\end{alltt}
+\end{small}
+
+\subsubsection{Odd Moduli}
+
+When the modulus $b$ is odd the variables $A$ and $C$ are fixed and are not required to compute the inverse.  In particular by attempting to solve
+the Diophantine $Cb + Da = 1$ only $B$ and $D$ are required to find the inverse of $a$.  
+
+The algorithm fast\_mp\_invmod is a direct adaptation of algorithm mp\_invmod with all all steps involving either $A$ or $C$ removed.  This 
+optimization will halve the time required to compute the modular inverse.
+
+\section{Primality Tests}
+
+A non-zero integer $a$ is said to be prime if it is not divisible by any other integer excluding one and itself.  For example, $a = 7$ is prime 
+since the integers $2 \ldots 6$ do not evenly divide $a$.  By contrast, $a = 6$ is not prime since $a = 6 = 2 \cdot 3$. 
+
+Prime numbers arise in cryptography considerably as they allow finite fields to be formed.  The ability to determine whether an integer is prime or
+not quickly has been a viable subject in cryptography and number theory for considerable time.  The algorithms that will be presented are all
+probablistic algorithms in that when they report an integer is composite it must be composite.  However, when the algorithms report an integer is
+prime the algorithm may be incorrect.  
+
+As will be discussed it is possible to limit the probability of error so well that for practical purposes the probablity of error might as 
+well be zero.  For the purposes of these discussions let $n$ represent the candidate integer of which the primality is in question.
+
+\subsection{Trial Division}
+
+Trial division means to attempt to evenly divide a candidate integer by small prime integers.  If the candidate can be evenly divided it obviously
+cannot be prime.  By dividing by all primes $1 < p \le \sqrt{n}$ this test can actually prove whether an integer is prime.  However, such a test
+would require a prohibitive amount of time as $n$ grows.
+
+Instead of dividing by every prime, a smaller, more mangeable set of primes may be used instead.  By performing trial division with only a subset
+of the primes less than $\sqrt{n} + 1$ the algorithm cannot prove if a candidate is prime.  However, often it can prove a candidate is not prime.
+
+The benefit of this test is that trial division by small values is fairly efficient.  Specially compared to the other algorithms that will be
+discussed shortly.  The probability that this approach correctly identifies a composite candidate when tested with all primes upto $q$ is given by
+$1 - {1.12 \over ln(q)}$.  The graph (\ref{pic:primality}, will be added later) demonstrates the probability of success for the range 
+$3 \le q \le 100$.  
+
+At approximately $q = 30$ the gain of performing further tests diminishes fairly quickly.  At $q = 90$ further testing is generally not going to 
+be of any practical use.  In the case of LibTomMath the default limit $q = 256$ was chosen since it is not too high and will eliminate 
+approximately $80\%$ of all candidate integers.  The constant \textbf{PRIME\_SIZE} is equal to the number of primes in the test base.  The 
+array \_\_prime\_tab is an array of the first \textbf{PRIME\_SIZE} prime numbers.  
+
+\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{mp\_prime\_is\_divisible}. \\
+\textbf{Input}.   mp\_int $a$ \\
+\textbf{Output}.  $c = 1$ if $n$ is divisible by a small prime, otherwise $c = 0$.  \\
+\hline \\
+1.  for $ix$ from $0$ to $PRIME\_SIZE$ do \\
+\hspace{3mm}1.1  $d \leftarrow n \mbox{ (mod }\_\_prime\_tab_{ix}\mbox{)}$ \\
+\hspace{3mm}1.2  If $d = 0$ then \\
+\hspace{6mm}1.2.1  $c \leftarrow 1$ \\
+\hspace{6mm}1.2.2  Return(\textit{MP\_OKAY}). \\
+2.  $c \leftarrow 0$ \\
+3.  Return(\textit{MP\_OKAY}). \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Algorithm mp\_prime\_is\_divisible}
+\end{figure}
+\textbf{Algorithm mp\_prime\_is\_divisible.}
+This algorithm attempts to determine if a candidate integer $n$ is composite by performing trial divisions.  
+
+\vspace{+3mm}\begin{small}
+\hspace{-5.1mm}{\bf File}: bn\_mp\_prime\_is\_divisible.c
+\vspace{-3mm}
+\begin{alltt}
+\end{alltt}
+\end{small}
+
+The algorithm defaults to a return of $0$ in case an error occurs.  The values in the prime table are all specified to be in the range of a 
+mp\_digit.  The table \_\_prime\_tab is defined in the following file.
+
+\vspace{+3mm}\begin{small}
+\hspace{-5.1mm}{\bf File}: bn\_prime\_tab.c
+\vspace{-3mm}
+\begin{alltt}
+\end{alltt}
+\end{small}
+
+Note that there are two possible tables.  When an mp\_digit is 7-bits long only the primes upto $127$ may be included, otherwise the primes
+upto $1619$ are used.  Note that the value of \textbf{PRIME\_SIZE} is a constant dependent on the size of a mp\_digit. 
+
+\subsection{The Fermat Test}
+The Fermat test is probably one the oldest tests to have a non-trivial probability of success.  It is based on the fact that if $n$ is in 
+fact prime then $a^{n} \equiv a \mbox{ (mod }n\mbox{)}$ for all $0 < a < n$.  The reason being that if $n$ is prime than the order of
+the multiplicative sub group is $n - 1$.  Any base $a$ must have an order which divides $n - 1$ and as such $a^n$ is equivalent to 
+$a^1 = a$.  
+
+If $n$ is composite then any given base $a$ does not have to have a period which divides $n - 1$.  In which case 
+it is possible that $a^n \nequiv a \mbox{ (mod }n\mbox{)}$.  However, this test is not absolute as it is possible that the order
+of a base will divide $n - 1$ which would then be reported as prime.  Such a base yields what is known as a Fermat pseudo-prime.  Several 
+integers known as Carmichael numbers will be a pseudo-prime to all valid bases.  Fortunately such numbers are extremely rare as $n$ grows
+in size.
+
+\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{mp\_prime\_fermat}. \\
+\textbf{Input}.   mp\_int $a$ and $b$, $a \ge 2$, $0 < b < a$.  \\
+\textbf{Output}.  $c = 1$ if $b^a \equiv b \mbox{ (mod }a\mbox{)}$, otherwise $c = 0$.  \\
+\hline \\
+1.  $t \leftarrow b^a \mbox{ (mod }a\mbox{)}$ \\
+2.  If $t = b$ then \\
+\hspace{3mm}2.1  $c = 1$ \\
+3.  else \\
+\hspace{3mm}3.1  $c = 0$ \\
+4.  Return(\textit{MP\_OKAY}). \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Algorithm mp\_prime\_fermat}
+\end{figure}
+\textbf{Algorithm mp\_prime\_fermat.}
+This algorithm determines whether an mp\_int $a$ is a Fermat prime to the base $b$ or not.  It uses a single modular exponentiation to
+determine the result.  
+
+\vspace{+3mm}\begin{small}
+\hspace{-5.1mm}{\bf File}: bn\_mp\_prime\_fermat.c
+\vspace{-3mm}
+\begin{alltt}
+\end{alltt}
+\end{small}
+
+\subsection{The Miller-Rabin Test}
+The Miller-Rabin (citation) test is another primality test which has tighter error bounds than the Fermat test specifically with sequentially chosen 
+candidate  integers.  The algorithm is based on the observation that if $n - 1 = 2^kr$ and if $b^r \nequiv \pm 1$ then after upto $k - 1$ squarings the 
+value must be equal to $-1$.  The squarings are stopped as soon as $-1$ is observed.  If the value of $1$ is observed first it means that
+some value not congruent to $\pm 1$ when squared equals one which cannot occur if $n$ is prime.
+
+\begin{figure}[!here]
+\begin{small}
+\begin{center}
+\begin{tabular}{l}
+\hline Algorithm \textbf{mp\_prime\_miller\_rabin}. \\
+\textbf{Input}.   mp\_int $a$ and $b$, $a \ge 2$, $0 < b < a$.  \\
+\textbf{Output}.  $c = 1$ if $a$ is a Miller-Rabin prime to the base $a$, otherwise $c = 0$.  \\
+\hline
+1.  $a' \leftarrow a - 1$ \\
+2.  $r  \leftarrow n1$    \\
+3.  $c \leftarrow 0, s  \leftarrow 0$ \\
+4.  While $r.used > 0$ and $r_0 \equiv 0 \mbox{ (mod }2\mbox{)}$ \\
+\hspace{3mm}4.1  $s \leftarrow s + 1$ \\
+\hspace{3mm}4.2  $r \leftarrow \lfloor r / 2 \rfloor$ \\
+5.  $y \leftarrow b^r \mbox{ (mod }a\mbox{)}$ \\
+6.  If $y \nequiv \pm 1$ then \\
+\hspace{3mm}6.1  $j \leftarrow 1$ \\
+\hspace{3mm}6.2  While $j \le (s - 1)$ and $y \nequiv a'$ \\
+\hspace{6mm}6.2.1  $y \leftarrow y^2 \mbox{ (mod }a\mbox{)}$ \\
+\hspace{6mm}6.2.2  If $y = 1$ then goto step 8. \\
+\hspace{6mm}6.2.3  $j \leftarrow j + 1$ \\
+\hspace{3mm}6.3  If $y \nequiv a'$ goto step 8. \\
+7.  $c \leftarrow 1$\\
+8.  Return(\textit{MP\_OKAY}). \\
+\hline
+\end{tabular}
+\end{center}
+\end{small}
+\caption{Algorithm mp\_prime\_miller\_rabin}
+\end{figure}
+\textbf{Algorithm mp\_prime\_miller\_rabin.}
+This algorithm performs one trial round of the Miller-Rabin algorithm to the base $b$.  It will set $c = 1$ if the algorithm cannot determine
+if $b$ is composite or $c = 0$ if $b$ is provably composite.  The values of $s$ and $r$ are computed such that $a' = a - 1 = 2^sr$.  
+
+If the value $y \equiv b^r$ is congruent to $\pm 1$ then the algorithm cannot prove if $a$ is composite or not.  Otherwise, the algorithm will
+square $y$ upto $s - 1$ times stopping only when $y \equiv -1$.  If $y^2 \equiv 1$ and $y \nequiv \pm 1$ then the algorithm can report that $a$
+is provably composite.  If the algorithm performs $s - 1$ squarings and $y \nequiv -1$ then $a$ is provably composite.  If $a$ is not provably 
+composite then it is \textit{probably} prime.
+
+\vspace{+3mm}\begin{small}
+\hspace{-5.1mm}{\bf File}: bn\_mp\_prime\_miller\_rabin.c
+\vspace{-3mm}
+\begin{alltt}
+\end{alltt}
+\end{small}
+
+
+
+
+\backmatter
+\appendix
+\begin{thebibliography}{ABCDEF}
+\bibitem[1]{TAOCPV2}
+Donald Knuth, \textit{The Art of Computer Programming}, Third Edition, Volume Two, Seminumerical Algorithms, Addison-Wesley, 1998
+
+\bibitem[2]{HAC}
+A. Menezes, P. van Oorschot, S. Vanstone, \textit{Handbook of Applied Cryptography}, CRC Press, 1996
+
+\bibitem[3]{ROSE}
+Michael Rosing, \textit{Implementing Elliptic Curve Cryptography}, Manning Publications, 1999
+
+\bibitem[4]{COMBA}
+Paul G. Comba, \textit{Exponentiation Cryptosystems on the IBM PC}. IBM Systems Journal 29(4): 526-538 (1990)
+
+\bibitem[5]{KARA}
+A. Karatsuba, Doklay Akad. Nauk SSSR 145 (1962), pp.293-294
+
+\bibitem[6]{KARAP}
+Andre Weimerskirch and Christof Paar, \textit{Generalizations of the Karatsuba Algorithm for Polynomial Multiplication}, Submitted to Design, Codes and Cryptography, March 2002
+
+\bibitem[7]{BARRETT}
+Paul Barrett, \textit{Implementing the Rivest Shamir and Adleman Public Key Encryption Algorithm on a Standard Digital Signal Processor}, Advances in Cryptology, Crypto '86, Springer-Verlag.
+
+\bibitem[8]{MONT}
+P.L.Montgomery. \textit{Modular multiplication without trial division}. Mathematics of Computation, 44(170):519-521, April 1985.
+
+\bibitem[9]{DRMET}
+Chae Hoon Lim and Pil Joong Lee, \textit{Generating Efficient Primes for Discrete Log Cryptosystems}, POSTECH Information Research Laboratories
+
+\bibitem[10]{MMB}
+J. Daemen and R. Govaerts and J. Vandewalle, \textit{Block ciphers based on Modular Arithmetic}, State and {P}rogress in the {R}esearch of {C}ryptography, 1993, pp. 80-89
+
+\bibitem[11]{RSAREF}
+R.L. Rivest, A. Shamir, L. Adleman, \textit{A Method for Obtaining Digital Signatures and Public-Key Cryptosystems}
+
+\bibitem[12]{DHREF}
+Whitfield Diffie, Martin E. Hellman, \textit{New Directions in Cryptography}, IEEE Transactions on Information Theory, 1976
+
+\bibitem[13]{IEEE}
+IEEE Standard for Binary Floating-Point Arithmetic (ANSI/IEEE Std 754-1985)
+
+\bibitem[14]{GMP}
+GNU Multiple Precision (GMP), \url{http://www.swox.com/gmp/}
+
+\bibitem[15]{MPI}
+Multiple Precision Integer Library (MPI), Michael Fromberger, \url{http://thayer.dartmouth.edu/~sting/mpi/}
+
+\bibitem[16]{OPENSSL}
+OpenSSL Cryptographic Toolkit, \url{http://openssl.org}
+
+\bibitem[17]{LIP}
+Large Integer Package, \url{http://home.hetnet.nl/~ecstr/LIP.zip}
+
+\bibitem[18]{ISOC}
+JTC1/SC22/WG14, ISO/IEC 9899:1999, ``A draft rationale for the C99 standard.''
+
+\bibitem[19]{JAVA}
+The Sun Java Website, \url{http://java.sun.com/}
+
+\end{thebibliography}
+
+\input{tommath.ind}
+
+\end{document}
diff --git a/libtommath/tommath_class.h b/libtommath/tommath_class.h
new file mode 100644
index 0000000..b9cc902
--- /dev/null
+++ b/libtommath/tommath_class.h
@@ -0,0 +1,995 @@
+#if !(defined(LTM1) && defined(LTM2) && defined(LTM3))
+#if defined(LTM2)
+#define LTM3
+#endif
+#if defined(LTM1)
+#define LTM2
+#endif
+#define LTM1
+
+#if defined(LTM_ALL)
+#define BN_ERROR_C
+#define BN_FAST_MP_INVMOD_C
+#define BN_FAST_MP_MONTGOMERY_REDUCE_C
+#define BN_FAST_S_MP_MUL_DIGS_C
+#define BN_FAST_S_MP_MUL_HIGH_DIGS_C
+#define BN_FAST_S_MP_SQR_C
+#define BN_MP_2EXPT_C
+#define BN_MP_ABS_C
+#define BN_MP_ADD_C
+#define BN_MP_ADD_D_C
+#define BN_MP_ADDMOD_C
+#define BN_MP_AND_C
+#define BN_MP_CLAMP_C
+#define BN_MP_CLEAR_C
+#define BN_MP_CLEAR_MULTI_C
+#define BN_MP_CMP_C
+#define BN_MP_CMP_D_C
+#define BN_MP_CMP_MAG_C
+#define BN_MP_CNT_LSB_C
+#define BN_MP_COPY_C
+#define BN_MP_COUNT_BITS_C
+#define BN_MP_DIV_C
+#define BN_MP_DIV_2_C
+#define BN_MP_DIV_2D_C
+#define BN_MP_DIV_3_C
+#define BN_MP_DIV_D_C
+#define BN_MP_DR_IS_MODULUS_C
+#define BN_MP_DR_REDUCE_C
+#define BN_MP_DR_SETUP_C
+#define BN_MP_EXCH_C
+#define BN_MP_EXPT_D_C
+#define BN_MP_EXPTMOD_C
+#define BN_MP_EXPTMOD_FAST_C
+#define BN_MP_EXTEUCLID_C
+#define BN_MP_FREAD_C
+#define BN_MP_FWRITE_C
+#define BN_MP_GCD_C
+#define BN_MP_GET_INT_C
+#define BN_MP_GROW_C
+#define BN_MP_INIT_C
+#define BN_MP_INIT_COPY_C
+#define BN_MP_INIT_MULTI_C
+#define BN_MP_INIT_SET_C
+#define BN_MP_INIT_SET_INT_C
+#define BN_MP_INIT_SIZE_C
+#define BN_MP_INVMOD_C
+#define BN_MP_INVMOD_SLOW_C
+#define BN_MP_IS_SQUARE_C
+#define BN_MP_JACOBI_C
+#define BN_MP_KARATSUBA_MUL_C
+#define BN_MP_KARATSUBA_SQR_C
+#define BN_MP_LCM_C
+#define BN_MP_LSHD_C
+#define BN_MP_MOD_C
+#define BN_MP_MOD_2D_C
+#define BN_MP_MOD_D_C
+#define BN_MP_MONTGOMERY_CALC_NORMALIZATION_C
+#define BN_MP_MONTGOMERY_REDUCE_C
+#define BN_MP_MONTGOMERY_SETUP_C
+#define BN_MP_MUL_C
+#define BN_MP_MUL_2_C
+#define BN_MP_MUL_2D_C
+#define BN_MP_MUL_D_C
+#define BN_MP_MULMOD_C
+#define BN_MP_N_ROOT_C
+#define BN_MP_NEG_C
+#define BN_MP_OR_C
+#define BN_MP_PRIME_FERMAT_C
+#define BN_MP_PRIME_IS_DIVISIBLE_C
+#define BN_MP_PRIME_IS_PRIME_C
+#define BN_MP_PRIME_MILLER_RABIN_C
+#define BN_MP_PRIME_NEXT_PRIME_C
+#define BN_MP_PRIME_RABIN_MILLER_TRIALS_C
+#define BN_MP_PRIME_RANDOM_EX_C
+#define BN_MP_RADIX_SIZE_C
+#define BN_MP_RADIX_SMAP_C
+#define BN_MP_RAND_C
+#define BN_MP_READ_RADIX_C
+#define BN_MP_READ_SIGNED_BIN_C
+#define BN_MP_READ_UNSIGNED_BIN_C
+#define BN_MP_REDUCE_C
+#define BN_MP_REDUCE_2K_C
+#define BN_MP_REDUCE_2K_L_C
+#define BN_MP_REDUCE_2K_SETUP_C
+#define BN_MP_REDUCE_2K_SETUP_L_C
+#define BN_MP_REDUCE_IS_2K_C
+#define BN_MP_REDUCE_IS_2K_L_C
+#define BN_MP_REDUCE_SETUP_C
+#define BN_MP_RSHD_C
+#define BN_MP_SET_C
+#define BN_MP_SET_INT_C
+#define BN_MP_SHRINK_C
+#define BN_MP_SIGNED_BIN_SIZE_C
+#define BN_MP_SQR_C
+#define BN_MP_SQRMOD_C
+#define BN_MP_SQRT_C
+#define BN_MP_SUB_C
+#define BN_MP_SUB_D_C
+#define BN_MP_SUBMOD_C
+#define BN_MP_TO_SIGNED_BIN_C
+#define BN_MP_TO_SIGNED_BIN_N_C
+#define BN_MP_TO_UNSIGNED_BIN_C
+#define BN_MP_TO_UNSIGNED_BIN_N_C
+#define BN_MP_TOOM_MUL_C
+#define BN_MP_TOOM_SQR_C
+#define BN_MP_TORADIX_C
+#define BN_MP_TORADIX_N_C
+#define BN_MP_UNSIGNED_BIN_SIZE_C
+#define BN_MP_XOR_C
+#define BN_MP_ZERO_C
+#define BN_PRIME_TAB_C
+#define BN_REVERSE_C
+#define BN_S_MP_ADD_C
+#define BN_S_MP_EXPTMOD_C
+#define BN_S_MP_MUL_DIGS_C
+#define BN_S_MP_MUL_HIGH_DIGS_C
+#define BN_S_MP_SQR_C
+#define BN_S_MP_SUB_C
+#define BNCORE_C
+#endif
+
+#if defined(BN_ERROR_C)
+   #define BN_MP_ERROR_TO_STRING_C
+#endif
+
+#if defined(BN_FAST_MP_INVMOD_C)
+   #define BN_MP_ISEVEN_C
+   #define BN_MP_INIT_MULTI_C
+   #define BN_MP_COPY_C
+   #define BN_MP_MOD_C
+   #define BN_MP_SET_C
+   #define BN_MP_DIV_2_C
+   #define BN_MP_ISODD_C
+   #define BN_MP_SUB_C
+   #define BN_MP_CMP_C
+   #define BN_MP_ISZERO_C
+   #define BN_MP_CMP_D_C
+   #define BN_MP_ADD_C
+   #define BN_MP_EXCH_C
+   #define BN_MP_CLEAR_MULTI_C
+#endif
+
+#if defined(BN_FAST_MP_MONTGOMERY_REDUCE_C)
+   #define BN_MP_GROW_C
+   #define BN_MP_RSHD_C
+   #define BN_MP_CLAMP_C
+   #define BN_MP_CMP_MAG_C
+   #define BN_S_MP_SUB_C
+#endif
+
+#if defined(BN_FAST_S_MP_MUL_DIGS_C)
+   #define BN_MP_GROW_C
+   #define BN_MP_CLAMP_C
+#endif
+
+#if defined(BN_FAST_S_MP_MUL_HIGH_DIGS_C)
+   #define BN_MP_GROW_C
+   #define BN_MP_CLAMP_C
+#endif
+
+#if defined(BN_FAST_S_MP_SQR_C)
+   #define BN_MP_GROW_C
+   #define BN_MP_CLAMP_C
+#endif
+
+#if defined(BN_MP_2EXPT_C)
+   #define BN_MP_ZERO_C
+   #define BN_MP_GROW_C
+#endif
+
+#if defined(BN_MP_ABS_C)
+   #define BN_MP_COPY_C
+#endif
+
+#if defined(BN_MP_ADD_C)
+   #define BN_S_MP_ADD_C
+   #define BN_MP_CMP_MAG_C
+   #define BN_S_MP_SUB_C
+#endif
+
+#if defined(BN_MP_ADD_D_C)
+   #define BN_MP_GROW_C
+   #define BN_MP_SUB_D_C
+   #define BN_MP_CLAMP_C
+#endif
+
+#if defined(BN_MP_ADDMOD_C)
+   #define BN_MP_INIT_C
+   #define BN_MP_ADD_C
+   #define BN_MP_CLEAR_C
+   #define BN_MP_MOD_C
+#endif
+
+#if defined(BN_MP_AND_C)
+   #define BN_MP_INIT_COPY_C
+   #define BN_MP_CLAMP_C
+   #define BN_MP_EXCH_C
+   #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_CLAMP_C)
+#endif
+
+#if defined(BN_MP_CLEAR_C)
+#endif
+
+#if defined(BN_MP_CLEAR_MULTI_C)
+   #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_CMP_C)
+   #define BN_MP_CMP_MAG_C
+#endif
+
+#if defined(BN_MP_CMP_D_C)
+#endif
+
+#if defined(BN_MP_CMP_MAG_C)
+#endif
+
+#if defined(BN_MP_CNT_LSB_C)
+   #define BN_MP_ISZERO_C
+#endif
+
+#if defined(BN_MP_COPY_C)
+   #define BN_MP_GROW_C
+#endif
+
+#if defined(BN_MP_COUNT_BITS_C)
+#endif
+
+#if defined(BN_MP_DIV_C)
+   #define BN_MP_ISZERO_C
+   #define BN_MP_CMP_MAG_C
+   #define BN_MP_COPY_C
+   #define BN_MP_ZERO_C
+   #define BN_MP_INIT_MULTI_C
+   #define BN_MP_SET_C
+   #define BN_MP_COUNT_BITS_C
+   #define BN_MP_ABS_C
+   #define BN_MP_MUL_2D_C
+   #define BN_MP_CMP_C
+   #define BN_MP_SUB_C
+   #define BN_MP_ADD_C
+   #define BN_MP_DIV_2D_C
+   #define BN_MP_EXCH_C
+   #define BN_MP_CLEAR_MULTI_C
+   #define BN_MP_INIT_SIZE_C
+   #define BN_MP_INIT_C
+   #define BN_MP_INIT_COPY_C
+   #define BN_MP_LSHD_C
+   #define BN_MP_RSHD_C
+   #define BN_MP_MUL_D_C
+   #define BN_MP_CLAMP_C
+   #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_DIV_2_C)
+   #define BN_MP_GROW_C
+   #define BN_MP_CLAMP_C
+#endif
+
+#if defined(BN_MP_DIV_2D_C)
+   #define BN_MP_COPY_C
+   #define BN_MP_ZERO_C
+   #define BN_MP_INIT_C
+   #define BN_MP_MOD_2D_C
+   #define BN_MP_CLEAR_C
+   #define BN_MP_RSHD_C
+   #define BN_MP_CLAMP_C
+   #define BN_MP_EXCH_C
+#endif
+
+#if defined(BN_MP_DIV_3_C)
+   #define BN_MP_INIT_SIZE_C
+   #define BN_MP_CLAMP_C
+   #define BN_MP_EXCH_C
+   #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_DIV_D_C)
+   #define BN_MP_ISZERO_C
+   #define BN_MP_COPY_C
+   #define BN_MP_DIV_2D_C
+   #define BN_MP_DIV_3_C
+   #define BN_MP_INIT_SIZE_C
+   #define BN_MP_CLAMP_C
+   #define BN_MP_EXCH_C
+   #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_DR_IS_MODULUS_C)
+#endif
+
+#if defined(BN_MP_DR_REDUCE_C)
+   #define BN_MP_GROW_C
+   #define BN_MP_CLAMP_C
+   #define BN_MP_CMP_MAG_C
+   #define BN_S_MP_SUB_C
+#endif
+
+#if defined(BN_MP_DR_SETUP_C)
+#endif
+
+#if defined(BN_MP_EXCH_C)
+#endif
+
+#if defined(BN_MP_EXPT_D_C)
+   #define BN_MP_INIT_COPY_C
+   #define BN_MP_SET_C
+   #define BN_MP_SQR_C
+   #define BN_MP_CLEAR_C
+   #define BN_MP_MUL_C
+#endif
+
+#if defined(BN_MP_EXPTMOD_C)
+   #define BN_MP_INIT_C
+   #define BN_MP_INVMOD_C
+   #define BN_MP_CLEAR_C
+   #define BN_MP_ABS_C
+   #define BN_MP_CLEAR_MULTI_C
+   #define BN_MP_REDUCE_IS_2K_L_C
+   #define BN_S_MP_EXPTMOD_C
+   #define BN_MP_DR_IS_MODULUS_C
+   #define BN_MP_REDUCE_IS_2K_C
+   #define BN_MP_ISODD_C
+   #define BN_MP_EXPTMOD_FAST_C
+#endif
+
+#if defined(BN_MP_EXPTMOD_FAST_C)
+   #define BN_MP_COUNT_BITS_C
+   #define BN_MP_INIT_C
+   #define BN_MP_CLEAR_C
+   #define BN_MP_MONTGOMERY_SETUP_C
+   #define BN_FAST_MP_MONTGOMERY_REDUCE_C
+   #define BN_MP_MONTGOMERY_REDUCE_C
+   #define BN_MP_DR_SETUP_C
+   #define BN_MP_DR_REDUCE_C
+   #define BN_MP_REDUCE_2K_SETUP_C
+   #define BN_MP_REDUCE_2K_C
+   #define BN_MP_MONTGOMERY_CALC_NORMALIZATION_C
+   #define BN_MP_MULMOD_C
+   #define BN_MP_SET_C
+   #define BN_MP_MOD_C
+   #define BN_MP_COPY_C
+   #define BN_MP_SQR_C
+   #define BN_MP_MUL_C
+   #define BN_MP_EXCH_C
+#endif
+
+#if defined(BN_MP_EXTEUCLID_C)
+   #define BN_MP_INIT_MULTI_C
+   #define BN_MP_SET_C
+   #define BN_MP_COPY_C
+   #define BN_MP_ISZERO_C
+   #define BN_MP_DIV_C
+   #define BN_MP_MUL_C
+   #define BN_MP_SUB_C
+   #define BN_MP_NEG_C
+   #define BN_MP_EXCH_C
+   #define BN_MP_CLEAR_MULTI_C
+#endif
+
+#if defined(BN_MP_FREAD_C)
+   #define BN_MP_ZERO_C
+   #define BN_MP_S_RMAP_C
+   #define BN_MP_MUL_D_C
+   #define BN_MP_ADD_D_C
+   #define BN_MP_CMP_D_C
+#endif
+
+#if defined(BN_MP_FWRITE_C)
+   #define BN_MP_RADIX_SIZE_C
+   #define BN_MP_TORADIX_C
+#endif
+
+#if defined(BN_MP_GCD_C)
+   #define BN_MP_ISZERO_C
+   #define BN_MP_ABS_C
+   #define BN_MP_ZERO_C
+   #define BN_MP_INIT_COPY_C
+   #define BN_MP_CNT_LSB_C
+   #define BN_MP_DIV_2D_C
+   #define BN_MP_CMP_MAG_C
+   #define BN_MP_EXCH_C
+   #define BN_S_MP_SUB_C
+   #define BN_MP_MUL_2D_C
+   #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_GET_INT_C)
+#endif
+
+#if defined(BN_MP_GROW_C)
+#endif
+
+#if defined(BN_MP_INIT_C)
+#endif
+
+#if defined(BN_MP_INIT_COPY_C)
+   #define BN_MP_COPY_C
+#endif
+
+#if defined(BN_MP_INIT_MULTI_C)
+   #define BN_MP_ERR_C
+   #define BN_MP_INIT_C
+   #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_INIT_SET_C)
+   #define BN_MP_INIT_C
+   #define BN_MP_SET_C
+#endif
+
+#if defined(BN_MP_INIT_SET_INT_C)
+   #define BN_MP_INIT_C
+   #define BN_MP_SET_INT_C
+#endif
+
+#if defined(BN_MP_INIT_SIZE_C)
+   #define BN_MP_INIT_C
+#endif
+
+#if defined(BN_MP_INVMOD_C)
+   #define BN_MP_ISZERO_C
+   #define BN_MP_ISODD_C
+   #define BN_FAST_MP_INVMOD_C
+   #define BN_MP_INVMOD_SLOW_C
+#endif
+
+#if defined(BN_MP_INVMOD_SLOW_C)
+   #define BN_MP_ISZERO_C
+   #define BN_MP_INIT_MULTI_C
+   #define BN_MP_MOD_C
+   #define BN_MP_COPY_C
+   #define BN_MP_ISEVEN_C
+   #define BN_MP_SET_C
+   #define BN_MP_DIV_2_C
+   #define BN_MP_ISODD_C
+   #define BN_MP_ADD_C
+   #define BN_MP_SUB_C
+   #define BN_MP_CMP_C
+   #define BN_MP_CMP_D_C
+   #define BN_MP_CMP_MAG_C
+   #define BN_MP_EXCH_C
+   #define BN_MP_CLEAR_MULTI_C
+#endif
+
+#if defined(BN_MP_IS_SQUARE_C)
+   #define BN_MP_MOD_D_C
+   #define BN_MP_INIT_SET_INT_C
+   #define BN_MP_MOD_C
+   #define BN_MP_GET_INT_C
+   #define BN_MP_SQRT_C
+   #define BN_MP_SQR_C
+   #define BN_MP_CMP_MAG_C
+   #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_JACOBI_C)
+   #define BN_MP_CMP_D_C
+   #define BN_MP_ISZERO_C
+   #define BN_MP_INIT_COPY_C
+   #define BN_MP_CNT_LSB_C
+   #define BN_MP_DIV_2D_C
+   #define BN_MP_MOD_C
+   #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_KARATSUBA_MUL_C)
+   #define BN_MP_MUL_C
+   #define BN_MP_INIT_SIZE_C
+   #define BN_MP_CLAMP_C
+   #define BN_MP_SUB_C
+   #define BN_MP_ADD_C
+   #define BN_MP_LSHD_C
+   #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_KARATSUBA_SQR_C)
+   #define BN_MP_INIT_SIZE_C
+   #define BN_MP_CLAMP_C
+   #define BN_MP_SQR_C
+   #define BN_MP_SUB_C
+   #define BN_S_MP_ADD_C
+   #define BN_MP_LSHD_C
+   #define BN_MP_ADD_C
+   #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_LCM_C)
+   #define BN_MP_INIT_MULTI_C
+   #define BN_MP_GCD_C
+   #define BN_MP_CMP_MAG_C
+   #define BN_MP_DIV_C
+   #define BN_MP_MUL_C
+   #define BN_MP_CLEAR_MULTI_C
+#endif
+
+#if defined(BN_MP_LSHD_C)
+   #define BN_MP_GROW_C
+   #define BN_MP_RSHD_C
+#endif
+
+#if defined(BN_MP_MOD_C)
+   #define BN_MP_INIT_C
+   #define BN_MP_DIV_C
+   #define BN_MP_CLEAR_C
+   #define BN_MP_ADD_C
+   #define BN_MP_EXCH_C
+#endif
+
+#if defined(BN_MP_MOD_2D_C)
+   #define BN_MP_ZERO_C
+   #define BN_MP_COPY_C
+   #define BN_MP_CLAMP_C
+#endif
+
+#if defined(BN_MP_MOD_D_C)
+   #define BN_MP_DIV_D_C
+#endif
+
+#if defined(BN_MP_MONTGOMERY_CALC_NORMALIZATION_C)
+   #define BN_MP_COUNT_BITS_C
+   #define BN_MP_2EXPT_C
+   #define BN_MP_SET_C
+   #define BN_MP_MUL_2_C
+   #define BN_MP_CMP_MAG_C
+   #define BN_S_MP_SUB_C
+#endif
+
+#if defined(BN_MP_MONTGOMERY_REDUCE_C)
+   #define BN_FAST_MP_MONTGOMERY_REDUCE_C
+   #define BN_MP_GROW_C
+   #define BN_MP_CLAMP_C
+   #define BN_MP_RSHD_C
+   #define BN_MP_CMP_MAG_C
+   #define BN_S_MP_SUB_C
+#endif
+
+#if defined(BN_MP_MONTGOMERY_SETUP_C)
+#endif
+
+#if defined(BN_MP_MUL_C)
+   #define BN_MP_TOOM_MUL_C
+   #define BN_MP_KARATSUBA_MUL_C
+   #define BN_FAST_S_MP_MUL_DIGS_C
+   #define BN_S_MP_MUL_C
+   #define BN_S_MP_MUL_DIGS_C
+#endif
+
+#if defined(BN_MP_MUL_2_C)
+   #define BN_MP_GROW_C
+#endif
+
+#if defined(BN_MP_MUL_2D_C)
+   #define BN_MP_COPY_C
+   #define BN_MP_GROW_C
+   #define BN_MP_LSHD_C
+   #define BN_MP_CLAMP_C
+#endif
+
+#if defined(BN_MP_MUL_D_C)
+   #define BN_MP_GROW_C
+   #define BN_MP_CLAMP_C
+#endif
+
+#if defined(BN_MP_MULMOD_C)
+   #define BN_MP_INIT_C
+   #define BN_MP_MUL_C
+   #define BN_MP_CLEAR_C
+   #define BN_MP_MOD_C
+#endif
+
+#if defined(BN_MP_N_ROOT_C)
+   #define BN_MP_INIT_C
+   #define BN_MP_SET_C
+   #define BN_MP_COPY_C
+   #define BN_MP_EXPT_D_C
+   #define BN_MP_MUL_C
+   #define BN_MP_SUB_C
+   #define BN_MP_MUL_D_C
+   #define BN_MP_DIV_C
+   #define BN_MP_CMP_C
+   #define BN_MP_SUB_D_C
+   #define BN_MP_EXCH_C
+   #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_NEG_C)
+   #define BN_MP_COPY_C
+   #define BN_MP_ISZERO_C
+#endif
+
+#if defined(BN_MP_OR_C)
+   #define BN_MP_INIT_COPY_C
+   #define BN_MP_CLAMP_C
+   #define BN_MP_EXCH_C
+   #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_PRIME_FERMAT_C)
+   #define BN_MP_CMP_D_C
+   #define BN_MP_INIT_C
+   #define BN_MP_EXPTMOD_C
+   #define BN_MP_CMP_C
+   #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_PRIME_IS_DIVISIBLE_C)
+   #define BN_MP_MOD_D_C
+#endif
+
+#if defined(BN_MP_PRIME_IS_PRIME_C)
+   #define BN_MP_CMP_D_C
+   #define BN_MP_PRIME_IS_DIVISIBLE_C
+   #define BN_MP_INIT_C
+   #define BN_MP_SET_C
+   #define BN_MP_PRIME_MILLER_RABIN_C
+   #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_PRIME_MILLER_RABIN_C)
+   #define BN_MP_CMP_D_C
+   #define BN_MP_INIT_COPY_C
+   #define BN_MP_SUB_D_C
+   #define BN_MP_CNT_LSB_C
+   #define BN_MP_DIV_2D_C
+   #define BN_MP_EXPTMOD_C
+   #define BN_MP_CMP_C
+   #define BN_MP_SQRMOD_C
+   #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_PRIME_NEXT_PRIME_C)
+   #define BN_MP_CMP_D_C
+   #define BN_MP_SET_C
+   #define BN_MP_SUB_D_C
+   #define BN_MP_ISEVEN_C
+   #define BN_MP_MOD_D_C
+   #define BN_MP_INIT_C
+   #define BN_MP_ADD_D_C
+   #define BN_MP_PRIME_MILLER_RABIN_C
+   #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_PRIME_RABIN_MILLER_TRIALS_C)
+#endif
+
+#if defined(BN_MP_PRIME_RANDOM_EX_C)
+   #define BN_MP_READ_UNSIGNED_BIN_C
+   #define BN_MP_PRIME_IS_PRIME_C
+   #define BN_MP_SUB_D_C
+   #define BN_MP_DIV_2_C
+   #define BN_MP_MUL_2_C
+   #define BN_MP_ADD_D_C
+#endif
+
+#if defined(BN_MP_RADIX_SIZE_C)
+   #define BN_MP_COUNT_BITS_C
+   #define BN_MP_INIT_COPY_C
+   #define BN_MP_ISZERO_C
+   #define BN_MP_DIV_D_C
+   #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_RADIX_SMAP_C)
+   #define BN_MP_S_RMAP_C
+#endif
+
+#if defined(BN_MP_RAND_C)
+   #define BN_MP_ZERO_C
+   #define BN_MP_ADD_D_C
+   #define BN_MP_LSHD_C
+#endif
+
+#if defined(BN_MP_READ_RADIX_C)
+   #define BN_MP_ZERO_C
+   #define BN_MP_S_RMAP_C
+   #define BN_MP_RADIX_SMAP_C
+   #define BN_MP_MUL_D_C
+   #define BN_MP_ADD_D_C
+   #define BN_MP_ISZERO_C
+#endif
+
+#if defined(BN_MP_READ_SIGNED_BIN_C)
+   #define BN_MP_READ_UNSIGNED_BIN_C
+#endif
+
+#if defined(BN_MP_READ_UNSIGNED_BIN_C)
+   #define BN_MP_GROW_C
+   #define BN_MP_ZERO_C
+   #define BN_MP_MUL_2D_C
+   #define BN_MP_CLAMP_C
+#endif
+
+#if defined(BN_MP_REDUCE_C)
+   #define BN_MP_REDUCE_SETUP_C
+   #define BN_MP_INIT_COPY_C
+   #define BN_MP_RSHD_C
+   #define BN_MP_MUL_C
+   #define BN_S_MP_MUL_HIGH_DIGS_C
+   #define BN_FAST_S_MP_MUL_HIGH_DIGS_C
+   #define BN_MP_MOD_2D_C
+   #define BN_S_MP_MUL_DIGS_C
+   #define BN_MP_SUB_C
+   #define BN_MP_CMP_D_C
+   #define BN_MP_SET_C
+   #define BN_MP_LSHD_C
+   #define BN_MP_ADD_C
+   #define BN_MP_CMP_C
+   #define BN_S_MP_SUB_C
+   #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_REDUCE_2K_C)
+   #define BN_MP_INIT_C
+   #define BN_MP_COUNT_BITS_C
+   #define BN_MP_DIV_2D_C
+   #define BN_MP_MUL_D_C
+   #define BN_S_MP_ADD_C
+   #define BN_MP_CMP_MAG_C
+   #define BN_S_MP_SUB_C
+   #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_REDUCE_2K_L_C)
+   #define BN_MP_INIT_C
+   #define BN_MP_COUNT_BITS_C
+   #define BN_MP_DIV_2D_C
+   #define BN_MP_MUL_C
+   #define BN_S_MP_ADD_C
+   #define BN_MP_CMP_MAG_C
+   #define BN_S_MP_SUB_C
+   #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_REDUCE_2K_SETUP_C)
+   #define BN_MP_INIT_C
+   #define BN_MP_COUNT_BITS_C
+   #define BN_MP_2EXPT_C
+   #define BN_MP_CLEAR_C
+   #define BN_S_MP_SUB_C
+#endif
+
+#if defined(BN_MP_REDUCE_2K_SETUP_L_C)
+   #define BN_MP_INIT_C
+   #define BN_MP_2EXPT_C
+   #define BN_MP_COUNT_BITS_C
+   #define BN_S_MP_SUB_C
+   #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_REDUCE_IS_2K_C)
+   #define BN_MP_REDUCE_2K_C
+   #define BN_MP_COUNT_BITS_C
+#endif
+
+#if defined(BN_MP_REDUCE_IS_2K_L_C)
+#endif
+
+#if defined(BN_MP_REDUCE_SETUP_C)
+   #define BN_MP_2EXPT_C
+   #define BN_MP_DIV_C
+#endif
+
+#if defined(BN_MP_RSHD_C)
+   #define BN_MP_ZERO_C
+#endif
+
+#if defined(BN_MP_SET_C)
+   #define BN_MP_ZERO_C
+#endif
+
+#if defined(BN_MP_SET_INT_C)
+   #define BN_MP_ZERO_C
+   #define BN_MP_MUL_2D_C
+   #define BN_MP_CLAMP_C
+#endif
+
+#if defined(BN_MP_SHRINK_C)
+#endif
+
+#if defined(BN_MP_SIGNED_BIN_SIZE_C)
+   #define BN_MP_UNSIGNED_BIN_SIZE_C
+#endif
+
+#if defined(BN_MP_SQR_C)
+   #define BN_MP_TOOM_SQR_C
+   #define BN_MP_KARATSUBA_SQR_C
+   #define BN_FAST_S_MP_SQR_C
+   #define BN_S_MP_SQR_C
+#endif
+
+#if defined(BN_MP_SQRMOD_C)
+   #define BN_MP_INIT_C
+   #define BN_MP_SQR_C
+   #define BN_MP_CLEAR_C
+   #define BN_MP_MOD_C
+#endif
+
+#if defined(BN_MP_SQRT_C)
+   #define BN_MP_N_ROOT_C
+   #define BN_MP_ISZERO_C
+   #define BN_MP_ZERO_C
+   #define BN_MP_INIT_COPY_C
+   #define BN_MP_RSHD_C
+   #define BN_MP_DIV_C
+   #define BN_MP_ADD_C
+   #define BN_MP_DIV_2_C
+   #define BN_MP_CMP_MAG_C
+   #define BN_MP_EXCH_C
+   #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_SUB_C)
+   #define BN_S_MP_ADD_C
+   #define BN_MP_CMP_MAG_C
+   #define BN_S_MP_SUB_C
+#endif
+
+#if defined(BN_MP_SUB_D_C)
+   #define BN_MP_GROW_C
+   #define BN_MP_ADD_D_C
+   #define BN_MP_CLAMP_C
+#endif
+
+#if defined(BN_MP_SUBMOD_C)
+   #define BN_MP_INIT_C
+   #define BN_MP_SUB_C
+   #define BN_MP_CLEAR_C
+   #define BN_MP_MOD_C
+#endif
+
+#if defined(BN_MP_TO_SIGNED_BIN_C)
+   #define BN_MP_TO_UNSIGNED_BIN_C
+#endif
+
+#if defined(BN_MP_TO_SIGNED_BIN_N_C)
+   #define BN_MP_SIGNED_BIN_SIZE_C
+   #define BN_MP_TO_SIGNED_BIN_C
+#endif
+
+#if defined(BN_MP_TO_UNSIGNED_BIN_C)
+   #define BN_MP_INIT_COPY_C
+   #define BN_MP_ISZERO_C
+   #define BN_MP_DIV_2D_C
+   #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_TO_UNSIGNED_BIN_N_C)
+   #define BN_MP_UNSIGNED_BIN_SIZE_C
+   #define BN_MP_TO_UNSIGNED_BIN_C
+#endif
+
+#if defined(BN_MP_TOOM_MUL_C)
+   #define BN_MP_INIT_MULTI_C
+   #define BN_MP_MOD_2D_C
+   #define BN_MP_COPY_C
+   #define BN_MP_RSHD_C
+   #define BN_MP_MUL_C
+   #define BN_MP_MUL_2_C
+   #define BN_MP_ADD_C
+   #define BN_MP_SUB_C
+   #define BN_MP_DIV_2_C
+   #define BN_MP_MUL_2D_C
+   #define BN_MP_MUL_D_C
+   #define BN_MP_DIV_3_C
+   #define BN_MP_LSHD_C
+   #define BN_MP_CLEAR_MULTI_C
+#endif
+
+#if defined(BN_MP_TOOM_SQR_C)
+   #define BN_MP_INIT_MULTI_C
+   #define BN_MP_MOD_2D_C
+   #define BN_MP_COPY_C
+   #define BN_MP_RSHD_C
+   #define BN_MP_SQR_C
+   #define BN_MP_MUL_2_C
+   #define BN_MP_ADD_C
+   #define BN_MP_SUB_C
+   #define BN_MP_DIV_2_C
+   #define BN_MP_MUL_2D_C
+   #define BN_MP_MUL_D_C
+   #define BN_MP_DIV_3_C
+   #define BN_MP_LSHD_C
+   #define BN_MP_CLEAR_MULTI_C
+#endif
+
+#if defined(BN_MP_TORADIX_C)
+   #define BN_MP_ISZERO_C
+   #define BN_MP_INIT_COPY_C
+   #define BN_MP_DIV_D_C
+   #define BN_MP_CLEAR_C
+   #define BN_MP_S_RMAP_C
+#endif
+
+#if defined(BN_MP_TORADIX_N_C)
+   #define BN_MP_ISZERO_C
+   #define BN_MP_INIT_COPY_C
+   #define BN_MP_DIV_D_C
+   #define BN_MP_CLEAR_C
+   #define BN_MP_S_RMAP_C
+#endif
+
+#if defined(BN_MP_UNSIGNED_BIN_SIZE_C)
+   #define BN_MP_COUNT_BITS_C
+#endif
+
+#if defined(BN_MP_XOR_C)
+   #define BN_MP_INIT_COPY_C
+   #define BN_MP_CLAMP_C
+   #define BN_MP_EXCH_C
+   #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_MP_ZERO_C)
+#endif
+
+#if defined(BN_PRIME_TAB_C)
+#endif
+
+#if defined(BN_REVERSE_C)
+#endif
+
+#if defined(BN_S_MP_ADD_C)
+   #define BN_MP_GROW_C
+   #define BN_MP_CLAMP_C
+#endif
+
+#if defined(BN_S_MP_EXPTMOD_C)
+   #define BN_MP_COUNT_BITS_C
+   #define BN_MP_INIT_C
+   #define BN_MP_CLEAR_C
+   #define BN_MP_REDUCE_SETUP_C
+   #define BN_MP_REDUCE_C
+   #define BN_MP_REDUCE_2K_SETUP_L_C
+   #define BN_MP_REDUCE_2K_L_C
+   #define BN_MP_MOD_C
+   #define BN_MP_COPY_C
+   #define BN_MP_SQR_C
+   #define BN_MP_MUL_C
+   #define BN_MP_SET_C
+   #define BN_MP_EXCH_C
+#endif
+
+#if defined(BN_S_MP_MUL_DIGS_C)
+   #define BN_FAST_S_MP_MUL_DIGS_C
+   #define BN_MP_INIT_SIZE_C
+   #define BN_MP_CLAMP_C
+   #define BN_MP_EXCH_C
+   #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_S_MP_MUL_HIGH_DIGS_C)
+   #define BN_FAST_S_MP_MUL_HIGH_DIGS_C
+   #define BN_MP_INIT_SIZE_C
+   #define BN_MP_CLAMP_C
+   #define BN_MP_EXCH_C
+   #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_S_MP_SQR_C)
+   #define BN_MP_INIT_SIZE_C
+   #define BN_MP_CLAMP_C
+   #define BN_MP_EXCH_C
+   #define BN_MP_CLEAR_C
+#endif
+
+#if defined(BN_S_MP_SUB_C)
+   #define BN_MP_GROW_C
+   #define BN_MP_CLAMP_C
+#endif
+
+#if defined(BNCORE_C)
+#endif
+
+#ifdef LTM3
+#define LTM_LAST
+#endif
+#include <tommath_superclass.h>
+#include <tommath_class.h>
+#else
+#define LTM_LAST
+#endif
diff --git a/libtommath/tommath_superclass.h b/libtommath/tommath_superclass.h
new file mode 100644
index 0000000..e3926df
--- /dev/null
+++ b/libtommath/tommath_superclass.h
@@ -0,0 +1,72 @@
+/* super class file for PK algos */
+
+/* default ... include all MPI */
+#define LTM_ALL
+
+/* RSA only (does not support DH/DSA/ECC) */
+/* #define SC_RSA_1 */
+
+/* For reference.... On an Athlon64 optimizing for speed...
+
+   LTM's mpi.o with all functions [striped] is 142KiB in size.
+
+*/
+
+/* Works for RSA only, mpi.o is 68KiB */
+#ifdef SC_RSA_1
+   #define BN_MP_SHRINK_C
+   #define BN_MP_LCM_C
+   #define BN_MP_PRIME_RANDOM_EX_C
+   #define BN_MP_INVMOD_C
+   #define BN_MP_GCD_C
+   #define BN_MP_MOD_C
+   #define BN_MP_MULMOD_C
+   #define BN_MP_ADDMOD_C
+   #define BN_MP_EXPTMOD_C
+   #define BN_MP_SET_INT_C
+   #define BN_MP_INIT_MULTI_C
+   #define BN_MP_CLEAR_MULTI_C
+   #define BN_MP_UNSIGNED_BIN_SIZE_C
+   #define BN_MP_TO_UNSIGNED_BIN_C
+   #define BN_MP_MOD_D_C
+   #define BN_MP_PRIME_RABIN_MILLER_TRIALS_C
+   #define BN_REVERSE_C
+   #define BN_PRIME_TAB_C
+
+   /* other modifiers */
+   #define BN_MP_DIV_SMALL                    /* Slower division, not critical */
+
+   /* here we are on the last pass so we turn things off.  The functions classes are still there
+    * but we remove them specifically from the build.  This also invokes tweaks in functions
+    * like removing support for even moduli, etc...
+    */
+#ifdef LTM_LAST
+   #undef  BN_MP_TOOM_MUL_C
+   #undef  BN_MP_TOOM_SQR_C
+   #undef  BN_MP_KARATSUBA_MUL_C
+   #undef  BN_MP_KARATSUBA_SQR_C
+   #undef  BN_MP_REDUCE_C
+   #undef  BN_MP_REDUCE_SETUP_C
+   #undef  BN_MP_DR_IS_MODULUS_C
+   #undef  BN_MP_DR_SETUP_C
+   #undef  BN_MP_DR_REDUCE_C
+   #undef  BN_MP_REDUCE_IS_2K_C
+   #undef  BN_MP_REDUCE_2K_SETUP_C
+   #undef  BN_MP_REDUCE_2K_C
+   #undef  BN_S_MP_EXPTMOD_C
+   #undef  BN_MP_DIV_3_C
+   #undef  BN_S_MP_MUL_HIGH_DIGS_C
+   #undef  BN_FAST_S_MP_MUL_HIGH_DIGS_C
+   #undef  BN_FAST_MP_INVMOD_C
+
+   /* To safely undefine these you have to make sure your RSA key won't exceed the Comba threshold
+    * which is roughly 255 digits [7140 bits for 32-bit machines, 15300 bits for 64-bit machines] 
+    * which means roughly speaking you can handle upto 2536-bit RSA keys with these defined without
+    * trouble.  
+    */
+   #undef  BN_S_MP_MUL_DIGS_C
+   #undef  BN_S_MP_SQR_C
+   #undef  BN_MP_MONTGOMERY_REDUCE_C
+#endif
+
+#endif
diff --git a/license.terms b/license.terms
new file mode 100644
index 0000000..d8049cd
--- /dev/null
+++ b/license.terms
@@ -0,0 +1,40 @@
+This software is copyrighted by the Regents of the University of
+California, Sun Microsystems, Inc., Scriptics Corporation, ActiveState
+Corporation and other parties.  The following terms apply to all files
+associated with the software unless explicitly disclaimed in
+individual files.
+
+The authors hereby grant permission to use, copy, modify, distribute,
+and license this software and its documentation for any purpose, provided
+that existing copyright notices are retained in all copies and that this
+notice is included verbatim in any distributions. No written agreement,
+license, or royalty fee is required for any of the authorized uses.
+Modifications to this software may be copyrighted by their authors
+and need not follow the licensing terms described here, provided that
+the new terms are clearly indicated on the first page of each file where
+they apply.
+
+IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY
+FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY
+DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+
+THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES,
+INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.  THIS SOFTWARE
+IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE
+NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR
+MODIFICATIONS.
+
+GOVERNMENT USE: If you are acquiring this software on behalf of the
+U.S. government, the Government shall have only "Restricted Rights"
+in the software and related documentation as defined in the Federal
+Acquisition Regulations (FARs) in Clause 52.227.19 (c) (2).  If you
+are acquiring the software on behalf of the Department of Defense, the
+software shall be classified as "Commercial Computer Software" and the
+Government shall have only "Restricted Rights" as defined in Clause
+252.227-7014 (b) (3) of DFARs.  Notwithstanding the foregoing, the
+authors grant the U.S. Government and others acting in its behalf
+permission to use and distribute the software in accordance with the
+terms specified in this license.
diff --git a/macosx/GNUmakefile b/macosx/GNUmakefile
new file mode 100644
index 0000000..54eea8e
--- /dev/null
+++ b/macosx/GNUmakefile
@@ -0,0 +1,208 @@
+########################################################################################################
+#
+# Makefile wrapper to build tcl on Mac OS X in a way compatible with the tk/macosx Xcode buildsystem
+#	uses the standard unix build system in tcl/unix (which can be used directly instead of this
+#	if you are not using the tk/macosx projects).
+#
+# Copyright (c) 2002-2008 Daniel A. Steffen <das@users.sourceforge.net>
+#
+# See the file "license.terms" for information on usage and redistribution of
+# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+########################################################################################################
+
+#-------------------------------------------------------------------------------------------------------
+# customizable settings
+
+DESTDIR			?=
+INSTALL_ROOT		?= ${DESTDIR}
+
+BUILD_DIR		?= ${CURDIR}/../../build
+SYMROOT			?= ${BUILD_DIR}/${PROJECT}
+OBJROOT			?= ${SYMROOT}
+
+EXTRA_CONFIGURE_ARGS	?=
+EXTRA_MAKE_ARGS		?=
+
+INSTALL_PATH		?= /Library/Frameworks
+PREFIX			?= /usr/local
+BINDIR			?= ${PREFIX}/bin
+LIBDIR			?= ${INSTALL_PATH}
+MANDIR			?= ${PREFIX}/man
+
+# set to non-empty value to install manpages in addition to html help:
+INSTALL_MANPAGES	?=
+
+#-------------------------------------------------------------------------------------------------------
+# meta targets
+
+meta			:= all install embedded install-embedded clean distclean test
+
+styles			:= develop deploy
+
+all			:= ${styles}
+all			: ${all}
+
+install			:= ${styles:%=install-%}
+install			: ${install}
+install-%:		action := install-
+
+embedded		:= ${styles:%=embedded-%}
+embedded		: embedded-deploy
+install-embedded	:= ${embedded:%=install-%}
+install-embedded	: install-embedded-deploy
+
+clean			:= ${styles:%=clean-%}
+clean			: ${clean}
+clean-%:		action := clean-
+distclean		:= ${styles:%=distclean-%}
+distclean		: ${distclean}
+distclean-%:		action := distclean-
+
+test			:= ${styles:%=test-%}
+test			: ${test}
+test-%:			action := test-
+
+targets			:= $(foreach v,${meta},${$v})
+
+#-------------------------------------------------------------------------------------------------------
+# build styles
+
+BUILD_STYLE		=
+CONFIGURE_ARGS		=
+OBJ_DIR			= ${OBJROOT}/${BUILD_STYLE}
+
+empty			:=
+space			:= ${empty} ${empty}
+objdir			= $(subst ${space},\ ,${OBJ_DIR})
+
+develop_make_args	:= BUILD_STYLE=Development CONFIGURE_ARGS=--enable-symbols
+deploy_make_args	:= BUILD_STYLE=Deployment INSTALL_TARGET=install-strip \
+			   EXTRA_CFLAGS=-DNDEBUG
+embedded_make_args	:= EMBEDDED_BUILD=1
+install_make_args	:= INSTALL_BUILD=1
+
+${targets}:
+	${MAKE} ${action}${PROJECT} \
+	$(foreach s,${styles} embedded install,$(if $(findstring $s,$@),${${s}_make_args}))
+
+#-------------------------------------------------------------------------------------------------------
+# project specific settings
+
+PROJECT			:= tcl
+PRODUCT_NAME		:= Tcl
+
+UNIX_DIR		:= ${CURDIR}/../unix
+VERSION			:= $(shell awk -F= '/^TCL_VERSION/ {print $$2; nextfile}' ${UNIX_DIR}/configure.in)
+TCLSH			:= tclsh${VERSION}
+
+BUILD_TARGET		:= all tcltest
+INSTALL_TARGET		:= install
+
+export CPPROG		:= cp -p
+
+INSTALL_TARGETS		= install-binaries install-headers install-libraries
+ifeq (${EMBEDDED_BUILD},)
+INSTALL_TARGETS		+= install-private-headers
+endif
+ifeq (${INSTALL_BUILD}_${EMBEDDED_BUILD}_${BUILD_STYLE},1__Deployment)
+INSTALL_TARGETS		+= install-packages html-tcl
+ifneq (${INSTALL_MANPAGES},)
+INSTALL_TARGETS		+= install-doc
+endif
+endif
+
+MAKE_VARS		:= INSTALL_ROOT INSTALL_TARGETS VERSION GENERIC_FLAGS
+MAKE_ARGS_V		= $(foreach v,${MAKE_VARS},$v='${$v}')
+
+build-${PROJECT}:	target = ${BUILD_TARGET}
+install-${PROJECT}:	target = ${INSTALL_TARGET}
+clean-${PROJECT} distclean-${PROJECT} test-${PROJECT}: \
+			target = $*
+
+DO_MAKE			= +${MAKE} -C "${OBJ_DIR}" ${target} ${MAKE_ARGS_V} ${MAKE_ARGS} ${EXTRA_MAKE_ARGS}
+
+#-------------------------------------------------------------------------------------------------------
+# build rules
+
+${PROJECT}:
+	${MAKE} install-${PROJECT} INSTALL_ROOT="${OBJ_DIR}/"
+
+${objdir}/Makefile: ${UNIX_DIR}/Makefile.in ${UNIX_DIR}/configure \
+		     ${UNIX_DIR}/tclConfig.sh.in Tcl-Info.plist.in
+	mkdir -p "${OBJ_DIR}" && cd "${OBJ_DIR}" && \
+	if [ ${UNIX_DIR}/configure -nt config.status ]; then ${UNIX_DIR}/configure -C \
+	--prefix="${PREFIX}" --bindir="${BINDIR}" --libdir="${LIBDIR}" \
+	--mandir="${MANDIR}" --enable-threads --enable-framework --enable-dtrace \
+	${CONFIGURE_ARGS} ${EXTRA_CONFIGURE_ARGS}; else ./config.status; fi
+
+build-${PROJECT}: ${objdir}/Makefile
+	${DO_MAKE}
+ifeq (${INSTALL_BUILD},)
+# symolic link hackery to trick
+# 'make install INSTALL_ROOT=${OBJ_DIR}'
+# into building Tcl.framework and tclsh in ${SYMROOT}
+	@cd "${OBJ_DIR}" && mkdir -p $(dir $(subst ${space},\ ,./${LIBDIR})) $(dir $(subst ${space},\ ,./${BINDIR})) "${SYMROOT}" && \
+	rm -f "./${LIBDIR}" "./${BINDIR}" && ln -fs "${SYMROOT}" "./${LIBDIR}" && \
+	ln -fs "${SYMROOT}" "./${BINDIR}" && ln -fs "${OBJ_DIR}/tcltest" "${SYMROOT}"
+endif
+
+install-${PROJECT}: build-${PROJECT}
+ifeq (${EMBEDDED_BUILD}_${INSTALL_ROOT},1_)
+	@echo "Cannot install-embedded with empty INSTALL_ROOT !" && false
+endif
+ifeq (${EMBEDDED_BUILD},1)
+	@rm -rf "${INSTALL_ROOT}/${LIBDIR}/Tcl.framework"
+endif
+	${DO_MAKE}
+ifeq (${INSTALL_BUILD},1)
+ifeq (${EMBEDDED_BUILD},1)
+# if we are embedding frameworks, don't install tclsh
+	@rm -f "${INSTALL_ROOT}${BINDIR}/${TCLSH}" && \
+	rmdir -p "${INSTALL_ROOT}${BINDIR}" 2>&- || true
+else
+# redo prebinding (when not building for Mac OS X 10.4 or later only)
+	@if [ "`echo "$${MACOSX_DEPLOYMENT_TARGET}" | \
+	awk -F '10\\.' '{print int($$2)}'`" -lt 4 -a "`echo "$${CFLAGS}" | \
+	awk -F '-mmacosx-version-min=10\\.' '{print int($$2)}'`" -lt 4 ]; \
+	then cd ${INSTALL_ROOT}/; \
+	if [ ! -d usr/lib ]; then mkdir -p usr && ln -fs /usr/lib usr/ && RM_USRLIB=1; fi; \
+	if [ ! -d System ]; then ln -fs /System . && RM_SYSTEM=1; fi; \
+	redo_prebinding -r . "./${LIBDIR}/${PRODUCT_NAME}.framework/Versions/${VERSION}/${PRODUCT_NAME}"; \
+	redo_prebinding -r . "./${BINDIR}/${TCLSH}"; \
+	if [ -n "$${RM_USRLIB:-}" ]; then rm -f usr/lib; rmdir -p usr 2>&-; fi; \
+	if [ -n "$${RM_SYSTEM:-}" ]; then rm -f System; fi; fi
+# install tclsh symbolic link
+	@ln -fs ${TCLSH} "${INSTALL_ROOT}${BINDIR}/tclsh"
+endif
+endif
+ifeq (${BUILD_STYLE}_${EMBEDDED_BUILD},Development_)
+# keep copy of debug library around, so that
+# Deployment build can be installed on top
+# of Development build without overwriting
+# the debug library
+	@cd "${INSTALL_ROOT}${LIBDIR}/${PRODUCT_NAME}.framework/Versions/${VERSION}" && \
+	ln -f "${PRODUCT_NAME}" "${PRODUCT_NAME}_debug"
+endif
+
+clean-${PROJECT}: %-${PROJECT}:
+	${DO_MAKE}
+	rm -rf "${SYMROOT}"/{${PRODUCT_NAME}.framework,${TCLSH},tcltest}
+	rm -f "${OBJ_DIR}"{"${LIBDIR}","${BINDIR}"} && \
+	rmdir -p "${OBJ_DIR}"$(dir $(subst ${space},\ ,${LIBDIR})) 2>&- || true && \
+	rmdir -p "${OBJ_DIR}"$(dir $(subst ${space},\ ,${BINDIR})) 2>&- || true
+
+distclean-${PROJECT}: %-${PROJECT}: clean-${PROJECT}
+	${DO_MAKE}
+	rm -rf "${OBJ_DIR}"
+
+test-${PROJECT}: %-${PROJECT}: build-${PROJECT}
+	${DO_MAKE}
+
+#-------------------------------------------------------------------------------------------------------
+
+.PHONY: ${meta} ${targets} ${PROJECT} build-${PROJECT} install-${PROJECT} \
+	clean-${PROJECT} distclean-${PROJECT}
+
+.NOTPARALLEL:
+
+#-------------------------------------------------------------------------------------------------------
diff --git a/macosx/README b/macosx/README
new file mode 100644
index 0000000..bcffde3
--- /dev/null
+++ b/macosx/README
@@ -0,0 +1,174 @@
+Tcl Mac OS X README
+-------------------
+
+This is the README file for the Mac OS X/Darwin version of Tcl.
+
+
+1. Where to go for support
+--------------------------
+
+- The tcl-mac mailing list on sourceforge is the best place to ask questions
+specific to Tcl & Tk on Mac OS X:
+	http://lists.sourceforge.net/lists/listinfo/tcl-mac
+(this page also has a link to searchable archives of the list, please check them
+before asking on the list, many questions have already been answered).
+
+- For general Tcl/Tk questions, the newsgroup comp.lang.tcl is your best bet:
+	http://groups.google.com/group/comp.lang.tcl/
+
+- The Tcl'ers Wiki also has many pages dealing with Tcl & Tk on Mac OS X, see
+	http://wiki.tcl.tk/_/ref?N=3753
+	http://wiki.tcl.tk/_/ref?N=8361
+
+- Please report bugs with Tcl on Mac OS X to the tracker:
+	http://core.tcl.tk/tcl/reportlist
+
+2. Using Tcl on Mac OS X
+------------------------
+
+- At a minimum, Mac OS X 10.3 is required to run Tcl.
+
+- Unless weak-linking is used, Tcl built on Mac OS X 10.x will not run on 10.y
+with y < x; on the other hand Tcl built on 10.y will always run on 10.x with
+y <= x (but without any of the fixes and optimizations that would be available
+in a binary built on 10.x).
+Weak-linking is available on OS X 10.2 or later, it additionally allows Tcl
+built on 10.x to run on any 10.y with x > y >= z (for a chosen z >= 2).
+
+- Tcl extensions can be installed in any of:
+	$HOME/Library/Tcl /Library/Tcl /System/Library/Tcl
+	$HOME/Library/Frameworks /Library/Frameworks /System/Library/Frameworks
+	(searched in that order).
+Given a potential package directory $pkg, Tcl on OSX checks for the file
+$pkg/Resources/Scripts/pkgIndex.tcl as well as the usual $pkg/pkgIndex.tcl.
+This allows building extensions as frameworks with all script files contained in
+the Resources/Scripts directory of the framework.
+
+- [load]able binary extensions can linked as either ordinary shared libraries
+(.dylib) or as MachO bundles (since 8.4.10/8.5a3); bundles have the advantage
+that they are [load]ed more efficiently from a tcl VFS (no temporary copy to the
+native filesystem required), and prior to Mac OS X 10.5, only bundles can be
+[unload]ed.
+
+- The 'deploy' target of macosx/GNUmakefile installs the html manpages into the
+standard documentation location in the Tcl framework:
+	Tcl.framework/Resources/Documentation/Reference/Tcl
+No nroff manpages are installed by default by the GNUmakefile.
+
+- The Tcl framework can be installed in any of the system's standard
+framework directories:
+	$HOME/Library/Frameworks /Library/Frameworks /System/Library/Frameworks
+
+
+3. Building Tcl on Mac OS X
+---------------------------
+
+- At least Mac OS X 10.3 is required to build Tcl.
+Apple's Xcode Developer Tools need to be installed (only the most recent version
+matching your OS release is supported), the Xcode installer is available on Mac
+OS X install media or may be present in /Applications/Installers on Macs that
+came with OS X preinstalled. The most recent version can always be downloaded
+from the ADC website http://connect.apple.com (free ADC membership required).
+
+- Tcl is most easily built as a Mac OS X framework via GNUmakefile in tcl/macosx
+(see below for details), but can also be built with the standard unix configure
+and make buildsystem in tcl/unix as on any other unix platform (indeed, the
+GNUmakefile is just a wrapper around the unix buildsystem).
+The Mac OS X specific configure flags are --enable-framework and
+--disable-corefoundation (which disables CF and notably reverts to the standard
+select based notifier).
+
+- It is also possible to build with the Xcode IDE via the projects in
+tcl/macosx, take care to use the project matching your DevTools and OS version:
+	Tcl.xcode: 		    for Xcode 3.1 on 10.5
+	Tcl.xcodeproj:		    for Xcode 3.2 on 10.6
+These have the following targets:
+	Tcl:			    calls through to tcl/macosx/GNUMakefile.
+	tcltest:		    static build of tcltest for debugging.
+	tests:			    build tcltest target and run tcl testsuite.
+The following build configurations are available:
+	Debug:			    debug build for the active architecture,
+				    with Fix & Continue enabled.
+	Debug clang:		    use clang compiler.
+	Debug llvm-gcc:		    use llvm-gcc compiler.
+	Debug gcc40:		    use gcc 4.0 compiler.
+	DebugNoFixAndContinue:      disable Fix & Continue.
+	DebugUnthreaded:	    disable threading.
+	DebugNoCF:		    disable corefoundation.
+	DebugNoCFUnthreaded:	    disable corefoundation an threading.
+	DebugMemCompile:	    enable memory and bytecode debugging.
+	DebugLeaks:		    define PURIFY.
+	DebugGCov:		    enable generation of gcov data files.
+	Debug64bit:		    configure with --enable-64bit (requires
+				    building on a 64bit capable processor).
+	Release:		    release build for the active architecture.
+	ReleaseUniversal:	    32/64-bit universal build.
+	ReleaseUniversal clang:	    use clang compiler.
+	ReleaseUniversal llvm-gcc:  use llvm-gcc compiler.
+	ReleaseUniversal gcc40:	    use gcc 4.0 compiler.
+	ReleaseUniversal10.5SDK:    build against the 10.5 SDK (with 10.5
+				    deployment target).
+	Note that the non-SDK configurations have their deployment target set to
+	10.5 (Tcl.xcode) resp. 10.6 (Tcl.xcodeproj).
+The Xcode projects refer to the toplevel tcl source directory via the
+TCL_SRCROOT user build setting, by default this is set to the project-relative
+path '../../tcl', if your tcl source directory is named differently, e.g.
+'../../tcl8.6', you need to manually change the TCL_SRCROOT setting by editing
+your ${USER}.pbxuser file (located inside the Tcl.xcodeproj bundle directory)
+with a text editor.
+
+- To build universal binaries outside of the Xcode IDE, set CFLAGS as follows:
+	export CFLAGS="-arch i386 -arch x86_64 -arch ppc"
+This requires Mac OS X 10.4 and Xcode 2.4 (or Xcode 2.2 if -arch x86_64 is
+omitted, but _not_ Xcode 2.1) and will work on any architecture (on PowerPC
+Tiger you need to add "-isysroot /Developer/SDKs/MacOSX10.4u.sdk").
+Note that configure requires CFLAGS to contain a least one architecture that can
+be run on the build machine (i.e. ppc on G3/G4, ppc or ppc64 on G5, ppc or i386
+on Core and ppc, i386 or x86_64 on Core2/Xeon).
+Universal builds of Tcl TEA extensions are also possible with CFLAGS set as
+above, they will be [load]able by universal as well as thin binaries of Tcl.
+
+- To enable weak-linking, set the MACOSX_DEPLOYMENT_TARGET environment variable
+to the minimal OS version the binaries should be able to run on, e.g:
+	export MACOSX_DEPLOYMENT_TARGET=10.4
+This requires at least gcc 3.1; with gcc 4 or later, set/add to CFLAGS instead:
+	export CFLAGS="-mmacosx-version-min=10.4"
+Support for weak-linking was added with 8.4.14/8.5a5.
+
+Detailed Instructions for building with macosx/GNUmakefile
+----------------------------------------------------------
+
+- Unpack the Tcl source release archive.
+
+- The following instructions assume the Tcl source tree is named "tcl${ver}",
+(where ${ver} is a shell variable containing the Tcl version number e.g. '8.6').
+Setup this shell variable as follows:
+	ver="8.6"
+If you are building from CVS, omit this step (CVS source tree names usually do
+not contain a version number).
+
+- Setup environment variables as desired, e.g. for a universal build on 10.5:
+	CFLAGS="-arch i386 -arch x86_64 -arch ppc -mmacosx-version-min=10.5"
+	export CFLAGS
+
+- Change to the directory containing the Tcl source tree and build:
+	make -C tcl${ver}/macosx
+
+- Install Tcl onto the root volume (admin password required):
+	sudo make -C tcl${ver}/macosx install
+if you don't have an admin password, you can install into your home directory
+instead by passing an INSTALL_ROOT argument to make:
+	make -C tcl${ver}/macosx install INSTALL_ROOT="${HOME}/"
+
+- The default GNUmakefile targets will build _both_ debug and optimized versions
+of the Tcl framework with the standard convention of naming the debug library
+Tcl.framework/Tcl_debug.
+This allows switching to the debug libraries at runtime by setting
+	export DYLD_IMAGE_SUFFIX=_debug
+(c.f. man dyld for more details)
+
+If you only want to build and install the debug or optimized build, use the
+'develop' or 'deploy' target variants of the GNUmakefile, respectively.
+For example, to build and install only the optimized versions:
+	make -C tcl${ver}/macosx deploy
+	sudo make -C tcl${ver}/macosx install-deploy
diff --git a/macosx/Tcl-Common.xcconfig b/macosx/Tcl-Common.xcconfig
new file mode 100644
index 0000000..9c47547
--- /dev/null
+++ b/macosx/Tcl-Common.xcconfig
@@ -0,0 +1,37 @@
+//
+// Tcl-Common.xcconfig --
+//
+//	This file contains the Xcode build settings comon to all
+//	project configurations in Tcl.xcodeproj.
+//
+// Copyright (c) 2007-2008 Daniel A. Steffen <das@users.sourceforge.net>
+//
+// See the file "license.terms" for information on usage and redistribution
+// of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+HEADER_SEARCH_PATHS = "$(DERIVED_FILE_DIR)/tcl" $(HEADER_SEARCH_PATHS)
+OTHER_LDFLAGS = -headerpad_max_install_names -sectcreate __TEXT __info_plist "$(DERIVED_FILE_DIR)/tcl/Tclsh-Info.plist" $(OTHER_LDFLAGS)
+INSTALL_PATH = $(BINDIR)
+INSTALL_MODE_FLAG = go-w,a+rX
+GCC_PREFIX_HEADER = $(DERIVED_FILE_DIR)/tcl/tclConfig.h
+GCC_GENERATE_DEBUGGING_SYMBOLS = YES
+GCC_NO_COMMON_BLOCKS = YES
+GCC_DYNAMIC_NO_PIC = YES
+GCC_VERSION = 4.2
+GCC = gcc-$(GCC_VERSION)
+WARNING_CFLAGS = -Wall -Wextra -Wno-unused-parameter -Wno-missing-field-initializers -Wno-unused-value -Winit-self -Wpointer-arith -Wcast-align -Wdisabled-optimization -Winline $(WARNING_CFLAGS)
+BINDIR = $(PREFIX)/bin
+CFLAGS = $(CFLAGS)
+CPPFLAGS = -mmacosx-version-min=$(MACOSX_DEPLOYMENT_TARGET) $(CPPFLAGS)
+FRAMEWORK_INSTALL_PATH = /Library/Frameworks
+INCLUDEDIR = $(PREFIX)/include
+LIBDIR = $(PREFIX)/lib
+MANDIR = $(PREFIX)/man
+PER_ARCH_CFLAGS_ppc = -mcpu=G3 -mtune=G4 $(PER_ARCH_CFLAGS_ppc)
+PER_ARCH_CFLAGS_ppc64 = -mcpu=G5 -mpowerpc64 $(PER_ARCH_CFLAGS_ppc64)
+PREFIX = /usr/local
+TCL_CONFIGURE_ARGS = --enable-threads --enable-dtrace
+TCL_LIBRARY = $(LIBDIR)/tcl$(VERSION)
+TCL_PACKAGE_PATH = "$(LIBDIR)"
+TCL_DEFS = HAVE_TCL_CONFIG_H
+VERSION = 8.6
diff --git a/macosx/Tcl-Debug.xcconfig b/macosx/Tcl-Debug.xcconfig
new file mode 100644
index 0000000..03d2b2d
--- /dev/null
+++ b/macosx/Tcl-Debug.xcconfig
@@ -0,0 +1,20 @@
+//
+// Tcl-Debug.xcconfig --
+//
+//	This file contains the Xcode build settings for all Debug
+//	project configurations in Tcl.xcodeproj.
+//
+// Copyright (c) 2007 Daniel A. Steffen <das@users.sourceforge.net>
+//
+// See the file "license.terms" for information on usage and redistribution
+// of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+#include "Tcl-Common.xcconfig"
+
+DEBUG_INFORMATION_FORMAT = dwarf
+DEAD_CODE_STRIPPING = NO
+DEPLOYMENT_POSTPROCESSING = NO
+GCC_OPTIMIZATION_LEVEL = 0
+GCC_PREPROCESSOR_DEFINITIONS = $(TCL_DEFS) $(GCC_PREPROCESSOR_DEFINITIONS)
+CONFIGURE_ARGS = --enable-symbols $(TCL_CONFIGURE_ARGS) $(CONFIGURE_ARGS)
+MAKE_TARGET = develop
diff --git a/macosx/Tcl-Info.plist.in b/macosx/Tcl-Info.plist.in
new file mode 100644
index 0000000..f5c6b15
--- /dev/null
+++ b/macosx/Tcl-Info.plist.in
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<!--
+	Copyright (c) 2005-2007 Daniel A. Steffen <das@users.sourceforge.net>
+
+	See the file "license.terms" for information on usage and redistribution of
+	this file, and for a DISCLAIMER OF ALL WARRANTIES.
+-->
+<plist version="1.0">
+<dict>
+	<key>CFBundleDevelopmentRegion</key>
+	<string>English</string>
+	<key>CFBundleExecutable</key>
+	<string>@TCL_LIB_FILE@</string>
+	<key>CFBundleGetInfoString</key>
+	<string>Tcl @TCL_VERSION@@TCL_PATCH_LEVEL@,
+Copyright © 1987-@TCL_YEAR@ Tcl Core Team,
+Copyright © 2001-@TCL_YEAR@ Daniel A. Steffen,
+Copyright © 2001-2009 Apple Inc.,
+Copyright © 2001-2002 Jim Ingham &amp; Ian Reid</string>
+	<key>CFBundleIdentifier</key>
+	<string>com.tcltk.tcllibrary</string>
+	<key>CFBundleInfoDictionaryVersion</key>
+	<string>6.0</string>
+	<key>CFBundleName</key>
+	<string>Tcl @TCL_VERSION@</string>
+	<key>CFBundlePackageType</key>
+	<string>FMWK</string>
+	<key>CFBundleShortVersionString</key>
+	<string>@TCL_VERSION@@TCL_PATCH_LEVEL@</string>
+	<key>CFBundleSignature</key>
+	<string>Tcl </string>
+	<key>CFBundleVersion</key>
+	<string>@TCL_VERSION@@TCL_PATCH_LEVEL@</string>
+</dict>
+</plist>
diff --git a/macosx/Tcl-Release.xcconfig b/macosx/Tcl-Release.xcconfig
new file mode 100644
index 0000000..d960a52
--- /dev/null
+++ b/macosx/Tcl-Release.xcconfig
@@ -0,0 +1,20 @@
+//
+// Tcl-Release.xcconfig --
+//
+//	This file contains the Xcode build settings for all Release
+//	project configurations in Tcl.xcodeproj.
+//
+// Copyright (c) 2007 Daniel A. Steffen <das@users.sourceforge.net>
+//
+// See the file "license.terms" for information on usage and redistribution
+// of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+#include "Tcl-Common.xcconfig"
+
+DEBUG_INFORMATION_FORMAT = dwarf-with-dsym
+DEAD_CODE_STRIPPING = YES
+DEPLOYMENT_POSTPROCESSING = YES
+GCC_OPTIMIZATION_LEVEL = s
+GCC_PREPROCESSOR_DEFINITIONS = NDEBUG $(TCL_DEFS) $(GCC_PREPROCESSOR_DEFINITIONS)
+CONFIGURE_ARGS = --disable-symbols $(TCL_CONFIGURE_ARGS) $(CONFIGURE_ARGS)
+MAKE_TARGET = deploy
diff --git a/macosx/Tcl.xcode/default.pbxuser b/macosx/Tcl.xcode/default.pbxuser
new file mode 100644
index 0000000..22ffa9e
--- /dev/null
+++ b/macosx/Tcl.xcode/default.pbxuser
@@ -0,0 +1,200 @@
+// !$*UTF8*$!
+{
+	08FB7793FE84155DC02AAC07 /* Project object */ = {
+		activeBuildConfigurationName = Debug;
+		activeExecutable = F9E61D1C090A4282002B3151 /* tclsh */;
+		activeTarget = F9E61D16090A3E94002B3151 /* Tcl */;
+		codeSenseManager = F944EB9D08F798180049FDD4 /* Code sense */;
+		executables = (
+			F9E61D1C090A4282002B3151 /* tclsh */,
+			F944EB8F08F798100049FDD4 /* tcltest */,
+		);
+		perUserDictionary = {
+			com.apple.ide.smrt.PBXUserSmartGroupsKey.Rev10 = <040b73747265616d747970656481e8038401408484840e4e534d757461626c654172726179008484074e534172726179008484084e534f626a65637400858401690192848484134e534d757461626c6544696374696f6e6172790084840c4e5344696374696f6e6172790095960792848484084e53537472696e67019584012b046e616d658692849a9a14496d706c656d656e746174696f6e2046696c65738692849a9a146162736f6c75746550617468546f42756e646c658692849a9a008692849a9a195042585472616e7369656e744c6f636174696f6e4174546f708692849a9a06626f74746f6d8692849a9a03636c7a8692849a9a1550425846696c656e616d65536d61727447726f75708692849a9a0b6465736372697074696f6e8692849a9a103c6e6f206465736372697074696f6e3e8692849a9a0b707265666572656e63657386928497960892849a9a07666e6d617463688692849a9a008692849a9a05696d6167658692849a9a0b536d617274466f6c6465728692849a9a04726f6f748692849a9a093c50524f4a4543543e8692849a9a0572656765788692849a9a065c2e286329248692849a9a097265637572736976658692848484084e534e756d626572008484074e5356616c7565009584012a849696018692849a9a0669734c656166869284b09db296008692849a9a0763616e536176658692af92849a9a1250425850726f6a65637453636f70654b65798692849a9a03594553868692849a9a08676c6f62616c49448692849a9a18314343304541343030343335304546393030343434313042868686>;
+		};
+		sourceControlManager = F944EB9C08F798180049FDD4 /* Source Control */;
+		userBuildSettings = {
+			SYMROOT = "${SRCROOT}/../../build/tcl";
+			TCL_SRCROOT = "${SRCROOT}/../../tcl";
+		};
+	};
+	8DD76FA90486AB0100D96B5E /* tcltest */ = {
+		activeExec = 0;
+		executables = (
+			F944EB8F08F798100049FDD4 /* tcltest */,
+		);
+	};
+	F944EB8F08F798100049FDD4 /* tcltest */ = {
+		isa = PBXExecutable;
+		activeArgIndices = (
+			NO,
+			NO,
+			NO,
+		);
+		argumentStrings = (
+			"${TCL_SRCROOT}/tests/all.tcl",
+			"-singleproc 1",
+			"-verbose \"bet\"",
+		);
+		autoAttachOnCrash = 1;
+		breakpointsEnabled = 1;
+		configStateDict = {
+			"PBXLSLaunchAction-0" = {
+				PBXLSLaunchAction = 0;
+				PBXLSLaunchStartAction = 1;
+				PBXLSLaunchStdioStyle = 2;
+				PBXLSLaunchStyle = 0;
+				class = PBXLSRunLaunchConfig;
+				displayName = "Executable Runner";
+				identifier = com.apple.Xcode.launch.runConfig;
+				remoteHostInfo = "";
+				startActionInfo = "";
+			};
+			"PBXLSLaunchAction-1" = {
+				PBXLSLaunchAction = 1;
+				PBXLSLaunchStartAction = 1;
+				PBXLSLaunchStdioStyle = 2;
+				PBXLSLaunchStyle = 0;
+				class = PBXGDB_LaunchConfig;
+				displayName = GDB;
+				identifier = com.apple.Xcode.launch.GDBMI_Config;
+				remoteHostInfo = "";
+				startActionInfo = "";
+			};
+		};
+		customDataFormattersEnabled = 1;
+		debuggerPlugin = GDBDebugging;
+		disassemblyDisplayState = 0;
+		dylibVariantSuffix = "";
+		enableDebugStr = 0;
+		environmentEntries = (
+			{
+				active = YES;
+				name = TCL_LIBRARY;
+				value = "${TCL_SRCROOT}/library";
+			},
+			{
+				active = YES;
+				name = TCLLIBPATH;
+				value = /Library/Tcl;
+			},
+			{
+				active = NO;
+				name = DYLD_PRINT_LIBRARIES;
+			},
+			{
+				active = NO;
+				name = MallocBadFreeAbort;
+				value = 1;
+			},
+			{
+				active = NO;
+				name = MallocLogFile;
+				value = /tmp/malloc.log;
+			},
+			{
+				active = NO;
+				name = MallocStackLogging;
+				value = 1;
+			},
+			{
+				active = NO;
+				name = MallocStackLoggingNoCompact;
+				value = 1;
+			},
+			{
+				active = NO;
+				name = MallocPreScribble;
+				value = 1;
+			},
+			{
+				active = NO;
+				name = MallocScribble;
+				value = 1;
+			},
+		);
+		executableSystemSymbolLevel = 0;
+		executableUserSymbolLevel = 0;
+		libgmallocEnabled = 0;
+		name = tcltest;
+		sourceDirectories = (
+		);
+	};
+	F944EB9C08F798180049FDD4 /* Source Control */ = {
+		isa = PBXSourceControlManager;
+		fallbackIsa = XCSourceControlManager;
+		isSCMEnabled = 0;
+		scmConfiguration = {
+			CVSToolPath = /usr/bin/cvs;
+			CVSUseSSH = NO;
+			SubversionToolPath = /usr/bin/svn;
+			repositoryNamesForRoots = {
+				.. = "";
+			};
+		};
+		scmType = scm.cvs;
+	};
+	F944EB9D08F798180049FDD4 /* Code sense */ = {
+		isa = PBXCodeSenseManager;
+		indexTemplatePath = "";
+	};
+	F97258A50A86873C00096C78 /* tests */ = {
+		activeExec = 0;
+	};
+	F9E61D16090A3E94002B3151 /* Tcl */ = {
+		activeExec = 0;
+		executables = (
+			F9E61D1C090A4282002B3151 /* tclsh */,
+		);
+	};
+	F9E61D1C090A4282002B3151 /* tclsh */ = {
+		isa = PBXExecutable;
+		activeArgIndices = (
+		);
+		argumentStrings = (
+		);
+		autoAttachOnCrash = 1;
+		breakpointsEnabled = 1;
+		configStateDict = {
+			"PBXLSLaunchAction-0" = {
+				PBXLSLaunchAction = 0;
+				PBXLSLaunchStartAction = 1;
+				PBXLSLaunchStdioStyle = 2;
+				PBXLSLaunchStyle = 0;
+				class = PBXLSRunLaunchConfig;
+				displayName = "Executable Runner";
+				identifier = com.apple.Xcode.launch.runConfig;
+				remoteHostInfo = "";
+				startActionInfo = "";
+			};
+			"PBXLSLaunchAction-1" = {
+				PBXLSLaunchAction = 1;
+				PBXLSLaunchStartAction = 1;
+				PBXLSLaunchStdioStyle = 2;
+				PBXLSLaunchStyle = 0;
+				class = PBXGDB_LaunchConfig;
+				displayName = GDB;
+				identifier = com.apple.Xcode.launch.GDBMI_Config;
+				remoteHostInfo = "";
+				startActionInfo = "";
+			};
+		};
+		customDataFormattersEnabled = 1;
+		debuggerPlugin = GDBDebugging;
+		disassemblyDisplayState = 0;
+		dylibVariantSuffix = _debug;
+		enableDebugStr = 0;
+		environmentEntries = (
+			{
+				active = NO;
+				name = DYLD_PRINT_LIBRARIES;
+			},
+		);
+		executableSystemSymbolLevel = 0;
+		executableUserSymbolLevel = 0;
+		libgmallocEnabled = 0;
+		name = tclsh;
+		sourceDirectories = (
+		);
+	};
+}
diff --git a/macosx/Tcl.xcode/project.pbxproj b/macosx/Tcl.xcode/project.pbxproj
new file mode 100644
index 0000000..a28b8db
--- /dev/null
+++ b/macosx/Tcl.xcode/project.pbxproj
@@ -0,0 +1,2934 @@
+// !$*UTF8*$!
+{
+	archiveVersion = 1;
+	classes = {
+	};
+	objectVersion = 45;
+	objects = {
+
+/* Begin PBXBuildFile section */
+		F90509300913A72400327603 /* tclAppInit.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D445508F272B9004A47F5 /* tclAppInit.c */; settings = {COMPILER_FLAGS = "-DTCL_TEST -DTCL_BUILDTIME_LIBRARY=\\\"$(TCL_SRCROOT)/library\\\""; }; };
+		F93599B30DF1F75400E04F67 /* tclOO.c in Sources */ = {isa = PBXBuildFile; fileRef = F93599B20DF1F75400E04F67 /* tclOO.c */; };
+		F93599B70DF1F76100E04F67 /* tclOOBasic.c in Sources */ = {isa = PBXBuildFile; fileRef = F93599B60DF1F76100E04F67 /* tclOOBasic.c */; };
+		F93599B90DF1F76600E04F67 /* tclOOCall.c in Sources */ = {isa = PBXBuildFile; fileRef = F93599B80DF1F76600E04F67 /* tclOOCall.c */; };
+		F93599BC0DF1F77000E04F67 /* tclOODefineCmds.c in Sources */ = {isa = PBXBuildFile; fileRef = F93599BB0DF1F77000E04F67 /* tclOODefineCmds.c */; };
+		F93599BE0DF1F77400E04F67 /* tclOOInfo.c in Sources */ = {isa = PBXBuildFile; fileRef = F93599BD0DF1F77400E04F67 /* tclOOInfo.c */; };
+		F93599C20DF1F78300E04F67 /* tclOOMethod.c in Sources */ = {isa = PBXBuildFile; fileRef = F93599C10DF1F78300E04F67 /* tclOOMethod.c */; };
+		F93599C40DF1F78800E04F67 /* tclOOStubInit.c in Sources */ = {isa = PBXBuildFile; fileRef = F93599C30DF1F78800E04F67 /* tclOOStubInit.c */; };
+		F93599C60DF1F78D00E04F67 /* tclOOStubLib.c in Sources */ = {isa = PBXBuildFile; fileRef = F93599C50DF1F78D00E04F67 /* tclOOStubLib.c */; };
+		F95D77EA0DFD820D00A8BF6F /* tclIORTrans.c in Sources */ = {isa = PBXBuildFile; fileRef = F95D77E90DFD820D00A8BF6F /* tclIORTrans.c */; };
+		F96437CA0EF0D4B2003F468E /* tclZlib.c in Sources */ = {isa = PBXBuildFile; fileRef = F96437C90EF0D4B2003F468E /* tclZlib.c */; };
+		F96437E70EF0D652003F468E /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = F96437E60EF0D652003F468E /* libz.dylib */; };
+		F966C07508F2820D005CB29B /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F966C07408F2820D005CB29B /* CoreFoundation.framework */; };
+		F96D456F08F272BB004A47F5 /* regcomp.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3ED008F272A7004A47F5 /* regcomp.c */; };
+		F96D457208F272BB004A47F5 /* regerror.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3ED308F272A7004A47F5 /* regerror.c */; };
+		F96D457508F272BB004A47F5 /* regexec.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3ED608F272A7004A47F5 /* regexec.c */; };
+		F96D457608F272BB004A47F5 /* regfree.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3ED708F272A7004A47F5 /* regfree.c */; };
+		F96D457B08F272BB004A47F5 /* tclAlloc.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EDC08F272A7004A47F5 /* tclAlloc.c */; settings = {COMPILER_FLAGS = "-DUSE_TCLALLOC=0"; }; };
+		F96D457C08F272BB004A47F5 /* tclAsync.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EDD08F272A7004A47F5 /* tclAsync.c */; };
+		F96D457D08F272BB004A47F5 /* tclBasic.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EDE08F272A7004A47F5 /* tclBasic.c */; };
+		F96D457E08F272BC004A47F5 /* tclBinary.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EDF08F272A7004A47F5 /* tclBinary.c */; };
+		F96D457F08F272BC004A47F5 /* tclCkalloc.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EE008F272A7004A47F5 /* tclCkalloc.c */; };
+		F96D458008F272BC004A47F5 /* tclClock.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EE108F272A7004A47F5 /* tclClock.c */; };
+		F96D458108F272BC004A47F5 /* tclCmdAH.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EE208F272A7004A47F5 /* tclCmdAH.c */; };
+		F96D458208F272BC004A47F5 /* tclCmdIL.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EE308F272A7004A47F5 /* tclCmdIL.c */; };
+		F96D458308F272BC004A47F5 /* tclCmdMZ.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EE408F272A7004A47F5 /* tclCmdMZ.c */; };
+		F96D458408F272BC004A47F5 /* tclCompCmds.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EE508F272A7004A47F5 /* tclCompCmds.c */; };
+		F96D458508F272BC004A47F5 /* tclCompExpr.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EE608F272A7004A47F5 /* tclCompExpr.c */; };
+		F96D458608F272BC004A47F5 /* tclCompile.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EE708F272A7004A47F5 /* tclCompile.c */; };
+		F96D458808F272BC004A47F5 /* tclConfig.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EE908F272A7004A47F5 /* tclConfig.c */; };
+		F96D458908F272BC004A47F5 /* tclDate.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EEA08F272A7004A47F5 /* tclDate.c */; };
+		F96D458B08F272BC004A47F5 /* tclDictObj.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EEC08F272A7004A47F5 /* tclDictObj.c */; };
+		F96D458C08F272BC004A47F5 /* tclEncoding.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EED08F272A7004A47F5 /* tclEncoding.c */; };
+		F96D458D08F272BC004A47F5 /* tclEnv.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EEE08F272A7004A47F5 /* tclEnv.c */; };
+		F96D458E08F272BC004A47F5 /* tclEvent.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EEF08F272A7004A47F5 /* tclEvent.c */; };
+		F96D458F08F272BC004A47F5 /* tclExecute.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EF008F272A7004A47F5 /* tclExecute.c */; };
+		F96D459008F272BC004A47F5 /* tclFCmd.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EF108F272A7004A47F5 /* tclFCmd.c */; };
+		F96D459108F272BC004A47F5 /* tclFileName.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EF208F272A7004A47F5 /* tclFileName.c */; };
+		F96D459308F272BC004A47F5 /* tclGet.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EF408F272A7004A47F5 /* tclGet.c */; };
+		F96D459508F272BC004A47F5 /* tclHash.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EF608F272A7004A47F5 /* tclHash.c */; };
+		F96D459608F272BC004A47F5 /* tclHistory.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EF708F272A7004A47F5 /* tclHistory.c */; };
+		F96D459708F272BC004A47F5 /* tclIndexObj.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EF808F272A7004A47F5 /* tclIndexObj.c */; };
+		F96D459B08F272BC004A47F5 /* tclInterp.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EFC08F272A7004A47F5 /* tclInterp.c */; };
+		F96D459D08F272BC004A47F5 /* tclIO.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EFE08F272A7004A47F5 /* tclIO.c */; };
+		F96D459F08F272BC004A47F5 /* tclIOCmd.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0008F272A7004A47F5 /* tclIOCmd.c */; };
+		F96D45A008F272BC004A47F5 /* tclIOGT.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0108F272A7004A47F5 /* tclIOGT.c */; };
+		F96D45A108F272BC004A47F5 /* tclIORChan.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0208F272A7004A47F5 /* tclIORChan.c */; };
+		F96D45A208F272BC004A47F5 /* tclIOSock.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0308F272A7004A47F5 /* tclIOSock.c */; };
+		F96D45A308F272BC004A47F5 /* tclIOUtil.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0408F272A7004A47F5 /* tclIOUtil.c */; };
+		F96D45A408F272BC004A47F5 /* tclLink.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0508F272A7004A47F5 /* tclLink.c */; };
+		F96D45A508F272BC004A47F5 /* tclListObj.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0608F272A7004A47F5 /* tclListObj.c */; };
+		F96D45A608F272BC004A47F5 /* tclLiteral.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0708F272A7004A47F5 /* tclLiteral.c */; };
+		F96D45A708F272BC004A47F5 /* tclLoad.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0808F272A7004A47F5 /* tclLoad.c */; };
+		F96D45A908F272BC004A47F5 /* tclMain.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0A08F272A7004A47F5 /* tclMain.c */; };
+		F96D45AA08F272BC004A47F5 /* tclNamesp.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0B08F272A7004A47F5 /* tclNamesp.c */; };
+		F96D45AB08F272BC004A47F5 /* tclNotify.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0C08F272A7004A47F5 /* tclNotify.c */; };
+		F96D45AC08F272BC004A47F5 /* tclObj.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0D08F272A7004A47F5 /* tclObj.c */; };
+		F96D45AD08F272BC004A47F5 /* tclPanic.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0E08F272A7004A47F5 /* tclPanic.c */; };
+		F96D45AE08F272BC004A47F5 /* tclParse.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0F08F272A7004A47F5 /* tclParse.c */; };
+		F96D45B008F272BC004A47F5 /* tclPathObj.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1108F272A7004A47F5 /* tclPathObj.c */; };
+		F96D45B108F272BC004A47F5 /* tclPipe.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1208F272A7004A47F5 /* tclPipe.c */; };
+		F96D45B208F272BC004A47F5 /* tclPkg.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1308F272A7004A47F5 /* tclPkg.c */; };
+		F96D45B308F272BC004A47F5 /* tclPkgConfig.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1408F272A7004A47F5 /* tclPkgConfig.c */; settings = {COMPILER_FLAGS = "-DCFG_INSTALL_LIBDIR=\\\"$(LIBDIR)\\\" -DCFG_INSTALL_BINDIR=\\\"$(BINDIR)\\\" -DCFG_INSTALL_SCRDIR=\\\"$(TCL_LIBRARY)\\\" -DCFG_INSTALL_INCDIR=\\\"$(INCLUDEDIR)\\\" -DCFG_INSTALL_DOCDIR=\\\"$(MANDIR)\\\" -DCFG_RUNTIME_LIBDIR=\\\"$(LIBDIR)\\\" -DCFG_RUNTIME_BINDIR=\\\"$(BINDIR)\\\" -DCFG_RUNTIME_SCRDIR=\\\"$(TCL_LIBRARY)\\\" -DCFG_RUNTIME_INCDIR=\\\"$(INCLUDEDIR)\\\" -DCFG_RUNTIME_DOCDIR=\\\"$(MANDIR)\\\""; }; };
+		F96D45B608F272BC004A47F5 /* tclPosixStr.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1708F272A7004A47F5 /* tclPosixStr.c */; };
+		F96D45B708F272BC004A47F5 /* tclPreserve.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1808F272A7004A47F5 /* tclPreserve.c */; };
+		F96D45B808F272BC004A47F5 /* tclProc.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1908F272A7004A47F5 /* tclProc.c */; };
+		F96D45B908F272BC004A47F5 /* tclRegexp.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1A08F272A7004A47F5 /* tclRegexp.c */; };
+		F96D45BB08F272BC004A47F5 /* tclResolve.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1C08F272A7004A47F5 /* tclResolve.c */; };
+		F96D45BC08F272BC004A47F5 /* tclResult.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1D08F272A7004A47F5 /* tclResult.c */; };
+		F96D45BD08F272BC004A47F5 /* tclScan.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1E08F272A7004A47F5 /* tclScan.c */; };
+		F96D45BE08F272BC004A47F5 /* tclStringObj.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1F08F272A7004A47F5 /* tclStringObj.c */; };
+		F96D45C308F272BC004A47F5 /* tclStrToD.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F2408F272A7004A47F5 /* tclStrToD.c */; };
+		F96D45C408F272BC004A47F5 /* tclStubInit.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F2508F272A7004A47F5 /* tclStubInit.c */; };
+		F96D45C508F272BC004A47F5 /* tclStubLib.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F2608F272A7004A47F5 /* tclStubLib.c */; };
+		F96D45C608F272BC004A47F5 /* tclTest.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F2708F272A7004A47F5 /* tclTest.c */; };
+		F96D45C708F272BC004A47F5 /* tclTestObj.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F2808F272A7004A47F5 /* tclTestObj.c */; };
+		F96D45C808F272BC004A47F5 /* tclTestProcBodyObj.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F2908F272A7004A47F5 /* tclTestProcBodyObj.c */; };
+		F96D45C908F272BC004A47F5 /* tclThread.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F2A08F272A7004A47F5 /* tclThread.c */; };
+		F96D45CA08F272BC004A47F5 /* tclThreadAlloc.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F2B08F272A7004A47F5 /* tclThreadAlloc.c */; };
+		F96D45CB08F272BC004A47F5 /* tclThreadJoin.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F2C08F272A7004A47F5 /* tclThreadJoin.c */; };
+		F96D45CC08F272BC004A47F5 /* tclThreadStorage.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F2D08F272A7004A47F5 /* tclThreadStorage.c */; };
+		F96D45CD08F272BC004A47F5 /* tclThreadTest.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F2E08F272A7004A47F5 /* tclThreadTest.c */; };
+		F96D45CE08F272BC004A47F5 /* tclTimer.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F2F08F272A7004A47F5 /* tclTimer.c */; };
+		F96D45D008F272BC004A47F5 /* tclTomMathInterface.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F3108F272A7004A47F5 /* tclTomMathInterface.c */; };
+		F96D45D108F272BC004A47F5 /* tclTrace.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F3208F272A7004A47F5 /* tclTrace.c */; };
+		F96D45D308F272BC004A47F5 /* tclUtf.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F3408F272A7004A47F5 /* tclUtf.c */; };
+		F96D45D408F272BC004A47F5 /* tclUtil.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F3508F272A7004A47F5 /* tclUtil.c */; };
+		F96D45D508F272BC004A47F5 /* tclVar.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F3608F272A7004A47F5 /* tclVar.c */; };
+		F96D48E208F272C3004A47F5 /* bn_fast_s_mp_mul_digs.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D426408F272B3004A47F5 /* bn_fast_s_mp_mul_digs.c */; };
+		F96D48E408F272C3004A47F5 /* bn_fast_s_mp_sqr.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D426608F272B3004A47F5 /* bn_fast_s_mp_sqr.c */; };
+		F96D48E708F272C3004A47F5 /* bn_mp_add.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D426908F272B3004A47F5 /* bn_mp_add.c */; };
+		F96D48E808F272C3004A47F5 /* bn_mp_add_d.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D426A08F272B3004A47F5 /* bn_mp_add_d.c */; };
+		F96D48EB08F272C3004A47F5 /* bn_mp_clamp.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D426D08F272B3004A47F5 /* bn_mp_clamp.c */; };
+		F96D48EC08F272C3004A47F5 /* bn_mp_clear.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D426E08F272B3004A47F5 /* bn_mp_clear.c */; };
+		F96D48ED08F272C3004A47F5 /* bn_mp_clear_multi.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D426F08F272B3004A47F5 /* bn_mp_clear_multi.c */; };
+		F96D48EE08F272C3004A47F5 /* bn_mp_cmp.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427008F272B3004A47F5 /* bn_mp_cmp.c */; };
+		F96D48F008F272C3004A47F5 /* bn_mp_cmp_mag.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427208F272B3004A47F5 /* bn_mp_cmp_mag.c */; };
+		F96D48F208F272C3004A47F5 /* bn_mp_cnt_lsb.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427408F272B3004A47F5 /* bn_mp_cnt_lsb.c */; };
+		F96D48F208F272C3004A47F5 /* bn_mp_copy.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427408F272B3004A47F5 /* bn_mp_copy.c */; };
+		F96D48F308F272C3004A47F5 /* bn_mp_count_bits.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427508F272B3004A47F5 /* bn_mp_count_bits.c */; };
+		F96D48F408F272C3004A47F5 /* bn_mp_div.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427608F272B3004A47F5 /* bn_mp_div.c */; };
+		F96D48F508F272C3004A47F5 /* bn_mp_div_2.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427708F272B3004A47F5 /* bn_mp_div_2.c */; };
+		F96D48F608F272C3004A47F5 /* bn_mp_div_2d.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427808F272B3004A47F5 /* bn_mp_div_2d.c */; };
+		F96D48F708F272C3004A47F5 /* bn_mp_div_3.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427908F272B3004A47F5 /* bn_mp_div_3.c */; };
+		F96D48F808F272C3004A47F5 /* bn_mp_div_d.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427A08F272B3004A47F5 /* bn_mp_div_d.c */; };
+		F96D48FC08F272C3004A47F5 /* bn_mp_exch.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427E08F272B3004A47F5 /* bn_mp_exch.c */; };
+		F96D490508F272C3004A47F5 /* bn_mp_grow.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D428708F272B3004A47F5 /* bn_mp_grow.c */; };
+		F96D490608F272C3004A47F5 /* bn_mp_init.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D428808F272B3004A47F5 /* bn_mp_init.c */; };
+		F96D490708F272C3004A47F5 /* bn_mp_init_copy.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D428908F272B3004A47F5 /* bn_mp_init_copy.c */; };
+		F96D490808F272C3004A47F5 /* bn_mp_init_multi.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D428A08F272B3004A47F5 /* bn_mp_init_multi.c */; };
+		F96D490908F272C3004A47F5 /* bn_mp_init_set.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D428B08F272B3004A47F5 /* bn_mp_init_set.c */; };
+		F96D490B08F272C3004A47F5 /* bn_mp_init_size.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D428D08F272B3004A47F5 /* bn_mp_init_size.c */; };
+		F96D491008F272C3004A47F5 /* bn_mp_karatsuba_mul.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D429208F272B3004A47F5 /* bn_mp_karatsuba_mul.c */; };
+		F96D491108F272C3004A47F5 /* bn_mp_karatsuba_sqr.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D429308F272B3004A47F5 /* bn_mp_karatsuba_sqr.c */; };
+		F96D491308F272C3004A47F5 /* bn_mp_lshd.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D429508F272B3004A47F5 /* bn_mp_lshd.c */; };
+		F96D491408F272C3004A47F5 /* bn_mp_mod.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D429608F272B3004A47F5 /* bn_mp_mod.c */; };
+		F96D491508F272C3004A47F5 /* bn_mp_mod_2d.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D429708F272B3004A47F5 /* bn_mp_mod_2d.c */; };
+		F96D491A08F272C3004A47F5 /* bn_mp_mul.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D429C08F272B3004A47F5 /* bn_mp_mul.c */; };
+		F96D491B08F272C3004A47F5 /* bn_mp_mul_2.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D429D08F272B3004A47F5 /* bn_mp_mul_2.c */; };
+		F96D491C08F272C3004A47F5 /* bn_mp_mul_2d.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D429E08F272B3004A47F5 /* bn_mp_mul_2d.c */; };
+		F96D491D08F272C3004A47F5 /* bn_mp_mul_d.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D429F08F272B3004A47F5 /* bn_mp_mul_d.c */; };
+		F96D492908F272C3004A47F5 /* bn_mp_radix_size.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42AB08F272B3004A47F5 /* bn_mp_radix_size.c */; };
+		F96D492A08F272C3004A47F5 /* bn_mp_radix_smap.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42AC08F272B3004A47F5 /* bn_mp_radix_smap.c */; };
+		F96D492C08F272C3004A47F5 /* bn_mp_read_radix.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42AE08F272B3004A47F5 /* bn_mp_read_radix.c */; };
+		F96D493708F272C3004A47F5 /* bn_mp_rshd.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42B908F272B3004A47F5 /* bn_mp_rshd.c */; };
+		F96D493808F272C3004A47F5 /* bn_mp_set.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42BA08F272B3004A47F5 /* bn_mp_set.c */; };
+		F96D493C08F272C3004A47F5 /* bn_mp_sqr.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42BE08F272B3004A47F5 /* bn_mp_sqr.c */; };
+		F96D493F08F272C3004A47F5 /* bn_mp_sub.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42C108F272B3004A47F5 /* bn_mp_sub.c */; };
+		F96D494008F272C3004A47F5 /* bn_mp_sub_d.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42C208F272B3004A47F5 /* bn_mp_sub_d.c */; };
+		F96D494608F272C3004A47F5 /* bn_mp_toom_mul.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42C808F272B3004A47F5 /* bn_mp_toom_mul.c */; };
+		F96D494708F272C3004A47F5 /* bn_mp_toom_sqr.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42C908F272B3004A47F5 /* bn_mp_toom_sqr.c */; };
+		F96D494908F272C3004A47F5 /* bn_mp_toradix_n.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42CB08F272B3004A47F5 /* bn_mp_toradix_n.c */; };
+		F96D494C08F272C3004A47F5 /* bn_mp_zero.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42CE08F272B3004A47F5 /* bn_mp_zero.c */; };
+		F96D494E08F272C3004A47F5 /* bn_reverse.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42D008F272B3004A47F5 /* bn_reverse.c */; };
+		F96D494F08F272C3004A47F5 /* bn_s_mp_add.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42D108F272B3004A47F5 /* bn_s_mp_add.c */; };
+		F96D495108F272C3004A47F5 /* bn_s_mp_mul_digs.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42D308F272B3004A47F5 /* bn_s_mp_mul_digs.c */; };
+		F96D495308F272C3004A47F5 /* bn_s_mp_sqr.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42D508F272B3004A47F5 /* bn_s_mp_sqr.c */; };
+		F96D495408F272C3004A47F5 /* bn_s_mp_sub.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42D608F272B3004A47F5 /* bn_s_mp_sub.c */; };
+		F96D495508F272C3004A47F5 /* bncore.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42D708F272B3004A47F5 /* bncore.c */; };
+		F96D49A908F272C4004A47F5 /* tclMacOSXBundle.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D433908F272B5004A47F5 /* tclMacOSXBundle.c */; };
+		F96D49AD08F272C4004A47F5 /* tclMacOSXFCmd.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D433D08F272B5004A47F5 /* tclMacOSXFCmd.c */; };
+		F96D49AE08F272C4004A47F5 /* tclMacOSXNotify.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D433E08F272B5004A47F5 /* tclMacOSXNotify.c */; };
+		F96D4AC608F272C9004A47F5 /* tclLoadDyld.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D445B08F272B9004A47F5 /* tclLoadDyld.c */; settings = {COMPILER_FLAGS = "-Wno-deprecated-declarations"; }; };
+		F96D4ACA08F272C9004A47F5 /* tclUnixChan.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D445F08F272B9004A47F5 /* tclUnixChan.c */; };
+		F96D4ACB08F272C9004A47F5 /* tclUnixEvent.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D446008F272B9004A47F5 /* tclUnixEvent.c */; };
+		F96D4ACC08F272C9004A47F5 /* tclUnixFCmd.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D446108F272B9004A47F5 /* tclUnixFCmd.c */; };
+		F96D4ACD08F272C9004A47F5 /* tclUnixFile.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D446208F272B9004A47F5 /* tclUnixFile.c */; };
+		F96D4ACE08F272C9004A47F5 /* tclUnixInit.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D446308F272B9004A47F5 /* tclUnixInit.c */; settings = {COMPILER_FLAGS = "-DTCL_LIBRARY=\\\"$(TCL_LIBRARY)\\\" -DTCL_PACKAGE_PATH=\\\"$(TCL_PACKAGE_PATH)\\\""; }; };
+		F96D4ACF08F272C9004A47F5 /* tclUnixNotfy.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D446408F272B9004A47F5 /* tclUnixNotfy.c */; };
+		F96D4AD008F272C9004A47F5 /* tclUnixPipe.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D446508F272B9004A47F5 /* tclUnixPipe.c */; };
+		F96D4AD208F272CA004A47F5 /* tclUnixSock.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D446708F272B9004A47F5 /* tclUnixSock.c */; };
+		F96D4AD308F272CA004A47F5 /* tclUnixTest.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D446808F272B9004A47F5 /* tclUnixTest.c */; };
+		F96D4AD408F272CA004A47F5 /* tclUnixThrd.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D446908F272B9004A47F5 /* tclUnixThrd.c */; };
+		F96D4AD608F272CA004A47F5 /* tclUnixTime.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D446B08F272B9004A47F5 /* tclUnixTime.c */; };
+		F9E61D28090A481F002B3151 /* bn_mp_cmp_d.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427108F272B3004A47F5 /* bn_mp_cmp_d.c */; };
+		F9E61D29090A486C002B3151 /* bn_mp_neg.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42A208F272B3004A47F5 /* bn_mp_neg.c */; };
+		F9E61D2A090A4891002B3151 /* bn_mp_sqrt.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42C008F272B3004A47F5 /* bn_mp_sqrt.c */; };
+		F9E61D2B090A48A4002B3151 /* bn_mp_and.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D426C08F272B3004A47F5 /* bn_mp_and.c */; };
+		F9E61D2C090A48AC002B3151 /* bn_mp_expt_d.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427F08F272B3004A47F5 /* bn_mp_expt_d.c */; };
+		F9E61D2D090A48BB002B3151 /* bn_mp_xor.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42CD08F272B3004A47F5 /* bn_mp_xor.c */; };
+		F9E61D2E090A48BF002B3151 /* bn_mp_or.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42A308F272B3004A47F5 /* bn_mp_or.c */; };
+		F9E61D2F090A48C7002B3151 /* bn_mp_shrink.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42BC08F272B3004A47F5 /* bn_mp_shrink.c */; };
+		F9E61D30090A48E2002B3151 /* bn_mp_to_unsigned_bin_n.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42C708F272B3004A47F5 /* bn_mp_to_unsigned_bin_n.c */; };
+		F9E61D31090A48F9002B3151 /* bn_mp_to_unsigned_bin.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42C608F272B3004A47F5 /* bn_mp_to_unsigned_bin.c */; };
+		F9E61D32090A48FA002B3151 /* bn_mp_unsigned_bin_size.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42CC08F272B3004A47F5 /* bn_mp_unsigned_bin_size.c */; };
+		F9F4415E0C8BAE6F00BCCD67 /* tclDTrace.d in Sources */ = {isa = PBXBuildFile; fileRef = F9F4415D0C8BAE6F00BCCD67 /* tclDTrace.d */; };
+		F9FC77B80AB29E9100B7077D /* tclUnixCompat.c in Sources */ = {isa = PBXBuildFile; fileRef = F9FC77B70AB29E9100B7077D /* tclUnixCompat.c */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXContainerItemProxy section */
+		F97258D20A868C6F00096C78 /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */;
+			proxyType = 1;
+			remoteGlobalIDString = 8DD76FA90486AB0100D96B5E;
+			remoteInfo = tcltest;
+		};
+/* End PBXContainerItemProxy section */
+
+/* Begin PBXFileReference section */
+		8DD76FB20486AB0100D96B5E /* tcltest */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = tcltest; sourceTree = BUILT_PRODUCTS_DIR; };
+		F915432A0EF201CF0032D1E8 /* zlib.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = zlib.test; sourceTree = "<group>"; };
+		F915432D0EF201EE0032D1E8 /* zlib.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = zlib.n; sourceTree = "<group>"; };
+		F9183E640EFC80CD0030B814 /* throw.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = throw.n; sourceTree = "<group>"; };
+		F9183E650EFC80D70030B814 /* try.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = try.n; sourceTree = "<group>"; };
+		F9183E6A0EFC81560030B814 /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
+		F9183E8F0EFC817B0030B814 /* tdbc */ = {isa = PBXFileReference; lastKnownFileType = folder; path = tdbc; sourceTree = "<group>"; };
+		F91DC23C0E44C51B002CB8D1 /* nre.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = nre.test; sourceTree = "<group>"; };
+		F91E62260C1AE686006C9D96 /* Tclsh-Info.plist.in */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = "Tclsh-Info.plist.in"; sourceTree = "<group>"; };
+		F92D7F100DE777240033A13A /* tsdPerf.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tsdPerf.tcl; sourceTree = "<group>"; };
+		F93599B20DF1F75400E04F67 /* tclOO.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclOO.c; sourceTree = "<group>"; };
+		F93599B40DF1F75900E04F67 /* tclOO.decls */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tclOO.decls; sourceTree = "<group>"; };
+		F93599B50DF1F75D00E04F67 /* tclOO.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclOO.h; sourceTree = "<group>"; };
+		F93599B60DF1F76100E04F67 /* tclOOBasic.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclOOBasic.c; sourceTree = "<group>"; };
+		F93599B80DF1F76600E04F67 /* tclOOCall.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclOOCall.c; sourceTree = "<group>"; };
+		F93599BA0DF1F76A00E04F67 /* tclOODecls.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclOODecls.h; sourceTree = "<group>"; };
+		F93599BB0DF1F77000E04F67 /* tclOODefineCmds.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclOODefineCmds.c; sourceTree = "<group>"; };
+		F93599BD0DF1F77400E04F67 /* tclOOInfo.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclOOInfo.c; sourceTree = "<group>"; };
+		F93599BF0DF1F77900E04F67 /* tclOOInt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclOOInt.h; sourceTree = "<group>"; };
+		F93599C00DF1F77D00E04F67 /* tclOOIntDecls.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclOOIntDecls.h; sourceTree = "<group>"; };
+		F93599C10DF1F78300E04F67 /* tclOOMethod.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclOOMethod.c; sourceTree = "<group>"; };
+		F93599C30DF1F78800E04F67 /* tclOOStubInit.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclOOStubInit.c; sourceTree = "<group>"; };
+		F93599C50DF1F78D00E04F67 /* tclOOStubLib.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclOOStubLib.c; sourceTree = "<group>"; };
+		F93599C80DF1F81900E04F67 /* oo.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = oo.test; sourceTree = "<group>"; };
+		F93599CF0DF1F87F00E04F67 /* Class.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Class.3; sourceTree = "<group>"; };
+		F93599D00DF1F89E00E04F67 /* class.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = class.n; sourceTree = "<group>"; };
+		F93599D20DF1F8DF00E04F67 /* copy.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = copy.n; sourceTree = "<group>"; };
+		F93599D30DF1F8F500E04F67 /* define.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = define.n; sourceTree = "<group>"; };
+		F93599D40DF1F91900E04F67 /* Method.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Method.3; sourceTree = "<group>"; };
+		F93599D50DF1F93700E04F67 /* my.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = my.n; sourceTree = "<group>"; };
+		F93599D60DF1F95000E04F67 /* next.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = next.n; sourceTree = "<group>"; };
+		F93599D70DF1F96800E04F67 /* object.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = object.n; sourceTree = "<group>"; };
+		F93599D80DF1F98300E04F67 /* self.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = self.n; sourceTree = "<group>"; };
+		F946FB8B0FBE3AED00CD6495 /* itcl */ = {isa = PBXFileReference; lastKnownFileType = folder; path = itcl; sourceTree = "<group>"; };
+		F95D77E90DFD820D00A8BF6F /* tclIORTrans.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclIORTrans.c; sourceTree = "<group>"; };
+		F95FAFF90B34F1130072E431 /* macOSXLoad.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = macOSXLoad.test; sourceTree = "<group>"; };
+		F96437C90EF0D4B2003F468E /* tclZlib.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclZlib.c; sourceTree = "<group>"; };
+		F96437E60EF0D652003F468E /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = /usr/lib/libz.dylib; sourceTree = "<absolute>"; };
+		F966C07408F2820D005CB29B /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = /System/Library/Frameworks/CoreFoundation.framework; sourceTree = "<absolute>"; };
+		F96D3DFA08F272A4004A47F5 /* ChangeLog */ = {isa = PBXFileReference; explicitFileType = text; fileEncoding = 4; path = ChangeLog; sourceTree = "<group>"; };
+		F96D3DFB08F272A4004A47F5 /* changes */ = {isa = PBXFileReference; explicitFileType = text; fileEncoding = 4; path = changes; sourceTree = "<group>"; };
+		F96D3DFD08F272A4004A47F5 /* Access.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Access.3; sourceTree = "<group>"; };
+		F96D3DFE08F272A4004A47F5 /* AddErrInfo.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = AddErrInfo.3; sourceTree = "<group>"; };
+		F96D3DFF08F272A4004A47F5 /* after.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = after.n; sourceTree = "<group>"; };
+		F96D3E0008F272A4004A47F5 /* Alloc.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Alloc.3; sourceTree = "<group>"; };
+		F96D3E0108F272A4004A47F5 /* AllowExc.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = AllowExc.3; sourceTree = "<group>"; };
+		F96D3E0208F272A4004A47F5 /* append.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = append.n; sourceTree = "<group>"; };
+		F96D3E0308F272A4004A47F5 /* AppInit.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = AppInit.3; sourceTree = "<group>"; };
+		F96D3E0408F272A5004A47F5 /* array.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = array.n; sourceTree = "<group>"; };
+		F96D3E0508F272A5004A47F5 /* AssocData.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = AssocData.3; sourceTree = "<group>"; };
+		F96D3E0608F272A5004A47F5 /* Async.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Async.3; sourceTree = "<group>"; };
+		F96D3E0708F272A5004A47F5 /* BackgdErr.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = BackgdErr.3; sourceTree = "<group>"; };
+		F96D3E0808F272A5004A47F5 /* Backslash.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Backslash.3; sourceTree = "<group>"; };
+		F96D3E0908F272A5004A47F5 /* bgerror.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = bgerror.n; sourceTree = "<group>"; };
+		F96D3E0A08F272A5004A47F5 /* binary.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = binary.n; sourceTree = "<group>"; };
+		F96D3E0B08F272A5004A47F5 /* BoolObj.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = BoolObj.3; sourceTree = "<group>"; };
+		F96D3E0C08F272A5004A47F5 /* break.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = break.n; sourceTree = "<group>"; };
+		F96D3E0D08F272A5004A47F5 /* ByteArrObj.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ByteArrObj.3; sourceTree = "<group>"; };
+		F96D3E0E08F272A5004A47F5 /* CallDel.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CallDel.3; sourceTree = "<group>"; };
+		F96D3E0F08F272A5004A47F5 /* case.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = case.n; sourceTree = "<group>"; };
+		F96D3E1008F272A5004A47F5 /* catch.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = catch.n; sourceTree = "<group>"; };
+		F96D3E1108F272A5004A47F5 /* cd.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = cd.n; sourceTree = "<group>"; };
+		F96D3E1208F272A5004A47F5 /* chan.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = chan.n; sourceTree = "<group>"; };
+		F96D3E1308F272A5004A47F5 /* ChnlStack.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ChnlStack.3; sourceTree = "<group>"; };
+		F96D3E1408F272A5004A47F5 /* clock.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = clock.n; sourceTree = "<group>"; };
+		F96D3E1508F272A5004A47F5 /* close.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = close.n; sourceTree = "<group>"; };
+		F96D3E1608F272A5004A47F5 /* CmdCmplt.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CmdCmplt.3; sourceTree = "<group>"; };
+		F96D3E1708F272A5004A47F5 /* Concat.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Concat.3; sourceTree = "<group>"; };
+		F96D3E1808F272A5004A47F5 /* concat.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = concat.n; sourceTree = "<group>"; };
+		F96D3E1908F272A5004A47F5 /* continue.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = continue.n; sourceTree = "<group>"; };
+		F96D3E1A08F272A5004A47F5 /* CrtChannel.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtChannel.3; sourceTree = "<group>"; };
+		F96D3E1B08F272A5004A47F5 /* CrtChnlHdlr.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtChnlHdlr.3; sourceTree = "<group>"; };
+		F96D3E1C08F272A5004A47F5 /* CrtCloseHdlr.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtCloseHdlr.3; sourceTree = "<group>"; };
+		F96D3E1D08F272A5004A47F5 /* CrtCommand.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtCommand.3; sourceTree = "<group>"; };
+		F96D3E1E08F272A5004A47F5 /* CrtFileHdlr.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtFileHdlr.3; sourceTree = "<group>"; };
+		F96D3E1F08F272A5004A47F5 /* CrtInterp.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtInterp.3; sourceTree = "<group>"; };
+		F96D3E2008F272A5004A47F5 /* CrtMathFnc.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtMathFnc.3; sourceTree = "<group>"; };
+		F96D3E2108F272A5004A47F5 /* CrtObjCmd.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtObjCmd.3; sourceTree = "<group>"; };
+		F96D3E2208F272A5004A47F5 /* CrtSlave.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtSlave.3; sourceTree = "<group>"; };
+		F96D3E2308F272A5004A47F5 /* CrtTimerHdlr.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtTimerHdlr.3; sourceTree = "<group>"; };
+		F96D3E2408F272A5004A47F5 /* CrtTrace.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtTrace.3; sourceTree = "<group>"; };
+		F96D3E2508F272A5004A47F5 /* dde.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = dde.n; sourceTree = "<group>"; };
+		F96D3E2608F272A5004A47F5 /* DetachPids.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = DetachPids.3; sourceTree = "<group>"; };
+		F96D3E2708F272A5004A47F5 /* dict.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = dict.n; sourceTree = "<group>"; };
+		F96D3E2808F272A5004A47F5 /* DictObj.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = DictObj.3; sourceTree = "<group>"; };
+		F96D3E2908F272A5004A47F5 /* DoOneEvent.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = DoOneEvent.3; sourceTree = "<group>"; };
+		F96D3E2A08F272A5004A47F5 /* DoubleObj.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = DoubleObj.3; sourceTree = "<group>"; };
+		F96D3E2B08F272A5004A47F5 /* DoWhenIdle.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = DoWhenIdle.3; sourceTree = "<group>"; };
+		F96D3E2C08F272A5004A47F5 /* DString.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = DString.3; sourceTree = "<group>"; };
+		F96D3E2D08F272A5004A47F5 /* DumpActiveMemory.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = DumpActiveMemory.3; sourceTree = "<group>"; };
+		F96D3E2E08F272A5004A47F5 /* Encoding.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Encoding.3; sourceTree = "<group>"; };
+		F96D3E2F08F272A5004A47F5 /* encoding.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = encoding.n; sourceTree = "<group>"; };
+		F96D3E3008F272A5004A47F5 /* Ensemble.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Ensemble.3; sourceTree = "<group>"; };
+		F96D3E3108F272A5004A47F5 /* Environment.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Environment.3; sourceTree = "<group>"; };
+		F96D3E3208F272A5004A47F5 /* eof.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = eof.n; sourceTree = "<group>"; };
+		F96D3E3308F272A5004A47F5 /* error.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = error.n; sourceTree = "<group>"; };
+		F96D3E3408F272A5004A47F5 /* Eval.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Eval.3; sourceTree = "<group>"; };
+		F96D3E3508F272A5004A47F5 /* eval.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = eval.n; sourceTree = "<group>"; };
+		F96D3E3608F272A5004A47F5 /* exec.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = exec.n; sourceTree = "<group>"; };
+		F96D3E3708F272A5004A47F5 /* Exit.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Exit.3; sourceTree = "<group>"; };
+		F96D3E3808F272A5004A47F5 /* exit.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = exit.n; sourceTree = "<group>"; };
+		F96D3E3908F272A5004A47F5 /* expr.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = expr.n; sourceTree = "<group>"; };
+		F96D3E3A08F272A5004A47F5 /* ExprLong.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ExprLong.3; sourceTree = "<group>"; };
+		F96D3E3B08F272A5004A47F5 /* ExprLongObj.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ExprLongObj.3; sourceTree = "<group>"; };
+		F96D3E3C08F272A5004A47F5 /* fblocked.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = fblocked.n; sourceTree = "<group>"; };
+		F96D3E3D08F272A5004A47F5 /* fconfigure.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = fconfigure.n; sourceTree = "<group>"; };
+		F96D3E3E08F272A5004A47F5 /* fcopy.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = fcopy.n; sourceTree = "<group>"; };
+		F96D3E3F08F272A5004A47F5 /* file.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = file.n; sourceTree = "<group>"; };
+		F96D3E4008F272A5004A47F5 /* fileevent.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = fileevent.n; sourceTree = "<group>"; };
+		F96D3E4108F272A5004A47F5 /* filename.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = filename.n; sourceTree = "<group>"; };
+		F96D3E4208F272A5004A47F5 /* FileSystem.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = FileSystem.3; sourceTree = "<group>"; };
+		F96D3E4308F272A5004A47F5 /* FindExec.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = FindExec.3; sourceTree = "<group>"; };
+		F96D3E4408F272A5004A47F5 /* flush.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = flush.n; sourceTree = "<group>"; };
+		F96D3E4508F272A5004A47F5 /* for.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = for.n; sourceTree = "<group>"; };
+		F96D3E4608F272A5004A47F5 /* foreach.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = foreach.n; sourceTree = "<group>"; };
+		F96D3E4708F272A5004A47F5 /* format.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = format.n; sourceTree = "<group>"; };
+		F96D3E4808F272A5004A47F5 /* GetCwd.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetCwd.3; sourceTree = "<group>"; };
+		F96D3E4908F272A5004A47F5 /* GetHostName.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetHostName.3; sourceTree = "<group>"; };
+		F96D3E4A08F272A5004A47F5 /* GetIndex.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetIndex.3; sourceTree = "<group>"; };
+		F96D3E4B08F272A5004A47F5 /* GetInt.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetInt.3; sourceTree = "<group>"; };
+		F96D3E4C08F272A5004A47F5 /* GetOpnFl.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetOpnFl.3; sourceTree = "<group>"; };
+		F96D3E4D08F272A5004A47F5 /* gets.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = gets.n; sourceTree = "<group>"; };
+		F96D3E4E08F272A5004A47F5 /* GetStdChan.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetStdChan.3; sourceTree = "<group>"; };
+		F96D3E4F08F272A5004A47F5 /* GetTime.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetTime.3; sourceTree = "<group>"; };
+		F96D3E5008F272A5004A47F5 /* GetVersion.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetVersion.3; sourceTree = "<group>"; };
+		F96D3E5108F272A5004A47F5 /* glob.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = glob.n; sourceTree = "<group>"; };
+		F96D3E5208F272A6004A47F5 /* global.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = global.n; sourceTree = "<group>"; };
+		F96D3E5308F272A6004A47F5 /* Hash.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Hash.3; sourceTree = "<group>"; };
+		F96D3E5408F272A6004A47F5 /* history.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = history.n; sourceTree = "<group>"; };
+		F96D3E5508F272A6004A47F5 /* http.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = http.n; sourceTree = "<group>"; };
+		F96D3E5608F272A6004A47F5 /* if.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = if.n; sourceTree = "<group>"; };
+		F96D3E5708F272A6004A47F5 /* incr.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = incr.n; sourceTree = "<group>"; };
+		F96D3E5808F272A6004A47F5 /* info.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = info.n; sourceTree = "<group>"; };
+		F96D3E5908F272A6004A47F5 /* Init.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Init.3; sourceTree = "<group>"; };
+		F96D3E5A08F272A6004A47F5 /* InitStubs.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = InitStubs.3; sourceTree = "<group>"; };
+		F96D3E5B08F272A6004A47F5 /* Interp.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Interp.3; sourceTree = "<group>"; };
+		F96D3E5C08F272A6004A47F5 /* interp.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = interp.n; sourceTree = "<group>"; };
+		F96D3E5D08F272A6004A47F5 /* IntObj.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = IntObj.3; sourceTree = "<group>"; };
+		F96D3E5E08F272A6004A47F5 /* join.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = join.n; sourceTree = "<group>"; };
+		F96D3E5F08F272A6004A47F5 /* lappend.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = lappend.n; sourceTree = "<group>"; };
+		F96D3E6008F272A6004A47F5 /* lassign.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = lassign.n; sourceTree = "<group>"; };
+		F96D3E6108F272A6004A47F5 /* library.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = library.n; sourceTree = "<group>"; };
+		F96D3E6208F272A6004A47F5 /* Limit.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Limit.3; sourceTree = "<group>"; };
+		F96D3E6308F272A6004A47F5 /* lindex.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = lindex.n; sourceTree = "<group>"; };
+		F96D3E6408F272A6004A47F5 /* LinkVar.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = LinkVar.3; sourceTree = "<group>"; };
+		F96D3E6508F272A6004A47F5 /* linsert.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = linsert.n; sourceTree = "<group>"; };
+		F96D3E6608F272A6004A47F5 /* list.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = list.n; sourceTree = "<group>"; };
+		F96D3E6708F272A6004A47F5 /* ListObj.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ListObj.3; sourceTree = "<group>"; };
+		F96D3E6808F272A6004A47F5 /* llength.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = llength.n; sourceTree = "<group>"; };
+		F96D3E6908F272A6004A47F5 /* load.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = load.n; sourceTree = "<group>"; };
+		F96D3E6A08F272A6004A47F5 /* lrange.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = lrange.n; sourceTree = "<group>"; };
+		F96D3E6B08F272A6004A47F5 /* lrepeat.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = lrepeat.n; sourceTree = "<group>"; };
+		F96D3E6C08F272A6004A47F5 /* lreplace.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = lreplace.n; sourceTree = "<group>"; };
+		F96D3E6D08F272A6004A47F5 /* lsearch.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = lsearch.n; sourceTree = "<group>"; };
+		F96D3E6E08F272A6004A47F5 /* lset.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = lset.n; sourceTree = "<group>"; };
+		F96D3E6F08F272A6004A47F5 /* lsort.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = lsort.n; sourceTree = "<group>"; };
+		F96D3E7008F272A6004A47F5 /* man.macros */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = man.macros; sourceTree = "<group>"; };
+		F96D3E7108F272A6004A47F5 /* mathfunc.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = mathfunc.n; sourceTree = "<group>"; };
+		F96D3E7208F272A6004A47F5 /* memory.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = memory.n; sourceTree = "<group>"; };
+		F96D3E7308F272A6004A47F5 /* msgcat.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = msgcat.n; sourceTree = "<group>"; };
+		F96D3E7408F272A6004A47F5 /* Namespace.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Namespace.3; sourceTree = "<group>"; };
+		F96D3E7508F272A6004A47F5 /* namespace.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = namespace.n; sourceTree = "<group>"; };
+		F96D3E7608F272A6004A47F5 /* Notifier.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Notifier.3; sourceTree = "<group>"; };
+		F96D3E7708F272A6004A47F5 /* Object.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Object.3; sourceTree = "<group>"; };
+		F96D3E7808F272A6004A47F5 /* ObjectType.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ObjectType.3; sourceTree = "<group>"; };
+		F96D3E7908F272A6004A47F5 /* open.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = open.n; sourceTree = "<group>"; };
+		F96D3E7A08F272A6004A47F5 /* OpenFileChnl.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = OpenFileChnl.3; sourceTree = "<group>"; };
+		F96D3E7B08F272A6004A47F5 /* OpenTcp.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = OpenTcp.3; sourceTree = "<group>"; };
+		F96D3E7C08F272A6004A47F5 /* package.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = package.n; sourceTree = "<group>"; };
+		F96D3E7D08F272A6004A47F5 /* packagens.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = packagens.n; sourceTree = "<group>"; };
+		F96D3E7E08F272A6004A47F5 /* Panic.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Panic.3; sourceTree = "<group>"; };
+		F96D3E7F08F272A6004A47F5 /* ParseCmd.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ParseCmd.3; sourceTree = "<group>"; };
+		F96D3E8008F272A6004A47F5 /* pid.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = pid.n; sourceTree = "<group>"; };
+		F96D3E8108F272A6004A47F5 /* pkgMkIndex.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = pkgMkIndex.n; sourceTree = "<group>"; };
+		F96D3E8208F272A6004A47F5 /* PkgRequire.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = PkgRequire.3; sourceTree = "<group>"; };
+		F96D3E8308F272A6004A47F5 /* Preserve.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Preserve.3; sourceTree = "<group>"; };
+		F96D3E8408F272A6004A47F5 /* PrintDbl.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = PrintDbl.3; sourceTree = "<group>"; };
+		F96D3E8508F272A6004A47F5 /* proc.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = proc.n; sourceTree = "<group>"; };
+		F96D3E8608F272A6004A47F5 /* puts.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = puts.n; sourceTree = "<group>"; };
+		F96D3E8708F272A6004A47F5 /* pwd.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = pwd.n; sourceTree = "<group>"; };
+		F96D3E8808F272A6004A47F5 /* re_syntax.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = re_syntax.n; sourceTree = "<group>"; };
+		F96D3E8908F272A6004A47F5 /* read.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = read.n; sourceTree = "<group>"; };
+		F96D3E8A08F272A6004A47F5 /* RecEvalObj.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = RecEvalObj.3; sourceTree = "<group>"; };
+		F96D3E8B08F272A6004A47F5 /* RecordEval.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = RecordEval.3; sourceTree = "<group>"; };
+		F96D3E8C08F272A6004A47F5 /* RegConfig.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = RegConfig.3; sourceTree = "<group>"; };
+		F96D3E8D08F272A6004A47F5 /* RegExp.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = RegExp.3; sourceTree = "<group>"; };
+		F96D3E8E08F272A6004A47F5 /* regexp.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = regexp.n; sourceTree = "<group>"; };
+		F96D3E8F08F272A6004A47F5 /* registry.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = registry.n; sourceTree = "<group>"; };
+		F96D3E9008F272A6004A47F5 /* regsub.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = regsub.n; sourceTree = "<group>"; };
+		F96D3E9108F272A6004A47F5 /* rename.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = rename.n; sourceTree = "<group>"; };
+		F96D3E9208F272A6004A47F5 /* return.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = return.n; sourceTree = "<group>"; };
+		F96D3E9308F272A6004A47F5 /* safe.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = safe.n; sourceTree = "<group>"; };
+		F96D3E9408F272A6004A47F5 /* SaveResult.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SaveResult.3; sourceTree = "<group>"; };
+		F96D3E9508F272A6004A47F5 /* scan.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = scan.n; sourceTree = "<group>"; };
+		F96D3E9608F272A6004A47F5 /* seek.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = seek.n; sourceTree = "<group>"; };
+		F96D3E9708F272A6004A47F5 /* set.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = set.n; sourceTree = "<group>"; };
+		F96D3E9808F272A6004A47F5 /* SetChanErr.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SetChanErr.3; sourceTree = "<group>"; };
+		F96D3E9908F272A6004A47F5 /* SetErrno.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SetErrno.3; sourceTree = "<group>"; };
+		F96D3E9A08F272A6004A47F5 /* SetRecLmt.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SetRecLmt.3; sourceTree = "<group>"; };
+		F96D3E9B08F272A7004A47F5 /* SetResult.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SetResult.3; sourceTree = "<group>"; };
+		F96D3E9C08F272A7004A47F5 /* SetVar.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SetVar.3; sourceTree = "<group>"; };
+		F96D3E9D08F272A7004A47F5 /* Signal.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Signal.3; sourceTree = "<group>"; };
+		F96D3E9E08F272A7004A47F5 /* Sleep.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Sleep.3; sourceTree = "<group>"; };
+		F96D3E9F08F272A7004A47F5 /* socket.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = socket.n; sourceTree = "<group>"; };
+		F96D3EA008F272A7004A47F5 /* source.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = source.n; sourceTree = "<group>"; };
+		F96D3EA108F272A7004A47F5 /* SourceRCFile.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SourceRCFile.3; sourceTree = "<group>"; };
+		F96D3EA208F272A7004A47F5 /* split.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = split.n; sourceTree = "<group>"; };
+		F96D3EA308F272A7004A47F5 /* SplitList.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SplitList.3; sourceTree = "<group>"; };
+		F96D3EA408F272A7004A47F5 /* SplitPath.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SplitPath.3; sourceTree = "<group>"; };
+		F96D3EA508F272A7004A47F5 /* StaticPkg.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = StaticPkg.3; sourceTree = "<group>"; };
+		F96D3EA608F272A7004A47F5 /* StdChannels.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = StdChannels.3; sourceTree = "<group>"; };
+		F96D3EA708F272A7004A47F5 /* string.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = string.n; sourceTree = "<group>"; };
+		F96D3EA808F272A7004A47F5 /* StringObj.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = StringObj.3; sourceTree = "<group>"; };
+		F96D3EA908F272A7004A47F5 /* StrMatch.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = StrMatch.3; sourceTree = "<group>"; };
+		F96D3EAA08F272A7004A47F5 /* subst.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = subst.n; sourceTree = "<group>"; };
+		F96D3EAB08F272A7004A47F5 /* SubstObj.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SubstObj.3; sourceTree = "<group>"; };
+		F96D3EAC08F272A7004A47F5 /* switch.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = switch.n; sourceTree = "<group>"; };
+		F96D3EAD08F272A7004A47F5 /* Tcl.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Tcl.n; sourceTree = "<group>"; };
+		F96D3EAE08F272A7004A47F5 /* Tcl_Main.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Tcl_Main.3; sourceTree = "<group>"; };
+		F96D3EAF08F272A7004A47F5 /* TCL_MEM_DEBUG.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = TCL_MEM_DEBUG.3; sourceTree = "<group>"; };
+		F96D3EB008F272A7004A47F5 /* tclsh.1 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = tclsh.1; sourceTree = "<group>"; };
+		F96D3EB108F272A7004A47F5 /* tcltest.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = tcltest.n; sourceTree = "<group>"; };
+		F96D3EB208F272A7004A47F5 /* tclvars.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = tclvars.n; sourceTree = "<group>"; };
+		F96D3EB308F272A7004A47F5 /* tell.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = tell.n; sourceTree = "<group>"; };
+		F96D3EB408F272A7004A47F5 /* Thread.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Thread.3; sourceTree = "<group>"; };
+		F96D3EB508F272A7004A47F5 /* time.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = time.n; sourceTree = "<group>"; };
+		F96D3EB608F272A7004A47F5 /* tm.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = tm.n; sourceTree = "<group>"; };
+		F96D3EB708F272A7004A47F5 /* ToUpper.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ToUpper.3; sourceTree = "<group>"; };
+		F96D3EB808F272A7004A47F5 /* trace.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = trace.n; sourceTree = "<group>"; };
+		F96D3EB908F272A7004A47F5 /* TraceCmd.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = TraceCmd.3; sourceTree = "<group>"; };
+		F96D3EBA08F272A7004A47F5 /* TraceVar.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = TraceVar.3; sourceTree = "<group>"; };
+		F96D3EBB08F272A7004A47F5 /* Translate.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Translate.3; sourceTree = "<group>"; };
+		F96D3EBC08F272A7004A47F5 /* UniCharIsAlpha.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = UniCharIsAlpha.3; sourceTree = "<group>"; };
+		F96D3EBD08F272A7004A47F5 /* unknown.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = unknown.n; sourceTree = "<group>"; };
+		F96D3EBE08F272A7004A47F5 /* unload.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = unload.n; sourceTree = "<group>"; };
+		F96D3EBF08F272A7004A47F5 /* unset.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = unset.n; sourceTree = "<group>"; };
+		F96D3EC008F272A7004A47F5 /* update.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = update.n; sourceTree = "<group>"; };
+		F96D3EC108F272A7004A47F5 /* uplevel.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = uplevel.n; sourceTree = "<group>"; };
+		F96D3EC208F272A7004A47F5 /* UpVar.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = UpVar.3; sourceTree = "<group>"; };
+		F96D3EC308F272A7004A47F5 /* upvar.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = upvar.n; sourceTree = "<group>"; };
+		F96D3EC408F272A7004A47F5 /* Utf.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Utf.3; sourceTree = "<group>"; };
+		F96D3EC508F272A7004A47F5 /* variable.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = variable.n; sourceTree = "<group>"; };
+		F96D3EC608F272A7004A47F5 /* vwait.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = vwait.n; sourceTree = "<group>"; };
+		F96D3EC708F272A7004A47F5 /* while.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = while.n; sourceTree = "<group>"; };
+		F96D3EC808F272A7004A47F5 /* WrongNumArgs.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = WrongNumArgs.3; sourceTree = "<group>"; };
+		F96D3ECA08F272A7004A47F5 /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
+		F96D3ECB08F272A7004A47F5 /* regc_color.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = regc_color.c; sourceTree = "<group>"; };
+		F96D3ECC08F272A7004A47F5 /* regc_cvec.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = regc_cvec.c; sourceTree = "<group>"; };
+		F96D3ECD08F272A7004A47F5 /* regc_lex.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = regc_lex.c; sourceTree = "<group>"; };
+		F96D3ECE08F272A7004A47F5 /* regc_locale.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = regc_locale.c; sourceTree = "<group>"; };
+		F96D3ECF08F272A7004A47F5 /* regc_nfa.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = regc_nfa.c; sourceTree = "<group>"; };
+		F96D3ED008F272A7004A47F5 /* regcomp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = regcomp.c; sourceTree = "<group>"; };
+		F96D3ED108F272A7004A47F5 /* regcustom.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = regcustom.h; sourceTree = "<group>"; };
+		F96D3ED208F272A7004A47F5 /* rege_dfa.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = rege_dfa.c; sourceTree = "<group>"; };
+		F96D3ED308F272A7004A47F5 /* regerror.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = regerror.c; sourceTree = "<group>"; };
+		F96D3ED408F272A7004A47F5 /* regerrs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = regerrs.h; sourceTree = "<group>"; };
+		F96D3ED508F272A7004A47F5 /* regex.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = regex.h; sourceTree = "<group>"; };
+		F96D3ED608F272A7004A47F5 /* regexec.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = regexec.c; sourceTree = "<group>"; };
+		F96D3ED708F272A7004A47F5 /* regfree.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = regfree.c; sourceTree = "<group>"; };
+		F96D3ED808F272A7004A47F5 /* regfronts.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = regfronts.c; sourceTree = "<group>"; };
+		F96D3ED908F272A7004A47F5 /* regguts.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = regguts.h; sourceTree = "<group>"; };
+		F96D3EDA08F272A7004A47F5 /* tcl.decls */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tcl.decls; sourceTree = "<group>"; };
+		F96D3EDB08F272A7004A47F5 /* tcl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tcl.h; sourceTree = "<group>"; };
+		F96D3EDC08F272A7004A47F5 /* tclAlloc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclAlloc.c; sourceTree = "<group>"; };
+		F96D3EDD08F272A7004A47F5 /* tclAsync.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclAsync.c; sourceTree = "<group>"; };
+		F96D3EDE08F272A7004A47F5 /* tclBasic.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclBasic.c; sourceTree = "<group>"; };
+		F96D3EDF08F272A7004A47F5 /* tclBinary.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclBinary.c; sourceTree = "<group>"; };
+		F96D3EE008F272A7004A47F5 /* tclCkalloc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclCkalloc.c; sourceTree = "<group>"; };
+		F96D3EE108F272A7004A47F5 /* tclClock.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclClock.c; sourceTree = "<group>"; };
+		F96D3EE208F272A7004A47F5 /* tclCmdAH.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclCmdAH.c; sourceTree = "<group>"; };
+		F96D3EE308F272A7004A47F5 /* tclCmdIL.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclCmdIL.c; sourceTree = "<group>"; };
+		F96D3EE408F272A7004A47F5 /* tclCmdMZ.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclCmdMZ.c; sourceTree = "<group>"; };
+		F96D3EE508F272A7004A47F5 /* tclCompCmds.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclCompCmds.c; sourceTree = "<group>"; };
+		F96D3EE608F272A7004A47F5 /* tclCompExpr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclCompExpr.c; sourceTree = "<group>"; };
+		F96D3EE708F272A7004A47F5 /* tclCompile.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclCompile.c; sourceTree = "<group>"; };
+		F96D3EE808F272A7004A47F5 /* tclCompile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclCompile.h; sourceTree = "<group>"; };
+		F96D3EE908F272A7004A47F5 /* tclConfig.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclConfig.c; sourceTree = "<group>"; };
+		F96D3EEA08F272A7004A47F5 /* tclDate.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclDate.c; sourceTree = "<group>"; };
+		F96D3EEB08F272A7004A47F5 /* tclDecls.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclDecls.h; sourceTree = "<group>"; };
+		F96D3EEC08F272A7004A47F5 /* tclDictObj.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclDictObj.c; sourceTree = "<group>"; };
+		F96D3EED08F272A7004A47F5 /* tclEncoding.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclEncoding.c; sourceTree = "<group>"; };
+		F96D3EEE08F272A7004A47F5 /* tclEnv.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclEnv.c; sourceTree = "<group>"; };
+		F96D3EEF08F272A7004A47F5 /* tclEvent.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclEvent.c; sourceTree = "<group>"; };
+		F96D3EF008F272A7004A47F5 /* tclExecute.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclExecute.c; sourceTree = "<group>"; };
+		F96D3EF108F272A7004A47F5 /* tclFCmd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclFCmd.c; sourceTree = "<group>"; };
+		F96D3EF208F272A7004A47F5 /* tclFileName.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclFileName.c; sourceTree = "<group>"; };
+		F96D3EF308F272A7004A47F5 /* tclFileSystem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclFileSystem.h; sourceTree = "<group>"; };
+		F96D3EF408F272A7004A47F5 /* tclGet.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclGet.c; sourceTree = "<group>"; };
+		F96D3EF508F272A7004A47F5 /* tclGetDate.y */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.yacc; path = tclGetDate.y; sourceTree = "<group>"; };
+		F96D3EF608F272A7004A47F5 /* tclHash.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclHash.c; sourceTree = "<group>"; };
+		F96D3EF708F272A7004A47F5 /* tclHistory.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclHistory.c; sourceTree = "<group>"; };
+		F96D3EF808F272A7004A47F5 /* tclIndexObj.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclIndexObj.c; sourceTree = "<group>"; };
+		F96D3EF908F272A7004A47F5 /* tclInt.decls */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tclInt.decls; sourceTree = "<group>"; };
+		F96D3EFA08F272A7004A47F5 /* tclInt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclInt.h; sourceTree = "<group>"; };
+		F96D3EFB08F272A7004A47F5 /* tclIntDecls.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclIntDecls.h; sourceTree = "<group>"; };
+		F96D3EFC08F272A7004A47F5 /* tclInterp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclInterp.c; sourceTree = "<group>"; };
+		F96D3EFD08F272A7004A47F5 /* tclIntPlatDecls.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclIntPlatDecls.h; sourceTree = "<group>"; };
+		F96D3EFE08F272A7004A47F5 /* tclIO.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclIO.c; sourceTree = "<group>"; };
+		F96D3EFF08F272A7004A47F5 /* tclIO.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclIO.h; sourceTree = "<group>"; };
+		F96D3F0008F272A7004A47F5 /* tclIOCmd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclIOCmd.c; sourceTree = "<group>"; };
+		F96D3F0108F272A7004A47F5 /* tclIOGT.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclIOGT.c; sourceTree = "<group>"; };
+		F96D3F0208F272A7004A47F5 /* tclIORChan.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclIORChan.c; sourceTree = "<group>"; };
+		F96D3F0308F272A7004A47F5 /* tclIOSock.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclIOSock.c; sourceTree = "<group>"; };
+		F96D3F0408F272A7004A47F5 /* tclIOUtil.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclIOUtil.c; sourceTree = "<group>"; };
+		F96D3F0508F272A7004A47F5 /* tclLink.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclLink.c; sourceTree = "<group>"; };
+		F96D3F0608F272A7004A47F5 /* tclListObj.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclListObj.c; sourceTree = "<group>"; };
+		F96D3F0708F272A7004A47F5 /* tclLiteral.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclLiteral.c; sourceTree = "<group>"; };
+		F96D3F0808F272A7004A47F5 /* tclLoad.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclLoad.c; sourceTree = "<group>"; };
+		F96D3F0908F272A7004A47F5 /* tclLoadNone.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclLoadNone.c; sourceTree = "<group>"; };
+		F96D3F0A08F272A7004A47F5 /* tclMain.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclMain.c; sourceTree = "<group>"; };
+		F96D3F0B08F272A7004A47F5 /* tclNamesp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclNamesp.c; sourceTree = "<group>"; };
+		F96D3F0C08F272A7004A47F5 /* tclNotify.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclNotify.c; sourceTree = "<group>"; };
+		F96D3F0D08F272A7004A47F5 /* tclObj.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclObj.c; sourceTree = "<group>"; };
+		F96D3F0E08F272A7004A47F5 /* tclPanic.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclPanic.c; sourceTree = "<group>"; };
+		F96D3F0F08F272A7004A47F5 /* tclParse.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclParse.c; sourceTree = "<group>"; };
+		F96D3F1108F272A7004A47F5 /* tclPathObj.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclPathObj.c; sourceTree = "<group>"; };
+		F96D3F1208F272A7004A47F5 /* tclPipe.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclPipe.c; sourceTree = "<group>"; };
+		F96D3F1308F272A7004A47F5 /* tclPkg.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclPkg.c; sourceTree = "<group>"; };
+		F96D3F1408F272A7004A47F5 /* tclPkgConfig.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclPkgConfig.c; sourceTree = "<group>"; };
+		F96D3F1508F272A7004A47F5 /* tclPlatDecls.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclPlatDecls.h; sourceTree = "<group>"; };
+		F96D3F1608F272A7004A47F5 /* tclPort.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclPort.h; sourceTree = "<group>"; };
+		F96D3F1708F272A7004A47F5 /* tclPosixStr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclPosixStr.c; sourceTree = "<group>"; };
+		F96D3F1808F272A7004A47F5 /* tclPreserve.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclPreserve.c; sourceTree = "<group>"; };
+		F96D3F1908F272A7004A47F5 /* tclProc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclProc.c; sourceTree = "<group>"; };
+		F96D3F1A08F272A7004A47F5 /* tclRegexp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclRegexp.c; sourceTree = "<group>"; };
+		F96D3F1B08F272A7004A47F5 /* tclRegexp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclRegexp.h; sourceTree = "<group>"; };
+		F96D3F1C08F272A7004A47F5 /* tclResolve.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclResolve.c; sourceTree = "<group>"; };
+		F96D3F1D08F272A7004A47F5 /* tclResult.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclResult.c; sourceTree = "<group>"; };
+		F96D3F1E08F272A7004A47F5 /* tclScan.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclScan.c; sourceTree = "<group>"; };
+		F96D3F1F08F272A7004A47F5 /* tclStringObj.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclStringObj.c; sourceTree = "<group>"; };
+		F96D3F2408F272A7004A47F5 /* tclStrToD.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclStrToD.c; sourceTree = "<group>"; };
+		F96D3F2508F272A7004A47F5 /* tclStubInit.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclStubInit.c; sourceTree = "<group>"; };
+		F96D3F2608F272A7004A47F5 /* tclStubLib.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclStubLib.c; sourceTree = "<group>"; };
+		F96D3F2708F272A7004A47F5 /* tclTest.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclTest.c; sourceTree = "<group>"; };
+		F96D3F2808F272A7004A47F5 /* tclTestObj.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclTestObj.c; sourceTree = "<group>"; };
+		F96D3F2908F272A7004A47F5 /* tclTestProcBodyObj.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclTestProcBodyObj.c; sourceTree = "<group>"; };
+		F96D3F2A08F272A7004A47F5 /* tclThread.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclThread.c; sourceTree = "<group>"; };
+		F96D3F2B08F272A7004A47F5 /* tclThreadAlloc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclThreadAlloc.c; sourceTree = "<group>"; };
+		F96D3F2C08F272A7004A47F5 /* tclThreadJoin.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclThreadJoin.c; sourceTree = "<group>"; };
+		F96D3F2D08F272A7004A47F5 /* tclThreadStorage.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclThreadStorage.c; sourceTree = "<group>"; };
+		F96D3F2E08F272A7004A47F5 /* tclThreadTest.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclThreadTest.c; sourceTree = "<group>"; };
+		F96D3F2F08F272A7004A47F5 /* tclTimer.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclTimer.c; sourceTree = "<group>"; };
+		F96D3F3008F272A7004A47F5 /* tclTomMath.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclTomMath.h; sourceTree = "<group>"; };
+		F96D3F3108F272A7004A47F5 /* tclTomMathInterface.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclTomMathInterface.c; sourceTree = "<group>"; };
+		F96D3F3208F272A7004A47F5 /* tclTrace.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclTrace.c; sourceTree = "<group>"; };
+		F96D3F3308F272A7004A47F5 /* tclUniData.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUniData.c; sourceTree = "<group>"; };
+		F96D3F3408F272A7004A47F5 /* tclUtf.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUtf.c; sourceTree = "<group>"; };
+		F96D3F3508F272A7004A47F5 /* tclUtil.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUtil.c; sourceTree = "<group>"; };
+		F96D3F3608F272A7004A47F5 /* tclVar.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclVar.c; sourceTree = "<group>"; };
+		F96D3F3708F272A7004A47F5 /* tommath.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tommath.h; sourceTree = "<group>"; };
+		F96D3F3908F272A8004A47F5 /* auto.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = auto.tcl; sourceTree = "<group>"; };
+		F96D3F3A08F272A8004A47F5 /* clock.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = clock.tcl; sourceTree = "<group>"; };
+		F96D3F3C08F272A8004A47F5 /* pkgIndex.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = pkgIndex.tcl; sourceTree = "<group>"; };
+		F96D3F8C08F272A8004A47F5 /* history.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = history.tcl; sourceTree = "<group>"; };
+		F96D3F8E08F272A8004A47F5 /* http.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = http.tcl; sourceTree = "<group>"; };
+		F96D3F8F08F272A8004A47F5 /* pkgIndex.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = pkgIndex.tcl; sourceTree = "<group>"; };
+		F96D3F9108F272A8004A47F5 /* http.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = http.tcl; sourceTree = "<group>"; };
+		F96D3F9208F272A8004A47F5 /* pkgIndex.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = pkgIndex.tcl; sourceTree = "<group>"; };
+		F96D3F9308F272A8004A47F5 /* init.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = init.tcl; sourceTree = "<group>"; };
+		F96D3F9508F272A8004A47F5 /* msgcat.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = msgcat.tcl; sourceTree = "<group>"; };
+		F96D3F9608F272A8004A47F5 /* pkgIndex.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = pkgIndex.tcl; sourceTree = "<group>"; };
+		F96D401808F272AA004A47F5 /* optparse.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = optparse.tcl; sourceTree = "<group>"; };
+		F96D401908F272AA004A47F5 /* pkgIndex.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = pkgIndex.tcl; sourceTree = "<group>"; };
+		F96D401A08F272AA004A47F5 /* package.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = package.tcl; sourceTree = "<group>"; };
+		F96D401B08F272AA004A47F5 /* parray.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = parray.tcl; sourceTree = "<group>"; };
+		F96D401D08F272AA004A47F5 /* pkgIndex.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = pkgIndex.tcl; sourceTree = "<group>"; };
+		F96D401E08F272AA004A47F5 /* safe.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = safe.tcl; sourceTree = "<group>"; };
+		F96D401F08F272AA004A47F5 /* tclIndex */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tclIndex; sourceTree = "<group>"; };
+		F96D402108F272AA004A47F5 /* pkgIndex.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = pkgIndex.tcl; sourceTree = "<group>"; };
+		F96D402208F272AA004A47F5 /* tcltest.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tcltest.tcl; sourceTree = "<group>"; };
+		F96D402308F272AA004A47F5 /* tm.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tm.tcl; sourceTree = "<group>"; };
+		F96D425B08F272B2004A47F5 /* word.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = word.tcl; sourceTree = "<group>"; };
+		F96D426408F272B3004A47F5 /* bn_fast_s_mp_mul_digs.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_fast_s_mp_mul_digs.c; sourceTree = "<group>"; };
+		F96D426608F272B3004A47F5 /* bn_fast_s_mp_sqr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_fast_s_mp_sqr.c; sourceTree = "<group>"; };
+		F96D426908F272B3004A47F5 /* bn_mp_add.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_add.c; sourceTree = "<group>"; };
+		F96D426A08F272B3004A47F5 /* bn_mp_add_d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_add_d.c; sourceTree = "<group>"; };
+		F96D426C08F272B3004A47F5 /* bn_mp_and.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_and.c; sourceTree = "<group>"; };
+		F96D426D08F272B3004A47F5 /* bn_mp_clamp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_clamp.c; sourceTree = "<group>"; };
+		F96D426E08F272B3004A47F5 /* bn_mp_clear.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_clear.c; sourceTree = "<group>"; };
+		F96D426F08F272B3004A47F5 /* bn_mp_clear_multi.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_clear_multi.c; sourceTree = "<group>"; };
+		F96D427008F272B3004A47F5 /* bn_mp_cmp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_cmp.c; sourceTree = "<group>"; };
+		F96D427108F272B3004A47F5 /* bn_mp_cmp_d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_cmp_d.c; sourceTree = "<group>"; };
+		F96D427208F272B3004A47F5 /* bn_mp_cmp_mag.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_cmp_mag.c; sourceTree = "<group>"; };
+		F96D427408F272B3004A47F5 /* bn_mp_copy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_copy.c; sourceTree = "<group>"; };
+		F96D427508F272B3004A47F5 /* bn_mp_count_bits.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_count_bits.c; sourceTree = "<group>"; };
+		F96D427608F272B3004A47F5 /* bn_mp_div.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_div.c; sourceTree = "<group>"; };
+		F96D427708F272B3004A47F5 /* bn_mp_div_2.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_div_2.c; sourceTree = "<group>"; };
+		F96D427808F272B3004A47F5 /* bn_mp_div_2d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_div_2d.c; sourceTree = "<group>"; };
+		F96D427908F272B3004A47F5 /* bn_mp_div_3.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_div_3.c; sourceTree = "<group>"; };
+		F96D427A08F272B3004A47F5 /* bn_mp_div_d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_div_d.c; sourceTree = "<group>"; };
+		F96D427E08F272B3004A47F5 /* bn_mp_exch.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_exch.c; sourceTree = "<group>"; };
+		F96D427F08F272B3004A47F5 /* bn_mp_expt_d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_expt_d.c; sourceTree = "<group>"; };
+		F96D428708F272B3004A47F5 /* bn_mp_grow.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_grow.c; sourceTree = "<group>"; };
+		F96D428808F272B3004A47F5 /* bn_mp_init.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_init.c; sourceTree = "<group>"; };
+		F96D428908F272B3004A47F5 /* bn_mp_init_copy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_init_copy.c; sourceTree = "<group>"; };
+		F96D428A08F272B3004A47F5 /* bn_mp_init_multi.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_init_multi.c; sourceTree = "<group>"; };
+		F96D428B08F272B3004A47F5 /* bn_mp_init_set.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_init_set.c; sourceTree = "<group>"; };
+		F96D428D08F272B3004A47F5 /* bn_mp_init_size.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_init_size.c; sourceTree = "<group>"; };
+		F96D429208F272B3004A47F5 /* bn_mp_karatsuba_mul.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_karatsuba_mul.c; sourceTree = "<group>"; };
+		F96D429308F272B3004A47F5 /* bn_mp_karatsuba_sqr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_karatsuba_sqr.c; sourceTree = "<group>"; };
+		F96D429508F272B3004A47F5 /* bn_mp_lshd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_lshd.c; sourceTree = "<group>"; };
+		F96D429608F272B3004A47F5 /* bn_mp_mod.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_mod.c; sourceTree = "<group>"; };
+		F96D429708F272B3004A47F5 /* bn_mp_mod_2d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_mod_2d.c; sourceTree = "<group>"; };
+		F96D429C08F272B3004A47F5 /* bn_mp_mul.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_mul.c; sourceTree = "<group>"; };
+		F96D429D08F272B3004A47F5 /* bn_mp_mul_2.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_mul_2.c; sourceTree = "<group>"; };
+		F96D429E08F272B3004A47F5 /* bn_mp_mul_2d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_mul_2d.c; sourceTree = "<group>"; };
+		F96D429F08F272B3004A47F5 /* bn_mp_mul_d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_mul_d.c; sourceTree = "<group>"; };
+		F96D42A208F272B3004A47F5 /* bn_mp_neg.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_neg.c; sourceTree = "<group>"; };
+		F96D42A308F272B3004A47F5 /* bn_mp_or.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_or.c; sourceTree = "<group>"; };
+		F96D42AB08F272B3004A47F5 /* bn_mp_radix_size.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_radix_size.c; sourceTree = "<group>"; };
+		F96D42AC08F272B3004A47F5 /* bn_mp_radix_smap.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_radix_smap.c; sourceTree = "<group>"; };
+		F96D42AE08F272B3004A47F5 /* bn_mp_read_radix.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_read_radix.c; sourceTree = "<group>"; };
+		F96D42B908F272B3004A47F5 /* bn_mp_rshd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_rshd.c; sourceTree = "<group>"; };
+		F96D42BA08F272B3004A47F5 /* bn_mp_set.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_set.c; sourceTree = "<group>"; };
+		F96D42BC08F272B3004A47F5 /* bn_mp_shrink.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_shrink.c; sourceTree = "<group>"; };
+		F96D42BE08F272B3004A47F5 /* bn_mp_sqr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_sqr.c; sourceTree = "<group>"; };
+		F96D42C008F272B3004A47F5 /* bn_mp_sqrt.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_sqrt.c; sourceTree = "<group>"; };
+		F96D42C108F272B3004A47F5 /* bn_mp_sub.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_sub.c; sourceTree = "<group>"; };
+		F96D42C208F272B3004A47F5 /* bn_mp_sub_d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_sub_d.c; sourceTree = "<group>"; };
+		F96D42C608F272B3004A47F5 /* bn_mp_to_unsigned_bin.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_to_unsigned_bin.c; sourceTree = "<group>"; };
+		F96D42C708F272B3004A47F5 /* bn_mp_to_unsigned_bin_n.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_to_unsigned_bin_n.c; sourceTree = "<group>"; };
+		F96D42C808F272B3004A47F5 /* bn_mp_toom_mul.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_toom_mul.c; sourceTree = "<group>"; };
+		F96D42C908F272B3004A47F5 /* bn_mp_toom_sqr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_toom_sqr.c; sourceTree = "<group>"; };
+		F96D42CB08F272B3004A47F5 /* bn_mp_toradix_n.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_toradix_n.c; sourceTree = "<group>"; };
+		F96D42CC08F272B3004A47F5 /* bn_mp_unsigned_bin_size.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_unsigned_bin_size.c; sourceTree = "<group>"; };
+		F96D42CD08F272B3004A47F5 /* bn_mp_xor.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_xor.c; sourceTree = "<group>"; };
+		F96D42CE08F272B3004A47F5 /* bn_mp_zero.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_zero.c; sourceTree = "<group>"; };
+		F96D42D008F272B3004A47F5 /* bn_reverse.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_reverse.c; sourceTree = "<group>"; };
+		F96D42D108F272B3004A47F5 /* bn_s_mp_add.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_s_mp_add.c; sourceTree = "<group>"; };
+		F96D42D308F272B3004A47F5 /* bn_s_mp_mul_digs.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_s_mp_mul_digs.c; sourceTree = "<group>"; };
+		F96D42D508F272B3004A47F5 /* bn_s_mp_sqr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_s_mp_sqr.c; sourceTree = "<group>"; };
+		F96D42D608F272B3004A47F5 /* bn_s_mp_sub.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_s_mp_sub.c; sourceTree = "<group>"; };
+		F96D42D708F272B3004A47F5 /* bncore.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bncore.c; sourceTree = "<group>"; };
+		F96D432908F272B4004A47F5 /* tommath_class.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tommath_class.h; sourceTree = "<group>"; };
+		F96D432A08F272B4004A47F5 /* tommath_superclass.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tommath_superclass.h; sourceTree = "<group>"; };
+		F96D432B08F272B4004A47F5 /* license.terms */ = {isa = PBXFileReference; explicitFileType = text; fileEncoding = 4; path = license.terms; sourceTree = "<group>"; };
+		F96D432E08F272B5004A47F5 /* configure.ac */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = configure.ac; sourceTree = "<group>"; };
+		F96D432F08F272B5004A47F5 /* GNUmakefile */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = GNUmakefile; sourceTree = "<group>"; };
+		F96D433108F272B5004A47F5 /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
+		F96D433208F272B5004A47F5 /* Tcl-Info.plist.in */ = {isa = PBXFileReference; explicitFileType = text.plist; fileEncoding = 4; path = "Tcl-Info.plist.in"; sourceTree = "<group>"; };
+		F96D433908F272B5004A47F5 /* tclMacOSXBundle.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclMacOSXBundle.c; sourceTree = "<group>"; };
+		F96D433D08F272B5004A47F5 /* tclMacOSXFCmd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclMacOSXFCmd.c; sourceTree = "<group>"; };
+		F96D433E08F272B5004A47F5 /* tclMacOSXNotify.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclMacOSXNotify.c; sourceTree = "<group>"; };
+		F96D434308F272B5004A47F5 /* README */ = {isa = PBXFileReference; explicitFileType = text; fileEncoding = 4; path = README; sourceTree = "<group>"; };
+		F96D434508F272B5004A47F5 /* all.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = all.tcl; sourceTree = "<group>"; };
+		F96D434608F272B5004A47F5 /* append.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = append.test; sourceTree = "<group>"; };
+		F96D434708F272B5004A47F5 /* appendComp.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = appendComp.test; sourceTree = "<group>"; };
+		F96D434808F272B5004A47F5 /* assocd.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = assocd.test; sourceTree = "<group>"; };
+		F96D434908F272B5004A47F5 /* async.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = async.test; sourceTree = "<group>"; };
+		F96D434A08F272B5004A47F5 /* autoMkindex.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = autoMkindex.test; sourceTree = "<group>"; };
+		F96D434B08F272B5004A47F5 /* basic.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = basic.test; sourceTree = "<group>"; };
+		F96D434C08F272B5004A47F5 /* binary.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = binary.test; sourceTree = "<group>"; };
+		F96D434D08F272B5004A47F5 /* case.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = case.test; sourceTree = "<group>"; };
+		F96D434E08F272B5004A47F5 /* chan.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = chan.test; sourceTree = "<group>"; };
+		F96D434F08F272B5004A47F5 /* clock.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = clock.test; sourceTree = "<group>"; };
+		F96D435008F272B5004A47F5 /* cmdAH.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = cmdAH.test; sourceTree = "<group>"; };
+		F96D435108F272B5004A47F5 /* cmdIL.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = cmdIL.test; sourceTree = "<group>"; };
+		F96D435208F272B5004A47F5 /* cmdInfo.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = cmdInfo.test; sourceTree = "<group>"; };
+		F96D435308F272B5004A47F5 /* cmdMZ.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = cmdMZ.test; sourceTree = "<group>"; };
+		F96D435408F272B5004A47F5 /* compExpr-old.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = "compExpr-old.test"; sourceTree = "<group>"; };
+		F96D435508F272B5004A47F5 /* compExpr.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = compExpr.test; sourceTree = "<group>"; };
+		F96D435608F272B5004A47F5 /* compile.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = compile.test; sourceTree = "<group>"; };
+		F96D435708F272B5004A47F5 /* concat.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = concat.test; sourceTree = "<group>"; };
+		F96D435808F272B5004A47F5 /* config.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = config.test; sourceTree = "<group>"; };
+		F96D435908F272B5004A47F5 /* dcall.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = dcall.test; sourceTree = "<group>"; };
+		F96D435A08F272B5004A47F5 /* dict.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = dict.test; sourceTree = "<group>"; };
+		F96D435C08F272B5004A47F5 /* dstring.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = dstring.test; sourceTree = "<group>"; };
+		F96D435E08F272B5004A47F5 /* encoding.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = encoding.test; sourceTree = "<group>"; };
+		F96D435F08F272B5004A47F5 /* env.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = env.test; sourceTree = "<group>"; };
+		F96D436008F272B5004A47F5 /* error.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = error.test; sourceTree = "<group>"; };
+		F96D436108F272B5004A47F5 /* eval.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = eval.test; sourceTree = "<group>"; };
+		F96D436208F272B5004A47F5 /* event.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = event.test; sourceTree = "<group>"; };
+		F96D436308F272B5004A47F5 /* exec.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = exec.test; sourceTree = "<group>"; };
+		F96D436408F272B5004A47F5 /* execute.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = execute.test; sourceTree = "<group>"; };
+		F96D436508F272B5004A47F5 /* expr-old.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = "expr-old.test"; sourceTree = "<group>"; };
+		F96D436608F272B5004A47F5 /* expr.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = expr.test; sourceTree = "<group>"; };
+		F96D436708F272B6004A47F5 /* fCmd.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = fCmd.test; sourceTree = "<group>"; };
+		F96D436808F272B6004A47F5 /* fileName.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = fileName.test; sourceTree = "<group>"; };
+		F96D436908F272B6004A47F5 /* fileSystem.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = fileSystem.test; sourceTree = "<group>"; };
+		F96D436A08F272B6004A47F5 /* for-old.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = "for-old.test"; sourceTree = "<group>"; };
+		F96D436B08F272B6004A47F5 /* for.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = for.test; sourceTree = "<group>"; };
+		F96D436C08F272B6004A47F5 /* foreach.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = foreach.test; sourceTree = "<group>"; };
+		F96D436D08F272B6004A47F5 /* format.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = format.test; sourceTree = "<group>"; };
+		F96D436E08F272B6004A47F5 /* get.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = get.test; sourceTree = "<group>"; };
+		F96D436F08F272B6004A47F5 /* history.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = history.test; sourceTree = "<group>"; };
+		F96D437008F272B6004A47F5 /* http.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = http.test; sourceTree = "<group>"; };
+		F96D437108F272B6004A47F5 /* httpd */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = httpd; sourceTree = "<group>"; };
+		F96D437208F272B6004A47F5 /* httpold.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = httpold.test; sourceTree = "<group>"; };
+		F96D437308F272B6004A47F5 /* if-old.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = "if-old.test"; sourceTree = "<group>"; };
+		F96D437408F272B6004A47F5 /* if.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = if.test; sourceTree = "<group>"; };
+		F96D437508F272B6004A47F5 /* incr-old.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = "incr-old.test"; sourceTree = "<group>"; };
+		F96D437608F272B6004A47F5 /* incr.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = incr.test; sourceTree = "<group>"; };
+		F96D437708F272B6004A47F5 /* indexObj.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = indexObj.test; sourceTree = "<group>"; };
+		F96D437808F272B6004A47F5 /* info.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = info.test; sourceTree = "<group>"; };
+		F96D437908F272B6004A47F5 /* init.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = init.test; sourceTree = "<group>"; };
+		F96D437A08F272B6004A47F5 /* interp.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = interp.test; sourceTree = "<group>"; };
+		F96D437B08F272B6004A47F5 /* io.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = io.test; sourceTree = "<group>"; };
+		F96D437C08F272B6004A47F5 /* ioCmd.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = ioCmd.test; sourceTree = "<group>"; };
+		F96D437D08F272B6004A47F5 /* iogt.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = iogt.test; sourceTree = "<group>"; };
+		F96D437F08F272B6004A47F5 /* join.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = join.test; sourceTree = "<group>"; };
+		F96D438008F272B6004A47F5 /* lindex.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = lindex.test; sourceTree = "<group>"; };
+		F96D438108F272B6004A47F5 /* link.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = link.test; sourceTree = "<group>"; };
+		F96D438208F272B6004A47F5 /* linsert.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = linsert.test; sourceTree = "<group>"; };
+		F96D438308F272B6004A47F5 /* list.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = list.test; sourceTree = "<group>"; };
+		F96D438408F272B6004A47F5 /* listObj.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = listObj.test; sourceTree = "<group>"; };
+		F96D438508F272B6004A47F5 /* llength.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = llength.test; sourceTree = "<group>"; };
+		F96D438608F272B6004A47F5 /* load.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = load.test; sourceTree = "<group>"; };
+		F96D438708F272B6004A47F5 /* lrange.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = lrange.test; sourceTree = "<group>"; };
+		F96D438808F272B6004A47F5 /* lrepeat.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = lrepeat.test; sourceTree = "<group>"; };
+		F96D438908F272B6004A47F5 /* lreplace.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = lreplace.test; sourceTree = "<group>"; };
+		F96D438A08F272B6004A47F5 /* lsearch.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = lsearch.test; sourceTree = "<group>"; };
+		F96D438B08F272B6004A47F5 /* lset.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = lset.test; sourceTree = "<group>"; };
+		F96D438C08F272B6004A47F5 /* lsetComp.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = lsetComp.test; sourceTree = "<group>"; };
+		F96D438D08F272B6004A47F5 /* macOSXFCmd.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = macOSXFCmd.test; sourceTree = "<group>"; };
+		F96D438E08F272B6004A47F5 /* main.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = main.test; sourceTree = "<group>"; };
+		F96D438F08F272B6004A47F5 /* misc.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = misc.test; sourceTree = "<group>"; };
+		F96D439008F272B6004A47F5 /* msgcat.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = msgcat.test; sourceTree = "<group>"; };
+		F96D439108F272B6004A47F5 /* namespace-old.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = "namespace-old.test"; sourceTree = "<group>"; };
+		F96D439208F272B7004A47F5 /* namespace.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = namespace.test; sourceTree = "<group>"; };
+		F96D439308F272B7004A47F5 /* notify.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = notify.test; sourceTree = "<group>"; };
+		F96D439408F272B7004A47F5 /* obj.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = obj.test; sourceTree = "<group>"; };
+		F96D439508F272B7004A47F5 /* opt.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = opt.test; sourceTree = "<group>"; };
+		F96D439608F272B7004A47F5 /* package.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = package.test; sourceTree = "<group>"; };
+		F96D439708F272B7004A47F5 /* parse.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = parse.test; sourceTree = "<group>"; };
+		F96D439808F272B7004A47F5 /* parseExpr.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = parseExpr.test; sourceTree = "<group>"; };
+		F96D439908F272B7004A47F5 /* parseOld.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = parseOld.test; sourceTree = "<group>"; };
+		F96D439A08F272B7004A47F5 /* pid.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = pid.test; sourceTree = "<group>"; };
+		F96D439B08F272B7004A47F5 /* pkg.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = pkg.test; sourceTree = "<group>"; };
+		F96D439C08F272B7004A47F5 /* pkgMkIndex.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = pkgMkIndex.test; sourceTree = "<group>"; };
+		F96D439D08F272B7004A47F5 /* platform.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = platform.test; sourceTree = "<group>"; };
+		F96D439E08F272B7004A47F5 /* proc-old.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = "proc-old.test"; sourceTree = "<group>"; };
+		F96D439F08F272B7004A47F5 /* proc.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = proc.test; sourceTree = "<group>"; };
+		F96D43A008F272B7004A47F5 /* pwd.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = pwd.test; sourceTree = "<group>"; };
+		F96D43A108F272B7004A47F5 /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
+		F96D43A208F272B7004A47F5 /* reg.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = reg.test; sourceTree = "<group>"; };
+		F96D43A308F272B7004A47F5 /* regexp.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = regexp.test; sourceTree = "<group>"; };
+		F96D43A408F272B7004A47F5 /* regexpComp.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = regexpComp.test; sourceTree = "<group>"; };
+		F96D43A508F272B7004A47F5 /* registry.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = registry.test; sourceTree = "<group>"; };
+		F96D43A608F272B7004A47F5 /* remote.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = remote.tcl; sourceTree = "<group>"; };
+		F96D43A708F272B7004A47F5 /* rename.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = rename.test; sourceTree = "<group>"; };
+		F96D43A808F272B7004A47F5 /* result.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = result.test; sourceTree = "<group>"; };
+		F96D43A908F272B7004A47F5 /* safe.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = safe.test; sourceTree = "<group>"; };
+		F96D43AA08F272B7004A47F5 /* scan.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = scan.test; sourceTree = "<group>"; };
+		F96D43AB08F272B7004A47F5 /* security.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = security.test; sourceTree = "<group>"; };
+		F96D43AC08F272B7004A47F5 /* set-old.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = "set-old.test"; sourceTree = "<group>"; };
+		F96D43AD08F272B7004A47F5 /* set.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = set.test; sourceTree = "<group>"; };
+		F96D43AE08F272B7004A47F5 /* socket.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = socket.test; sourceTree = "<group>"; };
+		F96D43AF08F272B7004A47F5 /* source.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = source.test; sourceTree = "<group>"; };
+		F96D43B008F272B7004A47F5 /* split.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = split.test; sourceTree = "<group>"; };
+		F96D43B108F272B7004A47F5 /* stack.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = stack.test; sourceTree = "<group>"; };
+		F96D43B208F272B7004A47F5 /* string.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = string.test; sourceTree = "<group>"; };
+		F96D43B308F272B7004A47F5 /* stringComp.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = stringComp.test; sourceTree = "<group>"; };
+		F96D43B408F272B7004A47F5 /* stringObj.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = stringObj.test; sourceTree = "<group>"; };
+		F96D43B508F272B7004A47F5 /* subst.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = subst.test; sourceTree = "<group>"; };
+		F96D43B608F272B7004A47F5 /* switch.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = switch.test; sourceTree = "<group>"; };
+		F96D43B708F272B7004A47F5 /* tcltest.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tcltest.test; sourceTree = "<group>"; };
+		F96D43B808F272B7004A47F5 /* thread.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = thread.test; sourceTree = "<group>"; };
+		F96D43B908F272B7004A47F5 /* timer.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = timer.test; sourceTree = "<group>"; };
+		F96D43BA08F272B7004A47F5 /* tm.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tm.test; sourceTree = "<group>"; };
+		F96D43BB08F272B7004A47F5 /* trace.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = trace.test; sourceTree = "<group>"; };
+		F96D43BC08F272B7004A47F5 /* unixFCmd.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = unixFCmd.test; sourceTree = "<group>"; };
+		F96D43BD08F272B7004A47F5 /* unixFile.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = unixFile.test; sourceTree = "<group>"; };
+		F96D43BE08F272B7004A47F5 /* unixInit.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = unixInit.test; sourceTree = "<group>"; };
+		F96D43BF08F272B7004A47F5 /* unixNotfy.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = unixNotfy.test; sourceTree = "<group>"; };
+		F96D43C008F272B7004A47F5 /* unknown.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = unknown.test; sourceTree = "<group>"; };
+		F96D43C108F272B7004A47F5 /* unload.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = unload.test; sourceTree = "<group>"; };
+		F96D43C208F272B7004A47F5 /* uplevel.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = uplevel.test; sourceTree = "<group>"; };
+		F96D43C308F272B7004A47F5 /* upvar.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = upvar.test; sourceTree = "<group>"; };
+		F96D43C408F272B7004A47F5 /* utf.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = utf.test; sourceTree = "<group>"; };
+		F96D43C508F272B7004A47F5 /* util.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = util.test; sourceTree = "<group>"; };
+		F96D43C608F272B7004A47F5 /* var.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = var.test; sourceTree = "<group>"; };
+		F96D43C708F272B7004A47F5 /* while-old.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = "while-old.test"; sourceTree = "<group>"; };
+		F96D43C808F272B7004A47F5 /* while.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = while.test; sourceTree = "<group>"; };
+		F96D43C908F272B7004A47F5 /* winConsole.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = winConsole.test; sourceTree = "<group>"; };
+		F96D43CA08F272B7004A47F5 /* winDde.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = winDde.test; sourceTree = "<group>"; };
+		F96D43CB08F272B7004A47F5 /* winFCmd.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = winFCmd.test; sourceTree = "<group>"; };
+		F96D43CC08F272B7004A47F5 /* winFile.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = winFile.test; sourceTree = "<group>"; };
+		F96D43CD08F272B7004A47F5 /* winNotify.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = winNotify.test; sourceTree = "<group>"; };
+		F96D43CE08F272B7004A47F5 /* winPipe.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = winPipe.test; sourceTree = "<group>"; };
+		F96D43CF08F272B7004A47F5 /* winTime.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = winTime.test; sourceTree = "<group>"; };
+		F96D43D108F272B8004A47F5 /* checkLibraryDoc.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = checkLibraryDoc.tcl; sourceTree = "<group>"; };
+		F96D43D208F272B8004A47F5 /* configure */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = configure; sourceTree = "<group>"; };
+		F96D43D308F272B8004A47F5 /* configure.in */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = configure.in; sourceTree = "<group>"; };
+		F96D442408F272B8004A47F5 /* fix_tommath_h.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = fix_tommath_h.tcl; sourceTree = "<group>"; };
+		F96D442508F272B8004A47F5 /* genStubs.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = genStubs.tcl; sourceTree = "<group>"; };
+		F96D442708F272B8004A47F5 /* index.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = index.tcl; sourceTree = "<group>"; };
+		F96D442808F272B8004A47F5 /* installData.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = installData.tcl; sourceTree = "<group>"; };
+		F96D442908F272B8004A47F5 /* loadICU.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = loadICU.tcl; sourceTree = "<group>"; };
+		F96D442A08F272B8004A47F5 /* Makefile.in */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = Makefile.in; sourceTree = "<group>"; };
+		F96D442B08F272B8004A47F5 /* makeTestCases.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = makeTestCases.tcl; sourceTree = "<group>"; };
+		F96D442C08F272B8004A47F5 /* man2help.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = man2help.tcl; sourceTree = "<group>"; };
+		F96D442D08F272B8004A47F5 /* man2help2.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = man2help2.tcl; sourceTree = "<group>"; };
+		F96D442E08F272B8004A47F5 /* man2html.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = man2html.tcl; sourceTree = "<group>"; };
+		F96D442F08F272B8004A47F5 /* man2html1.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = man2html1.tcl; sourceTree = "<group>"; };
+		F96D443008F272B8004A47F5 /* man2html2.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = man2html2.tcl; sourceTree = "<group>"; };
+		F96D443108F272B8004A47F5 /* man2tcl.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = man2tcl.c; sourceTree = "<group>"; };
+		F96D443208F272B8004A47F5 /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
+		F96D443308F272B8004A47F5 /* regexpTestLib.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = regexpTestLib.tcl; sourceTree = "<group>"; };
+		F96D443508F272B8004A47F5 /* tcl.hpj.in */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = tcl.hpj.in; sourceTree = "<group>"; };
+		F96D443908F272B9004A47F5 /* tcltk-man2html.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = "tcltk-man2html.tcl"; sourceTree = "<group>"; };
+		F96D443A08F272B9004A47F5 /* tclZIC.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tclZIC.tcl; sourceTree = "<group>"; };
+		F96D443B08F272B9004A47F5 /* uniClass.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = uniClass.tcl; sourceTree = "<group>"; };
+		F96D443C08F272B9004A47F5 /* uniParse.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = uniParse.tcl; sourceTree = "<group>"; };
+		F96D444008F272B9004A47F5 /* aclocal.m4 */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = aclocal.m4; sourceTree = "<group>"; };
+		F96D444108F272B9004A47F5 /* configure */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = configure; sourceTree = "<group>"; };
+		F96D444208F272B9004A47F5 /* configure.in */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = configure.in; sourceTree = "<group>"; };
+		F96D444408F272B9004A47F5 /* Makefile.in */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = Makefile.in; sourceTree = "<group>"; };
+		F96D444508F272B9004A47F5 /* pkga.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pkga.c; sourceTree = "<group>"; };
+		F96D444608F272B9004A47F5 /* pkgb.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pkgb.c; sourceTree = "<group>"; };
+		F96D444708F272B9004A47F5 /* pkgc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pkgc.c; sourceTree = "<group>"; };
+		F96D444808F272B9004A47F5 /* pkgd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pkgd.c; sourceTree = "<group>"; };
+		F96D444908F272B9004A47F5 /* pkge.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pkge.c; sourceTree = "<group>"; };
+		F96D444B08F272B9004A47F5 /* pkgua.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pkgua.c; sourceTree = "<group>"; };
+		F96D444C08F272B9004A47F5 /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
+		F96D444D08F272B9004A47F5 /* install-sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = "install-sh"; sourceTree = "<group>"; };
+		F96D444E08F272B9004A47F5 /* installManPage */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = installManPage; sourceTree = "<group>"; };
+		F96D444F08F272B9004A47F5 /* ldAix */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = ldAix; sourceTree = "<group>"; };
+		F96D445008F272B9004A47F5 /* Makefile.in */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = Makefile.in; sourceTree = "<group>"; };
+		F96D445208F272B9004A47F5 /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
+		F96D445308F272B9004A47F5 /* tcl.m4 */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = tcl.m4; sourceTree = "<group>"; };
+		F96D445408F272B9004A47F5 /* tcl.spec */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = tcl.spec; sourceTree = "<group>"; };
+		F96D445508F272B9004A47F5 /* tclAppInit.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclAppInit.c; sourceTree = "<group>"; };
+		F96D445608F272B9004A47F5 /* tclConfig.h.in */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; path = tclConfig.h.in; sourceTree = "<group>"; };
+		F96D445708F272B9004A47F5 /* tclConfig.sh.in */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = tclConfig.sh.in; sourceTree = "<group>"; };
+		F96D445808F272B9004A47F5 /* tclLoadAix.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclLoadAix.c; sourceTree = "<group>"; };
+		F96D445908F272B9004A47F5 /* tclLoadDl.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclLoadDl.c; sourceTree = "<group>"; };
+		F96D445B08F272B9004A47F5 /* tclLoadDyld.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclLoadDyld.c; sourceTree = "<group>"; };
+		F96D445C08F272B9004A47F5 /* tclLoadNext.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclLoadNext.c; sourceTree = "<group>"; };
+		F96D445D08F272B9004A47F5 /* tclLoadOSF.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclLoadOSF.c; sourceTree = "<group>"; };
+		F96D445E08F272B9004A47F5 /* tclLoadShl.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclLoadShl.c; sourceTree = "<group>"; };
+		F96D445F08F272B9004A47F5 /* tclUnixChan.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUnixChan.c; sourceTree = "<group>"; };
+		F96D446008F272B9004A47F5 /* tclUnixEvent.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUnixEvent.c; sourceTree = "<group>"; };
+		F96D446108F272B9004A47F5 /* tclUnixFCmd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUnixFCmd.c; sourceTree = "<group>"; };
+		F96D446208F272B9004A47F5 /* tclUnixFile.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUnixFile.c; sourceTree = "<group>"; };
+		F96D446308F272B9004A47F5 /* tclUnixInit.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUnixInit.c; sourceTree = "<group>"; };
+		F96D446408F272B9004A47F5 /* tclUnixNotfy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUnixNotfy.c; sourceTree = "<group>"; };
+		F96D446508F272B9004A47F5 /* tclUnixPipe.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUnixPipe.c; sourceTree = "<group>"; };
+		F96D446608F272B9004A47F5 /* tclUnixPort.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclUnixPort.h; sourceTree = "<group>"; };
+		F96D446708F272B9004A47F5 /* tclUnixSock.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUnixSock.c; sourceTree = "<group>"; };
+		F96D446808F272B9004A47F5 /* tclUnixTest.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUnixTest.c; sourceTree = "<group>"; };
+		F96D446908F272B9004A47F5 /* tclUnixThrd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUnixThrd.c; sourceTree = "<group>"; };
+		F96D446B08F272B9004A47F5 /* tclUnixTime.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUnixTime.c; sourceTree = "<group>"; };
+		F96D446C08F272B9004A47F5 /* tclXtNotify.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclXtNotify.c; sourceTree = "<group>"; };
+		F96D446D08F272B9004A47F5 /* tclXtTest.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclXtTest.c; sourceTree = "<group>"; };
+		F96D447008F272BA004A47F5 /* aclocal.m4 */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = aclocal.m4; sourceTree = "<group>"; };
+		F96D447108F272BA004A47F5 /* buildall.vc.bat */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = buildall.vc.bat; sourceTree = "<group>"; };
+		F96D447208F272BA004A47F5 /* cat.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = cat.c; sourceTree = "<group>"; };
+		F96D447308F272BA004A47F5 /* coffbase.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = coffbase.txt; sourceTree = "<group>"; };
+		F96D447408F272BA004A47F5 /* configure */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = configure; sourceTree = "<group>"; };
+		F96D447508F272BA004A47F5 /* configure.in */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = configure.in; sourceTree = "<group>"; };
+		F96D447608F272BA004A47F5 /* makefile.bc */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = makefile.bc; sourceTree = "<group>"; };
+		F96D447708F272BA004A47F5 /* Makefile.in */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = Makefile.in; sourceTree = "<group>"; };
+		F96D447808F272BA004A47F5 /* makefile.vc */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = makefile.vc; sourceTree = "<group>"; };
+		F96D447908F272BA004A47F5 /* nmakehlp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = nmakehlp.c; sourceTree = "<group>"; };
+		F96D447A08F272BA004A47F5 /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
+		F96D447C08F272BA004A47F5 /* rules.vc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = rules.vc; sourceTree = "<group>"; };
+		F96D447D08F272BA004A47F5 /* stub16.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = stub16.c; sourceTree = "<group>"; };
+		F96D447E08F272BA004A47F5 /* tcl.dsp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = tcl.dsp; sourceTree = "<group>"; };
+		F96D447F08F272BA004A47F5 /* tcl.dsw */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = tcl.dsw; sourceTree = "<group>"; };
+		F96D448008F272BA004A47F5 /* tcl.hpj.in */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = tcl.hpj.in; sourceTree = "<group>"; };
+		F96D448108F272BA004A47F5 /* tcl.m4 */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = tcl.m4; sourceTree = "<group>"; };
+		F96D448208F272BA004A47F5 /* tcl.rc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = tcl.rc; sourceTree = "<group>"; };
+		F96D448308F272BA004A47F5 /* tclAppInit.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclAppInit.c; sourceTree = "<group>"; };
+		F96D448408F272BA004A47F5 /* tclConfig.sh.in */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = tclConfig.sh.in; sourceTree = "<group>"; };
+		F96D448608F272BA004A47F5 /* tclsh.rc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = tclsh.rc; sourceTree = "<group>"; };
+		F96D448708F272BA004A47F5 /* tclWin32Dll.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWin32Dll.c; sourceTree = "<group>"; };
+		F96D448808F272BA004A47F5 /* tclWinChan.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinChan.c; sourceTree = "<group>"; };
+		F96D448908F272BA004A47F5 /* tclWinConsole.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinConsole.c; sourceTree = "<group>"; };
+		F96D448A08F272BA004A47F5 /* tclWinDde.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinDde.c; sourceTree = "<group>"; };
+		F96D448B08F272BA004A47F5 /* tclWinError.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinError.c; sourceTree = "<group>"; };
+		F96D448C08F272BA004A47F5 /* tclWinFCmd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinFCmd.c; sourceTree = "<group>"; };
+		F96D448D08F272BA004A47F5 /* tclWinFile.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinFile.c; sourceTree = "<group>"; };
+		F96D448E08F272BA004A47F5 /* tclWinInit.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinInit.c; sourceTree = "<group>"; };
+		F96D448F08F272BA004A47F5 /* tclWinInt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclWinInt.h; sourceTree = "<group>"; };
+		F96D449008F272BA004A47F5 /* tclWinLoad.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinLoad.c; sourceTree = "<group>"; };
+		F96D449108F272BA004A47F5 /* tclWinNotify.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinNotify.c; sourceTree = "<group>"; };
+		F96D449208F272BA004A47F5 /* tclWinPipe.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinPipe.c; sourceTree = "<group>"; };
+		F96D449308F272BA004A47F5 /* tclWinPort.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclWinPort.h; sourceTree = "<group>"; };
+		F96D449408F272BA004A47F5 /* tclWinReg.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinReg.c; sourceTree = "<group>"; };
+		F96D449508F272BA004A47F5 /* tclWinSerial.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinSerial.c; sourceTree = "<group>"; };
+		F96D449608F272BA004A47F5 /* tclWinSock.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinSock.c; sourceTree = "<group>"; };
+		F96D449708F272BA004A47F5 /* tclWinTest.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinTest.c; sourceTree = "<group>"; };
+		F96D449808F272BA004A47F5 /* tclWinThrd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinThrd.c; sourceTree = "<group>"; };
+		F96D449908F272BA004A47F5 /* tclWinThrd.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclWinThrd.h; sourceTree = "<group>"; };
+		F96D449A08F272BA004A47F5 /* tclWinTime.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinTime.c; sourceTree = "<group>"; };
+		F974D56C0FBE7D6300BF728B /* http11.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = http11.test; sourceTree = "<group>"; };
+		F974D56D0FBE7D6300BF728B /* httpd11.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = httpd11.tcl; sourceTree = "<group>"; };
+		F974D5720FBE7DC600BF728B /* coroutine.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = coroutine.n; sourceTree = "<group>"; };
+		F974D5760FBE7E1900BF728B /* tailcall.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = tailcall.n; sourceTree = "<group>"; };
+		F974D5770FBE7E6100BF728B /* coroutine.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = coroutine.test; sourceTree = "<group>"; };
+		F974D5780FBE7E6100BF728B /* tailcall.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tailcall.test; sourceTree = "<group>"; };
+		F974D5790FBE7E9C00BF728B /* tcl.pc.in */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = tcl.pc.in; sourceTree = "<group>"; };
+		F97AE7F10B65C1E900310EA2 /* Tcl-Common.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = "Tcl-Common.xcconfig"; sourceTree = "<group>"; };
+		F97AE82B0B65C69B00310EA2 /* Tcl-Release.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = "Tcl-Release.xcconfig"; sourceTree = "<group>"; };
+		F97AE8330B65C87F00310EA2 /* Tcl-Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = "Tcl-Debug.xcconfig"; sourceTree = "<group>"; };
+		F9903CAF094FAADA004613E9 /* tclTomMath.decls */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tclTomMath.decls; sourceTree = "<group>"; };
+		F9903CB0094FAADA004613E9 /* tclTomMathDecls.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclTomMathDecls.h; sourceTree = "<group>"; };
+		F99D61180EF5573A00BBFE01 /* TclZlib.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = TclZlib.3; sourceTree = "<group>"; };
+		F9A3084B08F2D4CE00BAE1AB /* tclsh */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = tclsh; sourceTree = BUILT_PRODUCTS_DIR; };
+		F9A3084E08F2D4F400BAE1AB /* Tcl.framework */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = wrapper.framework; path = Tcl.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+		F9A493240CEBF38300B78AE2 /* chanio.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = chanio.test; sourceTree = "<group>"; };
+		F9ECB1120B26521500A28025 /* pkgIndex.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = pkgIndex.tcl; sourceTree = "<group>"; };
+		F9ECB1130B26521500A28025 /* platform.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = platform.tcl; sourceTree = "<group>"; };
+		F9ECB1140B26521500A28025 /* shell.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = shell.tcl; sourceTree = "<group>"; };
+		F9ECB1CA0B2652D300A28025 /* apply.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = apply.test; sourceTree = "<group>"; };
+		F9ECB1CB0B26534C00A28025 /* mathop.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = mathop.test; sourceTree = "<group>"; };
+		F9ECB1E10B26543C00A28025 /* platform_shell.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = platform_shell.n; sourceTree = "<group>"; };
+		F9ECB1E20B26543C00A28025 /* platform.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = platform.n; sourceTree = "<group>"; };
+		F9F4415D0C8BAE6F00BCCD67 /* tclDTrace.d */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.dtrace; path = tclDTrace.d; sourceTree = "<group>"; };
+		F9FC77B70AB29E9100B7077D /* tclUnixCompat.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUnixCompat.c; sourceTree = "<group>"; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+		8DD76FAD0486AB0100D96B5E /* Frameworks */ = {
+			isa = PBXFrameworksBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				F966C07508F2820D005CB29B /* CoreFoundation.framework in Frameworks */,
+				F96437E70EF0D652003F468E /* libz.dylib in Frameworks */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+		08FB7794FE84155DC02AAC07 /* Tcl */ = {
+			isa = PBXGroup;
+			children = (
+				F96D3DF608F27169004A47F5 /* Tcl Sources */,
+				F966C06F08F281DC005CB29B /* Frameworks */,
+				1AB674ADFE9D54B511CA2CBB /* Products */,
+			);
+			comments = "Copyright (c) 2004-2009 Daniel A. Steffen <das@users.sourceforge.net>\nCopyright 2008-2009, Apple Inc.\n\nSee the file \"license.terms\" for information on usage and redistribution of\nthis file, and for a DISCLAIMER OF ALL WARRANTIES.\n\n";
+			name = Tcl;
+			path = .;
+			sourceTree = SOURCE_ROOT;
+		};
+		1AB674ADFE9D54B511CA2CBB /* Products */ = {
+			isa = PBXGroup;
+			children = (
+				F9A3084B08F2D4CE00BAE1AB /* tclsh */,
+				8DD76FB20486AB0100D96B5E /* tcltest */,
+				F9A3084E08F2D4F400BAE1AB /* Tcl.framework */,
+			);
+			includeInIndex = 0;
+			name = Products;
+			sourceTree = "<group>";
+		};
+		F9183E690EFC81560030B814 /* pkgs */ = {
+			isa = PBXGroup;
+			children = (
+				F9183E6A0EFC81560030B814 /* README */,
+				F946FB8B0FBE3AED00CD6495 /* itcl */,
+				F9183E8F0EFC817B0030B814 /* tdbc */,
+			);
+			path = pkgs;
+			sourceTree = "<group>";
+		};
+		F966C06F08F281DC005CB29B /* Frameworks */ = {
+			isa = PBXGroup;
+			children = (
+				F966C07408F2820D005CB29B /* CoreFoundation.framework */,
+				F96437E60EF0D652003F468E /* libz.dylib */,
+			);
+			name = Frameworks;
+			sourceTree = "<group>";
+		};
+		F96D3DF608F27169004A47F5 /* Tcl Sources */ = {
+			isa = PBXGroup;
+			children = (
+				F96D3EC908F272A7004A47F5 /* generic */,
+				F96D432C08F272B4004A47F5 /* macosx */,
+				F96D443E08F272B9004A47F5 /* unix */,
+				F96D425C08F272B2004A47F5 /* libtommath */,
+				F96D446E08F272B9004A47F5 /* win */,
+				F96D3F3808F272A7004A47F5 /* library */,
+				F96D434408F272B5004A47F5 /* tests */,
+				F96D3DFC08F272A4004A47F5 /* doc */,
+				F96D43D008F272B8004A47F5 /* tools */,
+				F9183E690EFC81560030B814 /* pkgs */,
+				F96D3DFA08F272A4004A47F5 /* ChangeLog */,
+				F96D3DFB08F272A4004A47F5 /* changes */,
+				F96D434308F272B5004A47F5 /* README */,
+				F96D432B08F272B4004A47F5 /* license.terms */,
+			);
+			name = "Tcl Sources";
+			sourceTree = TCL_SRCROOT;
+		};
+		F96D3DFC08F272A4004A47F5 /* doc */ = {
+			isa = PBXGroup;
+			children = (
+				F96D3DFD08F272A4004A47F5 /* Access.3 */,
+				F96D3DFE08F272A4004A47F5 /* AddErrInfo.3 */,
+				F96D3DFF08F272A4004A47F5 /* after.n */,
+				F96D3E0008F272A4004A47F5 /* Alloc.3 */,
+				F96D3E0108F272A4004A47F5 /* AllowExc.3 */,
+				F96D3E0208F272A4004A47F5 /* append.n */,
+				F96D3E0308F272A4004A47F5 /* AppInit.3 */,
+				F96D3E0408F272A5004A47F5 /* array.n */,
+				F96D3E0508F272A5004A47F5 /* AssocData.3 */,
+				F96D3E0608F272A5004A47F5 /* Async.3 */,
+				F96D3E0708F272A5004A47F5 /* BackgdErr.3 */,
+				F96D3E0808F272A5004A47F5 /* Backslash.3 */,
+				F96D3E0908F272A5004A47F5 /* bgerror.n */,
+				F96D3E0A08F272A5004A47F5 /* binary.n */,
+				F96D3E0B08F272A5004A47F5 /* BoolObj.3 */,
+				F96D3E0C08F272A5004A47F5 /* break.n */,
+				F96D3E0D08F272A5004A47F5 /* ByteArrObj.3 */,
+				F96D3E0E08F272A5004A47F5 /* CallDel.3 */,
+				F96D3E0F08F272A5004A47F5 /* case.n */,
+				F96D3E1008F272A5004A47F5 /* catch.n */,
+				F96D3E1108F272A5004A47F5 /* cd.n */,
+				F96D3E1208F272A5004A47F5 /* chan.n */,
+				F96D3E1308F272A5004A47F5 /* ChnlStack.3 */,
+				F93599CF0DF1F87F00E04F67 /* Class.3 */,
+				F93599D00DF1F89E00E04F67 /* class.n */,
+				F96D3E1408F272A5004A47F5 /* clock.n */,
+				F96D3E1508F272A5004A47F5 /* close.n */,
+				F96D3E1608F272A5004A47F5 /* CmdCmplt.3 */,
+				F96D3E1708F272A5004A47F5 /* Concat.3 */,
+				F96D3E1808F272A5004A47F5 /* concat.n */,
+				F96D3E1908F272A5004A47F5 /* continue.n */,
+				F93599D20DF1F8DF00E04F67 /* copy.n */,
+				F974D5720FBE7DC600BF728B /* coroutine.n */,
+				F96D3E1A08F272A5004A47F5 /* CrtChannel.3 */,
+				F96D3E1B08F272A5004A47F5 /* CrtChnlHdlr.3 */,
+				F96D3E1C08F272A5004A47F5 /* CrtCloseHdlr.3 */,
+				F96D3E1D08F272A5004A47F5 /* CrtCommand.3 */,
+				F96D3E1E08F272A5004A47F5 /* CrtFileHdlr.3 */,
+				F96D3E1F08F272A5004A47F5 /* CrtInterp.3 */,
+				F96D3E2008F272A5004A47F5 /* CrtMathFnc.3 */,
+				F96D3E2108F272A5004A47F5 /* CrtObjCmd.3 */,
+				F96D3E2208F272A5004A47F5 /* CrtSlave.3 */,
+				F96D3E2308F272A5004A47F5 /* CrtTimerHdlr.3 */,
+				F96D3E2408F272A5004A47F5 /* CrtTrace.3 */,
+				F96D3E2508F272A5004A47F5 /* dde.n */,
+				F93599D30DF1F8F500E04F67 /* define.n */,
+				F96D3E2608F272A5004A47F5 /* DetachPids.3 */,
+				F96D3E2708F272A5004A47F5 /* dict.n */,
+				F96D3E2808F272A5004A47F5 /* DictObj.3 */,
+				F96D3E2908F272A5004A47F5 /* DoOneEvent.3 */,
+				F96D3E2A08F272A5004A47F5 /* DoubleObj.3 */,
+				F96D3E2B08F272A5004A47F5 /* DoWhenIdle.3 */,
+				F96D3E2C08F272A5004A47F5 /* DString.3 */,
+				F96D3E2D08F272A5004A47F5 /* DumpActiveMemory.3 */,
+				F96D3E2E08F272A5004A47F5 /* Encoding.3 */,
+				F96D3E2F08F272A5004A47F5 /* encoding.n */,
+				F96D3E3008F272A5004A47F5 /* Ensemble.3 */,
+				F96D3E3108F272A5004A47F5 /* Environment.3 */,
+				F96D3E3208F272A5004A47F5 /* eof.n */,
+				F96D3E3308F272A5004A47F5 /* error.n */,
+				F96D3E3408F272A5004A47F5 /* Eval.3 */,
+				F96D3E3508F272A5004A47F5 /* eval.n */,
+				F96D3E3608F272A5004A47F5 /* exec.n */,
+				F96D3E3708F272A5004A47F5 /* Exit.3 */,
+				F96D3E3808F272A5004A47F5 /* exit.n */,
+				F96D3E3908F272A5004A47F5 /* expr.n */,
+				F96D3E3A08F272A5004A47F5 /* ExprLong.3 */,
+				F96D3E3B08F272A5004A47F5 /* ExprLongObj.3 */,
+				F96D3E3C08F272A5004A47F5 /* fblocked.n */,
+				F96D3E3D08F272A5004A47F5 /* fconfigure.n */,
+				F96D3E3E08F272A5004A47F5 /* fcopy.n */,
+				F96D3E3F08F272A5004A47F5 /* file.n */,
+				F96D3E4008F272A5004A47F5 /* fileevent.n */,
+				F96D3E4108F272A5004A47F5 /* filename.n */,
+				F96D3E4208F272A5004A47F5 /* FileSystem.3 */,
+				F96D3E4308F272A5004A47F5 /* FindExec.3 */,
+				F96D3E4408F272A5004A47F5 /* flush.n */,
+				F96D3E4508F272A5004A47F5 /* for.n */,
+				F96D3E4608F272A5004A47F5 /* foreach.n */,
+				F96D3E4708F272A5004A47F5 /* format.n */,
+				F96D3E4808F272A5004A47F5 /* GetCwd.3 */,
+				F96D3E4908F272A5004A47F5 /* GetHostName.3 */,
+				F96D3E4A08F272A5004A47F5 /* GetIndex.3 */,
+				F96D3E4B08F272A5004A47F5 /* GetInt.3 */,
+				F96D3E4C08F272A5004A47F5 /* GetOpnFl.3 */,
+				F96D3E4D08F272A5004A47F5 /* gets.n */,
+				F96D3E4E08F272A5004A47F5 /* GetStdChan.3 */,
+				F96D3E4F08F272A5004A47F5 /* GetTime.3 */,
+				F96D3E5008F272A5004A47F5 /* GetVersion.3 */,
+				F96D3E5108F272A5004A47F5 /* glob.n */,
+				F96D3E5208F272A6004A47F5 /* global.n */,
+				F96D3E5308F272A6004A47F5 /* Hash.3 */,
+				F96D3E5408F272A6004A47F5 /* history.n */,
+				F96D3E5508F272A6004A47F5 /* http.n */,
+				F96D3E5608F272A6004A47F5 /* if.n */,
+				F96D3E5708F272A6004A47F5 /* incr.n */,
+				F96D3E5808F272A6004A47F5 /* info.n */,
+				F96D3E5908F272A6004A47F5 /* Init.3 */,
+				F96D3E5A08F272A6004A47F5 /* InitStubs.3 */,
+				F96D3E5B08F272A6004A47F5 /* Interp.3 */,
+				F96D3E5C08F272A6004A47F5 /* interp.n */,
+				F96D3E5D08F272A6004A47F5 /* IntObj.3 */,
+				F96D3E5E08F272A6004A47F5 /* join.n */,
+				F96D3E5F08F272A6004A47F5 /* lappend.n */,
+				F96D3E6008F272A6004A47F5 /* lassign.n */,
+				F96D3E6108F272A6004A47F5 /* library.n */,
+				F96D3E6208F272A6004A47F5 /* Limit.3 */,
+				F96D3E6308F272A6004A47F5 /* lindex.n */,
+				F96D3E6408F272A6004A47F5 /* LinkVar.3 */,
+				F96D3E6508F272A6004A47F5 /* linsert.n */,
+				F96D3E6608F272A6004A47F5 /* list.n */,
+				F96D3E6708F272A6004A47F5 /* ListObj.3 */,
+				F96D3E6808F272A6004A47F5 /* llength.n */,
+				F96D3E6908F272A6004A47F5 /* load.n */,
+				F96D3E6A08F272A6004A47F5 /* lrange.n */,
+				F96D3E6B08F272A6004A47F5 /* lrepeat.n */,
+				F96D3E6C08F272A6004A47F5 /* lreplace.n */,
+				F96D3E6D08F272A6004A47F5 /* lsearch.n */,
+				F96D3E6E08F272A6004A47F5 /* lset.n */,
+				F96D3E6F08F272A6004A47F5 /* lsort.n */,
+				F96D3E7008F272A6004A47F5 /* man.macros */,
+				F96D3E7108F272A6004A47F5 /* mathfunc.n */,
+				F96D3E7208F272A6004A47F5 /* memory.n */,
+				F93599D40DF1F91900E04F67 /* Method.3 */,
+				F96D3E7308F272A6004A47F5 /* msgcat.n */,
+				F93599D50DF1F93700E04F67 /* my.n */,
+				F96D3E7408F272A6004A47F5 /* Namespace.3 */,
+				F96D3E7508F272A6004A47F5 /* namespace.n */,
+				F93599D60DF1F95000E04F67 /* next.n */,
+				F96D3E7608F272A6004A47F5 /* Notifier.3 */,
+				F96D3E7708F272A6004A47F5 /* Object.3 */,
+				F93599D70DF1F96800E04F67 /* object.n */,
+				F96D3E7808F272A6004A47F5 /* ObjectType.3 */,
+				F96D3E7908F272A6004A47F5 /* open.n */,
+				F96D3E7A08F272A6004A47F5 /* OpenFileChnl.3 */,
+				F96D3E7B08F272A6004A47F5 /* OpenTcp.3 */,
+				F96D3E7C08F272A6004A47F5 /* package.n */,
+				F96D3E7D08F272A6004A47F5 /* packagens.n */,
+				F96D3E7E08F272A6004A47F5 /* Panic.3 */,
+				F96D3E7F08F272A6004A47F5 /* ParseCmd.3 */,
+				F96D3E8008F272A6004A47F5 /* pid.n */,
+				F96D3E8108F272A6004A47F5 /* pkgMkIndex.n */,
+				F96D3E8208F272A6004A47F5 /* PkgRequire.3 */,
+				F9ECB1E10B26543C00A28025 /* platform_shell.n */,
+				F9ECB1E20B26543C00A28025 /* platform.n */,
+				F96D3E8308F272A6004A47F5 /* Preserve.3 */,
+				F96D3E8408F272A6004A47F5 /* PrintDbl.3 */,
+				F96D3E8508F272A6004A47F5 /* proc.n */,
+				F96D3E8608F272A6004A47F5 /* puts.n */,
+				F96D3E8708F272A6004A47F5 /* pwd.n */,
+				F96D3E8808F272A6004A47F5 /* re_syntax.n */,
+				F96D3E8908F272A6004A47F5 /* read.n */,
+				F96D3E8A08F272A6004A47F5 /* RecEvalObj.3 */,
+				F96D3E8B08F272A6004A47F5 /* RecordEval.3 */,
+				F96D3E8C08F272A6004A47F5 /* RegConfig.3 */,
+				F96D3E8D08F272A6004A47F5 /* RegExp.3 */,
+				F96D3E8E08F272A6004A47F5 /* regexp.n */,
+				F96D3E8F08F272A6004A47F5 /* registry.n */,
+				F96D3E9008F272A6004A47F5 /* regsub.n */,
+				F96D3E9108F272A6004A47F5 /* rename.n */,
+				F96D3E9208F272A6004A47F5 /* return.n */,
+				F96D3E9308F272A6004A47F5 /* safe.n */,
+				F96D3E9408F272A6004A47F5 /* SaveResult.3 */,
+				F96D3E9508F272A6004A47F5 /* scan.n */,
+				F96D3E9608F272A6004A47F5 /* seek.n */,
+				F93599D80DF1F98300E04F67 /* self.n */,
+				F96D3E9708F272A6004A47F5 /* set.n */,
+				F96D3E9808F272A6004A47F5 /* SetChanErr.3 */,
+				F96D3E9908F272A6004A47F5 /* SetErrno.3 */,
+				F96D3E9A08F272A6004A47F5 /* SetRecLmt.3 */,
+				F96D3E9B08F272A7004A47F5 /* SetResult.3 */,
+				F96D3E9C08F272A7004A47F5 /* SetVar.3 */,
+				F96D3E9D08F272A7004A47F5 /* Signal.3 */,
+				F96D3E9E08F272A7004A47F5 /* Sleep.3 */,
+				F96D3E9F08F272A7004A47F5 /* socket.n */,
+				F96D3EA008F272A7004A47F5 /* source.n */,
+				F96D3EA108F272A7004A47F5 /* SourceRCFile.3 */,
+				F96D3EA208F272A7004A47F5 /* split.n */,
+				F96D3EA308F272A7004A47F5 /* SplitList.3 */,
+				F96D3EA408F272A7004A47F5 /* SplitPath.3 */,
+				F96D3EA508F272A7004A47F5 /* StaticPkg.3 */,
+				F96D3EA608F272A7004A47F5 /* StdChannels.3 */,
+				F96D3EA708F272A7004A47F5 /* string.n */,
+				F96D3EA808F272A7004A47F5 /* StringObj.3 */,
+				F96D3EA908F272A7004A47F5 /* StrMatch.3 */,
+				F96D3EAA08F272A7004A47F5 /* subst.n */,
+				F96D3EAB08F272A7004A47F5 /* SubstObj.3 */,
+				F96D3EAC08F272A7004A47F5 /* switch.n */,
+				F974D5760FBE7E1900BF728B /* tailcall.n */,
+				F96D3EAD08F272A7004A47F5 /* Tcl.n */,
+				F99D61180EF5573A00BBFE01 /* TclZlib.3 */,
+				F96D3EAE08F272A7004A47F5 /* Tcl_Main.3 */,
+				F96D3EAF08F272A7004A47F5 /* TCL_MEM_DEBUG.3 */,
+				F96D3EB008F272A7004A47F5 /* tclsh.1 */,
+				F96D3EB108F272A7004A47F5 /* tcltest.n */,
+				F96D3EB208F272A7004A47F5 /* tclvars.n */,
+				F96D3EB308F272A7004A47F5 /* tell.n */,
+				F96D3EB408F272A7004A47F5 /* Thread.3 */,
+				F9183E640EFC80CD0030B814 /* throw.n */,
+				F96D3EB508F272A7004A47F5 /* time.n */,
+				F96D3EB608F272A7004A47F5 /* tm.n */,
+				F96D3EB708F272A7004A47F5 /* ToUpper.3 */,
+				F96D3EB808F272A7004A47F5 /* trace.n */,
+				F96D3EB908F272A7004A47F5 /* TraceCmd.3 */,
+				F96D3EBA08F272A7004A47F5 /* TraceVar.3 */,
+				F96D3EBB08F272A7004A47F5 /* Translate.3 */,
+				F9183E650EFC80D70030B814 /* try.n */,
+				F96D3EBC08F272A7004A47F5 /* UniCharIsAlpha.3 */,
+				F96D3EBD08F272A7004A47F5 /* unknown.n */,
+				F96D3EBE08F272A7004A47F5 /* unload.n */,
+				F96D3EBF08F272A7004A47F5 /* unset.n */,
+				F96D3EC008F272A7004A47F5 /* update.n */,
+				F96D3EC108F272A7004A47F5 /* uplevel.n */,
+				F96D3EC208F272A7004A47F5 /* UpVar.3 */,
+				F96D3EC308F272A7004A47F5 /* upvar.n */,
+				F96D3EC408F272A7004A47F5 /* Utf.3 */,
+				F96D3EC508F272A7004A47F5 /* variable.n */,
+				F96D3EC608F272A7004A47F5 /* vwait.n */,
+				F96D3EC708F272A7004A47F5 /* while.n */,
+				F96D3EC808F272A7004A47F5 /* WrongNumArgs.3 */,
+				F915432D0EF201EE0032D1E8 /* zlib.n */,
+			);
+			path = doc;
+			sourceTree = "<group>";
+		};
+		F96D3EC908F272A7004A47F5 /* generic */ = {
+			isa = PBXGroup;
+			children = (
+				F96D3ECA08F272A7004A47F5 /* README */,
+				F96D3ECB08F272A7004A47F5 /* regc_color.c */,
+				F96D3ECC08F272A7004A47F5 /* regc_cvec.c */,
+				F96D3ECD08F272A7004A47F5 /* regc_lex.c */,
+				F96D3ECE08F272A7004A47F5 /* regc_locale.c */,
+				F96D3ECF08F272A7004A47F5 /* regc_nfa.c */,
+				F96D3ED008F272A7004A47F5 /* regcomp.c */,
+				F96D3ED108F272A7004A47F5 /* regcustom.h */,
+				F96D3ED208F272A7004A47F5 /* rege_dfa.c */,
+				F96D3ED308F272A7004A47F5 /* regerror.c */,
+				F96D3ED408F272A7004A47F5 /* regerrs.h */,
+				F96D3ED508F272A7004A47F5 /* regex.h */,
+				F96D3ED608F272A7004A47F5 /* regexec.c */,
+				F96D3ED708F272A7004A47F5 /* regfree.c */,
+				F96D3ED808F272A7004A47F5 /* regfronts.c */,
+				F96D3ED908F272A7004A47F5 /* regguts.h */,
+				F96D3EDA08F272A7004A47F5 /* tcl.decls */,
+				F96D3EDB08F272A7004A47F5 /* tcl.h */,
+				F96D3EDC08F272A7004A47F5 /* tclAlloc.c */,
+				F96D3EDD08F272A7004A47F5 /* tclAsync.c */,
+				F96D3EDE08F272A7004A47F5 /* tclBasic.c */,
+				F96D3EDF08F272A7004A47F5 /* tclBinary.c */,
+				F96D3EE008F272A7004A47F5 /* tclCkalloc.c */,
+				F96D3EE108F272A7004A47F5 /* tclClock.c */,
+				F96D3EE208F272A7004A47F5 /* tclCmdAH.c */,
+				F96D3EE308F272A7004A47F5 /* tclCmdIL.c */,
+				F96D3EE408F272A7004A47F5 /* tclCmdMZ.c */,
+				F96D3EE508F272A7004A47F5 /* tclCompCmds.c */,
+				F96D3EE608F272A7004A47F5 /* tclCompExpr.c */,
+				F96D3EE708F272A7004A47F5 /* tclCompile.c */,
+				F96D3EE808F272A7004A47F5 /* tclCompile.h */,
+				F96D3EE908F272A7004A47F5 /* tclConfig.c */,
+				F96D3EEA08F272A7004A47F5 /* tclDate.c */,
+				F96D3EEB08F272A7004A47F5 /* tclDecls.h */,
+				F96D3EEC08F272A7004A47F5 /* tclDictObj.c */,
+				F9F4415D0C8BAE6F00BCCD67 /* tclDTrace.d */,
+				F96D3EED08F272A7004A47F5 /* tclEncoding.c */,
+				F96D3EEE08F272A7004A47F5 /* tclEnv.c */,
+				F96D3EEF08F272A7004A47F5 /* tclEvent.c */,
+				F96D3EF008F272A7004A47F5 /* tclExecute.c */,
+				F96D3EF108F272A7004A47F5 /* tclFCmd.c */,
+				F96D3EF208F272A7004A47F5 /* tclFileName.c */,
+				F96D3EF308F272A7004A47F5 /* tclFileSystem.h */,
+				F96D3EF408F272A7004A47F5 /* tclGet.c */,
+				F96D3EF508F272A7004A47F5 /* tclGetDate.y */,
+				F96D3EF608F272A7004A47F5 /* tclHash.c */,
+				F96D3EF708F272A7004A47F5 /* tclHistory.c */,
+				F96D3EF808F272A7004A47F5 /* tclIndexObj.c */,
+				F96D3EF908F272A7004A47F5 /* tclInt.decls */,
+				F96D3EFA08F272A7004A47F5 /* tclInt.h */,
+				F96D3EFB08F272A7004A47F5 /* tclIntDecls.h */,
+				F96D3EFC08F272A7004A47F5 /* tclInterp.c */,
+				F96D3EFD08F272A7004A47F5 /* tclIntPlatDecls.h */,
+				F96D3EFE08F272A7004A47F5 /* tclIO.c */,
+				F96D3EFF08F272A7004A47F5 /* tclIO.h */,
+				F96D3F0008F272A7004A47F5 /* tclIOCmd.c */,
+				F96D3F0108F272A7004A47F5 /* tclIOGT.c */,
+				F96D3F0208F272A7004A47F5 /* tclIORChan.c */,
+				F95D77E90DFD820D00A8BF6F /* tclIORTrans.c */,
+				F96D3F0308F272A7004A47F5 /* tclIOSock.c */,
+				F96D3F0408F272A7004A47F5 /* tclIOUtil.c */,
+				F96D3F0508F272A7004A47F5 /* tclLink.c */,
+				F96D3F0608F272A7004A47F5 /* tclListObj.c */,
+				F96D3F0708F272A7004A47F5 /* tclLiteral.c */,
+				F96D3F0808F272A7004A47F5 /* tclLoad.c */,
+				F96D3F0908F272A7004A47F5 /* tclLoadNone.c */,
+				F96D3F0A08F272A7004A47F5 /* tclMain.c */,
+				F96D3F0B08F272A7004A47F5 /* tclNamesp.c */,
+				F96D3F0C08F272A7004A47F5 /* tclNotify.c */,
+				F96D3F0D08F272A7004A47F5 /* tclObj.c */,
+				F93599B20DF1F75400E04F67 /* tclOO.c */,
+				F93599B40DF1F75900E04F67 /* tclOO.decls */,
+				F93599B50DF1F75D00E04F67 /* tclOO.h */,
+				F93599B60DF1F76100E04F67 /* tclOOBasic.c */,
+				F93599B80DF1F76600E04F67 /* tclOOCall.c */,
+				F93599BA0DF1F76A00E04F67 /* tclOODecls.h */,
+				F93599BB0DF1F77000E04F67 /* tclOODefineCmds.c */,
+				F93599BD0DF1F77400E04F67 /* tclOOInfo.c */,
+				F93599BF0DF1F77900E04F67 /* tclOOInt.h */,
+				F93599C00DF1F77D00E04F67 /* tclOOIntDecls.h */,
+				F93599C10DF1F78300E04F67 /* tclOOMethod.c */,
+				F93599C30DF1F78800E04F67 /* tclOOStubInit.c */,
+				F93599C50DF1F78D00E04F67 /* tclOOStubLib.c */,
+				F96D3F0E08F272A7004A47F5 /* tclPanic.c */,
+				F96D3F0F08F272A7004A47F5 /* tclParse.c */,
+				F96D3F1108F272A7004A47F5 /* tclPathObj.c */,
+				F96D3F1208F272A7004A47F5 /* tclPipe.c */,
+				F96D3F1308F272A7004A47F5 /* tclPkg.c */,
+				F96D3F1408F272A7004A47F5 /* tclPkgConfig.c */,
+				F96D3F1508F272A7004A47F5 /* tclPlatDecls.h */,
+				F96D3F1608F272A7004A47F5 /* tclPort.h */,
+				F96D3F1708F272A7004A47F5 /* tclPosixStr.c */,
+				F96D3F1808F272A7004A47F5 /* tclPreserve.c */,
+				F96D3F1908F272A7004A47F5 /* tclProc.c */,
+				F96D3F1A08F272A7004A47F5 /* tclRegexp.c */,
+				F96D3F1B08F272A7004A47F5 /* tclRegexp.h */,
+				F96D3F1C08F272A7004A47F5 /* tclResolve.c */,
+				F96D3F1D08F272A7004A47F5 /* tclResult.c */,
+				F96D3F1E08F272A7004A47F5 /* tclScan.c */,
+				F96D3F1F08F272A7004A47F5 /* tclStringObj.c */,
+				F96D3F2408F272A7004A47F5 /* tclStrToD.c */,
+				F96D3F2508F272A7004A47F5 /* tclStubInit.c */,
+				F96D3F2608F272A7004A47F5 /* tclStubLib.c */,
+				F96D3F2708F272A7004A47F5 /* tclTest.c */,
+				F96D3F2808F272A7004A47F5 /* tclTestObj.c */,
+				F96D3F2908F272A7004A47F5 /* tclTestProcBodyObj.c */,
+				F96D3F2A08F272A7004A47F5 /* tclThread.c */,
+				F96D3F2B08F272A7004A47F5 /* tclThreadAlloc.c */,
+				F96D3F2C08F272A7004A47F5 /* tclThreadJoin.c */,
+				F96D3F2D08F272A7004A47F5 /* tclThreadStorage.c */,
+				F96D3F2E08F272A7004A47F5 /* tclThreadTest.c */,
+				F96D3F2F08F272A7004A47F5 /* tclTimer.c */,
+				F9903CAF094FAADA004613E9 /* tclTomMath.decls */,
+				F96D3F3008F272A7004A47F5 /* tclTomMath.h */,
+				F9903CB0094FAADA004613E9 /* tclTomMathDecls.h */,
+				F96D3F3108F272A7004A47F5 /* tclTomMathInterface.c */,
+				F96D3F3208F272A7004A47F5 /* tclTrace.c */,
+				F96D3F3308F272A7004A47F5 /* tclUniData.c */,
+				F96D3F3408F272A7004A47F5 /* tclUtf.c */,
+				F96D3F3508F272A7004A47F5 /* tclUtil.c */,
+				F96D3F3608F272A7004A47F5 /* tclVar.c */,
+				F96437C90EF0D4B2003F468E /* tclZlib.c */,
+				F96D3F3708F272A7004A47F5 /* tommath.h */,
+			);
+			path = generic;
+			sourceTree = "<group>";
+		};
+		F96D3F3808F272A7004A47F5 /* library */ = {
+			isa = PBXGroup;
+			children = (
+				F96D3F3908F272A8004A47F5 /* auto.tcl */,
+				F96D3F3A08F272A8004A47F5 /* clock.tcl */,
+				F96D3F3B08F272A8004A47F5 /* dde */,
+				F96D3F8C08F272A8004A47F5 /* history.tcl */,
+				F96D3F8D08F272A8004A47F5 /* http */,
+				F96D3F9008F272A8004A47F5 /* http1.0 */,
+				F96D3F9308F272A8004A47F5 /* init.tcl */,
+				F96D3F9408F272A8004A47F5 /* msgcat */,
+				F96D401708F272AA004A47F5 /* opt */,
+				F96D401A08F272AA004A47F5 /* package.tcl */,
+				F96D401B08F272AA004A47F5 /* parray.tcl */,
+				F9ECB1110B26521500A28025 /* platform */,
+				F96D401C08F272AA004A47F5 /* reg */,
+				F96D401E08F272AA004A47F5 /* safe.tcl */,
+				F96D401F08F272AA004A47F5 /* tclIndex */,
+				F96D402008F272AA004A47F5 /* tcltest */,
+				F96D402308F272AA004A47F5 /* tm.tcl */,
+				F96D425B08F272B2004A47F5 /* word.tcl */,
+			);
+			path = library;
+			sourceTree = "<group>";
+		};
+		F96D3F3B08F272A8004A47F5 /* dde */ = {
+			isa = PBXGroup;
+			children = (
+				F96D3F3C08F272A8004A47F5 /* pkgIndex.tcl */,
+			);
+			path = dde;
+			sourceTree = "<group>";
+		};
+		F96D3F8D08F272A8004A47F5 /* http */ = {
+			isa = PBXGroup;
+			children = (
+				F96D3F8E08F272A8004A47F5 /* http.tcl */,
+				F96D3F8F08F272A8004A47F5 /* pkgIndex.tcl */,
+			);
+			path = http;
+			sourceTree = "<group>";
+		};
+		F96D3F9008F272A8004A47F5 /* http1.0 */ = {
+			isa = PBXGroup;
+			children = (
+				F96D3F9108F272A8004A47F5 /* http.tcl */,
+				F96D3F9208F272A8004A47F5 /* pkgIndex.tcl */,
+			);
+			path = http1.0;
+			sourceTree = "<group>";
+		};
+		F96D3F9408F272A8004A47F5 /* msgcat */ = {
+			isa = PBXGroup;
+			children = (
+				F96D3F9508F272A8004A47F5 /* msgcat.tcl */,
+				F96D3F9608F272A8004A47F5 /* pkgIndex.tcl */,
+			);
+			path = msgcat;
+			sourceTree = "<group>";
+		};
+		F96D401708F272AA004A47F5 /* opt */ = {
+			isa = PBXGroup;
+			children = (
+				F96D401808F272AA004A47F5 /* optparse.tcl */,
+				F96D401908F272AA004A47F5 /* pkgIndex.tcl */,
+			);
+			path = opt;
+			sourceTree = "<group>";
+		};
+		F96D401C08F272AA004A47F5 /* reg */ = {
+			isa = PBXGroup;
+			children = (
+				F96D401D08F272AA004A47F5 /* pkgIndex.tcl */,
+			);
+			path = reg;
+			sourceTree = "<group>";
+		};
+		F96D402008F272AA004A47F5 /* tcltest */ = {
+			isa = PBXGroup;
+			children = (
+				F96D402108F272AA004A47F5 /* pkgIndex.tcl */,
+				F96D402208F272AA004A47F5 /* tcltest.tcl */,
+			);
+			path = tcltest;
+			sourceTree = "<group>";
+		};
+		F96D425C08F272B2004A47F5 /* libtommath */ = {
+			isa = PBXGroup;
+			children = (
+				F96D426408F272B3004A47F5 /* bn_fast_s_mp_mul_digs.c */,
+				F96D426608F272B3004A47F5 /* bn_fast_s_mp_sqr.c */,
+				F96D426908F272B3004A47F5 /* bn_mp_add.c */,
+				F96D426A08F272B3004A47F5 /* bn_mp_add_d.c */,
+				F96D426C08F272B3004A47F5 /* bn_mp_and.c */,
+				F96D426D08F272B3004A47F5 /* bn_mp_clamp.c */,
+				F96D426E08F272B3004A47F5 /* bn_mp_clear.c */,
+				F96D426F08F272B3004A47F5 /* bn_mp_clear_multi.c */,
+				F96D427008F272B3004A47F5 /* bn_mp_cmp.c */,
+				F96D427108F272B3004A47F5 /* bn_mp_cmp_d.c */,
+				F96D427208F272B3004A47F5 /* bn_mp_cmp_mag.c */,
+				F96D427408F272B3004A47F5 /* bn_mp_copy.c */,
+				F96D427508F272B3004A47F5 /* bn_mp_count_bits.c */,
+				F96D427608F272B3004A47F5 /* bn_mp_div.c */,
+				F96D427708F272B3004A47F5 /* bn_mp_div_2.c */,
+				F96D427808F272B3004A47F5 /* bn_mp_div_2d.c */,
+				F96D427908F272B3004A47F5 /* bn_mp_div_3.c */,
+				F96D427A08F272B3004A47F5 /* bn_mp_div_d.c */,
+				F96D427E08F272B3004A47F5 /* bn_mp_exch.c */,
+				F96D427F08F272B3004A47F5 /* bn_mp_expt_d.c */,
+				F96D428708F272B3004A47F5 /* bn_mp_grow.c */,
+				F96D428808F272B3004A47F5 /* bn_mp_init.c */,
+				F96D428908F272B3004A47F5 /* bn_mp_init_copy.c */,
+				F96D428A08F272B3004A47F5 /* bn_mp_init_multi.c */,
+				F96D428B08F272B3004A47F5 /* bn_mp_init_set.c */,
+				F96D428D08F272B3004A47F5 /* bn_mp_init_size.c */,
+				F96D429208F272B3004A47F5 /* bn_mp_karatsuba_mul.c */,
+				F96D429308F272B3004A47F5 /* bn_mp_karatsuba_sqr.c */,
+				F96D429508F272B3004A47F5 /* bn_mp_lshd.c */,
+				F96D429608F272B3004A47F5 /* bn_mp_mod.c */,
+				F96D429708F272B3004A47F5 /* bn_mp_mod_2d.c */,
+				F96D429C08F272B3004A47F5 /* bn_mp_mul.c */,
+				F96D429D08F272B3004A47F5 /* bn_mp_mul_2.c */,
+				F96D429E08F272B3004A47F5 /* bn_mp_mul_2d.c */,
+				F96D429F08F272B3004A47F5 /* bn_mp_mul_d.c */,
+				F96D42A208F272B3004A47F5 /* bn_mp_neg.c */,
+				F96D42A308F272B3004A47F5 /* bn_mp_or.c */,
+				F96D42AB08F272B3004A47F5 /* bn_mp_radix_size.c */,
+				F96D42AC08F272B3004A47F5 /* bn_mp_radix_smap.c */,
+				F96D42AE08F272B3004A47F5 /* bn_mp_read_radix.c */,
+				F96D42B908F272B3004A47F5 /* bn_mp_rshd.c */,
+				F96D42BA08F272B3004A47F5 /* bn_mp_set.c */,
+				F96D42BC08F272B3004A47F5 /* bn_mp_shrink.c */,
+				F96D42BE08F272B3004A47F5 /* bn_mp_sqr.c */,
+				F96D42C008F272B3004A47F5 /* bn_mp_sqrt.c */,
+				F96D42C108F272B3004A47F5 /* bn_mp_sub.c */,
+				F96D42C208F272B3004A47F5 /* bn_mp_sub_d.c */,
+				F96D42C608F272B3004A47F5 /* bn_mp_to_unsigned_bin.c */,
+				F96D42C708F272B3004A47F5 /* bn_mp_to_unsigned_bin_n.c */,
+				F96D42C808F272B3004A47F5 /* bn_mp_toom_mul.c */,
+				F96D42C908F272B3004A47F5 /* bn_mp_toom_sqr.c */,
+				F96D42CB08F272B3004A47F5 /* bn_mp_toradix_n.c */,
+				F96D42CC08F272B3004A47F5 /* bn_mp_unsigned_bin_size.c */,
+				F96D42CD08F272B3004A47F5 /* bn_mp_xor.c */,
+				F96D42CE08F272B3004A47F5 /* bn_mp_zero.c */,
+				F96D42D008F272B3004A47F5 /* bn_reverse.c */,
+				F96D42D108F272B3004A47F5 /* bn_s_mp_add.c */,
+				F96D42D308F272B3004A47F5 /* bn_s_mp_mul_digs.c */,
+				F96D42D508F272B3004A47F5 /* bn_s_mp_sqr.c */,
+				F96D42D608F272B3004A47F5 /* bn_s_mp_sub.c */,
+				F96D42D708F272B3004A47F5 /* bncore.c */,
+				F96D432908F272B4004A47F5 /* tommath_class.h */,
+				F96D432A08F272B4004A47F5 /* tommath_superclass.h */,
+			);
+			path = libtommath;
+			sourceTree = "<group>";
+		};
+		F96D432C08F272B4004A47F5 /* macosx */ = {
+			isa = PBXGroup;
+			children = (
+				F96D432E08F272B5004A47F5 /* configure.ac */,
+				F96D432F08F272B5004A47F5 /* GNUmakefile */,
+				F96D433108F272B5004A47F5 /* README */,
+				F96D433908F272B5004A47F5 /* tclMacOSXBundle.c */,
+				F96D433D08F272B5004A47F5 /* tclMacOSXFCmd.c */,
+				F96D433E08F272B5004A47F5 /* tclMacOSXNotify.c */,
+				F96D433208F272B5004A47F5 /* Tcl-Info.plist.in */,
+				F91E62260C1AE686006C9D96 /* Tclsh-Info.plist.in */,
+				F97AE7F10B65C1E900310EA2 /* Tcl-Common.xcconfig */,
+				F97AE8330B65C87F00310EA2 /* Tcl-Debug.xcconfig */,
+				F97AE82B0B65C69B00310EA2 /* Tcl-Release.xcconfig */,
+			);
+			path = macosx;
+			sourceTree = "<group>";
+		};
+		F96D434408F272B5004A47F5 /* tests */ = {
+			isa = PBXGroup;
+			children = (
+				F96D434508F272B5004A47F5 /* all.tcl */,
+				F96D434608F272B5004A47F5 /* append.test */,
+				F96D434708F272B5004A47F5 /* appendComp.test */,
+				F9ECB1CA0B2652D300A28025 /* apply.test */,
+				F96D434808F272B5004A47F5 /* assocd.test */,
+				F96D434908F272B5004A47F5 /* async.test */,
+				F96D434A08F272B5004A47F5 /* autoMkindex.test */,
+				F96D434B08F272B5004A47F5 /* basic.test */,
+				F96D434C08F272B5004A47F5 /* binary.test */,
+				F96D434D08F272B5004A47F5 /* case.test */,
+				F96D434E08F272B5004A47F5 /* chan.test */,
+				F9A493240CEBF38300B78AE2 /* chanio.test */,
+				F96D434F08F272B5004A47F5 /* clock.test */,
+				F96D435008F272B5004A47F5 /* cmdAH.test */,
+				F96D435108F272B5004A47F5 /* cmdIL.test */,
+				F96D435208F272B5004A47F5 /* cmdInfo.test */,
+				F96D435308F272B5004A47F5 /* cmdMZ.test */,
+				F96D435408F272B5004A47F5 /* compExpr-old.test */,
+				F96D435508F272B5004A47F5 /* compExpr.test */,
+				F96D435608F272B5004A47F5 /* compile.test */,
+				F96D435708F272B5004A47F5 /* concat.test */,
+				F96D435808F272B5004A47F5 /* config.test */,
+				F974D5770FBE7E6100BF728B /* coroutine.test */,
+				F96D435908F272B5004A47F5 /* dcall.test */,
+				F96D435A08F272B5004A47F5 /* dict.test */,
+				F96D435C08F272B5004A47F5 /* dstring.test */,
+				F96D435E08F272B5004A47F5 /* encoding.test */,
+				F96D435F08F272B5004A47F5 /* env.test */,
+				F96D436008F272B5004A47F5 /* error.test */,
+				F96D436108F272B5004A47F5 /* eval.test */,
+				F96D436208F272B5004A47F5 /* event.test */,
+				F96D436308F272B5004A47F5 /* exec.test */,
+				F96D436408F272B5004A47F5 /* execute.test */,
+				F96D436508F272B5004A47F5 /* expr-old.test */,
+				F96D436608F272B5004A47F5 /* expr.test */,
+				F96D436708F272B6004A47F5 /* fCmd.test */,
+				F96D436808F272B6004A47F5 /* fileName.test */,
+				F96D436908F272B6004A47F5 /* fileSystem.test */,
+				F96D436A08F272B6004A47F5 /* for-old.test */,
+				F96D436B08F272B6004A47F5 /* for.test */,
+				F96D436C08F272B6004A47F5 /* foreach.test */,
+				F96D436D08F272B6004A47F5 /* format.test */,
+				F96D436E08F272B6004A47F5 /* get.test */,
+				F96D436F08F272B6004A47F5 /* history.test */,
+				F96D437008F272B6004A47F5 /* http.test */,
+				F974D56C0FBE7D6300BF728B /* http11.test */,
+				F96D437108F272B6004A47F5 /* httpd */,
+				F974D56D0FBE7D6300BF728B /* httpd11.tcl */,
+				F96D437208F272B6004A47F5 /* httpold.test */,
+				F96D437308F272B6004A47F5 /* if-old.test */,
+				F96D437408F272B6004A47F5 /* if.test */,
+				F96D437508F272B6004A47F5 /* incr-old.test */,
+				F96D437608F272B6004A47F5 /* incr.test */,
+				F96D437708F272B6004A47F5 /* indexObj.test */,
+				F96D437808F272B6004A47F5 /* info.test */,
+				F96D437908F272B6004A47F5 /* init.test */,
+				F96D437A08F272B6004A47F5 /* interp.test */,
+				F96D437B08F272B6004A47F5 /* io.test */,
+				F96D437C08F272B6004A47F5 /* ioCmd.test */,
+				F96D437D08F272B6004A47F5 /* iogt.test */,
+				F96D437F08F272B6004A47F5 /* join.test */,
+				F96D438008F272B6004A47F5 /* lindex.test */,
+				F96D438108F272B6004A47F5 /* link.test */,
+				F96D438208F272B6004A47F5 /* linsert.test */,
+				F96D438308F272B6004A47F5 /* list.test */,
+				F96D438408F272B6004A47F5 /* listObj.test */,
+				F96D438508F272B6004A47F5 /* llength.test */,
+				F96D438608F272B6004A47F5 /* load.test */,
+				F96D438708F272B6004A47F5 /* lrange.test */,
+				F96D438808F272B6004A47F5 /* lrepeat.test */,
+				F96D438908F272B6004A47F5 /* lreplace.test */,
+				F96D438A08F272B6004A47F5 /* lsearch.test */,
+				F96D438B08F272B6004A47F5 /* lset.test */,
+				F96D438C08F272B6004A47F5 /* lsetComp.test */,
+				F96D438D08F272B6004A47F5 /* macOSXFCmd.test */,
+				F95FAFF90B34F1130072E431 /* macOSXLoad.test */,
+				F96D438E08F272B6004A47F5 /* main.test */,
+				F9ECB1CB0B26534C00A28025 /* mathop.test */,
+				F96D438F08F272B6004A47F5 /* misc.test */,
+				F96D439008F272B6004A47F5 /* msgcat.test */,
+				F96D439108F272B6004A47F5 /* namespace-old.test */,
+				F96D439208F272B7004A47F5 /* namespace.test */,
+				F96D439308F272B7004A47F5 /* notify.test */,
+				F91DC23C0E44C51B002CB8D1 /* nre.test */,
+				F96D439408F272B7004A47F5 /* obj.test */,
+				F93599C80DF1F81900E04F67 /* oo.test */,
+				F96D439508F272B7004A47F5 /* opt.test */,
+				F96D439608F272B7004A47F5 /* package.test */,
+				F96D439708F272B7004A47F5 /* parse.test */,
+				F96D439808F272B7004A47F5 /* parseExpr.test */,
+				F96D439908F272B7004A47F5 /* parseOld.test */,
+				F96D439A08F272B7004A47F5 /* pid.test */,
+				F96D439B08F272B7004A47F5 /* pkg.test */,
+				F96D439C08F272B7004A47F5 /* pkgMkIndex.test */,
+				F96D439D08F272B7004A47F5 /* platform.test */,
+				F96D439E08F272B7004A47F5 /* proc-old.test */,
+				F96D439F08F272B7004A47F5 /* proc.test */,
+				F96D43A008F272B7004A47F5 /* pwd.test */,
+				F96D43A108F272B7004A47F5 /* README */,
+				F96D43A208F272B7004A47F5 /* reg.test */,
+				F96D43A308F272B7004A47F5 /* regexp.test */,
+				F96D43A408F272B7004A47F5 /* regexpComp.test */,
+				F96D43A508F272B7004A47F5 /* registry.test */,
+				F96D43A608F272B7004A47F5 /* remote.tcl */,
+				F96D43A708F272B7004A47F5 /* rename.test */,
+				F96D43A808F272B7004A47F5 /* result.test */,
+				F96D43A908F272B7004A47F5 /* safe.test */,
+				F96D43AA08F272B7004A47F5 /* scan.test */,
+				F96D43AB08F272B7004A47F5 /* security.test */,
+				F96D43AC08F272B7004A47F5 /* set-old.test */,
+				F96D43AD08F272B7004A47F5 /* set.test */,
+				F96D43AE08F272B7004A47F5 /* socket.test */,
+				F96D43AF08F272B7004A47F5 /* source.test */,
+				F96D43B008F272B7004A47F5 /* split.test */,
+				F96D43B108F272B7004A47F5 /* stack.test */,
+				F96D43B208F272B7004A47F5 /* string.test */,
+				F96D43B308F272B7004A47F5 /* stringComp.test */,
+				F96D43B408F272B7004A47F5 /* stringObj.test */,
+				F96D43B508F272B7004A47F5 /* subst.test */,
+				F96D43B608F272B7004A47F5 /* switch.test */,
+				F974D5780FBE7E6100BF728B /* tailcall.test */,
+				F96D43B708F272B7004A47F5 /* tcltest.test */,
+				F96D43B808F272B7004A47F5 /* thread.test */,
+				F96D43B908F272B7004A47F5 /* timer.test */,
+				F96D43BA08F272B7004A47F5 /* tm.test */,
+				F96D43BB08F272B7004A47F5 /* trace.test */,
+				F96D43BC08F272B7004A47F5 /* unixFCmd.test */,
+				F96D43BD08F272B7004A47F5 /* unixFile.test */,
+				F96D43BE08F272B7004A47F5 /* unixInit.test */,
+				F96D43BF08F272B7004A47F5 /* unixNotfy.test */,
+				F96D43C008F272B7004A47F5 /* unknown.test */,
+				F96D43C108F272B7004A47F5 /* unload.test */,
+				F96D43C208F272B7004A47F5 /* uplevel.test */,
+				F96D43C308F272B7004A47F5 /* upvar.test */,
+				F96D43C408F272B7004A47F5 /* utf.test */,
+				F96D43C508F272B7004A47F5 /* util.test */,
+				F96D43C608F272B7004A47F5 /* var.test */,
+				F96D43C708F272B7004A47F5 /* while-old.test */,
+				F96D43C808F272B7004A47F5 /* while.test */,
+				F96D43C908F272B7004A47F5 /* winConsole.test */,
+				F96D43CA08F272B7004A47F5 /* winDde.test */,
+				F96D43CB08F272B7004A47F5 /* winFCmd.test */,
+				F96D43CC08F272B7004A47F5 /* winFile.test */,
+				F96D43CD08F272B7004A47F5 /* winNotify.test */,
+				F96D43CE08F272B7004A47F5 /* winPipe.test */,
+				F96D43CF08F272B7004A47F5 /* winTime.test */,
+				F915432A0EF201CF0032D1E8 /* zlib.test */,
+			);
+			path = tests;
+			sourceTree = "<group>";
+		};
+		F96D43D008F272B8004A47F5 /* tools */ = {
+			isa = PBXGroup;
+			children = (
+				F96D43D108F272B8004A47F5 /* checkLibraryDoc.tcl */,
+				F96D43D208F272B8004A47F5 /* configure */,
+				F96D43D308F272B8004A47F5 /* configure.in */,
+				F96D442408F272B8004A47F5 /* fix_tommath_h.tcl */,
+				F96D442508F272B8004A47F5 /* genStubs.tcl */,
+				F96D442708F272B8004A47F5 /* index.tcl */,
+				F96D442808F272B8004A47F5 /* installData.tcl */,
+				F96D442908F272B8004A47F5 /* loadICU.tcl */,
+				F96D442A08F272B8004A47F5 /* Makefile.in */,
+				F96D442B08F272B8004A47F5 /* makeTestCases.tcl */,
+				F96D442C08F272B8004A47F5 /* man2help.tcl */,
+				F96D442D08F272B8004A47F5 /* man2help2.tcl */,
+				F96D442E08F272B8004A47F5 /* man2html.tcl */,
+				F96D442F08F272B8004A47F5 /* man2html1.tcl */,
+				F96D443008F272B8004A47F5 /* man2html2.tcl */,
+				F96D443108F272B8004A47F5 /* man2tcl.c */,
+				F96D443208F272B8004A47F5 /* README */,
+				F96D443308F272B8004A47F5 /* regexpTestLib.tcl */,
+				F96D443508F272B8004A47F5 /* tcl.hpj.in */,
+				F96D443908F272B9004A47F5 /* tcltk-man2html.tcl */,
+				F96D443A08F272B9004A47F5 /* tclZIC.tcl */,
+				F92D7F100DE777240033A13A /* tsdPerf.tcl */,
+				F96D443B08F272B9004A47F5 /* uniClass.tcl */,
+				F96D443C08F272B9004A47F5 /* uniParse.tcl */,
+			);
+			path = tools;
+			sourceTree = "<group>";
+		};
+		F96D443E08F272B9004A47F5 /* unix */ = {
+			isa = PBXGroup;
+			children = (
+				F96D444008F272B9004A47F5 /* aclocal.m4 */,
+				F96D444108F272B9004A47F5 /* configure */,
+				F96D444208F272B9004A47F5 /* configure.in */,
+				F96D444308F272B9004A47F5 /* dltest */,
+				F96D444D08F272B9004A47F5 /* install-sh */,
+				F96D444E08F272B9004A47F5 /* installManPage */,
+				F96D444F08F272B9004A47F5 /* ldAix */,
+				F96D445008F272B9004A47F5 /* Makefile.in */,
+				F96D445208F272B9004A47F5 /* README */,
+				F96D445308F272B9004A47F5 /* tcl.m4 */,
+				F974D5790FBE7E9C00BF728B /* tcl.pc.in */,
+				F96D445408F272B9004A47F5 /* tcl.spec */,
+				F96D445508F272B9004A47F5 /* tclAppInit.c */,
+				F96D445608F272B9004A47F5 /* tclConfig.h.in */,
+				F96D445708F272B9004A47F5 /* tclConfig.sh.in */,
+				F96D445808F272B9004A47F5 /* tclLoadAix.c */,
+				F96D445908F272B9004A47F5 /* tclLoadDl.c */,
+				F96D445B08F272B9004A47F5 /* tclLoadDyld.c */,
+				F96D445C08F272B9004A47F5 /* tclLoadNext.c */,
+				F96D445D08F272B9004A47F5 /* tclLoadOSF.c */,
+				F96D445E08F272B9004A47F5 /* tclLoadShl.c */,
+				F96D445F08F272B9004A47F5 /* tclUnixChan.c */,
+				F9FC77B70AB29E9100B7077D /* tclUnixCompat.c */,
+				F96D446008F272B9004A47F5 /* tclUnixEvent.c */,
+				F96D446108F272B9004A47F5 /* tclUnixFCmd.c */,
+				F96D446208F272B9004A47F5 /* tclUnixFile.c */,
+				F96D446308F272B9004A47F5 /* tclUnixInit.c */,
+				F96D446408F272B9004A47F5 /* tclUnixNotfy.c */,
+				F96D446508F272B9004A47F5 /* tclUnixPipe.c */,
+				F96D446608F272B9004A47F5 /* tclUnixPort.h */,
+				F96D446708F272B9004A47F5 /* tclUnixSock.c */,
+				F96D446808F272B9004A47F5 /* tclUnixTest.c */,
+				F96D446908F272B9004A47F5 /* tclUnixThrd.c */,
+				F96D446B08F272B9004A47F5 /* tclUnixTime.c */,
+				F96D446C08F272B9004A47F5 /* tclXtNotify.c */,
+				F96D446D08F272B9004A47F5 /* tclXtTest.c */,
+			);
+			path = unix;
+			sourceTree = "<group>";
+		};
+		F96D444308F272B9004A47F5 /* dltest */ = {
+			isa = PBXGroup;
+			children = (
+				F96D444408F272B9004A47F5 /* Makefile.in */,
+				F96D444508F272B9004A47F5 /* pkga.c */,
+				F96D444608F272B9004A47F5 /* pkgb.c */,
+				F96D444708F272B9004A47F5 /* pkgc.c */,
+				F96D444808F272B9004A47F5 /* pkgd.c */,
+				F96D444908F272B9004A47F5 /* pkge.c */,
+				F96D444B08F272B9004A47F5 /* pkgua.c */,
+				F96D444C08F272B9004A47F5 /* README */,
+			);
+			path = dltest;
+			sourceTree = "<group>";
+		};
+		F96D446E08F272B9004A47F5 /* win */ = {
+			isa = PBXGroup;
+			children = (
+				F96D447008F272BA004A47F5 /* aclocal.m4 */,
+				F96D447108F272BA004A47F5 /* buildall.vc.bat */,
+				F96D447208F272BA004A47F5 /* cat.c */,
+				F96D447308F272BA004A47F5 /* coffbase.txt */,
+				F96D447408F272BA004A47F5 /* configure */,
+				F96D447508F272BA004A47F5 /* configure.in */,
+				F96D447608F272BA004A47F5 /* makefile.bc */,
+				F96D447708F272BA004A47F5 /* Makefile.in */,
+				F96D447808F272BA004A47F5 /* makefile.vc */,
+				F96D447908F272BA004A47F5 /* nmakehlp.c */,
+				F96D447A08F272BA004A47F5 /* README */,
+				F96D447C08F272BA004A47F5 /* rules.vc */,
+				F96D447D08F272BA004A47F5 /* stub16.c */,
+				F96D447E08F272BA004A47F5 /* tcl.dsp */,
+				F96D447F08F272BA004A47F5 /* tcl.dsw */,
+				F96D448008F272BA004A47F5 /* tcl.hpj.in */,
+				F96D448108F272BA004A47F5 /* tcl.m4 */,
+				F96D448208F272BA004A47F5 /* tcl.rc */,
+				F96D448308F272BA004A47F5 /* tclAppInit.c */,
+				F96D448408F272BA004A47F5 /* tclConfig.sh.in */,
+				F96D448608F272BA004A47F5 /* tclsh.rc */,
+				F96D448708F272BA004A47F5 /* tclWin32Dll.c */,
+				F96D448808F272BA004A47F5 /* tclWinChan.c */,
+				F96D448908F272BA004A47F5 /* tclWinConsole.c */,
+				F96D448A08F272BA004A47F5 /* tclWinDde.c */,
+				F96D448B08F272BA004A47F5 /* tclWinError.c */,
+				F96D448C08F272BA004A47F5 /* tclWinFCmd.c */,
+				F96D448D08F272BA004A47F5 /* tclWinFile.c */,
+				F96D448E08F272BA004A47F5 /* tclWinInit.c */,
+				F96D448F08F272BA004A47F5 /* tclWinInt.h */,
+				F96D449008F272BA004A47F5 /* tclWinLoad.c */,
+				F96D449108F272BA004A47F5 /* tclWinNotify.c */,
+				F96D449208F272BA004A47F5 /* tclWinPipe.c */,
+				F96D449308F272BA004A47F5 /* tclWinPort.h */,
+				F96D449408F272BA004A47F5 /* tclWinReg.c */,
+				F96D449508F272BA004A47F5 /* tclWinSerial.c */,
+				F96D449608F272BA004A47F5 /* tclWinSock.c */,
+				F96D449708F272BA004A47F5 /* tclWinTest.c */,
+				F96D449808F272BA004A47F5 /* tclWinThrd.c */,
+				F96D449908F272BA004A47F5 /* tclWinThrd.h */,
+				F96D449A08F272BA004A47F5 /* tclWinTime.c */,
+			);
+			path = win;
+			sourceTree = "<group>";
+		};
+		F9ECB1110B26521500A28025 /* platform */ = {
+			isa = PBXGroup;
+			children = (
+				F9ECB1120B26521500A28025 /* pkgIndex.tcl */,
+				F9ECB1130B26521500A28025 /* platform.tcl */,
+				F9ECB1140B26521500A28025 /* shell.tcl */,
+			);
+			path = platform;
+			sourceTree = "<group>";
+		};
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+		8DD76FA90486AB0100D96B5E /* tcltest */ = {
+			isa = PBXNativeTarget;
+			buildConfigurationList = F95CC8B009158F3100EA5ACE /* Build configuration list for PBXNativeTarget "tcltest" */;
+			buildPhases = (
+				F9A5C5F508F651A2008AE941 /* Configure Tcl */,
+				8DD76FAB0486AB0100D96B5E /* Sources */,
+				8DD76FAD0486AB0100D96B5E /* Frameworks */,
+				F95FA74C0B32CE190072E431 /* Build dltest */,
+			);
+			buildRules = (
+			);
+			dependencies = (
+			);
+			name = tcltest;
+			productInstallPath = "$(BINDIR)";
+			productName = tcltest;
+			productReference = 8DD76FB20486AB0100D96B5E /* tcltest */;
+			productType = "com.apple.product-type.tool";
+		};
+		F97258A50A86873C00096C78 /* tests */ = {
+			isa = PBXNativeTarget;
+			buildConfigurationList = F97258A80A86873D00096C78 /* Build configuration list for PBXNativeTarget "tests" */;
+			buildPhases = (
+				F97258A40A86873C00096C78 /* Run Testsuite */,
+			);
+			buildRules = (
+			);
+			dependencies = (
+				F97258D30A868C6F00096C78 /* PBXTargetDependency */,
+			);
+			name = tests;
+			productName = tests;
+			productType = "com.apple.product-type.bundle";
+		};
+		F9E61D16090A3E94002B3151 /* Tcl */ = {
+			isa = PBXNativeTarget;
+			buildConfigurationList = F95CC8AB09158F3100EA5ACE /* Build configuration list for PBXNativeTarget "Tcl" */;
+			buildPhases = (
+				F97AF02F0B665DA900310EA2 /* Build Tcl */,
+			);
+			buildRules = (
+			);
+			dependencies = (
+			);
+			name = Tcl;
+			productName = tclsh;
+			productReference = F9A3084B08F2D4CE00BAE1AB /* tclsh */;
+			productType = "com.apple.product-type.tool";
+		};
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+		08FB7793FE84155DC02AAC07 /* Project object */ = {
+			isa = PBXProject;
+			attributes = {
+				BuildIndependentTargetsInParallel = YES;
+			};
+			buildConfigurationList = F95CC8B509158F3100EA5ACE /* Build configuration list for PBXProject "Tcl" */;
+			compatibilityVersion = "Xcode 3.1";
+			hasScannedForEncodings = 1;
+			mainGroup = 08FB7794FE84155DC02AAC07 /* Tcl */;
+			projectDirPath = "";
+			projectRoot = ..;
+			targets = (
+				F9E61D16090A3E94002B3151 /* Tcl */,
+				8DD76FA90486AB0100D96B5E /* tcltest */,
+				F97258A50A86873C00096C78 /* tests */,
+			);
+		};
+/* End PBXProject section */
+
+/* Begin PBXShellScriptBuildPhase section */
+		F95FA74C0B32CE190072E431 /* Build dltest */ = {
+			isa = PBXShellScriptBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			inputPaths = (
+				"$(DERIVED_FILE_DIR)/tcl/tclConfig.sh",
+				"$(TCL_SRCROOT)/generic/tclStubLib.c",
+				"$(TCL_SRCROOT)/unix/dltest/pkga.c",
+				"$(TCL_SRCROOT)/unix/dltest/pkgb.c",
+				"$(TCL_SRCROOT)/unix/dltest/pkgc.c",
+				"$(TCL_SRCROOT)/unix/dltest/pkgd.c",
+				"$(TCL_SRCROOT)/unix/dltest/pkge.c",
+				"$(TCL_SRCROOT)/unix/dltest/pkgua.c",
+			);
+			name = "Build dltest";
+			outputPaths = (
+				"$(DERIVED_FILE_DIR)/tcl/dltest.marker",
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+			shellPath = /bin/bash;
+			shellScript = "## dltest build script phase\n\nrm -f \"${DERIVED_FILE_DIR}/tcl/dltest.marker\"\nmake -C \"${DERIVED_FILE_DIR}/tcl\" dltest.marker\nln -fsh \"${DERIVED_FILE_DIR}/tcl/dltest\" \"${CONFIGURATION_BUILD_DIR}\"\n";
+			showEnvVarsInLog = 0;
+		};
+		F97258A40A86873C00096C78 /* Run Testsuite */ = {
+			isa = PBXShellScriptBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			inputPaths = (
+			);
+			name = "Run Testsuite";
+			outputPaths = (
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+			shellPath = /bin/bash;
+			shellScript = "if [ \"${ACTION:-build}\" == \"build\" ]; then\nif [ -z \"${HOME}\" ]; then export HOME=\"$(echo ~)\"; fi\ncd \"${TARGET_TEMP_DIR}\"; rm -rf \"${DERIVED_FILE_DIR}\"; mkdir -p \"${DERIVED_FILE_DIR}\"\nprintf '%s%s%s%s%s' '\npackage require tcltest 2.2\nnamespace import tcltest::*\nconfigure -testdir [file normalize {' \"${TCL_SRCROOT}\" '/tests}]\nconfigure -tmpdir [file normalize {' \"${DERIVED_FILE_DIR}\" '}]\nconfigure -verbose [concat [configure -verbose] line]\nrunAllTests\n' | \"${TEST_RIG}\"; TEST_RIG_RESULT=$?\n[ ${TEST_RIG_RESULT} -ne 0 ] && echo \"tcltest:0: error: tcltest exited abnormally with code ${TEST_RIG_RESULT}.\"\nexit ${TEST_RIG_RESULT}\nfi";
+			showEnvVarsInLog = 0;
+		};
+		F97AF02F0B665DA900310EA2 /* Build Tcl */ = {
+			isa = PBXShellScriptBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			inputPaths = (
+				"${TARGET_TEMP_DIR}/.none",
+			);
+			name = "Build Tcl";
+			outputPaths = (
+				"${TARGET_BUILD_DIR}/${EXECUTABLE_NAME}",
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+			shellPath = /bin/bash;
+			shellScript = "if [ -e \"${TARGET_BUILD_DIR}/tclsh\" ]; then\n    mv -f \"${TARGET_BUILD_DIR}/tclsh\" \"${TARGET_BUILD_DIR}/tclsh${VERSION}\"\nfi\nexport CC=$(xcrun -find ${GCC} || echo ${GCC}); export LD=${CC}\ngnumake -C \"${TCL_SRCROOT}/macosx\" -j \"$(sysctl -n hw.activecpu)\" \"$(echo \"${ACTION}\" | sed -e s/build// -e s/clean/distclean/ -e s/..\\*/\\&-/)${MAKE_TARGET}\" CFLAGS_WARNING=\"${WARNING_CFLAGS}\" CFLAGS_OPTIMIZE=\"-O${GCC_OPTIMIZATION_LEVEL}\" SYMROOT=\"${BUILT_PRODUCTS_DIR}\" OBJ_DIR=\"${OBJECT_FILE_DIR}\" INSTALL_ROOT=\"${DSTROOT}\" PREFIX=\"${PREFIX}\" BINDIR=\"${BINDIR}\" LIBDIR=\"${FRAMEWORK_INSTALL_PATH}\" MANDIR=\"${MANDIR}\" EXTRA_CONFIGURE_ARGS=\"${CONFIGURE_ARGS}\" ${EXTRA_MAKE_FLAGS}\nresult=$?\nif [ -e \"${TARGET_BUILD_DIR}/tclsh${VERSION}\" ]; then\n    mv -f \"${TARGET_BUILD_DIR}/tclsh${VERSION}\" \"${TARGET_BUILD_DIR}/tclsh\"\nfi\nif [ -e \"${BUILT_PRODUCTS_DIR}/tcltest\" ]; then\n\trm -f \"${BUILT_PRODUCTS_DIR}/tcltest\"\nfi\necho \"Done\"\nrm -f \"${SCRIPT_INPUT_FILE_0}\"\nexit ${result}\n";
+			showEnvVarsInLog = 0;
+		};
+		F9A5C5F508F651A2008AE941 /* Configure Tcl */ = {
+			isa = PBXShellScriptBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			inputPaths = (
+				"$(TCL_SRCROOT)/macosx/configure.ac",
+				"$(TCL_SRCROOT)/unix/configure.in",
+				"$(TCL_SRCROOT)/unix/tcl.m4",
+				"$(TCL_SRCROOT)/unix/aclocal.m4",
+				"$(TCL_SRCROOT)/unix/tclConfig.sh.in",
+				"$(TCL_SRCROOT)/unix/Makefile.in",
+				"$(TCL_SRCROOT)/unix/dltest/Makefile.in",
+			);
+			name = "Configure Tcl";
+			outputPaths = (
+				"$(DERIVED_FILE_DIR)/tcl/tclConfig.sh",
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+			shellPath = /bin/bash;
+			shellScript = "## tcl configure shell script phase\n\ncd \"${TCL_SRCROOT}\"/macosx &&\nif [ configure.ac -nt configure -o ../unix/configure.in -nt configure -o ../unix/tcl.m4 -nt configure -o ../unix/aclocal.m4 -nt configure ]; then\n    echo \"Running autoconf & autoheader in tcl/macosx\"\n    rm -rf autom4te.cache\n    ${AUTOCONF:-${DEVELOPER_DIR}/usr/bin/autoconf} && ${AUTOHEADER:-${DEVELOPER_DIR}/usr/bin/autoheader} || exit $?\n    rm -rf autom4te.cache\nfi\n\ncd \"${DERIVED_FILE_DIR}\" && mkdir -p tcl && cd tcl &&\nif [ \"${TCL_SRCROOT}\"/macosx/configure -nt config.status ]; then\n    echo \"Configuring Tcl\"\n    CC=$(xcrun -find ${GCC} || echo ${GCC})\n    \"${TCL_SRCROOT}\"/macosx/configure --cache-file=../config.cache --prefix=${PREFIX} --bindir=${BINDIR} --libdir=${LIBDIR} --mandir=${MANDIR} --includedir=${INCLUDEDIR} --disable-shared CC=${CC} LD=${CC} ${CONFIGURE_ARGS}\nelse\n    ./config.status\nfi\n";
+			showEnvVarsInLog = 0;
+		};
+/* End PBXShellScriptBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+		8DD76FAB0486AB0100D96B5E /* Sources */ = {
+			isa = PBXSourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				F96D456F08F272BB004A47F5 /* regcomp.c in Sources */,
+				F96D457208F272BB004A47F5 /* regerror.c in Sources */,
+				F96D457508F272BB004A47F5 /* regexec.c in Sources */,
+				F96D457608F272BB004A47F5 /* regfree.c in Sources */,
+				F96D457B08F272BB004A47F5 /* tclAlloc.c in Sources */,
+				F96D457C08F272BB004A47F5 /* tclAsync.c in Sources */,
+				F96D457D08F272BB004A47F5 /* tclBasic.c in Sources */,
+				F96D457E08F272BC004A47F5 /* tclBinary.c in Sources */,
+				F96D457F08F272BC004A47F5 /* tclCkalloc.c in Sources */,
+				F96D458008F272BC004A47F5 /* tclClock.c in Sources */,
+				F96D458108F272BC004A47F5 /* tclCmdAH.c in Sources */,
+				F96D458208F272BC004A47F5 /* tclCmdIL.c in Sources */,
+				F96D458308F272BC004A47F5 /* tclCmdMZ.c in Sources */,
+				F96D458408F272BC004A47F5 /* tclCompCmds.c in Sources */,
+				F96D458508F272BC004A47F5 /* tclCompExpr.c in Sources */,
+				F96D458608F272BC004A47F5 /* tclCompile.c in Sources */,
+				F96D458808F272BC004A47F5 /* tclConfig.c in Sources */,
+				F96D458908F272BC004A47F5 /* tclDate.c in Sources */,
+				F96D458B08F272BC004A47F5 /* tclDictObj.c in Sources */,
+				F96D458C08F272BC004A47F5 /* tclEncoding.c in Sources */,
+				F96D458D08F272BC004A47F5 /* tclEnv.c in Sources */,
+				F96D458E08F272BC004A47F5 /* tclEvent.c in Sources */,
+				F96D458F08F272BC004A47F5 /* tclExecute.c in Sources */,
+				F96D459008F272BC004A47F5 /* tclFCmd.c in Sources */,
+				F96D459108F272BC004A47F5 /* tclFileName.c in Sources */,
+				F96D459308F272BC004A47F5 /* tclGet.c in Sources */,
+				F96D459508F272BC004A47F5 /* tclHash.c in Sources */,
+				F96D459608F272BC004A47F5 /* tclHistory.c in Sources */,
+				F96D459708F272BC004A47F5 /* tclIndexObj.c in Sources */,
+				F96D459B08F272BC004A47F5 /* tclInterp.c in Sources */,
+				F96D459D08F272BC004A47F5 /* tclIO.c in Sources */,
+				F96D459F08F272BC004A47F5 /* tclIOCmd.c in Sources */,
+				F96D45A008F272BC004A47F5 /* tclIOGT.c in Sources */,
+				F96D45A108F272BC004A47F5 /* tclIORChan.c in Sources */,
+				F95D77EA0DFD820D00A8BF6F /* tclIORTrans.c in Sources */,
+				F96D45A208F272BC004A47F5 /* tclIOSock.c in Sources */,
+				F96D45A308F272BC004A47F5 /* tclIOUtil.c in Sources */,
+				F96D45A408F272BC004A47F5 /* tclLink.c in Sources */,
+				F96D45A508F272BC004A47F5 /* tclListObj.c in Sources */,
+				F96D45A608F272BC004A47F5 /* tclLiteral.c in Sources */,
+				F96D45A708F272BC004A47F5 /* tclLoad.c in Sources */,
+				F96D45A908F272BC004A47F5 /* tclMain.c in Sources */,
+				F96D45AA08F272BC004A47F5 /* tclNamesp.c in Sources */,
+				F96D45AB08F272BC004A47F5 /* tclNotify.c in Sources */,
+				F96D45AC08F272BC004A47F5 /* tclObj.c in Sources */,
+				F93599B30DF1F75400E04F67 /* tclOO.c in Sources */,
+				F93599B70DF1F76100E04F67 /* tclOOBasic.c in Sources */,
+				F93599B90DF1F76600E04F67 /* tclOOCall.c in Sources */,
+				F93599BC0DF1F77000E04F67 /* tclOODefineCmds.c in Sources */,
+				F93599BE0DF1F77400E04F67 /* tclOOInfo.c in Sources */,
+				F93599C20DF1F78300E04F67 /* tclOOMethod.c in Sources */,
+				F93599C40DF1F78800E04F67 /* tclOOStubInit.c in Sources */,
+				F93599C60DF1F78D00E04F67 /* tclOOStubLib.c in Sources */,
+				F96D45AD08F272BC004A47F5 /* tclPanic.c in Sources */,
+				F96D45AE08F272BC004A47F5 /* tclParse.c in Sources */,
+				F96D45B008F272BC004A47F5 /* tclPathObj.c in Sources */,
+				F96D45B108F272BC004A47F5 /* tclPipe.c in Sources */,
+				F96D45B208F272BC004A47F5 /* tclPkg.c in Sources */,
+				F96D45B308F272BC004A47F5 /* tclPkgConfig.c in Sources */,
+				F96D45B608F272BC004A47F5 /* tclPosixStr.c in Sources */,
+				F96D45B708F272BC004A47F5 /* tclPreserve.c in Sources */,
+				F96D45B808F272BC004A47F5 /* tclProc.c in Sources */,
+				F96D45B908F272BC004A47F5 /* tclRegexp.c in Sources */,
+				F96D45BB08F272BC004A47F5 /* tclResolve.c in Sources */,
+				F96D45BC08F272BC004A47F5 /* tclResult.c in Sources */,
+				F96D45BD08F272BC004A47F5 /* tclScan.c in Sources */,
+				F96D45BE08F272BC004A47F5 /* tclStringObj.c in Sources */,
+				F96D45C308F272BC004A47F5 /* tclStrToD.c in Sources */,
+				F96D45C408F272BC004A47F5 /* tclStubInit.c in Sources */,
+				F96D45C508F272BC004A47F5 /* tclStubLib.c in Sources */,
+				F96D45C608F272BC004A47F5 /* tclTest.c in Sources */,
+				F96D45C708F272BC004A47F5 /* tclTestObj.c in Sources */,
+				F96D45C808F272BC004A47F5 /* tclTestProcBodyObj.c in Sources */,
+				F96D45C908F272BC004A47F5 /* tclThread.c in Sources */,
+				F96D45CA08F272BC004A47F5 /* tclThreadAlloc.c in Sources */,
+				F96D45CB08F272BC004A47F5 /* tclThreadJoin.c in Sources */,
+				F96D45CC08F272BC004A47F5 /* tclThreadStorage.c in Sources */,
+				F96D45CD08F272BC004A47F5 /* tclThreadTest.c in Sources */,
+				F96D45CE08F272BC004A47F5 /* tclTimer.c in Sources */,
+				F96D45D008F272BC004A47F5 /* tclTomMathInterface.c in Sources */,
+				F96D45D108F272BC004A47F5 /* tclTrace.c in Sources */,
+				F96D45D308F272BC004A47F5 /* tclUtf.c in Sources */,
+				F96D45D408F272BC004A47F5 /* tclUtil.c in Sources */,
+				F96D45D508F272BC004A47F5 /* tclVar.c in Sources */,
+				F96437CA0EF0D4B2003F468E /* tclZlib.c in Sources */,
+				F96D48E208F272C3004A47F5 /* bn_fast_s_mp_mul_digs.c in Sources */,
+				F96D48E408F272C3004A47F5 /* bn_fast_s_mp_sqr.c in Sources */,
+				F96D48E708F272C3004A47F5 /* bn_mp_add.c in Sources */,
+				F96D48E808F272C3004A47F5 /* bn_mp_add_d.c in Sources */,
+				F9E61D2B090A48A4002B3151 /* bn_mp_and.c in Sources */,
+				F96D48EB08F272C3004A47F5 /* bn_mp_clamp.c in Sources */,
+				F96D48EC08F272C3004A47F5 /* bn_mp_clear.c in Sources */,
+				F96D48ED08F272C3004A47F5 /* bn_mp_clear_multi.c in Sources */,
+				F96D48EE08F272C3004A47F5 /* bn_mp_cmp.c in Sources */,
+				F9E61D28090A481F002B3151 /* bn_mp_cmp_d.c in Sources */,
+				F96D48F008F272C3004A47F5 /* bn_mp_cmp_mag.c in Sources */,
+				F96D48F208F272C3004A47F5 /* bn_mp_cnt_lsb.c in Sources */,
+				F96D48F208F272C3004A47F5 /* bn_mp_copy.c in Sources */,
+				F96D48F308F272C3004A47F5 /* bn_mp_count_bits.c in Sources */,
+				F96D48F408F272C3004A47F5 /* bn_mp_div.c in Sources */,
+				F96D48F508F272C3004A47F5 /* bn_mp_div_2.c in Sources */,
+				F96D48F608F272C3004A47F5 /* bn_mp_div_2d.c in Sources */,
+				F96D48F708F272C3004A47F5 /* bn_mp_div_3.c in Sources */,
+				F96D48F808F272C3004A47F5 /* bn_mp_div_d.c in Sources */,
+				F96D48FC08F272C3004A47F5 /* bn_mp_exch.c in Sources */,
+				F9E61D2C090A48AC002B3151 /* bn_mp_expt_d.c in Sources */,
+				F96D490508F272C3004A47F5 /* bn_mp_grow.c in Sources */,
+				F96D490608F272C3004A47F5 /* bn_mp_init.c in Sources */,
+				F96D490708F272C3004A47F5 /* bn_mp_init_copy.c in Sources */,
+				F96D490808F272C3004A47F5 /* bn_mp_init_multi.c in Sources */,
+				F96D490908F272C3004A47F5 /* bn_mp_init_set.c in Sources */,
+				F96D490B08F272C3004A47F5 /* bn_mp_init_size.c in Sources */,
+				F96D491008F272C3004A47F5 /* bn_mp_karatsuba_mul.c in Sources */,
+				F96D491108F272C3004A47F5 /* bn_mp_karatsuba_sqr.c in Sources */,
+				F96D491308F272C3004A47F5 /* bn_mp_lshd.c in Sources */,
+				F96D491408F272C3004A47F5 /* bn_mp_mod.c in Sources */,
+				F96D491508F272C3004A47F5 /* bn_mp_mod_2d.c in Sources */,
+				F96D491A08F272C3004A47F5 /* bn_mp_mul.c in Sources */,
+				F96D491B08F272C3004A47F5 /* bn_mp_mul_2.c in Sources */,
+				F96D491C08F272C3004A47F5 /* bn_mp_mul_2d.c in Sources */,
+				F96D491D08F272C3004A47F5 /* bn_mp_mul_d.c in Sources */,
+				F9E61D29090A486C002B3151 /* bn_mp_neg.c in Sources */,
+				F9E61D2E090A48BF002B3151 /* bn_mp_or.c in Sources */,
+				F96D492908F272C3004A47F5 /* bn_mp_radix_size.c in Sources */,
+				F96D492A08F272C3004A47F5 /* bn_mp_radix_smap.c in Sources */,
+				F96D492C08F272C3004A47F5 /* bn_mp_read_radix.c in Sources */,
+				F96D493708F272C3004A47F5 /* bn_mp_rshd.c in Sources */,
+				F96D493808F272C3004A47F5 /* bn_mp_set.c in Sources */,
+				F9E61D2F090A48C7002B3151 /* bn_mp_shrink.c in Sources */,
+				F96D493C08F272C3004A47F5 /* bn_mp_sqr.c in Sources */,
+				F9E61D2A090A4891002B3151 /* bn_mp_sqrt.c in Sources */,
+				F96D493F08F272C3004A47F5 /* bn_mp_sub.c in Sources */,
+				F96D494008F272C3004A47F5 /* bn_mp_sub_d.c in Sources */,
+				F9E61D30090A48E2002B3151 /* bn_mp_to_unsigned_bin_n.c in Sources */,
+				F9E61D31090A48F9002B3151 /* bn_mp_to_unsigned_bin.c in Sources */,
+				F96D494608F272C3004A47F5 /* bn_mp_toom_mul.c in Sources */,
+				F96D494708F272C3004A47F5 /* bn_mp_toom_sqr.c in Sources */,
+				F96D494908F272C3004A47F5 /* bn_mp_toradix_n.c in Sources */,
+				F9E61D32090A48FA002B3151 /* bn_mp_unsigned_bin_size.c in Sources */,
+				F9E61D2D090A48BB002B3151 /* bn_mp_xor.c in Sources */,
+				F96D494C08F272C3004A47F5 /* bn_mp_zero.c in Sources */,
+				F96D494E08F272C3004A47F5 /* bn_reverse.c in Sources */,
+				F96D494F08F272C3004A47F5 /* bn_s_mp_add.c in Sources */,
+				F96D495108F272C3004A47F5 /* bn_s_mp_mul_digs.c in Sources */,
+				F96D495308F272C3004A47F5 /* bn_s_mp_sqr.c in Sources */,
+				F96D495408F272C3004A47F5 /* bn_s_mp_sub.c in Sources */,
+				F96D495508F272C3004A47F5 /* bncore.c in Sources */,
+				F96D49A908F272C4004A47F5 /* tclMacOSXBundle.c in Sources */,
+				F96D49AD08F272C4004A47F5 /* tclMacOSXFCmd.c in Sources */,
+				F96D49AE08F272C4004A47F5 /* tclMacOSXNotify.c in Sources */,
+				F90509300913A72400327603 /* tclAppInit.c in Sources */,
+				F96D4AC608F272C9004A47F5 /* tclLoadDyld.c in Sources */,
+				F96D4ACA08F272C9004A47F5 /* tclUnixChan.c in Sources */,
+				F9FC77B80AB29E9100B7077D /* tclUnixCompat.c in Sources */,
+				F96D4ACB08F272C9004A47F5 /* tclUnixEvent.c in Sources */,
+				F96D4ACC08F272C9004A47F5 /* tclUnixFCmd.c in Sources */,
+				F96D4ACD08F272C9004A47F5 /* tclUnixFile.c in Sources */,
+				F96D4ACE08F272C9004A47F5 /* tclUnixInit.c in Sources */,
+				F96D4ACF08F272C9004A47F5 /* tclUnixNotfy.c in Sources */,
+				F96D4AD008F272C9004A47F5 /* tclUnixPipe.c in Sources */,
+				F96D4AD208F272CA004A47F5 /* tclUnixSock.c in Sources */,
+				F96D4AD308F272CA004A47F5 /* tclUnixTest.c in Sources */,
+				F96D4AD408F272CA004A47F5 /* tclUnixThrd.c in Sources */,
+				F96D4AD608F272CA004A47F5 /* tclUnixTime.c in Sources */,
+				F9F4415E0C8BAE6F00BCCD67 /* tclDTrace.d in Sources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXSourcesBuildPhase section */
+
+/* Begin PBXTargetDependency section */
+		F97258D30A868C6F00096C78 /* PBXTargetDependency */ = {
+			isa = PBXTargetDependency;
+			target = 8DD76FA90486AB0100D96B5E /* tcltest */;
+			targetProxy = F97258D20A868C6F00096C78 /* PBXContainerItemProxy */;
+		};
+/* End PBXTargetDependency section */
+
+/* Begin XCBuildConfiguration section */
+		F91BCC4F093152310042A6BF /* ReleaseUniversal */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				PRODUCT_NAME = tclsh;
+				SKIP_INSTALL = NO;
+			};
+			name = ReleaseUniversal;
+		};
+		F91BCC50093152310042A6BF /* ReleaseUniversal */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				PRODUCT_NAME = tcltest;
+			};
+			name = ReleaseUniversal;
+		};
+		F91BCC51093152310042A6BF /* ReleaseUniversal */ = {
+			isa = XCBuildConfiguration;
+			baseConfigurationReference = F97AE82B0B65C69B00310EA2 /* Tcl-Release.xcconfig */;
+			buildSettings = {
+				ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
+				CFLAGS = "-arch i386 -arch x86_64 -arch ppc $(CFLAGS)";
+				MACOSX_DEPLOYMENT_TARGET = 10.5;
+				PREBINDING = NO;
+			};
+			name = ReleaseUniversal;
+		};
+		F93084370BB93D2800CD0B9E /* DebugMemCompile */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				PRODUCT_NAME = tclsh;
+				SKIP_INSTALL = NO;
+			};
+			name = DebugMemCompile;
+		};
+		F93084380BB93D2800CD0B9E /* DebugMemCompile */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				PRODUCT_NAME = tcltest;
+			};
+			name = DebugMemCompile;
+		};
+		F93084390BB93D2800CD0B9E /* DebugMemCompile */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				CODE_SIGN_IDENTITY = "";
+				PRODUCT_NAME = tests;
+				TCLTEST_OPTIONS = "";
+				TCL_LIBRARY = "$(TCL_SRCROOT)/library";
+				TEST_RIG = "$(OBJROOT)/$(CONFIGURATION)/tcltest";
+			};
+			name = DebugMemCompile;
+		};
+		F930843A0BB93D2800CD0B9E /* DebugMemCompile */ = {
+			isa = XCBuildConfiguration;
+			baseConfigurationReference = F97AE8330B65C87F00310EA2 /* Tcl-Debug.xcconfig */;
+			buildSettings = {
+				ARCHS = (
+					"$(NATIVE_ARCH_64_BIT)",
+					"$(NATIVE_ARCH_32_BIT)",
+				);
+				CONFIGURE_ARGS = "$(CONFIGURE_ARGS) --enable-symbols=all";
+				CPPFLAGS = "-arch $(CURRENT_ARCH) $(CPPFLAGS)";
+				MACOSX_DEPLOYMENT_TARGET = 10.5;
+				ONLY_ACTIVE_ARCH = YES;
+				PREBINDING = NO;
+			};
+			name = DebugMemCompile;
+		};
+		F9359B250DF212DA00E04F67 /* DebugGCov */ = {
+			isa = XCBuildConfiguration;
+			baseConfigurationReference = F97AE8330B65C87F00310EA2 /* Tcl-Debug.xcconfig */;
+			buildSettings = {
+				ARCHS = (
+					"$(NATIVE_ARCH_64_BIT)",
+					"$(NATIVE_ARCH_32_BIT)",
+				);
+				CPPFLAGS = "-arch $(CURRENT_ARCH) $(CPPFLAGS)";
+				GCC_GENERATE_TEST_COVERAGE_FILES = YES;
+				GCC_INSTRUMENT_PROGRAM_FLOW_ARCS = YES;
+				MACOSX_DEPLOYMENT_TARGET = 10.5;
+				ONLY_ACTIVE_ARCH = YES;
+				OTHER_LDFLAGS = (
+					"$(OTHER_LDFLAGS)",
+					"-lgcov",
+				);
+				PREBINDING = NO;
+			};
+			name = DebugGCov;
+		};
+		F9359B260DF212DA00E04F67 /* DebugGCov */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				PRODUCT_NAME = tclsh;
+				SKIP_INSTALL = NO;
+			};
+			name = DebugGCov;
+		};
+		F9359B270DF212DA00E04F67 /* DebugGCov */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				PRODUCT_NAME = tcltest;
+			};
+			name = DebugGCov;
+		};
+		F9359B280DF212DA00E04F67 /* DebugGCov */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				CODE_SIGN_IDENTITY = "";
+				PRODUCT_NAME = tests;
+				TCLTEST_OPTIONS = "";
+				TCL_LIBRARY = "$(TCL_SRCROOT)/library";
+				TEST_RIG = "$(OBJROOT)/$(CONFIGURATION)/tcltest";
+			};
+			name = DebugGCov;
+		};
+		F95CC8AC09158F3100EA5ACE /* Debug */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				PRODUCT_NAME = tclsh;
+				SKIP_INSTALL = NO;
+			};
+			name = Debug;
+		};
+		F95CC8AD09158F3100EA5ACE /* Release */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				PRODUCT_NAME = tclsh;
+				SKIP_INSTALL = NO;
+			};
+			name = Release;
+		};
+		F95CC8AE09158F3100EA5ACE /* DebugNoFixAndContinue */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				PRODUCT_NAME = tclsh;
+				SKIP_INSTALL = NO;
+			};
+			name = DebugNoFixAndContinue;
+		};
+		F95CC8B109158F3100EA5ACE /* Debug */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				CONFIGURE_ARGS = "tcl_cv_cc_visibility_hidden=no $(CONFIGURE_ARGS)";
+				GCC_DYNAMIC_NO_PIC = NO;
+				GCC_ENABLE_FIX_AND_CONTINUE = YES;
+				GCC_PREPROCESSOR_DEFINITIONS = (
+					"__private_extern__=extern",
+					"$(GCC_PREPROCESSOR_DEFINITIONS)",
+				);
+				GCC_SYMBOLS_PRIVATE_EXTERN = NO;
+				PRODUCT_NAME = tcltest;
+			};
+			name = Debug;
+		};
+		F95CC8B209158F3100EA5ACE /* Release */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				PRODUCT_NAME = tcltest;
+			};
+			name = Release;
+		};
+		F95CC8B309158F3100EA5ACE /* DebugNoFixAndContinue */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				PRODUCT_NAME = tcltest;
+			};
+			name = DebugNoFixAndContinue;
+		};
+		F95CC8B609158F3100EA5ACE /* Debug */ = {
+			isa = XCBuildConfiguration;
+			baseConfigurationReference = F97AE8330B65C87F00310EA2 /* Tcl-Debug.xcconfig */;
+			buildSettings = {
+				ARCHS = (
+					"$(NATIVE_ARCH_64_BIT)",
+					"$(NATIVE_ARCH_32_BIT)",
+				);
+				CPPFLAGS = "-arch $(CURRENT_ARCH) $(CPPFLAGS)";
+				MACOSX_DEPLOYMENT_TARGET = 10.5;
+				ONLY_ACTIVE_ARCH = YES;
+				PREBINDING = NO;
+			};
+			name = Debug;
+		};
+		F95CC8B709158F3100EA5ACE /* Release */ = {
+			isa = XCBuildConfiguration;
+			baseConfigurationReference = F97AE82B0B65C69B00310EA2 /* Tcl-Release.xcconfig */;
+			buildSettings = {
+				ARCHS = (
+					"$(NATIVE_ARCH_64_BIT)",
+					"$(NATIVE_ARCH_32_BIT)",
+				);
+				CPPFLAGS = "-arch $(CURRENT_ARCH) $(CPPFLAGS)";
+				MACOSX_DEPLOYMENT_TARGET = 10.5;
+				ONLY_ACTIVE_ARCH = YES;
+				PREBINDING = NO;
+			};
+			name = Release;
+		};
+		F95CC8B809158F3100EA5ACE /* DebugNoFixAndContinue */ = {
+			isa = XCBuildConfiguration;
+			baseConfigurationReference = F97AE8330B65C87F00310EA2 /* Tcl-Debug.xcconfig */;
+			buildSettings = {
+				ARCHS = (
+					"$(NATIVE_ARCH_64_BIT)",
+					"$(NATIVE_ARCH_32_BIT)",
+				);
+				CPPFLAGS = "-arch $(CURRENT_ARCH) $(CPPFLAGS)";
+				MACOSX_DEPLOYMENT_TARGET = 10.5;
+				ONLY_ACTIVE_ARCH = YES;
+				PREBINDING = NO;
+			};
+			name = DebugNoFixAndContinue;
+		};
+		F97258A90A86873D00096C78 /* Debug */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				CODE_SIGN_IDENTITY = "";
+				PRODUCT_NAME = tests;
+				TCLTEST_OPTIONS = "";
+				TCL_LIBRARY = "$(TCL_SRCROOT)/library";
+				TEST_RIG = "$(OBJROOT)/$(CONFIGURATION)/tcltest";
+			};
+			name = Debug;
+		};
+		F97258AA0A86873D00096C78 /* Release */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				CODE_SIGN_IDENTITY = "";
+				PRODUCT_NAME = tests;
+				TCLTEST_OPTIONS = "";
+				TCL_LIBRARY = "$(TCL_SRCROOT)/library";
+				TEST_RIG = "$(OBJROOT)/$(CONFIGURATION)/tcltest";
+			};
+			name = Release;
+		};
+		F97258AB0A86873D00096C78 /* DebugNoFixAndContinue */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				CODE_SIGN_IDENTITY = "";
+				PRODUCT_NAME = tests;
+				TCLTEST_OPTIONS = "";
+				TCL_LIBRARY = "$(TCL_SRCROOT)/library";
+				TEST_RIG = "$(OBJROOT)/$(CONFIGURATION)/tcltest";
+			};
+			name = DebugNoFixAndContinue;
+		};
+		F97258AC0A86873D00096C78 /* ReleaseUniversal */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				CODE_SIGN_IDENTITY = "";
+				PRODUCT_NAME = tests;
+				TCLTEST_OPTIONS = "";
+				TCL_LIBRARY = "$(TCL_SRCROOT)/library";
+				TEST_RIG = "$(OBJROOT)/$(CONFIGURATION)/tcltest";
+			};
+			name = ReleaseUniversal;
+		};
+		F97AED1B0B660B2100310EA2 /* Debug64bit */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				PRODUCT_NAME = tclsh;
+				SKIP_INSTALL = NO;
+			};
+			name = Debug64bit;
+		};
+		F97AED1C0B660B2100310EA2 /* Debug64bit */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				PRODUCT_NAME = tcltest;
+			};
+			name = Debug64bit;
+		};
+		F97AED1D0B660B2100310EA2 /* Debug64bit */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				CODE_SIGN_IDENTITY = "";
+				PRODUCT_NAME = tests;
+				TCLTEST_OPTIONS = "";
+				TCL_LIBRARY = "$(TCL_SRCROOT)/library";
+				TEST_RIG = "$(OBJROOT)/$(CONFIGURATION)/tcltest";
+			};
+			name = Debug64bit;
+		};
+		F97AED1E0B660B2100310EA2 /* Debug64bit */ = {
+			isa = XCBuildConfiguration;
+			baseConfigurationReference = F97AE8330B65C87F00310EA2 /* Tcl-Debug.xcconfig */;
+			buildSettings = {
+				ARCHS = "$(NATIVE_ARCH_64_BIT)";
+				CONFIGURE_ARGS = "--enable-64bit $(CONFIGURE_ARGS)";
+				CPPFLAGS = "-arch $(NATIVE_ARCH_64_BIT) $(CPPFLAGS)";
+				MACOSX_DEPLOYMENT_TARGET = 10.5;
+				PREBINDING = NO;
+			};
+			name = Debug64bit;
+		};
+		F987512F0DE7B57E00B1C9EC /* DebugNoCF */ = {
+			isa = XCBuildConfiguration;
+			baseConfigurationReference = F97AE8330B65C87F00310EA2 /* Tcl-Debug.xcconfig */;
+			buildSettings = {
+				ARCHS = (
+					"$(NATIVE_ARCH_64_BIT)",
+					"$(NATIVE_ARCH_32_BIT)",
+				);
+				CONFIGURE_ARGS = "$(CONFIGURE_ARGS) --disable-corefoundation";
+				CPPFLAGS = "-arch $(CURRENT_ARCH) $(CPPFLAGS)";
+				MACOSX_DEPLOYMENT_TARGET = 10.5;
+				ONLY_ACTIVE_ARCH = YES;
+				PREBINDING = NO;
+			};
+			name = DebugNoCF;
+		};
+		F98751300DE7B57E00B1C9EC /* DebugNoCF */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				PRODUCT_NAME = tclsh;
+				SKIP_INSTALL = NO;
+			};
+			name = DebugNoCF;
+		};
+		F98751310DE7B57E00B1C9EC /* DebugNoCF */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				PRODUCT_NAME = tcltest;
+			};
+			name = DebugNoCF;
+		};
+		F98751320DE7B57E00B1C9EC /* DebugNoCF */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				CODE_SIGN_IDENTITY = "";
+				PRODUCT_NAME = tests;
+				TCLTEST_OPTIONS = "";
+				TCL_LIBRARY = "$(TCL_SRCROOT)/library";
+				TEST_RIG = "$(OBJROOT)/$(CONFIGURATION)/tcltest";
+			};
+			name = DebugNoCF;
+		};
+		F98751330DE7B5A200B1C9EC /* DebugNoCFUnthreaded */ = {
+			isa = XCBuildConfiguration;
+			baseConfigurationReference = F97AE8330B65C87F00310EA2 /* Tcl-Debug.xcconfig */;
+			buildSettings = {
+				ARCHS = (
+					"$(NATIVE_ARCH_64_BIT)",
+					"$(NATIVE_ARCH_32_BIT)",
+				);
+				CONFIGURE_ARGS = "$(CONFIGURE_ARGS) --disable-threads --disable-corefoundation";
+				CPPFLAGS = "-arch $(CURRENT_ARCH) $(CPPFLAGS)";
+				MACOSX_DEPLOYMENT_TARGET = 10.5;
+				ONLY_ACTIVE_ARCH = YES;
+				PREBINDING = NO;
+			};
+			name = DebugNoCFUnthreaded;
+		};
+		F98751340DE7B5A200B1C9EC /* DebugNoCFUnthreaded */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				PRODUCT_NAME = tclsh;
+				SKIP_INSTALL = NO;
+			};
+			name = DebugNoCFUnthreaded;
+		};
+		F98751350DE7B5A200B1C9EC /* DebugNoCFUnthreaded */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				PRODUCT_NAME = tcltest;
+			};
+			name = DebugNoCFUnthreaded;
+		};
+		F98751360DE7B5A200B1C9EC /* DebugNoCFUnthreaded */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				CODE_SIGN_IDENTITY = "";
+				PRODUCT_NAME = tests;
+				TCLTEST_OPTIONS = "";
+				TCL_LIBRARY = "$(TCL_SRCROOT)/library";
+				TEST_RIG = "$(OBJROOT)/$(CONFIGURATION)/tcltest";
+			};
+			name = DebugNoCFUnthreaded;
+		};
+		F9988AB10D814C6500B6B03B /* Debug gcc40 */ = {
+			isa = XCBuildConfiguration;
+			baseConfigurationReference = F97AE8330B65C87F00310EA2 /* Tcl-Debug.xcconfig */;
+			buildSettings = {
+				ARCHS = (
+					"$(NATIVE_ARCH_64_BIT)",
+					"$(NATIVE_ARCH_32_BIT)",
+				);
+				CPPFLAGS = "-arch $(CURRENT_ARCH) $(CPPFLAGS)";
+				GCC_VERSION = 4.0;
+				MACOSX_DEPLOYMENT_TARGET = 10.5;
+				ONLY_ACTIVE_ARCH = YES;
+				PREBINDING = NO;
+			};
+			name = "Debug gcc40";
+		};
+		F9988AB20D814C6500B6B03B /* Debug gcc40 */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				PRODUCT_NAME = tclsh;
+				SKIP_INSTALL = NO;
+			};
+			name = "Debug gcc40";
+		};
+		F9988AB30D814C6500B6B03B /* Debug gcc40 */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				CONFIGURE_ARGS = "tcl_cv_cc_visibility_hidden=no $(CONFIGURE_ARGS)";
+				GCC_DYNAMIC_NO_PIC = NO;
+				GCC_ENABLE_FIX_AND_CONTINUE = YES;
+				GCC_PREPROCESSOR_DEFINITIONS = (
+					"__private_extern__=extern",
+					"$(GCC_PREPROCESSOR_DEFINITIONS)",
+				);
+				GCC_SYMBOLS_PRIVATE_EXTERN = NO;
+				PRODUCT_NAME = tcltest;
+			};
+			name = "Debug gcc40";
+		};
+		F9988AB40D814C6500B6B03B /* Debug gcc40 */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				CODE_SIGN_IDENTITY = "";
+				PRODUCT_NAME = tests;
+				TCLTEST_OPTIONS = "";
+				TCL_LIBRARY = "$(TCL_SRCROOT)/library";
+				TEST_RIG = "$(OBJROOT)/$(CONFIGURATION)/tcltest";
+			};
+			name = "Debug gcc40";
+		};
+		F9988AB50D814C7500B6B03B /* Debug llvm-gcc */ = {
+			isa = XCBuildConfiguration;
+			baseConfigurationReference = F97AE8330B65C87F00310EA2 /* Tcl-Debug.xcconfig */;
+			buildSettings = {
+				ARCHS = (
+					"$(NATIVE_ARCH_64_BIT)",
+					"$(NATIVE_ARCH_32_BIT)",
+				);
+				CPPFLAGS = "-arch $(CURRENT_ARCH) $(CPPFLAGS)";
+				GCC = "llvm-gcc";
+				GCC_VERSION = com.apple.compilers.llvmgcc42;
+				MACOSX_DEPLOYMENT_TARGET = 10.5;
+				ONLY_ACTIVE_ARCH = YES;
+				PREBINDING = NO;
+			};
+			name = "Debug llvm-gcc";
+		};
+		F9988AB60D814C7500B6B03B /* Debug llvm-gcc */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				PRODUCT_NAME = tclsh;
+				SKIP_INSTALL = NO;
+			};
+			name = "Debug llvm-gcc";
+		};
+		F9988AB70D814C7500B6B03B /* Debug llvm-gcc */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				CONFIGURE_ARGS = "tcl_cv_cc_visibility_hidden=no $(CONFIGURE_ARGS)";
+				GCC_DYNAMIC_NO_PIC = NO;
+				GCC_ENABLE_FIX_AND_CONTINUE = YES;
+				GCC_PREPROCESSOR_DEFINITIONS = (
+					"__private_extern__=extern",
+					"$(GCC_PREPROCESSOR_DEFINITIONS)",
+				);
+				GCC_SYMBOLS_PRIVATE_EXTERN = NO;
+				PRODUCT_NAME = tcltest;
+			};
+			name = "Debug llvm-gcc";
+		};
+		F9988AB80D814C7500B6B03B /* Debug llvm-gcc */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				CODE_SIGN_IDENTITY = "";
+				PRODUCT_NAME = tests;
+				TCLTEST_OPTIONS = "";
+				TCL_LIBRARY = "$(TCL_SRCROOT)/library";
+				TEST_RIG = "$(OBJROOT)/$(CONFIGURATION)/tcltest";
+			};
+			name = "Debug llvm-gcc";
+		};
+		F9988BB10D81586D00B6B03B /* ReleaseUniversal gcc40 */ = {
+			isa = XCBuildConfiguration;
+			baseConfigurationReference = F97AE82B0B65C69B00310EA2 /* Tcl-Release.xcconfig */;
+			buildSettings = {
+				ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
+				CFLAGS = "-arch i386 -arch x86_64 -arch ppc $(CFLAGS)";
+				GCC_VERSION = 4.0;
+				MACOSX_DEPLOYMENT_TARGET = 10.5;
+				PREBINDING = NO;
+			};
+			name = "ReleaseUniversal gcc40";
+		};
+		F9988BB20D81586D00B6B03B /* ReleaseUniversal gcc40 */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				PRODUCT_NAME = tclsh;
+				SKIP_INSTALL = NO;
+			};
+			name = "ReleaseUniversal gcc40";
+		};
+		F9988BB30D81586D00B6B03B /* ReleaseUniversal gcc40 */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				PRODUCT_NAME = tcltest;
+			};
+			name = "ReleaseUniversal gcc40";
+		};
+		F9988BB40D81586D00B6B03B /* ReleaseUniversal gcc40 */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				CODE_SIGN_IDENTITY = "";
+				PRODUCT_NAME = tests;
+				TCLTEST_OPTIONS = "";
+				TCL_LIBRARY = "$(TCL_SRCROOT)/library";
+				TEST_RIG = "$(OBJROOT)/$(CONFIGURATION)/tcltest";
+			};
+			name = "ReleaseUniversal gcc40";
+		};
+		F9988BB50D81587400B6B03B /* ReleaseUniversal llvm-gcc */ = {
+			isa = XCBuildConfiguration;
+			baseConfigurationReference = F97AE82B0B65C69B00310EA2 /* Tcl-Release.xcconfig */;
+			buildSettings = {
+				ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
+				CFLAGS = "-arch i386 -arch x86_64 -arch ppc $(CFLAGS)";
+				DEBUG_INFORMATION_FORMAT = dwarf;
+				GCC = "llvm-gcc";
+				GCC_OPTIMIZATION_LEVEL = 4;
+				GCC_VERSION = com.apple.compilers.llvmgcc42;
+				MACOSX_DEPLOYMENT_TARGET = 10.5;
+				PREBINDING = NO;
+			};
+			name = "ReleaseUniversal llvm-gcc";
+		};
+		F9988BB60D81587400B6B03B /* ReleaseUniversal llvm-gcc */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				PRODUCT_NAME = tclsh;
+				SKIP_INSTALL = NO;
+			};
+			name = "ReleaseUniversal llvm-gcc";
+		};
+		F9988BB70D81587400B6B03B /* ReleaseUniversal llvm-gcc */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				PRODUCT_NAME = tcltest;
+			};
+			name = "ReleaseUniversal llvm-gcc";
+		};
+		F9988BB80D81587400B6B03B /* ReleaseUniversal llvm-gcc */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				CODE_SIGN_IDENTITY = "";
+				PRODUCT_NAME = tests;
+				TCLTEST_OPTIONS = "";
+				TCL_LIBRARY = "$(TCL_SRCROOT)/library";
+				TEST_RIG = "$(OBJROOT)/$(CONFIGURATION)/tcltest";
+			};
+			name = "ReleaseUniversal llvm-gcc";
+		};
+		F99EE73B0BE835310060D4AF /* DebugUnthreaded */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				PRODUCT_NAME = tclsh;
+				SKIP_INSTALL = NO;
+			};
+			name = DebugUnthreaded;
+		};
+		F99EE73C0BE835310060D4AF /* DebugLeaks */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				PRODUCT_NAME = tclsh;
+				SKIP_INSTALL = NO;
+			};
+			name = DebugLeaks;
+		};
+		F99EE73D0BE835310060D4AF /* DebugUnthreaded */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				PRODUCT_NAME = tcltest;
+			};
+			name = DebugUnthreaded;
+		};
+		F99EE73E0BE835310060D4AF /* DebugLeaks */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				PRODUCT_NAME = tcltest;
+			};
+			name = DebugLeaks;
+		};
+		F99EE73F0BE835310060D4AF /* DebugUnthreaded */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				CODE_SIGN_IDENTITY = "";
+				PRODUCT_NAME = tests;
+				TCLTEST_OPTIONS = "";
+				TCL_LIBRARY = "$(TCL_SRCROOT)/library";
+				TEST_RIG = "$(OBJROOT)/$(CONFIGURATION)/tcltest";
+			};
+			name = DebugUnthreaded;
+		};
+		F99EE7400BE835310060D4AF /* DebugLeaks */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				CODE_SIGN_IDENTITY = "";
+				PRODUCT_NAME = tests;
+				TCLTEST_OPTIONS = "";
+				TCL_LIBRARY = "$(TCL_SRCROOT)/library";
+				TEST_RIG = "$(OBJROOT)/$(CONFIGURATION)/tcltest";
+			};
+			name = DebugLeaks;
+		};
+		F99EE7410BE835310060D4AF /* DebugUnthreaded */ = {
+			isa = XCBuildConfiguration;
+			baseConfigurationReference = F97AE8330B65C87F00310EA2 /* Tcl-Debug.xcconfig */;
+			buildSettings = {
+				ARCHS = (
+					"$(NATIVE_ARCH_64_BIT)",
+					"$(NATIVE_ARCH_32_BIT)",
+				);
+				CONFIGURE_ARGS = "$(CONFIGURE_ARGS) --disable-threads";
+				CPPFLAGS = "-arch $(CURRENT_ARCH) $(CPPFLAGS)";
+				MACOSX_DEPLOYMENT_TARGET = 10.5;
+				ONLY_ACTIVE_ARCH = YES;
+				PREBINDING = NO;
+			};
+			name = DebugUnthreaded;
+		};
+		F99EE7420BE835310060D4AF /* DebugLeaks */ = {
+			isa = XCBuildConfiguration;
+			baseConfigurationReference = F97AE8330B65C87F00310EA2 /* Tcl-Debug.xcconfig */;
+			buildSettings = {
+				ARCHS = (
+					"$(NATIVE_ARCH_64_BIT)",
+					"$(NATIVE_ARCH_32_BIT)",
+				);
+				CPPFLAGS = "-arch $(CURRENT_ARCH) $(CPPFLAGS)";
+				GCC_PREPROCESSOR_DEFINITIONS = (
+					PURIFY,
+					"$(GCC_PREPROCESSOR_DEFINITIONS)",
+				);
+				MACOSX_DEPLOYMENT_TARGET = 10.5;
+				ONLY_ACTIVE_ARCH = YES;
+				PREBINDING = NO;
+			};
+			name = DebugLeaks;
+		};
+		F9EEED960C2FEFD300396116 /* ReleaseUniversal10.5SDK */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				PRODUCT_NAME = tclsh;
+				SKIP_INSTALL = NO;
+			};
+			name = ReleaseUniversal10.5SDK;
+		};
+		F9EEED970C2FEFD300396116 /* ReleaseUniversal10.5SDK */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				PRODUCT_NAME = tcltest;
+			};
+			name = ReleaseUniversal10.5SDK;
+		};
+		F9EEED980C2FEFD300396116 /* ReleaseUniversal10.5SDK */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				CODE_SIGN_IDENTITY = "";
+				PRODUCT_NAME = tests;
+				TCLTEST_OPTIONS = "";
+				TCL_LIBRARY = "$(TCL_SRCROOT)/library";
+				TEST_RIG = "$(OBJROOT)/$(CONFIGURATION)/tcltest";
+			};
+			name = ReleaseUniversal10.5SDK;
+		};
+		F9EEED990C2FEFD300396116 /* ReleaseUniversal10.5SDK */ = {
+			isa = XCBuildConfiguration;
+			baseConfigurationReference = F97AE82B0B65C69B00310EA2 /* Tcl-Release.xcconfig */;
+			buildSettings = {
+				ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
+				CFLAGS = "-arch i386 -arch x86_64 -arch ppc $(CFLAGS)";
+				CPPFLAGS = "-isysroot $(SDKROOT) $(CPPFLAGS)";
+				MACOSX_DEPLOYMENT_TARGET = 10.5;
+				PREBINDING = NO;
+				SDKROOT = macosx10.5;
+			};
+			name = ReleaseUniversal10.5SDK;
+		};
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+		F95CC8AB09158F3100EA5ACE /* Build configuration list for PBXNativeTarget "Tcl" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				F95CC8AC09158F3100EA5ACE /* Debug */,
+				F9988AB60D814C7500B6B03B /* Debug llvm-gcc */,
+				F9988AB20D814C6500B6B03B /* Debug gcc40 */,
+				F95CC8AE09158F3100EA5ACE /* DebugNoFixAndContinue */,
+				F99EE73B0BE835310060D4AF /* DebugUnthreaded */,
+				F98751300DE7B57E00B1C9EC /* DebugNoCF */,
+				F98751340DE7B5A200B1C9EC /* DebugNoCFUnthreaded */,
+				F93084370BB93D2800CD0B9E /* DebugMemCompile */,
+				F99EE73C0BE835310060D4AF /* DebugLeaks */,
+				F9359B260DF212DA00E04F67 /* DebugGCov */,
+				F97AED1B0B660B2100310EA2 /* Debug64bit */,
+				F95CC8AD09158F3100EA5ACE /* Release */,
+				F91BCC4F093152310042A6BF /* ReleaseUniversal */,
+				F9988BB60D81587400B6B03B /* ReleaseUniversal llvm-gcc */,
+				F9988BB20D81586D00B6B03B /* ReleaseUniversal gcc40 */,
+				F9EEED960C2FEFD300396116 /* ReleaseUniversal10.5SDK */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Debug;
+		};
+		F95CC8B009158F3100EA5ACE /* Build configuration list for PBXNativeTarget "tcltest" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				F95CC8B109158F3100EA5ACE /* Debug */,
+				F9988AB70D814C7500B6B03B /* Debug llvm-gcc */,
+				F9988AB30D814C6500B6B03B /* Debug gcc40 */,
+				F95CC8B309158F3100EA5ACE /* DebugNoFixAndContinue */,
+				F99EE73D0BE835310060D4AF /* DebugUnthreaded */,
+				F98751310DE7B57E00B1C9EC /* DebugNoCF */,
+				F98751350DE7B5A200B1C9EC /* DebugNoCFUnthreaded */,
+				F93084380BB93D2800CD0B9E /* DebugMemCompile */,
+				F99EE73E0BE835310060D4AF /* DebugLeaks */,
+				F9359B270DF212DA00E04F67 /* DebugGCov */,
+				F97AED1C0B660B2100310EA2 /* Debug64bit */,
+				F95CC8B209158F3100EA5ACE /* Release */,
+				F91BCC50093152310042A6BF /* ReleaseUniversal */,
+				F9988BB70D81587400B6B03B /* ReleaseUniversal llvm-gcc */,
+				F9988BB30D81586D00B6B03B /* ReleaseUniversal gcc40 */,
+				F9EEED970C2FEFD300396116 /* ReleaseUniversal10.5SDK */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Debug;
+		};
+		F95CC8B509158F3100EA5ACE /* Build configuration list for PBXProject "Tcl" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				F95CC8B609158F3100EA5ACE /* Debug */,
+				F9988AB50D814C7500B6B03B /* Debug llvm-gcc */,
+				F9988AB10D814C6500B6B03B /* Debug gcc40 */,
+				F95CC8B809158F3100EA5ACE /* DebugNoFixAndContinue */,
+				F99EE7410BE835310060D4AF /* DebugUnthreaded */,
+				F987512F0DE7B57E00B1C9EC /* DebugNoCF */,
+				F98751330DE7B5A200B1C9EC /* DebugNoCFUnthreaded */,
+				F930843A0BB93D2800CD0B9E /* DebugMemCompile */,
+				F99EE7420BE835310060D4AF /* DebugLeaks */,
+				F9359B250DF212DA00E04F67 /* DebugGCov */,
+				F97AED1E0B660B2100310EA2 /* Debug64bit */,
+				F95CC8B709158F3100EA5ACE /* Release */,
+				F91BCC51093152310042A6BF /* ReleaseUniversal */,
+				F9988BB50D81587400B6B03B /* ReleaseUniversal llvm-gcc */,
+				F9988BB10D81586D00B6B03B /* ReleaseUniversal gcc40 */,
+				F9EEED990C2FEFD300396116 /* ReleaseUniversal10.5SDK */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Debug;
+		};
+		F97258A80A86873D00096C78 /* Build configuration list for PBXNativeTarget "tests" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				F97258A90A86873D00096C78 /* Debug */,
+				F9988AB80D814C7500B6B03B /* Debug llvm-gcc */,
+				F9988AB40D814C6500B6B03B /* Debug gcc40 */,
+				F97258AB0A86873D00096C78 /* DebugNoFixAndContinue */,
+				F99EE73F0BE835310060D4AF /* DebugUnthreaded */,
+				F98751320DE7B57E00B1C9EC /* DebugNoCF */,
+				F98751360DE7B5A200B1C9EC /* DebugNoCFUnthreaded */,
+				F93084390BB93D2800CD0B9E /* DebugMemCompile */,
+				F99EE7400BE835310060D4AF /* DebugLeaks */,
+				F9359B280DF212DA00E04F67 /* DebugGCov */,
+				F97AED1D0B660B2100310EA2 /* Debug64bit */,
+				F97258AA0A86873D00096C78 /* Release */,
+				F97258AC0A86873D00096C78 /* ReleaseUniversal */,
+				F9988BB80D81587400B6B03B /* ReleaseUniversal llvm-gcc */,
+				F9988BB40D81586D00B6B03B /* ReleaseUniversal gcc40 */,
+				F9EEED980C2FEFD300396116 /* ReleaseUniversal10.5SDK */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Debug;
+		};
+/* End XCConfigurationList section */
+	};
+	rootObject = 08FB7793FE84155DC02AAC07 /* Project object */;
+}
diff --git a/macosx/Tcl.xcodeproj/default.pbxuser b/macosx/Tcl.xcodeproj/default.pbxuser
new file mode 100644
index 0000000..0399c7b
--- /dev/null
+++ b/macosx/Tcl.xcodeproj/default.pbxuser
@@ -0,0 +1,211 @@
+// !$*UTF8*$!
+{
+	08FB7793FE84155DC02AAC07 /* Project object */ = {
+		activeBuildConfigurationName = Debug;
+		activeExecutable = F9E61D1C090A4282002B3151 /* tclsh */;
+		activeTarget = F9E61D16090A3E94002B3151 /* Tcl */;
+		codeSenseManager = F944EB9D08F798180049FDD4 /* Code sense */;
+		executables = (
+			F9E61D1C090A4282002B3151 /* tclsh */,
+			F944EB8F08F798100049FDD4 /* tcltest */,
+		);
+		perUserDictionary = {
+			com.apple.ide.smrt.PBXUserSmartGroupsKey.Rev10 = <040b73747265616d747970656481e8038401408484840e4e534d757461626c654172726179008484074e534172726179008484084e534f626a65637400858401690192848484134e534d757461626c6544696374696f6e6172790084840c4e5344696374696f6e6172790095960792848484084e53537472696e67019584012b046e616d658692849a9a14496d706c656d656e746174696f6e2046696c65738692849a9a195042585472616e7369656e744c6f636174696f6e4174546f708692849a9a06626f74746f6d8692849a9a0b707265666572656e63657386928497960892849a9a0669734c6561668692848484084e534e756d626572008484074e5356616c7565009584012a849696008692849a9a04726f6f748692849a9a093c50524f4a4543543e8692849a9a09726563757273697665869284a29da496018692849a9a05696d6167658692849a9a0b536d617274466f6c6465728692849a9a0763616e536176658692a892849a9a1250425850726f6a65637453636f70654b65798692849a9a035945538692849a9a0572656765788692849a9a065c2e286329248692849a9a07666e6d617463688692849a9a00868692849a9a146162736f6c75746550617468546f42756e646c658692849a9a008692849a9a0b6465736372697074696f6e8692849a9a103c6e6f206465736372697074696f6e3e8692849a9a08676c6f62616c49448692849a9a183143433045413430303433353045463930303434343130428692849a9a03636c7a8692849a9a1550425846696c656e616d65536d61727447726f7570868686>;
+		};
+		sourceControlManager = F944EB9C08F798180049FDD4 /* Source Control */;
+		userBuildSettings = {
+			SYMROOT = "${SRCROOT}/../../build/tcl";
+			TCL_SRCROOT = "${SRCROOT}/../../tcl";
+		};
+	};
+	8DD76FA90486AB0100D96B5E /* tcltest */ = {
+		activeExec = 0;
+		executables = (
+			F944EB8F08F798100049FDD4 /* tcltest */,
+		);
+	};
+	F944EB8F08F798100049FDD4 /* tcltest */ = {
+		isa = PBXExecutable;
+		activeArgIndices = (
+			NO,
+			NO,
+			NO,
+		);
+		argumentStrings = (
+			"${TCL_SRCROOT}/tests/all.tcl",
+			"-singleproc 1",
+			"-verbose \"bet\"",
+		);
+		autoAttachOnCrash = 1;
+		breakpointsEnabled = 1;
+		configStateDict = {
+			"PBXLSLaunchAction-0" = {
+				PBXLSLaunchAction = 0;
+				PBXLSLaunchStartAction = 1;
+				PBXLSLaunchStdioStyle = 2;
+				PBXLSLaunchStyle = 0;
+				class = PBXLSRunLaunchConfig;
+				displayName = "Executable Runner";
+				identifier = com.apple.Xcode.launch.runConfig;
+				remoteHostInfo = "";
+				startActionInfo = "";
+			};
+			"PBXLSLaunchAction-1" = {
+				PBXLSLaunchAction = 1;
+				PBXLSLaunchStartAction = 1;
+				PBXLSLaunchStdioStyle = 2;
+				PBXLSLaunchStyle = 0;
+				class = PBXGDB_LaunchConfig;
+				displayName = GDB;
+				identifier = com.apple.Xcode.launch.GDBMI_Config;
+				remoteHostInfo = "";
+				startActionInfo = "";
+			};
+		};
+		customDataFormattersEnabled = 1;
+		dataTipCustomDataFormattersEnabled = 1;
+		dataTipShowTypeColumn = 1;
+		dataTipSortType = 0;
+		debuggerPlugin = GDBDebugging;
+		disassemblyDisplayState = 0;
+		dylibVariantSuffix = "";
+		enableDebugStr = 0;
+		environmentEntries = (
+			{
+				active = YES;
+				name = TCL_LIBRARY;
+				value = "${TCL_SRCROOT}/library";
+			},
+			{
+				active = YES;
+				name = TCLLIBPATH;
+				value = /Library/Tcl;
+			},
+			{
+				active = NO;
+				name = DYLD_PRINT_LIBRARIES;
+			},
+			{
+				active = NO;
+				name = MallocBadFreeAbort;
+				value = 1;
+			},
+			{
+				active = NO;
+				name = MallocLogFile;
+				value = /tmp/malloc.log;
+			},
+			{
+				active = NO;
+				name = MallocStackLogging;
+				value = 1;
+			},
+			{
+				active = NO;
+				name = MallocStackLoggingNoCompact;
+				value = 1;
+			},
+			{
+				active = NO;
+				name = MallocPreScribble;
+				value = 1;
+			},
+			{
+				active = NO;
+				name = MallocScribble;
+				value = 1;
+			},
+		);
+		executableSystemSymbolLevel = 0;
+		executableUserSymbolLevel = 0;
+		libgmallocEnabled = 0;
+		name = tcltest;
+		showTypeColumn = 0;
+		sourceDirectories = (
+		);
+	};
+	F944EB9C08F798180049FDD4 /* Source Control */ = {
+		isa = PBXSourceControlManager;
+		fallbackIsa = XCSourceControlManager;
+		isSCMEnabled = 0;
+		repositoryNamesForRoots = {
+			.. = "";
+		};
+		scmConfiguration = {
+			CVSToolPath = /usr/bin/cvs;
+			CVSUseSSH = NO;
+			SubversionToolPath = /usr/bin/svn;
+			repositoryNamesForRoots = {
+				.. = "";
+			};
+		};
+		scmType = scm.cvs;
+	};
+	F944EB9D08F798180049FDD4 /* Code sense */ = {
+		isa = PBXCodeSenseManager;
+		indexTemplatePath = "";
+	};
+	F97258A50A86873C00096C78 /* tests */ = {
+		activeExec = 0;
+	};
+	F9E61D16090A3E94002B3151 /* Tcl */ = {
+		activeExec = 0;
+		executables = (
+			F9E61D1C090A4282002B3151 /* tclsh */,
+		);
+	};
+	F9E61D1C090A4282002B3151 /* tclsh */ = {
+		isa = PBXExecutable;
+		activeArgIndices = (
+		);
+		argumentStrings = (
+		);
+		autoAttachOnCrash = 1;
+		breakpointsEnabled = 1;
+		configStateDict = {
+			"PBXLSLaunchAction-0" = {
+				PBXLSLaunchAction = 0;
+				PBXLSLaunchStartAction = 1;
+				PBXLSLaunchStdioStyle = 2;
+				PBXLSLaunchStyle = 0;
+				class = PBXLSRunLaunchConfig;
+				displayName = "Executable Runner";
+				identifier = com.apple.Xcode.launch.runConfig;
+				remoteHostInfo = "";
+				startActionInfo = "";
+			};
+			"PBXLSLaunchAction-1" = {
+				PBXLSLaunchAction = 1;
+				PBXLSLaunchStartAction = 1;
+				PBXLSLaunchStdioStyle = 2;
+				PBXLSLaunchStyle = 0;
+				class = PBXGDB_LaunchConfig;
+				displayName = GDB;
+				identifier = com.apple.Xcode.launch.GDBMI_Config;
+				remoteHostInfo = "";
+				startActionInfo = "";
+			};
+		};
+		customDataFormattersEnabled = 1;
+		dataTipCustomDataFormattersEnabled = 1;
+		dataTipShowTypeColumn = 1;
+		dataTipSortType = 0;
+		debuggerPlugin = GDBDebugging;
+		disassemblyDisplayState = 0;
+		dylibVariantSuffix = _debug;
+		enableDebugStr = 0;
+		environmentEntries = (
+			{
+				active = NO;
+				name = DYLD_PRINT_LIBRARIES;
+			},
+		);
+		executableSystemSymbolLevel = 0;
+		executableUserSymbolLevel = 0;
+		libgmallocEnabled = 0;
+		name = tclsh;
+		showTypeColumn = 0;
+		sourceDirectories = (
+		);
+	};
+}
diff --git a/macosx/Tcl.xcodeproj/project.pbxproj b/macosx/Tcl.xcodeproj/project.pbxproj
new file mode 100644
index 0000000..7c0d083
--- /dev/null
+++ b/macosx/Tcl.xcodeproj/project.pbxproj
@@ -0,0 +1,3039 @@
+// !$*UTF8*$!
+{
+	archiveVersion = 1;
+	classes = {
+	};
+	objectVersion = 46;
+	objects = {
+
+/* Begin PBXBuildFile section */
+		F90509300913A72400327603 /* tclAppInit.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D445508F272B9004A47F5 /* tclAppInit.c */; settings = {COMPILER_FLAGS = "-DTCL_TEST -DTCL_BUILDTIME_LIBRARY=\\\"$(TCL_SRCROOT)/library\\\""; }; };
+		F93599B30DF1F75400E04F67 /* tclOO.c in Sources */ = {isa = PBXBuildFile; fileRef = F93599B20DF1F75400E04F67 /* tclOO.c */; };
+		F93599B70DF1F76100E04F67 /* tclOOBasic.c in Sources */ = {isa = PBXBuildFile; fileRef = F93599B60DF1F76100E04F67 /* tclOOBasic.c */; };
+		F93599B90DF1F76600E04F67 /* tclOOCall.c in Sources */ = {isa = PBXBuildFile; fileRef = F93599B80DF1F76600E04F67 /* tclOOCall.c */; };
+		F93599BC0DF1F77000E04F67 /* tclOODefineCmds.c in Sources */ = {isa = PBXBuildFile; fileRef = F93599BB0DF1F77000E04F67 /* tclOODefineCmds.c */; };
+		F93599BE0DF1F77400E04F67 /* tclOOInfo.c in Sources */ = {isa = PBXBuildFile; fileRef = F93599BD0DF1F77400E04F67 /* tclOOInfo.c */; };
+		F93599C20DF1F78300E04F67 /* tclOOMethod.c in Sources */ = {isa = PBXBuildFile; fileRef = F93599C10DF1F78300E04F67 /* tclOOMethod.c */; };
+		F93599C40DF1F78800E04F67 /* tclOOStubInit.c in Sources */ = {isa = PBXBuildFile; fileRef = F93599C30DF1F78800E04F67 /* tclOOStubInit.c */; };
+		F93599C60DF1F78D00E04F67 /* tclOOStubLib.c in Sources */ = {isa = PBXBuildFile; fileRef = F93599C50DF1F78D00E04F67 /* tclOOStubLib.c */; };
+		F95D77EA0DFD820D00A8BF6F /* tclIORTrans.c in Sources */ = {isa = PBXBuildFile; fileRef = F95D77E90DFD820D00A8BF6F /* tclIORTrans.c */; };
+		F96437CA0EF0D4B2003F468E /* tclZlib.c in Sources */ = {isa = PBXBuildFile; fileRef = F96437C90EF0D4B2003F468E /* tclZlib.c */; };
+		F96437E70EF0D652003F468E /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = F96437E60EF0D652003F468E /* libz.dylib */; };
+		F966C07508F2820D005CB29B /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F966C07408F2820D005CB29B /* CoreFoundation.framework */; };
+		F96D456F08F272BB004A47F5 /* regcomp.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3ED008F272A7004A47F5 /* regcomp.c */; };
+		F96D457208F272BB004A47F5 /* regerror.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3ED308F272A7004A47F5 /* regerror.c */; };
+		F96D457508F272BB004A47F5 /* regexec.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3ED608F272A7004A47F5 /* regexec.c */; };
+		F96D457608F272BB004A47F5 /* regfree.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3ED708F272A7004A47F5 /* regfree.c */; };
+		F96D457B08F272BB004A47F5 /* tclAlloc.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EDC08F272A7004A47F5 /* tclAlloc.c */; settings = {COMPILER_FLAGS = "-DUSE_TCLALLOC=0"; }; };
+		F96D457C08F272BB004A47F5 /* tclAsync.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EDD08F272A7004A47F5 /* tclAsync.c */; };
+		F96D457D08F272BB004A47F5 /* tclBasic.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EDE08F272A7004A47F5 /* tclBasic.c */; };
+		F96D457E08F272BC004A47F5 /* tclBinary.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EDF08F272A7004A47F5 /* tclBinary.c */; };
+		F96D457F08F272BC004A47F5 /* tclCkalloc.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EE008F272A7004A47F5 /* tclCkalloc.c */; };
+		F96D458008F272BC004A47F5 /* tclClock.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EE108F272A7004A47F5 /* tclClock.c */; };
+		F96D458108F272BC004A47F5 /* tclCmdAH.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EE208F272A7004A47F5 /* tclCmdAH.c */; };
+		F96D458208F272BC004A47F5 /* tclCmdIL.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EE308F272A7004A47F5 /* tclCmdIL.c */; };
+		F96D458308F272BC004A47F5 /* tclCmdMZ.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EE408F272A7004A47F5 /* tclCmdMZ.c */; };
+		F96D458408F272BC004A47F5 /* tclCompCmds.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EE508F272A7004A47F5 /* tclCompCmds.c */; };
+		F96D458508F272BC004A47F5 /* tclCompExpr.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EE608F272A7004A47F5 /* tclCompExpr.c */; };
+		F96D458608F272BC004A47F5 /* tclCompile.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EE708F272A7004A47F5 /* tclCompile.c */; };
+		F96D458808F272BC004A47F5 /* tclConfig.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EE908F272A7004A47F5 /* tclConfig.c */; };
+		F96D458908F272BC004A47F5 /* tclDate.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EEA08F272A7004A47F5 /* tclDate.c */; };
+		F96D458B08F272BC004A47F5 /* tclDictObj.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EEC08F272A7004A47F5 /* tclDictObj.c */; };
+		F96D458C08F272BC004A47F5 /* tclEncoding.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EED08F272A7004A47F5 /* tclEncoding.c */; };
+		F96D458D08F272BC004A47F5 /* tclEnv.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EEE08F272A7004A47F5 /* tclEnv.c */; };
+		F96D458E08F272BC004A47F5 /* tclEvent.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EEF08F272A7004A47F5 /* tclEvent.c */; };
+		F96D458F08F272BC004A47F5 /* tclExecute.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EF008F272A7004A47F5 /* tclExecute.c */; };
+		F96D459008F272BC004A47F5 /* tclFCmd.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EF108F272A7004A47F5 /* tclFCmd.c */; };
+		F96D459108F272BC004A47F5 /* tclFileName.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EF208F272A7004A47F5 /* tclFileName.c */; };
+		F96D459308F272BC004A47F5 /* tclGet.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EF408F272A7004A47F5 /* tclGet.c */; };
+		F96D459508F272BC004A47F5 /* tclHash.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EF608F272A7004A47F5 /* tclHash.c */; };
+		F96D459608F272BC004A47F5 /* tclHistory.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EF708F272A7004A47F5 /* tclHistory.c */; };
+		F96D459708F272BC004A47F5 /* tclIndexObj.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EF808F272A7004A47F5 /* tclIndexObj.c */; };
+		F96D459B08F272BC004A47F5 /* tclInterp.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EFC08F272A7004A47F5 /* tclInterp.c */; };
+		F96D459D08F272BC004A47F5 /* tclIO.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3EFE08F272A7004A47F5 /* tclIO.c */; };
+		F96D459F08F272BC004A47F5 /* tclIOCmd.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0008F272A7004A47F5 /* tclIOCmd.c */; };
+		F96D45A008F272BC004A47F5 /* tclIOGT.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0108F272A7004A47F5 /* tclIOGT.c */; };
+		F96D45A108F272BC004A47F5 /* tclIORChan.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0208F272A7004A47F5 /* tclIORChan.c */; };
+		F96D45A208F272BC004A47F5 /* tclIOSock.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0308F272A7004A47F5 /* tclIOSock.c */; };
+		F96D45A308F272BC004A47F5 /* tclIOUtil.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0408F272A7004A47F5 /* tclIOUtil.c */; };
+		F96D45A408F272BC004A47F5 /* tclLink.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0508F272A7004A47F5 /* tclLink.c */; };
+		F96D45A508F272BC004A47F5 /* tclListObj.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0608F272A7004A47F5 /* tclListObj.c */; };
+		F96D45A608F272BC004A47F5 /* tclLiteral.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0708F272A7004A47F5 /* tclLiteral.c */; };
+		F96D45A708F272BC004A47F5 /* tclLoad.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0808F272A7004A47F5 /* tclLoad.c */; };
+		F96D45A908F272BC004A47F5 /* tclMain.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0A08F272A7004A47F5 /* tclMain.c */; };
+		F96D45AA08F272BC004A47F5 /* tclNamesp.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0B08F272A7004A47F5 /* tclNamesp.c */; };
+		F96D45AB08F272BC004A47F5 /* tclNotify.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0C08F272A7004A47F5 /* tclNotify.c */; };
+		F96D45AC08F272BC004A47F5 /* tclObj.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0D08F272A7004A47F5 /* tclObj.c */; };
+		F96D45AD08F272BC004A47F5 /* tclPanic.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0E08F272A7004A47F5 /* tclPanic.c */; };
+		F96D45AE08F272BC004A47F5 /* tclParse.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F0F08F272A7004A47F5 /* tclParse.c */; };
+		F96D45B008F272BC004A47F5 /* tclPathObj.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1108F272A7004A47F5 /* tclPathObj.c */; };
+		F96D45B108F272BC004A47F5 /* tclPipe.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1208F272A7004A47F5 /* tclPipe.c */; };
+		F96D45B208F272BC004A47F5 /* tclPkg.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1308F272A7004A47F5 /* tclPkg.c */; };
+		F96D45B308F272BC004A47F5 /* tclPkgConfig.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1408F272A7004A47F5 /* tclPkgConfig.c */; settings = {COMPILER_FLAGS = "-DCFG_INSTALL_LIBDIR=\\\"$(LIBDIR)\\\" -DCFG_INSTALL_BINDIR=\\\"$(BINDIR)\\\" -DCFG_INSTALL_SCRDIR=\\\"$(TCL_LIBRARY)\\\" -DCFG_INSTALL_INCDIR=\\\"$(INCLUDEDIR)\\\" -DCFG_INSTALL_DOCDIR=\\\"$(MANDIR)\\\" -DCFG_RUNTIME_LIBDIR=\\\"$(LIBDIR)\\\" -DCFG_RUNTIME_BINDIR=\\\"$(BINDIR)\\\" -DCFG_RUNTIME_SCRDIR=\\\"$(TCL_LIBRARY)\\\" -DCFG_RUNTIME_INCDIR=\\\"$(INCLUDEDIR)\\\" -DCFG_RUNTIME_DOCDIR=\\\"$(MANDIR)\\\""; }; };
+		F96D45B608F272BC004A47F5 /* tclPosixStr.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1708F272A7004A47F5 /* tclPosixStr.c */; };
+		F96D45B708F272BC004A47F5 /* tclPreserve.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1808F272A7004A47F5 /* tclPreserve.c */; };
+		F96D45B808F272BC004A47F5 /* tclProc.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1908F272A7004A47F5 /* tclProc.c */; };
+		F96D45B908F272BC004A47F5 /* tclRegexp.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1A08F272A7004A47F5 /* tclRegexp.c */; };
+		F96D45BB08F272BC004A47F5 /* tclResolve.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1C08F272A7004A47F5 /* tclResolve.c */; };
+		F96D45BC08F272BC004A47F5 /* tclResult.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1D08F272A7004A47F5 /* tclResult.c */; };
+		F96D45BD08F272BC004A47F5 /* tclScan.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1E08F272A7004A47F5 /* tclScan.c */; };
+		F96D45BE08F272BC004A47F5 /* tclStringObj.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F1F08F272A7004A47F5 /* tclStringObj.c */; };
+		F96D45C308F272BC004A47F5 /* tclStrToD.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F2408F272A7004A47F5 /* tclStrToD.c */; };
+		F96D45C408F272BC004A47F5 /* tclStubInit.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F2508F272A7004A47F5 /* tclStubInit.c */; };
+		F96D45C508F272BC004A47F5 /* tclStubLib.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F2608F272A7004A47F5 /* tclStubLib.c */; };
+		F96D45C608F272BC004A47F5 /* tclTest.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F2708F272A7004A47F5 /* tclTest.c */; };
+		F96D45C708F272BC004A47F5 /* tclTestObj.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F2808F272A7004A47F5 /* tclTestObj.c */; };
+		F96D45C808F272BC004A47F5 /* tclTestProcBodyObj.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F2908F272A7004A47F5 /* tclTestProcBodyObj.c */; };
+		F96D45C908F272BC004A47F5 /* tclThread.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F2A08F272A7004A47F5 /* tclThread.c */; };
+		F96D45CA08F272BC004A47F5 /* tclThreadAlloc.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F2B08F272A7004A47F5 /* tclThreadAlloc.c */; };
+		F96D45CB08F272BC004A47F5 /* tclThreadJoin.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F2C08F272A7004A47F5 /* tclThreadJoin.c */; };
+		F96D45CC08F272BC004A47F5 /* tclThreadStorage.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F2D08F272A7004A47F5 /* tclThreadStorage.c */; };
+		F96D45CD08F272BC004A47F5 /* tclThreadTest.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F2E08F272A7004A47F5 /* tclThreadTest.c */; };
+		F96D45CE08F272BC004A47F5 /* tclTimer.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F2F08F272A7004A47F5 /* tclTimer.c */; };
+		F96D45D008F272BC004A47F5 /* tclTomMathInterface.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F3108F272A7004A47F5 /* tclTomMathInterface.c */; };
+		F96D45D108F272BC004A47F5 /* tclTrace.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F3208F272A7004A47F5 /* tclTrace.c */; };
+		F96D45D308F272BC004A47F5 /* tclUtf.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F3408F272A7004A47F5 /* tclUtf.c */; };
+		F96D45D408F272BC004A47F5 /* tclUtil.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F3508F272A7004A47F5 /* tclUtil.c */; };
+		F96D45D508F272BC004A47F5 /* tclVar.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D3F3608F272A7004A47F5 /* tclVar.c */; };
+		F96D48E208F272C3004A47F5 /* bn_fast_s_mp_mul_digs.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D426408F272B3004A47F5 /* bn_fast_s_mp_mul_digs.c */; };
+		F96D48E408F272C3004A47F5 /* bn_fast_s_mp_sqr.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D426608F272B3004A47F5 /* bn_fast_s_mp_sqr.c */; };
+		F96D48E708F272C3004A47F5 /* bn_mp_add.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D426908F272B3004A47F5 /* bn_mp_add.c */; };
+		F96D48E808F272C3004A47F5 /* bn_mp_add_d.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D426A08F272B3004A47F5 /* bn_mp_add_d.c */; };
+		F96D48EB08F272C3004A47F5 /* bn_mp_clamp.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D426D08F272B3004A47F5 /* bn_mp_clamp.c */; };
+		F96D48EC08F272C3004A47F5 /* bn_mp_clear.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D426E08F272B3004A47F5 /* bn_mp_clear.c */; };
+		F96D48ED08F272C3004A47F5 /* bn_mp_clear_multi.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D426F08F272B3004A47F5 /* bn_mp_clear_multi.c */; };
+		F96D48EE08F272C3004A47F5 /* bn_mp_cmp.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427008F272B3004A47F5 /* bn_mp_cmp.c */; };
+		F96D48F008F272C3004A47F5 /* bn_mp_cmp_mag.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427208F272B3004A47F5 /* bn_mp_cmp_mag.c */; };
+		F96D48F208F272C3004A47F5 /* bn_mp_cnt_lsb.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427408F272B3004A47F5 /* bn_mp_cnt_lsb.c */; };
+		F96D48F208F272C3004A47F5 /* bn_mp_copy.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427408F272B3004A47F5 /* bn_mp_copy.c */; };
+		F96D48F308F272C3004A47F5 /* bn_mp_count_bits.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427508F272B3004A47F5 /* bn_mp_count_bits.c */; };
+		F96D48F408F272C3004A47F5 /* bn_mp_div.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427608F272B3004A47F5 /* bn_mp_div.c */; };
+		F96D48F508F272C3004A47F5 /* bn_mp_div_2.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427708F272B3004A47F5 /* bn_mp_div_2.c */; };
+		F96D48F608F272C3004A47F5 /* bn_mp_div_2d.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427808F272B3004A47F5 /* bn_mp_div_2d.c */; };
+		F96D48F708F272C3004A47F5 /* bn_mp_div_3.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427908F272B3004A47F5 /* bn_mp_div_3.c */; };
+		F96D48F808F272C3004A47F5 /* bn_mp_div_d.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427A08F272B3004A47F5 /* bn_mp_div_d.c */; };
+		F96D48FC08F272C3004A47F5 /* bn_mp_exch.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427E08F272B3004A47F5 /* bn_mp_exch.c */; };
+		F96D490508F272C3004A47F5 /* bn_mp_grow.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D428708F272B3004A47F5 /* bn_mp_grow.c */; };
+		F96D490608F272C3004A47F5 /* bn_mp_init.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D428808F272B3004A47F5 /* bn_mp_init.c */; };
+		F96D490708F272C3004A47F5 /* bn_mp_init_copy.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D428908F272B3004A47F5 /* bn_mp_init_copy.c */; };
+		F96D490808F272C3004A47F5 /* bn_mp_init_multi.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D428A08F272B3004A47F5 /* bn_mp_init_multi.c */; };
+		F96D490908F272C3004A47F5 /* bn_mp_init_set.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D428B08F272B3004A47F5 /* bn_mp_init_set.c */; };
+		F96D490B08F272C3004A47F5 /* bn_mp_init_size.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D428D08F272B3004A47F5 /* bn_mp_init_size.c */; };
+		F96D491008F272C3004A47F5 /* bn_mp_karatsuba_mul.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D429208F272B3004A47F5 /* bn_mp_karatsuba_mul.c */; };
+		F96D491108F272C3004A47F5 /* bn_mp_karatsuba_sqr.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D429308F272B3004A47F5 /* bn_mp_karatsuba_sqr.c */; };
+		F96D491308F272C3004A47F5 /* bn_mp_lshd.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D429508F272B3004A47F5 /* bn_mp_lshd.c */; };
+		F96D491408F272C3004A47F5 /* bn_mp_mod.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D429608F272B3004A47F5 /* bn_mp_mod.c */; };
+		F96D491508F272C3004A47F5 /* bn_mp_mod_2d.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D429708F272B3004A47F5 /* bn_mp_mod_2d.c */; };
+		F96D491A08F272C3004A47F5 /* bn_mp_mul.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D429C08F272B3004A47F5 /* bn_mp_mul.c */; };
+		F96D491B08F272C3004A47F5 /* bn_mp_mul_2.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D429D08F272B3004A47F5 /* bn_mp_mul_2.c */; };
+		F96D491C08F272C3004A47F5 /* bn_mp_mul_2d.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D429E08F272B3004A47F5 /* bn_mp_mul_2d.c */; };
+		F96D491D08F272C3004A47F5 /* bn_mp_mul_d.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D429F08F272B3004A47F5 /* bn_mp_mul_d.c */; };
+		F96D492908F272C3004A47F5 /* bn_mp_radix_size.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42AB08F272B3004A47F5 /* bn_mp_radix_size.c */; };
+		F96D492A08F272C3004A47F5 /* bn_mp_radix_smap.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42AC08F272B3004A47F5 /* bn_mp_radix_smap.c */; };
+		F96D492C08F272C3004A47F5 /* bn_mp_read_radix.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42AE08F272B3004A47F5 /* bn_mp_read_radix.c */; };
+		F96D493708F272C3004A47F5 /* bn_mp_rshd.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42B908F272B3004A47F5 /* bn_mp_rshd.c */; };
+		F96D493808F272C3004A47F5 /* bn_mp_set.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42BA08F272B3004A47F5 /* bn_mp_set.c */; };
+		F96D493C08F272C3004A47F5 /* bn_mp_sqr.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42BE08F272B3004A47F5 /* bn_mp_sqr.c */; };
+		F96D493F08F272C3004A47F5 /* bn_mp_sub.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42C108F272B3004A47F5 /* bn_mp_sub.c */; };
+		F96D494008F272C3004A47F5 /* bn_mp_sub_d.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42C208F272B3004A47F5 /* bn_mp_sub_d.c */; };
+		F96D494608F272C3004A47F5 /* bn_mp_toom_mul.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42C808F272B3004A47F5 /* bn_mp_toom_mul.c */; };
+		F96D494708F272C3004A47F5 /* bn_mp_toom_sqr.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42C908F272B3004A47F5 /* bn_mp_toom_sqr.c */; };
+		F96D494908F272C3004A47F5 /* bn_mp_toradix_n.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42CB08F272B3004A47F5 /* bn_mp_toradix_n.c */; };
+		F96D494C08F272C3004A47F5 /* bn_mp_zero.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42CE08F272B3004A47F5 /* bn_mp_zero.c */; };
+		F96D494E08F272C3004A47F5 /* bn_reverse.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42D008F272B3004A47F5 /* bn_reverse.c */; };
+		F96D494F08F272C3004A47F5 /* bn_s_mp_add.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42D108F272B3004A47F5 /* bn_s_mp_add.c */; };
+		F96D495108F272C3004A47F5 /* bn_s_mp_mul_digs.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42D308F272B3004A47F5 /* bn_s_mp_mul_digs.c */; };
+		F96D495308F272C3004A47F5 /* bn_s_mp_sqr.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42D508F272B3004A47F5 /* bn_s_mp_sqr.c */; };
+		F96D495408F272C3004A47F5 /* bn_s_mp_sub.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42D608F272B3004A47F5 /* bn_s_mp_sub.c */; };
+		F96D495508F272C3004A47F5 /* bncore.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42D708F272B3004A47F5 /* bncore.c */; };
+		F96D49A908F272C4004A47F5 /* tclMacOSXBundle.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D433908F272B5004A47F5 /* tclMacOSXBundle.c */; };
+		F96D49AD08F272C4004A47F5 /* tclMacOSXFCmd.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D433D08F272B5004A47F5 /* tclMacOSXFCmd.c */; };
+		F96D49AE08F272C4004A47F5 /* tclMacOSXNotify.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D433E08F272B5004A47F5 /* tclMacOSXNotify.c */; };
+		F96D4AC608F272C9004A47F5 /* tclLoadDyld.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D445B08F272B9004A47F5 /* tclLoadDyld.c */; settings = {COMPILER_FLAGS = "-Wno-deprecated-declarations"; }; };
+		F96D4ACA08F272C9004A47F5 /* tclUnixChan.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D445F08F272B9004A47F5 /* tclUnixChan.c */; };
+		F96D4ACB08F272C9004A47F5 /* tclUnixEvent.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D446008F272B9004A47F5 /* tclUnixEvent.c */; };
+		F96D4ACC08F272C9004A47F5 /* tclUnixFCmd.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D446108F272B9004A47F5 /* tclUnixFCmd.c */; };
+		F96D4ACD08F272C9004A47F5 /* tclUnixFile.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D446208F272B9004A47F5 /* tclUnixFile.c */; };
+		F96D4ACE08F272C9004A47F5 /* tclUnixInit.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D446308F272B9004A47F5 /* tclUnixInit.c */; settings = {COMPILER_FLAGS = "-DTCL_LIBRARY=\\\"$(TCL_LIBRARY)\\\" -DTCL_PACKAGE_PATH=\\\"$(TCL_PACKAGE_PATH)\\\""; }; };
+		F96D4ACF08F272C9004A47F5 /* tclUnixNotfy.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D446408F272B9004A47F5 /* tclUnixNotfy.c */; };
+		F96D4AD008F272C9004A47F5 /* tclUnixPipe.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D446508F272B9004A47F5 /* tclUnixPipe.c */; };
+		F96D4AD208F272CA004A47F5 /* tclUnixSock.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D446708F272B9004A47F5 /* tclUnixSock.c */; };
+		F96D4AD308F272CA004A47F5 /* tclUnixTest.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D446808F272B9004A47F5 /* tclUnixTest.c */; };
+		F96D4AD408F272CA004A47F5 /* tclUnixThrd.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D446908F272B9004A47F5 /* tclUnixThrd.c */; };
+		F96D4AD608F272CA004A47F5 /* tclUnixTime.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D446B08F272B9004A47F5 /* tclUnixTime.c */; };
+		F9E61D28090A481F002B3151 /* bn_mp_cmp_d.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427108F272B3004A47F5 /* bn_mp_cmp_d.c */; };
+		F9E61D29090A486C002B3151 /* bn_mp_neg.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42A208F272B3004A47F5 /* bn_mp_neg.c */; };
+		F9E61D2A090A4891002B3151 /* bn_mp_sqrt.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42C008F272B3004A47F5 /* bn_mp_sqrt.c */; };
+		F9E61D2B090A48A4002B3151 /* bn_mp_and.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D426C08F272B3004A47F5 /* bn_mp_and.c */; };
+		F9E61D2C090A48AC002B3151 /* bn_mp_expt_d.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D427F08F272B3004A47F5 /* bn_mp_expt_d.c */; };
+		F9E61D2D090A48BB002B3151 /* bn_mp_xor.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42CD08F272B3004A47F5 /* bn_mp_xor.c */; };
+		F9E61D2E090A48BF002B3151 /* bn_mp_or.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42A308F272B3004A47F5 /* bn_mp_or.c */; };
+		F9E61D2F090A48C7002B3151 /* bn_mp_shrink.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42BC08F272B3004A47F5 /* bn_mp_shrink.c */; };
+		F9E61D30090A48E2002B3151 /* bn_mp_to_unsigned_bin_n.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42C708F272B3004A47F5 /* bn_mp_to_unsigned_bin_n.c */; };
+		F9E61D31090A48F9002B3151 /* bn_mp_to_unsigned_bin.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42C608F272B3004A47F5 /* bn_mp_to_unsigned_bin.c */; };
+		F9E61D32090A48FA002B3151 /* bn_mp_unsigned_bin_size.c in Sources */ = {isa = PBXBuildFile; fileRef = F96D42CC08F272B3004A47F5 /* bn_mp_unsigned_bin_size.c */; };
+		F9F4415E0C8BAE6F00BCCD67 /* tclDTrace.d in Sources */ = {isa = PBXBuildFile; fileRef = F9F4415D0C8BAE6F00BCCD67 /* tclDTrace.d */; };
+		F9FC77B80AB29E9100B7077D /* tclUnixCompat.c in Sources */ = {isa = PBXBuildFile; fileRef = F9FC77B70AB29E9100B7077D /* tclUnixCompat.c */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXContainerItemProxy section */
+		F97258D20A868C6F00096C78 /* PBXContainerItemProxy */ = {
+			isa = PBXContainerItemProxy;
+			containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */;
+			proxyType = 1;
+			remoteGlobalIDString = 8DD76FA90486AB0100D96B5E;
+			remoteInfo = tcltest;
+		};
+/* End PBXContainerItemProxy section */
+
+/* Begin PBXFileReference section */
+		8DD76FB20486AB0100D96B5E /* tcltest */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = tcltest; sourceTree = BUILT_PRODUCTS_DIR; };
+		F915432A0EF201CF0032D1E8 /* zlib.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = zlib.test; sourceTree = "<group>"; };
+		F915432D0EF201EE0032D1E8 /* zlib.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = zlib.n; sourceTree = "<group>"; };
+		F9183E640EFC80CD0030B814 /* throw.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = throw.n; sourceTree = "<group>"; };
+		F9183E650EFC80D70030B814 /* try.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = try.n; sourceTree = "<group>"; };
+		F9183E6A0EFC81560030B814 /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
+		F9183E8F0EFC817B0030B814 /* tdbc */ = {isa = PBXFileReference; lastKnownFileType = folder; path = tdbc; sourceTree = "<group>"; };
+		F91DC23C0E44C51B002CB8D1 /* nre.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = nre.test; sourceTree = "<group>"; };
+		F91E62260C1AE686006C9D96 /* Tclsh-Info.plist.in */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = "Tclsh-Info.plist.in"; sourceTree = "<group>"; };
+		F92D7F100DE777240033A13A /* tsdPerf.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tsdPerf.tcl; sourceTree = "<group>"; };
+		F93599B20DF1F75400E04F67 /* tclOO.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclOO.c; sourceTree = "<group>"; };
+		F93599B40DF1F75900E04F67 /* tclOO.decls */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tclOO.decls; sourceTree = "<group>"; };
+		F93599B50DF1F75D00E04F67 /* tclOO.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclOO.h; sourceTree = "<group>"; };
+		F93599B60DF1F76100E04F67 /* tclOOBasic.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclOOBasic.c; sourceTree = "<group>"; };
+		F93599B80DF1F76600E04F67 /* tclOOCall.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclOOCall.c; sourceTree = "<group>"; };
+		F93599BA0DF1F76A00E04F67 /* tclOODecls.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclOODecls.h; sourceTree = "<group>"; };
+		F93599BB0DF1F77000E04F67 /* tclOODefineCmds.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclOODefineCmds.c; sourceTree = "<group>"; };
+		F93599BD0DF1F77400E04F67 /* tclOOInfo.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclOOInfo.c; sourceTree = "<group>"; };
+		F93599BF0DF1F77900E04F67 /* tclOOInt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclOOInt.h; sourceTree = "<group>"; };
+		F93599C00DF1F77D00E04F67 /* tclOOIntDecls.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclOOIntDecls.h; sourceTree = "<group>"; };
+		F93599C10DF1F78300E04F67 /* tclOOMethod.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclOOMethod.c; sourceTree = "<group>"; };
+		F93599C30DF1F78800E04F67 /* tclOOStubInit.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclOOStubInit.c; sourceTree = "<group>"; };
+		F93599C50DF1F78D00E04F67 /* tclOOStubLib.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclOOStubLib.c; sourceTree = "<group>"; };
+		F93599C80DF1F81900E04F67 /* oo.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = oo.test; sourceTree = "<group>"; };
+		F93599CF0DF1F87F00E04F67 /* Class.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Class.3; sourceTree = "<group>"; };
+		F93599D00DF1F89E00E04F67 /* class.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = class.n; sourceTree = "<group>"; };
+		F93599D20DF1F8DF00E04F67 /* copy.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = copy.n; sourceTree = "<group>"; };
+		F93599D30DF1F8F500E04F67 /* define.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = define.n; sourceTree = "<group>"; };
+		F93599D40DF1F91900E04F67 /* Method.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Method.3; sourceTree = "<group>"; };
+		F93599D50DF1F93700E04F67 /* my.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = my.n; sourceTree = "<group>"; };
+		F93599D60DF1F95000E04F67 /* next.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = next.n; sourceTree = "<group>"; };
+		F93599D70DF1F96800E04F67 /* object.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = object.n; sourceTree = "<group>"; };
+		F93599D80DF1F98300E04F67 /* self.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = self.n; sourceTree = "<group>"; };
+		F946FB8B0FBE3AED00CD6495 /* itcl */ = {isa = PBXFileReference; lastKnownFileType = folder; path = itcl; sourceTree = "<group>"; };
+		F95D77E90DFD820D00A8BF6F /* tclIORTrans.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclIORTrans.c; sourceTree = "<group>"; };
+		F95FAFF90B34F1130072E431 /* macOSXLoad.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = macOSXLoad.test; sourceTree = "<group>"; };
+		F96437C90EF0D4B2003F468E /* tclZlib.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclZlib.c; sourceTree = "<group>"; };
+		F96437E60EF0D652003F468E /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = /usr/lib/libz.dylib; sourceTree = "<absolute>"; };
+		F966C07408F2820D005CB29B /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = /System/Library/Frameworks/CoreFoundation.framework; sourceTree = "<absolute>"; };
+		F96D3DFA08F272A4004A47F5 /* ChangeLog */ = {isa = PBXFileReference; explicitFileType = text; fileEncoding = 4; path = ChangeLog; sourceTree = "<group>"; };
+		F96D3DFB08F272A4004A47F5 /* changes */ = {isa = PBXFileReference; explicitFileType = text; fileEncoding = 4; path = changes; sourceTree = "<group>"; };
+		F96D3DFD08F272A4004A47F5 /* Access.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Access.3; sourceTree = "<group>"; };
+		F96D3DFE08F272A4004A47F5 /* AddErrInfo.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = AddErrInfo.3; sourceTree = "<group>"; };
+		F96D3DFF08F272A4004A47F5 /* after.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = after.n; sourceTree = "<group>"; };
+		F96D3E0008F272A4004A47F5 /* Alloc.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Alloc.3; sourceTree = "<group>"; };
+		F96D3E0108F272A4004A47F5 /* AllowExc.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = AllowExc.3; sourceTree = "<group>"; };
+		F96D3E0208F272A4004A47F5 /* append.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = append.n; sourceTree = "<group>"; };
+		F96D3E0308F272A4004A47F5 /* AppInit.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = AppInit.3; sourceTree = "<group>"; };
+		F96D3E0408F272A5004A47F5 /* array.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = array.n; sourceTree = "<group>"; };
+		F96D3E0508F272A5004A47F5 /* AssocData.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = AssocData.3; sourceTree = "<group>"; };
+		F96D3E0608F272A5004A47F5 /* Async.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Async.3; sourceTree = "<group>"; };
+		F96D3E0708F272A5004A47F5 /* BackgdErr.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = BackgdErr.3; sourceTree = "<group>"; };
+		F96D3E0808F272A5004A47F5 /* Backslash.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Backslash.3; sourceTree = "<group>"; };
+		F96D3E0908F272A5004A47F5 /* bgerror.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = bgerror.n; sourceTree = "<group>"; };
+		F96D3E0A08F272A5004A47F5 /* binary.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = binary.n; sourceTree = "<group>"; };
+		F96D3E0B08F272A5004A47F5 /* BoolObj.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = BoolObj.3; sourceTree = "<group>"; };
+		F96D3E0C08F272A5004A47F5 /* break.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = break.n; sourceTree = "<group>"; };
+		F96D3E0D08F272A5004A47F5 /* ByteArrObj.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ByteArrObj.3; sourceTree = "<group>"; };
+		F96D3E0E08F272A5004A47F5 /* CallDel.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CallDel.3; sourceTree = "<group>"; };
+		F96D3E0F08F272A5004A47F5 /* case.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = case.n; sourceTree = "<group>"; };
+		F96D3E1008F272A5004A47F5 /* catch.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = catch.n; sourceTree = "<group>"; };
+		F96D3E1108F272A5004A47F5 /* cd.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = cd.n; sourceTree = "<group>"; };
+		F96D3E1208F272A5004A47F5 /* chan.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = chan.n; sourceTree = "<group>"; };
+		F96D3E1308F272A5004A47F5 /* ChnlStack.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ChnlStack.3; sourceTree = "<group>"; };
+		F96D3E1408F272A5004A47F5 /* clock.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = clock.n; sourceTree = "<group>"; };
+		F96D3E1508F272A5004A47F5 /* close.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = close.n; sourceTree = "<group>"; };
+		F96D3E1608F272A5004A47F5 /* CmdCmplt.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CmdCmplt.3; sourceTree = "<group>"; };
+		F96D3E1708F272A5004A47F5 /* Concat.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Concat.3; sourceTree = "<group>"; };
+		F96D3E1808F272A5004A47F5 /* concat.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = concat.n; sourceTree = "<group>"; };
+		F96D3E1908F272A5004A47F5 /* continue.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = continue.n; sourceTree = "<group>"; };
+		F96D3E1A08F272A5004A47F5 /* CrtChannel.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtChannel.3; sourceTree = "<group>"; };
+		F96D3E1B08F272A5004A47F5 /* CrtChnlHdlr.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtChnlHdlr.3; sourceTree = "<group>"; };
+		F96D3E1C08F272A5004A47F5 /* CrtCloseHdlr.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtCloseHdlr.3; sourceTree = "<group>"; };
+		F96D3E1D08F272A5004A47F5 /* CrtCommand.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtCommand.3; sourceTree = "<group>"; };
+		F96D3E1E08F272A5004A47F5 /* CrtFileHdlr.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtFileHdlr.3; sourceTree = "<group>"; };
+		F96D3E1F08F272A5004A47F5 /* CrtInterp.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtInterp.3; sourceTree = "<group>"; };
+		F96D3E2008F272A5004A47F5 /* CrtMathFnc.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtMathFnc.3; sourceTree = "<group>"; };
+		F96D3E2108F272A5004A47F5 /* CrtObjCmd.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtObjCmd.3; sourceTree = "<group>"; };
+		F96D3E2208F272A5004A47F5 /* CrtSlave.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtSlave.3; sourceTree = "<group>"; };
+		F96D3E2308F272A5004A47F5 /* CrtTimerHdlr.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtTimerHdlr.3; sourceTree = "<group>"; };
+		F96D3E2408F272A5004A47F5 /* CrtTrace.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = CrtTrace.3; sourceTree = "<group>"; };
+		F96D3E2508F272A5004A47F5 /* dde.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = dde.n; sourceTree = "<group>"; };
+		F96D3E2608F272A5004A47F5 /* DetachPids.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = DetachPids.3; sourceTree = "<group>"; };
+		F96D3E2708F272A5004A47F5 /* dict.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = dict.n; sourceTree = "<group>"; };
+		F96D3E2808F272A5004A47F5 /* DictObj.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = DictObj.3; sourceTree = "<group>"; };
+		F96D3E2908F272A5004A47F5 /* DoOneEvent.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = DoOneEvent.3; sourceTree = "<group>"; };
+		F96D3E2A08F272A5004A47F5 /* DoubleObj.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = DoubleObj.3; sourceTree = "<group>"; };
+		F96D3E2B08F272A5004A47F5 /* DoWhenIdle.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = DoWhenIdle.3; sourceTree = "<group>"; };
+		F96D3E2C08F272A5004A47F5 /* DString.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = DString.3; sourceTree = "<group>"; };
+		F96D3E2D08F272A5004A47F5 /* DumpActiveMemory.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = DumpActiveMemory.3; sourceTree = "<group>"; };
+		F96D3E2E08F272A5004A47F5 /* Encoding.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Encoding.3; sourceTree = "<group>"; };
+		F96D3E2F08F272A5004A47F5 /* encoding.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = encoding.n; sourceTree = "<group>"; };
+		F96D3E3008F272A5004A47F5 /* Ensemble.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Ensemble.3; sourceTree = "<group>"; };
+		F96D3E3108F272A5004A47F5 /* Environment.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Environment.3; sourceTree = "<group>"; };
+		F96D3E3208F272A5004A47F5 /* eof.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = eof.n; sourceTree = "<group>"; };
+		F96D3E3308F272A5004A47F5 /* error.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = error.n; sourceTree = "<group>"; };
+		F96D3E3408F272A5004A47F5 /* Eval.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Eval.3; sourceTree = "<group>"; };
+		F96D3E3508F272A5004A47F5 /* eval.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = eval.n; sourceTree = "<group>"; };
+		F96D3E3608F272A5004A47F5 /* exec.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = exec.n; sourceTree = "<group>"; };
+		F96D3E3708F272A5004A47F5 /* Exit.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Exit.3; sourceTree = "<group>"; };
+		F96D3E3808F272A5004A47F5 /* exit.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = exit.n; sourceTree = "<group>"; };
+		F96D3E3908F272A5004A47F5 /* expr.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = expr.n; sourceTree = "<group>"; };
+		F96D3E3A08F272A5004A47F5 /* ExprLong.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ExprLong.3; sourceTree = "<group>"; };
+		F96D3E3B08F272A5004A47F5 /* ExprLongObj.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ExprLongObj.3; sourceTree = "<group>"; };
+		F96D3E3C08F272A5004A47F5 /* fblocked.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = fblocked.n; sourceTree = "<group>"; };
+		F96D3E3D08F272A5004A47F5 /* fconfigure.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = fconfigure.n; sourceTree = "<group>"; };
+		F96D3E3E08F272A5004A47F5 /* fcopy.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = fcopy.n; sourceTree = "<group>"; };
+		F96D3E3F08F272A5004A47F5 /* file.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = file.n; sourceTree = "<group>"; };
+		F96D3E4008F272A5004A47F5 /* fileevent.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = fileevent.n; sourceTree = "<group>"; };
+		F96D3E4108F272A5004A47F5 /* filename.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = filename.n; sourceTree = "<group>"; };
+		F96D3E4208F272A5004A47F5 /* FileSystem.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = FileSystem.3; sourceTree = "<group>"; };
+		F96D3E4308F272A5004A47F5 /* FindExec.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = FindExec.3; sourceTree = "<group>"; };
+		F96D3E4408F272A5004A47F5 /* flush.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = flush.n; sourceTree = "<group>"; };
+		F96D3E4508F272A5004A47F5 /* for.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = for.n; sourceTree = "<group>"; };
+		F96D3E4608F272A5004A47F5 /* foreach.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = foreach.n; sourceTree = "<group>"; };
+		F96D3E4708F272A5004A47F5 /* format.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = format.n; sourceTree = "<group>"; };
+		F96D3E4808F272A5004A47F5 /* GetCwd.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetCwd.3; sourceTree = "<group>"; };
+		F96D3E4908F272A5004A47F5 /* GetHostName.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetHostName.3; sourceTree = "<group>"; };
+		F96D3E4A08F272A5004A47F5 /* GetIndex.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetIndex.3; sourceTree = "<group>"; };
+		F96D3E4B08F272A5004A47F5 /* GetInt.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetInt.3; sourceTree = "<group>"; };
+		F96D3E4C08F272A5004A47F5 /* GetOpnFl.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetOpnFl.3; sourceTree = "<group>"; };
+		F96D3E4D08F272A5004A47F5 /* gets.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = gets.n; sourceTree = "<group>"; };
+		F96D3E4E08F272A5004A47F5 /* GetStdChan.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetStdChan.3; sourceTree = "<group>"; };
+		F96D3E4F08F272A5004A47F5 /* GetTime.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetTime.3; sourceTree = "<group>"; };
+		F96D3E5008F272A5004A47F5 /* GetVersion.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = GetVersion.3; sourceTree = "<group>"; };
+		F96D3E5108F272A5004A47F5 /* glob.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = glob.n; sourceTree = "<group>"; };
+		F96D3E5208F272A6004A47F5 /* global.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = global.n; sourceTree = "<group>"; };
+		F96D3E5308F272A6004A47F5 /* Hash.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Hash.3; sourceTree = "<group>"; };
+		F96D3E5408F272A6004A47F5 /* history.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = history.n; sourceTree = "<group>"; };
+		F96D3E5508F272A6004A47F5 /* http.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = http.n; sourceTree = "<group>"; };
+		F96D3E5608F272A6004A47F5 /* if.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = if.n; sourceTree = "<group>"; };
+		F96D3E5708F272A6004A47F5 /* incr.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = incr.n; sourceTree = "<group>"; };
+		F96D3E5808F272A6004A47F5 /* info.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = info.n; sourceTree = "<group>"; };
+		F96D3E5908F272A6004A47F5 /* Init.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Init.3; sourceTree = "<group>"; };
+		F96D3E5A08F272A6004A47F5 /* InitStubs.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = InitStubs.3; sourceTree = "<group>"; };
+		F96D3E5B08F272A6004A47F5 /* Interp.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Interp.3; sourceTree = "<group>"; };
+		F96D3E5C08F272A6004A47F5 /* interp.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = interp.n; sourceTree = "<group>"; };
+		F96D3E5D08F272A6004A47F5 /* IntObj.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = IntObj.3; sourceTree = "<group>"; };
+		F96D3E5E08F272A6004A47F5 /* join.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = join.n; sourceTree = "<group>"; };
+		F96D3E5F08F272A6004A47F5 /* lappend.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = lappend.n; sourceTree = "<group>"; };
+		F96D3E6008F272A6004A47F5 /* lassign.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = lassign.n; sourceTree = "<group>"; };
+		F96D3E6108F272A6004A47F5 /* library.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = library.n; sourceTree = "<group>"; };
+		F96D3E6208F272A6004A47F5 /* Limit.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Limit.3; sourceTree = "<group>"; };
+		F96D3E6308F272A6004A47F5 /* lindex.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = lindex.n; sourceTree = "<group>"; };
+		F96D3E6408F272A6004A47F5 /* LinkVar.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = LinkVar.3; sourceTree = "<group>"; };
+		F96D3E6508F272A6004A47F5 /* linsert.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = linsert.n; sourceTree = "<group>"; };
+		F96D3E6608F272A6004A47F5 /* list.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = list.n; sourceTree = "<group>"; };
+		F96D3E6708F272A6004A47F5 /* ListObj.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ListObj.3; sourceTree = "<group>"; };
+		F96D3E6808F272A6004A47F5 /* llength.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = llength.n; sourceTree = "<group>"; };
+		F96D3E6908F272A6004A47F5 /* load.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = load.n; sourceTree = "<group>"; };
+		F96D3E6A08F272A6004A47F5 /* lrange.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = lrange.n; sourceTree = "<group>"; };
+		F96D3E6B08F272A6004A47F5 /* lrepeat.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = lrepeat.n; sourceTree = "<group>"; };
+		F96D3E6C08F272A6004A47F5 /* lreplace.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = lreplace.n; sourceTree = "<group>"; };
+		F96D3E6D08F272A6004A47F5 /* lsearch.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = lsearch.n; sourceTree = "<group>"; };
+		F96D3E6E08F272A6004A47F5 /* lset.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = lset.n; sourceTree = "<group>"; };
+		F96D3E6F08F272A6004A47F5 /* lsort.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = lsort.n; sourceTree = "<group>"; };
+		F96D3E7008F272A6004A47F5 /* man.macros */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = man.macros; sourceTree = "<group>"; };
+		F96D3E7108F272A6004A47F5 /* mathfunc.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = mathfunc.n; sourceTree = "<group>"; };
+		F96D3E7208F272A6004A47F5 /* memory.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = memory.n; sourceTree = "<group>"; };
+		F96D3E7308F272A6004A47F5 /* msgcat.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = msgcat.n; sourceTree = "<group>"; };
+		F96D3E7408F272A6004A47F5 /* Namespace.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Namespace.3; sourceTree = "<group>"; };
+		F96D3E7508F272A6004A47F5 /* namespace.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = namespace.n; sourceTree = "<group>"; };
+		F96D3E7608F272A6004A47F5 /* Notifier.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Notifier.3; sourceTree = "<group>"; };
+		F96D3E7708F272A6004A47F5 /* Object.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Object.3; sourceTree = "<group>"; };
+		F96D3E7808F272A6004A47F5 /* ObjectType.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ObjectType.3; sourceTree = "<group>"; };
+		F96D3E7908F272A6004A47F5 /* open.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = open.n; sourceTree = "<group>"; };
+		F96D3E7A08F272A6004A47F5 /* OpenFileChnl.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = OpenFileChnl.3; sourceTree = "<group>"; };
+		F96D3E7B08F272A6004A47F5 /* OpenTcp.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = OpenTcp.3; sourceTree = "<group>"; };
+		F96D3E7C08F272A6004A47F5 /* package.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = package.n; sourceTree = "<group>"; };
+		F96D3E7D08F272A6004A47F5 /* packagens.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = packagens.n; sourceTree = "<group>"; };
+		F96D3E7E08F272A6004A47F5 /* Panic.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Panic.3; sourceTree = "<group>"; };
+		F96D3E7F08F272A6004A47F5 /* ParseCmd.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ParseCmd.3; sourceTree = "<group>"; };
+		F96D3E8008F272A6004A47F5 /* pid.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = pid.n; sourceTree = "<group>"; };
+		F96D3E8108F272A6004A47F5 /* pkgMkIndex.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = pkgMkIndex.n; sourceTree = "<group>"; };
+		F96D3E8208F272A6004A47F5 /* PkgRequire.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = PkgRequire.3; sourceTree = "<group>"; };
+		F96D3E8308F272A6004A47F5 /* Preserve.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Preserve.3; sourceTree = "<group>"; };
+		F96D3E8408F272A6004A47F5 /* PrintDbl.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = PrintDbl.3; sourceTree = "<group>"; };
+		F96D3E8508F272A6004A47F5 /* proc.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = proc.n; sourceTree = "<group>"; };
+		F96D3E8608F272A6004A47F5 /* puts.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = puts.n; sourceTree = "<group>"; };
+		F96D3E8708F272A6004A47F5 /* pwd.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = pwd.n; sourceTree = "<group>"; };
+		F96D3E8808F272A6004A47F5 /* re_syntax.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = re_syntax.n; sourceTree = "<group>"; };
+		F96D3E8908F272A6004A47F5 /* read.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = read.n; sourceTree = "<group>"; };
+		F96D3E8A08F272A6004A47F5 /* RecEvalObj.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = RecEvalObj.3; sourceTree = "<group>"; };
+		F96D3E8B08F272A6004A47F5 /* RecordEval.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = RecordEval.3; sourceTree = "<group>"; };
+		F96D3E8C08F272A6004A47F5 /* RegConfig.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = RegConfig.3; sourceTree = "<group>"; };
+		F96D3E8D08F272A6004A47F5 /* RegExp.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = RegExp.3; sourceTree = "<group>"; };
+		F96D3E8E08F272A6004A47F5 /* regexp.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = regexp.n; sourceTree = "<group>"; };
+		F96D3E8F08F272A6004A47F5 /* registry.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = registry.n; sourceTree = "<group>"; };
+		F96D3E9008F272A6004A47F5 /* regsub.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = regsub.n; sourceTree = "<group>"; };
+		F96D3E9108F272A6004A47F5 /* rename.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = rename.n; sourceTree = "<group>"; };
+		F96D3E9208F272A6004A47F5 /* return.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = return.n; sourceTree = "<group>"; };
+		F96D3E9308F272A6004A47F5 /* safe.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = safe.n; sourceTree = "<group>"; };
+		F96D3E9408F272A6004A47F5 /* SaveResult.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SaveResult.3; sourceTree = "<group>"; };
+		F96D3E9508F272A6004A47F5 /* scan.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = scan.n; sourceTree = "<group>"; };
+		F96D3E9608F272A6004A47F5 /* seek.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = seek.n; sourceTree = "<group>"; };
+		F96D3E9708F272A6004A47F5 /* set.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = set.n; sourceTree = "<group>"; };
+		F96D3E9808F272A6004A47F5 /* SetChanErr.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SetChanErr.3; sourceTree = "<group>"; };
+		F96D3E9908F272A6004A47F5 /* SetErrno.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SetErrno.3; sourceTree = "<group>"; };
+		F96D3E9A08F272A6004A47F5 /* SetRecLmt.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SetRecLmt.3; sourceTree = "<group>"; };
+		F96D3E9B08F272A7004A47F5 /* SetResult.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SetResult.3; sourceTree = "<group>"; };
+		F96D3E9C08F272A7004A47F5 /* SetVar.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SetVar.3; sourceTree = "<group>"; };
+		F96D3E9D08F272A7004A47F5 /* Signal.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Signal.3; sourceTree = "<group>"; };
+		F96D3E9E08F272A7004A47F5 /* Sleep.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Sleep.3; sourceTree = "<group>"; };
+		F96D3E9F08F272A7004A47F5 /* socket.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = socket.n; sourceTree = "<group>"; };
+		F96D3EA008F272A7004A47F5 /* source.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = source.n; sourceTree = "<group>"; };
+		F96D3EA108F272A7004A47F5 /* SourceRCFile.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SourceRCFile.3; sourceTree = "<group>"; };
+		F96D3EA208F272A7004A47F5 /* split.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = split.n; sourceTree = "<group>"; };
+		F96D3EA308F272A7004A47F5 /* SplitList.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SplitList.3; sourceTree = "<group>"; };
+		F96D3EA408F272A7004A47F5 /* SplitPath.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SplitPath.3; sourceTree = "<group>"; };
+		F96D3EA508F272A7004A47F5 /* StaticPkg.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = StaticPkg.3; sourceTree = "<group>"; };
+		F96D3EA608F272A7004A47F5 /* StdChannels.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = StdChannels.3; sourceTree = "<group>"; };
+		F96D3EA708F272A7004A47F5 /* string.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = string.n; sourceTree = "<group>"; };
+		F96D3EA808F272A7004A47F5 /* StringObj.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = StringObj.3; sourceTree = "<group>"; };
+		F96D3EA908F272A7004A47F5 /* StrMatch.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = StrMatch.3; sourceTree = "<group>"; };
+		F96D3EAA08F272A7004A47F5 /* subst.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = subst.n; sourceTree = "<group>"; };
+		F96D3EAB08F272A7004A47F5 /* SubstObj.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = SubstObj.3; sourceTree = "<group>"; };
+		F96D3EAC08F272A7004A47F5 /* switch.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = switch.n; sourceTree = "<group>"; };
+		F96D3EAD08F272A7004A47F5 /* Tcl.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Tcl.n; sourceTree = "<group>"; };
+		F96D3EAE08F272A7004A47F5 /* Tcl_Main.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Tcl_Main.3; sourceTree = "<group>"; };
+		F96D3EAF08F272A7004A47F5 /* TCL_MEM_DEBUG.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = TCL_MEM_DEBUG.3; sourceTree = "<group>"; };
+		F96D3EB008F272A7004A47F5 /* tclsh.1 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = tclsh.1; sourceTree = "<group>"; };
+		F96D3EB108F272A7004A47F5 /* tcltest.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = tcltest.n; sourceTree = "<group>"; };
+		F96D3EB208F272A7004A47F5 /* tclvars.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = tclvars.n; sourceTree = "<group>"; };
+		F96D3EB308F272A7004A47F5 /* tell.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = tell.n; sourceTree = "<group>"; };
+		F96D3EB408F272A7004A47F5 /* Thread.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Thread.3; sourceTree = "<group>"; };
+		F96D3EB508F272A7004A47F5 /* time.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = time.n; sourceTree = "<group>"; };
+		F96D3EB608F272A7004A47F5 /* tm.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = tm.n; sourceTree = "<group>"; };
+		F96D3EB708F272A7004A47F5 /* ToUpper.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = ToUpper.3; sourceTree = "<group>"; };
+		F96D3EB808F272A7004A47F5 /* trace.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = trace.n; sourceTree = "<group>"; };
+		F96D3EB908F272A7004A47F5 /* TraceCmd.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = TraceCmd.3; sourceTree = "<group>"; };
+		F96D3EBA08F272A7004A47F5 /* TraceVar.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = TraceVar.3; sourceTree = "<group>"; };
+		F96D3EBB08F272A7004A47F5 /* Translate.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Translate.3; sourceTree = "<group>"; };
+		F96D3EBC08F272A7004A47F5 /* UniCharIsAlpha.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = UniCharIsAlpha.3; sourceTree = "<group>"; };
+		F96D3EBD08F272A7004A47F5 /* unknown.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = unknown.n; sourceTree = "<group>"; };
+		F96D3EBE08F272A7004A47F5 /* unload.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = unload.n; sourceTree = "<group>"; };
+		F96D3EBF08F272A7004A47F5 /* unset.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = unset.n; sourceTree = "<group>"; };
+		F96D3EC008F272A7004A47F5 /* update.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = update.n; sourceTree = "<group>"; };
+		F96D3EC108F272A7004A47F5 /* uplevel.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = uplevel.n; sourceTree = "<group>"; };
+		F96D3EC208F272A7004A47F5 /* UpVar.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = UpVar.3; sourceTree = "<group>"; };
+		F96D3EC308F272A7004A47F5 /* upvar.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = upvar.n; sourceTree = "<group>"; };
+		F96D3EC408F272A7004A47F5 /* Utf.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = Utf.3; sourceTree = "<group>"; };
+		F96D3EC508F272A7004A47F5 /* variable.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = variable.n; sourceTree = "<group>"; };
+		F96D3EC608F272A7004A47F5 /* vwait.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = vwait.n; sourceTree = "<group>"; };
+		F96D3EC708F272A7004A47F5 /* while.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = while.n; sourceTree = "<group>"; };
+		F96D3EC808F272A7004A47F5 /* WrongNumArgs.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = WrongNumArgs.3; sourceTree = "<group>"; };
+		F96D3ECA08F272A7004A47F5 /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
+		F96D3ECB08F272A7004A47F5 /* regc_color.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = regc_color.c; sourceTree = "<group>"; };
+		F96D3ECC08F272A7004A47F5 /* regc_cvec.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = regc_cvec.c; sourceTree = "<group>"; };
+		F96D3ECD08F272A7004A47F5 /* regc_lex.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = regc_lex.c; sourceTree = "<group>"; };
+		F96D3ECE08F272A7004A47F5 /* regc_locale.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = regc_locale.c; sourceTree = "<group>"; };
+		F96D3ECF08F272A7004A47F5 /* regc_nfa.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = regc_nfa.c; sourceTree = "<group>"; };
+		F96D3ED008F272A7004A47F5 /* regcomp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = regcomp.c; sourceTree = "<group>"; };
+		F96D3ED108F272A7004A47F5 /* regcustom.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = regcustom.h; sourceTree = "<group>"; };
+		F96D3ED208F272A7004A47F5 /* rege_dfa.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = rege_dfa.c; sourceTree = "<group>"; };
+		F96D3ED308F272A7004A47F5 /* regerror.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = regerror.c; sourceTree = "<group>"; };
+		F96D3ED408F272A7004A47F5 /* regerrs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = regerrs.h; sourceTree = "<group>"; };
+		F96D3ED508F272A7004A47F5 /* regex.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = regex.h; sourceTree = "<group>"; };
+		F96D3ED608F272A7004A47F5 /* regexec.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = regexec.c; sourceTree = "<group>"; };
+		F96D3ED708F272A7004A47F5 /* regfree.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = regfree.c; sourceTree = "<group>"; };
+		F96D3ED808F272A7004A47F5 /* regfronts.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = regfronts.c; sourceTree = "<group>"; };
+		F96D3ED908F272A7004A47F5 /* regguts.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = regguts.h; sourceTree = "<group>"; };
+		F96D3EDA08F272A7004A47F5 /* tcl.decls */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tcl.decls; sourceTree = "<group>"; };
+		F96D3EDB08F272A7004A47F5 /* tcl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tcl.h; sourceTree = "<group>"; };
+		F96D3EDC08F272A7004A47F5 /* tclAlloc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclAlloc.c; sourceTree = "<group>"; };
+		F96D3EDD08F272A7004A47F5 /* tclAsync.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclAsync.c; sourceTree = "<group>"; };
+		F96D3EDE08F272A7004A47F5 /* tclBasic.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclBasic.c; sourceTree = "<group>"; };
+		F96D3EDF08F272A7004A47F5 /* tclBinary.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclBinary.c; sourceTree = "<group>"; };
+		F96D3EE008F272A7004A47F5 /* tclCkalloc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclCkalloc.c; sourceTree = "<group>"; };
+		F96D3EE108F272A7004A47F5 /* tclClock.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclClock.c; sourceTree = "<group>"; };
+		F96D3EE208F272A7004A47F5 /* tclCmdAH.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclCmdAH.c; sourceTree = "<group>"; };
+		F96D3EE308F272A7004A47F5 /* tclCmdIL.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclCmdIL.c; sourceTree = "<group>"; };
+		F96D3EE408F272A7004A47F5 /* tclCmdMZ.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclCmdMZ.c; sourceTree = "<group>"; };
+		F96D3EE508F272A7004A47F5 /* tclCompCmds.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclCompCmds.c; sourceTree = "<group>"; };
+		F96D3EE608F272A7004A47F5 /* tclCompExpr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclCompExpr.c; sourceTree = "<group>"; };
+		F96D3EE708F272A7004A47F5 /* tclCompile.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclCompile.c; sourceTree = "<group>"; };
+		F96D3EE808F272A7004A47F5 /* tclCompile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclCompile.h; sourceTree = "<group>"; };
+		F96D3EE908F272A7004A47F5 /* tclConfig.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclConfig.c; sourceTree = "<group>"; };
+		F96D3EEA08F272A7004A47F5 /* tclDate.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclDate.c; sourceTree = "<group>"; };
+		F96D3EEB08F272A7004A47F5 /* tclDecls.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclDecls.h; sourceTree = "<group>"; };
+		F96D3EEC08F272A7004A47F5 /* tclDictObj.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclDictObj.c; sourceTree = "<group>"; };
+		F96D3EED08F272A7004A47F5 /* tclEncoding.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclEncoding.c; sourceTree = "<group>"; };
+		F96D3EEE08F272A7004A47F5 /* tclEnv.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclEnv.c; sourceTree = "<group>"; };
+		F96D3EEF08F272A7004A47F5 /* tclEvent.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclEvent.c; sourceTree = "<group>"; };
+		F96D3EF008F272A7004A47F5 /* tclExecute.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclExecute.c; sourceTree = "<group>"; };
+		F96D3EF108F272A7004A47F5 /* tclFCmd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclFCmd.c; sourceTree = "<group>"; };
+		F96D3EF208F272A7004A47F5 /* tclFileName.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclFileName.c; sourceTree = "<group>"; };
+		F96D3EF308F272A7004A47F5 /* tclFileSystem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclFileSystem.h; sourceTree = "<group>"; };
+		F96D3EF408F272A7004A47F5 /* tclGet.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclGet.c; sourceTree = "<group>"; };
+		F96D3EF508F272A7004A47F5 /* tclGetDate.y */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.yacc; path = tclGetDate.y; sourceTree = "<group>"; };
+		F96D3EF608F272A7004A47F5 /* tclHash.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclHash.c; sourceTree = "<group>"; };
+		F96D3EF708F272A7004A47F5 /* tclHistory.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclHistory.c; sourceTree = "<group>"; };
+		F96D3EF808F272A7004A47F5 /* tclIndexObj.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclIndexObj.c; sourceTree = "<group>"; };
+		F96D3EF908F272A7004A47F5 /* tclInt.decls */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tclInt.decls; sourceTree = "<group>"; };
+		F96D3EFA08F272A7004A47F5 /* tclInt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclInt.h; sourceTree = "<group>"; };
+		F96D3EFB08F272A7004A47F5 /* tclIntDecls.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclIntDecls.h; sourceTree = "<group>"; };
+		F96D3EFC08F272A7004A47F5 /* tclInterp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclInterp.c; sourceTree = "<group>"; };
+		F96D3EFD08F272A7004A47F5 /* tclIntPlatDecls.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclIntPlatDecls.h; sourceTree = "<group>"; };
+		F96D3EFE08F272A7004A47F5 /* tclIO.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclIO.c; sourceTree = "<group>"; };
+		F96D3EFF08F272A7004A47F5 /* tclIO.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclIO.h; sourceTree = "<group>"; };
+		F96D3F0008F272A7004A47F5 /* tclIOCmd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclIOCmd.c; sourceTree = "<group>"; };
+		F96D3F0108F272A7004A47F5 /* tclIOGT.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclIOGT.c; sourceTree = "<group>"; };
+		F96D3F0208F272A7004A47F5 /* tclIORChan.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclIORChan.c; sourceTree = "<group>"; };
+		F96D3F0308F272A7004A47F5 /* tclIOSock.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclIOSock.c; sourceTree = "<group>"; };
+		F96D3F0408F272A7004A47F5 /* tclIOUtil.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclIOUtil.c; sourceTree = "<group>"; };
+		F96D3F0508F272A7004A47F5 /* tclLink.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclLink.c; sourceTree = "<group>"; };
+		F96D3F0608F272A7004A47F5 /* tclListObj.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclListObj.c; sourceTree = "<group>"; };
+		F96D3F0708F272A7004A47F5 /* tclLiteral.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclLiteral.c; sourceTree = "<group>"; };
+		F96D3F0808F272A7004A47F5 /* tclLoad.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclLoad.c; sourceTree = "<group>"; };
+		F96D3F0908F272A7004A47F5 /* tclLoadNone.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclLoadNone.c; sourceTree = "<group>"; };
+		F96D3F0A08F272A7004A47F5 /* tclMain.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclMain.c; sourceTree = "<group>"; };
+		F96D3F0B08F272A7004A47F5 /* tclNamesp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclNamesp.c; sourceTree = "<group>"; };
+		F96D3F0C08F272A7004A47F5 /* tclNotify.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclNotify.c; sourceTree = "<group>"; };
+		F96D3F0D08F272A7004A47F5 /* tclObj.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclObj.c; sourceTree = "<group>"; };
+		F96D3F0E08F272A7004A47F5 /* tclPanic.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclPanic.c; sourceTree = "<group>"; };
+		F96D3F0F08F272A7004A47F5 /* tclParse.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclParse.c; sourceTree = "<group>"; };
+		F96D3F1108F272A7004A47F5 /* tclPathObj.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclPathObj.c; sourceTree = "<group>"; };
+		F96D3F1208F272A7004A47F5 /* tclPipe.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclPipe.c; sourceTree = "<group>"; };
+		F96D3F1308F272A7004A47F5 /* tclPkg.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclPkg.c; sourceTree = "<group>"; };
+		F96D3F1408F272A7004A47F5 /* tclPkgConfig.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclPkgConfig.c; sourceTree = "<group>"; };
+		F96D3F1508F272A7004A47F5 /* tclPlatDecls.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclPlatDecls.h; sourceTree = "<group>"; };
+		F96D3F1608F272A7004A47F5 /* tclPort.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclPort.h; sourceTree = "<group>"; };
+		F96D3F1708F272A7004A47F5 /* tclPosixStr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclPosixStr.c; sourceTree = "<group>"; };
+		F96D3F1808F272A7004A47F5 /* tclPreserve.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclPreserve.c; sourceTree = "<group>"; };
+		F96D3F1908F272A7004A47F5 /* tclProc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclProc.c; sourceTree = "<group>"; };
+		F96D3F1A08F272A7004A47F5 /* tclRegexp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclRegexp.c; sourceTree = "<group>"; };
+		F96D3F1B08F272A7004A47F5 /* tclRegexp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclRegexp.h; sourceTree = "<group>"; };
+		F96D3F1C08F272A7004A47F5 /* tclResolve.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclResolve.c; sourceTree = "<group>"; };
+		F96D3F1D08F272A7004A47F5 /* tclResult.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclResult.c; sourceTree = "<group>"; };
+		F96D3F1E08F272A7004A47F5 /* tclScan.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclScan.c; sourceTree = "<group>"; };
+		F96D3F1F08F272A7004A47F5 /* tclStringObj.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclStringObj.c; sourceTree = "<group>"; };
+		F96D3F2408F272A7004A47F5 /* tclStrToD.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclStrToD.c; sourceTree = "<group>"; };
+		F96D3F2508F272A7004A47F5 /* tclStubInit.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclStubInit.c; sourceTree = "<group>"; };
+		F96D3F2608F272A7004A47F5 /* tclStubLib.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclStubLib.c; sourceTree = "<group>"; };
+		F96D3F2708F272A7004A47F5 /* tclTest.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclTest.c; sourceTree = "<group>"; };
+		F96D3F2808F272A7004A47F5 /* tclTestObj.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclTestObj.c; sourceTree = "<group>"; };
+		F96D3F2908F272A7004A47F5 /* tclTestProcBodyObj.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclTestProcBodyObj.c; sourceTree = "<group>"; };
+		F96D3F2A08F272A7004A47F5 /* tclThread.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclThread.c; sourceTree = "<group>"; };
+		F96D3F2B08F272A7004A47F5 /* tclThreadAlloc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclThreadAlloc.c; sourceTree = "<group>"; };
+		F96D3F2C08F272A7004A47F5 /* tclThreadJoin.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclThreadJoin.c; sourceTree = "<group>"; };
+		F96D3F2D08F272A7004A47F5 /* tclThreadStorage.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclThreadStorage.c; sourceTree = "<group>"; };
+		F96D3F2E08F272A7004A47F5 /* tclThreadTest.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclThreadTest.c; sourceTree = "<group>"; };
+		F96D3F2F08F272A7004A47F5 /* tclTimer.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclTimer.c; sourceTree = "<group>"; };
+		F96D3F3008F272A7004A47F5 /* tclTomMath.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclTomMath.h; sourceTree = "<group>"; };
+		F96D3F3108F272A7004A47F5 /* tclTomMathInterface.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclTomMathInterface.c; sourceTree = "<group>"; };
+		F96D3F3208F272A7004A47F5 /* tclTrace.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclTrace.c; sourceTree = "<group>"; };
+		F96D3F3308F272A7004A47F5 /* tclUniData.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUniData.c; sourceTree = "<group>"; };
+		F96D3F3408F272A7004A47F5 /* tclUtf.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUtf.c; sourceTree = "<group>"; };
+		F96D3F3508F272A7004A47F5 /* tclUtil.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUtil.c; sourceTree = "<group>"; };
+		F96D3F3608F272A7004A47F5 /* tclVar.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclVar.c; sourceTree = "<group>"; };
+		F96D3F3708F272A7004A47F5 /* tommath.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tommath.h; sourceTree = "<group>"; };
+		F96D3F3908F272A8004A47F5 /* auto.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = auto.tcl; sourceTree = "<group>"; };
+		F96D3F3A08F272A8004A47F5 /* clock.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = clock.tcl; sourceTree = "<group>"; };
+		F96D3F3C08F272A8004A47F5 /* pkgIndex.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = pkgIndex.tcl; sourceTree = "<group>"; };
+		F96D3F8C08F272A8004A47F5 /* history.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = history.tcl; sourceTree = "<group>"; };
+		F96D3F8E08F272A8004A47F5 /* http.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = http.tcl; sourceTree = "<group>"; };
+		F96D3F8F08F272A8004A47F5 /* pkgIndex.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = pkgIndex.tcl; sourceTree = "<group>"; };
+		F96D3F9108F272A8004A47F5 /* http.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = http.tcl; sourceTree = "<group>"; };
+		F96D3F9208F272A8004A47F5 /* pkgIndex.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = pkgIndex.tcl; sourceTree = "<group>"; };
+		F96D3F9308F272A8004A47F5 /* init.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = init.tcl; sourceTree = "<group>"; };
+		F96D3F9508F272A8004A47F5 /* msgcat.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = msgcat.tcl; sourceTree = "<group>"; };
+		F96D3F9608F272A8004A47F5 /* pkgIndex.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = pkgIndex.tcl; sourceTree = "<group>"; };
+		F96D401808F272AA004A47F5 /* optparse.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = optparse.tcl; sourceTree = "<group>"; };
+		F96D401908F272AA004A47F5 /* pkgIndex.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = pkgIndex.tcl; sourceTree = "<group>"; };
+		F96D401A08F272AA004A47F5 /* package.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = package.tcl; sourceTree = "<group>"; };
+		F96D401B08F272AA004A47F5 /* parray.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = parray.tcl; sourceTree = "<group>"; };
+		F96D401D08F272AA004A47F5 /* pkgIndex.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = pkgIndex.tcl; sourceTree = "<group>"; };
+		F96D401E08F272AA004A47F5 /* safe.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = safe.tcl; sourceTree = "<group>"; };
+		F96D401F08F272AA004A47F5 /* tclIndex */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tclIndex; sourceTree = "<group>"; };
+		F96D402108F272AA004A47F5 /* pkgIndex.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = pkgIndex.tcl; sourceTree = "<group>"; };
+		F96D402208F272AA004A47F5 /* tcltest.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tcltest.tcl; sourceTree = "<group>"; };
+		F96D402308F272AA004A47F5 /* tm.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tm.tcl; sourceTree = "<group>"; };
+		F96D425B08F272B2004A47F5 /* word.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = word.tcl; sourceTree = "<group>"; };
+		F96D426408F272B3004A47F5 /* bn_fast_s_mp_mul_digs.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_fast_s_mp_mul_digs.c; sourceTree = "<group>"; };
+		F96D426608F272B3004A47F5 /* bn_fast_s_mp_sqr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_fast_s_mp_sqr.c; sourceTree = "<group>"; };
+		F96D426908F272B3004A47F5 /* bn_mp_add.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_add.c; sourceTree = "<group>"; };
+		F96D426A08F272B3004A47F5 /* bn_mp_add_d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_add_d.c; sourceTree = "<group>"; };
+		F96D426C08F272B3004A47F5 /* bn_mp_and.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_and.c; sourceTree = "<group>"; };
+		F96D426D08F272B3004A47F5 /* bn_mp_clamp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_clamp.c; sourceTree = "<group>"; };
+		F96D426E08F272B3004A47F5 /* bn_mp_clear.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_clear.c; sourceTree = "<group>"; };
+		F96D426F08F272B3004A47F5 /* bn_mp_clear_multi.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_clear_multi.c; sourceTree = "<group>"; };
+		F96D427008F272B3004A47F5 /* bn_mp_cmp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_cmp.c; sourceTree = "<group>"; };
+		F96D427108F272B3004A47F5 /* bn_mp_cmp_d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_cmp_d.c; sourceTree = "<group>"; };
+		F96D427208F272B3004A47F5 /* bn_mp_cmp_mag.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_cmp_mag.c; sourceTree = "<group>"; };
+		F96D427408F272B3004A47F5 /* bn_mp_copy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_copy.c; sourceTree = "<group>"; };
+		F96D427508F272B3004A47F5 /* bn_mp_count_bits.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_count_bits.c; sourceTree = "<group>"; };
+		F96D427608F272B3004A47F5 /* bn_mp_div.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_div.c; sourceTree = "<group>"; };
+		F96D427708F272B3004A47F5 /* bn_mp_div_2.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_div_2.c; sourceTree = "<group>"; };
+		F96D427808F272B3004A47F5 /* bn_mp_div_2d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_div_2d.c; sourceTree = "<group>"; };
+		F96D427908F272B3004A47F5 /* bn_mp_div_3.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_div_3.c; sourceTree = "<group>"; };
+		F96D427A08F272B3004A47F5 /* bn_mp_div_d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_div_d.c; sourceTree = "<group>"; };
+		F96D427E08F272B3004A47F5 /* bn_mp_exch.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_exch.c; sourceTree = "<group>"; };
+		F96D427F08F272B3004A47F5 /* bn_mp_expt_d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_expt_d.c; sourceTree = "<group>"; };
+		F96D428708F272B3004A47F5 /* bn_mp_grow.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_grow.c; sourceTree = "<group>"; };
+		F96D428808F272B3004A47F5 /* bn_mp_init.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_init.c; sourceTree = "<group>"; };
+		F96D428908F272B3004A47F5 /* bn_mp_init_copy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_init_copy.c; sourceTree = "<group>"; };
+		F96D428A08F272B3004A47F5 /* bn_mp_init_multi.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_init_multi.c; sourceTree = "<group>"; };
+		F96D428B08F272B3004A47F5 /* bn_mp_init_set.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_init_set.c; sourceTree = "<group>"; };
+		F96D428D08F272B3004A47F5 /* bn_mp_init_size.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_init_size.c; sourceTree = "<group>"; };
+		F96D429208F272B3004A47F5 /* bn_mp_karatsuba_mul.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_karatsuba_mul.c; sourceTree = "<group>"; };
+		F96D429308F272B3004A47F5 /* bn_mp_karatsuba_sqr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_karatsuba_sqr.c; sourceTree = "<group>"; };
+		F96D429508F272B3004A47F5 /* bn_mp_lshd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_lshd.c; sourceTree = "<group>"; };
+		F96D429608F272B3004A47F5 /* bn_mp_mod.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_mod.c; sourceTree = "<group>"; };
+		F96D429708F272B3004A47F5 /* bn_mp_mod_2d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_mod_2d.c; sourceTree = "<group>"; };
+		F96D429C08F272B3004A47F5 /* bn_mp_mul.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_mul.c; sourceTree = "<group>"; };
+		F96D429D08F272B3004A47F5 /* bn_mp_mul_2.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_mul_2.c; sourceTree = "<group>"; };
+		F96D429E08F272B3004A47F5 /* bn_mp_mul_2d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_mul_2d.c; sourceTree = "<group>"; };
+		F96D429F08F272B3004A47F5 /* bn_mp_mul_d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_mul_d.c; sourceTree = "<group>"; };
+		F96D42A208F272B3004A47F5 /* bn_mp_neg.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_neg.c; sourceTree = "<group>"; };
+		F96D42A308F272B3004A47F5 /* bn_mp_or.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_or.c; sourceTree = "<group>"; };
+		F96D42AB08F272B3004A47F5 /* bn_mp_radix_size.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_radix_size.c; sourceTree = "<group>"; };
+		F96D42AC08F272B3004A47F5 /* bn_mp_radix_smap.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_radix_smap.c; sourceTree = "<group>"; };
+		F96D42AE08F272B3004A47F5 /* bn_mp_read_radix.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_read_radix.c; sourceTree = "<group>"; };
+		F96D42B908F272B3004A47F5 /* bn_mp_rshd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_rshd.c; sourceTree = "<group>"; };
+		F96D42BA08F272B3004A47F5 /* bn_mp_set.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_set.c; sourceTree = "<group>"; };
+		F96D42BC08F272B3004A47F5 /* bn_mp_shrink.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_shrink.c; sourceTree = "<group>"; };
+		F96D42BE08F272B3004A47F5 /* bn_mp_sqr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_sqr.c; sourceTree = "<group>"; };
+		F96D42C008F272B3004A47F5 /* bn_mp_sqrt.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_sqrt.c; sourceTree = "<group>"; };
+		F96D42C108F272B3004A47F5 /* bn_mp_sub.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_sub.c; sourceTree = "<group>"; };
+		F96D42C208F272B3004A47F5 /* bn_mp_sub_d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_sub_d.c; sourceTree = "<group>"; };
+		F96D42C608F272B3004A47F5 /* bn_mp_to_unsigned_bin.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_to_unsigned_bin.c; sourceTree = "<group>"; };
+		F96D42C708F272B3004A47F5 /* bn_mp_to_unsigned_bin_n.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_to_unsigned_bin_n.c; sourceTree = "<group>"; };
+		F96D42C808F272B3004A47F5 /* bn_mp_toom_mul.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_toom_mul.c; sourceTree = "<group>"; };
+		F96D42C908F272B3004A47F5 /* bn_mp_toom_sqr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_toom_sqr.c; sourceTree = "<group>"; };
+		F96D42CB08F272B3004A47F5 /* bn_mp_toradix_n.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_toradix_n.c; sourceTree = "<group>"; };
+		F96D42CC08F272B3004A47F5 /* bn_mp_unsigned_bin_size.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_unsigned_bin_size.c; sourceTree = "<group>"; };
+		F96D42CD08F272B3004A47F5 /* bn_mp_xor.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_xor.c; sourceTree = "<group>"; };
+		F96D42CE08F272B3004A47F5 /* bn_mp_zero.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_mp_zero.c; sourceTree = "<group>"; };
+		F96D42D008F272B3004A47F5 /* bn_reverse.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_reverse.c; sourceTree = "<group>"; };
+		F96D42D108F272B3004A47F5 /* bn_s_mp_add.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_s_mp_add.c; sourceTree = "<group>"; };
+		F96D42D308F272B3004A47F5 /* bn_s_mp_mul_digs.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_s_mp_mul_digs.c; sourceTree = "<group>"; };
+		F96D42D508F272B3004A47F5 /* bn_s_mp_sqr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_s_mp_sqr.c; sourceTree = "<group>"; };
+		F96D42D608F272B3004A47F5 /* bn_s_mp_sub.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bn_s_mp_sub.c; sourceTree = "<group>"; };
+		F96D42D708F272B3004A47F5 /* bncore.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bncore.c; sourceTree = "<group>"; };
+		F96D432908F272B4004A47F5 /* tommath_class.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tommath_class.h; sourceTree = "<group>"; };
+		F96D432A08F272B4004A47F5 /* tommath_superclass.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tommath_superclass.h; sourceTree = "<group>"; };
+		F96D432B08F272B4004A47F5 /* license.terms */ = {isa = PBXFileReference; explicitFileType = text; fileEncoding = 4; path = license.terms; sourceTree = "<group>"; };
+		F96D432E08F272B5004A47F5 /* configure.ac */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = configure.ac; sourceTree = "<group>"; };
+		F96D432F08F272B5004A47F5 /* GNUmakefile */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = GNUmakefile; sourceTree = "<group>"; };
+		F96D433108F272B5004A47F5 /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
+		F96D433208F272B5004A47F5 /* Tcl-Info.plist.in */ = {isa = PBXFileReference; explicitFileType = text.plist; fileEncoding = 4; path = "Tcl-Info.plist.in"; sourceTree = "<group>"; };
+		F96D433908F272B5004A47F5 /* tclMacOSXBundle.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclMacOSXBundle.c; sourceTree = "<group>"; };
+		F96D433D08F272B5004A47F5 /* tclMacOSXFCmd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclMacOSXFCmd.c; sourceTree = "<group>"; };
+		F96D433E08F272B5004A47F5 /* tclMacOSXNotify.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclMacOSXNotify.c; sourceTree = "<group>"; };
+		F96D434308F272B5004A47F5 /* README */ = {isa = PBXFileReference; explicitFileType = text; fileEncoding = 4; path = README; sourceTree = "<group>"; };
+		F96D434508F272B5004A47F5 /* all.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = all.tcl; sourceTree = "<group>"; };
+		F96D434608F272B5004A47F5 /* append.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = append.test; sourceTree = "<group>"; };
+		F96D434708F272B5004A47F5 /* appendComp.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = appendComp.test; sourceTree = "<group>"; };
+		F96D434808F272B5004A47F5 /* assocd.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = assocd.test; sourceTree = "<group>"; };
+		F96D434908F272B5004A47F5 /* async.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = async.test; sourceTree = "<group>"; };
+		F96D434A08F272B5004A47F5 /* autoMkindex.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = autoMkindex.test; sourceTree = "<group>"; };
+		F96D434B08F272B5004A47F5 /* basic.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = basic.test; sourceTree = "<group>"; };
+		F96D434C08F272B5004A47F5 /* binary.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = binary.test; sourceTree = "<group>"; };
+		F96D434D08F272B5004A47F5 /* case.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = case.test; sourceTree = "<group>"; };
+		F96D434E08F272B5004A47F5 /* chan.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = chan.test; sourceTree = "<group>"; };
+		F96D434F08F272B5004A47F5 /* clock.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = clock.test; sourceTree = "<group>"; };
+		F96D435008F272B5004A47F5 /* cmdAH.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = cmdAH.test; sourceTree = "<group>"; };
+		F96D435108F272B5004A47F5 /* cmdIL.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = cmdIL.test; sourceTree = "<group>"; };
+		F96D435208F272B5004A47F5 /* cmdInfo.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = cmdInfo.test; sourceTree = "<group>"; };
+		F96D435308F272B5004A47F5 /* cmdMZ.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = cmdMZ.test; sourceTree = "<group>"; };
+		F96D435408F272B5004A47F5 /* compExpr-old.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = "compExpr-old.test"; sourceTree = "<group>"; };
+		F96D435508F272B5004A47F5 /* compExpr.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = compExpr.test; sourceTree = "<group>"; };
+		F96D435608F272B5004A47F5 /* compile.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = compile.test; sourceTree = "<group>"; };
+		F96D435708F272B5004A47F5 /* concat.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = concat.test; sourceTree = "<group>"; };
+		F96D435808F272B5004A47F5 /* config.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = config.test; sourceTree = "<group>"; };
+		F96D435908F272B5004A47F5 /* dcall.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = dcall.test; sourceTree = "<group>"; };
+		F96D435A08F272B5004A47F5 /* dict.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = dict.test; sourceTree = "<group>"; };
+		F96D435C08F272B5004A47F5 /* dstring.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = dstring.test; sourceTree = "<group>"; };
+		F96D435E08F272B5004A47F5 /* encoding.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = encoding.test; sourceTree = "<group>"; };
+		F96D435F08F272B5004A47F5 /* env.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = env.test; sourceTree = "<group>"; };
+		F96D436008F272B5004A47F5 /* error.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = error.test; sourceTree = "<group>"; };
+		F96D436108F272B5004A47F5 /* eval.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = eval.test; sourceTree = "<group>"; };
+		F96D436208F272B5004A47F5 /* event.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = event.test; sourceTree = "<group>"; };
+		F96D436308F272B5004A47F5 /* exec.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = exec.test; sourceTree = "<group>"; };
+		F96D436408F272B5004A47F5 /* execute.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = execute.test; sourceTree = "<group>"; };
+		F96D436508F272B5004A47F5 /* expr-old.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = "expr-old.test"; sourceTree = "<group>"; };
+		F96D436608F272B5004A47F5 /* expr.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = expr.test; sourceTree = "<group>"; };
+		F96D436708F272B6004A47F5 /* fCmd.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = fCmd.test; sourceTree = "<group>"; };
+		F96D436808F272B6004A47F5 /* fileName.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = fileName.test; sourceTree = "<group>"; };
+		F96D436908F272B6004A47F5 /* fileSystem.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = fileSystem.test; sourceTree = "<group>"; };
+		F96D436A08F272B6004A47F5 /* for-old.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = "for-old.test"; sourceTree = "<group>"; };
+		F96D436B08F272B6004A47F5 /* for.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = for.test; sourceTree = "<group>"; };
+		F96D436C08F272B6004A47F5 /* foreach.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = foreach.test; sourceTree = "<group>"; };
+		F96D436D08F272B6004A47F5 /* format.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = format.test; sourceTree = "<group>"; };
+		F96D436E08F272B6004A47F5 /* get.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = get.test; sourceTree = "<group>"; };
+		F96D436F08F272B6004A47F5 /* history.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = history.test; sourceTree = "<group>"; };
+		F96D437008F272B6004A47F5 /* http.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = http.test; sourceTree = "<group>"; };
+		F96D437108F272B6004A47F5 /* httpd */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = httpd; sourceTree = "<group>"; };
+		F96D437208F272B6004A47F5 /* httpold.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = httpold.test; sourceTree = "<group>"; };
+		F96D437308F272B6004A47F5 /* if-old.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = "if-old.test"; sourceTree = "<group>"; };
+		F96D437408F272B6004A47F5 /* if.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = if.test; sourceTree = "<group>"; };
+		F96D437508F272B6004A47F5 /* incr-old.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = "incr-old.test"; sourceTree = "<group>"; };
+		F96D437608F272B6004A47F5 /* incr.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = incr.test; sourceTree = "<group>"; };
+		F96D437708F272B6004A47F5 /* indexObj.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = indexObj.test; sourceTree = "<group>"; };
+		F96D437808F272B6004A47F5 /* info.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = info.test; sourceTree = "<group>"; };
+		F96D437908F272B6004A47F5 /* init.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = init.test; sourceTree = "<group>"; };
+		F96D437A08F272B6004A47F5 /* interp.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = interp.test; sourceTree = "<group>"; };
+		F96D437B08F272B6004A47F5 /* io.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = io.test; sourceTree = "<group>"; };
+		F96D437C08F272B6004A47F5 /* ioCmd.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = ioCmd.test; sourceTree = "<group>"; };
+		F96D437D08F272B6004A47F5 /* iogt.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = iogt.test; sourceTree = "<group>"; };
+		F96D437F08F272B6004A47F5 /* join.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = join.test; sourceTree = "<group>"; };
+		F96D438008F272B6004A47F5 /* lindex.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = lindex.test; sourceTree = "<group>"; };
+		F96D438108F272B6004A47F5 /* link.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = link.test; sourceTree = "<group>"; };
+		F96D438208F272B6004A47F5 /* linsert.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = linsert.test; sourceTree = "<group>"; };
+		F96D438308F272B6004A47F5 /* list.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = list.test; sourceTree = "<group>"; };
+		F96D438408F272B6004A47F5 /* listObj.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = listObj.test; sourceTree = "<group>"; };
+		F96D438508F272B6004A47F5 /* llength.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = llength.test; sourceTree = "<group>"; };
+		F96D438608F272B6004A47F5 /* load.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = load.test; sourceTree = "<group>"; };
+		F96D438708F272B6004A47F5 /* lrange.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = lrange.test; sourceTree = "<group>"; };
+		F96D438808F272B6004A47F5 /* lrepeat.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = lrepeat.test; sourceTree = "<group>"; };
+		F96D438908F272B6004A47F5 /* lreplace.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = lreplace.test; sourceTree = "<group>"; };
+		F96D438A08F272B6004A47F5 /* lsearch.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = lsearch.test; sourceTree = "<group>"; };
+		F96D438B08F272B6004A47F5 /* lset.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = lset.test; sourceTree = "<group>"; };
+		F96D438C08F272B6004A47F5 /* lsetComp.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = lsetComp.test; sourceTree = "<group>"; };
+		F96D438D08F272B6004A47F5 /* macOSXFCmd.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = macOSXFCmd.test; sourceTree = "<group>"; };
+		F96D438E08F272B6004A47F5 /* main.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = main.test; sourceTree = "<group>"; };
+		F96D438F08F272B6004A47F5 /* misc.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = misc.test; sourceTree = "<group>"; };
+		F96D439008F272B6004A47F5 /* msgcat.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = msgcat.test; sourceTree = "<group>"; };
+		F96D439108F272B6004A47F5 /* namespace-old.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = "namespace-old.test"; sourceTree = "<group>"; };
+		F96D439208F272B7004A47F5 /* namespace.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = namespace.test; sourceTree = "<group>"; };
+		F96D439308F272B7004A47F5 /* notify.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = notify.test; sourceTree = "<group>"; };
+		F96D439408F272B7004A47F5 /* obj.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = obj.test; sourceTree = "<group>"; };
+		F96D439508F272B7004A47F5 /* opt.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = opt.test; sourceTree = "<group>"; };
+		F96D439608F272B7004A47F5 /* package.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = package.test; sourceTree = "<group>"; };
+		F96D439708F272B7004A47F5 /* parse.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = parse.test; sourceTree = "<group>"; };
+		F96D439808F272B7004A47F5 /* parseExpr.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = parseExpr.test; sourceTree = "<group>"; };
+		F96D439908F272B7004A47F5 /* parseOld.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = parseOld.test; sourceTree = "<group>"; };
+		F96D439A08F272B7004A47F5 /* pid.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = pid.test; sourceTree = "<group>"; };
+		F96D439B08F272B7004A47F5 /* pkg.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = pkg.test; sourceTree = "<group>"; };
+		F96D439C08F272B7004A47F5 /* pkgMkIndex.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = pkgMkIndex.test; sourceTree = "<group>"; };
+		F96D439D08F272B7004A47F5 /* platform.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = platform.test; sourceTree = "<group>"; };
+		F96D439E08F272B7004A47F5 /* proc-old.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = "proc-old.test"; sourceTree = "<group>"; };
+		F96D439F08F272B7004A47F5 /* proc.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = proc.test; sourceTree = "<group>"; };
+		F96D43A008F272B7004A47F5 /* pwd.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = pwd.test; sourceTree = "<group>"; };
+		F96D43A108F272B7004A47F5 /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
+		F96D43A208F272B7004A47F5 /* reg.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = reg.test; sourceTree = "<group>"; };
+		F96D43A308F272B7004A47F5 /* regexp.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = regexp.test; sourceTree = "<group>"; };
+		F96D43A408F272B7004A47F5 /* regexpComp.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = regexpComp.test; sourceTree = "<group>"; };
+		F96D43A508F272B7004A47F5 /* registry.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = registry.test; sourceTree = "<group>"; };
+		F96D43A608F272B7004A47F5 /* remote.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = remote.tcl; sourceTree = "<group>"; };
+		F96D43A708F272B7004A47F5 /* rename.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = rename.test; sourceTree = "<group>"; };
+		F96D43A808F272B7004A47F5 /* result.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = result.test; sourceTree = "<group>"; };
+		F96D43A908F272B7004A47F5 /* safe.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = safe.test; sourceTree = "<group>"; };
+		F96D43AA08F272B7004A47F5 /* scan.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = scan.test; sourceTree = "<group>"; };
+		F96D43AB08F272B7004A47F5 /* security.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = security.test; sourceTree = "<group>"; };
+		F96D43AC08F272B7004A47F5 /* set-old.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = "set-old.test"; sourceTree = "<group>"; };
+		F96D43AD08F272B7004A47F5 /* set.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = set.test; sourceTree = "<group>"; };
+		F96D43AE08F272B7004A47F5 /* socket.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = socket.test; sourceTree = "<group>"; };
+		F96D43AF08F272B7004A47F5 /* source.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = source.test; sourceTree = "<group>"; };
+		F96D43B008F272B7004A47F5 /* split.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = split.test; sourceTree = "<group>"; };
+		F96D43B108F272B7004A47F5 /* stack.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = stack.test; sourceTree = "<group>"; };
+		F96D43B208F272B7004A47F5 /* string.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = string.test; sourceTree = "<group>"; };
+		F96D43B308F272B7004A47F5 /* stringComp.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = stringComp.test; sourceTree = "<group>"; };
+		F96D43B408F272B7004A47F5 /* stringObj.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = stringObj.test; sourceTree = "<group>"; };
+		F96D43B508F272B7004A47F5 /* subst.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = subst.test; sourceTree = "<group>"; };
+		F96D43B608F272B7004A47F5 /* switch.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = switch.test; sourceTree = "<group>"; };
+		F96D43B708F272B7004A47F5 /* tcltest.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tcltest.test; sourceTree = "<group>"; };
+		F96D43B808F272B7004A47F5 /* thread.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = thread.test; sourceTree = "<group>"; };
+		F96D43B908F272B7004A47F5 /* timer.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = timer.test; sourceTree = "<group>"; };
+		F96D43BA08F272B7004A47F5 /* tm.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tm.test; sourceTree = "<group>"; };
+		F96D43BB08F272B7004A47F5 /* trace.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = trace.test; sourceTree = "<group>"; };
+		F96D43BC08F272B7004A47F5 /* unixFCmd.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = unixFCmd.test; sourceTree = "<group>"; };
+		F96D43BD08F272B7004A47F5 /* unixFile.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = unixFile.test; sourceTree = "<group>"; };
+		F96D43BE08F272B7004A47F5 /* unixInit.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = unixInit.test; sourceTree = "<group>"; };
+		F96D43BF08F272B7004A47F5 /* unixNotfy.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = unixNotfy.test; sourceTree = "<group>"; };
+		F96D43C008F272B7004A47F5 /* unknown.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = unknown.test; sourceTree = "<group>"; };
+		F96D43C108F272B7004A47F5 /* unload.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = unload.test; sourceTree = "<group>"; };
+		F96D43C208F272B7004A47F5 /* uplevel.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = uplevel.test; sourceTree = "<group>"; };
+		F96D43C308F272B7004A47F5 /* upvar.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = upvar.test; sourceTree = "<group>"; };
+		F96D43C408F272B7004A47F5 /* utf.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = utf.test; sourceTree = "<group>"; };
+		F96D43C508F272B7004A47F5 /* util.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = util.test; sourceTree = "<group>"; };
+		F96D43C608F272B7004A47F5 /* var.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = var.test; sourceTree = "<group>"; };
+		F96D43C708F272B7004A47F5 /* while-old.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = "while-old.test"; sourceTree = "<group>"; };
+		F96D43C808F272B7004A47F5 /* while.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = while.test; sourceTree = "<group>"; };
+		F96D43C908F272B7004A47F5 /* winConsole.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = winConsole.test; sourceTree = "<group>"; };
+		F96D43CA08F272B7004A47F5 /* winDde.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = winDde.test; sourceTree = "<group>"; };
+		F96D43CB08F272B7004A47F5 /* winFCmd.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = winFCmd.test; sourceTree = "<group>"; };
+		F96D43CC08F272B7004A47F5 /* winFile.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = winFile.test; sourceTree = "<group>"; };
+		F96D43CD08F272B7004A47F5 /* winNotify.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = winNotify.test; sourceTree = "<group>"; };
+		F96D43CE08F272B7004A47F5 /* winPipe.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = winPipe.test; sourceTree = "<group>"; };
+		F96D43CF08F272B7004A47F5 /* winTime.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = winTime.test; sourceTree = "<group>"; };
+		F96D43D108F272B8004A47F5 /* checkLibraryDoc.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = checkLibraryDoc.tcl; sourceTree = "<group>"; };
+		F96D43D208F272B8004A47F5 /* configure */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = configure; sourceTree = "<group>"; };
+		F96D43D308F272B8004A47F5 /* configure.in */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = configure.in; sourceTree = "<group>"; };
+		F96D442408F272B8004A47F5 /* fix_tommath_h.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = fix_tommath_h.tcl; sourceTree = "<group>"; };
+		F96D442508F272B8004A47F5 /* genStubs.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = genStubs.tcl; sourceTree = "<group>"; };
+		F96D442708F272B8004A47F5 /* index.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = index.tcl; sourceTree = "<group>"; };
+		F96D442808F272B8004A47F5 /* installData.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = installData.tcl; sourceTree = "<group>"; };
+		F96D442908F272B8004A47F5 /* loadICU.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = loadICU.tcl; sourceTree = "<group>"; };
+		F96D442A08F272B8004A47F5 /* Makefile.in */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = Makefile.in; sourceTree = "<group>"; };
+		F96D442B08F272B8004A47F5 /* makeTestCases.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = makeTestCases.tcl; sourceTree = "<group>"; };
+		F96D442C08F272B8004A47F5 /* man2help.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = man2help.tcl; sourceTree = "<group>"; };
+		F96D442D08F272B8004A47F5 /* man2help2.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = man2help2.tcl; sourceTree = "<group>"; };
+		F96D442E08F272B8004A47F5 /* man2html.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = man2html.tcl; sourceTree = "<group>"; };
+		F96D442F08F272B8004A47F5 /* man2html1.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = man2html1.tcl; sourceTree = "<group>"; };
+		F96D443008F272B8004A47F5 /* man2html2.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = man2html2.tcl; sourceTree = "<group>"; };
+		F96D443108F272B8004A47F5 /* man2tcl.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = man2tcl.c; sourceTree = "<group>"; };
+		F96D443208F272B8004A47F5 /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
+		F96D443308F272B8004A47F5 /* regexpTestLib.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = regexpTestLib.tcl; sourceTree = "<group>"; };
+		F96D443508F272B8004A47F5 /* tcl.hpj.in */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = tcl.hpj.in; sourceTree = "<group>"; };
+		F96D443908F272B9004A47F5 /* tcltk-man2html.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = "tcltk-man2html.tcl"; sourceTree = "<group>"; };
+		F96D443A08F272B9004A47F5 /* tclZIC.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tclZIC.tcl; sourceTree = "<group>"; };
+		F96D443B08F272B9004A47F5 /* uniClass.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = uniClass.tcl; sourceTree = "<group>"; };
+		F96D443C08F272B9004A47F5 /* uniParse.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = uniParse.tcl; sourceTree = "<group>"; };
+		F96D444008F272B9004A47F5 /* aclocal.m4 */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = aclocal.m4; sourceTree = "<group>"; };
+		F96D444108F272B9004A47F5 /* configure */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = configure; sourceTree = "<group>"; };
+		F96D444208F272B9004A47F5 /* configure.in */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = configure.in; sourceTree = "<group>"; };
+		F96D444408F272B9004A47F5 /* Makefile.in */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = Makefile.in; sourceTree = "<group>"; };
+		F96D444508F272B9004A47F5 /* pkga.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pkga.c; sourceTree = "<group>"; };
+		F96D444608F272B9004A47F5 /* pkgb.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pkgb.c; sourceTree = "<group>"; };
+		F96D444708F272B9004A47F5 /* pkgc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pkgc.c; sourceTree = "<group>"; };
+		F96D444808F272B9004A47F5 /* pkgd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pkgd.c; sourceTree = "<group>"; };
+		F96D444908F272B9004A47F5 /* pkge.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pkge.c; sourceTree = "<group>"; };
+		F96D444B08F272B9004A47F5 /* pkgua.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pkgua.c; sourceTree = "<group>"; };
+		F96D444C08F272B9004A47F5 /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
+		F96D444D08F272B9004A47F5 /* install-sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = "install-sh"; sourceTree = "<group>"; };
+		F96D444E08F272B9004A47F5 /* installManPage */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = installManPage; sourceTree = "<group>"; };
+		F96D444F08F272B9004A47F5 /* ldAix */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = ldAix; sourceTree = "<group>"; };
+		F96D445008F272B9004A47F5 /* Makefile.in */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = Makefile.in; sourceTree = "<group>"; };
+		F96D445208F272B9004A47F5 /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
+		F96D445308F272B9004A47F5 /* tcl.m4 */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = tcl.m4; sourceTree = "<group>"; };
+		F96D445408F272B9004A47F5 /* tcl.spec */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = tcl.spec; sourceTree = "<group>"; };
+		F96D445508F272B9004A47F5 /* tclAppInit.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclAppInit.c; sourceTree = "<group>"; };
+		F96D445608F272B9004A47F5 /* tclConfig.h.in */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; fileEncoding = 4; path = tclConfig.h.in; sourceTree = "<group>"; };
+		F96D445708F272B9004A47F5 /* tclConfig.sh.in */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = tclConfig.sh.in; sourceTree = "<group>"; };
+		F96D445808F272B9004A47F5 /* tclLoadAix.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclLoadAix.c; sourceTree = "<group>"; };
+		F96D445908F272B9004A47F5 /* tclLoadDl.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclLoadDl.c; sourceTree = "<group>"; };
+		F96D445B08F272B9004A47F5 /* tclLoadDyld.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclLoadDyld.c; sourceTree = "<group>"; };
+		F96D445C08F272B9004A47F5 /* tclLoadNext.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclLoadNext.c; sourceTree = "<group>"; };
+		F96D445D08F272B9004A47F5 /* tclLoadOSF.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclLoadOSF.c; sourceTree = "<group>"; };
+		F96D445E08F272B9004A47F5 /* tclLoadShl.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclLoadShl.c; sourceTree = "<group>"; };
+		F96D445F08F272B9004A47F5 /* tclUnixChan.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUnixChan.c; sourceTree = "<group>"; };
+		F96D446008F272B9004A47F5 /* tclUnixEvent.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUnixEvent.c; sourceTree = "<group>"; };
+		F96D446108F272B9004A47F5 /* tclUnixFCmd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUnixFCmd.c; sourceTree = "<group>"; };
+		F96D446208F272B9004A47F5 /* tclUnixFile.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUnixFile.c; sourceTree = "<group>"; };
+		F96D446308F272B9004A47F5 /* tclUnixInit.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUnixInit.c; sourceTree = "<group>"; };
+		F96D446408F272B9004A47F5 /* tclUnixNotfy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUnixNotfy.c; sourceTree = "<group>"; };
+		F96D446508F272B9004A47F5 /* tclUnixPipe.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUnixPipe.c; sourceTree = "<group>"; };
+		F96D446608F272B9004A47F5 /* tclUnixPort.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclUnixPort.h; sourceTree = "<group>"; };
+		F96D446708F272B9004A47F5 /* tclUnixSock.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUnixSock.c; sourceTree = "<group>"; };
+		F96D446808F272B9004A47F5 /* tclUnixTest.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUnixTest.c; sourceTree = "<group>"; };
+		F96D446908F272B9004A47F5 /* tclUnixThrd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUnixThrd.c; sourceTree = "<group>"; };
+		F96D446B08F272B9004A47F5 /* tclUnixTime.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUnixTime.c; sourceTree = "<group>"; };
+		F96D446C08F272B9004A47F5 /* tclXtNotify.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclXtNotify.c; sourceTree = "<group>"; };
+		F96D446D08F272B9004A47F5 /* tclXtTest.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclXtTest.c; sourceTree = "<group>"; };
+		F96D447008F272BA004A47F5 /* aclocal.m4 */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = aclocal.m4; sourceTree = "<group>"; };
+		F96D447108F272BA004A47F5 /* buildall.vc.bat */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = buildall.vc.bat; sourceTree = "<group>"; };
+		F96D447208F272BA004A47F5 /* cat.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = cat.c; sourceTree = "<group>"; };
+		F96D447308F272BA004A47F5 /* coffbase.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = coffbase.txt; sourceTree = "<group>"; };
+		F96D447408F272BA004A47F5 /* configure */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = configure; sourceTree = "<group>"; };
+		F96D447508F272BA004A47F5 /* configure.in */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = configure.in; sourceTree = "<group>"; };
+		F96D447608F272BA004A47F5 /* makefile.bc */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = makefile.bc; sourceTree = "<group>"; };
+		F96D447708F272BA004A47F5 /* Makefile.in */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = Makefile.in; sourceTree = "<group>"; };
+		F96D447808F272BA004A47F5 /* makefile.vc */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = makefile.vc; sourceTree = "<group>"; };
+		F96D447908F272BA004A47F5 /* nmakehlp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = nmakehlp.c; sourceTree = "<group>"; };
+		F96D447A08F272BA004A47F5 /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
+		F96D447C08F272BA004A47F5 /* rules.vc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = rules.vc; sourceTree = "<group>"; };
+		F96D447D08F272BA004A47F5 /* stub16.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = stub16.c; sourceTree = "<group>"; };
+		F96D447E08F272BA004A47F5 /* tcl.dsp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = tcl.dsp; sourceTree = "<group>"; };
+		F96D447F08F272BA004A47F5 /* tcl.dsw */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = tcl.dsw; sourceTree = "<group>"; };
+		F96D448008F272BA004A47F5 /* tcl.hpj.in */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = tcl.hpj.in; sourceTree = "<group>"; };
+		F96D448108F272BA004A47F5 /* tcl.m4 */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = tcl.m4; sourceTree = "<group>"; };
+		F96D448208F272BA004A47F5 /* tcl.rc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = tcl.rc; sourceTree = "<group>"; };
+		F96D448308F272BA004A47F5 /* tclAppInit.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclAppInit.c; sourceTree = "<group>"; };
+		F96D448408F272BA004A47F5 /* tclConfig.sh.in */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = tclConfig.sh.in; sourceTree = "<group>"; };
+		F96D448608F272BA004A47F5 /* tclsh.rc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = tclsh.rc; sourceTree = "<group>"; };
+		F96D448708F272BA004A47F5 /* tclWin32Dll.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWin32Dll.c; sourceTree = "<group>"; };
+		F96D448808F272BA004A47F5 /* tclWinChan.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinChan.c; sourceTree = "<group>"; };
+		F96D448908F272BA004A47F5 /* tclWinConsole.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinConsole.c; sourceTree = "<group>"; };
+		F96D448A08F272BA004A47F5 /* tclWinDde.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinDde.c; sourceTree = "<group>"; };
+		F96D448B08F272BA004A47F5 /* tclWinError.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinError.c; sourceTree = "<group>"; };
+		F96D448C08F272BA004A47F5 /* tclWinFCmd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinFCmd.c; sourceTree = "<group>"; };
+		F96D448D08F272BA004A47F5 /* tclWinFile.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinFile.c; sourceTree = "<group>"; };
+		F96D448E08F272BA004A47F5 /* tclWinInit.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinInit.c; sourceTree = "<group>"; };
+		F96D448F08F272BA004A47F5 /* tclWinInt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclWinInt.h; sourceTree = "<group>"; };
+		F96D449008F272BA004A47F5 /* tclWinLoad.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinLoad.c; sourceTree = "<group>"; };
+		F96D449108F272BA004A47F5 /* tclWinNotify.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinNotify.c; sourceTree = "<group>"; };
+		F96D449208F272BA004A47F5 /* tclWinPipe.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinPipe.c; sourceTree = "<group>"; };
+		F96D449308F272BA004A47F5 /* tclWinPort.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclWinPort.h; sourceTree = "<group>"; };
+		F96D449408F272BA004A47F5 /* tclWinReg.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinReg.c; sourceTree = "<group>"; };
+		F96D449508F272BA004A47F5 /* tclWinSerial.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinSerial.c; sourceTree = "<group>"; };
+		F96D449608F272BA004A47F5 /* tclWinSock.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinSock.c; sourceTree = "<group>"; };
+		F96D449708F272BA004A47F5 /* tclWinTest.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinTest.c; sourceTree = "<group>"; };
+		F96D449808F272BA004A47F5 /* tclWinThrd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinThrd.c; sourceTree = "<group>"; };
+		F96D449908F272BA004A47F5 /* tclWinThrd.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclWinThrd.h; sourceTree = "<group>"; };
+		F96D449A08F272BA004A47F5 /* tclWinTime.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclWinTime.c; sourceTree = "<group>"; };
+		F974D56C0FBE7D6300BF728B /* http11.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = http11.test; sourceTree = "<group>"; };
+		F974D56D0FBE7D6300BF728B /* httpd11.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = httpd11.tcl; sourceTree = "<group>"; };
+		F974D5720FBE7DC600BF728B /* coroutine.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = coroutine.n; sourceTree = "<group>"; };
+		F974D5760FBE7E1900BF728B /* tailcall.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = tailcall.n; sourceTree = "<group>"; };
+		F974D5770FBE7E6100BF728B /* coroutine.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = coroutine.test; sourceTree = "<group>"; };
+		F974D5780FBE7E6100BF728B /* tailcall.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tailcall.test; sourceTree = "<group>"; };
+		F974D5790FBE7E9C00BF728B /* tcl.pc.in */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = tcl.pc.in; sourceTree = "<group>"; };
+		F97AE7F10B65C1E900310EA2 /* Tcl-Common.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = "Tcl-Common.xcconfig"; sourceTree = "<group>"; };
+		F97AE82B0B65C69B00310EA2 /* Tcl-Release.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = "Tcl-Release.xcconfig"; sourceTree = "<group>"; };
+		F97AE8330B65C87F00310EA2 /* Tcl-Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = "Tcl-Debug.xcconfig"; sourceTree = "<group>"; };
+		F9903CAF094FAADA004613E9 /* tclTomMath.decls */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tclTomMath.decls; sourceTree = "<group>"; };
+		F9903CB0094FAADA004613E9 /* tclTomMathDecls.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclTomMathDecls.h; sourceTree = "<group>"; };
+		F99D61180EF5573A00BBFE01 /* TclZlib.3 */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = TclZlib.3; sourceTree = "<group>"; };
+		F9A3084B08F2D4CE00BAE1AB /* tclsh */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = tclsh; sourceTree = BUILT_PRODUCTS_DIR; };
+		F9A3084E08F2D4F400BAE1AB /* Tcl.framework */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = wrapper.framework; path = Tcl.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+		F9A493240CEBF38300B78AE2 /* chanio.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = chanio.test; sourceTree = "<group>"; };
+		F9ECB1120B26521500A28025 /* pkgIndex.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = pkgIndex.tcl; sourceTree = "<group>"; };
+		F9ECB1130B26521500A28025 /* platform.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = platform.tcl; sourceTree = "<group>"; };
+		F9ECB1140B26521500A28025 /* shell.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = shell.tcl; sourceTree = "<group>"; };
+		F9ECB1CA0B2652D300A28025 /* apply.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = apply.test; sourceTree = "<group>"; };
+		F9ECB1CB0B26534C00A28025 /* mathop.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = mathop.test; sourceTree = "<group>"; };
+		F9ECB1E10B26543C00A28025 /* platform_shell.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = platform_shell.n; sourceTree = "<group>"; };
+		F9ECB1E20B26543C00A28025 /* platform.n */ = {isa = PBXFileReference; explicitFileType = text.man; fileEncoding = 4; path = platform.n; sourceTree = "<group>"; };
+		F9F4415D0C8BAE6F00BCCD67 /* tclDTrace.d */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.dtrace; path = tclDTrace.d; sourceTree = "<group>"; };
+		F9FC77B70AB29E9100B7077D /* tclUnixCompat.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUnixCompat.c; sourceTree = "<group>"; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+		8DD76FAD0486AB0100D96B5E /* Frameworks */ = {
+			isa = PBXFrameworksBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				F966C07508F2820D005CB29B /* CoreFoundation.framework in Frameworks */,
+				F96437E70EF0D652003F468E /* libz.dylib in Frameworks */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+		08FB7794FE84155DC02AAC07 /* Tcl */ = {
+			isa = PBXGroup;
+			children = (
+				F96D3DF608F27169004A47F5 /* Tcl Sources */,
+				F966C06F08F281DC005CB29B /* Frameworks */,
+				1AB674ADFE9D54B511CA2CBB /* Products */,
+			);
+			comments = "Copyright (c) 2004-2009 Daniel A. Steffen <das@users.sourceforge.net>\nCopyright 2008-2009, Apple Inc.\n\nSee the file \"license.terms\" for information on usage and redistribution of\nthis file, and for a DISCLAIMER OF ALL WARRANTIES.\n\n";
+			name = Tcl;
+			path = .;
+			sourceTree = SOURCE_ROOT;
+		};
+		1AB674ADFE9D54B511CA2CBB /* Products */ = {
+			isa = PBXGroup;
+			children = (
+				F9A3084B08F2D4CE00BAE1AB /* tclsh */,
+				8DD76FB20486AB0100D96B5E /* tcltest */,
+				F9A3084E08F2D4F400BAE1AB /* Tcl.framework */,
+			);
+			includeInIndex = 0;
+			name = Products;
+			sourceTree = "<group>";
+		};
+		F9183E690EFC81560030B814 /* pkgs */ = {
+			isa = PBXGroup;
+			children = (
+				F9183E6A0EFC81560030B814 /* README */,
+				F946FB8B0FBE3AED00CD6495 /* itcl */,
+				F9183E8F0EFC817B0030B814 /* tdbc */,
+			);
+			path = pkgs;
+			sourceTree = "<group>";
+		};
+		F966C06F08F281DC005CB29B /* Frameworks */ = {
+			isa = PBXGroup;
+			children = (
+				F966C07408F2820D005CB29B /* CoreFoundation.framework */,
+				F96437E60EF0D652003F468E /* libz.dylib */,
+			);
+			name = Frameworks;
+			sourceTree = "<group>";
+		};
+		F96D3DF608F27169004A47F5 /* Tcl Sources */ = {
+			isa = PBXGroup;
+			children = (
+				F96D3EC908F272A7004A47F5 /* generic */,
+				F96D432C08F272B4004A47F5 /* macosx */,
+				F96D443E08F272B9004A47F5 /* unix */,
+				F96D425C08F272B2004A47F5 /* libtommath */,
+				F96D446E08F272B9004A47F5 /* win */,
+				F96D3F3808F272A7004A47F5 /* library */,
+				F96D434408F272B5004A47F5 /* tests */,
+				F96D3DFC08F272A4004A47F5 /* doc */,
+				F96D43D008F272B8004A47F5 /* tools */,
+				F9183E690EFC81560030B814 /* pkgs */,
+				F96D3DFA08F272A4004A47F5 /* ChangeLog */,
+				F96D3DFB08F272A4004A47F5 /* changes */,
+				F96D434308F272B5004A47F5 /* README */,
+				F96D432B08F272B4004A47F5 /* license.terms */,
+			);
+			name = "Tcl Sources";
+			sourceTree = TCL_SRCROOT;
+		};
+		F96D3DFC08F272A4004A47F5 /* doc */ = {
+			isa = PBXGroup;
+			children = (
+				F96D3DFD08F272A4004A47F5 /* Access.3 */,
+				F96D3DFE08F272A4004A47F5 /* AddErrInfo.3 */,
+				F96D3DFF08F272A4004A47F5 /* after.n */,
+				F96D3E0008F272A4004A47F5 /* Alloc.3 */,
+				F96D3E0108F272A4004A47F5 /* AllowExc.3 */,
+				F96D3E0208F272A4004A47F5 /* append.n */,
+				F96D3E0308F272A4004A47F5 /* AppInit.3 */,
+				F96D3E0408F272A5004A47F5 /* array.n */,
+				F96D3E0508F272A5004A47F5 /* AssocData.3 */,
+				F96D3E0608F272A5004A47F5 /* Async.3 */,
+				F96D3E0708F272A5004A47F5 /* BackgdErr.3 */,
+				F96D3E0808F272A5004A47F5 /* Backslash.3 */,
+				F96D3E0908F272A5004A47F5 /* bgerror.n */,
+				F96D3E0A08F272A5004A47F5 /* binary.n */,
+				F96D3E0B08F272A5004A47F5 /* BoolObj.3 */,
+				F96D3E0C08F272A5004A47F5 /* break.n */,
+				F96D3E0D08F272A5004A47F5 /* ByteArrObj.3 */,
+				F96D3E0E08F272A5004A47F5 /* CallDel.3 */,
+				F96D3E0F08F272A5004A47F5 /* case.n */,
+				F96D3E1008F272A5004A47F5 /* catch.n */,
+				F96D3E1108F272A5004A47F5 /* cd.n */,
+				F96D3E1208F272A5004A47F5 /* chan.n */,
+				F96D3E1308F272A5004A47F5 /* ChnlStack.3 */,
+				F93599CF0DF1F87F00E04F67 /* Class.3 */,
+				F93599D00DF1F89E00E04F67 /* class.n */,
+				F96D3E1408F272A5004A47F5 /* clock.n */,
+				F96D3E1508F272A5004A47F5 /* close.n */,
+				F96D3E1608F272A5004A47F5 /* CmdCmplt.3 */,
+				F96D3E1708F272A5004A47F5 /* Concat.3 */,
+				F96D3E1808F272A5004A47F5 /* concat.n */,
+				F96D3E1908F272A5004A47F5 /* continue.n */,
+				F93599D20DF1F8DF00E04F67 /* copy.n */,
+				F974D5720FBE7DC600BF728B /* coroutine.n */,
+				F96D3E1A08F272A5004A47F5 /* CrtChannel.3 */,
+				F96D3E1B08F272A5004A47F5 /* CrtChnlHdlr.3 */,
+				F96D3E1C08F272A5004A47F5 /* CrtCloseHdlr.3 */,
+				F96D3E1D08F272A5004A47F5 /* CrtCommand.3 */,
+				F96D3E1E08F272A5004A47F5 /* CrtFileHdlr.3 */,
+				F96D3E1F08F272A5004A47F5 /* CrtInterp.3 */,
+				F96D3E2008F272A5004A47F5 /* CrtMathFnc.3 */,
+				F96D3E2108F272A5004A47F5 /* CrtObjCmd.3 */,
+				F96D3E2208F272A5004A47F5 /* CrtSlave.3 */,
+				F96D3E2308F272A5004A47F5 /* CrtTimerHdlr.3 */,
+				F96D3E2408F272A5004A47F5 /* CrtTrace.3 */,
+				F96D3E2508F272A5004A47F5 /* dde.n */,
+				F93599D30DF1F8F500E04F67 /* define.n */,
+				F96D3E2608F272A5004A47F5 /* DetachPids.3 */,
+				F96D3E2708F272A5004A47F5 /* dict.n */,
+				F96D3E2808F272A5004A47F5 /* DictObj.3 */,
+				F96D3E2908F272A5004A47F5 /* DoOneEvent.3 */,
+				F96D3E2A08F272A5004A47F5 /* DoubleObj.3 */,
+				F96D3E2B08F272A5004A47F5 /* DoWhenIdle.3 */,
+				F96D3E2C08F272A5004A47F5 /* DString.3 */,
+				F96D3E2D08F272A5004A47F5 /* DumpActiveMemory.3 */,
+				F96D3E2E08F272A5004A47F5 /* Encoding.3 */,
+				F96D3E2F08F272A5004A47F5 /* encoding.n */,
+				F96D3E3008F272A5004A47F5 /* Ensemble.3 */,
+				F96D3E3108F272A5004A47F5 /* Environment.3 */,
+				F96D3E3208F272A5004A47F5 /* eof.n */,
+				F96D3E3308F272A5004A47F5 /* error.n */,
+				F96D3E3408F272A5004A47F5 /* Eval.3 */,
+				F96D3E3508F272A5004A47F5 /* eval.n */,
+				F96D3E3608F272A5004A47F5 /* exec.n */,
+				F96D3E3708F272A5004A47F5 /* Exit.3 */,
+				F96D3E3808F272A5004A47F5 /* exit.n */,
+				F96D3E3908F272A5004A47F5 /* expr.n */,
+				F96D3E3A08F272A5004A47F5 /* ExprLong.3 */,
+				F96D3E3B08F272A5004A47F5 /* ExprLongObj.3 */,
+				F96D3E3C08F272A5004A47F5 /* fblocked.n */,
+				F96D3E3D08F272A5004A47F5 /* fconfigure.n */,
+				F96D3E3E08F272A5004A47F5 /* fcopy.n */,
+				F96D3E3F08F272A5004A47F5 /* file.n */,
+				F96D3E4008F272A5004A47F5 /* fileevent.n */,
+				F96D3E4108F272A5004A47F5 /* filename.n */,
+				F96D3E4208F272A5004A47F5 /* FileSystem.3 */,
+				F96D3E4308F272A5004A47F5 /* FindExec.3 */,
+				F96D3E4408F272A5004A47F5 /* flush.n */,
+				F96D3E4508F272A5004A47F5 /* for.n */,
+				F96D3E4608F272A5004A47F5 /* foreach.n */,
+				F96D3E4708F272A5004A47F5 /* format.n */,
+				F96D3E4808F272A5004A47F5 /* GetCwd.3 */,
+				F96D3E4908F272A5004A47F5 /* GetHostName.3 */,
+				F96D3E4A08F272A5004A47F5 /* GetIndex.3 */,
+				F96D3E4B08F272A5004A47F5 /* GetInt.3 */,
+				F96D3E4C08F272A5004A47F5 /* GetOpnFl.3 */,
+				F96D3E4D08F272A5004A47F5 /* gets.n */,
+				F96D3E4E08F272A5004A47F5 /* GetStdChan.3 */,
+				F96D3E4F08F272A5004A47F5 /* GetTime.3 */,
+				F96D3E5008F272A5004A47F5 /* GetVersion.3 */,
+				F96D3E5108F272A5004A47F5 /* glob.n */,
+				F96D3E5208F272A6004A47F5 /* global.n */,
+				F96D3E5308F272A6004A47F5 /* Hash.3 */,
+				F96D3E5408F272A6004A47F5 /* history.n */,
+				F96D3E5508F272A6004A47F5 /* http.n */,
+				F96D3E5608F272A6004A47F5 /* if.n */,
+				F96D3E5708F272A6004A47F5 /* incr.n */,
+				F96D3E5808F272A6004A47F5 /* info.n */,
+				F96D3E5908F272A6004A47F5 /* Init.3 */,
+				F96D3E5A08F272A6004A47F5 /* InitStubs.3 */,
+				F96D3E5B08F272A6004A47F5 /* Interp.3 */,
+				F96D3E5C08F272A6004A47F5 /* interp.n */,
+				F96D3E5D08F272A6004A47F5 /* IntObj.3 */,
+				F96D3E5E08F272A6004A47F5 /* join.n */,
+				F96D3E5F08F272A6004A47F5 /* lappend.n */,
+				F96D3E6008F272A6004A47F5 /* lassign.n */,
+				F96D3E6108F272A6004A47F5 /* library.n */,
+				F96D3E6208F272A6004A47F5 /* Limit.3 */,
+				F96D3E6308F272A6004A47F5 /* lindex.n */,
+				F96D3E6408F272A6004A47F5 /* LinkVar.3 */,
+				F96D3E6508F272A6004A47F5 /* linsert.n */,
+				F96D3E6608F272A6004A47F5 /* list.n */,
+				F96D3E6708F272A6004A47F5 /* ListObj.3 */,
+				F96D3E6808F272A6004A47F5 /* llength.n */,
+				F96D3E6908F272A6004A47F5 /* load.n */,
+				F96D3E6A08F272A6004A47F5 /* lrange.n */,
+				F96D3E6B08F272A6004A47F5 /* lrepeat.n */,
+				F96D3E6C08F272A6004A47F5 /* lreplace.n */,
+				F96D3E6D08F272A6004A47F5 /* lsearch.n */,
+				F96D3E6E08F272A6004A47F5 /* lset.n */,
+				F96D3E6F08F272A6004A47F5 /* lsort.n */,
+				F96D3E7008F272A6004A47F5 /* man.macros */,
+				F96D3E7108F272A6004A47F5 /* mathfunc.n */,
+				F96D3E7208F272A6004A47F5 /* memory.n */,
+				F93599D40DF1F91900E04F67 /* Method.3 */,
+				F96D3E7308F272A6004A47F5 /* msgcat.n */,
+				F93599D50DF1F93700E04F67 /* my.n */,
+				F96D3E7408F272A6004A47F5 /* Namespace.3 */,
+				F96D3E7508F272A6004A47F5 /* namespace.n */,
+				F93599D60DF1F95000E04F67 /* next.n */,
+				F96D3E7608F272A6004A47F5 /* Notifier.3 */,
+				F96D3E7708F272A6004A47F5 /* Object.3 */,
+				F93599D70DF1F96800E04F67 /* object.n */,
+				F96D3E7808F272A6004A47F5 /* ObjectType.3 */,
+				F96D3E7908F272A6004A47F5 /* open.n */,
+				F96D3E7A08F272A6004A47F5 /* OpenFileChnl.3 */,
+				F96D3E7B08F272A6004A47F5 /* OpenTcp.3 */,
+				F96D3E7C08F272A6004A47F5 /* package.n */,
+				F96D3E7D08F272A6004A47F5 /* packagens.n */,
+				F96D3E7E08F272A6004A47F5 /* Panic.3 */,
+				F96D3E7F08F272A6004A47F5 /* ParseCmd.3 */,
+				F96D3E8008F272A6004A47F5 /* pid.n */,
+				F96D3E8108F272A6004A47F5 /* pkgMkIndex.n */,
+				F96D3E8208F272A6004A47F5 /* PkgRequire.3 */,
+				F9ECB1E10B26543C00A28025 /* platform_shell.n */,
+				F9ECB1E20B26543C00A28025 /* platform.n */,
+				F96D3E8308F272A6004A47F5 /* Preserve.3 */,
+				F96D3E8408F272A6004A47F5 /* PrintDbl.3 */,
+				F96D3E8508F272A6004A47F5 /* proc.n */,
+				F96D3E8608F272A6004A47F5 /* puts.n */,
+				F96D3E8708F272A6004A47F5 /* pwd.n */,
+				F96D3E8808F272A6004A47F5 /* re_syntax.n */,
+				F96D3E8908F272A6004A47F5 /* read.n */,
+				F96D3E8A08F272A6004A47F5 /* RecEvalObj.3 */,
+				F96D3E8B08F272A6004A47F5 /* RecordEval.3 */,
+				F96D3E8C08F272A6004A47F5 /* RegConfig.3 */,
+				F96D3E8D08F272A6004A47F5 /* RegExp.3 */,
+				F96D3E8E08F272A6004A47F5 /* regexp.n */,
+				F96D3E8F08F272A6004A47F5 /* registry.n */,
+				F96D3E9008F272A6004A47F5 /* regsub.n */,
+				F96D3E9108F272A6004A47F5 /* rename.n */,
+				F96D3E9208F272A6004A47F5 /* return.n */,
+				F96D3E9308F272A6004A47F5 /* safe.n */,
+				F96D3E9408F272A6004A47F5 /* SaveResult.3 */,
+				F96D3E9508F272A6004A47F5 /* scan.n */,
+				F96D3E9608F272A6004A47F5 /* seek.n */,
+				F93599D80DF1F98300E04F67 /* self.n */,
+				F96D3E9708F272A6004A47F5 /* set.n */,
+				F96D3E9808F272A6004A47F5 /* SetChanErr.3 */,
+				F96D3E9908F272A6004A47F5 /* SetErrno.3 */,
+				F96D3E9A08F272A6004A47F5 /* SetRecLmt.3 */,
+				F96D3E9B08F272A7004A47F5 /* SetResult.3 */,
+				F96D3E9C08F272A7004A47F5 /* SetVar.3 */,
+				F96D3E9D08F272A7004A47F5 /* Signal.3 */,
+				F96D3E9E08F272A7004A47F5 /* Sleep.3 */,
+				F96D3E9F08F272A7004A47F5 /* socket.n */,
+				F96D3EA008F272A7004A47F5 /* source.n */,
+				F96D3EA108F272A7004A47F5 /* SourceRCFile.3 */,
+				F96D3EA208F272A7004A47F5 /* split.n */,
+				F96D3EA308F272A7004A47F5 /* SplitList.3 */,
+				F96D3EA408F272A7004A47F5 /* SplitPath.3 */,
+				F96D3EA508F272A7004A47F5 /* StaticPkg.3 */,
+				F96D3EA608F272A7004A47F5 /* StdChannels.3 */,
+				F96D3EA708F272A7004A47F5 /* string.n */,
+				F96D3EA808F272A7004A47F5 /* StringObj.3 */,
+				F96D3EA908F272A7004A47F5 /* StrMatch.3 */,
+				F96D3EAA08F272A7004A47F5 /* subst.n */,
+				F96D3EAB08F272A7004A47F5 /* SubstObj.3 */,
+				F96D3EAC08F272A7004A47F5 /* switch.n */,
+				F974D5760FBE7E1900BF728B /* tailcall.n */,
+				F96D3EAD08F272A7004A47F5 /* Tcl.n */,
+				F99D61180EF5573A00BBFE01 /* TclZlib.3 */,
+				F96D3EAE08F272A7004A47F5 /* Tcl_Main.3 */,
+				F96D3EAF08F272A7004A47F5 /* TCL_MEM_DEBUG.3 */,
+				F96D3EB008F272A7004A47F5 /* tclsh.1 */,
+				F96D3EB108F272A7004A47F5 /* tcltest.n */,
+				F96D3EB208F272A7004A47F5 /* tclvars.n */,
+				F96D3EB308F272A7004A47F5 /* tell.n */,
+				F96D3EB408F272A7004A47F5 /* Thread.3 */,
+				F9183E640EFC80CD0030B814 /* throw.n */,
+				F96D3EB508F272A7004A47F5 /* time.n */,
+				F96D3EB608F272A7004A47F5 /* tm.n */,
+				F96D3EB708F272A7004A47F5 /* ToUpper.3 */,
+				F96D3EB808F272A7004A47F5 /* trace.n */,
+				F96D3EB908F272A7004A47F5 /* TraceCmd.3 */,
+				F96D3EBA08F272A7004A47F5 /* TraceVar.3 */,
+				F96D3EBB08F272A7004A47F5 /* Translate.3 */,
+				F9183E650EFC80D70030B814 /* try.n */,
+				F96D3EBC08F272A7004A47F5 /* UniCharIsAlpha.3 */,
+				F96D3EBD08F272A7004A47F5 /* unknown.n */,
+				F96D3EBE08F272A7004A47F5 /* unload.n */,
+				F96D3EBF08F272A7004A47F5 /* unset.n */,
+				F96D3EC008F272A7004A47F5 /* update.n */,
+				F96D3EC108F272A7004A47F5 /* uplevel.n */,
+				F96D3EC208F272A7004A47F5 /* UpVar.3 */,
+				F96D3EC308F272A7004A47F5 /* upvar.n */,
+				F96D3EC408F272A7004A47F5 /* Utf.3 */,
+				F96D3EC508F272A7004A47F5 /* variable.n */,
+				F96D3EC608F272A7004A47F5 /* vwait.n */,
+				F96D3EC708F272A7004A47F5 /* while.n */,
+				F96D3EC808F272A7004A47F5 /* WrongNumArgs.3 */,
+				F915432D0EF201EE0032D1E8 /* zlib.n */,
+			);
+			path = doc;
+			sourceTree = "<group>";
+		};
+		F96D3EC908F272A7004A47F5 /* generic */ = {
+			isa = PBXGroup;
+			children = (
+				F96D3ECA08F272A7004A47F5 /* README */,
+				F96D3ECB08F272A7004A47F5 /* regc_color.c */,
+				F96D3ECC08F272A7004A47F5 /* regc_cvec.c */,
+				F96D3ECD08F272A7004A47F5 /* regc_lex.c */,
+				F96D3ECE08F272A7004A47F5 /* regc_locale.c */,
+				F96D3ECF08F272A7004A47F5 /* regc_nfa.c */,
+				F96D3ED008F272A7004A47F5 /* regcomp.c */,
+				F96D3ED108F272A7004A47F5 /* regcustom.h */,
+				F96D3ED208F272A7004A47F5 /* rege_dfa.c */,
+				F96D3ED308F272A7004A47F5 /* regerror.c */,
+				F96D3ED408F272A7004A47F5 /* regerrs.h */,
+				F96D3ED508F272A7004A47F5 /* regex.h */,
+				F96D3ED608F272A7004A47F5 /* regexec.c */,
+				F96D3ED708F272A7004A47F5 /* regfree.c */,
+				F96D3ED808F272A7004A47F5 /* regfronts.c */,
+				F96D3ED908F272A7004A47F5 /* regguts.h */,
+				F96D3EDA08F272A7004A47F5 /* tcl.decls */,
+				F96D3EDB08F272A7004A47F5 /* tcl.h */,
+				F96D3EDC08F272A7004A47F5 /* tclAlloc.c */,
+				F96D3EDD08F272A7004A47F5 /* tclAsync.c */,
+				F96D3EDE08F272A7004A47F5 /* tclBasic.c */,
+				F96D3EDF08F272A7004A47F5 /* tclBinary.c */,
+				F96D3EE008F272A7004A47F5 /* tclCkalloc.c */,
+				F96D3EE108F272A7004A47F5 /* tclClock.c */,
+				F96D3EE208F272A7004A47F5 /* tclCmdAH.c */,
+				F96D3EE308F272A7004A47F5 /* tclCmdIL.c */,
+				F96D3EE408F272A7004A47F5 /* tclCmdMZ.c */,
+				F96D3EE508F272A7004A47F5 /* tclCompCmds.c */,
+				F96D3EE608F272A7004A47F5 /* tclCompExpr.c */,
+				F96D3EE708F272A7004A47F5 /* tclCompile.c */,
+				F96D3EE808F272A7004A47F5 /* tclCompile.h */,
+				F96D3EE908F272A7004A47F5 /* tclConfig.c */,
+				F96D3EEA08F272A7004A47F5 /* tclDate.c */,
+				F96D3EEB08F272A7004A47F5 /* tclDecls.h */,
+				F96D3EEC08F272A7004A47F5 /* tclDictObj.c */,
+				F9F4415D0C8BAE6F00BCCD67 /* tclDTrace.d */,
+				F96D3EED08F272A7004A47F5 /* tclEncoding.c */,
+				F96D3EEE08F272A7004A47F5 /* tclEnv.c */,
+				F96D3EEF08F272A7004A47F5 /* tclEvent.c */,
+				F96D3EF008F272A7004A47F5 /* tclExecute.c */,
+				F96D3EF108F272A7004A47F5 /* tclFCmd.c */,
+				F96D3EF208F272A7004A47F5 /* tclFileName.c */,
+				F96D3EF308F272A7004A47F5 /* tclFileSystem.h */,
+				F96D3EF408F272A7004A47F5 /* tclGet.c */,
+				F96D3EF508F272A7004A47F5 /* tclGetDate.y */,
+				F96D3EF608F272A7004A47F5 /* tclHash.c */,
+				F96D3EF708F272A7004A47F5 /* tclHistory.c */,
+				F96D3EF808F272A7004A47F5 /* tclIndexObj.c */,
+				F96D3EF908F272A7004A47F5 /* tclInt.decls */,
+				F96D3EFA08F272A7004A47F5 /* tclInt.h */,
+				F96D3EFB08F272A7004A47F5 /* tclIntDecls.h */,
+				F96D3EFC08F272A7004A47F5 /* tclInterp.c */,
+				F96D3EFD08F272A7004A47F5 /* tclIntPlatDecls.h */,
+				F96D3EFE08F272A7004A47F5 /* tclIO.c */,
+				F96D3EFF08F272A7004A47F5 /* tclIO.h */,
+				F96D3F0008F272A7004A47F5 /* tclIOCmd.c */,
+				F96D3F0108F272A7004A47F5 /* tclIOGT.c */,
+				F96D3F0208F272A7004A47F5 /* tclIORChan.c */,
+				F95D77E90DFD820D00A8BF6F /* tclIORTrans.c */,
+				F96D3F0308F272A7004A47F5 /* tclIOSock.c */,
+				F96D3F0408F272A7004A47F5 /* tclIOUtil.c */,
+				F96D3F0508F272A7004A47F5 /* tclLink.c */,
+				F96D3F0608F272A7004A47F5 /* tclListObj.c */,
+				F96D3F0708F272A7004A47F5 /* tclLiteral.c */,
+				F96D3F0808F272A7004A47F5 /* tclLoad.c */,
+				F96D3F0908F272A7004A47F5 /* tclLoadNone.c */,
+				F96D3F0A08F272A7004A47F5 /* tclMain.c */,
+				F96D3F0B08F272A7004A47F5 /* tclNamesp.c */,
+				F96D3F0C08F272A7004A47F5 /* tclNotify.c */,
+				F96D3F0D08F272A7004A47F5 /* tclObj.c */,
+				F93599B20DF1F75400E04F67 /* tclOO.c */,
+				F93599B40DF1F75900E04F67 /* tclOO.decls */,
+				F93599B50DF1F75D00E04F67 /* tclOO.h */,
+				F93599B60DF1F76100E04F67 /* tclOOBasic.c */,
+				F93599B80DF1F76600E04F67 /* tclOOCall.c */,
+				F93599BA0DF1F76A00E04F67 /* tclOODecls.h */,
+				F93599BB0DF1F77000E04F67 /* tclOODefineCmds.c */,
+				F93599BD0DF1F77400E04F67 /* tclOOInfo.c */,
+				F93599BF0DF1F77900E04F67 /* tclOOInt.h */,
+				F93599C00DF1F77D00E04F67 /* tclOOIntDecls.h */,
+				F93599C10DF1F78300E04F67 /* tclOOMethod.c */,
+				F93599C30DF1F78800E04F67 /* tclOOStubInit.c */,
+				F93599C50DF1F78D00E04F67 /* tclOOStubLib.c */,
+				F96D3F0E08F272A7004A47F5 /* tclPanic.c */,
+				F96D3F0F08F272A7004A47F5 /* tclParse.c */,
+				F96D3F1108F272A7004A47F5 /* tclPathObj.c */,
+				F96D3F1208F272A7004A47F5 /* tclPipe.c */,
+				F96D3F1308F272A7004A47F5 /* tclPkg.c */,
+				F96D3F1408F272A7004A47F5 /* tclPkgConfig.c */,
+				F96D3F1508F272A7004A47F5 /* tclPlatDecls.h */,
+				F96D3F1608F272A7004A47F5 /* tclPort.h */,
+				F96D3F1708F272A7004A47F5 /* tclPosixStr.c */,
+				F96D3F1808F272A7004A47F5 /* tclPreserve.c */,
+				F96D3F1908F272A7004A47F5 /* tclProc.c */,
+				F96D3F1A08F272A7004A47F5 /* tclRegexp.c */,
+				F96D3F1B08F272A7004A47F5 /* tclRegexp.h */,
+				F96D3F1C08F272A7004A47F5 /* tclResolve.c */,
+				F96D3F1D08F272A7004A47F5 /* tclResult.c */,
+				F96D3F1E08F272A7004A47F5 /* tclScan.c */,
+				F96D3F1F08F272A7004A47F5 /* tclStringObj.c */,
+				F96D3F2408F272A7004A47F5 /* tclStrToD.c */,
+				F96D3F2508F272A7004A47F5 /* tclStubInit.c */,
+				F96D3F2608F272A7004A47F5 /* tclStubLib.c */,
+				F96D3F2708F272A7004A47F5 /* tclTest.c */,
+				F96D3F2808F272A7004A47F5 /* tclTestObj.c */,
+				F96D3F2908F272A7004A47F5 /* tclTestProcBodyObj.c */,
+				F96D3F2A08F272A7004A47F5 /* tclThread.c */,
+				F96D3F2B08F272A7004A47F5 /* tclThreadAlloc.c */,
+				F96D3F2C08F272A7004A47F5 /* tclThreadJoin.c */,
+				F96D3F2D08F272A7004A47F5 /* tclThreadStorage.c */,
+				F96D3F2E08F272A7004A47F5 /* tclThreadTest.c */,
+				F96D3F2F08F272A7004A47F5 /* tclTimer.c */,
+				F9903CAF094FAADA004613E9 /* tclTomMath.decls */,
+				F96D3F3008F272A7004A47F5 /* tclTomMath.h */,
+				F9903CB0094FAADA004613E9 /* tclTomMathDecls.h */,
+				F96D3F3108F272A7004A47F5 /* tclTomMathInterface.c */,
+				F96D3F3208F272A7004A47F5 /* tclTrace.c */,
+				F96D3F3308F272A7004A47F5 /* tclUniData.c */,
+				F96D3F3408F272A7004A47F5 /* tclUtf.c */,
+				F96D3F3508F272A7004A47F5 /* tclUtil.c */,
+				F96D3F3608F272A7004A47F5 /* tclVar.c */,
+				F96437C90EF0D4B2003F468E /* tclZlib.c */,
+				F96D3F3708F272A7004A47F5 /* tommath.h */,
+			);
+			path = generic;
+			sourceTree = "<group>";
+		};
+		F96D3F3808F272A7004A47F5 /* library */ = {
+			isa = PBXGroup;
+			children = (
+				F96D3F3908F272A8004A47F5 /* auto.tcl */,
+				F96D3F3A08F272A8004A47F5 /* clock.tcl */,
+				F96D3F3B08F272A8004A47F5 /* dde */,
+				F96D3F8C08F272A8004A47F5 /* history.tcl */,
+				F96D3F8D08F272A8004A47F5 /* http */,
+				F96D3F9008F272A8004A47F5 /* http1.0 */,
+				F96D3F9308F272A8004A47F5 /* init.tcl */,
+				F96D3F9408F272A8004A47F5 /* msgcat */,
+				F96D401708F272AA004A47F5 /* opt */,
+				F96D401A08F272AA004A47F5 /* package.tcl */,
+				F96D401B08F272AA004A47F5 /* parray.tcl */,
+				F9ECB1110B26521500A28025 /* platform */,
+				F96D401C08F272AA004A47F5 /* reg */,
+				F96D401E08F272AA004A47F5 /* safe.tcl */,
+				F96D401F08F272AA004A47F5 /* tclIndex */,
+				F96D402008F272AA004A47F5 /* tcltest */,
+				F96D402308F272AA004A47F5 /* tm.tcl */,
+				F96D425B08F272B2004A47F5 /* word.tcl */,
+			);
+			path = library;
+			sourceTree = "<group>";
+		};
+		F96D3F3B08F272A8004A47F5 /* dde */ = {
+			isa = PBXGroup;
+			children = (
+				F96D3F3C08F272A8004A47F5 /* pkgIndex.tcl */,
+			);
+			path = dde;
+			sourceTree = "<group>";
+		};
+		F96D3F8D08F272A8004A47F5 /* http */ = {
+			isa = PBXGroup;
+			children = (
+				F96D3F8E08F272A8004A47F5 /* http.tcl */,
+				F96D3F8F08F272A8004A47F5 /* pkgIndex.tcl */,
+			);
+			path = http;
+			sourceTree = "<group>";
+		};
+		F96D3F9008F272A8004A47F5 /* http1.0 */ = {
+			isa = PBXGroup;
+			children = (
+				F96D3F9108F272A8004A47F5 /* http.tcl */,
+				F96D3F9208F272A8004A47F5 /* pkgIndex.tcl */,
+			);
+			path = http1.0;
+			sourceTree = "<group>";
+		};
+		F96D3F9408F272A8004A47F5 /* msgcat */ = {
+			isa = PBXGroup;
+			children = (
+				F96D3F9508F272A8004A47F5 /* msgcat.tcl */,
+				F96D3F9608F272A8004A47F5 /* pkgIndex.tcl */,
+			);
+			path = msgcat;
+			sourceTree = "<group>";
+		};
+		F96D401708F272AA004A47F5 /* opt */ = {
+			isa = PBXGroup;
+			children = (
+				F96D401808F272AA004A47F5 /* optparse.tcl */,
+				F96D401908F272AA004A47F5 /* pkgIndex.tcl */,
+			);
+			path = opt;
+			sourceTree = "<group>";
+		};
+		F96D401C08F272AA004A47F5 /* reg */ = {
+			isa = PBXGroup;
+			children = (
+				F96D401D08F272AA004A47F5 /* pkgIndex.tcl */,
+			);
+			path = reg;
+			sourceTree = "<group>";
+		};
+		F96D402008F272AA004A47F5 /* tcltest */ = {
+			isa = PBXGroup;
+			children = (
+				F96D402108F272AA004A47F5 /* pkgIndex.tcl */,
+				F96D402208F272AA004A47F5 /* tcltest.tcl */,
+			);
+			path = tcltest;
+			sourceTree = "<group>";
+		};
+		F96D425C08F272B2004A47F5 /* libtommath */ = {
+			isa = PBXGroup;
+			children = (
+				F96D426408F272B3004A47F5 /* bn_fast_s_mp_mul_digs.c */,
+				F96D426608F272B3004A47F5 /* bn_fast_s_mp_sqr.c */,
+				F96D426908F272B3004A47F5 /* bn_mp_add.c */,
+				F96D426A08F272B3004A47F5 /* bn_mp_add_d.c */,
+				F96D426C08F272B3004A47F5 /* bn_mp_and.c */,
+				F96D426D08F272B3004A47F5 /* bn_mp_clamp.c */,
+				F96D426E08F272B3004A47F5 /* bn_mp_clear.c */,
+				F96D426F08F272B3004A47F5 /* bn_mp_clear_multi.c */,
+				F96D427008F272B3004A47F5 /* bn_mp_cmp.c */,
+				F96D427108F272B3004A47F5 /* bn_mp_cmp_d.c */,
+				F96D427208F272B3004A47F5 /* bn_mp_cmp_mag.c */,
+				F96D427408F272B3004A47F5 /* bn_mp_copy.c */,
+				F96D427508F272B3004A47F5 /* bn_mp_count_bits.c */,
+				F96D427608F272B3004A47F5 /* bn_mp_div.c */,
+				F96D427708F272B3004A47F5 /* bn_mp_div_2.c */,
+				F96D427808F272B3004A47F5 /* bn_mp_div_2d.c */,
+				F96D427908F272B3004A47F5 /* bn_mp_div_3.c */,
+				F96D427A08F272B3004A47F5 /* bn_mp_div_d.c */,
+				F96D427E08F272B3004A47F5 /* bn_mp_exch.c */,
+				F96D427F08F272B3004A47F5 /* bn_mp_expt_d.c */,
+				F96D428708F272B3004A47F5 /* bn_mp_grow.c */,
+				F96D428808F272B3004A47F5 /* bn_mp_init.c */,
+				F96D428908F272B3004A47F5 /* bn_mp_init_copy.c */,
+				F96D428A08F272B3004A47F5 /* bn_mp_init_multi.c */,
+				F96D428B08F272B3004A47F5 /* bn_mp_init_set.c */,
+				F96D428D08F272B3004A47F5 /* bn_mp_init_size.c */,
+				F96D429208F272B3004A47F5 /* bn_mp_karatsuba_mul.c */,
+				F96D429308F272B3004A47F5 /* bn_mp_karatsuba_sqr.c */,
+				F96D429508F272B3004A47F5 /* bn_mp_lshd.c */,
+				F96D429608F272B3004A47F5 /* bn_mp_mod.c */,
+				F96D429708F272B3004A47F5 /* bn_mp_mod_2d.c */,
+				F96D429C08F272B3004A47F5 /* bn_mp_mul.c */,
+				F96D429D08F272B3004A47F5 /* bn_mp_mul_2.c */,
+				F96D429E08F272B3004A47F5 /* bn_mp_mul_2d.c */,
+				F96D429F08F272B3004A47F5 /* bn_mp_mul_d.c */,
+				F96D42A208F272B3004A47F5 /* bn_mp_neg.c */,
+				F96D42A308F272B3004A47F5 /* bn_mp_or.c */,
+				F96D42AB08F272B3004A47F5 /* bn_mp_radix_size.c */,
+				F96D42AC08F272B3004A47F5 /* bn_mp_radix_smap.c */,
+				F96D42AE08F272B3004A47F5 /* bn_mp_read_radix.c */,
+				F96D42B908F272B3004A47F5 /* bn_mp_rshd.c */,
+				F96D42BA08F272B3004A47F5 /* bn_mp_set.c */,
+				F96D42BC08F272B3004A47F5 /* bn_mp_shrink.c */,
+				F96D42BE08F272B3004A47F5 /* bn_mp_sqr.c */,
+				F96D42C008F272B3004A47F5 /* bn_mp_sqrt.c */,
+				F96D42C108F272B3004A47F5 /* bn_mp_sub.c */,
+				F96D42C208F272B3004A47F5 /* bn_mp_sub_d.c */,
+				F96D42C608F272B3004A47F5 /* bn_mp_to_unsigned_bin.c */,
+				F96D42C708F272B3004A47F5 /* bn_mp_to_unsigned_bin_n.c */,
+				F96D42C808F272B3004A47F5 /* bn_mp_toom_mul.c */,
+				F96D42C908F272B3004A47F5 /* bn_mp_toom_sqr.c */,
+				F96D42CB08F272B3004A47F5 /* bn_mp_toradix_n.c */,
+				F96D42CC08F272B3004A47F5 /* bn_mp_unsigned_bin_size.c */,
+				F96D42CD08F272B3004A47F5 /* bn_mp_xor.c */,
+				F96D42CE08F272B3004A47F5 /* bn_mp_zero.c */,
+				F96D42D008F272B3004A47F5 /* bn_reverse.c */,
+				F96D42D108F272B3004A47F5 /* bn_s_mp_add.c */,
+				F96D42D308F272B3004A47F5 /* bn_s_mp_mul_digs.c */,
+				F96D42D508F272B3004A47F5 /* bn_s_mp_sqr.c */,
+				F96D42D608F272B3004A47F5 /* bn_s_mp_sub.c */,
+				F96D42D708F272B3004A47F5 /* bncore.c */,
+				F96D432908F272B4004A47F5 /* tommath_class.h */,
+				F96D432A08F272B4004A47F5 /* tommath_superclass.h */,
+			);
+			path = libtommath;
+			sourceTree = "<group>";
+		};
+		F96D432C08F272B4004A47F5 /* macosx */ = {
+			isa = PBXGroup;
+			children = (
+				F96D432E08F272B5004A47F5 /* configure.ac */,
+				F96D432F08F272B5004A47F5 /* GNUmakefile */,
+				F96D433108F272B5004A47F5 /* README */,
+				F96D433908F272B5004A47F5 /* tclMacOSXBundle.c */,
+				F96D433D08F272B5004A47F5 /* tclMacOSXFCmd.c */,
+				F96D433E08F272B5004A47F5 /* tclMacOSXNotify.c */,
+				F96D433208F272B5004A47F5 /* Tcl-Info.plist.in */,
+				F91E62260C1AE686006C9D96 /* Tclsh-Info.plist.in */,
+				F97AE7F10B65C1E900310EA2 /* Tcl-Common.xcconfig */,
+				F97AE8330B65C87F00310EA2 /* Tcl-Debug.xcconfig */,
+				F97AE82B0B65C69B00310EA2 /* Tcl-Release.xcconfig */,
+			);
+			path = macosx;
+			sourceTree = "<group>";
+		};
+		F96D434408F272B5004A47F5 /* tests */ = {
+			isa = PBXGroup;
+			children = (
+				F96D434508F272B5004A47F5 /* all.tcl */,
+				F96D434608F272B5004A47F5 /* append.test */,
+				F96D434708F272B5004A47F5 /* appendComp.test */,
+				F9ECB1CA0B2652D300A28025 /* apply.test */,
+				F96D434808F272B5004A47F5 /* assocd.test */,
+				F96D434908F272B5004A47F5 /* async.test */,
+				F96D434A08F272B5004A47F5 /* autoMkindex.test */,
+				F96D434B08F272B5004A47F5 /* basic.test */,
+				F96D434C08F272B5004A47F5 /* binary.test */,
+				F96D434D08F272B5004A47F5 /* case.test */,
+				F96D434E08F272B5004A47F5 /* chan.test */,
+				F9A493240CEBF38300B78AE2 /* chanio.test */,
+				F96D434F08F272B5004A47F5 /* clock.test */,
+				F96D435008F272B5004A47F5 /* cmdAH.test */,
+				F96D435108F272B5004A47F5 /* cmdIL.test */,
+				F96D435208F272B5004A47F5 /* cmdInfo.test */,
+				F96D435308F272B5004A47F5 /* cmdMZ.test */,
+				F96D435408F272B5004A47F5 /* compExpr-old.test */,
+				F96D435508F272B5004A47F5 /* compExpr.test */,
+				F96D435608F272B5004A47F5 /* compile.test */,
+				F96D435708F272B5004A47F5 /* concat.test */,
+				F96D435808F272B5004A47F5 /* config.test */,
+				F974D5770FBE7E6100BF728B /* coroutine.test */,
+				F96D435908F272B5004A47F5 /* dcall.test */,
+				F96D435A08F272B5004A47F5 /* dict.test */,
+				F96D435C08F272B5004A47F5 /* dstring.test */,
+				F96D435E08F272B5004A47F5 /* encoding.test */,
+				F96D435F08F272B5004A47F5 /* env.test */,
+				F96D436008F272B5004A47F5 /* error.test */,
+				F96D436108F272B5004A47F5 /* eval.test */,
+				F96D436208F272B5004A47F5 /* event.test */,
+				F96D436308F272B5004A47F5 /* exec.test */,
+				F96D436408F272B5004A47F5 /* execute.test */,
+				F96D436508F272B5004A47F5 /* expr-old.test */,
+				F96D436608F272B5004A47F5 /* expr.test */,
+				F96D436708F272B6004A47F5 /* fCmd.test */,
+				F96D436808F272B6004A47F5 /* fileName.test */,
+				F96D436908F272B6004A47F5 /* fileSystem.test */,
+				F96D436A08F272B6004A47F5 /* for-old.test */,
+				F96D436B08F272B6004A47F5 /* for.test */,
+				F96D436C08F272B6004A47F5 /* foreach.test */,
+				F96D436D08F272B6004A47F5 /* format.test */,
+				F96D436E08F272B6004A47F5 /* get.test */,
+				F96D436F08F272B6004A47F5 /* history.test */,
+				F96D437008F272B6004A47F5 /* http.test */,
+				F974D56C0FBE7D6300BF728B /* http11.test */,
+				F96D437108F272B6004A47F5 /* httpd */,
+				F974D56D0FBE7D6300BF728B /* httpd11.tcl */,
+				F96D437208F272B6004A47F5 /* httpold.test */,
+				F96D437308F272B6004A47F5 /* if-old.test */,
+				F96D437408F272B6004A47F5 /* if.test */,
+				F96D437508F272B6004A47F5 /* incr-old.test */,
+				F96D437608F272B6004A47F5 /* incr.test */,
+				F96D437708F272B6004A47F5 /* indexObj.test */,
+				F96D437808F272B6004A47F5 /* info.test */,
+				F96D437908F272B6004A47F5 /* init.test */,
+				F96D437A08F272B6004A47F5 /* interp.test */,
+				F96D437B08F272B6004A47F5 /* io.test */,
+				F96D437C08F272B6004A47F5 /* ioCmd.test */,
+				F96D437D08F272B6004A47F5 /* iogt.test */,
+				F96D437F08F272B6004A47F5 /* join.test */,
+				F96D438008F272B6004A47F5 /* lindex.test */,
+				F96D438108F272B6004A47F5 /* link.test */,
+				F96D438208F272B6004A47F5 /* linsert.test */,
+				F96D438308F272B6004A47F5 /* list.test */,
+				F96D438408F272B6004A47F5 /* listObj.test */,
+				F96D438508F272B6004A47F5 /* llength.test */,
+				F96D438608F272B6004A47F5 /* load.test */,
+				F96D438708F272B6004A47F5 /* lrange.test */,
+				F96D438808F272B6004A47F5 /* lrepeat.test */,
+				F96D438908F272B6004A47F5 /* lreplace.test */,
+				F96D438A08F272B6004A47F5 /* lsearch.test */,
+				F96D438B08F272B6004A47F5 /* lset.test */,
+				F96D438C08F272B6004A47F5 /* lsetComp.test */,
+				F96D438D08F272B6004A47F5 /* macOSXFCmd.test */,
+				F95FAFF90B34F1130072E431 /* macOSXLoad.test */,
+				F96D438E08F272B6004A47F5 /* main.test */,
+				F9ECB1CB0B26534C00A28025 /* mathop.test */,
+				F96D438F08F272B6004A47F5 /* misc.test */,
+				F96D439008F272B6004A47F5 /* msgcat.test */,
+				F96D439108F272B6004A47F5 /* namespace-old.test */,
+				F96D439208F272B7004A47F5 /* namespace.test */,
+				F96D439308F272B7004A47F5 /* notify.test */,
+				F91DC23C0E44C51B002CB8D1 /* nre.test */,
+				F96D439408F272B7004A47F5 /* obj.test */,
+				F93599C80DF1F81900E04F67 /* oo.test */,
+				F96D439508F272B7004A47F5 /* opt.test */,
+				F96D439608F272B7004A47F5 /* package.test */,
+				F96D439708F272B7004A47F5 /* parse.test */,
+				F96D439808F272B7004A47F5 /* parseExpr.test */,
+				F96D439908F272B7004A47F5 /* parseOld.test */,
+				F96D439A08F272B7004A47F5 /* pid.test */,
+				F96D439B08F272B7004A47F5 /* pkg.test */,
+				F96D439C08F272B7004A47F5 /* pkgMkIndex.test */,
+				F96D439D08F272B7004A47F5 /* platform.test */,
+				F96D439E08F272B7004A47F5 /* proc-old.test */,
+				F96D439F08F272B7004A47F5 /* proc.test */,
+				F96D43A008F272B7004A47F5 /* pwd.test */,
+				F96D43A108F272B7004A47F5 /* README */,
+				F96D43A208F272B7004A47F5 /* reg.test */,
+				F96D43A308F272B7004A47F5 /* regexp.test */,
+				F96D43A408F272B7004A47F5 /* regexpComp.test */,
+				F96D43A508F272B7004A47F5 /* registry.test */,
+				F96D43A608F272B7004A47F5 /* remote.tcl */,
+				F96D43A708F272B7004A47F5 /* rename.test */,
+				F96D43A808F272B7004A47F5 /* result.test */,
+				F96D43A908F272B7004A47F5 /* safe.test */,
+				F96D43AA08F272B7004A47F5 /* scan.test */,
+				F96D43AB08F272B7004A47F5 /* security.test */,
+				F96D43AC08F272B7004A47F5 /* set-old.test */,
+				F96D43AD08F272B7004A47F5 /* set.test */,
+				F96D43AE08F272B7004A47F5 /* socket.test */,
+				F96D43AF08F272B7004A47F5 /* source.test */,
+				F96D43B008F272B7004A47F5 /* split.test */,
+				F96D43B108F272B7004A47F5 /* stack.test */,
+				F96D43B208F272B7004A47F5 /* string.test */,
+				F96D43B308F272B7004A47F5 /* stringComp.test */,
+				F96D43B408F272B7004A47F5 /* stringObj.test */,
+				F96D43B508F272B7004A47F5 /* subst.test */,
+				F96D43B608F272B7004A47F5 /* switch.test */,
+				F974D5780FBE7E6100BF728B /* tailcall.test */,
+				F96D43B708F272B7004A47F5 /* tcltest.test */,
+				F96D43B808F272B7004A47F5 /* thread.test */,
+				F96D43B908F272B7004A47F5 /* timer.test */,
+				F96D43BA08F272B7004A47F5 /* tm.test */,
+				F96D43BB08F272B7004A47F5 /* trace.test */,
+				F96D43BC08F272B7004A47F5 /* unixFCmd.test */,
+				F96D43BD08F272B7004A47F5 /* unixFile.test */,
+				F96D43BE08F272B7004A47F5 /* unixInit.test */,
+				F96D43BF08F272B7004A47F5 /* unixNotfy.test */,
+				F96D43C008F272B7004A47F5 /* unknown.test */,
+				F96D43C108F272B7004A47F5 /* unload.test */,
+				F96D43C208F272B7004A47F5 /* uplevel.test */,
+				F96D43C308F272B7004A47F5 /* upvar.test */,
+				F96D43C408F272B7004A47F5 /* utf.test */,
+				F96D43C508F272B7004A47F5 /* util.test */,
+				F96D43C608F272B7004A47F5 /* var.test */,
+				F96D43C708F272B7004A47F5 /* while-old.test */,
+				F96D43C808F272B7004A47F5 /* while.test */,
+				F96D43C908F272B7004A47F5 /* winConsole.test */,
+				F96D43CA08F272B7004A47F5 /* winDde.test */,
+				F96D43CB08F272B7004A47F5 /* winFCmd.test */,
+				F96D43CC08F272B7004A47F5 /* winFile.test */,
+				F96D43CD08F272B7004A47F5 /* winNotify.test */,
+				F96D43CE08F272B7004A47F5 /* winPipe.test */,
+				F96D43CF08F272B7004A47F5 /* winTime.test */,
+				F915432A0EF201CF0032D1E8 /* zlib.test */,
+			);
+			path = tests;
+			sourceTree = "<group>";
+		};
+		F96D43D008F272B8004A47F5 /* tools */ = {
+			isa = PBXGroup;
+			children = (
+				F96D43D108F272B8004A47F5 /* checkLibraryDoc.tcl */,
+				F96D43D208F272B8004A47F5 /* configure */,
+				F96D43D308F272B8004A47F5 /* configure.in */,
+				F96D442408F272B8004A47F5 /* fix_tommath_h.tcl */,
+				F96D442508F272B8004A47F5 /* genStubs.tcl */,
+				F96D442708F272B8004A47F5 /* index.tcl */,
+				F96D442808F272B8004A47F5 /* installData.tcl */,
+				F96D442908F272B8004A47F5 /* loadICU.tcl */,
+				F96D442A08F272B8004A47F5 /* Makefile.in */,
+				F96D442B08F272B8004A47F5 /* makeTestCases.tcl */,
+				F96D442C08F272B8004A47F5 /* man2help.tcl */,
+				F96D442D08F272B8004A47F5 /* man2help2.tcl */,
+				F96D442E08F272B8004A47F5 /* man2html.tcl */,
+				F96D442F08F272B8004A47F5 /* man2html1.tcl */,
+				F96D443008F272B8004A47F5 /* man2html2.tcl */,
+				F96D443108F272B8004A47F5 /* man2tcl.c */,
+				F96D443208F272B8004A47F5 /* README */,
+				F96D443308F272B8004A47F5 /* regexpTestLib.tcl */,
+				F96D443508F272B8004A47F5 /* tcl.hpj.in */,
+				F96D443908F272B9004A47F5 /* tcltk-man2html.tcl */,
+				F96D443A08F272B9004A47F5 /* tclZIC.tcl */,
+				F92D7F100DE777240033A13A /* tsdPerf.tcl */,
+				F96D443B08F272B9004A47F5 /* uniClass.tcl */,
+				F96D443C08F272B9004A47F5 /* uniParse.tcl */,
+			);
+			path = tools;
+			sourceTree = "<group>";
+		};
+		F96D443E08F272B9004A47F5 /* unix */ = {
+			isa = PBXGroup;
+			children = (
+				F96D444008F272B9004A47F5 /* aclocal.m4 */,
+				F96D444108F272B9004A47F5 /* configure */,
+				F96D444208F272B9004A47F5 /* configure.in */,
+				F96D444308F272B9004A47F5 /* dltest */,
+				F96D444D08F272B9004A47F5 /* install-sh */,
+				F96D444E08F272B9004A47F5 /* installManPage */,
+				F96D444F08F272B9004A47F5 /* ldAix */,
+				F96D445008F272B9004A47F5 /* Makefile.in */,
+				F96D445208F272B9004A47F5 /* README */,
+				F96D445308F272B9004A47F5 /* tcl.m4 */,
+				F974D5790FBE7E9C00BF728B /* tcl.pc.in */,
+				F96D445408F272B9004A47F5 /* tcl.spec */,
+				F96D445508F272B9004A47F5 /* tclAppInit.c */,
+				F96D445608F272B9004A47F5 /* tclConfig.h.in */,
+				F96D445708F272B9004A47F5 /* tclConfig.sh.in */,
+				F96D445808F272B9004A47F5 /* tclLoadAix.c */,
+				F96D445908F272B9004A47F5 /* tclLoadDl.c */,
+				F96D445B08F272B9004A47F5 /* tclLoadDyld.c */,
+				F96D445C08F272B9004A47F5 /* tclLoadNext.c */,
+				F96D445D08F272B9004A47F5 /* tclLoadOSF.c */,
+				F96D445E08F272B9004A47F5 /* tclLoadShl.c */,
+				F96D445F08F272B9004A47F5 /* tclUnixChan.c */,
+				F9FC77B70AB29E9100B7077D /* tclUnixCompat.c */,
+				F96D446008F272B9004A47F5 /* tclUnixEvent.c */,
+				F96D446108F272B9004A47F5 /* tclUnixFCmd.c */,
+				F96D446208F272B9004A47F5 /* tclUnixFile.c */,
+				F96D446308F272B9004A47F5 /* tclUnixInit.c */,
+				F96D446408F272B9004A47F5 /* tclUnixNotfy.c */,
+				F96D446508F272B9004A47F5 /* tclUnixPipe.c */,
+				F96D446608F272B9004A47F5 /* tclUnixPort.h */,
+				F96D446708F272B9004A47F5 /* tclUnixSock.c */,
+				F96D446808F272B9004A47F5 /* tclUnixTest.c */,
+				F96D446908F272B9004A47F5 /* tclUnixThrd.c */,
+				F96D446B08F272B9004A47F5 /* tclUnixTime.c */,
+				F96D446C08F272B9004A47F5 /* tclXtNotify.c */,
+				F96D446D08F272B9004A47F5 /* tclXtTest.c */,
+			);
+			path = unix;
+			sourceTree = "<group>";
+		};
+		F96D444308F272B9004A47F5 /* dltest */ = {
+			isa = PBXGroup;
+			children = (
+				F96D444408F272B9004A47F5 /* Makefile.in */,
+				F96D444508F272B9004A47F5 /* pkga.c */,
+				F96D444608F272B9004A47F5 /* pkgb.c */,
+				F96D444708F272B9004A47F5 /* pkgc.c */,
+				F96D444808F272B9004A47F5 /* pkgd.c */,
+				F96D444908F272B9004A47F5 /* pkge.c */,
+				F96D444B08F272B9004A47F5 /* pkgua.c */,
+				F96D444C08F272B9004A47F5 /* README */,
+			);
+			path = dltest;
+			sourceTree = "<group>";
+		};
+		F96D446E08F272B9004A47F5 /* win */ = {
+			isa = PBXGroup;
+			children = (
+				F96D447008F272BA004A47F5 /* aclocal.m4 */,
+				F96D447108F272BA004A47F5 /* buildall.vc.bat */,
+				F96D447208F272BA004A47F5 /* cat.c */,
+				F96D447308F272BA004A47F5 /* coffbase.txt */,
+				F96D447408F272BA004A47F5 /* configure */,
+				F96D447508F272BA004A47F5 /* configure.in */,
+				F96D447608F272BA004A47F5 /* makefile.bc */,
+				F96D447708F272BA004A47F5 /* Makefile.in */,
+				F96D447808F272BA004A47F5 /* makefile.vc */,
+				F96D447908F272BA004A47F5 /* nmakehlp.c */,
+				F96D447A08F272BA004A47F5 /* README */,
+				F96D447C08F272BA004A47F5 /* rules.vc */,
+				F96D447D08F272BA004A47F5 /* stub16.c */,
+				F96D447E08F272BA004A47F5 /* tcl.dsp */,
+				F96D447F08F272BA004A47F5 /* tcl.dsw */,
+				F96D448008F272BA004A47F5 /* tcl.hpj.in */,
+				F96D448108F272BA004A47F5 /* tcl.m4 */,
+				F96D448208F272BA004A47F5 /* tcl.rc */,
+				F96D448308F272BA004A47F5 /* tclAppInit.c */,
+				F96D448408F272BA004A47F5 /* tclConfig.sh.in */,
+				F96D448608F272BA004A47F5 /* tclsh.rc */,
+				F96D448708F272BA004A47F5 /* tclWin32Dll.c */,
+				F96D448808F272BA004A47F5 /* tclWinChan.c */,
+				F96D448908F272BA004A47F5 /* tclWinConsole.c */,
+				F96D448A08F272BA004A47F5 /* tclWinDde.c */,
+				F96D448B08F272BA004A47F5 /* tclWinError.c */,
+				F96D448C08F272BA004A47F5 /* tclWinFCmd.c */,
+				F96D448D08F272BA004A47F5 /* tclWinFile.c */,
+				F96D448E08F272BA004A47F5 /* tclWinInit.c */,
+				F96D448F08F272BA004A47F5 /* tclWinInt.h */,
+				F96D449008F272BA004A47F5 /* tclWinLoad.c */,
+				F96D449108F272BA004A47F5 /* tclWinNotify.c */,
+				F96D449208F272BA004A47F5 /* tclWinPipe.c */,
+				F96D449308F272BA004A47F5 /* tclWinPort.h */,
+				F96D449408F272BA004A47F5 /* tclWinReg.c */,
+				F96D449508F272BA004A47F5 /* tclWinSerial.c */,
+				F96D449608F272BA004A47F5 /* tclWinSock.c */,
+				F96D449708F272BA004A47F5 /* tclWinTest.c */,
+				F96D449808F272BA004A47F5 /* tclWinThrd.c */,
+				F96D449908F272BA004A47F5 /* tclWinThrd.h */,
+				F96D449A08F272BA004A47F5 /* tclWinTime.c */,
+			);
+			path = win;
+			sourceTree = "<group>";
+		};
+		F9ECB1110B26521500A28025 /* platform */ = {
+			isa = PBXGroup;
+			children = (
+				F9ECB1120B26521500A28025 /* pkgIndex.tcl */,
+				F9ECB1130B26521500A28025 /* platform.tcl */,
+				F9ECB1140B26521500A28025 /* shell.tcl */,
+			);
+			path = platform;
+			sourceTree = "<group>";
+		};
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+		8DD76FA90486AB0100D96B5E /* tcltest */ = {
+			isa = PBXNativeTarget;
+			buildConfigurationList = F95CC8B009158F3100EA5ACE /* Build configuration list for PBXNativeTarget "tcltest" */;
+			buildPhases = (
+				F9A5C5F508F651A2008AE941 /* Configure Tcl */,
+				8DD76FAB0486AB0100D96B5E /* Sources */,
+				8DD76FAD0486AB0100D96B5E /* Frameworks */,
+				F95FA74C0B32CE190072E431 /* Build dltest */,
+			);
+			buildRules = (
+			);
+			dependencies = (
+			);
+			name = tcltest;
+			productInstallPath = "$(BINDIR)";
+			productName = tcltest;
+			productReference = 8DD76FB20486AB0100D96B5E /* tcltest */;
+			productType = "com.apple.product-type.tool";
+		};
+		F97258A50A86873C00096C78 /* tests */ = {
+			isa = PBXNativeTarget;
+			buildConfigurationList = F97258A80A86873D00096C78 /* Build configuration list for PBXNativeTarget "tests" */;
+			buildPhases = (
+				F97258A40A86873C00096C78 /* Run Testsuite */,
+			);
+			buildRules = (
+			);
+			dependencies = (
+				F97258D30A868C6F00096C78 /* PBXTargetDependency */,
+			);
+			name = tests;
+			productName = tests;
+			productType = "com.apple.product-type.bundle";
+		};
+		F9E61D16090A3E94002B3151 /* Tcl */ = {
+			isa = PBXNativeTarget;
+			buildConfigurationList = F95CC8AB09158F3100EA5ACE /* Build configuration list for PBXNativeTarget "Tcl" */;
+			buildPhases = (
+				F97AF02F0B665DA900310EA2 /* Build Tcl */,
+			);
+			buildRules = (
+			);
+			dependencies = (
+			);
+			name = Tcl;
+			productName = tclsh;
+			productReference = F9A3084B08F2D4CE00BAE1AB /* tclsh */;
+			productType = "com.apple.product-type.tool";
+		};
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+		08FB7793FE84155DC02AAC07 /* Project object */ = {
+			isa = PBXProject;
+			attributes = {
+				BuildIndependentTargetsInParallel = YES;
+			};
+			buildConfigurationList = F95CC8B509158F3100EA5ACE /* Build configuration list for PBXProject "Tcl" */;
+			compatibilityVersion = "Xcode 3.2";
+			hasScannedForEncodings = 1;
+			mainGroup = 08FB7794FE84155DC02AAC07 /* Tcl */;
+			projectDirPath = "";
+			projectRoot = ..;
+			targets = (
+				F9E61D16090A3E94002B3151 /* Tcl */,
+				8DD76FA90486AB0100D96B5E /* tcltest */,
+				F97258A50A86873C00096C78 /* tests */,
+			);
+		};
+/* End PBXProject section */
+
+/* Begin PBXShellScriptBuildPhase section */
+		F95FA74C0B32CE190072E431 /* Build dltest */ = {
+			isa = PBXShellScriptBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			inputPaths = (
+				"$(DERIVED_FILE_DIR)/tcl/tclConfig.sh",
+				"$(TCL_SRCROOT)/generic/tclStubLib.c",
+				"$(TCL_SRCROOT)/unix/dltest/pkga.c",
+				"$(TCL_SRCROOT)/unix/dltest/pkgb.c",
+				"$(TCL_SRCROOT)/unix/dltest/pkgc.c",
+				"$(TCL_SRCROOT)/unix/dltest/pkgd.c",
+				"$(TCL_SRCROOT)/unix/dltest/pkge.c",
+				"$(TCL_SRCROOT)/unix/dltest/pkgua.c",
+			);
+			name = "Build dltest";
+			outputPaths = (
+				"$(DERIVED_FILE_DIR)/tcl/dltest.marker",
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+			shellPath = /bin/bash;
+			shellScript = "## dltest build script phase\n\nrm -f \"${DERIVED_FILE_DIR}/tcl/dltest.marker\"\nmake -C \"${DERIVED_FILE_DIR}/tcl\" dltest.marker\nln -fsh \"${DERIVED_FILE_DIR}/tcl/dltest\" \"${CONFIGURATION_BUILD_DIR}\"\n";
+			showEnvVarsInLog = 0;
+		};
+		F97258A40A86873C00096C78 /* Run Testsuite */ = {
+			isa = PBXShellScriptBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			inputPaths = (
+			);
+			name = "Run Testsuite";
+			outputPaths = (
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+			shellPath = /bin/bash;
+			shellScript = "if [ \"${ACTION:-build}\" == \"build\" ]; then\nif [ -z \"${HOME}\" ]; then export HOME=\"$(echo ~)\"; fi\ncd \"${TARGET_TEMP_DIR}\"; rm -rf \"${DERIVED_FILE_DIR}\"; mkdir -p \"${DERIVED_FILE_DIR}\"\nprintf '%s%s%s%s%s' '\npackage require tcltest 2.2\nnamespace import tcltest::*\nconfigure -testdir [file normalize {' \"${TCL_SRCROOT}\" '/tests}]\nconfigure -tmpdir [file normalize {' \"${DERIVED_FILE_DIR}\" '}]\nconfigure -verbose [concat [configure -verbose] line]\nrunAllTests\n' | \"${TEST_RIG}\"; TEST_RIG_RESULT=$?\n[ ${TEST_RIG_RESULT} -ne 0 ] && echo \"tcltest:0: error: tcltest exited abnormally with code ${TEST_RIG_RESULT}.\"\nexit ${TEST_RIG_RESULT}\nfi";
+			showEnvVarsInLog = 0;
+		};
+		F97AF02F0B665DA900310EA2 /* Build Tcl */ = {
+			isa = PBXShellScriptBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			inputPaths = (
+				"${TARGET_TEMP_DIR}/.none",
+			);
+			name = "Build Tcl";
+			outputPaths = (
+				"${TARGET_BUILD_DIR}/${EXECUTABLE_NAME}",
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+			shellPath = /bin/bash;
+			shellScript = "if [ -e \"${TARGET_BUILD_DIR}/tclsh\" ]; then\n    mv -f \"${TARGET_BUILD_DIR}/tclsh\" \"${TARGET_BUILD_DIR}/tclsh${VERSION}\"\nfi\nexport CC=$(xcrun -find ${GCC} || echo ${GCC}); export LD=${CC}\ngnumake -C \"${TCL_SRCROOT}/macosx\" -j \"$(sysctl -n hw.activecpu)\" \"$(echo \"${ACTION}\" | sed -e s/build// -e s/clean/distclean/ -e s/..\\*/\\&-/)${MAKE_TARGET}\" CFLAGS_WARNING=\"${WARNING_CFLAGS}\" CFLAGS_OPTIMIZE=\"-O${GCC_OPTIMIZATION_LEVEL}\" SYMROOT=\"${BUILT_PRODUCTS_DIR}\" OBJ_DIR=\"${OBJECT_FILE_DIR}\" INSTALL_ROOT=\"${DSTROOT}\" PREFIX=\"${PREFIX}\" BINDIR=\"${BINDIR}\" LIBDIR=\"${FRAMEWORK_INSTALL_PATH}\" MANDIR=\"${MANDIR}\" EXTRA_CONFIGURE_ARGS=\"${CONFIGURE_ARGS}\" ${EXTRA_MAKE_FLAGS}\nresult=$?\nif [ -e \"${TARGET_BUILD_DIR}/tclsh${VERSION}\" ]; then\n    mv -f \"${TARGET_BUILD_DIR}/tclsh${VERSION}\" \"${TARGET_BUILD_DIR}/tclsh\"\nfi\nif [ -e \"${BUILT_PRODUCTS_DIR}/tcltest\" ]; then\n\trm -f \"${BUILT_PRODUCTS_DIR}/tcltest\"\nfi\necho \"Done\"\nrm -f \"${SCRIPT_INPUT_FILE_0}\"\nexit ${result}\n";
+			showEnvVarsInLog = 0;
+		};
+		F9A5C5F508F651A2008AE941 /* Configure Tcl */ = {
+			isa = PBXShellScriptBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			inputPaths = (
+				"$(TCL_SRCROOT)/macosx/configure.ac",
+				"$(TCL_SRCROOT)/unix/configure.in",
+				"$(TCL_SRCROOT)/unix/tcl.m4",
+				"$(TCL_SRCROOT)/unix/aclocal.m4",
+				"$(TCL_SRCROOT)/unix/tclConfig.sh.in",
+				"$(TCL_SRCROOT)/unix/Makefile.in",
+				"$(TCL_SRCROOT)/unix/dltest/Makefile.in",
+			);
+			name = "Configure Tcl";
+			outputPaths = (
+				"$(DERIVED_FILE_DIR)/tcl/tclConfig.sh",
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+			shellPath = /bin/bash;
+			shellScript = "## tcl configure shell script phase\n\ncd \"${TCL_SRCROOT}\"/macosx &&\nif [ configure.ac -nt configure -o ../unix/configure.in -nt configure -o ../unix/tcl.m4 -nt configure -o ../unix/aclocal.m4 -nt configure ]; then\n    echo \"Running autoconf & autoheader in tcl/macosx\"\n    rm -rf autom4te.cache\n    ${AUTOCONF:-${DEVELOPER_DIR}/usr/bin/autoconf} && ${AUTOHEADER:-${DEVELOPER_DIR}/usr/bin/autoheader} || exit $?\n    rm -rf autom4te.cache\nfi\n\ncd \"${DERIVED_FILE_DIR}\" && mkdir -p tcl && cd tcl &&\nif [ \"${TCL_SRCROOT}\"/macosx/configure -nt config.status ]; then\n    echo \"Configuring Tcl\"\n    CC=$(xcrun -find ${GCC} || echo ${GCC})\n    \"${TCL_SRCROOT}\"/macosx/configure --cache-file=../config.cache --prefix=${PREFIX} --bindir=${BINDIR} --libdir=${LIBDIR} --mandir=${MANDIR} --includedir=${INCLUDEDIR} --disable-shared CC=${CC} LD=${CC} ${CONFIGURE_ARGS}\nelse\n    ./config.status\nfi\n";
+			showEnvVarsInLog = 0;
+		};
+/* End PBXShellScriptBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+		8DD76FAB0486AB0100D96B5E /* Sources */ = {
+			isa = PBXSourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+				F96D456F08F272BB004A47F5 /* regcomp.c in Sources */,
+				F96D457208F272BB004A47F5 /* regerror.c in Sources */,
+				F96D457508F272BB004A47F5 /* regexec.c in Sources */,
+				F96D457608F272BB004A47F5 /* regfree.c in Sources */,
+				F96D457B08F272BB004A47F5 /* tclAlloc.c in Sources */,
+				F96D457C08F272BB004A47F5 /* tclAsync.c in Sources */,
+				F96D457D08F272BB004A47F5 /* tclBasic.c in Sources */,
+				F96D457E08F272BC004A47F5 /* tclBinary.c in Sources */,
+				F96D457F08F272BC004A47F5 /* tclCkalloc.c in Sources */,
+				F96D458008F272BC004A47F5 /* tclClock.c in Sources */,
+				F96D458108F272BC004A47F5 /* tclCmdAH.c in Sources */,
+				F96D458208F272BC004A47F5 /* tclCmdIL.c in Sources */,
+				F96D458308F272BC004A47F5 /* tclCmdMZ.c in Sources */,
+				F96D458408F272BC004A47F5 /* tclCompCmds.c in Sources */,
+				F96D458508F272BC004A47F5 /* tclCompExpr.c in Sources */,
+				F96D458608F272BC004A47F5 /* tclCompile.c in Sources */,
+				F96D458808F272BC004A47F5 /* tclConfig.c in Sources */,
+				F96D458908F272BC004A47F5 /* tclDate.c in Sources */,
+				F96D458B08F272BC004A47F5 /* tclDictObj.c in Sources */,
+				F96D458C08F272BC004A47F5 /* tclEncoding.c in Sources */,
+				F96D458D08F272BC004A47F5 /* tclEnv.c in Sources */,
+				F96D458E08F272BC004A47F5 /* tclEvent.c in Sources */,
+				F96D458F08F272BC004A47F5 /* tclExecute.c in Sources */,
+				F96D459008F272BC004A47F5 /* tclFCmd.c in Sources */,
+				F96D459108F272BC004A47F5 /* tclFileName.c in Sources */,
+				F96D459308F272BC004A47F5 /* tclGet.c in Sources */,
+				F96D459508F272BC004A47F5 /* tclHash.c in Sources */,
+				F96D459608F272BC004A47F5 /* tclHistory.c in Sources */,
+				F96D459708F272BC004A47F5 /* tclIndexObj.c in Sources */,
+				F96D459B08F272BC004A47F5 /* tclInterp.c in Sources */,
+				F96D459D08F272BC004A47F5 /* tclIO.c in Sources */,
+				F96D459F08F272BC004A47F5 /* tclIOCmd.c in Sources */,
+				F96D45A008F272BC004A47F5 /* tclIOGT.c in Sources */,
+				F96D45A108F272BC004A47F5 /* tclIORChan.c in Sources */,
+				F95D77EA0DFD820D00A8BF6F /* tclIORTrans.c in Sources */,
+				F96D45A208F272BC004A47F5 /* tclIOSock.c in Sources */,
+				F96D45A308F272BC004A47F5 /* tclIOUtil.c in Sources */,
+				F96D45A408F272BC004A47F5 /* tclLink.c in Sources */,
+				F96D45A508F272BC004A47F5 /* tclListObj.c in Sources */,
+				F96D45A608F272BC004A47F5 /* tclLiteral.c in Sources */,
+				F96D45A708F272BC004A47F5 /* tclLoad.c in Sources */,
+				F96D45A908F272BC004A47F5 /* tclMain.c in Sources */,
+				F96D45AA08F272BC004A47F5 /* tclNamesp.c in Sources */,
+				F96D45AB08F272BC004A47F5 /* tclNotify.c in Sources */,
+				F96D45AC08F272BC004A47F5 /* tclObj.c in Sources */,
+				F93599B30DF1F75400E04F67 /* tclOO.c in Sources */,
+				F93599B70DF1F76100E04F67 /* tclOOBasic.c in Sources */,
+				F93599B90DF1F76600E04F67 /* tclOOCall.c in Sources */,
+				F93599BC0DF1F77000E04F67 /* tclOODefineCmds.c in Sources */,
+				F93599BE0DF1F77400E04F67 /* tclOOInfo.c in Sources */,
+				F93599C20DF1F78300E04F67 /* tclOOMethod.c in Sources */,
+				F93599C40DF1F78800E04F67 /* tclOOStubInit.c in Sources */,
+				F93599C60DF1F78D00E04F67 /* tclOOStubLib.c in Sources */,
+				F96D45AD08F272BC004A47F5 /* tclPanic.c in Sources */,
+				F96D45AE08F272BC004A47F5 /* tclParse.c in Sources */,
+				F96D45B008F272BC004A47F5 /* tclPathObj.c in Sources */,
+				F96D45B108F272BC004A47F5 /* tclPipe.c in Sources */,
+				F96D45B208F272BC004A47F5 /* tclPkg.c in Sources */,
+				F96D45B308F272BC004A47F5 /* tclPkgConfig.c in Sources */,
+				F96D45B608F272BC004A47F5 /* tclPosixStr.c in Sources */,
+				F96D45B708F272BC004A47F5 /* tclPreserve.c in Sources */,
+				F96D45B808F272BC004A47F5 /* tclProc.c in Sources */,
+				F96D45B908F272BC004A47F5 /* tclRegexp.c in Sources */,
+				F96D45BB08F272BC004A47F5 /* tclResolve.c in Sources */,
+				F96D45BC08F272BC004A47F5 /* tclResult.c in Sources */,
+				F96D45BD08F272BC004A47F5 /* tclScan.c in Sources */,
+				F96D45BE08F272BC004A47F5 /* tclStringObj.c in Sources */,
+				F96D45C308F272BC004A47F5 /* tclStrToD.c in Sources */,
+				F96D45C408F272BC004A47F5 /* tclStubInit.c in Sources */,
+				F96D45C508F272BC004A47F5 /* tclStubLib.c in Sources */,
+				F96D45C608F272BC004A47F5 /* tclTest.c in Sources */,
+				F96D45C708F272BC004A47F5 /* tclTestObj.c in Sources */,
+				F96D45C808F272BC004A47F5 /* tclTestProcBodyObj.c in Sources */,
+				F96D45C908F272BC004A47F5 /* tclThread.c in Sources */,
+				F96D45CA08F272BC004A47F5 /* tclThreadAlloc.c in Sources */,
+				F96D45CB08F272BC004A47F5 /* tclThreadJoin.c in Sources */,
+				F96D45CC08F272BC004A47F5 /* tclThreadStorage.c in Sources */,
+				F96D45CD08F272BC004A47F5 /* tclThreadTest.c in Sources */,
+				F96D45CE08F272BC004A47F5 /* tclTimer.c in Sources */,
+				F96D45D008F272BC004A47F5 /* tclTomMathInterface.c in Sources */,
+				F96D45D108F272BC004A47F5 /* tclTrace.c in Sources */,
+				F96D45D308F272BC004A47F5 /* tclUtf.c in Sources */,
+				F96D45D408F272BC004A47F5 /* tclUtil.c in Sources */,
+				F96D45D508F272BC004A47F5 /* tclVar.c in Sources */,
+				F96437CA0EF0D4B2003F468E /* tclZlib.c in Sources */,
+				F96D48E208F272C3004A47F5 /* bn_fast_s_mp_mul_digs.c in Sources */,
+				F96D48E408F272C3004A47F5 /* bn_fast_s_mp_sqr.c in Sources */,
+				F96D48E708F272C3004A47F5 /* bn_mp_add.c in Sources */,
+				F96D48E808F272C3004A47F5 /* bn_mp_add_d.c in Sources */,
+				F9E61D2B090A48A4002B3151 /* bn_mp_and.c in Sources */,
+				F96D48EB08F272C3004A47F5 /* bn_mp_clamp.c in Sources */,
+				F96D48EC08F272C3004A47F5 /* bn_mp_clear.c in Sources */,
+				F96D48ED08F272C3004A47F5 /* bn_mp_clear_multi.c in Sources */,
+				F96D48EE08F272C3004A47F5 /* bn_mp_cmp.c in Sources */,
+				F9E61D28090A481F002B3151 /* bn_mp_cmp_d.c in Sources */,
+				F96D48F008F272C3004A47F5 /* bn_mp_cmp_mag.c in Sources */,
+				F96D48F208F272C3004A47F5 /* bn_mp_cnt_lsb.c in Sources */,
+				F96D48F208F272C3004A47F5 /* bn_mp_copy.c in Sources */,
+				F96D48F308F272C3004A47F5 /* bn_mp_count_bits.c in Sources */,
+				F96D48F408F272C3004A47F5 /* bn_mp_div.c in Sources */,
+				F96D48F508F272C3004A47F5 /* bn_mp_div_2.c in Sources */,
+				F96D48F608F272C3004A47F5 /* bn_mp_div_2d.c in Sources */,
+				F96D48F708F272C3004A47F5 /* bn_mp_div_3.c in Sources */,
+				F96D48F808F272C3004A47F5 /* bn_mp_div_d.c in Sources */,
+				F96D48FC08F272C3004A47F5 /* bn_mp_exch.c in Sources */,
+				F9E61D2C090A48AC002B3151 /* bn_mp_expt_d.c in Sources */,
+				F96D490508F272C3004A47F5 /* bn_mp_grow.c in Sources */,
+				F96D490608F272C3004A47F5 /* bn_mp_init.c in Sources */,
+				F96D490708F272C3004A47F5 /* bn_mp_init_copy.c in Sources */,
+				F96D490808F272C3004A47F5 /* bn_mp_init_multi.c in Sources */,
+				F96D490908F272C3004A47F5 /* bn_mp_init_set.c in Sources */,
+				F96D490B08F272C3004A47F5 /* bn_mp_init_size.c in Sources */,
+				F96D491008F272C3004A47F5 /* bn_mp_karatsuba_mul.c in Sources */,
+				F96D491108F272C3004A47F5 /* bn_mp_karatsuba_sqr.c in Sources */,
+				F96D491308F272C3004A47F5 /* bn_mp_lshd.c in Sources */,
+				F96D491408F272C3004A47F5 /* bn_mp_mod.c in Sources */,
+				F96D491508F272C3004A47F5 /* bn_mp_mod_2d.c in Sources */,
+				F96D491A08F272C3004A47F5 /* bn_mp_mul.c in Sources */,
+				F96D491B08F272C3004A47F5 /* bn_mp_mul_2.c in Sources */,
+				F96D491C08F272C3004A47F5 /* bn_mp_mul_2d.c in Sources */,
+				F96D491D08F272C3004A47F5 /* bn_mp_mul_d.c in Sources */,
+				F9E61D29090A486C002B3151 /* bn_mp_neg.c in Sources */,
+				F9E61D2E090A48BF002B3151 /* bn_mp_or.c in Sources */,
+				F96D492908F272C3004A47F5 /* bn_mp_radix_size.c in Sources */,
+				F96D492A08F272C3004A47F5 /* bn_mp_radix_smap.c in Sources */,
+				F96D492C08F272C3004A47F5 /* bn_mp_read_radix.c in Sources */,
+				F96D493708F272C3004A47F5 /* bn_mp_rshd.c in Sources */,
+				F96D493808F272C3004A47F5 /* bn_mp_set.c in Sources */,
+				F9E61D2F090A48C7002B3151 /* bn_mp_shrink.c in Sources */,
+				F96D493C08F272C3004A47F5 /* bn_mp_sqr.c in Sources */,
+				F9E61D2A090A4891002B3151 /* bn_mp_sqrt.c in Sources */,
+				F96D493F08F272C3004A47F5 /* bn_mp_sub.c in Sources */,
+				F96D494008F272C3004A47F5 /* bn_mp_sub_d.c in Sources */,
+				F9E61D30090A48E2002B3151 /* bn_mp_to_unsigned_bin_n.c in Sources */,
+				F9E61D31090A48F9002B3151 /* bn_mp_to_unsigned_bin.c in Sources */,
+				F96D494608F272C3004A47F5 /* bn_mp_toom_mul.c in Sources */,
+				F96D494708F272C3004A47F5 /* bn_mp_toom_sqr.c in Sources */,
+				F96D494908F272C3004A47F5 /* bn_mp_toradix_n.c in Sources */,
+				F9E61D32090A48FA002B3151 /* bn_mp_unsigned_bin_size.c in Sources */,
+				F9E61D2D090A48BB002B3151 /* bn_mp_xor.c in Sources */,
+				F96D494C08F272C3004A47F5 /* bn_mp_zero.c in Sources */,
+				F96D494E08F272C3004A47F5 /* bn_reverse.c in Sources */,
+				F96D494F08F272C3004A47F5 /* bn_s_mp_add.c in Sources */,
+				F96D495108F272C3004A47F5 /* bn_s_mp_mul_digs.c in Sources */,
+				F96D495308F272C3004A47F5 /* bn_s_mp_sqr.c in Sources */,
+				F96D495408F272C3004A47F5 /* bn_s_mp_sub.c in Sources */,
+				F96D495508F272C3004A47F5 /* bncore.c in Sources */,
+				F96D49A908F272C4004A47F5 /* tclMacOSXBundle.c in Sources */,
+				F96D49AD08F272C4004A47F5 /* tclMacOSXFCmd.c in Sources */,
+				F96D49AE08F272C4004A47F5 /* tclMacOSXNotify.c in Sources */,
+				F90509300913A72400327603 /* tclAppInit.c in Sources */,
+				F96D4AC608F272C9004A47F5 /* tclLoadDyld.c in Sources */,
+				F96D4ACA08F272C9004A47F5 /* tclUnixChan.c in Sources */,
+				F9FC77B80AB29E9100B7077D /* tclUnixCompat.c in Sources */,
+				F96D4ACB08F272C9004A47F5 /* tclUnixEvent.c in Sources */,
+				F96D4ACC08F272C9004A47F5 /* tclUnixFCmd.c in Sources */,
+				F96D4ACD08F272C9004A47F5 /* tclUnixFile.c in Sources */,
+				F96D4ACE08F272C9004A47F5 /* tclUnixInit.c in Sources */,
+				F96D4ACF08F272C9004A47F5 /* tclUnixNotfy.c in Sources */,
+				F96D4AD008F272C9004A47F5 /* tclUnixPipe.c in Sources */,
+				F96D4AD208F272CA004A47F5 /* tclUnixSock.c in Sources */,
+				F96D4AD308F272CA004A47F5 /* tclUnixTest.c in Sources */,
+				F96D4AD408F272CA004A47F5 /* tclUnixThrd.c in Sources */,
+				F96D4AD608F272CA004A47F5 /* tclUnixTime.c in Sources */,
+				F9F4415E0C8BAE6F00BCCD67 /* tclDTrace.d in Sources */,
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXSourcesBuildPhase section */
+
+/* Begin PBXTargetDependency section */
+		F97258D30A868C6F00096C78 /* PBXTargetDependency */ = {
+			isa = PBXTargetDependency;
+			target = 8DD76FA90486AB0100D96B5E /* tcltest */;
+			targetProxy = F97258D20A868C6F00096C78 /* PBXContainerItemProxy */;
+		};
+/* End PBXTargetDependency section */
+
+/* Begin XCBuildConfiguration section */
+		F91BCC4F093152310042A6BF /* ReleaseUniversal */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				PRODUCT_NAME = tclsh;
+				SKIP_INSTALL = NO;
+			};
+			name = ReleaseUniversal;
+		};
+		F91BCC50093152310042A6BF /* ReleaseUniversal */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				PRODUCT_NAME = tcltest;
+			};
+			name = ReleaseUniversal;
+		};
+		F91BCC51093152310042A6BF /* ReleaseUniversal */ = {
+			isa = XCBuildConfiguration;
+			baseConfigurationReference = F97AE82B0B65C69B00310EA2 /* Tcl-Release.xcconfig */;
+			buildSettings = {
+				ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
+				CFLAGS = "-arch i386 -arch x86_64 -arch ppc $(CFLAGS)";
+				MACOSX_DEPLOYMENT_TARGET = 10.6;
+				PREBINDING = NO;
+			};
+			name = ReleaseUniversal;
+		};
+		F93084370BB93D2800CD0B9E /* DebugMemCompile */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				PRODUCT_NAME = tclsh;
+				SKIP_INSTALL = NO;
+			};
+			name = DebugMemCompile;
+		};
+		F93084380BB93D2800CD0B9E /* DebugMemCompile */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				PRODUCT_NAME = tcltest;
+			};
+			name = DebugMemCompile;
+		};
+		F93084390BB93D2800CD0B9E /* DebugMemCompile */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				CODE_SIGN_IDENTITY = "";
+				PRODUCT_NAME = tests;
+				TCLTEST_OPTIONS = "";
+				TCL_LIBRARY = "$(TCL_SRCROOT)/library";
+				TEST_RIG = "$(OBJROOT)/$(CONFIGURATION)/tcltest";
+			};
+			name = DebugMemCompile;
+		};
+		F930843A0BB93D2800CD0B9E /* DebugMemCompile */ = {
+			isa = XCBuildConfiguration;
+			baseConfigurationReference = F97AE8330B65C87F00310EA2 /* Tcl-Debug.xcconfig */;
+			buildSettings = {
+				ARCHS = (
+					"$(NATIVE_ARCH_64_BIT)",
+					"$(NATIVE_ARCH_32_BIT)",
+				);
+				CONFIGURE_ARGS = "$(CONFIGURE_ARGS) --enable-symbols=all";
+				CPPFLAGS = "-arch $(CURRENT_ARCH) $(CPPFLAGS)";
+				MACOSX_DEPLOYMENT_TARGET = 10.6;
+				ONLY_ACTIVE_ARCH = YES;
+				PREBINDING = NO;
+			};
+			name = DebugMemCompile;
+		};
+		F9359B250DF212DA00E04F67 /* DebugGCov */ = {
+			isa = XCBuildConfiguration;
+			baseConfigurationReference = F97AE8330B65C87F00310EA2 /* Tcl-Debug.xcconfig */;
+			buildSettings = {
+				ARCHS = (
+					"$(NATIVE_ARCH_64_BIT)",
+					"$(NATIVE_ARCH_32_BIT)",
+				);
+				CPPFLAGS = "-arch $(CURRENT_ARCH) $(CPPFLAGS)";
+				GCC_GENERATE_TEST_COVERAGE_FILES = YES;
+				GCC_INSTRUMENT_PROGRAM_FLOW_ARCS = YES;
+				MACOSX_DEPLOYMENT_TARGET = 10.6;
+				ONLY_ACTIVE_ARCH = YES;
+				OTHER_LDFLAGS = (
+					"$(OTHER_LDFLAGS)",
+					"-lgcov",
+				);
+				PREBINDING = NO;
+			};
+			name = DebugGCov;
+		};
+		F9359B260DF212DA00E04F67 /* DebugGCov */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				PRODUCT_NAME = tclsh;
+				SKIP_INSTALL = NO;
+			};
+			name = DebugGCov;
+		};
+		F9359B270DF212DA00E04F67 /* DebugGCov */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				PRODUCT_NAME = tcltest;
+			};
+			name = DebugGCov;
+		};
+		F9359B280DF212DA00E04F67 /* DebugGCov */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				CODE_SIGN_IDENTITY = "";
+				PRODUCT_NAME = tests;
+				TCLTEST_OPTIONS = "";
+				TCL_LIBRARY = "$(TCL_SRCROOT)/library";
+				TEST_RIG = "$(OBJROOT)/$(CONFIGURATION)/tcltest";
+			};
+			name = DebugGCov;
+		};
+		F95CC8AC09158F3100EA5ACE /* Debug */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				PRODUCT_NAME = tclsh;
+				SKIP_INSTALL = NO;
+			};
+			name = Debug;
+		};
+		F95CC8AD09158F3100EA5ACE /* Release */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				PRODUCT_NAME = tclsh;
+				SKIP_INSTALL = NO;
+			};
+			name = Release;
+		};
+		F95CC8AE09158F3100EA5ACE /* DebugNoFixAndContinue */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				PRODUCT_NAME = tclsh;
+				SKIP_INSTALL = NO;
+			};
+			name = DebugNoFixAndContinue;
+		};
+		F95CC8B109158F3100EA5ACE /* Debug */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				CONFIGURE_ARGS = "tcl_cv_cc_visibility_hidden=no $(CONFIGURE_ARGS)";
+				GCC_DYNAMIC_NO_PIC = NO;
+				GCC_ENABLE_FIX_AND_CONTINUE = YES;
+				GCC_PREPROCESSOR_DEFINITIONS = (
+					"__private_extern__=extern",
+					"$(GCC_PREPROCESSOR_DEFINITIONS)",
+				);
+				GCC_SYMBOLS_PRIVATE_EXTERN = NO;
+				PRODUCT_NAME = tcltest;
+			};
+			name = Debug;
+		};
+		F95CC8B209158F3100EA5ACE /* Release */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				PRODUCT_NAME = tcltest;
+			};
+			name = Release;
+		};
+		F95CC8B309158F3100EA5ACE /* DebugNoFixAndContinue */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				PRODUCT_NAME = tcltest;
+			};
+			name = DebugNoFixAndContinue;
+		};
+		F95CC8B609158F3100EA5ACE /* Debug */ = {
+			isa = XCBuildConfiguration;
+			baseConfigurationReference = F97AE8330B65C87F00310EA2 /* Tcl-Debug.xcconfig */;
+			buildSettings = {
+				ARCHS = (
+					"$(NATIVE_ARCH_64_BIT)",
+					"$(NATIVE_ARCH_32_BIT)",
+				);
+				CPPFLAGS = "-arch $(CURRENT_ARCH) $(CPPFLAGS)";
+				MACOSX_DEPLOYMENT_TARGET = 10.6;
+				ONLY_ACTIVE_ARCH = YES;
+				PREBINDING = NO;
+			};
+			name = Debug;
+		};
+		F95CC8B709158F3100EA5ACE /* Release */ = {
+			isa = XCBuildConfiguration;
+			baseConfigurationReference = F97AE82B0B65C69B00310EA2 /* Tcl-Release.xcconfig */;
+			buildSettings = {
+				ARCHS = (
+					"$(NATIVE_ARCH_64_BIT)",
+					"$(NATIVE_ARCH_32_BIT)",
+				);
+				CPPFLAGS = "-arch $(CURRENT_ARCH) $(CPPFLAGS)";
+				MACOSX_DEPLOYMENT_TARGET = 10.6;
+				ONLY_ACTIVE_ARCH = YES;
+				PREBINDING = NO;
+			};
+			name = Release;
+		};
+		F95CC8B809158F3100EA5ACE /* DebugNoFixAndContinue */ = {
+			isa = XCBuildConfiguration;
+			baseConfigurationReference = F97AE8330B65C87F00310EA2 /* Tcl-Debug.xcconfig */;
+			buildSettings = {
+				ARCHS = (
+					"$(NATIVE_ARCH_64_BIT)",
+					"$(NATIVE_ARCH_32_BIT)",
+				);
+				CPPFLAGS = "-arch $(CURRENT_ARCH) $(CPPFLAGS)";
+				MACOSX_DEPLOYMENT_TARGET = 10.6;
+				ONLY_ACTIVE_ARCH = YES;
+				PREBINDING = NO;
+			};
+			name = DebugNoFixAndContinue;
+		};
+		F97258A90A86873D00096C78 /* Debug */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				CODE_SIGN_IDENTITY = "";
+				PRODUCT_NAME = tests;
+				TCLTEST_OPTIONS = "";
+				TCL_LIBRARY = "$(TCL_SRCROOT)/library";
+				TEST_RIG = "$(OBJROOT)/$(CONFIGURATION)/tcltest";
+			};
+			name = Debug;
+		};
+		F97258AA0A86873D00096C78 /* Release */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				CODE_SIGN_IDENTITY = "";
+				PRODUCT_NAME = tests;
+				TCLTEST_OPTIONS = "";
+				TCL_LIBRARY = "$(TCL_SRCROOT)/library";
+				TEST_RIG = "$(OBJROOT)/$(CONFIGURATION)/tcltest";
+			};
+			name = Release;
+		};
+		F97258AB0A86873D00096C78 /* DebugNoFixAndContinue */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				CODE_SIGN_IDENTITY = "";
+				PRODUCT_NAME = tests;
+				TCLTEST_OPTIONS = "";
+				TCL_LIBRARY = "$(TCL_SRCROOT)/library";
+				TEST_RIG = "$(OBJROOT)/$(CONFIGURATION)/tcltest";
+			};
+			name = DebugNoFixAndContinue;
+		};
+		F97258AC0A86873D00096C78 /* ReleaseUniversal */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				CODE_SIGN_IDENTITY = "";
+				PRODUCT_NAME = tests;
+				TCLTEST_OPTIONS = "";
+				TCL_LIBRARY = "$(TCL_SRCROOT)/library";
+				TEST_RIG = "$(OBJROOT)/$(CONFIGURATION)/tcltest";
+			};
+			name = ReleaseUniversal;
+		};
+		F97AED1B0B660B2100310EA2 /* Debug64bit */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				PRODUCT_NAME = tclsh;
+				SKIP_INSTALL = NO;
+			};
+			name = Debug64bit;
+		};
+		F97AED1C0B660B2100310EA2 /* Debug64bit */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				PRODUCT_NAME = tcltest;
+			};
+			name = Debug64bit;
+		};
+		F97AED1D0B660B2100310EA2 /* Debug64bit */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				CODE_SIGN_IDENTITY = "";
+				PRODUCT_NAME = tests;
+				TCLTEST_OPTIONS = "";
+				TCL_LIBRARY = "$(TCL_SRCROOT)/library";
+				TEST_RIG = "$(OBJROOT)/$(CONFIGURATION)/tcltest";
+			};
+			name = Debug64bit;
+		};
+		F97AED1E0B660B2100310EA2 /* Debug64bit */ = {
+			isa = XCBuildConfiguration;
+			baseConfigurationReference = F97AE8330B65C87F00310EA2 /* Tcl-Debug.xcconfig */;
+			buildSettings = {
+				ARCHS = "$(NATIVE_ARCH_64_BIT)";
+				CONFIGURE_ARGS = "--enable-64bit $(CONFIGURE_ARGS)";
+				CPPFLAGS = "-arch $(NATIVE_ARCH_64_BIT) $(CPPFLAGS)";
+				MACOSX_DEPLOYMENT_TARGET = 10.6;
+				PREBINDING = NO;
+			};
+			name = Debug64bit;
+		};
+		F987512F0DE7B57E00B1C9EC /* DebugNoCF */ = {
+			isa = XCBuildConfiguration;
+			baseConfigurationReference = F97AE8330B65C87F00310EA2 /* Tcl-Debug.xcconfig */;
+			buildSettings = {
+				ARCHS = (
+					"$(NATIVE_ARCH_64_BIT)",
+					"$(NATIVE_ARCH_32_BIT)",
+				);
+				CONFIGURE_ARGS = "$(CONFIGURE_ARGS) --disable-corefoundation";
+				CPPFLAGS = "-arch $(CURRENT_ARCH) $(CPPFLAGS)";
+				MACOSX_DEPLOYMENT_TARGET = 10.6;
+				ONLY_ACTIVE_ARCH = YES;
+				PREBINDING = NO;
+			};
+			name = DebugNoCF;
+		};
+		F98751300DE7B57E00B1C9EC /* DebugNoCF */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				PRODUCT_NAME = tclsh;
+				SKIP_INSTALL = NO;
+			};
+			name = DebugNoCF;
+		};
+		F98751310DE7B57E00B1C9EC /* DebugNoCF */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				PRODUCT_NAME = tcltest;
+			};
+			name = DebugNoCF;
+		};
+		F98751320DE7B57E00B1C9EC /* DebugNoCF */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				CODE_SIGN_IDENTITY = "";
+				PRODUCT_NAME = tests;
+				TCLTEST_OPTIONS = "";
+				TCL_LIBRARY = "$(TCL_SRCROOT)/library";
+				TEST_RIG = "$(OBJROOT)/$(CONFIGURATION)/tcltest";
+			};
+			name = DebugNoCF;
+		};
+		F98751330DE7B5A200B1C9EC /* DebugNoCFUnthreaded */ = {
+			isa = XCBuildConfiguration;
+			baseConfigurationReference = F97AE8330B65C87F00310EA2 /* Tcl-Debug.xcconfig */;
+			buildSettings = {
+				ARCHS = (
+					"$(NATIVE_ARCH_64_BIT)",
+					"$(NATIVE_ARCH_32_BIT)",
+				);
+				CONFIGURE_ARGS = "$(CONFIGURE_ARGS) --disable-threads --disable-corefoundation";
+				CPPFLAGS = "-arch $(CURRENT_ARCH) $(CPPFLAGS)";
+				MACOSX_DEPLOYMENT_TARGET = 10.6;
+				ONLY_ACTIVE_ARCH = YES;
+				PREBINDING = NO;
+			};
+			name = DebugNoCFUnthreaded;
+		};
+		F98751340DE7B5A200B1C9EC /* DebugNoCFUnthreaded */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				PRODUCT_NAME = tclsh;
+				SKIP_INSTALL = NO;
+			};
+			name = DebugNoCFUnthreaded;
+		};
+		F98751350DE7B5A200B1C9EC /* DebugNoCFUnthreaded */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				PRODUCT_NAME = tcltest;
+			};
+			name = DebugNoCFUnthreaded;
+		};
+		F98751360DE7B5A200B1C9EC /* DebugNoCFUnthreaded */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				CODE_SIGN_IDENTITY = "";
+				PRODUCT_NAME = tests;
+				TCLTEST_OPTIONS = "";
+				TCL_LIBRARY = "$(TCL_SRCROOT)/library";
+				TEST_RIG = "$(OBJROOT)/$(CONFIGURATION)/tcltest";
+			};
+			name = DebugNoCFUnthreaded;
+		};
+		F9988AB10D814C6500B6B03B /* Debug gcc40 */ = {
+			isa = XCBuildConfiguration;
+			baseConfigurationReference = F97AE8330B65C87F00310EA2 /* Tcl-Debug.xcconfig */;
+			buildSettings = {
+				ARCHS = (
+					"$(NATIVE_ARCH_64_BIT)",
+					"$(NATIVE_ARCH_32_BIT)",
+				);
+				CPPFLAGS = "-arch $(CURRENT_ARCH) $(CPPFLAGS)";
+				GCC_VERSION = 4.0;
+				MACOSX_DEPLOYMENT_TARGET = 10.6;
+				ONLY_ACTIVE_ARCH = YES;
+				PREBINDING = NO;
+			};
+			name = "Debug gcc40";
+		};
+		F9988AB20D814C6500B6B03B /* Debug gcc40 */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				PRODUCT_NAME = tclsh;
+				SKIP_INSTALL = NO;
+			};
+			name = "Debug gcc40";
+		};
+		F9988AB30D814C6500B6B03B /* Debug gcc40 */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				CONFIGURE_ARGS = "tcl_cv_cc_visibility_hidden=no $(CONFIGURE_ARGS)";
+				GCC_DYNAMIC_NO_PIC = NO;
+				GCC_ENABLE_FIX_AND_CONTINUE = YES;
+				GCC_PREPROCESSOR_DEFINITIONS = (
+					"__private_extern__=extern",
+					"$(GCC_PREPROCESSOR_DEFINITIONS)",
+				);
+				GCC_SYMBOLS_PRIVATE_EXTERN = NO;
+				PRODUCT_NAME = tcltest;
+			};
+			name = "Debug gcc40";
+		};
+		F9988AB40D814C6500B6B03B /* Debug gcc40 */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				CODE_SIGN_IDENTITY = "";
+				PRODUCT_NAME = tests;
+				TCLTEST_OPTIONS = "";
+				TCL_LIBRARY = "$(TCL_SRCROOT)/library";
+				TEST_RIG = "$(OBJROOT)/$(CONFIGURATION)/tcltest";
+			};
+			name = "Debug gcc40";
+		};
+		F9988AB50D814C7500B6B03B /* Debug llvm-gcc */ = {
+			isa = XCBuildConfiguration;
+			baseConfigurationReference = F97AE8330B65C87F00310EA2 /* Tcl-Debug.xcconfig */;
+			buildSettings = {
+				ARCHS = (
+					"$(NATIVE_ARCH_64_BIT)",
+					"$(NATIVE_ARCH_32_BIT)",
+				);
+				CPPFLAGS = "-arch $(CURRENT_ARCH) $(CPPFLAGS)";
+				GCC = "llvm-gcc";
+				GCC_VERSION = com.apple.compilers.llvmgcc42;
+				MACOSX_DEPLOYMENT_TARGET = 10.6;
+				ONLY_ACTIVE_ARCH = YES;
+				PREBINDING = NO;
+			};
+			name = "Debug llvm-gcc";
+		};
+		F9988AB60D814C7500B6B03B /* Debug llvm-gcc */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				PRODUCT_NAME = tclsh;
+				SKIP_INSTALL = NO;
+			};
+			name = "Debug llvm-gcc";
+		};
+		F9988AB70D814C7500B6B03B /* Debug llvm-gcc */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				CONFIGURE_ARGS = "tcl_cv_cc_visibility_hidden=no $(CONFIGURE_ARGS)";
+				GCC_DYNAMIC_NO_PIC = NO;
+				GCC_ENABLE_FIX_AND_CONTINUE = YES;
+				GCC_PREPROCESSOR_DEFINITIONS = (
+					"__private_extern__=extern",
+					"$(GCC_PREPROCESSOR_DEFINITIONS)",
+				);
+				GCC_SYMBOLS_PRIVATE_EXTERN = NO;
+				PRODUCT_NAME = tcltest;
+			};
+			name = "Debug llvm-gcc";
+		};
+		F9988AB80D814C7500B6B03B /* Debug llvm-gcc */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				CODE_SIGN_IDENTITY = "";
+				PRODUCT_NAME = tests;
+				TCLTEST_OPTIONS = "";
+				TCL_LIBRARY = "$(TCL_SRCROOT)/library";
+				TEST_RIG = "$(OBJROOT)/$(CONFIGURATION)/tcltest";
+			};
+			name = "Debug llvm-gcc";
+		};
+		F9988BB10D81586D00B6B03B /* ReleaseUniversal gcc40 */ = {
+			isa = XCBuildConfiguration;
+			baseConfigurationReference = F97AE82B0B65C69B00310EA2 /* Tcl-Release.xcconfig */;
+			buildSettings = {
+				ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
+				CFLAGS = "-arch i386 -arch x86_64 -arch ppc $(CFLAGS)";
+				GCC_VERSION = 4.0;
+				MACOSX_DEPLOYMENT_TARGET = 10.6;
+				PREBINDING = NO;
+			};
+			name = "ReleaseUniversal gcc40";
+		};
+		F9988BB20D81586D00B6B03B /* ReleaseUniversal gcc40 */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				PRODUCT_NAME = tclsh;
+				SKIP_INSTALL = NO;
+			};
+			name = "ReleaseUniversal gcc40";
+		};
+		F9988BB30D81586D00B6B03B /* ReleaseUniversal gcc40 */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				PRODUCT_NAME = tcltest;
+			};
+			name = "ReleaseUniversal gcc40";
+		};
+		F9988BB40D81586D00B6B03B /* ReleaseUniversal gcc40 */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				CODE_SIGN_IDENTITY = "";
+				PRODUCT_NAME = tests;
+				TCLTEST_OPTIONS = "";
+				TCL_LIBRARY = "$(TCL_SRCROOT)/library";
+				TEST_RIG = "$(OBJROOT)/$(CONFIGURATION)/tcltest";
+			};
+			name = "ReleaseUniversal gcc40";
+		};
+		F9988BB50D81587400B6B03B /* ReleaseUniversal llvm-gcc */ = {
+			isa = XCBuildConfiguration;
+			baseConfigurationReference = F97AE82B0B65C69B00310EA2 /* Tcl-Release.xcconfig */;
+			buildSettings = {
+				ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
+				CFLAGS = "-arch i386 -arch x86_64 -arch ppc $(CFLAGS)";
+				DEBUG_INFORMATION_FORMAT = dwarf;
+				GCC = "llvm-gcc";
+				GCC_OPTIMIZATION_LEVEL = 4;
+				"GCC_OPTIMIZATION_LEVEL[arch=ppc]" = s;
+				GCC_VERSION = com.apple.compilers.llvmgcc42;
+				MACOSX_DEPLOYMENT_TARGET = 10.6;
+				PREBINDING = NO;
+			};
+			name = "ReleaseUniversal llvm-gcc";
+		};
+		F9988BB60D81587400B6B03B /* ReleaseUniversal llvm-gcc */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				PRODUCT_NAME = tclsh;
+				SKIP_INSTALL = NO;
+			};
+			name = "ReleaseUniversal llvm-gcc";
+		};
+		F9988BB70D81587400B6B03B /* ReleaseUniversal llvm-gcc */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				PRODUCT_NAME = tcltest;
+			};
+			name = "ReleaseUniversal llvm-gcc";
+		};
+		F9988BB80D81587400B6B03B /* ReleaseUniversal llvm-gcc */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				CODE_SIGN_IDENTITY = "";
+				PRODUCT_NAME = tests;
+				TCLTEST_OPTIONS = "";
+				TCL_LIBRARY = "$(TCL_SRCROOT)/library";
+				TEST_RIG = "$(OBJROOT)/$(CONFIGURATION)/tcltest";
+			};
+			name = "ReleaseUniversal llvm-gcc";
+		};
+		F99EE73B0BE835310060D4AF /* DebugUnthreaded */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				PRODUCT_NAME = tclsh;
+				SKIP_INSTALL = NO;
+			};
+			name = DebugUnthreaded;
+		};
+		F99EE73C0BE835310060D4AF /* DebugLeaks */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				PRODUCT_NAME = tclsh;
+				SKIP_INSTALL = NO;
+			};
+			name = DebugLeaks;
+		};
+		F99EE73D0BE835310060D4AF /* DebugUnthreaded */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				PRODUCT_NAME = tcltest;
+			};
+			name = DebugUnthreaded;
+		};
+		F99EE73E0BE835310060D4AF /* DebugLeaks */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				PRODUCT_NAME = tcltest;
+			};
+			name = DebugLeaks;
+		};
+		F99EE73F0BE835310060D4AF /* DebugUnthreaded */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				CODE_SIGN_IDENTITY = "";
+				PRODUCT_NAME = tests;
+				TCLTEST_OPTIONS = "";
+				TCL_LIBRARY = "$(TCL_SRCROOT)/library";
+				TEST_RIG = "$(OBJROOT)/$(CONFIGURATION)/tcltest";
+			};
+			name = DebugUnthreaded;
+		};
+		F99EE7400BE835310060D4AF /* DebugLeaks */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				CODE_SIGN_IDENTITY = "";
+				PRODUCT_NAME = tests;
+				TCLTEST_OPTIONS = "";
+				TCL_LIBRARY = "$(TCL_SRCROOT)/library";
+				TEST_RIG = "$(OBJROOT)/$(CONFIGURATION)/tcltest";
+			};
+			name = DebugLeaks;
+		};
+		F99EE7410BE835310060D4AF /* DebugUnthreaded */ = {
+			isa = XCBuildConfiguration;
+			baseConfigurationReference = F97AE8330B65C87F00310EA2 /* Tcl-Debug.xcconfig */;
+			buildSettings = {
+				ARCHS = (
+					"$(NATIVE_ARCH_64_BIT)",
+					"$(NATIVE_ARCH_32_BIT)",
+				);
+				CONFIGURE_ARGS = "$(CONFIGURE_ARGS) --disable-threads";
+				CPPFLAGS = "-arch $(CURRENT_ARCH) $(CPPFLAGS)";
+				MACOSX_DEPLOYMENT_TARGET = 10.6;
+				ONLY_ACTIVE_ARCH = YES;
+				PREBINDING = NO;
+			};
+			name = DebugUnthreaded;
+		};
+		F99EE7420BE835310060D4AF /* DebugLeaks */ = {
+			isa = XCBuildConfiguration;
+			baseConfigurationReference = F97AE8330B65C87F00310EA2 /* Tcl-Debug.xcconfig */;
+			buildSettings = {
+				ARCHS = (
+					"$(NATIVE_ARCH_64_BIT)",
+					"$(NATIVE_ARCH_32_BIT)",
+				);
+				CPPFLAGS = "-arch $(CURRENT_ARCH) $(CPPFLAGS)";
+				GCC_PREPROCESSOR_DEFINITIONS = (
+					PURIFY,
+					"$(GCC_PREPROCESSOR_DEFINITIONS)",
+				);
+				MACOSX_DEPLOYMENT_TARGET = 10.6;
+				ONLY_ACTIVE_ARCH = YES;
+				PREBINDING = NO;
+				RUN_CLANG_STATIC_ANALYZER = YES;
+			};
+			name = DebugLeaks;
+		};
+		F9A9D1EF0FC77787002A2BE3 /* Debug clang */ = {
+			isa = XCBuildConfiguration;
+			baseConfigurationReference = F97AE8330B65C87F00310EA2 /* Tcl-Debug.xcconfig */;
+			buildSettings = {
+				ARCHS = (
+					"$(NATIVE_ARCH_64_BIT)",
+					"$(NATIVE_ARCH_32_BIT)",
+				);
+				CPPFLAGS = "-arch $(CURRENT_ARCH) $(CPPFLAGS)";
+				GCC = clang;
+				GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+				MACOSX_DEPLOYMENT_TARGET = 10.6;
+				ONLY_ACTIVE_ARCH = YES;
+				PREBINDING = NO;
+			};
+			name = "Debug clang";
+		};
+		F9A9D1F00FC77787002A2BE3 /* Debug clang */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				PRODUCT_NAME = tclsh;
+				SKIP_INSTALL = NO;
+			};
+			name = "Debug clang";
+		};
+		F9A9D1F10FC77787002A2BE3 /* Debug clang */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				CONFIGURE_ARGS = "tcl_cv_cc_visibility_hidden=no $(CONFIGURE_ARGS)";
+				GCC_DYNAMIC_NO_PIC = NO;
+				GCC_ENABLE_FIX_AND_CONTINUE = YES;
+				GCC_PREPROCESSOR_DEFINITIONS = (
+					"__private_extern__=extern",
+					"$(GCC_PREPROCESSOR_DEFINITIONS)",
+				);
+				GCC_SYMBOLS_PRIVATE_EXTERN = NO;
+				PRODUCT_NAME = tcltest;
+			};
+			name = "Debug clang";
+		};
+		F9A9D1F20FC77787002A2BE3 /* Debug clang */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				CODE_SIGN_IDENTITY = "";
+				PRODUCT_NAME = tests;
+				TCLTEST_OPTIONS = "";
+				TCL_LIBRARY = "$(TCL_SRCROOT)/library";
+				TEST_RIG = "$(OBJROOT)/$(CONFIGURATION)/tcltest";
+			};
+			name = "Debug clang";
+		};
+		F9A9D1F30FC77799002A2BE3 /* ReleaseUniversal clang */ = {
+			isa = XCBuildConfiguration;
+			baseConfigurationReference = F97AE82B0B65C69B00310EA2 /* Tcl-Release.xcconfig */;
+			buildSettings = {
+				ARCHS = (
+					"$(NATIVE_ARCH_64_BIT)",
+					"$(NATIVE_ARCH_32_BIT)",
+				);
+				CFLAGS = "-arch i386 -arch x86_64 $(CFLAGS)";
+				DEBUG_INFORMATION_FORMAT = dwarf;
+				GCC = clang;
+				GCC_OPTIMIZATION_LEVEL = 4;
+				GCC_VERSION = com.apple.compilers.llvm.clang.1_0;
+				MACOSX_DEPLOYMENT_TARGET = 10.6;
+				PREBINDING = NO;
+			};
+			name = "ReleaseUniversal clang";
+		};
+		F9A9D1F40FC77799002A2BE3 /* ReleaseUniversal clang */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				PRODUCT_NAME = tclsh;
+				SKIP_INSTALL = NO;
+			};
+			name = "ReleaseUniversal clang";
+		};
+		F9A9D1F50FC77799002A2BE3 /* ReleaseUniversal clang */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				PRODUCT_NAME = tcltest;
+			};
+			name = "ReleaseUniversal clang";
+		};
+		F9A9D1F60FC77799002A2BE3 /* ReleaseUniversal clang */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				CODE_SIGN_IDENTITY = "";
+				PRODUCT_NAME = tests;
+				TCLTEST_OPTIONS = "";
+				TCL_LIBRARY = "$(TCL_SRCROOT)/library";
+				TEST_RIG = "$(OBJROOT)/$(CONFIGURATION)/tcltest";
+			};
+			name = "ReleaseUniversal clang";
+		};
+		F9EEED960C2FEFD300396116 /* ReleaseUniversal10.5SDK */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				PRODUCT_NAME = tclsh;
+				SKIP_INSTALL = NO;
+			};
+			name = ReleaseUniversal10.5SDK;
+		};
+		F9EEED970C2FEFD300396116 /* ReleaseUniversal10.5SDK */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				PRODUCT_NAME = tcltest;
+			};
+			name = ReleaseUniversal10.5SDK;
+		};
+		F9EEED980C2FEFD300396116 /* ReleaseUniversal10.5SDK */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				CODE_SIGN_IDENTITY = "";
+				PRODUCT_NAME = tests;
+				TCLTEST_OPTIONS = "";
+				TCL_LIBRARY = "$(TCL_SRCROOT)/library";
+				TEST_RIG = "$(OBJROOT)/$(CONFIGURATION)/tcltest";
+			};
+			name = ReleaseUniversal10.5SDK;
+		};
+		F9EEED990C2FEFD300396116 /* ReleaseUniversal10.5SDK */ = {
+			isa = XCBuildConfiguration;
+			baseConfigurationReference = F97AE82B0B65C69B00310EA2 /* Tcl-Release.xcconfig */;
+			buildSettings = {
+				ARCHS = "$(ARCHS_STANDARD_32_64_BIT)";
+				CFLAGS = "-arch i386 -arch x86_64 -arch ppc $(CFLAGS)";
+				CPPFLAGS = "-isysroot $(SDKROOT) $(CPPFLAGS)";
+				MACOSX_DEPLOYMENT_TARGET = 10.5;
+				PREBINDING = NO;
+				SDKROOT = macosx10.5;
+			};
+			name = ReleaseUniversal10.5SDK;
+		};
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+		F95CC8AB09158F3100EA5ACE /* Build configuration list for PBXNativeTarget "Tcl" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				F95CC8AC09158F3100EA5ACE /* Debug */,
+				F9A9D1F00FC77787002A2BE3 /* Debug clang */,
+				F9988AB60D814C7500B6B03B /* Debug llvm-gcc */,
+				F9988AB20D814C6500B6B03B /* Debug gcc40 */,
+				F95CC8AE09158F3100EA5ACE /* DebugNoFixAndContinue */,
+				F99EE73B0BE835310060D4AF /* DebugUnthreaded */,
+				F98751300DE7B57E00B1C9EC /* DebugNoCF */,
+				F98751340DE7B5A200B1C9EC /* DebugNoCFUnthreaded */,
+				F93084370BB93D2800CD0B9E /* DebugMemCompile */,
+				F99EE73C0BE835310060D4AF /* DebugLeaks */,
+				F9359B260DF212DA00E04F67 /* DebugGCov */,
+				F97AED1B0B660B2100310EA2 /* Debug64bit */,
+				F95CC8AD09158F3100EA5ACE /* Release */,
+				F91BCC4F093152310042A6BF /* ReleaseUniversal */,
+				F9A9D1F40FC77799002A2BE3 /* ReleaseUniversal clang */,
+				F9988BB60D81587400B6B03B /* ReleaseUniversal llvm-gcc */,
+				F9988BB20D81586D00B6B03B /* ReleaseUniversal gcc40 */,
+				F9EEED960C2FEFD300396116 /* ReleaseUniversal10.5SDK */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Debug;
+		};
+		F95CC8B009158F3100EA5ACE /* Build configuration list for PBXNativeTarget "tcltest" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				F95CC8B109158F3100EA5ACE /* Debug */,
+				F9A9D1F10FC77787002A2BE3 /* Debug clang */,
+				F9988AB70D814C7500B6B03B /* Debug llvm-gcc */,
+				F9988AB30D814C6500B6B03B /* Debug gcc40 */,
+				F95CC8B309158F3100EA5ACE /* DebugNoFixAndContinue */,
+				F99EE73D0BE835310060D4AF /* DebugUnthreaded */,
+				F98751310DE7B57E00B1C9EC /* DebugNoCF */,
+				F98751350DE7B5A200B1C9EC /* DebugNoCFUnthreaded */,
+				F93084380BB93D2800CD0B9E /* DebugMemCompile */,
+				F99EE73E0BE835310060D4AF /* DebugLeaks */,
+				F9359B270DF212DA00E04F67 /* DebugGCov */,
+				F97AED1C0B660B2100310EA2 /* Debug64bit */,
+				F95CC8B209158F3100EA5ACE /* Release */,
+				F91BCC50093152310042A6BF /* ReleaseUniversal */,
+				F9A9D1F50FC77799002A2BE3 /* ReleaseUniversal clang */,
+				F9988BB70D81587400B6B03B /* ReleaseUniversal llvm-gcc */,
+				F9988BB30D81586D00B6B03B /* ReleaseUniversal gcc40 */,
+				F9EEED970C2FEFD300396116 /* ReleaseUniversal10.5SDK */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Debug;
+		};
+		F95CC8B509158F3100EA5ACE /* Build configuration list for PBXProject "Tcl" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				F95CC8B609158F3100EA5ACE /* Debug */,
+				F9A9D1EF0FC77787002A2BE3 /* Debug clang */,
+				F9988AB50D814C7500B6B03B /* Debug llvm-gcc */,
+				F9988AB10D814C6500B6B03B /* Debug gcc40 */,
+				F95CC8B809158F3100EA5ACE /* DebugNoFixAndContinue */,
+				F99EE7410BE835310060D4AF /* DebugUnthreaded */,
+				F987512F0DE7B57E00B1C9EC /* DebugNoCF */,
+				F98751330DE7B5A200B1C9EC /* DebugNoCFUnthreaded */,
+				F930843A0BB93D2800CD0B9E /* DebugMemCompile */,
+				F99EE7420BE835310060D4AF /* DebugLeaks */,
+				F9359B250DF212DA00E04F67 /* DebugGCov */,
+				F97AED1E0B660B2100310EA2 /* Debug64bit */,
+				F95CC8B709158F3100EA5ACE /* Release */,
+				F91BCC51093152310042A6BF /* ReleaseUniversal */,
+				F9A9D1F30FC77799002A2BE3 /* ReleaseUniversal clang */,
+				F9988BB50D81587400B6B03B /* ReleaseUniversal llvm-gcc */,
+				F9988BB10D81586D00B6B03B /* ReleaseUniversal gcc40 */,
+				F9EEED990C2FEFD300396116 /* ReleaseUniversal10.5SDK */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Debug;
+		};
+		F97258A80A86873D00096C78 /* Build configuration list for PBXNativeTarget "tests" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				F97258A90A86873D00096C78 /* Debug */,
+				F9A9D1F20FC77787002A2BE3 /* Debug clang */,
+				F9988AB80D814C7500B6B03B /* Debug llvm-gcc */,
+				F9988AB40D814C6500B6B03B /* Debug gcc40 */,
+				F97258AB0A86873D00096C78 /* DebugNoFixAndContinue */,
+				F99EE73F0BE835310060D4AF /* DebugUnthreaded */,
+				F98751320DE7B57E00B1C9EC /* DebugNoCF */,
+				F98751360DE7B5A200B1C9EC /* DebugNoCFUnthreaded */,
+				F93084390BB93D2800CD0B9E /* DebugMemCompile */,
+				F99EE7400BE835310060D4AF /* DebugLeaks */,
+				F9359B280DF212DA00E04F67 /* DebugGCov */,
+				F97AED1D0B660B2100310EA2 /* Debug64bit */,
+				F97258AA0A86873D00096C78 /* Release */,
+				F97258AC0A86873D00096C78 /* ReleaseUniversal */,
+				F9A9D1F60FC77799002A2BE3 /* ReleaseUniversal clang */,
+				F9988BB80D81587400B6B03B /* ReleaseUniversal llvm-gcc */,
+				F9988BB40D81586D00B6B03B /* ReleaseUniversal gcc40 */,
+				F9EEED980C2FEFD300396116 /* ReleaseUniversal10.5SDK */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Debug;
+		};
+/* End XCConfigurationList section */
+	};
+	rootObject = 08FB7793FE84155DC02AAC07 /* Project object */;
+}
diff --git a/macosx/Tclsh-Info.plist.in b/macosx/Tclsh-Info.plist.in
new file mode 100644
index 0000000..ecc7f21
--- /dev/null
+++ b/macosx/Tclsh-Info.plist.in
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<!--
+	Copyright (c) 2005-2007 Daniel A. Steffen <das@users.sourceforge.net>
+
+	See the file "license.terms" for information on usage and redistribution of
+	this file, and for a DISCLAIMER OF ALL WARRANTIES.
+-->
+<plist version="1.0">
+<dict>
+	<key>CFBundleDevelopmentRegion</key>
+	<string>English</string>
+	<key>CFBundleExecutable</key>
+	<string>tclsh@TCL_VERSION@</string>
+	<key>CFBundleGetInfoString</key>
+	<string>Tcl Shell @TCL_VERSION@@TCL_PATCH_LEVEL@,
+Copyright © 1987-@TCL_YEAR@ Tcl Core Team,
+Copyright © 2001-@TCL_YEAR@ Daniel A. Steffen,
+Copyright © 2001-2009 Apple Inc.,
+Copyright © 2001-2002 Jim Ingham &amp; Ian Reid</string>
+	<key>CFBundleIdentifier</key>
+	<string>com.tcltk.tclsh</string>
+	<key>CFBundleInfoDictionaryVersion</key>
+	<string>6.0</string>
+	<key>CFBundleName</key>
+	<string>tclsh</string>
+	<key>CFBundlePackageType</key>
+	<string>APPL</string>
+	<key>CFBundleShortVersionString</key>
+	<string>@TCL_VERSION@@TCL_PATCH_LEVEL@</string>
+	<key>CFBundleSignature</key>
+	<string>TclS</string>
+	<key>CFBundleVersion</key>
+	<string>@TCL_VERSION@@TCL_PATCH_LEVEL@</string>
+</dict>
+</plist>
diff --git a/macosx/configure.ac b/macosx/configure.ac
new file mode 100644
index 0000000..f7a8bb3
--- /dev/null
+++ b/macosx/configure.ac
@@ -0,0 +1,11 @@
+#! /bin/bash -norc
+dnl	This file is an input file used by the GNU "autoconf" program to
+dnl	generate the file "configure", which is run during Tcl installation
+dnl	to configure the system for the local environment.
+
+dnl	Ensure that the config (auto)headers support is used, then just
+dnl	include the configure sources from ../unix:
+
+m4_include(../unix/aclocal.m4)
+m4_define(SC_USE_CONFIG_HEADERS)
+m4_include(../unix/configure.in)
diff --git a/macosx/tclMacOSXBundle.c b/macosx/tclMacOSXBundle.c
new file mode 100644
index 0000000..dad3733
--- /dev/null
+++ b/macosx/tclMacOSXBundle.c
@@ -0,0 +1,312 @@
+/*
+ * tclMacOSXBundle.c --
+ *
+ *	This file implements functions that inspect CFBundle structures on
+ *	MacOS X.
+ *
+ * Copyright 2001-2009, Apple Inc.
+ * Copyright (c) 2003-2009 Daniel A. Steffen <das@users.sourceforge.net>
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#include "tclPort.h"
+
+#ifdef HAVE_COREFOUNDATION
+#include <CoreFoundation/CoreFoundation.h>
+
+#ifndef TCL_DYLD_USE_DLFCN
+/*
+ * Use preferred dlfcn API on 10.4 and later
+ */
+#   if !defined(NO_DLFCN_H) && MAC_OS_X_VERSION_MAX_ALLOWED >= 1040
+#	define TCL_DYLD_USE_DLFCN 1
+#   else
+#	define TCL_DYLD_USE_DLFCN 0
+#   endif
+#endif /* TCL_DYLD_USE_DLFCN */
+
+#ifndef TCL_DYLD_USE_NSMODULE
+/*
+ * Use deprecated NSModule API only to support 10.3 and earlier:
+ */
+#   if MAC_OS_X_VERSION_MIN_REQUIRED < 1040
+#	define TCL_DYLD_USE_NSMODULE 1
+#   else
+#	define TCL_DYLD_USE_NSMODULE 0
+#   endif
+#endif /* TCL_DYLD_USE_NSMODULE */
+
+#if TCL_DYLD_USE_DLFCN
+#include <dlfcn.h>
+#if defined(HAVE_WEAK_IMPORT) && MAC_OS_X_VERSION_MIN_REQUIRED < 1040
+/*
+ * Support for weakly importing dlfcn API.
+ */
+extern void *		dlsym(void *handle, const char *symbol)
+			    WEAK_IMPORT_ATTRIBUTE;
+extern char *		dlerror(void) WEAK_IMPORT_ATTRIBUTE;
+#endif
+#endif /* TCL_DYLD_USE_DLFCN */
+
+#if TCL_DYLD_USE_NSMODULE
+#include <mach-o/dyld.h>
+#endif
+
+#if (TCL_DYLD_USE_DLFCN && MAC_OS_X_VERSION_MIN_REQUIRED < 1040) || \
+	(MAC_OS_X_VERSION_MIN_REQUIRED < 1050)
+MODULE_SCOPE long	tclMacOSXDarwinRelease;
+#endif
+
+#ifdef TCL_DEBUG_LOAD
+#define TclLoadDbgMsg(m, ...) \
+    do {								\
+	fprintf(stderr, "%s:%d: %s(): " m ".\n",			\
+		strrchr(__FILE__, '/')+1, __LINE__, __func__,		\
+		##__VA_ARGS__);						\
+    } while (0)
+#else
+#define TclLoadDbgMsg(m, ...)
+#endif /* TCL_DEBUG_LOAD */
+
+/*
+ * Forward declaration of functions defined in this file:
+ */
+
+static short		OpenResourceMap(CFBundleRef bundleRef);
+
+#endif /* HAVE_COREFOUNDATION */
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * OpenResourceMap --
+ *
+ *	Wrapper that dynamically acquires the address for the function
+ *	CFBundleOpenBundleResourceMap before calling it, since it is only
+ *	present in full CoreFoundation on Mac OS X and not in CFLite on pure
+ *	Darwin. Factored out because it is moderately ugly code.
+ *
+ *----------------------------------------------------------------------
+ */
+
+#ifdef HAVE_COREFOUNDATION
+
+static short
+OpenResourceMap(
+    CFBundleRef bundleRef)
+{
+    static int initialized = FALSE;
+    static short (*openresourcemap)(CFBundleRef) = NULL;
+
+    if (!initialized) {
+#if TCL_DYLD_USE_DLFCN
+#if MAC_OS_X_VERSION_MIN_REQUIRED < 1040
+	if (tclMacOSXDarwinRelease >= 8)
+#endif
+	{
+	    openresourcemap = dlsym(RTLD_NEXT,
+		    "CFBundleOpenBundleResourceMap");
+#ifdef TCL_DEBUG_LOAD
+	    if (!openresourcemap) {
+		const char *errMsg = dlerror();
+
+		TclLoadDbgMsg("dlsym() failed: %s", errMsg);
+	    }
+#endif /* TCL_DEBUG_LOAD */
+	}
+	if (!openresourcemap)
+#endif /* TCL_DYLD_USE_DLFCN */
+	{
+#if TCL_DYLD_USE_NSMODULE
+	    if (NSIsSymbolNameDefinedWithHint(
+		    "_CFBundleOpenBundleResourceMap", "CoreFoundation")) {
+		NSSymbol nsSymbol = NSLookupAndBindSymbolWithHint(
+			"_CFBundleOpenBundleResourceMap", "CoreFoundation");
+
+		if (nsSymbol) {
+		    openresourcemap = NSAddressOfSymbol(nsSymbol);
+		}
+	    }
+#endif /* TCL_DYLD_USE_NSMODULE */
+	}
+	initialized = TRUE;
+    }
+
+    if (openresourcemap) {
+	return openresourcemap(bundleRef);
+    }
+    return -1;
+}
+
+#endif /* HAVE_COREFOUNDATION */
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_MacOSXOpenBundleResources --
+ *
+ *	Given the bundle name for a shared library, this routine sets
+ *	libraryPath to the Resources/Scripts directory in the framework
+ *	package. If hasResourceFile is true, it will also open the main
+ *	resource file for the bundle.
+ *
+ * Results:
+ *	TCL_OK if the bundle could be opened, and the Scripts folder found.
+ *	TCL_ERROR otherwise.
+ *
+ * Side effects:
+ *	libraryVariableName may be set, and the resource file opened.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_MacOSXOpenBundleResources(
+    Tcl_Interp *interp,
+    const char *bundleName,
+    int hasResourceFile,
+    int maxPathLen,
+    char *libraryPath)
+{
+    return Tcl_MacOSXOpenVersionedBundleResources(interp, bundleName, NULL,
+	    hasResourceFile, maxPathLen, libraryPath);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_MacOSXOpenVersionedBundleResources --
+ *
+ *	Given the bundle and version name for a shared library (version name
+ *	can be NULL to indicate latest version), this routine sets libraryPath
+ *	to the Resources/Scripts directory in the framework package. If
+ *	hasResourceFile is true, it will also open the main resource file for
+ *	the bundle.
+ *
+ * Results:
+ *	TCL_OK if the bundle could be opened, and the Scripts folder found.
+ *	TCL_ERROR otherwise.
+ *
+ * Side effects:
+ *	libraryVariableName may be set, and the resource file opened.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_MacOSXOpenVersionedBundleResources(
+    Tcl_Interp *interp,
+    const char *bundleName,
+    const char *bundleVersion,
+    int hasResourceFile,
+    int maxPathLen,
+    char *libraryPath)
+{
+#ifdef HAVE_COREFOUNDATION
+    CFBundleRef bundleRef, versionedBundleRef = NULL;
+    CFStringRef bundleNameRef;
+    CFURLRef libURL;
+
+    libraryPath[0] = '\0';
+
+    bundleNameRef = CFStringCreateWithCString(NULL, bundleName,
+	    kCFStringEncodingUTF8);
+
+    bundleRef = CFBundleGetBundleWithIdentifier(bundleNameRef);
+    CFRelease(bundleNameRef);
+
+    if (bundleVersion && bundleRef) {
+	/*
+	 * Create bundle from bundleVersion subdirectory of 'Versions'.
+	 */
+
+	CFURLRef bundleURL = CFBundleCopyBundleURL(bundleRef);
+
+	if (bundleURL) {
+	    CFStringRef bundleVersionRef = CFStringCreateWithCString(NULL,
+		    bundleVersion, kCFStringEncodingUTF8);
+
+	    if (bundleVersionRef) {
+		CFComparisonResult versionComparison = kCFCompareLessThan;
+		CFStringRef bundleTailRef = CFURLCopyLastPathComponent(
+			bundleURL);
+
+		if (bundleTailRef) {
+		    versionComparison = CFStringCompare(bundleTailRef,
+			    bundleVersionRef, 0);
+		    CFRelease(bundleTailRef);
+		}
+		if (versionComparison != kCFCompareEqualTo) {
+		    CFURLRef versURL = CFURLCreateCopyAppendingPathComponent(
+			    NULL, bundleURL, CFSTR("Versions"), TRUE);
+
+		    if (versURL) {
+			CFURLRef versionedBundleURL =
+				CFURLCreateCopyAppendingPathComponent(
+				NULL, versURL, bundleVersionRef, TRUE);
+
+			if (versionedBundleURL) {
+			    versionedBundleRef = CFBundleCreate(NULL,
+				    versionedBundleURL);
+			    if (versionedBundleRef) {
+				bundleRef = versionedBundleRef;
+			    }
+			    CFRelease(versionedBundleURL);
+			}
+			CFRelease(versURL);
+		    }
+		}
+		CFRelease(bundleVersionRef);
+	    }
+	    CFRelease(bundleURL);
+	}
+    }
+
+    if (bundleRef) {
+	if (hasResourceFile) {
+	    (void) OpenResourceMap(bundleRef);
+	}
+
+	libURL = CFBundleCopyResourceURL(bundleRef, CFSTR("Scripts"),
+		NULL, NULL);
+
+	if (libURL) {
+	    /*
+	     * FIXME: This is a quick fix, it is probably not right for
+	     * internationalization.
+	     */
+
+	    CFURLGetFileSystemRepresentation(libURL, TRUE,
+		    (unsigned char *) libraryPath, maxPathLen);
+	    CFRelease(libURL);
+	}
+	if (versionedBundleRef) {
+#if MAC_OS_X_VERSION_MIN_REQUIRED < 1050
+	    /*
+	     * Workaround CFBundle bug in Tiger and earlier. [Bug 2569449]
+	     */
+
+	    if (tclMacOSXDarwinRelease >= 9)
+#endif
+	    {
+		CFRelease(versionedBundleRef);
+	    }
+	}
+    }
+
+    if (libraryPath[0]) {
+	return TCL_OK;
+    }
+#endif /* HAVE_COREFOUNDATION */
+    return TCL_ERROR;
+}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/macosx/tclMacOSXFCmd.c b/macosx/tclMacOSXFCmd.c
new file mode 100644
index 0000000..8ecfd0b
--- /dev/null
+++ b/macosx/tclMacOSXFCmd.c
@@ -0,0 +1,721 @@
+/*
+ * tclMacOSXFCmd.c
+ *
+ *	This file implements the MacOSX specific portion of file manipulation
+ *	subcommands of the "file" command.
+ *
+ * Copyright (c) 2003-2007 Daniel A. Steffen <das@users.sourceforge.net>
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#include "tclInt.h"
+
+#ifdef HAVE_GETATTRLIST
+#include <sys/attr.h>
+#include <sys/paths.h>
+#include <libkern/OSByteOrder.h>
+#endif
+
+/* Darwin 8 copyfile API. */
+#ifdef HAVE_COPYFILE
+#ifdef HAVE_COPYFILE_H
+#include <copyfile.h>
+#if defined(HAVE_WEAK_IMPORT) && (MAC_OS_X_VERSION_MIN_REQUIRED < 1040)
+/* Support for weakly importing copyfile. */
+#define WEAK_IMPORT_COPYFILE
+extern int		copyfile(const char *from, const char *to,
+			    copyfile_state_t state, copyfile_flags_t flags)
+			    WEAK_IMPORT_ATTRIBUTE;
+#endif /* HAVE_WEAK_IMPORT */
+#else /* HAVE_COPYFILE_H */
+int			copyfile(const char *from, const char *to,
+			    void *state, uint32_t flags);
+#define COPYFILE_ACL		(1<<0)
+#define COPYFILE_XATTR		(1<<2)
+#define COPYFILE_NOFOLLOW_SRC	(1<<18)
+#if defined(HAVE_WEAK_IMPORT) && (MAC_OS_X_VERSION_MIN_REQUIRED < 1040)
+/* Support for weakly importing copyfile. */
+#define WEAK_IMPORT_COPYFILE
+extern int		copyfile(const char *from, const char *to,
+			    void *state, uint32_t flags)
+			    WEAK_IMPORT_ATTRIBUTE;
+#endif /* HAVE_WEAK_IMPORT */
+#endif /* HAVE_COPYFILE_H */
+#endif /* HAVE_COPYFILE */
+
+#ifdef WEAK_IMPORT_COPYFILE
+#define MayUseCopyFile()	(copyfile != NULL)
+#elif defined(HAVE_COPYFILE)
+#define MayUseCopyFile()	(1)
+#else
+#define MayUseCopyFile()	(0)
+#endif
+
+#include <libkern/OSByteOrder.h>
+
+/*
+ * Constants for file attributes subcommand. Need to be kept in sync with
+ * tclUnixFCmd.c !
+ */
+
+enum {
+    UNIX_GROUP_ATTRIBUTE,
+    UNIX_OWNER_ATTRIBUTE,
+    UNIX_PERMISSIONS_ATTRIBUTE,
+#ifdef HAVE_CHFLAGS
+    UNIX_READONLY_ATTRIBUTE,
+#endif
+#ifdef MAC_OSX_TCL
+    MACOSX_CREATOR_ATTRIBUTE,
+    MACOSX_TYPE_ATTRIBUTE,
+    MACOSX_HIDDEN_ATTRIBUTE,
+    MACOSX_RSRCLENGTH_ATTRIBUTE,
+#endif
+};
+
+typedef u_int32_t OSType;
+
+static int		GetOSTypeFromObj(Tcl_Interp *interp,
+			    Tcl_Obj *objPtr, OSType *osTypePtr);
+static Tcl_Obj *	NewOSTypeObj(const OSType newOSType);
+static int		SetOSTypeFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr);
+static void		UpdateStringOfOSType(Tcl_Obj *objPtr);
+
+static const Tcl_ObjType tclOSTypeType = {
+    "osType",				/* name */
+    NULL,				/* freeIntRepProc */
+    NULL,				/* dupIntRepProc */
+    UpdateStringOfOSType,		/* updateStringProc */
+    SetOSTypeFromAny			/* setFromAnyProc */
+};
+
+enum {
+    kIsInvisible = 0x4000,
+};
+
+#define kFinfoIsInvisible	(OSSwapHostToBigConstInt16(kIsInvisible))
+
+typedef	struct finderinfo {
+    u_int32_t type;
+    u_int32_t creator;
+    u_int16_t fdFlags;
+    u_int32_t location;
+    u_int16_t reserved;
+    u_int32_t extendedFileInfo[4];
+} __attribute__ ((__packed__)) finderinfo;
+
+typedef struct fileinfobuf {
+    u_int32_t info_length;
+    u_int32_t data[8];
+} fileinfobuf;
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclMacOSXGetFileAttribute
+ *
+ *	Gets a MacOSX attribute of a file. Which attribute is controlled by
+ *	objIndex. The object will have ref count 0.
+ *
+ * Results:
+ *	Standard TCL result. Returns a new Tcl_Obj in attributePtrPtr if there
+ *	is no error.
+ *
+ * Side effects:
+ *	A new object is allocated.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclMacOSXGetFileAttribute(
+    Tcl_Interp *interp,		 /* The interp we are using for errors. */
+    int objIndex,		 /* The index of the attribute. */
+    Tcl_Obj *fileName,		 /* The name of the file (UTF-8). */
+    Tcl_Obj **attributePtrPtr)	 /* A pointer to return the object with. */
+{
+#ifdef HAVE_GETATTRLIST
+    int result;
+    Tcl_StatBuf statBuf;
+    struct attrlist alist;
+    fileinfobuf finfo;
+    finderinfo *finder = (finderinfo *) &finfo.data;
+    off_t *rsrcForkSize = (off_t *) &finfo.data;
+    const char *native;
+
+    result = TclpObjStat(fileName, &statBuf);
+
+    if (result != 0) {
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		"could not read \"%s\": %s",
+		TclGetString(fileName), Tcl_PosixError(interp)));
+	return TCL_ERROR;
+    }
+
+    if (S_ISDIR(statBuf.st_mode) && objIndex != MACOSX_HIDDEN_ATTRIBUTE) {
+	/*
+	 * Directories only support attribute "-hidden".
+	 */
+
+	errno = EISDIR;
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		"invalid attribute: %s", Tcl_PosixError(interp)));
+	return TCL_ERROR;
+    }
+
+    bzero(&alist, sizeof(struct attrlist));
+    alist.bitmapcount = ATTR_BIT_MAP_COUNT;
+    if (objIndex == MACOSX_RSRCLENGTH_ATTRIBUTE) {
+	alist.fileattr = ATTR_FILE_RSRCLENGTH;
+    } else {
+	alist.commonattr = ATTR_CMN_FNDRINFO;
+    }
+    native = Tcl_FSGetNativePath(fileName);
+    result = getattrlist(native, &alist, &finfo, sizeof(fileinfobuf), 0);
+
+    if (result != 0) {
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		"could not read attributes of \"%s\": %s",
+		TclGetString(fileName), Tcl_PosixError(interp)));
+	return TCL_ERROR;
+    }
+
+    switch (objIndex) {
+    case MACOSX_CREATOR_ATTRIBUTE:
+	*attributePtrPtr = NewOSTypeObj(
+		OSSwapBigToHostInt32(finder->creator));
+	break;
+    case MACOSX_TYPE_ATTRIBUTE:
+	*attributePtrPtr = NewOSTypeObj(
+		OSSwapBigToHostInt32(finder->type));
+	break;
+    case MACOSX_HIDDEN_ATTRIBUTE:
+	*attributePtrPtr = Tcl_NewBooleanObj(
+		(finder->fdFlags & kFinfoIsInvisible) != 0);
+	break;
+    case MACOSX_RSRCLENGTH_ATTRIBUTE:
+	*attributePtrPtr = Tcl_NewWideIntObj(*rsrcForkSize);
+	break;
+    }
+    return TCL_OK;
+#else
+    Tcl_SetObjResult(interp, Tcl_NewStringObj(
+	    "Mac OS X file attributes not supported", -1));
+    Tcl_SetErrorCode(interp, "TCL", "UNSUPPORTED", NULL);
+    return TCL_ERROR;
+#endif /* HAVE_GETATTRLIST */
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * TclMacOSXSetFileAttribute --
+ *
+ *	Sets a MacOSX attribute of a file. Which attribute is controlled by
+ *	objIndex.
+ *
+ * Results:
+ *	Standard TCL result.
+ *
+ * Side effects:
+ *	As above.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+int
+TclMacOSXSetFileAttribute(
+    Tcl_Interp *interp,		/* The interp for error reporting. */
+    int objIndex,		/* The index of the attribute. */
+    Tcl_Obj *fileName,		/* The name of the file (UTF-8). */
+    Tcl_Obj *attributePtr)	/* New owner for file. */
+{
+#ifdef HAVE_GETATTRLIST
+    int result;
+    Tcl_StatBuf statBuf;
+    struct attrlist alist;
+    fileinfobuf finfo;
+    finderinfo *finder = (finderinfo *) &finfo.data;
+    off_t *rsrcForkSize = (off_t *) &finfo.data;
+    const char *native;
+
+    result = TclpObjStat(fileName, &statBuf);
+
+    if (result != 0) {
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		"could not read \"%s\": %s",
+		TclGetString(fileName), Tcl_PosixError(interp)));
+	return TCL_ERROR;
+    }
+
+    if (S_ISDIR(statBuf.st_mode) && objIndex != MACOSX_HIDDEN_ATTRIBUTE) {
+	/*
+	 * Directories only support attribute "-hidden".
+	 */
+
+	errno = EISDIR;
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		"invalid attribute: %s", Tcl_PosixError(interp)));
+	return TCL_ERROR;
+    }
+
+    bzero(&alist, sizeof(struct attrlist));
+    alist.bitmapcount = ATTR_BIT_MAP_COUNT;
+    if (objIndex == MACOSX_RSRCLENGTH_ATTRIBUTE) {
+	alist.fileattr = ATTR_FILE_RSRCLENGTH;
+    } else {
+	alist.commonattr = ATTR_CMN_FNDRINFO;
+    }
+    native = Tcl_FSGetNativePath(fileName);
+    result = getattrlist(native, &alist, &finfo, sizeof(fileinfobuf), 0);
+
+    if (result != 0) {
+	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		"could not read attributes of \"%s\": %s",
+		TclGetString(fileName), Tcl_PosixError(interp)));
+	return TCL_ERROR;
+    }
+
+    if (objIndex != MACOSX_RSRCLENGTH_ATTRIBUTE) {
+	OSType t;
+	int h;
+
+	switch (objIndex) {
+	case MACOSX_CREATOR_ATTRIBUTE:
+	    if (GetOSTypeFromObj(interp, attributePtr, &t) != TCL_OK) {
+		return TCL_ERROR;
+	    }
+	    finder->creator = OSSwapHostToBigInt32(t);
+	    break;
+	case MACOSX_TYPE_ATTRIBUTE:
+	    if (GetOSTypeFromObj(interp, attributePtr, &t) != TCL_OK) {
+		return TCL_ERROR;
+	    }
+	    finder->type = OSSwapHostToBigInt32(t);
+	    break;
+	case MACOSX_HIDDEN_ATTRIBUTE:
+	    if (Tcl_GetBooleanFromObj(interp, attributePtr, &h) != TCL_OK) {
+		return TCL_ERROR;
+	    }
+	    if (h) {
+		finder->fdFlags |= kFinfoIsInvisible;
+	    } else {
+		finder->fdFlags &= ~kFinfoIsInvisible;
+	    }
+	    break;
+	}
+
+	result = setattrlist(native, &alist,
+		&finfo.data, sizeof(finfo.data), 0);
+
+	if (result != 0) {
+	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		    "could not set attributes of \"%s\": %s",
+		    TclGetString(fileName), Tcl_PosixError(interp)));
+	    return TCL_ERROR;
+	}
+    } else {
+	Tcl_WideInt newRsrcForkSize;
+
+	if (Tcl_GetWideIntFromObj(interp, attributePtr,
+		&newRsrcForkSize) != TCL_OK) {
+	    return TCL_ERROR;
+	}
+
+	if (newRsrcForkSize != *rsrcForkSize) {
+	    Tcl_DString ds;
+
+	    /*
+	     * Only setting rsrclength to 0 to strip a file's resource fork is
+	     * supported.
+	     */
+
+	    if (newRsrcForkSize != 0) {
+		Tcl_SetObjResult(interp, Tcl_NewStringObj(
+			"setting nonzero rsrclength not supported", -1));
+		Tcl_SetErrorCode(interp, "TCL", "UNSUPPORTED", NULL);
+		return TCL_ERROR;
+	    }
+
+	    /*
+	     * Construct path to resource fork.
+	     */
+
+	    Tcl_DStringInit(&ds);
+	    Tcl_DStringAppend(&ds, native, -1);
+	    Tcl_DStringAppend(&ds, _PATH_RSRCFORKSPEC, -1);
+
+	    result = truncate(Tcl_DStringValue(&ds), (off_t)0);
+	    if (result != 0) {
+		/*
+		 * truncate() on a valid resource fork path may fail with a
+		 * permission error in some OS releases, try truncating with
+		 * open() instead:
+		 */
+
+		int fd = open(Tcl_DStringValue(&ds), O_WRONLY | O_TRUNC);
+
+		if (fd > 0) {
+		    result = close(fd);
+		}
+	    }
+
+	    Tcl_DStringFree(&ds);
+
+	    if (result != 0) {
+		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+			"could not truncate resource fork of \"%s\": %s",
+			TclGetString(fileName), Tcl_PosixError(interp)));
+		return TCL_ERROR;
+	    }
+	}
+    }
+    return TCL_OK;
+#else
+    Tcl_SetObjResult(interp, Tcl_NewStringObj(
+	    "Mac OS X file attributes not supported", -1));
+    Tcl_SetErrorCode(interp, "TCL", "UNSUPPORTED", NULL);
+    return TCL_ERROR;
+#endif
+}
+
+/*
+ *---------------------------------------------------------------------------
+ *
+ * TclMacOSXCopyFileAttributes --
+ *
+ *	Copy the MacOSX attributes and resource fork (if present) from one
+ *	file to another.
+ *
+ * Results:
+ *	Standard Tcl result.
+ *
+ * Side effects:
+ *	MacOSX attributes and resource fork are updated in the new file to
+ *	reflect the old file.
+ *
+ *---------------------------------------------------------------------------
+ */
+
+int
+TclMacOSXCopyFileAttributes(
+    const char *src,		/* Path name of source file (native). */
+    const char *dst,		/* Path name of target file (native). */
+    const Tcl_StatBuf *statBufPtr)
+				/* Stat info for source file */
+{
+    if (MayUseCopyFile()) {
+#ifdef HAVE_COPYFILE
+	if (0 == copyfile(src, dst, NULL, (S_ISLNK(statBufPtr->st_mode)
+		? COPYFILE_XATTR | COPYFILE_NOFOLLOW_SRC
+		: COPYFILE_XATTR | COPYFILE_ACL))) {
+	    return TCL_OK;
+	}
+#endif /* HAVE_COPYFILE */
+    } else {
+#if (!defined(HAVE_COPYFILE) || defined(WEAK_IMPORT_COPYFILE)) && defined(HAVE_GETATTRLIST)
+	struct attrlist alist;
+	fileinfobuf finfo;
+	off_t *rsrcForkSize = (off_t *) &finfo.data;
+	Tcl_DString srcBuf, dstBuf;
+	int result;
+
+	bzero(&alist, sizeof(struct attrlist));
+	alist.bitmapcount = ATTR_BIT_MAP_COUNT;
+	alist.commonattr = ATTR_CMN_FNDRINFO;
+
+	if (getattrlist(src, &alist, &finfo, sizeof(fileinfobuf), 0)) {
+	    return TCL_ERROR;
+	}
+	if (setattrlist(dst, &alist, &finfo.data, sizeof(finfo.data), 0)) {
+	    return TCL_ERROR;
+	}
+
+	/*
+	 * If we're a directory, we're done as they never have resource forks.
+	 */
+
+	if (S_ISDIR(statBufPtr->st_mode)) {
+	    return TCL_OK;
+	}
+
+	/*
+	 * We only copy a non-empty resource fork, so determine if that's the
+	 * case first.
+	 */
+
+	alist.commonattr = 0;
+	alist.fileattr = ATTR_FILE_RSRCLENGTH;
+	if (getattrlist(src, &alist, &finfo, sizeof(fileinfobuf), 0)) {
+	    return TCL_ERROR;
+	} else if (*rsrcForkSize == 0) {
+	    return TCL_OK;
+	}
+
+	/*
+	 * Construct paths to resource forks.
+	 */
+
+	Tcl_DStringInit(&srcBuf);
+	Tcl_DStringAppend(&srcBuf, src, -1);
+	Tcl_DStringAppend(&srcBuf, _PATH_RSRCFORKSPEC, -1);
+	Tcl_DStringInit(&dstBuf);
+	Tcl_DStringAppend(&dstBuf, dst, -1);
+	Tcl_DStringAppend(&dstBuf, _PATH_RSRCFORKSPEC, -1);
+
+	/*
+	 * Do the copy.
+	 */
+
+	result = TclUnixCopyFile(Tcl_DStringValue(&srcBuf),
+		Tcl_DStringValue(&dstBuf), statBufPtr, 1);
+	Tcl_DStringFree(&srcBuf);
+	Tcl_DStringFree(&dstBuf);
+	if (result == 0) {
+	    return TCL_OK;
+	}
+#endif /* (!HAVE_COPYFILE || WEAK_IMPORT_COPYFILE) && HAVE_GETATTRLIST */
+    }
+    return TCL_ERROR;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclMacOSXMatchType --
+ *
+ *	This routine is used by the globbing code to check if a file matches a
+ *	given mac type and/or creator code.
+ *
+ * Results:
+ *	The return value is 1, 0 or -1 indicating whether the file matches the
+ *	given criteria, does not match them, or an error occurred (in wich
+ *	case an error is left in interp).
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclMacOSXMatchType(
+    Tcl_Interp *interp,		/* Interpreter to receive errors. */
+    const char *pathName,	/* Native path to check. */
+    const char *fileName,	/* Native filename to check. */
+    Tcl_StatBuf *statBufPtr,	/* Stat info for file to check */
+    Tcl_GlobTypeData *types)	/* Type description to match against. */
+{
+#ifdef HAVE_GETATTRLIST
+    struct attrlist alist;
+    fileinfobuf finfo;
+    finderinfo *finder = (finderinfo *) &finfo.data;
+    OSType osType;
+
+    bzero(&alist, sizeof(struct attrlist));
+    alist.bitmapcount = ATTR_BIT_MAP_COUNT;
+    alist.commonattr = ATTR_CMN_FNDRINFO;
+    if (getattrlist(pathName, &alist, &finfo, sizeof(fileinfobuf), 0) != 0) {
+	return 0;
+    }
+    if ((types->perm & TCL_GLOB_PERM_HIDDEN) &&
+	    !((finder->fdFlags & kFinfoIsInvisible) || (*fileName == '.'))) {
+	return 0;
+    }
+    if (S_ISDIR(statBufPtr->st_mode)
+	    && (types->macType || types->macCreator)) {
+	/*
+	 * Directories don't support types or creators.
+	 */
+
+	return 0;
+    }
+    if (types->macType) {
+	if (GetOSTypeFromObj(interp, types->macType, &osType) != TCL_OK) {
+	    return -1;
+	}
+	if (osType != OSSwapBigToHostInt32(finder->type)) {
+	    return 0;
+	}
+    }
+    if (types->macCreator) {
+	if (GetOSTypeFromObj(interp, types->macCreator, &osType) != TCL_OK) {
+	    return -1;
+	}
+	if (osType != OSSwapBigToHostInt32(finder->creator)) {
+	    return 0;
+	}
+    }
+#endif
+    return 1;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * GetOSTypeFromObj --
+ *
+ *	Attempt to return an OSType from the Tcl object "objPtr".
+ *
+ * Results:
+ *	Standard TCL result. If an error occurs during conversion, an error
+ *	message is left in interp->objResult.
+ *
+ * Side effects:
+ *	The string representation of objPtr will be updated if necessary.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+GetOSTypeFromObj(
+    Tcl_Interp *interp,		/* Used for error reporting if not NULL. */
+    Tcl_Obj *objPtr,		/* The object from which to get an OSType. */
+    OSType *osTypePtr)		/* Place to store resulting OSType. */
+{
+    int result = TCL_OK;
+
+    if (objPtr->typePtr != &tclOSTypeType) {
+	result = SetOSTypeFromAny(interp, objPtr);
+    }
+    *osTypePtr = (OSType) objPtr->internalRep.longValue;
+    return result;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * NewOSTypeObj --
+ *
+ *	Create a new OSType object.
+ *
+ * Results:
+ *	The newly created OSType object is returned, it has ref count 0.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static Tcl_Obj *
+NewOSTypeObj(
+    const OSType osType)	/* OSType used to initialize the new
+				 * object. */
+{
+    Tcl_Obj *objPtr;
+
+    TclNewObj(objPtr);
+    TclInvalidateStringRep(objPtr);
+    objPtr->internalRep.longValue = (long) osType;
+    objPtr->typePtr = &tclOSTypeType;
+    return objPtr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * SetOSTypeFromAny --
+ *
+ *	Attempts to force the internal representation for a Tcl object to
+ *	tclOSTypeType, specifically.
+ *
+ * Results:
+ *	The return value is a standard object Tcl result. If an error occurs
+ *	during conversion, an error message is left in the interpreter's
+ *	result unless "interp" is NULL.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+SetOSTypeFromAny(
+    Tcl_Interp *interp,		/* Tcl interpreter */
+    Tcl_Obj *objPtr)		/* Pointer to the object to convert */
+{
+    const char *string;
+    int length, result = TCL_OK;
+    Tcl_DString ds;
+    Tcl_Encoding encoding = Tcl_GetEncoding(NULL, "macRoman");
+
+    string = Tcl_GetStringFromObj(objPtr, &length);
+    Tcl_UtfToExternalDString(encoding, string, length, &ds);
+
+    if (Tcl_DStringLength(&ds) > 4) {
+	if (interp) {
+	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
+		    "expected Macintosh OS type but got \"%s\": ", string));
+	    Tcl_SetErrorCode(interp, "TCL", "VALUE", "MAC_OSTYPE", NULL);
+	}
+	result = TCL_ERROR;
+    } else {
+	OSType osType;
+	char bytes[4] = {'\0','\0','\0','\0'};
+
+	memcpy(bytes, Tcl_DStringValue(&ds), (size_t)Tcl_DStringLength(&ds));
+	osType = (OSType) bytes[0] << 24 |
+		 (OSType) bytes[1] << 16 |
+		 (OSType) bytes[2] <<  8 |
+		 (OSType) bytes[3];
+	TclFreeIntRep(objPtr);
+	objPtr->internalRep.longValue = (long) osType;
+	objPtr->typePtr = &tclOSTypeType;
+    }
+    Tcl_DStringFree(&ds);
+    Tcl_FreeEncoding(encoding);
+    return result;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * UpdateStringOfOSType --
+ *
+ *	Update the string representation for an OSType object. Note: This
+ *	function does not free an existing old string rep so storage will be
+ *	lost if this has not already been done.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	The object's string is set to a valid string that results from the
+ *	OSType-to-string conversion.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+UpdateStringOfOSType(
+    register Tcl_Obj *objPtr)	/* OSType object whose string rep to
+				 * update. */
+{
+    char string[5];
+    OSType osType = (OSType) objPtr->internalRep.longValue;
+    Tcl_DString ds;
+    Tcl_Encoding encoding = Tcl_GetEncoding(NULL, "macRoman");
+    unsigned len;
+
+    string[0] = (char) (osType >> 24);
+    string[1] = (char) (osType >> 16);
+    string[2] = (char) (osType >>  8);
+    string[3] = (char) (osType);
+    string[4] = '\0';
+    Tcl_ExternalToUtfDString(encoding, string, -1, &ds);
+    len = (unsigned) Tcl_DStringLength(&ds) + 1;
+    objPtr->bytes = ckalloc(len);
+    memcpy(objPtr->bytes, Tcl_DStringValue(&ds), len);
+    objPtr->length = Tcl_DStringLength(&ds);
+    Tcl_DStringFree(&ds);
+    Tcl_FreeEncoding(encoding);
+}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/macosx/tclMacOSXNotify.c b/macosx/tclMacOSXNotify.c
new file mode 100644
index 0000000..9b7bd1a
--- /dev/null
+++ b/macosx/tclMacOSXNotify.c
@@ -0,0 +1,2037 @@
+/*
+ * tclMacOSXNotify.c --
+ *
+ *	This file contains the implementation of a merged CFRunLoop/select()
+ *	based notifier, which is the lowest-level part of the Tcl event loop.
+ *	This file works together with generic/tclNotify.c.
+ *
+ * Copyright (c) 1995-1997 Sun Microsystems, Inc.
+ * Copyright 2001-2009, Apple Inc.
+ * Copyright (c) 2005-2009 Daniel A. Steffen <das@users.sourceforge.net>
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#include "tclInt.h"
+#ifdef HAVE_COREFOUNDATION	/* Traditional unix select-based notifier is
+				 * in tclUnixNotfy.c */
+#include <CoreFoundation/CoreFoundation.h>
+#include <pthread.h>
+
+/* #define TCL_MAC_DEBUG_NOTIFIER 1 */
+
+/*
+ * We use the Darwin-native spinlock API rather than pthread mutexes for
+ * notifier locking: this radically simplifies the implementation and lowers
+ * overhead. Note that these are not pure spinlocks, they employ various
+ * strategies to back off and relinquish the processor, making them immune to
+ * most priority-inversion livelocks (c.f. 'man 3 OSSpinLockLock' and Darwin
+ * sources: xnu/osfmk/{ppc,i386}/commpage/spinlocks.s).
+ */
+
+#if defined(HAVE_LIBKERN_OSATOMIC_H) && defined(HAVE_OSSPINLOCKLOCK)
+/*
+ * Use OSSpinLock API where available (Tiger or later).
+ */
+
+#include <libkern/OSAtomic.h>
+
+#if defined(HAVE_WEAK_IMPORT) && MAC_OS_X_VERSION_MIN_REQUIRED < 1040
+/*
+ * Support for weakly importing spinlock API.
+ */
+#define WEAK_IMPORT_SPINLOCKLOCK
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1050
+#define VOLATILE volatile
+#else
+#define VOLATILE
+#endif /* MAC_OS_X_VERSION_MAX_ALLOWED >= 1050 */
+#ifndef bool
+#define bool int
+#endif
+extern void		OSSpinLockLock(VOLATILE OSSpinLock *lock)
+			    WEAK_IMPORT_ATTRIBUTE;
+extern void		OSSpinLockUnlock(VOLATILE OSSpinLock *lock)
+			    WEAK_IMPORT_ATTRIBUTE;
+extern bool		OSSpinLockTry(VOLATILE OSSpinLock *lock)
+			    WEAK_IMPORT_ATTRIBUTE;
+extern void		_spin_lock(VOLATILE OSSpinLock *lock)
+			    WEAK_IMPORT_ATTRIBUTE;
+extern void		_spin_unlock(VOLATILE OSSpinLock *lock)
+			    WEAK_IMPORT_ATTRIBUTE;
+extern bool		_spin_lock_try(VOLATILE OSSpinLock *lock)
+			    WEAK_IMPORT_ATTRIBUTE;
+static void (* lockLock)(VOLATILE OSSpinLock *lock) = NULL;
+static void (* lockUnlock)(VOLATILE OSSpinLock *lock) = NULL;
+static bool (* lockTry)(VOLATILE OSSpinLock *lock) = NULL;
+#undef VOLATILE
+static pthread_once_t spinLockLockInitControl = PTHREAD_ONCE_INIT;
+static void
+SpinLockLockInit(void)
+{
+    lockLock   = OSSpinLockLock   != NULL ? OSSpinLockLock   : _spin_lock;
+    lockUnlock = OSSpinLockUnlock != NULL ? OSSpinLockUnlock : _spin_unlock;
+    lockTry    = OSSpinLockTry    != NULL ? OSSpinLockTry    : _spin_lock_try;
+    if (lockLock == NULL || lockUnlock == NULL) {
+	Tcl_Panic("SpinLockLockInit: no spinlock API available");
+    }
+}
+#define SpinLockLock(p) 	lockLock(p)
+#define SpinLockUnlock(p)	lockUnlock(p)
+#define SpinLockTry(p)		lockTry(p)
+#else
+#define SpinLockLock(p) 	OSSpinLockLock(p)
+#define SpinLockUnlock(p)	OSSpinLockUnlock(p)
+#define SpinLockTry(p)		OSSpinLockTry(p)
+#endif /* HAVE_WEAK_IMPORT */
+#define SPINLOCK_INIT		OS_SPINLOCK_INIT
+
+#else
+/*
+ * Otherwise, use commpage spinlock SPI directly.
+ */
+
+typedef uint32_t OSSpinLock;
+extern void		_spin_lock(OSSpinLock *lock);
+extern void		_spin_unlock(OSSpinLock *lock);
+extern int		_spin_lock_try(OSSpinLock *lock);
+#define SpinLockLock(p) 	_spin_lock(p)
+#define SpinLockUnlock(p)	_spin_unlock(p)
+#define SpinLockTry(p)		_spin_lock_try(p)
+#define SPINLOCK_INIT		0
+
+#endif /* HAVE_LIBKERN_OSATOMIC_H && HAVE_OSSPINLOCKLOCK */
+
+/*
+ * These spinlocks lock access to the global notifier state.
+ */
+
+static OSSpinLock notifierInitLock = SPINLOCK_INIT;
+static OSSpinLock notifierLock     = SPINLOCK_INIT;
+
+/*
+ * Macros abstracting notifier locking/unlocking
+ */
+
+#define LOCK_NOTIFIER_INIT	SpinLockLock(&notifierInitLock)
+#define UNLOCK_NOTIFIER_INIT	SpinLockUnlock(&notifierInitLock)
+#define LOCK_NOTIFIER		SpinLockLock(&notifierLock)
+#define UNLOCK_NOTIFIER		SpinLockUnlock(&notifierLock)
+#define LOCK_NOTIFIER_TSD	SpinLockLock(&tsdPtr->tsdLock)
+#define UNLOCK_NOTIFIER_TSD	SpinLockUnlock(&tsdPtr->tsdLock)
+
+#ifdef TCL_MAC_DEBUG_NOTIFIER
+#define TclMacOSXNotifierDbgMsg(m, ...) \
+    do {								\
+	fprintf(notifierLog?notifierLog:stderr, "tclMacOSXNotify.c:%d: " \
+		"%s() pid %5d thread %10p: " m "\n", __LINE__, __func__, \
+		getpid(), pthread_self(), ##__VA_ARGS__);		\
+	fflush(notifierLog?notifierLog:stderr);				\
+    } while (0)
+
+/*
+ * Debug version of SpinLockLock that logs the time spent waiting for the lock
+ */
+
+#define SpinLockLockDbg(p) \
+    if (!SpinLockTry(p)) {						\
+	Tcl_WideInt s = TclpGetWideClicks(), e;				\
+									\
+	SpinLockLock(p);						\
+	e = TclpGetWideClicks();					\
+	TclMacOSXNotifierDbgMsg("waited on %s for %8.0f ns",		\
+		#p, TclpWideClicksToNanoseconds(e-s));			\
+    }
+#undef LOCK_NOTIFIER_INIT
+#define LOCK_NOTIFIER_INIT	SpinLockLockDbg(&notifierInitLock)
+#undef LOCK_NOTIFIER
+#define LOCK_NOTIFIER		SpinLockLockDbg(&notifierLock)
+#undef LOCK_NOTIFIER_TSD
+#define LOCK_NOTIFIER_TSD	SpinLockLockDbg(&tsdPtr->tsdLock)
+#include <asl.h>
+static FILE *notifierLog = NULL;
+#ifndef NOTIFIER_LOG
+#define NOTIFIER_LOG "/tmp/tclMacOSXNotify.log"
+#endif
+#define OPEN_NOTIFIER_LOG \
+    if (!notifierLog) {							\
+	notifierLog = fopen(NOTIFIER_LOG, "a");				\
+	/*TclMacOSXNotifierDbgMsg("open log");				\
+	 *asl_set_filter(NULL,						\
+	 *	ASL_FILTER_MASK_UPTO(ASL_LEVEL_DEBUG));			\
+	 *asl_add_log_file(NULL, fileno(notifierLog));*/		\
+    }
+#define CLOSE_NOTIFIER_LOG \
+    if (notifierLog) {							\
+	/*asl_remove_log_file(NULL, fileno(notifierLog));		\
+	 *TclMacOSXNotifierDbgMsg("close log");*/			\
+	fclose(notifierLog);						\
+	notifierLog = NULL;						\
+    }
+#define ENABLE_ASL \
+    if (notifierLog) {							\
+	/*tsdPtr->asl = asl_open(NULL, "com.apple.console",		\
+	 *	ASL_OPT_NO_REMOTE);					\
+	 *asl_set_filter(tsdPtr->asl,					\
+	 *	ASL_FILTER_MASK_UPTO(ASL_LEVEL_DEBUG));			\
+	 *asl_add_log_file(tsdPtr->asl, fileno(notifierLog));*/		\
+    }
+#define DISABLE_ASL \
+    /*if (tsdPtr->asl) {						\
+     *	if (notifierLog) {						\
+     *	    asl_remove_log_file(tsdPtr->asl, fileno(notifierLog));	\
+     *	}								\
+     *	asl_close(tsdPtr->asl);						\
+     *}*/
+#define ASLCLIENT_DECL		/*aslclient asl*/
+#else
+#define TclMacOSXNotifierDbgMsg(m, ...)
+#define OPEN_NOTIFIER_LOG
+#define CLOSE_NOTIFIER_LOG
+#define ENABLE_ASL
+#define DISABLE_ASL
+#define ASLCLIENT_DECL
+#endif /* TCL_MAC_DEBUG_NOTIFIER */
+
+/*
+ * This structure is used to keep track of the notifier info for a registered
+ * file.
+ */
+
+typedef struct FileHandler {
+    int fd;
+    int mask;			/* Mask of desired events: TCL_READABLE,
+				 * etc. */
+    int readyMask;		/* Mask of events that have been seen since
+				 * the last time file handlers were invoked
+				 * for this file. */
+    Tcl_FileProc *proc;		/* Function to call, in the style of
+				 * Tcl_CreateFileHandler. */
+    ClientData clientData;	/* Argument to pass to proc. */
+    struct FileHandler *nextPtr;/* Next in list of all files we care about. */
+} FileHandler;
+
+/*
+ * The following structure is what is added to the Tcl event queue when file
+ * handlers are ready to fire.
+ */
+
+typedef struct FileHandlerEvent {
+    Tcl_Event header;		/* Information that is standard for all
+				 * events. */
+    int fd;			/* File descriptor that is ready. Used to find
+				 * the FileHandler structure for the file
+				 * (can't point directly to the FileHandler
+				 * structure because it could go away while
+				 * the event is queued). */
+} FileHandlerEvent;
+
+/*
+ * The following structure contains a set of select() masks to track readable,
+ * writable, and exceptional conditions.
+ */
+
+typedef struct SelectMasks {
+    fd_set readable;
+    fd_set writable;
+    fd_set exceptional;
+} SelectMasks;
+
+/*
+ * The following static structure contains the state information for the
+ * select based implementation of the Tcl notifier. One of these structures is
+ * created for each thread that is using the notifier.
+ */
+
+typedef struct ThreadSpecificData {
+    FileHandler *firstFileHandlerPtr;
+				/* Pointer to head of file handler list. */
+    int polled;			/* True if the notifier thread has polled for
+				 * this thread. */
+    int sleeping;		/* True if runloop is inside Tcl_Sleep. */
+    int runLoopSourcePerformed;	/* True after the runLoopSource callack was
+				 * performed. */
+    int runLoopRunning;		/* True if this thread's Tcl runLoop is
+				 * running. */
+    int runLoopNestingLevel;	/* Level of nested runLoop invocations. */
+    int runLoopServicingEvents;	/* True if this thread's runLoop is servicing
+				 * Tcl events. */
+
+    /* Must hold the notifierLock before accessing the following fields: */
+    /* Start notifierLock section */
+    int onList;			/* True if this thread is on the
+				 * waitingList */
+    struct ThreadSpecificData *nextPtr, *prevPtr;
+				/* All threads that are currently waiting on
+				 * an event have their ThreadSpecificData
+				 * structure on a doubly-linked listed formed
+				 * from these pointers. */
+    /* End notifierLock section */
+
+    OSSpinLock tsdLock;		/* Must hold this lock before acessing the
+				 * following fields from more than one
+				 * thread. */
+    /* Start tsdLock section */
+    SelectMasks checkMasks;	/* This structure is used to build up the
+				 * masks to be used in the next call to
+				 * select. Bits are set in response to calls
+				 * to Tcl_CreateFileHandler. */
+    SelectMasks readyMasks;	/* This array reflects the readable/writable
+				 * conditions that were found to exist by the
+				 * last call to select. */
+    int numFdBits;		/* Number of valid bits in checkMasks (one
+				 * more than highest fd for which
+				 * Tcl_WatchFile has been called). */
+    int polling;		/* True if this thread is polling for
+				 * events. */
+    CFRunLoopRef runLoop;	/* This thread's CFRunLoop, needs to be woken
+				 * up whenever the runLoopSource is
+				 * signaled. */
+    CFRunLoopSourceRef runLoopSource;
+				/* Any other thread alerts a notifier that an
+				 * event is ready to be processed by signaling
+				 * this CFRunLoopSource. */
+    CFRunLoopObserverRef runLoopObserver, runLoopObserverTcl;
+				/* Adds/removes this thread from waitingList
+				 * when the CFRunLoop starts/stops. */
+    CFRunLoopTimerRef runLoopTimer;
+				/* Wakes up CFRunLoop after given timeout when
+				 * running embedded. */
+    /* End tsdLock section */
+
+    CFTimeInterval waitTime;	/* runLoopTimer wait time when running
+				 * embedded. */
+    ASLCLIENT_DECL;
+} ThreadSpecificData;
+
+static Tcl_ThreadDataKey dataKey;
+
+/*
+ * The following static indicates the number of threads that have initialized
+ * notifiers.
+ *
+ * You must hold the notifierInitLock before accessing this variable.
+ */
+
+static int notifierCount = 0;
+
+/*
+ * The following variable points to the head of a doubly-linked list of
+ * ThreadSpecificData structures for all threads that are currently waiting on
+ * an event.
+ *
+ * You must hold the notifierLock before accessing this list.
+ */
+
+static ThreadSpecificData *waitingListPtr = NULL;
+
+/*
+ * The notifier thread spends all its time in select() waiting for a file
+ * descriptor associated with one of the threads on the waitingListPtr list to
+ * do something interesting. But if the contents of the waitingListPtr list
+ * ever changes, we need to wake up and restart the select() system call. You
+ * can wake up the notifier thread by writing a single byte to the file
+ * descriptor defined below. This file descriptor is the input-end of a pipe
+ * and the notifier thread is listening for data on the output-end of the same
+ * pipe. Hence writing to this file descriptor will cause the select() system
+ * call to return and wake up the notifier thread.
+ *
+ * You must hold the notifierLock lock before writing to the pipe.
+ */
+
+static int triggerPipe = -1;
+static int receivePipe = -1; /* Output end of triggerPipe */
+
+/*
+ * The following static indicates if the notifier thread is running.
+ *
+ * You must hold the notifierInitLock before accessing this variable.
+ */
+
+static int notifierThreadRunning;
+
+/*
+ * This is the thread ID of the notifier thread that does select. Only valid
+ * when notifierThreadRunning is non-zero.
+ *
+ * You must hold the notifierInitLock before accessing this variable.
+ */
+
+static pthread_t notifierThread;
+
+/*
+ * Custom runloop mode for running with only the runloop source for the
+ * notifier thread.
+ */
+
+#ifndef TCL_EVENTS_ONLY_RUN_LOOP_MODE
+#define TCL_EVENTS_ONLY_RUN_LOOP_MODE	"com.tcltk.tclEventsOnlyRunLoopMode"
+#endif
+#ifdef __CONSTANT_CFSTRINGS__
+#define tclEventsOnlyRunLoopMode	CFSTR(TCL_EVENTS_ONLY_RUN_LOOP_MODE)
+#else
+static CFStringRef tclEventsOnlyRunLoopMode = NULL;
+#endif
+
+/*
+ * CFTimeInterval to wait forever.
+ */
+
+#define CF_TIMEINTERVAL_FOREVER 5.05e8
+
+/*
+ * Static routines defined in this file.
+ */
+
+static void		StartNotifierThread(void);
+static void		NotifierThreadProc(ClientData clientData)
+			    __attribute__ ((__noreturn__));
+static int		FileHandlerEventProc(Tcl_Event *evPtr, int flags);
+static void		TimerWakeUp(CFRunLoopTimerRef timer, void *info);
+static void		QueueFileEvents(void *info);
+static void		UpdateWaitingListAndServiceEvents(
+			    CFRunLoopObserverRef observer,
+			    CFRunLoopActivity activity, void *info);
+static int		OnOffWaitingList(ThreadSpecificData *tsdPtr,
+			    int onList, int signalNotifier);
+
+#ifdef HAVE_PTHREAD_ATFORK
+static int atForkInit = 0;
+static void		AtForkPrepare(void);
+static void		AtForkParent(void);
+static void		AtForkChild(void);
+#if defined(HAVE_WEAK_IMPORT) && MAC_OS_X_VERSION_MIN_REQUIRED < 1040
+/* Support for weakly importing pthread_atfork. */
+#define WEAK_IMPORT_PTHREAD_ATFORK
+extern int		pthread_atfork(void (*prepare)(void),
+			    void (*parent)(void), void (*child)(void))
+			    WEAK_IMPORT_ATTRIBUTE;
+#define MayUsePthreadAtfork()	(pthread_atfork != NULL)
+#else
+#define MayUsePthreadAtfork()	(1)
+#endif /* HAVE_WEAK_IMPORT */
+
+/*
+ * On Darwin 9 and later, it is not possible to call CoreFoundation after
+ * a fork.
+ */
+
+#if !defined(MAC_OS_X_VERSION_MIN_REQUIRED) || \
+	MAC_OS_X_VERSION_MIN_REQUIRED < 1050
+MODULE_SCOPE long tclMacOSXDarwinRelease;
+#define noCFafterFork	(tclMacOSXDarwinRelease >= 9)
+#else /* MAC_OS_X_VERSION_MIN_REQUIRED */
+#define noCFafterFork	1
+#endif /* MAC_OS_X_VERSION_MIN_REQUIRED */
+#endif /* HAVE_PTHREAD_ATFORK */
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_InitNotifier --
+ *
+ *	Initializes the platform specific notifier state.
+ *
+ * Results:
+ *	Returns a handle to the notifier state for this thread.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+ClientData
+Tcl_InitNotifier(void)
+{
+    ThreadSpecificData *tsdPtr;
+
+    if (tclNotifierHooks.initNotifierProc) {
+	return tclNotifierHooks.initNotifierProc();
+    }
+
+    tsdPtr = TCL_TSD_INIT(&dataKey);
+
+#ifdef WEAK_IMPORT_SPINLOCKLOCK
+    /*
+     * Initialize support for weakly imported spinlock API.
+     */
+
+    if (pthread_once(&spinLockLockInitControl, SpinLockLockInit)) {
+	Tcl_Panic("Tcl_InitNotifier: pthread_once failed");
+    }
+#endif
+
+#ifndef __CONSTANT_CFSTRINGS__
+    if (!tclEventsOnlyRunLoopMode) {
+	tclEventsOnlyRunLoopMode = CFSTR(TCL_EVENTS_ONLY_RUN_LOOP_MODE);
+    }
+#endif
+
+    /*
+     * Initialize CFRunLoopSource and add it to CFRunLoop of this thread.
+     */
+
+    if (!tsdPtr->runLoop) {
+	CFRunLoopRef runLoop = CFRunLoopGetCurrent();
+	CFRunLoopSourceRef runLoopSource;
+	CFRunLoopSourceContext runLoopSourceContext;
+	CFRunLoopObserverContext runLoopObserverContext;
+	CFRunLoopObserverRef runLoopObserver, runLoopObserverTcl;
+
+	bzero(&runLoopSourceContext, sizeof(CFRunLoopSourceContext));
+	runLoopSourceContext.info = tsdPtr;
+	runLoopSourceContext.perform = QueueFileEvents;
+	runLoopSource = CFRunLoopSourceCreate(NULL, LONG_MIN,
+		&runLoopSourceContext);
+	if (!runLoopSource) {
+	    Tcl_Panic("Tcl_InitNotifier: could not create CFRunLoopSource");
+	}
+	CFRunLoopAddSource(runLoop, runLoopSource, kCFRunLoopCommonModes);
+	CFRunLoopAddSource(runLoop, runLoopSource, tclEventsOnlyRunLoopMode);
+
+	bzero(&runLoopObserverContext, sizeof(CFRunLoopObserverContext));
+	runLoopObserverContext.info = tsdPtr;
+	runLoopObserver = CFRunLoopObserverCreate(NULL,
+		kCFRunLoopEntry|kCFRunLoopExit|kCFRunLoopBeforeWaiting, TRUE,
+		LONG_MIN, UpdateWaitingListAndServiceEvents,
+		&runLoopObserverContext);
+	if (!runLoopObserver) {
+	    Tcl_Panic("Tcl_InitNotifier: could not create "
+		    "CFRunLoopObserver");
+	}
+	CFRunLoopAddObserver(runLoop, runLoopObserver, kCFRunLoopCommonModes);
+
+	/*
+	 * Create a second CFRunLoopObserver with the same callback as above
+	 * for the tclEventsOnlyRunLoopMode to ensure that the callback can be
+	 * re-entered via Tcl_ServiceAll() in the kCFRunLoopBeforeWaiting case
+	 * (CFRunLoop prevents observer callback re-entry of a given observer
+	 * instance).
+	 */
+
+	runLoopObserverTcl = CFRunLoopObserverCreate(NULL,
+		kCFRunLoopEntry|kCFRunLoopExit|kCFRunLoopBeforeWaiting, TRUE,
+		LONG_MIN, UpdateWaitingListAndServiceEvents,
+		&runLoopObserverContext);
+	if (!runLoopObserverTcl) {
+	    Tcl_Panic("Tcl_InitNotifier: could not create "
+		    "CFRunLoopObserver");
+	}
+	CFRunLoopAddObserver(runLoop, runLoopObserverTcl,
+		tclEventsOnlyRunLoopMode);
+
+	tsdPtr->runLoop = runLoop;
+	tsdPtr->runLoopSource = runLoopSource;
+	tsdPtr->runLoopObserver = runLoopObserver;
+	tsdPtr->runLoopObserverTcl = runLoopObserverTcl;
+	tsdPtr->runLoopTimer = NULL;
+	tsdPtr->waitTime = CF_TIMEINTERVAL_FOREVER;
+	tsdPtr->tsdLock = SPINLOCK_INIT;
+    }
+
+    LOCK_NOTIFIER_INIT;
+#ifdef HAVE_PTHREAD_ATFORK
+    /*
+     * Install pthread_atfork handlers to reinitialize the notifier in the
+     * child of a fork.
+     */
+
+    if (MayUsePthreadAtfork() && !atForkInit) {
+	int result = pthread_atfork(AtForkPrepare, AtForkParent, AtForkChild);
+
+	if (result) {
+	    Tcl_Panic("Tcl_InitNotifier: pthread_atfork failed");
+	}
+	atForkInit = 1;
+    }
+#endif /* HAVE_PTHREAD_ATFORK */
+    if (notifierCount == 0) {
+	int fds[2], status;
+
+	/*
+	 * Initialize trigger pipe.
+	 */
+
+	if (pipe(fds) != 0) {
+	    Tcl_Panic("Tcl_InitNotifier: could not create trigger pipe");
+	}
+
+	status = fcntl(fds[0], F_GETFL);
+	status |= O_NONBLOCK;
+	if (fcntl(fds[0], F_SETFL, status) < 0) {
+	    Tcl_Panic("Tcl_InitNotifier: could not make receive pipe non "
+		    "blocking");
+	}
+	status = fcntl(fds[1], F_GETFL);
+	status |= O_NONBLOCK;
+	if (fcntl(fds[1], F_SETFL, status) < 0) {
+	    Tcl_Panic("Tcl_InitNotifier: could not make trigger pipe non "
+		    "blocking");
+	}
+
+	receivePipe = fds[0];
+	triggerPipe = fds[1];
+
+	/*
+	 * Create notifier thread lazily in Tcl_WaitForEvent() to avoid
+	 * interfering with fork() followed immediately by execve() (we cannot
+	 * execve() when more than one thread is present).
+	 */
+
+	notifierThreadRunning = 0;
+	OPEN_NOTIFIER_LOG;
+    }
+    ENABLE_ASL;
+    notifierCount++;
+    UNLOCK_NOTIFIER_INIT;
+
+    return tsdPtr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclMacOSXNotifierAddRunLoopMode --
+ *
+ *	Add the tcl notifier RunLoop source, observer and timer (if any)
+ *	to the given RunLoop mode.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclMacOSXNotifierAddRunLoopMode(
+    const void *runLoopMode)
+{
+    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+    CFStringRef mode = (CFStringRef) runLoopMode;
+
+    if (tsdPtr->runLoop) {
+	CFRunLoopAddSource(tsdPtr->runLoop, tsdPtr->runLoopSource, mode);
+	CFRunLoopAddObserver(tsdPtr->runLoop, tsdPtr->runLoopObserver, mode);
+	if (tsdPtr->runLoopTimer) {
+	    CFRunLoopAddTimer(tsdPtr->runLoop, tsdPtr->runLoopTimer, mode);
+	}
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * StartNotifierThread --
+ *
+ *	Start notifier thread if necessary.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+StartNotifierThread(void)
+{
+    LOCK_NOTIFIER_INIT;
+    if (!notifierCount) {
+	Tcl_Panic("StartNotifierThread: notifier not initialized");
+    }
+    if (!notifierThreadRunning) {
+	int result;
+	pthread_attr_t attr;
+
+	pthread_attr_init(&attr);
+	pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
+	pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
+	pthread_attr_setstacksize(&attr, 60 * 1024);
+	result = pthread_create(&notifierThread, &attr,
+		(void * (*)(void *))NotifierThreadProc, NULL);
+	pthread_attr_destroy(&attr);
+	if (result) {
+	    Tcl_Panic("StartNotifierThread: unable to start notifier thread");
+	}
+	notifierThreadRunning = 1;
+    }
+    UNLOCK_NOTIFIER_INIT;
+}
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_FinalizeNotifier --
+ *
+ *	This function is called to cleanup the notifier state before a thread
+ *	is terminated.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	May terminate the background notifier thread if this is the last
+ *	notifier instance.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_FinalizeNotifier(
+    ClientData clientData)		/* Not used. */
+{
+    ThreadSpecificData *tsdPtr;
+
+    if (tclNotifierHooks.finalizeNotifierProc) {
+	tclNotifierHooks.finalizeNotifierProc(clientData);
+	return;
+    }
+
+    tsdPtr = TCL_TSD_INIT(&dataKey);
+
+    LOCK_NOTIFIER_INIT;
+    notifierCount--;
+    DISABLE_ASL;
+
+    /*
+     * If this is the last thread to use the notifier, close the notifier pipe
+     * and wait for the background thread to terminate.
+     */
+
+    if (notifierCount == 0) {
+	if (triggerPipe != -1) {
+	    /*
+	     * Send "q" message to the notifier thread so that it will
+	     * terminate. The notifier will return from its call to select()
+	     * and notice that a "q" message has arrived, it will then close
+	     * its side of the pipe and terminate its thread. Note the we can
+	     * not just close the pipe and check for EOF in the notifier
+	     * thread because if a background child process was created with
+	     * exec, select() would not register the EOF on the pipe until the
+	     * child processes had terminated. [Bug: 4139] [Bug 1222872]
+	     */
+
+	    write(triggerPipe, "q", 1);
+	    close(triggerPipe);
+
+	    if (notifierThreadRunning) {
+		int result = pthread_join(notifierThread, NULL);
+
+		if (result) {
+		    Tcl_Panic("Tcl_FinalizeNotifier: unable to join notifier "
+			    "thread");
+		}
+		notifierThreadRunning = 0;
+	    }
+
+	    close(receivePipe);
+	    triggerPipe = -1;
+	}
+	CLOSE_NOTIFIER_LOG;
+    }
+    UNLOCK_NOTIFIER_INIT;
+
+    LOCK_NOTIFIER_TSD;		/* For concurrency with Tcl_AlertNotifier */
+    if (tsdPtr->runLoop) {
+	tsdPtr->runLoop = NULL;
+
+	/*
+	 * Remove runLoopSource, runLoopObserver and runLoopTimer from all
+	 * CFRunLoops.
+	 */
+
+	CFRunLoopSourceInvalidate(tsdPtr->runLoopSource);
+	CFRelease(tsdPtr->runLoopSource);
+	tsdPtr->runLoopSource = NULL;
+	CFRunLoopObserverInvalidate(tsdPtr->runLoopObserver);
+	CFRelease(tsdPtr->runLoopObserver);
+	tsdPtr->runLoopObserver = NULL;
+	CFRunLoopObserverInvalidate(tsdPtr->runLoopObserverTcl);
+	CFRelease(tsdPtr->runLoopObserverTcl);
+	tsdPtr->runLoopObserverTcl = NULL;
+	if (tsdPtr->runLoopTimer) {
+	    CFRunLoopTimerInvalidate(tsdPtr->runLoopTimer);
+	    CFRelease(tsdPtr->runLoopTimer);
+	    tsdPtr->runLoopTimer = NULL;
+	}
+    }
+    UNLOCK_NOTIFIER_TSD;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_AlertNotifier --
+ *
+ *	Wake up the specified notifier from any thread. This routine is called
+ *	by the platform independent notifier code whenever the Tcl_ThreadAlert
+ *	routine is called. This routine is guaranteed not to be called on a
+ *	given notifier after Tcl_FinalizeNotifier is called for that notifier.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Signals the notifier condition variable for the specified notifier.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_AlertNotifier(
+    ClientData clientData)
+{
+    ThreadSpecificData *tsdPtr = clientData;
+
+    if (tclNotifierHooks.alertNotifierProc) {
+	tclNotifierHooks.alertNotifierProc(clientData);
+	return;
+    }
+
+    LOCK_NOTIFIER_TSD;
+    if (tsdPtr->runLoop) {
+	CFRunLoopSourceSignal(tsdPtr->runLoopSource);
+	CFRunLoopWakeUp(tsdPtr->runLoop);
+    }
+    UNLOCK_NOTIFIER_TSD;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_SetTimer --
+ *
+ *	This function sets the current notifier timer value.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Replaces any previous timer.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_SetTimer(
+    const Tcl_Time *timePtr)		/* Timeout value, may be NULL. */
+{
+    ThreadSpecificData *tsdPtr;
+    CFRunLoopTimerRef runLoopTimer;
+    CFTimeInterval waitTime;
+
+    if (tclNotifierHooks.setTimerProc) {
+	tclNotifierHooks.setTimerProc(timePtr);
+	return;
+    }
+
+    tsdPtr = TCL_TSD_INIT(&dataKey);
+    runLoopTimer = tsdPtr->runLoopTimer;
+    if (!runLoopTimer) {
+	return;
+    }
+    if (timePtr) {
+	Tcl_Time vTime = *timePtr;
+
+	if (vTime.sec != 0 || vTime.usec != 0) {
+	    tclScaleTimeProcPtr(&vTime, tclTimeClientData);
+	    waitTime = vTime.sec + 1.0e-6 * vTime.usec;
+	} else {
+	    waitTime = 0;
+	}
+    } else {
+	waitTime = CF_TIMEINTERVAL_FOREVER;
+    }
+    tsdPtr->waitTime = waitTime;
+    CFRunLoopTimerSetNextFireDate(runLoopTimer,
+	    CFAbsoluteTimeGetCurrent() + waitTime);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TimerWakeUp --
+ *
+ *	CFRunLoopTimer callback.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+TimerWakeUp(
+    CFRunLoopTimerRef timer,
+    void *info)
+{
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_ServiceModeHook --
+ *
+ *	This function is invoked whenever the service mode changes.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_ServiceModeHook(
+    int mode)			/* Either TCL_SERVICE_ALL, or
+				 * TCL_SERVICE_NONE. */
+{
+    ThreadSpecificData *tsdPtr;
+
+    if (tclNotifierHooks.serviceModeHookProc) {
+	tclNotifierHooks.serviceModeHookProc(mode);
+	return;
+    }
+
+    tsdPtr = TCL_TSD_INIT(&dataKey);
+
+    if (mode == TCL_SERVICE_ALL && !tsdPtr->runLoopTimer) {
+	if (!tsdPtr->runLoop) {
+	    Tcl_Panic("Tcl_ServiceModeHook: Notifier not initialized");
+	}
+	tsdPtr->runLoopTimer = CFRunLoopTimerCreate(NULL,
+		CFAbsoluteTimeGetCurrent() + CF_TIMEINTERVAL_FOREVER,
+		CF_TIMEINTERVAL_FOREVER, 0, 0, TimerWakeUp, NULL);
+	if (tsdPtr->runLoopTimer) {
+	    CFRunLoopAddTimer(tsdPtr->runLoop, tsdPtr->runLoopTimer,
+		    kCFRunLoopCommonModes);
+	    StartNotifierThread();
+	}
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_CreateFileHandler --
+ *
+ *	This function registers a file handler with the select notifier.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Creates a new file handler structure.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_CreateFileHandler(
+    int fd,			/* Handle of stream to watch. */
+    int mask,			/* OR'ed combination of TCL_READABLE,
+				 * TCL_WRITABLE, and TCL_EXCEPTION: indicates
+				 * conditions under which proc should be
+				 * called. */
+    Tcl_FileProc *proc,		/* Function to call for each selected
+				 * event. */
+    ClientData clientData)	/* Arbitrary data to pass to proc. */
+{
+    ThreadSpecificData *tsdPtr;
+    FileHandler *filePtr;
+
+    if (tclNotifierHooks.createFileHandlerProc) {
+	tclNotifierHooks.createFileHandlerProc(fd, mask, proc, clientData);
+	return;
+    }
+
+    tsdPtr = TCL_TSD_INIT(&dataKey);
+
+    for (filePtr = tsdPtr->firstFileHandlerPtr; filePtr != NULL;
+	    filePtr = filePtr->nextPtr) {
+	if (filePtr->fd == fd) {
+	    break;
+	}
+    }
+    if (filePtr == NULL) {
+	filePtr = ckalloc(sizeof(FileHandler));
+	filePtr->fd = fd;
+	filePtr->readyMask = 0;
+	filePtr->nextPtr = tsdPtr->firstFileHandlerPtr;
+	tsdPtr->firstFileHandlerPtr = filePtr;
+    }
+    filePtr->proc = proc;
+    filePtr->clientData = clientData;
+    filePtr->mask = mask;
+
+    /*
+     * Update the check masks for this file.
+     */
+
+    LOCK_NOTIFIER_TSD;
+    if (mask & TCL_READABLE) {
+	FD_SET(fd, &tsdPtr->checkMasks.readable);
+    } else {
+	FD_CLR(fd, &tsdPtr->checkMasks.readable);
+    }
+    if (mask & TCL_WRITABLE) {
+	FD_SET(fd, &tsdPtr->checkMasks.writable);
+    } else {
+	FD_CLR(fd, &tsdPtr->checkMasks.writable);
+    }
+    if (mask & TCL_EXCEPTION) {
+	FD_SET(fd, &tsdPtr->checkMasks.exceptional);
+    } else {
+	FD_CLR(fd, &tsdPtr->checkMasks.exceptional);
+    }
+    if (tsdPtr->numFdBits <= fd) {
+	tsdPtr->numFdBits = fd+1;
+    }
+    UNLOCK_NOTIFIER_TSD;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_DeleteFileHandler --
+ *
+ *	Cancel a previously-arranged callback arrangement for a file.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	If a callback was previously registered on file, remove it.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_DeleteFileHandler(
+    int fd)			/* Stream id for which to remove callback
+				 * function. */
+{
+    FileHandler *filePtr, *prevPtr;
+    int i, numFdBits;
+    ThreadSpecificData *tsdPtr;
+
+    if (tclNotifierHooks.deleteFileHandlerProc) {
+	tclNotifierHooks.deleteFileHandlerProc(fd);
+	return;
+    }
+
+    tsdPtr = TCL_TSD_INIT(&dataKey);
+    numFdBits = -1;
+
+    /*
+     * Find the entry for the given file (and return if there isn't one).
+     */
+
+    for (prevPtr = NULL, filePtr = tsdPtr->firstFileHandlerPtr; ;
+	    prevPtr = filePtr, filePtr = filePtr->nextPtr) {
+	if (filePtr == NULL) {
+	    return;
+	}
+	if (filePtr->fd == fd) {
+	    break;
+	}
+    }
+
+    /*
+     * Find current max fd.
+     */
+
+    if (fd+1 == tsdPtr->numFdBits) {
+	numFdBits = 0;
+	for (i = fd-1; i >= 0; i--) {
+	    if (FD_ISSET(i, &tsdPtr->checkMasks.readable)
+		    || FD_ISSET(i, &tsdPtr->checkMasks.writable)
+		    || FD_ISSET(i, &tsdPtr->checkMasks.exceptional)) {
+		numFdBits = i+1;
+		break;
+	    }
+	}
+    }
+
+    LOCK_NOTIFIER_TSD;
+    if (numFdBits != -1) {
+	tsdPtr->numFdBits = numFdBits;
+    }
+
+    /*
+     * Update the check masks for this file.
+     */
+
+    if (filePtr->mask & TCL_READABLE) {
+	FD_CLR(fd, &tsdPtr->checkMasks.readable);
+    }
+    if (filePtr->mask & TCL_WRITABLE) {
+	FD_CLR(fd, &tsdPtr->checkMasks.writable);
+    }
+    if (filePtr->mask & TCL_EXCEPTION) {
+	FD_CLR(fd, &tsdPtr->checkMasks.exceptional);
+    }
+    UNLOCK_NOTIFIER_TSD;
+
+    /*
+     * Clean up information in the callback record.
+     */
+
+    if (prevPtr == NULL) {
+	tsdPtr->firstFileHandlerPtr = filePtr->nextPtr;
+    } else {
+	prevPtr->nextPtr = filePtr->nextPtr;
+    }
+    ckfree(filePtr);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * FileHandlerEventProc --
+ *
+ *	This function is called by Tcl_ServiceEvent when a file event reaches
+ *	the front of the event queue. This function is responsible for
+ *	actually handling the event by invoking the callback for the file
+ *	handler.
+ *
+ * Results:
+ *	Returns 1 if the event was handled, meaning it should be removed from
+ *	the queue. Returns 0 if the event was not handled, meaning it should
+ *	stay on the queue. The only time the event isn't handled is if the
+ *	TCL_FILE_EVENTS flag bit isn't set.
+ *
+ * Side effects:
+ *	Whatever the file handler's callback function does.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+FileHandlerEventProc(
+    Tcl_Event *evPtr,		/* Event to service. */
+    int flags)			/* Flags that indicate what events to handle,
+				 * such as TCL_FILE_EVENTS. */
+{
+    int mask;
+    FileHandler *filePtr;
+    FileHandlerEvent *fileEvPtr = (FileHandlerEvent *) evPtr;
+    ThreadSpecificData *tsdPtr;
+
+    if (!(flags & TCL_FILE_EVENTS)) {
+	return 0;
+    }
+
+    /*
+     * Search through the file handlers to find the one whose handle matches
+     * the event. We do this rather than keeping a pointer to the file handler
+     * directly in the event, so that the handler can be deleted while the
+     * event is queued without leaving a dangling pointer.
+     */
+
+    tsdPtr = TCL_TSD_INIT(&dataKey);
+    for (filePtr = tsdPtr->firstFileHandlerPtr; filePtr != NULL;
+	    filePtr = filePtr->nextPtr) {
+	if (filePtr->fd != fileEvPtr->fd) {
+	    continue;
+	}
+
+	/*
+	 * The code is tricky for two reasons:
+	 * 1. The file handler's desired events could have changed since the
+	 *    time when the event was queued, so AND the ready mask with the
+	 *    desired mask.
+	 * 2. The file could have been closed and re-opened since the time
+	 *    when the event was queued. This is why the ready mask is stored
+	 *    in the file handler rather than the queued event: it will be
+	 *    zeroed when a new file handler is created for the newly opened
+	 *    file.
+	 */
+
+	mask = filePtr->readyMask & filePtr->mask;
+	filePtr->readyMask = 0;
+	if (mask != 0) {
+	    LOCK_NOTIFIER_TSD;
+	    if (mask & TCL_READABLE) {
+		FD_CLR(filePtr->fd, &tsdPtr->readyMasks.readable);
+	    }
+	    if (mask & TCL_WRITABLE) {
+		FD_CLR(filePtr->fd, &tsdPtr->readyMasks.writable);
+	    }
+	    if (mask & TCL_EXCEPTION) {
+		FD_CLR(filePtr->fd, &tsdPtr->readyMasks.exceptional);
+	    }
+	    UNLOCK_NOTIFIER_TSD;
+	    filePtr->proc(filePtr->clientData, mask);
+	}
+	break;
+    }
+    return 1;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_WaitForEvent --
+ *
+ *	This function is called by Tcl_DoOneEvent to wait for new events on
+ *	the message queue. If the block time is 0, then Tcl_WaitForEvent just
+ *	polls without blocking.
+ *
+ * Results:
+ *	Returns 0 if a tcl event or timeout ocurred and 1 if a non-tcl
+ *	CFRunLoop source was processed.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_WaitForEvent(
+    const Tcl_Time *timePtr)		/* Maximum block time, or NULL. */
+{
+    int result, polling, runLoopRunning;
+    CFTimeInterval waitTime;
+    SInt32 runLoopStatus;
+    ThreadSpecificData *tsdPtr;
+
+    if (tclNotifierHooks.waitForEventProc) {
+	return tclNotifierHooks.waitForEventProc(timePtr);
+    }
+    result = -1;
+    polling = 0;
+    waitTime = CF_TIMEINTERVAL_FOREVER;
+    tsdPtr = TCL_TSD_INIT(&dataKey);
+
+    if (!tsdPtr->runLoop) {
+	Tcl_Panic("Tcl_WaitForEvent: Notifier not initialized");
+    }
+
+    if (timePtr) {
+	Tcl_Time vTime = *timePtr;
+
+	/*
+	 * TIP #233 (Virtualized Time). Is virtual time in effect? And do we
+	 * actually have something to scale? If yes to both then we call the
+	 * handler to do this scaling.
+	 */
+
+	if (vTime.sec != 0 || vTime.usec != 0) {
+	    tclScaleTimeProcPtr(&vTime, tclTimeClientData);
+	    waitTime = vTime.sec + 1.0e-6 * vTime.usec;
+	} else {
+	    /*
+	     * Polling: pretend to wait for files and tell the notifier thread
+	     * what we are doing. The notifier thread makes sure it goes
+	     * through select with its select mask in the same state as ours
+	     * currently is. We block until that happens.
+	     */
+
+	    polling = 1;
+	}
+    }
+
+    StartNotifierThread();
+
+    LOCK_NOTIFIER_TSD;
+    tsdPtr->polling = polling;
+    UNLOCK_NOTIFIER_TSD;
+    tsdPtr->runLoopSourcePerformed = 0;
+
+    /*
+     * If the Tcl runloop is already running (e.g. if Tcl_WaitForEvent was
+     * called recursively) or is servicing events via the runloop observer,
+     * re-run it in a custom runloop mode containing only the source for the
+     * notifier thread, otherwise wakeups from other sources added to the
+     * common runloop modes might get lost or 3rd party event handlers might
+     * get called when they do not expect to be.
+     */
+
+    runLoopRunning = tsdPtr->runLoopRunning;
+    tsdPtr->runLoopRunning = 1;
+    runLoopStatus = CFRunLoopRunInMode(tsdPtr->runLoopServicingEvents ||
+	    runLoopRunning ? tclEventsOnlyRunLoopMode : kCFRunLoopDefaultMode,
+	    waitTime, TRUE);
+    tsdPtr->runLoopRunning = runLoopRunning;
+
+    LOCK_NOTIFIER_TSD;
+    tsdPtr->polling = 0;
+    UNLOCK_NOTIFIER_TSD;
+    switch (runLoopStatus) {
+    case kCFRunLoopRunFinished:
+	Tcl_Panic("Tcl_WaitForEvent: CFRunLoop finished");
+	break;
+    case kCFRunLoopRunTimedOut:
+	QueueFileEvents(tsdPtr);
+	result = 0;
+	break;
+    case kCFRunLoopRunStopped:
+    case kCFRunLoopRunHandledSource:
+	result = tsdPtr->runLoopSourcePerformed ? 0 : 1;
+	break;
+    }
+
+    return result;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * QueueFileEvents --
+ *
+ *	CFRunLoopSource callback for queueing file events.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Queues file events that are detected by the select.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+QueueFileEvents(
+    void *info)
+{
+    SelectMasks readyMasks;
+    FileHandler *filePtr;
+    ThreadSpecificData *tsdPtr = info;
+
+    /*
+     * Queue all detected file events.
+     */
+
+    LOCK_NOTIFIER_TSD;
+    FD_COPY(&tsdPtr->readyMasks.readable, &readyMasks.readable);
+    FD_COPY(&tsdPtr->readyMasks.writable, &readyMasks.writable);
+    FD_COPY(&tsdPtr->readyMasks.exceptional, &readyMasks.exceptional);
+    FD_ZERO(&tsdPtr->readyMasks.readable);
+    FD_ZERO(&tsdPtr->readyMasks.writable);
+    FD_ZERO(&tsdPtr->readyMasks.exceptional);
+    UNLOCK_NOTIFIER_TSD;
+    tsdPtr->runLoopSourcePerformed = 1;
+
+    for (filePtr = tsdPtr->firstFileHandlerPtr; (filePtr != NULL);
+	    filePtr = filePtr->nextPtr) {
+	int mask = 0;
+
+	if (FD_ISSET(filePtr->fd, &readyMasks.readable)) {
+	    mask |= TCL_READABLE;
+	}
+	if (FD_ISSET(filePtr->fd, &readyMasks.writable)) {
+	    mask |= TCL_WRITABLE;
+	}
+	if (FD_ISSET(filePtr->fd, &readyMasks.exceptional)) {
+	    mask |= TCL_EXCEPTION;
+	}
+	if (!mask) {
+	    continue;
+	}
+
+	/*
+	 * Don't bother to queue an event if the mask was previously non-zero
+	 * since an event must still be on the queue.
+	 */
+
+	if (filePtr->readyMask == 0) {
+	    FileHandlerEvent *fileEvPtr = ckalloc(sizeof(FileHandlerEvent));
+
+	    fileEvPtr->header.proc = FileHandlerEventProc;
+	    fileEvPtr->fd = filePtr->fd;
+	    Tcl_QueueEvent((Tcl_Event *) fileEvPtr, TCL_QUEUE_TAIL);
+	}
+	filePtr->readyMask = mask;
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * UpdateWaitingListAndServiceEvents --
+ *
+ *	CFRunLoopObserver callback for updating waitingList and
+ *	servicing Tcl events.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+UpdateWaitingListAndServiceEvents(
+    CFRunLoopObserverRef observer,
+    CFRunLoopActivity activity,
+    void *info)
+{
+    ThreadSpecificData *tsdPtr = info;
+
+    if (tsdPtr->sleeping) {
+	return;
+    }
+    switch (activity) {
+    case kCFRunLoopEntry:
+	tsdPtr->runLoopNestingLevel++;
+	if (tsdPtr->numFdBits > 0 || tsdPtr->polling) {
+	    LOCK_NOTIFIER;
+	    if (!OnOffWaitingList(tsdPtr, 1, 1) && tsdPtr->polling) {
+		write(triggerPipe, "", 1);
+	    }
+	    UNLOCK_NOTIFIER;
+	}
+	break;
+    case kCFRunLoopExit:
+	if (tsdPtr->runLoopNestingLevel == 1) {
+	    LOCK_NOTIFIER;
+	    OnOffWaitingList(tsdPtr, 0, 1);
+	    UNLOCK_NOTIFIER;
+	}
+	tsdPtr->runLoopNestingLevel--;
+	break;
+    case kCFRunLoopBeforeWaiting:
+	if (tsdPtr->runLoopTimer && !tsdPtr->runLoopServicingEvents &&
+		(tsdPtr->runLoopNestingLevel > 1
+			|| !tsdPtr->runLoopRunning)) {
+	    tsdPtr->runLoopServicingEvents = 1;
+            /* This call seems to simply force event processing through and prevents hangups that have long been observed with Tk-Cocoa.  */
+	    Tcl_ServiceAll();
+	    tsdPtr->runLoopServicingEvents = 0;
+	}
+	break;
+    default:
+	break;
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * OnOffWaitingList --
+ *
+ *	Add/remove the specified thread to/from the global waitingList and
+ *	optionally signal the notifier.
+ *
+ *	!!! Requires notifierLock to be held !!!
+ *
+ * Results:
+ *	Boolean indicating whether the waitingList was changed.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+OnOffWaitingList(
+    ThreadSpecificData *tsdPtr,
+    int onList,
+    int signalNotifier)
+{
+    int changeWaitingList;
+
+#ifdef TCL_MAC_DEBUG_NOTIFIER
+    if (SpinLockTry(&notifierLock)) {
+	Tcl_Panic("OnOffWaitingList: notifierLock unlocked");
+    }
+#endif
+    changeWaitingList = (!onList ^ !tsdPtr->onList);
+    if (changeWaitingList) {
+	if (onList) {
+	    tsdPtr->nextPtr = waitingListPtr;
+	    if (waitingListPtr) {
+		waitingListPtr->prevPtr = tsdPtr;
+	    }
+	    tsdPtr->prevPtr = NULL;
+	    waitingListPtr = tsdPtr;
+	    tsdPtr->onList = 1;
+	} else {
+	    if (tsdPtr->prevPtr) {
+		tsdPtr->prevPtr->nextPtr = tsdPtr->nextPtr;
+	    } else {
+		waitingListPtr = tsdPtr->nextPtr;
+	    }
+	    if (tsdPtr->nextPtr) {
+		tsdPtr->nextPtr->prevPtr = tsdPtr->prevPtr;
+	    }
+	    tsdPtr->nextPtr = tsdPtr->prevPtr = NULL;
+	    tsdPtr->onList = 0;
+	}
+	if (signalNotifier) {
+	    write(triggerPipe, "", 1);
+	}
+    }
+
+    return changeWaitingList;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * Tcl_Sleep --
+ *
+ *	Delay execution for the specified number of milliseconds.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	Time passes.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+Tcl_Sleep(
+    int ms)			/* Number of milliseconds to sleep. */
+{
+    Tcl_Time vdelay;
+    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+
+    if (ms <= 0) {
+	return;
+    }
+
+    /*
+     * TIP #233: Scale from virtual time to real-time.
+     */
+
+    vdelay.sec = ms / 1000;
+    vdelay.usec = (ms % 1000) * 1000;
+    tclScaleTimeProcPtr(&vdelay, tclTimeClientData);
+
+
+    if (tsdPtr->runLoop) {
+	CFTimeInterval waitTime;
+	CFRunLoopTimerRef runLoopTimer = tsdPtr->runLoopTimer;
+	CFAbsoluteTime nextTimerFire = 0, waitEnd, now;
+	SInt32 runLoopStatus;
+
+	waitTime = vdelay.sec + 1.0e-6 * vdelay.usec;
+ 	now = CFAbsoluteTimeGetCurrent();
+	waitEnd = now + waitTime;
+
+	if (runLoopTimer) {
+	    nextTimerFire = CFRunLoopTimerGetNextFireDate(runLoopTimer);
+	    if (nextTimerFire < waitEnd) {
+		CFRunLoopTimerSetNextFireDate(runLoopTimer, now +
+			CF_TIMEINTERVAL_FOREVER);
+	    } else {
+		runLoopTimer = NULL;
+	    }
+	}
+	tsdPtr->sleeping = 1;
+	do {
+	    runLoopStatus = CFRunLoopRunInMode(kCFRunLoopDefaultMode,
+		    waitTime, FALSE);
+	    switch (runLoopStatus) {
+	    case kCFRunLoopRunFinished:
+		Tcl_Panic("Tcl_Sleep: CFRunLoop finished");
+		break;
+	    case kCFRunLoopRunStopped:
+		TclMacOSXNotifierDbgMsg("CFRunLoop stopped");
+		waitTime = waitEnd - CFAbsoluteTimeGetCurrent();
+		break;
+	    case kCFRunLoopRunTimedOut:
+		waitTime = 0;
+		break;
+	    }
+	} while (waitTime > 0);
+	tsdPtr->sleeping = 0;
+ 	if (runLoopTimer) {
+	    CFRunLoopTimerSetNextFireDate(runLoopTimer, nextTimerFire);
+	}
+    } else {
+	struct timespec waitTime;
+
+	waitTime.tv_sec = vdelay.sec;
+	waitTime.tv_nsec = vdelay.usec * 1000;
+	while (nanosleep(&waitTime, &waitTime));
+    }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclUnixWaitForFile --
+ *
+ *	This function waits synchronously for a file to become readable or
+ *	writable, with an optional timeout.
+ *
+ * Results:
+ *	The return value is an OR'ed combination of TCL_READABLE,
+ *	TCL_WRITABLE, and TCL_EXCEPTION, indicating the conditions that are
+ *	present on file at the time of the return. This function will not
+ *	return until either "timeout" milliseconds have elapsed or at least
+ *	one of the conditions given by mask has occurred for file (a return
+ *	value of 0 means that a timeout occurred). No normal events will be
+ *	serviced during the execution of this function.
+ *
+ * Side effects:
+ *	Time passes.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclUnixWaitForFile(
+    int fd,			/* Handle for file on which to wait. */
+    int mask,			/* What to wait for: OR'ed combination of
+				 * TCL_READABLE, TCL_WRITABLE, and
+				 * TCL_EXCEPTION. */
+    int timeout)		/* Maximum amount of time to wait for one of
+				 * the conditions in mask to occur, in
+				 * milliseconds. A value of 0 means don't wait
+				 * at all, and a value of -1 means wait
+				 * forever. */
+{
+    Tcl_Time abortTime = {0, 0}, now; /* silence gcc 4 warning */
+    struct timeval blockTime, *timeoutPtr;
+    int numFound, result = 0;
+    fd_set readableMask;
+    fd_set writableMask;
+    fd_set exceptionalMask;
+
+#define SET_BITS(var, bits)	((var) |= (bits))
+#define CLEAR_BITS(var, bits)	((var) &= ~(bits))
+
+#ifndef _DARWIN_C_SOURCE
+    /*
+     * Sanity check fd.
+     */
+
+    if (fd >= FD_SETSIZE) {
+	Tcl_Panic("TclUnixWaitForFile can't handle file id %d", fd);
+	/* must never get here, or select masks overrun will occur below */
+    }
+#endif
+
+    /*
+     * If there is a non-zero finite timeout, compute the time when we give
+     * up.
+     */
+
+    if (timeout > 0) {
+	Tcl_GetTime(&now);
+	abortTime.sec = now.sec + timeout/1000;
+	abortTime.usec = now.usec + (timeout%1000)*1000;
+	if (abortTime.usec >= 1000000) {
+	    abortTime.usec -= 1000000;
+	    abortTime.sec += 1;
+	}
+	timeoutPtr = &blockTime;
+    } else if (timeout == 0) {
+	timeoutPtr = &blockTime;
+	blockTime.tv_sec = 0;
+	blockTime.tv_usec = 0;
+    } else {
+	timeoutPtr = NULL;
+    }
+
+    /*
+     * Initialize the select masks.
+     */
+
+    FD_ZERO(&readableMask);
+    FD_ZERO(&writableMask);
+    FD_ZERO(&exceptionalMask);
+
+    /*
+     * Loop in a mini-event loop of our own, waiting for either the file to
+     * become ready or a timeout to occur.
+     */
+
+    while (1) {
+	if (timeout > 0) {
+	    blockTime.tv_sec = abortTime.sec - now.sec;
+	    blockTime.tv_usec = abortTime.usec - now.usec;
+	    if (blockTime.tv_usec < 0) {
+		blockTime.tv_sec -= 1;
+		blockTime.tv_usec += 1000000;
+	    }
+	    if (blockTime.tv_sec < 0) {
+		blockTime.tv_sec = 0;
+		blockTime.tv_usec = 0;
+	    }
+	}
+
+	/*
+	 * Setup the select masks for the fd.
+	 */
+
+	if (mask & TCL_READABLE) {
+	    FD_SET(fd, &readableMask);
+	}
+	if (mask & TCL_WRITABLE) {
+	    FD_SET(fd, &writableMask);
+	}
+	if (mask & TCL_EXCEPTION) {
+	    FD_SET(fd, &exceptionalMask);
+	}
+
+	/*
+	 * Wait for the event or a timeout.
+	 */
+
+	numFound = select(fd + 1, &readableMask, &writableMask,
+		&exceptionalMask, timeoutPtr);
+	if (numFound == 1) {
+	    if (FD_ISSET(fd, &readableMask)) {
+		SET_BITS(result, TCL_READABLE);
+	    }
+	    if (FD_ISSET(fd, &writableMask)) {
+		SET_BITS(result, TCL_WRITABLE);
+	    }
+	    if (FD_ISSET(fd, &exceptionalMask)) {
+		SET_BITS(result, TCL_EXCEPTION);
+	    }
+	    result &= mask;
+	    if (result) {
+		break;
+	    }
+	}
+	if (timeout == 0) {
+	    break;
+	}
+	if (timeout < 0) {
+	    continue;
+	}
+
+	/*
+	 * The select returned early, so we need to recompute the timeout.
+	 */
+
+	Tcl_GetTime(&now);
+	if ((abortTime.sec < now.sec)
+		|| (abortTime.sec==now.sec && abortTime.usec<=now.usec)) {
+	    break;
+	}
+    }
+    return result;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * NotifierThreadProc --
+ *
+ *	This routine is the initial (and only) function executed by the
+ *	special notifier thread. Its job is to wait for file descriptors to
+ *	become readable or writable or to have an exception condition and then
+ *	to notify other threads who are interested in this information by
+ *	signalling a condition variable. Other threads can signal this
+ *	notifier thread of a change in their interests by writing a single
+ *	byte to a special pipe that the notifier thread is monitoring.
+ *
+ * Result:
+ *	None. Once started, this routine never exits. It dies with the overall
+ *	process.
+ *
+ * Side effects:
+ *	The trigger pipe used to signal the notifier thread is created when
+ *	the notifier thread first starts.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+NotifierThreadProc(
+    ClientData clientData)	/* Not used. */
+{
+    ThreadSpecificData *tsdPtr;
+    fd_set readableMask, writableMask, exceptionalMask;
+    int i, numFdBits = 0, polling;
+    struct timeval poll = {0., 0.}, *timePtr;
+    char buf[2];
+
+    /*
+     * Look for file events and report them to interested threads.
+     */
+
+    while (1) {
+	FD_ZERO(&readableMask);
+	FD_ZERO(&writableMask);
+	FD_ZERO(&exceptionalMask);
+
+	/*
+	 * Compute the logical OR of the select masks from all the waiting
+	 * notifiers.
+	 */
+
+	timePtr = NULL;
+	LOCK_NOTIFIER;
+	for (tsdPtr = waitingListPtr; tsdPtr; tsdPtr = tsdPtr->nextPtr) {
+	    LOCK_NOTIFIER_TSD;
+	    for (i = tsdPtr->numFdBits-1; i >= 0; --i) {
+		if (FD_ISSET(i, &tsdPtr->checkMasks.readable)) {
+		    FD_SET(i, &readableMask);
+		}
+		if (FD_ISSET(i, &tsdPtr->checkMasks.writable)) {
+		    FD_SET(i, &writableMask);
+		}
+		if (FD_ISSET(i, &tsdPtr->checkMasks.exceptional)) {
+		    FD_SET(i, &exceptionalMask);
+		}
+	    }
+	    if (tsdPtr->numFdBits > numFdBits) {
+		numFdBits = tsdPtr->numFdBits;
+	    }
+	    polling = tsdPtr->polling;
+	    UNLOCK_NOTIFIER_TSD;
+	    if ((tsdPtr->polled = polling)) {
+		timePtr = &poll;
+	    }
+	}
+	UNLOCK_NOTIFIER;
+
+	/*
+	 * Set up the select mask to include the receive pipe.
+	 */
+
+	if (receivePipe >= numFdBits) {
+	    numFdBits = receivePipe + 1;
+	}
+	FD_SET(receivePipe, &readableMask);
+
+	if (select(numFdBits, &readableMask, &writableMask, &exceptionalMask,
+		timePtr) == -1) {
+	    /*
+	     * Try again immediately on an error.
+	     */
+
+	    continue;
+	}
+
+	/*
+	 * Alert any threads that are waiting on a ready file descriptor.
+	 */
+
+	LOCK_NOTIFIER;
+	for (tsdPtr = waitingListPtr; tsdPtr; tsdPtr = tsdPtr->nextPtr) {
+	    int found = 0;
+	    SelectMasks readyMasks, checkMasks;
+
+	    LOCK_NOTIFIER_TSD;
+	    FD_COPY(&tsdPtr->checkMasks.readable, &checkMasks.readable);
+	    FD_COPY(&tsdPtr->checkMasks.writable, &checkMasks.writable);
+	    FD_COPY(&tsdPtr->checkMasks.exceptional, &checkMasks.exceptional);
+	    UNLOCK_NOTIFIER_TSD;
+	    found = tsdPtr->polled;
+	    FD_ZERO(&readyMasks.readable);
+	    FD_ZERO(&readyMasks.writable);
+	    FD_ZERO(&readyMasks.exceptional);
+
+	    for (i = tsdPtr->numFdBits-1; i >= 0; --i) {
+		if (FD_ISSET(i, &checkMasks.readable)
+			&& FD_ISSET(i, &readableMask)) {
+		    FD_SET(i, &readyMasks.readable);
+		    found = 1;
+		}
+		if (FD_ISSET(i, &checkMasks.writable)
+			&& FD_ISSET(i, &writableMask)) {
+		    FD_SET(i, &readyMasks.writable);
+		    found = 1;
+		}
+		if (FD_ISSET(i, &checkMasks.exceptional)
+			&& FD_ISSET(i, &exceptionalMask)) {
+		    FD_SET(i, &readyMasks.exceptional);
+		    found = 1;
+		}
+	    }
+
+	    if (found) {
+		/*
+		 * Remove the ThreadSpecificData structure of this thread from
+		 * the waiting list. This prevents us from spinning
+		 * continuously on select until the other threads runs and
+		 * services the file event.
+		 */
+
+		OnOffWaitingList(tsdPtr, 0, 0);
+
+		LOCK_NOTIFIER_TSD;
+		FD_COPY(&readyMasks.readable, &tsdPtr->readyMasks.readable);
+		FD_COPY(&readyMasks.writable, &tsdPtr->readyMasks.writable);
+		FD_COPY(&readyMasks.exceptional,
+			&tsdPtr->readyMasks.exceptional);
+		UNLOCK_NOTIFIER_TSD;
+		tsdPtr->polled = 0;
+		if (tsdPtr->runLoop) {
+		    CFRunLoopSourceSignal(tsdPtr->runLoopSource);
+		    CFRunLoopWakeUp(tsdPtr->runLoop);
+		}
+	    }
+	}
+	UNLOCK_NOTIFIER;
+
+	/*
+	 * Consume the next byte from the notifier pipe if the pipe was
+	 * readable. Note that there may be multiple bytes pending, but to
+	 * avoid a race condition we only read one at a time.
+	 */
+
+	if (FD_ISSET(receivePipe, &readableMask)) {
+	    i = read(receivePipe, buf, 1);
+
+	    if ((i == 0) || ((i == 1) && (buf[0] == 'q'))) {
+		/*
+		 * Someone closed the write end of the pipe or sent us a Quit
+		 * message [Bug: 4139] and then closed the write end of the
+		 * pipe so we need to shut down the notifier thread.
+		 */
+
+		break;
+	    }
+	}
+    }
+    pthread_exit(0);
+}
+
+#ifdef HAVE_PTHREAD_ATFORK
+/*
+ *----------------------------------------------------------------------
+ *
+ * AtForkPrepare --
+ *
+ *	Lock the notifier in preparation for a fork.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+AtForkPrepare(void)
+{
+    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+
+    LOCK_NOTIFIER_INIT;
+    LOCK_NOTIFIER;
+    LOCK_NOTIFIER_TSD;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * AtForkParent --
+ *
+ *	Unlock the notifier in the parent after a fork.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+AtForkParent(void)
+{
+    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+
+    UNLOCK_NOTIFIER_TSD;
+    UNLOCK_NOTIFIER;
+    UNLOCK_NOTIFIER_INIT;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * AtForkChild --
+ *
+ *	Unlock and reinstall the notifier in the child after a fork.
+ *
+ * Results:
+ *	None.
+ *
+ * Side effects:
+ *	None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static void
+AtForkChild(void)
+{
+    ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+
+    UNLOCK_NOTIFIER_TSD;
+    UNLOCK_NOTIFIER;
+    UNLOCK_NOTIFIER_INIT;
+    if (tsdPtr->runLoop) {
+	tsdPtr->runLoop = NULL;
+	if (!noCFafterFork) {
+	    CFRunLoopSourceInvalidate(tsdPtr->runLoopSource);
+	    CFRelease(tsdPtr->runLoopSource);
+	    if (tsdPtr->runLoopTimer) {
+		CFRunLoopTimerInvalidate(tsdPtr->runLoopTimer);
+		CFRelease(tsdPtr->runLoopTimer);
+	    }
+	}
+	tsdPtr->runLoopSource = NULL;
+	tsdPtr->runLoopTimer = NULL;
+    }
+    if (notifierCount > 0) {
+	notifierCount = 1;
+	notifierThreadRunning = 0;
+
+	/*
+	 * Assume that the return value of Tcl_InitNotifier in the child will
+	 * be identical to the one stored as clientData in tclNotify.c's
+	 * ThreadSpecificData by the parent's TclInitNotifier, so discard the
+	 * return value here. This assumption may require the fork() to be
+	 * executed in the main thread of the parent, otherwise
+	 * Tcl_AlertNotifier may break in the child.
+	 */
+
+	if (!noCFafterFork) {
+	    Tcl_InitNotifier();
+	}
+    }
+}
+#endif /* HAVE_PTHREAD_ATFORK */
+
+#else /* HAVE_COREFOUNDATION */
+
+void
+TclMacOSXNotifierAddRunLoopMode(
+    const void *runLoopMode)
+{
+    Tcl_Panic("TclMacOSXNotifierAddRunLoopMode: "
+	    "Tcl not built with CoreFoundation support");
+}
+
+#endif /* HAVE_COREFOUNDATION */
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * End:
+ */
diff --git a/pkgs/README b/pkgs/README
new file mode 100644
index 0000000..159a237
--- /dev/null
+++ b/pkgs/README
@@ -0,0 +1,57 @@
+
+The 'pkgs' subdirectory of the Tcl source code distribution is meant to be
+a place where the source code distribution of Tcl packages may be placed so
+that they are built, installed, and tested along with Tcl.  As originally
+distributed, Tcl re-distributes a number of packages in this location.  The
+build systems for Tcl are written so that additional packages may be added,
+or the original packages removed in any number and still have all packages
+present get built, installed, and tested along with Tcl.
+
+In order for a package to work properly under the pkgs subdirectory, it
+needs to conform to the following conventions.
+
+  All files of the package need to be contained in (subdirs of ...) a
+  single subdirectory of the "pkgs" directrory.
+
+  In that subdirectory of "pkgs" there must be an executable file named
+  "configure".  When the program "configure" is run, it should generate
+  a file "Makefile" in the current working directory.  The "configure"
+  program should be able to accept as command line arguments all the
+  arguments that can be passed to the master unix/configure program.  It
+  should also accept the --with-tcl= and --with-tclinclude= options in
+  the conventional way.
+
+  The generated "Makefile" must be one suitable for controlling the operations
+  of a `make` program.  The following targets must be defined:
+
+    <default>:	Perform a build of the runtime components of the
+		package from sources.
+
+    install:	Copy the runtime components of the package into their
+		installed location.  Must respect the DESTDIR variable
+		for determining the installation location.
+
+    test:	Run the test suite of the package.  Must respect the
+		TCLSH_PROG, TESTFLAGS variables.
+
+    clean:	Delete all files generated by the default build target.
+
+    distclean:	Delete all generated files.
+
+    dist:	Produce a copy of the package's source code distribution.
+		Must respect the DIST_ROOT variable determining where to
+		write the generated directory.
+
+Packages that are written to make use of the Tcl Extension Architecture (TEA)
+and that make use of the tclconfig collection of support files, should
+conform to these conventions without further efforts.
+
+These conventions are subject to revision and refinement over time to
+better support the needs of the build system.  Efforts will be made to
+keep the TEA support scripts consistent with the demands of this system.
+
+In addition, it is requested that packages also support building with
+Microsoft Visual Studio tools.  This means the file win/makefile.vc
+should be included, suitable for use by the nmake program, defining the
+targets <default>, install, test, and clean.
+
diff --git a/pkgs/package.list.txt b/pkgs/package.list.txt
new file mode 100644
index 0000000..0d5dcf8
--- /dev/null
+++ b/pkgs/package.list.txt
@@ -0,0 +1,35 @@
+# This file contains the mapping of directory names to package names for
+# documentation purposes. Each non-blank non-comment line is a two-element
+# list that says a possible name of directory (multiple lines may be needed
+# because of capitalization issues) and the documentation name of the package
+# to match. Pseudo-numeric suffixes are interpreted as version numbers.
+
+# [incr Tcl]
+itcl {[incr Tcl]}
+Itcl {[incr Tcl]}
+
+# SQLite
+Sqlite SQLite3
+sqlite SQLite3
+Sqlite3 SQLite3
+sqlite3 SQLite3
+
+# Thread
+Thread Thread
+thread Thread
+
+# Tcl Database Connectivity
+tdbc TDBC
+Tdbc TDBC
+TDBC TDBC
+# Drivers for TDBC
+Tdbcmysql	tdbc::mysql
+tdbcmysql	tdbc::mysql
+Tdbcodbc	tdbc::odbc
+tdbcodbc	tdbc::odbc
+Tdbcpostgres	tdbc::postgres
+tdbcpostgres	tdbc::postgres
+Tdbcsqlite3	tdbc::sqlite3
+tdbcsqlite3	tdbc::sqlite3
+Tdbcsqlite	tdbc::sqlite3
+tdbcsqlite	tdbc::sqlite3
diff --git a/tests/README b/tests/README
new file mode 100644
index 0000000..ce2382e
--- /dev/null
+++ b/tests/README
@@ -0,0 +1,107 @@
+README -- Tcl test suite design document.
+
+Contents:
+---------
+
+    1. Introduction
+    2. Running tests
+    3. Adding tests
+    4. Incompatibilities with prior Tcl versions
+
+1. Introduction:
+----------------
+
+This directory contains a set of validation tests for the Tcl commands
+and C Library procedures for Tcl.  Each of the files whose name ends
+in ".test" is intended to fully exercise the functions in the C source
+file that corresponds to the file prefix.  The C functions and/or Tcl
+commands tested by a given file are listed in the first line of the
+file.
+
+2. Running tests:
+-----------------
+
+We recommend that you use the "test" target of Tcl's Makefile to run
+the test suite.  From the directory in which you build Tcl, simply
+type "make test".  This will create a special executable named
+tcltest in which the testing scripts will be evaluated.  To create
+the tcltest executable without running the test suite, simple type
+"make tcltest".
+
+All the configuration options of the tcltest package are available
+during a "make test" by defining the TESTFLAGS environment variable.
+For example,if you wish to run only those tests in the file append.test,
+you can type:
+
+	make test TESTFLAGS="-file append.test"
+
+For interactive testing, the Tcl Makefile provides the "runtest" target.
+Type "make runtest" in your build directory, and the tcltest executable
+will be created, if necessary, then it will run interactively.  At the
+command prompt, you may type any Tcl commands.  If you type
+"source ../tests/all.tcl", the test suite will run.  You may use the
+tcltest::configure command to configure the test suite run as an
+alternative to command line options via TESTFLAGS.  You might also
+wish to use the tcltest::testConstraint command to select the constraints
+that govern which tests are run.  See the documentation for the tcltest
+package for details.
+
+3. Adding tests:
+----------------
+
+Please see the tcltest man page for more information regarding how to
+write and run tests.
+
+Please note that the all.tcl file will source your new test file if
+the filename matches the tests/*.test pattern (as it should).  The
+names of test files that contain regression (or glass-box) tests
+should correspond to the Tcl or C code file that they are testing.
+For example, the test file for the C file "tclCmdAH.c" is
+"cmdAH.test".  Test files that contain black-box tests may not
+correspond to any Tcl or C code file so they should match the pattern
+"*_bb.test". 
+
+Be sure your new test file can be run from any working directory.
+
+Be sure no temporary files are left behind by your test file.
+Use [tcltest::makeFile], [tcltest::removeFile], and [tcltest::cleanupTests]
+properly to be sure of this.
+
+Be sure your tests can run cross-platform in both a build environment
+as well as an installation environment.  If your test file contains
+tests that should not be run in one or more of those cases, please use
+the constraints mechanism to skip those tests.
+
+4. Incompatibilities of package tcltest 2.1 with 
+   testing machinery of very old versions of Tcl:
+------------------------------------------------
+
+1) Global variables such as VERBOSE, TESTS, and testConfig of the
+   old machinery correspond to the [configure -verbose], 
+   [configure -match], and [testConstraint] commands of tcltest 2.1,
+   respectively.
+
+2) VERBOSE values were longer numeric.  [configure -verbose] values
+   are lists of keywords.
+
+3) When you run "make test", the working dir for the test suite is now
+   the one from which you called "make test", rather than the "tests"
+   directory.  This change allows for both unix and windows test
+   suites to be run simultaneously without interference with each
+   other or with existing files.  All tests must now run independently
+   of their working directory.
+
+4) The "all" file is now called "all.tcl"
+
+5) The "defs" and "defs.tcl" files no longer exist.
+
+6) Instead of creating a doAllTests file in the tests directory, to
+   run all nonPortable tests, just use the "-constraints nonPortable"
+   command line flag.  If you are running interactively, you can run
+   [tcltest::testConstraint nonPortable 1] (after loading the tcltest
+   package).
+
+7) Direct evaluation of the *.test files by the "source" command is no
+   longer recommended.  Instead, "source all.tcl" and use the "-file" and
+   "-notfile" options of tcltest::configure to control which *.test files
+   are evaluated.
diff --git a/tests/aaa_exit.test b/tests/aaa_exit.test
new file mode 100644
index 0000000..3ba5167
--- /dev/null
+++ b/tests/aaa_exit.test
@@ -0,0 +1,54 @@
+# Commands covered:  exit, emphasis on finalization hangs
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands.  Sourcing this file into Tcl runs the tests and
+# generates output for errors.  No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994-1997 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+    package require tcltest 2
+    namespace import -force ::tcltest::*
+}
+
+test exit-1.1 {normal, quick exit} {
+     set f [open "|[interpreter] << \"exec [interpreter] << {set ::env(TCL_FINALIZE_ON_EXIT) 0;exit}\"" r]
+     set aft [after 1000 {set done "Quick exit hangs !!!"}]
+     fileevent $f readable {after cancel $aft;set done OK}
+     vwait done
+     if {$done != "OK"} {
+     	fconfigure $f -blocking 0
+	close $f
+     } else {
+	if {[catch {close $f} err]} {
+	    set done "Quick exit misbehaves: $err"
+	}
+     }
+     set done
+} OK
+
+test exit-1.2 {full-finalized exit} {
+     set f [open "|[interpreter] << \"exec [interpreter] << {set ::env(TCL_FINALIZE_ON_EXIT) 1;exit}\"" r]
+     set aft [after 1000 {set done "Full-finalized exit hangs !!!"}]
+     fileevent $f readable {after cancel $aft;set done OK}
+     vwait done
+     if {$done != "OK"} {
+     	fconfigure $f -blocking 0
+	close $f
+     } else {
+	if {[catch {close $f} err]} {
+	    set done "Full-finalized exit misbehaves: $err"
+	}
+     }
+     set done
+} OK
+
+
+# cleanup
+::tcltest::cleanupTests
+return
diff --git a/tests/all.tcl b/tests/all.tcl
new file mode 100644
index 0000000..0a6f57f
--- /dev/null
+++ b/tests/all.tcl
@@ -0,0 +1,22 @@
+# all.tcl --
+#
+# This file contains a top-level script to run all of the Tcl
+# tests.  Execute it by invoking "source all.test" when running tcltest
+# in this directory.
+#
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+# Copyright (c) 2000 by Ajuba Solutions
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+package prefer latest
+package require Tcl 8.5
+package require tcltest 2.2
+namespace import tcltest::*
+configure {*}$argv -testdir [file dir [info script]]
+if {[singleProcess]} {
+    interp debug {} -frame 1
+}
+runAllTests
+proc exit args {}
diff --git a/tests/append.test b/tests/append.test
new file mode 100644
index 0000000..8fa4e61
--- /dev/null
+++ b/tests/append.test
@@ -0,0 +1,323 @@
+# Commands covered:  append lappend
+#
+# This file contains a collection of tests for one or more of the Tcl built-in
+# commands. Sourcing this file into Tcl runs the tests and generates output
+# for errors. No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994-1996 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution of
+# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+    package require tcltest 2
+    namespace import -force ::tcltest::*
+}
+unset -nocomplain x
+
+test append-1.1 {append command} {
+    unset -nocomplain x
+    list [append x 1 2 abc "long string"] $x
+} {{12abclong string} {12abclong string}}
+test append-1.2 {append command} {
+    set x ""
+    list [append x first] [append x second] [append x third] $x
+} {first firstsecond firstsecondthird firstsecondthird}
+test append-1.3 {append command} {
+    set x "abcd"
+    append x
+} abcd
+
+test append-2.1 {long appends} {
+    set x ""
+    for {set i 0} {$i < 1000} {set i [expr $i+1]} {
+	append x "foobar "
+    }
+    set y "foobar"
+    set y "$y $y $y $y $y $y $y $y $y $y"
+    set y "$y $y $y $y $y $y $y $y $y $y"
+    set y "$y $y $y $y $y $y $y $y $y $y "
+    expr {$x == $y}
+} 1
+
+test append-3.1 {append errors} -returnCodes error -body {
+    append
+} -result {wrong # args: should be "append varName ?value ...?"}
+test append-3.2 {append errors} -returnCodes error -body {
+    set x ""
+    append x(0) 44
+} -result {can't set "x(0)": variable isn't array}
+test append-3.3 {append errors} -returnCodes error -body {
+    unset -nocomplain x
+    append x
+} -result {can't read "x": no such variable}
+
+test append-4.1 {lappend command} {
+    unset -nocomplain x
+    list [lappend x 1 2 abc "long string"] $x
+} {{1 2 abc {long string}} {1 2 abc {long string}}}
+test append-4.2 {lappend command} {
+    set x ""
+    list [lappend x first] [lappend x second] [lappend x third] $x
+} {first {first second} {first second third} {first second third}}
+test append-4.3 {lappend command} -body {
+    proc foo {} {
+	global x
+	set x old
+	unset x
+	lappend x new
+    }
+    foo
+} -cleanup {
+    rename foo {}
+} -result {new}
+test append-4.4 {lappend command} {
+    set x {}
+    lappend x \{\  abc
+} {\{\  abc}
+test append-4.5 {lappend command} {
+    set x {}
+    lappend x \{ abc
+} {\{ abc}
+test append-4.6 {lappend command} {
+    set x {1 2 3}
+    lappend x
+} {1 2 3}
+test append-4.7 {lappend command} {
+    set x "a\{"
+    lappend x abc
+} "a\\\{ abc"
+test append-4.8 {lappend command} {
+    set x "\\\{"
+    lappend x abc
+} "\\{ abc"
+test append-4.9 {lappend command} -returnCodes error -body {
+    set x " \{"
+    lappend x abc
+} -result {unmatched open brace in list}
+test append-4.10 {lappend command} -returnCodes error -body {
+    set x "	\{"
+    lappend x abc
+} -result {unmatched open brace in list}
+test append-4.11 {lappend command} -returnCodes error -body {
+    set x "\{\{\{"
+    lappend x abc
+} -result {unmatched open brace in list}
+test append-4.12 {lappend command} -returnCodes error -body {
+    set x "x \{\{\{"
+    lappend x abc
+} -result {unmatched open brace in list}
+test append-4.13 {lappend command} {
+    set x "x\{\{\{"
+    lappend x abc
+} "x\\\{\\\{\\\{ abc"
+test append-4.14 {lappend command} {
+    set x " "
+    lappend x abc
+} "abc"
+test append-4.15 {lappend command} {
+    set x "\\ "
+    lappend x abc
+} "{ } abc"
+test append-4.16 {lappend command} {
+    set x "x "
+    lappend x abc
+} "x abc"
+test append-4.17 {lappend command} {
+    unset -nocomplain x
+    lappend x
+} {}
+test append-4.18 {lappend command} {
+    unset -nocomplain x
+    lappend x {}
+} {{}}
+test append-4.19 {lappend command} {
+    unset -nocomplain x
+    lappend x(0)
+} {}
+test append-4.20 {lappend command} {
+    unset -nocomplain x
+    lappend x(0) abc
+} {abc}
+unset -nocomplain x
+test append-4.21 {lappend command} -returnCodes error -body {
+    set x \"
+    lappend x
+} -result {unmatched open quote in list}
+test append-4.22 {lappend command} -returnCodes error -body {
+    set x \"
+    lappend x abc
+} -result {unmatched open quote in list}
+
+test append-5.1 {long lappends} -setup {
+    unset -nocomplain x
+    proc check {var size} {
+	set l [llength $var]
+	if {$l != $size} {
+	    return "length mismatch: should have been $size, was $l"
+	}
+	for {set i 0} {$i < $size} {set i [expr $i+1]} {
+	    set j [lindex $var $i]
+	    if {$j ne "item $i"} {
+		return "element $i should have been \"item $i\", was \"$j\""
+	    }
+	}
+	return ok
+    }
+} -body {
+    set x ""
+    for {set i 0} {$i < 300} {incr i} {
+	lappend x "item $i"
+    }
+    check $x 300
+} -cleanup {
+    rename check {}
+} -result ok
+
+test append-6.1 {lappend errors} -returnCodes error -body {
+    lappend
+} -result {wrong # args: should be "lappend varName ?value ...?"}
+test append-6.2 {lappend errors} -returnCodes error -body {
+    set x ""
+    lappend x(0) 44
+} -result {can't set "x(0)": variable isn't array}
+
+test append-7.1 {lappend-created var and error in trace on that var} -setup {
+    catch {rename foo ""}
+    unset -nocomplain x
+} -body {
+    trace variable x w foo
+    proc foo {} {global x; unset x}
+    catch {lappend x 1}
+    proc foo {args} {global x; unset x}
+    info exists x
+    set x
+    lappend x 1
+    list [info exists x] [catch {set x} msg] $msg
+} -result {0 1 {can't read "x": no such variable}}
+test append-7.2 {lappend var triggers read trace} -setup {
+    unset -nocomplain myvar
+    unset -nocomplain ::result
+} -body {
+    trace variable myvar r foo
+    proc foo {args} {append ::result $args}
+    lappend myvar a
+    return $::result
+} -result {myvar {} r}
+test append-7.3 {lappend var triggers read trace, array var} -setup {
+    unset -nocomplain myvar
+    unset -nocomplain ::result
+} -body {
+    # The behavior of read triggers on lappend changed in 8.0 to not trigger
+    # them, and was changed back in 8.4.
+    trace variable myvar r foo
+    proc foo {args} {append ::result $args}
+    lappend myvar(b) a
+    return $::result
+} -result {myvar b r}
+test append-7.4 {lappend var triggers read trace, array var exists} -setup {
+    unset -nocomplain myvar
+    unset -nocomplain ::result
+} -body {
+    set myvar(0) 1
+    trace variable myvar r foo
+    proc foo {args} {append ::result $args}
+    lappend myvar(b) a
+    return $::result
+} -result {myvar b r}
+test append-7.5 {append var does not trigger read trace} -setup {
+    unset -nocomplain myvar
+    unset -nocomplain ::result
+} -body {
+    trace variable myvar r foo
+    proc foo {args} {append ::result $args}
+    append myvar a
+    info exists ::result
+} -result {0}
+
+# THERE ARE NO append-8.* TESTS
+
+# New tests for bug 3057639 to show off the more consistent behaviour of
+# lappend in both direct-eval and bytecompiled code paths (see appendComp.test
+# for the compiled variants). lappend now behaves like append. 9.0/1 lappend -
+# 9.2/3 append
+
+test append-9.0 {bug 3057639, lappend direct eval, read trace on non-existing array variable element} -setup {
+    unset -nocomplain myvar
+} -body {
+    array set myvar {}
+    proc nonull {var key val} {
+	upvar 1 $var lvar
+	if {![info exists lvar($key)]} {
+	    return -code error "no such variable"
+	}
+    }
+    trace add variable myvar read nonull
+    list [catch {
+	lappend myvar(key) "new value"
+    } msg] $msg
+} -result {0 {{new value}}}
+test append-9.1 {bug 3057639, lappend direct eval, read trace on non-existing env element} -setup {
+    unset -nocomplain ::env(__DUMMY__)
+} -body {
+    list [catch {
+	lappend ::env(__DUMMY__) "new value"
+    } msg] $msg
+} -cleanup {
+    unset -nocomplain ::env(__DUMMY__)
+} -result {0 {{new value}}}
+test append-9.2 {bug 3057639, append direct eval, read trace on non-existing array variable element} -setup {
+    unset -nocomplain myvar
+} -body {
+    array set myvar {}
+    proc nonull {var key val} {
+	upvar 1 $var lvar
+	if {![info exists lvar($key)]} {
+	    return -code error "no such variable"
+	}
+    }
+    trace add variable myvar read nonull
+    list [catch {
+	append myvar(key) "new value"
+    } msg] $msg
+} -result {0 {new value}}
+test append-9.3 {bug 3057639, append direct eval, read trace on non-existing env element} -setup {
+    unset -nocomplain ::env(__DUMMY__)
+} -body {
+    list [catch {
+	append ::env(__DUMMY__) "new value"
+    } msg] $msg
+} -cleanup {
+    unset -nocomplain ::env(__DUMMY__)
+} -result {0 {new value}}
+
+test append-10.1 {Bug 214cc0eb22: lappend with no values} {
+    set lst "# 1 2 3"
+    [subst lappend] lst
+} "# 1 2 3"
+test append-10.2 {Bug 214cc0eb22: lappend with no values} -body {
+    set lst "1 \{ 2"
+    [subst lappend] lst
+} -returnCodes error -result {unmatched open brace in list}
+test append-10.3 {Bug 214cc0eb22: expanded lappend with no values} {
+    set lst "# 1 2 3"
+    [subst lappend] lst {*}[list]
+} "# 1 2 3"
+test append-10.4 {Bug 214cc0eb22: expanded lappend with no values} -body {
+    set lst "1 \{ 2"
+    [subst lappend] lst {*}[list]
+} -returnCodes error -result {unmatched open brace in list}
+
+unset -nocomplain i x result y
+catch {rename foo ""}
+
+# cleanup
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# fill-column: 78
+# End:
diff --git a/tests/appendComp.test b/tests/appendComp.test
new file mode 100644
index 0000000..bbf5f9c
--- /dev/null
+++ b/tests/appendComp.test
@@ -0,0 +1,476 @@
+# Commands covered:  append lappend
+#
+# This file contains a collection of tests for one or more of the Tcl built-in
+# commands. Sourcing this file into Tcl runs the tests and generates output
+# for errors. No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994-1996 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution of
+# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+    package require tcltest 2
+    namespace import -force ::tcltest::*
+}
+catch {unset x}
+
+test appendComp-1.1 {append command} -setup {
+    unset -nocomplain x
+} -body {
+    proc foo {} {append ::x 1 2 abc "long string"}
+    list [foo] $x
+} -result {{12abclong string} {12abclong string}}
+test appendComp-1.2 {append command} {
+    proc foo {} {
+	set x ""
+	list [append x first] [append x second] [append x third] $x
+    }
+    foo
+} {first firstsecond firstsecondthird firstsecondthird}
+test appendComp-1.3 {append command} {
+    proc foo {} {
+	set x "abcd"
+	append x
+    }
+    foo
+} abcd
+
+test appendComp-2.1 {long appends} {
+    proc foo {} {
+	set x ""
+	for {set i 0} {$i < 1000} {set i [expr $i+1]} {
+	    append x "foobar "
+	}
+	set y "foobar"
+	set y "$y $y $y $y $y $y $y $y $y $y"
+	set y "$y $y $y $y $y $y $y $y $y $y"
+	set y "$y $y $y $y $y $y $y $y $y $y "
+	expr {$x == $y}
+    }
+    foo
+} 1
+
+test appendComp-3.1 {append errors} -returnCodes error -body {
+    proc foo {} {append}
+    foo
+} -result {wrong # args: should be "append varName ?value ...?"}
+test appendComp-3.2 {append errors} -returnCodes error -body {
+    proc foo {} {
+	set x ""
+	append x(0) 44
+    }
+    foo
+} -result {can't set "x(0)": variable isn't array}
+test appendComp-3.3 {append errors} -returnCodes error -body {
+    proc foo {} {
+	unset -nocomplain x
+	append x
+    }
+    foo
+} -result {can't read "x": no such variable}
+
+test appendComp-4.1 {lappend command} {
+    proc foo {} {
+	global x
+	unset -nocomplain x
+	lappend x 1 2 abc "long string"
+    }
+    list [foo] $x
+} {{1 2 abc {long string}} {1 2 abc {long string}}}
+test appendComp-4.2 {lappend command} {
+    proc foo {} {
+	set x ""
+	list [lappend x first] [lappend x second] [lappend x third] $x
+    }
+    foo
+} {first {first second} {first second third} {first second third}}
+test appendComp-4.3 {lappend command} {
+    proc foo {} {
+	global x
+	set x old
+	unset x
+	lappend x new
+    }
+    set result [foo]
+    rename foo {}
+    set result
+} {new}
+test appendComp-4.4 {lappend command} {
+    proc foo {} {
+	set x {}
+	lappend x \{\  abc
+    }
+    foo
+} {\{\  abc}
+test appendComp-4.5 {lappend command} {
+    proc foo {} {
+	set x {}
+	lappend x \{ abc
+    }
+    foo
+} {\{ abc}
+test appendComp-4.6 {lappend command} {
+    proc foo {} {
+	set x {1 2 3}
+	lappend x
+    }
+    foo
+} {1 2 3}
+test appendComp-4.7 {lappend command} {
+    proc foo {} {
+	set x "a\{"
+	lappend x abc
+    }
+    foo
+} "a\\\{ abc"
+test appendComp-4.8 {lappend command} {
+    proc foo {} {
+	set x "\\\{"
+	lappend x abc
+    }
+    foo
+} "\\{ abc"
+test appendComp-4.9 {lappend command} -returnCodes error -body {
+    proc foo {} {
+	set x " \{"
+	lappend x abc
+    }
+    foo
+} -result {unmatched open brace in list}
+test appendComp-4.10 {lappend command} -returnCodes error -body {
+    proc foo {} {
+	set x "	\{"
+	lappend x abc
+    }
+    foo
+} -result {unmatched open brace in list}
+test appendComp-4.11 {lappend command} -returnCodes error -body {
+    proc foo {} {
+	set x "\{\{\{"
+	lappend x abc
+    }
+    foo
+} -result {unmatched open brace in list}
+test appendComp-4.12 {lappend command} -returnCodes error -body {
+    proc foo {} {
+	set x "x \{\{\{"
+	lappend x abc
+    }
+    foo
+} -result {unmatched open brace in list}
+test appendComp-4.13 {lappend command} {
+    proc foo {} {
+	set x "x\{\{\{"
+	lappend x abc
+    }
+    foo
+} "x\\\{\\\{\\\{ abc"
+test appendComp-4.14 {lappend command} {
+    proc foo {} {
+	set x " "
+	lappend x abc
+    }
+    foo
+} "abc"
+test appendComp-4.15 {lappend command} {
+    proc foo {} {
+	set x "\\ "
+	lappend x abc
+    }
+    foo
+} "{ } abc"
+test appendComp-4.16 {lappend command} {
+    proc foo {} {
+	set x "x "
+	lappend x abc
+    }
+    foo
+} "x abc"
+test appendComp-4.17 {lappend command} {
+    proc foo {} { lappend x }
+    foo
+} {}
+test appendComp-4.18 {lappend command} {
+    proc foo {} { lappend x {} }
+    foo
+} {{}}
+test appendComp-4.19 {lappend command} {
+    proc foo {} { lappend x(0) }
+    foo
+} {}
+test appendComp-4.20 {lappend command} {
+    proc foo {} { lappend x(0) abc }
+    foo
+} {abc}
+
+test appendComp-5.1 {long lappends} -setup {
+    unset -nocomplain x
+    proc check {var size} {
+	set l [llength $var]
+	if {$l != $size} {
+	    return "length mismatch: should have been $size, was $l"
+	}
+	for {set i 0} {$i < $size} {incr i} {
+	    set j [lindex $var $i]
+	    if {$j ne "item $i"} {
+		return "element $i should have been \"item $i\", was \"$j\""
+	    }
+	}
+	return ok
+    }
+} -body {
+    set x ""
+    for {set i 0} {$i < 300} {set i [expr $i+1]} {
+	lappend x "item $i"
+    }
+    check $x 300
+} -cleanup {
+    unset -nocomplain x
+    catch {rename check ""}
+} -result ok
+
+test appendComp-6.1 {lappend errors} -returnCodes error -body {
+    proc foo {} {lappend}
+    foo
+} -result {wrong # args: should be "lappend varName ?value ...?"}
+test appendComp-6.2 {lappend errors} -returnCodes error -body {
+    proc foo {} {
+	set x ""
+	lappend x(0) 44
+    }
+    foo
+} -result {can't set "x(0)": variable isn't array}
+
+test appendComp-7.1 {lappendComp-created var and error in trace on that var} -setup {
+    catch {rename foo ""}
+    unset -nocomplain x
+} -body {
+    proc bar {} {
+	global x
+	trace variable x w foo
+	proc foo {} {global x; unset x}
+	catch {lappend x 1}
+	proc foo {args} {global x; unset x}
+	info exists x
+	set x
+	lappend x 1
+	list [info exists x] [catch {set x} msg] $msg
+    }
+    bar
+} -result {0 1 {can't read "x": no such variable}}
+test appendComp-7.2 {lappend var triggers read trace, index var} -setup {
+    unset -nocomplain ::result
+} -body {
+    proc bar {} {
+	trace variable myvar r foo
+	proc foo {args} {append ::result $args}
+	lappend myvar a
+	return $::result
+    }
+    bar
+} -result {myvar {} r} -constraints {bug-3057639}
+test appendComp-7.3 {lappend var triggers read trace, stack var} -setup {
+    unset -nocomplain ::result
+    unset -nocomplain ::myvar
+} -body {
+    proc bar {} {
+	trace variable ::myvar r foo
+	proc foo {args} {append ::result $args}
+	lappend ::myvar a
+	return $::result
+    }
+    bar
+} -result {::myvar {} r} -constraints {bug-3057639}
+test appendComp-7.4 {lappend var triggers read trace, array var} -setup {
+    unset -nocomplain ::result
+} -body {
+    # The behavior of read triggers on lappend changed in 8.0 to not trigger
+    # them. Maybe not correct, but been there a while.
+    proc bar {} {
+	trace variable myvar r foo
+	proc foo {args} {append ::result $args}
+	lappend myvar(b) a
+	return $::result
+    }
+    bar
+} -result {myvar b r} -constraints {bug-3057639}
+test appendComp-7.5 {lappend var triggers read trace, array var} -setup {
+    unset -nocomplain ::result
+} -body {
+    # The behavior of read triggers on lappend changed in 8.0 to not trigger
+    # them. Maybe not correct, but been there a while.
+    proc bar {} {
+	trace variable myvar r foo
+	proc foo {args} {append ::result $args}
+	lappend myvar(b) a b
+	return $::result
+    }
+    bar
+} -result {myvar b r}
+test appendComp-7.6 {lappend var triggers read trace, array var exists} -setup {
+    unset -nocomplain ::result
+} -body {
+    proc bar {} {
+	set myvar(0) 1
+	trace variable myvar r foo
+	proc foo {args} {append ::result $args}
+	lappend myvar(b) a
+	return $::result
+    }
+    bar
+} -result {myvar b r} -constraints {bug-3057639}
+test appendComp-7.7 {lappend var triggers read trace, array stack var} -setup {
+    unset -nocomplain ::myvar
+    unset -nocomplain ::result
+} -body {
+    proc bar {} {
+	trace variable ::myvar r foo
+	proc foo {args} {append ::result $args}
+	lappend ::myvar(b) a
+	return $::result
+    }
+    bar
+} -result {::myvar b r} -constraints {bug-3057639}
+test appendComp-7.8 {lappend var triggers read trace, array stack var} -setup {
+    unset -nocomplain ::myvar
+    unset -nocomplain ::result
+} -body {
+    proc bar {} {
+	trace variable ::myvar r foo
+	proc foo {args} {append ::result $args}
+	lappend ::myvar(b) a b
+	return $::result
+    }
+    bar
+} -result {::myvar b r}
+test appendComp-7.9 {append var does not trigger read trace} -setup {
+    unset -nocomplain ::result
+} -body {
+    proc bar {} {
+	trace variable myvar r foo
+	proc foo {args} {append ::result $args}
+	append myvar a
+	info exists ::result
+    }
+    bar
+} -result {0}
+
+test appendComp-8.1 {defer error to runtime} -setup {
+    interp create slave
+} -body {
+    slave eval {
+	proc foo {} {
+	    proc append args {}
+	    append
+	}
+	foo
+    }
+} -cleanup {
+    interp delete slave
+} -result {}
+
+# New tests for bug 3057639 to show off the more consistent behaviour of
+# lappend in both direct-eval and bytecompiled code paths (see append.test for
+# the direct-eval variants). lappend now behaves like append. 9.0/1 lappend -
+# 9.2/3 append.
+
+# Note also the tests above now constrained by bug-3057639, these changed
+# behaviour with the triggering of read traces in bc mode gone.
+
+# Going back to the tests below. The direct-eval tests are ok before and after
+# patch (no read traces run for lappend, append). The compiled tests are
+# failing for lappend (9.0/1) before the patch, showing how it invokes read
+# traces in the compiled path. The append tests are good (9.2/3). After the
+# patch the failues are gone.
+
+test appendComp-9.0 {bug 3057639, lappend compiled, read trace on non-existing array variable element} -setup {
+    unset -nocomplain myvar
+    array set myvar {}
+} -body {
+    proc nonull {var key val} {
+	upvar 1 $var lvar
+	if {![info exists lvar($key)]} {
+	    return -code error "BOOM. no such variable"
+	}
+    }
+    trace add variable myvar read nonull
+    proc foo {} {
+	lappend ::myvar(key) "new value"
+    }
+    list [catch { foo } msg] $msg
+} -result {0 {{new value}}}
+test appendComp-9.1 {bug 3057639, lappend direct eval, read trace on non-existing env element} -setup {
+    unset -nocomplain ::env(__DUMMY__)
+} -body {
+    proc foo {} {
+	lappend ::env(__DUMMY__) "new value"
+    }
+    list [catch { foo } msg] $msg
+} -cleanup {
+    unset -nocomplain ::env(__DUMMY__)
+} -result {0 {{new value}}}
+test appendComp-9.2 {bug 3057639, append compiled, read trace on non-existing array variable element} -setup {
+    unset -nocomplain myvar
+    array set myvar {}
+} -body {
+    proc nonull {var key val} {
+	upvar 1 $var lvar
+	if {![info exists lvar($key)]} {
+	    return -code error "BOOM. no such variable"
+	}
+    }
+    trace add variable myvar read nonull
+    proc foo {} {
+	append ::myvar(key) "new value"
+    }
+    list [catch { foo } msg] $msg
+} -result {0 {new value}}
+test appendComp-9.3 {bug 3057639, append direct eval, read trace on non-existing env element} -setup {
+    unset -nocomplain ::env(__DUMMY__)
+} -body {
+    proc foo {} {
+	append ::env(__DUMMY__) "new value"
+    }
+    list [catch { foo } msg] $msg
+} -cleanup {
+    unset -nocomplain ::env(__DUMMY__)
+} -result {0 {new value}}
+
+test appendComp-10.1 {Bug 214cc0eb22: lappend with no values} {
+    apply {lst {
+	lappend lst
+    }} "# 1 2 3"
+} "# 1 2 3"
+test appendComp-10.2 {Bug 214cc0eb22: lappend with no values} -body {
+    apply {lst {
+	lappend lst
+    }} "1 \{ 2"
+} -returnCodes error -result {unmatched open brace in list}
+test appendComp-10.3 {Bug 214cc0eb22: expanded lappend with no values} {
+    apply {lst {
+	lappend lst {*}[list]
+    }} "# 1 2 3"
+} "# 1 2 3"
+test appendComp-10.4 {Bug 214cc0eb22: expanded lappend with no values} -body {
+    apply {lst {
+	lappend lst {*}[list]
+    }} "1 \{ 2"
+} -returnCodes error -result {unmatched open brace in list}
+
+catch {unset i x result y}
+catch {rename foo ""}
+catch {rename bar ""}
+catch {rename check ""}
+catch {rename bar {}}
+
+# cleanup
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# fill-column: 78
+# End:
diff --git a/tests/apply.test b/tests/apply.test
new file mode 100644
index 0000000..ba19b81
--- /dev/null
+++ b/tests/apply.test
@@ -0,0 +1,321 @@
+# Commands covered:  apply
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands.  Sourcing this file into Tcl runs the tests and
+# generates output for errors.  No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994-1996 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+# Copyright (c) 2005-2006 Miguel Sofer
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+    package require tcltest 2.2
+    namespace import -force ::tcltest::*
+}
+
+if {[info commands ::apply] eq {}} {
+    return
+}
+
+testConstraint memory [llength [info commands memory]]
+
+# Tests for wrong number of arguments
+
+test apply-1.1 {too few arguments} -returnCodes error -body {
+    apply
+} -result {wrong # args: should be "apply lambdaExpr ?arg ...?"}
+
+# Tests for malformed lambda
+
+test apply-2.0 {malformed lambda} -returnCodes error -body {
+    set lambda a
+    apply $lambda
+} -result {can't interpret "a" as a lambda expression}
+test apply-2.1 {malformed lambda} -returnCodes error -body {
+    set lambda [list a b c d]
+    apply $lambda
+} -result {can't interpret "a b c d" as a lambda expression}
+test apply-2.2 {malformed lambda} {
+    set lambda [list {{}} boo]
+    list [catch {apply $lambda} msg] $msg $::errorInfo
+} {1 {argument with no name} {argument with no name
+    (parsing lambda expression "{{}} boo")
+    invoked from within
+"apply $lambda"}}
+test apply-2.3 {malformed lambda} {
+    set lambda [list {{a b c}} boo]
+    list [catch {apply $lambda} msg] $msg $::errorInfo
+} {1 {too many fields in argument specifier "a b c"} {too many fields in argument specifier "a b c"
+    (parsing lambda expression "{{a b c}} boo")
+    invoked from within
+"apply $lambda"}}
+test apply-2.4 {malformed lambda} {
+    set lambda [list a(1) boo]
+    list [catch {apply $lambda} msg] $msg $::errorInfo
+} {1 {formal parameter "a(1)" is an array element} {formal parameter "a(1)" is an array element
+    (parsing lambda expression "a(1) boo")
+    invoked from within
+"apply $lambda"}}
+test apply-2.5 {malformed lambda} {
+    set lambda [list a::b boo]
+    list [catch {apply $lambda} msg] $msg $::errorInfo
+} {1 {formal parameter "a::b" is not a simple name} {formal parameter "a::b" is not a simple name
+    (parsing lambda expression "a::b boo")
+    invoked from within
+"apply $lambda"}}
+
+# Tests for runtime errors in the lambda expression
+
+test apply-3.1 {non-existing namespace} -body {
+    apply [list x {set x 1} ::NONEXIST::FOR::SURE] x
+} -returnCodes error -result {namespace "::NONEXIST::FOR::SURE" not found}
+test apply-3.2 {non-existing namespace} -body {
+    namespace eval ::NONEXIST::FOR::SURE {}
+    set lambda [list x {set x 1} ::NONEXIST::FOR::SURE]
+    apply $lambda x
+    namespace delete ::NONEXIST
+    apply $lambda x
+} -returnCodes error -result {namespace "::NONEXIST::FOR::SURE" not found}
+test apply-3.3 {non-existing namespace} -body {
+    apply [list x {set x 1} NONEXIST::FOR::SURE] x
+} -returnCodes error -result {namespace "::NONEXIST::FOR::SURE" not found}
+test apply-3.4 {non-existing namespace} -body {
+    namespace eval ::NONEXIST::FOR::SURE {}
+    set lambda [list x {set x 1} NONEXIST::FOR::SURE]
+    apply $lambda x
+    namespace delete ::NONEXIST
+    apply $lambda x
+} -returnCodes error -result {namespace "::NONEXIST::FOR::SURE" not found}
+
+test apply-4.1 {error in arguments to lambda expression} -body {
+    set lambda [list x {set x 1}]
+    apply $lambda
+} -returnCodes error -result {wrong # args: should be "apply lambdaExpr x"}
+test apply-4.2 {error in arguments to lambda expression} -body {
+    set lambda [list x {set x 1}]
+    apply $lambda a b
+} -returnCodes error -result {wrong # args: should be "apply lambdaExpr x"}
+test apply-4.3 {error in arguments to lambda expression} -body {
+    interp alias {} foo {} ::apply [list x {set x 1}]
+    foo a b
+} -cleanup {
+    rename foo {}
+} -returnCodes error -result {wrong # args: should be "foo x"}
+test apply-4.4 {error in arguments to lambda expression} -body {
+    interp alias {} foo {} ::apply [list x {set x 1}] a
+    foo b
+} -cleanup {
+    rename foo {}
+} -returnCodes error -result {wrong # args: should be "foo"}
+test apply-4.5 {error in arguments to lambda expression} -body {
+    set lambda [list x {set x 1}]
+    namespace eval a {
+	namespace ensemble create -command ::bar -map {id {::a::const foo}}
+	proc const val { return $val }
+	proc alias {object slot = command args} {
+	    set map [namespace ensemble configure $object -map]
+	    dict set map $slot [linsert $args 0 $command]
+	    namespace ensemble configure $object -map $map
+	}
+	proc method {object name params body} {
+	    set params [linsert $params 0 self]
+	    alias $object $name = ::apply [list $params $body] $object
+	}
+	method ::bar boo x {return "[expr {$x*$x}] - $self"}
+    }
+    bar boo
+} -cleanup {
+    namespace delete ::a
+} -returnCodes error -result {wrong # args: should be "bar boo x"}
+
+test apply-5.1 {runtime error in lambda expression} {
+    set lambda [list {} {error foo}]
+    set res [catch {apply $lambda}]
+    list $res $::errorInfo
+} {1 {foo
+    while executing
+"error foo"
+    (lambda term "{} {error foo}" line 1)
+    invoked from within
+"apply $lambda"}}
+
+# Tests for correct execution; as the implementation is the same as that for
+# procs, the general functionality is mostly tested elsewhere
+
+test apply-6.1 {info level} {
+    set lev [info level]
+    set lambda [list {} {info level}]
+    expr {[apply $lambda] - $lev}
+} 1
+test apply-6.2 {info level} {
+    set lambda [list {} {info level 0}]
+    apply $lambda
+} {apply {{} {info level 0}}}
+test apply-6.3 {info level} {
+    set lambda [list args {info level 0}]
+    apply $lambda x y
+} {apply {args {info level 0}} x y}
+
+# Tests for correct namespace scope
+
+namespace eval ::testApply {
+    proc testApply args {return testApply}
+}
+
+test apply-7.1 {namespace access} {
+    set ::testApply::x 0
+    set body {set x 1; set x}
+    list [apply [list args $body ::testApply]] $::testApply::x
+} {1 0}
+test apply-7.2 {namespace access} {
+    set ::testApply::x 0
+    set body {variable x; set x}
+    list [apply [list args $body ::testApply]] $::testApply::x
+} {0 0}
+test apply-7.3 {namespace access} {
+    set ::testApply::x 0
+    set body {variable x; set x 1}
+    list [apply [list args $body ::testApply]] $::testApply::x
+} {1 1}
+test apply-7.4 {namespace access} {
+    set ::testApply::x 0
+    set body {testApply}
+    apply [list args $body ::testApply]
+} testApply
+test apply-7.5 {namespace access} {
+    set ::testApply::x 0
+    set body {set x 1; set x}
+    list [apply [list args $body testApply]] $::testApply::x
+} {1 0}
+test apply-7.6 {namespace access} {
+    set ::testApply::x 0
+    set body {variable x; set x}
+    list [apply [list args $body testApply]] $::testApply::x
+} {0 0}
+test apply-7.7 {namespace access} {
+    set ::testApply::x 0
+    set body {variable x; set x 1}
+    list [apply [list args $body testApply]] $::testApply::x
+} {1 1}
+test apply-7.8 {namespace access} {
+    set ::testApply::x 0
+    set body {testApply}
+    apply [list args $body testApply]
+} testApply
+
+# Tests for correct argument treatment
+
+set applyBody {
+    set res {}
+    foreach v [info locals] {
+	if {$v eq "res"} continue
+	lappend res [list $v [set $v]]
+    }
+    set res
+}
+
+test apply-8.1 {args treatment} {
+    apply [list args $applyBody] 1 2 3
+} {{args {1 2 3}}}
+test apply-8.2 {args treatment} {
+    apply [list {x args} $applyBody] 1 2
+} {{x 1} {args 2}}
+test apply-8.3 {args treatment} {
+    apply [list {x args} $applyBody] 1 2 3
+} {{x 1} {args {2 3}}}
+test apply-8.4 {default values} {
+    apply [list {{x 1} {y 2}} $applyBody] 
+} {{x 1} {y 2}}
+test apply-8.5 {default values} {
+    apply [list {{x 1} {y 2}} $applyBody] 3 4
+} {{x 3} {y 4}}
+test apply-8.6 {default values} {
+    apply [list {{x 1} {y 2}} $applyBody] 3
+} {{x 3} {y 2}}
+test apply-8.7 {default values} {
+    apply [list {x {y 2}} $applyBody] 1
+} {{x 1} {y 2}}
+test apply-8.8 {default values} {
+    apply [list {x {y 2}} $applyBody] 1 3
+} {{x 1} {y 3}}
+test apply-8.9 {default values} {
+    apply [list {x {y 2} args} $applyBody] 1
+} {{x 1} {y 2} {args {}}}
+test apply-8.10 {default values} {
+    apply [list {x {y 2} args} $applyBody] 1 3
+} {{x 1} {y 3} {args {}}}
+
+# Tests for leaks
+
+test apply-9.1 {leaking internal rep} -setup {
+    proc getbytes {} {
+	set lines [split [memory info] "\n"]
+	lindex $lines 3 3
+    }
+    set lam [list {} {set a 1}]
+} -constraints memory -body {
+    set end [getbytes]
+    for {set i 0} {$i < 5} {incr i} {
+	::apply [lrange $lam 0 end]
+	set tmp $end
+	set end [getbytes]
+    }
+    set leakedBytes [expr {$end - $tmp}]
+} -cleanup {
+    rename getbytes {}
+    unset -nocomplain lam end i tmp leakedBytes
+} -result 0
+test apply-9.2 {leaking internal rep} -setup {
+    proc getbytes {} {
+	set lines [split [memory info] "\n"]
+	lindex $lines 3 3
+    }
+} -constraints memory -body {
+    set end [getbytes]
+    for {set i 0} {$i < 5} {incr i} {
+	::apply [list {} {set a 1}]
+	set tmp $end
+	set end [getbytes]
+    }
+    set leakedBytes [expr {$end - $tmp}]
+} -cleanup {
+    rename getbytes {}
+    unset -nocomplain end i tmp leakedBytes
+} -result 0
+test apply-9.3 {leaking internal rep} -setup {
+    proc getbytes {} {
+	set lines [split [memory info] "\n"]
+	lindex $lines 3 3
+    }
+} -constraints memory -body {
+    set end [getbytes]
+    for {set i 0} {$i < 5} {incr i} {
+	set x [list {} {set a 1} ::NS::THAT::DOES::NOT::EXIST]
+	catch {::apply $x}
+	set x {}
+	set tmp $end
+	set end [getbytes]
+    }
+    set leakedBytes [expr {$end - $tmp}]
+} -cleanup {
+    rename getbytes {}
+    unset -nocomplain end i x tmp leakedBytes
+} -result 0
+
+# Tests for the avoidance of recompilation
+
+# cleanup
+
+namespace delete testApply
+
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# fill-column: 78
+# End:
diff --git a/tests/assemble.test b/tests/assemble.test
new file mode 100644
index 0000000..a9c77e3
--- /dev/null
+++ b/tests/assemble.test
@@ -0,0 +1,3378 @@
+# assemble.test --
+#
+#	Test suite for the 'tcl::unsupported::assemble' command
+#
+# Copyright (c) 2010 by Ozgur Dogan Ugurlu.
+# Copyright (c) 2010 by Kevin B. Kenny.
+#
+# See the file "license.terms" for information on usage and redistribution of
+# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#-----------------------------------------------------------------------------
+
+# Commands covered: assemble
+
+if {"::tcltest" ni [namespace children]} {
+    package require tcltest 2.2
+    namespace import -force ::tcltest::*
+}
+namespace eval tcl::unsupported {namespace export assemble}
+namespace import tcl::unsupported::assemble
+
+# Procedure to make code that fills the literal and local variable tables, to
+# force instructions to spill to four bytes.
+
+proc fillTables {} {
+    set s {}
+    set sep {}
+    for {set i 0} {$i < 256} {incr i} {
+	append s $sep [list set v$i literal$i]
+	set sep \n
+    }
+    return $s
+}
+
+testConstraint memory [llength [info commands memory]]
+if {[testConstraint memory]} {
+    proc getbytes {} {
+	set lines [split [memory info] \n]
+	return [lindex $lines 3 3]
+    }
+    proc leaktest {script {iterations 3}} {
+	set end [getbytes]
+	for {set i 0} {$i < $iterations} {incr i} {
+	    uplevel 1 $script
+	    set tmp $end
+	    set end [getbytes]
+	}
+	return [expr {$end - $tmp}]
+    }
+}
+
+# assemble-1 - TclNRAssembleObjCmd
+
+test assemble-1.1 {wrong # args, direct eval} {
+    -body {
+	eval [list assemble]
+    }
+    -returnCodes error
+    -result {wrong # args*}
+    -match glob
+}
+test assemble-1.2 {wrong # args, direct eval} {
+    -body {
+	eval [list assemble too many]
+    }
+    -returnCodes error
+    -result {wrong # args*}
+    -match glob
+}
+test assemble-1.3 {error reporting, direct eval} {
+    -body {
+	list [catch {
+	    eval [list assemble {
+		# bad opcode
+		rubbish
+	    }]
+	} result] $result $errorInfo
+    }
+    -match glob
+    -result {1 {bad instruction "rubbish":*} {bad instruction "rubbish":*
+    while executing
+"rubbish"
+    ("assemble" body, line 3)*}}
+    -cleanup {unset result}
+}
+test assemble-1.4 {simple direct eval} {
+    -body {
+	eval [list assemble {push {this is a test}}]
+    }
+    -result {this is a test}
+}
+
+# assemble-2 - CompileAssembleObj
+
+test assemble-2.1 {bytecode reuse, direct eval} {
+    -body {
+	set x {push "this is a test"}
+	list [eval [list assemble $x]] \
+	    [eval [list assemble $x]]
+    }
+    -result {{this is a test} {this is a test}}
+}
+test assemble-2.2 {bytecode discard, direct eval} {
+    -body {
+	set x {load value}
+	proc p1 {x} {
+	    set value value1
+	    assemble $x
+	}
+	proc p2 {x} {
+	    set a b
+	    set value value2
+	    assemble $x
+	}
+	list [p1 $x] [p2 $x]
+    }
+    -result {value1 value2}
+    -cleanup {
+	unset x
+	rename p1 {}
+	rename p2 {}
+    }
+}
+test assemble-2.3 {null script, direct eval} {
+    -body {
+	set x {}
+	assemble $x
+    }
+    -result {}
+    -cleanup {unset x}
+}
+
+# assemble-3 - TclCompileAssembleCmd
+
+test assemble-3.1 {wrong # args, compiled path} {
+    -body {
+	proc x {} {
+	    assemble
+	}
+	x
+    }
+    -returnCodes error
+    -match glob
+    -result {wrong # args:*}
+}
+test assemble-3.2 {wrong # args, compiled path} {
+    -body {
+	proc x {} {
+	    assemble too many
+	}
+	x
+    }
+    -returnCodes error
+    -match glob
+    -result {wrong # args:*}
+    -cleanup {
+	rename x {}
+    }
+}
+
+# assemble-4 - TclAssembleCode mainline
+
+test assemble-4.1 {syntax error} {
+    -body {
+	proc x {} {
+	    assemble {
+		{}extra
+	    }
+	}
+	list [catch x result] $result $::errorInfo
+    }
+    -cleanup {
+	rename x {}
+	unset result
+    }
+    -match glob
+    -result {1 {extra characters after close-brace} {extra characters after close-brace
+    while executing
+"{}e"
+    ("assemble" body, line 2)*}}
+}
+test assemble-4.2 {null command} {
+    -body {
+	proc x {} {
+	    assemble {
+		push hello; pop;;push goodbye
+	    }
+	}
+	x
+    }
+    -result goodbye
+    -cleanup {
+	rename x {}
+    }
+}
+
+# assemble-5 - GetNextOperand off-nominal cases
+
+test assemble-5.1 {unsupported expansion} {
+    -body {
+	proc x {y} {
+	    assemble {
+		{*}$y
+	    }
+	}
+	list [catch {x {push hello}} result] $result $::errorCode
+    }
+    -result {1 {assembly code may not contain substitutions} {TCL ASSEM NOSUBST}}
+    -cleanup {
+	rename x {}
+	unset result
+    }
+}
+test assemble-5.2 {unsupported substitution} {
+    -body {
+	proc x {y} {
+	    assemble {
+		$y
+	    }
+	}
+	list [catch {x {nop}} result] $result $::errorCode
+    }
+    -cleanup {
+	rename x {}
+	unset result
+    }
+    -result {1 {assembly code may not contain substitutions} {TCL ASSEM NOSUBST}}
+}
+test assemble-5.3 {unsupported substitution} {
+    -body {
+	proc x {} {
+	    assemble {
+		[x]
+	    }
+	}
+	list [catch {x} result] $result $::errorCode
+    }
+    -result {1 {assembly code may not contain substitutions} {TCL ASSEM NOSUBST}}
+}
+test assemble-5.4 {backslash substitution} {
+    -body {
+	proc x {} {
+	    assemble {
+		p\x75sh\
+		    hello\ world
+	    }
+	}
+	x
+    }
+    -cleanup {
+	rename x {}
+    }
+    -result {hello world}
+}
+
+# assemble-6 - ASSEM_PUSH
+
+test assemble-6.1 {push, wrong # args} {
+    -body {
+	assemble push
+    }
+    -returnCodes error
+    -match glob
+    -result {wrong # args*}
+}
+test assemble-6.2 {push, wrong # args} {
+    -body {
+	assemble {push too many}
+    }
+    -returnCodes error
+    -match glob
+    -result {wrong # args*}
+}
+test assemble-6.3 {push} {
+    -body {
+	eval [list assemble {push hello}]
+    }
+    -result hello
+}
+test assemble-6.4 {push4} {
+    -body {
+	proc x {} "
+            [fillTables]
+            assemble {push hello}
+        "
+	x
+    }
+    -cleanup {
+	rename x {}
+    }
+    -result hello
+}
+
+# assemble-7 - ASSEM_1BYTE
+
+test assemble-7.1 {add, wrong # args} {
+    -body {
+	assemble {add excess}
+    }
+    -returnCodes error
+    -match glob
+    -result {wrong # args*}
+}
+test assemble-7.2 {add} {
+    -body { 
+	assemble {
+	    push 2
+	    push 2
+	    add
+	} 
+    }
+    -result {4}
+}
+test assemble-7.3 {appendArrayStk} {
+    -body {
+	set a(b) {hello, }
+	assemble {
+	    push a
+	    push b
+	    push world
+	    appendArrayStk
+	}
+	set a(b)
+    }
+    -result {hello, world}
+    -cleanup {unset a}
+}
+test assemble-7.4 {appendStk} {
+    -body {
+	set a {hello, }
+	assemble {
+	    push a
+	    push world
+	    appendStk
+	}
+	set a
+    }
+    -result {hello, world}
+    -cleanup {unset a}
+}
+test assemble-7.5 {bitwise ops} {
+    -body {
+	list \
+	    [assemble {push 0b1100; push 0b1010; bitand}] \
+	    [assemble {push 0b1100; bitnot}] \
+	    [assemble {push 0b1100; push 0b1010; bitor}] \
+	    [assemble {push 0b1100; push 0b1010; bitxor}]
+    }
+    -result {8 -13 14 6}
+}
+test assemble-7.6 {div} {
+    -body {
+	assemble {push 999999; push 7; div} 
+    }
+    -result 142857
+}
+test assemble-7.7 {dup} {
+    -body {
+	assemble {
+	    push 1; dup; dup; add; dup; add; dup; add; add
+	}
+    }
+    -result 9
+}	
+test assemble-7.8 {eq} {
+    -body {
+	list \
+	    [assemble {push able; push baker; eq}] \
+	    [assemble {push able; push able;  eq}]
+    }
+    -result {0 1}
+}
+test assemble-7.9 {evalStk} {
+    -body {
+	assemble {
+	    push {concat test 7.3}
+	    evalStk
+	}
+    }
+    -result {test 7.3}
+}
+test assemble-7.9a {evalStk, syntax} {
+    -body {
+	assemble {
+	    push {{}bad}
+	    evalStk
+	}
+    }
+    -returnCodes error
+    -result {extra characters after close-brace}
+}
+test assemble-7.9b {evalStk, backtrace} {
+    -body {
+	proc y {z} {
+	    error testing
+	}
+	proc x {} {
+	    assemble {
+		push {
+		    # test error in evalStk
+		    y asd
+		}
+		evalStk
+	    }
+	}
+	list [catch x result] $result $errorInfo
+    }
+    -result {1 testing {testing
+    while executing
+"error testing"
+    (procedure "y" line 2)
+    invoked from within
+"y asd"*}}
+    -match glob
+    -cleanup {
+	rename y {}
+	rename x {}
+    }
+}
+test assemble-7.10 {existArrayStk} {
+    -body {
+	proc x {name key} {
+	    set a(b) c
+	    assemble {
+		load name; load key; existArrayStk
+	    }
+	}
+	list [x a a] [x a b] [x b a] [x b b]
+    }
+    -result {0 1 0 0}
+    -cleanup {rename x {}}
+}
+test assemble-7.11 {existStk} {
+    -body {
+	proc x {name} {
+	    set a b
+	    assemble {
+		load name; existStk
+	    }
+	}
+	list [x a] [x b]
+    }
+    -result {1 0}
+    -cleanup {rename x {}}
+}
+test assemble-7.12 {expon} {
+    -body {
+	assemble {push 3; push 4; expon}
+    }
+    -result 81
+}
+test assemble-7.13 {exprStk} {
+    -body {
+	assemble {
+	    push {acos(-1)}
+	    exprStk
+	}
+    }
+    -result 3.141592653589793
+}
+test assemble-7.13a {exprStk, syntax} {
+    -body {
+	assemble {
+	    push {2+}
+	    exprStk
+	}
+    }
+    -returnCodes error
+    -result {missing operand at _@_
+in expression "2+_@_"}
+}
+test assemble-7.13b {exprStk, backtrace} {
+    -body {
+	proc y {z} {
+	    error testing
+	}
+	proc x {} {
+	    assemble {
+		push {[y asd]}
+		exprStk
+	    }
+	}
+	list [catch x result] $result $errorInfo
+    }
+    -result {1 testing {testing
+    while executing
+"error testing"
+    (procedure "y" line 2)
+    invoked from within
+"y asd"*}}
+    -match glob
+    -cleanup {
+	rename y {}
+	rename x {}
+    }
+}
+test assemble-7.14 {ge gt le lt} {
+    -body {
+	proc x {a b} {
+	    list [assemble {load a; load b; ge}] \
+		[assemble {load a; load b; gt}] \
+		[assemble {load a; load b; le}] \
+		[assemble {load a; load b; lt}]
+	}
+	list [x 0 0] [x 0 1] [x 1 0]
+    }
+    -result {{1 0 1 0} {0 0 1 1} {1 1 0 0}}
+    -cleanup {rename x {}}
+}
+test assemble-7.15 {incrArrayStk} {
+    -body {
+	proc x {} {
+	    set a(b) 5
+	    assemble {
+		push a; push b; push 7; incrArrayStk
+	    }
+	}
+	x
+    }
+    -result 12
+    -cleanup {rename x {}}
+}
+test assemble-7.16 {incrStk} {
+    -body {
+	proc x {} {
+	    set a 5
+	    assemble {
+		push a; push 7; incrStk
+	    }
+	}
+	x
+    }
+    -result 12
+    -cleanup {rename x {}}
+}
+test assemble-7.17 {land/lor} {
+    -body {
+	proc x {a b} {
+	    list \
+		[assemble {load a; load b; land}] \
+		[assemble {load a; load b; lor}]
+	}
+	list [x 0 0] [x 0 23] [x 35 0] [x 47 59]
+    }
+    -result {{0 0} {0 1} {0 1} {1 1}}
+    -cleanup {rename x {}}
+}
+test assemble-7.18 {lappendArrayStk} {
+    -body {
+	proc x {} {
+	    set able(baker) charlie
+	    assemble {
+		push able
+		push baker
+		push dog
+		lappendArrayStk
+	    }
+	}
+	x
+    }
+    -result {charlie dog}
+    -cleanup {rename x {}}
+}
+test assemble-7.19 {lappendStk} {
+    -body {
+	proc x {} {
+	    set able baker
+	    assemble {
+		push able
+		push charlie
+		lappendStk
+	    }
+	}
+	x
+    }
+    -result {baker charlie}
+    -cleanup {rename x {}}
+}
+test assemble-7.20 {listIndex} {
+    -body {
+	assemble {
+	    push {a b c d}
+	    push 2
+	    listIndex
+	}
+    }
+    -result c
+}
+test assemble-7.21 {listLength} {
+    -body {
+	assemble {
+	    push {a b c d}
+	    listLength
+	}
+    }
+    -result 4
+}
+test assemble-7.22 {loadArrayStk} {
+    -body {
+	proc x {} {
+	    set able(baker) charlie
+	    assemble {
+		push able
+		push baker
+		loadArrayStk
+	    }
+	}
+	x
+    }
+    -result charlie
+    -cleanup {rename x {}}
+}
+test assemble-7.23 {loadStk} {
+    -body {
+	proc x {} {
+	    set able baker
+	    assemble {
+		push able
+		loadStk
+	    }
+	}
+	x
+    }
+    -result baker
+    -cleanup {rename x {}}
+}
+test assemble-7.24 {lsetList} {
+    -body {
+	proc x {} {
+	    set l {{a b} {c d} {e f} {g h}}
+	    assemble {
+		push {2 1}; push i; load l; lsetList
+	    }
+	}
+	x
+    }
+    -result {{a b} {c d} {e i} {g h}}
+}
+test assemble-7.25 {lshift} {
+    -body {
+	assemble {push 16; push 4; lshift}
+    } 
+    -result 256
+}
+test assemble-7.26 {mod} {
+    -body {
+	assemble {push 123456; push 1000; mod}
+    }
+    -result 456
+}
+test assemble-7.27 {mult} {
+    -body {
+	assemble {push 12345679; push 9; mult}
+    }
+    -result 111111111
+}
+test assemble-7.28 {neq} {
+    -body {
+	list \
+	    [assemble {push able; push baker; neq}] \
+	    [assemble {push able; push able;  neq}]
+    }
+    -result {1 0}
+}
+test assemble-7.29 {not} {
+    -body {
+	list \
+	    [assemble {push 17; not}] \
+	    [assemble {push 0; not}]
+    }
+    -result {0 1}
+}
+test assemble-7.30 {pop} {
+    -body {
+	assemble {push this; pop; push that}
+    }
+    -result that
+}
+test assemble-7.31 {rshift} {
+    -body {
+	assemble {push 257; push 4; rshift}
+    } 
+    -result 16
+}
+test assemble-7.32 {storeArrayStk} {
+    -body {
+	proc x {} {
+	    assemble {
+		push able; push baker; push charlie; storeArrayStk
+	    }
+	    array get able
+	}
+	x
+    }
+    -result {baker charlie}
+    -cleanup {rename x {}}
+}
+test assemble-7.33 {storeStk} {
+    -body {
+	proc x {} {
+	    assemble {
+		push able; push baker; storeStk
+	    }
+	    set able
+	}
+	x
+    }
+    -result {baker}
+    -cleanup {rename x {}}
+}
+test assemble-7,34 {strcmp} {
+    -body {
+	proc x {a b} {
+	    assemble {
+		load a; load b; strcmp
+	    }
+	}
+	list [x able baker] [x baker able] [x baker baker]
+    }
+    -result {-1 1 0}
+    -cleanup {rename x {}}
+}
+test assemble-7.35 {streq/strneq} {
+    -body {
+	proc x {a b} {
+	    list \
+		[assemble {load a; load b; streq}] \
+		[assemble {load a; load b; strneq}]
+	}
+	list [x able able] [x able baker]
+    }
+    -result {{1 0} {0 1}}
+    -cleanup {rename x {}}
+}
+test assemble-7.36 {strindex} {
+    -body {
+	assemble {push testing; push 4; strindex}
+    }
+    -result i
+}
+test assemble-7.37 {strlen} {
+    -body {
+	assemble {push testing; strlen}
+    }
+    -result 7
+}
+test assemble-7.38 {sub} {
+    -body {
+	assemble {push 42; push 17; sub}
+    }
+    -result 25
+}
+test assemble-7.39 {tryCvtToNumeric} {
+    -body {
+	assemble {
+	    push 42; tryCvtToNumeric
+	}
+    }
+    -result 42
+}
+# assemble-7.40 absent
+test assemble-7.41 {uminus} {
+    -body {
+	assemble {
+	    push 42; uminus
+	}
+    }
+    -result -42
+}
+test assemble-7.42 {uplus} {
+    -body {
+	assemble {
+	    push 42; uplus
+	}
+    }
+    -result 42
+}
+test assemble-7.43 {uplus} {
+    -body {
+	assemble {
+	    push NaN; uplus
+	}
+    }
+    -returnCodes error
+    -result {can't use non-numeric floating-point value as operand of "+"}
+}
+test assemble-7.43.1 {tryCvtToNumeric} {
+    -body {
+	assemble {
+	    push NaN; tryCvtToNumeric
+	}
+    }
+    -returnCodes error
+    -result {domain error: argument not in valid range}
+}
+test assemble-7.44 {listIn} {
+    -body {
+	assemble {
+	    push b; push {a b c}; listIn
+	}
+    }
+    -result 1
+}
+test assemble-7.45 {listNotIn} {
+    -body {
+	assemble {
+	    push d; push {a b c}; listNotIn
+	}
+    }
+    -result 1
+}
+test assemble-7.46 {nop} {
+    -body {
+	assemble { push x; nop; nop; nop}
+    }
+    -result x
+}
+
+# assemble-8 ASSEM_LVT and FindLocalVar
+
+test assemble-8.1 {load, wrong # args} {
+    -body {
+	assemble load
+    }
+    -returnCodes error
+    -match glob
+    -result {wrong # args*}
+}
+test assemble-8.2 {load, wrong # args} {
+    -body {
+	assemble {load too many}
+    }
+    -returnCodes error
+    -match glob
+    -result {wrong # args*}
+}
+test assemble-8.3 {nonlocal var} {
+    -body {
+	list [catch {assemble {load ::env}} result] $result $errorCode
+    }
+    -result {1 {variable "::env" is not local} {TCL ASSEM NONLOCAL ::env}}
+    -cleanup {unset result}
+}
+test assemble-8.4 {bad context} {
+    -body {
+	set x 1
+	list [catch {assemble {load x}} result] $result $errorCode
+    }
+    -result {1 {cannot use this instruction to create a variable in a non-proc context} {TCL ASSEM LVT}}
+    -cleanup {unset result}
+}
+test assemble-8.5 {bad context} {
+    -body {
+	namespace eval assem {
+	    set x 1
+	    list [catch {assemble {load x}} result] $result $errorCode
+	}
+    }
+    -result {1 {cannot use this instruction to create a variable in a non-proc context} {TCL ASSEM LVT}}
+    -cleanup {namespace delete assem}
+}
+test assemble-8.6 {load1} {
+    -body {
+	proc x {a} {
+	    assemble {
+		load a
+	    }
+	}
+	x able
+    }
+    -result able
+    -cleanup {rename x {}}
+}
+test assemble-8.7 {load4} {
+    -body {
+	proc x {a} "
+	    [fillTables]
+            set b \$a
+            assemble {load b}
+        "
+	x able
+    }
+    -result able
+    -cleanup {rename x {}}
+}
+test assemble-8.8 {loadArray1} {
+    -body {
+	proc x {} {
+	    set able(baker) charlie
+	    assemble {
+		push baker
+		loadArray able
+	    }
+	}
+	x
+    }
+    -result charlie
+    -cleanup {rename x {}}
+}
+test assemble-8.9 {loadArray4} {
+    -body "
+	proc x {} {
+            [fillTables]
+	    set able(baker) charlie
+	    assemble {
+		push baker
+		loadArray able
+	    }
+	}
+	x
+    "
+    -result charlie
+    -cleanup {rename x {}}
+}
+test assemble-8.10 {append1} {
+    -body {
+	proc x {} {
+	    set y {hello, }
+	    assemble {
+		push world; append y
+	    }
+	}
+	x
+    }
+    -result {hello, world}
+    -cleanup {rename x {}}
+}
+test assemble-8.11 {append4} {
+    -body {
+	proc x {} "
+            [fillTables]
+	    set y {hello, }
+	    assemble {
+		push world; append y
+	    }
+	"
+	x
+    }
+    -result {hello, world}
+    -cleanup {rename x {}}
+}
+test assemble-8.12 {appendArray1} {
+    -body {
+	proc x {} {
+	    set y(z) {hello, }
+	    assemble {
+		push z; push world; appendArray y
+	    }
+	}
+	x
+    }
+    -result {hello, world}
+    -cleanup {rename x {}}
+}
+test assemble-8.13 {appendArray4} {
+    -body {
+	proc x {} "
+            [fillTables]
+	    set y(z) {hello, }
+	    assemble {
+		push z; push world; appendArray y
+	    }
+	"
+	x
+    }
+    -result {hello, world}
+    -cleanup {rename x {}}
+}
+test assemble-8.14 {lappend1} {
+    -body {
+	proc x {} {
+	    set y {hello,}
+	    assemble {
+		push world; lappend y
+	    }
+	}
+	x
+    }
+    -result {hello, world}
+    -cleanup {rename x {}}
+}
+test assemble-8.15 {lappend4} {
+    -body {
+	proc x {} "
+            [fillTables]
+	    set y {hello,}
+	    assemble {
+		push world; lappend y
+	    }
+	"
+	x
+    }
+    -result {hello, world}
+    -cleanup {rename x {}}
+}
+test assemble-8.16 {lappendArray1} {
+    -body {
+	proc x {} {
+	    set y(z) {hello,}
+	    assemble {
+		push z; push world; lappendArray y
+	    }
+	}
+	x
+    }
+    -result {hello, world}
+    -cleanup {rename x {}}
+}
+test assemble-8.17 {lappendArray4} {
+    -body {
+	proc x {} "
+            [fillTables]
+	    set y(z) {hello,}
+	    assemble {
+		push z; push world; lappendArray y
+	    }
+	"
+	x
+    }
+    -result {hello, world}
+    -cleanup {rename x {}}
+}
+test assemble-8.18 {store1} {
+    -body {
+	proc x {} {
+	    assemble {
+		push test; store y
+	    }
+	    set y
+	}
+	x
+    }
+    -result {test}
+    -cleanup {rename x {}}
+}
+test assemble-8.19 {store4} {
+    -body {
+	proc x {} "
+            [fillTables]
+	    assemble {
+		push test; store y
+	    }
+            set y
+	"
+	x
+    }
+    -result test
+    -cleanup {rename x {}}
+}
+test assemble-8.20 {storeArray1} {
+    -body {
+	proc x {} {
+	    assemble {
+		push z; push test; storeArray y
+	    }
+	    set y(z)
+	}
+	x
+    }
+    -result test
+    -cleanup {rename x {}}
+}
+test assemble-8.21 {storeArray4} {
+    -body {
+	proc x {} "
+            [fillTables]
+	    assemble {
+		push z; push test; storeArray y
+	    }
+	"
+	x
+    }
+    -result test
+    -cleanup {rename x {}}
+}
+
+# assemble-9 - ASSEM_CONCAT1, GetIntegerOperand, CheckOneByte
+
+test assemble-9.1 {wrong # args} {
+    -body {assemble concat}
+    -result {wrong # args*}
+    -match glob
+    -returnCodes error
+}
+test assemble-9.2 {wrong # args} {
+    -body {assemble {concat too many}}
+    -result {wrong # args*}
+    -match glob
+    -returnCodes error
+}
+test assemble-9.3 {not a number} {
+    -body {assemble {concat rubbish}}
+    -result {expected integer but got "rubbish"}
+    -returnCodes error
+}
+test assemble-9.4 {too small} {
+    -body {assemble {concat -1}}
+    -result {operand does not fit in one byte}
+    -returnCodes error
+}
+test assemble-9.5 {too small} {
+    -body {assemble {concat 256}}
+    -result {operand does not fit in one byte}
+    -returnCodes error
+}
+test assemble-9.6 {concat} {
+    -body {
+	assemble {push h; push e; push l; push l; push o; concat 5}
+    }
+    -result hello
+}
+test assemble-9.7 {concat} {
+    -body {
+	list [catch {assemble {concat 0}} result] $result $::errorCode
+    }
+    -result {1 {operand must be positive} {TCL ASSEM POSITIVE}}
+    -cleanup {unset result}
+}
+
+# assemble-10 -- eval and expr
+
+test assemble-10.1 {eval - wrong # args} {
+    -body {
+	assemble {eval}
+    }
+    -returnCodes error
+    -match glob
+    -result {wrong # args*}
+}
+test assemble-10.2 {eval - wrong # args} {
+    -body {
+	assemble {eval too many}
+    }
+    -returnCodes error
+    -match glob
+    -result {wrong # args*}
+}
+test assemble-10.3 {eval} {
+    -body {
+	proc x {} {
+	    assemble {
+		push 3
+		store n
+		pop
+		eval {expr {3*$n + 1}}
+		push 1
+		add
+	    }
+	}
+	x
+    }
+    -result 11
+    -cleanup {rename x {}}
+}
+test assemble-10.4 {expr} {
+    -body {
+	proc x {} {
+	    assemble {
+		push 3
+		store n
+		pop
+		expr {3*$n + 1}
+		push 1
+		add
+	    }
+	}
+	x
+    }
+    -result 11
+    -cleanup {rename x {}}
+}
+test assemble-10.5 {eval and expr - nonsimple} {
+    -body {
+	proc x {} {
+	    assemble {
+		eval "s\x65t n 3"
+		pop
+		expr "\x33*\$n + 1"
+		push 1
+		add
+	    }
+	}
+	x
+    }
+    -result 11
+    -cleanup {
+	rename x {}
+    }
+}
+test assemble-10.6 {eval - noncompilable} {
+    -body {
+	list [catch {assemble {eval $x}} result] $result $::errorCode
+    }
+    -result {1 {assembly code may not contain substitutions} {TCL ASSEM NOSUBST}}
+}
+test assemble-10.7 {expr - noncompilable} {
+    -body {
+	list [catch {assemble {expr $x}} result] $result $::errorCode
+    }
+    -result {1 {assembly code may not contain substitutions} {TCL ASSEM NOSUBST}}
+}
+
+# assemble-11 - ASSEM_LVT4 (exist, existArray, dictAppend, dictLappend,
+#			    nsupvar, variable, upvar)
+		
+test assemble-11.1 {exist - wrong # args} {
+    -body {
+	assemble {exist}
+    }
+    -returnCodes error
+    -match glob
+    -result {wrong # args*}
+}
+test assemble-11.2 {exist - wrong # args} {
+    -body {
+	assemble {exist too many}
+    }
+    -returnCodes error
+    -match glob
+    -result {wrong # args*}
+}
+test assemble-11.3 {nonlocal var} {
+    -body {
+	list [catch {assemble {exist ::env}} result] $result $errorCode
+    }
+    -result {1 {variable "::env" is not local} {TCL ASSEM NONLOCAL ::env}}
+    -cleanup {unset result}
+}
+test assemble-11.4 {exist} {
+    -body {
+	proc x {} {
+	    set y z
+	    list [assemble {exist y}] \
+		[assemble {exist z}]
+	}
+	x
+    }
+    -result {1 0}
+    -cleanup {rename x {}}
+}
+test assemble-11.5 {existArray} {
+    -body {
+	proc x {} {
+	    set a(b) c
+	    list [assemble {push b; existArray a}] \
+		[assemble {push c; existArray a}] \
+		[assemble {push a; existArray b}]
+	}
+	x
+    }
+    -result {1 0 0}
+    -cleanup {rename x {}}
+}
+test assemble-11.6 {dictAppend} {
+    -body {
+	proc x {} {
+	    set dict {a 1 b 2 c 3}
+	    assemble {push b; push 22; dictAppend dict}
+	}
+	x
+    }
+    -result {a 1 b 222 c 3}
+    -cleanup {rename x {}}
+}
+test assemble-11.7 {dictLappend} {
+    -body {
+	proc x {} {
+	    set dict {a 1 b 2 c 3}
+	    assemble {push b; push 2; dictLappend dict}
+	}
+	x
+    }
+    -result {a 1 b {2 2} c 3}
+    -cleanup {rename x {}}
+}
+test assemble-11.8 {upvar} {
+    -body {
+	proc x {v} {
+	    assemble {push 1; load v; upvar w; pop; load w}
+	}
+	proc y {} {
+	    set z 123
+	    x z
+	}
+	y
+    }
+    -result 123
+    -cleanup {rename x {}; rename y {}}
+}
+test assemble-11.9 {nsupvar} {
+    -body {
+	namespace eval q { variable v 123 }
+	proc x {} {
+	    assemble {push q; push v; nsupvar y; pop; load y}
+	}
+	x
+    }
+    -result 123
+    -cleanup {namespace delete q; rename x {}}
+}
+test assemble-11.10 {variable} {
+    -body {
+	namespace eval q { namespace eval r {variable v 123}}
+	proc x {} {
+	    assemble {push q::r::v; variable y; load y}
+	}
+	x
+    }
+    -result 123
+    -cleanup {namespace delete q; rename x {}}
+}
+
+# assemble-12 - ASSEM_LVT1 (incr and incrArray)
+		
+test assemble-12.1 {incr - wrong # args} {
+    -body {
+	assemble {incr}
+    }
+    -returnCodes error
+    -match glob
+    -result {wrong # args*}
+}
+test assemble-12.2 {incr - wrong # args} {
+    -body {
+	assemble {incr too many}
+    }
+    -returnCodes error
+    -match glob
+    -result {wrong # args*}
+}
+test assemble-12.3 {incr nonlocal var} {
+    -body {
+	list [catch {assemble {incr ::env}} result] $result $errorCode
+    }
+    -result {1 {variable "::env" is not local} {TCL ASSEM NONLOCAL ::env}}
+    -cleanup {unset result}
+}
+test assemble-12.4 {incr} {
+    -body {
+	proc x {} {
+	    set y 5
+	    assemble {push 3; incr y}
+	}
+	x
+    }
+    -result 8
+    -cleanup {rename x {}}
+}
+test assemble-12.5 {incrArray} {
+    -body {
+	proc x {} {
+	    set a(b) 5
+	    assemble {push b; push 3; incrArray a}
+	}
+	x
+    }
+    -result 8
+    -cleanup {rename x {}}
+}
+test assemble-12.6 {incr, stupid stack restriction} {
+    -body {
+	proc x {} "
+	    [fillTables]
+            set y 5
+            assemble {push 3; incr y}
+        "
+	list [catch {x} result] $result $errorCode
+    }
+    -result {1 {operand does not fit in one byte} {TCL ASSEM 1BYTE}}
+    -cleanup {unset result; rename x {}}
+}
+
+# assemble-13 -- ASSEM_LVT1_SINT1 - incrImm and incrArrayImm
+
+test assemble-13.1 {incrImm - wrong # args} {
+    -body {
+	assemble {incrImm x}
+    }
+    -returnCodes error
+    -match glob
+    -result {wrong # args*}
+}
+test assemble-13.2 {incrImm - wrong # args} {
+    -body {
+	assemble {incrImm too many args}
+    }
+    -returnCodes error
+    -match glob
+    -result {wrong # args*}
+}
+test assemble-13.3 {incrImm nonlocal var} {
+    -body {
+	list [catch {assemble {incrImm ::env 2}} result] $result $errorCode
+    }
+    -result {1 {variable "::env" is not local} {TCL ASSEM NONLOCAL ::env}}
+    -cleanup {unset result}
+}
+test assemble-13.4 {incrImm not a number} {
+    -body {
+	proc x {} {
+	    assemble {incrImm x rubbish}
+	}
+	x
+    }
+    -returnCodes error
+    -result {expected integer but got "rubbish"}
+    -cleanup {rename x {}}
+}
+test assemble-13.5 {incrImm too big} {
+    -body {
+	proc x {} {
+	    assemble {incrImm x 0x80}
+	}
+	list [catch x result] $result $::errorCode
+    }
+    -result {1 {operand does not fit in one byte} {TCL ASSEM 1BYTE}}
+    -cleanup {rename x {}; unset result}
+}
+test assemble-13.6 {incrImm too small} {
+    -body {
+	proc x {} {
+	    assemble {incrImm x -0x81}
+	}
+	list [catch x result] $result $::errorCode
+    }
+    -result {1 {operand does not fit in one byte} {TCL ASSEM 1BYTE}}
+    -cleanup {rename x {}; unset result}
+}
+test assemble-13.7 {incrImm} {
+    -body {
+	proc x {} {
+	    set y 1
+	    list [assemble {incrImm y -0x80}] [assemble {incrImm y 0x7f}]
+	}
+	x
+    }
+    -result {-127 0}
+    -cleanup {rename x {}}
+}
+test assemble-13.8 {incrArrayImm} {
+    -body {
+	proc x {} {
+	    set a(b) 5
+	    assemble {push b; incrArrayImm a 3}
+	}
+	x
+    }
+    -result 8
+    -cleanup {rename x {}}
+}
+test assemble-13.9 {incrImm, stupid stack restriction} {
+    -body {
+	proc x {} "
+	    [fillTables]
+            set y 5
+            assemble {incrImm y 3}
+        "
+	list [catch {x} result] $result $errorCode
+    }
+    -result {1 {operand does not fit in one byte} {TCL ASSEM 1BYTE}}
+    -cleanup {unset result; rename x {}}
+}
+
+# assemble-14 -- ASSEM_SINT1 (incrArrayStkImm and incrStkImm)
+
+test assemble-14.1 {incrStkImm - wrong # args} {
+    -body {
+	assemble {incrStkImm}
+    }
+    -returnCodes error
+    -match glob
+    -result {wrong # args*}
+}
+test assemble-14.2 {incrStkImm - wrong # args} {
+    -body {
+	assemble {incrStkImm too many}
+    }
+    -returnCodes error
+    -match glob
+    -result {wrong # args*}
+}
+test assemble-14.3 {incrStkImm not a number} {
+    -body {
+	proc x {} {
+	    assemble {incrStkImm rubbish}
+	}
+	x
+    }
+    -returnCodes error
+    -result {expected integer but got "rubbish"}
+    -cleanup {rename x {}}
+}
+test assemble-14.4 {incrStkImm too big} {
+    -body {
+	proc x {} {
+	    assemble {incrStkImm 0x80}
+	}
+	list [catch x result] $result $::errorCode
+    }
+    -result {1 {operand does not fit in one byte} {TCL ASSEM 1BYTE}}
+    -cleanup {rename x {}; unset result}
+}
+test assemble-14.5 {incrStkImm too small} {
+    -body {
+	proc x {} {
+	    assemble {incrStkImm -0x81}
+	}
+	list [catch x result] $result $::errorCode
+    }
+    -result {1 {operand does not fit in one byte} {TCL ASSEM 1BYTE}}
+    -cleanup {rename x {}; unset result}
+}
+test assemble-14.6 {incrStkImm} {
+    -body {
+	proc x {} {
+	    set y 1
+	    list [assemble {push y; incrStkImm -0x80}] \
+		[assemble {push y; incrStkImm 0x7f}]
+	}
+	x
+    }
+    -result {-127 0}
+    -cleanup {rename x {}}
+}
+test assemble-14.7 {incrArrayStkImm} {
+    -body {
+	proc x {} {
+	    set a(b) 5
+	    assemble {push a; push b; incrArrayStkImm 3}
+	}
+	x
+    }
+    -result 8
+    -cleanup {rename x {}}
+}
+
+# assemble-15 - listIndexImm
+
+test assemble-15.1 {listIndexImm - wrong # args} {
+    -body {
+	assemble {listIndexImm}
+    }
+    -returnCodes error
+    -match glob
+    -result {wrong # args*}
+}
+test assemble-15.2 {listIndexImm - wrong # args} {
+    -body {
+	assemble {listIndexImm too many}
+    }
+    -returnCodes error
+    -match glob
+    -result {wrong # args*}
+}
+test assemble-15.3 {listIndexImm - bad substitution} {
+    -body {
+	list [catch {assemble {listIndexImm $foo}} result] $result $::errorCode
+    }
+    -result {1 {assembly code may not contain substitutions} {TCL ASSEM NOSUBST}}
+    -cleanup {unset result}
+}
+test assemble-15.4 {listIndexImm - invalid index} {
+    -body {
+	assemble {listIndexImm rubbish}
+    }
+    -returnCodes error
+    -match glob
+    -result {bad index "rubbish"*}
+}
+test assemble-15.5 {listIndexImm} {
+    -body {
+	assemble {push {a b c}; listIndexImm 2}
+    }
+    -result c
+}
+test assemble-15.6 {listIndexImm} {
+    -body {
+	assemble {push {a b c}; listIndexImm end-1}
+    }
+    -result b
+}
+test assemble-15.7 {listIndexImm} {
+    -body {
+	assemble {push {a b c}; listIndexImm end}
+    }
+    -result c
+}
+
+# assemble-16 - invokeStk
+
+test assemble-16.1 {invokeStk - wrong # args} {
+    -body {
+	assemble {invokeStk}
+    }
+    -returnCodes error
+    -match glob
+    -result {wrong # args*}
+}
+test assemble-16.2 {invokeStk - wrong # args} {
+    -body {
+	assemble {invokeStk too many}
+    }
+    -returnCodes error
+    -match glob
+    -result {wrong # args*}
+}
+test assemble-16.3 {invokeStk - not a number} {
+    -body {
+	proc x {} {
+	    assemble {invokeStk rubbish}
+	}
+	x
+    }
+    -returnCodes error
+    -result {expected integer but got "rubbish"}
+    -cleanup {rename x {}}
+}
+test assemble-16.4 {invokeStk - no operands} {
+    -body {
+	proc x {} {
+	    assemble {invokeStk 0}
+	}
+	list [catch x result] $result $::errorCode
+    }
+    -result {1 {operand must be positive} {TCL ASSEM POSITIVE}}
+    -cleanup {rename x {}; unset result}
+}
+test assemble-16.5 {invokeStk1} {
+    -body {
+	tcl::unsupported::assemble {push concat; push 1; push 2; invokeStk 3}
+    }
+    -result {1 2}
+}
+test assemble-16.6 {invokeStk4} {
+    -body {
+	proc x {n} {
+	    set code {push concat}
+	    set shouldbe {}
+	    for {set i 1} {$i < $n} {incr i} {
+		append code \n {push a} $i
+		lappend shouldbe a$i
+	    }
+	    append code \n {invokeStk} { } $n
+	    set is [assemble $code]
+	    expr {$is eq $shouldbe}
+	}
+	list [x 254] [x 255] [x 256] [x 257]
+    }
+    -result {1 1 1 1}
+    -cleanup {rename x {}}
+}
+
+# assemble-17 -- jumps and labels
+
+test assemble-17.1 {label, wrong # args} {
+    -body {
+	assemble {label}
+    }
+    -returnCodes error
+    -match glob
+    -result {wrong # args*}
+}
+test assemble-17.2 {label, wrong # args} {
+    -body {
+	assemble {label too many}
+    }
+    -returnCodes error
+    -match glob
+    -result {wrong # args*}
+}
+test assemble-17.3 {label, bad subst} {
+    -body {
+	list [catch {assemble {label $foo}} result] $result $::errorCode
+    }
+    -result {1 {assembly code may not contain substitutions} {TCL ASSEM NOSUBST}}
+    -cleanup {unset result}
+}
+test assemble-17.4 {duplicate label} {
+    -body {
+	list [catch {assemble {label foo; label foo}} result] \
+	    $result $::errorCode
+    }
+    -result {1 {duplicate definition of label "foo"} {TCL ASSEM DUPLABEL foo}}
+}
+test assemble-17.5 {jump, wrong # args} {
+    -body {
+	assemble {jump}
+    }
+    -returnCodes error
+    -match glob
+    -result {wrong # args*}
+}
+test assemble-17.6 {jump, wrong # args} {
+    -body {
+	assemble {jump too many}
+    }
+    -returnCodes error
+    -match glob
+    -result {wrong # args*}
+}
+test assemble-17.7 {jump, bad subst} {
+    -body {
+	list [catch {assemble {jump $foo}} result] $result $::errorCode
+    }
+    -result {1 {assembly code may not contain substitutions} {TCL ASSEM NOSUBST}}
+    -cleanup {unset result}
+}
+test assemble-17.8 {jump - ahead and back} {
+    -body {
+	assemble {
+	    jump three
+
+	    label one
+	    push a
+	    jump four
+
+	    label two
+	    push b
+	    jump six
+
+	    label three
+	    push c
+	    jump five
+
+	    label four
+	    push d
+	    jump two
+
+	    label five
+	    push e
+	    jump one
+
+	    label six
+	    push f
+	    concat 6
+	}
+    }
+    -result ceadbf
+}
+test assemble-17.9 {jump - resolve a label multiple times} {
+    -body {
+	proc x {} {
+	    set case 0
+	    set result {}
+	    assemble {
+		jump common
+		
+		label zero
+		pop		
+		incrImm case 1
+		pop
+		push a
+		append result
+		pop
+		jump common
+		
+		label one
+		pop
+		incrImm case 1
+		pop
+		push b
+		append result
+		pop
+		jump common
+		
+		label common
+		load case
+		dup
+		push 0
+		eq
+		jumpTrue zero
+		dup
+		push 1
+		eq
+		jumpTrue one
+		dup
+		push 2
+		eq
+		jumpTrue two
+		dup
+		push 3
+		eq
+		jumpTrue three
+		
+		label two
+		pop
+		incrImm case 1
+		pop
+		push c
+		append result
+		pop
+		jump common
+		
+		label three
+		pop
+		incrImm case 1
+		pop
+		push d
+		append result
+	    }
+	}
+	x
+    }
+    -result abcd
+    -cleanup {rename x {}}
+}
+test assemble-17.10 {jump4 needed} {
+    -body {
+	assemble "push x; jump one; label two; [string repeat {dup; pop;} 128]
+	      jump three; label one; jump two; label three"
+    }
+    -result x
+}
+test assemble-17.11 {jumpTrue} {
+    -body {
+	proc x {y} {
+	    assemble {
+		load y
+		jumpTrue then
+		push no
+		jump else
+		label then
+		push yes
+		label else
+	    }
+	}
+	list [x 0] [x 1]
+    }
+    -result {no yes}
+    -cleanup {rename x {}}
+}
+test assemble-17.12 {jumpFalse} {
+    -body {
+	proc x {y} {
+	    assemble {
+		load y
+		jumpFalse then
+		push no
+		jump else
+		label then
+		push yes
+		label else
+	    }
+	}
+	list [x 0] [x 1]
+    }
+    -result {yes no}
+    -cleanup {rename x {}}
+}
+test assemble-17.13 {jump to undefined label} {
+    -body {
+	list [catch {assemble {jump nowhere}} result] $result $::errorCode
+    }
+    -result {1 {undefined label "nowhere"} {TCL ASSEM NOLABEL nowhere}}
+}
+test assemble-17.14 {jump to undefined label, line number correct?} {
+    -body {
+	catch {assemble {#1
+	    #2
+	    #3
+	    jump nowhere
+	    #5
+	    #6
+	}}
+	set ::errorInfo
+    }
+    -match glob
+    -result {*"assemble" body, line 4*}
+}
+test assemble-17.15 {multiple passes of code resizing} {
+    -setup {
+	set body {
+	    push -
+	}
+	for {set i 0} {$i < 14} {incr i} {
+	    append body "label a" $i \
+		"; push a; concat 2; nop; nop; jump b" \
+		$i \n
+	}
+	append body {label a14; push a; concat 2; push 1; jumpTrue b14} \n
+	append body {label a15; push a; concat 2; push 0; jumpFalse b15} \n
+	for {set i 0} {$i < 15} {incr i} {
+	    append body "label b" $i \
+		"; push b; concat 2; nop; nop; jump a" \
+		[expr {$i+1}] \n
+	}
+	append body {label c; push -; concat 2; nop; nop; nop; jump d} \n
+	append body {label b15; push b; concat 2; nop; nop; jump c} \n
+	append body {label d}
+	proc x {} [list assemble $body]
+    }	
+    -body {
+	x
+    }
+    -cleanup {
+	catch {unset body}
+	catch {rename x {}}
+    }
+    -result -abababababababababababababababab-
+}
+
+# assemble-18 - lindexMulti
+
+test assemble-18.1 {lindexMulti - wrong # args} {
+    -body {
+	assemble {lindexMulti}
+    }
+    -returnCodes error
+    -match glob
+    -result {wrong # args*}
+}
+test assemble-18.2 {lindexMulti - wrong # args} {
+    -body {
+	assemble {lindexMulti too many}
+    }
+    -returnCodes error
+    -match glob
+    -result {wrong # args*}
+}
+test assemble-18.3 {lindexMulti - bad subst} {
+    -body {
+	assemble {lindexMulti $foo}
+    }
+    -returnCodes error
+    -match glob
+    -result {assembly code may not contain substitutions}
+}
+test assemble-18.4 {lindexMulti - not a number} {
+    -body {
+	proc x {} {
+	    assemble {lindexMulti rubbish}
+	}
+	x
+    }
+    -returnCodes error
+    -result {expected integer but got "rubbish"}
+    -cleanup {rename x {}}
+}
+test assemble-18.5 {lindexMulti - bad operand count} {
+    -body {
+	proc x {} {
+	    assemble {lindexMulti 0}
+	}
+	list [catch x result] $result $::errorCode
+    }
+    -result {1 {operand must be positive} {TCL ASSEM POSITIVE}}
+    -cleanup {rename x {}; unset result}
+}
+test assemble-18.6 {lindexMulti} {
+    -body {
+	assemble {push {{a b c} {d e f} {g h j}}; lindexMulti 1}
+    }
+    -result {{a b c} {d e f} {g h j}}
+}
+test assemble-18.7 {lindexMulti} {
+    -body {
+	assemble {push {{a b c} {d e f} {g h j}}; push 1; lindexMulti 2}
+    }
+    -result {d e f}
+}
+test assemble-18.8 {lindexMulti} {
+    -body {
+	assemble {push {{a b c} {d e f} {g h j}}; push 2; push 1; lindexMulti 3}
+    }
+    -result h
+}
+
+# assemble-19 - list
+
+test assemble-19.1 {list - wrong # args} {
+    -body {
+	assemble {list}
+    }
+    -returnCodes error
+    -match glob
+    -result {wrong # args*}
+}
+test assemble-19.2 {list - wrong # args} {
+    -body {
+	assemble {list too many}
+    }
+    -returnCodes error
+    -match glob
+    -result {wrong # args*}
+}
+test assemble-19.3 {list - bad subst} {
+    -body {
+	assemble {list $foo}
+    }
+    -returnCodes error
+    -match glob
+    -result {assembly code may not contain substitutions}
+}
+test assemble-19.4 {list - not a number} {
+    -body {
+	proc x {} {
+	    assemble {list rubbish}
+	}
+	x
+    }
+    -returnCodes error
+    -result {expected integer but got "rubbish"}
+    -cleanup {rename x {}}
+}
+test assemble-19.5 {list - negative operand count} {
+    -body {
+	proc x {} {
+	    assemble {list -1}
+	}
+	list [catch x result] $result $::errorCode
+    }
+    -result {1 {operand must be nonnegative} {TCL ASSEM NONNEGATIVE}}
+    -cleanup {rename x {}; unset result}
+}
+test assemble-19.6 {list - no args} {
+    -body {
+	assemble {list 0}
+    }
+    -result {}
+}
+test assemble-19.7 {list - 1 arg} {
+    -body {
+	assemble {push hello; list 1}
+    }
+    -result hello
+}
+test assemble-19.8 {list - 2 args} {
+    -body {
+	assemble {push hello; push world; list 2}
+    }
+    -result {hello world}
+}
+
+# assemble-20 - lsetFlat
+
+test assemble-20.1 {lsetFlat - wrong # args} {
+    -body {
+	assemble {lsetFlat}
+    }
+    -returnCodes error
+    -match glob
+    -result {wrong # args*}
+}
+test assemble-20.2 {lsetFlat - wrong # args} {
+    -body {
+	assemble {lsetFlat too many}
+    }
+    -returnCodes error
+    -match glob
+    -result {wrong # args*}
+}
+test assemble-20.3 {lsetFlat - bad subst} {
+    -body {
+	assemble {lsetFlat $foo}
+    }
+    -returnCodes error
+    -match glob
+    -result {assembly code may not contain substitutions}
+}
+test assemble-20.4 {lsetFlat - not a number} {
+    -body {
+	proc x {} {
+	    assemble {lsetFlat rubbish}
+	}
+	x
+    }
+    -returnCodes error
+    -result {expected integer but got "rubbish"}
+    -cleanup {rename x {}}
+}
+test assemble-20.5 {lsetFlat - negative operand count} {
+    -body {
+	proc x {} {
+	    assemble {lsetFlat 1}
+	}
+	list [catch x result] $result $::errorCode
+    }
+    -result {1 {operand must be >=2} {TCL ASSEM OPERAND>=2}}
+    -cleanup {rename x {}; unset result}
+}
+test assemble-20.6 {lsetFlat} {
+    -body {
+	assemble {push b; push a; lsetFlat 2}
+    } 
+    -result b
+}
+test assemble-20.7 {lsetFlat} {
+    -body {
+	assemble {push 1; push d; push {a b c}; lsetFlat 3}
+    }
+    -result {a d c}
+}
+
+# assemble-21 - over
+
+test assemble-21.1 {over - wrong # args} {
+    -body {
+	assemble {over}
+    }
+    -returnCodes error
+    -match glob
+    -result {wrong # args*}
+}
+test assemble-21.2 {over - wrong # args} {
+    -body {
+	assemble {over too many}
+    }
+    -returnCodes error
+    -match glob
+    -result {wrong # args*}
+}
+test assemble-21.3 {over - bad subst} {
+    -body {
+	assemble {over $foo}
+    }
+    -returnCodes error
+    -match glob
+    -result {assembly code may not contain substitutions}
+}
+test assemble-21.4 {over - not a number} {
+    -body {
+	proc x {} {
+	    assemble {over rubbish}
+	}
+	x
+    }
+    -returnCodes error
+    -result {expected integer but got "rubbish"}
+    -cleanup {rename x {}}
+}
+test assemble-21.5 {over - negative operand count} {
+    -body {
+	proc x {} {
+	    assemble {over -1}
+	}
+	list [catch x result] $result $::errorCode
+    }
+    -result {1 {operand must be nonnegative} {TCL ASSEM NONNEGATIVE}}
+    -cleanup {rename x {}; unset result}
+}
+test assemble-21.6 {over} {
+    -body {
+	proc x {} {
+	    assemble {
+		push 1
+		push 2
+		push 3
+		over 0
+		store x
+		pop
+		pop
+		pop
+		pop
+		load x
+	    }
+	}
+	x
+    }
+    -result 3
+    -cleanup {rename x {}}
+}
+test assemble-21.7 {over} {
+    -body {
+	proc x {} {
+	    assemble {
+		push 1
+		push 2
+		push 3
+		over 2
+		store x
+		pop
+		pop
+		pop
+		pop
+		load x
+	    }
+	}
+	x
+    }
+    -result 1
+    -cleanup {rename x {}}
+}
+
+# assemble-22 - reverse
+
+test assemble-22.1 {reverse - wrong # args} {
+    -body {
+	assemble {reverse}
+    }
+    -returnCodes error
+    -match glob
+    -result {wrong # args*}
+}
+test assemble-22.2 {reverse - wrong # args} {
+    -body {
+	assemble {reverse too many}
+    }
+    -returnCodes error
+    -match glob
+    -result {wrong # args*}
+}
+
+test assemble-22.3 {reverse - bad subst} {
+    -body {
+	assemble {reverse $foo}
+    }
+    -returnCodes error
+    -match glob
+    -result {assembly code may not contain substitutions}
+}
+
+test assemble-22.4 {reverse - not a number} {
+    -body {
+	proc x {} {
+	    assemble {reverse rubbish}
+	}
+	x
+    }
+    -returnCodes error
+    -result {expected integer but got "rubbish"}
+    -cleanup {rename x {}}
+}
+test assemble-22.5 {reverse - negative operand count} {
+    -body {
+	proc x {} {
+	    assemble {reverse -1}
+	}
+	list [catch x result] $result $::errorCode
+    }
+    -result {1 {operand must be nonnegative} {TCL ASSEM NONNEGATIVE}}
+    -cleanup {rename x {}; unset result}
+}
+test assemble-22.6 {reverse - zero operand count} {
+    -body {
+	proc x {} {
+	    assemble {push 1; reverse 0}
+	}
+	x
+    }
+    -result 1
+    -cleanup {rename x {}}
+}
+test assemble-22.7 {reverse} {
+    -body {
+	proc x {} {
+	    assemble {
+		push 1
+		push 2
+		push 3
+		reverse 1
+		store x
+		pop
+		pop
+		pop
+		load x
+	    }
+	}
+	x
+    }
+    -result 3
+    -cleanup {rename x {}}
+}
+test assemble-22.8 {reverse} {
+    -body {
+	proc x {} {
+	    assemble {
+		push 1
+		push 2
+		push 3
+		reverse 3
+		store x
+		pop
+		pop
+		pop
+		load x
+	    }
+	}
+	x
+    }
+    -result 1
+    -cleanup {rename x {}}
+}
+
+# assemble-23 - ASSEM_BOOL (strmatch, unsetStk, unsetArrayStk)
+
+test assemble-23.1 {strmatch - wrong # args} {
+    -body {
+	assemble {strmatch}
+    }
+    -returnCodes error
+    -match glob
+    -result {wrong # args*}
+}
+test assemble-23.2 {strmatch - wrong # args} {
+    -body {
+	assemble {strmatch too many}
+    }
+    -returnCodes error
+    -match glob
+    -result {wrong # args*}
+}
+test assemble-23.3 {strmatch - bad subst} {
+    -body {
+	assemble {strmatch $foo}
+    }
+    -returnCodes error
+    -match glob
+    -result {assembly code may not contain substitutions}
+}
+test assemble-23.4 {strmatch - not a boolean} {
+    -body {
+	proc x {} {
+	    assemble {strmatch rubbish}
+	}
+	x
+    }
+    -returnCodes error
+    -result {expected boolean value but got "rubbish"}
+    -cleanup {rename x {}}
+}
+test assemble-23.5 {strmatch} {
+    -body {
+	proc x {a b} {
+	    list [assemble {load a; load b; strmatch 0}] \
+		[assemble {load a; load b; strmatch 1}]
+	}
+	list [x foo*.grill fengbar.grill] [x foo*.grill foobar.grill] [x foo*.grill FOOBAR.GRILL]
+    }
+    -result {{0 0} {1 1} {0 1}}
+    -cleanup {rename x {}}
+}
+test assemble-23.6 {unsetStk} {
+    -body {
+	proc x {} {
+	    set a {}
+	    assemble {push a; unsetStk false}
+	    info exists a
+	}
+	x
+    }
+    -result 0
+    -cleanup {rename x {}}
+}
+test assemble-23.7 {unsetStk} {
+    -body {
+	proc x {} {
+	    assemble {push a; unsetStk false}
+	    info exists a
+	}
+	x
+    }
+    -result 0
+    -cleanup {rename x {}}
+}
+test assemble-23.8 {unsetStk} {
+    -body {
+	proc x {} {
+	    assemble {push a; unsetStk true}
+	    info exists a
+	}
+	x
+    }
+    -returnCodes error
+    -result {can't unset "a": no such variable}
+    -cleanup {rename x {}}
+}
+test assemble-23.9 {unsetArrayStk} {
+    -body {
+	proc x {} {
+	    set a(b) {}
+	    assemble {push a; push b; unsetArrayStk false}
+	    info exists a(b)
+	}
+	x
+    }
+    -result 0
+    -cleanup {rename x {}}
+}
+test assemble-23.10 {unsetArrayStk} {
+    -body {
+	proc x {} {
+	    assemble {push a; push b; unsetArrayStk false}
+	    info exists a(b)
+	}
+	x
+    }
+    -result 0
+    -cleanup {rename x {}}
+}
+test assemble-23.11 {unsetArrayStk} {
+    -body {
+	proc x {} {
+	    assemble {push a; push b; unsetArrayStk true}
+	    info exists a(b)
+	}
+	x
+    }
+    -returnCodes error
+    -result {can't unset "a(b)": no such variable}
+    -cleanup {rename x {}}
+}
+
+# assemble-24 -- ASSEM_BOOL_LVT4 (unset; unsetArray)
+
+test assemble-24.1 {unset - wrong # args} {
+    -body {
+	assemble {unset one}
+    }
+    -returnCodes error
+    -match glob
+    -result {wrong # args*}
+}
+test assemble-24.2 {unset - wrong # args} {
+    -body {
+	assemble {unset too many args}
+    }
+    -returnCodes error
+    -match glob
+    -result {wrong # args*}
+}
+test assemble-24.3 {unset - bad subst -arg 1} {
+    -body {
+	assemble {unset $foo bar}
+    }
+    -returnCodes error
+    -match glob
+    -result {assembly code may not contain substitutions}
+}
+test assemble-24.4 {unset - not a boolean} {
+    -body {
+	proc x {} {
+	    assemble {unset rubbish trash}
+	}
+	x
+    }
+    -returnCodes error
+    -result {expected boolean value but got "rubbish"}
+    -cleanup {rename x {}}
+}
+test assemble-24.5 {unset - bad subst - arg 2} {
+    -body {
+	assemble {unset true $bar}
+    }
+    -returnCodes error
+    -result {assembly code may not contain substitutions}
+}
+test assemble-24.6 {unset - nonlocal var} {
+    -body {
+	assemble {unset true ::foo::bar}
+    }
+    -returnCodes error
+    -result {variable "::foo::bar" is not local}
+}
+test assemble-24.7 {unset} {
+    -body {
+	proc x {} {
+	    set a {}
+	    assemble {unset false a}
+	    info exists a
+	}
+	x
+    }
+    -result 0
+    -cleanup {rename x {}}
+}
+test assemble-24.8 {unset} {
+    -body {
+	proc x {} {
+	    assemble {unset false a}
+	    info exists a
+	}
+	x
+    }
+    -result 0
+    -cleanup {rename x {}}
+}
+test assemble-24.9 {unset} {
+    -body {
+	proc x {} {
+	    assemble {unset true a}
+	    info exists a
+	}
+	x
+    }
+    -returnCodes error
+    -result {can't unset "a": no such variable}
+    -cleanup {rename x {}}
+}
+test assemble-24.10 {unsetArray} {
+    -body {
+	proc x {} {
+	    set a(b) {}
+	    assemble {push b; unsetArray false a}
+	    info exists a(b)
+	}
+	x
+    }
+    -result 0
+    -cleanup {rename x {}}
+}
+test assemble-24.11 {unsetArray} {
+    -body {
+	proc x {} {
+	    assemble {push b; unsetArray false a}
+	    info exists a(b)
+	}
+	x
+    }
+    -result 0
+    -cleanup {rename x {}}
+}
+test assemble-24.12 {unsetArray} {
+    -body {
+	proc x {} {
+	    assemble {push b; unsetArray true a}
+	    info exists a(b)
+	}
+	x
+    }
+    -returnCodes error
+    -result {can't unset "a(b)": no such variable}
+    -cleanup {rename x {}}
+}
+
+# assemble-25 - dict get
+
+test assemble-25.1 {dict get - wrong # args} {
+    -body {
+	assemble {dictGet}
+    }
+    -returnCodes error
+    -match glob
+    -result {wrong # args*}
+}
+test assemble-25.2 {dict get - wrong # args} {
+    -body {
+	assemble {dictGet too many}
+    }
+    -returnCodes error
+    -match glob
+    -result {wrong # args*}
+}
+test assemble-25.3 {dictGet - bad subst} {
+    -body {
+	assemble {dictGet $foo}
+    }
+    -returnCodes error
+    -match glob
+    -result {assembly code may not contain substitutions}
+}
+test assemble-25.4 {dict get - not a number} {
+    -body {
+	proc x {} {
+	    assemble {dictGet rubbish}
+	}
+	x
+    }
+    -returnCodes error
+    -result {expected integer but got "rubbish"}
+    -cleanup {rename x {}}
+}
+test assemble-25.5 {dictGet - negative operand count} {
+    -body {
+	proc x {} {
+	    assemble {dictGet 0}
+	}
+	list [catch x result] $result $::errorCode
+    }
+    -result {1 {operand must be positive} {TCL ASSEM POSITIVE}}
+    -cleanup {rename x {}; unset result}
+}
+test assemble-25.6 {dictGet - 1 index} {
+    -body {
+	assemble {push {a 1 b 2}; push a; dictGet 1}
+    }
+    -result 1
+}
+
+# assemble-26 - dict set
+
+test assemble-26.1 {dict set - wrong # args} {
+    -body {
+	assemble {dictSet 1}
+    }
+    -returnCodes error
+    -match glob
+    -result {wrong # args*}
+}
+test assemble-26.2 {dict get - wrong # args} {
+    -body {
+	assemble {dictSet too many args}
+    }
+    -returnCodes error
+    -match glob
+    -result {wrong # args*}
+}
+test assemble-26.3 {dictSet - bad subst} {
+    -body {
+	assemble {dictSet 1 $foo}
+    }
+    -returnCodes error
+    -match glob
+    -result {assembly code may not contain substitutions}
+}
+test assemble-26.4 {dictSet - not a number} {
+    -body {
+	proc x {} {
+	    assemble {dictSet rubbish foo}
+	}
+	x
+    }
+    -returnCodes error
+    -result {expected integer but got "rubbish"}
+    -cleanup {rename x {}}
+}
+test assemble-26.5 {dictSet - zero operand count} {
+    -body {
+	proc x {} {
+	    assemble {dictSet 0 foo}
+	}
+	list [catch x result] $result $::errorCode
+    }
+    -result {1 {operand must be positive} {TCL ASSEM POSITIVE}}
+    -cleanup {rename x {}; unset result}
+}
+test assemble-26.6 {dictSet - bad local} {
+    -body {
+	proc x {} {
+	    assemble {dictSet 1 ::foo::bar}
+	}
+	list [catch x result] $result $::errorCode
+    }
+    -result {1 {variable "::foo::bar" is not local} {TCL ASSEM NONLOCAL ::foo::bar}}
+    -cleanup {rename x {}; unset result}
+}
+test assemble-26.7 {dictSet} {
+    -body {
+	proc x {} {
+	    set dict {a 1 b 2 c 3}
+	    assemble {push b; push 4; dictSet 1 dict}
+	}
+	x
+    }
+    -result {a 1 b 4 c 3}
+    -cleanup {rename x {}}
+}
+
+# assemble-27 - dictUnset
+
+test assemble-27.1 {dictUnset - wrong # args} {
+    -body {
+	assemble {dictUnset 1}
+    }
+    -returnCodes error
+    -match glob
+    -result {wrong # args*}
+}
+test assemble-27.2 {dictUnset - wrong # args} {
+    -body {
+	assemble {dictUnset too many args}
+    }
+    -returnCodes error
+    -match glob
+    -result {wrong # args*}
+}
+test assemble-27.3 {dictUnset - bad subst} {
+    -body {
+	assemble {dictUnset 1 $foo}
+    }
+    -returnCodes error
+    -match glob
+    -result {assembly code may not contain substitutions}
+}
+test assemble-27.4 {dictUnset - not a number} {
+    -body {
+	proc x {} {
+	    assemble {dictUnset rubbish foo}
+	}
+	x
+    }
+    -returnCodes error
+    -result {expected integer but got "rubbish"}
+    -cleanup {rename x {}}
+}
+test assemble-27.5 {dictUnset - zero operand count} {
+    -body {
+	proc x {} {
+	    assemble {dictUnset 0 foo}
+	}
+	list [catch x result] $result $::errorCode
+    }
+    -result {1 {operand must be positive} {TCL ASSEM POSITIVE}}
+    -cleanup {rename x {}; unset result}
+}
+test assemble-27.6 {dictUnset - bad local} {
+    -body {
+	proc x {} {
+	    assemble {dictUnset 1 ::foo::bar}
+	}
+	list [catch x result] $result $::errorCode
+    }
+    -result {1 {variable "::foo::bar" is not local} {TCL ASSEM NONLOCAL ::foo::bar}}
+    -cleanup {rename x {}; unset result}
+}
+test assemble-27.7 {dictUnset} {
+    -body {
+	proc x {} {
+	    set dict {a 1 b 2 c 3}
+	    assemble {push b; dictUnset 1 dict}
+	}
+	x
+    }
+    -result {a 1 c 3}
+    -cleanup {rename x {}}
+}
+
+# assemble-28 - dictIncrImm
+
+test assemble-28.1 {dictIncrImm - wrong # args} {
+    -body {
+	assemble {dictIncrImm 1}
+    }
+    -returnCodes error
+    -match glob
+    -result {wrong # args*}
+}
+test assemble-28.2 {dictIncrImm - wrong # args} {
+    -body {
+	assemble {dictIncrImm too many args}
+    }
+    -returnCodes error
+    -match glob
+    -result {wrong # args*}
+}
+test assemble-28.3 {dictIncrImm - bad subst} {
+    -body {
+	assemble {dictIncrImm 1 $foo}
+    }
+    -returnCodes error
+    -match glob
+    -result {assembly code may not contain substitutions}
+}
+test assemble-28.4 {dictIncrImm - not a number} {
+    -body {
+	proc x {} {
+	    assemble {dictIncrImm rubbish foo}
+	}
+	x
+    }
+    -returnCodes error
+    -result {expected integer but got "rubbish"}
+    -cleanup {rename x {}}
+}
+test assemble-28.5 {dictIncrImm - bad local} {
+    -body {
+	proc x {} {
+	    assemble {dictIncrImm 1 ::foo::bar}
+	}
+	list [catch x result] $result $::errorCode
+    }
+    -result {1 {variable "::foo::bar" is not local} {TCL ASSEM NONLOCAL ::foo::bar}}
+    -cleanup {rename x {}; unset result}
+}
+test assemble-28.6 {dictIncrImm} {
+    -body {
+	proc x {} {
+	    set dict {a 1 b 2 c 3}
+	    assemble {push b; dictIncrImm 42 dict}
+	}
+	x
+    }
+    -result {a 1 b 44 c 3}
+    -cleanup {rename x {}}
+}
+
+# assemble-29 - ASSEM_REGEXP
+
+test assemble-29.1 {regexp - wrong # args} {
+    -body {
+	assemble {regexp}
+    }
+    -returnCodes error
+    -match glob
+    -result {wrong # args*}
+}
+test assemble-29.2 {regexp - wrong # args} {
+    -body {
+	assemble {regexp too many}
+    }
+    -returnCodes error
+    -match glob
+    -result {wrong # args*}
+}
+test assemble-29.3 {regexp - bad subst} {
+    -body {
+	assemble {regexp $foo}
+    }
+    -returnCodes error
+    -match glob
+    -result {assembly code may not contain substitutions}
+}
+test assemble-29.4 {regexp - not a boolean} {
+    -body {
+	proc x {} {
+	    assemble {regexp rubbish}
+	}
+	x
+    }
+    -returnCodes error
+    -result {expected boolean value but got "rubbish"}
+    -cleanup {rename x {}}
+}
+test assemble-29.5 {regexp} {
+    -body {
+	assemble {push br.*br; push abracadabra; regexp false}
+    }
+    -result 1
+}
+test assemble-29.6 {regexp} {
+    -body {
+	assemble {push br.*br; push aBRacadabra; regexp false}
+    }
+    -result 0
+}
+test assemble-29.7 {regexp} {
+    -body {
+	assemble {push br.*br; push aBRacadabra; regexp true}
+    }
+    -result 1
+}
+
+# assemble-30 - Catches
+
+test assemble-30.1 {simplest possible catch} {
+    -body {
+	proc x {} {
+	    assemble {
+		beginCatch @bad
+		push error
+		push testing
+		invokeStk 2
+		pop
+		push 0
+		jump @ok
+		label @bad
+		push 1; # should be pushReturnCode
+		label @ok
+		endCatch
+	    }
+	}
+	x
+    }
+    -result 1
+    -cleanup {rename x {}}
+}
+test assemble-30.2 {catch in external catch conntext} {
+    -body {
+	proc x {} {
+	    list [catch {
+		assemble {
+		    beginCatch @bad
+		    push error
+		    push testing
+		    invokeStk 2
+		    pop
+		    push 0
+		    jump @ok
+		    label @bad
+		    pushReturnCode
+		    label @ok
+		    endCatch
+		}
+	    } result] $result
+	}
+	x
+    }
+    -result {0 1}
+    -cleanup {rename x {}}
+}
+test assemble-30.3 {embedded catches} {
+    -body {
+	proc x {} {
+	    list [catch {
+		assemble {
+		    beginCatch @bad
+		    push error
+		    eval { list [catch {error whatever} result] $result }
+		    invokeStk 2
+		    push 0
+		    reverse 2
+		    jump @done
+		    label @bad
+		    pushReturnCode
+		    pushResult
+		    label @done
+		    endCatch
+		    list 2
+		}
+	    } result2] $result2
+	}
+	x
+    }
+    -result {0 {1 {1 whatever}}}
+    -cleanup {rename x {}}
+}
+test assemble-30.4 {throw in wrong context} {
+    -body {
+	proc x {} {
+	    list [catch {
+		assemble {
+		    beginCatch @bad
+		    push error
+		    eval { list [catch {error whatever} result] $result }
+		    invokeStk 2
+		    push 0
+		    reverse 2
+		    jump @done
+
+		    label @bad
+		    load x
+		    pushResult
+
+		    label @done
+		    endCatch
+		    list 2
+		}
+	    } result] $result $::errorCode [split $::errorInfo \n]
+	}
+	x
+    }
+    -match glob
+    -result {1 {"loadScalar1" instruction may not appear in a context where an exception has been caught and not disposed of.} {TCL ASSEM BADTHROW} {{"loadScalar1" instruction may not appear in a context where an exception has been caught and not disposed of.} {    in assembly code between lines 10 and 15}*}}
+    -cleanup {rename x {}}
+}
+test assemble-30.5 {unclosed catch} {
+    -body {
+	proc x {} {
+	    assemble {
+		beginCatch @error
+		push 0
+		jump @done
+		label @error
+		push 1
+		label @done
+		push ""
+		pop
+	    }
+	}
+	list [catch {x} result] $result $::errorCode $::errorInfo
+    }
+    -match glob
+    -result {1 {catch still active on exit from assembly code} {TCL ASSEM UNCLOSEDCATCH} {catch still active on exit from assembly code
+    ("assemble" body, line 2)*}}
+    -cleanup {rename x {}}
+}
+test assemble-30.6 {inconsistent catch contexts} {
+    -body {
+	proc x {y} {
+	    assemble {
+		load y
+		jumpTrue @inblock
+		beginCatch @error
+		label @inblock
+		push 0
+		jump @done
+		label @error
+		push 1
+		label @done
+	    }
+	}
+	list [catch {x 2} result] $::errorCode $::errorInfo
+    }
+    -match glob
+    -result {1 {TCL ASSEM BADCATCH} {execution reaches an instruction in inconsistent exception contexts
+    ("assemble" body, line 5)*}}
+    -cleanup {rename x {}}
+}
+
+# assemble-31 - Jump tables
+
+test assemble-31.1 {jumpTable, wrong # args} {
+    -body {
+	assemble {jumpTable}
+    }
+    -returnCodes error
+    -match glob
+    -result {wrong # args*}
+}
+test assemble-31.2 {jumpTable, wrong # args} {
+    -body {
+	assemble {jumpTable too many}
+    }
+    -returnCodes error
+    -match glob
+    -result {wrong # args*}
+}
+test assemble-31.3 {jumpTable - bad subst} {
+    -body {
+	assemble {jumpTable $foo}
+    }
+    -returnCodes error
+    -match glob
+    -result {assembly code may not contain substitutions}
+}
+test assemble-31.4 {jumptable - not a list} {
+    -body {
+	assemble {jumpTable \{rubbish}
+    }
+    -returnCodes error
+    -result {unmatched open brace in list}
+}
+test assemble-31.5 {jumpTable, badly structured} {
+    -body {
+	list [catch {assemble {
+	    # line 2
+	    jumpTable {one two three};# line 3
+	}} result] \
+	    $result $::errorCode $::errorInfo
+    }
+    -match glob
+    -result {1 {jump table must have an even number of list elements} {TCL ASSEM BADJUMPTABLE} {jump table must have an even number of list elements*("assemble" body, line 3)*}}
+}
+test assemble-31.6 {jumpTable, missing symbol} {
+    -body {
+	list [catch {assemble {
+	    # line 2
+	    jumpTable {1 a};# line 3
+	}} result] \
+	    $result $::errorCode $::errorInfo
+    }
+    -match glob
+    -result {1 {undefined label "a"} {TCL ASSEM NOLABEL a} {undefined label "a"*("assemble" body, line 3)*}}
+}
+test assemble-31.7 {jumptable, actual example} {
+    -setup {
+	proc x {} {
+	    set result {}
+	    for {set i 0} {$i < 5} {incr i} {
+		lappend result [assemble {
+		    load i
+		    jumpTable {1 @one 2 @two 3 @three}
+		    push {none of the above}
+		    jump @done
+		    label @one
+		    push one
+		    jump @done
+		    label @two
+		    push two
+		    jump @done
+		    label @three
+		    push three
+		    label @done
+		}]
+	    }
+	    set tcl_traceCompile 2
+	    set result
+	}
+    }
+    -body x
+    -result {{none of the above} one two three {none of the above}}
+    -cleanup {set tcl_traceCompile 0; rename x {}}
+}
+
+test assemble-40.1 {unbalanced stack} {
+    -body {
+	list \
+	    [catch {
+		assemble {
+		    push 3
+		    dup 
+		    mult 
+		    push 4
+		    dup 
+		    mult 
+		    pop 
+		    expon
+		}
+	    } result] $result $::errorInfo
+    }
+    -result {1 {stack underflow} {stack underflow
+    in assembly code between lines 1 and end of assembly code*}}
+    -match glob
+   -returnCodes ok
+}
+test assemble-40.2 {unbalanced stack} {*}{
+    -body {
+	list \
+	    [catch {
+		assemble {
+		    label a
+		    push {}
+		    label b
+		    pop
+		    label c
+		    pop
+		    label d
+		    push {}
+		}
+	    } result] $result $::errorInfo
+    }
+    -result {1 {stack underflow} {stack underflow
+    in assembly code between lines 7 and 9*}}
+    -match glob
+   -returnCodes ok
+}
+
+test assemble-41.1 {Inconsistent stack usage} {*}{
+    -body {
+	proc x {y} {
+	    assemble {
+		load y
+		jumpFalse else
+		push 0
+		jump then
+	      label else
+		push 1
+		push 2
+	      label then
+		pop
+	    }
+	}
+	catch {x 1}
+	set errorInfo
+    }
+    -match glob
+    -result {inconsistent stack depths on two execution paths
+    ("assemble" body, line 10)*}
+}
+test assemble-41.2 {Inconsistent stack, jumptable and default} {
+    -body {
+	proc x {y} {
+	    assemble {
+		load y
+		jumpTable {0 else}
+		push 0
+	      label else
+		pop
+	    }
+	}
+	catch {x 1}
+	set errorInfo
+    }
+    -match glob
+    -result {inconsistent stack depths on two execution paths
+    ("assemble" body, line 6)*}
+}
+test assemble-41.3 {Inconsistent stack, two legs of jumptable} {
+    -body {
+	proc x {y} {
+	    assemble {
+		load y
+		jumpTable {0 no 1 yes}
+		label no
+		push 0
+		label yes
+		pop
+	    }
+	}
+	catch {x 1}
+	set errorInfo
+    }
+    -match glob
+    -result {inconsistent stack depths on two execution paths
+    ("assemble" body, line 7)*}
+}
+
+test assemble-50.1 {Ulam's 3n+1 problem, TAL implementation} {
+    -body {
+	proc ulam {n} {
+	    assemble {
+		load n;		# max
+		dup;		# max n
+		jump start;     # max n
+	    
+		label loop;	# max n
+		over 1;         # max n max
+		over 1;		# max in max n
+		ge;             # man n max>=n
+		jumpTrue skip;  # max n
+
+		reverse 2;      # n max
+		pop;            # n
+		dup;            # n n
+	    
+		label skip;	# max n
+		dup;            # max n n
+		push 2;         # max n n 2
+		mod;            # max n n%2
+		jumpTrue odd;   # max n
+	    
+		push 2;         # max n 2
+		div;            # max n/2 -> max n
+		jump start;     # max n
+	     
+		label odd;	# max n
+		push 3;         # max n 3
+		mult;           # max 3*n
+		push 1;         # max 3*n 1
+		add;            # max 3*n+1
+	    
+		label start;	# max n
+		dup;		# max n n
+		push 1;		# max n n 1
+		neq;		# max n n>1
+		jumpTrue loop;	# max n
+	    
+		pop;		# max
+	    }
+	}
+	set result {}
+	for {set i 1} {$i < 30} {incr i} {
+	    lappend result [ulam $i]
+	}
+	set result
+    }
+    -result {1 2 16 4 16 16 52 8 52 16 52 16 40 52 160 16 52 52 88 20 64 52 160 24 88 40 9232 52 88}
+}
+
+test assemble-51.1 {memory leak testing} memory {
+    leaktest {
+	apply {{} {assemble {push hello}}}
+    }
+} 0
+test assemble-51.2 {memory leak testing} memory {
+    leaktest {
+	apply {{{x 0}} {assemble {incrImm x 1}}}
+    }
+} 0
+test assemble-51.3 {memory leak testing} memory {
+    leaktest {
+	apply {{n} {
+	    assemble {
+		load n;		# max
+		dup;		# max n
+		jump start;     # max n
+	    
+		label loop;	# max n
+		over 1;         # max n max
+		over 1;		# max in max n
+		ge;             # man n max>=n
+		jumpTrue skip;  # max n
+
+		reverse 2;      # n max
+		pop;            # n
+		dup;            # n n
+	    
+		label skip;	# max n
+		dup;            # max n n
+		push 2;         # max n n 2
+		mod;            # max n n%2
+		jumpTrue odd;   # max n
+	    
+		push 2;         # max n 2
+		div;            # max n/2 -> max n
+		jump start;     # max n
+	     
+		label odd;	# max n
+		push 3;         # max n 3
+		mult;           # max 3*n
+		push 1;         # max 3*n 1
+		add;            # max 3*n+1
+	    
+		label start;	# max n
+		dup;		# max n n
+		push 1;		# max n n 1
+		neq;		# max n n>1
+		jumpTrue loop;	# max n
+	    
+		pop;		# max
+	    }
+	}} 1
+    }
+} 0
+test assemble-51.4 {memory leak testing} memory {
+    leaktest {
+	catch {
+	    apply {{} {
+		assemble {reverse polish notation}
+	    }}
+	}
+    }
+} 0
+
+test assemble-52.1 {Bug 3154ea2759} {
+    apply {{} {
+	# Needs six exception ranges to force the range allocations to use the
+	# malloced store.
+	::tcl::unsupported::assemble {
+	    beginCatch @badLabel
+	    push error
+	    push testing
+	    invokeStk 2
+	    pop
+	    push 0
+	    jump @okLabel
+	    label @badLabel
+	    push 1;		# should be pushReturnCode
+	    label @okLabel
+	    endCatch
+	    pop
+	    
+	    beginCatch @badLabel2
+	    push error
+	    push testing
+	    invokeStk 2
+	    pop
+	    push 0
+	    jump @okLabel2
+	    label @badLabel2
+	    push 1;		# should be pushReturnCode
+	    label @okLabel2
+	    endCatch
+	    pop
+	    
+	    beginCatch @badLabel3
+	    push error
+	    push testing
+	    invokeStk 2
+	    pop
+	    push 0
+	    jump @okLabel3
+	    label @badLabel3
+	    push 1;		# should be pushReturnCode
+	    label @okLabel3
+	    endCatch
+	    pop
+	    
+	    beginCatch @badLabel4
+	    push error
+	    push testing
+	    invokeStk 2
+	    pop
+	    push 0
+	    jump @okLabel4
+	    label @badLabel4
+	    push 1;		# should be pushReturnCode
+	    label @okLabel4
+	    endCatch
+	    pop
+	    
+	    beginCatch @badLabel5
+	    push error
+	    push testing
+	    invokeStk 2
+	    pop
+	    push 0
+	    jump @okLabel5
+	    label @badLabel5
+	    push 1;		# should be pushReturnCode
+	    label @okLabel5
+	    endCatch
+	    pop
+	    
+	    beginCatch @badLabel6
+	    push error
+	    push testing
+	    invokeStk 2
+	    pop
+	    push 0
+	    jump @okLabel6
+	    label @badLabel6
+	    push 1;		# should be pushReturnCode
+	    label @okLabel6
+	    endCatch
+	    pop
+	}
+    }}
+} {};				# must not crash
+
+rename fillTables {}
+rename assemble {}
+
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# fill-column: 78
+# End:
diff --git a/tests/assemble1.bench b/tests/assemble1.bench
new file mode 100644
index 0000000..18fd3a9
--- /dev/null
+++ b/tests/assemble1.bench
@@ -0,0 +1,85 @@
+proc ulam1 {n} {
+    set max $n
+    while {$n != 1} {
+	if {$n > $max} {
+	    set max $n
+	}
+	if {$n % 2} {
+	    set n [expr {3 * $n + 1}]
+	} else {
+	    set n [expr {$n / 2}]
+	}
+    }
+    return $max
+}
+
+set tcl_traceCompile 2; ulam1 1; set tcl_traceCompile 0
+
+proc ulam2 {n} {
+    tcl::unsupported::assemble {
+	load n;		# max
+	dup;		# max n
+	jump start;     # max n
+	
+	label loop;	# max n
+	over 1;         # max n max
+	over 1;		# max in max n
+	ge;             # man n max>=n
+	jumpTrue skip;  # max n
+
+	reverse 2;      # n max
+	pop;            # n
+	dup;            # n n
+	
+	label skip;	# max n
+	dup;            # max n n
+	push 2;         # max n n 2
+	mod;            # max n n%2
+	jumpTrue odd;   # max n
+	
+	push 2;         # max n 2
+	div;            # max n/2 -> max n
+	jump start;     # max n
+	
+	label odd;	# max n
+	push 3;         # max n 3
+	mult;           # max 3*n
+	push 1;         # max 3*n 1
+	add;            # max 3*n+1
+	
+	label start;	# max n
+	dup;		# max n n
+	push 1;		# max n n 1
+	neq;		# max n n>1
+	jumpTrue loop;	# max n
+	
+	pop;		# max
+    }
+}
+set tcl_traceCompile 2; ulam2 1; set tcl_traceCompile 0
+
+proc test1 {n} {
+    for {set i 1} {$i <= $n} {incr i} {
+	ulam1 $i  
+    }
+}
+proc test2 {n} {
+    for {set i 1} {$i <= $n} {incr i} {
+	ulam2 $i  
+    }
+}
+
+for {set j 0} {$j < 10} {incr j} {
+    test1 1
+    set before [clock microseconds]
+    test1 30000
+    set after [clock microseconds]
+    puts "compiled: [expr {1e-6 * ($after - $before)}]"
+    
+    test2 1
+    set before [clock microseconds]
+    test2 30000
+    set after [clock microseconds]
+    puts "assembled: [expr {1e-6 * ($after - $before)}]"
+}
+    
\ No newline at end of file
diff --git a/tests/assocd.test b/tests/assocd.test
new file mode 100644
index 0000000..edf55c4
--- /dev/null
+++ b/tests/assocd.test
@@ -0,0 +1,68 @@
+# This file tests the AssocData facility of Tcl
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands.  Sourcing this file into Tcl runs the tests and
+# generates output for errors.  No output means no errors were found.
+#
+# Copyright (c) 1991-1994 The Regents of the University of California.
+# Copyright (c) 1994 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+package require tcltest 2
+namespace import ::tcltest::*
+
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
+
+testConstraint testgetassocdata [llength [info commands testgetassocdata]]
+testConstraint testsetassocdata [llength [info commands testsetassocdata]]
+testConstraint testdelassocdata [llength [info commands testdelassocdata]]
+
+test assocd-1.1 {testing setting assoc data} testsetassocdata {
+   testsetassocdata a 1
+} ""
+test assocd-1.2 {testing setting assoc data} testsetassocdata {
+   testsetassocdata a 2
+} ""
+test assocd-1.3 {testing setting assoc data} testsetassocdata {
+   testsetassocdata 123 456
+} ""
+test assocd-1.4 {testing setting assoc data} testsetassocdata {
+   testsetassocdata abc "abc d e f"
+} ""
+
+test assocd-2.1 {testing getting assoc data} -setup {
+    testsetassocdata a 2
+} -constraints {testgetassocdata} -body {
+    testgetassocdata a
+} -result 2
+test assocd-2.2 {testing getting assoc data} -setup {
+    testsetassocdata 123 456
+} -constraints {testgetassocdata} -body {
+    testgetassocdata 123
+} -result 456
+test assocd-2.3 {testing getting assoc data} -setup {
+   testsetassocdata abc "abc d e f"
+} -constraints {testgetassocdata} -body {
+   testgetassocdata abc
+} -result "abc d e f"
+test assocd-2.4 {testing getting assoc data} testgetassocdata {
+   testgetassocdata xxx
+} ""
+
+test assocd-3.1 {testing deleting assoc data} testdelassocdata {
+   testdelassocdata a
+} ""
+test assocd-3.2 {testing deleting assoc data} testdelassocdata {
+   testdelassocdata 123
+} ""
+test assocd-3.3 {testing deleting assoc data} testdelassocdata {
+   list [catch {testdelassocdata nonexistent} msg] $msg
+} {0 {}}
+
+# cleanup
+cleanupTests
+return
diff --git a/tests/async.test b/tests/async.test
new file mode 100644
index 0000000..cb67cc2
--- /dev/null
+++ b/tests/async.test
@@ -0,0 +1,216 @@
+# Commands covered:  none
+#
+# This file contains a collection of tests for Tcl_AsyncCreate and related
+# library procedures.  Sourcing this file into Tcl runs the tests and
+# generates output for errors.  No output means no errors were found.
+#
+# Copyright (c) 1993 The Regents of the University of California.
+# Copyright (c) 1994-1996 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+    package require tcltest
+    namespace import -force ::tcltest::*
+}
+
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
+
+testConstraint testasync [llength [info commands testasync]]
+testConstraint threaded [::tcl::pkgconfig get threaded]
+
+proc async1 {result code} {
+    global aresult acode
+    set aresult $result
+    set acode $code
+    return "new result"
+}
+proc async2 {result code} {
+    global aresult acode
+    set aresult $result
+    set acode $code
+    return -code error "xyzzy"
+}
+proc async3 {result code} {
+    global aresult
+    set aresult "test pattern"
+    return -code $code $result
+}
+proc \# {result code} {
+    global aresult acode
+    set aresult $result
+    set acode $code
+    return "comment quoting"
+}
+
+if {[testConstraint testasync]} {
+    set handler1 [testasync create async1]
+    set handler2 [testasync create async2]
+    set handler3 [testasync create async3]
+    set handler4 [testasync create \#]
+}
+test async-1.1 {basic async handlers} testasync {
+    set aresult xxx
+    set acode yyy
+    list [catch {testasync mark $handler1 "original" 0} msg] $msg \
+	   $acode $aresult
+} {0 {new result} 0 original}
+test async-1.2 {basic async handlers} testasync {
+    set aresult xxx
+    set acode yyy
+    list [catch {testasync mark $handler1 "original" 1} msg] $msg \
+	   $acode $aresult
+} {0 {new result} 1 original}
+test async-1.3 {basic async handlers} testasync {
+    set aresult xxx
+    set acode yyy
+    list [catch {testasync mark $handler2 "old" 0} msg] $msg \
+	   $acode $aresult
+} {1 xyzzy 0 old}
+test async-1.4 {basic async handlers} testasync {
+    set aresult xxx
+    set acode yyy
+    list [catch {testasync mark $handler2 "old" 3} msg] $msg \
+	   $acode $aresult
+} {1 xyzzy 3 old}
+test async-1.5 {basic async handlers} testasync {
+    set aresult xxx
+    list [catch {testasync mark $handler3 "foobar" 0} msg] $msg $aresult
+} {0 foobar {test pattern}}
+test async-1.6 {basic async handlers} testasync {
+    set aresult xxx
+    list [catch {testasync mark $handler3 "foobar" 1} msg] $msg $aresult
+} {1 foobar {test pattern}}
+test async-1.7 {basic async handlers} testasync {
+    set aresult xxx
+    set acode yyy
+    list [catch {testasync mark $handler4 "original" 0} msg] $msg \
+	   $acode $aresult
+} {0 {comment quoting} 0 original}
+
+proc mult1 {result code} {
+    global x
+    lappend x mult1
+    return -code 7 mult1
+}
+proc mult2 {result code} {
+    global x
+    lappend x mult2
+    return -code 9 mult2
+}
+proc mult3 {result code} {
+    global x hm1 hm2
+    lappend x [catch {testasync mark $hm2 serial2 0}]
+    lappend x [catch {testasync mark $hm1 serial1 0}]
+    lappend x mult3
+    return -code 11 mult3
+}
+if {[testConstraint testasync]} {
+    set hm1 [testasync create mult1]
+    set hm2 [testasync create mult2]
+    set hm3 [testasync create mult3]
+}
+test async-2.1 {multiple handlers} testasync {
+    set x {}
+    list [catch {testasync mark $hm3 "foobar" 5} msg] $msg $x
+} {9 mult2 {0 0 mult3 mult1 mult2}}
+
+proc del1 {result code} {
+    global x hm1 hm2 hm3 hm4
+    lappend x [catch {testasync mark $hm3 serial2 0}]
+    lappend x [catch {testasync mark $hm1 serial1 0}]
+    lappend x [catch {testasync mark $hm4 serial1 0}]
+    testasync delete $hm1
+    testasync delete $hm2
+    testasync delete $hm3
+    lappend x del1
+    return -code 13 del1
+}
+proc del2 {result code} {
+    global x
+    lappend x del2
+    return -code 3 del2
+}
+if {[testConstraint testasync]} {
+    testasync delete $handler1
+    testasync delete $hm2
+    testasync delete $hm3
+    set hm2 [testasync create del1]
+    set hm3 [testasync create mult2]
+    set hm4 [testasync create del2]
+}
+
+test async-3.1 {deleting handlers} testasync {
+    set x {}
+    list [catch {testasync mark $hm2 "foobar" 5} msg] $msg $x
+} {3 del2 {0 0 0 del1 del2}}
+
+test async-4.1 {async interrupting bytecode sequence} -constraints {
+    testasync threaded
+} -setup {
+    set hm [testasync create async3]
+    proc nothing {} {
+	# empty proc
+    }
+} -body {
+    apply {{handle} {
+	global aresult
+	set aresult {Async event not delivered}
+	testasync marklater $handle
+	for {set i 0} {
+	    $i < 2500000  &&  $aresult eq "Async event not delivered"
+	} {incr i} {
+	    nothing
+	}
+	return $aresult
+    }} $hm
+} -result {test pattern} -cleanup {
+    testasync delete $hm
+}
+test async-4.2 {async interrupting straight bytecode sequence} -constraints {
+    testasync threaded
+} -setup {
+    set hm [testasync create async3]
+} -body {
+    apply {{handle} {
+	global aresult
+	set aresult {Async event not delivered}
+	testasync marklater $handle
+	for {set i 0} {
+	    $i < 2500000  &&  $aresult eq "Async event not delivered"
+	} {incr i} {}
+	return $aresult
+    }} $hm
+} -result {test pattern} -cleanup {
+    testasync delete $hm
+}
+test async-4.3 {async interrupting loop-less bytecode sequence} -constraints {
+    testasync threaded
+} -setup {
+    set hm [testasync create async3]
+} -body {
+    apply [list {handle} [concat {
+	global aresult
+	set aresult {Async event not delivered}
+	testasync marklater $handle
+	set i 0
+    } "[string repeat {;incr i;} 1500000]after 10;" {
+	return $aresult
+    }]] $hm
+} -result {test pattern} -cleanup {
+    testasync delete $hm
+}
+
+# cleanup
+if {[testConstraint testasync]} {
+    testasync delete
+}
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/tests/autoMkindex.test b/tests/autoMkindex.test
new file mode 100644
index 0000000..4721553
--- /dev/null
+++ b/tests/autoMkindex.test
@@ -0,0 +1,372 @@
+# Commands covered:  auto_mkindex auto_import
+#
+# This file contains tests related to autoloading and generating the
+# autoloading index.
+#
+# Copyright (c) 1998  Lucent Technologies, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution of
+# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {"::tcltest" ni [namespace children]} {
+    package require tcltest 2
+    namespace import -force ::tcltest::*
+}
+
+makeFile {# Test file for:
+#   auto_mkindex
+#
+# This file provides example cases for testing the Tcl autoloading facility.
+# Things are much more complicated with namespaces and classes.  The
+# "auto_mkindex" facility can no longer be built on top of a simple regular
+# expression parser.  It must recognize constructs like this:
+#
+#   namespace eval foo {
+#       proc test {x y} { ... }
+#       namespace eval bar {
+#           proc another {args} { ... }
+#       }
+#   }
+#
+# Note that procedures and itcl class definitions can be nested inside of
+# namespaces.
+#
+# Copyright (c) 1993-1998  Lucent Technologies, Inc.
+
+# This shouldn't cause any problems
+namespace import -force blt::*
+
+# Should be able to handle "proc" definitions, even if they are preceded by
+# white space.
+
+proc normal {x y} {return [expr $x+$y]}
+  proc indented {x y} {return [expr $x+$y]}
+
+#
+# Should be able to handle proc declarations within namespaces, even if they
+# have explicit namespace paths.
+#
+namespace eval buried {
+    proc inside {args} {return "inside: $args"}
+
+    namespace export pub_*
+    proc pub_one {args} {return "one: $args"}
+    proc pub_two {args} {return "two: $args"}
+}
+proc buried::within {args} {return "within: $args"}
+
+namespace eval buried {
+    namespace eval under {
+        proc neath {args} {return "neath: $args"}
+    }
+    namespace eval ::buried {
+        proc relative {args} {return "relative: $args"}
+        proc ::top {args} {return "top: $args"}
+        proc ::buried::explicit {args} {return "explicit: $args"}
+    }
+}
+
+# With proper hooks, we should be able to support other commands that create
+# procedures
+
+proc buried::myproc {name body args} {
+    ::proc $name $body $args
+}
+namespace eval ::buried {
+    proc mycmd1 args {return "mycmd"}
+    myproc mycmd2 args {return "mycmd"}
+}
+::buried::myproc mycmd3 args {return "another"}
+
+proc {buried::my proc} {name body args} {
+    ::proc $name $body $args
+}
+namespace eval ::buried {
+    proc mycmd4 args {return "mycmd"}
+    {my proc} mycmd5 args {return "mycmd"}
+}
+{::buried::my proc} mycmd6 args {return "another"}
+
+# A correctly functioning [auto_import] won't choke when a child namespace
+# [namespace import]s from its parent.
+#
+namespace eval ::parent::child {
+    namespace import ::parent::*
+}
+proc ::parent::child::test {} {}
+} autoMkindex.tcl
+
+# Save initial state of auto_mkindex_parser
+
+auto_load auto_mkindex
+if {[info exists auto_mkindex_parser::initCommands]} {
+    set saveCommands $auto_mkindex_parser::initCommands
+}
+proc AutoMkindexTestReset {} {
+    global saveCommands
+    if {[info exists saveCommands]} {
+	set auto_mkindex_parser::initCommands $saveCommands
+    } elseif {[info exists auto_mkindex_parser::initCommands]} {
+	unset auto_mkindex_parser::initCommands
+    }
+}
+
+set result ""
+
+set origDir [pwd]
+cd $::tcltest::temporaryDirectory
+
+test autoMkindex-1.1 {remove any existing tclIndex file} {
+    file delete tclIndex
+    file exists tclIndex
+} {0}
+test autoMkindex-1.2 {build tclIndex based on a test file} {
+    auto_mkindex . autoMkindex.tcl
+    file exists tclIndex
+} {1}
+set element "{source [file join . autoMkindex.tcl]}"
+test autoMkindex-1.3 {examine tclIndex} -setup {
+    file delete tclIndex
+} -body {
+    auto_mkindex . autoMkindex.tcl
+    namespace eval tcl_autoMkindex_tmp {
+        set dir "."
+        variable auto_index
+        source tclIndex
+        set ::result ""
+        foreach elem [lsort [array names auto_index]] {
+            lappend ::result [list $elem $auto_index($elem)]
+        }
+    }
+    return $result
+} -cleanup {
+    namespace delete tcl_autoMkindex_tmp
+} -result "{::buried::explicit $element} {::buried::inside $element} {{::buried::my proc} $element} {::buried::mycmd1 $element} {::buried::mycmd4 $element} {::buried::myproc $element} {::buried::pub_one $element} {::buried::pub_two $element} {::buried::relative $element} {::buried::under::neath $element} {::buried::within $element} {::parent::child::test $element} {indented $element} {normal $element} {top $element}"
+
+test autoMkindex-2.1 {commands on the autoload path can be imported} -setup {
+    file delete tclIndex
+    interp create slave
+} -body {
+    auto_mkindex . autoMkindex.tcl
+    slave eval {
+        namespace eval blt {}
+        set auto_path [linsert $auto_path 0 .]
+        set info [list [catch {namespace import buried::*} result] $result]
+        foreach name [lsort [info commands pub_*]] {
+            lappend info $name [namespace origin $name]
+        }
+        return $info
+    }
+} -cleanup {
+    interp delete slave
+} -result "0 {} pub_one ::buried::pub_one pub_two ::buried::pub_two"
+
+# Test auto_mkindex hooks
+
+# Slave hook executes interesting code in the interp used to watch code.
+test autoMkindex-3.1 {slaveHook} -setup {
+    file delete tclIndex
+} -body {
+    auto_mkindex_parser::slavehook {
+	_%@namespace eval ::blt {
+	    proc foo {} {}
+	    _%@namespace export foo
+	}
+    }
+    auto_mkindex_parser::slavehook { _%@namespace import -force ::blt::* }
+    auto_mkindex . autoMkindex.tcl
+    file exists tclIndex
+} -cleanup {
+    # Reset initCommands to avoid trashing other tests
+    AutoMkindexTestReset
+} -result 1 
+# The auto_mkindex_parser::command is used to register commands that create
+# new commands.
+test autoMkindex-3.2 {auto_mkindex_parser::command} -setup {
+    file delete tclIndex
+} -body {
+    auto_mkindex_parser::command buried::myproc {name args} {
+	variable index
+	variable scriptFile
+	append index [list set auto_index([fullname $name])] \
+		" \[list source \[file join \$dir [list $scriptFile]\]\]\n"
+    }
+    auto_mkindex . autoMkindex.tcl
+    namespace eval tcl_autoMkindex_tmp {
+        set dir "."
+        variable auto_index
+        source tclIndex
+        set ::result ""
+        foreach elem [lsort [array names auto_index]] {
+            lappend ::result [list $elem $auto_index($elem)]
+        }
+	return $::result
+    }
+} -cleanup {
+    namespace delete tcl_autoMkindex_tmp
+    # Reset initCommands to avoid trashing other tests
+    AutoMkindexTestReset
+} -result "{::buried::explicit $element} {::buried::inside $element} {{::buried::my proc} $element} {::buried::mycmd1 $element} {::buried::mycmd2 $element} {::buried::mycmd4 $element} {::buried::myproc $element} {::buried::pub_one $element} {::buried::pub_two $element} {::buried::relative $element} {::buried::under::neath $element} {::buried::within $element} {::parent::child::test $element} {indented $element} {mycmd3 $element} {normal $element} {top $element}"
+test autoMkindex-3.3 {auto_mkindex_parser::command} -setup {
+    file delete tclIndex
+} -constraints {knownBug} -body {
+    auto_mkindex_parser::command {buried::my proc} {name args} {
+	variable index
+	variable scriptFile
+	puts "my proc $name"
+	append index [list set auto_index([fullname $name])] \
+		" \[list source \[file join \$dir [list $scriptFile]\]\]\n"
+    }
+    auto_mkindex . autoMkindex.tcl
+    namespace eval tcl_autoMkindex_tmp {
+        set dir "."
+        variable auto_index
+        source tclIndex
+        set ::result ""
+        foreach elem [lsort [array names auto_index]] {
+            lappend ::result [list $elem $auto_index($elem)]
+        }
+    }
+    list [lsearch -inline $::result *mycmd4*] \
+	[lsearch -inline $::result *mycmd5*] \
+	[lsearch -inline $::result *mycmd6*]
+} -cleanup {
+    namespace delete tcl_autoMkindex_tmp
+    # Reset initCommands to avoid trashing other tests
+    AutoMkindexTestReset
+} -result "{::buried::mycmd4 $element} {::buried::mycmd5 $element} {mycmd6 $element}"
+makeFile {
+
+namespace eval wok {
+    namespace ensemble create -subcommands {commands vars}
+
+    proc commands {{pattern *}} {
+	puts [join [lsort -dictionary [info commands $pattern]] \n]
+    }
+
+    proc vars {{pattern *}} {
+	puts [join [lsort -dictionary [info vars $pattern]] \n]
+    }
+
+}
+
+} ensemblecommands.tcl
+
+test autoMkindex-3.4 {ensemble commands in tclIndex} {
+    file delete tclIndex
+    auto_mkindex . ensemblecommands.tcl
+    set f [open tclIndex r]
+    set dat [list]
+    foreach r [split [string trim [read $f]] "\n"] {
+	if {[string match {set auto_index*} $r]} {
+	    lappend dat $r
+	}
+    }
+    set result [lsort $dat]
+    close $f
+    set result
+} {{set auto_index(::wok::commands) [list source [file join $dir ensemblecommands.tcl]]} {set auto_index(::wok::vars) [list source [file join $dir ensemblecommands.tcl]]} {set auto_index(wok) [list source [file join $dir ensemblecommands.tcl]]}}
+removeFile ensemblecommands.tcl
+
+test autoMkindex-4.1 {platform independent source commands} -setup {
+    file delete tclIndex
+    makeDirectory pkg
+    makeFile {
+	package provide football 1.0
+	namespace eval ::pro:: {
+	    #
+	    # export only public functions.
+	    #
+	    namespace export {[a-z]*}
+	}
+	namespace eval ::college:: {
+	    #
+	    # export only public functions.
+	    #
+	    namespace export {[a-z]*}
+	}
+	proc ::pro::team {} {
+	    puts "go packers!"
+	    return true
+	}
+	proc ::college::team {} {
+	    puts "go badgers!"
+	    return true
+	}
+    } [file join pkg samename.tcl]
+} -body {
+    auto_mkindex . pkg/samename.tcl
+    set f [open tclIndex r]
+    lsort [lrange [split [string trim [read $f]] "\n"] end-1 end]
+} -cleanup {
+    catch {close $f}
+    removeFile [file join pkg samename.tcl]
+    removeDirectory pkg
+} -result {{set auto_index(::college::team) [list source [file join $dir pkg samename.tcl]]} {set auto_index(::pro::team) [list source [file join $dir pkg samename.tcl]]}}
+
+test autoMkindex-5.1 {escape magic tcl chars in general code} -setup {
+    file delete tclIndex
+    makeDirectory pkg
+    makeFile {
+	set dollar1 "this string contains an unescaped dollar sign -> \\$foo"
+	set dollar2 \
+	    "this string contains an escaped dollar sign -> \$foo \\\$foo"
+	set bracket1 "this contains an unescaped bracket [NoSuchProc]"
+	set bracket2 "this contains an escaped bracket \[NoSuchProc\]"
+	set bracket3 \
+	    "this contains nested unescaped brackets [[NoSuchProc]]"
+	proc testProc {} {}
+    } [file join pkg magicchar.tcl]
+    set result {}
+} -body {
+    auto_mkindex . pkg/magicchar.tcl
+    set f [open tclIndex r]
+    lindex [split [string trim [read $f]] "\n"] end
+} -cleanup {
+    catch {close $f}
+    removeFile [file join pkg magicchar.tcl]
+    removeDirectory pkg
+} -result {set auto_index(testProc) [list source [file join $dir pkg magicchar.tcl]]}
+test autoMkindex-5.2 {correctly locate auto loaded procs with []} -setup {
+    file delete tclIndex
+    makeDirectory pkg
+    makeFile {
+	proc {[magic mojo proc]} {} {}
+    } [file join pkg magicchar2.tcl]
+    set result {}
+    interp create slave
+} -body {
+    auto_mkindex . pkg/magicchar2.tcl
+    # Make a slave interp to test the autoloading
+    slave eval {lappend auto_path [pwd]}
+    slave eval {catch {{[magic mojo proc]}}}
+} -cleanup {
+    interp delete slave
+    removeFile [file join pkg magicchar2.tcl]
+    removeDirectory pkg
+} -result 0
+
+# Clean up.
+
+unset result
+AutoMkindexTestReset
+if {[info exists saveCommands]} {
+    unset saveCommands
+}
+rename AutoMkindexTestReset ""
+
+removeFile autoMkindex.tcl
+if {[file exists tclIndex]} {
+    file delete -force tclIndex
+}
+
+cd $origDir
+
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# fill-column: 78
+# End:
diff --git a/tests/basic.test b/tests/basic.test
new file mode 100644
index 0000000..1a0037c
--- /dev/null
+++ b/tests/basic.test
@@ -0,0 +1,987 @@
+# This file contains tests for the tclBasic.c source file. Tests appear in
+# the same order as the C code that they test. The set of tests is
+# currently incomplete since it currently includes only new tests for
+# code changed for the addition of Tcl namespaces. Other variable-
+# related tests appear in several other test files including
+# assocd.test, cmdInfo.test, eval.test, expr.test, interp.test,
+# and trace.test.
+#
+# Sourcing this file into Tcl runs the tests and generates output for
+# errors. No output means no errors were found.
+#
+# Copyright (c) 1997 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+package require tcltest 2
+namespace import ::tcltest::*
+
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
+
+testConstraint testevalex [llength [info commands testevalex]]
+testConstraint testcmdtoken [llength [info commands testcmdtoken]]
+testConstraint testcreatecommand [llength [info commands testcreatecommand]]
+testConstraint exec [llength [info commands exec]]
+
+catch {namespace delete test_ns_basic}
+catch {interp delete test_interp}
+catch {rename p ""}
+catch {rename q ""}
+catch {rename cmd ""}
+unset -nocomplain x
+
+test basic-1.1 {Tcl_CreateInterp, creates interp's global namespace} {
+    catch {interp delete test_interp}
+    interp create test_interp
+    interp eval test_interp {
+        namespace eval test_ns_basic {
+            proc p {} {
+                return [namespace current]
+            }
+        }
+    }
+    list [interp eval test_interp {test_ns_basic::p}] \
+         [interp delete test_interp]
+} {::test_ns_basic {}}
+
+test basic-2.1 {TclHideUnsafeCommands} {emptyTest} {
+} {}
+
+test basic-3.1 {Tcl_CallWhenDeleted: see dcall.test} {emptyTest} {
+} {}
+
+test basic-4.1 {Tcl_DontCallWhenDeleted: see dcall.test} {emptyTest} {
+} {}
+
+test basic-5.1 {Tcl_SetAssocData: see assoc.test} {emptyTest} {
+} {}
+
+test basic-6.1 {Tcl_DeleteAssocData: see assoc.test} {emptyTest} {
+} {}
+
+test basic-7.1 {Tcl_GetAssocData: see assoc.test} {emptyTest} {
+} {}
+
+test basic-8.1 {Tcl_InterpDeleted} {emptyTest} {
+} {}
+
+test basic-9.1 {Tcl_DeleteInterp: see interp.test} {emptyTest} {
+} {}
+
+test basic-10.1 {DeleteInterpProc, destroys interp's global namespace} {
+    catch {interp delete test_interp}
+    interp create test_interp
+    interp eval test_interp {
+        namespace eval test_ns_basic {
+            namespace export p
+            proc p {} {
+                return [namespace current]
+            }
+        }
+        namespace eval test_ns_2 {
+            namespace import ::test_ns_basic::p
+            variable v 27
+            proc q {} {
+                variable v
+                return "[p] $v"
+            }
+        }
+    }
+    list [interp eval test_interp {test_ns_2::q}] \
+         [interp eval test_interp {namespace delete ::}] \
+         [catch {interp eval test_interp {set a 123}} msg] $msg \
+         [interp delete test_interp]
+} {{::test_ns_basic 27} {} 1 {invalid command name "set"} {}}
+
+test basic-11.1 {HiddenCmdsDeleteProc, invalidate cached refs to deleted hidden cmd} {
+    catch {interp delete test_interp}
+    interp create test_interp
+    interp eval test_interp {
+        proc p {} {
+            return 27
+        }
+    }
+    interp alias {} localP test_interp p
+    list [interp eval test_interp {p}] \
+         [localP] \
+         [test_interp hide p] \
+         [catch {localP} msg] $msg \
+         [interp delete test_interp] \
+         [catch {localP} msg] $msg
+} {27 27 {} 1 {invalid command name "p"} {} 1 {invalid command name "localP"}}
+
+# NB: More tests about hide/expose are found in interp.test
+
+test basic-12.1 {Tcl_HideCommand, names of hidden cmds can't have namespace qualifiers} {
+    catch {interp delete test_interp}
+    interp create test_interp
+    interp eval test_interp {
+        namespace eval test_ns_basic {
+            proc p {} {
+                return [namespace current]
+            }
+        }
+    }
+    list [catch {test_interp hide test_ns_basic::p x} msg] $msg \
+	 [catch {test_interp hide x test_ns_basic::p} msg1] $msg1 \
+         [interp delete test_interp]
+} {1 {can only hide global namespace commands (use rename then hide)} 1 {cannot use namespace qualifiers in hidden command token (rename)} {}}
+
+test basic-12.2 {Tcl_HideCommand, a hidden cmd remembers its containing namespace} {
+    catch {namespace delete test_ns_basic}
+    catch {rename cmd ""}
+    proc cmd {} {   ;# note that this is global
+        return [namespace current]
+    }
+    namespace eval test_ns_basic {
+        proc hideCmd {} {
+            interp hide {} cmd
+        }
+        proc exposeCmd {} {
+            interp expose {} cmd
+        }
+        proc callCmd {} {
+            cmd
+        }
+    }
+    list [test_ns_basic::callCmd] \
+         [test_ns_basic::hideCmd] \
+         [catch {cmd} msg] $msg \
+         [test_ns_basic::exposeCmd] \
+         [test_ns_basic::callCmd] \
+         [namespace delete test_ns_basic]
+} {:: {} 1 {invalid command name "cmd"} {} :: {}}
+
+test basic-13.1 {Tcl_ExposeCommand, a command stays in the global namespace and cannot go to another namespace} {
+    catch {namespace delete test_ns_basic}
+    catch {rename cmd ""}
+    proc cmd {} {   ;# note that this is global
+        return [namespace current]
+    }
+    namespace eval test_ns_basic {
+        proc hideCmd {} {
+            interp hide {} cmd
+        }
+        proc exposeCmdFailing {} {
+            interp expose {} cmd ::test_ns_basic::newCmd
+        }
+        proc exposeCmdWorkAround {} {
+            interp expose {} cmd;
+	    rename cmd ::test_ns_basic::newCmd;
+        }
+        proc callCmd {} {
+            cmd
+        }
+    }
+    list [test_ns_basic::callCmd] \
+         [test_ns_basic::hideCmd] \
+         [catch {test_ns_basic::exposeCmdFailing} msg] $msg \
+         [test_ns_basic::exposeCmdWorkAround] \
+         [test_ns_basic::newCmd] \
+         [namespace delete test_ns_basic]
+} {:: {} 1 {cannot expose to a namespace (use expose to toplevel, then rename)} {} ::test_ns_basic {}}
+test basic-13.2 {Tcl_ExposeCommand, invalidate cached refs to cmd now being exposed} {
+    catch {rename p ""}
+    catch {rename cmd ""}
+    proc p {} {
+        cmd
+    }
+    proc cmd {} {
+        return 42
+    }
+    list [p] \
+         [interp hide {} cmd] \
+         [proc cmd {} {return Hello}] \
+         [cmd] \
+         [rename cmd ""] \
+         [interp expose {} cmd] \
+         [p]
+} {42 {} {} Hello {} {} 42}
+
+test basic-14.1 {Tcl_CreateCommand, new cmd goes into a namespace specified in its name, if any} {testcreatecommand} {
+    catch {namespace delete {*}[namespace children :: test_ns_*]}
+    list [testcreatecommand create] \
+	 [test_ns_basic::createdcommand] \
+	 [testcreatecommand delete]
+} {{} {CreatedCommandProc in ::test_ns_basic} {}}
+test basic-14.2 {Tcl_CreateCommand, namespace code ignore single ":"s in middle or end of names} {testcreatecommand} {
+    catch {namespace delete {*}[namespace children :: test_ns_*]}
+    catch {rename value:at: ""}
+    list [testcreatecommand create2] \
+	 [value:at:] \
+	 [testcreatecommand delete2]
+} {{} {CreatedCommandProc2 in ::} {}}
+
+test basic-15.1 {Tcl_CreateObjCommand, new cmd goes into a namespace specified in its name, if any} {
+    catch {namespace delete {*}[namespace children :: test_ns_*]}
+    namespace eval test_ns_basic {}
+    proc test_ns_basic::cmd {} {  ;# proc requires that ns already exist
+        return [namespace current]
+    }
+    list [test_ns_basic::cmd] \
+         [namespace delete test_ns_basic]
+} {::test_ns_basic {}}
+
+test basic-16.1 {TclInvokeStringCommand} {emptyTest} {
+} {}
+
+test basic-17.1 {TclInvokeObjCommand} {emptyTest} {
+} {}
+
+test basic-18.1 {TclRenameCommand, name of existing cmd can have namespace qualifiers} {
+    catch {namespace delete {*}[namespace children :: test_ns_*]}
+    catch {rename cmd ""}
+    namespace eval test_ns_basic {
+        proc p {} {
+            return "p in [namespace current]"
+        }
+    }
+    list [test_ns_basic::p] \
+         [rename test_ns_basic::p test_ns_basic::q] \
+         [test_ns_basic::q] 
+} {{p in ::test_ns_basic} {} {p in ::test_ns_basic}}
+test basic-18.2 {TclRenameCommand, existing cmd must be found} {
+    catch {namespace delete {*}[namespace children :: test_ns_*]}
+    list [catch {rename test_ns_basic::p test_ns_basic::q} msg] $msg
+} {1 {can't rename "test_ns_basic::p": command doesn't exist}}
+test basic-18.3 {TclRenameCommand, delete cmd if new name is empty} {
+    catch {namespace delete {*}[namespace children :: test_ns_*]}
+    namespace eval test_ns_basic {
+        proc p {} {
+            return "p in [namespace current]"
+        }
+    }
+    list [info commands test_ns_basic::*] \
+         [rename test_ns_basic::p ""] \
+         [info commands test_ns_basic::*]
+} {::test_ns_basic::p {} {}}
+test basic-18.4 {TclRenameCommand, bad new name} {
+    catch {namespace delete {*}[namespace children :: test_ns_*]}
+    namespace eval test_ns_basic {
+        proc p {} {
+            return "p in [namespace current]"
+        }
+    }
+    rename test_ns_basic::p :::george::martha
+} {}
+test basic-18.5 {TclRenameCommand, new name must not already exist} -setup {
+    if {![llength [info commands :::george::martha]]} {
+        catch {namespace delete {*}[namespace children :: test_ns_*]}
+        namespace eval test_ns_basic {
+            proc p {} {
+                return "p in [namespace current]"
+            }
+        }
+        rename test_ns_basic::p :::george::martha
+    }
+} -body {
+    namespace eval test_ns_basic {
+        proc q {} {
+            return 42
+        }
+    }
+    list [catch {rename test_ns_basic::q :::george::martha} msg] $msg
+} -result {1 {can't rename to ":::george::martha": command already exists}}
+test basic-18.6 {TclRenameCommand, check for command shadowing by newly renamed cmd} {
+    catch {namespace delete {*}[namespace children :: test_ns_*]}
+    catch {rename p ""}
+    catch {rename q ""}
+    proc p {} {
+        return "p in [namespace current]"
+    }
+    proc q {} {
+        return "q in [namespace current]"
+    }
+    namespace eval test_ns_basic {
+        proc callP {} {
+            p
+        }
+    }
+    list [test_ns_basic::callP] \
+         [rename q test_ns_basic::p] \
+         [test_ns_basic::callP]
+} {{p in ::} {} {q in ::test_ns_basic}}
+
+test basic-19.1 {Tcl_SetCommandInfo} {emptyTest} {
+} {}
+
+test basic-20.1 {Tcl_GetCommandInfo, names for commands created inside namespaces} {testcmdtoken} {
+    catch {namespace delete {*}[namespace children :: test_ns_*]}
+    catch {rename p ""}
+    catch {rename q ""}
+    unset -nocomplain x
+    set x [namespace eval test_ns_basic::test_ns_basic2 {
+        # the following creates a cmd in the global namespace
+        testcmdtoken create p
+    }]
+    list [testcmdtoken name $x] \
+         [rename ::p q] \
+         [testcmdtoken name $x]
+} {{p ::p} {} {q ::q}}
+test basic-20.2 {Tcl_GetCommandInfo, names for commands created outside namespaces} {testcmdtoken} {
+    catch {rename q ""}
+    set x [testcmdtoken create test_ns_basic::test_ns_basic2::p]
+    list [testcmdtoken name $x] \
+         [rename test_ns_basic::test_ns_basic2::p q] \
+         [testcmdtoken name $x]
+} {{p ::test_ns_basic::test_ns_basic2::p} {} {q ::q}}
+test basic-20.3 {Tcl_GetCommandInfo, #-quoting} testcmdtoken {
+    catch {rename \# ""}
+    set x [testcmdtoken create \#]
+    testcmdtoken name $x
+} {{#} ::#}
+
+test basic-21.1 {Tcl_GetCommandName} {emptyTest} {
+} {}
+
+test basic-22.1 {Tcl_GetCommandFullName} {
+    catch {namespace delete {*}[namespace children :: test_ns_*]}
+    namespace eval test_ns_basic1 {
+        namespace export cmd*
+        proc cmd1 {} {}
+        proc cmd2 {} {}
+    }
+    namespace eval test_ns_basic2 {
+        namespace export *
+        namespace import ::test_ns_basic1::*
+        proc p {} {}
+    }
+    namespace eval test_ns_basic3 {
+        namespace import ::test_ns_basic2::*
+        proc q {} {}
+        list [namespace which -command foreach] \
+             [namespace which -command q] \
+             [namespace which -command p] \
+             [namespace which -command cmd1] \
+             [namespace which -command ::test_ns_basic2::cmd2]
+    }
+} {::foreach ::test_ns_basic3::q ::test_ns_basic3::p ::test_ns_basic3::cmd1 ::test_ns_basic2::cmd2}
+
+test basic-23.1 {Tcl_DeleteCommand} {emptyTest} {
+} {}
+
+test basic-24.1 {Tcl_DeleteCommandFromToken, invalidate all compiled code if cmd has compile proc} {
+    catch {interp delete test_interp}
+    unset -nocomplain x
+    interp create test_interp
+    interp eval test_interp {
+        proc useSet {} {
+            return [set a 123]
+        }
+    }
+    set x [interp eval test_interp {useSet}]
+    interp eval test_interp {
+        rename set ""
+        proc set {args} {
+            return "set called with $args"
+        }
+    }
+    list $x \
+         [interp eval test_interp {useSet}] \
+         [interp delete test_interp]
+} {123 {set called with a 123} {}}
+test basic-24.2 {Tcl_DeleteCommandFromToken, deleting commands changes command epoch} {
+    catch {namespace delete {*}[namespace children :: test_ns_*]}
+    catch {rename p ""}
+    proc p {} {
+        return "global p"
+    }
+    namespace eval test_ns_basic {
+        proc p {} {
+            return "namespace p"
+        }
+        proc callP {} {
+            p
+        }
+    }
+    list [test_ns_basic::callP] \
+         [rename test_ns_basic::p ""] \
+         [test_ns_basic::callP]
+} {{namespace p} {} {global p}}
+test basic-24.3 {Tcl_DeleteCommandFromToken, delete imported cmds that refer to a deleted cmd} {
+    catch {namespace delete {*}[namespace children :: test_ns_*]}
+    catch {rename p ""}
+    namespace eval test_ns_basic {
+        namespace export p
+        proc p {} {return 42}
+    }
+    namespace eval test_ns_basic2 {
+        namespace import ::test_ns_basic::*
+        proc callP {} {
+            p
+        }
+    }
+    list [test_ns_basic2::callP] \
+         [info commands test_ns_basic2::*] \
+         [rename test_ns_basic::p ""] \
+         [catch {test_ns_basic2::callP} msg] $msg \
+         [info commands test_ns_basic2::*]
+} {42 {::test_ns_basic2::callP ::test_ns_basic2::p} {} 1 {invalid command name "p"} ::test_ns_basic2::callP}
+
+test basic-25.1 {TclCleanupCommand} {emptyTest} {
+} {}
+
+test basic-26.1 {Tcl_EvalObj: preserve object while evaling it} -setup {
+    proc myHandler {msg options} {
+	set ::x [dict get $options -errorinfo]
+    }
+    set handler [interp bgerror {}]
+    interp bgerror {} [namespace which myHandler]
+    set fName [makeFile {} test1]
+} -body {
+    # If object isn't preserved, errorInfo would be set to
+    # "foo\n    while executing\n\"garbage bytes\"" because the object's
+    # string would have been freed, leaving garbage bytes for the error
+    # message.
+    set f [open $fName w]
+    chan event $f writable "chan event $f writable {}; error foo"
+    set x {}
+    vwait x
+    close $f
+    set x
+} -cleanup {
+    removeFile test1
+    interp bgerror {} $handler
+    rename myHandler {}
+} -result "foo\n    while executing\n\"error foo\""
+
+test basic-26.2 {Tcl_EvalObjEx, pure-list branch: preserve "objv"} -body {
+    #
+    # Follow the pure-list branch in a manner that
+    #   a - the pure-list internal rep is destroyed by shimmering
+    #   b - the command returns an error
+    # As the error code in Tcl_EvalObjv accesses the list elements, this will
+    # cause a segfault if [Bug 1119369] has not been fixed. 
+    # NOTE: a MEM_DEBUG build may be necessary to guarantee the segfault.
+    #
+
+    set SRC [list foo 1] ;# pure-list command 
+    proc foo str {
+	# Shimmer pure-list to cmdName, cleanup and error
+	proc $::SRC {} {}; $::SRC
+	error "BAD CALL"
+    }
+    catch {eval $SRC}
+} -result 1 -cleanup {
+    rename foo {}
+    rename $::SRC {}
+    unset ::SRC
+}
+
+test basic-26.3 {Tcl_EvalObjEx, pure-list branch: preserve "objv"} -body {
+    #
+    # Follow the pure-list branch in a manner that
+    #   a - the pure-list internal rep is destroyed by shimmering
+    #   b - the command accesses its command line
+    # This will cause a segfault if [Bug 1119369] has not been fixed. 
+    # NOTE: a MEM_DEBUG build may be necessary to guarantee the segfault.
+    #
+
+    set SRC [list foo 1] ;# pure-list command 
+    proc foo str {
+	# Shimmer pure-list to cmdName, cleanup and error
+	proc $::SRC {} {}; $::SRC
+	info level 0
+    }
+    catch {eval $SRC}
+} -result 0 -cleanup {
+    rename foo {}
+    rename $::SRC {}
+    unset ::SRC
+}
+
+test basic-27.1 {Tcl_ExprLong} {emptyTest} {
+} {}
+
+test basic-28.1 {Tcl_ExprDouble} {emptyTest} {
+} {}
+
+test basic-29.1 {Tcl_ExprBoolean} {emptyTest} {
+} {}
+
+test basic-30.1 {Tcl_ExprLongObj} {emptyTest} {
+} {}
+
+test basic-31.1 {Tcl_ExprDoubleObj} {emptyTest} {
+} {}
+
+test basic-32.1 {Tcl_ExprBooleanObj} {emptyTest} {
+} {}
+
+test basic-36.1 {Tcl_EvalObjv, lookup of "unknown" command} {
+    catch {namespace delete {*}[namespace children :: test_ns_*]}
+    catch {interp delete test_interp}
+    interp create test_interp
+    interp eval test_interp {
+        proc unknown {args} {
+            return "global unknown"
+        }
+        namespace eval test_ns_basic {
+            proc unknown {args} {
+                return "namespace unknown"
+            }
+        }
+    }
+    list [interp alias test_interp newAlias test_interp doesntExist] \
+         [catch {interp eval test_interp {newAlias}} msg] $msg \
+         [interp delete test_interp]
+} {newAlias 0 {global unknown} {}}
+
+test basic-37.1 {Tcl_ExprString: see expr.test} {emptyTest} {
+} {}
+
+test basic-38.1 {Tcl_ExprObj} {emptyTest} {
+} {}
+
+# Tests basic-39.* and basic-40.* refactored into trace.test
+
+test basic-41.1 {Tcl_AddErrorInfo} {emptyTest} {
+} {}
+
+test basic-42.1 {Tcl_AddObjErrorInfo} {emptyTest} {
+} {}
+
+test basic-43.1 {Tcl_VarEval} {emptyTest} {
+} {}
+
+test basic-44.1 {Tcl_GlobalEval} {emptyTest} {
+} {}
+
+test basic-45.1 {Tcl_SetRecursionLimit: see interp.test} {emptyTest} {
+} {}
+
+test basic-46.1 {Tcl_AllowExceptions: exception return not allowed} {stdio} {
+    catch {close $f}
+    set res [catch {
+	set f [open |[list [interpreter]] w+]
+	chan configure $f -buffering line
+	puts $f {chan configure stdout -buffering line}
+	puts $f continue
+	puts $f {puts $::errorInfo}
+	puts $f {puts DONE}
+	set newMsg {}
+	set msg {}
+	while {$newMsg != "DONE"} {
+	    set newMsg [gets $f]
+	    append msg "${newMsg}\n"
+	}
+	close $f
+    } error]
+    list $res $msg
+} {1 {invoked "continue" outside of a loop
+    while executing
+"continue"
+DONE
+}}
+
+test basic-46.2 {Tcl_AllowExceptions: exception return not allowed} -setup {
+    set fName [makeFile {
+	puts hello
+	break
+    } BREAKtest]
+} -constraints {
+    exec
+} -body {
+    exec [interpreter] $fName
+} -cleanup {
+    removeFile BREAKtest
+} -returnCodes error -match glob -result {hello
+invoked "break" outside of a loop
+    while executing
+"break"
+    (file "*BREAKtest" line 3)}    
+
+test basic-46.3 {Tcl_AllowExceptions: exception return not allowed} -setup {
+    set fName [makeFile {
+	interp alias {} patch {} info patchlevel
+	patch
+	break
+    } BREAKtest]
+} -constraints {
+    exec
+} -body {
+    exec [interpreter] $fName
+} -cleanup {
+    removeFile BREAKtest
+} -returnCodes error -match glob -result {invoked "break" outside of a loop
+    while executing
+"break"
+    (file "*BREAKtest" line 4)}    
+
+test basic-46.4 {Tcl_AllowExceptions: exception return not allowed} -setup {
+    set fName [makeFile {
+	foo [set a 1] [break]
+    } BREAKtest]
+} -constraints {
+    exec
+} -body {
+    exec [interpreter] $fName
+} -cleanup {
+    removeFile BREAKtest
+} -returnCodes error -match glob -result {invoked "break" outside of a loop
+    while executing*
+"foo \[set a 1] \[break]"
+    (file "*BREAKtest" line 2)}
+
+test basic-46.5 {Tcl_AllowExceptions: exception return not allowed} -setup {
+    set fName [makeFile {
+	return -code return
+    } BREAKtest]
+} -constraints {
+    exec
+} -body {
+    exec [interpreter] $fName
+} -cleanup {
+    removeFile BREAKtest
+} -returnCodes error -match glob -result {command returned bad code: 2
+    while executing
+"return -code return"
+    (file "*BREAKtest" line 2)}
+
+test basic-47.1 {Tcl_EvalEx: check for missing close-bracket} -constraints {
+    testevalex
+} -body {
+    testevalex {a[set b [format cd]}
+} -returnCodes error -result {missing close-bracket}
+
+# Some lists for expansion tests to work with
+set l1 [list a {b b} c d]
+set l2 [list e f {g g} h]
+proc l3 {} {
+    list i j k {l l}
+}
+
+# Do all tests once byte compiled and once with direct string evaluation
+for {set noComp 0} {$noComp <= 1} {incr noComp} {
+
+if $noComp {
+    interp alias {} run {} testevalex
+    set constraints testevalex
+} else {
+    interp alias {} run {} if 1
+    set constraints {}
+}
+
+test basic-47.2.$noComp {Tcl_EvalEx: error during word expansion} -body {
+    run {{*}\{}
+} -constraints $constraints -returnCodes error -result {unmatched open brace in list}
+
+test basic-47.3.$noComp {Tcl_EvalEx, error during substitution} -body {
+    run {{*}[error foo]}
+} -constraints $constraints -returnCodes error -result foo
+
+test basic-47.4.$noComp {Tcl_EvalEx: no expansion} $constraints {
+    run {list {*} {*}	{*}}
+} {* * *}
+
+test basic-47.5.$noComp {Tcl_EvalEx: expansion} $constraints {
+    run {list {*}{} {*}	{*}x {*}"y z"}
+} {* x y z}
+
+test basic-47.6.$noComp {Tcl_EvalEx: expansion to zero args} $constraints {
+    run {list {*}{}}
+} {}
+
+test basic-47.7.$noComp {Tcl_EvalEx: expansion to one arg} $constraints {
+    run {list {*}x}
+} x
+
+test basic-47.8.$noComp {Tcl_EvalEx: expansion to many args} $constraints {
+    run {list {*}"y z"}
+} {y z}
+
+test basic-47.9.$noComp {Tcl_EvalEx: expansion and subst order} $constraints {
+    set x 0
+    run {list [incr x] {*}[incr x] [incr x] \
+		{*}[list [incr x] [incr x]] [incr x]}
+} {1 2 3 4 5 6}
+
+test basic-47.10.$noComp {Tcl_EvalEx: expand and memory management} $constraints {
+    run {concat {*}{} a b c d e f g h i j k l m n o p q r}
+} {a b c d e f g h i j k l m n o p q r}
+
+test basic-47.11.$noComp {Tcl_EvalEx: expand and memory management} $constraints {
+    run {concat {*}1 a b c d e f g h i j k l m n o p q r}
+} {1 a b c d e f g h i j k l m n o p q r}
+
+test basic-47.12.$noComp {Tcl_EvalEx: expand and memory management} $constraints {
+    run {concat {*}{1 2} a b c d e f g h i j k l m n o p q r}
+} {1 2 a b c d e f g h i j k l m n o p q r}
+
+test basic-47.13.$noComp {Tcl_EvalEx: expand and memory management} $constraints {
+    run {concat {*}{} {*}{1 2} a b c d e f g h i j k l m n o p q}
+} {1 2 a b c d e f g h i j k l m n o p q}
+
+test basic-47.14.$noComp {Tcl_EvalEx: expand and memory management} $constraints {
+    run {concat {*}{} a b c d e f g h i j k l m n o p q r s}
+} {a b c d e f g h i j k l m n o p q r s}
+
+test basic-47.15.$noComp {Tcl_EvalEx: expand and memory management} $constraints {
+    run {concat {*}1 a b c d e f g h i j k l m n o p q r s}
+} {1 a b c d e f g h i j k l m n o p q r s}
+
+test basic-47.16.$noComp {Tcl_EvalEx: expand and memory management} $constraints {
+    run {concat {*}{1 2} a b c d e f g h i j k l m n o p q r s}
+} {1 2 a b c d e f g h i j k l m n o p q r s}
+
+test basic-47.17.$noComp {Tcl_EvalEx: expand and memory management} $constraints {
+    run {concat {*}{} {*}{1 2} a b c d e f g h i j k l m n o p q r}
+} {1 2 a b c d e f g h i j k l m n o p q r}
+
+test basic-48.1.$noComp {expansion: parsing} $constraints {
+	run { # A comment
+
+		# Another comment
+		list 1  2\
+			3   {*}$::l1
+            
+		# Comment again
+	}
+} {1 2 3 a {b b} c d}
+
+test basic-48.2.$noComp {no expansion} $constraints {
+        run {list $::l1 $::l2 [l3]}
+} {{a {b b} c d} {e f {g g} h} {i j k {l l}}}
+
+test basic-48.3.$noComp {expansion} $constraints {
+        run {list {*}$::l1 $::l2 {*}[l3]}
+} {a {b b} c d {e f {g g} h} i j k {l l}}
+
+test basic-48.4.$noComp {expansion: really long cmd} $constraints {
+        set cmd [list list]
+        for {set t 0} {$t < 500} {incr t} {
+            lappend cmd {{*}$::l1}
+        }
+        llength [run [join $cmd]]
+} 2000
+
+test basic-48.5.$noComp {expansion: error detection} -setup {
+	set l "a {a b}x y"
+} -constraints $constraints -body {
+	run {list $::l1 {*}$l}
+} -cleanup {
+	unset l
+} -returnCodes 1 -result {list element in braces followed by "x" instead of space}
+
+test basic-48.6.$noComp {expansion: odd usage} $constraints {
+        run {list {*}$::l1$::l2}
+} {a {b b} c de f {g g} h}
+
+test basic-48.7.$noComp {expansion: odd usage} -constraints $constraints -body {
+        run {list {*}[l3]$::l1}
+} -returnCodes 1 -result {list element in braces followed by "a" instead of space}
+
+test basic-48.8.$noComp {expansion: odd usage} $constraints {
+        run {list {*}hej$::l1}
+} {heja {b b} c d}
+
+test basic-48.9.$noComp {expansion: Not all {*} should trigger} $constraints {
+	run {list {*}$::l1 \{*\}$::l2 "{*}$::l1" {{*} i j k}}
+} {a {b b} c d {{*}e f {g g} h} {{*}a {b b} c d} {{*} i j k}}
+
+test basic-48.10.$noComp {expansion: expansion of command word} -setup {
+	set cmd [list string range jultomte]
+} -constraints $constraints -body {
+	run {{*}$cmd 2 6}
+} -cleanup {
+	unset cmd
+} -result ltomt
+
+test basic-48.11.$noComp {expansion: expansion into nothing} -setup {
+        set cmd {}
+        set bar {}
+} -constraints $constraints -body {
+        run {{*}$cmd {*}$bar}
+} -cleanup {
+	unset cmd bar
+} -result {}
+
+test basic-48.12.$noComp {expansion: odd usage} $constraints {
+	run {list {*}$::l1 {*}"hej hopp" {*}$::l2}
+} {a {b b} c d hej hopp e f {g g} h}
+
+test basic-48.13.$noComp {expansion: odd usage} $constraints {
+	run {list {*}$::l1 {*}{hej hopp} {*}$::l2}
+} {a {b b} c d hej hopp e f {g g} h}
+
+test basic-48.14.$noComp {expansion: hash command} -setup {
+        catch {rename \# ""}
+        set cmd "#"
+    } -constraints $constraints -body { 
+           run { {*}$cmd apa bepa }
+    } -cleanup {
+	unset cmd
+} -returnCodes 1 -result {invalid command name "#"}
+
+test basic-48.15.$noComp {expansion: complex words} -setup {
+            set a(x) [list a {b c} d e]
+            set b x
+            set c [list {f\ g h\ i j k} x y]
+            set d {0\ 1 2 3}
+    } -constraints $constraints -body {
+            run { lappend d {*}$a($b) {*}[lindex $c 0] }
+    } -cleanup {
+	unset a b c d
+} -result {{0 1} 2 3 a {b c} d e {f g} {h i} j k}
+
+testConstraint memory [llength [info commands memory]]
+test basic-48.16.$noComp {expansion: testing for leaks} -setup {
+        proc getbytes {} {
+            set lines [split [memory info] "\n"]
+            lindex [lindex $lines 3] 3
+        }
+        # This test is made to stress the allocation, reallocation and
+        # object reference management in Tcl_EvalEx.
+        proc stress {} {
+            set a x
+            # Create free objects that should disappear
+            set l [list 1$a 2$a 3$a 4$a 5$a 6$a 7$a]
+            # A short number of words and a short result (8)
+            set l [run {list {*}$l $a$a}]
+            # A short number of words and a longer result (27)
+            set l [run {list {*}$l $a$a {*}$l $a$a {*}$l $a$a}]
+            # A short number of words and a longer result, with an error
+            # This is to stress the cleanup in the error case
+            if {![catch {run {_moo_ {*}$l $a$a {*}$l $a$a {*}$l}}]} {
+                error "An error was expected in the previous statement"
+            }
+            # Many words
+            set l [run {list {*}$l $a$a {*}$l $a$a \
+                                 {*}$l $a$a {*}$l $a$a \
+                                 {*}$l $a$a {*}$l $a$a \
+                                 {*}$l $a$a {*}$l $a$a \
+                                 {*}$l $a$a {*}$l $a$a \
+                                 {*}$l $a$a {*}$l $a$a \
+                                 {*}$l $a$a {*}$l $a$a \
+                                 {*}$l $a$a {*}$l $a$a \
+                                 {*}$l $a$a {*}$l $a$a \
+                                 {*}$l $a$a}]
+
+            if {[llength $l] != 19*28} {
+                error "Bad Length: [llength $l] should be [expr {19*28}]"
+            }
+        }
+    } -constraints [linsert $constraints 0 memory] -body {
+        set end [getbytes]
+        for {set i 0} {$i < 5} {incr i} {
+            stress
+            set tmp $end
+            set end [getbytes]
+        }    
+        set leak [expr {$end - $tmp}]
+    } -cleanup {
+	unset end i tmp
+	rename getbytes {}
+	rename stress {}
+} -result 0
+
+test basic-48.17.$noComp {expansion: object safety} -setup {
+        set old_precision $::tcl_precision
+        set ::tcl_precision 4
+    } -constraints $constraints -body { 
+            set third [expr {1.0/3.0}]
+            set l [list $third $third]
+            set x [run {list $third {*}$l $third}]
+	    set res [list]
+            foreach t $x {
+                lappend res [expr {$t * 3.0}]
+            }
+            set res
+    } -cleanup {
+        set ::tcl_precision $old_precision
+        unset old_precision res t l x third
+} -result {1.0 1.0 1.0 1.0}
+
+test basic-48.18.$noComp {expansion: list semantics} -constraints $constraints -body {
+        set badcmd {
+            list a b
+            set apa 10
+        }
+        set apa 0
+        list [llength [run { {*}$badcmd }]] $apa
+    } -cleanup {
+	unset apa badcmd
+} -result {5 0}
+
+test basic-48.19.$noComp {expansion: error checking order} -body {
+        set badlist "a {}x y"
+        set a 0
+        set b 0
+        catch {run {list [incr a] {*}$badlist [incr b]}}
+        list $a $b
+    } -constraints $constraints -cleanup {
+	unset badlist a b
+} -result {1 0}
+
+test basic-48.20.$noComp {expansion: odd case with word boundaries} $constraints {
+    run {list {*}$::l1 {*}"hej hopp" {*}$::l2}
+} {a {b b} c d hej hopp e f {g g} h}
+
+test basic-48.21.$noComp {expansion: odd case with word boundaries} $constraints {
+    run {list {*}$::l1 {*}{hej hopp} {*}$::l2}
+} {a {b b} c d hej hopp e f {g g} h}
+
+test basic-48.22.$noComp {expansion: odd case with word boundaries} -body {
+    run {list {*}$::l1 {*}"hej hopp {*}$::l2}
+} -constraints $constraints -returnCodes error -result {missing "}
+
+test basic-48.23.$noComp {expansion: handle return codes} -constraints $constraints -body {
+        set res {}
+        for {set t 0} {$t < 10} {incr t} {
+            run { {*}break }
+        }
+        lappend res $t
+
+        for {set t 0} {$t < 10} {incr t} {
+            run { {*}continue }
+            set t 20
+        }
+        lappend res $t
+
+        lappend res [catch { run { {*}{error Hejsan} } } err]
+        lappend res $err
+    } -cleanup {
+	unset res t
+} -result {0 10 1 Hejsan}
+
+} ;# End of noComp loop
+
+test basic-49.1 {Tcl_EvalEx: verify TCL_EVAL_GLOBAL operation} testevalex {
+    set ::x global
+    namespace eval ns {
+	variable x namespace
+	testevalex {set x changed} global
+	set ::result [list $::x $x]
+    }
+    namespace delete ns
+    set ::result
+} {changed namespace}
+test basic-49.2 {Tcl_EvalEx: verify TCL_EVAL_GLOBAL operation} testevalex {
+    set ::x global
+    namespace eval ns {
+	variable x namespace
+	testevalex {set ::context $x} global
+    }
+    namespace delete ns
+    set ::context
+} {global}
+
+# Clean up after expand tests
+unset noComp l1 l2 constraints
+rename l3 {}
+rename run {}
+
+ #cleanup
+catch {namespace delete {*}[namespace children :: test_ns_*]}
+catch {namespace delete george}
+catch {interp delete test_interp}
+catch {rename p ""}
+catch {rename q ""}
+catch {rename cmd ""}
+catch {rename value:at: ""}
+unset -nocomplain x
+cleanupTests
+return
diff --git a/tests/binary.test b/tests/binary.test
new file mode 100644
index 0000000..40b1315
--- /dev/null
+++ b/tests/binary.test
@@ -0,0 +1,2849 @@
+# This file tests the tclBinary.c file and the "binary" Tcl command.
+#
+# This file contains a collection of tests for one or more of the Tcl built-in
+# commands. Sourcing this file into Tcl runs the tests and generates output
+# for errors. No output means no errors were found.
+#
+# Copyright (c) 1997 by Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution of
+# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+    package require tcltest
+    namespace import -force ::tcltest::*
+}
+testConstraint bigEndian [expr {$tcl_platform(byteOrder) eq "bigEndian"}]
+testConstraint littleEndian [expr {$tcl_platform(byteOrder) eq "littleEndian"}]
+
+# Big test for correct ordering of data in [expr]
+proc testIEEE {} {
+    variable ieeeValues
+    binary scan [binary format dd -1.0 1.0] c* c
+    switch -exact -- $c {
+	{0 0 0 0 0 0 -16 -65 0 0 0 0 0 0 -16 63} {
+	    # little endian
+	    binary scan \x00\x00\x00\x00\x00\x00\xf0\xff d \
+		ieeeValues(-Infinity)
+	    binary scan \x00\x00\x00\x00\x00\x00\xf0\xbf d \
+		ieeeValues(-Normal)
+	    binary scan \x00\x00\x00\x00\x00\x00\x08\x80 d \
+		ieeeValues(-Subnormal)
+	    binary scan \x00\x00\x00\x00\x00\x00\x00\x80 d \
+		ieeeValues(-0)
+	    binary scan \x00\x00\x00\x00\x00\x00\x00\x00 d \
+		ieeeValues(+0)
+	    binary scan \x00\x00\x00\x00\x00\x00\x08\x00 d \
+		ieeeValues(+Subnormal)
+	    binary scan \x00\x00\x00\x00\x00\x00\xf0\x3f d \
+		ieeeValues(+Normal)
+	    binary scan \x00\x00\x00\x00\x00\x00\xf0\x7f d \
+		ieeeValues(+Infinity)
+	    binary scan \x00\x00\x00\x00\x00\x00\xf8\x7f d \
+		ieeeValues(NaN)
+	    set ieeeValues(littleEndian) 1
+	    return 1
+	}
+	{-65 -16 0 0 0 0 0 0 63 -16 0 0 0 0 0 0} {
+	    binary scan \xff\xf0\x00\x00\x00\x00\x00\x00 d \
+		ieeeValues(-Infinity)
+	    binary scan \xbf\xf0\x00\x00\x00\x00\x00\x00 d \
+		ieeeValues(-Normal)
+	    binary scan \x80\x08\x00\x00\x00\x00\x00\x00 d \
+		ieeeValues(-Subnormal)
+	    binary scan \x80\x00\x00\x00\x00\x00\x00\x00 d \
+		ieeeValues(-0)
+	    binary scan \x00\x00\x00\x00\x00\x00\x00\x00 d \
+		ieeeValues(+0)
+	    binary scan \x00\x08\x00\x00\x00\x00\x00\x00 d \
+		ieeeValues(+Subnormal)
+	    binary scan \x3f\xf0\x00\x00\x00\x00\x00\x00 d \
+		ieeeValues(+Normal)
+	    binary scan \x7f\xf0\x00\x00\x00\x00\x00\x00 d \
+		ieeeValues(+Infinity)
+	    binary scan \x7f\xf8\x00\x00\x00\x00\x00\x00 d \
+		ieeeValues(NaN)
+	    set ieeeValues(littleEndian) 0
+	    return 1
+	}
+	default {
+	    return 0
+	}
+    }
+}
+
+testConstraint ieeeFloatingPoint [testIEEE]
+
+# ----------------------------------------------------------------------
+
+test binary-0.1 {DupByteArrayInternalRep} {
+    set hdr [binary format cc 0 0316]
+    set buf hellomatt
+    set data $hdr
+    append data $buf
+    string length $data
+} 11
+
+test binary-1.1 {Tcl_BinaryObjCmd: bad args} -body {
+    binary
+} -returnCodes error -match glob -result {wrong # args: *}
+test binary-1.2 {Tcl_BinaryObjCmd: bad args} -returnCodes error -body {
+    binary foo
+} -match glob -result {unknown or ambiguous subcommand "foo": *}
+test binary-1.3 {Tcl_BinaryObjCmd: format error} -returnCodes error -body {
+    binary f
+} -result {wrong # args: should be "binary format formatString ?arg ...?"}
+test binary-1.4 {Tcl_BinaryObjCmd: format} -body {
+    binary format ""
+} -result {}
+
+test binary-2.1 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+    binary format a
+} -result {not enough arguments for all format specifiers}
+test binary-2.2 {Tcl_BinaryObjCmd: format} {
+    binary format a0 foo
+} {}
+test binary-2.3 {Tcl_BinaryObjCmd: format} {
+    binary format a f
+} {f}
+test binary-2.4 {Tcl_BinaryObjCmd: format} {
+    binary format a foo
+} {f}
+test binary-2.5 {Tcl_BinaryObjCmd: format} {
+    binary format a3 foo
+} {foo}
+test binary-2.6 {Tcl_BinaryObjCmd: format} {
+    binary format a5 foo
+} foo\x00\x00
+test binary-2.7 {Tcl_BinaryObjCmd: format} {
+    binary format a*a3 foobarbaz blat
+} foobarbazbla
+test binary-2.8 {Tcl_BinaryObjCmd: format} {
+    binary format a*X3a2 foobar x
+} foox\x00r
+
+test binary-3.1 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+    binary format A
+} -result {not enough arguments for all format specifiers}
+test binary-3.2 {Tcl_BinaryObjCmd: format} {
+    binary format A0 f
+} {}
+test binary-3.3 {Tcl_BinaryObjCmd: format} {
+    binary format A f
+} {f}
+test binary-3.4 {Tcl_BinaryObjCmd: format} {
+    binary format A foo
+} {f}
+test binary-3.5 {Tcl_BinaryObjCmd: format} {
+    binary format A3 foo
+} {foo}
+test binary-3.6 {Tcl_BinaryObjCmd: format} {
+    binary format A5 foo
+} {foo  }
+test binary-3.7 {Tcl_BinaryObjCmd: format} {
+    binary format A*A3 foobarbaz blat
+} foobarbazbla
+test binary-3.8 {Tcl_BinaryObjCmd: format} {
+    binary format A*X3A2 foobar x
+} {foox r}
+
+test binary-4.1 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+    binary format B
+} -result {not enough arguments for all format specifiers}
+test binary-4.2 {Tcl_BinaryObjCmd: format} {
+    binary format B0 1
+} {}
+test binary-4.3 {Tcl_BinaryObjCmd: format} {
+    binary format B 1
+} \x80
+test binary-4.4 {Tcl_BinaryObjCmd: format} {
+    binary format B* 010011
+} \x4c
+test binary-4.5 {Tcl_BinaryObjCmd: format} {
+    binary format B8 01001101
+} \x4d
+test binary-4.6 {Tcl_BinaryObjCmd: format} {
+    binary format A2X2B9 oo 01001101
+} \x4d\x00
+test binary-4.7 {Tcl_BinaryObjCmd: format} {
+    binary format B9 010011011010
+} \x4d\x80
+test binary-4.8 {Tcl_BinaryObjCmd: format} {
+    binary format B2B3 10 010
+} \x80\x40
+test binary-4.9 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+    binary format B1B5 1 foo
+} -result {expected binary string but got "foo" instead}
+
+test binary-5.1 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+    binary format b
+} -result {not enough arguments for all format specifiers}
+test binary-5.2 {Tcl_BinaryObjCmd: format} {
+    binary format b0 1
+} {}
+test binary-5.3 {Tcl_BinaryObjCmd: format} {
+    binary format b 1
+} \x01
+test binary-5.4 {Tcl_BinaryObjCmd: format} {
+    binary format b* 010011
+} 2
+test binary-5.5 {Tcl_BinaryObjCmd: format} {
+    binary format b8 01001101
+} \xb2
+test binary-5.6 {Tcl_BinaryObjCmd: format} {
+    binary format A2X2b9 oo 01001101
+} \xb2\x00
+test binary-5.7 {Tcl_BinaryObjCmd: format} {
+    binary format b9 010011011010
+} \xb2\x01
+test binary-5.8 {Tcl_BinaryObjCmd: format} {
+    binary format b17 1
+} \x01\00\00
+test binary-5.9 {Tcl_BinaryObjCmd: format} {
+    binary format b2b3 10 010
+} \x01\x02
+test binary-5.10 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+    binary format b1b5 1 foo
+} -result {expected binary string but got "foo" instead}
+
+test binary-6.1 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+    binary format h
+} -result {not enough arguments for all format specifiers}
+test binary-6.2 {Tcl_BinaryObjCmd: format} {
+    binary format h0 1
+} {}
+test binary-6.3 {Tcl_BinaryObjCmd: format} {
+    binary format h 1
+} \x01
+test binary-6.4 {Tcl_BinaryObjCmd: format} {
+    binary format h c
+} \x0c
+test binary-6.5 {Tcl_BinaryObjCmd: format} {
+    binary format h* baadf00d
+} \xab\xda\x0f\xd0
+test binary-6.6 {Tcl_BinaryObjCmd: format} {
+    binary format h4 c410
+} \x4c\x01
+test binary-6.7 {Tcl_BinaryObjCmd: format} {
+    binary format h6 c4102
+} \x4c\x01\x02
+test binary-6.8 {Tcl_BinaryObjCmd: format} {
+    binary format h5 c41020304
+} \x4c\x01\x02
+test binary-6.9 {Tcl_BinaryObjCmd: format} {
+    binary format a3X3h5 foo 2
+} \x02\x00\x00
+test binary-6.10 {Tcl_BinaryObjCmd: format} {
+    binary format h2h3 23 456
+} \x32\x54\x06
+test binary-6.11 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+    binary format h2 foo
+} -result {expected hexadecimal string but got "foo" instead}
+
+test binary-7.1 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+    binary format H
+} -result {not enough arguments for all format specifiers}
+test binary-7.2 {Tcl_BinaryObjCmd: format} {
+    binary format H0 1
+} {}
+test binary-7.3 {Tcl_BinaryObjCmd: format} {
+    binary format H 1
+} \x10
+test binary-7.4 {Tcl_BinaryObjCmd: format} {
+    binary format H c
+} \xc0
+test binary-7.5 {Tcl_BinaryObjCmd: format} {
+    binary format H* baadf00d
+} \xba\xad\xf0\x0d
+test binary-7.6 {Tcl_BinaryObjCmd: format} {
+    binary format H4 c410
+} \xc4\x10
+test binary-7.7 {Tcl_BinaryObjCmd: format} {
+    binary format H6 c4102
+} \xc4\x10\x20
+test binary-7.8 {Tcl_BinaryObjCmd: format} {
+    binary format H5 c41023304
+} \xc4\x10\x20
+test binary-7.9 {Tcl_BinaryObjCmd: format} {
+    binary format a3X3H5 foo 2
+} \x20\x00\x00
+test binary-7.10 {Tcl_BinaryObjCmd: format} {
+    binary format H2H3 23 456
+} \x23\x45\x60
+test binary-7.11 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+    binary format H2 foo
+} -result {expected hexadecimal string but got "foo" instead}
+
+test binary-8.1 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+    binary format c
+} -result {not enough arguments for all format specifiers}
+test binary-8.2 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+    binary format c blat
+} -result {expected integer but got "blat"}
+test binary-8.3 {Tcl_BinaryObjCmd: format} {
+    binary format c0 0x50
+} {}
+test binary-8.4 {Tcl_BinaryObjCmd: format} {
+    binary format c 0x50
+} P
+test binary-8.5 {Tcl_BinaryObjCmd: format} {
+    binary format c 0x5052
+} R
+test binary-8.6 {Tcl_BinaryObjCmd: format} {
+    binary format c2 {0x50 0x52}
+} PR
+test binary-8.7 {Tcl_BinaryObjCmd: format} {
+    binary format c2 {0x50 0x52 0x53}
+} PR
+test binary-8.8 {Tcl_BinaryObjCmd: format} {
+    binary format c* {0x50 0x52}
+} PR
+test binary-8.9 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+    binary format c2 {0x50}
+} -result {number of elements in list does not match count}
+test binary-8.10 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+    set a {0x50 0x51}
+    binary format c $a
+} -result "expected integer but got \"0x50 0x51\""
+test binary-8.11 {Tcl_BinaryObjCmd: format} {
+    set a {0x50 0x51}
+    binary format c1 $a
+} P
+
+test binary-9.1 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+    binary format s
+} -result {not enough arguments for all format specifiers}
+test binary-9.2 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+    binary format s blat
+} -result {expected integer but got "blat"}
+test binary-9.3 {Tcl_BinaryObjCmd: format} {
+    binary format s0 0x50
+} {}
+test binary-9.4 {Tcl_BinaryObjCmd: format} {
+    binary format s 0x50
+} P\x00
+test binary-9.5 {Tcl_BinaryObjCmd: format} {
+    binary format s 0x5052
+} RP
+test binary-9.6 {Tcl_BinaryObjCmd: format} {
+    binary format s 0x505251 0x53
+} QR
+test binary-9.7 {Tcl_BinaryObjCmd: format} {
+    binary format s2 {0x50 0x52}
+} P\x00R\x00
+test binary-9.8 {Tcl_BinaryObjCmd: format} {
+    binary format s* {0x5051 0x52}
+} QPR\x00
+test binary-9.9 {Tcl_BinaryObjCmd: format} {
+    binary format s2 {0x50 0x52 0x53} 0x54
+} P\x00R\x00
+test binary-9.10 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+    binary format s2 {0x50}
+} -result {number of elements in list does not match count}
+test binary-9.11 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+    set a {0x50 0x51}
+    binary format s $a
+} -result "expected integer but got \"0x50 0x51\""
+test binary-9.12 {Tcl_BinaryObjCmd: format} {
+    set a {0x50 0x51}
+    binary format s1 $a
+} P\x00
+
+test binary-10.1 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+    binary format S
+} -result {not enough arguments for all format specifiers}
+test binary-10.2 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+    binary format S blat
+} -result {expected integer but got "blat"}
+test binary-10.3 {Tcl_BinaryObjCmd: format} {
+    binary format S0 0x50
+} {}
+test binary-10.4 {Tcl_BinaryObjCmd: format} {
+    binary format S 0x50
+} \x00P
+test binary-10.5 {Tcl_BinaryObjCmd: format} {
+    binary format S 0x5052
+} PR
+test binary-10.6 {Tcl_BinaryObjCmd: format} {
+    binary format S 0x505251 0x53
+} RQ
+test binary-10.7 {Tcl_BinaryObjCmd: format} {
+    binary format S2 {0x50 0x52}
+} \x00P\x00R
+test binary-10.8 {Tcl_BinaryObjCmd: format} {
+    binary format S* {0x5051 0x52}
+} PQ\x00R
+test binary-10.9 {Tcl_BinaryObjCmd: format} {
+    binary format S2 {0x50 0x52 0x53} 0x54
+} \x00P\x00R
+test binary-10.10 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+    binary format S2 {0x50}
+} -result {number of elements in list does not match count}
+test binary-10.11 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+    set a {0x50 0x51}
+    binary format S $a
+} -result "expected integer but got \"0x50 0x51\""
+test binary-10.12 {Tcl_BinaryObjCmd: format} {
+    set a {0x50 0x51}
+    binary format S1 $a
+} \x00P
+
+test binary-11.1 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+    binary format i
+} -result {not enough arguments for all format specifiers}
+test binary-11.2 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+    binary format i blat
+} -result {expected integer but got "blat"}
+test binary-11.3 {Tcl_BinaryObjCmd: format} {
+    binary format i0 0x50
+} {}
+test binary-11.4 {Tcl_BinaryObjCmd: format} {
+    binary format i 0x50
+} P\x00\x00\x00
+test binary-11.5 {Tcl_BinaryObjCmd: format} {
+    binary format i 0x5052
+} RP\x00\x00
+test binary-11.6 {Tcl_BinaryObjCmd: format} {
+    binary format i 0x505251 0x53
+} QRP\x00
+test binary-11.7 {Tcl_BinaryObjCmd: format} {
+    binary format i1 {0x505251 0x53}
+} QRP\x00
+test binary-11.8 {Tcl_BinaryObjCmd: format} {
+    binary format i 0x53525150
+} PQRS
+test binary-11.9 {Tcl_BinaryObjCmd: format} {
+    binary format i2 {0x50 0x52}
+} P\x00\x00\x00R\x00\x00\x00
+test binary-11.10 {Tcl_BinaryObjCmd: format} {
+    binary format i* {0x50515253 0x52}
+} SRQPR\x00\x00\x00
+test binary-11.11 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+    binary format i2 {0x50}
+} -result {number of elements in list does not match count}
+test binary-11.12 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+    set a {0x50 0x51}
+    binary format i $a
+} -result "expected integer but got \"0x50 0x51\""
+test binary-11.13 {Tcl_BinaryObjCmd: format} {
+    set a {0x50 0x51}
+    binary format i1 $a
+} P\x00\x00\x00
+
+test binary-12.1 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+    binary format I
+} -result {not enough arguments for all format specifiers}
+test binary-12.2 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+    binary format I blat
+} -result {expected integer but got "blat"}
+test binary-12.3 {Tcl_BinaryObjCmd: format} {
+    binary format I0 0x50
+} {}
+test binary-12.4 {Tcl_BinaryObjCmd: format} {
+    binary format I 0x50
+} \x00\x00\x00P
+test binary-12.5 {Tcl_BinaryObjCmd: format} {
+    binary format I 0x5052
+} \x00\x00PR
+test binary-12.6 {Tcl_BinaryObjCmd: format} {
+    binary format I 0x505251 0x53
+} \x00PRQ
+test binary-12.7 {Tcl_BinaryObjCmd: format} {
+    binary format I1 {0x505251 0x53}
+} \x00PRQ
+test binary-12.8 {Tcl_BinaryObjCmd: format} {
+    binary format I 0x53525150
+} SRQP
+test binary-12.9 {Tcl_BinaryObjCmd: format} {
+    binary format I2 {0x50 0x52}
+} \x00\x00\x00P\x00\x00\x00R
+test binary-12.10 {Tcl_BinaryObjCmd: format} {
+    binary format I* {0x50515253 0x52}
+} PQRS\x00\x00\x00R
+test binary-12.11 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+    binary format i2 {0x50}
+} -result {number of elements in list does not match count}
+test binary-12.12 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+    set a {0x50 0x51}
+    binary format I $a
+} -result "expected integer but got \"0x50 0x51\""
+test binary-12.13 {Tcl_BinaryObjCmd: format} {
+    set a {0x50 0x51}
+    binary format I1 $a
+} \x00\x00\x00P
+
+test binary-13.1 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+    binary format f
+} -result {not enough arguments for all format specifiers}
+test binary-13.2 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+    binary format f blat
+} -result {expected floating-point number but got "blat"}
+test binary-13.3 {Tcl_BinaryObjCmd: format} {
+    binary format f0 1.6
+} {}
+test binary-13.4 {Tcl_BinaryObjCmd: format} bigEndian {
+    binary format f 1.6
+} \x3f\xcc\xcc\xcd
+test binary-13.5 {Tcl_BinaryObjCmd: format} littleEndian {
+    binary format f 1.6
+} \xcd\xcc\xcc\x3f
+test binary-13.6 {Tcl_BinaryObjCmd: format} bigEndian {
+    binary format f* {1.6 3.4}
+} \x3f\xcc\xcc\xcd\x40\x59\x99\x9a
+test binary-13.7 {Tcl_BinaryObjCmd: format} littleEndian {
+    binary format f* {1.6 3.4}
+} \xcd\xcc\xcc\x3f\x9a\x99\x59\x40
+test binary-13.8 {Tcl_BinaryObjCmd: format} bigEndian {
+    binary format f2 {1.6 3.4}
+} \x3f\xcc\xcc\xcd\x40\x59\x99\x9a
+test binary-13.9 {Tcl_BinaryObjCmd: format} littleEndian {
+    binary format f2 {1.6 3.4}
+} \xcd\xcc\xcc\x3f\x9a\x99\x59\x40
+test binary-13.10 {Tcl_BinaryObjCmd: format} bigEndian {
+    binary format f2 {1.6 3.4 5.6}
+} \x3f\xcc\xcc\xcd\x40\x59\x99\x9a
+test binary-13.11 {Tcl_BinaryObjCmd: format} littleEndian {
+    binary format f2 {1.6 3.4 5.6}
+} \xcd\xcc\xcc\x3f\x9a\x99\x59\x40
+test binary-13.12 {Tcl_BinaryObjCmd: float overflow} bigEndian {
+    binary format f -3.402825e+38
+} \xff\x7f\xff\xff
+test binary-13.13 {Tcl_BinaryObjCmd: float overflow} littleEndian {
+    binary format f -3.402825e+38
+} \xff\xff\x7f\xff
+test binary-13.14 {Tcl_BinaryObjCmd: float underflow} bigEndian {
+    binary format f -3.402825e-100
+} \x80\x00\x00\x00
+test binary-13.15 {Tcl_BinaryObjCmd: float underflow} littleEndian {
+    binary format f -3.402825e-100
+} \x00\x00\x00\x80
+test binary-13.16 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+    binary format f2 {1.6}
+} -result {number of elements in list does not match count}
+test binary-13.17 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+    set a {1.6 3.4}
+    binary format f $a
+} -result "expected floating-point number but got \"1.6 3.4\""
+test binary-13.18 {Tcl_BinaryObjCmd: format} bigEndian {
+    set a {1.6 3.4}
+    binary format f1 $a
+} \x3f\xcc\xcc\xcd
+test binary-13.19 {Tcl_BinaryObjCmd: format} littleEndian {
+    set a {1.6 3.4}
+    binary format f1 $a
+} \xcd\xcc\xcc\x3f
+
+test binary-14.1 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+    binary format d
+} -result {not enough arguments for all format specifiers}
+test binary-14.2 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+    binary format d blat
+} -result {expected floating-point number but got "blat"}
+test binary-14.3 {Tcl_BinaryObjCmd: format} {
+    binary format d0 1.6
+} {}
+test binary-14.4 {Tcl_BinaryObjCmd: format} bigEndian {
+    binary format d 1.6
+} \x3f\xf9\x99\x99\x99\x99\x99\x9a
+test binary-14.5 {Tcl_BinaryObjCmd: format} littleEndian {
+    binary format d 1.6
+} \x9a\x99\x99\x99\x99\x99\xf9\x3f
+test binary-14.6 {Tcl_BinaryObjCmd: format} bigEndian {
+    binary format d* {1.6 3.4}
+} \x3f\xf9\x99\x99\x99\x99\x99\x9a\x40\x0b\x33\x33\x33\x33\x33\x33
+test binary-14.7 {Tcl_BinaryObjCmd: format} littleEndian {
+    binary format d* {1.6 3.4}
+} \x9a\x99\x99\x99\x99\x99\xf9\x3f\x33\x33\x33\x33\x33\x33\x0b\x40
+test binary-14.8 {Tcl_BinaryObjCmd: format} bigEndian {
+    binary format d2 {1.6 3.4}
+} \x3f\xf9\x99\x99\x99\x99\x99\x9a\x40\x0b\x33\x33\x33\x33\x33\x33
+test binary-14.9 {Tcl_BinaryObjCmd: format} littleEndian {
+    binary format d2 {1.6 3.4}
+} \x9a\x99\x99\x99\x99\x99\xf9\x3f\x33\x33\x33\x33\x33\x33\x0b\x40
+test binary-14.10 {Tcl_BinaryObjCmd: format} bigEndian {
+    binary format d2 {1.6 3.4 5.6}
+} \x3f\xf9\x99\x99\x99\x99\x99\x9a\x40\x0b\x33\x33\x33\x33\x33\x33
+test binary-14.11 {Tcl_BinaryObjCmd: format} littleEndian {
+    binary format d2 {1.6 3.4 5.6}
+} \x9a\x99\x99\x99\x99\x99\xf9\x3f\x33\x33\x33\x33\x33\x33\x0b\x40
+test binary-14.14 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+    binary format d2 {1.6}
+} -result {number of elements in list does not match count}
+test binary-14.15 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+    set a {1.6 3.4}
+    binary format d $a
+} -result "expected floating-point number but got \"1.6 3.4\""
+test binary-14.16 {Tcl_BinaryObjCmd: format} bigEndian {
+    set a {1.6 3.4}
+    binary format d1 $a
+} \x3f\xf9\x99\x99\x99\x99\x99\x9a
+test binary-14.17 {Tcl_BinaryObjCmd: format} littleEndian {
+    set a {1.6 3.4}
+    binary format d1 $a
+} \x9a\x99\x99\x99\x99\x99\xf9\x3f
+test binary-14.18 {FormatNumber: Bug 1116542} {
+    binary scan [binary format d 1.25] d w
+    set w
+} 1.25
+
+test binary-15.1 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+    binary format ax*a "y" "z"
+} -result {cannot use "*" in format string with "x"}
+test binary-15.2 {Tcl_BinaryObjCmd: format} {
+    binary format axa "y" "z"
+} y\x00z
+test binary-15.3 {Tcl_BinaryObjCmd: format} {
+    binary format ax3a "y" "z"
+} y\x00\x00\x00z
+test binary-15.4 {Tcl_BinaryObjCmd: format} {
+    binary format a*X3x3a* "foo" "z"
+} \x00\x00\x00z
+test binary-15.5 {Tcl_BinaryObjCmd: format - bug #1923966} {
+    binary format x0s 1
+} \x01\x00
+test binary-15.6 {Tcl_BinaryObjCmd: format - bug #1923966} {
+    binary format x0ss 1 1
+} \x01\x00\x01\x00
+test binary-15.7 {Tcl_BinaryObjCmd: format - bug #1923966} {
+    binary format x1s 1
+} \x00\x01\x00
+test binary-15.8 {Tcl_BinaryObjCmd: format - bug #1923966} {
+    binary format x1ss 1 1
+} \x00\x01\x00\x01\x00
+
+test binary-16.1 {Tcl_BinaryObjCmd: format} {
+    binary format a*X*a "foo" "z"
+} zoo
+test binary-16.2 {Tcl_BinaryObjCmd: format} {
+    binary format aX3a "y" "z"
+} z
+test binary-16.3 {Tcl_BinaryObjCmd: format} {
+    binary format a*Xa* "foo" "zy"
+} fozy
+test binary-16.4 {Tcl_BinaryObjCmd: format} {
+    binary format a*X3a "foobar" "z"
+} foozar
+test binary-16.5 {Tcl_BinaryObjCmd: format} {
+    binary format a*X3aX2a "foobar" "z" "b"
+} fobzar
+
+test binary-17.1 {Tcl_BinaryObjCmd: format} {
+    binary format @1
+} \x00
+test binary-17.2 {Tcl_BinaryObjCmd: format} {
+    binary format @5a2 "ab"
+} \x00\x00\x00\x00\x00\x61\x62
+test binary-17.3 {Tcl_BinaryObjCmd: format} {
+    binary format {a*  @0  a2 @* a*} "foobar" "ab" "blat"
+} abobarblat
+
+test binary-18.1 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+    binary format u0a3 abc abd
+} -result {bad field specifier "u"}
+
+test binary-19.1 {Tcl_BinaryObjCmd: errors} -returnCodes error -body {
+    binary s
+} -result {wrong # args: should be "binary scan value formatString ?varName ...?"}
+test binary-19.2 {Tcl_BinaryObjCmd: errors} -returnCodes error -body {
+    binary scan foo
+} -result {wrong # args: should be "binary scan value formatString ?varName ...?"}
+test binary-19.3 {Tcl_BinaryObjCmd: scan} {
+    binary scan {} {}
+} 0
+
+test binary-20.1 {Tcl_BinaryObjCmd: scan} -returnCodes error -body {
+    binary scan abc a
+} -result {not enough arguments for all format specifiers}
+test binary-20.2 {Tcl_BinaryObjCmd: scan} -setup {
+    unset -nocomplain arg1
+} -returnCodes error -body {
+    set arg1 1
+    binary scan abc a arg1(a)
+} -result {can't set "arg1(a)": variable isn't array}
+test binary-20.3 {Tcl_BinaryObjCmd: scan} -setup {
+    unset -nocomplain arg1
+} -body {
+    set arg1 abc
+    list [binary scan abc a0 arg1] $arg1
+} -result {1 {}}
+test binary-20.4 {Tcl_BinaryObjCmd: scan} -setup {
+    unset -nocomplain arg1
+} -body {
+    list [binary scan abc a* arg1] $arg1
+} -result {1 abc}
+test binary-20.5 {Tcl_BinaryObjCmd: scan} -setup {
+    unset -nocomplain arg1
+} -body {
+    list [binary scan abc a5 arg1] [info exists arg1]
+} -result {0 0}
+test binary-20.6 {Tcl_BinaryObjCmd: scan} {
+    set arg1 foo
+    list [binary scan abc a2 arg1] $arg1
+} {1 ab}
+test binary-20.7 {Tcl_BinaryObjCmd: scan} -setup {
+    unset -nocomplain arg1
+    unset -nocomplain arg2
+} -body {
+    list [binary scan abcdef a2a2 arg1 arg2] $arg1 $arg2
+} -result {2 ab cd}
+test binary-20.8 {Tcl_BinaryObjCmd: scan} -setup {
+    unset -nocomplain arg1
+} -body {
+    list [binary scan abc a2 arg1(a)] $arg1(a)
+} -result {1 ab}
+test binary-20.9 {Tcl_BinaryObjCmd: scan} -setup {
+    unset -nocomplain arg1
+} -body {
+    list [binary scan abc a arg1(a)] $arg1(a)
+} -result {1 a}
+
+test binary-21.1 {Tcl_BinaryObjCmd: scan} -returnCodes error -body {
+    binary scan abc A
+} -result {not enough arguments for all format specifiers}
+test binary-21.2 {Tcl_BinaryObjCmd: scan} -setup {
+    unset -nocomplain arg1
+} -returnCodes error -body {
+    set arg1 1
+    binary scan abc A arg1(a)
+} -result {can't set "arg1(a)": variable isn't array}
+test binary-21.3 {Tcl_BinaryObjCmd: scan} -setup {
+    unset -nocomplain arg1
+} -body {
+    set arg1 abc
+    list [binary scan abc A0 arg1] $arg1
+} -result {1 {}}
+test binary-21.4 {Tcl_BinaryObjCmd: scan} -setup {
+    unset -nocomplain arg1
+} -body {
+    list [binary scan abc A* arg1] $arg1
+} -result {1 abc}
+test binary-21.5 {Tcl_BinaryObjCmd: scan} -setup {
+    unset -nocomplain arg1
+} -body {
+    list [binary scan abc A5 arg1] [info exists arg1]
+} -result {0 0}
+test binary-21.6 {Tcl_BinaryObjCmd: scan} {
+    set arg1 foo
+    list [binary scan abc A2 arg1] $arg1
+} {1 ab}
+test binary-21.7 {Tcl_BinaryObjCmd: scan} -setup {
+    unset -nocomplain arg1
+    unset -nocomplain arg2
+} -body {
+    list [binary scan abcdef A2A2 arg1 arg2] $arg1 $arg2
+} -result {2 ab cd}
+test binary-21.8 {Tcl_BinaryObjCmd: scan} -setup {
+    unset -nocomplain arg1
+} -body {
+    list [binary scan abc A2 arg1(a)] $arg1(a)
+} -result {1 ab}
+test binary-21.9 {Tcl_BinaryObjCmd: scan} -setup {
+    unset -nocomplain arg1
+} -body {
+    list [binary scan abc A2 arg1(a)] $arg1(a)
+} -result {1 ab}
+test binary-21.10 {Tcl_BinaryObjCmd: scan} -setup {
+    unset -nocomplain arg1
+} -body {
+    list [binary scan abc A arg1(a)] $arg1(a)
+} -result {1 a}
+test binary-21.11 {Tcl_BinaryObjCmd: scan} -setup {
+    unset -nocomplain arg1
+} -body {
+    list [binary scan "abc def \x00  " A* arg1] $arg1
+} -result {1 {abc def}}
+test binary-21.12 {Tcl_BinaryObjCmd: scan} -setup {
+    unset -nocomplain arg1
+} -body {
+    list [binary scan "abc def \x00ghi  " A* arg1] $arg1
+} -result [list 1 "abc def \x00ghi"]
+
+test binary-22.1 {Tcl_BinaryObjCmd: scan} -returnCodes error -body {
+    binary scan abc b
+} -result {not enough arguments for all format specifiers}
+test binary-22.2 {Tcl_BinaryObjCmd: scan} {
+    unset -nocomplain arg1
+    list [binary scan \x52\x53 b* arg1] $arg1
+} {1 0100101011001010}
+test binary-22.3 {Tcl_BinaryObjCmd: scan} {
+    unset -nocomplain arg1
+    list [binary scan \x82\x53 b arg1] $arg1
+} {1 0}
+test binary-22.4 {Tcl_BinaryObjCmd: scan} {
+    unset -nocomplain arg1
+    list [binary scan \x82\x53 b1 arg1] $arg1
+} {1 0}
+test binary-22.5 {Tcl_BinaryObjCmd: scan} {
+    unset -nocomplain arg1
+    list [binary scan \x82\x53 b0 arg1] $arg1
+} {1 {}}
+test binary-22.6 {Tcl_BinaryObjCmd: scan} {
+    unset -nocomplain arg1
+    list [binary scan \x52\x53 b5 arg1] $arg1
+} {1 01001}
+test binary-22.7 {Tcl_BinaryObjCmd: scan} {
+    unset -nocomplain arg1
+    list [binary scan \x52\x53 b8 arg1] $arg1
+} {1 01001010}
+test binary-22.8 {Tcl_BinaryObjCmd: scan} {
+    unset -nocomplain arg1
+    list [binary scan \x52\x53 b14 arg1] $arg1
+} {1 01001010110010}
+test binary-22.9 {Tcl_BinaryObjCmd: scan} {
+    unset -nocomplain arg1
+    set arg1 foo
+    list [binary scan \x52 b14 arg1] $arg1
+} {0 foo}
+test binary-22.10 {Tcl_BinaryObjCmd: scan} -setup {
+    unset -nocomplain arg1
+} -returnCodes error -body {
+    set arg1 1
+    binary scan \x52\x53 b1 arg1(a)
+} -result {can't set "arg1(a)": variable isn't array}
+test binary-22.11 {Tcl_BinaryObjCmd: scan} -setup {
+    unset -nocomplain arg1 arg2
+} -body {
+    set arg1 foo
+    set arg2 bar
+    list [binary scan \x07\x87\x05 b5b* arg1 arg2] $arg1 $arg2
+} -result {2 11100 1110000110100000}
+
+test binary-23.1 {Tcl_BinaryObjCmd: scan} -returnCodes error -body {
+    binary scan abc B
+} -result {not enough arguments for all format specifiers}
+test binary-23.2 {Tcl_BinaryObjCmd: scan} {
+    unset -nocomplain arg1
+    list [binary scan \x52\x53 B* arg1] $arg1
+} {1 0101001001010011}
+test binary-23.3 {Tcl_BinaryObjCmd: scan} {
+    unset -nocomplain arg1
+    list [binary scan \x82\x53 B arg1] $arg1
+} {1 1}
+test binary-23.4 {Tcl_BinaryObjCmd: scan} {
+    unset -nocomplain arg1
+    list [binary scan \x82\x53 B1 arg1] $arg1
+} {1 1}
+test binary-23.5 {Tcl_BinaryObjCmd: scan} {
+    unset -nocomplain arg1
+    list [binary scan \x52\x53 B0 arg1] $arg1
+} {1 {}}
+test binary-23.6 {Tcl_BinaryObjCmd: scan} {
+    unset -nocomplain arg1
+    list [binary scan \x52\x53 B5 arg1] $arg1
+} {1 01010}
+test binary-23.7 {Tcl_BinaryObjCmd: scan} {
+    unset -nocomplain arg1
+    list [binary scan \x52\x53 B8 arg1] $arg1
+} {1 01010010}
+test binary-23.8 {Tcl_BinaryObjCmd: scan} {
+    unset -nocomplain arg1
+    list [binary scan \x52\x53 B14 arg1] $arg1
+} {1 01010010010100}
+test binary-23.9 {Tcl_BinaryObjCmd: scan} {
+    unset -nocomplain arg1
+    set arg1 foo
+    list [binary scan \x52 B14 arg1] $arg1
+} {0 foo}
+test binary-23.10 {Tcl_BinaryObjCmd: scan} -setup {
+    unset -nocomplain arg1
+} -returnCodes error -body {
+    set arg1 1
+    binary scan \x52\x53 B1 arg1(a)
+} -result {can't set "arg1(a)": variable isn't array}
+test binary-23.11 {Tcl_BinaryObjCmd: scan} -setup {
+    unset -nocomplain arg1 arg2
+} -body {
+    set arg1 foo
+    set arg2 bar
+    list [binary scan \x70\x87\x05 B5B* arg1 arg2] $arg1 $arg2
+} -result {2 01110 1000011100000101}
+
+test binary-24.1 {Tcl_BinaryObjCmd: scan} -returnCodes error -body {
+    binary scan abc h
+} -result {not enough arguments for all format specifiers}
+test binary-24.2 {Tcl_BinaryObjCmd: scan} {
+    unset -nocomplain arg1
+    list [binary scan \x52\xa3 h* arg1] $arg1
+} {1 253a}
+test binary-24.3 {Tcl_BinaryObjCmd: scan} {
+    unset -nocomplain arg1
+    list [binary scan \xc2\xa3 h arg1] $arg1
+} {1 2}
+test binary-24.4 {Tcl_BinaryObjCmd: scan} {
+    unset -nocomplain arg1
+    list [binary scan \x82\x53 h1 arg1] $arg1
+} {1 2}
+test binary-24.5 {Tcl_BinaryObjCmd: scan} {
+    unset -nocomplain arg1
+    list [binary scan \x52\x53 h0 arg1] $arg1
+} {1 {}}
+test binary-24.6 {Tcl_BinaryObjCmd: scan} {
+    unset -nocomplain arg1
+    list [binary scan \xf2\x53 h2 arg1] $arg1
+} {1 2f}
+test binary-24.7 {Tcl_BinaryObjCmd: scan} {
+    unset -nocomplain arg1
+    list [binary scan \x52\x53 h3 arg1] $arg1
+} {1 253}
+test binary-24.8 {Tcl_BinaryObjCmd: scan} {
+    unset -nocomplain arg1
+    set arg1 foo
+    list [binary scan \x52 h3 arg1] $arg1
+} {0 foo}
+test binary-24.9 {Tcl_BinaryObjCmd: scan} -setup {
+    unset -nocomplain arg1
+} -returnCodes error -body {
+    set arg1 1
+    binary scan \x52\x53 h1 arg1(a)
+} -result {can't set "arg1(a)": variable isn't array}
+test binary-24.10 {Tcl_BinaryObjCmd: scan} -setup {
+    unset -nocomplain arg1 arg2
+} -body {
+    set arg1 foo
+    set arg2 bar
+    list [binary scan \x70\x87\x05 h2h* arg1 arg2] $arg1 $arg2
+} -result {2 07 7850}
+
+test binary-25.1 {Tcl_BinaryObjCmd: scan} -returnCodes error -body {
+    binary scan abc H
+} -result {not enough arguments for all format specifiers}
+test binary-25.2 {Tcl_BinaryObjCmd: scan} {
+    unset -nocomplain arg1
+    list [binary scan \x52\xa3 H* arg1] $arg1
+} {1 52a3}
+test binary-25.3 {Tcl_BinaryObjCmd: scan} {
+    unset -nocomplain arg1
+    list [binary scan \xc2\xa3 H arg1] $arg1
+} {1 c}
+test binary-25.4 {Tcl_BinaryObjCmd: scan} {
+    unset -nocomplain arg1
+    list [binary scan \x82\x53 H1 arg1] $arg1
+} {1 8}
+test binary-25.5 {Tcl_BinaryObjCmd: scan} {
+    unset -nocomplain arg1
+    list [binary scan \x52\x53 H0 arg1] $arg1
+} {1 {}}
+test binary-25.6 {Tcl_BinaryObjCmd: scan} {
+    unset -nocomplain arg1
+    list [binary scan \xf2\x53 H2 arg1] $arg1
+} {1 f2}
+test binary-25.7 {Tcl_BinaryObjCmd: scan} {
+    unset -nocomplain arg1
+    list [binary scan \x52\x53 H3 arg1] $arg1
+} {1 525}
+test binary-25.8 {Tcl_BinaryObjCmd: scan} {
+    unset -nocomplain arg1
+    set arg1 foo
+    list [binary scan \x52 H3 arg1] $arg1
+} {0 foo}
+test binary-25.9 {Tcl_BinaryObjCmd: scan} -setup {
+    unset -nocomplain arg1
+} -returnCodes error -body {
+    set arg1 1
+    binary scan \x52\x53 H1 arg1(a)
+} -result {can't set "arg1(a)": variable isn't array}
+test binary-25.10 {Tcl_BinaryObjCmd: scan} {
+    unset -nocomplain arg1 arg2
+    set arg1 foo
+    set arg2 bar
+    list [binary scan \x70\x87\x05 H2H* arg1 arg2] $arg1 $arg2
+} {2 70 8705}
+
+test binary-26.1 {Tcl_BinaryObjCmd: scan} -returnCodes error -body {
+    binary scan abc c
+} -result {not enough arguments for all format specifiers}
+test binary-26.2 {Tcl_BinaryObjCmd: scan} {
+    unset -nocomplain arg1
+    list [binary scan \x52\xa3 c* arg1] $arg1
+} {1 {82 -93}}
+test binary-26.3 {Tcl_BinaryObjCmd: scan} {
+    unset -nocomplain arg1
+    list [binary scan \x52\xa3 c arg1] $arg1
+} {1 82}
+test binary-26.4 {Tcl_BinaryObjCmd: scan} {
+    unset -nocomplain arg1
+    list [binary scan \x52\xa3 c1 arg1] $arg1
+} {1 82}
+test binary-26.5 {Tcl_BinaryObjCmd: scan} {
+    unset -nocomplain arg1
+    list [binary scan \x52\xa3 c0 arg1] $arg1
+} {1 {}}
+test binary-26.6 {Tcl_BinaryObjCmd: scan} {
+    unset -nocomplain arg1
+    list [binary scan \x52\xa3 c2 arg1] $arg1
+} {1 {82 -93}}
+test binary-26.7 {Tcl_BinaryObjCmd: scan} {
+    unset -nocomplain arg1
+    list [binary scan \xff c arg1] $arg1
+} {1 -1}
+test binary-26.8 {Tcl_BinaryObjCmd: scan} {
+    unset -nocomplain arg1
+    set arg1 foo
+    list [binary scan \x52 c3 arg1] $arg1
+} {0 foo}
+test binary-26.9 {Tcl_BinaryObjCmd: scan} -setup {
+    unset -nocomplain arg1
+} -returnCodes error -body {
+    set arg1 1
+    binary scan \x52\x53 c1 arg1(a)
+} -result {can't set "arg1(a)": variable isn't array}
+test binary-26.10 {Tcl_BinaryObjCmd: scan} {
+    unset -nocomplain arg1 arg2
+    set arg1 foo
+    set arg2 bar
+    list [binary scan \x70\x87\x05 c2c* arg1 arg2] $arg1 $arg2
+} {2 {112 -121} 5}
+test binary-26.11 {Tcl_BinaryObjCmd: scan} {
+    unset -nocomplain arg1
+    list [binary scan \x52\xa3 cu* arg1] $arg1
+} {1 {82 163}}
+test binary-26.12 {Tcl_BinaryObjCmd: scan} {
+    unset -nocomplain arg1
+    list [binary scan \x52\xa3 cu arg1] $arg1
+} {1 82}
+test binary-26.13 {Tcl_BinaryObjCmd: scan} {
+    unset -nocomplain arg1
+    list [binary scan \xff cu arg1] $arg1
+} {1 255}
+test binary-26.14 {Tcl_BinaryObjCmd: scan} {
+    unset -nocomplain arg1 arg2
+    set arg1 foo
+    set arg2 bar
+    list [binary scan \x80\x80 cuc arg1 arg2] $arg1 $arg2
+} {2 128 -128}
+test binary-26.15 {Tcl_BinaryObjCmd: scan} {
+    unset -nocomplain arg1 arg2
+    set arg1 foo
+    set arg2 bar
+    list [binary scan \x80\x80 ccu arg1 arg2] $arg1 $arg2
+} {2 -128 128}
+
+test binary-27.1 {Tcl_BinaryObjCmd: scan} -returnCodes error -body {
+    binary scan abc s
+} -result {not enough arguments for all format specifiers}
+test binary-27.2 {Tcl_BinaryObjCmd: scan} {
+    unset -nocomplain arg1
+    list [binary scan \x52\xa3\x53\x54 s* arg1] $arg1
+} {1 {-23726 21587}}
+test binary-27.3 {Tcl_BinaryObjCmd: scan} {
+    unset -nocomplain arg1
+    list [binary scan \x52\xa3\x53\x54 s arg1] $arg1
+} {1 -23726}
+test binary-27.4 {Tcl_BinaryObjCmd: scan} {
+    unset -nocomplain arg1
+    list [binary scan \x52\xa3 s1 arg1] $arg1
+} {1 -23726}
+test binary-27.5 {Tcl_BinaryObjCmd: scan} {
+    unset -nocomplain arg1
+    list [binary scan \x52\xa3 s0 arg1] $arg1
+} {1 {}}
+test binary-27.6 {Tcl_BinaryObjCmd: scan} {
+    unset -nocomplain arg1
+    list [binary scan \x52\xa3\x53\x54 s2 arg1] $arg1
+} {1 {-23726 21587}}
+test binary-27.7 {Tcl_BinaryObjCmd: scan} {
+    unset -nocomplain arg1
+    set arg1 foo
+    list [binary scan \x52 s1 arg1] $arg1
+} {0 foo}
+test binary-27.8 {Tcl_BinaryObjCmd: scan} -setup {
+    unset -nocomplain arg1
+} -returnCodes error -body {
+    set arg1 1
+    binary scan \x52\x53 s1 arg1(a)
+} -result {can't set "arg1(a)": variable isn't array}
+test binary-27.9 {Tcl_BinaryObjCmd: scan} {
+    unset -nocomplain arg1 arg2
+    set arg1 foo
+    set arg2 bar
+    list [binary scan \x52\xa3\x53\x54\x05 s2c* arg1 arg2] $arg1 $arg2
+} {2 {-23726 21587} 5}
+test binary-27.10 {Tcl_BinaryObjCmd: scan} {
+    unset -nocomplain arg1
+    list [binary scan \x52\xa3\x53\x54 su* arg1] $arg1
+} {1 {41810 21587}}
+test binary-27.11 {Tcl_BinaryObjCmd: scan} {
+    unset -nocomplain arg1 arg2
+    set arg1 foo
+    set arg2 bar
+    list [binary scan \xff\xff\xff\xff sus arg1 arg2] $arg1 $arg2
+} {2 65535 -1}
+test binary-27.12 {Tcl_BinaryObjCmd: scan} {
+    unset -nocomplain arg1 arg2
+    set arg1 foo
+    set arg2 bar
+    list [binary scan \xff\xff\xff\xff ssu arg1 arg2] $arg1 $arg2
+} {2 -1 65535}
+
+test binary-28.1 {Tcl_BinaryObjCmd: scan} -returnCodes error -body {
+    binary scan abc S
+} -result {not enough arguments for all format specifiers}
+test binary-28.2 {Tcl_BinaryObjCmd: scan} {
+    unset -nocomplain arg1
+    list [binary scan \x52\xa3\x53\x54 S* arg1] $arg1
+} {1 {21155 21332}}
+test binary-28.3 {Tcl_BinaryObjCmd: scan} {
+    unset -nocomplain arg1
+    list [binary scan \x52\xa3\x53\x54 S arg1] $arg1
+} {1 21155}
+test binary-28.4 {Tcl_BinaryObjCmd: scan} {
+    unset -nocomplain arg1
+    list [binary scan \x52\xa3 S1 arg1] $arg1
+} {1 21155}
+test binary-28.5 {Tcl_BinaryObjCmd: scan} {
+    unset -nocomplain arg1
+    list [binary scan \x52\xa3 S0 arg1] $arg1
+} {1 {}}
+test binary-28.6 {Tcl_BinaryObjCmd: scan} {
+    unset -nocomplain arg1
+    list [binary scan \x52\xa3\x53\x54 S2 arg1] $arg1
+} {1 {21155 21332}}
+test binary-28.7 {Tcl_BinaryObjCmd: scan} {
+    unset -nocomplain arg1
+    set arg1 foo
+    list [binary scan \x52 S1 arg1] $arg1
+} {0 foo}
+test binary-28.8 {Tcl_BinaryObjCmd: scan} -setup {
+    unset -nocomplain arg1
+} -returnCodes error -body {
+    set arg1 1
+    binary scan \x52\x53 S1 arg1(a)
+} -result {can't set "arg1(a)": variable isn't array}
+test binary-28.9 {Tcl_BinaryObjCmd: scan} {
+    unset -nocomplain arg1 arg2
+    set arg1 foo
+    set arg2 bar
+    list [binary scan \x52\xa3\x53\x54\x05 S2c* arg1 arg2] $arg1 $arg2
+} {2 {21155 21332} 5}
+test binary-28.10 {Tcl_BinaryObjCmd: scan} {
+    unset -nocomplain arg1
+    list [binary scan \x52\xa3\x53\x54 Su* arg1] $arg1
+} {1 {21155 21332}}
+test binary-28.11 {Tcl_BinaryObjCmd: scan} {
+    unset -nocomplain arg1
+    list [binary scan \xa3\x52\x54\x53 Su* arg1] $arg1
+} {1 {41810 21587}}
+
+test binary-29.1 {Tcl_BinaryObjCmd: scan} -returnCodes error -body {
+    binary scan abc i
+} -result {not enough arguments for all format specifiers}
+test binary-29.2 {Tcl_BinaryObjCmd: scan} {
+    unset -nocomplain arg1
+    list [binary scan \x52\xa3\x53\x54\x01\x02\x03\x04 i* arg1] $arg1
+} {1 {1414767442 67305985}}
+test binary-29.3 {Tcl_BinaryObjCmd: scan} {
+    unset -nocomplain arg1
+    list [binary scan \x52\xa3\x53\x54\x01\x02\x03\x04 i arg1] $arg1
+} {1 1414767442}
+test binary-29.4 {Tcl_BinaryObjCmd: scan} {
+    unset -nocomplain arg1
+    list [binary scan \x52\xa3\x53\x54 i1 arg1] $arg1
+} {1 1414767442}
+test binary-29.5 {Tcl_BinaryObjCmd: scan} {
+    unset -nocomplain arg1
+    list [binary scan \x52\xa3\x53 i0 arg1] $arg1
+} {1 {}}
+test binary-29.6 {Tcl_BinaryObjCmd: scan} {
+    unset -nocomplain arg1
+    list [binary scan \x52\xa3\x53\x54\x01\x02\x03\x04 i2 arg1] $arg1
+} {1 {1414767442 67305985}}
+test binary-29.7 {Tcl_BinaryObjCmd: scan} {
+    unset -nocomplain arg1
+    set arg1 foo
+    list [binary scan \x52 i1 arg1] $arg1
+} {0 foo}
+test binary-29.8 {Tcl_BinaryObjCmd: scan} -setup {
+    unset -nocomplain arg1
+} -returnCodes error -body {
+    set arg1 1
+    binary scan \x52\x53\x53\x54 i1 arg1(a)
+} -result {can't set "arg1(a)": variable isn't array}
+test binary-29.9 {Tcl_BinaryObjCmd: scan} {
+    unset -nocomplain arg1 arg2
+    set arg1 foo
+    set arg2 bar
+    list [binary scan \x52\xa3\x53\x54\x01\x02\x03\x04\x05 i2c* arg1 arg2] $arg1 $arg2
+} {2 {1414767442 67305985} 5}
+test binary-29.10 {Tcl_BinaryObjCmd: scan} {
+    unset -nocomplain arg1 arg2
+    list [binary scan \xff\xff\xff\xff\xff\xff\xff\xff iui arg1 arg2] $arg1 $arg2
+} {2 4294967295 -1}
+test binary-29.11 {Tcl_BinaryObjCmd: scan} {
+    unset -nocomplain arg1 arg2
+    list [binary scan \xff\xff\xff\xff\xff\xff\xff\xff iiu arg1 arg2] $arg1 $arg2
+} {2 -1 4294967295}
+test binary-29.12 {Tcl_BinaryObjCmd: scan} {
+    unset -nocomplain arg1 arg2
+    list [binary scan \x80\x00\x00\x00\x00\x00\x00\x80 iuiu arg1 arg2] $arg1 $arg2
+} {2 128 2147483648}
+
+test binary-30.1 {Tcl_BinaryObjCmd: scan} -returnCodes error -body {
+    binary scan abc I
+} -result {not enough arguments for all format specifiers}
+test binary-30.2 {Tcl_BinaryObjCmd: scan} {
+    unset -nocomplain arg1
+    list [binary scan \x52\xa3\x53\x54\x01\x02\x03\x04 I* arg1] $arg1
+} {1 {1386435412 16909060}}
+test binary-30.3 {Tcl_BinaryObjCmd: scan} {
+    unset -nocomplain arg1
+    list [binary scan \x52\xa3\x53\x54\x01\x02\x03\x04 I arg1] $arg1
+} {1 1386435412}
+test binary-30.4 {Tcl_BinaryObjCmd: scan} {
+    unset -nocomplain arg1
+    list [binary scan \x52\xa3\x53\x54 I1 arg1] $arg1
+} {1 1386435412}
+test binary-30.5 {Tcl_BinaryObjCmd: scan} {
+    unset -nocomplain arg1
+    list [binary scan \x52\xa3\x53 I0 arg1] $arg1
+} {1 {}}
+test binary-30.6 {Tcl_BinaryObjCmd: scan} {
+    unset -nocomplain arg1
+    list [binary scan \x52\xa3\x53\x54\x01\x02\x03\x04 I2 arg1] $arg1
+} {1 {1386435412 16909060}}
+test binary-30.7 {Tcl_BinaryObjCmd: scan} {
+    unset -nocomplain arg1
+    set arg1 foo
+    list [binary scan \x52 I1 arg1] $arg1
+} {0 foo}
+test binary-30.8 {Tcl_BinaryObjCmd: scan} -setup {
+    unset -nocomplain arg1
+} -returnCodes error -body {
+    set arg1 1
+    binary scan \x52\x53\x53\x54 I1 arg1(a)
+} -result {can't set "arg1(a)": variable isn't array}
+test binary-30.9 {Tcl_BinaryObjCmd: scan} {
+    unset -nocomplain arg1 arg2
+    set arg1 foo
+    set arg2 bar
+    list [binary scan \x52\xa3\x53\x54\x01\x02\x03\x04\x05 I2c* arg1 arg2] $arg1 $arg2
+} {2 {1386435412 16909060} 5}
+test binary-30.10 {Tcl_BinaryObjCmd: scan} {
+    unset -nocomplain arg1 arg2
+    list [binary scan \xff\xff\xff\xff\xff\xff\xff\xff IuI arg1 arg2] $arg1 $arg2
+} {2 4294967295 -1}
+test binary-30.11 {Tcl_BinaryObjCmd: scan} {
+    unset -nocomplain arg1 arg2
+    list [binary scan \xff\xff\xff\xff\xff\xff\xff\xff IIu arg1 arg2] $arg1 $arg2
+} {2 -1 4294967295}
+test binary-30.12 {Tcl_BinaryObjCmd: scan} {
+    unset -nocomplain arg1 arg2
+    list [binary scan \x80\x00\x00\x00\x00\x00\x00\x80 IuIu arg1 arg2] $arg1 $arg2
+} {2 2147483648 128}
+
+test binary-31.1 {Tcl_BinaryObjCmd: scan} -returnCodes error -body {
+    binary scan abc f
+} -result {not enough arguments for all format specifiers}
+test binary-31.2 {Tcl_BinaryObjCmd: scan} bigEndian {
+    unset -nocomplain arg1
+    list [binary scan \x3f\xcc\xcc\xcd\x40\x59\x99\x9a f* arg1] $arg1
+} {1 {1.600000023841858 3.4000000953674316}}
+test binary-31.3 {Tcl_BinaryObjCmd: scan} littleEndian {
+    unset -nocomplain arg1
+    list [binary scan \xcd\xcc\xcc\x3f\x9a\x99\x59\x40 f* arg1] $arg1
+} {1 {1.600000023841858 3.4000000953674316}}
+test binary-31.4 {Tcl_BinaryObjCmd: scan} bigEndian {
+    unset -nocomplain arg1
+    list [binary scan \x3f\xcc\xcc\xcd\x40\x59\x99\x9a f arg1] $arg1
+} {1 1.600000023841858}
+test binary-31.5 {Tcl_BinaryObjCmd: scan} littleEndian {
+    unset -nocomplain arg1
+    list [binary scan \xcd\xcc\xcc\x3f\x9a\x99\x59\x40 f arg1] $arg1
+} {1 1.600000023841858}
+test binary-31.6 {Tcl_BinaryObjCmd: scan} bigEndian {
+    unset -nocomplain arg1
+    list [binary scan \x3f\xcc\xcc\xcd f1 arg1] $arg1
+} {1 1.600000023841858}
+test binary-31.7 {Tcl_BinaryObjCmd: scan} littleEndian {
+    unset -nocomplain arg1
+    list [binary scan \xcd\xcc\xcc\x3f f1 arg1] $arg1
+} {1 1.600000023841858}
+test binary-31.8 {Tcl_BinaryObjCmd: scan} bigEndian {
+    unset -nocomplain arg1
+    list [binary scan \x3f\xcc\xcc\xcd f0 arg1] $arg1
+} {1 {}}
+test binary-31.9 {Tcl_BinaryObjCmd: scan} littleEndian {
+    unset -nocomplain arg1
+    list [binary scan \xcd\xcc\xcc\x3f f0 arg1] $arg1
+} {1 {}}
+test binary-31.10 {Tcl_BinaryObjCmd: scan} bigEndian {
+    unset -nocomplain arg1
+    list [binary scan \x3f\xcc\xcc\xcd\x40\x59\x99\x9a f2 arg1] $arg1
+} {1 {1.600000023841858 3.4000000953674316}}
+test binary-31.11 {Tcl_BinaryObjCmd: scan} littleEndian {
+    unset -nocomplain arg1
+    list [binary scan \xcd\xcc\xcc\x3f\x9a\x99\x59\x40 f2 arg1] $arg1
+} {1 {1.600000023841858 3.4000000953674316}}
+test binary-31.12 {Tcl_BinaryObjCmd: scan} {
+    unset -nocomplain arg1
+    set arg1 foo
+    list [binary scan \x52 f1 arg1] $arg1
+} {0 foo}
+test binary-31.13 {Tcl_BinaryObjCmd: scan} -setup {
+    unset -nocomplain arg1
+} -returnCodes error -body {
+    set arg1 1
+    binary scan \x3f\xcc\xcc\xcd f1 arg1(a)
+} -result {can't set "arg1(a)": variable isn't array}
+test binary-31.14 {Tcl_BinaryObjCmd: scan} bigEndian {
+    unset -nocomplain arg1 arg2
+    set arg1 foo
+    set arg2 bar
+    list [binary scan \x3f\xcc\xcc\xcd\x40\x59\x99\x9a\x05 f2c* arg1 arg2] $arg1 $arg2
+} {2 {1.600000023841858 3.4000000953674316} 5}
+test binary-31.15 {Tcl_BinaryObjCmd: scan} littleEndian {
+    unset -nocomplain arg1 arg2
+    set arg1 foo
+    set arg2 bar
+    list [binary scan \xcd\xcc\xcc\x3f\x9a\x99\x59\x40\x05 f2c* arg1 arg2] $arg1 $arg2
+} {2 {1.600000023841858 3.4000000953674316} 5}
+
+test binary-32.1 {Tcl_BinaryObjCmd: scan} -returnCodes error -body {
+    binary scan abc d
+} -result {not enough arguments for all format specifiers}
+test binary-32.2 {Tcl_BinaryObjCmd: scan} bigEndian {
+    unset -nocomplain arg1
+    list [binary scan \x3f\xf9\x99\x99\x99\x99\x99\x9a\x40\x0b\x33\x33\x33\x33\x33\x33 d* arg1] $arg1
+} {1 {1.6 3.4}}
+test binary-32.3 {Tcl_BinaryObjCmd: scan} littleEndian {
+    unset -nocomplain arg1
+    list [binary scan \x9a\x99\x99\x99\x99\x99\xf9\x3f\x33\x33\x33\x33\x33\x33\x0b\x40 d* arg1] $arg1
+} {1 {1.6 3.4}}
+test binary-32.4 {Tcl_BinaryObjCmd: scan} bigEndian {
+    unset -nocomplain arg1
+    list [binary scan \x3f\xf9\x99\x99\x99\x99\x99\x9a\x40\x0b\x33\x33\x33\x33\x33\x33 d arg1] $arg1
+} {1 1.6}
+test binary-32.5 {Tcl_BinaryObjCmd: scan} littleEndian {
+    unset -nocomplain arg1
+    list [binary scan \x9a\x99\x99\x99\x99\x99\xf9\x3f\x33\x33\x33\x33\x33\x33\x0b\x40 d arg1] $arg1
+} {1 1.6}
+test binary-32.6 {Tcl_BinaryObjCmd: scan} bigEndian {
+    unset -nocomplain arg1
+    list [binary scan \x3f\xf9\x99\x99\x99\x99\x99\x9a d1 arg1] $arg1
+} {1 1.6}
+test binary-32.7 {Tcl_BinaryObjCmd: scan} littleEndian {
+    unset -nocomplain arg1
+    list [binary scan \x9a\x99\x99\x99\x99\x99\xf9\x3f d1 arg1] $arg1
+} {1 1.6}
+test binary-32.8 {Tcl_BinaryObjCmd: scan} bigEndian {
+    unset -nocomplain arg1
+    list [binary scan \x3f\xf9\x99\x99\x99\x99\x99\x9a d0 arg1] $arg1
+} {1 {}}
+test binary-32.9 {Tcl_BinaryObjCmd: scan} littleEndian {
+    unset -nocomplain arg1
+    list [binary scan \x9a\x99\x99\x99\x99\x99\xf9\x3f d0 arg1] $arg1
+} {1 {}}
+test binary-32.10 {Tcl_BinaryObjCmd: scan} bigEndian {
+    unset -nocomplain arg1
+    list [binary scan \x3f\xf9\x99\x99\x99\x99\x99\x9a\x40\x0b\x33\x33\x33\x33\x33\x33 d2 arg1] $arg1
+} {1 {1.6 3.4}}
+test binary-32.11 {Tcl_BinaryObjCmd: scan} littleEndian {
+    unset -nocomplain arg1
+    list [binary scan \x9a\x99\x99\x99\x99\x99\xf9\x3f\x33\x33\x33\x33\x33\x33\x0b\x40 d2 arg1] $arg1
+} {1 {1.6 3.4}}
+test binary-32.12 {Tcl_BinaryObjCmd: scan} {
+    unset -nocomplain arg1
+    set arg1 foo
+    list [binary scan \x52 d1 arg1] $arg1
+} {0 foo}
+test binary-32.13 {Tcl_BinaryObjCmd: scan} -setup {
+    unset -nocomplain arg1
+} -returnCodes error -body {
+    set arg1 1
+    binary scan \x3f\xf9\x99\x99\x99\x99\x99\x9a d1 arg1(a)
+} -result {can't set "arg1(a)": variable isn't array}
+test binary-32.14 {Tcl_BinaryObjCmd: scan} bigEndian {
+    unset -nocomplain arg1 arg2
+    set arg1 foo
+    set arg2 bar
+    list [binary scan \x3f\xf9\x99\x99\x99\x99\x99\x9a\x40\x0b\x33\x33\x33\x33\x33\x33\x05 d2c* arg1 arg2] $arg1 $arg2
+} {2 {1.6 3.4} 5}
+test binary-32.15 {Tcl_BinaryObjCmd: scan} littleEndian {
+    unset -nocomplain arg1 arg2
+    set arg1 foo
+    set arg2 bar
+    list [binary scan \x9a\x99\x99\x99\x99\x99\xf9\x3f\x33\x33\x33\x33\x33\x33\x0b\x40\x05 d2c* arg1 arg2] $arg1 $arg2
+} {2 {1.6 3.4} 5}
+
+test binary-33.1 {Tcl_BinaryObjCmd: scan} {
+    unset -nocomplain arg1
+    unset -nocomplain arg2
+    list [binary scan abcdefg a2xa3 arg1 arg2] $arg1 $arg2
+} {2 ab def}
+test binary-33.2 {Tcl_BinaryObjCmd: scan} {
+    unset -nocomplain arg1
+    unset -nocomplain arg2
+    set arg2 foo
+    list [binary scan abcdefg a3x*a3 arg1 arg2] $arg1 $arg2
+} {1 abc foo}
+test binary-33.3 {Tcl_BinaryObjCmd: scan} {
+    unset -nocomplain arg1
+    unset -nocomplain arg2
+    set arg2 foo
+    list [binary scan abcdefg a3x20a3 arg1 arg2] $arg1 $arg2
+} {1 abc foo}
+test binary-33.4 {Tcl_BinaryObjCmd: scan} {
+    unset -nocomplain arg1
+    unset -nocomplain arg2
+    set arg2 foo
+    list [binary scan abc a3x20a3 arg1 arg2] $arg1 $arg2
+} {1 abc foo}
+test binary-33.5 {Tcl_BinaryObjCmd: scan} {
+    unset -nocomplain arg1
+    list [binary scan abcdef x1a1 arg1] $arg1
+} {1 b}
+test binary-33.6 {Tcl_BinaryObjCmd: scan} {
+    unset -nocomplain arg1
+    list [binary scan abcdef x5a1 arg1] $arg1
+} {1 f}
+test binary-33.7 {Tcl_BinaryObjCmd: scan} {
+    unset -nocomplain arg1
+    list [binary scan abcdef x0a1 arg1] $arg1
+} {1 a}
+
+test binary-34.1 {Tcl_BinaryObjCmd: scan} {
+    unset -nocomplain arg1
+    unset -nocomplain arg2
+    list [binary scan abcdefg a2Xa3 arg1 arg2] $arg1 $arg2
+} {2 ab bcd}
+test binary-34.2 {Tcl_BinaryObjCmd: scan} {
+    unset -nocomplain arg1
+    unset -nocomplain arg2
+    set arg2 foo
+    list [binary scan abcdefg a3X*a3 arg1 arg2] $arg1 $arg2
+} {2 abc abc}
+test binary-34.3 {Tcl_BinaryObjCmd: scan} {
+    unset -nocomplain arg1
+    unset -nocomplain arg2
+    set arg2 foo
+    list [binary scan abcdefg a3X20a3 arg1 arg2] $arg1 $arg2
+} {2 abc abc}
+test binary-34.4 {Tcl_BinaryObjCmd: scan} {
+    unset -nocomplain arg1
+    list [binary scan abc X20a3 arg1] $arg1
+} {1 abc}
+test binary-34.5 {Tcl_BinaryObjCmd: scan} {
+    unset -nocomplain arg1
+    list [binary scan abcdef x*X1a1 arg1] $arg1
+} {1 f}
+test binary-34.6 {Tcl_BinaryObjCmd: scan} {
+    unset -nocomplain arg1
+    list [binary scan abcdef x*X5a1 arg1] $arg1
+} {1 b}
+test binary-34.7 {Tcl_BinaryObjCmd: scan} {
+    unset -nocomplain arg1
+    list [binary scan abcdef x3X0a1 arg1] $arg1
+} {1 d}
+
+test binary-35.1 {Tcl_BinaryObjCmd: scan} -setup {
+    unset -nocomplain arg1
+    unset -nocomplain arg2
+} -returnCodes error -body {
+    binary scan abcdefg a2@a3 arg1 arg2
+} -result {missing count for "@" field specifier}
+test binary-35.2 {Tcl_BinaryObjCmd: scan} {
+    unset -nocomplain arg1
+    unset -nocomplain arg2
+    set arg2 foo
+    list [binary scan abcdefg a3@*a3 arg1 arg2] $arg1 $arg2
+} {1 abc foo}
+test binary-35.3 {Tcl_BinaryObjCmd: scan} {
+    unset -nocomplain arg1
+    unset -nocomplain arg2
+    set arg2 foo
+    list [binary scan abcdefg a3@20a3 arg1 arg2] $arg1 $arg2
+} {1 abc foo}
+test binary-35.4 {Tcl_BinaryObjCmd: scan} {
+    unset -nocomplain arg1
+    list [binary scan abcdef @2a3 arg1] $arg1
+} {1 cde}
+test binary-35.5 {Tcl_BinaryObjCmd: scan} {
+    unset -nocomplain arg1
+    list [binary scan abcdef x*@1a1 arg1] $arg1
+} {1 b}
+test binary-35.6 {Tcl_BinaryObjCmd: scan} {
+    unset -nocomplain arg1
+    list [binary scan abcdef x*@0a1 arg1] $arg1
+} {1 a}
+
+test binary-36.1 {Tcl_BinaryObjCmd: scan} -returnCodes error -body {
+    binary scan abcdef u0a3
+} -result {bad field specifier "u"}
+
+# GetFormatSpec is pretty thoroughly tested above, but there are a few cases
+# we should text explicitly
+
+test binary-37.1 {GetFormatSpec: whitespace} {
+    binary format "a3 a5     a3" foo barblat baz
+} foobarblbaz
+test binary-37.2 {GetFormatSpec: whitespace} {
+    binary format "      " foo
+} {}
+test binary-37.3 {GetFormatSpec: whitespace} {
+    binary format "     a3" foo
+} foo
+test binary-37.4 {GetFormatSpec: whitespace} {
+    binary format "" foo
+} {}
+test binary-37.5 {GetFormatSpec: whitespace} {
+    binary format "" foo
+} {}
+test binary-37.6 {GetFormatSpec: whitespace} {
+    binary format "     a3   " foo
+} foo
+test binary-37.7 {GetFormatSpec: numbers} -returnCodes error -body {
+    binary scan abcdef "x-1" foo
+} -result {bad field specifier "-"}
+test binary-37.8 {GetFormatSpec: numbers} {
+    unset -nocomplain arg1
+    set arg1 foo
+    list [binary scan abcdef "a0x3" arg1] $arg1
+} {1 {}}
+test binary-37.9 {GetFormatSpec: numbers} {
+    # test format of neg numbers
+    # bug report/fix provided by Harald Kirsch
+    set x [binary format f* {1 -1 2 -2 0}]
+    binary scan $x f* bla
+    set bla
+} {1.0 -1.0 2.0 -2.0 0.0}
+
+test binary-38.1 {FormatNumber: word alignment} {
+    set x [binary format c1s1 1 1]
+} \x01\x01\x00
+test binary-38.2 {FormatNumber: word alignment} {
+    set x [binary format c1S1 1 1]
+} \x01\x00\x01
+test binary-38.3 {FormatNumber: word alignment} {
+    set x [binary format c1i1 1 1]
+} \x01\x01\x00\x00\x00
+test binary-38.4 {FormatNumber: word alignment} {
+    set x [binary format c1I1 1 1]
+} \x01\x00\x00\x00\x01
+test binary-38.5 {FormatNumber: word alignment} bigEndian {
+    set x [binary format c1d1 1 1.6]
+} \x01\x3f\xf9\x99\x99\x99\x99\x99\x9a
+test binary-38.6 {FormatNumber: word alignment} littleEndian {
+    set x [binary format c1d1 1 1.6]
+} \x01\x9a\x99\x99\x99\x99\x99\xf9\x3f
+test binary-38.7 {FormatNumber: word alignment} bigEndian {
+    set x [binary format c1f1 1 1.6]
+} \x01\x3f\xcc\xcc\xcd
+test binary-38.8 {FormatNumber: word alignment} littleEndian {
+    set x [binary format c1f1 1 1.6]
+} \x01\xcd\xcc\xcc\x3f
+
+test binary-39.1 {ScanNumber: sign extension} {
+    unset -nocomplain arg1
+    list [binary scan \x52\xa3 c2 arg1] $arg1
+} {1 {82 -93}}
+test binary-39.2 {ScanNumber: sign extension} {
+    unset -nocomplain arg1
+    list [binary scan \x01\x02\x01\x81\x82\x01\x81\x82 s4 arg1] $arg1
+} {1 {513 -32511 386 -32127}}
+test binary-39.3 {ScanNumber: sign extension} {
+    unset -nocomplain arg1
+    list [binary scan \x01\x02\x01\x81\x82\x01\x81\x82 S4 arg1] $arg1
+} {1 {258 385 -32255 -32382}}
+test binary-39.4 {ScanNumber: sign extension} {
+    unset -nocomplain arg1
+    list [binary scan \x01\x01\x01\x02\x81\x01\x01\x01\x01\x82\x01\x01\x01\x01\x82\x01\x01\x01\x01\x81 i5 arg1] $arg1
+} {1 {33620225 16843137 16876033 25297153 -2130640639}}
+test binary-39.5 {ScanNumber: sign extension} {
+    unset -nocomplain arg1
+    list [binary scan \x01\x01\x01\x02\x81\x01\x01\x01\x01\x82\x01\x01\x01\x01\x82\x01\x01\x01\x01\x81 I5 arg1] $arg1
+} {1 {16843010 -2130640639 25297153 16876033 16843137}}
+test binary-39.6 {ScanNumber: no sign extension} {
+    unset -nocomplain arg1
+    list [binary scan \x52\xa3 cu2 arg1] $arg1
+} {1 {82 163}}
+test binary-39.7 {ScanNumber: no sign extension} {
+    unset -nocomplain arg1
+    list [binary scan \x01\x02\x01\x81\x82\x01\x81\x82 su4 arg1] $arg1
+} {1 {513 33025 386 33409}}
+test binary-39.8 {ScanNumber: no sign extension} {
+    unset -nocomplain arg1
+    list [binary scan \x01\x02\x01\x81\x82\x01\x81\x82 Su4 arg1] $arg1
+} {1 {258 385 33281 33154}}
+test binary-39.9 {ScanNumber: no sign extension} {
+    unset -nocomplain arg1
+    list [binary scan \x01\x01\x01\x02\x81\x01\x01\x01\x01\x82\x01\x01\x01\x01\x82\x01\x01\x01\x01\x81 iu5 arg1] $arg1
+} {1 {33620225 16843137 16876033 25297153 2164326657}}
+test binary-39.10 {ScanNumber: no sign extension} {
+    unset -nocomplain arg1
+    list [binary scan \x01\x01\x01\x02\x81\x01\x01\x01\x01\x82\x01\x01\x01\x01\x82\x01\x01\x01\x01\x81 Iu5 arg1] $arg1
+} {1 {16843010 2164326657 25297153 16876033 16843137}}
+
+test binary-40.3 {ScanNumber: NaN} -body {
+    unset -nocomplain arg1
+    list [binary scan \xff\xff\xff\xff f1 arg1] $arg1
+} -match glob -result {1 -NaN*}
+test binary-40.4 {ScanNumber: NaN} -body {
+    unset -nocomplain arg1
+    list [binary scan \xff\xff\xff\xff\xff\xff\xff\xff d arg1] $arg1
+} -match glob -result {1 -NaN*}
+
+test binary-41.1 {ScanNumber: word alignment} -setup {
+    unset -nocomplain arg1 arg2
+} -body {
+    list [binary scan \x01\x01\x00 c1s1 arg1 arg2] $arg1 $arg2
+} -result {2 1 1}
+test binary-41.2 {ScanNumber: word alignment} -setup {
+    unset -nocomplain arg1 arg2
+} -body {
+    list [binary scan \x01\x00\x01 c1S1 arg1 arg2] $arg1 $arg2
+} -result {2 1 1}
+test binary-41.3 {ScanNumber: word alignment} -setup {
+    unset -nocomplain arg1 arg2
+} -body {
+    list [binary scan \x01\x01\x00\x00\x00 c1i1 arg1 arg2] $arg1 $arg2
+} -result {2 1 1}
+test binary-41.4 {ScanNumber: word alignment} -setup {
+    unset -nocomplain arg1 arg2
+} -body {
+    list [binary scan \x01\x00\x00\x00\x01 c1I1 arg1 arg2] $arg1 $arg2
+} -result {2 1 1}
+test binary-41.5 {ScanNumber: word alignment} -setup {
+    unset -nocomplain arg1 arg2
+} -constraints bigEndian -body {
+    list [binary scan \x01\x3f\xcc\xcc\xcd c1f1 arg1 arg2] $arg1 $arg2
+} -result {2 1 1.600000023841858}
+test binary-41.6 {ScanNumber: word alignment} -setup {
+    unset -nocomplain arg1 arg2
+} -constraints littleEndian -body {
+    list [binary scan \x01\xcd\xcc\xcc\x3f c1f1 arg1 arg2] $arg1 $arg2
+} -result {2 1 1.600000023841858}
+test binary-41.7 {ScanNumber: word alignment} -setup {
+    unset -nocomplain arg1 arg2
+} -constraints bigEndian -body {
+    list [binary scan \x01\x3f\xf9\x99\x99\x99\x99\x99\x9a c1d1 arg1 arg2] $arg1 $arg2
+} -result {2 1 1.6}
+test binary-41.8 {ScanNumber: word alignment} -setup {
+    unset -nocomplain arg1 arg2
+} -constraints littleEndian -body {
+    list [binary scan \x01\x9a\x99\x99\x99\x99\x99\xf9\x3f c1d1 arg1 arg2] $arg1 $arg2
+} -result {2 1 1.6}
+
+test binary-42.1 {Tcl_BinaryObjCmd: bad arguments} -constraints {} -body {
+    binary ?
+} -returnCodes error -match glob -result {unknown or ambiguous subcommand "?": *}
+
+# Wide int (guaranteed at least 64-bit) handling
+test binary-43.1 {Tcl_BinaryObjCmd: format wide int} {} {
+    binary format w 7810179016327718216
+} HelloTcl
+test binary-43.2 {Tcl_BinaryObjCmd: format wide int} {} {
+    binary format W 7810179016327718216
+} lcTolleH
+
+test binary-44.1 {Tcl_BinaryObjCmd: scan wide int} {} {
+    binary scan HelloTcl W x
+    set x
+} 5216694956358656876
+test binary-44.2 {Tcl_BinaryObjCmd: scan wide int} {} {
+    binary scan lcTolleH w x
+    set x
+} 5216694956358656876
+test binary-44.3 {Tcl_BinaryObjCmd: scan wide int with bit 31 set} {} {
+    binary scan [binary format w [expr {wide(3) << 31}]] w x
+    set x
+} 6442450944
+test binary-44.4 {Tcl_BinaryObjCmd: scan wide int with bit 31 set} {} {
+    binary scan [binary format W [expr {wide(3) << 31}]] W x
+    set x
+} 6442450944
+test binary-43.5 {Tcl_BinaryObjCmd: scan wide int} {} {
+    unset -nocomplain arg1
+    list [binary scan \x80[string repeat \x00 7] W arg1] $arg1
+} {1 -9223372036854775808}
+test binary-43.6 {Tcl_BinaryObjCmd: scan unsigned wide int} {} {
+    unset -nocomplain arg1
+    list [binary scan \x80[string repeat \x00 7] Wu arg1] $arg1
+} {1 9223372036854775808}
+test binary-43.7 {Tcl_BinaryObjCmd: scan unsigned wide int} {} {
+    unset -nocomplain arg1
+    list [binary scan [string repeat \x00 7]\x80 wu arg1] $arg1
+} {1 9223372036854775808}
+test binary-43.8 {Tcl_BinaryObjCmd: scan unsigned wide int} {} {
+    unset -nocomplain arg1 arg2
+    list [binary scan \x80[string repeat \x00 7]\x80[string repeat \x00 7] WuW arg1 arg2] $arg1 $arg2
+} {2 9223372036854775808 -9223372036854775808}
+test binary-43.9 {Tcl_BinaryObjCmd: scan unsigned wide int} {} {
+    unset -nocomplain arg1 arg2
+    list [binary scan [string repeat \x00 7]\x80[string repeat \x00 7]\x80 wuw arg1 arg2] $arg1 $arg2
+} {2 9223372036854775808 -9223372036854775808}
+
+test binary-45.1 {Tcl_BinaryObjCmd: combined wide int handling} {
+    binary scan [binary format sws 16450 -1 19521] c* x
+    set x
+} {66 64 -1 -1 -1 -1 -1 -1 -1 -1 65 76}
+test binary-45.2 {Tcl_BinaryObjCmd: combined wide int handling} {
+    binary scan [binary format sWs 16450 0x7fffffff 19521] c* x
+    set x
+} {66 64 0 0 0 0 127 -1 -1 -1 65 76}
+
+test binary-46.1 {Tcl_BinaryObjCmd: handling of non-ISO8859-1 chars} {
+    binary format a* \u20ac
+} \u00ac
+test binary-46.2 {Tcl_BinaryObjCmd: handling of non-ISO8859-1 chars} {
+    list [binary scan [binary format a* \u20ac\u20bd] s x] $x
+} {1 -16980}
+test binary-46.3 {Tcl_BinaryObjCmd: handling of non-ISO8859-1 chars} {
+    set x {}
+    set y {}
+    set z {}
+    list [binary scan [binary format a* \u20ac\u20bd] aaa x y z] $x $y $z
+} "2 \u00ac \u00bd {}"
+test binary-46.4 {Tcl_BinaryObjCmd: handling of non-ISO8859-1 chars} {
+    set x [encoding convertto iso8859-15 \u20ac]
+    set y [binary format a* $x]
+    list $x $y
+} "\u00a4 \u00a4"
+test binary-46.5 {Tcl_BinaryObjCmd: handling of non-ISO8859-1 chars} {
+    set x [binary scan \u00a4 a* y]
+    list $x $y [encoding convertfrom iso8859-15 $y]
+} "1 \u00a4 \u20ac"
+
+test binary-47.1 {Tcl_BinaryObjCmd: number cache reference count handling} {
+    # This test is only reliable when memory debugging is turned on, but
+    # without even memory debugging it should still generate the expected
+    # answers and might therefore still pick up memory corruption caused by
+    # [Bug 851747].
+    list [binary scan aba ccc x x x] $x
+} {3 97}
+
+### TIP#129: endian specifiers ----
+
+# format t
+test binary-48.1 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+    binary format t
+} -result {not enough arguments for all format specifiers}
+test binary-48.2 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+    binary format t blat
+} -result {expected integer but got "blat"}
+test binary-48.3 {Tcl_BinaryObjCmd: format} {
+    binary format S0 0x50
+} {}
+test binary-48.4 {Tcl_BinaryObjCmd: format} bigEndian {
+    binary format t 0x50
+} \x00P
+test binary-48.5 {Tcl_BinaryObjCmd: format} littleEndian {
+    binary format t 0x50
+} P\x00
+test binary-48.6 {Tcl_BinaryObjCmd: format} bigEndian {
+    binary format t 0x5052
+} PR
+test binary-48.7 {Tcl_BinaryObjCmd: format} littleEndian {
+    binary format t 0x5052
+} RP
+test binary-48.8 {Tcl_BinaryObjCmd: format} bigEndian {
+    binary format t 0x505251 0x53
+} RQ
+test binary-48.9 {Tcl_BinaryObjCmd: format} littleEndian {
+    binary format t 0x505251 0x53
+} QR
+test binary-48.10 {Tcl_BinaryObjCmd: format} bigEndian {
+    binary format t2 {0x50 0x52}
+} \x00P\x00R
+test binary-48.11 {Tcl_BinaryObjCmd: format} littleEndian {
+    binary format t2 {0x50 0x52}
+} P\x00R\x00
+test binary-48.12 {Tcl_BinaryObjCmd: format} bigEndian {
+    binary format t* {0x5051 0x52}
+} PQ\x00R
+test binary-48.13 {Tcl_BinaryObjCmd: format} littleEndian {
+    binary format t* {0x5051 0x52}
+} QPR\x00
+test binary-48.14 {Tcl_BinaryObjCmd: format} bigEndian {
+    binary format t2 {0x50 0x52 0x53} 0x54
+} \x00P\x00R
+test binary-48.15 {Tcl_BinaryObjCmd: format} littleEndian {
+    binary format t2 {0x50 0x52 0x53} 0x54
+} P\x00R\x00
+test binary-48.16 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+    binary format t2 {0x50}
+} -result {number of elements in list does not match count}
+test binary-48.17 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+    set a {0x50 0x51}
+    binary format t $a
+} -result "expected integer but got \"0x50 0x51\""
+test binary-48.18 {Tcl_BinaryObjCmd: format} bigEndian {
+    set a {0x50 0x51}
+    binary format t1 $a
+} \x00P
+test binary-48.19 {Tcl_BinaryObjCmd: format} littleEndian {
+    set a {0x50 0x51}
+    binary format t1 $a
+} P\x00
+
+# format n
+test binary-49.1 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+    binary format n
+} -result {not enough arguments for all format specifiers}
+test binary-49.2 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+    binary format n blat
+} -result {expected integer but got "blat"}
+test binary-49.3 {Tcl_BinaryObjCmd: format} {
+    binary format n0 0x50
+} {}
+test binary-49.4 {Tcl_BinaryObjCmd: format} littleEndian {
+    binary format n 0x50
+} P\x00\x00\x00
+test binary-49.5 {Tcl_BinaryObjCmd: format} littleEndian {
+    binary format n 0x5052
+} RP\x00\x00
+test binary-49.6 {Tcl_BinaryObjCmd: format} littleEndian {
+    binary format n 0x505251 0x53
+} QRP\x00
+test binary-49.7 {Tcl_BinaryObjCmd: format} littleEndian {
+    binary format i1 {0x505251 0x53}
+} QRP\x00
+test binary-49.8 {Tcl_BinaryObjCmd: format} littleEndian {
+    binary format n 0x53525150
+} PQRS
+test binary-49.9 {Tcl_BinaryObjCmd: format} littleEndian {
+    binary format n2 {0x50 0x52}
+} P\x00\x00\x00R\x00\x00\x00
+test binary-49.10 {Tcl_BinaryObjCmd: format} littleEndian {
+    binary format n* {0x50515253 0x52}
+} SRQPR\x00\x00\x00
+test binary-49.11 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+    binary format n2 {0x50}
+} -result {number of elements in list does not match count}
+test binary-49.12 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+    set a {0x50 0x51}
+    binary format n $a
+} -result "expected integer but got \"0x50 0x51\""
+test binary-49.13 {Tcl_BinaryObjCmd: format} littleEndian {
+    set a {0x50 0x51}
+    binary format n1 $a
+} P\x00\x00\x00
+test binary-49.14 {Tcl_BinaryObjCmd: format} bigEndian {
+    binary format n 0x50
+} \x00\x00\x00P
+test binary-49.15 {Tcl_BinaryObjCmd: format} bigEndian {
+    binary format n 0x5052
+} \x00\x00PR
+test binary-49.16 {Tcl_BinaryObjCmd: format} bigEndian {
+    binary format n 0x505251 0x53
+} \x00PRQ
+test binary-49.17 {Tcl_BinaryObjCmd: format} bigEndian {
+    binary format i1 {0x505251 0x53}
+} QRP\x00
+test binary-49.18 {Tcl_BinaryObjCmd: format} bigEndian {
+    binary format n 0x53525150
+} SRQP
+test binary-49.19 {Tcl_BinaryObjCmd: format} bigEndian {
+    binary format n2 {0x50 0x52}
+} \x00\x00\x00P\x00\x00\x00R
+test binary-49.20 {Tcl_BinaryObjCmd: format} bigEndian {
+    binary format n* {0x50515253 0x52}
+} PQRS\x00\x00\x00R
+
+# format m
+test binary-50.1 {Tcl_BinaryObjCmd: format wide int} littleEndian {
+    binary format m 7810179016327718216
+} HelloTcl
+test binary-50.2 {Tcl_BinaryObjCmd: format wide int} bigEndian {
+    binary format m 7810179016327718216
+} lcTolleH
+test binary-50.3 {Tcl_BinaryObjCmd: scan wide int with bit 31 set} littleEndian {
+    binary scan [binary format m [expr {wide(3) << 31}]] w x
+    set x
+} 6442450944
+test binary-50.4 {Tcl_BinaryObjCmd: scan wide int with bit 31 set} bigEndian {
+    binary scan [binary format m [expr {wide(3) << 31}]] W x
+    set x
+} 6442450944
+
+# format Q/q
+test binary-51.1 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+    binary format Q
+} -result {not enough arguments for all format specifiers}
+test binary-51.2 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+    binary format q blat
+} -result {expected floating-point number but got "blat"}
+test binary-51.3 {Tcl_BinaryObjCmd: format} {
+    binary format q0 1.6
+} {}
+test binary-51.4 {Tcl_BinaryObjCmd: format} {} {
+    binary format Q 1.6
+} \x3f\xf9\x99\x99\x99\x99\x99\x9a
+test binary-51.5 {Tcl_BinaryObjCmd: format} {} {
+    binary format q 1.6
+} \x9a\x99\x99\x99\x99\x99\xf9\x3f
+test binary-51.6 {Tcl_BinaryObjCmd: format} {} {
+    binary format Q* {1.6 3.4}
+} \x3f\xf9\x99\x99\x99\x99\x99\x9a\x40\x0b\x33\x33\x33\x33\x33\x33
+test binary-51.7 {Tcl_BinaryObjCmd: format} {} {
+    binary format q* {1.6 3.4}
+} \x9a\x99\x99\x99\x99\x99\xf9\x3f\x33\x33\x33\x33\x33\x33\x0b\x40
+test binary-51.8 {Tcl_BinaryObjCmd: format} {} {
+    binary format Q2 {1.6 3.4}
+} \x3f\xf9\x99\x99\x99\x99\x99\x9a\x40\x0b\x33\x33\x33\x33\x33\x33
+test binary-51.9 {Tcl_BinaryObjCmd: format} {} {
+    binary format q2 {1.6 3.4}
+} \x9a\x99\x99\x99\x99\x99\xf9\x3f\x33\x33\x33\x33\x33\x33\x0b\x40
+test binary-51.10 {Tcl_BinaryObjCmd: format} {} {
+    binary format Q2 {1.6 3.4 5.6}
+} \x3f\xf9\x99\x99\x99\x99\x99\x9a\x40\x0b\x33\x33\x33\x33\x33\x33
+test binary-51.11 {Tcl_BinaryObjCmd: format} {} {
+    binary format q2 {1.6 3.4 5.6}
+} \x9a\x99\x99\x99\x99\x99\xf9\x3f\x33\x33\x33\x33\x33\x33\x0b\x40
+test binary-51.14 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+    binary format q2 {1.6}
+} -result {number of elements in list does not match count}
+test binary-51.15 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+    set a {1.6 3.4}
+    binary format q $a
+} -result "expected floating-point number but got \"1.6 3.4\""
+test binary-51.16 {Tcl_BinaryObjCmd: format} {} {
+    set a {1.6 3.4}
+    binary format Q1 $a
+} \x3f\xf9\x99\x99\x99\x99\x99\x9a
+test binary-51.17 {Tcl_BinaryObjCmd: format} {} {
+    set a {1.6 3.4}
+    binary format q1 $a
+} \x9a\x99\x99\x99\x99\x99\xf9\x3f
+
+# format R/r
+test binary-53.1 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+    binary format r
+} -result {not enough arguments for all format specifiers}
+test binary-53.2 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+    binary format r blat
+} -result {expected floating-point number but got "blat"}
+test binary-53.3 {Tcl_BinaryObjCmd: format} {
+    binary format f0 1.6
+} {}
+test binary-53.4 {Tcl_BinaryObjCmd: format} {} {
+    binary format R 1.6
+} \x3f\xcc\xcc\xcd
+test binary-53.5 {Tcl_BinaryObjCmd: format} {} {
+    binary format r 1.6
+} \xcd\xcc\xcc\x3f
+test binary-53.6 {Tcl_BinaryObjCmd: format} {} {
+    binary format R* {1.6 3.4}
+} \x3f\xcc\xcc\xcd\x40\x59\x99\x9a
+test binary-53.7 {Tcl_BinaryObjCmd: format} {} {
+    binary format r* {1.6 3.4}
+} \xcd\xcc\xcc\x3f\x9a\x99\x59\x40
+test binary-53.8 {Tcl_BinaryObjCmd: format} {} {
+    binary format R2 {1.6 3.4}
+} \x3f\xcc\xcc\xcd\x40\x59\x99\x9a
+test binary-53.9 {Tcl_BinaryObjCmd: format} {} {
+    binary format r2 {1.6 3.4}
+} \xcd\xcc\xcc\x3f\x9a\x99\x59\x40
+test binary-53.10 {Tcl_BinaryObjCmd: format} {} {
+    binary format R2 {1.6 3.4 5.6}
+} \x3f\xcc\xcc\xcd\x40\x59\x99\x9a
+test binary-53.11 {Tcl_BinaryObjCmd: format} {} {
+    binary format r2 {1.6 3.4 5.6}
+} \xcd\xcc\xcc\x3f\x9a\x99\x59\x40
+test binary-53.12 {Tcl_BinaryObjCmd: float overflow} {} {
+    binary format R -3.402825e+38
+} \xff\x7f\xff\xff
+test binary-53.13 {Tcl_BinaryObjCmd: float overflow} {} {
+    binary format r -3.402825e+38
+} \xff\xff\x7f\xff
+test binary-53.14 {Tcl_BinaryObjCmd: float underflow} {} {
+    binary format R -3.402825e-100
+} \x80\x00\x00\x00
+test binary-53.15 {Tcl_BinaryObjCmd: float underflow} {} {
+    binary format r -3.402825e-100
+} \x00\x00\x00\x80
+test binary-53.16 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+    binary format r2 {1.6}
+} -result {number of elements in list does not match count}
+test binary-53.17 {Tcl_BinaryObjCmd: format} -returnCodes error -body {
+    set a {1.6 3.4}
+    binary format r $a
+} -result "expected floating-point number but got \"1.6 3.4\""
+test binary-53.18 {Tcl_BinaryObjCmd: format} {} {
+    set a {1.6 3.4}
+    binary format R1 $a
+} \x3f\xcc\xcc\xcd
+test binary-53.19 {Tcl_BinaryObjCmd: format} {} {
+    set a {1.6 3.4}
+    binary format r1 $a
+} \xcd\xcc\xcc\x3f
+
+# scan t (s)
+test binary-54.1 {Tcl_BinaryObjCmd: scan} -returnCodes error -body {
+    binary scan abc t
+} -result {not enough arguments for all format specifiers}
+test binary-54.2 {Tcl_BinaryObjCmd: scan} littleEndian {
+    unset -nocomplain arg1
+    list [binary scan \x52\xa3\x53\x54 t* arg1] $arg1
+} {1 {-23726 21587}}
+test binary-54.3 {Tcl_BinaryObjCmd: scan} littleEndian {
+    unset -nocomplain arg1
+    list [binary scan \x52\xa3\x53\x54 t arg1] $arg1
+} {1 -23726}
+test binary-54.4 {Tcl_BinaryObjCmd: scan} littleEndian {
+    unset -nocomplain arg1
+    list [binary scan \x52\xa3 t1 arg1] $arg1
+} {1 -23726}
+test binary-54.5 {Tcl_BinaryObjCmd: scan} littleEndian {
+    unset -nocomplain arg1
+    list [binary scan \x52\xa3 t0 arg1] $arg1
+} {1 {}}
+test binary-54.6 {Tcl_BinaryObjCmd: scan} littleEndian {
+    unset -nocomplain arg1
+    list [binary scan \x52\xa3\x53\x54 t2 arg1] $arg1
+} {1 {-23726 21587}}
+test binary-54.7 {Tcl_BinaryObjCmd: scan} littleEndian {
+    unset -nocomplain arg1
+    set arg1 foo
+    list [binary scan \x52 t1 arg1] $arg1
+} {0 foo}
+test binary-54.8 {Tcl_BinaryObjCmd: scan} -setup {
+    unset -nocomplain arg1
+} -returnCodes error -body {
+    set arg1 1
+    binary scan \x52\x53 t1 arg1(a)
+} -result {can't set "arg1(a)": variable isn't array}
+test binary-54.9 {Tcl_BinaryObjCmd: scan} littleEndian {
+    unset -nocomplain arg1 arg2
+    set arg1 foo
+    set arg2 bar
+    list [binary scan \x52\xa3\x53\x54\x05 t2c* arg1 arg2] $arg1 $arg2
+} {2 {-23726 21587} 5}
+test binary-54.10 {Tcl_BinaryObjCmd: scan} littleEndian {
+    unset -nocomplain arg1 arg2
+    set arg1 foo
+    set arg2 bar
+    list [binary scan \x00\x80\x00\x80 tut arg1 arg2] $arg1 $arg2
+} {2 32768 -32768}
+test binary-54.11 {Tcl_BinaryObjCmd: scan} littleEndian {
+    unset -nocomplain arg1 arg2
+    set arg1 foo
+    set arg2 bar
+    list [binary scan \x00\x80\x00\x80 ttu arg1 arg2] $arg1 $arg2
+} {2 -32768 32768}
+
+# scan t (b)
+test binary-55.1 {Tcl_BinaryObjCmd: scan} -returnCodes error -body {
+    binary scan abc t
+} -result {not enough arguments for all format specifiers}
+test binary-55.2 {Tcl_BinaryObjCmd: scan} bigEndian {
+    unset -nocomplain arg1
+    list [binary scan \x52\xa3\x53\x54 t* arg1] $arg1
+} {1 {21155 21332}}
+test binary-55.3 {Tcl_BinaryObjCmd: scan} bigEndian {
+    unset -nocomplain arg1
+    list [binary scan \x52\xa3\x53\x54 t arg1] $arg1
+} {1 21155}
+test binary-55.4 {Tcl_BinaryObjCmd: scan} bigEndian {
+    unset -nocomplain arg1
+    list [binary scan \x52\xa3 t1 arg1] $arg1
+} {1 21155}
+test binary-55.5 {Tcl_BinaryObjCmd: scan} bigEndian {
+    unset -nocomplain arg1
+    list [binary scan \x52\xa3 t0 arg1] $arg1
+} {1 {}}
+test binary-55.6 {Tcl_BinaryObjCmd: scan} bigEndian {
+    unset -nocomplain arg1
+    list [binary scan \x52\xa3\x53\x54 t2 arg1] $arg1
+} {1 {21155 21332}}
+test binary-55.7 {Tcl_BinaryObjCmd: scan} bigEndian {
+    unset -nocomplain arg1
+    set arg1 foo
+    list [binary scan \x52 t1 arg1] $arg1
+} {0 foo}
+test binary-55.8 {Tcl_BinaryObjCmd: scan} -setup {
+    unset -nocomplain arg1
+} -returnCodes error -body {
+    set arg1 1
+    binary scan \x52\x53 t1 arg1(a)
+} -result {can't set "arg1(a)": variable isn't array}
+test binary-55.9 {Tcl_BinaryObjCmd: scan} bigEndian {
+    unset -nocomplain arg1 arg2
+    set arg1 foo
+    set arg2 bar
+    list [binary scan \x52\xa3\x53\x54\x05 t2c* arg1 arg2] $arg1 $arg2
+} {2 {21155 21332} 5}
+test binary-55.10 {Tcl_BinaryObjCmd: scan} bigEndian {
+    unset -nocomplain arg1 arg2
+    set arg1 foo
+    set arg2 bar
+    list [binary scan \x80\x00\x80\x00 tut arg1 arg2] $arg1 $arg2
+} {2 32768 -32768}
+test binary-55.11 {Tcl_BinaryObjCmd: scan} bigEndian {
+    unset -nocomplain arg1 arg2
+    set arg1 foo
+    set arg2 bar
+    list [binary scan \x80\x00\x80\x00 ttu arg1 arg2] $arg1 $arg2
+} {2 -32768 32768}
+
+# scan n (s)
+test binary-56.1 {Tcl_BinaryObjCmd: scan} -returnCodes error -body {
+    binary scan abc n
+} -result {not enough arguments for all format specifiers}
+test binary-56.2 {Tcl_BinaryObjCmd: scan} littleEndian {
+    unset -nocomplain arg1
+    list [binary scan \x52\xa3\x53\x54\x01\x02\x03\x04 n* arg1] $arg1
+} {1 {1414767442 67305985}}
+test binary-56.3 {Tcl_BinaryObjCmd: scan} littleEndian {
+    unset -nocomplain arg1
+    list [binary scan \x52\xa3\x53\x54\x01\x02\x03\x04 n arg1] $arg1
+} {1 1414767442}
+test binary-56.4 {Tcl_BinaryObjCmd: scan} littleEndian {
+    unset -nocomplain arg1
+    list [binary scan \x52\xa3\x53\x54 n1 arg1] $arg1
+} {1 1414767442}
+test binary-56.5 {Tcl_BinaryObjCmd: scan} littleEndian {
+    unset -nocomplain arg1
+    list [binary scan \x52\xa3\x53 n0 arg1] $arg1
+} {1 {}}
+test binary-56.6 {Tcl_BinaryObjCmd: scan} littleEndian {
+    unset -nocomplain arg1
+    list [binary scan \x52\xa3\x53\x54\x01\x02\x03\x04 n2 arg1] $arg1
+} {1 {1414767442 67305985}}
+test binary-56.7 {Tcl_BinaryObjCmd: scan} littleEndian {
+    unset -nocomplain arg1
+    set arg1 foo
+    list [binary scan \x52 n1 arg1] $arg1
+} {0 foo}
+test binary-56.8 {Tcl_BinaryObjCmd: scan} -setup {
+    unset -nocomplain arg1
+} -returnCodes error -body {
+    set arg1 1
+    binary scan \x52\x53\x53\x54 n1 arg1(a)
+} -result {can't set "arg1(a)": variable isn't array}
+test binary-56.9 {Tcl_BinaryObjCmd: scan} littleEndian {
+    unset -nocomplain arg1 arg2
+    set arg1 foo
+    set arg2 bar
+    list [binary scan \x52\xa3\x53\x54\x01\x02\x03\x04\x05 n2c* arg1 arg2] $arg1 $arg2
+} {2 {1414767442 67305985} 5}
+test binary-56.10 {Tcl_BinaryObjCmd: scan} littleEndian {
+    unset -nocomplain arg1 arg2
+    set arg1 foo
+    set arg2 bar
+    list [binary scan \x80\x00\x00\x00\x80\x00\x00\x00 nun arg1 arg2] $arg1 $arg2
+} {2 128 128}
+test binary-56.11 {Tcl_BinaryObjCmd: scan} littleEndian {
+    unset -nocomplain arg1 arg2
+    set arg1 foo
+    set arg2 bar
+    list [binary scan \x00\x00\x00\x80\x00\x00\x00\x80 nun arg1 arg2] $arg1 $arg2
+} {2 2147483648 -2147483648}
+
+# scan n (b)
+test binary-57.1 {Tcl_BinaryObjCmd: scan} -returnCodes error -body {
+    binary scan abc n
+} -result {not enough arguments for all format specifiers}
+test binary-57.2 {Tcl_BinaryObjCmd: scan} bigEndian {
+    unset -nocomplain arg1
+    list [binary scan \x52\xa3\x53\x54\x01\x02\x03\x04 n* arg1] $arg1
+} {1 {1386435412 16909060}}
+test binary-57.3 {Tcl_BinaryObjCmd: scan} bigEndian {
+    unset -nocomplain arg1
+    list [binary scan \x52\xa3\x53\x54\x01\x02\x03\x04 n arg1] $arg1
+} {1 1386435412}
+test binary-57.4 {Tcl_BinaryObjCmd: scan} bigEndian {
+    unset -nocomplain arg1
+    list [binary scan \x52\xa3\x53\x54 n1 arg1] $arg1
+} {1 1386435412}
+test binary-57.5 {Tcl_BinaryObjCmd: scan} bigEndian {
+    unset -nocomplain arg1
+    list [binary scan \x52\xa3\x53 n0 arg1] $arg1
+} {1 {}}
+test binary-57.6 {Tcl_BinaryObjCmd: scan} bigEndian {
+    unset -nocomplain arg1
+    list [binary scan \x52\xa3\x53\x54\x01\x02\x03\x04 n2 arg1] $arg1
+} {1 {1386435412 16909060}}
+test binary-57.7 {Tcl_BinaryObjCmd: scan} bigEndian {
+    unset -nocomplain arg1
+    set arg1 foo
+    list [binary scan \x52 n1 arg1] $arg1
+} {0 foo}
+test binary-57.8 {Tcl_BinaryObjCmd: scan} -setup {
+    unset -nocomplain arg1
+} -returnCodes error -body {
+    set arg1 1
+    binary scan \x52\x53\x53\x54 n1 arg1(a)
+} -result {can't set "arg1(a)": variable isn't array}
+test binary-57.9 {Tcl_BinaryObjCmd: scan} bigEndian {
+    unset -nocomplain arg1 arg2
+    set arg1 foo
+    set arg2 bar
+    list [binary scan \x52\xa3\x53\x54\x01\x02\x03\x04\x05 n2c* arg1 arg2] $arg1 $arg2
+} {2 {1386435412 16909060} 5}
+test binary-57.10 {Tcl_BinaryObjCmd: scan} bigEndian {
+    unset -nocomplain arg1 arg2
+    set arg1 foo
+    set arg2 bar
+    list [binary scan \x80\x00\x00\x00\x80\x00\x00\x00 nun arg1 arg2] $arg1 $arg2
+} {2 2147483648 -2147483648}
+test binary-57.11 {Tcl_BinaryObjCmd: scan} bigEndian {
+    unset -nocomplain arg1 arg2
+    set arg1 foo
+    set arg2 bar
+    list [binary scan \x00\x00\x00\x80\x00\x00\x00\x80 nun arg1 arg2] $arg1 $arg2
+} {2 128 128}
+
+# scan Q/q
+test binary-58.1 {Tcl_BinaryObjCmd: scan} -returnCodes error -body {
+    binary scan abc q
+} -result {not enough arguments for all format specifiers}
+test binary-58.2 {Tcl_BinaryObjCmd: scan} bigEndian {
+    unset -nocomplain arg1
+    list [binary scan \x3f\xf9\x99\x99\x99\x99\x99\x9a\x40\x0b\x33\x33\x33\x33\x33\x33 Q* arg1] $arg1
+} {1 {1.6 3.4}}
+test binary-58.3 {Tcl_BinaryObjCmd: scan} littleEndian {
+    unset -nocomplain arg1
+    list [binary scan \x9a\x99\x99\x99\x99\x99\xf9\x3f\x33\x33\x33\x33\x33\x33\x0b\x40 q* arg1] $arg1
+} {1 {1.6 3.4}}
+test binary-58.4 {Tcl_BinaryObjCmd: scan} bigEndian {
+    unset -nocomplain arg1
+    list [binary scan \x3f\xf9\x99\x99\x99\x99\x99\x9a\x40\x0b\x33\x33\x33\x33\x33\x33 Q arg1] $arg1
+} {1 1.6}
+test binary-58.5 {Tcl_BinaryObjCmd: scan} littleEndian {
+    unset -nocomplain arg1
+    list [binary scan \x9a\x99\x99\x99\x99\x99\xf9\x3f\x33\x33\x33\x33\x33\x33\x0b\x40 q arg1] $arg1
+} {1 1.6}
+test binary-58.6 {Tcl_BinaryObjCmd: scan} bigEndian {
+    unset -nocomplain arg1
+    list [binary scan \x3f\xf9\x99\x99\x99\x99\x99\x9a Q1 arg1] $arg1
+} {1 1.6}
+test binary-58.7 {Tcl_BinaryObjCmd: scan} littleEndian {
+    unset -nocomplain arg1
+    list [binary scan \x9a\x99\x99\x99\x99\x99\xf9\x3f q1 arg1] $arg1
+} {1 1.6}
+test binary-58.8 {Tcl_BinaryObjCmd: scan} bigEndian {
+    unset -nocomplain arg1
+    list [binary scan \x3f\xf9\x99\x99\x99\x99\x99\x9a Q0 arg1] $arg1
+} {1 {}}
+test binary-58.9 {Tcl_BinaryObjCmd: scan} littleEndian {
+    unset -nocomplain arg1
+    list [binary scan \x9a\x99\x99\x99\x99\x99\xf9\x3f q0 arg1] $arg1
+} {1 {}}
+test binary-58.10 {Tcl_BinaryObjCmd: scan} bigEndian {
+    unset -nocomplain arg1
+    list [binary scan \x3f\xf9\x99\x99\x99\x99\x99\x9a\x40\x0b\x33\x33\x33\x33\x33\x33 Q2 arg1] $arg1
+} {1 {1.6 3.4}}
+test binary-58.11 {Tcl_BinaryObjCmd: scan} littleEndian {
+    unset -nocomplain arg1
+    list [binary scan \x9a\x99\x99\x99\x99\x99\xf9\x3f\x33\x33\x33\x33\x33\x33\x0b\x40 q2 arg1] $arg1
+} {1 {1.6 3.4}}
+test binary-58.12 {Tcl_BinaryObjCmd: scan} {
+    unset -nocomplain arg1
+    set arg1 foo
+    list [binary scan \x52 q1 arg1] $arg1
+} {0 foo}
+test binary-58.13 {Tcl_BinaryObjCmd: scan} -setup {
+    unset -nocomplain arg1
+} -returnCodes error -body {
+    set arg1 1
+    binary scan \x3f\xf9\x99\x99\x99\x99\x99\x9a q1 arg1(a)
+} -result {can't set "arg1(a)": variable isn't array}
+test binary-58.14 {Tcl_BinaryObjCmd: scan} bigEndian {
+    unset -nocomplain arg1 arg2
+    set arg1 foo
+    set arg2 bar
+    list [binary scan \x3f\xf9\x99\x99\x99\x99\x99\x9a\x40\x0b\x33\x33\x33\x33\x33\x33\x05 Q2c* arg1 arg2] $arg1 $arg2
+} {2 {1.6 3.4} 5}
+test binary-58.15 {Tcl_BinaryObjCmd: scan} littleEndian {
+    unset -nocomplain arg1 arg2
+    set arg1 foo
+    set arg2 bar
+    list [binary scan \x9a\x99\x99\x99\x99\x99\xf9\x3f\x33\x33\x33\x33\x33\x33\x0b\x40\x05 q2c* arg1 arg2] $arg1 $arg2
+} {2 {1.6 3.4} 5}
+
+# scan R/r
+test binary-59.1 {Tcl_BinaryObjCmd: scan} -returnCodes error -body {
+    binary scan abc r
+} -result {not enough arguments for all format specifiers}
+test binary-59.2 {Tcl_BinaryObjCmd: scan} bigEndian {
+    unset -nocomplain arg1
+    list [binary scan \x3f\xcc\xcc\xcd\x40\x59\x99\x9a R* arg1] $arg1
+} {1 {1.600000023841858 3.4000000953674316}}
+test binary-59.3 {Tcl_BinaryObjCmd: scan} littleEndian {
+    unset -nocomplain arg1
+    list [binary scan \xcd\xcc\xcc\x3f\x9a\x99\x59\x40 r* arg1] $arg1
+} {1 {1.600000023841858 3.4000000953674316}}
+test binary-59.4 {Tcl_BinaryObjCmd: scan} bigEndian {
+    unset -nocomplain arg1
+    list [binary scan \x3f\xcc\xcc\xcd\x40\x59\x99\x9a R arg1] $arg1
+} {1 1.600000023841858}
+test binary-59.5 {Tcl_BinaryObjCmd: scan} littleEndian {
+    unset -nocomplain arg1
+    list [binary scan \xcd\xcc\xcc\x3f\x9a\x99\x59\x40 r arg1] $arg1
+} {1 1.600000023841858}
+test binary-59.6 {Tcl_BinaryObjCmd: scan} bigEndian {
+    unset -nocomplain arg1
+    list [binary scan \x3f\xcc\xcc\xcd R1 arg1] $arg1
+} {1 1.600000023841858}
+test binary-59.7 {Tcl_BinaryObjCmd: scan} littleEndian {
+    unset -nocomplain arg1
+    list [binary scan \xcd\xcc\xcc\x3f r1 arg1] $arg1
+} {1 1.600000023841858}
+test binary-59.8 {Tcl_BinaryObjCmd: scan} bigEndian {
+    unset -nocomplain arg1
+    list [binary scan \x3f\xcc\xcc\xcd R0 arg1] $arg1
+} {1 {}}
+test binary-59.9 {Tcl_BinaryObjCmd: scan} littleEndian {
+    unset -nocomplain arg1
+    list [binary scan \xcd\xcc\xcc\x3f r0 arg1] $arg1
+} {1 {}}
+test binary-59.10 {Tcl_BinaryObjCmd: scan} bigEndian {
+    unset -nocomplain arg1
+    list [binary scan \x3f\xcc\xcc\xcd\x40\x59\x99\x9a R2 arg1] $arg1
+} {1 {1.600000023841858 3.4000000953674316}}
+test binary-59.11 {Tcl_BinaryObjCmd: scan} littleEndian {
+    unset -nocomplain arg1
+    list [binary scan \xcd\xcc\xcc\x3f\x9a\x99\x59\x40 r2 arg1] $arg1
+} {1 {1.600000023841858 3.4000000953674316}}
+test binary-59.12 {Tcl_BinaryObjCmd: scan} {
+    unset -nocomplain arg1
+    set arg1 foo
+    list [binary scan \x52 r1 arg1] $arg1
+} {0 foo}
+test binary-59.13 {Tcl_BinaryObjCmd: scan} -setup {
+    unset -nocomplain arg1
+} -returnCodes error -body {
+    set arg1 1
+    binary scan \x3f\xcc\xcc\xcd r1 arg1(a)
+} -result {can't set "arg1(a)": variable isn't array}
+test binary-59.14 {Tcl_BinaryObjCmd: scan} bigEndian {
+    unset -nocomplain arg1 arg2
+    set arg1 foo
+    set arg2 bar
+    list [binary scan \x3f\xcc\xcc\xcd\x40\x59\x99\x9a\x05 R2c* arg1 arg2] $arg1 $arg2
+} {2 {1.600000023841858 3.4000000953674316} 5}
+test binary-59.15 {Tcl_BinaryObjCmd: scan} littleEndian {
+    unset -nocomplain arg1 arg2
+    set arg1 foo
+    set arg2 bar
+    list [binary scan \xcd\xcc\xcc\x3f\x9a\x99\x59\x40\x05 r2c* arg1 arg2] $arg1 $arg2
+} {2 {1.600000023841858 3.4000000953674316} 5}
+
+test binary-60.1 {[binary format] with NaN} -body {
+    binary scan [binary format dqQfrR NaN NaN NaN NaN NaN NaN] dqQfrR \
+	v1 v2 v3 v4 v5 v6
+    list $v1 $v2 $v3 $v4 $v5 $v6
+} -match regexp -result {NaN(\([[:xdigit:]]+\))? NaN(\([[:xdigit:]]+\))? NaN(\([[:xdigit:]]+\))? NaN(\([[:xdigit:]]+\))? NaN(\([[:xdigit:]]+\))? NaN(\([[:xdigit:]]+\))?}
+
+# scan m
+test binary-61.1 {Tcl_BinaryObjCmd: scan wide int} bigEndian {
+    binary scan HelloTcl m x
+    set x
+} 5216694956358656876
+test binary-61.2 {Tcl_BinaryObjCmd: scan wide int} littleEndian {
+    binary scan lcTolleH m x
+    set x
+} 5216694956358656876
+test binary-61.3 {Tcl_BinaryObjCmd: scan wide int with bit 31 set} littleEndian {
+    binary scan [binary format w [expr {wide(3) << 31}]] m x
+    set x
+} 6442450944
+test binary-61.4 {Tcl_BinaryObjCmd: scan wide int with bit 31 set} bigEndian {
+    binary scan [binary format W [expr {wide(3) << 31}]] m x
+    set x
+} 6442450944
+
+# scan/format infinities
+
+test binary-62.1 {infinity} ieeeFloatingPoint {
+    binary scan [binary format q Infinity] w w
+    format 0x%016lx $w
+} 0x7ff0000000000000
+test binary-62.2 {infinity} ieeeFloatingPoint {
+    binary scan [binary format q -Infinity] w w
+    format 0x%016lx $w
+} 0xfff0000000000000
+test binary-62.3 {infinity} ieeeFloatingPoint {
+    binary scan [binary format q Inf] w w
+    format 0x%016lx $w
+} 0x7ff0000000000000
+test binary-62.4 {infinity} ieeeFloatingPoint {
+    binary scan [binary format q -Infinity] w w
+    format 0x%016lx $w
+} 0xfff0000000000000
+test binary-62.5 {infinity} ieeeFloatingPoint {
+    binary scan [binary format w 0x7ff0000000000000] q d
+    set d
+} Inf
+test binary-62.6 {infinity} ieeeFloatingPoint {
+    binary scan [binary format w 0xfff0000000000000] q d
+    set d
+} -Inf
+
+# scan/format Not-a-Number
+
+test binary-63.1 {NaN} ieeeFloatingPoint {
+    binary scan [binary format q NaN] w w
+    format 0x%016lx [expr {$w & 0xfff3ffffffffffff}]
+} 0x7ff0000000000000
+test binary-63.2 {NaN} ieeeFloatingPoint {
+    binary scan [binary format q -NaN] w w
+    format 0x%016lx [expr {$w & 0xfff3ffffffffffff}]
+} 0xfff0000000000000
+test binary-63.3 {NaN} ieeeFloatingPoint {
+    binary scan [binary format q NaN(3123456789aBc)] w w
+    format 0x%016lx [expr {$w & 0xfff3ffffffffffff}]
+} 0x7ff3123456789abc
+test binary-63.4 {NaN} ieeeFloatingPoint {
+    binary scan [binary format q {NaN( 3123456789aBc)}] w w
+    format 0x%016lx [expr {$w & 0xfff3ffffffffffff}]
+} 0x7ff3123456789abc
+
+# Make sure TclParseNumber() rejects invalid nan-hex formats [Bug 3402540]
+test binary-63.5 {NaN} -constraints ieeeFloatingPoint -body {
+    binary format q Nan(
+} -returnCodes error -match glob -result {expected floating-point number*}
+test binary-63.6 {NaN} -constraints ieeeFloatingPoint -body {
+    binary format q Nan()
+} -returnCodes error -match glob -result {expected floating-point number*}
+test binary-63.7 {NaN} -constraints ieeeFloatingPoint -body {
+    binary format q Nan(g)
+} -returnCodes error -match glob -result {expected floating-point number*}
+test binary-63.8 {NaN} -constraints ieeeFloatingPoint -body {
+    binary format q Nan(1,2)
+} -returnCodes error -match glob -result {expected floating-point number*}
+test binary-63.9 {NaN} -constraints ieeeFloatingPoint -body {
+    binary format q Nan(1234567890abcd)
+} -returnCodes error -match glob -result {expected floating-point number*}
+
+test binary-64.1 {NaN} -constraints ieeeFloatingPoint -body {
+    binary scan [binary format w 0x7ff8000000000000] q d
+    set d
+} -match glob -result NaN*
+test binary-64.2 {NaN} -constraints ieeeFloatingPoint -body {
+    binary scan [binary format w 0x7ff0123456789aBc] q d
+    set d
+} -match glob -result NaN(*123456789abc)
+
+test binary-65.1 {largest significand} ieeeFloatingPoint {
+    binary scan [binary format w 0x3fcfffffffffffff] q d
+    set d
+} 0.24999999999999997
+test binary-65.2 {smallest significand} ieeeFloatingPoint {
+    binary scan [binary format w 0x3fd0000000000000] q d
+    set d
+} 0.25
+test binary-65.3 {largest significand} ieeeFloatingPoint {
+    binary scan [binary format w 0x3fdfffffffffffff] q d
+    set d
+} 0.49999999999999994
+test binary-65.4 {smallest significand} ieeeFloatingPoint {
+    binary scan [binary format w 0x3fe0000000000000] q d
+    set d
+} 0.5
+test binary-65.5 {largest significand} ieeeFloatingPoint {
+    binary scan [binary format w 0x3fffffffffffffff] q d
+    set d
+} 1.9999999999999998
+test binary-65.6 {smallest significand} ieeeFloatingPoint {
+    binary scan [binary format w 0x4000000000000000] q d
+    set d
+} 2.0
+test binary-65.7 {smallest significand} ieeeFloatingPoint {
+    binary scan [binary format w 0x434fffffffffffff] q d
+    set d
+} 18014398509481982.0
+test binary-65.8 {largest significand} ieeeFloatingPoint {
+    binary scan [binary format w 0x4350000000000000] q d
+    set d
+} 18014398509481984.0
+test binary-65.9 {largest significand} ieeeFloatingPoint {
+    binary scan [binary format w 0x4350000000000001] q d
+    set d
+} 18014398509481988.0
+
+test binary-70.1 {binary encode hex} -body {
+    binary encode hex
+} -returnCodes error -match glob -result "wrong # args: *"
+test binary-70.2 {binary encode hex} -body {
+    binary encode hex a
+} -result {61}
+test binary-70.3 {binary encode hex} -body {
+    binary encode hex {}
+} -result {}
+test binary-70.4 {binary encode hex} -body {
+    binary encode hex [string repeat a 20]
+} -result [string repeat 61 20]
+test binary-70.5 {binary encode hex} -body {
+    binary encode hex \0\1\2\3\4\0\1\2\3\4
+} -result {00010203040001020304}
+
+test binary-71.1 {binary decode hex} -body {
+    binary decode hex
+} -returnCodes error -match glob -result "wrong # args: *"
+test binary-71.2 {binary decode hex} -body {
+    binary decode hex 61
+} -result {a}
+test binary-71.3 {binary decode hex} -body {
+    binary decode hex {}
+} -result {}
+test binary-71.4 {binary decode hex} -body {
+    binary decode hex [string repeat 61 20]
+} -result [string repeat a 20]
+test binary-71.5 {binary decode hex} -body {
+    binary decode hex 00010203040001020304
+} -result "\0\1\2\3\4\0\1\2\3\4"
+test binary-71.6 {binary decode hex} -body {
+    binary decode hex "61 61"
+} -result {aa}
+test binary-71.7 {binary decode hex} -body {
+    binary decode hex "61\n\n\n61"
+} -result {aa}
+test binary-71.8 {binary decode hex} -body {
+    binary decode hex -strict "61 61"
+} -returnCodes error -result {invalid hexadecimal digit " " at position 2}
+test binary-71.9 {binary decode hex} -body {
+    set r [binary decode hex "6"]
+    list [string length $r] $r
+} -result {0 {}}
+test binary-71.10 {binary decode hex} -body {
+    string length [binary decode hex " "]
+} -result 0
+test binary-71.11 {binary decode hex: Bug b98fa55285} -body {
+    apply {{} {
+	set str "137b6f95e7519389e7c4b36599781e2ccf492699649249aae43fbe8c26\n"
+	set decoded [binary decode hex $str]
+	list [string length $decoded] [scan [string index $decoded end] %c]
+    }}
+} -result {29 38}
+test binary-71.12 {binary decode hex: Bug b98fa55285 cross check} -body {
+    apply {{} {
+	set str "137b6f95e7519389e7c4b36599781e2ccf492699649249aae43fbe8c2\n"
+	set decoded [binary decode hex $str]
+	list [string length $decoded] [scan [string index $decoded end] %c]
+    }}
+} -result {28 140}
+test binary-71.13 {binary decode hex: Bug b98fa55285 cross check} -body {
+    apply {{} {
+	set str "137b6f95e7519389e7c4b36599781e2ccf492699649249aae43fbe8c2\n\n"
+	set decoded [binary decode hex $str]
+	list [string length $decoded] [scan [string index $decoded end] %c]
+    }}
+} -result {28 140}
+test binary-71.14 {binary decode hex: Bug b98fa55285 cross check} -body {
+    apply {{} {
+	set str "137b6f95e7519389e7c4b36599781e2ccf492699649249aae43fbe8c2\n\n\n"
+	set decoded [binary decode hex $str]
+	list [string length $decoded] [scan [string index $decoded end] %c]
+    }}
+} -result {28 140}
+
+test binary-72.1 {binary encode base64} -body {
+    binary encode base64
+} -returnCodes error -match glob -result "wrong # args: *"
+test binary-72.2 {binary encode base64} -body {
+    binary encode base64 abc
+} -result {YWJj}
+test binary-72.3 {binary encode base64} -body {
+    binary encode base64 {}
+} -result {}
+test binary-72.4 {binary encode base64} -body {
+    binary encode base64 [string repeat abc 20]
+} -result [string repeat YWJj 20]
+test binary-72.5 {binary encode base64} -body {
+    binary encode base64 \0\1\2\3\4\0\1\2\3
+} -result {AAECAwQAAQID}
+test binary-72.6 {binary encode base64} -body {
+    binary encode base64 \0
+} -result {AA==}
+test binary-72.7 {binary encode base64} -body {
+    binary encode base64 \0\0
+} -result {AAA=}
+test binary-72.8 {binary encode base64} -body {
+    binary encode base64 \0\0\0
+} -result {AAAA}
+test binary-72.9 {binary encode base64} -body {
+    binary encode base64 \0\0\0\0
+} -result {AAAAAA==}
+test binary-72.10 {binary encode base64} -body {
+    binary encode base64 -maxlen 0 -wrapchar : abcabcabc
+} -result {YWJjYWJjYWJj}
+test binary-72.11 {binary encode base64} -body {
+    binary encode base64 -maxlen 1 -wrapchar : abcabcabc
+} -result {Y:W:J:j:Y:W:J:j:Y:W:J:j}
+test binary-72.12 {binary encode base64} -body {
+    binary encode base64 -maxlen 2 -wrapchar : abcabcabc
+} -result {YW:Jj:YW:Jj:YW:Jj}
+test binary-72.13 {binary encode base64} -body {
+    binary encode base64 -maxlen 3 -wrapchar : abcabcabc
+} -result {YWJ:jYW:JjY:WJj}
+test binary-72.14 {binary encode base64} -body {
+    binary encode base64 -maxlen 4 -wrapchar : abcabcabc
+} -result {YWJj:YWJj:YWJj}
+test binary-72.15 {binary encode base64} -body {
+    binary encode base64 -maxlen 5 -wrapchar : abcabcabc
+} -result {YWJjY:WJjYW:Jj}
+test binary-72.16 {binary encode base64} -body {
+    binary encode base64 -maxlen 6 -wrapchar : abcabcabc
+} -result {YWJjYW:JjYWJj}
+test binary-72.17 {binary encode base64} -body {
+    binary encode base64 -maxlen 7 -wrapchar : abcabcabc
+} -result {YWJjYWJ:jYWJj}
+test binary-72.18 {binary encode base64} -body {
+    binary encode base64 -maxlen 8 -wrapchar : abcabcabc
+} -result {YWJjYWJj:YWJj}
+test binary-72.19 {binary encode base64} -body {
+    binary encode base64 -maxlen 9 -wrapchar : abcabcabc
+} -result {YWJjYWJjY:WJj}
+test binary-72.20 {binary encode base64} -body {
+    binary encode base64 -maxlen 10 -wrapchar : abcabcabc
+} -result {YWJjYWJjYW:Jj}
+test binary-72.21 {binary encode base64} -body {
+    binary encode base64 -maxlen 11 -wrapchar : abcabcabc
+} -result {YWJjYWJjYWJ:j}
+test binary-72.22 {binary encode base64} -body {
+    binary encode base64 -maxlen 12 -wrapchar : abcabcabc
+} -result {YWJjYWJjYWJj}
+test binary-72.23 {binary encode base64} -body {
+    binary encode base64 -maxlen 13 -wrapchar : abcabcabc
+} -result {YWJjYWJjYWJj}
+test binary-72.24 {binary encode base64} -body {
+    binary encode base64 -maxlen 60 -wrapchar : abcabcabc
+} -result {YWJjYWJjYWJj}
+test binary-72.25 {binary encode base64} -body {
+    binary encode base64 -maxlen 2 -wrapchar * abcabcabc
+} -result {YW*Jj*YW*Jj*YW*Jj}
+test binary-72.26 {binary encode base64} -body {
+    binary encode base64 -maxlen 6 -wrapchar -*- abcabcabc
+} -result {YWJjYW-*-JjYWJj}
+test binary-72.27 {binary encode base64} -body {
+    binary encode base64 -maxlen 4 -wrapchar -*- abcabcabc
+} -result {YWJj-*-YWJj-*-YWJj}
+test binary-72.28 {binary encode base64} -body {
+    binary encode base64 -maxlen 6 -wrapchar 0123456789 abcabcabc
+} -result {YWJjYW0123456789JjYWJj}
+
+test binary-73.1 {binary decode base64} -body {
+    binary decode base64
+} -returnCodes error -match glob -result "wrong # args: *"
+test binary-73.2 {binary decode base64} -body {
+    binary decode base64 YWJj
+} -result {abc}
+test binary-73.3 {binary decode base64} -body {
+    binary decode base64 {}
+} -result {}
+test binary-73.4 {binary decode base64} -body {
+    binary decode base64 [string repeat YWJj 20]
+} -result [string repeat abc 20]
+test binary-73.5 {binary encode base64} -body {
+    binary decode base64 AAECAwQAAQID
+} -result "\0\1\2\3\4\0\1\2\3"
+test binary-73.6 {binary encode base64} -body {
+    binary decode base64 AA==
+} -result "\0"
+test binary-73.7 {binary encode base64} -body {
+    binary decode base64 AAA=
+} -result "\0\0"
+test binary-73.8 {binary encode base64} -body {
+    binary decode base64 AAAA
+} -result "\0\0\0"
+test binary-73.9 {binary encode base64} -body {
+    binary decode base64 AAAAAA==
+} -result "\0\0\0\0"
+test binary-73.10 {binary decode base64} -body {
+    set s "[string repeat YWJj 10]\n[string repeat YWJj 10]"
+    binary decode base64 $s
+} -result [string repeat abc 20]
+test binary-73.11 {binary decode base64} -body {
+    set s "[string repeat YWJj 10]\n    [string repeat YWJj 10]"
+    binary decode base64 $s
+} -result [string repeat abc 20]
+test binary-73.12 {binary decode base64} -body {
+    binary decode base64 -strict ":YWJj"
+} -returnCodes error -match glob -result {invalid base64 character ":" at position 0}
+test binary-73.13 {binary decode base64} -body {
+    set s "[string repeat YWJj 10]:[string repeat YWJj 10]"
+    binary decode base64 -strict $s
+} -returnCodes error -match glob -result {invalid base64 character ":" at position 40}
+test binary-73.14 {binary decode base64} -body {
+    set s "[string repeat YWJj 10]\n    [string repeat YWJj 10]"
+    binary decode base64 -strict $s
+} -returnCodes error -match glob -result {invalid base64 character *}
+test binary-73.20 {binary decode base64} -body {
+    set r [binary decode base64 Y]
+    list [string length $r] $r
+} -result {0 {}}
+test binary-73.21 {binary decode base64} -body {
+    set r [binary decode base64 YW]
+    list [string length $r] $r
+} -result {1 a}
+test binary-73.22 {binary decode base64} -body {
+    set r [binary decode base64 YWJ]
+    list [string length $r] $r
+} -result {2 ab}
+test binary-73.23 {binary decode base64} -body {
+    set r [binary decode base64 YWJj]
+    list [string length $r] $r
+} -result {3 abc}
+test binary-73.24 {binary decode base64} -body {
+    string length [binary decode base64 " "]
+} -result 0
+test binary-73.25 {binary decode base64} -body {
+    list [string length [set r [binary decode base64 WA==\n]]] $r
+} -result {1 X}
+test binary-73.26 {binary decode base64} -body {
+    list [string length [set r [binary decode base64 WFk=\n]]] $r
+} -result {2 XY}
+test binary-73.27 {binary decode base64} -body {
+    list [string length [set r [binary decode base64 WFla\n]]] $r
+} -result {3 XYZ}
+test binary-73.28 {binary decode base64} -body {
+    list [string length [set r [binary decode base64 -strict WA==\n]]] $r
+} -returnCodes error -match glob -result {invalid base64 character *}
+test binary-73.29 {binary decode base64} -body {
+    list [string length [set r [binary decode base64 -strict WFk=\n]]] $r
+} -returnCodes error -match glob -result {invalid base64 character *}
+test binary-73.30 {binary decode base64} -body {
+    list [string length [set r [binary decode base64 -strict WFla\n]]] $r
+} -returnCodes error -match glob -result {invalid base64 character *}
+test binary-73.31 {binary decode base64} -body {
+    list [string length [set r [binary decode base64 WA==WFla]]] $r
+} -returnCodes error -match glob -result {invalid base64 character *}
+
+test binary-74.1 {binary encode uuencode} -body {
+    binary encode uuencode
+} -returnCodes error -match glob -result "wrong # args: *"
+test binary-74.2 {binary encode uuencode} -body {
+    binary encode uuencode abc
+} -result {#86)C
+}
+test binary-74.3 {binary encode uuencode} -body {
+    binary encode uuencode {}
+} -result {}
+test binary-74.4 {binary encode uuencode} -body {
+    binary encode uuencode [string repeat abc 20]
+} -result "M[string repeat 86)C 15]\n/[string repeat 86)C 5]\n"
+test binary-74.5 {binary encode uuencode} -body {
+    binary encode uuencode \0\1\2\3\4\0\1\2\3
+} -result ")``\$\"`P0``0(#\n"
+test binary-74.6 {binary encode uuencode} -body {
+    binary encode uuencode \0
+} -result {!``
+}
+test binary-74.7 {binary encode uuencode} -body {
+    binary encode uuencode \0\0
+} -result "\"```
+"
+test binary-74.8 {binary encode uuencode} -body {
+    binary encode uuencode \0\0\0
+} -result {#````
+}
+test binary-74.9 {binary encode uuencode} -body {
+    binary encode uuencode \0\0\0\0
+} -result {$``````
+}
+test binary-74.10 {binary encode uuencode} -returnCodes error -body {
+    binary encode uuencode -foo 30 abcabcabc
+} -result {bad option "-foo": must be -maxlen or -wrapchar}
+test binary-74.11 {binary encode uuencode} -returnCodes error -body {
+    binary encode uuencode -maxlen 1 abcabcabc
+} -result {line length out of range}
+test binary-74.12 {binary encode uuencode} -body {
+    binary encode uuencode -maxlen 3 -wrapchar | abcabcabc
+} -result {!80|!8@|!8P|!80|!8@|!8P|!80|!8@|!8P|}
+
+test binary-75.1 {binary decode uuencode} -body {
+    binary decode uuencode
+} -returnCodes error -match glob -result "wrong # args: *"
+test binary-75.2 {binary decode uuencode} -body {
+    binary decode uuencode "#86)C\n"
+} -result {abc}
+test binary-75.3 {binary decode uuencode} -body {
+    binary decode uuencode {}
+} -result {}
+test binary-75.3.1 {binary decode uuencode} -body {
+    binary decode uuencode `\n
+} -result {}
+test binary-75.4 {binary decode uuencode} -body {
+    binary decode uuencode "M[string repeat 86)C 15]\n/[string repeat 86)C 5]\n"
+} -result [string repeat abc 20]
+test binary-75.5 {binary decode uuencode} -body {
+    binary decode uuencode ")``\$\"`P0``0(#"
+} -result "\0\1\2\3\4\0\1\2\3"
+test binary-75.6 {binary decode uuencode} -body {
+    string length [binary decode uuencode "`\n"]
+} -result 0
+test binary-75.7 {binary decode uuencode} -body {
+    string length [binary decode uuencode "!`\n"]
+} -result 1
+test binary-75.8 {binary decode uuencode} -body {
+    string length [binary decode uuencode "\"``\n"]
+} -result 2
+test binary-75.9 {binary decode uuencode} -body {
+    string length [binary decode uuencode "#```\n"]
+} -result 3
+test binary-75.10 {binary decode uuencode} -body {
+    set s ">[string repeat 86)C 10]\n>[string repeat 86)C 10]"
+    binary decode uuencode $s
+} -result [string repeat abc 20]
+test binary-75.11 {binary decode uuencode} -body {
+    set s ">[string repeat 86)C 10]\n\t>\t[string repeat 86)C 10]\r"
+    binary decode uuencode $s
+} -result [string repeat abc 20]
+test binary-75.12 {binary decode uuencode} -body {
+    binary decode uuencode -strict "|86)C"
+} -returnCodes error -match glob -result {invalid uuencode character "|" at position 0}
+test binary-75.13 {binary decode uuencode} -body {
+    set s ">[string repeat 86)C 10]|[string repeat 86)C 10]"
+    binary decode uuencode -strict $s
+} -returnCodes error -match glob -result {invalid uuencode character "|" at position 41}
+test binary-75.14 {binary decode uuencode} -body {
+    set s ">[string repeat 86)C 10]\na[string repeat 86)C 10]"
+    binary decode uuencode -strict $s
+} -returnCodes error -match glob -result {invalid uuencode character *}
+test binary-75.20 {binary decode uuencode} -body {
+    set r [binary decode uuencode " 8"]
+    list [string length $r] $r
+} -result {0 {}}
+test binary-75.21 {binary decode uuencode} -body {
+    set r [binary decode uuencode "!86"]
+    list [string length $r] $r
+} -result {1 a}
+test binary-75.22 {binary decode uuencode} -body {
+    set r [binary decode uuencode "\"86)"]
+    list [string length $r] $r
+} -result {2 ab}
+test binary-75.23 {binary decode uuencode} -body {
+    set r [binary decode uuencode "#86)C"]
+    list [string length $r] $r
+} -result {3 abc}
+test binary-75.24 {binary decode uuencode} -body {
+    set s "#04)\# "
+    binary decode uuencode $s
+} -result ABC
+test binary-75.25 {binary decode uuencode} -body {
+    set s "#04)\#z"
+    binary decode uuencode $s
+} -returnCodes error -match glob -result {invalid uuencode character "z" at position 5}
+test binary-75.26 {binary decode uuencode} -body {
+    string length [binary decode uuencode " "]
+} -result 0
+
+test binary-76.1 {binary string appending growth algorithm} unix {
+    # Create zero-length byte array first
+    set f [open /dev/null rb]
+    chan configure $f -blocking 0
+    set str [read $f 2]
+    close $f
+    # Append to it
+    string length [append str [binary format a* foo]]
+} 3
+test binary-76.2 {binary string appending growth algorithm} win {
+    # Create zero-length byte array first
+    set f [open NUL rb]
+    chan configure $f -blocking 0
+    set str [read $f 2]
+    close $f
+    # Append to it
+    string length [append str [binary format a* foo]]
+} 3
+
+# ----------------------------------------------------------------------
+# cleanup
+
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/tests/case.test b/tests/case.test
new file mode 100644
index 0000000..6d63cea
--- /dev/null
+++ b/tests/case.test
@@ -0,0 +1,89 @@
+# Commands covered:  case
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands.  Sourcing this file into Tcl runs the tests and
+# generates output for errors.  No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+    package require tcltest
+    namespace import -force ::tcltest::*
+}
+
+test case-1.1 {simple pattern} {
+    case a in a {format 1} b {format 2} c {format 3} default {format 4}
+} 1
+test case-1.2 {simple pattern} {
+    case b a {format 1} b {format 2} c {format 3} default {format 4}
+} 2
+test case-1.3 {simple pattern} {
+    case x in a {format 1} b {format 2} c {format 3} default {format 4}
+} 4
+test case-1.4 {simple pattern} {
+    case x a {format 1} b {format 2} c {format 3}
+} {}
+test case-1.5 {simple pattern matches many times} {
+    case b a {format 1} b {format 2} b {format 3} b {format 4}
+} 2
+test case-1.6 {fancier pattern} {
+    case cx a {format 1} *c {format 2} *x {format 3} default {format 4}
+} 3
+test case-1.7 {list of patterns} {
+    case abc in {a b c} {format 1} {def abc ghi} {format 2}
+} 2
+
+test case-2.1 {error in executed command} {
+    list [catch {case a in a {error "Just a test"} default {format 1}} msg] \
+	    $msg $::errorInfo
+} {1 {Just a test} {Just a test
+    while executing
+"error "Just a test""
+    ("a" arm line 1)
+    invoked from within
+"case a in a {error "Just a test"} default {format 1}"}}
+test case-2.2 {error: not enough args} {
+    list [catch {case} msg] $msg
+} {1 {wrong # args: should be "case string ?in? ?pattern body ...? ?default body?"}}
+test case-2.3 {error: pattern with no body} {
+    list [catch {case a b} msg] $msg
+} {1 {extra case pattern with no body}}
+test case-2.4 {error: pattern with no body} {
+    list [catch {case a in b {format 1} c} msg] $msg
+} {1 {extra case pattern with no body}}
+test case-2.5 {error in default command} {
+    list [catch {case foo in a {error case1} default {error case2} \
+	    b {error case 3}} msg] $msg $::errorInfo
+} {1 case2 {case2
+    while executing
+"error case2"
+    ("default" arm line 1)
+    invoked from within
+"case foo in a {error case1} default {error case2}  b {error case 3}"}}
+
+test case-3.1 {single-argument form for pattern/command pairs} {
+    case b in {
+	a {format 1}
+	b {format 2}
+	default {format 6}
+    }
+} {2}
+test case-3.2 {single-argument form for pattern/command pairs} {
+    case b {
+	a {format 1}
+	b {format 2}
+	default {format 6}
+    }
+} {2}
+test case-3.3 {single-argument form for pattern/command pairs} {
+    list [catch {case z in {a 2 b}} msg] $msg
+} {1 {extra case pattern with no body}}
+
+# cleanup
+::tcltest::cleanupTests
+return
diff --git a/tests/chan.test b/tests/chan.test
new file mode 100644
index 0000000..d8390e2
--- /dev/null
+++ b/tests/chan.test
@@ -0,0 +1,275 @@
+# This file contains a collection of tests for the Tcl built-in 'chan'
+# command. Sourcing this file into Tcl runs the tests and generates
+# output for errors. No output means no errors were found.
+#
+# Copyright (c) 2005 Donal K. Fellows
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+    package require tcltest 2
+    namespace import -force ::tcltest::*
+}
+
+#
+# Note: The tests for the chan methods "create" and "postevent"
+# currently reside in the file "ioCmd.test".
+#
+
+test chan-1.1 {chan command general syntax} -body {
+    chan
+} -returnCodes error -result "wrong # args: should be \"chan subcommand ?arg ...?\""
+test chan-1.2 {chan command general syntax} -body {
+    chan FOOBAR
+} -returnCodes error -match glob -result "unknown or ambiguous subcommand \"FOOBAR\": must be *"
+
+test chan-2.1 {chan command: blocked subcommand} -body {
+    chan blocked foo bar
+} -returnCodes error -result "wrong # args: should be \"chan blocked channelId\""
+test chan-3.1 {chan command: close subcommand} -body {
+    chan close foo bar zet
+} -returnCodes error -result "wrong # args: should be \"chan close channelId ?direction?\""
+test chan-3.2 {chan command: close subcommand} -setup {
+    set chan [open [info script] r]
+} -body {
+    chan close $chan bar
+} -cleanup {
+    close $chan
+} -returnCodes error -result "bad direction \"bar\": must be read or write"
+test chan-3.3 {chan command: close subcommand} -setup {
+    set chan [open [info script] r]
+} -body {
+    chan close $chan write
+} -cleanup {
+    close $chan
+} -returnCodes error -result "Half-close of write-side not possible, side not opened or already closed"
+test chan-4.1 {chan command: configure subcommand} -body {
+    chan configure
+} -returnCodes error -result "wrong # args: should be \"chan configure channelId ?-option value ...?\""
+test chan-4.2 {chan command: [Bug 800753]} -body {
+    chan configure stdout -eofchar \u0100
+} -returnCodes error -match glob -result {bad value*}
+test chan-4.3 {chan command: [Bug 800753]} -body {
+    chan configure stdout -eofchar \u0000
+} -returnCodes error -match glob -result {bad value*}
+test chan-4.4 {chan command: check valid inValue, no outValue} -body {
+    chan configure stdout -eofchar [list \x27 {}]
+} -returnCodes ok -result {}
+test chan-4.5 {chan command: check valid inValue, invalid outValue} -body {
+    chan configure stdout -eofchar [list \x27 \x80]
+} -returnCodes error -match glob -result {bad value for -eofchar:*}
+test chan-4.6 {chan command: check no inValue, valid outValue} -body {
+    chan configure stdout -eofchar [list {} \x27]
+} -returnCodes ok -result {} -cleanup {chan configure stdout -eofchar [list {} {}]}
+
+test chan-5.1 {chan command: copy subcommand} -body {
+    chan copy foo
+} -returnCodes error -result "wrong # args: should be \"chan copy input output ?-size size? ?-command callback?\""
+
+test chan-6.1 {chan command: eof subcommand} -body {
+    chan eof foo bar
+} -returnCodes error -result "wrong # args: should be \"chan eof channelId\""
+
+test chan-7.1 {chan command: event subcommand} -body {
+    chan event foo
+} -returnCodes error -result "wrong # args: should be \"chan event channelId event ?script?\""
+
+test chan-8.1 {chan command: flush subcommand} -body {
+    chan flush foo bar
+} -returnCodes error -result "wrong # args: should be \"chan flush channelId\""
+
+test chan-9.1 {chan command: gets subcommand} -body {
+    chan gets
+} -returnCodes error -result "wrong # args: should be \"chan gets channelId ?varName?\""
+
+test chan-10.1 {chan command: names subcommand} -body {
+    chan names foo bar
+} -returnCodes error -result "wrong # args: should be \"chan names ?pattern?\""
+
+test chan-11.1 {chan command: puts subcommand} -body {
+    chan puts foo bar foo bar
+} -returnCodes error -result "wrong # args: should be \"chan puts ?-nonewline? ?channelId? string\""
+
+test chan-12.1 {chan command: read subcommand} -body {
+    chan read
+} -returnCodes error -result "wrong # args: should be \"chan read channelId ?numChars?\" or \"chan read ?-nonewline? channelId\""
+
+test chan-13.1 {chan command: seek subcommand} -body {
+    chan seek foo bar foo bar
+} -returnCodes error -result "wrong # args: should be \"chan seek channelId offset ?origin?\""
+
+test chan-14.1 {chan command: tell subcommand} -body {
+    chan tell foo bar
+} -returnCodes error -result "wrong # args: should be \"chan tell channelId\""
+
+test chan-15.1 {chan command: truncate subcommand} -body {
+    chan truncate foo bar foo bar
+} -returnCodes error -result "wrong \# args: should be \"chan truncate channelId ?length?\""
+test chan-15.2 {chan command: truncate subcommand} -setup {
+    set file [makeFile {} testTruncate]
+    set f [open $file w+]
+    fconfigure $f -translation binary
+} -body {
+    seek $f 0
+    puts -nonewline $f 12345
+    seek $f 0
+    chan truncate $f 2
+    read $f
+} -result 12 -cleanup {
+    catch {close $f}
+    catch {removeFile $file}
+}
+
+# TIP 287: chan pending
+test chan-16.1 {chan command: pending subcommand} -body {
+    chan pending
+} -returnCodes error -result "wrong # args: should be \"chan pending mode channelId\""
+test chan-16.2 {chan command: pending subcommand} -body {
+    chan pending stdin
+} -returnCodes error -result "wrong # args: should be \"chan pending mode channelId\""
+test chan-16.3 {chan command: pending subcommand} -body {
+    chan pending stdin stdout stderr
+} -returnCodes error -result "wrong # args: should be \"chan pending mode channelId\""
+test chan-16.4 {chan command: pending subcommand} -body {
+    chan pending {input output} stdout
+} -returnCodes error -result "bad mode \"input output\": must be input or output"
+test chan-16.5 {chan command: pending input subcommand} -body {
+    chan pending input stdout 
+} -result -1
+test chan-16.6 {chan command: pending input subcommand} -body {
+    chan pending input stdin
+} -result 0
+test chan-16.7 {chan command: pending input subcommand} -body {
+    chan pending input FOOBAR
+} -returnCodes error -result "can not find channel named \"FOOBAR\""
+test chan-16.8 {chan command: pending input subcommand} -setup {
+    set file [makeFile {} testAvailable]
+    set f [open $file w+]
+    chan configure $f -translation lf -buffering line
+} -body {
+    chan puts $f foo
+    chan puts $f bar
+    chan puts $f baz
+    chan seek $f 0
+    chan gets $f
+    chan pending input $f
+} -result 8 -cleanup {
+    catch {chan close $f}
+    catch {removeFile $file}
+}
+test chan-16.9 {chan command: pending input subcommand} -setup {
+    proc chan-16.9-accept {sock addr port} {
+        chan configure $sock -blocking 0 -buffering line -buffersize 32
+        chan event $sock readable [list chan-16.9-readable $sock]
+    }
+
+    proc chan-16.9-readable {sock} {
+        set r [chan gets $sock line]
+        set l [string length $line]
+        set e [chan eof $sock]
+        set b [chan blocked $sock]
+        set i [chan pending input $sock]
+
+        lappend ::chan-16.9-data $r $l $e $b $i
+
+        if {$r != -1 || $e || $l || !$b || $i > 128} {
+            set data [read $sock $i]
+            lappend ::chan-16.9-data [string range $data 0 2]
+            lappend ::chan-16.9-data [string range $data end-2 end]
+            set ::chan-16.9-done 1
+            chan event $sock readable {}
+        } else {
+	    after idle chan-16.9-client
+	}
+    }
+
+    proc chan-16.9-client {} {
+        chan puts -nonewline $::client ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890
+        chan flush $::client
+    }
+
+    set ::server [socket -server chan-16.9-accept -myaddr 127.0.0.1 0]
+    set ::client [socket 127.0.0.1 [lindex [fconfigure $::server -sockname] 2]]
+    set ::chan-16.9-data [list]
+    set ::chan-16.9-done 0
+} -body {
+    after idle chan-16.9-client 
+    vwait ::chan-16.9-done
+    set ::chan-16.9-data
+} -result {-1 0 0 1 36 -1 0 0 1 72 -1 0 0 1 108 -1 0 0 1 144 ABC 890} -cleanup {
+    catch {chan close $client}
+    catch {chan close $server}
+    rename chan-16.9-accept {}
+    rename chan-16.9-readable {}
+    rename chan-16.9-client {}
+    unset -nocomplain ::chan-16.9-data
+    unset -nocomplain ::chan-16.9-done
+    unset -nocomplain ::server
+    unset -nocomplain ::client
+}
+test chan-16.10 {chan command: pending output subcommand} -body {
+    chan pending output stdin
+} -result -1
+test chan-16.11 {chan command: pending output subcommand} -body {
+    chan pending output stdout
+} -result 0
+test chan-16.12 {chan command: pending output subcommand} -body {
+    chan pending output FOOBAR
+} -returnCodes error -result "can not find channel named \"FOOBAR\""
+test chan-16.13 {chan command: pending output subcommand} -setup {
+    set file [makeFile {} testPendingOutput]
+    set f [open $file w+]
+    chan configure $f -translation lf -buffering full -buffersize 1024
+} -body {
+    set result [list]
+    chan puts $f [string repeat x 512]
+    lappend result [chan pending output $f]
+    chan flush $f
+    lappend result [chan pending output $f]
+} -result [list 513 0] -cleanup {
+    unset -nocomplain result
+    catch {chan close $f}
+    catch {removeFile $file}
+}
+
+# TIP 304: chan pipe
+
+test chan-17.1 {chan command: pipe subcommand} -body {
+    chan pipe foo
+} -returnCodes error -result "wrong # args: should be \"chan pipe \""
+
+test chan-17.2 {chan command: pipe subcommand} -body {
+    chan pipe foo bar
+} -returnCodes error -result "wrong # args: should be \"chan pipe \""
+
+test chan-17.3 {chan command: pipe subcommand} -body {
+	set l [chan pipe]
+    foreach {pr pw} $l break
+    list [llength $l] [fconfigure $pr -blocking] [fconfigure $pw -blocking]
+} -result [list 2 1 1] -cleanup {
+    close $pw
+    close $pr
+}
+
+test chan-17.4 {chan command: pipe subcommand} -body {
+    set ::done 0
+    foreach {::pr ::pw} [chan pipe] break
+    after 100 {puts $::pw foo;flush $::pw}
+    fileevent $::pr readable {set ::done 1}
+    after 500 {set ::done -1}
+    vwait ::done
+    set out nope
+    if {$::done==1} {gets $::pr out}
+    list $::done $out
+} -result [list 1 foo] -cleanup {
+    close $::pw
+    close $::pr
+}
+
+cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/tests/chanio.test b/tests/chanio.test
new file mode 100644
index 0000000..9a27233
--- /dev/null
+++ b/tests/chanio.test
@@ -0,0 +1,7742 @@
+# -*- tcl -*-
+# Functionality covered: operation of all IO commands, and all procedures
+# defined in generic/tclIO.c.
+#
+# This file contains a collection of tests for one or more of the Tcl built-in
+# commands. Sourcing this file into Tcl runs the tests and generates output
+# for errors. No output means no errors were found.
+#
+# Copyright (c) 1991-1994 The Regents of the University of California.
+# Copyright (c) 1994-1997 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution of
+# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+    package require tcltest 2
+    namespace import -force ::tcltest::*
+}
+
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
+
+testConstraint testbytestring [llength [info commands testbytestring]]
+
+namespace eval ::tcl::test::io {
+    namespace import ::tcltest::*
+
+    variable umaskValue
+    variable path
+    variable f
+    variable i
+    variable n
+    variable v
+    variable msg
+    variable expected
+
+    ::tcltest::loadTestedCommands
+    catch [list package require -exact Tcltest [info patchlevel]]
+    
+    testConstraint testchannel      [llength [info commands testchannel]]
+    testConstraint exec             [llength [info commands exec]]
+    testConstraint openpipe         1
+    testConstraint fileevent        [llength [info commands fileevent]]
+    testConstraint fcopy            [llength [info commands fcopy]]
+    testConstraint testfevent       [llength [info commands testfevent]]
+    testConstraint testchannelevent [llength [info commands testchannelevent]]
+    testConstraint testmainthread   [llength [info commands testmainthread]]
+    testConstraint thread [expr {0 == [catch {package require Thread 2.7-}]}]
+
+    # You need a *very* special environment to do some tests.  In particular,
+    # many file systems do not support large-files...
+    testConstraint largefileSupport [expr {$::tcl_platform(os) ne "Darwin"}]
+
+    # some tests can only be run is umask is 2 if "umask" cannot be run, the
+    # tests will be skipped.
+    set umaskValue 0
+    testConstraint umask [expr {![catch {set umaskValue [scan [exec /bin/sh -c umask] %o]}]}]
+
+    testConstraint makeFileInHome [expr {![file exists ~/_test_] && [file writable ~]}]
+
+    # set up a long data file for some of the following tests
+
+    set path(longfile) [makeFile {} longfile]
+    set f [open $path(longfile) w]
+    chan configure $f -eofchar {} -translation lf
+    for { set i 0 } { $i < 100 } { incr i} {
+	chan puts $f "#123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef
+\#123456789abcdef01
+\#"
+    }
+    chan close $f
+
+    set path(cat) [makeFile {
+	set f stdin
+	if {$argv != ""} {
+	    set f [open [lindex $argv 0]]
+	}
+	chan configure $f -encoding binary -translation lf -blocking 0 -eofchar \x1a
+	chan configure stdout -encoding binary -translation lf -buffering none
+	chan event $f readable "foo $f"
+	proc foo {f} {
+	    set x [chan read $f]
+	    catch {chan puts -nonewline $x}
+	    if {[chan eof $f]} {
+		chan close $f
+		exit 0
+	    }
+	}
+	vwait forever
+    } cat]
+
+    set thisScript [file join [pwd] [info script]]
+
+    proc contents {file} {
+	set f [open $file]
+	chan configure $f -translation binary
+	set a [chan read $f]
+	chan close $f
+	return $a
+    }
+
+    # Wrapper round butt-ugly pipe syntax
+    proc openpipe {{mode r+} args} {
+	open "|[list [interpreter] {*}$args]" $mode
+    }
+
+test chan-io-1.5 {Tcl_WriteChars: CheckChannelErrors} {emptyTest} {
+    # no test, need to cause an async error.
+} {}
+set path(test1) [makeFile {} test1]
+test chan-io-1.6 {Tcl_WriteChars: WriteBytes} {
+    set f [open $path(test1) w]
+    chan configure $f -encoding binary
+    chan puts -nonewline $f "a\u4e4d\0"
+    chan close $f
+    contents $path(test1)
+} "a\x4d\x00"
+test chan-io-1.7 {Tcl_WriteChars: WriteChars} {
+    set f [open $path(test1) w]
+    chan configure $f -encoding shiftjis
+    chan puts -nonewline $f "a\u4e4d\0"
+    chan close $f
+    contents $path(test1)
+} "a\x93\xe1\x00"
+set path(test2) [makeFile {} test2]
+test chan-io-1.8 {Tcl_WriteChars: WriteChars} {
+    # This test written for SF bug #506297.
+    #
+    # Executing this test without the fix for the referenced bug applied to
+    # tcl will cause tcl, more specifically WriteChars, to go into an infinite
+    # loop.
+    set f [open $path(test2) w] 
+    chan configure      $f -encoding iso2022-jp 
+    chan puts -nonewline $f [format %s%c [string repeat " " 4] 12399] 
+    chan close           $f 
+    contents $path(test2)
+} "    \x1b\$B\$O\x1b(B"
+test chan-io-1.9 {Tcl_WriteChars: WriteChars} {
+    # When closing a channel with an encoding that appends escape bytes, check
+    # for the case where the escape bytes overflow the current IO buffer. The
+    # bytes should be moved into a new buffer.
+    set data "1234567890 [format %c 12399]"
+    set sizes [list]
+    # With default buffer size
+    set f [open $path(test2) w]
+    chan configure      $f -encoding iso2022-jp
+    chan puts -nonewline $f $data
+    chan close           $f
+    lappend sizes [file size $path(test2)]
+    # With buffer size equal to the length of the data, the escape bytes would
+    # go into the next buffer.
+    set f [open $path(test2) w]
+    chan configure      $f -encoding iso2022-jp -buffersize 16
+    chan puts -nonewline $f $data
+    chan close           $f
+    lappend sizes [file size $path(test2)]
+    # With buffer size that is large enough to hold 1 byte of escaped data,
+    # but not all 3. This should not write the escape bytes to the first
+    # buffer and then again to the second buffer.
+    set f [open $path(test2) w]
+    chan configure      $f -encoding iso2022-jp -buffersize 17
+    chan puts -nonewline $f $data
+    chan close           $f
+    lappend sizes [file size $path(test2)]
+    # With buffer size that can hold 2 out of 3 bytes of escaped data.
+    set f [open $path(test2) w]
+    chan configure      $f -encoding iso2022-jp -buffersize 18
+    chan puts -nonewline $f $data
+    chan close           $f
+    lappend sizes [file size $path(test2)]
+    # With buffer size that can hold all the data and escape bytes.
+    set f [open $path(test2) w]
+    chan configure      $f -encoding iso2022-jp -buffersize 19
+    chan puts -nonewline $f $data
+    chan close           $f
+    lappend sizes [file size $path(test2)]
+} {19 19 19 19 19}
+
+test chan-io-2.1 {WriteBytes} {
+    # loop until all bytes are written
+    set f [open $path(test1) w]
+    chan configure $f  -encoding binary -buffersize 16 -translation crlf
+    chan puts $f "abcdefghijklmnopqrstuvwxyz"
+    chan close $f
+    contents $path(test1)
+} "abcdefghijklmnopqrstuvwxyz\r\n"
+test chan-io-2.2 {WriteBytes: savedLF > 0} {
+    # After flushing buffer, there was a \n left over from the last
+    # \n -> \r\n expansion.  It gets stuck at beginning of this buffer.
+    set f [open $path(test1) w]
+    chan configure $f -encoding binary -buffersize 16 -translation crlf
+    chan puts -nonewline $f "123456789012345\n12"
+    set x [list [contents $path(test1)]]
+    chan close $f
+    lappend x [contents $path(test1)]
+} [list "123456789012345\r" "123456789012345\r\n12"]
+test chan-io-2.3 {WriteBytes: flush on line} -body {
+    # Tcl "line" buffering has weird behavior: if current buffer contains a
+    # \n, entire buffer gets flushed.  Logical behavior would be to flush only
+    # up to the \n.
+    set f [open $path(test1) w]
+    chan configure $f -encoding binary -buffering line -translation crlf
+    chan puts -nonewline $f "\n12"
+    contents $path(test1)
+} -cleanup {
+    chan close $f
+} -result "\r\n12"
+test chan-io-2.4 {WriteBytes: reset sawLF after each buffer} {
+    set f [open $path(test1) w]
+     chan configure $f -encoding binary -buffering line -translation lf \
+	     -buffersize 16
+    chan puts -nonewline $f "abcdefg\nhijklmnopqrstuvwxyz"
+    set x [list [contents $path(test1)]]
+    chan close $f
+    lappend x [contents $path(test1)]
+} [list "abcdefg\nhijklmno" "abcdefg\nhijklmnopqrstuvwxyz"]
+
+test chan-io-3.1 {WriteChars: compatibility with WriteBytes} {
+    # loop until all bytes are written
+    set f [open $path(test1) w]
+    chan configure $f -encoding ascii -buffersize 16 -translation crlf
+    chan puts $f "abcdefghijklmnopqrstuvwxyz"
+    chan close $f
+    contents $path(test1)
+} "abcdefghijklmnopqrstuvwxyz\r\n"
+test chan-io-3.2 {WriteChars: compatibility with WriteBytes: savedLF > 0} {
+    # After flushing buffer, there was a \n left over from the last
+    # \n -> \r\n expansion.  It gets stuck at beginning of this buffer.
+    set f [open $path(test1) w]
+    chan configure $f -encoding ascii -buffersize 16 -translation crlf
+    chan puts -nonewline $f "123456789012345\n12"
+    set x [list [contents $path(test1)]]
+    chan close $f
+    lappend x [contents $path(test1)]
+} [list "123456789012345\r" "123456789012345\r\n12"]
+test chan-io-3.3 {WriteChars: compatibility with WriteBytes: flush on line} -body {
+    # Tcl "line" buffering has weird behavior: if current buffer contains a
+    # \n, entire buffer gets flushed.  Logical behavior would be to flush only
+    # up to the \n.
+    set f [open $path(test1) w]
+    chan configure $f -encoding ascii -buffering line -translation crlf
+    chan puts -nonewline $f "\n12"
+    contents $path(test1)
+} -cleanup {
+    chan close $f
+} -result "\r\n12"
+test chan-io-3.4 {WriteChars: loop over stage buffer} {
+    # stage buffer maps to more than can be queued at once.
+    set f [open $path(test1) w]
+    chan configure $f -encoding jis0208 -buffersize 16 
+    chan puts -nonewline $f "\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"
+    set x [list [contents $path(test1)]]
+    chan close $f
+    lappend x [contents $path(test1)]
+} [list "!)!)!)!)!)!)!)!)" "!)!)!)!)!)!)!)!)!)!)!)!)!)!)!)"]
+test chan-io-3.5 {WriteChars: saved != 0} {
+    # Bytes produced by UtfToExternal from end of last channel buffer had to
+    # be moved to beginning of next channel buffer to preserve requested
+    # buffersize.
+    set f [open $path(test1) w]
+    chan configure $f -encoding jis0208 -buffersize 17 
+    chan puts -nonewline $f "\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"
+    set x [list [contents $path(test1)]]
+    chan close $f
+    lappend x [contents $path(test1)]
+} [list "!)!)!)!)!)!)!)!)!" "!)!)!)!)!)!)!)!)!)!)!)!)!)!)!)"]
+test chan-io-3.6 {WriteChars: (stageRead + dstWrote == 0)} {
+    # One incomplete UTF-8 character at end of staging buffer. Backup in src
+    # to the beginning of that UTF-8 character and try again.
+    #
+    # Translate the first 16 bytes, produce 14 bytes of output, 2 left over
+    # (first two bytes of \uff21 in UTF-8). Given those two bytes try
+    # translating them again, find that no bytes are read produced, and break
+    # to outer loop where those two bytes will have the remaining 4 bytes (the
+    # last byte of \uff21 plus the all of \uff22) appended.
+    set f [open $path(test1) w]
+    chan configure $f -encoding shiftjis -buffersize 16
+    chan puts -nonewline $f "12345678901234\uff21\uff22"
+    set x [list [contents $path(test1)]]
+    chan close $f
+    lappend x [contents $path(test1)]
+} [list "12345678901234\x82\x60" "12345678901234\x82\x60\x82\x61"]
+test chan-io-3.7 {WriteChars: (bufPtr->nextAdded > bufPtr->length)} {
+    # When translating UTF-8 to external, the produced bytes went past end of
+    # the channel buffer. This is done on purpose - we then truncate the bytes
+    # at the end of the partial character to preserve the requested blocksize
+    # on flush. The truncated bytes are moved to the beginning of the next
+    # channel buffer.
+    set f [open $path(test1) w]
+    chan configure $f -encoding jis0208 -buffersize 17 
+    chan puts -nonewline $f "\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"
+    set x [list [contents $path(test1)]]
+    chan close $f
+    lappend x [contents $path(test1)]
+} [list "!)!)!)!)!)!)!)!)!" "!)!)!)!)!)!)!)!)!)!)!)!)!)!)!)"]
+test chan-io-3.8 {WriteChars: reset sawLF after each buffer} {
+    set f [open $path(test1) w]
+    chan configure $f -encoding ascii -buffering line -translation lf \
+	     -buffersize 16
+    chan puts -nonewline $f "abcdefg\nhijklmnopqrstuvwxyz"
+    set x [list [contents $path(test1)]]
+    chan close $f
+    lappend x [contents $path(test1)]
+} [list "abcdefg\nhijklmno" "abcdefg\nhijklmnopqrstuvwxyz"]
+
+test chan-io-4.1 {TranslateOutputEOL: lf} {
+    # search for \n
+    set f [open $path(test1) w]
+    chan configure $f -buffering line -translation lf
+    chan puts $f "abcde"
+    set x [list [contents $path(test1)]]
+    chan close $f
+    lappend x [contents $path(test1)]
+} [list "abcde\n" "abcde\n"]
+test chan-io-4.2 {TranslateOutputEOL: cr} {
+    # search for \n, replace with \r
+    set f [open $path(test1) w]
+    chan configure $f -buffering line -translation cr
+    chan puts $f "abcde"
+    set x [list [contents $path(test1)]]
+    chan close $f
+    lappend x [contents $path(test1)]
+} [list "abcde\r" "abcde\r"]
+test chan-io-4.3 {TranslateOutputEOL: crlf} {
+    # simple case: search for \n, replace with \r
+    set f [open $path(test1) w]
+    chan configure $f -buffering line -translation crlf
+    chan puts $f "abcde"
+    set x [list [contents $path(test1)]]
+    chan close $f
+    lappend x [contents $path(test1)]
+} [list "abcde\r\n" "abcde\r\n"]
+test chan-io-4.4 {TranslateOutputEOL: crlf} {
+    # Keep storing more bytes in output buffer until output buffer is full. We
+    # have 13 bytes initially that would turn into 18 bytes. Fill dest buffer
+    # while (dstEnd < dstMax).
+    set f [open $path(test1) w]
+    chan configure $f -translation crlf -buffersize 16
+    chan puts -nonewline $f "1234567\n\n\n\n\nA"
+    set x [list [contents $path(test1)]]
+    chan close $f
+    lappend x [contents $path(test1)]
+} [list "1234567\r\n\r\n\r\n\r\n\r" "1234567\r\n\r\n\r\n\r\n\r\nA"]
+test chan-io-4.5 {TranslateOutputEOL: crlf} {
+    # Check for overflow of the destination buffer
+    set f [open $path(test1) w]
+    chan configure $f -translation crlf -buffersize 12
+    chan puts -nonewline $f "12345678901\n456789012345678901234"
+    chan close $f
+    set x [contents $path(test1)]
+} "12345678901\r\n456789012345678901234"
+
+test chan-io-5.1 {CheckFlush: not full} {
+    set f [open $path(test1) w]
+    chan configure $f 
+    chan puts -nonewline $f "12345678901234567890"
+    set x [list [contents $path(test1)]]
+    chan close $f
+    lappend x [contents $path(test1)]
+} [list "" "12345678901234567890"]
+test chan-io-5.2 {CheckFlush: full} {
+    set f [open $path(test1) w]
+    chan configure $f -buffersize 16
+    chan puts -nonewline $f "12345678901234567890"
+    set x [list [contents $path(test1)]]
+    chan close $f
+    lappend x [contents $path(test1)]
+} [list "1234567890123456" "12345678901234567890"]
+test chan-io-5.3 {CheckFlush: not line} {
+    set f [open $path(test1) w]
+    chan configure $f -buffering line
+    chan puts -nonewline $f "12345678901234567890"
+    set x [list [contents $path(test1)]]
+    chan close $f
+    lappend x [contents $path(test1)]
+} [list "" "12345678901234567890"]
+test chan-io-5.4 {CheckFlush: line} {
+    set f [open $path(test1) w]
+    chan configure $f -buffering line -translation lf -encoding ascii
+    chan puts -nonewline $f "1234567890\n1234567890"
+    set x [list [contents $path(test1)]]
+    chan close $f
+    lappend x [contents $path(test1)]
+} [list "1234567890\n1234567890" "1234567890\n1234567890"]
+test chan-io-5.5 {CheckFlush: none} {
+    set f [open $path(test1) w]
+    chan configure $f -buffering none
+    chan puts -nonewline $f "1234567890"
+    set x [list [contents $path(test1)]]
+    chan close $f
+    lappend x [contents $path(test1)]
+} [list "1234567890" "1234567890"]
+
+test chan-io-6.1 {Tcl_GetsObj: working} -body {
+    set f [open $path(test1) w]
+    chan puts $f "foo\nboo"
+    chan close $f
+    set f [open $path(test1)]
+    chan gets $f
+} -cleanup {
+    chan close $f
+} -result {foo}
+test chan-io-6.2 {Tcl_GetsObj: CheckChannelErrors() != 0} emptyTest {
+    # no test, need to cause an async error.
+} {}
+test chan-io-6.3 {Tcl_GetsObj: how many have we used?} -body {
+    # if (bufPtr != NULL) {oldRemoved = bufPtr->nextRemoved}
+    set f [open $path(test1) w]
+    chan configure $f -translation crlf
+    chan puts $f "abc\ndefg"
+    chan close $f
+    set f [open $path(test1)]
+    list [chan tell $f] [chan gets $f line] [chan tell $f] [chan gets $f line] $line
+} -cleanup {
+    chan close $f
+} -result {0 3 5 4 defg}
+test chan-io-6.4 {Tcl_GetsObj: encoding == NULL} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation binary
+    chan puts $f "\x81\u1234\0"
+    chan close $f
+    set f [open $path(test1)]
+    chan configure $f -translation binary
+    list [chan gets $f line] $line
+} -cleanup {
+    chan close $f
+} -result [list 3 "\x81\x34\x00"]
+test chan-io-6.5 {Tcl_GetsObj: encoding != NULL} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation binary
+    chan puts $f "\x88\xea\x92\x9a"
+    chan close $f
+    set f [open $path(test1)]
+    chan configure $f -encoding shiftjis
+    list [chan gets $f line] $line
+} -cleanup {
+    chan close $f
+} -result [list 2 "\u4e00\u4e01"]
+set a "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
+append a $a
+append a $a
+test chan-io-6.6 {Tcl_GetsObj: loop test} -body {
+    # if (dst >= dstEnd) 
+    set f [open $path(test1) w]
+    chan puts $f $a
+    chan puts $f hi
+    chan close $f
+    set f [open $path(test1)]
+    list [chan gets $f line] $line
+} -cleanup {
+    chan close $f
+} -result [list 256 $a]
+test chan-io-6.7 {Tcl_GetsObj: error in input} -constraints {stdio openpipe} -body {
+    # if (FilterInputBytes(chanPtr, &gs) != 0)
+    set f [openpipe w+ $path(cat)]
+    chan puts -nonewline $f "hi\nwould"
+    chan flush $f
+    chan gets $f
+    chan configure $f -blocking 0
+    chan gets $f line
+} -cleanup {
+    chan close $f
+} -result {-1}
+test chan-io-6.8 {Tcl_GetsObj: remember if EOF is seen} -body {
+    set f [open $path(test1) w]
+    chan puts $f "abcdef\x1aghijk\nwombat"
+    chan close $f
+    set f [open $path(test1)]
+    chan configure $f -eofchar \x1a
+    list [chan gets $f line] $line [chan gets $f line] $line
+} -cleanup {
+    chan close $f
+} -result {6 abcdef -1 {}}
+test chan-io-6.9 {Tcl_GetsObj: remember if EOF is seen} -body {
+    set f [open $path(test1) w]
+    chan puts $f "abcdefghijk\nwom\u001abat"
+    chan close $f
+    set f [open $path(test1)]
+    chan configure $f -eofchar \x1a
+    list [chan gets $f line] $line [chan gets $f line] $line
+} -cleanup {
+    chan close $f
+} -result {11 abcdefghijk 3 wom}
+# Comprehensive tests
+test chan-io-6.10 {Tcl_GetsObj: lf mode: no chars} -body {
+    set f [open $path(test1) w]
+    chan close $f
+    set f [open $path(test1)]
+    chan configure $f -translation lf
+    list [chan gets $f line] $line
+} -cleanup {
+    chan close $f
+} -result {-1 {}}
+test chan-io-6.11 {Tcl_GetsObj: lf mode: lone \n} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation lf
+    chan puts -nonewline $f "\n"
+    chan close $f
+    set f [open $path(test1)]
+    chan configure $f -translation lf
+    list [chan gets $f line] $line [chan gets $f line] $line
+} -cleanup {
+    chan close $f
+} -result {0 {} -1 {}}
+test chan-io-6.12 {Tcl_GetsObj: lf mode: lone \r} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation lf
+    chan puts -nonewline $f "\r"
+    chan close $f
+    set f [open $path(test1)]
+    chan configure $f -translation lf
+    set x [list [chan gets $f line] $line [chan gets $f line] $line]
+} -cleanup {
+    chan close $f
+} -result [list 1 "\r" -1 ""]
+test chan-io-6.13 {Tcl_GetsObj: lf mode: 1 char} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation lf
+    chan puts -nonewline $f a
+    chan close $f
+    set f [open $path(test1)]
+    chan configure $f -translation lf
+    list [chan gets $f line] $line [chan gets $f line] $line
+} -cleanup {
+    chan close $f
+} -result {1 a -1 {}}
+test chan-io-6.14 {Tcl_GetsObj: lf mode: 1 char followed by EOL} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation lf
+    chan puts -nonewline $f "a\n"
+    chan close $f
+    set f [open $path(test1)]
+    chan configure $f -translation lf
+    list [chan gets $f line] $line [chan gets $f line] $line
+} -cleanup {
+    chan close $f
+} -result {1 a -1 {}}
+test chan-io-6.15 {Tcl_GetsObj: lf mode: several chars} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation lf
+    chan puts -nonewline $f "abcd\nefgh\rijkl\r\nmnop"
+    chan close $f
+    set f [open $path(test1)]
+    chan configure $f -translation lf
+    list [chan gets $f line] $line [chan gets $f line] $line \
+	[chan gets $f line] $line [chan gets $f line] $line
+} -cleanup {
+    chan close $f
+} -result [list 4 "abcd" 10 "efgh\rijkl\r" 4 "mnop" -1 ""]
+test chan-io-6.16 {Tcl_GetsObj: cr mode: no chars} -body {
+    set f [open $path(test1) w]
+    chan close $f
+    set f [open $path(test1)]
+    chan configure $f -translation cr
+    list [chan gets $f line] $line
+} -cleanup {
+    chan close $f
+} -result {-1 {}}
+test chan-io-6.17 {Tcl_GetsObj: cr mode: lone \n} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation lf
+    chan puts -nonewline $f "\n"
+    chan close $f
+    set f [open $path(test1)]
+    chan configure $f -translation cr
+    list [chan gets $f line] $line [chan gets $f line] $line
+} -cleanup {
+    chan close $f
+} -result [list 1 "\n" -1 ""]
+test chan-io-6.18 {Tcl_GetsObj: cr mode: lone \r} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation lf
+    chan puts -nonewline $f "\r"
+    chan close $f
+    set f [open $path(test1)]
+    chan configure $f -translation cr
+    list [chan gets $f line] $line [chan gets $f line] $line
+} -cleanup {
+    chan close $f
+} -result {0 {} -1 {}}
+test chan-io-6.19 {Tcl_GetsObj: cr mode: 1 char} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation lf
+    chan puts -nonewline $f a
+    chan close $f
+    set f [open $path(test1)]
+    chan configure $f -translation cr
+    list [chan gets $f line] $line [chan gets $f line] $line
+} -cleanup {
+    chan close $f
+} -result {1 a -1 {}}
+test chan-io-6.20 {Tcl_GetsObj: cr mode: 1 char followed by EOL} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation lf
+    chan puts -nonewline $f "a\r"
+    chan close $f
+    set f [open $path(test1)]
+    chan configure $f -translation cr
+    list [chan gets $f line] $line [chan gets $f line] $line
+} -cleanup {
+    chan close $f
+} -result {1 a -1 {}}
+test chan-io-6.21 {Tcl_GetsObj: cr mode: several chars} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation lf
+    chan puts -nonewline $f "abcd\nefgh\rijkl\r\nmnop"
+    chan close $f
+    set f [open $path(test1)]
+    chan configure $f -translation cr
+    list [chan gets $f line] $line [chan gets $f line] $line [chan gets $f line] $line [chan gets $f line] $line
+} -cleanup {
+    chan close $f
+} -result [list 9 "abcd\nefgh" 4 "ijkl" 5 "\nmnop" -1 ""]
+test chan-io-6.22 {Tcl_GetsObj: crlf mode: no chars} -body {
+    set f [open $path(test1) w]
+    chan close $f
+    set f [open $path(test1)]
+    chan configure $f -translation crlf
+    list [chan gets $f line] $line
+} -cleanup {
+    chan close $f
+} -result {-1 {}}
+test chan-io-6.23 {Tcl_GetsObj: crlf mode: lone \n} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation lf
+    chan puts -nonewline $f "\n"
+    chan close $f
+    set f [open $path(test1)]
+    chan configure $f -translation crlf
+    list [chan gets $f line] $line [chan gets $f line] $line
+} -cleanup {
+    chan close $f
+} -result [list 1 "\n" -1 ""]
+test chan-io-6.24 {Tcl_GetsObj: crlf mode: lone \r} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation lf
+    chan puts -nonewline $f "\r"
+    chan close $f
+    set f [open $path(test1)]
+    chan configure $f -translation crlf
+    list [chan gets $f line] $line [chan gets $f line] $line
+} -cleanup {
+    chan close $f
+} -result [list 1 "\r" -1 ""]
+test chan-io-6.25 {Tcl_GetsObj: crlf mode: \r\r} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation lf
+    chan puts -nonewline $f "\r\r"
+    chan close $f
+    set f [open $path(test1)]
+    chan configure $f -translation crlf
+    list [chan gets $f line] $line [chan gets $f line] $line
+} -cleanup {
+    chan close $f
+} -result [list 2 "\r\r" -1 ""]
+test chan-io-6.26 {Tcl_GetsObj: crlf mode: \r\n} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation lf
+    chan puts -nonewline $f "\r\n"
+    chan close $f
+    set f [open $path(test1)]
+    chan configure $f -translation crlf
+    list [chan gets $f line] $line [chan gets $f line] $line
+} -cleanup {
+    chan close $f
+} -result {0 {} -1 {}}
+test chan-io-6.27 {Tcl_GetsObj: crlf mode: 1 char} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation lf
+    chan puts -nonewline $f a
+    chan close $f
+    set f [open $path(test1)]
+    chan configure $f -translation crlf
+    list [chan gets $f line] $line [chan gets $f line] $line
+} -cleanup {
+    chan close $f
+} -result {1 a -1 {}}
+test chan-io-6.28 {Tcl_GetsObj: crlf mode: 1 char followed by EOL} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation lf
+    chan puts -nonewline $f "a\r\n"
+    chan close $f
+    set f [open $path(test1)]
+    chan configure $f -translation crlf
+    list [chan gets $f line] $line [chan gets $f line] $line
+} -cleanup {
+    chan close $f
+} -result {1 a -1 {}}
+test chan-io-6.29 {Tcl_GetsObj: crlf mode: several chars} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation lf
+    chan puts -nonewline $f "abcd\nefgh\rijkl\r\nmnop"
+    chan close $f
+    set f [open $path(test1)]
+    chan configure $f -translation crlf
+    list [chan gets $f line] $line [chan gets $f line] $line [chan gets $f line] $line
+} -cleanup {
+    chan close $f
+} -result [list 14 "abcd\nefgh\rijkl" 4 "mnop" -1 ""]
+test chan-io-6.30 {Tcl_GetsObj: crlf mode: buffer exhausted} -constraints {testchannel} -body {
+    # if (eol >= dstEnd)
+    set f [open $path(test1) w]
+    chan configure $f -translation lf
+    chan puts -nonewline $f "123456789012345\r\nabcdefghijklmnoprstuvwxyz"
+    chan close $f
+    set f [open $path(test1)]
+    chan configure $f -translation crlf -buffersize 16
+    list [chan gets $f line] $line [testchannel inputbuffered $f]
+} -cleanup {
+    chan close $f
+} -result [list 15 "123456789012345" 15]
+test chan-io-6.31 {Tcl_GetsObj: crlf mode: buffer exhausted, blocked} -setup {
+    set x ""
+} -constraints {stdio testchannel openpipe fileevent} -body {
+    # (FilterInputBytes() != 0)
+    set f [openpipe w+ $path(cat)]
+    chan configure $f -translation {crlf lf} -buffering none
+    chan puts -nonewline $f "bbbbbbbbbbbbbb\r\n123456789012345\r"
+    chan configure $f -buffersize 16
+    lappend x [chan gets $f]
+    chan configure $f -blocking 0
+    lappend x [chan gets $f line] $line [chan blocked $f] \
+	[testchannel inputbuffered $f]
+} -cleanup {
+    chan close $f
+} -result {bbbbbbbbbbbbbb -1 {} 1 16}
+test chan-io-6.32 {Tcl_GetsObj: crlf mode: buffer exhausted, more data} -constraints {testchannel} -body {
+    # not (FilterInputBytes() != 0)
+    set f [open $path(test1) w]
+    chan configure $f -translation lf
+    chan puts -nonewline $f "123456789012345\r\n123"
+    chan close $f
+    set f [open $path(test1)]
+    chan configure $f -translation crlf -buffersize 16
+    list [chan gets $f line] $line [chan tell $f] [testchannel inputbuffered $f]
+} -cleanup {
+    chan close $f
+} -result {15 123456789012345 17 3}
+test chan-io-6.33 {Tcl_GetsObj: crlf mode: buffer exhausted, at eof} -body {
+    # eol still equals dstEnd
+    set f [open $path(test1) w]
+    chan configure $f -translation lf
+    chan puts -nonewline $f "123456789012345\r"
+    chan close $f
+    set f [open $path(test1)]
+    chan configure $f -translation crlf -buffersize 16
+    list [chan gets $f line] $line [chan eof $f]
+} -cleanup {
+    chan close $f
+} -result [list 16 "123456789012345\r" 1]
+test chan-io-6.34 {Tcl_GetsObj: crlf mode: buffer exhausted, not followed by \n} -body {
+    # not (*eol == '\n') 
+    set f [open $path(test1) w]
+    chan configure $f -translation lf
+    chan puts -nonewline $f "123456789012345\rabcd\r\nefg"
+    chan close $f
+    set f [open $path(test1)]
+    chan configure $f -translation crlf -buffersize 16
+    list [chan gets $f line] $line [chan tell $f]
+} -cleanup {
+    chan close $f
+} -result [list 20 "123456789012345\rabcd" 22]
+test chan-io-6.35 {Tcl_GetsObj: auto mode: no chars} -body {
+    set f [open $path(test1) w]
+    chan close $f
+    set f [open $path(test1)]
+    chan configure $f -translation auto
+    list [chan gets $f line] $line
+} -cleanup {
+    chan close $f
+} -result {-1 {}}
+test chan-io-6.36 {Tcl_GetsObj: auto mode: lone \n} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation lf
+    chan puts -nonewline $f "\n"
+    chan close $f
+    set f [open $path(test1)]
+    chan configure $f -translation auto
+    list [chan gets $f line] $line [chan gets $f line] $line
+} -cleanup {
+    chan close $f
+} -result {0 {} -1 {}}
+test chan-io-6.37 {Tcl_GetsObj: auto mode: lone \r} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation lf
+    chan puts -nonewline $f "\r"
+    chan close $f
+    set f [open $path(test1)]
+    chan configure $f -translation auto
+    list [chan gets $f line] $line [chan gets $f line] $line
+} -cleanup {
+    chan close $f
+} -result {0 {} -1 {}}
+test chan-io-6.38 {Tcl_GetsObj: auto mode: \r\r} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation lf
+    chan puts -nonewline $f "\r\r"
+    chan close $f
+    set f [open $path(test1)]
+    chan configure $f -translation auto
+    list [chan gets $f line] $line [chan gets $f line] $line [chan gets $f line] $line
+} -cleanup {
+    chan close $f
+} -result {0 {} 0 {} -1 {}}
+test chan-io-6.39 {Tcl_GetsObj: auto mode: \r\n} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation lf
+    chan puts -nonewline $f "\r\n"
+    chan close $f
+    set f [open $path(test1)]
+    chan configure $f -translation auto
+    list [chan gets $f line] $line [chan gets $f line] $line
+} -cleanup {
+    chan close $f
+} -result {0 {} -1 {}}
+test chan-io-6.40 {Tcl_GetsObj: auto mode: 1 char} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation lf
+    chan puts -nonewline $f a
+    chan close $f
+    set f [open $path(test1)]
+    chan configure $f -translation auto
+    list [chan gets $f line] $line [chan gets $f line] $line
+} -cleanup {
+    chan close $f
+} -result {1 a -1 {}}
+test chan-io-6.41 {Tcl_GetsObj: auto mode: 1 char followed by EOL} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation lf
+    chan puts -nonewline $f "a\r\n"
+    chan close $f
+    set f [open $path(test1)]
+    chan configure $f -translation auto
+    list [chan gets $f line] $line [chan gets $f line] $line
+} -cleanup {
+    chan close $f
+} -result {1 a -1 {}}
+test chan-io-6.42 {Tcl_GetsObj: auto mode: several chars} -setup {
+    set x ""
+} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation lf
+    chan puts -nonewline $f "abcd\nefgh\rijkl\r\nmnop"
+    chan close $f
+    set f [open $path(test1)]
+    chan configure $f -translation auto
+    lappend x [chan gets $f line] $line [chan gets $f line] $line
+    lappend x [chan gets $f line] $line [chan gets $f line] $line [chan gets $f line] $line
+} -cleanup {
+    chan close $f
+} -result {4 abcd 4 efgh 4 ijkl 4 mnop -1 {}}
+test chan-io-6.43 {Tcl_GetsObj: input saw cr} -setup {
+    set x ""
+} -constraints {stdio testchannel openpipe fileevent} -body {
+    # if (chanPtr->flags & INPUT_SAW_CR)
+    set f [openpipe w+ $path(cat)]
+    chan configure $f -translation {auto lf} -buffering none
+    chan puts -nonewline $f "bbbbbbbbbbbbbbb\n123456789abcdef\r"
+    chan configure $f -buffersize 16
+    lappend x [chan gets $f]
+    chan configure $f -blocking 0
+    lappend x [chan gets $f line] $line [testchannel queuedcr $f] 
+    chan configure $f -blocking 1
+    chan puts -nonewline $f "\nabcd\refg\x1a"
+    lappend x [chan gets $f line] $line [testchannel queuedcr $f]
+    lappend x [chan gets $f line] $line
+} -cleanup {
+    chan close $f
+} -result {bbbbbbbbbbbbbbb 15 123456789abcdef 1 4 abcd 0 3 efg}
+test chan-io-6.44 {Tcl_GetsObj: input saw cr, not followed by cr} -setup {
+    set x ""
+} -constraints {stdio testchannel openpipe fileevent} -body {
+    # not (*eol == '\n') 
+    set f [openpipe w+ $path(cat)]
+    chan configure $f -translation {auto lf} -buffering none
+    chan puts -nonewline $f "bbbbbbbbbbbbbbb\n123456789abcdef\r"
+    chan configure $f -buffersize 16
+    lappend x [chan gets $f]
+    chan configure $f -blocking 0
+    lappend x [chan gets $f line] $line [testchannel queuedcr $f] 
+    chan configure $f -blocking 1
+    chan puts -nonewline $f "abcd\refg\x1a"
+    lappend x [chan gets $f line] $line [testchannel queuedcr $f]
+    lappend x [chan gets $f line] $line
+} -cleanup {
+    chan close $f
+} -result {bbbbbbbbbbbbbbb 15 123456789abcdef 1 4 abcd 0 3 efg}
+test chan-io-6.45 {Tcl_GetsObj: input saw cr, skip right number of bytes} -setup {
+    set x ""
+} -constraints {stdio testchannel openpipe fileevent} -body {
+    # Tcl_ExternalToUtf()
+    set f [openpipe w+ $path(cat)]
+    chan configure $f -translation {auto lf} -buffering none
+    chan configure $f -encoding unicode
+    chan puts -nonewline $f "bbbbbbbbbbbbbbb\n123456789abcdef\r"
+    chan configure $f -buffersize 16
+    chan gets $f
+    chan configure $f -blocking 0
+    lappend x [chan gets $f line] $line [testchannel queuedcr $f]
+    chan configure $f -blocking 1
+    chan puts -nonewline $f "\nabcd\refg"
+    lappend x [chan gets $f line] $line [testchannel queuedcr $f]
+} -cleanup {
+    chan close $f
+} -result {15 123456789abcdef 1 4 abcd 0}
+test chan-io-6.46 {Tcl_GetsObj: input saw cr, followed by just \n should give eof} -setup {
+    set x ""
+} -constraints {stdio testchannel openpipe fileevent} -body {
+    # memmove()
+    set f [openpipe w+ $path(cat)]
+    chan configure $f -translation {auto lf} -buffering none
+    chan puts -nonewline $f "bbbbbbbbbbbbbbb\n123456789abcdef\r"
+    chan configure $f -buffersize 16
+    chan gets $f
+    chan configure $f -blocking 0
+    lappend x [chan gets $f line] $line [testchannel queuedcr $f]
+    chan configure $f -blocking 1
+    chan puts -nonewline $f "\n\x1a"
+    lappend x [chan gets $f line] $line [testchannel queuedcr $f]
+} -cleanup {
+    chan close $f
+} -result {15 123456789abcdef 1 -1 {} 0}
+test chan-io-6.47 {Tcl_GetsObj: auto mode: \r at end of buffer, peek for \n} -constraints {testchannel} -body {
+    # (eol == dstEnd)
+    set f [open $path(test1) w]
+    chan configure $f -translation lf
+    chan puts -nonewline $f "123456789012345\r\nabcdefghijklmnopq"
+    chan close $f
+    set f [open $path(test1)]
+    chan configure $f -translation auto -buffersize 16
+    list [chan gets $f] [testchannel inputbuffered $f]
+} -cleanup {
+    chan close $f
+} -result {123456789012345 15}
+test chan-io-6.48 {Tcl_GetsObj: auto mode: \r at end of buffer, no more avail} -constraints {testchannel} -body {
+    # PeekAhead() did not get any, so (eol >= dstEnd)
+    set f [open $path(test1) w]
+    chan configure $f -translation lf
+    chan puts -nonewline $f "123456789012345\r"
+    chan close $f
+    set f [open $path(test1)]
+    chan configure $f -translation auto -buffersize 16
+    list [chan gets $f] [testchannel queuedcr $f]
+} -cleanup {
+    chan close $f
+} -result {123456789012345 1}
+test chan-io-6.49 {Tcl_GetsObj: auto mode: \r followed by \n} -constraints {testchannel} -body {
+    # if (*eol == '\n') {skip++}
+    set f [open $path(test1) w]
+    chan configure $f -translation lf
+    chan puts -nonewline $f "123456\r\n78901"
+    chan close $f
+    set f [open $path(test1)]
+    list [chan gets $f] [testchannel queuedcr $f] [chan tell $f] [chan gets $f]
+} -cleanup {
+    chan close $f
+} -result {123456 0 8 78901}
+test chan-io-6.50 {Tcl_GetsObj: auto mode: \r not followed by \n} -constraints {testchannel} -body {
+    # not (*eol == '\n') 
+    set f [open $path(test1) w]
+    chan configure $f -translation lf
+    chan puts -nonewline $f "123456\r78901"
+    chan close $f
+    set f [open $path(test1)]
+    list [chan gets $f] [testchannel queuedcr $f] [chan tell $f] [chan gets $f]
+} -cleanup {
+    chan close $f
+} -result {123456 0 7 78901}
+test chan-io-6.51 {Tcl_GetsObj: auto mode: \n} -body {
+    # else if (*eol == '\n') {goto gotoeol;}
+    set f [open $path(test1) w]
+    chan configure $f -translation lf
+    chan puts -nonewline $f "123456\n78901"
+    chan close $f
+    set f [open $path(test1)]
+    list [chan gets $f] [chan tell $f] [chan gets $f]
+} -cleanup {
+    chan close $f
+} -result {123456 7 78901}
+test chan-io-6.52 {Tcl_GetsObj: saw EOF character} -constraints {testchannel} -body {
+    # if (eof != NULL)
+    set f [open $path(test1) w]
+    chan configure $f -translation lf
+    chan puts -nonewline $f "123456\x1ak9012345\r"
+    chan close $f
+    set f [open $path(test1)]
+    chan configure $f -eofchar \x1a
+    list [chan gets $f] [testchannel queuedcr $f] [chan tell $f] [chan gets $f]
+} -cleanup {
+    chan close $f
+} -result {123456 0 6 {}}
+test chan-io-6.53 {Tcl_GetsObj: device EOF} -body {
+    # didn't produce any bytes
+    set f [open $path(test1) w]
+    chan close $f
+    set f [open $path(test1)]
+    list [chan gets $f line] $line [chan eof $f]
+} -cleanup {
+    chan close $f
+} -result {-1 {} 1}
+test chan-io-6.54 {Tcl_GetsObj: device EOF} -body {
+    # got some bytes before EOF.
+    set f [open $path(test1) w]
+    chan puts -nonewline $f abc
+    chan close $f
+    set f [open $path(test1)]
+    list [chan gets $f line] $line [chan eof $f]
+} -cleanup {
+    chan close $f
+} -result {3 abc 1}
+test chan-io-6.55 {Tcl_GetsObj: overconverted} -body {
+    # Tcl_ExternalToUtf(), make sure state updated
+    set f [open $path(test1) w]
+    chan configure $f -encoding iso2022-jp
+    chan puts $f "there\u4e00ok\n\u4e01more bytes\nhere"
+    chan close $f
+    set f [open $path(test1)]
+    chan configure $f -encoding iso2022-jp
+    list [chan gets $f line] $line [chan gets $f line] $line [chan gets $f line] $line
+} -cleanup {
+    chan close $f
+} -result [list 8 "there\u4e00ok" 11 "\u4e01more bytes" 4 "here"]
+test chan-io-6.56 {Tcl_GetsObj: incomplete lines should disable file events} -setup {
+    update
+    variable x {}
+} -constraints {stdio openpipe fileevent} -body {
+    set f [openpipe w+ $path(cat)]
+    chan configure $f -buffering none
+    chan puts -nonewline $f "foobar"
+    chan configure $f -blocking 0
+    after 500 [namespace code {
+	lappend x timeout
+    }]
+    chan event $f readable [namespace code {
+	lappend x [chan gets $f]
+    }]
+    vwait [namespace which -variable x]
+    vwait [namespace which -variable x]
+    chan configure $f -blocking 1
+    chan puts -nonewline $f "baz\n"
+    after 500 [namespace code {
+	lappend x timeout
+    }]
+    chan configure $f -blocking 0
+    vwait [namespace which -variable x]
+    vwait [namespace which -variable x]
+    return $x
+} -cleanup {
+    chan close $f
+} -result {{} timeout foobarbaz timeout}
+
+test chan-io-7.1 {FilterInputBytes: split up character at end of buffer} -body {
+    # (result == TCL_CONVERT_MULTIBYTE)
+    set f [open $path(test1) w]
+    chan configure $f -encoding shiftjis
+    chan puts $f "1234567890123\uff10\uff11\uff12\uff13\uff14\nend"
+    chan close $f
+    set f [open $path(test1)]
+    chan configure $f -encoding shiftjis -buffersize 16
+    chan gets $f
+} -cleanup {
+    chan close $f
+} -result "1234567890123\uff10\uff11\uff12\uff13\uff14"
+test chan-io-7.2 {FilterInputBytes: split up character in middle of buffer} -body {
+    # (bufPtr->nextAdded < bufPtr->bufLength)
+    set f [open $path(test1) w]
+    chan configure $f -encoding binary
+    chan puts -nonewline $f "1234567890\n123\x82\x4f\x82\x50\x82"
+    chan close $f
+    set f [open $path(test1)]
+    chan configure $f -encoding shiftjis
+    list [chan gets $f line] $line [chan eof $f]
+} -cleanup {
+    chan close $f
+} -result {10 1234567890 0}
+test chan-io-7.3 {FilterInputBytes: split up character at EOF} -setup {
+    set x ""
+} -constraints {testchannel} -body {
+    set f [open $path(test1) w]
+    chan configure $f -encoding binary
+    chan puts -nonewline $f "1234567890123\x82\x4f\x82\x50\x82"
+    chan close $f
+    set f [open $path(test1)]
+    chan configure $f -encoding shiftjis
+    lappend x [chan gets $f line] $line
+    lappend x [chan tell $f] [testchannel inputbuffered $f] [chan eof $f]
+    lappend x [chan gets $f line] $line
+} -cleanup {
+    chan close $f
+} -result [list 15 "1234567890123\uff10\uff11" 18 0 1 -1 ""]
+test chan-io-7.4 {FilterInputBytes: recover from split up character} -setup {
+    variable x ""
+} -constraints {stdio openpipe fileevent} -body {
+    set f [openpipe w+ $path(cat)]
+    chan configure $f -encoding binary -buffering none
+    chan puts -nonewline $f "1234567890123\x82\x4f\x82\x50\x82"
+    chan configure $f -encoding shiftjis -blocking 0
+    chan event $f read [namespace code {
+	lappend x [chan gets $f line] $line [chan blocked $f]
+    }]
+    vwait [namespace which -variable x]
+    chan configure $f -encoding binary -blocking 1
+    chan puts $f "\x51\x82\x52"
+    chan configure $f -encoding shiftjis
+    vwait [namespace which -variable x]
+    return $x
+} -cleanup {
+    chan close $f
+} -result [list -1 "" 1 17 "1234567890123\uff10\uff11\uff12\uff13" 0]
+
+test chan-io-8.1 {PeekAhead: only go to device if no more cached data} -constraints {testchannel} -body {
+    # (bufPtr->nextPtr == NULL)
+    set f [open $path(test1) w]
+    chan configure $f -encoding ascii -translation lf
+    chan puts -nonewline $f "123456789012345\r\n2345678"
+    chan close $f
+    set f [open $path(test1)]
+    chan configure $f -encoding ascii -translation auto -buffersize 16
+    # here
+    chan gets $f
+    testchannel inputbuffered $f
+} -cleanup {
+    chan close $f
+} -result 7
+test chan-io-8.2 {PeekAhead: only go to device if no more cached data} -setup {
+    variable x {}
+} -constraints {stdio testchannel openpipe fileevent} -body {
+    # not (bufPtr->nextPtr == NULL)
+    set f [openpipe w+ $path(cat)]
+    chan configure $f -translation lf -encoding ascii -buffering none
+    chan puts -nonewline $f "123456789012345\r\nbcdefghijklmnopqrstuvwxyz"
+    chan event $f read [namespace code {
+	lappend x [chan gets $f line] $line [testchannel inputbuffered $f]
+    }]
+    chan configure $f -encoding unicode -buffersize 16 -blocking 0
+    vwait [namespace which -variable x]
+    chan configure $f -translation auto -encoding ascii -blocking 1
+    # here
+    vwait [namespace which -variable x]
+    return $x
+} -cleanup {
+    chan close $f
+} -result {-1 {} 42 15 123456789012345 25}
+test chan-io-8.3 {PeekAhead: no cached data available} -constraints {stdio testchannel openpipe fileevent} -body {
+    # (bytesLeft == 0)
+    set f [openpipe w+ $path(cat)]
+    chan configure $f -translation {auto binary}
+    chan puts -nonewline $f "abcdefghijklmno\r"
+    chan flush $f
+    list [chan gets $f line] $line [testchannel queuedcr $f]
+} -cleanup {
+    chan close $f
+} -result {15 abcdefghijklmno 1}
+set a "123456789012345678901234567890"
+append a "123456789012345678901234567890"
+append a "1234567890123456789012345678901"
+test chan-io-8.4 {PeekAhead: cached data available in this buffer} -body {
+    # not (bytesLeft == 0)
+    set f [open $path(test1) w+]
+    chan configure $f -translation binary
+    chan puts $f "${a}\r\nabcdef"
+    chan close $f
+    set f [open $path(test1)]
+    chan configure $f -encoding binary -translation auto
+    # "${a}\r" was converted in one operation (because ENCODING_LINESIZE is
+    # 30). To check if "\n" follows, calls PeekAhead and determines that
+    # cached data is available in buffer w/o having to call driver.
+    chan gets $f
+} -cleanup {
+    chan close $f
+} -result $a
+unset a
+test chan-io-8.5 {PeekAhead: don't peek if last read was short} -constraints {stdio testchannel openpipe fileevent} -body {
+    # (bufPtr->nextAdded < bufPtr->length)
+    set f [openpipe w+ $path(cat)]
+    chan configure $f -translation {auto binary}
+    chan puts -nonewline $f "abcdefghijklmno\r"
+    chan flush $f
+    # here
+    list [chan gets $f line] $line [testchannel queuedcr $f]
+} -cleanup {
+    chan close $f
+} -result {15 abcdefghijklmno 1}
+test chan-io-8.6 {PeekAhead: change to non-blocking mode} -constraints {stdio testchannel openpipe fileevent} -body {
+    # ((chanPtr->flags & CHANNEL_NONBLOCKING) == 0) 
+    set f [openpipe w+ $path(cat)]
+    chan configure $f -translation {auto binary} -buffersize 16
+    chan puts -nonewline $f "abcdefghijklmno\r"
+    chan flush $f
+    # here
+    list [chan gets $f line] $line [testchannel queuedcr $f]
+} -cleanup {
+    chan close $f
+} -result {15 abcdefghijklmno 1}
+test chan-io-8.7 {PeekAhead: cleanup} -setup {
+    set x ""
+} -constraints {stdio testchannel openpipe fileevent} -body {
+    # Make sure bytes are removed from buffer.
+    set f [openpipe w+ $path(cat)]
+    chan configure $f -translation {auto binary} -buffering none
+    chan puts -nonewline $f "abcdefghijklmno\r"
+    # here
+    lappend x [chan gets $f line] $line [testchannel queuedcr $f]
+    chan puts -nonewline $f "\x1a"
+    lappend x [chan gets $f line] $line
+} -cleanup {
+    chan close $f
+} -result {15 abcdefghijklmno 1 -1 {}}
+
+test chan-io-9.1 {CommonGetsCleanup} emptyTest {
+} {}
+
+test chan-io-10.1 {Tcl_ReadChars: CheckChannelErrors} emptyTest {
+    # no test, need to cause an async error.
+} {}
+test chan-io-10.2 {Tcl_ReadChars: loop until enough copied} -body {
+    # one time
+    # for (copied = 0; (unsigned) toRead > 0; )
+    set f [open $path(test1) w]
+    chan puts $f abcdefghijklmnop
+    chan close $f
+    set f [open $path(test1)]
+    chan read $f 5
+} -cleanup {
+    chan close $f
+} -result {abcde}
+test chan-io-10.3 {Tcl_ReadChars: loop until enough copied} -body {
+    # multiple times
+    # for (copied = 0; (unsigned) toRead > 0; )
+    set f [open $path(test1) w]
+    chan puts $f abcdefghijklmnopqrstuvwxyz
+    chan close $f
+    set f [open $path(test1)]
+    chan configure $f -buffersize 16
+    # here
+    chan read $f 19
+} -cleanup {
+    chan close $f
+} -result {abcdefghijklmnopqrs}
+test chan-io-10.4 {Tcl_ReadChars: no more in channel buffer} -body {
+    # (copiedNow < 0)
+    set f [open $path(test1) w]
+    chan puts -nonewline $f abcdefghijkl
+    chan close $f
+    set f [open $path(test1)]
+    # here
+    chan read $f 1000
+} -cleanup {
+    chan close $f
+} -result {abcdefghijkl}
+test chan-io-10.5 {Tcl_ReadChars: stop on EOF} -body {
+    # (chanPtr->flags & CHANNEL_EOF)
+    set f [open $path(test1) w]
+    chan puts -nonewline $f abcdefghijkl
+    chan close $f
+    set f [open $path(test1)]
+    # here
+    chan read $f 1000
+} -cleanup {
+    chan close $f
+} -result {abcdefghijkl}
+
+test chan-io-11.1 {ReadBytes: want to read a lot} -body {
+    # ((unsigned) toRead > (unsigned) srcLen)
+    set f [open $path(test1) w]
+    chan puts -nonewline $f abcdefghijkl
+    chan close $f
+    set f [open $path(test1)]
+    chan configure $f -encoding binary
+    # here
+    chan read $f 1000
+} -cleanup {
+    chan close $f
+} -result {abcdefghijkl}
+test chan-io-11.2 {ReadBytes: want to read all} -body {
+    # ((unsigned) toRead > (unsigned) srcLen)
+    set f [open $path(test1) w]
+    chan puts -nonewline $f abcdefghijkl
+    chan close $f
+    set f [open $path(test1)]
+    chan configure $f -encoding binary
+    # here
+    chan read $f
+} -cleanup {
+    chan close $f
+} -result {abcdefghijkl}
+test chan-io-11.3 {ReadBytes: allocate more space} -body {
+    # (toRead > length - offset - 1)
+    set f [open $path(test1) w]
+    chan puts -nonewline $f abcdefghijklmnopqrstuvwxyz
+    chan close $f
+    set f [open $path(test1)]
+    chan configure $f -buffersize 16 -encoding binary
+    # here
+    chan read $f
+} -cleanup {
+    chan close $f
+} -result {abcdefghijklmnopqrstuvwxyz}
+test chan-io-11.4 {ReadBytes: EOF char found} -body {
+    # (TranslateInputEOL() != 0)
+    set f [open $path(test1) w]
+    chan puts $f abcdefghijklmnopqrstuvwxyz
+    chan close $f
+    set f [open $path(test1)]
+    chan configure $f -eofchar m -encoding binary
+    # here
+    list [chan read $f] [chan eof $f] [chan read $f] [chan eof $f]
+} -cleanup {
+    chan close $f
+} -result {abcdefghijkl 1 {} 1}
+
+test chan-io-12.1 {ReadChars: want to read a lot} -body {
+    # ((unsigned) toRead > (unsigned) srcLen)
+    set f [open $path(test1) w]
+    chan puts -nonewline $f abcdefghijkl
+    chan close $f
+    set f [open $path(test1)]
+    # here
+    chan read $f 1000
+} -cleanup {
+    chan close $f
+} -result {abcdefghijkl}
+test chan-io-12.2 {ReadChars: want to read all} -body {
+    # ((unsigned) toRead > (unsigned) srcLen)
+    set f [open $path(test1) w]
+    chan puts -nonewline $f abcdefghijkl
+    chan close $f
+    set f [open $path(test1)]
+    # here
+    chan read $f
+} -cleanup {
+    chan close $f
+} -result {abcdefghijkl}
+test chan-io-12.3 {ReadChars: allocate more space} -body {
+    # (toRead > length - offset - 1)
+    set f [open $path(test1) w]
+    chan puts -nonewline $f abcdefghijklmnopqrstuvwxyz
+    chan close $f
+    set f [open $path(test1)]
+    chan configure $f -buffersize 16
+    # here
+    chan read $f
+} -cleanup {
+    chan close $f
+} -result {abcdefghijklmnopqrstuvwxyz}
+test chan-io-12.4 {ReadChars: split-up char} -setup {
+    variable x {}
+} -constraints {stdio testchannel openpipe fileevent} -body {
+    # (srcRead == 0)
+    set f [openpipe w+ $path(cat)]
+    chan configure $f -encoding binary -buffering none -buffersize 16
+    chan puts -nonewline $f "123456789012345\x96"
+    chan configure $f -encoding shiftjis -blocking 0
+    chan event $f read [namespace code {
+	lappend x [chan read $f] [testchannel inputbuffered $f]
+    }]
+    chan configure $f -encoding shiftjis
+    vwait [namespace which -variable x]
+    chan configure $f -encoding binary -blocking 1
+    chan puts -nonewline $f "\x7b"
+    after 500			;# Give the cat process time to catch up
+    chan configure $f -encoding shiftjis -blocking 0
+    vwait [namespace which -variable x]
+    return $x
+} -cleanup {
+    chan close $f
+} -result [list "123456789012345" 1 "\u672c" 0]
+test chan-io-12.5 {ReadChars: chan events on partial characters} -setup {
+    variable x {}
+} -constraints {stdio openpipe fileevent} -body {
+    set path(test1) [makeFile {
+	chan configure stdout -encoding binary -buffering none
+	chan gets stdin; chan puts -nonewline "\xe7"
+	chan gets stdin; chan puts -nonewline "\x89"
+	chan gets stdin; chan puts -nonewline "\xa6"
+    } test1]
+    set f [openpipe r+ $path(test1)]
+    chan event $f readable [namespace code {
+	lappend x [chan read $f]
+	if {[chan eof $f]} {
+	    lappend x eof
+	}
+    }]
+    chan puts $f "go1"
+    chan flush $f
+    chan configure $f -blocking 0 -encoding utf-8
+    vwait [namespace which -variable x]
+    after 500 [namespace code { lappend x timeout }]
+    vwait [namespace which -variable x]
+    chan puts $f "go2"
+    chan flush $f
+    vwait [namespace which -variable x]
+    after 500 [namespace code { lappend x timeout }]
+    vwait [namespace which -variable x]
+    chan puts $f "go3"
+    chan flush $f
+    vwait [namespace which -variable x]
+    vwait [namespace which -variable x]
+    lappend x [catch {chan close $f} msg] $msg
+} -result "{} timeout {} timeout \u7266 {} eof 0 {}"
+
+test chan-io-13.1 {TranslateInputEOL: cr mode} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation lf
+    chan puts -nonewline $f "abcd\rdef\r"
+    chan close $f
+    set f [open $path(test1)]
+    chan configure $f -translation cr
+    chan read $f
+} -cleanup {
+    chan close $f
+} -result "abcd\ndef\n"
+test chan-io-13.2 {TranslateInputEOL: crlf mode} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation lf
+    chan puts -nonewline $f "abcd\r\ndef\r\n"
+    chan close $f
+    set f [open $path(test1)]
+    chan configure $f -translation crlf
+    chan read $f
+} -cleanup {
+    chan close $f
+} -result "abcd\ndef\n"
+test chan-io-13.3 {TranslateInputEOL: crlf mode: naked cr} -body {
+    # (src >= srcMax) 
+    set f [open $path(test1) w]
+    chan configure $f -translation lf
+    chan puts -nonewline $f "abcd\r\ndef\r"
+    chan close $f
+    set f [open $path(test1)]
+    chan configure $f -translation crlf
+    chan read $f
+} -cleanup {
+    chan close $f
+} -result "abcd\ndef\r"
+test chan-io-13.4 {TranslateInputEOL: crlf mode: cr followed by not \n} -body {
+    # (src >= srcMax) 
+    set f [open $path(test1) w]
+    chan configure $f -translation lf
+    chan puts -nonewline $f "abcd\r\ndef\rfgh"
+    chan close $f
+    set f [open $path(test1)]
+    chan configure $f -translation crlf
+    chan read $f
+} -cleanup {
+    chan close $f
+} -result "abcd\ndef\rfgh"
+test chan-io-13.5 {TranslateInputEOL: crlf mode: naked lf} -body {
+    # (src >= srcMax) 
+    set f [open $path(test1) w]
+    chan configure $f -translation lf
+    chan puts -nonewline $f "abcd\r\ndef\nfgh"
+    chan close $f
+    set f [open $path(test1)]
+    chan configure $f -translation crlf
+    chan read $f
+} -cleanup {
+    chan close $f
+} -result "abcd\ndef\nfgh"
+test chan-io-13.6 {TranslateInputEOL: auto mode: saw cr in last segment} -setup {
+    variable x {}
+    variable y {}
+} -constraints {stdio testchannel openpipe fileevent} -body {
+    # (chanPtr->flags & INPUT_SAW_CR)
+    # This test may fail on slower machines.
+    set f [openpipe w+ $path(cat)]
+    chan configure $f -blocking 0 -buffering none -translation {auto lf}
+    chan event $f read [namespace code {
+	lappend x [chan read $f] [testchannel queuedcr $f]
+    }]
+    chan puts -nonewline $f "abcdefghj\r"
+    after 500 [namespace code {set y ok}]
+    vwait [namespace which -variable y]
+    chan puts -nonewline $f "\n01234"
+    after 500 [namespace code {set y ok}]
+    vwait [namespace which -variable y]
+    return $x
+} -cleanup {
+    chan close $f
+} -result [list "abcdefghj\n" 1 "01234" 0]
+test chan-io-13.7 {TranslateInputEOL: auto mode: naked \r} -constraints {testchannel openpipe} -body {
+    # (src >= srcMax)
+    set f [open $path(test1) w]
+    chan configure $f -translation lf
+    chan puts -nonewline $f "abcd\r"
+    chan close $f
+    set f [open $path(test1)]
+    chan configure $f -translation auto
+    list [chan read $f] [testchannel queuedcr $f]
+} -cleanup {
+    chan close $f
+} -result [list "abcd\n" 1]
+test chan-io-13.8 {TranslateInputEOL: auto mode: \r\n} -body {
+    # (*src == '\n')
+    set f [open $path(test1) w]
+    chan configure $f -translation lf
+    chan puts -nonewline $f "abcd\r\ndef"
+    chan close $f
+    set f [open $path(test1)]
+    chan configure $f -translation auto
+    chan read $f
+} -cleanup {
+    chan close $f
+} -result "abcd\ndef"
+test chan-io-13.9 {TranslateInputEOL: auto mode: \r followed by not \n} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation lf
+    chan puts -nonewline $f "abcd\rdef"
+    chan close $f
+    set f [open $path(test1)]
+    chan configure $f -translation auto
+    chan read $f
+} -cleanup {
+    chan close $f
+} -result "abcd\ndef"
+test chan-io-13.10 {TranslateInputEOL: auto mode: \n} -body {
+    # not (*src == '\r') 
+    set f [open $path(test1) w]
+    chan configure $f -translation lf
+    chan puts -nonewline $f "abcd\ndef"
+    chan close $f
+    set f [open $path(test1)]
+    chan configure $f -translation auto
+    chan read $f
+} -cleanup {
+    chan close $f
+} -result "abcd\ndef"
+test chan-io-13.11 {TranslateInputEOL: EOF char} -body {
+    # (*chanPtr->inEofChar != '\0')
+    set f [open $path(test1) w]
+    chan configure $f -translation lf
+    chan puts -nonewline $f "abcd\ndefgh"
+    chan close $f
+    set f [open $path(test1)]
+    chan configure $f -translation auto -eofchar e
+    chan read $f
+} -cleanup {
+    chan close $f
+} -result "abcd\nd"
+test chan-io-13.12 {TranslateInputEOL: find EOF char in src} -body {
+    # (*chanPtr->inEofChar != '\0')
+    set f [open $path(test1) w]
+    chan configure $f -translation lf
+    chan puts -nonewline $f "\r\n\r\n\r\nab\r\n\r\ndef\r\n\r\n\r\n"
+    chan close $f
+    set f [open $path(test1)]
+    chan configure $f -translation auto -eofchar e
+    chan read $f
+} -cleanup {
+    chan close $f
+} -result "\n\n\nab\n\nd"
+
+# Test standard handle management. The functions tested are Tcl_SetStdChannel
+# and Tcl_GetStdChannel. Incidentally we are also testing channel table
+# management.
+
+if {[testConstraint testchannel]} {
+    set consoleFileNames [lsort [testchannel open]]
+} else {
+    # just to avoid an error
+    set consoleFileNames [list]
+}
+
+test chan-io-14.1 {Tcl_SetStdChannel and Tcl_GetStdChannel} {testchannel} {
+    set result ""
+    lappend result [chan configure stdin -buffering]
+    lappend result [chan configure stdout -buffering]
+    lappend result [chan configure stderr -buffering]
+    lappend result [lsort [testchannel open]]
+} [list line line none $consoleFileNames]
+test chan-io-14.2 {Tcl_SetStdChannel and Tcl_GetStdChannel} -setup {
+    interp create x
+    set result ""
+} -body {
+    lappend result [x eval {chan configure stdin -buffering}]
+    lappend result [x eval {chan configure stdout -buffering}]
+    lappend result [x eval {chan configure stderr -buffering}]
+} -cleanup {
+    interp delete x
+} -result {line line none}
+set path(test3) [makeFile {} test3]
+test chan-io-14.3 {Tcl_SetStdChannel & Tcl_GetStdChannel} -constraints {exec openpipe} -body {
+    set f [open $path(test1) w]
+    chan puts -nonewline $f {
+	chan close stdin
+	chan close stdout
+	chan close stderr
+	set f  [}
+    chan puts $f [list open $path(test1) r]]
+    chan puts $f "set f2 \[[list open $path(test2) w]]"
+    chan puts $f "set f3 \[[list open $path(test3) w]]"
+    chan puts $f {	chan puts stdout [chan gets stdin]
+	chan puts stdout out
+	chan puts stderr err
+	chan close $f
+	chan close $f2
+	chan close $f3
+    }
+    chan close $f
+    set result [exec [interpreter] $path(test1)]
+    set f  [open $path(test2) r]
+    set f2 [open $path(test3) r]
+    lappend result [chan read $f] [chan read $f2]
+} -cleanup {
+    chan close $f
+    chan close $f2
+} -result {{
+out
+} {err
+}}
+# This test relies on the fact that stdout is used before stderr.
+test chan-io-14.4 {Tcl_SetStdChannel & Tcl_GetStdChannel} -constraints {exec} -body {
+    set f [open $path(test1) w]
+    chan puts -nonewline $f { chan close stdin
+	chan close stdout
+	chan close stderr
+	set f  [}
+    chan puts $f [list open $path(test1) r]]
+    chan puts $f "set f2 \[[list open $path(test2) w]]"
+    chan puts $f "set f3 \[[list open $path(test3) w]]"
+    chan puts $f {
+	chan puts stdout [chan gets stdin]
+	chan puts stdout $f2
+	chan puts stderr $f3
+	chan close $f
+	chan close $f2
+	chan close $f3
+    }
+    chan close $f
+    set result [exec [interpreter] $path(test1)]
+    set f  [open $path(test2) r]
+    set f2 [open $path(test3) r]
+    lappend result [chan read $f] [chan read $f2]
+} -cleanup {
+    chan close $f
+    chan close $f2
+} -result {{ chan close stdin
+stdout
+} {stderr
+}}
+catch {interp delete z}
+test chan-io-14.5 {Tcl_GetChannel: stdio name translation} -setup {
+    interp create z
+} -body {
+    chan eof stdin
+    catch {z eval chan flush stdin} msg1
+    catch {z eval chan close stdin} msg2
+    catch {z eval chan flush stdin} msg3
+    list $msg1 $msg2 $msg3
+} -cleanup {
+    interp delete z
+} -result {{channel "stdin" wasn't opened for writing} {} {can not find channel named "stdin"}}
+test chan-io-14.6 {Tcl_GetChannel: stdio name translation} -setup {
+    interp create z
+} -body {
+    chan eof stdout
+    catch {z eval chan flush stdout} msg1
+    catch {z eval chan close stdout} msg2
+    catch {z eval chan flush stdout} msg3
+    list $msg1 $msg2 $msg3
+} -cleanup {
+    interp delete z
+} -result {{} {} {can not find channel named "stdout"}}
+test chan-io-14.7 {Tcl_GetChannel: stdio name translation} -setup {
+    interp create z
+} -body {
+    chan eof stderr
+    catch {z eval chan flush stderr} msg1
+    catch {z eval chan close stderr} msg2
+    catch {z eval chan flush stderr} msg3
+    list $msg1 $msg2 $msg3
+} -cleanup {
+    interp delete z
+} -result {{} {} {can not find channel named "stderr"}}
+set path(script) [makeFile {} script]
+test chan-io-14.8 {reuse of stdio special channels} -setup {
+    file delete $path(script)
+    file delete $path(test1)
+} -constraints {stdio openpipe} -body {
+    set f [open $path(script) w]
+    chan puts -nonewline $f {
+	chan close stderr
+	set f [}
+    chan puts $f [list open $path(test1) w]]
+    chan puts -nonewline $f {
+	chan puts stderr hello
+	chan close $f
+	set f [}
+    chan puts $f [list open $path(test1) r]]
+    chan puts $f {
+	chan puts [chan gets $f]
+    }
+    chan close $f
+    set f [openpipe r $path(script)]
+    chan gets $f
+} -cleanup {
+    chan close $f
+} -result hello
+test chan-io-14.9 {reuse of stdio special channels} -setup {
+    file delete $path(script)
+    file delete $path(test1)
+} -constraints {stdio openpipe fileevent} -body {
+    set f [open $path(script) w]
+    chan puts $f {
+        array set path [lindex $argv 0]
+	set f [open $path(test1) w]
+	chan puts $f hello
+	chan close $f
+	chan close stderr
+	set f [open "|[list [info nameofexecutable] $path(cat) $path(test1)]" r]
+	chan puts [chan gets $f]
+    }
+    chan close $f
+    set f [openpipe r $path(script) [array get path]]
+    chan gets $f
+} -cleanup {
+    chan close $f
+    # Added delay to give Windows time to stop the spawned process and clean
+    # up its grip on the file test1. Added delete as proper test cleanup.
+    # The failing tests were 18.1 and 18.2 as first re-users of file "test1".
+    after [expr {[testConstraint win] ? 10000 : 500}]
+    file delete $path(script)
+    file delete $path(test1)
+} -result hello
+
+test chan-io-15.1 {Tcl_CreateChan CloseHandler} emptyTest {
+} {}
+
+test chan-io-16.1 {Tcl_DeleteChan CloseHandler} emptyTest {
+} {}
+
+# Test channel table management. The functions tested are GetChannelTable,
+# DeleteChannelTable, Tcl_RegisterChannel, Tcl_UnregisterChannel,
+# Tcl_GetChannel and Tcl_CreateChannel.
+#
+# These functions use "eof stdin" to ensure that the standard channels are
+# added to the channel table of the interpreter.
+
+test chan-io-17.1 {GetChannelTable, DeleteChannelTable on std handles} -setup {
+    set l ""
+} -constraints {testchannel} -body {
+    set l1 [testchannel refcount stdin]
+    chan eof stdin
+    interp create x
+    lappend l [expr {[testchannel refcount stdin] - $l1}]
+    x eval {chan eof stdin}
+    lappend l [expr {[testchannel refcount stdin] - $l1}]
+    interp delete x
+    lappend l [expr {[testchannel refcount stdin] - $l1}]
+} -result {0 1 0}
+test chan-io-17.2 {GetChannelTable, DeleteChannelTable on std handles} -setup  {
+    set l ""
+} -constraints {testchannel} -body {
+    set l1 [testchannel refcount stdout]
+    chan eof stdin
+    interp create x
+    lappend l [expr {[testchannel refcount stdout] - $l1}]
+    x eval {chan eof stdout}
+    lappend l [expr {[testchannel refcount stdout] - $l1}]
+    interp delete x
+    lappend l [expr {[testchannel refcount stdout] - $l1}]
+} -result {0 1 0}
+test chan-io-17.3 {GetChannelTable, DeleteChannelTable on std handles} -setup {
+    set l ""
+} -constraints {testchannel} -body {
+    set l1 [testchannel refcount stderr]
+    chan eof stdin
+    interp create x
+    lappend l [expr {[testchannel refcount stderr] - $l1}]
+    x eval {chan eof stderr}
+    lappend l [expr {[testchannel refcount stderr] - $l1}]
+    interp delete x
+    lappend l [expr {[testchannel refcount stderr] - $l1}]
+} -result {0 1 0}
+
+test chan-io-18.1 {Tcl_RegisterChannel, Tcl_UnregisterChannel} -setup {
+    file delete -force $path(test1)
+    set l ""
+} -constraints {testchannel} -body {
+    set f [open $path(test1) w]
+    lappend l [lindex [testchannel info $f] 15]
+    chan close $f
+    if {[catch {lindex [testchannel info $f] 15} msg]} {
+	lappend l $msg
+    } else {
+	lappend l "very broken: $f found after being chan closed"
+    }
+    string equal $l [list 1 "can not find channel named \"$f\""]
+} -result 1
+test chan-io-18.2 {Tcl_RegisterChannel, Tcl_UnregisterChannel} -setup {
+    file delete -force $path(test1)
+    set l ""
+} -constraints {testchannel} -body {
+    set f [open $path(test1) w]
+    lappend l [lindex [testchannel info $f] 15]
+    interp create x
+    interp share "" $f x
+    lappend l [lindex [testchannel info $f] 15]
+    x eval chan close $f
+    lappend l [lindex [testchannel info $f] 15]
+    interp delete x
+    lappend l [lindex [testchannel info $f] 15]
+    chan close $f
+    if {[catch {lindex [testchannel info $f] 15} msg]} {
+	lappend l $msg
+    } else {
+	lappend l "very broken: $f found after being chan closed"
+    }
+    string equal $l [list 1 2 1 1 "can not find channel named \"$f\""]
+} -result 1
+test chan-io-18.3 {Tcl_RegisterChannel, Tcl_UnregisterChannel} -setup {
+    file delete $path(test1)
+    set l ""
+} -constraints {testchannel} -body {
+    set f [open $path(test1) w]
+    lappend l [lindex [testchannel info $f] 15]
+    interp create x
+    interp share "" $f x
+    lappend l [lindex [testchannel info $f] 15]
+    interp delete x
+    lappend l [lindex [testchannel info $f] 15]
+    chan close $f
+    if {[catch {lindex [testchannel info $f] 15} msg]} {
+	lappend l $msg
+    } else {
+	lappend l "very broken: $f found after being chan closed"
+    }
+    string equal $l [list 1 2 1 "can not find channel named \"$f\""]
+} -result 1
+
+test chan-io-19.1 {Tcl_GetChannel->Tcl_GetStdChannel, standard handles} {
+    chan eof stdin
+} 0
+test chan-io-19.2 {testing Tcl_GetChannel, user opened handle} -setup {
+    file delete $path(test1)
+} -body {
+    set f [open $path(test1) w]
+    chan eof $f
+} -cleanup {
+    chan close $f
+} -result 0
+test chan-io-19.3 {Tcl_GetChannel, channel not found} -body {
+    chan eof file34
+} -returnCodes error -result {can not find channel named "file34"}
+test chan-io-19.4 {Tcl_CreateChannel, insertion into channel table} -setup {
+    file delete $path(test1)
+    set l ""
+} -constraints {testchannel} -body {
+    set f [open $path(test1) w]
+    lappend l [chan eof $f]
+    chan close $f
+    if {[catch {lindex [testchannel info $f] 15} msg]} {
+	lappend l $msg
+    } else {
+	lappend l "very broken: $f found after being chan closed"
+    }
+    string equal $l [list 0 "can not find channel named \"$f\""]
+} -result 1
+
+test chan-io-20.1 {Tcl_CreateChannel: initial settings} -setup {
+    set old [encoding system]
+} -body {
+    set a [open $path(test2) w]
+    encoding system ascii
+    set f [open $path(test1) w]
+    chan configure $f -encoding
+} -cleanup {
+    encoding system $old
+    chan close $f
+    chan close $a
+} -result {ascii}
+test chan-io-20.2 {Tcl_CreateChannel: initial settings} -constraints {win} -body {
+    set f [open $path(test1) w+]
+    list [chan configure $f -eofchar] [chan configure $f -translation]
+} -cleanup {
+    chan close $f
+} -result [list [list \x1a ""] {auto crlf}]
+test chan-io-20.3 {Tcl_CreateChannel: initial settings} -constraints {unix} -body {
+    set f [open $path(test1) w+]
+    list [chan configure $f -eofchar] [chan configure $f -translation]
+} -cleanup {
+    chan close $f
+} -result {{{} {}} {auto lf}}
+test chan-io-20.5 {Tcl_CreateChannel: install channel in empty slot} -setup {
+    set path(stdout) [makeFile {} stdout]
+} -constraints {stdio openpipe} -body {
+    set f [open $path(script) w]
+    chan puts -nonewline $f {
+	chan close stdout
+	set f1 [}
+    chan puts $f [list open $path(stdout) w]]
+    chan puts $f {
+	chan configure $f1 -buffersize 777
+	chan puts stderr [chan configure stdout -buffersize]
+    }
+    chan close $f
+    set f [openpipe r $path(script)]
+    chan close $f
+} -cleanup {
+    removeFile $path(stdout)
+} -returnCodes error -result {777}
+
+test chan-io-21.1 {Chan CloseChannelsOnExit} emptyTest {
+} {}
+
+# Test management of attributes associated with a channel, such as its default
+# translation, its name and type, etc. The functions tested in this group are
+# Tcl_GetChannelName, Tcl_GetChannelType and Tcl_GetChannelFile.
+# Tcl_GetChannelInstanceData not tested because files do not use the instance
+# data.
+
+test chan-io-22.1 {Tcl_GetChannelMode} emptyTest {
+    # Not used anywhere in Tcl.
+} {}
+
+test chan-io-23.1 {Tcl_GetChannelName} -constraints {testchannel} -setup {
+    file delete $path(test1)
+} -body {
+    set f [open $path(test1) w]
+    set n [testchannel name $f]
+    expr {$n eq $f ? "ok" : "$n != $f"}
+} -cleanup {
+    chan close $f
+} -result ok
+
+test chan-io-24.1 {Tcl_GetChannelType} -constraints {testchannel} -setup {
+    file delete $path(test1)
+} -body {
+    set f [open $path(test1) w]
+    testchannel type $f
+} -cleanup {
+    chan close $f
+} -result "file"
+
+test chan-io-25.1 {Tcl_GetChannelHandle, input} -setup {
+    set l ""
+} -constraints {testchannel} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation lf -eofchar {}
+    chan puts $f "1234567890\n098765432"
+    chan close $f
+    set f [open $path(test1) r]
+    chan gets $f
+    lappend l [testchannel inputbuffered $f]
+    lappend l [chan tell $f]
+} -cleanup {
+    chan close $f
+} -result {10 11}
+test chan-io-25.2 {Tcl_GetChannelHandle, output} -setup {
+    file delete $path(test1)
+    set l ""
+} -constraints {testchannel} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation lf
+    chan puts $f hello
+    lappend l [testchannel outputbuffered $f]
+    lappend l [chan tell $f]
+    chan flush $f
+    lappend l [testchannel outputbuffered $f]
+    lappend l [chan tell $f]
+} -cleanup {
+    chan close $f
+    file delete $path(test1)
+} -result {6 6 0 6}
+
+test chan-io-26.1 {Tcl_GetChannelInstanceData} -body {
+    # "pid" command uses Tcl_GetChannelInstanceData
+    # Don't care what pid is (but must be a number), just want to exercise it.
+    set f [openpipe r << exit]
+    pid $f
+} -constraints {stdio openpipe} -cleanup {
+    chan close $f
+} -match regexp -result {^\d+$}
+
+# Test flushing. The functions tested here are FlushChannel.
+
+test chan-io-27.1 {FlushChannel, no output buffered} -setup {
+    file delete $path(test1)
+} -body {
+    set f [open $path(test1) w]
+    chan flush $f
+    file size $path(test1)
+} -cleanup {
+    chan close $f
+} -result 0
+test chan-io-27.2 {FlushChannel, some output buffered} -setup {
+    file delete $path(test1)
+    set l ""
+} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation lf -eofchar {}
+    chan puts $f hello
+    lappend l [file size $path(test1)]
+    chan flush $f
+    lappend l [file size $path(test1)]
+    chan close $f
+    lappend l [file size $path(test1)]
+} -result {0 6 6}
+test chan-io-27.3 {FlushChannel, implicit flush on chan close} -setup {
+    file delete $path(test1)
+    set l ""
+} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation lf -eofchar {}
+    chan puts $f hello
+    lappend l [file size $path(test1)]
+    chan close $f
+    lappend l [file size $path(test1)]
+} -result {0 6}
+test chan-io-27.4 {FlushChannel, implicit flush when buffer fills} -setup {
+    file delete $path(test1)
+    set l ""
+} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation lf -eofchar {}
+    chan configure $f -buffersize 60
+    lappend l [file size $path(test1)]
+    for {set i 0} {$i < 12} {incr i} {
+	chan puts $f hello
+    }
+    lappend l [file size $path(test1)]
+    chan flush $f
+    lappend l [file size $path(test1)]
+} -cleanup {
+    chan close $f
+} -result {0 60 72}
+test chan-io-27.5 {FlushChannel, implicit flush when buffer fills and on chan close} -setup {
+    file delete $path(test1)
+    set l ""
+} -constraints {unixOrPc} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation lf -buffersize 60 -eofchar {}
+    lappend l [file size $path(test1)]
+    for {set i 0} {$i < 12} {incr i} {
+	chan puts $f hello
+    }
+    lappend l [file size $path(test1)]
+    chan close $f
+    lappend l [file size $path(test1)]
+} -result {0 60 72}
+set path(pipe)   [makeFile {} pipe]
+set path(output) [makeFile {} output]
+test chan-io-27.6 {FlushChannel, async flushing, async chan close} -setup {
+    file delete $path(pipe)
+    file delete $path(output)
+} -constraints {stdio asyncPipeChan Close openpipe} -body {
+    set f [open $path(pipe) w]
+    chan puts $f "set f \[[list open $path(output) w]]"
+    chan puts $f {
+	chan configure $f -translation lf -buffering none -eofchar {}
+	while {![chan eof stdin]} {
+	    after 20
+	    chan puts -nonewline $f [chan read stdin 1024]
+	}
+	chan close $f
+    }
+    chan close $f
+    set x 01234567890123456789012345678901
+    for {set i 0} {$i < 11} {incr i} {
+        set x "$x$x"
+    }
+    set f [open $path(output) w]
+    chan close $f
+    set f [openpipe w $path(pipe)]
+    chan configure $f -blocking off
+    chan puts -nonewline $f $x
+    chan close $f
+    set counter 0
+    while {([file size $path(output)] < 65536) && ($counter < 1000)} {
+	after 20 [list incr [namespace which -variable counter]]
+	vwait [namespace which -variable counter]
+    }
+    if {$counter == 1000} {
+        set result "file size only [file size $path(output)]"
+    } else {
+        set result ok
+    }
+} -result ok
+
+# Tests closing a channel. The functions tested are Chan CloseChannel and
+# Tcl_Chan Close.
+
+test chan-io-28.1 {Chan CloseChannel called when all references are dropped} -setup {
+    file delete $path(test1)
+    set l ""
+} -constraints {testchannel} -body {
+    set f [open $path(test1) w]
+    interp create x
+    interp share "" $f x
+    lappend l [testchannel refcount $f]
+    x eval chan close $f
+    interp delete x
+    lappend l [testchannel refcount $f]
+} -cleanup {
+    chan close $f
+} -result {2 1}
+test chan-io-28.2 {Chan CloseChannel called when all references are dropped} -setup {
+    file delete $path(test1)
+} -body {
+    set f [open $path(test1) w]
+    interp create x
+    interp share "" $f x
+    chan puts -nonewline $f abc
+    chan close $f
+    x eval chan puts $f def
+    x eval chan close $f
+    interp delete x
+    set f [open $path(test1) r]
+    chan gets $f
+} -cleanup {
+    chan close $f
+} -result abcdef
+test chan-io-28.3 {Chan CloseChannel, not called before output queue is empty} -setup {
+    file delete $path(pipe)
+    file delete $path(output)
+} -constraints {stdio asyncPipeChan Close nonPortable openpipe} -body {
+    set f [open $path(pipe) w]
+    chan puts $f {
+	# Need to not have eof char appended on chan close, because the other
+	# side of the pipe already chan closed, so that writing would cause an
+	# error "invalid file".
+	chan configure stdout -eofchar {}
+	chan configure stderr -eofchar {}
+	set f [open $path(output) w]
+	chan configure $f -translation lf -buffering none
+	for {set x 0} {$x < 20} {incr x} {
+	    after 20
+	    chan puts -nonewline $f [chan read stdin 1024]
+	}
+	chan close $f
+    }
+    chan close $f
+    set x 01234567890123456789012345678901
+    for {set i 0} {$i < 11} {incr i} {
+        set x "$x$x"
+    }
+    set f [open $path(output) w]
+    chan close $f
+    set f [openpipe r+ $path(pipe)]
+    chan configure $f -blocking off -eofchar {}
+    chan puts -nonewline $f $x
+    chan close $f
+    set counter 0
+    while {([file size $path(output)] < 20480) && ($counter < 1000)} {
+	after 20 [list incr [namespace which -variable counter]]
+	vwait [namespace which -variable counter]
+    }
+    if {$counter == 1000} {
+        set result probably_broken
+    } else {
+        set result ok
+    }
+} -result ok
+test chan-io-28.4 {Tcl_Chan Close} -constraints {testchannel} -setup {
+    file delete $path(test1)
+    set l ""
+} -body {
+    lappend l [lsort [testchannel open]]
+    set f [open $path(test1) w]
+    lappend l [lsort [testchannel open]]
+    chan close $f
+    lappend l [lsort [testchannel open]]
+    set x [list $consoleFileNames \
+		[lsort [list {*}$consoleFileNames $f]] \
+		$consoleFileNames]
+    expr {$l eq $x ? "ok" : "{$l} != {$x}"}
+} -result ok
+test chan-io-28.5 {Tcl_Chan Close vs standard handles} -setup {
+    file delete $path(script)
+} -constraints {stdio unix testchannel openpipe} -body {
+    set f [open $path(script) w]
+    chan puts $f {
+	chan close stdin
+	chan puts [testchannel open]
+    }
+    chan close $f
+    set f [openpipe r $path(script)]
+    set l [chan gets $f]
+    chan close $f
+    lsort $l
+} -result {file1 file2}
+test chan-io-28.6 {Tcl_CloseEx (half-close) pipe} -setup {
+    set cat [makeFile {
+	fconfigure stdout -buffering line
+	while {[gets stdin line] >= 0} {puts $line}
+	puts DONE
+	exit 0
+    } cat.tcl]
+    variable done
+} -body {
+    set ff [openpipe r+ $cat]
+    puts $ff Hey
+    close $ff w
+    set timer [after 1000 [namespace code {set done Failed}]]
+    set acc {}
+    fileevent $ff readable [namespace code {
+	if {[gets $ff line] < 0} {
+	    set done Succeeded
+	} else {
+	    lappend acc $line
+	}
+    }]
+    vwait [namespace which -variable done]
+    after cancel $timer
+    close $ff r
+    list $done $acc
+} -cleanup {
+    removeFile cat.tcl
+} -result {Succeeded {Hey DONE}}
+test chan-io-28.7 {Tcl_CloseEx (half-close) socket} -setup {
+    set echo [makeFile {
+	proc accept {s args} {set ::sok $s}
+	set s [socket -server accept 0]
+	puts [lindex [fconfigure $s -sockname] 2]
+	flush stdout
+	vwait ::sok
+	fconfigure $sok -buffering line
+	while {[gets $sok line]>=0} {puts $sok $line}
+	puts $sok DONE
+	exit 0
+    } echo.tcl]
+    variable done
+    unset -nocomplain done
+    set done ""
+    set timer ""
+    set ff [openpipe r $echo]
+    gets $ff port
+} -body {
+    set s [socket 127.0.0.1 $port]
+    puts $s Hey
+    close $s w
+    set timer [after 1000 [namespace code {set done Failed}]]
+    set acc {}
+    fileevent $s readable [namespace code {
+	if {[gets $s line]<0} {
+	    set done Succeeded
+	} else {
+	    lappend acc $line
+	}
+    }]
+    vwait [namespace which -variable done]
+    list $done $acc
+} -cleanup {
+    catch {close $s}
+    close $ff
+    after cancel $timer
+    removeFile echo.tcl
+} -result {Succeeded {Hey DONE}}
+
+test chan-io-29.1 {Tcl_WriteChars, channel not writable} -body {
+    chan puts stdin hello
+} -returnCodes error -result {channel "stdin" wasn't opened for writing}
+test chan-io-29.2 {Tcl_WriteChars, empty string} -setup {
+    file delete $path(test1)
+} -body {
+    set f [open $path(test1) w]
+    chan configure $f -eofchar {}
+    chan puts -nonewline $f ""
+    chan close $f
+    file size $path(test1)
+} -result 0
+test chan-io-29.3 {Tcl_WriteChars, nonempty string} -setup {
+    file delete $path(test1)
+} -body {
+    set f [open $path(test1) w]
+    chan configure $f -eofchar {}
+    chan puts -nonewline $f hello
+    chan close $f
+    file size $path(test1)
+} -result 5
+test chan-io-29.4 {Tcl_WriteChars, buffering in full buffering mode} -setup {
+    file delete $path(test1)
+    set l ""
+} -constraints {testchannel} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation lf -buffering full -eofchar {}
+    chan puts $f hello
+    lappend l [testchannel outputbuffered $f]
+    lappend l [file size $path(test1)]
+    chan flush $f
+    lappend l [testchannel outputbuffered $f]
+    lappend l [file size $path(test1)]
+} -cleanup {
+    chan close $f
+} -result {6 0 0 6}
+test chan-io-29.5 {Tcl_WriteChars, buffering in line buffering mode} -setup {
+    file delete $path(test1)
+    set l ""
+} -constraints {testchannel} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation lf -buffering line -eofchar {}
+    chan puts -nonewline $f hello
+    lappend l [testchannel outputbuffered $f]
+    lappend l [file size $path(test1)]
+    chan puts $f hello
+    lappend l [testchannel outputbuffered $f]
+    lappend l [file size $path(test1)]
+} -cleanup {
+    chan close $f
+} -result {5 0 0 11}
+test chan-io-29.6 {Tcl_WriteChars, buffering in no buffering mode} -setup {
+    file delete $path(test1)
+    set l ""
+} -constraints {testchannel} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation lf -buffering none -eofchar {}
+    chan puts -nonewline $f hello
+    lappend l [testchannel outputbuffered $f]
+    lappend l [file size $path(test1)]
+    chan puts $f hello
+    lappend l [testchannel outputbuffered $f]
+    lappend l [file size $path(test1)]
+} -cleanup {
+    chan close $f
+} -result {0 5 0 11}
+test chan-io-29.7 {Tcl_Flush, full buffering} -setup {
+    file delete $path(test1)
+    set l ""
+} -constraints {testchannel} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation lf -buffering full -eofchar {}
+    chan puts -nonewline $f hello
+    lappend l [testchannel outputbuffered $f]
+    lappend l [file size $path(test1)]
+    chan puts $f hello
+    lappend l [testchannel outputbuffered $f]
+    lappend l [file size $path(test1)]
+    chan flush $f
+    lappend l [testchannel outputbuffered $f]
+    lappend l [file size $path(test1)]
+} -cleanup {
+    chan close $f
+} -result {5 0 11 0 0 11}
+test chan-io-29.8 {Tcl_Flush, full buffering} -setup {
+    file delete $path(test1)
+    set l ""
+} -constraints {testchannel} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation lf -buffering line
+    chan puts -nonewline $f hello
+    lappend l [testchannel outputbuffered $f]
+    lappend l [file size $path(test1)]
+    chan flush $f
+    lappend l [testchannel outputbuffered $f]
+    lappend l [file size $path(test1)]
+    chan puts $f hello
+    lappend l [testchannel outputbuffered $f]
+    lappend l [file size $path(test1)]
+    chan flush $f
+    lappend l [testchannel outputbuffered $f]
+    lappend l [file size $path(test1)]
+} -cleanup {
+    chan close $f
+} -result {5 0 0 5 0 11 0 11}
+test chan-io-29.9 {Tcl_Flush, channel not writable} -body {
+    chan flush stdin
+} -returnCodes error -result {channel "stdin" wasn't opened for writing}
+test chan-io-29.10 {Tcl_WriteChars, looping and buffering} -setup {
+    file delete $path(test1)
+} -body {
+    set f1 [open $path(test1) w]
+    chan configure $f1 -translation lf -eofchar {}
+    set f2 [open $path(longfile) r]
+    for {set x 0} {$x < 10} {incr x} {
+	chan puts $f1 [chan gets $f2]
+    }
+    chan close $f2
+    chan close $f1
+    file size $path(test1)
+} -result 387
+test chan-io-29.11 {Tcl_WriteChars, no newline, implicit flush} -setup {
+    file delete $path(test1)
+} -body {
+    set f1 [open $path(test1) w]
+    chan configure $f1 -eofchar {}
+    set f2 [open $path(longfile) r]
+    for {set x 0} {$x < 10} {incr x} {
+	chan puts -nonewline $f1 [chan gets $f2]
+    }
+    chan close $f1
+    chan close $f2
+    file size $path(test1)
+} -result 377
+test chan-io-29.12 {Tcl_WriteChars on a pipe} -setup {
+    file delete $path(test1)
+    file delete $path(pipe)
+} -constraints {stdio openpipe} -body {
+    set f1 [open $path(pipe) w]
+    chan puts $f1 "set f1 \[[list open $path(longfile) r]]"
+    chan puts $f1 {
+	for {set x 0} {$x < 10} {incr x} {
+	    chan puts [chan gets $f1]
+	}
+    }
+    chan close $f1
+    set f1 [openpipe r $path(pipe)]
+    set f2 [open $path(longfile) r]
+    set y ok
+    for {set x 0} {$x < 10} {incr x} {
+	set l1 [chan gets $f1]
+	set l2 [chan gets $f2]
+	if {$l1 ne $l2} {
+	    set y broken:$x
+	}
+    }
+    return $y
+} -cleanup {
+    chan close $f1
+    chan close $f2
+} -result ok
+test chan-io-29.13 {Tcl_WriteChars to a pipe, line buffered} -setup {
+    file delete $path(test1)
+    file delete $path(pipe)
+} -constraints {stdio openpipe} -body {
+    set f1 [open $path(pipe) w]
+    chan puts $f1 {
+	chan puts [chan gets stdin]
+	chan puts [chan gets stdin]
+    }
+    chan close $f1
+    set y ok
+    set f1 [openpipe r+ $path(pipe)]
+    chan configure $f1 -buffering line
+    set f2 [open $path(longfile) r]
+    set line [chan gets $f2]
+    chan puts $f1 $line
+    set backline [chan gets $f1]
+    if {$line ne $backline} {
+	set y broken1
+    }
+    set line [chan gets $f2]
+    chan puts $f1 $line
+    set backline [chan gets $f1]
+    if {$line ne $backline} {
+	set y broken2
+    }
+    return $y
+} -cleanup {
+    chan close $f1
+    chan close $f2
+} -result ok
+test chan-io-29.14 {Tcl_WriteChars, buffering and implicit flush at chan close} -setup {
+    file delete $path(test3)
+} -body {
+    set f [open $path(test3) w]
+    chan puts -nonewline $f "Text1"
+    chan puts -nonewline $f " Text 2"
+    chan puts $f " Text 3"
+    chan close $f
+    set f [open $path(test3) r]
+    chan gets $f
+} -cleanup {
+    chan close $f
+} -result {Text1 Text 2 Text 3}
+test chan-io-29.15 {Tcl_Flush, channel not open for writing} -setup {
+    file delete $path(test1)
+    set fd [open $path(test1) w]
+    chan close $fd
+} -body {
+    set fd [open $path(test1) r]
+    chan flush $fd
+} -returnCodes error -cleanup {
+    catch {chan close $fd}
+} -match glob -result {channel "*" wasn't opened for writing}
+test chan-io-29.16 {Tcl_Flush on pipe opened only for reading} -setup {
+    set fd [openpipe r cat longfile]
+} -constraints {stdio openpipe} -body {
+    chan flush $fd
+} -returnCodes error -cleanup {
+    catch {chan close $fd}
+} -match glob -result {channel "*" wasn't opened for writing}
+test chan-io-29.17 {Tcl_WriteChars buffers, then Tcl_Flush flushes} -setup {
+    file delete $path(test1)
+} -body {
+    set f1 [open $path(test1) w]
+    chan configure $f1 -translation lf
+    chan puts $f1 hello
+    chan puts $f1 hello
+    chan puts $f1 hello
+    chan flush $f1
+    file size $path(test1)
+} -cleanup {
+    chan close $f1
+} -result 18
+test chan-io-29.18 {Tcl_WriteChars and Tcl_Flush intermixed} -setup {
+    file delete $path(test1)
+    set x ""
+    set f1 [open $path(test1) w]
+} -body {
+    chan configure $f1 -translation lf
+    chan puts $f1 hello
+    chan puts $f1 hello
+    chan puts $f1 hello
+    chan flush $f1
+    lappend x [file size $path(test1)]
+    chan puts $f1 hello
+    chan flush $f1
+    lappend x [file size $path(test1)]
+    chan puts $f1 hello
+    chan flush $f1
+    lappend x [file size $path(test1)]
+} -cleanup {
+    chan close $f1
+} -result {18 24 30}
+test chan-io-29.19 {Explicit and implicit flushes} -setup {
+    file delete $path(test1)
+} -body {
+    set f1 [open $path(test1) w]
+    chan configure $f1 -translation lf -eofchar {}
+    set x ""
+    chan puts $f1 hello
+    chan puts $f1 hello
+    chan puts $f1 hello
+    chan flush $f1
+    lappend x [file size $path(test1)]
+    chan puts $f1 hello
+    chan flush $f1
+    lappend x [file size $path(test1)]
+    chan puts $f1 hello
+    chan close $f1
+    lappend x [file size $path(test1)]
+} -result {18 24 30}
+test chan-io-29.20 {Implicit flush when buffer is full} -setup {
+    file delete $path(test1)
+} -body {
+    set f1 [open $path(test1) w]
+    chan configure $f1 -translation lf -eofchar {}
+    set line "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
+    for {set x 0} {$x < 100} {incr x} {
+      chan puts $f1 $line
+    }
+    set z ""
+    lappend z [file size $path(test1)]
+    for {set x 0} {$x < 100} {incr x} {
+	chan puts $f1 $line
+    }
+    lappend z [file size $path(test1)]
+    chan close $f1
+    lappend z [file size $path(test1)]
+} -result {4096 12288 12600}
+test chan-io-29.21 {Tcl_Flush to pipe} -setup {
+    file delete $path(pipe)
+} -constraints {stdio openpipe} -body {
+    set f1 [open $path(pipe) w]
+    chan puts $f1 {set x [chan read stdin 6]}
+    chan puts $f1 {set cnt [string length $x]}
+    chan puts $f1 {chan puts "read $cnt characters"}
+    chan close $f1
+    set f1 [openpipe r+ $path(pipe)]
+    chan puts $f1 hello
+    chan flush $f1
+    chan gets $f1
+} -cleanup {
+    catch {chan close $f1}
+} -result "read 6 characters"
+test chan-io-29.22 {Tcl_Flush called at other end of pipe} -setup {
+    file delete $path(pipe)
+} -constraints {stdio openpipe} -body {
+    set f1 [open $path(pipe) w]
+    chan puts $f1 {
+	chan configure stdout -buffering full
+	chan puts hello
+	chan puts hello
+	chan flush stdout
+	chan gets stdin
+	chan puts bye
+	chan flush stdout
+    }
+    chan close $f1
+    set f1 [openpipe r+ $path(pipe)]
+    set x ""
+    lappend x [chan gets $f1]
+    lappend x [chan gets $f1]
+    chan puts $f1 hello
+    chan flush $f1
+    lappend x [chan gets $f1]
+} -cleanup {
+    chan close $f1
+} -result {hello hello bye}
+test chan-io-29.23 {Tcl_Flush and line buffering at end of pipe} -setup {
+    file delete $path(pipe)
+} -constraints {stdio openpipe} -body {
+    set f1 [open $path(pipe) w]
+    chan puts $f1 {
+	chan puts hello
+	chan puts hello
+	chan gets stdin
+	chan puts bye
+    }
+    chan close $f1
+    set f1 [openpipe r+ $path(pipe)]
+    set x ""
+    lappend x [chan gets $f1]
+    lappend x [chan gets $f1]
+    chan puts $f1 hello
+    chan flush $f1
+    lappend x [chan gets $f1]
+} -cleanup {
+    chan close $f1
+} -result {hello hello bye}
+test chan-io-29.24 {Tcl_WriteChars and Tcl_Flush move end of file} -setup {
+    variable x {}
+} -body {
+    set f [open $path(test3) w]
+    chan puts $f "Line 1"
+    chan puts $f "Line 2"
+    set f2 [open $path(test3)]
+    lappend x [chan read -nonewline $f2]
+    chan close $f2
+    chan flush $f
+    set f2 [open $path(test3)]
+    lappend x [chan read -nonewline $f2]
+} -cleanup {
+    chan close $f2
+    chan close $f
+} -result "{} {Line 1\nLine 2}"
+test chan-io-29.25 {Implicit flush with Tcl_Flush to command pipelines} -setup {
+    file delete $path(test3)
+} -constraints {stdio openpipe fileevent} -body {
+    set f [openpipe w $path(cat) | [interpreter] $path(cat) > $path(test3)]
+    chan puts $f "Line 1"
+    chan puts $f "Line 2"
+    chan close $f
+    after 100
+    set f [open $path(test3) r]
+    chan read $f
+} -cleanup {
+    chan close $f
+} -result "Line 1\nLine 2\n"
+test chan-io-29.26 {Tcl_Flush, Tcl_Write on bidirectional pipelines} -constraints {stdio unixExecs openpipe} -body {
+    set f [open "|[list cat -u]" r+]
+    chan puts $f "Line1"
+    chan flush $f
+    chan gets $f
+} -cleanup {
+    chan close $f
+} -result {Line1}
+test chan-io-29.27 {Tcl_Flush on chan closed pipeline} -setup {
+    file delete $path(pipe)
+    set f [open $path(pipe) w]
+    chan puts $f {exit}
+    chan close $f
+} -constraints {stdio openpipe} -body {
+    set f [openpipe r+ $path(pipe)]
+    chan gets $f
+    chan puts $f output
+    after 50
+    #
+    # The flush below will get a SIGPIPE. This is an expected part of the test
+    # and indicates that the test operates correctly. If you run this test
+    # under a debugger, the signal will by intercepted unless you disable the
+    # debugger's signal interception.
+    #
+    if {[catch {chan flush $f} msg]} {
+	set x [list 1 $msg $::errorCode]
+	catch {chan close $f}
+    } elseif {[catch {chan close $f} msg]} {
+	set x [list 1 $msg $::errorCode]
+    } else {
+	set x {this was supposed to fail and did not}
+    }
+    string tolower $x
+} -match glob -result {1 {error flushing "*": broken pipe} {posix epipe {broken pipe}}}
+test chan-io-29.28 {Tcl_WriteChars, lf mode} -setup {
+    file delete $path(test1)
+} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation lf -eofchar {}
+    chan puts $f hello\nthere\nand\nhere
+    chan flush $f
+    file size $path(test1)
+} -cleanup {
+    chan close $f
+} -result 21
+test chan-io-29.29 {Tcl_WriteChars, cr mode} -setup {
+    file delete $path(test1)
+} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation cr -eofchar {}
+    chan puts $f hello\nthere\nand\nhere
+    chan close $f
+    file size $path(test1)
+} -result 21
+test chan-io-29.30 {Tcl_WriteChars, crlf mode} -setup {
+    file delete $path(test1)
+} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation crlf -eofchar {}
+    chan puts $f hello\nthere\nand\nhere
+    chan close $f
+    file size $path(test1)
+} -result 25
+test chan-io-29.31 {Tcl_WriteChars, background flush} -setup {
+    file delete $path(pipe)
+    file delete $path(output)
+} -constraints {stdio openpipe} -body {
+    set f [open $path(pipe) w]
+    chan puts $f "set f \[[list open $path(output)  w]]"
+    chan puts $f {chan configure $f -translation lf}
+    set x [list while {![chan eof stdin]}]
+    set x "$x {"
+    chan puts $f $x
+    chan puts $f {  chan puts -nonewline $f [chan read stdin 4096]}
+    chan puts $f {  chan flush $f}
+    chan puts $f "}"
+    chan puts $f {chan close $f}
+    chan close $f
+    set x 01234567890123456789012345678901
+    for {set i 0} {$i < 11} {incr i} {
+	set x "$x$x"
+    }
+    set f [open $path(output) w]
+    chan close $f
+    set f [openpipe r+ $path(pipe)]
+    chan configure $f -blocking off
+    chan puts -nonewline $f $x
+    chan close $f
+    set counter 0
+    while {([file size $path(output)] < 65536) && ($counter < 1000)} {
+	after 10 [list incr [namespace which -variable counter]]
+	vwait [namespace which -variable counter]
+    }
+    if {$counter == 1000} {
+	set result "file size only [file size $path(output)]"
+    } else {
+	set result ok
+    }
+    # allow a little time for the background process to chan close.
+    # otherwise, the following test fails on the [file delete $path(output)
+    # on Windows because a process still has the file open.
+    after 100 set v 1; vwait v
+    return $result
+} -result ok
+test chan-io-29.32 {Tcl_WriteChars, background flush to slow reader} -setup {
+    file delete $path(pipe)
+    file delete $path(output)
+} -constraints {stdio asyncPipeChan Close openpipe} -body {
+    set f [open $path(pipe) w]
+    chan puts $f "set f \[[list open $path(output) w]]"
+    chan puts $f {chan configure $f -translation lf}
+    set x [list while {![chan eof stdin]}]
+    set x "$x \{"
+    chan puts $f $x
+    chan puts $f {  after 20}
+    chan puts $f {  chan puts -nonewline $f [chan read stdin 1024]}
+    chan puts $f {  chan flush $f}
+    chan puts $f "\}"
+    chan puts $f {chan close $f}
+    chan close $f
+    set x 01234567890123456789012345678901
+    for {set i 0} {$i < 11} {incr i} {
+	set x "$x$x"
+    }
+    set f [open $path(output) w]
+    chan close $f
+    set f [openpipe r+ $path(pipe)]
+    chan configure $f -blocking off
+    chan puts -nonewline $f $x
+    chan close $f
+    set counter 0
+    while {([file size $path(output)] < 65536) && ($counter < 1000)} {
+	after 20 [list incr [namespace which -variable counter]]
+	vwait [namespace which -variable counter]
+    }
+    if {$counter == 1000} {
+	set result "file size only [file size $path(output)]"
+    } else {
+	set result ok
+    }
+} -result ok
+test chan-io-29.33 {Tcl_Flush, implicit flush on exit} -setup {
+    set f [open $path(script) w]
+    chan puts $f "set f \[[list open $path(test1) w]]"
+    chan puts $f {chan configure $f -translation lf
+	chan puts $f hello
+	chan puts $f bye
+	chan puts $f strange
+    }
+    chan close $f
+} -constraints exec -body {
+    exec [interpreter] $path(script)
+    set f [open $path(test1) r]
+    chan read $f
+} -cleanup {
+    chan close $f
+} -result "hello\nbye\nstrange\n"
+test chan-io-29.34 {Tcl_Chan Close, async flush on chan close, using sockets} -setup {
+    variable c 0
+    variable x running
+    set l abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz
+    proc writelots {s l} {
+	for {set i 0} {$i < 2000} {incr i} {
+	    chan puts $s $l
+	}
+    }
+} -constraints {socket tempNotMac fileevent} -body {
+    proc accept {s a p} {
+	variable x
+	chan event $s readable [namespace code [list readit $s]]
+	chan configure $s -blocking off
+	set x accepted
+    }
+    proc readit {s} {
+	variable c
+	variable x
+	set l [chan gets $s]
+	if {[chan eof $s]} {
+	    chan close $s
+	    set x done
+	} elseif {([string length $l] > 0) || ![chan blocked $s]} {
+	    incr c
+	}
+    }
+    set ss [socket -server [namespace code accept] -myaddr 127.0.0.1 0]
+    set cs [socket 127.0.0.1 [lindex [chan configure $ss -sockname] 2]]
+    vwait [namespace which -variable x]
+    chan configure $cs -blocking off
+    writelots $cs $l
+    chan close $cs
+    chan close $ss
+    vwait [namespace which -variable x]
+    return $c
+} -result 2000
+test chan-io-29.35 {Tcl_Chan Close vs chan event vs multiple interpreters} -setup {
+    catch {interp delete x}
+    catch {interp delete y}
+} -constraints {socket tempNotMac fileevent} -body {
+    # On Mac, this test screws up sockets such that subsequent tests using
+    # port 2828 either cause errors or panic().
+    interp create x
+    interp create y
+    set s [socket -server [namespace code accept] -myaddr 127.0.0.1 0]
+    proc accept {s a p} {
+	chan puts $s hello
+	chan close $s
+    }
+    set c [socket 127.0.0.1 [lindex [chan configure $s -sockname] 2]]
+    interp share {} $c x
+    interp share {} $c y
+    chan close $c
+    x eval {
+	proc readit {s} {
+	    chan gets $s
+	    if {[chan eof $s]} {
+		chan close $s
+	    }
+	}
+    }
+    y eval {
+	proc readit {s} {
+	    chan gets $s
+	    if {[chan eof $s]} {
+		chan close $s
+	    }
+	}
+    }
+    x eval "chan event $c readable \{readit $c\}"
+    y eval "chan event $c readable \{readit $c\}"
+    y eval [list chan close $c]
+    update
+} -cleanup {
+    chan close $s
+    interp delete x
+    interp delete y
+} -result ""
+
+# Test end of line translations. Procedures tested are Tcl_Write, Tcl_Read.
+
+test chan-io-30.1 {Tcl_Write lf, Tcl_Read lf} -setup {
+    file delete $path(test1)
+} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation lf
+    chan puts $f hello\nthere\nand\nhere
+    chan close $f
+    set f [open $path(test1) r]
+    chan configure $f -translation lf
+    chan read $f
+} -cleanup {
+    chan close $f
+} -result "hello\nthere\nand\nhere\n"
+test chan-io-30.2 {Tcl_Write lf, Tcl_Read cr} -setup {
+    file delete $path(test1)
+} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation lf
+    chan puts $f hello\nthere\nand\nhere
+    chan close $f
+    set f [open $path(test1) r]
+    chan configure $f -translation cr
+    chan read $f
+} -cleanup {
+    chan close $f
+} -result "hello\nthere\nand\nhere\n"
+test chan-io-30.3 {Tcl_Write lf, Tcl_Read crlf} -setup {
+    file delete $path(test1)
+} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation lf
+    chan puts $f hello\nthere\nand\nhere
+    chan close $f
+    set f [open $path(test1) r]
+    chan configure $f -translation crlf
+    chan read $f
+} -cleanup {
+    chan close $f
+} -result "hello\nthere\nand\nhere\n"
+test chan-io-30.4 {Tcl_Write cr, Tcl_Read cr} -setup {
+    file delete $path(test1)
+} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation cr
+    chan puts $f hello\nthere\nand\nhere
+    chan close $f
+    set f [open $path(test1) r]
+    chan configure $f -translation cr
+    chan read $f
+} -cleanup {
+    chan close $f
+} -result "hello\nthere\nand\nhere\n"
+test chan-io-30.5 {Tcl_Write cr, Tcl_Read lf} -setup {
+    file delete $path(test1)
+} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation cr
+    chan puts $f hello\nthere\nand\nhere
+    chan close $f
+    set f [open $path(test1) r]
+    chan configure $f -translation lf
+    chan read $f
+} -cleanup {
+    chan close $f
+} -result "hello\rthere\rand\rhere\r"
+test chan-io-30.6 {Tcl_Write cr, Tcl_Read crlf} -setup {
+    file delete $path(test1)
+} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation cr
+    chan puts $f hello\nthere\nand\nhere
+    chan close $f
+    set f [open $path(test1) r]
+    chan configure $f -translation crlf
+    chan read $f
+} -cleanup {
+    chan close $f
+} -result "hello\rthere\rand\rhere\r"
+test chan-io-30.7 {Tcl_Write crlf, Tcl_Read crlf} -setup {
+    file delete $path(test1)
+} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation crlf
+    chan puts $f hello\nthere\nand\nhere
+    chan close $f
+    set f [open $path(test1) r]
+    chan configure $f -translation crlf
+    chan read $f
+} -cleanup {
+    chan close $f
+} -result "hello\nthere\nand\nhere\n"
+test chan-io-30.8 {Tcl_Write crlf, Tcl_Read lf} -setup {
+    file delete $path(test1)
+} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation crlf
+    chan puts $f hello\nthere\nand\nhere
+    chan close $f
+    set f [open $path(test1) r]
+    chan configure $f -translation lf
+    chan read $f
+} -cleanup {
+    chan close $f
+} -result "hello\r\nthere\r\nand\r\nhere\r\n"
+test chan-io-30.9 {Tcl_Write crlf, Tcl_Read cr} -setup {
+    file delete $path(test1)
+} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation crlf
+    chan puts $f hello\nthere\nand\nhere
+    chan close $f
+    set f [open $path(test1) r]
+    chan configure $f -translation cr
+    chan read $f
+} -cleanup {
+    chan close $f
+} -result "hello\n\nthere\n\nand\n\nhere\n\n"
+test chan-io-30.10 {Tcl_Write lf, Tcl_Read auto} -setup {
+    file delete $path(test1)
+} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation lf
+    chan puts $f hello\nthere\nand\nhere
+    chan close $f
+    set f [open $path(test1) r]
+    list [chan read $f] [chan configure $f -translation]
+} -cleanup {
+    chan close $f
+} -result {{hello
+there
+and
+here
+} auto}
+test chan-io-30.11 {Tcl_Write cr, Tcl_Read auto} -setup {
+    file delete $path(test1)
+} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation cr
+    chan puts $f hello\nthere\nand\nhere
+    chan close $f
+    set f [open $path(test1) r]
+    list [chan read $f] [chan configure $f -translation]
+} -cleanup {
+    chan close $f
+} -result {{hello
+there
+and
+here
+} auto}
+test chan-io-30.12 {Tcl_Write crlf, Tcl_Read auto} -setup {
+    file delete $path(test1)
+} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation crlf
+    chan puts $f hello\nthere\nand\nhere
+    chan close $f
+    set f [open $path(test1) r]
+    list [chan read $f] [chan configure $f -translation]
+} -cleanup {
+    chan close $f
+} -result {{hello
+there
+and
+here
+} auto}
+test chan-io-30.13 {Tcl_Write crlf on block boundary, Tcl_Read auto} -setup {
+    file delete $path(test1)
+} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation crlf
+    set line "123456789ABCDE"	;# 14 char plus crlf
+    chan puts -nonewline $f x	;# shift crlf across block boundary
+    for {set i 0} {$i < 700} {incr i} {
+	chan puts $f $line
+    }
+    chan close $f
+    set f [open $path(test1) r]
+    chan configure $f -translation auto
+    string length [chan read $f]
+} -cleanup {
+    chan close $f
+} -result [expr 700*15+1]
+test chan-io-30.14 {Tcl_Write crlf on block boundary, Tcl_Read crlf} -setup {
+    file delete $path(test1)
+} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation crlf
+    set line "123456789ABCDE"	;# 14 char plus crlf
+    chan puts -nonewline $f x	;# shift crlf across block boundary
+    for {set i 0} {$i < 700} {incr i} {
+	chan puts $f $line
+    }
+    chan close $f
+    set f [open $path(test1) r]
+    chan configure $f -translation crlf
+    string length [chan read $f]
+} -cleanup {
+    chan close $f
+} -result [expr 700*15+1]
+test chan-io-30.15 {Tcl_Write mixed, Tcl_Read auto} -setup {
+    file delete $path(test1)
+} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation lf
+    chan puts $f hello\nthere\nand\rhere
+    chan close $f
+    set f [open $path(test1) r]
+    chan configure $f -translation auto
+    chan read $f
+} -cleanup {
+    chan close $f
+} -result {hello
+there
+and
+here
+}
+test chan-io-30.16 {Tcl_Write ^Z at end, Tcl_Read auto} -setup {
+    file delete $path(test1)
+} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation lf
+    chan puts -nonewline $f hello\nthere\nand\rhere\n\x1a
+    chan close $f
+    set f [open $path(test1) r]
+    chan configure $f -eofchar \x1a -translation auto
+    chan read $f
+} -cleanup {
+    chan close $f
+} -result {hello
+there
+and
+here
+}
+test chan-io-30.17 {Tcl_Write, implicit ^Z at end, Tcl_Read auto} -setup {
+    file delete $path(test1)
+} -constraints {win} -body {
+    set f [open $path(test1) w]
+    chan configure $f -eofchar \x1a -translation lf
+    chan puts $f hello\nthere\nand\rhere
+    chan close $f
+    set f [open $path(test1) r]
+    chan configure $f -eofchar \x1a -translation auto
+    chan read $f
+} -cleanup {
+    chan close $f
+} -result {hello
+there
+and
+here
+}
+test chan-io-30.18 {Tcl_Write, ^Z in middle, Tcl_Read auto} -setup {
+    file delete $path(test1)
+} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation lf
+    set s [format "abc\ndef\n%cghi\nqrs" 26]
+    chan puts $f $s
+    chan close $f
+    set f [open $path(test1) r]
+    chan configure $f -eofchar \x1a -translation auto
+    set l ""
+    lappend l [chan gets $f]
+    lappend l [chan gets $f]
+    lappend l [chan eof $f]
+    lappend l [chan gets $f]
+    lappend l [chan eof $f]
+    lappend l [chan gets $f]
+    lappend l [chan eof $f]
+} -cleanup {
+    chan close $f
+} -result {abc def 0 {} 1 {} 1}
+test chan-io-30.19 {Tcl_Write, ^Z no newline in middle, Tcl_Read auto} -setup {
+    file delete $path(test1)
+} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation lf
+    set s [format "abc\ndef\n%cghi\nqrs" 26]
+    chan puts $f $s
+    chan close $f
+    set f [open $path(test1) r]
+    chan configure $f -eofchar \x1a -translation auto
+    set l ""
+    lappend l [chan gets $f]
+    lappend l [chan gets $f]
+    lappend l [chan eof $f]
+    lappend l [chan gets $f]
+    lappend l [chan eof $f]
+    lappend l [chan gets $f]
+    lappend l [chan eof $f]
+} -cleanup {
+    chan close $f
+} -result {abc def 0 {} 1 {} 1}
+test chan-io-30.20 {Tcl_Write, ^Z in middle ignored, Tcl_Read lf} -setup {
+    file delete $path(test1)
+    set l ""
+} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation lf -eofchar {}
+    chan puts $f [format "abc\ndef\n%cghi\nqrs" 26]
+    chan close $f
+    set f [open $path(test1) r]
+    chan configure $f -translation lf -eofchar {}
+    lappend l [chan gets $f]
+    lappend l [chan gets $f]
+    lappend l [chan eof $f]
+    lappend l [chan gets $f]
+    lappend l [chan eof $f]
+    lappend l [chan gets $f]
+    lappend l [chan eof $f]
+    lappend l [chan gets $f]
+    lappend l [chan eof $f]
+} -cleanup {
+    chan close $f
+} -result "abc def 0 \x1aghi 0 qrs 0 {} 1"
+test chan-io-30.21 {Tcl_Write, ^Z in middle ignored, Tcl_Read cr} -setup {
+    file delete $path(test1)
+    set l ""
+} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation lf -eofchar {}
+    chan puts $f [format "abc\ndef\n%cghi\nqrs" 26]
+    chan close $f
+    set f [open $path(test1) r]
+    chan configure $f -translation cr -eofchar {}
+    set x [chan gets $f]
+    lappend l [string equal $x "abc\ndef\n\x1aghi\nqrs\n"]
+    lappend l [chan eof $f]
+    lappend l [chan gets $f]
+    lappend l [chan eof $f]
+} -cleanup {
+    chan close $f
+} -result {1 1 {} 1}
+test chan-io-30.22 {Tcl_Write, ^Z in middle ignored, Tcl_Read crlf} -setup {
+    file delete $path(test1)
+    set l ""
+} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation lf -eofchar {}
+    chan puts $f [format "abc\ndef\n%cghi\nqrs" 26]
+    chan close $f
+    set f [open $path(test1) r]
+    chan configure $f -translation crlf -eofchar {}
+    set x [chan gets $f]
+    lappend l [string equal $x "abc\ndef\n\x1aghi\nqrs\n"]
+    lappend l [chan eof $f]
+    lappend l [chan gets $f]
+    lappend l [chan eof $f]
+} -cleanup {
+    chan close $f
+} -result {1 1 {} 1}
+test chan-io-30.23 {Tcl_Write lf, ^Z in middle, Tcl_Read auto} -setup {
+    file delete $path(test1)
+} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation lf
+    chan puts $f [format abc\ndef\n%cqrs\ntuv 26]
+    chan close $f
+    set f [open $path(test1) r]
+    chan configure $f -translation auto -eofchar \x1a
+    list [string length [chan read $f]] [chan eof $f]
+} -cleanup {
+    chan close $f
+} -result {8 1}
+test chan-io-30.24 {Tcl_Write lf, ^Z in middle, Tcl_Read lf} -setup {
+    file delete $path(test1)
+} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation lf
+    set c [format abc\ndef\n%cqrs\ntuv 26]
+    chan puts $f $c
+    chan close $f
+    set f [open $path(test1) r]
+    chan configure $f -translation lf -eofchar \x1a
+    list [string length [chan read $f]] [chan eof $f]
+} -cleanup {
+    chan close $f
+} -result {8 1}
+test chan-io-30.25 {Tcl_Write cr, ^Z in middle, Tcl_Read auto} -setup {
+    file delete $path(test1)
+} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation cr
+    set c [format abc\ndef\n%cqrs\ntuv 26]
+    chan puts $f $c
+    chan close $f
+    set f [open $path(test1) r]
+    chan configure $f -translation auto -eofchar \x1a
+    list [string length [chan read $f]] [chan eof $f]
+} -cleanup {
+    chan close $f
+} -result {8 1}
+test chan-io-30.26 {Tcl_Write cr, ^Z in middle, Tcl_Read cr} -setup {
+    file delete $path(test1)
+} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation cr
+    set c [format abc\ndef\n%cqrs\ntuv 26]
+    chan puts $f $c
+    chan close $f
+    set f [open $path(test1) r]
+    chan configure $f -translation cr -eofchar \x1a
+    list [string length [chan read $f]] [chan eof $f]
+} -cleanup {
+    chan close $f
+} -result {8 1}
+test chan-io-30.27 {Tcl_Write crlf, ^Z in middle, Tcl_Read auto} -setup {
+    file delete $path(test1)
+} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation crlf
+    set c [format abc\ndef\n%cqrs\ntuv 26]
+    chan puts $f $c
+    chan close $f
+    set f [open $path(test1) r]
+    chan configure $f -translation auto -eofchar \x1a
+    list [string length [chan read $f]] [chan eof $f]
+} -cleanup {
+    chan close $f
+} -result {8 1}
+test chan-io-30.28 {Tcl_Write crlf, ^Z in middle, Tcl_Read crlf} -setup {
+    file delete $path(test1)
+} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation crlf
+    set c [format abc\ndef\n%cqrs\ntuv 26]
+    chan puts $f $c
+    chan close $f
+    set f [open $path(test1) r]
+    chan configure $f -translation crlf -eofchar \x1a
+    list [string length [chan read $f]] [chan eof $f]
+} -cleanup {
+    chan close $f
+} -result {8 1}
+
+# Test end of line translations. Functions tested are Tcl_Write and
+# Tcl_Gets.
+
+test chan-io-31.1 {Tcl_Write lf, Tcl_Gets auto} -setup {
+    file delete $path(test1)
+    set l ""
+} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation lf
+    chan puts $f hello\nthere\nand\nhere
+    chan close $f
+    set f [open $path(test1) r]
+    lappend l [chan gets $f]
+    lappend l [chan tell $f]
+    lappend l [chan configure $f -translation]
+    lappend l [chan gets $f]
+    lappend l [chan tell $f]
+    lappend l [chan configure $f -translation]
+} -cleanup {
+    chan close $f
+} -result {hello 6 auto there 12 auto}
+test chan-io-31.2 {Tcl_Write cr, Tcl_Gets auto} -setup {
+    file delete $path(test1)
+    set l ""
+} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation cr
+    chan puts $f hello\nthere\nand\nhere
+    chan close $f
+    set f [open $path(test1) r]
+    lappend l [chan gets $f]
+    lappend l [chan tell $f]
+    lappend l [chan configure $f -translation]
+    lappend l [chan gets $f]
+    lappend l [chan tell $f]
+    lappend l [chan configure $f -translation]
+} -cleanup {
+    chan close $f
+} -result {hello 6 auto there 12 auto}
+test chan-io-31.3 {Tcl_Write crlf, Tcl_Gets auto} -setup {
+    file delete $path(test1)
+    set l ""
+} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation crlf
+    chan puts $f hello\nthere\nand\nhere
+    chan close $f
+    set f [open $path(test1) r]
+    lappend l [chan gets $f]
+    lappend l [chan tell $f]
+    lappend l [chan configure $f -translation]
+    lappend l [chan gets $f]
+    lappend l [chan tell $f]
+    lappend l [chan configure $f -translation]
+} -cleanup {
+    chan close $f
+} -result {hello 7 auto there 14 auto}
+test chan-io-31.4 {Tcl_Write lf, Tcl_Gets lf} -setup {
+    file delete $path(test1)
+    set l ""
+} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation lf
+    chan puts $f hello\nthere\nand\nhere
+    chan close $f
+    set f [open $path(test1) r]
+    chan configure $f -translation lf
+    lappend l [chan gets $f]
+    lappend l [chan tell $f]
+    lappend l [chan configure $f -translation]
+    lappend l [chan gets $f]
+    lappend l [chan tell $f]
+    lappend l [chan configure $f -translation]
+} -cleanup {
+    chan close $f
+} -result {hello 6 lf there 12 lf}
+test chan-io-31.5 {Tcl_Write lf, Tcl_Gets cr} -setup {
+    file delete $path(test1)
+    set l ""
+} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation lf
+    chan puts $f hello\nthere\nand\nhere
+    chan close $f
+    set f [open $path(test1) r]
+    chan configure $f -translation cr
+    lappend l [string length [chan gets $f]]
+    lappend l [chan tell $f]
+    lappend l [chan configure $f -translation]
+    lappend l [chan eof $f]
+    lappend l [chan gets $f]
+    lappend l [chan tell $f]
+    lappend l [chan configure $f -translation]
+    lappend l [chan eof $f]
+} -cleanup {
+    chan close $f
+} -result {21 21 cr 1 {} 21 cr 1}
+test chan-io-31.6 {Tcl_Write lf, Tcl_Gets crlf} -setup {
+    file delete $path(test1)
+    set l ""
+} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation lf
+    chan puts $f hello\nthere\nand\nhere
+    chan close $f
+    set f [open $path(test1) r]
+    chan configure $f -translation crlf
+    lappend l [string length [chan gets $f]]
+    lappend l [chan tell $f]
+    lappend l [chan configure $f -translation]
+    lappend l [chan eof $f]
+    lappend l [chan gets $f]
+    lappend l [chan tell $f]
+    lappend l [chan configure $f -translation]
+    lappend l [chan eof $f]
+} -cleanup {
+    chan close $f
+} -result {21 21 crlf 1 {} 21 crlf 1}
+test chan-io-31.7 {Tcl_Write cr, Tcl_Gets cr} -setup {
+    file delete $path(test1)
+    set l ""
+} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation cr
+    chan puts $f hello\nthere\nand\nhere
+    chan close $f
+    set f [open $path(test1) r]
+    chan configure $f -translation cr
+    lappend l [chan gets $f]
+    lappend l [chan tell $f]
+    lappend l [chan configure $f -translation]
+    lappend l [chan eof $f]
+    lappend l [chan gets $f]
+    lappend l [chan tell $f]
+    lappend l [chan configure $f -translation]
+    lappend l [chan eof $f]
+} -cleanup {
+    chan close $f
+} -result {hello 6 cr 0 there 12 cr 0}
+test chan-io-31.8 {Tcl_Write cr, Tcl_Gets lf} -setup {
+    file delete $path(test1)
+    set l ""
+} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation cr
+    chan puts $f hello\nthere\nand\nhere
+    chan close $f
+    set f [open $path(test1) r]
+    chan configure $f -translation lf
+    lappend l [string length [chan gets $f]]
+    lappend l [chan tell $f]
+    lappend l [chan configure $f -translation]
+    lappend l [chan eof $f]
+    lappend l [chan gets $f]
+    lappend l [chan tell $f]
+    lappend l [chan configure $f -translation]
+    lappend l [chan eof $f]
+} -cleanup {
+    chan close $f
+} -result {21 21 lf 1 {} 21 lf 1}
+test chan-io-31.9 {Tcl_Write cr, Tcl_Gets crlf} -setup {
+    file delete $path(test1)
+    set l ""
+} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation cr
+    chan puts $f hello\nthere\nand\nhere
+    chan close $f
+    set f [open $path(test1) r]
+    chan configure $f -translation crlf
+    lappend l [string length [chan gets $f]]
+    lappend l [chan tell $f]
+    lappend l [chan configure $f -translation]
+    lappend l [chan eof $f]
+    lappend l [chan gets $f]
+    lappend l [chan tell $f]
+    lappend l [chan configure $f -translation]
+    lappend l [chan eof $f]
+} -cleanup {
+    chan close $f
+} -result {21 21 crlf 1 {} 21 crlf 1}
+test chan-io-31.10 {Tcl_Write crlf, Tcl_Gets crlf} -setup {
+    file delete $path(test1)
+    set l ""
+} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation crlf
+    chan puts $f hello\nthere\nand\nhere
+    chan close $f
+    set f [open $path(test1) r]
+    chan configure $f -translation crlf
+    lappend l [chan gets $f]
+    lappend l [chan tell $f]
+    lappend l [chan configure $f -translation]
+    lappend l [chan eof $f]
+    lappend l [chan gets $f]
+    lappend l [chan tell $f]
+    lappend l [chan configure $f -translation]
+    lappend l [chan eof $f]
+} -cleanup {
+    chan close $f
+} -result {hello 7 crlf 0 there 14 crlf 0}
+test chan-io-31.11 {Tcl_Write crlf, Tcl_Gets cr} -setup {
+    file delete $path(test1)
+    set l ""
+} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation crlf
+    chan puts $f hello\nthere\nand\nhere
+    chan close $f
+    set f [open $path(test1) r]
+    chan configure $f -translation cr
+    lappend l [chan gets $f]
+    lappend l [chan tell $f]
+    lappend l [chan configure $f -translation]
+    lappend l [chan eof $f]
+    lappend l [string length [chan gets $f]]
+    lappend l [chan tell $f]
+    lappend l [chan configure $f -translation]
+    lappend l [chan eof $f]
+} -cleanup {
+    chan close $f
+} -result {hello 6 cr 0 6 13 cr 0}
+test chan-io-31.12 {Tcl_Write crlf, Tcl_Gets lf} -setup {
+    file delete $path(test1)
+    set l ""
+} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation crlf
+    chan puts $f hello\nthere\nand\nhere
+    chan close $f
+    set f [open $path(test1) r]
+    chan configure $f -translation lf
+    lappend l [string length [chan gets $f]]
+    lappend l [chan tell $f]
+    lappend l [chan configure $f -translation]
+    lappend l [chan eof $f]
+    lappend l [string length [chan gets $f]]
+    lappend l [chan tell $f]
+    lappend l [chan configure $f -translation]
+    lappend l [chan eof $f]
+} -cleanup {
+    chan close $f
+} -result {6 7 lf 0 6 14 lf 0}
+test chan-io-31.13 {binary mode is synonym of lf mode} -setup {
+    file delete $path(test1)
+} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation binary
+    chan configure $f -translation
+} -cleanup {
+    chan close $f
+} -result lf
+#
+# Test chan-io-9.14 has been removed because "auto" output translation mode is
+# not supoprted.
+#
+test chan-io-31.14 {Tcl_Write mixed, Tcl_Gets auto} -setup {
+    file delete $path(test1)
+    set l ""
+} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation lf
+    chan puts $f hello\nthere\rand\r\nhere
+    chan close $f
+    set f [open $path(test1) r]
+    chan configure $f -translation auto
+    lappend l [chan gets $f]
+    lappend l [chan gets $f]
+    lappend l [chan gets $f]
+    lappend l [chan gets $f]
+    lappend l [chan eof $f]
+    lappend l [chan gets $f]
+    lappend l [chan eof $f]
+} -cleanup {
+    chan close $f
+} -result {hello there and here 0 {} 1}
+test chan-io-31.15 {Tcl_Write mixed, Tcl_Gets auto} -setup {
+    file delete $path(test1)
+    set l ""
+} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation lf
+    chan puts -nonewline $f hello\nthere\rand\r\nhere\r
+    chan close $f
+    set f [open $path(test1) r]
+    chan configure $f -translation auto
+    lappend l [chan gets $f]
+    lappend l [chan gets $f]
+    lappend l [chan gets $f]
+    lappend l [chan gets $f]
+    lappend l [chan eof $f]
+    lappend l [chan gets $f]
+    lappend l [chan eof $f]
+} -cleanup {
+    chan close $f
+} -result {hello there and here 0 {} 1}
+test chan-io-31.16 {Tcl_Write mixed, Tcl_Gets auto} -setup {
+    file delete $path(test1)
+    set l ""
+} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation lf
+    chan puts -nonewline $f hello\nthere\rand\r\nhere\n
+    chan close $f
+    set f [open $path(test1) r]
+    lappend l [chan gets $f]
+    lappend l [chan gets $f]
+    lappend l [chan gets $f]
+    lappend l [chan gets $f]
+    lappend l [chan eof $f]
+    lappend l [chan gets $f]
+    lappend l [chan eof $f]
+} -cleanup {
+    chan close $f
+} -result {hello there and here 0 {} 1}
+test chan-io-31.17 {Tcl_Write mixed, Tcl_Gets auto} -setup {
+    file delete $path(test1)
+    set l ""
+} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation lf
+    chan puts -nonewline $f hello\nthere\rand\r\nhere\r\n
+    chan close $f
+    set f [open $path(test1) r]
+    chan configure $f -translation auto
+    lappend l [chan gets $f]
+    lappend l [chan gets $f]
+    lappend l [chan gets $f]
+    lappend l [chan gets $f]
+    lappend l [chan eof $f]
+    lappend l [chan gets $f]
+    lappend l [chan eof $f]
+} -cleanup {
+    chan close $f
+} -result {hello there and here 0 {} 1}
+test chan-io-31.18 {Tcl_Write ^Z at end, Tcl_Gets auto} -setup {
+    file delete $path(test1)
+    set l ""
+} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation lf
+    chan puts $f [format "hello\nthere\nand\rhere\n\%c" 26]
+    chan close $f
+    set f [open $path(test1) r]
+    chan configure $f -eofchar \x1a -translation auto
+    lappend l [chan gets $f]
+    lappend l [chan gets $f]
+    lappend l [chan gets $f]
+    lappend l [chan gets $f]
+    lappend l [chan eof $f]
+    lappend l [chan gets $f]
+    lappend l [chan eof $f]
+} -cleanup {
+    chan close $f
+} -result {hello there and here 0 {} 1}
+test chan-io-31.19 {Tcl_Write, implicit ^Z at end, Tcl_Gets auto} -setup {
+    file delete $path(test1)
+    set l ""
+} -body {
+    set f [open $path(test1) w]
+    chan configure $f -eofchar \x1a -translation lf
+    chan puts $f hello\nthere\nand\rhere
+    chan close $f
+    set f [open $path(test1) r]
+    chan configure $f -eofchar \x1a -translation auto
+    lappend l [chan gets $f]
+    lappend l [chan gets $f]
+    lappend l [chan gets $f]
+    lappend l [chan gets $f]
+    lappend l [chan eof $f]
+    lappend l [chan gets $f]
+    lappend l [chan eof $f]
+} -cleanup {
+    chan close $f
+} -result {hello there and here 0 {} 1}
+test chan-io-31.20 {Tcl_Write, ^Z in middle, Tcl_Gets auto, eofChar} -setup {
+    file delete $path(test1)
+    set l ""
+} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation lf
+    chan puts $f [format "abc\ndef\n%cqrs\ntuv" 26]
+    chan close $f
+    set f [open $path(test1) r]
+    chan configure $f -eofchar \x1a
+    chan configure $f -translation auto
+    lappend l [chan gets $f]
+    lappend l [chan gets $f]
+    lappend l [chan eof $f]
+    lappend l [chan gets $f]
+    lappend l [chan eof $f]
+} -cleanup {
+    chan close $f
+} -result {abc def 0 {} 1}
+test chan-io-31.21 {Tcl_Write, no newline ^Z in middle, Tcl_Gets auto, eofChar} -setup {
+    file delete $path(test1)
+    set l ""
+} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation lf
+    chan puts $f [format "abc\ndef\n%cqrs\ntuv" 26]
+    chan close $f
+    set f [open $path(test1) r]
+    chan configure $f -eofchar \x1a -translation auto
+    lappend l [chan gets $f]
+    lappend l [chan gets $f]
+    lappend l [chan eof $f]
+    lappend l [chan gets $f]
+    lappend l [chan eof $f]
+} -cleanup {
+    chan close $f
+} -result {abc def 0 {} 1}
+test chan-io-31.22 {Tcl_Write, ^Z in middle ignored, Tcl_Gets lf} -setup {
+    file delete $path(test1)
+    set l ""
+} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation lf -eofchar {}
+    chan puts $f [format "abc\ndef\n%cqrs\ntuv" 26]
+    chan close $f
+    set f [open $path(test1) r]
+    chan configure $f -translation lf -eofchar {}
+    lappend l [chan gets $f]
+    lappend l [chan gets $f]
+    lappend l [chan eof $f]
+    lappend l [chan gets $f]
+    lappend l [chan eof $f]
+    lappend l [chan gets $f]
+    lappend l [chan eof $f]
+    lappend l [chan gets $f]
+    lappend l [chan eof $f]
+} -cleanup {
+    chan close $f
+} -result "abc def 0 \x1aqrs 0 tuv 0 {} 1"
+test chan-io-31.23 {Tcl_Write, ^Z in middle ignored, Tcl_Gets cr} -setup {
+    file delete $path(test1)
+    set l ""
+} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation cr -eofchar {}
+    chan puts $f [format "abc\ndef\n%cqrs\ntuv" 26]
+    chan close $f
+    set f [open $path(test1) r]
+    chan configure $f -translation cr -eofchar {}
+    lappend l [chan gets $f]
+    lappend l [chan gets $f]
+    lappend l [chan eof $f]
+    lappend l [chan gets $f]
+    lappend l [chan eof $f]
+    lappend l [chan gets $f]
+    lappend l [chan eof $f]
+    lappend l [chan gets $f]
+    lappend l [chan eof $f]
+} -cleanup {
+    chan close $f
+} -result "abc def 0 \x1aqrs 0 tuv 0 {} 1"
+test chan-io-31.24 {Tcl_Write, ^Z in middle ignored, Tcl_Gets crlf} -setup {
+    file delete $path(test1)
+    set l ""
+} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation crlf -eofchar {}
+    chan puts $f [format "abc\ndef\n%cqrs\ntuv" 26]
+    chan close $f
+    set f [open $path(test1) r]
+    chan configure $f -translation crlf -eofchar {}
+    lappend l [chan gets $f]
+    lappend l [chan gets $f]
+    lappend l [chan eof $f]
+    lappend l [chan gets $f]
+    lappend l [chan eof $f]
+    lappend l [chan gets $f]
+    lappend l [chan eof $f]
+    lappend l [chan gets $f]
+    lappend l [chan eof $f]
+} -cleanup {
+    chan close $f
+} -result "abc def 0 \x1aqrs 0 tuv 0 {} 1"
+test chan-io-31.25 {Tcl_Write lf, ^Z in middle, Tcl_Gets auto} -setup {
+    file delete $path(test1)
+    set l ""
+} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation lf
+    chan puts $f [format "abc\ndef\n%cqrs\ntuv" 26]
+    chan close $f
+    set f [open $path(test1) r]
+    chan configure $f -translation auto -eofchar \x1a
+    lappend l [chan gets $f]
+    lappend l [chan gets $f]
+    lappend l [chan eof $f]
+    lappend l [chan gets $f]
+    lappend l [chan eof $f]
+} -cleanup {
+    chan close $f
+} -result {abc def 0 {} 1}
+test chan-io-31.26 {Tcl_Write lf, ^Z in middle, Tcl_Gets lf} -setup {
+    file delete $path(test1)
+    set l ""
+} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation lf
+    chan puts $f [format "abc\ndef\n%cqrs\ntuv" 26]
+    chan close $f
+    set f [open $path(test1) r]
+    chan configure $f -translation lf -eofchar \x1a
+    lappend l [chan gets $f]
+    lappend l [chan gets $f]
+    lappend l [chan eof $f]
+    lappend l [chan gets $f]
+    lappend l [chan eof $f]
+} -cleanup {
+    chan close $f
+} -result {abc def 0 {} 1}
+test chan-io-31.27 {Tcl_Write cr, ^Z in middle, Tcl_Gets auto} -setup {
+    file delete $path(test1)
+    set l ""
+} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation cr -eofchar {}
+    chan puts $f [format "abc\ndef\n%cqrs\ntuv" 26]
+    chan close $f
+    set f [open $path(test1) r]
+    chan configure $f -translation auto -eofchar \x1a
+    lappend l [chan gets $f]
+    lappend l [chan gets $f]
+    lappend l [chan eof $f]
+    lappend l [chan gets $f]
+    lappend l [chan eof $f]
+} -cleanup {
+    chan close $f
+} -result {abc def 0 {} 1}
+test chan-io-31.28 {Tcl_Write cr, ^Z in middle, Tcl_Gets cr} -setup {
+    file delete $path(test1)
+    set l ""
+} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation cr -eofchar {}
+    chan puts $f [format "abc\ndef\n%cqrs\ntuv" 26]
+    chan close $f
+    set f [open $path(test1) r]
+    chan configure $f -translation cr -eofchar \x1a
+    lappend l [chan gets $f]
+    lappend l [chan gets $f]
+    lappend l [chan eof $f]
+    lappend l [chan gets $f]
+    lappend l [chan eof $f]
+} -cleanup {
+    chan close $f
+} -result {abc def 0 {} 1}
+test chan-io-31.29 {Tcl_Write crlf, ^Z in middle, Tcl_Gets auto} -setup {
+    file delete $path(test1)
+    set l ""
+} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation crlf -eofchar {}
+    chan puts $f [format "abc\ndef\n%cqrs\ntuv" 26]
+    chan close $f
+    set f [open $path(test1) r]
+    chan configure $f -translation auto -eofchar \x1a
+    lappend l [chan gets $f]
+    lappend l [chan gets $f]
+    lappend l [chan eof $f]
+    lappend l [chan gets $f]
+    lappend l [chan eof $f]
+} -cleanup {
+    chan close $f
+} -result {abc def 0 {} 1}
+test chan-io-31.30 {Tcl_Write crlf, ^Z in middle, Tcl_Gets crlf} -setup {
+    file delete $path(test1)
+    set l ""
+} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation crlf -eofchar {}
+    chan puts $f [format "abc\ndef\n%cqrs\ntuv" 26]
+    chan close $f
+    set f [open $path(test1) r]
+    chan configure $f -translation crlf -eofchar \x1a
+    lappend l [chan gets $f]
+    lappend l [chan gets $f]
+    lappend l [chan eof $f]
+    lappend l [chan gets $f]
+    lappend l [chan eof $f]
+} -cleanup {
+    chan close $f
+} -result {abc def 0 {} 1}
+test chan-io-31.31 {Tcl_Write crlf on block boundary, Tcl_Gets crlf} -setup {
+    file delete $path(test1)
+    set c ""
+} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation crlf
+    set line "123456789ABCDE"	;# 14 char plus crlf
+    chan puts -nonewline $f x	;# shift crlf across block boundary
+    for {set i 0} {$i < 700} {incr i} {
+	chan puts $f $line
+    }
+    chan close $f
+    set f [open $path(test1) r]
+    chan configure $f -translation crlf 
+    while {[chan gets $f line] >= 0} {
+	append c $line\n
+    }
+    chan close $f
+    string length $c
+} -result [expr 700*15+1]
+test chan-io-31.32 {Tcl_Write crlf on block boundary, Tcl_Gets auto} -setup {
+    file delete $path(test1)
+    set c ""
+} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation crlf
+    set line "123456789ABCDE"	;# 14 char plus crlf
+    chan puts -nonewline $f x	;# shift crlf across block boundary
+    for {set i 0} {$i < 700} {incr i} {
+	chan puts $f $line
+    }
+    chan close $f
+    set f [open $path(test1) r]
+    chan configure $f -translation auto
+    while {[chan gets $f line] >= 0} {
+	append c $line\n
+    }
+    chan close $f
+    string length $c
+} -result [expr 700*15+1]
+
+# Test Tcl_Read and buffering.
+
+test chan-io-32.1 {Tcl_Read, channel not readable} -body {
+    read stdout
+} -returnCodes error -result {channel "stdout" wasn't opened for reading}
+test chan-io-32.2 {Tcl_Read, zero byte count} {
+    chan read stdin 0
+} ""
+test chan-io-32.3 {Tcl_Read, negative byte count} -setup {
+    set f [open $path(longfile) r]
+} -body {
+    chan read $f -1
+} -returnCodes error -cleanup {
+    chan close $f
+} -result {expected non-negative integer but got "-1"}
+test chan-io-32.4 {Tcl_Read, positive byte count} -body {
+    set f [open $path(longfile) r]
+    string length [chan read $f 1024]
+} -cleanup {
+    chan close $f
+} -result 1024
+test chan-io-32.5 {Tcl_Read, multiple buffers} -body {
+    set f [open $path(longfile) r]
+    chan configure $f -buffersize 100
+    string length [chan read $f 1024]
+} -cleanup {
+    chan close $f
+} -result 1024
+test chan-io-32.6 {Tcl_Read, very large read} {
+    set f1 [open $path(longfile) r]
+    set z [chan read $f1 1000000]
+    chan close $f1
+    set l [string length $z]
+    set x ok
+    set z [file size $path(longfile)]
+    if {$z != $l} {
+	set x "$z != $l"
+    }
+    set x
+} ok
+test chan-io-32.7 {Tcl_Read, nonblocking, file} {nonBlockFiles} {
+    set f1 [open $path(longfile) r]
+    chan configure $f1 -blocking off
+    set z [chan read $f1 20]
+    chan close $f1
+    set l [string length $z]
+    set x ok
+    if {$l != 20} {
+	set x "$l != 20"
+    }
+    set x
+} ok
+test chan-io-32.8 {Tcl_Read, nonblocking, file} {nonBlockFiles} {
+    set f1 [open $path(longfile) r]
+    chan configure $f1 -blocking off
+    set z [chan read $f1 1000000]
+    chan close $f1
+    set x ok
+    set l [string length $z]
+    set z [file size $path(longfile)]
+    if {$z != $l} {
+	set x "$z != $l"
+    }
+    set x
+} ok
+test chan-io-32.9 {Tcl_Read, read to end of file} {
+    set f1 [open $path(longfile) r]
+    set z [chan read $f1]
+    chan close $f1
+    set l [string length $z]
+    set x ok
+    set z [file size $path(longfile)]
+    if {$z != $l} {
+	set x "$z != $l"
+    }
+    set x
+} ok
+test chan-io-32.10 {Tcl_Read from a pipe} -setup {
+    file delete $path(pipe)
+} -constraints {stdio openpipe} -body {
+    set f1 [open $path(pipe) w]
+    chan puts $f1 {chan puts [chan gets stdin]}
+    chan close $f1
+    set f1 [openpipe r+ $path(pipe)]
+    chan puts $f1 hello
+    chan flush $f1
+    chan read $f1
+} -cleanup {
+    chan close $f1
+} -result "hello\n"
+test chan-io-32.11 {Tcl_Read from a pipe} -setup {
+    file delete $path(pipe)
+    set x ""
+} -constraints {stdio openpipe} -body {
+    set f1 [open $path(pipe) w]
+    chan puts $f1 {chan puts [chan gets stdin]}
+    chan puts $f1 {chan puts [chan gets stdin]}
+    chan close $f1
+    set f1 [openpipe r+ $path(pipe)]
+    chan puts $f1 hello
+    chan flush $f1
+    lappend x [chan read $f1 6]
+    chan puts $f1 hello
+    chan flush $f1
+    lappend x [chan read $f1]
+} -cleanup {
+    chan close $f1
+} -result {{hello
+} {hello
+}}
+test chan-io-32.12 {Tcl_Read, -nonewline} -setup {
+    file delete $path(test1)
+} -body {
+    set f1 [open $path(test1) w]
+    chan puts $f1 hello
+    chan puts $f1 bye
+    chan close $f1
+    set f1 [open $path(test1) r]
+    chan read -nonewline $f1
+} -cleanup {
+    chan close $f1
+} -result {hello
+bye}
+test chan-io-32.13 {Tcl_Read, -nonewline} -setup {
+    file delete $path(test1)
+} -body {
+    set f1 [open $path(test1) w]
+    chan puts $f1 hello
+    chan puts $f1 bye
+    chan close $f1
+    set f1 [open $path(test1) r]
+    set c [chan read -nonewline $f1]
+    list [string length $c] $c
+} -cleanup {
+    chan close $f1
+} -result {9 {hello
+bye}}
+test chan-io-32.14 {Tcl_Read, reading in small chunks} -setup {
+    file delete $path(test1)
+} -body {
+    set f [open $path(test1) w]
+    chan puts $f "Two lines: this one"
+    chan puts $f "and this one"
+    chan close $f
+    set f [open $path(test1)]
+    list [chan read $f 1] [chan read $f 2] [chan read $f]
+} -cleanup {
+    chan close $f
+} -result {T wo { lines: this one
+and this one
+}}
+test chan-io-32.15 {Tcl_Read, asking for more input than available} -setup {
+    file delete $path(test1)
+} -body {
+    set f [open $path(test1) w]
+    chan puts $f "Two lines: this one"
+    chan puts $f "and this one"
+    chan close $f
+    set f [open $path(test1)]
+    chan read $f 100
+} -cleanup {
+    chan close $f
+} -result {Two lines: this one
+and this one
+}
+test chan-io-32.16 {Tcl_Read, read to end of file with -nonewline} -setup {
+    file delete $path(test1)
+} -body {
+    set f [open $path(test1) w]
+    chan puts $f "Two lines: this one"
+    chan puts $f "and this one"
+    chan close $f
+    set f [open $path(test1)]
+    chan read -nonewline $f
+} -cleanup {
+    chan close $f
+} -result {Two lines: this one
+and this one}
+
+# Test Tcl_Gets.
+
+test chan-io-33.1 {Tcl_Gets, reading what was written} -setup {
+    file delete $path(test1)
+} -body {
+    set f1 [open $path(test1) w]
+    chan puts $f1 "first line"
+    chan close $f1
+    set f1 [open $path(test1) r]
+    chan gets $f1
+} -cleanup {
+    chan close $f1
+} -result {first line}
+test chan-io-33.2 {Tcl_Gets into variable} {
+    set f1 [open $path(longfile) r]
+    set c [chan gets $f1 x]
+    set l [string length x]
+    set z ok
+    if {$l != $l} {
+	set z broken
+    }
+    chan close $f1
+    set z
+} ok
+test chan-io-33.3 {Tcl_Gets from pipe} -setup {
+    file delete $path(pipe)
+} -constraints {stdio openpipe} -body {
+    set f1 [open $path(pipe) w]
+    chan puts $f1 {chan puts [chan gets stdin]}
+    chan close $f1
+    set f1 [openpipe r+ $path(pipe)]
+    chan puts $f1 hello
+    chan flush $f1
+    chan gets $f1
+} -cleanup {
+    chan close $f1
+} -result hello
+test chan-io-33.4 {Tcl_Gets with long line} -setup {
+    file delete $path(test3)
+} -body {
+    set f [open $path(test3) w]
+    chan puts -nonewline $f "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
+    chan puts -nonewline $f "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
+    chan puts -nonewline $f "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
+    chan puts -nonewline $f "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
+    chan puts $f "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
+    chan close $f
+    set f [open $path(test3)]
+    chan gets $f
+} -cleanup {
+    chan close $f
+} -result {abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ}
+test chan-io-33.5 {Tcl_Gets with long line} -setup {
+    set f [open $path(test3) w]
+    puts -nonewline $f "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
+    puts -nonewline $f "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
+    puts -nonewline $f "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
+    puts -nonewline $f "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
+    puts $f "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
+    close $f
+} -body {
+    set f [open $path(test3)]
+    set x [chan gets $f y]
+    chan close $f
+    list $x $y
+} -result {260 abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ}
+test chan-io-33.6 {Tcl_Gets and end of file} -setup {
+    file delete $path(test3)
+    set x {}
+} -body {
+    set f [open $path(test3) w]
+    chan puts -nonewline $f "Test1\nTest2"
+    chan close $f
+    set f [open $path(test3)]
+    set y {}
+    lappend x [chan gets $f y] $y
+    set y {}
+    lappend x [chan gets $f y] $y
+    set y {}
+    lappend x [chan gets $f y] $y
+} -cleanup {
+    chan close $f
+} -result {5 Test1 5 Test2 -1 {}}
+test chan-io-33.7 {Tcl_Gets and bad variable} -setup {
+    set f [open $path(test3) w]
+    chan puts $f "Line 1"
+    chan puts $f "Line 2"
+    chan close $f
+    catch {unset x}
+    set f [open $path(test3) r]
+} -body {
+    set x 24
+    chan gets $f x(0)
+} -returnCodes error -cleanup {
+    chan close $f
+} -result {can't set "x(0)": variable isn't array}
+test chan-io-33.8 {Tcl_Gets, exercising double buffering} {
+    set f [open $path(test3) w]
+    chan configure $f -translation lf -eofchar {}
+    set x ""
+    for {set y 0} {$y < 99} {incr y} {set x "a$x"}
+    for {set y 0} {$y < 100} {incr y} {chan puts $f $x}
+    chan close $f
+    set f [open $path(test3) r]
+    chan configure $f -translation lf
+    for {set y 0} {$y < 100} {incr y} {chan gets $f}
+    chan close $f
+    set y
+} 100
+test chan-io-33.9 {Tcl_Gets, exercising double buffering} {
+    set f [open $path(test3) w]
+    chan configure $f -translation lf -eofchar {}
+    set x ""
+    for {set y 0} {$y < 99} {incr y} {set x "a$x"}
+    for {set y 0} {$y < 200} {incr y} {chan puts $f $x}
+    chan close $f
+    set f [open $path(test3) r]
+    chan configure $f -translation lf
+    for {set y 0} {$y < 200} {incr y} {chan gets $f}
+    chan close $f
+    set y
+} 200
+test chan-io-33.10 {Tcl_Gets, exercising double buffering} {
+    set f [open $path(test3) w]
+    chan configure $f -translation lf -eofchar {}
+    set x ""
+    for {set y 0} {$y < 99} {incr y} {set x "a$x"}
+    for {set y 0} {$y < 300} {incr y} {chan puts $f $x}
+    chan close $f
+    set f [open $path(test3) r]
+    chan configure $f -translation lf
+    for {set y 0} {$y < 300} {incr y} {chan gets $f}
+    chan close $f
+    set y
+} 300
+
+# Test Tcl_Seek and Tcl_Tell.
+
+test chan-io-34.1 {Tcl_Seek to current position at start of file} -body {
+    set f1 [open $path(longfile) r]
+    chan seek $f1 0 current
+    chan tell $f1
+} -cleanup {
+    chan close $f1
+} -result 0
+test chan-io-34.2 {Tcl_Seek to offset from start} -setup {
+    file delete $path(test1)
+} -body {
+    set f1 [open $path(test1) w]
+    chan configure $f1 -translation lf -eofchar {}
+    chan puts $f1 "abcdefghijklmnopqrstuvwxyz"
+    chan puts $f1 "abcdefghijklmnopqrstuvwxyz"
+    chan close $f1
+    set f1 [open $path(test1) r]
+    chan seek $f1 10 start
+    chan tell $f1
+} -cleanup {
+    chan close $f1
+} -result 10
+test chan-io-34.3 {Tcl_Seek to end of file} -setup {
+    file delete $path(test1)
+} -body {
+    set f1 [open $path(test1) w]
+    chan configure $f1 -translation lf -eofchar {}
+    chan puts $f1 "abcdefghijklmnopqrstuvwxyz"
+    chan puts $f1 "abcdefghijklmnopqrstuvwxyz"
+    chan close $f1
+    set f1 [open $path(test1) r]
+    chan seek $f1 0 end
+    chan tell $f1
+} -cleanup {
+    chan close $f1
+} -result 54
+test chan-io-34.4 {Tcl_Seek to offset from end of file} -setup {
+    file delete $path(test1)
+} -body {
+    set f1 [open $path(test1) w]
+    chan configure $f1 -translation lf -eofchar {}
+    chan puts $f1 "abcdefghijklmnopqrstuvwxyz"
+    chan puts $f1 "abcdefghijklmnopqrstuvwxyz"
+    chan close $f1
+    set f1 [open $path(test1) r]
+    chan seek $f1 -10 end
+    chan tell $f1
+} -cleanup {
+    chan close $f1
+} -result 44
+test chan-io-34.5 {Tcl_Seek to offset from current position} -setup {
+    file delete $path(test1)
+} -body {
+    set f1 [open $path(test1) w]
+    chan configure $f1 -translation lf -eofchar {}
+    chan puts $f1 "abcdefghijklmnopqrstuvwxyz"
+    chan puts $f1 "abcdefghijklmnopqrstuvwxyz"
+    chan close $f1
+    set f1 [open $path(test1) r]
+    chan seek $f1 10 current
+    chan seek $f1 10 current
+    chan tell $f1
+} -cleanup {
+    chan close $f1
+} -result 20
+test chan-io-34.6 {Tcl_Seek to offset from end of file} -setup {
+    file delete $path(test1)
+} -body {
+    set f1 [open $path(test1) w]
+    chan configure $f1 -translation lf -eofchar {}
+    chan puts $f1 "abcdefghijklmnopqrstuvwxyz"
+    chan puts $f1 "abcdefghijklmnopqrstuvwxyz"
+    chan close $f1
+    set f1 [open $path(test1) r]
+    chan seek $f1 -10 end
+    list [chan tell $f1] [chan read $f1]
+} -cleanup {
+    chan close $f1
+} -result {44 {rstuvwxyz
+}}
+test chan-io-34.7 {Tcl_Seek to offset from end of file, then to current position} -setup {
+    file delete $path(test1)
+} -body {
+    set f1 [open $path(test1) w]
+    chan configure $f1 -translation lf -eofchar {}
+    chan puts $f1 "abcdefghijklmnopqrstuvwxyz"
+    chan puts $f1 "abcdefghijklmnopqrstuvwxyz"
+    chan close $f1
+    set f1 [open $path(test1) r]
+    chan seek $f1 -10 end
+    set c1 [chan tell $f1]
+    set r1 [chan read $f1 5]
+    chan seek $f1 0 current
+    list $c1 $r1 [chan tell $f1]
+} -cleanup {
+    chan close $f1
+} -result {44 rstuv 49}
+test chan-io-34.8 {Tcl_Seek on pipes: not supported} -setup {
+    set pipe [openpipe]
+} -constraints {stdio openpipe} -body {
+    chan seek $pipe 0 current
+} -returnCodes error -cleanup {
+    chan close $pipe
+} -match glob -result {error during seek on "*": invalid argument}
+test chan-io-34.9 {Tcl_Seek, testing buffered input flushing} -setup {
+    file delete $path(test3)
+} -body {
+    set f [open $path(test3) w]
+    chan configure $f -eofchar {}
+    chan puts -nonewline $f "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
+    chan close $f
+    set f [open $path(test3) RDWR]
+    set x [chan read $f 1]
+    chan seek $f 3
+    lappend x [chan read $f 1]
+    chan seek $f 0 start
+    lappend x [chan read $f 1]
+    chan seek $f 10 current
+    lappend x [chan read $f 1]
+    chan seek $f -2 end
+    lappend x [chan read $f 1]
+    chan seek $f 50 end
+    lappend x [chan read $f 1]
+    chan seek $f 1
+    lappend x [chan read $f 1]
+} -cleanup {
+    chan close $f
+} -result {a d a l Y {} b}
+set path(test3) [makeFile {} test3]
+test chan-io-34.10 {Tcl_Seek testing flushing of buffered input} {
+    set f [open $path(test3) w]
+    chan configure $f -translation lf
+    chan puts $f xyz\n123
+    chan close $f
+    set f [open $path(test3) r+]
+    chan configure $f -translation lf
+    set x [chan gets $f]
+    chan seek $f 0 current
+    chan puts $f 456
+    chan close $f
+    list $x [viewFile test3]
+} "xyz {xyz
+456}"
+test chan-io-34.11 {Tcl_Seek testing flushing of buffered output} {
+    set f [open $path(test3) w]
+    chan puts $f xyz\n123
+    chan close $f
+    set f [open $path(test3) w+]
+    chan puts $f xyzzy
+    chan seek $f 2
+    set x [chan gets $f]
+    chan close $f
+    list $x [viewFile test3]
+} "zzy xyzzy"
+test chan-io-34.12 {Tcl_Seek testing combination of write, seek back and read} {
+    set f [open $path(test3) w]
+    chan configure $f -translation lf -eofchar {}
+    chan puts $f xyz\n123
+    chan close $f
+    set f [open $path(test3) a+]
+    chan configure $f -translation lf -eofchar {}
+    chan puts $f xyzzy
+    chan flush $f
+    set x [chan tell $f]
+    chan seek $f -4 cur
+    set y [chan gets $f]
+    chan close $f
+    list $x [viewFile test3] $y
+} {14 {xyz
+123
+xyzzy} zzy}
+test chan-io-34.13 {Tcl_Tell at start of file} -setup {
+    file delete $path(test1)
+} -body {
+    set f1 [open $path(test1) w]
+    chan tell $f1
+} -cleanup {
+    chan close $f1
+} -result 0
+test chan-io-34.14 {Tcl_Tell after seek to end of file} -setup {
+    file delete $path(test1)
+} -body {
+    set f1 [open $path(test1) w]
+    chan configure $f1 -translation lf -eofchar {}
+    chan puts $f1 "abcdefghijklmnopqrstuvwxyz"
+    chan puts $f1 "abcdefghijklmnopqrstuvwxyz"
+    chan close $f1
+    set f1 [open $path(test1) r]
+    chan seek $f1 0 end
+    chan tell $f1
+} -cleanup {
+    chan close $f1
+} -result 54
+test chan-io-34.15 {Tcl_Tell combined with seeking} -setup {
+    file delete $path(test1)
+} -body {
+    set f1 [open $path(test1) w]
+    chan configure $f1 -translation lf -eofchar {}
+    chan puts $f1 "abcdefghijklmnopqrstuvwxyz"
+    chan puts $f1 "abcdefghijklmnopqrstuvwxyz"
+    chan close $f1
+    set f1 [open $path(test1) r]
+    chan seek $f1 10 start
+    set c1 [chan tell $f1]
+    chan seek $f1 10 current
+    list $c1 [chan tell $f1]
+} -cleanup {
+    chan close $f1
+} -result {10 20}
+test chan-io-34.16 {Tcl_Tell on pipe: always -1} -constraints {stdio openpipe} -body {
+    set f1 [openpipe]
+    chan tell $f1
+} -cleanup {
+    chan close $f1
+} -result -1
+test chan-io-34.17 {Tcl_Tell on pipe: always -1} {stdio openpipe} {
+    set f1 [openpipe]
+    chan puts $f1 {chan puts hello}
+    chan flush $f1
+    set c [chan tell $f1]
+    chan gets $f1
+    chan close $f1
+    set c
+} -1
+test chan-io-34.18 {Tcl_Tell combined with seeking and reading} -setup {
+    file delete $path(test2)
+} -body {
+    set f [open $path(test2) w]
+    chan configure $f -translation lf -eofchar {}
+    chan puts -nonewline $f "line1\nline2\nline3\nline4\nline5\n"
+    chan close $f
+    set f [open $path(test2)]
+    chan configure $f -translation lf
+    set x [chan tell $f]
+    chan read $f 3
+    lappend x [chan tell $f]
+    chan seek $f 2
+    lappend x [chan tell $f]
+    chan seek $f 10 current
+    lappend x [chan tell $f]
+    chan seek $f 0 end
+    lappend x [chan tell $f]
+} -cleanup {
+    chan close $f
+} -result {0 3 2 12 30}
+test chan-io-34.19 {Tcl_Tell combined with opening in append mode} -body {
+    set f [open $path(test3) w]
+    chan configure $f -translation lf -eofchar {}
+    chan puts $f "abcdefghijklmnopqrstuvwxyz"
+    chan puts $f "abcdefghijklmnopqrstuvwxyz"
+    chan close $f
+    set f [open $path(test3) a]
+    chan tell $f
+} -cleanup {
+    chan close $f
+} -result 54
+test chan-io-34.20 {Tcl_Tell combined with writing} -setup {
+    set l ""
+} -body {
+    set f [open $path(test3) w]
+    chan seek $f 29 start
+    lappend l [chan tell $f]
+    chan puts -nonewline $f a
+    chan seek $f 39 start
+    lappend l [chan tell $f]
+    chan puts -nonewline $f a
+    lappend l [chan tell $f]
+    chan seek $f 407 end
+    lappend l [chan tell $f]
+} -cleanup {
+    chan close $f
+} -result {29 39 40 447}
+test chan-io-34.21 {Tcl_Seek and Tcl_Tell on large files} -setup {
+    file delete $path(test3)
+    set l ""
+} -constraints {largefileSupport} -body {
+    set f [open $path(test3) w]
+    chan configure $f -encoding binary
+    lappend l [chan tell $f]
+    chan puts -nonewline $f abcdef
+    lappend l [chan tell $f]
+    chan flush $f
+    lappend l [chan tell $f]
+    # 4GB offset!
+    chan seek $f 0x100000000
+    lappend l [chan tell $f]
+    chan puts -nonewline $f abcdef
+    lappend l [chan tell $f]
+    chan close $f
+    lappend l [file size $path(test3)]
+    # truncate...
+    chan close [open $path(test3) w]
+    lappend l [file size $path(test3)]
+} -result {0 6 6 4294967296 4294967302 4294967302 0}
+
+# Test Tcl_Eof
+
+test chan-io-35.1 {Tcl_Eof} -setup {
+    file delete $path(test1)
+} -body {
+    set f [open $path(test1) w]
+    chan puts $f hello
+    chan puts $f hello
+    chan close $f
+    set f [open $path(test1)]
+    set x [chan eof $f]
+    lappend x [chan eof $f]
+    chan gets $f
+    lappend x [chan eof $f]
+    chan gets $f
+    lappend x [chan eof $f]
+    chan gets $f
+    lappend x [chan eof $f]
+    lappend x [chan eof $f]
+} -cleanup {
+    chan close $f
+} -result {0 0 0 0 1 1}
+test chan-io-35.2 {Tcl_Eof with pipe} -constraints {stdio openpipe} -setup {
+    file delete $path(pipe)
+} -body {
+    set f1 [open $path(pipe) w]
+    chan puts $f1 {chan gets stdin}
+    chan puts $f1 {chan puts hello}
+    chan close $f1
+    set f1 [openpipe r+ $path(pipe)]
+    chan puts $f1 hello
+    set x [chan eof $f1]
+    chan flush $f1
+    lappend x [chan eof $f1]
+    chan gets $f1
+    lappend x [chan eof $f1]
+    chan gets $f1
+    lappend x [chan eof $f1]
+} -cleanup {
+    chan close $f1
+} -result {0 0 0 1}
+test chan-io-35.3 {Tcl_Eof with pipe} -constraints {stdio openpipe} -setup {
+    file delete $path(pipe)
+} -body {
+    set f1 [open $path(pipe) w]
+    chan puts $f1 {chan gets stdin}
+    chan puts $f1 {chan puts hello}
+    chan close $f1
+    set f1 [openpipe r+ $path(pipe)]
+    chan puts $f1 hello
+    set x [chan eof $f1]
+    chan flush $f1
+    lappend x [chan eof $f1]
+    chan gets $f1
+    lappend x [chan eof $f1]
+    chan gets $f1
+    lappend x [chan eof $f1]
+    chan gets $f1
+    lappend x [chan eof $f1]
+    chan gets $f1
+    lappend x [chan eof $f1]
+} -cleanup {
+    chan close $f1
+} -result {0 0 0 1 1 1}
+test chan-io-35.4 {Tcl_Eof, eof detection on nonblocking file} -setup {
+    file delete $path(test1)
+    set l ""
+} -constraints {nonBlockFiles} -body {
+    chan close [open $path(test1) w]
+    set f [open $path(test1) r]
+    chan configure $f -blocking off
+    lappend l [chan gets $f]
+    lappend l [chan eof $f]
+} -cleanup {
+    chan close $f
+} -result {{} 1}
+test chan-io-35.5 {Tcl_Eof, eof detection on nonblocking pipe} -setup {
+    file delete $path(pipe)
+    set l ""
+} -constraints {stdio openpipe} -body {
+    set f [open $path(pipe) w]
+    chan puts $f {
+	exit
+    }
+    chan close $f
+    set f [openpipe r $path(pipe)]
+    lappend l [chan gets $f]
+    lappend l [chan eof $f]
+} -cleanup {
+    chan close $f
+} -result {{} 1}
+test chan-io-35.6 {Tcl_Eof, eof char, lf write, auto read} -setup {
+    file delete $path(test1)
+} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation lf -eofchar \x1a
+    chan puts $f abc\ndef
+    chan close $f
+    set s [file size $path(test1)]
+    set f [open $path(test1) r]
+    chan configure $f -translation auto -eofchar \x1a
+    list $s [string length [chan read $f]] [chan eof $f]
+} -cleanup {
+    chan close $f
+} -result {9 8 1}
+test chan-io-35.7 {Tcl_Eof, eof char, lf write, lf read} -setup {
+    file delete $path(test1)
+} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation lf -eofchar \x1a
+    chan puts $f abc\ndef
+    chan close $f
+    set s [file size $path(test1)]
+    set f [open $path(test1) r]
+    chan configure $f -translation lf -eofchar \x1a
+    list $s [string length [chan read $f]] [chan eof $f]
+} -cleanup {
+    chan close $f
+} -result {9 8 1}
+test chan-io-35.8 {Tcl_Eof, eof char, cr write, auto read} -setup {
+    file delete $path(test1)
+} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation cr -eofchar \x1a
+    chan puts $f abc\ndef
+    chan close $f
+    set s [file size $path(test1)]
+    set f [open $path(test1) r]
+    chan configure $f -translation auto -eofchar \x1a
+    list $s [string length [chan read $f]] [chan eof $f]
+} -cleanup {
+    chan close $f
+} -result {9 8 1}
+test chan-io-35.9 {Tcl_Eof, eof char, cr write, cr read} -setup {
+    file delete $path(test1)
+} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation cr -eofchar \x1a
+    chan puts $f abc\ndef
+    chan close $f
+    set s [file size $path(test1)]
+    set f [open $path(test1) r]
+    chan configure $f -translation cr -eofchar \x1a
+    list $s [string length [chan read $f]] [chan eof $f]
+} -cleanup {
+    chan close $f
+} -result {9 8 1}
+test chan-io-35.10 {Tcl_Eof, eof char, crlf write, auto read} -setup {
+    file delete $path(test1)
+} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation crlf -eofchar \x1a
+    chan puts $f abc\ndef
+    chan close $f
+    set s [file size $path(test1)]
+    set f [open $path(test1) r]
+    chan configure $f -translation auto -eofchar \x1a
+    list $s [string length [chan read $f]] [chan eof $f]
+} -cleanup {
+    chan close $f
+} -result {11 8 1}
+test chan-io-35.11 {Tcl_Eof, eof char, crlf write, crlf read} -setup {
+    file delete $path(test1)
+} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation crlf -eofchar \x1a
+    chan puts $f abc\ndef
+    chan close $f
+    set s [file size $path(test1)]
+    set f [open $path(test1) r]
+    chan configure $f -translation crlf -eofchar \x1a
+    list $s [string length [chan read $f]] [chan eof $f]
+} -cleanup {
+    chan close $f
+} -result {11 8 1}
+test chan-io-35.12 {Tcl_Eof, eof char in middle, lf write, auto read} -setup {
+    file delete $path(test1)
+} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation lf -eofchar {}
+    chan puts $f [format abc\ndef\n%cqrs\nuvw 26]
+    chan close $f
+    set c [file size $path(test1)]
+    set f [open $path(test1) r]
+    chan configure $f -translation auto -eofchar \x1a
+    list $c [string length [chan read $f]] [chan eof $f]
+} -cleanup {
+    chan close $f
+} -result {17 8 1}
+test chan-io-35.13 {Tcl_Eof, eof char in middle, lf write, lf read} -setup {
+    file delete $path(test1)
+} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation lf -eofchar {}
+    chan puts $f [format abc\ndef\n%cqrs\nuvw 26]
+    chan close $f
+    set c [file size $path(test1)]
+    set f [open $path(test1) r]
+    chan configure $f -translation lf -eofchar \x1a
+    list $c [string length [chan read $f]] [chan eof $f]
+} -cleanup {
+    chan close $f
+} -result {17 8 1}
+test chan-io-35.14 {Tcl_Eof, eof char in middle, cr write, auto read} -setup {
+    file delete $path(test1)
+} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation cr -eofchar {}
+    chan puts $f [format abc\ndef\n%cqrs\nuvw 26]
+    chan close $f
+    set c [file size $path(test1)]
+    set f [open $path(test1) r]
+    chan configure $f -translation auto -eofchar \x1a
+    list $c [string length [chan read $f]] [chan eof $f]
+} -cleanup {
+    chan close $f
+} -result {17 8 1}
+test chan-io-35.15 {Tcl_Eof, eof char in middle, cr write, cr read} -setup {
+    file delete $path(test1)
+} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation cr -eofchar {}
+    chan puts $f [format abc\ndef\n%cqrs\nuvw 26]
+    chan close $f
+    set c [file size $path(test1)]
+    set f [open $path(test1) r]
+    chan configure $f -translation cr -eofchar \x1a
+    list $c [string length [chan read $f]] [chan eof $f]
+} -cleanup {
+    chan close $f
+} -result {17 8 1}
+test chan-io-35.16 {Tcl_Eof, eof char in middle, crlf write, auto read} -setup {
+    file delete $path(test1)
+} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation crlf -eofchar {}
+    chan puts $f [format abc\ndef\n%cqrs\nuvw 26]
+    chan close $f
+    set c [file size $path(test1)]
+    set f [open $path(test1) r]
+    chan configure $f -translation auto -eofchar \x1a
+    list $c [string length [chan read $f]] [chan eof $f]
+} -cleanup {
+    chan close $f
+} -result {21 8 1}
+test chan-io-35.17 {Tcl_Eof, eof char in middle, crlf write, crlf read} -setup {
+    file delete $path(test1)
+} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation crlf -eofchar {}
+    chan puts $f [format abc\ndef\n%cqrs\nuvw 26]
+    chan close $f
+    set c [file size $path(test1)]
+    set f [open $path(test1) r]
+    chan configure $f -translation crlf -eofchar \x1a
+    list $c [string length [chan read $f]] [chan eof $f]
+} -cleanup {
+    chan close $f
+} -result {21 8 1}
+
+# Test Tcl_InputBlocked
+
+test chan-io-36.1 {Tcl_InputBlocked on nonblocking pipe} -setup {
+    set x ""
+} -constraints {stdio openpipe} -body {
+    set f1 [openpipe]
+    chan puts $f1 {chan puts hello_from_pipe}
+    chan flush $f1
+    chan gets $f1
+    chan configure $f1 -blocking off -buffering full
+    chan puts $f1 {chan puts hello}
+    lappend x [chan gets $f1]
+    lappend x [chan blocked $f1]
+    chan flush $f1
+    after 200
+    lappend x [chan gets $f1]
+    lappend x [chan blocked $f1]
+    lappend x [chan gets $f1]
+    lappend x [chan blocked $f1]
+} -cleanup {
+    chan close $f1
+} -result {{} 1 hello 0 {} 1}
+test chan-io-36.2 {Tcl_InputBlocked on blocking pipe} -setup {
+    set x ""
+} -constraints {stdio openpipe} -body {
+    set f1 [openpipe]
+    chan configure $f1 -buffering line
+    chan puts $f1 {chan puts hello_from_pipe}
+    lappend x [chan gets $f1]
+    lappend x [chan blocked $f1]
+    chan puts $f1 {exit}
+    lappend x [chan gets $f1]
+    lappend x [chan blocked $f1]
+    lappend x [chan eof $f1]
+} -cleanup {
+    chan close $f1
+} -result {hello_from_pipe 0 {} 0 1}
+test chan-io-36.3 {Tcl_InputBlocked vs files, short read} -setup {
+    file delete $path(test1)
+    set l ""
+} -body {
+    set f [open $path(test1) w]
+    chan puts $f abcdefghijklmnop
+    chan close $f
+    set f [open $path(test1) r]
+    lappend l [chan blocked $f]
+    lappend l [chan read $f 3]
+    lappend l [chan blocked $f]
+    lappend l [chan read -nonewline $f]
+    lappend l [chan blocked $f]
+    lappend l [chan eof $f]
+} -cleanup {
+    chan close $f
+} -result {0 abc 0 defghijklmnop 0 1}
+test chan-io-36.4 {Tcl_InputBlocked vs files, event driven read} -setup {
+    file delete $path(test1)
+    set l ""
+    variable x
+} -constraints {fileevent} -body {
+    set f [open $path(test1) w]
+    chan puts $f abcdefghijklmnop
+    chan close $f
+    set f [open $path(test1) r]
+    chan event $f readable [namespace code {
+	lappend l [chan read $f 3]
+	if {[chan eof $f]} {lappend l eof; chan close $f; set x done}
+    }]
+    vwait [namespace which -variable x]
+    return $l
+} -result {abc def ghi jkl mno {p
+} eof}
+test chan-io-36.5 {Tcl_InputBlocked vs files, short read, nonblocking} -setup {
+    file delete $path(test1)
+    set l ""
+} -constraints {nonBlockFiles} -body {
+    set f [open $path(test1) w]
+    chan puts $f abcdefghijklmnop
+    chan close $f
+    set f [open $path(test1) r]
+    chan configure $f -blocking off
+    lappend l [chan blocked $f]
+    lappend l [chan read $f 3]
+    lappend l [chan blocked $f]
+    lappend l [chan read -nonewline $f]
+    lappend l [chan blocked $f]
+    lappend l [chan eof $f]
+} -cleanup {
+    chan close $f
+} -result {0 abc 0 defghijklmnop 0 1}
+test chan-io-36.6 {Tcl_InputBlocked vs files, event driven read} -setup {
+    file delete $path(test1)
+    set l ""
+    variable x
+} -constraints {nonBlockFiles fileevent} -body {
+    set f [open $path(test1) w]
+    chan puts $f abcdefghijklmnop
+    chan close $f
+    set f [open $path(test1) r]
+    chan configure $f -blocking off
+    chan event $f readable [namespace code {
+	lappend l [chan read $f 3]
+	if {[chan eof $f]} {lappend l eof; chan close $f; set x done}
+    }]
+    vwait [namespace which -variable x]
+    return $l
+} -result {abc def ghi jkl mno {p
+} eof}
+
+# Test Tcl_InputBuffered
+
+test chan-io-37.1 {Tcl_InputBuffered} -setup {
+    set l ""
+} -constraints {testchannel} -body {
+    set f [open $path(longfile) r]
+    chan configure $f -buffersize 4096
+    chan read $f 3
+    lappend l [testchannel inputbuffered $f]
+    lappend l [chan tell $f]
+} -cleanup {
+    chan close $f
+} -result {4093 3}
+test chan-io-37.2 {Tcl_InputBuffered, test input flushing on seek} -setup {
+    set l ""
+} -constraints {testchannel} -body {
+    set f [open $path(longfile) r]
+    chan configure $f -buffersize 4096
+    chan read $f 3
+    lappend l [testchannel inputbuffered $f]
+    lappend l [chan tell $f]
+    chan seek $f 0 current
+    lappend l [testchannel inputbuffered $f]
+    lappend l [chan tell $f]
+} -cleanup {
+    chan close $f
+} -result {4093 3 0 3}
+
+# Test Tcl_SetChannelBufferSize, Tcl_GetChannelBufferSize
+
+test chan-io-38.1 {Tcl_GetChannelBufferSize, default buffer size} -body {
+    set f [open $path(longfile) r]
+    chan configure $f -buffersize
+} -cleanup {
+    chan close $f
+} -result 4096
+test chan-io-38.2 {Tcl_SetChannelBufferSize, Tcl_GetChannelBufferSize} -setup {
+    set l ""
+} -body {
+    set f [open $path(longfile) r]
+    lappend l [chan configure $f -buffersize]
+    chan configure $f -buffersize 10000
+    lappend l [chan configure $f -buffersize]
+    chan configure $f -buffersize 1
+    lappend l [chan configure $f -buffersize]
+    chan configure $f -buffersize -1
+    lappend l [chan configure $f -buffersize]
+    chan configure $f -buffersize 0
+    lappend l [chan configure $f -buffersize]
+    chan configure $f -buffersize 100000
+    lappend l [chan configure $f -buffersize]
+    chan configure $f -buffersize 10000000
+    lappend l [chan configure $f -buffersize]
+} -cleanup {
+    chan close $f
+} -result {4096 10000 1 1 1 100000 1048576}
+test chan-io-38.3 {Tcl_SetChannelBufferSize, changing buffersize between reads} {
+    # This test crashes the interp if Bug #427196 is not fixed
+    set chan [open [info script] r]
+    chan configure $chan -buffersize 10
+    set var [chan read $chan 2]
+    chan configure $chan -buffersize 32
+    append var [chan read $chan]
+    chan close $chan
+} {}
+
+# Test Tcl_SetChannelOption, Tcl_GetChannelOption
+
+test chan-io-39.1 {Tcl_GetChannelOption} -setup {
+    file delete $path(test1)
+} -body {
+    set f1 [open $path(test1) w]
+    chan configure $f1 -blocking
+} -cleanup {
+    chan close $f1
+} -result 1
+#
+# Test 17.2 was removed.
+#
+test chan-io-39.2 {Tcl_GetChannelOption} -setup {
+    file delete $path(test1)
+} -body {
+    set f1 [open $path(test1) w]
+    chan configure $f1 -buffering
+} -cleanup {
+    chan close $f1
+} -result full
+test chan-io-39.3 {Tcl_GetChannelOption} -setup {
+    file delete $path(test1)
+} -body {
+    set f1 [open $path(test1) w]
+    chan configure $f1 -buffering line
+    chan configure $f1 -buffering
+} -cleanup {
+    chan close $f1
+} -result line
+test chan-io-39.4 {Tcl_GetChannelOption, Tcl_SetChannelOption} -setup {
+    file delete $path(test1)
+    set l ""
+} -body {
+    set f1 [open $path(test1) w]
+    lappend l [chan configure $f1 -buffering]
+    chan configure $f1 -buffering line
+    lappend l [chan configure $f1 -buffering]
+    chan configure $f1 -buffering none
+    lappend l [chan configure $f1 -buffering]
+    chan configure $f1 -buffering line
+    lappend l [chan configure $f1 -buffering]
+    chan configure $f1 -buffering full
+    lappend l [chan configure $f1 -buffering]
+} -cleanup {
+    chan close $f1
+} -result {full line none line full}
+test chan-io-39.5 {Tcl_GetChannelOption, invariance} -setup {
+    file delete $path(test1)
+    set l ""
+} -body {
+    set f1 [open $path(test1) w]
+    lappend l [chan configure $f1 -buffering]
+    lappend l [list [catch {chan configure $f1 -buffering green} msg] $msg]
+    lappend l [chan configure $f1 -buffering]
+} -cleanup {
+    chan close $f1
+} -result {full {1 {bad value for -buffering: must be one of full, line, or none}} full}
+test chan-io-39.6 {Tcl_SetChannelOption, multiple options} -setup {
+    file delete $path(test1)
+} -body {
+    set f1 [open $path(test1) w]
+    chan configure $f1 -translation lf -buffering line
+    chan puts $f1 hello
+    chan puts $f1 bye
+    file size $path(test1)
+} -cleanup {
+    chan close $f1
+} -result 10
+test chan-io-39.7 {Tcl_SetChannelOption, buffering, translation} -setup {
+    file delete $path(test1)
+    set x ""
+} -body {
+    set f1 [open $path(test1) w]
+    chan configure $f1 -translation lf
+    chan puts $f1 hello
+    chan puts $f1 bye
+    chan configure $f1 -buffering line
+    lappend x [file size $path(test1)]
+    chan puts $f1 really_bye
+    lappend x [file size $path(test1)]
+} -cleanup {
+    chan close $f1
+} -result {0 21}
+test chan-io-39.8 {Tcl_SetChannelOption, different buffering options} -setup {
+    file delete $path(test1)
+    set l ""
+} -body {
+    set f1 [open $path(test1) w]
+    chan configure $f1 -translation lf -buffering none -eofchar {}
+    chan puts -nonewline $f1 hello
+    lappend l [file size $path(test1)]
+    chan puts -nonewline $f1 hello
+    lappend l [file size $path(test1)]
+    chan configure $f1 -buffering full
+    chan puts -nonewline $f1 hello
+    lappend l [file size $path(test1)]
+    chan configure $f1 -buffering none
+    lappend l [file size $path(test1)]
+    chan puts -nonewline $f1 hello
+    lappend l [file size $path(test1)]
+    chan close $f1
+    lappend l [file size $path(test1)]
+} -result {5 10 10 10 20 20}
+test chan-io-39.9 {Tcl_SetChannelOption, blocking mode} -setup {
+    file delete $path(test1)
+    set x ""
+} -constraints {nonBlockFiles} -body {
+    set f1 [open $path(test1) w]
+    chan close $f1
+    set f1 [open $path(test1) r]
+    lappend x [chan configure $f1 -blocking]
+    chan configure $f1 -blocking off
+    lappend x [chan configure $f1 -blocking]
+    lappend x [chan gets $f1]
+    lappend x [chan read $f1 1000]
+    lappend x [chan blocked $f1]
+    lappend x [chan eof $f1]
+} -cleanup {
+    chan close $f1
+} -result {1 0 {} {} 0 1}
+test chan-io-39.10 {Tcl_SetChannelOption, blocking mode} -setup {
+    file delete $path(pipe)
+    set x ""
+} -constraints {stdio openpipe} -body {
+    set f1 [open $path(pipe) w]
+    chan puts $f1 {
+	chan gets stdin
+	after 100
+	chan puts hi
+	chan gets stdin
+    }
+    chan close $f1
+    set f1 [openpipe r+ $path(pipe)]
+    chan configure $f1 -blocking off -buffering line
+    lappend x [chan configure $f1 -blocking]
+    lappend x [chan gets $f1]
+    lappend x [chan blocked $f1]
+    chan configure $f1 -blocking on
+    chan puts $f1 hello
+    chan configure $f1 -blocking off
+    lappend x [chan gets $f1]
+    lappend x [chan blocked $f1]
+    chan configure $f1 -blocking on
+    chan puts $f1 bye
+    chan configure $f1 -blocking off
+    lappend x [chan gets $f1]
+    lappend x [chan blocked $f1]
+    chan configure $f1 -blocking on
+    lappend x [chan configure $f1 -blocking]
+    lappend x [chan gets $f1]
+    lappend x [chan blocked $f1]
+    lappend x [chan eof $f1]
+    lappend x [chan gets $f1]
+    lappend x [chan eof $f1]
+} -cleanup {
+    chan close $f1
+} -result {0 {} 1 {} 1 {} 1 1 hi 0 0 {} 1}
+test chan-io-39.11 {Tcl_SetChannelOption, Tcl_GetChannelOption, buffer size clipped to lower bound} -setup {
+    file delete $path(test1)
+} -body {
+    set f [open $path(test1) w]
+    chan configure $f -buffersize -10
+    chan configure $f -buffersize
+} -cleanup {
+    chan close $f
+} -result 1
+test chan-io-39.12 {Tcl_SetChannelOption, Tcl_GetChannelOption buffer size clipped to upper bound} -setup {
+    file delete $path(test1)
+} -body {
+    set f [open $path(test1) w]
+    chan configure $f -buffersize 10000000
+    chan configure $f -buffersize
+} -cleanup {
+    chan close $f
+} -result 1048576
+test chan-io-39.13 {Tcl_SetChannelOption, Tcl_GetChannelOption, buffer size} -setup {
+    file delete $path(test1)
+} -body {
+    set f [open $path(test1) w]
+    chan configure $f -buffersize 40000
+    chan configure $f -buffersize
+} -cleanup {
+    chan close $f
+} -result 40000
+test chan-io-39.14 {Tcl_SetChannelOption: -encoding, binary & utf-8} -setup {
+    file delete $path(test1)
+} -body {
+    set f [open $path(test1) w]
+    chan configure $f -encoding {} 
+    chan puts -nonewline $f \xe7\x89\xa6
+    chan close $f
+    set f [open $path(test1) r]
+    chan configure $f -encoding utf-8
+    chan read $f
+} -cleanup {
+    chan close $f
+} -result \u7266
+test chan-io-39.15 {Tcl_SetChannelOption: -encoding, binary & utf-8} -setup {
+    file delete $path(test1)
+} -body {
+    set f [open $path(test1) w]
+    chan configure $f -encoding binary
+    chan puts -nonewline $f \xe7\x89\xa6
+    chan close $f
+    set f [open $path(test1) r]
+    chan configure $f -encoding utf-8
+    chan read $f
+} -cleanup {
+    chan close $f
+} -result \u7266
+test chan-io-39.16 {Tcl_SetChannelOption: -encoding, errors} -setup {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+} -body {
+    chan configure $f -encoding foobar
+} -returnCodes error -cleanup {
+    chan close $f
+} -result {unknown encoding "foobar"}
+test chan-io-39.17 {Tcl_SetChannelOption: -encoding, clearing CHANNEL_NEED_MORE_DATA} -setup {
+    variable x {}
+} -constraints {stdio openpipe fileevent} -body {
+    set f [openpipe r+ $path(cat)]
+    chan configure $f -encoding binary
+    chan puts -nonewline $f "\xe7"
+    chan flush $f
+    chan configure $f -encoding utf-8 -blocking 0
+    chan event $f readable [namespace code { lappend x [chan read $f] }]
+    vwait [namespace which -variable x]
+    after 300 [namespace code { lappend x timeout }]
+    vwait [namespace which -variable x]
+    chan configure $f -encoding utf-8
+    vwait [namespace which -variable x]
+    after 300 [namespace code { lappend x timeout }]
+    vwait [namespace which -variable x]
+    chan configure $f -encoding binary
+    vwait [namespace which -variable x]
+    after 300 [namespace code { lappend x timeout }]
+    vwait [namespace which -variable x]
+    return $x
+} -cleanup {
+    chan close $f
+} -result "{} timeout {} timeout \xe7 timeout"
+test chan-io-39.18 {Tcl_SetChannelOption, setting read mode independently} \
+	-constraints {socket} -body {
+    proc accept {s a p} {chan close $s}
+    set s1 [socket -server [namespace code accept] -myaddr 127.0.0.1 0]
+    set port [lindex [chan configure $s1 -sockname] 2]
+    set s2 [socket 127.0.0.1 $port]
+    update
+    chan configure $s2 -translation {auto lf}
+    chan configure $s2 -translation
+} -cleanup {
+    chan close $s1
+    chan close $s2
+} -result {auto lf}
+test chan-io-39.19 {Tcl_SetChannelOption, setting read mode independently} \
+	-constraints {socket} -body {
+    proc accept {s a p} {chan close $s}
+    set s1 [socket -server [namespace code accept] -myaddr 127.0.0.1 0]
+    set port [lindex [chan configure $s1 -sockname] 2]
+    set s2 [socket 127.0.0.1 $port]
+    update
+    chan configure $s2 -translation {auto crlf}
+    chan configure $s2 -translation
+} -cleanup {
+    chan close $s1
+    chan close $s2
+} -result {auto crlf}
+test chan-io-39.20 {Tcl_SetChannelOption, setting read mode independently} \
+	-constraints {socket} -body {
+    proc accept {s a p} {chan close $s}
+    set s1 [socket -server [namespace code accept] -myaddr 127.0.0.1 0]
+    set port [lindex [chan configure $s1 -sockname] 2]
+    set s2 [socket 127.0.0.1 $port]
+    update
+    chan configure $s2 -translation {auto cr}
+    chan configure $s2 -translation
+} -cleanup {
+    chan close $s1
+    chan close $s2
+} -result {auto cr}
+test chan-io-39.21 {Tcl_SetChannelOption, setting read mode independently} \
+	-constraints {socket} -body {
+    proc accept {s a p} {chan close $s}
+    set s1 [socket -server [namespace code accept] -myaddr 127.0.0.1 0]
+    set port [lindex [chan configure $s1 -sockname] 2]
+    set s2 [socket 127.0.0.1 $port]
+    update
+    chan configure $s2 -translation {auto auto}
+    chan configure $s2 -translation
+} -cleanup {
+    chan close $s1
+    chan close $s2
+} -result {auto crlf}
+test chan-io-39.22 {Tcl_SetChannelOption, invariance} -setup {
+    file delete $path(test1)
+    set l ""
+} -constraints {unix} -body {
+    set f1 [open $path(test1) w+]
+    lappend l [chan configure $f1 -eofchar]
+    chan configure $f1 -eofchar {ON GO}
+    lappend l [chan configure $f1 -eofchar]
+    chan configure $f1 -eofchar D
+    lappend l [chan configure $f1 -eofchar]
+} -cleanup {
+    chan close $f1
+} -result {{{} {}} {O G} {D D}}
+test chan-io-39.22a {Tcl_SetChannelOption, invariance} -setup {
+    file delete $path(test1)
+    set l [list]
+} -body {
+    set f1 [open $path(test1) w+]
+    chan configure $f1 -eofchar {ON GO}
+    lappend l [chan configure $f1 -eofchar]
+    chan configure $f1 -eofchar D
+    lappend l [chan configure $f1 -eofchar]
+    lappend l [list [catch {chan configure $f1 -eofchar {1 2 3}} msg] $msg]
+} -cleanup {
+    chan close $f1
+} -result {{O G} {D D} {1 {bad value for -eofchar: should be a list of zero, one, or two elements}}}
+test chan-io-39.23 {Tcl_GetChannelOption, server socket is not readable or\
+        writeable, it should still have valid -eofchar and -translation options} -setup {
+    set l [list]
+} -body {
+    set sock [socket -server [namespace code accept] -myaddr 127.0.0.1 0]
+    lappend l [chan configure $sock -eofchar] \
+	[chan configure $sock -translation]
+} -cleanup {
+    chan close $sock
+} -result {{{}} auto}
+test chan-io-39.24 {Tcl_SetChannelOption, server socket is not readable or\
+        writable so we can't change -eofchar or -translation} -setup {
+    set l [list]
+} -body { 
+    set sock [socket -server [namespace code accept] -myaddr 127.0.0.1 0]
+    chan configure $sock -eofchar D -translation lf
+    lappend l [chan configure $sock -eofchar] \
+	[chan configure $sock -translation]
+} -cleanup {
+    chan close $sock
+} -result {{{}} auto}
+
+test chan-io-40.1 {POSIX open access modes: RDWR} -setup {
+    file delete $path(test3)
+} -body {
+    set f [open $path(test3) w]
+    chan puts $f xyzzy
+    chan close $f
+    set f [open $path(test3) RDWR]
+    chan puts -nonewline $f "ab"
+    chan seek $f 0 current
+    set x [chan gets $f]
+    chan close $f
+    set f [open $path(test3) r]
+    lappend x [chan gets $f]
+} -cleanup {
+    chan close $f
+} -result {zzy abzzy}
+test chan-io-40.2 {POSIX open access modes: CREAT} -setup {
+    file delete $path(test3)
+} -constraints {unix} -body {
+    set f [open $path(test3) {WRONLY CREAT} 0600]
+    file stat $path(test3) stats
+    set x [format "0%o" [expr $stats(mode)&0o777]]
+    chan puts $f "line 1"
+    chan close $f
+    set f [open $path(test3) r]
+    lappend x [chan gets $f]
+} -cleanup {
+    chan close $f
+} -result {0600 {line 1}}
+test chan-io-40.3 {POSIX open access modes: CREAT} -setup {
+    file delete $path(test3)
+} -constraints {unix umask} -body {
+    # This test only works if your umask is 2, like ouster's.
+    chan close [open $path(test3) {WRONLY CREAT}]
+    file stat $path(test3) stats
+    format "0%o" [expr $stats(mode)&0o777]
+} -result [format %04o [expr {0o666 & ~ $umaskValue}]]
+test chan-io-40.4 {POSIX open access modes: CREAT} -setup {
+    file delete $path(test3)
+} -body {
+    set f [open $path(test3) w]
+    chan configure $f -eofchar {}
+    chan puts $f xyzzy
+    chan close $f
+    set f [open $path(test3) {WRONLY CREAT}]
+    chan configure $f -eofchar {}
+    chan puts -nonewline $f "ab"
+    chan close $f
+    set f [open $path(test3) r]
+    chan gets $f
+} -cleanup {
+    chan close $f
+} -result abzzy
+test chan-io-40.5 {POSIX open access modes: APPEND} -setup {
+    file delete $path(test3)
+    set x ""
+} -body {
+    set f [open $path(test3) w]
+    chan configure $f -translation lf -eofchar {}
+    chan puts $f xyzzy
+    chan close $f
+    set f [open $path(test3) {WRONLY APPEND}]
+    chan configure $f -translation lf
+    chan puts $f "new line"
+    chan seek $f 0
+    chan puts $f "abc"
+    chan close $f
+    set f [open $path(test3) r]
+    chan configure $f -translation lf
+    chan seek $f 6 current
+    lappend x [chan gets $f]
+    lappend x [chan gets $f]
+} -cleanup {
+    chan close $f
+} -result {{new line} abc}
+test chan-io-40.6 {POSIX open access modes: EXCL} -match regexp -setup {
+    file delete $path(test3)
+} -body {
+    set f [open $path(test3) w]
+    chan puts $f xyzzy
+    chan close $f
+    open $path(test3) {WRONLY CREAT EXCL}
+} -returnCodes error -result {(?i)couldn't open ".*test3": file (already )?exists}
+test chan-io-40.7 {POSIX open access modes: EXCL} -setup {
+    file delete $path(test3)
+} -body {
+    set f [open $path(test3) {WRONLY CREAT EXCL}]
+    chan configure $f -eofchar {}
+    chan puts $f "A test line"
+    chan close $f
+    viewFile test3
+} -result {A test line}
+test chan-io-40.8 {POSIX open access modes: TRUNC} -setup {
+    file delete $path(test3)
+} -body {
+    set f [open $path(test3) w]
+    chan puts $f xyzzy
+    chan close $f
+    set f [open $path(test3) {WRONLY TRUNC}]
+    chan puts $f abc
+    chan close $f
+    set f [open $path(test3) r]
+    chan gets $f
+} -cleanup {
+    chan close $f
+} -result abc
+test chan-io-40.9 {POSIX open access modes: NONBLOCK} -setup {
+    file delete $path(test3)
+} -constraints {nonPortable unix} -body {
+    set f [open $path(test3) {WRONLY NONBLOCK CREAT}]
+    chan puts $f "NONBLOCK test"
+    chan close $f
+    set f [open $path(test3) r]
+    chan gets $f
+} -cleanup {
+    chan close $f
+} -result {NONBLOCK test}
+test chan-io-40.10 {POSIX open access modes: RDONLY} -body {
+    set f [open $path(test1) w]
+    chan puts $f "two lines: this one"
+    chan puts $f "and this"
+    chan close $f
+    set f [open $path(test1) RDONLY]
+    list [chan gets $f] [catch {chan puts $f Test} msg] $msg
+} -cleanup {
+    chan close $f
+} -match glob -result {{two lines: this one} 1 {channel "*" wasn't opened for writing}}
+test chan-io-40.11 {POSIX open access modes: RDONLY} -match regexp -body {
+    file delete $path(test3)
+    open $path(test3) RDONLY
+} -returnCodes error -result {(?i)couldn't open ".*test3": no such file or directory}
+test chan-io-40.12 {POSIX open access modes: WRONLY} -match regexp -body {
+    file delete $path(test3)
+    open $path(test3) WRONLY
+} -returnCodes error -result {(?i)couldn't open ".*test3": no such file or directory}
+test chan-io-40.13 {POSIX open access modes: WRONLY} -body {
+    makeFile xyzzy test3
+    set f [open $path(test3) WRONLY]
+    chan configure $f -eofchar {}
+    chan puts -nonewline $f "ab"
+    chan seek $f 0 current
+    set x [list [catch {chan gets $f} msg] $msg]
+    chan close $f
+    lappend x [viewFile test3]
+} -match glob -result {1 {channel "*" wasn't opened for reading} abzzy} 
+test chan-io-40.14 {POSIX open access modes: RDWR} -match regexp -body {
+    file delete $path(test3)
+    open $path(test3) RDWR
+} -returnCodes error -result {(?i)couldn't open ".*test3": no such file or directory}
+test chan-io-40.15 {POSIX open access modes: RDWR} {
+    makeFile xyzzy test3
+    set f [open $path(test3) RDWR]
+    chan puts -nonewline $f "ab"
+    chan seek $f 0 current
+    set x [chan gets $f]
+    chan close $f
+    lappend x [viewFile test3]
+} {zzy abzzy}
+test chan-io-40.16 {tilde substitution in open} -constraints makeFileInHome -setup {
+    makeFile {Some text} _test_ ~
+} -body {
+    file exists [file join $::env(HOME) _test_]
+} -cleanup {
+    removeFile _test_ ~
+} -result 1
+test chan-io-40.17 {tilde substitution in open} -setup {
+    set home $::env(HOME)
+} -body {
+    unset ::env(HOME)
+    open ~/foo
+} -returnCodes error -cleanup {
+    set ::env(HOME) $home
+} -result {couldn't find HOME environment variable to expand path}
+
+test chan-io-41.1 {Tcl_FileeventCmd: errors} -constraints fileevent -body {
+    chan event foo
+} -returnCodes error -result {wrong # args: should be "chan event channelId event ?script?"}
+test chan-io-41.2 {Tcl_FileeventCmd: errors} -constraints fileevent -body {
+    chan event foo bar baz q
+} -returnCodes error -result {wrong # args: should be "chan event channelId event ?script?"}
+test chan-io-41.3 {Tcl_FileeventCmd: errors} -constraints fileevent -body {
+    chan event gorp readable
+} -returnCodes error -result {can not find channel named "gorp"}
+test chan-io-41.4 {Tcl_FileeventCmd: errors} -constraints fileevent -body {
+    chan event gorp writable
+} -returnCodes error -result {can not find channel named "gorp"}
+test chan-io-41.5 {Tcl_FileeventCmd: errors} -constraints fileevent -body {
+    chan event gorp who-knows
+} -returnCodes error -result {bad event name "who-knows": must be readable or writable}
+
+#
+# Test chan event on a file
+#
+
+set path(foo) [makeFile {} foo]
+set f [open $path(foo) w+]
+
+test chan-io-42.1 {Tcl_FileeventCmd: creating, deleting, querying} {fileevent} {
+    list [chan event $f readable] [chan event $f writable]
+} {{} {}}
+test chan-io-42.2 {Tcl_FileeventCmd: replacing} {fileevent} {
+    set result {}
+    chan event $f r "first script"
+    lappend result [chan event $f readable]
+    chan event $f r "new script"
+    lappend result [chan event $f readable]
+    chan event $f r "yet another"
+    lappend result [chan event $f readable]
+    chan event $f r ""
+    lappend result [chan event $f readable]
+} {{first script} {new script} {yet another} {}}
+test chan-io-42.3 {Tcl_FileeventCmd: replacing, with NULL chars in script} {fileevent} {
+    set result {}
+    chan event $f r "first scr\0ipt"
+    lappend result [string length [chan event $f readable]]
+    chan event $f r "new scr\0ipt"
+    lappend result [string length [chan event $f readable]]
+    chan event $f r "yet ano\0ther"
+    lappend result [string length [chan event $f readable]]
+    chan event $f r ""
+    lappend result [chan event $f readable]
+} {13 11 12 {}}
+
+test chan-io-43.1 {Tcl_FileeventCmd: creating, deleting, querying} {stdio unixExecs fileevent} {
+    set result {}
+    chan event $f readable "script 1"
+    lappend result [chan event $f readable] [chan event $f writable]
+    chan event $f writable "write script"
+    lappend result [chan event $f readable] [chan event $f writable]
+    chan event $f readable {}
+    lappend result [chan event $f readable] [chan event $f writable]
+    chan event $f writable {}
+    lappend result [chan event $f readable] [chan event $f writable]
+} {{script 1} {} {script 1} {write script} {} {write script} {} {}}
+test chan-io-43.2 {Tcl_FileeventCmd: deleting when many present} -setup {
+    set f2 [open "|[list cat -u]" r+]
+    set f3 [open "|[list cat -u]" r+]
+    set result {}
+} -constraints {stdio unixExecs fileevent openpipe} -body {
+    lappend result [chan event $f r] [chan event $f2 r] [chan event $f3 r]
+    chan event $f r "chan read f"
+    chan event $f2 r "chan read f2"
+    chan event $f3 r "chan read f3"
+    lappend result [chan event $f r] [chan event $f2 r] [chan event $f3 r]
+    chan event $f2 r {}
+    lappend result [chan event $f r] [chan event $f2 r] [chan event $f3 r]
+    chan event $f3 r {}
+    lappend result [chan event $f r] [chan event $f2 r] [chan event $f3 r]
+    chan event $f r {}
+    lappend result [chan event $f r] [chan event $f2 r] [chan event $f3 r]
+} -cleanup {
+    catch {chan close $f2}
+    catch {chan close $f3}
+} -result {{} {} {} {chan read f} {chan read f2} {chan read f3} {chan read f} {} {chan read f3} {chan read f} {} {} {} {} {}}
+
+test chan-io-44.1 {FileEventProc procedure: normal read event} -setup {
+    set f2 [open "|[list cat -u]" r+]
+    set f3 [open "|[list cat -u]" r+]
+} -constraints {stdio unixExecs fileevent openpipe} -body {
+    chan event $f2 readable [namespace code {
+	set x [chan gets $f2]; chan event $f2 readable {}
+    }]
+    chan puts $f2 text; chan flush $f2
+    variable x initial
+    vwait [namespace which -variable x]
+    return $x
+} -cleanup {
+    catch {chan close $f2}
+    catch {chan close $f3}
+} -result {text}
+test chan-io-44.2 {FileEventProc procedure: error in read event} -setup {
+    set f2 [open "|[list cat -u]" r+]
+    set f3 [open "|[list cat -u]" r+]
+    proc myHandler {msg options} {
+	variable x $msg
+    }
+    set handler [interp bgerror {}]
+    interp bgerror {} [namespace which myHandler]
+} -constraints {stdio unixExecs fileevent openpipe} -body {
+    chan event $f2 readable {error bogus}
+    chan puts $f2 text; chan flush $f2
+    variable x initial
+    vwait [namespace which -variable x]
+    list $x [chan event $f2 readable]
+} -cleanup {
+    interp bgerror {} $handler
+    catch {chan close $f2}
+    catch {chan close $f3}
+} -result {bogus {}}
+test chan-io-44.3 {FileEventProc procedure: normal write event} -setup {
+    set f2 [open "|[list cat -u]" r+]
+    set f3 [open "|[list cat -u]" r+]
+} -constraints {stdio unixExecs fileevent openpipe} -body {
+    chan event $f2 writable [namespace code {
+	lappend x "triggered"
+	incr count -1
+	if {$count <= 0} {
+	    chan event $f2 writable {}
+	}
+    }]
+    variable x initial
+    set count 3
+    vwait [namespace which -variable x]
+    vwait [namespace which -variable x]
+    vwait [namespace which -variable x]
+    return $x
+} -cleanup {
+    catch {chan close $f2}
+    catch {chan close $f3}
+} -result {initial triggered triggered triggered}
+test chan-io-44.4 {FileEventProc procedure: eror in write event} -setup {
+    set f2 [open "|[list cat -u]" r+]
+    set f3 [open "|[list cat -u]" r+]
+    proc myHandler {msg options} {
+	variable x $msg
+    }
+    set handler [interp bgerror {}]
+    interp bgerror {} [namespace which myHandler]
+} -constraints {stdio unixExecs fileevent openpipe} -body {
+    chan event $f2 writable {error bad-write}
+    variable x initial
+    vwait [namespace which -variable x]
+    list $x [chan event $f2 writable]
+} -cleanup {
+    interp bgerror {} $handler
+    catch {chan close $f2}
+    catch {chan close $f3}
+} -result {bad-write {}}
+test chan-io-44.5 {FileEventProc procedure: end of file} {stdio unixExecs openpipe fileevent} {
+    set f4 [openpipe r $path(cat) << foo]
+    chan event $f4 readable [namespace code {
+	if {[chan gets $f4 line] < 0} {
+	    lappend x eof
+	    chan event $f4 readable {}
+	} else {
+	    lappend x $line
+	}
+    }]
+    variable x initial
+    vwait [namespace which -variable x]
+    vwait [namespace which -variable x]
+    chan close $f4
+    set x
+} {initial foo eof}
+
+chan close $f
+makeFile "foo bar" foo
+
+test chan-io-45.1 {DeleteFileEvent, cleanup on chan close} {fileevent} {
+    set f [open $path(foo) r]
+    chan event $f readable [namespace code {
+	lappend x "binding triggered: \"[chan gets $f]\""
+	chan event $f readable {}
+    }]
+    chan close $f
+    set x initial
+    after 100 [namespace code {
+	set y done
+    }]
+    variable y
+    vwait [namespace which -variable y]
+    set x
+} {initial}
+test chan-io-45.2 {DeleteFileEvent, cleanup on chan close} {fileevent} {
+    set f  [open $path(foo) r]
+    set f2 [open $path(foo) r]
+    chan event $f readable [namespace code {
+	lappend x "f triggered: \"[chan gets $f]\""
+	chan event $f readable {}
+    }]
+    chan event $f2 readable [namespace code {
+	lappend x "f2 triggered: \"[chan gets $f2]\""
+	chan event $f2 readable {}
+    }]
+    chan close $f
+    variable x initial
+    vwait [namespace which -variable x]
+    chan close $f2
+    set x
+} {initial {f2 triggered: "foo bar"}}
+test chan-io-45.3 {DeleteFileEvent, cleanup on chan close} {fileevent} {
+    set f  [open $path(foo) r]
+    set f2 [open $path(foo) r]
+    set f3 [open $path(foo) r]
+    chan event $f readable {f script}
+    chan event $f2 readable {f2 script}
+    chan event $f3 readable {f3 script}
+    set x {}
+    chan close $f2
+    lappend x [catch {chan event $f readable} msg] $msg \
+	    [catch {chan event $f2 readable}] \
+	    [catch {chan event $f3 readable} msg] $msg
+    chan close $f3
+    lappend x [catch {chan event $f readable} msg] $msg \
+	    [catch {chan event $f2 readable}] \
+	    [catch {chan event $f3 readable}]
+    chan close $f
+    lappend x [catch {chan event $f readable}] \
+	    [catch {chan event $f2 readable}] \
+	    [catch {chan event $f3 readable}]
+} {0 {f script} 1 0 {f3 script} 0 {f script} 1 1 1 1 1}
+
+# Execute these tests only if the "testfevent" command is present.
+
+test chan-io-46.1 {Tcl event loop vs multiple interpreters} {testfevent fileevent} {
+    testfevent create
+    set script "set f \[[list open $path(foo) r]]\n"
+    append script {
+	set x "no event"
+	chan event $f readable [namespace code {
+	    set x "f triggered: [chan gets $f]"
+	    chan event $f readable {}
+	}]
+    }
+    testfevent cmd $script
+    after 1	;# We must delay because Windows takes a little time to notice
+    update
+    testfevent cmd {chan close $f}
+    list [testfevent cmd {set x}] [testfevent cmd {info commands after}]
+} {{f triggered: foo bar} after}
+test chan-io-46.2 {Tcl event loop vs multiple interpreters} testfevent {
+    testfevent create
+    testfevent cmd {
+        variable x 0
+        after 100 {set x triggered}
+        vwait [namespace which -variable x]
+        set x
+    }
+} {triggered}
+test chan-io-46.3 {Tcl event loop vs multiple interpreters} testfevent {
+    testfevent create
+    testfevent cmd {
+        set x 0
+        after 10 {lappend x timer}
+        after 30
+        set result $x
+        update idletasks
+        lappend result $x
+        update
+        lappend result $x
+    }
+} {0 0 {0 timer}}
+
+test chan-io-47.1 {chan event vs multiple interpreters} -setup {
+    set f  [open $path(foo) r]
+    set f2 [open $path(foo) r]
+    set f3 [open $path(foo) r]
+    set x {}
+} -constraints {testfevent fileevent} -body {
+    chan event $f readable {script 1}
+    testfevent create
+    testfevent share $f2
+    testfevent cmd "chan event $f2 readable {script 2}"
+    chan event $f3 readable {sript 3}
+    lappend x [chan event $f2 readable]
+    testfevent delete
+    lappend x [chan event $f readable] [chan event $f2 readable] \
+        [chan event $f3 readable]
+} -cleanup {
+    chan close $f
+    chan close $f2
+    chan close $f3
+} -result {{} {script 1} {} {sript 3}}
+test chan-io-47.2 {deleting chan event on interpreter delete} -setup {
+    set f  [open $path(foo) r]
+    set f2 [open $path(foo) r]
+    set f3 [open $path(foo) r]
+    set f4 [open $path(foo) r]
+} -constraints {testfevent fileevent} -body {
+    chan event $f readable {script 1}
+    testfevent create
+    testfevent share $f2
+    testfevent share $f3
+    testfevent cmd "chan event $f2 readable {script 2}
+        chan event $f3 readable {script 3}"
+    chan event $f4 readable {script 4}
+    testfevent delete
+    list [chan event $f readable] [chan event $f2 readable] \
+	[chan event $f3 readable] [chan event $f4 readable]
+} -cleanup {
+    chan close $f
+    chan close $f2
+    chan close $f3
+    chan close $f4
+} -result {{script 1} {} {} {script 4}}
+test chan-io-47.3 {deleting chan event on interpreter delete} -setup {
+    set f  [open $path(foo) r]
+    set f2 [open $path(foo) r]
+    set f3 [open $path(foo) r]
+    set f4 [open $path(foo) r]
+} -constraints {testfevent fileevent} -body {
+    testfevent create
+    testfevent share $f3
+    testfevent share $f4
+    chan event $f readable {script 1}
+    chan event $f2 readable {script 2}
+    testfevent cmd "chan event $f3 readable {script 3}
+      chan event $f4 readable {script 4}"
+    testfevent delete
+    list [chan event $f readable] [chan event $f2 readable] \
+	[chan event $f3 readable] [chan event $f4 readable]
+} -cleanup {
+    chan close $f
+    chan close $f2
+    chan close $f3
+    chan close $f4
+} -result {{script 1} {script 2} {} {}}
+test chan-io-47.4 {file events on shared files and multiple interpreters} -setup {
+    set f  [open $path(foo) r]
+    set f2 [open $path(foo) r]
+} -constraints {testfevent fileevent} -body {
+    testfevent create
+    testfevent share $f
+    testfevent cmd "chan event $f readable {script 1}"
+    chan event $f readable {script 2}
+    chan event $f2 readable {script 3}
+    list [chan event $f2 readable] [testfevent cmd "chan event $f readable"] \
+	[chan event $f readable]
+} -cleanup {
+    testfevent delete
+    chan close $f
+    chan close $f2
+} -result {{script 3} {script 1} {script 2}}
+test chan-io-47.5 {file events on shared files, deleting file events} -setup {
+    set f [open $path(foo) r]
+} -body {
+    testfevent create
+    testfevent share $f
+    testfevent cmd "chan event $f readable {script 1}"
+    chan event $f readable {script 2}
+    testfevent cmd "chan event $f readable {}"
+    list [testfevent cmd "chan event $f readable"] [chan event $f readable]
+} -constraints {testfevent fileevent} -cleanup {
+    testfevent delete
+    chan close $f
+} -result {{} {script 2}}
+test chan-io-47.6 {file events on shared files, deleting file events} -setup {
+    set f [open $path(foo) r]
+} -body {
+    testfevent create
+    testfevent share $f
+    testfevent cmd "chan event $f readable {script 1}"
+    chan event $f readable {script 2}
+    chan event $f readable {}
+    list [testfevent cmd "chan event $f readable"] [chan event $f readable]
+} -constraints {testfevent fileevent} -cleanup {
+    testfevent delete
+    chan close $f
+} -result {{script 1} {}}
+
+set path(bar) [makeFile {} bar]
+
+test chan-io-48.1 {testing readability conditions} {fileevent} {
+    set f [open $path(bar) w]
+    chan puts $f abcdefg
+    chan puts $f abcdefg
+    chan puts $f abcdefg
+    chan puts $f abcdefg
+    chan puts $f abcdefg
+    chan close $f
+    set f [open $path(bar) r]
+    chan event $f readable [namespace code {
+	lappend l called
+	if {[chan eof $f]} {
+	    chan close $f
+	    set x done
+	} else {
+	    chan gets $f
+	}
+    }]
+    set l ""
+    variable x not_done
+    vwait [namespace which -variable x]
+    list $x $l
+} {done {called called called called called called called}}
+test chan-io-48.2 {testing readability conditions} {nonBlockFiles fileevent} {
+    set f [open $path(bar) w]
+    chan puts $f abcdefg
+    chan puts $f abcdefg
+    chan puts $f abcdefg
+    chan puts $f abcdefg
+    chan puts $f abcdefg
+    chan close $f
+    set f [open $path(bar) r]
+    chan event $f readable [namespace code {
+	lappend l called
+	if {[chan eof $f]} {
+	    chan close $f
+	    set x done
+	} else {
+	    chan gets $f
+	}
+    }]
+    chan configure $f -blocking off
+    set l ""
+    variable x not_done
+    vwait [namespace which -variable x]
+    list $x $l
+} {done {called called called called called called called}}
+set path(my_script) [makeFile {} my_script]
+test chan-io-48.3 {testing readability conditions} -setup {
+    set l ""
+} -constraints {stdio unix nonBlockFiles openpipe fileevent} -body {
+    set f [open $path(bar) w]
+    chan puts $f abcdefg
+    chan puts $f abcdefg
+    chan puts $f abcdefg
+    chan puts $f abcdefg
+    chan puts $f abcdefg
+    chan close $f
+    set f [open $path(my_script) w]
+    chan puts $f {
+	proc copy_slowly {f} {
+	    while {![chan eof $f]} {
+		chan puts [chan gets $f]
+		after 200
+	    }
+	    chan close $f
+	}
+    }
+    chan close $f
+    set f [openpipe]
+    chan event $f readable [namespace code {
+	if {[chan eof $f]} {
+	    set x done
+	} else {
+	    chan gets $f
+	    lappend l [chan blocked $f]
+	    chan gets $f
+	    lappend l [chan blocked $f]
+	}
+    }]
+    chan configure $f -buffering line
+    chan configure $f -blocking off
+    variable x not_done
+    chan puts $f [list source $path(my_script)]
+    chan puts $f "set f \[[list open $path(bar) r]]"
+    chan puts $f {copy_slowly $f}
+    chan puts $f {exit}
+    vwait [namespace which -variable x]
+    list $x $l
+} -cleanup {
+    chan close $f
+} -result {done {0 1 0 1 0 1 0 1 0 1 0 1 0 0}}
+test chan-io-48.4 {lf write, testing readability, ^Z termination, auto read mode} -setup {
+    file delete $path(test1)
+    set c 0
+    set l ""
+} -constraints {fileevent} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation lf
+    chan puts -nonewline $f [format "abc\ndef\n%c" 26]
+    chan close $f
+    set f [open $path(test1) r]
+    chan configure $f -translation auto -eofchar \x1a
+    chan event $f readable [namespace code {
+	if {[chan eof $f]} {
+	   set x done
+	   chan close $f
+	} else {
+	   lappend l [chan gets $f]
+	   incr c
+	}
+    }]
+    variable x
+    vwait [namespace which -variable x]
+    list $c $l
+} -result {3 {abc def {}}}
+test chan-io-48.5 {lf write, testing readability, ^Z in middle, auto read mode} -setup {
+    file delete $path(test1)
+    set c 0
+    set l ""
+} -constraints {fileevent} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation lf
+    chan puts -nonewline $f [format "abc\ndef\n%cfoo\nbar\n" 26]
+    chan close $f
+    set f [open $path(test1) r]
+    chan configure $f -eofchar \x1a -translation auto
+    chan event $f readable [namespace code {
+	if {[chan eof $f]} {
+	   set x done
+	   chan close $f
+	} else {
+	   lappend l [chan gets $f]
+	   incr c
+	}
+    }]
+    variable x
+    vwait [namespace which -variable x]
+    list $c $l
+} -result {3 {abc def {}}}
+test chan-io-48.6 {cr write, testing readability, ^Z termination, auto read mode} -setup {
+    file delete $path(test1)
+    set c 0
+    set l ""
+} -constraints {fileevent} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation cr
+    chan puts -nonewline $f [format "abc\ndef\n%c" 26]
+    chan close $f
+    set f [open $path(test1) r]
+    chan configure $f -translation auto -eofchar \x1a
+    chan event $f readable [namespace code {
+	if {[chan eof $f]} {
+	   set x done
+	   chan close $f
+	} else {
+	   lappend l [chan gets $f]
+	   incr c
+	}
+    }]
+    variable x
+    vwait [namespace which -variable x]
+    list $c $l
+} -result {3 {abc def {}}}
+test chan-io-48.7 {cr write, testing readability, ^Z in middle, auto read mode} -setup {
+    file delete $path(test1)
+    set c 0
+    set l ""
+} -constraints {fileevent} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation cr
+    chan puts -nonewline $f [format "abc\ndef\n%cfoo\nbar\n" 26]
+    chan close $f
+    set f [open $path(test1) r]
+    chan configure $f -eofchar \x1a -translation auto
+    chan event $f readable [namespace code {
+	if {[chan eof $f]} {
+	   set x done
+	   chan close $f
+	} else {
+	   lappend l [chan gets $f]
+	   incr c
+	}
+    }]
+    variable x
+    vwait [namespace which -variable x]
+    list $c $l
+} -result {3 {abc def {}}}
+test chan-io-48.8 {crlf write, testing readability, ^Z termination, auto read mode} -setup {
+    file delete $path(test1)
+    set c 0
+    set l ""
+} -constraints {fileevent} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation crlf
+    chan puts -nonewline $f [format "abc\ndef\n%c" 26]
+    chan close $f
+    set f [open $path(test1) r]
+    chan configure $f -translation auto -eofchar \x1a
+    chan event $f readable [namespace code {
+	if {[chan eof $f]} {
+	   set x done
+	   chan close $f
+	} else {
+	   lappend l [chan gets $f]
+	   incr c
+	}
+    }]
+    variable x
+    vwait [namespace which -variable x]
+    list $c $l
+} -result {3 {abc def {}}}
+test chan-io-48.9 {crlf write, testing readability, ^Z in middle, auto read mode} -setup {
+    file delete $path(test1)
+    set c 0
+    set l ""
+} -constraints {fileevent} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation crlf
+    chan puts -nonewline $f [format "abc\ndef\n%cfoo\nbar\n" 26]
+    chan close $f
+    set f [open $path(test1) r]
+    chan configure $f -eofchar \x1a -translation auto
+    chan event $f readable [namespace code {
+	if {[chan eof $f]} {
+	   set x done
+	   chan close $f
+	} else {
+	   lappend l [chan gets $f]
+	   incr c
+	}
+    }]
+    variable x
+    vwait [namespace which -variable x]
+    list $c $l
+} -result {3 {abc def {}}}
+test chan-io-48.10 {lf write, testing readability, ^Z in middle, lf read mode} -setup {
+    file delete $path(test1)
+    set c 0
+    set l ""
+} -constraints {fileevent} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation lf
+    chan puts -nonewline $f [format "abc\ndef\n%cfoo\nbar\n" 26]
+    chan close $f
+    set f [open $path(test1) r]
+    chan configure $f -eofchar \x1a -translation lf
+    chan event $f readable [namespace code {
+	if {[chan eof $f]} {
+	   set x done
+	   chan close $f
+	} else {
+	   lappend l [chan gets $f]
+	   incr c
+	}
+    }]
+    variable x
+    vwait [namespace which -variable x]
+    list $c $l
+} -result {3 {abc def {}}}
+test chan-io-48.11 {lf write, testing readability, ^Z termination, lf read mode} -setup {
+    file delete $path(test1)
+    set c 0
+    set l ""
+} -constraints {fileevent} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation lf
+    chan puts -nonewline $f [format "abc\ndef\n%c" 26]
+    chan close $f
+    set f [open $path(test1) r]
+    chan configure $f -translation lf -eofchar \x1a
+    chan event $f readable [namespace code {
+	if {[chan eof $f]} {
+	   set x done
+	   chan close $f
+	} else {
+	   lappend l [chan gets $f]
+	   incr c
+	}
+    }]
+    variable x
+    vwait [namespace which -variable x]
+    list $c $l
+} -result {3 {abc def {}}}
+test chan-io-48.12 {cr write, testing readability, ^Z in middle, cr read mode} -setup {
+    file delete $path(test1)
+    set c 0
+    set l ""
+} -constraints {fileevent} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation cr
+    chan puts -nonewline $f [format "abc\ndef\n%cfoo\nbar\n" 26]
+    chan close $f
+    set f [open $path(test1) r]
+    chan configure $f -eofchar \x1a -translation cr
+    chan event $f readable [namespace code {
+	if {[chan eof $f]} {
+	   set x done
+	   chan close $f
+	} else {
+	   lappend l [chan gets $f]
+	   incr c
+	}
+    }]
+    variable x
+    vwait [namespace which -variable x]
+    list $c $l
+} -result {3 {abc def {}}}
+test chan-io-48.13 {cr write, testing readability, ^Z termination, cr read mode} -setup {
+    file delete $path(test1)
+    set c 0
+    set l ""
+} -constraints {fileevent} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation cr
+    chan puts -nonewline $f [format "abc\ndef\n%c" 26]
+    chan close $f
+    set f [open $path(test1) r]
+    chan configure $f -translation cr -eofchar \x1a
+    chan event $f readable [namespace code {
+	if {[chan eof $f]} {
+	   set x done
+	   chan close $f
+	} else {
+	   lappend l [chan gets $f]
+	   incr c
+	}
+    }]
+    variable x
+    vwait [namespace which -variable x]
+    list $c $l
+} -result {3 {abc def {}}}
+test chan-io-48.14 {crlf write, testing readability, ^Z in middle, crlf read mode} -setup {
+    file delete $path(test1)
+    set c 0
+    set l ""
+} -constraints {fileevent} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation crlf
+    chan puts -nonewline $f [format "abc\ndef\n%cfoo\nbar\n" 26]
+    chan close $f
+    set f [open $path(test1) r]
+    chan configure $f -eofchar \x1a -translation crlf
+    chan event $f readable [namespace code {
+	if {[chan eof $f]} {
+	   set x done
+	   chan close $f
+	} else {
+	   lappend l [chan gets $f]
+	   incr c
+	}
+    }]
+    variable x
+    vwait [namespace which -variable x]
+    list $c $l
+} -result {3 {abc def {}}}
+test chan-io-48.15 {crlf write, testing readability, ^Z termi, crlf read mode} -setup {
+    file delete $path(test1)
+    set c 0
+    set l ""
+} -constraints {fileevent} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation crlf
+    chan puts -nonewline $f [format "abc\ndef\n%c" 26]
+    chan close $f
+    set f [open $path(test1) r]
+    chan configure $f -translation crlf -eofchar \x1a
+    chan event $f readable [namespace code {
+	if {[chan eof $f]} {
+	   set x done
+	   chan close $f
+	} else {
+	   lappend l [chan gets $f]
+	   incr c
+	}
+    }]
+    variable x
+    vwait [namespace which -variable x]
+    list $c $l
+} -result {3 {abc def {}}}
+
+test chan-io-49.1 {testing crlf reading, leftover cr disgorgment} -setup {
+    file delete $path(test1)
+    set l ""
+} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation lf
+    chan puts -nonewline $f "a\rb\rc\r\n"
+    chan close $f
+    set f [open $path(test1) r]
+    lappend l [file size $path(test1)]
+    chan configure $f -translation crlf
+    lappend l [chan read $f 1]
+    lappend l [chan tell $f]
+    lappend l [chan read $f 1]
+    lappend l [chan tell $f]
+    lappend l [chan read $f 1]
+    lappend l [chan tell $f]
+    lappend l [chan read $f 1]
+    lappend l [chan tell $f]
+    lappend l [chan read $f 1]
+    lappend l [chan tell $f]
+    lappend l [chan read $f 1]
+    lappend l [chan tell $f]
+    lappend l [chan eof $f]
+    lappend l [chan read $f 1]
+    lappend l [chan eof $f]
+} -cleanup {
+    chan close $f
+} -result "7 a 1 [list \r] 2 b 3 [list \r] 4 c 5 {
+} 7 0 {} 1"
+test chan-io-49.2 {testing crlf reading, leftover cr disgorgment} -setup {
+    file delete $path(test1)
+    set l ""
+} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation lf
+    chan puts -nonewline $f "a\rb\rc\r\n"
+    chan close $f
+    set f [open $path(test1) r]
+    lappend l [file size $path(test1)]
+    chan configure $f -translation crlf
+    lappend l [chan read $f 2]
+    lappend l [chan tell $f]
+    lappend l [chan read $f 2]
+    lappend l [chan tell $f]
+    lappend l [chan read $f 2]
+    lappend l [chan tell $f]
+    lappend l [chan eof $f]
+    lappend l [chan read $f 2]
+    lappend l [chan tell $f]
+    lappend l [chan eof $f]
+} -cleanup {
+    chan close $f
+} -result "7 [list a\r] 2 [list b\r] 4 [list c\n] 7 0 {} 7 1"
+test chan-io-49.3 {testing crlf reading, leftover cr disgorgment} -setup {
+    file delete $path(test1)
+    set l ""
+} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation lf
+    chan puts -nonewline $f "a\rb\rc\r\n"
+    chan close $f
+    set f [open $path(test1) r]
+    lappend l [file size $path(test1)]
+    chan configure $f -translation crlf
+    lappend l [chan read $f 3]
+    lappend l [chan tell $f]
+    lappend l [chan read $f 3]
+    lappend l [chan tell $f]
+    lappend l [chan eof $f]
+    lappend l [chan read $f 3]
+    lappend l [chan tell $f]
+    lappend l [chan eof $f]
+} -cleanup {
+    chan close $f
+} -result "7 [list a\rb] 3 [list \rc\n] 7 0 {} 7 1"
+test chan-io-49.4 {testing crlf reading, leftover cr disgorgment} -setup {
+    file delete $path(test1)
+    set l ""
+} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation lf
+    chan puts -nonewline $f "a\rb\rc\r\n"
+    chan close $f
+    set f [open $path(test1) r]
+    lappend l [file size $path(test1)]
+    chan configure $f -translation crlf
+    lappend l [chan read $f 3]
+    lappend l [chan tell $f]
+    lappend l [chan gets $f]
+    lappend l [chan tell $f]
+    lappend l [chan eof $f]
+    lappend l [chan gets $f]
+    lappend l [chan tell $f]
+    lappend l [chan eof $f]
+} -cleanup {
+    chan close $f
+} -result "7 [list a\rb] 3 [list \rc] 7 0 {} 7 1"
+test chan-io-49.5 {testing crlf reading, leftover cr disgorgment} -setup {
+    file delete $path(test1)
+    set l ""
+} -body {
+    set f [open $path(test1) w]
+    chan configure $f -translation lf
+    chan puts -nonewline $f "a\rb\rc\r\n"
+    chan close $f
+    set f [open $path(test1) r]
+    lappend l [file size $path(test1)]
+    chan configure $f -translation crlf
+    lappend l [set x [chan gets $f]]
+    lappend l [chan tell $f]
+    lappend l [chan gets $f]
+    lappend l [chan tell $f]
+    lappend l [chan eof $f]
+} -cleanup {
+    chan close $f
+} -result [list 7 a\rb\rc 7 {} 7 1]
+
+test chan-io-50.1 {testing handler deletion} -setup {
+    file delete $path(test1)
+} -constraints {testchannelevent} -body {
+    set f [open $path(test1) w]
+    chan close $f
+    set f [open $path(test1) r]
+    testchannelevent $f add readable [namespace code {
+	variable z called
+	testchannelevent $f delete 0
+    }]
+    variable z not_called
+    update
+    return $z
+} -cleanup {
+    chan close $f
+} -result called
+test chan-io-50.2 {testing handler deletion with multiple handlers} -setup {
+    file delete $path(test1)
+    chan close [open $path(test1) w]
+    set z ""
+} -constraints {testchannelevent} -body {
+    set f [open $path(test1) r]
+    testchannelevent $f add readable [namespace code [list delhandler $f 1]]
+    testchannelevent $f add readable [namespace code [list delhandler $f 0]]
+    proc delhandler {f i} {
+	variable z
+	lappend z "called delhandler $f $i"
+	testchannelevent $f delete 0
+    }
+    update
+    string equal $z \
+	[list [list called delhandler $f 0] [list called delhandler $f 1]]
+} -cleanup {
+    chan close $f
+} -result 1
+test chan-io-50.3 {testing handler deletion with multiple handlers} -setup {
+    file delete $path(test1)
+    chan close [open $path(test1) w]
+    set z ""
+} -constraints {testchannelevent} -body {
+    set f [open $path(test1) r]
+    testchannelevent $f add readable [namespace code [list notcalled $f 1]]
+    testchannelevent $f add readable [namespace code [list delhandler $f 0]]
+    proc notcalled {f i} {
+	variable z
+	lappend z "notcalled was called!! $f $i"
+    }
+    proc delhandler {f i} {
+	variable z
+	testchannelevent $f delete 1
+	lappend z "delhandler $f $i called"
+	testchannelevent $f delete 0
+	lappend z "delhandler $f $i deleted myself"
+    }
+    update
+    string equal $z \
+	[list [list delhandler $f 0 called] \
+	      [list delhandler $f 0 deleted myself]]
+} -cleanup {
+    chan close $f
+} -result 1
+test chan-io-50.4 {testing handler deletion vs reentrant calls} -setup {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    chan close $f
+} -constraints {testchannelevent} -body {
+    set f [open $path(test1) r]
+    testchannelevent $f add readable [namespace code {
+	if {$u eq "recursive"} {
+	    testchannelevent $f delete 0
+	    lappend z "delrecursive deleting recursive"
+	} else {
+	    lappend z "delrecursive calling recursive"
+	    set u recursive
+	    update
+	}
+    }]
+    variable u toplevel
+    variable z ""
+    update
+    return $z
+} -cleanup {
+    chan close $f
+} -result {{delrecursive calling recursive} {delrecursive deleting recursive}}
+test chan-io-50.5 {testing handler deletion vs reentrant calls} -setup {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    chan close $f
+} -constraints {testchannelevent} -body {
+    set f [open $path(test1) r]
+    testchannelevent $f add readable [namespace code [list notcalled $f]]
+    testchannelevent $f add readable [namespace code [list del $f]]
+    proc notcalled {f} {
+	variable z
+	lappend z "notcalled was called!! $f"
+    }
+    proc del {f} {
+	variable u
+	variable z
+	if {$u eq "recursive"} {
+	    testchannelevent $f delete 1
+	    testchannelevent $f delete 0
+	    lappend z "del deleted notcalled"
+	    lappend z "del deleted myself"
+	} else {
+	    set u recursive
+	    lappend z "del calling recursive"
+	    update
+	    lappend z "del after update"
+	}
+    }
+    set z ""
+    set u toplevel
+    update
+    return $z
+} -cleanup {
+    chan close $f
+} -result [list {del calling recursive} {del deleted notcalled} \
+	       {del deleted myself} {del after update}]
+test chan-io-50.6 {testing handler deletion vs reentrant calls} -setup {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    chan close $f
+} -constraints {testchannelevent} -body {
+    set f [open $path(test1) r]
+    testchannelevent $f add readable [namespace code [list second $f]]
+    testchannelevent $f add readable [namespace code [list first $f]]
+    proc first {f} {
+	variable u
+	variable z
+	if {$u eq "toplevel"} {
+	    lappend z "first called"
+	    set u first
+	    update
+	    lappend z "first after update"
+	} else {
+	    lappend z "first called not toplevel"
+	}
+    }
+    proc second {f} {
+	variable u
+	variable z
+	if {$u eq "first"} {
+	    lappend z "second called, first time"
+	    set u second
+	    testchannelevent $f delete 0
+	} elseif {$u eq "second"} {
+	    lappend z "second called, second time"
+	    testchannelevent $f delete 0
+	} else {
+	    lappend z "second called, cannot happen!"
+	    testchannelevent $f removeall
+	}
+    }
+    set z ""
+    set u toplevel
+    update
+    return $z
+} -cleanup {
+    chan close $f
+} -result [list {first called} {first called not toplevel} \
+	       {second called, first time} {second called, second time} \
+	       {first after update}]
+
+test chan-io-51.1 {Test old socket deletion on Macintosh} -setup {
+    set x 0
+    set result ""
+    variable wait ""
+} -constraints {socket} -body {
+    proc accept {s a p} {
+	variable x
+	chan configure $s -blocking off
+	chan puts $s "sock[incr x]"
+	chan close $s
+	variable wait done
+    }
+    set ss [socket -server [namespace code accept] -myaddr 127.0.0.1 0]
+    set port [lindex [chan configure $ss -sockname] 2]
+    set cs [socket 127.0.0.1 $port]
+    vwait [namespace which -variable wait]
+    lappend result [chan gets $cs]
+    chan close $cs
+    set cs [socket 127.0.0.1 $port]
+    vwait [namespace which -variable wait]
+    lappend result [chan gets $cs]
+    chan close $cs
+    set cs [socket 127.0.0.1 $port]
+    vwait [namespace which -variable wait]
+    lappend result [chan gets $cs]
+    chan close $cs
+    set cs [socket 127.0.0.1 $port]
+    vwait [namespace which -variable wait]
+    lappend result [chan gets $cs]
+} -cleanup {
+    chan close $cs
+    chan close $ss
+} -result {sock1 sock2 sock3 sock4}
+
+test chan-io-52.1 {TclCopyChannel} -constraints {fcopy} -setup {
+    file delete $path(test1)
+} -body {
+    set f1 [open $thisScript]
+    set f2 [open $path(test1) w]
+    chan copy $f1 $f2 -command " # "
+    chan copy $f1 $f2
+} -returnCodes error -cleanup {
+    chan close $f1
+    chan close $f2
+} -match glob -result {channel "*" is busy}
+test chan-io-52.2 {TclCopyChannel} -constraints {fcopy} -setup {
+    file delete $path(test1)
+} -body {
+    set f1 [open $thisScript]
+    set f2 [open $path(test1) w]
+    set f3 [open $thisScript]
+    chan copy $f1 $f2 -command " # "
+    chan copy $f3 $f2
+} -returnCodes error -cleanup {
+    chan close $f1
+    chan close $f2
+    chan close $f3
+} -match glob -result {channel "*" is busy}
+test chan-io-52.3 {TclCopyChannel} -constraints {fcopy} -setup {
+    file delete $path(test1)
+} -body {
+    set f1 [open $thisScript]
+    set f2 [open $path(test1) w]
+    chan configure $f1 -translation lf -blocking 0
+    chan configure $f2 -translation cr -blocking 0
+    set s0 [chan copy $f1 $f2]
+    set result [list [chan configure $f1 -blocking] [chan configure $f2 -blocking]]
+    chan close $f1
+    chan close $f2
+    set s1 [file size $thisScript]
+    set s2 [file size $path(test1)]
+    if {($s1 == $s2) && ($s0 == $s1)} {
+        lappend result ok
+    }
+    return $result
+} -result {0 0 ok}
+test chan-io-52.4 {TclCopyChannel} -constraints {fcopy} -setup {
+    file delete $path(test1)
+} -body {
+    set f1 [open $thisScript]
+    set f2 [open $path(test1) w]
+    chan configure $f1 -translation lf -blocking 0
+    chan configure $f2 -translation cr -blocking 0
+    chan copy $f1 $f2 -size 40
+    set result [list [chan configure $f1 -blocking] [chan configure $f2 -blocking]]
+    chan close $f1
+    chan close $f2
+    lappend result [file size $path(test1)]
+} -result {0 0 40}
+test chan-io-52.5 {TclCopyChannel, all} -constraints {fcopy} -setup {
+    file delete $path(test1)
+} -body {
+    set f1 [open $thisScript]
+    set f2 [open $path(test1) w]
+    chan configure $f1 -translation lf -blocking 0
+    chan configure $f2 -translation lf -blocking 0
+    chan copy $f1 $f2 -size -1 ;# -1 means 'copy all', same as if no -size specified.
+    set result [list [chan configure $f1 -blocking] [chan configure $f2 -blocking]]
+    chan close $f1
+    chan close $f2
+    if {[file size $thisScript] == [file size $path(test1)]} {
+        lappend result ok
+    }
+    return $result
+} -result {0 0 ok}
+test chan-io-52.5a {TclCopyChannel, all, other negative value} -setup {
+    file delete $path(test1)
+} -constraints {fcopy} -body {
+    set f1 [open $thisScript]
+    set f2 [open $path(test1) w]
+    chan configure $f1 -translation lf -blocking 0
+    chan configure $f2 -translation lf -blocking 0
+    chan copy $f1 $f2 -size -2 ;# < 0 behaves like -1, copy all
+    set result [list [chan configure $f1 -blocking] [chan configure $f2 -blocking]]
+    chan close $f1
+    chan close $f2
+    if {[file size $thisScript] == [file size $path(test1)]} {
+        lappend result ok
+    }
+    return $result
+} -result {0 0 ok}
+test chan-io-52.5b {TclCopyChannel, all, wrap to negative value} -setup {
+    file delete $path(test1)
+} -constraints {fcopy} -body {
+    set f1 [open $thisScript]
+    set f2 [open $path(test1) w]
+    chan configure $f1 -translation lf -blocking 0
+    chan configure $f2 -translation lf -blocking 0
+    chan copy $f1 $f2 -size 3221176172 ;# Wrapped to < 0, behaves like -1, copy all
+    set result [list [chan configure $f1 -blocking] [chan configure $f2 -blocking]]
+    chan close $f1
+    chan close $f2
+    if {[file size $thisScript] ==  [file size $path(test1)]} {
+        lappend result ok
+    }
+    return $result
+} -result {0 0 ok}
+test chan-io-52.6 {TclCopyChannel} -setup {
+    file delete $path(test1)
+} -constraints {fcopy} -body {
+    set f1 [open $thisScript]
+    set f2 [open $path(test1) w]
+    chan configure $f1 -translation lf -blocking 0
+    chan configure $f2 -translation lf -blocking 0
+    set s0 [chan copy $f1 $f2 -size [expr [file size $thisScript] + 5]]
+    set result [list [chan configure $f1 -blocking] [chan configure $f2 -blocking]]
+    chan close $f1
+    chan close $f2
+    set s1 [file size $thisScript]
+    set s2 [file size $path(test1)]
+    if {($s1 == $s2) && ($s0 == $s1)} {
+        lappend result ok
+    }
+    return $result
+} -result {0 0 ok}
+test chan-io-52.7 {TclCopyChannel} -constraints {fcopy} -setup {
+    file delete $path(test1)
+} -body {
+    set f1 [open $thisScript]
+    set f2 [open $path(test1) w]
+    chan configure $f1 -translation lf -blocking 0
+    chan configure $f2 -translation lf -blocking 0
+    chan copy $f1 $f2
+    set result [list [chan configure $f1 -blocking] [chan configure $f2 -blocking]]
+    if {[file size $thisScript] == [file size $path(test1)]} {
+        lappend result ok
+    }
+    return $result
+} -cleanup {
+    chan close $f1
+    chan close $f2
+} -result {0 0 ok}
+test chan-io-52.8 {TclCopyChannel} -setup {
+    file delete $path(test1)
+    file delete $path(pipe)
+} -constraints {stdio openpipe fcopy} -body {
+    set f1 [open $path(pipe) w]
+    chan configure $f1 -translation lf
+    chan puts $f1 "
+	chan puts ready
+	chan gets stdin
+	set f1 \[open [list $thisScript] r\]
+	chan configure \$f1 -translation lf
+	chan puts \[chan read \$f1 100\]
+	chan close \$f1
+    "
+    chan close $f1
+    set f1 [openpipe r+ $path(pipe)]
+    chan configure $f1 -translation lf
+    chan gets $f1
+    chan puts $f1 ready
+    chan flush $f1
+    set f2 [open $path(test1) w]
+    chan configure $f2 -translation lf
+    set s0 [chan copy $f1 $f2 -size 40]
+    catch {chan close $f1}
+    chan close $f2
+    list $s0 [file size $path(test1)]
+} -result {40 40}
+# Empty files, to register them with the test facility
+set path(kyrillic.txt)   [makeFile {} kyrillic.txt]
+set path(utf8-fcopy.txt) [makeFile {} utf8-fcopy.txt]
+set path(utf8-rp.txt)    [makeFile {} utf8-rp.txt]
+# Create kyrillic file, use lf translation to avoid os eol issues
+set out [open $path(kyrillic.txt) w]
+chan configure $out -encoding koi8-r -translation lf
+chan puts       $out "\u0410\u0410"
+chan close      $out
+test chan-io-52.9 {TclCopyChannel & encodings} {fcopy} {
+    # Copy kyrillic to UTF-8, using chan copy.
+    set in  [open $path(kyrillic.txt) r]
+    set out [open $path(utf8-fcopy.txt) w]
+    chan configure $in  -encoding koi8-r -translation lf
+    chan configure $out -encoding utf-8 -translation lf
+    chan copy $in $out
+    chan close $in
+    chan close $out
+    # Do the same again, but differently (read/chan puts).
+    set in  [open $path(kyrillic.txt) r]
+    set out [open $path(utf8-rp.txt) w]
+    chan configure $in  -encoding koi8-r -translation lf
+    chan configure $out -encoding utf-8 -translation lf
+    chan puts -nonewline $out [chan read $in]
+    chan close $in
+    chan close $out
+    list [file size $path(kyrillic.txt)] \
+	    [file size $path(utf8-fcopy.txt)] \
+	    [file size $path(utf8-rp.txt)]
+} {3 5 5}
+test chan-io-52.10 {TclCopyChannel & encodings} {fcopy} {
+    # encoding to binary (=> implies that the internal utf-8 is written)
+    set in  [open $path(kyrillic.txt) r]
+    set out [open $path(utf8-fcopy.txt) w]
+    chan configure $in  -encoding koi8-r -translation lf
+    # -translation binary is also -encoding binary
+    chan configure $out -translation binary
+    chan copy $in $out
+    chan close $in
+    chan close $out
+    file size $path(utf8-fcopy.txt)
+} 5
+test chan-io-52.11 {TclCopyChannel & encodings} -setup {
+    set f [open $path(utf8-fcopy.txt) w]
+    fconfigure $f -encoding utf-8
+    puts $f "\u0410\u0410"
+    close $f
+} -constraints {fcopy} -body {
+    # binary to encoding => the input has to be in utf-8 to make sense to the
+    # encoder
+    set in  [open $path(utf8-fcopy.txt) r]
+    set out [open $path(kyrillic.txt) w]
+    # -translation binary is also -encoding binary
+    chan configure $in  -translation binary
+    chan configure $out -encoding koi8-r -translation lf
+    chan copy $in $out
+    chan close $in
+    chan close $out
+    file size $path(kyrillic.txt)
+} -result 3
+
+test chan-io-53.1 {CopyData} -setup {
+    file delete $path(test1)
+} -constraints {fcopy} -body {
+    set f1 [open $thisScript]
+    set f2 [open $path(test1) w]
+    chan configure $f1 -translation lf -blocking 0
+    chan configure $f2 -translation cr -blocking 0
+    chan copy $f1 $f2 -size 0
+    set result [list [chan configure $f1 -blocking] [chan configure $f2 -blocking]]
+    chan close $f1
+    chan close $f2
+    lappend result [file size $path(test1)]
+} -result {0 0 0}
+test chan-io-53.2 {CopyData} -setup {
+    file delete $path(test1)
+} -constraints {fcopy} -body {
+    set f1 [open $thisScript]
+    set f2 [open $path(test1) w]
+    chan configure $f1 -translation lf -blocking 0
+    chan configure $f2 -translation cr -blocking 0
+    chan copy $f1 $f2 -command [namespace code {set s0}]
+    set result [list [chan configure $f1 -blocking] [chan configure $f2 -blocking]]
+    variable s0
+    vwait [namespace which -variable s0]
+    chan close $f1
+    chan close $f2
+    set s1 [file size $thisScript]
+    set s2 [file size $path(test1)]
+    if {($s1 == $s2) && ($s0 == $s1)} {
+        lappend result ok
+    }
+    return $result
+} -result {0 0 ok}
+test chan-io-53.3 {CopyData: background read underflow} -setup {
+    file delete $path(test1)
+    file delete $path(pipe)
+} -constraints {stdio unix openpipe fcopy} -body {
+    set f1 [open $path(pipe) w]
+    chan puts -nonewline $f1 {
+	chan puts ready
+	chan flush stdout			;# Don't assume line buffered!
+	chan copy stdin stdout -command { set x }
+	vwait x
+	set f [}
+    chan puts $f1 [list open $path(test1) w]]
+    chan puts $f1 {
+	chan configure $f -translation lf
+	chan puts $f "done"
+	chan close $f
+    }
+    chan close $f1
+    set f1 [openpipe r+ $path(pipe)]
+    set result [chan gets $f1]
+    chan puts $f1 line1
+    chan flush $f1
+    lappend result [chan gets $f1]
+    chan puts $f1 line2
+    chan flush $f1
+    lappend result [chan gets $f1]
+    chan close $f1
+    after 500
+    set f [open $path(test1)]
+    lappend result [chan read $f]
+} -cleanup {
+    chan close $f
+} -result "ready line1 line2 {done\n}"
+test chan-io-53.4 {CopyData: background write overflow} -setup {
+    set big bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\n
+    variable x
+    for {set x 0} {$x < 12} {incr x} {
+	append big $big
+    }
+    file delete $path(test1)
+    file delete $path(pipe)
+} -constraints {stdio unix openpipe fileevent fcopy} -body {
+    set f1 [open $path(pipe) w]
+    chan puts $f1 {
+	chan puts ready
+	chan copy stdin stdout -command { set x }
+	vwait x
+	set f [open $path(test1) w]
+	chan configure $f -translation lf
+	chan puts $f "done"
+	chan close $f
+    }
+    chan close $f1
+    set f1 [openpipe r+ $path(pipe)]
+    set result [chan gets $f1]
+    chan configure $f1 -blocking 0
+    chan puts $f1 $big
+    chan flush $f1
+    after 500
+    set result ""
+    chan event $f1 read [namespace code {
+	append result [chan read $f1 1024]
+	if {[string length $result] >= [string length $big]} {
+	    set x done
+	}
+    }]
+    vwait [namespace which -variable x]
+    return $x
+} -cleanup {
+    set big {}
+    chan close $f1
+} -result done
+set result {}
+proc FcopyTestAccept {sock args} {
+    after 1000 "chan close $sock"
+}
+proc FcopyTestDone {bytes {error {}}} {
+    variable fcopyTestDone
+    if {[string length $error]} {
+	set fcopyTestDone 1
+    } else {
+	set fcopyTestDone 0
+    }
+}
+test chan-io-53.5 {CopyData: error during chan copy} {socket fcopy} {
+    variable fcopyTestDone
+    set listen [socket -server [namespace code FcopyTestAccept] -myaddr 127.0.0.1 0]
+    set in [open $thisScript]	;# 126 K
+    set out [socket 127.0.0.1 [lindex [chan configure $listen -sockname] 2]]
+    catch {unset fcopyTestDone}
+    chan close $listen	;# This means the socket open never really succeeds
+    chan copy $in $out -command [namespace code FcopyTestDone]
+    variable fcopyTestDone
+    if ![info exists fcopyTestDone] {
+	vwait [namespace which -variable fcopyTestDone]		;# The error occurs here in the b.g.
+    }
+    chan close $in
+    chan close $out
+    set fcopyTestDone	;# 1 for error condition
+} 1
+test chan-io-53.6 {CopyData: error during chan copy} -setup {
+    variable fcopyTestDone
+    file delete $path(pipe)
+    file delete $path(test1)
+    catch {unset fcopyTestDone}
+} -constraints {stdio openpipe fcopy} -body {
+    set f1 [open $path(pipe) w]
+    chan puts $f1 "exit 1"
+    chan close $f1
+    set in [openpipe r+ $path(pipe)]
+    set out [open $path(test1) w]
+    chan copy $in $out -command [namespace code FcopyTestDone]
+    variable fcopyTestDone
+    if ![info exists fcopyTestDone] {
+	vwait [namespace which -variable fcopyTestDone]
+    }
+    return $fcopyTestDone	;# 0 for plain end of file
+} -cleanup {
+    catch {chan close $in}
+    chan close $out
+} -result 0
+proc doFcopy {in out {bytes 0} {error {}}} {
+    variable fcopyTestDone
+    variable fcopyTestCount
+    incr fcopyTestCount $bytes
+    if {[string length $error]} {
+	set fcopyTestDone 1
+    } elseif {[chan eof $in]} {
+	set fcopyTestDone 0
+    } else {
+        # Delay next chan copy to wait for size>0 input bytes
+        after 100 [list chan copy $in $out -size 1000 \
+		-command [namespace code [list doFcopy $in $out]]]
+    }
+}
+test chan-io-53.7 {CopyData: Flooding chan copy from pipe} -setup {
+    variable fcopyTestDone
+    file delete $path(pipe)
+    catch {unset fcopyTestDone}
+} -constraints {stdio openpipe fcopy} -body {
+    set fcopyTestCount 0
+    set f1 [open $path(pipe) w]
+    chan puts $f1 {
+	# Write  10 bytes / 10 msec
+	proc Write {count} {
+	    chan puts -nonewline "1234567890"
+	    if {[incr count -1]} {
+	        after 10 [list Write $count]
+	    } else {
+	        set ::ready 1
+	    }
+	}
+	chan configure stdout -buffering none
+	Write 345 ;# 3450 bytes ~3.45 sec
+	vwait ready
+	exit 0
+    }
+    chan close $f1
+    set in [openpipe r+ $path(pipe) &]
+    set out [open $path(test1) w]
+    doFcopy $in $out
+    variable fcopyTestDone
+    if {![info exists fcopyTestDone]} {
+	vwait [namespace which -variable fcopyTestDone]
+    }
+    # -1=error 0=script error N=number of bytes
+    expr ($fcopyTestDone == 0) ? $fcopyTestCount : -1
+} -cleanup {
+    catch {chan close $in}
+    chan close $out
+} -result {3450}
+test chan-io-53.8 {CopyData: async callback and error handling, Bug 1932639} -setup {
+    # copy progress callback. errors out intentionally
+    proc cmd args {
+	lappend ::RES "CMD $args"
+	error !STOP
+    }
+    # capture callback error here
+    proc ::bgerror args {
+	lappend ::RES "bgerror/OK $args"
+	set ::forever has-been-reached
+	return
+    }
+    # Files we use for our channels
+    set foo [makeFile ashgdfashdgfasdhgfasdhgf foo]
+    set bar [makeFile {} bar]
+    # Channels to copy between
+    set f [open $foo r] ; fconfigure $f -translation binary
+    set g [open $bar w] ; fconfigure $g -translation binary -buffering none
+} -constraints {stdio openpipe fcopy} -body {
+    # Record input size, so that result is always defined
+    lappend ::RES [file size $bar]
+    # Run the copy. Should not invoke -command now.
+    chan copy $f $g -size 2 -command [namespace code cmd]
+    # Check that -command was not called synchronously
+    set sbs [file size $bar]
+    lappend ::RES [expr {($sbs > 0) ? "sync/FAIL" : "sync/OK"}] $sbs
+    # Now let the async part happen. Should capture the error in cmd via
+    # bgerror. If not break the event loop via timer.
+    set token [after 1000 {
+	lappend ::RES {bgerror/FAIL timeout}
+	set ::forever has-been-reached
+    }]
+    vwait ::forever
+    catch {after cancel $token}
+    # Report
+    return $::RES
+} -cleanup {
+    chan close $f
+    chan close $g
+    catch {unset ::RES}
+    catch {unset ::forever}
+    rename ::bgerror {}
+    removeFile foo
+    removeFile bar
+} -result {0 sync/OK 0 {CMD 2} {bgerror/OK !STOP}}
+test chan-io-53.8a {CopyData: async callback and error handling, Bug 1932639, at eof} -setup {
+    # copy progress callback.
+    proc cmd args {
+	lappend ::RES "CMD $args"
+	set ::forever has-been-reached
+	return
+    }
+    # Files we use for our channels
+    set foo [makeFile ashgdfashdgfasdhgfasdhgf foo]
+    set bar [makeFile {} bar]
+    # Channels to copy between
+    set f [open $foo r] ; chan configure $f -translation binary
+    set g [open $bar w] ; chan configure $g -translation binary -buffering none
+} -constraints {stdio openpipe fcopy} -body {
+    # Initialize and force eof on the input.
+    chan seek $f 0 end ; chan read $f 1
+    set ::RES [chan eof $f]
+    # Run the copy. Should not invoke -command now.
+    chan copy $f $g -size 2 -command [namespace code cmd]
+    # Check that -command was not called synchronously
+    lappend ::RES [expr {([llength $::RES] > 1) ? "sync/FAIL" : "sync/OK"}]
+    # Now let the async part happen. Should capture the eof in cmd
+    # If not break the event loop via timer.
+    set token [after 1000 {
+	lappend ::RES {cmd/FAIL timeout}
+	set ::forever has-been-reached
+    }]
+    vwait ::forever
+    catch {after cancel $token}
+    # Report
+    return $::RES
+} -cleanup {
+    chan close $f
+    chan close $g
+    catch {unset ::RES}
+    catch {unset ::forever}
+    removeFile foo
+    removeFile bar
+} -result {1 sync/OK {CMD 0}}
+test chan-io-53.9 {CopyData: -size and event interaction, Bug 780533} -setup {
+    set out [makeFile {} out]
+    set err [makeFile {} err]
+    set pipe [open "|[list [info nameofexecutable] 2> $err]" r+]
+    chan configure $pipe -translation binary -buffering line
+    chan puts $pipe {
+	chan configure stdout -translation binary -buffering line
+	chan puts stderr Waiting...
+	after 1000
+	foreach x {a b c} {
+	    chan puts stderr Looping...
+	    chan puts $x
+	    after 500
+	}
+	proc bye args {
+	    if {[chan gets stdin line]<0} {
+		chan puts stderr "CHILD: EOF detected, exiting"
+		exit
+	    } else {
+		chan puts stderr "CHILD: ignoring line: $line"
+	    }
+	}
+	chan puts stderr Now-sleeping-forever
+	chan event stdin readable bye
+	vwait forever
+    }
+    proc ::done args {
+	set ::forever OK
+	return
+    }
+    set ::forever {}
+    set out [open $out w]
+} -constraints {stdio openpipe fcopy} -body {
+    chan copy $pipe $out -size 6 -command ::done
+    set token [after 5000 {
+	set ::forever {fcopy hangs}
+    }]
+    vwait ::forever
+    catch {after cancel $token}
+    set ::forever
+} -cleanup {
+    chan close $pipe
+    rename ::done {}
+    if {[testConstraint win]} {
+	after 1000;		# Allow Windows time to figure out that the
+                                # process is gone
+    }
+    catch {close $out}
+    catch {removeFile out}
+    catch {removeFile err}
+    catch {unset ::forever}
+} -result OK
+test chan-io-53.10 {Bug 1350564, multi-directional fcopy} -setup {
+    set err [makeFile {} err]
+    set pipe [open "|[list [info nameofexecutable] 2> $err]" r+]
+    chan configure $pipe -translation binary -buffering line
+    chan puts $pipe {
+	chan configure stderr -buffering line
+	# Kill server when pipe closed by invoker.
+	proc bye args {
+	    if {![chan eof stdin]} { chan gets stdin ; return }
+	    chan puts stderr BYE
+	    exit
+	}
+	# Server code. Bi-directional copy between 2 sockets.
+	proc geof {sok} {
+	    chan puts stderr DONE/$sok
+	    chan close $sok
+	}
+	proc new {sok args} {
+	    chan puts stderr NEW/$sok
+	    global l srv
+	    chan configure $sok -translation binary -buffering none
+	    lappend l $sok
+	    if {[llength $l] == 2} {
+		chan close $srv
+		foreach {a b} $l break
+		chan copy $a $b -command [list geof $a]
+		chan copy $b $a -command [list geof $b]
+		chan puts stderr 2COPY
+	    }
+	    chan puts stderr ...
+	}
+	chan puts stderr SRV
+	set l {}
+	set srv [socket -server new 9999]
+	chan puts stderr WAITING
+	chan event stdin readable bye
+	chan puts OK
+	vwait forever
+    }
+    # wait for OK from server.
+    chan gets $pipe
+    # Now the two clients.
+    proc done {sock} {
+	if {[chan eof $sock]} { chan close $sock ; return }
+	lappend ::forever [chan gets $sock]
+	return
+    }
+    set a [socket 127.0.0.1 9999]
+    set b [socket 127.0.0.1 9999]
+    chan configure $a -translation binary -buffering none
+    chan configure $b -translation binary -buffering none
+    chan event  $a readable [namespace code "done $a"]
+    chan event  $b readable [namespace code "done $b"]
+} -constraints {stdio openpipe fcopy} -body {
+    # Now pass data through the server in both directions.
+    set ::forever {}
+    chan puts $a AB
+    vwait ::forever
+    chan puts $b BA
+    vwait ::forever
+    set ::forever
+} -cleanup {
+    catch {chan close $a}
+    catch {chan close $b}
+    chan close $pipe
+    if {[testConstraint win]} {
+	after 1000		;# Give Windows time to kill the process
+    }
+    removeFile err
+    catch {unset ::forever}
+} -result {AB BA}
+
+test chan-io-54.1 {Recursive channel events} {socket fileevent} {
+    # This test checks to see if file events are delivered during recursive
+    # event loops when there is buffered data on the channel.
+    proc accept {s a p} {
+	variable as
+	chan configure $s -translation lf
+	chan puts $s "line 1\nline2\nline3"
+	chan flush $s
+	set as $s
+    }
+    proc readit {s next} {
+	variable x
+	variable result
+	lappend result $next
+	if {$next == 1} {
+	    chan event $s readable [namespace code [list readit $s 2]]
+	    vwait [namespace which -variable x]
+	}
+	incr x
+    }
+    set ss [socket -server [namespace code accept] -myaddr 127.0.0.1 0]
+    # We need to delay on some systems until the creation of the server socket
+    # completes.
+    set done 0
+    for {set i 0} {$i < 10} {incr i} {
+	if {![catch {
+	    set cs [socket 127.0.0.1 [lindex [chan configure $ss -sockname] 2]]
+	}]} then {
+	    set done 1
+	    break
+	}
+	after 100
+    }
+    if {$done == 0} {
+	chan close $ss
+	error "failed to connect to server"
+    }
+    variable result {}
+    variable x 0
+    variable as
+    vwait [namespace which -variable as]
+    chan configure $cs -translation lf
+    lappend result [chan gets $cs]
+    chan configure $cs -blocking off
+    chan event $cs readable [namespace code [list readit $cs 1]]
+    set a [after 2000 [namespace code { set x failure }]]
+    vwait [namespace which -variable x]
+    after cancel $a
+    chan close $as
+    chan close $ss
+    chan close $cs
+    list $result $x
+} {{{line 1} 1 2} 2}
+test chan-io-54.2 {Testing for busy-wait in recursive channel events} -setup {
+    set accept {}
+    set after {}
+    variable done 0
+} -constraints {socket fileevent} -body {
+    variable s [socket -server [namespace code accept] -myaddr 127.0.0.1 0]
+    proc accept {s a p} {
+	variable counter 0
+	variable accept $s
+	chan configure $s -blocking off -buffering line -translation lf
+	chan event $s readable [namespace code "doit $s"]
+    }
+    proc doit {s} {
+	variable counter
+	variable after
+	incr counter
+	if {[chan gets $s] eq ""} {
+	    chan event $s readable [namespace code "doit1 $s"]
+	    set after [after 1000 [namespace code {
+		chan puts $writer hello
+		chan flush $writer
+		set done 1
+	    }]]
+	}
+    }
+    proc doit1 {s} {
+	variable counter
+	variable accept
+	incr counter
+	chan gets $s
+	chan close $s
+	set accept {}
+    }
+    proc producer {} {
+	variable s
+	variable writer
+	set writer [socket 127.0.0.1 [lindex [chan configure $s -sockname] 2]]
+	chan configure $writer -buffering line
+	chan puts -nonewline $writer hello
+	chan flush $writer
+    }
+    producer
+    vwait [namespace which -variable done]
+    chan close $writer
+    chan close $s
+    after cancel $after
+    return $counter
+} -cleanup {
+    if {$accept ne {}} {chan close $accept}
+} -result 1
+
+set path(fooBar) [makeFile {} fooBar]
+
+test chan-io-55.1 {ChannelEventScriptInvoker: deletion} -constraints {
+    fileevent
+} -setup {
+    variable x
+    proc eventScript {fd} {
+	variable x
+	chan close $fd
+	error "planned error"
+	set x whoops
+    }
+    proc myHandler args {
+	variable x got_error
+    }
+    set handler [interp bgerror {}]
+    interp bgerror {} [namespace which myHandler]
+} -body {
+    set f [open $path(fooBar) w]
+    chan event $f writable [namespace code [list eventScript $f]]
+    variable x not_done
+    vwait [namespace which -variable x]
+    return $x
+} -cleanup {
+    interp bgerror {} $handler
+} -result {got_error}
+
+test chan-io-56.1 {ChannelTimerProc} {testchannelevent} {
+    set f [open $path(fooBar) w]
+    chan puts $f "this is a test"
+    chan close $f
+    set f [open $path(fooBar) r]
+    testchannelevent $f add readable [namespace code {
+	chan read $f 1
+	incr x
+    }]
+    variable x 0
+    vwait [namespace which -variable x]
+    vwait [namespace which -variable x]
+    set result $x
+    testchannelevent $f set 0 none
+    after idle [namespace code {set y done}]
+    variable y
+    vwait [namespace which -variable y]
+    chan close $f
+    lappend result $y
+} {2 done}
+
+test chan-io-57.1 {buffered data and file events, gets} -setup {
+    variable s2
+} -constraints {fileevent} -body {
+    proc accept {sock args} {
+	variable s2
+	set s2 $sock
+    }
+    set server [socket -server [namespace code accept] -myaddr 127.0.0.1 0]
+    set s [socket 127.0.0.1 [lindex [chan configure $server -sockname] 2]]
+    vwait [namespace which -variable s2]
+    update
+    chan event $s2 readable [namespace code {lappend result readable}]
+    chan puts $s "12\n34567890"
+    chan flush $s
+    variable result [chan gets $s2]
+    after 1000 [namespace code {lappend result timer}]
+    vwait [namespace which -variable result]
+    lappend result [chan gets $s2]
+    vwait [namespace which -variable result]
+    return $result
+} -cleanup {
+    chan close $s
+    chan close $s2
+    chan close $server
+} -result {12 readable 34567890 timer}
+test chan-io-57.2 {buffered data and file events, read} -setup {
+    variable s2
+} -constraints {fileevent} -body {
+    proc accept {sock args} {
+	variable s2
+	set s2 $sock
+    }
+    set server [socket -server [namespace code accept] -myaddr 127.0.0.1 0]
+    set s [socket 127.0.0.1 [lindex [chan configure $server -sockname] 2]]
+    vwait [namespace which -variable s2]
+    update
+    chan event $s2 readable [namespace code {lappend result readable}]
+    chan puts -nonewline $s "1234567890"
+    chan flush $s
+    variable result [chan read $s2 1]
+    after 1000 [namespace code {lappend result timer}]
+    vwait [namespace which -variable result]
+    lappend result [chan read $s2 9]
+    vwait [namespace which -variable result]
+    return $result
+} -cleanup {
+    chan close $s
+    chan close $s2
+    chan close $server
+} -result {1 readable 234567890 timer}
+
+test chan-io-58.1 {Tcl_NotifyChannel and error when closing} {stdio unixOrPc openpipe fileevent} {
+    set out [open $path(script) w]
+    chan puts $out {
+	chan puts "normal message from pipe"
+	chan puts stderr "error message from pipe"
+	exit 1
+    }
+    proc readit {pipe} {
+	variable x
+	variable result
+	if {[chan eof $pipe]} {
+	    set x [catch {chan close $pipe} line]
+	    lappend result catch $line
+	} else {
+	    chan gets $pipe line
+	    lappend result chan gets $line
+	}
+    }
+    chan close $out
+    set pipe [openpipe r $path(script)]
+    chan event $pipe readable [namespace code [list readit $pipe]]
+    variable x ""
+    set result ""
+    vwait [namespace which -variable x]
+    list $x $result
+} {1 {chan gets {normal message from pipe} chan gets {} catch {error message from pipe}}}
+
+test chan-io-59.1 {Thread reference of channels} {testmainthread testchannel} {
+    # TIP #10
+    # More complicated tests (like that the reference changes as a channel is
+    # moved from thread to thread) can be done only in the extension which
+    # fully implements the moving of channels between threads, i.e. 'Threads'.
+    set f [open $path(longfile) r]
+    set result [testchannel mthread $f]
+    chan close $f
+    string equal $result [testmainthread]
+} {1}
+
+test chan-io-60.1 {writing illegal utf sequences} {openpipe fileevent testbytestring} {
+    # This test will hang in older revisions of the core.
+    set out [open $path(script) w]
+    chan puts $out {
+	chan puts [testbytestring \xe2]
+	exit 1
+    }
+    proc readit {pipe} {
+	variable x
+	variable result
+	if {[chan eof $pipe]} {
+	    set x [catch {chan close $pipe} line]
+	    lappend result catch $line
+	} else {
+	    chan gets $pipe line
+	    lappend result gets $line
+	}
+    }
+    chan close $out
+    set pipe [openpipe r $path(script)]
+    chan event $pipe readable [namespace code [list readit $pipe]]
+    variable x ""
+    set result ""
+    vwait [namespace which -variable x]
+    # cut of the remainder of the error stack, especially the filename
+    set result [lreplace $result 3 3 [lindex [split [lindex $result 3] \n] 0]]
+    list $x $result
+} {1 {gets {} catch {error writing "stdout": invalid argument}}}
+
+test chan-io-61.1 {Reset eof state after changing the eof char} -setup {
+    set datafile [makeFile {} eofchar]
+    set f [open $datafile w]
+    chan configure $f -translation binary
+    chan puts -nonewline $f [string repeat "Ho hum\n" 11]
+    chan puts $f =
+    set line [string repeat "Ge gla " 4]
+    chan puts -nonewline $f [string repeat [string trimright $line]\n 834]
+    chan close $f
+} -body {
+    set f [open $datafile r]
+    chan configure $f -eofchar =
+    set res {}
+    lappend res [chan read $f; chan tell $f]
+    chan configure $f -eofchar {}
+    lappend res [chan read $f 1]
+    lappend res [chan read $f; chan tell $f]
+    # Any seek zaps the internals into a good state.
+    #chan seek $f 0 start
+    #chan seek $f 0 current
+    #lappend res [chan read $f; chan tell $f]
+} -cleanup {
+    chan close $f
+    removeFile eofchar
+} -result {77 = 23431}
+
+# Test the cutting and splicing of channels, this is incidentially the
+# attach/detach facility of package Thread, but __without any safeguards__. It
+# can also be used to emulate transfer of channels between threads, and is
+# used for that here.
+
+test chan-io-70.0 {Cutting & Splicing channels} -setup {
+    set f [makeFile {... dummy ...} cutsplice]
+    set res {}
+} -constraints {testchannel} -body {
+    set c [open $f r]
+    lappend res [catch {chan seek $c 0 start}]
+    testchannel cut $c
+    lappend res [catch {chan seek $c 0 start}]
+    testchannel splice $c
+    lappend res [catch {chan seek $c 0 start}]
+} -cleanup {
+    chan close $c
+    removeFile cutsplice
+} -result {0 1 0}
+
+test chan-io-70.1 {Transfer channel} -setup {
+    set f [makeFile {... dummy ...} cutsplice]
+    set res {}
+} -constraints {testchannel thread} -body {
+    set c [open $f r]
+    lappend res [catch {chan seek $c 0 start}]
+    testchannel cut $c
+    lappend res [catch {chan seek $c 0 start}]
+    set tid [thread::create -preserved]
+    thread::send $tid [list set c $c]
+    thread::send $tid {load {} Tcltest}
+    lappend res [thread::send $tid {
+	testchannel splice $c
+	set res [catch {chan seek $c 0 start}]
+	chan close $c
+	set res
+    }]
+} -cleanup {
+    thread::release $tid
+    removeFile cutsplice
+} -result {0 1 0}
+
+# ### ### ### ######### ######### #########
+
+foreach {n msg expected} {
+     0 {}                                 {}
+     1 {{message only}}                   {{message only}}
+     2 {-options x}                       {-options x}
+     3 {-options {x y} {the message}}     {-options {x y} {the message}}
+
+     4 {-code 1     -level 0 -f ba snarf} {-code 1     -level 0 -f ba snarf}
+     5 {-code 0     -level 0 -f ba snarf} {-code 1     -level 0 -f ba snarf}
+     6 {-code 1     -level 5 -f ba snarf} {-code 1     -level 0 -f ba snarf}
+     7 {-code 0     -level 5 -f ba snarf} {-code 1     -level 0 -f ba snarf}
+     8 {-code error -level 0 -f ba snarf} {-code error -level 0 -f ba snarf}
+     9 {-code ok    -level 0 -f ba snarf} {-code 1     -level 0 -f ba snarf}
+    10 {-code error -level 5 -f ba snarf} {-code error -level 0 -f ba snarf}
+    11 {-code ok    -level 5 -f ba snarf} {-code 1     -level 0 -f ba snarf}
+    12 {-code boss  -level 0 -f ba snarf} {-code 1     -level 0 -f ba snarf}
+    13 {-code boss  -level 5 -f ba snarf} {-code 1     -level 0 -f ba snarf}
+    14 {-code 1     -level 0 -f ba}       {-code 1     -level 0 -f ba}
+    15 {-code 0     -level 0 -f ba}       {-code 1     -level 0 -f ba}
+    16 {-code 1     -level 5 -f ba}       {-code 1     -level 0 -f ba}
+    17 {-code 0     -level 5 -f ba}       {-code 1     -level 0 -f ba}
+    18 {-code error -level 0 -f ba}       {-code error -level 0 -f ba}
+    19 {-code ok    -level 0 -f ba}       {-code 1     -level 0 -f ba}
+    20 {-code error -level 5 -f ba}       {-code error -level 0 -f ba}
+    21 {-code ok    -level 5 -f ba}       {-code 1     -level 0 -f ba}
+    22 {-code boss  -level 0 -f ba}       {-code 1     -level 0 -f ba}
+    23 {-code boss  -level 5 -f ba}       {-code 1     -level 0 -f ba}
+    24 {-code 1     -level X -f ba snarf} {-code 1     -level 0 -f ba snarf}
+    25 {-code 0     -level X -f ba snarf} {-code 1     -level 0 -f ba snarf}
+    26 {-code error -level X -f ba snarf} {-code error -level 0 -f ba snarf}
+    27 {-code ok    -level X -f ba snarf} {-code 1     -level 0 -f ba snarf}
+    28 {-code boss  -level X -f ba snarf} {-code 1     -level 0 -f ba snarf}
+    29 {-code 1     -level X -f ba}       {-code 1     -level 0 -f ba}
+    30 {-code 0     -level X -f ba}       {-code 1     -level 0 -f ba}
+    31 {-code error -level X -f ba}       {-code error -level 0 -f ba}
+    32 {-code ok    -level X -f ba}       {-code 1     -level 0 -f ba}
+    33 {-code boss  -level X -f ba}       {-code 1     -level 0 -f ba}
+
+    34 {-code 1 -code 1     -level 0 -f ba snarf} {-code 1 -code 1     -level 0 -f ba snarf}
+    35 {-code 1 -code 0     -level 0 -f ba snarf} {-code 1             -level 0 -f ba snarf}
+    36 {-code 1 -code 1     -level 5 -f ba snarf} {-code 1 -code 1     -level 0 -f ba snarf}
+    37 {-code 1 -code 0     -level 5 -f ba snarf} {-code 1             -level 0 -f ba snarf}
+    38 {-code 1 -code error -level 0 -f ba snarf} {-code 1 -code error -level 0 -f ba snarf}
+    39 {-code 1 -code ok    -level 0 -f ba snarf} {-code 1             -level 0 -f ba snarf}
+    40 {-code 1 -code error -level 5 -f ba snarf} {-code 1 -code error -level 0 -f ba snarf}
+    41 {-code 1 -code ok    -level 5 -f ba snarf} {-code 1             -level 0 -f ba snarf}
+    42 {-code 1 -code boss  -level 0 -f ba snarf} {-code 1             -level 0 -f ba snarf}
+    43 {-code 1 -code boss  -level 5 -f ba snarf} {-code 1             -level 0 -f ba snarf}
+    44 {-code 1 -code 1     -level 0 -f ba}       {-code 1 -code 1     -level 0 -f ba}
+    45 {-code 1 -code 0     -level 0 -f ba}       {-code 1             -level 0 -f ba}
+    46 {-code 1 -code 1     -level 5 -f ba}       {-code 1 -code 1     -level 0 -f ba}
+    47 {-code 1 -code 0     -level 5 -f ba}       {-code 1             -level 0 -f ba}
+    48 {-code 1 -code error -level 0 -f ba}       {-code 1 -code error -level 0 -f ba}
+    49 {-code 1 -code ok    -level 0 -f ba}       {-code 1             -level 0 -f ba}
+    50 {-code 1 -code error -level 5 -f ba}       {-code 1 -code error -level 0 -f ba}
+    51 {-code 1 -code ok    -level 5 -f ba}       {-code 1             -level 0 -f ba}
+    52 {-code 1 -code boss  -level 0 -f ba}       {-code 1             -level 0 -f ba}
+    53 {-code 1 -code boss  -level 5 -f ba}       {-code 1             -level 0 -f ba}
+    54 {-code 1 -code 1     -level X -f ba snarf} {-code 1 -code 1     -level 0 -f ba snarf}
+    55 {-code 1 -code 0     -level X -f ba snarf} {-code 1             -level 0 -f ba snarf}
+    56 {-code 1 -code error -level X -f ba snarf} {-code 1 -code error -level 0 -f ba snarf}
+    57 {-code 1 -code ok    -level X -f ba snarf} {-code 1             -level 0 -f ba snarf}
+    58 {-code 1 -code boss  -level X -f ba snarf} {-code 1             -level 0 -f ba snarf}
+    59 {-code 1 -code 1     -level X -f ba}       {-code 1 -code 1     -level 0 -f ba}
+    60 {-code 1 -code 0     -level X -f ba}       {-code 1             -level 0 -f ba}
+    61 {-code 1 -code error -level X -f ba}       {-code 1 -code error -level 0 -f ba}
+    62 {-code 1 -code ok    -level X -f ba}       {-code 1             -level 0 -f ba}
+    63 {-code 1 -code boss  -level X -f ba}       {-code 1             -level 0 -f ba}
+
+    64 {-code 0 -code 1     -level 0 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+    65 {-code 0 -code 0     -level 0 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+    66 {-code 0 -code 1     -level 5 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+    67 {-code 0 -code 0     -level 5 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+    68 {-code 0 -code error -level 0 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+    69 {-code 0 -code ok    -level 0 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+    70 {-code 0 -code error -level 5 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+    71 {-code 0 -code ok    -level 5 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+    72 {-code 0 -code boss  -level 0 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+    73 {-code 0 -code boss  -level 5 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+    74 {-code 0 -code 1     -level 0 -f ba}       {-code 1 -level 0 -f ba}
+    75 {-code 0 -code 0     -level 0 -f ba}       {-code 1 -level 0 -f ba}
+    76 {-code 0 -code 1     -level 5 -f ba}       {-code 1 -level 0 -f ba}
+    77 {-code 0 -code 0     -level 5 -f ba}       {-code 1 -level 0 -f ba}
+    78 {-code 0 -code error -level 0 -f ba}       {-code 1 -level 0 -f ba}
+    79 {-code 0 -code ok    -level 0 -f ba}       {-code 1 -level 0 -f ba}
+    80 {-code 0 -code error -level 5 -f ba}       {-code 1 -level 0 -f ba}
+    81 {-code 0 -code ok    -level 5 -f ba}       {-code 1 -level 0 -f ba}
+    82 {-code 0 -code boss  -level 0 -f ba}       {-code 1 -level 0 -f ba}
+    83 {-code 0 -code boss  -level 5 -f ba}       {-code 1 -level 0 -f ba}
+    84 {-code 0 -code 1     -level X -f ba snarf} {-code 1 -level 0 -f ba snarf}
+    85 {-code 0 -code 0     -level X -f ba snarf} {-code 1 -level 0 -f ba snarf}
+    86 {-code 0 -code error -level X -f ba snarf} {-code 1 -level 0 -f ba snarf}
+    87 {-code 0 -code ok    -level X -f ba snarf} {-code 1 -level 0 -f ba snarf}
+    88 {-code 0 -code boss  -level X -f ba snarf} {-code 1 -level 0 -f ba snarf}
+    89 {-code 0 -code 1     -level X -f ba}       {-code 1 -level 0 -f ba}
+    90 {-code 0 -code 0     -level X -f ba}       {-code 1 -level 0 -f ba}
+    91 {-code 0 -code error -level X -f ba}       {-code 1 -level 0 -f ba}
+    92 {-code 0 -code ok    -level X -f ba}       {-code 1 -level 0 -f ba}
+    93 {-code 0 -code boss  -level X -f ba}       {-code 1 -level 0 -f ba}
+
+    94 {-code 1     -code 1 -level 0 -f ba snarf} {-code 1 -code 1     -level 0 -f ba snarf}
+    95 {-code 0     -code 1 -level 0 -f ba snarf} {-code 1             -level 0 -f ba snarf}
+    96 {-code 1     -code 1 -level 5 -f ba snarf} {-code 1 -code 1     -level 0 -f ba snarf}
+    97 {-code 0     -code 1 -level 5 -f ba snarf} {-code 1             -level 0 -f ba snarf}
+    98 {-code error -code 1 -level 0 -f ba snarf} {-code error -code 1 -level 0 -f ba snarf}
+    99 {-code ok    -code 1 -level 0 -f ba snarf} {-code 1             -level 0 -f ba snarf}
+    a0 {-code error -code 1 -level 5 -f ba snarf} {-code error -code 1 -level 0 -f ba snarf}
+    a1 {-code ok    -code 1 -level 5 -f ba snarf} {-code 1             -level 0 -f ba snarf}
+    a2 {-code boss  -code 1 -level 0 -f ba snarf} {-code 1             -level 0 -f ba snarf}
+    a3 {-code boss  -code 1 -level 5 -f ba snarf} {-code 1             -level 0 -f ba snarf}
+    a4 {-code 1     -code 1 -level 0 -f ba}       {-code 1 -code 1     -level 0 -f ba}
+    a5 {-code 0     -code 1 -level 0 -f ba}       {-code 1             -level 0 -f ba}
+    a6 {-code 1     -code 1 -level 5 -f ba}       {-code 1 -code 1     -level 0 -f ba}
+    a7 {-code 0     -code 1 -level 5 -f ba}       {-code 1             -level 0 -f ba}
+    a8 {-code error -code 1 -level 0 -f ba}       {-code error -code 1 -level 0 -f ba}
+    a9 {-code ok    -code 1 -level 0 -f ba}       {-code 1             -level 0 -f ba}
+    b0 {-code error -code 1 -level 5 -f ba}       {-code error -code 1 -level 0 -f ba}
+    b1 {-code ok    -code 1 -level 5 -f ba}       {-code 1             -level 0 -f ba}
+    b2 {-code boss  -code 1 -level 0 -f ba}       {-code 1             -level 0 -f ba}
+    b3 {-code boss  -code 1 -level 5 -f ba}       {-code 1             -level 0 -f ba}
+    b4 {-code 1     -code 1 -level X -f ba snarf} {-code 1 -code 1     -level 0 -f ba snarf}
+    b5 {-code 0     -code 1 -level X -f ba snarf} {-code 1             -level 0 -f ba snarf}
+    b6 {-code error -code 1 -level X -f ba snarf} {-code error -code 1 -level 0 -f ba snarf}
+    b7 {-code ok    -code 1 -level X -f ba snarf} {-code 1             -level 0 -f ba snarf}
+    b8 {-code boss  -code 1 -level X -f ba snarf} {-code 1             -level 0 -f ba snarf}
+    b9 {-code 1     -code 1 -level X -f ba}       {-code 1 -code 1     -level 0 -f ba}
+    c0 {-code 0     -code 1 -level X -f ba}       {-code 1             -level 0 -f ba}
+    c1 {-code error -code 1 -level X -f ba}       {-code error -code 1 -level 0 -f ba}
+    c2 {-code ok    -code 1 -level X -f ba}       {-code 1             -level 0 -f ba}
+    c3 {-code boss  -code 1 -level X -f ba}       {-code 1             -level 0 -f ba}
+
+    c4 {-code 1     -code 0 -level 0 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+    c5 {-code 0     -code 0 -level 0 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+    c6 {-code 1     -code 0 -level 5 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+    c7 {-code 0     -code 0 -level 5 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+    c8 {-code error -code 0 -level 0 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+    c9 {-code ok    -code 0 -level 0 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+    d0 {-code error -code 0 -level 5 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+    d1 {-code ok    -code 0 -level 5 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+    d2 {-code boss  -code 0 -level 0 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+    d3 {-code boss  -code 0 -level 5 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+    d4 {-code 1     -code 0 -level 0 -f ba}       {-code 1 -level 0 -f ba}
+    d5 {-code 0     -code 0 -level 0 -f ba}       {-code 1 -level 0 -f ba}
+    d6 {-code 1     -code 0 -level 5 -f ba}       {-code 1 -level 0 -f ba}
+    d7 {-code 0     -code 0 -level 5 -f ba}       {-code 1 -level 0 -f ba}
+    d8 {-code error -code 0 -level 0 -f ba}       {-code 1 -level 0 -f ba}
+    d9 {-code ok    -code 0 -level 0 -f ba}       {-code 1 -level 0 -f ba}
+    e0 {-code error -code 0 -level 5 -f ba}       {-code 1 -level 0 -f ba}
+    e1 {-code ok    -code 0 -level 5 -f ba}       {-code 1 -level 0 -f ba}
+    e2 {-code boss  -code 0 -level 0 -f ba}       {-code 1 -level 0 -f ba}
+    e3 {-code boss  -code 0 -level 5 -f ba}       {-code 1 -level 0 -f ba}
+    e4 {-code 1     -code 0 -level X -f ba snarf} {-code 1 -level 0 -f ba snarf}
+    e5 {-code 0     -code 0 -level X -f ba snarf} {-code 1 -level 0 -f ba snarf}
+    e6 {-code error -code 0 -level X -f ba snarf} {-code 1 -level 0 -f ba snarf}
+    e7 {-code ok    -code 0 -level X -f ba snarf} {-code 1 -level 0 -f ba snarf}
+    e8 {-code boss  -code 0 -level X -f ba snarf} {-code 1 -level 0 -f ba snarf}
+    e9 {-code 1     -code 0 -level X -f ba}       {-code 1 -level 0 -f ba}
+    f0 {-code 0     -code 0 -level X -f ba}       {-code 1 -level 0 -f ba}
+    f1 {-code error -code 0 -level X -f ba}       {-code 1 -level 0 -f ba}
+    f2 {-code ok    -code 0 -level X -f ba}       {-code 1 -level 0 -f ba}
+    f3 {-code boss  -code 0 -level X -f ba}       {-code 1 -level 0 -f ba}
+} {
+    test chan-io-71.$n {Tcl_SetChannelError} -setup {
+	set f [makeFile {... dummy ...} cutsplice]
+    } -constraints {testchannel} -body {
+	set c [open $f r]
+	testchannel setchannelerror $c [lrange $msg 0 end]
+    } -cleanup {
+	chan close $c
+	removeFile cutsplice
+    } -result [lrange $expected 0 end]
+    test chan-io-72.$n {Tcl_SetChannelErrorInterp} -setup {
+	set f [makeFile {... dummy ...} cutsplice]
+    } -constraints {testchannel} -body {
+	set c [open $f r]
+	testchannel setchannelerrorinterp $c [lrange $msg 0 end]
+    } -cleanup {
+	chan close $c
+	removeFile cutsplice
+    } -result [lrange $expected 0 end]
+}
+
+test chan-io-73.1 {channel Tcl_Obj SetChannelFromAny} -body {
+    # Test for Bug 1847044 - don't spoil type unless we have a valid channel
+    chan close [lreplace [list a] 0 end]
+} -returnCodes error -match glob -result *
+
+# ### ### ### ######### ######### #########
+
+# cleanup
+foreach file [list fooBar longfile script output test1 pipe my_script \
+	test2 test3 cat kyrillic.txt utf8-fcopy.txt utf8-rp.txt] {
+    removeFile $file
+}
+cleanupTests
+}
+namespace delete ::tcl::test::io
diff --git a/tests/clock.test b/tests/clock.test
new file mode 100644
index 0000000..615f3a8
--- /dev/null
+++ b/tests/clock.test
@@ -0,0 +1,36974 @@
+# clock.test --
+#
+#	This test file covers the 'clock' command that manipulates time.
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors.  No output means no errors were found.
+#
+# Copyright (c) 2004 by Kevin B. Kenny.  All rights reserved.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+    package require tcltest 2
+    namespace import -force ::tcltest::*
+}
+
+if {[testConstraint win]} {
+    if {[catch {
+	    ::tcltest::loadTestedCommands
+	    package require registry
+	}]} {
+	namespace eval ::tcl::clock {variable NoRegistry {}}
+    }
+}
+
+package require msgcat 1.4
+
+testConstraint detroit \
+    [expr {![catch {clock format 0 -timezone :America/Detroit -format %z}]}]
+testConstraint y2038 \
+    [expr {[clock format 2158894800 -format %z -timezone :America/Detroit] eq {-0400}}]
+
+# TEST PLAN
+
+# clock-1:
+#	[clock format] - tests of bad and empty arguments 
+#
+# clock-2 
+#	formatting of year, month and day of month
+#
+# clock-3
+#	formatting of fiscal year, fiscal week and day of week.
+#
+# clock-4
+#	formatting of time of day.
+#
+# clock-5
+#	handling of Daylight Saving Time in a known locale, formatting of
+#	%z and %Z
+#
+# clock-6
+#	input conversion - seconds
+#
+# clock-7
+#	input conversion - Julian Day
+#
+# clock-8
+#	input conversion - ccyymmdd
+#
+# clock-9
+#	input conversion - ccyymmdd (test that %s and %J take precedence)
+#
+# clock-10
+#	input conversion - ccyyddd
+#
+# clock-11
+#	input conversion - relative precedence of ccyyddd and ccyymmdd
+#	(tests the 'rightmost field' comparison)
+#
+# clock-12
+#	input conversion - ccyyWwwd
+#
+# clock-13
+#	input conversion - ccyyWwwd (test that %s and %J take precedence,
+#	and that invalid days are rejected).
+#
+# clock-14
+#	input conversion - yymmdd
+#
+# clock-15
+#	precedence - yymmdd
+#
+# clock-16
+#	input conversion and precedence - yyddd
+#
+# clock-17
+#	input conversion - yyWwwd
+#
+# clock-18
+#	precedence - yyWwwd
+#
+# clock-19
+#	input conversion - mmdd
+#
+# clock-20
+#	precedence - mmdd
+#
+# clock-21
+#	input conversion and precedence - ddd
+#
+# clock-22
+#	input conversion - Wwwd
+#
+# clock-23
+#	precedence - Wwwd
+#
+# clock-24
+#	input conversion - naked day of month
+#
+# clock-25
+#	precedence - naked day of month
+#
+# clock-26
+#	input conversion - naked day of week
+#
+# clock-27
+#	precedence - day of week
+#
+# clock-28
+#	scan with empty -format is midnight of base date
+#
+# clock-29
+#	scanning of all time-of-day formats
+#
+# clock-30
+#	[clock add]
+#
+# clock-31
+#	Use of -locale system on Windows
+#
+# clock-32
+#	Handling of the Julian-Gregorian transition
+#
+# clock-33
+#	Legacy tests - [clock clicks]
+#
+# clock-34
+#	Legacy tests - [clock scan] without -format
+#
+# clock-35
+#	Legacy tests - [clock seconds]
+#
+# clock-36
+#	Legacy tests - [clock scan] with 'next monthname'
+#
+# clock-37
+#	Test that -gmt does not affect the value of %s
+#
+# clock-38
+#	Regression test to verify that changes in TZ work
+#	both east and west of Greenwich
+
+
+# Note that all code between comments '# BEGIN' and '# END' is
+# autogenerated by 'tools/makeTestCases.tcl'.  DO NOT EDIT CODE BETWEEN
+# '# BEGIN' and '# END'.
+
+# Define a fictitious locale, 'en_US_roman', for formatting of clock
+# strings with localized numerics and eras.  This locale will be used
+# in testing the 'clock' command.
+
+namespace eval ::tcl::clock {
+    ::msgcat::mcmset en_US_roman {
+	LOCALE_ERAS {
+	    {-62164627200 {} 0}
+	    {-59008867200 c 100}
+	    {-55853107200 cc 200}
+	    {-52697347200 ccc 300}
+	    {-49541587200 cd 400}
+	    {-46385827200 d 500}
+	    {-43230067200 dc 600}
+	    {-40074307200 dcc 700}
+	    {-36918547200 dccc 800}
+	    {-33762787200 cm 900}
+	    {-30607027200 m 1000}
+	    {-27451267200 mc 1100}
+	    {-24295507200 mcc 1200}
+	    {-21139747200 mccc 1300}
+	    {-17983987200 mcd 1400}
+	    {-14828227200 md 1500}
+	    {-11672467200 mdc 1600}
+	    {-8516707200 mdcc 1700}
+	    {-5364662400 mdccc 1800}
+	    {-2208988800 mcm 1900}
+	    {946684800 mm 2000}
+	}
+	LOCALE_NUMERALS {
+	    ? i ii iii iv v vi vii viii ix
+	    x xi xii xiii xiv xv xvi xvii xviii xix
+	    xx xxi xxii xxiii xxiv xxv xxvi xxvii xxviii xxix
+	    xxx xxxi xxxii xxxiii xxxiv xxxv xxxvi xxxvii xxxviii xxxix
+	    xl xli xlii xliii xliv xlv xlvi xlvii xlviii xlix
+	    l li lii liii liv lv lvi lvii lviii lix
+	    lx lxi lxii lxiii lxiv lxv lxvi lxvii lxviii lxix
+	    lxx lxxi lxxii lxxiii lxxiv lxxv lxxvi lxxvii lxxviii lxxix
+	    lxxx lxxxi lxxxii lxxxiii lxxxiv lxxxv lxxxvi lxxxvii lxxxviii 
+	    lxxxix
+	    xc xci xcii xciii xciv xcv xcvi xcvii xcviii xcix
+	    c
+	}
+	DATE_FORMAT {%m/%d/%Y}
+	TIME_FORMAT {%H:%M:%S}
+	DATE_TIME_FORMAT {%x %X}
+	LOCALE_DATE_FORMAT {die %Od mensis %Om annoque %EY}
+	LOCALE_TIME_FORMAT {%OH h %OM m %OS s}
+	LOCALE_DATE_TIME_FORMAT {%Ex %EX}
+	BCE {Before Christ}
+	CE {Anno Domini}
+    }
+}
+
+#----------------------------------------------------------------------
+#
+# The tests for the Windows platform are careful *not* to muck with
+# the system registry.  Instead, the 'registry' command is overridden
+# in the '::tcl::clock' namespace.
+#
+#----------------------------------------------------------------------
+
+namespace eval ::testClock {
+    namespace export registry
+    set reg \
+	[dict create \
+	     HKEY_CURRENT_USER\\Control\ Panel\\International \
+	     [dict create \
+		  locale 0409 \
+		  sShortDate dd-MMM-yyyy \
+		  sLongDate "'the' dd''' day of' MMMM yyyy" \
+		  sTimeFormat "h:mm:ss tt"] \
+	     HKEY_LOCAL_MACHINE\\System\\CurrentControlSet\\Control\\TimeZoneInformation \
+	     [dict create \
+		  Bias 300 \
+		  StandardBias 0 \
+		  DaylightBias -60 \
+		  StandardStart \x00\x00\x0b\x00\x01\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00 \
+		  DaylightStart \x00\x00\x03\x00\x02\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00]]
+}
+
+
+proc ::testClock::registry { cmd path key } {
+    variable reg
+    if { $cmd ne {get} } {
+	return -code error "test case attempts to write/query the registry"
+    }
+    if { ![dict exists $reg $path $key] } {
+	return -code error "test case attempts to read unknown registry entry $path $key"
+    }
+    return [dict get $reg $path $key]
+}
+
+# Test some of the basics of [clock format]
+
+test clock-1.0 "clock format - wrong # args" {
+    list [catch {clock format} msg] $msg $::errorCode
+} {1 {wrong # args: should be "clock format clockval ?-format string? ?-gmt boolean? ?-locale LOCALE? ?-timezone ZONE?"} {CLOCK wrongNumArgs}}
+
+test clock-1.1 "clock format - bad time" {
+    list [catch {clock format foo} msg] $msg
+} {1 {expected integer but got "foo"}}
+
+test clock-1.2 "clock format - bad gmt val" {
+    list [catch {clock format 0 -gmt foo} msg] $msg
+} {1 {expected boolean value but got "foo"}}
+
+test clock-1.3 "clock format - empty val" {
+    clock format 0 -gmt 1 -format ""
+} {}
+
+test clock-1.4 "clock format - bad flag" {*}{
+    -body {
+    list [catch {clock format 0 -oops badflag} msg] $msg $::errorCode
+    } 
+    -match glob
+    -result {1 {bad option "-oops": must be -format, -gmt, -locale, or -timezone} {CLOCK badOption -oops}}
+}
+
+test clock-1.5 "clock format - bad timezone" {
+    list [catch {clock format 0 -format "%s" -timezone :NOWHERE} msg] $msg $::errorCode
+} {1 {time zone ":NOWHERE" not found} {CLOCK badTimeZone :NOWHERE}}
+
+test clock-1.6 "clock format - gmt + timezone" {
+    list [catch {clock format 0 -timezone :GMT -gmt true} msg] $msg $::errorCode
+} {1 {cannot use -gmt and -timezone in same call} {CLOCK gmtWithTimezone}}
+
+test clock-1.7 "clock format - option abbreviations" {
+    clock format 0 -g true -f "%Y-%m-%d"
+} 1970-01-01
+
+# BEGIN testcases2
+
+# Test formatting of Gregorian year, month, day, all formats
+# Formats tested: %b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y %EY
+
+test clock-2.1 {conversion of 1872-01-01} {
+    clock format -3092556304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/01/1872 12:34:56 die i mensis i annoque mdccclxxii xii h xxxiv m lvi s 18 mdccc 01 i  1 i Jan 001 2404794 01 i  1 01/01/1872 die i mensis i annoque mdccclxxii 72 lxxii 1872}
+test clock-2.2 {conversion of 1872-01-31} {
+    clock format -3089964304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/31/1872 12:34:56 die xxxi mensis i annoque mdccclxxii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Jan 031 2404824 01 i  1 01/31/1872 die xxxi mensis i annoque mdccclxxii 72 lxxii 1872}
+test clock-2.3 {conversion of 1872-02-01} {
+    clock format -3089877904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/01/1872 12:34:56 die i mensis ii annoque mdccclxxii xii h xxxiv m lvi s 18 mdccc 01 i  1 i Feb 032 2404825 02 ii  2 02/01/1872 die i mensis ii annoque mdccclxxii 72 lxxii 1872}
+test clock-2.4 {conversion of 1872-02-29} {
+    clock format -3087458704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/29/1872 12:34:56 die xxix mensis ii annoque mdccclxxii xii h xxxiv m lvi s 18 mdccc 29 xxix 29 xxix Feb 060 2404853 02 ii  2 02/29/1872 die xxix mensis ii annoque mdccclxxii 72 lxxii 1872}
+test clock-2.5 {conversion of 1872-03-01} {
+    clock format -3087372304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/01/1872 12:34:56 die i mensis iii annoque mdccclxxii xii h xxxiv m lvi s 18 mdccc 01 i  1 i Mar 061 2404854 03 iii  3 03/01/1872 die i mensis iii annoque mdccclxxii 72 lxxii 1872}
+test clock-2.6 {conversion of 1872-03-31} {
+    clock format -3084780304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/31/1872 12:34:56 die xxxi mensis iii annoque mdccclxxii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Mar 091 2404884 03 iii  3 03/31/1872 die xxxi mensis iii annoque mdccclxxii 72 lxxii 1872}
+test clock-2.7 {conversion of 1872-04-01} {
+    clock format -3084693904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/01/1872 12:34:56 die i mensis iv annoque mdccclxxii xii h xxxiv m lvi s 18 mdccc 01 i  1 i Apr 092 2404885 04 iv  4 04/01/1872 die i mensis iv annoque mdccclxxii 72 lxxii 1872}
+test clock-2.8 {conversion of 1872-04-30} {
+    clock format -3082188304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/30/1872 12:34:56 die xxx mensis iv annoque mdccclxxii xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Apr 121 2404914 04 iv  4 04/30/1872 die xxx mensis iv annoque mdccclxxii 72 lxxii 1872}
+test clock-2.9 {conversion of 1872-05-01} {
+    clock format -3082101904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/01/1872 12:34:56 die i mensis v annoque mdccclxxii xii h xxxiv m lvi s 18 mdccc 01 i  1 i May 122 2404915 05 v  5 05/01/1872 die i mensis v annoque mdccclxxii 72 lxxii 1872}
+test clock-2.10 {conversion of 1872-05-31} {
+    clock format -3079509904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/31/1872 12:34:56 die xxxi mensis v annoque mdccclxxii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi May 152 2404945 05 v  5 05/31/1872 die xxxi mensis v annoque mdccclxxii 72 lxxii 1872}
+test clock-2.11 {conversion of 1872-06-01} {
+    clock format -3079423504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/01/1872 12:34:56 die i mensis vi annoque mdccclxxii xii h xxxiv m lvi s 18 mdccc 01 i  1 i Jun 153 2404946 06 vi  6 06/01/1872 die i mensis vi annoque mdccclxxii 72 lxxii 1872}
+test clock-2.12 {conversion of 1872-06-30} {
+    clock format -3076917904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/30/1872 12:34:56 die xxx mensis vi annoque mdccclxxii xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Jun 182 2404975 06 vi  6 06/30/1872 die xxx mensis vi annoque mdccclxxii 72 lxxii 1872}
+test clock-2.13 {conversion of 1872-07-01} {
+    clock format -3076831504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/01/1872 12:34:56 die i mensis vii annoque mdccclxxii xii h xxxiv m lvi s 18 mdccc 01 i  1 i Jul 183 2404976 07 vii  7 07/01/1872 die i mensis vii annoque mdccclxxii 72 lxxii 1872}
+test clock-2.14 {conversion of 1872-07-31} {
+    clock format -3074239504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/31/1872 12:34:56 die xxxi mensis vii annoque mdccclxxii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Jul 213 2405006 07 vii  7 07/31/1872 die xxxi mensis vii annoque mdccclxxii 72 lxxii 1872}
+test clock-2.15 {conversion of 1872-08-01} {
+    clock format -3074153104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/01/1872 12:34:56 die i mensis viii annoque mdccclxxii xii h xxxiv m lvi s 18 mdccc 01 i  1 i Aug 214 2405007 08 viii  8 08/01/1872 die i mensis viii annoque mdccclxxii 72 lxxii 1872}
+test clock-2.16 {conversion of 1872-08-31} {
+    clock format -3071561104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/31/1872 12:34:56 die xxxi mensis viii annoque mdccclxxii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Aug 244 2405037 08 viii  8 08/31/1872 die xxxi mensis viii annoque mdccclxxii 72 lxxii 1872}
+test clock-2.17 {conversion of 1872-09-01} {
+    clock format -3071474704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/01/1872 12:34:56 die i mensis ix annoque mdccclxxii xii h xxxiv m lvi s 18 mdccc 01 i  1 i Sep 245 2405038 09 ix  9 09/01/1872 die i mensis ix annoque mdccclxxii 72 lxxii 1872}
+test clock-2.18 {conversion of 1872-09-30} {
+    clock format -3068969104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/30/1872 12:34:56 die xxx mensis ix annoque mdccclxxii xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Sep 274 2405067 09 ix  9 09/30/1872 die xxx mensis ix annoque mdccclxxii 72 lxxii 1872}
+test clock-2.19 {conversion of 1872-10-01} {
+    clock format -3068882704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/01/1872 12:34:56 die i mensis x annoque mdccclxxii xii h xxxiv m lvi s 18 mdccc 01 i  1 i Oct 275 2405068 10 x 10 10/01/1872 die i mensis x annoque mdccclxxii 72 lxxii 1872}
+test clock-2.20 {conversion of 1872-10-31} {
+    clock format -3066290704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/31/1872 12:34:56 die xxxi mensis x annoque mdccclxxii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Oct 305 2405098 10 x 10 10/31/1872 die xxxi mensis x annoque mdccclxxii 72 lxxii 1872}
+test clock-2.21 {conversion of 1872-11-01} {
+    clock format -3066204304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/01/1872 12:34:56 die i mensis xi annoque mdccclxxii xii h xxxiv m lvi s 18 mdccc 01 i  1 i Nov 306 2405099 11 xi 11 11/01/1872 die i mensis xi annoque mdccclxxii 72 lxxii 1872}
+test clock-2.22 {conversion of 1872-11-30} {
+    clock format -3063698704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/30/1872 12:34:56 die xxx mensis xi annoque mdccclxxii xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Nov 335 2405128 11 xi 11 11/30/1872 die xxx mensis xi annoque mdccclxxii 72 lxxii 1872}
+test clock-2.23 {conversion of 1872-12-01} {
+    clock format -3063612304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/01/1872 12:34:56 die i mensis xii annoque mdccclxxii xii h xxxiv m lvi s 18 mdccc 01 i  1 i Dec 336 2405129 12 xii 12 12/01/1872 die i mensis xii annoque mdccclxxii 72 lxxii 1872}
+test clock-2.24 {conversion of 1872-12-31} {
+    clock format -3061020304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/31/1872 12:34:56 die xxxi mensis xii annoque mdccclxxii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Dec 366 2405159 12 xii 12 12/31/1872 die xxxi mensis xii annoque mdccclxxii 72 lxxii 1872}
+test clock-2.25 {conversion of 1873-01-01} {
+    clock format -3060933904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/01/1873 12:34:56 die i mensis i annoque mdccclxxiii xii h xxxiv m lvi s 18 mdccc 01 i  1 i Jan 001 2405160 01 i  1 01/01/1873 die i mensis i annoque mdccclxxiii 73 lxxiii 1873}
+test clock-2.26 {conversion of 1873-01-31} {
+    clock format -3058341904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/31/1873 12:34:56 die xxxi mensis i annoque mdccclxxiii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Jan 031 2405190 01 i  1 01/31/1873 die xxxi mensis i annoque mdccclxxiii 73 lxxiii 1873}
+test clock-2.27 {conversion of 1873-02-01} {
+    clock format -3058255504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/01/1873 12:34:56 die i mensis ii annoque mdccclxxiii xii h xxxiv m lvi s 18 mdccc 01 i  1 i Feb 032 2405191 02 ii  2 02/01/1873 die i mensis ii annoque mdccclxxiii 73 lxxiii 1873}
+test clock-2.28 {conversion of 1873-02-28} {
+    clock format -3055922704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/28/1873 12:34:56 die xxviii mensis ii annoque mdccclxxiii xii h xxxiv m lvi s 18 mdccc 28 xxviii 28 xxviii Feb 059 2405218 02 ii  2 02/28/1873 die xxviii mensis ii annoque mdccclxxiii 73 lxxiii 1873}
+test clock-2.29 {conversion of 1873-03-01} {
+    clock format -3055836304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/01/1873 12:34:56 die i mensis iii annoque mdccclxxiii xii h xxxiv m lvi s 18 mdccc 01 i  1 i Mar 060 2405219 03 iii  3 03/01/1873 die i mensis iii annoque mdccclxxiii 73 lxxiii 1873}
+test clock-2.30 {conversion of 1873-03-31} {
+    clock format -3053244304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/31/1873 12:34:56 die xxxi mensis iii annoque mdccclxxiii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Mar 090 2405249 03 iii  3 03/31/1873 die xxxi mensis iii annoque mdccclxxiii 73 lxxiii 1873}
+test clock-2.31 {conversion of 1873-04-01} {
+    clock format -3053157904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/01/1873 12:34:56 die i mensis iv annoque mdccclxxiii xii h xxxiv m lvi s 18 mdccc 01 i  1 i Apr 091 2405250 04 iv  4 04/01/1873 die i mensis iv annoque mdccclxxiii 73 lxxiii 1873}
+test clock-2.32 {conversion of 1873-04-30} {
+    clock format -3050652304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/30/1873 12:34:56 die xxx mensis iv annoque mdccclxxiii xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Apr 120 2405279 04 iv  4 04/30/1873 die xxx mensis iv annoque mdccclxxiii 73 lxxiii 1873}
+test clock-2.33 {conversion of 1873-05-01} {
+    clock format -3050565904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/01/1873 12:34:56 die i mensis v annoque mdccclxxiii xii h xxxiv m lvi s 18 mdccc 01 i  1 i May 121 2405280 05 v  5 05/01/1873 die i mensis v annoque mdccclxxiii 73 lxxiii 1873}
+test clock-2.34 {conversion of 1873-05-31} {
+    clock format -3047973904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/31/1873 12:34:56 die xxxi mensis v annoque mdccclxxiii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi May 151 2405310 05 v  5 05/31/1873 die xxxi mensis v annoque mdccclxxiii 73 lxxiii 1873}
+test clock-2.35 {conversion of 1873-06-01} {
+    clock format -3047887504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/01/1873 12:34:56 die i mensis vi annoque mdccclxxiii xii h xxxiv m lvi s 18 mdccc 01 i  1 i Jun 152 2405311 06 vi  6 06/01/1873 die i mensis vi annoque mdccclxxiii 73 lxxiii 1873}
+test clock-2.36 {conversion of 1873-06-30} {
+    clock format -3045381904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/30/1873 12:34:56 die xxx mensis vi annoque mdccclxxiii xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Jun 181 2405340 06 vi  6 06/30/1873 die xxx mensis vi annoque mdccclxxiii 73 lxxiii 1873}
+test clock-2.37 {conversion of 1873-07-01} {
+    clock format -3045295504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/01/1873 12:34:56 die i mensis vii annoque mdccclxxiii xii h xxxiv m lvi s 18 mdccc 01 i  1 i Jul 182 2405341 07 vii  7 07/01/1873 die i mensis vii annoque mdccclxxiii 73 lxxiii 1873}
+test clock-2.38 {conversion of 1873-07-31} {
+    clock format -3042703504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/31/1873 12:34:56 die xxxi mensis vii annoque mdccclxxiii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Jul 212 2405371 07 vii  7 07/31/1873 die xxxi mensis vii annoque mdccclxxiii 73 lxxiii 1873}
+test clock-2.39 {conversion of 1873-08-01} {
+    clock format -3042617104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/01/1873 12:34:56 die i mensis viii annoque mdccclxxiii xii h xxxiv m lvi s 18 mdccc 01 i  1 i Aug 213 2405372 08 viii  8 08/01/1873 die i mensis viii annoque mdccclxxiii 73 lxxiii 1873}
+test clock-2.40 {conversion of 1873-08-31} {
+    clock format -3040025104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/31/1873 12:34:56 die xxxi mensis viii annoque mdccclxxiii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Aug 243 2405402 08 viii  8 08/31/1873 die xxxi mensis viii annoque mdccclxxiii 73 lxxiii 1873}
+test clock-2.41 {conversion of 1873-09-01} {
+    clock format -3039938704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/01/1873 12:34:56 die i mensis ix annoque mdccclxxiii xii h xxxiv m lvi s 18 mdccc 01 i  1 i Sep 244 2405403 09 ix  9 09/01/1873 die i mensis ix annoque mdccclxxiii 73 lxxiii 1873}
+test clock-2.42 {conversion of 1873-09-30} {
+    clock format -3037433104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/30/1873 12:34:56 die xxx mensis ix annoque mdccclxxiii xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Sep 273 2405432 09 ix  9 09/30/1873 die xxx mensis ix annoque mdccclxxiii 73 lxxiii 1873}
+test clock-2.43 {conversion of 1873-10-01} {
+    clock format -3037346704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/01/1873 12:34:56 die i mensis x annoque mdccclxxiii xii h xxxiv m lvi s 18 mdccc 01 i  1 i Oct 274 2405433 10 x 10 10/01/1873 die i mensis x annoque mdccclxxiii 73 lxxiii 1873}
+test clock-2.44 {conversion of 1873-10-31} {
+    clock format -3034754704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/31/1873 12:34:56 die xxxi mensis x annoque mdccclxxiii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Oct 304 2405463 10 x 10 10/31/1873 die xxxi mensis x annoque mdccclxxiii 73 lxxiii 1873}
+test clock-2.45 {conversion of 1873-11-01} {
+    clock format -3034668304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/01/1873 12:34:56 die i mensis xi annoque mdccclxxiii xii h xxxiv m lvi s 18 mdccc 01 i  1 i Nov 305 2405464 11 xi 11 11/01/1873 die i mensis xi annoque mdccclxxiii 73 lxxiii 1873}
+test clock-2.46 {conversion of 1873-11-30} {
+    clock format -3032162704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/30/1873 12:34:56 die xxx mensis xi annoque mdccclxxiii xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Nov 334 2405493 11 xi 11 11/30/1873 die xxx mensis xi annoque mdccclxxiii 73 lxxiii 1873}
+test clock-2.47 {conversion of 1873-12-01} {
+    clock format -3032076304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/01/1873 12:34:56 die i mensis xii annoque mdccclxxiii xii h xxxiv m lvi s 18 mdccc 01 i  1 i Dec 335 2405494 12 xii 12 12/01/1873 die i mensis xii annoque mdccclxxiii 73 lxxiii 1873}
+test clock-2.48 {conversion of 1873-12-31} {
+    clock format -3029484304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/31/1873 12:34:56 die xxxi mensis xii annoque mdccclxxiii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Dec 365 2405524 12 xii 12 12/31/1873 die xxxi mensis xii annoque mdccclxxiii 73 lxxiii 1873}
+test clock-2.49 {conversion of 1876-01-01} {
+    clock format -2966325904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/01/1876 12:34:56 die i mensis i annoque mdccclxxvi xii h xxxiv m lvi s 18 mdccc 01 i  1 i Jan 001 2406255 01 i  1 01/01/1876 die i mensis i annoque mdccclxxvi 76 lxxvi 1876}
+test clock-2.50 {conversion of 1876-01-31} {
+    clock format -2963733904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/31/1876 12:34:56 die xxxi mensis i annoque mdccclxxvi xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Jan 031 2406285 01 i  1 01/31/1876 die xxxi mensis i annoque mdccclxxvi 76 lxxvi 1876}
+test clock-2.51 {conversion of 1876-02-01} {
+    clock format -2963647504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/01/1876 12:34:56 die i mensis ii annoque mdccclxxvi xii h xxxiv m lvi s 18 mdccc 01 i  1 i Feb 032 2406286 02 ii  2 02/01/1876 die i mensis ii annoque mdccclxxvi 76 lxxvi 1876}
+test clock-2.52 {conversion of 1876-02-29} {
+    clock format -2961228304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/29/1876 12:34:56 die xxix mensis ii annoque mdccclxxvi xii h xxxiv m lvi s 18 mdccc 29 xxix 29 xxix Feb 060 2406314 02 ii  2 02/29/1876 die xxix mensis ii annoque mdccclxxvi 76 lxxvi 1876}
+test clock-2.53 {conversion of 1876-03-01} {
+    clock format -2961141904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/01/1876 12:34:56 die i mensis iii annoque mdccclxxvi xii h xxxiv m lvi s 18 mdccc 01 i  1 i Mar 061 2406315 03 iii  3 03/01/1876 die i mensis iii annoque mdccclxxvi 76 lxxvi 1876}
+test clock-2.54 {conversion of 1876-03-31} {
+    clock format -2958549904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/31/1876 12:34:56 die xxxi mensis iii annoque mdccclxxvi xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Mar 091 2406345 03 iii  3 03/31/1876 die xxxi mensis iii annoque mdccclxxvi 76 lxxvi 1876}
+test clock-2.55 {conversion of 1876-04-01} {
+    clock format -2958463504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/01/1876 12:34:56 die i mensis iv annoque mdccclxxvi xii h xxxiv m lvi s 18 mdccc 01 i  1 i Apr 092 2406346 04 iv  4 04/01/1876 die i mensis iv annoque mdccclxxvi 76 lxxvi 1876}
+test clock-2.56 {conversion of 1876-04-30} {
+    clock format -2955957904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/30/1876 12:34:56 die xxx mensis iv annoque mdccclxxvi xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Apr 121 2406375 04 iv  4 04/30/1876 die xxx mensis iv annoque mdccclxxvi 76 lxxvi 1876}
+test clock-2.57 {conversion of 1876-05-01} {
+    clock format -2955871504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/01/1876 12:34:56 die i mensis v annoque mdccclxxvi xii h xxxiv m lvi s 18 mdccc 01 i  1 i May 122 2406376 05 v  5 05/01/1876 die i mensis v annoque mdccclxxvi 76 lxxvi 1876}
+test clock-2.58 {conversion of 1876-05-31} {
+    clock format -2953279504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/31/1876 12:34:56 die xxxi mensis v annoque mdccclxxvi xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi May 152 2406406 05 v  5 05/31/1876 die xxxi mensis v annoque mdccclxxvi 76 lxxvi 1876}
+test clock-2.59 {conversion of 1876-06-01} {
+    clock format -2953193104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/01/1876 12:34:56 die i mensis vi annoque mdccclxxvi xii h xxxiv m lvi s 18 mdccc 01 i  1 i Jun 153 2406407 06 vi  6 06/01/1876 die i mensis vi annoque mdccclxxvi 76 lxxvi 1876}
+test clock-2.60 {conversion of 1876-06-30} {
+    clock format -2950687504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/30/1876 12:34:56 die xxx mensis vi annoque mdccclxxvi xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Jun 182 2406436 06 vi  6 06/30/1876 die xxx mensis vi annoque mdccclxxvi 76 lxxvi 1876}
+test clock-2.61 {conversion of 1876-07-01} {
+    clock format -2950601104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/01/1876 12:34:56 die i mensis vii annoque mdccclxxvi xii h xxxiv m lvi s 18 mdccc 01 i  1 i Jul 183 2406437 07 vii  7 07/01/1876 die i mensis vii annoque mdccclxxvi 76 lxxvi 1876}
+test clock-2.62 {conversion of 1876-07-31} {
+    clock format -2948009104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/31/1876 12:34:56 die xxxi mensis vii annoque mdccclxxvi xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Jul 213 2406467 07 vii  7 07/31/1876 die xxxi mensis vii annoque mdccclxxvi 76 lxxvi 1876}
+test clock-2.63 {conversion of 1876-08-01} {
+    clock format -2947922704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/01/1876 12:34:56 die i mensis viii annoque mdccclxxvi xii h xxxiv m lvi s 18 mdccc 01 i  1 i Aug 214 2406468 08 viii  8 08/01/1876 die i mensis viii annoque mdccclxxvi 76 lxxvi 1876}
+test clock-2.64 {conversion of 1876-08-31} {
+    clock format -2945330704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/31/1876 12:34:56 die xxxi mensis viii annoque mdccclxxvi xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Aug 244 2406498 08 viii  8 08/31/1876 die xxxi mensis viii annoque mdccclxxvi 76 lxxvi 1876}
+test clock-2.65 {conversion of 1876-09-01} {
+    clock format -2945244304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/01/1876 12:34:56 die i mensis ix annoque mdccclxxvi xii h xxxiv m lvi s 18 mdccc 01 i  1 i Sep 245 2406499 09 ix  9 09/01/1876 die i mensis ix annoque mdccclxxvi 76 lxxvi 1876}
+test clock-2.66 {conversion of 1876-09-30} {
+    clock format -2942738704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/30/1876 12:34:56 die xxx mensis ix annoque mdccclxxvi xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Sep 274 2406528 09 ix  9 09/30/1876 die xxx mensis ix annoque mdccclxxvi 76 lxxvi 1876}
+test clock-2.67 {conversion of 1876-10-01} {
+    clock format -2942652304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/01/1876 12:34:56 die i mensis x annoque mdccclxxvi xii h xxxiv m lvi s 18 mdccc 01 i  1 i Oct 275 2406529 10 x 10 10/01/1876 die i mensis x annoque mdccclxxvi 76 lxxvi 1876}
+test clock-2.68 {conversion of 1876-10-31} {
+    clock format -2940060304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/31/1876 12:34:56 die xxxi mensis x annoque mdccclxxvi xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Oct 305 2406559 10 x 10 10/31/1876 die xxxi mensis x annoque mdccclxxvi 76 lxxvi 1876}
+test clock-2.69 {conversion of 1876-11-01} {
+    clock format -2939973904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/01/1876 12:34:56 die i mensis xi annoque mdccclxxvi xii h xxxiv m lvi s 18 mdccc 01 i  1 i Nov 306 2406560 11 xi 11 11/01/1876 die i mensis xi annoque mdccclxxvi 76 lxxvi 1876}
+test clock-2.70 {conversion of 1876-11-30} {
+    clock format -2937468304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/30/1876 12:34:56 die xxx mensis xi annoque mdccclxxvi xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Nov 335 2406589 11 xi 11 11/30/1876 die xxx mensis xi annoque mdccclxxvi 76 lxxvi 1876}
+test clock-2.71 {conversion of 1876-12-01} {
+    clock format -2937381904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/01/1876 12:34:56 die i mensis xii annoque mdccclxxvi xii h xxxiv m lvi s 18 mdccc 01 i  1 i Dec 336 2406590 12 xii 12 12/01/1876 die i mensis xii annoque mdccclxxvi 76 lxxvi 1876}
+test clock-2.72 {conversion of 1876-12-31} {
+    clock format -2934789904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/31/1876 12:34:56 die xxxi mensis xii annoque mdccclxxvi xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Dec 366 2406620 12 xii 12 12/31/1876 die xxxi mensis xii annoque mdccclxxvi 76 lxxvi 1876}
+test clock-2.73 {conversion of 1877-01-01} {
+    clock format -2934703504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/01/1877 12:34:56 die i mensis i annoque mdccclxxvii xii h xxxiv m lvi s 18 mdccc 01 i  1 i Jan 001 2406621 01 i  1 01/01/1877 die i mensis i annoque mdccclxxvii 77 lxxvii 1877}
+test clock-2.74 {conversion of 1877-01-31} {
+    clock format -2932111504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/31/1877 12:34:56 die xxxi mensis i annoque mdccclxxvii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Jan 031 2406651 01 i  1 01/31/1877 die xxxi mensis i annoque mdccclxxvii 77 lxxvii 1877}
+test clock-2.75 {conversion of 1877-02-01} {
+    clock format -2932025104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/01/1877 12:34:56 die i mensis ii annoque mdccclxxvii xii h xxxiv m lvi s 18 mdccc 01 i  1 i Feb 032 2406652 02 ii  2 02/01/1877 die i mensis ii annoque mdccclxxvii 77 lxxvii 1877}
+test clock-2.76 {conversion of 1877-02-28} {
+    clock format -2929692304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/28/1877 12:34:56 die xxviii mensis ii annoque mdccclxxvii xii h xxxiv m lvi s 18 mdccc 28 xxviii 28 xxviii Feb 059 2406679 02 ii  2 02/28/1877 die xxviii mensis ii annoque mdccclxxvii 77 lxxvii 1877}
+test clock-2.77 {conversion of 1877-03-01} {
+    clock format -2929605904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/01/1877 12:34:56 die i mensis iii annoque mdccclxxvii xii h xxxiv m lvi s 18 mdccc 01 i  1 i Mar 060 2406680 03 iii  3 03/01/1877 die i mensis iii annoque mdccclxxvii 77 lxxvii 1877}
+test clock-2.78 {conversion of 1877-03-31} {
+    clock format -2927013904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/31/1877 12:34:56 die xxxi mensis iii annoque mdccclxxvii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Mar 090 2406710 03 iii  3 03/31/1877 die xxxi mensis iii annoque mdccclxxvii 77 lxxvii 1877}
+test clock-2.79 {conversion of 1877-04-01} {
+    clock format -2926927504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/01/1877 12:34:56 die i mensis iv annoque mdccclxxvii xii h xxxiv m lvi s 18 mdccc 01 i  1 i Apr 091 2406711 04 iv  4 04/01/1877 die i mensis iv annoque mdccclxxvii 77 lxxvii 1877}
+test clock-2.80 {conversion of 1877-04-30} {
+    clock format -2924421904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/30/1877 12:34:56 die xxx mensis iv annoque mdccclxxvii xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Apr 120 2406740 04 iv  4 04/30/1877 die xxx mensis iv annoque mdccclxxvii 77 lxxvii 1877}
+test clock-2.81 {conversion of 1877-05-01} {
+    clock format -2924335504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/01/1877 12:34:56 die i mensis v annoque mdccclxxvii xii h xxxiv m lvi s 18 mdccc 01 i  1 i May 121 2406741 05 v  5 05/01/1877 die i mensis v annoque mdccclxxvii 77 lxxvii 1877}
+test clock-2.82 {conversion of 1877-05-31} {
+    clock format -2921743504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/31/1877 12:34:56 die xxxi mensis v annoque mdccclxxvii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi May 151 2406771 05 v  5 05/31/1877 die xxxi mensis v annoque mdccclxxvii 77 lxxvii 1877}
+test clock-2.83 {conversion of 1877-06-01} {
+    clock format -2921657104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/01/1877 12:34:56 die i mensis vi annoque mdccclxxvii xii h xxxiv m lvi s 18 mdccc 01 i  1 i Jun 152 2406772 06 vi  6 06/01/1877 die i mensis vi annoque mdccclxxvii 77 lxxvii 1877}
+test clock-2.84 {conversion of 1877-06-30} {
+    clock format -2919151504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/30/1877 12:34:56 die xxx mensis vi annoque mdccclxxvii xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Jun 181 2406801 06 vi  6 06/30/1877 die xxx mensis vi annoque mdccclxxvii 77 lxxvii 1877}
+test clock-2.85 {conversion of 1877-07-01} {
+    clock format -2919065104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/01/1877 12:34:56 die i mensis vii annoque mdccclxxvii xii h xxxiv m lvi s 18 mdccc 01 i  1 i Jul 182 2406802 07 vii  7 07/01/1877 die i mensis vii annoque mdccclxxvii 77 lxxvii 1877}
+test clock-2.86 {conversion of 1877-07-31} {
+    clock format -2916473104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/31/1877 12:34:56 die xxxi mensis vii annoque mdccclxxvii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Jul 212 2406832 07 vii  7 07/31/1877 die xxxi mensis vii annoque mdccclxxvii 77 lxxvii 1877}
+test clock-2.87 {conversion of 1877-08-01} {
+    clock format -2916386704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/01/1877 12:34:56 die i mensis viii annoque mdccclxxvii xii h xxxiv m lvi s 18 mdccc 01 i  1 i Aug 213 2406833 08 viii  8 08/01/1877 die i mensis viii annoque mdccclxxvii 77 lxxvii 1877}
+test clock-2.88 {conversion of 1877-08-31} {
+    clock format -2913794704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/31/1877 12:34:56 die xxxi mensis viii annoque mdccclxxvii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Aug 243 2406863 08 viii  8 08/31/1877 die xxxi mensis viii annoque mdccclxxvii 77 lxxvii 1877}
+test clock-2.89 {conversion of 1877-09-01} {
+    clock format -2913708304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/01/1877 12:34:56 die i mensis ix annoque mdccclxxvii xii h xxxiv m lvi s 18 mdccc 01 i  1 i Sep 244 2406864 09 ix  9 09/01/1877 die i mensis ix annoque mdccclxxvii 77 lxxvii 1877}
+test clock-2.90 {conversion of 1877-09-30} {
+    clock format -2911202704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/30/1877 12:34:56 die xxx mensis ix annoque mdccclxxvii xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Sep 273 2406893 09 ix  9 09/30/1877 die xxx mensis ix annoque mdccclxxvii 77 lxxvii 1877}
+test clock-2.91 {conversion of 1877-10-01} {
+    clock format -2911116304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/01/1877 12:34:56 die i mensis x annoque mdccclxxvii xii h xxxiv m lvi s 18 mdccc 01 i  1 i Oct 274 2406894 10 x 10 10/01/1877 die i mensis x annoque mdccclxxvii 77 lxxvii 1877}
+test clock-2.92 {conversion of 1877-10-31} {
+    clock format -2908524304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/31/1877 12:34:56 die xxxi mensis x annoque mdccclxxvii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Oct 304 2406924 10 x 10 10/31/1877 die xxxi mensis x annoque mdccclxxvii 77 lxxvii 1877}
+test clock-2.93 {conversion of 1877-11-01} {
+    clock format -2908437904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/01/1877 12:34:56 die i mensis xi annoque mdccclxxvii xii h xxxiv m lvi s 18 mdccc 01 i  1 i Nov 305 2406925 11 xi 11 11/01/1877 die i mensis xi annoque mdccclxxvii 77 lxxvii 1877}
+test clock-2.94 {conversion of 1877-11-30} {
+    clock format -2905932304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/30/1877 12:34:56 die xxx mensis xi annoque mdccclxxvii xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Nov 334 2406954 11 xi 11 11/30/1877 die xxx mensis xi annoque mdccclxxvii 77 lxxvii 1877}
+test clock-2.95 {conversion of 1877-12-01} {
+    clock format -2905845904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/01/1877 12:34:56 die i mensis xii annoque mdccclxxvii xii h xxxiv m lvi s 18 mdccc 01 i  1 i Dec 335 2406955 12 xii 12 12/01/1877 die i mensis xii annoque mdccclxxvii 77 lxxvii 1877}
+test clock-2.96 {conversion of 1877-12-31} {
+    clock format -2903253904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/31/1877 12:34:56 die xxxi mensis xii annoque mdccclxxvii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Dec 365 2406985 12 xii 12 12/31/1877 die xxxi mensis xii annoque mdccclxxvii 77 lxxvii 1877}
+test clock-2.97 {conversion of 1880-01-01} {
+    clock format -2840095504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/01/1880 12:34:56 die i mensis i annoque mdccclxxx xii h xxxiv m lvi s 18 mdccc 01 i  1 i Jan 001 2407716 01 i  1 01/01/1880 die i mensis i annoque mdccclxxx 80 lxxx 1880}
+test clock-2.98 {conversion of 1880-01-31} {
+    clock format -2837503504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/31/1880 12:34:56 die xxxi mensis i annoque mdccclxxx xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Jan 031 2407746 01 i  1 01/31/1880 die xxxi mensis i annoque mdccclxxx 80 lxxx 1880}
+test clock-2.99 {conversion of 1880-02-01} {
+    clock format -2837417104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/01/1880 12:34:56 die i mensis ii annoque mdccclxxx xii h xxxiv m lvi s 18 mdccc 01 i  1 i Feb 032 2407747 02 ii  2 02/01/1880 die i mensis ii annoque mdccclxxx 80 lxxx 1880}
+test clock-2.100 {conversion of 1880-02-29} {
+    clock format -2834997904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/29/1880 12:34:56 die xxix mensis ii annoque mdccclxxx xii h xxxiv m lvi s 18 mdccc 29 xxix 29 xxix Feb 060 2407775 02 ii  2 02/29/1880 die xxix mensis ii annoque mdccclxxx 80 lxxx 1880}
+test clock-2.101 {conversion of 1880-03-01} {
+    clock format -2834911504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/01/1880 12:34:56 die i mensis iii annoque mdccclxxx xii h xxxiv m lvi s 18 mdccc 01 i  1 i Mar 061 2407776 03 iii  3 03/01/1880 die i mensis iii annoque mdccclxxx 80 lxxx 1880}
+test clock-2.102 {conversion of 1880-03-31} {
+    clock format -2832319504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/31/1880 12:34:56 die xxxi mensis iii annoque mdccclxxx xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Mar 091 2407806 03 iii  3 03/31/1880 die xxxi mensis iii annoque mdccclxxx 80 lxxx 1880}
+test clock-2.103 {conversion of 1880-04-01} {
+    clock format -2832233104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/01/1880 12:34:56 die i mensis iv annoque mdccclxxx xii h xxxiv m lvi s 18 mdccc 01 i  1 i Apr 092 2407807 04 iv  4 04/01/1880 die i mensis iv annoque mdccclxxx 80 lxxx 1880}
+test clock-2.104 {conversion of 1880-04-30} {
+    clock format -2829727504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/30/1880 12:34:56 die xxx mensis iv annoque mdccclxxx xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Apr 121 2407836 04 iv  4 04/30/1880 die xxx mensis iv annoque mdccclxxx 80 lxxx 1880}
+test clock-2.105 {conversion of 1880-05-01} {
+    clock format -2829641104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/01/1880 12:34:56 die i mensis v annoque mdccclxxx xii h xxxiv m lvi s 18 mdccc 01 i  1 i May 122 2407837 05 v  5 05/01/1880 die i mensis v annoque mdccclxxx 80 lxxx 1880}
+test clock-2.106 {conversion of 1880-05-31} {
+    clock format -2827049104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/31/1880 12:34:56 die xxxi mensis v annoque mdccclxxx xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi May 152 2407867 05 v  5 05/31/1880 die xxxi mensis v annoque mdccclxxx 80 lxxx 1880}
+test clock-2.107 {conversion of 1880-06-01} {
+    clock format -2826962704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/01/1880 12:34:56 die i mensis vi annoque mdccclxxx xii h xxxiv m lvi s 18 mdccc 01 i  1 i Jun 153 2407868 06 vi  6 06/01/1880 die i mensis vi annoque mdccclxxx 80 lxxx 1880}
+test clock-2.108 {conversion of 1880-06-30} {
+    clock format -2824457104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/30/1880 12:34:56 die xxx mensis vi annoque mdccclxxx xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Jun 182 2407897 06 vi  6 06/30/1880 die xxx mensis vi annoque mdccclxxx 80 lxxx 1880}
+test clock-2.109 {conversion of 1880-07-01} {
+    clock format -2824370704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/01/1880 12:34:56 die i mensis vii annoque mdccclxxx xii h xxxiv m lvi s 18 mdccc 01 i  1 i Jul 183 2407898 07 vii  7 07/01/1880 die i mensis vii annoque mdccclxxx 80 lxxx 1880}
+test clock-2.110 {conversion of 1880-07-31} {
+    clock format -2821778704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/31/1880 12:34:56 die xxxi mensis vii annoque mdccclxxx xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Jul 213 2407928 07 vii  7 07/31/1880 die xxxi mensis vii annoque mdccclxxx 80 lxxx 1880}
+test clock-2.111 {conversion of 1880-08-01} {
+    clock format -2821692304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/01/1880 12:34:56 die i mensis viii annoque mdccclxxx xii h xxxiv m lvi s 18 mdccc 01 i  1 i Aug 214 2407929 08 viii  8 08/01/1880 die i mensis viii annoque mdccclxxx 80 lxxx 1880}
+test clock-2.112 {conversion of 1880-08-31} {
+    clock format -2819100304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/31/1880 12:34:56 die xxxi mensis viii annoque mdccclxxx xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Aug 244 2407959 08 viii  8 08/31/1880 die xxxi mensis viii annoque mdccclxxx 80 lxxx 1880}
+test clock-2.113 {conversion of 1880-09-01} {
+    clock format -2819013904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/01/1880 12:34:56 die i mensis ix annoque mdccclxxx xii h xxxiv m lvi s 18 mdccc 01 i  1 i Sep 245 2407960 09 ix  9 09/01/1880 die i mensis ix annoque mdccclxxx 80 lxxx 1880}
+test clock-2.114 {conversion of 1880-09-30} {
+    clock format -2816508304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/30/1880 12:34:56 die xxx mensis ix annoque mdccclxxx xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Sep 274 2407989 09 ix  9 09/30/1880 die xxx mensis ix annoque mdccclxxx 80 lxxx 1880}
+test clock-2.115 {conversion of 1880-10-01} {
+    clock format -2816421904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/01/1880 12:34:56 die i mensis x annoque mdccclxxx xii h xxxiv m lvi s 18 mdccc 01 i  1 i Oct 275 2407990 10 x 10 10/01/1880 die i mensis x annoque mdccclxxx 80 lxxx 1880}
+test clock-2.116 {conversion of 1880-10-31} {
+    clock format -2813829904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/31/1880 12:34:56 die xxxi mensis x annoque mdccclxxx xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Oct 305 2408020 10 x 10 10/31/1880 die xxxi mensis x annoque mdccclxxx 80 lxxx 1880}
+test clock-2.117 {conversion of 1880-11-01} {
+    clock format -2813743504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/01/1880 12:34:56 die i mensis xi annoque mdccclxxx xii h xxxiv m lvi s 18 mdccc 01 i  1 i Nov 306 2408021 11 xi 11 11/01/1880 die i mensis xi annoque mdccclxxx 80 lxxx 1880}
+test clock-2.118 {conversion of 1880-11-30} {
+    clock format -2811237904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/30/1880 12:34:56 die xxx mensis xi annoque mdccclxxx xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Nov 335 2408050 11 xi 11 11/30/1880 die xxx mensis xi annoque mdccclxxx 80 lxxx 1880}
+test clock-2.119 {conversion of 1880-12-01} {
+    clock format -2811151504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/01/1880 12:34:56 die i mensis xii annoque mdccclxxx xii h xxxiv m lvi s 18 mdccc 01 i  1 i Dec 336 2408051 12 xii 12 12/01/1880 die i mensis xii annoque mdccclxxx 80 lxxx 1880}
+test clock-2.120 {conversion of 1880-12-31} {
+    clock format -2808559504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/31/1880 12:34:56 die xxxi mensis xii annoque mdccclxxx xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Dec 366 2408081 12 xii 12 12/31/1880 die xxxi mensis xii annoque mdccclxxx 80 lxxx 1880}
+test clock-2.121 {conversion of 1881-01-01} {
+    clock format -2808473104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/01/1881 12:34:56 die i mensis i annoque mdccclxxxi xii h xxxiv m lvi s 18 mdccc 01 i  1 i Jan 001 2408082 01 i  1 01/01/1881 die i mensis i annoque mdccclxxxi 81 lxxxi 1881}
+test clock-2.122 {conversion of 1881-01-31} {
+    clock format -2805881104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/31/1881 12:34:56 die xxxi mensis i annoque mdccclxxxi xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Jan 031 2408112 01 i  1 01/31/1881 die xxxi mensis i annoque mdccclxxxi 81 lxxxi 1881}
+test clock-2.123 {conversion of 1881-02-01} {
+    clock format -2805794704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/01/1881 12:34:56 die i mensis ii annoque mdccclxxxi xii h xxxiv m lvi s 18 mdccc 01 i  1 i Feb 032 2408113 02 ii  2 02/01/1881 die i mensis ii annoque mdccclxxxi 81 lxxxi 1881}
+test clock-2.124 {conversion of 1881-02-28} {
+    clock format -2803461904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/28/1881 12:34:56 die xxviii mensis ii annoque mdccclxxxi xii h xxxiv m lvi s 18 mdccc 28 xxviii 28 xxviii Feb 059 2408140 02 ii  2 02/28/1881 die xxviii mensis ii annoque mdccclxxxi 81 lxxxi 1881}
+test clock-2.125 {conversion of 1881-03-01} {
+    clock format -2803375504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/01/1881 12:34:56 die i mensis iii annoque mdccclxxxi xii h xxxiv m lvi s 18 mdccc 01 i  1 i Mar 060 2408141 03 iii  3 03/01/1881 die i mensis iii annoque mdccclxxxi 81 lxxxi 1881}
+test clock-2.126 {conversion of 1881-03-31} {
+    clock format -2800783504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/31/1881 12:34:56 die xxxi mensis iii annoque mdccclxxxi xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Mar 090 2408171 03 iii  3 03/31/1881 die xxxi mensis iii annoque mdccclxxxi 81 lxxxi 1881}
+test clock-2.127 {conversion of 1881-04-01} {
+    clock format -2800697104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/01/1881 12:34:56 die i mensis iv annoque mdccclxxxi xii h xxxiv m lvi s 18 mdccc 01 i  1 i Apr 091 2408172 04 iv  4 04/01/1881 die i mensis iv annoque mdccclxxxi 81 lxxxi 1881}
+test clock-2.128 {conversion of 1881-04-30} {
+    clock format -2798191504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/30/1881 12:34:56 die xxx mensis iv annoque mdccclxxxi xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Apr 120 2408201 04 iv  4 04/30/1881 die xxx mensis iv annoque mdccclxxxi 81 lxxxi 1881}
+test clock-2.129 {conversion of 1881-05-01} {
+    clock format -2798105104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/01/1881 12:34:56 die i mensis v annoque mdccclxxxi xii h xxxiv m lvi s 18 mdccc 01 i  1 i May 121 2408202 05 v  5 05/01/1881 die i mensis v annoque mdccclxxxi 81 lxxxi 1881}
+test clock-2.130 {conversion of 1881-05-31} {
+    clock format -2795513104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/31/1881 12:34:56 die xxxi mensis v annoque mdccclxxxi xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi May 151 2408232 05 v  5 05/31/1881 die xxxi mensis v annoque mdccclxxxi 81 lxxxi 1881}
+test clock-2.131 {conversion of 1881-06-01} {
+    clock format -2795426704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/01/1881 12:34:56 die i mensis vi annoque mdccclxxxi xii h xxxiv m lvi s 18 mdccc 01 i  1 i Jun 152 2408233 06 vi  6 06/01/1881 die i mensis vi annoque mdccclxxxi 81 lxxxi 1881}
+test clock-2.132 {conversion of 1881-06-30} {
+    clock format -2792921104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/30/1881 12:34:56 die xxx mensis vi annoque mdccclxxxi xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Jun 181 2408262 06 vi  6 06/30/1881 die xxx mensis vi annoque mdccclxxxi 81 lxxxi 1881}
+test clock-2.133 {conversion of 1881-07-01} {
+    clock format -2792834704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/01/1881 12:34:56 die i mensis vii annoque mdccclxxxi xii h xxxiv m lvi s 18 mdccc 01 i  1 i Jul 182 2408263 07 vii  7 07/01/1881 die i mensis vii annoque mdccclxxxi 81 lxxxi 1881}
+test clock-2.134 {conversion of 1881-07-31} {
+    clock format -2790242704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/31/1881 12:34:56 die xxxi mensis vii annoque mdccclxxxi xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Jul 212 2408293 07 vii  7 07/31/1881 die xxxi mensis vii annoque mdccclxxxi 81 lxxxi 1881}
+test clock-2.135 {conversion of 1881-08-01} {
+    clock format -2790156304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/01/1881 12:34:56 die i mensis viii annoque mdccclxxxi xii h xxxiv m lvi s 18 mdccc 01 i  1 i Aug 213 2408294 08 viii  8 08/01/1881 die i mensis viii annoque mdccclxxxi 81 lxxxi 1881}
+test clock-2.136 {conversion of 1881-08-31} {
+    clock format -2787564304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/31/1881 12:34:56 die xxxi mensis viii annoque mdccclxxxi xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Aug 243 2408324 08 viii  8 08/31/1881 die xxxi mensis viii annoque mdccclxxxi 81 lxxxi 1881}
+test clock-2.137 {conversion of 1881-09-01} {
+    clock format -2787477904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/01/1881 12:34:56 die i mensis ix annoque mdccclxxxi xii h xxxiv m lvi s 18 mdccc 01 i  1 i Sep 244 2408325 09 ix  9 09/01/1881 die i mensis ix annoque mdccclxxxi 81 lxxxi 1881}
+test clock-2.138 {conversion of 1881-09-30} {
+    clock format -2784972304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/30/1881 12:34:56 die xxx mensis ix annoque mdccclxxxi xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Sep 273 2408354 09 ix  9 09/30/1881 die xxx mensis ix annoque mdccclxxxi 81 lxxxi 1881}
+test clock-2.139 {conversion of 1881-10-01} {
+    clock format -2784885904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/01/1881 12:34:56 die i mensis x annoque mdccclxxxi xii h xxxiv m lvi s 18 mdccc 01 i  1 i Oct 274 2408355 10 x 10 10/01/1881 die i mensis x annoque mdccclxxxi 81 lxxxi 1881}
+test clock-2.140 {conversion of 1881-10-31} {
+    clock format -2782293904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/31/1881 12:34:56 die xxxi mensis x annoque mdccclxxxi xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Oct 304 2408385 10 x 10 10/31/1881 die xxxi mensis x annoque mdccclxxxi 81 lxxxi 1881}
+test clock-2.141 {conversion of 1881-11-01} {
+    clock format -2782207504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/01/1881 12:34:56 die i mensis xi annoque mdccclxxxi xii h xxxiv m lvi s 18 mdccc 01 i  1 i Nov 305 2408386 11 xi 11 11/01/1881 die i mensis xi annoque mdccclxxxi 81 lxxxi 1881}
+test clock-2.142 {conversion of 1881-11-30} {
+    clock format -2779701904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/30/1881 12:34:56 die xxx mensis xi annoque mdccclxxxi xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Nov 334 2408415 11 xi 11 11/30/1881 die xxx mensis xi annoque mdccclxxxi 81 lxxxi 1881}
+test clock-2.143 {conversion of 1881-12-01} {
+    clock format -2779615504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/01/1881 12:34:56 die i mensis xii annoque mdccclxxxi xii h xxxiv m lvi s 18 mdccc 01 i  1 i Dec 335 2408416 12 xii 12 12/01/1881 die i mensis xii annoque mdccclxxxi 81 lxxxi 1881}
+test clock-2.144 {conversion of 1881-12-31} {
+    clock format -2777023504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/31/1881 12:34:56 die xxxi mensis xii annoque mdccclxxxi xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Dec 365 2408446 12 xii 12 12/31/1881 die xxxi mensis xii annoque mdccclxxxi 81 lxxxi 1881}
+test clock-2.145 {conversion of 1884-01-01} {
+    clock format -2713865104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/01/1884 12:34:56 die i mensis i annoque mdccclxxxiv xii h xxxiv m lvi s 18 mdccc 01 i  1 i Jan 001 2409177 01 i  1 01/01/1884 die i mensis i annoque mdccclxxxiv 84 lxxxiv 1884}
+test clock-2.146 {conversion of 1884-01-31} {
+    clock format -2711273104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/31/1884 12:34:56 die xxxi mensis i annoque mdccclxxxiv xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Jan 031 2409207 01 i  1 01/31/1884 die xxxi mensis i annoque mdccclxxxiv 84 lxxxiv 1884}
+test clock-2.147 {conversion of 1884-02-01} {
+    clock format -2711186704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/01/1884 12:34:56 die i mensis ii annoque mdccclxxxiv xii h xxxiv m lvi s 18 mdccc 01 i  1 i Feb 032 2409208 02 ii  2 02/01/1884 die i mensis ii annoque mdccclxxxiv 84 lxxxiv 1884}
+test clock-2.148 {conversion of 1884-02-29} {
+    clock format -2708767504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/29/1884 12:34:56 die xxix mensis ii annoque mdccclxxxiv xii h xxxiv m lvi s 18 mdccc 29 xxix 29 xxix Feb 060 2409236 02 ii  2 02/29/1884 die xxix mensis ii annoque mdccclxxxiv 84 lxxxiv 1884}
+test clock-2.149 {conversion of 1884-03-01} {
+    clock format -2708681104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/01/1884 12:34:56 die i mensis iii annoque mdccclxxxiv xii h xxxiv m lvi s 18 mdccc 01 i  1 i Mar 061 2409237 03 iii  3 03/01/1884 die i mensis iii annoque mdccclxxxiv 84 lxxxiv 1884}
+test clock-2.150 {conversion of 1884-03-31} {
+    clock format -2706089104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/31/1884 12:34:56 die xxxi mensis iii annoque mdccclxxxiv xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Mar 091 2409267 03 iii  3 03/31/1884 die xxxi mensis iii annoque mdccclxxxiv 84 lxxxiv 1884}
+test clock-2.151 {conversion of 1884-04-01} {
+    clock format -2706002704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/01/1884 12:34:56 die i mensis iv annoque mdccclxxxiv xii h xxxiv m lvi s 18 mdccc 01 i  1 i Apr 092 2409268 04 iv  4 04/01/1884 die i mensis iv annoque mdccclxxxiv 84 lxxxiv 1884}
+test clock-2.152 {conversion of 1884-04-30} {
+    clock format -2703497104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/30/1884 12:34:56 die xxx mensis iv annoque mdccclxxxiv xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Apr 121 2409297 04 iv  4 04/30/1884 die xxx mensis iv annoque mdccclxxxiv 84 lxxxiv 1884}
+test clock-2.153 {conversion of 1884-05-01} {
+    clock format -2703410704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/01/1884 12:34:56 die i mensis v annoque mdccclxxxiv xii h xxxiv m lvi s 18 mdccc 01 i  1 i May 122 2409298 05 v  5 05/01/1884 die i mensis v annoque mdccclxxxiv 84 lxxxiv 1884}
+test clock-2.154 {conversion of 1884-05-31} {
+    clock format -2700818704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/31/1884 12:34:56 die xxxi mensis v annoque mdccclxxxiv xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi May 152 2409328 05 v  5 05/31/1884 die xxxi mensis v annoque mdccclxxxiv 84 lxxxiv 1884}
+test clock-2.155 {conversion of 1884-06-01} {
+    clock format -2700732304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/01/1884 12:34:56 die i mensis vi annoque mdccclxxxiv xii h xxxiv m lvi s 18 mdccc 01 i  1 i Jun 153 2409329 06 vi  6 06/01/1884 die i mensis vi annoque mdccclxxxiv 84 lxxxiv 1884}
+test clock-2.156 {conversion of 1884-06-30} {
+    clock format -2698226704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/30/1884 12:34:56 die xxx mensis vi annoque mdccclxxxiv xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Jun 182 2409358 06 vi  6 06/30/1884 die xxx mensis vi annoque mdccclxxxiv 84 lxxxiv 1884}
+test clock-2.157 {conversion of 1884-07-01} {
+    clock format -2698140304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/01/1884 12:34:56 die i mensis vii annoque mdccclxxxiv xii h xxxiv m lvi s 18 mdccc 01 i  1 i Jul 183 2409359 07 vii  7 07/01/1884 die i mensis vii annoque mdccclxxxiv 84 lxxxiv 1884}
+test clock-2.158 {conversion of 1884-07-31} {
+    clock format -2695548304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/31/1884 12:34:56 die xxxi mensis vii annoque mdccclxxxiv xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Jul 213 2409389 07 vii  7 07/31/1884 die xxxi mensis vii annoque mdccclxxxiv 84 lxxxiv 1884}
+test clock-2.159 {conversion of 1884-08-01} {
+    clock format -2695461904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/01/1884 12:34:56 die i mensis viii annoque mdccclxxxiv xii h xxxiv m lvi s 18 mdccc 01 i  1 i Aug 214 2409390 08 viii  8 08/01/1884 die i mensis viii annoque mdccclxxxiv 84 lxxxiv 1884}
+test clock-2.160 {conversion of 1884-08-31} {
+    clock format -2692869904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/31/1884 12:34:56 die xxxi mensis viii annoque mdccclxxxiv xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Aug 244 2409420 08 viii  8 08/31/1884 die xxxi mensis viii annoque mdccclxxxiv 84 lxxxiv 1884}
+test clock-2.161 {conversion of 1884-09-01} {
+    clock format -2692783504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/01/1884 12:34:56 die i mensis ix annoque mdccclxxxiv xii h xxxiv m lvi s 18 mdccc 01 i  1 i Sep 245 2409421 09 ix  9 09/01/1884 die i mensis ix annoque mdccclxxxiv 84 lxxxiv 1884}
+test clock-2.162 {conversion of 1884-09-30} {
+    clock format -2690277904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/30/1884 12:34:56 die xxx mensis ix annoque mdccclxxxiv xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Sep 274 2409450 09 ix  9 09/30/1884 die xxx mensis ix annoque mdccclxxxiv 84 lxxxiv 1884}
+test clock-2.163 {conversion of 1884-10-01} {
+    clock format -2690191504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/01/1884 12:34:56 die i mensis x annoque mdccclxxxiv xii h xxxiv m lvi s 18 mdccc 01 i  1 i Oct 275 2409451 10 x 10 10/01/1884 die i mensis x annoque mdccclxxxiv 84 lxxxiv 1884}
+test clock-2.164 {conversion of 1884-10-31} {
+    clock format -2687599504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/31/1884 12:34:56 die xxxi mensis x annoque mdccclxxxiv xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Oct 305 2409481 10 x 10 10/31/1884 die xxxi mensis x annoque mdccclxxxiv 84 lxxxiv 1884}
+test clock-2.165 {conversion of 1884-11-01} {
+    clock format -2687513104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/01/1884 12:34:56 die i mensis xi annoque mdccclxxxiv xii h xxxiv m lvi s 18 mdccc 01 i  1 i Nov 306 2409482 11 xi 11 11/01/1884 die i mensis xi annoque mdccclxxxiv 84 lxxxiv 1884}
+test clock-2.166 {conversion of 1884-11-30} {
+    clock format -2685007504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/30/1884 12:34:56 die xxx mensis xi annoque mdccclxxxiv xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Nov 335 2409511 11 xi 11 11/30/1884 die xxx mensis xi annoque mdccclxxxiv 84 lxxxiv 1884}
+test clock-2.167 {conversion of 1884-12-01} {
+    clock format -2684921104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/01/1884 12:34:56 die i mensis xii annoque mdccclxxxiv xii h xxxiv m lvi s 18 mdccc 01 i  1 i Dec 336 2409512 12 xii 12 12/01/1884 die i mensis xii annoque mdccclxxxiv 84 lxxxiv 1884}
+test clock-2.168 {conversion of 1884-12-31} {
+    clock format -2682329104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/31/1884 12:34:56 die xxxi mensis xii annoque mdccclxxxiv xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Dec 366 2409542 12 xii 12 12/31/1884 die xxxi mensis xii annoque mdccclxxxiv 84 lxxxiv 1884}
+test clock-2.169 {conversion of 1885-01-01} {
+    clock format -2682242704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/01/1885 12:34:56 die i mensis i annoque mdccclxxxv xii h xxxiv m lvi s 18 mdccc 01 i  1 i Jan 001 2409543 01 i  1 01/01/1885 die i mensis i annoque mdccclxxxv 85 lxxxv 1885}
+test clock-2.170 {conversion of 1885-01-31} {
+    clock format -2679650704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/31/1885 12:34:56 die xxxi mensis i annoque mdccclxxxv xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Jan 031 2409573 01 i  1 01/31/1885 die xxxi mensis i annoque mdccclxxxv 85 lxxxv 1885}
+test clock-2.171 {conversion of 1885-02-01} {
+    clock format -2679564304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/01/1885 12:34:56 die i mensis ii annoque mdccclxxxv xii h xxxiv m lvi s 18 mdccc 01 i  1 i Feb 032 2409574 02 ii  2 02/01/1885 die i mensis ii annoque mdccclxxxv 85 lxxxv 1885}
+test clock-2.172 {conversion of 1885-02-28} {
+    clock format -2677231504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/28/1885 12:34:56 die xxviii mensis ii annoque mdccclxxxv xii h xxxiv m lvi s 18 mdccc 28 xxviii 28 xxviii Feb 059 2409601 02 ii  2 02/28/1885 die xxviii mensis ii annoque mdccclxxxv 85 lxxxv 1885}
+test clock-2.173 {conversion of 1885-03-01} {
+    clock format -2677145104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/01/1885 12:34:56 die i mensis iii annoque mdccclxxxv xii h xxxiv m lvi s 18 mdccc 01 i  1 i Mar 060 2409602 03 iii  3 03/01/1885 die i mensis iii annoque mdccclxxxv 85 lxxxv 1885}
+test clock-2.174 {conversion of 1885-03-31} {
+    clock format -2674553104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/31/1885 12:34:56 die xxxi mensis iii annoque mdccclxxxv xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Mar 090 2409632 03 iii  3 03/31/1885 die xxxi mensis iii annoque mdccclxxxv 85 lxxxv 1885}
+test clock-2.175 {conversion of 1885-04-01} {
+    clock format -2674466704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/01/1885 12:34:56 die i mensis iv annoque mdccclxxxv xii h xxxiv m lvi s 18 mdccc 01 i  1 i Apr 091 2409633 04 iv  4 04/01/1885 die i mensis iv annoque mdccclxxxv 85 lxxxv 1885}
+test clock-2.176 {conversion of 1885-04-30} {
+    clock format -2671961104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/30/1885 12:34:56 die xxx mensis iv annoque mdccclxxxv xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Apr 120 2409662 04 iv  4 04/30/1885 die xxx mensis iv annoque mdccclxxxv 85 lxxxv 1885}
+test clock-2.177 {conversion of 1885-05-01} {
+    clock format -2671874704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/01/1885 12:34:56 die i mensis v annoque mdccclxxxv xii h xxxiv m lvi s 18 mdccc 01 i  1 i May 121 2409663 05 v  5 05/01/1885 die i mensis v annoque mdccclxxxv 85 lxxxv 1885}
+test clock-2.178 {conversion of 1885-05-31} {
+    clock format -2669282704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/31/1885 12:34:56 die xxxi mensis v annoque mdccclxxxv xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi May 151 2409693 05 v  5 05/31/1885 die xxxi mensis v annoque mdccclxxxv 85 lxxxv 1885}
+test clock-2.179 {conversion of 1885-06-01} {
+    clock format -2669196304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/01/1885 12:34:56 die i mensis vi annoque mdccclxxxv xii h xxxiv m lvi s 18 mdccc 01 i  1 i Jun 152 2409694 06 vi  6 06/01/1885 die i mensis vi annoque mdccclxxxv 85 lxxxv 1885}
+test clock-2.180 {conversion of 1885-06-30} {
+    clock format -2666690704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/30/1885 12:34:56 die xxx mensis vi annoque mdccclxxxv xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Jun 181 2409723 06 vi  6 06/30/1885 die xxx mensis vi annoque mdccclxxxv 85 lxxxv 1885}
+test clock-2.181 {conversion of 1885-07-01} {
+    clock format -2666604304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/01/1885 12:34:56 die i mensis vii annoque mdccclxxxv xii h xxxiv m lvi s 18 mdccc 01 i  1 i Jul 182 2409724 07 vii  7 07/01/1885 die i mensis vii annoque mdccclxxxv 85 lxxxv 1885}
+test clock-2.182 {conversion of 1885-07-31} {
+    clock format -2664012304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/31/1885 12:34:56 die xxxi mensis vii annoque mdccclxxxv xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Jul 212 2409754 07 vii  7 07/31/1885 die xxxi mensis vii annoque mdccclxxxv 85 lxxxv 1885}
+test clock-2.183 {conversion of 1885-08-01} {
+    clock format -2663925904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/01/1885 12:34:56 die i mensis viii annoque mdccclxxxv xii h xxxiv m lvi s 18 mdccc 01 i  1 i Aug 213 2409755 08 viii  8 08/01/1885 die i mensis viii annoque mdccclxxxv 85 lxxxv 1885}
+test clock-2.184 {conversion of 1885-08-31} {
+    clock format -2661333904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/31/1885 12:34:56 die xxxi mensis viii annoque mdccclxxxv xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Aug 243 2409785 08 viii  8 08/31/1885 die xxxi mensis viii annoque mdccclxxxv 85 lxxxv 1885}
+test clock-2.185 {conversion of 1885-09-01} {
+    clock format -2661247504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/01/1885 12:34:56 die i mensis ix annoque mdccclxxxv xii h xxxiv m lvi s 18 mdccc 01 i  1 i Sep 244 2409786 09 ix  9 09/01/1885 die i mensis ix annoque mdccclxxxv 85 lxxxv 1885}
+test clock-2.186 {conversion of 1885-09-30} {
+    clock format -2658741904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/30/1885 12:34:56 die xxx mensis ix annoque mdccclxxxv xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Sep 273 2409815 09 ix  9 09/30/1885 die xxx mensis ix annoque mdccclxxxv 85 lxxxv 1885}
+test clock-2.187 {conversion of 1885-10-01} {
+    clock format -2658655504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/01/1885 12:34:56 die i mensis x annoque mdccclxxxv xii h xxxiv m lvi s 18 mdccc 01 i  1 i Oct 274 2409816 10 x 10 10/01/1885 die i mensis x annoque mdccclxxxv 85 lxxxv 1885}
+test clock-2.188 {conversion of 1885-10-31} {
+    clock format -2656063504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/31/1885 12:34:56 die xxxi mensis x annoque mdccclxxxv xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Oct 304 2409846 10 x 10 10/31/1885 die xxxi mensis x annoque mdccclxxxv 85 lxxxv 1885}
+test clock-2.189 {conversion of 1885-11-01} {
+    clock format -2655977104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/01/1885 12:34:56 die i mensis xi annoque mdccclxxxv xii h xxxiv m lvi s 18 mdccc 01 i  1 i Nov 305 2409847 11 xi 11 11/01/1885 die i mensis xi annoque mdccclxxxv 85 lxxxv 1885}
+test clock-2.190 {conversion of 1885-11-30} {
+    clock format -2653471504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/30/1885 12:34:56 die xxx mensis xi annoque mdccclxxxv xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Nov 334 2409876 11 xi 11 11/30/1885 die xxx mensis xi annoque mdccclxxxv 85 lxxxv 1885}
+test clock-2.191 {conversion of 1885-12-01} {
+    clock format -2653385104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/01/1885 12:34:56 die i mensis xii annoque mdccclxxxv xii h xxxiv m lvi s 18 mdccc 01 i  1 i Dec 335 2409877 12 xii 12 12/01/1885 die i mensis xii annoque mdccclxxxv 85 lxxxv 1885}
+test clock-2.192 {conversion of 1885-12-31} {
+    clock format -2650793104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/31/1885 12:34:56 die xxxi mensis xii annoque mdccclxxxv xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Dec 365 2409907 12 xii 12 12/31/1885 die xxxi mensis xii annoque mdccclxxxv 85 lxxxv 1885}
+test clock-2.193 {conversion of 1888-01-01} {
+    clock format -2587634704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/01/1888 12:34:56 die i mensis i annoque mdccclxxxviii xii h xxxiv m lvi s 18 mdccc 01 i  1 i Jan 001 2410638 01 i  1 01/01/1888 die i mensis i annoque mdccclxxxviii 88 lxxxviii 1888}
+test clock-2.194 {conversion of 1888-01-31} {
+    clock format -2585042704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/31/1888 12:34:56 die xxxi mensis i annoque mdccclxxxviii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Jan 031 2410668 01 i  1 01/31/1888 die xxxi mensis i annoque mdccclxxxviii 88 lxxxviii 1888}
+test clock-2.195 {conversion of 1888-02-01} {
+    clock format -2584956304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/01/1888 12:34:56 die i mensis ii annoque mdccclxxxviii xii h xxxiv m lvi s 18 mdccc 01 i  1 i Feb 032 2410669 02 ii  2 02/01/1888 die i mensis ii annoque mdccclxxxviii 88 lxxxviii 1888}
+test clock-2.196 {conversion of 1888-02-29} {
+    clock format -2582537104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/29/1888 12:34:56 die xxix mensis ii annoque mdccclxxxviii xii h xxxiv m lvi s 18 mdccc 29 xxix 29 xxix Feb 060 2410697 02 ii  2 02/29/1888 die xxix mensis ii annoque mdccclxxxviii 88 lxxxviii 1888}
+test clock-2.197 {conversion of 1888-03-01} {
+    clock format -2582450704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/01/1888 12:34:56 die i mensis iii annoque mdccclxxxviii xii h xxxiv m lvi s 18 mdccc 01 i  1 i Mar 061 2410698 03 iii  3 03/01/1888 die i mensis iii annoque mdccclxxxviii 88 lxxxviii 1888}
+test clock-2.198 {conversion of 1888-03-31} {
+    clock format -2579858704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/31/1888 12:34:56 die xxxi mensis iii annoque mdccclxxxviii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Mar 091 2410728 03 iii  3 03/31/1888 die xxxi mensis iii annoque mdccclxxxviii 88 lxxxviii 1888}
+test clock-2.199 {conversion of 1888-04-01} {
+    clock format -2579772304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/01/1888 12:34:56 die i mensis iv annoque mdccclxxxviii xii h xxxiv m lvi s 18 mdccc 01 i  1 i Apr 092 2410729 04 iv  4 04/01/1888 die i mensis iv annoque mdccclxxxviii 88 lxxxviii 1888}
+test clock-2.200 {conversion of 1888-04-30} {
+    clock format -2577266704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/30/1888 12:34:56 die xxx mensis iv annoque mdccclxxxviii xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Apr 121 2410758 04 iv  4 04/30/1888 die xxx mensis iv annoque mdccclxxxviii 88 lxxxviii 1888}
+test clock-2.201 {conversion of 1888-05-01} {
+    clock format -2577180304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/01/1888 12:34:56 die i mensis v annoque mdccclxxxviii xii h xxxiv m lvi s 18 mdccc 01 i  1 i May 122 2410759 05 v  5 05/01/1888 die i mensis v annoque mdccclxxxviii 88 lxxxviii 1888}
+test clock-2.202 {conversion of 1888-05-31} {
+    clock format -2574588304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/31/1888 12:34:56 die xxxi mensis v annoque mdccclxxxviii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi May 152 2410789 05 v  5 05/31/1888 die xxxi mensis v annoque mdccclxxxviii 88 lxxxviii 1888}
+test clock-2.203 {conversion of 1888-06-01} {
+    clock format -2574501904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/01/1888 12:34:56 die i mensis vi annoque mdccclxxxviii xii h xxxiv m lvi s 18 mdccc 01 i  1 i Jun 153 2410790 06 vi  6 06/01/1888 die i mensis vi annoque mdccclxxxviii 88 lxxxviii 1888}
+test clock-2.204 {conversion of 1888-06-30} {
+    clock format -2571996304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/30/1888 12:34:56 die xxx mensis vi annoque mdccclxxxviii xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Jun 182 2410819 06 vi  6 06/30/1888 die xxx mensis vi annoque mdccclxxxviii 88 lxxxviii 1888}
+test clock-2.205 {conversion of 1888-07-01} {
+    clock format -2571909904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/01/1888 12:34:56 die i mensis vii annoque mdccclxxxviii xii h xxxiv m lvi s 18 mdccc 01 i  1 i Jul 183 2410820 07 vii  7 07/01/1888 die i mensis vii annoque mdccclxxxviii 88 lxxxviii 1888}
+test clock-2.206 {conversion of 1888-07-31} {
+    clock format -2569317904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/31/1888 12:34:56 die xxxi mensis vii annoque mdccclxxxviii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Jul 213 2410850 07 vii  7 07/31/1888 die xxxi mensis vii annoque mdccclxxxviii 88 lxxxviii 1888}
+test clock-2.207 {conversion of 1888-08-01} {
+    clock format -2569231504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/01/1888 12:34:56 die i mensis viii annoque mdccclxxxviii xii h xxxiv m lvi s 18 mdccc 01 i  1 i Aug 214 2410851 08 viii  8 08/01/1888 die i mensis viii annoque mdccclxxxviii 88 lxxxviii 1888}
+test clock-2.208 {conversion of 1888-08-31} {
+    clock format -2566639504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/31/1888 12:34:56 die xxxi mensis viii annoque mdccclxxxviii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Aug 244 2410881 08 viii  8 08/31/1888 die xxxi mensis viii annoque mdccclxxxviii 88 lxxxviii 1888}
+test clock-2.209 {conversion of 1888-09-01} {
+    clock format -2566553104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/01/1888 12:34:56 die i mensis ix annoque mdccclxxxviii xii h xxxiv m lvi s 18 mdccc 01 i  1 i Sep 245 2410882 09 ix  9 09/01/1888 die i mensis ix annoque mdccclxxxviii 88 lxxxviii 1888}
+test clock-2.210 {conversion of 1888-09-30} {
+    clock format -2564047504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/30/1888 12:34:56 die xxx mensis ix annoque mdccclxxxviii xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Sep 274 2410911 09 ix  9 09/30/1888 die xxx mensis ix annoque mdccclxxxviii 88 lxxxviii 1888}
+test clock-2.211 {conversion of 1888-10-01} {
+    clock format -2563961104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/01/1888 12:34:56 die i mensis x annoque mdccclxxxviii xii h xxxiv m lvi s 18 mdccc 01 i  1 i Oct 275 2410912 10 x 10 10/01/1888 die i mensis x annoque mdccclxxxviii 88 lxxxviii 1888}
+test clock-2.212 {conversion of 1888-10-31} {
+    clock format -2561369104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/31/1888 12:34:56 die xxxi mensis x annoque mdccclxxxviii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Oct 305 2410942 10 x 10 10/31/1888 die xxxi mensis x annoque mdccclxxxviii 88 lxxxviii 1888}
+test clock-2.213 {conversion of 1888-11-01} {
+    clock format -2561282704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/01/1888 12:34:56 die i mensis xi annoque mdccclxxxviii xii h xxxiv m lvi s 18 mdccc 01 i  1 i Nov 306 2410943 11 xi 11 11/01/1888 die i mensis xi annoque mdccclxxxviii 88 lxxxviii 1888}
+test clock-2.214 {conversion of 1888-11-30} {
+    clock format -2558777104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/30/1888 12:34:56 die xxx mensis xi annoque mdccclxxxviii xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Nov 335 2410972 11 xi 11 11/30/1888 die xxx mensis xi annoque mdccclxxxviii 88 lxxxviii 1888}
+test clock-2.215 {conversion of 1888-12-01} {
+    clock format -2558690704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/01/1888 12:34:56 die i mensis xii annoque mdccclxxxviii xii h xxxiv m lvi s 18 mdccc 01 i  1 i Dec 336 2410973 12 xii 12 12/01/1888 die i mensis xii annoque mdccclxxxviii 88 lxxxviii 1888}
+test clock-2.216 {conversion of 1888-12-31} {
+    clock format -2556098704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/31/1888 12:34:56 die xxxi mensis xii annoque mdccclxxxviii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Dec 366 2411003 12 xii 12 12/31/1888 die xxxi mensis xii annoque mdccclxxxviii 88 lxxxviii 1888}
+test clock-2.217 {conversion of 1889-01-01} {
+    clock format -2556012304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/01/1889 12:34:56 die i mensis i annoque mdccclxxxix xii h xxxiv m lvi s 18 mdccc 01 i  1 i Jan 001 2411004 01 i  1 01/01/1889 die i mensis i annoque mdccclxxxix 89 lxxxix 1889}
+test clock-2.218 {conversion of 1889-01-31} {
+    clock format -2553420304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/31/1889 12:34:56 die xxxi mensis i annoque mdccclxxxix xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Jan 031 2411034 01 i  1 01/31/1889 die xxxi mensis i annoque mdccclxxxix 89 lxxxix 1889}
+test clock-2.219 {conversion of 1889-02-01} {
+    clock format -2553333904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/01/1889 12:34:56 die i mensis ii annoque mdccclxxxix xii h xxxiv m lvi s 18 mdccc 01 i  1 i Feb 032 2411035 02 ii  2 02/01/1889 die i mensis ii annoque mdccclxxxix 89 lxxxix 1889}
+test clock-2.220 {conversion of 1889-02-28} {
+    clock format -2551001104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/28/1889 12:34:56 die xxviii mensis ii annoque mdccclxxxix xii h xxxiv m lvi s 18 mdccc 28 xxviii 28 xxviii Feb 059 2411062 02 ii  2 02/28/1889 die xxviii mensis ii annoque mdccclxxxix 89 lxxxix 1889}
+test clock-2.221 {conversion of 1889-03-01} {
+    clock format -2550914704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/01/1889 12:34:56 die i mensis iii annoque mdccclxxxix xii h xxxiv m lvi s 18 mdccc 01 i  1 i Mar 060 2411063 03 iii  3 03/01/1889 die i mensis iii annoque mdccclxxxix 89 lxxxix 1889}
+test clock-2.222 {conversion of 1889-03-31} {
+    clock format -2548322704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/31/1889 12:34:56 die xxxi mensis iii annoque mdccclxxxix xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Mar 090 2411093 03 iii  3 03/31/1889 die xxxi mensis iii annoque mdccclxxxix 89 lxxxix 1889}
+test clock-2.223 {conversion of 1889-04-01} {
+    clock format -2548236304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/01/1889 12:34:56 die i mensis iv annoque mdccclxxxix xii h xxxiv m lvi s 18 mdccc 01 i  1 i Apr 091 2411094 04 iv  4 04/01/1889 die i mensis iv annoque mdccclxxxix 89 lxxxix 1889}
+test clock-2.224 {conversion of 1889-04-30} {
+    clock format -2545730704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/30/1889 12:34:56 die xxx mensis iv annoque mdccclxxxix xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Apr 120 2411123 04 iv  4 04/30/1889 die xxx mensis iv annoque mdccclxxxix 89 lxxxix 1889}
+test clock-2.225 {conversion of 1889-05-01} {
+    clock format -2545644304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/01/1889 12:34:56 die i mensis v annoque mdccclxxxix xii h xxxiv m lvi s 18 mdccc 01 i  1 i May 121 2411124 05 v  5 05/01/1889 die i mensis v annoque mdccclxxxix 89 lxxxix 1889}
+test clock-2.226 {conversion of 1889-05-31} {
+    clock format -2543052304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/31/1889 12:34:56 die xxxi mensis v annoque mdccclxxxix xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi May 151 2411154 05 v  5 05/31/1889 die xxxi mensis v annoque mdccclxxxix 89 lxxxix 1889}
+test clock-2.227 {conversion of 1889-06-01} {
+    clock format -2542965904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/01/1889 12:34:56 die i mensis vi annoque mdccclxxxix xii h xxxiv m lvi s 18 mdccc 01 i  1 i Jun 152 2411155 06 vi  6 06/01/1889 die i mensis vi annoque mdccclxxxix 89 lxxxix 1889}
+test clock-2.228 {conversion of 1889-06-30} {
+    clock format -2540460304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/30/1889 12:34:56 die xxx mensis vi annoque mdccclxxxix xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Jun 181 2411184 06 vi  6 06/30/1889 die xxx mensis vi annoque mdccclxxxix 89 lxxxix 1889}
+test clock-2.229 {conversion of 1889-07-01} {
+    clock format -2540373904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/01/1889 12:34:56 die i mensis vii annoque mdccclxxxix xii h xxxiv m lvi s 18 mdccc 01 i  1 i Jul 182 2411185 07 vii  7 07/01/1889 die i mensis vii annoque mdccclxxxix 89 lxxxix 1889}
+test clock-2.230 {conversion of 1889-07-31} {
+    clock format -2537781904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/31/1889 12:34:56 die xxxi mensis vii annoque mdccclxxxix xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Jul 212 2411215 07 vii  7 07/31/1889 die xxxi mensis vii annoque mdccclxxxix 89 lxxxix 1889}
+test clock-2.231 {conversion of 1889-08-01} {
+    clock format -2537695504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/01/1889 12:34:56 die i mensis viii annoque mdccclxxxix xii h xxxiv m lvi s 18 mdccc 01 i  1 i Aug 213 2411216 08 viii  8 08/01/1889 die i mensis viii annoque mdccclxxxix 89 lxxxix 1889}
+test clock-2.232 {conversion of 1889-08-31} {
+    clock format -2535103504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/31/1889 12:34:56 die xxxi mensis viii annoque mdccclxxxix xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Aug 243 2411246 08 viii  8 08/31/1889 die xxxi mensis viii annoque mdccclxxxix 89 lxxxix 1889}
+test clock-2.233 {conversion of 1889-09-01} {
+    clock format -2535017104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/01/1889 12:34:56 die i mensis ix annoque mdccclxxxix xii h xxxiv m lvi s 18 mdccc 01 i  1 i Sep 244 2411247 09 ix  9 09/01/1889 die i mensis ix annoque mdccclxxxix 89 lxxxix 1889}
+test clock-2.234 {conversion of 1889-09-30} {
+    clock format -2532511504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/30/1889 12:34:56 die xxx mensis ix annoque mdccclxxxix xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Sep 273 2411276 09 ix  9 09/30/1889 die xxx mensis ix annoque mdccclxxxix 89 lxxxix 1889}
+test clock-2.235 {conversion of 1889-10-01} {
+    clock format -2532425104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/01/1889 12:34:56 die i mensis x annoque mdccclxxxix xii h xxxiv m lvi s 18 mdccc 01 i  1 i Oct 274 2411277 10 x 10 10/01/1889 die i mensis x annoque mdccclxxxix 89 lxxxix 1889}
+test clock-2.236 {conversion of 1889-10-31} {
+    clock format -2529833104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/31/1889 12:34:56 die xxxi mensis x annoque mdccclxxxix xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Oct 304 2411307 10 x 10 10/31/1889 die xxxi mensis x annoque mdccclxxxix 89 lxxxix 1889}
+test clock-2.237 {conversion of 1889-11-01} {
+    clock format -2529746704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/01/1889 12:34:56 die i mensis xi annoque mdccclxxxix xii h xxxiv m lvi s 18 mdccc 01 i  1 i Nov 305 2411308 11 xi 11 11/01/1889 die i mensis xi annoque mdccclxxxix 89 lxxxix 1889}
+test clock-2.238 {conversion of 1889-11-30} {
+    clock format -2527241104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/30/1889 12:34:56 die xxx mensis xi annoque mdccclxxxix xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Nov 334 2411337 11 xi 11 11/30/1889 die xxx mensis xi annoque mdccclxxxix 89 lxxxix 1889}
+test clock-2.239 {conversion of 1889-12-01} {
+    clock format -2527154704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/01/1889 12:34:56 die i mensis xii annoque mdccclxxxix xii h xxxiv m lvi s 18 mdccc 01 i  1 i Dec 335 2411338 12 xii 12 12/01/1889 die i mensis xii annoque mdccclxxxix 89 lxxxix 1889}
+test clock-2.240 {conversion of 1889-12-31} {
+    clock format -2524562704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/31/1889 12:34:56 die xxxi mensis xii annoque mdccclxxxix xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Dec 365 2411368 12 xii 12 12/31/1889 die xxxi mensis xii annoque mdccclxxxix 89 lxxxix 1889}
+test clock-2.241 {conversion of 1890-01-01} {
+    clock format -2524476304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/01/1890 12:34:56 die i mensis i annoque mdcccxc xii h xxxiv m lvi s 18 mdccc 01 i  1 i Jan 001 2411369 01 i  1 01/01/1890 die i mensis i annoque mdcccxc 90 xc 1890}
+test clock-2.242 {conversion of 1890-01-31} {
+    clock format -2521884304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/31/1890 12:34:56 die xxxi mensis i annoque mdcccxc xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Jan 031 2411399 01 i  1 01/31/1890 die xxxi mensis i annoque mdcccxc 90 xc 1890}
+test clock-2.243 {conversion of 1890-02-01} {
+    clock format -2521797904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/01/1890 12:34:56 die i mensis ii annoque mdcccxc xii h xxxiv m lvi s 18 mdccc 01 i  1 i Feb 032 2411400 02 ii  2 02/01/1890 die i mensis ii annoque mdcccxc 90 xc 1890}
+test clock-2.244 {conversion of 1890-02-28} {
+    clock format -2519465104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/28/1890 12:34:56 die xxviii mensis ii annoque mdcccxc xii h xxxiv m lvi s 18 mdccc 28 xxviii 28 xxviii Feb 059 2411427 02 ii  2 02/28/1890 die xxviii mensis ii annoque mdcccxc 90 xc 1890}
+test clock-2.245 {conversion of 1890-03-01} {
+    clock format -2519378704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/01/1890 12:34:56 die i mensis iii annoque mdcccxc xii h xxxiv m lvi s 18 mdccc 01 i  1 i Mar 060 2411428 03 iii  3 03/01/1890 die i mensis iii annoque mdcccxc 90 xc 1890}
+test clock-2.246 {conversion of 1890-03-31} {
+    clock format -2516786704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/31/1890 12:34:56 die xxxi mensis iii annoque mdcccxc xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Mar 090 2411458 03 iii  3 03/31/1890 die xxxi mensis iii annoque mdcccxc 90 xc 1890}
+test clock-2.247 {conversion of 1890-04-01} {
+    clock format -2516700304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/01/1890 12:34:56 die i mensis iv annoque mdcccxc xii h xxxiv m lvi s 18 mdccc 01 i  1 i Apr 091 2411459 04 iv  4 04/01/1890 die i mensis iv annoque mdcccxc 90 xc 1890}
+test clock-2.248 {conversion of 1890-04-30} {
+    clock format -2514194704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/30/1890 12:34:56 die xxx mensis iv annoque mdcccxc xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Apr 120 2411488 04 iv  4 04/30/1890 die xxx mensis iv annoque mdcccxc 90 xc 1890}
+test clock-2.249 {conversion of 1890-05-01} {
+    clock format -2514108304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/01/1890 12:34:56 die i mensis v annoque mdcccxc xii h xxxiv m lvi s 18 mdccc 01 i  1 i May 121 2411489 05 v  5 05/01/1890 die i mensis v annoque mdcccxc 90 xc 1890}
+test clock-2.250 {conversion of 1890-05-31} {
+    clock format -2511516304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/31/1890 12:34:56 die xxxi mensis v annoque mdcccxc xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi May 151 2411519 05 v  5 05/31/1890 die xxxi mensis v annoque mdcccxc 90 xc 1890}
+test clock-2.251 {conversion of 1890-06-01} {
+    clock format -2511429904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/01/1890 12:34:56 die i mensis vi annoque mdcccxc xii h xxxiv m lvi s 18 mdccc 01 i  1 i Jun 152 2411520 06 vi  6 06/01/1890 die i mensis vi annoque mdcccxc 90 xc 1890}
+test clock-2.252 {conversion of 1890-06-30} {
+    clock format -2508924304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/30/1890 12:34:56 die xxx mensis vi annoque mdcccxc xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Jun 181 2411549 06 vi  6 06/30/1890 die xxx mensis vi annoque mdcccxc 90 xc 1890}
+test clock-2.253 {conversion of 1890-07-01} {
+    clock format -2508837904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/01/1890 12:34:56 die i mensis vii annoque mdcccxc xii h xxxiv m lvi s 18 mdccc 01 i  1 i Jul 182 2411550 07 vii  7 07/01/1890 die i mensis vii annoque mdcccxc 90 xc 1890}
+test clock-2.254 {conversion of 1890-07-31} {
+    clock format -2506245904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/31/1890 12:34:56 die xxxi mensis vii annoque mdcccxc xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Jul 212 2411580 07 vii  7 07/31/1890 die xxxi mensis vii annoque mdcccxc 90 xc 1890}
+test clock-2.255 {conversion of 1890-08-01} {
+    clock format -2506159504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/01/1890 12:34:56 die i mensis viii annoque mdcccxc xii h xxxiv m lvi s 18 mdccc 01 i  1 i Aug 213 2411581 08 viii  8 08/01/1890 die i mensis viii annoque mdcccxc 90 xc 1890}
+test clock-2.256 {conversion of 1890-08-31} {
+    clock format -2503567504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/31/1890 12:34:56 die xxxi mensis viii annoque mdcccxc xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Aug 243 2411611 08 viii  8 08/31/1890 die xxxi mensis viii annoque mdcccxc 90 xc 1890}
+test clock-2.257 {conversion of 1890-09-01} {
+    clock format -2503481104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/01/1890 12:34:56 die i mensis ix annoque mdcccxc xii h xxxiv m lvi s 18 mdccc 01 i  1 i Sep 244 2411612 09 ix  9 09/01/1890 die i mensis ix annoque mdcccxc 90 xc 1890}
+test clock-2.258 {conversion of 1890-09-30} {
+    clock format -2500975504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/30/1890 12:34:56 die xxx mensis ix annoque mdcccxc xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Sep 273 2411641 09 ix  9 09/30/1890 die xxx mensis ix annoque mdcccxc 90 xc 1890}
+test clock-2.259 {conversion of 1890-10-01} {
+    clock format -2500889104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/01/1890 12:34:56 die i mensis x annoque mdcccxc xii h xxxiv m lvi s 18 mdccc 01 i  1 i Oct 274 2411642 10 x 10 10/01/1890 die i mensis x annoque mdcccxc 90 xc 1890}
+test clock-2.260 {conversion of 1890-10-31} {
+    clock format -2498297104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/31/1890 12:34:56 die xxxi mensis x annoque mdcccxc xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Oct 304 2411672 10 x 10 10/31/1890 die xxxi mensis x annoque mdcccxc 90 xc 1890}
+test clock-2.261 {conversion of 1890-11-01} {
+    clock format -2498210704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/01/1890 12:34:56 die i mensis xi annoque mdcccxc xii h xxxiv m lvi s 18 mdccc 01 i  1 i Nov 305 2411673 11 xi 11 11/01/1890 die i mensis xi annoque mdcccxc 90 xc 1890}
+test clock-2.262 {conversion of 1890-11-30} {
+    clock format -2495705104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/30/1890 12:34:56 die xxx mensis xi annoque mdcccxc xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Nov 334 2411702 11 xi 11 11/30/1890 die xxx mensis xi annoque mdcccxc 90 xc 1890}
+test clock-2.263 {conversion of 1890-12-01} {
+    clock format -2495618704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/01/1890 12:34:56 die i mensis xii annoque mdcccxc xii h xxxiv m lvi s 18 mdccc 01 i  1 i Dec 335 2411703 12 xii 12 12/01/1890 die i mensis xii annoque mdcccxc 90 xc 1890}
+test clock-2.264 {conversion of 1890-12-31} {
+    clock format -2493026704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/31/1890 12:34:56 die xxxi mensis xii annoque mdcccxc xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Dec 365 2411733 12 xii 12 12/31/1890 die xxxi mensis xii annoque mdcccxc 90 xc 1890}
+test clock-2.265 {conversion of 1891-01-01} {
+    clock format -2492940304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/01/1891 12:34:56 die i mensis i annoque mdcccxci xii h xxxiv m lvi s 18 mdccc 01 i  1 i Jan 001 2411734 01 i  1 01/01/1891 die i mensis i annoque mdcccxci 91 xci 1891}
+test clock-2.266 {conversion of 1891-01-31} {
+    clock format -2490348304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/31/1891 12:34:56 die xxxi mensis i annoque mdcccxci xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Jan 031 2411764 01 i  1 01/31/1891 die xxxi mensis i annoque mdcccxci 91 xci 1891}
+test clock-2.267 {conversion of 1891-02-01} {
+    clock format -2490261904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/01/1891 12:34:56 die i mensis ii annoque mdcccxci xii h xxxiv m lvi s 18 mdccc 01 i  1 i Feb 032 2411765 02 ii  2 02/01/1891 die i mensis ii annoque mdcccxci 91 xci 1891}
+test clock-2.268 {conversion of 1891-02-28} {
+    clock format -2487929104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/28/1891 12:34:56 die xxviii mensis ii annoque mdcccxci xii h xxxiv m lvi s 18 mdccc 28 xxviii 28 xxviii Feb 059 2411792 02 ii  2 02/28/1891 die xxviii mensis ii annoque mdcccxci 91 xci 1891}
+test clock-2.269 {conversion of 1891-03-01} {
+    clock format -2487842704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/01/1891 12:34:56 die i mensis iii annoque mdcccxci xii h xxxiv m lvi s 18 mdccc 01 i  1 i Mar 060 2411793 03 iii  3 03/01/1891 die i mensis iii annoque mdcccxci 91 xci 1891}
+test clock-2.270 {conversion of 1891-03-31} {
+    clock format -2485250704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/31/1891 12:34:56 die xxxi mensis iii annoque mdcccxci xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Mar 090 2411823 03 iii  3 03/31/1891 die xxxi mensis iii annoque mdcccxci 91 xci 1891}
+test clock-2.271 {conversion of 1891-04-01} {
+    clock format -2485164304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/01/1891 12:34:56 die i mensis iv annoque mdcccxci xii h xxxiv m lvi s 18 mdccc 01 i  1 i Apr 091 2411824 04 iv  4 04/01/1891 die i mensis iv annoque mdcccxci 91 xci 1891}
+test clock-2.272 {conversion of 1891-04-30} {
+    clock format -2482658704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/30/1891 12:34:56 die xxx mensis iv annoque mdcccxci xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Apr 120 2411853 04 iv  4 04/30/1891 die xxx mensis iv annoque mdcccxci 91 xci 1891}
+test clock-2.273 {conversion of 1891-05-01} {
+    clock format -2482572304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/01/1891 12:34:56 die i mensis v annoque mdcccxci xii h xxxiv m lvi s 18 mdccc 01 i  1 i May 121 2411854 05 v  5 05/01/1891 die i mensis v annoque mdcccxci 91 xci 1891}
+test clock-2.274 {conversion of 1891-05-31} {
+    clock format -2479980304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/31/1891 12:34:56 die xxxi mensis v annoque mdcccxci xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi May 151 2411884 05 v  5 05/31/1891 die xxxi mensis v annoque mdcccxci 91 xci 1891}
+test clock-2.275 {conversion of 1891-06-01} {
+    clock format -2479893904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/01/1891 12:34:56 die i mensis vi annoque mdcccxci xii h xxxiv m lvi s 18 mdccc 01 i  1 i Jun 152 2411885 06 vi  6 06/01/1891 die i mensis vi annoque mdcccxci 91 xci 1891}
+test clock-2.276 {conversion of 1891-06-30} {
+    clock format -2477388304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/30/1891 12:34:56 die xxx mensis vi annoque mdcccxci xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Jun 181 2411914 06 vi  6 06/30/1891 die xxx mensis vi annoque mdcccxci 91 xci 1891}
+test clock-2.277 {conversion of 1891-07-01} {
+    clock format -2477301904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/01/1891 12:34:56 die i mensis vii annoque mdcccxci xii h xxxiv m lvi s 18 mdccc 01 i  1 i Jul 182 2411915 07 vii  7 07/01/1891 die i mensis vii annoque mdcccxci 91 xci 1891}
+test clock-2.278 {conversion of 1891-07-31} {
+    clock format -2474709904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/31/1891 12:34:56 die xxxi mensis vii annoque mdcccxci xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Jul 212 2411945 07 vii  7 07/31/1891 die xxxi mensis vii annoque mdcccxci 91 xci 1891}
+test clock-2.279 {conversion of 1891-08-01} {
+    clock format -2474623504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/01/1891 12:34:56 die i mensis viii annoque mdcccxci xii h xxxiv m lvi s 18 mdccc 01 i  1 i Aug 213 2411946 08 viii  8 08/01/1891 die i mensis viii annoque mdcccxci 91 xci 1891}
+test clock-2.280 {conversion of 1891-08-31} {
+    clock format -2472031504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/31/1891 12:34:56 die xxxi mensis viii annoque mdcccxci xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Aug 243 2411976 08 viii  8 08/31/1891 die xxxi mensis viii annoque mdcccxci 91 xci 1891}
+test clock-2.281 {conversion of 1891-09-01} {
+    clock format -2471945104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/01/1891 12:34:56 die i mensis ix annoque mdcccxci xii h xxxiv m lvi s 18 mdccc 01 i  1 i Sep 244 2411977 09 ix  9 09/01/1891 die i mensis ix annoque mdcccxci 91 xci 1891}
+test clock-2.282 {conversion of 1891-09-30} {
+    clock format -2469439504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/30/1891 12:34:56 die xxx mensis ix annoque mdcccxci xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Sep 273 2412006 09 ix  9 09/30/1891 die xxx mensis ix annoque mdcccxci 91 xci 1891}
+test clock-2.283 {conversion of 1891-10-01} {
+    clock format -2469353104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/01/1891 12:34:56 die i mensis x annoque mdcccxci xii h xxxiv m lvi s 18 mdccc 01 i  1 i Oct 274 2412007 10 x 10 10/01/1891 die i mensis x annoque mdcccxci 91 xci 1891}
+test clock-2.284 {conversion of 1891-10-31} {
+    clock format -2466761104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/31/1891 12:34:56 die xxxi mensis x annoque mdcccxci xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Oct 304 2412037 10 x 10 10/31/1891 die xxxi mensis x annoque mdcccxci 91 xci 1891}
+test clock-2.285 {conversion of 1891-11-01} {
+    clock format -2466674704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/01/1891 12:34:56 die i mensis xi annoque mdcccxci xii h xxxiv m lvi s 18 mdccc 01 i  1 i Nov 305 2412038 11 xi 11 11/01/1891 die i mensis xi annoque mdcccxci 91 xci 1891}
+test clock-2.286 {conversion of 1891-11-30} {
+    clock format -2464169104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/30/1891 12:34:56 die xxx mensis xi annoque mdcccxci xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Nov 334 2412067 11 xi 11 11/30/1891 die xxx mensis xi annoque mdcccxci 91 xci 1891}
+test clock-2.287 {conversion of 1891-12-01} {
+    clock format -2464082704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/01/1891 12:34:56 die i mensis xii annoque mdcccxci xii h xxxiv m lvi s 18 mdccc 01 i  1 i Dec 335 2412068 12 xii 12 12/01/1891 die i mensis xii annoque mdcccxci 91 xci 1891}
+test clock-2.288 {conversion of 1891-12-31} {
+    clock format -2461490704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/31/1891 12:34:56 die xxxi mensis xii annoque mdcccxci xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Dec 365 2412098 12 xii 12 12/31/1891 die xxxi mensis xii annoque mdcccxci 91 xci 1891}
+test clock-2.289 {conversion of 1892-01-01} {
+    clock format -2461404304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/01/1892 12:34:56 die i mensis i annoque mdcccxcii xii h xxxiv m lvi s 18 mdccc 01 i  1 i Jan 001 2412099 01 i  1 01/01/1892 die i mensis i annoque mdcccxcii 92 xcii 1892}
+test clock-2.290 {conversion of 1892-01-31} {
+    clock format -2458812304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/31/1892 12:34:56 die xxxi mensis i annoque mdcccxcii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Jan 031 2412129 01 i  1 01/31/1892 die xxxi mensis i annoque mdcccxcii 92 xcii 1892}
+test clock-2.291 {conversion of 1892-02-01} {
+    clock format -2458725904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/01/1892 12:34:56 die i mensis ii annoque mdcccxcii xii h xxxiv m lvi s 18 mdccc 01 i  1 i Feb 032 2412130 02 ii  2 02/01/1892 die i mensis ii annoque mdcccxcii 92 xcii 1892}
+test clock-2.292 {conversion of 1892-02-29} {
+    clock format -2456306704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/29/1892 12:34:56 die xxix mensis ii annoque mdcccxcii xii h xxxiv m lvi s 18 mdccc 29 xxix 29 xxix Feb 060 2412158 02 ii  2 02/29/1892 die xxix mensis ii annoque mdcccxcii 92 xcii 1892}
+test clock-2.293 {conversion of 1892-03-01} {
+    clock format -2456220304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/01/1892 12:34:56 die i mensis iii annoque mdcccxcii xii h xxxiv m lvi s 18 mdccc 01 i  1 i Mar 061 2412159 03 iii  3 03/01/1892 die i mensis iii annoque mdcccxcii 92 xcii 1892}
+test clock-2.294 {conversion of 1892-03-31} {
+    clock format -2453628304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/31/1892 12:34:56 die xxxi mensis iii annoque mdcccxcii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Mar 091 2412189 03 iii  3 03/31/1892 die xxxi mensis iii annoque mdcccxcii 92 xcii 1892}
+test clock-2.295 {conversion of 1892-04-01} {
+    clock format -2453541904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/01/1892 12:34:56 die i mensis iv annoque mdcccxcii xii h xxxiv m lvi s 18 mdccc 01 i  1 i Apr 092 2412190 04 iv  4 04/01/1892 die i mensis iv annoque mdcccxcii 92 xcii 1892}
+test clock-2.296 {conversion of 1892-04-30} {
+    clock format -2451036304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/30/1892 12:34:56 die xxx mensis iv annoque mdcccxcii xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Apr 121 2412219 04 iv  4 04/30/1892 die xxx mensis iv annoque mdcccxcii 92 xcii 1892}
+test clock-2.297 {conversion of 1892-05-01} {
+    clock format -2450949904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/01/1892 12:34:56 die i mensis v annoque mdcccxcii xii h xxxiv m lvi s 18 mdccc 01 i  1 i May 122 2412220 05 v  5 05/01/1892 die i mensis v annoque mdcccxcii 92 xcii 1892}
+test clock-2.298 {conversion of 1892-05-31} {
+    clock format -2448357904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/31/1892 12:34:56 die xxxi mensis v annoque mdcccxcii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi May 152 2412250 05 v  5 05/31/1892 die xxxi mensis v annoque mdcccxcii 92 xcii 1892}
+test clock-2.299 {conversion of 1892-06-01} {
+    clock format -2448271504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/01/1892 12:34:56 die i mensis vi annoque mdcccxcii xii h xxxiv m lvi s 18 mdccc 01 i  1 i Jun 153 2412251 06 vi  6 06/01/1892 die i mensis vi annoque mdcccxcii 92 xcii 1892}
+test clock-2.300 {conversion of 1892-06-30} {
+    clock format -2445765904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/30/1892 12:34:56 die xxx mensis vi annoque mdcccxcii xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Jun 182 2412280 06 vi  6 06/30/1892 die xxx mensis vi annoque mdcccxcii 92 xcii 1892}
+test clock-2.301 {conversion of 1892-07-01} {
+    clock format -2445679504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/01/1892 12:34:56 die i mensis vii annoque mdcccxcii xii h xxxiv m lvi s 18 mdccc 01 i  1 i Jul 183 2412281 07 vii  7 07/01/1892 die i mensis vii annoque mdcccxcii 92 xcii 1892}
+test clock-2.302 {conversion of 1892-07-31} {
+    clock format -2443087504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/31/1892 12:34:56 die xxxi mensis vii annoque mdcccxcii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Jul 213 2412311 07 vii  7 07/31/1892 die xxxi mensis vii annoque mdcccxcii 92 xcii 1892}
+test clock-2.303 {conversion of 1892-08-01} {
+    clock format -2443001104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/01/1892 12:34:56 die i mensis viii annoque mdcccxcii xii h xxxiv m lvi s 18 mdccc 01 i  1 i Aug 214 2412312 08 viii  8 08/01/1892 die i mensis viii annoque mdcccxcii 92 xcii 1892}
+test clock-2.304 {conversion of 1892-08-31} {
+    clock format -2440409104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/31/1892 12:34:56 die xxxi mensis viii annoque mdcccxcii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Aug 244 2412342 08 viii  8 08/31/1892 die xxxi mensis viii annoque mdcccxcii 92 xcii 1892}
+test clock-2.305 {conversion of 1892-09-01} {
+    clock format -2440322704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/01/1892 12:34:56 die i mensis ix annoque mdcccxcii xii h xxxiv m lvi s 18 mdccc 01 i  1 i Sep 245 2412343 09 ix  9 09/01/1892 die i mensis ix annoque mdcccxcii 92 xcii 1892}
+test clock-2.306 {conversion of 1892-09-30} {
+    clock format -2437817104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/30/1892 12:34:56 die xxx mensis ix annoque mdcccxcii xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Sep 274 2412372 09 ix  9 09/30/1892 die xxx mensis ix annoque mdcccxcii 92 xcii 1892}
+test clock-2.307 {conversion of 1892-10-01} {
+    clock format -2437730704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/01/1892 12:34:56 die i mensis x annoque mdcccxcii xii h xxxiv m lvi s 18 mdccc 01 i  1 i Oct 275 2412373 10 x 10 10/01/1892 die i mensis x annoque mdcccxcii 92 xcii 1892}
+test clock-2.308 {conversion of 1892-10-31} {
+    clock format -2435138704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/31/1892 12:34:56 die xxxi mensis x annoque mdcccxcii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Oct 305 2412403 10 x 10 10/31/1892 die xxxi mensis x annoque mdcccxcii 92 xcii 1892}
+test clock-2.309 {conversion of 1892-11-01} {
+    clock format -2435052304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/01/1892 12:34:56 die i mensis xi annoque mdcccxcii xii h xxxiv m lvi s 18 mdccc 01 i  1 i Nov 306 2412404 11 xi 11 11/01/1892 die i mensis xi annoque mdcccxcii 92 xcii 1892}
+test clock-2.310 {conversion of 1892-11-30} {
+    clock format -2432546704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/30/1892 12:34:56 die xxx mensis xi annoque mdcccxcii xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Nov 335 2412433 11 xi 11 11/30/1892 die xxx mensis xi annoque mdcccxcii 92 xcii 1892}
+test clock-2.311 {conversion of 1892-12-01} {
+    clock format -2432460304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/01/1892 12:34:56 die i mensis xii annoque mdcccxcii xii h xxxiv m lvi s 18 mdccc 01 i  1 i Dec 336 2412434 12 xii 12 12/01/1892 die i mensis xii annoque mdcccxcii 92 xcii 1892}
+test clock-2.312 {conversion of 1892-12-31} {
+    clock format -2429868304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/31/1892 12:34:56 die xxxi mensis xii annoque mdcccxcii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Dec 366 2412464 12 xii 12 12/31/1892 die xxxi mensis xii annoque mdcccxcii 92 xcii 1892}
+test clock-2.313 {conversion of 1893-01-01} {
+    clock format -2429781904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/01/1893 12:34:56 die i mensis i annoque mdcccxciii xii h xxxiv m lvi s 18 mdccc 01 i  1 i Jan 001 2412465 01 i  1 01/01/1893 die i mensis i annoque mdcccxciii 93 xciii 1893}
+test clock-2.314 {conversion of 1893-01-31} {
+    clock format -2427189904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/31/1893 12:34:56 die xxxi mensis i annoque mdcccxciii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Jan 031 2412495 01 i  1 01/31/1893 die xxxi mensis i annoque mdcccxciii 93 xciii 1893}
+test clock-2.315 {conversion of 1893-02-01} {
+    clock format -2427103504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/01/1893 12:34:56 die i mensis ii annoque mdcccxciii xii h xxxiv m lvi s 18 mdccc 01 i  1 i Feb 032 2412496 02 ii  2 02/01/1893 die i mensis ii annoque mdcccxciii 93 xciii 1893}
+test clock-2.316 {conversion of 1893-02-28} {
+    clock format -2424770704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/28/1893 12:34:56 die xxviii mensis ii annoque mdcccxciii xii h xxxiv m lvi s 18 mdccc 28 xxviii 28 xxviii Feb 059 2412523 02 ii  2 02/28/1893 die xxviii mensis ii annoque mdcccxciii 93 xciii 1893}
+test clock-2.317 {conversion of 1893-03-01} {
+    clock format -2424684304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/01/1893 12:34:56 die i mensis iii annoque mdcccxciii xii h xxxiv m lvi s 18 mdccc 01 i  1 i Mar 060 2412524 03 iii  3 03/01/1893 die i mensis iii annoque mdcccxciii 93 xciii 1893}
+test clock-2.318 {conversion of 1893-03-31} {
+    clock format -2422092304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/31/1893 12:34:56 die xxxi mensis iii annoque mdcccxciii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Mar 090 2412554 03 iii  3 03/31/1893 die xxxi mensis iii annoque mdcccxciii 93 xciii 1893}
+test clock-2.319 {conversion of 1893-04-01} {
+    clock format -2422005904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/01/1893 12:34:56 die i mensis iv annoque mdcccxciii xii h xxxiv m lvi s 18 mdccc 01 i  1 i Apr 091 2412555 04 iv  4 04/01/1893 die i mensis iv annoque mdcccxciii 93 xciii 1893}
+test clock-2.320 {conversion of 1893-04-30} {
+    clock format -2419500304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/30/1893 12:34:56 die xxx mensis iv annoque mdcccxciii xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Apr 120 2412584 04 iv  4 04/30/1893 die xxx mensis iv annoque mdcccxciii 93 xciii 1893}
+test clock-2.321 {conversion of 1893-05-01} {
+    clock format -2419413904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/01/1893 12:34:56 die i mensis v annoque mdcccxciii xii h xxxiv m lvi s 18 mdccc 01 i  1 i May 121 2412585 05 v  5 05/01/1893 die i mensis v annoque mdcccxciii 93 xciii 1893}
+test clock-2.322 {conversion of 1893-05-31} {
+    clock format -2416821904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/31/1893 12:34:56 die xxxi mensis v annoque mdcccxciii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi May 151 2412615 05 v  5 05/31/1893 die xxxi mensis v annoque mdcccxciii 93 xciii 1893}
+test clock-2.323 {conversion of 1893-06-01} {
+    clock format -2416735504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/01/1893 12:34:56 die i mensis vi annoque mdcccxciii xii h xxxiv m lvi s 18 mdccc 01 i  1 i Jun 152 2412616 06 vi  6 06/01/1893 die i mensis vi annoque mdcccxciii 93 xciii 1893}
+test clock-2.324 {conversion of 1893-06-30} {
+    clock format -2414229904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/30/1893 12:34:56 die xxx mensis vi annoque mdcccxciii xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Jun 181 2412645 06 vi  6 06/30/1893 die xxx mensis vi annoque mdcccxciii 93 xciii 1893}
+test clock-2.325 {conversion of 1893-07-01} {
+    clock format -2414143504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/01/1893 12:34:56 die i mensis vii annoque mdcccxciii xii h xxxiv m lvi s 18 mdccc 01 i  1 i Jul 182 2412646 07 vii  7 07/01/1893 die i mensis vii annoque mdcccxciii 93 xciii 1893}
+test clock-2.326 {conversion of 1893-07-31} {
+    clock format -2411551504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/31/1893 12:34:56 die xxxi mensis vii annoque mdcccxciii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Jul 212 2412676 07 vii  7 07/31/1893 die xxxi mensis vii annoque mdcccxciii 93 xciii 1893}
+test clock-2.327 {conversion of 1893-08-01} {
+    clock format -2411465104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/01/1893 12:34:56 die i mensis viii annoque mdcccxciii xii h xxxiv m lvi s 18 mdccc 01 i  1 i Aug 213 2412677 08 viii  8 08/01/1893 die i mensis viii annoque mdcccxciii 93 xciii 1893}
+test clock-2.328 {conversion of 1893-08-31} {
+    clock format -2408873104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/31/1893 12:34:56 die xxxi mensis viii annoque mdcccxciii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Aug 243 2412707 08 viii  8 08/31/1893 die xxxi mensis viii annoque mdcccxciii 93 xciii 1893}
+test clock-2.329 {conversion of 1893-09-01} {
+    clock format -2408786704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/01/1893 12:34:56 die i mensis ix annoque mdcccxciii xii h xxxiv m lvi s 18 mdccc 01 i  1 i Sep 244 2412708 09 ix  9 09/01/1893 die i mensis ix annoque mdcccxciii 93 xciii 1893}
+test clock-2.330 {conversion of 1893-09-30} {
+    clock format -2406281104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/30/1893 12:34:56 die xxx mensis ix annoque mdcccxciii xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Sep 273 2412737 09 ix  9 09/30/1893 die xxx mensis ix annoque mdcccxciii 93 xciii 1893}
+test clock-2.331 {conversion of 1893-10-01} {
+    clock format -2406194704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/01/1893 12:34:56 die i mensis x annoque mdcccxciii xii h xxxiv m lvi s 18 mdccc 01 i  1 i Oct 274 2412738 10 x 10 10/01/1893 die i mensis x annoque mdcccxciii 93 xciii 1893}
+test clock-2.332 {conversion of 1893-10-31} {
+    clock format -2403602704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/31/1893 12:34:56 die xxxi mensis x annoque mdcccxciii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Oct 304 2412768 10 x 10 10/31/1893 die xxxi mensis x annoque mdcccxciii 93 xciii 1893}
+test clock-2.333 {conversion of 1893-11-01} {
+    clock format -2403516304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/01/1893 12:34:56 die i mensis xi annoque mdcccxciii xii h xxxiv m lvi s 18 mdccc 01 i  1 i Nov 305 2412769 11 xi 11 11/01/1893 die i mensis xi annoque mdcccxciii 93 xciii 1893}
+test clock-2.334 {conversion of 1893-11-30} {
+    clock format -2401010704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/30/1893 12:34:56 die xxx mensis xi annoque mdcccxciii xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Nov 334 2412798 11 xi 11 11/30/1893 die xxx mensis xi annoque mdcccxciii 93 xciii 1893}
+test clock-2.335 {conversion of 1893-12-01} {
+    clock format -2400924304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/01/1893 12:34:56 die i mensis xii annoque mdcccxciii xii h xxxiv m lvi s 18 mdccc 01 i  1 i Dec 335 2412799 12 xii 12 12/01/1893 die i mensis xii annoque mdcccxciii 93 xciii 1893}
+test clock-2.336 {conversion of 1893-12-31} {
+    clock format -2398332304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/31/1893 12:34:56 die xxxi mensis xii annoque mdcccxciii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Dec 365 2412829 12 xii 12 12/31/1893 die xxxi mensis xii annoque mdcccxciii 93 xciii 1893}
+test clock-2.337 {conversion of 1894-01-01} {
+    clock format -2398245904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/01/1894 12:34:56 die i mensis i annoque mdcccxciv xii h xxxiv m lvi s 18 mdccc 01 i  1 i Jan 001 2412830 01 i  1 01/01/1894 die i mensis i annoque mdcccxciv 94 xciv 1894}
+test clock-2.338 {conversion of 1894-01-31} {
+    clock format -2395653904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/31/1894 12:34:56 die xxxi mensis i annoque mdcccxciv xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Jan 031 2412860 01 i  1 01/31/1894 die xxxi mensis i annoque mdcccxciv 94 xciv 1894}
+test clock-2.339 {conversion of 1894-02-01} {
+    clock format -2395567504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/01/1894 12:34:56 die i mensis ii annoque mdcccxciv xii h xxxiv m lvi s 18 mdccc 01 i  1 i Feb 032 2412861 02 ii  2 02/01/1894 die i mensis ii annoque mdcccxciv 94 xciv 1894}
+test clock-2.340 {conversion of 1894-02-28} {
+    clock format -2393234704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/28/1894 12:34:56 die xxviii mensis ii annoque mdcccxciv xii h xxxiv m lvi s 18 mdccc 28 xxviii 28 xxviii Feb 059 2412888 02 ii  2 02/28/1894 die xxviii mensis ii annoque mdcccxciv 94 xciv 1894}
+test clock-2.341 {conversion of 1894-03-01} {
+    clock format -2393148304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/01/1894 12:34:56 die i mensis iii annoque mdcccxciv xii h xxxiv m lvi s 18 mdccc 01 i  1 i Mar 060 2412889 03 iii  3 03/01/1894 die i mensis iii annoque mdcccxciv 94 xciv 1894}
+test clock-2.342 {conversion of 1894-03-31} {
+    clock format -2390556304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/31/1894 12:34:56 die xxxi mensis iii annoque mdcccxciv xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Mar 090 2412919 03 iii  3 03/31/1894 die xxxi mensis iii annoque mdcccxciv 94 xciv 1894}
+test clock-2.343 {conversion of 1894-04-01} {
+    clock format -2390469904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/01/1894 12:34:56 die i mensis iv annoque mdcccxciv xii h xxxiv m lvi s 18 mdccc 01 i  1 i Apr 091 2412920 04 iv  4 04/01/1894 die i mensis iv annoque mdcccxciv 94 xciv 1894}
+test clock-2.344 {conversion of 1894-04-30} {
+    clock format -2387964304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/30/1894 12:34:56 die xxx mensis iv annoque mdcccxciv xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Apr 120 2412949 04 iv  4 04/30/1894 die xxx mensis iv annoque mdcccxciv 94 xciv 1894}
+test clock-2.345 {conversion of 1894-05-01} {
+    clock format -2387877904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/01/1894 12:34:56 die i mensis v annoque mdcccxciv xii h xxxiv m lvi s 18 mdccc 01 i  1 i May 121 2412950 05 v  5 05/01/1894 die i mensis v annoque mdcccxciv 94 xciv 1894}
+test clock-2.346 {conversion of 1894-05-31} {
+    clock format -2385285904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/31/1894 12:34:56 die xxxi mensis v annoque mdcccxciv xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi May 151 2412980 05 v  5 05/31/1894 die xxxi mensis v annoque mdcccxciv 94 xciv 1894}
+test clock-2.347 {conversion of 1894-06-01} {
+    clock format -2385199504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/01/1894 12:34:56 die i mensis vi annoque mdcccxciv xii h xxxiv m lvi s 18 mdccc 01 i  1 i Jun 152 2412981 06 vi  6 06/01/1894 die i mensis vi annoque mdcccxciv 94 xciv 1894}
+test clock-2.348 {conversion of 1894-06-30} {
+    clock format -2382693904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/30/1894 12:34:56 die xxx mensis vi annoque mdcccxciv xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Jun 181 2413010 06 vi  6 06/30/1894 die xxx mensis vi annoque mdcccxciv 94 xciv 1894}
+test clock-2.349 {conversion of 1894-07-01} {
+    clock format -2382607504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/01/1894 12:34:56 die i mensis vii annoque mdcccxciv xii h xxxiv m lvi s 18 mdccc 01 i  1 i Jul 182 2413011 07 vii  7 07/01/1894 die i mensis vii annoque mdcccxciv 94 xciv 1894}
+test clock-2.350 {conversion of 1894-07-31} {
+    clock format -2380015504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/31/1894 12:34:56 die xxxi mensis vii annoque mdcccxciv xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Jul 212 2413041 07 vii  7 07/31/1894 die xxxi mensis vii annoque mdcccxciv 94 xciv 1894}
+test clock-2.351 {conversion of 1894-08-01} {
+    clock format -2379929104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/01/1894 12:34:56 die i mensis viii annoque mdcccxciv xii h xxxiv m lvi s 18 mdccc 01 i  1 i Aug 213 2413042 08 viii  8 08/01/1894 die i mensis viii annoque mdcccxciv 94 xciv 1894}
+test clock-2.352 {conversion of 1894-08-31} {
+    clock format -2377337104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/31/1894 12:34:56 die xxxi mensis viii annoque mdcccxciv xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Aug 243 2413072 08 viii  8 08/31/1894 die xxxi mensis viii annoque mdcccxciv 94 xciv 1894}
+test clock-2.353 {conversion of 1894-09-01} {
+    clock format -2377250704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/01/1894 12:34:56 die i mensis ix annoque mdcccxciv xii h xxxiv m lvi s 18 mdccc 01 i  1 i Sep 244 2413073 09 ix  9 09/01/1894 die i mensis ix annoque mdcccxciv 94 xciv 1894}
+test clock-2.354 {conversion of 1894-09-30} {
+    clock format -2374745104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/30/1894 12:34:56 die xxx mensis ix annoque mdcccxciv xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Sep 273 2413102 09 ix  9 09/30/1894 die xxx mensis ix annoque mdcccxciv 94 xciv 1894}
+test clock-2.355 {conversion of 1894-10-01} {
+    clock format -2374658704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/01/1894 12:34:56 die i mensis x annoque mdcccxciv xii h xxxiv m lvi s 18 mdccc 01 i  1 i Oct 274 2413103 10 x 10 10/01/1894 die i mensis x annoque mdcccxciv 94 xciv 1894}
+test clock-2.356 {conversion of 1894-10-31} {
+    clock format -2372066704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/31/1894 12:34:56 die xxxi mensis x annoque mdcccxciv xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Oct 304 2413133 10 x 10 10/31/1894 die xxxi mensis x annoque mdcccxciv 94 xciv 1894}
+test clock-2.357 {conversion of 1894-11-01} {
+    clock format -2371980304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/01/1894 12:34:56 die i mensis xi annoque mdcccxciv xii h xxxiv m lvi s 18 mdccc 01 i  1 i Nov 305 2413134 11 xi 11 11/01/1894 die i mensis xi annoque mdcccxciv 94 xciv 1894}
+test clock-2.358 {conversion of 1894-11-30} {
+    clock format -2369474704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/30/1894 12:34:56 die xxx mensis xi annoque mdcccxciv xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Nov 334 2413163 11 xi 11 11/30/1894 die xxx mensis xi annoque mdcccxciv 94 xciv 1894}
+test clock-2.359 {conversion of 1894-12-01} {
+    clock format -2369388304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/01/1894 12:34:56 die i mensis xii annoque mdcccxciv xii h xxxiv m lvi s 18 mdccc 01 i  1 i Dec 335 2413164 12 xii 12 12/01/1894 die i mensis xii annoque mdcccxciv 94 xciv 1894}
+test clock-2.360 {conversion of 1894-12-31} {
+    clock format -2366796304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/31/1894 12:34:56 die xxxi mensis xii annoque mdcccxciv xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Dec 365 2413194 12 xii 12 12/31/1894 die xxxi mensis xii annoque mdcccxciv 94 xciv 1894}
+test clock-2.361 {conversion of 1895-01-01} {
+    clock format -2366709904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/01/1895 12:34:56 die i mensis i annoque mdcccxcv xii h xxxiv m lvi s 18 mdccc 01 i  1 i Jan 001 2413195 01 i  1 01/01/1895 die i mensis i annoque mdcccxcv 95 xcv 1895}
+test clock-2.362 {conversion of 1895-01-31} {
+    clock format -2364117904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/31/1895 12:34:56 die xxxi mensis i annoque mdcccxcv xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Jan 031 2413225 01 i  1 01/31/1895 die xxxi mensis i annoque mdcccxcv 95 xcv 1895}
+test clock-2.363 {conversion of 1895-02-01} {
+    clock format -2364031504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/01/1895 12:34:56 die i mensis ii annoque mdcccxcv xii h xxxiv m lvi s 18 mdccc 01 i  1 i Feb 032 2413226 02 ii  2 02/01/1895 die i mensis ii annoque mdcccxcv 95 xcv 1895}
+test clock-2.364 {conversion of 1895-02-28} {
+    clock format -2361698704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/28/1895 12:34:56 die xxviii mensis ii annoque mdcccxcv xii h xxxiv m lvi s 18 mdccc 28 xxviii 28 xxviii Feb 059 2413253 02 ii  2 02/28/1895 die xxviii mensis ii annoque mdcccxcv 95 xcv 1895}
+test clock-2.365 {conversion of 1895-03-01} {
+    clock format -2361612304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/01/1895 12:34:56 die i mensis iii annoque mdcccxcv xii h xxxiv m lvi s 18 mdccc 01 i  1 i Mar 060 2413254 03 iii  3 03/01/1895 die i mensis iii annoque mdcccxcv 95 xcv 1895}
+test clock-2.366 {conversion of 1895-03-31} {
+    clock format -2359020304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/31/1895 12:34:56 die xxxi mensis iii annoque mdcccxcv xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Mar 090 2413284 03 iii  3 03/31/1895 die xxxi mensis iii annoque mdcccxcv 95 xcv 1895}
+test clock-2.367 {conversion of 1895-04-01} {
+    clock format -2358933904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/01/1895 12:34:56 die i mensis iv annoque mdcccxcv xii h xxxiv m lvi s 18 mdccc 01 i  1 i Apr 091 2413285 04 iv  4 04/01/1895 die i mensis iv annoque mdcccxcv 95 xcv 1895}
+test clock-2.368 {conversion of 1895-04-30} {
+    clock format -2356428304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/30/1895 12:34:56 die xxx mensis iv annoque mdcccxcv xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Apr 120 2413314 04 iv  4 04/30/1895 die xxx mensis iv annoque mdcccxcv 95 xcv 1895}
+test clock-2.369 {conversion of 1895-05-01} {
+    clock format -2356341904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/01/1895 12:34:56 die i mensis v annoque mdcccxcv xii h xxxiv m lvi s 18 mdccc 01 i  1 i May 121 2413315 05 v  5 05/01/1895 die i mensis v annoque mdcccxcv 95 xcv 1895}
+test clock-2.370 {conversion of 1895-05-31} {
+    clock format -2353749904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/31/1895 12:34:56 die xxxi mensis v annoque mdcccxcv xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi May 151 2413345 05 v  5 05/31/1895 die xxxi mensis v annoque mdcccxcv 95 xcv 1895}
+test clock-2.371 {conversion of 1895-06-01} {
+    clock format -2353663504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/01/1895 12:34:56 die i mensis vi annoque mdcccxcv xii h xxxiv m lvi s 18 mdccc 01 i  1 i Jun 152 2413346 06 vi  6 06/01/1895 die i mensis vi annoque mdcccxcv 95 xcv 1895}
+test clock-2.372 {conversion of 1895-06-30} {
+    clock format -2351157904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/30/1895 12:34:56 die xxx mensis vi annoque mdcccxcv xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Jun 181 2413375 06 vi  6 06/30/1895 die xxx mensis vi annoque mdcccxcv 95 xcv 1895}
+test clock-2.373 {conversion of 1895-07-01} {
+    clock format -2351071504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/01/1895 12:34:56 die i mensis vii annoque mdcccxcv xii h xxxiv m lvi s 18 mdccc 01 i  1 i Jul 182 2413376 07 vii  7 07/01/1895 die i mensis vii annoque mdcccxcv 95 xcv 1895}
+test clock-2.374 {conversion of 1895-07-31} {
+    clock format -2348479504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/31/1895 12:34:56 die xxxi mensis vii annoque mdcccxcv xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Jul 212 2413406 07 vii  7 07/31/1895 die xxxi mensis vii annoque mdcccxcv 95 xcv 1895}
+test clock-2.375 {conversion of 1895-08-01} {
+    clock format -2348393104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/01/1895 12:34:56 die i mensis viii annoque mdcccxcv xii h xxxiv m lvi s 18 mdccc 01 i  1 i Aug 213 2413407 08 viii  8 08/01/1895 die i mensis viii annoque mdcccxcv 95 xcv 1895}
+test clock-2.376 {conversion of 1895-08-31} {
+    clock format -2345801104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/31/1895 12:34:56 die xxxi mensis viii annoque mdcccxcv xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Aug 243 2413437 08 viii  8 08/31/1895 die xxxi mensis viii annoque mdcccxcv 95 xcv 1895}
+test clock-2.377 {conversion of 1895-09-01} {
+    clock format -2345714704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/01/1895 12:34:56 die i mensis ix annoque mdcccxcv xii h xxxiv m lvi s 18 mdccc 01 i  1 i Sep 244 2413438 09 ix  9 09/01/1895 die i mensis ix annoque mdcccxcv 95 xcv 1895}
+test clock-2.378 {conversion of 1895-09-30} {
+    clock format -2343209104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/30/1895 12:34:56 die xxx mensis ix annoque mdcccxcv xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Sep 273 2413467 09 ix  9 09/30/1895 die xxx mensis ix annoque mdcccxcv 95 xcv 1895}
+test clock-2.379 {conversion of 1895-10-01} {
+    clock format -2343122704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/01/1895 12:34:56 die i mensis x annoque mdcccxcv xii h xxxiv m lvi s 18 mdccc 01 i  1 i Oct 274 2413468 10 x 10 10/01/1895 die i mensis x annoque mdcccxcv 95 xcv 1895}
+test clock-2.380 {conversion of 1895-10-31} {
+    clock format -2340530704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/31/1895 12:34:56 die xxxi mensis x annoque mdcccxcv xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Oct 304 2413498 10 x 10 10/31/1895 die xxxi mensis x annoque mdcccxcv 95 xcv 1895}
+test clock-2.381 {conversion of 1895-11-01} {
+    clock format -2340444304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/01/1895 12:34:56 die i mensis xi annoque mdcccxcv xii h xxxiv m lvi s 18 mdccc 01 i  1 i Nov 305 2413499 11 xi 11 11/01/1895 die i mensis xi annoque mdcccxcv 95 xcv 1895}
+test clock-2.382 {conversion of 1895-11-30} {
+    clock format -2337938704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/30/1895 12:34:56 die xxx mensis xi annoque mdcccxcv xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Nov 334 2413528 11 xi 11 11/30/1895 die xxx mensis xi annoque mdcccxcv 95 xcv 1895}
+test clock-2.383 {conversion of 1895-12-01} {
+    clock format -2337852304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/01/1895 12:34:56 die i mensis xii annoque mdcccxcv xii h xxxiv m lvi s 18 mdccc 01 i  1 i Dec 335 2413529 12 xii 12 12/01/1895 die i mensis xii annoque mdcccxcv 95 xcv 1895}
+test clock-2.384 {conversion of 1895-12-31} {
+    clock format -2335260304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/31/1895 12:34:56 die xxxi mensis xii annoque mdcccxcv xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Dec 365 2413559 12 xii 12 12/31/1895 die xxxi mensis xii annoque mdcccxcv 95 xcv 1895}
+test clock-2.385 {conversion of 1896-01-01} {
+    clock format -2335173904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/01/1896 12:34:56 die i mensis i annoque mdcccxcvi xii h xxxiv m lvi s 18 mdccc 01 i  1 i Jan 001 2413560 01 i  1 01/01/1896 die i mensis i annoque mdcccxcvi 96 xcvi 1896}
+test clock-2.386 {conversion of 1896-01-31} {
+    clock format -2332581904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/31/1896 12:34:56 die xxxi mensis i annoque mdcccxcvi xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Jan 031 2413590 01 i  1 01/31/1896 die xxxi mensis i annoque mdcccxcvi 96 xcvi 1896}
+test clock-2.387 {conversion of 1896-02-01} {
+    clock format -2332495504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/01/1896 12:34:56 die i mensis ii annoque mdcccxcvi xii h xxxiv m lvi s 18 mdccc 01 i  1 i Feb 032 2413591 02 ii  2 02/01/1896 die i mensis ii annoque mdcccxcvi 96 xcvi 1896}
+test clock-2.388 {conversion of 1896-02-29} {
+    clock format -2330076304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/29/1896 12:34:56 die xxix mensis ii annoque mdcccxcvi xii h xxxiv m lvi s 18 mdccc 29 xxix 29 xxix Feb 060 2413619 02 ii  2 02/29/1896 die xxix mensis ii annoque mdcccxcvi 96 xcvi 1896}
+test clock-2.389 {conversion of 1896-03-01} {
+    clock format -2329989904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/01/1896 12:34:56 die i mensis iii annoque mdcccxcvi xii h xxxiv m lvi s 18 mdccc 01 i  1 i Mar 061 2413620 03 iii  3 03/01/1896 die i mensis iii annoque mdcccxcvi 96 xcvi 1896}
+test clock-2.390 {conversion of 1896-03-31} {
+    clock format -2327397904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/31/1896 12:34:56 die xxxi mensis iii annoque mdcccxcvi xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Mar 091 2413650 03 iii  3 03/31/1896 die xxxi mensis iii annoque mdcccxcvi 96 xcvi 1896}
+test clock-2.391 {conversion of 1896-04-01} {
+    clock format -2327311504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/01/1896 12:34:56 die i mensis iv annoque mdcccxcvi xii h xxxiv m lvi s 18 mdccc 01 i  1 i Apr 092 2413651 04 iv  4 04/01/1896 die i mensis iv annoque mdcccxcvi 96 xcvi 1896}
+test clock-2.392 {conversion of 1896-04-30} {
+    clock format -2324805904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/30/1896 12:34:56 die xxx mensis iv annoque mdcccxcvi xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Apr 121 2413680 04 iv  4 04/30/1896 die xxx mensis iv annoque mdcccxcvi 96 xcvi 1896}
+test clock-2.393 {conversion of 1896-05-01} {
+    clock format -2324719504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/01/1896 12:34:56 die i mensis v annoque mdcccxcvi xii h xxxiv m lvi s 18 mdccc 01 i  1 i May 122 2413681 05 v  5 05/01/1896 die i mensis v annoque mdcccxcvi 96 xcvi 1896}
+test clock-2.394 {conversion of 1896-05-31} {
+    clock format -2322127504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/31/1896 12:34:56 die xxxi mensis v annoque mdcccxcvi xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi May 152 2413711 05 v  5 05/31/1896 die xxxi mensis v annoque mdcccxcvi 96 xcvi 1896}
+test clock-2.395 {conversion of 1896-06-01} {
+    clock format -2322041104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/01/1896 12:34:56 die i mensis vi annoque mdcccxcvi xii h xxxiv m lvi s 18 mdccc 01 i  1 i Jun 153 2413712 06 vi  6 06/01/1896 die i mensis vi annoque mdcccxcvi 96 xcvi 1896}
+test clock-2.396 {conversion of 1896-06-30} {
+    clock format -2319535504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/30/1896 12:34:56 die xxx mensis vi annoque mdcccxcvi xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Jun 182 2413741 06 vi  6 06/30/1896 die xxx mensis vi annoque mdcccxcvi 96 xcvi 1896}
+test clock-2.397 {conversion of 1896-07-01} {
+    clock format -2319449104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/01/1896 12:34:56 die i mensis vii annoque mdcccxcvi xii h xxxiv m lvi s 18 mdccc 01 i  1 i Jul 183 2413742 07 vii  7 07/01/1896 die i mensis vii annoque mdcccxcvi 96 xcvi 1896}
+test clock-2.398 {conversion of 1896-07-31} {
+    clock format -2316857104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/31/1896 12:34:56 die xxxi mensis vii annoque mdcccxcvi xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Jul 213 2413772 07 vii  7 07/31/1896 die xxxi mensis vii annoque mdcccxcvi 96 xcvi 1896}
+test clock-2.399 {conversion of 1896-08-01} {
+    clock format -2316770704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/01/1896 12:34:56 die i mensis viii annoque mdcccxcvi xii h xxxiv m lvi s 18 mdccc 01 i  1 i Aug 214 2413773 08 viii  8 08/01/1896 die i mensis viii annoque mdcccxcvi 96 xcvi 1896}
+test clock-2.400 {conversion of 1896-08-31} {
+    clock format -2314178704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/31/1896 12:34:56 die xxxi mensis viii annoque mdcccxcvi xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Aug 244 2413803 08 viii  8 08/31/1896 die xxxi mensis viii annoque mdcccxcvi 96 xcvi 1896}
+test clock-2.401 {conversion of 1896-09-01} {
+    clock format -2314092304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/01/1896 12:34:56 die i mensis ix annoque mdcccxcvi xii h xxxiv m lvi s 18 mdccc 01 i  1 i Sep 245 2413804 09 ix  9 09/01/1896 die i mensis ix annoque mdcccxcvi 96 xcvi 1896}
+test clock-2.402 {conversion of 1896-09-30} {
+    clock format -2311586704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/30/1896 12:34:56 die xxx mensis ix annoque mdcccxcvi xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Sep 274 2413833 09 ix  9 09/30/1896 die xxx mensis ix annoque mdcccxcvi 96 xcvi 1896}
+test clock-2.403 {conversion of 1896-10-01} {
+    clock format -2311500304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/01/1896 12:34:56 die i mensis x annoque mdcccxcvi xii h xxxiv m lvi s 18 mdccc 01 i  1 i Oct 275 2413834 10 x 10 10/01/1896 die i mensis x annoque mdcccxcvi 96 xcvi 1896}
+test clock-2.404 {conversion of 1896-10-31} {
+    clock format -2308908304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/31/1896 12:34:56 die xxxi mensis x annoque mdcccxcvi xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Oct 305 2413864 10 x 10 10/31/1896 die xxxi mensis x annoque mdcccxcvi 96 xcvi 1896}
+test clock-2.405 {conversion of 1896-11-01} {
+    clock format -2308821904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/01/1896 12:34:56 die i mensis xi annoque mdcccxcvi xii h xxxiv m lvi s 18 mdccc 01 i  1 i Nov 306 2413865 11 xi 11 11/01/1896 die i mensis xi annoque mdcccxcvi 96 xcvi 1896}
+test clock-2.406 {conversion of 1896-11-30} {
+    clock format -2306316304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/30/1896 12:34:56 die xxx mensis xi annoque mdcccxcvi xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Nov 335 2413894 11 xi 11 11/30/1896 die xxx mensis xi annoque mdcccxcvi 96 xcvi 1896}
+test clock-2.407 {conversion of 1896-12-01} {
+    clock format -2306229904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/01/1896 12:34:56 die i mensis xii annoque mdcccxcvi xii h xxxiv m lvi s 18 mdccc 01 i  1 i Dec 336 2413895 12 xii 12 12/01/1896 die i mensis xii annoque mdcccxcvi 96 xcvi 1896}
+test clock-2.408 {conversion of 1896-12-31} {
+    clock format -2303637904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/31/1896 12:34:56 die xxxi mensis xii annoque mdcccxcvi xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Dec 366 2413925 12 xii 12 12/31/1896 die xxxi mensis xii annoque mdcccxcvi 96 xcvi 1896}
+test clock-2.409 {conversion of 1897-01-01} {
+    clock format -2303551504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/01/1897 12:34:56 die i mensis i annoque mdcccxcvii xii h xxxiv m lvi s 18 mdccc 01 i  1 i Jan 001 2413926 01 i  1 01/01/1897 die i mensis i annoque mdcccxcvii 97 xcvii 1897}
+test clock-2.410 {conversion of 1897-01-31} {
+    clock format -2300959504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/31/1897 12:34:56 die xxxi mensis i annoque mdcccxcvii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Jan 031 2413956 01 i  1 01/31/1897 die xxxi mensis i annoque mdcccxcvii 97 xcvii 1897}
+test clock-2.411 {conversion of 1897-02-01} {
+    clock format -2300873104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/01/1897 12:34:56 die i mensis ii annoque mdcccxcvii xii h xxxiv m lvi s 18 mdccc 01 i  1 i Feb 032 2413957 02 ii  2 02/01/1897 die i mensis ii annoque mdcccxcvii 97 xcvii 1897}
+test clock-2.412 {conversion of 1897-02-28} {
+    clock format -2298540304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/28/1897 12:34:56 die xxviii mensis ii annoque mdcccxcvii xii h xxxiv m lvi s 18 mdccc 28 xxviii 28 xxviii Feb 059 2413984 02 ii  2 02/28/1897 die xxviii mensis ii annoque mdcccxcvii 97 xcvii 1897}
+test clock-2.413 {conversion of 1897-03-01} {
+    clock format -2298453904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/01/1897 12:34:56 die i mensis iii annoque mdcccxcvii xii h xxxiv m lvi s 18 mdccc 01 i  1 i Mar 060 2413985 03 iii  3 03/01/1897 die i mensis iii annoque mdcccxcvii 97 xcvii 1897}
+test clock-2.414 {conversion of 1897-03-31} {
+    clock format -2295861904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/31/1897 12:34:56 die xxxi mensis iii annoque mdcccxcvii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Mar 090 2414015 03 iii  3 03/31/1897 die xxxi mensis iii annoque mdcccxcvii 97 xcvii 1897}
+test clock-2.415 {conversion of 1897-04-01} {
+    clock format -2295775504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/01/1897 12:34:56 die i mensis iv annoque mdcccxcvii xii h xxxiv m lvi s 18 mdccc 01 i  1 i Apr 091 2414016 04 iv  4 04/01/1897 die i mensis iv annoque mdcccxcvii 97 xcvii 1897}
+test clock-2.416 {conversion of 1897-04-30} {
+    clock format -2293269904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/30/1897 12:34:56 die xxx mensis iv annoque mdcccxcvii xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Apr 120 2414045 04 iv  4 04/30/1897 die xxx mensis iv annoque mdcccxcvii 97 xcvii 1897}
+test clock-2.417 {conversion of 1897-05-01} {
+    clock format -2293183504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/01/1897 12:34:56 die i mensis v annoque mdcccxcvii xii h xxxiv m lvi s 18 mdccc 01 i  1 i May 121 2414046 05 v  5 05/01/1897 die i mensis v annoque mdcccxcvii 97 xcvii 1897}
+test clock-2.418 {conversion of 1897-05-31} {
+    clock format -2290591504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/31/1897 12:34:56 die xxxi mensis v annoque mdcccxcvii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi May 151 2414076 05 v  5 05/31/1897 die xxxi mensis v annoque mdcccxcvii 97 xcvii 1897}
+test clock-2.419 {conversion of 1897-06-01} {
+    clock format -2290505104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/01/1897 12:34:56 die i mensis vi annoque mdcccxcvii xii h xxxiv m lvi s 18 mdccc 01 i  1 i Jun 152 2414077 06 vi  6 06/01/1897 die i mensis vi annoque mdcccxcvii 97 xcvii 1897}
+test clock-2.420 {conversion of 1897-06-30} {
+    clock format -2287999504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/30/1897 12:34:56 die xxx mensis vi annoque mdcccxcvii xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Jun 181 2414106 06 vi  6 06/30/1897 die xxx mensis vi annoque mdcccxcvii 97 xcvii 1897}
+test clock-2.421 {conversion of 1897-07-01} {
+    clock format -2287913104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/01/1897 12:34:56 die i mensis vii annoque mdcccxcvii xii h xxxiv m lvi s 18 mdccc 01 i  1 i Jul 182 2414107 07 vii  7 07/01/1897 die i mensis vii annoque mdcccxcvii 97 xcvii 1897}
+test clock-2.422 {conversion of 1897-07-31} {
+    clock format -2285321104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/31/1897 12:34:56 die xxxi mensis vii annoque mdcccxcvii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Jul 212 2414137 07 vii  7 07/31/1897 die xxxi mensis vii annoque mdcccxcvii 97 xcvii 1897}
+test clock-2.423 {conversion of 1897-08-01} {
+    clock format -2285234704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/01/1897 12:34:56 die i mensis viii annoque mdcccxcvii xii h xxxiv m lvi s 18 mdccc 01 i  1 i Aug 213 2414138 08 viii  8 08/01/1897 die i mensis viii annoque mdcccxcvii 97 xcvii 1897}
+test clock-2.424 {conversion of 1897-08-31} {
+    clock format -2282642704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/31/1897 12:34:56 die xxxi mensis viii annoque mdcccxcvii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Aug 243 2414168 08 viii  8 08/31/1897 die xxxi mensis viii annoque mdcccxcvii 97 xcvii 1897}
+test clock-2.425 {conversion of 1897-09-01} {
+    clock format -2282556304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/01/1897 12:34:56 die i mensis ix annoque mdcccxcvii xii h xxxiv m lvi s 18 mdccc 01 i  1 i Sep 244 2414169 09 ix  9 09/01/1897 die i mensis ix annoque mdcccxcvii 97 xcvii 1897}
+test clock-2.426 {conversion of 1897-09-30} {
+    clock format -2280050704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/30/1897 12:34:56 die xxx mensis ix annoque mdcccxcvii xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Sep 273 2414198 09 ix  9 09/30/1897 die xxx mensis ix annoque mdcccxcvii 97 xcvii 1897}
+test clock-2.427 {conversion of 1897-10-01} {
+    clock format -2279964304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/01/1897 12:34:56 die i mensis x annoque mdcccxcvii xii h xxxiv m lvi s 18 mdccc 01 i  1 i Oct 274 2414199 10 x 10 10/01/1897 die i mensis x annoque mdcccxcvii 97 xcvii 1897}
+test clock-2.428 {conversion of 1897-10-31} {
+    clock format -2277372304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/31/1897 12:34:56 die xxxi mensis x annoque mdcccxcvii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Oct 304 2414229 10 x 10 10/31/1897 die xxxi mensis x annoque mdcccxcvii 97 xcvii 1897}
+test clock-2.429 {conversion of 1897-11-01} {
+    clock format -2277285904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/01/1897 12:34:56 die i mensis xi annoque mdcccxcvii xii h xxxiv m lvi s 18 mdccc 01 i  1 i Nov 305 2414230 11 xi 11 11/01/1897 die i mensis xi annoque mdcccxcvii 97 xcvii 1897}
+test clock-2.430 {conversion of 1897-11-30} {
+    clock format -2274780304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/30/1897 12:34:56 die xxx mensis xi annoque mdcccxcvii xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Nov 334 2414259 11 xi 11 11/30/1897 die xxx mensis xi annoque mdcccxcvii 97 xcvii 1897}
+test clock-2.431 {conversion of 1897-12-01} {
+    clock format -2274693904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/01/1897 12:34:56 die i mensis xii annoque mdcccxcvii xii h xxxiv m lvi s 18 mdccc 01 i  1 i Dec 335 2414260 12 xii 12 12/01/1897 die i mensis xii annoque mdcccxcvii 97 xcvii 1897}
+test clock-2.432 {conversion of 1897-12-31} {
+    clock format -2272101904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/31/1897 12:34:56 die xxxi mensis xii annoque mdcccxcvii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Dec 365 2414290 12 xii 12 12/31/1897 die xxxi mensis xii annoque mdcccxcvii 97 xcvii 1897}
+test clock-2.433 {conversion of 1898-01-01} {
+    clock format -2272015504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/01/1898 12:34:56 die i mensis i annoque mdcccxcviii xii h xxxiv m lvi s 18 mdccc 01 i  1 i Jan 001 2414291 01 i  1 01/01/1898 die i mensis i annoque mdcccxcviii 98 xcviii 1898}
+test clock-2.434 {conversion of 1898-01-31} {
+    clock format -2269423504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/31/1898 12:34:56 die xxxi mensis i annoque mdcccxcviii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Jan 031 2414321 01 i  1 01/31/1898 die xxxi mensis i annoque mdcccxcviii 98 xcviii 1898}
+test clock-2.435 {conversion of 1898-02-01} {
+    clock format -2269337104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/01/1898 12:34:56 die i mensis ii annoque mdcccxcviii xii h xxxiv m lvi s 18 mdccc 01 i  1 i Feb 032 2414322 02 ii  2 02/01/1898 die i mensis ii annoque mdcccxcviii 98 xcviii 1898}
+test clock-2.436 {conversion of 1898-02-28} {
+    clock format -2267004304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/28/1898 12:34:56 die xxviii mensis ii annoque mdcccxcviii xii h xxxiv m lvi s 18 mdccc 28 xxviii 28 xxviii Feb 059 2414349 02 ii  2 02/28/1898 die xxviii mensis ii annoque mdcccxcviii 98 xcviii 1898}
+test clock-2.437 {conversion of 1898-03-01} {
+    clock format -2266917904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/01/1898 12:34:56 die i mensis iii annoque mdcccxcviii xii h xxxiv m lvi s 18 mdccc 01 i  1 i Mar 060 2414350 03 iii  3 03/01/1898 die i mensis iii annoque mdcccxcviii 98 xcviii 1898}
+test clock-2.438 {conversion of 1898-03-31} {
+    clock format -2264325904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/31/1898 12:34:56 die xxxi mensis iii annoque mdcccxcviii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Mar 090 2414380 03 iii  3 03/31/1898 die xxxi mensis iii annoque mdcccxcviii 98 xcviii 1898}
+test clock-2.439 {conversion of 1898-04-01} {
+    clock format -2264239504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/01/1898 12:34:56 die i mensis iv annoque mdcccxcviii xii h xxxiv m lvi s 18 mdccc 01 i  1 i Apr 091 2414381 04 iv  4 04/01/1898 die i mensis iv annoque mdcccxcviii 98 xcviii 1898}
+test clock-2.440 {conversion of 1898-04-30} {
+    clock format -2261733904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/30/1898 12:34:56 die xxx mensis iv annoque mdcccxcviii xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Apr 120 2414410 04 iv  4 04/30/1898 die xxx mensis iv annoque mdcccxcviii 98 xcviii 1898}
+test clock-2.441 {conversion of 1898-05-01} {
+    clock format -2261647504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/01/1898 12:34:56 die i mensis v annoque mdcccxcviii xii h xxxiv m lvi s 18 mdccc 01 i  1 i May 121 2414411 05 v  5 05/01/1898 die i mensis v annoque mdcccxcviii 98 xcviii 1898}
+test clock-2.442 {conversion of 1898-05-31} {
+    clock format -2259055504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/31/1898 12:34:56 die xxxi mensis v annoque mdcccxcviii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi May 151 2414441 05 v  5 05/31/1898 die xxxi mensis v annoque mdcccxcviii 98 xcviii 1898}
+test clock-2.443 {conversion of 1898-06-01} {
+    clock format -2258969104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/01/1898 12:34:56 die i mensis vi annoque mdcccxcviii xii h xxxiv m lvi s 18 mdccc 01 i  1 i Jun 152 2414442 06 vi  6 06/01/1898 die i mensis vi annoque mdcccxcviii 98 xcviii 1898}
+test clock-2.444 {conversion of 1898-06-30} {
+    clock format -2256463504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/30/1898 12:34:56 die xxx mensis vi annoque mdcccxcviii xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Jun 181 2414471 06 vi  6 06/30/1898 die xxx mensis vi annoque mdcccxcviii 98 xcviii 1898}
+test clock-2.445 {conversion of 1898-07-01} {
+    clock format -2256377104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/01/1898 12:34:56 die i mensis vii annoque mdcccxcviii xii h xxxiv m lvi s 18 mdccc 01 i  1 i Jul 182 2414472 07 vii  7 07/01/1898 die i mensis vii annoque mdcccxcviii 98 xcviii 1898}
+test clock-2.446 {conversion of 1898-07-31} {
+    clock format -2253785104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/31/1898 12:34:56 die xxxi mensis vii annoque mdcccxcviii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Jul 212 2414502 07 vii  7 07/31/1898 die xxxi mensis vii annoque mdcccxcviii 98 xcviii 1898}
+test clock-2.447 {conversion of 1898-08-01} {
+    clock format -2253698704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/01/1898 12:34:56 die i mensis viii annoque mdcccxcviii xii h xxxiv m lvi s 18 mdccc 01 i  1 i Aug 213 2414503 08 viii  8 08/01/1898 die i mensis viii annoque mdcccxcviii 98 xcviii 1898}
+test clock-2.448 {conversion of 1898-08-31} {
+    clock format -2251106704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/31/1898 12:34:56 die xxxi mensis viii annoque mdcccxcviii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Aug 243 2414533 08 viii  8 08/31/1898 die xxxi mensis viii annoque mdcccxcviii 98 xcviii 1898}
+test clock-2.449 {conversion of 1898-09-01} {
+    clock format -2251020304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/01/1898 12:34:56 die i mensis ix annoque mdcccxcviii xii h xxxiv m lvi s 18 mdccc 01 i  1 i Sep 244 2414534 09 ix  9 09/01/1898 die i mensis ix annoque mdcccxcviii 98 xcviii 1898}
+test clock-2.450 {conversion of 1898-09-30} {
+    clock format -2248514704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/30/1898 12:34:56 die xxx mensis ix annoque mdcccxcviii xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Sep 273 2414563 09 ix  9 09/30/1898 die xxx mensis ix annoque mdcccxcviii 98 xcviii 1898}
+test clock-2.451 {conversion of 1898-10-01} {
+    clock format -2248428304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/01/1898 12:34:56 die i mensis x annoque mdcccxcviii xii h xxxiv m lvi s 18 mdccc 01 i  1 i Oct 274 2414564 10 x 10 10/01/1898 die i mensis x annoque mdcccxcviii 98 xcviii 1898}
+test clock-2.452 {conversion of 1898-10-31} {
+    clock format -2245836304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/31/1898 12:34:56 die xxxi mensis x annoque mdcccxcviii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Oct 304 2414594 10 x 10 10/31/1898 die xxxi mensis x annoque mdcccxcviii 98 xcviii 1898}
+test clock-2.453 {conversion of 1898-11-01} {
+    clock format -2245749904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/01/1898 12:34:56 die i mensis xi annoque mdcccxcviii xii h xxxiv m lvi s 18 mdccc 01 i  1 i Nov 305 2414595 11 xi 11 11/01/1898 die i mensis xi annoque mdcccxcviii 98 xcviii 1898}
+test clock-2.454 {conversion of 1898-11-30} {
+    clock format -2243244304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/30/1898 12:34:56 die xxx mensis xi annoque mdcccxcviii xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Nov 334 2414624 11 xi 11 11/30/1898 die xxx mensis xi annoque mdcccxcviii 98 xcviii 1898}
+test clock-2.455 {conversion of 1898-12-01} {
+    clock format -2243157904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/01/1898 12:34:56 die i mensis xii annoque mdcccxcviii xii h xxxiv m lvi s 18 mdccc 01 i  1 i Dec 335 2414625 12 xii 12 12/01/1898 die i mensis xii annoque mdcccxcviii 98 xcviii 1898}
+test clock-2.456 {conversion of 1898-12-31} {
+    clock format -2240565904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/31/1898 12:34:56 die xxxi mensis xii annoque mdcccxcviii xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Dec 365 2414655 12 xii 12 12/31/1898 die xxxi mensis xii annoque mdcccxcviii 98 xcviii 1898}
+test clock-2.457 {conversion of 1899-01-01} {
+    clock format -2240479504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/01/1899 12:34:56 die i mensis i annoque mdcccxcix xii h xxxiv m lvi s 18 mdccc 01 i  1 i Jan 001 2414656 01 i  1 01/01/1899 die i mensis i annoque mdcccxcix 99 xcix 1899}
+test clock-2.458 {conversion of 1899-01-31} {
+    clock format -2237887504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/31/1899 12:34:56 die xxxi mensis i annoque mdcccxcix xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Jan 031 2414686 01 i  1 01/31/1899 die xxxi mensis i annoque mdcccxcix 99 xcix 1899}
+test clock-2.459 {conversion of 1899-02-01} {
+    clock format -2237801104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/01/1899 12:34:56 die i mensis ii annoque mdcccxcix xii h xxxiv m lvi s 18 mdccc 01 i  1 i Feb 032 2414687 02 ii  2 02/01/1899 die i mensis ii annoque mdcccxcix 99 xcix 1899}
+test clock-2.460 {conversion of 1899-02-28} {
+    clock format -2235468304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/28/1899 12:34:56 die xxviii mensis ii annoque mdcccxcix xii h xxxiv m lvi s 18 mdccc 28 xxviii 28 xxviii Feb 059 2414714 02 ii  2 02/28/1899 die xxviii mensis ii annoque mdcccxcix 99 xcix 1899}
+test clock-2.461 {conversion of 1899-03-01} {
+    clock format -2235381904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/01/1899 12:34:56 die i mensis iii annoque mdcccxcix xii h xxxiv m lvi s 18 mdccc 01 i  1 i Mar 060 2414715 03 iii  3 03/01/1899 die i mensis iii annoque mdcccxcix 99 xcix 1899}
+test clock-2.462 {conversion of 1899-03-31} {
+    clock format -2232789904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/31/1899 12:34:56 die xxxi mensis iii annoque mdcccxcix xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Mar 090 2414745 03 iii  3 03/31/1899 die xxxi mensis iii annoque mdcccxcix 99 xcix 1899}
+test clock-2.463 {conversion of 1899-04-01} {
+    clock format -2232703504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/01/1899 12:34:56 die i mensis iv annoque mdcccxcix xii h xxxiv m lvi s 18 mdccc 01 i  1 i Apr 091 2414746 04 iv  4 04/01/1899 die i mensis iv annoque mdcccxcix 99 xcix 1899}
+test clock-2.464 {conversion of 1899-04-30} {
+    clock format -2230197904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/30/1899 12:34:56 die xxx mensis iv annoque mdcccxcix xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Apr 120 2414775 04 iv  4 04/30/1899 die xxx mensis iv annoque mdcccxcix 99 xcix 1899}
+test clock-2.465 {conversion of 1899-05-01} {
+    clock format -2230111504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/01/1899 12:34:56 die i mensis v annoque mdcccxcix xii h xxxiv m lvi s 18 mdccc 01 i  1 i May 121 2414776 05 v  5 05/01/1899 die i mensis v annoque mdcccxcix 99 xcix 1899}
+test clock-2.466 {conversion of 1899-05-31} {
+    clock format -2227519504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/31/1899 12:34:56 die xxxi mensis v annoque mdcccxcix xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi May 151 2414806 05 v  5 05/31/1899 die xxxi mensis v annoque mdcccxcix 99 xcix 1899}
+test clock-2.467 {conversion of 1899-06-01} {
+    clock format -2227433104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/01/1899 12:34:56 die i mensis vi annoque mdcccxcix xii h xxxiv m lvi s 18 mdccc 01 i  1 i Jun 152 2414807 06 vi  6 06/01/1899 die i mensis vi annoque mdcccxcix 99 xcix 1899}
+test clock-2.468 {conversion of 1899-06-30} {
+    clock format -2224927504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/30/1899 12:34:56 die xxx mensis vi annoque mdcccxcix xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Jun 181 2414836 06 vi  6 06/30/1899 die xxx mensis vi annoque mdcccxcix 99 xcix 1899}
+test clock-2.469 {conversion of 1899-07-01} {
+    clock format -2224841104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/01/1899 12:34:56 die i mensis vii annoque mdcccxcix xii h xxxiv m lvi s 18 mdccc 01 i  1 i Jul 182 2414837 07 vii  7 07/01/1899 die i mensis vii annoque mdcccxcix 99 xcix 1899}
+test clock-2.470 {conversion of 1899-07-31} {
+    clock format -2222249104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/31/1899 12:34:56 die xxxi mensis vii annoque mdcccxcix xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Jul 212 2414867 07 vii  7 07/31/1899 die xxxi mensis vii annoque mdcccxcix 99 xcix 1899}
+test clock-2.471 {conversion of 1899-08-01} {
+    clock format -2222162704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/01/1899 12:34:56 die i mensis viii annoque mdcccxcix xii h xxxiv m lvi s 18 mdccc 01 i  1 i Aug 213 2414868 08 viii  8 08/01/1899 die i mensis viii annoque mdcccxcix 99 xcix 1899}
+test clock-2.472 {conversion of 1899-08-31} {
+    clock format -2219570704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/31/1899 12:34:56 die xxxi mensis viii annoque mdcccxcix xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Aug 243 2414898 08 viii  8 08/31/1899 die xxxi mensis viii annoque mdcccxcix 99 xcix 1899}
+test clock-2.473 {conversion of 1899-09-01} {
+    clock format -2219484304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/01/1899 12:34:56 die i mensis ix annoque mdcccxcix xii h xxxiv m lvi s 18 mdccc 01 i  1 i Sep 244 2414899 09 ix  9 09/01/1899 die i mensis ix annoque mdcccxcix 99 xcix 1899}
+test clock-2.474 {conversion of 1899-09-30} {
+    clock format -2216978704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/30/1899 12:34:56 die xxx mensis ix annoque mdcccxcix xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Sep 273 2414928 09 ix  9 09/30/1899 die xxx mensis ix annoque mdcccxcix 99 xcix 1899}
+test clock-2.475 {conversion of 1899-10-01} {
+    clock format -2216892304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/01/1899 12:34:56 die i mensis x annoque mdcccxcix xii h xxxiv m lvi s 18 mdccc 01 i  1 i Oct 274 2414929 10 x 10 10/01/1899 die i mensis x annoque mdcccxcix 99 xcix 1899}
+test clock-2.476 {conversion of 1899-10-31} {
+    clock format -2214300304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/31/1899 12:34:56 die xxxi mensis x annoque mdcccxcix xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Oct 304 2414959 10 x 10 10/31/1899 die xxxi mensis x annoque mdcccxcix 99 xcix 1899}
+test clock-2.477 {conversion of 1899-11-01} {
+    clock format -2214213904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/01/1899 12:34:56 die i mensis xi annoque mdcccxcix xii h xxxiv m lvi s 18 mdccc 01 i  1 i Nov 305 2414960 11 xi 11 11/01/1899 die i mensis xi annoque mdcccxcix 99 xcix 1899}
+test clock-2.478 {conversion of 1899-11-30} {
+    clock format -2211708304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/30/1899 12:34:56 die xxx mensis xi annoque mdcccxcix xii h xxxiv m lvi s 18 mdccc 30 xxx 30 xxx Nov 334 2414989 11 xi 11 11/30/1899 die xxx mensis xi annoque mdcccxcix 99 xcix 1899}
+test clock-2.479 {conversion of 1899-12-01} {
+    clock format -2211621904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/01/1899 12:34:56 die i mensis xii annoque mdcccxcix xii h xxxiv m lvi s 18 mdccc 01 i  1 i Dec 335 2414990 12 xii 12 12/01/1899 die i mensis xii annoque mdcccxcix 99 xcix 1899}
+test clock-2.480 {conversion of 1899-12-31} {
+    clock format -2209029904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/31/1899 12:34:56 die xxxi mensis xii annoque mdcccxcix xii h xxxiv m lvi s 18 mdccc 31 xxxi 31 xxxi Dec 365 2415020 12 xii 12 12/31/1899 die xxxi mensis xii annoque mdcccxcix 99 xcix 1899}
+test clock-2.481 {conversion of 1900-01-01} {
+    clock format -2208943504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/01/1900 12:34:56 die i mensis i annoque mcm? xii h xxxiv m lvi s 19 mcm 01 i  1 i Jan 001 2415021 01 i  1 01/01/1900 die i mensis i annoque mcm? 00 ? 1900}
+test clock-2.482 {conversion of 1900-01-31} {
+    clock format -2206351504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/31/1900 12:34:56 die xxxi mensis i annoque mcm? xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jan 031 2415051 01 i  1 01/31/1900 die xxxi mensis i annoque mcm? 00 ? 1900}
+test clock-2.483 {conversion of 1900-02-01} {
+    clock format -2206265104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/01/1900 12:34:56 die i mensis ii annoque mcm? xii h xxxiv m lvi s 19 mcm 01 i  1 i Feb 032 2415052 02 ii  2 02/01/1900 die i mensis ii annoque mcm? 00 ? 1900}
+test clock-2.484 {conversion of 1900-02-28} {
+    clock format -2203932304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/28/1900 12:34:56 die xxviii mensis ii annoque mcm? xii h xxxiv m lvi s 19 mcm 28 xxviii 28 xxviii Feb 059 2415079 02 ii  2 02/28/1900 die xxviii mensis ii annoque mcm? 00 ? 1900}
+test clock-2.485 {conversion of 1900-03-01} {
+    clock format -2203845904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/01/1900 12:34:56 die i mensis iii annoque mcm? xii h xxxiv m lvi s 19 mcm 01 i  1 i Mar 060 2415080 03 iii  3 03/01/1900 die i mensis iii annoque mcm? 00 ? 1900}
+test clock-2.486 {conversion of 1900-03-31} {
+    clock format -2201253904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/31/1900 12:34:56 die xxxi mensis iii annoque mcm? xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Mar 090 2415110 03 iii  3 03/31/1900 die xxxi mensis iii annoque mcm? 00 ? 1900}
+test clock-2.487 {conversion of 1900-04-01} {
+    clock format -2201167504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/01/1900 12:34:56 die i mensis iv annoque mcm? xii h xxxiv m lvi s 19 mcm 01 i  1 i Apr 091 2415111 04 iv  4 04/01/1900 die i mensis iv annoque mcm? 00 ? 1900}
+test clock-2.488 {conversion of 1900-04-30} {
+    clock format -2198661904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/30/1900 12:34:56 die xxx mensis iv annoque mcm? xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Apr 120 2415140 04 iv  4 04/30/1900 die xxx mensis iv annoque mcm? 00 ? 1900}
+test clock-2.489 {conversion of 1900-05-01} {
+    clock format -2198575504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/01/1900 12:34:56 die i mensis v annoque mcm? xii h xxxiv m lvi s 19 mcm 01 i  1 i May 121 2415141 05 v  5 05/01/1900 die i mensis v annoque mcm? 00 ? 1900}
+test clock-2.490 {conversion of 1900-05-31} {
+    clock format -2195983504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/31/1900 12:34:56 die xxxi mensis v annoque mcm? xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi May 151 2415171 05 v  5 05/31/1900 die xxxi mensis v annoque mcm? 00 ? 1900}
+test clock-2.491 {conversion of 1900-06-01} {
+    clock format -2195897104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/01/1900 12:34:56 die i mensis vi annoque mcm? xii h xxxiv m lvi s 19 mcm 01 i  1 i Jun 152 2415172 06 vi  6 06/01/1900 die i mensis vi annoque mcm? 00 ? 1900}
+test clock-2.492 {conversion of 1900-06-30} {
+    clock format -2193391504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/30/1900 12:34:56 die xxx mensis vi annoque mcm? xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Jun 181 2415201 06 vi  6 06/30/1900 die xxx mensis vi annoque mcm? 00 ? 1900}
+test clock-2.493 {conversion of 1900-07-01} {
+    clock format -2193305104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/01/1900 12:34:56 die i mensis vii annoque mcm? xii h xxxiv m lvi s 19 mcm 01 i  1 i Jul 182 2415202 07 vii  7 07/01/1900 die i mensis vii annoque mcm? 00 ? 1900}
+test clock-2.494 {conversion of 1900-07-31} {
+    clock format -2190713104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/31/1900 12:34:56 die xxxi mensis vii annoque mcm? xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jul 212 2415232 07 vii  7 07/31/1900 die xxxi mensis vii annoque mcm? 00 ? 1900}
+test clock-2.495 {conversion of 1900-08-01} {
+    clock format -2190626704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/01/1900 12:34:56 die i mensis viii annoque mcm? xii h xxxiv m lvi s 19 mcm 01 i  1 i Aug 213 2415233 08 viii  8 08/01/1900 die i mensis viii annoque mcm? 00 ? 1900}
+test clock-2.496 {conversion of 1900-08-31} {
+    clock format -2188034704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/31/1900 12:34:56 die xxxi mensis viii annoque mcm? xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Aug 243 2415263 08 viii  8 08/31/1900 die xxxi mensis viii annoque mcm? 00 ? 1900}
+test clock-2.497 {conversion of 1900-09-01} {
+    clock format -2187948304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/01/1900 12:34:56 die i mensis ix annoque mcm? xii h xxxiv m lvi s 19 mcm 01 i  1 i Sep 244 2415264 09 ix  9 09/01/1900 die i mensis ix annoque mcm? 00 ? 1900}
+test clock-2.498 {conversion of 1900-09-30} {
+    clock format -2185442704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/30/1900 12:34:56 die xxx mensis ix annoque mcm? xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Sep 273 2415293 09 ix  9 09/30/1900 die xxx mensis ix annoque mcm? 00 ? 1900}
+test clock-2.499 {conversion of 1900-10-01} {
+    clock format -2185356304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/01/1900 12:34:56 die i mensis x annoque mcm? xii h xxxiv m lvi s 19 mcm 01 i  1 i Oct 274 2415294 10 x 10 10/01/1900 die i mensis x annoque mcm? 00 ? 1900}
+test clock-2.500 {conversion of 1900-10-31} {
+    clock format -2182764304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/31/1900 12:34:56 die xxxi mensis x annoque mcm? xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Oct 304 2415324 10 x 10 10/31/1900 die xxxi mensis x annoque mcm? 00 ? 1900}
+test clock-2.501 {conversion of 1900-11-01} {
+    clock format -2182677904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/01/1900 12:34:56 die i mensis xi annoque mcm? xii h xxxiv m lvi s 19 mcm 01 i  1 i Nov 305 2415325 11 xi 11 11/01/1900 die i mensis xi annoque mcm? 00 ? 1900}
+test clock-2.502 {conversion of 1900-11-30} {
+    clock format -2180172304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/30/1900 12:34:56 die xxx mensis xi annoque mcm? xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Nov 334 2415354 11 xi 11 11/30/1900 die xxx mensis xi annoque mcm? 00 ? 1900}
+test clock-2.503 {conversion of 1900-12-01} {
+    clock format -2180085904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/01/1900 12:34:56 die i mensis xii annoque mcm? xii h xxxiv m lvi s 19 mcm 01 i  1 i Dec 335 2415355 12 xii 12 12/01/1900 die i mensis xii annoque mcm? 00 ? 1900}
+test clock-2.504 {conversion of 1900-12-31} {
+    clock format -2177493904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/31/1900 12:34:56 die xxxi mensis xii annoque mcm? xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Dec 365 2415385 12 xii 12 12/31/1900 die xxxi mensis xii annoque mcm? 00 ? 1900}
+test clock-2.505 {conversion of 1944-01-01} {
+    clock format -820495504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/01/1944 12:34:56 die i mensis i annoque mcmxliv xii h xxxiv m lvi s 19 mcm 01 i  1 i Jan 001 2431091 01 i  1 01/01/1944 die i mensis i annoque mcmxliv 44 xliv 1944}
+test clock-2.506 {conversion of 1944-01-31} {
+    clock format -817903504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/31/1944 12:34:56 die xxxi mensis i annoque mcmxliv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jan 031 2431121 01 i  1 01/31/1944 die xxxi mensis i annoque mcmxliv 44 xliv 1944}
+test clock-2.507 {conversion of 1944-02-01} {
+    clock format -817817104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/01/1944 12:34:56 die i mensis ii annoque mcmxliv xii h xxxiv m lvi s 19 mcm 01 i  1 i Feb 032 2431122 02 ii  2 02/01/1944 die i mensis ii annoque mcmxliv 44 xliv 1944}
+test clock-2.508 {conversion of 1944-02-29} {
+    clock format -815397904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/29/1944 12:34:56 die xxix mensis ii annoque mcmxliv xii h xxxiv m lvi s 19 mcm 29 xxix 29 xxix Feb 060 2431150 02 ii  2 02/29/1944 die xxix mensis ii annoque mcmxliv 44 xliv 1944}
+test clock-2.509 {conversion of 1944-03-01} {
+    clock format -815311504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/01/1944 12:34:56 die i mensis iii annoque mcmxliv xii h xxxiv m lvi s 19 mcm 01 i  1 i Mar 061 2431151 03 iii  3 03/01/1944 die i mensis iii annoque mcmxliv 44 xliv 1944}
+test clock-2.510 {conversion of 1944-03-31} {
+    clock format -812719504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/31/1944 12:34:56 die xxxi mensis iii annoque mcmxliv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Mar 091 2431181 03 iii  3 03/31/1944 die xxxi mensis iii annoque mcmxliv 44 xliv 1944}
+test clock-2.511 {conversion of 1944-04-01} {
+    clock format -812633104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/01/1944 12:34:56 die i mensis iv annoque mcmxliv xii h xxxiv m lvi s 19 mcm 01 i  1 i Apr 092 2431182 04 iv  4 04/01/1944 die i mensis iv annoque mcmxliv 44 xliv 1944}
+test clock-2.512 {conversion of 1944-04-30} {
+    clock format -810127504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/30/1944 12:34:56 die xxx mensis iv annoque mcmxliv xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Apr 121 2431211 04 iv  4 04/30/1944 die xxx mensis iv annoque mcmxliv 44 xliv 1944}
+test clock-2.513 {conversion of 1944-05-01} {
+    clock format -810041104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/01/1944 12:34:56 die i mensis v annoque mcmxliv xii h xxxiv m lvi s 19 mcm 01 i  1 i May 122 2431212 05 v  5 05/01/1944 die i mensis v annoque mcmxliv 44 xliv 1944}
+test clock-2.514 {conversion of 1944-05-31} {
+    clock format -807449104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/31/1944 12:34:56 die xxxi mensis v annoque mcmxliv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi May 152 2431242 05 v  5 05/31/1944 die xxxi mensis v annoque mcmxliv 44 xliv 1944}
+test clock-2.515 {conversion of 1944-06-01} {
+    clock format -807362704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/01/1944 12:34:56 die i mensis vi annoque mcmxliv xii h xxxiv m lvi s 19 mcm 01 i  1 i Jun 153 2431243 06 vi  6 06/01/1944 die i mensis vi annoque mcmxliv 44 xliv 1944}
+test clock-2.516 {conversion of 1944-06-30} {
+    clock format -804857104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/30/1944 12:34:56 die xxx mensis vi annoque mcmxliv xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Jun 182 2431272 06 vi  6 06/30/1944 die xxx mensis vi annoque mcmxliv 44 xliv 1944}
+test clock-2.517 {conversion of 1944-07-01} {
+    clock format -804770704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/01/1944 12:34:56 die i mensis vii annoque mcmxliv xii h xxxiv m lvi s 19 mcm 01 i  1 i Jul 183 2431273 07 vii  7 07/01/1944 die i mensis vii annoque mcmxliv 44 xliv 1944}
+test clock-2.518 {conversion of 1944-07-31} {
+    clock format -802178704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/31/1944 12:34:56 die xxxi mensis vii annoque mcmxliv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jul 213 2431303 07 vii  7 07/31/1944 die xxxi mensis vii annoque mcmxliv 44 xliv 1944}
+test clock-2.519 {conversion of 1944-08-01} {
+    clock format -802092304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/01/1944 12:34:56 die i mensis viii annoque mcmxliv xii h xxxiv m lvi s 19 mcm 01 i  1 i Aug 214 2431304 08 viii  8 08/01/1944 die i mensis viii annoque mcmxliv 44 xliv 1944}
+test clock-2.520 {conversion of 1944-08-31} {
+    clock format -799500304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/31/1944 12:34:56 die xxxi mensis viii annoque mcmxliv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Aug 244 2431334 08 viii  8 08/31/1944 die xxxi mensis viii annoque mcmxliv 44 xliv 1944}
+test clock-2.521 {conversion of 1944-09-01} {
+    clock format -799413904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/01/1944 12:34:56 die i mensis ix annoque mcmxliv xii h xxxiv m lvi s 19 mcm 01 i  1 i Sep 245 2431335 09 ix  9 09/01/1944 die i mensis ix annoque mcmxliv 44 xliv 1944}
+test clock-2.522 {conversion of 1944-09-30} {
+    clock format -796908304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/30/1944 12:34:56 die xxx mensis ix annoque mcmxliv xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Sep 274 2431364 09 ix  9 09/30/1944 die xxx mensis ix annoque mcmxliv 44 xliv 1944}
+test clock-2.523 {conversion of 1944-10-01} {
+    clock format -796821904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/01/1944 12:34:56 die i mensis x annoque mcmxliv xii h xxxiv m lvi s 19 mcm 01 i  1 i Oct 275 2431365 10 x 10 10/01/1944 die i mensis x annoque mcmxliv 44 xliv 1944}
+test clock-2.524 {conversion of 1944-10-31} {
+    clock format -794229904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/31/1944 12:34:56 die xxxi mensis x annoque mcmxliv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Oct 305 2431395 10 x 10 10/31/1944 die xxxi mensis x annoque mcmxliv 44 xliv 1944}
+test clock-2.525 {conversion of 1944-11-01} {
+    clock format -794143504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/01/1944 12:34:56 die i mensis xi annoque mcmxliv xii h xxxiv m lvi s 19 mcm 01 i  1 i Nov 306 2431396 11 xi 11 11/01/1944 die i mensis xi annoque mcmxliv 44 xliv 1944}
+test clock-2.526 {conversion of 1944-11-30} {
+    clock format -791637904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/30/1944 12:34:56 die xxx mensis xi annoque mcmxliv xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Nov 335 2431425 11 xi 11 11/30/1944 die xxx mensis xi annoque mcmxliv 44 xliv 1944}
+test clock-2.527 {conversion of 1944-12-01} {
+    clock format -791551504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/01/1944 12:34:56 die i mensis xii annoque mcmxliv xii h xxxiv m lvi s 19 mcm 01 i  1 i Dec 336 2431426 12 xii 12 12/01/1944 die i mensis xii annoque mcmxliv 44 xliv 1944}
+test clock-2.528 {conversion of 1944-12-31} {
+    clock format -788959504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/31/1944 12:34:56 die xxxi mensis xii annoque mcmxliv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Dec 366 2431456 12 xii 12 12/31/1944 die xxxi mensis xii annoque mcmxliv 44 xliv 1944}
+test clock-2.529 {conversion of 1945-01-01} {
+    clock format -788873104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/01/1945 12:34:56 die i mensis i annoque mcmxlv xii h xxxiv m lvi s 19 mcm 01 i  1 i Jan 001 2431457 01 i  1 01/01/1945 die i mensis i annoque mcmxlv 45 xlv 1945}
+test clock-2.530 {conversion of 1945-01-31} {
+    clock format -786281104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/31/1945 12:34:56 die xxxi mensis i annoque mcmxlv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jan 031 2431487 01 i  1 01/31/1945 die xxxi mensis i annoque mcmxlv 45 xlv 1945}
+test clock-2.531 {conversion of 1945-02-01} {
+    clock format -786194704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/01/1945 12:34:56 die i mensis ii annoque mcmxlv xii h xxxiv m lvi s 19 mcm 01 i  1 i Feb 032 2431488 02 ii  2 02/01/1945 die i mensis ii annoque mcmxlv 45 xlv 1945}
+test clock-2.532 {conversion of 1945-02-28} {
+    clock format -783861904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/28/1945 12:34:56 die xxviii mensis ii annoque mcmxlv xii h xxxiv m lvi s 19 mcm 28 xxviii 28 xxviii Feb 059 2431515 02 ii  2 02/28/1945 die xxviii mensis ii annoque mcmxlv 45 xlv 1945}
+test clock-2.533 {conversion of 1945-03-01} {
+    clock format -783775504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/01/1945 12:34:56 die i mensis iii annoque mcmxlv xii h xxxiv m lvi s 19 mcm 01 i  1 i Mar 060 2431516 03 iii  3 03/01/1945 die i mensis iii annoque mcmxlv 45 xlv 1945}
+test clock-2.534 {conversion of 1945-03-31} {
+    clock format -781183504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/31/1945 12:34:56 die xxxi mensis iii annoque mcmxlv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Mar 090 2431546 03 iii  3 03/31/1945 die xxxi mensis iii annoque mcmxlv 45 xlv 1945}
+test clock-2.535 {conversion of 1945-04-01} {
+    clock format -781097104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/01/1945 12:34:56 die i mensis iv annoque mcmxlv xii h xxxiv m lvi s 19 mcm 01 i  1 i Apr 091 2431547 04 iv  4 04/01/1945 die i mensis iv annoque mcmxlv 45 xlv 1945}
+test clock-2.536 {conversion of 1945-04-30} {
+    clock format -778591504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/30/1945 12:34:56 die xxx mensis iv annoque mcmxlv xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Apr 120 2431576 04 iv  4 04/30/1945 die xxx mensis iv annoque mcmxlv 45 xlv 1945}
+test clock-2.537 {conversion of 1945-05-01} {
+    clock format -778505104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/01/1945 12:34:56 die i mensis v annoque mcmxlv xii h xxxiv m lvi s 19 mcm 01 i  1 i May 121 2431577 05 v  5 05/01/1945 die i mensis v annoque mcmxlv 45 xlv 1945}
+test clock-2.538 {conversion of 1945-05-31} {
+    clock format -775913104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/31/1945 12:34:56 die xxxi mensis v annoque mcmxlv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi May 151 2431607 05 v  5 05/31/1945 die xxxi mensis v annoque mcmxlv 45 xlv 1945}
+test clock-2.539 {conversion of 1945-06-01} {
+    clock format -775826704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/01/1945 12:34:56 die i mensis vi annoque mcmxlv xii h xxxiv m lvi s 19 mcm 01 i  1 i Jun 152 2431608 06 vi  6 06/01/1945 die i mensis vi annoque mcmxlv 45 xlv 1945}
+test clock-2.540 {conversion of 1945-06-30} {
+    clock format -773321104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/30/1945 12:34:56 die xxx mensis vi annoque mcmxlv xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Jun 181 2431637 06 vi  6 06/30/1945 die xxx mensis vi annoque mcmxlv 45 xlv 1945}
+test clock-2.541 {conversion of 1945-07-01} {
+    clock format -773234704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/01/1945 12:34:56 die i mensis vii annoque mcmxlv xii h xxxiv m lvi s 19 mcm 01 i  1 i Jul 182 2431638 07 vii  7 07/01/1945 die i mensis vii annoque mcmxlv 45 xlv 1945}
+test clock-2.542 {conversion of 1945-07-31} {
+    clock format -770642704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/31/1945 12:34:56 die xxxi mensis vii annoque mcmxlv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jul 212 2431668 07 vii  7 07/31/1945 die xxxi mensis vii annoque mcmxlv 45 xlv 1945}
+test clock-2.543 {conversion of 1945-08-01} {
+    clock format -770556304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/01/1945 12:34:56 die i mensis viii annoque mcmxlv xii h xxxiv m lvi s 19 mcm 01 i  1 i Aug 213 2431669 08 viii  8 08/01/1945 die i mensis viii annoque mcmxlv 45 xlv 1945}
+test clock-2.544 {conversion of 1945-08-31} {
+    clock format -767964304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/31/1945 12:34:56 die xxxi mensis viii annoque mcmxlv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Aug 243 2431699 08 viii  8 08/31/1945 die xxxi mensis viii annoque mcmxlv 45 xlv 1945}
+test clock-2.545 {conversion of 1945-09-01} {
+    clock format -767877904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/01/1945 12:34:56 die i mensis ix annoque mcmxlv xii h xxxiv m lvi s 19 mcm 01 i  1 i Sep 244 2431700 09 ix  9 09/01/1945 die i mensis ix annoque mcmxlv 45 xlv 1945}
+test clock-2.546 {conversion of 1945-09-30} {
+    clock format -765372304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/30/1945 12:34:56 die xxx mensis ix annoque mcmxlv xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Sep 273 2431729 09 ix  9 09/30/1945 die xxx mensis ix annoque mcmxlv 45 xlv 1945}
+test clock-2.547 {conversion of 1945-10-01} {
+    clock format -765285904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/01/1945 12:34:56 die i mensis x annoque mcmxlv xii h xxxiv m lvi s 19 mcm 01 i  1 i Oct 274 2431730 10 x 10 10/01/1945 die i mensis x annoque mcmxlv 45 xlv 1945}
+test clock-2.548 {conversion of 1945-10-31} {
+    clock format -762693904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/31/1945 12:34:56 die xxxi mensis x annoque mcmxlv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Oct 304 2431760 10 x 10 10/31/1945 die xxxi mensis x annoque mcmxlv 45 xlv 1945}
+test clock-2.549 {conversion of 1945-11-01} {
+    clock format -762607504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/01/1945 12:34:56 die i mensis xi annoque mcmxlv xii h xxxiv m lvi s 19 mcm 01 i  1 i Nov 305 2431761 11 xi 11 11/01/1945 die i mensis xi annoque mcmxlv 45 xlv 1945}
+test clock-2.550 {conversion of 1945-11-30} {
+    clock format -760101904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/30/1945 12:34:56 die xxx mensis xi annoque mcmxlv xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Nov 334 2431790 11 xi 11 11/30/1945 die xxx mensis xi annoque mcmxlv 45 xlv 1945}
+test clock-2.551 {conversion of 1945-12-01} {
+    clock format -760015504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/01/1945 12:34:56 die i mensis xii annoque mcmxlv xii h xxxiv m lvi s 19 mcm 01 i  1 i Dec 335 2431791 12 xii 12 12/01/1945 die i mensis xii annoque mcmxlv 45 xlv 1945}
+test clock-2.552 {conversion of 1945-12-31} {
+    clock format -757423504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/31/1945 12:34:56 die xxxi mensis xii annoque mcmxlv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Dec 365 2431821 12 xii 12 12/31/1945 die xxxi mensis xii annoque mcmxlv 45 xlv 1945}
+test clock-2.553 {conversion of 1948-01-01} {
+    clock format -694265104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/01/1948 12:34:56 die i mensis i annoque mcmxlviii xii h xxxiv m lvi s 19 mcm 01 i  1 i Jan 001 2432552 01 i  1 01/01/1948 die i mensis i annoque mcmxlviii 48 xlviii 1948}
+test clock-2.554 {conversion of 1948-01-31} {
+    clock format -691673104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/31/1948 12:34:56 die xxxi mensis i annoque mcmxlviii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jan 031 2432582 01 i  1 01/31/1948 die xxxi mensis i annoque mcmxlviii 48 xlviii 1948}
+test clock-2.555 {conversion of 1948-02-01} {
+    clock format -691586704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/01/1948 12:34:56 die i mensis ii annoque mcmxlviii xii h xxxiv m lvi s 19 mcm 01 i  1 i Feb 032 2432583 02 ii  2 02/01/1948 die i mensis ii annoque mcmxlviii 48 xlviii 1948}
+test clock-2.556 {conversion of 1948-02-29} {
+    clock format -689167504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/29/1948 12:34:56 die xxix mensis ii annoque mcmxlviii xii h xxxiv m lvi s 19 mcm 29 xxix 29 xxix Feb 060 2432611 02 ii  2 02/29/1948 die xxix mensis ii annoque mcmxlviii 48 xlviii 1948}
+test clock-2.557 {conversion of 1948-03-01} {
+    clock format -689081104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/01/1948 12:34:56 die i mensis iii annoque mcmxlviii xii h xxxiv m lvi s 19 mcm 01 i  1 i Mar 061 2432612 03 iii  3 03/01/1948 die i mensis iii annoque mcmxlviii 48 xlviii 1948}
+test clock-2.558 {conversion of 1948-03-31} {
+    clock format -686489104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/31/1948 12:34:56 die xxxi mensis iii annoque mcmxlviii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Mar 091 2432642 03 iii  3 03/31/1948 die xxxi mensis iii annoque mcmxlviii 48 xlviii 1948}
+test clock-2.559 {conversion of 1948-04-01} {
+    clock format -686402704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/01/1948 12:34:56 die i mensis iv annoque mcmxlviii xii h xxxiv m lvi s 19 mcm 01 i  1 i Apr 092 2432643 04 iv  4 04/01/1948 die i mensis iv annoque mcmxlviii 48 xlviii 1948}
+test clock-2.560 {conversion of 1948-04-30} {
+    clock format -683897104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/30/1948 12:34:56 die xxx mensis iv annoque mcmxlviii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Apr 121 2432672 04 iv  4 04/30/1948 die xxx mensis iv annoque mcmxlviii 48 xlviii 1948}
+test clock-2.561 {conversion of 1948-05-01} {
+    clock format -683810704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/01/1948 12:34:56 die i mensis v annoque mcmxlviii xii h xxxiv m lvi s 19 mcm 01 i  1 i May 122 2432673 05 v  5 05/01/1948 die i mensis v annoque mcmxlviii 48 xlviii 1948}
+test clock-2.562 {conversion of 1948-05-31} {
+    clock format -681218704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/31/1948 12:34:56 die xxxi mensis v annoque mcmxlviii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi May 152 2432703 05 v  5 05/31/1948 die xxxi mensis v annoque mcmxlviii 48 xlviii 1948}
+test clock-2.563 {conversion of 1948-06-01} {
+    clock format -681132304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/01/1948 12:34:56 die i mensis vi annoque mcmxlviii xii h xxxiv m lvi s 19 mcm 01 i  1 i Jun 153 2432704 06 vi  6 06/01/1948 die i mensis vi annoque mcmxlviii 48 xlviii 1948}
+test clock-2.564 {conversion of 1948-06-30} {
+    clock format -678626704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/30/1948 12:34:56 die xxx mensis vi annoque mcmxlviii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Jun 182 2432733 06 vi  6 06/30/1948 die xxx mensis vi annoque mcmxlviii 48 xlviii 1948}
+test clock-2.565 {conversion of 1948-07-01} {
+    clock format -678540304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/01/1948 12:34:56 die i mensis vii annoque mcmxlviii xii h xxxiv m lvi s 19 mcm 01 i  1 i Jul 183 2432734 07 vii  7 07/01/1948 die i mensis vii annoque mcmxlviii 48 xlviii 1948}
+test clock-2.566 {conversion of 1948-07-31} {
+    clock format -675948304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/31/1948 12:34:56 die xxxi mensis vii annoque mcmxlviii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jul 213 2432764 07 vii  7 07/31/1948 die xxxi mensis vii annoque mcmxlviii 48 xlviii 1948}
+test clock-2.567 {conversion of 1948-08-01} {
+    clock format -675861904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/01/1948 12:34:56 die i mensis viii annoque mcmxlviii xii h xxxiv m lvi s 19 mcm 01 i  1 i Aug 214 2432765 08 viii  8 08/01/1948 die i mensis viii annoque mcmxlviii 48 xlviii 1948}
+test clock-2.568 {conversion of 1948-08-31} {
+    clock format -673269904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/31/1948 12:34:56 die xxxi mensis viii annoque mcmxlviii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Aug 244 2432795 08 viii  8 08/31/1948 die xxxi mensis viii annoque mcmxlviii 48 xlviii 1948}
+test clock-2.569 {conversion of 1948-09-01} {
+    clock format -673183504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/01/1948 12:34:56 die i mensis ix annoque mcmxlviii xii h xxxiv m lvi s 19 mcm 01 i  1 i Sep 245 2432796 09 ix  9 09/01/1948 die i mensis ix annoque mcmxlviii 48 xlviii 1948}
+test clock-2.570 {conversion of 1948-09-30} {
+    clock format -670677904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/30/1948 12:34:56 die xxx mensis ix annoque mcmxlviii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Sep 274 2432825 09 ix  9 09/30/1948 die xxx mensis ix annoque mcmxlviii 48 xlviii 1948}
+test clock-2.571 {conversion of 1948-10-01} {
+    clock format -670591504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/01/1948 12:34:56 die i mensis x annoque mcmxlviii xii h xxxiv m lvi s 19 mcm 01 i  1 i Oct 275 2432826 10 x 10 10/01/1948 die i mensis x annoque mcmxlviii 48 xlviii 1948}
+test clock-2.572 {conversion of 1948-10-31} {
+    clock format -667999504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/31/1948 12:34:56 die xxxi mensis x annoque mcmxlviii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Oct 305 2432856 10 x 10 10/31/1948 die xxxi mensis x annoque mcmxlviii 48 xlviii 1948}
+test clock-2.573 {conversion of 1948-11-01} {
+    clock format -667913104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/01/1948 12:34:56 die i mensis xi annoque mcmxlviii xii h xxxiv m lvi s 19 mcm 01 i  1 i Nov 306 2432857 11 xi 11 11/01/1948 die i mensis xi annoque mcmxlviii 48 xlviii 1948}
+test clock-2.574 {conversion of 1948-11-30} {
+    clock format -665407504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/30/1948 12:34:56 die xxx mensis xi annoque mcmxlviii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Nov 335 2432886 11 xi 11 11/30/1948 die xxx mensis xi annoque mcmxlviii 48 xlviii 1948}
+test clock-2.575 {conversion of 1948-12-01} {
+    clock format -665321104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/01/1948 12:34:56 die i mensis xii annoque mcmxlviii xii h xxxiv m lvi s 19 mcm 01 i  1 i Dec 336 2432887 12 xii 12 12/01/1948 die i mensis xii annoque mcmxlviii 48 xlviii 1948}
+test clock-2.576 {conversion of 1948-12-31} {
+    clock format -662729104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/31/1948 12:34:56 die xxxi mensis xii annoque mcmxlviii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Dec 366 2432917 12 xii 12 12/31/1948 die xxxi mensis xii annoque mcmxlviii 48 xlviii 1948}
+test clock-2.577 {conversion of 1949-01-01} {
+    clock format -662642704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/01/1949 12:34:56 die i mensis i annoque mcmxlix xii h xxxiv m lvi s 19 mcm 01 i  1 i Jan 001 2432918 01 i  1 01/01/1949 die i mensis i annoque mcmxlix 49 xlix 1949}
+test clock-2.578 {conversion of 1949-01-31} {
+    clock format -660050704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/31/1949 12:34:56 die xxxi mensis i annoque mcmxlix xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jan 031 2432948 01 i  1 01/31/1949 die xxxi mensis i annoque mcmxlix 49 xlix 1949}
+test clock-2.579 {conversion of 1949-02-01} {
+    clock format -659964304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/01/1949 12:34:56 die i mensis ii annoque mcmxlix xii h xxxiv m lvi s 19 mcm 01 i  1 i Feb 032 2432949 02 ii  2 02/01/1949 die i mensis ii annoque mcmxlix 49 xlix 1949}
+test clock-2.580 {conversion of 1949-02-28} {
+    clock format -657631504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/28/1949 12:34:56 die xxviii mensis ii annoque mcmxlix xii h xxxiv m lvi s 19 mcm 28 xxviii 28 xxviii Feb 059 2432976 02 ii  2 02/28/1949 die xxviii mensis ii annoque mcmxlix 49 xlix 1949}
+test clock-2.581 {conversion of 1949-03-01} {
+    clock format -657545104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/01/1949 12:34:56 die i mensis iii annoque mcmxlix xii h xxxiv m lvi s 19 mcm 01 i  1 i Mar 060 2432977 03 iii  3 03/01/1949 die i mensis iii annoque mcmxlix 49 xlix 1949}
+test clock-2.582 {conversion of 1949-03-31} {
+    clock format -654953104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/31/1949 12:34:56 die xxxi mensis iii annoque mcmxlix xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Mar 090 2433007 03 iii  3 03/31/1949 die xxxi mensis iii annoque mcmxlix 49 xlix 1949}
+test clock-2.583 {conversion of 1949-04-01} {
+    clock format -654866704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/01/1949 12:34:56 die i mensis iv annoque mcmxlix xii h xxxiv m lvi s 19 mcm 01 i  1 i Apr 091 2433008 04 iv  4 04/01/1949 die i mensis iv annoque mcmxlix 49 xlix 1949}
+test clock-2.584 {conversion of 1949-04-30} {
+    clock format -652361104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/30/1949 12:34:56 die xxx mensis iv annoque mcmxlix xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Apr 120 2433037 04 iv  4 04/30/1949 die xxx mensis iv annoque mcmxlix 49 xlix 1949}
+test clock-2.585 {conversion of 1949-05-01} {
+    clock format -652274704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/01/1949 12:34:56 die i mensis v annoque mcmxlix xii h xxxiv m lvi s 19 mcm 01 i  1 i May 121 2433038 05 v  5 05/01/1949 die i mensis v annoque mcmxlix 49 xlix 1949}
+test clock-2.586 {conversion of 1949-05-31} {
+    clock format -649682704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/31/1949 12:34:56 die xxxi mensis v annoque mcmxlix xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi May 151 2433068 05 v  5 05/31/1949 die xxxi mensis v annoque mcmxlix 49 xlix 1949}
+test clock-2.587 {conversion of 1949-06-01} {
+    clock format -649596304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/01/1949 12:34:56 die i mensis vi annoque mcmxlix xii h xxxiv m lvi s 19 mcm 01 i  1 i Jun 152 2433069 06 vi  6 06/01/1949 die i mensis vi annoque mcmxlix 49 xlix 1949}
+test clock-2.588 {conversion of 1949-06-30} {
+    clock format -647090704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/30/1949 12:34:56 die xxx mensis vi annoque mcmxlix xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Jun 181 2433098 06 vi  6 06/30/1949 die xxx mensis vi annoque mcmxlix 49 xlix 1949}
+test clock-2.589 {conversion of 1949-07-01} {
+    clock format -647004304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/01/1949 12:34:56 die i mensis vii annoque mcmxlix xii h xxxiv m lvi s 19 mcm 01 i  1 i Jul 182 2433099 07 vii  7 07/01/1949 die i mensis vii annoque mcmxlix 49 xlix 1949}
+test clock-2.590 {conversion of 1949-07-31} {
+    clock format -644412304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/31/1949 12:34:56 die xxxi mensis vii annoque mcmxlix xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jul 212 2433129 07 vii  7 07/31/1949 die xxxi mensis vii annoque mcmxlix 49 xlix 1949}
+test clock-2.591 {conversion of 1949-08-01} {
+    clock format -644325904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/01/1949 12:34:56 die i mensis viii annoque mcmxlix xii h xxxiv m lvi s 19 mcm 01 i  1 i Aug 213 2433130 08 viii  8 08/01/1949 die i mensis viii annoque mcmxlix 49 xlix 1949}
+test clock-2.592 {conversion of 1949-08-31} {
+    clock format -641733904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/31/1949 12:34:56 die xxxi mensis viii annoque mcmxlix xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Aug 243 2433160 08 viii  8 08/31/1949 die xxxi mensis viii annoque mcmxlix 49 xlix 1949}
+test clock-2.593 {conversion of 1949-09-01} {
+    clock format -641647504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/01/1949 12:34:56 die i mensis ix annoque mcmxlix xii h xxxiv m lvi s 19 mcm 01 i  1 i Sep 244 2433161 09 ix  9 09/01/1949 die i mensis ix annoque mcmxlix 49 xlix 1949}
+test clock-2.594 {conversion of 1949-09-30} {
+    clock format -639141904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/30/1949 12:34:56 die xxx mensis ix annoque mcmxlix xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Sep 273 2433190 09 ix  9 09/30/1949 die xxx mensis ix annoque mcmxlix 49 xlix 1949}
+test clock-2.595 {conversion of 1949-10-01} {
+    clock format -639055504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/01/1949 12:34:56 die i mensis x annoque mcmxlix xii h xxxiv m lvi s 19 mcm 01 i  1 i Oct 274 2433191 10 x 10 10/01/1949 die i mensis x annoque mcmxlix 49 xlix 1949}
+test clock-2.596 {conversion of 1949-10-31} {
+    clock format -636463504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/31/1949 12:34:56 die xxxi mensis x annoque mcmxlix xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Oct 304 2433221 10 x 10 10/31/1949 die xxxi mensis x annoque mcmxlix 49 xlix 1949}
+test clock-2.597 {conversion of 1949-11-01} {
+    clock format -636377104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/01/1949 12:34:56 die i mensis xi annoque mcmxlix xii h xxxiv m lvi s 19 mcm 01 i  1 i Nov 305 2433222 11 xi 11 11/01/1949 die i mensis xi annoque mcmxlix 49 xlix 1949}
+test clock-2.598 {conversion of 1949-11-30} {
+    clock format -633871504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/30/1949 12:34:56 die xxx mensis xi annoque mcmxlix xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Nov 334 2433251 11 xi 11 11/30/1949 die xxx mensis xi annoque mcmxlix 49 xlix 1949}
+test clock-2.599 {conversion of 1949-12-01} {
+    clock format -633785104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/01/1949 12:34:56 die i mensis xii annoque mcmxlix xii h xxxiv m lvi s 19 mcm 01 i  1 i Dec 335 2433252 12 xii 12 12/01/1949 die i mensis xii annoque mcmxlix 49 xlix 1949}
+test clock-2.600 {conversion of 1949-12-31} {
+    clock format -631193104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/31/1949 12:34:56 die xxxi mensis xii annoque mcmxlix xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Dec 365 2433282 12 xii 12 12/31/1949 die xxxi mensis xii annoque mcmxlix 49 xlix 1949}
+test clock-2.601 {conversion of 1952-01-01} {
+    clock format -568034704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/01/1952 12:34:56 die i mensis i annoque mcmlii xii h xxxiv m lvi s 19 mcm 01 i  1 i Jan 001 2434013 01 i  1 01/01/1952 die i mensis i annoque mcmlii 52 lii 1952}
+test clock-2.602 {conversion of 1952-01-31} {
+    clock format -565442704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/31/1952 12:34:56 die xxxi mensis i annoque mcmlii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jan 031 2434043 01 i  1 01/31/1952 die xxxi mensis i annoque mcmlii 52 lii 1952}
+test clock-2.603 {conversion of 1952-02-01} {
+    clock format -565356304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/01/1952 12:34:56 die i mensis ii annoque mcmlii xii h xxxiv m lvi s 19 mcm 01 i  1 i Feb 032 2434044 02 ii  2 02/01/1952 die i mensis ii annoque mcmlii 52 lii 1952}
+test clock-2.604 {conversion of 1952-02-29} {
+    clock format -562937104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/29/1952 12:34:56 die xxix mensis ii annoque mcmlii xii h xxxiv m lvi s 19 mcm 29 xxix 29 xxix Feb 060 2434072 02 ii  2 02/29/1952 die xxix mensis ii annoque mcmlii 52 lii 1952}
+test clock-2.605 {conversion of 1952-03-01} {
+    clock format -562850704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/01/1952 12:34:56 die i mensis iii annoque mcmlii xii h xxxiv m lvi s 19 mcm 01 i  1 i Mar 061 2434073 03 iii  3 03/01/1952 die i mensis iii annoque mcmlii 52 lii 1952}
+test clock-2.606 {conversion of 1952-03-31} {
+    clock format -560258704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/31/1952 12:34:56 die xxxi mensis iii annoque mcmlii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Mar 091 2434103 03 iii  3 03/31/1952 die xxxi mensis iii annoque mcmlii 52 lii 1952}
+test clock-2.607 {conversion of 1952-04-01} {
+    clock format -560172304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/01/1952 12:34:56 die i mensis iv annoque mcmlii xii h xxxiv m lvi s 19 mcm 01 i  1 i Apr 092 2434104 04 iv  4 04/01/1952 die i mensis iv annoque mcmlii 52 lii 1952}
+test clock-2.608 {conversion of 1952-04-30} {
+    clock format -557666704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/30/1952 12:34:56 die xxx mensis iv annoque mcmlii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Apr 121 2434133 04 iv  4 04/30/1952 die xxx mensis iv annoque mcmlii 52 lii 1952}
+test clock-2.609 {conversion of 1952-05-01} {
+    clock format -557580304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/01/1952 12:34:56 die i mensis v annoque mcmlii xii h xxxiv m lvi s 19 mcm 01 i  1 i May 122 2434134 05 v  5 05/01/1952 die i mensis v annoque mcmlii 52 lii 1952}
+test clock-2.610 {conversion of 1952-05-31} {
+    clock format -554988304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/31/1952 12:34:56 die xxxi mensis v annoque mcmlii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi May 152 2434164 05 v  5 05/31/1952 die xxxi mensis v annoque mcmlii 52 lii 1952}
+test clock-2.611 {conversion of 1952-06-01} {
+    clock format -554901904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/01/1952 12:34:56 die i mensis vi annoque mcmlii xii h xxxiv m lvi s 19 mcm 01 i  1 i Jun 153 2434165 06 vi  6 06/01/1952 die i mensis vi annoque mcmlii 52 lii 1952}
+test clock-2.612 {conversion of 1952-06-30} {
+    clock format -552396304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/30/1952 12:34:56 die xxx mensis vi annoque mcmlii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Jun 182 2434194 06 vi  6 06/30/1952 die xxx mensis vi annoque mcmlii 52 lii 1952}
+test clock-2.613 {conversion of 1952-07-01} {
+    clock format -552309904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/01/1952 12:34:56 die i mensis vii annoque mcmlii xii h xxxiv m lvi s 19 mcm 01 i  1 i Jul 183 2434195 07 vii  7 07/01/1952 die i mensis vii annoque mcmlii 52 lii 1952}
+test clock-2.614 {conversion of 1952-07-31} {
+    clock format -549717904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/31/1952 12:34:56 die xxxi mensis vii annoque mcmlii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jul 213 2434225 07 vii  7 07/31/1952 die xxxi mensis vii annoque mcmlii 52 lii 1952}
+test clock-2.615 {conversion of 1952-08-01} {
+    clock format -549631504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/01/1952 12:34:56 die i mensis viii annoque mcmlii xii h xxxiv m lvi s 19 mcm 01 i  1 i Aug 214 2434226 08 viii  8 08/01/1952 die i mensis viii annoque mcmlii 52 lii 1952}
+test clock-2.616 {conversion of 1952-08-31} {
+    clock format -547039504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/31/1952 12:34:56 die xxxi mensis viii annoque mcmlii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Aug 244 2434256 08 viii  8 08/31/1952 die xxxi mensis viii annoque mcmlii 52 lii 1952}
+test clock-2.617 {conversion of 1952-09-01} {
+    clock format -546953104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/01/1952 12:34:56 die i mensis ix annoque mcmlii xii h xxxiv m lvi s 19 mcm 01 i  1 i Sep 245 2434257 09 ix  9 09/01/1952 die i mensis ix annoque mcmlii 52 lii 1952}
+test clock-2.618 {conversion of 1952-09-30} {
+    clock format -544447504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/30/1952 12:34:56 die xxx mensis ix annoque mcmlii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Sep 274 2434286 09 ix  9 09/30/1952 die xxx mensis ix annoque mcmlii 52 lii 1952}
+test clock-2.619 {conversion of 1952-10-01} {
+    clock format -544361104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/01/1952 12:34:56 die i mensis x annoque mcmlii xii h xxxiv m lvi s 19 mcm 01 i  1 i Oct 275 2434287 10 x 10 10/01/1952 die i mensis x annoque mcmlii 52 lii 1952}
+test clock-2.620 {conversion of 1952-10-31} {
+    clock format -541769104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/31/1952 12:34:56 die xxxi mensis x annoque mcmlii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Oct 305 2434317 10 x 10 10/31/1952 die xxxi mensis x annoque mcmlii 52 lii 1952}
+test clock-2.621 {conversion of 1952-11-01} {
+    clock format -541682704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/01/1952 12:34:56 die i mensis xi annoque mcmlii xii h xxxiv m lvi s 19 mcm 01 i  1 i Nov 306 2434318 11 xi 11 11/01/1952 die i mensis xi annoque mcmlii 52 lii 1952}
+test clock-2.622 {conversion of 1952-11-30} {
+    clock format -539177104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/30/1952 12:34:56 die xxx mensis xi annoque mcmlii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Nov 335 2434347 11 xi 11 11/30/1952 die xxx mensis xi annoque mcmlii 52 lii 1952}
+test clock-2.623 {conversion of 1952-12-01} {
+    clock format -539090704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/01/1952 12:34:56 die i mensis xii annoque mcmlii xii h xxxiv m lvi s 19 mcm 01 i  1 i Dec 336 2434348 12 xii 12 12/01/1952 die i mensis xii annoque mcmlii 52 lii 1952}
+test clock-2.624 {conversion of 1952-12-31} {
+    clock format -536498704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/31/1952 12:34:56 die xxxi mensis xii annoque mcmlii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Dec 366 2434378 12 xii 12 12/31/1952 die xxxi mensis xii annoque mcmlii 52 lii 1952}
+test clock-2.625 {conversion of 1953-01-01} {
+    clock format -536412304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/01/1953 12:34:56 die i mensis i annoque mcmliii xii h xxxiv m lvi s 19 mcm 01 i  1 i Jan 001 2434379 01 i  1 01/01/1953 die i mensis i annoque mcmliii 53 liii 1953}
+test clock-2.626 {conversion of 1953-01-31} {
+    clock format -533820304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/31/1953 12:34:56 die xxxi mensis i annoque mcmliii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jan 031 2434409 01 i  1 01/31/1953 die xxxi mensis i annoque mcmliii 53 liii 1953}
+test clock-2.627 {conversion of 1953-02-01} {
+    clock format -533733904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/01/1953 12:34:56 die i mensis ii annoque mcmliii xii h xxxiv m lvi s 19 mcm 01 i  1 i Feb 032 2434410 02 ii  2 02/01/1953 die i mensis ii annoque mcmliii 53 liii 1953}
+test clock-2.628 {conversion of 1953-02-28} {
+    clock format -531401104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/28/1953 12:34:56 die xxviii mensis ii annoque mcmliii xii h xxxiv m lvi s 19 mcm 28 xxviii 28 xxviii Feb 059 2434437 02 ii  2 02/28/1953 die xxviii mensis ii annoque mcmliii 53 liii 1953}
+test clock-2.629 {conversion of 1953-03-01} {
+    clock format -531314704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/01/1953 12:34:56 die i mensis iii annoque mcmliii xii h xxxiv m lvi s 19 mcm 01 i  1 i Mar 060 2434438 03 iii  3 03/01/1953 die i mensis iii annoque mcmliii 53 liii 1953}
+test clock-2.630 {conversion of 1953-03-31} {
+    clock format -528722704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/31/1953 12:34:56 die xxxi mensis iii annoque mcmliii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Mar 090 2434468 03 iii  3 03/31/1953 die xxxi mensis iii annoque mcmliii 53 liii 1953}
+test clock-2.631 {conversion of 1953-04-01} {
+    clock format -528636304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/01/1953 12:34:56 die i mensis iv annoque mcmliii xii h xxxiv m lvi s 19 mcm 01 i  1 i Apr 091 2434469 04 iv  4 04/01/1953 die i mensis iv annoque mcmliii 53 liii 1953}
+test clock-2.632 {conversion of 1953-04-30} {
+    clock format -526130704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/30/1953 12:34:56 die xxx mensis iv annoque mcmliii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Apr 120 2434498 04 iv  4 04/30/1953 die xxx mensis iv annoque mcmliii 53 liii 1953}
+test clock-2.633 {conversion of 1953-05-01} {
+    clock format -526044304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/01/1953 12:34:56 die i mensis v annoque mcmliii xii h xxxiv m lvi s 19 mcm 01 i  1 i May 121 2434499 05 v  5 05/01/1953 die i mensis v annoque mcmliii 53 liii 1953}
+test clock-2.634 {conversion of 1953-05-31} {
+    clock format -523452304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/31/1953 12:34:56 die xxxi mensis v annoque mcmliii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi May 151 2434529 05 v  5 05/31/1953 die xxxi mensis v annoque mcmliii 53 liii 1953}
+test clock-2.635 {conversion of 1953-06-01} {
+    clock format -523365904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/01/1953 12:34:56 die i mensis vi annoque mcmliii xii h xxxiv m lvi s 19 mcm 01 i  1 i Jun 152 2434530 06 vi  6 06/01/1953 die i mensis vi annoque mcmliii 53 liii 1953}
+test clock-2.636 {conversion of 1953-06-30} {
+    clock format -520860304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/30/1953 12:34:56 die xxx mensis vi annoque mcmliii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Jun 181 2434559 06 vi  6 06/30/1953 die xxx mensis vi annoque mcmliii 53 liii 1953}
+test clock-2.637 {conversion of 1953-07-01} {
+    clock format -520773904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/01/1953 12:34:56 die i mensis vii annoque mcmliii xii h xxxiv m lvi s 19 mcm 01 i  1 i Jul 182 2434560 07 vii  7 07/01/1953 die i mensis vii annoque mcmliii 53 liii 1953}
+test clock-2.638 {conversion of 1953-07-31} {
+    clock format -518181904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/31/1953 12:34:56 die xxxi mensis vii annoque mcmliii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jul 212 2434590 07 vii  7 07/31/1953 die xxxi mensis vii annoque mcmliii 53 liii 1953}
+test clock-2.639 {conversion of 1953-08-01} {
+    clock format -518095504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/01/1953 12:34:56 die i mensis viii annoque mcmliii xii h xxxiv m lvi s 19 mcm 01 i  1 i Aug 213 2434591 08 viii  8 08/01/1953 die i mensis viii annoque mcmliii 53 liii 1953}
+test clock-2.640 {conversion of 1953-08-31} {
+    clock format -515503504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/31/1953 12:34:56 die xxxi mensis viii annoque mcmliii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Aug 243 2434621 08 viii  8 08/31/1953 die xxxi mensis viii annoque mcmliii 53 liii 1953}
+test clock-2.641 {conversion of 1953-09-01} {
+    clock format -515417104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/01/1953 12:34:56 die i mensis ix annoque mcmliii xii h xxxiv m lvi s 19 mcm 01 i  1 i Sep 244 2434622 09 ix  9 09/01/1953 die i mensis ix annoque mcmliii 53 liii 1953}
+test clock-2.642 {conversion of 1953-09-30} {
+    clock format -512911504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/30/1953 12:34:56 die xxx mensis ix annoque mcmliii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Sep 273 2434651 09 ix  9 09/30/1953 die xxx mensis ix annoque mcmliii 53 liii 1953}
+test clock-2.643 {conversion of 1953-10-01} {
+    clock format -512825104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/01/1953 12:34:56 die i mensis x annoque mcmliii xii h xxxiv m lvi s 19 mcm 01 i  1 i Oct 274 2434652 10 x 10 10/01/1953 die i mensis x annoque mcmliii 53 liii 1953}
+test clock-2.644 {conversion of 1953-10-31} {
+    clock format -510233104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/31/1953 12:34:56 die xxxi mensis x annoque mcmliii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Oct 304 2434682 10 x 10 10/31/1953 die xxxi mensis x annoque mcmliii 53 liii 1953}
+test clock-2.645 {conversion of 1953-11-01} {
+    clock format -510146704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/01/1953 12:34:56 die i mensis xi annoque mcmliii xii h xxxiv m lvi s 19 mcm 01 i  1 i Nov 305 2434683 11 xi 11 11/01/1953 die i mensis xi annoque mcmliii 53 liii 1953}
+test clock-2.646 {conversion of 1953-11-30} {
+    clock format -507641104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/30/1953 12:34:56 die xxx mensis xi annoque mcmliii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Nov 334 2434712 11 xi 11 11/30/1953 die xxx mensis xi annoque mcmliii 53 liii 1953}
+test clock-2.647 {conversion of 1953-12-01} {
+    clock format -507554704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/01/1953 12:34:56 die i mensis xii annoque mcmliii xii h xxxiv m lvi s 19 mcm 01 i  1 i Dec 335 2434713 12 xii 12 12/01/1953 die i mensis xii annoque mcmliii 53 liii 1953}
+test clock-2.648 {conversion of 1953-12-31} {
+    clock format -504962704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/31/1953 12:34:56 die xxxi mensis xii annoque mcmliii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Dec 365 2434743 12 xii 12 12/31/1953 die xxxi mensis xii annoque mcmliii 53 liii 1953}
+test clock-2.649 {conversion of 1956-01-01} {
+    clock format -441804304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/01/1956 12:34:56 die i mensis i annoque mcmlvi xii h xxxiv m lvi s 19 mcm 01 i  1 i Jan 001 2435474 01 i  1 01/01/1956 die i mensis i annoque mcmlvi 56 lvi 1956}
+test clock-2.650 {conversion of 1956-01-31} {
+    clock format -439212304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/31/1956 12:34:56 die xxxi mensis i annoque mcmlvi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jan 031 2435504 01 i  1 01/31/1956 die xxxi mensis i annoque mcmlvi 56 lvi 1956}
+test clock-2.651 {conversion of 1956-02-01} {
+    clock format -439125904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/01/1956 12:34:56 die i mensis ii annoque mcmlvi xii h xxxiv m lvi s 19 mcm 01 i  1 i Feb 032 2435505 02 ii  2 02/01/1956 die i mensis ii annoque mcmlvi 56 lvi 1956}
+test clock-2.652 {conversion of 1956-02-29} {
+    clock format -436706704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/29/1956 12:34:56 die xxix mensis ii annoque mcmlvi xii h xxxiv m lvi s 19 mcm 29 xxix 29 xxix Feb 060 2435533 02 ii  2 02/29/1956 die xxix mensis ii annoque mcmlvi 56 lvi 1956}
+test clock-2.653 {conversion of 1956-03-01} {
+    clock format -436620304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/01/1956 12:34:56 die i mensis iii annoque mcmlvi xii h xxxiv m lvi s 19 mcm 01 i  1 i Mar 061 2435534 03 iii  3 03/01/1956 die i mensis iii annoque mcmlvi 56 lvi 1956}
+test clock-2.654 {conversion of 1956-03-31} {
+    clock format -434028304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/31/1956 12:34:56 die xxxi mensis iii annoque mcmlvi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Mar 091 2435564 03 iii  3 03/31/1956 die xxxi mensis iii annoque mcmlvi 56 lvi 1956}
+test clock-2.655 {conversion of 1956-04-01} {
+    clock format -433941904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/01/1956 12:34:56 die i mensis iv annoque mcmlvi xii h xxxiv m lvi s 19 mcm 01 i  1 i Apr 092 2435565 04 iv  4 04/01/1956 die i mensis iv annoque mcmlvi 56 lvi 1956}
+test clock-2.656 {conversion of 1956-04-30} {
+    clock format -431436304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/30/1956 12:34:56 die xxx mensis iv annoque mcmlvi xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Apr 121 2435594 04 iv  4 04/30/1956 die xxx mensis iv annoque mcmlvi 56 lvi 1956}
+test clock-2.657 {conversion of 1956-05-01} {
+    clock format -431349904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/01/1956 12:34:56 die i mensis v annoque mcmlvi xii h xxxiv m lvi s 19 mcm 01 i  1 i May 122 2435595 05 v  5 05/01/1956 die i mensis v annoque mcmlvi 56 lvi 1956}
+test clock-2.658 {conversion of 1956-05-31} {
+    clock format -428757904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/31/1956 12:34:56 die xxxi mensis v annoque mcmlvi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi May 152 2435625 05 v  5 05/31/1956 die xxxi mensis v annoque mcmlvi 56 lvi 1956}
+test clock-2.659 {conversion of 1956-06-01} {
+    clock format -428671504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/01/1956 12:34:56 die i mensis vi annoque mcmlvi xii h xxxiv m lvi s 19 mcm 01 i  1 i Jun 153 2435626 06 vi  6 06/01/1956 die i mensis vi annoque mcmlvi 56 lvi 1956}
+test clock-2.660 {conversion of 1956-06-30} {
+    clock format -426165904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/30/1956 12:34:56 die xxx mensis vi annoque mcmlvi xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Jun 182 2435655 06 vi  6 06/30/1956 die xxx mensis vi annoque mcmlvi 56 lvi 1956}
+test clock-2.661 {conversion of 1956-07-01} {
+    clock format -426079504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/01/1956 12:34:56 die i mensis vii annoque mcmlvi xii h xxxiv m lvi s 19 mcm 01 i  1 i Jul 183 2435656 07 vii  7 07/01/1956 die i mensis vii annoque mcmlvi 56 lvi 1956}
+test clock-2.662 {conversion of 1956-07-31} {
+    clock format -423487504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/31/1956 12:34:56 die xxxi mensis vii annoque mcmlvi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jul 213 2435686 07 vii  7 07/31/1956 die xxxi mensis vii annoque mcmlvi 56 lvi 1956}
+test clock-2.663 {conversion of 1956-08-01} {
+    clock format -423401104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/01/1956 12:34:56 die i mensis viii annoque mcmlvi xii h xxxiv m lvi s 19 mcm 01 i  1 i Aug 214 2435687 08 viii  8 08/01/1956 die i mensis viii annoque mcmlvi 56 lvi 1956}
+test clock-2.664 {conversion of 1956-08-31} {
+    clock format -420809104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/31/1956 12:34:56 die xxxi mensis viii annoque mcmlvi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Aug 244 2435717 08 viii  8 08/31/1956 die xxxi mensis viii annoque mcmlvi 56 lvi 1956}
+test clock-2.665 {conversion of 1956-09-01} {
+    clock format -420722704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/01/1956 12:34:56 die i mensis ix annoque mcmlvi xii h xxxiv m lvi s 19 mcm 01 i  1 i Sep 245 2435718 09 ix  9 09/01/1956 die i mensis ix annoque mcmlvi 56 lvi 1956}
+test clock-2.666 {conversion of 1956-09-30} {
+    clock format -418217104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/30/1956 12:34:56 die xxx mensis ix annoque mcmlvi xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Sep 274 2435747 09 ix  9 09/30/1956 die xxx mensis ix annoque mcmlvi 56 lvi 1956}
+test clock-2.667 {conversion of 1956-10-01} {
+    clock format -418130704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/01/1956 12:34:56 die i mensis x annoque mcmlvi xii h xxxiv m lvi s 19 mcm 01 i  1 i Oct 275 2435748 10 x 10 10/01/1956 die i mensis x annoque mcmlvi 56 lvi 1956}
+test clock-2.668 {conversion of 1956-10-31} {
+    clock format -415538704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/31/1956 12:34:56 die xxxi mensis x annoque mcmlvi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Oct 305 2435778 10 x 10 10/31/1956 die xxxi mensis x annoque mcmlvi 56 lvi 1956}
+test clock-2.669 {conversion of 1956-11-01} {
+    clock format -415452304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/01/1956 12:34:56 die i mensis xi annoque mcmlvi xii h xxxiv m lvi s 19 mcm 01 i  1 i Nov 306 2435779 11 xi 11 11/01/1956 die i mensis xi annoque mcmlvi 56 lvi 1956}
+test clock-2.670 {conversion of 1956-11-30} {
+    clock format -412946704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/30/1956 12:34:56 die xxx mensis xi annoque mcmlvi xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Nov 335 2435808 11 xi 11 11/30/1956 die xxx mensis xi annoque mcmlvi 56 lvi 1956}
+test clock-2.671 {conversion of 1956-12-01} {
+    clock format -412860304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/01/1956 12:34:56 die i mensis xii annoque mcmlvi xii h xxxiv m lvi s 19 mcm 01 i  1 i Dec 336 2435809 12 xii 12 12/01/1956 die i mensis xii annoque mcmlvi 56 lvi 1956}
+test clock-2.672 {conversion of 1956-12-31} {
+    clock format -410268304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/31/1956 12:34:56 die xxxi mensis xii annoque mcmlvi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Dec 366 2435839 12 xii 12 12/31/1956 die xxxi mensis xii annoque mcmlvi 56 lvi 1956}
+test clock-2.673 {conversion of 1957-01-01} {
+    clock format -410181904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/01/1957 12:34:56 die i mensis i annoque mcmlvii xii h xxxiv m lvi s 19 mcm 01 i  1 i Jan 001 2435840 01 i  1 01/01/1957 die i mensis i annoque mcmlvii 57 lvii 1957}
+test clock-2.674 {conversion of 1957-01-31} {
+    clock format -407589904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/31/1957 12:34:56 die xxxi mensis i annoque mcmlvii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jan 031 2435870 01 i  1 01/31/1957 die xxxi mensis i annoque mcmlvii 57 lvii 1957}
+test clock-2.675 {conversion of 1957-02-01} {
+    clock format -407503504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/01/1957 12:34:56 die i mensis ii annoque mcmlvii xii h xxxiv m lvi s 19 mcm 01 i  1 i Feb 032 2435871 02 ii  2 02/01/1957 die i mensis ii annoque mcmlvii 57 lvii 1957}
+test clock-2.676 {conversion of 1957-02-28} {
+    clock format -405170704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/28/1957 12:34:56 die xxviii mensis ii annoque mcmlvii xii h xxxiv m lvi s 19 mcm 28 xxviii 28 xxviii Feb 059 2435898 02 ii  2 02/28/1957 die xxviii mensis ii annoque mcmlvii 57 lvii 1957}
+test clock-2.677 {conversion of 1957-03-01} {
+    clock format -405084304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/01/1957 12:34:56 die i mensis iii annoque mcmlvii xii h xxxiv m lvi s 19 mcm 01 i  1 i Mar 060 2435899 03 iii  3 03/01/1957 die i mensis iii annoque mcmlvii 57 lvii 1957}
+test clock-2.678 {conversion of 1957-03-31} {
+    clock format -402492304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/31/1957 12:34:56 die xxxi mensis iii annoque mcmlvii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Mar 090 2435929 03 iii  3 03/31/1957 die xxxi mensis iii annoque mcmlvii 57 lvii 1957}
+test clock-2.679 {conversion of 1957-04-01} {
+    clock format -402405904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/01/1957 12:34:56 die i mensis iv annoque mcmlvii xii h xxxiv m lvi s 19 mcm 01 i  1 i Apr 091 2435930 04 iv  4 04/01/1957 die i mensis iv annoque mcmlvii 57 lvii 1957}
+test clock-2.680 {conversion of 1957-04-30} {
+    clock format -399900304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/30/1957 12:34:56 die xxx mensis iv annoque mcmlvii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Apr 120 2435959 04 iv  4 04/30/1957 die xxx mensis iv annoque mcmlvii 57 lvii 1957}
+test clock-2.681 {conversion of 1957-05-01} {
+    clock format -399813904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/01/1957 12:34:56 die i mensis v annoque mcmlvii xii h xxxiv m lvi s 19 mcm 01 i  1 i May 121 2435960 05 v  5 05/01/1957 die i mensis v annoque mcmlvii 57 lvii 1957}
+test clock-2.682 {conversion of 1957-05-31} {
+    clock format -397221904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/31/1957 12:34:56 die xxxi mensis v annoque mcmlvii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi May 151 2435990 05 v  5 05/31/1957 die xxxi mensis v annoque mcmlvii 57 lvii 1957}
+test clock-2.683 {conversion of 1957-06-01} {
+    clock format -397135504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/01/1957 12:34:56 die i mensis vi annoque mcmlvii xii h xxxiv m lvi s 19 mcm 01 i  1 i Jun 152 2435991 06 vi  6 06/01/1957 die i mensis vi annoque mcmlvii 57 lvii 1957}
+test clock-2.684 {conversion of 1957-06-30} {
+    clock format -394629904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/30/1957 12:34:56 die xxx mensis vi annoque mcmlvii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Jun 181 2436020 06 vi  6 06/30/1957 die xxx mensis vi annoque mcmlvii 57 lvii 1957}
+test clock-2.685 {conversion of 1957-07-01} {
+    clock format -394543504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/01/1957 12:34:56 die i mensis vii annoque mcmlvii xii h xxxiv m lvi s 19 mcm 01 i  1 i Jul 182 2436021 07 vii  7 07/01/1957 die i mensis vii annoque mcmlvii 57 lvii 1957}
+test clock-2.686 {conversion of 1957-07-31} {
+    clock format -391951504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/31/1957 12:34:56 die xxxi mensis vii annoque mcmlvii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jul 212 2436051 07 vii  7 07/31/1957 die xxxi mensis vii annoque mcmlvii 57 lvii 1957}
+test clock-2.687 {conversion of 1957-08-01} {
+    clock format -391865104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/01/1957 12:34:56 die i mensis viii annoque mcmlvii xii h xxxiv m lvi s 19 mcm 01 i  1 i Aug 213 2436052 08 viii  8 08/01/1957 die i mensis viii annoque mcmlvii 57 lvii 1957}
+test clock-2.688 {conversion of 1957-08-31} {
+    clock format -389273104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/31/1957 12:34:56 die xxxi mensis viii annoque mcmlvii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Aug 243 2436082 08 viii  8 08/31/1957 die xxxi mensis viii annoque mcmlvii 57 lvii 1957}
+test clock-2.689 {conversion of 1957-09-01} {
+    clock format -389186704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/01/1957 12:34:56 die i mensis ix annoque mcmlvii xii h xxxiv m lvi s 19 mcm 01 i  1 i Sep 244 2436083 09 ix  9 09/01/1957 die i mensis ix annoque mcmlvii 57 lvii 1957}
+test clock-2.690 {conversion of 1957-09-30} {
+    clock format -386681104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/30/1957 12:34:56 die xxx mensis ix annoque mcmlvii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Sep 273 2436112 09 ix  9 09/30/1957 die xxx mensis ix annoque mcmlvii 57 lvii 1957}
+test clock-2.691 {conversion of 1957-10-01} {
+    clock format -386594704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/01/1957 12:34:56 die i mensis x annoque mcmlvii xii h xxxiv m lvi s 19 mcm 01 i  1 i Oct 274 2436113 10 x 10 10/01/1957 die i mensis x annoque mcmlvii 57 lvii 1957}
+test clock-2.692 {conversion of 1957-10-31} {
+    clock format -384002704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/31/1957 12:34:56 die xxxi mensis x annoque mcmlvii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Oct 304 2436143 10 x 10 10/31/1957 die xxxi mensis x annoque mcmlvii 57 lvii 1957}
+test clock-2.693 {conversion of 1957-11-01} {
+    clock format -383916304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/01/1957 12:34:56 die i mensis xi annoque mcmlvii xii h xxxiv m lvi s 19 mcm 01 i  1 i Nov 305 2436144 11 xi 11 11/01/1957 die i mensis xi annoque mcmlvii 57 lvii 1957}
+test clock-2.694 {conversion of 1957-11-30} {
+    clock format -381410704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/30/1957 12:34:56 die xxx mensis xi annoque mcmlvii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Nov 334 2436173 11 xi 11 11/30/1957 die xxx mensis xi annoque mcmlvii 57 lvii 1957}
+test clock-2.695 {conversion of 1957-12-01} {
+    clock format -381324304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/01/1957 12:34:56 die i mensis xii annoque mcmlvii xii h xxxiv m lvi s 19 mcm 01 i  1 i Dec 335 2436174 12 xii 12 12/01/1957 die i mensis xii annoque mcmlvii 57 lvii 1957}
+test clock-2.696 {conversion of 1957-12-31} {
+    clock format -378732304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/31/1957 12:34:56 die xxxi mensis xii annoque mcmlvii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Dec 365 2436204 12 xii 12 12/31/1957 die xxxi mensis xii annoque mcmlvii 57 lvii 1957}
+test clock-2.697 {conversion of 1959-01-01} {
+    clock format -347109904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/01/1959 12:34:56 die i mensis i annoque mcmlix xii h xxxiv m lvi s 19 mcm 01 i  1 i Jan 001 2436570 01 i  1 01/01/1959 die i mensis i annoque mcmlix 59 lix 1959}
+test clock-2.698 {conversion of 1959-01-31} {
+    clock format -344517904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/31/1959 12:34:56 die xxxi mensis i annoque mcmlix xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jan 031 2436600 01 i  1 01/31/1959 die xxxi mensis i annoque mcmlix 59 lix 1959}
+test clock-2.699 {conversion of 1959-02-01} {
+    clock format -344431504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/01/1959 12:34:56 die i mensis ii annoque mcmlix xii h xxxiv m lvi s 19 mcm 01 i  1 i Feb 032 2436601 02 ii  2 02/01/1959 die i mensis ii annoque mcmlix 59 lix 1959}
+test clock-2.700 {conversion of 1959-02-28} {
+    clock format -342098704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/28/1959 12:34:56 die xxviii mensis ii annoque mcmlix xii h xxxiv m lvi s 19 mcm 28 xxviii 28 xxviii Feb 059 2436628 02 ii  2 02/28/1959 die xxviii mensis ii annoque mcmlix 59 lix 1959}
+test clock-2.701 {conversion of 1959-03-01} {
+    clock format -342012304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/01/1959 12:34:56 die i mensis iii annoque mcmlix xii h xxxiv m lvi s 19 mcm 01 i  1 i Mar 060 2436629 03 iii  3 03/01/1959 die i mensis iii annoque mcmlix 59 lix 1959}
+test clock-2.702 {conversion of 1959-03-31} {
+    clock format -339420304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/31/1959 12:34:56 die xxxi mensis iii annoque mcmlix xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Mar 090 2436659 03 iii  3 03/31/1959 die xxxi mensis iii annoque mcmlix 59 lix 1959}
+test clock-2.703 {conversion of 1959-04-01} {
+    clock format -339333904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/01/1959 12:34:56 die i mensis iv annoque mcmlix xii h xxxiv m lvi s 19 mcm 01 i  1 i Apr 091 2436660 04 iv  4 04/01/1959 die i mensis iv annoque mcmlix 59 lix 1959}
+test clock-2.704 {conversion of 1959-04-30} {
+    clock format -336828304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/30/1959 12:34:56 die xxx mensis iv annoque mcmlix xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Apr 120 2436689 04 iv  4 04/30/1959 die xxx mensis iv annoque mcmlix 59 lix 1959}
+test clock-2.705 {conversion of 1959-05-01} {
+    clock format -336741904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/01/1959 12:34:56 die i mensis v annoque mcmlix xii h xxxiv m lvi s 19 mcm 01 i  1 i May 121 2436690 05 v  5 05/01/1959 die i mensis v annoque mcmlix 59 lix 1959}
+test clock-2.706 {conversion of 1959-05-31} {
+    clock format -334149904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/31/1959 12:34:56 die xxxi mensis v annoque mcmlix xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi May 151 2436720 05 v  5 05/31/1959 die xxxi mensis v annoque mcmlix 59 lix 1959}
+test clock-2.707 {conversion of 1959-06-01} {
+    clock format -334063504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/01/1959 12:34:56 die i mensis vi annoque mcmlix xii h xxxiv m lvi s 19 mcm 01 i  1 i Jun 152 2436721 06 vi  6 06/01/1959 die i mensis vi annoque mcmlix 59 lix 1959}
+test clock-2.708 {conversion of 1959-06-30} {
+    clock format -331557904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/30/1959 12:34:56 die xxx mensis vi annoque mcmlix xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Jun 181 2436750 06 vi  6 06/30/1959 die xxx mensis vi annoque mcmlix 59 lix 1959}
+test clock-2.709 {conversion of 1959-07-01} {
+    clock format -331471504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/01/1959 12:34:56 die i mensis vii annoque mcmlix xii h xxxiv m lvi s 19 mcm 01 i  1 i Jul 182 2436751 07 vii  7 07/01/1959 die i mensis vii annoque mcmlix 59 lix 1959}
+test clock-2.710 {conversion of 1959-07-31} {
+    clock format -328879504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/31/1959 12:34:56 die xxxi mensis vii annoque mcmlix xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jul 212 2436781 07 vii  7 07/31/1959 die xxxi mensis vii annoque mcmlix 59 lix 1959}
+test clock-2.711 {conversion of 1959-08-01} {
+    clock format -328793104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/01/1959 12:34:56 die i mensis viii annoque mcmlix xii h xxxiv m lvi s 19 mcm 01 i  1 i Aug 213 2436782 08 viii  8 08/01/1959 die i mensis viii annoque mcmlix 59 lix 1959}
+test clock-2.712 {conversion of 1959-08-31} {
+    clock format -326201104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/31/1959 12:34:56 die xxxi mensis viii annoque mcmlix xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Aug 243 2436812 08 viii  8 08/31/1959 die xxxi mensis viii annoque mcmlix 59 lix 1959}
+test clock-2.713 {conversion of 1959-09-01} {
+    clock format -326114704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/01/1959 12:34:56 die i mensis ix annoque mcmlix xii h xxxiv m lvi s 19 mcm 01 i  1 i Sep 244 2436813 09 ix  9 09/01/1959 die i mensis ix annoque mcmlix 59 lix 1959}
+test clock-2.714 {conversion of 1959-09-30} {
+    clock format -323609104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/30/1959 12:34:56 die xxx mensis ix annoque mcmlix xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Sep 273 2436842 09 ix  9 09/30/1959 die xxx mensis ix annoque mcmlix 59 lix 1959}
+test clock-2.715 {conversion of 1959-10-01} {
+    clock format -323522704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/01/1959 12:34:56 die i mensis x annoque mcmlix xii h xxxiv m lvi s 19 mcm 01 i  1 i Oct 274 2436843 10 x 10 10/01/1959 die i mensis x annoque mcmlix 59 lix 1959}
+test clock-2.716 {conversion of 1959-10-31} {
+    clock format -320930704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/31/1959 12:34:56 die xxxi mensis x annoque mcmlix xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Oct 304 2436873 10 x 10 10/31/1959 die xxxi mensis x annoque mcmlix 59 lix 1959}
+test clock-2.717 {conversion of 1959-11-01} {
+    clock format -320844304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/01/1959 12:34:56 die i mensis xi annoque mcmlix xii h xxxiv m lvi s 19 mcm 01 i  1 i Nov 305 2436874 11 xi 11 11/01/1959 die i mensis xi annoque mcmlix 59 lix 1959}
+test clock-2.718 {conversion of 1959-11-30} {
+    clock format -318338704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/30/1959 12:34:56 die xxx mensis xi annoque mcmlix xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Nov 334 2436903 11 xi 11 11/30/1959 die xxx mensis xi annoque mcmlix 59 lix 1959}
+test clock-2.719 {conversion of 1959-12-01} {
+    clock format -318252304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/01/1959 12:34:56 die i mensis xii annoque mcmlix xii h xxxiv m lvi s 19 mcm 01 i  1 i Dec 335 2436904 12 xii 12 12/01/1959 die i mensis xii annoque mcmlix 59 lix 1959}
+test clock-2.720 {conversion of 1959-12-31} {
+    clock format -315660304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/31/1959 12:34:56 die xxxi mensis xii annoque mcmlix xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Dec 365 2436934 12 xii 12 12/31/1959 die xxxi mensis xii annoque mcmlix 59 lix 1959}
+test clock-2.721 {conversion of 1960-01-01} {
+    clock format -315573904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/01/1960 12:34:56 die i mensis i annoque mcmlx xii h xxxiv m lvi s 19 mcm 01 i  1 i Jan 001 2436935 01 i  1 01/01/1960 die i mensis i annoque mcmlx 60 lx 1960}
+test clock-2.722 {conversion of 1960-01-31} {
+    clock format -312981904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/31/1960 12:34:56 die xxxi mensis i annoque mcmlx xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jan 031 2436965 01 i  1 01/31/1960 die xxxi mensis i annoque mcmlx 60 lx 1960}
+test clock-2.723 {conversion of 1960-02-01} {
+    clock format -312895504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/01/1960 12:34:56 die i mensis ii annoque mcmlx xii h xxxiv m lvi s 19 mcm 01 i  1 i Feb 032 2436966 02 ii  2 02/01/1960 die i mensis ii annoque mcmlx 60 lx 1960}
+test clock-2.724 {conversion of 1960-02-29} {
+    clock format -310476304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/29/1960 12:34:56 die xxix mensis ii annoque mcmlx xii h xxxiv m lvi s 19 mcm 29 xxix 29 xxix Feb 060 2436994 02 ii  2 02/29/1960 die xxix mensis ii annoque mcmlx 60 lx 1960}
+test clock-2.725 {conversion of 1960-03-01} {
+    clock format -310389904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/01/1960 12:34:56 die i mensis iii annoque mcmlx xii h xxxiv m lvi s 19 mcm 01 i  1 i Mar 061 2436995 03 iii  3 03/01/1960 die i mensis iii annoque mcmlx 60 lx 1960}
+test clock-2.726 {conversion of 1960-03-31} {
+    clock format -307797904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/31/1960 12:34:56 die xxxi mensis iii annoque mcmlx xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Mar 091 2437025 03 iii  3 03/31/1960 die xxxi mensis iii annoque mcmlx 60 lx 1960}
+test clock-2.727 {conversion of 1960-04-01} {
+    clock format -307711504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/01/1960 12:34:56 die i mensis iv annoque mcmlx xii h xxxiv m lvi s 19 mcm 01 i  1 i Apr 092 2437026 04 iv  4 04/01/1960 die i mensis iv annoque mcmlx 60 lx 1960}
+test clock-2.728 {conversion of 1960-04-30} {
+    clock format -305205904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/30/1960 12:34:56 die xxx mensis iv annoque mcmlx xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Apr 121 2437055 04 iv  4 04/30/1960 die xxx mensis iv annoque mcmlx 60 lx 1960}
+test clock-2.729 {conversion of 1960-05-01} {
+    clock format -305119504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/01/1960 12:34:56 die i mensis v annoque mcmlx xii h xxxiv m lvi s 19 mcm 01 i  1 i May 122 2437056 05 v  5 05/01/1960 die i mensis v annoque mcmlx 60 lx 1960}
+test clock-2.730 {conversion of 1960-05-31} {
+    clock format -302527504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/31/1960 12:34:56 die xxxi mensis v annoque mcmlx xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi May 152 2437086 05 v  5 05/31/1960 die xxxi mensis v annoque mcmlx 60 lx 1960}
+test clock-2.731 {conversion of 1960-06-01} {
+    clock format -302441104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/01/1960 12:34:56 die i mensis vi annoque mcmlx xii h xxxiv m lvi s 19 mcm 01 i  1 i Jun 153 2437087 06 vi  6 06/01/1960 die i mensis vi annoque mcmlx 60 lx 1960}
+test clock-2.732 {conversion of 1960-06-30} {
+    clock format -299935504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/30/1960 12:34:56 die xxx mensis vi annoque mcmlx xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Jun 182 2437116 06 vi  6 06/30/1960 die xxx mensis vi annoque mcmlx 60 lx 1960}
+test clock-2.733 {conversion of 1960-07-01} {
+    clock format -299849104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/01/1960 12:34:56 die i mensis vii annoque mcmlx xii h xxxiv m lvi s 19 mcm 01 i  1 i Jul 183 2437117 07 vii  7 07/01/1960 die i mensis vii annoque mcmlx 60 lx 1960}
+test clock-2.734 {conversion of 1960-07-31} {
+    clock format -297257104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/31/1960 12:34:56 die xxxi mensis vii annoque mcmlx xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jul 213 2437147 07 vii  7 07/31/1960 die xxxi mensis vii annoque mcmlx 60 lx 1960}
+test clock-2.735 {conversion of 1960-08-01} {
+    clock format -297170704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/01/1960 12:34:56 die i mensis viii annoque mcmlx xii h xxxiv m lvi s 19 mcm 01 i  1 i Aug 214 2437148 08 viii  8 08/01/1960 die i mensis viii annoque mcmlx 60 lx 1960}
+test clock-2.736 {conversion of 1960-08-31} {
+    clock format -294578704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/31/1960 12:34:56 die xxxi mensis viii annoque mcmlx xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Aug 244 2437178 08 viii  8 08/31/1960 die xxxi mensis viii annoque mcmlx 60 lx 1960}
+test clock-2.737 {conversion of 1960-09-01} {
+    clock format -294492304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/01/1960 12:34:56 die i mensis ix annoque mcmlx xii h xxxiv m lvi s 19 mcm 01 i  1 i Sep 245 2437179 09 ix  9 09/01/1960 die i mensis ix annoque mcmlx 60 lx 1960}
+test clock-2.738 {conversion of 1960-09-30} {
+    clock format -291986704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/30/1960 12:34:56 die xxx mensis ix annoque mcmlx xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Sep 274 2437208 09 ix  9 09/30/1960 die xxx mensis ix annoque mcmlx 60 lx 1960}
+test clock-2.739 {conversion of 1960-10-01} {
+    clock format -291900304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/01/1960 12:34:56 die i mensis x annoque mcmlx xii h xxxiv m lvi s 19 mcm 01 i  1 i Oct 275 2437209 10 x 10 10/01/1960 die i mensis x annoque mcmlx 60 lx 1960}
+test clock-2.740 {conversion of 1960-10-31} {
+    clock format -289308304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/31/1960 12:34:56 die xxxi mensis x annoque mcmlx xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Oct 305 2437239 10 x 10 10/31/1960 die xxxi mensis x annoque mcmlx 60 lx 1960}
+test clock-2.741 {conversion of 1960-11-01} {
+    clock format -289221904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/01/1960 12:34:56 die i mensis xi annoque mcmlx xii h xxxiv m lvi s 19 mcm 01 i  1 i Nov 306 2437240 11 xi 11 11/01/1960 die i mensis xi annoque mcmlx 60 lx 1960}
+test clock-2.742 {conversion of 1960-11-30} {
+    clock format -286716304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/30/1960 12:34:56 die xxx mensis xi annoque mcmlx xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Nov 335 2437269 11 xi 11 11/30/1960 die xxx mensis xi annoque mcmlx 60 lx 1960}
+test clock-2.743 {conversion of 1960-12-01} {
+    clock format -286629904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/01/1960 12:34:56 die i mensis xii annoque mcmlx xii h xxxiv m lvi s 19 mcm 01 i  1 i Dec 336 2437270 12 xii 12 12/01/1960 die i mensis xii annoque mcmlx 60 lx 1960}
+test clock-2.744 {conversion of 1960-12-31} {
+    clock format -284037904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/31/1960 12:34:56 die xxxi mensis xii annoque mcmlx xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Dec 366 2437300 12 xii 12 12/31/1960 die xxxi mensis xii annoque mcmlx 60 lx 1960}
+test clock-2.745 {conversion of 1961-01-01} {
+    clock format -283951504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/01/1961 12:34:56 die i mensis i annoque mcmlxi xii h xxxiv m lvi s 19 mcm 01 i  1 i Jan 001 2437301 01 i  1 01/01/1961 die i mensis i annoque mcmlxi 61 lxi 1961}
+test clock-2.746 {conversion of 1961-01-31} {
+    clock format -281359504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/31/1961 12:34:56 die xxxi mensis i annoque mcmlxi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jan 031 2437331 01 i  1 01/31/1961 die xxxi mensis i annoque mcmlxi 61 lxi 1961}
+test clock-2.747 {conversion of 1961-02-01} {
+    clock format -281273104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/01/1961 12:34:56 die i mensis ii annoque mcmlxi xii h xxxiv m lvi s 19 mcm 01 i  1 i Feb 032 2437332 02 ii  2 02/01/1961 die i mensis ii annoque mcmlxi 61 lxi 1961}
+test clock-2.748 {conversion of 1961-02-28} {
+    clock format -278940304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/28/1961 12:34:56 die xxviii mensis ii annoque mcmlxi xii h xxxiv m lvi s 19 mcm 28 xxviii 28 xxviii Feb 059 2437359 02 ii  2 02/28/1961 die xxviii mensis ii annoque mcmlxi 61 lxi 1961}
+test clock-2.749 {conversion of 1961-03-01} {
+    clock format -278853904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/01/1961 12:34:56 die i mensis iii annoque mcmlxi xii h xxxiv m lvi s 19 mcm 01 i  1 i Mar 060 2437360 03 iii  3 03/01/1961 die i mensis iii annoque mcmlxi 61 lxi 1961}
+test clock-2.750 {conversion of 1961-03-31} {
+    clock format -276261904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/31/1961 12:34:56 die xxxi mensis iii annoque mcmlxi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Mar 090 2437390 03 iii  3 03/31/1961 die xxxi mensis iii annoque mcmlxi 61 lxi 1961}
+test clock-2.751 {conversion of 1961-04-01} {
+    clock format -276175504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/01/1961 12:34:56 die i mensis iv annoque mcmlxi xii h xxxiv m lvi s 19 mcm 01 i  1 i Apr 091 2437391 04 iv  4 04/01/1961 die i mensis iv annoque mcmlxi 61 lxi 1961}
+test clock-2.752 {conversion of 1961-04-30} {
+    clock format -273669904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/30/1961 12:34:56 die xxx mensis iv annoque mcmlxi xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Apr 120 2437420 04 iv  4 04/30/1961 die xxx mensis iv annoque mcmlxi 61 lxi 1961}
+test clock-2.753 {conversion of 1961-05-01} {
+    clock format -273583504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/01/1961 12:34:56 die i mensis v annoque mcmlxi xii h xxxiv m lvi s 19 mcm 01 i  1 i May 121 2437421 05 v  5 05/01/1961 die i mensis v annoque mcmlxi 61 lxi 1961}
+test clock-2.754 {conversion of 1961-05-31} {
+    clock format -270991504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/31/1961 12:34:56 die xxxi mensis v annoque mcmlxi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi May 151 2437451 05 v  5 05/31/1961 die xxxi mensis v annoque mcmlxi 61 lxi 1961}
+test clock-2.755 {conversion of 1961-06-01} {
+    clock format -270905104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/01/1961 12:34:56 die i mensis vi annoque mcmlxi xii h xxxiv m lvi s 19 mcm 01 i  1 i Jun 152 2437452 06 vi  6 06/01/1961 die i mensis vi annoque mcmlxi 61 lxi 1961}
+test clock-2.756 {conversion of 1961-06-30} {
+    clock format -268399504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/30/1961 12:34:56 die xxx mensis vi annoque mcmlxi xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Jun 181 2437481 06 vi  6 06/30/1961 die xxx mensis vi annoque mcmlxi 61 lxi 1961}
+test clock-2.757 {conversion of 1961-07-01} {
+    clock format -268313104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/01/1961 12:34:56 die i mensis vii annoque mcmlxi xii h xxxiv m lvi s 19 mcm 01 i  1 i Jul 182 2437482 07 vii  7 07/01/1961 die i mensis vii annoque mcmlxi 61 lxi 1961}
+test clock-2.758 {conversion of 1961-07-31} {
+    clock format -265721104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/31/1961 12:34:56 die xxxi mensis vii annoque mcmlxi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jul 212 2437512 07 vii  7 07/31/1961 die xxxi mensis vii annoque mcmlxi 61 lxi 1961}
+test clock-2.759 {conversion of 1961-08-01} {
+    clock format -265634704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/01/1961 12:34:56 die i mensis viii annoque mcmlxi xii h xxxiv m lvi s 19 mcm 01 i  1 i Aug 213 2437513 08 viii  8 08/01/1961 die i mensis viii annoque mcmlxi 61 lxi 1961}
+test clock-2.760 {conversion of 1961-08-31} {
+    clock format -263042704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/31/1961 12:34:56 die xxxi mensis viii annoque mcmlxi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Aug 243 2437543 08 viii  8 08/31/1961 die xxxi mensis viii annoque mcmlxi 61 lxi 1961}
+test clock-2.761 {conversion of 1961-09-01} {
+    clock format -262956304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/01/1961 12:34:56 die i mensis ix annoque mcmlxi xii h xxxiv m lvi s 19 mcm 01 i  1 i Sep 244 2437544 09 ix  9 09/01/1961 die i mensis ix annoque mcmlxi 61 lxi 1961}
+test clock-2.762 {conversion of 1961-09-30} {
+    clock format -260450704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/30/1961 12:34:56 die xxx mensis ix annoque mcmlxi xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Sep 273 2437573 09 ix  9 09/30/1961 die xxx mensis ix annoque mcmlxi 61 lxi 1961}
+test clock-2.763 {conversion of 1961-10-01} {
+    clock format -260364304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/01/1961 12:34:56 die i mensis x annoque mcmlxi xii h xxxiv m lvi s 19 mcm 01 i  1 i Oct 274 2437574 10 x 10 10/01/1961 die i mensis x annoque mcmlxi 61 lxi 1961}
+test clock-2.764 {conversion of 1961-10-31} {
+    clock format -257772304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/31/1961 12:34:56 die xxxi mensis x annoque mcmlxi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Oct 304 2437604 10 x 10 10/31/1961 die xxxi mensis x annoque mcmlxi 61 lxi 1961}
+test clock-2.765 {conversion of 1961-11-01} {
+    clock format -257685904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/01/1961 12:34:56 die i mensis xi annoque mcmlxi xii h xxxiv m lvi s 19 mcm 01 i  1 i Nov 305 2437605 11 xi 11 11/01/1961 die i mensis xi annoque mcmlxi 61 lxi 1961}
+test clock-2.766 {conversion of 1961-11-30} {
+    clock format -255180304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/30/1961 12:34:56 die xxx mensis xi annoque mcmlxi xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Nov 334 2437634 11 xi 11 11/30/1961 die xxx mensis xi annoque mcmlxi 61 lxi 1961}
+test clock-2.767 {conversion of 1961-12-01} {
+    clock format -255093904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/01/1961 12:34:56 die i mensis xii annoque mcmlxi xii h xxxiv m lvi s 19 mcm 01 i  1 i Dec 335 2437635 12 xii 12 12/01/1961 die i mensis xii annoque mcmlxi 61 lxi 1961}
+test clock-2.768 {conversion of 1961-12-31} {
+    clock format -252501904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/31/1961 12:34:56 die xxxi mensis xii annoque mcmlxi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Dec 365 2437665 12 xii 12 12/31/1961 die xxxi mensis xii annoque mcmlxi 61 lxi 1961}
+test clock-2.769 {conversion of 1962-01-01} {
+    clock format -252415504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/01/1962 12:34:56 die i mensis i annoque mcmlxii xii h xxxiv m lvi s 19 mcm 01 i  1 i Jan 001 2437666 01 i  1 01/01/1962 die i mensis i annoque mcmlxii 62 lxii 1962}
+test clock-2.770 {conversion of 1962-01-31} {
+    clock format -249823504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/31/1962 12:34:56 die xxxi mensis i annoque mcmlxii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jan 031 2437696 01 i  1 01/31/1962 die xxxi mensis i annoque mcmlxii 62 lxii 1962}
+test clock-2.771 {conversion of 1962-02-01} {
+    clock format -249737104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/01/1962 12:34:56 die i mensis ii annoque mcmlxii xii h xxxiv m lvi s 19 mcm 01 i  1 i Feb 032 2437697 02 ii  2 02/01/1962 die i mensis ii annoque mcmlxii 62 lxii 1962}
+test clock-2.772 {conversion of 1962-02-28} {
+    clock format -247404304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/28/1962 12:34:56 die xxviii mensis ii annoque mcmlxii xii h xxxiv m lvi s 19 mcm 28 xxviii 28 xxviii Feb 059 2437724 02 ii  2 02/28/1962 die xxviii mensis ii annoque mcmlxii 62 lxii 1962}
+test clock-2.773 {conversion of 1962-03-01} {
+    clock format -247317904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/01/1962 12:34:56 die i mensis iii annoque mcmlxii xii h xxxiv m lvi s 19 mcm 01 i  1 i Mar 060 2437725 03 iii  3 03/01/1962 die i mensis iii annoque mcmlxii 62 lxii 1962}
+test clock-2.774 {conversion of 1962-03-31} {
+    clock format -244725904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/31/1962 12:34:56 die xxxi mensis iii annoque mcmlxii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Mar 090 2437755 03 iii  3 03/31/1962 die xxxi mensis iii annoque mcmlxii 62 lxii 1962}
+test clock-2.775 {conversion of 1962-04-01} {
+    clock format -244639504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/01/1962 12:34:56 die i mensis iv annoque mcmlxii xii h xxxiv m lvi s 19 mcm 01 i  1 i Apr 091 2437756 04 iv  4 04/01/1962 die i mensis iv annoque mcmlxii 62 lxii 1962}
+test clock-2.776 {conversion of 1962-04-30} {
+    clock format -242133904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/30/1962 12:34:56 die xxx mensis iv annoque mcmlxii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Apr 120 2437785 04 iv  4 04/30/1962 die xxx mensis iv annoque mcmlxii 62 lxii 1962}
+test clock-2.777 {conversion of 1962-05-01} {
+    clock format -242047504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/01/1962 12:34:56 die i mensis v annoque mcmlxii xii h xxxiv m lvi s 19 mcm 01 i  1 i May 121 2437786 05 v  5 05/01/1962 die i mensis v annoque mcmlxii 62 lxii 1962}
+test clock-2.778 {conversion of 1962-05-31} {
+    clock format -239455504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/31/1962 12:34:56 die xxxi mensis v annoque mcmlxii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi May 151 2437816 05 v  5 05/31/1962 die xxxi mensis v annoque mcmlxii 62 lxii 1962}
+test clock-2.779 {conversion of 1962-06-01} {
+    clock format -239369104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/01/1962 12:34:56 die i mensis vi annoque mcmlxii xii h xxxiv m lvi s 19 mcm 01 i  1 i Jun 152 2437817 06 vi  6 06/01/1962 die i mensis vi annoque mcmlxii 62 lxii 1962}
+test clock-2.780 {conversion of 1962-06-30} {
+    clock format -236863504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/30/1962 12:34:56 die xxx mensis vi annoque mcmlxii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Jun 181 2437846 06 vi  6 06/30/1962 die xxx mensis vi annoque mcmlxii 62 lxii 1962}
+test clock-2.781 {conversion of 1962-07-01} {
+    clock format -236777104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/01/1962 12:34:56 die i mensis vii annoque mcmlxii xii h xxxiv m lvi s 19 mcm 01 i  1 i Jul 182 2437847 07 vii  7 07/01/1962 die i mensis vii annoque mcmlxii 62 lxii 1962}
+test clock-2.782 {conversion of 1962-07-31} {
+    clock format -234185104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/31/1962 12:34:56 die xxxi mensis vii annoque mcmlxii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jul 212 2437877 07 vii  7 07/31/1962 die xxxi mensis vii annoque mcmlxii 62 lxii 1962}
+test clock-2.783 {conversion of 1962-08-01} {
+    clock format -234098704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/01/1962 12:34:56 die i mensis viii annoque mcmlxii xii h xxxiv m lvi s 19 mcm 01 i  1 i Aug 213 2437878 08 viii  8 08/01/1962 die i mensis viii annoque mcmlxii 62 lxii 1962}
+test clock-2.784 {conversion of 1962-08-31} {
+    clock format -231506704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/31/1962 12:34:56 die xxxi mensis viii annoque mcmlxii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Aug 243 2437908 08 viii  8 08/31/1962 die xxxi mensis viii annoque mcmlxii 62 lxii 1962}
+test clock-2.785 {conversion of 1962-09-01} {
+    clock format -231420304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/01/1962 12:34:56 die i mensis ix annoque mcmlxii xii h xxxiv m lvi s 19 mcm 01 i  1 i Sep 244 2437909 09 ix  9 09/01/1962 die i mensis ix annoque mcmlxii 62 lxii 1962}
+test clock-2.786 {conversion of 1962-09-30} {
+    clock format -228914704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/30/1962 12:34:56 die xxx mensis ix annoque mcmlxii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Sep 273 2437938 09 ix  9 09/30/1962 die xxx mensis ix annoque mcmlxii 62 lxii 1962}
+test clock-2.787 {conversion of 1962-10-01} {
+    clock format -228828304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/01/1962 12:34:56 die i mensis x annoque mcmlxii xii h xxxiv m lvi s 19 mcm 01 i  1 i Oct 274 2437939 10 x 10 10/01/1962 die i mensis x annoque mcmlxii 62 lxii 1962}
+test clock-2.788 {conversion of 1962-10-31} {
+    clock format -226236304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/31/1962 12:34:56 die xxxi mensis x annoque mcmlxii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Oct 304 2437969 10 x 10 10/31/1962 die xxxi mensis x annoque mcmlxii 62 lxii 1962}
+test clock-2.789 {conversion of 1962-11-01} {
+    clock format -226149904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/01/1962 12:34:56 die i mensis xi annoque mcmlxii xii h xxxiv m lvi s 19 mcm 01 i  1 i Nov 305 2437970 11 xi 11 11/01/1962 die i mensis xi annoque mcmlxii 62 lxii 1962}
+test clock-2.790 {conversion of 1962-11-30} {
+    clock format -223644304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/30/1962 12:34:56 die xxx mensis xi annoque mcmlxii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Nov 334 2437999 11 xi 11 11/30/1962 die xxx mensis xi annoque mcmlxii 62 lxii 1962}
+test clock-2.791 {conversion of 1962-12-01} {
+    clock format -223557904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/01/1962 12:34:56 die i mensis xii annoque mcmlxii xii h xxxiv m lvi s 19 mcm 01 i  1 i Dec 335 2438000 12 xii 12 12/01/1962 die i mensis xii annoque mcmlxii 62 lxii 1962}
+test clock-2.792 {conversion of 1962-12-31} {
+    clock format -220965904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/31/1962 12:34:56 die xxxi mensis xii annoque mcmlxii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Dec 365 2438030 12 xii 12 12/31/1962 die xxxi mensis xii annoque mcmlxii 62 lxii 1962}
+test clock-2.793 {conversion of 1963-01-01} {
+    clock format -220879504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/01/1963 12:34:56 die i mensis i annoque mcmlxiii xii h xxxiv m lvi s 19 mcm 01 i  1 i Jan 001 2438031 01 i  1 01/01/1963 die i mensis i annoque mcmlxiii 63 lxiii 1963}
+test clock-2.794 {conversion of 1963-01-31} {
+    clock format -218287504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/31/1963 12:34:56 die xxxi mensis i annoque mcmlxiii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jan 031 2438061 01 i  1 01/31/1963 die xxxi mensis i annoque mcmlxiii 63 lxiii 1963}
+test clock-2.795 {conversion of 1963-02-01} {
+    clock format -218201104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/01/1963 12:34:56 die i mensis ii annoque mcmlxiii xii h xxxiv m lvi s 19 mcm 01 i  1 i Feb 032 2438062 02 ii  2 02/01/1963 die i mensis ii annoque mcmlxiii 63 lxiii 1963}
+test clock-2.796 {conversion of 1963-02-28} {
+    clock format -215868304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/28/1963 12:34:56 die xxviii mensis ii annoque mcmlxiii xii h xxxiv m lvi s 19 mcm 28 xxviii 28 xxviii Feb 059 2438089 02 ii  2 02/28/1963 die xxviii mensis ii annoque mcmlxiii 63 lxiii 1963}
+test clock-2.797 {conversion of 1963-03-01} {
+    clock format -215781904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/01/1963 12:34:56 die i mensis iii annoque mcmlxiii xii h xxxiv m lvi s 19 mcm 01 i  1 i Mar 060 2438090 03 iii  3 03/01/1963 die i mensis iii annoque mcmlxiii 63 lxiii 1963}
+test clock-2.798 {conversion of 1963-03-31} {
+    clock format -213189904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/31/1963 12:34:56 die xxxi mensis iii annoque mcmlxiii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Mar 090 2438120 03 iii  3 03/31/1963 die xxxi mensis iii annoque mcmlxiii 63 lxiii 1963}
+test clock-2.799 {conversion of 1963-04-01} {
+    clock format -213103504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/01/1963 12:34:56 die i mensis iv annoque mcmlxiii xii h xxxiv m lvi s 19 mcm 01 i  1 i Apr 091 2438121 04 iv  4 04/01/1963 die i mensis iv annoque mcmlxiii 63 lxiii 1963}
+test clock-2.800 {conversion of 1963-04-30} {
+    clock format -210597904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/30/1963 12:34:56 die xxx mensis iv annoque mcmlxiii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Apr 120 2438150 04 iv  4 04/30/1963 die xxx mensis iv annoque mcmlxiii 63 lxiii 1963}
+test clock-2.801 {conversion of 1963-05-01} {
+    clock format -210511504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/01/1963 12:34:56 die i mensis v annoque mcmlxiii xii h xxxiv m lvi s 19 mcm 01 i  1 i May 121 2438151 05 v  5 05/01/1963 die i mensis v annoque mcmlxiii 63 lxiii 1963}
+test clock-2.802 {conversion of 1963-05-31} {
+    clock format -207919504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/31/1963 12:34:56 die xxxi mensis v annoque mcmlxiii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi May 151 2438181 05 v  5 05/31/1963 die xxxi mensis v annoque mcmlxiii 63 lxiii 1963}
+test clock-2.803 {conversion of 1963-06-01} {
+    clock format -207833104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/01/1963 12:34:56 die i mensis vi annoque mcmlxiii xii h xxxiv m lvi s 19 mcm 01 i  1 i Jun 152 2438182 06 vi  6 06/01/1963 die i mensis vi annoque mcmlxiii 63 lxiii 1963}
+test clock-2.804 {conversion of 1963-06-30} {
+    clock format -205327504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/30/1963 12:34:56 die xxx mensis vi annoque mcmlxiii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Jun 181 2438211 06 vi  6 06/30/1963 die xxx mensis vi annoque mcmlxiii 63 lxiii 1963}
+test clock-2.805 {conversion of 1963-07-01} {
+    clock format -205241104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/01/1963 12:34:56 die i mensis vii annoque mcmlxiii xii h xxxiv m lvi s 19 mcm 01 i  1 i Jul 182 2438212 07 vii  7 07/01/1963 die i mensis vii annoque mcmlxiii 63 lxiii 1963}
+test clock-2.806 {conversion of 1963-07-31} {
+    clock format -202649104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/31/1963 12:34:56 die xxxi mensis vii annoque mcmlxiii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jul 212 2438242 07 vii  7 07/31/1963 die xxxi mensis vii annoque mcmlxiii 63 lxiii 1963}
+test clock-2.807 {conversion of 1963-08-01} {
+    clock format -202562704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/01/1963 12:34:56 die i mensis viii annoque mcmlxiii xii h xxxiv m lvi s 19 mcm 01 i  1 i Aug 213 2438243 08 viii  8 08/01/1963 die i mensis viii annoque mcmlxiii 63 lxiii 1963}
+test clock-2.808 {conversion of 1963-08-31} {
+    clock format -199970704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/31/1963 12:34:56 die xxxi mensis viii annoque mcmlxiii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Aug 243 2438273 08 viii  8 08/31/1963 die xxxi mensis viii annoque mcmlxiii 63 lxiii 1963}
+test clock-2.809 {conversion of 1963-09-01} {
+    clock format -199884304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/01/1963 12:34:56 die i mensis ix annoque mcmlxiii xii h xxxiv m lvi s 19 mcm 01 i  1 i Sep 244 2438274 09 ix  9 09/01/1963 die i mensis ix annoque mcmlxiii 63 lxiii 1963}
+test clock-2.810 {conversion of 1963-09-30} {
+    clock format -197378704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/30/1963 12:34:56 die xxx mensis ix annoque mcmlxiii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Sep 273 2438303 09 ix  9 09/30/1963 die xxx mensis ix annoque mcmlxiii 63 lxiii 1963}
+test clock-2.811 {conversion of 1963-10-01} {
+    clock format -197292304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/01/1963 12:34:56 die i mensis x annoque mcmlxiii xii h xxxiv m lvi s 19 mcm 01 i  1 i Oct 274 2438304 10 x 10 10/01/1963 die i mensis x annoque mcmlxiii 63 lxiii 1963}
+test clock-2.812 {conversion of 1963-10-31} {
+    clock format -194700304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/31/1963 12:34:56 die xxxi mensis x annoque mcmlxiii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Oct 304 2438334 10 x 10 10/31/1963 die xxxi mensis x annoque mcmlxiii 63 lxiii 1963}
+test clock-2.813 {conversion of 1963-11-01} {
+    clock format -194613904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/01/1963 12:34:56 die i mensis xi annoque mcmlxiii xii h xxxiv m lvi s 19 mcm 01 i  1 i Nov 305 2438335 11 xi 11 11/01/1963 die i mensis xi annoque mcmlxiii 63 lxiii 1963}
+test clock-2.814 {conversion of 1963-11-30} {
+    clock format -192108304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/30/1963 12:34:56 die xxx mensis xi annoque mcmlxiii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Nov 334 2438364 11 xi 11 11/30/1963 die xxx mensis xi annoque mcmlxiii 63 lxiii 1963}
+test clock-2.815 {conversion of 1963-12-01} {
+    clock format -192021904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/01/1963 12:34:56 die i mensis xii annoque mcmlxiii xii h xxxiv m lvi s 19 mcm 01 i  1 i Dec 335 2438365 12 xii 12 12/01/1963 die i mensis xii annoque mcmlxiii 63 lxiii 1963}
+test clock-2.816 {conversion of 1963-12-31} {
+    clock format -189429904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/31/1963 12:34:56 die xxxi mensis xii annoque mcmlxiii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Dec 365 2438395 12 xii 12 12/31/1963 die xxxi mensis xii annoque mcmlxiii 63 lxiii 1963}
+test clock-2.817 {conversion of 1964-01-01} {
+    clock format -189343504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/01/1964 12:34:56 die i mensis i annoque mcmlxiv xii h xxxiv m lvi s 19 mcm 01 i  1 i Jan 001 2438396 01 i  1 01/01/1964 die i mensis i annoque mcmlxiv 64 lxiv 1964}
+test clock-2.818 {conversion of 1964-01-31} {
+    clock format -186751504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/31/1964 12:34:56 die xxxi mensis i annoque mcmlxiv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jan 031 2438426 01 i  1 01/31/1964 die xxxi mensis i annoque mcmlxiv 64 lxiv 1964}
+test clock-2.819 {conversion of 1964-02-01} {
+    clock format -186665104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/01/1964 12:34:56 die i mensis ii annoque mcmlxiv xii h xxxiv m lvi s 19 mcm 01 i  1 i Feb 032 2438427 02 ii  2 02/01/1964 die i mensis ii annoque mcmlxiv 64 lxiv 1964}
+test clock-2.820 {conversion of 1964-02-29} {
+    clock format -184245904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/29/1964 12:34:56 die xxix mensis ii annoque mcmlxiv xii h xxxiv m lvi s 19 mcm 29 xxix 29 xxix Feb 060 2438455 02 ii  2 02/29/1964 die xxix mensis ii annoque mcmlxiv 64 lxiv 1964}
+test clock-2.821 {conversion of 1964-03-01} {
+    clock format -184159504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/01/1964 12:34:56 die i mensis iii annoque mcmlxiv xii h xxxiv m lvi s 19 mcm 01 i  1 i Mar 061 2438456 03 iii  3 03/01/1964 die i mensis iii annoque mcmlxiv 64 lxiv 1964}
+test clock-2.822 {conversion of 1964-03-31} {
+    clock format -181567504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/31/1964 12:34:56 die xxxi mensis iii annoque mcmlxiv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Mar 091 2438486 03 iii  3 03/31/1964 die xxxi mensis iii annoque mcmlxiv 64 lxiv 1964}
+test clock-2.823 {conversion of 1964-04-01} {
+    clock format -181481104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/01/1964 12:34:56 die i mensis iv annoque mcmlxiv xii h xxxiv m lvi s 19 mcm 01 i  1 i Apr 092 2438487 04 iv  4 04/01/1964 die i mensis iv annoque mcmlxiv 64 lxiv 1964}
+test clock-2.824 {conversion of 1964-04-30} {
+    clock format -178975504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/30/1964 12:34:56 die xxx mensis iv annoque mcmlxiv xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Apr 121 2438516 04 iv  4 04/30/1964 die xxx mensis iv annoque mcmlxiv 64 lxiv 1964}
+test clock-2.825 {conversion of 1964-05-01} {
+    clock format -178889104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/01/1964 12:34:56 die i mensis v annoque mcmlxiv xii h xxxiv m lvi s 19 mcm 01 i  1 i May 122 2438517 05 v  5 05/01/1964 die i mensis v annoque mcmlxiv 64 lxiv 1964}
+test clock-2.826 {conversion of 1964-05-31} {
+    clock format -176297104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/31/1964 12:34:56 die xxxi mensis v annoque mcmlxiv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi May 152 2438547 05 v  5 05/31/1964 die xxxi mensis v annoque mcmlxiv 64 lxiv 1964}
+test clock-2.827 {conversion of 1964-06-01} {
+    clock format -176210704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/01/1964 12:34:56 die i mensis vi annoque mcmlxiv xii h xxxiv m lvi s 19 mcm 01 i  1 i Jun 153 2438548 06 vi  6 06/01/1964 die i mensis vi annoque mcmlxiv 64 lxiv 1964}
+test clock-2.828 {conversion of 1964-06-30} {
+    clock format -173705104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/30/1964 12:34:56 die xxx mensis vi annoque mcmlxiv xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Jun 182 2438577 06 vi  6 06/30/1964 die xxx mensis vi annoque mcmlxiv 64 lxiv 1964}
+test clock-2.829 {conversion of 1964-07-01} {
+    clock format -173618704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/01/1964 12:34:56 die i mensis vii annoque mcmlxiv xii h xxxiv m lvi s 19 mcm 01 i  1 i Jul 183 2438578 07 vii  7 07/01/1964 die i mensis vii annoque mcmlxiv 64 lxiv 1964}
+test clock-2.830 {conversion of 1964-07-31} {
+    clock format -171026704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/31/1964 12:34:56 die xxxi mensis vii annoque mcmlxiv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jul 213 2438608 07 vii  7 07/31/1964 die xxxi mensis vii annoque mcmlxiv 64 lxiv 1964}
+test clock-2.831 {conversion of 1964-08-01} {
+    clock format -170940304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/01/1964 12:34:56 die i mensis viii annoque mcmlxiv xii h xxxiv m lvi s 19 mcm 01 i  1 i Aug 214 2438609 08 viii  8 08/01/1964 die i mensis viii annoque mcmlxiv 64 lxiv 1964}
+test clock-2.832 {conversion of 1964-08-31} {
+    clock format -168348304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/31/1964 12:34:56 die xxxi mensis viii annoque mcmlxiv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Aug 244 2438639 08 viii  8 08/31/1964 die xxxi mensis viii annoque mcmlxiv 64 lxiv 1964}
+test clock-2.833 {conversion of 1964-09-01} {
+    clock format -168261904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/01/1964 12:34:56 die i mensis ix annoque mcmlxiv xii h xxxiv m lvi s 19 mcm 01 i  1 i Sep 245 2438640 09 ix  9 09/01/1964 die i mensis ix annoque mcmlxiv 64 lxiv 1964}
+test clock-2.834 {conversion of 1964-09-30} {
+    clock format -165756304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/30/1964 12:34:56 die xxx mensis ix annoque mcmlxiv xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Sep 274 2438669 09 ix  9 09/30/1964 die xxx mensis ix annoque mcmlxiv 64 lxiv 1964}
+test clock-2.835 {conversion of 1964-10-01} {
+    clock format -165669904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/01/1964 12:34:56 die i mensis x annoque mcmlxiv xii h xxxiv m lvi s 19 mcm 01 i  1 i Oct 275 2438670 10 x 10 10/01/1964 die i mensis x annoque mcmlxiv 64 lxiv 1964}
+test clock-2.836 {conversion of 1964-10-31} {
+    clock format -163077904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/31/1964 12:34:56 die xxxi mensis x annoque mcmlxiv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Oct 305 2438700 10 x 10 10/31/1964 die xxxi mensis x annoque mcmlxiv 64 lxiv 1964}
+test clock-2.837 {conversion of 1964-11-01} {
+    clock format -162991504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/01/1964 12:34:56 die i mensis xi annoque mcmlxiv xii h xxxiv m lvi s 19 mcm 01 i  1 i Nov 306 2438701 11 xi 11 11/01/1964 die i mensis xi annoque mcmlxiv 64 lxiv 1964}
+test clock-2.838 {conversion of 1964-11-30} {
+    clock format -160485904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/30/1964 12:34:56 die xxx mensis xi annoque mcmlxiv xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Nov 335 2438730 11 xi 11 11/30/1964 die xxx mensis xi annoque mcmlxiv 64 lxiv 1964}
+test clock-2.839 {conversion of 1964-12-01} {
+    clock format -160399504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/01/1964 12:34:56 die i mensis xii annoque mcmlxiv xii h xxxiv m lvi s 19 mcm 01 i  1 i Dec 336 2438731 12 xii 12 12/01/1964 die i mensis xii annoque mcmlxiv 64 lxiv 1964}
+test clock-2.840 {conversion of 1964-12-31} {
+    clock format -157807504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/31/1964 12:34:56 die xxxi mensis xii annoque mcmlxiv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Dec 366 2438761 12 xii 12 12/31/1964 die xxxi mensis xii annoque mcmlxiv 64 lxiv 1964}
+test clock-2.841 {conversion of 1965-01-01} {
+    clock format -157721104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/01/1965 12:34:56 die i mensis i annoque mcmlxv xii h xxxiv m lvi s 19 mcm 01 i  1 i Jan 001 2438762 01 i  1 01/01/1965 die i mensis i annoque mcmlxv 65 lxv 1965}
+test clock-2.842 {conversion of 1965-01-31} {
+    clock format -155129104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/31/1965 12:34:56 die xxxi mensis i annoque mcmlxv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jan 031 2438792 01 i  1 01/31/1965 die xxxi mensis i annoque mcmlxv 65 lxv 1965}
+test clock-2.843 {conversion of 1965-02-01} {
+    clock format -155042704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/01/1965 12:34:56 die i mensis ii annoque mcmlxv xii h xxxiv m lvi s 19 mcm 01 i  1 i Feb 032 2438793 02 ii  2 02/01/1965 die i mensis ii annoque mcmlxv 65 lxv 1965}
+test clock-2.844 {conversion of 1965-02-28} {
+    clock format -152709904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/28/1965 12:34:56 die xxviii mensis ii annoque mcmlxv xii h xxxiv m lvi s 19 mcm 28 xxviii 28 xxviii Feb 059 2438820 02 ii  2 02/28/1965 die xxviii mensis ii annoque mcmlxv 65 lxv 1965}
+test clock-2.845 {conversion of 1965-03-01} {
+    clock format -152623504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/01/1965 12:34:56 die i mensis iii annoque mcmlxv xii h xxxiv m lvi s 19 mcm 01 i  1 i Mar 060 2438821 03 iii  3 03/01/1965 die i mensis iii annoque mcmlxv 65 lxv 1965}
+test clock-2.846 {conversion of 1965-03-31} {
+    clock format -150031504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/31/1965 12:34:56 die xxxi mensis iii annoque mcmlxv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Mar 090 2438851 03 iii  3 03/31/1965 die xxxi mensis iii annoque mcmlxv 65 lxv 1965}
+test clock-2.847 {conversion of 1965-04-01} {
+    clock format -149945104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/01/1965 12:34:56 die i mensis iv annoque mcmlxv xii h xxxiv m lvi s 19 mcm 01 i  1 i Apr 091 2438852 04 iv  4 04/01/1965 die i mensis iv annoque mcmlxv 65 lxv 1965}
+test clock-2.848 {conversion of 1965-04-30} {
+    clock format -147439504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/30/1965 12:34:56 die xxx mensis iv annoque mcmlxv xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Apr 120 2438881 04 iv  4 04/30/1965 die xxx mensis iv annoque mcmlxv 65 lxv 1965}
+test clock-2.849 {conversion of 1965-05-01} {
+    clock format -147353104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/01/1965 12:34:56 die i mensis v annoque mcmlxv xii h xxxiv m lvi s 19 mcm 01 i  1 i May 121 2438882 05 v  5 05/01/1965 die i mensis v annoque mcmlxv 65 lxv 1965}
+test clock-2.850 {conversion of 1965-05-31} {
+    clock format -144761104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/31/1965 12:34:56 die xxxi mensis v annoque mcmlxv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi May 151 2438912 05 v  5 05/31/1965 die xxxi mensis v annoque mcmlxv 65 lxv 1965}
+test clock-2.851 {conversion of 1965-06-01} {
+    clock format -144674704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/01/1965 12:34:56 die i mensis vi annoque mcmlxv xii h xxxiv m lvi s 19 mcm 01 i  1 i Jun 152 2438913 06 vi  6 06/01/1965 die i mensis vi annoque mcmlxv 65 lxv 1965}
+test clock-2.852 {conversion of 1965-06-30} {
+    clock format -142169104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/30/1965 12:34:56 die xxx mensis vi annoque mcmlxv xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Jun 181 2438942 06 vi  6 06/30/1965 die xxx mensis vi annoque mcmlxv 65 lxv 1965}
+test clock-2.853 {conversion of 1965-07-01} {
+    clock format -142082704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/01/1965 12:34:56 die i mensis vii annoque mcmlxv xii h xxxiv m lvi s 19 mcm 01 i  1 i Jul 182 2438943 07 vii  7 07/01/1965 die i mensis vii annoque mcmlxv 65 lxv 1965}
+test clock-2.854 {conversion of 1965-07-31} {
+    clock format -139490704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/31/1965 12:34:56 die xxxi mensis vii annoque mcmlxv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jul 212 2438973 07 vii  7 07/31/1965 die xxxi mensis vii annoque mcmlxv 65 lxv 1965}
+test clock-2.855 {conversion of 1965-08-01} {
+    clock format -139404304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/01/1965 12:34:56 die i mensis viii annoque mcmlxv xii h xxxiv m lvi s 19 mcm 01 i  1 i Aug 213 2438974 08 viii  8 08/01/1965 die i mensis viii annoque mcmlxv 65 lxv 1965}
+test clock-2.856 {conversion of 1965-08-31} {
+    clock format -136812304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/31/1965 12:34:56 die xxxi mensis viii annoque mcmlxv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Aug 243 2439004 08 viii  8 08/31/1965 die xxxi mensis viii annoque mcmlxv 65 lxv 1965}
+test clock-2.857 {conversion of 1965-09-01} {
+    clock format -136725904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/01/1965 12:34:56 die i mensis ix annoque mcmlxv xii h xxxiv m lvi s 19 mcm 01 i  1 i Sep 244 2439005 09 ix  9 09/01/1965 die i mensis ix annoque mcmlxv 65 lxv 1965}
+test clock-2.858 {conversion of 1965-09-30} {
+    clock format -134220304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/30/1965 12:34:56 die xxx mensis ix annoque mcmlxv xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Sep 273 2439034 09 ix  9 09/30/1965 die xxx mensis ix annoque mcmlxv 65 lxv 1965}
+test clock-2.859 {conversion of 1965-10-01} {
+    clock format -134133904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/01/1965 12:34:56 die i mensis x annoque mcmlxv xii h xxxiv m lvi s 19 mcm 01 i  1 i Oct 274 2439035 10 x 10 10/01/1965 die i mensis x annoque mcmlxv 65 lxv 1965}
+test clock-2.860 {conversion of 1965-10-31} {
+    clock format -131541904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/31/1965 12:34:56 die xxxi mensis x annoque mcmlxv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Oct 304 2439065 10 x 10 10/31/1965 die xxxi mensis x annoque mcmlxv 65 lxv 1965}
+test clock-2.861 {conversion of 1965-11-01} {
+    clock format -131455504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/01/1965 12:34:56 die i mensis xi annoque mcmlxv xii h xxxiv m lvi s 19 mcm 01 i  1 i Nov 305 2439066 11 xi 11 11/01/1965 die i mensis xi annoque mcmlxv 65 lxv 1965}
+test clock-2.862 {conversion of 1965-11-30} {
+    clock format -128949904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/30/1965 12:34:56 die xxx mensis xi annoque mcmlxv xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Nov 334 2439095 11 xi 11 11/30/1965 die xxx mensis xi annoque mcmlxv 65 lxv 1965}
+test clock-2.863 {conversion of 1965-12-01} {
+    clock format -128863504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/01/1965 12:34:56 die i mensis xii annoque mcmlxv xii h xxxiv m lvi s 19 mcm 01 i  1 i Dec 335 2439096 12 xii 12 12/01/1965 die i mensis xii annoque mcmlxv 65 lxv 1965}
+test clock-2.864 {conversion of 1965-12-31} {
+    clock format -126271504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/31/1965 12:34:56 die xxxi mensis xii annoque mcmlxv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Dec 365 2439126 12 xii 12 12/31/1965 die xxxi mensis xii annoque mcmlxv 65 lxv 1965}
+test clock-2.865 {conversion of 1966-01-01} {
+    clock format -126185104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/01/1966 12:34:56 die i mensis i annoque mcmlxvi xii h xxxiv m lvi s 19 mcm 01 i  1 i Jan 001 2439127 01 i  1 01/01/1966 die i mensis i annoque mcmlxvi 66 lxvi 1966}
+test clock-2.866 {conversion of 1966-01-31} {
+    clock format -123593104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/31/1966 12:34:56 die xxxi mensis i annoque mcmlxvi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jan 031 2439157 01 i  1 01/31/1966 die xxxi mensis i annoque mcmlxvi 66 lxvi 1966}
+test clock-2.867 {conversion of 1966-02-01} {
+    clock format -123506704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/01/1966 12:34:56 die i mensis ii annoque mcmlxvi xii h xxxiv m lvi s 19 mcm 01 i  1 i Feb 032 2439158 02 ii  2 02/01/1966 die i mensis ii annoque mcmlxvi 66 lxvi 1966}
+test clock-2.868 {conversion of 1966-02-28} {
+    clock format -121173904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/28/1966 12:34:56 die xxviii mensis ii annoque mcmlxvi xii h xxxiv m lvi s 19 mcm 28 xxviii 28 xxviii Feb 059 2439185 02 ii  2 02/28/1966 die xxviii mensis ii annoque mcmlxvi 66 lxvi 1966}
+test clock-2.869 {conversion of 1966-03-01} {
+    clock format -121087504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/01/1966 12:34:56 die i mensis iii annoque mcmlxvi xii h xxxiv m lvi s 19 mcm 01 i  1 i Mar 060 2439186 03 iii  3 03/01/1966 die i mensis iii annoque mcmlxvi 66 lxvi 1966}
+test clock-2.870 {conversion of 1966-03-31} {
+    clock format -118495504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/31/1966 12:34:56 die xxxi mensis iii annoque mcmlxvi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Mar 090 2439216 03 iii  3 03/31/1966 die xxxi mensis iii annoque mcmlxvi 66 lxvi 1966}
+test clock-2.871 {conversion of 1966-04-01} {
+    clock format -118409104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/01/1966 12:34:56 die i mensis iv annoque mcmlxvi xii h xxxiv m lvi s 19 mcm 01 i  1 i Apr 091 2439217 04 iv  4 04/01/1966 die i mensis iv annoque mcmlxvi 66 lxvi 1966}
+test clock-2.872 {conversion of 1966-04-30} {
+    clock format -115903504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/30/1966 12:34:56 die xxx mensis iv annoque mcmlxvi xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Apr 120 2439246 04 iv  4 04/30/1966 die xxx mensis iv annoque mcmlxvi 66 lxvi 1966}
+test clock-2.873 {conversion of 1966-05-01} {
+    clock format -115817104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/01/1966 12:34:56 die i mensis v annoque mcmlxvi xii h xxxiv m lvi s 19 mcm 01 i  1 i May 121 2439247 05 v  5 05/01/1966 die i mensis v annoque mcmlxvi 66 lxvi 1966}
+test clock-2.874 {conversion of 1966-05-31} {
+    clock format -113225104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/31/1966 12:34:56 die xxxi mensis v annoque mcmlxvi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi May 151 2439277 05 v  5 05/31/1966 die xxxi mensis v annoque mcmlxvi 66 lxvi 1966}
+test clock-2.875 {conversion of 1966-06-01} {
+    clock format -113138704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/01/1966 12:34:56 die i mensis vi annoque mcmlxvi xii h xxxiv m lvi s 19 mcm 01 i  1 i Jun 152 2439278 06 vi  6 06/01/1966 die i mensis vi annoque mcmlxvi 66 lxvi 1966}
+test clock-2.876 {conversion of 1966-06-30} {
+    clock format -110633104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/30/1966 12:34:56 die xxx mensis vi annoque mcmlxvi xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Jun 181 2439307 06 vi  6 06/30/1966 die xxx mensis vi annoque mcmlxvi 66 lxvi 1966}
+test clock-2.877 {conversion of 1966-07-01} {
+    clock format -110546704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/01/1966 12:34:56 die i mensis vii annoque mcmlxvi xii h xxxiv m lvi s 19 mcm 01 i  1 i Jul 182 2439308 07 vii  7 07/01/1966 die i mensis vii annoque mcmlxvi 66 lxvi 1966}
+test clock-2.878 {conversion of 1966-07-31} {
+    clock format -107954704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/31/1966 12:34:56 die xxxi mensis vii annoque mcmlxvi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jul 212 2439338 07 vii  7 07/31/1966 die xxxi mensis vii annoque mcmlxvi 66 lxvi 1966}
+test clock-2.879 {conversion of 1966-08-01} {
+    clock format -107868304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/01/1966 12:34:56 die i mensis viii annoque mcmlxvi xii h xxxiv m lvi s 19 mcm 01 i  1 i Aug 213 2439339 08 viii  8 08/01/1966 die i mensis viii annoque mcmlxvi 66 lxvi 1966}
+test clock-2.880 {conversion of 1966-08-31} {
+    clock format -105276304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/31/1966 12:34:56 die xxxi mensis viii annoque mcmlxvi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Aug 243 2439369 08 viii  8 08/31/1966 die xxxi mensis viii annoque mcmlxvi 66 lxvi 1966}
+test clock-2.881 {conversion of 1966-09-01} {
+    clock format -105189904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/01/1966 12:34:56 die i mensis ix annoque mcmlxvi xii h xxxiv m lvi s 19 mcm 01 i  1 i Sep 244 2439370 09 ix  9 09/01/1966 die i mensis ix annoque mcmlxvi 66 lxvi 1966}
+test clock-2.882 {conversion of 1966-09-30} {
+    clock format -102684304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/30/1966 12:34:56 die xxx mensis ix annoque mcmlxvi xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Sep 273 2439399 09 ix  9 09/30/1966 die xxx mensis ix annoque mcmlxvi 66 lxvi 1966}
+test clock-2.883 {conversion of 1966-10-01} {
+    clock format -102597904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/01/1966 12:34:56 die i mensis x annoque mcmlxvi xii h xxxiv m lvi s 19 mcm 01 i  1 i Oct 274 2439400 10 x 10 10/01/1966 die i mensis x annoque mcmlxvi 66 lxvi 1966}
+test clock-2.884 {conversion of 1966-10-31} {
+    clock format -100005904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/31/1966 12:34:56 die xxxi mensis x annoque mcmlxvi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Oct 304 2439430 10 x 10 10/31/1966 die xxxi mensis x annoque mcmlxvi 66 lxvi 1966}
+test clock-2.885 {conversion of 1966-11-01} {
+    clock format -99919504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/01/1966 12:34:56 die i mensis xi annoque mcmlxvi xii h xxxiv m lvi s 19 mcm 01 i  1 i Nov 305 2439431 11 xi 11 11/01/1966 die i mensis xi annoque mcmlxvi 66 lxvi 1966}
+test clock-2.886 {conversion of 1966-11-30} {
+    clock format -97413904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/30/1966 12:34:56 die xxx mensis xi annoque mcmlxvi xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Nov 334 2439460 11 xi 11 11/30/1966 die xxx mensis xi annoque mcmlxvi 66 lxvi 1966}
+test clock-2.887 {conversion of 1966-12-01} {
+    clock format -97327504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/01/1966 12:34:56 die i mensis xii annoque mcmlxvi xii h xxxiv m lvi s 19 mcm 01 i  1 i Dec 335 2439461 12 xii 12 12/01/1966 die i mensis xii annoque mcmlxvi 66 lxvi 1966}
+test clock-2.888 {conversion of 1966-12-31} {
+    clock format -94735504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/31/1966 12:34:56 die xxxi mensis xii annoque mcmlxvi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Dec 365 2439491 12 xii 12 12/31/1966 die xxxi mensis xii annoque mcmlxvi 66 lxvi 1966}
+test clock-2.889 {conversion of 1967-01-01} {
+    clock format -94649104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/01/1967 12:34:56 die i mensis i annoque mcmlxvii xii h xxxiv m lvi s 19 mcm 01 i  1 i Jan 001 2439492 01 i  1 01/01/1967 die i mensis i annoque mcmlxvii 67 lxvii 1967}
+test clock-2.890 {conversion of 1967-01-31} {
+    clock format -92057104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/31/1967 12:34:56 die xxxi mensis i annoque mcmlxvii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jan 031 2439522 01 i  1 01/31/1967 die xxxi mensis i annoque mcmlxvii 67 lxvii 1967}
+test clock-2.891 {conversion of 1967-02-01} {
+    clock format -91970704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/01/1967 12:34:56 die i mensis ii annoque mcmlxvii xii h xxxiv m lvi s 19 mcm 01 i  1 i Feb 032 2439523 02 ii  2 02/01/1967 die i mensis ii annoque mcmlxvii 67 lxvii 1967}
+test clock-2.892 {conversion of 1967-02-28} {
+    clock format -89637904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/28/1967 12:34:56 die xxviii mensis ii annoque mcmlxvii xii h xxxiv m lvi s 19 mcm 28 xxviii 28 xxviii Feb 059 2439550 02 ii  2 02/28/1967 die xxviii mensis ii annoque mcmlxvii 67 lxvii 1967}
+test clock-2.893 {conversion of 1967-03-01} {
+    clock format -89551504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/01/1967 12:34:56 die i mensis iii annoque mcmlxvii xii h xxxiv m lvi s 19 mcm 01 i  1 i Mar 060 2439551 03 iii  3 03/01/1967 die i mensis iii annoque mcmlxvii 67 lxvii 1967}
+test clock-2.894 {conversion of 1967-03-31} {
+    clock format -86959504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/31/1967 12:34:56 die xxxi mensis iii annoque mcmlxvii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Mar 090 2439581 03 iii  3 03/31/1967 die xxxi mensis iii annoque mcmlxvii 67 lxvii 1967}
+test clock-2.895 {conversion of 1967-04-01} {
+    clock format -86873104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/01/1967 12:34:56 die i mensis iv annoque mcmlxvii xii h xxxiv m lvi s 19 mcm 01 i  1 i Apr 091 2439582 04 iv  4 04/01/1967 die i mensis iv annoque mcmlxvii 67 lxvii 1967}
+test clock-2.896 {conversion of 1967-04-30} {
+    clock format -84367504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/30/1967 12:34:56 die xxx mensis iv annoque mcmlxvii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Apr 120 2439611 04 iv  4 04/30/1967 die xxx mensis iv annoque mcmlxvii 67 lxvii 1967}
+test clock-2.897 {conversion of 1967-05-01} {
+    clock format -84281104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/01/1967 12:34:56 die i mensis v annoque mcmlxvii xii h xxxiv m lvi s 19 mcm 01 i  1 i May 121 2439612 05 v  5 05/01/1967 die i mensis v annoque mcmlxvii 67 lxvii 1967}
+test clock-2.898 {conversion of 1967-05-31} {
+    clock format -81689104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/31/1967 12:34:56 die xxxi mensis v annoque mcmlxvii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi May 151 2439642 05 v  5 05/31/1967 die xxxi mensis v annoque mcmlxvii 67 lxvii 1967}
+test clock-2.899 {conversion of 1967-06-01} {
+    clock format -81602704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/01/1967 12:34:56 die i mensis vi annoque mcmlxvii xii h xxxiv m lvi s 19 mcm 01 i  1 i Jun 152 2439643 06 vi  6 06/01/1967 die i mensis vi annoque mcmlxvii 67 lxvii 1967}
+test clock-2.900 {conversion of 1967-06-30} {
+    clock format -79097104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/30/1967 12:34:56 die xxx mensis vi annoque mcmlxvii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Jun 181 2439672 06 vi  6 06/30/1967 die xxx mensis vi annoque mcmlxvii 67 lxvii 1967}
+test clock-2.901 {conversion of 1967-07-01} {
+    clock format -79010704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/01/1967 12:34:56 die i mensis vii annoque mcmlxvii xii h xxxiv m lvi s 19 mcm 01 i  1 i Jul 182 2439673 07 vii  7 07/01/1967 die i mensis vii annoque mcmlxvii 67 lxvii 1967}
+test clock-2.902 {conversion of 1967-07-31} {
+    clock format -76418704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/31/1967 12:34:56 die xxxi mensis vii annoque mcmlxvii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jul 212 2439703 07 vii  7 07/31/1967 die xxxi mensis vii annoque mcmlxvii 67 lxvii 1967}
+test clock-2.903 {conversion of 1967-08-01} {
+    clock format -76332304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/01/1967 12:34:56 die i mensis viii annoque mcmlxvii xii h xxxiv m lvi s 19 mcm 01 i  1 i Aug 213 2439704 08 viii  8 08/01/1967 die i mensis viii annoque mcmlxvii 67 lxvii 1967}
+test clock-2.904 {conversion of 1967-08-31} {
+    clock format -73740304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/31/1967 12:34:56 die xxxi mensis viii annoque mcmlxvii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Aug 243 2439734 08 viii  8 08/31/1967 die xxxi mensis viii annoque mcmlxvii 67 lxvii 1967}
+test clock-2.905 {conversion of 1967-09-01} {
+    clock format -73653904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/01/1967 12:34:56 die i mensis ix annoque mcmlxvii xii h xxxiv m lvi s 19 mcm 01 i  1 i Sep 244 2439735 09 ix  9 09/01/1967 die i mensis ix annoque mcmlxvii 67 lxvii 1967}
+test clock-2.906 {conversion of 1967-09-30} {
+    clock format -71148304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/30/1967 12:34:56 die xxx mensis ix annoque mcmlxvii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Sep 273 2439764 09 ix  9 09/30/1967 die xxx mensis ix annoque mcmlxvii 67 lxvii 1967}
+test clock-2.907 {conversion of 1967-10-01} {
+    clock format -71061904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/01/1967 12:34:56 die i mensis x annoque mcmlxvii xii h xxxiv m lvi s 19 mcm 01 i  1 i Oct 274 2439765 10 x 10 10/01/1967 die i mensis x annoque mcmlxvii 67 lxvii 1967}
+test clock-2.908 {conversion of 1967-10-31} {
+    clock format -68469904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/31/1967 12:34:56 die xxxi mensis x annoque mcmlxvii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Oct 304 2439795 10 x 10 10/31/1967 die xxxi mensis x annoque mcmlxvii 67 lxvii 1967}
+test clock-2.909 {conversion of 1967-11-01} {
+    clock format -68383504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/01/1967 12:34:56 die i mensis xi annoque mcmlxvii xii h xxxiv m lvi s 19 mcm 01 i  1 i Nov 305 2439796 11 xi 11 11/01/1967 die i mensis xi annoque mcmlxvii 67 lxvii 1967}
+test clock-2.910 {conversion of 1967-11-30} {
+    clock format -65877904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/30/1967 12:34:56 die xxx mensis xi annoque mcmlxvii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Nov 334 2439825 11 xi 11 11/30/1967 die xxx mensis xi annoque mcmlxvii 67 lxvii 1967}
+test clock-2.911 {conversion of 1967-12-01} {
+    clock format -65791504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/01/1967 12:34:56 die i mensis xii annoque mcmlxvii xii h xxxiv m lvi s 19 mcm 01 i  1 i Dec 335 2439826 12 xii 12 12/01/1967 die i mensis xii annoque mcmlxvii 67 lxvii 1967}
+test clock-2.912 {conversion of 1967-12-31} {
+    clock format -63199504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/31/1967 12:34:56 die xxxi mensis xii annoque mcmlxvii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Dec 365 2439856 12 xii 12 12/31/1967 die xxxi mensis xii annoque mcmlxvii 67 lxvii 1967}
+test clock-2.913 {conversion of 1968-01-01} {
+    clock format -63113104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/01/1968 12:34:56 die i mensis i annoque mcmlxviii xii h xxxiv m lvi s 19 mcm 01 i  1 i Jan 001 2439857 01 i  1 01/01/1968 die i mensis i annoque mcmlxviii 68 lxviii 1968}
+test clock-2.914 {conversion of 1968-01-31} {
+    clock format -60521104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/31/1968 12:34:56 die xxxi mensis i annoque mcmlxviii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jan 031 2439887 01 i  1 01/31/1968 die xxxi mensis i annoque mcmlxviii 68 lxviii 1968}
+test clock-2.915 {conversion of 1968-02-01} {
+    clock format -60434704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/01/1968 12:34:56 die i mensis ii annoque mcmlxviii xii h xxxiv m lvi s 19 mcm 01 i  1 i Feb 032 2439888 02 ii  2 02/01/1968 die i mensis ii annoque mcmlxviii 68 lxviii 1968}
+test clock-2.916 {conversion of 1968-02-29} {
+    clock format -58015504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/29/1968 12:34:56 die xxix mensis ii annoque mcmlxviii xii h xxxiv m lvi s 19 mcm 29 xxix 29 xxix Feb 060 2439916 02 ii  2 02/29/1968 die xxix mensis ii annoque mcmlxviii 68 lxviii 1968}
+test clock-2.917 {conversion of 1968-03-01} {
+    clock format -57929104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/01/1968 12:34:56 die i mensis iii annoque mcmlxviii xii h xxxiv m lvi s 19 mcm 01 i  1 i Mar 061 2439917 03 iii  3 03/01/1968 die i mensis iii annoque mcmlxviii 68 lxviii 1968}
+test clock-2.918 {conversion of 1968-03-31} {
+    clock format -55337104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/31/1968 12:34:56 die xxxi mensis iii annoque mcmlxviii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Mar 091 2439947 03 iii  3 03/31/1968 die xxxi mensis iii annoque mcmlxviii 68 lxviii 1968}
+test clock-2.919 {conversion of 1968-04-01} {
+    clock format -55250704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/01/1968 12:34:56 die i mensis iv annoque mcmlxviii xii h xxxiv m lvi s 19 mcm 01 i  1 i Apr 092 2439948 04 iv  4 04/01/1968 die i mensis iv annoque mcmlxviii 68 lxviii 1968}
+test clock-2.920 {conversion of 1968-04-30} {
+    clock format -52745104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/30/1968 12:34:56 die xxx mensis iv annoque mcmlxviii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Apr 121 2439977 04 iv  4 04/30/1968 die xxx mensis iv annoque mcmlxviii 68 lxviii 1968}
+test clock-2.921 {conversion of 1968-05-01} {
+    clock format -52658704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/01/1968 12:34:56 die i mensis v annoque mcmlxviii xii h xxxiv m lvi s 19 mcm 01 i  1 i May 122 2439978 05 v  5 05/01/1968 die i mensis v annoque mcmlxviii 68 lxviii 1968}
+test clock-2.922 {conversion of 1968-05-31} {
+    clock format -50066704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/31/1968 12:34:56 die xxxi mensis v annoque mcmlxviii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi May 152 2440008 05 v  5 05/31/1968 die xxxi mensis v annoque mcmlxviii 68 lxviii 1968}
+test clock-2.923 {conversion of 1968-06-01} {
+    clock format -49980304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/01/1968 12:34:56 die i mensis vi annoque mcmlxviii xii h xxxiv m lvi s 19 mcm 01 i  1 i Jun 153 2440009 06 vi  6 06/01/1968 die i mensis vi annoque mcmlxviii 68 lxviii 1968}
+test clock-2.924 {conversion of 1968-06-30} {
+    clock format -47474704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/30/1968 12:34:56 die xxx mensis vi annoque mcmlxviii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Jun 182 2440038 06 vi  6 06/30/1968 die xxx mensis vi annoque mcmlxviii 68 lxviii 1968}
+test clock-2.925 {conversion of 1968-07-01} {
+    clock format -47388304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/01/1968 12:34:56 die i mensis vii annoque mcmlxviii xii h xxxiv m lvi s 19 mcm 01 i  1 i Jul 183 2440039 07 vii  7 07/01/1968 die i mensis vii annoque mcmlxviii 68 lxviii 1968}
+test clock-2.926 {conversion of 1968-07-31} {
+    clock format -44796304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/31/1968 12:34:56 die xxxi mensis vii annoque mcmlxviii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jul 213 2440069 07 vii  7 07/31/1968 die xxxi mensis vii annoque mcmlxviii 68 lxviii 1968}
+test clock-2.927 {conversion of 1968-08-01} {
+    clock format -44709904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/01/1968 12:34:56 die i mensis viii annoque mcmlxviii xii h xxxiv m lvi s 19 mcm 01 i  1 i Aug 214 2440070 08 viii  8 08/01/1968 die i mensis viii annoque mcmlxviii 68 lxviii 1968}
+test clock-2.928 {conversion of 1968-08-31} {
+    clock format -42117904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/31/1968 12:34:56 die xxxi mensis viii annoque mcmlxviii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Aug 244 2440100 08 viii  8 08/31/1968 die xxxi mensis viii annoque mcmlxviii 68 lxviii 1968}
+test clock-2.929 {conversion of 1968-09-01} {
+    clock format -42031504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/01/1968 12:34:56 die i mensis ix annoque mcmlxviii xii h xxxiv m lvi s 19 mcm 01 i  1 i Sep 245 2440101 09 ix  9 09/01/1968 die i mensis ix annoque mcmlxviii 68 lxviii 1968}
+test clock-2.930 {conversion of 1968-09-30} {
+    clock format -39525904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/30/1968 12:34:56 die xxx mensis ix annoque mcmlxviii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Sep 274 2440130 09 ix  9 09/30/1968 die xxx mensis ix annoque mcmlxviii 68 lxviii 1968}
+test clock-2.931 {conversion of 1968-10-01} {
+    clock format -39439504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/01/1968 12:34:56 die i mensis x annoque mcmlxviii xii h xxxiv m lvi s 19 mcm 01 i  1 i Oct 275 2440131 10 x 10 10/01/1968 die i mensis x annoque mcmlxviii 68 lxviii 1968}
+test clock-2.932 {conversion of 1968-10-31} {
+    clock format -36847504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/31/1968 12:34:56 die xxxi mensis x annoque mcmlxviii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Oct 305 2440161 10 x 10 10/31/1968 die xxxi mensis x annoque mcmlxviii 68 lxviii 1968}
+test clock-2.933 {conversion of 1968-11-01} {
+    clock format -36761104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/01/1968 12:34:56 die i mensis xi annoque mcmlxviii xii h xxxiv m lvi s 19 mcm 01 i  1 i Nov 306 2440162 11 xi 11 11/01/1968 die i mensis xi annoque mcmlxviii 68 lxviii 1968}
+test clock-2.934 {conversion of 1968-11-30} {
+    clock format -34255504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/30/1968 12:34:56 die xxx mensis xi annoque mcmlxviii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Nov 335 2440191 11 xi 11 11/30/1968 die xxx mensis xi annoque mcmlxviii 68 lxviii 1968}
+test clock-2.935 {conversion of 1968-12-01} {
+    clock format -34169104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/01/1968 12:34:56 die i mensis xii annoque mcmlxviii xii h xxxiv m lvi s 19 mcm 01 i  1 i Dec 336 2440192 12 xii 12 12/01/1968 die i mensis xii annoque mcmlxviii 68 lxviii 1968}
+test clock-2.936 {conversion of 1968-12-31} {
+    clock format -31577104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/31/1968 12:34:56 die xxxi mensis xii annoque mcmlxviii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Dec 366 2440222 12 xii 12 12/31/1968 die xxxi mensis xii annoque mcmlxviii 68 lxviii 1968}
+test clock-2.937 {conversion of 1969-01-01} {
+    clock format -31490704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/01/1969 12:34:56 die i mensis i annoque mcmlxix xii h xxxiv m lvi s 19 mcm 01 i  1 i Jan 001 2440223 01 i  1 01/01/1969 die i mensis i annoque mcmlxix 69 lxix 1969}
+test clock-2.938 {conversion of 1969-01-31} {
+    clock format -28898704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/31/1969 12:34:56 die xxxi mensis i annoque mcmlxix xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jan 031 2440253 01 i  1 01/31/1969 die xxxi mensis i annoque mcmlxix 69 lxix 1969}
+test clock-2.939 {conversion of 1969-02-01} {
+    clock format -28812304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/01/1969 12:34:56 die i mensis ii annoque mcmlxix xii h xxxiv m lvi s 19 mcm 01 i  1 i Feb 032 2440254 02 ii  2 02/01/1969 die i mensis ii annoque mcmlxix 69 lxix 1969}
+test clock-2.940 {conversion of 1969-02-28} {
+    clock format -26479504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/28/1969 12:34:56 die xxviii mensis ii annoque mcmlxix xii h xxxiv m lvi s 19 mcm 28 xxviii 28 xxviii Feb 059 2440281 02 ii  2 02/28/1969 die xxviii mensis ii annoque mcmlxix 69 lxix 1969}
+test clock-2.941 {conversion of 1969-03-01} {
+    clock format -26393104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/01/1969 12:34:56 die i mensis iii annoque mcmlxix xii h xxxiv m lvi s 19 mcm 01 i  1 i Mar 060 2440282 03 iii  3 03/01/1969 die i mensis iii annoque mcmlxix 69 lxix 1969}
+test clock-2.942 {conversion of 1969-03-31} {
+    clock format -23801104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/31/1969 12:34:56 die xxxi mensis iii annoque mcmlxix xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Mar 090 2440312 03 iii  3 03/31/1969 die xxxi mensis iii annoque mcmlxix 69 lxix 1969}
+test clock-2.943 {conversion of 1969-04-01} {
+    clock format -23714704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/01/1969 12:34:56 die i mensis iv annoque mcmlxix xii h xxxiv m lvi s 19 mcm 01 i  1 i Apr 091 2440313 04 iv  4 04/01/1969 die i mensis iv annoque mcmlxix 69 lxix 1969}
+test clock-2.944 {conversion of 1969-04-30} {
+    clock format -21209104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/30/1969 12:34:56 die xxx mensis iv annoque mcmlxix xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Apr 120 2440342 04 iv  4 04/30/1969 die xxx mensis iv annoque mcmlxix 69 lxix 1969}
+test clock-2.945 {conversion of 1969-05-01} {
+    clock format -21122704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/01/1969 12:34:56 die i mensis v annoque mcmlxix xii h xxxiv m lvi s 19 mcm 01 i  1 i May 121 2440343 05 v  5 05/01/1969 die i mensis v annoque mcmlxix 69 lxix 1969}
+test clock-2.946 {conversion of 1969-05-31} {
+    clock format -18530704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/31/1969 12:34:56 die xxxi mensis v annoque mcmlxix xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi May 151 2440373 05 v  5 05/31/1969 die xxxi mensis v annoque mcmlxix 69 lxix 1969}
+test clock-2.947 {conversion of 1969-06-01} {
+    clock format -18444304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/01/1969 12:34:56 die i mensis vi annoque mcmlxix xii h xxxiv m lvi s 19 mcm 01 i  1 i Jun 152 2440374 06 vi  6 06/01/1969 die i mensis vi annoque mcmlxix 69 lxix 1969}
+test clock-2.948 {conversion of 1969-06-30} {
+    clock format -15938704 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/30/1969 12:34:56 die xxx mensis vi annoque mcmlxix xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Jun 181 2440403 06 vi  6 06/30/1969 die xxx mensis vi annoque mcmlxix 69 lxix 1969}
+test clock-2.949 {conversion of 1969-07-01} {
+    clock format -15852304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/01/1969 12:34:56 die i mensis vii annoque mcmlxix xii h xxxiv m lvi s 19 mcm 01 i  1 i Jul 182 2440404 07 vii  7 07/01/1969 die i mensis vii annoque mcmlxix 69 lxix 1969}
+test clock-2.950 {conversion of 1969-07-31} {
+    clock format -13260304 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/31/1969 12:34:56 die xxxi mensis vii annoque mcmlxix xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jul 212 2440434 07 vii  7 07/31/1969 die xxxi mensis vii annoque mcmlxix 69 lxix 1969}
+test clock-2.951 {conversion of 1969-08-01} {
+    clock format -13173904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/01/1969 12:34:56 die i mensis viii annoque mcmlxix xii h xxxiv m lvi s 19 mcm 01 i  1 i Aug 213 2440435 08 viii  8 08/01/1969 die i mensis viii annoque mcmlxix 69 lxix 1969}
+test clock-2.952 {conversion of 1969-08-31} {
+    clock format -10581904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/31/1969 12:34:56 die xxxi mensis viii annoque mcmlxix xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Aug 243 2440465 08 viii  8 08/31/1969 die xxxi mensis viii annoque mcmlxix 69 lxix 1969}
+test clock-2.953 {conversion of 1969-09-01} {
+    clock format -10495504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/01/1969 12:34:56 die i mensis ix annoque mcmlxix xii h xxxiv m lvi s 19 mcm 01 i  1 i Sep 244 2440466 09 ix  9 09/01/1969 die i mensis ix annoque mcmlxix 69 lxix 1969}
+test clock-2.954 {conversion of 1969-09-30} {
+    clock format -7989904 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/30/1969 12:34:56 die xxx mensis ix annoque mcmlxix xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Sep 273 2440495 09 ix  9 09/30/1969 die xxx mensis ix annoque mcmlxix 69 lxix 1969}
+test clock-2.955 {conversion of 1969-10-01} {
+    clock format -7903504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/01/1969 12:34:56 die i mensis x annoque mcmlxix xii h xxxiv m lvi s 19 mcm 01 i  1 i Oct 274 2440496 10 x 10 10/01/1969 die i mensis x annoque mcmlxix 69 lxix 1969}
+test clock-2.956 {conversion of 1969-10-31} {
+    clock format -5311504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/31/1969 12:34:56 die xxxi mensis x annoque mcmlxix xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Oct 304 2440526 10 x 10 10/31/1969 die xxxi mensis x annoque mcmlxix 69 lxix 1969}
+test clock-2.957 {conversion of 1969-11-01} {
+    clock format -5225104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/01/1969 12:34:56 die i mensis xi annoque mcmlxix xii h xxxiv m lvi s 19 mcm 01 i  1 i Nov 305 2440527 11 xi 11 11/01/1969 die i mensis xi annoque mcmlxix 69 lxix 1969}
+test clock-2.958 {conversion of 1969-11-30} {
+    clock format -2719504 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/30/1969 12:34:56 die xxx mensis xi annoque mcmlxix xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Nov 334 2440556 11 xi 11 11/30/1969 die xxx mensis xi annoque mcmlxix 69 lxix 1969}
+test clock-2.959 {conversion of 1969-12-01} {
+    clock format -2633104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/01/1969 12:34:56 die i mensis xii annoque mcmlxix xii h xxxiv m lvi s 19 mcm 01 i  1 i Dec 335 2440557 12 xii 12 12/01/1969 die i mensis xii annoque mcmlxix 69 lxix 1969}
+test clock-2.960 {conversion of 1969-12-31} {
+    clock format -41104 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/31/1969 12:34:56 die xxxi mensis xii annoque mcmlxix xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Dec 365 2440587 12 xii 12 12/31/1969 die xxxi mensis xii annoque mcmlxix 69 lxix 1969}
+test clock-2.961 {conversion of 1970-01-01} {
+    clock format 45296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/01/1970 12:34:56 die i mensis i annoque mcmlxx xii h xxxiv m lvi s 19 mcm 01 i  1 i Jan 001 2440588 01 i  1 01/01/1970 die i mensis i annoque mcmlxx 70 lxx 1970}
+test clock-2.962 {conversion of 1970-01-31} {
+    clock format 2637296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/31/1970 12:34:56 die xxxi mensis i annoque mcmlxx xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jan 031 2440618 01 i  1 01/31/1970 die xxxi mensis i annoque mcmlxx 70 lxx 1970}
+test clock-2.963 {conversion of 1970-02-01} {
+    clock format 2723696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/01/1970 12:34:56 die i mensis ii annoque mcmlxx xii h xxxiv m lvi s 19 mcm 01 i  1 i Feb 032 2440619 02 ii  2 02/01/1970 die i mensis ii annoque mcmlxx 70 lxx 1970}
+test clock-2.964 {conversion of 1970-02-28} {
+    clock format 5056496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/28/1970 12:34:56 die xxviii mensis ii annoque mcmlxx xii h xxxiv m lvi s 19 mcm 28 xxviii 28 xxviii Feb 059 2440646 02 ii  2 02/28/1970 die xxviii mensis ii annoque mcmlxx 70 lxx 1970}
+test clock-2.965 {conversion of 1970-03-01} {
+    clock format 5142896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/01/1970 12:34:56 die i mensis iii annoque mcmlxx xii h xxxiv m lvi s 19 mcm 01 i  1 i Mar 060 2440647 03 iii  3 03/01/1970 die i mensis iii annoque mcmlxx 70 lxx 1970}
+test clock-2.966 {conversion of 1970-03-31} {
+    clock format 7734896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/31/1970 12:34:56 die xxxi mensis iii annoque mcmlxx xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Mar 090 2440677 03 iii  3 03/31/1970 die xxxi mensis iii annoque mcmlxx 70 lxx 1970}
+test clock-2.967 {conversion of 1970-04-01} {
+    clock format 7821296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/01/1970 12:34:56 die i mensis iv annoque mcmlxx xii h xxxiv m lvi s 19 mcm 01 i  1 i Apr 091 2440678 04 iv  4 04/01/1970 die i mensis iv annoque mcmlxx 70 lxx 1970}
+test clock-2.968 {conversion of 1970-04-30} {
+    clock format 10326896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/30/1970 12:34:56 die xxx mensis iv annoque mcmlxx xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Apr 120 2440707 04 iv  4 04/30/1970 die xxx mensis iv annoque mcmlxx 70 lxx 1970}
+test clock-2.969 {conversion of 1970-05-01} {
+    clock format 10413296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/01/1970 12:34:56 die i mensis v annoque mcmlxx xii h xxxiv m lvi s 19 mcm 01 i  1 i May 121 2440708 05 v  5 05/01/1970 die i mensis v annoque mcmlxx 70 lxx 1970}
+test clock-2.970 {conversion of 1970-05-31} {
+    clock format 13005296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/31/1970 12:34:56 die xxxi mensis v annoque mcmlxx xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi May 151 2440738 05 v  5 05/31/1970 die xxxi mensis v annoque mcmlxx 70 lxx 1970}
+test clock-2.971 {conversion of 1970-06-01} {
+    clock format 13091696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/01/1970 12:34:56 die i mensis vi annoque mcmlxx xii h xxxiv m lvi s 19 mcm 01 i  1 i Jun 152 2440739 06 vi  6 06/01/1970 die i mensis vi annoque mcmlxx 70 lxx 1970}
+test clock-2.972 {conversion of 1970-06-30} {
+    clock format 15597296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/30/1970 12:34:56 die xxx mensis vi annoque mcmlxx xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Jun 181 2440768 06 vi  6 06/30/1970 die xxx mensis vi annoque mcmlxx 70 lxx 1970}
+test clock-2.973 {conversion of 1970-07-01} {
+    clock format 15683696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/01/1970 12:34:56 die i mensis vii annoque mcmlxx xii h xxxiv m lvi s 19 mcm 01 i  1 i Jul 182 2440769 07 vii  7 07/01/1970 die i mensis vii annoque mcmlxx 70 lxx 1970}
+test clock-2.974 {conversion of 1970-07-31} {
+    clock format 18275696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/31/1970 12:34:56 die xxxi mensis vii annoque mcmlxx xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jul 212 2440799 07 vii  7 07/31/1970 die xxxi mensis vii annoque mcmlxx 70 lxx 1970}
+test clock-2.975 {conversion of 1970-08-01} {
+    clock format 18362096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/01/1970 12:34:56 die i mensis viii annoque mcmlxx xii h xxxiv m lvi s 19 mcm 01 i  1 i Aug 213 2440800 08 viii  8 08/01/1970 die i mensis viii annoque mcmlxx 70 lxx 1970}
+test clock-2.976 {conversion of 1970-08-31} {
+    clock format 20954096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/31/1970 12:34:56 die xxxi mensis viii annoque mcmlxx xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Aug 243 2440830 08 viii  8 08/31/1970 die xxxi mensis viii annoque mcmlxx 70 lxx 1970}
+test clock-2.977 {conversion of 1970-09-01} {
+    clock format 21040496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/01/1970 12:34:56 die i mensis ix annoque mcmlxx xii h xxxiv m lvi s 19 mcm 01 i  1 i Sep 244 2440831 09 ix  9 09/01/1970 die i mensis ix annoque mcmlxx 70 lxx 1970}
+test clock-2.978 {conversion of 1970-09-30} {
+    clock format 23546096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/30/1970 12:34:56 die xxx mensis ix annoque mcmlxx xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Sep 273 2440860 09 ix  9 09/30/1970 die xxx mensis ix annoque mcmlxx 70 lxx 1970}
+test clock-2.979 {conversion of 1970-10-01} {
+    clock format 23632496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/01/1970 12:34:56 die i mensis x annoque mcmlxx xii h xxxiv m lvi s 19 mcm 01 i  1 i Oct 274 2440861 10 x 10 10/01/1970 die i mensis x annoque mcmlxx 70 lxx 1970}
+test clock-2.980 {conversion of 1970-10-31} {
+    clock format 26224496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/31/1970 12:34:56 die xxxi mensis x annoque mcmlxx xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Oct 304 2440891 10 x 10 10/31/1970 die xxxi mensis x annoque mcmlxx 70 lxx 1970}
+test clock-2.981 {conversion of 1970-11-01} {
+    clock format 26310896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/01/1970 12:34:56 die i mensis xi annoque mcmlxx xii h xxxiv m lvi s 19 mcm 01 i  1 i Nov 305 2440892 11 xi 11 11/01/1970 die i mensis xi annoque mcmlxx 70 lxx 1970}
+test clock-2.982 {conversion of 1970-11-30} {
+    clock format 28816496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/30/1970 12:34:56 die xxx mensis xi annoque mcmlxx xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Nov 334 2440921 11 xi 11 11/30/1970 die xxx mensis xi annoque mcmlxx 70 lxx 1970}
+test clock-2.983 {conversion of 1970-12-01} {
+    clock format 28902896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/01/1970 12:34:56 die i mensis xii annoque mcmlxx xii h xxxiv m lvi s 19 mcm 01 i  1 i Dec 335 2440922 12 xii 12 12/01/1970 die i mensis xii annoque mcmlxx 70 lxx 1970}
+test clock-2.984 {conversion of 1970-12-31} {
+    clock format 31494896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/31/1970 12:34:56 die xxxi mensis xii annoque mcmlxx xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Dec 365 2440952 12 xii 12 12/31/1970 die xxxi mensis xii annoque mcmlxx 70 lxx 1970}
+test clock-2.985 {conversion of 1971-01-01} {
+    clock format 31581296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/01/1971 12:34:56 die i mensis i annoque mcmlxxi xii h xxxiv m lvi s 19 mcm 01 i  1 i Jan 001 2440953 01 i  1 01/01/1971 die i mensis i annoque mcmlxxi 71 lxxi 1971}
+test clock-2.986 {conversion of 1971-01-31} {
+    clock format 34173296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/31/1971 12:34:56 die xxxi mensis i annoque mcmlxxi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jan 031 2440983 01 i  1 01/31/1971 die xxxi mensis i annoque mcmlxxi 71 lxxi 1971}
+test clock-2.987 {conversion of 1971-02-01} {
+    clock format 34259696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/01/1971 12:34:56 die i mensis ii annoque mcmlxxi xii h xxxiv m lvi s 19 mcm 01 i  1 i Feb 032 2440984 02 ii  2 02/01/1971 die i mensis ii annoque mcmlxxi 71 lxxi 1971}
+test clock-2.988 {conversion of 1971-02-28} {
+    clock format 36592496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/28/1971 12:34:56 die xxviii mensis ii annoque mcmlxxi xii h xxxiv m lvi s 19 mcm 28 xxviii 28 xxviii Feb 059 2441011 02 ii  2 02/28/1971 die xxviii mensis ii annoque mcmlxxi 71 lxxi 1971}
+test clock-2.989 {conversion of 1971-03-01} {
+    clock format 36678896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/01/1971 12:34:56 die i mensis iii annoque mcmlxxi xii h xxxiv m lvi s 19 mcm 01 i  1 i Mar 060 2441012 03 iii  3 03/01/1971 die i mensis iii annoque mcmlxxi 71 lxxi 1971}
+test clock-2.990 {conversion of 1971-03-31} {
+    clock format 39270896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/31/1971 12:34:56 die xxxi mensis iii annoque mcmlxxi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Mar 090 2441042 03 iii  3 03/31/1971 die xxxi mensis iii annoque mcmlxxi 71 lxxi 1971}
+test clock-2.991 {conversion of 1971-04-01} {
+    clock format 39357296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/01/1971 12:34:56 die i mensis iv annoque mcmlxxi xii h xxxiv m lvi s 19 mcm 01 i  1 i Apr 091 2441043 04 iv  4 04/01/1971 die i mensis iv annoque mcmlxxi 71 lxxi 1971}
+test clock-2.992 {conversion of 1971-04-30} {
+    clock format 41862896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/30/1971 12:34:56 die xxx mensis iv annoque mcmlxxi xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Apr 120 2441072 04 iv  4 04/30/1971 die xxx mensis iv annoque mcmlxxi 71 lxxi 1971}
+test clock-2.993 {conversion of 1971-05-01} {
+    clock format 41949296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/01/1971 12:34:56 die i mensis v annoque mcmlxxi xii h xxxiv m lvi s 19 mcm 01 i  1 i May 121 2441073 05 v  5 05/01/1971 die i mensis v annoque mcmlxxi 71 lxxi 1971}
+test clock-2.994 {conversion of 1971-05-31} {
+    clock format 44541296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/31/1971 12:34:56 die xxxi mensis v annoque mcmlxxi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi May 151 2441103 05 v  5 05/31/1971 die xxxi mensis v annoque mcmlxxi 71 lxxi 1971}
+test clock-2.995 {conversion of 1971-06-01} {
+    clock format 44627696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/01/1971 12:34:56 die i mensis vi annoque mcmlxxi xii h xxxiv m lvi s 19 mcm 01 i  1 i Jun 152 2441104 06 vi  6 06/01/1971 die i mensis vi annoque mcmlxxi 71 lxxi 1971}
+test clock-2.996 {conversion of 1971-06-30} {
+    clock format 47133296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/30/1971 12:34:56 die xxx mensis vi annoque mcmlxxi xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Jun 181 2441133 06 vi  6 06/30/1971 die xxx mensis vi annoque mcmlxxi 71 lxxi 1971}
+test clock-2.997 {conversion of 1971-07-01} {
+    clock format 47219696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/01/1971 12:34:56 die i mensis vii annoque mcmlxxi xii h xxxiv m lvi s 19 mcm 01 i  1 i Jul 182 2441134 07 vii  7 07/01/1971 die i mensis vii annoque mcmlxxi 71 lxxi 1971}
+test clock-2.998 {conversion of 1971-07-31} {
+    clock format 49811696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/31/1971 12:34:56 die xxxi mensis vii annoque mcmlxxi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jul 212 2441164 07 vii  7 07/31/1971 die xxxi mensis vii annoque mcmlxxi 71 lxxi 1971}
+test clock-2.999 {conversion of 1971-08-01} {
+    clock format 49898096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/01/1971 12:34:56 die i mensis viii annoque mcmlxxi xii h xxxiv m lvi s 19 mcm 01 i  1 i Aug 213 2441165 08 viii  8 08/01/1971 die i mensis viii annoque mcmlxxi 71 lxxi 1971}
+test clock-2.1000 {conversion of 1971-08-31} {
+    clock format 52490096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/31/1971 12:34:56 die xxxi mensis viii annoque mcmlxxi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Aug 243 2441195 08 viii  8 08/31/1971 die xxxi mensis viii annoque mcmlxxi 71 lxxi 1971}
+test clock-2.1001 {conversion of 1971-09-01} {
+    clock format 52576496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/01/1971 12:34:56 die i mensis ix annoque mcmlxxi xii h xxxiv m lvi s 19 mcm 01 i  1 i Sep 244 2441196 09 ix  9 09/01/1971 die i mensis ix annoque mcmlxxi 71 lxxi 1971}
+test clock-2.1002 {conversion of 1971-09-30} {
+    clock format 55082096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/30/1971 12:34:56 die xxx mensis ix annoque mcmlxxi xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Sep 273 2441225 09 ix  9 09/30/1971 die xxx mensis ix annoque mcmlxxi 71 lxxi 1971}
+test clock-2.1003 {conversion of 1971-10-01} {
+    clock format 55168496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/01/1971 12:34:56 die i mensis x annoque mcmlxxi xii h xxxiv m lvi s 19 mcm 01 i  1 i Oct 274 2441226 10 x 10 10/01/1971 die i mensis x annoque mcmlxxi 71 lxxi 1971}
+test clock-2.1004 {conversion of 1971-10-31} {
+    clock format 57760496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/31/1971 12:34:56 die xxxi mensis x annoque mcmlxxi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Oct 304 2441256 10 x 10 10/31/1971 die xxxi mensis x annoque mcmlxxi 71 lxxi 1971}
+test clock-2.1005 {conversion of 1971-11-01} {
+    clock format 57846896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/01/1971 12:34:56 die i mensis xi annoque mcmlxxi xii h xxxiv m lvi s 19 mcm 01 i  1 i Nov 305 2441257 11 xi 11 11/01/1971 die i mensis xi annoque mcmlxxi 71 lxxi 1971}
+test clock-2.1006 {conversion of 1971-11-30} {
+    clock format 60352496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/30/1971 12:34:56 die xxx mensis xi annoque mcmlxxi xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Nov 334 2441286 11 xi 11 11/30/1971 die xxx mensis xi annoque mcmlxxi 71 lxxi 1971}
+test clock-2.1007 {conversion of 1971-12-01} {
+    clock format 60438896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/01/1971 12:34:56 die i mensis xii annoque mcmlxxi xii h xxxiv m lvi s 19 mcm 01 i  1 i Dec 335 2441287 12 xii 12 12/01/1971 die i mensis xii annoque mcmlxxi 71 lxxi 1971}
+test clock-2.1008 {conversion of 1971-12-31} {
+    clock format 63030896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/31/1971 12:34:56 die xxxi mensis xii annoque mcmlxxi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Dec 365 2441317 12 xii 12 12/31/1971 die xxxi mensis xii annoque mcmlxxi 71 lxxi 1971}
+test clock-2.1009 {conversion of 1972-01-01} {
+    clock format 63117296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/01/1972 12:34:56 die i mensis i annoque mcmlxxii xii h xxxiv m lvi s 19 mcm 01 i  1 i Jan 001 2441318 01 i  1 01/01/1972 die i mensis i annoque mcmlxxii 72 lxxii 1972}
+test clock-2.1010 {conversion of 1972-01-31} {
+    clock format 65709296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/31/1972 12:34:56 die xxxi mensis i annoque mcmlxxii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jan 031 2441348 01 i  1 01/31/1972 die xxxi mensis i annoque mcmlxxii 72 lxxii 1972}
+test clock-2.1011 {conversion of 1972-02-01} {
+    clock format 65795696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/01/1972 12:34:56 die i mensis ii annoque mcmlxxii xii h xxxiv m lvi s 19 mcm 01 i  1 i Feb 032 2441349 02 ii  2 02/01/1972 die i mensis ii annoque mcmlxxii 72 lxxii 1972}
+test clock-2.1012 {conversion of 1972-02-29} {
+    clock format 68214896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/29/1972 12:34:56 die xxix mensis ii annoque mcmlxxii xii h xxxiv m lvi s 19 mcm 29 xxix 29 xxix Feb 060 2441377 02 ii  2 02/29/1972 die xxix mensis ii annoque mcmlxxii 72 lxxii 1972}
+test clock-2.1013 {conversion of 1972-03-01} {
+    clock format 68301296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/01/1972 12:34:56 die i mensis iii annoque mcmlxxii xii h xxxiv m lvi s 19 mcm 01 i  1 i Mar 061 2441378 03 iii  3 03/01/1972 die i mensis iii annoque mcmlxxii 72 lxxii 1972}
+test clock-2.1014 {conversion of 1972-03-31} {
+    clock format 70893296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/31/1972 12:34:56 die xxxi mensis iii annoque mcmlxxii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Mar 091 2441408 03 iii  3 03/31/1972 die xxxi mensis iii annoque mcmlxxii 72 lxxii 1972}
+test clock-2.1015 {conversion of 1972-04-01} {
+    clock format 70979696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/01/1972 12:34:56 die i mensis iv annoque mcmlxxii xii h xxxiv m lvi s 19 mcm 01 i  1 i Apr 092 2441409 04 iv  4 04/01/1972 die i mensis iv annoque mcmlxxii 72 lxxii 1972}
+test clock-2.1016 {conversion of 1972-04-30} {
+    clock format 73485296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/30/1972 12:34:56 die xxx mensis iv annoque mcmlxxii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Apr 121 2441438 04 iv  4 04/30/1972 die xxx mensis iv annoque mcmlxxii 72 lxxii 1972}
+test clock-2.1017 {conversion of 1972-05-01} {
+    clock format 73571696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/01/1972 12:34:56 die i mensis v annoque mcmlxxii xii h xxxiv m lvi s 19 mcm 01 i  1 i May 122 2441439 05 v  5 05/01/1972 die i mensis v annoque mcmlxxii 72 lxxii 1972}
+test clock-2.1018 {conversion of 1972-05-31} {
+    clock format 76163696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/31/1972 12:34:56 die xxxi mensis v annoque mcmlxxii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi May 152 2441469 05 v  5 05/31/1972 die xxxi mensis v annoque mcmlxxii 72 lxxii 1972}
+test clock-2.1019 {conversion of 1972-06-01} {
+    clock format 76250096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/01/1972 12:34:56 die i mensis vi annoque mcmlxxii xii h xxxiv m lvi s 19 mcm 01 i  1 i Jun 153 2441470 06 vi  6 06/01/1972 die i mensis vi annoque mcmlxxii 72 lxxii 1972}
+test clock-2.1020 {conversion of 1972-06-30} {
+    clock format 78755696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/30/1972 12:34:56 die xxx mensis vi annoque mcmlxxii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Jun 182 2441499 06 vi  6 06/30/1972 die xxx mensis vi annoque mcmlxxii 72 lxxii 1972}
+test clock-2.1021 {conversion of 1972-07-01} {
+    clock format 78842096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/01/1972 12:34:56 die i mensis vii annoque mcmlxxii xii h xxxiv m lvi s 19 mcm 01 i  1 i Jul 183 2441500 07 vii  7 07/01/1972 die i mensis vii annoque mcmlxxii 72 lxxii 1972}
+test clock-2.1022 {conversion of 1972-07-31} {
+    clock format 81434096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/31/1972 12:34:56 die xxxi mensis vii annoque mcmlxxii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jul 213 2441530 07 vii  7 07/31/1972 die xxxi mensis vii annoque mcmlxxii 72 lxxii 1972}
+test clock-2.1023 {conversion of 1972-08-01} {
+    clock format 81520496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/01/1972 12:34:56 die i mensis viii annoque mcmlxxii xii h xxxiv m lvi s 19 mcm 01 i  1 i Aug 214 2441531 08 viii  8 08/01/1972 die i mensis viii annoque mcmlxxii 72 lxxii 1972}
+test clock-2.1024 {conversion of 1972-08-31} {
+    clock format 84112496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/31/1972 12:34:56 die xxxi mensis viii annoque mcmlxxii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Aug 244 2441561 08 viii  8 08/31/1972 die xxxi mensis viii annoque mcmlxxii 72 lxxii 1972}
+test clock-2.1025 {conversion of 1972-09-01} {
+    clock format 84198896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/01/1972 12:34:56 die i mensis ix annoque mcmlxxii xii h xxxiv m lvi s 19 mcm 01 i  1 i Sep 245 2441562 09 ix  9 09/01/1972 die i mensis ix annoque mcmlxxii 72 lxxii 1972}
+test clock-2.1026 {conversion of 1972-09-30} {
+    clock format 86704496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/30/1972 12:34:56 die xxx mensis ix annoque mcmlxxii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Sep 274 2441591 09 ix  9 09/30/1972 die xxx mensis ix annoque mcmlxxii 72 lxxii 1972}
+test clock-2.1027 {conversion of 1972-10-01} {
+    clock format 86790896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/01/1972 12:34:56 die i mensis x annoque mcmlxxii xii h xxxiv m lvi s 19 mcm 01 i  1 i Oct 275 2441592 10 x 10 10/01/1972 die i mensis x annoque mcmlxxii 72 lxxii 1972}
+test clock-2.1028 {conversion of 1972-10-31} {
+    clock format 89382896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/31/1972 12:34:56 die xxxi mensis x annoque mcmlxxii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Oct 305 2441622 10 x 10 10/31/1972 die xxxi mensis x annoque mcmlxxii 72 lxxii 1972}
+test clock-2.1029 {conversion of 1972-11-01} {
+    clock format 89469296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/01/1972 12:34:56 die i mensis xi annoque mcmlxxii xii h xxxiv m lvi s 19 mcm 01 i  1 i Nov 306 2441623 11 xi 11 11/01/1972 die i mensis xi annoque mcmlxxii 72 lxxii 1972}
+test clock-2.1030 {conversion of 1972-11-30} {
+    clock format 91974896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/30/1972 12:34:56 die xxx mensis xi annoque mcmlxxii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Nov 335 2441652 11 xi 11 11/30/1972 die xxx mensis xi annoque mcmlxxii 72 lxxii 1972}
+test clock-2.1031 {conversion of 1972-12-01} {
+    clock format 92061296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/01/1972 12:34:56 die i mensis xii annoque mcmlxxii xii h xxxiv m lvi s 19 mcm 01 i  1 i Dec 336 2441653 12 xii 12 12/01/1972 die i mensis xii annoque mcmlxxii 72 lxxii 1972}
+test clock-2.1032 {conversion of 1972-12-31} {
+    clock format 94653296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/31/1972 12:34:56 die xxxi mensis xii annoque mcmlxxii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Dec 366 2441683 12 xii 12 12/31/1972 die xxxi mensis xii annoque mcmlxxii 72 lxxii 1972}
+test clock-2.1033 {conversion of 1973-01-01} {
+    clock format 94739696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/01/1973 12:34:56 die i mensis i annoque mcmlxxiii xii h xxxiv m lvi s 19 mcm 01 i  1 i Jan 001 2441684 01 i  1 01/01/1973 die i mensis i annoque mcmlxxiii 73 lxxiii 1973}
+test clock-2.1034 {conversion of 1973-01-31} {
+    clock format 97331696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/31/1973 12:34:56 die xxxi mensis i annoque mcmlxxiii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jan 031 2441714 01 i  1 01/31/1973 die xxxi mensis i annoque mcmlxxiii 73 lxxiii 1973}
+test clock-2.1035 {conversion of 1973-02-01} {
+    clock format 97418096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/01/1973 12:34:56 die i mensis ii annoque mcmlxxiii xii h xxxiv m lvi s 19 mcm 01 i  1 i Feb 032 2441715 02 ii  2 02/01/1973 die i mensis ii annoque mcmlxxiii 73 lxxiii 1973}
+test clock-2.1036 {conversion of 1973-02-28} {
+    clock format 99750896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/28/1973 12:34:56 die xxviii mensis ii annoque mcmlxxiii xii h xxxiv m lvi s 19 mcm 28 xxviii 28 xxviii Feb 059 2441742 02 ii  2 02/28/1973 die xxviii mensis ii annoque mcmlxxiii 73 lxxiii 1973}
+test clock-2.1037 {conversion of 1973-03-01} {
+    clock format 99837296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/01/1973 12:34:56 die i mensis iii annoque mcmlxxiii xii h xxxiv m lvi s 19 mcm 01 i  1 i Mar 060 2441743 03 iii  3 03/01/1973 die i mensis iii annoque mcmlxxiii 73 lxxiii 1973}
+test clock-2.1038 {conversion of 1973-03-31} {
+    clock format 102429296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/31/1973 12:34:56 die xxxi mensis iii annoque mcmlxxiii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Mar 090 2441773 03 iii  3 03/31/1973 die xxxi mensis iii annoque mcmlxxiii 73 lxxiii 1973}
+test clock-2.1039 {conversion of 1973-04-01} {
+    clock format 102515696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/01/1973 12:34:56 die i mensis iv annoque mcmlxxiii xii h xxxiv m lvi s 19 mcm 01 i  1 i Apr 091 2441774 04 iv  4 04/01/1973 die i mensis iv annoque mcmlxxiii 73 lxxiii 1973}
+test clock-2.1040 {conversion of 1973-04-30} {
+    clock format 105021296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/30/1973 12:34:56 die xxx mensis iv annoque mcmlxxiii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Apr 120 2441803 04 iv  4 04/30/1973 die xxx mensis iv annoque mcmlxxiii 73 lxxiii 1973}
+test clock-2.1041 {conversion of 1973-05-01} {
+    clock format 105107696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/01/1973 12:34:56 die i mensis v annoque mcmlxxiii xii h xxxiv m lvi s 19 mcm 01 i  1 i May 121 2441804 05 v  5 05/01/1973 die i mensis v annoque mcmlxxiii 73 lxxiii 1973}
+test clock-2.1042 {conversion of 1973-05-31} {
+    clock format 107699696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/31/1973 12:34:56 die xxxi mensis v annoque mcmlxxiii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi May 151 2441834 05 v  5 05/31/1973 die xxxi mensis v annoque mcmlxxiii 73 lxxiii 1973}
+test clock-2.1043 {conversion of 1973-06-01} {
+    clock format 107786096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/01/1973 12:34:56 die i mensis vi annoque mcmlxxiii xii h xxxiv m lvi s 19 mcm 01 i  1 i Jun 152 2441835 06 vi  6 06/01/1973 die i mensis vi annoque mcmlxxiii 73 lxxiii 1973}
+test clock-2.1044 {conversion of 1973-06-30} {
+    clock format 110291696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/30/1973 12:34:56 die xxx mensis vi annoque mcmlxxiii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Jun 181 2441864 06 vi  6 06/30/1973 die xxx mensis vi annoque mcmlxxiii 73 lxxiii 1973}
+test clock-2.1045 {conversion of 1973-07-01} {
+    clock format 110378096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/01/1973 12:34:56 die i mensis vii annoque mcmlxxiii xii h xxxiv m lvi s 19 mcm 01 i  1 i Jul 182 2441865 07 vii  7 07/01/1973 die i mensis vii annoque mcmlxxiii 73 lxxiii 1973}
+test clock-2.1046 {conversion of 1973-07-31} {
+    clock format 112970096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/31/1973 12:34:56 die xxxi mensis vii annoque mcmlxxiii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jul 212 2441895 07 vii  7 07/31/1973 die xxxi mensis vii annoque mcmlxxiii 73 lxxiii 1973}
+test clock-2.1047 {conversion of 1973-08-01} {
+    clock format 113056496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/01/1973 12:34:56 die i mensis viii annoque mcmlxxiii xii h xxxiv m lvi s 19 mcm 01 i  1 i Aug 213 2441896 08 viii  8 08/01/1973 die i mensis viii annoque mcmlxxiii 73 lxxiii 1973}
+test clock-2.1048 {conversion of 1973-08-31} {
+    clock format 115648496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/31/1973 12:34:56 die xxxi mensis viii annoque mcmlxxiii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Aug 243 2441926 08 viii  8 08/31/1973 die xxxi mensis viii annoque mcmlxxiii 73 lxxiii 1973}
+test clock-2.1049 {conversion of 1973-09-01} {
+    clock format 115734896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/01/1973 12:34:56 die i mensis ix annoque mcmlxxiii xii h xxxiv m lvi s 19 mcm 01 i  1 i Sep 244 2441927 09 ix  9 09/01/1973 die i mensis ix annoque mcmlxxiii 73 lxxiii 1973}
+test clock-2.1050 {conversion of 1973-09-30} {
+    clock format 118240496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/30/1973 12:34:56 die xxx mensis ix annoque mcmlxxiii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Sep 273 2441956 09 ix  9 09/30/1973 die xxx mensis ix annoque mcmlxxiii 73 lxxiii 1973}
+test clock-2.1051 {conversion of 1973-10-01} {
+    clock format 118326896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/01/1973 12:34:56 die i mensis x annoque mcmlxxiii xii h xxxiv m lvi s 19 mcm 01 i  1 i Oct 274 2441957 10 x 10 10/01/1973 die i mensis x annoque mcmlxxiii 73 lxxiii 1973}
+test clock-2.1052 {conversion of 1973-10-31} {
+    clock format 120918896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/31/1973 12:34:56 die xxxi mensis x annoque mcmlxxiii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Oct 304 2441987 10 x 10 10/31/1973 die xxxi mensis x annoque mcmlxxiii 73 lxxiii 1973}
+test clock-2.1053 {conversion of 1973-11-01} {
+    clock format 121005296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/01/1973 12:34:56 die i mensis xi annoque mcmlxxiii xii h xxxiv m lvi s 19 mcm 01 i  1 i Nov 305 2441988 11 xi 11 11/01/1973 die i mensis xi annoque mcmlxxiii 73 lxxiii 1973}
+test clock-2.1054 {conversion of 1973-11-30} {
+    clock format 123510896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/30/1973 12:34:56 die xxx mensis xi annoque mcmlxxiii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Nov 334 2442017 11 xi 11 11/30/1973 die xxx mensis xi annoque mcmlxxiii 73 lxxiii 1973}
+test clock-2.1055 {conversion of 1973-12-01} {
+    clock format 123597296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/01/1973 12:34:56 die i mensis xii annoque mcmlxxiii xii h xxxiv m lvi s 19 mcm 01 i  1 i Dec 335 2442018 12 xii 12 12/01/1973 die i mensis xii annoque mcmlxxiii 73 lxxiii 1973}
+test clock-2.1056 {conversion of 1973-12-31} {
+    clock format 126189296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/31/1973 12:34:56 die xxxi mensis xii annoque mcmlxxiii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Dec 365 2442048 12 xii 12 12/31/1973 die xxxi mensis xii annoque mcmlxxiii 73 lxxiii 1973}
+test clock-2.1057 {conversion of 1974-01-01} {
+    clock format 126275696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/01/1974 12:34:56 die i mensis i annoque mcmlxxiv xii h xxxiv m lvi s 19 mcm 01 i  1 i Jan 001 2442049 01 i  1 01/01/1974 die i mensis i annoque mcmlxxiv 74 lxxiv 1974}
+test clock-2.1058 {conversion of 1974-01-31} {
+    clock format 128867696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/31/1974 12:34:56 die xxxi mensis i annoque mcmlxxiv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jan 031 2442079 01 i  1 01/31/1974 die xxxi mensis i annoque mcmlxxiv 74 lxxiv 1974}
+test clock-2.1059 {conversion of 1974-02-01} {
+    clock format 128954096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/01/1974 12:34:56 die i mensis ii annoque mcmlxxiv xii h xxxiv m lvi s 19 mcm 01 i  1 i Feb 032 2442080 02 ii  2 02/01/1974 die i mensis ii annoque mcmlxxiv 74 lxxiv 1974}
+test clock-2.1060 {conversion of 1974-02-28} {
+    clock format 131286896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/28/1974 12:34:56 die xxviii mensis ii annoque mcmlxxiv xii h xxxiv m lvi s 19 mcm 28 xxviii 28 xxviii Feb 059 2442107 02 ii  2 02/28/1974 die xxviii mensis ii annoque mcmlxxiv 74 lxxiv 1974}
+test clock-2.1061 {conversion of 1974-03-01} {
+    clock format 131373296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/01/1974 12:34:56 die i mensis iii annoque mcmlxxiv xii h xxxiv m lvi s 19 mcm 01 i  1 i Mar 060 2442108 03 iii  3 03/01/1974 die i mensis iii annoque mcmlxxiv 74 lxxiv 1974}
+test clock-2.1062 {conversion of 1974-03-31} {
+    clock format 133965296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/31/1974 12:34:56 die xxxi mensis iii annoque mcmlxxiv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Mar 090 2442138 03 iii  3 03/31/1974 die xxxi mensis iii annoque mcmlxxiv 74 lxxiv 1974}
+test clock-2.1063 {conversion of 1974-04-01} {
+    clock format 134051696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/01/1974 12:34:56 die i mensis iv annoque mcmlxxiv xii h xxxiv m lvi s 19 mcm 01 i  1 i Apr 091 2442139 04 iv  4 04/01/1974 die i mensis iv annoque mcmlxxiv 74 lxxiv 1974}
+test clock-2.1064 {conversion of 1974-04-30} {
+    clock format 136557296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/30/1974 12:34:56 die xxx mensis iv annoque mcmlxxiv xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Apr 120 2442168 04 iv  4 04/30/1974 die xxx mensis iv annoque mcmlxxiv 74 lxxiv 1974}
+test clock-2.1065 {conversion of 1974-05-01} {
+    clock format 136643696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/01/1974 12:34:56 die i mensis v annoque mcmlxxiv xii h xxxiv m lvi s 19 mcm 01 i  1 i May 121 2442169 05 v  5 05/01/1974 die i mensis v annoque mcmlxxiv 74 lxxiv 1974}
+test clock-2.1066 {conversion of 1974-05-31} {
+    clock format 139235696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/31/1974 12:34:56 die xxxi mensis v annoque mcmlxxiv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi May 151 2442199 05 v  5 05/31/1974 die xxxi mensis v annoque mcmlxxiv 74 lxxiv 1974}
+test clock-2.1067 {conversion of 1974-06-01} {
+    clock format 139322096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/01/1974 12:34:56 die i mensis vi annoque mcmlxxiv xii h xxxiv m lvi s 19 mcm 01 i  1 i Jun 152 2442200 06 vi  6 06/01/1974 die i mensis vi annoque mcmlxxiv 74 lxxiv 1974}
+test clock-2.1068 {conversion of 1974-06-30} {
+    clock format 141827696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/30/1974 12:34:56 die xxx mensis vi annoque mcmlxxiv xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Jun 181 2442229 06 vi  6 06/30/1974 die xxx mensis vi annoque mcmlxxiv 74 lxxiv 1974}
+test clock-2.1069 {conversion of 1974-07-01} {
+    clock format 141914096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/01/1974 12:34:56 die i mensis vii annoque mcmlxxiv xii h xxxiv m lvi s 19 mcm 01 i  1 i Jul 182 2442230 07 vii  7 07/01/1974 die i mensis vii annoque mcmlxxiv 74 lxxiv 1974}
+test clock-2.1070 {conversion of 1974-07-31} {
+    clock format 144506096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/31/1974 12:34:56 die xxxi mensis vii annoque mcmlxxiv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jul 212 2442260 07 vii  7 07/31/1974 die xxxi mensis vii annoque mcmlxxiv 74 lxxiv 1974}
+test clock-2.1071 {conversion of 1974-08-01} {
+    clock format 144592496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/01/1974 12:34:56 die i mensis viii annoque mcmlxxiv xii h xxxiv m lvi s 19 mcm 01 i  1 i Aug 213 2442261 08 viii  8 08/01/1974 die i mensis viii annoque mcmlxxiv 74 lxxiv 1974}
+test clock-2.1072 {conversion of 1974-08-31} {
+    clock format 147184496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/31/1974 12:34:56 die xxxi mensis viii annoque mcmlxxiv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Aug 243 2442291 08 viii  8 08/31/1974 die xxxi mensis viii annoque mcmlxxiv 74 lxxiv 1974}
+test clock-2.1073 {conversion of 1974-09-01} {
+    clock format 147270896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/01/1974 12:34:56 die i mensis ix annoque mcmlxxiv xii h xxxiv m lvi s 19 mcm 01 i  1 i Sep 244 2442292 09 ix  9 09/01/1974 die i mensis ix annoque mcmlxxiv 74 lxxiv 1974}
+test clock-2.1074 {conversion of 1974-09-30} {
+    clock format 149776496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/30/1974 12:34:56 die xxx mensis ix annoque mcmlxxiv xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Sep 273 2442321 09 ix  9 09/30/1974 die xxx mensis ix annoque mcmlxxiv 74 lxxiv 1974}
+test clock-2.1075 {conversion of 1974-10-01} {
+    clock format 149862896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/01/1974 12:34:56 die i mensis x annoque mcmlxxiv xii h xxxiv m lvi s 19 mcm 01 i  1 i Oct 274 2442322 10 x 10 10/01/1974 die i mensis x annoque mcmlxxiv 74 lxxiv 1974}
+test clock-2.1076 {conversion of 1974-10-31} {
+    clock format 152454896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/31/1974 12:34:56 die xxxi mensis x annoque mcmlxxiv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Oct 304 2442352 10 x 10 10/31/1974 die xxxi mensis x annoque mcmlxxiv 74 lxxiv 1974}
+test clock-2.1077 {conversion of 1974-11-01} {
+    clock format 152541296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/01/1974 12:34:56 die i mensis xi annoque mcmlxxiv xii h xxxiv m lvi s 19 mcm 01 i  1 i Nov 305 2442353 11 xi 11 11/01/1974 die i mensis xi annoque mcmlxxiv 74 lxxiv 1974}
+test clock-2.1078 {conversion of 1974-11-30} {
+    clock format 155046896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/30/1974 12:34:56 die xxx mensis xi annoque mcmlxxiv xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Nov 334 2442382 11 xi 11 11/30/1974 die xxx mensis xi annoque mcmlxxiv 74 lxxiv 1974}
+test clock-2.1079 {conversion of 1974-12-01} {
+    clock format 155133296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/01/1974 12:34:56 die i mensis xii annoque mcmlxxiv xii h xxxiv m lvi s 19 mcm 01 i  1 i Dec 335 2442383 12 xii 12 12/01/1974 die i mensis xii annoque mcmlxxiv 74 lxxiv 1974}
+test clock-2.1080 {conversion of 1974-12-31} {
+    clock format 157725296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/31/1974 12:34:56 die xxxi mensis xii annoque mcmlxxiv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Dec 365 2442413 12 xii 12 12/31/1974 die xxxi mensis xii annoque mcmlxxiv 74 lxxiv 1974}
+test clock-2.1081 {conversion of 1975-01-01} {
+    clock format 157811696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/01/1975 12:34:56 die i mensis i annoque mcmlxxv xii h xxxiv m lvi s 19 mcm 01 i  1 i Jan 001 2442414 01 i  1 01/01/1975 die i mensis i annoque mcmlxxv 75 lxxv 1975}
+test clock-2.1082 {conversion of 1975-01-31} {
+    clock format 160403696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/31/1975 12:34:56 die xxxi mensis i annoque mcmlxxv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jan 031 2442444 01 i  1 01/31/1975 die xxxi mensis i annoque mcmlxxv 75 lxxv 1975}
+test clock-2.1083 {conversion of 1975-02-01} {
+    clock format 160490096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/01/1975 12:34:56 die i mensis ii annoque mcmlxxv xii h xxxiv m lvi s 19 mcm 01 i  1 i Feb 032 2442445 02 ii  2 02/01/1975 die i mensis ii annoque mcmlxxv 75 lxxv 1975}
+test clock-2.1084 {conversion of 1975-02-28} {
+    clock format 162822896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/28/1975 12:34:56 die xxviii mensis ii annoque mcmlxxv xii h xxxiv m lvi s 19 mcm 28 xxviii 28 xxviii Feb 059 2442472 02 ii  2 02/28/1975 die xxviii mensis ii annoque mcmlxxv 75 lxxv 1975}
+test clock-2.1085 {conversion of 1975-03-01} {
+    clock format 162909296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/01/1975 12:34:56 die i mensis iii annoque mcmlxxv xii h xxxiv m lvi s 19 mcm 01 i  1 i Mar 060 2442473 03 iii  3 03/01/1975 die i mensis iii annoque mcmlxxv 75 lxxv 1975}
+test clock-2.1086 {conversion of 1975-03-31} {
+    clock format 165501296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/31/1975 12:34:56 die xxxi mensis iii annoque mcmlxxv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Mar 090 2442503 03 iii  3 03/31/1975 die xxxi mensis iii annoque mcmlxxv 75 lxxv 1975}
+test clock-2.1087 {conversion of 1975-04-01} {
+    clock format 165587696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/01/1975 12:34:56 die i mensis iv annoque mcmlxxv xii h xxxiv m lvi s 19 mcm 01 i  1 i Apr 091 2442504 04 iv  4 04/01/1975 die i mensis iv annoque mcmlxxv 75 lxxv 1975}
+test clock-2.1088 {conversion of 1975-04-30} {
+    clock format 168093296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/30/1975 12:34:56 die xxx mensis iv annoque mcmlxxv xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Apr 120 2442533 04 iv  4 04/30/1975 die xxx mensis iv annoque mcmlxxv 75 lxxv 1975}
+test clock-2.1089 {conversion of 1975-05-01} {
+    clock format 168179696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/01/1975 12:34:56 die i mensis v annoque mcmlxxv xii h xxxiv m lvi s 19 mcm 01 i  1 i May 121 2442534 05 v  5 05/01/1975 die i mensis v annoque mcmlxxv 75 lxxv 1975}
+test clock-2.1090 {conversion of 1975-05-31} {
+    clock format 170771696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/31/1975 12:34:56 die xxxi mensis v annoque mcmlxxv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi May 151 2442564 05 v  5 05/31/1975 die xxxi mensis v annoque mcmlxxv 75 lxxv 1975}
+test clock-2.1091 {conversion of 1975-06-01} {
+    clock format 170858096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/01/1975 12:34:56 die i mensis vi annoque mcmlxxv xii h xxxiv m lvi s 19 mcm 01 i  1 i Jun 152 2442565 06 vi  6 06/01/1975 die i mensis vi annoque mcmlxxv 75 lxxv 1975}
+test clock-2.1092 {conversion of 1975-06-30} {
+    clock format 173363696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/30/1975 12:34:56 die xxx mensis vi annoque mcmlxxv xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Jun 181 2442594 06 vi  6 06/30/1975 die xxx mensis vi annoque mcmlxxv 75 lxxv 1975}
+test clock-2.1093 {conversion of 1975-07-01} {
+    clock format 173450096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/01/1975 12:34:56 die i mensis vii annoque mcmlxxv xii h xxxiv m lvi s 19 mcm 01 i  1 i Jul 182 2442595 07 vii  7 07/01/1975 die i mensis vii annoque mcmlxxv 75 lxxv 1975}
+test clock-2.1094 {conversion of 1975-07-31} {
+    clock format 176042096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/31/1975 12:34:56 die xxxi mensis vii annoque mcmlxxv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jul 212 2442625 07 vii  7 07/31/1975 die xxxi mensis vii annoque mcmlxxv 75 lxxv 1975}
+test clock-2.1095 {conversion of 1975-08-01} {
+    clock format 176128496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/01/1975 12:34:56 die i mensis viii annoque mcmlxxv xii h xxxiv m lvi s 19 mcm 01 i  1 i Aug 213 2442626 08 viii  8 08/01/1975 die i mensis viii annoque mcmlxxv 75 lxxv 1975}
+test clock-2.1096 {conversion of 1975-08-31} {
+    clock format 178720496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/31/1975 12:34:56 die xxxi mensis viii annoque mcmlxxv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Aug 243 2442656 08 viii  8 08/31/1975 die xxxi mensis viii annoque mcmlxxv 75 lxxv 1975}
+test clock-2.1097 {conversion of 1975-09-01} {
+    clock format 178806896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/01/1975 12:34:56 die i mensis ix annoque mcmlxxv xii h xxxiv m lvi s 19 mcm 01 i  1 i Sep 244 2442657 09 ix  9 09/01/1975 die i mensis ix annoque mcmlxxv 75 lxxv 1975}
+test clock-2.1098 {conversion of 1975-09-30} {
+    clock format 181312496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/30/1975 12:34:56 die xxx mensis ix annoque mcmlxxv xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Sep 273 2442686 09 ix  9 09/30/1975 die xxx mensis ix annoque mcmlxxv 75 lxxv 1975}
+test clock-2.1099 {conversion of 1975-10-01} {
+    clock format 181398896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/01/1975 12:34:56 die i mensis x annoque mcmlxxv xii h xxxiv m lvi s 19 mcm 01 i  1 i Oct 274 2442687 10 x 10 10/01/1975 die i mensis x annoque mcmlxxv 75 lxxv 1975}
+test clock-2.1100 {conversion of 1975-10-31} {
+    clock format 183990896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/31/1975 12:34:56 die xxxi mensis x annoque mcmlxxv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Oct 304 2442717 10 x 10 10/31/1975 die xxxi mensis x annoque mcmlxxv 75 lxxv 1975}
+test clock-2.1101 {conversion of 1975-11-01} {
+    clock format 184077296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/01/1975 12:34:56 die i mensis xi annoque mcmlxxv xii h xxxiv m lvi s 19 mcm 01 i  1 i Nov 305 2442718 11 xi 11 11/01/1975 die i mensis xi annoque mcmlxxv 75 lxxv 1975}
+test clock-2.1102 {conversion of 1975-11-30} {
+    clock format 186582896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/30/1975 12:34:56 die xxx mensis xi annoque mcmlxxv xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Nov 334 2442747 11 xi 11 11/30/1975 die xxx mensis xi annoque mcmlxxv 75 lxxv 1975}
+test clock-2.1103 {conversion of 1975-12-01} {
+    clock format 186669296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/01/1975 12:34:56 die i mensis xii annoque mcmlxxv xii h xxxiv m lvi s 19 mcm 01 i  1 i Dec 335 2442748 12 xii 12 12/01/1975 die i mensis xii annoque mcmlxxv 75 lxxv 1975}
+test clock-2.1104 {conversion of 1975-12-31} {
+    clock format 189261296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/31/1975 12:34:56 die xxxi mensis xii annoque mcmlxxv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Dec 365 2442778 12 xii 12 12/31/1975 die xxxi mensis xii annoque mcmlxxv 75 lxxv 1975}
+test clock-2.1105 {conversion of 1976-01-01} {
+    clock format 189347696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/01/1976 12:34:56 die i mensis i annoque mcmlxxvi xii h xxxiv m lvi s 19 mcm 01 i  1 i Jan 001 2442779 01 i  1 01/01/1976 die i mensis i annoque mcmlxxvi 76 lxxvi 1976}
+test clock-2.1106 {conversion of 1976-01-31} {
+    clock format 191939696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/31/1976 12:34:56 die xxxi mensis i annoque mcmlxxvi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jan 031 2442809 01 i  1 01/31/1976 die xxxi mensis i annoque mcmlxxvi 76 lxxvi 1976}
+test clock-2.1107 {conversion of 1976-02-01} {
+    clock format 192026096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/01/1976 12:34:56 die i mensis ii annoque mcmlxxvi xii h xxxiv m lvi s 19 mcm 01 i  1 i Feb 032 2442810 02 ii  2 02/01/1976 die i mensis ii annoque mcmlxxvi 76 lxxvi 1976}
+test clock-2.1108 {conversion of 1976-02-29} {
+    clock format 194445296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/29/1976 12:34:56 die xxix mensis ii annoque mcmlxxvi xii h xxxiv m lvi s 19 mcm 29 xxix 29 xxix Feb 060 2442838 02 ii  2 02/29/1976 die xxix mensis ii annoque mcmlxxvi 76 lxxvi 1976}
+test clock-2.1109 {conversion of 1976-03-01} {
+    clock format 194531696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/01/1976 12:34:56 die i mensis iii annoque mcmlxxvi xii h xxxiv m lvi s 19 mcm 01 i  1 i Mar 061 2442839 03 iii  3 03/01/1976 die i mensis iii annoque mcmlxxvi 76 lxxvi 1976}
+test clock-2.1110 {conversion of 1976-03-31} {
+    clock format 197123696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/31/1976 12:34:56 die xxxi mensis iii annoque mcmlxxvi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Mar 091 2442869 03 iii  3 03/31/1976 die xxxi mensis iii annoque mcmlxxvi 76 lxxvi 1976}
+test clock-2.1111 {conversion of 1976-04-01} {
+    clock format 197210096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/01/1976 12:34:56 die i mensis iv annoque mcmlxxvi xii h xxxiv m lvi s 19 mcm 01 i  1 i Apr 092 2442870 04 iv  4 04/01/1976 die i mensis iv annoque mcmlxxvi 76 lxxvi 1976}
+test clock-2.1112 {conversion of 1976-04-30} {
+    clock format 199715696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/30/1976 12:34:56 die xxx mensis iv annoque mcmlxxvi xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Apr 121 2442899 04 iv  4 04/30/1976 die xxx mensis iv annoque mcmlxxvi 76 lxxvi 1976}
+test clock-2.1113 {conversion of 1976-05-01} {
+    clock format 199802096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/01/1976 12:34:56 die i mensis v annoque mcmlxxvi xii h xxxiv m lvi s 19 mcm 01 i  1 i May 122 2442900 05 v  5 05/01/1976 die i mensis v annoque mcmlxxvi 76 lxxvi 1976}
+test clock-2.1114 {conversion of 1976-05-31} {
+    clock format 202394096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/31/1976 12:34:56 die xxxi mensis v annoque mcmlxxvi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi May 152 2442930 05 v  5 05/31/1976 die xxxi mensis v annoque mcmlxxvi 76 lxxvi 1976}
+test clock-2.1115 {conversion of 1976-06-01} {
+    clock format 202480496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/01/1976 12:34:56 die i mensis vi annoque mcmlxxvi xii h xxxiv m lvi s 19 mcm 01 i  1 i Jun 153 2442931 06 vi  6 06/01/1976 die i mensis vi annoque mcmlxxvi 76 lxxvi 1976}
+test clock-2.1116 {conversion of 1976-06-30} {
+    clock format 204986096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/30/1976 12:34:56 die xxx mensis vi annoque mcmlxxvi xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Jun 182 2442960 06 vi  6 06/30/1976 die xxx mensis vi annoque mcmlxxvi 76 lxxvi 1976}
+test clock-2.1117 {conversion of 1976-07-01} {
+    clock format 205072496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/01/1976 12:34:56 die i mensis vii annoque mcmlxxvi xii h xxxiv m lvi s 19 mcm 01 i  1 i Jul 183 2442961 07 vii  7 07/01/1976 die i mensis vii annoque mcmlxxvi 76 lxxvi 1976}
+test clock-2.1118 {conversion of 1976-07-31} {
+    clock format 207664496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/31/1976 12:34:56 die xxxi mensis vii annoque mcmlxxvi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jul 213 2442991 07 vii  7 07/31/1976 die xxxi mensis vii annoque mcmlxxvi 76 lxxvi 1976}
+test clock-2.1119 {conversion of 1976-08-01} {
+    clock format 207750896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/01/1976 12:34:56 die i mensis viii annoque mcmlxxvi xii h xxxiv m lvi s 19 mcm 01 i  1 i Aug 214 2442992 08 viii  8 08/01/1976 die i mensis viii annoque mcmlxxvi 76 lxxvi 1976}
+test clock-2.1120 {conversion of 1976-08-31} {
+    clock format 210342896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/31/1976 12:34:56 die xxxi mensis viii annoque mcmlxxvi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Aug 244 2443022 08 viii  8 08/31/1976 die xxxi mensis viii annoque mcmlxxvi 76 lxxvi 1976}
+test clock-2.1121 {conversion of 1976-09-01} {
+    clock format 210429296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/01/1976 12:34:56 die i mensis ix annoque mcmlxxvi xii h xxxiv m lvi s 19 mcm 01 i  1 i Sep 245 2443023 09 ix  9 09/01/1976 die i mensis ix annoque mcmlxxvi 76 lxxvi 1976}
+test clock-2.1122 {conversion of 1976-09-30} {
+    clock format 212934896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/30/1976 12:34:56 die xxx mensis ix annoque mcmlxxvi xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Sep 274 2443052 09 ix  9 09/30/1976 die xxx mensis ix annoque mcmlxxvi 76 lxxvi 1976}
+test clock-2.1123 {conversion of 1976-10-01} {
+    clock format 213021296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/01/1976 12:34:56 die i mensis x annoque mcmlxxvi xii h xxxiv m lvi s 19 mcm 01 i  1 i Oct 275 2443053 10 x 10 10/01/1976 die i mensis x annoque mcmlxxvi 76 lxxvi 1976}
+test clock-2.1124 {conversion of 1976-10-31} {
+    clock format 215613296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/31/1976 12:34:56 die xxxi mensis x annoque mcmlxxvi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Oct 305 2443083 10 x 10 10/31/1976 die xxxi mensis x annoque mcmlxxvi 76 lxxvi 1976}
+test clock-2.1125 {conversion of 1976-11-01} {
+    clock format 215699696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/01/1976 12:34:56 die i mensis xi annoque mcmlxxvi xii h xxxiv m lvi s 19 mcm 01 i  1 i Nov 306 2443084 11 xi 11 11/01/1976 die i mensis xi annoque mcmlxxvi 76 lxxvi 1976}
+test clock-2.1126 {conversion of 1976-11-30} {
+    clock format 218205296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/30/1976 12:34:56 die xxx mensis xi annoque mcmlxxvi xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Nov 335 2443113 11 xi 11 11/30/1976 die xxx mensis xi annoque mcmlxxvi 76 lxxvi 1976}
+test clock-2.1127 {conversion of 1976-12-01} {
+    clock format 218291696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/01/1976 12:34:56 die i mensis xii annoque mcmlxxvi xii h xxxiv m lvi s 19 mcm 01 i  1 i Dec 336 2443114 12 xii 12 12/01/1976 die i mensis xii annoque mcmlxxvi 76 lxxvi 1976}
+test clock-2.1128 {conversion of 1976-12-31} {
+    clock format 220883696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/31/1976 12:34:56 die xxxi mensis xii annoque mcmlxxvi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Dec 366 2443144 12 xii 12 12/31/1976 die xxxi mensis xii annoque mcmlxxvi 76 lxxvi 1976}
+test clock-2.1129 {conversion of 1977-01-01} {
+    clock format 220970096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/01/1977 12:34:56 die i mensis i annoque mcmlxxvii xii h xxxiv m lvi s 19 mcm 01 i  1 i Jan 001 2443145 01 i  1 01/01/1977 die i mensis i annoque mcmlxxvii 77 lxxvii 1977}
+test clock-2.1130 {conversion of 1977-01-31} {
+    clock format 223562096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/31/1977 12:34:56 die xxxi mensis i annoque mcmlxxvii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jan 031 2443175 01 i  1 01/31/1977 die xxxi mensis i annoque mcmlxxvii 77 lxxvii 1977}
+test clock-2.1131 {conversion of 1977-02-01} {
+    clock format 223648496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/01/1977 12:34:56 die i mensis ii annoque mcmlxxvii xii h xxxiv m lvi s 19 mcm 01 i  1 i Feb 032 2443176 02 ii  2 02/01/1977 die i mensis ii annoque mcmlxxvii 77 lxxvii 1977}
+test clock-2.1132 {conversion of 1977-02-28} {
+    clock format 225981296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/28/1977 12:34:56 die xxviii mensis ii annoque mcmlxxvii xii h xxxiv m lvi s 19 mcm 28 xxviii 28 xxviii Feb 059 2443203 02 ii  2 02/28/1977 die xxviii mensis ii annoque mcmlxxvii 77 lxxvii 1977}
+test clock-2.1133 {conversion of 1977-03-01} {
+    clock format 226067696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/01/1977 12:34:56 die i mensis iii annoque mcmlxxvii xii h xxxiv m lvi s 19 mcm 01 i  1 i Mar 060 2443204 03 iii  3 03/01/1977 die i mensis iii annoque mcmlxxvii 77 lxxvii 1977}
+test clock-2.1134 {conversion of 1977-03-31} {
+    clock format 228659696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/31/1977 12:34:56 die xxxi mensis iii annoque mcmlxxvii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Mar 090 2443234 03 iii  3 03/31/1977 die xxxi mensis iii annoque mcmlxxvii 77 lxxvii 1977}
+test clock-2.1135 {conversion of 1977-04-01} {
+    clock format 228746096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/01/1977 12:34:56 die i mensis iv annoque mcmlxxvii xii h xxxiv m lvi s 19 mcm 01 i  1 i Apr 091 2443235 04 iv  4 04/01/1977 die i mensis iv annoque mcmlxxvii 77 lxxvii 1977}
+test clock-2.1136 {conversion of 1977-04-30} {
+    clock format 231251696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/30/1977 12:34:56 die xxx mensis iv annoque mcmlxxvii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Apr 120 2443264 04 iv  4 04/30/1977 die xxx mensis iv annoque mcmlxxvii 77 lxxvii 1977}
+test clock-2.1137 {conversion of 1977-05-01} {
+    clock format 231338096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/01/1977 12:34:56 die i mensis v annoque mcmlxxvii xii h xxxiv m lvi s 19 mcm 01 i  1 i May 121 2443265 05 v  5 05/01/1977 die i mensis v annoque mcmlxxvii 77 lxxvii 1977}
+test clock-2.1138 {conversion of 1977-05-31} {
+    clock format 233930096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/31/1977 12:34:56 die xxxi mensis v annoque mcmlxxvii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi May 151 2443295 05 v  5 05/31/1977 die xxxi mensis v annoque mcmlxxvii 77 lxxvii 1977}
+test clock-2.1139 {conversion of 1977-06-01} {
+    clock format 234016496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/01/1977 12:34:56 die i mensis vi annoque mcmlxxvii xii h xxxiv m lvi s 19 mcm 01 i  1 i Jun 152 2443296 06 vi  6 06/01/1977 die i mensis vi annoque mcmlxxvii 77 lxxvii 1977}
+test clock-2.1140 {conversion of 1977-06-30} {
+    clock format 236522096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/30/1977 12:34:56 die xxx mensis vi annoque mcmlxxvii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Jun 181 2443325 06 vi  6 06/30/1977 die xxx mensis vi annoque mcmlxxvii 77 lxxvii 1977}
+test clock-2.1141 {conversion of 1977-07-01} {
+    clock format 236608496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/01/1977 12:34:56 die i mensis vii annoque mcmlxxvii xii h xxxiv m lvi s 19 mcm 01 i  1 i Jul 182 2443326 07 vii  7 07/01/1977 die i mensis vii annoque mcmlxxvii 77 lxxvii 1977}
+test clock-2.1142 {conversion of 1977-07-31} {
+    clock format 239200496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/31/1977 12:34:56 die xxxi mensis vii annoque mcmlxxvii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jul 212 2443356 07 vii  7 07/31/1977 die xxxi mensis vii annoque mcmlxxvii 77 lxxvii 1977}
+test clock-2.1143 {conversion of 1977-08-01} {
+    clock format 239286896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/01/1977 12:34:56 die i mensis viii annoque mcmlxxvii xii h xxxiv m lvi s 19 mcm 01 i  1 i Aug 213 2443357 08 viii  8 08/01/1977 die i mensis viii annoque mcmlxxvii 77 lxxvii 1977}
+test clock-2.1144 {conversion of 1977-08-31} {
+    clock format 241878896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/31/1977 12:34:56 die xxxi mensis viii annoque mcmlxxvii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Aug 243 2443387 08 viii  8 08/31/1977 die xxxi mensis viii annoque mcmlxxvii 77 lxxvii 1977}
+test clock-2.1145 {conversion of 1977-09-01} {
+    clock format 241965296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/01/1977 12:34:56 die i mensis ix annoque mcmlxxvii xii h xxxiv m lvi s 19 mcm 01 i  1 i Sep 244 2443388 09 ix  9 09/01/1977 die i mensis ix annoque mcmlxxvii 77 lxxvii 1977}
+test clock-2.1146 {conversion of 1977-09-30} {
+    clock format 244470896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/30/1977 12:34:56 die xxx mensis ix annoque mcmlxxvii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Sep 273 2443417 09 ix  9 09/30/1977 die xxx mensis ix annoque mcmlxxvii 77 lxxvii 1977}
+test clock-2.1147 {conversion of 1977-10-01} {
+    clock format 244557296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/01/1977 12:34:56 die i mensis x annoque mcmlxxvii xii h xxxiv m lvi s 19 mcm 01 i  1 i Oct 274 2443418 10 x 10 10/01/1977 die i mensis x annoque mcmlxxvii 77 lxxvii 1977}
+test clock-2.1148 {conversion of 1977-10-31} {
+    clock format 247149296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/31/1977 12:34:56 die xxxi mensis x annoque mcmlxxvii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Oct 304 2443448 10 x 10 10/31/1977 die xxxi mensis x annoque mcmlxxvii 77 lxxvii 1977}
+test clock-2.1149 {conversion of 1977-11-01} {
+    clock format 247235696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/01/1977 12:34:56 die i mensis xi annoque mcmlxxvii xii h xxxiv m lvi s 19 mcm 01 i  1 i Nov 305 2443449 11 xi 11 11/01/1977 die i mensis xi annoque mcmlxxvii 77 lxxvii 1977}
+test clock-2.1150 {conversion of 1977-11-30} {
+    clock format 249741296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/30/1977 12:34:56 die xxx mensis xi annoque mcmlxxvii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Nov 334 2443478 11 xi 11 11/30/1977 die xxx mensis xi annoque mcmlxxvii 77 lxxvii 1977}
+test clock-2.1151 {conversion of 1977-12-01} {
+    clock format 249827696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/01/1977 12:34:56 die i mensis xii annoque mcmlxxvii xii h xxxiv m lvi s 19 mcm 01 i  1 i Dec 335 2443479 12 xii 12 12/01/1977 die i mensis xii annoque mcmlxxvii 77 lxxvii 1977}
+test clock-2.1152 {conversion of 1977-12-31} {
+    clock format 252419696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/31/1977 12:34:56 die xxxi mensis xii annoque mcmlxxvii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Dec 365 2443509 12 xii 12 12/31/1977 die xxxi mensis xii annoque mcmlxxvii 77 lxxvii 1977}
+test clock-2.1153 {conversion of 1978-01-01} {
+    clock format 252506096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/01/1978 12:34:56 die i mensis i annoque mcmlxxviii xii h xxxiv m lvi s 19 mcm 01 i  1 i Jan 001 2443510 01 i  1 01/01/1978 die i mensis i annoque mcmlxxviii 78 lxxviii 1978}
+test clock-2.1154 {conversion of 1978-01-31} {
+    clock format 255098096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/31/1978 12:34:56 die xxxi mensis i annoque mcmlxxviii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jan 031 2443540 01 i  1 01/31/1978 die xxxi mensis i annoque mcmlxxviii 78 lxxviii 1978}
+test clock-2.1155 {conversion of 1978-02-01} {
+    clock format 255184496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/01/1978 12:34:56 die i mensis ii annoque mcmlxxviii xii h xxxiv m lvi s 19 mcm 01 i  1 i Feb 032 2443541 02 ii  2 02/01/1978 die i mensis ii annoque mcmlxxviii 78 lxxviii 1978}
+test clock-2.1156 {conversion of 1978-02-28} {
+    clock format 257517296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/28/1978 12:34:56 die xxviii mensis ii annoque mcmlxxviii xii h xxxiv m lvi s 19 mcm 28 xxviii 28 xxviii Feb 059 2443568 02 ii  2 02/28/1978 die xxviii mensis ii annoque mcmlxxviii 78 lxxviii 1978}
+test clock-2.1157 {conversion of 1978-03-01} {
+    clock format 257603696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/01/1978 12:34:56 die i mensis iii annoque mcmlxxviii xii h xxxiv m lvi s 19 mcm 01 i  1 i Mar 060 2443569 03 iii  3 03/01/1978 die i mensis iii annoque mcmlxxviii 78 lxxviii 1978}
+test clock-2.1158 {conversion of 1978-03-31} {
+    clock format 260195696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/31/1978 12:34:56 die xxxi mensis iii annoque mcmlxxviii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Mar 090 2443599 03 iii  3 03/31/1978 die xxxi mensis iii annoque mcmlxxviii 78 lxxviii 1978}
+test clock-2.1159 {conversion of 1978-04-01} {
+    clock format 260282096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/01/1978 12:34:56 die i mensis iv annoque mcmlxxviii xii h xxxiv m lvi s 19 mcm 01 i  1 i Apr 091 2443600 04 iv  4 04/01/1978 die i mensis iv annoque mcmlxxviii 78 lxxviii 1978}
+test clock-2.1160 {conversion of 1978-04-30} {
+    clock format 262787696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/30/1978 12:34:56 die xxx mensis iv annoque mcmlxxviii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Apr 120 2443629 04 iv  4 04/30/1978 die xxx mensis iv annoque mcmlxxviii 78 lxxviii 1978}
+test clock-2.1161 {conversion of 1978-05-01} {
+    clock format 262874096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/01/1978 12:34:56 die i mensis v annoque mcmlxxviii xii h xxxiv m lvi s 19 mcm 01 i  1 i May 121 2443630 05 v  5 05/01/1978 die i mensis v annoque mcmlxxviii 78 lxxviii 1978}
+test clock-2.1162 {conversion of 1978-05-31} {
+    clock format 265466096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/31/1978 12:34:56 die xxxi mensis v annoque mcmlxxviii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi May 151 2443660 05 v  5 05/31/1978 die xxxi mensis v annoque mcmlxxviii 78 lxxviii 1978}
+test clock-2.1163 {conversion of 1978-06-01} {
+    clock format 265552496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/01/1978 12:34:56 die i mensis vi annoque mcmlxxviii xii h xxxiv m lvi s 19 mcm 01 i  1 i Jun 152 2443661 06 vi  6 06/01/1978 die i mensis vi annoque mcmlxxviii 78 lxxviii 1978}
+test clock-2.1164 {conversion of 1978-06-30} {
+    clock format 268058096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/30/1978 12:34:56 die xxx mensis vi annoque mcmlxxviii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Jun 181 2443690 06 vi  6 06/30/1978 die xxx mensis vi annoque mcmlxxviii 78 lxxviii 1978}
+test clock-2.1165 {conversion of 1978-07-01} {
+    clock format 268144496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/01/1978 12:34:56 die i mensis vii annoque mcmlxxviii xii h xxxiv m lvi s 19 mcm 01 i  1 i Jul 182 2443691 07 vii  7 07/01/1978 die i mensis vii annoque mcmlxxviii 78 lxxviii 1978}
+test clock-2.1166 {conversion of 1978-07-31} {
+    clock format 270736496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/31/1978 12:34:56 die xxxi mensis vii annoque mcmlxxviii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jul 212 2443721 07 vii  7 07/31/1978 die xxxi mensis vii annoque mcmlxxviii 78 lxxviii 1978}
+test clock-2.1167 {conversion of 1978-08-01} {
+    clock format 270822896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/01/1978 12:34:56 die i mensis viii annoque mcmlxxviii xii h xxxiv m lvi s 19 mcm 01 i  1 i Aug 213 2443722 08 viii  8 08/01/1978 die i mensis viii annoque mcmlxxviii 78 lxxviii 1978}
+test clock-2.1168 {conversion of 1978-08-31} {
+    clock format 273414896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/31/1978 12:34:56 die xxxi mensis viii annoque mcmlxxviii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Aug 243 2443752 08 viii  8 08/31/1978 die xxxi mensis viii annoque mcmlxxviii 78 lxxviii 1978}
+test clock-2.1169 {conversion of 1978-09-01} {
+    clock format 273501296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/01/1978 12:34:56 die i mensis ix annoque mcmlxxviii xii h xxxiv m lvi s 19 mcm 01 i  1 i Sep 244 2443753 09 ix  9 09/01/1978 die i mensis ix annoque mcmlxxviii 78 lxxviii 1978}
+test clock-2.1170 {conversion of 1978-09-30} {
+    clock format 276006896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/30/1978 12:34:56 die xxx mensis ix annoque mcmlxxviii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Sep 273 2443782 09 ix  9 09/30/1978 die xxx mensis ix annoque mcmlxxviii 78 lxxviii 1978}
+test clock-2.1171 {conversion of 1978-10-01} {
+    clock format 276093296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/01/1978 12:34:56 die i mensis x annoque mcmlxxviii xii h xxxiv m lvi s 19 mcm 01 i  1 i Oct 274 2443783 10 x 10 10/01/1978 die i mensis x annoque mcmlxxviii 78 lxxviii 1978}
+test clock-2.1172 {conversion of 1978-10-31} {
+    clock format 278685296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/31/1978 12:34:56 die xxxi mensis x annoque mcmlxxviii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Oct 304 2443813 10 x 10 10/31/1978 die xxxi mensis x annoque mcmlxxviii 78 lxxviii 1978}
+test clock-2.1173 {conversion of 1978-11-01} {
+    clock format 278771696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/01/1978 12:34:56 die i mensis xi annoque mcmlxxviii xii h xxxiv m lvi s 19 mcm 01 i  1 i Nov 305 2443814 11 xi 11 11/01/1978 die i mensis xi annoque mcmlxxviii 78 lxxviii 1978}
+test clock-2.1174 {conversion of 1978-11-30} {
+    clock format 281277296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/30/1978 12:34:56 die xxx mensis xi annoque mcmlxxviii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Nov 334 2443843 11 xi 11 11/30/1978 die xxx mensis xi annoque mcmlxxviii 78 lxxviii 1978}
+test clock-2.1175 {conversion of 1978-12-01} {
+    clock format 281363696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/01/1978 12:34:56 die i mensis xii annoque mcmlxxviii xii h xxxiv m lvi s 19 mcm 01 i  1 i Dec 335 2443844 12 xii 12 12/01/1978 die i mensis xii annoque mcmlxxviii 78 lxxviii 1978}
+test clock-2.1176 {conversion of 1978-12-31} {
+    clock format 283955696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/31/1978 12:34:56 die xxxi mensis xii annoque mcmlxxviii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Dec 365 2443874 12 xii 12 12/31/1978 die xxxi mensis xii annoque mcmlxxviii 78 lxxviii 1978}
+test clock-2.1177 {conversion of 1979-01-01} {
+    clock format 284042096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/01/1979 12:34:56 die i mensis i annoque mcmlxxix xii h xxxiv m lvi s 19 mcm 01 i  1 i Jan 001 2443875 01 i  1 01/01/1979 die i mensis i annoque mcmlxxix 79 lxxix 1979}
+test clock-2.1178 {conversion of 1979-01-31} {
+    clock format 286634096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/31/1979 12:34:56 die xxxi mensis i annoque mcmlxxix xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jan 031 2443905 01 i  1 01/31/1979 die xxxi mensis i annoque mcmlxxix 79 lxxix 1979}
+test clock-2.1179 {conversion of 1979-02-01} {
+    clock format 286720496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/01/1979 12:34:56 die i mensis ii annoque mcmlxxix xii h xxxiv m lvi s 19 mcm 01 i  1 i Feb 032 2443906 02 ii  2 02/01/1979 die i mensis ii annoque mcmlxxix 79 lxxix 1979}
+test clock-2.1180 {conversion of 1979-02-28} {
+    clock format 289053296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/28/1979 12:34:56 die xxviii mensis ii annoque mcmlxxix xii h xxxiv m lvi s 19 mcm 28 xxviii 28 xxviii Feb 059 2443933 02 ii  2 02/28/1979 die xxviii mensis ii annoque mcmlxxix 79 lxxix 1979}
+test clock-2.1181 {conversion of 1979-03-01} {
+    clock format 289139696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/01/1979 12:34:56 die i mensis iii annoque mcmlxxix xii h xxxiv m lvi s 19 mcm 01 i  1 i Mar 060 2443934 03 iii  3 03/01/1979 die i mensis iii annoque mcmlxxix 79 lxxix 1979}
+test clock-2.1182 {conversion of 1979-03-31} {
+    clock format 291731696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/31/1979 12:34:56 die xxxi mensis iii annoque mcmlxxix xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Mar 090 2443964 03 iii  3 03/31/1979 die xxxi mensis iii annoque mcmlxxix 79 lxxix 1979}
+test clock-2.1183 {conversion of 1979-04-01} {
+    clock format 291818096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/01/1979 12:34:56 die i mensis iv annoque mcmlxxix xii h xxxiv m lvi s 19 mcm 01 i  1 i Apr 091 2443965 04 iv  4 04/01/1979 die i mensis iv annoque mcmlxxix 79 lxxix 1979}
+test clock-2.1184 {conversion of 1979-04-30} {
+    clock format 294323696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/30/1979 12:34:56 die xxx mensis iv annoque mcmlxxix xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Apr 120 2443994 04 iv  4 04/30/1979 die xxx mensis iv annoque mcmlxxix 79 lxxix 1979}
+test clock-2.1185 {conversion of 1979-05-01} {
+    clock format 294410096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/01/1979 12:34:56 die i mensis v annoque mcmlxxix xii h xxxiv m lvi s 19 mcm 01 i  1 i May 121 2443995 05 v  5 05/01/1979 die i mensis v annoque mcmlxxix 79 lxxix 1979}
+test clock-2.1186 {conversion of 1979-05-31} {
+    clock format 297002096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/31/1979 12:34:56 die xxxi mensis v annoque mcmlxxix xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi May 151 2444025 05 v  5 05/31/1979 die xxxi mensis v annoque mcmlxxix 79 lxxix 1979}
+test clock-2.1187 {conversion of 1979-06-01} {
+    clock format 297088496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/01/1979 12:34:56 die i mensis vi annoque mcmlxxix xii h xxxiv m lvi s 19 mcm 01 i  1 i Jun 152 2444026 06 vi  6 06/01/1979 die i mensis vi annoque mcmlxxix 79 lxxix 1979}
+test clock-2.1188 {conversion of 1979-06-30} {
+    clock format 299594096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/30/1979 12:34:56 die xxx mensis vi annoque mcmlxxix xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Jun 181 2444055 06 vi  6 06/30/1979 die xxx mensis vi annoque mcmlxxix 79 lxxix 1979}
+test clock-2.1189 {conversion of 1979-07-01} {
+    clock format 299680496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/01/1979 12:34:56 die i mensis vii annoque mcmlxxix xii h xxxiv m lvi s 19 mcm 01 i  1 i Jul 182 2444056 07 vii  7 07/01/1979 die i mensis vii annoque mcmlxxix 79 lxxix 1979}
+test clock-2.1190 {conversion of 1979-07-31} {
+    clock format 302272496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/31/1979 12:34:56 die xxxi mensis vii annoque mcmlxxix xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jul 212 2444086 07 vii  7 07/31/1979 die xxxi mensis vii annoque mcmlxxix 79 lxxix 1979}
+test clock-2.1191 {conversion of 1979-08-01} {
+    clock format 302358896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/01/1979 12:34:56 die i mensis viii annoque mcmlxxix xii h xxxiv m lvi s 19 mcm 01 i  1 i Aug 213 2444087 08 viii  8 08/01/1979 die i mensis viii annoque mcmlxxix 79 lxxix 1979}
+test clock-2.1192 {conversion of 1979-08-31} {
+    clock format 304950896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/31/1979 12:34:56 die xxxi mensis viii annoque mcmlxxix xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Aug 243 2444117 08 viii  8 08/31/1979 die xxxi mensis viii annoque mcmlxxix 79 lxxix 1979}
+test clock-2.1193 {conversion of 1979-09-01} {
+    clock format 305037296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/01/1979 12:34:56 die i mensis ix annoque mcmlxxix xii h xxxiv m lvi s 19 mcm 01 i  1 i Sep 244 2444118 09 ix  9 09/01/1979 die i mensis ix annoque mcmlxxix 79 lxxix 1979}
+test clock-2.1194 {conversion of 1979-09-30} {
+    clock format 307542896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/30/1979 12:34:56 die xxx mensis ix annoque mcmlxxix xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Sep 273 2444147 09 ix  9 09/30/1979 die xxx mensis ix annoque mcmlxxix 79 lxxix 1979}
+test clock-2.1195 {conversion of 1979-10-01} {
+    clock format 307629296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/01/1979 12:34:56 die i mensis x annoque mcmlxxix xii h xxxiv m lvi s 19 mcm 01 i  1 i Oct 274 2444148 10 x 10 10/01/1979 die i mensis x annoque mcmlxxix 79 lxxix 1979}
+test clock-2.1196 {conversion of 1979-10-31} {
+    clock format 310221296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/31/1979 12:34:56 die xxxi mensis x annoque mcmlxxix xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Oct 304 2444178 10 x 10 10/31/1979 die xxxi mensis x annoque mcmlxxix 79 lxxix 1979}
+test clock-2.1197 {conversion of 1979-11-01} {
+    clock format 310307696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/01/1979 12:34:56 die i mensis xi annoque mcmlxxix xii h xxxiv m lvi s 19 mcm 01 i  1 i Nov 305 2444179 11 xi 11 11/01/1979 die i mensis xi annoque mcmlxxix 79 lxxix 1979}
+test clock-2.1198 {conversion of 1979-11-30} {
+    clock format 312813296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/30/1979 12:34:56 die xxx mensis xi annoque mcmlxxix xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Nov 334 2444208 11 xi 11 11/30/1979 die xxx mensis xi annoque mcmlxxix 79 lxxix 1979}
+test clock-2.1199 {conversion of 1979-12-01} {
+    clock format 312899696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/01/1979 12:34:56 die i mensis xii annoque mcmlxxix xii h xxxiv m lvi s 19 mcm 01 i  1 i Dec 335 2444209 12 xii 12 12/01/1979 die i mensis xii annoque mcmlxxix 79 lxxix 1979}
+test clock-2.1200 {conversion of 1979-12-31} {
+    clock format 315491696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/31/1979 12:34:56 die xxxi mensis xii annoque mcmlxxix xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Dec 365 2444239 12 xii 12 12/31/1979 die xxxi mensis xii annoque mcmlxxix 79 lxxix 1979}
+test clock-2.1201 {conversion of 1980-01-01} {
+    clock format 315578096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/01/1980 12:34:56 die i mensis i annoque mcmlxxx xii h xxxiv m lvi s 19 mcm 01 i  1 i Jan 001 2444240 01 i  1 01/01/1980 die i mensis i annoque mcmlxxx 80 lxxx 1980}
+test clock-2.1202 {conversion of 1980-01-31} {
+    clock format 318170096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/31/1980 12:34:56 die xxxi mensis i annoque mcmlxxx xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jan 031 2444270 01 i  1 01/31/1980 die xxxi mensis i annoque mcmlxxx 80 lxxx 1980}
+test clock-2.1203 {conversion of 1980-02-01} {
+    clock format 318256496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/01/1980 12:34:56 die i mensis ii annoque mcmlxxx xii h xxxiv m lvi s 19 mcm 01 i  1 i Feb 032 2444271 02 ii  2 02/01/1980 die i mensis ii annoque mcmlxxx 80 lxxx 1980}
+test clock-2.1204 {conversion of 1980-02-29} {
+    clock format 320675696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/29/1980 12:34:56 die xxix mensis ii annoque mcmlxxx xii h xxxiv m lvi s 19 mcm 29 xxix 29 xxix Feb 060 2444299 02 ii  2 02/29/1980 die xxix mensis ii annoque mcmlxxx 80 lxxx 1980}
+test clock-2.1205 {conversion of 1980-03-01} {
+    clock format 320762096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/01/1980 12:34:56 die i mensis iii annoque mcmlxxx xii h xxxiv m lvi s 19 mcm 01 i  1 i Mar 061 2444300 03 iii  3 03/01/1980 die i mensis iii annoque mcmlxxx 80 lxxx 1980}
+test clock-2.1206 {conversion of 1980-03-31} {
+    clock format 323354096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/31/1980 12:34:56 die xxxi mensis iii annoque mcmlxxx xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Mar 091 2444330 03 iii  3 03/31/1980 die xxxi mensis iii annoque mcmlxxx 80 lxxx 1980}
+test clock-2.1207 {conversion of 1980-04-01} {
+    clock format 323440496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/01/1980 12:34:56 die i mensis iv annoque mcmlxxx xii h xxxiv m lvi s 19 mcm 01 i  1 i Apr 092 2444331 04 iv  4 04/01/1980 die i mensis iv annoque mcmlxxx 80 lxxx 1980}
+test clock-2.1208 {conversion of 1980-04-30} {
+    clock format 325946096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/30/1980 12:34:56 die xxx mensis iv annoque mcmlxxx xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Apr 121 2444360 04 iv  4 04/30/1980 die xxx mensis iv annoque mcmlxxx 80 lxxx 1980}
+test clock-2.1209 {conversion of 1980-05-01} {
+    clock format 326032496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/01/1980 12:34:56 die i mensis v annoque mcmlxxx xii h xxxiv m lvi s 19 mcm 01 i  1 i May 122 2444361 05 v  5 05/01/1980 die i mensis v annoque mcmlxxx 80 lxxx 1980}
+test clock-2.1210 {conversion of 1980-05-31} {
+    clock format 328624496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/31/1980 12:34:56 die xxxi mensis v annoque mcmlxxx xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi May 152 2444391 05 v  5 05/31/1980 die xxxi mensis v annoque mcmlxxx 80 lxxx 1980}
+test clock-2.1211 {conversion of 1980-06-01} {
+    clock format 328710896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/01/1980 12:34:56 die i mensis vi annoque mcmlxxx xii h xxxiv m lvi s 19 mcm 01 i  1 i Jun 153 2444392 06 vi  6 06/01/1980 die i mensis vi annoque mcmlxxx 80 lxxx 1980}
+test clock-2.1212 {conversion of 1980-06-30} {
+    clock format 331216496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/30/1980 12:34:56 die xxx mensis vi annoque mcmlxxx xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Jun 182 2444421 06 vi  6 06/30/1980 die xxx mensis vi annoque mcmlxxx 80 lxxx 1980}
+test clock-2.1213 {conversion of 1980-07-01} {
+    clock format 331302896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/01/1980 12:34:56 die i mensis vii annoque mcmlxxx xii h xxxiv m lvi s 19 mcm 01 i  1 i Jul 183 2444422 07 vii  7 07/01/1980 die i mensis vii annoque mcmlxxx 80 lxxx 1980}
+test clock-2.1214 {conversion of 1980-07-31} {
+    clock format 333894896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/31/1980 12:34:56 die xxxi mensis vii annoque mcmlxxx xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jul 213 2444452 07 vii  7 07/31/1980 die xxxi mensis vii annoque mcmlxxx 80 lxxx 1980}
+test clock-2.1215 {conversion of 1980-08-01} {
+    clock format 333981296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/01/1980 12:34:56 die i mensis viii annoque mcmlxxx xii h xxxiv m lvi s 19 mcm 01 i  1 i Aug 214 2444453 08 viii  8 08/01/1980 die i mensis viii annoque mcmlxxx 80 lxxx 1980}
+test clock-2.1216 {conversion of 1980-08-31} {
+    clock format 336573296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/31/1980 12:34:56 die xxxi mensis viii annoque mcmlxxx xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Aug 244 2444483 08 viii  8 08/31/1980 die xxxi mensis viii annoque mcmlxxx 80 lxxx 1980}
+test clock-2.1217 {conversion of 1980-09-01} {
+    clock format 336659696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/01/1980 12:34:56 die i mensis ix annoque mcmlxxx xii h xxxiv m lvi s 19 mcm 01 i  1 i Sep 245 2444484 09 ix  9 09/01/1980 die i mensis ix annoque mcmlxxx 80 lxxx 1980}
+test clock-2.1218 {conversion of 1980-09-30} {
+    clock format 339165296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/30/1980 12:34:56 die xxx mensis ix annoque mcmlxxx xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Sep 274 2444513 09 ix  9 09/30/1980 die xxx mensis ix annoque mcmlxxx 80 lxxx 1980}
+test clock-2.1219 {conversion of 1980-10-01} {
+    clock format 339251696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/01/1980 12:34:56 die i mensis x annoque mcmlxxx xii h xxxiv m lvi s 19 mcm 01 i  1 i Oct 275 2444514 10 x 10 10/01/1980 die i mensis x annoque mcmlxxx 80 lxxx 1980}
+test clock-2.1220 {conversion of 1980-10-31} {
+    clock format 341843696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/31/1980 12:34:56 die xxxi mensis x annoque mcmlxxx xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Oct 305 2444544 10 x 10 10/31/1980 die xxxi mensis x annoque mcmlxxx 80 lxxx 1980}
+test clock-2.1221 {conversion of 1980-11-01} {
+    clock format 341930096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/01/1980 12:34:56 die i mensis xi annoque mcmlxxx xii h xxxiv m lvi s 19 mcm 01 i  1 i Nov 306 2444545 11 xi 11 11/01/1980 die i mensis xi annoque mcmlxxx 80 lxxx 1980}
+test clock-2.1222 {conversion of 1980-11-30} {
+    clock format 344435696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/30/1980 12:34:56 die xxx mensis xi annoque mcmlxxx xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Nov 335 2444574 11 xi 11 11/30/1980 die xxx mensis xi annoque mcmlxxx 80 lxxx 1980}
+test clock-2.1223 {conversion of 1980-12-01} {
+    clock format 344522096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/01/1980 12:34:56 die i mensis xii annoque mcmlxxx xii h xxxiv m lvi s 19 mcm 01 i  1 i Dec 336 2444575 12 xii 12 12/01/1980 die i mensis xii annoque mcmlxxx 80 lxxx 1980}
+test clock-2.1224 {conversion of 1980-12-31} {
+    clock format 347114096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/31/1980 12:34:56 die xxxi mensis xii annoque mcmlxxx xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Dec 366 2444605 12 xii 12 12/31/1980 die xxxi mensis xii annoque mcmlxxx 80 lxxx 1980}
+test clock-2.1225 {conversion of 1981-01-01} {
+    clock format 347200496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/01/1981 12:34:56 die i mensis i annoque mcmlxxxi xii h xxxiv m lvi s 19 mcm 01 i  1 i Jan 001 2444606 01 i  1 01/01/1981 die i mensis i annoque mcmlxxxi 81 lxxxi 1981}
+test clock-2.1226 {conversion of 1981-01-31} {
+    clock format 349792496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/31/1981 12:34:56 die xxxi mensis i annoque mcmlxxxi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jan 031 2444636 01 i  1 01/31/1981 die xxxi mensis i annoque mcmlxxxi 81 lxxxi 1981}
+test clock-2.1227 {conversion of 1981-02-01} {
+    clock format 349878896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/01/1981 12:34:56 die i mensis ii annoque mcmlxxxi xii h xxxiv m lvi s 19 mcm 01 i  1 i Feb 032 2444637 02 ii  2 02/01/1981 die i mensis ii annoque mcmlxxxi 81 lxxxi 1981}
+test clock-2.1228 {conversion of 1981-02-28} {
+    clock format 352211696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/28/1981 12:34:56 die xxviii mensis ii annoque mcmlxxxi xii h xxxiv m lvi s 19 mcm 28 xxviii 28 xxviii Feb 059 2444664 02 ii  2 02/28/1981 die xxviii mensis ii annoque mcmlxxxi 81 lxxxi 1981}
+test clock-2.1229 {conversion of 1981-03-01} {
+    clock format 352298096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/01/1981 12:34:56 die i mensis iii annoque mcmlxxxi xii h xxxiv m lvi s 19 mcm 01 i  1 i Mar 060 2444665 03 iii  3 03/01/1981 die i mensis iii annoque mcmlxxxi 81 lxxxi 1981}
+test clock-2.1230 {conversion of 1981-03-31} {
+    clock format 354890096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/31/1981 12:34:56 die xxxi mensis iii annoque mcmlxxxi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Mar 090 2444695 03 iii  3 03/31/1981 die xxxi mensis iii annoque mcmlxxxi 81 lxxxi 1981}
+test clock-2.1231 {conversion of 1981-04-01} {
+    clock format 354976496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/01/1981 12:34:56 die i mensis iv annoque mcmlxxxi xii h xxxiv m lvi s 19 mcm 01 i  1 i Apr 091 2444696 04 iv  4 04/01/1981 die i mensis iv annoque mcmlxxxi 81 lxxxi 1981}
+test clock-2.1232 {conversion of 1981-04-30} {
+    clock format 357482096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/30/1981 12:34:56 die xxx mensis iv annoque mcmlxxxi xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Apr 120 2444725 04 iv  4 04/30/1981 die xxx mensis iv annoque mcmlxxxi 81 lxxxi 1981}
+test clock-2.1233 {conversion of 1981-05-01} {
+    clock format 357568496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/01/1981 12:34:56 die i mensis v annoque mcmlxxxi xii h xxxiv m lvi s 19 mcm 01 i  1 i May 121 2444726 05 v  5 05/01/1981 die i mensis v annoque mcmlxxxi 81 lxxxi 1981}
+test clock-2.1234 {conversion of 1981-05-31} {
+    clock format 360160496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/31/1981 12:34:56 die xxxi mensis v annoque mcmlxxxi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi May 151 2444756 05 v  5 05/31/1981 die xxxi mensis v annoque mcmlxxxi 81 lxxxi 1981}
+test clock-2.1235 {conversion of 1981-06-01} {
+    clock format 360246896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/01/1981 12:34:56 die i mensis vi annoque mcmlxxxi xii h xxxiv m lvi s 19 mcm 01 i  1 i Jun 152 2444757 06 vi  6 06/01/1981 die i mensis vi annoque mcmlxxxi 81 lxxxi 1981}
+test clock-2.1236 {conversion of 1981-06-30} {
+    clock format 362752496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/30/1981 12:34:56 die xxx mensis vi annoque mcmlxxxi xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Jun 181 2444786 06 vi  6 06/30/1981 die xxx mensis vi annoque mcmlxxxi 81 lxxxi 1981}
+test clock-2.1237 {conversion of 1981-07-01} {
+    clock format 362838896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/01/1981 12:34:56 die i mensis vii annoque mcmlxxxi xii h xxxiv m lvi s 19 mcm 01 i  1 i Jul 182 2444787 07 vii  7 07/01/1981 die i mensis vii annoque mcmlxxxi 81 lxxxi 1981}
+test clock-2.1238 {conversion of 1981-07-31} {
+    clock format 365430896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/31/1981 12:34:56 die xxxi mensis vii annoque mcmlxxxi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jul 212 2444817 07 vii  7 07/31/1981 die xxxi mensis vii annoque mcmlxxxi 81 lxxxi 1981}
+test clock-2.1239 {conversion of 1981-08-01} {
+    clock format 365517296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/01/1981 12:34:56 die i mensis viii annoque mcmlxxxi xii h xxxiv m lvi s 19 mcm 01 i  1 i Aug 213 2444818 08 viii  8 08/01/1981 die i mensis viii annoque mcmlxxxi 81 lxxxi 1981}
+test clock-2.1240 {conversion of 1981-08-31} {
+    clock format 368109296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/31/1981 12:34:56 die xxxi mensis viii annoque mcmlxxxi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Aug 243 2444848 08 viii  8 08/31/1981 die xxxi mensis viii annoque mcmlxxxi 81 lxxxi 1981}
+test clock-2.1241 {conversion of 1981-09-01} {
+    clock format 368195696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/01/1981 12:34:56 die i mensis ix annoque mcmlxxxi xii h xxxiv m lvi s 19 mcm 01 i  1 i Sep 244 2444849 09 ix  9 09/01/1981 die i mensis ix annoque mcmlxxxi 81 lxxxi 1981}
+test clock-2.1242 {conversion of 1981-09-30} {
+    clock format 370701296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/30/1981 12:34:56 die xxx mensis ix annoque mcmlxxxi xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Sep 273 2444878 09 ix  9 09/30/1981 die xxx mensis ix annoque mcmlxxxi 81 lxxxi 1981}
+test clock-2.1243 {conversion of 1981-10-01} {
+    clock format 370787696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/01/1981 12:34:56 die i mensis x annoque mcmlxxxi xii h xxxiv m lvi s 19 mcm 01 i  1 i Oct 274 2444879 10 x 10 10/01/1981 die i mensis x annoque mcmlxxxi 81 lxxxi 1981}
+test clock-2.1244 {conversion of 1981-10-31} {
+    clock format 373379696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/31/1981 12:34:56 die xxxi mensis x annoque mcmlxxxi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Oct 304 2444909 10 x 10 10/31/1981 die xxxi mensis x annoque mcmlxxxi 81 lxxxi 1981}
+test clock-2.1245 {conversion of 1981-11-01} {
+    clock format 373466096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/01/1981 12:34:56 die i mensis xi annoque mcmlxxxi xii h xxxiv m lvi s 19 mcm 01 i  1 i Nov 305 2444910 11 xi 11 11/01/1981 die i mensis xi annoque mcmlxxxi 81 lxxxi 1981}
+test clock-2.1246 {conversion of 1981-11-30} {
+    clock format 375971696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/30/1981 12:34:56 die xxx mensis xi annoque mcmlxxxi xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Nov 334 2444939 11 xi 11 11/30/1981 die xxx mensis xi annoque mcmlxxxi 81 lxxxi 1981}
+test clock-2.1247 {conversion of 1981-12-01} {
+    clock format 376058096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/01/1981 12:34:56 die i mensis xii annoque mcmlxxxi xii h xxxiv m lvi s 19 mcm 01 i  1 i Dec 335 2444940 12 xii 12 12/01/1981 die i mensis xii annoque mcmlxxxi 81 lxxxi 1981}
+test clock-2.1248 {conversion of 1981-12-31} {
+    clock format 378650096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/31/1981 12:34:56 die xxxi mensis xii annoque mcmlxxxi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Dec 365 2444970 12 xii 12 12/31/1981 die xxxi mensis xii annoque mcmlxxxi 81 lxxxi 1981}
+test clock-2.1249 {conversion of 1984-01-01} {
+    clock format 441808496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/01/1984 12:34:56 die i mensis i annoque mcmlxxxiv xii h xxxiv m lvi s 19 mcm 01 i  1 i Jan 001 2445701 01 i  1 01/01/1984 die i mensis i annoque mcmlxxxiv 84 lxxxiv 1984}
+test clock-2.1250 {conversion of 1984-01-31} {
+    clock format 444400496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/31/1984 12:34:56 die xxxi mensis i annoque mcmlxxxiv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jan 031 2445731 01 i  1 01/31/1984 die xxxi mensis i annoque mcmlxxxiv 84 lxxxiv 1984}
+test clock-2.1251 {conversion of 1984-02-01} {
+    clock format 444486896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/01/1984 12:34:56 die i mensis ii annoque mcmlxxxiv xii h xxxiv m lvi s 19 mcm 01 i  1 i Feb 032 2445732 02 ii  2 02/01/1984 die i mensis ii annoque mcmlxxxiv 84 lxxxiv 1984}
+test clock-2.1252 {conversion of 1984-02-29} {
+    clock format 446906096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/29/1984 12:34:56 die xxix mensis ii annoque mcmlxxxiv xii h xxxiv m lvi s 19 mcm 29 xxix 29 xxix Feb 060 2445760 02 ii  2 02/29/1984 die xxix mensis ii annoque mcmlxxxiv 84 lxxxiv 1984}
+test clock-2.1253 {conversion of 1984-03-01} {
+    clock format 446992496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/01/1984 12:34:56 die i mensis iii annoque mcmlxxxiv xii h xxxiv m lvi s 19 mcm 01 i  1 i Mar 061 2445761 03 iii  3 03/01/1984 die i mensis iii annoque mcmlxxxiv 84 lxxxiv 1984}
+test clock-2.1254 {conversion of 1984-03-31} {
+    clock format 449584496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/31/1984 12:34:56 die xxxi mensis iii annoque mcmlxxxiv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Mar 091 2445791 03 iii  3 03/31/1984 die xxxi mensis iii annoque mcmlxxxiv 84 lxxxiv 1984}
+test clock-2.1255 {conversion of 1984-04-01} {
+    clock format 449670896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/01/1984 12:34:56 die i mensis iv annoque mcmlxxxiv xii h xxxiv m lvi s 19 mcm 01 i  1 i Apr 092 2445792 04 iv  4 04/01/1984 die i mensis iv annoque mcmlxxxiv 84 lxxxiv 1984}
+test clock-2.1256 {conversion of 1984-04-30} {
+    clock format 452176496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/30/1984 12:34:56 die xxx mensis iv annoque mcmlxxxiv xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Apr 121 2445821 04 iv  4 04/30/1984 die xxx mensis iv annoque mcmlxxxiv 84 lxxxiv 1984}
+test clock-2.1257 {conversion of 1984-05-01} {
+    clock format 452262896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/01/1984 12:34:56 die i mensis v annoque mcmlxxxiv xii h xxxiv m lvi s 19 mcm 01 i  1 i May 122 2445822 05 v  5 05/01/1984 die i mensis v annoque mcmlxxxiv 84 lxxxiv 1984}
+test clock-2.1258 {conversion of 1984-05-31} {
+    clock format 454854896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/31/1984 12:34:56 die xxxi mensis v annoque mcmlxxxiv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi May 152 2445852 05 v  5 05/31/1984 die xxxi mensis v annoque mcmlxxxiv 84 lxxxiv 1984}
+test clock-2.1259 {conversion of 1984-06-01} {
+    clock format 454941296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/01/1984 12:34:56 die i mensis vi annoque mcmlxxxiv xii h xxxiv m lvi s 19 mcm 01 i  1 i Jun 153 2445853 06 vi  6 06/01/1984 die i mensis vi annoque mcmlxxxiv 84 lxxxiv 1984}
+test clock-2.1260 {conversion of 1984-06-30} {
+    clock format 457446896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/30/1984 12:34:56 die xxx mensis vi annoque mcmlxxxiv xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Jun 182 2445882 06 vi  6 06/30/1984 die xxx mensis vi annoque mcmlxxxiv 84 lxxxiv 1984}
+test clock-2.1261 {conversion of 1984-07-01} {
+    clock format 457533296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/01/1984 12:34:56 die i mensis vii annoque mcmlxxxiv xii h xxxiv m lvi s 19 mcm 01 i  1 i Jul 183 2445883 07 vii  7 07/01/1984 die i mensis vii annoque mcmlxxxiv 84 lxxxiv 1984}
+test clock-2.1262 {conversion of 1984-07-31} {
+    clock format 460125296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/31/1984 12:34:56 die xxxi mensis vii annoque mcmlxxxiv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jul 213 2445913 07 vii  7 07/31/1984 die xxxi mensis vii annoque mcmlxxxiv 84 lxxxiv 1984}
+test clock-2.1263 {conversion of 1984-08-01} {
+    clock format 460211696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/01/1984 12:34:56 die i mensis viii annoque mcmlxxxiv xii h xxxiv m lvi s 19 mcm 01 i  1 i Aug 214 2445914 08 viii  8 08/01/1984 die i mensis viii annoque mcmlxxxiv 84 lxxxiv 1984}
+test clock-2.1264 {conversion of 1984-08-31} {
+    clock format 462803696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/31/1984 12:34:56 die xxxi mensis viii annoque mcmlxxxiv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Aug 244 2445944 08 viii  8 08/31/1984 die xxxi mensis viii annoque mcmlxxxiv 84 lxxxiv 1984}
+test clock-2.1265 {conversion of 1984-09-01} {
+    clock format 462890096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/01/1984 12:34:56 die i mensis ix annoque mcmlxxxiv xii h xxxiv m lvi s 19 mcm 01 i  1 i Sep 245 2445945 09 ix  9 09/01/1984 die i mensis ix annoque mcmlxxxiv 84 lxxxiv 1984}
+test clock-2.1266 {conversion of 1984-09-30} {
+    clock format 465395696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/30/1984 12:34:56 die xxx mensis ix annoque mcmlxxxiv xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Sep 274 2445974 09 ix  9 09/30/1984 die xxx mensis ix annoque mcmlxxxiv 84 lxxxiv 1984}
+test clock-2.1267 {conversion of 1984-10-01} {
+    clock format 465482096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/01/1984 12:34:56 die i mensis x annoque mcmlxxxiv xii h xxxiv m lvi s 19 mcm 01 i  1 i Oct 275 2445975 10 x 10 10/01/1984 die i mensis x annoque mcmlxxxiv 84 lxxxiv 1984}
+test clock-2.1268 {conversion of 1984-10-31} {
+    clock format 468074096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/31/1984 12:34:56 die xxxi mensis x annoque mcmlxxxiv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Oct 305 2446005 10 x 10 10/31/1984 die xxxi mensis x annoque mcmlxxxiv 84 lxxxiv 1984}
+test clock-2.1269 {conversion of 1984-11-01} {
+    clock format 468160496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/01/1984 12:34:56 die i mensis xi annoque mcmlxxxiv xii h xxxiv m lvi s 19 mcm 01 i  1 i Nov 306 2446006 11 xi 11 11/01/1984 die i mensis xi annoque mcmlxxxiv 84 lxxxiv 1984}
+test clock-2.1270 {conversion of 1984-11-30} {
+    clock format 470666096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/30/1984 12:34:56 die xxx mensis xi annoque mcmlxxxiv xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Nov 335 2446035 11 xi 11 11/30/1984 die xxx mensis xi annoque mcmlxxxiv 84 lxxxiv 1984}
+test clock-2.1271 {conversion of 1984-12-01} {
+    clock format 470752496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/01/1984 12:34:56 die i mensis xii annoque mcmlxxxiv xii h xxxiv m lvi s 19 mcm 01 i  1 i Dec 336 2446036 12 xii 12 12/01/1984 die i mensis xii annoque mcmlxxxiv 84 lxxxiv 1984}
+test clock-2.1272 {conversion of 1984-12-31} {
+    clock format 473344496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/31/1984 12:34:56 die xxxi mensis xii annoque mcmlxxxiv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Dec 366 2446066 12 xii 12 12/31/1984 die xxxi mensis xii annoque mcmlxxxiv 84 lxxxiv 1984}
+test clock-2.1273 {conversion of 1985-01-01} {
+    clock format 473430896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/01/1985 12:34:56 die i mensis i annoque mcmlxxxv xii h xxxiv m lvi s 19 mcm 01 i  1 i Jan 001 2446067 01 i  1 01/01/1985 die i mensis i annoque mcmlxxxv 85 lxxxv 1985}
+test clock-2.1274 {conversion of 1985-01-31} {
+    clock format 476022896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/31/1985 12:34:56 die xxxi mensis i annoque mcmlxxxv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jan 031 2446097 01 i  1 01/31/1985 die xxxi mensis i annoque mcmlxxxv 85 lxxxv 1985}
+test clock-2.1275 {conversion of 1985-02-01} {
+    clock format 476109296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/01/1985 12:34:56 die i mensis ii annoque mcmlxxxv xii h xxxiv m lvi s 19 mcm 01 i  1 i Feb 032 2446098 02 ii  2 02/01/1985 die i mensis ii annoque mcmlxxxv 85 lxxxv 1985}
+test clock-2.1276 {conversion of 1985-02-28} {
+    clock format 478442096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/28/1985 12:34:56 die xxviii mensis ii annoque mcmlxxxv xii h xxxiv m lvi s 19 mcm 28 xxviii 28 xxviii Feb 059 2446125 02 ii  2 02/28/1985 die xxviii mensis ii annoque mcmlxxxv 85 lxxxv 1985}
+test clock-2.1277 {conversion of 1985-03-01} {
+    clock format 478528496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/01/1985 12:34:56 die i mensis iii annoque mcmlxxxv xii h xxxiv m lvi s 19 mcm 01 i  1 i Mar 060 2446126 03 iii  3 03/01/1985 die i mensis iii annoque mcmlxxxv 85 lxxxv 1985}
+test clock-2.1278 {conversion of 1985-03-31} {
+    clock format 481120496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/31/1985 12:34:56 die xxxi mensis iii annoque mcmlxxxv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Mar 090 2446156 03 iii  3 03/31/1985 die xxxi mensis iii annoque mcmlxxxv 85 lxxxv 1985}
+test clock-2.1279 {conversion of 1985-04-01} {
+    clock format 481206896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/01/1985 12:34:56 die i mensis iv annoque mcmlxxxv xii h xxxiv m lvi s 19 mcm 01 i  1 i Apr 091 2446157 04 iv  4 04/01/1985 die i mensis iv annoque mcmlxxxv 85 lxxxv 1985}
+test clock-2.1280 {conversion of 1985-04-30} {
+    clock format 483712496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/30/1985 12:34:56 die xxx mensis iv annoque mcmlxxxv xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Apr 120 2446186 04 iv  4 04/30/1985 die xxx mensis iv annoque mcmlxxxv 85 lxxxv 1985}
+test clock-2.1281 {conversion of 1985-05-01} {
+    clock format 483798896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/01/1985 12:34:56 die i mensis v annoque mcmlxxxv xii h xxxiv m lvi s 19 mcm 01 i  1 i May 121 2446187 05 v  5 05/01/1985 die i mensis v annoque mcmlxxxv 85 lxxxv 1985}
+test clock-2.1282 {conversion of 1985-05-31} {
+    clock format 486390896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/31/1985 12:34:56 die xxxi mensis v annoque mcmlxxxv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi May 151 2446217 05 v  5 05/31/1985 die xxxi mensis v annoque mcmlxxxv 85 lxxxv 1985}
+test clock-2.1283 {conversion of 1985-06-01} {
+    clock format 486477296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/01/1985 12:34:56 die i mensis vi annoque mcmlxxxv xii h xxxiv m lvi s 19 mcm 01 i  1 i Jun 152 2446218 06 vi  6 06/01/1985 die i mensis vi annoque mcmlxxxv 85 lxxxv 1985}
+test clock-2.1284 {conversion of 1985-06-30} {
+    clock format 488982896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/30/1985 12:34:56 die xxx mensis vi annoque mcmlxxxv xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Jun 181 2446247 06 vi  6 06/30/1985 die xxx mensis vi annoque mcmlxxxv 85 lxxxv 1985}
+test clock-2.1285 {conversion of 1985-07-01} {
+    clock format 489069296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/01/1985 12:34:56 die i mensis vii annoque mcmlxxxv xii h xxxiv m lvi s 19 mcm 01 i  1 i Jul 182 2446248 07 vii  7 07/01/1985 die i mensis vii annoque mcmlxxxv 85 lxxxv 1985}
+test clock-2.1286 {conversion of 1985-07-31} {
+    clock format 491661296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/31/1985 12:34:56 die xxxi mensis vii annoque mcmlxxxv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jul 212 2446278 07 vii  7 07/31/1985 die xxxi mensis vii annoque mcmlxxxv 85 lxxxv 1985}
+test clock-2.1287 {conversion of 1985-08-01} {
+    clock format 491747696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/01/1985 12:34:56 die i mensis viii annoque mcmlxxxv xii h xxxiv m lvi s 19 mcm 01 i  1 i Aug 213 2446279 08 viii  8 08/01/1985 die i mensis viii annoque mcmlxxxv 85 lxxxv 1985}
+test clock-2.1288 {conversion of 1985-08-31} {
+    clock format 494339696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/31/1985 12:34:56 die xxxi mensis viii annoque mcmlxxxv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Aug 243 2446309 08 viii  8 08/31/1985 die xxxi mensis viii annoque mcmlxxxv 85 lxxxv 1985}
+test clock-2.1289 {conversion of 1985-09-01} {
+    clock format 494426096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/01/1985 12:34:56 die i mensis ix annoque mcmlxxxv xii h xxxiv m lvi s 19 mcm 01 i  1 i Sep 244 2446310 09 ix  9 09/01/1985 die i mensis ix annoque mcmlxxxv 85 lxxxv 1985}
+test clock-2.1290 {conversion of 1985-09-30} {
+    clock format 496931696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/30/1985 12:34:56 die xxx mensis ix annoque mcmlxxxv xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Sep 273 2446339 09 ix  9 09/30/1985 die xxx mensis ix annoque mcmlxxxv 85 lxxxv 1985}
+test clock-2.1291 {conversion of 1985-10-01} {
+    clock format 497018096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/01/1985 12:34:56 die i mensis x annoque mcmlxxxv xii h xxxiv m lvi s 19 mcm 01 i  1 i Oct 274 2446340 10 x 10 10/01/1985 die i mensis x annoque mcmlxxxv 85 lxxxv 1985}
+test clock-2.1292 {conversion of 1985-10-31} {
+    clock format 499610096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/31/1985 12:34:56 die xxxi mensis x annoque mcmlxxxv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Oct 304 2446370 10 x 10 10/31/1985 die xxxi mensis x annoque mcmlxxxv 85 lxxxv 1985}
+test clock-2.1293 {conversion of 1985-11-01} {
+    clock format 499696496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/01/1985 12:34:56 die i mensis xi annoque mcmlxxxv xii h xxxiv m lvi s 19 mcm 01 i  1 i Nov 305 2446371 11 xi 11 11/01/1985 die i mensis xi annoque mcmlxxxv 85 lxxxv 1985}
+test clock-2.1294 {conversion of 1985-11-30} {
+    clock format 502202096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/30/1985 12:34:56 die xxx mensis xi annoque mcmlxxxv xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Nov 334 2446400 11 xi 11 11/30/1985 die xxx mensis xi annoque mcmlxxxv 85 lxxxv 1985}
+test clock-2.1295 {conversion of 1985-12-01} {
+    clock format 502288496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/01/1985 12:34:56 die i mensis xii annoque mcmlxxxv xii h xxxiv m lvi s 19 mcm 01 i  1 i Dec 335 2446401 12 xii 12 12/01/1985 die i mensis xii annoque mcmlxxxv 85 lxxxv 1985}
+test clock-2.1296 {conversion of 1985-12-31} {
+    clock format 504880496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/31/1985 12:34:56 die xxxi mensis xii annoque mcmlxxxv xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Dec 365 2446431 12 xii 12 12/31/1985 die xxxi mensis xii annoque mcmlxxxv 85 lxxxv 1985}
+test clock-2.1297 {conversion of 1988-01-01} {
+    clock format 568038896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/01/1988 12:34:56 die i mensis i annoque mcmlxxxviii xii h xxxiv m lvi s 19 mcm 01 i  1 i Jan 001 2447162 01 i  1 01/01/1988 die i mensis i annoque mcmlxxxviii 88 lxxxviii 1988}
+test clock-2.1298 {conversion of 1988-01-31} {
+    clock format 570630896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/31/1988 12:34:56 die xxxi mensis i annoque mcmlxxxviii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jan 031 2447192 01 i  1 01/31/1988 die xxxi mensis i annoque mcmlxxxviii 88 lxxxviii 1988}
+test clock-2.1299 {conversion of 1988-02-01} {
+    clock format 570717296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/01/1988 12:34:56 die i mensis ii annoque mcmlxxxviii xii h xxxiv m lvi s 19 mcm 01 i  1 i Feb 032 2447193 02 ii  2 02/01/1988 die i mensis ii annoque mcmlxxxviii 88 lxxxviii 1988}
+test clock-2.1300 {conversion of 1988-02-29} {
+    clock format 573136496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/29/1988 12:34:56 die xxix mensis ii annoque mcmlxxxviii xii h xxxiv m lvi s 19 mcm 29 xxix 29 xxix Feb 060 2447221 02 ii  2 02/29/1988 die xxix mensis ii annoque mcmlxxxviii 88 lxxxviii 1988}
+test clock-2.1301 {conversion of 1988-03-01} {
+    clock format 573222896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/01/1988 12:34:56 die i mensis iii annoque mcmlxxxviii xii h xxxiv m lvi s 19 mcm 01 i  1 i Mar 061 2447222 03 iii  3 03/01/1988 die i mensis iii annoque mcmlxxxviii 88 lxxxviii 1988}
+test clock-2.1302 {conversion of 1988-03-31} {
+    clock format 575814896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/31/1988 12:34:56 die xxxi mensis iii annoque mcmlxxxviii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Mar 091 2447252 03 iii  3 03/31/1988 die xxxi mensis iii annoque mcmlxxxviii 88 lxxxviii 1988}
+test clock-2.1303 {conversion of 1988-04-01} {
+    clock format 575901296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/01/1988 12:34:56 die i mensis iv annoque mcmlxxxviii xii h xxxiv m lvi s 19 mcm 01 i  1 i Apr 092 2447253 04 iv  4 04/01/1988 die i mensis iv annoque mcmlxxxviii 88 lxxxviii 1988}
+test clock-2.1304 {conversion of 1988-04-30} {
+    clock format 578406896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/30/1988 12:34:56 die xxx mensis iv annoque mcmlxxxviii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Apr 121 2447282 04 iv  4 04/30/1988 die xxx mensis iv annoque mcmlxxxviii 88 lxxxviii 1988}
+test clock-2.1305 {conversion of 1988-05-01} {
+    clock format 578493296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/01/1988 12:34:56 die i mensis v annoque mcmlxxxviii xii h xxxiv m lvi s 19 mcm 01 i  1 i May 122 2447283 05 v  5 05/01/1988 die i mensis v annoque mcmlxxxviii 88 lxxxviii 1988}
+test clock-2.1306 {conversion of 1988-05-31} {
+    clock format 581085296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/31/1988 12:34:56 die xxxi mensis v annoque mcmlxxxviii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi May 152 2447313 05 v  5 05/31/1988 die xxxi mensis v annoque mcmlxxxviii 88 lxxxviii 1988}
+test clock-2.1307 {conversion of 1988-06-01} {
+    clock format 581171696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/01/1988 12:34:56 die i mensis vi annoque mcmlxxxviii xii h xxxiv m lvi s 19 mcm 01 i  1 i Jun 153 2447314 06 vi  6 06/01/1988 die i mensis vi annoque mcmlxxxviii 88 lxxxviii 1988}
+test clock-2.1308 {conversion of 1988-06-30} {
+    clock format 583677296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/30/1988 12:34:56 die xxx mensis vi annoque mcmlxxxviii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Jun 182 2447343 06 vi  6 06/30/1988 die xxx mensis vi annoque mcmlxxxviii 88 lxxxviii 1988}
+test clock-2.1309 {conversion of 1988-07-01} {
+    clock format 583763696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/01/1988 12:34:56 die i mensis vii annoque mcmlxxxviii xii h xxxiv m lvi s 19 mcm 01 i  1 i Jul 183 2447344 07 vii  7 07/01/1988 die i mensis vii annoque mcmlxxxviii 88 lxxxviii 1988}
+test clock-2.1310 {conversion of 1988-07-31} {
+    clock format 586355696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/31/1988 12:34:56 die xxxi mensis vii annoque mcmlxxxviii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jul 213 2447374 07 vii  7 07/31/1988 die xxxi mensis vii annoque mcmlxxxviii 88 lxxxviii 1988}
+test clock-2.1311 {conversion of 1988-08-01} {
+    clock format 586442096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/01/1988 12:34:56 die i mensis viii annoque mcmlxxxviii xii h xxxiv m lvi s 19 mcm 01 i  1 i Aug 214 2447375 08 viii  8 08/01/1988 die i mensis viii annoque mcmlxxxviii 88 lxxxviii 1988}
+test clock-2.1312 {conversion of 1988-08-31} {
+    clock format 589034096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/31/1988 12:34:56 die xxxi mensis viii annoque mcmlxxxviii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Aug 244 2447405 08 viii  8 08/31/1988 die xxxi mensis viii annoque mcmlxxxviii 88 lxxxviii 1988}
+test clock-2.1313 {conversion of 1988-09-01} {
+    clock format 589120496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/01/1988 12:34:56 die i mensis ix annoque mcmlxxxviii xii h xxxiv m lvi s 19 mcm 01 i  1 i Sep 245 2447406 09 ix  9 09/01/1988 die i mensis ix annoque mcmlxxxviii 88 lxxxviii 1988}
+test clock-2.1314 {conversion of 1988-09-30} {
+    clock format 591626096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/30/1988 12:34:56 die xxx mensis ix annoque mcmlxxxviii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Sep 274 2447435 09 ix  9 09/30/1988 die xxx mensis ix annoque mcmlxxxviii 88 lxxxviii 1988}
+test clock-2.1315 {conversion of 1988-10-01} {
+    clock format 591712496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/01/1988 12:34:56 die i mensis x annoque mcmlxxxviii xii h xxxiv m lvi s 19 mcm 01 i  1 i Oct 275 2447436 10 x 10 10/01/1988 die i mensis x annoque mcmlxxxviii 88 lxxxviii 1988}
+test clock-2.1316 {conversion of 1988-10-31} {
+    clock format 594304496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/31/1988 12:34:56 die xxxi mensis x annoque mcmlxxxviii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Oct 305 2447466 10 x 10 10/31/1988 die xxxi mensis x annoque mcmlxxxviii 88 lxxxviii 1988}
+test clock-2.1317 {conversion of 1988-11-01} {
+    clock format 594390896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/01/1988 12:34:56 die i mensis xi annoque mcmlxxxviii xii h xxxiv m lvi s 19 mcm 01 i  1 i Nov 306 2447467 11 xi 11 11/01/1988 die i mensis xi annoque mcmlxxxviii 88 lxxxviii 1988}
+test clock-2.1318 {conversion of 1988-11-30} {
+    clock format 596896496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/30/1988 12:34:56 die xxx mensis xi annoque mcmlxxxviii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Nov 335 2447496 11 xi 11 11/30/1988 die xxx mensis xi annoque mcmlxxxviii 88 lxxxviii 1988}
+test clock-2.1319 {conversion of 1988-12-01} {
+    clock format 596982896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/01/1988 12:34:56 die i mensis xii annoque mcmlxxxviii xii h xxxiv m lvi s 19 mcm 01 i  1 i Dec 336 2447497 12 xii 12 12/01/1988 die i mensis xii annoque mcmlxxxviii 88 lxxxviii 1988}
+test clock-2.1320 {conversion of 1988-12-31} {
+    clock format 599574896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/31/1988 12:34:56 die xxxi mensis xii annoque mcmlxxxviii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Dec 366 2447527 12 xii 12 12/31/1988 die xxxi mensis xii annoque mcmlxxxviii 88 lxxxviii 1988}
+test clock-2.1321 {conversion of 1989-01-01} {
+    clock format 599661296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/01/1989 12:34:56 die i mensis i annoque mcmlxxxix xii h xxxiv m lvi s 19 mcm 01 i  1 i Jan 001 2447528 01 i  1 01/01/1989 die i mensis i annoque mcmlxxxix 89 lxxxix 1989}
+test clock-2.1322 {conversion of 1989-01-31} {
+    clock format 602253296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/31/1989 12:34:56 die xxxi mensis i annoque mcmlxxxix xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jan 031 2447558 01 i  1 01/31/1989 die xxxi mensis i annoque mcmlxxxix 89 lxxxix 1989}
+test clock-2.1323 {conversion of 1989-02-01} {
+    clock format 602339696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/01/1989 12:34:56 die i mensis ii annoque mcmlxxxix xii h xxxiv m lvi s 19 mcm 01 i  1 i Feb 032 2447559 02 ii  2 02/01/1989 die i mensis ii annoque mcmlxxxix 89 lxxxix 1989}
+test clock-2.1324 {conversion of 1989-02-28} {
+    clock format 604672496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/28/1989 12:34:56 die xxviii mensis ii annoque mcmlxxxix xii h xxxiv m lvi s 19 mcm 28 xxviii 28 xxviii Feb 059 2447586 02 ii  2 02/28/1989 die xxviii mensis ii annoque mcmlxxxix 89 lxxxix 1989}
+test clock-2.1325 {conversion of 1989-03-01} {
+    clock format 604758896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/01/1989 12:34:56 die i mensis iii annoque mcmlxxxix xii h xxxiv m lvi s 19 mcm 01 i  1 i Mar 060 2447587 03 iii  3 03/01/1989 die i mensis iii annoque mcmlxxxix 89 lxxxix 1989}
+test clock-2.1326 {conversion of 1989-03-31} {
+    clock format 607350896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/31/1989 12:34:56 die xxxi mensis iii annoque mcmlxxxix xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Mar 090 2447617 03 iii  3 03/31/1989 die xxxi mensis iii annoque mcmlxxxix 89 lxxxix 1989}
+test clock-2.1327 {conversion of 1989-04-01} {
+    clock format 607437296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/01/1989 12:34:56 die i mensis iv annoque mcmlxxxix xii h xxxiv m lvi s 19 mcm 01 i  1 i Apr 091 2447618 04 iv  4 04/01/1989 die i mensis iv annoque mcmlxxxix 89 lxxxix 1989}
+test clock-2.1328 {conversion of 1989-04-30} {
+    clock format 609942896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/30/1989 12:34:56 die xxx mensis iv annoque mcmlxxxix xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Apr 120 2447647 04 iv  4 04/30/1989 die xxx mensis iv annoque mcmlxxxix 89 lxxxix 1989}
+test clock-2.1329 {conversion of 1989-05-01} {
+    clock format 610029296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/01/1989 12:34:56 die i mensis v annoque mcmlxxxix xii h xxxiv m lvi s 19 mcm 01 i  1 i May 121 2447648 05 v  5 05/01/1989 die i mensis v annoque mcmlxxxix 89 lxxxix 1989}
+test clock-2.1330 {conversion of 1989-05-31} {
+    clock format 612621296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/31/1989 12:34:56 die xxxi mensis v annoque mcmlxxxix xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi May 151 2447678 05 v  5 05/31/1989 die xxxi mensis v annoque mcmlxxxix 89 lxxxix 1989}
+test clock-2.1331 {conversion of 1989-06-01} {
+    clock format 612707696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/01/1989 12:34:56 die i mensis vi annoque mcmlxxxix xii h xxxiv m lvi s 19 mcm 01 i  1 i Jun 152 2447679 06 vi  6 06/01/1989 die i mensis vi annoque mcmlxxxix 89 lxxxix 1989}
+test clock-2.1332 {conversion of 1989-06-30} {
+    clock format 615213296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/30/1989 12:34:56 die xxx mensis vi annoque mcmlxxxix xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Jun 181 2447708 06 vi  6 06/30/1989 die xxx mensis vi annoque mcmlxxxix 89 lxxxix 1989}
+test clock-2.1333 {conversion of 1989-07-01} {
+    clock format 615299696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/01/1989 12:34:56 die i mensis vii annoque mcmlxxxix xii h xxxiv m lvi s 19 mcm 01 i  1 i Jul 182 2447709 07 vii  7 07/01/1989 die i mensis vii annoque mcmlxxxix 89 lxxxix 1989}
+test clock-2.1334 {conversion of 1989-07-31} {
+    clock format 617891696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/31/1989 12:34:56 die xxxi mensis vii annoque mcmlxxxix xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jul 212 2447739 07 vii  7 07/31/1989 die xxxi mensis vii annoque mcmlxxxix 89 lxxxix 1989}
+test clock-2.1335 {conversion of 1989-08-01} {
+    clock format 617978096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/01/1989 12:34:56 die i mensis viii annoque mcmlxxxix xii h xxxiv m lvi s 19 mcm 01 i  1 i Aug 213 2447740 08 viii  8 08/01/1989 die i mensis viii annoque mcmlxxxix 89 lxxxix 1989}
+test clock-2.1336 {conversion of 1989-08-31} {
+    clock format 620570096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/31/1989 12:34:56 die xxxi mensis viii annoque mcmlxxxix xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Aug 243 2447770 08 viii  8 08/31/1989 die xxxi mensis viii annoque mcmlxxxix 89 lxxxix 1989}
+test clock-2.1337 {conversion of 1989-09-01} {
+    clock format 620656496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/01/1989 12:34:56 die i mensis ix annoque mcmlxxxix xii h xxxiv m lvi s 19 mcm 01 i  1 i Sep 244 2447771 09 ix  9 09/01/1989 die i mensis ix annoque mcmlxxxix 89 lxxxix 1989}
+test clock-2.1338 {conversion of 1989-09-30} {
+    clock format 623162096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/30/1989 12:34:56 die xxx mensis ix annoque mcmlxxxix xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Sep 273 2447800 09 ix  9 09/30/1989 die xxx mensis ix annoque mcmlxxxix 89 lxxxix 1989}
+test clock-2.1339 {conversion of 1989-10-01} {
+    clock format 623248496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/01/1989 12:34:56 die i mensis x annoque mcmlxxxix xii h xxxiv m lvi s 19 mcm 01 i  1 i Oct 274 2447801 10 x 10 10/01/1989 die i mensis x annoque mcmlxxxix 89 lxxxix 1989}
+test clock-2.1340 {conversion of 1989-10-31} {
+    clock format 625840496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/31/1989 12:34:56 die xxxi mensis x annoque mcmlxxxix xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Oct 304 2447831 10 x 10 10/31/1989 die xxxi mensis x annoque mcmlxxxix 89 lxxxix 1989}
+test clock-2.1341 {conversion of 1989-11-01} {
+    clock format 625926896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/01/1989 12:34:56 die i mensis xi annoque mcmlxxxix xii h xxxiv m lvi s 19 mcm 01 i  1 i Nov 305 2447832 11 xi 11 11/01/1989 die i mensis xi annoque mcmlxxxix 89 lxxxix 1989}
+test clock-2.1342 {conversion of 1989-11-30} {
+    clock format 628432496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/30/1989 12:34:56 die xxx mensis xi annoque mcmlxxxix xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Nov 334 2447861 11 xi 11 11/30/1989 die xxx mensis xi annoque mcmlxxxix 89 lxxxix 1989}
+test clock-2.1343 {conversion of 1989-12-01} {
+    clock format 628518896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/01/1989 12:34:56 die i mensis xii annoque mcmlxxxix xii h xxxiv m lvi s 19 mcm 01 i  1 i Dec 335 2447862 12 xii 12 12/01/1989 die i mensis xii annoque mcmlxxxix 89 lxxxix 1989}
+test clock-2.1344 {conversion of 1989-12-31} {
+    clock format 631110896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/31/1989 12:34:56 die xxxi mensis xii annoque mcmlxxxix xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Dec 365 2447892 12 xii 12 12/31/1989 die xxxi mensis xii annoque mcmlxxxix 89 lxxxix 1989}
+test clock-2.1345 {conversion of 1992-01-01} {
+    clock format 694269296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/01/1992 12:34:56 die i mensis i annoque mcmxcii xii h xxxiv m lvi s 19 mcm 01 i  1 i Jan 001 2448623 01 i  1 01/01/1992 die i mensis i annoque mcmxcii 92 xcii 1992}
+test clock-2.1346 {conversion of 1992-01-31} {
+    clock format 696861296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/31/1992 12:34:56 die xxxi mensis i annoque mcmxcii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jan 031 2448653 01 i  1 01/31/1992 die xxxi mensis i annoque mcmxcii 92 xcii 1992}
+test clock-2.1347 {conversion of 1992-02-01} {
+    clock format 696947696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/01/1992 12:34:56 die i mensis ii annoque mcmxcii xii h xxxiv m lvi s 19 mcm 01 i  1 i Feb 032 2448654 02 ii  2 02/01/1992 die i mensis ii annoque mcmxcii 92 xcii 1992}
+test clock-2.1348 {conversion of 1992-02-29} {
+    clock format 699366896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/29/1992 12:34:56 die xxix mensis ii annoque mcmxcii xii h xxxiv m lvi s 19 mcm 29 xxix 29 xxix Feb 060 2448682 02 ii  2 02/29/1992 die xxix mensis ii annoque mcmxcii 92 xcii 1992}
+test clock-2.1349 {conversion of 1992-03-01} {
+    clock format 699453296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/01/1992 12:34:56 die i mensis iii annoque mcmxcii xii h xxxiv m lvi s 19 mcm 01 i  1 i Mar 061 2448683 03 iii  3 03/01/1992 die i mensis iii annoque mcmxcii 92 xcii 1992}
+test clock-2.1350 {conversion of 1992-03-31} {
+    clock format 702045296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/31/1992 12:34:56 die xxxi mensis iii annoque mcmxcii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Mar 091 2448713 03 iii  3 03/31/1992 die xxxi mensis iii annoque mcmxcii 92 xcii 1992}
+test clock-2.1351 {conversion of 1992-04-01} {
+    clock format 702131696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/01/1992 12:34:56 die i mensis iv annoque mcmxcii xii h xxxiv m lvi s 19 mcm 01 i  1 i Apr 092 2448714 04 iv  4 04/01/1992 die i mensis iv annoque mcmxcii 92 xcii 1992}
+test clock-2.1352 {conversion of 1992-04-30} {
+    clock format 704637296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/30/1992 12:34:56 die xxx mensis iv annoque mcmxcii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Apr 121 2448743 04 iv  4 04/30/1992 die xxx mensis iv annoque mcmxcii 92 xcii 1992}
+test clock-2.1353 {conversion of 1992-05-01} {
+    clock format 704723696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/01/1992 12:34:56 die i mensis v annoque mcmxcii xii h xxxiv m lvi s 19 mcm 01 i  1 i May 122 2448744 05 v  5 05/01/1992 die i mensis v annoque mcmxcii 92 xcii 1992}
+test clock-2.1354 {conversion of 1992-05-31} {
+    clock format 707315696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/31/1992 12:34:56 die xxxi mensis v annoque mcmxcii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi May 152 2448774 05 v  5 05/31/1992 die xxxi mensis v annoque mcmxcii 92 xcii 1992}
+test clock-2.1355 {conversion of 1992-06-01} {
+    clock format 707402096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/01/1992 12:34:56 die i mensis vi annoque mcmxcii xii h xxxiv m lvi s 19 mcm 01 i  1 i Jun 153 2448775 06 vi  6 06/01/1992 die i mensis vi annoque mcmxcii 92 xcii 1992}
+test clock-2.1356 {conversion of 1992-06-30} {
+    clock format 709907696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/30/1992 12:34:56 die xxx mensis vi annoque mcmxcii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Jun 182 2448804 06 vi  6 06/30/1992 die xxx mensis vi annoque mcmxcii 92 xcii 1992}
+test clock-2.1357 {conversion of 1992-07-01} {
+    clock format 709994096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/01/1992 12:34:56 die i mensis vii annoque mcmxcii xii h xxxiv m lvi s 19 mcm 01 i  1 i Jul 183 2448805 07 vii  7 07/01/1992 die i mensis vii annoque mcmxcii 92 xcii 1992}
+test clock-2.1358 {conversion of 1992-07-31} {
+    clock format 712586096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/31/1992 12:34:56 die xxxi mensis vii annoque mcmxcii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jul 213 2448835 07 vii  7 07/31/1992 die xxxi mensis vii annoque mcmxcii 92 xcii 1992}
+test clock-2.1359 {conversion of 1992-08-01} {
+    clock format 712672496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/01/1992 12:34:56 die i mensis viii annoque mcmxcii xii h xxxiv m lvi s 19 mcm 01 i  1 i Aug 214 2448836 08 viii  8 08/01/1992 die i mensis viii annoque mcmxcii 92 xcii 1992}
+test clock-2.1360 {conversion of 1992-08-31} {
+    clock format 715264496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/31/1992 12:34:56 die xxxi mensis viii annoque mcmxcii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Aug 244 2448866 08 viii  8 08/31/1992 die xxxi mensis viii annoque mcmxcii 92 xcii 1992}
+test clock-2.1361 {conversion of 1992-09-01} {
+    clock format 715350896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/01/1992 12:34:56 die i mensis ix annoque mcmxcii xii h xxxiv m lvi s 19 mcm 01 i  1 i Sep 245 2448867 09 ix  9 09/01/1992 die i mensis ix annoque mcmxcii 92 xcii 1992}
+test clock-2.1362 {conversion of 1992-09-30} {
+    clock format 717856496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/30/1992 12:34:56 die xxx mensis ix annoque mcmxcii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Sep 274 2448896 09 ix  9 09/30/1992 die xxx mensis ix annoque mcmxcii 92 xcii 1992}
+test clock-2.1363 {conversion of 1992-10-01} {
+    clock format 717942896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/01/1992 12:34:56 die i mensis x annoque mcmxcii xii h xxxiv m lvi s 19 mcm 01 i  1 i Oct 275 2448897 10 x 10 10/01/1992 die i mensis x annoque mcmxcii 92 xcii 1992}
+test clock-2.1364 {conversion of 1992-10-31} {
+    clock format 720534896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/31/1992 12:34:56 die xxxi mensis x annoque mcmxcii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Oct 305 2448927 10 x 10 10/31/1992 die xxxi mensis x annoque mcmxcii 92 xcii 1992}
+test clock-2.1365 {conversion of 1992-11-01} {
+    clock format 720621296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/01/1992 12:34:56 die i mensis xi annoque mcmxcii xii h xxxiv m lvi s 19 mcm 01 i  1 i Nov 306 2448928 11 xi 11 11/01/1992 die i mensis xi annoque mcmxcii 92 xcii 1992}
+test clock-2.1366 {conversion of 1992-11-30} {
+    clock format 723126896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/30/1992 12:34:56 die xxx mensis xi annoque mcmxcii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Nov 335 2448957 11 xi 11 11/30/1992 die xxx mensis xi annoque mcmxcii 92 xcii 1992}
+test clock-2.1367 {conversion of 1992-12-01} {
+    clock format 723213296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/01/1992 12:34:56 die i mensis xii annoque mcmxcii xii h xxxiv m lvi s 19 mcm 01 i  1 i Dec 336 2448958 12 xii 12 12/01/1992 die i mensis xii annoque mcmxcii 92 xcii 1992}
+test clock-2.1368 {conversion of 1992-12-31} {
+    clock format 725805296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/31/1992 12:34:56 die xxxi mensis xii annoque mcmxcii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Dec 366 2448988 12 xii 12 12/31/1992 die xxxi mensis xii annoque mcmxcii 92 xcii 1992}
+test clock-2.1369 {conversion of 1993-01-01} {
+    clock format 725891696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/01/1993 12:34:56 die i mensis i annoque mcmxciii xii h xxxiv m lvi s 19 mcm 01 i  1 i Jan 001 2448989 01 i  1 01/01/1993 die i mensis i annoque mcmxciii 93 xciii 1993}
+test clock-2.1370 {conversion of 1993-01-31} {
+    clock format 728483696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/31/1993 12:34:56 die xxxi mensis i annoque mcmxciii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jan 031 2449019 01 i  1 01/31/1993 die xxxi mensis i annoque mcmxciii 93 xciii 1993}
+test clock-2.1371 {conversion of 1993-02-01} {
+    clock format 728570096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/01/1993 12:34:56 die i mensis ii annoque mcmxciii xii h xxxiv m lvi s 19 mcm 01 i  1 i Feb 032 2449020 02 ii  2 02/01/1993 die i mensis ii annoque mcmxciii 93 xciii 1993}
+test clock-2.1372 {conversion of 1993-02-28} {
+    clock format 730902896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/28/1993 12:34:56 die xxviii mensis ii annoque mcmxciii xii h xxxiv m lvi s 19 mcm 28 xxviii 28 xxviii Feb 059 2449047 02 ii  2 02/28/1993 die xxviii mensis ii annoque mcmxciii 93 xciii 1993}
+test clock-2.1373 {conversion of 1993-03-01} {
+    clock format 730989296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/01/1993 12:34:56 die i mensis iii annoque mcmxciii xii h xxxiv m lvi s 19 mcm 01 i  1 i Mar 060 2449048 03 iii  3 03/01/1993 die i mensis iii annoque mcmxciii 93 xciii 1993}
+test clock-2.1374 {conversion of 1993-03-31} {
+    clock format 733581296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/31/1993 12:34:56 die xxxi mensis iii annoque mcmxciii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Mar 090 2449078 03 iii  3 03/31/1993 die xxxi mensis iii annoque mcmxciii 93 xciii 1993}
+test clock-2.1375 {conversion of 1993-04-01} {
+    clock format 733667696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/01/1993 12:34:56 die i mensis iv annoque mcmxciii xii h xxxiv m lvi s 19 mcm 01 i  1 i Apr 091 2449079 04 iv  4 04/01/1993 die i mensis iv annoque mcmxciii 93 xciii 1993}
+test clock-2.1376 {conversion of 1993-04-30} {
+    clock format 736173296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/30/1993 12:34:56 die xxx mensis iv annoque mcmxciii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Apr 120 2449108 04 iv  4 04/30/1993 die xxx mensis iv annoque mcmxciii 93 xciii 1993}
+test clock-2.1377 {conversion of 1993-05-01} {
+    clock format 736259696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/01/1993 12:34:56 die i mensis v annoque mcmxciii xii h xxxiv m lvi s 19 mcm 01 i  1 i May 121 2449109 05 v  5 05/01/1993 die i mensis v annoque mcmxciii 93 xciii 1993}
+test clock-2.1378 {conversion of 1993-05-31} {
+    clock format 738851696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/31/1993 12:34:56 die xxxi mensis v annoque mcmxciii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi May 151 2449139 05 v  5 05/31/1993 die xxxi mensis v annoque mcmxciii 93 xciii 1993}
+test clock-2.1379 {conversion of 1993-06-01} {
+    clock format 738938096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/01/1993 12:34:56 die i mensis vi annoque mcmxciii xii h xxxiv m lvi s 19 mcm 01 i  1 i Jun 152 2449140 06 vi  6 06/01/1993 die i mensis vi annoque mcmxciii 93 xciii 1993}
+test clock-2.1380 {conversion of 1993-06-30} {
+    clock format 741443696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/30/1993 12:34:56 die xxx mensis vi annoque mcmxciii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Jun 181 2449169 06 vi  6 06/30/1993 die xxx mensis vi annoque mcmxciii 93 xciii 1993}
+test clock-2.1381 {conversion of 1993-07-01} {
+    clock format 741530096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/01/1993 12:34:56 die i mensis vii annoque mcmxciii xii h xxxiv m lvi s 19 mcm 01 i  1 i Jul 182 2449170 07 vii  7 07/01/1993 die i mensis vii annoque mcmxciii 93 xciii 1993}
+test clock-2.1382 {conversion of 1993-07-31} {
+    clock format 744122096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/31/1993 12:34:56 die xxxi mensis vii annoque mcmxciii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jul 212 2449200 07 vii  7 07/31/1993 die xxxi mensis vii annoque mcmxciii 93 xciii 1993}
+test clock-2.1383 {conversion of 1993-08-01} {
+    clock format 744208496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/01/1993 12:34:56 die i mensis viii annoque mcmxciii xii h xxxiv m lvi s 19 mcm 01 i  1 i Aug 213 2449201 08 viii  8 08/01/1993 die i mensis viii annoque mcmxciii 93 xciii 1993}
+test clock-2.1384 {conversion of 1993-08-31} {
+    clock format 746800496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/31/1993 12:34:56 die xxxi mensis viii annoque mcmxciii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Aug 243 2449231 08 viii  8 08/31/1993 die xxxi mensis viii annoque mcmxciii 93 xciii 1993}
+test clock-2.1385 {conversion of 1993-09-01} {
+    clock format 746886896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/01/1993 12:34:56 die i mensis ix annoque mcmxciii xii h xxxiv m lvi s 19 mcm 01 i  1 i Sep 244 2449232 09 ix  9 09/01/1993 die i mensis ix annoque mcmxciii 93 xciii 1993}
+test clock-2.1386 {conversion of 1993-09-30} {
+    clock format 749392496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/30/1993 12:34:56 die xxx mensis ix annoque mcmxciii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Sep 273 2449261 09 ix  9 09/30/1993 die xxx mensis ix annoque mcmxciii 93 xciii 1993}
+test clock-2.1387 {conversion of 1993-10-01} {
+    clock format 749478896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/01/1993 12:34:56 die i mensis x annoque mcmxciii xii h xxxiv m lvi s 19 mcm 01 i  1 i Oct 274 2449262 10 x 10 10/01/1993 die i mensis x annoque mcmxciii 93 xciii 1993}
+test clock-2.1388 {conversion of 1993-10-31} {
+    clock format 752070896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/31/1993 12:34:56 die xxxi mensis x annoque mcmxciii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Oct 304 2449292 10 x 10 10/31/1993 die xxxi mensis x annoque mcmxciii 93 xciii 1993}
+test clock-2.1389 {conversion of 1993-11-01} {
+    clock format 752157296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/01/1993 12:34:56 die i mensis xi annoque mcmxciii xii h xxxiv m lvi s 19 mcm 01 i  1 i Nov 305 2449293 11 xi 11 11/01/1993 die i mensis xi annoque mcmxciii 93 xciii 1993}
+test clock-2.1390 {conversion of 1993-11-30} {
+    clock format 754662896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/30/1993 12:34:56 die xxx mensis xi annoque mcmxciii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Nov 334 2449322 11 xi 11 11/30/1993 die xxx mensis xi annoque mcmxciii 93 xciii 1993}
+test clock-2.1391 {conversion of 1993-12-01} {
+    clock format 754749296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/01/1993 12:34:56 die i mensis xii annoque mcmxciii xii h xxxiv m lvi s 19 mcm 01 i  1 i Dec 335 2449323 12 xii 12 12/01/1993 die i mensis xii annoque mcmxciii 93 xciii 1993}
+test clock-2.1392 {conversion of 1993-12-31} {
+    clock format 757341296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/31/1993 12:34:56 die xxxi mensis xii annoque mcmxciii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Dec 365 2449353 12 xii 12 12/31/1993 die xxxi mensis xii annoque mcmxciii 93 xciii 1993}
+test clock-2.1393 {conversion of 1996-01-01} {
+    clock format 820499696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/01/1996 12:34:56 die i mensis i annoque mcmxcvi xii h xxxiv m lvi s 19 mcm 01 i  1 i Jan 001 2450084 01 i  1 01/01/1996 die i mensis i annoque mcmxcvi 96 xcvi 1996}
+test clock-2.1394 {conversion of 1996-01-31} {
+    clock format 823091696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/31/1996 12:34:56 die xxxi mensis i annoque mcmxcvi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jan 031 2450114 01 i  1 01/31/1996 die xxxi mensis i annoque mcmxcvi 96 xcvi 1996}
+test clock-2.1395 {conversion of 1996-02-01} {
+    clock format 823178096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/01/1996 12:34:56 die i mensis ii annoque mcmxcvi xii h xxxiv m lvi s 19 mcm 01 i  1 i Feb 032 2450115 02 ii  2 02/01/1996 die i mensis ii annoque mcmxcvi 96 xcvi 1996}
+test clock-2.1396 {conversion of 1996-02-29} {
+    clock format 825597296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/29/1996 12:34:56 die xxix mensis ii annoque mcmxcvi xii h xxxiv m lvi s 19 mcm 29 xxix 29 xxix Feb 060 2450143 02 ii  2 02/29/1996 die xxix mensis ii annoque mcmxcvi 96 xcvi 1996}
+test clock-2.1397 {conversion of 1996-03-01} {
+    clock format 825683696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/01/1996 12:34:56 die i mensis iii annoque mcmxcvi xii h xxxiv m lvi s 19 mcm 01 i  1 i Mar 061 2450144 03 iii  3 03/01/1996 die i mensis iii annoque mcmxcvi 96 xcvi 1996}
+test clock-2.1398 {conversion of 1996-03-31} {
+    clock format 828275696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/31/1996 12:34:56 die xxxi mensis iii annoque mcmxcvi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Mar 091 2450174 03 iii  3 03/31/1996 die xxxi mensis iii annoque mcmxcvi 96 xcvi 1996}
+test clock-2.1399 {conversion of 1996-04-01} {
+    clock format 828362096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/01/1996 12:34:56 die i mensis iv annoque mcmxcvi xii h xxxiv m lvi s 19 mcm 01 i  1 i Apr 092 2450175 04 iv  4 04/01/1996 die i mensis iv annoque mcmxcvi 96 xcvi 1996}
+test clock-2.1400 {conversion of 1996-04-30} {
+    clock format 830867696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/30/1996 12:34:56 die xxx mensis iv annoque mcmxcvi xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Apr 121 2450204 04 iv  4 04/30/1996 die xxx mensis iv annoque mcmxcvi 96 xcvi 1996}
+test clock-2.1401 {conversion of 1996-05-01} {
+    clock format 830954096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/01/1996 12:34:56 die i mensis v annoque mcmxcvi xii h xxxiv m lvi s 19 mcm 01 i  1 i May 122 2450205 05 v  5 05/01/1996 die i mensis v annoque mcmxcvi 96 xcvi 1996}
+test clock-2.1402 {conversion of 1996-05-31} {
+    clock format 833546096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/31/1996 12:34:56 die xxxi mensis v annoque mcmxcvi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi May 152 2450235 05 v  5 05/31/1996 die xxxi mensis v annoque mcmxcvi 96 xcvi 1996}
+test clock-2.1403 {conversion of 1996-06-01} {
+    clock format 833632496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/01/1996 12:34:56 die i mensis vi annoque mcmxcvi xii h xxxiv m lvi s 19 mcm 01 i  1 i Jun 153 2450236 06 vi  6 06/01/1996 die i mensis vi annoque mcmxcvi 96 xcvi 1996}
+test clock-2.1404 {conversion of 1996-06-30} {
+    clock format 836138096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/30/1996 12:34:56 die xxx mensis vi annoque mcmxcvi xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Jun 182 2450265 06 vi  6 06/30/1996 die xxx mensis vi annoque mcmxcvi 96 xcvi 1996}
+test clock-2.1405 {conversion of 1996-07-01} {
+    clock format 836224496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/01/1996 12:34:56 die i mensis vii annoque mcmxcvi xii h xxxiv m lvi s 19 mcm 01 i  1 i Jul 183 2450266 07 vii  7 07/01/1996 die i mensis vii annoque mcmxcvi 96 xcvi 1996}
+test clock-2.1406 {conversion of 1996-07-31} {
+    clock format 838816496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/31/1996 12:34:56 die xxxi mensis vii annoque mcmxcvi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jul 213 2450296 07 vii  7 07/31/1996 die xxxi mensis vii annoque mcmxcvi 96 xcvi 1996}
+test clock-2.1407 {conversion of 1996-08-01} {
+    clock format 838902896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/01/1996 12:34:56 die i mensis viii annoque mcmxcvi xii h xxxiv m lvi s 19 mcm 01 i  1 i Aug 214 2450297 08 viii  8 08/01/1996 die i mensis viii annoque mcmxcvi 96 xcvi 1996}
+test clock-2.1408 {conversion of 1996-08-31} {
+    clock format 841494896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/31/1996 12:34:56 die xxxi mensis viii annoque mcmxcvi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Aug 244 2450327 08 viii  8 08/31/1996 die xxxi mensis viii annoque mcmxcvi 96 xcvi 1996}
+test clock-2.1409 {conversion of 1996-09-01} {
+    clock format 841581296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/01/1996 12:34:56 die i mensis ix annoque mcmxcvi xii h xxxiv m lvi s 19 mcm 01 i  1 i Sep 245 2450328 09 ix  9 09/01/1996 die i mensis ix annoque mcmxcvi 96 xcvi 1996}
+test clock-2.1410 {conversion of 1996-09-30} {
+    clock format 844086896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/30/1996 12:34:56 die xxx mensis ix annoque mcmxcvi xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Sep 274 2450357 09 ix  9 09/30/1996 die xxx mensis ix annoque mcmxcvi 96 xcvi 1996}
+test clock-2.1411 {conversion of 1996-10-01} {
+    clock format 844173296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/01/1996 12:34:56 die i mensis x annoque mcmxcvi xii h xxxiv m lvi s 19 mcm 01 i  1 i Oct 275 2450358 10 x 10 10/01/1996 die i mensis x annoque mcmxcvi 96 xcvi 1996}
+test clock-2.1412 {conversion of 1996-10-31} {
+    clock format 846765296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/31/1996 12:34:56 die xxxi mensis x annoque mcmxcvi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Oct 305 2450388 10 x 10 10/31/1996 die xxxi mensis x annoque mcmxcvi 96 xcvi 1996}
+test clock-2.1413 {conversion of 1996-11-01} {
+    clock format 846851696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/01/1996 12:34:56 die i mensis xi annoque mcmxcvi xii h xxxiv m lvi s 19 mcm 01 i  1 i Nov 306 2450389 11 xi 11 11/01/1996 die i mensis xi annoque mcmxcvi 96 xcvi 1996}
+test clock-2.1414 {conversion of 1996-11-30} {
+    clock format 849357296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/30/1996 12:34:56 die xxx mensis xi annoque mcmxcvi xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Nov 335 2450418 11 xi 11 11/30/1996 die xxx mensis xi annoque mcmxcvi 96 xcvi 1996}
+test clock-2.1415 {conversion of 1996-12-01} {
+    clock format 849443696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/01/1996 12:34:56 die i mensis xii annoque mcmxcvi xii h xxxiv m lvi s 19 mcm 01 i  1 i Dec 336 2450419 12 xii 12 12/01/1996 die i mensis xii annoque mcmxcvi 96 xcvi 1996}
+test clock-2.1416 {conversion of 1996-12-31} {
+    clock format 852035696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/31/1996 12:34:56 die xxxi mensis xii annoque mcmxcvi xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Dec 366 2450449 12 xii 12 12/31/1996 die xxxi mensis xii annoque mcmxcvi 96 xcvi 1996}
+test clock-2.1417 {conversion of 1997-01-01} {
+    clock format 852122096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/01/1997 12:34:56 die i mensis i annoque mcmxcvii xii h xxxiv m lvi s 19 mcm 01 i  1 i Jan 001 2450450 01 i  1 01/01/1997 die i mensis i annoque mcmxcvii 97 xcvii 1997}
+test clock-2.1418 {conversion of 1997-01-31} {
+    clock format 854714096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/31/1997 12:34:56 die xxxi mensis i annoque mcmxcvii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jan 031 2450480 01 i  1 01/31/1997 die xxxi mensis i annoque mcmxcvii 97 xcvii 1997}
+test clock-2.1419 {conversion of 1997-02-01} {
+    clock format 854800496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/01/1997 12:34:56 die i mensis ii annoque mcmxcvii xii h xxxiv m lvi s 19 mcm 01 i  1 i Feb 032 2450481 02 ii  2 02/01/1997 die i mensis ii annoque mcmxcvii 97 xcvii 1997}
+test clock-2.1420 {conversion of 1997-02-28} {
+    clock format 857133296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/28/1997 12:34:56 die xxviii mensis ii annoque mcmxcvii xii h xxxiv m lvi s 19 mcm 28 xxviii 28 xxviii Feb 059 2450508 02 ii  2 02/28/1997 die xxviii mensis ii annoque mcmxcvii 97 xcvii 1997}
+test clock-2.1421 {conversion of 1997-03-01} {
+    clock format 857219696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/01/1997 12:34:56 die i mensis iii annoque mcmxcvii xii h xxxiv m lvi s 19 mcm 01 i  1 i Mar 060 2450509 03 iii  3 03/01/1997 die i mensis iii annoque mcmxcvii 97 xcvii 1997}
+test clock-2.1422 {conversion of 1997-03-31} {
+    clock format 859811696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/31/1997 12:34:56 die xxxi mensis iii annoque mcmxcvii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Mar 090 2450539 03 iii  3 03/31/1997 die xxxi mensis iii annoque mcmxcvii 97 xcvii 1997}
+test clock-2.1423 {conversion of 1997-04-01} {
+    clock format 859898096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/01/1997 12:34:56 die i mensis iv annoque mcmxcvii xii h xxxiv m lvi s 19 mcm 01 i  1 i Apr 091 2450540 04 iv  4 04/01/1997 die i mensis iv annoque mcmxcvii 97 xcvii 1997}
+test clock-2.1424 {conversion of 1997-04-30} {
+    clock format 862403696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/30/1997 12:34:56 die xxx mensis iv annoque mcmxcvii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Apr 120 2450569 04 iv  4 04/30/1997 die xxx mensis iv annoque mcmxcvii 97 xcvii 1997}
+test clock-2.1425 {conversion of 1997-05-01} {
+    clock format 862490096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/01/1997 12:34:56 die i mensis v annoque mcmxcvii xii h xxxiv m lvi s 19 mcm 01 i  1 i May 121 2450570 05 v  5 05/01/1997 die i mensis v annoque mcmxcvii 97 xcvii 1997}
+test clock-2.1426 {conversion of 1997-05-31} {
+    clock format 865082096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/31/1997 12:34:56 die xxxi mensis v annoque mcmxcvii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi May 151 2450600 05 v  5 05/31/1997 die xxxi mensis v annoque mcmxcvii 97 xcvii 1997}
+test clock-2.1427 {conversion of 1997-06-01} {
+    clock format 865168496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/01/1997 12:34:56 die i mensis vi annoque mcmxcvii xii h xxxiv m lvi s 19 mcm 01 i  1 i Jun 152 2450601 06 vi  6 06/01/1997 die i mensis vi annoque mcmxcvii 97 xcvii 1997}
+test clock-2.1428 {conversion of 1997-06-30} {
+    clock format 867674096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/30/1997 12:34:56 die xxx mensis vi annoque mcmxcvii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Jun 181 2450630 06 vi  6 06/30/1997 die xxx mensis vi annoque mcmxcvii 97 xcvii 1997}
+test clock-2.1429 {conversion of 1997-07-01} {
+    clock format 867760496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/01/1997 12:34:56 die i mensis vii annoque mcmxcvii xii h xxxiv m lvi s 19 mcm 01 i  1 i Jul 182 2450631 07 vii  7 07/01/1997 die i mensis vii annoque mcmxcvii 97 xcvii 1997}
+test clock-2.1430 {conversion of 1997-07-31} {
+    clock format 870352496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/31/1997 12:34:56 die xxxi mensis vii annoque mcmxcvii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Jul 212 2450661 07 vii  7 07/31/1997 die xxxi mensis vii annoque mcmxcvii 97 xcvii 1997}
+test clock-2.1431 {conversion of 1997-08-01} {
+    clock format 870438896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/01/1997 12:34:56 die i mensis viii annoque mcmxcvii xii h xxxiv m lvi s 19 mcm 01 i  1 i Aug 213 2450662 08 viii  8 08/01/1997 die i mensis viii annoque mcmxcvii 97 xcvii 1997}
+test clock-2.1432 {conversion of 1997-08-31} {
+    clock format 873030896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/31/1997 12:34:56 die xxxi mensis viii annoque mcmxcvii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Aug 243 2450692 08 viii  8 08/31/1997 die xxxi mensis viii annoque mcmxcvii 97 xcvii 1997}
+test clock-2.1433 {conversion of 1997-09-01} {
+    clock format 873117296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/01/1997 12:34:56 die i mensis ix annoque mcmxcvii xii h xxxiv m lvi s 19 mcm 01 i  1 i Sep 244 2450693 09 ix  9 09/01/1997 die i mensis ix annoque mcmxcvii 97 xcvii 1997}
+test clock-2.1434 {conversion of 1997-09-30} {
+    clock format 875622896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/30/1997 12:34:56 die xxx mensis ix annoque mcmxcvii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Sep 273 2450722 09 ix  9 09/30/1997 die xxx mensis ix annoque mcmxcvii 97 xcvii 1997}
+test clock-2.1435 {conversion of 1997-10-01} {
+    clock format 875709296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/01/1997 12:34:56 die i mensis x annoque mcmxcvii xii h xxxiv m lvi s 19 mcm 01 i  1 i Oct 274 2450723 10 x 10 10/01/1997 die i mensis x annoque mcmxcvii 97 xcvii 1997}
+test clock-2.1436 {conversion of 1997-10-31} {
+    clock format 878301296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/31/1997 12:34:56 die xxxi mensis x annoque mcmxcvii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Oct 304 2450753 10 x 10 10/31/1997 die xxxi mensis x annoque mcmxcvii 97 xcvii 1997}
+test clock-2.1437 {conversion of 1997-11-01} {
+    clock format 878387696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/01/1997 12:34:56 die i mensis xi annoque mcmxcvii xii h xxxiv m lvi s 19 mcm 01 i  1 i Nov 305 2450754 11 xi 11 11/01/1997 die i mensis xi annoque mcmxcvii 97 xcvii 1997}
+test clock-2.1438 {conversion of 1997-11-30} {
+    clock format 880893296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/30/1997 12:34:56 die xxx mensis xi annoque mcmxcvii xii h xxxiv m lvi s 19 mcm 30 xxx 30 xxx Nov 334 2450783 11 xi 11 11/30/1997 die xxx mensis xi annoque mcmxcvii 97 xcvii 1997}
+test clock-2.1439 {conversion of 1997-12-01} {
+    clock format 880979696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/01/1997 12:34:56 die i mensis xii annoque mcmxcvii xii h xxxiv m lvi s 19 mcm 01 i  1 i Dec 335 2450784 12 xii 12 12/01/1997 die i mensis xii annoque mcmxcvii 97 xcvii 1997}
+test clock-2.1440 {conversion of 1997-12-31} {
+    clock format 883571696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/31/1997 12:34:56 die xxxi mensis xii annoque mcmxcvii xii h xxxiv m lvi s 19 mcm 31 xxxi 31 xxxi Dec 365 2450814 12 xii 12 12/31/1997 die xxxi mensis xii annoque mcmxcvii 97 xcvii 1997}
+test clock-2.1441 {conversion of 2000-01-01} {
+    clock format 946730096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/01/2000 12:34:56 die i mensis i annoque mm? xii h xxxiv m lvi s 20 mm 01 i  1 i Jan 001 2451545 01 i  1 01/01/2000 die i mensis i annoque mm? 00 ? 2000}
+test clock-2.1442 {conversion of 2000-01-31} {
+    clock format 949322096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/31/2000 12:34:56 die xxxi mensis i annoque mm? xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2451575 01 i  1 01/31/2000 die xxxi mensis i annoque mm? 00 ? 2000}
+test clock-2.1443 {conversion of 2000-02-01} {
+    clock format 949408496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/01/2000 12:34:56 die i mensis ii annoque mm? xii h xxxiv m lvi s 20 mm 01 i  1 i Feb 032 2451576 02 ii  2 02/01/2000 die i mensis ii annoque mm? 00 ? 2000}
+test clock-2.1444 {conversion of 2000-02-29} {
+    clock format 951827696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/29/2000 12:34:56 die xxix mensis ii annoque mm? xii h xxxiv m lvi s 20 mm 29 xxix 29 xxix Feb 060 2451604 02 ii  2 02/29/2000 die xxix mensis ii annoque mm? 00 ? 2000}
+test clock-2.1445 {conversion of 2000-03-01} {
+    clock format 951914096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/01/2000 12:34:56 die i mensis iii annoque mm? xii h xxxiv m lvi s 20 mm 01 i  1 i Mar 061 2451605 03 iii  3 03/01/2000 die i mensis iii annoque mm? 00 ? 2000}
+test clock-2.1446 {conversion of 2000-03-31} {
+    clock format 954506096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/31/2000 12:34:56 die xxxi mensis iii annoque mm? xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 091 2451635 03 iii  3 03/31/2000 die xxxi mensis iii annoque mm? 00 ? 2000}
+test clock-2.1447 {conversion of 2000-04-01} {
+    clock format 954592496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/01/2000 12:34:56 die i mensis iv annoque mm? xii h xxxiv m lvi s 20 mm 01 i  1 i Apr 092 2451636 04 iv  4 04/01/2000 die i mensis iv annoque mm? 00 ? 2000}
+test clock-2.1448 {conversion of 2000-04-30} {
+    clock format 957098096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/30/2000 12:34:56 die xxx mensis iv annoque mm? xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 121 2451665 04 iv  4 04/30/2000 die xxx mensis iv annoque mm? 00 ? 2000}
+test clock-2.1449 {conversion of 2000-05-01} {
+    clock format 957184496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/01/2000 12:34:56 die i mensis v annoque mm? xii h xxxiv m lvi s 20 mm 01 i  1 i May 122 2451666 05 v  5 05/01/2000 die i mensis v annoque mm? 00 ? 2000}
+test clock-2.1450 {conversion of 2000-05-31} {
+    clock format 959776496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/31/2000 12:34:56 die xxxi mensis v annoque mm? xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 152 2451696 05 v  5 05/31/2000 die xxxi mensis v annoque mm? 00 ? 2000}
+test clock-2.1451 {conversion of 2000-06-01} {
+    clock format 959862896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/01/2000 12:34:56 die i mensis vi annoque mm? xii h xxxiv m lvi s 20 mm 01 i  1 i Jun 153 2451697 06 vi  6 06/01/2000 die i mensis vi annoque mm? 00 ? 2000}
+test clock-2.1452 {conversion of 2000-06-30} {
+    clock format 962368496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/30/2000 12:34:56 die xxx mensis vi annoque mm? xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 182 2451726 06 vi  6 06/30/2000 die xxx mensis vi annoque mm? 00 ? 2000}
+test clock-2.1453 {conversion of 2000-07-01} {
+    clock format 962454896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/01/2000 12:34:56 die i mensis vii annoque mm? xii h xxxiv m lvi s 20 mm 01 i  1 i Jul 183 2451727 07 vii  7 07/01/2000 die i mensis vii annoque mm? 00 ? 2000}
+test clock-2.1454 {conversion of 2000-07-31} {
+    clock format 965046896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/31/2000 12:34:56 die xxxi mensis vii annoque mm? xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 213 2451757 07 vii  7 07/31/2000 die xxxi mensis vii annoque mm? 00 ? 2000}
+test clock-2.1455 {conversion of 2000-08-01} {
+    clock format 965133296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/01/2000 12:34:56 die i mensis viii annoque mm? xii h xxxiv m lvi s 20 mm 01 i  1 i Aug 214 2451758 08 viii  8 08/01/2000 die i mensis viii annoque mm? 00 ? 2000}
+test clock-2.1456 {conversion of 2000-08-31} {
+    clock format 967725296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/31/2000 12:34:56 die xxxi mensis viii annoque mm? xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 244 2451788 08 viii  8 08/31/2000 die xxxi mensis viii annoque mm? 00 ? 2000}
+test clock-2.1457 {conversion of 2000-09-01} {
+    clock format 967811696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/01/2000 12:34:56 die i mensis ix annoque mm? xii h xxxiv m lvi s 20 mm 01 i  1 i Sep 245 2451789 09 ix  9 09/01/2000 die i mensis ix annoque mm? 00 ? 2000}
+test clock-2.1458 {conversion of 2000-09-30} {
+    clock format 970317296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/30/2000 12:34:56 die xxx mensis ix annoque mm? xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 274 2451818 09 ix  9 09/30/2000 die xxx mensis ix annoque mm? 00 ? 2000}
+test clock-2.1459 {conversion of 2000-10-01} {
+    clock format 970403696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/01/2000 12:34:56 die i mensis x annoque mm? xii h xxxiv m lvi s 20 mm 01 i  1 i Oct 275 2451819 10 x 10 10/01/2000 die i mensis x annoque mm? 00 ? 2000}
+test clock-2.1460 {conversion of 2000-10-31} {
+    clock format 972995696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/31/2000 12:34:56 die xxxi mensis x annoque mm? xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 305 2451849 10 x 10 10/31/2000 die xxxi mensis x annoque mm? 00 ? 2000}
+test clock-2.1461 {conversion of 2000-11-01} {
+    clock format 973082096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/01/2000 12:34:56 die i mensis xi annoque mm? xii h xxxiv m lvi s 20 mm 01 i  1 i Nov 306 2451850 11 xi 11 11/01/2000 die i mensis xi annoque mm? 00 ? 2000}
+test clock-2.1462 {conversion of 2000-11-30} {
+    clock format 975587696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/30/2000 12:34:56 die xxx mensis xi annoque mm? xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 335 2451879 11 xi 11 11/30/2000 die xxx mensis xi annoque mm? 00 ? 2000}
+test clock-2.1463 {conversion of 2000-12-01} {
+    clock format 975674096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/01/2000 12:34:56 die i mensis xii annoque mm? xii h xxxiv m lvi s 20 mm 01 i  1 i Dec 336 2451880 12 xii 12 12/01/2000 die i mensis xii annoque mm? 00 ? 2000}
+test clock-2.1464 {conversion of 2000-12-31} {
+    clock format 978266096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/31/2000 12:34:56 die xxxi mensis xii annoque mm? xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 366 2451910 12 xii 12 12/31/2000 die xxxi mensis xii annoque mm? 00 ? 2000}
+test clock-2.1465 {conversion of 2001-01-01} {
+    clock format 978352496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/01/2001 12:34:56 die i mensis i annoque mmi xii h xxxiv m lvi s 20 mm 01 i  1 i Jan 001 2451911 01 i  1 01/01/2001 die i mensis i annoque mmi 01 i 2001}
+test clock-2.1466 {conversion of 2001-01-31} {
+    clock format 980944496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/31/2001 12:34:56 die xxxi mensis i annoque mmi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2451941 01 i  1 01/31/2001 die xxxi mensis i annoque mmi 01 i 2001}
+test clock-2.1467 {conversion of 2001-02-01} {
+    clock format 981030896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/01/2001 12:34:56 die i mensis ii annoque mmi xii h xxxiv m lvi s 20 mm 01 i  1 i Feb 032 2451942 02 ii  2 02/01/2001 die i mensis ii annoque mmi 01 i 2001}
+test clock-2.1468 {conversion of 2001-02-28} {
+    clock format 983363696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/28/2001 12:34:56 die xxviii mensis ii annoque mmi xii h xxxiv m lvi s 20 mm 28 xxviii 28 xxviii Feb 059 2451969 02 ii  2 02/28/2001 die xxviii mensis ii annoque mmi 01 i 2001}
+test clock-2.1469 {conversion of 2001-03-01} {
+    clock format 983450096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/01/2001 12:34:56 die i mensis iii annoque mmi xii h xxxiv m lvi s 20 mm 01 i  1 i Mar 060 2451970 03 iii  3 03/01/2001 die i mensis iii annoque mmi 01 i 2001}
+test clock-2.1470 {conversion of 2001-03-31} {
+    clock format 986042096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/31/2001 12:34:56 die xxxi mensis iii annoque mmi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 090 2452000 03 iii  3 03/31/2001 die xxxi mensis iii annoque mmi 01 i 2001}
+test clock-2.1471 {conversion of 2001-04-01} {
+    clock format 986128496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/01/2001 12:34:56 die i mensis iv annoque mmi xii h xxxiv m lvi s 20 mm 01 i  1 i Apr 091 2452001 04 iv  4 04/01/2001 die i mensis iv annoque mmi 01 i 2001}
+test clock-2.1472 {conversion of 2001-04-30} {
+    clock format 988634096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/30/2001 12:34:56 die xxx mensis iv annoque mmi xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 120 2452030 04 iv  4 04/30/2001 die xxx mensis iv annoque mmi 01 i 2001}
+test clock-2.1473 {conversion of 2001-05-01} {
+    clock format 988720496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/01/2001 12:34:56 die i mensis v annoque mmi xii h xxxiv m lvi s 20 mm 01 i  1 i May 121 2452031 05 v  5 05/01/2001 die i mensis v annoque mmi 01 i 2001}
+test clock-2.1474 {conversion of 2001-05-31} {
+    clock format 991312496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/31/2001 12:34:56 die xxxi mensis v annoque mmi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 151 2452061 05 v  5 05/31/2001 die xxxi mensis v annoque mmi 01 i 2001}
+test clock-2.1475 {conversion of 2001-06-01} {
+    clock format 991398896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/01/2001 12:34:56 die i mensis vi annoque mmi xii h xxxiv m lvi s 20 mm 01 i  1 i Jun 152 2452062 06 vi  6 06/01/2001 die i mensis vi annoque mmi 01 i 2001}
+test clock-2.1476 {conversion of 2001-06-30} {
+    clock format 993904496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/30/2001 12:34:56 die xxx mensis vi annoque mmi xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 181 2452091 06 vi  6 06/30/2001 die xxx mensis vi annoque mmi 01 i 2001}
+test clock-2.1477 {conversion of 2001-07-01} {
+    clock format 993990896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/01/2001 12:34:56 die i mensis vii annoque mmi xii h xxxiv m lvi s 20 mm 01 i  1 i Jul 182 2452092 07 vii  7 07/01/2001 die i mensis vii annoque mmi 01 i 2001}
+test clock-2.1478 {conversion of 2001-07-31} {
+    clock format 996582896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/31/2001 12:34:56 die xxxi mensis vii annoque mmi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 212 2452122 07 vii  7 07/31/2001 die xxxi mensis vii annoque mmi 01 i 2001}
+test clock-2.1479 {conversion of 2001-08-01} {
+    clock format 996669296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/01/2001 12:34:56 die i mensis viii annoque mmi xii h xxxiv m lvi s 20 mm 01 i  1 i Aug 213 2452123 08 viii  8 08/01/2001 die i mensis viii annoque mmi 01 i 2001}
+test clock-2.1480 {conversion of 2001-08-31} {
+    clock format 999261296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/31/2001 12:34:56 die xxxi mensis viii annoque mmi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 243 2452153 08 viii  8 08/31/2001 die xxxi mensis viii annoque mmi 01 i 2001}
+test clock-2.1481 {conversion of 2001-09-01} {
+    clock format 999347696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/01/2001 12:34:56 die i mensis ix annoque mmi xii h xxxiv m lvi s 20 mm 01 i  1 i Sep 244 2452154 09 ix  9 09/01/2001 die i mensis ix annoque mmi 01 i 2001}
+test clock-2.1482 {conversion of 2001-09-30} {
+    clock format 1001853296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/30/2001 12:34:56 die xxx mensis ix annoque mmi xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 273 2452183 09 ix  9 09/30/2001 die xxx mensis ix annoque mmi 01 i 2001}
+test clock-2.1483 {conversion of 2001-10-01} {
+    clock format 1001939696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/01/2001 12:34:56 die i mensis x annoque mmi xii h xxxiv m lvi s 20 mm 01 i  1 i Oct 274 2452184 10 x 10 10/01/2001 die i mensis x annoque mmi 01 i 2001}
+test clock-2.1484 {conversion of 2001-10-31} {
+    clock format 1004531696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/31/2001 12:34:56 die xxxi mensis x annoque mmi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 304 2452214 10 x 10 10/31/2001 die xxxi mensis x annoque mmi 01 i 2001}
+test clock-2.1485 {conversion of 2001-11-01} {
+    clock format 1004618096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/01/2001 12:34:56 die i mensis xi annoque mmi xii h xxxiv m lvi s 20 mm 01 i  1 i Nov 305 2452215 11 xi 11 11/01/2001 die i mensis xi annoque mmi 01 i 2001}
+test clock-2.1486 {conversion of 2001-11-30} {
+    clock format 1007123696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/30/2001 12:34:56 die xxx mensis xi annoque mmi xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 334 2452244 11 xi 11 11/30/2001 die xxx mensis xi annoque mmi 01 i 2001}
+test clock-2.1487 {conversion of 2001-12-01} {
+    clock format 1007210096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/01/2001 12:34:56 die i mensis xii annoque mmi xii h xxxiv m lvi s 20 mm 01 i  1 i Dec 335 2452245 12 xii 12 12/01/2001 die i mensis xii annoque mmi 01 i 2001}
+test clock-2.1488 {conversion of 2001-12-31} {
+    clock format 1009802096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/31/2001 12:34:56 die xxxi mensis xii annoque mmi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 365 2452275 12 xii 12 12/31/2001 die xxxi mensis xii annoque mmi 01 i 2001}
+test clock-2.1489 {conversion of 2002-01-01} {
+    clock format 1009888496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/01/2002 12:34:56 die i mensis i annoque mmii xii h xxxiv m lvi s 20 mm 01 i  1 i Jan 001 2452276 01 i  1 01/01/2002 die i mensis i annoque mmii 02 ii 2002}
+test clock-2.1490 {conversion of 2002-01-31} {
+    clock format 1012480496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/31/2002 12:34:56 die xxxi mensis i annoque mmii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2452306 01 i  1 01/31/2002 die xxxi mensis i annoque mmii 02 ii 2002}
+test clock-2.1491 {conversion of 2002-02-01} {
+    clock format 1012566896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/01/2002 12:34:56 die i mensis ii annoque mmii xii h xxxiv m lvi s 20 mm 01 i  1 i Feb 032 2452307 02 ii  2 02/01/2002 die i mensis ii annoque mmii 02 ii 2002}
+test clock-2.1492 {conversion of 2002-02-28} {
+    clock format 1014899696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/28/2002 12:34:56 die xxviii mensis ii annoque mmii xii h xxxiv m lvi s 20 mm 28 xxviii 28 xxviii Feb 059 2452334 02 ii  2 02/28/2002 die xxviii mensis ii annoque mmii 02 ii 2002}
+test clock-2.1493 {conversion of 2002-03-01} {
+    clock format 1014986096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/01/2002 12:34:56 die i mensis iii annoque mmii xii h xxxiv m lvi s 20 mm 01 i  1 i Mar 060 2452335 03 iii  3 03/01/2002 die i mensis iii annoque mmii 02 ii 2002}
+test clock-2.1494 {conversion of 2002-03-31} {
+    clock format 1017578096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/31/2002 12:34:56 die xxxi mensis iii annoque mmii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 090 2452365 03 iii  3 03/31/2002 die xxxi mensis iii annoque mmii 02 ii 2002}
+test clock-2.1495 {conversion of 2002-04-01} {
+    clock format 1017664496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/01/2002 12:34:56 die i mensis iv annoque mmii xii h xxxiv m lvi s 20 mm 01 i  1 i Apr 091 2452366 04 iv  4 04/01/2002 die i mensis iv annoque mmii 02 ii 2002}
+test clock-2.1496 {conversion of 2002-04-30} {
+    clock format 1020170096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/30/2002 12:34:56 die xxx mensis iv annoque mmii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 120 2452395 04 iv  4 04/30/2002 die xxx mensis iv annoque mmii 02 ii 2002}
+test clock-2.1497 {conversion of 2002-05-01} {
+    clock format 1020256496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/01/2002 12:34:56 die i mensis v annoque mmii xii h xxxiv m lvi s 20 mm 01 i  1 i May 121 2452396 05 v  5 05/01/2002 die i mensis v annoque mmii 02 ii 2002}
+test clock-2.1498 {conversion of 2002-05-31} {
+    clock format 1022848496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/31/2002 12:34:56 die xxxi mensis v annoque mmii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 151 2452426 05 v  5 05/31/2002 die xxxi mensis v annoque mmii 02 ii 2002}
+test clock-2.1499 {conversion of 2002-06-01} {
+    clock format 1022934896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/01/2002 12:34:56 die i mensis vi annoque mmii xii h xxxiv m lvi s 20 mm 01 i  1 i Jun 152 2452427 06 vi  6 06/01/2002 die i mensis vi annoque mmii 02 ii 2002}
+test clock-2.1500 {conversion of 2002-06-30} {
+    clock format 1025440496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/30/2002 12:34:56 die xxx mensis vi annoque mmii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 181 2452456 06 vi  6 06/30/2002 die xxx mensis vi annoque mmii 02 ii 2002}
+test clock-2.1501 {conversion of 2002-07-01} {
+    clock format 1025526896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/01/2002 12:34:56 die i mensis vii annoque mmii xii h xxxiv m lvi s 20 mm 01 i  1 i Jul 182 2452457 07 vii  7 07/01/2002 die i mensis vii annoque mmii 02 ii 2002}
+test clock-2.1502 {conversion of 2002-07-31} {
+    clock format 1028118896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/31/2002 12:34:56 die xxxi mensis vii annoque mmii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 212 2452487 07 vii  7 07/31/2002 die xxxi mensis vii annoque mmii 02 ii 2002}
+test clock-2.1503 {conversion of 2002-08-01} {
+    clock format 1028205296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/01/2002 12:34:56 die i mensis viii annoque mmii xii h xxxiv m lvi s 20 mm 01 i  1 i Aug 213 2452488 08 viii  8 08/01/2002 die i mensis viii annoque mmii 02 ii 2002}
+test clock-2.1504 {conversion of 2002-08-31} {
+    clock format 1030797296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/31/2002 12:34:56 die xxxi mensis viii annoque mmii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 243 2452518 08 viii  8 08/31/2002 die xxxi mensis viii annoque mmii 02 ii 2002}
+test clock-2.1505 {conversion of 2002-09-01} {
+    clock format 1030883696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/01/2002 12:34:56 die i mensis ix annoque mmii xii h xxxiv m lvi s 20 mm 01 i  1 i Sep 244 2452519 09 ix  9 09/01/2002 die i mensis ix annoque mmii 02 ii 2002}
+test clock-2.1506 {conversion of 2002-09-30} {
+    clock format 1033389296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/30/2002 12:34:56 die xxx mensis ix annoque mmii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 273 2452548 09 ix  9 09/30/2002 die xxx mensis ix annoque mmii 02 ii 2002}
+test clock-2.1507 {conversion of 2002-10-01} {
+    clock format 1033475696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/01/2002 12:34:56 die i mensis x annoque mmii xii h xxxiv m lvi s 20 mm 01 i  1 i Oct 274 2452549 10 x 10 10/01/2002 die i mensis x annoque mmii 02 ii 2002}
+test clock-2.1508 {conversion of 2002-10-31} {
+    clock format 1036067696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/31/2002 12:34:56 die xxxi mensis x annoque mmii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 304 2452579 10 x 10 10/31/2002 die xxxi mensis x annoque mmii 02 ii 2002}
+test clock-2.1509 {conversion of 2002-11-01} {
+    clock format 1036154096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/01/2002 12:34:56 die i mensis xi annoque mmii xii h xxxiv m lvi s 20 mm 01 i  1 i Nov 305 2452580 11 xi 11 11/01/2002 die i mensis xi annoque mmii 02 ii 2002}
+test clock-2.1510 {conversion of 2002-11-30} {
+    clock format 1038659696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/30/2002 12:34:56 die xxx mensis xi annoque mmii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 334 2452609 11 xi 11 11/30/2002 die xxx mensis xi annoque mmii 02 ii 2002}
+test clock-2.1511 {conversion of 2002-12-01} {
+    clock format 1038746096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/01/2002 12:34:56 die i mensis xii annoque mmii xii h xxxiv m lvi s 20 mm 01 i  1 i Dec 335 2452610 12 xii 12 12/01/2002 die i mensis xii annoque mmii 02 ii 2002}
+test clock-2.1512 {conversion of 2002-12-31} {
+    clock format 1041338096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/31/2002 12:34:56 die xxxi mensis xii annoque mmii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 365 2452640 12 xii 12 12/31/2002 die xxxi mensis xii annoque mmii 02 ii 2002}
+test clock-2.1513 {conversion of 2003-01-01} {
+    clock format 1041424496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/01/2003 12:34:56 die i mensis i annoque mmiii xii h xxxiv m lvi s 20 mm 01 i  1 i Jan 001 2452641 01 i  1 01/01/2003 die i mensis i annoque mmiii 03 iii 2003}
+test clock-2.1514 {conversion of 2003-01-31} {
+    clock format 1044016496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/31/2003 12:34:56 die xxxi mensis i annoque mmiii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2452671 01 i  1 01/31/2003 die xxxi mensis i annoque mmiii 03 iii 2003}
+test clock-2.1515 {conversion of 2003-02-01} {
+    clock format 1044102896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/01/2003 12:34:56 die i mensis ii annoque mmiii xii h xxxiv m lvi s 20 mm 01 i  1 i Feb 032 2452672 02 ii  2 02/01/2003 die i mensis ii annoque mmiii 03 iii 2003}
+test clock-2.1516 {conversion of 2003-02-28} {
+    clock format 1046435696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/28/2003 12:34:56 die xxviii mensis ii annoque mmiii xii h xxxiv m lvi s 20 mm 28 xxviii 28 xxviii Feb 059 2452699 02 ii  2 02/28/2003 die xxviii mensis ii annoque mmiii 03 iii 2003}
+test clock-2.1517 {conversion of 2003-03-01} {
+    clock format 1046522096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/01/2003 12:34:56 die i mensis iii annoque mmiii xii h xxxiv m lvi s 20 mm 01 i  1 i Mar 060 2452700 03 iii  3 03/01/2003 die i mensis iii annoque mmiii 03 iii 2003}
+test clock-2.1518 {conversion of 2003-03-31} {
+    clock format 1049114096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/31/2003 12:34:56 die xxxi mensis iii annoque mmiii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 090 2452730 03 iii  3 03/31/2003 die xxxi mensis iii annoque mmiii 03 iii 2003}
+test clock-2.1519 {conversion of 2003-04-01} {
+    clock format 1049200496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/01/2003 12:34:56 die i mensis iv annoque mmiii xii h xxxiv m lvi s 20 mm 01 i  1 i Apr 091 2452731 04 iv  4 04/01/2003 die i mensis iv annoque mmiii 03 iii 2003}
+test clock-2.1520 {conversion of 2003-04-30} {
+    clock format 1051706096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/30/2003 12:34:56 die xxx mensis iv annoque mmiii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 120 2452760 04 iv  4 04/30/2003 die xxx mensis iv annoque mmiii 03 iii 2003}
+test clock-2.1521 {conversion of 2003-05-01} {
+    clock format 1051792496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/01/2003 12:34:56 die i mensis v annoque mmiii xii h xxxiv m lvi s 20 mm 01 i  1 i May 121 2452761 05 v  5 05/01/2003 die i mensis v annoque mmiii 03 iii 2003}
+test clock-2.1522 {conversion of 2003-05-31} {
+    clock format 1054384496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/31/2003 12:34:56 die xxxi mensis v annoque mmiii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 151 2452791 05 v  5 05/31/2003 die xxxi mensis v annoque mmiii 03 iii 2003}
+test clock-2.1523 {conversion of 2003-06-01} {
+    clock format 1054470896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/01/2003 12:34:56 die i mensis vi annoque mmiii xii h xxxiv m lvi s 20 mm 01 i  1 i Jun 152 2452792 06 vi  6 06/01/2003 die i mensis vi annoque mmiii 03 iii 2003}
+test clock-2.1524 {conversion of 2003-06-30} {
+    clock format 1056976496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/30/2003 12:34:56 die xxx mensis vi annoque mmiii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 181 2452821 06 vi  6 06/30/2003 die xxx mensis vi annoque mmiii 03 iii 2003}
+test clock-2.1525 {conversion of 2003-07-01} {
+    clock format 1057062896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/01/2003 12:34:56 die i mensis vii annoque mmiii xii h xxxiv m lvi s 20 mm 01 i  1 i Jul 182 2452822 07 vii  7 07/01/2003 die i mensis vii annoque mmiii 03 iii 2003}
+test clock-2.1526 {conversion of 2003-07-31} {
+    clock format 1059654896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/31/2003 12:34:56 die xxxi mensis vii annoque mmiii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 212 2452852 07 vii  7 07/31/2003 die xxxi mensis vii annoque mmiii 03 iii 2003}
+test clock-2.1527 {conversion of 2003-08-01} {
+    clock format 1059741296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/01/2003 12:34:56 die i mensis viii annoque mmiii xii h xxxiv m lvi s 20 mm 01 i  1 i Aug 213 2452853 08 viii  8 08/01/2003 die i mensis viii annoque mmiii 03 iii 2003}
+test clock-2.1528 {conversion of 2003-08-31} {
+    clock format 1062333296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/31/2003 12:34:56 die xxxi mensis viii annoque mmiii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 243 2452883 08 viii  8 08/31/2003 die xxxi mensis viii annoque mmiii 03 iii 2003}
+test clock-2.1529 {conversion of 2003-09-01} {
+    clock format 1062419696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/01/2003 12:34:56 die i mensis ix annoque mmiii xii h xxxiv m lvi s 20 mm 01 i  1 i Sep 244 2452884 09 ix  9 09/01/2003 die i mensis ix annoque mmiii 03 iii 2003}
+test clock-2.1530 {conversion of 2003-09-30} {
+    clock format 1064925296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/30/2003 12:34:56 die xxx mensis ix annoque mmiii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 273 2452913 09 ix  9 09/30/2003 die xxx mensis ix annoque mmiii 03 iii 2003}
+test clock-2.1531 {conversion of 2003-10-01} {
+    clock format 1065011696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/01/2003 12:34:56 die i mensis x annoque mmiii xii h xxxiv m lvi s 20 mm 01 i  1 i Oct 274 2452914 10 x 10 10/01/2003 die i mensis x annoque mmiii 03 iii 2003}
+test clock-2.1532 {conversion of 2003-10-31} {
+    clock format 1067603696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/31/2003 12:34:56 die xxxi mensis x annoque mmiii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 304 2452944 10 x 10 10/31/2003 die xxxi mensis x annoque mmiii 03 iii 2003}
+test clock-2.1533 {conversion of 2003-11-01} {
+    clock format 1067690096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/01/2003 12:34:56 die i mensis xi annoque mmiii xii h xxxiv m lvi s 20 mm 01 i  1 i Nov 305 2452945 11 xi 11 11/01/2003 die i mensis xi annoque mmiii 03 iii 2003}
+test clock-2.1534 {conversion of 2003-11-30} {
+    clock format 1070195696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/30/2003 12:34:56 die xxx mensis xi annoque mmiii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 334 2452974 11 xi 11 11/30/2003 die xxx mensis xi annoque mmiii 03 iii 2003}
+test clock-2.1535 {conversion of 2003-12-01} {
+    clock format 1070282096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/01/2003 12:34:56 die i mensis xii annoque mmiii xii h xxxiv m lvi s 20 mm 01 i  1 i Dec 335 2452975 12 xii 12 12/01/2003 die i mensis xii annoque mmiii 03 iii 2003}
+test clock-2.1536 {conversion of 2003-12-31} {
+    clock format 1072874096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/31/2003 12:34:56 die xxxi mensis xii annoque mmiii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 365 2453005 12 xii 12 12/31/2003 die xxxi mensis xii annoque mmiii 03 iii 2003}
+test clock-2.1537 {conversion of 2004-01-01} {
+    clock format 1072960496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/01/2004 12:34:56 die i mensis i annoque mmiv xii h xxxiv m lvi s 20 mm 01 i  1 i Jan 001 2453006 01 i  1 01/01/2004 die i mensis i annoque mmiv 04 iv 2004}
+test clock-2.1538 {conversion of 2004-01-31} {
+    clock format 1075552496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/31/2004 12:34:56 die xxxi mensis i annoque mmiv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2453036 01 i  1 01/31/2004 die xxxi mensis i annoque mmiv 04 iv 2004}
+test clock-2.1539 {conversion of 2004-02-01} {
+    clock format 1075638896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/01/2004 12:34:56 die i mensis ii annoque mmiv xii h xxxiv m lvi s 20 mm 01 i  1 i Feb 032 2453037 02 ii  2 02/01/2004 die i mensis ii annoque mmiv 04 iv 2004}
+test clock-2.1540 {conversion of 2004-02-29} {
+    clock format 1078058096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/29/2004 12:34:56 die xxix mensis ii annoque mmiv xii h xxxiv m lvi s 20 mm 29 xxix 29 xxix Feb 060 2453065 02 ii  2 02/29/2004 die xxix mensis ii annoque mmiv 04 iv 2004}
+test clock-2.1541 {conversion of 2004-03-01} {
+    clock format 1078144496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/01/2004 12:34:56 die i mensis iii annoque mmiv xii h xxxiv m lvi s 20 mm 01 i  1 i Mar 061 2453066 03 iii  3 03/01/2004 die i mensis iii annoque mmiv 04 iv 2004}
+test clock-2.1542 {conversion of 2004-03-31} {
+    clock format 1080736496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/31/2004 12:34:56 die xxxi mensis iii annoque mmiv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 091 2453096 03 iii  3 03/31/2004 die xxxi mensis iii annoque mmiv 04 iv 2004}
+test clock-2.1543 {conversion of 2004-04-01} {
+    clock format 1080822896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/01/2004 12:34:56 die i mensis iv annoque mmiv xii h xxxiv m lvi s 20 mm 01 i  1 i Apr 092 2453097 04 iv  4 04/01/2004 die i mensis iv annoque mmiv 04 iv 2004}
+test clock-2.1544 {conversion of 2004-04-30} {
+    clock format 1083328496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/30/2004 12:34:56 die xxx mensis iv annoque mmiv xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 121 2453126 04 iv  4 04/30/2004 die xxx mensis iv annoque mmiv 04 iv 2004}
+test clock-2.1545 {conversion of 2004-05-01} {
+    clock format 1083414896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/01/2004 12:34:56 die i mensis v annoque mmiv xii h xxxiv m lvi s 20 mm 01 i  1 i May 122 2453127 05 v  5 05/01/2004 die i mensis v annoque mmiv 04 iv 2004}
+test clock-2.1546 {conversion of 2004-05-31} {
+    clock format 1086006896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/31/2004 12:34:56 die xxxi mensis v annoque mmiv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 152 2453157 05 v  5 05/31/2004 die xxxi mensis v annoque mmiv 04 iv 2004}
+test clock-2.1547 {conversion of 2004-06-01} {
+    clock format 1086093296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/01/2004 12:34:56 die i mensis vi annoque mmiv xii h xxxiv m lvi s 20 mm 01 i  1 i Jun 153 2453158 06 vi  6 06/01/2004 die i mensis vi annoque mmiv 04 iv 2004}
+test clock-2.1548 {conversion of 2004-06-30} {
+    clock format 1088598896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/30/2004 12:34:56 die xxx mensis vi annoque mmiv xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 182 2453187 06 vi  6 06/30/2004 die xxx mensis vi annoque mmiv 04 iv 2004}
+test clock-2.1549 {conversion of 2004-07-01} {
+    clock format 1088685296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/01/2004 12:34:56 die i mensis vii annoque mmiv xii h xxxiv m lvi s 20 mm 01 i  1 i Jul 183 2453188 07 vii  7 07/01/2004 die i mensis vii annoque mmiv 04 iv 2004}
+test clock-2.1550 {conversion of 2004-07-31} {
+    clock format 1091277296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/31/2004 12:34:56 die xxxi mensis vii annoque mmiv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 213 2453218 07 vii  7 07/31/2004 die xxxi mensis vii annoque mmiv 04 iv 2004}
+test clock-2.1551 {conversion of 2004-08-01} {
+    clock format 1091363696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/01/2004 12:34:56 die i mensis viii annoque mmiv xii h xxxiv m lvi s 20 mm 01 i  1 i Aug 214 2453219 08 viii  8 08/01/2004 die i mensis viii annoque mmiv 04 iv 2004}
+test clock-2.1552 {conversion of 2004-08-31} {
+    clock format 1093955696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/31/2004 12:34:56 die xxxi mensis viii annoque mmiv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 244 2453249 08 viii  8 08/31/2004 die xxxi mensis viii annoque mmiv 04 iv 2004}
+test clock-2.1553 {conversion of 2004-09-01} {
+    clock format 1094042096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/01/2004 12:34:56 die i mensis ix annoque mmiv xii h xxxiv m lvi s 20 mm 01 i  1 i Sep 245 2453250 09 ix  9 09/01/2004 die i mensis ix annoque mmiv 04 iv 2004}
+test clock-2.1554 {conversion of 2004-09-30} {
+    clock format 1096547696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/30/2004 12:34:56 die xxx mensis ix annoque mmiv xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 274 2453279 09 ix  9 09/30/2004 die xxx mensis ix annoque mmiv 04 iv 2004}
+test clock-2.1555 {conversion of 2004-10-01} {
+    clock format 1096634096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/01/2004 12:34:56 die i mensis x annoque mmiv xii h xxxiv m lvi s 20 mm 01 i  1 i Oct 275 2453280 10 x 10 10/01/2004 die i mensis x annoque mmiv 04 iv 2004}
+test clock-2.1556 {conversion of 2004-10-31} {
+    clock format 1099226096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/31/2004 12:34:56 die xxxi mensis x annoque mmiv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 305 2453310 10 x 10 10/31/2004 die xxxi mensis x annoque mmiv 04 iv 2004}
+test clock-2.1557 {conversion of 2004-11-01} {
+    clock format 1099312496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/01/2004 12:34:56 die i mensis xi annoque mmiv xii h xxxiv m lvi s 20 mm 01 i  1 i Nov 306 2453311 11 xi 11 11/01/2004 die i mensis xi annoque mmiv 04 iv 2004}
+test clock-2.1558 {conversion of 2004-11-30} {
+    clock format 1101818096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/30/2004 12:34:56 die xxx mensis xi annoque mmiv xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 335 2453340 11 xi 11 11/30/2004 die xxx mensis xi annoque mmiv 04 iv 2004}
+test clock-2.1559 {conversion of 2004-12-01} {
+    clock format 1101904496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/01/2004 12:34:56 die i mensis xii annoque mmiv xii h xxxiv m lvi s 20 mm 01 i  1 i Dec 336 2453341 12 xii 12 12/01/2004 die i mensis xii annoque mmiv 04 iv 2004}
+test clock-2.1560 {conversion of 2004-12-31} {
+    clock format 1104496496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/31/2004 12:34:56 die xxxi mensis xii annoque mmiv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 366 2453371 12 xii 12 12/31/2004 die xxxi mensis xii annoque mmiv 04 iv 2004}
+test clock-2.1561 {conversion of 2005-01-01} {
+    clock format 1104582896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/01/2005 12:34:56 die i mensis i annoque mmv xii h xxxiv m lvi s 20 mm 01 i  1 i Jan 001 2453372 01 i  1 01/01/2005 die i mensis i annoque mmv 05 v 2005}
+test clock-2.1562 {conversion of 2005-01-31} {
+    clock format 1107174896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/31/2005 12:34:56 die xxxi mensis i annoque mmv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2453402 01 i  1 01/31/2005 die xxxi mensis i annoque mmv 05 v 2005}
+test clock-2.1563 {conversion of 2005-02-01} {
+    clock format 1107261296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/01/2005 12:34:56 die i mensis ii annoque mmv xii h xxxiv m lvi s 20 mm 01 i  1 i Feb 032 2453403 02 ii  2 02/01/2005 die i mensis ii annoque mmv 05 v 2005}
+test clock-2.1564 {conversion of 2005-02-28} {
+    clock format 1109594096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/28/2005 12:34:56 die xxviii mensis ii annoque mmv xii h xxxiv m lvi s 20 mm 28 xxviii 28 xxviii Feb 059 2453430 02 ii  2 02/28/2005 die xxviii mensis ii annoque mmv 05 v 2005}
+test clock-2.1565 {conversion of 2005-03-01} {
+    clock format 1109680496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/01/2005 12:34:56 die i mensis iii annoque mmv xii h xxxiv m lvi s 20 mm 01 i  1 i Mar 060 2453431 03 iii  3 03/01/2005 die i mensis iii annoque mmv 05 v 2005}
+test clock-2.1566 {conversion of 2005-03-31} {
+    clock format 1112272496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/31/2005 12:34:56 die xxxi mensis iii annoque mmv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 090 2453461 03 iii  3 03/31/2005 die xxxi mensis iii annoque mmv 05 v 2005}
+test clock-2.1567 {conversion of 2005-04-01} {
+    clock format 1112358896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/01/2005 12:34:56 die i mensis iv annoque mmv xii h xxxiv m lvi s 20 mm 01 i  1 i Apr 091 2453462 04 iv  4 04/01/2005 die i mensis iv annoque mmv 05 v 2005}
+test clock-2.1568 {conversion of 2005-04-30} {
+    clock format 1114864496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/30/2005 12:34:56 die xxx mensis iv annoque mmv xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 120 2453491 04 iv  4 04/30/2005 die xxx mensis iv annoque mmv 05 v 2005}
+test clock-2.1569 {conversion of 2005-05-01} {
+    clock format 1114950896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/01/2005 12:34:56 die i mensis v annoque mmv xii h xxxiv m lvi s 20 mm 01 i  1 i May 121 2453492 05 v  5 05/01/2005 die i mensis v annoque mmv 05 v 2005}
+test clock-2.1570 {conversion of 2005-05-31} {
+    clock format 1117542896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/31/2005 12:34:56 die xxxi mensis v annoque mmv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 151 2453522 05 v  5 05/31/2005 die xxxi mensis v annoque mmv 05 v 2005}
+test clock-2.1571 {conversion of 2005-06-01} {
+    clock format 1117629296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/01/2005 12:34:56 die i mensis vi annoque mmv xii h xxxiv m lvi s 20 mm 01 i  1 i Jun 152 2453523 06 vi  6 06/01/2005 die i mensis vi annoque mmv 05 v 2005}
+test clock-2.1572 {conversion of 2005-06-30} {
+    clock format 1120134896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/30/2005 12:34:56 die xxx mensis vi annoque mmv xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 181 2453552 06 vi  6 06/30/2005 die xxx mensis vi annoque mmv 05 v 2005}
+test clock-2.1573 {conversion of 2005-07-01} {
+    clock format 1120221296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/01/2005 12:34:56 die i mensis vii annoque mmv xii h xxxiv m lvi s 20 mm 01 i  1 i Jul 182 2453553 07 vii  7 07/01/2005 die i mensis vii annoque mmv 05 v 2005}
+test clock-2.1574 {conversion of 2005-07-31} {
+    clock format 1122813296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/31/2005 12:34:56 die xxxi mensis vii annoque mmv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 212 2453583 07 vii  7 07/31/2005 die xxxi mensis vii annoque mmv 05 v 2005}
+test clock-2.1575 {conversion of 2005-08-01} {
+    clock format 1122899696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/01/2005 12:34:56 die i mensis viii annoque mmv xii h xxxiv m lvi s 20 mm 01 i  1 i Aug 213 2453584 08 viii  8 08/01/2005 die i mensis viii annoque mmv 05 v 2005}
+test clock-2.1576 {conversion of 2005-08-31} {
+    clock format 1125491696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/31/2005 12:34:56 die xxxi mensis viii annoque mmv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 243 2453614 08 viii  8 08/31/2005 die xxxi mensis viii annoque mmv 05 v 2005}
+test clock-2.1577 {conversion of 2005-09-01} {
+    clock format 1125578096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/01/2005 12:34:56 die i mensis ix annoque mmv xii h xxxiv m lvi s 20 mm 01 i  1 i Sep 244 2453615 09 ix  9 09/01/2005 die i mensis ix annoque mmv 05 v 2005}
+test clock-2.1578 {conversion of 2005-09-30} {
+    clock format 1128083696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/30/2005 12:34:56 die xxx mensis ix annoque mmv xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 273 2453644 09 ix  9 09/30/2005 die xxx mensis ix annoque mmv 05 v 2005}
+test clock-2.1579 {conversion of 2005-10-01} {
+    clock format 1128170096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/01/2005 12:34:56 die i mensis x annoque mmv xii h xxxiv m lvi s 20 mm 01 i  1 i Oct 274 2453645 10 x 10 10/01/2005 die i mensis x annoque mmv 05 v 2005}
+test clock-2.1580 {conversion of 2005-10-31} {
+    clock format 1130762096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/31/2005 12:34:56 die xxxi mensis x annoque mmv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 304 2453675 10 x 10 10/31/2005 die xxxi mensis x annoque mmv 05 v 2005}
+test clock-2.1581 {conversion of 2005-11-01} {
+    clock format 1130848496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/01/2005 12:34:56 die i mensis xi annoque mmv xii h xxxiv m lvi s 20 mm 01 i  1 i Nov 305 2453676 11 xi 11 11/01/2005 die i mensis xi annoque mmv 05 v 2005}
+test clock-2.1582 {conversion of 2005-11-30} {
+    clock format 1133354096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/30/2005 12:34:56 die xxx mensis xi annoque mmv xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 334 2453705 11 xi 11 11/30/2005 die xxx mensis xi annoque mmv 05 v 2005}
+test clock-2.1583 {conversion of 2005-12-01} {
+    clock format 1133440496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/01/2005 12:34:56 die i mensis xii annoque mmv xii h xxxiv m lvi s 20 mm 01 i  1 i Dec 335 2453706 12 xii 12 12/01/2005 die i mensis xii annoque mmv 05 v 2005}
+test clock-2.1584 {conversion of 2005-12-31} {
+    clock format 1136032496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/31/2005 12:34:56 die xxxi mensis xii annoque mmv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 365 2453736 12 xii 12 12/31/2005 die xxxi mensis xii annoque mmv 05 v 2005}
+test clock-2.1585 {conversion of 2006-01-01} {
+    clock format 1136118896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/01/2006 12:34:56 die i mensis i annoque mmvi xii h xxxiv m lvi s 20 mm 01 i  1 i Jan 001 2453737 01 i  1 01/01/2006 die i mensis i annoque mmvi 06 vi 2006}
+test clock-2.1586 {conversion of 2006-01-31} {
+    clock format 1138710896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/31/2006 12:34:56 die xxxi mensis i annoque mmvi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2453767 01 i  1 01/31/2006 die xxxi mensis i annoque mmvi 06 vi 2006}
+test clock-2.1587 {conversion of 2006-02-01} {
+    clock format 1138797296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/01/2006 12:34:56 die i mensis ii annoque mmvi xii h xxxiv m lvi s 20 mm 01 i  1 i Feb 032 2453768 02 ii  2 02/01/2006 die i mensis ii annoque mmvi 06 vi 2006}
+test clock-2.1588 {conversion of 2006-02-28} {
+    clock format 1141130096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/28/2006 12:34:56 die xxviii mensis ii annoque mmvi xii h xxxiv m lvi s 20 mm 28 xxviii 28 xxviii Feb 059 2453795 02 ii  2 02/28/2006 die xxviii mensis ii annoque mmvi 06 vi 2006}
+test clock-2.1589 {conversion of 2006-03-01} {
+    clock format 1141216496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/01/2006 12:34:56 die i mensis iii annoque mmvi xii h xxxiv m lvi s 20 mm 01 i  1 i Mar 060 2453796 03 iii  3 03/01/2006 die i mensis iii annoque mmvi 06 vi 2006}
+test clock-2.1590 {conversion of 2006-03-31} {
+    clock format 1143808496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/31/2006 12:34:56 die xxxi mensis iii annoque mmvi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 090 2453826 03 iii  3 03/31/2006 die xxxi mensis iii annoque mmvi 06 vi 2006}
+test clock-2.1591 {conversion of 2006-04-01} {
+    clock format 1143894896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/01/2006 12:34:56 die i mensis iv annoque mmvi xii h xxxiv m lvi s 20 mm 01 i  1 i Apr 091 2453827 04 iv  4 04/01/2006 die i mensis iv annoque mmvi 06 vi 2006}
+test clock-2.1592 {conversion of 2006-04-30} {
+    clock format 1146400496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/30/2006 12:34:56 die xxx mensis iv annoque mmvi xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 120 2453856 04 iv  4 04/30/2006 die xxx mensis iv annoque mmvi 06 vi 2006}
+test clock-2.1593 {conversion of 2006-05-01} {
+    clock format 1146486896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/01/2006 12:34:56 die i mensis v annoque mmvi xii h xxxiv m lvi s 20 mm 01 i  1 i May 121 2453857 05 v  5 05/01/2006 die i mensis v annoque mmvi 06 vi 2006}
+test clock-2.1594 {conversion of 2006-05-31} {
+    clock format 1149078896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/31/2006 12:34:56 die xxxi mensis v annoque mmvi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 151 2453887 05 v  5 05/31/2006 die xxxi mensis v annoque mmvi 06 vi 2006}
+test clock-2.1595 {conversion of 2006-06-01} {
+    clock format 1149165296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/01/2006 12:34:56 die i mensis vi annoque mmvi xii h xxxiv m lvi s 20 mm 01 i  1 i Jun 152 2453888 06 vi  6 06/01/2006 die i mensis vi annoque mmvi 06 vi 2006}
+test clock-2.1596 {conversion of 2006-06-30} {
+    clock format 1151670896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/30/2006 12:34:56 die xxx mensis vi annoque mmvi xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 181 2453917 06 vi  6 06/30/2006 die xxx mensis vi annoque mmvi 06 vi 2006}
+test clock-2.1597 {conversion of 2006-07-01} {
+    clock format 1151757296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/01/2006 12:34:56 die i mensis vii annoque mmvi xii h xxxiv m lvi s 20 mm 01 i  1 i Jul 182 2453918 07 vii  7 07/01/2006 die i mensis vii annoque mmvi 06 vi 2006}
+test clock-2.1598 {conversion of 2006-07-31} {
+    clock format 1154349296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/31/2006 12:34:56 die xxxi mensis vii annoque mmvi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 212 2453948 07 vii  7 07/31/2006 die xxxi mensis vii annoque mmvi 06 vi 2006}
+test clock-2.1599 {conversion of 2006-08-01} {
+    clock format 1154435696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/01/2006 12:34:56 die i mensis viii annoque mmvi xii h xxxiv m lvi s 20 mm 01 i  1 i Aug 213 2453949 08 viii  8 08/01/2006 die i mensis viii annoque mmvi 06 vi 2006}
+test clock-2.1600 {conversion of 2006-08-31} {
+    clock format 1157027696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/31/2006 12:34:56 die xxxi mensis viii annoque mmvi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 243 2453979 08 viii  8 08/31/2006 die xxxi mensis viii annoque mmvi 06 vi 2006}
+test clock-2.1601 {conversion of 2006-09-01} {
+    clock format 1157114096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/01/2006 12:34:56 die i mensis ix annoque mmvi xii h xxxiv m lvi s 20 mm 01 i  1 i Sep 244 2453980 09 ix  9 09/01/2006 die i mensis ix annoque mmvi 06 vi 2006}
+test clock-2.1602 {conversion of 2006-09-30} {
+    clock format 1159619696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/30/2006 12:34:56 die xxx mensis ix annoque mmvi xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 273 2454009 09 ix  9 09/30/2006 die xxx mensis ix annoque mmvi 06 vi 2006}
+test clock-2.1603 {conversion of 2006-10-01} {
+    clock format 1159706096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/01/2006 12:34:56 die i mensis x annoque mmvi xii h xxxiv m lvi s 20 mm 01 i  1 i Oct 274 2454010 10 x 10 10/01/2006 die i mensis x annoque mmvi 06 vi 2006}
+test clock-2.1604 {conversion of 2006-10-31} {
+    clock format 1162298096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/31/2006 12:34:56 die xxxi mensis x annoque mmvi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 304 2454040 10 x 10 10/31/2006 die xxxi mensis x annoque mmvi 06 vi 2006}
+test clock-2.1605 {conversion of 2006-11-01} {
+    clock format 1162384496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/01/2006 12:34:56 die i mensis xi annoque mmvi xii h xxxiv m lvi s 20 mm 01 i  1 i Nov 305 2454041 11 xi 11 11/01/2006 die i mensis xi annoque mmvi 06 vi 2006}
+test clock-2.1606 {conversion of 2006-11-30} {
+    clock format 1164890096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/30/2006 12:34:56 die xxx mensis xi annoque mmvi xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 334 2454070 11 xi 11 11/30/2006 die xxx mensis xi annoque mmvi 06 vi 2006}
+test clock-2.1607 {conversion of 2006-12-01} {
+    clock format 1164976496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/01/2006 12:34:56 die i mensis xii annoque mmvi xii h xxxiv m lvi s 20 mm 01 i  1 i Dec 335 2454071 12 xii 12 12/01/2006 die i mensis xii annoque mmvi 06 vi 2006}
+test clock-2.1608 {conversion of 2006-12-31} {
+    clock format 1167568496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/31/2006 12:34:56 die xxxi mensis xii annoque mmvi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 365 2454101 12 xii 12 12/31/2006 die xxxi mensis xii annoque mmvi 06 vi 2006}
+test clock-2.1609 {conversion of 2007-01-01} {
+    clock format 1167654896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/01/2007 12:34:56 die i mensis i annoque mmvii xii h xxxiv m lvi s 20 mm 01 i  1 i Jan 001 2454102 01 i  1 01/01/2007 die i mensis i annoque mmvii 07 vii 2007}
+test clock-2.1610 {conversion of 2007-01-31} {
+    clock format 1170246896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/31/2007 12:34:56 die xxxi mensis i annoque mmvii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2454132 01 i  1 01/31/2007 die xxxi mensis i annoque mmvii 07 vii 2007}
+test clock-2.1611 {conversion of 2007-02-01} {
+    clock format 1170333296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/01/2007 12:34:56 die i mensis ii annoque mmvii xii h xxxiv m lvi s 20 mm 01 i  1 i Feb 032 2454133 02 ii  2 02/01/2007 die i mensis ii annoque mmvii 07 vii 2007}
+test clock-2.1612 {conversion of 2007-02-28} {
+    clock format 1172666096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/28/2007 12:34:56 die xxviii mensis ii annoque mmvii xii h xxxiv m lvi s 20 mm 28 xxviii 28 xxviii Feb 059 2454160 02 ii  2 02/28/2007 die xxviii mensis ii annoque mmvii 07 vii 2007}
+test clock-2.1613 {conversion of 2007-03-01} {
+    clock format 1172752496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/01/2007 12:34:56 die i mensis iii annoque mmvii xii h xxxiv m lvi s 20 mm 01 i  1 i Mar 060 2454161 03 iii  3 03/01/2007 die i mensis iii annoque mmvii 07 vii 2007}
+test clock-2.1614 {conversion of 2007-03-31} {
+    clock format 1175344496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/31/2007 12:34:56 die xxxi mensis iii annoque mmvii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 090 2454191 03 iii  3 03/31/2007 die xxxi mensis iii annoque mmvii 07 vii 2007}
+test clock-2.1615 {conversion of 2007-04-01} {
+    clock format 1175430896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/01/2007 12:34:56 die i mensis iv annoque mmvii xii h xxxiv m lvi s 20 mm 01 i  1 i Apr 091 2454192 04 iv  4 04/01/2007 die i mensis iv annoque mmvii 07 vii 2007}
+test clock-2.1616 {conversion of 2007-04-30} {
+    clock format 1177936496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/30/2007 12:34:56 die xxx mensis iv annoque mmvii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 120 2454221 04 iv  4 04/30/2007 die xxx mensis iv annoque mmvii 07 vii 2007}
+test clock-2.1617 {conversion of 2007-05-01} {
+    clock format 1178022896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/01/2007 12:34:56 die i mensis v annoque mmvii xii h xxxiv m lvi s 20 mm 01 i  1 i May 121 2454222 05 v  5 05/01/2007 die i mensis v annoque mmvii 07 vii 2007}
+test clock-2.1618 {conversion of 2007-05-31} {
+    clock format 1180614896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/31/2007 12:34:56 die xxxi mensis v annoque mmvii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 151 2454252 05 v  5 05/31/2007 die xxxi mensis v annoque mmvii 07 vii 2007}
+test clock-2.1619 {conversion of 2007-06-01} {
+    clock format 1180701296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/01/2007 12:34:56 die i mensis vi annoque mmvii xii h xxxiv m lvi s 20 mm 01 i  1 i Jun 152 2454253 06 vi  6 06/01/2007 die i mensis vi annoque mmvii 07 vii 2007}
+test clock-2.1620 {conversion of 2007-06-30} {
+    clock format 1183206896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/30/2007 12:34:56 die xxx mensis vi annoque mmvii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 181 2454282 06 vi  6 06/30/2007 die xxx mensis vi annoque mmvii 07 vii 2007}
+test clock-2.1621 {conversion of 2007-07-01} {
+    clock format 1183293296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/01/2007 12:34:56 die i mensis vii annoque mmvii xii h xxxiv m lvi s 20 mm 01 i  1 i Jul 182 2454283 07 vii  7 07/01/2007 die i mensis vii annoque mmvii 07 vii 2007}
+test clock-2.1622 {conversion of 2007-07-31} {
+    clock format 1185885296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/31/2007 12:34:56 die xxxi mensis vii annoque mmvii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 212 2454313 07 vii  7 07/31/2007 die xxxi mensis vii annoque mmvii 07 vii 2007}
+test clock-2.1623 {conversion of 2007-08-01} {
+    clock format 1185971696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/01/2007 12:34:56 die i mensis viii annoque mmvii xii h xxxiv m lvi s 20 mm 01 i  1 i Aug 213 2454314 08 viii  8 08/01/2007 die i mensis viii annoque mmvii 07 vii 2007}
+test clock-2.1624 {conversion of 2007-08-31} {
+    clock format 1188563696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/31/2007 12:34:56 die xxxi mensis viii annoque mmvii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 243 2454344 08 viii  8 08/31/2007 die xxxi mensis viii annoque mmvii 07 vii 2007}
+test clock-2.1625 {conversion of 2007-09-01} {
+    clock format 1188650096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/01/2007 12:34:56 die i mensis ix annoque mmvii xii h xxxiv m lvi s 20 mm 01 i  1 i Sep 244 2454345 09 ix  9 09/01/2007 die i mensis ix annoque mmvii 07 vii 2007}
+test clock-2.1626 {conversion of 2007-09-30} {
+    clock format 1191155696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/30/2007 12:34:56 die xxx mensis ix annoque mmvii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 273 2454374 09 ix  9 09/30/2007 die xxx mensis ix annoque mmvii 07 vii 2007}
+test clock-2.1627 {conversion of 2007-10-01} {
+    clock format 1191242096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/01/2007 12:34:56 die i mensis x annoque mmvii xii h xxxiv m lvi s 20 mm 01 i  1 i Oct 274 2454375 10 x 10 10/01/2007 die i mensis x annoque mmvii 07 vii 2007}
+test clock-2.1628 {conversion of 2007-10-31} {
+    clock format 1193834096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/31/2007 12:34:56 die xxxi mensis x annoque mmvii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 304 2454405 10 x 10 10/31/2007 die xxxi mensis x annoque mmvii 07 vii 2007}
+test clock-2.1629 {conversion of 2007-11-01} {
+    clock format 1193920496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/01/2007 12:34:56 die i mensis xi annoque mmvii xii h xxxiv m lvi s 20 mm 01 i  1 i Nov 305 2454406 11 xi 11 11/01/2007 die i mensis xi annoque mmvii 07 vii 2007}
+test clock-2.1630 {conversion of 2007-11-30} {
+    clock format 1196426096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/30/2007 12:34:56 die xxx mensis xi annoque mmvii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 334 2454435 11 xi 11 11/30/2007 die xxx mensis xi annoque mmvii 07 vii 2007}
+test clock-2.1631 {conversion of 2007-12-01} {
+    clock format 1196512496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/01/2007 12:34:56 die i mensis xii annoque mmvii xii h xxxiv m lvi s 20 mm 01 i  1 i Dec 335 2454436 12 xii 12 12/01/2007 die i mensis xii annoque mmvii 07 vii 2007}
+test clock-2.1632 {conversion of 2007-12-31} {
+    clock format 1199104496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/31/2007 12:34:56 die xxxi mensis xii annoque mmvii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 365 2454466 12 xii 12 12/31/2007 die xxxi mensis xii annoque mmvii 07 vii 2007}
+test clock-2.1633 {conversion of 2008-01-01} {
+    clock format 1199190896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/01/2008 12:34:56 die i mensis i annoque mmviii xii h xxxiv m lvi s 20 mm 01 i  1 i Jan 001 2454467 01 i  1 01/01/2008 die i mensis i annoque mmviii 08 viii 2008}
+test clock-2.1634 {conversion of 2008-01-31} {
+    clock format 1201782896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/31/2008 12:34:56 die xxxi mensis i annoque mmviii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2454497 01 i  1 01/31/2008 die xxxi mensis i annoque mmviii 08 viii 2008}
+test clock-2.1635 {conversion of 2008-02-01} {
+    clock format 1201869296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/01/2008 12:34:56 die i mensis ii annoque mmviii xii h xxxiv m lvi s 20 mm 01 i  1 i Feb 032 2454498 02 ii  2 02/01/2008 die i mensis ii annoque mmviii 08 viii 2008}
+test clock-2.1636 {conversion of 2008-02-29} {
+    clock format 1204288496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/29/2008 12:34:56 die xxix mensis ii annoque mmviii xii h xxxiv m lvi s 20 mm 29 xxix 29 xxix Feb 060 2454526 02 ii  2 02/29/2008 die xxix mensis ii annoque mmviii 08 viii 2008}
+test clock-2.1637 {conversion of 2008-03-01} {
+    clock format 1204374896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/01/2008 12:34:56 die i mensis iii annoque mmviii xii h xxxiv m lvi s 20 mm 01 i  1 i Mar 061 2454527 03 iii  3 03/01/2008 die i mensis iii annoque mmviii 08 viii 2008}
+test clock-2.1638 {conversion of 2008-03-31} {
+    clock format 1206966896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/31/2008 12:34:56 die xxxi mensis iii annoque mmviii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 091 2454557 03 iii  3 03/31/2008 die xxxi mensis iii annoque mmviii 08 viii 2008}
+test clock-2.1639 {conversion of 2008-04-01} {
+    clock format 1207053296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/01/2008 12:34:56 die i mensis iv annoque mmviii xii h xxxiv m lvi s 20 mm 01 i  1 i Apr 092 2454558 04 iv  4 04/01/2008 die i mensis iv annoque mmviii 08 viii 2008}
+test clock-2.1640 {conversion of 2008-04-30} {
+    clock format 1209558896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/30/2008 12:34:56 die xxx mensis iv annoque mmviii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 121 2454587 04 iv  4 04/30/2008 die xxx mensis iv annoque mmviii 08 viii 2008}
+test clock-2.1641 {conversion of 2008-05-01} {
+    clock format 1209645296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/01/2008 12:34:56 die i mensis v annoque mmviii xii h xxxiv m lvi s 20 mm 01 i  1 i May 122 2454588 05 v  5 05/01/2008 die i mensis v annoque mmviii 08 viii 2008}
+test clock-2.1642 {conversion of 2008-05-31} {
+    clock format 1212237296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/31/2008 12:34:56 die xxxi mensis v annoque mmviii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 152 2454618 05 v  5 05/31/2008 die xxxi mensis v annoque mmviii 08 viii 2008}
+test clock-2.1643 {conversion of 2008-06-01} {
+    clock format 1212323696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/01/2008 12:34:56 die i mensis vi annoque mmviii xii h xxxiv m lvi s 20 mm 01 i  1 i Jun 153 2454619 06 vi  6 06/01/2008 die i mensis vi annoque mmviii 08 viii 2008}
+test clock-2.1644 {conversion of 2008-06-30} {
+    clock format 1214829296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/30/2008 12:34:56 die xxx mensis vi annoque mmviii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 182 2454648 06 vi  6 06/30/2008 die xxx mensis vi annoque mmviii 08 viii 2008}
+test clock-2.1645 {conversion of 2008-07-01} {
+    clock format 1214915696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/01/2008 12:34:56 die i mensis vii annoque mmviii xii h xxxiv m lvi s 20 mm 01 i  1 i Jul 183 2454649 07 vii  7 07/01/2008 die i mensis vii annoque mmviii 08 viii 2008}
+test clock-2.1646 {conversion of 2008-07-31} {
+    clock format 1217507696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/31/2008 12:34:56 die xxxi mensis vii annoque mmviii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 213 2454679 07 vii  7 07/31/2008 die xxxi mensis vii annoque mmviii 08 viii 2008}
+test clock-2.1647 {conversion of 2008-08-01} {
+    clock format 1217594096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/01/2008 12:34:56 die i mensis viii annoque mmviii xii h xxxiv m lvi s 20 mm 01 i  1 i Aug 214 2454680 08 viii  8 08/01/2008 die i mensis viii annoque mmviii 08 viii 2008}
+test clock-2.1648 {conversion of 2008-08-31} {
+    clock format 1220186096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/31/2008 12:34:56 die xxxi mensis viii annoque mmviii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 244 2454710 08 viii  8 08/31/2008 die xxxi mensis viii annoque mmviii 08 viii 2008}
+test clock-2.1649 {conversion of 2008-09-01} {
+    clock format 1220272496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/01/2008 12:34:56 die i mensis ix annoque mmviii xii h xxxiv m lvi s 20 mm 01 i  1 i Sep 245 2454711 09 ix  9 09/01/2008 die i mensis ix annoque mmviii 08 viii 2008}
+test clock-2.1650 {conversion of 2008-09-30} {
+    clock format 1222778096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/30/2008 12:34:56 die xxx mensis ix annoque mmviii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 274 2454740 09 ix  9 09/30/2008 die xxx mensis ix annoque mmviii 08 viii 2008}
+test clock-2.1651 {conversion of 2008-10-01} {
+    clock format 1222864496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/01/2008 12:34:56 die i mensis x annoque mmviii xii h xxxiv m lvi s 20 mm 01 i  1 i Oct 275 2454741 10 x 10 10/01/2008 die i mensis x annoque mmviii 08 viii 2008}
+test clock-2.1652 {conversion of 2008-10-31} {
+    clock format 1225456496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/31/2008 12:34:56 die xxxi mensis x annoque mmviii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 305 2454771 10 x 10 10/31/2008 die xxxi mensis x annoque mmviii 08 viii 2008}
+test clock-2.1653 {conversion of 2008-11-01} {
+    clock format 1225542896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/01/2008 12:34:56 die i mensis xi annoque mmviii xii h xxxiv m lvi s 20 mm 01 i  1 i Nov 306 2454772 11 xi 11 11/01/2008 die i mensis xi annoque mmviii 08 viii 2008}
+test clock-2.1654 {conversion of 2008-11-30} {
+    clock format 1228048496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/30/2008 12:34:56 die xxx mensis xi annoque mmviii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 335 2454801 11 xi 11 11/30/2008 die xxx mensis xi annoque mmviii 08 viii 2008}
+test clock-2.1655 {conversion of 2008-12-01} {
+    clock format 1228134896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/01/2008 12:34:56 die i mensis xii annoque mmviii xii h xxxiv m lvi s 20 mm 01 i  1 i Dec 336 2454802 12 xii 12 12/01/2008 die i mensis xii annoque mmviii 08 viii 2008}
+test clock-2.1656 {conversion of 2008-12-31} {
+    clock format 1230726896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/31/2008 12:34:56 die xxxi mensis xii annoque mmviii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 366 2454832 12 xii 12 12/31/2008 die xxxi mensis xii annoque mmviii 08 viii 2008}
+test clock-2.1657 {conversion of 2009-01-01} {
+    clock format 1230813296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/01/2009 12:34:56 die i mensis i annoque mmix xii h xxxiv m lvi s 20 mm 01 i  1 i Jan 001 2454833 01 i  1 01/01/2009 die i mensis i annoque mmix 09 ix 2009}
+test clock-2.1658 {conversion of 2009-01-31} {
+    clock format 1233405296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/31/2009 12:34:56 die xxxi mensis i annoque mmix xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2454863 01 i  1 01/31/2009 die xxxi mensis i annoque mmix 09 ix 2009}
+test clock-2.1659 {conversion of 2009-02-01} {
+    clock format 1233491696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/01/2009 12:34:56 die i mensis ii annoque mmix xii h xxxiv m lvi s 20 mm 01 i  1 i Feb 032 2454864 02 ii  2 02/01/2009 die i mensis ii annoque mmix 09 ix 2009}
+test clock-2.1660 {conversion of 2009-02-28} {
+    clock format 1235824496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/28/2009 12:34:56 die xxviii mensis ii annoque mmix xii h xxxiv m lvi s 20 mm 28 xxviii 28 xxviii Feb 059 2454891 02 ii  2 02/28/2009 die xxviii mensis ii annoque mmix 09 ix 2009}
+test clock-2.1661 {conversion of 2009-03-01} {
+    clock format 1235910896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/01/2009 12:34:56 die i mensis iii annoque mmix xii h xxxiv m lvi s 20 mm 01 i  1 i Mar 060 2454892 03 iii  3 03/01/2009 die i mensis iii annoque mmix 09 ix 2009}
+test clock-2.1662 {conversion of 2009-03-31} {
+    clock format 1238502896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/31/2009 12:34:56 die xxxi mensis iii annoque mmix xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 090 2454922 03 iii  3 03/31/2009 die xxxi mensis iii annoque mmix 09 ix 2009}
+test clock-2.1663 {conversion of 2009-04-01} {
+    clock format 1238589296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/01/2009 12:34:56 die i mensis iv annoque mmix xii h xxxiv m lvi s 20 mm 01 i  1 i Apr 091 2454923 04 iv  4 04/01/2009 die i mensis iv annoque mmix 09 ix 2009}
+test clock-2.1664 {conversion of 2009-04-30} {
+    clock format 1241094896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/30/2009 12:34:56 die xxx mensis iv annoque mmix xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 120 2454952 04 iv  4 04/30/2009 die xxx mensis iv annoque mmix 09 ix 2009}
+test clock-2.1665 {conversion of 2009-05-01} {
+    clock format 1241181296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/01/2009 12:34:56 die i mensis v annoque mmix xii h xxxiv m lvi s 20 mm 01 i  1 i May 121 2454953 05 v  5 05/01/2009 die i mensis v annoque mmix 09 ix 2009}
+test clock-2.1666 {conversion of 2009-05-31} {
+    clock format 1243773296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/31/2009 12:34:56 die xxxi mensis v annoque mmix xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 151 2454983 05 v  5 05/31/2009 die xxxi mensis v annoque mmix 09 ix 2009}
+test clock-2.1667 {conversion of 2009-06-01} {
+    clock format 1243859696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/01/2009 12:34:56 die i mensis vi annoque mmix xii h xxxiv m lvi s 20 mm 01 i  1 i Jun 152 2454984 06 vi  6 06/01/2009 die i mensis vi annoque mmix 09 ix 2009}
+test clock-2.1668 {conversion of 2009-06-30} {
+    clock format 1246365296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/30/2009 12:34:56 die xxx mensis vi annoque mmix xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 181 2455013 06 vi  6 06/30/2009 die xxx mensis vi annoque mmix 09 ix 2009}
+test clock-2.1669 {conversion of 2009-07-01} {
+    clock format 1246451696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/01/2009 12:34:56 die i mensis vii annoque mmix xii h xxxiv m lvi s 20 mm 01 i  1 i Jul 182 2455014 07 vii  7 07/01/2009 die i mensis vii annoque mmix 09 ix 2009}
+test clock-2.1670 {conversion of 2009-07-31} {
+    clock format 1249043696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/31/2009 12:34:56 die xxxi mensis vii annoque mmix xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 212 2455044 07 vii  7 07/31/2009 die xxxi mensis vii annoque mmix 09 ix 2009}
+test clock-2.1671 {conversion of 2009-08-01} {
+    clock format 1249130096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/01/2009 12:34:56 die i mensis viii annoque mmix xii h xxxiv m lvi s 20 mm 01 i  1 i Aug 213 2455045 08 viii  8 08/01/2009 die i mensis viii annoque mmix 09 ix 2009}
+test clock-2.1672 {conversion of 2009-08-31} {
+    clock format 1251722096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/31/2009 12:34:56 die xxxi mensis viii annoque mmix xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 243 2455075 08 viii  8 08/31/2009 die xxxi mensis viii annoque mmix 09 ix 2009}
+test clock-2.1673 {conversion of 2009-09-01} {
+    clock format 1251808496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/01/2009 12:34:56 die i mensis ix annoque mmix xii h xxxiv m lvi s 20 mm 01 i  1 i Sep 244 2455076 09 ix  9 09/01/2009 die i mensis ix annoque mmix 09 ix 2009}
+test clock-2.1674 {conversion of 2009-09-30} {
+    clock format 1254314096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/30/2009 12:34:56 die xxx mensis ix annoque mmix xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 273 2455105 09 ix  9 09/30/2009 die xxx mensis ix annoque mmix 09 ix 2009}
+test clock-2.1675 {conversion of 2009-10-01} {
+    clock format 1254400496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/01/2009 12:34:56 die i mensis x annoque mmix xii h xxxiv m lvi s 20 mm 01 i  1 i Oct 274 2455106 10 x 10 10/01/2009 die i mensis x annoque mmix 09 ix 2009}
+test clock-2.1676 {conversion of 2009-10-31} {
+    clock format 1256992496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/31/2009 12:34:56 die xxxi mensis x annoque mmix xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 304 2455136 10 x 10 10/31/2009 die xxxi mensis x annoque mmix 09 ix 2009}
+test clock-2.1677 {conversion of 2009-11-01} {
+    clock format 1257078896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/01/2009 12:34:56 die i mensis xi annoque mmix xii h xxxiv m lvi s 20 mm 01 i  1 i Nov 305 2455137 11 xi 11 11/01/2009 die i mensis xi annoque mmix 09 ix 2009}
+test clock-2.1678 {conversion of 2009-11-30} {
+    clock format 1259584496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/30/2009 12:34:56 die xxx mensis xi annoque mmix xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 334 2455166 11 xi 11 11/30/2009 die xxx mensis xi annoque mmix 09 ix 2009}
+test clock-2.1679 {conversion of 2009-12-01} {
+    clock format 1259670896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/01/2009 12:34:56 die i mensis xii annoque mmix xii h xxxiv m lvi s 20 mm 01 i  1 i Dec 335 2455167 12 xii 12 12/01/2009 die i mensis xii annoque mmix 09 ix 2009}
+test clock-2.1680 {conversion of 2009-12-31} {
+    clock format 1262262896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/31/2009 12:34:56 die xxxi mensis xii annoque mmix xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 365 2455197 12 xii 12 12/31/2009 die xxxi mensis xii annoque mmix 09 ix 2009}
+test clock-2.1681 {conversion of 2010-01-01} {
+    clock format 1262349296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/01/2010 12:34:56 die i mensis i annoque mmx xii h xxxiv m lvi s 20 mm 01 i  1 i Jan 001 2455198 01 i  1 01/01/2010 die i mensis i annoque mmx 10 x 2010}
+test clock-2.1682 {conversion of 2010-01-31} {
+    clock format 1264941296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/31/2010 12:34:56 die xxxi mensis i annoque mmx xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2455228 01 i  1 01/31/2010 die xxxi mensis i annoque mmx 10 x 2010}
+test clock-2.1683 {conversion of 2010-02-01} {
+    clock format 1265027696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/01/2010 12:34:56 die i mensis ii annoque mmx xii h xxxiv m lvi s 20 mm 01 i  1 i Feb 032 2455229 02 ii  2 02/01/2010 die i mensis ii annoque mmx 10 x 2010}
+test clock-2.1684 {conversion of 2010-02-28} {
+    clock format 1267360496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/28/2010 12:34:56 die xxviii mensis ii annoque mmx xii h xxxiv m lvi s 20 mm 28 xxviii 28 xxviii Feb 059 2455256 02 ii  2 02/28/2010 die xxviii mensis ii annoque mmx 10 x 2010}
+test clock-2.1685 {conversion of 2010-03-01} {
+    clock format 1267446896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/01/2010 12:34:56 die i mensis iii annoque mmx xii h xxxiv m lvi s 20 mm 01 i  1 i Mar 060 2455257 03 iii  3 03/01/2010 die i mensis iii annoque mmx 10 x 2010}
+test clock-2.1686 {conversion of 2010-03-31} {
+    clock format 1270038896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/31/2010 12:34:56 die xxxi mensis iii annoque mmx xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 090 2455287 03 iii  3 03/31/2010 die xxxi mensis iii annoque mmx 10 x 2010}
+test clock-2.1687 {conversion of 2010-04-01} {
+    clock format 1270125296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/01/2010 12:34:56 die i mensis iv annoque mmx xii h xxxiv m lvi s 20 mm 01 i  1 i Apr 091 2455288 04 iv  4 04/01/2010 die i mensis iv annoque mmx 10 x 2010}
+test clock-2.1688 {conversion of 2010-04-30} {
+    clock format 1272630896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/30/2010 12:34:56 die xxx mensis iv annoque mmx xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 120 2455317 04 iv  4 04/30/2010 die xxx mensis iv annoque mmx 10 x 2010}
+test clock-2.1689 {conversion of 2010-05-01} {
+    clock format 1272717296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/01/2010 12:34:56 die i mensis v annoque mmx xii h xxxiv m lvi s 20 mm 01 i  1 i May 121 2455318 05 v  5 05/01/2010 die i mensis v annoque mmx 10 x 2010}
+test clock-2.1690 {conversion of 2010-05-31} {
+    clock format 1275309296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/31/2010 12:34:56 die xxxi mensis v annoque mmx xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 151 2455348 05 v  5 05/31/2010 die xxxi mensis v annoque mmx 10 x 2010}
+test clock-2.1691 {conversion of 2010-06-01} {
+    clock format 1275395696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/01/2010 12:34:56 die i mensis vi annoque mmx xii h xxxiv m lvi s 20 mm 01 i  1 i Jun 152 2455349 06 vi  6 06/01/2010 die i mensis vi annoque mmx 10 x 2010}
+test clock-2.1692 {conversion of 2010-06-30} {
+    clock format 1277901296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/30/2010 12:34:56 die xxx mensis vi annoque mmx xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 181 2455378 06 vi  6 06/30/2010 die xxx mensis vi annoque mmx 10 x 2010}
+test clock-2.1693 {conversion of 2010-07-01} {
+    clock format 1277987696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/01/2010 12:34:56 die i mensis vii annoque mmx xii h xxxiv m lvi s 20 mm 01 i  1 i Jul 182 2455379 07 vii  7 07/01/2010 die i mensis vii annoque mmx 10 x 2010}
+test clock-2.1694 {conversion of 2010-07-31} {
+    clock format 1280579696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/31/2010 12:34:56 die xxxi mensis vii annoque mmx xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 212 2455409 07 vii  7 07/31/2010 die xxxi mensis vii annoque mmx 10 x 2010}
+test clock-2.1695 {conversion of 2010-08-01} {
+    clock format 1280666096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/01/2010 12:34:56 die i mensis viii annoque mmx xii h xxxiv m lvi s 20 mm 01 i  1 i Aug 213 2455410 08 viii  8 08/01/2010 die i mensis viii annoque mmx 10 x 2010}
+test clock-2.1696 {conversion of 2010-08-31} {
+    clock format 1283258096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/31/2010 12:34:56 die xxxi mensis viii annoque mmx xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 243 2455440 08 viii  8 08/31/2010 die xxxi mensis viii annoque mmx 10 x 2010}
+test clock-2.1697 {conversion of 2010-09-01} {
+    clock format 1283344496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/01/2010 12:34:56 die i mensis ix annoque mmx xii h xxxiv m lvi s 20 mm 01 i  1 i Sep 244 2455441 09 ix  9 09/01/2010 die i mensis ix annoque mmx 10 x 2010}
+test clock-2.1698 {conversion of 2010-09-30} {
+    clock format 1285850096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/30/2010 12:34:56 die xxx mensis ix annoque mmx xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 273 2455470 09 ix  9 09/30/2010 die xxx mensis ix annoque mmx 10 x 2010}
+test clock-2.1699 {conversion of 2010-10-01} {
+    clock format 1285936496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/01/2010 12:34:56 die i mensis x annoque mmx xii h xxxiv m lvi s 20 mm 01 i  1 i Oct 274 2455471 10 x 10 10/01/2010 die i mensis x annoque mmx 10 x 2010}
+test clock-2.1700 {conversion of 2010-10-31} {
+    clock format 1288528496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/31/2010 12:34:56 die xxxi mensis x annoque mmx xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 304 2455501 10 x 10 10/31/2010 die xxxi mensis x annoque mmx 10 x 2010}
+test clock-2.1701 {conversion of 2010-11-01} {
+    clock format 1288614896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/01/2010 12:34:56 die i mensis xi annoque mmx xii h xxxiv m lvi s 20 mm 01 i  1 i Nov 305 2455502 11 xi 11 11/01/2010 die i mensis xi annoque mmx 10 x 2010}
+test clock-2.1702 {conversion of 2010-11-30} {
+    clock format 1291120496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/30/2010 12:34:56 die xxx mensis xi annoque mmx xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 334 2455531 11 xi 11 11/30/2010 die xxx mensis xi annoque mmx 10 x 2010}
+test clock-2.1703 {conversion of 2010-12-01} {
+    clock format 1291206896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/01/2010 12:34:56 die i mensis xii annoque mmx xii h xxxiv m lvi s 20 mm 01 i  1 i Dec 335 2455532 12 xii 12 12/01/2010 die i mensis xii annoque mmx 10 x 2010}
+test clock-2.1704 {conversion of 2010-12-31} {
+    clock format 1293798896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/31/2010 12:34:56 die xxxi mensis xii annoque mmx xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 365 2455562 12 xii 12 12/31/2010 die xxxi mensis xii annoque mmx 10 x 2010}
+test clock-2.1705 {conversion of 2011-01-01} {
+    clock format 1293885296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/01/2011 12:34:56 die i mensis i annoque mmxi xii h xxxiv m lvi s 20 mm 01 i  1 i Jan 001 2455563 01 i  1 01/01/2011 die i mensis i annoque mmxi 11 xi 2011}
+test clock-2.1706 {conversion of 2011-01-31} {
+    clock format 1296477296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/31/2011 12:34:56 die xxxi mensis i annoque mmxi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2455593 01 i  1 01/31/2011 die xxxi mensis i annoque mmxi 11 xi 2011}
+test clock-2.1707 {conversion of 2011-02-01} {
+    clock format 1296563696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/01/2011 12:34:56 die i mensis ii annoque mmxi xii h xxxiv m lvi s 20 mm 01 i  1 i Feb 032 2455594 02 ii  2 02/01/2011 die i mensis ii annoque mmxi 11 xi 2011}
+test clock-2.1708 {conversion of 2011-02-28} {
+    clock format 1298896496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/28/2011 12:34:56 die xxviii mensis ii annoque mmxi xii h xxxiv m lvi s 20 mm 28 xxviii 28 xxviii Feb 059 2455621 02 ii  2 02/28/2011 die xxviii mensis ii annoque mmxi 11 xi 2011}
+test clock-2.1709 {conversion of 2011-03-01} {
+    clock format 1298982896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/01/2011 12:34:56 die i mensis iii annoque mmxi xii h xxxiv m lvi s 20 mm 01 i  1 i Mar 060 2455622 03 iii  3 03/01/2011 die i mensis iii annoque mmxi 11 xi 2011}
+test clock-2.1710 {conversion of 2011-03-31} {
+    clock format 1301574896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/31/2011 12:34:56 die xxxi mensis iii annoque mmxi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 090 2455652 03 iii  3 03/31/2011 die xxxi mensis iii annoque mmxi 11 xi 2011}
+test clock-2.1711 {conversion of 2011-04-01} {
+    clock format 1301661296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/01/2011 12:34:56 die i mensis iv annoque mmxi xii h xxxiv m lvi s 20 mm 01 i  1 i Apr 091 2455653 04 iv  4 04/01/2011 die i mensis iv annoque mmxi 11 xi 2011}
+test clock-2.1712 {conversion of 2011-04-30} {
+    clock format 1304166896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/30/2011 12:34:56 die xxx mensis iv annoque mmxi xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 120 2455682 04 iv  4 04/30/2011 die xxx mensis iv annoque mmxi 11 xi 2011}
+test clock-2.1713 {conversion of 2011-05-01} {
+    clock format 1304253296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/01/2011 12:34:56 die i mensis v annoque mmxi xii h xxxiv m lvi s 20 mm 01 i  1 i May 121 2455683 05 v  5 05/01/2011 die i mensis v annoque mmxi 11 xi 2011}
+test clock-2.1714 {conversion of 2011-05-31} {
+    clock format 1306845296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/31/2011 12:34:56 die xxxi mensis v annoque mmxi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 151 2455713 05 v  5 05/31/2011 die xxxi mensis v annoque mmxi 11 xi 2011}
+test clock-2.1715 {conversion of 2011-06-01} {
+    clock format 1306931696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/01/2011 12:34:56 die i mensis vi annoque mmxi xii h xxxiv m lvi s 20 mm 01 i  1 i Jun 152 2455714 06 vi  6 06/01/2011 die i mensis vi annoque mmxi 11 xi 2011}
+test clock-2.1716 {conversion of 2011-06-30} {
+    clock format 1309437296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/30/2011 12:34:56 die xxx mensis vi annoque mmxi xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 181 2455743 06 vi  6 06/30/2011 die xxx mensis vi annoque mmxi 11 xi 2011}
+test clock-2.1717 {conversion of 2011-07-01} {
+    clock format 1309523696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/01/2011 12:34:56 die i mensis vii annoque mmxi xii h xxxiv m lvi s 20 mm 01 i  1 i Jul 182 2455744 07 vii  7 07/01/2011 die i mensis vii annoque mmxi 11 xi 2011}
+test clock-2.1718 {conversion of 2011-07-31} {
+    clock format 1312115696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/31/2011 12:34:56 die xxxi mensis vii annoque mmxi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 212 2455774 07 vii  7 07/31/2011 die xxxi mensis vii annoque mmxi 11 xi 2011}
+test clock-2.1719 {conversion of 2011-08-01} {
+    clock format 1312202096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/01/2011 12:34:56 die i mensis viii annoque mmxi xii h xxxiv m lvi s 20 mm 01 i  1 i Aug 213 2455775 08 viii  8 08/01/2011 die i mensis viii annoque mmxi 11 xi 2011}
+test clock-2.1720 {conversion of 2011-08-31} {
+    clock format 1314794096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/31/2011 12:34:56 die xxxi mensis viii annoque mmxi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 243 2455805 08 viii  8 08/31/2011 die xxxi mensis viii annoque mmxi 11 xi 2011}
+test clock-2.1721 {conversion of 2011-09-01} {
+    clock format 1314880496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/01/2011 12:34:56 die i mensis ix annoque mmxi xii h xxxiv m lvi s 20 mm 01 i  1 i Sep 244 2455806 09 ix  9 09/01/2011 die i mensis ix annoque mmxi 11 xi 2011}
+test clock-2.1722 {conversion of 2011-09-30} {
+    clock format 1317386096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/30/2011 12:34:56 die xxx mensis ix annoque mmxi xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 273 2455835 09 ix  9 09/30/2011 die xxx mensis ix annoque mmxi 11 xi 2011}
+test clock-2.1723 {conversion of 2011-10-01} {
+    clock format 1317472496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/01/2011 12:34:56 die i mensis x annoque mmxi xii h xxxiv m lvi s 20 mm 01 i  1 i Oct 274 2455836 10 x 10 10/01/2011 die i mensis x annoque mmxi 11 xi 2011}
+test clock-2.1724 {conversion of 2011-10-31} {
+    clock format 1320064496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/31/2011 12:34:56 die xxxi mensis x annoque mmxi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 304 2455866 10 x 10 10/31/2011 die xxxi mensis x annoque mmxi 11 xi 2011}
+test clock-2.1725 {conversion of 2011-11-01} {
+    clock format 1320150896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/01/2011 12:34:56 die i mensis xi annoque mmxi xii h xxxiv m lvi s 20 mm 01 i  1 i Nov 305 2455867 11 xi 11 11/01/2011 die i mensis xi annoque mmxi 11 xi 2011}
+test clock-2.1726 {conversion of 2011-11-30} {
+    clock format 1322656496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/30/2011 12:34:56 die xxx mensis xi annoque mmxi xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 334 2455896 11 xi 11 11/30/2011 die xxx mensis xi annoque mmxi 11 xi 2011}
+test clock-2.1727 {conversion of 2011-12-01} {
+    clock format 1322742896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/01/2011 12:34:56 die i mensis xii annoque mmxi xii h xxxiv m lvi s 20 mm 01 i  1 i Dec 335 2455897 12 xii 12 12/01/2011 die i mensis xii annoque mmxi 11 xi 2011}
+test clock-2.1728 {conversion of 2011-12-31} {
+    clock format 1325334896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/31/2011 12:34:56 die xxxi mensis xii annoque mmxi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 365 2455927 12 xii 12 12/31/2011 die xxxi mensis xii annoque mmxi 11 xi 2011}
+test clock-2.1729 {conversion of 2012-01-01} {
+    clock format 1325421296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/01/2012 12:34:56 die i mensis i annoque mmxii xii h xxxiv m lvi s 20 mm 01 i  1 i Jan 001 2455928 01 i  1 01/01/2012 die i mensis i annoque mmxii 12 xii 2012}
+test clock-2.1730 {conversion of 2012-01-31} {
+    clock format 1328013296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/31/2012 12:34:56 die xxxi mensis i annoque mmxii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2455958 01 i  1 01/31/2012 die xxxi mensis i annoque mmxii 12 xii 2012}
+test clock-2.1731 {conversion of 2012-02-01} {
+    clock format 1328099696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/01/2012 12:34:56 die i mensis ii annoque mmxii xii h xxxiv m lvi s 20 mm 01 i  1 i Feb 032 2455959 02 ii  2 02/01/2012 die i mensis ii annoque mmxii 12 xii 2012}
+test clock-2.1732 {conversion of 2012-02-29} {
+    clock format 1330518896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/29/2012 12:34:56 die xxix mensis ii annoque mmxii xii h xxxiv m lvi s 20 mm 29 xxix 29 xxix Feb 060 2455987 02 ii  2 02/29/2012 die xxix mensis ii annoque mmxii 12 xii 2012}
+test clock-2.1733 {conversion of 2012-03-01} {
+    clock format 1330605296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/01/2012 12:34:56 die i mensis iii annoque mmxii xii h xxxiv m lvi s 20 mm 01 i  1 i Mar 061 2455988 03 iii  3 03/01/2012 die i mensis iii annoque mmxii 12 xii 2012}
+test clock-2.1734 {conversion of 2012-03-31} {
+    clock format 1333197296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/31/2012 12:34:56 die xxxi mensis iii annoque mmxii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 091 2456018 03 iii  3 03/31/2012 die xxxi mensis iii annoque mmxii 12 xii 2012}
+test clock-2.1735 {conversion of 2012-04-01} {
+    clock format 1333283696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/01/2012 12:34:56 die i mensis iv annoque mmxii xii h xxxiv m lvi s 20 mm 01 i  1 i Apr 092 2456019 04 iv  4 04/01/2012 die i mensis iv annoque mmxii 12 xii 2012}
+test clock-2.1736 {conversion of 2012-04-30} {
+    clock format 1335789296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/30/2012 12:34:56 die xxx mensis iv annoque mmxii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 121 2456048 04 iv  4 04/30/2012 die xxx mensis iv annoque mmxii 12 xii 2012}
+test clock-2.1737 {conversion of 2012-05-01} {
+    clock format 1335875696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/01/2012 12:34:56 die i mensis v annoque mmxii xii h xxxiv m lvi s 20 mm 01 i  1 i May 122 2456049 05 v  5 05/01/2012 die i mensis v annoque mmxii 12 xii 2012}
+test clock-2.1738 {conversion of 2012-05-31} {
+    clock format 1338467696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/31/2012 12:34:56 die xxxi mensis v annoque mmxii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 152 2456079 05 v  5 05/31/2012 die xxxi mensis v annoque mmxii 12 xii 2012}
+test clock-2.1739 {conversion of 2012-06-01} {
+    clock format 1338554096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/01/2012 12:34:56 die i mensis vi annoque mmxii xii h xxxiv m lvi s 20 mm 01 i  1 i Jun 153 2456080 06 vi  6 06/01/2012 die i mensis vi annoque mmxii 12 xii 2012}
+test clock-2.1740 {conversion of 2012-06-30} {
+    clock format 1341059696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/30/2012 12:34:56 die xxx mensis vi annoque mmxii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 182 2456109 06 vi  6 06/30/2012 die xxx mensis vi annoque mmxii 12 xii 2012}
+test clock-2.1741 {conversion of 2012-07-01} {
+    clock format 1341146096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/01/2012 12:34:56 die i mensis vii annoque mmxii xii h xxxiv m lvi s 20 mm 01 i  1 i Jul 183 2456110 07 vii  7 07/01/2012 die i mensis vii annoque mmxii 12 xii 2012}
+test clock-2.1742 {conversion of 2012-07-31} {
+    clock format 1343738096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/31/2012 12:34:56 die xxxi mensis vii annoque mmxii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 213 2456140 07 vii  7 07/31/2012 die xxxi mensis vii annoque mmxii 12 xii 2012}
+test clock-2.1743 {conversion of 2012-08-01} {
+    clock format 1343824496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/01/2012 12:34:56 die i mensis viii annoque mmxii xii h xxxiv m lvi s 20 mm 01 i  1 i Aug 214 2456141 08 viii  8 08/01/2012 die i mensis viii annoque mmxii 12 xii 2012}
+test clock-2.1744 {conversion of 2012-08-31} {
+    clock format 1346416496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/31/2012 12:34:56 die xxxi mensis viii annoque mmxii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 244 2456171 08 viii  8 08/31/2012 die xxxi mensis viii annoque mmxii 12 xii 2012}
+test clock-2.1745 {conversion of 2012-09-01} {
+    clock format 1346502896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/01/2012 12:34:56 die i mensis ix annoque mmxii xii h xxxiv m lvi s 20 mm 01 i  1 i Sep 245 2456172 09 ix  9 09/01/2012 die i mensis ix annoque mmxii 12 xii 2012}
+test clock-2.1746 {conversion of 2012-09-30} {
+    clock format 1349008496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/30/2012 12:34:56 die xxx mensis ix annoque mmxii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 274 2456201 09 ix  9 09/30/2012 die xxx mensis ix annoque mmxii 12 xii 2012}
+test clock-2.1747 {conversion of 2012-10-01} {
+    clock format 1349094896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/01/2012 12:34:56 die i mensis x annoque mmxii xii h xxxiv m lvi s 20 mm 01 i  1 i Oct 275 2456202 10 x 10 10/01/2012 die i mensis x annoque mmxii 12 xii 2012}
+test clock-2.1748 {conversion of 2012-10-31} {
+    clock format 1351686896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/31/2012 12:34:56 die xxxi mensis x annoque mmxii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 305 2456232 10 x 10 10/31/2012 die xxxi mensis x annoque mmxii 12 xii 2012}
+test clock-2.1749 {conversion of 2012-11-01} {
+    clock format 1351773296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/01/2012 12:34:56 die i mensis xi annoque mmxii xii h xxxiv m lvi s 20 mm 01 i  1 i Nov 306 2456233 11 xi 11 11/01/2012 die i mensis xi annoque mmxii 12 xii 2012}
+test clock-2.1750 {conversion of 2012-11-30} {
+    clock format 1354278896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/30/2012 12:34:56 die xxx mensis xi annoque mmxii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 335 2456262 11 xi 11 11/30/2012 die xxx mensis xi annoque mmxii 12 xii 2012}
+test clock-2.1751 {conversion of 2012-12-01} {
+    clock format 1354365296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/01/2012 12:34:56 die i mensis xii annoque mmxii xii h xxxiv m lvi s 20 mm 01 i  1 i Dec 336 2456263 12 xii 12 12/01/2012 die i mensis xii annoque mmxii 12 xii 2012}
+test clock-2.1752 {conversion of 2012-12-31} {
+    clock format 1356957296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/31/2012 12:34:56 die xxxi mensis xii annoque mmxii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 366 2456293 12 xii 12 12/31/2012 die xxxi mensis xii annoque mmxii 12 xii 2012}
+test clock-2.1753 {conversion of 2013-01-01} {
+    clock format 1357043696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/01/2013 12:34:56 die i mensis i annoque mmxiii xii h xxxiv m lvi s 20 mm 01 i  1 i Jan 001 2456294 01 i  1 01/01/2013 die i mensis i annoque mmxiii 13 xiii 2013}
+test clock-2.1754 {conversion of 2013-01-31} {
+    clock format 1359635696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/31/2013 12:34:56 die xxxi mensis i annoque mmxiii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2456324 01 i  1 01/31/2013 die xxxi mensis i annoque mmxiii 13 xiii 2013}
+test clock-2.1755 {conversion of 2013-02-01} {
+    clock format 1359722096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/01/2013 12:34:56 die i mensis ii annoque mmxiii xii h xxxiv m lvi s 20 mm 01 i  1 i Feb 032 2456325 02 ii  2 02/01/2013 die i mensis ii annoque mmxiii 13 xiii 2013}
+test clock-2.1756 {conversion of 2013-02-28} {
+    clock format 1362054896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/28/2013 12:34:56 die xxviii mensis ii annoque mmxiii xii h xxxiv m lvi s 20 mm 28 xxviii 28 xxviii Feb 059 2456352 02 ii  2 02/28/2013 die xxviii mensis ii annoque mmxiii 13 xiii 2013}
+test clock-2.1757 {conversion of 2013-03-01} {
+    clock format 1362141296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/01/2013 12:34:56 die i mensis iii annoque mmxiii xii h xxxiv m lvi s 20 mm 01 i  1 i Mar 060 2456353 03 iii  3 03/01/2013 die i mensis iii annoque mmxiii 13 xiii 2013}
+test clock-2.1758 {conversion of 2013-03-31} {
+    clock format 1364733296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/31/2013 12:34:56 die xxxi mensis iii annoque mmxiii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 090 2456383 03 iii  3 03/31/2013 die xxxi mensis iii annoque mmxiii 13 xiii 2013}
+test clock-2.1759 {conversion of 2013-04-01} {
+    clock format 1364819696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/01/2013 12:34:56 die i mensis iv annoque mmxiii xii h xxxiv m lvi s 20 mm 01 i  1 i Apr 091 2456384 04 iv  4 04/01/2013 die i mensis iv annoque mmxiii 13 xiii 2013}
+test clock-2.1760 {conversion of 2013-04-30} {
+    clock format 1367325296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/30/2013 12:34:56 die xxx mensis iv annoque mmxiii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 120 2456413 04 iv  4 04/30/2013 die xxx mensis iv annoque mmxiii 13 xiii 2013}
+test clock-2.1761 {conversion of 2013-05-01} {
+    clock format 1367411696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/01/2013 12:34:56 die i mensis v annoque mmxiii xii h xxxiv m lvi s 20 mm 01 i  1 i May 121 2456414 05 v  5 05/01/2013 die i mensis v annoque mmxiii 13 xiii 2013}
+test clock-2.1762 {conversion of 2013-05-31} {
+    clock format 1370003696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/31/2013 12:34:56 die xxxi mensis v annoque mmxiii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 151 2456444 05 v  5 05/31/2013 die xxxi mensis v annoque mmxiii 13 xiii 2013}
+test clock-2.1763 {conversion of 2013-06-01} {
+    clock format 1370090096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/01/2013 12:34:56 die i mensis vi annoque mmxiii xii h xxxiv m lvi s 20 mm 01 i  1 i Jun 152 2456445 06 vi  6 06/01/2013 die i mensis vi annoque mmxiii 13 xiii 2013}
+test clock-2.1764 {conversion of 2013-06-30} {
+    clock format 1372595696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/30/2013 12:34:56 die xxx mensis vi annoque mmxiii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 181 2456474 06 vi  6 06/30/2013 die xxx mensis vi annoque mmxiii 13 xiii 2013}
+test clock-2.1765 {conversion of 2013-07-01} {
+    clock format 1372682096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/01/2013 12:34:56 die i mensis vii annoque mmxiii xii h xxxiv m lvi s 20 mm 01 i  1 i Jul 182 2456475 07 vii  7 07/01/2013 die i mensis vii annoque mmxiii 13 xiii 2013}
+test clock-2.1766 {conversion of 2013-07-31} {
+    clock format 1375274096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/31/2013 12:34:56 die xxxi mensis vii annoque mmxiii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 212 2456505 07 vii  7 07/31/2013 die xxxi mensis vii annoque mmxiii 13 xiii 2013}
+test clock-2.1767 {conversion of 2013-08-01} {
+    clock format 1375360496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/01/2013 12:34:56 die i mensis viii annoque mmxiii xii h xxxiv m lvi s 20 mm 01 i  1 i Aug 213 2456506 08 viii  8 08/01/2013 die i mensis viii annoque mmxiii 13 xiii 2013}
+test clock-2.1768 {conversion of 2013-08-31} {
+    clock format 1377952496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/31/2013 12:34:56 die xxxi mensis viii annoque mmxiii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 243 2456536 08 viii  8 08/31/2013 die xxxi mensis viii annoque mmxiii 13 xiii 2013}
+test clock-2.1769 {conversion of 2013-09-01} {
+    clock format 1378038896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/01/2013 12:34:56 die i mensis ix annoque mmxiii xii h xxxiv m lvi s 20 mm 01 i  1 i Sep 244 2456537 09 ix  9 09/01/2013 die i mensis ix annoque mmxiii 13 xiii 2013}
+test clock-2.1770 {conversion of 2013-09-30} {
+    clock format 1380544496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/30/2013 12:34:56 die xxx mensis ix annoque mmxiii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 273 2456566 09 ix  9 09/30/2013 die xxx mensis ix annoque mmxiii 13 xiii 2013}
+test clock-2.1771 {conversion of 2013-10-01} {
+    clock format 1380630896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/01/2013 12:34:56 die i mensis x annoque mmxiii xii h xxxiv m lvi s 20 mm 01 i  1 i Oct 274 2456567 10 x 10 10/01/2013 die i mensis x annoque mmxiii 13 xiii 2013}
+test clock-2.1772 {conversion of 2013-10-31} {
+    clock format 1383222896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/31/2013 12:34:56 die xxxi mensis x annoque mmxiii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 304 2456597 10 x 10 10/31/2013 die xxxi mensis x annoque mmxiii 13 xiii 2013}
+test clock-2.1773 {conversion of 2013-11-01} {
+    clock format 1383309296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/01/2013 12:34:56 die i mensis xi annoque mmxiii xii h xxxiv m lvi s 20 mm 01 i  1 i Nov 305 2456598 11 xi 11 11/01/2013 die i mensis xi annoque mmxiii 13 xiii 2013}
+test clock-2.1774 {conversion of 2013-11-30} {
+    clock format 1385814896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/30/2013 12:34:56 die xxx mensis xi annoque mmxiii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 334 2456627 11 xi 11 11/30/2013 die xxx mensis xi annoque mmxiii 13 xiii 2013}
+test clock-2.1775 {conversion of 2013-12-01} {
+    clock format 1385901296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/01/2013 12:34:56 die i mensis xii annoque mmxiii xii h xxxiv m lvi s 20 mm 01 i  1 i Dec 335 2456628 12 xii 12 12/01/2013 die i mensis xii annoque mmxiii 13 xiii 2013}
+test clock-2.1776 {conversion of 2013-12-31} {
+    clock format 1388493296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/31/2013 12:34:56 die xxxi mensis xii annoque mmxiii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 365 2456658 12 xii 12 12/31/2013 die xxxi mensis xii annoque mmxiii 13 xiii 2013}
+test clock-2.1777 {conversion of 2016-01-01} {
+    clock format 1451651696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/01/2016 12:34:56 die i mensis i annoque mmxvi xii h xxxiv m lvi s 20 mm 01 i  1 i Jan 001 2457389 01 i  1 01/01/2016 die i mensis i annoque mmxvi 16 xvi 2016}
+test clock-2.1778 {conversion of 2016-01-31} {
+    clock format 1454243696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/31/2016 12:34:56 die xxxi mensis i annoque mmxvi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2457419 01 i  1 01/31/2016 die xxxi mensis i annoque mmxvi 16 xvi 2016}
+test clock-2.1779 {conversion of 2016-02-01} {
+    clock format 1454330096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/01/2016 12:34:56 die i mensis ii annoque mmxvi xii h xxxiv m lvi s 20 mm 01 i  1 i Feb 032 2457420 02 ii  2 02/01/2016 die i mensis ii annoque mmxvi 16 xvi 2016}
+test clock-2.1780 {conversion of 2016-02-29} {
+    clock format 1456749296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/29/2016 12:34:56 die xxix mensis ii annoque mmxvi xii h xxxiv m lvi s 20 mm 29 xxix 29 xxix Feb 060 2457448 02 ii  2 02/29/2016 die xxix mensis ii annoque mmxvi 16 xvi 2016}
+test clock-2.1781 {conversion of 2016-03-01} {
+    clock format 1456835696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/01/2016 12:34:56 die i mensis iii annoque mmxvi xii h xxxiv m lvi s 20 mm 01 i  1 i Mar 061 2457449 03 iii  3 03/01/2016 die i mensis iii annoque mmxvi 16 xvi 2016}
+test clock-2.1782 {conversion of 2016-03-31} {
+    clock format 1459427696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/31/2016 12:34:56 die xxxi mensis iii annoque mmxvi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 091 2457479 03 iii  3 03/31/2016 die xxxi mensis iii annoque mmxvi 16 xvi 2016}
+test clock-2.1783 {conversion of 2016-04-01} {
+    clock format 1459514096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/01/2016 12:34:56 die i mensis iv annoque mmxvi xii h xxxiv m lvi s 20 mm 01 i  1 i Apr 092 2457480 04 iv  4 04/01/2016 die i mensis iv annoque mmxvi 16 xvi 2016}
+test clock-2.1784 {conversion of 2016-04-30} {
+    clock format 1462019696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/30/2016 12:34:56 die xxx mensis iv annoque mmxvi xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 121 2457509 04 iv  4 04/30/2016 die xxx mensis iv annoque mmxvi 16 xvi 2016}
+test clock-2.1785 {conversion of 2016-05-01} {
+    clock format 1462106096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/01/2016 12:34:56 die i mensis v annoque mmxvi xii h xxxiv m lvi s 20 mm 01 i  1 i May 122 2457510 05 v  5 05/01/2016 die i mensis v annoque mmxvi 16 xvi 2016}
+test clock-2.1786 {conversion of 2016-05-31} {
+    clock format 1464698096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/31/2016 12:34:56 die xxxi mensis v annoque mmxvi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 152 2457540 05 v  5 05/31/2016 die xxxi mensis v annoque mmxvi 16 xvi 2016}
+test clock-2.1787 {conversion of 2016-06-01} {
+    clock format 1464784496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/01/2016 12:34:56 die i mensis vi annoque mmxvi xii h xxxiv m lvi s 20 mm 01 i  1 i Jun 153 2457541 06 vi  6 06/01/2016 die i mensis vi annoque mmxvi 16 xvi 2016}
+test clock-2.1788 {conversion of 2016-06-30} {
+    clock format 1467290096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/30/2016 12:34:56 die xxx mensis vi annoque mmxvi xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 182 2457570 06 vi  6 06/30/2016 die xxx mensis vi annoque mmxvi 16 xvi 2016}
+test clock-2.1789 {conversion of 2016-07-01} {
+    clock format 1467376496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/01/2016 12:34:56 die i mensis vii annoque mmxvi xii h xxxiv m lvi s 20 mm 01 i  1 i Jul 183 2457571 07 vii  7 07/01/2016 die i mensis vii annoque mmxvi 16 xvi 2016}
+test clock-2.1790 {conversion of 2016-07-31} {
+    clock format 1469968496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/31/2016 12:34:56 die xxxi mensis vii annoque mmxvi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 213 2457601 07 vii  7 07/31/2016 die xxxi mensis vii annoque mmxvi 16 xvi 2016}
+test clock-2.1791 {conversion of 2016-08-01} {
+    clock format 1470054896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/01/2016 12:34:56 die i mensis viii annoque mmxvi xii h xxxiv m lvi s 20 mm 01 i  1 i Aug 214 2457602 08 viii  8 08/01/2016 die i mensis viii annoque mmxvi 16 xvi 2016}
+test clock-2.1792 {conversion of 2016-08-31} {
+    clock format 1472646896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/31/2016 12:34:56 die xxxi mensis viii annoque mmxvi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 244 2457632 08 viii  8 08/31/2016 die xxxi mensis viii annoque mmxvi 16 xvi 2016}
+test clock-2.1793 {conversion of 2016-09-01} {
+    clock format 1472733296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/01/2016 12:34:56 die i mensis ix annoque mmxvi xii h xxxiv m lvi s 20 mm 01 i  1 i Sep 245 2457633 09 ix  9 09/01/2016 die i mensis ix annoque mmxvi 16 xvi 2016}
+test clock-2.1794 {conversion of 2016-09-30} {
+    clock format 1475238896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/30/2016 12:34:56 die xxx mensis ix annoque mmxvi xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 274 2457662 09 ix  9 09/30/2016 die xxx mensis ix annoque mmxvi 16 xvi 2016}
+test clock-2.1795 {conversion of 2016-10-01} {
+    clock format 1475325296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/01/2016 12:34:56 die i mensis x annoque mmxvi xii h xxxiv m lvi s 20 mm 01 i  1 i Oct 275 2457663 10 x 10 10/01/2016 die i mensis x annoque mmxvi 16 xvi 2016}
+test clock-2.1796 {conversion of 2016-10-31} {
+    clock format 1477917296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/31/2016 12:34:56 die xxxi mensis x annoque mmxvi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 305 2457693 10 x 10 10/31/2016 die xxxi mensis x annoque mmxvi 16 xvi 2016}
+test clock-2.1797 {conversion of 2016-11-01} {
+    clock format 1478003696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/01/2016 12:34:56 die i mensis xi annoque mmxvi xii h xxxiv m lvi s 20 mm 01 i  1 i Nov 306 2457694 11 xi 11 11/01/2016 die i mensis xi annoque mmxvi 16 xvi 2016}
+test clock-2.1798 {conversion of 2016-11-30} {
+    clock format 1480509296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/30/2016 12:34:56 die xxx mensis xi annoque mmxvi xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 335 2457723 11 xi 11 11/30/2016 die xxx mensis xi annoque mmxvi 16 xvi 2016}
+test clock-2.1799 {conversion of 2016-12-01} {
+    clock format 1480595696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/01/2016 12:34:56 die i mensis xii annoque mmxvi xii h xxxiv m lvi s 20 mm 01 i  1 i Dec 336 2457724 12 xii 12 12/01/2016 die i mensis xii annoque mmxvi 16 xvi 2016}
+test clock-2.1800 {conversion of 2016-12-31} {
+    clock format 1483187696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/31/2016 12:34:56 die xxxi mensis xii annoque mmxvi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 366 2457754 12 xii 12 12/31/2016 die xxxi mensis xii annoque mmxvi 16 xvi 2016}
+test clock-2.1801 {conversion of 2017-01-01} {
+    clock format 1483274096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/01/2017 12:34:56 die i mensis i annoque mmxvii xii h xxxiv m lvi s 20 mm 01 i  1 i Jan 001 2457755 01 i  1 01/01/2017 die i mensis i annoque mmxvii 17 xvii 2017}
+test clock-2.1802 {conversion of 2017-01-31} {
+    clock format 1485866096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/31/2017 12:34:56 die xxxi mensis i annoque mmxvii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2457785 01 i  1 01/31/2017 die xxxi mensis i annoque mmxvii 17 xvii 2017}
+test clock-2.1803 {conversion of 2017-02-01} {
+    clock format 1485952496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/01/2017 12:34:56 die i mensis ii annoque mmxvii xii h xxxiv m lvi s 20 mm 01 i  1 i Feb 032 2457786 02 ii  2 02/01/2017 die i mensis ii annoque mmxvii 17 xvii 2017}
+test clock-2.1804 {conversion of 2017-02-28} {
+    clock format 1488285296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/28/2017 12:34:56 die xxviii mensis ii annoque mmxvii xii h xxxiv m lvi s 20 mm 28 xxviii 28 xxviii Feb 059 2457813 02 ii  2 02/28/2017 die xxviii mensis ii annoque mmxvii 17 xvii 2017}
+test clock-2.1805 {conversion of 2017-03-01} {
+    clock format 1488371696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/01/2017 12:34:56 die i mensis iii annoque mmxvii xii h xxxiv m lvi s 20 mm 01 i  1 i Mar 060 2457814 03 iii  3 03/01/2017 die i mensis iii annoque mmxvii 17 xvii 2017}
+test clock-2.1806 {conversion of 2017-03-31} {
+    clock format 1490963696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/31/2017 12:34:56 die xxxi mensis iii annoque mmxvii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 090 2457844 03 iii  3 03/31/2017 die xxxi mensis iii annoque mmxvii 17 xvii 2017}
+test clock-2.1807 {conversion of 2017-04-01} {
+    clock format 1491050096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/01/2017 12:34:56 die i mensis iv annoque mmxvii xii h xxxiv m lvi s 20 mm 01 i  1 i Apr 091 2457845 04 iv  4 04/01/2017 die i mensis iv annoque mmxvii 17 xvii 2017}
+test clock-2.1808 {conversion of 2017-04-30} {
+    clock format 1493555696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/30/2017 12:34:56 die xxx mensis iv annoque mmxvii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 120 2457874 04 iv  4 04/30/2017 die xxx mensis iv annoque mmxvii 17 xvii 2017}
+test clock-2.1809 {conversion of 2017-05-01} {
+    clock format 1493642096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/01/2017 12:34:56 die i mensis v annoque mmxvii xii h xxxiv m lvi s 20 mm 01 i  1 i May 121 2457875 05 v  5 05/01/2017 die i mensis v annoque mmxvii 17 xvii 2017}
+test clock-2.1810 {conversion of 2017-05-31} {
+    clock format 1496234096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/31/2017 12:34:56 die xxxi mensis v annoque mmxvii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 151 2457905 05 v  5 05/31/2017 die xxxi mensis v annoque mmxvii 17 xvii 2017}
+test clock-2.1811 {conversion of 2017-06-01} {
+    clock format 1496320496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/01/2017 12:34:56 die i mensis vi annoque mmxvii xii h xxxiv m lvi s 20 mm 01 i  1 i Jun 152 2457906 06 vi  6 06/01/2017 die i mensis vi annoque mmxvii 17 xvii 2017}
+test clock-2.1812 {conversion of 2017-06-30} {
+    clock format 1498826096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/30/2017 12:34:56 die xxx mensis vi annoque mmxvii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 181 2457935 06 vi  6 06/30/2017 die xxx mensis vi annoque mmxvii 17 xvii 2017}
+test clock-2.1813 {conversion of 2017-07-01} {
+    clock format 1498912496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/01/2017 12:34:56 die i mensis vii annoque mmxvii xii h xxxiv m lvi s 20 mm 01 i  1 i Jul 182 2457936 07 vii  7 07/01/2017 die i mensis vii annoque mmxvii 17 xvii 2017}
+test clock-2.1814 {conversion of 2017-07-31} {
+    clock format 1501504496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/31/2017 12:34:56 die xxxi mensis vii annoque mmxvii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 212 2457966 07 vii  7 07/31/2017 die xxxi mensis vii annoque mmxvii 17 xvii 2017}
+test clock-2.1815 {conversion of 2017-08-01} {
+    clock format 1501590896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/01/2017 12:34:56 die i mensis viii annoque mmxvii xii h xxxiv m lvi s 20 mm 01 i  1 i Aug 213 2457967 08 viii  8 08/01/2017 die i mensis viii annoque mmxvii 17 xvii 2017}
+test clock-2.1816 {conversion of 2017-08-31} {
+    clock format 1504182896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/31/2017 12:34:56 die xxxi mensis viii annoque mmxvii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 243 2457997 08 viii  8 08/31/2017 die xxxi mensis viii annoque mmxvii 17 xvii 2017}
+test clock-2.1817 {conversion of 2017-09-01} {
+    clock format 1504269296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/01/2017 12:34:56 die i mensis ix annoque mmxvii xii h xxxiv m lvi s 20 mm 01 i  1 i Sep 244 2457998 09 ix  9 09/01/2017 die i mensis ix annoque mmxvii 17 xvii 2017}
+test clock-2.1818 {conversion of 2017-09-30} {
+    clock format 1506774896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/30/2017 12:34:56 die xxx mensis ix annoque mmxvii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 273 2458027 09 ix  9 09/30/2017 die xxx mensis ix annoque mmxvii 17 xvii 2017}
+test clock-2.1819 {conversion of 2017-10-01} {
+    clock format 1506861296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/01/2017 12:34:56 die i mensis x annoque mmxvii xii h xxxiv m lvi s 20 mm 01 i  1 i Oct 274 2458028 10 x 10 10/01/2017 die i mensis x annoque mmxvii 17 xvii 2017}
+test clock-2.1820 {conversion of 2017-10-31} {
+    clock format 1509453296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/31/2017 12:34:56 die xxxi mensis x annoque mmxvii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 304 2458058 10 x 10 10/31/2017 die xxxi mensis x annoque mmxvii 17 xvii 2017}
+test clock-2.1821 {conversion of 2017-11-01} {
+    clock format 1509539696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/01/2017 12:34:56 die i mensis xi annoque mmxvii xii h xxxiv m lvi s 20 mm 01 i  1 i Nov 305 2458059 11 xi 11 11/01/2017 die i mensis xi annoque mmxvii 17 xvii 2017}
+test clock-2.1822 {conversion of 2017-11-30} {
+    clock format 1512045296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/30/2017 12:34:56 die xxx mensis xi annoque mmxvii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 334 2458088 11 xi 11 11/30/2017 die xxx mensis xi annoque mmxvii 17 xvii 2017}
+test clock-2.1823 {conversion of 2017-12-01} {
+    clock format 1512131696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/01/2017 12:34:56 die i mensis xii annoque mmxvii xii h xxxiv m lvi s 20 mm 01 i  1 i Dec 335 2458089 12 xii 12 12/01/2017 die i mensis xii annoque mmxvii 17 xvii 2017}
+test clock-2.1824 {conversion of 2017-12-31} {
+    clock format 1514723696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/31/2017 12:34:56 die xxxi mensis xii annoque mmxvii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 365 2458119 12 xii 12 12/31/2017 die xxxi mensis xii annoque mmxvii 17 xvii 2017}
+test clock-2.1825 {conversion of 2020-01-01} {
+    clock format 1577882096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/01/2020 12:34:56 die i mensis i annoque mmxx xii h xxxiv m lvi s 20 mm 01 i  1 i Jan 001 2458850 01 i  1 01/01/2020 die i mensis i annoque mmxx 20 xx 2020}
+test clock-2.1826 {conversion of 2020-01-31} {
+    clock format 1580474096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/31/2020 12:34:56 die xxxi mensis i annoque mmxx xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2458880 01 i  1 01/31/2020 die xxxi mensis i annoque mmxx 20 xx 2020}
+test clock-2.1827 {conversion of 2020-02-01} {
+    clock format 1580560496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/01/2020 12:34:56 die i mensis ii annoque mmxx xii h xxxiv m lvi s 20 mm 01 i  1 i Feb 032 2458881 02 ii  2 02/01/2020 die i mensis ii annoque mmxx 20 xx 2020}
+test clock-2.1828 {conversion of 2020-02-29} {
+    clock format 1582979696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/29/2020 12:34:56 die xxix mensis ii annoque mmxx xii h xxxiv m lvi s 20 mm 29 xxix 29 xxix Feb 060 2458909 02 ii  2 02/29/2020 die xxix mensis ii annoque mmxx 20 xx 2020}
+test clock-2.1829 {conversion of 2020-03-01} {
+    clock format 1583066096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/01/2020 12:34:56 die i mensis iii annoque mmxx xii h xxxiv m lvi s 20 mm 01 i  1 i Mar 061 2458910 03 iii  3 03/01/2020 die i mensis iii annoque mmxx 20 xx 2020}
+test clock-2.1830 {conversion of 2020-03-31} {
+    clock format 1585658096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/31/2020 12:34:56 die xxxi mensis iii annoque mmxx xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 091 2458940 03 iii  3 03/31/2020 die xxxi mensis iii annoque mmxx 20 xx 2020}
+test clock-2.1831 {conversion of 2020-04-01} {
+    clock format 1585744496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/01/2020 12:34:56 die i mensis iv annoque mmxx xii h xxxiv m lvi s 20 mm 01 i  1 i Apr 092 2458941 04 iv  4 04/01/2020 die i mensis iv annoque mmxx 20 xx 2020}
+test clock-2.1832 {conversion of 2020-04-30} {
+    clock format 1588250096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/30/2020 12:34:56 die xxx mensis iv annoque mmxx xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 121 2458970 04 iv  4 04/30/2020 die xxx mensis iv annoque mmxx 20 xx 2020}
+test clock-2.1833 {conversion of 2020-05-01} {
+    clock format 1588336496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/01/2020 12:34:56 die i mensis v annoque mmxx xii h xxxiv m lvi s 20 mm 01 i  1 i May 122 2458971 05 v  5 05/01/2020 die i mensis v annoque mmxx 20 xx 2020}
+test clock-2.1834 {conversion of 2020-05-31} {
+    clock format 1590928496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/31/2020 12:34:56 die xxxi mensis v annoque mmxx xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 152 2459001 05 v  5 05/31/2020 die xxxi mensis v annoque mmxx 20 xx 2020}
+test clock-2.1835 {conversion of 2020-06-01} {
+    clock format 1591014896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/01/2020 12:34:56 die i mensis vi annoque mmxx xii h xxxiv m lvi s 20 mm 01 i  1 i Jun 153 2459002 06 vi  6 06/01/2020 die i mensis vi annoque mmxx 20 xx 2020}
+test clock-2.1836 {conversion of 2020-06-30} {
+    clock format 1593520496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/30/2020 12:34:56 die xxx mensis vi annoque mmxx xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 182 2459031 06 vi  6 06/30/2020 die xxx mensis vi annoque mmxx 20 xx 2020}
+test clock-2.1837 {conversion of 2020-07-01} {
+    clock format 1593606896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/01/2020 12:34:56 die i mensis vii annoque mmxx xii h xxxiv m lvi s 20 mm 01 i  1 i Jul 183 2459032 07 vii  7 07/01/2020 die i mensis vii annoque mmxx 20 xx 2020}
+test clock-2.1838 {conversion of 2020-07-31} {
+    clock format 1596198896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/31/2020 12:34:56 die xxxi mensis vii annoque mmxx xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 213 2459062 07 vii  7 07/31/2020 die xxxi mensis vii annoque mmxx 20 xx 2020}
+test clock-2.1839 {conversion of 2020-08-01} {
+    clock format 1596285296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/01/2020 12:34:56 die i mensis viii annoque mmxx xii h xxxiv m lvi s 20 mm 01 i  1 i Aug 214 2459063 08 viii  8 08/01/2020 die i mensis viii annoque mmxx 20 xx 2020}
+test clock-2.1840 {conversion of 2020-08-31} {
+    clock format 1598877296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/31/2020 12:34:56 die xxxi mensis viii annoque mmxx xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 244 2459093 08 viii  8 08/31/2020 die xxxi mensis viii annoque mmxx 20 xx 2020}
+test clock-2.1841 {conversion of 2020-09-01} {
+    clock format 1598963696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/01/2020 12:34:56 die i mensis ix annoque mmxx xii h xxxiv m lvi s 20 mm 01 i  1 i Sep 245 2459094 09 ix  9 09/01/2020 die i mensis ix annoque mmxx 20 xx 2020}
+test clock-2.1842 {conversion of 2020-09-30} {
+    clock format 1601469296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/30/2020 12:34:56 die xxx mensis ix annoque mmxx xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 274 2459123 09 ix  9 09/30/2020 die xxx mensis ix annoque mmxx 20 xx 2020}
+test clock-2.1843 {conversion of 2020-10-01} {
+    clock format 1601555696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/01/2020 12:34:56 die i mensis x annoque mmxx xii h xxxiv m lvi s 20 mm 01 i  1 i Oct 275 2459124 10 x 10 10/01/2020 die i mensis x annoque mmxx 20 xx 2020}
+test clock-2.1844 {conversion of 2020-10-31} {
+    clock format 1604147696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/31/2020 12:34:56 die xxxi mensis x annoque mmxx xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 305 2459154 10 x 10 10/31/2020 die xxxi mensis x annoque mmxx 20 xx 2020}
+test clock-2.1845 {conversion of 2020-11-01} {
+    clock format 1604234096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/01/2020 12:34:56 die i mensis xi annoque mmxx xii h xxxiv m lvi s 20 mm 01 i  1 i Nov 306 2459155 11 xi 11 11/01/2020 die i mensis xi annoque mmxx 20 xx 2020}
+test clock-2.1846 {conversion of 2020-11-30} {
+    clock format 1606739696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/30/2020 12:34:56 die xxx mensis xi annoque mmxx xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 335 2459184 11 xi 11 11/30/2020 die xxx mensis xi annoque mmxx 20 xx 2020}
+test clock-2.1847 {conversion of 2020-12-01} {
+    clock format 1606826096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/01/2020 12:34:56 die i mensis xii annoque mmxx xii h xxxiv m lvi s 20 mm 01 i  1 i Dec 336 2459185 12 xii 12 12/01/2020 die i mensis xii annoque mmxx 20 xx 2020}
+test clock-2.1848 {conversion of 2020-12-31} {
+    clock format 1609418096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/31/2020 12:34:56 die xxxi mensis xii annoque mmxx xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 366 2459215 12 xii 12 12/31/2020 die xxxi mensis xii annoque mmxx 20 xx 2020}
+test clock-2.1849 {conversion of 2021-01-01} {
+    clock format 1609504496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/01/2021 12:34:56 die i mensis i annoque mmxxi xii h xxxiv m lvi s 20 mm 01 i  1 i Jan 001 2459216 01 i  1 01/01/2021 die i mensis i annoque mmxxi 21 xxi 2021}
+test clock-2.1850 {conversion of 2021-01-31} {
+    clock format 1612096496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/31/2021 12:34:56 die xxxi mensis i annoque mmxxi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2459246 01 i  1 01/31/2021 die xxxi mensis i annoque mmxxi 21 xxi 2021}
+test clock-2.1851 {conversion of 2021-02-01} {
+    clock format 1612182896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/01/2021 12:34:56 die i mensis ii annoque mmxxi xii h xxxiv m lvi s 20 mm 01 i  1 i Feb 032 2459247 02 ii  2 02/01/2021 die i mensis ii annoque mmxxi 21 xxi 2021}
+test clock-2.1852 {conversion of 2021-02-28} {
+    clock format 1614515696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/28/2021 12:34:56 die xxviii mensis ii annoque mmxxi xii h xxxiv m lvi s 20 mm 28 xxviii 28 xxviii Feb 059 2459274 02 ii  2 02/28/2021 die xxviii mensis ii annoque mmxxi 21 xxi 2021}
+test clock-2.1853 {conversion of 2021-03-01} {
+    clock format 1614602096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/01/2021 12:34:56 die i mensis iii annoque mmxxi xii h xxxiv m lvi s 20 mm 01 i  1 i Mar 060 2459275 03 iii  3 03/01/2021 die i mensis iii annoque mmxxi 21 xxi 2021}
+test clock-2.1854 {conversion of 2021-03-31} {
+    clock format 1617194096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/31/2021 12:34:56 die xxxi mensis iii annoque mmxxi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 090 2459305 03 iii  3 03/31/2021 die xxxi mensis iii annoque mmxxi 21 xxi 2021}
+test clock-2.1855 {conversion of 2021-04-01} {
+    clock format 1617280496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/01/2021 12:34:56 die i mensis iv annoque mmxxi xii h xxxiv m lvi s 20 mm 01 i  1 i Apr 091 2459306 04 iv  4 04/01/2021 die i mensis iv annoque mmxxi 21 xxi 2021}
+test clock-2.1856 {conversion of 2021-04-30} {
+    clock format 1619786096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/30/2021 12:34:56 die xxx mensis iv annoque mmxxi xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 120 2459335 04 iv  4 04/30/2021 die xxx mensis iv annoque mmxxi 21 xxi 2021}
+test clock-2.1857 {conversion of 2021-05-01} {
+    clock format 1619872496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/01/2021 12:34:56 die i mensis v annoque mmxxi xii h xxxiv m lvi s 20 mm 01 i  1 i May 121 2459336 05 v  5 05/01/2021 die i mensis v annoque mmxxi 21 xxi 2021}
+test clock-2.1858 {conversion of 2021-05-31} {
+    clock format 1622464496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/31/2021 12:34:56 die xxxi mensis v annoque mmxxi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 151 2459366 05 v  5 05/31/2021 die xxxi mensis v annoque mmxxi 21 xxi 2021}
+test clock-2.1859 {conversion of 2021-06-01} {
+    clock format 1622550896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/01/2021 12:34:56 die i mensis vi annoque mmxxi xii h xxxiv m lvi s 20 mm 01 i  1 i Jun 152 2459367 06 vi  6 06/01/2021 die i mensis vi annoque mmxxi 21 xxi 2021}
+test clock-2.1860 {conversion of 2021-06-30} {
+    clock format 1625056496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/30/2021 12:34:56 die xxx mensis vi annoque mmxxi xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 181 2459396 06 vi  6 06/30/2021 die xxx mensis vi annoque mmxxi 21 xxi 2021}
+test clock-2.1861 {conversion of 2021-07-01} {
+    clock format 1625142896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/01/2021 12:34:56 die i mensis vii annoque mmxxi xii h xxxiv m lvi s 20 mm 01 i  1 i Jul 182 2459397 07 vii  7 07/01/2021 die i mensis vii annoque mmxxi 21 xxi 2021}
+test clock-2.1862 {conversion of 2021-07-31} {
+    clock format 1627734896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/31/2021 12:34:56 die xxxi mensis vii annoque mmxxi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 212 2459427 07 vii  7 07/31/2021 die xxxi mensis vii annoque mmxxi 21 xxi 2021}
+test clock-2.1863 {conversion of 2021-08-01} {
+    clock format 1627821296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/01/2021 12:34:56 die i mensis viii annoque mmxxi xii h xxxiv m lvi s 20 mm 01 i  1 i Aug 213 2459428 08 viii  8 08/01/2021 die i mensis viii annoque mmxxi 21 xxi 2021}
+test clock-2.1864 {conversion of 2021-08-31} {
+    clock format 1630413296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/31/2021 12:34:56 die xxxi mensis viii annoque mmxxi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 243 2459458 08 viii  8 08/31/2021 die xxxi mensis viii annoque mmxxi 21 xxi 2021}
+test clock-2.1865 {conversion of 2021-09-01} {
+    clock format 1630499696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/01/2021 12:34:56 die i mensis ix annoque mmxxi xii h xxxiv m lvi s 20 mm 01 i  1 i Sep 244 2459459 09 ix  9 09/01/2021 die i mensis ix annoque mmxxi 21 xxi 2021}
+test clock-2.1866 {conversion of 2021-09-30} {
+    clock format 1633005296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/30/2021 12:34:56 die xxx mensis ix annoque mmxxi xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 273 2459488 09 ix  9 09/30/2021 die xxx mensis ix annoque mmxxi 21 xxi 2021}
+test clock-2.1867 {conversion of 2021-10-01} {
+    clock format 1633091696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/01/2021 12:34:56 die i mensis x annoque mmxxi xii h xxxiv m lvi s 20 mm 01 i  1 i Oct 274 2459489 10 x 10 10/01/2021 die i mensis x annoque mmxxi 21 xxi 2021}
+test clock-2.1868 {conversion of 2021-10-31} {
+    clock format 1635683696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/31/2021 12:34:56 die xxxi mensis x annoque mmxxi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 304 2459519 10 x 10 10/31/2021 die xxxi mensis x annoque mmxxi 21 xxi 2021}
+test clock-2.1869 {conversion of 2021-11-01} {
+    clock format 1635770096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/01/2021 12:34:56 die i mensis xi annoque mmxxi xii h xxxiv m lvi s 20 mm 01 i  1 i Nov 305 2459520 11 xi 11 11/01/2021 die i mensis xi annoque mmxxi 21 xxi 2021}
+test clock-2.1870 {conversion of 2021-11-30} {
+    clock format 1638275696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/30/2021 12:34:56 die xxx mensis xi annoque mmxxi xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 334 2459549 11 xi 11 11/30/2021 die xxx mensis xi annoque mmxxi 21 xxi 2021}
+test clock-2.1871 {conversion of 2021-12-01} {
+    clock format 1638362096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/01/2021 12:34:56 die i mensis xii annoque mmxxi xii h xxxiv m lvi s 20 mm 01 i  1 i Dec 335 2459550 12 xii 12 12/01/2021 die i mensis xii annoque mmxxi 21 xxi 2021}
+test clock-2.1872 {conversion of 2021-12-31} {
+    clock format 1640954096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/31/2021 12:34:56 die xxxi mensis xii annoque mmxxi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 365 2459580 12 xii 12 12/31/2021 die xxxi mensis xii annoque mmxxi 21 xxi 2021}
+test clock-2.1873 {conversion of 2024-01-01} {
+    clock format 1704112496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/01/2024 12:34:56 die i mensis i annoque mmxxiv xii h xxxiv m lvi s 20 mm 01 i  1 i Jan 001 2460311 01 i  1 01/01/2024 die i mensis i annoque mmxxiv 24 xxiv 2024}
+test clock-2.1874 {conversion of 2024-01-31} {
+    clock format 1706704496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/31/2024 12:34:56 die xxxi mensis i annoque mmxxiv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2460341 01 i  1 01/31/2024 die xxxi mensis i annoque mmxxiv 24 xxiv 2024}
+test clock-2.1875 {conversion of 2024-02-01} {
+    clock format 1706790896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/01/2024 12:34:56 die i mensis ii annoque mmxxiv xii h xxxiv m lvi s 20 mm 01 i  1 i Feb 032 2460342 02 ii  2 02/01/2024 die i mensis ii annoque mmxxiv 24 xxiv 2024}
+test clock-2.1876 {conversion of 2024-02-29} {
+    clock format 1709210096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/29/2024 12:34:56 die xxix mensis ii annoque mmxxiv xii h xxxiv m lvi s 20 mm 29 xxix 29 xxix Feb 060 2460370 02 ii  2 02/29/2024 die xxix mensis ii annoque mmxxiv 24 xxiv 2024}
+test clock-2.1877 {conversion of 2024-03-01} {
+    clock format 1709296496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/01/2024 12:34:56 die i mensis iii annoque mmxxiv xii h xxxiv m lvi s 20 mm 01 i  1 i Mar 061 2460371 03 iii  3 03/01/2024 die i mensis iii annoque mmxxiv 24 xxiv 2024}
+test clock-2.1878 {conversion of 2024-03-31} {
+    clock format 1711888496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/31/2024 12:34:56 die xxxi mensis iii annoque mmxxiv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 091 2460401 03 iii  3 03/31/2024 die xxxi mensis iii annoque mmxxiv 24 xxiv 2024}
+test clock-2.1879 {conversion of 2024-04-01} {
+    clock format 1711974896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/01/2024 12:34:56 die i mensis iv annoque mmxxiv xii h xxxiv m lvi s 20 mm 01 i  1 i Apr 092 2460402 04 iv  4 04/01/2024 die i mensis iv annoque mmxxiv 24 xxiv 2024}
+test clock-2.1880 {conversion of 2024-04-30} {
+    clock format 1714480496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/30/2024 12:34:56 die xxx mensis iv annoque mmxxiv xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 121 2460431 04 iv  4 04/30/2024 die xxx mensis iv annoque mmxxiv 24 xxiv 2024}
+test clock-2.1881 {conversion of 2024-05-01} {
+    clock format 1714566896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/01/2024 12:34:56 die i mensis v annoque mmxxiv xii h xxxiv m lvi s 20 mm 01 i  1 i May 122 2460432 05 v  5 05/01/2024 die i mensis v annoque mmxxiv 24 xxiv 2024}
+test clock-2.1882 {conversion of 2024-05-31} {
+    clock format 1717158896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/31/2024 12:34:56 die xxxi mensis v annoque mmxxiv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 152 2460462 05 v  5 05/31/2024 die xxxi mensis v annoque mmxxiv 24 xxiv 2024}
+test clock-2.1883 {conversion of 2024-06-01} {
+    clock format 1717245296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/01/2024 12:34:56 die i mensis vi annoque mmxxiv xii h xxxiv m lvi s 20 mm 01 i  1 i Jun 153 2460463 06 vi  6 06/01/2024 die i mensis vi annoque mmxxiv 24 xxiv 2024}
+test clock-2.1884 {conversion of 2024-06-30} {
+    clock format 1719750896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/30/2024 12:34:56 die xxx mensis vi annoque mmxxiv xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 182 2460492 06 vi  6 06/30/2024 die xxx mensis vi annoque mmxxiv 24 xxiv 2024}
+test clock-2.1885 {conversion of 2024-07-01} {
+    clock format 1719837296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/01/2024 12:34:56 die i mensis vii annoque mmxxiv xii h xxxiv m lvi s 20 mm 01 i  1 i Jul 183 2460493 07 vii  7 07/01/2024 die i mensis vii annoque mmxxiv 24 xxiv 2024}
+test clock-2.1886 {conversion of 2024-07-31} {
+    clock format 1722429296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/31/2024 12:34:56 die xxxi mensis vii annoque mmxxiv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 213 2460523 07 vii  7 07/31/2024 die xxxi mensis vii annoque mmxxiv 24 xxiv 2024}
+test clock-2.1887 {conversion of 2024-08-01} {
+    clock format 1722515696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/01/2024 12:34:56 die i mensis viii annoque mmxxiv xii h xxxiv m lvi s 20 mm 01 i  1 i Aug 214 2460524 08 viii  8 08/01/2024 die i mensis viii annoque mmxxiv 24 xxiv 2024}
+test clock-2.1888 {conversion of 2024-08-31} {
+    clock format 1725107696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/31/2024 12:34:56 die xxxi mensis viii annoque mmxxiv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 244 2460554 08 viii  8 08/31/2024 die xxxi mensis viii annoque mmxxiv 24 xxiv 2024}
+test clock-2.1889 {conversion of 2024-09-01} {
+    clock format 1725194096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/01/2024 12:34:56 die i mensis ix annoque mmxxiv xii h xxxiv m lvi s 20 mm 01 i  1 i Sep 245 2460555 09 ix  9 09/01/2024 die i mensis ix annoque mmxxiv 24 xxiv 2024}
+test clock-2.1890 {conversion of 2024-09-30} {
+    clock format 1727699696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/30/2024 12:34:56 die xxx mensis ix annoque mmxxiv xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 274 2460584 09 ix  9 09/30/2024 die xxx mensis ix annoque mmxxiv 24 xxiv 2024}
+test clock-2.1891 {conversion of 2024-10-01} {
+    clock format 1727786096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/01/2024 12:34:56 die i mensis x annoque mmxxiv xii h xxxiv m lvi s 20 mm 01 i  1 i Oct 275 2460585 10 x 10 10/01/2024 die i mensis x annoque mmxxiv 24 xxiv 2024}
+test clock-2.1892 {conversion of 2024-10-31} {
+    clock format 1730378096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/31/2024 12:34:56 die xxxi mensis x annoque mmxxiv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 305 2460615 10 x 10 10/31/2024 die xxxi mensis x annoque mmxxiv 24 xxiv 2024}
+test clock-2.1893 {conversion of 2024-11-01} {
+    clock format 1730464496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/01/2024 12:34:56 die i mensis xi annoque mmxxiv xii h xxxiv m lvi s 20 mm 01 i  1 i Nov 306 2460616 11 xi 11 11/01/2024 die i mensis xi annoque mmxxiv 24 xxiv 2024}
+test clock-2.1894 {conversion of 2024-11-30} {
+    clock format 1732970096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/30/2024 12:34:56 die xxx mensis xi annoque mmxxiv xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 335 2460645 11 xi 11 11/30/2024 die xxx mensis xi annoque mmxxiv 24 xxiv 2024}
+test clock-2.1895 {conversion of 2024-12-01} {
+    clock format 1733056496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/01/2024 12:34:56 die i mensis xii annoque mmxxiv xii h xxxiv m lvi s 20 mm 01 i  1 i Dec 336 2460646 12 xii 12 12/01/2024 die i mensis xii annoque mmxxiv 24 xxiv 2024}
+test clock-2.1896 {conversion of 2024-12-31} {
+    clock format 1735648496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/31/2024 12:34:56 die xxxi mensis xii annoque mmxxiv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 366 2460676 12 xii 12 12/31/2024 die xxxi mensis xii annoque mmxxiv 24 xxiv 2024}
+test clock-2.1897 {conversion of 2025-01-01} {
+    clock format 1735734896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/01/2025 12:34:56 die i mensis i annoque mmxxv xii h xxxiv m lvi s 20 mm 01 i  1 i Jan 001 2460677 01 i  1 01/01/2025 die i mensis i annoque mmxxv 25 xxv 2025}
+test clock-2.1898 {conversion of 2025-01-31} {
+    clock format 1738326896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/31/2025 12:34:56 die xxxi mensis i annoque mmxxv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2460707 01 i  1 01/31/2025 die xxxi mensis i annoque mmxxv 25 xxv 2025}
+test clock-2.1899 {conversion of 2025-02-01} {
+    clock format 1738413296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/01/2025 12:34:56 die i mensis ii annoque mmxxv xii h xxxiv m lvi s 20 mm 01 i  1 i Feb 032 2460708 02 ii  2 02/01/2025 die i mensis ii annoque mmxxv 25 xxv 2025}
+test clock-2.1900 {conversion of 2025-02-28} {
+    clock format 1740746096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/28/2025 12:34:56 die xxviii mensis ii annoque mmxxv xii h xxxiv m lvi s 20 mm 28 xxviii 28 xxviii Feb 059 2460735 02 ii  2 02/28/2025 die xxviii mensis ii annoque mmxxv 25 xxv 2025}
+test clock-2.1901 {conversion of 2025-03-01} {
+    clock format 1740832496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/01/2025 12:34:56 die i mensis iii annoque mmxxv xii h xxxiv m lvi s 20 mm 01 i  1 i Mar 060 2460736 03 iii  3 03/01/2025 die i mensis iii annoque mmxxv 25 xxv 2025}
+test clock-2.1902 {conversion of 2025-03-31} {
+    clock format 1743424496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/31/2025 12:34:56 die xxxi mensis iii annoque mmxxv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 090 2460766 03 iii  3 03/31/2025 die xxxi mensis iii annoque mmxxv 25 xxv 2025}
+test clock-2.1903 {conversion of 2025-04-01} {
+    clock format 1743510896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/01/2025 12:34:56 die i mensis iv annoque mmxxv xii h xxxiv m lvi s 20 mm 01 i  1 i Apr 091 2460767 04 iv  4 04/01/2025 die i mensis iv annoque mmxxv 25 xxv 2025}
+test clock-2.1904 {conversion of 2025-04-30} {
+    clock format 1746016496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/30/2025 12:34:56 die xxx mensis iv annoque mmxxv xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 120 2460796 04 iv  4 04/30/2025 die xxx mensis iv annoque mmxxv 25 xxv 2025}
+test clock-2.1905 {conversion of 2025-05-01} {
+    clock format 1746102896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/01/2025 12:34:56 die i mensis v annoque mmxxv xii h xxxiv m lvi s 20 mm 01 i  1 i May 121 2460797 05 v  5 05/01/2025 die i mensis v annoque mmxxv 25 xxv 2025}
+test clock-2.1906 {conversion of 2025-05-31} {
+    clock format 1748694896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/31/2025 12:34:56 die xxxi mensis v annoque mmxxv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 151 2460827 05 v  5 05/31/2025 die xxxi mensis v annoque mmxxv 25 xxv 2025}
+test clock-2.1907 {conversion of 2025-06-01} {
+    clock format 1748781296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/01/2025 12:34:56 die i mensis vi annoque mmxxv xii h xxxiv m lvi s 20 mm 01 i  1 i Jun 152 2460828 06 vi  6 06/01/2025 die i mensis vi annoque mmxxv 25 xxv 2025}
+test clock-2.1908 {conversion of 2025-06-30} {
+    clock format 1751286896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/30/2025 12:34:56 die xxx mensis vi annoque mmxxv xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 181 2460857 06 vi  6 06/30/2025 die xxx mensis vi annoque mmxxv 25 xxv 2025}
+test clock-2.1909 {conversion of 2025-07-01} {
+    clock format 1751373296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/01/2025 12:34:56 die i mensis vii annoque mmxxv xii h xxxiv m lvi s 20 mm 01 i  1 i Jul 182 2460858 07 vii  7 07/01/2025 die i mensis vii annoque mmxxv 25 xxv 2025}
+test clock-2.1910 {conversion of 2025-07-31} {
+    clock format 1753965296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/31/2025 12:34:56 die xxxi mensis vii annoque mmxxv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 212 2460888 07 vii  7 07/31/2025 die xxxi mensis vii annoque mmxxv 25 xxv 2025}
+test clock-2.1911 {conversion of 2025-08-01} {
+    clock format 1754051696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/01/2025 12:34:56 die i mensis viii annoque mmxxv xii h xxxiv m lvi s 20 mm 01 i  1 i Aug 213 2460889 08 viii  8 08/01/2025 die i mensis viii annoque mmxxv 25 xxv 2025}
+test clock-2.1912 {conversion of 2025-08-31} {
+    clock format 1756643696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/31/2025 12:34:56 die xxxi mensis viii annoque mmxxv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 243 2460919 08 viii  8 08/31/2025 die xxxi mensis viii annoque mmxxv 25 xxv 2025}
+test clock-2.1913 {conversion of 2025-09-01} {
+    clock format 1756730096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/01/2025 12:34:56 die i mensis ix annoque mmxxv xii h xxxiv m lvi s 20 mm 01 i  1 i Sep 244 2460920 09 ix  9 09/01/2025 die i mensis ix annoque mmxxv 25 xxv 2025}
+test clock-2.1914 {conversion of 2025-09-30} {
+    clock format 1759235696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/30/2025 12:34:56 die xxx mensis ix annoque mmxxv xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 273 2460949 09 ix  9 09/30/2025 die xxx mensis ix annoque mmxxv 25 xxv 2025}
+test clock-2.1915 {conversion of 2025-10-01} {
+    clock format 1759322096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/01/2025 12:34:56 die i mensis x annoque mmxxv xii h xxxiv m lvi s 20 mm 01 i  1 i Oct 274 2460950 10 x 10 10/01/2025 die i mensis x annoque mmxxv 25 xxv 2025}
+test clock-2.1916 {conversion of 2025-10-31} {
+    clock format 1761914096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/31/2025 12:34:56 die xxxi mensis x annoque mmxxv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 304 2460980 10 x 10 10/31/2025 die xxxi mensis x annoque mmxxv 25 xxv 2025}
+test clock-2.1917 {conversion of 2025-11-01} {
+    clock format 1762000496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/01/2025 12:34:56 die i mensis xi annoque mmxxv xii h xxxiv m lvi s 20 mm 01 i  1 i Nov 305 2460981 11 xi 11 11/01/2025 die i mensis xi annoque mmxxv 25 xxv 2025}
+test clock-2.1918 {conversion of 2025-11-30} {
+    clock format 1764506096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/30/2025 12:34:56 die xxx mensis xi annoque mmxxv xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 334 2461010 11 xi 11 11/30/2025 die xxx mensis xi annoque mmxxv 25 xxv 2025}
+test clock-2.1919 {conversion of 2025-12-01} {
+    clock format 1764592496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/01/2025 12:34:56 die i mensis xii annoque mmxxv xii h xxxiv m lvi s 20 mm 01 i  1 i Dec 335 2461011 12 xii 12 12/01/2025 die i mensis xii annoque mmxxv 25 xxv 2025}
+test clock-2.1920 {conversion of 2025-12-31} {
+    clock format 1767184496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/31/2025 12:34:56 die xxxi mensis xii annoque mmxxv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 365 2461041 12 xii 12 12/31/2025 die xxxi mensis xii annoque mmxxv 25 xxv 2025}
+test clock-2.1921 {conversion of 2037-01-01} {
+    clock format 2114426096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/01/2037 12:34:56 die i mensis i annoque mmxxxvii xii h xxxiv m lvi s 20 mm 01 i  1 i Jan 001 2465060 01 i  1 01/01/2037 die i mensis i annoque mmxxxvii 37 xxxvii 2037}
+test clock-2.1922 {conversion of 2037-01-31} {
+    clock format 2117018096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/31/2037 12:34:56 die xxxi mensis i annoque mmxxxvii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2465090 01 i  1 01/31/2037 die xxxi mensis i annoque mmxxxvii 37 xxxvii 2037}
+test clock-2.1923 {conversion of 2037-02-01} {
+    clock format 2117104496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/01/2037 12:34:56 die i mensis ii annoque mmxxxvii xii h xxxiv m lvi s 20 mm 01 i  1 i Feb 032 2465091 02 ii  2 02/01/2037 die i mensis ii annoque mmxxxvii 37 xxxvii 2037}
+test clock-2.1924 {conversion of 2037-02-28} {
+    clock format 2119437296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/28/2037 12:34:56 die xxviii mensis ii annoque mmxxxvii xii h xxxiv m lvi s 20 mm 28 xxviii 28 xxviii Feb 059 2465118 02 ii  2 02/28/2037 die xxviii mensis ii annoque mmxxxvii 37 xxxvii 2037}
+test clock-2.1925 {conversion of 2037-03-01} {
+    clock format 2119523696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/01/2037 12:34:56 die i mensis iii annoque mmxxxvii xii h xxxiv m lvi s 20 mm 01 i  1 i Mar 060 2465119 03 iii  3 03/01/2037 die i mensis iii annoque mmxxxvii 37 xxxvii 2037}
+test clock-2.1926 {conversion of 2037-03-31} {
+    clock format 2122115696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/31/2037 12:34:56 die xxxi mensis iii annoque mmxxxvii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 090 2465149 03 iii  3 03/31/2037 die xxxi mensis iii annoque mmxxxvii 37 xxxvii 2037}
+test clock-2.1927 {conversion of 2037-04-01} {
+    clock format 2122202096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/01/2037 12:34:56 die i mensis iv annoque mmxxxvii xii h xxxiv m lvi s 20 mm 01 i  1 i Apr 091 2465150 04 iv  4 04/01/2037 die i mensis iv annoque mmxxxvii 37 xxxvii 2037}
+test clock-2.1928 {conversion of 2037-04-30} {
+    clock format 2124707696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/30/2037 12:34:56 die xxx mensis iv annoque mmxxxvii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 120 2465179 04 iv  4 04/30/2037 die xxx mensis iv annoque mmxxxvii 37 xxxvii 2037}
+test clock-2.1929 {conversion of 2037-05-01} {
+    clock format 2124794096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/01/2037 12:34:56 die i mensis v annoque mmxxxvii xii h xxxiv m lvi s 20 mm 01 i  1 i May 121 2465180 05 v  5 05/01/2037 die i mensis v annoque mmxxxvii 37 xxxvii 2037}
+test clock-2.1930 {conversion of 2037-05-31} {
+    clock format 2127386096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/31/2037 12:34:56 die xxxi mensis v annoque mmxxxvii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 151 2465210 05 v  5 05/31/2037 die xxxi mensis v annoque mmxxxvii 37 xxxvii 2037}
+test clock-2.1931 {conversion of 2037-06-01} {
+    clock format 2127472496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/01/2037 12:34:56 die i mensis vi annoque mmxxxvii xii h xxxiv m lvi s 20 mm 01 i  1 i Jun 152 2465211 06 vi  6 06/01/2037 die i mensis vi annoque mmxxxvii 37 xxxvii 2037}
+test clock-2.1932 {conversion of 2037-06-30} {
+    clock format 2129978096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/30/2037 12:34:56 die xxx mensis vi annoque mmxxxvii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 181 2465240 06 vi  6 06/30/2037 die xxx mensis vi annoque mmxxxvii 37 xxxvii 2037}
+test clock-2.1933 {conversion of 2037-07-01} {
+    clock format 2130064496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/01/2037 12:34:56 die i mensis vii annoque mmxxxvii xii h xxxiv m lvi s 20 mm 01 i  1 i Jul 182 2465241 07 vii  7 07/01/2037 die i mensis vii annoque mmxxxvii 37 xxxvii 2037}
+test clock-2.1934 {conversion of 2037-07-31} {
+    clock format 2132656496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/31/2037 12:34:56 die xxxi mensis vii annoque mmxxxvii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 212 2465271 07 vii  7 07/31/2037 die xxxi mensis vii annoque mmxxxvii 37 xxxvii 2037}
+test clock-2.1935 {conversion of 2037-08-01} {
+    clock format 2132742896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/01/2037 12:34:56 die i mensis viii annoque mmxxxvii xii h xxxiv m lvi s 20 mm 01 i  1 i Aug 213 2465272 08 viii  8 08/01/2037 die i mensis viii annoque mmxxxvii 37 xxxvii 2037}
+test clock-2.1936 {conversion of 2037-08-31} {
+    clock format 2135334896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/31/2037 12:34:56 die xxxi mensis viii annoque mmxxxvii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 243 2465302 08 viii  8 08/31/2037 die xxxi mensis viii annoque mmxxxvii 37 xxxvii 2037}
+test clock-2.1937 {conversion of 2037-09-01} {
+    clock format 2135421296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/01/2037 12:34:56 die i mensis ix annoque mmxxxvii xii h xxxiv m lvi s 20 mm 01 i  1 i Sep 244 2465303 09 ix  9 09/01/2037 die i mensis ix annoque mmxxxvii 37 xxxvii 2037}
+test clock-2.1938 {conversion of 2037-09-30} {
+    clock format 2137926896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/30/2037 12:34:56 die xxx mensis ix annoque mmxxxvii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 273 2465332 09 ix  9 09/30/2037 die xxx mensis ix annoque mmxxxvii 37 xxxvii 2037}
+test clock-2.1939 {conversion of 2037-10-01} {
+    clock format 2138013296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/01/2037 12:34:56 die i mensis x annoque mmxxxvii xii h xxxiv m lvi s 20 mm 01 i  1 i Oct 274 2465333 10 x 10 10/01/2037 die i mensis x annoque mmxxxvii 37 xxxvii 2037}
+test clock-2.1940 {conversion of 2037-10-31} {
+    clock format 2140605296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/31/2037 12:34:56 die xxxi mensis x annoque mmxxxvii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 304 2465363 10 x 10 10/31/2037 die xxxi mensis x annoque mmxxxvii 37 xxxvii 2037}
+test clock-2.1941 {conversion of 2037-11-01} {
+    clock format 2140691696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/01/2037 12:34:56 die i mensis xi annoque mmxxxvii xii h xxxiv m lvi s 20 mm 01 i  1 i Nov 305 2465364 11 xi 11 11/01/2037 die i mensis xi annoque mmxxxvii 37 xxxvii 2037}
+test clock-2.1942 {conversion of 2037-11-30} {
+    clock format 2143197296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/30/2037 12:34:56 die xxx mensis xi annoque mmxxxvii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 334 2465393 11 xi 11 11/30/2037 die xxx mensis xi annoque mmxxxvii 37 xxxvii 2037}
+test clock-2.1943 {conversion of 2037-12-01} {
+    clock format 2143283696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/01/2037 12:34:56 die i mensis xii annoque mmxxxvii xii h xxxiv m lvi s 20 mm 01 i  1 i Dec 335 2465394 12 xii 12 12/01/2037 die i mensis xii annoque mmxxxvii 37 xxxvii 2037}
+test clock-2.1944 {conversion of 2037-12-31} {
+    clock format 2145875696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/31/2037 12:34:56 die xxxi mensis xii annoque mmxxxvii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 365 2465424 12 xii 12 12/31/2037 die xxxi mensis xii annoque mmxxxvii 37 xxxvii 2037}
+test clock-2.1945 {conversion of 2038-01-01} {
+    clock format 2145962096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/01/2038 12:34:56 die i mensis i annoque mmxxxviii xii h xxxiv m lvi s 20 mm 01 i  1 i Jan 001 2465425 01 i  1 01/01/2038 die i mensis i annoque mmxxxviii 38 xxxviii 2038}
+test clock-2.1946 {conversion of 2038-01-31} {
+    clock format 2148554096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/31/2038 12:34:56 die xxxi mensis i annoque mmxxxviii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2465455 01 i  1 01/31/2038 die xxxi mensis i annoque mmxxxviii 38 xxxviii 2038}
+test clock-2.1947 {conversion of 2038-02-01} {
+    clock format 2148640496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/01/2038 12:34:56 die i mensis ii annoque mmxxxviii xii h xxxiv m lvi s 20 mm 01 i  1 i Feb 032 2465456 02 ii  2 02/01/2038 die i mensis ii annoque mmxxxviii 38 xxxviii 2038}
+test clock-2.1948 {conversion of 2038-02-28} {
+    clock format 2150973296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/28/2038 12:34:56 die xxviii mensis ii annoque mmxxxviii xii h xxxiv m lvi s 20 mm 28 xxviii 28 xxviii Feb 059 2465483 02 ii  2 02/28/2038 die xxviii mensis ii annoque mmxxxviii 38 xxxviii 2038}
+test clock-2.1949 {conversion of 2038-03-01} {
+    clock format 2151059696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/01/2038 12:34:56 die i mensis iii annoque mmxxxviii xii h xxxiv m lvi s 20 mm 01 i  1 i Mar 060 2465484 03 iii  3 03/01/2038 die i mensis iii annoque mmxxxviii 38 xxxviii 2038}
+test clock-2.1950 {conversion of 2038-03-31} {
+    clock format 2153651696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/31/2038 12:34:56 die xxxi mensis iii annoque mmxxxviii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 090 2465514 03 iii  3 03/31/2038 die xxxi mensis iii annoque mmxxxviii 38 xxxviii 2038}
+test clock-2.1951 {conversion of 2038-04-01} {
+    clock format 2153738096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/01/2038 12:34:56 die i mensis iv annoque mmxxxviii xii h xxxiv m lvi s 20 mm 01 i  1 i Apr 091 2465515 04 iv  4 04/01/2038 die i mensis iv annoque mmxxxviii 38 xxxviii 2038}
+test clock-2.1952 {conversion of 2038-04-30} {
+    clock format 2156243696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/30/2038 12:34:56 die xxx mensis iv annoque mmxxxviii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 120 2465544 04 iv  4 04/30/2038 die xxx mensis iv annoque mmxxxviii 38 xxxviii 2038}
+test clock-2.1953 {conversion of 2038-05-01} {
+    clock format 2156330096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/01/2038 12:34:56 die i mensis v annoque mmxxxviii xii h xxxiv m lvi s 20 mm 01 i  1 i May 121 2465545 05 v  5 05/01/2038 die i mensis v annoque mmxxxviii 38 xxxviii 2038}
+test clock-2.1954 {conversion of 2038-05-31} {
+    clock format 2158922096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/31/2038 12:34:56 die xxxi mensis v annoque mmxxxviii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 151 2465575 05 v  5 05/31/2038 die xxxi mensis v annoque mmxxxviii 38 xxxviii 2038}
+test clock-2.1955 {conversion of 2038-06-01} {
+    clock format 2159008496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/01/2038 12:34:56 die i mensis vi annoque mmxxxviii xii h xxxiv m lvi s 20 mm 01 i  1 i Jun 152 2465576 06 vi  6 06/01/2038 die i mensis vi annoque mmxxxviii 38 xxxviii 2038}
+test clock-2.1956 {conversion of 2038-06-30} {
+    clock format 2161514096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/30/2038 12:34:56 die xxx mensis vi annoque mmxxxviii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 181 2465605 06 vi  6 06/30/2038 die xxx mensis vi annoque mmxxxviii 38 xxxviii 2038}
+test clock-2.1957 {conversion of 2038-07-01} {
+    clock format 2161600496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/01/2038 12:34:56 die i mensis vii annoque mmxxxviii xii h xxxiv m lvi s 20 mm 01 i  1 i Jul 182 2465606 07 vii  7 07/01/2038 die i mensis vii annoque mmxxxviii 38 xxxviii 2038}
+test clock-2.1958 {conversion of 2038-07-31} {
+    clock format 2164192496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/31/2038 12:34:56 die xxxi mensis vii annoque mmxxxviii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 212 2465636 07 vii  7 07/31/2038 die xxxi mensis vii annoque mmxxxviii 38 xxxviii 2038}
+test clock-2.1959 {conversion of 2038-08-01} {
+    clock format 2164278896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/01/2038 12:34:56 die i mensis viii annoque mmxxxviii xii h xxxiv m lvi s 20 mm 01 i  1 i Aug 213 2465637 08 viii  8 08/01/2038 die i mensis viii annoque mmxxxviii 38 xxxviii 2038}
+test clock-2.1960 {conversion of 2038-08-31} {
+    clock format 2166870896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/31/2038 12:34:56 die xxxi mensis viii annoque mmxxxviii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 243 2465667 08 viii  8 08/31/2038 die xxxi mensis viii annoque mmxxxviii 38 xxxviii 2038}
+test clock-2.1961 {conversion of 2038-09-01} {
+    clock format 2166957296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/01/2038 12:34:56 die i mensis ix annoque mmxxxviii xii h xxxiv m lvi s 20 mm 01 i  1 i Sep 244 2465668 09 ix  9 09/01/2038 die i mensis ix annoque mmxxxviii 38 xxxviii 2038}
+test clock-2.1962 {conversion of 2038-09-30} {
+    clock format 2169462896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/30/2038 12:34:56 die xxx mensis ix annoque mmxxxviii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 273 2465697 09 ix  9 09/30/2038 die xxx mensis ix annoque mmxxxviii 38 xxxviii 2038}
+test clock-2.1963 {conversion of 2038-10-01} {
+    clock format 2169549296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/01/2038 12:34:56 die i mensis x annoque mmxxxviii xii h xxxiv m lvi s 20 mm 01 i  1 i Oct 274 2465698 10 x 10 10/01/2038 die i mensis x annoque mmxxxviii 38 xxxviii 2038}
+test clock-2.1964 {conversion of 2038-10-31} {
+    clock format 2172141296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/31/2038 12:34:56 die xxxi mensis x annoque mmxxxviii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 304 2465728 10 x 10 10/31/2038 die xxxi mensis x annoque mmxxxviii 38 xxxviii 2038}
+test clock-2.1965 {conversion of 2038-11-01} {
+    clock format 2172227696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/01/2038 12:34:56 die i mensis xi annoque mmxxxviii xii h xxxiv m lvi s 20 mm 01 i  1 i Nov 305 2465729 11 xi 11 11/01/2038 die i mensis xi annoque mmxxxviii 38 xxxviii 2038}
+test clock-2.1966 {conversion of 2038-11-30} {
+    clock format 2174733296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/30/2038 12:34:56 die xxx mensis xi annoque mmxxxviii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 334 2465758 11 xi 11 11/30/2038 die xxx mensis xi annoque mmxxxviii 38 xxxviii 2038}
+test clock-2.1967 {conversion of 2038-12-01} {
+    clock format 2174819696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/01/2038 12:34:56 die i mensis xii annoque mmxxxviii xii h xxxiv m lvi s 20 mm 01 i  1 i Dec 335 2465759 12 xii 12 12/01/2038 die i mensis xii annoque mmxxxviii 38 xxxviii 2038}
+test clock-2.1968 {conversion of 2038-12-31} {
+    clock format 2177411696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/31/2038 12:34:56 die xxxi mensis xii annoque mmxxxviii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 365 2465789 12 xii 12 12/31/2038 die xxxi mensis xii annoque mmxxxviii 38 xxxviii 2038}
+test clock-2.1969 {conversion of 2039-01-01} {
+    clock format 2177498096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/01/2039 12:34:56 die i mensis i annoque mmxxxix xii h xxxiv m lvi s 20 mm 01 i  1 i Jan 001 2465790 01 i  1 01/01/2039 die i mensis i annoque mmxxxix 39 xxxix 2039}
+test clock-2.1970 {conversion of 2039-01-31} {
+    clock format 2180090096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/31/2039 12:34:56 die xxxi mensis i annoque mmxxxix xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2465820 01 i  1 01/31/2039 die xxxi mensis i annoque mmxxxix 39 xxxix 2039}
+test clock-2.1971 {conversion of 2039-02-01} {
+    clock format 2180176496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/01/2039 12:34:56 die i mensis ii annoque mmxxxix xii h xxxiv m lvi s 20 mm 01 i  1 i Feb 032 2465821 02 ii  2 02/01/2039 die i mensis ii annoque mmxxxix 39 xxxix 2039}
+test clock-2.1972 {conversion of 2039-02-28} {
+    clock format 2182509296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/28/2039 12:34:56 die xxviii mensis ii annoque mmxxxix xii h xxxiv m lvi s 20 mm 28 xxviii 28 xxviii Feb 059 2465848 02 ii  2 02/28/2039 die xxviii mensis ii annoque mmxxxix 39 xxxix 2039}
+test clock-2.1973 {conversion of 2039-03-01} {
+    clock format 2182595696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/01/2039 12:34:56 die i mensis iii annoque mmxxxix xii h xxxiv m lvi s 20 mm 01 i  1 i Mar 060 2465849 03 iii  3 03/01/2039 die i mensis iii annoque mmxxxix 39 xxxix 2039}
+test clock-2.1974 {conversion of 2039-03-31} {
+    clock format 2185187696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/31/2039 12:34:56 die xxxi mensis iii annoque mmxxxix xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 090 2465879 03 iii  3 03/31/2039 die xxxi mensis iii annoque mmxxxix 39 xxxix 2039}
+test clock-2.1975 {conversion of 2039-04-01} {
+    clock format 2185274096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/01/2039 12:34:56 die i mensis iv annoque mmxxxix xii h xxxiv m lvi s 20 mm 01 i  1 i Apr 091 2465880 04 iv  4 04/01/2039 die i mensis iv annoque mmxxxix 39 xxxix 2039}
+test clock-2.1976 {conversion of 2039-04-30} {
+    clock format 2187779696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/30/2039 12:34:56 die xxx mensis iv annoque mmxxxix xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 120 2465909 04 iv  4 04/30/2039 die xxx mensis iv annoque mmxxxix 39 xxxix 2039}
+test clock-2.1977 {conversion of 2039-05-01} {
+    clock format 2187866096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/01/2039 12:34:56 die i mensis v annoque mmxxxix xii h xxxiv m lvi s 20 mm 01 i  1 i May 121 2465910 05 v  5 05/01/2039 die i mensis v annoque mmxxxix 39 xxxix 2039}
+test clock-2.1978 {conversion of 2039-05-31} {
+    clock format 2190458096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/31/2039 12:34:56 die xxxi mensis v annoque mmxxxix xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 151 2465940 05 v  5 05/31/2039 die xxxi mensis v annoque mmxxxix 39 xxxix 2039}
+test clock-2.1979 {conversion of 2039-06-01} {
+    clock format 2190544496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/01/2039 12:34:56 die i mensis vi annoque mmxxxix xii h xxxiv m lvi s 20 mm 01 i  1 i Jun 152 2465941 06 vi  6 06/01/2039 die i mensis vi annoque mmxxxix 39 xxxix 2039}
+test clock-2.1980 {conversion of 2039-06-30} {
+    clock format 2193050096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/30/2039 12:34:56 die xxx mensis vi annoque mmxxxix xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 181 2465970 06 vi  6 06/30/2039 die xxx mensis vi annoque mmxxxix 39 xxxix 2039}
+test clock-2.1981 {conversion of 2039-07-01} {
+    clock format 2193136496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/01/2039 12:34:56 die i mensis vii annoque mmxxxix xii h xxxiv m lvi s 20 mm 01 i  1 i Jul 182 2465971 07 vii  7 07/01/2039 die i mensis vii annoque mmxxxix 39 xxxix 2039}
+test clock-2.1982 {conversion of 2039-07-31} {
+    clock format 2195728496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/31/2039 12:34:56 die xxxi mensis vii annoque mmxxxix xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 212 2466001 07 vii  7 07/31/2039 die xxxi mensis vii annoque mmxxxix 39 xxxix 2039}
+test clock-2.1983 {conversion of 2039-08-01} {
+    clock format 2195814896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/01/2039 12:34:56 die i mensis viii annoque mmxxxix xii h xxxiv m lvi s 20 mm 01 i  1 i Aug 213 2466002 08 viii  8 08/01/2039 die i mensis viii annoque mmxxxix 39 xxxix 2039}
+test clock-2.1984 {conversion of 2039-08-31} {
+    clock format 2198406896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/31/2039 12:34:56 die xxxi mensis viii annoque mmxxxix xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 243 2466032 08 viii  8 08/31/2039 die xxxi mensis viii annoque mmxxxix 39 xxxix 2039}
+test clock-2.1985 {conversion of 2039-09-01} {
+    clock format 2198493296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/01/2039 12:34:56 die i mensis ix annoque mmxxxix xii h xxxiv m lvi s 20 mm 01 i  1 i Sep 244 2466033 09 ix  9 09/01/2039 die i mensis ix annoque mmxxxix 39 xxxix 2039}
+test clock-2.1986 {conversion of 2039-09-30} {
+    clock format 2200998896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/30/2039 12:34:56 die xxx mensis ix annoque mmxxxix xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 273 2466062 09 ix  9 09/30/2039 die xxx mensis ix annoque mmxxxix 39 xxxix 2039}
+test clock-2.1987 {conversion of 2039-10-01} {
+    clock format 2201085296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/01/2039 12:34:56 die i mensis x annoque mmxxxix xii h xxxiv m lvi s 20 mm 01 i  1 i Oct 274 2466063 10 x 10 10/01/2039 die i mensis x annoque mmxxxix 39 xxxix 2039}
+test clock-2.1988 {conversion of 2039-10-31} {
+    clock format 2203677296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/31/2039 12:34:56 die xxxi mensis x annoque mmxxxix xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 304 2466093 10 x 10 10/31/2039 die xxxi mensis x annoque mmxxxix 39 xxxix 2039}
+test clock-2.1989 {conversion of 2039-11-01} {
+    clock format 2203763696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/01/2039 12:34:56 die i mensis xi annoque mmxxxix xii h xxxiv m lvi s 20 mm 01 i  1 i Nov 305 2466094 11 xi 11 11/01/2039 die i mensis xi annoque mmxxxix 39 xxxix 2039}
+test clock-2.1990 {conversion of 2039-11-30} {
+    clock format 2206269296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/30/2039 12:34:56 die xxx mensis xi annoque mmxxxix xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 334 2466123 11 xi 11 11/30/2039 die xxx mensis xi annoque mmxxxix 39 xxxix 2039}
+test clock-2.1991 {conversion of 2039-12-01} {
+    clock format 2206355696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/01/2039 12:34:56 die i mensis xii annoque mmxxxix xii h xxxiv m lvi s 20 mm 01 i  1 i Dec 335 2466124 12 xii 12 12/01/2039 die i mensis xii annoque mmxxxix 39 xxxix 2039}
+test clock-2.1992 {conversion of 2039-12-31} {
+    clock format 2208947696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/31/2039 12:34:56 die xxxi mensis xii annoque mmxxxix xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 365 2466154 12 xii 12 12/31/2039 die xxxi mensis xii annoque mmxxxix 39 xxxix 2039}
+test clock-2.1993 {conversion of 2040-01-01} {
+    clock format 2209034096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/01/2040 12:34:56 die i mensis i annoque mmxl xii h xxxiv m lvi s 20 mm 01 i  1 i Jan 001 2466155 01 i  1 01/01/2040 die i mensis i annoque mmxl 40 xl 2040}
+test clock-2.1994 {conversion of 2040-01-31} {
+    clock format 2211626096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/31/2040 12:34:56 die xxxi mensis i annoque mmxl xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2466185 01 i  1 01/31/2040 die xxxi mensis i annoque mmxl 40 xl 2040}
+test clock-2.1995 {conversion of 2040-02-01} {
+    clock format 2211712496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/01/2040 12:34:56 die i mensis ii annoque mmxl xii h xxxiv m lvi s 20 mm 01 i  1 i Feb 032 2466186 02 ii  2 02/01/2040 die i mensis ii annoque mmxl 40 xl 2040}
+test clock-2.1996 {conversion of 2040-02-29} {
+    clock format 2214131696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/29/2040 12:34:56 die xxix mensis ii annoque mmxl xii h xxxiv m lvi s 20 mm 29 xxix 29 xxix Feb 060 2466214 02 ii  2 02/29/2040 die xxix mensis ii annoque mmxl 40 xl 2040}
+test clock-2.1997 {conversion of 2040-03-01} {
+    clock format 2214218096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/01/2040 12:34:56 die i mensis iii annoque mmxl xii h xxxiv m lvi s 20 mm 01 i  1 i Mar 061 2466215 03 iii  3 03/01/2040 die i mensis iii annoque mmxl 40 xl 2040}
+test clock-2.1998 {conversion of 2040-03-31} {
+    clock format 2216810096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/31/2040 12:34:56 die xxxi mensis iii annoque mmxl xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 091 2466245 03 iii  3 03/31/2040 die xxxi mensis iii annoque mmxl 40 xl 2040}
+test clock-2.1999 {conversion of 2040-04-01} {
+    clock format 2216896496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/01/2040 12:34:56 die i mensis iv annoque mmxl xii h xxxiv m lvi s 20 mm 01 i  1 i Apr 092 2466246 04 iv  4 04/01/2040 die i mensis iv annoque mmxl 40 xl 2040}
+test clock-2.2000 {conversion of 2040-04-30} {
+    clock format 2219402096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/30/2040 12:34:56 die xxx mensis iv annoque mmxl xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 121 2466275 04 iv  4 04/30/2040 die xxx mensis iv annoque mmxl 40 xl 2040}
+test clock-2.2001 {conversion of 2040-05-01} {
+    clock format 2219488496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/01/2040 12:34:56 die i mensis v annoque mmxl xii h xxxiv m lvi s 20 mm 01 i  1 i May 122 2466276 05 v  5 05/01/2040 die i mensis v annoque mmxl 40 xl 2040}
+test clock-2.2002 {conversion of 2040-05-31} {
+    clock format 2222080496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/31/2040 12:34:56 die xxxi mensis v annoque mmxl xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 152 2466306 05 v  5 05/31/2040 die xxxi mensis v annoque mmxl 40 xl 2040}
+test clock-2.2003 {conversion of 2040-06-01} {
+    clock format 2222166896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/01/2040 12:34:56 die i mensis vi annoque mmxl xii h xxxiv m lvi s 20 mm 01 i  1 i Jun 153 2466307 06 vi  6 06/01/2040 die i mensis vi annoque mmxl 40 xl 2040}
+test clock-2.2004 {conversion of 2040-06-30} {
+    clock format 2224672496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/30/2040 12:34:56 die xxx mensis vi annoque mmxl xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 182 2466336 06 vi  6 06/30/2040 die xxx mensis vi annoque mmxl 40 xl 2040}
+test clock-2.2005 {conversion of 2040-07-01} {
+    clock format 2224758896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/01/2040 12:34:56 die i mensis vii annoque mmxl xii h xxxiv m lvi s 20 mm 01 i  1 i Jul 183 2466337 07 vii  7 07/01/2040 die i mensis vii annoque mmxl 40 xl 2040}
+test clock-2.2006 {conversion of 2040-07-31} {
+    clock format 2227350896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/31/2040 12:34:56 die xxxi mensis vii annoque mmxl xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 213 2466367 07 vii  7 07/31/2040 die xxxi mensis vii annoque mmxl 40 xl 2040}
+test clock-2.2007 {conversion of 2040-08-01} {
+    clock format 2227437296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/01/2040 12:34:56 die i mensis viii annoque mmxl xii h xxxiv m lvi s 20 mm 01 i  1 i Aug 214 2466368 08 viii  8 08/01/2040 die i mensis viii annoque mmxl 40 xl 2040}
+test clock-2.2008 {conversion of 2040-08-31} {
+    clock format 2230029296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/31/2040 12:34:56 die xxxi mensis viii annoque mmxl xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 244 2466398 08 viii  8 08/31/2040 die xxxi mensis viii annoque mmxl 40 xl 2040}
+test clock-2.2009 {conversion of 2040-09-01} {
+    clock format 2230115696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/01/2040 12:34:56 die i mensis ix annoque mmxl xii h xxxiv m lvi s 20 mm 01 i  1 i Sep 245 2466399 09 ix  9 09/01/2040 die i mensis ix annoque mmxl 40 xl 2040}
+test clock-2.2010 {conversion of 2040-09-30} {
+    clock format 2232621296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/30/2040 12:34:56 die xxx mensis ix annoque mmxl xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 274 2466428 09 ix  9 09/30/2040 die xxx mensis ix annoque mmxl 40 xl 2040}
+test clock-2.2011 {conversion of 2040-10-01} {
+    clock format 2232707696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/01/2040 12:34:56 die i mensis x annoque mmxl xii h xxxiv m lvi s 20 mm 01 i  1 i Oct 275 2466429 10 x 10 10/01/2040 die i mensis x annoque mmxl 40 xl 2040}
+test clock-2.2012 {conversion of 2040-10-31} {
+    clock format 2235299696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/31/2040 12:34:56 die xxxi mensis x annoque mmxl xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 305 2466459 10 x 10 10/31/2040 die xxxi mensis x annoque mmxl 40 xl 2040}
+test clock-2.2013 {conversion of 2040-11-01} {
+    clock format 2235386096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/01/2040 12:34:56 die i mensis xi annoque mmxl xii h xxxiv m lvi s 20 mm 01 i  1 i Nov 306 2466460 11 xi 11 11/01/2040 die i mensis xi annoque mmxl 40 xl 2040}
+test clock-2.2014 {conversion of 2040-11-30} {
+    clock format 2237891696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/30/2040 12:34:56 die xxx mensis xi annoque mmxl xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 335 2466489 11 xi 11 11/30/2040 die xxx mensis xi annoque mmxl 40 xl 2040}
+test clock-2.2015 {conversion of 2040-12-01} {
+    clock format 2237978096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/01/2040 12:34:56 die i mensis xii annoque mmxl xii h xxxiv m lvi s 20 mm 01 i  1 i Dec 336 2466490 12 xii 12 12/01/2040 die i mensis xii annoque mmxl 40 xl 2040}
+test clock-2.2016 {conversion of 2040-12-31} {
+    clock format 2240570096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/31/2040 12:34:56 die xxxi mensis xii annoque mmxl xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 366 2466520 12 xii 12 12/31/2040 die xxxi mensis xii annoque mmxl 40 xl 2040}
+test clock-2.2017 {conversion of 2041-01-01} {
+    clock format 2240656496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/01/2041 12:34:56 die i mensis i annoque mmxli xii h xxxiv m lvi s 20 mm 01 i  1 i Jan 001 2466521 01 i  1 01/01/2041 die i mensis i annoque mmxli 41 xli 2041}
+test clock-2.2018 {conversion of 2041-01-31} {
+    clock format 2243248496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/31/2041 12:34:56 die xxxi mensis i annoque mmxli xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2466551 01 i  1 01/31/2041 die xxxi mensis i annoque mmxli 41 xli 2041}
+test clock-2.2019 {conversion of 2041-02-01} {
+    clock format 2243334896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/01/2041 12:34:56 die i mensis ii annoque mmxli xii h xxxiv m lvi s 20 mm 01 i  1 i Feb 032 2466552 02 ii  2 02/01/2041 die i mensis ii annoque mmxli 41 xli 2041}
+test clock-2.2020 {conversion of 2041-02-28} {
+    clock format 2245667696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/28/2041 12:34:56 die xxviii mensis ii annoque mmxli xii h xxxiv m lvi s 20 mm 28 xxviii 28 xxviii Feb 059 2466579 02 ii  2 02/28/2041 die xxviii mensis ii annoque mmxli 41 xli 2041}
+test clock-2.2021 {conversion of 2041-03-01} {
+    clock format 2245754096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/01/2041 12:34:56 die i mensis iii annoque mmxli xii h xxxiv m lvi s 20 mm 01 i  1 i Mar 060 2466580 03 iii  3 03/01/2041 die i mensis iii annoque mmxli 41 xli 2041}
+test clock-2.2022 {conversion of 2041-03-31} {
+    clock format 2248346096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/31/2041 12:34:56 die xxxi mensis iii annoque mmxli xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 090 2466610 03 iii  3 03/31/2041 die xxxi mensis iii annoque mmxli 41 xli 2041}
+test clock-2.2023 {conversion of 2041-04-01} {
+    clock format 2248432496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/01/2041 12:34:56 die i mensis iv annoque mmxli xii h xxxiv m lvi s 20 mm 01 i  1 i Apr 091 2466611 04 iv  4 04/01/2041 die i mensis iv annoque mmxli 41 xli 2041}
+test clock-2.2024 {conversion of 2041-04-30} {
+    clock format 2250938096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/30/2041 12:34:56 die xxx mensis iv annoque mmxli xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 120 2466640 04 iv  4 04/30/2041 die xxx mensis iv annoque mmxli 41 xli 2041}
+test clock-2.2025 {conversion of 2041-05-01} {
+    clock format 2251024496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/01/2041 12:34:56 die i mensis v annoque mmxli xii h xxxiv m lvi s 20 mm 01 i  1 i May 121 2466641 05 v  5 05/01/2041 die i mensis v annoque mmxli 41 xli 2041}
+test clock-2.2026 {conversion of 2041-05-31} {
+    clock format 2253616496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/31/2041 12:34:56 die xxxi mensis v annoque mmxli xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 151 2466671 05 v  5 05/31/2041 die xxxi mensis v annoque mmxli 41 xli 2041}
+test clock-2.2027 {conversion of 2041-06-01} {
+    clock format 2253702896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/01/2041 12:34:56 die i mensis vi annoque mmxli xii h xxxiv m lvi s 20 mm 01 i  1 i Jun 152 2466672 06 vi  6 06/01/2041 die i mensis vi annoque mmxli 41 xli 2041}
+test clock-2.2028 {conversion of 2041-06-30} {
+    clock format 2256208496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/30/2041 12:34:56 die xxx mensis vi annoque mmxli xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 181 2466701 06 vi  6 06/30/2041 die xxx mensis vi annoque mmxli 41 xli 2041}
+test clock-2.2029 {conversion of 2041-07-01} {
+    clock format 2256294896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/01/2041 12:34:56 die i mensis vii annoque mmxli xii h xxxiv m lvi s 20 mm 01 i  1 i Jul 182 2466702 07 vii  7 07/01/2041 die i mensis vii annoque mmxli 41 xli 2041}
+test clock-2.2030 {conversion of 2041-07-31} {
+    clock format 2258886896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/31/2041 12:34:56 die xxxi mensis vii annoque mmxli xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 212 2466732 07 vii  7 07/31/2041 die xxxi mensis vii annoque mmxli 41 xli 2041}
+test clock-2.2031 {conversion of 2041-08-01} {
+    clock format 2258973296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/01/2041 12:34:56 die i mensis viii annoque mmxli xii h xxxiv m lvi s 20 mm 01 i  1 i Aug 213 2466733 08 viii  8 08/01/2041 die i mensis viii annoque mmxli 41 xli 2041}
+test clock-2.2032 {conversion of 2041-08-31} {
+    clock format 2261565296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/31/2041 12:34:56 die xxxi mensis viii annoque mmxli xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 243 2466763 08 viii  8 08/31/2041 die xxxi mensis viii annoque mmxli 41 xli 2041}
+test clock-2.2033 {conversion of 2041-09-01} {
+    clock format 2261651696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/01/2041 12:34:56 die i mensis ix annoque mmxli xii h xxxiv m lvi s 20 mm 01 i  1 i Sep 244 2466764 09 ix  9 09/01/2041 die i mensis ix annoque mmxli 41 xli 2041}
+test clock-2.2034 {conversion of 2041-09-30} {
+    clock format 2264157296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/30/2041 12:34:56 die xxx mensis ix annoque mmxli xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 273 2466793 09 ix  9 09/30/2041 die xxx mensis ix annoque mmxli 41 xli 2041}
+test clock-2.2035 {conversion of 2041-10-01} {
+    clock format 2264243696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/01/2041 12:34:56 die i mensis x annoque mmxli xii h xxxiv m lvi s 20 mm 01 i  1 i Oct 274 2466794 10 x 10 10/01/2041 die i mensis x annoque mmxli 41 xli 2041}
+test clock-2.2036 {conversion of 2041-10-31} {
+    clock format 2266835696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/31/2041 12:34:56 die xxxi mensis x annoque mmxli xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 304 2466824 10 x 10 10/31/2041 die xxxi mensis x annoque mmxli 41 xli 2041}
+test clock-2.2037 {conversion of 2041-11-01} {
+    clock format 2266922096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/01/2041 12:34:56 die i mensis xi annoque mmxli xii h xxxiv m lvi s 20 mm 01 i  1 i Nov 305 2466825 11 xi 11 11/01/2041 die i mensis xi annoque mmxli 41 xli 2041}
+test clock-2.2038 {conversion of 2041-11-30} {
+    clock format 2269427696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/30/2041 12:34:56 die xxx mensis xi annoque mmxli xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 334 2466854 11 xi 11 11/30/2041 die xxx mensis xi annoque mmxli 41 xli 2041}
+test clock-2.2039 {conversion of 2041-12-01} {
+    clock format 2269514096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/01/2041 12:34:56 die i mensis xii annoque mmxli xii h xxxiv m lvi s 20 mm 01 i  1 i Dec 335 2466855 12 xii 12 12/01/2041 die i mensis xii annoque mmxli 41 xli 2041}
+test clock-2.2040 {conversion of 2041-12-31} {
+    clock format 2272106096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/31/2041 12:34:56 die xxxi mensis xii annoque mmxli xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 365 2466885 12 xii 12 12/31/2041 die xxxi mensis xii annoque mmxli 41 xli 2041}
+test clock-2.2041 {conversion of 2042-01-01} {
+    clock format 2272192496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/01/2042 12:34:56 die i mensis i annoque mmxlii xii h xxxiv m lvi s 20 mm 01 i  1 i Jan 001 2466886 01 i  1 01/01/2042 die i mensis i annoque mmxlii 42 xlii 2042}
+test clock-2.2042 {conversion of 2042-01-31} {
+    clock format 2274784496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/31/2042 12:34:56 die xxxi mensis i annoque mmxlii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2466916 01 i  1 01/31/2042 die xxxi mensis i annoque mmxlii 42 xlii 2042}
+test clock-2.2043 {conversion of 2042-02-01} {
+    clock format 2274870896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/01/2042 12:34:56 die i mensis ii annoque mmxlii xii h xxxiv m lvi s 20 mm 01 i  1 i Feb 032 2466917 02 ii  2 02/01/2042 die i mensis ii annoque mmxlii 42 xlii 2042}
+test clock-2.2044 {conversion of 2042-02-28} {
+    clock format 2277203696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/28/2042 12:34:56 die xxviii mensis ii annoque mmxlii xii h xxxiv m lvi s 20 mm 28 xxviii 28 xxviii Feb 059 2466944 02 ii  2 02/28/2042 die xxviii mensis ii annoque mmxlii 42 xlii 2042}
+test clock-2.2045 {conversion of 2042-03-01} {
+    clock format 2277290096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/01/2042 12:34:56 die i mensis iii annoque mmxlii xii h xxxiv m lvi s 20 mm 01 i  1 i Mar 060 2466945 03 iii  3 03/01/2042 die i mensis iii annoque mmxlii 42 xlii 2042}
+test clock-2.2046 {conversion of 2042-03-31} {
+    clock format 2279882096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/31/2042 12:34:56 die xxxi mensis iii annoque mmxlii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 090 2466975 03 iii  3 03/31/2042 die xxxi mensis iii annoque mmxlii 42 xlii 2042}
+test clock-2.2047 {conversion of 2042-04-01} {
+    clock format 2279968496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/01/2042 12:34:56 die i mensis iv annoque mmxlii xii h xxxiv m lvi s 20 mm 01 i  1 i Apr 091 2466976 04 iv  4 04/01/2042 die i mensis iv annoque mmxlii 42 xlii 2042}
+test clock-2.2048 {conversion of 2042-04-30} {
+    clock format 2282474096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/30/2042 12:34:56 die xxx mensis iv annoque mmxlii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 120 2467005 04 iv  4 04/30/2042 die xxx mensis iv annoque mmxlii 42 xlii 2042}
+test clock-2.2049 {conversion of 2042-05-01} {
+    clock format 2282560496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/01/2042 12:34:56 die i mensis v annoque mmxlii xii h xxxiv m lvi s 20 mm 01 i  1 i May 121 2467006 05 v  5 05/01/2042 die i mensis v annoque mmxlii 42 xlii 2042}
+test clock-2.2050 {conversion of 2042-05-31} {
+    clock format 2285152496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/31/2042 12:34:56 die xxxi mensis v annoque mmxlii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 151 2467036 05 v  5 05/31/2042 die xxxi mensis v annoque mmxlii 42 xlii 2042}
+test clock-2.2051 {conversion of 2042-06-01} {
+    clock format 2285238896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/01/2042 12:34:56 die i mensis vi annoque mmxlii xii h xxxiv m lvi s 20 mm 01 i  1 i Jun 152 2467037 06 vi  6 06/01/2042 die i mensis vi annoque mmxlii 42 xlii 2042}
+test clock-2.2052 {conversion of 2042-06-30} {
+    clock format 2287744496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/30/2042 12:34:56 die xxx mensis vi annoque mmxlii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 181 2467066 06 vi  6 06/30/2042 die xxx mensis vi annoque mmxlii 42 xlii 2042}
+test clock-2.2053 {conversion of 2042-07-01} {
+    clock format 2287830896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/01/2042 12:34:56 die i mensis vii annoque mmxlii xii h xxxiv m lvi s 20 mm 01 i  1 i Jul 182 2467067 07 vii  7 07/01/2042 die i mensis vii annoque mmxlii 42 xlii 2042}
+test clock-2.2054 {conversion of 2042-07-31} {
+    clock format 2290422896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/31/2042 12:34:56 die xxxi mensis vii annoque mmxlii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 212 2467097 07 vii  7 07/31/2042 die xxxi mensis vii annoque mmxlii 42 xlii 2042}
+test clock-2.2055 {conversion of 2042-08-01} {
+    clock format 2290509296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/01/2042 12:34:56 die i mensis viii annoque mmxlii xii h xxxiv m lvi s 20 mm 01 i  1 i Aug 213 2467098 08 viii  8 08/01/2042 die i mensis viii annoque mmxlii 42 xlii 2042}
+test clock-2.2056 {conversion of 2042-08-31} {
+    clock format 2293101296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/31/2042 12:34:56 die xxxi mensis viii annoque mmxlii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 243 2467128 08 viii  8 08/31/2042 die xxxi mensis viii annoque mmxlii 42 xlii 2042}
+test clock-2.2057 {conversion of 2042-09-01} {
+    clock format 2293187696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/01/2042 12:34:56 die i mensis ix annoque mmxlii xii h xxxiv m lvi s 20 mm 01 i  1 i Sep 244 2467129 09 ix  9 09/01/2042 die i mensis ix annoque mmxlii 42 xlii 2042}
+test clock-2.2058 {conversion of 2042-09-30} {
+    clock format 2295693296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/30/2042 12:34:56 die xxx mensis ix annoque mmxlii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 273 2467158 09 ix  9 09/30/2042 die xxx mensis ix annoque mmxlii 42 xlii 2042}
+test clock-2.2059 {conversion of 2042-10-01} {
+    clock format 2295779696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/01/2042 12:34:56 die i mensis x annoque mmxlii xii h xxxiv m lvi s 20 mm 01 i  1 i Oct 274 2467159 10 x 10 10/01/2042 die i mensis x annoque mmxlii 42 xlii 2042}
+test clock-2.2060 {conversion of 2042-10-31} {
+    clock format 2298371696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/31/2042 12:34:56 die xxxi mensis x annoque mmxlii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 304 2467189 10 x 10 10/31/2042 die xxxi mensis x annoque mmxlii 42 xlii 2042}
+test clock-2.2061 {conversion of 2042-11-01} {
+    clock format 2298458096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/01/2042 12:34:56 die i mensis xi annoque mmxlii xii h xxxiv m lvi s 20 mm 01 i  1 i Nov 305 2467190 11 xi 11 11/01/2042 die i mensis xi annoque mmxlii 42 xlii 2042}
+test clock-2.2062 {conversion of 2042-11-30} {
+    clock format 2300963696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/30/2042 12:34:56 die xxx mensis xi annoque mmxlii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 334 2467219 11 xi 11 11/30/2042 die xxx mensis xi annoque mmxlii 42 xlii 2042}
+test clock-2.2063 {conversion of 2042-12-01} {
+    clock format 2301050096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/01/2042 12:34:56 die i mensis xii annoque mmxlii xii h xxxiv m lvi s 20 mm 01 i  1 i Dec 335 2467220 12 xii 12 12/01/2042 die i mensis xii annoque mmxlii 42 xlii 2042}
+test clock-2.2064 {conversion of 2042-12-31} {
+    clock format 2303642096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/31/2042 12:34:56 die xxxi mensis xii annoque mmxlii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 365 2467250 12 xii 12 12/31/2042 die xxxi mensis xii annoque mmxlii 42 xlii 2042}
+test clock-2.2065 {conversion of 2043-01-01} {
+    clock format 2303728496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/01/2043 12:34:56 die i mensis i annoque mmxliii xii h xxxiv m lvi s 20 mm 01 i  1 i Jan 001 2467251 01 i  1 01/01/2043 die i mensis i annoque mmxliii 43 xliii 2043}
+test clock-2.2066 {conversion of 2043-01-31} {
+    clock format 2306320496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/31/2043 12:34:56 die xxxi mensis i annoque mmxliii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2467281 01 i  1 01/31/2043 die xxxi mensis i annoque mmxliii 43 xliii 2043}
+test clock-2.2067 {conversion of 2043-02-01} {
+    clock format 2306406896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/01/2043 12:34:56 die i mensis ii annoque mmxliii xii h xxxiv m lvi s 20 mm 01 i  1 i Feb 032 2467282 02 ii  2 02/01/2043 die i mensis ii annoque mmxliii 43 xliii 2043}
+test clock-2.2068 {conversion of 2043-02-28} {
+    clock format 2308739696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/28/2043 12:34:56 die xxviii mensis ii annoque mmxliii xii h xxxiv m lvi s 20 mm 28 xxviii 28 xxviii Feb 059 2467309 02 ii  2 02/28/2043 die xxviii mensis ii annoque mmxliii 43 xliii 2043}
+test clock-2.2069 {conversion of 2043-03-01} {
+    clock format 2308826096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/01/2043 12:34:56 die i mensis iii annoque mmxliii xii h xxxiv m lvi s 20 mm 01 i  1 i Mar 060 2467310 03 iii  3 03/01/2043 die i mensis iii annoque mmxliii 43 xliii 2043}
+test clock-2.2070 {conversion of 2043-03-31} {
+    clock format 2311418096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/31/2043 12:34:56 die xxxi mensis iii annoque mmxliii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 090 2467340 03 iii  3 03/31/2043 die xxxi mensis iii annoque mmxliii 43 xliii 2043}
+test clock-2.2071 {conversion of 2043-04-01} {
+    clock format 2311504496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/01/2043 12:34:56 die i mensis iv annoque mmxliii xii h xxxiv m lvi s 20 mm 01 i  1 i Apr 091 2467341 04 iv  4 04/01/2043 die i mensis iv annoque mmxliii 43 xliii 2043}
+test clock-2.2072 {conversion of 2043-04-30} {
+    clock format 2314010096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/30/2043 12:34:56 die xxx mensis iv annoque mmxliii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 120 2467370 04 iv  4 04/30/2043 die xxx mensis iv annoque mmxliii 43 xliii 2043}
+test clock-2.2073 {conversion of 2043-05-01} {
+    clock format 2314096496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/01/2043 12:34:56 die i mensis v annoque mmxliii xii h xxxiv m lvi s 20 mm 01 i  1 i May 121 2467371 05 v  5 05/01/2043 die i mensis v annoque mmxliii 43 xliii 2043}
+test clock-2.2074 {conversion of 2043-05-31} {
+    clock format 2316688496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/31/2043 12:34:56 die xxxi mensis v annoque mmxliii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 151 2467401 05 v  5 05/31/2043 die xxxi mensis v annoque mmxliii 43 xliii 2043}
+test clock-2.2075 {conversion of 2043-06-01} {
+    clock format 2316774896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/01/2043 12:34:56 die i mensis vi annoque mmxliii xii h xxxiv m lvi s 20 mm 01 i  1 i Jun 152 2467402 06 vi  6 06/01/2043 die i mensis vi annoque mmxliii 43 xliii 2043}
+test clock-2.2076 {conversion of 2043-06-30} {
+    clock format 2319280496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/30/2043 12:34:56 die xxx mensis vi annoque mmxliii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 181 2467431 06 vi  6 06/30/2043 die xxx mensis vi annoque mmxliii 43 xliii 2043}
+test clock-2.2077 {conversion of 2043-07-01} {
+    clock format 2319366896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/01/2043 12:34:56 die i mensis vii annoque mmxliii xii h xxxiv m lvi s 20 mm 01 i  1 i Jul 182 2467432 07 vii  7 07/01/2043 die i mensis vii annoque mmxliii 43 xliii 2043}
+test clock-2.2078 {conversion of 2043-07-31} {
+    clock format 2321958896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/31/2043 12:34:56 die xxxi mensis vii annoque mmxliii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 212 2467462 07 vii  7 07/31/2043 die xxxi mensis vii annoque mmxliii 43 xliii 2043}
+test clock-2.2079 {conversion of 2043-08-01} {
+    clock format 2322045296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/01/2043 12:34:56 die i mensis viii annoque mmxliii xii h xxxiv m lvi s 20 mm 01 i  1 i Aug 213 2467463 08 viii  8 08/01/2043 die i mensis viii annoque mmxliii 43 xliii 2043}
+test clock-2.2080 {conversion of 2043-08-31} {
+    clock format 2324637296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/31/2043 12:34:56 die xxxi mensis viii annoque mmxliii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 243 2467493 08 viii  8 08/31/2043 die xxxi mensis viii annoque mmxliii 43 xliii 2043}
+test clock-2.2081 {conversion of 2043-09-01} {
+    clock format 2324723696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/01/2043 12:34:56 die i mensis ix annoque mmxliii xii h xxxiv m lvi s 20 mm 01 i  1 i Sep 244 2467494 09 ix  9 09/01/2043 die i mensis ix annoque mmxliii 43 xliii 2043}
+test clock-2.2082 {conversion of 2043-09-30} {
+    clock format 2327229296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/30/2043 12:34:56 die xxx mensis ix annoque mmxliii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 273 2467523 09 ix  9 09/30/2043 die xxx mensis ix annoque mmxliii 43 xliii 2043}
+test clock-2.2083 {conversion of 2043-10-01} {
+    clock format 2327315696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/01/2043 12:34:56 die i mensis x annoque mmxliii xii h xxxiv m lvi s 20 mm 01 i  1 i Oct 274 2467524 10 x 10 10/01/2043 die i mensis x annoque mmxliii 43 xliii 2043}
+test clock-2.2084 {conversion of 2043-10-31} {
+    clock format 2329907696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/31/2043 12:34:56 die xxxi mensis x annoque mmxliii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 304 2467554 10 x 10 10/31/2043 die xxxi mensis x annoque mmxliii 43 xliii 2043}
+test clock-2.2085 {conversion of 2043-11-01} {
+    clock format 2329994096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/01/2043 12:34:56 die i mensis xi annoque mmxliii xii h xxxiv m lvi s 20 mm 01 i  1 i Nov 305 2467555 11 xi 11 11/01/2043 die i mensis xi annoque mmxliii 43 xliii 2043}
+test clock-2.2086 {conversion of 2043-11-30} {
+    clock format 2332499696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/30/2043 12:34:56 die xxx mensis xi annoque mmxliii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 334 2467584 11 xi 11 11/30/2043 die xxx mensis xi annoque mmxliii 43 xliii 2043}
+test clock-2.2087 {conversion of 2043-12-01} {
+    clock format 2332586096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/01/2043 12:34:56 die i mensis xii annoque mmxliii xii h xxxiv m lvi s 20 mm 01 i  1 i Dec 335 2467585 12 xii 12 12/01/2043 die i mensis xii annoque mmxliii 43 xliii 2043}
+test clock-2.2088 {conversion of 2043-12-31} {
+    clock format 2335178096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/31/2043 12:34:56 die xxxi mensis xii annoque mmxliii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 365 2467615 12 xii 12 12/31/2043 die xxxi mensis xii annoque mmxliii 43 xliii 2043}
+test clock-2.2089 {conversion of 2044-01-01} {
+    clock format 2335264496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/01/2044 12:34:56 die i mensis i annoque mmxliv xii h xxxiv m lvi s 20 mm 01 i  1 i Jan 001 2467616 01 i  1 01/01/2044 die i mensis i annoque mmxliv 44 xliv 2044}
+test clock-2.2090 {conversion of 2044-01-31} {
+    clock format 2337856496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/31/2044 12:34:56 die xxxi mensis i annoque mmxliv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2467646 01 i  1 01/31/2044 die xxxi mensis i annoque mmxliv 44 xliv 2044}
+test clock-2.2091 {conversion of 2044-02-01} {
+    clock format 2337942896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/01/2044 12:34:56 die i mensis ii annoque mmxliv xii h xxxiv m lvi s 20 mm 01 i  1 i Feb 032 2467647 02 ii  2 02/01/2044 die i mensis ii annoque mmxliv 44 xliv 2044}
+test clock-2.2092 {conversion of 2044-02-29} {
+    clock format 2340362096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/29/2044 12:34:56 die xxix mensis ii annoque mmxliv xii h xxxiv m lvi s 20 mm 29 xxix 29 xxix Feb 060 2467675 02 ii  2 02/29/2044 die xxix mensis ii annoque mmxliv 44 xliv 2044}
+test clock-2.2093 {conversion of 2044-03-01} {
+    clock format 2340448496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/01/2044 12:34:56 die i mensis iii annoque mmxliv xii h xxxiv m lvi s 20 mm 01 i  1 i Mar 061 2467676 03 iii  3 03/01/2044 die i mensis iii annoque mmxliv 44 xliv 2044}
+test clock-2.2094 {conversion of 2044-03-31} {
+    clock format 2343040496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/31/2044 12:34:56 die xxxi mensis iii annoque mmxliv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 091 2467706 03 iii  3 03/31/2044 die xxxi mensis iii annoque mmxliv 44 xliv 2044}
+test clock-2.2095 {conversion of 2044-04-01} {
+    clock format 2343126896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/01/2044 12:34:56 die i mensis iv annoque mmxliv xii h xxxiv m lvi s 20 mm 01 i  1 i Apr 092 2467707 04 iv  4 04/01/2044 die i mensis iv annoque mmxliv 44 xliv 2044}
+test clock-2.2096 {conversion of 2044-04-30} {
+    clock format 2345632496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/30/2044 12:34:56 die xxx mensis iv annoque mmxliv xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 121 2467736 04 iv  4 04/30/2044 die xxx mensis iv annoque mmxliv 44 xliv 2044}
+test clock-2.2097 {conversion of 2044-05-01} {
+    clock format 2345718896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/01/2044 12:34:56 die i mensis v annoque mmxliv xii h xxxiv m lvi s 20 mm 01 i  1 i May 122 2467737 05 v  5 05/01/2044 die i mensis v annoque mmxliv 44 xliv 2044}
+test clock-2.2098 {conversion of 2044-05-31} {
+    clock format 2348310896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/31/2044 12:34:56 die xxxi mensis v annoque mmxliv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 152 2467767 05 v  5 05/31/2044 die xxxi mensis v annoque mmxliv 44 xliv 2044}
+test clock-2.2099 {conversion of 2044-06-01} {
+    clock format 2348397296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/01/2044 12:34:56 die i mensis vi annoque mmxliv xii h xxxiv m lvi s 20 mm 01 i  1 i Jun 153 2467768 06 vi  6 06/01/2044 die i mensis vi annoque mmxliv 44 xliv 2044}
+test clock-2.2100 {conversion of 2044-06-30} {
+    clock format 2350902896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/30/2044 12:34:56 die xxx mensis vi annoque mmxliv xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 182 2467797 06 vi  6 06/30/2044 die xxx mensis vi annoque mmxliv 44 xliv 2044}
+test clock-2.2101 {conversion of 2044-07-01} {
+    clock format 2350989296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/01/2044 12:34:56 die i mensis vii annoque mmxliv xii h xxxiv m lvi s 20 mm 01 i  1 i Jul 183 2467798 07 vii  7 07/01/2044 die i mensis vii annoque mmxliv 44 xliv 2044}
+test clock-2.2102 {conversion of 2044-07-31} {
+    clock format 2353581296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/31/2044 12:34:56 die xxxi mensis vii annoque mmxliv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 213 2467828 07 vii  7 07/31/2044 die xxxi mensis vii annoque mmxliv 44 xliv 2044}
+test clock-2.2103 {conversion of 2044-08-01} {
+    clock format 2353667696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/01/2044 12:34:56 die i mensis viii annoque mmxliv xii h xxxiv m lvi s 20 mm 01 i  1 i Aug 214 2467829 08 viii  8 08/01/2044 die i mensis viii annoque mmxliv 44 xliv 2044}
+test clock-2.2104 {conversion of 2044-08-31} {
+    clock format 2356259696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/31/2044 12:34:56 die xxxi mensis viii annoque mmxliv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 244 2467859 08 viii  8 08/31/2044 die xxxi mensis viii annoque mmxliv 44 xliv 2044}
+test clock-2.2105 {conversion of 2044-09-01} {
+    clock format 2356346096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/01/2044 12:34:56 die i mensis ix annoque mmxliv xii h xxxiv m lvi s 20 mm 01 i  1 i Sep 245 2467860 09 ix  9 09/01/2044 die i mensis ix annoque mmxliv 44 xliv 2044}
+test clock-2.2106 {conversion of 2044-09-30} {
+    clock format 2358851696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/30/2044 12:34:56 die xxx mensis ix annoque mmxliv xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 274 2467889 09 ix  9 09/30/2044 die xxx mensis ix annoque mmxliv 44 xliv 2044}
+test clock-2.2107 {conversion of 2044-10-01} {
+    clock format 2358938096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/01/2044 12:34:56 die i mensis x annoque mmxliv xii h xxxiv m lvi s 20 mm 01 i  1 i Oct 275 2467890 10 x 10 10/01/2044 die i mensis x annoque mmxliv 44 xliv 2044}
+test clock-2.2108 {conversion of 2044-10-31} {
+    clock format 2361530096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/31/2044 12:34:56 die xxxi mensis x annoque mmxliv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 305 2467920 10 x 10 10/31/2044 die xxxi mensis x annoque mmxliv 44 xliv 2044}
+test clock-2.2109 {conversion of 2044-11-01} {
+    clock format 2361616496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/01/2044 12:34:56 die i mensis xi annoque mmxliv xii h xxxiv m lvi s 20 mm 01 i  1 i Nov 306 2467921 11 xi 11 11/01/2044 die i mensis xi annoque mmxliv 44 xliv 2044}
+test clock-2.2110 {conversion of 2044-11-30} {
+    clock format 2364122096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/30/2044 12:34:56 die xxx mensis xi annoque mmxliv xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 335 2467950 11 xi 11 11/30/2044 die xxx mensis xi annoque mmxliv 44 xliv 2044}
+test clock-2.2111 {conversion of 2044-12-01} {
+    clock format 2364208496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/01/2044 12:34:56 die i mensis xii annoque mmxliv xii h xxxiv m lvi s 20 mm 01 i  1 i Dec 336 2467951 12 xii 12 12/01/2044 die i mensis xii annoque mmxliv 44 xliv 2044}
+test clock-2.2112 {conversion of 2044-12-31} {
+    clock format 2366800496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/31/2044 12:34:56 die xxxi mensis xii annoque mmxliv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 366 2467981 12 xii 12 12/31/2044 die xxxi mensis xii annoque mmxliv 44 xliv 2044}
+test clock-2.2113 {conversion of 2045-01-01} {
+    clock format 2366886896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/01/2045 12:34:56 die i mensis i annoque mmxlv xii h xxxiv m lvi s 20 mm 01 i  1 i Jan 001 2467982 01 i  1 01/01/2045 die i mensis i annoque mmxlv 45 xlv 2045}
+test clock-2.2114 {conversion of 2045-01-31} {
+    clock format 2369478896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/31/2045 12:34:56 die xxxi mensis i annoque mmxlv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2468012 01 i  1 01/31/2045 die xxxi mensis i annoque mmxlv 45 xlv 2045}
+test clock-2.2115 {conversion of 2045-02-01} {
+    clock format 2369565296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/01/2045 12:34:56 die i mensis ii annoque mmxlv xii h xxxiv m lvi s 20 mm 01 i  1 i Feb 032 2468013 02 ii  2 02/01/2045 die i mensis ii annoque mmxlv 45 xlv 2045}
+test clock-2.2116 {conversion of 2045-02-28} {
+    clock format 2371898096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/28/2045 12:34:56 die xxviii mensis ii annoque mmxlv xii h xxxiv m lvi s 20 mm 28 xxviii 28 xxviii Feb 059 2468040 02 ii  2 02/28/2045 die xxviii mensis ii annoque mmxlv 45 xlv 2045}
+test clock-2.2117 {conversion of 2045-03-01} {
+    clock format 2371984496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/01/2045 12:34:56 die i mensis iii annoque mmxlv xii h xxxiv m lvi s 20 mm 01 i  1 i Mar 060 2468041 03 iii  3 03/01/2045 die i mensis iii annoque mmxlv 45 xlv 2045}
+test clock-2.2118 {conversion of 2045-03-31} {
+    clock format 2374576496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/31/2045 12:34:56 die xxxi mensis iii annoque mmxlv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 090 2468071 03 iii  3 03/31/2045 die xxxi mensis iii annoque mmxlv 45 xlv 2045}
+test clock-2.2119 {conversion of 2045-04-01} {
+    clock format 2374662896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/01/2045 12:34:56 die i mensis iv annoque mmxlv xii h xxxiv m lvi s 20 mm 01 i  1 i Apr 091 2468072 04 iv  4 04/01/2045 die i mensis iv annoque mmxlv 45 xlv 2045}
+test clock-2.2120 {conversion of 2045-04-30} {
+    clock format 2377168496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/30/2045 12:34:56 die xxx mensis iv annoque mmxlv xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 120 2468101 04 iv  4 04/30/2045 die xxx mensis iv annoque mmxlv 45 xlv 2045}
+test clock-2.2121 {conversion of 2045-05-01} {
+    clock format 2377254896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/01/2045 12:34:56 die i mensis v annoque mmxlv xii h xxxiv m lvi s 20 mm 01 i  1 i May 121 2468102 05 v  5 05/01/2045 die i mensis v annoque mmxlv 45 xlv 2045}
+test clock-2.2122 {conversion of 2045-05-31} {
+    clock format 2379846896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/31/2045 12:34:56 die xxxi mensis v annoque mmxlv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 151 2468132 05 v  5 05/31/2045 die xxxi mensis v annoque mmxlv 45 xlv 2045}
+test clock-2.2123 {conversion of 2045-06-01} {
+    clock format 2379933296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/01/2045 12:34:56 die i mensis vi annoque mmxlv xii h xxxiv m lvi s 20 mm 01 i  1 i Jun 152 2468133 06 vi  6 06/01/2045 die i mensis vi annoque mmxlv 45 xlv 2045}
+test clock-2.2124 {conversion of 2045-06-30} {
+    clock format 2382438896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/30/2045 12:34:56 die xxx mensis vi annoque mmxlv xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 181 2468162 06 vi  6 06/30/2045 die xxx mensis vi annoque mmxlv 45 xlv 2045}
+test clock-2.2125 {conversion of 2045-07-01} {
+    clock format 2382525296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/01/2045 12:34:56 die i mensis vii annoque mmxlv xii h xxxiv m lvi s 20 mm 01 i  1 i Jul 182 2468163 07 vii  7 07/01/2045 die i mensis vii annoque mmxlv 45 xlv 2045}
+test clock-2.2126 {conversion of 2045-07-31} {
+    clock format 2385117296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/31/2045 12:34:56 die xxxi mensis vii annoque mmxlv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 212 2468193 07 vii  7 07/31/2045 die xxxi mensis vii annoque mmxlv 45 xlv 2045}
+test clock-2.2127 {conversion of 2045-08-01} {
+    clock format 2385203696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/01/2045 12:34:56 die i mensis viii annoque mmxlv xii h xxxiv m lvi s 20 mm 01 i  1 i Aug 213 2468194 08 viii  8 08/01/2045 die i mensis viii annoque mmxlv 45 xlv 2045}
+test clock-2.2128 {conversion of 2045-08-31} {
+    clock format 2387795696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/31/2045 12:34:56 die xxxi mensis viii annoque mmxlv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 243 2468224 08 viii  8 08/31/2045 die xxxi mensis viii annoque mmxlv 45 xlv 2045}
+test clock-2.2129 {conversion of 2045-09-01} {
+    clock format 2387882096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/01/2045 12:34:56 die i mensis ix annoque mmxlv xii h xxxiv m lvi s 20 mm 01 i  1 i Sep 244 2468225 09 ix  9 09/01/2045 die i mensis ix annoque mmxlv 45 xlv 2045}
+test clock-2.2130 {conversion of 2045-09-30} {
+    clock format 2390387696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/30/2045 12:34:56 die xxx mensis ix annoque mmxlv xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 273 2468254 09 ix  9 09/30/2045 die xxx mensis ix annoque mmxlv 45 xlv 2045}
+test clock-2.2131 {conversion of 2045-10-01} {
+    clock format 2390474096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/01/2045 12:34:56 die i mensis x annoque mmxlv xii h xxxiv m lvi s 20 mm 01 i  1 i Oct 274 2468255 10 x 10 10/01/2045 die i mensis x annoque mmxlv 45 xlv 2045}
+test clock-2.2132 {conversion of 2045-10-31} {
+    clock format 2393066096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/31/2045 12:34:56 die xxxi mensis x annoque mmxlv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 304 2468285 10 x 10 10/31/2045 die xxxi mensis x annoque mmxlv 45 xlv 2045}
+test clock-2.2133 {conversion of 2045-11-01} {
+    clock format 2393152496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/01/2045 12:34:56 die i mensis xi annoque mmxlv xii h xxxiv m lvi s 20 mm 01 i  1 i Nov 305 2468286 11 xi 11 11/01/2045 die i mensis xi annoque mmxlv 45 xlv 2045}
+test clock-2.2134 {conversion of 2045-11-30} {
+    clock format 2395658096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/30/2045 12:34:56 die xxx mensis xi annoque mmxlv xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 334 2468315 11 xi 11 11/30/2045 die xxx mensis xi annoque mmxlv 45 xlv 2045}
+test clock-2.2135 {conversion of 2045-12-01} {
+    clock format 2395744496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/01/2045 12:34:56 die i mensis xii annoque mmxlv xii h xxxiv m lvi s 20 mm 01 i  1 i Dec 335 2468316 12 xii 12 12/01/2045 die i mensis xii annoque mmxlv 45 xlv 2045}
+test clock-2.2136 {conversion of 2045-12-31} {
+    clock format 2398336496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/31/2045 12:34:56 die xxxi mensis xii annoque mmxlv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 365 2468346 12 xii 12 12/31/2045 die xxxi mensis xii annoque mmxlv 45 xlv 2045}
+test clock-2.2137 {conversion of 2046-01-01} {
+    clock format 2398422896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/01/2046 12:34:56 die i mensis i annoque mmxlvi xii h xxxiv m lvi s 20 mm 01 i  1 i Jan 001 2468347 01 i  1 01/01/2046 die i mensis i annoque mmxlvi 46 xlvi 2046}
+test clock-2.2138 {conversion of 2046-01-31} {
+    clock format 2401014896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/31/2046 12:34:56 die xxxi mensis i annoque mmxlvi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2468377 01 i  1 01/31/2046 die xxxi mensis i annoque mmxlvi 46 xlvi 2046}
+test clock-2.2139 {conversion of 2046-02-01} {
+    clock format 2401101296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/01/2046 12:34:56 die i mensis ii annoque mmxlvi xii h xxxiv m lvi s 20 mm 01 i  1 i Feb 032 2468378 02 ii  2 02/01/2046 die i mensis ii annoque mmxlvi 46 xlvi 2046}
+test clock-2.2140 {conversion of 2046-02-28} {
+    clock format 2403434096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/28/2046 12:34:56 die xxviii mensis ii annoque mmxlvi xii h xxxiv m lvi s 20 mm 28 xxviii 28 xxviii Feb 059 2468405 02 ii  2 02/28/2046 die xxviii mensis ii annoque mmxlvi 46 xlvi 2046}
+test clock-2.2141 {conversion of 2046-03-01} {
+    clock format 2403520496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/01/2046 12:34:56 die i mensis iii annoque mmxlvi xii h xxxiv m lvi s 20 mm 01 i  1 i Mar 060 2468406 03 iii  3 03/01/2046 die i mensis iii annoque mmxlvi 46 xlvi 2046}
+test clock-2.2142 {conversion of 2046-03-31} {
+    clock format 2406112496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/31/2046 12:34:56 die xxxi mensis iii annoque mmxlvi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 090 2468436 03 iii  3 03/31/2046 die xxxi mensis iii annoque mmxlvi 46 xlvi 2046}
+test clock-2.2143 {conversion of 2046-04-01} {
+    clock format 2406198896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/01/2046 12:34:56 die i mensis iv annoque mmxlvi xii h xxxiv m lvi s 20 mm 01 i  1 i Apr 091 2468437 04 iv  4 04/01/2046 die i mensis iv annoque mmxlvi 46 xlvi 2046}
+test clock-2.2144 {conversion of 2046-04-30} {
+    clock format 2408704496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/30/2046 12:34:56 die xxx mensis iv annoque mmxlvi xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 120 2468466 04 iv  4 04/30/2046 die xxx mensis iv annoque mmxlvi 46 xlvi 2046}
+test clock-2.2145 {conversion of 2046-05-01} {
+    clock format 2408790896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/01/2046 12:34:56 die i mensis v annoque mmxlvi xii h xxxiv m lvi s 20 mm 01 i  1 i May 121 2468467 05 v  5 05/01/2046 die i mensis v annoque mmxlvi 46 xlvi 2046}
+test clock-2.2146 {conversion of 2046-05-31} {
+    clock format 2411382896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/31/2046 12:34:56 die xxxi mensis v annoque mmxlvi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 151 2468497 05 v  5 05/31/2046 die xxxi mensis v annoque mmxlvi 46 xlvi 2046}
+test clock-2.2147 {conversion of 2046-06-01} {
+    clock format 2411469296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/01/2046 12:34:56 die i mensis vi annoque mmxlvi xii h xxxiv m lvi s 20 mm 01 i  1 i Jun 152 2468498 06 vi  6 06/01/2046 die i mensis vi annoque mmxlvi 46 xlvi 2046}
+test clock-2.2148 {conversion of 2046-06-30} {
+    clock format 2413974896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/30/2046 12:34:56 die xxx mensis vi annoque mmxlvi xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 181 2468527 06 vi  6 06/30/2046 die xxx mensis vi annoque mmxlvi 46 xlvi 2046}
+test clock-2.2149 {conversion of 2046-07-01} {
+    clock format 2414061296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/01/2046 12:34:56 die i mensis vii annoque mmxlvi xii h xxxiv m lvi s 20 mm 01 i  1 i Jul 182 2468528 07 vii  7 07/01/2046 die i mensis vii annoque mmxlvi 46 xlvi 2046}
+test clock-2.2150 {conversion of 2046-07-31} {
+    clock format 2416653296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/31/2046 12:34:56 die xxxi mensis vii annoque mmxlvi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 212 2468558 07 vii  7 07/31/2046 die xxxi mensis vii annoque mmxlvi 46 xlvi 2046}
+test clock-2.2151 {conversion of 2046-08-01} {
+    clock format 2416739696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/01/2046 12:34:56 die i mensis viii annoque mmxlvi xii h xxxiv m lvi s 20 mm 01 i  1 i Aug 213 2468559 08 viii  8 08/01/2046 die i mensis viii annoque mmxlvi 46 xlvi 2046}
+test clock-2.2152 {conversion of 2046-08-31} {
+    clock format 2419331696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/31/2046 12:34:56 die xxxi mensis viii annoque mmxlvi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 243 2468589 08 viii  8 08/31/2046 die xxxi mensis viii annoque mmxlvi 46 xlvi 2046}
+test clock-2.2153 {conversion of 2046-09-01} {
+    clock format 2419418096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/01/2046 12:34:56 die i mensis ix annoque mmxlvi xii h xxxiv m lvi s 20 mm 01 i  1 i Sep 244 2468590 09 ix  9 09/01/2046 die i mensis ix annoque mmxlvi 46 xlvi 2046}
+test clock-2.2154 {conversion of 2046-09-30} {
+    clock format 2421923696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/30/2046 12:34:56 die xxx mensis ix annoque mmxlvi xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 273 2468619 09 ix  9 09/30/2046 die xxx mensis ix annoque mmxlvi 46 xlvi 2046}
+test clock-2.2155 {conversion of 2046-10-01} {
+    clock format 2422010096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/01/2046 12:34:56 die i mensis x annoque mmxlvi xii h xxxiv m lvi s 20 mm 01 i  1 i Oct 274 2468620 10 x 10 10/01/2046 die i mensis x annoque mmxlvi 46 xlvi 2046}
+test clock-2.2156 {conversion of 2046-10-31} {
+    clock format 2424602096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/31/2046 12:34:56 die xxxi mensis x annoque mmxlvi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 304 2468650 10 x 10 10/31/2046 die xxxi mensis x annoque mmxlvi 46 xlvi 2046}
+test clock-2.2157 {conversion of 2046-11-01} {
+    clock format 2424688496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/01/2046 12:34:56 die i mensis xi annoque mmxlvi xii h xxxiv m lvi s 20 mm 01 i  1 i Nov 305 2468651 11 xi 11 11/01/2046 die i mensis xi annoque mmxlvi 46 xlvi 2046}
+test clock-2.2158 {conversion of 2046-11-30} {
+    clock format 2427194096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/30/2046 12:34:56 die xxx mensis xi annoque mmxlvi xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 334 2468680 11 xi 11 11/30/2046 die xxx mensis xi annoque mmxlvi 46 xlvi 2046}
+test clock-2.2159 {conversion of 2046-12-01} {
+    clock format 2427280496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/01/2046 12:34:56 die i mensis xii annoque mmxlvi xii h xxxiv m lvi s 20 mm 01 i  1 i Dec 335 2468681 12 xii 12 12/01/2046 die i mensis xii annoque mmxlvi 46 xlvi 2046}
+test clock-2.2160 {conversion of 2046-12-31} {
+    clock format 2429872496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/31/2046 12:34:56 die xxxi mensis xii annoque mmxlvi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 365 2468711 12 xii 12 12/31/2046 die xxxi mensis xii annoque mmxlvi 46 xlvi 2046}
+test clock-2.2161 {conversion of 2047-01-01} {
+    clock format 2429958896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/01/2047 12:34:56 die i mensis i annoque mmxlvii xii h xxxiv m lvi s 20 mm 01 i  1 i Jan 001 2468712 01 i  1 01/01/2047 die i mensis i annoque mmxlvii 47 xlvii 2047}
+test clock-2.2162 {conversion of 2047-01-31} {
+    clock format 2432550896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/31/2047 12:34:56 die xxxi mensis i annoque mmxlvii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2468742 01 i  1 01/31/2047 die xxxi mensis i annoque mmxlvii 47 xlvii 2047}
+test clock-2.2163 {conversion of 2047-02-01} {
+    clock format 2432637296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/01/2047 12:34:56 die i mensis ii annoque mmxlvii xii h xxxiv m lvi s 20 mm 01 i  1 i Feb 032 2468743 02 ii  2 02/01/2047 die i mensis ii annoque mmxlvii 47 xlvii 2047}
+test clock-2.2164 {conversion of 2047-02-28} {
+    clock format 2434970096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/28/2047 12:34:56 die xxviii mensis ii annoque mmxlvii xii h xxxiv m lvi s 20 mm 28 xxviii 28 xxviii Feb 059 2468770 02 ii  2 02/28/2047 die xxviii mensis ii annoque mmxlvii 47 xlvii 2047}
+test clock-2.2165 {conversion of 2047-03-01} {
+    clock format 2435056496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/01/2047 12:34:56 die i mensis iii annoque mmxlvii xii h xxxiv m lvi s 20 mm 01 i  1 i Mar 060 2468771 03 iii  3 03/01/2047 die i mensis iii annoque mmxlvii 47 xlvii 2047}
+test clock-2.2166 {conversion of 2047-03-31} {
+    clock format 2437648496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/31/2047 12:34:56 die xxxi mensis iii annoque mmxlvii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 090 2468801 03 iii  3 03/31/2047 die xxxi mensis iii annoque mmxlvii 47 xlvii 2047}
+test clock-2.2167 {conversion of 2047-04-01} {
+    clock format 2437734896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/01/2047 12:34:56 die i mensis iv annoque mmxlvii xii h xxxiv m lvi s 20 mm 01 i  1 i Apr 091 2468802 04 iv  4 04/01/2047 die i mensis iv annoque mmxlvii 47 xlvii 2047}
+test clock-2.2168 {conversion of 2047-04-30} {
+    clock format 2440240496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/30/2047 12:34:56 die xxx mensis iv annoque mmxlvii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 120 2468831 04 iv  4 04/30/2047 die xxx mensis iv annoque mmxlvii 47 xlvii 2047}
+test clock-2.2169 {conversion of 2047-05-01} {
+    clock format 2440326896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/01/2047 12:34:56 die i mensis v annoque mmxlvii xii h xxxiv m lvi s 20 mm 01 i  1 i May 121 2468832 05 v  5 05/01/2047 die i mensis v annoque mmxlvii 47 xlvii 2047}
+test clock-2.2170 {conversion of 2047-05-31} {
+    clock format 2442918896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/31/2047 12:34:56 die xxxi mensis v annoque mmxlvii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 151 2468862 05 v  5 05/31/2047 die xxxi mensis v annoque mmxlvii 47 xlvii 2047}
+test clock-2.2171 {conversion of 2047-06-01} {
+    clock format 2443005296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/01/2047 12:34:56 die i mensis vi annoque mmxlvii xii h xxxiv m lvi s 20 mm 01 i  1 i Jun 152 2468863 06 vi  6 06/01/2047 die i mensis vi annoque mmxlvii 47 xlvii 2047}
+test clock-2.2172 {conversion of 2047-06-30} {
+    clock format 2445510896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/30/2047 12:34:56 die xxx mensis vi annoque mmxlvii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 181 2468892 06 vi  6 06/30/2047 die xxx mensis vi annoque mmxlvii 47 xlvii 2047}
+test clock-2.2173 {conversion of 2047-07-01} {
+    clock format 2445597296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/01/2047 12:34:56 die i mensis vii annoque mmxlvii xii h xxxiv m lvi s 20 mm 01 i  1 i Jul 182 2468893 07 vii  7 07/01/2047 die i mensis vii annoque mmxlvii 47 xlvii 2047}
+test clock-2.2174 {conversion of 2047-07-31} {
+    clock format 2448189296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/31/2047 12:34:56 die xxxi mensis vii annoque mmxlvii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 212 2468923 07 vii  7 07/31/2047 die xxxi mensis vii annoque mmxlvii 47 xlvii 2047}
+test clock-2.2175 {conversion of 2047-08-01} {
+    clock format 2448275696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/01/2047 12:34:56 die i mensis viii annoque mmxlvii xii h xxxiv m lvi s 20 mm 01 i  1 i Aug 213 2468924 08 viii  8 08/01/2047 die i mensis viii annoque mmxlvii 47 xlvii 2047}
+test clock-2.2176 {conversion of 2047-08-31} {
+    clock format 2450867696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/31/2047 12:34:56 die xxxi mensis viii annoque mmxlvii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 243 2468954 08 viii  8 08/31/2047 die xxxi mensis viii annoque mmxlvii 47 xlvii 2047}
+test clock-2.2177 {conversion of 2047-09-01} {
+    clock format 2450954096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/01/2047 12:34:56 die i mensis ix annoque mmxlvii xii h xxxiv m lvi s 20 mm 01 i  1 i Sep 244 2468955 09 ix  9 09/01/2047 die i mensis ix annoque mmxlvii 47 xlvii 2047}
+test clock-2.2178 {conversion of 2047-09-30} {
+    clock format 2453459696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/30/2047 12:34:56 die xxx mensis ix annoque mmxlvii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 273 2468984 09 ix  9 09/30/2047 die xxx mensis ix annoque mmxlvii 47 xlvii 2047}
+test clock-2.2179 {conversion of 2047-10-01} {
+    clock format 2453546096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/01/2047 12:34:56 die i mensis x annoque mmxlvii xii h xxxiv m lvi s 20 mm 01 i  1 i Oct 274 2468985 10 x 10 10/01/2047 die i mensis x annoque mmxlvii 47 xlvii 2047}
+test clock-2.2180 {conversion of 2047-10-31} {
+    clock format 2456138096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/31/2047 12:34:56 die xxxi mensis x annoque mmxlvii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 304 2469015 10 x 10 10/31/2047 die xxxi mensis x annoque mmxlvii 47 xlvii 2047}
+test clock-2.2181 {conversion of 2047-11-01} {
+    clock format 2456224496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/01/2047 12:34:56 die i mensis xi annoque mmxlvii xii h xxxiv m lvi s 20 mm 01 i  1 i Nov 305 2469016 11 xi 11 11/01/2047 die i mensis xi annoque mmxlvii 47 xlvii 2047}
+test clock-2.2182 {conversion of 2047-11-30} {
+    clock format 2458730096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/30/2047 12:34:56 die xxx mensis xi annoque mmxlvii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 334 2469045 11 xi 11 11/30/2047 die xxx mensis xi annoque mmxlvii 47 xlvii 2047}
+test clock-2.2183 {conversion of 2047-12-01} {
+    clock format 2458816496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/01/2047 12:34:56 die i mensis xii annoque mmxlvii xii h xxxiv m lvi s 20 mm 01 i  1 i Dec 335 2469046 12 xii 12 12/01/2047 die i mensis xii annoque mmxlvii 47 xlvii 2047}
+test clock-2.2184 {conversion of 2047-12-31} {
+    clock format 2461408496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/31/2047 12:34:56 die xxxi mensis xii annoque mmxlvii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 365 2469076 12 xii 12 12/31/2047 die xxxi mensis xii annoque mmxlvii 47 xlvii 2047}
+test clock-2.2185 {conversion of 2048-01-01} {
+    clock format 2461494896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/01/2048 12:34:56 die i mensis i annoque mmxlviii xii h xxxiv m lvi s 20 mm 01 i  1 i Jan 001 2469077 01 i  1 01/01/2048 die i mensis i annoque mmxlviii 48 xlviii 2048}
+test clock-2.2186 {conversion of 2048-01-31} {
+    clock format 2464086896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/31/2048 12:34:56 die xxxi mensis i annoque mmxlviii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2469107 01 i  1 01/31/2048 die xxxi mensis i annoque mmxlviii 48 xlviii 2048}
+test clock-2.2187 {conversion of 2048-02-01} {
+    clock format 2464173296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/01/2048 12:34:56 die i mensis ii annoque mmxlviii xii h xxxiv m lvi s 20 mm 01 i  1 i Feb 032 2469108 02 ii  2 02/01/2048 die i mensis ii annoque mmxlviii 48 xlviii 2048}
+test clock-2.2188 {conversion of 2048-02-29} {
+    clock format 2466592496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/29/2048 12:34:56 die xxix mensis ii annoque mmxlviii xii h xxxiv m lvi s 20 mm 29 xxix 29 xxix Feb 060 2469136 02 ii  2 02/29/2048 die xxix mensis ii annoque mmxlviii 48 xlviii 2048}
+test clock-2.2189 {conversion of 2048-03-01} {
+    clock format 2466678896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/01/2048 12:34:56 die i mensis iii annoque mmxlviii xii h xxxiv m lvi s 20 mm 01 i  1 i Mar 061 2469137 03 iii  3 03/01/2048 die i mensis iii annoque mmxlviii 48 xlviii 2048}
+test clock-2.2190 {conversion of 2048-03-31} {
+    clock format 2469270896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/31/2048 12:34:56 die xxxi mensis iii annoque mmxlviii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 091 2469167 03 iii  3 03/31/2048 die xxxi mensis iii annoque mmxlviii 48 xlviii 2048}
+test clock-2.2191 {conversion of 2048-04-01} {
+    clock format 2469357296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/01/2048 12:34:56 die i mensis iv annoque mmxlviii xii h xxxiv m lvi s 20 mm 01 i  1 i Apr 092 2469168 04 iv  4 04/01/2048 die i mensis iv annoque mmxlviii 48 xlviii 2048}
+test clock-2.2192 {conversion of 2048-04-30} {
+    clock format 2471862896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/30/2048 12:34:56 die xxx mensis iv annoque mmxlviii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 121 2469197 04 iv  4 04/30/2048 die xxx mensis iv annoque mmxlviii 48 xlviii 2048}
+test clock-2.2193 {conversion of 2048-05-01} {
+    clock format 2471949296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/01/2048 12:34:56 die i mensis v annoque mmxlviii xii h xxxiv m lvi s 20 mm 01 i  1 i May 122 2469198 05 v  5 05/01/2048 die i mensis v annoque mmxlviii 48 xlviii 2048}
+test clock-2.2194 {conversion of 2048-05-31} {
+    clock format 2474541296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/31/2048 12:34:56 die xxxi mensis v annoque mmxlviii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 152 2469228 05 v  5 05/31/2048 die xxxi mensis v annoque mmxlviii 48 xlviii 2048}
+test clock-2.2195 {conversion of 2048-06-01} {
+    clock format 2474627696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/01/2048 12:34:56 die i mensis vi annoque mmxlviii xii h xxxiv m lvi s 20 mm 01 i  1 i Jun 153 2469229 06 vi  6 06/01/2048 die i mensis vi annoque mmxlviii 48 xlviii 2048}
+test clock-2.2196 {conversion of 2048-06-30} {
+    clock format 2477133296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/30/2048 12:34:56 die xxx mensis vi annoque mmxlviii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 182 2469258 06 vi  6 06/30/2048 die xxx mensis vi annoque mmxlviii 48 xlviii 2048}
+test clock-2.2197 {conversion of 2048-07-01} {
+    clock format 2477219696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/01/2048 12:34:56 die i mensis vii annoque mmxlviii xii h xxxiv m lvi s 20 mm 01 i  1 i Jul 183 2469259 07 vii  7 07/01/2048 die i mensis vii annoque mmxlviii 48 xlviii 2048}
+test clock-2.2198 {conversion of 2048-07-31} {
+    clock format 2479811696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/31/2048 12:34:56 die xxxi mensis vii annoque mmxlviii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 213 2469289 07 vii  7 07/31/2048 die xxxi mensis vii annoque mmxlviii 48 xlviii 2048}
+test clock-2.2199 {conversion of 2048-08-01} {
+    clock format 2479898096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/01/2048 12:34:56 die i mensis viii annoque mmxlviii xii h xxxiv m lvi s 20 mm 01 i  1 i Aug 214 2469290 08 viii  8 08/01/2048 die i mensis viii annoque mmxlviii 48 xlviii 2048}
+test clock-2.2200 {conversion of 2048-08-31} {
+    clock format 2482490096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/31/2048 12:34:56 die xxxi mensis viii annoque mmxlviii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 244 2469320 08 viii  8 08/31/2048 die xxxi mensis viii annoque mmxlviii 48 xlviii 2048}
+test clock-2.2201 {conversion of 2048-09-01} {
+    clock format 2482576496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/01/2048 12:34:56 die i mensis ix annoque mmxlviii xii h xxxiv m lvi s 20 mm 01 i  1 i Sep 245 2469321 09 ix  9 09/01/2048 die i mensis ix annoque mmxlviii 48 xlviii 2048}
+test clock-2.2202 {conversion of 2048-09-30} {
+    clock format 2485082096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/30/2048 12:34:56 die xxx mensis ix annoque mmxlviii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 274 2469350 09 ix  9 09/30/2048 die xxx mensis ix annoque mmxlviii 48 xlviii 2048}
+test clock-2.2203 {conversion of 2048-10-01} {
+    clock format 2485168496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/01/2048 12:34:56 die i mensis x annoque mmxlviii xii h xxxiv m lvi s 20 mm 01 i  1 i Oct 275 2469351 10 x 10 10/01/2048 die i mensis x annoque mmxlviii 48 xlviii 2048}
+test clock-2.2204 {conversion of 2048-10-31} {
+    clock format 2487760496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/31/2048 12:34:56 die xxxi mensis x annoque mmxlviii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 305 2469381 10 x 10 10/31/2048 die xxxi mensis x annoque mmxlviii 48 xlviii 2048}
+test clock-2.2205 {conversion of 2048-11-01} {
+    clock format 2487846896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/01/2048 12:34:56 die i mensis xi annoque mmxlviii xii h xxxiv m lvi s 20 mm 01 i  1 i Nov 306 2469382 11 xi 11 11/01/2048 die i mensis xi annoque mmxlviii 48 xlviii 2048}
+test clock-2.2206 {conversion of 2048-11-30} {
+    clock format 2490352496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/30/2048 12:34:56 die xxx mensis xi annoque mmxlviii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 335 2469411 11 xi 11 11/30/2048 die xxx mensis xi annoque mmxlviii 48 xlviii 2048}
+test clock-2.2207 {conversion of 2048-12-01} {
+    clock format 2490438896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/01/2048 12:34:56 die i mensis xii annoque mmxlviii xii h xxxiv m lvi s 20 mm 01 i  1 i Dec 336 2469412 12 xii 12 12/01/2048 die i mensis xii annoque mmxlviii 48 xlviii 2048}
+test clock-2.2208 {conversion of 2048-12-31} {
+    clock format 2493030896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/31/2048 12:34:56 die xxxi mensis xii annoque mmxlviii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 366 2469442 12 xii 12 12/31/2048 die xxxi mensis xii annoque mmxlviii 48 xlviii 2048}
+test clock-2.2209 {conversion of 2049-01-01} {
+    clock format 2493117296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/01/2049 12:34:56 die i mensis i annoque mmxlix xii h xxxiv m lvi s 20 mm 01 i  1 i Jan 001 2469443 01 i  1 01/01/2049 die i mensis i annoque mmxlix 49 xlix 2049}
+test clock-2.2210 {conversion of 2049-01-31} {
+    clock format 2495709296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/31/2049 12:34:56 die xxxi mensis i annoque mmxlix xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2469473 01 i  1 01/31/2049 die xxxi mensis i annoque mmxlix 49 xlix 2049}
+test clock-2.2211 {conversion of 2049-02-01} {
+    clock format 2495795696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/01/2049 12:34:56 die i mensis ii annoque mmxlix xii h xxxiv m lvi s 20 mm 01 i  1 i Feb 032 2469474 02 ii  2 02/01/2049 die i mensis ii annoque mmxlix 49 xlix 2049}
+test clock-2.2212 {conversion of 2049-02-28} {
+    clock format 2498128496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/28/2049 12:34:56 die xxviii mensis ii annoque mmxlix xii h xxxiv m lvi s 20 mm 28 xxviii 28 xxviii Feb 059 2469501 02 ii  2 02/28/2049 die xxviii mensis ii annoque mmxlix 49 xlix 2049}
+test clock-2.2213 {conversion of 2049-03-01} {
+    clock format 2498214896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/01/2049 12:34:56 die i mensis iii annoque mmxlix xii h xxxiv m lvi s 20 mm 01 i  1 i Mar 060 2469502 03 iii  3 03/01/2049 die i mensis iii annoque mmxlix 49 xlix 2049}
+test clock-2.2214 {conversion of 2049-03-31} {
+    clock format 2500806896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/31/2049 12:34:56 die xxxi mensis iii annoque mmxlix xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 090 2469532 03 iii  3 03/31/2049 die xxxi mensis iii annoque mmxlix 49 xlix 2049}
+test clock-2.2215 {conversion of 2049-04-01} {
+    clock format 2500893296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/01/2049 12:34:56 die i mensis iv annoque mmxlix xii h xxxiv m lvi s 20 mm 01 i  1 i Apr 091 2469533 04 iv  4 04/01/2049 die i mensis iv annoque mmxlix 49 xlix 2049}
+test clock-2.2216 {conversion of 2049-04-30} {
+    clock format 2503398896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/30/2049 12:34:56 die xxx mensis iv annoque mmxlix xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 120 2469562 04 iv  4 04/30/2049 die xxx mensis iv annoque mmxlix 49 xlix 2049}
+test clock-2.2217 {conversion of 2049-05-01} {
+    clock format 2503485296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/01/2049 12:34:56 die i mensis v annoque mmxlix xii h xxxiv m lvi s 20 mm 01 i  1 i May 121 2469563 05 v  5 05/01/2049 die i mensis v annoque mmxlix 49 xlix 2049}
+test clock-2.2218 {conversion of 2049-05-31} {
+    clock format 2506077296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/31/2049 12:34:56 die xxxi mensis v annoque mmxlix xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 151 2469593 05 v  5 05/31/2049 die xxxi mensis v annoque mmxlix 49 xlix 2049}
+test clock-2.2219 {conversion of 2049-06-01} {
+    clock format 2506163696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/01/2049 12:34:56 die i mensis vi annoque mmxlix xii h xxxiv m lvi s 20 mm 01 i  1 i Jun 152 2469594 06 vi  6 06/01/2049 die i mensis vi annoque mmxlix 49 xlix 2049}
+test clock-2.2220 {conversion of 2049-06-30} {
+    clock format 2508669296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/30/2049 12:34:56 die xxx mensis vi annoque mmxlix xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 181 2469623 06 vi  6 06/30/2049 die xxx mensis vi annoque mmxlix 49 xlix 2049}
+test clock-2.2221 {conversion of 2049-07-01} {
+    clock format 2508755696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/01/2049 12:34:56 die i mensis vii annoque mmxlix xii h xxxiv m lvi s 20 mm 01 i  1 i Jul 182 2469624 07 vii  7 07/01/2049 die i mensis vii annoque mmxlix 49 xlix 2049}
+test clock-2.2222 {conversion of 2049-07-31} {
+    clock format 2511347696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/31/2049 12:34:56 die xxxi mensis vii annoque mmxlix xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 212 2469654 07 vii  7 07/31/2049 die xxxi mensis vii annoque mmxlix 49 xlix 2049}
+test clock-2.2223 {conversion of 2049-08-01} {
+    clock format 2511434096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/01/2049 12:34:56 die i mensis viii annoque mmxlix xii h xxxiv m lvi s 20 mm 01 i  1 i Aug 213 2469655 08 viii  8 08/01/2049 die i mensis viii annoque mmxlix 49 xlix 2049}
+test clock-2.2224 {conversion of 2049-08-31} {
+    clock format 2514026096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/31/2049 12:34:56 die xxxi mensis viii annoque mmxlix xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 243 2469685 08 viii  8 08/31/2049 die xxxi mensis viii annoque mmxlix 49 xlix 2049}
+test clock-2.2225 {conversion of 2049-09-01} {
+    clock format 2514112496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/01/2049 12:34:56 die i mensis ix annoque mmxlix xii h xxxiv m lvi s 20 mm 01 i  1 i Sep 244 2469686 09 ix  9 09/01/2049 die i mensis ix annoque mmxlix 49 xlix 2049}
+test clock-2.2226 {conversion of 2049-09-30} {
+    clock format 2516618096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/30/2049 12:34:56 die xxx mensis ix annoque mmxlix xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 273 2469715 09 ix  9 09/30/2049 die xxx mensis ix annoque mmxlix 49 xlix 2049}
+test clock-2.2227 {conversion of 2049-10-01} {
+    clock format 2516704496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/01/2049 12:34:56 die i mensis x annoque mmxlix xii h xxxiv m lvi s 20 mm 01 i  1 i Oct 274 2469716 10 x 10 10/01/2049 die i mensis x annoque mmxlix 49 xlix 2049}
+test clock-2.2228 {conversion of 2049-10-31} {
+    clock format 2519296496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/31/2049 12:34:56 die xxxi mensis x annoque mmxlix xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 304 2469746 10 x 10 10/31/2049 die xxxi mensis x annoque mmxlix 49 xlix 2049}
+test clock-2.2229 {conversion of 2049-11-01} {
+    clock format 2519382896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/01/2049 12:34:56 die i mensis xi annoque mmxlix xii h xxxiv m lvi s 20 mm 01 i  1 i Nov 305 2469747 11 xi 11 11/01/2049 die i mensis xi annoque mmxlix 49 xlix 2049}
+test clock-2.2230 {conversion of 2049-11-30} {
+    clock format 2521888496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/30/2049 12:34:56 die xxx mensis xi annoque mmxlix xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 334 2469776 11 xi 11 11/30/2049 die xxx mensis xi annoque mmxlix 49 xlix 2049}
+test clock-2.2231 {conversion of 2049-12-01} {
+    clock format 2521974896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/01/2049 12:34:56 die i mensis xii annoque mmxlix xii h xxxiv m lvi s 20 mm 01 i  1 i Dec 335 2469777 12 xii 12 12/01/2049 die i mensis xii annoque mmxlix 49 xlix 2049}
+test clock-2.2232 {conversion of 2049-12-31} {
+    clock format 2524566896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/31/2049 12:34:56 die xxxi mensis xii annoque mmxlix xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 365 2469807 12 xii 12 12/31/2049 die xxxi mensis xii annoque mmxlix 49 xlix 2049}
+test clock-2.2233 {conversion of 2052-01-01} {
+    clock format 2587725296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/01/2052 12:34:56 die i mensis i annoque mmlii xii h xxxiv m lvi s 20 mm 01 i  1 i Jan 001 2470538 01 i  1 01/01/2052 die i mensis i annoque mmlii 52 lii 2052}
+test clock-2.2234 {conversion of 2052-01-31} {
+    clock format 2590317296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/31/2052 12:34:56 die xxxi mensis i annoque mmlii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2470568 01 i  1 01/31/2052 die xxxi mensis i annoque mmlii 52 lii 2052}
+test clock-2.2235 {conversion of 2052-02-01} {
+    clock format 2590403696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/01/2052 12:34:56 die i mensis ii annoque mmlii xii h xxxiv m lvi s 20 mm 01 i  1 i Feb 032 2470569 02 ii  2 02/01/2052 die i mensis ii annoque mmlii 52 lii 2052}
+test clock-2.2236 {conversion of 2052-02-29} {
+    clock format 2592822896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/29/2052 12:34:56 die xxix mensis ii annoque mmlii xii h xxxiv m lvi s 20 mm 29 xxix 29 xxix Feb 060 2470597 02 ii  2 02/29/2052 die xxix mensis ii annoque mmlii 52 lii 2052}
+test clock-2.2237 {conversion of 2052-03-01} {
+    clock format 2592909296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/01/2052 12:34:56 die i mensis iii annoque mmlii xii h xxxiv m lvi s 20 mm 01 i  1 i Mar 061 2470598 03 iii  3 03/01/2052 die i mensis iii annoque mmlii 52 lii 2052}
+test clock-2.2238 {conversion of 2052-03-31} {
+    clock format 2595501296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/31/2052 12:34:56 die xxxi mensis iii annoque mmlii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 091 2470628 03 iii  3 03/31/2052 die xxxi mensis iii annoque mmlii 52 lii 2052}
+test clock-2.2239 {conversion of 2052-04-01} {
+    clock format 2595587696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/01/2052 12:34:56 die i mensis iv annoque mmlii xii h xxxiv m lvi s 20 mm 01 i  1 i Apr 092 2470629 04 iv  4 04/01/2052 die i mensis iv annoque mmlii 52 lii 2052}
+test clock-2.2240 {conversion of 2052-04-30} {
+    clock format 2598093296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/30/2052 12:34:56 die xxx mensis iv annoque mmlii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 121 2470658 04 iv  4 04/30/2052 die xxx mensis iv annoque mmlii 52 lii 2052}
+test clock-2.2241 {conversion of 2052-05-01} {
+    clock format 2598179696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/01/2052 12:34:56 die i mensis v annoque mmlii xii h xxxiv m lvi s 20 mm 01 i  1 i May 122 2470659 05 v  5 05/01/2052 die i mensis v annoque mmlii 52 lii 2052}
+test clock-2.2242 {conversion of 2052-05-31} {
+    clock format 2600771696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/31/2052 12:34:56 die xxxi mensis v annoque mmlii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 152 2470689 05 v  5 05/31/2052 die xxxi mensis v annoque mmlii 52 lii 2052}
+test clock-2.2243 {conversion of 2052-06-01} {
+    clock format 2600858096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/01/2052 12:34:56 die i mensis vi annoque mmlii xii h xxxiv m lvi s 20 mm 01 i  1 i Jun 153 2470690 06 vi  6 06/01/2052 die i mensis vi annoque mmlii 52 lii 2052}
+test clock-2.2244 {conversion of 2052-06-30} {
+    clock format 2603363696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/30/2052 12:34:56 die xxx mensis vi annoque mmlii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 182 2470719 06 vi  6 06/30/2052 die xxx mensis vi annoque mmlii 52 lii 2052}
+test clock-2.2245 {conversion of 2052-07-01} {
+    clock format 2603450096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/01/2052 12:34:56 die i mensis vii annoque mmlii xii h xxxiv m lvi s 20 mm 01 i  1 i Jul 183 2470720 07 vii  7 07/01/2052 die i mensis vii annoque mmlii 52 lii 2052}
+test clock-2.2246 {conversion of 2052-07-31} {
+    clock format 2606042096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/31/2052 12:34:56 die xxxi mensis vii annoque mmlii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 213 2470750 07 vii  7 07/31/2052 die xxxi mensis vii annoque mmlii 52 lii 2052}
+test clock-2.2247 {conversion of 2052-08-01} {
+    clock format 2606128496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/01/2052 12:34:56 die i mensis viii annoque mmlii xii h xxxiv m lvi s 20 mm 01 i  1 i Aug 214 2470751 08 viii  8 08/01/2052 die i mensis viii annoque mmlii 52 lii 2052}
+test clock-2.2248 {conversion of 2052-08-31} {
+    clock format 2608720496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/31/2052 12:34:56 die xxxi mensis viii annoque mmlii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 244 2470781 08 viii  8 08/31/2052 die xxxi mensis viii annoque mmlii 52 lii 2052}
+test clock-2.2249 {conversion of 2052-09-01} {
+    clock format 2608806896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/01/2052 12:34:56 die i mensis ix annoque mmlii xii h xxxiv m lvi s 20 mm 01 i  1 i Sep 245 2470782 09 ix  9 09/01/2052 die i mensis ix annoque mmlii 52 lii 2052}
+test clock-2.2250 {conversion of 2052-09-30} {
+    clock format 2611312496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/30/2052 12:34:56 die xxx mensis ix annoque mmlii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 274 2470811 09 ix  9 09/30/2052 die xxx mensis ix annoque mmlii 52 lii 2052}
+test clock-2.2251 {conversion of 2052-10-01} {
+    clock format 2611398896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/01/2052 12:34:56 die i mensis x annoque mmlii xii h xxxiv m lvi s 20 mm 01 i  1 i Oct 275 2470812 10 x 10 10/01/2052 die i mensis x annoque mmlii 52 lii 2052}
+test clock-2.2252 {conversion of 2052-10-31} {
+    clock format 2613990896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/31/2052 12:34:56 die xxxi mensis x annoque mmlii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 305 2470842 10 x 10 10/31/2052 die xxxi mensis x annoque mmlii 52 lii 2052}
+test clock-2.2253 {conversion of 2052-11-01} {
+    clock format 2614077296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/01/2052 12:34:56 die i mensis xi annoque mmlii xii h xxxiv m lvi s 20 mm 01 i  1 i Nov 306 2470843 11 xi 11 11/01/2052 die i mensis xi annoque mmlii 52 lii 2052}
+test clock-2.2254 {conversion of 2052-11-30} {
+    clock format 2616582896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/30/2052 12:34:56 die xxx mensis xi annoque mmlii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 335 2470872 11 xi 11 11/30/2052 die xxx mensis xi annoque mmlii 52 lii 2052}
+test clock-2.2255 {conversion of 2052-12-01} {
+    clock format 2616669296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/01/2052 12:34:56 die i mensis xii annoque mmlii xii h xxxiv m lvi s 20 mm 01 i  1 i Dec 336 2470873 12 xii 12 12/01/2052 die i mensis xii annoque mmlii 52 lii 2052}
+test clock-2.2256 {conversion of 2052-12-31} {
+    clock format 2619261296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/31/2052 12:34:56 die xxxi mensis xii annoque mmlii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 366 2470903 12 xii 12 12/31/2052 die xxxi mensis xii annoque mmlii 52 lii 2052}
+test clock-2.2257 {conversion of 2053-01-01} {
+    clock format 2619347696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/01/2053 12:34:56 die i mensis i annoque mmliii xii h xxxiv m lvi s 20 mm 01 i  1 i Jan 001 2470904 01 i  1 01/01/2053 die i mensis i annoque mmliii 53 liii 2053}
+test clock-2.2258 {conversion of 2053-01-31} {
+    clock format 2621939696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/31/2053 12:34:56 die xxxi mensis i annoque mmliii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2470934 01 i  1 01/31/2053 die xxxi mensis i annoque mmliii 53 liii 2053}
+test clock-2.2259 {conversion of 2053-02-01} {
+    clock format 2622026096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/01/2053 12:34:56 die i mensis ii annoque mmliii xii h xxxiv m lvi s 20 mm 01 i  1 i Feb 032 2470935 02 ii  2 02/01/2053 die i mensis ii annoque mmliii 53 liii 2053}
+test clock-2.2260 {conversion of 2053-02-28} {
+    clock format 2624358896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/28/2053 12:34:56 die xxviii mensis ii annoque mmliii xii h xxxiv m lvi s 20 mm 28 xxviii 28 xxviii Feb 059 2470962 02 ii  2 02/28/2053 die xxviii mensis ii annoque mmliii 53 liii 2053}
+test clock-2.2261 {conversion of 2053-03-01} {
+    clock format 2624445296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/01/2053 12:34:56 die i mensis iii annoque mmliii xii h xxxiv m lvi s 20 mm 01 i  1 i Mar 060 2470963 03 iii  3 03/01/2053 die i mensis iii annoque mmliii 53 liii 2053}
+test clock-2.2262 {conversion of 2053-03-31} {
+    clock format 2627037296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/31/2053 12:34:56 die xxxi mensis iii annoque mmliii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 090 2470993 03 iii  3 03/31/2053 die xxxi mensis iii annoque mmliii 53 liii 2053}
+test clock-2.2263 {conversion of 2053-04-01} {
+    clock format 2627123696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/01/2053 12:34:56 die i mensis iv annoque mmliii xii h xxxiv m lvi s 20 mm 01 i  1 i Apr 091 2470994 04 iv  4 04/01/2053 die i mensis iv annoque mmliii 53 liii 2053}
+test clock-2.2264 {conversion of 2053-04-30} {
+    clock format 2629629296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/30/2053 12:34:56 die xxx mensis iv annoque mmliii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 120 2471023 04 iv  4 04/30/2053 die xxx mensis iv annoque mmliii 53 liii 2053}
+test clock-2.2265 {conversion of 2053-05-01} {
+    clock format 2629715696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/01/2053 12:34:56 die i mensis v annoque mmliii xii h xxxiv m lvi s 20 mm 01 i  1 i May 121 2471024 05 v  5 05/01/2053 die i mensis v annoque mmliii 53 liii 2053}
+test clock-2.2266 {conversion of 2053-05-31} {
+    clock format 2632307696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/31/2053 12:34:56 die xxxi mensis v annoque mmliii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 151 2471054 05 v  5 05/31/2053 die xxxi mensis v annoque mmliii 53 liii 2053}
+test clock-2.2267 {conversion of 2053-06-01} {
+    clock format 2632394096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/01/2053 12:34:56 die i mensis vi annoque mmliii xii h xxxiv m lvi s 20 mm 01 i  1 i Jun 152 2471055 06 vi  6 06/01/2053 die i mensis vi annoque mmliii 53 liii 2053}
+test clock-2.2268 {conversion of 2053-06-30} {
+    clock format 2634899696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/30/2053 12:34:56 die xxx mensis vi annoque mmliii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 181 2471084 06 vi  6 06/30/2053 die xxx mensis vi annoque mmliii 53 liii 2053}
+test clock-2.2269 {conversion of 2053-07-01} {
+    clock format 2634986096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/01/2053 12:34:56 die i mensis vii annoque mmliii xii h xxxiv m lvi s 20 mm 01 i  1 i Jul 182 2471085 07 vii  7 07/01/2053 die i mensis vii annoque mmliii 53 liii 2053}
+test clock-2.2270 {conversion of 2053-07-31} {
+    clock format 2637578096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/31/2053 12:34:56 die xxxi mensis vii annoque mmliii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 212 2471115 07 vii  7 07/31/2053 die xxxi mensis vii annoque mmliii 53 liii 2053}
+test clock-2.2271 {conversion of 2053-08-01} {
+    clock format 2637664496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/01/2053 12:34:56 die i mensis viii annoque mmliii xii h xxxiv m lvi s 20 mm 01 i  1 i Aug 213 2471116 08 viii  8 08/01/2053 die i mensis viii annoque mmliii 53 liii 2053}
+test clock-2.2272 {conversion of 2053-08-31} {
+    clock format 2640256496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/31/2053 12:34:56 die xxxi mensis viii annoque mmliii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 243 2471146 08 viii  8 08/31/2053 die xxxi mensis viii annoque mmliii 53 liii 2053}
+test clock-2.2273 {conversion of 2053-09-01} {
+    clock format 2640342896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/01/2053 12:34:56 die i mensis ix annoque mmliii xii h xxxiv m lvi s 20 mm 01 i  1 i Sep 244 2471147 09 ix  9 09/01/2053 die i mensis ix annoque mmliii 53 liii 2053}
+test clock-2.2274 {conversion of 2053-09-30} {
+    clock format 2642848496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/30/2053 12:34:56 die xxx mensis ix annoque mmliii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 273 2471176 09 ix  9 09/30/2053 die xxx mensis ix annoque mmliii 53 liii 2053}
+test clock-2.2275 {conversion of 2053-10-01} {
+    clock format 2642934896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/01/2053 12:34:56 die i mensis x annoque mmliii xii h xxxiv m lvi s 20 mm 01 i  1 i Oct 274 2471177 10 x 10 10/01/2053 die i mensis x annoque mmliii 53 liii 2053}
+test clock-2.2276 {conversion of 2053-10-31} {
+    clock format 2645526896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/31/2053 12:34:56 die xxxi mensis x annoque mmliii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 304 2471207 10 x 10 10/31/2053 die xxxi mensis x annoque mmliii 53 liii 2053}
+test clock-2.2277 {conversion of 2053-11-01} {
+    clock format 2645613296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/01/2053 12:34:56 die i mensis xi annoque mmliii xii h xxxiv m lvi s 20 mm 01 i  1 i Nov 305 2471208 11 xi 11 11/01/2053 die i mensis xi annoque mmliii 53 liii 2053}
+test clock-2.2278 {conversion of 2053-11-30} {
+    clock format 2648118896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/30/2053 12:34:56 die xxx mensis xi annoque mmliii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 334 2471237 11 xi 11 11/30/2053 die xxx mensis xi annoque mmliii 53 liii 2053}
+test clock-2.2279 {conversion of 2053-12-01} {
+    clock format 2648205296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/01/2053 12:34:56 die i mensis xii annoque mmliii xii h xxxiv m lvi s 20 mm 01 i  1 i Dec 335 2471238 12 xii 12 12/01/2053 die i mensis xii annoque mmliii 53 liii 2053}
+test clock-2.2280 {conversion of 2053-12-31} {
+    clock format 2650797296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/31/2053 12:34:56 die xxxi mensis xii annoque mmliii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 365 2471268 12 xii 12 12/31/2053 die xxxi mensis xii annoque mmliii 53 liii 2053}
+test clock-2.2281 {conversion of 2056-01-01} {
+    clock format 2713955696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/01/2056 12:34:56 die i mensis i annoque mmlvi xii h xxxiv m lvi s 20 mm 01 i  1 i Jan 001 2471999 01 i  1 01/01/2056 die i mensis i annoque mmlvi 56 lvi 2056}
+test clock-2.2282 {conversion of 2056-01-31} {
+    clock format 2716547696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/31/2056 12:34:56 die xxxi mensis i annoque mmlvi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2472029 01 i  1 01/31/2056 die xxxi mensis i annoque mmlvi 56 lvi 2056}
+test clock-2.2283 {conversion of 2056-02-01} {
+    clock format 2716634096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/01/2056 12:34:56 die i mensis ii annoque mmlvi xii h xxxiv m lvi s 20 mm 01 i  1 i Feb 032 2472030 02 ii  2 02/01/2056 die i mensis ii annoque mmlvi 56 lvi 2056}
+test clock-2.2284 {conversion of 2056-02-29} {
+    clock format 2719053296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/29/2056 12:34:56 die xxix mensis ii annoque mmlvi xii h xxxiv m lvi s 20 mm 29 xxix 29 xxix Feb 060 2472058 02 ii  2 02/29/2056 die xxix mensis ii annoque mmlvi 56 lvi 2056}
+test clock-2.2285 {conversion of 2056-03-01} {
+    clock format 2719139696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/01/2056 12:34:56 die i mensis iii annoque mmlvi xii h xxxiv m lvi s 20 mm 01 i  1 i Mar 061 2472059 03 iii  3 03/01/2056 die i mensis iii annoque mmlvi 56 lvi 2056}
+test clock-2.2286 {conversion of 2056-03-31} {
+    clock format 2721731696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/31/2056 12:34:56 die xxxi mensis iii annoque mmlvi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 091 2472089 03 iii  3 03/31/2056 die xxxi mensis iii annoque mmlvi 56 lvi 2056}
+test clock-2.2287 {conversion of 2056-04-01} {
+    clock format 2721818096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/01/2056 12:34:56 die i mensis iv annoque mmlvi xii h xxxiv m lvi s 20 mm 01 i  1 i Apr 092 2472090 04 iv  4 04/01/2056 die i mensis iv annoque mmlvi 56 lvi 2056}
+test clock-2.2288 {conversion of 2056-04-30} {
+    clock format 2724323696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/30/2056 12:34:56 die xxx mensis iv annoque mmlvi xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 121 2472119 04 iv  4 04/30/2056 die xxx mensis iv annoque mmlvi 56 lvi 2056}
+test clock-2.2289 {conversion of 2056-05-01} {
+    clock format 2724410096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/01/2056 12:34:56 die i mensis v annoque mmlvi xii h xxxiv m lvi s 20 mm 01 i  1 i May 122 2472120 05 v  5 05/01/2056 die i mensis v annoque mmlvi 56 lvi 2056}
+test clock-2.2290 {conversion of 2056-05-31} {
+    clock format 2727002096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/31/2056 12:34:56 die xxxi mensis v annoque mmlvi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 152 2472150 05 v  5 05/31/2056 die xxxi mensis v annoque mmlvi 56 lvi 2056}
+test clock-2.2291 {conversion of 2056-06-01} {
+    clock format 2727088496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/01/2056 12:34:56 die i mensis vi annoque mmlvi xii h xxxiv m lvi s 20 mm 01 i  1 i Jun 153 2472151 06 vi  6 06/01/2056 die i mensis vi annoque mmlvi 56 lvi 2056}
+test clock-2.2292 {conversion of 2056-06-30} {
+    clock format 2729594096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/30/2056 12:34:56 die xxx mensis vi annoque mmlvi xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 182 2472180 06 vi  6 06/30/2056 die xxx mensis vi annoque mmlvi 56 lvi 2056}
+test clock-2.2293 {conversion of 2056-07-01} {
+    clock format 2729680496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/01/2056 12:34:56 die i mensis vii annoque mmlvi xii h xxxiv m lvi s 20 mm 01 i  1 i Jul 183 2472181 07 vii  7 07/01/2056 die i mensis vii annoque mmlvi 56 lvi 2056}
+test clock-2.2294 {conversion of 2056-07-31} {
+    clock format 2732272496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/31/2056 12:34:56 die xxxi mensis vii annoque mmlvi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 213 2472211 07 vii  7 07/31/2056 die xxxi mensis vii annoque mmlvi 56 lvi 2056}
+test clock-2.2295 {conversion of 2056-08-01} {
+    clock format 2732358896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/01/2056 12:34:56 die i mensis viii annoque mmlvi xii h xxxiv m lvi s 20 mm 01 i  1 i Aug 214 2472212 08 viii  8 08/01/2056 die i mensis viii annoque mmlvi 56 lvi 2056}
+test clock-2.2296 {conversion of 2056-08-31} {
+    clock format 2734950896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/31/2056 12:34:56 die xxxi mensis viii annoque mmlvi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 244 2472242 08 viii  8 08/31/2056 die xxxi mensis viii annoque mmlvi 56 lvi 2056}
+test clock-2.2297 {conversion of 2056-09-01} {
+    clock format 2735037296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/01/2056 12:34:56 die i mensis ix annoque mmlvi xii h xxxiv m lvi s 20 mm 01 i  1 i Sep 245 2472243 09 ix  9 09/01/2056 die i mensis ix annoque mmlvi 56 lvi 2056}
+test clock-2.2298 {conversion of 2056-09-30} {
+    clock format 2737542896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/30/2056 12:34:56 die xxx mensis ix annoque mmlvi xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 274 2472272 09 ix  9 09/30/2056 die xxx mensis ix annoque mmlvi 56 lvi 2056}
+test clock-2.2299 {conversion of 2056-10-01} {
+    clock format 2737629296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/01/2056 12:34:56 die i mensis x annoque mmlvi xii h xxxiv m lvi s 20 mm 01 i  1 i Oct 275 2472273 10 x 10 10/01/2056 die i mensis x annoque mmlvi 56 lvi 2056}
+test clock-2.2300 {conversion of 2056-10-31} {
+    clock format 2740221296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/31/2056 12:34:56 die xxxi mensis x annoque mmlvi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 305 2472303 10 x 10 10/31/2056 die xxxi mensis x annoque mmlvi 56 lvi 2056}
+test clock-2.2301 {conversion of 2056-11-01} {
+    clock format 2740307696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/01/2056 12:34:56 die i mensis xi annoque mmlvi xii h xxxiv m lvi s 20 mm 01 i  1 i Nov 306 2472304 11 xi 11 11/01/2056 die i mensis xi annoque mmlvi 56 lvi 2056}
+test clock-2.2302 {conversion of 2056-11-30} {
+    clock format 2742813296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/30/2056 12:34:56 die xxx mensis xi annoque mmlvi xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 335 2472333 11 xi 11 11/30/2056 die xxx mensis xi annoque mmlvi 56 lvi 2056}
+test clock-2.2303 {conversion of 2056-12-01} {
+    clock format 2742899696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/01/2056 12:34:56 die i mensis xii annoque mmlvi xii h xxxiv m lvi s 20 mm 01 i  1 i Dec 336 2472334 12 xii 12 12/01/2056 die i mensis xii annoque mmlvi 56 lvi 2056}
+test clock-2.2304 {conversion of 2056-12-31} {
+    clock format 2745491696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/31/2056 12:34:56 die xxxi mensis xii annoque mmlvi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 366 2472364 12 xii 12 12/31/2056 die xxxi mensis xii annoque mmlvi 56 lvi 2056}
+test clock-2.2305 {conversion of 2057-01-01} {
+    clock format 2745578096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/01/2057 12:34:56 die i mensis i annoque mmlvii xii h xxxiv m lvi s 20 mm 01 i  1 i Jan 001 2472365 01 i  1 01/01/2057 die i mensis i annoque mmlvii 57 lvii 2057}
+test clock-2.2306 {conversion of 2057-01-31} {
+    clock format 2748170096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/31/2057 12:34:56 die xxxi mensis i annoque mmlvii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2472395 01 i  1 01/31/2057 die xxxi mensis i annoque mmlvii 57 lvii 2057}
+test clock-2.2307 {conversion of 2057-02-01} {
+    clock format 2748256496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/01/2057 12:34:56 die i mensis ii annoque mmlvii xii h xxxiv m lvi s 20 mm 01 i  1 i Feb 032 2472396 02 ii  2 02/01/2057 die i mensis ii annoque mmlvii 57 lvii 2057}
+test clock-2.2308 {conversion of 2057-02-28} {
+    clock format 2750589296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/28/2057 12:34:56 die xxviii mensis ii annoque mmlvii xii h xxxiv m lvi s 20 mm 28 xxviii 28 xxviii Feb 059 2472423 02 ii  2 02/28/2057 die xxviii mensis ii annoque mmlvii 57 lvii 2057}
+test clock-2.2309 {conversion of 2057-03-01} {
+    clock format 2750675696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/01/2057 12:34:56 die i mensis iii annoque mmlvii xii h xxxiv m lvi s 20 mm 01 i  1 i Mar 060 2472424 03 iii  3 03/01/2057 die i mensis iii annoque mmlvii 57 lvii 2057}
+test clock-2.2310 {conversion of 2057-03-31} {
+    clock format 2753267696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/31/2057 12:34:56 die xxxi mensis iii annoque mmlvii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 090 2472454 03 iii  3 03/31/2057 die xxxi mensis iii annoque mmlvii 57 lvii 2057}
+test clock-2.2311 {conversion of 2057-04-01} {
+    clock format 2753354096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/01/2057 12:34:56 die i mensis iv annoque mmlvii xii h xxxiv m lvi s 20 mm 01 i  1 i Apr 091 2472455 04 iv  4 04/01/2057 die i mensis iv annoque mmlvii 57 lvii 2057}
+test clock-2.2312 {conversion of 2057-04-30} {
+    clock format 2755859696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/30/2057 12:34:56 die xxx mensis iv annoque mmlvii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 120 2472484 04 iv  4 04/30/2057 die xxx mensis iv annoque mmlvii 57 lvii 2057}
+test clock-2.2313 {conversion of 2057-05-01} {
+    clock format 2755946096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/01/2057 12:34:56 die i mensis v annoque mmlvii xii h xxxiv m lvi s 20 mm 01 i  1 i May 121 2472485 05 v  5 05/01/2057 die i mensis v annoque mmlvii 57 lvii 2057}
+test clock-2.2314 {conversion of 2057-05-31} {
+    clock format 2758538096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/31/2057 12:34:56 die xxxi mensis v annoque mmlvii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 151 2472515 05 v  5 05/31/2057 die xxxi mensis v annoque mmlvii 57 lvii 2057}
+test clock-2.2315 {conversion of 2057-06-01} {
+    clock format 2758624496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/01/2057 12:34:56 die i mensis vi annoque mmlvii xii h xxxiv m lvi s 20 mm 01 i  1 i Jun 152 2472516 06 vi  6 06/01/2057 die i mensis vi annoque mmlvii 57 lvii 2057}
+test clock-2.2316 {conversion of 2057-06-30} {
+    clock format 2761130096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/30/2057 12:34:56 die xxx mensis vi annoque mmlvii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 181 2472545 06 vi  6 06/30/2057 die xxx mensis vi annoque mmlvii 57 lvii 2057}
+test clock-2.2317 {conversion of 2057-07-01} {
+    clock format 2761216496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/01/2057 12:34:56 die i mensis vii annoque mmlvii xii h xxxiv m lvi s 20 mm 01 i  1 i Jul 182 2472546 07 vii  7 07/01/2057 die i mensis vii annoque mmlvii 57 lvii 2057}
+test clock-2.2318 {conversion of 2057-07-31} {
+    clock format 2763808496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/31/2057 12:34:56 die xxxi mensis vii annoque mmlvii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 212 2472576 07 vii  7 07/31/2057 die xxxi mensis vii annoque mmlvii 57 lvii 2057}
+test clock-2.2319 {conversion of 2057-08-01} {
+    clock format 2763894896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/01/2057 12:34:56 die i mensis viii annoque mmlvii xii h xxxiv m lvi s 20 mm 01 i  1 i Aug 213 2472577 08 viii  8 08/01/2057 die i mensis viii annoque mmlvii 57 lvii 2057}
+test clock-2.2320 {conversion of 2057-08-31} {
+    clock format 2766486896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/31/2057 12:34:56 die xxxi mensis viii annoque mmlvii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 243 2472607 08 viii  8 08/31/2057 die xxxi mensis viii annoque mmlvii 57 lvii 2057}
+test clock-2.2321 {conversion of 2057-09-01} {
+    clock format 2766573296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/01/2057 12:34:56 die i mensis ix annoque mmlvii xii h xxxiv m lvi s 20 mm 01 i  1 i Sep 244 2472608 09 ix  9 09/01/2057 die i mensis ix annoque mmlvii 57 lvii 2057}
+test clock-2.2322 {conversion of 2057-09-30} {
+    clock format 2769078896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/30/2057 12:34:56 die xxx mensis ix annoque mmlvii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 273 2472637 09 ix  9 09/30/2057 die xxx mensis ix annoque mmlvii 57 lvii 2057}
+test clock-2.2323 {conversion of 2057-10-01} {
+    clock format 2769165296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/01/2057 12:34:56 die i mensis x annoque mmlvii xii h xxxiv m lvi s 20 mm 01 i  1 i Oct 274 2472638 10 x 10 10/01/2057 die i mensis x annoque mmlvii 57 lvii 2057}
+test clock-2.2324 {conversion of 2057-10-31} {
+    clock format 2771757296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/31/2057 12:34:56 die xxxi mensis x annoque mmlvii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 304 2472668 10 x 10 10/31/2057 die xxxi mensis x annoque mmlvii 57 lvii 2057}
+test clock-2.2325 {conversion of 2057-11-01} {
+    clock format 2771843696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/01/2057 12:34:56 die i mensis xi annoque mmlvii xii h xxxiv m lvi s 20 mm 01 i  1 i Nov 305 2472669 11 xi 11 11/01/2057 die i mensis xi annoque mmlvii 57 lvii 2057}
+test clock-2.2326 {conversion of 2057-11-30} {
+    clock format 2774349296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/30/2057 12:34:56 die xxx mensis xi annoque mmlvii xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 334 2472698 11 xi 11 11/30/2057 die xxx mensis xi annoque mmlvii 57 lvii 2057}
+test clock-2.2327 {conversion of 2057-12-01} {
+    clock format 2774435696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/01/2057 12:34:56 die i mensis xii annoque mmlvii xii h xxxiv m lvi s 20 mm 01 i  1 i Dec 335 2472699 12 xii 12 12/01/2057 die i mensis xii annoque mmlvii 57 lvii 2057}
+test clock-2.2328 {conversion of 2057-12-31} {
+    clock format 2777027696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/31/2057 12:34:56 die xxxi mensis xii annoque mmlvii xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 365 2472729 12 xii 12 12/31/2057 die xxxi mensis xii annoque mmlvii 57 lvii 2057}
+test clock-2.2329 {conversion of 2060-01-01} {
+    clock format 2840186096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/01/2060 12:34:56 die i mensis i annoque mmlx xii h xxxiv m lvi s 20 mm 01 i  1 i Jan 001 2473460 01 i  1 01/01/2060 die i mensis i annoque mmlx 60 lx 2060}
+test clock-2.2330 {conversion of 2060-01-31} {
+    clock format 2842778096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/31/2060 12:34:56 die xxxi mensis i annoque mmlx xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2473490 01 i  1 01/31/2060 die xxxi mensis i annoque mmlx 60 lx 2060}
+test clock-2.2331 {conversion of 2060-02-01} {
+    clock format 2842864496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/01/2060 12:34:56 die i mensis ii annoque mmlx xii h xxxiv m lvi s 20 mm 01 i  1 i Feb 032 2473491 02 ii  2 02/01/2060 die i mensis ii annoque mmlx 60 lx 2060}
+test clock-2.2332 {conversion of 2060-02-29} {
+    clock format 2845283696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/29/2060 12:34:56 die xxix mensis ii annoque mmlx xii h xxxiv m lvi s 20 mm 29 xxix 29 xxix Feb 060 2473519 02 ii  2 02/29/2060 die xxix mensis ii annoque mmlx 60 lx 2060}
+test clock-2.2333 {conversion of 2060-03-01} {
+    clock format 2845370096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/01/2060 12:34:56 die i mensis iii annoque mmlx xii h xxxiv m lvi s 20 mm 01 i  1 i Mar 061 2473520 03 iii  3 03/01/2060 die i mensis iii annoque mmlx 60 lx 2060}
+test clock-2.2334 {conversion of 2060-03-31} {
+    clock format 2847962096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/31/2060 12:34:56 die xxxi mensis iii annoque mmlx xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 091 2473550 03 iii  3 03/31/2060 die xxxi mensis iii annoque mmlx 60 lx 2060}
+test clock-2.2335 {conversion of 2060-04-01} {
+    clock format 2848048496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/01/2060 12:34:56 die i mensis iv annoque mmlx xii h xxxiv m lvi s 20 mm 01 i  1 i Apr 092 2473551 04 iv  4 04/01/2060 die i mensis iv annoque mmlx 60 lx 2060}
+test clock-2.2336 {conversion of 2060-04-30} {
+    clock format 2850554096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/30/2060 12:34:56 die xxx mensis iv annoque mmlx xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 121 2473580 04 iv  4 04/30/2060 die xxx mensis iv annoque mmlx 60 lx 2060}
+test clock-2.2337 {conversion of 2060-05-01} {
+    clock format 2850640496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/01/2060 12:34:56 die i mensis v annoque mmlx xii h xxxiv m lvi s 20 mm 01 i  1 i May 122 2473581 05 v  5 05/01/2060 die i mensis v annoque mmlx 60 lx 2060}
+test clock-2.2338 {conversion of 2060-05-31} {
+    clock format 2853232496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/31/2060 12:34:56 die xxxi mensis v annoque mmlx xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 152 2473611 05 v  5 05/31/2060 die xxxi mensis v annoque mmlx 60 lx 2060}
+test clock-2.2339 {conversion of 2060-06-01} {
+    clock format 2853318896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/01/2060 12:34:56 die i mensis vi annoque mmlx xii h xxxiv m lvi s 20 mm 01 i  1 i Jun 153 2473612 06 vi  6 06/01/2060 die i mensis vi annoque mmlx 60 lx 2060}
+test clock-2.2340 {conversion of 2060-06-30} {
+    clock format 2855824496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/30/2060 12:34:56 die xxx mensis vi annoque mmlx xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 182 2473641 06 vi  6 06/30/2060 die xxx mensis vi annoque mmlx 60 lx 2060}
+test clock-2.2341 {conversion of 2060-07-01} {
+    clock format 2855910896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/01/2060 12:34:56 die i mensis vii annoque mmlx xii h xxxiv m lvi s 20 mm 01 i  1 i Jul 183 2473642 07 vii  7 07/01/2060 die i mensis vii annoque mmlx 60 lx 2060}
+test clock-2.2342 {conversion of 2060-07-31} {
+    clock format 2858502896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/31/2060 12:34:56 die xxxi mensis vii annoque mmlx xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 213 2473672 07 vii  7 07/31/2060 die xxxi mensis vii annoque mmlx 60 lx 2060}
+test clock-2.2343 {conversion of 2060-08-01} {
+    clock format 2858589296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/01/2060 12:34:56 die i mensis viii annoque mmlx xii h xxxiv m lvi s 20 mm 01 i  1 i Aug 214 2473673 08 viii  8 08/01/2060 die i mensis viii annoque mmlx 60 lx 2060}
+test clock-2.2344 {conversion of 2060-08-31} {
+    clock format 2861181296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/31/2060 12:34:56 die xxxi mensis viii annoque mmlx xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 244 2473703 08 viii  8 08/31/2060 die xxxi mensis viii annoque mmlx 60 lx 2060}
+test clock-2.2345 {conversion of 2060-09-01} {
+    clock format 2861267696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/01/2060 12:34:56 die i mensis ix annoque mmlx xii h xxxiv m lvi s 20 mm 01 i  1 i Sep 245 2473704 09 ix  9 09/01/2060 die i mensis ix annoque mmlx 60 lx 2060}
+test clock-2.2346 {conversion of 2060-09-30} {
+    clock format 2863773296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/30/2060 12:34:56 die xxx mensis ix annoque mmlx xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 274 2473733 09 ix  9 09/30/2060 die xxx mensis ix annoque mmlx 60 lx 2060}
+test clock-2.2347 {conversion of 2060-10-01} {
+    clock format 2863859696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/01/2060 12:34:56 die i mensis x annoque mmlx xii h xxxiv m lvi s 20 mm 01 i  1 i Oct 275 2473734 10 x 10 10/01/2060 die i mensis x annoque mmlx 60 lx 2060}
+test clock-2.2348 {conversion of 2060-10-31} {
+    clock format 2866451696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/31/2060 12:34:56 die xxxi mensis x annoque mmlx xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 305 2473764 10 x 10 10/31/2060 die xxxi mensis x annoque mmlx 60 lx 2060}
+test clock-2.2349 {conversion of 2060-11-01} {
+    clock format 2866538096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/01/2060 12:34:56 die i mensis xi annoque mmlx xii h xxxiv m lvi s 20 mm 01 i  1 i Nov 306 2473765 11 xi 11 11/01/2060 die i mensis xi annoque mmlx 60 lx 2060}
+test clock-2.2350 {conversion of 2060-11-30} {
+    clock format 2869043696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/30/2060 12:34:56 die xxx mensis xi annoque mmlx xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 335 2473794 11 xi 11 11/30/2060 die xxx mensis xi annoque mmlx 60 lx 2060}
+test clock-2.2351 {conversion of 2060-12-01} {
+    clock format 2869130096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/01/2060 12:34:56 die i mensis xii annoque mmlx xii h xxxiv m lvi s 20 mm 01 i  1 i Dec 336 2473795 12 xii 12 12/01/2060 die i mensis xii annoque mmlx 60 lx 2060}
+test clock-2.2352 {conversion of 2060-12-31} {
+    clock format 2871722096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/31/2060 12:34:56 die xxxi mensis xii annoque mmlx xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 366 2473825 12 xii 12 12/31/2060 die xxxi mensis xii annoque mmlx 60 lx 2060}
+test clock-2.2353 {conversion of 2061-01-01} {
+    clock format 2871808496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/01/2061 12:34:56 die i mensis i annoque mmlxi xii h xxxiv m lvi s 20 mm 01 i  1 i Jan 001 2473826 01 i  1 01/01/2061 die i mensis i annoque mmlxi 61 lxi 2061}
+test clock-2.2354 {conversion of 2061-01-31} {
+    clock format 2874400496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/31/2061 12:34:56 die xxxi mensis i annoque mmlxi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2473856 01 i  1 01/31/2061 die xxxi mensis i annoque mmlxi 61 lxi 2061}
+test clock-2.2355 {conversion of 2061-02-01} {
+    clock format 2874486896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/01/2061 12:34:56 die i mensis ii annoque mmlxi xii h xxxiv m lvi s 20 mm 01 i  1 i Feb 032 2473857 02 ii  2 02/01/2061 die i mensis ii annoque mmlxi 61 lxi 2061}
+test clock-2.2356 {conversion of 2061-02-28} {
+    clock format 2876819696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/28/2061 12:34:56 die xxviii mensis ii annoque mmlxi xii h xxxiv m lvi s 20 mm 28 xxviii 28 xxviii Feb 059 2473884 02 ii  2 02/28/2061 die xxviii mensis ii annoque mmlxi 61 lxi 2061}
+test clock-2.2357 {conversion of 2061-03-01} {
+    clock format 2876906096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/01/2061 12:34:56 die i mensis iii annoque mmlxi xii h xxxiv m lvi s 20 mm 01 i  1 i Mar 060 2473885 03 iii  3 03/01/2061 die i mensis iii annoque mmlxi 61 lxi 2061}
+test clock-2.2358 {conversion of 2061-03-31} {
+    clock format 2879498096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/31/2061 12:34:56 die xxxi mensis iii annoque mmlxi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 090 2473915 03 iii  3 03/31/2061 die xxxi mensis iii annoque mmlxi 61 lxi 2061}
+test clock-2.2359 {conversion of 2061-04-01} {
+    clock format 2879584496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/01/2061 12:34:56 die i mensis iv annoque mmlxi xii h xxxiv m lvi s 20 mm 01 i  1 i Apr 091 2473916 04 iv  4 04/01/2061 die i mensis iv annoque mmlxi 61 lxi 2061}
+test clock-2.2360 {conversion of 2061-04-30} {
+    clock format 2882090096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/30/2061 12:34:56 die xxx mensis iv annoque mmlxi xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 120 2473945 04 iv  4 04/30/2061 die xxx mensis iv annoque mmlxi 61 lxi 2061}
+test clock-2.2361 {conversion of 2061-05-01} {
+    clock format 2882176496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/01/2061 12:34:56 die i mensis v annoque mmlxi xii h xxxiv m lvi s 20 mm 01 i  1 i May 121 2473946 05 v  5 05/01/2061 die i mensis v annoque mmlxi 61 lxi 2061}
+test clock-2.2362 {conversion of 2061-05-31} {
+    clock format 2884768496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/31/2061 12:34:56 die xxxi mensis v annoque mmlxi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 151 2473976 05 v  5 05/31/2061 die xxxi mensis v annoque mmlxi 61 lxi 2061}
+test clock-2.2363 {conversion of 2061-06-01} {
+    clock format 2884854896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/01/2061 12:34:56 die i mensis vi annoque mmlxi xii h xxxiv m lvi s 20 mm 01 i  1 i Jun 152 2473977 06 vi  6 06/01/2061 die i mensis vi annoque mmlxi 61 lxi 2061}
+test clock-2.2364 {conversion of 2061-06-30} {
+    clock format 2887360496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/30/2061 12:34:56 die xxx mensis vi annoque mmlxi xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 181 2474006 06 vi  6 06/30/2061 die xxx mensis vi annoque mmlxi 61 lxi 2061}
+test clock-2.2365 {conversion of 2061-07-01} {
+    clock format 2887446896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/01/2061 12:34:56 die i mensis vii annoque mmlxi xii h xxxiv m lvi s 20 mm 01 i  1 i Jul 182 2474007 07 vii  7 07/01/2061 die i mensis vii annoque mmlxi 61 lxi 2061}
+test clock-2.2366 {conversion of 2061-07-31} {
+    clock format 2890038896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/31/2061 12:34:56 die xxxi mensis vii annoque mmlxi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 212 2474037 07 vii  7 07/31/2061 die xxxi mensis vii annoque mmlxi 61 lxi 2061}
+test clock-2.2367 {conversion of 2061-08-01} {
+    clock format 2890125296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/01/2061 12:34:56 die i mensis viii annoque mmlxi xii h xxxiv m lvi s 20 mm 01 i  1 i Aug 213 2474038 08 viii  8 08/01/2061 die i mensis viii annoque mmlxi 61 lxi 2061}
+test clock-2.2368 {conversion of 2061-08-31} {
+    clock format 2892717296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/31/2061 12:34:56 die xxxi mensis viii annoque mmlxi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 243 2474068 08 viii  8 08/31/2061 die xxxi mensis viii annoque mmlxi 61 lxi 2061}
+test clock-2.2369 {conversion of 2061-09-01} {
+    clock format 2892803696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/01/2061 12:34:56 die i mensis ix annoque mmlxi xii h xxxiv m lvi s 20 mm 01 i  1 i Sep 244 2474069 09 ix  9 09/01/2061 die i mensis ix annoque mmlxi 61 lxi 2061}
+test clock-2.2370 {conversion of 2061-09-30} {
+    clock format 2895309296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/30/2061 12:34:56 die xxx mensis ix annoque mmlxi xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 273 2474098 09 ix  9 09/30/2061 die xxx mensis ix annoque mmlxi 61 lxi 2061}
+test clock-2.2371 {conversion of 2061-10-01} {
+    clock format 2895395696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/01/2061 12:34:56 die i mensis x annoque mmlxi xii h xxxiv m lvi s 20 mm 01 i  1 i Oct 274 2474099 10 x 10 10/01/2061 die i mensis x annoque mmlxi 61 lxi 2061}
+test clock-2.2372 {conversion of 2061-10-31} {
+    clock format 2897987696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/31/2061 12:34:56 die xxxi mensis x annoque mmlxi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 304 2474129 10 x 10 10/31/2061 die xxxi mensis x annoque mmlxi 61 lxi 2061}
+test clock-2.2373 {conversion of 2061-11-01} {
+    clock format 2898074096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/01/2061 12:34:56 die i mensis xi annoque mmlxi xii h xxxiv m lvi s 20 mm 01 i  1 i Nov 305 2474130 11 xi 11 11/01/2061 die i mensis xi annoque mmlxi 61 lxi 2061}
+test clock-2.2374 {conversion of 2061-11-30} {
+    clock format 2900579696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/30/2061 12:34:56 die xxx mensis xi annoque mmlxi xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 334 2474159 11 xi 11 11/30/2061 die xxx mensis xi annoque mmlxi 61 lxi 2061}
+test clock-2.2375 {conversion of 2061-12-01} {
+    clock format 2900666096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/01/2061 12:34:56 die i mensis xii annoque mmlxi xii h xxxiv m lvi s 20 mm 01 i  1 i Dec 335 2474160 12 xii 12 12/01/2061 die i mensis xii annoque mmlxi 61 lxi 2061}
+test clock-2.2376 {conversion of 2061-12-31} {
+    clock format 2903258096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/31/2061 12:34:56 die xxxi mensis xii annoque mmlxi xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 365 2474190 12 xii 12 12/31/2061 die xxxi mensis xii annoque mmlxi 61 lxi 2061}
+test clock-2.2377 {conversion of 2064-01-01} {
+    clock format 2966416496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/01/2064 12:34:56 die i mensis i annoque mmlxiv xii h xxxiv m lvi s 20 mm 01 i  1 i Jan 001 2474921 01 i  1 01/01/2064 die i mensis i annoque mmlxiv 64 lxiv 2064}
+test clock-2.2378 {conversion of 2064-01-31} {
+    clock format 2969008496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/31/2064 12:34:56 die xxxi mensis i annoque mmlxiv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2474951 01 i  1 01/31/2064 die xxxi mensis i annoque mmlxiv 64 lxiv 2064}
+test clock-2.2379 {conversion of 2064-02-01} {
+    clock format 2969094896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/01/2064 12:34:56 die i mensis ii annoque mmlxiv xii h xxxiv m lvi s 20 mm 01 i  1 i Feb 032 2474952 02 ii  2 02/01/2064 die i mensis ii annoque mmlxiv 64 lxiv 2064}
+test clock-2.2380 {conversion of 2064-02-29} {
+    clock format 2971514096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/29/2064 12:34:56 die xxix mensis ii annoque mmlxiv xii h xxxiv m lvi s 20 mm 29 xxix 29 xxix Feb 060 2474980 02 ii  2 02/29/2064 die xxix mensis ii annoque mmlxiv 64 lxiv 2064}
+test clock-2.2381 {conversion of 2064-03-01} {
+    clock format 2971600496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/01/2064 12:34:56 die i mensis iii annoque mmlxiv xii h xxxiv m lvi s 20 mm 01 i  1 i Mar 061 2474981 03 iii  3 03/01/2064 die i mensis iii annoque mmlxiv 64 lxiv 2064}
+test clock-2.2382 {conversion of 2064-03-31} {
+    clock format 2974192496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/31/2064 12:34:56 die xxxi mensis iii annoque mmlxiv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 091 2475011 03 iii  3 03/31/2064 die xxxi mensis iii annoque mmlxiv 64 lxiv 2064}
+test clock-2.2383 {conversion of 2064-04-01} {
+    clock format 2974278896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/01/2064 12:34:56 die i mensis iv annoque mmlxiv xii h xxxiv m lvi s 20 mm 01 i  1 i Apr 092 2475012 04 iv  4 04/01/2064 die i mensis iv annoque mmlxiv 64 lxiv 2064}
+test clock-2.2384 {conversion of 2064-04-30} {
+    clock format 2976784496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/30/2064 12:34:56 die xxx mensis iv annoque mmlxiv xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 121 2475041 04 iv  4 04/30/2064 die xxx mensis iv annoque mmlxiv 64 lxiv 2064}
+test clock-2.2385 {conversion of 2064-05-01} {
+    clock format 2976870896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/01/2064 12:34:56 die i mensis v annoque mmlxiv xii h xxxiv m lvi s 20 mm 01 i  1 i May 122 2475042 05 v  5 05/01/2064 die i mensis v annoque mmlxiv 64 lxiv 2064}
+test clock-2.2386 {conversion of 2064-05-31} {
+    clock format 2979462896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/31/2064 12:34:56 die xxxi mensis v annoque mmlxiv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 152 2475072 05 v  5 05/31/2064 die xxxi mensis v annoque mmlxiv 64 lxiv 2064}
+test clock-2.2387 {conversion of 2064-06-01} {
+    clock format 2979549296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/01/2064 12:34:56 die i mensis vi annoque mmlxiv xii h xxxiv m lvi s 20 mm 01 i  1 i Jun 153 2475073 06 vi  6 06/01/2064 die i mensis vi annoque mmlxiv 64 lxiv 2064}
+test clock-2.2388 {conversion of 2064-06-30} {
+    clock format 2982054896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/30/2064 12:34:56 die xxx mensis vi annoque mmlxiv xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 182 2475102 06 vi  6 06/30/2064 die xxx mensis vi annoque mmlxiv 64 lxiv 2064}
+test clock-2.2389 {conversion of 2064-07-01} {
+    clock format 2982141296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/01/2064 12:34:56 die i mensis vii annoque mmlxiv xii h xxxiv m lvi s 20 mm 01 i  1 i Jul 183 2475103 07 vii  7 07/01/2064 die i mensis vii annoque mmlxiv 64 lxiv 2064}
+test clock-2.2390 {conversion of 2064-07-31} {
+    clock format 2984733296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/31/2064 12:34:56 die xxxi mensis vii annoque mmlxiv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 213 2475133 07 vii  7 07/31/2064 die xxxi mensis vii annoque mmlxiv 64 lxiv 2064}
+test clock-2.2391 {conversion of 2064-08-01} {
+    clock format 2984819696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/01/2064 12:34:56 die i mensis viii annoque mmlxiv xii h xxxiv m lvi s 20 mm 01 i  1 i Aug 214 2475134 08 viii  8 08/01/2064 die i mensis viii annoque mmlxiv 64 lxiv 2064}
+test clock-2.2392 {conversion of 2064-08-31} {
+    clock format 2987411696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/31/2064 12:34:56 die xxxi mensis viii annoque mmlxiv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 244 2475164 08 viii  8 08/31/2064 die xxxi mensis viii annoque mmlxiv 64 lxiv 2064}
+test clock-2.2393 {conversion of 2064-09-01} {
+    clock format 2987498096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/01/2064 12:34:56 die i mensis ix annoque mmlxiv xii h xxxiv m lvi s 20 mm 01 i  1 i Sep 245 2475165 09 ix  9 09/01/2064 die i mensis ix annoque mmlxiv 64 lxiv 2064}
+test clock-2.2394 {conversion of 2064-09-30} {
+    clock format 2990003696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/30/2064 12:34:56 die xxx mensis ix annoque mmlxiv xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 274 2475194 09 ix  9 09/30/2064 die xxx mensis ix annoque mmlxiv 64 lxiv 2064}
+test clock-2.2395 {conversion of 2064-10-01} {
+    clock format 2990090096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/01/2064 12:34:56 die i mensis x annoque mmlxiv xii h xxxiv m lvi s 20 mm 01 i  1 i Oct 275 2475195 10 x 10 10/01/2064 die i mensis x annoque mmlxiv 64 lxiv 2064}
+test clock-2.2396 {conversion of 2064-10-31} {
+    clock format 2992682096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/31/2064 12:34:56 die xxxi mensis x annoque mmlxiv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 305 2475225 10 x 10 10/31/2064 die xxxi mensis x annoque mmlxiv 64 lxiv 2064}
+test clock-2.2397 {conversion of 2064-11-01} {
+    clock format 2992768496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/01/2064 12:34:56 die i mensis xi annoque mmlxiv xii h xxxiv m lvi s 20 mm 01 i  1 i Nov 306 2475226 11 xi 11 11/01/2064 die i mensis xi annoque mmlxiv 64 lxiv 2064}
+test clock-2.2398 {conversion of 2064-11-30} {
+    clock format 2995274096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/30/2064 12:34:56 die xxx mensis xi annoque mmlxiv xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 335 2475255 11 xi 11 11/30/2064 die xxx mensis xi annoque mmlxiv 64 lxiv 2064}
+test clock-2.2399 {conversion of 2064-12-01} {
+    clock format 2995360496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/01/2064 12:34:56 die i mensis xii annoque mmlxiv xii h xxxiv m lvi s 20 mm 01 i  1 i Dec 336 2475256 12 xii 12 12/01/2064 die i mensis xii annoque mmlxiv 64 lxiv 2064}
+test clock-2.2400 {conversion of 2064-12-31} {
+    clock format 2997952496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/31/2064 12:34:56 die xxxi mensis xii annoque mmlxiv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 366 2475286 12 xii 12 12/31/2064 die xxxi mensis xii annoque mmlxiv 64 lxiv 2064}
+test clock-2.2401 {conversion of 2065-01-01} {
+    clock format 2998038896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/01/2065 12:34:56 die i mensis i annoque mmlxv xii h xxxiv m lvi s 20 mm 01 i  1 i Jan 001 2475287 01 i  1 01/01/2065 die i mensis i annoque mmlxv 65 lxv 2065}
+test clock-2.2402 {conversion of 2065-01-31} {
+    clock format 3000630896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jan January 01/31/2065 12:34:56 die xxxi mensis i annoque mmlxv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jan 031 2475317 01 i  1 01/31/2065 die xxxi mensis i annoque mmlxv 65 lxv 2065}
+test clock-2.2403 {conversion of 2065-02-01} {
+    clock format 3000717296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/01/2065 12:34:56 die i mensis ii annoque mmlxv xii h xxxiv m lvi s 20 mm 01 i  1 i Feb 032 2475318 02 ii  2 02/01/2065 die i mensis ii annoque mmlxv 65 lxv 2065}
+test clock-2.2404 {conversion of 2065-02-28} {
+    clock format 3003050096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Feb February 02/28/2065 12:34:56 die xxviii mensis ii annoque mmlxv xii h xxxiv m lvi s 20 mm 28 xxviii 28 xxviii Feb 059 2475345 02 ii  2 02/28/2065 die xxviii mensis ii annoque mmlxv 65 lxv 2065}
+test clock-2.2405 {conversion of 2065-03-01} {
+    clock format 3003136496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/01/2065 12:34:56 die i mensis iii annoque mmlxv xii h xxxiv m lvi s 20 mm 01 i  1 i Mar 060 2475346 03 iii  3 03/01/2065 die i mensis iii annoque mmlxv 65 lxv 2065}
+test clock-2.2406 {conversion of 2065-03-31} {
+    clock format 3005728496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Mar March 03/31/2065 12:34:56 die xxxi mensis iii annoque mmlxv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Mar 090 2475376 03 iii  3 03/31/2065 die xxxi mensis iii annoque mmlxv 65 lxv 2065}
+test clock-2.2407 {conversion of 2065-04-01} {
+    clock format 3005814896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/01/2065 12:34:56 die i mensis iv annoque mmlxv xii h xxxiv m lvi s 20 mm 01 i  1 i Apr 091 2475377 04 iv  4 04/01/2065 die i mensis iv annoque mmlxv 65 lxv 2065}
+test clock-2.2408 {conversion of 2065-04-30} {
+    clock format 3008320496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Apr April 04/30/2065 12:34:56 die xxx mensis iv annoque mmlxv xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Apr 120 2475406 04 iv  4 04/30/2065 die xxx mensis iv annoque mmlxv 65 lxv 2065}
+test clock-2.2409 {conversion of 2065-05-01} {
+    clock format 3008406896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/01/2065 12:34:56 die i mensis v annoque mmlxv xii h xxxiv m lvi s 20 mm 01 i  1 i May 121 2475407 05 v  5 05/01/2065 die i mensis v annoque mmlxv 65 lxv 2065}
+test clock-2.2410 {conversion of 2065-05-31} {
+    clock format 3010998896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {May May 05/31/2065 12:34:56 die xxxi mensis v annoque mmlxv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi May 151 2475437 05 v  5 05/31/2065 die xxxi mensis v annoque mmlxv 65 lxv 2065}
+test clock-2.2411 {conversion of 2065-06-01} {
+    clock format 3011085296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/01/2065 12:34:56 die i mensis vi annoque mmlxv xii h xxxiv m lvi s 20 mm 01 i  1 i Jun 152 2475438 06 vi  6 06/01/2065 die i mensis vi annoque mmlxv 65 lxv 2065}
+test clock-2.2412 {conversion of 2065-06-30} {
+    clock format 3013590896 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jun June 06/30/2065 12:34:56 die xxx mensis vi annoque mmlxv xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Jun 181 2475467 06 vi  6 06/30/2065 die xxx mensis vi annoque mmlxv 65 lxv 2065}
+test clock-2.2413 {conversion of 2065-07-01} {
+    clock format 3013677296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/01/2065 12:34:56 die i mensis vii annoque mmlxv xii h xxxiv m lvi s 20 mm 01 i  1 i Jul 182 2475468 07 vii  7 07/01/2065 die i mensis vii annoque mmlxv 65 lxv 2065}
+test clock-2.2414 {conversion of 2065-07-31} {
+    clock format 3016269296 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Jul July 07/31/2065 12:34:56 die xxxi mensis vii annoque mmlxv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Jul 212 2475498 07 vii  7 07/31/2065 die xxxi mensis vii annoque mmlxv 65 lxv 2065}
+test clock-2.2415 {conversion of 2065-08-01} {
+    clock format 3016355696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/01/2065 12:34:56 die i mensis viii annoque mmlxv xii h xxxiv m lvi s 20 mm 01 i  1 i Aug 213 2475499 08 viii  8 08/01/2065 die i mensis viii annoque mmlxv 65 lxv 2065}
+test clock-2.2416 {conversion of 2065-08-31} {
+    clock format 3018947696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Aug August 08/31/2065 12:34:56 die xxxi mensis viii annoque mmlxv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Aug 243 2475529 08 viii  8 08/31/2065 die xxxi mensis viii annoque mmlxv 65 lxv 2065}
+test clock-2.2417 {conversion of 2065-09-01} {
+    clock format 3019034096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/01/2065 12:34:56 die i mensis ix annoque mmlxv xii h xxxiv m lvi s 20 mm 01 i  1 i Sep 244 2475530 09 ix  9 09/01/2065 die i mensis ix annoque mmlxv 65 lxv 2065}
+test clock-2.2418 {conversion of 2065-09-30} {
+    clock format 3021539696 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Sep September 09/30/2065 12:34:56 die xxx mensis ix annoque mmlxv xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Sep 273 2475559 09 ix  9 09/30/2065 die xxx mensis ix annoque mmlxv 65 lxv 2065}
+test clock-2.2419 {conversion of 2065-10-01} {
+    clock format 3021626096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/01/2065 12:34:56 die i mensis x annoque mmlxv xii h xxxiv m lvi s 20 mm 01 i  1 i Oct 274 2475560 10 x 10 10/01/2065 die i mensis x annoque mmlxv 65 lxv 2065}
+test clock-2.2420 {conversion of 2065-10-31} {
+    clock format 3024218096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Oct October 10/31/2065 12:34:56 die xxxi mensis x annoque mmlxv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Oct 304 2475590 10 x 10 10/31/2065 die xxxi mensis x annoque mmlxv 65 lxv 2065}
+test clock-2.2421 {conversion of 2065-11-01} {
+    clock format 3024304496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/01/2065 12:34:56 die i mensis xi annoque mmlxv xii h xxxiv m lvi s 20 mm 01 i  1 i Nov 305 2475591 11 xi 11 11/01/2065 die i mensis xi annoque mmlxv 65 lxv 2065}
+test clock-2.2422 {conversion of 2065-11-30} {
+    clock format 3026810096 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Nov November 11/30/2065 12:34:56 die xxx mensis xi annoque mmlxv xii h xxxiv m lvi s 20 mm 30 xxx 30 xxx Nov 334 2475620 11 xi 11 11/30/2065 die xxx mensis xi annoque mmlxv 65 lxv 2065}
+test clock-2.2423 {conversion of 2065-12-01} {
+    clock format 3026896496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/01/2065 12:34:56 die i mensis xii annoque mmlxv xii h xxxiv m lvi s 20 mm 01 i  1 i Dec 335 2475621 12 xii 12 12/01/2065 die i mensis xii annoque mmlxv 65 lxv 2065}
+test clock-2.2424 {conversion of 2065-12-31} {
+    clock format 3029488496 \
+	-format {%b %B %c %Ec %C %EC %d %Od %e %Oe %h %j %J %m %Om %N %x %Ex %y %Oy %Y} \
+	-gmt true -locale en_US_roman
+} {Dec December 12/31/2065 12:34:56 die xxxi mensis xii annoque mmlxv xii h xxxiv m lvi s 20 mm 31 xxxi 31 xxxi Dec 365 2475651 12 xii 12 12/31/2065 die xxxi mensis xii annoque mmlxv 65 lxv 2065}
+# END testcases2
+
+# BEGIN testcases3
+test clock-3.1 {ISO week-based calendar 1871-W52-1} {
+    clock format -3093206400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1871-W52-1
+} {Mon Monday 71 1871 1 52 52 1 52}
+test clock-3.2 {ISO week-based calendar 1871-W52-6} {
+    clock format -3092774400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1871-W52-6
+} {Sat Saturday 71 1871 6 52 52 6 52}
+test clock-3.3 {ISO week-based calendar 1871-W52-7} {
+    clock format -3092688000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1871-W52-7
+} {Sun Sunday 71 1871 7 53 52 0 52}
+test clock-3.4 {ISO week-based calendar 1872-W01-1} {
+    clock format -3092601600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1872-W01-1
+} {Mon Monday 72 1872 1 00 01 1 01}
+test clock-3.5 {ISO week-based calendar 1872-W01-6} {
+    clock format -3092169600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1872-W01-6
+} {Sat Saturday 72 1872 6 00 01 6 01}
+test clock-3.6 {ISO week-based calendar 1872-W01-7} {
+    clock format -3092083200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1872-W01-7
+} {Sun Sunday 72 1872 7 01 01 0 01}
+test clock-3.7 {ISO week-based calendar 1872-W02-1} {
+    clock format -3091996800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1872-W02-1
+} {Mon Monday 72 1872 1 01 02 1 02}
+test clock-3.8 {ISO week-based calendar 1872-W52-1} {
+    clock format -3061756800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1872-W52-1
+} {Mon Monday 72 1872 1 51 52 1 52}
+test clock-3.9 {ISO week-based calendar 1872-W52-6} {
+    clock format -3061324800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1872-W52-6
+} {Sat Saturday 72 1872 6 51 52 6 52}
+test clock-3.10 {ISO week-based calendar 1872-W52-7} {
+    clock format -3061238400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1872-W52-7
+} {Sun Sunday 72 1872 7 52 52 0 52}
+test clock-3.11 {ISO week-based calendar 1873-W01-1} {
+    clock format -3061152000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1873-W01-1
+} {Mon Monday 73 1873 1 52 01 1 53}
+test clock-3.12 {ISO week-based calendar 1873-W01-3} {
+    clock format -3060979200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1873-W01-3
+} {Wed Wednesday 73 1873 3 00 01 3 00}
+test clock-3.13 {ISO week-based calendar 1873-W01-6} {
+    clock format -3060720000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1873-W01-6
+} {Sat Saturday 73 1873 6 00 01 6 00}
+test clock-3.14 {ISO week-based calendar 1873-W01-7} {
+    clock format -3060633600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1873-W01-7
+} {Sun Sunday 73 1873 7 01 01 0 00}
+test clock-3.15 {ISO week-based calendar 1873-W02-1} {
+    clock format -3060547200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1873-W02-1
+} {Mon Monday 73 1873 1 01 02 1 01}
+test clock-3.16 {ISO week-based calendar 1875-W52-1} {
+    clock format -2966803200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1875-W52-1
+} {Mon Monday 75 1875 1 52 52 1 52}
+test clock-3.17 {ISO week-based calendar 1875-W52-6} {
+    clock format -2966371200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1875-W52-6
+} {Sat Saturday 75 1875 6 00 52 6 00}
+test clock-3.18 {ISO week-based calendar 1875-W52-7} {
+    clock format -2966284800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1875-W52-7
+} {Sun Sunday 75 1875 7 01 52 0 00}
+test clock-3.19 {ISO week-based calendar 1876-W01-1} {
+    clock format -2966198400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1876-W01-1
+} {Mon Monday 76 1876 1 01 01 1 01}
+test clock-3.20 {ISO week-based calendar 1876-W01-6} {
+    clock format -2965766400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1876-W01-6
+} {Sat Saturday 76 1876 6 01 01 6 01}
+test clock-3.21 {ISO week-based calendar 1876-W01-7} {
+    clock format -2965680000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1876-W01-7
+} {Sun Sunday 76 1876 7 02 01 0 01}
+test clock-3.22 {ISO week-based calendar 1876-W02-1} {
+    clock format -2965593600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1876-W02-1
+} {Mon Monday 76 1876 1 02 02 1 02}
+test clock-3.23 {ISO week-based calendar 1876-W52-1} {
+    clock format -2935353600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1876-W52-1
+} {Mon Monday 76 1876 1 52 52 1 52}
+test clock-3.24 {ISO week-based calendar 1876-W52-6} {
+    clock format -2934921600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1876-W52-6
+} {Sat Saturday 76 1876 6 52 52 6 52}
+test clock-3.25 {ISO week-based calendar 1876-W52-7} {
+    clock format -2934835200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1876-W52-7
+} {Sun Sunday 76 1876 7 53 52 0 52}
+test clock-3.26 {ISO week-based calendar 1877-W01-1} {
+    clock format -2934748800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1877-W01-1
+} {Mon Monday 77 1877 1 00 01 1 01}
+test clock-3.27 {ISO week-based calendar 1877-W01-6} {
+    clock format -2934316800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1877-W01-6
+} {Sat Saturday 77 1877 6 00 01 6 01}
+test clock-3.28 {ISO week-based calendar 1877-W01-7} {
+    clock format -2934230400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1877-W01-7
+} {Sun Sunday 77 1877 7 01 01 0 01}
+test clock-3.29 {ISO week-based calendar 1877-W02-1} {
+    clock format -2934144000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1877-W02-1
+} {Mon Monday 77 1877 1 01 02 1 02}
+test clock-3.30 {ISO week-based calendar 1879-W52-1} {
+    clock format -2841004800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1879-W52-1
+} {Mon Monday 79 1879 1 51 52 1 51}
+test clock-3.31 {ISO week-based calendar 1879-W52-6} {
+    clock format -2840572800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1879-W52-6
+} {Sat Saturday 79 1879 6 51 52 6 51}
+test clock-3.32 {ISO week-based calendar 1879-W52-7} {
+    clock format -2840486400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1879-W52-7
+} {Sun Sunday 79 1879 7 52 52 0 51}
+test clock-3.33 {ISO week-based calendar 1880-W01-1} {
+    clock format -2840400000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1880-W01-1
+} {Mon Monday 80 1880 1 52 01 1 52}
+test clock-3.34 {ISO week-based calendar 1880-W01-4} {
+    clock format -2840140800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1880-W01-4
+} {Thu Thursday 80 1880 4 00 01 4 00}
+test clock-3.35 {ISO week-based calendar 1880-W01-6} {
+    clock format -2839968000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1880-W01-6
+} {Sat Saturday 80 1880 6 00 01 6 00}
+test clock-3.36 {ISO week-based calendar 1880-W01-7} {
+    clock format -2839881600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1880-W01-7
+} {Sun Sunday 80 1880 7 01 01 0 00}
+test clock-3.37 {ISO week-based calendar 1880-W02-1} {
+    clock format -2839795200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1880-W02-1
+} {Mon Monday 80 1880 1 01 02 1 01}
+test clock-3.38 {ISO week-based calendar 1880-W53-1} {
+    clock format -2808950400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1880-W53-1
+} {Mon Monday 80 1880 1 52 53 1 52}
+test clock-3.39 {ISO week-based calendar 1880-W53-6} {
+    clock format -2808518400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1880-W53-6
+} {Sat Saturday 80 1880 6 00 53 6 00}
+test clock-3.40 {ISO week-based calendar 1880-W53-7} {
+    clock format -2808432000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1880-W53-7
+} {Sun Sunday 80 1880 7 01 53 0 00}
+test clock-3.41 {ISO week-based calendar 1881-W01-1} {
+    clock format -2808345600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1881-W01-1
+} {Mon Monday 81 1881 1 01 01 1 01}
+test clock-3.42 {ISO week-based calendar 1881-W01-6} {
+    clock format -2807913600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1881-W01-6
+} {Sat Saturday 81 1881 6 01 01 6 01}
+test clock-3.43 {ISO week-based calendar 1881-W01-7} {
+    clock format -2807827200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1881-W01-7
+} {Sun Sunday 81 1881 7 02 01 0 01}
+test clock-3.44 {ISO week-based calendar 1881-W02-1} {
+    clock format -2807740800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1881-W02-1
+} {Mon Monday 81 1881 1 02 02 1 02}
+test clock-3.45 {ISO week-based calendar 1883-W52-1} {
+    clock format -2714601600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1883-W52-1
+} {Mon Monday 83 1883 1 51 52 1 52}
+test clock-3.46 {ISO week-based calendar 1883-W52-6} {
+    clock format -2714169600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1883-W52-6
+} {Sat Saturday 83 1883 6 51 52 6 52}
+test clock-3.47 {ISO week-based calendar 1883-W52-7} {
+    clock format -2714083200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1883-W52-7
+} {Sun Sunday 83 1883 7 52 52 0 52}
+test clock-3.48 {ISO week-based calendar 1884-W01-1} {
+    clock format -2713996800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1884-W01-1
+} {Mon Monday 84 1884 1 52 01 1 53}
+test clock-3.49 {ISO week-based calendar 1884-W01-2} {
+    clock format -2713910400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1884-W01-2
+} {Tue Tuesday 84 1884 2 00 01 2 00}
+test clock-3.50 {ISO week-based calendar 1884-W01-6} {
+    clock format -2713564800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1884-W01-6
+} {Sat Saturday 84 1884 6 00 01 6 00}
+test clock-3.51 {ISO week-based calendar 1884-W01-7} {
+    clock format -2713478400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1884-W01-7
+} {Sun Sunday 84 1884 7 01 01 0 00}
+test clock-3.52 {ISO week-based calendar 1884-W02-1} {
+    clock format -2713392000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1884-W02-1
+} {Mon Monday 84 1884 1 01 02 1 01}
+test clock-3.53 {ISO week-based calendar 1884-W52-1} {
+    clock format -2683152000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1884-W52-1
+} {Mon Monday 84 1884 1 51 52 1 51}
+test clock-3.54 {ISO week-based calendar 1884-W52-6} {
+    clock format -2682720000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1884-W52-6
+} {Sat Saturday 84 1884 6 51 52 6 51}
+test clock-3.55 {ISO week-based calendar 1884-W52-7} {
+    clock format -2682633600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1884-W52-7
+} {Sun Sunday 84 1884 7 52 52 0 51}
+test clock-3.56 {ISO week-based calendar 1885-W01-1} {
+    clock format -2682547200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1885-W01-1
+} {Mon Monday 85 1885 1 52 01 1 52}
+test clock-3.57 {ISO week-based calendar 1885-W01-4} {
+    clock format -2682288000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1885-W01-4
+} {Thu Thursday 85 1885 4 00 01 4 00}
+test clock-3.58 {ISO week-based calendar 1885-W01-6} {
+    clock format -2682115200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1885-W01-6
+} {Sat Saturday 85 1885 6 00 01 6 00}
+test clock-3.59 {ISO week-based calendar 1885-W01-7} {
+    clock format -2682028800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1885-W01-7
+} {Sun Sunday 85 1885 7 01 01 0 00}
+test clock-3.60 {ISO week-based calendar 1885-W02-1} {
+    clock format -2681942400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1885-W02-1
+} {Mon Monday 85 1885 1 01 02 1 01}
+test clock-3.61 {ISO week-based calendar 1887-W52-1} {
+    clock format -2588198400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1887-W52-1
+} {Mon Monday 87 1887 1 52 52 1 52}
+test clock-3.62 {ISO week-based calendar 1887-W52-6} {
+    clock format -2587766400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1887-W52-6
+} {Sat Saturday 87 1887 6 52 52 6 52}
+test clock-3.63 {ISO week-based calendar 1887-W52-7} {
+    clock format -2587680000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1887-W52-7
+} {Sun Sunday 87 1887 7 01 52 0 00}
+test clock-3.64 {ISO week-based calendar 1888-W01-1} {
+    clock format -2587593600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1888-W01-1
+} {Mon Monday 88 1888 1 01 01 1 01}
+test clock-3.65 {ISO week-based calendar 1888-W01-6} {
+    clock format -2587161600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1888-W01-6
+} {Sat Saturday 88 1888 6 01 01 6 01}
+test clock-3.66 {ISO week-based calendar 1888-W01-7} {
+    clock format -2587075200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1888-W01-7
+} {Sun Sunday 88 1888 7 02 01 0 01}
+test clock-3.67 {ISO week-based calendar 1888-W02-1} {
+    clock format -2586988800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1888-W02-1
+} {Mon Monday 88 1888 1 02 02 1 02}
+test clock-3.68 {ISO week-based calendar 1888-W52-1} {
+    clock format -2556748800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1888-W52-1
+} {Mon Monday 88 1888 1 52 52 1 52}
+test clock-3.69 {ISO week-based calendar 1888-W52-6} {
+    clock format -2556316800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1888-W52-6
+} {Sat Saturday 88 1888 6 52 52 6 52}
+test clock-3.70 {ISO week-based calendar 1888-W52-7} {
+    clock format -2556230400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1888-W52-7
+} {Sun Sunday 88 1888 7 53 52 0 52}
+test clock-3.71 {ISO week-based calendar 1889-W01-1} {
+    clock format -2556144000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1889-W01-1
+} {Mon Monday 89 1889 1 53 01 1 53}
+test clock-3.72 {ISO week-based calendar 1889-W01-2} {
+    clock format -2556057600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1889-W01-2
+} {Tue Tuesday 89 1889 2 00 01 2 00}
+test clock-3.73 {ISO week-based calendar 1889-W01-6} {
+    clock format -2555712000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1889-W01-6
+} {Sat Saturday 89 1889 6 00 01 6 00}
+test clock-3.74 {ISO week-based calendar 1889-W01-7} {
+    clock format -2555625600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1889-W01-7
+} {Sun Sunday 89 1889 7 01 01 0 00}
+test clock-3.75 {ISO week-based calendar 1889-W02-1} {
+    clock format -2555539200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1889-W02-1
+} {Mon Monday 89 1889 1 01 02 1 01}
+test clock-3.76 {ISO week-based calendar 1889-W52-1} {
+    clock format -2525299200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1889-W52-1
+} {Mon Monday 89 1889 1 51 52 1 51}
+test clock-3.77 {ISO week-based calendar 1889-W52-6} {
+    clock format -2524867200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1889-W52-6
+} {Sat Saturday 89 1889 6 51 52 6 51}
+test clock-3.78 {ISO week-based calendar 1889-W52-7} {
+    clock format -2524780800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1889-W52-7
+} {Sun Sunday 89 1889 7 52 52 0 51}
+test clock-3.79 {ISO week-based calendar 1890-W01-1} {
+    clock format -2524694400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1890-W01-1
+} {Mon Monday 90 1890 1 52 01 1 52}
+test clock-3.80 {ISO week-based calendar 1890-W01-3} {
+    clock format -2524521600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1890-W01-3
+} {Wed Wednesday 90 1890 3 00 01 3 00}
+test clock-3.81 {ISO week-based calendar 1890-W01-6} {
+    clock format -2524262400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1890-W01-6
+} {Sat Saturday 90 1890 6 00 01 6 00}
+test clock-3.82 {ISO week-based calendar 1890-W01-7} {
+    clock format -2524176000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1890-W01-7
+} {Sun Sunday 90 1890 7 01 01 0 00}
+test clock-3.83 {ISO week-based calendar 1890-W02-1} {
+    clock format -2524089600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1890-W02-1
+} {Mon Monday 90 1890 1 01 02 1 01}
+test clock-3.84 {ISO week-based calendar 1890-W52-1} {
+    clock format -2493849600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1890-W52-1
+} {Mon Monday 90 1890 1 51 52 1 51}
+test clock-3.85 {ISO week-based calendar 1890-W52-6} {
+    clock format -2493417600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1890-W52-6
+} {Sat Saturday 90 1890 6 51 52 6 51}
+test clock-3.86 {ISO week-based calendar 1890-W52-7} {
+    clock format -2493331200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1890-W52-7
+} {Sun Sunday 90 1890 7 52 52 0 51}
+test clock-3.87 {ISO week-based calendar 1891-W01-1} {
+    clock format -2493244800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1891-W01-1
+} {Mon Monday 91 1891 1 52 01 1 52}
+test clock-3.88 {ISO week-based calendar 1891-W01-4} {
+    clock format -2492985600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1891-W01-4
+} {Thu Thursday 91 1891 4 00 01 4 00}
+test clock-3.89 {ISO week-based calendar 1891-W01-6} {
+    clock format -2492812800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1891-W01-6
+} {Sat Saturday 91 1891 6 00 01 6 00}
+test clock-3.90 {ISO week-based calendar 1891-W01-7} {
+    clock format -2492726400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1891-W01-7
+} {Sun Sunday 91 1891 7 01 01 0 00}
+test clock-3.91 {ISO week-based calendar 1891-W02-1} {
+    clock format -2492640000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1891-W02-1
+} {Mon Monday 91 1891 1 01 02 1 01}
+test clock-3.92 {ISO week-based calendar 1891-W53-1} {
+    clock format -2461795200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1891-W53-1
+} {Mon Monday 91 1891 1 52 53 1 52}
+test clock-3.93 {ISO week-based calendar 1891-W53-5} {
+    clock format -2461449600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1891-W53-5
+} {Fri Friday 91 1891 5 00 53 5 00}
+test clock-3.94 {ISO week-based calendar 1891-W53-6} {
+    clock format -2461363200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1891-W53-6
+} {Sat Saturday 91 1891 6 00 53 6 00}
+test clock-3.95 {ISO week-based calendar 1891-W53-7} {
+    clock format -2461276800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1891-W53-7
+} {Sun Sunday 91 1891 7 01 53 0 00}
+test clock-3.96 {ISO week-based calendar 1892-W01-1} {
+    clock format -2461190400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1892-W01-1
+} {Mon Monday 92 1892 1 01 01 1 01}
+test clock-3.97 {ISO week-based calendar 1892-W01-6} {
+    clock format -2460758400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1892-W01-6
+} {Sat Saturday 92 1892 6 01 01 6 01}
+test clock-3.98 {ISO week-based calendar 1892-W01-7} {
+    clock format -2460672000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1892-W01-7
+} {Sun Sunday 92 1892 7 02 01 0 01}
+test clock-3.99 {ISO week-based calendar 1892-W02-1} {
+    clock format -2460585600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1892-W02-1
+} {Mon Monday 92 1892 1 02 02 1 02}
+test clock-3.100 {ISO week-based calendar 1892-W52-1} {
+    clock format -2430345600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1892-W52-1
+} {Mon Monday 92 1892 1 52 52 1 52}
+test clock-3.101 {ISO week-based calendar 1892-W52-6} {
+    clock format -2429913600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1892-W52-6
+} {Sat Saturday 92 1892 6 52 52 6 52}
+test clock-3.102 {ISO week-based calendar 1892-W52-7} {
+    clock format -2429827200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1892-W52-7
+} {Sun Sunday 92 1892 7 01 52 0 00}
+test clock-3.103 {ISO week-based calendar 1893-W01-1} {
+    clock format -2429740800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1893-W01-1
+} {Mon Monday 93 1893 1 01 01 1 01}
+test clock-3.104 {ISO week-based calendar 1893-W01-6} {
+    clock format -2429308800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1893-W01-6
+} {Sat Saturday 93 1893 6 01 01 6 01}
+test clock-3.105 {ISO week-based calendar 1893-W01-7} {
+    clock format -2429222400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1893-W01-7
+} {Sun Sunday 93 1893 7 02 01 0 01}
+test clock-3.106 {ISO week-based calendar 1893-W02-1} {
+    clock format -2429136000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1893-W02-1
+} {Mon Monday 93 1893 1 02 02 1 02}
+test clock-3.107 {ISO week-based calendar 1893-W52-1} {
+    clock format -2398896000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1893-W52-1
+} {Mon Monday 93 1893 1 52 52 1 52}
+test clock-3.108 {ISO week-based calendar 1893-W52-6} {
+    clock format -2398464000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1893-W52-6
+} {Sat Saturday 93 1893 6 52 52 6 52}
+test clock-3.109 {ISO week-based calendar 1893-W52-7} {
+    clock format -2398377600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1893-W52-7
+} {Sun Sunday 93 1893 7 53 52 0 52}
+test clock-3.110 {ISO week-based calendar 1894-W01-1} {
+    clock format -2398291200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1894-W01-1
+} {Mon Monday 94 1894 1 00 01 1 01}
+test clock-3.111 {ISO week-based calendar 1894-W01-6} {
+    clock format -2397859200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1894-W01-6
+} {Sat Saturday 94 1894 6 00 01 6 01}
+test clock-3.112 {ISO week-based calendar 1894-W01-7} {
+    clock format -2397772800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1894-W01-7
+} {Sun Sunday 94 1894 7 01 01 0 01}
+test clock-3.113 {ISO week-based calendar 1894-W02-1} {
+    clock format -2397686400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1894-W02-1
+} {Mon Monday 94 1894 1 01 02 1 02}
+test clock-3.114 {ISO week-based calendar 1894-W52-1} {
+    clock format -2367446400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1894-W52-1
+} {Mon Monday 94 1894 1 51 52 1 52}
+test clock-3.115 {ISO week-based calendar 1894-W52-6} {
+    clock format -2367014400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1894-W52-6
+} {Sat Saturday 94 1894 6 51 52 6 52}
+test clock-3.116 {ISO week-based calendar 1894-W52-7} {
+    clock format -2366928000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1894-W52-7
+} {Sun Sunday 94 1894 7 52 52 0 52}
+test clock-3.117 {ISO week-based calendar 1895-W01-1} {
+    clock format -2366841600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1895-W01-1
+} {Mon Monday 95 1895 1 52 01 1 53}
+test clock-3.118 {ISO week-based calendar 1895-W01-2} {
+    clock format -2366755200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1895-W01-2
+} {Tue Tuesday 95 1895 2 00 01 2 00}
+test clock-3.119 {ISO week-based calendar 1895-W01-6} {
+    clock format -2366409600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1895-W01-6
+} {Sat Saturday 95 1895 6 00 01 6 00}
+test clock-3.120 {ISO week-based calendar 1895-W01-7} {
+    clock format -2366323200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1895-W01-7
+} {Sun Sunday 95 1895 7 01 01 0 00}
+test clock-3.121 {ISO week-based calendar 1895-W02-1} {
+    clock format -2366236800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1895-W02-1
+} {Mon Monday 95 1895 1 01 02 1 01}
+test clock-3.122 {ISO week-based calendar 1895-W52-1} {
+    clock format -2335996800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1895-W52-1
+} {Mon Monday 95 1895 1 51 52 1 51}
+test clock-3.123 {ISO week-based calendar 1895-W52-6} {
+    clock format -2335564800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1895-W52-6
+} {Sat Saturday 95 1895 6 51 52 6 51}
+test clock-3.124 {ISO week-based calendar 1895-W52-7} {
+    clock format -2335478400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1895-W52-7
+} {Sun Sunday 95 1895 7 52 52 0 51}
+test clock-3.125 {ISO week-based calendar 1896-W01-1} {
+    clock format -2335392000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1896-W01-1
+} {Mon Monday 96 1896 1 52 01 1 52}
+test clock-3.126 {ISO week-based calendar 1896-W01-3} {
+    clock format -2335219200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1896-W01-3
+} {Wed Wednesday 96 1896 3 00 01 3 00}
+test clock-3.127 {ISO week-based calendar 1896-W01-6} {
+    clock format -2334960000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1896-W01-6
+} {Sat Saturday 96 1896 6 00 01 6 00}
+test clock-3.128 {ISO week-based calendar 1896-W01-7} {
+    clock format -2334873600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1896-W01-7
+} {Sun Sunday 96 1896 7 01 01 0 00}
+test clock-3.129 {ISO week-based calendar 1896-W02-1} {
+    clock format -2334787200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1896-W02-1
+} {Mon Monday 96 1896 1 01 02 1 01}
+test clock-3.130 {ISO week-based calendar 1896-W53-1} {
+    clock format -2303942400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1896-W53-1
+} {Mon Monday 96 1896 1 52 53 1 52}
+test clock-3.131 {ISO week-based calendar 1896-W53-5} {
+    clock format -2303596800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1896-W53-5
+} {Fri Friday 96 1896 5 00 53 5 00}
+test clock-3.132 {ISO week-based calendar 1896-W53-6} {
+    clock format -2303510400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1896-W53-6
+} {Sat Saturday 96 1896 6 00 53 6 00}
+test clock-3.133 {ISO week-based calendar 1896-W53-7} {
+    clock format -2303424000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1896-W53-7
+} {Sun Sunday 96 1896 7 01 53 0 00}
+test clock-3.134 {ISO week-based calendar 1897-W01-1} {
+    clock format -2303337600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1897-W01-1
+} {Mon Monday 97 1897 1 01 01 1 01}
+test clock-3.135 {ISO week-based calendar 1897-W01-6} {
+    clock format -2302905600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1897-W01-6
+} {Sat Saturday 97 1897 6 01 01 6 01}
+test clock-3.136 {ISO week-based calendar 1897-W01-7} {
+    clock format -2302819200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1897-W01-7
+} {Sun Sunday 97 1897 7 02 01 0 01}
+test clock-3.137 {ISO week-based calendar 1897-W02-1} {
+    clock format -2302732800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1897-W02-1
+} {Mon Monday 97 1897 1 02 02 1 02}
+test clock-3.138 {ISO week-based calendar 1897-W52-1} {
+    clock format -2272492800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1897-W52-1
+} {Mon Monday 97 1897 1 52 52 1 52}
+test clock-3.139 {ISO week-based calendar 1897-W52-6} {
+    clock format -2272060800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1897-W52-6
+} {Sat Saturday 97 1897 6 00 52 6 00}
+test clock-3.140 {ISO week-based calendar 1897-W52-7} {
+    clock format -2271974400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1897-W52-7
+} {Sun Sunday 97 1897 7 01 52 0 00}
+test clock-3.141 {ISO week-based calendar 1898-W01-1} {
+    clock format -2271888000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1898-W01-1
+} {Mon Monday 98 1898 1 01 01 1 01}
+test clock-3.142 {ISO week-based calendar 1898-W01-6} {
+    clock format -2271456000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1898-W01-6
+} {Sat Saturday 98 1898 6 01 01 6 01}
+test clock-3.143 {ISO week-based calendar 1898-W01-7} {
+    clock format -2271369600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1898-W01-7
+} {Sun Sunday 98 1898 7 02 01 0 01}
+test clock-3.144 {ISO week-based calendar 1898-W02-1} {
+    clock format -2271283200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1898-W02-1
+} {Mon Monday 98 1898 1 02 02 1 02}
+test clock-3.145 {ISO week-based calendar 1898-W52-1} {
+    clock format -2241043200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1898-W52-1
+} {Mon Monday 98 1898 1 52 52 1 52}
+test clock-3.146 {ISO week-based calendar 1898-W52-6} {
+    clock format -2240611200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1898-W52-6
+} {Sat Saturday 98 1898 6 52 52 6 52}
+test clock-3.147 {ISO week-based calendar 1898-W52-7} {
+    clock format -2240524800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1898-W52-7
+} {Sun Sunday 98 1898 7 01 52 0 00}
+test clock-3.148 {ISO week-based calendar 1899-W01-1} {
+    clock format -2240438400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1899-W01-1
+} {Mon Monday 99 1899 1 01 01 1 01}
+test clock-3.149 {ISO week-based calendar 1899-W01-6} {
+    clock format -2240006400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1899-W01-6
+} {Sat Saturday 99 1899 6 01 01 6 01}
+test clock-3.150 {ISO week-based calendar 1899-W01-7} {
+    clock format -2239920000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1899-W01-7
+} {Sun Sunday 99 1899 7 02 01 0 01}
+test clock-3.151 {ISO week-based calendar 1899-W02-1} {
+    clock format -2239833600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1899-W02-1
+} {Mon Monday 99 1899 1 02 02 1 02}
+test clock-3.152 {ISO week-based calendar 1899-W52-1} {
+    clock format -2209593600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1899-W52-1
+} {Mon Monday 99 1899 1 52 52 1 52}
+test clock-3.153 {ISO week-based calendar 1899-W52-6} {
+    clock format -2209161600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1899-W52-6
+} {Sat Saturday 99 1899 6 52 52 6 52}
+test clock-3.154 {ISO week-based calendar 1899-W52-7} {
+    clock format -2209075200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1899-W52-7
+} {Sun Sunday 99 1899 7 53 52 0 52}
+test clock-3.155 {ISO week-based calendar 1900-W01-1} {
+    clock format -2208988800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1900-W01-1
+} {Mon Monday 00 1900 1 00 01 1 01}
+test clock-3.156 {ISO week-based calendar 1900-W01-6} {
+    clock format -2208556800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1900-W01-6
+} {Sat Saturday 00 1900 6 00 01 6 01}
+test clock-3.157 {ISO week-based calendar 1900-W01-7} {
+    clock format -2208470400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1900-W01-7
+} {Sun Sunday 00 1900 7 01 01 0 01}
+test clock-3.158 {ISO week-based calendar 1900-W02-1} {
+    clock format -2208384000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1900-W02-1
+} {Mon Monday 00 1900 1 01 02 1 02}
+test clock-3.159 {ISO week-based calendar 1943-W52-1} {
+    clock format -820972800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1943-W52-1
+} {Mon Monday 43 1943 1 52 52 1 52}
+test clock-3.160 {ISO week-based calendar 1943-W52-6} {
+    clock format -820540800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1943-W52-6
+} {Sat Saturday 43 1943 6 00 52 6 00}
+test clock-3.161 {ISO week-based calendar 1943-W52-7} {
+    clock format -820454400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1943-W52-7
+} {Sun Sunday 43 1943 7 01 52 0 00}
+test clock-3.162 {ISO week-based calendar 1944-W01-1} {
+    clock format -820368000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1944-W01-1
+} {Mon Monday 44 1944 1 01 01 1 01}
+test clock-3.163 {ISO week-based calendar 1944-W01-6} {
+    clock format -819936000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1944-W01-6
+} {Sat Saturday 44 1944 6 01 01 6 01}
+test clock-3.164 {ISO week-based calendar 1944-W01-7} {
+    clock format -819849600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1944-W01-7
+} {Sun Sunday 44 1944 7 02 01 0 01}
+test clock-3.165 {ISO week-based calendar 1944-W02-1} {
+    clock format -819763200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1944-W02-1
+} {Mon Monday 44 1944 1 02 02 1 02}
+test clock-3.166 {ISO week-based calendar 1944-W52-1} {
+    clock format -789523200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1944-W52-1
+} {Mon Monday 44 1944 1 52 52 1 52}
+test clock-3.167 {ISO week-based calendar 1944-W52-6} {
+    clock format -789091200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1944-W52-6
+} {Sat Saturday 44 1944 6 52 52 6 52}
+test clock-3.168 {ISO week-based calendar 1944-W52-7} {
+    clock format -789004800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1944-W52-7
+} {Sun Sunday 44 1944 7 53 52 0 52}
+test clock-3.169 {ISO week-based calendar 1945-W01-1} {
+    clock format -788918400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1945-W01-1
+} {Mon Monday 45 1945 1 00 01 1 01}
+test clock-3.170 {ISO week-based calendar 1945-W01-6} {
+    clock format -788486400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1945-W01-6
+} {Sat Saturday 45 1945 6 00 01 6 01}
+test clock-3.171 {ISO week-based calendar 1945-W01-7} {
+    clock format -788400000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1945-W01-7
+} {Sun Sunday 45 1945 7 01 01 0 01}
+test clock-3.172 {ISO week-based calendar 1945-W02-1} {
+    clock format -788313600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1945-W02-1
+} {Mon Monday 45 1945 1 01 02 1 02}
+test clock-3.173 {ISO week-based calendar 1947-W52-1} {
+    clock format -695174400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1947-W52-1
+} {Mon Monday 47 1947 1 51 52 1 51}
+test clock-3.174 {ISO week-based calendar 1947-W52-6} {
+    clock format -694742400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1947-W52-6
+} {Sat Saturday 47 1947 6 51 52 6 51}
+test clock-3.175 {ISO week-based calendar 1947-W52-7} {
+    clock format -694656000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1947-W52-7
+} {Sun Sunday 47 1947 7 52 52 0 51}
+test clock-3.176 {ISO week-based calendar 1948-W01-1} {
+    clock format -694569600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1948-W01-1
+} {Mon Monday 48 1948 1 52 01 1 52}
+test clock-3.177 {ISO week-based calendar 1948-W01-4} {
+    clock format -694310400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1948-W01-4
+} {Thu Thursday 48 1948 4 00 01 4 00}
+test clock-3.178 {ISO week-based calendar 1948-W01-6} {
+    clock format -694137600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1948-W01-6
+} {Sat Saturday 48 1948 6 00 01 6 00}
+test clock-3.179 {ISO week-based calendar 1948-W01-7} {
+    clock format -694051200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1948-W01-7
+} {Sun Sunday 48 1948 7 01 01 0 00}
+test clock-3.180 {ISO week-based calendar 1948-W02-1} {
+    clock format -693964800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1948-W02-1
+} {Mon Monday 48 1948 1 01 02 1 01}
+test clock-3.181 {ISO week-based calendar 1948-W53-1} {
+    clock format -663120000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1948-W53-1
+} {Mon Monday 48 1948 1 52 53 1 52}
+test clock-3.182 {ISO week-based calendar 1948-W53-6} {
+    clock format -662688000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1948-W53-6
+} {Sat Saturday 48 1948 6 00 53 6 00}
+test clock-3.183 {ISO week-based calendar 1948-W53-7} {
+    clock format -662601600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1948-W53-7
+} {Sun Sunday 48 1948 7 01 53 0 00}
+test clock-3.184 {ISO week-based calendar 1949-W01-1} {
+    clock format -662515200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1949-W01-1
+} {Mon Monday 49 1949 1 01 01 1 01}
+test clock-3.185 {ISO week-based calendar 1949-W01-6} {
+    clock format -662083200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1949-W01-6
+} {Sat Saturday 49 1949 6 01 01 6 01}
+test clock-3.186 {ISO week-based calendar 1949-W01-7} {
+    clock format -661996800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1949-W01-7
+} {Sun Sunday 49 1949 7 02 01 0 01}
+test clock-3.187 {ISO week-based calendar 1949-W02-1} {
+    clock format -661910400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1949-W02-1
+} {Mon Monday 49 1949 1 02 02 1 02}
+test clock-3.188 {ISO week-based calendar 1951-W52-1} {
+    clock format -568771200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1951-W52-1
+} {Mon Monday 51 1951 1 51 52 1 52}
+test clock-3.189 {ISO week-based calendar 1951-W52-6} {
+    clock format -568339200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1951-W52-6
+} {Sat Saturday 51 1951 6 51 52 6 52}
+test clock-3.190 {ISO week-based calendar 1951-W52-7} {
+    clock format -568252800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1951-W52-7
+} {Sun Sunday 51 1951 7 52 52 0 52}
+test clock-3.191 {ISO week-based calendar 1952-W01-1} {
+    clock format -568166400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1952-W01-1
+} {Mon Monday 52 1952 1 52 01 1 53}
+test clock-3.192 {ISO week-based calendar 1952-W01-2} {
+    clock format -568080000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1952-W01-2
+} {Tue Tuesday 52 1952 2 00 01 2 00}
+test clock-3.193 {ISO week-based calendar 1952-W01-6} {
+    clock format -567734400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1952-W01-6
+} {Sat Saturday 52 1952 6 00 01 6 00}
+test clock-3.194 {ISO week-based calendar 1952-W01-7} {
+    clock format -567648000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1952-W01-7
+} {Sun Sunday 52 1952 7 01 01 0 00}
+test clock-3.195 {ISO week-based calendar 1952-W02-1} {
+    clock format -567561600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1952-W02-1
+} {Mon Monday 52 1952 1 01 02 1 01}
+test clock-3.196 {ISO week-based calendar 1952-W52-1} {
+    clock format -537321600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1952-W52-1
+} {Mon Monday 52 1952 1 51 52 1 51}
+test clock-3.197 {ISO week-based calendar 1952-W52-6} {
+    clock format -536889600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1952-W52-6
+} {Sat Saturday 52 1952 6 51 52 6 51}
+test clock-3.198 {ISO week-based calendar 1952-W52-7} {
+    clock format -536803200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1952-W52-7
+} {Sun Sunday 52 1952 7 52 52 0 51}
+test clock-3.199 {ISO week-based calendar 1953-W01-1} {
+    clock format -536716800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1953-W01-1
+} {Mon Monday 53 1953 1 52 01 1 52}
+test clock-3.200 {ISO week-based calendar 1953-W01-4} {
+    clock format -536457600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1953-W01-4
+} {Thu Thursday 53 1953 4 00 01 4 00}
+test clock-3.201 {ISO week-based calendar 1953-W01-6} {
+    clock format -536284800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1953-W01-6
+} {Sat Saturday 53 1953 6 00 01 6 00}
+test clock-3.202 {ISO week-based calendar 1953-W01-7} {
+    clock format -536198400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1953-W01-7
+} {Sun Sunday 53 1953 7 01 01 0 00}
+test clock-3.203 {ISO week-based calendar 1953-W02-1} {
+    clock format -536112000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1953-W02-1
+} {Mon Monday 53 1953 1 01 02 1 01}
+test clock-3.204 {ISO week-based calendar 1955-W52-1} {
+    clock format -442368000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1955-W52-1
+} {Mon Monday 55 1955 1 52 52 1 52}
+test clock-3.205 {ISO week-based calendar 1955-W52-6} {
+    clock format -441936000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1955-W52-6
+} {Sat Saturday 55 1955 6 52 52 6 52}
+test clock-3.206 {ISO week-based calendar 1955-W52-7} {
+    clock format -441849600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1955-W52-7
+} {Sun Sunday 55 1955 7 01 52 0 00}
+test clock-3.207 {ISO week-based calendar 1956-W01-1} {
+    clock format -441763200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1956-W01-1
+} {Mon Monday 56 1956 1 01 01 1 01}
+test clock-3.208 {ISO week-based calendar 1956-W01-6} {
+    clock format -441331200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1956-W01-6
+} {Sat Saturday 56 1956 6 01 01 6 01}
+test clock-3.209 {ISO week-based calendar 1956-W01-7} {
+    clock format -441244800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1956-W01-7
+} {Sun Sunday 56 1956 7 02 01 0 01}
+test clock-3.210 {ISO week-based calendar 1956-W02-1} {
+    clock format -441158400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1956-W02-1
+} {Mon Monday 56 1956 1 02 02 1 02}
+test clock-3.211 {ISO week-based calendar 1956-W52-1} {
+    clock format -410918400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1956-W52-1
+} {Mon Monday 56 1956 1 52 52 1 52}
+test clock-3.212 {ISO week-based calendar 1956-W52-6} {
+    clock format -410486400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1956-W52-6
+} {Sat Saturday 56 1956 6 52 52 6 52}
+test clock-3.213 {ISO week-based calendar 1956-W52-7} {
+    clock format -410400000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1956-W52-7
+} {Sun Sunday 56 1956 7 53 52 0 52}
+test clock-3.214 {ISO week-based calendar 1957-W01-1} {
+    clock format -410313600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1957-W01-1
+} {Mon Monday 57 1957 1 53 01 1 53}
+test clock-3.215 {ISO week-based calendar 1957-W01-2} {
+    clock format -410227200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1957-W01-2
+} {Tue Tuesday 57 1957 2 00 01 2 00}
+test clock-3.216 {ISO week-based calendar 1957-W01-6} {
+    clock format -409881600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1957-W01-6
+} {Sat Saturday 57 1957 6 00 01 6 00}
+test clock-3.217 {ISO week-based calendar 1957-W01-7} {
+    clock format -409795200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1957-W01-7
+} {Sun Sunday 57 1957 7 01 01 0 00}
+test clock-3.218 {ISO week-based calendar 1957-W02-1} {
+    clock format -409708800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1957-W02-1
+} {Mon Monday 57 1957 1 01 02 1 01}
+test clock-3.219 {ISO week-based calendar 1958-W52-1} {
+    clock format -348019200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1958-W52-1
+} {Mon Monday 58 1958 1 51 52 1 51}
+test clock-3.220 {ISO week-based calendar 1958-W52-6} {
+    clock format -347587200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1958-W52-6
+} {Sat Saturday 58 1958 6 51 52 6 51}
+test clock-3.221 {ISO week-based calendar 1958-W52-7} {
+    clock format -347500800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1958-W52-7
+} {Sun Sunday 58 1958 7 52 52 0 51}
+test clock-3.222 {ISO week-based calendar 1959-W01-1} {
+    clock format -347414400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1959-W01-1
+} {Mon Monday 59 1959 1 52 01 1 52}
+test clock-3.223 {ISO week-based calendar 1959-W01-4} {
+    clock format -347155200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1959-W01-4
+} {Thu Thursday 59 1959 4 00 01 4 00}
+test clock-3.224 {ISO week-based calendar 1959-W01-6} {
+    clock format -346982400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1959-W01-6
+} {Sat Saturday 59 1959 6 00 01 6 00}
+test clock-3.225 {ISO week-based calendar 1959-W01-7} {
+    clock format -346896000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1959-W01-7
+} {Sun Sunday 59 1959 7 01 01 0 00}
+test clock-3.226 {ISO week-based calendar 1959-W02-1} {
+    clock format -346809600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1959-W02-1
+} {Mon Monday 59 1959 1 01 02 1 01}
+test clock-3.227 {ISO week-based calendar 1959-W53-1} {
+    clock format -315964800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1959-W53-1
+} {Mon Monday 59 1959 1 52 53 1 52}
+test clock-3.228 {ISO week-based calendar 1959-W53-5} {
+    clock format -315619200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1959-W53-5
+} {Fri Friday 59 1959 5 00 53 5 00}
+test clock-3.229 {ISO week-based calendar 1959-W53-6} {
+    clock format -315532800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1959-W53-6
+} {Sat Saturday 59 1959 6 00 53 6 00}
+test clock-3.230 {ISO week-based calendar 1959-W53-7} {
+    clock format -315446400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1959-W53-7
+} {Sun Sunday 59 1959 7 01 53 0 00}
+test clock-3.231 {ISO week-based calendar 1960-W01-1} {
+    clock format -315360000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1960-W01-1
+} {Mon Monday 60 1960 1 01 01 1 01}
+test clock-3.232 {ISO week-based calendar 1960-W01-6} {
+    clock format -314928000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1960-W01-6
+} {Sat Saturday 60 1960 6 01 01 6 01}
+test clock-3.233 {ISO week-based calendar 1960-W01-7} {
+    clock format -314841600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1960-W01-7
+} {Sun Sunday 60 1960 7 02 01 0 01}
+test clock-3.234 {ISO week-based calendar 1960-W02-1} {
+    clock format -314755200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1960-W02-1
+} {Mon Monday 60 1960 1 02 02 1 02}
+test clock-3.235 {ISO week-based calendar 1960-W52-1} {
+    clock format -284515200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1960-W52-1
+} {Mon Monday 60 1960 1 52 52 1 52}
+test clock-3.236 {ISO week-based calendar 1960-W52-6} {
+    clock format -284083200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1960-W52-6
+} {Sat Saturday 60 1960 6 52 52 6 52}
+test clock-3.237 {ISO week-based calendar 1960-W52-7} {
+    clock format -283996800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1960-W52-7
+} {Sun Sunday 60 1960 7 01 52 0 00}
+test clock-3.238 {ISO week-based calendar 1961-W01-1} {
+    clock format -283910400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1961-W01-1
+} {Mon Monday 61 1961 1 01 01 1 01}
+test clock-3.239 {ISO week-based calendar 1961-W01-6} {
+    clock format -283478400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1961-W01-6
+} {Sat Saturday 61 1961 6 01 01 6 01}
+test clock-3.240 {ISO week-based calendar 1961-W01-7} {
+    clock format -283392000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1961-W01-7
+} {Sun Sunday 61 1961 7 02 01 0 01}
+test clock-3.241 {ISO week-based calendar 1961-W02-1} {
+    clock format -283305600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1961-W02-1
+} {Mon Monday 61 1961 1 02 02 1 02}
+test clock-3.242 {ISO week-based calendar 1961-W52-1} {
+    clock format -253065600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1961-W52-1
+} {Mon Monday 61 1961 1 52 52 1 52}
+test clock-3.243 {ISO week-based calendar 1961-W52-6} {
+    clock format -252633600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1961-W52-6
+} {Sat Saturday 61 1961 6 52 52 6 52}
+test clock-3.244 {ISO week-based calendar 1961-W52-7} {
+    clock format -252547200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1961-W52-7
+} {Sun Sunday 61 1961 7 53 52 0 52}
+test clock-3.245 {ISO week-based calendar 1962-W01-1} {
+    clock format -252460800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1962-W01-1
+} {Mon Monday 62 1962 1 00 01 1 01}
+test clock-3.246 {ISO week-based calendar 1962-W01-6} {
+    clock format -252028800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1962-W01-6
+} {Sat Saturday 62 1962 6 00 01 6 01}
+test clock-3.247 {ISO week-based calendar 1962-W01-7} {
+    clock format -251942400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1962-W01-7
+} {Sun Sunday 62 1962 7 01 01 0 01}
+test clock-3.248 {ISO week-based calendar 1962-W02-1} {
+    clock format -251856000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1962-W02-1
+} {Mon Monday 62 1962 1 01 02 1 02}
+test clock-3.249 {ISO week-based calendar 1962-W52-1} {
+    clock format -221616000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1962-W52-1
+} {Mon Monday 62 1962 1 51 52 1 52}
+test clock-3.250 {ISO week-based calendar 1962-W52-6} {
+    clock format -221184000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1962-W52-6
+} {Sat Saturday 62 1962 6 51 52 6 52}
+test clock-3.251 {ISO week-based calendar 1962-W52-7} {
+    clock format -221097600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1962-W52-7
+} {Sun Sunday 62 1962 7 52 52 0 52}
+test clock-3.252 {ISO week-based calendar 1963-W01-1} {
+    clock format -221011200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1963-W01-1
+} {Mon Monday 63 1963 1 52 01 1 53}
+test clock-3.253 {ISO week-based calendar 1963-W01-2} {
+    clock format -220924800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1963-W01-2
+} {Tue Tuesday 63 1963 2 00 01 2 00}
+test clock-3.254 {ISO week-based calendar 1963-W01-6} {
+    clock format -220579200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1963-W01-6
+} {Sat Saturday 63 1963 6 00 01 6 00}
+test clock-3.255 {ISO week-based calendar 1963-W01-7} {
+    clock format -220492800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1963-W01-7
+} {Sun Sunday 63 1963 7 01 01 0 00}
+test clock-3.256 {ISO week-based calendar 1963-W02-1} {
+    clock format -220406400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1963-W02-1
+} {Mon Monday 63 1963 1 01 02 1 01}
+test clock-3.257 {ISO week-based calendar 1963-W52-1} {
+    clock format -190166400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1963-W52-1
+} {Mon Monday 63 1963 1 51 52 1 51}
+test clock-3.258 {ISO week-based calendar 1963-W52-6} {
+    clock format -189734400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1963-W52-6
+} {Sat Saturday 63 1963 6 51 52 6 51}
+test clock-3.259 {ISO week-based calendar 1963-W52-7} {
+    clock format -189648000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1963-W52-7
+} {Sun Sunday 63 1963 7 52 52 0 51}
+test clock-3.260 {ISO week-based calendar 1964-W01-1} {
+    clock format -189561600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1964-W01-1
+} {Mon Monday 64 1964 1 52 01 1 52}
+test clock-3.261 {ISO week-based calendar 1964-W01-3} {
+    clock format -189388800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1964-W01-3
+} {Wed Wednesday 64 1964 3 00 01 3 00}
+test clock-3.262 {ISO week-based calendar 1964-W01-6} {
+    clock format -189129600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1964-W01-6
+} {Sat Saturday 64 1964 6 00 01 6 00}
+test clock-3.263 {ISO week-based calendar 1964-W01-7} {
+    clock format -189043200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1964-W01-7
+} {Sun Sunday 64 1964 7 01 01 0 00}
+test clock-3.264 {ISO week-based calendar 1964-W02-1} {
+    clock format -188956800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1964-W02-1
+} {Mon Monday 64 1964 1 01 02 1 01}
+test clock-3.265 {ISO week-based calendar 1964-W53-1} {
+    clock format -158112000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1964-W53-1
+} {Mon Monday 64 1964 1 52 53 1 52}
+test clock-3.266 {ISO week-based calendar 1964-W53-5} {
+    clock format -157766400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1964-W53-5
+} {Fri Friday 64 1964 5 00 53 5 00}
+test clock-3.267 {ISO week-based calendar 1964-W53-6} {
+    clock format -157680000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1964-W53-6
+} {Sat Saturday 64 1964 6 00 53 6 00}
+test clock-3.268 {ISO week-based calendar 1964-W53-7} {
+    clock format -157593600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1964-W53-7
+} {Sun Sunday 64 1964 7 01 53 0 00}
+test clock-3.269 {ISO week-based calendar 1965-W01-1} {
+    clock format -157507200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1965-W01-1
+} {Mon Monday 65 1965 1 01 01 1 01}
+test clock-3.270 {ISO week-based calendar 1965-W01-6} {
+    clock format -157075200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1965-W01-6
+} {Sat Saturday 65 1965 6 01 01 6 01}
+test clock-3.271 {ISO week-based calendar 1965-W01-7} {
+    clock format -156988800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1965-W01-7
+} {Sun Sunday 65 1965 7 02 01 0 01}
+test clock-3.272 {ISO week-based calendar 1965-W02-1} {
+    clock format -156902400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1965-W02-1
+} {Mon Monday 65 1965 1 02 02 1 02}
+test clock-3.273 {ISO week-based calendar 1965-W52-1} {
+    clock format -126662400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1965-W52-1
+} {Mon Monday 65 1965 1 52 52 1 52}
+test clock-3.274 {ISO week-based calendar 1965-W52-6} {
+    clock format -126230400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1965-W52-6
+} {Sat Saturday 65 1965 6 00 52 6 00}
+test clock-3.275 {ISO week-based calendar 1965-W52-7} {
+    clock format -126144000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1965-W52-7
+} {Sun Sunday 65 1965 7 01 52 0 00}
+test clock-3.276 {ISO week-based calendar 1966-W01-1} {
+    clock format -126057600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1966-W01-1
+} {Mon Monday 66 1966 1 01 01 1 01}
+test clock-3.277 {ISO week-based calendar 1966-W01-6} {
+    clock format -125625600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1966-W01-6
+} {Sat Saturday 66 1966 6 01 01 6 01}
+test clock-3.278 {ISO week-based calendar 1966-W01-7} {
+    clock format -125539200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1966-W01-7
+} {Sun Sunday 66 1966 7 02 01 0 01}
+test clock-3.279 {ISO week-based calendar 1966-W02-1} {
+    clock format -125452800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1966-W02-1
+} {Mon Monday 66 1966 1 02 02 1 02}
+test clock-3.280 {ISO week-based calendar 1966-W52-1} {
+    clock format -95212800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1966-W52-1
+} {Mon Monday 66 1966 1 52 52 1 52}
+test clock-3.281 {ISO week-based calendar 1966-W52-6} {
+    clock format -94780800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1966-W52-6
+} {Sat Saturday 66 1966 6 52 52 6 52}
+test clock-3.282 {ISO week-based calendar 1966-W52-7} {
+    clock format -94694400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1966-W52-7
+} {Sun Sunday 66 1966 7 01 52 0 00}
+test clock-3.283 {ISO week-based calendar 1967-W01-1} {
+    clock format -94608000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1967-W01-1
+} {Mon Monday 67 1967 1 01 01 1 01}
+test clock-3.284 {ISO week-based calendar 1967-W01-6} {
+    clock format -94176000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1967-W01-6
+} {Sat Saturday 67 1967 6 01 01 6 01}
+test clock-3.285 {ISO week-based calendar 1967-W01-7} {
+    clock format -94089600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1967-W01-7
+} {Sun Sunday 67 1967 7 02 01 0 01}
+test clock-3.286 {ISO week-based calendar 1967-W02-1} {
+    clock format -94003200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1967-W02-1
+} {Mon Monday 67 1967 1 02 02 1 02}
+test clock-3.287 {ISO week-based calendar 1967-W52-1} {
+    clock format -63763200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1967-W52-1
+} {Mon Monday 67 1967 1 52 52 1 52}
+test clock-3.288 {ISO week-based calendar 1967-W52-6} {
+    clock format -63331200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1967-W52-6
+} {Sat Saturday 67 1967 6 52 52 6 52}
+test clock-3.289 {ISO week-based calendar 1967-W52-7} {
+    clock format -63244800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1967-W52-7
+} {Sun Sunday 67 1967 7 53 52 0 52}
+test clock-3.290 {ISO week-based calendar 1968-W01-1} {
+    clock format -63158400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1968-W01-1
+} {Mon Monday 68 1968 1 00 01 1 01}
+test clock-3.291 {ISO week-based calendar 1968-W01-6} {
+    clock format -62726400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1968-W01-6
+} {Sat Saturday 68 1968 6 00 01 6 01}
+test clock-3.292 {ISO week-based calendar 1968-W01-7} {
+    clock format -62640000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1968-W01-7
+} {Sun Sunday 68 1968 7 01 01 0 01}
+test clock-3.293 {ISO week-based calendar 1968-W02-1} {
+    clock format -62553600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1968-W02-1
+} {Mon Monday 68 1968 1 01 02 1 02}
+test clock-3.294 {ISO week-based calendar 1968-W52-1} {
+    clock format -32313600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1968-W52-1
+} {Mon Monday 68 1968 1 51 52 1 52}
+test clock-3.295 {ISO week-based calendar 1968-W52-6} {
+    clock format -31881600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1968-W52-6
+} {Sat Saturday 68 1968 6 51 52 6 52}
+test clock-3.296 {ISO week-based calendar 1968-W52-7} {
+    clock format -31795200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1968-W52-7
+} {Sun Sunday 68 1968 7 52 52 0 52}
+test clock-3.297 {ISO week-based calendar 1969-W01-1} {
+    clock format -31708800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1969-W01-1
+} {Mon Monday 69 1969 1 52 01 1 53}
+test clock-3.298 {ISO week-based calendar 1969-W01-3} {
+    clock format -31536000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1969-W01-3
+} {Wed Wednesday 69 1969 3 00 01 3 00}
+test clock-3.299 {ISO week-based calendar 1969-W01-6} {
+    clock format -31276800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1969-W01-6
+} {Sat Saturday 69 1969 6 00 01 6 00}
+test clock-3.300 {ISO week-based calendar 1969-W01-7} {
+    clock format -31190400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1969-W01-7
+} {Sun Sunday 69 1969 7 01 01 0 00}
+test clock-3.301 {ISO week-based calendar 1969-W02-1} {
+    clock format -31104000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1969-W02-1
+} {Mon Monday 69 1969 1 01 02 1 01}
+test clock-3.302 {ISO week-based calendar 1969-W52-1} {
+    clock format -864000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1969-W52-1
+} {Mon Monday 69 1969 1 51 52 1 51}
+test clock-3.303 {ISO week-based calendar 1969-W52-6} {
+    clock format -432000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1969-W52-6
+} {Sat Saturday 69 1969 6 51 52 6 51}
+test clock-3.304 {ISO week-based calendar 1969-W52-7} {
+    clock format -345600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1969-W52-7
+} {Sun Sunday 69 1969 7 52 52 0 51}
+test clock-3.305 {ISO week-based calendar 1970-W01-1} {
+    clock format -259200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1970-W01-1
+} {Mon Monday 70 1970 1 52 01 1 52}
+test clock-3.306 {ISO week-based calendar 1970-W01-4} {
+    clock format 0 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1970-W01-4
+} {Thu Thursday 70 1970 4 00 01 4 00}
+test clock-3.307 {ISO week-based calendar 1970-W01-6} {
+    clock format 172800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1970-W01-6
+} {Sat Saturday 70 1970 6 00 01 6 00}
+test clock-3.308 {ISO week-based calendar 1970-W01-7} {
+    clock format 259200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1970-W01-7
+} {Sun Sunday 70 1970 7 01 01 0 00}
+test clock-3.309 {ISO week-based calendar 1970-W02-1} {
+    clock format 345600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1970-W02-1
+} {Mon Monday 70 1970 1 01 02 1 01}
+test clock-3.310 {ISO week-based calendar 1970-W53-1} {
+    clock format 31190400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1970-W53-1
+} {Mon Monday 70 1970 1 52 53 1 52}
+test clock-3.311 {ISO week-based calendar 1970-W53-5} {
+    clock format 31536000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1970-W53-5
+} {Fri Friday 70 1970 5 00 53 5 00}
+test clock-3.312 {ISO week-based calendar 1970-W53-6} {
+    clock format 31622400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1970-W53-6
+} {Sat Saturday 70 1970 6 00 53 6 00}
+test clock-3.313 {ISO week-based calendar 1970-W53-7} {
+    clock format 31708800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1970-W53-7
+} {Sun Sunday 70 1970 7 01 53 0 00}
+test clock-3.314 {ISO week-based calendar 1971-W01-1} {
+    clock format 31795200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1971-W01-1
+} {Mon Monday 71 1971 1 01 01 1 01}
+test clock-3.315 {ISO week-based calendar 1971-W01-6} {
+    clock format 32227200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1971-W01-6
+} {Sat Saturday 71 1971 6 01 01 6 01}
+test clock-3.316 {ISO week-based calendar 1971-W01-7} {
+    clock format 32313600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1971-W01-7
+} {Sun Sunday 71 1971 7 02 01 0 01}
+test clock-3.317 {ISO week-based calendar 1971-W02-1} {
+    clock format 32400000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1971-W02-1
+} {Mon Monday 71 1971 1 02 02 1 02}
+test clock-3.318 {ISO week-based calendar 1971-W52-1} {
+    clock format 62640000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1971-W52-1
+} {Mon Monday 71 1971 1 52 52 1 52}
+test clock-3.319 {ISO week-based calendar 1971-W52-6} {
+    clock format 63072000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1971-W52-6
+} {Sat Saturday 71 1971 6 00 52 6 00}
+test clock-3.320 {ISO week-based calendar 1971-W52-7} {
+    clock format 63158400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1971-W52-7
+} {Sun Sunday 71 1971 7 01 52 0 00}
+test clock-3.321 {ISO week-based calendar 1972-W01-1} {
+    clock format 63244800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1972-W01-1
+} {Mon Monday 72 1972 1 01 01 1 01}
+test clock-3.322 {ISO week-based calendar 1972-W01-6} {
+    clock format 63676800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1972-W01-6
+} {Sat Saturday 72 1972 6 01 01 6 01}
+test clock-3.323 {ISO week-based calendar 1972-W01-7} {
+    clock format 63763200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1972-W01-7
+} {Sun Sunday 72 1972 7 02 01 0 01}
+test clock-3.324 {ISO week-based calendar 1972-W02-1} {
+    clock format 63849600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1972-W02-1
+} {Mon Monday 72 1972 1 02 02 1 02}
+test clock-3.325 {ISO week-based calendar 1972-W52-1} {
+    clock format 94089600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1972-W52-1
+} {Mon Monday 72 1972 1 52 52 1 52}
+test clock-3.326 {ISO week-based calendar 1972-W52-6} {
+    clock format 94521600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1972-W52-6
+} {Sat Saturday 72 1972 6 52 52 6 52}
+test clock-3.327 {ISO week-based calendar 1972-W52-7} {
+    clock format 94608000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1972-W52-7
+} {Sun Sunday 72 1972 7 53 52 0 52}
+test clock-3.328 {ISO week-based calendar 1973-W01-1} {
+    clock format 94694400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1973-W01-1
+} {Mon Monday 73 1973 1 00 01 1 01}
+test clock-3.329 {ISO week-based calendar 1973-W01-6} {
+    clock format 95126400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1973-W01-6
+} {Sat Saturday 73 1973 6 00 01 6 01}
+test clock-3.330 {ISO week-based calendar 1973-W01-7} {
+    clock format 95212800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1973-W01-7
+} {Sun Sunday 73 1973 7 01 01 0 01}
+test clock-3.331 {ISO week-based calendar 1973-W02-1} {
+    clock format 95299200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1973-W02-1
+} {Mon Monday 73 1973 1 01 02 1 02}
+test clock-3.332 {ISO week-based calendar 1973-W52-1} {
+    clock format 125539200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1973-W52-1
+} {Mon Monday 73 1973 1 51 52 1 52}
+test clock-3.333 {ISO week-based calendar 1973-W52-6} {
+    clock format 125971200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1973-W52-6
+} {Sat Saturday 73 1973 6 51 52 6 52}
+test clock-3.334 {ISO week-based calendar 1973-W52-7} {
+    clock format 126057600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1973-W52-7
+} {Sun Sunday 73 1973 7 52 52 0 52}
+test clock-3.335 {ISO week-based calendar 1974-W01-1} {
+    clock format 126144000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1974-W01-1
+} {Mon Monday 74 1974 1 52 01 1 53}
+test clock-3.336 {ISO week-based calendar 1974-W01-2} {
+    clock format 126230400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1974-W01-2
+} {Tue Tuesday 74 1974 2 00 01 2 00}
+test clock-3.337 {ISO week-based calendar 1974-W01-6} {
+    clock format 126576000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1974-W01-6
+} {Sat Saturday 74 1974 6 00 01 6 00}
+test clock-3.338 {ISO week-based calendar 1974-W01-7} {
+    clock format 126662400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1974-W01-7
+} {Sun Sunday 74 1974 7 01 01 0 00}
+test clock-3.339 {ISO week-based calendar 1974-W02-1} {
+    clock format 126748800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1974-W02-1
+} {Mon Monday 74 1974 1 01 02 1 01}
+test clock-3.340 {ISO week-based calendar 1974-W52-1} {
+    clock format 156988800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1974-W52-1
+} {Mon Monday 74 1974 1 51 52 1 51}
+test clock-3.341 {ISO week-based calendar 1974-W52-6} {
+    clock format 157420800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1974-W52-6
+} {Sat Saturday 74 1974 6 51 52 6 51}
+test clock-3.342 {ISO week-based calendar 1974-W52-7} {
+    clock format 157507200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1974-W52-7
+} {Sun Sunday 74 1974 7 52 52 0 51}
+test clock-3.343 {ISO week-based calendar 1975-W01-1} {
+    clock format 157593600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1975-W01-1
+} {Mon Monday 75 1975 1 52 01 1 52}
+test clock-3.344 {ISO week-based calendar 1975-W01-3} {
+    clock format 157766400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1975-W01-3
+} {Wed Wednesday 75 1975 3 00 01 3 00}
+test clock-3.345 {ISO week-based calendar 1975-W01-6} {
+    clock format 158025600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1975-W01-6
+} {Sat Saturday 75 1975 6 00 01 6 00}
+test clock-3.346 {ISO week-based calendar 1975-W01-7} {
+    clock format 158112000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1975-W01-7
+} {Sun Sunday 75 1975 7 01 01 0 00}
+test clock-3.347 {ISO week-based calendar 1975-W02-1} {
+    clock format 158198400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1975-W02-1
+} {Mon Monday 75 1975 1 01 02 1 01}
+test clock-3.348 {ISO week-based calendar 1975-W52-1} {
+    clock format 188438400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1975-W52-1
+} {Mon Monday 75 1975 1 51 52 1 51}
+test clock-3.349 {ISO week-based calendar 1975-W52-6} {
+    clock format 188870400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1975-W52-6
+} {Sat Saturday 75 1975 6 51 52 6 51}
+test clock-3.350 {ISO week-based calendar 1975-W52-7} {
+    clock format 188956800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1975-W52-7
+} {Sun Sunday 75 1975 7 52 52 0 51}
+test clock-3.351 {ISO week-based calendar 1976-W01-1} {
+    clock format 189043200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1976-W01-1
+} {Mon Monday 76 1976 1 52 01 1 52}
+test clock-3.352 {ISO week-based calendar 1976-W01-4} {
+    clock format 189302400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1976-W01-4
+} {Thu Thursday 76 1976 4 00 01 4 00}
+test clock-3.353 {ISO week-based calendar 1976-W01-6} {
+    clock format 189475200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1976-W01-6
+} {Sat Saturday 76 1976 6 00 01 6 00}
+test clock-3.354 {ISO week-based calendar 1976-W01-7} {
+    clock format 189561600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1976-W01-7
+} {Sun Sunday 76 1976 7 01 01 0 00}
+test clock-3.355 {ISO week-based calendar 1976-W02-1} {
+    clock format 189648000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1976-W02-1
+} {Mon Monday 76 1976 1 01 02 1 01}
+test clock-3.356 {ISO week-based calendar 1976-W53-1} {
+    clock format 220492800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1976-W53-1
+} {Mon Monday 76 1976 1 52 53 1 52}
+test clock-3.357 {ISO week-based calendar 1976-W53-6} {
+    clock format 220924800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1976-W53-6
+} {Sat Saturday 76 1976 6 00 53 6 00}
+test clock-3.358 {ISO week-based calendar 1976-W53-7} {
+    clock format 221011200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1976-W53-7
+} {Sun Sunday 76 1976 7 01 53 0 00}
+test clock-3.359 {ISO week-based calendar 1977-W01-1} {
+    clock format 221097600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1977-W01-1
+} {Mon Monday 77 1977 1 01 01 1 01}
+test clock-3.360 {ISO week-based calendar 1977-W01-6} {
+    clock format 221529600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1977-W01-6
+} {Sat Saturday 77 1977 6 01 01 6 01}
+test clock-3.361 {ISO week-based calendar 1977-W01-7} {
+    clock format 221616000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1977-W01-7
+} {Sun Sunday 77 1977 7 02 01 0 01}
+test clock-3.362 {ISO week-based calendar 1977-W02-1} {
+    clock format 221702400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1977-W02-1
+} {Mon Monday 77 1977 1 02 02 1 02}
+test clock-3.363 {ISO week-based calendar 1977-W52-1} {
+    clock format 251942400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1977-W52-1
+} {Mon Monday 77 1977 1 52 52 1 52}
+test clock-3.364 {ISO week-based calendar 1977-W52-6} {
+    clock format 252374400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1977-W52-6
+} {Sat Saturday 77 1977 6 52 52 6 52}
+test clock-3.365 {ISO week-based calendar 1977-W52-7} {
+    clock format 252460800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1977-W52-7
+} {Sun Sunday 77 1977 7 01 52 0 00}
+test clock-3.366 {ISO week-based calendar 1978-W01-1} {
+    clock format 252547200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1978-W01-1
+} {Mon Monday 78 1978 1 01 01 1 01}
+test clock-3.367 {ISO week-based calendar 1978-W01-6} {
+    clock format 252979200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1978-W01-6
+} {Sat Saturday 78 1978 6 01 01 6 01}
+test clock-3.368 {ISO week-based calendar 1978-W01-7} {
+    clock format 253065600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1978-W01-7
+} {Sun Sunday 78 1978 7 02 01 0 01}
+test clock-3.369 {ISO week-based calendar 1978-W02-1} {
+    clock format 253152000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1978-W02-1
+} {Mon Monday 78 1978 1 02 02 1 02}
+test clock-3.370 {ISO week-based calendar 1978-W52-1} {
+    clock format 283392000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1978-W52-1
+} {Mon Monday 78 1978 1 52 52 1 52}
+test clock-3.371 {ISO week-based calendar 1978-W52-6} {
+    clock format 283824000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1978-W52-6
+} {Sat Saturday 78 1978 6 52 52 6 52}
+test clock-3.372 {ISO week-based calendar 1978-W52-7} {
+    clock format 283910400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1978-W52-7
+} {Sun Sunday 78 1978 7 53 52 0 52}
+test clock-3.373 {ISO week-based calendar 1979-W01-1} {
+    clock format 283996800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1979-W01-1
+} {Mon Monday 79 1979 1 00 01 1 01}
+test clock-3.374 {ISO week-based calendar 1979-W01-6} {
+    clock format 284428800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1979-W01-6
+} {Sat Saturday 79 1979 6 00 01 6 01}
+test clock-3.375 {ISO week-based calendar 1979-W01-7} {
+    clock format 284515200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1979-W01-7
+} {Sun Sunday 79 1979 7 01 01 0 01}
+test clock-3.376 {ISO week-based calendar 1979-W02-1} {
+    clock format 284601600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1979-W02-1
+} {Mon Monday 79 1979 1 01 02 1 02}
+test clock-3.377 {ISO week-based calendar 1979-W52-1} {
+    clock format 314841600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1979-W52-1
+} {Mon Monday 79 1979 1 51 52 1 52}
+test clock-3.378 {ISO week-based calendar 1979-W52-6} {
+    clock format 315273600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1979-W52-6
+} {Sat Saturday 79 1979 6 51 52 6 52}
+test clock-3.379 {ISO week-based calendar 1979-W52-7} {
+    clock format 315360000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1979-W52-7
+} {Sun Sunday 79 1979 7 52 52 0 52}
+test clock-3.380 {ISO week-based calendar 1980-W01-1} {
+    clock format 315446400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1980-W01-1
+} {Mon Monday 80 1980 1 52 01 1 53}
+test clock-3.381 {ISO week-based calendar 1980-W01-2} {
+    clock format 315532800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1980-W01-2
+} {Tue Tuesday 80 1980 2 00 01 2 00}
+test clock-3.382 {ISO week-based calendar 1980-W01-6} {
+    clock format 315878400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1980-W01-6
+} {Sat Saturday 80 1980 6 00 01 6 00}
+test clock-3.383 {ISO week-based calendar 1980-W01-7} {
+    clock format 315964800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1980-W01-7
+} {Sun Sunday 80 1980 7 01 01 0 00}
+test clock-3.384 {ISO week-based calendar 1980-W02-1} {
+    clock format 316051200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1980-W02-1
+} {Mon Monday 80 1980 1 01 02 1 01}
+test clock-3.385 {ISO week-based calendar 1980-W52-1} {
+    clock format 346291200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1980-W52-1
+} {Mon Monday 80 1980 1 51 52 1 51}
+test clock-3.386 {ISO week-based calendar 1980-W52-6} {
+    clock format 346723200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1980-W52-6
+} {Sat Saturday 80 1980 6 51 52 6 51}
+test clock-3.387 {ISO week-based calendar 1980-W52-7} {
+    clock format 346809600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1980-W52-7
+} {Sun Sunday 80 1980 7 52 52 0 51}
+test clock-3.388 {ISO week-based calendar 1981-W01-1} {
+    clock format 346896000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1981-W01-1
+} {Mon Monday 81 1981 1 52 01 1 52}
+test clock-3.389 {ISO week-based calendar 1981-W01-4} {
+    clock format 347155200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1981-W01-4
+} {Thu Thursday 81 1981 4 00 01 4 00}
+test clock-3.390 {ISO week-based calendar 1981-W01-6} {
+    clock format 347328000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1981-W01-6
+} {Sat Saturday 81 1981 6 00 01 6 00}
+test clock-3.391 {ISO week-based calendar 1981-W01-7} {
+    clock format 347414400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1981-W01-7
+} {Sun Sunday 81 1981 7 01 01 0 00}
+test clock-3.392 {ISO week-based calendar 1981-W02-1} {
+    clock format 347500800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1981-W02-1
+} {Mon Monday 81 1981 1 01 02 1 01}
+test clock-3.393 {ISO week-based calendar 1983-W52-1} {
+    clock format 441244800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1983-W52-1
+} {Mon Monday 83 1983 1 52 52 1 52}
+test clock-3.394 {ISO week-based calendar 1983-W52-6} {
+    clock format 441676800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1983-W52-6
+} {Sat Saturday 83 1983 6 52 52 6 52}
+test clock-3.395 {ISO week-based calendar 1983-W52-7} {
+    clock format 441763200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1983-W52-7
+} {Sun Sunday 83 1983 7 01 52 0 00}
+test clock-3.396 {ISO week-based calendar 1984-W01-1} {
+    clock format 441849600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1984-W01-1
+} {Mon Monday 84 1984 1 01 01 1 01}
+test clock-3.397 {ISO week-based calendar 1984-W01-6} {
+    clock format 442281600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1984-W01-6
+} {Sat Saturday 84 1984 6 01 01 6 01}
+test clock-3.398 {ISO week-based calendar 1984-W01-7} {
+    clock format 442368000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1984-W01-7
+} {Sun Sunday 84 1984 7 02 01 0 01}
+test clock-3.399 {ISO week-based calendar 1984-W02-1} {
+    clock format 442454400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1984-W02-1
+} {Mon Monday 84 1984 1 02 02 1 02}
+test clock-3.400 {ISO week-based calendar 1984-W52-1} {
+    clock format 472694400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1984-W52-1
+} {Mon Monday 84 1984 1 52 52 1 52}
+test clock-3.401 {ISO week-based calendar 1984-W52-6} {
+    clock format 473126400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1984-W52-6
+} {Sat Saturday 84 1984 6 52 52 6 52}
+test clock-3.402 {ISO week-based calendar 1984-W52-7} {
+    clock format 473212800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1984-W52-7
+} {Sun Sunday 84 1984 7 53 52 0 52}
+test clock-3.403 {ISO week-based calendar 1985-W01-1} {
+    clock format 473299200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1985-W01-1
+} {Mon Monday 85 1985 1 53 01 1 53}
+test clock-3.404 {ISO week-based calendar 1985-W01-2} {
+    clock format 473385600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1985-W01-2
+} {Tue Tuesday 85 1985 2 00 01 2 00}
+test clock-3.405 {ISO week-based calendar 1985-W01-6} {
+    clock format 473731200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1985-W01-6
+} {Sat Saturday 85 1985 6 00 01 6 00}
+test clock-3.406 {ISO week-based calendar 1985-W01-7} {
+    clock format 473817600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1985-W01-7
+} {Sun Sunday 85 1985 7 01 01 0 00}
+test clock-3.407 {ISO week-based calendar 1985-W02-1} {
+    clock format 473904000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1985-W02-1
+} {Mon Monday 85 1985 1 01 02 1 01}
+test clock-3.408 {ISO week-based calendar 1987-W53-1} {
+    clock format 567648000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1987-W53-1
+} {Mon Monday 87 1987 1 52 53 1 52}
+test clock-3.409 {ISO week-based calendar 1987-W53-5} {
+    clock format 567993600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1987-W53-5
+} {Fri Friday 87 1987 5 00 53 5 00}
+test clock-3.410 {ISO week-based calendar 1987-W53-6} {
+    clock format 568080000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1987-W53-6
+} {Sat Saturday 87 1987 6 00 53 6 00}
+test clock-3.411 {ISO week-based calendar 1987-W53-7} {
+    clock format 568166400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1987-W53-7
+} {Sun Sunday 87 1987 7 01 53 0 00}
+test clock-3.412 {ISO week-based calendar 1988-W01-1} {
+    clock format 568252800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1988-W01-1
+} {Mon Monday 88 1988 1 01 01 1 01}
+test clock-3.413 {ISO week-based calendar 1988-W01-6} {
+    clock format 568684800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1988-W01-6
+} {Sat Saturday 88 1988 6 01 01 6 01}
+test clock-3.414 {ISO week-based calendar 1988-W01-7} {
+    clock format 568771200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1988-W01-7
+} {Sun Sunday 88 1988 7 02 01 0 01}
+test clock-3.415 {ISO week-based calendar 1988-W02-1} {
+    clock format 568857600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1988-W02-1
+} {Mon Monday 88 1988 1 02 02 1 02}
+test clock-3.416 {ISO week-based calendar 1988-W52-1} {
+    clock format 599097600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1988-W52-1
+} {Mon Monday 88 1988 1 52 52 1 52}
+test clock-3.417 {ISO week-based calendar 1988-W52-6} {
+    clock format 599529600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1988-W52-6
+} {Sat Saturday 88 1988 6 52 52 6 52}
+test clock-3.418 {ISO week-based calendar 1988-W52-7} {
+    clock format 599616000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1988-W52-7
+} {Sun Sunday 88 1988 7 01 52 0 00}
+test clock-3.419 {ISO week-based calendar 1989-W01-1} {
+    clock format 599702400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1989-W01-1
+} {Mon Monday 89 1989 1 01 01 1 01}
+test clock-3.420 {ISO week-based calendar 1989-W01-6} {
+    clock format 600134400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1989-W01-6
+} {Sat Saturday 89 1989 6 01 01 6 01}
+test clock-3.421 {ISO week-based calendar 1989-W01-7} {
+    clock format 600220800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1989-W01-7
+} {Sun Sunday 89 1989 7 02 01 0 01}
+test clock-3.422 {ISO week-based calendar 1989-W02-1} {
+    clock format 600307200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1989-W02-1
+} {Mon Monday 89 1989 1 02 02 1 02}
+test clock-3.423 {ISO week-based calendar 1991-W52-1} {
+    clock format 693446400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1991-W52-1
+} {Mon Monday 91 1991 1 51 52 1 51}
+test clock-3.424 {ISO week-based calendar 1991-W52-6} {
+    clock format 693878400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1991-W52-6
+} {Sat Saturday 91 1991 6 51 52 6 51}
+test clock-3.425 {ISO week-based calendar 1991-W52-7} {
+    clock format 693964800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1991-W52-7
+} {Sun Sunday 91 1991 7 52 52 0 51}
+test clock-3.426 {ISO week-based calendar 1992-W01-1} {
+    clock format 694051200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1992-W01-1
+} {Mon Monday 92 1992 1 52 01 1 52}
+test clock-3.427 {ISO week-based calendar 1992-W01-3} {
+    clock format 694224000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1992-W01-3
+} {Wed Wednesday 92 1992 3 00 01 3 00}
+test clock-3.428 {ISO week-based calendar 1992-W01-6} {
+    clock format 694483200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1992-W01-6
+} {Sat Saturday 92 1992 6 00 01 6 00}
+test clock-3.429 {ISO week-based calendar 1992-W01-7} {
+    clock format 694569600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1992-W01-7
+} {Sun Sunday 92 1992 7 01 01 0 00}
+test clock-3.430 {ISO week-based calendar 1992-W02-1} {
+    clock format 694656000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1992-W02-1
+} {Mon Monday 92 1992 1 01 02 1 01}
+test clock-3.431 {ISO week-based calendar 1992-W53-1} {
+    clock format 725500800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1992-W53-1
+} {Mon Monday 92 1992 1 52 53 1 52}
+test clock-3.432 {ISO week-based calendar 1992-W53-5} {
+    clock format 725846400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1992-W53-5
+} {Fri Friday 92 1992 5 00 53 5 00}
+test clock-3.433 {ISO week-based calendar 1992-W53-6} {
+    clock format 725932800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1992-W53-6
+} {Sat Saturday 92 1992 6 00 53 6 00}
+test clock-3.434 {ISO week-based calendar 1992-W53-7} {
+    clock format 726019200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1992-W53-7
+} {Sun Sunday 92 1992 7 01 53 0 00}
+test clock-3.435 {ISO week-based calendar 1993-W01-1} {
+    clock format 726105600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1993-W01-1
+} {Mon Monday 93 1993 1 01 01 1 01}
+test clock-3.436 {ISO week-based calendar 1993-W01-6} {
+    clock format 726537600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1993-W01-6
+} {Sat Saturday 93 1993 6 01 01 6 01}
+test clock-3.437 {ISO week-based calendar 1993-W01-7} {
+    clock format 726624000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1993-W01-7
+} {Sun Sunday 93 1993 7 02 01 0 01}
+test clock-3.438 {ISO week-based calendar 1993-W02-1} {
+    clock format 726710400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1993-W02-1
+} {Mon Monday 93 1993 1 02 02 1 02}
+test clock-3.439 {ISO week-based calendar 1995-W52-1} {
+    clock format 819849600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1995-W52-1
+} {Mon Monday 95 1995 1 52 52 1 52}
+test clock-3.440 {ISO week-based calendar 1995-W52-6} {
+    clock format 820281600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1995-W52-6
+} {Sat Saturday 95 1995 6 52 52 6 52}
+test clock-3.441 {ISO week-based calendar 1995-W52-7} {
+    clock format 820368000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1995-W52-7
+} {Sun Sunday 95 1995 7 53 52 0 52}
+test clock-3.442 {ISO week-based calendar 1996-W01-1} {
+    clock format 820454400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1996-W01-1
+} {Mon Monday 96 1996 1 00 01 1 01}
+test clock-3.443 {ISO week-based calendar 1996-W01-6} {
+    clock format 820886400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1996-W01-6
+} {Sat Saturday 96 1996 6 00 01 6 01}
+test clock-3.444 {ISO week-based calendar 1996-W01-7} {
+    clock format 820972800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1996-W01-7
+} {Sun Sunday 96 1996 7 01 01 0 01}
+test clock-3.445 {ISO week-based calendar 1996-W02-1} {
+    clock format 821059200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1996-W02-1
+} {Mon Monday 96 1996 1 01 02 1 02}
+test clock-3.446 {ISO week-based calendar 1996-W52-1} {
+    clock format 851299200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1996-W52-1
+} {Mon Monday 96 1996 1 51 52 1 52}
+test clock-3.447 {ISO week-based calendar 1996-W52-6} {
+    clock format 851731200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1996-W52-6
+} {Sat Saturday 96 1996 6 51 52 6 52}
+test clock-3.448 {ISO week-based calendar 1996-W52-7} {
+    clock format 851817600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1996-W52-7
+} {Sun Sunday 96 1996 7 52 52 0 52}
+test clock-3.449 {ISO week-based calendar 1997-W01-1} {
+    clock format 851904000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1997-W01-1
+} {Mon Monday 97 1997 1 52 01 1 53}
+test clock-3.450 {ISO week-based calendar 1997-W01-3} {
+    clock format 852076800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1997-W01-3
+} {Wed Wednesday 97 1997 3 00 01 3 00}
+test clock-3.451 {ISO week-based calendar 1997-W01-6} {
+    clock format 852336000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1997-W01-6
+} {Sat Saturday 97 1997 6 00 01 6 00}
+test clock-3.452 {ISO week-based calendar 1997-W01-7} {
+    clock format 852422400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1997-W01-7
+} {Sun Sunday 97 1997 7 01 01 0 00}
+test clock-3.453 {ISO week-based calendar 1997-W02-1} {
+    clock format 852508800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1997-W02-1
+} {Mon Monday 97 1997 1 01 02 1 01}
+test clock-3.454 {ISO week-based calendar 1999-W52-1} {
+    clock format 946252800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1999-W52-1
+} {Mon Monday 99 1999 1 52 52 1 52}
+test clock-3.455 {ISO week-based calendar 1999-W52-6} {
+    clock format 946684800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1999-W52-6
+} {Sat Saturday 99 1999 6 00 52 6 00}
+test clock-3.456 {ISO week-based calendar 1999-W52-7} {
+    clock format 946771200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 1999-W52-7
+} {Sun Sunday 99 1999 7 01 52 0 00}
+test clock-3.457 {ISO week-based calendar 2000-W01-1} {
+    clock format 946857600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2000-W01-1
+} {Mon Monday 00 2000 1 01 01 1 01}
+test clock-3.458 {ISO week-based calendar 2000-W01-6} {
+    clock format 947289600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2000-W01-6
+} {Sat Saturday 00 2000 6 01 01 6 01}
+test clock-3.459 {ISO week-based calendar 2000-W01-7} {
+    clock format 947376000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2000-W01-7
+} {Sun Sunday 00 2000 7 02 01 0 01}
+test clock-3.460 {ISO week-based calendar 2000-W02-1} {
+    clock format 947462400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2000-W02-1
+} {Mon Monday 00 2000 1 02 02 1 02}
+test clock-3.461 {ISO week-based calendar 2000-W52-1} {
+    clock format 977702400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2000-W52-1
+} {Mon Monday 00 2000 1 52 52 1 52}
+test clock-3.462 {ISO week-based calendar 2000-W52-6} {
+    clock format 978134400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2000-W52-6
+} {Sat Saturday 00 2000 6 52 52 6 52}
+test clock-3.463 {ISO week-based calendar 2000-W52-7} {
+    clock format 978220800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2000-W52-7
+} {Sun Sunday 00 2000 7 53 52 0 52}
+test clock-3.464 {ISO week-based calendar 2001-W01-1} {
+    clock format 978307200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2001-W01-1
+} {Mon Monday 01 2001 1 00 01 1 01}
+test clock-3.465 {ISO week-based calendar 2001-W01-6} {
+    clock format 978739200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2001-W01-6
+} {Sat Saturday 01 2001 6 00 01 6 01}
+test clock-3.466 {ISO week-based calendar 2001-W01-7} {
+    clock format 978825600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2001-W01-7
+} {Sun Sunday 01 2001 7 01 01 0 01}
+test clock-3.467 {ISO week-based calendar 2001-W02-1} {
+    clock format 978912000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2001-W02-1
+} {Mon Monday 01 2001 1 01 02 1 02}
+test clock-3.468 {ISO week-based calendar 2001-W52-1} {
+    clock format 1009152000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2001-W52-1
+} {Mon Monday 01 2001 1 51 52 1 52}
+test clock-3.469 {ISO week-based calendar 2001-W52-6} {
+    clock format 1009584000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2001-W52-6
+} {Sat Saturday 01 2001 6 51 52 6 52}
+test clock-3.470 {ISO week-based calendar 2001-W52-7} {
+    clock format 1009670400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2001-W52-7
+} {Sun Sunday 01 2001 7 52 52 0 52}
+test clock-3.471 {ISO week-based calendar 2002-W01-1} {
+    clock format 1009756800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2002-W01-1
+} {Mon Monday 02 2002 1 52 01 1 53}
+test clock-3.472 {ISO week-based calendar 2002-W01-2} {
+    clock format 1009843200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2002-W01-2
+} {Tue Tuesday 02 2002 2 00 01 2 00}
+test clock-3.473 {ISO week-based calendar 2002-W01-6} {
+    clock format 1010188800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2002-W01-6
+} {Sat Saturday 02 2002 6 00 01 6 00}
+test clock-3.474 {ISO week-based calendar 2002-W01-7} {
+    clock format 1010275200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2002-W01-7
+} {Sun Sunday 02 2002 7 01 01 0 00}
+test clock-3.475 {ISO week-based calendar 2002-W02-1} {
+    clock format 1010361600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2002-W02-1
+} {Mon Monday 02 2002 1 01 02 1 01}
+test clock-3.476 {ISO week-based calendar 2002-W52-1} {
+    clock format 1040601600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2002-W52-1
+} {Mon Monday 02 2002 1 51 52 1 51}
+test clock-3.477 {ISO week-based calendar 2002-W52-6} {
+    clock format 1041033600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2002-W52-6
+} {Sat Saturday 02 2002 6 51 52 6 51}
+test clock-3.478 {ISO week-based calendar 2002-W52-7} {
+    clock format 1041120000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2002-W52-7
+} {Sun Sunday 02 2002 7 52 52 0 51}
+test clock-3.479 {ISO week-based calendar 2003-W01-1} {
+    clock format 1041206400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2003-W01-1
+} {Mon Monday 03 2003 1 52 01 1 52}
+test clock-3.480 {ISO week-based calendar 2003-W01-3} {
+    clock format 1041379200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2003-W01-3
+} {Wed Wednesday 03 2003 3 00 01 3 00}
+test clock-3.481 {ISO week-based calendar 2003-W01-6} {
+    clock format 1041638400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2003-W01-6
+} {Sat Saturday 03 2003 6 00 01 6 00}
+test clock-3.482 {ISO week-based calendar 2003-W01-7} {
+    clock format 1041724800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2003-W01-7
+} {Sun Sunday 03 2003 7 01 01 0 00}
+test clock-3.483 {ISO week-based calendar 2003-W02-1} {
+    clock format 1041811200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2003-W02-1
+} {Mon Monday 03 2003 1 01 02 1 01}
+test clock-3.484 {ISO week-based calendar 2003-W52-1} {
+    clock format 1072051200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2003-W52-1
+} {Mon Monday 03 2003 1 51 52 1 51}
+test clock-3.485 {ISO week-based calendar 2003-W52-6} {
+    clock format 1072483200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2003-W52-6
+} {Sat Saturday 03 2003 6 51 52 6 51}
+test clock-3.486 {ISO week-based calendar 2003-W52-7} {
+    clock format 1072569600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2003-W52-7
+} {Sun Sunday 03 2003 7 52 52 0 51}
+test clock-3.487 {ISO week-based calendar 2004-W01-1} {
+    clock format 1072656000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2004-W01-1
+} {Mon Monday 04 2004 1 52 01 1 52}
+test clock-3.488 {ISO week-based calendar 2004-W01-4} {
+    clock format 1072915200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2004-W01-4
+} {Thu Thursday 04 2004 4 00 01 4 00}
+test clock-3.489 {ISO week-based calendar 2004-W01-6} {
+    clock format 1073088000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2004-W01-6
+} {Sat Saturday 04 2004 6 00 01 6 00}
+test clock-3.490 {ISO week-based calendar 2004-W01-7} {
+    clock format 1073174400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2004-W01-7
+} {Sun Sunday 04 2004 7 01 01 0 00}
+test clock-3.491 {ISO week-based calendar 2004-W02-1} {
+    clock format 1073260800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2004-W02-1
+} {Mon Monday 04 2004 1 01 02 1 01}
+test clock-3.492 {ISO week-based calendar 2004-W53-1} {
+    clock format 1104105600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2004-W53-1
+} {Mon Monday 04 2004 1 52 53 1 52}
+test clock-3.493 {ISO week-based calendar 2004-W53-6} {
+    clock format 1104537600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2004-W53-6
+} {Sat Saturday 04 2004 6 00 53 6 00}
+test clock-3.494 {ISO week-based calendar 2004-W53-7} {
+    clock format 1104624000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2004-W53-7
+} {Sun Sunday 04 2004 7 01 53 0 00}
+test clock-3.495 {ISO week-based calendar 2005-W01-1} {
+    clock format 1104710400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2005-W01-1
+} {Mon Monday 05 2005 1 01 01 1 01}
+test clock-3.496 {ISO week-based calendar 2005-W01-6} {
+    clock format 1105142400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2005-W01-6
+} {Sat Saturday 05 2005 6 01 01 6 01}
+test clock-3.497 {ISO week-based calendar 2005-W01-7} {
+    clock format 1105228800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2005-W01-7
+} {Sun Sunday 05 2005 7 02 01 0 01}
+test clock-3.498 {ISO week-based calendar 2005-W02-1} {
+    clock format 1105315200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2005-W02-1
+} {Mon Monday 05 2005 1 02 02 1 02}
+test clock-3.499 {ISO week-based calendar 2005-W52-1} {
+    clock format 1135555200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2005-W52-1
+} {Mon Monday 05 2005 1 52 52 1 52}
+test clock-3.500 {ISO week-based calendar 2005-W52-6} {
+    clock format 1135987200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2005-W52-6
+} {Sat Saturday 05 2005 6 52 52 6 52}
+test clock-3.501 {ISO week-based calendar 2005-W52-7} {
+    clock format 1136073600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2005-W52-7
+} {Sun Sunday 05 2005 7 01 52 0 00}
+test clock-3.502 {ISO week-based calendar 2006-W01-1} {
+    clock format 1136160000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2006-W01-1
+} {Mon Monday 06 2006 1 01 01 1 01}
+test clock-3.503 {ISO week-based calendar 2006-W01-6} {
+    clock format 1136592000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2006-W01-6
+} {Sat Saturday 06 2006 6 01 01 6 01}
+test clock-3.504 {ISO week-based calendar 2006-W01-7} {
+    clock format 1136678400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2006-W01-7
+} {Sun Sunday 06 2006 7 02 01 0 01}
+test clock-3.505 {ISO week-based calendar 2006-W02-1} {
+    clock format 1136764800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2006-W02-1
+} {Mon Monday 06 2006 1 02 02 1 02}
+test clock-3.506 {ISO week-based calendar 2006-W52-1} {
+    clock format 1167004800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2006-W52-1
+} {Mon Monday 06 2006 1 52 52 1 52}
+test clock-3.507 {ISO week-based calendar 2006-W52-6} {
+    clock format 1167436800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2006-W52-6
+} {Sat Saturday 06 2006 6 52 52 6 52}
+test clock-3.508 {ISO week-based calendar 2006-W52-7} {
+    clock format 1167523200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2006-W52-7
+} {Sun Sunday 06 2006 7 53 52 0 52}
+test clock-3.509 {ISO week-based calendar 2007-W01-1} {
+    clock format 1167609600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2007-W01-1
+} {Mon Monday 07 2007 1 00 01 1 01}
+test clock-3.510 {ISO week-based calendar 2007-W01-6} {
+    clock format 1168041600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2007-W01-6
+} {Sat Saturday 07 2007 6 00 01 6 01}
+test clock-3.511 {ISO week-based calendar 2007-W01-7} {
+    clock format 1168128000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2007-W01-7
+} {Sun Sunday 07 2007 7 01 01 0 01}
+test clock-3.512 {ISO week-based calendar 2007-W02-1} {
+    clock format 1168214400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2007-W02-1
+} {Mon Monday 07 2007 1 01 02 1 02}
+test clock-3.513 {ISO week-based calendar 2007-W52-1} {
+    clock format 1198454400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2007-W52-1
+} {Mon Monday 07 2007 1 51 52 1 52}
+test clock-3.514 {ISO week-based calendar 2007-W52-6} {
+    clock format 1198886400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2007-W52-6
+} {Sat Saturday 07 2007 6 51 52 6 52}
+test clock-3.515 {ISO week-based calendar 2007-W52-7} {
+    clock format 1198972800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2007-W52-7
+} {Sun Sunday 07 2007 7 52 52 0 52}
+test clock-3.516 {ISO week-based calendar 2008-W01-1} {
+    clock format 1199059200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2008-W01-1
+} {Mon Monday 08 2008 1 52 01 1 53}
+test clock-3.517 {ISO week-based calendar 2008-W01-2} {
+    clock format 1199145600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2008-W01-2
+} {Tue Tuesday 08 2008 2 00 01 2 00}
+test clock-3.518 {ISO week-based calendar 2008-W01-6} {
+    clock format 1199491200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2008-W01-6
+} {Sat Saturday 08 2008 6 00 01 6 00}
+test clock-3.519 {ISO week-based calendar 2008-W01-7} {
+    clock format 1199577600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2008-W01-7
+} {Sun Sunday 08 2008 7 01 01 0 00}
+test clock-3.520 {ISO week-based calendar 2008-W02-1} {
+    clock format 1199664000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2008-W02-1
+} {Mon Monday 08 2008 1 01 02 1 01}
+test clock-3.521 {ISO week-based calendar 2008-W52-1} {
+    clock format 1229904000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2008-W52-1
+} {Mon Monday 08 2008 1 51 52 1 51}
+test clock-3.522 {ISO week-based calendar 2008-W52-6} {
+    clock format 1230336000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2008-W52-6
+} {Sat Saturday 08 2008 6 51 52 6 51}
+test clock-3.523 {ISO week-based calendar 2008-W52-7} {
+    clock format 1230422400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2008-W52-7
+} {Sun Sunday 08 2008 7 52 52 0 51}
+test clock-3.524 {ISO week-based calendar 2009-W01-1} {
+    clock format 1230508800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2009-W01-1
+} {Mon Monday 09 2009 1 52 01 1 52}
+test clock-3.525 {ISO week-based calendar 2009-W01-4} {
+    clock format 1230768000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2009-W01-4
+} {Thu Thursday 09 2009 4 00 01 4 00}
+test clock-3.526 {ISO week-based calendar 2009-W01-6} {
+    clock format 1230940800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2009-W01-6
+} {Sat Saturday 09 2009 6 00 01 6 00}
+test clock-3.527 {ISO week-based calendar 2009-W01-7} {
+    clock format 1231027200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2009-W01-7
+} {Sun Sunday 09 2009 7 01 01 0 00}
+test clock-3.528 {ISO week-based calendar 2009-W02-1} {
+    clock format 1231113600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2009-W02-1
+} {Mon Monday 09 2009 1 01 02 1 01}
+test clock-3.529 {ISO week-based calendar 2009-W53-1} {
+    clock format 1261958400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2009-W53-1
+} {Mon Monday 09 2009 1 52 53 1 52}
+test clock-3.530 {ISO week-based calendar 2009-W53-5} {
+    clock format 1262304000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2009-W53-5
+} {Fri Friday 09 2009 5 00 53 5 00}
+test clock-3.531 {ISO week-based calendar 2009-W53-6} {
+    clock format 1262390400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2009-W53-6
+} {Sat Saturday 09 2009 6 00 53 6 00}
+test clock-3.532 {ISO week-based calendar 2009-W53-7} {
+    clock format 1262476800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2009-W53-7
+} {Sun Sunday 09 2009 7 01 53 0 00}
+test clock-3.533 {ISO week-based calendar 2010-W01-1} {
+    clock format 1262563200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2010-W01-1
+} {Mon Monday 10 2010 1 01 01 1 01}
+test clock-3.534 {ISO week-based calendar 2010-W01-6} {
+    clock format 1262995200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2010-W01-6
+} {Sat Saturday 10 2010 6 01 01 6 01}
+test clock-3.535 {ISO week-based calendar 2010-W01-7} {
+    clock format 1263081600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2010-W01-7
+} {Sun Sunday 10 2010 7 02 01 0 01}
+test clock-3.536 {ISO week-based calendar 2010-W02-1} {
+    clock format 1263168000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2010-W02-1
+} {Mon Monday 10 2010 1 02 02 1 02}
+test clock-3.537 {ISO week-based calendar 2010-W52-1} {
+    clock format 1293408000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2010-W52-1
+} {Mon Monday 10 2010 1 52 52 1 52}
+test clock-3.538 {ISO week-based calendar 2010-W52-6} {
+    clock format 1293840000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2010-W52-6
+} {Sat Saturday 10 2010 6 00 52 6 00}
+test clock-3.539 {ISO week-based calendar 2010-W52-7} {
+    clock format 1293926400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2010-W52-7
+} {Sun Sunday 10 2010 7 01 52 0 00}
+test clock-3.540 {ISO week-based calendar 2011-W01-1} {
+    clock format 1294012800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2011-W01-1
+} {Mon Monday 11 2011 1 01 01 1 01}
+test clock-3.541 {ISO week-based calendar 2011-W01-6} {
+    clock format 1294444800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2011-W01-6
+} {Sat Saturday 11 2011 6 01 01 6 01}
+test clock-3.542 {ISO week-based calendar 2011-W01-7} {
+    clock format 1294531200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2011-W01-7
+} {Sun Sunday 11 2011 7 02 01 0 01}
+test clock-3.543 {ISO week-based calendar 2011-W02-1} {
+    clock format 1294617600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2011-W02-1
+} {Mon Monday 11 2011 1 02 02 1 02}
+test clock-3.544 {ISO week-based calendar 2011-W52-1} {
+    clock format 1324857600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2011-W52-1
+} {Mon Monday 11 2011 1 52 52 1 52}
+test clock-3.545 {ISO week-based calendar 2011-W52-6} {
+    clock format 1325289600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2011-W52-6
+} {Sat Saturday 11 2011 6 52 52 6 52}
+test clock-3.546 {ISO week-based calendar 2011-W52-7} {
+    clock format 1325376000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2011-W52-7
+} {Sun Sunday 11 2011 7 01 52 0 00}
+test clock-3.547 {ISO week-based calendar 2012-W01-1} {
+    clock format 1325462400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2012-W01-1
+} {Mon Monday 12 2012 1 01 01 1 01}
+test clock-3.548 {ISO week-based calendar 2012-W01-6} {
+    clock format 1325894400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2012-W01-6
+} {Sat Saturday 12 2012 6 01 01 6 01}
+test clock-3.549 {ISO week-based calendar 2012-W01-7} {
+    clock format 1325980800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2012-W01-7
+} {Sun Sunday 12 2012 7 02 01 0 01}
+test clock-3.550 {ISO week-based calendar 2012-W02-1} {
+    clock format 1326067200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2012-W02-1
+} {Mon Monday 12 2012 1 02 02 1 02}
+test clock-3.551 {ISO week-based calendar 2012-W52-1} {
+    clock format 1356307200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2012-W52-1
+} {Mon Monday 12 2012 1 52 52 1 52}
+test clock-3.552 {ISO week-based calendar 2012-W52-6} {
+    clock format 1356739200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2012-W52-6
+} {Sat Saturday 12 2012 6 52 52 6 52}
+test clock-3.553 {ISO week-based calendar 2012-W52-7} {
+    clock format 1356825600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2012-W52-7
+} {Sun Sunday 12 2012 7 53 52 0 52}
+test clock-3.554 {ISO week-based calendar 2013-W01-1} {
+    clock format 1356912000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2013-W01-1
+} {Mon Monday 13 2013 1 53 01 1 53}
+test clock-3.555 {ISO week-based calendar 2013-W01-2} {
+    clock format 1356998400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2013-W01-2
+} {Tue Tuesday 13 2013 2 00 01 2 00}
+test clock-3.556 {ISO week-based calendar 2013-W01-6} {
+    clock format 1357344000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2013-W01-6
+} {Sat Saturday 13 2013 6 00 01 6 00}
+test clock-3.557 {ISO week-based calendar 2013-W01-7} {
+    clock format 1357430400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2013-W01-7
+} {Sun Sunday 13 2013 7 01 01 0 00}
+test clock-3.558 {ISO week-based calendar 2013-W02-1} {
+    clock format 1357516800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2013-W02-1
+} {Mon Monday 13 2013 1 01 02 1 01}
+test clock-3.559 {ISO week-based calendar 2015-W53-1} {
+    clock format 1451260800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2015-W53-1
+} {Mon Monday 15 2015 1 52 53 1 52}
+test clock-3.560 {ISO week-based calendar 2015-W53-5} {
+    clock format 1451606400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2015-W53-5
+} {Fri Friday 15 2015 5 00 53 5 00}
+test clock-3.561 {ISO week-based calendar 2015-W53-6} {
+    clock format 1451692800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2015-W53-6
+} {Sat Saturday 15 2015 6 00 53 6 00}
+test clock-3.562 {ISO week-based calendar 2015-W53-7} {
+    clock format 1451779200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2015-W53-7
+} {Sun Sunday 15 2015 7 01 53 0 00}
+test clock-3.563 {ISO week-based calendar 2016-W01-1} {
+    clock format 1451865600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2016-W01-1
+} {Mon Monday 16 2016 1 01 01 1 01}
+test clock-3.564 {ISO week-based calendar 2016-W01-6} {
+    clock format 1452297600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2016-W01-6
+} {Sat Saturday 16 2016 6 01 01 6 01}
+test clock-3.565 {ISO week-based calendar 2016-W01-7} {
+    clock format 1452384000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2016-W01-7
+} {Sun Sunday 16 2016 7 02 01 0 01}
+test clock-3.566 {ISO week-based calendar 2016-W02-1} {
+    clock format 1452470400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2016-W02-1
+} {Mon Monday 16 2016 1 02 02 1 02}
+test clock-3.567 {ISO week-based calendar 2016-W52-1} {
+    clock format 1482710400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2016-W52-1
+} {Mon Monday 16 2016 1 52 52 1 52}
+test clock-3.568 {ISO week-based calendar 2016-W52-6} {
+    clock format 1483142400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2016-W52-6
+} {Sat Saturday 16 2016 6 52 52 6 52}
+test clock-3.569 {ISO week-based calendar 2016-W52-7} {
+    clock format 1483228800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2016-W52-7
+} {Sun Sunday 16 2016 7 01 52 0 00}
+test clock-3.570 {ISO week-based calendar 2017-W01-1} {
+    clock format 1483315200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2017-W01-1
+} {Mon Monday 17 2017 1 01 01 1 01}
+test clock-3.571 {ISO week-based calendar 2017-W01-6} {
+    clock format 1483747200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2017-W01-6
+} {Sat Saturday 17 2017 6 01 01 6 01}
+test clock-3.572 {ISO week-based calendar 2017-W01-7} {
+    clock format 1483833600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2017-W01-7
+} {Sun Sunday 17 2017 7 02 01 0 01}
+test clock-3.573 {ISO week-based calendar 2017-W02-1} {
+    clock format 1483920000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2017-W02-1
+} {Mon Monday 17 2017 1 02 02 1 02}
+test clock-3.574 {ISO week-based calendar 2019-W52-1} {
+    clock format 1577059200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2019-W52-1
+} {Mon Monday 19 2019 1 51 52 1 51}
+test clock-3.575 {ISO week-based calendar 2019-W52-6} {
+    clock format 1577491200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2019-W52-6
+} {Sat Saturday 19 2019 6 51 52 6 51}
+test clock-3.576 {ISO week-based calendar 2019-W52-7} {
+    clock format 1577577600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2019-W52-7
+} {Sun Sunday 19 2019 7 52 52 0 51}
+test clock-3.577 {ISO week-based calendar 2020-W01-1} {
+    clock format 1577664000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2020-W01-1
+} {Mon Monday 20 2020 1 52 01 1 52}
+test clock-3.578 {ISO week-based calendar 2020-W01-3} {
+    clock format 1577836800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2020-W01-3
+} {Wed Wednesday 20 2020 3 00 01 3 00}
+test clock-3.579 {ISO week-based calendar 2020-W01-6} {
+    clock format 1578096000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2020-W01-6
+} {Sat Saturday 20 2020 6 00 01 6 00}
+test clock-3.580 {ISO week-based calendar 2020-W01-7} {
+    clock format 1578182400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2020-W01-7
+} {Sun Sunday 20 2020 7 01 01 0 00}
+test clock-3.581 {ISO week-based calendar 2020-W02-1} {
+    clock format 1578268800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2020-W02-1
+} {Mon Monday 20 2020 1 01 02 1 01}
+test clock-3.582 {ISO week-based calendar 2020-W53-1} {
+    clock format 1609113600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2020-W53-1
+} {Mon Monday 20 2020 1 52 53 1 52}
+test clock-3.583 {ISO week-based calendar 2020-W53-5} {
+    clock format 1609459200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2020-W53-5
+} {Fri Friday 20 2020 5 00 53 5 00}
+test clock-3.584 {ISO week-based calendar 2020-W53-6} {
+    clock format 1609545600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2020-W53-6
+} {Sat Saturday 20 2020 6 00 53 6 00}
+test clock-3.585 {ISO week-based calendar 2020-W53-7} {
+    clock format 1609632000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2020-W53-7
+} {Sun Sunday 20 2020 7 01 53 0 00}
+test clock-3.586 {ISO week-based calendar 2021-W01-1} {
+    clock format 1609718400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2021-W01-1
+} {Mon Monday 21 2021 1 01 01 1 01}
+test clock-3.587 {ISO week-based calendar 2021-W01-6} {
+    clock format 1610150400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2021-W01-6
+} {Sat Saturday 21 2021 6 01 01 6 01}
+test clock-3.588 {ISO week-based calendar 2021-W01-7} {
+    clock format 1610236800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2021-W01-7
+} {Sun Sunday 21 2021 7 02 01 0 01}
+test clock-3.589 {ISO week-based calendar 2021-W02-1} {
+    clock format 1610323200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2021-W02-1
+} {Mon Monday 21 2021 1 02 02 1 02}
+test clock-3.590 {ISO week-based calendar 2023-W52-1} {
+    clock format 1703462400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2023-W52-1
+} {Mon Monday 23 2023 1 52 52 1 52}
+test clock-3.591 {ISO week-based calendar 2023-W52-6} {
+    clock format 1703894400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2023-W52-6
+} {Sat Saturday 23 2023 6 52 52 6 52}
+test clock-3.592 {ISO week-based calendar 2023-W52-7} {
+    clock format 1703980800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2023-W52-7
+} {Sun Sunday 23 2023 7 53 52 0 52}
+test clock-3.593 {ISO week-based calendar 2024-W01-1} {
+    clock format 1704067200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2024-W01-1
+} {Mon Monday 24 2024 1 00 01 1 01}
+test clock-3.594 {ISO week-based calendar 2024-W01-6} {
+    clock format 1704499200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2024-W01-6
+} {Sat Saturday 24 2024 6 00 01 6 01}
+test clock-3.595 {ISO week-based calendar 2024-W01-7} {
+    clock format 1704585600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2024-W01-7
+} {Sun Sunday 24 2024 7 01 01 0 01}
+test clock-3.596 {ISO week-based calendar 2024-W02-1} {
+    clock format 1704672000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2024-W02-1
+} {Mon Monday 24 2024 1 01 02 1 02}
+test clock-3.597 {ISO week-based calendar 2024-W52-1} {
+    clock format 1734912000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2024-W52-1
+} {Mon Monday 24 2024 1 51 52 1 52}
+test clock-3.598 {ISO week-based calendar 2024-W52-6} {
+    clock format 1735344000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2024-W52-6
+} {Sat Saturday 24 2024 6 51 52 6 52}
+test clock-3.599 {ISO week-based calendar 2024-W52-7} {
+    clock format 1735430400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2024-W52-7
+} {Sun Sunday 24 2024 7 52 52 0 52}
+test clock-3.600 {ISO week-based calendar 2025-W01-1} {
+    clock format 1735516800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2025-W01-1
+} {Mon Monday 25 2025 1 52 01 1 53}
+test clock-3.601 {ISO week-based calendar 2025-W01-3} {
+    clock format 1735689600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2025-W01-3
+} {Wed Wednesday 25 2025 3 00 01 3 00}
+test clock-3.602 {ISO week-based calendar 2025-W01-6} {
+    clock format 1735948800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2025-W01-6
+} {Sat Saturday 25 2025 6 00 01 6 00}
+test clock-3.603 {ISO week-based calendar 2025-W01-7} {
+    clock format 1736035200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2025-W01-7
+} {Sun Sunday 25 2025 7 01 01 0 00}
+test clock-3.604 {ISO week-based calendar 2025-W02-1} {
+    clock format 1736121600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2025-W02-1
+} {Mon Monday 25 2025 1 01 02 1 01}
+test clock-3.605 {ISO week-based calendar 2036-W52-1} {
+    clock format 2113516800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2036-W52-1
+} {Mon Monday 36 2036 1 51 52 1 51}
+test clock-3.606 {ISO week-based calendar 2036-W52-6} {
+    clock format 2113948800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2036-W52-6
+} {Sat Saturday 36 2036 6 51 52 6 51}
+test clock-3.607 {ISO week-based calendar 2036-W52-7} {
+    clock format 2114035200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2036-W52-7
+} {Sun Sunday 36 2036 7 52 52 0 51}
+test clock-3.608 {ISO week-based calendar 2037-W01-1} {
+    clock format 2114121600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2037-W01-1
+} {Mon Monday 37 2037 1 52 01 1 52}
+test clock-3.609 {ISO week-based calendar 2037-W01-4} {
+    clock format 2114380800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2037-W01-4
+} {Thu Thursday 37 2037 4 00 01 4 00}
+test clock-3.610 {ISO week-based calendar 2037-W01-6} {
+    clock format 2114553600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2037-W01-6
+} {Sat Saturday 37 2037 6 00 01 6 00}
+test clock-3.611 {ISO week-based calendar 2037-W01-7} {
+    clock format 2114640000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2037-W01-7
+} {Sun Sunday 37 2037 7 01 01 0 00}
+test clock-3.612 {ISO week-based calendar 2037-W02-1} {
+    clock format 2114726400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2037-W02-1
+} {Mon Monday 37 2037 1 01 02 1 01}
+test clock-3.613 {ISO week-based calendar 2037-W53-1} {
+    clock format 2145571200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2037-W53-1
+} {Mon Monday 37 2037 1 52 53 1 52}
+test clock-3.614 {ISO week-based calendar 2037-W53-5} {
+    clock format 2145916800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2037-W53-5
+} {Fri Friday 37 2037 5 00 53 5 00}
+test clock-3.615 {ISO week-based calendar 2037-W53-6} {
+    clock format 2146003200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2037-W53-6
+} {Sat Saturday 37 2037 6 00 53 6 00}
+test clock-3.616 {ISO week-based calendar 2037-W53-7} {
+    clock format 2146089600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2037-W53-7
+} {Sun Sunday 37 2037 7 01 53 0 00}
+test clock-3.617 {ISO week-based calendar 2038-W01-1} {
+    clock format 2146176000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2038-W01-1
+} {Mon Monday 38 2038 1 01 01 1 01}
+test clock-3.618 {ISO week-based calendar 2038-W01-6} {
+    clock format 2146608000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2038-W01-6
+} {Sat Saturday 38 2038 6 01 01 6 01}
+test clock-3.619 {ISO week-based calendar 2038-W01-7} {
+    clock format 2146694400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2038-W01-7
+} {Sun Sunday 38 2038 7 02 01 0 01}
+test clock-3.620 {ISO week-based calendar 2038-W02-1} {
+    clock format 2146780800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2038-W02-1
+} {Mon Monday 38 2038 1 02 02 1 02}
+test clock-3.621 {ISO week-based calendar 2038-W52-1} {
+    clock format 2177020800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2038-W52-1
+} {Mon Monday 38 2038 1 52 52 1 52}
+test clock-3.622 {ISO week-based calendar 2038-W52-6} {
+    clock format 2177452800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2038-W52-6
+} {Sat Saturday 38 2038 6 00 52 6 00}
+test clock-3.623 {ISO week-based calendar 2038-W52-7} {
+    clock format 2177539200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2038-W52-7
+} {Sun Sunday 38 2038 7 01 52 0 00}
+test clock-3.624 {ISO week-based calendar 2039-W01-1} {
+    clock format 2177625600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2039-W01-1
+} {Mon Monday 39 2039 1 01 01 1 01}
+test clock-3.625 {ISO week-based calendar 2039-W01-6} {
+    clock format 2178057600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2039-W01-6
+} {Sat Saturday 39 2039 6 01 01 6 01}
+test clock-3.626 {ISO week-based calendar 2039-W01-7} {
+    clock format 2178144000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2039-W01-7
+} {Sun Sunday 39 2039 7 02 01 0 01}
+test clock-3.627 {ISO week-based calendar 2039-W02-1} {
+    clock format 2178230400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2039-W02-1
+} {Mon Monday 39 2039 1 02 02 1 02}
+test clock-3.628 {ISO week-based calendar 2039-W52-1} {
+    clock format 2208470400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2039-W52-1
+} {Mon Monday 39 2039 1 52 52 1 52}
+test clock-3.629 {ISO week-based calendar 2039-W52-6} {
+    clock format 2208902400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2039-W52-6
+} {Sat Saturday 39 2039 6 52 52 6 52}
+test clock-3.630 {ISO week-based calendar 2039-W52-7} {
+    clock format 2208988800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2039-W52-7
+} {Sun Sunday 39 2039 7 01 52 0 00}
+test clock-3.631 {ISO week-based calendar 2040-W01-1} {
+    clock format 2209075200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2040-W01-1
+} {Mon Monday 40 2040 1 01 01 1 01}
+test clock-3.632 {ISO week-based calendar 2040-W01-6} {
+    clock format 2209507200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2040-W01-6
+} {Sat Saturday 40 2040 6 01 01 6 01}
+test clock-3.633 {ISO week-based calendar 2040-W01-7} {
+    clock format 2209593600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2040-W01-7
+} {Sun Sunday 40 2040 7 02 01 0 01}
+test clock-3.634 {ISO week-based calendar 2040-W02-1} {
+    clock format 2209680000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2040-W02-1
+} {Mon Monday 40 2040 1 02 02 1 02}
+test clock-3.635 {ISO week-based calendar 2040-W52-1} {
+    clock format 2239920000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2040-W52-1
+} {Mon Monday 40 2040 1 52 52 1 52}
+test clock-3.636 {ISO week-based calendar 2040-W52-6} {
+    clock format 2240352000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2040-W52-6
+} {Sat Saturday 40 2040 6 52 52 6 52}
+test clock-3.637 {ISO week-based calendar 2040-W52-7} {
+    clock format 2240438400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2040-W52-7
+} {Sun Sunday 40 2040 7 53 52 0 52}
+test clock-3.638 {ISO week-based calendar 2041-W01-1} {
+    clock format 2240524800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2041-W01-1
+} {Mon Monday 41 2041 1 53 01 1 53}
+test clock-3.639 {ISO week-based calendar 2041-W01-2} {
+    clock format 2240611200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2041-W01-2
+} {Tue Tuesday 41 2041 2 00 01 2 00}
+test clock-3.640 {ISO week-based calendar 2041-W01-6} {
+    clock format 2240956800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2041-W01-6
+} {Sat Saturday 41 2041 6 00 01 6 00}
+test clock-3.641 {ISO week-based calendar 2041-W01-7} {
+    clock format 2241043200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2041-W01-7
+} {Sun Sunday 41 2041 7 01 01 0 00}
+test clock-3.642 {ISO week-based calendar 2041-W02-1} {
+    clock format 2241129600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2041-W02-1
+} {Mon Monday 41 2041 1 01 02 1 01}
+test clock-3.643 {ISO week-based calendar 2041-W52-1} {
+    clock format 2271369600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2041-W52-1
+} {Mon Monday 41 2041 1 51 52 1 51}
+test clock-3.644 {ISO week-based calendar 2041-W52-6} {
+    clock format 2271801600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2041-W52-6
+} {Sat Saturday 41 2041 6 51 52 6 51}
+test clock-3.645 {ISO week-based calendar 2041-W52-7} {
+    clock format 2271888000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2041-W52-7
+} {Sun Sunday 41 2041 7 52 52 0 51}
+test clock-3.646 {ISO week-based calendar 2042-W01-1} {
+    clock format 2271974400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2042-W01-1
+} {Mon Monday 42 2042 1 52 01 1 52}
+test clock-3.647 {ISO week-based calendar 2042-W01-3} {
+    clock format 2272147200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2042-W01-3
+} {Wed Wednesday 42 2042 3 00 01 3 00}
+test clock-3.648 {ISO week-based calendar 2042-W01-6} {
+    clock format 2272406400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2042-W01-6
+} {Sat Saturday 42 2042 6 00 01 6 00}
+test clock-3.649 {ISO week-based calendar 2042-W01-7} {
+    clock format 2272492800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2042-W01-7
+} {Sun Sunday 42 2042 7 01 01 0 00}
+test clock-3.650 {ISO week-based calendar 2042-W02-1} {
+    clock format 2272579200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2042-W02-1
+} {Mon Monday 42 2042 1 01 02 1 01}
+test clock-3.651 {ISO week-based calendar 2042-W52-1} {
+    clock format 2302819200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2042-W52-1
+} {Mon Monday 42 2042 1 51 52 1 51}
+test clock-3.652 {ISO week-based calendar 2042-W52-6} {
+    clock format 2303251200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2042-W52-6
+} {Sat Saturday 42 2042 6 51 52 6 51}
+test clock-3.653 {ISO week-based calendar 2042-W52-7} {
+    clock format 2303337600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2042-W52-7
+} {Sun Sunday 42 2042 7 52 52 0 51}
+test clock-3.654 {ISO week-based calendar 2043-W01-1} {
+    clock format 2303424000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2043-W01-1
+} {Mon Monday 43 2043 1 52 01 1 52}
+test clock-3.655 {ISO week-based calendar 2043-W01-4} {
+    clock format 2303683200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2043-W01-4
+} {Thu Thursday 43 2043 4 00 01 4 00}
+test clock-3.656 {ISO week-based calendar 2043-W01-6} {
+    clock format 2303856000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2043-W01-6
+} {Sat Saturday 43 2043 6 00 01 6 00}
+test clock-3.657 {ISO week-based calendar 2043-W01-7} {
+    clock format 2303942400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2043-W01-7
+} {Sun Sunday 43 2043 7 01 01 0 00}
+test clock-3.658 {ISO week-based calendar 2043-W02-1} {
+    clock format 2304028800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2043-W02-1
+} {Mon Monday 43 2043 1 01 02 1 01}
+test clock-3.659 {ISO week-based calendar 2043-W53-1} {
+    clock format 2334873600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2043-W53-1
+} {Mon Monday 43 2043 1 52 53 1 52}
+test clock-3.660 {ISO week-based calendar 2043-W53-5} {
+    clock format 2335219200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2043-W53-5
+} {Fri Friday 43 2043 5 00 53 5 00}
+test clock-3.661 {ISO week-based calendar 2043-W53-6} {
+    clock format 2335305600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2043-W53-6
+} {Sat Saturday 43 2043 6 00 53 6 00}
+test clock-3.662 {ISO week-based calendar 2043-W53-7} {
+    clock format 2335392000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2043-W53-7
+} {Sun Sunday 43 2043 7 01 53 0 00}
+test clock-3.663 {ISO week-based calendar 2044-W01-1} {
+    clock format 2335478400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2044-W01-1
+} {Mon Monday 44 2044 1 01 01 1 01}
+test clock-3.664 {ISO week-based calendar 2044-W01-6} {
+    clock format 2335910400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2044-W01-6
+} {Sat Saturday 44 2044 6 01 01 6 01}
+test clock-3.665 {ISO week-based calendar 2044-W01-7} {
+    clock format 2335996800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2044-W01-7
+} {Sun Sunday 44 2044 7 02 01 0 01}
+test clock-3.666 {ISO week-based calendar 2044-W02-1} {
+    clock format 2336083200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2044-W02-1
+} {Mon Monday 44 2044 1 02 02 1 02}
+test clock-3.667 {ISO week-based calendar 2044-W52-1} {
+    clock format 2366323200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2044-W52-1
+} {Mon Monday 44 2044 1 52 52 1 52}
+test clock-3.668 {ISO week-based calendar 2044-W52-6} {
+    clock format 2366755200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2044-W52-6
+} {Sat Saturday 44 2044 6 52 52 6 52}
+test clock-3.669 {ISO week-based calendar 2044-W52-7} {
+    clock format 2366841600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2044-W52-7
+} {Sun Sunday 44 2044 7 01 52 0 00}
+test clock-3.670 {ISO week-based calendar 2045-W01-1} {
+    clock format 2366928000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2045-W01-1
+} {Mon Monday 45 2045 1 01 01 1 01}
+test clock-3.671 {ISO week-based calendar 2045-W01-6} {
+    clock format 2367360000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2045-W01-6
+} {Sat Saturday 45 2045 6 01 01 6 01}
+test clock-3.672 {ISO week-based calendar 2045-W01-7} {
+    clock format 2367446400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2045-W01-7
+} {Sun Sunday 45 2045 7 02 01 0 01}
+test clock-3.673 {ISO week-based calendar 2045-W02-1} {
+    clock format 2367532800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2045-W02-1
+} {Mon Monday 45 2045 1 02 02 1 02}
+test clock-3.674 {ISO week-based calendar 2045-W52-1} {
+    clock format 2397772800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2045-W52-1
+} {Mon Monday 45 2045 1 52 52 1 52}
+test clock-3.675 {ISO week-based calendar 2045-W52-6} {
+    clock format 2398204800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2045-W52-6
+} {Sat Saturday 45 2045 6 52 52 6 52}
+test clock-3.676 {ISO week-based calendar 2045-W52-7} {
+    clock format 2398291200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2045-W52-7
+} {Sun Sunday 45 2045 7 53 52 0 52}
+test clock-3.677 {ISO week-based calendar 2046-W01-1} {
+    clock format 2398377600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2046-W01-1
+} {Mon Monday 46 2046 1 00 01 1 01}
+test clock-3.678 {ISO week-based calendar 2046-W01-6} {
+    clock format 2398809600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2046-W01-6
+} {Sat Saturday 46 2046 6 00 01 6 01}
+test clock-3.679 {ISO week-based calendar 2046-W01-7} {
+    clock format 2398896000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2046-W01-7
+} {Sun Sunday 46 2046 7 01 01 0 01}
+test clock-3.680 {ISO week-based calendar 2046-W02-1} {
+    clock format 2398982400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2046-W02-1
+} {Mon Monday 46 2046 1 01 02 1 02}
+test clock-3.681 {ISO week-based calendar 2046-W52-1} {
+    clock format 2429222400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2046-W52-1
+} {Mon Monday 46 2046 1 51 52 1 52}
+test clock-3.682 {ISO week-based calendar 2046-W52-6} {
+    clock format 2429654400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2046-W52-6
+} {Sat Saturday 46 2046 6 51 52 6 52}
+test clock-3.683 {ISO week-based calendar 2046-W52-7} {
+    clock format 2429740800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2046-W52-7
+} {Sun Sunday 46 2046 7 52 52 0 52}
+test clock-3.684 {ISO week-based calendar 2047-W01-1} {
+    clock format 2429827200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2047-W01-1
+} {Mon Monday 47 2047 1 52 01 1 53}
+test clock-3.685 {ISO week-based calendar 2047-W01-2} {
+    clock format 2429913600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2047-W01-2
+} {Tue Tuesday 47 2047 2 00 01 2 00}
+test clock-3.686 {ISO week-based calendar 2047-W01-6} {
+    clock format 2430259200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2047-W01-6
+} {Sat Saturday 47 2047 6 00 01 6 00}
+test clock-3.687 {ISO week-based calendar 2047-W01-7} {
+    clock format 2430345600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2047-W01-7
+} {Sun Sunday 47 2047 7 01 01 0 00}
+test clock-3.688 {ISO week-based calendar 2047-W02-1} {
+    clock format 2430432000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2047-W02-1
+} {Mon Monday 47 2047 1 01 02 1 01}
+test clock-3.689 {ISO week-based calendar 2047-W52-1} {
+    clock format 2460672000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2047-W52-1
+} {Mon Monday 47 2047 1 51 52 1 51}
+test clock-3.690 {ISO week-based calendar 2047-W52-6} {
+    clock format 2461104000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2047-W52-6
+} {Sat Saturday 47 2047 6 51 52 6 51}
+test clock-3.691 {ISO week-based calendar 2047-W52-7} {
+    clock format 2461190400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2047-W52-7
+} {Sun Sunday 47 2047 7 52 52 0 51}
+test clock-3.692 {ISO week-based calendar 2048-W01-1} {
+    clock format 2461276800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2048-W01-1
+} {Mon Monday 48 2048 1 52 01 1 52}
+test clock-3.693 {ISO week-based calendar 2048-W01-3} {
+    clock format 2461449600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2048-W01-3
+} {Wed Wednesday 48 2048 3 00 01 3 00}
+test clock-3.694 {ISO week-based calendar 2048-W01-6} {
+    clock format 2461708800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2048-W01-6
+} {Sat Saturday 48 2048 6 00 01 6 00}
+test clock-3.695 {ISO week-based calendar 2048-W01-7} {
+    clock format 2461795200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2048-W01-7
+} {Sun Sunday 48 2048 7 01 01 0 00}
+test clock-3.696 {ISO week-based calendar 2048-W02-1} {
+    clock format 2461881600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2048-W02-1
+} {Mon Monday 48 2048 1 01 02 1 01}
+test clock-3.697 {ISO week-based calendar 2048-W53-1} {
+    clock format 2492726400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2048-W53-1
+} {Mon Monday 48 2048 1 52 53 1 52}
+test clock-3.698 {ISO week-based calendar 2048-W53-5} {
+    clock format 2493072000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2048-W53-5
+} {Fri Friday 48 2048 5 00 53 5 00}
+test clock-3.699 {ISO week-based calendar 2048-W53-6} {
+    clock format 2493158400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2048-W53-6
+} {Sat Saturday 48 2048 6 00 53 6 00}
+test clock-3.700 {ISO week-based calendar 2048-W53-7} {
+    clock format 2493244800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2048-W53-7
+} {Sun Sunday 48 2048 7 01 53 0 00}
+test clock-3.701 {ISO week-based calendar 2049-W01-1} {
+    clock format 2493331200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2049-W01-1
+} {Mon Monday 49 2049 1 01 01 1 01}
+test clock-3.702 {ISO week-based calendar 2049-W01-6} {
+    clock format 2493763200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2049-W01-6
+} {Sat Saturday 49 2049 6 01 01 6 01}
+test clock-3.703 {ISO week-based calendar 2049-W01-7} {
+    clock format 2493849600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2049-W01-7
+} {Sun Sunday 49 2049 7 02 01 0 01}
+test clock-3.704 {ISO week-based calendar 2049-W02-1} {
+    clock format 2493936000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2049-W02-1
+} {Mon Monday 49 2049 1 02 02 1 02}
+test clock-3.705 {ISO week-based calendar 2051-W52-1} {
+    clock format 2587075200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2051-W52-1
+} {Mon Monday 51 2051 1 52 52 1 52}
+test clock-3.706 {ISO week-based calendar 2051-W52-6} {
+    clock format 2587507200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2051-W52-6
+} {Sat Saturday 51 2051 6 52 52 6 52}
+test clock-3.707 {ISO week-based calendar 2051-W52-7} {
+    clock format 2587593600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2051-W52-7
+} {Sun Sunday 51 2051 7 53 52 0 52}
+test clock-3.708 {ISO week-based calendar 2052-W01-1} {
+    clock format 2587680000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2052-W01-1
+} {Mon Monday 52 2052 1 00 01 1 01}
+test clock-3.709 {ISO week-based calendar 2052-W01-6} {
+    clock format 2588112000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2052-W01-6
+} {Sat Saturday 52 2052 6 00 01 6 01}
+test clock-3.710 {ISO week-based calendar 2052-W01-7} {
+    clock format 2588198400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2052-W01-7
+} {Sun Sunday 52 2052 7 01 01 0 01}
+test clock-3.711 {ISO week-based calendar 2052-W02-1} {
+    clock format 2588284800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2052-W02-1
+} {Mon Monday 52 2052 1 01 02 1 02}
+test clock-3.712 {ISO week-based calendar 2052-W52-1} {
+    clock format 2618524800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2052-W52-1
+} {Mon Monday 52 2052 1 51 52 1 52}
+test clock-3.713 {ISO week-based calendar 2052-W52-6} {
+    clock format 2618956800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2052-W52-6
+} {Sat Saturday 52 2052 6 51 52 6 52}
+test clock-3.714 {ISO week-based calendar 2052-W52-7} {
+    clock format 2619043200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2052-W52-7
+} {Sun Sunday 52 2052 7 52 52 0 52}
+test clock-3.715 {ISO week-based calendar 2053-W01-1} {
+    clock format 2619129600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2053-W01-1
+} {Mon Monday 53 2053 1 52 01 1 53}
+test clock-3.716 {ISO week-based calendar 2053-W01-3} {
+    clock format 2619302400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2053-W01-3
+} {Wed Wednesday 53 2053 3 00 01 3 00}
+test clock-3.717 {ISO week-based calendar 2053-W01-6} {
+    clock format 2619561600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2053-W01-6
+} {Sat Saturday 53 2053 6 00 01 6 00}
+test clock-3.718 {ISO week-based calendar 2053-W01-7} {
+    clock format 2619648000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2053-W01-7
+} {Sun Sunday 53 2053 7 01 01 0 00}
+test clock-3.719 {ISO week-based calendar 2053-W02-1} {
+    clock format 2619734400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2053-W02-1
+} {Mon Monday 53 2053 1 01 02 1 01}
+test clock-3.720 {ISO week-based calendar 2055-W52-1} {
+    clock format 2713478400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2055-W52-1
+} {Mon Monday 55 2055 1 52 52 1 52}
+test clock-3.721 {ISO week-based calendar 2055-W52-6} {
+    clock format 2713910400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2055-W52-6
+} {Sat Saturday 55 2055 6 00 52 6 00}
+test clock-3.722 {ISO week-based calendar 2055-W52-7} {
+    clock format 2713996800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2055-W52-7
+} {Sun Sunday 55 2055 7 01 52 0 00}
+test clock-3.723 {ISO week-based calendar 2056-W01-1} {
+    clock format 2714083200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2056-W01-1
+} {Mon Monday 56 2056 1 01 01 1 01}
+test clock-3.724 {ISO week-based calendar 2056-W01-6} {
+    clock format 2714515200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2056-W01-6
+} {Sat Saturday 56 2056 6 01 01 6 01}
+test clock-3.725 {ISO week-based calendar 2056-W01-7} {
+    clock format 2714601600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2056-W01-7
+} {Sun Sunday 56 2056 7 02 01 0 01}
+test clock-3.726 {ISO week-based calendar 2056-W02-1} {
+    clock format 2714688000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2056-W02-1
+} {Mon Monday 56 2056 1 02 02 1 02}
+test clock-3.727 {ISO week-based calendar 2056-W52-1} {
+    clock format 2744928000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2056-W52-1
+} {Mon Monday 56 2056 1 52 52 1 52}
+test clock-3.728 {ISO week-based calendar 2056-W52-6} {
+    clock format 2745360000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2056-W52-6
+} {Sat Saturday 56 2056 6 52 52 6 52}
+test clock-3.729 {ISO week-based calendar 2056-W52-7} {
+    clock format 2745446400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2056-W52-7
+} {Sun Sunday 56 2056 7 53 52 0 52}
+test clock-3.730 {ISO week-based calendar 2057-W01-1} {
+    clock format 2745532800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2057-W01-1
+} {Mon Monday 57 2057 1 00 01 1 01}
+test clock-3.731 {ISO week-based calendar 2057-W01-6} {
+    clock format 2745964800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2057-W01-6
+} {Sat Saturday 57 2057 6 00 01 6 01}
+test clock-3.732 {ISO week-based calendar 2057-W01-7} {
+    clock format 2746051200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2057-W01-7
+} {Sun Sunday 57 2057 7 01 01 0 01}
+test clock-3.733 {ISO week-based calendar 2057-W02-1} {
+    clock format 2746137600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2057-W02-1
+} {Mon Monday 57 2057 1 01 02 1 02}
+test clock-3.734 {ISO week-based calendar 2059-W52-1} {
+    clock format 2839276800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2059-W52-1
+} {Mon Monday 59 2059 1 51 52 1 51}
+test clock-3.735 {ISO week-based calendar 2059-W52-6} {
+    clock format 2839708800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2059-W52-6
+} {Sat Saturday 59 2059 6 51 52 6 51}
+test clock-3.736 {ISO week-based calendar 2059-W52-7} {
+    clock format 2839795200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2059-W52-7
+} {Sun Sunday 59 2059 7 52 52 0 51}
+test clock-3.737 {ISO week-based calendar 2060-W01-1} {
+    clock format 2839881600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2060-W01-1
+} {Mon Monday 60 2060 1 52 01 1 52}
+test clock-3.738 {ISO week-based calendar 2060-W01-4} {
+    clock format 2840140800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2060-W01-4
+} {Thu Thursday 60 2060 4 00 01 4 00}
+test clock-3.739 {ISO week-based calendar 2060-W01-6} {
+    clock format 2840313600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2060-W01-6
+} {Sat Saturday 60 2060 6 00 01 6 00}
+test clock-3.740 {ISO week-based calendar 2060-W01-7} {
+    clock format 2840400000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2060-W01-7
+} {Sun Sunday 60 2060 7 01 01 0 00}
+test clock-3.741 {ISO week-based calendar 2060-W02-1} {
+    clock format 2840486400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2060-W02-1
+} {Mon Monday 60 2060 1 01 02 1 01}
+test clock-3.742 {ISO week-based calendar 2060-W53-1} {
+    clock format 2871331200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2060-W53-1
+} {Mon Monday 60 2060 1 52 53 1 52}
+test clock-3.743 {ISO week-based calendar 2060-W53-6} {
+    clock format 2871763200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2060-W53-6
+} {Sat Saturday 60 2060 6 00 53 6 00}
+test clock-3.744 {ISO week-based calendar 2060-W53-7} {
+    clock format 2871849600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2060-W53-7
+} {Sun Sunday 60 2060 7 01 53 0 00}
+test clock-3.745 {ISO week-based calendar 2061-W01-1} {
+    clock format 2871936000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2061-W01-1
+} {Mon Monday 61 2061 1 01 01 1 01}
+test clock-3.746 {ISO week-based calendar 2061-W01-6} {
+    clock format 2872368000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2061-W01-6
+} {Sat Saturday 61 2061 6 01 01 6 01}
+test clock-3.747 {ISO week-based calendar 2061-W01-7} {
+    clock format 2872454400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2061-W01-7
+} {Sun Sunday 61 2061 7 02 01 0 01}
+test clock-3.748 {ISO week-based calendar 2061-W02-1} {
+    clock format 2872540800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2061-W02-1
+} {Mon Monday 61 2061 1 02 02 1 02}
+test clock-3.749 {ISO week-based calendar 2063-W52-1} {
+    clock format 2965680000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2063-W52-1
+} {Mon Monday 63 2063 1 51 52 1 52}
+test clock-3.750 {ISO week-based calendar 2063-W52-6} {
+    clock format 2966112000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2063-W52-6
+} {Sat Saturday 63 2063 6 51 52 6 52}
+test clock-3.751 {ISO week-based calendar 2063-W52-7} {
+    clock format 2966198400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2063-W52-7
+} {Sun Sunday 63 2063 7 52 52 0 52}
+test clock-3.752 {ISO week-based calendar 2064-W01-1} {
+    clock format 2966284800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2064-W01-1
+} {Mon Monday 64 2064 1 52 01 1 53}
+test clock-3.753 {ISO week-based calendar 2064-W01-2} {
+    clock format 2966371200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2064-W01-2
+} {Tue Tuesday 64 2064 2 00 01 2 00}
+test clock-3.754 {ISO week-based calendar 2064-W01-6} {
+    clock format 2966716800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2064-W01-6
+} {Sat Saturday 64 2064 6 00 01 6 00}
+test clock-3.755 {ISO week-based calendar 2064-W01-7} {
+    clock format 2966803200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2064-W01-7
+} {Sun Sunday 64 2064 7 01 01 0 00}
+test clock-3.756 {ISO week-based calendar 2064-W02-1} {
+    clock format 2966889600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2064-W02-1
+} {Mon Monday 64 2064 1 01 02 1 01}
+test clock-3.757 {ISO week-based calendar 2064-W52-1} {
+    clock format 2997129600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2064-W52-1
+} {Mon Monday 64 2064 1 51 52 1 51}
+test clock-3.758 {ISO week-based calendar 2064-W52-6} {
+    clock format 2997561600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2064-W52-6
+} {Sat Saturday 64 2064 6 51 52 6 51}
+test clock-3.759 {ISO week-based calendar 2064-W52-7} {
+    clock format 2997648000 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2064-W52-7
+} {Sun Sunday 64 2064 7 52 52 0 51}
+test clock-3.760 {ISO week-based calendar 2065-W01-1} {
+    clock format 2997734400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2065-W01-1
+} {Mon Monday 65 2065 1 52 01 1 52}
+test clock-3.761 {ISO week-based calendar 2065-W01-4} {
+    clock format 2997993600 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2065-W01-4
+} {Thu Thursday 65 2065 4 00 01 4 00}
+test clock-3.762 {ISO week-based calendar 2065-W01-6} {
+    clock format 2998166400 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2065-W01-6
+} {Sat Saturday 65 2065 6 00 01 6 00}
+test clock-3.763 {ISO week-based calendar 2065-W01-7} {
+    clock format 2998252800 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2065-W01-7
+} {Sun Sunday 65 2065 7 01 01 0 00}
+test clock-3.764 {ISO week-based calendar 2065-W02-1} {
+    clock format 2998339200 -format {%a %A %g %G %u %U %V %w %W} -gmt true; # 2065-W02-1
+} {Mon Monday 65 2065 1 01 02 1 01}
+# END testcases3
+
+# BEGIN testcases4
+
+# Test formatting of time of day
+# Format groups tested: %H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+
+
+test clock-4.1 { format time of day 00:00:00 } {
+    clock format 0 \
+        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+	  -locale en_US_roman \
+        -gmt true
+} {00 ? 12 xii  0 ? 12 xii 00 ? AM am 12:00:00 am 00:00 00 ? 00:00:00 00:00:00 ? h ? m ? s Thu Jan  1 00:00:00 GMT 1970}
+test clock-4.2 { format time of day 00:00:01 } {
+    clock format 1 \
+        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+	  -locale en_US_roman \
+        -gmt true
+} {00 ? 12 xii  0 ? 12 xii 00 ? AM am 12:00:01 am 00:00 01 i 00:00:01 00:00:01 ? h ? m i s Thu Jan  1 00:00:01 GMT 1970}
+test clock-4.3 { format time of day 00:00:58 } {
+    clock format 58 \
+        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+	  -locale en_US_roman \
+        -gmt true
+} {00 ? 12 xii  0 ? 12 xii 00 ? AM am 12:00:58 am 00:00 58 lviii 00:00:58 00:00:58 ? h ? m lviii s Thu Jan  1 00:00:58 GMT 1970}
+test clock-4.4 { format time of day 00:00:59 } {
+    clock format 59 \
+        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+	  -locale en_US_roman \
+        -gmt true
+} {00 ? 12 xii  0 ? 12 xii 00 ? AM am 12:00:59 am 00:00 59 lix 00:00:59 00:00:59 ? h ? m lix s Thu Jan  1 00:00:59 GMT 1970}
+test clock-4.5 { format time of day 00:01:00 } {
+    clock format 60 \
+        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+	  -locale en_US_roman \
+        -gmt true
+} {00 ? 12 xii  0 ? 12 xii 01 i AM am 12:01:00 am 00:01 00 ? 00:01:00 00:01:00 ? h i m ? s Thu Jan  1 00:01:00 GMT 1970}
+test clock-4.6 { format time of day 00:01:01 } {
+    clock format 61 \
+        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+	  -locale en_US_roman \
+        -gmt true
+} {00 ? 12 xii  0 ? 12 xii 01 i AM am 12:01:01 am 00:01 01 i 00:01:01 00:01:01 ? h i m i s Thu Jan  1 00:01:01 GMT 1970}
+test clock-4.7 { format time of day 00:01:58 } {
+    clock format 118 \
+        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+	  -locale en_US_roman \
+        -gmt true
+} {00 ? 12 xii  0 ? 12 xii 01 i AM am 12:01:58 am 00:01 58 lviii 00:01:58 00:01:58 ? h i m lviii s Thu Jan  1 00:01:58 GMT 1970}
+test clock-4.8 { format time of day 00:01:59 } {
+    clock format 119 \
+        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+	  -locale en_US_roman \
+        -gmt true
+} {00 ? 12 xii  0 ? 12 xii 01 i AM am 12:01:59 am 00:01 59 lix 00:01:59 00:01:59 ? h i m lix s Thu Jan  1 00:01:59 GMT 1970}
+test clock-4.9 { format time of day 00:58:00 } {
+    clock format 3480 \
+        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+	  -locale en_US_roman \
+        -gmt true
+} {00 ? 12 xii  0 ? 12 xii 58 lviii AM am 12:58:00 am 00:58 00 ? 00:58:00 00:58:00 ? h lviii m ? s Thu Jan  1 00:58:00 GMT 1970}
+test clock-4.10 { format time of day 00:58:01 } {
+    clock format 3481 \
+        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+	  -locale en_US_roman \
+        -gmt true
+} {00 ? 12 xii  0 ? 12 xii 58 lviii AM am 12:58:01 am 00:58 01 i 00:58:01 00:58:01 ? h lviii m i s Thu Jan  1 00:58:01 GMT 1970}
+test clock-4.11 { format time of day 00:58:58 } {
+    clock format 3538 \
+        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+	  -locale en_US_roman \
+        -gmt true
+} {00 ? 12 xii  0 ? 12 xii 58 lviii AM am 12:58:58 am 00:58 58 lviii 00:58:58 00:58:58 ? h lviii m lviii s Thu Jan  1 00:58:58 GMT 1970}
+test clock-4.12 { format time of day 00:58:59 } {
+    clock format 3539 \
+        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+	  -locale en_US_roman \
+        -gmt true
+} {00 ? 12 xii  0 ? 12 xii 58 lviii AM am 12:58:59 am 00:58 59 lix 00:58:59 00:58:59 ? h lviii m lix s Thu Jan  1 00:58:59 GMT 1970}
+test clock-4.13 { format time of day 00:59:00 } {
+    clock format 3540 \
+        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+	  -locale en_US_roman \
+        -gmt true
+} {00 ? 12 xii  0 ? 12 xii 59 lix AM am 12:59:00 am 00:59 00 ? 00:59:00 00:59:00 ? h lix m ? s Thu Jan  1 00:59:00 GMT 1970}
+test clock-4.14 { format time of day 00:59:01 } {
+    clock format 3541 \
+        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+	  -locale en_US_roman \
+        -gmt true
+} {00 ? 12 xii  0 ? 12 xii 59 lix AM am 12:59:01 am 00:59 01 i 00:59:01 00:59:01 ? h lix m i s Thu Jan  1 00:59:01 GMT 1970}
+test clock-4.15 { format time of day 00:59:58 } {
+    clock format 3598 \
+        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+	  -locale en_US_roman \
+        -gmt true
+} {00 ? 12 xii  0 ? 12 xii 59 lix AM am 12:59:58 am 00:59 58 lviii 00:59:58 00:59:58 ? h lix m lviii s Thu Jan  1 00:59:58 GMT 1970}
+test clock-4.16 { format time of day 00:59:59 } {
+    clock format 3599 \
+        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+	  -locale en_US_roman \
+        -gmt true
+} {00 ? 12 xii  0 ? 12 xii 59 lix AM am 12:59:59 am 00:59 59 lix 00:59:59 00:59:59 ? h lix m lix s Thu Jan  1 00:59:59 GMT 1970}
+test clock-4.17 { format time of day 01:00:00 } {
+    clock format 3600 \
+        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+	  -locale en_US_roman \
+        -gmt true
+} {01 i 01 i  1 i  1 i 00 ? AM am 01:00:00 am 01:00 00 ? 01:00:00 01:00:00 i h ? m ? s Thu Jan  1 01:00:00 GMT 1970}
+test clock-4.18 { format time of day 01:00:01 } {
+    clock format 3601 \
+        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+	  -locale en_US_roman \
+        -gmt true
+} {01 i 01 i  1 i  1 i 00 ? AM am 01:00:01 am 01:00 01 i 01:00:01 01:00:01 i h ? m i s Thu Jan  1 01:00:01 GMT 1970}
+test clock-4.19 { format time of day 01:00:58 } {
+    clock format 3658 \
+        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+	  -locale en_US_roman \
+        -gmt true
+} {01 i 01 i  1 i  1 i 00 ? AM am 01:00:58 am 01:00 58 lviii 01:00:58 01:00:58 i h ? m lviii s Thu Jan  1 01:00:58 GMT 1970}
+test clock-4.20 { format time of day 01:00:59 } {
+    clock format 3659 \
+        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+	  -locale en_US_roman \
+        -gmt true
+} {01 i 01 i  1 i  1 i 00 ? AM am 01:00:59 am 01:00 59 lix 01:00:59 01:00:59 i h ? m lix s Thu Jan  1 01:00:59 GMT 1970}
+test clock-4.21 { format time of day 01:01:00 } {
+    clock format 3660 \
+        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+	  -locale en_US_roman \
+        -gmt true
+} {01 i 01 i  1 i  1 i 01 i AM am 01:01:00 am 01:01 00 ? 01:01:00 01:01:00 i h i m ? s Thu Jan  1 01:01:00 GMT 1970}
+test clock-4.22 { format time of day 01:01:01 } {
+    clock format 3661 \
+        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+	  -locale en_US_roman \
+        -gmt true
+} {01 i 01 i  1 i  1 i 01 i AM am 01:01:01 am 01:01 01 i 01:01:01 01:01:01 i h i m i s Thu Jan  1 01:01:01 GMT 1970}
+test clock-4.23 { format time of day 01:01:58 } {
+    clock format 3718 \
+        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+	  -locale en_US_roman \
+        -gmt true
+} {01 i 01 i  1 i  1 i 01 i AM am 01:01:58 am 01:01 58 lviii 01:01:58 01:01:58 i h i m lviii s Thu Jan  1 01:01:58 GMT 1970}
+test clock-4.24 { format time of day 01:01:59 } {
+    clock format 3719 \
+        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+	  -locale en_US_roman \
+        -gmt true
+} {01 i 01 i  1 i  1 i 01 i AM am 01:01:59 am 01:01 59 lix 01:01:59 01:01:59 i h i m lix s Thu Jan  1 01:01:59 GMT 1970}
+test clock-4.25 { format time of day 01:58:00 } {
+    clock format 7080 \
+        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+	  -locale en_US_roman \
+        -gmt true
+} {01 i 01 i  1 i  1 i 58 lviii AM am 01:58:00 am 01:58 00 ? 01:58:00 01:58:00 i h lviii m ? s Thu Jan  1 01:58:00 GMT 1970}
+test clock-4.26 { format time of day 01:58:01 } {
+    clock format 7081 \
+        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+	  -locale en_US_roman \
+        -gmt true
+} {01 i 01 i  1 i  1 i 58 lviii AM am 01:58:01 am 01:58 01 i 01:58:01 01:58:01 i h lviii m i s Thu Jan  1 01:58:01 GMT 1970}
+test clock-4.27 { format time of day 01:58:58 } {
+    clock format 7138 \
+        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+	  -locale en_US_roman \
+        -gmt true
+} {01 i 01 i  1 i  1 i 58 lviii AM am 01:58:58 am 01:58 58 lviii 01:58:58 01:58:58 i h lviii m lviii s Thu Jan  1 01:58:58 GMT 1970}
+test clock-4.28 { format time of day 01:58:59 } {
+    clock format 7139 \
+        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+	  -locale en_US_roman \
+        -gmt true
+} {01 i 01 i  1 i  1 i 58 lviii AM am 01:58:59 am 01:58 59 lix 01:58:59 01:58:59 i h lviii m lix s Thu Jan  1 01:58:59 GMT 1970}
+test clock-4.29 { format time of day 01:59:00 } {
+    clock format 7140 \
+        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+	  -locale en_US_roman \
+        -gmt true
+} {01 i 01 i  1 i  1 i 59 lix AM am 01:59:00 am 01:59 00 ? 01:59:00 01:59:00 i h lix m ? s Thu Jan  1 01:59:00 GMT 1970}
+test clock-4.30 { format time of day 01:59:01 } {
+    clock format 7141 \
+        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+	  -locale en_US_roman \
+        -gmt true
+} {01 i 01 i  1 i  1 i 59 lix AM am 01:59:01 am 01:59 01 i 01:59:01 01:59:01 i h lix m i s Thu Jan  1 01:59:01 GMT 1970}
+test clock-4.31 { format time of day 01:59:58 } {
+    clock format 7198 \
+        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+	  -locale en_US_roman \
+        -gmt true
+} {01 i 01 i  1 i  1 i 59 lix AM am 01:59:58 am 01:59 58 lviii 01:59:58 01:59:58 i h lix m lviii s Thu Jan  1 01:59:58 GMT 1970}
+test clock-4.32 { format time of day 01:59:59 } {
+    clock format 7199 \
+        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+	  -locale en_US_roman \
+        -gmt true
+} {01 i 01 i  1 i  1 i 59 lix AM am 01:59:59 am 01:59 59 lix 01:59:59 01:59:59 i h lix m lix s Thu Jan  1 01:59:59 GMT 1970}
+test clock-4.33 { format time of day 11:00:00 } {
+    clock format 39600 \
+        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+	  -locale en_US_roman \
+        -gmt true
+} {11 xi 11 xi 11 xi 11 xi 00 ? AM am 11:00:00 am 11:00 00 ? 11:00:00 11:00:00 xi h ? m ? s Thu Jan  1 11:00:00 GMT 1970}
+test clock-4.34 { format time of day 11:00:01 } {
+    clock format 39601 \
+        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+	  -locale en_US_roman \
+        -gmt true
+} {11 xi 11 xi 11 xi 11 xi 00 ? AM am 11:00:01 am 11:00 01 i 11:00:01 11:00:01 xi h ? m i s Thu Jan  1 11:00:01 GMT 1970}
+test clock-4.35 { format time of day 11:00:58 } {
+    clock format 39658 \
+        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+	  -locale en_US_roman \
+        -gmt true
+} {11 xi 11 xi 11 xi 11 xi 00 ? AM am 11:00:58 am 11:00 58 lviii 11:00:58 11:00:58 xi h ? m lviii s Thu Jan  1 11:00:58 GMT 1970}
+test clock-4.36 { format time of day 11:00:59 } {
+    clock format 39659 \
+        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+	  -locale en_US_roman \
+        -gmt true
+} {11 xi 11 xi 11 xi 11 xi 00 ? AM am 11:00:59 am 11:00 59 lix 11:00:59 11:00:59 xi h ? m lix s Thu Jan  1 11:00:59 GMT 1970}
+test clock-4.37 { format time of day 11:01:00 } {
+    clock format 39660 \
+        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+	  -locale en_US_roman \
+        -gmt true
+} {11 xi 11 xi 11 xi 11 xi 01 i AM am 11:01:00 am 11:01 00 ? 11:01:00 11:01:00 xi h i m ? s Thu Jan  1 11:01:00 GMT 1970}
+test clock-4.38 { format time of day 11:01:01 } {
+    clock format 39661 \
+        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+	  -locale en_US_roman \
+        -gmt true
+} {11 xi 11 xi 11 xi 11 xi 01 i AM am 11:01:01 am 11:01 01 i 11:01:01 11:01:01 xi h i m i s Thu Jan  1 11:01:01 GMT 1970}
+test clock-4.39 { format time of day 11:01:58 } {
+    clock format 39718 \
+        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+	  -locale en_US_roman \
+        -gmt true
+} {11 xi 11 xi 11 xi 11 xi 01 i AM am 11:01:58 am 11:01 58 lviii 11:01:58 11:01:58 xi h i m lviii s Thu Jan  1 11:01:58 GMT 1970}
+test clock-4.40 { format time of day 11:01:59 } {
+    clock format 39719 \
+        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+	  -locale en_US_roman \
+        -gmt true
+} {11 xi 11 xi 11 xi 11 xi 01 i AM am 11:01:59 am 11:01 59 lix 11:01:59 11:01:59 xi h i m lix s Thu Jan  1 11:01:59 GMT 1970}
+test clock-4.41 { format time of day 11:58:00 } {
+    clock format 43080 \
+        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+	  -locale en_US_roman \
+        -gmt true
+} {11 xi 11 xi 11 xi 11 xi 58 lviii AM am 11:58:00 am 11:58 00 ? 11:58:00 11:58:00 xi h lviii m ? s Thu Jan  1 11:58:00 GMT 1970}
+test clock-4.42 { format time of day 11:58:01 } {
+    clock format 43081 \
+        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+	  -locale en_US_roman \
+        -gmt true
+} {11 xi 11 xi 11 xi 11 xi 58 lviii AM am 11:58:01 am 11:58 01 i 11:58:01 11:58:01 xi h lviii m i s Thu Jan  1 11:58:01 GMT 1970}
+test clock-4.43 { format time of day 11:58:58 } {
+    clock format 43138 \
+        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+	  -locale en_US_roman \
+        -gmt true
+} {11 xi 11 xi 11 xi 11 xi 58 lviii AM am 11:58:58 am 11:58 58 lviii 11:58:58 11:58:58 xi h lviii m lviii s Thu Jan  1 11:58:58 GMT 1970}
+test clock-4.44 { format time of day 11:58:59 } {
+    clock format 43139 \
+        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+	  -locale en_US_roman \
+        -gmt true
+} {11 xi 11 xi 11 xi 11 xi 58 lviii AM am 11:58:59 am 11:58 59 lix 11:58:59 11:58:59 xi h lviii m lix s Thu Jan  1 11:58:59 GMT 1970}
+test clock-4.45 { format time of day 11:59:00 } {
+    clock format 43140 \
+        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+	  -locale en_US_roman \
+        -gmt true
+} {11 xi 11 xi 11 xi 11 xi 59 lix AM am 11:59:00 am 11:59 00 ? 11:59:00 11:59:00 xi h lix m ? s Thu Jan  1 11:59:00 GMT 1970}
+test clock-4.46 { format time of day 11:59:01 } {
+    clock format 43141 \
+        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+	  -locale en_US_roman \
+        -gmt true
+} {11 xi 11 xi 11 xi 11 xi 59 lix AM am 11:59:01 am 11:59 01 i 11:59:01 11:59:01 xi h lix m i s Thu Jan  1 11:59:01 GMT 1970}
+test clock-4.47 { format time of day 11:59:58 } {
+    clock format 43198 \
+        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+	  -locale en_US_roman \
+        -gmt true
+} {11 xi 11 xi 11 xi 11 xi 59 lix AM am 11:59:58 am 11:59 58 lviii 11:59:58 11:59:58 xi h lix m lviii s Thu Jan  1 11:59:58 GMT 1970}
+test clock-4.48 { format time of day 11:59:59 } {
+    clock format 43199 \
+        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+	  -locale en_US_roman \
+        -gmt true
+} {11 xi 11 xi 11 xi 11 xi 59 lix AM am 11:59:59 am 11:59 59 lix 11:59:59 11:59:59 xi h lix m lix s Thu Jan  1 11:59:59 GMT 1970}
+test clock-4.49 { format time of day 12:00:00 } {
+    clock format 43200 \
+        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+	  -locale en_US_roman \
+        -gmt true
+} {12 xii 12 xii 12 xii 12 xii 00 ? PM pm 12:00:00 pm 12:00 00 ? 12:00:00 12:00:00 xii h ? m ? s Thu Jan  1 12:00:00 GMT 1970}
+test clock-4.50 { format time of day 12:00:01 } {
+    clock format 43201 \
+        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+	  -locale en_US_roman \
+        -gmt true
+} {12 xii 12 xii 12 xii 12 xii 00 ? PM pm 12:00:01 pm 12:00 01 i 12:00:01 12:00:01 xii h ? m i s Thu Jan  1 12:00:01 GMT 1970}
+test clock-4.51 { format time of day 12:00:58 } {
+    clock format 43258 \
+        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+	  -locale en_US_roman \
+        -gmt true
+} {12 xii 12 xii 12 xii 12 xii 00 ? PM pm 12:00:58 pm 12:00 58 lviii 12:00:58 12:00:58 xii h ? m lviii s Thu Jan  1 12:00:58 GMT 1970}
+test clock-4.52 { format time of day 12:00:59 } {
+    clock format 43259 \
+        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+	  -locale en_US_roman \
+        -gmt true
+} {12 xii 12 xii 12 xii 12 xii 00 ? PM pm 12:00:59 pm 12:00 59 lix 12:00:59 12:00:59 xii h ? m lix s Thu Jan  1 12:00:59 GMT 1970}
+test clock-4.53 { format time of day 12:01:00 } {
+    clock format 43260 \
+        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+	  -locale en_US_roman \
+        -gmt true
+} {12 xii 12 xii 12 xii 12 xii 01 i PM pm 12:01:00 pm 12:01 00 ? 12:01:00 12:01:00 xii h i m ? s Thu Jan  1 12:01:00 GMT 1970}
+test clock-4.54 { format time of day 12:01:01 } {
+    clock format 43261 \
+        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+	  -locale en_US_roman \
+        -gmt true
+} {12 xii 12 xii 12 xii 12 xii 01 i PM pm 12:01:01 pm 12:01 01 i 12:01:01 12:01:01 xii h i m i s Thu Jan  1 12:01:01 GMT 1970}
+test clock-4.55 { format time of day 12:01:58 } {
+    clock format 43318 \
+        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+	  -locale en_US_roman \
+        -gmt true
+} {12 xii 12 xii 12 xii 12 xii 01 i PM pm 12:01:58 pm 12:01 58 lviii 12:01:58 12:01:58 xii h i m lviii s Thu Jan  1 12:01:58 GMT 1970}
+test clock-4.56 { format time of day 12:01:59 } {
+    clock format 43319 \
+        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+	  -locale en_US_roman \
+        -gmt true
+} {12 xii 12 xii 12 xii 12 xii 01 i PM pm 12:01:59 pm 12:01 59 lix 12:01:59 12:01:59 xii h i m lix s Thu Jan  1 12:01:59 GMT 1970}
+test clock-4.57 { format time of day 12:58:00 } {
+    clock format 46680 \
+        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+	  -locale en_US_roman \
+        -gmt true
+} {12 xii 12 xii 12 xii 12 xii 58 lviii PM pm 12:58:00 pm 12:58 00 ? 12:58:00 12:58:00 xii h lviii m ? s Thu Jan  1 12:58:00 GMT 1970}
+test clock-4.58 { format time of day 12:58:01 } {
+    clock format 46681 \
+        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+	  -locale en_US_roman \
+        -gmt true
+} {12 xii 12 xii 12 xii 12 xii 58 lviii PM pm 12:58:01 pm 12:58 01 i 12:58:01 12:58:01 xii h lviii m i s Thu Jan  1 12:58:01 GMT 1970}
+test clock-4.59 { format time of day 12:58:58 } {
+    clock format 46738 \
+        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+	  -locale en_US_roman \
+        -gmt true
+} {12 xii 12 xii 12 xii 12 xii 58 lviii PM pm 12:58:58 pm 12:58 58 lviii 12:58:58 12:58:58 xii h lviii m lviii s Thu Jan  1 12:58:58 GMT 1970}
+test clock-4.60 { format time of day 12:58:59 } {
+    clock format 46739 \
+        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+	  -locale en_US_roman \
+        -gmt true
+} {12 xii 12 xii 12 xii 12 xii 58 lviii PM pm 12:58:59 pm 12:58 59 lix 12:58:59 12:58:59 xii h lviii m lix s Thu Jan  1 12:58:59 GMT 1970}
+test clock-4.61 { format time of day 12:59:00 } {
+    clock format 46740 \
+        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+	  -locale en_US_roman \
+        -gmt true
+} {12 xii 12 xii 12 xii 12 xii 59 lix PM pm 12:59:00 pm 12:59 00 ? 12:59:00 12:59:00 xii h lix m ? s Thu Jan  1 12:59:00 GMT 1970}
+test clock-4.62 { format time of day 12:59:01 } {
+    clock format 46741 \
+        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+	  -locale en_US_roman \
+        -gmt true
+} {12 xii 12 xii 12 xii 12 xii 59 lix PM pm 12:59:01 pm 12:59 01 i 12:59:01 12:59:01 xii h lix m i s Thu Jan  1 12:59:01 GMT 1970}
+test clock-4.63 { format time of day 12:59:58 } {
+    clock format 46798 \
+        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+	  -locale en_US_roman \
+        -gmt true
+} {12 xii 12 xii 12 xii 12 xii 59 lix PM pm 12:59:58 pm 12:59 58 lviii 12:59:58 12:59:58 xii h lix m lviii s Thu Jan  1 12:59:58 GMT 1970}
+test clock-4.64 { format time of day 12:59:59 } {
+    clock format 46799 \
+        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+	  -locale en_US_roman \
+        -gmt true
+} {12 xii 12 xii 12 xii 12 xii 59 lix PM pm 12:59:59 pm 12:59 59 lix 12:59:59 12:59:59 xii h lix m lix s Thu Jan  1 12:59:59 GMT 1970}
+test clock-4.65 { format time of day 13:00:00 } {
+    clock format 46800 \
+        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+	  -locale en_US_roman \
+        -gmt true
+} {13 xiii 01 i 13 xiii  1 i 00 ? PM pm 01:00:00 pm 13:00 00 ? 13:00:00 13:00:00 xiii h ? m ? s Thu Jan  1 13:00:00 GMT 1970}
+test clock-4.66 { format time of day 13:00:01 } {
+    clock format 46801 \
+        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+	  -locale en_US_roman \
+        -gmt true
+} {13 xiii 01 i 13 xiii  1 i 00 ? PM pm 01:00:01 pm 13:00 01 i 13:00:01 13:00:01 xiii h ? m i s Thu Jan  1 13:00:01 GMT 1970}
+test clock-4.67 { format time of day 13:00:58 } {
+    clock format 46858 \
+        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+	  -locale en_US_roman \
+        -gmt true
+} {13 xiii 01 i 13 xiii  1 i 00 ? PM pm 01:00:58 pm 13:00 58 lviii 13:00:58 13:00:58 xiii h ? m lviii s Thu Jan  1 13:00:58 GMT 1970}
+test clock-4.68 { format time of day 13:00:59 } {
+    clock format 46859 \
+        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+	  -locale en_US_roman \
+        -gmt true
+} {13 xiii 01 i 13 xiii  1 i 00 ? PM pm 01:00:59 pm 13:00 59 lix 13:00:59 13:00:59 xiii h ? m lix s Thu Jan  1 13:00:59 GMT 1970}
+test clock-4.69 { format time of day 13:01:00 } {
+    clock format 46860 \
+        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+	  -locale en_US_roman \
+        -gmt true
+} {13 xiii 01 i 13 xiii  1 i 01 i PM pm 01:01:00 pm 13:01 00 ? 13:01:00 13:01:00 xiii h i m ? s Thu Jan  1 13:01:00 GMT 1970}
+test clock-4.70 { format time of day 13:01:01 } {
+    clock format 46861 \
+        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+	  -locale en_US_roman \
+        -gmt true
+} {13 xiii 01 i 13 xiii  1 i 01 i PM pm 01:01:01 pm 13:01 01 i 13:01:01 13:01:01 xiii h i m i s Thu Jan  1 13:01:01 GMT 1970}
+test clock-4.71 { format time of day 13:01:58 } {
+    clock format 46918 \
+        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+	  -locale en_US_roman \
+        -gmt true
+} {13 xiii 01 i 13 xiii  1 i 01 i PM pm 01:01:58 pm 13:01 58 lviii 13:01:58 13:01:58 xiii h i m lviii s Thu Jan  1 13:01:58 GMT 1970}
+test clock-4.72 { format time of day 13:01:59 } {
+    clock format 46919 \
+        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+	  -locale en_US_roman \
+        -gmt true
+} {13 xiii 01 i 13 xiii  1 i 01 i PM pm 01:01:59 pm 13:01 59 lix 13:01:59 13:01:59 xiii h i m lix s Thu Jan  1 13:01:59 GMT 1970}
+test clock-4.73 { format time of day 13:58:00 } {
+    clock format 50280 \
+        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+	  -locale en_US_roman \
+        -gmt true
+} {13 xiii 01 i 13 xiii  1 i 58 lviii PM pm 01:58:00 pm 13:58 00 ? 13:58:00 13:58:00 xiii h lviii m ? s Thu Jan  1 13:58:00 GMT 1970}
+test clock-4.74 { format time of day 13:58:01 } {
+    clock format 50281 \
+        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+	  -locale en_US_roman \
+        -gmt true
+} {13 xiii 01 i 13 xiii  1 i 58 lviii PM pm 01:58:01 pm 13:58 01 i 13:58:01 13:58:01 xiii h lviii m i s Thu Jan  1 13:58:01 GMT 1970}
+test clock-4.75 { format time of day 13:58:58 } {
+    clock format 50338 \
+        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+	  -locale en_US_roman \
+        -gmt true
+} {13 xiii 01 i 13 xiii  1 i 58 lviii PM pm 01:58:58 pm 13:58 58 lviii 13:58:58 13:58:58 xiii h lviii m lviii s Thu Jan  1 13:58:58 GMT 1970}
+test clock-4.76 { format time of day 13:58:59 } {
+    clock format 50339 \
+        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+	  -locale en_US_roman \
+        -gmt true
+} {13 xiii 01 i 13 xiii  1 i 58 lviii PM pm 01:58:59 pm 13:58 59 lix 13:58:59 13:58:59 xiii h lviii m lix s Thu Jan  1 13:58:59 GMT 1970}
+test clock-4.77 { format time of day 13:59:00 } {
+    clock format 50340 \
+        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+	  -locale en_US_roman \
+        -gmt true
+} {13 xiii 01 i 13 xiii  1 i 59 lix PM pm 01:59:00 pm 13:59 00 ? 13:59:00 13:59:00 xiii h lix m ? s Thu Jan  1 13:59:00 GMT 1970}
+test clock-4.78 { format time of day 13:59:01 } {
+    clock format 50341 \
+        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+	  -locale en_US_roman \
+        -gmt true
+} {13 xiii 01 i 13 xiii  1 i 59 lix PM pm 01:59:01 pm 13:59 01 i 13:59:01 13:59:01 xiii h lix m i s Thu Jan  1 13:59:01 GMT 1970}
+test clock-4.79 { format time of day 13:59:58 } {
+    clock format 50398 \
+        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+	  -locale en_US_roman \
+        -gmt true
+} {13 xiii 01 i 13 xiii  1 i 59 lix PM pm 01:59:58 pm 13:59 58 lviii 13:59:58 13:59:58 xiii h lix m lviii s Thu Jan  1 13:59:58 GMT 1970}
+test clock-4.80 { format time of day 13:59:59 } {
+    clock format 50399 \
+        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+	  -locale en_US_roman \
+        -gmt true
+} {13 xiii 01 i 13 xiii  1 i 59 lix PM pm 01:59:59 pm 13:59 59 lix 13:59:59 13:59:59 xiii h lix m lix s Thu Jan  1 13:59:59 GMT 1970}
+test clock-4.81 { format time of day 23:00:00 } {
+    clock format 82800 \
+        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+	  -locale en_US_roman \
+        -gmt true
+} {23 xxiii 11 xi 23 xxiii 11 xi 00 ? PM pm 11:00:00 pm 23:00 00 ? 23:00:00 23:00:00 xxiii h ? m ? s Thu Jan  1 23:00:00 GMT 1970}
+test clock-4.82 { format time of day 23:00:01 } {
+    clock format 82801 \
+        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+	  -locale en_US_roman \
+        -gmt true
+} {23 xxiii 11 xi 23 xxiii 11 xi 00 ? PM pm 11:00:01 pm 23:00 01 i 23:00:01 23:00:01 xxiii h ? m i s Thu Jan  1 23:00:01 GMT 1970}
+test clock-4.83 { format time of day 23:00:58 } {
+    clock format 82858 \
+        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+	  -locale en_US_roman \
+        -gmt true
+} {23 xxiii 11 xi 23 xxiii 11 xi 00 ? PM pm 11:00:58 pm 23:00 58 lviii 23:00:58 23:00:58 xxiii h ? m lviii s Thu Jan  1 23:00:58 GMT 1970}
+test clock-4.84 { format time of day 23:00:59 } {
+    clock format 82859 \
+        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+	  -locale en_US_roman \
+        -gmt true
+} {23 xxiii 11 xi 23 xxiii 11 xi 00 ? PM pm 11:00:59 pm 23:00 59 lix 23:00:59 23:00:59 xxiii h ? m lix s Thu Jan  1 23:00:59 GMT 1970}
+test clock-4.85 { format time of day 23:01:00 } {
+    clock format 82860 \
+        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+	  -locale en_US_roman \
+        -gmt true
+} {23 xxiii 11 xi 23 xxiii 11 xi 01 i PM pm 11:01:00 pm 23:01 00 ? 23:01:00 23:01:00 xxiii h i m ? s Thu Jan  1 23:01:00 GMT 1970}
+test clock-4.86 { format time of day 23:01:01 } {
+    clock format 82861 \
+        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+	  -locale en_US_roman \
+        -gmt true
+} {23 xxiii 11 xi 23 xxiii 11 xi 01 i PM pm 11:01:01 pm 23:01 01 i 23:01:01 23:01:01 xxiii h i m i s Thu Jan  1 23:01:01 GMT 1970}
+test clock-4.87 { format time of day 23:01:58 } {
+    clock format 82918 \
+        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+	  -locale en_US_roman \
+        -gmt true
+} {23 xxiii 11 xi 23 xxiii 11 xi 01 i PM pm 11:01:58 pm 23:01 58 lviii 23:01:58 23:01:58 xxiii h i m lviii s Thu Jan  1 23:01:58 GMT 1970}
+test clock-4.88 { format time of day 23:01:59 } {
+    clock format 82919 \
+        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+	  -locale en_US_roman \
+        -gmt true
+} {23 xxiii 11 xi 23 xxiii 11 xi 01 i PM pm 11:01:59 pm 23:01 59 lix 23:01:59 23:01:59 xxiii h i m lix s Thu Jan  1 23:01:59 GMT 1970}
+test clock-4.89 { format time of day 23:58:00 } {
+    clock format 86280 \
+        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+	  -locale en_US_roman \
+        -gmt true
+} {23 xxiii 11 xi 23 xxiii 11 xi 58 lviii PM pm 11:58:00 pm 23:58 00 ? 23:58:00 23:58:00 xxiii h lviii m ? s Thu Jan  1 23:58:00 GMT 1970}
+test clock-4.90 { format time of day 23:58:01 } {
+    clock format 86281 \
+        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+	  -locale en_US_roman \
+        -gmt true
+} {23 xxiii 11 xi 23 xxiii 11 xi 58 lviii PM pm 11:58:01 pm 23:58 01 i 23:58:01 23:58:01 xxiii h lviii m i s Thu Jan  1 23:58:01 GMT 1970}
+test clock-4.91 { format time of day 23:58:58 } {
+    clock format 86338 \
+        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+	  -locale en_US_roman \
+        -gmt true
+} {23 xxiii 11 xi 23 xxiii 11 xi 58 lviii PM pm 11:58:58 pm 23:58 58 lviii 23:58:58 23:58:58 xxiii h lviii m lviii s Thu Jan  1 23:58:58 GMT 1970}
+test clock-4.92 { format time of day 23:58:59 } {
+    clock format 86339 \
+        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+	  -locale en_US_roman \
+        -gmt true
+} {23 xxiii 11 xi 23 xxiii 11 xi 58 lviii PM pm 11:58:59 pm 23:58 59 lix 23:58:59 23:58:59 xxiii h lviii m lix s Thu Jan  1 23:58:59 GMT 1970}
+test clock-4.93 { format time of day 23:59:00 } {
+    clock format 86340 \
+        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+	  -locale en_US_roman \
+        -gmt true
+} {23 xxiii 11 xi 23 xxiii 11 xi 59 lix PM pm 11:59:00 pm 23:59 00 ? 23:59:00 23:59:00 xxiii h lix m ? s Thu Jan  1 23:59:00 GMT 1970}
+test clock-4.94 { format time of day 23:59:01 } {
+    clock format 86341 \
+        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+	  -locale en_US_roman \
+        -gmt true
+} {23 xxiii 11 xi 23 xxiii 11 xi 59 lix PM pm 11:59:01 pm 23:59 01 i 23:59:01 23:59:01 xxiii h lix m i s Thu Jan  1 23:59:01 GMT 1970}
+test clock-4.95 { format time of day 23:59:58 } {
+    clock format 86398 \
+        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+	  -locale en_US_roman \
+        -gmt true
+} {23 xxiii 11 xi 23 xxiii 11 xi 59 lix PM pm 11:59:58 pm 23:59 58 lviii 23:59:58 23:59:58 xxiii h lix m lviii s Thu Jan  1 23:59:58 GMT 1970}
+test clock-4.96 { format time of day 23:59:59 } {
+    clock format 86399 \
+        -format {%H %OH %I %OI %k %Ok %l %Ol %M %OM %p %P %r %R %S %OS %T %X %EX %+} \
+	  -locale en_US_roman \
+        -gmt true
+} {23 xxiii 11 xi 23 xxiii 11 xi 59 lix PM pm 11:59:59 pm 23:59 59 lix 23:59:59 23:59:59 xxiii h lix m lix s Thu Jan  1 23:59:59 GMT 1970}
+# END testcases4
+
+# BEGIN testcases5
+
+# Test formatting of Daylight Saving Time
+
+test clock-5.1 {does Detroit exist} {
+    clock format 0 -format {} -timezone :America/Detroit
+    concat
+} {}
+test clock-5.2 {does Detroit have a Y2038 problem} detroit {
+    if { [clock format 2158894800 -format %z -timezone :America/Detroit] ne {-0400} } {
+        concat {y2038 problem}
+    } else {
+        concat {ok}
+    }
+} ok
+test clock-5.3 {time zone boundary case 1904-12-31 23:59:59} detroit {
+    clock format -2051202470 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {23:59:59 -053211 LMT}
+test clock-5.4 {time zone boundary case 1904-12-31 23:32:11} detroit {
+    clock format -2051202469 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {23:32:11 -0600 CST}
+test clock-5.5 {time zone boundary case 1904-12-31 23:32:12} detroit {
+    clock format -2051202468 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {23:32:12 -0600 CST}
+test clock-5.6 {time zone boundary case 1915-05-15 01:59:59} detroit {
+    clock format -1724083201 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0600 CST}
+test clock-5.7 {time zone boundary case 1915-05-15 03:00:00} detroit {
+    clock format -1724083200 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0500 EST}
+test clock-5.8 {time zone boundary case 1915-05-15 03:00:01} detroit {
+    clock format -1724083199 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0500 EST}
+test clock-5.9 {time zone boundary case 1941-12-31 23:59:59} detroit {
+    clock format -883594801 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {23:59:59 -0500 EST}
+test clock-5.10 {time zone boundary case 1942-01-01 00:00:00} detroit {
+    clock format -883594800 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {00:00:00 -0500 EST}
+test clock-5.11 {time zone boundary case 1942-01-01 00:00:01} detroit {
+    clock format -883594799 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {00:00:01 -0500 EST}
+test clock-5.12 {time zone boundary case 1942-02-09 01:59:59} detroit {
+    clock format -880218001 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.13 {time zone boundary case 1942-02-09 03:00:00} detroit {
+    clock format -880218000 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EWT}
+test clock-5.14 {time zone boundary case 1942-02-09 03:00:01} detroit {
+    clock format -880217999 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EWT}
+test clock-5.15 {time zone boundary case 1945-08-14 18:59:59} detroit {
+    clock format -769395601 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {18:59:59 -0400 EWT}
+test clock-5.16 {time zone boundary case 1945-08-14 19:00:00} detroit {
+    clock format -769395600 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {19:00:00 -0400 EPT}
+test clock-5.17 {time zone boundary case 1945-08-14 19:00:01} detroit {
+    clock format -769395599 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {19:00:01 -0400 EPT}
+test clock-5.18 {time zone boundary case 1945-09-30 01:59:59} detroit {
+    clock format -765396001 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EPT}
+test clock-5.19 {time zone boundary case 1945-09-30 01:00:00} detroit {
+    clock format -765396000 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.20 {time zone boundary case 1945-09-30 01:00:01} detroit {
+    clock format -765395999 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.21 {time zone boundary case 1945-12-31 23:59:59} detroit {
+    clock format -757364401 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {23:59:59 -0500 EST}
+test clock-5.22 {time zone boundary case 1946-01-01 00:00:00} detroit {
+    clock format -757364400 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {00:00:00 -0500 EST}
+test clock-5.23 {time zone boundary case 1946-01-01 00:00:01} detroit {
+    clock format -757364399 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {00:00:01 -0500 EST}
+test clock-5.24 {time zone boundary case 1948-04-25 01:59:59} detroit {
+    clock format -684349201 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.25 {time zone boundary case 1948-04-25 03:00:00} detroit {
+    clock format -684349200 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.26 {time zone boundary case 1948-04-25 03:00:01} detroit {
+    clock format -684349199 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.27 {time zone boundary case 1948-09-26 01:59:59} detroit {
+    clock format -671047201 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.28 {time zone boundary case 1948-09-26 01:00:00} detroit {
+    clock format -671047200 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.29 {time zone boundary case 1948-09-26 01:00:01} detroit {
+    clock format -671047199 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.30 {time zone boundary case 1967-06-14 01:59:59} detroit {
+    clock format -80499601 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.31 {time zone boundary case 1967-06-14 03:00:00} detroit {
+    clock format -80499600 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.32 {time zone boundary case 1967-06-14 03:00:01} detroit {
+    clock format -80499599 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.33 {time zone boundary case 1967-10-29 01:59:59} detroit {
+    clock format -68666401 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.34 {time zone boundary case 1967-10-29 01:00:00} detroit {
+    clock format -68666400 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.35 {time zone boundary case 1967-10-29 01:00:01} detroit {
+    clock format -68666399 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.36 {time zone boundary case 1972-12-31 23:59:59} detroit {
+    clock format 94712399 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {23:59:59 -0500 EST}
+test clock-5.37 {time zone boundary case 1973-01-01 00:00:00} detroit {
+    clock format 94712400 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {00:00:00 -0500 EST}
+test clock-5.38 {time zone boundary case 1973-01-01 00:00:01} detroit {
+    clock format 94712401 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {00:00:01 -0500 EST}
+test clock-5.39 {time zone boundary case 1973-04-29 01:59:59} detroit {
+    clock format 104914799 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.40 {time zone boundary case 1973-04-29 03:00:00} detroit {
+    clock format 104914800 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.41 {time zone boundary case 1973-04-29 03:00:01} detroit {
+    clock format 104914801 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.42 {time zone boundary case 1973-10-28 01:59:59} detroit {
+    clock format 120635999 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.43 {time zone boundary case 1973-10-28 01:00:00} detroit {
+    clock format 120636000 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.44 {time zone boundary case 1973-10-28 01:00:01} detroit {
+    clock format 120636001 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.45 {time zone boundary case 1974-01-06 01:59:59} detroit {
+    clock format 126687599 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.46 {time zone boundary case 1974-01-06 03:00:00} detroit {
+    clock format 126687600 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.47 {time zone boundary case 1974-01-06 03:00:01} detroit {
+    clock format 126687601 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.48 {time zone boundary case 1974-10-27 01:59:59} detroit {
+    clock format 152085599 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.49 {time zone boundary case 1974-10-27 01:00:00} detroit {
+    clock format 152085600 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.50 {time zone boundary case 1974-10-27 01:00:01} detroit {
+    clock format 152085601 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.51 {time zone boundary case 1974-12-31 23:59:59} detroit {
+    clock format 157784399 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {23:59:59 -0500 EST}
+test clock-5.52 {time zone boundary case 1975-01-01 00:00:00} detroit {
+    clock format 157784400 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {00:00:00 -0500 EST}
+test clock-5.53 {time zone boundary case 1975-01-01 00:00:01} detroit {
+    clock format 157784401 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {00:00:01 -0500 EST}
+test clock-5.54 {time zone boundary case 1975-04-27 01:59:59} detroit {
+    clock format 167813999 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.55 {time zone boundary case 1975-04-27 03:00:00} detroit {
+    clock format 167814000 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.56 {time zone boundary case 1975-04-27 03:00:01} detroit {
+    clock format 167814001 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.57 {time zone boundary case 1975-10-26 01:59:59} detroit {
+    clock format 183535199 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.58 {time zone boundary case 1975-10-26 01:00:00} detroit {
+    clock format 183535200 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.59 {time zone boundary case 1975-10-26 01:00:01} detroit {
+    clock format 183535201 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.60 {time zone boundary case 1976-04-25 01:59:59} detroit {
+    clock format 199263599 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.61 {time zone boundary case 1976-04-25 03:00:00} detroit {
+    clock format 199263600 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.62 {time zone boundary case 1976-04-25 03:00:01} detroit {
+    clock format 199263601 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.63 {time zone boundary case 1976-10-31 01:59:59} detroit {
+    clock format 215589599 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.64 {time zone boundary case 1976-10-31 01:00:00} detroit {
+    clock format 215589600 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.65 {time zone boundary case 1976-10-31 01:00:01} detroit {
+    clock format 215589601 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.66 {time zone boundary case 1977-04-24 01:59:59} detroit {
+    clock format 230713199 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.67 {time zone boundary case 1977-04-24 03:00:00} detroit {
+    clock format 230713200 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.68 {time zone boundary case 1977-04-24 03:00:01} detroit {
+    clock format 230713201 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.69 {time zone boundary case 1977-10-30 01:59:59} detroit {
+    clock format 247039199 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.70 {time zone boundary case 1977-10-30 01:00:00} detroit {
+    clock format 247039200 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.71 {time zone boundary case 1977-10-30 01:00:01} detroit {
+    clock format 247039201 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.72 {time zone boundary case 1978-04-30 01:59:59} detroit {
+    clock format 262767599 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.73 {time zone boundary case 1978-04-30 03:00:00} detroit {
+    clock format 262767600 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.74 {time zone boundary case 1978-04-30 03:00:01} detroit {
+    clock format 262767601 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.75 {time zone boundary case 1978-10-29 01:59:59} detroit {
+    clock format 278488799 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.76 {time zone boundary case 1978-10-29 01:00:00} detroit {
+    clock format 278488800 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.77 {time zone boundary case 1978-10-29 01:00:01} detroit {
+    clock format 278488801 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.78 {time zone boundary case 1979-04-29 01:59:59} detroit {
+    clock format 294217199 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.79 {time zone boundary case 1979-04-29 03:00:00} detroit {
+    clock format 294217200 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.80 {time zone boundary case 1979-04-29 03:00:01} detroit {
+    clock format 294217201 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.81 {time zone boundary case 1979-10-28 01:59:59} detroit {
+    clock format 309938399 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.82 {time zone boundary case 1979-10-28 01:00:00} detroit {
+    clock format 309938400 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.83 {time zone boundary case 1979-10-28 01:00:01} detroit {
+    clock format 309938401 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.84 {time zone boundary case 1980-04-27 01:59:59} detroit {
+    clock format 325666799 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.85 {time zone boundary case 1980-04-27 03:00:00} detroit {
+    clock format 325666800 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.86 {time zone boundary case 1980-04-27 03:00:01} detroit {
+    clock format 325666801 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.87 {time zone boundary case 1980-10-26 01:59:59} detroit {
+    clock format 341387999 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.88 {time zone boundary case 1980-10-26 01:00:00} detroit {
+    clock format 341388000 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.89 {time zone boundary case 1980-10-26 01:00:01} detroit {
+    clock format 341388001 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.90 {time zone boundary case 1981-04-26 01:59:59} detroit {
+    clock format 357116399 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.91 {time zone boundary case 1981-04-26 03:00:00} detroit {
+    clock format 357116400 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.92 {time zone boundary case 1981-04-26 03:00:01} detroit {
+    clock format 357116401 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.93 {time zone boundary case 1981-10-25 01:59:59} detroit {
+    clock format 372837599 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.94 {time zone boundary case 1981-10-25 01:00:00} detroit {
+    clock format 372837600 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.95 {time zone boundary case 1981-10-25 01:00:01} detroit {
+    clock format 372837601 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.96 {time zone boundary case 1982-04-25 01:59:59} detroit {
+    clock format 388565999 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.97 {time zone boundary case 1982-04-25 03:00:00} detroit {
+    clock format 388566000 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.98 {time zone boundary case 1982-04-25 03:00:01} detroit {
+    clock format 388566001 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.99 {time zone boundary case 1982-10-31 01:59:59} detroit {
+    clock format 404891999 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.100 {time zone boundary case 1982-10-31 01:00:00} detroit {
+    clock format 404892000 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.101 {time zone boundary case 1982-10-31 01:00:01} detroit {
+    clock format 404892001 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.102 {time zone boundary case 1983-04-24 01:59:59} detroit {
+    clock format 420015599 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.103 {time zone boundary case 1983-04-24 03:00:00} detroit {
+    clock format 420015600 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.104 {time zone boundary case 1983-04-24 03:00:01} detroit {
+    clock format 420015601 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.105 {time zone boundary case 1983-10-30 01:59:59} detroit {
+    clock format 436341599 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.106 {time zone boundary case 1983-10-30 01:00:00} detroit {
+    clock format 436341600 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.107 {time zone boundary case 1983-10-30 01:00:01} detroit {
+    clock format 436341601 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.108 {time zone boundary case 1984-04-29 01:59:59} detroit {
+    clock format 452069999 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.109 {time zone boundary case 1984-04-29 03:00:00} detroit {
+    clock format 452070000 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.110 {time zone boundary case 1984-04-29 03:00:01} detroit {
+    clock format 452070001 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.111 {time zone boundary case 1984-10-28 01:59:59} detroit {
+    clock format 467791199 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.112 {time zone boundary case 1984-10-28 01:00:00} detroit {
+    clock format 467791200 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.113 {time zone boundary case 1984-10-28 01:00:01} detroit {
+    clock format 467791201 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.114 {time zone boundary case 1985-04-28 01:59:59} detroit {
+    clock format 483519599 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.115 {time zone boundary case 1985-04-28 03:00:00} detroit {
+    clock format 483519600 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.116 {time zone boundary case 1985-04-28 03:00:01} detroit {
+    clock format 483519601 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.117 {time zone boundary case 1985-10-27 01:59:59} detroit {
+    clock format 499240799 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.118 {time zone boundary case 1985-10-27 01:00:00} detroit {
+    clock format 499240800 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.119 {time zone boundary case 1985-10-27 01:00:01} detroit {
+    clock format 499240801 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.120 {time zone boundary case 1986-04-27 01:59:59} detroit {
+    clock format 514969199 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.121 {time zone boundary case 1986-04-27 03:00:00} detroit {
+    clock format 514969200 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.122 {time zone boundary case 1986-04-27 03:00:01} detroit {
+    clock format 514969201 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.123 {time zone boundary case 1986-10-26 01:59:59} detroit {
+    clock format 530690399 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.124 {time zone boundary case 1986-10-26 01:00:00} detroit {
+    clock format 530690400 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.125 {time zone boundary case 1986-10-26 01:00:01} detroit {
+    clock format 530690401 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.126 {time zone boundary case 1987-04-05 01:59:59} detroit {
+    clock format 544604399 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.127 {time zone boundary case 1987-04-05 03:00:00} detroit {
+    clock format 544604400 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.128 {time zone boundary case 1987-04-05 03:00:01} detroit {
+    clock format 544604401 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.129 {time zone boundary case 1987-10-25 01:59:59} detroit {
+    clock format 562139999 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.130 {time zone boundary case 1987-10-25 01:00:00} detroit {
+    clock format 562140000 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.131 {time zone boundary case 1987-10-25 01:00:01} detroit {
+    clock format 562140001 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.132 {time zone boundary case 1988-04-03 01:59:59} detroit {
+    clock format 576053999 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.133 {time zone boundary case 1988-04-03 03:00:00} detroit {
+    clock format 576054000 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.134 {time zone boundary case 1988-04-03 03:00:01} detroit {
+    clock format 576054001 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.135 {time zone boundary case 1988-10-30 01:59:59} detroit {
+    clock format 594194399 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.136 {time zone boundary case 1988-10-30 01:00:00} detroit {
+    clock format 594194400 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.137 {time zone boundary case 1988-10-30 01:00:01} detroit {
+    clock format 594194401 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.138 {time zone boundary case 1989-04-02 01:59:59} detroit {
+    clock format 607503599 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.139 {time zone boundary case 1989-04-02 03:00:00} detroit {
+    clock format 607503600 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.140 {time zone boundary case 1989-04-02 03:00:01} detroit {
+    clock format 607503601 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.141 {time zone boundary case 1989-10-29 01:59:59} detroit {
+    clock format 625643999 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.142 {time zone boundary case 1989-10-29 01:00:00} detroit {
+    clock format 625644000 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.143 {time zone boundary case 1989-10-29 01:00:01} detroit {
+    clock format 625644001 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.144 {time zone boundary case 1990-04-01 01:59:59} detroit {
+    clock format 638953199 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.145 {time zone boundary case 1990-04-01 03:00:00} detroit {
+    clock format 638953200 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.146 {time zone boundary case 1990-04-01 03:00:01} detroit {
+    clock format 638953201 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.147 {time zone boundary case 1990-10-28 01:59:59} detroit {
+    clock format 657093599 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.148 {time zone boundary case 1990-10-28 01:00:00} detroit {
+    clock format 657093600 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.149 {time zone boundary case 1990-10-28 01:00:01} detroit {
+    clock format 657093601 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.150 {time zone boundary case 1991-04-07 01:59:59} detroit {
+    clock format 671007599 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.151 {time zone boundary case 1991-04-07 03:00:00} detroit {
+    clock format 671007600 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.152 {time zone boundary case 1991-04-07 03:00:01} detroit {
+    clock format 671007601 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.153 {time zone boundary case 1991-10-27 01:59:59} detroit {
+    clock format 688543199 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.154 {time zone boundary case 1991-10-27 01:00:00} detroit {
+    clock format 688543200 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.155 {time zone boundary case 1991-10-27 01:00:01} detroit {
+    clock format 688543201 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.156 {time zone boundary case 1992-04-05 01:59:59} detroit {
+    clock format 702457199 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.157 {time zone boundary case 1992-04-05 03:00:00} detroit {
+    clock format 702457200 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.158 {time zone boundary case 1992-04-05 03:00:01} detroit {
+    clock format 702457201 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.159 {time zone boundary case 1992-10-25 01:59:59} detroit {
+    clock format 719992799 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.160 {time zone boundary case 1992-10-25 01:00:00} detroit {
+    clock format 719992800 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.161 {time zone boundary case 1992-10-25 01:00:01} detroit {
+    clock format 719992801 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.162 {time zone boundary case 1993-04-04 01:59:59} detroit {
+    clock format 733906799 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.163 {time zone boundary case 1993-04-04 03:00:00} detroit {
+    clock format 733906800 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.164 {time zone boundary case 1993-04-04 03:00:01} detroit {
+    clock format 733906801 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.165 {time zone boundary case 1993-10-31 01:59:59} detroit {
+    clock format 752047199 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.166 {time zone boundary case 1993-10-31 01:00:00} detroit {
+    clock format 752047200 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.167 {time zone boundary case 1993-10-31 01:00:01} detroit {
+    clock format 752047201 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.168 {time zone boundary case 1994-04-03 01:59:59} detroit {
+    clock format 765356399 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.169 {time zone boundary case 1994-04-03 03:00:00} detroit {
+    clock format 765356400 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.170 {time zone boundary case 1994-04-03 03:00:01} detroit {
+    clock format 765356401 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.171 {time zone boundary case 1994-10-30 01:59:59} detroit {
+    clock format 783496799 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.172 {time zone boundary case 1994-10-30 01:00:00} detroit {
+    clock format 783496800 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.173 {time zone boundary case 1994-10-30 01:00:01} detroit {
+    clock format 783496801 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.174 {time zone boundary case 1995-04-02 01:59:59} detroit {
+    clock format 796805999 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.175 {time zone boundary case 1995-04-02 03:00:00} detroit {
+    clock format 796806000 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.176 {time zone boundary case 1995-04-02 03:00:01} detroit {
+    clock format 796806001 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.177 {time zone boundary case 1995-10-29 01:59:59} detroit {
+    clock format 814946399 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.178 {time zone boundary case 1995-10-29 01:00:00} detroit {
+    clock format 814946400 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.179 {time zone boundary case 1995-10-29 01:00:01} detroit {
+    clock format 814946401 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.180 {time zone boundary case 1996-04-07 01:59:59} detroit {
+    clock format 828860399 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.181 {time zone boundary case 1996-04-07 03:00:00} detroit {
+    clock format 828860400 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.182 {time zone boundary case 1996-04-07 03:00:01} detroit {
+    clock format 828860401 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.183 {time zone boundary case 1996-10-27 01:59:59} detroit {
+    clock format 846395999 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.184 {time zone boundary case 1996-10-27 01:00:00} detroit {
+    clock format 846396000 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.185 {time zone boundary case 1996-10-27 01:00:01} detroit {
+    clock format 846396001 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.186 {time zone boundary case 1997-04-06 01:59:59} detroit {
+    clock format 860309999 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.187 {time zone boundary case 1997-04-06 03:00:00} detroit {
+    clock format 860310000 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.188 {time zone boundary case 1997-04-06 03:00:01} detroit {
+    clock format 860310001 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.189 {time zone boundary case 1997-10-26 01:59:59} detroit {
+    clock format 877845599 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.190 {time zone boundary case 1997-10-26 01:00:00} detroit {
+    clock format 877845600 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.191 {time zone boundary case 1997-10-26 01:00:01} detroit {
+    clock format 877845601 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.192 {time zone boundary case 1998-04-05 01:59:59} detroit {
+    clock format 891759599 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.193 {time zone boundary case 1998-04-05 03:00:00} detroit {
+    clock format 891759600 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.194 {time zone boundary case 1998-04-05 03:00:01} detroit {
+    clock format 891759601 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.195 {time zone boundary case 1998-10-25 01:59:59} detroit {
+    clock format 909295199 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.196 {time zone boundary case 1998-10-25 01:00:00} detroit {
+    clock format 909295200 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.197 {time zone boundary case 1998-10-25 01:00:01} detroit {
+    clock format 909295201 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.198 {time zone boundary case 1999-04-04 01:59:59} detroit {
+    clock format 923209199 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.199 {time zone boundary case 1999-04-04 03:00:00} detroit {
+    clock format 923209200 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.200 {time zone boundary case 1999-04-04 03:00:01} detroit {
+    clock format 923209201 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.201 {time zone boundary case 1999-10-31 01:59:59} detroit {
+    clock format 941349599 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.202 {time zone boundary case 1999-10-31 01:00:00} detroit {
+    clock format 941349600 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.203 {time zone boundary case 1999-10-31 01:00:01} detroit {
+    clock format 941349601 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.204 {time zone boundary case 2000-04-02 01:59:59} detroit {
+    clock format 954658799 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.205 {time zone boundary case 2000-04-02 03:00:00} detroit {
+    clock format 954658800 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.206 {time zone boundary case 2000-04-02 03:00:01} detroit {
+    clock format 954658801 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.207 {time zone boundary case 2000-10-29 01:59:59} detroit {
+    clock format 972799199 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.208 {time zone boundary case 2000-10-29 01:00:00} detroit {
+    clock format 972799200 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.209 {time zone boundary case 2000-10-29 01:00:01} detroit {
+    clock format 972799201 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.210 {time zone boundary case 2001-04-01 01:59:59} detroit {
+    clock format 986108399 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.211 {time zone boundary case 2001-04-01 03:00:00} detroit {
+    clock format 986108400 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.212 {time zone boundary case 2001-04-01 03:00:01} detroit {
+    clock format 986108401 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.213 {time zone boundary case 2001-10-28 01:59:59} detroit {
+    clock format 1004248799 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.214 {time zone boundary case 2001-10-28 01:00:00} detroit {
+    clock format 1004248800 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.215 {time zone boundary case 2001-10-28 01:00:01} detroit {
+    clock format 1004248801 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.216 {time zone boundary case 2002-04-07 01:59:59} detroit {
+    clock format 1018162799 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.217 {time zone boundary case 2002-04-07 03:00:00} detroit {
+    clock format 1018162800 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.218 {time zone boundary case 2002-04-07 03:00:01} detroit {
+    clock format 1018162801 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.219 {time zone boundary case 2002-10-27 01:59:59} detroit {
+    clock format 1035698399 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.220 {time zone boundary case 2002-10-27 01:00:00} detroit {
+    clock format 1035698400 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.221 {time zone boundary case 2002-10-27 01:00:01} detroit {
+    clock format 1035698401 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.222 {time zone boundary case 2003-04-06 01:59:59} detroit {
+    clock format 1049612399 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.223 {time zone boundary case 2003-04-06 03:00:00} detroit {
+    clock format 1049612400 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.224 {time zone boundary case 2003-04-06 03:00:01} detroit {
+    clock format 1049612401 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.225 {time zone boundary case 2003-10-26 01:59:59} detroit {
+    clock format 1067147999 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.226 {time zone boundary case 2003-10-26 01:00:00} detroit {
+    clock format 1067148000 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.227 {time zone boundary case 2003-10-26 01:00:01} detroit {
+    clock format 1067148001 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.228 {time zone boundary case 2004-04-04 01:59:59} detroit {
+    clock format 1081061999 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.229 {time zone boundary case 2004-04-04 03:00:00} detroit {
+    clock format 1081062000 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.230 {time zone boundary case 2004-04-04 03:00:01} detroit {
+    clock format 1081062001 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.231 {time zone boundary case 2004-10-31 01:59:59} detroit {
+    clock format 1099202399 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.232 {time zone boundary case 2004-10-31 01:00:00} detroit {
+    clock format 1099202400 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.233 {time zone boundary case 2004-10-31 01:00:01} detroit {
+    clock format 1099202401 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.234 {time zone boundary case 2005-04-03 01:59:59} detroit {
+    clock format 1112511599 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.235 {time zone boundary case 2005-04-03 03:00:00} detroit {
+    clock format 1112511600 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.236 {time zone boundary case 2005-04-03 03:00:01} detroit {
+    clock format 1112511601 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.237 {time zone boundary case 2005-10-30 01:59:59} detroit {
+    clock format 1130651999 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.238 {time zone boundary case 2005-10-30 01:00:00} detroit {
+    clock format 1130652000 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.239 {time zone boundary case 2005-10-30 01:00:01} detroit {
+    clock format 1130652001 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.240 {time zone boundary case 2006-04-02 01:59:59} detroit {
+    clock format 1143961199 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.241 {time zone boundary case 2006-04-02 03:00:00} detroit {
+    clock format 1143961200 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.242 {time zone boundary case 2006-04-02 03:00:01} detroit {
+    clock format 1143961201 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.243 {time zone boundary case 2006-10-29 01:59:59} detroit {
+    clock format 1162101599 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.244 {time zone boundary case 2006-10-29 01:00:00} detroit {
+    clock format 1162101600 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.245 {time zone boundary case 2006-10-29 01:00:01} detroit {
+    clock format 1162101601 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.246 {time zone boundary case 2007-03-11 01:59:59} detroit {
+    clock format 1173596399 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.247 {time zone boundary case 2007-03-11 03:00:00} detroit {
+    clock format 1173596400 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.248 {time zone boundary case 2007-03-11 03:00:01} detroit {
+    clock format 1173596401 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.249 {time zone boundary case 2007-11-04 01:59:59} detroit {
+    clock format 1194155999 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.250 {time zone boundary case 2007-11-04 01:00:00} detroit {
+    clock format 1194156000 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.251 {time zone boundary case 2007-11-04 01:00:01} detroit {
+    clock format 1194156001 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.252 {time zone boundary case 2008-03-09 01:59:59} detroit {
+    clock format 1205045999 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.253 {time zone boundary case 2008-03-09 03:00:00} detroit {
+    clock format 1205046000 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.254 {time zone boundary case 2008-03-09 03:00:01} detroit {
+    clock format 1205046001 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.255 {time zone boundary case 2008-11-02 01:59:59} detroit {
+    clock format 1225605599 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.256 {time zone boundary case 2008-11-02 01:00:00} detroit {
+    clock format 1225605600 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.257 {time zone boundary case 2008-11-02 01:00:01} detroit {
+    clock format 1225605601 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.258 {time zone boundary case 2009-03-08 01:59:59} detroit {
+    clock format 1236495599 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.259 {time zone boundary case 2009-03-08 03:00:00} detroit {
+    clock format 1236495600 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.260 {time zone boundary case 2009-03-08 03:00:01} detroit {
+    clock format 1236495601 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.261 {time zone boundary case 2009-11-01 01:59:59} detroit {
+    clock format 1257055199 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.262 {time zone boundary case 2009-11-01 01:00:00} detroit {
+    clock format 1257055200 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.263 {time zone boundary case 2009-11-01 01:00:01} detroit {
+    clock format 1257055201 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.264 {time zone boundary case 2010-03-14 01:59:59} detroit {
+    clock format 1268549999 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.265 {time zone boundary case 2010-03-14 03:00:00} detroit {
+    clock format 1268550000 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.266 {time zone boundary case 2010-03-14 03:00:01} detroit {
+    clock format 1268550001 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.267 {time zone boundary case 2010-11-07 01:59:59} detroit {
+    clock format 1289109599 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.268 {time zone boundary case 2010-11-07 01:00:00} detroit {
+    clock format 1289109600 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.269 {time zone boundary case 2010-11-07 01:00:01} detroit {
+    clock format 1289109601 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.270 {time zone boundary case 2011-03-13 01:59:59} detroit {
+    clock format 1299999599 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.271 {time zone boundary case 2011-03-13 03:00:00} detroit {
+    clock format 1299999600 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.272 {time zone boundary case 2011-03-13 03:00:01} detroit {
+    clock format 1299999601 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.273 {time zone boundary case 2011-11-06 01:59:59} detroit {
+    clock format 1320559199 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.274 {time zone boundary case 2011-11-06 01:00:00} detroit {
+    clock format 1320559200 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.275 {time zone boundary case 2011-11-06 01:00:01} detroit {
+    clock format 1320559201 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.276 {time zone boundary case 2012-03-11 01:59:59} detroit {
+    clock format 1331449199 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.277 {time zone boundary case 2012-03-11 03:00:00} detroit {
+    clock format 1331449200 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.278 {time zone boundary case 2012-03-11 03:00:01} detroit {
+    clock format 1331449201 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.279 {time zone boundary case 2012-11-04 01:59:59} detroit {
+    clock format 1352008799 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.280 {time zone boundary case 2012-11-04 01:00:00} detroit {
+    clock format 1352008800 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.281 {time zone boundary case 2012-11-04 01:00:01} detroit {
+    clock format 1352008801 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.282 {time zone boundary case 2013-03-10 01:59:59} detroit {
+    clock format 1362898799 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.283 {time zone boundary case 2013-03-10 03:00:00} detroit {
+    clock format 1362898800 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.284 {time zone boundary case 2013-03-10 03:00:01} detroit {
+    clock format 1362898801 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.285 {time zone boundary case 2013-11-03 01:59:59} detroit {
+    clock format 1383458399 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.286 {time zone boundary case 2013-11-03 01:00:00} detroit {
+    clock format 1383458400 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.287 {time zone boundary case 2013-11-03 01:00:01} detroit {
+    clock format 1383458401 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.288 {time zone boundary case 2014-03-09 01:59:59} detroit {
+    clock format 1394348399 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.289 {time zone boundary case 2014-03-09 03:00:00} detroit {
+    clock format 1394348400 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.290 {time zone boundary case 2014-03-09 03:00:01} detroit {
+    clock format 1394348401 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.291 {time zone boundary case 2014-11-02 01:59:59} detroit {
+    clock format 1414907999 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.292 {time zone boundary case 2014-11-02 01:00:00} detroit {
+    clock format 1414908000 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.293 {time zone boundary case 2014-11-02 01:00:01} detroit {
+    clock format 1414908001 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.294 {time zone boundary case 2015-03-08 01:59:59} detroit {
+    clock format 1425797999 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.295 {time zone boundary case 2015-03-08 03:00:00} detroit {
+    clock format 1425798000 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.296 {time zone boundary case 2015-03-08 03:00:01} detroit {
+    clock format 1425798001 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.297 {time zone boundary case 2015-11-01 01:59:59} detroit {
+    clock format 1446357599 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.298 {time zone boundary case 2015-11-01 01:00:00} detroit {
+    clock format 1446357600 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.299 {time zone boundary case 2015-11-01 01:00:01} detroit {
+    clock format 1446357601 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.300 {time zone boundary case 2016-03-13 01:59:59} detroit {
+    clock format 1457852399 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.301 {time zone boundary case 2016-03-13 03:00:00} detroit {
+    clock format 1457852400 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.302 {time zone boundary case 2016-03-13 03:00:01} detroit {
+    clock format 1457852401 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.303 {time zone boundary case 2016-11-06 01:59:59} detroit {
+    clock format 1478411999 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.304 {time zone boundary case 2016-11-06 01:00:00} detroit {
+    clock format 1478412000 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.305 {time zone boundary case 2016-11-06 01:00:01} detroit {
+    clock format 1478412001 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.306 {time zone boundary case 2017-03-12 01:59:59} detroit {
+    clock format 1489301999 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.307 {time zone boundary case 2017-03-12 03:00:00} detroit {
+    clock format 1489302000 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.308 {time zone boundary case 2017-03-12 03:00:01} detroit {
+    clock format 1489302001 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.309 {time zone boundary case 2017-11-05 01:59:59} detroit {
+    clock format 1509861599 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.310 {time zone boundary case 2017-11-05 01:00:00} detroit {
+    clock format 1509861600 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.311 {time zone boundary case 2017-11-05 01:00:01} detroit {
+    clock format 1509861601 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.312 {time zone boundary case 2018-03-11 01:59:59} detroit {
+    clock format 1520751599 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.313 {time zone boundary case 2018-03-11 03:00:00} detroit {
+    clock format 1520751600 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.314 {time zone boundary case 2018-03-11 03:00:01} detroit {
+    clock format 1520751601 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.315 {time zone boundary case 2018-11-04 01:59:59} detroit {
+    clock format 1541311199 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.316 {time zone boundary case 2018-11-04 01:00:00} detroit {
+    clock format 1541311200 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.317 {time zone boundary case 2018-11-04 01:00:01} detroit {
+    clock format 1541311201 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.318 {time zone boundary case 2019-03-10 01:59:59} detroit {
+    clock format 1552201199 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.319 {time zone boundary case 2019-03-10 03:00:00} detroit {
+    clock format 1552201200 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.320 {time zone boundary case 2019-03-10 03:00:01} detroit {
+    clock format 1552201201 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.321 {time zone boundary case 2019-11-03 01:59:59} detroit {
+    clock format 1572760799 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.322 {time zone boundary case 2019-11-03 01:00:00} detroit {
+    clock format 1572760800 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.323 {time zone boundary case 2019-11-03 01:00:01} detroit {
+    clock format 1572760801 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.324 {time zone boundary case 2020-03-08 01:59:59} detroit {
+    clock format 1583650799 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.325 {time zone boundary case 2020-03-08 03:00:00} detroit {
+    clock format 1583650800 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.326 {time zone boundary case 2020-03-08 03:00:01} detroit {
+    clock format 1583650801 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.327 {time zone boundary case 2020-11-01 01:59:59} detroit {
+    clock format 1604210399 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.328 {time zone boundary case 2020-11-01 01:00:00} detroit {
+    clock format 1604210400 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.329 {time zone boundary case 2020-11-01 01:00:01} detroit {
+    clock format 1604210401 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.330 {time zone boundary case 2021-03-14 01:59:59} detroit {
+    clock format 1615705199 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.331 {time zone boundary case 2021-03-14 03:00:00} detroit {
+    clock format 1615705200 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.332 {time zone boundary case 2021-03-14 03:00:01} detroit {
+    clock format 1615705201 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.333 {time zone boundary case 2021-11-07 01:59:59} detroit {
+    clock format 1636264799 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.334 {time zone boundary case 2021-11-07 01:00:00} detroit {
+    clock format 1636264800 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.335 {time zone boundary case 2021-11-07 01:00:01} detroit {
+    clock format 1636264801 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.336 {time zone boundary case 2022-03-13 01:59:59} detroit {
+    clock format 1647154799 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.337 {time zone boundary case 2022-03-13 03:00:00} detroit {
+    clock format 1647154800 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.338 {time zone boundary case 2022-03-13 03:00:01} detroit {
+    clock format 1647154801 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.339 {time zone boundary case 2022-11-06 01:59:59} detroit {
+    clock format 1667714399 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.340 {time zone boundary case 2022-11-06 01:00:00} detroit {
+    clock format 1667714400 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.341 {time zone boundary case 2022-11-06 01:00:01} detroit {
+    clock format 1667714401 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.342 {time zone boundary case 2023-03-12 01:59:59} detroit {
+    clock format 1678604399 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.343 {time zone boundary case 2023-03-12 03:00:00} detroit {
+    clock format 1678604400 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.344 {time zone boundary case 2023-03-12 03:00:01} detroit {
+    clock format 1678604401 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.345 {time zone boundary case 2023-11-05 01:59:59} detroit {
+    clock format 1699163999 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.346 {time zone boundary case 2023-11-05 01:00:00} detroit {
+    clock format 1699164000 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.347 {time zone boundary case 2023-11-05 01:00:01} detroit {
+    clock format 1699164001 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.348 {time zone boundary case 2024-03-10 01:59:59} detroit {
+    clock format 1710053999 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.349 {time zone boundary case 2024-03-10 03:00:00} detroit {
+    clock format 1710054000 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.350 {time zone boundary case 2024-03-10 03:00:01} detroit {
+    clock format 1710054001 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.351 {time zone boundary case 2024-11-03 01:59:59} detroit {
+    clock format 1730613599 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.352 {time zone boundary case 2024-11-03 01:00:00} detroit {
+    clock format 1730613600 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.353 {time zone boundary case 2024-11-03 01:00:01} detroit {
+    clock format 1730613601 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.354 {time zone boundary case 2025-03-09 01:59:59} detroit {
+    clock format 1741503599 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.355 {time zone boundary case 2025-03-09 03:00:00} detroit {
+    clock format 1741503600 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.356 {time zone boundary case 2025-03-09 03:00:01} detroit {
+    clock format 1741503601 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.357 {time zone boundary case 2025-11-02 01:59:59} detroit {
+    clock format 1762063199 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.358 {time zone boundary case 2025-11-02 01:00:00} detroit {
+    clock format 1762063200 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.359 {time zone boundary case 2025-11-02 01:00:01} detroit {
+    clock format 1762063201 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.360 {time zone boundary case 2026-03-08 01:59:59} detroit {
+    clock format 1772953199 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.361 {time zone boundary case 2026-03-08 03:00:00} detroit {
+    clock format 1772953200 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.362 {time zone boundary case 2026-03-08 03:00:01} detroit {
+    clock format 1772953201 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.363 {time zone boundary case 2026-11-01 01:59:59} detroit {
+    clock format 1793512799 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.364 {time zone boundary case 2026-11-01 01:00:00} detroit {
+    clock format 1793512800 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.365 {time zone boundary case 2026-11-01 01:00:01} detroit {
+    clock format 1793512801 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.366 {time zone boundary case 2027-03-14 01:59:59} detroit {
+    clock format 1805007599 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.367 {time zone boundary case 2027-03-14 03:00:00} detroit {
+    clock format 1805007600 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.368 {time zone boundary case 2027-03-14 03:00:01} detroit {
+    clock format 1805007601 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.369 {time zone boundary case 2027-11-07 01:59:59} detroit {
+    clock format 1825567199 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.370 {time zone boundary case 2027-11-07 01:00:00} detroit {
+    clock format 1825567200 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.371 {time zone boundary case 2027-11-07 01:00:01} detroit {
+    clock format 1825567201 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.372 {time zone boundary case 2028-03-12 01:59:59} detroit {
+    clock format 1836457199 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.373 {time zone boundary case 2028-03-12 03:00:00} detroit {
+    clock format 1836457200 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.374 {time zone boundary case 2028-03-12 03:00:01} detroit {
+    clock format 1836457201 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.375 {time zone boundary case 2028-11-05 01:59:59} detroit {
+    clock format 1857016799 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.376 {time zone boundary case 2028-11-05 01:00:00} detroit {
+    clock format 1857016800 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.377 {time zone boundary case 2028-11-05 01:00:01} detroit {
+    clock format 1857016801 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.378 {time zone boundary case 2029-03-11 01:59:59} detroit {
+    clock format 1867906799 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.379 {time zone boundary case 2029-03-11 03:00:00} detroit {
+    clock format 1867906800 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.380 {time zone boundary case 2029-03-11 03:00:01} detroit {
+    clock format 1867906801 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.381 {time zone boundary case 2029-11-04 01:59:59} detroit {
+    clock format 1888466399 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.382 {time zone boundary case 2029-11-04 01:00:00} detroit {
+    clock format 1888466400 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.383 {time zone boundary case 2029-11-04 01:00:01} detroit {
+    clock format 1888466401 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.384 {time zone boundary case 2030-03-10 01:59:59} detroit {
+    clock format 1899356399 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.385 {time zone boundary case 2030-03-10 03:00:00} detroit {
+    clock format 1899356400 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.386 {time zone boundary case 2030-03-10 03:00:01} detroit {
+    clock format 1899356401 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.387 {time zone boundary case 2030-11-03 01:59:59} detroit {
+    clock format 1919915999 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.388 {time zone boundary case 2030-11-03 01:00:00} detroit {
+    clock format 1919916000 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.389 {time zone boundary case 2030-11-03 01:00:01} detroit {
+    clock format 1919916001 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.390 {time zone boundary case 2031-03-09 01:59:59} detroit {
+    clock format 1930805999 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.391 {time zone boundary case 2031-03-09 03:00:00} detroit {
+    clock format 1930806000 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.392 {time zone boundary case 2031-03-09 03:00:01} detroit {
+    clock format 1930806001 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.393 {time zone boundary case 2031-11-02 01:59:59} detroit {
+    clock format 1951365599 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.394 {time zone boundary case 2031-11-02 01:00:00} detroit {
+    clock format 1951365600 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.395 {time zone boundary case 2031-11-02 01:00:01} detroit {
+    clock format 1951365601 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.396 {time zone boundary case 2032-03-14 01:59:59} detroit {
+    clock format 1962860399 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.397 {time zone boundary case 2032-03-14 03:00:00} detroit {
+    clock format 1962860400 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.398 {time zone boundary case 2032-03-14 03:00:01} detroit {
+    clock format 1962860401 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.399 {time zone boundary case 2032-11-07 01:59:59} detroit {
+    clock format 1983419999 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.400 {time zone boundary case 2032-11-07 01:00:00} detroit {
+    clock format 1983420000 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.401 {time zone boundary case 2032-11-07 01:00:01} detroit {
+    clock format 1983420001 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.402 {time zone boundary case 2033-03-13 01:59:59} detroit {
+    clock format 1994309999 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.403 {time zone boundary case 2033-03-13 03:00:00} detroit {
+    clock format 1994310000 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.404 {time zone boundary case 2033-03-13 03:00:01} detroit {
+    clock format 1994310001 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.405 {time zone boundary case 2033-11-06 01:59:59} detroit {
+    clock format 2014869599 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.406 {time zone boundary case 2033-11-06 01:00:00} detroit {
+    clock format 2014869600 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.407 {time zone boundary case 2033-11-06 01:00:01} detroit {
+    clock format 2014869601 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.408 {time zone boundary case 2034-03-12 01:59:59} detroit {
+    clock format 2025759599 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.409 {time zone boundary case 2034-03-12 03:00:00} detroit {
+    clock format 2025759600 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.410 {time zone boundary case 2034-03-12 03:00:01} detroit {
+    clock format 2025759601 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.411 {time zone boundary case 2034-11-05 01:59:59} detroit {
+    clock format 2046319199 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.412 {time zone boundary case 2034-11-05 01:00:00} detroit {
+    clock format 2046319200 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.413 {time zone boundary case 2034-11-05 01:00:01} detroit {
+    clock format 2046319201 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.414 {time zone boundary case 2035-03-11 01:59:59} detroit {
+    clock format 2057209199 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.415 {time zone boundary case 2035-03-11 03:00:00} detroit {
+    clock format 2057209200 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.416 {time zone boundary case 2035-03-11 03:00:01} detroit {
+    clock format 2057209201 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.417 {time zone boundary case 2035-11-04 01:59:59} detroit {
+    clock format 2077768799 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.418 {time zone boundary case 2035-11-04 01:00:00} detroit {
+    clock format 2077768800 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.419 {time zone boundary case 2035-11-04 01:00:01} detroit {
+    clock format 2077768801 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.420 {time zone boundary case 2036-03-09 01:59:59} detroit {
+    clock format 2088658799 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.421 {time zone boundary case 2036-03-09 03:00:00} detroit {
+    clock format 2088658800 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.422 {time zone boundary case 2036-03-09 03:00:01} detroit {
+    clock format 2088658801 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.423 {time zone boundary case 2036-11-02 01:59:59} detroit {
+    clock format 2109218399 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.424 {time zone boundary case 2036-11-02 01:00:00} detroit {
+    clock format 2109218400 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.425 {time zone boundary case 2036-11-02 01:00:01} detroit {
+    clock format 2109218401 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.426 {time zone boundary case 2037-03-08 01:59:59} detroit {
+    clock format 2120108399 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.427 {time zone boundary case 2037-03-08 03:00:00} detroit {
+    clock format 2120108400 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.428 {time zone boundary case 2037-03-08 03:00:01} detroit {
+    clock format 2120108401 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.429 {time zone boundary case 2037-11-01 01:59:59} detroit {
+    clock format 2140667999 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.430 {time zone boundary case 2037-11-01 01:00:00} detroit {
+    clock format 2140668000 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.431 {time zone boundary case 2037-11-01 01:00:01} detroit {
+    clock format 2140668001 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.432 {time zone boundary case 2038-03-14 01:59:59} {detroit y2038} {
+    clock format 2152162799 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.433 {time zone boundary case 2038-03-14 03:00:00} {detroit y2038} {
+    clock format 2152162800 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.434 {time zone boundary case 2038-03-14 03:00:01} {detroit y2038} {
+    clock format 2152162801 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.435 {time zone boundary case 2038-11-07 01:59:59} {detroit y2038} {
+    clock format 2172722399 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.436 {time zone boundary case 2038-11-07 01:00:00} {detroit y2038} {
+    clock format 2172722400 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.437 {time zone boundary case 2038-11-07 01:00:01} {detroit y2038} {
+    clock format 2172722401 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.438 {time zone boundary case 2039-03-13 01:59:59} {detroit y2038} {
+    clock format 2183612399 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.439 {time zone boundary case 2039-03-13 03:00:00} {detroit y2038} {
+    clock format 2183612400 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.440 {time zone boundary case 2039-03-13 03:00:01} {detroit y2038} {
+    clock format 2183612401 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.441 {time zone boundary case 2039-11-06 01:59:59} {detroit y2038} {
+    clock format 2204171999 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.442 {time zone boundary case 2039-11-06 01:00:00} {detroit y2038} {
+    clock format 2204172000 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.443 {time zone boundary case 2039-11-06 01:00:01} {detroit y2038} {
+    clock format 2204172001 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.444 {time zone boundary case 2040-03-11 01:59:59} {detroit y2038} {
+    clock format 2215061999 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.445 {time zone boundary case 2040-03-11 03:00:00} {detroit y2038} {
+    clock format 2215062000 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.446 {time zone boundary case 2040-03-11 03:00:01} {detroit y2038} {
+    clock format 2215062001 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.447 {time zone boundary case 2040-11-04 01:59:59} {detroit y2038} {
+    clock format 2235621599 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.448 {time zone boundary case 2040-11-04 01:00:00} {detroit y2038} {
+    clock format 2235621600 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.449 {time zone boundary case 2040-11-04 01:00:01} {detroit y2038} {
+    clock format 2235621601 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.450 {time zone boundary case 2041-03-10 01:59:59} {detroit y2038} {
+    clock format 2246511599 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.451 {time zone boundary case 2041-03-10 03:00:00} {detroit y2038} {
+    clock format 2246511600 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.452 {time zone boundary case 2041-03-10 03:00:01} {detroit y2038} {
+    clock format 2246511601 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.453 {time zone boundary case 2041-11-03 01:59:59} {detroit y2038} {
+    clock format 2267071199 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.454 {time zone boundary case 2041-11-03 01:00:00} {detroit y2038} {
+    clock format 2267071200 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.455 {time zone boundary case 2041-11-03 01:00:01} {detroit y2038} {
+    clock format 2267071201 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.456 {time zone boundary case 2042-03-09 01:59:59} {detroit y2038} {
+    clock format 2277961199 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.457 {time zone boundary case 2042-03-09 03:00:00} {detroit y2038} {
+    clock format 2277961200 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.458 {time zone boundary case 2042-03-09 03:00:01} {detroit y2038} {
+    clock format 2277961201 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.459 {time zone boundary case 2042-11-02 01:59:59} {detroit y2038} {
+    clock format 2298520799 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.460 {time zone boundary case 2042-11-02 01:00:00} {detroit y2038} {
+    clock format 2298520800 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.461 {time zone boundary case 2042-11-02 01:00:01} {detroit y2038} {
+    clock format 2298520801 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.462 {time zone boundary case 2043-03-08 01:59:59} {detroit y2038} {
+    clock format 2309410799 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.463 {time zone boundary case 2043-03-08 03:00:00} {detroit y2038} {
+    clock format 2309410800 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.464 {time zone boundary case 2043-03-08 03:00:01} {detroit y2038} {
+    clock format 2309410801 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.465 {time zone boundary case 2043-11-01 01:59:59} {detroit y2038} {
+    clock format 2329970399 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.466 {time zone boundary case 2043-11-01 01:00:00} {detroit y2038} {
+    clock format 2329970400 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.467 {time zone boundary case 2043-11-01 01:00:01} {detroit y2038} {
+    clock format 2329970401 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.468 {time zone boundary case 2044-03-13 01:59:59} {detroit y2038} {
+    clock format 2341465199 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.469 {time zone boundary case 2044-03-13 03:00:00} {detroit y2038} {
+    clock format 2341465200 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.470 {time zone boundary case 2044-03-13 03:00:01} {detroit y2038} {
+    clock format 2341465201 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.471 {time zone boundary case 2044-11-06 01:59:59} {detroit y2038} {
+    clock format 2362024799 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.472 {time zone boundary case 2044-11-06 01:00:00} {detroit y2038} {
+    clock format 2362024800 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.473 {time zone boundary case 2044-11-06 01:00:01} {detroit y2038} {
+    clock format 2362024801 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.474 {time zone boundary case 2045-03-12 01:59:59} {detroit y2038} {
+    clock format 2372914799 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.475 {time zone boundary case 2045-03-12 03:00:00} {detroit y2038} {
+    clock format 2372914800 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.476 {time zone boundary case 2045-03-12 03:00:01} {detroit y2038} {
+    clock format 2372914801 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.477 {time zone boundary case 2045-11-05 01:59:59} {detroit y2038} {
+    clock format 2393474399 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.478 {time zone boundary case 2045-11-05 01:00:00} {detroit y2038} {
+    clock format 2393474400 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.479 {time zone boundary case 2045-11-05 01:00:01} {detroit y2038} {
+    clock format 2393474401 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.480 {time zone boundary case 2046-03-11 01:59:59} {detroit y2038} {
+    clock format 2404364399 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.481 {time zone boundary case 2046-03-11 03:00:00} {detroit y2038} {
+    clock format 2404364400 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.482 {time zone boundary case 2046-03-11 03:00:01} {detroit y2038} {
+    clock format 2404364401 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.483 {time zone boundary case 2046-11-04 01:59:59} {detroit y2038} {
+    clock format 2424923999 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.484 {time zone boundary case 2046-11-04 01:00:00} {detroit y2038} {
+    clock format 2424924000 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.485 {time zone boundary case 2046-11-04 01:00:01} {detroit y2038} {
+    clock format 2424924001 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.486 {time zone boundary case 2047-03-10 01:59:59} {detroit y2038} {
+    clock format 2435813999 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.487 {time zone boundary case 2047-03-10 03:00:00} {detroit y2038} {
+    clock format 2435814000 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.488 {time zone boundary case 2047-03-10 03:00:01} {detroit y2038} {
+    clock format 2435814001 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.489 {time zone boundary case 2047-11-03 01:59:59} {detroit y2038} {
+    clock format 2456373599 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.490 {time zone boundary case 2047-11-03 01:00:00} {detroit y2038} {
+    clock format 2456373600 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.491 {time zone boundary case 2047-11-03 01:00:01} {detroit y2038} {
+    clock format 2456373601 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.492 {time zone boundary case 2048-03-08 01:59:59} {detroit y2038} {
+    clock format 2467263599 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.493 {time zone boundary case 2048-03-08 03:00:00} {detroit y2038} {
+    clock format 2467263600 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.494 {time zone boundary case 2048-03-08 03:00:01} {detroit y2038} {
+    clock format 2467263601 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.495 {time zone boundary case 2048-11-01 01:59:59} {detroit y2038} {
+    clock format 2487823199 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.496 {time zone boundary case 2048-11-01 01:00:00} {detroit y2038} {
+    clock format 2487823200 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.497 {time zone boundary case 2048-11-01 01:00:01} {detroit y2038} {
+    clock format 2487823201 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.498 {time zone boundary case 2049-03-14 01:59:59} {detroit y2038} {
+    clock format 2499317999 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.499 {time zone boundary case 2049-03-14 03:00:00} {detroit y2038} {
+    clock format 2499318000 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.500 {time zone boundary case 2049-03-14 03:00:01} {detroit y2038} {
+    clock format 2499318001 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.501 {time zone boundary case 2049-11-07 01:59:59} {detroit y2038} {
+    clock format 2519877599 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.502 {time zone boundary case 2049-11-07 01:00:00} {detroit y2038} {
+    clock format 2519877600 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.503 {time zone boundary case 2049-11-07 01:00:01} {detroit y2038} {
+    clock format 2519877601 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.504 {time zone boundary case 2050-03-13 01:59:59} {detroit y2038} {
+    clock format 2530767599 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.505 {time zone boundary case 2050-03-13 03:00:00} {detroit y2038} {
+    clock format 2530767600 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.506 {time zone boundary case 2050-03-13 03:00:01} {detroit y2038} {
+    clock format 2530767601 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.507 {time zone boundary case 2050-11-06 01:59:59} {detroit y2038} {
+    clock format 2551327199 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.508 {time zone boundary case 2050-11-06 01:00:00} {detroit y2038} {
+    clock format 2551327200 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.509 {time zone boundary case 2050-11-06 01:00:01} {detroit y2038} {
+    clock format 2551327201 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.510 {time zone boundary case 2051-03-12 01:59:59} {detroit y2038} {
+    clock format 2562217199 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.511 {time zone boundary case 2051-03-12 03:00:00} {detroit y2038} {
+    clock format 2562217200 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.512 {time zone boundary case 2051-03-12 03:00:01} {detroit y2038} {
+    clock format 2562217201 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.513 {time zone boundary case 2051-11-05 01:59:59} {detroit y2038} {
+    clock format 2582776799 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.514 {time zone boundary case 2051-11-05 01:00:00} {detroit y2038} {
+    clock format 2582776800 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.515 {time zone boundary case 2051-11-05 01:00:01} {detroit y2038} {
+    clock format 2582776801 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.516 {time zone boundary case 2052-03-10 01:59:59} {detroit y2038} {
+    clock format 2593666799 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.517 {time zone boundary case 2052-03-10 03:00:00} {detroit y2038} {
+    clock format 2593666800 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.518 {time zone boundary case 2052-03-10 03:00:01} {detroit y2038} {
+    clock format 2593666801 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.519 {time zone boundary case 2052-11-03 01:59:59} {detroit y2038} {
+    clock format 2614226399 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.520 {time zone boundary case 2052-11-03 01:00:00} {detroit y2038} {
+    clock format 2614226400 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.521 {time zone boundary case 2052-11-03 01:00:01} {detroit y2038} {
+    clock format 2614226401 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.522 {time zone boundary case 2053-03-09 01:59:59} {detroit y2038} {
+    clock format 2625116399 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.523 {time zone boundary case 2053-03-09 03:00:00} {detroit y2038} {
+    clock format 2625116400 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.524 {time zone boundary case 2053-03-09 03:00:01} {detroit y2038} {
+    clock format 2625116401 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.525 {time zone boundary case 2053-11-02 01:59:59} {detroit y2038} {
+    clock format 2645675999 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.526 {time zone boundary case 2053-11-02 01:00:00} {detroit y2038} {
+    clock format 2645676000 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.527 {time zone boundary case 2053-11-02 01:00:01} {detroit y2038} {
+    clock format 2645676001 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.528 {time zone boundary case 2054-03-08 01:59:59} {detroit y2038} {
+    clock format 2656565999 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.529 {time zone boundary case 2054-03-08 03:00:00} {detroit y2038} {
+    clock format 2656566000 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.530 {time zone boundary case 2054-03-08 03:00:01} {detroit y2038} {
+    clock format 2656566001 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.531 {time zone boundary case 2054-11-01 01:59:59} {detroit y2038} {
+    clock format 2677125599 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.532 {time zone boundary case 2054-11-01 01:00:00} {detroit y2038} {
+    clock format 2677125600 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.533 {time zone boundary case 2054-11-01 01:00:01} {detroit y2038} {
+    clock format 2677125601 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.534 {time zone boundary case 2055-03-14 01:59:59} {detroit y2038} {
+    clock format 2688620399 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.535 {time zone boundary case 2055-03-14 03:00:00} {detroit y2038} {
+    clock format 2688620400 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.536 {time zone boundary case 2055-03-14 03:00:01} {detroit y2038} {
+    clock format 2688620401 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.537 {time zone boundary case 2055-11-07 01:59:59} {detroit y2038} {
+    clock format 2709179999 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.538 {time zone boundary case 2055-11-07 01:00:00} {detroit y2038} {
+    clock format 2709180000 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.539 {time zone boundary case 2055-11-07 01:00:01} {detroit y2038} {
+    clock format 2709180001 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.540 {time zone boundary case 2056-03-12 01:59:59} {detroit y2038} {
+    clock format 2720069999 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.541 {time zone boundary case 2056-03-12 03:00:00} {detroit y2038} {
+    clock format 2720070000 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.542 {time zone boundary case 2056-03-12 03:00:01} {detroit y2038} {
+    clock format 2720070001 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.543 {time zone boundary case 2056-11-05 01:59:59} {detroit y2038} {
+    clock format 2740629599 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.544 {time zone boundary case 2056-11-05 01:00:00} {detroit y2038} {
+    clock format 2740629600 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.545 {time zone boundary case 2056-11-05 01:00:01} {detroit y2038} {
+    clock format 2740629601 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.546 {time zone boundary case 2057-03-11 01:59:59} {detroit y2038} {
+    clock format 2751519599 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.547 {time zone boundary case 2057-03-11 03:00:00} {detroit y2038} {
+    clock format 2751519600 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.548 {time zone boundary case 2057-03-11 03:00:01} {detroit y2038} {
+    clock format 2751519601 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.549 {time zone boundary case 2057-11-04 01:59:59} {detroit y2038} {
+    clock format 2772079199 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.550 {time zone boundary case 2057-11-04 01:00:00} {detroit y2038} {
+    clock format 2772079200 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.551 {time zone boundary case 2057-11-04 01:00:01} {detroit y2038} {
+    clock format 2772079201 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.552 {time zone boundary case 2058-03-10 01:59:59} {detroit y2038} {
+    clock format 2782969199 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.553 {time zone boundary case 2058-03-10 03:00:00} {detroit y2038} {
+    clock format 2782969200 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.554 {time zone boundary case 2058-03-10 03:00:01} {detroit y2038} {
+    clock format 2782969201 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.555 {time zone boundary case 2058-11-03 01:59:59} {detroit y2038} {
+    clock format 2803528799 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.556 {time zone boundary case 2058-11-03 01:00:00} {detroit y2038} {
+    clock format 2803528800 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.557 {time zone boundary case 2058-11-03 01:00:01} {detroit y2038} {
+    clock format 2803528801 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.558 {time zone boundary case 2059-03-09 01:59:59} {detroit y2038} {
+    clock format 2814418799 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.559 {time zone boundary case 2059-03-09 03:00:00} {detroit y2038} {
+    clock format 2814418800 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.560 {time zone boundary case 2059-03-09 03:00:01} {detroit y2038} {
+    clock format 2814418801 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.561 {time zone boundary case 2059-11-02 01:59:59} {detroit y2038} {
+    clock format 2834978399 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.562 {time zone boundary case 2059-11-02 01:00:00} {detroit y2038} {
+    clock format 2834978400 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.563 {time zone boundary case 2059-11-02 01:00:01} {detroit y2038} {
+    clock format 2834978401 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.564 {time zone boundary case 2060-03-14 01:59:59} {detroit y2038} {
+    clock format 2846473199 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.565 {time zone boundary case 2060-03-14 03:00:00} {detroit y2038} {
+    clock format 2846473200 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.566 {time zone boundary case 2060-03-14 03:00:01} {detroit y2038} {
+    clock format 2846473201 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.567 {time zone boundary case 2060-11-07 01:59:59} {detroit y2038} {
+    clock format 2867032799 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.568 {time zone boundary case 2060-11-07 01:00:00} {detroit y2038} {
+    clock format 2867032800 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.569 {time zone boundary case 2060-11-07 01:00:01} {detroit y2038} {
+    clock format 2867032801 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.570 {time zone boundary case 2061-03-13 01:59:59} {detroit y2038} {
+    clock format 2877922799 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.571 {time zone boundary case 2061-03-13 03:00:00} {detroit y2038} {
+    clock format 2877922800 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.572 {time zone boundary case 2061-03-13 03:00:01} {detroit y2038} {
+    clock format 2877922801 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.573 {time zone boundary case 2061-11-06 01:59:59} {detroit y2038} {
+    clock format 2898482399 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.574 {time zone boundary case 2061-11-06 01:00:00} {detroit y2038} {
+    clock format 2898482400 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.575 {time zone boundary case 2061-11-06 01:00:01} {detroit y2038} {
+    clock format 2898482401 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.576 {time zone boundary case 2062-03-12 01:59:59} {detroit y2038} {
+    clock format 2909372399 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.577 {time zone boundary case 2062-03-12 03:00:00} {detroit y2038} {
+    clock format 2909372400 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.578 {time zone boundary case 2062-03-12 03:00:01} {detroit y2038} {
+    clock format 2909372401 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.579 {time zone boundary case 2062-11-05 01:59:59} {detroit y2038} {
+    clock format 2929931999 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.580 {time zone boundary case 2062-11-05 01:00:00} {detroit y2038} {
+    clock format 2929932000 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.581 {time zone boundary case 2062-11-05 01:00:01} {detroit y2038} {
+    clock format 2929932001 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.582 {time zone boundary case 2063-03-11 01:59:59} {detroit y2038} {
+    clock format 2940821999 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.583 {time zone boundary case 2063-03-11 03:00:00} {detroit y2038} {
+    clock format 2940822000 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.584 {time zone boundary case 2063-03-11 03:00:01} {detroit y2038} {
+    clock format 2940822001 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.585 {time zone boundary case 2063-11-04 01:59:59} {detroit y2038} {
+    clock format 2961381599 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.586 {time zone boundary case 2063-11-04 01:00:00} {detroit y2038} {
+    clock format 2961381600 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.587 {time zone boundary case 2063-11-04 01:00:01} {detroit y2038} {
+    clock format 2961381601 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.588 {time zone boundary case 2064-03-09 01:59:59} {detroit y2038} {
+    clock format 2972271599 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.589 {time zone boundary case 2064-03-09 03:00:00} {detroit y2038} {
+    clock format 2972271600 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.590 {time zone boundary case 2064-03-09 03:00:01} {detroit y2038} {
+    clock format 2972271601 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.591 {time zone boundary case 2064-11-02 01:59:59} {detroit y2038} {
+    clock format 2992831199 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.592 {time zone boundary case 2064-11-02 01:00:00} {detroit y2038} {
+    clock format 2992831200 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.593 {time zone boundary case 2064-11-02 01:00:01} {detroit y2038} {
+    clock format 2992831201 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.594 {time zone boundary case 2065-03-08 01:59:59} {detroit y2038} {
+    clock format 3003721199 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.595 {time zone boundary case 2065-03-08 03:00:00} {detroit y2038} {
+    clock format 3003721200 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.596 {time zone boundary case 2065-03-08 03:00:01} {detroit y2038} {
+    clock format 3003721201 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.597 {time zone boundary case 2065-11-01 01:59:59} {detroit y2038} {
+    clock format 3024280799 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.598 {time zone boundary case 2065-11-01 01:00:00} {detroit y2038} {
+    clock format 3024280800 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.599 {time zone boundary case 2065-11-01 01:00:01} {detroit y2038} {
+    clock format 3024280801 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.600 {time zone boundary case 2066-03-14 01:59:59} {detroit y2038} {
+    clock format 3035775599 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.601 {time zone boundary case 2066-03-14 03:00:00} {detroit y2038} {
+    clock format 3035775600 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.602 {time zone boundary case 2066-03-14 03:00:01} {detroit y2038} {
+    clock format 3035775601 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.603 {time zone boundary case 2066-11-07 01:59:59} {detroit y2038} {
+    clock format 3056335199 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.604 {time zone boundary case 2066-11-07 01:00:00} {detroit y2038} {
+    clock format 3056335200 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.605 {time zone boundary case 2066-11-07 01:00:01} {detroit y2038} {
+    clock format 3056335201 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.606 {time zone boundary case 2067-03-13 01:59:59} {detroit y2038} {
+    clock format 3067225199 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.607 {time zone boundary case 2067-03-13 03:00:00} {detroit y2038} {
+    clock format 3067225200 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.608 {time zone boundary case 2067-03-13 03:00:01} {detroit y2038} {
+    clock format 3067225201 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.609 {time zone boundary case 2067-11-06 01:59:59} {detroit y2038} {
+    clock format 3087784799 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.610 {time zone boundary case 2067-11-06 01:00:00} {detroit y2038} {
+    clock format 3087784800 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.611 {time zone boundary case 2067-11-06 01:00:01} {detroit y2038} {
+    clock format 3087784801 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.612 {time zone boundary case 2068-03-11 01:59:59} {detroit y2038} {
+    clock format 3098674799 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.613 {time zone boundary case 2068-03-11 03:00:00} {detroit y2038} {
+    clock format 3098674800 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.614 {time zone boundary case 2068-03-11 03:00:01} {detroit y2038} {
+    clock format 3098674801 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.615 {time zone boundary case 2068-11-04 01:59:59} {detroit y2038} {
+    clock format 3119234399 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.616 {time zone boundary case 2068-11-04 01:00:00} {detroit y2038} {
+    clock format 3119234400 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.617 {time zone boundary case 2068-11-04 01:00:01} {detroit y2038} {
+    clock format 3119234401 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.618 {time zone boundary case 2069-03-10 01:59:59} {detroit y2038} {
+    clock format 3130124399 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.619 {time zone boundary case 2069-03-10 03:00:00} {detroit y2038} {
+    clock format 3130124400 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.620 {time zone boundary case 2069-03-10 03:00:01} {detroit y2038} {
+    clock format 3130124401 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.621 {time zone boundary case 2069-11-03 01:59:59} {detroit y2038} {
+    clock format 3150683999 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.622 {time zone boundary case 2069-11-03 01:00:00} {detroit y2038} {
+    clock format 3150684000 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.623 {time zone boundary case 2069-11-03 01:00:01} {detroit y2038} {
+    clock format 3150684001 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.624 {time zone boundary case 2070-03-09 01:59:59} {detroit y2038} {
+    clock format 3161573999 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.625 {time zone boundary case 2070-03-09 03:00:00} {detroit y2038} {
+    clock format 3161574000 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.626 {time zone boundary case 2070-03-09 03:00:01} {detroit y2038} {
+    clock format 3161574001 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.627 {time zone boundary case 2070-11-02 01:59:59} {detroit y2038} {
+    clock format 3182133599 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.628 {time zone boundary case 2070-11-02 01:00:00} {detroit y2038} {
+    clock format 3182133600 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.629 {time zone boundary case 2070-11-02 01:00:01} {detroit y2038} {
+    clock format 3182133601 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.630 {time zone boundary case 2071-03-08 01:59:59} {detroit y2038} {
+    clock format 3193023599 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.631 {time zone boundary case 2071-03-08 03:00:00} {detroit y2038} {
+    clock format 3193023600 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.632 {time zone boundary case 2071-03-08 03:00:01} {detroit y2038} {
+    clock format 3193023601 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.633 {time zone boundary case 2071-11-01 01:59:59} {detroit y2038} {
+    clock format 3213583199 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.634 {time zone boundary case 2071-11-01 01:00:00} {detroit y2038} {
+    clock format 3213583200 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.635 {time zone boundary case 2071-11-01 01:00:01} {detroit y2038} {
+    clock format 3213583201 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.636 {time zone boundary case 2072-03-13 01:59:59} {detroit y2038} {
+    clock format 3225077999 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.637 {time zone boundary case 2072-03-13 03:00:00} {detroit y2038} {
+    clock format 3225078000 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.638 {time zone boundary case 2072-03-13 03:00:01} {detroit y2038} {
+    clock format 3225078001 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.639 {time zone boundary case 2072-11-06 01:59:59} {detroit y2038} {
+    clock format 3245637599 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.640 {time zone boundary case 2072-11-06 01:00:00} {detroit y2038} {
+    clock format 3245637600 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.641 {time zone boundary case 2072-11-06 01:00:01} {detroit y2038} {
+    clock format 3245637601 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.642 {time zone boundary case 2073-03-12 01:59:59} {detroit y2038} {
+    clock format 3256527599 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.643 {time zone boundary case 2073-03-12 03:00:00} {detroit y2038} {
+    clock format 3256527600 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.644 {time zone boundary case 2073-03-12 03:00:01} {detroit y2038} {
+    clock format 3256527601 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.645 {time zone boundary case 2073-11-05 01:59:59} {detroit y2038} {
+    clock format 3277087199 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.646 {time zone boundary case 2073-11-05 01:00:00} {detroit y2038} {
+    clock format 3277087200 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.647 {time zone boundary case 2073-11-05 01:00:01} {detroit y2038} {
+    clock format 3277087201 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.648 {time zone boundary case 2074-03-11 01:59:59} {detroit y2038} {
+    clock format 3287977199 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.649 {time zone boundary case 2074-03-11 03:00:00} {detroit y2038} {
+    clock format 3287977200 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.650 {time zone boundary case 2074-03-11 03:00:01} {detroit y2038} {
+    clock format 3287977201 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.651 {time zone boundary case 2074-11-04 01:59:59} {detroit y2038} {
+    clock format 3308536799 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.652 {time zone boundary case 2074-11-04 01:00:00} {detroit y2038} {
+    clock format 3308536800 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.653 {time zone boundary case 2074-11-04 01:00:01} {detroit y2038} {
+    clock format 3308536801 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.654 {time zone boundary case 2075-03-10 01:59:59} {detroit y2038} {
+    clock format 3319426799 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.655 {time zone boundary case 2075-03-10 03:00:00} {detroit y2038} {
+    clock format 3319426800 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.656 {time zone boundary case 2075-03-10 03:00:01} {detroit y2038} {
+    clock format 3319426801 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.657 {time zone boundary case 2075-11-03 01:59:59} {detroit y2038} {
+    clock format 3339986399 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.658 {time zone boundary case 2075-11-03 01:00:00} {detroit y2038} {
+    clock format 3339986400 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.659 {time zone boundary case 2075-11-03 01:00:01} {detroit y2038} {
+    clock format 3339986401 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.660 {time zone boundary case 2076-03-08 01:59:59} {detroit y2038} {
+    clock format 3350876399 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.661 {time zone boundary case 2076-03-08 03:00:00} {detroit y2038} {
+    clock format 3350876400 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.662 {time zone boundary case 2076-03-08 03:00:01} {detroit y2038} {
+    clock format 3350876401 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.663 {time zone boundary case 2076-11-01 01:59:59} {detroit y2038} {
+    clock format 3371435999 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.664 {time zone boundary case 2076-11-01 01:00:00} {detroit y2038} {
+    clock format 3371436000 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.665 {time zone boundary case 2076-11-01 01:00:01} {detroit y2038} {
+    clock format 3371436001 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.666 {time zone boundary case 2077-03-14 01:59:59} {detroit y2038} {
+    clock format 3382930799 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.667 {time zone boundary case 2077-03-14 03:00:00} {detroit y2038} {
+    clock format 3382930800 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.668 {time zone boundary case 2077-03-14 03:00:01} {detroit y2038} {
+    clock format 3382930801 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.669 {time zone boundary case 2077-11-07 01:59:59} {detroit y2038} {
+    clock format 3403490399 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.670 {time zone boundary case 2077-11-07 01:00:00} {detroit y2038} {
+    clock format 3403490400 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.671 {time zone boundary case 2077-11-07 01:00:01} {detroit y2038} {
+    clock format 3403490401 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.672 {time zone boundary case 2078-03-13 01:59:59} {detroit y2038} {
+    clock format 3414380399 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.673 {time zone boundary case 2078-03-13 03:00:00} {detroit y2038} {
+    clock format 3414380400 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.674 {time zone boundary case 2078-03-13 03:00:01} {detroit y2038} {
+    clock format 3414380401 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.675 {time zone boundary case 2078-11-06 01:59:59} {detroit y2038} {
+    clock format 3434939999 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.676 {time zone boundary case 2078-11-06 01:00:00} {detroit y2038} {
+    clock format 3434940000 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.677 {time zone boundary case 2078-11-06 01:00:01} {detroit y2038} {
+    clock format 3434940001 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.678 {time zone boundary case 2079-03-12 01:59:59} {detroit y2038} {
+    clock format 3445829999 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.679 {time zone boundary case 2079-03-12 03:00:00} {detroit y2038} {
+    clock format 3445830000 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.680 {time zone boundary case 2079-03-12 03:00:01} {detroit y2038} {
+    clock format 3445830001 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.681 {time zone boundary case 2079-11-05 01:59:59} {detroit y2038} {
+    clock format 3466389599 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.682 {time zone boundary case 2079-11-05 01:00:00} {detroit y2038} {
+    clock format 3466389600 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.683 {time zone boundary case 2079-11-05 01:00:01} {detroit y2038} {
+    clock format 3466389601 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.684 {time zone boundary case 2080-03-10 01:59:59} {detroit y2038} {
+    clock format 3477279599 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.685 {time zone boundary case 2080-03-10 03:00:00} {detroit y2038} {
+    clock format 3477279600 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.686 {time zone boundary case 2080-03-10 03:00:01} {detroit y2038} {
+    clock format 3477279601 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.687 {time zone boundary case 2080-11-03 01:59:59} {detroit y2038} {
+    clock format 3497839199 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.688 {time zone boundary case 2080-11-03 01:00:00} {detroit y2038} {
+    clock format 3497839200 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.689 {time zone boundary case 2080-11-03 01:00:01} {detroit y2038} {
+    clock format 3497839201 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.690 {time zone boundary case 2081-03-09 01:59:59} {detroit y2038} {
+    clock format 3508729199 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.691 {time zone boundary case 2081-03-09 03:00:00} {detroit y2038} {
+    clock format 3508729200 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.692 {time zone boundary case 2081-03-09 03:00:01} {detroit y2038} {
+    clock format 3508729201 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.693 {time zone boundary case 2081-11-02 01:59:59} {detroit y2038} {
+    clock format 3529288799 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.694 {time zone boundary case 2081-11-02 01:00:00} {detroit y2038} {
+    clock format 3529288800 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.695 {time zone boundary case 2081-11-02 01:00:01} {detroit y2038} {
+    clock format 3529288801 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.696 {time zone boundary case 2082-03-08 01:59:59} {detroit y2038} {
+    clock format 3540178799 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.697 {time zone boundary case 2082-03-08 03:00:00} {detroit y2038} {
+    clock format 3540178800 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.698 {time zone boundary case 2082-03-08 03:00:01} {detroit y2038} {
+    clock format 3540178801 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.699 {time zone boundary case 2082-11-01 01:59:59} {detroit y2038} {
+    clock format 3560738399 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.700 {time zone boundary case 2082-11-01 01:00:00} {detroit y2038} {
+    clock format 3560738400 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.701 {time zone boundary case 2082-11-01 01:00:01} {detroit y2038} {
+    clock format 3560738401 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.702 {time zone boundary case 2083-03-14 01:59:59} {detroit y2038} {
+    clock format 3572233199 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.703 {time zone boundary case 2083-03-14 03:00:00} {detroit y2038} {
+    clock format 3572233200 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.704 {time zone boundary case 2083-03-14 03:00:01} {detroit y2038} {
+    clock format 3572233201 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.705 {time zone boundary case 2083-11-07 01:59:59} {detroit y2038} {
+    clock format 3592792799 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.706 {time zone boundary case 2083-11-07 01:00:00} {detroit y2038} {
+    clock format 3592792800 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.707 {time zone boundary case 2083-11-07 01:00:01} {detroit y2038} {
+    clock format 3592792801 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.708 {time zone boundary case 2084-03-12 01:59:59} {detroit y2038} {
+    clock format 3603682799 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.709 {time zone boundary case 2084-03-12 03:00:00} {detroit y2038} {
+    clock format 3603682800 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.710 {time zone boundary case 2084-03-12 03:00:01} {detroit y2038} {
+    clock format 3603682801 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.711 {time zone boundary case 2084-11-05 01:59:59} {detroit y2038} {
+    clock format 3624242399 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.712 {time zone boundary case 2084-11-05 01:00:00} {detroit y2038} {
+    clock format 3624242400 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.713 {time zone boundary case 2084-11-05 01:00:01} {detroit y2038} {
+    clock format 3624242401 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.714 {time zone boundary case 2085-03-11 01:59:59} {detroit y2038} {
+    clock format 3635132399 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.715 {time zone boundary case 2085-03-11 03:00:00} {detroit y2038} {
+    clock format 3635132400 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.716 {time zone boundary case 2085-03-11 03:00:01} {detroit y2038} {
+    clock format 3635132401 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.717 {time zone boundary case 2085-11-04 01:59:59} {detroit y2038} {
+    clock format 3655691999 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.718 {time zone boundary case 2085-11-04 01:00:00} {detroit y2038} {
+    clock format 3655692000 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.719 {time zone boundary case 2085-11-04 01:00:01} {detroit y2038} {
+    clock format 3655692001 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.720 {time zone boundary case 2086-03-10 01:59:59} {detroit y2038} {
+    clock format 3666581999 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.721 {time zone boundary case 2086-03-10 03:00:00} {detroit y2038} {
+    clock format 3666582000 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.722 {time zone boundary case 2086-03-10 03:00:01} {detroit y2038} {
+    clock format 3666582001 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.723 {time zone boundary case 2086-11-03 01:59:59} {detroit y2038} {
+    clock format 3687141599 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.724 {time zone boundary case 2086-11-03 01:00:00} {detroit y2038} {
+    clock format 3687141600 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.725 {time zone boundary case 2086-11-03 01:00:01} {detroit y2038} {
+    clock format 3687141601 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.726 {time zone boundary case 2087-03-09 01:59:59} {detroit y2038} {
+    clock format 3698031599 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.727 {time zone boundary case 2087-03-09 03:00:00} {detroit y2038} {
+    clock format 3698031600 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.728 {time zone boundary case 2087-03-09 03:00:01} {detroit y2038} {
+    clock format 3698031601 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.729 {time zone boundary case 2087-11-02 01:59:59} {detroit y2038} {
+    clock format 3718591199 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.730 {time zone boundary case 2087-11-02 01:00:00} {detroit y2038} {
+    clock format 3718591200 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.731 {time zone boundary case 2087-11-02 01:00:01} {detroit y2038} {
+    clock format 3718591201 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.732 {time zone boundary case 2088-03-14 01:59:59} {detroit y2038} {
+    clock format 3730085999 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.733 {time zone boundary case 2088-03-14 03:00:00} {detroit y2038} {
+    clock format 3730086000 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.734 {time zone boundary case 2088-03-14 03:00:01} {detroit y2038} {
+    clock format 3730086001 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.735 {time zone boundary case 2088-11-07 01:59:59} {detroit y2038} {
+    clock format 3750645599 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.736 {time zone boundary case 2088-11-07 01:00:00} {detroit y2038} {
+    clock format 3750645600 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.737 {time zone boundary case 2088-11-07 01:00:01} {detroit y2038} {
+    clock format 3750645601 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.738 {time zone boundary case 2089-03-13 01:59:59} {detroit y2038} {
+    clock format 3761535599 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.739 {time zone boundary case 2089-03-13 03:00:00} {detroit y2038} {
+    clock format 3761535600 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.740 {time zone boundary case 2089-03-13 03:00:01} {detroit y2038} {
+    clock format 3761535601 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.741 {time zone boundary case 2089-11-06 01:59:59} {detroit y2038} {
+    clock format 3782095199 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.742 {time zone boundary case 2089-11-06 01:00:00} {detroit y2038} {
+    clock format 3782095200 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.743 {time zone boundary case 2089-11-06 01:00:01} {detroit y2038} {
+    clock format 3782095201 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.744 {time zone boundary case 2090-03-12 01:59:59} {detroit y2038} {
+    clock format 3792985199 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.745 {time zone boundary case 2090-03-12 03:00:00} {detroit y2038} {
+    clock format 3792985200 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.746 {time zone boundary case 2090-03-12 03:00:01} {detroit y2038} {
+    clock format 3792985201 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.747 {time zone boundary case 2090-11-05 01:59:59} {detroit y2038} {
+    clock format 3813544799 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.748 {time zone boundary case 2090-11-05 01:00:00} {detroit y2038} {
+    clock format 3813544800 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.749 {time zone boundary case 2090-11-05 01:00:01} {detroit y2038} {
+    clock format 3813544801 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.750 {time zone boundary case 2091-03-11 01:59:59} {detroit y2038} {
+    clock format 3824434799 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.751 {time zone boundary case 2091-03-11 03:00:00} {detroit y2038} {
+    clock format 3824434800 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.752 {time zone boundary case 2091-03-11 03:00:01} {detroit y2038} {
+    clock format 3824434801 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.753 {time zone boundary case 2091-11-04 01:59:59} {detroit y2038} {
+    clock format 3844994399 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.754 {time zone boundary case 2091-11-04 01:00:00} {detroit y2038} {
+    clock format 3844994400 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.755 {time zone boundary case 2091-11-04 01:00:01} {detroit y2038} {
+    clock format 3844994401 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.756 {time zone boundary case 2092-03-09 01:59:59} {detroit y2038} {
+    clock format 3855884399 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.757 {time zone boundary case 2092-03-09 03:00:00} {detroit y2038} {
+    clock format 3855884400 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.758 {time zone boundary case 2092-03-09 03:00:01} {detroit y2038} {
+    clock format 3855884401 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.759 {time zone boundary case 2092-11-02 01:59:59} {detroit y2038} {
+    clock format 3876443999 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.760 {time zone boundary case 2092-11-02 01:00:00} {detroit y2038} {
+    clock format 3876444000 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.761 {time zone boundary case 2092-11-02 01:00:01} {detroit y2038} {
+    clock format 3876444001 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.762 {time zone boundary case 2093-03-08 01:59:59} {detroit y2038} {
+    clock format 3887333999 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.763 {time zone boundary case 2093-03-08 03:00:00} {detroit y2038} {
+    clock format 3887334000 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.764 {time zone boundary case 2093-03-08 03:00:01} {detroit y2038} {
+    clock format 3887334001 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.765 {time zone boundary case 2093-11-01 01:59:59} {detroit y2038} {
+    clock format 3907893599 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.766 {time zone boundary case 2093-11-01 01:00:00} {detroit y2038} {
+    clock format 3907893600 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.767 {time zone boundary case 2093-11-01 01:00:01} {detroit y2038} {
+    clock format 3907893601 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.768 {time zone boundary case 2094-03-14 01:59:59} {detroit y2038} {
+    clock format 3919388399 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.769 {time zone boundary case 2094-03-14 03:00:00} {detroit y2038} {
+    clock format 3919388400 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.770 {time zone boundary case 2094-03-14 03:00:01} {detroit y2038} {
+    clock format 3919388401 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.771 {time zone boundary case 2094-11-07 01:59:59} {detroit y2038} {
+    clock format 3939947999 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.772 {time zone boundary case 2094-11-07 01:00:00} {detroit y2038} {
+    clock format 3939948000 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.773 {time zone boundary case 2094-11-07 01:00:01} {detroit y2038} {
+    clock format 3939948001 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.774 {time zone boundary case 2095-03-13 01:59:59} {detroit y2038} {
+    clock format 3950837999 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.775 {time zone boundary case 2095-03-13 03:00:00} {detroit y2038} {
+    clock format 3950838000 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.776 {time zone boundary case 2095-03-13 03:00:01} {detroit y2038} {
+    clock format 3950838001 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.777 {time zone boundary case 2095-11-06 01:59:59} {detroit y2038} {
+    clock format 3971397599 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.778 {time zone boundary case 2095-11-06 01:00:00} {detroit y2038} {
+    clock format 3971397600 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.779 {time zone boundary case 2095-11-06 01:00:01} {detroit y2038} {
+    clock format 3971397601 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.780 {time zone boundary case 2096-03-11 01:59:59} {detroit y2038} {
+    clock format 3982287599 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.781 {time zone boundary case 2096-03-11 03:00:00} {detroit y2038} {
+    clock format 3982287600 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.782 {time zone boundary case 2096-03-11 03:00:01} {detroit y2038} {
+    clock format 3982287601 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.783 {time zone boundary case 2096-11-04 01:59:59} {detroit y2038} {
+    clock format 4002847199 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.784 {time zone boundary case 2096-11-04 01:00:00} {detroit y2038} {
+    clock format 4002847200 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.785 {time zone boundary case 2096-11-04 01:00:01} {detroit y2038} {
+    clock format 4002847201 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.786 {time zone boundary case 2097-03-10 01:59:59} {detroit y2038} {
+    clock format 4013737199 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.787 {time zone boundary case 2097-03-10 03:00:00} {detroit y2038} {
+    clock format 4013737200 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.788 {time zone boundary case 2097-03-10 03:00:01} {detroit y2038} {
+    clock format 4013737201 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.789 {time zone boundary case 2097-11-03 01:59:59} {detroit y2038} {
+    clock format 4034296799 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.790 {time zone boundary case 2097-11-03 01:00:00} {detroit y2038} {
+    clock format 4034296800 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.791 {time zone boundary case 2097-11-03 01:00:01} {detroit y2038} {
+    clock format 4034296801 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.792 {time zone boundary case 2098-03-09 01:59:59} {detroit y2038} {
+    clock format 4045186799 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.793 {time zone boundary case 2098-03-09 03:00:00} {detroit y2038} {
+    clock format 4045186800 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.794 {time zone boundary case 2098-03-09 03:00:01} {detroit y2038} {
+    clock format 4045186801 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.795 {time zone boundary case 2098-11-02 01:59:59} {detroit y2038} {
+    clock format 4065746399 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.796 {time zone boundary case 2098-11-02 01:00:00} {detroit y2038} {
+    clock format 4065746400 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.797 {time zone boundary case 2098-11-02 01:00:01} {detroit y2038} {
+    clock format 4065746401 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+test clock-5.798 {time zone boundary case 2099-03-08 01:59:59} {detroit y2038} {
+    clock format 4076636399 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0500 EST}
+test clock-5.799 {time zone boundary case 2099-03-08 03:00:00} {detroit y2038} {
+    clock format 4076636400 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:00 -0400 EDT}
+test clock-5.800 {time zone boundary case 2099-03-08 03:00:01} {detroit y2038} {
+    clock format 4076636401 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {03:00:01 -0400 EDT}
+test clock-5.801 {time zone boundary case 2099-11-01 01:59:59} {detroit y2038} {
+    clock format 4097195999 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:59:59 -0400 EDT}
+test clock-5.802 {time zone boundary case 2099-11-01 01:00:00} {detroit y2038} {
+    clock format 4097196000 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:00 -0500 EST}
+test clock-5.803 {time zone boundary case 2099-11-01 01:00:01} {detroit y2038} {
+    clock format 4097196001 -format {%H:%M:%S %z %Z} \
+        -timezone :America/Detroit
+} {01:00:01 -0500 EST}
+# END testcases5
+
+# Test input conversions.
+
+test clock-6.0 {input of seconds} {
+    clock scan {-9223372036854775808} -format %s -gmt true
+} -9223372036854775808
+
+test clock-6.1 {input of seconds} {
+    clock scan {-2147483649} -format %s -gmt true
+} -2147483649
+
+test clock-6.2 {input of seconds} {
+    clock scan {-2147483648} -format %s -gmt true
+} -2147483648
+
+test clock-6.3 {input of seconds} {
+    clock scan {-1} -format %s -gmt true
+} -1
+
+test clock-6.4 {input of seconds} {
+    clock scan {0} -format %s -gmt true
+} 0
+
+test clock-6.5 {input of seconds} {
+    clock scan {1} -format %s -gmt true
+} 1
+
+test clock-6.6 {input of seconds} {
+    clock scan {2147483647} -format %s -gmt true
+} 2147483647
+
+test clock-6.7 {input of seconds} {
+    clock scan {2147483648} -format %s -gmt true
+} 2147483648
+
+test clock-6.8 {input of seconds} {
+    clock scan {9223372036854775807} -format %s -gmt true
+} 9223372036854775807
+
+test clock-6.9 {input of seconds - overflow} {
+    list [catch {clock scan -9223372036854775809 -format %s -gmt true} result] $result
+} {1 {integer value too large to represent}}
+
+test clock-6.10 {input of seconds - overflow} {
+    list [catch {clock scan 9223372036854775808 -format %s -gmt true} result] $result
+} {1 {integer value too large to represent}}
+
+test clock-6.11 {input of seconds - two values} {
+    clock scan {1 2} -format {%s %s} -gmt true
+} 2
+
+test clock-7.1 {Julian Day} {
+    clock scan 0 -format %J -gmt true
+} -210866803200
+
+test clock-7.2 {Julian Day} {
+    clock format [clock scan 2440588 -format %J -gmt true] \
+	-format %Y-%m-%d -gmt true
+} 1970-01-01
+
+test clock-7.3 {Julian Day} {
+    clock format [clock scan 2451545 -format %J -gmt true] \
+	-format %Y-%m-%d -gmt true
+} 2000-01-01
+
+test clock-7.3.1 {Julian Day} {
+    clock format [clock scan 2488070 -format %J -gmt true] \
+	-format %Y-%m-%d -gmt true
+} 2100-01-01
+
+test clock-7.4 {Julian Day} {
+    clock format [clock scan 5373484 -format %J -gmt true] \
+	-format %Y-%m-%d -gmt true
+} 9999-12-31
+
+test clock-7.5 {Julian Day, bad} {
+    list [catch {
+	clock scan bogus -format %J
+    } result] $result $errorCode
+} {1 {input string does not match supplied format} {CLOCK badInputString}}
+
+test clock-7.6 {Julian Day, overflow} {
+    list [catch {
+	clock scan 5373485 -format %J
+    } result] $result $errorCode
+} {1 {requested date too large to represent} {CLOCK dateTooLarge}}
+
+test clock-7.7 {Julian Day, overflow} {
+    list [catch {
+	clock scan 2147483648 -format %J
+    } result] $result $errorCode
+} {1 {requested date too large to represent} {CLOCK dateTooLarge}}
+
+test clock-7.8 {Julian Day, precedence below seconds} {
+    list [clock scan {2440588 86400} -format {%J %s} -gmt true] \
+	[clock scan {2440589 0} -format {%J %s} -gmt true] \
+	[clock scan {86400 2440588} -format {%s %J} -gmt true] \
+	[clock scan {0 2440589} -format {%s %J} -gmt true]
+} {86400 0 86400 0}
+
+test clock-7.9 {Julian Day, two values} {
+    clock scan {2440588 2440589} -format {%J %J} -gmt true
+} 86400
+
+# BEGIN testcases8
+
+# Test parsing of ccyymmdd
+
+test clock-8.1 {parse ccyymmdd} {
+    clock scan {1970 Jan 02} -format {%C%y %b %d} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.2 {parse ccyymmdd} {
+    clock scan {1970 Jan ii} -format {%C%y %b %Od} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.3 {parse ccyymmdd} {
+    clock scan {1970 Jan  2} -format {%C%y %b %e} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.4 {parse ccyymmdd} {
+    clock scan {1970 Jan ii} -format {%C%y %b %Oe} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.5 {parse ccyymmdd} {
+    clock scan {1970 January 02} -format {%C%y %B %d} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.6 {parse ccyymmdd} {
+    clock scan {1970 January ii} -format {%C%y %B %Od} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.7 {parse ccyymmdd} {
+    clock scan {1970 January  2} -format {%C%y %B %e} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.8 {parse ccyymmdd} {
+    clock scan {1970 January ii} -format {%C%y %B %Oe} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.9 {parse ccyymmdd} {
+    clock scan {1970 Jan 02} -format {%C%y %h %d} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.10 {parse ccyymmdd} {
+    clock scan {1970 Jan ii} -format {%C%y %h %Od} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.11 {parse ccyymmdd} {
+    clock scan {1970 Jan  2} -format {%C%y %h %e} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.12 {parse ccyymmdd} {
+    clock scan {1970 Jan ii} -format {%C%y %h %Oe} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.13 {parse ccyymmdd} {
+    clock scan {1970 01 02} -format {%C%y %m %d} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.14 {parse ccyymmdd} {
+    clock scan {1970 01 ii} -format {%C%y %m %Od} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.15 {parse ccyymmdd} {
+    clock scan {1970 01  2} -format {%C%y %m %e} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.16 {parse ccyymmdd} {
+    clock scan {1970 01 ii} -format {%C%y %m %Oe} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.17 {parse ccyymmdd} {
+    clock scan {1970 i 02} -format {%C%y %Om %d} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.18 {parse ccyymmdd} {
+    clock scan {1970 i ii} -format {%C%y %Om %Od} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.19 {parse ccyymmdd} {
+    clock scan {1970 i  2} -format {%C%y %Om %e} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.20 {parse ccyymmdd} {
+    clock scan {1970 i ii} -format {%C%y %Om %Oe} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.21 {parse ccyymmdd} {
+    clock scan {1970  1 02} -format {%C%y %N %d} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.22 {parse ccyymmdd} {
+    clock scan {1970  1 ii} -format {%C%y %N %Od} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.23 {parse ccyymmdd} {
+    clock scan {1970  1  2} -format {%C%y %N %e} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.24 {parse ccyymmdd} {
+    clock scan {1970  1 ii} -format {%C%y %N %Oe} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.25 {parse ccyymmdd} {
+    clock scan {1970 Jan 02} -format {%Y %b %d} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.26 {parse ccyymmdd} {
+    clock scan {1970 Jan ii} -format {%Y %b %Od} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.27 {parse ccyymmdd} {
+    clock scan {1970 Jan  2} -format {%Y %b %e} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.28 {parse ccyymmdd} {
+    clock scan {1970 Jan ii} -format {%Y %b %Oe} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.29 {parse ccyymmdd} {
+    clock scan {1970 January 02} -format {%Y %B %d} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.30 {parse ccyymmdd} {
+    clock scan {1970 January ii} -format {%Y %B %Od} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.31 {parse ccyymmdd} {
+    clock scan {1970 January  2} -format {%Y %B %e} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.32 {parse ccyymmdd} {
+    clock scan {1970 January ii} -format {%Y %B %Oe} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.33 {parse ccyymmdd} {
+    clock scan {1970 Jan 02} -format {%Y %h %d} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.34 {parse ccyymmdd} {
+    clock scan {1970 Jan ii} -format {%Y %h %Od} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.35 {parse ccyymmdd} {
+    clock scan {1970 Jan  2} -format {%Y %h %e} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.36 {parse ccyymmdd} {
+    clock scan {1970 Jan ii} -format {%Y %h %Oe} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.37 {parse ccyymmdd} {
+    clock scan {1970 01 02} -format {%Y %m %d} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.38 {parse ccyymmdd} {
+    clock scan {1970 01 ii} -format {%Y %m %Od} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.39 {parse ccyymmdd} {
+    clock scan {1970 01  2} -format {%Y %m %e} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.40 {parse ccyymmdd} {
+    clock scan {1970 01 ii} -format {%Y %m %Oe} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.41 {parse ccyymmdd} {
+    clock scan {1970 i 02} -format {%Y %Om %d} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.42 {parse ccyymmdd} {
+    clock scan {1970 i ii} -format {%Y %Om %Od} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.43 {parse ccyymmdd} {
+    clock scan {1970 i  2} -format {%Y %Om %e} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.44 {parse ccyymmdd} {
+    clock scan {1970 i ii} -format {%Y %Om %Oe} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.45 {parse ccyymmdd} {
+    clock scan {1970  1 02} -format {%Y %N %d} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.46 {parse ccyymmdd} {
+    clock scan {1970  1 ii} -format {%Y %N %Od} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.47 {parse ccyymmdd} {
+    clock scan {1970  1  2} -format {%Y %N %e} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.48 {parse ccyymmdd} {
+    clock scan {1970  1 ii} -format {%Y %N %Oe} -locale en_US_roman -gmt 1
+} 86400
+test clock-8.49 {parse ccyymmdd} {
+    clock scan 01/02/1970 -format %x -locale en_US_roman -gmt 1
+} 86400
+test clock-8.50 {parse ccyymmdd} {
+    clock scan 01/02/1970 -format %D -locale en_US_roman -gmt 1
+} 86400
+test clock-8.51 {parse ccyymmdd} {
+    clock scan {1970 Jan 31} -format {%C%y %b %d} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.52 {parse ccyymmdd} {
+    clock scan {1970 Jan xxxi} -format {%C%y %b %Od} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.53 {parse ccyymmdd} {
+    clock scan {1970 Jan 31} -format {%C%y %b %e} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.54 {parse ccyymmdd} {
+    clock scan {1970 Jan xxxi} -format {%C%y %b %Oe} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.55 {parse ccyymmdd} {
+    clock scan {1970 January 31} -format {%C%y %B %d} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.56 {parse ccyymmdd} {
+    clock scan {1970 January xxxi} -format {%C%y %B %Od} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.57 {parse ccyymmdd} {
+    clock scan {1970 January 31} -format {%C%y %B %e} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.58 {parse ccyymmdd} {
+    clock scan {1970 January xxxi} -format {%C%y %B %Oe} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.59 {parse ccyymmdd} {
+    clock scan {1970 Jan 31} -format {%C%y %h %d} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.60 {parse ccyymmdd} {
+    clock scan {1970 Jan xxxi} -format {%C%y %h %Od} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.61 {parse ccyymmdd} {
+    clock scan {1970 Jan 31} -format {%C%y %h %e} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.62 {parse ccyymmdd} {
+    clock scan {1970 Jan xxxi} -format {%C%y %h %Oe} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.63 {parse ccyymmdd} {
+    clock scan {1970 01 31} -format {%C%y %m %d} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.64 {parse ccyymmdd} {
+    clock scan {1970 01 xxxi} -format {%C%y %m %Od} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.65 {parse ccyymmdd} {
+    clock scan {1970 01 31} -format {%C%y %m %e} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.66 {parse ccyymmdd} {
+    clock scan {1970 01 xxxi} -format {%C%y %m %Oe} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.67 {parse ccyymmdd} {
+    clock scan {1970 i 31} -format {%C%y %Om %d} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.68 {parse ccyymmdd} {
+    clock scan {1970 i xxxi} -format {%C%y %Om %Od} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.69 {parse ccyymmdd} {
+    clock scan {1970 i 31} -format {%C%y %Om %e} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.70 {parse ccyymmdd} {
+    clock scan {1970 i xxxi} -format {%C%y %Om %Oe} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.71 {parse ccyymmdd} {
+    clock scan {1970  1 31} -format {%C%y %N %d} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.72 {parse ccyymmdd} {
+    clock scan {1970  1 xxxi} -format {%C%y %N %Od} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.73 {parse ccyymmdd} {
+    clock scan {1970  1 31} -format {%C%y %N %e} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.74 {parse ccyymmdd} {
+    clock scan {1970  1 xxxi} -format {%C%y %N %Oe} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.75 {parse ccyymmdd} {
+    clock scan {1970 Jan 31} -format {%Y %b %d} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.76 {parse ccyymmdd} {
+    clock scan {1970 Jan xxxi} -format {%Y %b %Od} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.77 {parse ccyymmdd} {
+    clock scan {1970 Jan 31} -format {%Y %b %e} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.78 {parse ccyymmdd} {
+    clock scan {1970 Jan xxxi} -format {%Y %b %Oe} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.79 {parse ccyymmdd} {
+    clock scan {1970 January 31} -format {%Y %B %d} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.80 {parse ccyymmdd} {
+    clock scan {1970 January xxxi} -format {%Y %B %Od} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.81 {parse ccyymmdd} {
+    clock scan {1970 January 31} -format {%Y %B %e} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.82 {parse ccyymmdd} {
+    clock scan {1970 January xxxi} -format {%Y %B %Oe} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.83 {parse ccyymmdd} {
+    clock scan {1970 Jan 31} -format {%Y %h %d} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.84 {parse ccyymmdd} {
+    clock scan {1970 Jan xxxi} -format {%Y %h %Od} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.85 {parse ccyymmdd} {
+    clock scan {1970 Jan 31} -format {%Y %h %e} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.86 {parse ccyymmdd} {
+    clock scan {1970 Jan xxxi} -format {%Y %h %Oe} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.87 {parse ccyymmdd} {
+    clock scan {1970 01 31} -format {%Y %m %d} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.88 {parse ccyymmdd} {
+    clock scan {1970 01 xxxi} -format {%Y %m %Od} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.89 {parse ccyymmdd} {
+    clock scan {1970 01 31} -format {%Y %m %e} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.90 {parse ccyymmdd} {
+    clock scan {1970 01 xxxi} -format {%Y %m %Oe} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.91 {parse ccyymmdd} {
+    clock scan {1970 i 31} -format {%Y %Om %d} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.92 {parse ccyymmdd} {
+    clock scan {1970 i xxxi} -format {%Y %Om %Od} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.93 {parse ccyymmdd} {
+    clock scan {1970 i 31} -format {%Y %Om %e} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.94 {parse ccyymmdd} {
+    clock scan {1970 i xxxi} -format {%Y %Om %Oe} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.95 {parse ccyymmdd} {
+    clock scan {1970  1 31} -format {%Y %N %d} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.96 {parse ccyymmdd} {
+    clock scan {1970  1 xxxi} -format {%Y %N %Od} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.97 {parse ccyymmdd} {
+    clock scan {1970  1 31} -format {%Y %N %e} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.98 {parse ccyymmdd} {
+    clock scan {1970  1 xxxi} -format {%Y %N %Oe} -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.99 {parse ccyymmdd} {
+    clock scan 01/31/1970 -format %x -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.100 {parse ccyymmdd} {
+    clock scan 01/31/1970 -format %D -locale en_US_roman -gmt 1
+} 2592000
+test clock-8.101 {parse ccyymmdd} {
+    clock scan {1970 Dec 02} -format {%C%y %b %d} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.102 {parse ccyymmdd} {
+    clock scan {1970 Dec ii} -format {%C%y %b %Od} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.103 {parse ccyymmdd} {
+    clock scan {1970 Dec  2} -format {%C%y %b %e} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.104 {parse ccyymmdd} {
+    clock scan {1970 Dec ii} -format {%C%y %b %Oe} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.105 {parse ccyymmdd} {
+    clock scan {1970 December 02} -format {%C%y %B %d} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.106 {parse ccyymmdd} {
+    clock scan {1970 December ii} -format {%C%y %B %Od} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.107 {parse ccyymmdd} {
+    clock scan {1970 December  2} -format {%C%y %B %e} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.108 {parse ccyymmdd} {
+    clock scan {1970 December ii} -format {%C%y %B %Oe} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.109 {parse ccyymmdd} {
+    clock scan {1970 Dec 02} -format {%C%y %h %d} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.110 {parse ccyymmdd} {
+    clock scan {1970 Dec ii} -format {%C%y %h %Od} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.111 {parse ccyymmdd} {
+    clock scan {1970 Dec  2} -format {%C%y %h %e} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.112 {parse ccyymmdd} {
+    clock scan {1970 Dec ii} -format {%C%y %h %Oe} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.113 {parse ccyymmdd} {
+    clock scan {1970 12 02} -format {%C%y %m %d} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.114 {parse ccyymmdd} {
+    clock scan {1970 12 ii} -format {%C%y %m %Od} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.115 {parse ccyymmdd} {
+    clock scan {1970 12  2} -format {%C%y %m %e} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.116 {parse ccyymmdd} {
+    clock scan {1970 12 ii} -format {%C%y %m %Oe} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.117 {parse ccyymmdd} {
+    clock scan {1970 xii 02} -format {%C%y %Om %d} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.118 {parse ccyymmdd} {
+    clock scan {1970 xii ii} -format {%C%y %Om %Od} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.119 {parse ccyymmdd} {
+    clock scan {1970 xii  2} -format {%C%y %Om %e} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.120 {parse ccyymmdd} {
+    clock scan {1970 xii ii} -format {%C%y %Om %Oe} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.121 {parse ccyymmdd} {
+    clock scan {1970 12 02} -format {%C%y %N %d} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.122 {parse ccyymmdd} {
+    clock scan {1970 12 ii} -format {%C%y %N %Od} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.123 {parse ccyymmdd} {
+    clock scan {1970 12  2} -format {%C%y %N %e} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.124 {parse ccyymmdd} {
+    clock scan {1970 12 ii} -format {%C%y %N %Oe} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.125 {parse ccyymmdd} {
+    clock scan {1970 Dec 02} -format {%Y %b %d} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.126 {parse ccyymmdd} {
+    clock scan {1970 Dec ii} -format {%Y %b %Od} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.127 {parse ccyymmdd} {
+    clock scan {1970 Dec  2} -format {%Y %b %e} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.128 {parse ccyymmdd} {
+    clock scan {1970 Dec ii} -format {%Y %b %Oe} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.129 {parse ccyymmdd} {
+    clock scan {1970 December 02} -format {%Y %B %d} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.130 {parse ccyymmdd} {
+    clock scan {1970 December ii} -format {%Y %B %Od} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.131 {parse ccyymmdd} {
+    clock scan {1970 December  2} -format {%Y %B %e} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.132 {parse ccyymmdd} {
+    clock scan {1970 December ii} -format {%Y %B %Oe} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.133 {parse ccyymmdd} {
+    clock scan {1970 Dec 02} -format {%Y %h %d} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.134 {parse ccyymmdd} {
+    clock scan {1970 Dec ii} -format {%Y %h %Od} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.135 {parse ccyymmdd} {
+    clock scan {1970 Dec  2} -format {%Y %h %e} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.136 {parse ccyymmdd} {
+    clock scan {1970 Dec ii} -format {%Y %h %Oe} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.137 {parse ccyymmdd} {
+    clock scan {1970 12 02} -format {%Y %m %d} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.138 {parse ccyymmdd} {
+    clock scan {1970 12 ii} -format {%Y %m %Od} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.139 {parse ccyymmdd} {
+    clock scan {1970 12  2} -format {%Y %m %e} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.140 {parse ccyymmdd} {
+    clock scan {1970 12 ii} -format {%Y %m %Oe} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.141 {parse ccyymmdd} {
+    clock scan {1970 xii 02} -format {%Y %Om %d} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.142 {parse ccyymmdd} {
+    clock scan {1970 xii ii} -format {%Y %Om %Od} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.143 {parse ccyymmdd} {
+    clock scan {1970 xii  2} -format {%Y %Om %e} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.144 {parse ccyymmdd} {
+    clock scan {1970 xii ii} -format {%Y %Om %Oe} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.145 {parse ccyymmdd} {
+    clock scan {1970 12 02} -format {%Y %N %d} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.146 {parse ccyymmdd} {
+    clock scan {1970 12 ii} -format {%Y %N %Od} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.147 {parse ccyymmdd} {
+    clock scan {1970 12  2} -format {%Y %N %e} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.148 {parse ccyymmdd} {
+    clock scan {1970 12 ii} -format {%Y %N %Oe} -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.149 {parse ccyymmdd} {
+    clock scan 12/02/1970 -format %x -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.150 {parse ccyymmdd} {
+    clock scan 12/02/1970 -format %D -locale en_US_roman -gmt 1
+} 28944000
+test clock-8.151 {parse ccyymmdd} {
+    clock scan {1970 Dec 31} -format {%C%y %b %d} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.152 {parse ccyymmdd} {
+    clock scan {1970 Dec xxxi} -format {%C%y %b %Od} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.153 {parse ccyymmdd} {
+    clock scan {1970 Dec 31} -format {%C%y %b %e} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.154 {parse ccyymmdd} {
+    clock scan {1970 Dec xxxi} -format {%C%y %b %Oe} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.155 {parse ccyymmdd} {
+    clock scan {1970 December 31} -format {%C%y %B %d} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.156 {parse ccyymmdd} {
+    clock scan {1970 December xxxi} -format {%C%y %B %Od} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.157 {parse ccyymmdd} {
+    clock scan {1970 December 31} -format {%C%y %B %e} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.158 {parse ccyymmdd} {
+    clock scan {1970 December xxxi} -format {%C%y %B %Oe} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.159 {parse ccyymmdd} {
+    clock scan {1970 Dec 31} -format {%C%y %h %d} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.160 {parse ccyymmdd} {
+    clock scan {1970 Dec xxxi} -format {%C%y %h %Od} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.161 {parse ccyymmdd} {
+    clock scan {1970 Dec 31} -format {%C%y %h %e} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.162 {parse ccyymmdd} {
+    clock scan {1970 Dec xxxi} -format {%C%y %h %Oe} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.163 {parse ccyymmdd} {
+    clock scan {1970 12 31} -format {%C%y %m %d} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.164 {parse ccyymmdd} {
+    clock scan {1970 12 xxxi} -format {%C%y %m %Od} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.165 {parse ccyymmdd} {
+    clock scan {1970 12 31} -format {%C%y %m %e} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.166 {parse ccyymmdd} {
+    clock scan {1970 12 xxxi} -format {%C%y %m %Oe} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.167 {parse ccyymmdd} {
+    clock scan {1970 xii 31} -format {%C%y %Om %d} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.168 {parse ccyymmdd} {
+    clock scan {1970 xii xxxi} -format {%C%y %Om %Od} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.169 {parse ccyymmdd} {
+    clock scan {1970 xii 31} -format {%C%y %Om %e} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.170 {parse ccyymmdd} {
+    clock scan {1970 xii xxxi} -format {%C%y %Om %Oe} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.171 {parse ccyymmdd} {
+    clock scan {1970 12 31} -format {%C%y %N %d} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.172 {parse ccyymmdd} {
+    clock scan {1970 12 xxxi} -format {%C%y %N %Od} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.173 {parse ccyymmdd} {
+    clock scan {1970 12 31} -format {%C%y %N %e} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.174 {parse ccyymmdd} {
+    clock scan {1970 12 xxxi} -format {%C%y %N %Oe} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.175 {parse ccyymmdd} {
+    clock scan {1970 Dec 31} -format {%Y %b %d} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.176 {parse ccyymmdd} {
+    clock scan {1970 Dec xxxi} -format {%Y %b %Od} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.177 {parse ccyymmdd} {
+    clock scan {1970 Dec 31} -format {%Y %b %e} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.178 {parse ccyymmdd} {
+    clock scan {1970 Dec xxxi} -format {%Y %b %Oe} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.179 {parse ccyymmdd} {
+    clock scan {1970 December 31} -format {%Y %B %d} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.180 {parse ccyymmdd} {
+    clock scan {1970 December xxxi} -format {%Y %B %Od} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.181 {parse ccyymmdd} {
+    clock scan {1970 December 31} -format {%Y %B %e} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.182 {parse ccyymmdd} {
+    clock scan {1970 December xxxi} -format {%Y %B %Oe} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.183 {parse ccyymmdd} {
+    clock scan {1970 Dec 31} -format {%Y %h %d} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.184 {parse ccyymmdd} {
+    clock scan {1970 Dec xxxi} -format {%Y %h %Od} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.185 {parse ccyymmdd} {
+    clock scan {1970 Dec 31} -format {%Y %h %e} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.186 {parse ccyymmdd} {
+    clock scan {1970 Dec xxxi} -format {%Y %h %Oe} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.187 {parse ccyymmdd} {
+    clock scan {1970 12 31} -format {%Y %m %d} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.188 {parse ccyymmdd} {
+    clock scan {1970 12 xxxi} -format {%Y %m %Od} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.189 {parse ccyymmdd} {
+    clock scan {1970 12 31} -format {%Y %m %e} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.190 {parse ccyymmdd} {
+    clock scan {1970 12 xxxi} -format {%Y %m %Oe} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.191 {parse ccyymmdd} {
+    clock scan {1970 xii 31} -format {%Y %Om %d} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.192 {parse ccyymmdd} {
+    clock scan {1970 xii xxxi} -format {%Y %Om %Od} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.193 {parse ccyymmdd} {
+    clock scan {1970 xii 31} -format {%Y %Om %e} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.194 {parse ccyymmdd} {
+    clock scan {1970 xii xxxi} -format {%Y %Om %Oe} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.195 {parse ccyymmdd} {
+    clock scan {1970 12 31} -format {%Y %N %d} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.196 {parse ccyymmdd} {
+    clock scan {1970 12 xxxi} -format {%Y %N %Od} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.197 {parse ccyymmdd} {
+    clock scan {1970 12 31} -format {%Y %N %e} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.198 {parse ccyymmdd} {
+    clock scan {1970 12 xxxi} -format {%Y %N %Oe} -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.199 {parse ccyymmdd} {
+    clock scan 12/31/1970 -format %x -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.200 {parse ccyymmdd} {
+    clock scan 12/31/1970 -format %D -locale en_US_roman -gmt 1
+} 31449600
+test clock-8.201 {parse ccyymmdd} {
+    clock scan {1971 Jan 02} -format {%C%y %b %d} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.202 {parse ccyymmdd} {
+    clock scan {1971 Jan ii} -format {%C%y %b %Od} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.203 {parse ccyymmdd} {
+    clock scan {1971 Jan  2} -format {%C%y %b %e} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.204 {parse ccyymmdd} {
+    clock scan {1971 Jan ii} -format {%C%y %b %Oe} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.205 {parse ccyymmdd} {
+    clock scan {1971 January 02} -format {%C%y %B %d} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.206 {parse ccyymmdd} {
+    clock scan {1971 January ii} -format {%C%y %B %Od} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.207 {parse ccyymmdd} {
+    clock scan {1971 January  2} -format {%C%y %B %e} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.208 {parse ccyymmdd} {
+    clock scan {1971 January ii} -format {%C%y %B %Oe} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.209 {parse ccyymmdd} {
+    clock scan {1971 Jan 02} -format {%C%y %h %d} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.210 {parse ccyymmdd} {
+    clock scan {1971 Jan ii} -format {%C%y %h %Od} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.211 {parse ccyymmdd} {
+    clock scan {1971 Jan  2} -format {%C%y %h %e} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.212 {parse ccyymmdd} {
+    clock scan {1971 Jan ii} -format {%C%y %h %Oe} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.213 {parse ccyymmdd} {
+    clock scan {1971 01 02} -format {%C%y %m %d} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.214 {parse ccyymmdd} {
+    clock scan {1971 01 ii} -format {%C%y %m %Od} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.215 {parse ccyymmdd} {
+    clock scan {1971 01  2} -format {%C%y %m %e} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.216 {parse ccyymmdd} {
+    clock scan {1971 01 ii} -format {%C%y %m %Oe} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.217 {parse ccyymmdd} {
+    clock scan {1971 i 02} -format {%C%y %Om %d} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.218 {parse ccyymmdd} {
+    clock scan {1971 i ii} -format {%C%y %Om %Od} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.219 {parse ccyymmdd} {
+    clock scan {1971 i  2} -format {%C%y %Om %e} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.220 {parse ccyymmdd} {
+    clock scan {1971 i ii} -format {%C%y %Om %Oe} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.221 {parse ccyymmdd} {
+    clock scan {1971  1 02} -format {%C%y %N %d} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.222 {parse ccyymmdd} {
+    clock scan {1971  1 ii} -format {%C%y %N %Od} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.223 {parse ccyymmdd} {
+    clock scan {1971  1  2} -format {%C%y %N %e} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.224 {parse ccyymmdd} {
+    clock scan {1971  1 ii} -format {%C%y %N %Oe} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.225 {parse ccyymmdd} {
+    clock scan {1971 Jan 02} -format {%Y %b %d} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.226 {parse ccyymmdd} {
+    clock scan {1971 Jan ii} -format {%Y %b %Od} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.227 {parse ccyymmdd} {
+    clock scan {1971 Jan  2} -format {%Y %b %e} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.228 {parse ccyymmdd} {
+    clock scan {1971 Jan ii} -format {%Y %b %Oe} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.229 {parse ccyymmdd} {
+    clock scan {1971 January 02} -format {%Y %B %d} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.230 {parse ccyymmdd} {
+    clock scan {1971 January ii} -format {%Y %B %Od} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.231 {parse ccyymmdd} {
+    clock scan {1971 January  2} -format {%Y %B %e} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.232 {parse ccyymmdd} {
+    clock scan {1971 January ii} -format {%Y %B %Oe} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.233 {parse ccyymmdd} {
+    clock scan {1971 Jan 02} -format {%Y %h %d} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.234 {parse ccyymmdd} {
+    clock scan {1971 Jan ii} -format {%Y %h %Od} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.235 {parse ccyymmdd} {
+    clock scan {1971 Jan  2} -format {%Y %h %e} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.236 {parse ccyymmdd} {
+    clock scan {1971 Jan ii} -format {%Y %h %Oe} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.237 {parse ccyymmdd} {
+    clock scan {1971 01 02} -format {%Y %m %d} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.238 {parse ccyymmdd} {
+    clock scan {1971 01 ii} -format {%Y %m %Od} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.239 {parse ccyymmdd} {
+    clock scan {1971 01  2} -format {%Y %m %e} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.240 {parse ccyymmdd} {
+    clock scan {1971 01 ii} -format {%Y %m %Oe} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.241 {parse ccyymmdd} {
+    clock scan {1971 i 02} -format {%Y %Om %d} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.242 {parse ccyymmdd} {
+    clock scan {1971 i ii} -format {%Y %Om %Od} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.243 {parse ccyymmdd} {
+    clock scan {1971 i  2} -format {%Y %Om %e} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.244 {parse ccyymmdd} {
+    clock scan {1971 i ii} -format {%Y %Om %Oe} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.245 {parse ccyymmdd} {
+    clock scan {1971  1 02} -format {%Y %N %d} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.246 {parse ccyymmdd} {
+    clock scan {1971  1 ii} -format {%Y %N %Od} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.247 {parse ccyymmdd} {
+    clock scan {1971  1  2} -format {%Y %N %e} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.248 {parse ccyymmdd} {
+    clock scan {1971  1 ii} -format {%Y %N %Oe} -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.249 {parse ccyymmdd} {
+    clock scan 01/02/1971 -format %x -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.250 {parse ccyymmdd} {
+    clock scan 01/02/1971 -format %D -locale en_US_roman -gmt 1
+} 31622400
+test clock-8.251 {parse ccyymmdd} {
+    clock scan {1971 Jan 31} -format {%C%y %b %d} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.252 {parse ccyymmdd} {
+    clock scan {1971 Jan xxxi} -format {%C%y %b %Od} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.253 {parse ccyymmdd} {
+    clock scan {1971 Jan 31} -format {%C%y %b %e} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.254 {parse ccyymmdd} {
+    clock scan {1971 Jan xxxi} -format {%C%y %b %Oe} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.255 {parse ccyymmdd} {
+    clock scan {1971 January 31} -format {%C%y %B %d} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.256 {parse ccyymmdd} {
+    clock scan {1971 January xxxi} -format {%C%y %B %Od} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.257 {parse ccyymmdd} {
+    clock scan {1971 January 31} -format {%C%y %B %e} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.258 {parse ccyymmdd} {
+    clock scan {1971 January xxxi} -format {%C%y %B %Oe} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.259 {parse ccyymmdd} {
+    clock scan {1971 Jan 31} -format {%C%y %h %d} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.260 {parse ccyymmdd} {
+    clock scan {1971 Jan xxxi} -format {%C%y %h %Od} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.261 {parse ccyymmdd} {
+    clock scan {1971 Jan 31} -format {%C%y %h %e} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.262 {parse ccyymmdd} {
+    clock scan {1971 Jan xxxi} -format {%C%y %h %Oe} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.263 {parse ccyymmdd} {
+    clock scan {1971 01 31} -format {%C%y %m %d} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.264 {parse ccyymmdd} {
+    clock scan {1971 01 xxxi} -format {%C%y %m %Od} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.265 {parse ccyymmdd} {
+    clock scan {1971 01 31} -format {%C%y %m %e} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.266 {parse ccyymmdd} {
+    clock scan {1971 01 xxxi} -format {%C%y %m %Oe} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.267 {parse ccyymmdd} {
+    clock scan {1971 i 31} -format {%C%y %Om %d} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.268 {parse ccyymmdd} {
+    clock scan {1971 i xxxi} -format {%C%y %Om %Od} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.269 {parse ccyymmdd} {
+    clock scan {1971 i 31} -format {%C%y %Om %e} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.270 {parse ccyymmdd} {
+    clock scan {1971 i xxxi} -format {%C%y %Om %Oe} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.271 {parse ccyymmdd} {
+    clock scan {1971  1 31} -format {%C%y %N %d} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.272 {parse ccyymmdd} {
+    clock scan {1971  1 xxxi} -format {%C%y %N %Od} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.273 {parse ccyymmdd} {
+    clock scan {1971  1 31} -format {%C%y %N %e} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.274 {parse ccyymmdd} {
+    clock scan {1971  1 xxxi} -format {%C%y %N %Oe} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.275 {parse ccyymmdd} {
+    clock scan {1971 Jan 31} -format {%Y %b %d} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.276 {parse ccyymmdd} {
+    clock scan {1971 Jan xxxi} -format {%Y %b %Od} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.277 {parse ccyymmdd} {
+    clock scan {1971 Jan 31} -format {%Y %b %e} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.278 {parse ccyymmdd} {
+    clock scan {1971 Jan xxxi} -format {%Y %b %Oe} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.279 {parse ccyymmdd} {
+    clock scan {1971 January 31} -format {%Y %B %d} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.280 {parse ccyymmdd} {
+    clock scan {1971 January xxxi} -format {%Y %B %Od} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.281 {parse ccyymmdd} {
+    clock scan {1971 January 31} -format {%Y %B %e} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.282 {parse ccyymmdd} {
+    clock scan {1971 January xxxi} -format {%Y %B %Oe} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.283 {parse ccyymmdd} {
+    clock scan {1971 Jan 31} -format {%Y %h %d} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.284 {parse ccyymmdd} {
+    clock scan {1971 Jan xxxi} -format {%Y %h %Od} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.285 {parse ccyymmdd} {
+    clock scan {1971 Jan 31} -format {%Y %h %e} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.286 {parse ccyymmdd} {
+    clock scan {1971 Jan xxxi} -format {%Y %h %Oe} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.287 {parse ccyymmdd} {
+    clock scan {1971 01 31} -format {%Y %m %d} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.288 {parse ccyymmdd} {
+    clock scan {1971 01 xxxi} -format {%Y %m %Od} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.289 {parse ccyymmdd} {
+    clock scan {1971 01 31} -format {%Y %m %e} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.290 {parse ccyymmdd} {
+    clock scan {1971 01 xxxi} -format {%Y %m %Oe} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.291 {parse ccyymmdd} {
+    clock scan {1971 i 31} -format {%Y %Om %d} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.292 {parse ccyymmdd} {
+    clock scan {1971 i xxxi} -format {%Y %Om %Od} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.293 {parse ccyymmdd} {
+    clock scan {1971 i 31} -format {%Y %Om %e} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.294 {parse ccyymmdd} {
+    clock scan {1971 i xxxi} -format {%Y %Om %Oe} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.295 {parse ccyymmdd} {
+    clock scan {1971  1 31} -format {%Y %N %d} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.296 {parse ccyymmdd} {
+    clock scan {1971  1 xxxi} -format {%Y %N %Od} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.297 {parse ccyymmdd} {
+    clock scan {1971  1 31} -format {%Y %N %e} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.298 {parse ccyymmdd} {
+    clock scan {1971  1 xxxi} -format {%Y %N %Oe} -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.299 {parse ccyymmdd} {
+    clock scan 01/31/1971 -format %x -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.300 {parse ccyymmdd} {
+    clock scan 01/31/1971 -format %D -locale en_US_roman -gmt 1
+} 34128000
+test clock-8.301 {parse ccyymmdd} {
+    clock scan {1971 Dec 02} -format {%C%y %b %d} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.302 {parse ccyymmdd} {
+    clock scan {1971 Dec ii} -format {%C%y %b %Od} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.303 {parse ccyymmdd} {
+    clock scan {1971 Dec  2} -format {%C%y %b %e} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.304 {parse ccyymmdd} {
+    clock scan {1971 Dec ii} -format {%C%y %b %Oe} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.305 {parse ccyymmdd} {
+    clock scan {1971 December 02} -format {%C%y %B %d} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.306 {parse ccyymmdd} {
+    clock scan {1971 December ii} -format {%C%y %B %Od} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.307 {parse ccyymmdd} {
+    clock scan {1971 December  2} -format {%C%y %B %e} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.308 {parse ccyymmdd} {
+    clock scan {1971 December ii} -format {%C%y %B %Oe} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.309 {parse ccyymmdd} {
+    clock scan {1971 Dec 02} -format {%C%y %h %d} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.310 {parse ccyymmdd} {
+    clock scan {1971 Dec ii} -format {%C%y %h %Od} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.311 {parse ccyymmdd} {
+    clock scan {1971 Dec  2} -format {%C%y %h %e} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.312 {parse ccyymmdd} {
+    clock scan {1971 Dec ii} -format {%C%y %h %Oe} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.313 {parse ccyymmdd} {
+    clock scan {1971 12 02} -format {%C%y %m %d} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.314 {parse ccyymmdd} {
+    clock scan {1971 12 ii} -format {%C%y %m %Od} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.315 {parse ccyymmdd} {
+    clock scan {1971 12  2} -format {%C%y %m %e} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.316 {parse ccyymmdd} {
+    clock scan {1971 12 ii} -format {%C%y %m %Oe} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.317 {parse ccyymmdd} {
+    clock scan {1971 xii 02} -format {%C%y %Om %d} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.318 {parse ccyymmdd} {
+    clock scan {1971 xii ii} -format {%C%y %Om %Od} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.319 {parse ccyymmdd} {
+    clock scan {1971 xii  2} -format {%C%y %Om %e} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.320 {parse ccyymmdd} {
+    clock scan {1971 xii ii} -format {%C%y %Om %Oe} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.321 {parse ccyymmdd} {
+    clock scan {1971 12 02} -format {%C%y %N %d} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.322 {parse ccyymmdd} {
+    clock scan {1971 12 ii} -format {%C%y %N %Od} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.323 {parse ccyymmdd} {
+    clock scan {1971 12  2} -format {%C%y %N %e} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.324 {parse ccyymmdd} {
+    clock scan {1971 12 ii} -format {%C%y %N %Oe} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.325 {parse ccyymmdd} {
+    clock scan {1971 Dec 02} -format {%Y %b %d} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.326 {parse ccyymmdd} {
+    clock scan {1971 Dec ii} -format {%Y %b %Od} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.327 {parse ccyymmdd} {
+    clock scan {1971 Dec  2} -format {%Y %b %e} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.328 {parse ccyymmdd} {
+    clock scan {1971 Dec ii} -format {%Y %b %Oe} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.329 {parse ccyymmdd} {
+    clock scan {1971 December 02} -format {%Y %B %d} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.330 {parse ccyymmdd} {
+    clock scan {1971 December ii} -format {%Y %B %Od} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.331 {parse ccyymmdd} {
+    clock scan {1971 December  2} -format {%Y %B %e} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.332 {parse ccyymmdd} {
+    clock scan {1971 December ii} -format {%Y %B %Oe} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.333 {parse ccyymmdd} {
+    clock scan {1971 Dec 02} -format {%Y %h %d} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.334 {parse ccyymmdd} {
+    clock scan {1971 Dec ii} -format {%Y %h %Od} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.335 {parse ccyymmdd} {
+    clock scan {1971 Dec  2} -format {%Y %h %e} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.336 {parse ccyymmdd} {
+    clock scan {1971 Dec ii} -format {%Y %h %Oe} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.337 {parse ccyymmdd} {
+    clock scan {1971 12 02} -format {%Y %m %d} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.338 {parse ccyymmdd} {
+    clock scan {1971 12 ii} -format {%Y %m %Od} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.339 {parse ccyymmdd} {
+    clock scan {1971 12  2} -format {%Y %m %e} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.340 {parse ccyymmdd} {
+    clock scan {1971 12 ii} -format {%Y %m %Oe} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.341 {parse ccyymmdd} {
+    clock scan {1971 xii 02} -format {%Y %Om %d} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.342 {parse ccyymmdd} {
+    clock scan {1971 xii ii} -format {%Y %Om %Od} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.343 {parse ccyymmdd} {
+    clock scan {1971 xii  2} -format {%Y %Om %e} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.344 {parse ccyymmdd} {
+    clock scan {1971 xii ii} -format {%Y %Om %Oe} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.345 {parse ccyymmdd} {
+    clock scan {1971 12 02} -format {%Y %N %d} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.346 {parse ccyymmdd} {
+    clock scan {1971 12 ii} -format {%Y %N %Od} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.347 {parse ccyymmdd} {
+    clock scan {1971 12  2} -format {%Y %N %e} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.348 {parse ccyymmdd} {
+    clock scan {1971 12 ii} -format {%Y %N %Oe} -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.349 {parse ccyymmdd} {
+    clock scan 12/02/1971 -format %x -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.350 {parse ccyymmdd} {
+    clock scan 12/02/1971 -format %D -locale en_US_roman -gmt 1
+} 60480000
+test clock-8.351 {parse ccyymmdd} {
+    clock scan {1971 Dec 31} -format {%C%y %b %d} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.352 {parse ccyymmdd} {
+    clock scan {1971 Dec xxxi} -format {%C%y %b %Od} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.353 {parse ccyymmdd} {
+    clock scan {1971 Dec 31} -format {%C%y %b %e} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.354 {parse ccyymmdd} {
+    clock scan {1971 Dec xxxi} -format {%C%y %b %Oe} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.355 {parse ccyymmdd} {
+    clock scan {1971 December 31} -format {%C%y %B %d} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.356 {parse ccyymmdd} {
+    clock scan {1971 December xxxi} -format {%C%y %B %Od} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.357 {parse ccyymmdd} {
+    clock scan {1971 December 31} -format {%C%y %B %e} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.358 {parse ccyymmdd} {
+    clock scan {1971 December xxxi} -format {%C%y %B %Oe} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.359 {parse ccyymmdd} {
+    clock scan {1971 Dec 31} -format {%C%y %h %d} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.360 {parse ccyymmdd} {
+    clock scan {1971 Dec xxxi} -format {%C%y %h %Od} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.361 {parse ccyymmdd} {
+    clock scan {1971 Dec 31} -format {%C%y %h %e} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.362 {parse ccyymmdd} {
+    clock scan {1971 Dec xxxi} -format {%C%y %h %Oe} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.363 {parse ccyymmdd} {
+    clock scan {1971 12 31} -format {%C%y %m %d} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.364 {parse ccyymmdd} {
+    clock scan {1971 12 xxxi} -format {%C%y %m %Od} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.365 {parse ccyymmdd} {
+    clock scan {1971 12 31} -format {%C%y %m %e} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.366 {parse ccyymmdd} {
+    clock scan {1971 12 xxxi} -format {%C%y %m %Oe} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.367 {parse ccyymmdd} {
+    clock scan {1971 xii 31} -format {%C%y %Om %d} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.368 {parse ccyymmdd} {
+    clock scan {1971 xii xxxi} -format {%C%y %Om %Od} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.369 {parse ccyymmdd} {
+    clock scan {1971 xii 31} -format {%C%y %Om %e} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.370 {parse ccyymmdd} {
+    clock scan {1971 xii xxxi} -format {%C%y %Om %Oe} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.371 {parse ccyymmdd} {
+    clock scan {1971 12 31} -format {%C%y %N %d} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.372 {parse ccyymmdd} {
+    clock scan {1971 12 xxxi} -format {%C%y %N %Od} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.373 {parse ccyymmdd} {
+    clock scan {1971 12 31} -format {%C%y %N %e} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.374 {parse ccyymmdd} {
+    clock scan {1971 12 xxxi} -format {%C%y %N %Oe} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.375 {parse ccyymmdd} {
+    clock scan {1971 Dec 31} -format {%Y %b %d} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.376 {parse ccyymmdd} {
+    clock scan {1971 Dec xxxi} -format {%Y %b %Od} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.377 {parse ccyymmdd} {
+    clock scan {1971 Dec 31} -format {%Y %b %e} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.378 {parse ccyymmdd} {
+    clock scan {1971 Dec xxxi} -format {%Y %b %Oe} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.379 {parse ccyymmdd} {
+    clock scan {1971 December 31} -format {%Y %B %d} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.380 {parse ccyymmdd} {
+    clock scan {1971 December xxxi} -format {%Y %B %Od} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.381 {parse ccyymmdd} {
+    clock scan {1971 December 31} -format {%Y %B %e} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.382 {parse ccyymmdd} {
+    clock scan {1971 December xxxi} -format {%Y %B %Oe} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.383 {parse ccyymmdd} {
+    clock scan {1971 Dec 31} -format {%Y %h %d} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.384 {parse ccyymmdd} {
+    clock scan {1971 Dec xxxi} -format {%Y %h %Od} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.385 {parse ccyymmdd} {
+    clock scan {1971 Dec 31} -format {%Y %h %e} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.386 {parse ccyymmdd} {
+    clock scan {1971 Dec xxxi} -format {%Y %h %Oe} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.387 {parse ccyymmdd} {
+    clock scan {1971 12 31} -format {%Y %m %d} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.388 {parse ccyymmdd} {
+    clock scan {1971 12 xxxi} -format {%Y %m %Od} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.389 {parse ccyymmdd} {
+    clock scan {1971 12 31} -format {%Y %m %e} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.390 {parse ccyymmdd} {
+    clock scan {1971 12 xxxi} -format {%Y %m %Oe} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.391 {parse ccyymmdd} {
+    clock scan {1971 xii 31} -format {%Y %Om %d} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.392 {parse ccyymmdd} {
+    clock scan {1971 xii xxxi} -format {%Y %Om %Od} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.393 {parse ccyymmdd} {
+    clock scan {1971 xii 31} -format {%Y %Om %e} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.394 {parse ccyymmdd} {
+    clock scan {1971 xii xxxi} -format {%Y %Om %Oe} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.395 {parse ccyymmdd} {
+    clock scan {1971 12 31} -format {%Y %N %d} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.396 {parse ccyymmdd} {
+    clock scan {1971 12 xxxi} -format {%Y %N %Od} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.397 {parse ccyymmdd} {
+    clock scan {1971 12 31} -format {%Y %N %e} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.398 {parse ccyymmdd} {
+    clock scan {1971 12 xxxi} -format {%Y %N %Oe} -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.399 {parse ccyymmdd} {
+    clock scan 12/31/1971 -format %x -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.400 {parse ccyymmdd} {
+    clock scan 12/31/1971 -format %D -locale en_US_roman -gmt 1
+} 62985600
+test clock-8.401 {parse ccyymmdd} {
+    clock scan {2000 Jan 02} -format {%C%y %b %d} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.402 {parse ccyymmdd} {
+    clock scan {2000 Jan ii} -format {%C%y %b %Od} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.403 {parse ccyymmdd} {
+    clock scan {2000 Jan  2} -format {%C%y %b %e} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.404 {parse ccyymmdd} {
+    clock scan {2000 Jan ii} -format {%C%y %b %Oe} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.405 {parse ccyymmdd} {
+    clock scan {2000 January 02} -format {%C%y %B %d} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.406 {parse ccyymmdd} {
+    clock scan {2000 January ii} -format {%C%y %B %Od} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.407 {parse ccyymmdd} {
+    clock scan {2000 January  2} -format {%C%y %B %e} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.408 {parse ccyymmdd} {
+    clock scan {2000 January ii} -format {%C%y %B %Oe} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.409 {parse ccyymmdd} {
+    clock scan {2000 Jan 02} -format {%C%y %h %d} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.410 {parse ccyymmdd} {
+    clock scan {2000 Jan ii} -format {%C%y %h %Od} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.411 {parse ccyymmdd} {
+    clock scan {2000 Jan  2} -format {%C%y %h %e} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.412 {parse ccyymmdd} {
+    clock scan {2000 Jan ii} -format {%C%y %h %Oe} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.413 {parse ccyymmdd} {
+    clock scan {2000 01 02} -format {%C%y %m %d} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.414 {parse ccyymmdd} {
+    clock scan {2000 01 ii} -format {%C%y %m %Od} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.415 {parse ccyymmdd} {
+    clock scan {2000 01  2} -format {%C%y %m %e} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.416 {parse ccyymmdd} {
+    clock scan {2000 01 ii} -format {%C%y %m %Oe} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.417 {parse ccyymmdd} {
+    clock scan {2000 i 02} -format {%C%y %Om %d} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.418 {parse ccyymmdd} {
+    clock scan {2000 i ii} -format {%C%y %Om %Od} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.419 {parse ccyymmdd} {
+    clock scan {2000 i  2} -format {%C%y %Om %e} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.420 {parse ccyymmdd} {
+    clock scan {2000 i ii} -format {%C%y %Om %Oe} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.421 {parse ccyymmdd} {
+    clock scan {2000  1 02} -format {%C%y %N %d} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.422 {parse ccyymmdd} {
+    clock scan {2000  1 ii} -format {%C%y %N %Od} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.423 {parse ccyymmdd} {
+    clock scan {2000  1  2} -format {%C%y %N %e} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.424 {parse ccyymmdd} {
+    clock scan {2000  1 ii} -format {%C%y %N %Oe} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.425 {parse ccyymmdd} {
+    clock scan {2000 Jan 02} -format {%Y %b %d} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.426 {parse ccyymmdd} {
+    clock scan {2000 Jan ii} -format {%Y %b %Od} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.427 {parse ccyymmdd} {
+    clock scan {2000 Jan  2} -format {%Y %b %e} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.428 {parse ccyymmdd} {
+    clock scan {2000 Jan ii} -format {%Y %b %Oe} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.429 {parse ccyymmdd} {
+    clock scan {2000 January 02} -format {%Y %B %d} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.430 {parse ccyymmdd} {
+    clock scan {2000 January ii} -format {%Y %B %Od} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.431 {parse ccyymmdd} {
+    clock scan {2000 January  2} -format {%Y %B %e} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.432 {parse ccyymmdd} {
+    clock scan {2000 January ii} -format {%Y %B %Oe} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.433 {parse ccyymmdd} {
+    clock scan {2000 Jan 02} -format {%Y %h %d} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.434 {parse ccyymmdd} {
+    clock scan {2000 Jan ii} -format {%Y %h %Od} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.435 {parse ccyymmdd} {
+    clock scan {2000 Jan  2} -format {%Y %h %e} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.436 {parse ccyymmdd} {
+    clock scan {2000 Jan ii} -format {%Y %h %Oe} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.437 {parse ccyymmdd} {
+    clock scan {2000 01 02} -format {%Y %m %d} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.438 {parse ccyymmdd} {
+    clock scan {2000 01 ii} -format {%Y %m %Od} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.439 {parse ccyymmdd} {
+    clock scan {2000 01  2} -format {%Y %m %e} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.440 {parse ccyymmdd} {
+    clock scan {2000 01 ii} -format {%Y %m %Oe} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.441 {parse ccyymmdd} {
+    clock scan {2000 i 02} -format {%Y %Om %d} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.442 {parse ccyymmdd} {
+    clock scan {2000 i ii} -format {%Y %Om %Od} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.443 {parse ccyymmdd} {
+    clock scan {2000 i  2} -format {%Y %Om %e} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.444 {parse ccyymmdd} {
+    clock scan {2000 i ii} -format {%Y %Om %Oe} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.445 {parse ccyymmdd} {
+    clock scan {2000  1 02} -format {%Y %N %d} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.446 {parse ccyymmdd} {
+    clock scan {2000  1 ii} -format {%Y %N %Od} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.447 {parse ccyymmdd} {
+    clock scan {2000  1  2} -format {%Y %N %e} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.448 {parse ccyymmdd} {
+    clock scan {2000  1 ii} -format {%Y %N %Oe} -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.449 {parse ccyymmdd} {
+    clock scan 01/02/2000 -format %x -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.450 {parse ccyymmdd} {
+    clock scan 01/02/2000 -format %D -locale en_US_roman -gmt 1
+} 946771200
+test clock-8.451 {parse ccyymmdd} {
+    clock scan {2000 Jan 31} -format {%C%y %b %d} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.452 {parse ccyymmdd} {
+    clock scan {2000 Jan xxxi} -format {%C%y %b %Od} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.453 {parse ccyymmdd} {
+    clock scan {2000 Jan 31} -format {%C%y %b %e} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.454 {parse ccyymmdd} {
+    clock scan {2000 Jan xxxi} -format {%C%y %b %Oe} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.455 {parse ccyymmdd} {
+    clock scan {2000 January 31} -format {%C%y %B %d} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.456 {parse ccyymmdd} {
+    clock scan {2000 January xxxi} -format {%C%y %B %Od} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.457 {parse ccyymmdd} {
+    clock scan {2000 January 31} -format {%C%y %B %e} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.458 {parse ccyymmdd} {
+    clock scan {2000 January xxxi} -format {%C%y %B %Oe} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.459 {parse ccyymmdd} {
+    clock scan {2000 Jan 31} -format {%C%y %h %d} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.460 {parse ccyymmdd} {
+    clock scan {2000 Jan xxxi} -format {%C%y %h %Od} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.461 {parse ccyymmdd} {
+    clock scan {2000 Jan 31} -format {%C%y %h %e} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.462 {parse ccyymmdd} {
+    clock scan {2000 Jan xxxi} -format {%C%y %h %Oe} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.463 {parse ccyymmdd} {
+    clock scan {2000 01 31} -format {%C%y %m %d} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.464 {parse ccyymmdd} {
+    clock scan {2000 01 xxxi} -format {%C%y %m %Od} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.465 {parse ccyymmdd} {
+    clock scan {2000 01 31} -format {%C%y %m %e} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.466 {parse ccyymmdd} {
+    clock scan {2000 01 xxxi} -format {%C%y %m %Oe} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.467 {parse ccyymmdd} {
+    clock scan {2000 i 31} -format {%C%y %Om %d} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.468 {parse ccyymmdd} {
+    clock scan {2000 i xxxi} -format {%C%y %Om %Od} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.469 {parse ccyymmdd} {
+    clock scan {2000 i 31} -format {%C%y %Om %e} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.470 {parse ccyymmdd} {
+    clock scan {2000 i xxxi} -format {%C%y %Om %Oe} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.471 {parse ccyymmdd} {
+    clock scan {2000  1 31} -format {%C%y %N %d} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.472 {parse ccyymmdd} {
+    clock scan {2000  1 xxxi} -format {%C%y %N %Od} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.473 {parse ccyymmdd} {
+    clock scan {2000  1 31} -format {%C%y %N %e} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.474 {parse ccyymmdd} {
+    clock scan {2000  1 xxxi} -format {%C%y %N %Oe} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.475 {parse ccyymmdd} {
+    clock scan {2000 Jan 31} -format {%Y %b %d} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.476 {parse ccyymmdd} {
+    clock scan {2000 Jan xxxi} -format {%Y %b %Od} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.477 {parse ccyymmdd} {
+    clock scan {2000 Jan 31} -format {%Y %b %e} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.478 {parse ccyymmdd} {
+    clock scan {2000 Jan xxxi} -format {%Y %b %Oe} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.479 {parse ccyymmdd} {
+    clock scan {2000 January 31} -format {%Y %B %d} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.480 {parse ccyymmdd} {
+    clock scan {2000 January xxxi} -format {%Y %B %Od} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.481 {parse ccyymmdd} {
+    clock scan {2000 January 31} -format {%Y %B %e} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.482 {parse ccyymmdd} {
+    clock scan {2000 January xxxi} -format {%Y %B %Oe} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.483 {parse ccyymmdd} {
+    clock scan {2000 Jan 31} -format {%Y %h %d} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.484 {parse ccyymmdd} {
+    clock scan {2000 Jan xxxi} -format {%Y %h %Od} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.485 {parse ccyymmdd} {
+    clock scan {2000 Jan 31} -format {%Y %h %e} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.486 {parse ccyymmdd} {
+    clock scan {2000 Jan xxxi} -format {%Y %h %Oe} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.487 {parse ccyymmdd} {
+    clock scan {2000 01 31} -format {%Y %m %d} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.488 {parse ccyymmdd} {
+    clock scan {2000 01 xxxi} -format {%Y %m %Od} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.489 {parse ccyymmdd} {
+    clock scan {2000 01 31} -format {%Y %m %e} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.490 {parse ccyymmdd} {
+    clock scan {2000 01 xxxi} -format {%Y %m %Oe} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.491 {parse ccyymmdd} {
+    clock scan {2000 i 31} -format {%Y %Om %d} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.492 {parse ccyymmdd} {
+    clock scan {2000 i xxxi} -format {%Y %Om %Od} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.493 {parse ccyymmdd} {
+    clock scan {2000 i 31} -format {%Y %Om %e} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.494 {parse ccyymmdd} {
+    clock scan {2000 i xxxi} -format {%Y %Om %Oe} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.495 {parse ccyymmdd} {
+    clock scan {2000  1 31} -format {%Y %N %d} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.496 {parse ccyymmdd} {
+    clock scan {2000  1 xxxi} -format {%Y %N %Od} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.497 {parse ccyymmdd} {
+    clock scan {2000  1 31} -format {%Y %N %e} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.498 {parse ccyymmdd} {
+    clock scan {2000  1 xxxi} -format {%Y %N %Oe} -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.499 {parse ccyymmdd} {
+    clock scan 01/31/2000 -format %x -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.500 {parse ccyymmdd} {
+    clock scan 01/31/2000 -format %D -locale en_US_roman -gmt 1
+} 949276800
+test clock-8.501 {parse ccyymmdd} {
+    clock scan {2000 Dec 02} -format {%C%y %b %d} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.502 {parse ccyymmdd} {
+    clock scan {2000 Dec ii} -format {%C%y %b %Od} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.503 {parse ccyymmdd} {
+    clock scan {2000 Dec  2} -format {%C%y %b %e} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.504 {parse ccyymmdd} {
+    clock scan {2000 Dec ii} -format {%C%y %b %Oe} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.505 {parse ccyymmdd} {
+    clock scan {2000 December 02} -format {%C%y %B %d} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.506 {parse ccyymmdd} {
+    clock scan {2000 December ii} -format {%C%y %B %Od} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.507 {parse ccyymmdd} {
+    clock scan {2000 December  2} -format {%C%y %B %e} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.508 {parse ccyymmdd} {
+    clock scan {2000 December ii} -format {%C%y %B %Oe} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.509 {parse ccyymmdd} {
+    clock scan {2000 Dec 02} -format {%C%y %h %d} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.510 {parse ccyymmdd} {
+    clock scan {2000 Dec ii} -format {%C%y %h %Od} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.511 {parse ccyymmdd} {
+    clock scan {2000 Dec  2} -format {%C%y %h %e} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.512 {parse ccyymmdd} {
+    clock scan {2000 Dec ii} -format {%C%y %h %Oe} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.513 {parse ccyymmdd} {
+    clock scan {2000 12 02} -format {%C%y %m %d} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.514 {parse ccyymmdd} {
+    clock scan {2000 12 ii} -format {%C%y %m %Od} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.515 {parse ccyymmdd} {
+    clock scan {2000 12  2} -format {%C%y %m %e} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.516 {parse ccyymmdd} {
+    clock scan {2000 12 ii} -format {%C%y %m %Oe} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.517 {parse ccyymmdd} {
+    clock scan {2000 xii 02} -format {%C%y %Om %d} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.518 {parse ccyymmdd} {
+    clock scan {2000 xii ii} -format {%C%y %Om %Od} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.519 {parse ccyymmdd} {
+    clock scan {2000 xii  2} -format {%C%y %Om %e} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.520 {parse ccyymmdd} {
+    clock scan {2000 xii ii} -format {%C%y %Om %Oe} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.521 {parse ccyymmdd} {
+    clock scan {2000 12 02} -format {%C%y %N %d} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.522 {parse ccyymmdd} {
+    clock scan {2000 12 ii} -format {%C%y %N %Od} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.523 {parse ccyymmdd} {
+    clock scan {2000 12  2} -format {%C%y %N %e} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.524 {parse ccyymmdd} {
+    clock scan {2000 12 ii} -format {%C%y %N %Oe} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.525 {parse ccyymmdd} {
+    clock scan {2000 Dec 02} -format {%Y %b %d} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.526 {parse ccyymmdd} {
+    clock scan {2000 Dec ii} -format {%Y %b %Od} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.527 {parse ccyymmdd} {
+    clock scan {2000 Dec  2} -format {%Y %b %e} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.528 {parse ccyymmdd} {
+    clock scan {2000 Dec ii} -format {%Y %b %Oe} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.529 {parse ccyymmdd} {
+    clock scan {2000 December 02} -format {%Y %B %d} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.530 {parse ccyymmdd} {
+    clock scan {2000 December ii} -format {%Y %B %Od} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.531 {parse ccyymmdd} {
+    clock scan {2000 December  2} -format {%Y %B %e} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.532 {parse ccyymmdd} {
+    clock scan {2000 December ii} -format {%Y %B %Oe} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.533 {parse ccyymmdd} {
+    clock scan {2000 Dec 02} -format {%Y %h %d} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.534 {parse ccyymmdd} {
+    clock scan {2000 Dec ii} -format {%Y %h %Od} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.535 {parse ccyymmdd} {
+    clock scan {2000 Dec  2} -format {%Y %h %e} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.536 {parse ccyymmdd} {
+    clock scan {2000 Dec ii} -format {%Y %h %Oe} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.537 {parse ccyymmdd} {
+    clock scan {2000 12 02} -format {%Y %m %d} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.538 {parse ccyymmdd} {
+    clock scan {2000 12 ii} -format {%Y %m %Od} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.539 {parse ccyymmdd} {
+    clock scan {2000 12  2} -format {%Y %m %e} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.540 {parse ccyymmdd} {
+    clock scan {2000 12 ii} -format {%Y %m %Oe} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.541 {parse ccyymmdd} {
+    clock scan {2000 xii 02} -format {%Y %Om %d} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.542 {parse ccyymmdd} {
+    clock scan {2000 xii ii} -format {%Y %Om %Od} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.543 {parse ccyymmdd} {
+    clock scan {2000 xii  2} -format {%Y %Om %e} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.544 {parse ccyymmdd} {
+    clock scan {2000 xii ii} -format {%Y %Om %Oe} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.545 {parse ccyymmdd} {
+    clock scan {2000 12 02} -format {%Y %N %d} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.546 {parse ccyymmdd} {
+    clock scan {2000 12 ii} -format {%Y %N %Od} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.547 {parse ccyymmdd} {
+    clock scan {2000 12  2} -format {%Y %N %e} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.548 {parse ccyymmdd} {
+    clock scan {2000 12 ii} -format {%Y %N %Oe} -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.549 {parse ccyymmdd} {
+    clock scan 12/02/2000 -format %x -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.550 {parse ccyymmdd} {
+    clock scan 12/02/2000 -format %D -locale en_US_roman -gmt 1
+} 975715200
+test clock-8.551 {parse ccyymmdd} {
+    clock scan {2000 Dec 31} -format {%C%y %b %d} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.552 {parse ccyymmdd} {
+    clock scan {2000 Dec xxxi} -format {%C%y %b %Od} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.553 {parse ccyymmdd} {
+    clock scan {2000 Dec 31} -format {%C%y %b %e} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.554 {parse ccyymmdd} {
+    clock scan {2000 Dec xxxi} -format {%C%y %b %Oe} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.555 {parse ccyymmdd} {
+    clock scan {2000 December 31} -format {%C%y %B %d} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.556 {parse ccyymmdd} {
+    clock scan {2000 December xxxi} -format {%C%y %B %Od} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.557 {parse ccyymmdd} {
+    clock scan {2000 December 31} -format {%C%y %B %e} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.558 {parse ccyymmdd} {
+    clock scan {2000 December xxxi} -format {%C%y %B %Oe} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.559 {parse ccyymmdd} {
+    clock scan {2000 Dec 31} -format {%C%y %h %d} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.560 {parse ccyymmdd} {
+    clock scan {2000 Dec xxxi} -format {%C%y %h %Od} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.561 {parse ccyymmdd} {
+    clock scan {2000 Dec 31} -format {%C%y %h %e} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.562 {parse ccyymmdd} {
+    clock scan {2000 Dec xxxi} -format {%C%y %h %Oe} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.563 {parse ccyymmdd} {
+    clock scan {2000 12 31} -format {%C%y %m %d} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.564 {parse ccyymmdd} {
+    clock scan {2000 12 xxxi} -format {%C%y %m %Od} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.565 {parse ccyymmdd} {
+    clock scan {2000 12 31} -format {%C%y %m %e} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.566 {parse ccyymmdd} {
+    clock scan {2000 12 xxxi} -format {%C%y %m %Oe} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.567 {parse ccyymmdd} {
+    clock scan {2000 xii 31} -format {%C%y %Om %d} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.568 {parse ccyymmdd} {
+    clock scan {2000 xii xxxi} -format {%C%y %Om %Od} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.569 {parse ccyymmdd} {
+    clock scan {2000 xii 31} -format {%C%y %Om %e} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.570 {parse ccyymmdd} {
+    clock scan {2000 xii xxxi} -format {%C%y %Om %Oe} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.571 {parse ccyymmdd} {
+    clock scan {2000 12 31} -format {%C%y %N %d} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.572 {parse ccyymmdd} {
+    clock scan {2000 12 xxxi} -format {%C%y %N %Od} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.573 {parse ccyymmdd} {
+    clock scan {2000 12 31} -format {%C%y %N %e} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.574 {parse ccyymmdd} {
+    clock scan {2000 12 xxxi} -format {%C%y %N %Oe} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.575 {parse ccyymmdd} {
+    clock scan {2000 Dec 31} -format {%Y %b %d} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.576 {parse ccyymmdd} {
+    clock scan {2000 Dec xxxi} -format {%Y %b %Od} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.577 {parse ccyymmdd} {
+    clock scan {2000 Dec 31} -format {%Y %b %e} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.578 {parse ccyymmdd} {
+    clock scan {2000 Dec xxxi} -format {%Y %b %Oe} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.579 {parse ccyymmdd} {
+    clock scan {2000 December 31} -format {%Y %B %d} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.580 {parse ccyymmdd} {
+    clock scan {2000 December xxxi} -format {%Y %B %Od} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.581 {parse ccyymmdd} {
+    clock scan {2000 December 31} -format {%Y %B %e} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.582 {parse ccyymmdd} {
+    clock scan {2000 December xxxi} -format {%Y %B %Oe} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.583 {parse ccyymmdd} {
+    clock scan {2000 Dec 31} -format {%Y %h %d} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.584 {parse ccyymmdd} {
+    clock scan {2000 Dec xxxi} -format {%Y %h %Od} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.585 {parse ccyymmdd} {
+    clock scan {2000 Dec 31} -format {%Y %h %e} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.586 {parse ccyymmdd} {
+    clock scan {2000 Dec xxxi} -format {%Y %h %Oe} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.587 {parse ccyymmdd} {
+    clock scan {2000 12 31} -format {%Y %m %d} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.588 {parse ccyymmdd} {
+    clock scan {2000 12 xxxi} -format {%Y %m %Od} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.589 {parse ccyymmdd} {
+    clock scan {2000 12 31} -format {%Y %m %e} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.590 {parse ccyymmdd} {
+    clock scan {2000 12 xxxi} -format {%Y %m %Oe} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.591 {parse ccyymmdd} {
+    clock scan {2000 xii 31} -format {%Y %Om %d} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.592 {parse ccyymmdd} {
+    clock scan {2000 xii xxxi} -format {%Y %Om %Od} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.593 {parse ccyymmdd} {
+    clock scan {2000 xii 31} -format {%Y %Om %e} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.594 {parse ccyymmdd} {
+    clock scan {2000 xii xxxi} -format {%Y %Om %Oe} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.595 {parse ccyymmdd} {
+    clock scan {2000 12 31} -format {%Y %N %d} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.596 {parse ccyymmdd} {
+    clock scan {2000 12 xxxi} -format {%Y %N %Od} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.597 {parse ccyymmdd} {
+    clock scan {2000 12 31} -format {%Y %N %e} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.598 {parse ccyymmdd} {
+    clock scan {2000 12 xxxi} -format {%Y %N %Oe} -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.599 {parse ccyymmdd} {
+    clock scan 12/31/2000 -format %x -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.600 {parse ccyymmdd} {
+    clock scan 12/31/2000 -format %D -locale en_US_roman -gmt 1
+} 978220800
+test clock-8.601 {parse ccyymmdd} {
+    clock scan {2001 Jan 02} -format {%C%y %b %d} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.602 {parse ccyymmdd} {
+    clock scan {2001 Jan ii} -format {%C%y %b %Od} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.603 {parse ccyymmdd} {
+    clock scan {2001 Jan  2} -format {%C%y %b %e} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.604 {parse ccyymmdd} {
+    clock scan {2001 Jan ii} -format {%C%y %b %Oe} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.605 {parse ccyymmdd} {
+    clock scan {2001 January 02} -format {%C%y %B %d} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.606 {parse ccyymmdd} {
+    clock scan {2001 January ii} -format {%C%y %B %Od} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.607 {parse ccyymmdd} {
+    clock scan {2001 January  2} -format {%C%y %B %e} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.608 {parse ccyymmdd} {
+    clock scan {2001 January ii} -format {%C%y %B %Oe} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.609 {parse ccyymmdd} {
+    clock scan {2001 Jan 02} -format {%C%y %h %d} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.610 {parse ccyymmdd} {
+    clock scan {2001 Jan ii} -format {%C%y %h %Od} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.611 {parse ccyymmdd} {
+    clock scan {2001 Jan  2} -format {%C%y %h %e} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.612 {parse ccyymmdd} {
+    clock scan {2001 Jan ii} -format {%C%y %h %Oe} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.613 {parse ccyymmdd} {
+    clock scan {2001 01 02} -format {%C%y %m %d} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.614 {parse ccyymmdd} {
+    clock scan {2001 01 ii} -format {%C%y %m %Od} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.615 {parse ccyymmdd} {
+    clock scan {2001 01  2} -format {%C%y %m %e} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.616 {parse ccyymmdd} {
+    clock scan {2001 01 ii} -format {%C%y %m %Oe} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.617 {parse ccyymmdd} {
+    clock scan {2001 i 02} -format {%C%y %Om %d} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.618 {parse ccyymmdd} {
+    clock scan {2001 i ii} -format {%C%y %Om %Od} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.619 {parse ccyymmdd} {
+    clock scan {2001 i  2} -format {%C%y %Om %e} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.620 {parse ccyymmdd} {
+    clock scan {2001 i ii} -format {%C%y %Om %Oe} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.621 {parse ccyymmdd} {
+    clock scan {2001  1 02} -format {%C%y %N %d} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.622 {parse ccyymmdd} {
+    clock scan {2001  1 ii} -format {%C%y %N %Od} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.623 {parse ccyymmdd} {
+    clock scan {2001  1  2} -format {%C%y %N %e} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.624 {parse ccyymmdd} {
+    clock scan {2001  1 ii} -format {%C%y %N %Oe} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.625 {parse ccyymmdd} {
+    clock scan {2001 Jan 02} -format {%Y %b %d} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.626 {parse ccyymmdd} {
+    clock scan {2001 Jan ii} -format {%Y %b %Od} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.627 {parse ccyymmdd} {
+    clock scan {2001 Jan  2} -format {%Y %b %e} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.628 {parse ccyymmdd} {
+    clock scan {2001 Jan ii} -format {%Y %b %Oe} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.629 {parse ccyymmdd} {
+    clock scan {2001 January 02} -format {%Y %B %d} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.630 {parse ccyymmdd} {
+    clock scan {2001 January ii} -format {%Y %B %Od} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.631 {parse ccyymmdd} {
+    clock scan {2001 January  2} -format {%Y %B %e} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.632 {parse ccyymmdd} {
+    clock scan {2001 January ii} -format {%Y %B %Oe} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.633 {parse ccyymmdd} {
+    clock scan {2001 Jan 02} -format {%Y %h %d} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.634 {parse ccyymmdd} {
+    clock scan {2001 Jan ii} -format {%Y %h %Od} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.635 {parse ccyymmdd} {
+    clock scan {2001 Jan  2} -format {%Y %h %e} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.636 {parse ccyymmdd} {
+    clock scan {2001 Jan ii} -format {%Y %h %Oe} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.637 {parse ccyymmdd} {
+    clock scan {2001 01 02} -format {%Y %m %d} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.638 {parse ccyymmdd} {
+    clock scan {2001 01 ii} -format {%Y %m %Od} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.639 {parse ccyymmdd} {
+    clock scan {2001 01  2} -format {%Y %m %e} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.640 {parse ccyymmdd} {
+    clock scan {2001 01 ii} -format {%Y %m %Oe} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.641 {parse ccyymmdd} {
+    clock scan {2001 i 02} -format {%Y %Om %d} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.642 {parse ccyymmdd} {
+    clock scan {2001 i ii} -format {%Y %Om %Od} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.643 {parse ccyymmdd} {
+    clock scan {2001 i  2} -format {%Y %Om %e} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.644 {parse ccyymmdd} {
+    clock scan {2001 i ii} -format {%Y %Om %Oe} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.645 {parse ccyymmdd} {
+    clock scan {2001  1 02} -format {%Y %N %d} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.646 {parse ccyymmdd} {
+    clock scan {2001  1 ii} -format {%Y %N %Od} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.647 {parse ccyymmdd} {
+    clock scan {2001  1  2} -format {%Y %N %e} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.648 {parse ccyymmdd} {
+    clock scan {2001  1 ii} -format {%Y %N %Oe} -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.649 {parse ccyymmdd} {
+    clock scan 01/02/2001 -format %x -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.650 {parse ccyymmdd} {
+    clock scan 01/02/2001 -format %D -locale en_US_roman -gmt 1
+} 978393600
+test clock-8.651 {parse ccyymmdd} {
+    clock scan {2001 Jan 31} -format {%C%y %b %d} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.652 {parse ccyymmdd} {
+    clock scan {2001 Jan xxxi} -format {%C%y %b %Od} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.653 {parse ccyymmdd} {
+    clock scan {2001 Jan 31} -format {%C%y %b %e} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.654 {parse ccyymmdd} {
+    clock scan {2001 Jan xxxi} -format {%C%y %b %Oe} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.655 {parse ccyymmdd} {
+    clock scan {2001 January 31} -format {%C%y %B %d} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.656 {parse ccyymmdd} {
+    clock scan {2001 January xxxi} -format {%C%y %B %Od} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.657 {parse ccyymmdd} {
+    clock scan {2001 January 31} -format {%C%y %B %e} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.658 {parse ccyymmdd} {
+    clock scan {2001 January xxxi} -format {%C%y %B %Oe} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.659 {parse ccyymmdd} {
+    clock scan {2001 Jan 31} -format {%C%y %h %d} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.660 {parse ccyymmdd} {
+    clock scan {2001 Jan xxxi} -format {%C%y %h %Od} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.661 {parse ccyymmdd} {
+    clock scan {2001 Jan 31} -format {%C%y %h %e} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.662 {parse ccyymmdd} {
+    clock scan {2001 Jan xxxi} -format {%C%y %h %Oe} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.663 {parse ccyymmdd} {
+    clock scan {2001 01 31} -format {%C%y %m %d} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.664 {parse ccyymmdd} {
+    clock scan {2001 01 xxxi} -format {%C%y %m %Od} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.665 {parse ccyymmdd} {
+    clock scan {2001 01 31} -format {%C%y %m %e} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.666 {parse ccyymmdd} {
+    clock scan {2001 01 xxxi} -format {%C%y %m %Oe} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.667 {parse ccyymmdd} {
+    clock scan {2001 i 31} -format {%C%y %Om %d} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.668 {parse ccyymmdd} {
+    clock scan {2001 i xxxi} -format {%C%y %Om %Od} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.669 {parse ccyymmdd} {
+    clock scan {2001 i 31} -format {%C%y %Om %e} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.670 {parse ccyymmdd} {
+    clock scan {2001 i xxxi} -format {%C%y %Om %Oe} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.671 {parse ccyymmdd} {
+    clock scan {2001  1 31} -format {%C%y %N %d} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.672 {parse ccyymmdd} {
+    clock scan {2001  1 xxxi} -format {%C%y %N %Od} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.673 {parse ccyymmdd} {
+    clock scan {2001  1 31} -format {%C%y %N %e} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.674 {parse ccyymmdd} {
+    clock scan {2001  1 xxxi} -format {%C%y %N %Oe} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.675 {parse ccyymmdd} {
+    clock scan {2001 Jan 31} -format {%Y %b %d} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.676 {parse ccyymmdd} {
+    clock scan {2001 Jan xxxi} -format {%Y %b %Od} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.677 {parse ccyymmdd} {
+    clock scan {2001 Jan 31} -format {%Y %b %e} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.678 {parse ccyymmdd} {
+    clock scan {2001 Jan xxxi} -format {%Y %b %Oe} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.679 {parse ccyymmdd} {
+    clock scan {2001 January 31} -format {%Y %B %d} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.680 {parse ccyymmdd} {
+    clock scan {2001 January xxxi} -format {%Y %B %Od} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.681 {parse ccyymmdd} {
+    clock scan {2001 January 31} -format {%Y %B %e} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.682 {parse ccyymmdd} {
+    clock scan {2001 January xxxi} -format {%Y %B %Oe} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.683 {parse ccyymmdd} {
+    clock scan {2001 Jan 31} -format {%Y %h %d} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.684 {parse ccyymmdd} {
+    clock scan {2001 Jan xxxi} -format {%Y %h %Od} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.685 {parse ccyymmdd} {
+    clock scan {2001 Jan 31} -format {%Y %h %e} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.686 {parse ccyymmdd} {
+    clock scan {2001 Jan xxxi} -format {%Y %h %Oe} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.687 {parse ccyymmdd} {
+    clock scan {2001 01 31} -format {%Y %m %d} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.688 {parse ccyymmdd} {
+    clock scan {2001 01 xxxi} -format {%Y %m %Od} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.689 {parse ccyymmdd} {
+    clock scan {2001 01 31} -format {%Y %m %e} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.690 {parse ccyymmdd} {
+    clock scan {2001 01 xxxi} -format {%Y %m %Oe} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.691 {parse ccyymmdd} {
+    clock scan {2001 i 31} -format {%Y %Om %d} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.692 {parse ccyymmdd} {
+    clock scan {2001 i xxxi} -format {%Y %Om %Od} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.693 {parse ccyymmdd} {
+    clock scan {2001 i 31} -format {%Y %Om %e} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.694 {parse ccyymmdd} {
+    clock scan {2001 i xxxi} -format {%Y %Om %Oe} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.695 {parse ccyymmdd} {
+    clock scan {2001  1 31} -format {%Y %N %d} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.696 {parse ccyymmdd} {
+    clock scan {2001  1 xxxi} -format {%Y %N %Od} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.697 {parse ccyymmdd} {
+    clock scan {2001  1 31} -format {%Y %N %e} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.698 {parse ccyymmdd} {
+    clock scan {2001  1 xxxi} -format {%Y %N %Oe} -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.699 {parse ccyymmdd} {
+    clock scan 01/31/2001 -format %x -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.700 {parse ccyymmdd} {
+    clock scan 01/31/2001 -format %D -locale en_US_roman -gmt 1
+} 980899200
+test clock-8.701 {parse ccyymmdd} {
+    clock scan {2001 Dec 02} -format {%C%y %b %d} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.702 {parse ccyymmdd} {
+    clock scan {2001 Dec ii} -format {%C%y %b %Od} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.703 {parse ccyymmdd} {
+    clock scan {2001 Dec  2} -format {%C%y %b %e} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.704 {parse ccyymmdd} {
+    clock scan {2001 Dec ii} -format {%C%y %b %Oe} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.705 {parse ccyymmdd} {
+    clock scan {2001 December 02} -format {%C%y %B %d} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.706 {parse ccyymmdd} {
+    clock scan {2001 December ii} -format {%C%y %B %Od} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.707 {parse ccyymmdd} {
+    clock scan {2001 December  2} -format {%C%y %B %e} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.708 {parse ccyymmdd} {
+    clock scan {2001 December ii} -format {%C%y %B %Oe} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.709 {parse ccyymmdd} {
+    clock scan {2001 Dec 02} -format {%C%y %h %d} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.710 {parse ccyymmdd} {
+    clock scan {2001 Dec ii} -format {%C%y %h %Od} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.711 {parse ccyymmdd} {
+    clock scan {2001 Dec  2} -format {%C%y %h %e} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.712 {parse ccyymmdd} {
+    clock scan {2001 Dec ii} -format {%C%y %h %Oe} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.713 {parse ccyymmdd} {
+    clock scan {2001 12 02} -format {%C%y %m %d} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.714 {parse ccyymmdd} {
+    clock scan {2001 12 ii} -format {%C%y %m %Od} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.715 {parse ccyymmdd} {
+    clock scan {2001 12  2} -format {%C%y %m %e} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.716 {parse ccyymmdd} {
+    clock scan {2001 12 ii} -format {%C%y %m %Oe} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.717 {parse ccyymmdd} {
+    clock scan {2001 xii 02} -format {%C%y %Om %d} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.718 {parse ccyymmdd} {
+    clock scan {2001 xii ii} -format {%C%y %Om %Od} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.719 {parse ccyymmdd} {
+    clock scan {2001 xii  2} -format {%C%y %Om %e} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.720 {parse ccyymmdd} {
+    clock scan {2001 xii ii} -format {%C%y %Om %Oe} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.721 {parse ccyymmdd} {
+    clock scan {2001 12 02} -format {%C%y %N %d} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.722 {parse ccyymmdd} {
+    clock scan {2001 12 ii} -format {%C%y %N %Od} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.723 {parse ccyymmdd} {
+    clock scan {2001 12  2} -format {%C%y %N %e} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.724 {parse ccyymmdd} {
+    clock scan {2001 12 ii} -format {%C%y %N %Oe} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.725 {parse ccyymmdd} {
+    clock scan {2001 Dec 02} -format {%Y %b %d} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.726 {parse ccyymmdd} {
+    clock scan {2001 Dec ii} -format {%Y %b %Od} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.727 {parse ccyymmdd} {
+    clock scan {2001 Dec  2} -format {%Y %b %e} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.728 {parse ccyymmdd} {
+    clock scan {2001 Dec ii} -format {%Y %b %Oe} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.729 {parse ccyymmdd} {
+    clock scan {2001 December 02} -format {%Y %B %d} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.730 {parse ccyymmdd} {
+    clock scan {2001 December ii} -format {%Y %B %Od} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.731 {parse ccyymmdd} {
+    clock scan {2001 December  2} -format {%Y %B %e} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.732 {parse ccyymmdd} {
+    clock scan {2001 December ii} -format {%Y %B %Oe} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.733 {parse ccyymmdd} {
+    clock scan {2001 Dec 02} -format {%Y %h %d} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.734 {parse ccyymmdd} {
+    clock scan {2001 Dec ii} -format {%Y %h %Od} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.735 {parse ccyymmdd} {
+    clock scan {2001 Dec  2} -format {%Y %h %e} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.736 {parse ccyymmdd} {
+    clock scan {2001 Dec ii} -format {%Y %h %Oe} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.737 {parse ccyymmdd} {
+    clock scan {2001 12 02} -format {%Y %m %d} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.738 {parse ccyymmdd} {
+    clock scan {2001 12 ii} -format {%Y %m %Od} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.739 {parse ccyymmdd} {
+    clock scan {2001 12  2} -format {%Y %m %e} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.740 {parse ccyymmdd} {
+    clock scan {2001 12 ii} -format {%Y %m %Oe} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.741 {parse ccyymmdd} {
+    clock scan {2001 xii 02} -format {%Y %Om %d} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.742 {parse ccyymmdd} {
+    clock scan {2001 xii ii} -format {%Y %Om %Od} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.743 {parse ccyymmdd} {
+    clock scan {2001 xii  2} -format {%Y %Om %e} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.744 {parse ccyymmdd} {
+    clock scan {2001 xii ii} -format {%Y %Om %Oe} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.745 {parse ccyymmdd} {
+    clock scan {2001 12 02} -format {%Y %N %d} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.746 {parse ccyymmdd} {
+    clock scan {2001 12 ii} -format {%Y %N %Od} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.747 {parse ccyymmdd} {
+    clock scan {2001 12  2} -format {%Y %N %e} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.748 {parse ccyymmdd} {
+    clock scan {2001 12 ii} -format {%Y %N %Oe} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.749 {parse ccyymmdd} {
+    clock scan 12/02/2001 -format %x -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.750 {parse ccyymmdd} {
+    clock scan 12/02/2001 -format %D -locale en_US_roman -gmt 1
+} 1007251200
+test clock-8.751 {parse ccyymmdd} {
+    clock scan {2001 Dec 31} -format {%C%y %b %d} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.752 {parse ccyymmdd} {
+    clock scan {2001 Dec xxxi} -format {%C%y %b %Od} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.753 {parse ccyymmdd} {
+    clock scan {2001 Dec 31} -format {%C%y %b %e} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.754 {parse ccyymmdd} {
+    clock scan {2001 Dec xxxi} -format {%C%y %b %Oe} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.755 {parse ccyymmdd} {
+    clock scan {2001 December 31} -format {%C%y %B %d} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.756 {parse ccyymmdd} {
+    clock scan {2001 December xxxi} -format {%C%y %B %Od} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.757 {parse ccyymmdd} {
+    clock scan {2001 December 31} -format {%C%y %B %e} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.758 {parse ccyymmdd} {
+    clock scan {2001 December xxxi} -format {%C%y %B %Oe} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.759 {parse ccyymmdd} {
+    clock scan {2001 Dec 31} -format {%C%y %h %d} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.760 {parse ccyymmdd} {
+    clock scan {2001 Dec xxxi} -format {%C%y %h %Od} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.761 {parse ccyymmdd} {
+    clock scan {2001 Dec 31} -format {%C%y %h %e} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.762 {parse ccyymmdd} {
+    clock scan {2001 Dec xxxi} -format {%C%y %h %Oe} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.763 {parse ccyymmdd} {
+    clock scan {2001 12 31} -format {%C%y %m %d} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.764 {parse ccyymmdd} {
+    clock scan {2001 12 xxxi} -format {%C%y %m %Od} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.765 {parse ccyymmdd} {
+    clock scan {2001 12 31} -format {%C%y %m %e} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.766 {parse ccyymmdd} {
+    clock scan {2001 12 xxxi} -format {%C%y %m %Oe} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.767 {parse ccyymmdd} {
+    clock scan {2001 xii 31} -format {%C%y %Om %d} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.768 {parse ccyymmdd} {
+    clock scan {2001 xii xxxi} -format {%C%y %Om %Od} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.769 {parse ccyymmdd} {
+    clock scan {2001 xii 31} -format {%C%y %Om %e} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.770 {parse ccyymmdd} {
+    clock scan {2001 xii xxxi} -format {%C%y %Om %Oe} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.771 {parse ccyymmdd} {
+    clock scan {2001 12 31} -format {%C%y %N %d} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.772 {parse ccyymmdd} {
+    clock scan {2001 12 xxxi} -format {%C%y %N %Od} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.773 {parse ccyymmdd} {
+    clock scan {2001 12 31} -format {%C%y %N %e} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.774 {parse ccyymmdd} {
+    clock scan {2001 12 xxxi} -format {%C%y %N %Oe} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.775 {parse ccyymmdd} {
+    clock scan {2001 Dec 31} -format {%Y %b %d} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.776 {parse ccyymmdd} {
+    clock scan {2001 Dec xxxi} -format {%Y %b %Od} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.777 {parse ccyymmdd} {
+    clock scan {2001 Dec 31} -format {%Y %b %e} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.778 {parse ccyymmdd} {
+    clock scan {2001 Dec xxxi} -format {%Y %b %Oe} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.779 {parse ccyymmdd} {
+    clock scan {2001 December 31} -format {%Y %B %d} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.780 {parse ccyymmdd} {
+    clock scan {2001 December xxxi} -format {%Y %B %Od} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.781 {parse ccyymmdd} {
+    clock scan {2001 December 31} -format {%Y %B %e} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.782 {parse ccyymmdd} {
+    clock scan {2001 December xxxi} -format {%Y %B %Oe} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.783 {parse ccyymmdd} {
+    clock scan {2001 Dec 31} -format {%Y %h %d} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.784 {parse ccyymmdd} {
+    clock scan {2001 Dec xxxi} -format {%Y %h %Od} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.785 {parse ccyymmdd} {
+    clock scan {2001 Dec 31} -format {%Y %h %e} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.786 {parse ccyymmdd} {
+    clock scan {2001 Dec xxxi} -format {%Y %h %Oe} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.787 {parse ccyymmdd} {
+    clock scan {2001 12 31} -format {%Y %m %d} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.788 {parse ccyymmdd} {
+    clock scan {2001 12 xxxi} -format {%Y %m %Od} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.789 {parse ccyymmdd} {
+    clock scan {2001 12 31} -format {%Y %m %e} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.790 {parse ccyymmdd} {
+    clock scan {2001 12 xxxi} -format {%Y %m %Oe} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.791 {parse ccyymmdd} {
+    clock scan {2001 xii 31} -format {%Y %Om %d} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.792 {parse ccyymmdd} {
+    clock scan {2001 xii xxxi} -format {%Y %Om %Od} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.793 {parse ccyymmdd} {
+    clock scan {2001 xii 31} -format {%Y %Om %e} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.794 {parse ccyymmdd} {
+    clock scan {2001 xii xxxi} -format {%Y %Om %Oe} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.795 {parse ccyymmdd} {
+    clock scan {2001 12 31} -format {%Y %N %d} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.796 {parse ccyymmdd} {
+    clock scan {2001 12 xxxi} -format {%Y %N %Od} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.797 {parse ccyymmdd} {
+    clock scan {2001 12 31} -format {%Y %N %e} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.798 {parse ccyymmdd} {
+    clock scan {2001 12 xxxi} -format {%Y %N %Oe} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.799 {parse ccyymmdd} {
+    clock scan 12/31/2001 -format %x -locale en_US_roman -gmt 1
+} 1009756800
+test clock-8.800 {parse ccyymmdd} {
+    clock scan 12/31/2001 -format %D -locale en_US_roman -gmt 1
+} 1009756800
+# END testcases8
+
+test clock-9.1 {seconds take precedence over ccyymmdd} {
+    clock scan {0 20000101} -format {%s %Y%m%d} -gmt true
+} 0
+
+test clock-9.2 {Julian day takes precedence over ccyymmdd} {
+    clock scan {2440588 20000101} -format {%J %Y%m%d} -gmt true
+} 0
+
+# Test parsing of ccyyddd
+
+test clock-10.1 {parse ccyyddd} {
+    clock scan {1970 001} -format {%Y %j} -locale en_US_roman -gmt 1
+} 0
+test clock-10.2 {parse ccyyddd} {
+    clock scan {1970 365} -format {%Y %j} -locale en_US_roman -gmt 1
+} 31449600
+test clock-10.3 {parse ccyyddd} {
+    clock scan {1971 001} -format {%Y %j} -locale en_US_roman -gmt 1
+} 31536000
+test clock-10.4 {parse ccyyddd} {
+    clock scan {1971 365} -format {%Y %j} -locale en_US_roman -gmt 1
+} 62985600
+test clock-10.5 {parse ccyyddd} {
+    clock scan {2000 001} -format {%Y %j} -locale en_US_roman -gmt 1
+} 946684800
+test clock-10.6 {parse ccyyddd} {
+    clock scan {2000 365} -format {%Y %j} -locale en_US_roman -gmt 1
+} 978134400
+test clock-10.7 {parse ccyyddd} {
+    clock scan {2001 001} -format {%Y %j} -locale en_US_roman -gmt 1
+} 978307200
+test clock-10.8 {parse ccyyddd} {
+    clock scan {2001 365} -format {%Y %j} -locale en_US_roman -gmt 1
+} 1009756800
+
+
+test clock-10.9 {seconds take precedence over ccyyddd} {
+    list [clock scan {0 2000001} -format {%s %Y%j} -gmt true] \
+	 [clock scan {2000001 0} -format {%Y%j %s} -gmt true]
+} {0 0}
+test clock-10.10 {julian day takes precedence over ccyyddd} {
+    list [clock scan {2440588 2000001} -format {%J %Y%j} -gmt true] \
+	 [clock scan {2000001 2440588} -format {%Y%j %J} -gmt true]
+} {0 0}
+
+# BEGIN testcases11
+
+# Test precedence among yyyymmdd and yyyyddd
+
+test clock-11.1 {precedence of ccyyddd and ccyymmdd} {
+    clock scan 19700101002 -format %Y%m%d%j -gmt 1
+} 86400
+test clock-11.2 {precedence of ccyyddd and ccyymmdd} {
+    clock scan 01197001002 -format %m%Y%d%j -gmt 1
+} 86400
+test clock-11.3 {precedence of ccyyddd and ccyymmdd} {
+    clock scan 01197001002 -format %d%Y%m%j -gmt 1
+} 86400
+test clock-11.4 {precedence of ccyyddd and ccyymmdd} {
+    clock scan 00219700101 -format %j%Y%m%d -gmt 1
+} 0
+test clock-11.5 {precedence of ccyyddd and ccyymmdd} {
+    clock scan 19700100201 -format %Y%m%j%d -gmt 1
+} 0
+test clock-11.6 {precedence of ccyyddd and ccyymmdd} {
+    clock scan 01197000201 -format %m%Y%j%d -gmt 1
+} 0
+test clock-11.7 {precedence of ccyyddd and ccyymmdd} {
+    clock scan 01197000201 -format %d%Y%j%m -gmt 1
+} 0
+test clock-11.8 {precedence of ccyyddd and ccyymmdd} {
+    clock scan 00219700101 -format %j%Y%d%m -gmt 1
+} 0
+test clock-11.9 {precedence of ccyyddd and ccyymmdd} {
+    clock scan 19700101002 -format %Y%d%m%j -gmt 1
+} 86400
+test clock-11.10 {precedence of ccyyddd and ccyymmdd} {
+    clock scan 01011970002 -format %m%d%Y%j -gmt 1
+} 86400
+test clock-11.11 {precedence of ccyyddd and ccyymmdd} {
+    clock scan 01011970002 -format %d%m%Y%j -gmt 1
+} 86400
+test clock-11.12 {precedence of ccyyddd and ccyymmdd} {
+    clock scan 00201197001 -format %j%m%Y%d -gmt 1
+} 0
+test clock-11.13 {precedence of ccyyddd and ccyymmdd} {
+    clock scan 19700100201 -format %Y%d%j%m -gmt 1
+} 0
+test clock-11.14 {precedence of ccyyddd and ccyymmdd} {
+    clock scan 01010021970 -format %m%d%j%Y -gmt 1
+} 86400
+test clock-11.15 {precedence of ccyyddd and ccyymmdd} {
+    clock scan 01010021970 -format %d%m%j%Y -gmt 1
+} 86400
+test clock-11.16 {precedence of ccyyddd and ccyymmdd} {
+    clock scan 00201011970 -format %j%m%d%Y -gmt 1
+} 0
+test clock-11.17 {precedence of ccyyddd and ccyymmdd} {
+    clock scan 19700020101 -format %Y%j%m%d -gmt 1
+} 0
+test clock-11.18 {precedence of ccyyddd and ccyymmdd} {
+    clock scan 01002197001 -format %m%j%Y%d -gmt 1
+} 0
+test clock-11.19 {precedence of ccyyddd and ccyymmdd} {
+    clock scan 01002197001 -format %d%j%Y%m -gmt 1
+} 0
+test clock-11.20 {precedence of ccyyddd and ccyymmdd} {
+    clock scan 00201197001 -format %j%d%Y%m -gmt 1
+} 0
+test clock-11.21 {precedence of ccyyddd and ccyymmdd} {
+    clock scan 19700020101 -format %Y%j%d%m -gmt 1
+} 0
+test clock-11.22 {precedence of ccyyddd and ccyymmdd} {
+    clock scan 01002011970 -format %m%j%d%Y -gmt 1
+} 0
+test clock-11.23 {precedence of ccyyddd and ccyymmdd} {
+    clock scan 01002011970 -format %d%j%m%Y -gmt 1
+} 0
+test clock-11.24 {precedence of ccyyddd and ccyymmdd} {
+    clock scan 00201011970 -format %j%d%m%Y -gmt 1
+} 0
+# END testcases11
+
+# BEGIN testcases12
+
+# Test parsing of ccyyWwwd
+
+test clock-12.1 {parse ccyyWwwd} {
+    clock scan {1970 W01 Fri} -format {%G W%V %a} -locale en_US_roman -gmt 1
+} 86400
+test clock-12.2 {parse ccyyWwwd} {
+    clock scan {1970 W01 Friday} -format {%G W%V %A} -locale en_US_roman -gmt 1
+} 86400
+test clock-12.3 {parse ccyyWwwd} {
+    clock scan {1970 W01 5} -format {%G W%V %u} -locale en_US_roman -gmt 1
+} 86400
+test clock-12.4 {parse ccyyWwwd} {
+    clock scan {1970 W01 5} -format {%G W%V %w} -locale en_US_roman -gmt 1
+} 86400
+test clock-12.5 {parse ccyyWwwd} {
+    clock scan {1970 W01 v} -format {%G W%V %Ou} -locale en_US_roman -gmt 1
+} 86400
+test clock-12.6 {parse ccyyWwwd} {
+    clock scan {1970 W01 v} -format {%G W%V %Ow} -locale en_US_roman -gmt 1
+} 86400
+test clock-12.7 {parse ccyyWwwd} {
+    clock scan {1970 W05 Sat} -format {%G W%V %a} -locale en_US_roman -gmt 1
+} 2592000
+test clock-12.8 {parse ccyyWwwd} {
+    clock scan {1970 W05 Saturday} -format {%G W%V %A} -locale en_US_roman -gmt 1
+} 2592000
+test clock-12.9 {parse ccyyWwwd} {
+    clock scan {1970 W05 6} -format {%G W%V %u} -locale en_US_roman -gmt 1
+} 2592000
+test clock-12.10 {parse ccyyWwwd} {
+    clock scan {1970 W05 6} -format {%G W%V %w} -locale en_US_roman -gmt 1
+} 2592000
+test clock-12.11 {parse ccyyWwwd} {
+    clock scan {1970 W05 vi} -format {%G W%V %Ou} -locale en_US_roman -gmt 1
+} 2592000
+test clock-12.12 {parse ccyyWwwd} {
+    clock scan {1970 W05 vi} -format {%G W%V %Ow} -locale en_US_roman -gmt 1
+} 2592000
+test clock-12.13 {parse ccyyWwwd} {
+    clock scan {1970 W49 Wed} -format {%G W%V %a} -locale en_US_roman -gmt 1
+} 28944000
+test clock-12.14 {parse ccyyWwwd} {
+    clock scan {1970 W49 Wednesday} -format {%G W%V %A} -locale en_US_roman -gmt 1
+} 28944000
+test clock-12.15 {parse ccyyWwwd} {
+    clock scan {1970 W49 3} -format {%G W%V %u} -locale en_US_roman -gmt 1
+} 28944000
+test clock-12.16 {parse ccyyWwwd} {
+    clock scan {1970 W49 3} -format {%G W%V %w} -locale en_US_roman -gmt 1
+} 28944000
+test clock-12.17 {parse ccyyWwwd} {
+    clock scan {1970 W49 iii} -format {%G W%V %Ou} -locale en_US_roman -gmt 1
+} 28944000
+test clock-12.18 {parse ccyyWwwd} {
+    clock scan {1970 W49 iii} -format {%G W%V %Ow} -locale en_US_roman -gmt 1
+} 28944000
+test clock-12.19 {parse ccyyWwwd} {
+    clock scan {1970 W53 Thu} -format {%G W%V %a} -locale en_US_roman -gmt 1
+} 31449600
+test clock-12.20 {parse ccyyWwwd} {
+    clock scan {1970 W53 Thursday} -format {%G W%V %A} -locale en_US_roman -gmt 1
+} 31449600
+test clock-12.21 {parse ccyyWwwd} {
+    clock scan {1970 W53 4} -format {%G W%V %u} -locale en_US_roman -gmt 1
+} 31449600
+test clock-12.22 {parse ccyyWwwd} {
+    clock scan {1970 W53 4} -format {%G W%V %w} -locale en_US_roman -gmt 1
+} 31449600
+test clock-12.23 {parse ccyyWwwd} {
+    clock scan {1970 W53 iv} -format {%G W%V %Ou} -locale en_US_roman -gmt 1
+} 31449600
+test clock-12.24 {parse ccyyWwwd} {
+    clock scan {1970 W53 iv} -format {%G W%V %Ow} -locale en_US_roman -gmt 1
+} 31449600
+test clock-12.25 {parse ccyyWwwd} {
+    clock scan {1970 W53 Sat} -format {%G W%V %a} -locale en_US_roman -gmt 1
+} 31622400
+test clock-12.26 {parse ccyyWwwd} {
+    clock scan {1970 W53 Saturday} -format {%G W%V %A} -locale en_US_roman -gmt 1
+} 31622400
+test clock-12.27 {parse ccyyWwwd} {
+    clock scan {1970 W53 6} -format {%G W%V %u} -locale en_US_roman -gmt 1
+} 31622400
+test clock-12.28 {parse ccyyWwwd} {
+    clock scan {1970 W53 6} -format {%G W%V %w} -locale en_US_roman -gmt 1
+} 31622400
+test clock-12.29 {parse ccyyWwwd} {
+    clock scan {1970 W53 vi} -format {%G W%V %Ou} -locale en_US_roman -gmt 1
+} 31622400
+test clock-12.30 {parse ccyyWwwd} {
+    clock scan {1970 W53 vi} -format {%G W%V %Ow} -locale en_US_roman -gmt 1
+} 31622400
+test clock-12.31 {parse ccyyWwwd} {
+    clock scan {1971 W04 Sun} -format {%G W%V %a} -locale en_US_roman -gmt 1
+} 34128000
+test clock-12.32 {parse ccyyWwwd} {
+    clock scan {1971 W04 Sunday} -format {%G W%V %A} -locale en_US_roman -gmt 1
+} 34128000
+test clock-12.33 {parse ccyyWwwd} {
+    clock scan {1971 W04 7} -format {%G W%V %u} -locale en_US_roman -gmt 1
+} 34128000
+test clock-12.34 {parse ccyyWwwd} {
+    clock scan {1971 W04 0} -format {%G W%V %w} -locale en_US_roman -gmt 1
+} 34128000
+test clock-12.35 {parse ccyyWwwd} {
+    clock scan {1971 W04 vii} -format {%G W%V %Ou} -locale en_US_roman -gmt 1
+} 34128000
+test clock-12.36 {parse ccyyWwwd} {
+    clock scan {1971 W04 ?} -format {%G W%V %Ow} -locale en_US_roman -gmt 1
+} 34128000
+test clock-12.37 {parse ccyyWwwd} {
+    clock scan {1971 W48 Thu} -format {%G W%V %a} -locale en_US_roman -gmt 1
+} 60480000
+test clock-12.38 {parse ccyyWwwd} {
+    clock scan {1971 W48 Thursday} -format {%G W%V %A} -locale en_US_roman -gmt 1
+} 60480000
+test clock-12.39 {parse ccyyWwwd} {
+    clock scan {1971 W48 4} -format {%G W%V %u} -locale en_US_roman -gmt 1
+} 60480000
+test clock-12.40 {parse ccyyWwwd} {
+    clock scan {1971 W48 4} -format {%G W%V %w} -locale en_US_roman -gmt 1
+} 60480000
+test clock-12.41 {parse ccyyWwwd} {
+    clock scan {1971 W48 iv} -format {%G W%V %Ou} -locale en_US_roman -gmt 1
+} 60480000
+test clock-12.42 {parse ccyyWwwd} {
+    clock scan {1971 W48 iv} -format {%G W%V %Ow} -locale en_US_roman -gmt 1
+} 60480000
+test clock-12.43 {parse ccyyWwwd} {
+    clock scan {1971 W52 Fri} -format {%G W%V %a} -locale en_US_roman -gmt 1
+} 62985600
+test clock-12.44 {parse ccyyWwwd} {
+    clock scan {1971 W52 Friday} -format {%G W%V %A} -locale en_US_roman -gmt 1
+} 62985600
+test clock-12.45 {parse ccyyWwwd} {
+    clock scan {1971 W52 5} -format {%G W%V %u} -locale en_US_roman -gmt 1
+} 62985600
+test clock-12.46 {parse ccyyWwwd} {
+    clock scan {1971 W52 5} -format {%G W%V %w} -locale en_US_roman -gmt 1
+} 62985600
+test clock-12.47 {parse ccyyWwwd} {
+    clock scan {1971 W52 v} -format {%G W%V %Ou} -locale en_US_roman -gmt 1
+} 62985600
+test clock-12.48 {parse ccyyWwwd} {
+    clock scan {1971 W52 v} -format {%G W%V %Ow} -locale en_US_roman -gmt 1
+} 62985600
+test clock-12.49 {parse ccyyWwwd} {
+    clock scan {1999 W52 Sun} -format {%G W%V %a} -locale en_US_roman -gmt 1
+} 946771200
+test clock-12.50 {parse ccyyWwwd} {
+    clock scan {1999 W52 Sunday} -format {%G W%V %A} -locale en_US_roman -gmt 1
+} 946771200
+test clock-12.51 {parse ccyyWwwd} {
+    clock scan {1999 W52 7} -format {%G W%V %u} -locale en_US_roman -gmt 1
+} 946771200
+test clock-12.52 {parse ccyyWwwd} {
+    clock scan {1999 W52 0} -format {%G W%V %w} -locale en_US_roman -gmt 1
+} 946771200
+test clock-12.53 {parse ccyyWwwd} {
+    clock scan {1999 W52 vii} -format {%G W%V %Ou} -locale en_US_roman -gmt 1
+} 946771200
+test clock-12.54 {parse ccyyWwwd} {
+    clock scan {1999 W52 ?} -format {%G W%V %Ow} -locale en_US_roman -gmt 1
+} 946771200
+test clock-12.55 {parse ccyyWwwd} {
+    clock scan {2000 W05 Mon} -format {%G W%V %a} -locale en_US_roman -gmt 1
+} 949276800
+test clock-12.56 {parse ccyyWwwd} {
+    clock scan {2000 W05 Monday} -format {%G W%V %A} -locale en_US_roman -gmt 1
+} 949276800
+test clock-12.57 {parse ccyyWwwd} {
+    clock scan {2000 W05 1} -format {%G W%V %u} -locale en_US_roman -gmt 1
+} 949276800
+test clock-12.58 {parse ccyyWwwd} {
+    clock scan {2000 W05 1} -format {%G W%V %w} -locale en_US_roman -gmt 1
+} 949276800
+test clock-12.59 {parse ccyyWwwd} {
+    clock scan {2000 W05 i} -format {%G W%V %Ou} -locale en_US_roman -gmt 1
+} 949276800
+test clock-12.60 {parse ccyyWwwd} {
+    clock scan {2000 W05 i} -format {%G W%V %Ow} -locale en_US_roman -gmt 1
+} 949276800
+test clock-12.61 {parse ccyyWwwd} {
+    clock scan {2000 W48 Sat} -format {%G W%V %a} -locale en_US_roman -gmt 1
+} 975715200
+test clock-12.62 {parse ccyyWwwd} {
+    clock scan {2000 W48 Saturday} -format {%G W%V %A} -locale en_US_roman -gmt 1
+} 975715200
+test clock-12.63 {parse ccyyWwwd} {
+    clock scan {2000 W48 6} -format {%G W%V %u} -locale en_US_roman -gmt 1
+} 975715200
+test clock-12.64 {parse ccyyWwwd} {
+    clock scan {2000 W48 6} -format {%G W%V %w} -locale en_US_roman -gmt 1
+} 975715200
+test clock-12.65 {parse ccyyWwwd} {
+    clock scan {2000 W48 vi} -format {%G W%V %Ou} -locale en_US_roman -gmt 1
+} 975715200
+test clock-12.66 {parse ccyyWwwd} {
+    clock scan {2000 W48 vi} -format {%G W%V %Ow} -locale en_US_roman -gmt 1
+} 975715200
+test clock-12.67 {parse ccyyWwwd} {
+    clock scan {2000 W52 Sun} -format {%G W%V %a} -locale en_US_roman -gmt 1
+} 978220800
+test clock-12.68 {parse ccyyWwwd} {
+    clock scan {2000 W52 Sunday} -format {%G W%V %A} -locale en_US_roman -gmt 1
+} 978220800
+test clock-12.69 {parse ccyyWwwd} {
+    clock scan {2000 W52 7} -format {%G W%V %u} -locale en_US_roman -gmt 1
+} 978220800
+test clock-12.70 {parse ccyyWwwd} {
+    clock scan {2000 W52 0} -format {%G W%V %w} -locale en_US_roman -gmt 1
+} 978220800
+test clock-12.71 {parse ccyyWwwd} {
+    clock scan {2000 W52 vii} -format {%G W%V %Ou} -locale en_US_roman -gmt 1
+} 978220800
+test clock-12.72 {parse ccyyWwwd} {
+    clock scan {2000 W52 ?} -format {%G W%V %Ow} -locale en_US_roman -gmt 1
+} 978220800
+test clock-12.73 {parse ccyyWwwd} {
+    clock scan {2001 W01 Tue} -format {%G W%V %a} -locale en_US_roman -gmt 1
+} 978393600
+test clock-12.74 {parse ccyyWwwd} {
+    clock scan {2001 W01 Tuesday} -format {%G W%V %A} -locale en_US_roman -gmt 1
+} 978393600
+test clock-12.75 {parse ccyyWwwd} {
+    clock scan {2001 W01 2} -format {%G W%V %u} -locale en_US_roman -gmt 1
+} 978393600
+test clock-12.76 {parse ccyyWwwd} {
+    clock scan {2001 W01 2} -format {%G W%V %w} -locale en_US_roman -gmt 1
+} 978393600
+test clock-12.77 {parse ccyyWwwd} {
+    clock scan {2001 W01 ii} -format {%G W%V %Ou} -locale en_US_roman -gmt 1
+} 978393600
+test clock-12.78 {parse ccyyWwwd} {
+    clock scan {2001 W01 ii} -format {%G W%V %Ow} -locale en_US_roman -gmt 1
+} 978393600
+test clock-12.79 {parse ccyyWwwd} {
+    clock scan {2001 W05 Wed} -format {%G W%V %a} -locale en_US_roman -gmt 1
+} 980899200
+test clock-12.80 {parse ccyyWwwd} {
+    clock scan {2001 W05 Wednesday} -format {%G W%V %A} -locale en_US_roman -gmt 1
+} 980899200
+test clock-12.81 {parse ccyyWwwd} {
+    clock scan {2001 W05 3} -format {%G W%V %u} -locale en_US_roman -gmt 1
+} 980899200
+test clock-12.82 {parse ccyyWwwd} {
+    clock scan {2001 W05 3} -format {%G W%V %w} -locale en_US_roman -gmt 1
+} 980899200
+test clock-12.83 {parse ccyyWwwd} {
+    clock scan {2001 W05 iii} -format {%G W%V %Ou} -locale en_US_roman -gmt 1
+} 980899200
+test clock-12.84 {parse ccyyWwwd} {
+    clock scan {2001 W05 iii} -format {%G W%V %Ow} -locale en_US_roman -gmt 1
+} 980899200
+test clock-12.85 {parse ccyyWwwd} {
+    clock scan {2001 W48 Sun} -format {%G W%V %a} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-12.86 {parse ccyyWwwd} {
+    clock scan {2001 W48 Sunday} -format {%G W%V %A} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-12.87 {parse ccyyWwwd} {
+    clock scan {2001 W48 7} -format {%G W%V %u} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-12.88 {parse ccyyWwwd} {
+    clock scan {2001 W48 0} -format {%G W%V %w} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-12.89 {parse ccyyWwwd} {
+    clock scan {2001 W48 vii} -format {%G W%V %Ou} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-12.90 {parse ccyyWwwd} {
+    clock scan {2001 W48 ?} -format {%G W%V %Ow} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-12.91 {parse ccyyWwwd} {
+    clock scan {2002 W01 Mon} -format {%G W%V %a} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-12.92 {parse ccyyWwwd} {
+    clock scan {2002 W01 Monday} -format {%G W%V %A} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-12.93 {parse ccyyWwwd} {
+    clock scan {2002 W01 1} -format {%G W%V %u} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-12.94 {parse ccyyWwwd} {
+    clock scan {2002 W01 1} -format {%G W%V %w} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-12.95 {parse ccyyWwwd} {
+    clock scan {2002 W01 i} -format {%G W%V %Ou} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-12.96 {parse ccyyWwwd} {
+    clock scan {2002 W01 i} -format {%G W%V %Ow} -locale en_US_roman -gmt 1
+} 1009756800
+# END testcases12
+
+test clock-13.1 {test that %s takes precedence over ccyyWwwd} {
+    list [clock scan {0 2000W011} -format {%s %GW%V%u} -gmt true] \
+	 [clock scan {2000W011 0} -format {%GW%V%u %s} -gmt true]
+} {0 0}
+test clock-13.2 {test that %J takes precedence over ccyyWwwd} {
+    list [clock scan {2440588 2000W011} -format {%J %GW%V%u} -gmt true] \
+	 [clock scan {2000W011 2440588} -format {%GW%V%u %J} -gmt true]
+} {0 0}
+test clock-13.3 {invalid weekday} {
+    catch {clock scan 2000W018 -format %GW%V%u -gmt true} result
+    list $result $::errorCode
+} {{day of week is greater than 7} {CLOCK badDayOfWeek}}
+test clock-13.4 {invalid weekday} {
+    catch {
+	clock scan {2000 W01 viii} \
+	    -format {%G W%V %Ou} -gmt true -locale en_US_roman
+    } result
+    list $result $::errorCode
+} {{day of week is greater than 7} {CLOCK badDayOfWeek}}
+
+# BEGIN testcases14
+
+# Test parsing of yymmdd
+
+test clock-14.1 {parse yymmdd} {
+    clock scan {38 Jan 02} -format {%y %b %d} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.2 {parse yymmdd} {
+    clock scan {38 Jan ii} -format {%y %b %Od} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.3 {parse yymmdd} {
+    clock scan {38 Jan  2} -format {%y %b %e} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.4 {parse yymmdd} {
+    clock scan {38 Jan ii} -format {%y %b %Oe} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.5 {parse yymmdd} {
+    clock scan {38 January 02} -format {%y %B %d} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.6 {parse yymmdd} {
+    clock scan {38 January ii} -format {%y %B %Od} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.7 {parse yymmdd} {
+    clock scan {38 January  2} -format {%y %B %e} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.8 {parse yymmdd} {
+    clock scan {38 January ii} -format {%y %B %Oe} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.9 {parse yymmdd} {
+    clock scan {38 Jan 02} -format {%y %h %d} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.10 {parse yymmdd} {
+    clock scan {38 Jan ii} -format {%y %h %Od} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.11 {parse yymmdd} {
+    clock scan {38 Jan  2} -format {%y %h %e} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.12 {parse yymmdd} {
+    clock scan {38 Jan ii} -format {%y %h %Oe} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.13 {parse yymmdd} {
+    clock scan {38 01 02} -format {%y %m %d} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.14 {parse yymmdd} {
+    clock scan {38 01 ii} -format {%y %m %Od} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.15 {parse yymmdd} {
+    clock scan {38 01  2} -format {%y %m %e} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.16 {parse yymmdd} {
+    clock scan {38 01 ii} -format {%y %m %Oe} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.17 {parse yymmdd} {
+    clock scan {38 i 02} -format {%y %Om %d} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.18 {parse yymmdd} {
+    clock scan {38 i ii} -format {%y %Om %Od} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.19 {parse yymmdd} {
+    clock scan {38 i  2} -format {%y %Om %e} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.20 {parse yymmdd} {
+    clock scan {38 i ii} -format {%y %Om %Oe} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.21 {parse yymmdd} {
+    clock scan {38  1 02} -format {%y %N %d} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.22 {parse yymmdd} {
+    clock scan {38  1 ii} -format {%y %N %Od} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.23 {parse yymmdd} {
+    clock scan {38  1  2} -format {%y %N %e} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.24 {parse yymmdd} {
+    clock scan {38  1 ii} -format {%y %N %Oe} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.25 {parse yymmdd} {
+    clock scan {xxxviii Jan 02} -format {%Oy %b %d} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.26 {parse yymmdd} {
+    clock scan {xxxviii Jan ii} -format {%Oy %b %Od} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.27 {parse yymmdd} {
+    clock scan {xxxviii Jan  2} -format {%Oy %b %e} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.28 {parse yymmdd} {
+    clock scan {xxxviii Jan ii} -format {%Oy %b %Oe} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.29 {parse yymmdd} {
+    clock scan {xxxviii January 02} -format {%Oy %B %d} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.30 {parse yymmdd} {
+    clock scan {xxxviii January ii} -format {%Oy %B %Od} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.31 {parse yymmdd} {
+    clock scan {xxxviii January  2} -format {%Oy %B %e} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.32 {parse yymmdd} {
+    clock scan {xxxviii January ii} -format {%Oy %B %Oe} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.33 {parse yymmdd} {
+    clock scan {xxxviii Jan 02} -format {%Oy %h %d} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.34 {parse yymmdd} {
+    clock scan {xxxviii Jan ii} -format {%Oy %h %Od} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.35 {parse yymmdd} {
+    clock scan {xxxviii Jan  2} -format {%Oy %h %e} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.36 {parse yymmdd} {
+    clock scan {xxxviii Jan ii} -format {%Oy %h %Oe} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.37 {parse yymmdd} {
+    clock scan {xxxviii 01 02} -format {%Oy %m %d} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.38 {parse yymmdd} {
+    clock scan {xxxviii 01 ii} -format {%Oy %m %Od} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.39 {parse yymmdd} {
+    clock scan {xxxviii 01  2} -format {%Oy %m %e} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.40 {parse yymmdd} {
+    clock scan {xxxviii 01 ii} -format {%Oy %m %Oe} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.41 {parse yymmdd} {
+    clock scan {xxxviii i 02} -format {%Oy %Om %d} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.42 {parse yymmdd} {
+    clock scan {xxxviii i ii} -format {%Oy %Om %Od} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.43 {parse yymmdd} {
+    clock scan {xxxviii i  2} -format {%Oy %Om %e} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.44 {parse yymmdd} {
+    clock scan {xxxviii i ii} -format {%Oy %Om %Oe} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.45 {parse yymmdd} {
+    clock scan {xxxviii  1 02} -format {%Oy %N %d} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.46 {parse yymmdd} {
+    clock scan {xxxviii  1 ii} -format {%Oy %N %Od} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.47 {parse yymmdd} {
+    clock scan {xxxviii  1  2} -format {%Oy %N %e} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.48 {parse yymmdd} {
+    clock scan {xxxviii  1 ii} -format {%Oy %N %Oe} -locale en_US_roman -gmt 1
+} -1009756800
+test clock-14.49 {parse yymmdd} {
+    clock scan {38 Jan 31} -format {%y %b %d} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.50 {parse yymmdd} {
+    clock scan {38 Jan xxxi} -format {%y %b %Od} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.51 {parse yymmdd} {
+    clock scan {38 Jan 31} -format {%y %b %e} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.52 {parse yymmdd} {
+    clock scan {38 Jan xxxi} -format {%y %b %Oe} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.53 {parse yymmdd} {
+    clock scan {38 January 31} -format {%y %B %d} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.54 {parse yymmdd} {
+    clock scan {38 January xxxi} -format {%y %B %Od} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.55 {parse yymmdd} {
+    clock scan {38 January 31} -format {%y %B %e} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.56 {parse yymmdd} {
+    clock scan {38 January xxxi} -format {%y %B %Oe} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.57 {parse yymmdd} {
+    clock scan {38 Jan 31} -format {%y %h %d} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.58 {parse yymmdd} {
+    clock scan {38 Jan xxxi} -format {%y %h %Od} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.59 {parse yymmdd} {
+    clock scan {38 Jan 31} -format {%y %h %e} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.60 {parse yymmdd} {
+    clock scan {38 Jan xxxi} -format {%y %h %Oe} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.61 {parse yymmdd} {
+    clock scan {38 01 31} -format {%y %m %d} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.62 {parse yymmdd} {
+    clock scan {38 01 xxxi} -format {%y %m %Od} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.63 {parse yymmdd} {
+    clock scan {38 01 31} -format {%y %m %e} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.64 {parse yymmdd} {
+    clock scan {38 01 xxxi} -format {%y %m %Oe} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.65 {parse yymmdd} {
+    clock scan {38 i 31} -format {%y %Om %d} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.66 {parse yymmdd} {
+    clock scan {38 i xxxi} -format {%y %Om %Od} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.67 {parse yymmdd} {
+    clock scan {38 i 31} -format {%y %Om %e} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.68 {parse yymmdd} {
+    clock scan {38 i xxxi} -format {%y %Om %Oe} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.69 {parse yymmdd} {
+    clock scan {38  1 31} -format {%y %N %d} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.70 {parse yymmdd} {
+    clock scan {38  1 xxxi} -format {%y %N %Od} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.71 {parse yymmdd} {
+    clock scan {38  1 31} -format {%y %N %e} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.72 {parse yymmdd} {
+    clock scan {38  1 xxxi} -format {%y %N %Oe} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.73 {parse yymmdd} {
+    clock scan {xxxviii Jan 31} -format {%Oy %b %d} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.74 {parse yymmdd} {
+    clock scan {xxxviii Jan xxxi} -format {%Oy %b %Od} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.75 {parse yymmdd} {
+    clock scan {xxxviii Jan 31} -format {%Oy %b %e} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.76 {parse yymmdd} {
+    clock scan {xxxviii Jan xxxi} -format {%Oy %b %Oe} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.77 {parse yymmdd} {
+    clock scan {xxxviii January 31} -format {%Oy %B %d} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.78 {parse yymmdd} {
+    clock scan {xxxviii January xxxi} -format {%Oy %B %Od} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.79 {parse yymmdd} {
+    clock scan {xxxviii January 31} -format {%Oy %B %e} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.80 {parse yymmdd} {
+    clock scan {xxxviii January xxxi} -format {%Oy %B %Oe} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.81 {parse yymmdd} {
+    clock scan {xxxviii Jan 31} -format {%Oy %h %d} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.82 {parse yymmdd} {
+    clock scan {xxxviii Jan xxxi} -format {%Oy %h %Od} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.83 {parse yymmdd} {
+    clock scan {xxxviii Jan 31} -format {%Oy %h %e} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.84 {parse yymmdd} {
+    clock scan {xxxviii Jan xxxi} -format {%Oy %h %Oe} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.85 {parse yymmdd} {
+    clock scan {xxxviii 01 31} -format {%Oy %m %d} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.86 {parse yymmdd} {
+    clock scan {xxxviii 01 xxxi} -format {%Oy %m %Od} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.87 {parse yymmdd} {
+    clock scan {xxxviii 01 31} -format {%Oy %m %e} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.88 {parse yymmdd} {
+    clock scan {xxxviii 01 xxxi} -format {%Oy %m %Oe} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.89 {parse yymmdd} {
+    clock scan {xxxviii i 31} -format {%Oy %Om %d} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.90 {parse yymmdd} {
+    clock scan {xxxviii i xxxi} -format {%Oy %Om %Od} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.91 {parse yymmdd} {
+    clock scan {xxxviii i 31} -format {%Oy %Om %e} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.92 {parse yymmdd} {
+    clock scan {xxxviii i xxxi} -format {%Oy %Om %Oe} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.93 {parse yymmdd} {
+    clock scan {xxxviii  1 31} -format {%Oy %N %d} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.94 {parse yymmdd} {
+    clock scan {xxxviii  1 xxxi} -format {%Oy %N %Od} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.95 {parse yymmdd} {
+    clock scan {xxxviii  1 31} -format {%Oy %N %e} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.96 {parse yymmdd} {
+    clock scan {xxxviii  1 xxxi} -format {%Oy %N %Oe} -locale en_US_roman -gmt 1
+} -1007251200
+test clock-14.97 {parse yymmdd} {
+    clock scan {38 Dec 02} -format {%y %b %d} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.98 {parse yymmdd} {
+    clock scan {38 Dec ii} -format {%y %b %Od} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.99 {parse yymmdd} {
+    clock scan {38 Dec  2} -format {%y %b %e} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.100 {parse yymmdd} {
+    clock scan {38 Dec ii} -format {%y %b %Oe} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.101 {parse yymmdd} {
+    clock scan {38 December 02} -format {%y %B %d} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.102 {parse yymmdd} {
+    clock scan {38 December ii} -format {%y %B %Od} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.103 {parse yymmdd} {
+    clock scan {38 December  2} -format {%y %B %e} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.104 {parse yymmdd} {
+    clock scan {38 December ii} -format {%y %B %Oe} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.105 {parse yymmdd} {
+    clock scan {38 Dec 02} -format {%y %h %d} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.106 {parse yymmdd} {
+    clock scan {38 Dec ii} -format {%y %h %Od} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.107 {parse yymmdd} {
+    clock scan {38 Dec  2} -format {%y %h %e} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.108 {parse yymmdd} {
+    clock scan {38 Dec ii} -format {%y %h %Oe} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.109 {parse yymmdd} {
+    clock scan {38 12 02} -format {%y %m %d} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.110 {parse yymmdd} {
+    clock scan {38 12 ii} -format {%y %m %Od} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.111 {parse yymmdd} {
+    clock scan {38 12  2} -format {%y %m %e} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.112 {parse yymmdd} {
+    clock scan {38 12 ii} -format {%y %m %Oe} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.113 {parse yymmdd} {
+    clock scan {38 xii 02} -format {%y %Om %d} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.114 {parse yymmdd} {
+    clock scan {38 xii ii} -format {%y %Om %Od} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.115 {parse yymmdd} {
+    clock scan {38 xii  2} -format {%y %Om %e} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.116 {parse yymmdd} {
+    clock scan {38 xii ii} -format {%y %Om %Oe} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.117 {parse yymmdd} {
+    clock scan {38 12 02} -format {%y %N %d} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.118 {parse yymmdd} {
+    clock scan {38 12 ii} -format {%y %N %Od} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.119 {parse yymmdd} {
+    clock scan {38 12  2} -format {%y %N %e} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.120 {parse yymmdd} {
+    clock scan {38 12 ii} -format {%y %N %Oe} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.121 {parse yymmdd} {
+    clock scan {xxxviii Dec 02} -format {%Oy %b %d} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.122 {parse yymmdd} {
+    clock scan {xxxviii Dec ii} -format {%Oy %b %Od} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.123 {parse yymmdd} {
+    clock scan {xxxviii Dec  2} -format {%Oy %b %e} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.124 {parse yymmdd} {
+    clock scan {xxxviii Dec ii} -format {%Oy %b %Oe} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.125 {parse yymmdd} {
+    clock scan {xxxviii December 02} -format {%Oy %B %d} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.126 {parse yymmdd} {
+    clock scan {xxxviii December ii} -format {%Oy %B %Od} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.127 {parse yymmdd} {
+    clock scan {xxxviii December  2} -format {%Oy %B %e} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.128 {parse yymmdd} {
+    clock scan {xxxviii December ii} -format {%Oy %B %Oe} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.129 {parse yymmdd} {
+    clock scan {xxxviii Dec 02} -format {%Oy %h %d} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.130 {parse yymmdd} {
+    clock scan {xxxviii Dec ii} -format {%Oy %h %Od} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.131 {parse yymmdd} {
+    clock scan {xxxviii Dec  2} -format {%Oy %h %e} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.132 {parse yymmdd} {
+    clock scan {xxxviii Dec ii} -format {%Oy %h %Oe} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.133 {parse yymmdd} {
+    clock scan {xxxviii 12 02} -format {%Oy %m %d} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.134 {parse yymmdd} {
+    clock scan {xxxviii 12 ii} -format {%Oy %m %Od} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.135 {parse yymmdd} {
+    clock scan {xxxviii 12  2} -format {%Oy %m %e} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.136 {parse yymmdd} {
+    clock scan {xxxviii 12 ii} -format {%Oy %m %Oe} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.137 {parse yymmdd} {
+    clock scan {xxxviii xii 02} -format {%Oy %Om %d} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.138 {parse yymmdd} {
+    clock scan {xxxviii xii ii} -format {%Oy %Om %Od} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.139 {parse yymmdd} {
+    clock scan {xxxviii xii  2} -format {%Oy %Om %e} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.140 {parse yymmdd} {
+    clock scan {xxxviii xii ii} -format {%Oy %Om %Oe} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.141 {parse yymmdd} {
+    clock scan {xxxviii 12 02} -format {%Oy %N %d} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.142 {parse yymmdd} {
+    clock scan {xxxviii 12 ii} -format {%Oy %N %Od} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.143 {parse yymmdd} {
+    clock scan {xxxviii 12  2} -format {%Oy %N %e} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.144 {parse yymmdd} {
+    clock scan {xxxviii 12 ii} -format {%Oy %N %Oe} -locale en_US_roman -gmt 1
+} -980899200
+test clock-14.145 {parse yymmdd} {
+    clock scan {38 Dec 31} -format {%y %b %d} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.146 {parse yymmdd} {
+    clock scan {38 Dec xxxi} -format {%y %b %Od} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.147 {parse yymmdd} {
+    clock scan {38 Dec 31} -format {%y %b %e} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.148 {parse yymmdd} {
+    clock scan {38 Dec xxxi} -format {%y %b %Oe} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.149 {parse yymmdd} {
+    clock scan {38 December 31} -format {%y %B %d} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.150 {parse yymmdd} {
+    clock scan {38 December xxxi} -format {%y %B %Od} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.151 {parse yymmdd} {
+    clock scan {38 December 31} -format {%y %B %e} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.152 {parse yymmdd} {
+    clock scan {38 December xxxi} -format {%y %B %Oe} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.153 {parse yymmdd} {
+    clock scan {38 Dec 31} -format {%y %h %d} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.154 {parse yymmdd} {
+    clock scan {38 Dec xxxi} -format {%y %h %Od} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.155 {parse yymmdd} {
+    clock scan {38 Dec 31} -format {%y %h %e} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.156 {parse yymmdd} {
+    clock scan {38 Dec xxxi} -format {%y %h %Oe} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.157 {parse yymmdd} {
+    clock scan {38 12 31} -format {%y %m %d} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.158 {parse yymmdd} {
+    clock scan {38 12 xxxi} -format {%y %m %Od} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.159 {parse yymmdd} {
+    clock scan {38 12 31} -format {%y %m %e} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.160 {parse yymmdd} {
+    clock scan {38 12 xxxi} -format {%y %m %Oe} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.161 {parse yymmdd} {
+    clock scan {38 xii 31} -format {%y %Om %d} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.162 {parse yymmdd} {
+    clock scan {38 xii xxxi} -format {%y %Om %Od} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.163 {parse yymmdd} {
+    clock scan {38 xii 31} -format {%y %Om %e} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.164 {parse yymmdd} {
+    clock scan {38 xii xxxi} -format {%y %Om %Oe} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.165 {parse yymmdd} {
+    clock scan {38 12 31} -format {%y %N %d} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.166 {parse yymmdd} {
+    clock scan {38 12 xxxi} -format {%y %N %Od} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.167 {parse yymmdd} {
+    clock scan {38 12 31} -format {%y %N %e} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.168 {parse yymmdd} {
+    clock scan {38 12 xxxi} -format {%y %N %Oe} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.169 {parse yymmdd} {
+    clock scan {xxxviii Dec 31} -format {%Oy %b %d} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.170 {parse yymmdd} {
+    clock scan {xxxviii Dec xxxi} -format {%Oy %b %Od} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.171 {parse yymmdd} {
+    clock scan {xxxviii Dec 31} -format {%Oy %b %e} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.172 {parse yymmdd} {
+    clock scan {xxxviii Dec xxxi} -format {%Oy %b %Oe} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.173 {parse yymmdd} {
+    clock scan {xxxviii December 31} -format {%Oy %B %d} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.174 {parse yymmdd} {
+    clock scan {xxxviii December xxxi} -format {%Oy %B %Od} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.175 {parse yymmdd} {
+    clock scan {xxxviii December 31} -format {%Oy %B %e} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.176 {parse yymmdd} {
+    clock scan {xxxviii December xxxi} -format {%Oy %B %Oe} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.177 {parse yymmdd} {
+    clock scan {xxxviii Dec 31} -format {%Oy %h %d} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.178 {parse yymmdd} {
+    clock scan {xxxviii Dec xxxi} -format {%Oy %h %Od} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.179 {parse yymmdd} {
+    clock scan {xxxviii Dec 31} -format {%Oy %h %e} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.180 {parse yymmdd} {
+    clock scan {xxxviii Dec xxxi} -format {%Oy %h %Oe} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.181 {parse yymmdd} {
+    clock scan {xxxviii 12 31} -format {%Oy %m %d} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.182 {parse yymmdd} {
+    clock scan {xxxviii 12 xxxi} -format {%Oy %m %Od} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.183 {parse yymmdd} {
+    clock scan {xxxviii 12 31} -format {%Oy %m %e} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.184 {parse yymmdd} {
+    clock scan {xxxviii 12 xxxi} -format {%Oy %m %Oe} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.185 {parse yymmdd} {
+    clock scan {xxxviii xii 31} -format {%Oy %Om %d} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.186 {parse yymmdd} {
+    clock scan {xxxviii xii xxxi} -format {%Oy %Om %Od} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.187 {parse yymmdd} {
+    clock scan {xxxviii xii 31} -format {%Oy %Om %e} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.188 {parse yymmdd} {
+    clock scan {xxxviii xii xxxi} -format {%Oy %Om %Oe} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.189 {parse yymmdd} {
+    clock scan {xxxviii 12 31} -format {%Oy %N %d} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.190 {parse yymmdd} {
+    clock scan {xxxviii 12 xxxi} -format {%Oy %N %Od} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.191 {parse yymmdd} {
+    clock scan {xxxviii 12 31} -format {%Oy %N %e} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.192 {parse yymmdd} {
+    clock scan {xxxviii 12 xxxi} -format {%Oy %N %Oe} -locale en_US_roman -gmt 1
+} -978393600
+test clock-14.193 {parse yymmdd} {
+    clock scan {70 Jan 02} -format {%y %b %d} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.194 {parse yymmdd} {
+    clock scan {70 Jan ii} -format {%y %b %Od} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.195 {parse yymmdd} {
+    clock scan {70 Jan  2} -format {%y %b %e} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.196 {parse yymmdd} {
+    clock scan {70 Jan ii} -format {%y %b %Oe} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.197 {parse yymmdd} {
+    clock scan {70 January 02} -format {%y %B %d} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.198 {parse yymmdd} {
+    clock scan {70 January ii} -format {%y %B %Od} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.199 {parse yymmdd} {
+    clock scan {70 January  2} -format {%y %B %e} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.200 {parse yymmdd} {
+    clock scan {70 January ii} -format {%y %B %Oe} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.201 {parse yymmdd} {
+    clock scan {70 Jan 02} -format {%y %h %d} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.202 {parse yymmdd} {
+    clock scan {70 Jan ii} -format {%y %h %Od} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.203 {parse yymmdd} {
+    clock scan {70 Jan  2} -format {%y %h %e} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.204 {parse yymmdd} {
+    clock scan {70 Jan ii} -format {%y %h %Oe} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.205 {parse yymmdd} {
+    clock scan {70 01 02} -format {%y %m %d} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.206 {parse yymmdd} {
+    clock scan {70 01 ii} -format {%y %m %Od} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.207 {parse yymmdd} {
+    clock scan {70 01  2} -format {%y %m %e} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.208 {parse yymmdd} {
+    clock scan {70 01 ii} -format {%y %m %Oe} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.209 {parse yymmdd} {
+    clock scan {70 i 02} -format {%y %Om %d} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.210 {parse yymmdd} {
+    clock scan {70 i ii} -format {%y %Om %Od} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.211 {parse yymmdd} {
+    clock scan {70 i  2} -format {%y %Om %e} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.212 {parse yymmdd} {
+    clock scan {70 i ii} -format {%y %Om %Oe} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.213 {parse yymmdd} {
+    clock scan {70  1 02} -format {%y %N %d} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.214 {parse yymmdd} {
+    clock scan {70  1 ii} -format {%y %N %Od} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.215 {parse yymmdd} {
+    clock scan {70  1  2} -format {%y %N %e} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.216 {parse yymmdd} {
+    clock scan {70  1 ii} -format {%y %N %Oe} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.217 {parse yymmdd} {
+    clock scan {lxx Jan 02} -format {%Oy %b %d} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.218 {parse yymmdd} {
+    clock scan {lxx Jan ii} -format {%Oy %b %Od} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.219 {parse yymmdd} {
+    clock scan {lxx Jan  2} -format {%Oy %b %e} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.220 {parse yymmdd} {
+    clock scan {lxx Jan ii} -format {%Oy %b %Oe} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.221 {parse yymmdd} {
+    clock scan {lxx January 02} -format {%Oy %B %d} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.222 {parse yymmdd} {
+    clock scan {lxx January ii} -format {%Oy %B %Od} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.223 {parse yymmdd} {
+    clock scan {lxx January  2} -format {%Oy %B %e} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.224 {parse yymmdd} {
+    clock scan {lxx January ii} -format {%Oy %B %Oe} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.225 {parse yymmdd} {
+    clock scan {lxx Jan 02} -format {%Oy %h %d} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.226 {parse yymmdd} {
+    clock scan {lxx Jan ii} -format {%Oy %h %Od} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.227 {parse yymmdd} {
+    clock scan {lxx Jan  2} -format {%Oy %h %e} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.228 {parse yymmdd} {
+    clock scan {lxx Jan ii} -format {%Oy %h %Oe} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.229 {parse yymmdd} {
+    clock scan {lxx 01 02} -format {%Oy %m %d} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.230 {parse yymmdd} {
+    clock scan {lxx 01 ii} -format {%Oy %m %Od} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.231 {parse yymmdd} {
+    clock scan {lxx 01  2} -format {%Oy %m %e} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.232 {parse yymmdd} {
+    clock scan {lxx 01 ii} -format {%Oy %m %Oe} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.233 {parse yymmdd} {
+    clock scan {lxx i 02} -format {%Oy %Om %d} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.234 {parse yymmdd} {
+    clock scan {lxx i ii} -format {%Oy %Om %Od} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.235 {parse yymmdd} {
+    clock scan {lxx i  2} -format {%Oy %Om %e} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.236 {parse yymmdd} {
+    clock scan {lxx i ii} -format {%Oy %Om %Oe} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.237 {parse yymmdd} {
+    clock scan {lxx  1 02} -format {%Oy %N %d} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.238 {parse yymmdd} {
+    clock scan {lxx  1 ii} -format {%Oy %N %Od} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.239 {parse yymmdd} {
+    clock scan {lxx  1  2} -format {%Oy %N %e} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.240 {parse yymmdd} {
+    clock scan {lxx  1 ii} -format {%Oy %N %Oe} -locale en_US_roman -gmt 1
+} 86400
+test clock-14.241 {parse yymmdd} {
+    clock scan {70 Jan 31} -format {%y %b %d} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.242 {parse yymmdd} {
+    clock scan {70 Jan xxxi} -format {%y %b %Od} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.243 {parse yymmdd} {
+    clock scan {70 Jan 31} -format {%y %b %e} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.244 {parse yymmdd} {
+    clock scan {70 Jan xxxi} -format {%y %b %Oe} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.245 {parse yymmdd} {
+    clock scan {70 January 31} -format {%y %B %d} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.246 {parse yymmdd} {
+    clock scan {70 January xxxi} -format {%y %B %Od} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.247 {parse yymmdd} {
+    clock scan {70 January 31} -format {%y %B %e} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.248 {parse yymmdd} {
+    clock scan {70 January xxxi} -format {%y %B %Oe} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.249 {parse yymmdd} {
+    clock scan {70 Jan 31} -format {%y %h %d} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.250 {parse yymmdd} {
+    clock scan {70 Jan xxxi} -format {%y %h %Od} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.251 {parse yymmdd} {
+    clock scan {70 Jan 31} -format {%y %h %e} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.252 {parse yymmdd} {
+    clock scan {70 Jan xxxi} -format {%y %h %Oe} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.253 {parse yymmdd} {
+    clock scan {70 01 31} -format {%y %m %d} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.254 {parse yymmdd} {
+    clock scan {70 01 xxxi} -format {%y %m %Od} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.255 {parse yymmdd} {
+    clock scan {70 01 31} -format {%y %m %e} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.256 {parse yymmdd} {
+    clock scan {70 01 xxxi} -format {%y %m %Oe} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.257 {parse yymmdd} {
+    clock scan {70 i 31} -format {%y %Om %d} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.258 {parse yymmdd} {
+    clock scan {70 i xxxi} -format {%y %Om %Od} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.259 {parse yymmdd} {
+    clock scan {70 i 31} -format {%y %Om %e} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.260 {parse yymmdd} {
+    clock scan {70 i xxxi} -format {%y %Om %Oe} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.261 {parse yymmdd} {
+    clock scan {70  1 31} -format {%y %N %d} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.262 {parse yymmdd} {
+    clock scan {70  1 xxxi} -format {%y %N %Od} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.263 {parse yymmdd} {
+    clock scan {70  1 31} -format {%y %N %e} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.264 {parse yymmdd} {
+    clock scan {70  1 xxxi} -format {%y %N %Oe} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.265 {parse yymmdd} {
+    clock scan {lxx Jan 31} -format {%Oy %b %d} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.266 {parse yymmdd} {
+    clock scan {lxx Jan xxxi} -format {%Oy %b %Od} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.267 {parse yymmdd} {
+    clock scan {lxx Jan 31} -format {%Oy %b %e} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.268 {parse yymmdd} {
+    clock scan {lxx Jan xxxi} -format {%Oy %b %Oe} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.269 {parse yymmdd} {
+    clock scan {lxx January 31} -format {%Oy %B %d} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.270 {parse yymmdd} {
+    clock scan {lxx January xxxi} -format {%Oy %B %Od} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.271 {parse yymmdd} {
+    clock scan {lxx January 31} -format {%Oy %B %e} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.272 {parse yymmdd} {
+    clock scan {lxx January xxxi} -format {%Oy %B %Oe} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.273 {parse yymmdd} {
+    clock scan {lxx Jan 31} -format {%Oy %h %d} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.274 {parse yymmdd} {
+    clock scan {lxx Jan xxxi} -format {%Oy %h %Od} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.275 {parse yymmdd} {
+    clock scan {lxx Jan 31} -format {%Oy %h %e} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.276 {parse yymmdd} {
+    clock scan {lxx Jan xxxi} -format {%Oy %h %Oe} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.277 {parse yymmdd} {
+    clock scan {lxx 01 31} -format {%Oy %m %d} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.278 {parse yymmdd} {
+    clock scan {lxx 01 xxxi} -format {%Oy %m %Od} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.279 {parse yymmdd} {
+    clock scan {lxx 01 31} -format {%Oy %m %e} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.280 {parse yymmdd} {
+    clock scan {lxx 01 xxxi} -format {%Oy %m %Oe} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.281 {parse yymmdd} {
+    clock scan {lxx i 31} -format {%Oy %Om %d} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.282 {parse yymmdd} {
+    clock scan {lxx i xxxi} -format {%Oy %Om %Od} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.283 {parse yymmdd} {
+    clock scan {lxx i 31} -format {%Oy %Om %e} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.284 {parse yymmdd} {
+    clock scan {lxx i xxxi} -format {%Oy %Om %Oe} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.285 {parse yymmdd} {
+    clock scan {lxx  1 31} -format {%Oy %N %d} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.286 {parse yymmdd} {
+    clock scan {lxx  1 xxxi} -format {%Oy %N %Od} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.287 {parse yymmdd} {
+    clock scan {lxx  1 31} -format {%Oy %N %e} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.288 {parse yymmdd} {
+    clock scan {lxx  1 xxxi} -format {%Oy %N %Oe} -locale en_US_roman -gmt 1
+} 2592000
+test clock-14.289 {parse yymmdd} {
+    clock scan {70 Dec 02} -format {%y %b %d} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.290 {parse yymmdd} {
+    clock scan {70 Dec ii} -format {%y %b %Od} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.291 {parse yymmdd} {
+    clock scan {70 Dec  2} -format {%y %b %e} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.292 {parse yymmdd} {
+    clock scan {70 Dec ii} -format {%y %b %Oe} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.293 {parse yymmdd} {
+    clock scan {70 December 02} -format {%y %B %d} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.294 {parse yymmdd} {
+    clock scan {70 December ii} -format {%y %B %Od} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.295 {parse yymmdd} {
+    clock scan {70 December  2} -format {%y %B %e} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.296 {parse yymmdd} {
+    clock scan {70 December ii} -format {%y %B %Oe} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.297 {parse yymmdd} {
+    clock scan {70 Dec 02} -format {%y %h %d} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.298 {parse yymmdd} {
+    clock scan {70 Dec ii} -format {%y %h %Od} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.299 {parse yymmdd} {
+    clock scan {70 Dec  2} -format {%y %h %e} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.300 {parse yymmdd} {
+    clock scan {70 Dec ii} -format {%y %h %Oe} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.301 {parse yymmdd} {
+    clock scan {70 12 02} -format {%y %m %d} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.302 {parse yymmdd} {
+    clock scan {70 12 ii} -format {%y %m %Od} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.303 {parse yymmdd} {
+    clock scan {70 12  2} -format {%y %m %e} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.304 {parse yymmdd} {
+    clock scan {70 12 ii} -format {%y %m %Oe} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.305 {parse yymmdd} {
+    clock scan {70 xii 02} -format {%y %Om %d} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.306 {parse yymmdd} {
+    clock scan {70 xii ii} -format {%y %Om %Od} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.307 {parse yymmdd} {
+    clock scan {70 xii  2} -format {%y %Om %e} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.308 {parse yymmdd} {
+    clock scan {70 xii ii} -format {%y %Om %Oe} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.309 {parse yymmdd} {
+    clock scan {70 12 02} -format {%y %N %d} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.310 {parse yymmdd} {
+    clock scan {70 12 ii} -format {%y %N %Od} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.311 {parse yymmdd} {
+    clock scan {70 12  2} -format {%y %N %e} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.312 {parse yymmdd} {
+    clock scan {70 12 ii} -format {%y %N %Oe} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.313 {parse yymmdd} {
+    clock scan {lxx Dec 02} -format {%Oy %b %d} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.314 {parse yymmdd} {
+    clock scan {lxx Dec ii} -format {%Oy %b %Od} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.315 {parse yymmdd} {
+    clock scan {lxx Dec  2} -format {%Oy %b %e} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.316 {parse yymmdd} {
+    clock scan {lxx Dec ii} -format {%Oy %b %Oe} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.317 {parse yymmdd} {
+    clock scan {lxx December 02} -format {%Oy %B %d} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.318 {parse yymmdd} {
+    clock scan {lxx December ii} -format {%Oy %B %Od} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.319 {parse yymmdd} {
+    clock scan {lxx December  2} -format {%Oy %B %e} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.320 {parse yymmdd} {
+    clock scan {lxx December ii} -format {%Oy %B %Oe} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.321 {parse yymmdd} {
+    clock scan {lxx Dec 02} -format {%Oy %h %d} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.322 {parse yymmdd} {
+    clock scan {lxx Dec ii} -format {%Oy %h %Od} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.323 {parse yymmdd} {
+    clock scan {lxx Dec  2} -format {%Oy %h %e} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.324 {parse yymmdd} {
+    clock scan {lxx Dec ii} -format {%Oy %h %Oe} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.325 {parse yymmdd} {
+    clock scan {lxx 12 02} -format {%Oy %m %d} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.326 {parse yymmdd} {
+    clock scan {lxx 12 ii} -format {%Oy %m %Od} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.327 {parse yymmdd} {
+    clock scan {lxx 12  2} -format {%Oy %m %e} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.328 {parse yymmdd} {
+    clock scan {lxx 12 ii} -format {%Oy %m %Oe} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.329 {parse yymmdd} {
+    clock scan {lxx xii 02} -format {%Oy %Om %d} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.330 {parse yymmdd} {
+    clock scan {lxx xii ii} -format {%Oy %Om %Od} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.331 {parse yymmdd} {
+    clock scan {lxx xii  2} -format {%Oy %Om %e} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.332 {parse yymmdd} {
+    clock scan {lxx xii ii} -format {%Oy %Om %Oe} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.333 {parse yymmdd} {
+    clock scan {lxx 12 02} -format {%Oy %N %d} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.334 {parse yymmdd} {
+    clock scan {lxx 12 ii} -format {%Oy %N %Od} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.335 {parse yymmdd} {
+    clock scan {lxx 12  2} -format {%Oy %N %e} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.336 {parse yymmdd} {
+    clock scan {lxx 12 ii} -format {%Oy %N %Oe} -locale en_US_roman -gmt 1
+} 28944000
+test clock-14.337 {parse yymmdd} {
+    clock scan {70 Dec 31} -format {%y %b %d} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.338 {parse yymmdd} {
+    clock scan {70 Dec xxxi} -format {%y %b %Od} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.339 {parse yymmdd} {
+    clock scan {70 Dec 31} -format {%y %b %e} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.340 {parse yymmdd} {
+    clock scan {70 Dec xxxi} -format {%y %b %Oe} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.341 {parse yymmdd} {
+    clock scan {70 December 31} -format {%y %B %d} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.342 {parse yymmdd} {
+    clock scan {70 December xxxi} -format {%y %B %Od} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.343 {parse yymmdd} {
+    clock scan {70 December 31} -format {%y %B %e} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.344 {parse yymmdd} {
+    clock scan {70 December xxxi} -format {%y %B %Oe} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.345 {parse yymmdd} {
+    clock scan {70 Dec 31} -format {%y %h %d} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.346 {parse yymmdd} {
+    clock scan {70 Dec xxxi} -format {%y %h %Od} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.347 {parse yymmdd} {
+    clock scan {70 Dec 31} -format {%y %h %e} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.348 {parse yymmdd} {
+    clock scan {70 Dec xxxi} -format {%y %h %Oe} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.349 {parse yymmdd} {
+    clock scan {70 12 31} -format {%y %m %d} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.350 {parse yymmdd} {
+    clock scan {70 12 xxxi} -format {%y %m %Od} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.351 {parse yymmdd} {
+    clock scan {70 12 31} -format {%y %m %e} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.352 {parse yymmdd} {
+    clock scan {70 12 xxxi} -format {%y %m %Oe} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.353 {parse yymmdd} {
+    clock scan {70 xii 31} -format {%y %Om %d} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.354 {parse yymmdd} {
+    clock scan {70 xii xxxi} -format {%y %Om %Od} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.355 {parse yymmdd} {
+    clock scan {70 xii 31} -format {%y %Om %e} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.356 {parse yymmdd} {
+    clock scan {70 xii xxxi} -format {%y %Om %Oe} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.357 {parse yymmdd} {
+    clock scan {70 12 31} -format {%y %N %d} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.358 {parse yymmdd} {
+    clock scan {70 12 xxxi} -format {%y %N %Od} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.359 {parse yymmdd} {
+    clock scan {70 12 31} -format {%y %N %e} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.360 {parse yymmdd} {
+    clock scan {70 12 xxxi} -format {%y %N %Oe} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.361 {parse yymmdd} {
+    clock scan {lxx Dec 31} -format {%Oy %b %d} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.362 {parse yymmdd} {
+    clock scan {lxx Dec xxxi} -format {%Oy %b %Od} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.363 {parse yymmdd} {
+    clock scan {lxx Dec 31} -format {%Oy %b %e} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.364 {parse yymmdd} {
+    clock scan {lxx Dec xxxi} -format {%Oy %b %Oe} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.365 {parse yymmdd} {
+    clock scan {lxx December 31} -format {%Oy %B %d} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.366 {parse yymmdd} {
+    clock scan {lxx December xxxi} -format {%Oy %B %Od} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.367 {parse yymmdd} {
+    clock scan {lxx December 31} -format {%Oy %B %e} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.368 {parse yymmdd} {
+    clock scan {lxx December xxxi} -format {%Oy %B %Oe} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.369 {parse yymmdd} {
+    clock scan {lxx Dec 31} -format {%Oy %h %d} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.370 {parse yymmdd} {
+    clock scan {lxx Dec xxxi} -format {%Oy %h %Od} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.371 {parse yymmdd} {
+    clock scan {lxx Dec 31} -format {%Oy %h %e} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.372 {parse yymmdd} {
+    clock scan {lxx Dec xxxi} -format {%Oy %h %Oe} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.373 {parse yymmdd} {
+    clock scan {lxx 12 31} -format {%Oy %m %d} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.374 {parse yymmdd} {
+    clock scan {lxx 12 xxxi} -format {%Oy %m %Od} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.375 {parse yymmdd} {
+    clock scan {lxx 12 31} -format {%Oy %m %e} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.376 {parse yymmdd} {
+    clock scan {lxx 12 xxxi} -format {%Oy %m %Oe} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.377 {parse yymmdd} {
+    clock scan {lxx xii 31} -format {%Oy %Om %d} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.378 {parse yymmdd} {
+    clock scan {lxx xii xxxi} -format {%Oy %Om %Od} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.379 {parse yymmdd} {
+    clock scan {lxx xii 31} -format {%Oy %Om %e} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.380 {parse yymmdd} {
+    clock scan {lxx xii xxxi} -format {%Oy %Om %Oe} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.381 {parse yymmdd} {
+    clock scan {lxx 12 31} -format {%Oy %N %d} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.382 {parse yymmdd} {
+    clock scan {lxx 12 xxxi} -format {%Oy %N %Od} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.383 {parse yymmdd} {
+    clock scan {lxx 12 31} -format {%Oy %N %e} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.384 {parse yymmdd} {
+    clock scan {lxx 12 xxxi} -format {%Oy %N %Oe} -locale en_US_roman -gmt 1
+} 31449600
+test clock-14.385 {parse yymmdd} {
+    clock scan {00 Jan 02} -format {%y %b %d} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.386 {parse yymmdd} {
+    clock scan {00 Jan ii} -format {%y %b %Od} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.387 {parse yymmdd} {
+    clock scan {00 Jan  2} -format {%y %b %e} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.388 {parse yymmdd} {
+    clock scan {00 Jan ii} -format {%y %b %Oe} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.389 {parse yymmdd} {
+    clock scan {00 January 02} -format {%y %B %d} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.390 {parse yymmdd} {
+    clock scan {00 January ii} -format {%y %B %Od} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.391 {parse yymmdd} {
+    clock scan {00 January  2} -format {%y %B %e} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.392 {parse yymmdd} {
+    clock scan {00 January ii} -format {%y %B %Oe} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.393 {parse yymmdd} {
+    clock scan {00 Jan 02} -format {%y %h %d} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.394 {parse yymmdd} {
+    clock scan {00 Jan ii} -format {%y %h %Od} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.395 {parse yymmdd} {
+    clock scan {00 Jan  2} -format {%y %h %e} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.396 {parse yymmdd} {
+    clock scan {00 Jan ii} -format {%y %h %Oe} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.397 {parse yymmdd} {
+    clock scan {00 01 02} -format {%y %m %d} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.398 {parse yymmdd} {
+    clock scan {00 01 ii} -format {%y %m %Od} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.399 {parse yymmdd} {
+    clock scan {00 01  2} -format {%y %m %e} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.400 {parse yymmdd} {
+    clock scan {00 01 ii} -format {%y %m %Oe} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.401 {parse yymmdd} {
+    clock scan {00 i 02} -format {%y %Om %d} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.402 {parse yymmdd} {
+    clock scan {00 i ii} -format {%y %Om %Od} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.403 {parse yymmdd} {
+    clock scan {00 i  2} -format {%y %Om %e} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.404 {parse yymmdd} {
+    clock scan {00 i ii} -format {%y %Om %Oe} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.405 {parse yymmdd} {
+    clock scan {00  1 02} -format {%y %N %d} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.406 {parse yymmdd} {
+    clock scan {00  1 ii} -format {%y %N %Od} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.407 {parse yymmdd} {
+    clock scan {00  1  2} -format {%y %N %e} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.408 {parse yymmdd} {
+    clock scan {00  1 ii} -format {%y %N %Oe} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.409 {parse yymmdd} {
+    clock scan {? Jan 02} -format {%Oy %b %d} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.410 {parse yymmdd} {
+    clock scan {? Jan ii} -format {%Oy %b %Od} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.411 {parse yymmdd} {
+    clock scan {? Jan  2} -format {%Oy %b %e} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.412 {parse yymmdd} {
+    clock scan {? Jan ii} -format {%Oy %b %Oe} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.413 {parse yymmdd} {
+    clock scan {? January 02} -format {%Oy %B %d} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.414 {parse yymmdd} {
+    clock scan {? January ii} -format {%Oy %B %Od} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.415 {parse yymmdd} {
+    clock scan {? January  2} -format {%Oy %B %e} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.416 {parse yymmdd} {
+    clock scan {? January ii} -format {%Oy %B %Oe} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.417 {parse yymmdd} {
+    clock scan {? Jan 02} -format {%Oy %h %d} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.418 {parse yymmdd} {
+    clock scan {? Jan ii} -format {%Oy %h %Od} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.419 {parse yymmdd} {
+    clock scan {? Jan  2} -format {%Oy %h %e} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.420 {parse yymmdd} {
+    clock scan {? Jan ii} -format {%Oy %h %Oe} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.421 {parse yymmdd} {
+    clock scan {? 01 02} -format {%Oy %m %d} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.422 {parse yymmdd} {
+    clock scan {? 01 ii} -format {%Oy %m %Od} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.423 {parse yymmdd} {
+    clock scan {? 01  2} -format {%Oy %m %e} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.424 {parse yymmdd} {
+    clock scan {? 01 ii} -format {%Oy %m %Oe} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.425 {parse yymmdd} {
+    clock scan {? i 02} -format {%Oy %Om %d} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.426 {parse yymmdd} {
+    clock scan {? i ii} -format {%Oy %Om %Od} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.427 {parse yymmdd} {
+    clock scan {? i  2} -format {%Oy %Om %e} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.428 {parse yymmdd} {
+    clock scan {? i ii} -format {%Oy %Om %Oe} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.429 {parse yymmdd} {
+    clock scan {?  1 02} -format {%Oy %N %d} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.430 {parse yymmdd} {
+    clock scan {?  1 ii} -format {%Oy %N %Od} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.431 {parse yymmdd} {
+    clock scan {?  1  2} -format {%Oy %N %e} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.432 {parse yymmdd} {
+    clock scan {?  1 ii} -format {%Oy %N %Oe} -locale en_US_roman -gmt 1
+} 946771200
+test clock-14.433 {parse yymmdd} {
+    clock scan {00 Jan 31} -format {%y %b %d} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.434 {parse yymmdd} {
+    clock scan {00 Jan xxxi} -format {%y %b %Od} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.435 {parse yymmdd} {
+    clock scan {00 Jan 31} -format {%y %b %e} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.436 {parse yymmdd} {
+    clock scan {00 Jan xxxi} -format {%y %b %Oe} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.437 {parse yymmdd} {
+    clock scan {00 January 31} -format {%y %B %d} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.438 {parse yymmdd} {
+    clock scan {00 January xxxi} -format {%y %B %Od} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.439 {parse yymmdd} {
+    clock scan {00 January 31} -format {%y %B %e} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.440 {parse yymmdd} {
+    clock scan {00 January xxxi} -format {%y %B %Oe} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.441 {parse yymmdd} {
+    clock scan {00 Jan 31} -format {%y %h %d} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.442 {parse yymmdd} {
+    clock scan {00 Jan xxxi} -format {%y %h %Od} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.443 {parse yymmdd} {
+    clock scan {00 Jan 31} -format {%y %h %e} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.444 {parse yymmdd} {
+    clock scan {00 Jan xxxi} -format {%y %h %Oe} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.445 {parse yymmdd} {
+    clock scan {00 01 31} -format {%y %m %d} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.446 {parse yymmdd} {
+    clock scan {00 01 xxxi} -format {%y %m %Od} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.447 {parse yymmdd} {
+    clock scan {00 01 31} -format {%y %m %e} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.448 {parse yymmdd} {
+    clock scan {00 01 xxxi} -format {%y %m %Oe} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.449 {parse yymmdd} {
+    clock scan {00 i 31} -format {%y %Om %d} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.450 {parse yymmdd} {
+    clock scan {00 i xxxi} -format {%y %Om %Od} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.451 {parse yymmdd} {
+    clock scan {00 i 31} -format {%y %Om %e} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.452 {parse yymmdd} {
+    clock scan {00 i xxxi} -format {%y %Om %Oe} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.453 {parse yymmdd} {
+    clock scan {00  1 31} -format {%y %N %d} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.454 {parse yymmdd} {
+    clock scan {00  1 xxxi} -format {%y %N %Od} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.455 {parse yymmdd} {
+    clock scan {00  1 31} -format {%y %N %e} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.456 {parse yymmdd} {
+    clock scan {00  1 xxxi} -format {%y %N %Oe} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.457 {parse yymmdd} {
+    clock scan {? Jan 31} -format {%Oy %b %d} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.458 {parse yymmdd} {
+    clock scan {? Jan xxxi} -format {%Oy %b %Od} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.459 {parse yymmdd} {
+    clock scan {? Jan 31} -format {%Oy %b %e} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.460 {parse yymmdd} {
+    clock scan {? Jan xxxi} -format {%Oy %b %Oe} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.461 {parse yymmdd} {
+    clock scan {? January 31} -format {%Oy %B %d} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.462 {parse yymmdd} {
+    clock scan {? January xxxi} -format {%Oy %B %Od} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.463 {parse yymmdd} {
+    clock scan {? January 31} -format {%Oy %B %e} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.464 {parse yymmdd} {
+    clock scan {? January xxxi} -format {%Oy %B %Oe} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.465 {parse yymmdd} {
+    clock scan {? Jan 31} -format {%Oy %h %d} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.466 {parse yymmdd} {
+    clock scan {? Jan xxxi} -format {%Oy %h %Od} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.467 {parse yymmdd} {
+    clock scan {? Jan 31} -format {%Oy %h %e} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.468 {parse yymmdd} {
+    clock scan {? Jan xxxi} -format {%Oy %h %Oe} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.469 {parse yymmdd} {
+    clock scan {? 01 31} -format {%Oy %m %d} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.470 {parse yymmdd} {
+    clock scan {? 01 xxxi} -format {%Oy %m %Od} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.471 {parse yymmdd} {
+    clock scan {? 01 31} -format {%Oy %m %e} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.472 {parse yymmdd} {
+    clock scan {? 01 xxxi} -format {%Oy %m %Oe} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.473 {parse yymmdd} {
+    clock scan {? i 31} -format {%Oy %Om %d} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.474 {parse yymmdd} {
+    clock scan {? i xxxi} -format {%Oy %Om %Od} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.475 {parse yymmdd} {
+    clock scan {? i 31} -format {%Oy %Om %e} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.476 {parse yymmdd} {
+    clock scan {? i xxxi} -format {%Oy %Om %Oe} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.477 {parse yymmdd} {
+    clock scan {?  1 31} -format {%Oy %N %d} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.478 {parse yymmdd} {
+    clock scan {?  1 xxxi} -format {%Oy %N %Od} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.479 {parse yymmdd} {
+    clock scan {?  1 31} -format {%Oy %N %e} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.480 {parse yymmdd} {
+    clock scan {?  1 xxxi} -format {%Oy %N %Oe} -locale en_US_roman -gmt 1
+} 949276800
+test clock-14.481 {parse yymmdd} {
+    clock scan {00 Dec 02} -format {%y %b %d} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.482 {parse yymmdd} {
+    clock scan {00 Dec ii} -format {%y %b %Od} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.483 {parse yymmdd} {
+    clock scan {00 Dec  2} -format {%y %b %e} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.484 {parse yymmdd} {
+    clock scan {00 Dec ii} -format {%y %b %Oe} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.485 {parse yymmdd} {
+    clock scan {00 December 02} -format {%y %B %d} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.486 {parse yymmdd} {
+    clock scan {00 December ii} -format {%y %B %Od} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.487 {parse yymmdd} {
+    clock scan {00 December  2} -format {%y %B %e} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.488 {parse yymmdd} {
+    clock scan {00 December ii} -format {%y %B %Oe} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.489 {parse yymmdd} {
+    clock scan {00 Dec 02} -format {%y %h %d} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.490 {parse yymmdd} {
+    clock scan {00 Dec ii} -format {%y %h %Od} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.491 {parse yymmdd} {
+    clock scan {00 Dec  2} -format {%y %h %e} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.492 {parse yymmdd} {
+    clock scan {00 Dec ii} -format {%y %h %Oe} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.493 {parse yymmdd} {
+    clock scan {00 12 02} -format {%y %m %d} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.494 {parse yymmdd} {
+    clock scan {00 12 ii} -format {%y %m %Od} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.495 {parse yymmdd} {
+    clock scan {00 12  2} -format {%y %m %e} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.496 {parse yymmdd} {
+    clock scan {00 12 ii} -format {%y %m %Oe} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.497 {parse yymmdd} {
+    clock scan {00 xii 02} -format {%y %Om %d} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.498 {parse yymmdd} {
+    clock scan {00 xii ii} -format {%y %Om %Od} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.499 {parse yymmdd} {
+    clock scan {00 xii  2} -format {%y %Om %e} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.500 {parse yymmdd} {
+    clock scan {00 xii ii} -format {%y %Om %Oe} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.501 {parse yymmdd} {
+    clock scan {00 12 02} -format {%y %N %d} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.502 {parse yymmdd} {
+    clock scan {00 12 ii} -format {%y %N %Od} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.503 {parse yymmdd} {
+    clock scan {00 12  2} -format {%y %N %e} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.504 {parse yymmdd} {
+    clock scan {00 12 ii} -format {%y %N %Oe} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.505 {parse yymmdd} {
+    clock scan {? Dec 02} -format {%Oy %b %d} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.506 {parse yymmdd} {
+    clock scan {? Dec ii} -format {%Oy %b %Od} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.507 {parse yymmdd} {
+    clock scan {? Dec  2} -format {%Oy %b %e} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.508 {parse yymmdd} {
+    clock scan {? Dec ii} -format {%Oy %b %Oe} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.509 {parse yymmdd} {
+    clock scan {? December 02} -format {%Oy %B %d} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.510 {parse yymmdd} {
+    clock scan {? December ii} -format {%Oy %B %Od} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.511 {parse yymmdd} {
+    clock scan {? December  2} -format {%Oy %B %e} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.512 {parse yymmdd} {
+    clock scan {? December ii} -format {%Oy %B %Oe} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.513 {parse yymmdd} {
+    clock scan {? Dec 02} -format {%Oy %h %d} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.514 {parse yymmdd} {
+    clock scan {? Dec ii} -format {%Oy %h %Od} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.515 {parse yymmdd} {
+    clock scan {? Dec  2} -format {%Oy %h %e} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.516 {parse yymmdd} {
+    clock scan {? Dec ii} -format {%Oy %h %Oe} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.517 {parse yymmdd} {
+    clock scan {? 12 02} -format {%Oy %m %d} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.518 {parse yymmdd} {
+    clock scan {? 12 ii} -format {%Oy %m %Od} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.519 {parse yymmdd} {
+    clock scan {? 12  2} -format {%Oy %m %e} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.520 {parse yymmdd} {
+    clock scan {? 12 ii} -format {%Oy %m %Oe} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.521 {parse yymmdd} {
+    clock scan {? xii 02} -format {%Oy %Om %d} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.522 {parse yymmdd} {
+    clock scan {? xii ii} -format {%Oy %Om %Od} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.523 {parse yymmdd} {
+    clock scan {? xii  2} -format {%Oy %Om %e} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.524 {parse yymmdd} {
+    clock scan {? xii ii} -format {%Oy %Om %Oe} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.525 {parse yymmdd} {
+    clock scan {? 12 02} -format {%Oy %N %d} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.526 {parse yymmdd} {
+    clock scan {? 12 ii} -format {%Oy %N %Od} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.527 {parse yymmdd} {
+    clock scan {? 12  2} -format {%Oy %N %e} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.528 {parse yymmdd} {
+    clock scan {? 12 ii} -format {%Oy %N %Oe} -locale en_US_roman -gmt 1
+} 975715200
+test clock-14.529 {parse yymmdd} {
+    clock scan {00 Dec 31} -format {%y %b %d} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.530 {parse yymmdd} {
+    clock scan {00 Dec xxxi} -format {%y %b %Od} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.531 {parse yymmdd} {
+    clock scan {00 Dec 31} -format {%y %b %e} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.532 {parse yymmdd} {
+    clock scan {00 Dec xxxi} -format {%y %b %Oe} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.533 {parse yymmdd} {
+    clock scan {00 December 31} -format {%y %B %d} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.534 {parse yymmdd} {
+    clock scan {00 December xxxi} -format {%y %B %Od} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.535 {parse yymmdd} {
+    clock scan {00 December 31} -format {%y %B %e} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.536 {parse yymmdd} {
+    clock scan {00 December xxxi} -format {%y %B %Oe} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.537 {parse yymmdd} {
+    clock scan {00 Dec 31} -format {%y %h %d} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.538 {parse yymmdd} {
+    clock scan {00 Dec xxxi} -format {%y %h %Od} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.539 {parse yymmdd} {
+    clock scan {00 Dec 31} -format {%y %h %e} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.540 {parse yymmdd} {
+    clock scan {00 Dec xxxi} -format {%y %h %Oe} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.541 {parse yymmdd} {
+    clock scan {00 12 31} -format {%y %m %d} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.542 {parse yymmdd} {
+    clock scan {00 12 xxxi} -format {%y %m %Od} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.543 {parse yymmdd} {
+    clock scan {00 12 31} -format {%y %m %e} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.544 {parse yymmdd} {
+    clock scan {00 12 xxxi} -format {%y %m %Oe} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.545 {parse yymmdd} {
+    clock scan {00 xii 31} -format {%y %Om %d} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.546 {parse yymmdd} {
+    clock scan {00 xii xxxi} -format {%y %Om %Od} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.547 {parse yymmdd} {
+    clock scan {00 xii 31} -format {%y %Om %e} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.548 {parse yymmdd} {
+    clock scan {00 xii xxxi} -format {%y %Om %Oe} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.549 {parse yymmdd} {
+    clock scan {00 12 31} -format {%y %N %d} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.550 {parse yymmdd} {
+    clock scan {00 12 xxxi} -format {%y %N %Od} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.551 {parse yymmdd} {
+    clock scan {00 12 31} -format {%y %N %e} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.552 {parse yymmdd} {
+    clock scan {00 12 xxxi} -format {%y %N %Oe} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.553 {parse yymmdd} {
+    clock scan {? Dec 31} -format {%Oy %b %d} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.554 {parse yymmdd} {
+    clock scan {? Dec xxxi} -format {%Oy %b %Od} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.555 {parse yymmdd} {
+    clock scan {? Dec 31} -format {%Oy %b %e} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.556 {parse yymmdd} {
+    clock scan {? Dec xxxi} -format {%Oy %b %Oe} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.557 {parse yymmdd} {
+    clock scan {? December 31} -format {%Oy %B %d} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.558 {parse yymmdd} {
+    clock scan {? December xxxi} -format {%Oy %B %Od} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.559 {parse yymmdd} {
+    clock scan {? December 31} -format {%Oy %B %e} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.560 {parse yymmdd} {
+    clock scan {? December xxxi} -format {%Oy %B %Oe} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.561 {parse yymmdd} {
+    clock scan {? Dec 31} -format {%Oy %h %d} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.562 {parse yymmdd} {
+    clock scan {? Dec xxxi} -format {%Oy %h %Od} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.563 {parse yymmdd} {
+    clock scan {? Dec 31} -format {%Oy %h %e} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.564 {parse yymmdd} {
+    clock scan {? Dec xxxi} -format {%Oy %h %Oe} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.565 {parse yymmdd} {
+    clock scan {? 12 31} -format {%Oy %m %d} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.566 {parse yymmdd} {
+    clock scan {? 12 xxxi} -format {%Oy %m %Od} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.567 {parse yymmdd} {
+    clock scan {? 12 31} -format {%Oy %m %e} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.568 {parse yymmdd} {
+    clock scan {? 12 xxxi} -format {%Oy %m %Oe} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.569 {parse yymmdd} {
+    clock scan {? xii 31} -format {%Oy %Om %d} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.570 {parse yymmdd} {
+    clock scan {? xii xxxi} -format {%Oy %Om %Od} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.571 {parse yymmdd} {
+    clock scan {? xii 31} -format {%Oy %Om %e} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.572 {parse yymmdd} {
+    clock scan {? xii xxxi} -format {%Oy %Om %Oe} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.573 {parse yymmdd} {
+    clock scan {? 12 31} -format {%Oy %N %d} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.574 {parse yymmdd} {
+    clock scan {? 12 xxxi} -format {%Oy %N %Od} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.575 {parse yymmdd} {
+    clock scan {? 12 31} -format {%Oy %N %e} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.576 {parse yymmdd} {
+    clock scan {? 12 xxxi} -format {%Oy %N %Oe} -locale en_US_roman -gmt 1
+} 978220800
+test clock-14.577 {parse yymmdd} {
+    clock scan {37 Jan 02} -format {%y %b %d} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.578 {parse yymmdd} {
+    clock scan {37 Jan ii} -format {%y %b %Od} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.579 {parse yymmdd} {
+    clock scan {37 Jan  2} -format {%y %b %e} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.580 {parse yymmdd} {
+    clock scan {37 Jan ii} -format {%y %b %Oe} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.581 {parse yymmdd} {
+    clock scan {37 January 02} -format {%y %B %d} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.582 {parse yymmdd} {
+    clock scan {37 January ii} -format {%y %B %Od} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.583 {parse yymmdd} {
+    clock scan {37 January  2} -format {%y %B %e} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.584 {parse yymmdd} {
+    clock scan {37 January ii} -format {%y %B %Oe} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.585 {parse yymmdd} {
+    clock scan {37 Jan 02} -format {%y %h %d} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.586 {parse yymmdd} {
+    clock scan {37 Jan ii} -format {%y %h %Od} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.587 {parse yymmdd} {
+    clock scan {37 Jan  2} -format {%y %h %e} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.588 {parse yymmdd} {
+    clock scan {37 Jan ii} -format {%y %h %Oe} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.589 {parse yymmdd} {
+    clock scan {37 01 02} -format {%y %m %d} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.590 {parse yymmdd} {
+    clock scan {37 01 ii} -format {%y %m %Od} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.591 {parse yymmdd} {
+    clock scan {37 01  2} -format {%y %m %e} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.592 {parse yymmdd} {
+    clock scan {37 01 ii} -format {%y %m %Oe} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.593 {parse yymmdd} {
+    clock scan {37 i 02} -format {%y %Om %d} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.594 {parse yymmdd} {
+    clock scan {37 i ii} -format {%y %Om %Od} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.595 {parse yymmdd} {
+    clock scan {37 i  2} -format {%y %Om %e} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.596 {parse yymmdd} {
+    clock scan {37 i ii} -format {%y %Om %Oe} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.597 {parse yymmdd} {
+    clock scan {37  1 02} -format {%y %N %d} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.598 {parse yymmdd} {
+    clock scan {37  1 ii} -format {%y %N %Od} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.599 {parse yymmdd} {
+    clock scan {37  1  2} -format {%y %N %e} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.600 {parse yymmdd} {
+    clock scan {37  1 ii} -format {%y %N %Oe} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.601 {parse yymmdd} {
+    clock scan {xxxvii Jan 02} -format {%Oy %b %d} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.602 {parse yymmdd} {
+    clock scan {xxxvii Jan ii} -format {%Oy %b %Od} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.603 {parse yymmdd} {
+    clock scan {xxxvii Jan  2} -format {%Oy %b %e} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.604 {parse yymmdd} {
+    clock scan {xxxvii Jan ii} -format {%Oy %b %Oe} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.605 {parse yymmdd} {
+    clock scan {xxxvii January 02} -format {%Oy %B %d} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.606 {parse yymmdd} {
+    clock scan {xxxvii January ii} -format {%Oy %B %Od} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.607 {parse yymmdd} {
+    clock scan {xxxvii January  2} -format {%Oy %B %e} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.608 {parse yymmdd} {
+    clock scan {xxxvii January ii} -format {%Oy %B %Oe} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.609 {parse yymmdd} {
+    clock scan {xxxvii Jan 02} -format {%Oy %h %d} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.610 {parse yymmdd} {
+    clock scan {xxxvii Jan ii} -format {%Oy %h %Od} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.611 {parse yymmdd} {
+    clock scan {xxxvii Jan  2} -format {%Oy %h %e} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.612 {parse yymmdd} {
+    clock scan {xxxvii Jan ii} -format {%Oy %h %Oe} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.613 {parse yymmdd} {
+    clock scan {xxxvii 01 02} -format {%Oy %m %d} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.614 {parse yymmdd} {
+    clock scan {xxxvii 01 ii} -format {%Oy %m %Od} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.615 {parse yymmdd} {
+    clock scan {xxxvii 01  2} -format {%Oy %m %e} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.616 {parse yymmdd} {
+    clock scan {xxxvii 01 ii} -format {%Oy %m %Oe} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.617 {parse yymmdd} {
+    clock scan {xxxvii i 02} -format {%Oy %Om %d} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.618 {parse yymmdd} {
+    clock scan {xxxvii i ii} -format {%Oy %Om %Od} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.619 {parse yymmdd} {
+    clock scan {xxxvii i  2} -format {%Oy %Om %e} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.620 {parse yymmdd} {
+    clock scan {xxxvii i ii} -format {%Oy %Om %Oe} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.621 {parse yymmdd} {
+    clock scan {xxxvii  1 02} -format {%Oy %N %d} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.622 {parse yymmdd} {
+    clock scan {xxxvii  1 ii} -format {%Oy %N %Od} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.623 {parse yymmdd} {
+    clock scan {xxxvii  1  2} -format {%Oy %N %e} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.624 {parse yymmdd} {
+    clock scan {xxxvii  1 ii} -format {%Oy %N %Oe} -locale en_US_roman -gmt 1
+} 2114467200
+test clock-14.625 {parse yymmdd} {
+    clock scan {37 Jan 31} -format {%y %b %d} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.626 {parse yymmdd} {
+    clock scan {37 Jan xxxi} -format {%y %b %Od} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.627 {parse yymmdd} {
+    clock scan {37 Jan 31} -format {%y %b %e} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.628 {parse yymmdd} {
+    clock scan {37 Jan xxxi} -format {%y %b %Oe} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.629 {parse yymmdd} {
+    clock scan {37 January 31} -format {%y %B %d} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.630 {parse yymmdd} {
+    clock scan {37 January xxxi} -format {%y %B %Od} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.631 {parse yymmdd} {
+    clock scan {37 January 31} -format {%y %B %e} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.632 {parse yymmdd} {
+    clock scan {37 January xxxi} -format {%y %B %Oe} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.633 {parse yymmdd} {
+    clock scan {37 Jan 31} -format {%y %h %d} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.634 {parse yymmdd} {
+    clock scan {37 Jan xxxi} -format {%y %h %Od} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.635 {parse yymmdd} {
+    clock scan {37 Jan 31} -format {%y %h %e} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.636 {parse yymmdd} {
+    clock scan {37 Jan xxxi} -format {%y %h %Oe} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.637 {parse yymmdd} {
+    clock scan {37 01 31} -format {%y %m %d} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.638 {parse yymmdd} {
+    clock scan {37 01 xxxi} -format {%y %m %Od} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.639 {parse yymmdd} {
+    clock scan {37 01 31} -format {%y %m %e} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.640 {parse yymmdd} {
+    clock scan {37 01 xxxi} -format {%y %m %Oe} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.641 {parse yymmdd} {
+    clock scan {37 i 31} -format {%y %Om %d} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.642 {parse yymmdd} {
+    clock scan {37 i xxxi} -format {%y %Om %Od} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.643 {parse yymmdd} {
+    clock scan {37 i 31} -format {%y %Om %e} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.644 {parse yymmdd} {
+    clock scan {37 i xxxi} -format {%y %Om %Oe} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.645 {parse yymmdd} {
+    clock scan {37  1 31} -format {%y %N %d} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.646 {parse yymmdd} {
+    clock scan {37  1 xxxi} -format {%y %N %Od} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.647 {parse yymmdd} {
+    clock scan {37  1 31} -format {%y %N %e} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.648 {parse yymmdd} {
+    clock scan {37  1 xxxi} -format {%y %N %Oe} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.649 {parse yymmdd} {
+    clock scan {xxxvii Jan 31} -format {%Oy %b %d} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.650 {parse yymmdd} {
+    clock scan {xxxvii Jan xxxi} -format {%Oy %b %Od} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.651 {parse yymmdd} {
+    clock scan {xxxvii Jan 31} -format {%Oy %b %e} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.652 {parse yymmdd} {
+    clock scan {xxxvii Jan xxxi} -format {%Oy %b %Oe} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.653 {parse yymmdd} {
+    clock scan {xxxvii January 31} -format {%Oy %B %d} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.654 {parse yymmdd} {
+    clock scan {xxxvii January xxxi} -format {%Oy %B %Od} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.655 {parse yymmdd} {
+    clock scan {xxxvii January 31} -format {%Oy %B %e} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.656 {parse yymmdd} {
+    clock scan {xxxvii January xxxi} -format {%Oy %B %Oe} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.657 {parse yymmdd} {
+    clock scan {xxxvii Jan 31} -format {%Oy %h %d} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.658 {parse yymmdd} {
+    clock scan {xxxvii Jan xxxi} -format {%Oy %h %Od} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.659 {parse yymmdd} {
+    clock scan {xxxvii Jan 31} -format {%Oy %h %e} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.660 {parse yymmdd} {
+    clock scan {xxxvii Jan xxxi} -format {%Oy %h %Oe} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.661 {parse yymmdd} {
+    clock scan {xxxvii 01 31} -format {%Oy %m %d} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.662 {parse yymmdd} {
+    clock scan {xxxvii 01 xxxi} -format {%Oy %m %Od} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.663 {parse yymmdd} {
+    clock scan {xxxvii 01 31} -format {%Oy %m %e} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.664 {parse yymmdd} {
+    clock scan {xxxvii 01 xxxi} -format {%Oy %m %Oe} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.665 {parse yymmdd} {
+    clock scan {xxxvii i 31} -format {%Oy %Om %d} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.666 {parse yymmdd} {
+    clock scan {xxxvii i xxxi} -format {%Oy %Om %Od} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.667 {parse yymmdd} {
+    clock scan {xxxvii i 31} -format {%Oy %Om %e} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.668 {parse yymmdd} {
+    clock scan {xxxvii i xxxi} -format {%Oy %Om %Oe} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.669 {parse yymmdd} {
+    clock scan {xxxvii  1 31} -format {%Oy %N %d} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.670 {parse yymmdd} {
+    clock scan {xxxvii  1 xxxi} -format {%Oy %N %Od} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.671 {parse yymmdd} {
+    clock scan {xxxvii  1 31} -format {%Oy %N %e} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.672 {parse yymmdd} {
+    clock scan {xxxvii  1 xxxi} -format {%Oy %N %Oe} -locale en_US_roman -gmt 1
+} 2116972800
+test clock-14.673 {parse yymmdd} {
+    clock scan {37 Dec 02} -format {%y %b %d} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.674 {parse yymmdd} {
+    clock scan {37 Dec ii} -format {%y %b %Od} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.675 {parse yymmdd} {
+    clock scan {37 Dec  2} -format {%y %b %e} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.676 {parse yymmdd} {
+    clock scan {37 Dec ii} -format {%y %b %Oe} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.677 {parse yymmdd} {
+    clock scan {37 December 02} -format {%y %B %d} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.678 {parse yymmdd} {
+    clock scan {37 December ii} -format {%y %B %Od} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.679 {parse yymmdd} {
+    clock scan {37 December  2} -format {%y %B %e} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.680 {parse yymmdd} {
+    clock scan {37 December ii} -format {%y %B %Oe} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.681 {parse yymmdd} {
+    clock scan {37 Dec 02} -format {%y %h %d} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.682 {parse yymmdd} {
+    clock scan {37 Dec ii} -format {%y %h %Od} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.683 {parse yymmdd} {
+    clock scan {37 Dec  2} -format {%y %h %e} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.684 {parse yymmdd} {
+    clock scan {37 Dec ii} -format {%y %h %Oe} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.685 {parse yymmdd} {
+    clock scan {37 12 02} -format {%y %m %d} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.686 {parse yymmdd} {
+    clock scan {37 12 ii} -format {%y %m %Od} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.687 {parse yymmdd} {
+    clock scan {37 12  2} -format {%y %m %e} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.688 {parse yymmdd} {
+    clock scan {37 12 ii} -format {%y %m %Oe} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.689 {parse yymmdd} {
+    clock scan {37 xii 02} -format {%y %Om %d} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.690 {parse yymmdd} {
+    clock scan {37 xii ii} -format {%y %Om %Od} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.691 {parse yymmdd} {
+    clock scan {37 xii  2} -format {%y %Om %e} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.692 {parse yymmdd} {
+    clock scan {37 xii ii} -format {%y %Om %Oe} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.693 {parse yymmdd} {
+    clock scan {37 12 02} -format {%y %N %d} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.694 {parse yymmdd} {
+    clock scan {37 12 ii} -format {%y %N %Od} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.695 {parse yymmdd} {
+    clock scan {37 12  2} -format {%y %N %e} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.696 {parse yymmdd} {
+    clock scan {37 12 ii} -format {%y %N %Oe} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.697 {parse yymmdd} {
+    clock scan {xxxvii Dec 02} -format {%Oy %b %d} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.698 {parse yymmdd} {
+    clock scan {xxxvii Dec ii} -format {%Oy %b %Od} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.699 {parse yymmdd} {
+    clock scan {xxxvii Dec  2} -format {%Oy %b %e} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.700 {parse yymmdd} {
+    clock scan {xxxvii Dec ii} -format {%Oy %b %Oe} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.701 {parse yymmdd} {
+    clock scan {xxxvii December 02} -format {%Oy %B %d} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.702 {parse yymmdd} {
+    clock scan {xxxvii December ii} -format {%Oy %B %Od} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.703 {parse yymmdd} {
+    clock scan {xxxvii December  2} -format {%Oy %B %e} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.704 {parse yymmdd} {
+    clock scan {xxxvii December ii} -format {%Oy %B %Oe} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.705 {parse yymmdd} {
+    clock scan {xxxvii Dec 02} -format {%Oy %h %d} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.706 {parse yymmdd} {
+    clock scan {xxxvii Dec ii} -format {%Oy %h %Od} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.707 {parse yymmdd} {
+    clock scan {xxxvii Dec  2} -format {%Oy %h %e} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.708 {parse yymmdd} {
+    clock scan {xxxvii Dec ii} -format {%Oy %h %Oe} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.709 {parse yymmdd} {
+    clock scan {xxxvii 12 02} -format {%Oy %m %d} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.710 {parse yymmdd} {
+    clock scan {xxxvii 12 ii} -format {%Oy %m %Od} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.711 {parse yymmdd} {
+    clock scan {xxxvii 12  2} -format {%Oy %m %e} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.712 {parse yymmdd} {
+    clock scan {xxxvii 12 ii} -format {%Oy %m %Oe} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.713 {parse yymmdd} {
+    clock scan {xxxvii xii 02} -format {%Oy %Om %d} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.714 {parse yymmdd} {
+    clock scan {xxxvii xii ii} -format {%Oy %Om %Od} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.715 {parse yymmdd} {
+    clock scan {xxxvii xii  2} -format {%Oy %Om %e} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.716 {parse yymmdd} {
+    clock scan {xxxvii xii ii} -format {%Oy %Om %Oe} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.717 {parse yymmdd} {
+    clock scan {xxxvii 12 02} -format {%Oy %N %d} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.718 {parse yymmdd} {
+    clock scan {xxxvii 12 ii} -format {%Oy %N %Od} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.719 {parse yymmdd} {
+    clock scan {xxxvii 12  2} -format {%Oy %N %e} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.720 {parse yymmdd} {
+    clock scan {xxxvii 12 ii} -format {%Oy %N %Oe} -locale en_US_roman -gmt 1
+} 2143324800
+test clock-14.721 {parse yymmdd} {
+    clock scan {37 Dec 31} -format {%y %b %d} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.722 {parse yymmdd} {
+    clock scan {37 Dec xxxi} -format {%y %b %Od} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.723 {parse yymmdd} {
+    clock scan {37 Dec 31} -format {%y %b %e} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.724 {parse yymmdd} {
+    clock scan {37 Dec xxxi} -format {%y %b %Oe} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.725 {parse yymmdd} {
+    clock scan {37 December 31} -format {%y %B %d} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.726 {parse yymmdd} {
+    clock scan {37 December xxxi} -format {%y %B %Od} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.727 {parse yymmdd} {
+    clock scan {37 December 31} -format {%y %B %e} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.728 {parse yymmdd} {
+    clock scan {37 December xxxi} -format {%y %B %Oe} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.729 {parse yymmdd} {
+    clock scan {37 Dec 31} -format {%y %h %d} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.730 {parse yymmdd} {
+    clock scan {37 Dec xxxi} -format {%y %h %Od} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.731 {parse yymmdd} {
+    clock scan {37 Dec 31} -format {%y %h %e} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.732 {parse yymmdd} {
+    clock scan {37 Dec xxxi} -format {%y %h %Oe} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.733 {parse yymmdd} {
+    clock scan {37 12 31} -format {%y %m %d} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.734 {parse yymmdd} {
+    clock scan {37 12 xxxi} -format {%y %m %Od} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.735 {parse yymmdd} {
+    clock scan {37 12 31} -format {%y %m %e} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.736 {parse yymmdd} {
+    clock scan {37 12 xxxi} -format {%y %m %Oe} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.737 {parse yymmdd} {
+    clock scan {37 xii 31} -format {%y %Om %d} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.738 {parse yymmdd} {
+    clock scan {37 xii xxxi} -format {%y %Om %Od} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.739 {parse yymmdd} {
+    clock scan {37 xii 31} -format {%y %Om %e} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.740 {parse yymmdd} {
+    clock scan {37 xii xxxi} -format {%y %Om %Oe} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.741 {parse yymmdd} {
+    clock scan {37 12 31} -format {%y %N %d} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.742 {parse yymmdd} {
+    clock scan {37 12 xxxi} -format {%y %N %Od} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.743 {parse yymmdd} {
+    clock scan {37 12 31} -format {%y %N %e} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.744 {parse yymmdd} {
+    clock scan {37 12 xxxi} -format {%y %N %Oe} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.745 {parse yymmdd} {
+    clock scan {xxxvii Dec 31} -format {%Oy %b %d} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.746 {parse yymmdd} {
+    clock scan {xxxvii Dec xxxi} -format {%Oy %b %Od} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.747 {parse yymmdd} {
+    clock scan {xxxvii Dec 31} -format {%Oy %b %e} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.748 {parse yymmdd} {
+    clock scan {xxxvii Dec xxxi} -format {%Oy %b %Oe} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.749 {parse yymmdd} {
+    clock scan {xxxvii December 31} -format {%Oy %B %d} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.750 {parse yymmdd} {
+    clock scan {xxxvii December xxxi} -format {%Oy %B %Od} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.751 {parse yymmdd} {
+    clock scan {xxxvii December 31} -format {%Oy %B %e} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.752 {parse yymmdd} {
+    clock scan {xxxvii December xxxi} -format {%Oy %B %Oe} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.753 {parse yymmdd} {
+    clock scan {xxxvii Dec 31} -format {%Oy %h %d} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.754 {parse yymmdd} {
+    clock scan {xxxvii Dec xxxi} -format {%Oy %h %Od} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.755 {parse yymmdd} {
+    clock scan {xxxvii Dec 31} -format {%Oy %h %e} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.756 {parse yymmdd} {
+    clock scan {xxxvii Dec xxxi} -format {%Oy %h %Oe} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.757 {parse yymmdd} {
+    clock scan {xxxvii 12 31} -format {%Oy %m %d} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.758 {parse yymmdd} {
+    clock scan {xxxvii 12 xxxi} -format {%Oy %m %Od} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.759 {parse yymmdd} {
+    clock scan {xxxvii 12 31} -format {%Oy %m %e} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.760 {parse yymmdd} {
+    clock scan {xxxvii 12 xxxi} -format {%Oy %m %Oe} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.761 {parse yymmdd} {
+    clock scan {xxxvii xii 31} -format {%Oy %Om %d} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.762 {parse yymmdd} {
+    clock scan {xxxvii xii xxxi} -format {%Oy %Om %Od} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.763 {parse yymmdd} {
+    clock scan {xxxvii xii 31} -format {%Oy %Om %e} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.764 {parse yymmdd} {
+    clock scan {xxxvii xii xxxi} -format {%Oy %Om %Oe} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.765 {parse yymmdd} {
+    clock scan {xxxvii 12 31} -format {%Oy %N %d} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.766 {parse yymmdd} {
+    clock scan {xxxvii 12 xxxi} -format {%Oy %N %Od} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.767 {parse yymmdd} {
+    clock scan {xxxvii 12 31} -format {%Oy %N %e} -locale en_US_roman -gmt 1
+} 2145830400
+test clock-14.768 {parse yymmdd} {
+    clock scan {xxxvii 12 xxxi} -format {%Oy %N %Oe} -locale en_US_roman -gmt 1
+} 2145830400
+# END testcases14
+
+test clock-15.1 {yymmdd precedence below seconds} {
+    list [clock scan {0 000101} -format {%s %y%m%d} -gmt true] \
+	[clock scan {000101 0} -format {%y%m%d %s} -gmt true]
+} {0 0}
+
+test clock-15.2 {yymmdd precedence below julian day} {
+    list [clock scan {2440588 000101} -format {%J %y%m%d} -gmt true] \
+	[clock scan {000101 2440588} -format {%y%m%d %J} -gmt true]
+} {0 0}
+
+test clock-15.3 {yymmdd precedence below yyyyWwwd} {
+    list [clock scan {1970W014000101} -format {%GW%V%u%y%m%d} -gmt true] \
+	[clock scan {0001011970W014} -format {%y%m%d%GW%V%u} -gmt true]
+} {0 0}
+
+# Test parsing of yyddd
+
+test clock-16.1 {parse yyddd} {
+    clock scan {70 001} -format {%y %j} -locale en_US_roman -gmt 1
+} 0
+test clock-16.2 {parse yyddd} {
+    clock scan {70 365} -format {%y %j} -locale en_US_roman -gmt 1
+} 31449600
+test clock-16.3 {parse yyddd} {
+    clock scan {71 001} -format {%y %j} -locale en_US_roman -gmt 1
+} 31536000
+test clock-16.4 {parse yyddd} {
+    clock scan {71 365} -format {%y %j} -locale en_US_roman -gmt 1
+} 62985600
+test clock-16.5 {parse yyddd} {
+    clock scan {00 001} -format {%y %j} -locale en_US_roman -gmt 1
+} 946684800
+test clock-16.6 {parse yyddd} {
+    clock scan {00 365} -format {%y %j} -locale en_US_roman -gmt 1
+} 978134400
+test clock-16.7 {parse yyddd} {
+    clock scan {01 001} -format {%y %j} -locale en_US_roman -gmt 1
+} 978307200
+test clock-16.8 {parse yyddd} {
+    clock scan {01 365} -format {%y %j} -locale en_US_roman -gmt 1
+} 1009756800
+
+test clock-16.9 {seconds take precedence over yyddd} {
+    list [clock scan {0 00001} -format {%s %y%j} -gmt true] \
+	 [clock scan {00001 0} -format {%y%j %s} -gmt true]
+} {0 0}
+test clock-16.10 {julian day takes precedence over yyddd} {
+    list [clock scan {2440588 00001} -format {%J %y%j} -gmt true] \
+	 [clock scan {00001 2440588} -format {%Y%j %J} -gmt true]
+} {0 0}
+test clock-16.11 {yyddd precedence below yyyyWwwd} {
+    list [clock scan {1970W01400001} -format {%GW%V%u%y%j} -gmt true] \
+	[clock scan {000011970W014} -format {%y%j%GW%V%u} -gmt true]
+} {0 0}
+
+# BEGIN testcases17
+
+# Test parsing of yyWwwd
+
+test clock-17.1 {parse yyWwwd} {
+    clock scan {70 W01 Fri} -format {%g W%V %a} -locale en_US_roman -gmt 1
+} 86400
+test clock-17.2 {parse yyWwwd} {
+    clock scan {70 W01 Friday} -format {%g W%V %A} -locale en_US_roman -gmt 1
+} 86400
+test clock-17.3 {parse yyWwwd} {
+    clock scan {70 W01 5} -format {%g W%V %u} -locale en_US_roman -gmt 1
+} 86400
+test clock-17.4 {parse yyWwwd} {
+    clock scan {70 W01 5} -format {%g W%V %w} -locale en_US_roman -gmt 1
+} 86400
+test clock-17.5 {parse yyWwwd} {
+    clock scan {70 W01 v} -format {%g W%V %Ou} -locale en_US_roman -gmt 1
+} 86400
+test clock-17.6 {parse yyWwwd} {
+    clock scan {70 W01 v} -format {%g W%V %Ow} -locale en_US_roman -gmt 1
+} 86400
+test clock-17.7 {parse yyWwwd} {
+    clock scan {70 W05 Sat} -format {%g W%V %a} -locale en_US_roman -gmt 1
+} 2592000
+test clock-17.8 {parse yyWwwd} {
+    clock scan {70 W05 Saturday} -format {%g W%V %A} -locale en_US_roman -gmt 1
+} 2592000
+test clock-17.9 {parse yyWwwd} {
+    clock scan {70 W05 6} -format {%g W%V %u} -locale en_US_roman -gmt 1
+} 2592000
+test clock-17.10 {parse yyWwwd} {
+    clock scan {70 W05 6} -format {%g W%V %w} -locale en_US_roman -gmt 1
+} 2592000
+test clock-17.11 {parse yyWwwd} {
+    clock scan {70 W05 vi} -format {%g W%V %Ou} -locale en_US_roman -gmt 1
+} 2592000
+test clock-17.12 {parse yyWwwd} {
+    clock scan {70 W05 vi} -format {%g W%V %Ow} -locale en_US_roman -gmt 1
+} 2592000
+test clock-17.13 {parse yyWwwd} {
+    clock scan {70 W49 Wed} -format {%g W%V %a} -locale en_US_roman -gmt 1
+} 28944000
+test clock-17.14 {parse yyWwwd} {
+    clock scan {70 W49 Wednesday} -format {%g W%V %A} -locale en_US_roman -gmt 1
+} 28944000
+test clock-17.15 {parse yyWwwd} {
+    clock scan {70 W49 3} -format {%g W%V %u} -locale en_US_roman -gmt 1
+} 28944000
+test clock-17.16 {parse yyWwwd} {
+    clock scan {70 W49 3} -format {%g W%V %w} -locale en_US_roman -gmt 1
+} 28944000
+test clock-17.17 {parse yyWwwd} {
+    clock scan {70 W49 iii} -format {%g W%V %Ou} -locale en_US_roman -gmt 1
+} 28944000
+test clock-17.18 {parse yyWwwd} {
+    clock scan {70 W49 iii} -format {%g W%V %Ow} -locale en_US_roman -gmt 1
+} 28944000
+test clock-17.19 {parse yyWwwd} {
+    clock scan {70 W53 Thu} -format {%g W%V %a} -locale en_US_roman -gmt 1
+} 31449600
+test clock-17.20 {parse yyWwwd} {
+    clock scan {70 W53 Thursday} -format {%g W%V %A} -locale en_US_roman -gmt 1
+} 31449600
+test clock-17.21 {parse yyWwwd} {
+    clock scan {70 W53 4} -format {%g W%V %u} -locale en_US_roman -gmt 1
+} 31449600
+test clock-17.22 {parse yyWwwd} {
+    clock scan {70 W53 4} -format {%g W%V %w} -locale en_US_roman -gmt 1
+} 31449600
+test clock-17.23 {parse yyWwwd} {
+    clock scan {70 W53 iv} -format {%g W%V %Ou} -locale en_US_roman -gmt 1
+} 31449600
+test clock-17.24 {parse yyWwwd} {
+    clock scan {70 W53 iv} -format {%g W%V %Ow} -locale en_US_roman -gmt 1
+} 31449600
+test clock-17.25 {parse yyWwwd} {
+    clock scan {70 W53 Sat} -format {%g W%V %a} -locale en_US_roman -gmt 1
+} 31622400
+test clock-17.26 {parse yyWwwd} {
+    clock scan {70 W53 Saturday} -format {%g W%V %A} -locale en_US_roman -gmt 1
+} 31622400
+test clock-17.27 {parse yyWwwd} {
+    clock scan {70 W53 6} -format {%g W%V %u} -locale en_US_roman -gmt 1
+} 31622400
+test clock-17.28 {parse yyWwwd} {
+    clock scan {70 W53 6} -format {%g W%V %w} -locale en_US_roman -gmt 1
+} 31622400
+test clock-17.29 {parse yyWwwd} {
+    clock scan {70 W53 vi} -format {%g W%V %Ou} -locale en_US_roman -gmt 1
+} 31622400
+test clock-17.30 {parse yyWwwd} {
+    clock scan {70 W53 vi} -format {%g W%V %Ow} -locale en_US_roman -gmt 1
+} 31622400
+test clock-17.31 {parse yyWwwd} {
+    clock scan {71 W04 Sun} -format {%g W%V %a} -locale en_US_roman -gmt 1
+} 34128000
+test clock-17.32 {parse yyWwwd} {
+    clock scan {71 W04 Sunday} -format {%g W%V %A} -locale en_US_roman -gmt 1
+} 34128000
+test clock-17.33 {parse yyWwwd} {
+    clock scan {71 W04 7} -format {%g W%V %u} -locale en_US_roman -gmt 1
+} 34128000
+test clock-17.34 {parse yyWwwd} {
+    clock scan {71 W04 0} -format {%g W%V %w} -locale en_US_roman -gmt 1
+} 34128000
+test clock-17.35 {parse yyWwwd} {
+    clock scan {71 W04 vii} -format {%g W%V %Ou} -locale en_US_roman -gmt 1
+} 34128000
+test clock-17.36 {parse yyWwwd} {
+    clock scan {71 W04 ?} -format {%g W%V %Ow} -locale en_US_roman -gmt 1
+} 34128000
+test clock-17.37 {parse yyWwwd} {
+    clock scan {71 W48 Thu} -format {%g W%V %a} -locale en_US_roman -gmt 1
+} 60480000
+test clock-17.38 {parse yyWwwd} {
+    clock scan {71 W48 Thursday} -format {%g W%V %A} -locale en_US_roman -gmt 1
+} 60480000
+test clock-17.39 {parse yyWwwd} {
+    clock scan {71 W48 4} -format {%g W%V %u} -locale en_US_roman -gmt 1
+} 60480000
+test clock-17.40 {parse yyWwwd} {
+    clock scan {71 W48 4} -format {%g W%V %w} -locale en_US_roman -gmt 1
+} 60480000
+test clock-17.41 {parse yyWwwd} {
+    clock scan {71 W48 iv} -format {%g W%V %Ou} -locale en_US_roman -gmt 1
+} 60480000
+test clock-17.42 {parse yyWwwd} {
+    clock scan {71 W48 iv} -format {%g W%V %Ow} -locale en_US_roman -gmt 1
+} 60480000
+test clock-17.43 {parse yyWwwd} {
+    clock scan {71 W52 Fri} -format {%g W%V %a} -locale en_US_roman -gmt 1
+} 62985600
+test clock-17.44 {parse yyWwwd} {
+    clock scan {71 W52 Friday} -format {%g W%V %A} -locale en_US_roman -gmt 1
+} 62985600
+test clock-17.45 {parse yyWwwd} {
+    clock scan {71 W52 5} -format {%g W%V %u} -locale en_US_roman -gmt 1
+} 62985600
+test clock-17.46 {parse yyWwwd} {
+    clock scan {71 W52 5} -format {%g W%V %w} -locale en_US_roman -gmt 1
+} 62985600
+test clock-17.47 {parse yyWwwd} {
+    clock scan {71 W52 v} -format {%g W%V %Ou} -locale en_US_roman -gmt 1
+} 62985600
+test clock-17.48 {parse yyWwwd} {
+    clock scan {71 W52 v} -format {%g W%V %Ow} -locale en_US_roman -gmt 1
+} 62985600
+test clock-17.49 {parse yyWwwd} {
+    clock scan {99 W52 Sun} -format {%g W%V %a} -locale en_US_roman -gmt 1
+} 946771200
+test clock-17.50 {parse yyWwwd} {
+    clock scan {99 W52 Sunday} -format {%g W%V %A} -locale en_US_roman -gmt 1
+} 946771200
+test clock-17.51 {parse yyWwwd} {
+    clock scan {99 W52 7} -format {%g W%V %u} -locale en_US_roman -gmt 1
+} 946771200
+test clock-17.52 {parse yyWwwd} {
+    clock scan {99 W52 0} -format {%g W%V %w} -locale en_US_roman -gmt 1
+} 946771200
+test clock-17.53 {parse yyWwwd} {
+    clock scan {99 W52 vii} -format {%g W%V %Ou} -locale en_US_roman -gmt 1
+} 946771200
+test clock-17.54 {parse yyWwwd} {
+    clock scan {99 W52 ?} -format {%g W%V %Ow} -locale en_US_roman -gmt 1
+} 946771200
+test clock-17.55 {parse yyWwwd} {
+    clock scan {00 W05 Mon} -format {%g W%V %a} -locale en_US_roman -gmt 1
+} 949276800
+test clock-17.56 {parse yyWwwd} {
+    clock scan {00 W05 Monday} -format {%g W%V %A} -locale en_US_roman -gmt 1
+} 949276800
+test clock-17.57 {parse yyWwwd} {
+    clock scan {00 W05 1} -format {%g W%V %u} -locale en_US_roman -gmt 1
+} 949276800
+test clock-17.58 {parse yyWwwd} {
+    clock scan {00 W05 1} -format {%g W%V %w} -locale en_US_roman -gmt 1
+} 949276800
+test clock-17.59 {parse yyWwwd} {
+    clock scan {00 W05 i} -format {%g W%V %Ou} -locale en_US_roman -gmt 1
+} 949276800
+test clock-17.60 {parse yyWwwd} {
+    clock scan {00 W05 i} -format {%g W%V %Ow} -locale en_US_roman -gmt 1
+} 949276800
+test clock-17.61 {parse yyWwwd} {
+    clock scan {00 W48 Sat} -format {%g W%V %a} -locale en_US_roman -gmt 1
+} 975715200
+test clock-17.62 {parse yyWwwd} {
+    clock scan {00 W48 Saturday} -format {%g W%V %A} -locale en_US_roman -gmt 1
+} 975715200
+test clock-17.63 {parse yyWwwd} {
+    clock scan {00 W48 6} -format {%g W%V %u} -locale en_US_roman -gmt 1
+} 975715200
+test clock-17.64 {parse yyWwwd} {
+    clock scan {00 W48 6} -format {%g W%V %w} -locale en_US_roman -gmt 1
+} 975715200
+test clock-17.65 {parse yyWwwd} {
+    clock scan {00 W48 vi} -format {%g W%V %Ou} -locale en_US_roman -gmt 1
+} 975715200
+test clock-17.66 {parse yyWwwd} {
+    clock scan {00 W48 vi} -format {%g W%V %Ow} -locale en_US_roman -gmt 1
+} 975715200
+test clock-17.67 {parse yyWwwd} {
+    clock scan {00 W52 Sun} -format {%g W%V %a} -locale en_US_roman -gmt 1
+} 978220800
+test clock-17.68 {parse yyWwwd} {
+    clock scan {00 W52 Sunday} -format {%g W%V %A} -locale en_US_roman -gmt 1
+} 978220800
+test clock-17.69 {parse yyWwwd} {
+    clock scan {00 W52 7} -format {%g W%V %u} -locale en_US_roman -gmt 1
+} 978220800
+test clock-17.70 {parse yyWwwd} {
+    clock scan {00 W52 0} -format {%g W%V %w} -locale en_US_roman -gmt 1
+} 978220800
+test clock-17.71 {parse yyWwwd} {
+    clock scan {00 W52 vii} -format {%g W%V %Ou} -locale en_US_roman -gmt 1
+} 978220800
+test clock-17.72 {parse yyWwwd} {
+    clock scan {00 W52 ?} -format {%g W%V %Ow} -locale en_US_roman -gmt 1
+} 978220800
+test clock-17.73 {parse yyWwwd} {
+    clock scan {01 W01 Tue} -format {%g W%V %a} -locale en_US_roman -gmt 1
+} 978393600
+test clock-17.74 {parse yyWwwd} {
+    clock scan {01 W01 Tuesday} -format {%g W%V %A} -locale en_US_roman -gmt 1
+} 978393600
+test clock-17.75 {parse yyWwwd} {
+    clock scan {01 W01 2} -format {%g W%V %u} -locale en_US_roman -gmt 1
+} 978393600
+test clock-17.76 {parse yyWwwd} {
+    clock scan {01 W01 2} -format {%g W%V %w} -locale en_US_roman -gmt 1
+} 978393600
+test clock-17.77 {parse yyWwwd} {
+    clock scan {01 W01 ii} -format {%g W%V %Ou} -locale en_US_roman -gmt 1
+} 978393600
+test clock-17.78 {parse yyWwwd} {
+    clock scan {01 W01 ii} -format {%g W%V %Ow} -locale en_US_roman -gmt 1
+} 978393600
+test clock-17.79 {parse yyWwwd} {
+    clock scan {01 W05 Wed} -format {%g W%V %a} -locale en_US_roman -gmt 1
+} 980899200
+test clock-17.80 {parse yyWwwd} {
+    clock scan {01 W05 Wednesday} -format {%g W%V %A} -locale en_US_roman -gmt 1
+} 980899200
+test clock-17.81 {parse yyWwwd} {
+    clock scan {01 W05 3} -format {%g W%V %u} -locale en_US_roman -gmt 1
+} 980899200
+test clock-17.82 {parse yyWwwd} {
+    clock scan {01 W05 3} -format {%g W%V %w} -locale en_US_roman -gmt 1
+} 980899200
+test clock-17.83 {parse yyWwwd} {
+    clock scan {01 W05 iii} -format {%g W%V %Ou} -locale en_US_roman -gmt 1
+} 980899200
+test clock-17.84 {parse yyWwwd} {
+    clock scan {01 W05 iii} -format {%g W%V %Ow} -locale en_US_roman -gmt 1
+} 980899200
+test clock-17.85 {parse yyWwwd} {
+    clock scan {01 W48 Sun} -format {%g W%V %a} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-17.86 {parse yyWwwd} {
+    clock scan {01 W48 Sunday} -format {%g W%V %A} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-17.87 {parse yyWwwd} {
+    clock scan {01 W48 7} -format {%g W%V %u} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-17.88 {parse yyWwwd} {
+    clock scan {01 W48 0} -format {%g W%V %w} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-17.89 {parse yyWwwd} {
+    clock scan {01 W48 vii} -format {%g W%V %Ou} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-17.90 {parse yyWwwd} {
+    clock scan {01 W48 ?} -format {%g W%V %Ow} -locale en_US_roman -gmt 1
+} 1007251200
+test clock-17.91 {parse yyWwwd} {
+    clock scan {02 W01 Mon} -format {%g W%V %a} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-17.92 {parse yyWwwd} {
+    clock scan {02 W01 Monday} -format {%g W%V %A} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-17.93 {parse yyWwwd} {
+    clock scan {02 W01 1} -format {%g W%V %u} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-17.94 {parse yyWwwd} {
+    clock scan {02 W01 1} -format {%g W%V %w} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-17.95 {parse yyWwwd} {
+    clock scan {02 W01 i} -format {%g W%V %Ou} -locale en_US_roman -gmt 1
+} 1009756800
+test clock-17.96 {parse yyWwwd} {
+    clock scan {02 W01 i} -format {%g W%V %Ow} -locale en_US_roman -gmt 1
+} 1009756800
+# END testcases17
+
+# Test precedence of yyWwwd
+
+test clock-18.1 {seconds take precedence over yyWwwd} {
+    list [clock scan {0 00W014} -format {%s %gW%V%u} -gmt true] \
+	 [clock scan {00W014 0} -format {%gW%V%u %s} -gmt true]
+} {0 0}
+test clock-18.2 {julian day takes precedence over yyddd} {
+    list [clock scan {2440588 00W014} -format {%J %gW%V%u} -gmt true] \
+	 [clock scan {00W014 2440588} -format {%gW%V%u %J} -gmt true]
+} {0 0}
+test clock-18.3 {yyWwwd precedence below yyyymmdd} {
+    list [clock scan {19700101 00W014} -format {%Y%m%d %gW%V%u} -gmt true] \
+	[clock scan {00W014 19700101} -format {%gW%V%u %Y%m%d} -gmt true]
+} {0 0}
+test clock-18.4 {yyWwwd precedence below yyyyddd} {
+    list [clock scan {1970001 00W014} -format {%Y%j %gW%V%u} -gmt true] \
+	[clock scan {00W014 1970001} -format {%gW%V%u %Y%j} -gmt true]
+} {0 0}
+
+# BEGIN testcases19
+
+# Test parsing of mmdd
+
+test clock-19.1 {parse mmdd} {
+    clock scan {Jan 02} -format {%b %d} -locale en_US_roman -base -1009843200 -gmt 1
+} -1009756800
+test clock-19.2 {parse mmdd} {
+    clock scan {Jan ii} -format {%b %Od} -locale en_US_roman -base -1009843200 -gmt 1
+} -1009756800
+test clock-19.3 {parse mmdd} {
+    clock scan {Jan  2} -format {%b %e} -locale en_US_roman -base -1009843200 -gmt 1
+} -1009756800
+test clock-19.4 {parse mmdd} {
+    clock scan {Jan ii} -format {%b %Oe} -locale en_US_roman -base -1009843200 -gmt 1
+} -1009756800
+test clock-19.5 {parse mmdd} {
+    clock scan {January 02} -format {%B %d} -locale en_US_roman -base -1009843200 -gmt 1
+} -1009756800
+test clock-19.6 {parse mmdd} {
+    clock scan {January ii} -format {%B %Od} -locale en_US_roman -base -1009843200 -gmt 1
+} -1009756800
+test clock-19.7 {parse mmdd} {
+    clock scan {January  2} -format {%B %e} -locale en_US_roman -base -1009843200 -gmt 1
+} -1009756800
+test clock-19.8 {parse mmdd} {
+    clock scan {January ii} -format {%B %Oe} -locale en_US_roman -base -1009843200 -gmt 1
+} -1009756800
+test clock-19.9 {parse mmdd} {
+    clock scan {Jan 02} -format {%h %d} -locale en_US_roman -base -1009843200 -gmt 1
+} -1009756800
+test clock-19.10 {parse mmdd} {
+    clock scan {Jan ii} -format {%h %Od} -locale en_US_roman -base -1009843200 -gmt 1
+} -1009756800
+test clock-19.11 {parse mmdd} {
+    clock scan {Jan  2} -format {%h %e} -locale en_US_roman -base -1009843200 -gmt 1
+} -1009756800
+test clock-19.12 {parse mmdd} {
+    clock scan {Jan ii} -format {%h %Oe} -locale en_US_roman -base -1009843200 -gmt 1
+} -1009756800
+test clock-19.13 {parse mmdd} {
+    clock scan {01 02} -format {%m %d} -locale en_US_roman -base -1009843200 -gmt 1
+} -1009756800
+test clock-19.14 {parse mmdd} {
+    clock scan {01 ii} -format {%m %Od} -locale en_US_roman -base -1009843200 -gmt 1
+} -1009756800
+test clock-19.15 {parse mmdd} {
+    clock scan {01  2} -format {%m %e} -locale en_US_roman -base -1009843200 -gmt 1
+} -1009756800
+test clock-19.16 {parse mmdd} {
+    clock scan {01 ii} -format {%m %Oe} -locale en_US_roman -base -1009843200 -gmt 1
+} -1009756800
+test clock-19.17 {parse mmdd} {
+    clock scan {i 02} -format {%Om %d} -locale en_US_roman -base -1009843200 -gmt 1
+} -1009756800
+test clock-19.18 {parse mmdd} {
+    clock scan {i ii} -format {%Om %Od} -locale en_US_roman -base -1009843200 -gmt 1
+} -1009756800
+test clock-19.19 {parse mmdd} {
+    clock scan {i  2} -format {%Om %e} -locale en_US_roman -base -1009843200 -gmt 1
+} -1009756800
+test clock-19.20 {parse mmdd} {
+    clock scan {i ii} -format {%Om %Oe} -locale en_US_roman -base -1009843200 -gmt 1
+} -1009756800
+test clock-19.21 {parse mmdd} {
+    clock scan { 1 02} -format {%N %d} -locale en_US_roman -base -1009843200 -gmt 1
+} -1009756800
+test clock-19.22 {parse mmdd} {
+    clock scan { 1 ii} -format {%N %Od} -locale en_US_roman -base -1009843200 -gmt 1
+} -1009756800
+test clock-19.23 {parse mmdd} {
+    clock scan { 1  2} -format {%N %e} -locale en_US_roman -base -1009843200 -gmt 1
+} -1009756800
+test clock-19.24 {parse mmdd} {
+    clock scan { 1 ii} -format {%N %Oe} -locale en_US_roman -base -1009843200 -gmt 1
+} -1009756800
+test clock-19.25 {parse mmdd} {
+    clock scan {Jan 31} -format {%b %d} -locale en_US_roman -base -1009843200 -gmt 1
+} -1007251200
+test clock-19.26 {parse mmdd} {
+    clock scan {Jan xxxi} -format {%b %Od} -locale en_US_roman -base -1009843200 -gmt 1
+} -1007251200
+test clock-19.27 {parse mmdd} {
+    clock scan {Jan 31} -format {%b %e} -locale en_US_roman -base -1009843200 -gmt 1
+} -1007251200
+test clock-19.28 {parse mmdd} {
+    clock scan {Jan xxxi} -format {%b %Oe} -locale en_US_roman -base -1009843200 -gmt 1
+} -1007251200
+test clock-19.29 {parse mmdd} {
+    clock scan {January 31} -format {%B %d} -locale en_US_roman -base -1009843200 -gmt 1
+} -1007251200
+test clock-19.30 {parse mmdd} {
+    clock scan {January xxxi} -format {%B %Od} -locale en_US_roman -base -1009843200 -gmt 1
+} -1007251200
+test clock-19.31 {parse mmdd} {
+    clock scan {January 31} -format {%B %e} -locale en_US_roman -base -1009843200 -gmt 1
+} -1007251200
+test clock-19.32 {parse mmdd} {
+    clock scan {January xxxi} -format {%B %Oe} -locale en_US_roman -base -1009843200 -gmt 1
+} -1007251200
+test clock-19.33 {parse mmdd} {
+    clock scan {Jan 31} -format {%h %d} -locale en_US_roman -base -1009843200 -gmt 1
+} -1007251200
+test clock-19.34 {parse mmdd} {
+    clock scan {Jan xxxi} -format {%h %Od} -locale en_US_roman -base -1009843200 -gmt 1
+} -1007251200
+test clock-19.35 {parse mmdd} {
+    clock scan {Jan 31} -format {%h %e} -locale en_US_roman -base -1009843200 -gmt 1
+} -1007251200
+test clock-19.36 {parse mmdd} {
+    clock scan {Jan xxxi} -format {%h %Oe} -locale en_US_roman -base -1009843200 -gmt 1
+} -1007251200
+test clock-19.37 {parse mmdd} {
+    clock scan {01 31} -format {%m %d} -locale en_US_roman -base -1009843200 -gmt 1
+} -1007251200
+test clock-19.38 {parse mmdd} {
+    clock scan {01 xxxi} -format {%m %Od} -locale en_US_roman -base -1009843200 -gmt 1
+} -1007251200
+test clock-19.39 {parse mmdd} {
+    clock scan {01 31} -format {%m %e} -locale en_US_roman -base -1009843200 -gmt 1
+} -1007251200
+test clock-19.40 {parse mmdd} {
+    clock scan {01 xxxi} -format {%m %Oe} -locale en_US_roman -base -1009843200 -gmt 1
+} -1007251200
+test clock-19.41 {parse mmdd} {
+    clock scan {i 31} -format {%Om %d} -locale en_US_roman -base -1009843200 -gmt 1
+} -1007251200
+test clock-19.42 {parse mmdd} {
+    clock scan {i xxxi} -format {%Om %Od} -locale en_US_roman -base -1009843200 -gmt 1
+} -1007251200
+test clock-19.43 {parse mmdd} {
+    clock scan {i 31} -format {%Om %e} -locale en_US_roman -base -1009843200 -gmt 1
+} -1007251200
+test clock-19.44 {parse mmdd} {
+    clock scan {i xxxi} -format {%Om %Oe} -locale en_US_roman -base -1009843200 -gmt 1
+} -1007251200
+test clock-19.45 {parse mmdd} {
+    clock scan { 1 31} -format {%N %d} -locale en_US_roman -base -1009843200 -gmt 1
+} -1007251200
+test clock-19.46 {parse mmdd} {
+    clock scan { 1 xxxi} -format {%N %Od} -locale en_US_roman -base -1009843200 -gmt 1
+} -1007251200
+test clock-19.47 {parse mmdd} {
+    clock scan { 1 31} -format {%N %e} -locale en_US_roman -base -1009843200 -gmt 1
+} -1007251200
+test clock-19.48 {parse mmdd} {
+    clock scan { 1 xxxi} -format {%N %Oe} -locale en_US_roman -base -1009843200 -gmt 1
+} -1007251200
+test clock-19.49 {parse mmdd} {
+    clock scan {Dec 02} -format {%b %d} -locale en_US_roman -base -1009843200 -gmt 1
+} -980899200
+test clock-19.50 {parse mmdd} {
+    clock scan {Dec ii} -format {%b %Od} -locale en_US_roman -base -1009843200 -gmt 1
+} -980899200
+test clock-19.51 {parse mmdd} {
+    clock scan {Dec  2} -format {%b %e} -locale en_US_roman -base -1009843200 -gmt 1
+} -980899200
+test clock-19.52 {parse mmdd} {
+    clock scan {Dec ii} -format {%b %Oe} -locale en_US_roman -base -1009843200 -gmt 1
+} -980899200
+test clock-19.53 {parse mmdd} {
+    clock scan {December 02} -format {%B %d} -locale en_US_roman -base -1009843200 -gmt 1
+} -980899200
+test clock-19.54 {parse mmdd} {
+    clock scan {December ii} -format {%B %Od} -locale en_US_roman -base -1009843200 -gmt 1
+} -980899200
+test clock-19.55 {parse mmdd} {
+    clock scan {December  2} -format {%B %e} -locale en_US_roman -base -1009843200 -gmt 1
+} -980899200
+test clock-19.56 {parse mmdd} {
+    clock scan {December ii} -format {%B %Oe} -locale en_US_roman -base -1009843200 -gmt 1
+} -980899200
+test clock-19.57 {parse mmdd} {
+    clock scan {Dec 02} -format {%h %d} -locale en_US_roman -base -1009843200 -gmt 1
+} -980899200
+test clock-19.58 {parse mmdd} {
+    clock scan {Dec ii} -format {%h %Od} -locale en_US_roman -base -1009843200 -gmt 1
+} -980899200
+test clock-19.59 {parse mmdd} {
+    clock scan {Dec  2} -format {%h %e} -locale en_US_roman -base -1009843200 -gmt 1
+} -980899200
+test clock-19.60 {parse mmdd} {
+    clock scan {Dec ii} -format {%h %Oe} -locale en_US_roman -base -1009843200 -gmt 1
+} -980899200
+test clock-19.61 {parse mmdd} {
+    clock scan {12 02} -format {%m %d} -locale en_US_roman -base -1009843200 -gmt 1
+} -980899200
+test clock-19.62 {parse mmdd} {
+    clock scan {12 ii} -format {%m %Od} -locale en_US_roman -base -1009843200 -gmt 1
+} -980899200
+test clock-19.63 {parse mmdd} {
+    clock scan {12  2} -format {%m %e} -locale en_US_roman -base -1009843200 -gmt 1
+} -980899200
+test clock-19.64 {parse mmdd} {
+    clock scan {12 ii} -format {%m %Oe} -locale en_US_roman -base -1009843200 -gmt 1
+} -980899200
+test clock-19.65 {parse mmdd} {
+    clock scan {xii 02} -format {%Om %d} -locale en_US_roman -base -1009843200 -gmt 1
+} -980899200
+test clock-19.66 {parse mmdd} {
+    clock scan {xii ii} -format {%Om %Od} -locale en_US_roman -base -1009843200 -gmt 1
+} -980899200
+test clock-19.67 {parse mmdd} {
+    clock scan {xii  2} -format {%Om %e} -locale en_US_roman -base -1009843200 -gmt 1
+} -980899200
+test clock-19.68 {parse mmdd} {
+    clock scan {xii ii} -format {%Om %Oe} -locale en_US_roman -base -1009843200 -gmt 1
+} -980899200
+test clock-19.69 {parse mmdd} {
+    clock scan {12 02} -format {%N %d} -locale en_US_roman -base -1009843200 -gmt 1
+} -980899200
+test clock-19.70 {parse mmdd} {
+    clock scan {12 ii} -format {%N %Od} -locale en_US_roman -base -1009843200 -gmt 1
+} -980899200
+test clock-19.71 {parse mmdd} {
+    clock scan {12  2} -format {%N %e} -locale en_US_roman -base -1009843200 -gmt 1
+} -980899200
+test clock-19.72 {parse mmdd} {
+    clock scan {12 ii} -format {%N %Oe} -locale en_US_roman -base -1009843200 -gmt 1
+} -980899200
+test clock-19.73 {parse mmdd} {
+    clock scan {Dec 31} -format {%b %d} -locale en_US_roman -base -1009843200 -gmt 1
+} -978393600
+test clock-19.74 {parse mmdd} {
+    clock scan {Dec xxxi} -format {%b %Od} -locale en_US_roman -base -1009843200 -gmt 1
+} -978393600
+test clock-19.75 {parse mmdd} {
+    clock scan {Dec 31} -format {%b %e} -locale en_US_roman -base -1009843200 -gmt 1
+} -978393600
+test clock-19.76 {parse mmdd} {
+    clock scan {Dec xxxi} -format {%b %Oe} -locale en_US_roman -base -1009843200 -gmt 1
+} -978393600
+test clock-19.77 {parse mmdd} {
+    clock scan {December 31} -format {%B %d} -locale en_US_roman -base -1009843200 -gmt 1
+} -978393600
+test clock-19.78 {parse mmdd} {
+    clock scan {December xxxi} -format {%B %Od} -locale en_US_roman -base -1009843200 -gmt 1
+} -978393600
+test clock-19.79 {parse mmdd} {
+    clock scan {December 31} -format {%B %e} -locale en_US_roman -base -1009843200 -gmt 1
+} -978393600
+test clock-19.80 {parse mmdd} {
+    clock scan {December xxxi} -format {%B %Oe} -locale en_US_roman -base -1009843200 -gmt 1
+} -978393600
+test clock-19.81 {parse mmdd} {
+    clock scan {Dec 31} -format {%h %d} -locale en_US_roman -base -1009843200 -gmt 1
+} -978393600
+test clock-19.82 {parse mmdd} {
+    clock scan {Dec xxxi} -format {%h %Od} -locale en_US_roman -base -1009843200 -gmt 1
+} -978393600
+test clock-19.83 {parse mmdd} {
+    clock scan {Dec 31} -format {%h %e} -locale en_US_roman -base -1009843200 -gmt 1
+} -978393600
+test clock-19.84 {parse mmdd} {
+    clock scan {Dec xxxi} -format {%h %Oe} -locale en_US_roman -base -1009843200 -gmt 1
+} -978393600
+test clock-19.85 {parse mmdd} {
+    clock scan {12 31} -format {%m %d} -locale en_US_roman -base -1009843200 -gmt 1
+} -978393600
+test clock-19.86 {parse mmdd} {
+    clock scan {12 xxxi} -format {%m %Od} -locale en_US_roman -base -1009843200 -gmt 1
+} -978393600
+test clock-19.87 {parse mmdd} {
+    clock scan {12 31} -format {%m %e} -locale en_US_roman -base -1009843200 -gmt 1
+} -978393600
+test clock-19.88 {parse mmdd} {
+    clock scan {12 xxxi} -format {%m %Oe} -locale en_US_roman -base -1009843200 -gmt 1
+} -978393600
+test clock-19.89 {parse mmdd} {
+    clock scan {xii 31} -format {%Om %d} -locale en_US_roman -base -1009843200 -gmt 1
+} -978393600
+test clock-19.90 {parse mmdd} {
+    clock scan {xii xxxi} -format {%Om %Od} -locale en_US_roman -base -1009843200 -gmt 1
+} -978393600
+test clock-19.91 {parse mmdd} {
+    clock scan {xii 31} -format {%Om %e} -locale en_US_roman -base -1009843200 -gmt 1
+} -978393600
+test clock-19.92 {parse mmdd} {
+    clock scan {xii xxxi} -format {%Om %Oe} -locale en_US_roman -base -1009843200 -gmt 1
+} -978393600
+test clock-19.93 {parse mmdd} {
+    clock scan {12 31} -format {%N %d} -locale en_US_roman -base -1009843200 -gmt 1
+} -978393600
+test clock-19.94 {parse mmdd} {
+    clock scan {12 xxxi} -format {%N %Od} -locale en_US_roman -base -1009843200 -gmt 1
+} -978393600
+test clock-19.95 {parse mmdd} {
+    clock scan {12 31} -format {%N %e} -locale en_US_roman -base -1009843200 -gmt 1
+} -978393600
+test clock-19.96 {parse mmdd} {
+    clock scan {12 xxxi} -format {%N %Oe} -locale en_US_roman -base -1009843200 -gmt 1
+} -978393600
+test clock-19.97 {parse mmdd} {
+    clock scan {Jan 02} -format {%b %d} -locale en_US_roman -base 0 -gmt 1
+} 86400
+test clock-19.98 {parse mmdd} {
+    clock scan {Jan ii} -format {%b %Od} -locale en_US_roman -base 0 -gmt 1
+} 86400
+test clock-19.99 {parse mmdd} {
+    clock scan {Jan  2} -format {%b %e} -locale en_US_roman -base 0 -gmt 1
+} 86400
+test clock-19.100 {parse mmdd} {
+    clock scan {Jan ii} -format {%b %Oe} -locale en_US_roman -base 0 -gmt 1
+} 86400
+test clock-19.101 {parse mmdd} {
+    clock scan {January 02} -format {%B %d} -locale en_US_roman -base 0 -gmt 1
+} 86400
+test clock-19.102 {parse mmdd} {
+    clock scan {January ii} -format {%B %Od} -locale en_US_roman -base 0 -gmt 1
+} 86400
+test clock-19.103 {parse mmdd} {
+    clock scan {January  2} -format {%B %e} -locale en_US_roman -base 0 -gmt 1
+} 86400
+test clock-19.104 {parse mmdd} {
+    clock scan {January ii} -format {%B %Oe} -locale en_US_roman -base 0 -gmt 1
+} 86400
+test clock-19.105 {parse mmdd} {
+    clock scan {Jan 02} -format {%h %d} -locale en_US_roman -base 0 -gmt 1
+} 86400
+test clock-19.106 {parse mmdd} {
+    clock scan {Jan ii} -format {%h %Od} -locale en_US_roman -base 0 -gmt 1
+} 86400
+test clock-19.107 {parse mmdd} {
+    clock scan {Jan  2} -format {%h %e} -locale en_US_roman -base 0 -gmt 1
+} 86400
+test clock-19.108 {parse mmdd} {
+    clock scan {Jan ii} -format {%h %Oe} -locale en_US_roman -base 0 -gmt 1
+} 86400
+test clock-19.109 {parse mmdd} {
+    clock scan {01 02} -format {%m %d} -locale en_US_roman -base 0 -gmt 1
+} 86400
+test clock-19.110 {parse mmdd} {
+    clock scan {01 ii} -format {%m %Od} -locale en_US_roman -base 0 -gmt 1
+} 86400
+test clock-19.111 {parse mmdd} {
+    clock scan {01  2} -format {%m %e} -locale en_US_roman -base 0 -gmt 1
+} 86400
+test clock-19.112 {parse mmdd} {
+    clock scan {01 ii} -format {%m %Oe} -locale en_US_roman -base 0 -gmt 1
+} 86400
+test clock-19.113 {parse mmdd} {
+    clock scan {i 02} -format {%Om %d} -locale en_US_roman -base 0 -gmt 1
+} 86400
+test clock-19.114 {parse mmdd} {
+    clock scan {i ii} -format {%Om %Od} -locale en_US_roman -base 0 -gmt 1
+} 86400
+test clock-19.115 {parse mmdd} {
+    clock scan {i  2} -format {%Om %e} -locale en_US_roman -base 0 -gmt 1
+} 86400
+test clock-19.116 {parse mmdd} {
+    clock scan {i ii} -format {%Om %Oe} -locale en_US_roman -base 0 -gmt 1
+} 86400
+test clock-19.117 {parse mmdd} {
+    clock scan { 1 02} -format {%N %d} -locale en_US_roman -base 0 -gmt 1
+} 86400
+test clock-19.118 {parse mmdd} {
+    clock scan { 1 ii} -format {%N %Od} -locale en_US_roman -base 0 -gmt 1
+} 86400
+test clock-19.119 {parse mmdd} {
+    clock scan { 1  2} -format {%N %e} -locale en_US_roman -base 0 -gmt 1
+} 86400
+test clock-19.120 {parse mmdd} {
+    clock scan { 1 ii} -format {%N %Oe} -locale en_US_roman -base 0 -gmt 1
+} 86400
+test clock-19.121 {parse mmdd} {
+    clock scan {Jan 31} -format {%b %d} -locale en_US_roman -base 0 -gmt 1
+} 2592000
+test clock-19.122 {parse mmdd} {
+    clock scan {Jan xxxi} -format {%b %Od} -locale en_US_roman -base 0 -gmt 1
+} 2592000
+test clock-19.123 {parse mmdd} {
+    clock scan {Jan 31} -format {%b %e} -locale en_US_roman -base 0 -gmt 1
+} 2592000
+test clock-19.124 {parse mmdd} {
+    clock scan {Jan xxxi} -format {%b %Oe} -locale en_US_roman -base 0 -gmt 1
+} 2592000
+test clock-19.125 {parse mmdd} {
+    clock scan {January 31} -format {%B %d} -locale en_US_roman -base 0 -gmt 1
+} 2592000
+test clock-19.126 {parse mmdd} {
+    clock scan {January xxxi} -format {%B %Od} -locale en_US_roman -base 0 -gmt 1
+} 2592000
+test clock-19.127 {parse mmdd} {
+    clock scan {January 31} -format {%B %e} -locale en_US_roman -base 0 -gmt 1
+} 2592000
+test clock-19.128 {parse mmdd} {
+    clock scan {January xxxi} -format {%B %Oe} -locale en_US_roman -base 0 -gmt 1
+} 2592000
+test clock-19.129 {parse mmdd} {
+    clock scan {Jan 31} -format {%h %d} -locale en_US_roman -base 0 -gmt 1
+} 2592000
+test clock-19.130 {parse mmdd} {
+    clock scan {Jan xxxi} -format {%h %Od} -locale en_US_roman -base 0 -gmt 1
+} 2592000
+test clock-19.131 {parse mmdd} {
+    clock scan {Jan 31} -format {%h %e} -locale en_US_roman -base 0 -gmt 1
+} 2592000
+test clock-19.132 {parse mmdd} {
+    clock scan {Jan xxxi} -format {%h %Oe} -locale en_US_roman -base 0 -gmt 1
+} 2592000
+test clock-19.133 {parse mmdd} {
+    clock scan {01 31} -format {%m %d} -locale en_US_roman -base 0 -gmt 1
+} 2592000
+test clock-19.134 {parse mmdd} {
+    clock scan {01 xxxi} -format {%m %Od} -locale en_US_roman -base 0 -gmt 1
+} 2592000
+test clock-19.135 {parse mmdd} {
+    clock scan {01 31} -format {%m %e} -locale en_US_roman -base 0 -gmt 1
+} 2592000
+test clock-19.136 {parse mmdd} {
+    clock scan {01 xxxi} -format {%m %Oe} -locale en_US_roman -base 0 -gmt 1
+} 2592000
+test clock-19.137 {parse mmdd} {
+    clock scan {i 31} -format {%Om %d} -locale en_US_roman -base 0 -gmt 1
+} 2592000
+test clock-19.138 {parse mmdd} {
+    clock scan {i xxxi} -format {%Om %Od} -locale en_US_roman -base 0 -gmt 1
+} 2592000
+test clock-19.139 {parse mmdd} {
+    clock scan {i 31} -format {%Om %e} -locale en_US_roman -base 0 -gmt 1
+} 2592000
+test clock-19.140 {parse mmdd} {
+    clock scan {i xxxi} -format {%Om %Oe} -locale en_US_roman -base 0 -gmt 1
+} 2592000
+test clock-19.141 {parse mmdd} {
+    clock scan { 1 31} -format {%N %d} -locale en_US_roman -base 0 -gmt 1
+} 2592000
+test clock-19.142 {parse mmdd} {
+    clock scan { 1 xxxi} -format {%N %Od} -locale en_US_roman -base 0 -gmt 1
+} 2592000
+test clock-19.143 {parse mmdd} {
+    clock scan { 1 31} -format {%N %e} -locale en_US_roman -base 0 -gmt 1
+} 2592000
+test clock-19.144 {parse mmdd} {
+    clock scan { 1 xxxi} -format {%N %Oe} -locale en_US_roman -base 0 -gmt 1
+} 2592000
+test clock-19.145 {parse mmdd} {
+    clock scan {Dec 02} -format {%b %d} -locale en_US_roman -base 0 -gmt 1
+} 28944000
+test clock-19.146 {parse mmdd} {
+    clock scan {Dec ii} -format {%b %Od} -locale en_US_roman -base 0 -gmt 1
+} 28944000
+test clock-19.147 {parse mmdd} {
+    clock scan {Dec  2} -format {%b %e} -locale en_US_roman -base 0 -gmt 1
+} 28944000
+test clock-19.148 {parse mmdd} {
+    clock scan {Dec ii} -format {%b %Oe} -locale en_US_roman -base 0 -gmt 1
+} 28944000
+test clock-19.149 {parse mmdd} {
+    clock scan {December 02} -format {%B %d} -locale en_US_roman -base 0 -gmt 1
+} 28944000
+test clock-19.150 {parse mmdd} {
+    clock scan {December ii} -format {%B %Od} -locale en_US_roman -base 0 -gmt 1
+} 28944000
+test clock-19.151 {parse mmdd} {
+    clock scan {December  2} -format {%B %e} -locale en_US_roman -base 0 -gmt 1
+} 28944000
+test clock-19.152 {parse mmdd} {
+    clock scan {December ii} -format {%B %Oe} -locale en_US_roman -base 0 -gmt 1
+} 28944000
+test clock-19.153 {parse mmdd} {
+    clock scan {Dec 02} -format {%h %d} -locale en_US_roman -base 0 -gmt 1
+} 28944000
+test clock-19.154 {parse mmdd} {
+    clock scan {Dec ii} -format {%h %Od} -locale en_US_roman -base 0 -gmt 1
+} 28944000
+test clock-19.155 {parse mmdd} {
+    clock scan {Dec  2} -format {%h %e} -locale en_US_roman -base 0 -gmt 1
+} 28944000
+test clock-19.156 {parse mmdd} {
+    clock scan {Dec ii} -format {%h %Oe} -locale en_US_roman -base 0 -gmt 1
+} 28944000
+test clock-19.157 {parse mmdd} {
+    clock scan {12 02} -format {%m %d} -locale en_US_roman -base 0 -gmt 1
+} 28944000
+test clock-19.158 {parse mmdd} {
+    clock scan {12 ii} -format {%m %Od} -locale en_US_roman -base 0 -gmt 1
+} 28944000
+test clock-19.159 {parse mmdd} {
+    clock scan {12  2} -format {%m %e} -locale en_US_roman -base 0 -gmt 1
+} 28944000
+test clock-19.160 {parse mmdd} {
+    clock scan {12 ii} -format {%m %Oe} -locale en_US_roman -base 0 -gmt 1
+} 28944000
+test clock-19.161 {parse mmdd} {
+    clock scan {xii 02} -format {%Om %d} -locale en_US_roman -base 0 -gmt 1
+} 28944000
+test clock-19.162 {parse mmdd} {
+    clock scan {xii ii} -format {%Om %Od} -locale en_US_roman -base 0 -gmt 1
+} 28944000
+test clock-19.163 {parse mmdd} {
+    clock scan {xii  2} -format {%Om %e} -locale en_US_roman -base 0 -gmt 1
+} 28944000
+test clock-19.164 {parse mmdd} {
+    clock scan {xii ii} -format {%Om %Oe} -locale en_US_roman -base 0 -gmt 1
+} 28944000
+test clock-19.165 {parse mmdd} {
+    clock scan {12 02} -format {%N %d} -locale en_US_roman -base 0 -gmt 1
+} 28944000
+test clock-19.166 {parse mmdd} {
+    clock scan {12 ii} -format {%N %Od} -locale en_US_roman -base 0 -gmt 1
+} 28944000
+test clock-19.167 {parse mmdd} {
+    clock scan {12  2} -format {%N %e} -locale en_US_roman -base 0 -gmt 1
+} 28944000
+test clock-19.168 {parse mmdd} {
+    clock scan {12 ii} -format {%N %Oe} -locale en_US_roman -base 0 -gmt 1
+} 28944000
+test clock-19.169 {parse mmdd} {
+    clock scan {Dec 31} -format {%b %d} -locale en_US_roman -base 0 -gmt 1
+} 31449600
+test clock-19.170 {parse mmdd} {
+    clock scan {Dec xxxi} -format {%b %Od} -locale en_US_roman -base 0 -gmt 1
+} 31449600
+test clock-19.171 {parse mmdd} {
+    clock scan {Dec 31} -format {%b %e} -locale en_US_roman -base 0 -gmt 1
+} 31449600
+test clock-19.172 {parse mmdd} {
+    clock scan {Dec xxxi} -format {%b %Oe} -locale en_US_roman -base 0 -gmt 1
+} 31449600
+test clock-19.173 {parse mmdd} {
+    clock scan {December 31} -format {%B %d} -locale en_US_roman -base 0 -gmt 1
+} 31449600
+test clock-19.174 {parse mmdd} {
+    clock scan {December xxxi} -format {%B %Od} -locale en_US_roman -base 0 -gmt 1
+} 31449600
+test clock-19.175 {parse mmdd} {
+    clock scan {December 31} -format {%B %e} -locale en_US_roman -base 0 -gmt 1
+} 31449600
+test clock-19.176 {parse mmdd} {
+    clock scan {December xxxi} -format {%B %Oe} -locale en_US_roman -base 0 -gmt 1
+} 31449600
+test clock-19.177 {parse mmdd} {
+    clock scan {Dec 31} -format {%h %d} -locale en_US_roman -base 0 -gmt 1
+} 31449600
+test clock-19.178 {parse mmdd} {
+    clock scan {Dec xxxi} -format {%h %Od} -locale en_US_roman -base 0 -gmt 1
+} 31449600
+test clock-19.179 {parse mmdd} {
+    clock scan {Dec 31} -format {%h %e} -locale en_US_roman -base 0 -gmt 1
+} 31449600
+test clock-19.180 {parse mmdd} {
+    clock scan {Dec xxxi} -format {%h %Oe} -locale en_US_roman -base 0 -gmt 1
+} 31449600
+test clock-19.181 {parse mmdd} {
+    clock scan {12 31} -format {%m %d} -locale en_US_roman -base 0 -gmt 1
+} 31449600
+test clock-19.182 {parse mmdd} {
+    clock scan {12 xxxi} -format {%m %Od} -locale en_US_roman -base 0 -gmt 1
+} 31449600
+test clock-19.183 {parse mmdd} {
+    clock scan {12 31} -format {%m %e} -locale en_US_roman -base 0 -gmt 1
+} 31449600
+test clock-19.184 {parse mmdd} {
+    clock scan {12 xxxi} -format {%m %Oe} -locale en_US_roman -base 0 -gmt 1
+} 31449600
+test clock-19.185 {parse mmdd} {
+    clock scan {xii 31} -format {%Om %d} -locale en_US_roman -base 0 -gmt 1
+} 31449600
+test clock-19.186 {parse mmdd} {
+    clock scan {xii xxxi} -format {%Om %Od} -locale en_US_roman -base 0 -gmt 1
+} 31449600
+test clock-19.187 {parse mmdd} {
+    clock scan {xii 31} -format {%Om %e} -locale en_US_roman -base 0 -gmt 1
+} 31449600
+test clock-19.188 {parse mmdd} {
+    clock scan {xii xxxi} -format {%Om %Oe} -locale en_US_roman -base 0 -gmt 1
+} 31449600
+test clock-19.189 {parse mmdd} {
+    clock scan {12 31} -format {%N %d} -locale en_US_roman -base 0 -gmt 1
+} 31449600
+test clock-19.190 {parse mmdd} {
+    clock scan {12 xxxi} -format {%N %Od} -locale en_US_roman -base 0 -gmt 1
+} 31449600
+test clock-19.191 {parse mmdd} {
+    clock scan {12 31} -format {%N %e} -locale en_US_roman -base 0 -gmt 1
+} 31449600
+test clock-19.192 {parse mmdd} {
+    clock scan {12 xxxi} -format {%N %Oe} -locale en_US_roman -base 0 -gmt 1
+} 31449600
+test clock-19.193 {parse mmdd} {
+    clock scan {Jan 02} -format {%b %d} -locale en_US_roman -base 946684800 -gmt 1
+} 946771200
+test clock-19.194 {parse mmdd} {
+    clock scan {Jan ii} -format {%b %Od} -locale en_US_roman -base 946684800 -gmt 1
+} 946771200
+test clock-19.195 {parse mmdd} {
+    clock scan {Jan  2} -format {%b %e} -locale en_US_roman -base 946684800 -gmt 1
+} 946771200
+test clock-19.196 {parse mmdd} {
+    clock scan {Jan ii} -format {%b %Oe} -locale en_US_roman -base 946684800 -gmt 1
+} 946771200
+test clock-19.197 {parse mmdd} {
+    clock scan {January 02} -format {%B %d} -locale en_US_roman -base 946684800 -gmt 1
+} 946771200
+test clock-19.198 {parse mmdd} {
+    clock scan {January ii} -format {%B %Od} -locale en_US_roman -base 946684800 -gmt 1
+} 946771200
+test clock-19.199 {parse mmdd} {
+    clock scan {January  2} -format {%B %e} -locale en_US_roman -base 946684800 -gmt 1
+} 946771200
+test clock-19.200 {parse mmdd} {
+    clock scan {January ii} -format {%B %Oe} -locale en_US_roman -base 946684800 -gmt 1
+} 946771200
+test clock-19.201 {parse mmdd} {
+    clock scan {Jan 02} -format {%h %d} -locale en_US_roman -base 946684800 -gmt 1
+} 946771200
+test clock-19.202 {parse mmdd} {
+    clock scan {Jan ii} -format {%h %Od} -locale en_US_roman -base 946684800 -gmt 1
+} 946771200
+test clock-19.203 {parse mmdd} {
+    clock scan {Jan  2} -format {%h %e} -locale en_US_roman -base 946684800 -gmt 1
+} 946771200
+test clock-19.204 {parse mmdd} {
+    clock scan {Jan ii} -format {%h %Oe} -locale en_US_roman -base 946684800 -gmt 1
+} 946771200
+test clock-19.205 {parse mmdd} {
+    clock scan {01 02} -format {%m %d} -locale en_US_roman -base 946684800 -gmt 1
+} 946771200
+test clock-19.206 {parse mmdd} {
+    clock scan {01 ii} -format {%m %Od} -locale en_US_roman -base 946684800 -gmt 1
+} 946771200
+test clock-19.207 {parse mmdd} {
+    clock scan {01  2} -format {%m %e} -locale en_US_roman -base 946684800 -gmt 1
+} 946771200
+test clock-19.208 {parse mmdd} {
+    clock scan {01 ii} -format {%m %Oe} -locale en_US_roman -base 946684800 -gmt 1
+} 946771200
+test clock-19.209 {parse mmdd} {
+    clock scan {i 02} -format {%Om %d} -locale en_US_roman -base 946684800 -gmt 1
+} 946771200
+test clock-19.210 {parse mmdd} {
+    clock scan {i ii} -format {%Om %Od} -locale en_US_roman -base 946684800 -gmt 1
+} 946771200
+test clock-19.211 {parse mmdd} {
+    clock scan {i  2} -format {%Om %e} -locale en_US_roman -base 946684800 -gmt 1
+} 946771200
+test clock-19.212 {parse mmdd} {
+    clock scan {i ii} -format {%Om %Oe} -locale en_US_roman -base 946684800 -gmt 1
+} 946771200
+test clock-19.213 {parse mmdd} {
+    clock scan { 1 02} -format {%N %d} -locale en_US_roman -base 946684800 -gmt 1
+} 946771200
+test clock-19.214 {parse mmdd} {
+    clock scan { 1 ii} -format {%N %Od} -locale en_US_roman -base 946684800 -gmt 1
+} 946771200
+test clock-19.215 {parse mmdd} {
+    clock scan { 1  2} -format {%N %e} -locale en_US_roman -base 946684800 -gmt 1
+} 946771200
+test clock-19.216 {parse mmdd} {
+    clock scan { 1 ii} -format {%N %Oe} -locale en_US_roman -base 946684800 -gmt 1
+} 946771200
+test clock-19.217 {parse mmdd} {
+    clock scan {Jan 31} -format {%b %d} -locale en_US_roman -base 946684800 -gmt 1
+} 949276800
+test clock-19.218 {parse mmdd} {
+    clock scan {Jan xxxi} -format {%b %Od} -locale en_US_roman -base 946684800 -gmt 1
+} 949276800
+test clock-19.219 {parse mmdd} {
+    clock scan {Jan 31} -format {%b %e} -locale en_US_roman -base 946684800 -gmt 1
+} 949276800
+test clock-19.220 {parse mmdd} {
+    clock scan {Jan xxxi} -format {%b %Oe} -locale en_US_roman -base 946684800 -gmt 1
+} 949276800
+test clock-19.221 {parse mmdd} {
+    clock scan {January 31} -format {%B %d} -locale en_US_roman -base 946684800 -gmt 1
+} 949276800
+test clock-19.222 {parse mmdd} {
+    clock scan {January xxxi} -format {%B %Od} -locale en_US_roman -base 946684800 -gmt 1
+} 949276800
+test clock-19.223 {parse mmdd} {
+    clock scan {January 31} -format {%B %e} -locale en_US_roman -base 946684800 -gmt 1
+} 949276800
+test clock-19.224 {parse mmdd} {
+    clock scan {January xxxi} -format {%B %Oe} -locale en_US_roman -base 946684800 -gmt 1
+} 949276800
+test clock-19.225 {parse mmdd} {
+    clock scan {Jan 31} -format {%h %d} -locale en_US_roman -base 946684800 -gmt 1
+} 949276800
+test clock-19.226 {parse mmdd} {
+    clock scan {Jan xxxi} -format {%h %Od} -locale en_US_roman -base 946684800 -gmt 1
+} 949276800
+test clock-19.227 {parse mmdd} {
+    clock scan {Jan 31} -format {%h %e} -locale en_US_roman -base 946684800 -gmt 1
+} 949276800
+test clock-19.228 {parse mmdd} {
+    clock scan {Jan xxxi} -format {%h %Oe} -locale en_US_roman -base 946684800 -gmt 1
+} 949276800
+test clock-19.229 {parse mmdd} {
+    clock scan {01 31} -format {%m %d} -locale en_US_roman -base 946684800 -gmt 1
+} 949276800
+test clock-19.230 {parse mmdd} {
+    clock scan {01 xxxi} -format {%m %Od} -locale en_US_roman -base 946684800 -gmt 1
+} 949276800
+test clock-19.231 {parse mmdd} {
+    clock scan {01 31} -format {%m %e} -locale en_US_roman -base 946684800 -gmt 1
+} 949276800
+test clock-19.232 {parse mmdd} {
+    clock scan {01 xxxi} -format {%m %Oe} -locale en_US_roman -base 946684800 -gmt 1
+} 949276800
+test clock-19.233 {parse mmdd} {
+    clock scan {i 31} -format {%Om %d} -locale en_US_roman -base 946684800 -gmt 1
+} 949276800
+test clock-19.234 {parse mmdd} {
+    clock scan {i xxxi} -format {%Om %Od} -locale en_US_roman -base 946684800 -gmt 1
+} 949276800
+test clock-19.235 {parse mmdd} {
+    clock scan {i 31} -format {%Om %e} -locale en_US_roman -base 946684800 -gmt 1
+} 949276800
+test clock-19.236 {parse mmdd} {
+    clock scan {i xxxi} -format {%Om %Oe} -locale en_US_roman -base 946684800 -gmt 1
+} 949276800
+test clock-19.237 {parse mmdd} {
+    clock scan { 1 31} -format {%N %d} -locale en_US_roman -base 946684800 -gmt 1
+} 949276800
+test clock-19.238 {parse mmdd} {
+    clock scan { 1 xxxi} -format {%N %Od} -locale en_US_roman -base 946684800 -gmt 1
+} 949276800
+test clock-19.239 {parse mmdd} {
+    clock scan { 1 31} -format {%N %e} -locale en_US_roman -base 946684800 -gmt 1
+} 949276800
+test clock-19.240 {parse mmdd} {
+    clock scan { 1 xxxi} -format {%N %Oe} -locale en_US_roman -base 946684800 -gmt 1
+} 949276800
+test clock-19.241 {parse mmdd} {
+    clock scan {Dec 02} -format {%b %d} -locale en_US_roman -base 946684800 -gmt 1
+} 975715200
+test clock-19.242 {parse mmdd} {
+    clock scan {Dec ii} -format {%b %Od} -locale en_US_roman -base 946684800 -gmt 1
+} 975715200
+test clock-19.243 {parse mmdd} {
+    clock scan {Dec  2} -format {%b %e} -locale en_US_roman -base 946684800 -gmt 1
+} 975715200
+test clock-19.244 {parse mmdd} {
+    clock scan {Dec ii} -format {%b %Oe} -locale en_US_roman -base 946684800 -gmt 1
+} 975715200
+test clock-19.245 {parse mmdd} {
+    clock scan {December 02} -format {%B %d} -locale en_US_roman -base 946684800 -gmt 1
+} 975715200
+test clock-19.246 {parse mmdd} {
+    clock scan {December ii} -format {%B %Od} -locale en_US_roman -base 946684800 -gmt 1
+} 975715200
+test clock-19.247 {parse mmdd} {
+    clock scan {December  2} -format {%B %e} -locale en_US_roman -base 946684800 -gmt 1
+} 975715200
+test clock-19.248 {parse mmdd} {
+    clock scan {December ii} -format {%B %Oe} -locale en_US_roman -base 946684800 -gmt 1
+} 975715200
+test clock-19.249 {parse mmdd} {
+    clock scan {Dec 02} -format {%h %d} -locale en_US_roman -base 946684800 -gmt 1
+} 975715200
+test clock-19.250 {parse mmdd} {
+    clock scan {Dec ii} -format {%h %Od} -locale en_US_roman -base 946684800 -gmt 1
+} 975715200
+test clock-19.251 {parse mmdd} {
+    clock scan {Dec  2} -format {%h %e} -locale en_US_roman -base 946684800 -gmt 1
+} 975715200
+test clock-19.252 {parse mmdd} {
+    clock scan {Dec ii} -format {%h %Oe} -locale en_US_roman -base 946684800 -gmt 1
+} 975715200
+test clock-19.253 {parse mmdd} {
+    clock scan {12 02} -format {%m %d} -locale en_US_roman -base 946684800 -gmt 1
+} 975715200
+test clock-19.254 {parse mmdd} {
+    clock scan {12 ii} -format {%m %Od} -locale en_US_roman -base 946684800 -gmt 1
+} 975715200
+test clock-19.255 {parse mmdd} {
+    clock scan {12  2} -format {%m %e} -locale en_US_roman -base 946684800 -gmt 1
+} 975715200
+test clock-19.256 {parse mmdd} {
+    clock scan {12 ii} -format {%m %Oe} -locale en_US_roman -base 946684800 -gmt 1
+} 975715200
+test clock-19.257 {parse mmdd} {
+    clock scan {xii 02} -format {%Om %d} -locale en_US_roman -base 946684800 -gmt 1
+} 975715200
+test clock-19.258 {parse mmdd} {
+    clock scan {xii ii} -format {%Om %Od} -locale en_US_roman -base 946684800 -gmt 1
+} 975715200
+test clock-19.259 {parse mmdd} {
+    clock scan {xii  2} -format {%Om %e} -locale en_US_roman -base 946684800 -gmt 1
+} 975715200
+test clock-19.260 {parse mmdd} {
+    clock scan {xii ii} -format {%Om %Oe} -locale en_US_roman -base 946684800 -gmt 1
+} 975715200
+test clock-19.261 {parse mmdd} {
+    clock scan {12 02} -format {%N %d} -locale en_US_roman -base 946684800 -gmt 1
+} 975715200
+test clock-19.262 {parse mmdd} {
+    clock scan {12 ii} -format {%N %Od} -locale en_US_roman -base 946684800 -gmt 1
+} 975715200
+test clock-19.263 {parse mmdd} {
+    clock scan {12  2} -format {%N %e} -locale en_US_roman -base 946684800 -gmt 1
+} 975715200
+test clock-19.264 {parse mmdd} {
+    clock scan {12 ii} -format {%N %Oe} -locale en_US_roman -base 946684800 -gmt 1
+} 975715200
+test clock-19.265 {parse mmdd} {
+    clock scan {Dec 31} -format {%b %d} -locale en_US_roman -base 946684800 -gmt 1
+} 978220800
+test clock-19.266 {parse mmdd} {
+    clock scan {Dec xxxi} -format {%b %Od} -locale en_US_roman -base 946684800 -gmt 1
+} 978220800
+test clock-19.267 {parse mmdd} {
+    clock scan {Dec 31} -format {%b %e} -locale en_US_roman -base 946684800 -gmt 1
+} 978220800
+test clock-19.268 {parse mmdd} {
+    clock scan {Dec xxxi} -format {%b %Oe} -locale en_US_roman -base 946684800 -gmt 1
+} 978220800
+test clock-19.269 {parse mmdd} {
+    clock scan {December 31} -format {%B %d} -locale en_US_roman -base 946684800 -gmt 1
+} 978220800
+test clock-19.270 {parse mmdd} {
+    clock scan {December xxxi} -format {%B %Od} -locale en_US_roman -base 946684800 -gmt 1
+} 978220800
+test clock-19.271 {parse mmdd} {
+    clock scan {December 31} -format {%B %e} -locale en_US_roman -base 946684800 -gmt 1
+} 978220800
+test clock-19.272 {parse mmdd} {
+    clock scan {December xxxi} -format {%B %Oe} -locale en_US_roman -base 946684800 -gmt 1
+} 978220800
+test clock-19.273 {parse mmdd} {
+    clock scan {Dec 31} -format {%h %d} -locale en_US_roman -base 946684800 -gmt 1
+} 978220800
+test clock-19.274 {parse mmdd} {
+    clock scan {Dec xxxi} -format {%h %Od} -locale en_US_roman -base 946684800 -gmt 1
+} 978220800
+test clock-19.275 {parse mmdd} {
+    clock scan {Dec 31} -format {%h %e} -locale en_US_roman -base 946684800 -gmt 1
+} 978220800
+test clock-19.276 {parse mmdd} {
+    clock scan {Dec xxxi} -format {%h %Oe} -locale en_US_roman -base 946684800 -gmt 1
+} 978220800
+test clock-19.277 {parse mmdd} {
+    clock scan {12 31} -format {%m %d} -locale en_US_roman -base 946684800 -gmt 1
+} 978220800
+test clock-19.278 {parse mmdd} {
+    clock scan {12 xxxi} -format {%m %Od} -locale en_US_roman -base 946684800 -gmt 1
+} 978220800
+test clock-19.279 {parse mmdd} {
+    clock scan {12 31} -format {%m %e} -locale en_US_roman -base 946684800 -gmt 1
+} 978220800
+test clock-19.280 {parse mmdd} {
+    clock scan {12 xxxi} -format {%m %Oe} -locale en_US_roman -base 946684800 -gmt 1
+} 978220800
+test clock-19.281 {parse mmdd} {
+    clock scan {xii 31} -format {%Om %d} -locale en_US_roman -base 946684800 -gmt 1
+} 978220800
+test clock-19.282 {parse mmdd} {
+    clock scan {xii xxxi} -format {%Om %Od} -locale en_US_roman -base 946684800 -gmt 1
+} 978220800
+test clock-19.283 {parse mmdd} {
+    clock scan {xii 31} -format {%Om %e} -locale en_US_roman -base 946684800 -gmt 1
+} 978220800
+test clock-19.284 {parse mmdd} {
+    clock scan {xii xxxi} -format {%Om %Oe} -locale en_US_roman -base 946684800 -gmt 1
+} 978220800
+test clock-19.285 {parse mmdd} {
+    clock scan {12 31} -format {%N %d} -locale en_US_roman -base 946684800 -gmt 1
+} 978220800
+test clock-19.286 {parse mmdd} {
+    clock scan {12 xxxi} -format {%N %Od} -locale en_US_roman -base 946684800 -gmt 1
+} 978220800
+test clock-19.287 {parse mmdd} {
+    clock scan {12 31} -format {%N %e} -locale en_US_roman -base 946684800 -gmt 1
+} 978220800
+test clock-19.288 {parse mmdd} {
+    clock scan {12 xxxi} -format {%N %Oe} -locale en_US_roman -base 946684800 -gmt 1
+} 978220800
+test clock-19.289 {parse mmdd} {
+    clock scan {Jan 02} -format {%b %d} -locale en_US_roman -base 2114380800 -gmt 1
+} 2114467200
+test clock-19.290 {parse mmdd} {
+    clock scan {Jan ii} -format {%b %Od} -locale en_US_roman -base 2114380800 -gmt 1
+} 2114467200
+test clock-19.291 {parse mmdd} {
+    clock scan {Jan  2} -format {%b %e} -locale en_US_roman -base 2114380800 -gmt 1
+} 2114467200
+test clock-19.292 {parse mmdd} {
+    clock scan {Jan ii} -format {%b %Oe} -locale en_US_roman -base 2114380800 -gmt 1
+} 2114467200
+test clock-19.293 {parse mmdd} {
+    clock scan {January 02} -format {%B %d} -locale en_US_roman -base 2114380800 -gmt 1
+} 2114467200
+test clock-19.294 {parse mmdd} {
+    clock scan {January ii} -format {%B %Od} -locale en_US_roman -base 2114380800 -gmt 1
+} 2114467200
+test clock-19.295 {parse mmdd} {
+    clock scan {January  2} -format {%B %e} -locale en_US_roman -base 2114380800 -gmt 1
+} 2114467200
+test clock-19.296 {parse mmdd} {
+    clock scan {January ii} -format {%B %Oe} -locale en_US_roman -base 2114380800 -gmt 1
+} 2114467200
+test clock-19.297 {parse mmdd} {
+    clock scan {Jan 02} -format {%h %d} -locale en_US_roman -base 2114380800 -gmt 1
+} 2114467200
+test clock-19.298 {parse mmdd} {
+    clock scan {Jan ii} -format {%h %Od} -locale en_US_roman -base 2114380800 -gmt 1
+} 2114467200
+test clock-19.299 {parse mmdd} {
+    clock scan {Jan  2} -format {%h %e} -locale en_US_roman -base 2114380800 -gmt 1
+} 2114467200
+test clock-19.300 {parse mmdd} {
+    clock scan {Jan ii} -format {%h %Oe} -locale en_US_roman -base 2114380800 -gmt 1
+} 2114467200
+test clock-19.301 {parse mmdd} {
+    clock scan {01 02} -format {%m %d} -locale en_US_roman -base 2114380800 -gmt 1
+} 2114467200
+test clock-19.302 {parse mmdd} {
+    clock scan {01 ii} -format {%m %Od} -locale en_US_roman -base 2114380800 -gmt 1
+} 2114467200
+test clock-19.303 {parse mmdd} {
+    clock scan {01  2} -format {%m %e} -locale en_US_roman -base 2114380800 -gmt 1
+} 2114467200
+test clock-19.304 {parse mmdd} {
+    clock scan {01 ii} -format {%m %Oe} -locale en_US_roman -base 2114380800 -gmt 1
+} 2114467200
+test clock-19.305 {parse mmdd} {
+    clock scan {i 02} -format {%Om %d} -locale en_US_roman -base 2114380800 -gmt 1
+} 2114467200
+test clock-19.306 {parse mmdd} {
+    clock scan {i ii} -format {%Om %Od} -locale en_US_roman -base 2114380800 -gmt 1
+} 2114467200
+test clock-19.307 {parse mmdd} {
+    clock scan {i  2} -format {%Om %e} -locale en_US_roman -base 2114380800 -gmt 1
+} 2114467200
+test clock-19.308 {parse mmdd} {
+    clock scan {i ii} -format {%Om %Oe} -locale en_US_roman -base 2114380800 -gmt 1
+} 2114467200
+test clock-19.309 {parse mmdd} {
+    clock scan { 1 02} -format {%N %d} -locale en_US_roman -base 2114380800 -gmt 1
+} 2114467200
+test clock-19.310 {parse mmdd} {
+    clock scan { 1 ii} -format {%N %Od} -locale en_US_roman -base 2114380800 -gmt 1
+} 2114467200
+test clock-19.311 {parse mmdd} {
+    clock scan { 1  2} -format {%N %e} -locale en_US_roman -base 2114380800 -gmt 1
+} 2114467200
+test clock-19.312 {parse mmdd} {
+    clock scan { 1 ii} -format {%N %Oe} -locale en_US_roman -base 2114380800 -gmt 1
+} 2114467200
+test clock-19.313 {parse mmdd} {
+    clock scan {Jan 31} -format {%b %d} -locale en_US_roman -base 2114380800 -gmt 1
+} 2116972800
+test clock-19.314 {parse mmdd} {
+    clock scan {Jan xxxi} -format {%b %Od} -locale en_US_roman -base 2114380800 -gmt 1
+} 2116972800
+test clock-19.315 {parse mmdd} {
+    clock scan {Jan 31} -format {%b %e} -locale en_US_roman -base 2114380800 -gmt 1
+} 2116972800
+test clock-19.316 {parse mmdd} {
+    clock scan {Jan xxxi} -format {%b %Oe} -locale en_US_roman -base 2114380800 -gmt 1
+} 2116972800
+test clock-19.317 {parse mmdd} {
+    clock scan {January 31} -format {%B %d} -locale en_US_roman -base 2114380800 -gmt 1
+} 2116972800
+test clock-19.318 {parse mmdd} {
+    clock scan {January xxxi} -format {%B %Od} -locale en_US_roman -base 2114380800 -gmt 1
+} 2116972800
+test clock-19.319 {parse mmdd} {
+    clock scan {January 31} -format {%B %e} -locale en_US_roman -base 2114380800 -gmt 1
+} 2116972800
+test clock-19.320 {parse mmdd} {
+    clock scan {January xxxi} -format {%B %Oe} -locale en_US_roman -base 2114380800 -gmt 1
+} 2116972800
+test clock-19.321 {parse mmdd} {
+    clock scan {Jan 31} -format {%h %d} -locale en_US_roman -base 2114380800 -gmt 1
+} 2116972800
+test clock-19.322 {parse mmdd} {
+    clock scan {Jan xxxi} -format {%h %Od} -locale en_US_roman -base 2114380800 -gmt 1
+} 2116972800
+test clock-19.323 {parse mmdd} {
+    clock scan {Jan 31} -format {%h %e} -locale en_US_roman -base 2114380800 -gmt 1
+} 2116972800
+test clock-19.324 {parse mmdd} {
+    clock scan {Jan xxxi} -format {%h %Oe} -locale en_US_roman -base 2114380800 -gmt 1
+} 2116972800
+test clock-19.325 {parse mmdd} {
+    clock scan {01 31} -format {%m %d} -locale en_US_roman -base 2114380800 -gmt 1
+} 2116972800
+test clock-19.326 {parse mmdd} {
+    clock scan {01 xxxi} -format {%m %Od} -locale en_US_roman -base 2114380800 -gmt 1
+} 2116972800
+test clock-19.327 {parse mmdd} {
+    clock scan {01 31} -format {%m %e} -locale en_US_roman -base 2114380800 -gmt 1
+} 2116972800
+test clock-19.328 {parse mmdd} {
+    clock scan {01 xxxi} -format {%m %Oe} -locale en_US_roman -base 2114380800 -gmt 1
+} 2116972800
+test clock-19.329 {parse mmdd} {
+    clock scan {i 31} -format {%Om %d} -locale en_US_roman -base 2114380800 -gmt 1
+} 2116972800
+test clock-19.330 {parse mmdd} {
+    clock scan {i xxxi} -format {%Om %Od} -locale en_US_roman -base 2114380800 -gmt 1
+} 2116972800
+test clock-19.331 {parse mmdd} {
+    clock scan {i 31} -format {%Om %e} -locale en_US_roman -base 2114380800 -gmt 1
+} 2116972800
+test clock-19.332 {parse mmdd} {
+    clock scan {i xxxi} -format {%Om %Oe} -locale en_US_roman -base 2114380800 -gmt 1
+} 2116972800
+test clock-19.333 {parse mmdd} {
+    clock scan { 1 31} -format {%N %d} -locale en_US_roman -base 2114380800 -gmt 1
+} 2116972800
+test clock-19.334 {parse mmdd} {
+    clock scan { 1 xxxi} -format {%N %Od} -locale en_US_roman -base 2114380800 -gmt 1
+} 2116972800
+test clock-19.335 {parse mmdd} {
+    clock scan { 1 31} -format {%N %e} -locale en_US_roman -base 2114380800 -gmt 1
+} 2116972800
+test clock-19.336 {parse mmdd} {
+    clock scan { 1 xxxi} -format {%N %Oe} -locale en_US_roman -base 2114380800 -gmt 1
+} 2116972800
+test clock-19.337 {parse mmdd} {
+    clock scan {Dec 02} -format {%b %d} -locale en_US_roman -base 2114380800 -gmt 1
+} 2143324800
+test clock-19.338 {parse mmdd} {
+    clock scan {Dec ii} -format {%b %Od} -locale en_US_roman -base 2114380800 -gmt 1
+} 2143324800
+test clock-19.339 {parse mmdd} {
+    clock scan {Dec  2} -format {%b %e} -locale en_US_roman -base 2114380800 -gmt 1
+} 2143324800
+test clock-19.340 {parse mmdd} {
+    clock scan {Dec ii} -format {%b %Oe} -locale en_US_roman -base 2114380800 -gmt 1
+} 2143324800
+test clock-19.341 {parse mmdd} {
+    clock scan {December 02} -format {%B %d} -locale en_US_roman -base 2114380800 -gmt 1
+} 2143324800
+test clock-19.342 {parse mmdd} {
+    clock scan {December ii} -format {%B %Od} -locale en_US_roman -base 2114380800 -gmt 1
+} 2143324800
+test clock-19.343 {parse mmdd} {
+    clock scan {December  2} -format {%B %e} -locale en_US_roman -base 2114380800 -gmt 1
+} 2143324800
+test clock-19.344 {parse mmdd} {
+    clock scan {December ii} -format {%B %Oe} -locale en_US_roman -base 2114380800 -gmt 1
+} 2143324800
+test clock-19.345 {parse mmdd} {
+    clock scan {Dec 02} -format {%h %d} -locale en_US_roman -base 2114380800 -gmt 1
+} 2143324800
+test clock-19.346 {parse mmdd} {
+    clock scan {Dec ii} -format {%h %Od} -locale en_US_roman -base 2114380800 -gmt 1
+} 2143324800
+test clock-19.347 {parse mmdd} {
+    clock scan {Dec  2} -format {%h %e} -locale en_US_roman -base 2114380800 -gmt 1
+} 2143324800
+test clock-19.348 {parse mmdd} {
+    clock scan {Dec ii} -format {%h %Oe} -locale en_US_roman -base 2114380800 -gmt 1
+} 2143324800
+test clock-19.349 {parse mmdd} {
+    clock scan {12 02} -format {%m %d} -locale en_US_roman -base 2114380800 -gmt 1
+} 2143324800
+test clock-19.350 {parse mmdd} {
+    clock scan {12 ii} -format {%m %Od} -locale en_US_roman -base 2114380800 -gmt 1
+} 2143324800
+test clock-19.351 {parse mmdd} {
+    clock scan {12  2} -format {%m %e} -locale en_US_roman -base 2114380800 -gmt 1
+} 2143324800
+test clock-19.352 {parse mmdd} {
+    clock scan {12 ii} -format {%m %Oe} -locale en_US_roman -base 2114380800 -gmt 1
+} 2143324800
+test clock-19.353 {parse mmdd} {
+    clock scan {xii 02} -format {%Om %d} -locale en_US_roman -base 2114380800 -gmt 1
+} 2143324800
+test clock-19.354 {parse mmdd} {
+    clock scan {xii ii} -format {%Om %Od} -locale en_US_roman -base 2114380800 -gmt 1
+} 2143324800
+test clock-19.355 {parse mmdd} {
+    clock scan {xii  2} -format {%Om %e} -locale en_US_roman -base 2114380800 -gmt 1
+} 2143324800
+test clock-19.356 {parse mmdd} {
+    clock scan {xii ii} -format {%Om %Oe} -locale en_US_roman -base 2114380800 -gmt 1
+} 2143324800
+test clock-19.357 {parse mmdd} {
+    clock scan {12 02} -format {%N %d} -locale en_US_roman -base 2114380800 -gmt 1
+} 2143324800
+test clock-19.358 {parse mmdd} {
+    clock scan {12 ii} -format {%N %Od} -locale en_US_roman -base 2114380800 -gmt 1
+} 2143324800
+test clock-19.359 {parse mmdd} {
+    clock scan {12  2} -format {%N %e} -locale en_US_roman -base 2114380800 -gmt 1
+} 2143324800
+test clock-19.360 {parse mmdd} {
+    clock scan {12 ii} -format {%N %Oe} -locale en_US_roman -base 2114380800 -gmt 1
+} 2143324800
+test clock-19.361 {parse mmdd} {
+    clock scan {Dec 31} -format {%b %d} -locale en_US_roman -base 2114380800 -gmt 1
+} 2145830400
+test clock-19.362 {parse mmdd} {
+    clock scan {Dec xxxi} -format {%b %Od} -locale en_US_roman -base 2114380800 -gmt 1
+} 2145830400
+test clock-19.363 {parse mmdd} {
+    clock scan {Dec 31} -format {%b %e} -locale en_US_roman -base 2114380800 -gmt 1
+} 2145830400
+test clock-19.364 {parse mmdd} {
+    clock scan {Dec xxxi} -format {%b %Oe} -locale en_US_roman -base 2114380800 -gmt 1
+} 2145830400
+test clock-19.365 {parse mmdd} {
+    clock scan {December 31} -format {%B %d} -locale en_US_roman -base 2114380800 -gmt 1
+} 2145830400
+test clock-19.366 {parse mmdd} {
+    clock scan {December xxxi} -format {%B %Od} -locale en_US_roman -base 2114380800 -gmt 1
+} 2145830400
+test clock-19.367 {parse mmdd} {
+    clock scan {December 31} -format {%B %e} -locale en_US_roman -base 2114380800 -gmt 1
+} 2145830400
+test clock-19.368 {parse mmdd} {
+    clock scan {December xxxi} -format {%B %Oe} -locale en_US_roman -base 2114380800 -gmt 1
+} 2145830400
+test clock-19.369 {parse mmdd} {
+    clock scan {Dec 31} -format {%h %d} -locale en_US_roman -base 2114380800 -gmt 1
+} 2145830400
+test clock-19.370 {parse mmdd} {
+    clock scan {Dec xxxi} -format {%h %Od} -locale en_US_roman -base 2114380800 -gmt 1
+} 2145830400
+test clock-19.371 {parse mmdd} {
+    clock scan {Dec 31} -format {%h %e} -locale en_US_roman -base 2114380800 -gmt 1
+} 2145830400
+test clock-19.372 {parse mmdd} {
+    clock scan {Dec xxxi} -format {%h %Oe} -locale en_US_roman -base 2114380800 -gmt 1
+} 2145830400
+test clock-19.373 {parse mmdd} {
+    clock scan {12 31} -format {%m %d} -locale en_US_roman -base 2114380800 -gmt 1
+} 2145830400
+test clock-19.374 {parse mmdd} {
+    clock scan {12 xxxi} -format {%m %Od} -locale en_US_roman -base 2114380800 -gmt 1
+} 2145830400
+test clock-19.375 {parse mmdd} {
+    clock scan {12 31} -format {%m %e} -locale en_US_roman -base 2114380800 -gmt 1
+} 2145830400
+test clock-19.376 {parse mmdd} {
+    clock scan {12 xxxi} -format {%m %Oe} -locale en_US_roman -base 2114380800 -gmt 1
+} 2145830400
+test clock-19.377 {parse mmdd} {
+    clock scan {xii 31} -format {%Om %d} -locale en_US_roman -base 2114380800 -gmt 1
+} 2145830400
+test clock-19.378 {parse mmdd} {
+    clock scan {xii xxxi} -format {%Om %Od} -locale en_US_roman -base 2114380800 -gmt 1
+} 2145830400
+test clock-19.379 {parse mmdd} {
+    clock scan {xii 31} -format {%Om %e} -locale en_US_roman -base 2114380800 -gmt 1
+} 2145830400
+test clock-19.380 {parse mmdd} {
+    clock scan {xii xxxi} -format {%Om %Oe} -locale en_US_roman -base 2114380800 -gmt 1
+} 2145830400
+test clock-19.381 {parse mmdd} {
+    clock scan {12 31} -format {%N %d} -locale en_US_roman -base 2114380800 -gmt 1
+} 2145830400
+test clock-19.382 {parse mmdd} {
+    clock scan {12 xxxi} -format {%N %Od} -locale en_US_roman -base 2114380800 -gmt 1
+} 2145830400
+test clock-19.383 {parse mmdd} {
+    clock scan {12 31} -format {%N %e} -locale en_US_roman -base 2114380800 -gmt 1
+} 2145830400
+test clock-19.384 {parse mmdd} {
+    clock scan {12 xxxi} -format {%N %Oe} -locale en_US_roman -base 2114380800 -gmt 1
+} 2145830400
+# END testcases19
+
+test clock-20.1 {seconds take precedence over mmdd} {
+    list [clock scan {0 0201} -format {%s %m%d} -gmt true -base 0] \
+	 [clock scan {0201 0} -format {%m%d %s} -gmt true -base 0]
+} {0 0}
+test clock-20.2 {julian day takes precedence over yyddd} {
+    list [clock scan {2440588 0201} -format {%J %m%d} -gmt true -base 0] \
+	 [clock scan {0201 2440588} -format {%m%d %J} -gmt true -base 0]
+} {0 0}
+test clock-20.3 {yyyyWwwd over mmdd} {
+    list [clock scan {1970W014 0201} -format {%GW%V%u %m%d} -gmt true -base 0] \
+	[clock scan {0201 1970W014} -format {%m%d %GW%V%u} -gmt true -base 0]
+} {0 0}
+test clock-20.4 {yyWwwd over mmdd} {
+    list [clock scan {70W014 0201} -format {%gW%V%u %m%d} -gmt true -base 0] \
+	[clock scan {0201 70W014} -format {%m%d %gW%V%u} -gmt true -base 0]
+} {0 0}
+
+# Test parsing of ddd
+
+test clock-21.1 {parse ddd} {
+    clock scan {001} -format {%j} -locale en_US_roman -gmt 1 -base 0
+} 0
+test clock-21.2 {parse ddd} {
+    clock scan {365} -format {%j} -locale en_US_roman -gmt 1 -base 0
+} 31449600
+test clock-21.3 {parse ddd} {
+    clock scan {001} -format {%j} -locale en_US_roman -gmt 1 -base 31536000
+} 31536000
+test clock-21.4 {parse ddd} {
+    clock scan {365} -format {%j} -locale en_US_roman -gmt 1 -base 31536000
+} 62985600
+test clock-21.5 {seconds take precedence over ddd} {
+    list [clock scan {0 002} -format {%s %j} -gmt true -base 0] \
+	 [clock scan {002 0} -format {%j %s} -gmt true -base 0]
+} {0 0}
+test clock-21.6 {julian day takes precedence over yyddd} {
+    list [clock scan {2440588 002} -format {%J %j} -gmt true -base 0] \
+	 [clock scan {002 2440588} -format {%j %J} -gmt true -base 0]
+} {0 0}
+test clock-21.7 {yyyyWwwd over ddd} {
+    list [clock scan {1970W014 002} -format {%GW%V%u %j} -gmt true -base 0] \
+	[clock scan {002 1970W014} -format {%j %GW%V%u} -gmt true -base 0]
+} {0 0}
+test clock-21.8 {yyWwwd over ddd} {
+    list [clock scan {70W014 002} -format {%gW%V%u %j} -gmt true -base 0] \
+	[clock scan {002 70W014} -format {%j %gW%V%u} -gmt true -base 0]
+} {0 0}
+
+# BEGIN testcases22
+
+# Test parsing of Wwwd
+
+test clock-22.1 {parse Wwwd} {
+    clock scan {W09 Sun} -format {W%V %a} -locale en_US_roman -gmt 1 -base 259200
+} 5097600
+test clock-22.2 {parse Wwwd} {
+    clock scan {W09 Sunday} -format {W%V %A} -locale en_US_roman -gmt 1 -base 259200
+} 5097600
+test clock-22.3 {parse Wwwd} {
+    clock scan {W09 7} -format {W%V %u} -locale en_US_roman -gmt 1 -base 259200
+} 5097600
+test clock-22.4 {parse Wwwd} {
+    clock scan {W09 0} -format {W%V %w} -locale en_US_roman -gmt 1 -base 259200
+} 5097600
+test clock-22.5 {parse Wwwd} {
+    clock scan {W09 vii} -format {W%V %Ou} -locale en_US_roman -gmt 1 -base 259200
+} 5097600
+test clock-22.6 {parse Wwwd} {
+    clock scan {W09 ?} -format {W%V %Ow} -locale en_US_roman -gmt 1 -base 259200
+} 5097600
+test clock-22.7 {parse Wwwd} {
+    clock scan {W14 Tue} -format {W%V %a} -locale en_US_roman -gmt 1 -base 259200
+} 7689600
+test clock-22.8 {parse Wwwd} {
+    clock scan {W14 Tuesday} -format {W%V %A} -locale en_US_roman -gmt 1 -base 259200
+} 7689600
+test clock-22.9 {parse Wwwd} {
+    clock scan {W14 2} -format {W%V %u} -locale en_US_roman -gmt 1 -base 259200
+} 7689600
+test clock-22.10 {parse Wwwd} {
+    clock scan {W14 2} -format {W%V %w} -locale en_US_roman -gmt 1 -base 259200
+} 7689600
+test clock-22.11 {parse Wwwd} {
+    clock scan {W14 ii} -format {W%V %Ou} -locale en_US_roman -gmt 1 -base 259200
+} 7689600
+test clock-22.12 {parse Wwwd} {
+    clock scan {W14 ii} -format {W%V %Ow} -locale en_US_roman -gmt 1 -base 259200
+} 7689600
+test clock-22.13 {parse Wwwd} {
+    clock scan {W40 Thu} -format {W%V %a} -locale en_US_roman -gmt 1 -base 259200
+} 23587200
+test clock-22.14 {parse Wwwd} {
+    clock scan {W40 Thursday} -format {W%V %A} -locale en_US_roman -gmt 1 -base 259200
+} 23587200
+test clock-22.15 {parse Wwwd} {
+    clock scan {W40 4} -format {W%V %u} -locale en_US_roman -gmt 1 -base 259200
+} 23587200
+test clock-22.16 {parse Wwwd} {
+    clock scan {W40 4} -format {W%V %w} -locale en_US_roman -gmt 1 -base 259200
+} 23587200
+test clock-22.17 {parse Wwwd} {
+    clock scan {W40 iv} -format {W%V %Ou} -locale en_US_roman -gmt 1 -base 259200
+} 23587200
+test clock-22.18 {parse Wwwd} {
+    clock scan {W40 iv} -format {W%V %Ow} -locale en_US_roman -gmt 1 -base 259200
+} 23587200
+test clock-22.19 {parse Wwwd} {
+    clock scan {W44 Sat} -format {W%V %a} -locale en_US_roman -gmt 1 -base 259200
+} 26179200
+test clock-22.20 {parse Wwwd} {
+    clock scan {W44 Saturday} -format {W%V %A} -locale en_US_roman -gmt 1 -base 259200
+} 26179200
+test clock-22.21 {parse Wwwd} {
+    clock scan {W44 6} -format {W%V %u} -locale en_US_roman -gmt 1 -base 259200
+} 26179200
+test clock-22.22 {parse Wwwd} {
+    clock scan {W44 6} -format {W%V %w} -locale en_US_roman -gmt 1 -base 259200
+} 26179200
+test clock-22.23 {parse Wwwd} {
+    clock scan {W44 vi} -format {W%V %Ou} -locale en_US_roman -gmt 1 -base 259200
+} 26179200
+test clock-22.24 {parse Wwwd} {
+    clock scan {W44 vi} -format {W%V %Ow} -locale en_US_roman -gmt 1 -base 259200
+} 26179200
+test clock-22.25 {parse Wwwd} {
+    clock scan {W09 Mon} -format {W%V %a} -locale en_US_roman -gmt 1 -base 31795200
+} 36633600
+test clock-22.26 {parse Wwwd} {
+    clock scan {W09 Monday} -format {W%V %A} -locale en_US_roman -gmt 1 -base 31795200
+} 36633600
+test clock-22.27 {parse Wwwd} {
+    clock scan {W09 1} -format {W%V %u} -locale en_US_roman -gmt 1 -base 31795200
+} 36633600
+test clock-22.28 {parse Wwwd} {
+    clock scan {W09 1} -format {W%V %w} -locale en_US_roman -gmt 1 -base 31795200
+} 36633600
+test clock-22.29 {parse Wwwd} {
+    clock scan {W09 i} -format {W%V %Ou} -locale en_US_roman -gmt 1 -base 31795200
+} 36633600
+test clock-22.30 {parse Wwwd} {
+    clock scan {W09 i} -format {W%V %Ow} -locale en_US_roman -gmt 1 -base 31795200
+} 36633600
+test clock-22.31 {parse Wwwd} {
+    clock scan {W13 Wed} -format {W%V %a} -locale en_US_roman -gmt 1 -base 31795200
+} 39225600
+test clock-22.32 {parse Wwwd} {
+    clock scan {W13 Wednesday} -format {W%V %A} -locale en_US_roman -gmt 1 -base 31795200
+} 39225600
+test clock-22.33 {parse Wwwd} {
+    clock scan {W13 3} -format {W%V %u} -locale en_US_roman -gmt 1 -base 31795200
+} 39225600
+test clock-22.34 {parse Wwwd} {
+    clock scan {W13 3} -format {W%V %w} -locale en_US_roman -gmt 1 -base 31795200
+} 39225600
+test clock-22.35 {parse Wwwd} {
+    clock scan {W13 iii} -format {W%V %Ou} -locale en_US_roman -gmt 1 -base 31795200
+} 39225600
+test clock-22.36 {parse Wwwd} {
+    clock scan {W13 iii} -format {W%V %Ow} -locale en_US_roman -gmt 1 -base 31795200
+} 39225600
+test clock-22.37 {parse Wwwd} {
+    clock scan {W39 Fri} -format {W%V %a} -locale en_US_roman -gmt 1 -base 31795200
+} 55123200
+test clock-22.38 {parse Wwwd} {
+    clock scan {W39 Friday} -format {W%V %A} -locale en_US_roman -gmt 1 -base 31795200
+} 55123200
+test clock-22.39 {parse Wwwd} {
+    clock scan {W39 5} -format {W%V %u} -locale en_US_roman -gmt 1 -base 31795200
+} 55123200
+test clock-22.40 {parse Wwwd} {
+    clock scan {W39 5} -format {W%V %w} -locale en_US_roman -gmt 1 -base 31795200
+} 55123200
+test clock-22.41 {parse Wwwd} {
+    clock scan {W39 v} -format {W%V %Ou} -locale en_US_roman -gmt 1 -base 31795200
+} 55123200
+test clock-22.42 {parse Wwwd} {
+    clock scan {W39 v} -format {W%V %Ow} -locale en_US_roman -gmt 1 -base 31795200
+} 55123200
+test clock-22.43 {parse Wwwd} {
+    clock scan {W43 Sun} -format {W%V %a} -locale en_US_roman -gmt 1 -base 31795200
+} 57715200
+test clock-22.44 {parse Wwwd} {
+    clock scan {W43 Sunday} -format {W%V %A} -locale en_US_roman -gmt 1 -base 31795200
+} 57715200
+test clock-22.45 {parse Wwwd} {
+    clock scan {W43 7} -format {W%V %u} -locale en_US_roman -gmt 1 -base 31795200
+} 57715200
+test clock-22.46 {parse Wwwd} {
+    clock scan {W43 0} -format {W%V %w} -locale en_US_roman -gmt 1 -base 31795200
+} 57715200
+test clock-22.47 {parse Wwwd} {
+    clock scan {W43 vii} -format {W%V %Ou} -locale en_US_roman -gmt 1 -base 31795200
+} 57715200
+test clock-22.48 {parse Wwwd} {
+    clock scan {W43 ?} -format {W%V %Ow} -locale en_US_roman -gmt 1 -base 31795200
+} 57715200
+test clock-22.49 {parse Wwwd} {
+    clock scan {W09 Wed} -format {W%V %a} -locale en_US_roman -gmt 1 -base 946944000
+} 951868800
+test clock-22.50 {parse Wwwd} {
+    clock scan {W09 Wednesday} -format {W%V %A} -locale en_US_roman -gmt 1 -base 946944000
+} 951868800
+test clock-22.51 {parse Wwwd} {
+    clock scan {W09 3} -format {W%V %u} -locale en_US_roman -gmt 1 -base 946944000
+} 951868800
+test clock-22.52 {parse Wwwd} {
+    clock scan {W09 3} -format {W%V %w} -locale en_US_roman -gmt 1 -base 946944000
+} 951868800
+test clock-22.53 {parse Wwwd} {
+    clock scan {W09 iii} -format {W%V %Ou} -locale en_US_roman -gmt 1 -base 946944000
+} 951868800
+test clock-22.54 {parse Wwwd} {
+    clock scan {W09 iii} -format {W%V %Ow} -locale en_US_roman -gmt 1 -base 946944000
+} 951868800
+test clock-22.55 {parse Wwwd} {
+    clock scan {W13 Fri} -format {W%V %a} -locale en_US_roman -gmt 1 -base 946944000
+} 954460800
+test clock-22.56 {parse Wwwd} {
+    clock scan {W13 Friday} -format {W%V %A} -locale en_US_roman -gmt 1 -base 946944000
+} 954460800
+test clock-22.57 {parse Wwwd} {
+    clock scan {W13 5} -format {W%V %u} -locale en_US_roman -gmt 1 -base 946944000
+} 954460800
+test clock-22.58 {parse Wwwd} {
+    clock scan {W13 5} -format {W%V %w} -locale en_US_roman -gmt 1 -base 946944000
+} 954460800
+test clock-22.59 {parse Wwwd} {
+    clock scan {W13 v} -format {W%V %Ou} -locale en_US_roman -gmt 1 -base 946944000
+} 954460800
+test clock-22.60 {parse Wwwd} {
+    clock scan {W13 v} -format {W%V %Ow} -locale en_US_roman -gmt 1 -base 946944000
+} 954460800
+test clock-22.61 {parse Wwwd} {
+    clock scan {W39 Sun} -format {W%V %a} -locale en_US_roman -gmt 1 -base 946944000
+} 970358400
+test clock-22.62 {parse Wwwd} {
+    clock scan {W39 Sunday} -format {W%V %A} -locale en_US_roman -gmt 1 -base 946944000
+} 970358400
+test clock-22.63 {parse Wwwd} {
+    clock scan {W39 7} -format {W%V %u} -locale en_US_roman -gmt 1 -base 946944000
+} 970358400
+test clock-22.64 {parse Wwwd} {
+    clock scan {W39 0} -format {W%V %w} -locale en_US_roman -gmt 1 -base 946944000
+} 970358400
+test clock-22.65 {parse Wwwd} {
+    clock scan {W39 vii} -format {W%V %Ou} -locale en_US_roman -gmt 1 -base 946944000
+} 970358400
+test clock-22.66 {parse Wwwd} {
+    clock scan {W39 ?} -format {W%V %Ow} -locale en_US_roman -gmt 1 -base 946944000
+} 970358400
+test clock-22.67 {parse Wwwd} {
+    clock scan {W44 Tue} -format {W%V %a} -locale en_US_roman -gmt 1 -base 946944000
+} 972950400
+test clock-22.68 {parse Wwwd} {
+    clock scan {W44 Tuesday} -format {W%V %A} -locale en_US_roman -gmt 1 -base 946944000
+} 972950400
+test clock-22.69 {parse Wwwd} {
+    clock scan {W44 2} -format {W%V %u} -locale en_US_roman -gmt 1 -base 946944000
+} 972950400
+test clock-22.70 {parse Wwwd} {
+    clock scan {W44 2} -format {W%V %w} -locale en_US_roman -gmt 1 -base 946944000
+} 972950400
+test clock-22.71 {parse Wwwd} {
+    clock scan {W44 ii} -format {W%V %Ou} -locale en_US_roman -gmt 1 -base 946944000
+} 972950400
+test clock-22.72 {parse Wwwd} {
+    clock scan {W44 ii} -format {W%V %Ow} -locale en_US_roman -gmt 1 -base 946944000
+} 972950400
+test clock-22.73 {parse Wwwd} {
+    clock scan {W09 Thu} -format {W%V %a} -locale en_US_roman -gmt 1 -base 978566400
+} 983404800
+test clock-22.74 {parse Wwwd} {
+    clock scan {W09 Thursday} -format {W%V %A} -locale en_US_roman -gmt 1 -base 978566400
+} 983404800
+test clock-22.75 {parse Wwwd} {
+    clock scan {W09 4} -format {W%V %u} -locale en_US_roman -gmt 1 -base 978566400
+} 983404800
+test clock-22.76 {parse Wwwd} {
+    clock scan {W09 4} -format {W%V %w} -locale en_US_roman -gmt 1 -base 978566400
+} 983404800
+test clock-22.77 {parse Wwwd} {
+    clock scan {W09 iv} -format {W%V %Ou} -locale en_US_roman -gmt 1 -base 978566400
+} 983404800
+test clock-22.78 {parse Wwwd} {
+    clock scan {W09 iv} -format {W%V %Ow} -locale en_US_roman -gmt 1 -base 978566400
+} 983404800
+test clock-22.79 {parse Wwwd} {
+    clock scan {W13 Sat} -format {W%V %a} -locale en_US_roman -gmt 1 -base 978566400
+} 985996800
+test clock-22.80 {parse Wwwd} {
+    clock scan {W13 Saturday} -format {W%V %A} -locale en_US_roman -gmt 1 -base 978566400
+} 985996800
+test clock-22.81 {parse Wwwd} {
+    clock scan {W13 6} -format {W%V %u} -locale en_US_roman -gmt 1 -base 978566400
+} 985996800
+test clock-22.82 {parse Wwwd} {
+    clock scan {W13 6} -format {W%V %w} -locale en_US_roman -gmt 1 -base 978566400
+} 985996800
+test clock-22.83 {parse Wwwd} {
+    clock scan {W13 vi} -format {W%V %Ou} -locale en_US_roman -gmt 1 -base 978566400
+} 985996800
+test clock-22.84 {parse Wwwd} {
+    clock scan {W13 vi} -format {W%V %Ow} -locale en_US_roman -gmt 1 -base 978566400
+} 985996800
+test clock-22.85 {parse Wwwd} {
+    clock scan {W40 Mon} -format {W%V %a} -locale en_US_roman -gmt 1 -base 978566400
+} 1001894400
+test clock-22.86 {parse Wwwd} {
+    clock scan {W40 Monday} -format {W%V %A} -locale en_US_roman -gmt 1 -base 978566400
+} 1001894400
+test clock-22.87 {parse Wwwd} {
+    clock scan {W40 1} -format {W%V %u} -locale en_US_roman -gmt 1 -base 978566400
+} 1001894400
+test clock-22.88 {parse Wwwd} {
+    clock scan {W40 1} -format {W%V %w} -locale en_US_roman -gmt 1 -base 978566400
+} 1001894400
+test clock-22.89 {parse Wwwd} {
+    clock scan {W40 i} -format {W%V %Ou} -locale en_US_roman -gmt 1 -base 978566400
+} 1001894400
+test clock-22.90 {parse Wwwd} {
+    clock scan {W40 i} -format {W%V %Ow} -locale en_US_roman -gmt 1 -base 978566400
+} 1001894400
+test clock-22.91 {parse Wwwd} {
+    clock scan {W44 Wed} -format {W%V %a} -locale en_US_roman -gmt 1 -base 978566400
+} 1004486400
+test clock-22.92 {parse Wwwd} {
+    clock scan {W44 Wednesday} -format {W%V %A} -locale en_US_roman -gmt 1 -base 978566400
+} 1004486400
+test clock-22.93 {parse Wwwd} {
+    clock scan {W44 3} -format {W%V %u} -locale en_US_roman -gmt 1 -base 978566400
+} 1004486400
+test clock-22.94 {parse Wwwd} {
+    clock scan {W44 3} -format {W%V %w} -locale en_US_roman -gmt 1 -base 978566400
+} 1004486400
+test clock-22.95 {parse Wwwd} {
+    clock scan {W44 iii} -format {W%V %Ou} -locale en_US_roman -gmt 1 -base 978566400
+} 1004486400
+test clock-22.96 {parse Wwwd} {
+    clock scan {W44 iii} -format {W%V %Ow} -locale en_US_roman -gmt 1 -base 978566400
+} 1004486400
+# END testcases22
+
+# Test precedence of Wwwd
+test clock-23.1 {seconds take precedence over Wwwd} {
+    list [clock scan {0 W024} -format {%s W%V%u} -gmt true -base 0] \
+	 [clock scan {W024 0} -format {W%V%u %s} -gmt true -base 0]
+} {0 0}
+test clock-23.2 {julian day takes precedence over Wwwd} {
+    list [clock scan {2440588 W024} -format {%J W%V%u} -gmt true -base 0] \
+	 [clock scan {W024 2440588} -format {W%V%u %J} -gmt true -base 0]
+} {0 0}
+test clock-23.3 {Wwwd precedence below yyyymmdd} {
+    list [clock scan {19700101 W014} -format {%Y%m%d W%V%u} -gmt true -base 0] \
+	[clock scan {W014 19700101} -format {W%V%u %Y%m%d} -gmt true -base 0]
+} {0 0}
+test clock-23.4 {Wwwd precedence below yyyyddd} {
+    list [clock scan {1970001 W014} -format {%Y%j W%V%u} -gmt true -base 0] \
+	[clock scan {W014 1970001} -format {W%V%u %Y%j} -gmt true -base 0]
+} {0 0}
+test clock-23.5 {Wwwd precedence below yymmdd} {
+    list [clock scan {700101 W014} -format {%y%m%d W%V%u} -gmt true -base 0] \
+	[clock scan {W014 700101} -format {W%V%u %y%m%d} -gmt true -base 0]
+} {0 0}
+test clock-23.6 {Wwwd precedence below yyddd} {
+    list [clock scan {70001 W014} -format {%y%j W%V%u} -gmt true -base 0] \
+	[clock scan {W014 70001} -format {W%V%u %y%j} -gmt true -base 0]
+} {0 0}
+
+# BEGIN testcases24
+
+# Test parsing of naked day-of-month
+
+test clock-24.1 {parse naked day of month} {
+    clock scan 02 -format %d -locale en_US_roman -base 0 -gmt 1
+} 86400
+test clock-24.2 {parse naked day of month} {
+    clock scan ii -format %Od -locale en_US_roman -base 0 -gmt 1
+} 86400
+test clock-24.3 {parse naked day of month} {
+    clock scan { 2} -format %e -locale en_US_roman -base 0 -gmt 1
+} 86400
+test clock-24.4 {parse naked day of month} {
+    clock scan ii -format %Oe -locale en_US_roman -base 0 -gmt 1
+} 86400
+test clock-24.5 {parse naked day of month} {
+    clock scan 28 -format %d -locale en_US_roman -base 0 -gmt 1
+} 2332800
+test clock-24.6 {parse naked day of month} {
+    clock scan xxviii -format %Od -locale en_US_roman -base 0 -gmt 1
+} 2332800
+test clock-24.7 {parse naked day of month} {
+    clock scan 28 -format %e -locale en_US_roman -base 0 -gmt 1
+} 2332800
+test clock-24.8 {parse naked day of month} {
+    clock scan xxviii -format %Oe -locale en_US_roman -base 0 -gmt 1
+} 2332800
+test clock-24.9 {parse naked day of month} {
+    clock scan 02 -format %d -locale en_US_roman -base 28857600 -gmt 1
+} 28944000
+test clock-24.10 {parse naked day of month} {
+    clock scan ii -format %Od -locale en_US_roman -base 28857600 -gmt 1
+} 28944000
+test clock-24.11 {parse naked day of month} {
+    clock scan { 2} -format %e -locale en_US_roman -base 28857600 -gmt 1
+} 28944000
+test clock-24.12 {parse naked day of month} {
+    clock scan ii -format %Oe -locale en_US_roman -base 28857600 -gmt 1
+} 28944000
+test clock-24.13 {parse naked day of month} {
+    clock scan 28 -format %d -locale en_US_roman -base 28857600 -gmt 1
+} 31190400
+test clock-24.14 {parse naked day of month} {
+    clock scan xxviii -format %Od -locale en_US_roman -base 28857600 -gmt 1
+} 31190400
+test clock-24.15 {parse naked day of month} {
+    clock scan 28 -format %e -locale en_US_roman -base 28857600 -gmt 1
+} 31190400
+test clock-24.16 {parse naked day of month} {
+    clock scan xxviii -format %Oe -locale en_US_roman -base 28857600 -gmt 1
+} 31190400
+test clock-24.17 {parse naked day of month} {
+    clock scan 02 -format %d -locale en_US_roman -base 946684800 -gmt 1
+} 946771200
+test clock-24.18 {parse naked day of month} {
+    clock scan ii -format %Od -locale en_US_roman -base 946684800 -gmt 1
+} 946771200
+test clock-24.19 {parse naked day of month} {
+    clock scan { 2} -format %e -locale en_US_roman -base 946684800 -gmt 1
+} 946771200
+test clock-24.20 {parse naked day of month} {
+    clock scan ii -format %Oe -locale en_US_roman -base 946684800 -gmt 1
+} 946771200
+test clock-24.21 {parse naked day of month} {
+    clock scan 28 -format %d -locale en_US_roman -base 946684800 -gmt 1
+} 949017600
+test clock-24.22 {parse naked day of month} {
+    clock scan xxviii -format %Od -locale en_US_roman -base 946684800 -gmt 1
+} 949017600
+test clock-24.23 {parse naked day of month} {
+    clock scan 28 -format %e -locale en_US_roman -base 946684800 -gmt 1
+} 949017600
+test clock-24.24 {parse naked day of month} {
+    clock scan xxviii -format %Oe -locale en_US_roman -base 946684800 -gmt 1
+} 949017600
+test clock-24.25 {parse naked day of month} {
+    clock scan 02 -format %d -locale en_US_roman -base 975628800 -gmt 1
+} 975715200
+test clock-24.26 {parse naked day of month} {
+    clock scan ii -format %Od -locale en_US_roman -base 975628800 -gmt 1
+} 975715200
+test clock-24.27 {parse naked day of month} {
+    clock scan { 2} -format %e -locale en_US_roman -base 975628800 -gmt 1
+} 975715200
+test clock-24.28 {parse naked day of month} {
+    clock scan ii -format %Oe -locale en_US_roman -base 975628800 -gmt 1
+} 975715200
+test clock-24.29 {parse naked day of month} {
+    clock scan 28 -format %d -locale en_US_roman -base 975628800 -gmt 1
+} 977961600
+test clock-24.30 {parse naked day of month} {
+    clock scan xxviii -format %Od -locale en_US_roman -base 975628800 -gmt 1
+} 977961600
+test clock-24.31 {parse naked day of month} {
+    clock scan 28 -format %e -locale en_US_roman -base 975628800 -gmt 1
+} 977961600
+test clock-24.32 {parse naked day of month} {
+    clock scan xxviii -format %Oe -locale en_US_roman -base 975628800 -gmt 1
+} 977961600
+# END testcases24
+
+test clock-25.1 {seconds take precedence over dd} {
+    list [clock scan {0 02} -format {%s %d} -gmt true -base 0] \
+	 [clock scan {02 0} -format {%d %s} -gmt true -base 0]
+} {0 0}
+test clock-25.2 {julian day takes precedence over dd} {
+    list [clock scan {2440588 02} -format {%J %d} -gmt true -base 0] \
+	 [clock scan {02 2440588} -format {%d %J} -gmt true -base 0]
+} {0 0}
+test clock-25.3 {yyyyddd over dd} {
+    list [clock scan {1970001 02} -format {%Y%j %d} -gmt true -base 0] \
+	[clock scan {02 1970001} -format {%d %Y%j} -gmt true -base 0]
+} {0 0}
+test clock-25.4 {yyyyWwwd over dd} {
+    list [clock scan {1970W014 02} -format {%GW%V%u %d} -gmt true -base 0] \
+	[clock scan {02 1970W014} -format {%d %GW%V%u} -gmt true -base 0]
+} {0 0}
+test clock-25.5 {yyWwwd over dd} {
+    list [clock scan {70W014 02} -format {%gW%V%u %d} -gmt true -base 0] \
+	[clock scan {02 70W014} -format {%d %gW%V%u} -gmt true -base 0]
+} {0 0}
+test clock-25.6 {yyddd over dd} {
+    list [clock scan {70001 02} -format {%y%j %d} -gmt true -base 0] \
+	[clock scan {02 70001} -format {%d %y%j} -gmt true -base 0]
+} {0 0}
+test clock-25.7 {ddd over dd} {
+    list [clock scan {001 02} -format {%j %d} -gmt true -base 0] \
+	[clock scan {02 001} -format {%d %j} -gmt true -base 0]
+} {0 0}
+
+# BEGIN testcases26
+
+# Test parsing of naked day of week
+
+test clock-26.1 {parse naked day of week} {
+    clock scan Mon -format %a -locale en_US_roman -gmt 1 -base 0
+} -259200
+test clock-26.2 {parse naked day of week} {
+    clock scan Monday -format %A -locale en_US_roman -gmt 1 -base 0
+} -259200
+test clock-26.3 {parse naked day of week} {
+    clock scan 1 -format %u -locale en_US_roman -gmt 1 -base 0
+} -259200
+test clock-26.4 {parse naked day of week} {
+    clock scan 1 -format %w -locale en_US_roman -gmt 1 -base 0
+} -259200
+test clock-26.5 {parse naked day of week} {
+    clock scan i -format %Ou -locale en_US_roman -gmt 1 -base 0
+} -259200
+test clock-26.6 {parse naked day of week} {
+    clock scan i -format %Ow -locale en_US_roman -gmt 1 -base 0
+} -259200
+test clock-26.7 {parse naked day of week} {
+    clock scan Sun -format %a -locale en_US_roman -gmt 1 -base 0
+} 259200
+test clock-26.8 {parse naked day of week} {
+    clock scan Sunday -format %A -locale en_US_roman -gmt 1 -base 0
+} 259200
+test clock-26.9 {parse naked day of week} {
+    clock scan 7 -format %u -locale en_US_roman -gmt 1 -base 0
+} 259200
+test clock-26.10 {parse naked day of week} {
+    clock scan 0 -format %w -locale en_US_roman -gmt 1 -base 0
+} 259200
+test clock-26.11 {parse naked day of week} {
+    clock scan vii -format %Ou -locale en_US_roman -gmt 1 -base 0
+} 259200
+test clock-26.12 {parse naked day of week} {
+    clock scan ? -format %Ow -locale en_US_roman -gmt 1 -base 0
+} 259200
+test clock-26.13 {parse naked day of week} {
+    clock scan Mon -format %a -locale en_US_roman -gmt 1 -base 30844800
+} 30585600
+test clock-26.14 {parse naked day of week} {
+    clock scan Monday -format %A -locale en_US_roman -gmt 1 -base 30844800
+} 30585600
+test clock-26.15 {parse naked day of week} {
+    clock scan 1 -format %u -locale en_US_roman -gmt 1 -base 30844800
+} 30585600
+test clock-26.16 {parse naked day of week} {
+    clock scan 1 -format %w -locale en_US_roman -gmt 1 -base 30844800
+} 30585600
+test clock-26.17 {parse naked day of week} {
+    clock scan i -format %Ou -locale en_US_roman -gmt 1 -base 30844800
+} 30585600
+test clock-26.18 {parse naked day of week} {
+    clock scan i -format %Ow -locale en_US_roman -gmt 1 -base 30844800
+} 30585600
+test clock-26.19 {parse naked day of week} {
+    clock scan Sun -format %a -locale en_US_roman -gmt 1 -base 30844800
+} 31104000
+test clock-26.20 {parse naked day of week} {
+    clock scan Sunday -format %A -locale en_US_roman -gmt 1 -base 30844800
+} 31104000
+test clock-26.21 {parse naked day of week} {
+    clock scan 7 -format %u -locale en_US_roman -gmt 1 -base 30844800
+} 31104000
+test clock-26.22 {parse naked day of week} {
+    clock scan 0 -format %w -locale en_US_roman -gmt 1 -base 30844800
+} 31104000
+test clock-26.23 {parse naked day of week} {
+    clock scan vii -format %Ou -locale en_US_roman -gmt 1 -base 30844800
+} 31104000
+test clock-26.24 {parse naked day of week} {
+    clock scan ? -format %Ow -locale en_US_roman -gmt 1 -base 30844800
+} 31104000
+test clock-26.25 {parse naked day of week} {
+    clock scan Mon -format %a -locale en_US_roman -gmt 1 -base 978566400
+} 978307200
+test clock-26.26 {parse naked day of week} {
+    clock scan Monday -format %A -locale en_US_roman -gmt 1 -base 978566400
+} 978307200
+test clock-26.27 {parse naked day of week} {
+    clock scan 1 -format %u -locale en_US_roman -gmt 1 -base 978566400
+} 978307200
+test clock-26.28 {parse naked day of week} {
+    clock scan 1 -format %w -locale en_US_roman -gmt 1 -base 978566400
+} 978307200
+test clock-26.29 {parse naked day of week} {
+    clock scan i -format %Ou -locale en_US_roman -gmt 1 -base 978566400
+} 978307200
+test clock-26.30 {parse naked day of week} {
+    clock scan i -format %Ow -locale en_US_roman -gmt 1 -base 978566400
+} 978307200
+test clock-26.31 {parse naked day of week} {
+    clock scan Sun -format %a -locale en_US_roman -gmt 1 -base 978566400
+} 978825600
+test clock-26.32 {parse naked day of week} {
+    clock scan Sunday -format %A -locale en_US_roman -gmt 1 -base 978566400
+} 978825600
+test clock-26.33 {parse naked day of week} {
+    clock scan 7 -format %u -locale en_US_roman -gmt 1 -base 978566400
+} 978825600
+test clock-26.34 {parse naked day of week} {
+    clock scan 0 -format %w -locale en_US_roman -gmt 1 -base 978566400
+} 978825600
+test clock-26.35 {parse naked day of week} {
+    clock scan vii -format %Ou -locale en_US_roman -gmt 1 -base 978566400
+} 978825600
+test clock-26.36 {parse naked day of week} {
+    clock scan ? -format %Ow -locale en_US_roman -gmt 1 -base 978566400
+} 978825600
+test clock-26.37 {parse naked day of week} {
+    clock scan Mon -format %a -locale en_US_roman -gmt 1 -base 1009411200
+} 1009152000
+test clock-26.38 {parse naked day of week} {
+    clock scan Monday -format %A -locale en_US_roman -gmt 1 -base 1009411200
+} 1009152000
+test clock-26.39 {parse naked day of week} {
+    clock scan 1 -format %u -locale en_US_roman -gmt 1 -base 1009411200
+} 1009152000
+test clock-26.40 {parse naked day of week} {
+    clock scan 1 -format %w -locale en_US_roman -gmt 1 -base 1009411200
+} 1009152000
+test clock-26.41 {parse naked day of week} {
+    clock scan i -format %Ou -locale en_US_roman -gmt 1 -base 1009411200
+} 1009152000
+test clock-26.42 {parse naked day of week} {
+    clock scan i -format %Ow -locale en_US_roman -gmt 1 -base 1009411200
+} 1009152000
+test clock-26.43 {parse naked day of week} {
+    clock scan Sun -format %a -locale en_US_roman -gmt 1 -base 1009411200
+} 1009670400
+test clock-26.44 {parse naked day of week} {
+    clock scan Sunday -format %A -locale en_US_roman -gmt 1 -base 1009411200
+} 1009670400
+test clock-26.45 {parse naked day of week} {
+    clock scan 7 -format %u -locale en_US_roman -gmt 1 -base 1009411200
+} 1009670400
+test clock-26.46 {parse naked day of week} {
+    clock scan 0 -format %w -locale en_US_roman -gmt 1 -base 1009411200
+} 1009670400
+test clock-26.47 {parse naked day of week} {
+    clock scan vii -format %Ou -locale en_US_roman -gmt 1 -base 1009411200
+} 1009670400
+test clock-26.48 {parse naked day of week} {
+    clock scan ? -format %Ow -locale en_US_roman -gmt 1 -base 1009411200
+} 1009670400
+# END testcases26
+
+test clock-27.1 {seconds take precedence over naked weekday} {
+    list [clock scan {0 1} -format {%s %u} -gmt true -base 0] \
+	 [clock scan {1 0} -format {%u %s} -gmt true -base 0]
+} {0 0}
+test clock-27.2 {julian day takes precedence over naked weekday} {
+    list [clock scan {2440588 1} -format {%J %u} -gmt true -base 0] \
+	 [clock scan {1 2440588} -format {%u %J} -gmt true -base 0]
+} {0 0}
+test clock-27.3 {yyyymmdd over naked weekday} {
+    list [clock scan {19700101 1} -format {%Y%m%d %u} -gmt true -base 0] \
+	[clock scan {1 19700101} -format {%u %Y%m%d} -gmt true -base 0]
+} {0 0}
+test clock-27.4 {yyyyddd over naked weekday} {
+    list [clock scan {1970001 1} -format {%Y%j %u} -gmt true -base 0] \
+	[clock scan {1 1970001} -format {%u %Y%j} -gmt true -base 0]
+} {0 0}
+test clock-27.5 {yymmdd over naked weekday} {
+    list [clock scan {700101 1} -format {%y%m%d %u} -gmt true -base 0] \
+	[clock scan {1 700101} -format {%u %y%m%d} -gmt true -base 0]
+} {0 0}
+test clock-27.6 {yyddd over naked weekday} {
+    list [clock scan {70001 1} -format {%y%j %u} -gmt true -base 0] \
+	[clock scan {1 70001} -format {%u %y%j} -gmt true -base 0]
+} {0 0}
+test clock-27.7 {mmdd over naked weekday} {
+    list [clock scan {0101 1} -format {%m%d %u} -gmt true -base 0] \
+	[clock scan {1 0101} -format {%u %m%d} -gmt true -base 0]
+} {0 0}
+test clock-27.8 {ddd over naked weekday} {
+    list [clock scan {001 1} -format {%j %u} -gmt true -base 0] \
+	[clock scan {1 001} -format {%u %j} -gmt true -base 0]
+} {0 0}
+test clock-27.9 {naked day of month over naked weekday} {
+    list [clock scan {01 1} -format {%d %u} -gmt true -base 0] \
+	[clock scan {1 01} -format {%u %d} -gmt true -base 0]
+} {0 0}
+
+test clock-28.1 {base date} {
+    clock scan {} -format {} -gmt true -base 1234567890
+} 1234483200
+
+# BEGIN testcases29
+
+# Test parsing of time of day
+
+test clock-29.1 {time parsing} {
+    clock scan {2440588 00 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H }
+} 0
+test clock-29.2 {time parsing} {
+    clock scan {2440588 00:00 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%M }
+} 0
+test clock-29.3 {time parsing} {
+    clock scan {2440588 00:? } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%OM }
+} 0
+test clock-29.4 {time parsing} {
+    clock scan {2440588 00:00:00 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%M:%S }
+} 0
+test clock-29.5 {time parsing} {
+    clock scan {2440588 00:?:? } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%OM:%OS }
+} 0
+test clock-29.6 {time parsing} {
+    clock scan {2440588  0 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k }
+} 0
+test clock-29.7 {time parsing} {
+    clock scan {2440588  0:00 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%M }
+} 0
+test clock-29.8 {time parsing} {
+    clock scan {2440588  0:? } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%OM }
+} 0
+test clock-29.9 {time parsing} {
+    clock scan {2440588  0:00:00 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%M:%S }
+} 0
+test clock-29.10 {time parsing} {
+    clock scan {2440588  0:?:? } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%OM:%OS }
+} 0
+test clock-29.11 {time parsing} {
+    clock scan {2440588 ? } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH }
+} 0
+test clock-29.12 {time parsing} {
+    clock scan {2440588 ?:00 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%M }
+} 0
+test clock-29.13 {time parsing} {
+    clock scan {2440588 ?:? } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%OM }
+} 0
+test clock-29.14 {time parsing} {
+    clock scan {2440588 ?:00:00 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%M:%S }
+} 0
+test clock-29.15 {time parsing} {
+    clock scan {2440588 ?:?:? } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%OM:%OS }
+} 0
+test clock-29.16 {time parsing} {
+    clock scan {2440588 ? } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok }
+} 0
+test clock-29.17 {time parsing} {
+    clock scan {2440588 ?:00 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%M }
+} 0
+test clock-29.18 {time parsing} {
+    clock scan {2440588 ?:? } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%OM }
+} 0
+test clock-29.19 {time parsing} {
+    clock scan {2440588 ?:00:00 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%M:%S }
+} 0
+test clock-29.20 {time parsing} {
+    clock scan {2440588 ?:?:? } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%OM:%OS }
+} 0
+test clock-29.21 {time parsing} {
+    clock scan {2440588 12 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I %p}
+} 0
+test clock-29.22 {time parsing} {
+    clock scan {2440588 12:00 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M %p}
+} 0
+test clock-29.23 {time parsing} {
+    clock scan {2440588 12:? AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM %p}
+} 0
+test clock-29.24 {time parsing} {
+    clock scan {2440588 12:00:00 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M:%S %p}
+} 0
+test clock-29.25 {time parsing} {
+    clock scan {2440588 12:?:? AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM:%OS %p}
+} 0
+test clock-29.26 {time parsing} {
+    clock scan {2440588 12 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l %p}
+} 0
+test clock-29.27 {time parsing} {
+    clock scan {2440588 12:00 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M %p}
+} 0
+test clock-29.28 {time parsing} {
+    clock scan {2440588 12:? AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM %p}
+} 0
+test clock-29.29 {time parsing} {
+    clock scan {2440588 12:00:00 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M:%S %p}
+} 0
+test clock-29.30 {time parsing} {
+    clock scan {2440588 12:?:? AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM:%OS %p}
+} 0
+test clock-29.31 {time parsing} {
+    clock scan {2440588 xii AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI %p}
+} 0
+test clock-29.32 {time parsing} {
+    clock scan {2440588 xii:00 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M %p}
+} 0
+test clock-29.33 {time parsing} {
+    clock scan {2440588 xii:? AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM %p}
+} 0
+test clock-29.34 {time parsing} {
+    clock scan {2440588 xii:00:00 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M:%S %p}
+} 0
+test clock-29.35 {time parsing} {
+    clock scan {2440588 xii:?:? AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM:%OS %p}
+} 0
+test clock-29.36 {time parsing} {
+    clock scan {2440588 xii AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol %p}
+} 0
+test clock-29.37 {time parsing} {
+    clock scan {2440588 xii:00 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M %p}
+} 0
+test clock-29.38 {time parsing} {
+    clock scan {2440588 xii:? AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM %p}
+} 0
+test clock-29.39 {time parsing} {
+    clock scan {2440588 xii:00:00 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M:%S %p}
+} 0
+test clock-29.40 {time parsing} {
+    clock scan {2440588 xii:?:? AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM:%OS %p}
+} 0
+test clock-29.41 {time parsing} {
+    clock scan {2440588 12 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I %P}
+} 0
+test clock-29.42 {time parsing} {
+    clock scan {2440588 12:00 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M %P}
+} 0
+test clock-29.43 {time parsing} {
+    clock scan {2440588 12:? am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM %P}
+} 0
+test clock-29.44 {time parsing} {
+    clock scan {2440588 12:00:00 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M:%S %P}
+} 0
+test clock-29.45 {time parsing} {
+    clock scan {2440588 12:?:? am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM:%OS %P}
+} 0
+test clock-29.46 {time parsing} {
+    clock scan {2440588 12 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l %P}
+} 0
+test clock-29.47 {time parsing} {
+    clock scan {2440588 12:00 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M %P}
+} 0
+test clock-29.48 {time parsing} {
+    clock scan {2440588 12:? am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM %P}
+} 0
+test clock-29.49 {time parsing} {
+    clock scan {2440588 12:00:00 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M:%S %P}
+} 0
+test clock-29.50 {time parsing} {
+    clock scan {2440588 12:?:? am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM:%OS %P}
+} 0
+test clock-29.51 {time parsing} {
+    clock scan {2440588 xii am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI %P}
+} 0
+test clock-29.52 {time parsing} {
+    clock scan {2440588 xii:00 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M %P}
+} 0
+test clock-29.53 {time parsing} {
+    clock scan {2440588 xii:? am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM %P}
+} 0
+test clock-29.54 {time parsing} {
+    clock scan {2440588 xii:00:00 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M:%S %P}
+} 0
+test clock-29.55 {time parsing} {
+    clock scan {2440588 xii:?:? am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM:%OS %P}
+} 0
+test clock-29.56 {time parsing} {
+    clock scan {2440588 xii am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol %P}
+} 0
+test clock-29.57 {time parsing} {
+    clock scan {2440588 xii:00 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M %P}
+} 0
+test clock-29.58 {time parsing} {
+    clock scan {2440588 xii:? am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM %P}
+} 0
+test clock-29.59 {time parsing} {
+    clock scan {2440588 xii:00:00 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M:%S %P}
+} 0
+test clock-29.60 {time parsing} {
+    clock scan {2440588 xii:?:? am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM:%OS %P}
+} 0
+test clock-29.61 {time parsing} {
+    clock scan {2440588 00:00:01 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%M:%S }
+} 1
+test clock-29.62 {time parsing} {
+    clock scan {2440588 00:?:i } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%OM:%OS }
+} 1
+test clock-29.63 {time parsing} {
+    clock scan {2440588  0:00:01 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%M:%S }
+} 1
+test clock-29.64 {time parsing} {
+    clock scan {2440588  0:?:i } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%OM:%OS }
+} 1
+test clock-29.65 {time parsing} {
+    clock scan {2440588 ?:00:01 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%M:%S }
+} 1
+test clock-29.66 {time parsing} {
+    clock scan {2440588 ?:?:i } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%OM:%OS }
+} 1
+test clock-29.67 {time parsing} {
+    clock scan {2440588 ?:00:01 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%M:%S }
+} 1
+test clock-29.68 {time parsing} {
+    clock scan {2440588 ?:?:i } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%OM:%OS }
+} 1
+test clock-29.69 {time parsing} {
+    clock scan {2440588 12:00:01 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M:%S %p}
+} 1
+test clock-29.70 {time parsing} {
+    clock scan {2440588 12:?:i AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM:%OS %p}
+} 1
+test clock-29.71 {time parsing} {
+    clock scan {2440588 12:00:01 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M:%S %p}
+} 1
+test clock-29.72 {time parsing} {
+    clock scan {2440588 12:?:i AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM:%OS %p}
+} 1
+test clock-29.73 {time parsing} {
+    clock scan {2440588 xii:00:01 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M:%S %p}
+} 1
+test clock-29.74 {time parsing} {
+    clock scan {2440588 xii:?:i AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM:%OS %p}
+} 1
+test clock-29.75 {time parsing} {
+    clock scan {2440588 xii:00:01 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M:%S %p}
+} 1
+test clock-29.76 {time parsing} {
+    clock scan {2440588 xii:?:i AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM:%OS %p}
+} 1
+test clock-29.77 {time parsing} {
+    clock scan {2440588 12:00:01 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M:%S %P}
+} 1
+test clock-29.78 {time parsing} {
+    clock scan {2440588 12:?:i am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM:%OS %P}
+} 1
+test clock-29.79 {time parsing} {
+    clock scan {2440588 12:00:01 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M:%S %P}
+} 1
+test clock-29.80 {time parsing} {
+    clock scan {2440588 12:?:i am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM:%OS %P}
+} 1
+test clock-29.81 {time parsing} {
+    clock scan {2440588 xii:00:01 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M:%S %P}
+} 1
+test clock-29.82 {time parsing} {
+    clock scan {2440588 xii:?:i am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM:%OS %P}
+} 1
+test clock-29.83 {time parsing} {
+    clock scan {2440588 xii:00:01 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M:%S %P}
+} 1
+test clock-29.84 {time parsing} {
+    clock scan {2440588 xii:?:i am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM:%OS %P}
+} 1
+test clock-29.85 {time parsing} {
+    clock scan {2440588 00:00:59 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%M:%S }
+} 59
+test clock-29.86 {time parsing} {
+    clock scan {2440588 00:?:lix } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%OM:%OS }
+} 59
+test clock-29.87 {time parsing} {
+    clock scan {2440588  0:00:59 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%M:%S }
+} 59
+test clock-29.88 {time parsing} {
+    clock scan {2440588  0:?:lix } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%OM:%OS }
+} 59
+test clock-29.89 {time parsing} {
+    clock scan {2440588 ?:00:59 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%M:%S }
+} 59
+test clock-29.90 {time parsing} {
+    clock scan {2440588 ?:?:lix } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%OM:%OS }
+} 59
+test clock-29.91 {time parsing} {
+    clock scan {2440588 ?:00:59 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%M:%S }
+} 59
+test clock-29.92 {time parsing} {
+    clock scan {2440588 ?:?:lix } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%OM:%OS }
+} 59
+test clock-29.93 {time parsing} {
+    clock scan {2440588 12:00:59 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M:%S %p}
+} 59
+test clock-29.94 {time parsing} {
+    clock scan {2440588 12:?:lix AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM:%OS %p}
+} 59
+test clock-29.95 {time parsing} {
+    clock scan {2440588 12:00:59 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M:%S %p}
+} 59
+test clock-29.96 {time parsing} {
+    clock scan {2440588 12:?:lix AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM:%OS %p}
+} 59
+test clock-29.97 {time parsing} {
+    clock scan {2440588 xii:00:59 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M:%S %p}
+} 59
+test clock-29.98 {time parsing} {
+    clock scan {2440588 xii:?:lix AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM:%OS %p}
+} 59
+test clock-29.99 {time parsing} {
+    clock scan {2440588 xii:00:59 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M:%S %p}
+} 59
+test clock-29.100 {time parsing} {
+    clock scan {2440588 xii:?:lix AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM:%OS %p}
+} 59
+test clock-29.101 {time parsing} {
+    clock scan {2440588 12:00:59 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M:%S %P}
+} 59
+test clock-29.102 {time parsing} {
+    clock scan {2440588 12:?:lix am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM:%OS %P}
+} 59
+test clock-29.103 {time parsing} {
+    clock scan {2440588 12:00:59 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M:%S %P}
+} 59
+test clock-29.104 {time parsing} {
+    clock scan {2440588 12:?:lix am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM:%OS %P}
+} 59
+test clock-29.105 {time parsing} {
+    clock scan {2440588 xii:00:59 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M:%S %P}
+} 59
+test clock-29.106 {time parsing} {
+    clock scan {2440588 xii:?:lix am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM:%OS %P}
+} 59
+test clock-29.107 {time parsing} {
+    clock scan {2440588 xii:00:59 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M:%S %P}
+} 59
+test clock-29.108 {time parsing} {
+    clock scan {2440588 xii:?:lix am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM:%OS %P}
+} 59
+test clock-29.109 {time parsing} {
+    clock scan {2440588 00:01 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%M }
+} 60
+test clock-29.110 {time parsing} {
+    clock scan {2440588 00:i } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%OM }
+} 60
+test clock-29.111 {time parsing} {
+    clock scan {2440588 00:01:00 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%M:%S }
+} 60
+test clock-29.112 {time parsing} {
+    clock scan {2440588 00:i:? } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%OM:%OS }
+} 60
+test clock-29.113 {time parsing} {
+    clock scan {2440588  0:01 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%M }
+} 60
+test clock-29.114 {time parsing} {
+    clock scan {2440588  0:i } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%OM }
+} 60
+test clock-29.115 {time parsing} {
+    clock scan {2440588  0:01:00 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%M:%S }
+} 60
+test clock-29.116 {time parsing} {
+    clock scan {2440588  0:i:? } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%OM:%OS }
+} 60
+test clock-29.117 {time parsing} {
+    clock scan {2440588 ?:01 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%M }
+} 60
+test clock-29.118 {time parsing} {
+    clock scan {2440588 ?:i } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%OM }
+} 60
+test clock-29.119 {time parsing} {
+    clock scan {2440588 ?:01:00 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%M:%S }
+} 60
+test clock-29.120 {time parsing} {
+    clock scan {2440588 ?:i:? } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%OM:%OS }
+} 60
+test clock-29.121 {time parsing} {
+    clock scan {2440588 ?:01 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%M }
+} 60
+test clock-29.122 {time parsing} {
+    clock scan {2440588 ?:i } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%OM }
+} 60
+test clock-29.123 {time parsing} {
+    clock scan {2440588 ?:01:00 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%M:%S }
+} 60
+test clock-29.124 {time parsing} {
+    clock scan {2440588 ?:i:? } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%OM:%OS }
+} 60
+test clock-29.125 {time parsing} {
+    clock scan {2440588 12:01 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M %p}
+} 60
+test clock-29.126 {time parsing} {
+    clock scan {2440588 12:i AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM %p}
+} 60
+test clock-29.127 {time parsing} {
+    clock scan {2440588 12:01:00 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M:%S %p}
+} 60
+test clock-29.128 {time parsing} {
+    clock scan {2440588 12:i:? AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM:%OS %p}
+} 60
+test clock-29.129 {time parsing} {
+    clock scan {2440588 12:01 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M %p}
+} 60
+test clock-29.130 {time parsing} {
+    clock scan {2440588 12:i AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM %p}
+} 60
+test clock-29.131 {time parsing} {
+    clock scan {2440588 12:01:00 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M:%S %p}
+} 60
+test clock-29.132 {time parsing} {
+    clock scan {2440588 12:i:? AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM:%OS %p}
+} 60
+test clock-29.133 {time parsing} {
+    clock scan {2440588 xii:01 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M %p}
+} 60
+test clock-29.134 {time parsing} {
+    clock scan {2440588 xii:i AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM %p}
+} 60
+test clock-29.135 {time parsing} {
+    clock scan {2440588 xii:01:00 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M:%S %p}
+} 60
+test clock-29.136 {time parsing} {
+    clock scan {2440588 xii:i:? AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM:%OS %p}
+} 60
+test clock-29.137 {time parsing} {
+    clock scan {2440588 xii:01 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M %p}
+} 60
+test clock-29.138 {time parsing} {
+    clock scan {2440588 xii:i AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM %p}
+} 60
+test clock-29.139 {time parsing} {
+    clock scan {2440588 xii:01:00 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M:%S %p}
+} 60
+test clock-29.140 {time parsing} {
+    clock scan {2440588 xii:i:? AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM:%OS %p}
+} 60
+test clock-29.141 {time parsing} {
+    clock scan {2440588 12:01 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M %P}
+} 60
+test clock-29.142 {time parsing} {
+    clock scan {2440588 12:i am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM %P}
+} 60
+test clock-29.143 {time parsing} {
+    clock scan {2440588 12:01:00 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M:%S %P}
+} 60
+test clock-29.144 {time parsing} {
+    clock scan {2440588 12:i:? am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM:%OS %P}
+} 60
+test clock-29.145 {time parsing} {
+    clock scan {2440588 12:01 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M %P}
+} 60
+test clock-29.146 {time parsing} {
+    clock scan {2440588 12:i am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM %P}
+} 60
+test clock-29.147 {time parsing} {
+    clock scan {2440588 12:01:00 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M:%S %P}
+} 60
+test clock-29.148 {time parsing} {
+    clock scan {2440588 12:i:? am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM:%OS %P}
+} 60
+test clock-29.149 {time parsing} {
+    clock scan {2440588 xii:01 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M %P}
+} 60
+test clock-29.150 {time parsing} {
+    clock scan {2440588 xii:i am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM %P}
+} 60
+test clock-29.151 {time parsing} {
+    clock scan {2440588 xii:01:00 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M:%S %P}
+} 60
+test clock-29.152 {time parsing} {
+    clock scan {2440588 xii:i:? am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM:%OS %P}
+} 60
+test clock-29.153 {time parsing} {
+    clock scan {2440588 xii:01 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M %P}
+} 60
+test clock-29.154 {time parsing} {
+    clock scan {2440588 xii:i am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM %P}
+} 60
+test clock-29.155 {time parsing} {
+    clock scan {2440588 xii:01:00 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M:%S %P}
+} 60
+test clock-29.156 {time parsing} {
+    clock scan {2440588 xii:i:? am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM:%OS %P}
+} 60
+test clock-29.157 {time parsing} {
+    clock scan {2440588 00:01:01 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%M:%S }
+} 61
+test clock-29.158 {time parsing} {
+    clock scan {2440588 00:i:i } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%OM:%OS }
+} 61
+test clock-29.159 {time parsing} {
+    clock scan {2440588  0:01:01 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%M:%S }
+} 61
+test clock-29.160 {time parsing} {
+    clock scan {2440588  0:i:i } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%OM:%OS }
+} 61
+test clock-29.161 {time parsing} {
+    clock scan {2440588 ?:01:01 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%M:%S }
+} 61
+test clock-29.162 {time parsing} {
+    clock scan {2440588 ?:i:i } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%OM:%OS }
+} 61
+test clock-29.163 {time parsing} {
+    clock scan {2440588 ?:01:01 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%M:%S }
+} 61
+test clock-29.164 {time parsing} {
+    clock scan {2440588 ?:i:i } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%OM:%OS }
+} 61
+test clock-29.165 {time parsing} {
+    clock scan {2440588 12:01:01 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M:%S %p}
+} 61
+test clock-29.166 {time parsing} {
+    clock scan {2440588 12:i:i AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM:%OS %p}
+} 61
+test clock-29.167 {time parsing} {
+    clock scan {2440588 12:01:01 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M:%S %p}
+} 61
+test clock-29.168 {time parsing} {
+    clock scan {2440588 12:i:i AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM:%OS %p}
+} 61
+test clock-29.169 {time parsing} {
+    clock scan {2440588 xii:01:01 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M:%S %p}
+} 61
+test clock-29.170 {time parsing} {
+    clock scan {2440588 xii:i:i AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM:%OS %p}
+} 61
+test clock-29.171 {time parsing} {
+    clock scan {2440588 xii:01:01 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M:%S %p}
+} 61
+test clock-29.172 {time parsing} {
+    clock scan {2440588 xii:i:i AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM:%OS %p}
+} 61
+test clock-29.173 {time parsing} {
+    clock scan {2440588 12:01:01 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M:%S %P}
+} 61
+test clock-29.174 {time parsing} {
+    clock scan {2440588 12:i:i am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM:%OS %P}
+} 61
+test clock-29.175 {time parsing} {
+    clock scan {2440588 12:01:01 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M:%S %P}
+} 61
+test clock-29.176 {time parsing} {
+    clock scan {2440588 12:i:i am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM:%OS %P}
+} 61
+test clock-29.177 {time parsing} {
+    clock scan {2440588 xii:01:01 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M:%S %P}
+} 61
+test clock-29.178 {time parsing} {
+    clock scan {2440588 xii:i:i am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM:%OS %P}
+} 61
+test clock-29.179 {time parsing} {
+    clock scan {2440588 xii:01:01 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M:%S %P}
+} 61
+test clock-29.180 {time parsing} {
+    clock scan {2440588 xii:i:i am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM:%OS %P}
+} 61
+test clock-29.181 {time parsing} {
+    clock scan {2440588 00:01:59 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%M:%S }
+} 119
+test clock-29.182 {time parsing} {
+    clock scan {2440588 00:i:lix } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%OM:%OS }
+} 119
+test clock-29.183 {time parsing} {
+    clock scan {2440588  0:01:59 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%M:%S }
+} 119
+test clock-29.184 {time parsing} {
+    clock scan {2440588  0:i:lix } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%OM:%OS }
+} 119
+test clock-29.185 {time parsing} {
+    clock scan {2440588 ?:01:59 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%M:%S }
+} 119
+test clock-29.186 {time parsing} {
+    clock scan {2440588 ?:i:lix } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%OM:%OS }
+} 119
+test clock-29.187 {time parsing} {
+    clock scan {2440588 ?:01:59 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%M:%S }
+} 119
+test clock-29.188 {time parsing} {
+    clock scan {2440588 ?:i:lix } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%OM:%OS }
+} 119
+test clock-29.189 {time parsing} {
+    clock scan {2440588 12:01:59 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M:%S %p}
+} 119
+test clock-29.190 {time parsing} {
+    clock scan {2440588 12:i:lix AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM:%OS %p}
+} 119
+test clock-29.191 {time parsing} {
+    clock scan {2440588 12:01:59 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M:%S %p}
+} 119
+test clock-29.192 {time parsing} {
+    clock scan {2440588 12:i:lix AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM:%OS %p}
+} 119
+test clock-29.193 {time parsing} {
+    clock scan {2440588 xii:01:59 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M:%S %p}
+} 119
+test clock-29.194 {time parsing} {
+    clock scan {2440588 xii:i:lix AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM:%OS %p}
+} 119
+test clock-29.195 {time parsing} {
+    clock scan {2440588 xii:01:59 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M:%S %p}
+} 119
+test clock-29.196 {time parsing} {
+    clock scan {2440588 xii:i:lix AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM:%OS %p}
+} 119
+test clock-29.197 {time parsing} {
+    clock scan {2440588 12:01:59 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M:%S %P}
+} 119
+test clock-29.198 {time parsing} {
+    clock scan {2440588 12:i:lix am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM:%OS %P}
+} 119
+test clock-29.199 {time parsing} {
+    clock scan {2440588 12:01:59 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M:%S %P}
+} 119
+test clock-29.200 {time parsing} {
+    clock scan {2440588 12:i:lix am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM:%OS %P}
+} 119
+test clock-29.201 {time parsing} {
+    clock scan {2440588 xii:01:59 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M:%S %P}
+} 119
+test clock-29.202 {time parsing} {
+    clock scan {2440588 xii:i:lix am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM:%OS %P}
+} 119
+test clock-29.203 {time parsing} {
+    clock scan {2440588 xii:01:59 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M:%S %P}
+} 119
+test clock-29.204 {time parsing} {
+    clock scan {2440588 xii:i:lix am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM:%OS %P}
+} 119
+test clock-29.205 {time parsing} {
+    clock scan {2440588 00:59 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%M }
+} 3540
+test clock-29.206 {time parsing} {
+    clock scan {2440588 00:lix } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%OM }
+} 3540
+test clock-29.207 {time parsing} {
+    clock scan {2440588 00:59:00 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%M:%S }
+} 3540
+test clock-29.208 {time parsing} {
+    clock scan {2440588 00:lix:? } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%OM:%OS }
+} 3540
+test clock-29.209 {time parsing} {
+    clock scan {2440588  0:59 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%M }
+} 3540
+test clock-29.210 {time parsing} {
+    clock scan {2440588  0:lix } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%OM }
+} 3540
+test clock-29.211 {time parsing} {
+    clock scan {2440588  0:59:00 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%M:%S }
+} 3540
+test clock-29.212 {time parsing} {
+    clock scan {2440588  0:lix:? } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%OM:%OS }
+} 3540
+test clock-29.213 {time parsing} {
+    clock scan {2440588 ?:59 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%M }
+} 3540
+test clock-29.214 {time parsing} {
+    clock scan {2440588 ?:lix } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%OM }
+} 3540
+test clock-29.215 {time parsing} {
+    clock scan {2440588 ?:59:00 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%M:%S }
+} 3540
+test clock-29.216 {time parsing} {
+    clock scan {2440588 ?:lix:? } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%OM:%OS }
+} 3540
+test clock-29.217 {time parsing} {
+    clock scan {2440588 ?:59 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%M }
+} 3540
+test clock-29.218 {time parsing} {
+    clock scan {2440588 ?:lix } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%OM }
+} 3540
+test clock-29.219 {time parsing} {
+    clock scan {2440588 ?:59:00 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%M:%S }
+} 3540
+test clock-29.220 {time parsing} {
+    clock scan {2440588 ?:lix:? } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%OM:%OS }
+} 3540
+test clock-29.221 {time parsing} {
+    clock scan {2440588 12:59 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M %p}
+} 3540
+test clock-29.222 {time parsing} {
+    clock scan {2440588 12:lix AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM %p}
+} 3540
+test clock-29.223 {time parsing} {
+    clock scan {2440588 12:59:00 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M:%S %p}
+} 3540
+test clock-29.224 {time parsing} {
+    clock scan {2440588 12:lix:? AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM:%OS %p}
+} 3540
+test clock-29.225 {time parsing} {
+    clock scan {2440588 12:59 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M %p}
+} 3540
+test clock-29.226 {time parsing} {
+    clock scan {2440588 12:lix AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM %p}
+} 3540
+test clock-29.227 {time parsing} {
+    clock scan {2440588 12:59:00 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M:%S %p}
+} 3540
+test clock-29.228 {time parsing} {
+    clock scan {2440588 12:lix:? AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM:%OS %p}
+} 3540
+test clock-29.229 {time parsing} {
+    clock scan {2440588 xii:59 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M %p}
+} 3540
+test clock-29.230 {time parsing} {
+    clock scan {2440588 xii:lix AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM %p}
+} 3540
+test clock-29.231 {time parsing} {
+    clock scan {2440588 xii:59:00 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M:%S %p}
+} 3540
+test clock-29.232 {time parsing} {
+    clock scan {2440588 xii:lix:? AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM:%OS %p}
+} 3540
+test clock-29.233 {time parsing} {
+    clock scan {2440588 xii:59 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M %p}
+} 3540
+test clock-29.234 {time parsing} {
+    clock scan {2440588 xii:lix AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM %p}
+} 3540
+test clock-29.235 {time parsing} {
+    clock scan {2440588 xii:59:00 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M:%S %p}
+} 3540
+test clock-29.236 {time parsing} {
+    clock scan {2440588 xii:lix:? AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM:%OS %p}
+} 3540
+test clock-29.237 {time parsing} {
+    clock scan {2440588 12:59 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M %P}
+} 3540
+test clock-29.238 {time parsing} {
+    clock scan {2440588 12:lix am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM %P}
+} 3540
+test clock-29.239 {time parsing} {
+    clock scan {2440588 12:59:00 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M:%S %P}
+} 3540
+test clock-29.240 {time parsing} {
+    clock scan {2440588 12:lix:? am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM:%OS %P}
+} 3540
+test clock-29.241 {time parsing} {
+    clock scan {2440588 12:59 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M %P}
+} 3540
+test clock-29.242 {time parsing} {
+    clock scan {2440588 12:lix am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM %P}
+} 3540
+test clock-29.243 {time parsing} {
+    clock scan {2440588 12:59:00 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M:%S %P}
+} 3540
+test clock-29.244 {time parsing} {
+    clock scan {2440588 12:lix:? am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM:%OS %P}
+} 3540
+test clock-29.245 {time parsing} {
+    clock scan {2440588 xii:59 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M %P}
+} 3540
+test clock-29.246 {time parsing} {
+    clock scan {2440588 xii:lix am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM %P}
+} 3540
+test clock-29.247 {time parsing} {
+    clock scan {2440588 xii:59:00 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M:%S %P}
+} 3540
+test clock-29.248 {time parsing} {
+    clock scan {2440588 xii:lix:? am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM:%OS %P}
+} 3540
+test clock-29.249 {time parsing} {
+    clock scan {2440588 xii:59 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M %P}
+} 3540
+test clock-29.250 {time parsing} {
+    clock scan {2440588 xii:lix am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM %P}
+} 3540
+test clock-29.251 {time parsing} {
+    clock scan {2440588 xii:59:00 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M:%S %P}
+} 3540
+test clock-29.252 {time parsing} {
+    clock scan {2440588 xii:lix:? am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM:%OS %P}
+} 3540
+test clock-29.253 {time parsing} {
+    clock scan {2440588 00:59:01 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%M:%S }
+} 3541
+test clock-29.254 {time parsing} {
+    clock scan {2440588 00:lix:i } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%OM:%OS }
+} 3541
+test clock-29.255 {time parsing} {
+    clock scan {2440588  0:59:01 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%M:%S }
+} 3541
+test clock-29.256 {time parsing} {
+    clock scan {2440588  0:lix:i } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%OM:%OS }
+} 3541
+test clock-29.257 {time parsing} {
+    clock scan {2440588 ?:59:01 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%M:%S }
+} 3541
+test clock-29.258 {time parsing} {
+    clock scan {2440588 ?:lix:i } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%OM:%OS }
+} 3541
+test clock-29.259 {time parsing} {
+    clock scan {2440588 ?:59:01 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%M:%S }
+} 3541
+test clock-29.260 {time parsing} {
+    clock scan {2440588 ?:lix:i } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%OM:%OS }
+} 3541
+test clock-29.261 {time parsing} {
+    clock scan {2440588 12:59:01 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M:%S %p}
+} 3541
+test clock-29.262 {time parsing} {
+    clock scan {2440588 12:lix:i AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM:%OS %p}
+} 3541
+test clock-29.263 {time parsing} {
+    clock scan {2440588 12:59:01 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M:%S %p}
+} 3541
+test clock-29.264 {time parsing} {
+    clock scan {2440588 12:lix:i AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM:%OS %p}
+} 3541
+test clock-29.265 {time parsing} {
+    clock scan {2440588 xii:59:01 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M:%S %p}
+} 3541
+test clock-29.266 {time parsing} {
+    clock scan {2440588 xii:lix:i AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM:%OS %p}
+} 3541
+test clock-29.267 {time parsing} {
+    clock scan {2440588 xii:59:01 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M:%S %p}
+} 3541
+test clock-29.268 {time parsing} {
+    clock scan {2440588 xii:lix:i AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM:%OS %p}
+} 3541
+test clock-29.269 {time parsing} {
+    clock scan {2440588 12:59:01 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M:%S %P}
+} 3541
+test clock-29.270 {time parsing} {
+    clock scan {2440588 12:lix:i am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM:%OS %P}
+} 3541
+test clock-29.271 {time parsing} {
+    clock scan {2440588 12:59:01 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M:%S %P}
+} 3541
+test clock-29.272 {time parsing} {
+    clock scan {2440588 12:lix:i am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM:%OS %P}
+} 3541
+test clock-29.273 {time parsing} {
+    clock scan {2440588 xii:59:01 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M:%S %P}
+} 3541
+test clock-29.274 {time parsing} {
+    clock scan {2440588 xii:lix:i am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM:%OS %P}
+} 3541
+test clock-29.275 {time parsing} {
+    clock scan {2440588 xii:59:01 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M:%S %P}
+} 3541
+test clock-29.276 {time parsing} {
+    clock scan {2440588 xii:lix:i am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM:%OS %P}
+} 3541
+test clock-29.277 {time parsing} {
+    clock scan {2440588 00:59:59 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%M:%S }
+} 3599
+test clock-29.278 {time parsing} {
+    clock scan {2440588 00:lix:lix } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%OM:%OS }
+} 3599
+test clock-29.279 {time parsing} {
+    clock scan {2440588  0:59:59 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%M:%S }
+} 3599
+test clock-29.280 {time parsing} {
+    clock scan {2440588  0:lix:lix } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%OM:%OS }
+} 3599
+test clock-29.281 {time parsing} {
+    clock scan {2440588 ?:59:59 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%M:%S }
+} 3599
+test clock-29.282 {time parsing} {
+    clock scan {2440588 ?:lix:lix } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%OM:%OS }
+} 3599
+test clock-29.283 {time parsing} {
+    clock scan {2440588 ?:59:59 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%M:%S }
+} 3599
+test clock-29.284 {time parsing} {
+    clock scan {2440588 ?:lix:lix } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%OM:%OS }
+} 3599
+test clock-29.285 {time parsing} {
+    clock scan {2440588 12:59:59 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M:%S %p}
+} 3599
+test clock-29.286 {time parsing} {
+    clock scan {2440588 12:lix:lix AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM:%OS %p}
+} 3599
+test clock-29.287 {time parsing} {
+    clock scan {2440588 12:59:59 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M:%S %p}
+} 3599
+test clock-29.288 {time parsing} {
+    clock scan {2440588 12:lix:lix AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM:%OS %p}
+} 3599
+test clock-29.289 {time parsing} {
+    clock scan {2440588 xii:59:59 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M:%S %p}
+} 3599
+test clock-29.290 {time parsing} {
+    clock scan {2440588 xii:lix:lix AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM:%OS %p}
+} 3599
+test clock-29.291 {time parsing} {
+    clock scan {2440588 xii:59:59 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M:%S %p}
+} 3599
+test clock-29.292 {time parsing} {
+    clock scan {2440588 xii:lix:lix AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM:%OS %p}
+} 3599
+test clock-29.293 {time parsing} {
+    clock scan {2440588 12:59:59 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M:%S %P}
+} 3599
+test clock-29.294 {time parsing} {
+    clock scan {2440588 12:lix:lix am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM:%OS %P}
+} 3599
+test clock-29.295 {time parsing} {
+    clock scan {2440588 12:59:59 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M:%S %P}
+} 3599
+test clock-29.296 {time parsing} {
+    clock scan {2440588 12:lix:lix am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM:%OS %P}
+} 3599
+test clock-29.297 {time parsing} {
+    clock scan {2440588 xii:59:59 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M:%S %P}
+} 3599
+test clock-29.298 {time parsing} {
+    clock scan {2440588 xii:lix:lix am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM:%OS %P}
+} 3599
+test clock-29.299 {time parsing} {
+    clock scan {2440588 xii:59:59 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M:%S %P}
+} 3599
+test clock-29.300 {time parsing} {
+    clock scan {2440588 xii:lix:lix am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM:%OS %P}
+} 3599
+test clock-29.301 {time parsing} {
+    clock scan {2440588 01 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H }
+} 3600
+test clock-29.302 {time parsing} {
+    clock scan {2440588 01:00 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%M }
+} 3600
+test clock-29.303 {time parsing} {
+    clock scan {2440588 01:? } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%OM }
+} 3600
+test clock-29.304 {time parsing} {
+    clock scan {2440588 01:00:00 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%M:%S }
+} 3600
+test clock-29.305 {time parsing} {
+    clock scan {2440588 01:?:? } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%OM:%OS }
+} 3600
+test clock-29.306 {time parsing} {
+    clock scan {2440588  1 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k }
+} 3600
+test clock-29.307 {time parsing} {
+    clock scan {2440588  1:00 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%M }
+} 3600
+test clock-29.308 {time parsing} {
+    clock scan {2440588  1:? } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%OM }
+} 3600
+test clock-29.309 {time parsing} {
+    clock scan {2440588  1:00:00 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%M:%S }
+} 3600
+test clock-29.310 {time parsing} {
+    clock scan {2440588  1:?:? } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%OM:%OS }
+} 3600
+test clock-29.311 {time parsing} {
+    clock scan {2440588 i } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH }
+} 3600
+test clock-29.312 {time parsing} {
+    clock scan {2440588 i:00 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%M }
+} 3600
+test clock-29.313 {time parsing} {
+    clock scan {2440588 i:? } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%OM }
+} 3600
+test clock-29.314 {time parsing} {
+    clock scan {2440588 i:00:00 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%M:%S }
+} 3600
+test clock-29.315 {time parsing} {
+    clock scan {2440588 i:?:? } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%OM:%OS }
+} 3600
+test clock-29.316 {time parsing} {
+    clock scan {2440588 i } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok }
+} 3600
+test clock-29.317 {time parsing} {
+    clock scan {2440588 i:00 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%M }
+} 3600
+test clock-29.318 {time parsing} {
+    clock scan {2440588 i:? } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%OM }
+} 3600
+test clock-29.319 {time parsing} {
+    clock scan {2440588 i:00:00 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%M:%S }
+} 3600
+test clock-29.320 {time parsing} {
+    clock scan {2440588 i:?:? } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%OM:%OS }
+} 3600
+test clock-29.321 {time parsing} {
+    clock scan {2440588 01 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I %p}
+} 3600
+test clock-29.322 {time parsing} {
+    clock scan {2440588 01:00 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M %p}
+} 3600
+test clock-29.323 {time parsing} {
+    clock scan {2440588 01:? AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM %p}
+} 3600
+test clock-29.324 {time parsing} {
+    clock scan {2440588 01:00:00 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M:%S %p}
+} 3600
+test clock-29.325 {time parsing} {
+    clock scan {2440588 01:?:? AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM:%OS %p}
+} 3600
+test clock-29.326 {time parsing} {
+    clock scan {2440588  1 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l %p}
+} 3600
+test clock-29.327 {time parsing} {
+    clock scan {2440588  1:00 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M %p}
+} 3600
+test clock-29.328 {time parsing} {
+    clock scan {2440588  1:? AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM %p}
+} 3600
+test clock-29.329 {time parsing} {
+    clock scan {2440588  1:00:00 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M:%S %p}
+} 3600
+test clock-29.330 {time parsing} {
+    clock scan {2440588  1:?:? AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM:%OS %p}
+} 3600
+test clock-29.331 {time parsing} {
+    clock scan {2440588 i AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI %p}
+} 3600
+test clock-29.332 {time parsing} {
+    clock scan {2440588 i:00 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M %p}
+} 3600
+test clock-29.333 {time parsing} {
+    clock scan {2440588 i:? AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM %p}
+} 3600
+test clock-29.334 {time parsing} {
+    clock scan {2440588 i:00:00 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M:%S %p}
+} 3600
+test clock-29.335 {time parsing} {
+    clock scan {2440588 i:?:? AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM:%OS %p}
+} 3600
+test clock-29.336 {time parsing} {
+    clock scan {2440588 i AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol %p}
+} 3600
+test clock-29.337 {time parsing} {
+    clock scan {2440588 i:00 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M %p}
+} 3600
+test clock-29.338 {time parsing} {
+    clock scan {2440588 i:? AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM %p}
+} 3600
+test clock-29.339 {time parsing} {
+    clock scan {2440588 i:00:00 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M:%S %p}
+} 3600
+test clock-29.340 {time parsing} {
+    clock scan {2440588 i:?:? AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM:%OS %p}
+} 3600
+test clock-29.341 {time parsing} {
+    clock scan {2440588 01 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I %P}
+} 3600
+test clock-29.342 {time parsing} {
+    clock scan {2440588 01:00 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M %P}
+} 3600
+test clock-29.343 {time parsing} {
+    clock scan {2440588 01:? am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM %P}
+} 3600
+test clock-29.344 {time parsing} {
+    clock scan {2440588 01:00:00 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M:%S %P}
+} 3600
+test clock-29.345 {time parsing} {
+    clock scan {2440588 01:?:? am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM:%OS %P}
+} 3600
+test clock-29.346 {time parsing} {
+    clock scan {2440588  1 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l %P}
+} 3600
+test clock-29.347 {time parsing} {
+    clock scan {2440588  1:00 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M %P}
+} 3600
+test clock-29.348 {time parsing} {
+    clock scan {2440588  1:? am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM %P}
+} 3600
+test clock-29.349 {time parsing} {
+    clock scan {2440588  1:00:00 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M:%S %P}
+} 3600
+test clock-29.350 {time parsing} {
+    clock scan {2440588  1:?:? am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM:%OS %P}
+} 3600
+test clock-29.351 {time parsing} {
+    clock scan {2440588 i am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI %P}
+} 3600
+test clock-29.352 {time parsing} {
+    clock scan {2440588 i:00 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M %P}
+} 3600
+test clock-29.353 {time parsing} {
+    clock scan {2440588 i:? am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM %P}
+} 3600
+test clock-29.354 {time parsing} {
+    clock scan {2440588 i:00:00 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M:%S %P}
+} 3600
+test clock-29.355 {time parsing} {
+    clock scan {2440588 i:?:? am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM:%OS %P}
+} 3600
+test clock-29.356 {time parsing} {
+    clock scan {2440588 i am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol %P}
+} 3600
+test clock-29.357 {time parsing} {
+    clock scan {2440588 i:00 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M %P}
+} 3600
+test clock-29.358 {time parsing} {
+    clock scan {2440588 i:? am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM %P}
+} 3600
+test clock-29.359 {time parsing} {
+    clock scan {2440588 i:00:00 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M:%S %P}
+} 3600
+test clock-29.360 {time parsing} {
+    clock scan {2440588 i:?:? am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM:%OS %P}
+} 3600
+test clock-29.361 {time parsing} {
+    clock scan {2440588 01:00:01 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%M:%S }
+} 3601
+test clock-29.362 {time parsing} {
+    clock scan {2440588 01:?:i } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%OM:%OS }
+} 3601
+test clock-29.363 {time parsing} {
+    clock scan {2440588  1:00:01 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%M:%S }
+} 3601
+test clock-29.364 {time parsing} {
+    clock scan {2440588  1:?:i } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%OM:%OS }
+} 3601
+test clock-29.365 {time parsing} {
+    clock scan {2440588 i:00:01 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%M:%S }
+} 3601
+test clock-29.366 {time parsing} {
+    clock scan {2440588 i:?:i } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%OM:%OS }
+} 3601
+test clock-29.367 {time parsing} {
+    clock scan {2440588 i:00:01 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%M:%S }
+} 3601
+test clock-29.368 {time parsing} {
+    clock scan {2440588 i:?:i } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%OM:%OS }
+} 3601
+test clock-29.369 {time parsing} {
+    clock scan {2440588 01:00:01 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M:%S %p}
+} 3601
+test clock-29.370 {time parsing} {
+    clock scan {2440588 01:?:i AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM:%OS %p}
+} 3601
+test clock-29.371 {time parsing} {
+    clock scan {2440588  1:00:01 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M:%S %p}
+} 3601
+test clock-29.372 {time parsing} {
+    clock scan {2440588  1:?:i AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM:%OS %p}
+} 3601
+test clock-29.373 {time parsing} {
+    clock scan {2440588 i:00:01 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M:%S %p}
+} 3601
+test clock-29.374 {time parsing} {
+    clock scan {2440588 i:?:i AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM:%OS %p}
+} 3601
+test clock-29.375 {time parsing} {
+    clock scan {2440588 i:00:01 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M:%S %p}
+} 3601
+test clock-29.376 {time parsing} {
+    clock scan {2440588 i:?:i AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM:%OS %p}
+} 3601
+test clock-29.377 {time parsing} {
+    clock scan {2440588 01:00:01 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M:%S %P}
+} 3601
+test clock-29.378 {time parsing} {
+    clock scan {2440588 01:?:i am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM:%OS %P}
+} 3601
+test clock-29.379 {time parsing} {
+    clock scan {2440588  1:00:01 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M:%S %P}
+} 3601
+test clock-29.380 {time parsing} {
+    clock scan {2440588  1:?:i am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM:%OS %P}
+} 3601
+test clock-29.381 {time parsing} {
+    clock scan {2440588 i:00:01 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M:%S %P}
+} 3601
+test clock-29.382 {time parsing} {
+    clock scan {2440588 i:?:i am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM:%OS %P}
+} 3601
+test clock-29.383 {time parsing} {
+    clock scan {2440588 i:00:01 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M:%S %P}
+} 3601
+test clock-29.384 {time parsing} {
+    clock scan {2440588 i:?:i am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM:%OS %P}
+} 3601
+test clock-29.385 {time parsing} {
+    clock scan {2440588 01:00:59 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%M:%S }
+} 3659
+test clock-29.386 {time parsing} {
+    clock scan {2440588 01:?:lix } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%OM:%OS }
+} 3659
+test clock-29.387 {time parsing} {
+    clock scan {2440588  1:00:59 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%M:%S }
+} 3659
+test clock-29.388 {time parsing} {
+    clock scan {2440588  1:?:lix } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%OM:%OS }
+} 3659
+test clock-29.389 {time parsing} {
+    clock scan {2440588 i:00:59 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%M:%S }
+} 3659
+test clock-29.390 {time parsing} {
+    clock scan {2440588 i:?:lix } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%OM:%OS }
+} 3659
+test clock-29.391 {time parsing} {
+    clock scan {2440588 i:00:59 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%M:%S }
+} 3659
+test clock-29.392 {time parsing} {
+    clock scan {2440588 i:?:lix } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%OM:%OS }
+} 3659
+test clock-29.393 {time parsing} {
+    clock scan {2440588 01:00:59 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M:%S %p}
+} 3659
+test clock-29.394 {time parsing} {
+    clock scan {2440588 01:?:lix AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM:%OS %p}
+} 3659
+test clock-29.395 {time parsing} {
+    clock scan {2440588  1:00:59 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M:%S %p}
+} 3659
+test clock-29.396 {time parsing} {
+    clock scan {2440588  1:?:lix AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM:%OS %p}
+} 3659
+test clock-29.397 {time parsing} {
+    clock scan {2440588 i:00:59 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M:%S %p}
+} 3659
+test clock-29.398 {time parsing} {
+    clock scan {2440588 i:?:lix AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM:%OS %p}
+} 3659
+test clock-29.399 {time parsing} {
+    clock scan {2440588 i:00:59 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M:%S %p}
+} 3659
+test clock-29.400 {time parsing} {
+    clock scan {2440588 i:?:lix AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM:%OS %p}
+} 3659
+test clock-29.401 {time parsing} {
+    clock scan {2440588 01:00:59 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M:%S %P}
+} 3659
+test clock-29.402 {time parsing} {
+    clock scan {2440588 01:?:lix am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM:%OS %P}
+} 3659
+test clock-29.403 {time parsing} {
+    clock scan {2440588  1:00:59 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M:%S %P}
+} 3659
+test clock-29.404 {time parsing} {
+    clock scan {2440588  1:?:lix am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM:%OS %P}
+} 3659
+test clock-29.405 {time parsing} {
+    clock scan {2440588 i:00:59 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M:%S %P}
+} 3659
+test clock-29.406 {time parsing} {
+    clock scan {2440588 i:?:lix am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM:%OS %P}
+} 3659
+test clock-29.407 {time parsing} {
+    clock scan {2440588 i:00:59 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M:%S %P}
+} 3659
+test clock-29.408 {time parsing} {
+    clock scan {2440588 i:?:lix am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM:%OS %P}
+} 3659
+test clock-29.409 {time parsing} {
+    clock scan {2440588 01:01 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%M }
+} 3660
+test clock-29.410 {time parsing} {
+    clock scan {2440588 01:i } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%OM }
+} 3660
+test clock-29.411 {time parsing} {
+    clock scan {2440588 01:01:00 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%M:%S }
+} 3660
+test clock-29.412 {time parsing} {
+    clock scan {2440588 01:i:? } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%OM:%OS }
+} 3660
+test clock-29.413 {time parsing} {
+    clock scan {2440588  1:01 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%M }
+} 3660
+test clock-29.414 {time parsing} {
+    clock scan {2440588  1:i } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%OM }
+} 3660
+test clock-29.415 {time parsing} {
+    clock scan {2440588  1:01:00 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%M:%S }
+} 3660
+test clock-29.416 {time parsing} {
+    clock scan {2440588  1:i:? } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%OM:%OS }
+} 3660
+test clock-29.417 {time parsing} {
+    clock scan {2440588 i:01 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%M }
+} 3660
+test clock-29.418 {time parsing} {
+    clock scan {2440588 i:i } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%OM }
+} 3660
+test clock-29.419 {time parsing} {
+    clock scan {2440588 i:01:00 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%M:%S }
+} 3660
+test clock-29.420 {time parsing} {
+    clock scan {2440588 i:i:? } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%OM:%OS }
+} 3660
+test clock-29.421 {time parsing} {
+    clock scan {2440588 i:01 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%M }
+} 3660
+test clock-29.422 {time parsing} {
+    clock scan {2440588 i:i } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%OM }
+} 3660
+test clock-29.423 {time parsing} {
+    clock scan {2440588 i:01:00 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%M:%S }
+} 3660
+test clock-29.424 {time parsing} {
+    clock scan {2440588 i:i:? } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%OM:%OS }
+} 3660
+test clock-29.425 {time parsing} {
+    clock scan {2440588 01:01 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M %p}
+} 3660
+test clock-29.426 {time parsing} {
+    clock scan {2440588 01:i AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM %p}
+} 3660
+test clock-29.427 {time parsing} {
+    clock scan {2440588 01:01:00 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M:%S %p}
+} 3660
+test clock-29.428 {time parsing} {
+    clock scan {2440588 01:i:? AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM:%OS %p}
+} 3660
+test clock-29.429 {time parsing} {
+    clock scan {2440588  1:01 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M %p}
+} 3660
+test clock-29.430 {time parsing} {
+    clock scan {2440588  1:i AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM %p}
+} 3660
+test clock-29.431 {time parsing} {
+    clock scan {2440588  1:01:00 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M:%S %p}
+} 3660
+test clock-29.432 {time parsing} {
+    clock scan {2440588  1:i:? AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM:%OS %p}
+} 3660
+test clock-29.433 {time parsing} {
+    clock scan {2440588 i:01 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M %p}
+} 3660
+test clock-29.434 {time parsing} {
+    clock scan {2440588 i:i AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM %p}
+} 3660
+test clock-29.435 {time parsing} {
+    clock scan {2440588 i:01:00 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M:%S %p}
+} 3660
+test clock-29.436 {time parsing} {
+    clock scan {2440588 i:i:? AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM:%OS %p}
+} 3660
+test clock-29.437 {time parsing} {
+    clock scan {2440588 i:01 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M %p}
+} 3660
+test clock-29.438 {time parsing} {
+    clock scan {2440588 i:i AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM %p}
+} 3660
+test clock-29.439 {time parsing} {
+    clock scan {2440588 i:01:00 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M:%S %p}
+} 3660
+test clock-29.440 {time parsing} {
+    clock scan {2440588 i:i:? AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM:%OS %p}
+} 3660
+test clock-29.441 {time parsing} {
+    clock scan {2440588 01:01 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M %P}
+} 3660
+test clock-29.442 {time parsing} {
+    clock scan {2440588 01:i am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM %P}
+} 3660
+test clock-29.443 {time parsing} {
+    clock scan {2440588 01:01:00 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M:%S %P}
+} 3660
+test clock-29.444 {time parsing} {
+    clock scan {2440588 01:i:? am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM:%OS %P}
+} 3660
+test clock-29.445 {time parsing} {
+    clock scan {2440588  1:01 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M %P}
+} 3660
+test clock-29.446 {time parsing} {
+    clock scan {2440588  1:i am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM %P}
+} 3660
+test clock-29.447 {time parsing} {
+    clock scan {2440588  1:01:00 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M:%S %P}
+} 3660
+test clock-29.448 {time parsing} {
+    clock scan {2440588  1:i:? am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM:%OS %P}
+} 3660
+test clock-29.449 {time parsing} {
+    clock scan {2440588 i:01 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M %P}
+} 3660
+test clock-29.450 {time parsing} {
+    clock scan {2440588 i:i am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM %P}
+} 3660
+test clock-29.451 {time parsing} {
+    clock scan {2440588 i:01:00 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M:%S %P}
+} 3660
+test clock-29.452 {time parsing} {
+    clock scan {2440588 i:i:? am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM:%OS %P}
+} 3660
+test clock-29.453 {time parsing} {
+    clock scan {2440588 i:01 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M %P}
+} 3660
+test clock-29.454 {time parsing} {
+    clock scan {2440588 i:i am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM %P}
+} 3660
+test clock-29.455 {time parsing} {
+    clock scan {2440588 i:01:00 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M:%S %P}
+} 3660
+test clock-29.456 {time parsing} {
+    clock scan {2440588 i:i:? am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM:%OS %P}
+} 3660
+test clock-29.457 {time parsing} {
+    clock scan {2440588 01:01:01 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%M:%S }
+} 3661
+test clock-29.458 {time parsing} {
+    clock scan {2440588 01:i:i } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%OM:%OS }
+} 3661
+test clock-29.459 {time parsing} {
+    clock scan {2440588  1:01:01 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%M:%S }
+} 3661
+test clock-29.460 {time parsing} {
+    clock scan {2440588  1:i:i } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%OM:%OS }
+} 3661
+test clock-29.461 {time parsing} {
+    clock scan {2440588 i:01:01 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%M:%S }
+} 3661
+test clock-29.462 {time parsing} {
+    clock scan {2440588 i:i:i } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%OM:%OS }
+} 3661
+test clock-29.463 {time parsing} {
+    clock scan {2440588 i:01:01 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%M:%S }
+} 3661
+test clock-29.464 {time parsing} {
+    clock scan {2440588 i:i:i } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%OM:%OS }
+} 3661
+test clock-29.465 {time parsing} {
+    clock scan {2440588 01:01:01 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M:%S %p}
+} 3661
+test clock-29.466 {time parsing} {
+    clock scan {2440588 01:i:i AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM:%OS %p}
+} 3661
+test clock-29.467 {time parsing} {
+    clock scan {2440588  1:01:01 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M:%S %p}
+} 3661
+test clock-29.468 {time parsing} {
+    clock scan {2440588  1:i:i AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM:%OS %p}
+} 3661
+test clock-29.469 {time parsing} {
+    clock scan {2440588 i:01:01 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M:%S %p}
+} 3661
+test clock-29.470 {time parsing} {
+    clock scan {2440588 i:i:i AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM:%OS %p}
+} 3661
+test clock-29.471 {time parsing} {
+    clock scan {2440588 i:01:01 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M:%S %p}
+} 3661
+test clock-29.472 {time parsing} {
+    clock scan {2440588 i:i:i AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM:%OS %p}
+} 3661
+test clock-29.473 {time parsing} {
+    clock scan {2440588 01:01:01 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M:%S %P}
+} 3661
+test clock-29.474 {time parsing} {
+    clock scan {2440588 01:i:i am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM:%OS %P}
+} 3661
+test clock-29.475 {time parsing} {
+    clock scan {2440588  1:01:01 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M:%S %P}
+} 3661
+test clock-29.476 {time parsing} {
+    clock scan {2440588  1:i:i am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM:%OS %P}
+} 3661
+test clock-29.477 {time parsing} {
+    clock scan {2440588 i:01:01 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M:%S %P}
+} 3661
+test clock-29.478 {time parsing} {
+    clock scan {2440588 i:i:i am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM:%OS %P}
+} 3661
+test clock-29.479 {time parsing} {
+    clock scan {2440588 i:01:01 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M:%S %P}
+} 3661
+test clock-29.480 {time parsing} {
+    clock scan {2440588 i:i:i am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM:%OS %P}
+} 3661
+test clock-29.481 {time parsing} {
+    clock scan {2440588 01:01:59 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%M:%S }
+} 3719
+test clock-29.482 {time parsing} {
+    clock scan {2440588 01:i:lix } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%OM:%OS }
+} 3719
+test clock-29.483 {time parsing} {
+    clock scan {2440588  1:01:59 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%M:%S }
+} 3719
+test clock-29.484 {time parsing} {
+    clock scan {2440588  1:i:lix } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%OM:%OS }
+} 3719
+test clock-29.485 {time parsing} {
+    clock scan {2440588 i:01:59 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%M:%S }
+} 3719
+test clock-29.486 {time parsing} {
+    clock scan {2440588 i:i:lix } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%OM:%OS }
+} 3719
+test clock-29.487 {time parsing} {
+    clock scan {2440588 i:01:59 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%M:%S }
+} 3719
+test clock-29.488 {time parsing} {
+    clock scan {2440588 i:i:lix } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%OM:%OS }
+} 3719
+test clock-29.489 {time parsing} {
+    clock scan {2440588 01:01:59 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M:%S %p}
+} 3719
+test clock-29.490 {time parsing} {
+    clock scan {2440588 01:i:lix AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM:%OS %p}
+} 3719
+test clock-29.491 {time parsing} {
+    clock scan {2440588  1:01:59 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M:%S %p}
+} 3719
+test clock-29.492 {time parsing} {
+    clock scan {2440588  1:i:lix AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM:%OS %p}
+} 3719
+test clock-29.493 {time parsing} {
+    clock scan {2440588 i:01:59 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M:%S %p}
+} 3719
+test clock-29.494 {time parsing} {
+    clock scan {2440588 i:i:lix AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM:%OS %p}
+} 3719
+test clock-29.495 {time parsing} {
+    clock scan {2440588 i:01:59 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M:%S %p}
+} 3719
+test clock-29.496 {time parsing} {
+    clock scan {2440588 i:i:lix AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM:%OS %p}
+} 3719
+test clock-29.497 {time parsing} {
+    clock scan {2440588 01:01:59 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M:%S %P}
+} 3719
+test clock-29.498 {time parsing} {
+    clock scan {2440588 01:i:lix am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM:%OS %P}
+} 3719
+test clock-29.499 {time parsing} {
+    clock scan {2440588  1:01:59 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M:%S %P}
+} 3719
+test clock-29.500 {time parsing} {
+    clock scan {2440588  1:i:lix am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM:%OS %P}
+} 3719
+test clock-29.501 {time parsing} {
+    clock scan {2440588 i:01:59 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M:%S %P}
+} 3719
+test clock-29.502 {time parsing} {
+    clock scan {2440588 i:i:lix am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM:%OS %P}
+} 3719
+test clock-29.503 {time parsing} {
+    clock scan {2440588 i:01:59 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M:%S %P}
+} 3719
+test clock-29.504 {time parsing} {
+    clock scan {2440588 i:i:lix am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM:%OS %P}
+} 3719
+test clock-29.505 {time parsing} {
+    clock scan {2440588 01:59 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%M }
+} 7140
+test clock-29.506 {time parsing} {
+    clock scan {2440588 01:lix } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%OM }
+} 7140
+test clock-29.507 {time parsing} {
+    clock scan {2440588 01:59:00 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%M:%S }
+} 7140
+test clock-29.508 {time parsing} {
+    clock scan {2440588 01:lix:? } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%OM:%OS }
+} 7140
+test clock-29.509 {time parsing} {
+    clock scan {2440588  1:59 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%M }
+} 7140
+test clock-29.510 {time parsing} {
+    clock scan {2440588  1:lix } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%OM }
+} 7140
+test clock-29.511 {time parsing} {
+    clock scan {2440588  1:59:00 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%M:%S }
+} 7140
+test clock-29.512 {time parsing} {
+    clock scan {2440588  1:lix:? } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%OM:%OS }
+} 7140
+test clock-29.513 {time parsing} {
+    clock scan {2440588 i:59 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%M }
+} 7140
+test clock-29.514 {time parsing} {
+    clock scan {2440588 i:lix } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%OM }
+} 7140
+test clock-29.515 {time parsing} {
+    clock scan {2440588 i:59:00 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%M:%S }
+} 7140
+test clock-29.516 {time parsing} {
+    clock scan {2440588 i:lix:? } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%OM:%OS }
+} 7140
+test clock-29.517 {time parsing} {
+    clock scan {2440588 i:59 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%M }
+} 7140
+test clock-29.518 {time parsing} {
+    clock scan {2440588 i:lix } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%OM }
+} 7140
+test clock-29.519 {time parsing} {
+    clock scan {2440588 i:59:00 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%M:%S }
+} 7140
+test clock-29.520 {time parsing} {
+    clock scan {2440588 i:lix:? } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%OM:%OS }
+} 7140
+test clock-29.521 {time parsing} {
+    clock scan {2440588 01:59 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M %p}
+} 7140
+test clock-29.522 {time parsing} {
+    clock scan {2440588 01:lix AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM %p}
+} 7140
+test clock-29.523 {time parsing} {
+    clock scan {2440588 01:59:00 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M:%S %p}
+} 7140
+test clock-29.524 {time parsing} {
+    clock scan {2440588 01:lix:? AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM:%OS %p}
+} 7140
+test clock-29.525 {time parsing} {
+    clock scan {2440588  1:59 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M %p}
+} 7140
+test clock-29.526 {time parsing} {
+    clock scan {2440588  1:lix AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM %p}
+} 7140
+test clock-29.527 {time parsing} {
+    clock scan {2440588  1:59:00 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M:%S %p}
+} 7140
+test clock-29.528 {time parsing} {
+    clock scan {2440588  1:lix:? AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM:%OS %p}
+} 7140
+test clock-29.529 {time parsing} {
+    clock scan {2440588 i:59 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M %p}
+} 7140
+test clock-29.530 {time parsing} {
+    clock scan {2440588 i:lix AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM %p}
+} 7140
+test clock-29.531 {time parsing} {
+    clock scan {2440588 i:59:00 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M:%S %p}
+} 7140
+test clock-29.532 {time parsing} {
+    clock scan {2440588 i:lix:? AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM:%OS %p}
+} 7140
+test clock-29.533 {time parsing} {
+    clock scan {2440588 i:59 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M %p}
+} 7140
+test clock-29.534 {time parsing} {
+    clock scan {2440588 i:lix AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM %p}
+} 7140
+test clock-29.535 {time parsing} {
+    clock scan {2440588 i:59:00 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M:%S %p}
+} 7140
+test clock-29.536 {time parsing} {
+    clock scan {2440588 i:lix:? AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM:%OS %p}
+} 7140
+test clock-29.537 {time parsing} {
+    clock scan {2440588 01:59 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M %P}
+} 7140
+test clock-29.538 {time parsing} {
+    clock scan {2440588 01:lix am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM %P}
+} 7140
+test clock-29.539 {time parsing} {
+    clock scan {2440588 01:59:00 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M:%S %P}
+} 7140
+test clock-29.540 {time parsing} {
+    clock scan {2440588 01:lix:? am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM:%OS %P}
+} 7140
+test clock-29.541 {time parsing} {
+    clock scan {2440588  1:59 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M %P}
+} 7140
+test clock-29.542 {time parsing} {
+    clock scan {2440588  1:lix am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM %P}
+} 7140
+test clock-29.543 {time parsing} {
+    clock scan {2440588  1:59:00 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M:%S %P}
+} 7140
+test clock-29.544 {time parsing} {
+    clock scan {2440588  1:lix:? am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM:%OS %P}
+} 7140
+test clock-29.545 {time parsing} {
+    clock scan {2440588 i:59 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M %P}
+} 7140
+test clock-29.546 {time parsing} {
+    clock scan {2440588 i:lix am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM %P}
+} 7140
+test clock-29.547 {time parsing} {
+    clock scan {2440588 i:59:00 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M:%S %P}
+} 7140
+test clock-29.548 {time parsing} {
+    clock scan {2440588 i:lix:? am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM:%OS %P}
+} 7140
+test clock-29.549 {time parsing} {
+    clock scan {2440588 i:59 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M %P}
+} 7140
+test clock-29.550 {time parsing} {
+    clock scan {2440588 i:lix am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM %P}
+} 7140
+test clock-29.551 {time parsing} {
+    clock scan {2440588 i:59:00 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M:%S %P}
+} 7140
+test clock-29.552 {time parsing} {
+    clock scan {2440588 i:lix:? am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM:%OS %P}
+} 7140
+test clock-29.553 {time parsing} {
+    clock scan {2440588 01:59:01 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%M:%S }
+} 7141
+test clock-29.554 {time parsing} {
+    clock scan {2440588 01:lix:i } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%OM:%OS }
+} 7141
+test clock-29.555 {time parsing} {
+    clock scan {2440588  1:59:01 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%M:%S }
+} 7141
+test clock-29.556 {time parsing} {
+    clock scan {2440588  1:lix:i } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%OM:%OS }
+} 7141
+test clock-29.557 {time parsing} {
+    clock scan {2440588 i:59:01 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%M:%S }
+} 7141
+test clock-29.558 {time parsing} {
+    clock scan {2440588 i:lix:i } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%OM:%OS }
+} 7141
+test clock-29.559 {time parsing} {
+    clock scan {2440588 i:59:01 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%M:%S }
+} 7141
+test clock-29.560 {time parsing} {
+    clock scan {2440588 i:lix:i } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%OM:%OS }
+} 7141
+test clock-29.561 {time parsing} {
+    clock scan {2440588 01:59:01 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M:%S %p}
+} 7141
+test clock-29.562 {time parsing} {
+    clock scan {2440588 01:lix:i AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM:%OS %p}
+} 7141
+test clock-29.563 {time parsing} {
+    clock scan {2440588  1:59:01 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M:%S %p}
+} 7141
+test clock-29.564 {time parsing} {
+    clock scan {2440588  1:lix:i AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM:%OS %p}
+} 7141
+test clock-29.565 {time parsing} {
+    clock scan {2440588 i:59:01 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M:%S %p}
+} 7141
+test clock-29.566 {time parsing} {
+    clock scan {2440588 i:lix:i AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM:%OS %p}
+} 7141
+test clock-29.567 {time parsing} {
+    clock scan {2440588 i:59:01 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M:%S %p}
+} 7141
+test clock-29.568 {time parsing} {
+    clock scan {2440588 i:lix:i AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM:%OS %p}
+} 7141
+test clock-29.569 {time parsing} {
+    clock scan {2440588 01:59:01 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M:%S %P}
+} 7141
+test clock-29.570 {time parsing} {
+    clock scan {2440588 01:lix:i am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM:%OS %P}
+} 7141
+test clock-29.571 {time parsing} {
+    clock scan {2440588  1:59:01 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M:%S %P}
+} 7141
+test clock-29.572 {time parsing} {
+    clock scan {2440588  1:lix:i am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM:%OS %P}
+} 7141
+test clock-29.573 {time parsing} {
+    clock scan {2440588 i:59:01 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M:%S %P}
+} 7141
+test clock-29.574 {time parsing} {
+    clock scan {2440588 i:lix:i am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM:%OS %P}
+} 7141
+test clock-29.575 {time parsing} {
+    clock scan {2440588 i:59:01 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M:%S %P}
+} 7141
+test clock-29.576 {time parsing} {
+    clock scan {2440588 i:lix:i am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM:%OS %P}
+} 7141
+test clock-29.577 {time parsing} {
+    clock scan {2440588 01:59:59 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%M:%S }
+} 7199
+test clock-29.578 {time parsing} {
+    clock scan {2440588 01:lix:lix } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%OM:%OS }
+} 7199
+test clock-29.579 {time parsing} {
+    clock scan {2440588  1:59:59 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%M:%S }
+} 7199
+test clock-29.580 {time parsing} {
+    clock scan {2440588  1:lix:lix } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%OM:%OS }
+} 7199
+test clock-29.581 {time parsing} {
+    clock scan {2440588 i:59:59 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%M:%S }
+} 7199
+test clock-29.582 {time parsing} {
+    clock scan {2440588 i:lix:lix } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%OM:%OS }
+} 7199
+test clock-29.583 {time parsing} {
+    clock scan {2440588 i:59:59 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%M:%S }
+} 7199
+test clock-29.584 {time parsing} {
+    clock scan {2440588 i:lix:lix } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%OM:%OS }
+} 7199
+test clock-29.585 {time parsing} {
+    clock scan {2440588 01:59:59 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M:%S %p}
+} 7199
+test clock-29.586 {time parsing} {
+    clock scan {2440588 01:lix:lix AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM:%OS %p}
+} 7199
+test clock-29.587 {time parsing} {
+    clock scan {2440588  1:59:59 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M:%S %p}
+} 7199
+test clock-29.588 {time parsing} {
+    clock scan {2440588  1:lix:lix AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM:%OS %p}
+} 7199
+test clock-29.589 {time parsing} {
+    clock scan {2440588 i:59:59 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M:%S %p}
+} 7199
+test clock-29.590 {time parsing} {
+    clock scan {2440588 i:lix:lix AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM:%OS %p}
+} 7199
+test clock-29.591 {time parsing} {
+    clock scan {2440588 i:59:59 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M:%S %p}
+} 7199
+test clock-29.592 {time parsing} {
+    clock scan {2440588 i:lix:lix AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM:%OS %p}
+} 7199
+test clock-29.593 {time parsing} {
+    clock scan {2440588 01:59:59 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M:%S %P}
+} 7199
+test clock-29.594 {time parsing} {
+    clock scan {2440588 01:lix:lix am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM:%OS %P}
+} 7199
+test clock-29.595 {time parsing} {
+    clock scan {2440588  1:59:59 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M:%S %P}
+} 7199
+test clock-29.596 {time parsing} {
+    clock scan {2440588  1:lix:lix am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM:%OS %P}
+} 7199
+test clock-29.597 {time parsing} {
+    clock scan {2440588 i:59:59 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M:%S %P}
+} 7199
+test clock-29.598 {time parsing} {
+    clock scan {2440588 i:lix:lix am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM:%OS %P}
+} 7199
+test clock-29.599 {time parsing} {
+    clock scan {2440588 i:59:59 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M:%S %P}
+} 7199
+test clock-29.600 {time parsing} {
+    clock scan {2440588 i:lix:lix am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM:%OS %P}
+} 7199
+test clock-29.601 {time parsing} {
+    clock scan {2440588 11 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H }
+} 39600
+test clock-29.602 {time parsing} {
+    clock scan {2440588 11:00 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%M }
+} 39600
+test clock-29.603 {time parsing} {
+    clock scan {2440588 11:? } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%OM }
+} 39600
+test clock-29.604 {time parsing} {
+    clock scan {2440588 11:00:00 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%M:%S }
+} 39600
+test clock-29.605 {time parsing} {
+    clock scan {2440588 11:?:? } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%OM:%OS }
+} 39600
+test clock-29.606 {time parsing} {
+    clock scan {2440588 11 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k }
+} 39600
+test clock-29.607 {time parsing} {
+    clock scan {2440588 11:00 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%M }
+} 39600
+test clock-29.608 {time parsing} {
+    clock scan {2440588 11:? } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%OM }
+} 39600
+test clock-29.609 {time parsing} {
+    clock scan {2440588 11:00:00 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%M:%S }
+} 39600
+test clock-29.610 {time parsing} {
+    clock scan {2440588 11:?:? } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%OM:%OS }
+} 39600
+test clock-29.611 {time parsing} {
+    clock scan {2440588 xi } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH }
+} 39600
+test clock-29.612 {time parsing} {
+    clock scan {2440588 xi:00 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%M }
+} 39600
+test clock-29.613 {time parsing} {
+    clock scan {2440588 xi:? } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%OM }
+} 39600
+test clock-29.614 {time parsing} {
+    clock scan {2440588 xi:00:00 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%M:%S }
+} 39600
+test clock-29.615 {time parsing} {
+    clock scan {2440588 xi:?:? } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%OM:%OS }
+} 39600
+test clock-29.616 {time parsing} {
+    clock scan {2440588 xi } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok }
+} 39600
+test clock-29.617 {time parsing} {
+    clock scan {2440588 xi:00 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%M }
+} 39600
+test clock-29.618 {time parsing} {
+    clock scan {2440588 xi:? } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%OM }
+} 39600
+test clock-29.619 {time parsing} {
+    clock scan {2440588 xi:00:00 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%M:%S }
+} 39600
+test clock-29.620 {time parsing} {
+    clock scan {2440588 xi:?:? } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%OM:%OS }
+} 39600
+test clock-29.621 {time parsing} {
+    clock scan {2440588 11 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I %p}
+} 39600
+test clock-29.622 {time parsing} {
+    clock scan {2440588 11:00 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M %p}
+} 39600
+test clock-29.623 {time parsing} {
+    clock scan {2440588 11:? AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM %p}
+} 39600
+test clock-29.624 {time parsing} {
+    clock scan {2440588 11:00:00 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M:%S %p}
+} 39600
+test clock-29.625 {time parsing} {
+    clock scan {2440588 11:?:? AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM:%OS %p}
+} 39600
+test clock-29.626 {time parsing} {
+    clock scan {2440588 11 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l %p}
+} 39600
+test clock-29.627 {time parsing} {
+    clock scan {2440588 11:00 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M %p}
+} 39600
+test clock-29.628 {time parsing} {
+    clock scan {2440588 11:? AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM %p}
+} 39600
+test clock-29.629 {time parsing} {
+    clock scan {2440588 11:00:00 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M:%S %p}
+} 39600
+test clock-29.630 {time parsing} {
+    clock scan {2440588 11:?:? AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM:%OS %p}
+} 39600
+test clock-29.631 {time parsing} {
+    clock scan {2440588 xi AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI %p}
+} 39600
+test clock-29.632 {time parsing} {
+    clock scan {2440588 xi:00 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M %p}
+} 39600
+test clock-29.633 {time parsing} {
+    clock scan {2440588 xi:? AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM %p}
+} 39600
+test clock-29.634 {time parsing} {
+    clock scan {2440588 xi:00:00 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M:%S %p}
+} 39600
+test clock-29.635 {time parsing} {
+    clock scan {2440588 xi:?:? AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM:%OS %p}
+} 39600
+test clock-29.636 {time parsing} {
+    clock scan {2440588 xi AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol %p}
+} 39600
+test clock-29.637 {time parsing} {
+    clock scan {2440588 xi:00 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M %p}
+} 39600
+test clock-29.638 {time parsing} {
+    clock scan {2440588 xi:? AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM %p}
+} 39600
+test clock-29.639 {time parsing} {
+    clock scan {2440588 xi:00:00 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M:%S %p}
+} 39600
+test clock-29.640 {time parsing} {
+    clock scan {2440588 xi:?:? AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM:%OS %p}
+} 39600
+test clock-29.641 {time parsing} {
+    clock scan {2440588 11 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I %P}
+} 39600
+test clock-29.642 {time parsing} {
+    clock scan {2440588 11:00 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M %P}
+} 39600
+test clock-29.643 {time parsing} {
+    clock scan {2440588 11:? am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM %P}
+} 39600
+test clock-29.644 {time parsing} {
+    clock scan {2440588 11:00:00 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M:%S %P}
+} 39600
+test clock-29.645 {time parsing} {
+    clock scan {2440588 11:?:? am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM:%OS %P}
+} 39600
+test clock-29.646 {time parsing} {
+    clock scan {2440588 11 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l %P}
+} 39600
+test clock-29.647 {time parsing} {
+    clock scan {2440588 11:00 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M %P}
+} 39600
+test clock-29.648 {time parsing} {
+    clock scan {2440588 11:? am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM %P}
+} 39600
+test clock-29.649 {time parsing} {
+    clock scan {2440588 11:00:00 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M:%S %P}
+} 39600
+test clock-29.650 {time parsing} {
+    clock scan {2440588 11:?:? am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM:%OS %P}
+} 39600
+test clock-29.651 {time parsing} {
+    clock scan {2440588 xi am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI %P}
+} 39600
+test clock-29.652 {time parsing} {
+    clock scan {2440588 xi:00 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M %P}
+} 39600
+test clock-29.653 {time parsing} {
+    clock scan {2440588 xi:? am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM %P}
+} 39600
+test clock-29.654 {time parsing} {
+    clock scan {2440588 xi:00:00 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M:%S %P}
+} 39600
+test clock-29.655 {time parsing} {
+    clock scan {2440588 xi:?:? am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM:%OS %P}
+} 39600
+test clock-29.656 {time parsing} {
+    clock scan {2440588 xi am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol %P}
+} 39600
+test clock-29.657 {time parsing} {
+    clock scan {2440588 xi:00 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M %P}
+} 39600
+test clock-29.658 {time parsing} {
+    clock scan {2440588 xi:? am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM %P}
+} 39600
+test clock-29.659 {time parsing} {
+    clock scan {2440588 xi:00:00 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M:%S %P}
+} 39600
+test clock-29.660 {time parsing} {
+    clock scan {2440588 xi:?:? am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM:%OS %P}
+} 39600
+test clock-29.661 {time parsing} {
+    clock scan {2440588 11:00:01 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%M:%S }
+} 39601
+test clock-29.662 {time parsing} {
+    clock scan {2440588 11:?:i } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%OM:%OS }
+} 39601
+test clock-29.663 {time parsing} {
+    clock scan {2440588 11:00:01 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%M:%S }
+} 39601
+test clock-29.664 {time parsing} {
+    clock scan {2440588 11:?:i } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%OM:%OS }
+} 39601
+test clock-29.665 {time parsing} {
+    clock scan {2440588 xi:00:01 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%M:%S }
+} 39601
+test clock-29.666 {time parsing} {
+    clock scan {2440588 xi:?:i } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%OM:%OS }
+} 39601
+test clock-29.667 {time parsing} {
+    clock scan {2440588 xi:00:01 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%M:%S }
+} 39601
+test clock-29.668 {time parsing} {
+    clock scan {2440588 xi:?:i } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%OM:%OS }
+} 39601
+test clock-29.669 {time parsing} {
+    clock scan {2440588 11:00:01 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M:%S %p}
+} 39601
+test clock-29.670 {time parsing} {
+    clock scan {2440588 11:?:i AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM:%OS %p}
+} 39601
+test clock-29.671 {time parsing} {
+    clock scan {2440588 11:00:01 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M:%S %p}
+} 39601
+test clock-29.672 {time parsing} {
+    clock scan {2440588 11:?:i AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM:%OS %p}
+} 39601
+test clock-29.673 {time parsing} {
+    clock scan {2440588 xi:00:01 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M:%S %p}
+} 39601
+test clock-29.674 {time parsing} {
+    clock scan {2440588 xi:?:i AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM:%OS %p}
+} 39601
+test clock-29.675 {time parsing} {
+    clock scan {2440588 xi:00:01 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M:%S %p}
+} 39601
+test clock-29.676 {time parsing} {
+    clock scan {2440588 xi:?:i AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM:%OS %p}
+} 39601
+test clock-29.677 {time parsing} {
+    clock scan {2440588 11:00:01 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M:%S %P}
+} 39601
+test clock-29.678 {time parsing} {
+    clock scan {2440588 11:?:i am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM:%OS %P}
+} 39601
+test clock-29.679 {time parsing} {
+    clock scan {2440588 11:00:01 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M:%S %P}
+} 39601
+test clock-29.680 {time parsing} {
+    clock scan {2440588 11:?:i am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM:%OS %P}
+} 39601
+test clock-29.681 {time parsing} {
+    clock scan {2440588 xi:00:01 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M:%S %P}
+} 39601
+test clock-29.682 {time parsing} {
+    clock scan {2440588 xi:?:i am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM:%OS %P}
+} 39601
+test clock-29.683 {time parsing} {
+    clock scan {2440588 xi:00:01 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M:%S %P}
+} 39601
+test clock-29.684 {time parsing} {
+    clock scan {2440588 xi:?:i am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM:%OS %P}
+} 39601
+test clock-29.685 {time parsing} {
+    clock scan {2440588 11:00:59 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%M:%S }
+} 39659
+test clock-29.686 {time parsing} {
+    clock scan {2440588 11:?:lix } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%OM:%OS }
+} 39659
+test clock-29.687 {time parsing} {
+    clock scan {2440588 11:00:59 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%M:%S }
+} 39659
+test clock-29.688 {time parsing} {
+    clock scan {2440588 11:?:lix } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%OM:%OS }
+} 39659
+test clock-29.689 {time parsing} {
+    clock scan {2440588 xi:00:59 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%M:%S }
+} 39659
+test clock-29.690 {time parsing} {
+    clock scan {2440588 xi:?:lix } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%OM:%OS }
+} 39659
+test clock-29.691 {time parsing} {
+    clock scan {2440588 xi:00:59 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%M:%S }
+} 39659
+test clock-29.692 {time parsing} {
+    clock scan {2440588 xi:?:lix } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%OM:%OS }
+} 39659
+test clock-29.693 {time parsing} {
+    clock scan {2440588 11:00:59 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M:%S %p}
+} 39659
+test clock-29.694 {time parsing} {
+    clock scan {2440588 11:?:lix AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM:%OS %p}
+} 39659
+test clock-29.695 {time parsing} {
+    clock scan {2440588 11:00:59 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M:%S %p}
+} 39659
+test clock-29.696 {time parsing} {
+    clock scan {2440588 11:?:lix AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM:%OS %p}
+} 39659
+test clock-29.697 {time parsing} {
+    clock scan {2440588 xi:00:59 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M:%S %p}
+} 39659
+test clock-29.698 {time parsing} {
+    clock scan {2440588 xi:?:lix AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM:%OS %p}
+} 39659
+test clock-29.699 {time parsing} {
+    clock scan {2440588 xi:00:59 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M:%S %p}
+} 39659
+test clock-29.700 {time parsing} {
+    clock scan {2440588 xi:?:lix AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM:%OS %p}
+} 39659
+test clock-29.701 {time parsing} {
+    clock scan {2440588 11:00:59 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M:%S %P}
+} 39659
+test clock-29.702 {time parsing} {
+    clock scan {2440588 11:?:lix am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM:%OS %P}
+} 39659
+test clock-29.703 {time parsing} {
+    clock scan {2440588 11:00:59 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M:%S %P}
+} 39659
+test clock-29.704 {time parsing} {
+    clock scan {2440588 11:?:lix am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM:%OS %P}
+} 39659
+test clock-29.705 {time parsing} {
+    clock scan {2440588 xi:00:59 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M:%S %P}
+} 39659
+test clock-29.706 {time parsing} {
+    clock scan {2440588 xi:?:lix am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM:%OS %P}
+} 39659
+test clock-29.707 {time parsing} {
+    clock scan {2440588 xi:00:59 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M:%S %P}
+} 39659
+test clock-29.708 {time parsing} {
+    clock scan {2440588 xi:?:lix am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM:%OS %P}
+} 39659
+test clock-29.709 {time parsing} {
+    clock scan {2440588 11:01 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%M }
+} 39660
+test clock-29.710 {time parsing} {
+    clock scan {2440588 11:i } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%OM }
+} 39660
+test clock-29.711 {time parsing} {
+    clock scan {2440588 11:01:00 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%M:%S }
+} 39660
+test clock-29.712 {time parsing} {
+    clock scan {2440588 11:i:? } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%OM:%OS }
+} 39660
+test clock-29.713 {time parsing} {
+    clock scan {2440588 11:01 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%M }
+} 39660
+test clock-29.714 {time parsing} {
+    clock scan {2440588 11:i } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%OM }
+} 39660
+test clock-29.715 {time parsing} {
+    clock scan {2440588 11:01:00 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%M:%S }
+} 39660
+test clock-29.716 {time parsing} {
+    clock scan {2440588 11:i:? } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%OM:%OS }
+} 39660
+test clock-29.717 {time parsing} {
+    clock scan {2440588 xi:01 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%M }
+} 39660
+test clock-29.718 {time parsing} {
+    clock scan {2440588 xi:i } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%OM }
+} 39660
+test clock-29.719 {time parsing} {
+    clock scan {2440588 xi:01:00 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%M:%S }
+} 39660
+test clock-29.720 {time parsing} {
+    clock scan {2440588 xi:i:? } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%OM:%OS }
+} 39660
+test clock-29.721 {time parsing} {
+    clock scan {2440588 xi:01 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%M }
+} 39660
+test clock-29.722 {time parsing} {
+    clock scan {2440588 xi:i } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%OM }
+} 39660
+test clock-29.723 {time parsing} {
+    clock scan {2440588 xi:01:00 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%M:%S }
+} 39660
+test clock-29.724 {time parsing} {
+    clock scan {2440588 xi:i:? } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%OM:%OS }
+} 39660
+test clock-29.725 {time parsing} {
+    clock scan {2440588 11:01 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M %p}
+} 39660
+test clock-29.726 {time parsing} {
+    clock scan {2440588 11:i AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM %p}
+} 39660
+test clock-29.727 {time parsing} {
+    clock scan {2440588 11:01:00 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M:%S %p}
+} 39660
+test clock-29.728 {time parsing} {
+    clock scan {2440588 11:i:? AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM:%OS %p}
+} 39660
+test clock-29.729 {time parsing} {
+    clock scan {2440588 11:01 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M %p}
+} 39660
+test clock-29.730 {time parsing} {
+    clock scan {2440588 11:i AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM %p}
+} 39660
+test clock-29.731 {time parsing} {
+    clock scan {2440588 11:01:00 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M:%S %p}
+} 39660
+test clock-29.732 {time parsing} {
+    clock scan {2440588 11:i:? AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM:%OS %p}
+} 39660
+test clock-29.733 {time parsing} {
+    clock scan {2440588 xi:01 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M %p}
+} 39660
+test clock-29.734 {time parsing} {
+    clock scan {2440588 xi:i AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM %p}
+} 39660
+test clock-29.735 {time parsing} {
+    clock scan {2440588 xi:01:00 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M:%S %p}
+} 39660
+test clock-29.736 {time parsing} {
+    clock scan {2440588 xi:i:? AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM:%OS %p}
+} 39660
+test clock-29.737 {time parsing} {
+    clock scan {2440588 xi:01 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M %p}
+} 39660
+test clock-29.738 {time parsing} {
+    clock scan {2440588 xi:i AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM %p}
+} 39660
+test clock-29.739 {time parsing} {
+    clock scan {2440588 xi:01:00 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M:%S %p}
+} 39660
+test clock-29.740 {time parsing} {
+    clock scan {2440588 xi:i:? AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM:%OS %p}
+} 39660
+test clock-29.741 {time parsing} {
+    clock scan {2440588 11:01 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M %P}
+} 39660
+test clock-29.742 {time parsing} {
+    clock scan {2440588 11:i am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM %P}
+} 39660
+test clock-29.743 {time parsing} {
+    clock scan {2440588 11:01:00 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M:%S %P}
+} 39660
+test clock-29.744 {time parsing} {
+    clock scan {2440588 11:i:? am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM:%OS %P}
+} 39660
+test clock-29.745 {time parsing} {
+    clock scan {2440588 11:01 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M %P}
+} 39660
+test clock-29.746 {time parsing} {
+    clock scan {2440588 11:i am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM %P}
+} 39660
+test clock-29.747 {time parsing} {
+    clock scan {2440588 11:01:00 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M:%S %P}
+} 39660
+test clock-29.748 {time parsing} {
+    clock scan {2440588 11:i:? am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM:%OS %P}
+} 39660
+test clock-29.749 {time parsing} {
+    clock scan {2440588 xi:01 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M %P}
+} 39660
+test clock-29.750 {time parsing} {
+    clock scan {2440588 xi:i am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM %P}
+} 39660
+test clock-29.751 {time parsing} {
+    clock scan {2440588 xi:01:00 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M:%S %P}
+} 39660
+test clock-29.752 {time parsing} {
+    clock scan {2440588 xi:i:? am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM:%OS %P}
+} 39660
+test clock-29.753 {time parsing} {
+    clock scan {2440588 xi:01 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M %P}
+} 39660
+test clock-29.754 {time parsing} {
+    clock scan {2440588 xi:i am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM %P}
+} 39660
+test clock-29.755 {time parsing} {
+    clock scan {2440588 xi:01:00 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M:%S %P}
+} 39660
+test clock-29.756 {time parsing} {
+    clock scan {2440588 xi:i:? am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM:%OS %P}
+} 39660
+test clock-29.757 {time parsing} {
+    clock scan {2440588 11:01:01 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%M:%S }
+} 39661
+test clock-29.758 {time parsing} {
+    clock scan {2440588 11:i:i } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%OM:%OS }
+} 39661
+test clock-29.759 {time parsing} {
+    clock scan {2440588 11:01:01 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%M:%S }
+} 39661
+test clock-29.760 {time parsing} {
+    clock scan {2440588 11:i:i } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%OM:%OS }
+} 39661
+test clock-29.761 {time parsing} {
+    clock scan {2440588 xi:01:01 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%M:%S }
+} 39661
+test clock-29.762 {time parsing} {
+    clock scan {2440588 xi:i:i } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%OM:%OS }
+} 39661
+test clock-29.763 {time parsing} {
+    clock scan {2440588 xi:01:01 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%M:%S }
+} 39661
+test clock-29.764 {time parsing} {
+    clock scan {2440588 xi:i:i } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%OM:%OS }
+} 39661
+test clock-29.765 {time parsing} {
+    clock scan {2440588 11:01:01 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M:%S %p}
+} 39661
+test clock-29.766 {time parsing} {
+    clock scan {2440588 11:i:i AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM:%OS %p}
+} 39661
+test clock-29.767 {time parsing} {
+    clock scan {2440588 11:01:01 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M:%S %p}
+} 39661
+test clock-29.768 {time parsing} {
+    clock scan {2440588 11:i:i AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM:%OS %p}
+} 39661
+test clock-29.769 {time parsing} {
+    clock scan {2440588 xi:01:01 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M:%S %p}
+} 39661
+test clock-29.770 {time parsing} {
+    clock scan {2440588 xi:i:i AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM:%OS %p}
+} 39661
+test clock-29.771 {time parsing} {
+    clock scan {2440588 xi:01:01 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M:%S %p}
+} 39661
+test clock-29.772 {time parsing} {
+    clock scan {2440588 xi:i:i AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM:%OS %p}
+} 39661
+test clock-29.773 {time parsing} {
+    clock scan {2440588 11:01:01 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M:%S %P}
+} 39661
+test clock-29.774 {time parsing} {
+    clock scan {2440588 11:i:i am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM:%OS %P}
+} 39661
+test clock-29.775 {time parsing} {
+    clock scan {2440588 11:01:01 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M:%S %P}
+} 39661
+test clock-29.776 {time parsing} {
+    clock scan {2440588 11:i:i am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM:%OS %P}
+} 39661
+test clock-29.777 {time parsing} {
+    clock scan {2440588 xi:01:01 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M:%S %P}
+} 39661
+test clock-29.778 {time parsing} {
+    clock scan {2440588 xi:i:i am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM:%OS %P}
+} 39661
+test clock-29.779 {time parsing} {
+    clock scan {2440588 xi:01:01 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M:%S %P}
+} 39661
+test clock-29.780 {time parsing} {
+    clock scan {2440588 xi:i:i am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM:%OS %P}
+} 39661
+test clock-29.781 {time parsing} {
+    clock scan {2440588 11:01:59 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%M:%S }
+} 39719
+test clock-29.782 {time parsing} {
+    clock scan {2440588 11:i:lix } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%OM:%OS }
+} 39719
+test clock-29.783 {time parsing} {
+    clock scan {2440588 11:01:59 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%M:%S }
+} 39719
+test clock-29.784 {time parsing} {
+    clock scan {2440588 11:i:lix } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%OM:%OS }
+} 39719
+test clock-29.785 {time parsing} {
+    clock scan {2440588 xi:01:59 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%M:%S }
+} 39719
+test clock-29.786 {time parsing} {
+    clock scan {2440588 xi:i:lix } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%OM:%OS }
+} 39719
+test clock-29.787 {time parsing} {
+    clock scan {2440588 xi:01:59 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%M:%S }
+} 39719
+test clock-29.788 {time parsing} {
+    clock scan {2440588 xi:i:lix } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%OM:%OS }
+} 39719
+test clock-29.789 {time parsing} {
+    clock scan {2440588 11:01:59 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M:%S %p}
+} 39719
+test clock-29.790 {time parsing} {
+    clock scan {2440588 11:i:lix AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM:%OS %p}
+} 39719
+test clock-29.791 {time parsing} {
+    clock scan {2440588 11:01:59 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M:%S %p}
+} 39719
+test clock-29.792 {time parsing} {
+    clock scan {2440588 11:i:lix AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM:%OS %p}
+} 39719
+test clock-29.793 {time parsing} {
+    clock scan {2440588 xi:01:59 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M:%S %p}
+} 39719
+test clock-29.794 {time parsing} {
+    clock scan {2440588 xi:i:lix AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM:%OS %p}
+} 39719
+test clock-29.795 {time parsing} {
+    clock scan {2440588 xi:01:59 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M:%S %p}
+} 39719
+test clock-29.796 {time parsing} {
+    clock scan {2440588 xi:i:lix AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM:%OS %p}
+} 39719
+test clock-29.797 {time parsing} {
+    clock scan {2440588 11:01:59 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M:%S %P}
+} 39719
+test clock-29.798 {time parsing} {
+    clock scan {2440588 11:i:lix am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM:%OS %P}
+} 39719
+test clock-29.799 {time parsing} {
+    clock scan {2440588 11:01:59 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M:%S %P}
+} 39719
+test clock-29.800 {time parsing} {
+    clock scan {2440588 11:i:lix am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM:%OS %P}
+} 39719
+test clock-29.801 {time parsing} {
+    clock scan {2440588 xi:01:59 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M:%S %P}
+} 39719
+test clock-29.802 {time parsing} {
+    clock scan {2440588 xi:i:lix am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM:%OS %P}
+} 39719
+test clock-29.803 {time parsing} {
+    clock scan {2440588 xi:01:59 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M:%S %P}
+} 39719
+test clock-29.804 {time parsing} {
+    clock scan {2440588 xi:i:lix am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM:%OS %P}
+} 39719
+test clock-29.805 {time parsing} {
+    clock scan {2440588 11:59 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%M }
+} 43140
+test clock-29.806 {time parsing} {
+    clock scan {2440588 11:lix } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%OM }
+} 43140
+test clock-29.807 {time parsing} {
+    clock scan {2440588 11:59:00 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%M:%S }
+} 43140
+test clock-29.808 {time parsing} {
+    clock scan {2440588 11:lix:? } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%OM:%OS }
+} 43140
+test clock-29.809 {time parsing} {
+    clock scan {2440588 11:59 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%M }
+} 43140
+test clock-29.810 {time parsing} {
+    clock scan {2440588 11:lix } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%OM }
+} 43140
+test clock-29.811 {time parsing} {
+    clock scan {2440588 11:59:00 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%M:%S }
+} 43140
+test clock-29.812 {time parsing} {
+    clock scan {2440588 11:lix:? } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%OM:%OS }
+} 43140
+test clock-29.813 {time parsing} {
+    clock scan {2440588 xi:59 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%M }
+} 43140
+test clock-29.814 {time parsing} {
+    clock scan {2440588 xi:lix } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%OM }
+} 43140
+test clock-29.815 {time parsing} {
+    clock scan {2440588 xi:59:00 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%M:%S }
+} 43140
+test clock-29.816 {time parsing} {
+    clock scan {2440588 xi:lix:? } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%OM:%OS }
+} 43140
+test clock-29.817 {time parsing} {
+    clock scan {2440588 xi:59 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%M }
+} 43140
+test clock-29.818 {time parsing} {
+    clock scan {2440588 xi:lix } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%OM }
+} 43140
+test clock-29.819 {time parsing} {
+    clock scan {2440588 xi:59:00 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%M:%S }
+} 43140
+test clock-29.820 {time parsing} {
+    clock scan {2440588 xi:lix:? } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%OM:%OS }
+} 43140
+test clock-29.821 {time parsing} {
+    clock scan {2440588 11:59 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M %p}
+} 43140
+test clock-29.822 {time parsing} {
+    clock scan {2440588 11:lix AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM %p}
+} 43140
+test clock-29.823 {time parsing} {
+    clock scan {2440588 11:59:00 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M:%S %p}
+} 43140
+test clock-29.824 {time parsing} {
+    clock scan {2440588 11:lix:? AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM:%OS %p}
+} 43140
+test clock-29.825 {time parsing} {
+    clock scan {2440588 11:59 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M %p}
+} 43140
+test clock-29.826 {time parsing} {
+    clock scan {2440588 11:lix AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM %p}
+} 43140
+test clock-29.827 {time parsing} {
+    clock scan {2440588 11:59:00 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M:%S %p}
+} 43140
+test clock-29.828 {time parsing} {
+    clock scan {2440588 11:lix:? AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM:%OS %p}
+} 43140
+test clock-29.829 {time parsing} {
+    clock scan {2440588 xi:59 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M %p}
+} 43140
+test clock-29.830 {time parsing} {
+    clock scan {2440588 xi:lix AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM %p}
+} 43140
+test clock-29.831 {time parsing} {
+    clock scan {2440588 xi:59:00 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M:%S %p}
+} 43140
+test clock-29.832 {time parsing} {
+    clock scan {2440588 xi:lix:? AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM:%OS %p}
+} 43140
+test clock-29.833 {time parsing} {
+    clock scan {2440588 xi:59 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M %p}
+} 43140
+test clock-29.834 {time parsing} {
+    clock scan {2440588 xi:lix AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM %p}
+} 43140
+test clock-29.835 {time parsing} {
+    clock scan {2440588 xi:59:00 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M:%S %p}
+} 43140
+test clock-29.836 {time parsing} {
+    clock scan {2440588 xi:lix:? AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM:%OS %p}
+} 43140
+test clock-29.837 {time parsing} {
+    clock scan {2440588 11:59 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M %P}
+} 43140
+test clock-29.838 {time parsing} {
+    clock scan {2440588 11:lix am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM %P}
+} 43140
+test clock-29.839 {time parsing} {
+    clock scan {2440588 11:59:00 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M:%S %P}
+} 43140
+test clock-29.840 {time parsing} {
+    clock scan {2440588 11:lix:? am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM:%OS %P}
+} 43140
+test clock-29.841 {time parsing} {
+    clock scan {2440588 11:59 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M %P}
+} 43140
+test clock-29.842 {time parsing} {
+    clock scan {2440588 11:lix am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM %P}
+} 43140
+test clock-29.843 {time parsing} {
+    clock scan {2440588 11:59:00 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M:%S %P}
+} 43140
+test clock-29.844 {time parsing} {
+    clock scan {2440588 11:lix:? am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM:%OS %P}
+} 43140
+test clock-29.845 {time parsing} {
+    clock scan {2440588 xi:59 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M %P}
+} 43140
+test clock-29.846 {time parsing} {
+    clock scan {2440588 xi:lix am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM %P}
+} 43140
+test clock-29.847 {time parsing} {
+    clock scan {2440588 xi:59:00 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M:%S %P}
+} 43140
+test clock-29.848 {time parsing} {
+    clock scan {2440588 xi:lix:? am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM:%OS %P}
+} 43140
+test clock-29.849 {time parsing} {
+    clock scan {2440588 xi:59 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M %P}
+} 43140
+test clock-29.850 {time parsing} {
+    clock scan {2440588 xi:lix am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM %P}
+} 43140
+test clock-29.851 {time parsing} {
+    clock scan {2440588 xi:59:00 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M:%S %P}
+} 43140
+test clock-29.852 {time parsing} {
+    clock scan {2440588 xi:lix:? am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM:%OS %P}
+} 43140
+test clock-29.853 {time parsing} {
+    clock scan {2440588 11:59:01 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%M:%S }
+} 43141
+test clock-29.854 {time parsing} {
+    clock scan {2440588 11:lix:i } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%OM:%OS }
+} 43141
+test clock-29.855 {time parsing} {
+    clock scan {2440588 11:59:01 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%M:%S }
+} 43141
+test clock-29.856 {time parsing} {
+    clock scan {2440588 11:lix:i } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%OM:%OS }
+} 43141
+test clock-29.857 {time parsing} {
+    clock scan {2440588 xi:59:01 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%M:%S }
+} 43141
+test clock-29.858 {time parsing} {
+    clock scan {2440588 xi:lix:i } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%OM:%OS }
+} 43141
+test clock-29.859 {time parsing} {
+    clock scan {2440588 xi:59:01 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%M:%S }
+} 43141
+test clock-29.860 {time parsing} {
+    clock scan {2440588 xi:lix:i } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%OM:%OS }
+} 43141
+test clock-29.861 {time parsing} {
+    clock scan {2440588 11:59:01 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M:%S %p}
+} 43141
+test clock-29.862 {time parsing} {
+    clock scan {2440588 11:lix:i AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM:%OS %p}
+} 43141
+test clock-29.863 {time parsing} {
+    clock scan {2440588 11:59:01 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M:%S %p}
+} 43141
+test clock-29.864 {time parsing} {
+    clock scan {2440588 11:lix:i AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM:%OS %p}
+} 43141
+test clock-29.865 {time parsing} {
+    clock scan {2440588 xi:59:01 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M:%S %p}
+} 43141
+test clock-29.866 {time parsing} {
+    clock scan {2440588 xi:lix:i AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM:%OS %p}
+} 43141
+test clock-29.867 {time parsing} {
+    clock scan {2440588 xi:59:01 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M:%S %p}
+} 43141
+test clock-29.868 {time parsing} {
+    clock scan {2440588 xi:lix:i AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM:%OS %p}
+} 43141
+test clock-29.869 {time parsing} {
+    clock scan {2440588 11:59:01 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M:%S %P}
+} 43141
+test clock-29.870 {time parsing} {
+    clock scan {2440588 11:lix:i am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM:%OS %P}
+} 43141
+test clock-29.871 {time parsing} {
+    clock scan {2440588 11:59:01 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M:%S %P}
+} 43141
+test clock-29.872 {time parsing} {
+    clock scan {2440588 11:lix:i am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM:%OS %P}
+} 43141
+test clock-29.873 {time parsing} {
+    clock scan {2440588 xi:59:01 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M:%S %P}
+} 43141
+test clock-29.874 {time parsing} {
+    clock scan {2440588 xi:lix:i am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM:%OS %P}
+} 43141
+test clock-29.875 {time parsing} {
+    clock scan {2440588 xi:59:01 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M:%S %P}
+} 43141
+test clock-29.876 {time parsing} {
+    clock scan {2440588 xi:lix:i am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM:%OS %P}
+} 43141
+test clock-29.877 {time parsing} {
+    clock scan {2440588 11:59:59 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%M:%S }
+} 43199
+test clock-29.878 {time parsing} {
+    clock scan {2440588 11:lix:lix } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%OM:%OS }
+} 43199
+test clock-29.879 {time parsing} {
+    clock scan {2440588 11:59:59 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%M:%S }
+} 43199
+test clock-29.880 {time parsing} {
+    clock scan {2440588 11:lix:lix } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%OM:%OS }
+} 43199
+test clock-29.881 {time parsing} {
+    clock scan {2440588 xi:59:59 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%M:%S }
+} 43199
+test clock-29.882 {time parsing} {
+    clock scan {2440588 xi:lix:lix } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%OM:%OS }
+} 43199
+test clock-29.883 {time parsing} {
+    clock scan {2440588 xi:59:59 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%M:%S }
+} 43199
+test clock-29.884 {time parsing} {
+    clock scan {2440588 xi:lix:lix } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%OM:%OS }
+} 43199
+test clock-29.885 {time parsing} {
+    clock scan {2440588 11:59:59 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M:%S %p}
+} 43199
+test clock-29.886 {time parsing} {
+    clock scan {2440588 11:lix:lix AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM:%OS %p}
+} 43199
+test clock-29.887 {time parsing} {
+    clock scan {2440588 11:59:59 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M:%S %p}
+} 43199
+test clock-29.888 {time parsing} {
+    clock scan {2440588 11:lix:lix AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM:%OS %p}
+} 43199
+test clock-29.889 {time parsing} {
+    clock scan {2440588 xi:59:59 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M:%S %p}
+} 43199
+test clock-29.890 {time parsing} {
+    clock scan {2440588 xi:lix:lix AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM:%OS %p}
+} 43199
+test clock-29.891 {time parsing} {
+    clock scan {2440588 xi:59:59 AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M:%S %p}
+} 43199
+test clock-29.892 {time parsing} {
+    clock scan {2440588 xi:lix:lix AM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM:%OS %p}
+} 43199
+test clock-29.893 {time parsing} {
+    clock scan {2440588 11:59:59 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M:%S %P}
+} 43199
+test clock-29.894 {time parsing} {
+    clock scan {2440588 11:lix:lix am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM:%OS %P}
+} 43199
+test clock-29.895 {time parsing} {
+    clock scan {2440588 11:59:59 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M:%S %P}
+} 43199
+test clock-29.896 {time parsing} {
+    clock scan {2440588 11:lix:lix am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM:%OS %P}
+} 43199
+test clock-29.897 {time parsing} {
+    clock scan {2440588 xi:59:59 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M:%S %P}
+} 43199
+test clock-29.898 {time parsing} {
+    clock scan {2440588 xi:lix:lix am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM:%OS %P}
+} 43199
+test clock-29.899 {time parsing} {
+    clock scan {2440588 xi:59:59 am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M:%S %P}
+} 43199
+test clock-29.900 {time parsing} {
+    clock scan {2440588 xi:lix:lix am} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM:%OS %P}
+} 43199
+test clock-29.901 {time parsing} {
+    clock scan {2440588 12 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H }
+} 43200
+test clock-29.902 {time parsing} {
+    clock scan {2440588 12:00 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%M }
+} 43200
+test clock-29.903 {time parsing} {
+    clock scan {2440588 12:? } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%OM }
+} 43200
+test clock-29.904 {time parsing} {
+    clock scan {2440588 12:00:00 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%M:%S }
+} 43200
+test clock-29.905 {time parsing} {
+    clock scan {2440588 12:?:? } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%OM:%OS }
+} 43200
+test clock-29.906 {time parsing} {
+    clock scan {2440588 12 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k }
+} 43200
+test clock-29.907 {time parsing} {
+    clock scan {2440588 12:00 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%M }
+} 43200
+test clock-29.908 {time parsing} {
+    clock scan {2440588 12:? } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%OM }
+} 43200
+test clock-29.909 {time parsing} {
+    clock scan {2440588 12:00:00 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%M:%S }
+} 43200
+test clock-29.910 {time parsing} {
+    clock scan {2440588 12:?:? } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%OM:%OS }
+} 43200
+test clock-29.911 {time parsing} {
+    clock scan {2440588 xii } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH }
+} 43200
+test clock-29.912 {time parsing} {
+    clock scan {2440588 xii:00 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%M }
+} 43200
+test clock-29.913 {time parsing} {
+    clock scan {2440588 xii:? } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%OM }
+} 43200
+test clock-29.914 {time parsing} {
+    clock scan {2440588 xii:00:00 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%M:%S }
+} 43200
+test clock-29.915 {time parsing} {
+    clock scan {2440588 xii:?:? } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%OM:%OS }
+} 43200
+test clock-29.916 {time parsing} {
+    clock scan {2440588 xii } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok }
+} 43200
+test clock-29.917 {time parsing} {
+    clock scan {2440588 xii:00 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%M }
+} 43200
+test clock-29.918 {time parsing} {
+    clock scan {2440588 xii:? } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%OM }
+} 43200
+test clock-29.919 {time parsing} {
+    clock scan {2440588 xii:00:00 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%M:%S }
+} 43200
+test clock-29.920 {time parsing} {
+    clock scan {2440588 xii:?:? } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%OM:%OS }
+} 43200
+test clock-29.921 {time parsing} {
+    clock scan {2440588 12 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I %p}
+} 43200
+test clock-29.922 {time parsing} {
+    clock scan {2440588 12:00 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M %p}
+} 43200
+test clock-29.923 {time parsing} {
+    clock scan {2440588 12:? PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM %p}
+} 43200
+test clock-29.924 {time parsing} {
+    clock scan {2440588 12:00:00 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M:%S %p}
+} 43200
+test clock-29.925 {time parsing} {
+    clock scan {2440588 12:?:? PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM:%OS %p}
+} 43200
+test clock-29.926 {time parsing} {
+    clock scan {2440588 12 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l %p}
+} 43200
+test clock-29.927 {time parsing} {
+    clock scan {2440588 12:00 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M %p}
+} 43200
+test clock-29.928 {time parsing} {
+    clock scan {2440588 12:? PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM %p}
+} 43200
+test clock-29.929 {time parsing} {
+    clock scan {2440588 12:00:00 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M:%S %p}
+} 43200
+test clock-29.930 {time parsing} {
+    clock scan {2440588 12:?:? PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM:%OS %p}
+} 43200
+test clock-29.931 {time parsing} {
+    clock scan {2440588 xii PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI %p}
+} 43200
+test clock-29.932 {time parsing} {
+    clock scan {2440588 xii:00 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M %p}
+} 43200
+test clock-29.933 {time parsing} {
+    clock scan {2440588 xii:? PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM %p}
+} 43200
+test clock-29.934 {time parsing} {
+    clock scan {2440588 xii:00:00 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M:%S %p}
+} 43200
+test clock-29.935 {time parsing} {
+    clock scan {2440588 xii:?:? PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM:%OS %p}
+} 43200
+test clock-29.936 {time parsing} {
+    clock scan {2440588 xii PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol %p}
+} 43200
+test clock-29.937 {time parsing} {
+    clock scan {2440588 xii:00 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M %p}
+} 43200
+test clock-29.938 {time parsing} {
+    clock scan {2440588 xii:? PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM %p}
+} 43200
+test clock-29.939 {time parsing} {
+    clock scan {2440588 xii:00:00 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M:%S %p}
+} 43200
+test clock-29.940 {time parsing} {
+    clock scan {2440588 xii:?:? PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM:%OS %p}
+} 43200
+test clock-29.941 {time parsing} {
+    clock scan {2440588 12 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I %P}
+} 43200
+test clock-29.942 {time parsing} {
+    clock scan {2440588 12:00 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M %P}
+} 43200
+test clock-29.943 {time parsing} {
+    clock scan {2440588 12:? pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM %P}
+} 43200
+test clock-29.944 {time parsing} {
+    clock scan {2440588 12:00:00 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M:%S %P}
+} 43200
+test clock-29.945 {time parsing} {
+    clock scan {2440588 12:?:? pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM:%OS %P}
+} 43200
+test clock-29.946 {time parsing} {
+    clock scan {2440588 12 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l %P}
+} 43200
+test clock-29.947 {time parsing} {
+    clock scan {2440588 12:00 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M %P}
+} 43200
+test clock-29.948 {time parsing} {
+    clock scan {2440588 12:? pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM %P}
+} 43200
+test clock-29.949 {time parsing} {
+    clock scan {2440588 12:00:00 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M:%S %P}
+} 43200
+test clock-29.950 {time parsing} {
+    clock scan {2440588 12:?:? pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM:%OS %P}
+} 43200
+test clock-29.951 {time parsing} {
+    clock scan {2440588 xii pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI %P}
+} 43200
+test clock-29.952 {time parsing} {
+    clock scan {2440588 xii:00 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M %P}
+} 43200
+test clock-29.953 {time parsing} {
+    clock scan {2440588 xii:? pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM %P}
+} 43200
+test clock-29.954 {time parsing} {
+    clock scan {2440588 xii:00:00 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M:%S %P}
+} 43200
+test clock-29.955 {time parsing} {
+    clock scan {2440588 xii:?:? pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM:%OS %P}
+} 43200
+test clock-29.956 {time parsing} {
+    clock scan {2440588 xii pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol %P}
+} 43200
+test clock-29.957 {time parsing} {
+    clock scan {2440588 xii:00 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M %P}
+} 43200
+test clock-29.958 {time parsing} {
+    clock scan {2440588 xii:? pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM %P}
+} 43200
+test clock-29.959 {time parsing} {
+    clock scan {2440588 xii:00:00 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M:%S %P}
+} 43200
+test clock-29.960 {time parsing} {
+    clock scan {2440588 xii:?:? pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM:%OS %P}
+} 43200
+test clock-29.961 {time parsing} {
+    clock scan {2440588 12:00:01 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%M:%S }
+} 43201
+test clock-29.962 {time parsing} {
+    clock scan {2440588 12:?:i } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%OM:%OS }
+} 43201
+test clock-29.963 {time parsing} {
+    clock scan {2440588 12:00:01 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%M:%S }
+} 43201
+test clock-29.964 {time parsing} {
+    clock scan {2440588 12:?:i } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%OM:%OS }
+} 43201
+test clock-29.965 {time parsing} {
+    clock scan {2440588 xii:00:01 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%M:%S }
+} 43201
+test clock-29.966 {time parsing} {
+    clock scan {2440588 xii:?:i } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%OM:%OS }
+} 43201
+test clock-29.967 {time parsing} {
+    clock scan {2440588 xii:00:01 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%M:%S }
+} 43201
+test clock-29.968 {time parsing} {
+    clock scan {2440588 xii:?:i } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%OM:%OS }
+} 43201
+test clock-29.969 {time parsing} {
+    clock scan {2440588 12:00:01 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M:%S %p}
+} 43201
+test clock-29.970 {time parsing} {
+    clock scan {2440588 12:?:i PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM:%OS %p}
+} 43201
+test clock-29.971 {time parsing} {
+    clock scan {2440588 12:00:01 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M:%S %p}
+} 43201
+test clock-29.972 {time parsing} {
+    clock scan {2440588 12:?:i PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM:%OS %p}
+} 43201
+test clock-29.973 {time parsing} {
+    clock scan {2440588 xii:00:01 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M:%S %p}
+} 43201
+test clock-29.974 {time parsing} {
+    clock scan {2440588 xii:?:i PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM:%OS %p}
+} 43201
+test clock-29.975 {time parsing} {
+    clock scan {2440588 xii:00:01 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M:%S %p}
+} 43201
+test clock-29.976 {time parsing} {
+    clock scan {2440588 xii:?:i PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM:%OS %p}
+} 43201
+test clock-29.977 {time parsing} {
+    clock scan {2440588 12:00:01 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M:%S %P}
+} 43201
+test clock-29.978 {time parsing} {
+    clock scan {2440588 12:?:i pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM:%OS %P}
+} 43201
+test clock-29.979 {time parsing} {
+    clock scan {2440588 12:00:01 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M:%S %P}
+} 43201
+test clock-29.980 {time parsing} {
+    clock scan {2440588 12:?:i pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM:%OS %P}
+} 43201
+test clock-29.981 {time parsing} {
+    clock scan {2440588 xii:00:01 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M:%S %P}
+} 43201
+test clock-29.982 {time parsing} {
+    clock scan {2440588 xii:?:i pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM:%OS %P}
+} 43201
+test clock-29.983 {time parsing} {
+    clock scan {2440588 xii:00:01 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M:%S %P}
+} 43201
+test clock-29.984 {time parsing} {
+    clock scan {2440588 xii:?:i pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM:%OS %P}
+} 43201
+test clock-29.985 {time parsing} {
+    clock scan {2440588 12:00:59 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%M:%S }
+} 43259
+test clock-29.986 {time parsing} {
+    clock scan {2440588 12:?:lix } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%OM:%OS }
+} 43259
+test clock-29.987 {time parsing} {
+    clock scan {2440588 12:00:59 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%M:%S }
+} 43259
+test clock-29.988 {time parsing} {
+    clock scan {2440588 12:?:lix } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%OM:%OS }
+} 43259
+test clock-29.989 {time parsing} {
+    clock scan {2440588 xii:00:59 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%M:%S }
+} 43259
+test clock-29.990 {time parsing} {
+    clock scan {2440588 xii:?:lix } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%OM:%OS }
+} 43259
+test clock-29.991 {time parsing} {
+    clock scan {2440588 xii:00:59 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%M:%S }
+} 43259
+test clock-29.992 {time parsing} {
+    clock scan {2440588 xii:?:lix } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%OM:%OS }
+} 43259
+test clock-29.993 {time parsing} {
+    clock scan {2440588 12:00:59 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M:%S %p}
+} 43259
+test clock-29.994 {time parsing} {
+    clock scan {2440588 12:?:lix PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM:%OS %p}
+} 43259
+test clock-29.995 {time parsing} {
+    clock scan {2440588 12:00:59 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M:%S %p}
+} 43259
+test clock-29.996 {time parsing} {
+    clock scan {2440588 12:?:lix PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM:%OS %p}
+} 43259
+test clock-29.997 {time parsing} {
+    clock scan {2440588 xii:00:59 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M:%S %p}
+} 43259
+test clock-29.998 {time parsing} {
+    clock scan {2440588 xii:?:lix PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM:%OS %p}
+} 43259
+test clock-29.999 {time parsing} {
+    clock scan {2440588 xii:00:59 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M:%S %p}
+} 43259
+test clock-29.1000 {time parsing} {
+    clock scan {2440588 xii:?:lix PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM:%OS %p}
+} 43259
+test clock-29.1001 {time parsing} {
+    clock scan {2440588 12:00:59 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M:%S %P}
+} 43259
+test clock-29.1002 {time parsing} {
+    clock scan {2440588 12:?:lix pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM:%OS %P}
+} 43259
+test clock-29.1003 {time parsing} {
+    clock scan {2440588 12:00:59 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M:%S %P}
+} 43259
+test clock-29.1004 {time parsing} {
+    clock scan {2440588 12:?:lix pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM:%OS %P}
+} 43259
+test clock-29.1005 {time parsing} {
+    clock scan {2440588 xii:00:59 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M:%S %P}
+} 43259
+test clock-29.1006 {time parsing} {
+    clock scan {2440588 xii:?:lix pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM:%OS %P}
+} 43259
+test clock-29.1007 {time parsing} {
+    clock scan {2440588 xii:00:59 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M:%S %P}
+} 43259
+test clock-29.1008 {time parsing} {
+    clock scan {2440588 xii:?:lix pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM:%OS %P}
+} 43259
+test clock-29.1009 {time parsing} {
+    clock scan {2440588 12:01 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%M }
+} 43260
+test clock-29.1010 {time parsing} {
+    clock scan {2440588 12:i } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%OM }
+} 43260
+test clock-29.1011 {time parsing} {
+    clock scan {2440588 12:01:00 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%M:%S }
+} 43260
+test clock-29.1012 {time parsing} {
+    clock scan {2440588 12:i:? } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%OM:%OS }
+} 43260
+test clock-29.1013 {time parsing} {
+    clock scan {2440588 12:01 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%M }
+} 43260
+test clock-29.1014 {time parsing} {
+    clock scan {2440588 12:i } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%OM }
+} 43260
+test clock-29.1015 {time parsing} {
+    clock scan {2440588 12:01:00 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%M:%S }
+} 43260
+test clock-29.1016 {time parsing} {
+    clock scan {2440588 12:i:? } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%OM:%OS }
+} 43260
+test clock-29.1017 {time parsing} {
+    clock scan {2440588 xii:01 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%M }
+} 43260
+test clock-29.1018 {time parsing} {
+    clock scan {2440588 xii:i } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%OM }
+} 43260
+test clock-29.1019 {time parsing} {
+    clock scan {2440588 xii:01:00 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%M:%S }
+} 43260
+test clock-29.1020 {time parsing} {
+    clock scan {2440588 xii:i:? } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%OM:%OS }
+} 43260
+test clock-29.1021 {time parsing} {
+    clock scan {2440588 xii:01 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%M }
+} 43260
+test clock-29.1022 {time parsing} {
+    clock scan {2440588 xii:i } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%OM }
+} 43260
+test clock-29.1023 {time parsing} {
+    clock scan {2440588 xii:01:00 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%M:%S }
+} 43260
+test clock-29.1024 {time parsing} {
+    clock scan {2440588 xii:i:? } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%OM:%OS }
+} 43260
+test clock-29.1025 {time parsing} {
+    clock scan {2440588 12:01 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M %p}
+} 43260
+test clock-29.1026 {time parsing} {
+    clock scan {2440588 12:i PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM %p}
+} 43260
+test clock-29.1027 {time parsing} {
+    clock scan {2440588 12:01:00 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M:%S %p}
+} 43260
+test clock-29.1028 {time parsing} {
+    clock scan {2440588 12:i:? PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM:%OS %p}
+} 43260
+test clock-29.1029 {time parsing} {
+    clock scan {2440588 12:01 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M %p}
+} 43260
+test clock-29.1030 {time parsing} {
+    clock scan {2440588 12:i PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM %p}
+} 43260
+test clock-29.1031 {time parsing} {
+    clock scan {2440588 12:01:00 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M:%S %p}
+} 43260
+test clock-29.1032 {time parsing} {
+    clock scan {2440588 12:i:? PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM:%OS %p}
+} 43260
+test clock-29.1033 {time parsing} {
+    clock scan {2440588 xii:01 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M %p}
+} 43260
+test clock-29.1034 {time parsing} {
+    clock scan {2440588 xii:i PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM %p}
+} 43260
+test clock-29.1035 {time parsing} {
+    clock scan {2440588 xii:01:00 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M:%S %p}
+} 43260
+test clock-29.1036 {time parsing} {
+    clock scan {2440588 xii:i:? PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM:%OS %p}
+} 43260
+test clock-29.1037 {time parsing} {
+    clock scan {2440588 xii:01 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M %p}
+} 43260
+test clock-29.1038 {time parsing} {
+    clock scan {2440588 xii:i PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM %p}
+} 43260
+test clock-29.1039 {time parsing} {
+    clock scan {2440588 xii:01:00 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M:%S %p}
+} 43260
+test clock-29.1040 {time parsing} {
+    clock scan {2440588 xii:i:? PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM:%OS %p}
+} 43260
+test clock-29.1041 {time parsing} {
+    clock scan {2440588 12:01 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M %P}
+} 43260
+test clock-29.1042 {time parsing} {
+    clock scan {2440588 12:i pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM %P}
+} 43260
+test clock-29.1043 {time parsing} {
+    clock scan {2440588 12:01:00 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M:%S %P}
+} 43260
+test clock-29.1044 {time parsing} {
+    clock scan {2440588 12:i:? pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM:%OS %P}
+} 43260
+test clock-29.1045 {time parsing} {
+    clock scan {2440588 12:01 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M %P}
+} 43260
+test clock-29.1046 {time parsing} {
+    clock scan {2440588 12:i pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM %P}
+} 43260
+test clock-29.1047 {time parsing} {
+    clock scan {2440588 12:01:00 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M:%S %P}
+} 43260
+test clock-29.1048 {time parsing} {
+    clock scan {2440588 12:i:? pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM:%OS %P}
+} 43260
+test clock-29.1049 {time parsing} {
+    clock scan {2440588 xii:01 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M %P}
+} 43260
+test clock-29.1050 {time parsing} {
+    clock scan {2440588 xii:i pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM %P}
+} 43260
+test clock-29.1051 {time parsing} {
+    clock scan {2440588 xii:01:00 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M:%S %P}
+} 43260
+test clock-29.1052 {time parsing} {
+    clock scan {2440588 xii:i:? pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM:%OS %P}
+} 43260
+test clock-29.1053 {time parsing} {
+    clock scan {2440588 xii:01 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M %P}
+} 43260
+test clock-29.1054 {time parsing} {
+    clock scan {2440588 xii:i pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM %P}
+} 43260
+test clock-29.1055 {time parsing} {
+    clock scan {2440588 xii:01:00 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M:%S %P}
+} 43260
+test clock-29.1056 {time parsing} {
+    clock scan {2440588 xii:i:? pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM:%OS %P}
+} 43260
+test clock-29.1057 {time parsing} {
+    clock scan {2440588 12:01:01 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%M:%S }
+} 43261
+test clock-29.1058 {time parsing} {
+    clock scan {2440588 12:i:i } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%OM:%OS }
+} 43261
+test clock-29.1059 {time parsing} {
+    clock scan {2440588 12:01:01 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%M:%S }
+} 43261
+test clock-29.1060 {time parsing} {
+    clock scan {2440588 12:i:i } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%OM:%OS }
+} 43261
+test clock-29.1061 {time parsing} {
+    clock scan {2440588 xii:01:01 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%M:%S }
+} 43261
+test clock-29.1062 {time parsing} {
+    clock scan {2440588 xii:i:i } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%OM:%OS }
+} 43261
+test clock-29.1063 {time parsing} {
+    clock scan {2440588 xii:01:01 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%M:%S }
+} 43261
+test clock-29.1064 {time parsing} {
+    clock scan {2440588 xii:i:i } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%OM:%OS }
+} 43261
+test clock-29.1065 {time parsing} {
+    clock scan {2440588 12:01:01 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M:%S %p}
+} 43261
+test clock-29.1066 {time parsing} {
+    clock scan {2440588 12:i:i PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM:%OS %p}
+} 43261
+test clock-29.1067 {time parsing} {
+    clock scan {2440588 12:01:01 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M:%S %p}
+} 43261
+test clock-29.1068 {time parsing} {
+    clock scan {2440588 12:i:i PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM:%OS %p}
+} 43261
+test clock-29.1069 {time parsing} {
+    clock scan {2440588 xii:01:01 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M:%S %p}
+} 43261
+test clock-29.1070 {time parsing} {
+    clock scan {2440588 xii:i:i PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM:%OS %p}
+} 43261
+test clock-29.1071 {time parsing} {
+    clock scan {2440588 xii:01:01 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M:%S %p}
+} 43261
+test clock-29.1072 {time parsing} {
+    clock scan {2440588 xii:i:i PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM:%OS %p}
+} 43261
+test clock-29.1073 {time parsing} {
+    clock scan {2440588 12:01:01 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M:%S %P}
+} 43261
+test clock-29.1074 {time parsing} {
+    clock scan {2440588 12:i:i pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM:%OS %P}
+} 43261
+test clock-29.1075 {time parsing} {
+    clock scan {2440588 12:01:01 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M:%S %P}
+} 43261
+test clock-29.1076 {time parsing} {
+    clock scan {2440588 12:i:i pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM:%OS %P}
+} 43261
+test clock-29.1077 {time parsing} {
+    clock scan {2440588 xii:01:01 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M:%S %P}
+} 43261
+test clock-29.1078 {time parsing} {
+    clock scan {2440588 xii:i:i pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM:%OS %P}
+} 43261
+test clock-29.1079 {time parsing} {
+    clock scan {2440588 xii:01:01 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M:%S %P}
+} 43261
+test clock-29.1080 {time parsing} {
+    clock scan {2440588 xii:i:i pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM:%OS %P}
+} 43261
+test clock-29.1081 {time parsing} {
+    clock scan {2440588 12:01:59 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%M:%S }
+} 43319
+test clock-29.1082 {time parsing} {
+    clock scan {2440588 12:i:lix } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%OM:%OS }
+} 43319
+test clock-29.1083 {time parsing} {
+    clock scan {2440588 12:01:59 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%M:%S }
+} 43319
+test clock-29.1084 {time parsing} {
+    clock scan {2440588 12:i:lix } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%OM:%OS }
+} 43319
+test clock-29.1085 {time parsing} {
+    clock scan {2440588 xii:01:59 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%M:%S }
+} 43319
+test clock-29.1086 {time parsing} {
+    clock scan {2440588 xii:i:lix } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%OM:%OS }
+} 43319
+test clock-29.1087 {time parsing} {
+    clock scan {2440588 xii:01:59 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%M:%S }
+} 43319
+test clock-29.1088 {time parsing} {
+    clock scan {2440588 xii:i:lix } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%OM:%OS }
+} 43319
+test clock-29.1089 {time parsing} {
+    clock scan {2440588 12:01:59 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M:%S %p}
+} 43319
+test clock-29.1090 {time parsing} {
+    clock scan {2440588 12:i:lix PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM:%OS %p}
+} 43319
+test clock-29.1091 {time parsing} {
+    clock scan {2440588 12:01:59 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M:%S %p}
+} 43319
+test clock-29.1092 {time parsing} {
+    clock scan {2440588 12:i:lix PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM:%OS %p}
+} 43319
+test clock-29.1093 {time parsing} {
+    clock scan {2440588 xii:01:59 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M:%S %p}
+} 43319
+test clock-29.1094 {time parsing} {
+    clock scan {2440588 xii:i:lix PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM:%OS %p}
+} 43319
+test clock-29.1095 {time parsing} {
+    clock scan {2440588 xii:01:59 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M:%S %p}
+} 43319
+test clock-29.1096 {time parsing} {
+    clock scan {2440588 xii:i:lix PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM:%OS %p}
+} 43319
+test clock-29.1097 {time parsing} {
+    clock scan {2440588 12:01:59 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M:%S %P}
+} 43319
+test clock-29.1098 {time parsing} {
+    clock scan {2440588 12:i:lix pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM:%OS %P}
+} 43319
+test clock-29.1099 {time parsing} {
+    clock scan {2440588 12:01:59 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M:%S %P}
+} 43319
+test clock-29.1100 {time parsing} {
+    clock scan {2440588 12:i:lix pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM:%OS %P}
+} 43319
+test clock-29.1101 {time parsing} {
+    clock scan {2440588 xii:01:59 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M:%S %P}
+} 43319
+test clock-29.1102 {time parsing} {
+    clock scan {2440588 xii:i:lix pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM:%OS %P}
+} 43319
+test clock-29.1103 {time parsing} {
+    clock scan {2440588 xii:01:59 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M:%S %P}
+} 43319
+test clock-29.1104 {time parsing} {
+    clock scan {2440588 xii:i:lix pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM:%OS %P}
+} 43319
+test clock-29.1105 {time parsing} {
+    clock scan {2440588 12:59 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%M }
+} 46740
+test clock-29.1106 {time parsing} {
+    clock scan {2440588 12:lix } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%OM }
+} 46740
+test clock-29.1107 {time parsing} {
+    clock scan {2440588 12:59:00 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%M:%S }
+} 46740
+test clock-29.1108 {time parsing} {
+    clock scan {2440588 12:lix:? } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%OM:%OS }
+} 46740
+test clock-29.1109 {time parsing} {
+    clock scan {2440588 12:59 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%M }
+} 46740
+test clock-29.1110 {time parsing} {
+    clock scan {2440588 12:lix } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%OM }
+} 46740
+test clock-29.1111 {time parsing} {
+    clock scan {2440588 12:59:00 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%M:%S }
+} 46740
+test clock-29.1112 {time parsing} {
+    clock scan {2440588 12:lix:? } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%OM:%OS }
+} 46740
+test clock-29.1113 {time parsing} {
+    clock scan {2440588 xii:59 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%M }
+} 46740
+test clock-29.1114 {time parsing} {
+    clock scan {2440588 xii:lix } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%OM }
+} 46740
+test clock-29.1115 {time parsing} {
+    clock scan {2440588 xii:59:00 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%M:%S }
+} 46740
+test clock-29.1116 {time parsing} {
+    clock scan {2440588 xii:lix:? } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%OM:%OS }
+} 46740
+test clock-29.1117 {time parsing} {
+    clock scan {2440588 xii:59 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%M }
+} 46740
+test clock-29.1118 {time parsing} {
+    clock scan {2440588 xii:lix } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%OM }
+} 46740
+test clock-29.1119 {time parsing} {
+    clock scan {2440588 xii:59:00 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%M:%S }
+} 46740
+test clock-29.1120 {time parsing} {
+    clock scan {2440588 xii:lix:? } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%OM:%OS }
+} 46740
+test clock-29.1121 {time parsing} {
+    clock scan {2440588 12:59 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M %p}
+} 46740
+test clock-29.1122 {time parsing} {
+    clock scan {2440588 12:lix PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM %p}
+} 46740
+test clock-29.1123 {time parsing} {
+    clock scan {2440588 12:59:00 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M:%S %p}
+} 46740
+test clock-29.1124 {time parsing} {
+    clock scan {2440588 12:lix:? PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM:%OS %p}
+} 46740
+test clock-29.1125 {time parsing} {
+    clock scan {2440588 12:59 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M %p}
+} 46740
+test clock-29.1126 {time parsing} {
+    clock scan {2440588 12:lix PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM %p}
+} 46740
+test clock-29.1127 {time parsing} {
+    clock scan {2440588 12:59:00 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M:%S %p}
+} 46740
+test clock-29.1128 {time parsing} {
+    clock scan {2440588 12:lix:? PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM:%OS %p}
+} 46740
+test clock-29.1129 {time parsing} {
+    clock scan {2440588 xii:59 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M %p}
+} 46740
+test clock-29.1130 {time parsing} {
+    clock scan {2440588 xii:lix PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM %p}
+} 46740
+test clock-29.1131 {time parsing} {
+    clock scan {2440588 xii:59:00 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M:%S %p}
+} 46740
+test clock-29.1132 {time parsing} {
+    clock scan {2440588 xii:lix:? PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM:%OS %p}
+} 46740
+test clock-29.1133 {time parsing} {
+    clock scan {2440588 xii:59 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M %p}
+} 46740
+test clock-29.1134 {time parsing} {
+    clock scan {2440588 xii:lix PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM %p}
+} 46740
+test clock-29.1135 {time parsing} {
+    clock scan {2440588 xii:59:00 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M:%S %p}
+} 46740
+test clock-29.1136 {time parsing} {
+    clock scan {2440588 xii:lix:? PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM:%OS %p}
+} 46740
+test clock-29.1137 {time parsing} {
+    clock scan {2440588 12:59 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M %P}
+} 46740
+test clock-29.1138 {time parsing} {
+    clock scan {2440588 12:lix pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM %P}
+} 46740
+test clock-29.1139 {time parsing} {
+    clock scan {2440588 12:59:00 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M:%S %P}
+} 46740
+test clock-29.1140 {time parsing} {
+    clock scan {2440588 12:lix:? pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM:%OS %P}
+} 46740
+test clock-29.1141 {time parsing} {
+    clock scan {2440588 12:59 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M %P}
+} 46740
+test clock-29.1142 {time parsing} {
+    clock scan {2440588 12:lix pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM %P}
+} 46740
+test clock-29.1143 {time parsing} {
+    clock scan {2440588 12:59:00 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M:%S %P}
+} 46740
+test clock-29.1144 {time parsing} {
+    clock scan {2440588 12:lix:? pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM:%OS %P}
+} 46740
+test clock-29.1145 {time parsing} {
+    clock scan {2440588 xii:59 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M %P}
+} 46740
+test clock-29.1146 {time parsing} {
+    clock scan {2440588 xii:lix pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM %P}
+} 46740
+test clock-29.1147 {time parsing} {
+    clock scan {2440588 xii:59:00 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M:%S %P}
+} 46740
+test clock-29.1148 {time parsing} {
+    clock scan {2440588 xii:lix:? pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM:%OS %P}
+} 46740
+test clock-29.1149 {time parsing} {
+    clock scan {2440588 xii:59 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M %P}
+} 46740
+test clock-29.1150 {time parsing} {
+    clock scan {2440588 xii:lix pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM %P}
+} 46740
+test clock-29.1151 {time parsing} {
+    clock scan {2440588 xii:59:00 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M:%S %P}
+} 46740
+test clock-29.1152 {time parsing} {
+    clock scan {2440588 xii:lix:? pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM:%OS %P}
+} 46740
+test clock-29.1153 {time parsing} {
+    clock scan {2440588 12:59:01 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%M:%S }
+} 46741
+test clock-29.1154 {time parsing} {
+    clock scan {2440588 12:lix:i } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%OM:%OS }
+} 46741
+test clock-29.1155 {time parsing} {
+    clock scan {2440588 12:59:01 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%M:%S }
+} 46741
+test clock-29.1156 {time parsing} {
+    clock scan {2440588 12:lix:i } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%OM:%OS }
+} 46741
+test clock-29.1157 {time parsing} {
+    clock scan {2440588 xii:59:01 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%M:%S }
+} 46741
+test clock-29.1158 {time parsing} {
+    clock scan {2440588 xii:lix:i } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%OM:%OS }
+} 46741
+test clock-29.1159 {time parsing} {
+    clock scan {2440588 xii:59:01 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%M:%S }
+} 46741
+test clock-29.1160 {time parsing} {
+    clock scan {2440588 xii:lix:i } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%OM:%OS }
+} 46741
+test clock-29.1161 {time parsing} {
+    clock scan {2440588 12:59:01 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M:%S %p}
+} 46741
+test clock-29.1162 {time parsing} {
+    clock scan {2440588 12:lix:i PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM:%OS %p}
+} 46741
+test clock-29.1163 {time parsing} {
+    clock scan {2440588 12:59:01 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M:%S %p}
+} 46741
+test clock-29.1164 {time parsing} {
+    clock scan {2440588 12:lix:i PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM:%OS %p}
+} 46741
+test clock-29.1165 {time parsing} {
+    clock scan {2440588 xii:59:01 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M:%S %p}
+} 46741
+test clock-29.1166 {time parsing} {
+    clock scan {2440588 xii:lix:i PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM:%OS %p}
+} 46741
+test clock-29.1167 {time parsing} {
+    clock scan {2440588 xii:59:01 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M:%S %p}
+} 46741
+test clock-29.1168 {time parsing} {
+    clock scan {2440588 xii:lix:i PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM:%OS %p}
+} 46741
+test clock-29.1169 {time parsing} {
+    clock scan {2440588 12:59:01 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M:%S %P}
+} 46741
+test clock-29.1170 {time parsing} {
+    clock scan {2440588 12:lix:i pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM:%OS %P}
+} 46741
+test clock-29.1171 {time parsing} {
+    clock scan {2440588 12:59:01 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M:%S %P}
+} 46741
+test clock-29.1172 {time parsing} {
+    clock scan {2440588 12:lix:i pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM:%OS %P}
+} 46741
+test clock-29.1173 {time parsing} {
+    clock scan {2440588 xii:59:01 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M:%S %P}
+} 46741
+test clock-29.1174 {time parsing} {
+    clock scan {2440588 xii:lix:i pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM:%OS %P}
+} 46741
+test clock-29.1175 {time parsing} {
+    clock scan {2440588 xii:59:01 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M:%S %P}
+} 46741
+test clock-29.1176 {time parsing} {
+    clock scan {2440588 xii:lix:i pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM:%OS %P}
+} 46741
+test clock-29.1177 {time parsing} {
+    clock scan {2440588 12:59:59 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%M:%S }
+} 46799
+test clock-29.1178 {time parsing} {
+    clock scan {2440588 12:lix:lix } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%OM:%OS }
+} 46799
+test clock-29.1179 {time parsing} {
+    clock scan {2440588 12:59:59 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%M:%S }
+} 46799
+test clock-29.1180 {time parsing} {
+    clock scan {2440588 12:lix:lix } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%OM:%OS }
+} 46799
+test clock-29.1181 {time parsing} {
+    clock scan {2440588 xii:59:59 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%M:%S }
+} 46799
+test clock-29.1182 {time parsing} {
+    clock scan {2440588 xii:lix:lix } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%OM:%OS }
+} 46799
+test clock-29.1183 {time parsing} {
+    clock scan {2440588 xii:59:59 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%M:%S }
+} 46799
+test clock-29.1184 {time parsing} {
+    clock scan {2440588 xii:lix:lix } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%OM:%OS }
+} 46799
+test clock-29.1185 {time parsing} {
+    clock scan {2440588 12:59:59 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M:%S %p}
+} 46799
+test clock-29.1186 {time parsing} {
+    clock scan {2440588 12:lix:lix PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM:%OS %p}
+} 46799
+test clock-29.1187 {time parsing} {
+    clock scan {2440588 12:59:59 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M:%S %p}
+} 46799
+test clock-29.1188 {time parsing} {
+    clock scan {2440588 12:lix:lix PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM:%OS %p}
+} 46799
+test clock-29.1189 {time parsing} {
+    clock scan {2440588 xii:59:59 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M:%S %p}
+} 46799
+test clock-29.1190 {time parsing} {
+    clock scan {2440588 xii:lix:lix PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM:%OS %p}
+} 46799
+test clock-29.1191 {time parsing} {
+    clock scan {2440588 xii:59:59 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M:%S %p}
+} 46799
+test clock-29.1192 {time parsing} {
+    clock scan {2440588 xii:lix:lix PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM:%OS %p}
+} 46799
+test clock-29.1193 {time parsing} {
+    clock scan {2440588 12:59:59 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M:%S %P}
+} 46799
+test clock-29.1194 {time parsing} {
+    clock scan {2440588 12:lix:lix pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM:%OS %P}
+} 46799
+test clock-29.1195 {time parsing} {
+    clock scan {2440588 12:59:59 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M:%S %P}
+} 46799
+test clock-29.1196 {time parsing} {
+    clock scan {2440588 12:lix:lix pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM:%OS %P}
+} 46799
+test clock-29.1197 {time parsing} {
+    clock scan {2440588 xii:59:59 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M:%S %P}
+} 46799
+test clock-29.1198 {time parsing} {
+    clock scan {2440588 xii:lix:lix pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM:%OS %P}
+} 46799
+test clock-29.1199 {time parsing} {
+    clock scan {2440588 xii:59:59 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M:%S %P}
+} 46799
+test clock-29.1200 {time parsing} {
+    clock scan {2440588 xii:lix:lix pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM:%OS %P}
+} 46799
+test clock-29.1201 {time parsing} {
+    clock scan {2440588 13 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H }
+} 46800
+test clock-29.1202 {time parsing} {
+    clock scan {2440588 13:00 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%M }
+} 46800
+test clock-29.1203 {time parsing} {
+    clock scan {2440588 13:? } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%OM }
+} 46800
+test clock-29.1204 {time parsing} {
+    clock scan {2440588 13:00:00 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%M:%S }
+} 46800
+test clock-29.1205 {time parsing} {
+    clock scan {2440588 13:?:? } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%OM:%OS }
+} 46800
+test clock-29.1206 {time parsing} {
+    clock scan {2440588 13 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k }
+} 46800
+test clock-29.1207 {time parsing} {
+    clock scan {2440588 13:00 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%M }
+} 46800
+test clock-29.1208 {time parsing} {
+    clock scan {2440588 13:? } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%OM }
+} 46800
+test clock-29.1209 {time parsing} {
+    clock scan {2440588 13:00:00 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%M:%S }
+} 46800
+test clock-29.1210 {time parsing} {
+    clock scan {2440588 13:?:? } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%OM:%OS }
+} 46800
+test clock-29.1211 {time parsing} {
+    clock scan {2440588 xiii } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH }
+} 46800
+test clock-29.1212 {time parsing} {
+    clock scan {2440588 xiii:00 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%M }
+} 46800
+test clock-29.1213 {time parsing} {
+    clock scan {2440588 xiii:? } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%OM }
+} 46800
+test clock-29.1214 {time parsing} {
+    clock scan {2440588 xiii:00:00 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%M:%S }
+} 46800
+test clock-29.1215 {time parsing} {
+    clock scan {2440588 xiii:?:? } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%OM:%OS }
+} 46800
+test clock-29.1216 {time parsing} {
+    clock scan {2440588 xiii } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok }
+} 46800
+test clock-29.1217 {time parsing} {
+    clock scan {2440588 xiii:00 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%M }
+} 46800
+test clock-29.1218 {time parsing} {
+    clock scan {2440588 xiii:? } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%OM }
+} 46800
+test clock-29.1219 {time parsing} {
+    clock scan {2440588 xiii:00:00 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%M:%S }
+} 46800
+test clock-29.1220 {time parsing} {
+    clock scan {2440588 xiii:?:? } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%OM:%OS }
+} 46800
+test clock-29.1221 {time parsing} {
+    clock scan {2440588 01 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I %p}
+} 46800
+test clock-29.1222 {time parsing} {
+    clock scan {2440588 01:00 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M %p}
+} 46800
+test clock-29.1223 {time parsing} {
+    clock scan {2440588 01:? PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM %p}
+} 46800
+test clock-29.1224 {time parsing} {
+    clock scan {2440588 01:00:00 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M:%S %p}
+} 46800
+test clock-29.1225 {time parsing} {
+    clock scan {2440588 01:?:? PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM:%OS %p}
+} 46800
+test clock-29.1226 {time parsing} {
+    clock scan {2440588  1 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l %p}
+} 46800
+test clock-29.1227 {time parsing} {
+    clock scan {2440588  1:00 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M %p}
+} 46800
+test clock-29.1228 {time parsing} {
+    clock scan {2440588  1:? PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM %p}
+} 46800
+test clock-29.1229 {time parsing} {
+    clock scan {2440588  1:00:00 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M:%S %p}
+} 46800
+test clock-29.1230 {time parsing} {
+    clock scan {2440588  1:?:? PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM:%OS %p}
+} 46800
+test clock-29.1231 {time parsing} {
+    clock scan {2440588 i PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI %p}
+} 46800
+test clock-29.1232 {time parsing} {
+    clock scan {2440588 i:00 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M %p}
+} 46800
+test clock-29.1233 {time parsing} {
+    clock scan {2440588 i:? PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM %p}
+} 46800
+test clock-29.1234 {time parsing} {
+    clock scan {2440588 i:00:00 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M:%S %p}
+} 46800
+test clock-29.1235 {time parsing} {
+    clock scan {2440588 i:?:? PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM:%OS %p}
+} 46800
+test clock-29.1236 {time parsing} {
+    clock scan {2440588 i PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol %p}
+} 46800
+test clock-29.1237 {time parsing} {
+    clock scan {2440588 i:00 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M %p}
+} 46800
+test clock-29.1238 {time parsing} {
+    clock scan {2440588 i:? PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM %p}
+} 46800
+test clock-29.1239 {time parsing} {
+    clock scan {2440588 i:00:00 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M:%S %p}
+} 46800
+test clock-29.1240 {time parsing} {
+    clock scan {2440588 i:?:? PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM:%OS %p}
+} 46800
+test clock-29.1241 {time parsing} {
+    clock scan {2440588 01 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I %P}
+} 46800
+test clock-29.1242 {time parsing} {
+    clock scan {2440588 01:00 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M %P}
+} 46800
+test clock-29.1243 {time parsing} {
+    clock scan {2440588 01:? pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM %P}
+} 46800
+test clock-29.1244 {time parsing} {
+    clock scan {2440588 01:00:00 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M:%S %P}
+} 46800
+test clock-29.1245 {time parsing} {
+    clock scan {2440588 01:?:? pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM:%OS %P}
+} 46800
+test clock-29.1246 {time parsing} {
+    clock scan {2440588  1 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l %P}
+} 46800
+test clock-29.1247 {time parsing} {
+    clock scan {2440588  1:00 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M %P}
+} 46800
+test clock-29.1248 {time parsing} {
+    clock scan {2440588  1:? pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM %P}
+} 46800
+test clock-29.1249 {time parsing} {
+    clock scan {2440588  1:00:00 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M:%S %P}
+} 46800
+test clock-29.1250 {time parsing} {
+    clock scan {2440588  1:?:? pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM:%OS %P}
+} 46800
+test clock-29.1251 {time parsing} {
+    clock scan {2440588 i pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI %P}
+} 46800
+test clock-29.1252 {time parsing} {
+    clock scan {2440588 i:00 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M %P}
+} 46800
+test clock-29.1253 {time parsing} {
+    clock scan {2440588 i:? pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM %P}
+} 46800
+test clock-29.1254 {time parsing} {
+    clock scan {2440588 i:00:00 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M:%S %P}
+} 46800
+test clock-29.1255 {time parsing} {
+    clock scan {2440588 i:?:? pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM:%OS %P}
+} 46800
+test clock-29.1256 {time parsing} {
+    clock scan {2440588 i pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol %P}
+} 46800
+test clock-29.1257 {time parsing} {
+    clock scan {2440588 i:00 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M %P}
+} 46800
+test clock-29.1258 {time parsing} {
+    clock scan {2440588 i:? pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM %P}
+} 46800
+test clock-29.1259 {time parsing} {
+    clock scan {2440588 i:00:00 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M:%S %P}
+} 46800
+test clock-29.1260 {time parsing} {
+    clock scan {2440588 i:?:? pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM:%OS %P}
+} 46800
+test clock-29.1261 {time parsing} {
+    clock scan {2440588 13:00:01 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%M:%S }
+} 46801
+test clock-29.1262 {time parsing} {
+    clock scan {2440588 13:?:i } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%OM:%OS }
+} 46801
+test clock-29.1263 {time parsing} {
+    clock scan {2440588 13:00:01 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%M:%S }
+} 46801
+test clock-29.1264 {time parsing} {
+    clock scan {2440588 13:?:i } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%OM:%OS }
+} 46801
+test clock-29.1265 {time parsing} {
+    clock scan {2440588 xiii:00:01 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%M:%S }
+} 46801
+test clock-29.1266 {time parsing} {
+    clock scan {2440588 xiii:?:i } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%OM:%OS }
+} 46801
+test clock-29.1267 {time parsing} {
+    clock scan {2440588 xiii:00:01 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%M:%S }
+} 46801
+test clock-29.1268 {time parsing} {
+    clock scan {2440588 xiii:?:i } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%OM:%OS }
+} 46801
+test clock-29.1269 {time parsing} {
+    clock scan {2440588 01:00:01 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M:%S %p}
+} 46801
+test clock-29.1270 {time parsing} {
+    clock scan {2440588 01:?:i PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM:%OS %p}
+} 46801
+test clock-29.1271 {time parsing} {
+    clock scan {2440588  1:00:01 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M:%S %p}
+} 46801
+test clock-29.1272 {time parsing} {
+    clock scan {2440588  1:?:i PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM:%OS %p}
+} 46801
+test clock-29.1273 {time parsing} {
+    clock scan {2440588 i:00:01 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M:%S %p}
+} 46801
+test clock-29.1274 {time parsing} {
+    clock scan {2440588 i:?:i PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM:%OS %p}
+} 46801
+test clock-29.1275 {time parsing} {
+    clock scan {2440588 i:00:01 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M:%S %p}
+} 46801
+test clock-29.1276 {time parsing} {
+    clock scan {2440588 i:?:i PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM:%OS %p}
+} 46801
+test clock-29.1277 {time parsing} {
+    clock scan {2440588 01:00:01 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M:%S %P}
+} 46801
+test clock-29.1278 {time parsing} {
+    clock scan {2440588 01:?:i pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM:%OS %P}
+} 46801
+test clock-29.1279 {time parsing} {
+    clock scan {2440588  1:00:01 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M:%S %P}
+} 46801
+test clock-29.1280 {time parsing} {
+    clock scan {2440588  1:?:i pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM:%OS %P}
+} 46801
+test clock-29.1281 {time parsing} {
+    clock scan {2440588 i:00:01 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M:%S %P}
+} 46801
+test clock-29.1282 {time parsing} {
+    clock scan {2440588 i:?:i pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM:%OS %P}
+} 46801
+test clock-29.1283 {time parsing} {
+    clock scan {2440588 i:00:01 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M:%S %P}
+} 46801
+test clock-29.1284 {time parsing} {
+    clock scan {2440588 i:?:i pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM:%OS %P}
+} 46801
+test clock-29.1285 {time parsing} {
+    clock scan {2440588 13:00:59 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%M:%S }
+} 46859
+test clock-29.1286 {time parsing} {
+    clock scan {2440588 13:?:lix } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%OM:%OS }
+} 46859
+test clock-29.1287 {time parsing} {
+    clock scan {2440588 13:00:59 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%M:%S }
+} 46859
+test clock-29.1288 {time parsing} {
+    clock scan {2440588 13:?:lix } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%OM:%OS }
+} 46859
+test clock-29.1289 {time parsing} {
+    clock scan {2440588 xiii:00:59 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%M:%S }
+} 46859
+test clock-29.1290 {time parsing} {
+    clock scan {2440588 xiii:?:lix } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%OM:%OS }
+} 46859
+test clock-29.1291 {time parsing} {
+    clock scan {2440588 xiii:00:59 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%M:%S }
+} 46859
+test clock-29.1292 {time parsing} {
+    clock scan {2440588 xiii:?:lix } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%OM:%OS }
+} 46859
+test clock-29.1293 {time parsing} {
+    clock scan {2440588 01:00:59 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M:%S %p}
+} 46859
+test clock-29.1294 {time parsing} {
+    clock scan {2440588 01:?:lix PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM:%OS %p}
+} 46859
+test clock-29.1295 {time parsing} {
+    clock scan {2440588  1:00:59 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M:%S %p}
+} 46859
+test clock-29.1296 {time parsing} {
+    clock scan {2440588  1:?:lix PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM:%OS %p}
+} 46859
+test clock-29.1297 {time parsing} {
+    clock scan {2440588 i:00:59 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M:%S %p}
+} 46859
+test clock-29.1298 {time parsing} {
+    clock scan {2440588 i:?:lix PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM:%OS %p}
+} 46859
+test clock-29.1299 {time parsing} {
+    clock scan {2440588 i:00:59 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M:%S %p}
+} 46859
+test clock-29.1300 {time parsing} {
+    clock scan {2440588 i:?:lix PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM:%OS %p}
+} 46859
+test clock-29.1301 {time parsing} {
+    clock scan {2440588 01:00:59 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M:%S %P}
+} 46859
+test clock-29.1302 {time parsing} {
+    clock scan {2440588 01:?:lix pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM:%OS %P}
+} 46859
+test clock-29.1303 {time parsing} {
+    clock scan {2440588  1:00:59 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M:%S %P}
+} 46859
+test clock-29.1304 {time parsing} {
+    clock scan {2440588  1:?:lix pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM:%OS %P}
+} 46859
+test clock-29.1305 {time parsing} {
+    clock scan {2440588 i:00:59 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M:%S %P}
+} 46859
+test clock-29.1306 {time parsing} {
+    clock scan {2440588 i:?:lix pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM:%OS %P}
+} 46859
+test clock-29.1307 {time parsing} {
+    clock scan {2440588 i:00:59 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M:%S %P}
+} 46859
+test clock-29.1308 {time parsing} {
+    clock scan {2440588 i:?:lix pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM:%OS %P}
+} 46859
+test clock-29.1309 {time parsing} {
+    clock scan {2440588 13:01 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%M }
+} 46860
+test clock-29.1310 {time parsing} {
+    clock scan {2440588 13:i } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%OM }
+} 46860
+test clock-29.1311 {time parsing} {
+    clock scan {2440588 13:01:00 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%M:%S }
+} 46860
+test clock-29.1312 {time parsing} {
+    clock scan {2440588 13:i:? } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%OM:%OS }
+} 46860
+test clock-29.1313 {time parsing} {
+    clock scan {2440588 13:01 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%M }
+} 46860
+test clock-29.1314 {time parsing} {
+    clock scan {2440588 13:i } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%OM }
+} 46860
+test clock-29.1315 {time parsing} {
+    clock scan {2440588 13:01:00 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%M:%S }
+} 46860
+test clock-29.1316 {time parsing} {
+    clock scan {2440588 13:i:? } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%OM:%OS }
+} 46860
+test clock-29.1317 {time parsing} {
+    clock scan {2440588 xiii:01 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%M }
+} 46860
+test clock-29.1318 {time parsing} {
+    clock scan {2440588 xiii:i } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%OM }
+} 46860
+test clock-29.1319 {time parsing} {
+    clock scan {2440588 xiii:01:00 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%M:%S }
+} 46860
+test clock-29.1320 {time parsing} {
+    clock scan {2440588 xiii:i:? } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%OM:%OS }
+} 46860
+test clock-29.1321 {time parsing} {
+    clock scan {2440588 xiii:01 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%M }
+} 46860
+test clock-29.1322 {time parsing} {
+    clock scan {2440588 xiii:i } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%OM }
+} 46860
+test clock-29.1323 {time parsing} {
+    clock scan {2440588 xiii:01:00 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%M:%S }
+} 46860
+test clock-29.1324 {time parsing} {
+    clock scan {2440588 xiii:i:? } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%OM:%OS }
+} 46860
+test clock-29.1325 {time parsing} {
+    clock scan {2440588 01:01 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M %p}
+} 46860
+test clock-29.1326 {time parsing} {
+    clock scan {2440588 01:i PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM %p}
+} 46860
+test clock-29.1327 {time parsing} {
+    clock scan {2440588 01:01:00 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M:%S %p}
+} 46860
+test clock-29.1328 {time parsing} {
+    clock scan {2440588 01:i:? PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM:%OS %p}
+} 46860
+test clock-29.1329 {time parsing} {
+    clock scan {2440588  1:01 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M %p}
+} 46860
+test clock-29.1330 {time parsing} {
+    clock scan {2440588  1:i PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM %p}
+} 46860
+test clock-29.1331 {time parsing} {
+    clock scan {2440588  1:01:00 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M:%S %p}
+} 46860
+test clock-29.1332 {time parsing} {
+    clock scan {2440588  1:i:? PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM:%OS %p}
+} 46860
+test clock-29.1333 {time parsing} {
+    clock scan {2440588 i:01 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M %p}
+} 46860
+test clock-29.1334 {time parsing} {
+    clock scan {2440588 i:i PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM %p}
+} 46860
+test clock-29.1335 {time parsing} {
+    clock scan {2440588 i:01:00 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M:%S %p}
+} 46860
+test clock-29.1336 {time parsing} {
+    clock scan {2440588 i:i:? PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM:%OS %p}
+} 46860
+test clock-29.1337 {time parsing} {
+    clock scan {2440588 i:01 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M %p}
+} 46860
+test clock-29.1338 {time parsing} {
+    clock scan {2440588 i:i PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM %p}
+} 46860
+test clock-29.1339 {time parsing} {
+    clock scan {2440588 i:01:00 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M:%S %p}
+} 46860
+test clock-29.1340 {time parsing} {
+    clock scan {2440588 i:i:? PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM:%OS %p}
+} 46860
+test clock-29.1341 {time parsing} {
+    clock scan {2440588 01:01 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M %P}
+} 46860
+test clock-29.1342 {time parsing} {
+    clock scan {2440588 01:i pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM %P}
+} 46860
+test clock-29.1343 {time parsing} {
+    clock scan {2440588 01:01:00 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M:%S %P}
+} 46860
+test clock-29.1344 {time parsing} {
+    clock scan {2440588 01:i:? pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM:%OS %P}
+} 46860
+test clock-29.1345 {time parsing} {
+    clock scan {2440588  1:01 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M %P}
+} 46860
+test clock-29.1346 {time parsing} {
+    clock scan {2440588  1:i pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM %P}
+} 46860
+test clock-29.1347 {time parsing} {
+    clock scan {2440588  1:01:00 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M:%S %P}
+} 46860
+test clock-29.1348 {time parsing} {
+    clock scan {2440588  1:i:? pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM:%OS %P}
+} 46860
+test clock-29.1349 {time parsing} {
+    clock scan {2440588 i:01 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M %P}
+} 46860
+test clock-29.1350 {time parsing} {
+    clock scan {2440588 i:i pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM %P}
+} 46860
+test clock-29.1351 {time parsing} {
+    clock scan {2440588 i:01:00 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M:%S %P}
+} 46860
+test clock-29.1352 {time parsing} {
+    clock scan {2440588 i:i:? pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM:%OS %P}
+} 46860
+test clock-29.1353 {time parsing} {
+    clock scan {2440588 i:01 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M %P}
+} 46860
+test clock-29.1354 {time parsing} {
+    clock scan {2440588 i:i pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM %P}
+} 46860
+test clock-29.1355 {time parsing} {
+    clock scan {2440588 i:01:00 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M:%S %P}
+} 46860
+test clock-29.1356 {time parsing} {
+    clock scan {2440588 i:i:? pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM:%OS %P}
+} 46860
+test clock-29.1357 {time parsing} {
+    clock scan {2440588 13:01:01 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%M:%S }
+} 46861
+test clock-29.1358 {time parsing} {
+    clock scan {2440588 13:i:i } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%OM:%OS }
+} 46861
+test clock-29.1359 {time parsing} {
+    clock scan {2440588 13:01:01 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%M:%S }
+} 46861
+test clock-29.1360 {time parsing} {
+    clock scan {2440588 13:i:i } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%OM:%OS }
+} 46861
+test clock-29.1361 {time parsing} {
+    clock scan {2440588 xiii:01:01 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%M:%S }
+} 46861
+test clock-29.1362 {time parsing} {
+    clock scan {2440588 xiii:i:i } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%OM:%OS }
+} 46861
+test clock-29.1363 {time parsing} {
+    clock scan {2440588 xiii:01:01 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%M:%S }
+} 46861
+test clock-29.1364 {time parsing} {
+    clock scan {2440588 xiii:i:i } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%OM:%OS }
+} 46861
+test clock-29.1365 {time parsing} {
+    clock scan {2440588 01:01:01 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M:%S %p}
+} 46861
+test clock-29.1366 {time parsing} {
+    clock scan {2440588 01:i:i PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM:%OS %p}
+} 46861
+test clock-29.1367 {time parsing} {
+    clock scan {2440588  1:01:01 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M:%S %p}
+} 46861
+test clock-29.1368 {time parsing} {
+    clock scan {2440588  1:i:i PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM:%OS %p}
+} 46861
+test clock-29.1369 {time parsing} {
+    clock scan {2440588 i:01:01 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M:%S %p}
+} 46861
+test clock-29.1370 {time parsing} {
+    clock scan {2440588 i:i:i PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM:%OS %p}
+} 46861
+test clock-29.1371 {time parsing} {
+    clock scan {2440588 i:01:01 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M:%S %p}
+} 46861
+test clock-29.1372 {time parsing} {
+    clock scan {2440588 i:i:i PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM:%OS %p}
+} 46861
+test clock-29.1373 {time parsing} {
+    clock scan {2440588 01:01:01 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M:%S %P}
+} 46861
+test clock-29.1374 {time parsing} {
+    clock scan {2440588 01:i:i pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM:%OS %P}
+} 46861
+test clock-29.1375 {time parsing} {
+    clock scan {2440588  1:01:01 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M:%S %P}
+} 46861
+test clock-29.1376 {time parsing} {
+    clock scan {2440588  1:i:i pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM:%OS %P}
+} 46861
+test clock-29.1377 {time parsing} {
+    clock scan {2440588 i:01:01 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M:%S %P}
+} 46861
+test clock-29.1378 {time parsing} {
+    clock scan {2440588 i:i:i pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM:%OS %P}
+} 46861
+test clock-29.1379 {time parsing} {
+    clock scan {2440588 i:01:01 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M:%S %P}
+} 46861
+test clock-29.1380 {time parsing} {
+    clock scan {2440588 i:i:i pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM:%OS %P}
+} 46861
+test clock-29.1381 {time parsing} {
+    clock scan {2440588 13:01:59 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%M:%S }
+} 46919
+test clock-29.1382 {time parsing} {
+    clock scan {2440588 13:i:lix } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%OM:%OS }
+} 46919
+test clock-29.1383 {time parsing} {
+    clock scan {2440588 13:01:59 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%M:%S }
+} 46919
+test clock-29.1384 {time parsing} {
+    clock scan {2440588 13:i:lix } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%OM:%OS }
+} 46919
+test clock-29.1385 {time parsing} {
+    clock scan {2440588 xiii:01:59 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%M:%S }
+} 46919
+test clock-29.1386 {time parsing} {
+    clock scan {2440588 xiii:i:lix } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%OM:%OS }
+} 46919
+test clock-29.1387 {time parsing} {
+    clock scan {2440588 xiii:01:59 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%M:%S }
+} 46919
+test clock-29.1388 {time parsing} {
+    clock scan {2440588 xiii:i:lix } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%OM:%OS }
+} 46919
+test clock-29.1389 {time parsing} {
+    clock scan {2440588 01:01:59 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M:%S %p}
+} 46919
+test clock-29.1390 {time parsing} {
+    clock scan {2440588 01:i:lix PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM:%OS %p}
+} 46919
+test clock-29.1391 {time parsing} {
+    clock scan {2440588  1:01:59 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M:%S %p}
+} 46919
+test clock-29.1392 {time parsing} {
+    clock scan {2440588  1:i:lix PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM:%OS %p}
+} 46919
+test clock-29.1393 {time parsing} {
+    clock scan {2440588 i:01:59 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M:%S %p}
+} 46919
+test clock-29.1394 {time parsing} {
+    clock scan {2440588 i:i:lix PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM:%OS %p}
+} 46919
+test clock-29.1395 {time parsing} {
+    clock scan {2440588 i:01:59 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M:%S %p}
+} 46919
+test clock-29.1396 {time parsing} {
+    clock scan {2440588 i:i:lix PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM:%OS %p}
+} 46919
+test clock-29.1397 {time parsing} {
+    clock scan {2440588 01:01:59 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M:%S %P}
+} 46919
+test clock-29.1398 {time parsing} {
+    clock scan {2440588 01:i:lix pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM:%OS %P}
+} 46919
+test clock-29.1399 {time parsing} {
+    clock scan {2440588  1:01:59 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M:%S %P}
+} 46919
+test clock-29.1400 {time parsing} {
+    clock scan {2440588  1:i:lix pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM:%OS %P}
+} 46919
+test clock-29.1401 {time parsing} {
+    clock scan {2440588 i:01:59 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M:%S %P}
+} 46919
+test clock-29.1402 {time parsing} {
+    clock scan {2440588 i:i:lix pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM:%OS %P}
+} 46919
+test clock-29.1403 {time parsing} {
+    clock scan {2440588 i:01:59 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M:%S %P}
+} 46919
+test clock-29.1404 {time parsing} {
+    clock scan {2440588 i:i:lix pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM:%OS %P}
+} 46919
+test clock-29.1405 {time parsing} {
+    clock scan {2440588 13:59 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%M }
+} 50340
+test clock-29.1406 {time parsing} {
+    clock scan {2440588 13:lix } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%OM }
+} 50340
+test clock-29.1407 {time parsing} {
+    clock scan {2440588 13:59:00 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%M:%S }
+} 50340
+test clock-29.1408 {time parsing} {
+    clock scan {2440588 13:lix:? } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%OM:%OS }
+} 50340
+test clock-29.1409 {time parsing} {
+    clock scan {2440588 13:59 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%M }
+} 50340
+test clock-29.1410 {time parsing} {
+    clock scan {2440588 13:lix } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%OM }
+} 50340
+test clock-29.1411 {time parsing} {
+    clock scan {2440588 13:59:00 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%M:%S }
+} 50340
+test clock-29.1412 {time parsing} {
+    clock scan {2440588 13:lix:? } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%OM:%OS }
+} 50340
+test clock-29.1413 {time parsing} {
+    clock scan {2440588 xiii:59 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%M }
+} 50340
+test clock-29.1414 {time parsing} {
+    clock scan {2440588 xiii:lix } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%OM }
+} 50340
+test clock-29.1415 {time parsing} {
+    clock scan {2440588 xiii:59:00 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%M:%S }
+} 50340
+test clock-29.1416 {time parsing} {
+    clock scan {2440588 xiii:lix:? } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%OM:%OS }
+} 50340
+test clock-29.1417 {time parsing} {
+    clock scan {2440588 xiii:59 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%M }
+} 50340
+test clock-29.1418 {time parsing} {
+    clock scan {2440588 xiii:lix } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%OM }
+} 50340
+test clock-29.1419 {time parsing} {
+    clock scan {2440588 xiii:59:00 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%M:%S }
+} 50340
+test clock-29.1420 {time parsing} {
+    clock scan {2440588 xiii:lix:? } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%OM:%OS }
+} 50340
+test clock-29.1421 {time parsing} {
+    clock scan {2440588 01:59 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M %p}
+} 50340
+test clock-29.1422 {time parsing} {
+    clock scan {2440588 01:lix PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM %p}
+} 50340
+test clock-29.1423 {time parsing} {
+    clock scan {2440588 01:59:00 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M:%S %p}
+} 50340
+test clock-29.1424 {time parsing} {
+    clock scan {2440588 01:lix:? PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM:%OS %p}
+} 50340
+test clock-29.1425 {time parsing} {
+    clock scan {2440588  1:59 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M %p}
+} 50340
+test clock-29.1426 {time parsing} {
+    clock scan {2440588  1:lix PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM %p}
+} 50340
+test clock-29.1427 {time parsing} {
+    clock scan {2440588  1:59:00 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M:%S %p}
+} 50340
+test clock-29.1428 {time parsing} {
+    clock scan {2440588  1:lix:? PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM:%OS %p}
+} 50340
+test clock-29.1429 {time parsing} {
+    clock scan {2440588 i:59 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M %p}
+} 50340
+test clock-29.1430 {time parsing} {
+    clock scan {2440588 i:lix PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM %p}
+} 50340
+test clock-29.1431 {time parsing} {
+    clock scan {2440588 i:59:00 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M:%S %p}
+} 50340
+test clock-29.1432 {time parsing} {
+    clock scan {2440588 i:lix:? PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM:%OS %p}
+} 50340
+test clock-29.1433 {time parsing} {
+    clock scan {2440588 i:59 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M %p}
+} 50340
+test clock-29.1434 {time parsing} {
+    clock scan {2440588 i:lix PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM %p}
+} 50340
+test clock-29.1435 {time parsing} {
+    clock scan {2440588 i:59:00 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M:%S %p}
+} 50340
+test clock-29.1436 {time parsing} {
+    clock scan {2440588 i:lix:? PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM:%OS %p}
+} 50340
+test clock-29.1437 {time parsing} {
+    clock scan {2440588 01:59 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M %P}
+} 50340
+test clock-29.1438 {time parsing} {
+    clock scan {2440588 01:lix pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM %P}
+} 50340
+test clock-29.1439 {time parsing} {
+    clock scan {2440588 01:59:00 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M:%S %P}
+} 50340
+test clock-29.1440 {time parsing} {
+    clock scan {2440588 01:lix:? pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM:%OS %P}
+} 50340
+test clock-29.1441 {time parsing} {
+    clock scan {2440588  1:59 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M %P}
+} 50340
+test clock-29.1442 {time parsing} {
+    clock scan {2440588  1:lix pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM %P}
+} 50340
+test clock-29.1443 {time parsing} {
+    clock scan {2440588  1:59:00 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M:%S %P}
+} 50340
+test clock-29.1444 {time parsing} {
+    clock scan {2440588  1:lix:? pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM:%OS %P}
+} 50340
+test clock-29.1445 {time parsing} {
+    clock scan {2440588 i:59 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M %P}
+} 50340
+test clock-29.1446 {time parsing} {
+    clock scan {2440588 i:lix pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM %P}
+} 50340
+test clock-29.1447 {time parsing} {
+    clock scan {2440588 i:59:00 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M:%S %P}
+} 50340
+test clock-29.1448 {time parsing} {
+    clock scan {2440588 i:lix:? pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM:%OS %P}
+} 50340
+test clock-29.1449 {time parsing} {
+    clock scan {2440588 i:59 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M %P}
+} 50340
+test clock-29.1450 {time parsing} {
+    clock scan {2440588 i:lix pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM %P}
+} 50340
+test clock-29.1451 {time parsing} {
+    clock scan {2440588 i:59:00 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M:%S %P}
+} 50340
+test clock-29.1452 {time parsing} {
+    clock scan {2440588 i:lix:? pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM:%OS %P}
+} 50340
+test clock-29.1453 {time parsing} {
+    clock scan {2440588 13:59:01 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%M:%S }
+} 50341
+test clock-29.1454 {time parsing} {
+    clock scan {2440588 13:lix:i } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%OM:%OS }
+} 50341
+test clock-29.1455 {time parsing} {
+    clock scan {2440588 13:59:01 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%M:%S }
+} 50341
+test clock-29.1456 {time parsing} {
+    clock scan {2440588 13:lix:i } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%OM:%OS }
+} 50341
+test clock-29.1457 {time parsing} {
+    clock scan {2440588 xiii:59:01 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%M:%S }
+} 50341
+test clock-29.1458 {time parsing} {
+    clock scan {2440588 xiii:lix:i } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%OM:%OS }
+} 50341
+test clock-29.1459 {time parsing} {
+    clock scan {2440588 xiii:59:01 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%M:%S }
+} 50341
+test clock-29.1460 {time parsing} {
+    clock scan {2440588 xiii:lix:i } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%OM:%OS }
+} 50341
+test clock-29.1461 {time parsing} {
+    clock scan {2440588 01:59:01 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M:%S %p}
+} 50341
+test clock-29.1462 {time parsing} {
+    clock scan {2440588 01:lix:i PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM:%OS %p}
+} 50341
+test clock-29.1463 {time parsing} {
+    clock scan {2440588  1:59:01 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M:%S %p}
+} 50341
+test clock-29.1464 {time parsing} {
+    clock scan {2440588  1:lix:i PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM:%OS %p}
+} 50341
+test clock-29.1465 {time parsing} {
+    clock scan {2440588 i:59:01 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M:%S %p}
+} 50341
+test clock-29.1466 {time parsing} {
+    clock scan {2440588 i:lix:i PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM:%OS %p}
+} 50341
+test clock-29.1467 {time parsing} {
+    clock scan {2440588 i:59:01 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M:%S %p}
+} 50341
+test clock-29.1468 {time parsing} {
+    clock scan {2440588 i:lix:i PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM:%OS %p}
+} 50341
+test clock-29.1469 {time parsing} {
+    clock scan {2440588 01:59:01 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M:%S %P}
+} 50341
+test clock-29.1470 {time parsing} {
+    clock scan {2440588 01:lix:i pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM:%OS %P}
+} 50341
+test clock-29.1471 {time parsing} {
+    clock scan {2440588  1:59:01 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M:%S %P}
+} 50341
+test clock-29.1472 {time parsing} {
+    clock scan {2440588  1:lix:i pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM:%OS %P}
+} 50341
+test clock-29.1473 {time parsing} {
+    clock scan {2440588 i:59:01 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M:%S %P}
+} 50341
+test clock-29.1474 {time parsing} {
+    clock scan {2440588 i:lix:i pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM:%OS %P}
+} 50341
+test clock-29.1475 {time parsing} {
+    clock scan {2440588 i:59:01 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M:%S %P}
+} 50341
+test clock-29.1476 {time parsing} {
+    clock scan {2440588 i:lix:i pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM:%OS %P}
+} 50341
+test clock-29.1477 {time parsing} {
+    clock scan {2440588 13:59:59 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%M:%S }
+} 50399
+test clock-29.1478 {time parsing} {
+    clock scan {2440588 13:lix:lix } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%OM:%OS }
+} 50399
+test clock-29.1479 {time parsing} {
+    clock scan {2440588 13:59:59 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%M:%S }
+} 50399
+test clock-29.1480 {time parsing} {
+    clock scan {2440588 13:lix:lix } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%OM:%OS }
+} 50399
+test clock-29.1481 {time parsing} {
+    clock scan {2440588 xiii:59:59 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%M:%S }
+} 50399
+test clock-29.1482 {time parsing} {
+    clock scan {2440588 xiii:lix:lix } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%OM:%OS }
+} 50399
+test clock-29.1483 {time parsing} {
+    clock scan {2440588 xiii:59:59 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%M:%S }
+} 50399
+test clock-29.1484 {time parsing} {
+    clock scan {2440588 xiii:lix:lix } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%OM:%OS }
+} 50399
+test clock-29.1485 {time parsing} {
+    clock scan {2440588 01:59:59 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M:%S %p}
+} 50399
+test clock-29.1486 {time parsing} {
+    clock scan {2440588 01:lix:lix PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM:%OS %p}
+} 50399
+test clock-29.1487 {time parsing} {
+    clock scan {2440588  1:59:59 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M:%S %p}
+} 50399
+test clock-29.1488 {time parsing} {
+    clock scan {2440588  1:lix:lix PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM:%OS %p}
+} 50399
+test clock-29.1489 {time parsing} {
+    clock scan {2440588 i:59:59 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M:%S %p}
+} 50399
+test clock-29.1490 {time parsing} {
+    clock scan {2440588 i:lix:lix PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM:%OS %p}
+} 50399
+test clock-29.1491 {time parsing} {
+    clock scan {2440588 i:59:59 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M:%S %p}
+} 50399
+test clock-29.1492 {time parsing} {
+    clock scan {2440588 i:lix:lix PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM:%OS %p}
+} 50399
+test clock-29.1493 {time parsing} {
+    clock scan {2440588 01:59:59 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M:%S %P}
+} 50399
+test clock-29.1494 {time parsing} {
+    clock scan {2440588 01:lix:lix pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM:%OS %P}
+} 50399
+test clock-29.1495 {time parsing} {
+    clock scan {2440588  1:59:59 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M:%S %P}
+} 50399
+test clock-29.1496 {time parsing} {
+    clock scan {2440588  1:lix:lix pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM:%OS %P}
+} 50399
+test clock-29.1497 {time parsing} {
+    clock scan {2440588 i:59:59 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M:%S %P}
+} 50399
+test clock-29.1498 {time parsing} {
+    clock scan {2440588 i:lix:lix pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM:%OS %P}
+} 50399
+test clock-29.1499 {time parsing} {
+    clock scan {2440588 i:59:59 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M:%S %P}
+} 50399
+test clock-29.1500 {time parsing} {
+    clock scan {2440588 i:lix:lix pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM:%OS %P}
+} 50399
+test clock-29.1501 {time parsing} {
+    clock scan {2440588 23 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H }
+} 82800
+test clock-29.1502 {time parsing} {
+    clock scan {2440588 23:00 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%M }
+} 82800
+test clock-29.1503 {time parsing} {
+    clock scan {2440588 23:? } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%OM }
+} 82800
+test clock-29.1504 {time parsing} {
+    clock scan {2440588 23:00:00 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%M:%S }
+} 82800
+test clock-29.1505 {time parsing} {
+    clock scan {2440588 23:?:? } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%OM:%OS }
+} 82800
+test clock-29.1506 {time parsing} {
+    clock scan {2440588 23 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k }
+} 82800
+test clock-29.1507 {time parsing} {
+    clock scan {2440588 23:00 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%M }
+} 82800
+test clock-29.1508 {time parsing} {
+    clock scan {2440588 23:? } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%OM }
+} 82800
+test clock-29.1509 {time parsing} {
+    clock scan {2440588 23:00:00 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%M:%S }
+} 82800
+test clock-29.1510 {time parsing} {
+    clock scan {2440588 23:?:? } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%OM:%OS }
+} 82800
+test clock-29.1511 {time parsing} {
+    clock scan {2440588 xxiii } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH }
+} 82800
+test clock-29.1512 {time parsing} {
+    clock scan {2440588 xxiii:00 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%M }
+} 82800
+test clock-29.1513 {time parsing} {
+    clock scan {2440588 xxiii:? } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%OM }
+} 82800
+test clock-29.1514 {time parsing} {
+    clock scan {2440588 xxiii:00:00 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%M:%S }
+} 82800
+test clock-29.1515 {time parsing} {
+    clock scan {2440588 xxiii:?:? } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%OM:%OS }
+} 82800
+test clock-29.1516 {time parsing} {
+    clock scan {2440588 xxiii } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok }
+} 82800
+test clock-29.1517 {time parsing} {
+    clock scan {2440588 xxiii:00 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%M }
+} 82800
+test clock-29.1518 {time parsing} {
+    clock scan {2440588 xxiii:? } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%OM }
+} 82800
+test clock-29.1519 {time parsing} {
+    clock scan {2440588 xxiii:00:00 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%M:%S }
+} 82800
+test clock-29.1520 {time parsing} {
+    clock scan {2440588 xxiii:?:? } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%OM:%OS }
+} 82800
+test clock-29.1521 {time parsing} {
+    clock scan {2440588 11 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I %p}
+} 82800
+test clock-29.1522 {time parsing} {
+    clock scan {2440588 11:00 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M %p}
+} 82800
+test clock-29.1523 {time parsing} {
+    clock scan {2440588 11:? PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM %p}
+} 82800
+test clock-29.1524 {time parsing} {
+    clock scan {2440588 11:00:00 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M:%S %p}
+} 82800
+test clock-29.1525 {time parsing} {
+    clock scan {2440588 11:?:? PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM:%OS %p}
+} 82800
+test clock-29.1526 {time parsing} {
+    clock scan {2440588 11 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l %p}
+} 82800
+test clock-29.1527 {time parsing} {
+    clock scan {2440588 11:00 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M %p}
+} 82800
+test clock-29.1528 {time parsing} {
+    clock scan {2440588 11:? PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM %p}
+} 82800
+test clock-29.1529 {time parsing} {
+    clock scan {2440588 11:00:00 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M:%S %p}
+} 82800
+test clock-29.1530 {time parsing} {
+    clock scan {2440588 11:?:? PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM:%OS %p}
+} 82800
+test clock-29.1531 {time parsing} {
+    clock scan {2440588 xi PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI %p}
+} 82800
+test clock-29.1532 {time parsing} {
+    clock scan {2440588 xi:00 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M %p}
+} 82800
+test clock-29.1533 {time parsing} {
+    clock scan {2440588 xi:? PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM %p}
+} 82800
+test clock-29.1534 {time parsing} {
+    clock scan {2440588 xi:00:00 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M:%S %p}
+} 82800
+test clock-29.1535 {time parsing} {
+    clock scan {2440588 xi:?:? PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM:%OS %p}
+} 82800
+test clock-29.1536 {time parsing} {
+    clock scan {2440588 xi PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol %p}
+} 82800
+test clock-29.1537 {time parsing} {
+    clock scan {2440588 xi:00 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M %p}
+} 82800
+test clock-29.1538 {time parsing} {
+    clock scan {2440588 xi:? PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM %p}
+} 82800
+test clock-29.1539 {time parsing} {
+    clock scan {2440588 xi:00:00 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M:%S %p}
+} 82800
+test clock-29.1540 {time parsing} {
+    clock scan {2440588 xi:?:? PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM:%OS %p}
+} 82800
+test clock-29.1541 {time parsing} {
+    clock scan {2440588 11 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I %P}
+} 82800
+test clock-29.1542 {time parsing} {
+    clock scan {2440588 11:00 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M %P}
+} 82800
+test clock-29.1543 {time parsing} {
+    clock scan {2440588 11:? pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM %P}
+} 82800
+test clock-29.1544 {time parsing} {
+    clock scan {2440588 11:00:00 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M:%S %P}
+} 82800
+test clock-29.1545 {time parsing} {
+    clock scan {2440588 11:?:? pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM:%OS %P}
+} 82800
+test clock-29.1546 {time parsing} {
+    clock scan {2440588 11 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l %P}
+} 82800
+test clock-29.1547 {time parsing} {
+    clock scan {2440588 11:00 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M %P}
+} 82800
+test clock-29.1548 {time parsing} {
+    clock scan {2440588 11:? pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM %P}
+} 82800
+test clock-29.1549 {time parsing} {
+    clock scan {2440588 11:00:00 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M:%S %P}
+} 82800
+test clock-29.1550 {time parsing} {
+    clock scan {2440588 11:?:? pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM:%OS %P}
+} 82800
+test clock-29.1551 {time parsing} {
+    clock scan {2440588 xi pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI %P}
+} 82800
+test clock-29.1552 {time parsing} {
+    clock scan {2440588 xi:00 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M %P}
+} 82800
+test clock-29.1553 {time parsing} {
+    clock scan {2440588 xi:? pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM %P}
+} 82800
+test clock-29.1554 {time parsing} {
+    clock scan {2440588 xi:00:00 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M:%S %P}
+} 82800
+test clock-29.1555 {time parsing} {
+    clock scan {2440588 xi:?:? pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM:%OS %P}
+} 82800
+test clock-29.1556 {time parsing} {
+    clock scan {2440588 xi pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol %P}
+} 82800
+test clock-29.1557 {time parsing} {
+    clock scan {2440588 xi:00 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M %P}
+} 82800
+test clock-29.1558 {time parsing} {
+    clock scan {2440588 xi:? pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM %P}
+} 82800
+test clock-29.1559 {time parsing} {
+    clock scan {2440588 xi:00:00 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M:%S %P}
+} 82800
+test clock-29.1560 {time parsing} {
+    clock scan {2440588 xi:?:? pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM:%OS %P}
+} 82800
+test clock-29.1561 {time parsing} {
+    clock scan {2440588 23:00:01 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%M:%S }
+} 82801
+test clock-29.1562 {time parsing} {
+    clock scan {2440588 23:?:i } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%OM:%OS }
+} 82801
+test clock-29.1563 {time parsing} {
+    clock scan {2440588 23:00:01 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%M:%S }
+} 82801
+test clock-29.1564 {time parsing} {
+    clock scan {2440588 23:?:i } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%OM:%OS }
+} 82801
+test clock-29.1565 {time parsing} {
+    clock scan {2440588 xxiii:00:01 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%M:%S }
+} 82801
+test clock-29.1566 {time parsing} {
+    clock scan {2440588 xxiii:?:i } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%OM:%OS }
+} 82801
+test clock-29.1567 {time parsing} {
+    clock scan {2440588 xxiii:00:01 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%M:%S }
+} 82801
+test clock-29.1568 {time parsing} {
+    clock scan {2440588 xxiii:?:i } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%OM:%OS }
+} 82801
+test clock-29.1569 {time parsing} {
+    clock scan {2440588 11:00:01 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M:%S %p}
+} 82801
+test clock-29.1570 {time parsing} {
+    clock scan {2440588 11:?:i PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM:%OS %p}
+} 82801
+test clock-29.1571 {time parsing} {
+    clock scan {2440588 11:00:01 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M:%S %p}
+} 82801
+test clock-29.1572 {time parsing} {
+    clock scan {2440588 11:?:i PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM:%OS %p}
+} 82801
+test clock-29.1573 {time parsing} {
+    clock scan {2440588 xi:00:01 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M:%S %p}
+} 82801
+test clock-29.1574 {time parsing} {
+    clock scan {2440588 xi:?:i PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM:%OS %p}
+} 82801
+test clock-29.1575 {time parsing} {
+    clock scan {2440588 xi:00:01 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M:%S %p}
+} 82801
+test clock-29.1576 {time parsing} {
+    clock scan {2440588 xi:?:i PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM:%OS %p}
+} 82801
+test clock-29.1577 {time parsing} {
+    clock scan {2440588 11:00:01 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M:%S %P}
+} 82801
+test clock-29.1578 {time parsing} {
+    clock scan {2440588 11:?:i pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM:%OS %P}
+} 82801
+test clock-29.1579 {time parsing} {
+    clock scan {2440588 11:00:01 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M:%S %P}
+} 82801
+test clock-29.1580 {time parsing} {
+    clock scan {2440588 11:?:i pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM:%OS %P}
+} 82801
+test clock-29.1581 {time parsing} {
+    clock scan {2440588 xi:00:01 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M:%S %P}
+} 82801
+test clock-29.1582 {time parsing} {
+    clock scan {2440588 xi:?:i pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM:%OS %P}
+} 82801
+test clock-29.1583 {time parsing} {
+    clock scan {2440588 xi:00:01 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M:%S %P}
+} 82801
+test clock-29.1584 {time parsing} {
+    clock scan {2440588 xi:?:i pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM:%OS %P}
+} 82801
+test clock-29.1585 {time parsing} {
+    clock scan {2440588 23:00:59 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%M:%S }
+} 82859
+test clock-29.1586 {time parsing} {
+    clock scan {2440588 23:?:lix } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%OM:%OS }
+} 82859
+test clock-29.1587 {time parsing} {
+    clock scan {2440588 23:00:59 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%M:%S }
+} 82859
+test clock-29.1588 {time parsing} {
+    clock scan {2440588 23:?:lix } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%OM:%OS }
+} 82859
+test clock-29.1589 {time parsing} {
+    clock scan {2440588 xxiii:00:59 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%M:%S }
+} 82859
+test clock-29.1590 {time parsing} {
+    clock scan {2440588 xxiii:?:lix } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%OM:%OS }
+} 82859
+test clock-29.1591 {time parsing} {
+    clock scan {2440588 xxiii:00:59 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%M:%S }
+} 82859
+test clock-29.1592 {time parsing} {
+    clock scan {2440588 xxiii:?:lix } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%OM:%OS }
+} 82859
+test clock-29.1593 {time parsing} {
+    clock scan {2440588 11:00:59 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M:%S %p}
+} 82859
+test clock-29.1594 {time parsing} {
+    clock scan {2440588 11:?:lix PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM:%OS %p}
+} 82859
+test clock-29.1595 {time parsing} {
+    clock scan {2440588 11:00:59 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M:%S %p}
+} 82859
+test clock-29.1596 {time parsing} {
+    clock scan {2440588 11:?:lix PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM:%OS %p}
+} 82859
+test clock-29.1597 {time parsing} {
+    clock scan {2440588 xi:00:59 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M:%S %p}
+} 82859
+test clock-29.1598 {time parsing} {
+    clock scan {2440588 xi:?:lix PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM:%OS %p}
+} 82859
+test clock-29.1599 {time parsing} {
+    clock scan {2440588 xi:00:59 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M:%S %p}
+} 82859
+test clock-29.1600 {time parsing} {
+    clock scan {2440588 xi:?:lix PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM:%OS %p}
+} 82859
+test clock-29.1601 {time parsing} {
+    clock scan {2440588 11:00:59 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M:%S %P}
+} 82859
+test clock-29.1602 {time parsing} {
+    clock scan {2440588 11:?:lix pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM:%OS %P}
+} 82859
+test clock-29.1603 {time parsing} {
+    clock scan {2440588 11:00:59 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M:%S %P}
+} 82859
+test clock-29.1604 {time parsing} {
+    clock scan {2440588 11:?:lix pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM:%OS %P}
+} 82859
+test clock-29.1605 {time parsing} {
+    clock scan {2440588 xi:00:59 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M:%S %P}
+} 82859
+test clock-29.1606 {time parsing} {
+    clock scan {2440588 xi:?:lix pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM:%OS %P}
+} 82859
+test clock-29.1607 {time parsing} {
+    clock scan {2440588 xi:00:59 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M:%S %P}
+} 82859
+test clock-29.1608 {time parsing} {
+    clock scan {2440588 xi:?:lix pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM:%OS %P}
+} 82859
+test clock-29.1609 {time parsing} {
+    clock scan {2440588 23:01 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%M }
+} 82860
+test clock-29.1610 {time parsing} {
+    clock scan {2440588 23:i } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%OM }
+} 82860
+test clock-29.1611 {time parsing} {
+    clock scan {2440588 23:01:00 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%M:%S }
+} 82860
+test clock-29.1612 {time parsing} {
+    clock scan {2440588 23:i:? } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%OM:%OS }
+} 82860
+test clock-29.1613 {time parsing} {
+    clock scan {2440588 23:01 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%M }
+} 82860
+test clock-29.1614 {time parsing} {
+    clock scan {2440588 23:i } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%OM }
+} 82860
+test clock-29.1615 {time parsing} {
+    clock scan {2440588 23:01:00 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%M:%S }
+} 82860
+test clock-29.1616 {time parsing} {
+    clock scan {2440588 23:i:? } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%OM:%OS }
+} 82860
+test clock-29.1617 {time parsing} {
+    clock scan {2440588 xxiii:01 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%M }
+} 82860
+test clock-29.1618 {time parsing} {
+    clock scan {2440588 xxiii:i } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%OM }
+} 82860
+test clock-29.1619 {time parsing} {
+    clock scan {2440588 xxiii:01:00 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%M:%S }
+} 82860
+test clock-29.1620 {time parsing} {
+    clock scan {2440588 xxiii:i:? } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%OM:%OS }
+} 82860
+test clock-29.1621 {time parsing} {
+    clock scan {2440588 xxiii:01 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%M }
+} 82860
+test clock-29.1622 {time parsing} {
+    clock scan {2440588 xxiii:i } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%OM }
+} 82860
+test clock-29.1623 {time parsing} {
+    clock scan {2440588 xxiii:01:00 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%M:%S }
+} 82860
+test clock-29.1624 {time parsing} {
+    clock scan {2440588 xxiii:i:? } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%OM:%OS }
+} 82860
+test clock-29.1625 {time parsing} {
+    clock scan {2440588 11:01 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M %p}
+} 82860
+test clock-29.1626 {time parsing} {
+    clock scan {2440588 11:i PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM %p}
+} 82860
+test clock-29.1627 {time parsing} {
+    clock scan {2440588 11:01:00 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M:%S %p}
+} 82860
+test clock-29.1628 {time parsing} {
+    clock scan {2440588 11:i:? PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM:%OS %p}
+} 82860
+test clock-29.1629 {time parsing} {
+    clock scan {2440588 11:01 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M %p}
+} 82860
+test clock-29.1630 {time parsing} {
+    clock scan {2440588 11:i PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM %p}
+} 82860
+test clock-29.1631 {time parsing} {
+    clock scan {2440588 11:01:00 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M:%S %p}
+} 82860
+test clock-29.1632 {time parsing} {
+    clock scan {2440588 11:i:? PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM:%OS %p}
+} 82860
+test clock-29.1633 {time parsing} {
+    clock scan {2440588 xi:01 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M %p}
+} 82860
+test clock-29.1634 {time parsing} {
+    clock scan {2440588 xi:i PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM %p}
+} 82860
+test clock-29.1635 {time parsing} {
+    clock scan {2440588 xi:01:00 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M:%S %p}
+} 82860
+test clock-29.1636 {time parsing} {
+    clock scan {2440588 xi:i:? PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM:%OS %p}
+} 82860
+test clock-29.1637 {time parsing} {
+    clock scan {2440588 xi:01 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M %p}
+} 82860
+test clock-29.1638 {time parsing} {
+    clock scan {2440588 xi:i PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM %p}
+} 82860
+test clock-29.1639 {time parsing} {
+    clock scan {2440588 xi:01:00 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M:%S %p}
+} 82860
+test clock-29.1640 {time parsing} {
+    clock scan {2440588 xi:i:? PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM:%OS %p}
+} 82860
+test clock-29.1641 {time parsing} {
+    clock scan {2440588 11:01 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M %P}
+} 82860
+test clock-29.1642 {time parsing} {
+    clock scan {2440588 11:i pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM %P}
+} 82860
+test clock-29.1643 {time parsing} {
+    clock scan {2440588 11:01:00 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M:%S %P}
+} 82860
+test clock-29.1644 {time parsing} {
+    clock scan {2440588 11:i:? pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM:%OS %P}
+} 82860
+test clock-29.1645 {time parsing} {
+    clock scan {2440588 11:01 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M %P}
+} 82860
+test clock-29.1646 {time parsing} {
+    clock scan {2440588 11:i pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM %P}
+} 82860
+test clock-29.1647 {time parsing} {
+    clock scan {2440588 11:01:00 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M:%S %P}
+} 82860
+test clock-29.1648 {time parsing} {
+    clock scan {2440588 11:i:? pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM:%OS %P}
+} 82860
+test clock-29.1649 {time parsing} {
+    clock scan {2440588 xi:01 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M %P}
+} 82860
+test clock-29.1650 {time parsing} {
+    clock scan {2440588 xi:i pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM %P}
+} 82860
+test clock-29.1651 {time parsing} {
+    clock scan {2440588 xi:01:00 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M:%S %P}
+} 82860
+test clock-29.1652 {time parsing} {
+    clock scan {2440588 xi:i:? pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM:%OS %P}
+} 82860
+test clock-29.1653 {time parsing} {
+    clock scan {2440588 xi:01 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M %P}
+} 82860
+test clock-29.1654 {time parsing} {
+    clock scan {2440588 xi:i pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM %P}
+} 82860
+test clock-29.1655 {time parsing} {
+    clock scan {2440588 xi:01:00 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M:%S %P}
+} 82860
+test clock-29.1656 {time parsing} {
+    clock scan {2440588 xi:i:? pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM:%OS %P}
+} 82860
+test clock-29.1657 {time parsing} {
+    clock scan {2440588 23:01:01 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%M:%S }
+} 82861
+test clock-29.1658 {time parsing} {
+    clock scan {2440588 23:i:i } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%OM:%OS }
+} 82861
+test clock-29.1659 {time parsing} {
+    clock scan {2440588 23:01:01 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%M:%S }
+} 82861
+test clock-29.1660 {time parsing} {
+    clock scan {2440588 23:i:i } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%OM:%OS }
+} 82861
+test clock-29.1661 {time parsing} {
+    clock scan {2440588 xxiii:01:01 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%M:%S }
+} 82861
+test clock-29.1662 {time parsing} {
+    clock scan {2440588 xxiii:i:i } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%OM:%OS }
+} 82861
+test clock-29.1663 {time parsing} {
+    clock scan {2440588 xxiii:01:01 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%M:%S }
+} 82861
+test clock-29.1664 {time parsing} {
+    clock scan {2440588 xxiii:i:i } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%OM:%OS }
+} 82861
+test clock-29.1665 {time parsing} {
+    clock scan {2440588 11:01:01 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M:%S %p}
+} 82861
+test clock-29.1666 {time parsing} {
+    clock scan {2440588 11:i:i PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM:%OS %p}
+} 82861
+test clock-29.1667 {time parsing} {
+    clock scan {2440588 11:01:01 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M:%S %p}
+} 82861
+test clock-29.1668 {time parsing} {
+    clock scan {2440588 11:i:i PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM:%OS %p}
+} 82861
+test clock-29.1669 {time parsing} {
+    clock scan {2440588 xi:01:01 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M:%S %p}
+} 82861
+test clock-29.1670 {time parsing} {
+    clock scan {2440588 xi:i:i PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM:%OS %p}
+} 82861
+test clock-29.1671 {time parsing} {
+    clock scan {2440588 xi:01:01 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M:%S %p}
+} 82861
+test clock-29.1672 {time parsing} {
+    clock scan {2440588 xi:i:i PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM:%OS %p}
+} 82861
+test clock-29.1673 {time parsing} {
+    clock scan {2440588 11:01:01 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M:%S %P}
+} 82861
+test clock-29.1674 {time parsing} {
+    clock scan {2440588 11:i:i pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM:%OS %P}
+} 82861
+test clock-29.1675 {time parsing} {
+    clock scan {2440588 11:01:01 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M:%S %P}
+} 82861
+test clock-29.1676 {time parsing} {
+    clock scan {2440588 11:i:i pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM:%OS %P}
+} 82861
+test clock-29.1677 {time parsing} {
+    clock scan {2440588 xi:01:01 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M:%S %P}
+} 82861
+test clock-29.1678 {time parsing} {
+    clock scan {2440588 xi:i:i pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM:%OS %P}
+} 82861
+test clock-29.1679 {time parsing} {
+    clock scan {2440588 xi:01:01 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M:%S %P}
+} 82861
+test clock-29.1680 {time parsing} {
+    clock scan {2440588 xi:i:i pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM:%OS %P}
+} 82861
+test clock-29.1681 {time parsing} {
+    clock scan {2440588 23:01:59 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%M:%S }
+} 82919
+test clock-29.1682 {time parsing} {
+    clock scan {2440588 23:i:lix } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%OM:%OS }
+} 82919
+test clock-29.1683 {time parsing} {
+    clock scan {2440588 23:01:59 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%M:%S }
+} 82919
+test clock-29.1684 {time parsing} {
+    clock scan {2440588 23:i:lix } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%OM:%OS }
+} 82919
+test clock-29.1685 {time parsing} {
+    clock scan {2440588 xxiii:01:59 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%M:%S }
+} 82919
+test clock-29.1686 {time parsing} {
+    clock scan {2440588 xxiii:i:lix } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%OM:%OS }
+} 82919
+test clock-29.1687 {time parsing} {
+    clock scan {2440588 xxiii:01:59 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%M:%S }
+} 82919
+test clock-29.1688 {time parsing} {
+    clock scan {2440588 xxiii:i:lix } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%OM:%OS }
+} 82919
+test clock-29.1689 {time parsing} {
+    clock scan {2440588 11:01:59 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M:%S %p}
+} 82919
+test clock-29.1690 {time parsing} {
+    clock scan {2440588 11:i:lix PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM:%OS %p}
+} 82919
+test clock-29.1691 {time parsing} {
+    clock scan {2440588 11:01:59 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M:%S %p}
+} 82919
+test clock-29.1692 {time parsing} {
+    clock scan {2440588 11:i:lix PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM:%OS %p}
+} 82919
+test clock-29.1693 {time parsing} {
+    clock scan {2440588 xi:01:59 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M:%S %p}
+} 82919
+test clock-29.1694 {time parsing} {
+    clock scan {2440588 xi:i:lix PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM:%OS %p}
+} 82919
+test clock-29.1695 {time parsing} {
+    clock scan {2440588 xi:01:59 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M:%S %p}
+} 82919
+test clock-29.1696 {time parsing} {
+    clock scan {2440588 xi:i:lix PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM:%OS %p}
+} 82919
+test clock-29.1697 {time parsing} {
+    clock scan {2440588 11:01:59 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M:%S %P}
+} 82919
+test clock-29.1698 {time parsing} {
+    clock scan {2440588 11:i:lix pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM:%OS %P}
+} 82919
+test clock-29.1699 {time parsing} {
+    clock scan {2440588 11:01:59 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M:%S %P}
+} 82919
+test clock-29.1700 {time parsing} {
+    clock scan {2440588 11:i:lix pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM:%OS %P}
+} 82919
+test clock-29.1701 {time parsing} {
+    clock scan {2440588 xi:01:59 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M:%S %P}
+} 82919
+test clock-29.1702 {time parsing} {
+    clock scan {2440588 xi:i:lix pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM:%OS %P}
+} 82919
+test clock-29.1703 {time parsing} {
+    clock scan {2440588 xi:01:59 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M:%S %P}
+} 82919
+test clock-29.1704 {time parsing} {
+    clock scan {2440588 xi:i:lix pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM:%OS %P}
+} 82919
+test clock-29.1705 {time parsing} {
+    clock scan {2440588 23:59 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%M }
+} 86340
+test clock-29.1706 {time parsing} {
+    clock scan {2440588 23:lix } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%OM }
+} 86340
+test clock-29.1707 {time parsing} {
+    clock scan {2440588 23:59:00 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%M:%S }
+} 86340
+test clock-29.1708 {time parsing} {
+    clock scan {2440588 23:lix:? } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%OM:%OS }
+} 86340
+test clock-29.1709 {time parsing} {
+    clock scan {2440588 23:59 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%M }
+} 86340
+test clock-29.1710 {time parsing} {
+    clock scan {2440588 23:lix } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%OM }
+} 86340
+test clock-29.1711 {time parsing} {
+    clock scan {2440588 23:59:00 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%M:%S }
+} 86340
+test clock-29.1712 {time parsing} {
+    clock scan {2440588 23:lix:? } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%OM:%OS }
+} 86340
+test clock-29.1713 {time parsing} {
+    clock scan {2440588 xxiii:59 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%M }
+} 86340
+test clock-29.1714 {time parsing} {
+    clock scan {2440588 xxiii:lix } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%OM }
+} 86340
+test clock-29.1715 {time parsing} {
+    clock scan {2440588 xxiii:59:00 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%M:%S }
+} 86340
+test clock-29.1716 {time parsing} {
+    clock scan {2440588 xxiii:lix:? } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%OM:%OS }
+} 86340
+test clock-29.1717 {time parsing} {
+    clock scan {2440588 xxiii:59 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%M }
+} 86340
+test clock-29.1718 {time parsing} {
+    clock scan {2440588 xxiii:lix } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%OM }
+} 86340
+test clock-29.1719 {time parsing} {
+    clock scan {2440588 xxiii:59:00 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%M:%S }
+} 86340
+test clock-29.1720 {time parsing} {
+    clock scan {2440588 xxiii:lix:? } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%OM:%OS }
+} 86340
+test clock-29.1721 {time parsing} {
+    clock scan {2440588 11:59 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M %p}
+} 86340
+test clock-29.1722 {time parsing} {
+    clock scan {2440588 11:lix PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM %p}
+} 86340
+test clock-29.1723 {time parsing} {
+    clock scan {2440588 11:59:00 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M:%S %p}
+} 86340
+test clock-29.1724 {time parsing} {
+    clock scan {2440588 11:lix:? PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM:%OS %p}
+} 86340
+test clock-29.1725 {time parsing} {
+    clock scan {2440588 11:59 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M %p}
+} 86340
+test clock-29.1726 {time parsing} {
+    clock scan {2440588 11:lix PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM %p}
+} 86340
+test clock-29.1727 {time parsing} {
+    clock scan {2440588 11:59:00 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M:%S %p}
+} 86340
+test clock-29.1728 {time parsing} {
+    clock scan {2440588 11:lix:? PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM:%OS %p}
+} 86340
+test clock-29.1729 {time parsing} {
+    clock scan {2440588 xi:59 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M %p}
+} 86340
+test clock-29.1730 {time parsing} {
+    clock scan {2440588 xi:lix PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM %p}
+} 86340
+test clock-29.1731 {time parsing} {
+    clock scan {2440588 xi:59:00 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M:%S %p}
+} 86340
+test clock-29.1732 {time parsing} {
+    clock scan {2440588 xi:lix:? PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM:%OS %p}
+} 86340
+test clock-29.1733 {time parsing} {
+    clock scan {2440588 xi:59 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M %p}
+} 86340
+test clock-29.1734 {time parsing} {
+    clock scan {2440588 xi:lix PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM %p}
+} 86340
+test clock-29.1735 {time parsing} {
+    clock scan {2440588 xi:59:00 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M:%S %p}
+} 86340
+test clock-29.1736 {time parsing} {
+    clock scan {2440588 xi:lix:? PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM:%OS %p}
+} 86340
+test clock-29.1737 {time parsing} {
+    clock scan {2440588 11:59 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M %P}
+} 86340
+test clock-29.1738 {time parsing} {
+    clock scan {2440588 11:lix pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM %P}
+} 86340
+test clock-29.1739 {time parsing} {
+    clock scan {2440588 11:59:00 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M:%S %P}
+} 86340
+test clock-29.1740 {time parsing} {
+    clock scan {2440588 11:lix:? pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM:%OS %P}
+} 86340
+test clock-29.1741 {time parsing} {
+    clock scan {2440588 11:59 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M %P}
+} 86340
+test clock-29.1742 {time parsing} {
+    clock scan {2440588 11:lix pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM %P}
+} 86340
+test clock-29.1743 {time parsing} {
+    clock scan {2440588 11:59:00 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M:%S %P}
+} 86340
+test clock-29.1744 {time parsing} {
+    clock scan {2440588 11:lix:? pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM:%OS %P}
+} 86340
+test clock-29.1745 {time parsing} {
+    clock scan {2440588 xi:59 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M %P}
+} 86340
+test clock-29.1746 {time parsing} {
+    clock scan {2440588 xi:lix pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM %P}
+} 86340
+test clock-29.1747 {time parsing} {
+    clock scan {2440588 xi:59:00 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M:%S %P}
+} 86340
+test clock-29.1748 {time parsing} {
+    clock scan {2440588 xi:lix:? pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM:%OS %P}
+} 86340
+test clock-29.1749 {time parsing} {
+    clock scan {2440588 xi:59 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M %P}
+} 86340
+test clock-29.1750 {time parsing} {
+    clock scan {2440588 xi:lix pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM %P}
+} 86340
+test clock-29.1751 {time parsing} {
+    clock scan {2440588 xi:59:00 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M:%S %P}
+} 86340
+test clock-29.1752 {time parsing} {
+    clock scan {2440588 xi:lix:? pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM:%OS %P}
+} 86340
+test clock-29.1753 {time parsing} {
+    clock scan {2440588 23:59:01 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%M:%S }
+} 86341
+test clock-29.1754 {time parsing} {
+    clock scan {2440588 23:lix:i } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%OM:%OS }
+} 86341
+test clock-29.1755 {time parsing} {
+    clock scan {2440588 23:59:01 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%M:%S }
+} 86341
+test clock-29.1756 {time parsing} {
+    clock scan {2440588 23:lix:i } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%OM:%OS }
+} 86341
+test clock-29.1757 {time parsing} {
+    clock scan {2440588 xxiii:59:01 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%M:%S }
+} 86341
+test clock-29.1758 {time parsing} {
+    clock scan {2440588 xxiii:lix:i } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%OM:%OS }
+} 86341
+test clock-29.1759 {time parsing} {
+    clock scan {2440588 xxiii:59:01 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%M:%S }
+} 86341
+test clock-29.1760 {time parsing} {
+    clock scan {2440588 xxiii:lix:i } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%OM:%OS }
+} 86341
+test clock-29.1761 {time parsing} {
+    clock scan {2440588 11:59:01 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M:%S %p}
+} 86341
+test clock-29.1762 {time parsing} {
+    clock scan {2440588 11:lix:i PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM:%OS %p}
+} 86341
+test clock-29.1763 {time parsing} {
+    clock scan {2440588 11:59:01 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M:%S %p}
+} 86341
+test clock-29.1764 {time parsing} {
+    clock scan {2440588 11:lix:i PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM:%OS %p}
+} 86341
+test clock-29.1765 {time parsing} {
+    clock scan {2440588 xi:59:01 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M:%S %p}
+} 86341
+test clock-29.1766 {time parsing} {
+    clock scan {2440588 xi:lix:i PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM:%OS %p}
+} 86341
+test clock-29.1767 {time parsing} {
+    clock scan {2440588 xi:59:01 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M:%S %p}
+} 86341
+test clock-29.1768 {time parsing} {
+    clock scan {2440588 xi:lix:i PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM:%OS %p}
+} 86341
+test clock-29.1769 {time parsing} {
+    clock scan {2440588 11:59:01 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M:%S %P}
+} 86341
+test clock-29.1770 {time parsing} {
+    clock scan {2440588 11:lix:i pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM:%OS %P}
+} 86341
+test clock-29.1771 {time parsing} {
+    clock scan {2440588 11:59:01 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M:%S %P}
+} 86341
+test clock-29.1772 {time parsing} {
+    clock scan {2440588 11:lix:i pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM:%OS %P}
+} 86341
+test clock-29.1773 {time parsing} {
+    clock scan {2440588 xi:59:01 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M:%S %P}
+} 86341
+test clock-29.1774 {time parsing} {
+    clock scan {2440588 xi:lix:i pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM:%OS %P}
+} 86341
+test clock-29.1775 {time parsing} {
+    clock scan {2440588 xi:59:01 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M:%S %P}
+} 86341
+test clock-29.1776 {time parsing} {
+    clock scan {2440588 xi:lix:i pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM:%OS %P}
+} 86341
+test clock-29.1777 {time parsing} {
+    clock scan {2440588 23:59:59 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%M:%S }
+} 86399
+test clock-29.1778 {time parsing} {
+    clock scan {2440588 23:lix:lix } \
+        -gmt true -locale en_US_roman \
+        -format {%J %H:%OM:%OS }
+} 86399
+test clock-29.1779 {time parsing} {
+    clock scan {2440588 23:59:59 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%M:%S }
+} 86399
+test clock-29.1780 {time parsing} {
+    clock scan {2440588 23:lix:lix } \
+        -gmt true -locale en_US_roman \
+        -format {%J %k:%OM:%OS }
+} 86399
+test clock-29.1781 {time parsing} {
+    clock scan {2440588 xxiii:59:59 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%M:%S }
+} 86399
+test clock-29.1782 {time parsing} {
+    clock scan {2440588 xxiii:lix:lix } \
+        -gmt true -locale en_US_roman \
+        -format {%J %OH:%OM:%OS }
+} 86399
+test clock-29.1783 {time parsing} {
+    clock scan {2440588 xxiii:59:59 } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%M:%S }
+} 86399
+test clock-29.1784 {time parsing} {
+    clock scan {2440588 xxiii:lix:lix } \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ok:%OM:%OS }
+} 86399
+test clock-29.1785 {time parsing} {
+    clock scan {2440588 11:59:59 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M:%S %p}
+} 86399
+test clock-29.1786 {time parsing} {
+    clock scan {2440588 11:lix:lix PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM:%OS %p}
+} 86399
+test clock-29.1787 {time parsing} {
+    clock scan {2440588 11:59:59 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M:%S %p}
+} 86399
+test clock-29.1788 {time parsing} {
+    clock scan {2440588 11:lix:lix PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM:%OS %p}
+} 86399
+test clock-29.1789 {time parsing} {
+    clock scan {2440588 xi:59:59 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M:%S %p}
+} 86399
+test clock-29.1790 {time parsing} {
+    clock scan {2440588 xi:lix:lix PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM:%OS %p}
+} 86399
+test clock-29.1791 {time parsing} {
+    clock scan {2440588 xi:59:59 PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M:%S %p}
+} 86399
+test clock-29.1792 {time parsing} {
+    clock scan {2440588 xi:lix:lix PM} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM:%OS %p}
+} 86399
+test clock-29.1793 {time parsing} {
+    clock scan {2440588 11:59:59 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%M:%S %P}
+} 86399
+test clock-29.1794 {time parsing} {
+    clock scan {2440588 11:lix:lix pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %I:%OM:%OS %P}
+} 86399
+test clock-29.1795 {time parsing} {
+    clock scan {2440588 11:59:59 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%M:%S %P}
+} 86399
+test clock-29.1796 {time parsing} {
+    clock scan {2440588 11:lix:lix pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %l:%OM:%OS %P}
+} 86399
+test clock-29.1797 {time parsing} {
+    clock scan {2440588 xi:59:59 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%M:%S %P}
+} 86399
+test clock-29.1798 {time parsing} {
+    clock scan {2440588 xi:lix:lix pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %OI:%OM:%OS %P}
+} 86399
+test clock-29.1799 {time parsing} {
+    clock scan {2440588 xi:59:59 pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%M:%S %P}
+} 86399
+test clock-29.1800 {time parsing} {
+    clock scan {2440588 xi:lix:lix pm} \
+        -gmt true -locale en_US_roman \
+        -format {%J %Ol:%OM:%OS %P}
+} 86399
+# END testcases29
+
+test clock-30.1 {clock add years} {
+    set t [clock scan 2000-01-01 -format %Y-%m-%d -timezone :UTC]
+    set f [clock add $t 1 year -timezone :UTC]
+    clock format $f -format %Y-%m-%d -timezone :UTC
+} {2001-01-01}
+test clock-30.2 {clock add years - leap day} {
+    set t [clock scan 2000-02-29 -format %Y-%m-%d -timezone :UTC]
+    set f [clock add $t 1 years -timezone :UTC]
+    clock format $f -format %Y-%m-%d -timezone :UTC
+} {2001-02-28}
+test clock-30.3 {clock add months} {
+    set t [clock scan 2000-01-01 -format %Y-%m-%d -timezone :UTC]
+    set f [clock add $t 1 month -timezone :UTC]
+    clock format $f -format %Y-%m-%d -timezone :UTC
+} {2000-02-01}
+test clock-30.4 {clock add months, short month} {
+    set t [clock scan 2000-01-31 -format %Y-%m-%d -timezone :UTC]
+    set f [clock add $t 1 months -timezone :UTC]
+    clock format $f -format %Y-%m-%d -timezone :UTC
+} {2000-02-29}
+test clock-30.5 {clock add months, end of year} {
+    set t [clock scan 2000-12-01 -format %Y-%m-%d -timezone :UTC]
+    set f [clock add $t 1 month -timezone :UTC]
+    clock format $f -format %Y-%m-%d -timezone :UTC
+} {2001-01-01}
+test clock-30.6 {clock add months, one year one month vs 13 months} {
+    set t [clock scan 2000-02-29 -format %Y-%m-%d -timezone :UTC]
+    set f1 [clock add $t 1 year 1 month -timezone :UTC]
+    set f2 [clock add $t 13 months -timezone :UTC]
+    set x1 [clock format $f1 -format %Y-%m-%d -timezone :UTC]
+    set x2 [clock format $f2 -format %Y-%m-%d -timezone :UTC]
+    list $x1 $x2
+} {2001-03-28 2001-03-29}
+test clock-30.7 {clock add months, 1 year 1 month vs 1 month 1 year} {
+    set t [clock scan 2000-02-29 -format %Y-%m-%d -timezone :UTC]
+    set f1 [clock add $t 1 year 1 month -timezone :UTC]
+    set f2 [clock add $t 1 month 1 year -timezone :UTC]
+    set x1 [clock format $f1 -format %Y-%m-%d -timezone :UTC]
+    set x2 [clock format $f2 -format %Y-%m-%d -timezone :UTC]
+    list $x1 $x2
+} {2001-03-28 2001-03-29}
+test clock-30.8 {clock add months, negative} {
+    set t [clock scan 2000-03-31 -format %Y-%m-%d -timezone :UTC]
+    set f1 [clock add $t -1 month -timezone :UTC]
+    set f2 [clock add $t -2 month -timezone :UTC]
+    set f3 [clock add $t -3 month -timezone :UTC]
+    set f4 [clock add $t -4 month -timezone :UTC]
+    set x1 [clock format $f1 -format %Y-%m-%d -timezone :UTC]
+    set x2 [clock format $f2 -format %Y-%m-%d -timezone :UTC]
+    set x3 [clock format $f3 -format %Y-%m-%d -timezone :UTC]
+    set x4 [clock format $f4 -format %Y-%m-%d -timezone :UTC]
+    list $x1 $x2 $x3 $x4
+} {2000-02-29 2000-01-31 1999-12-31 1999-11-30}
+test clock-30.9 {clock add days} {
+    set t [clock scan {2000-01-01 12:34:56} -format {%Y-%m-%d %H:%M:%S} \
+	       -timezone :UTC]
+    set f1 [clock add $t 1 day -timezone :UTC]
+    set f2 [clock add $t -1 day -timezone :UTC]
+    set x1 [clock format $f1 -format {%Y-%m-%d %H:%M:%S} -timezone :UTC]
+    set x2 [clock format $f2 -format {%Y-%m-%d %H:%M:%S} -timezone :UTC]
+    list $x1 $x2
+} {{2000-01-02 12:34:56} {1999-12-31 12:34:56}}
+test clock-30.10 {clock add days, spring DST conversion, before} {
+    set t [clock scan {2004-04-03 01:59:59} -format {%Y-%m-%d %H:%M:%S} \
+	       -timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+    set f1 [clock add $t 1 day \
+		-timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+    set f2 [clock add $t 2 days \
+		-timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+    set x1 [clock format $f1 -format {%Y-%m-%d %H:%M:%S %z} \
+		-timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+    set x2 [clock format $f2 -format {%Y-%m-%d %H:%M:%S %z} \
+		-timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+    list $x1 $x2
+} {{2004-04-04 01:59:59 -0500} {2004-04-05 01:59:59 -0400}}
+test clock-30.11 {clock add days, spring DST conversion, bad case} {
+    set t [clock scan {2004-04-03 02:30:00} -format {%Y-%m-%d %H:%M:%S} \
+	       -timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+    set f1 [clock add $t 1 day \
+		-timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+    set f2 [clock add $t 2 day \
+		-timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+    set x1 [clock format $f1 -format {%Y-%m-%d %H:%M:%S %z} \
+		-timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+    set x2 [clock format $f2 -format {%Y-%m-%d %H:%M:%S %z} \
+		-timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+    list $x1 $x2
+} {{2004-04-04 03:30:00 -0400} {2004-04-05 02:30:00 -0400}}
+test clock-30.12 {clock add days, spring DST conversion, after} {
+    set t [clock scan {2004-04-03 03:00:00} -format {%Y-%m-%d %H:%M:%S} \
+	       -timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+    set f1 [clock add $t 1 day -timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+    set f2 [clock add $t 2 day -timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+    set x1 [clock format $f1 -format {%Y-%m-%d %H:%M:%S %z} \
+		-timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+    set x2 [clock format $f2 -format {%Y-%m-%d %H:%M:%S %z} \
+		-timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+    list $x1 $x2
+} {{2004-04-04 03:00:00 -0400} {2004-04-05 03:00:00 -0400}}
+test clock-30.13 {clock add days, fall DST conversion, before} {
+    set t [clock scan {2004-10-30 00:59:59} -format {%Y-%m-%d %H:%M:%S} \
+	       -timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+    set f1 [clock add $t 1 day \
+		-timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+    set f2 [clock add $t 2 day \
+		-timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+    set x1 [clock format $f1 -format {%Y-%m-%d %H:%M:%S %z} \
+		-timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+    set x2 [clock format $f2 -format {%Y-%m-%d %H:%M:%S %z} \
+		-timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+    list $x1 $x2
+} {{2004-10-31 00:59:59 -0400} {2004-11-01 00:59:59 -0500}}
+test clock-30.14 {clock add days, fall DST conversion, bad case} {
+    set t [clock scan {2004-10-30 01:30:00} -format {%Y-%m-%d %H:%M:%S} \
+	       -timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+    set f1 [clock add $t 1 day \
+		-timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+    set f2 [clock add $t 2 day \
+		-timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+    set x1 [clock format $f1 -format {%Y-%m-%d %H:%M:%S %z} \
+		-timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+    set x2 [clock format $f2 -format {%Y-%m-%d %H:%M:%S %z} \
+		-timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+    list $x1 $x2
+} {{2004-10-31 01:30:00 -0400} {2004-11-01 01:30:00 -0500}}
+test clock-30.15 {clock add days, fall DST conversion, after} {
+    set t [clock scan {2004-10-30 02:30:00} -format {%Y-%m-%d %H:%M:%S} \
+	       -timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+    set f1 [clock add $t 1 day \
+		-timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+    set f2 [clock add $t 2 day \
+		-timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+    set x1 [clock format $f1 -format {%Y-%m-%d %H:%M:%S %z} \
+		-timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+    set x2 [clock format $f2 -format {%Y-%m-%d %H:%M:%S %z} \
+		-timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+    list $x1 $x2
+} {{2004-10-31 02:30:00 -0500} {2004-11-01 02:30:00 -0500}}
+test clock-30.16 {clock add weeks} {
+    set t [clock scan {2000-01-01 12:34:56} -format {%Y-%m-%d %H:%M:%S} \
+	       -timezone :UTC]
+    set f1 [clock add $t 1 week -timezone :UTC]
+    set f2 [clock add $t -1 weeks -timezone :UTC]
+    set x1 [clock format $f1 -format {%Y-%m-%d %H:%M:%S} -timezone :UTC]
+    set x2 [clock format $f2 -format {%Y-%m-%d %H:%M:%S} -timezone :UTC]
+    list $x1 $x2
+} {{2000-01-08 12:34:56} {1999-12-25 12:34:56}}
+test clock-30.17 {clock add hours} {
+    set t [clock scan {2000-01-01 12:34:56} -format {%Y-%m-%d %H:%M:%S} \
+	       -timezone :UTC]
+    set f1 [clock add $t 1 hour -timezone :UTC]
+    set f2 [clock add $t -1 hours -timezone :UTC]
+    set x1 [clock format $f1 -format {%Y-%m-%d %H:%M:%S} -timezone :UTC]
+    set x2 [clock format $f2 -format {%Y-%m-%d %H:%M:%S} -timezone :UTC]
+    list $x1 $x2
+} {{2000-01-01 13:34:56} {2000-01-01 11:34:56}}
+test clock-30.18 {clock add hours at DST conversion} {
+    set t [clock scan {2004-04-04 01:00:00 -0500} \
+	       -format {%Y-%m-%d %H:%M:%S %z} \
+	       -timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+    set f1 [clock add $t 1 hour -timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+    set x1 [clock format $f1 -format {%Y-%m-%d %H:%M:%S %z} \
+		-timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+} {2004-04-04 03:00:00 -0400}
+test clock-30.19 {clock add hours at DST conversion} {
+    set t [clock scan {2004-10-31 01:00:00 -0400} \
+	       -format {%Y-%m-%d %H:%M:%S %z} \
+	       -timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+    set f1 [clock add $t 1 hour \
+		-timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+    set x1 [clock format $f1 -format {%Y-%m-%d %H:%M:%S %z} \
+		-timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+} {2004-10-31 01:00:00 -0500}
+test clock-30.20 {clock add minutes} {
+    set t [clock scan {2000-01-01 12:34:56} -format {%Y-%m-%d %H:%M:%S} \
+	       -timezone :UTC]
+    set f1 [clock add $t 60 minute -timezone :UTC]
+    set f2 [clock add $t -60 minutes -timezone :UTC]
+    set x1 [clock format $f1 -format {%Y-%m-%d %H:%M:%S} -timezone :UTC]
+    set x2 [clock format $f2 -format {%Y-%m-%d %H:%M:%S} -timezone :UTC]
+    list $x1 $x2
+} {{2000-01-01 13:34:56} {2000-01-01 11:34:56}}
+test clock-30.21 {clock add minutes at DST conversion} {
+    set t [clock scan {2004-04-04 01:00:00 -0500} \
+	       -format {%Y-%m-%d %H:%M:%S %z} \
+	       -timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+    set f1 [clock add $t 60 minutes \
+		-timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+    set x1 [clock format $f1 -format {%Y-%m-%d %H:%M:%S %z} \
+		-timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+} {2004-04-04 03:00:00 -0400}
+test clock-30.22 {clock add minutes at DST conversion} {
+    set t [clock scan {2004-10-31 01:00:00 -0400} \
+	       -format {%Y-%m-%d %H:%M:%S %z} \
+	       -timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+    set f1 [clock add $t 60 minutes \
+		-timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+    set x1 [clock format $f1 -format {%Y-%m-%d %H:%M:%S %z} \
+		-timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+} {2004-10-31 01:00:00 -0500}
+test clock-30.23 {clock add seconds} {
+    set t [clock scan {2000-01-01 12:34:56} -format {%Y-%m-%d %H:%M:%S} \
+	       -timezone :UTC]
+    set f1 [clock add $t 3600 second -timezone :UTC]
+    set f2 [clock add $t -3600 seconds -timezone :UTC]
+    set x1 [clock format $f1 -format {%Y-%m-%d %H:%M:%S} -timezone :UTC]
+    set x2 [clock format $f2 -format {%Y-%m-%d %H:%M:%S} -timezone :UTC]
+    list $x1 $x2
+} {{2000-01-01 13:34:56} {2000-01-01 11:34:56}}
+test clock-30.24 {clock add seconds at DST conversion} {
+    set t [clock scan {2004-04-04 01:00:00 -0500} \
+	       -format {%Y-%m-%d %H:%M:%S %z} \
+	       -timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+    set f1 [clock add $t 3600 seconds \
+		-timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+    set x1 [clock format $f1 -format {%Y-%m-%d %H:%M:%S %z} \
+		-timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+} {2004-04-04 03:00:00 -0400}
+test clock-30.25 {clock add seconds at DST conversion} {
+    set t [clock scan {2004-10-31 01:00:00 -0400} \
+	       -format {%Y-%m-%d %H:%M:%S %z} \
+	       -timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+    set f1 [clock add $t 3600 seconds -timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+    set x1 [clock format $f1 -format {%Y-%m-%d %H:%M:%S %z} \
+		-timezone EST05:00EDT04:00,M4.1.0/02:00,M10.5.0/02:00]
+} {2004-10-31 01:00:00 -0500}
+
+test clock-31.1 {system locale} \
+    -constraints win \
+    -setup { 
+	namespace eval ::tcl::clock {
+	    namespace import -force ::testClock::registry
+	}
+	set noreg [info exists ::tcl::clock::NoRegistry]
+	if {$noreg} {unset ::tcl::clock::NoRegistry}
+	::tcl::clock::ClearCaches
+    } \
+    -body {
+	clock format 0 -timezone :UTC -locale system -format %x
+    } \
+    -cleanup {
+	namespace eval ::tcl::clock {
+	    rename registry {}
+	}
+	if {$noreg} {set ::tcl::clock::NoRegistry {}}
+	::tcl::clock::ClearCaches
+    } \
+    -result [clock format 0 -timezone :UTC -locale current \
+		 -format {%d-%b-%Y}]
+
+test clock-31.2 {system locale} \
+    -constraints win \
+    -setup { 
+	namespace eval ::tcl::clock {
+	    namespace import -force ::testClock::registry
+	}
+	set noreg [info exists ::tcl::clock::NoRegistry]
+	if {$noreg} {unset ::tcl::clock::NoRegistry}
+	::tcl::clock::ClearCaches
+    } \
+    -body {
+	clock format 0 -timezone :UTC -locale system -format %Ex
+    } \
+    -cleanup {
+	namespace eval ::tcl::clock {
+	    rename registry {}
+	}
+	if {$noreg} {set ::tcl::clock::NoRegistry {}}
+	::tcl::clock::ClearCaches
+    } \
+    -result [clock format 0 -timezone :UTC -locale current \
+		 -format {the %d' day of %B %Y}]
+
+test clock-31.3 {system locale} \
+    -constraints win \
+    -setup { 
+	namespace eval ::tcl::clock {
+	    namespace import -force ::testClock::registry
+	}
+	set noreg [info exists ::tcl::clock::NoRegistry]
+	if {$noreg} {unset ::tcl::clock::NoRegistry}
+	::tcl::clock::ClearCaches
+    } \
+    -body {
+	clock format 0 -timezone :UTC -locale system -format %X
+    } \
+    -cleanup {
+	namespace eval ::tcl::clock {
+	    rename registry {}
+	}
+	if {$noreg} {set ::tcl::clock::NoRegistry {}}
+	::tcl::clock::ClearCaches
+    } \
+    -result [clock format 0 -timezone :UTC -locale current \
+		 -format {%l:%M:%S %p}]
+
+test clock-31.4 {system locale} \
+    -constraints win \
+    -setup { 
+	namespace eval ::tcl::clock {
+	    namespace import -force ::testClock::registry
+	}
+	set noreg [info exists ::tcl::clock::NoRegistry]
+	if {$noreg} {unset ::tcl::clock::NoRegistry}
+	if { [info exists env(TZ)] } {
+	    set oldTZ $env(TZ)
+	    unset env(TZ)
+	}
+	if { [info exists env(TCL_TZ)] } {
+	    set oldTclTZ $env(TCL_TZ)
+	    unset env(TCL_TZ)
+	}
+	::tcl::clock::ClearCaches
+    } \
+    -body {
+	clock format 0 -locale system -format %x
+    } \
+    -cleanup {
+	namespace eval ::tcl::clock {
+	    rename registry {}
+	}
+	if { [info exists oldTclTZ] } {
+	    set env(TCL_TZ) $oldTclTZ
+	}
+	if { [info exists oldTZ] } {
+	    set env(TZ) $oldTZ
+	}
+	if {$noreg} {set ::tcl::clock::NoRegistry {}}
+	::tcl::clock::ClearCaches
+    } \
+    -result [clock format 0 -locale current -timezone EST5 \
+		 -format {%d-%b-%Y}]
+
+test clock-31.5 {system locale} \
+    -constraints win \
+    -setup { 
+	namespace eval ::tcl::clock {
+	    namespace import -force ::testClock::registry
+	}
+	set noreg [info exists ::tcl::clock::NoRegistry]
+	if {$noreg} {unset ::tcl::clock::NoRegistry}
+	if { [info exists env(TZ)] } {
+	    set oldTZ $env(TZ)
+	    unset env(TZ)
+	}
+	if { [info exists env(TCL_TZ)] } {
+	    set oldTclTZ $env(TCL_TZ)
+	    unset env(TCL_TZ)
+	}
+	::tcl::clock::ClearCaches
+    } \
+    -body {
+	clock format 0 -locale system -format %Ex
+    } \
+    -cleanup {
+	namespace eval ::tcl::clock {
+	    rename registry {}
+	}
+	if {$noreg} {set ::tcl::clock::NoRegistry {}}
+	if { [info exists oldTclTZ] } {
+	    set env(TCL_TZ) $oldTclTZ
+	}
+	if { [info exists oldTZ] } {
+	    set env(TZ) $oldTZ
+	}
+	::tcl::clock::ClearCaches
+    } \
+    -result [clock format 0 -locale current -timezone EST5 \
+		 -format {the %d' day of %B %Y}]
+
+test clock-31.6 {system locale} \
+    -constraints win \
+    -setup { 
+	namespace eval ::tcl::clock {
+	    namespace import -force ::testClock::registry
+	}
+	set noreg [info exists ::tcl::clock::NoRegistry]
+	if {$noreg} {unset ::tcl::clock::NoRegistry}
+	if { [info exists env(TZ)] } {
+	    set oldTZ $env(TZ)
+	    unset env(TZ)
+	}
+	if { [info exists env(TCL_TZ)] } {
+	    set oldTclTZ $env(TCL_TZ)
+	    unset env(TCL_TZ)
+	}
+	::tcl::clock::ClearCaches
+    } \
+    -body {
+	clock format 0 -locale system -format "%X %Z"
+    } \
+    -cleanup {
+	namespace eval ::tcl::clock {
+	    rename registry {}
+	}
+	if {$noreg} {set ::tcl::clock::NoRegistry {}}
+	if { [info exists oldTclTZ] } {
+	    set env(TCL_TZ) $oldTclTZ
+	}
+	if { [info exists oldTZ] } {
+	    set env(TZ) $oldTZ
+	}
+	::tcl::clock::ClearCaches
+    } \
+    -result [clock format 0 -locale current -timezone EST5 \
+		 -format {%l:%M:%S %p %Z}]
+
+test clock-32.1 {scan/format across the Gregorian change} {
+    set problems {}
+    set t [expr { wide(-6857395200) }]
+    foreach d {       1  2 14 15 16
+	       17 18 19 20 21 22 23
+	       24 25 26 27 28 29 30 } \
+	j {         245 246 258 259 260
+            261 262 263 264 265 266 267
+	    268 269 270 271 272 273 274 } {
+	set u [format 1752-09-%02d $d]
+	set s [clock format $t -format %Y-%m-%d \
+		   -locale en_US_roman -timezone :UTC]
+	if { $s ne $u } {
+	    append problems "formatting $t: $s should be $u\n"
+	}
+	set v [clock scan $u -format %Y-%m-%d \
+		   -locale en_US_roman -timezone :UTC]
+	if { $t ne $v } {
+	    append problems "scanning $u: $t should be $v\n"
+	}
+	set u [format 1752-%03d $j]
+	set s [clock format $t -format %Y-%j \
+		   -locale en_US_roman -timezone :UTC]
+	if { $s ne $u } {
+	    append problems "formatting $t: $s should be $u\n"
+	}
+	set v [clock scan $u -format %Y-%j \
+		   -locale en_US_roman -timezone :UTC]
+	if { $t ne $v } {
+	    append problems "scanning $u: $t should be $v\n"
+	}
+	incr t 86400
+    }
+    set problems
+} {}
+			 
+# Legacy tests
+
+# clock clicks
+test clock-33.1 {clock clicks tests} {
+    expr [clock clicks]+1
+    concat {}
+} {}
+test clock-33.2 {clock clicks tests} {
+    set start [clock clicks]
+    after 10
+    set end [clock clicks]
+    expr "$end > $start"
+} {1}
+test clock-33.3 {clock clicks tests} {
+    list [catch {clock clicks foo} msg] $msg
+} {1 {bad option "foo": must be -milliseconds or -microseconds}}
+test clock-33.4 {clock clicks tests} {
+    expr [clock clicks -milliseconds]+1
+    concat {}
+} {}
+test clock-33.4a {clock milliseconds} {
+    expr { [clock milliseconds] + 1 }
+    concat {}
+} {}
+test clock-33.5 {clock clicks tests, millisecond timing test} {
+    # This test can fail on a system that is so heavily loaded that
+    # the test takes >60 ms to run.
+    set start [clock clicks -milli]
+    after 10
+    set end [clock clicks -milli]
+    # 60 msecs seems to be the max time slice under Windows 95/98
+    expr {
+	  ($end > $start) && (($end - $start) <= 60) ?
+	  "ok" : 
+	  "test should have taken 0-60 ms, actually took [expr $end - $start]"}
+} {ok}
+test clock-33.5a {clock tests, millisecond timing test} {
+    # This test can fail on a system that is so heavily loaded that
+    # the test takes >60 ms to run.
+    set start [clock milliseconds]
+    after 10
+    set end [clock milliseconds]
+    # 60 msecs seems to be the max time slice under Windows 95/98
+    expr {
+	  ($end > $start) && (($end - $start) <= 60) ?
+	  "ok" : 
+	  "test should have taken 0-60 ms, actually took [expr $end - $start]"}
+} {ok}
+test clock-33.6 {clock clicks, milli with too much abbreviation} {
+    list [catch { clock clicks ? } msg] $msg
+} {1 {bad option "?": must be -milliseconds or -microseconds}}
+test clock-33.7 {clock clicks, milli with too much abbreviation} {
+    list [catch { clock clicks - } msg] $msg
+} {1 {ambiguous option "-": must be -milliseconds or -microseconds}}
+
+test clock-33.8 {clock clicks test, microsecond timing test} {
+    # This test can fail on a system that is so heavily loaded that
+    # the test takes >60 ms to run.
+    set start [clock clicks -micro]
+    after 10
+    set end [clock clicks -micro]
+    expr {($end > $start) && (($end - $start) <= 60000)}
+} {1}
+test clock-33.8a {clock test, microsecond timing test} {
+    # This test can fail on a system that is so heavily loaded that
+    # the test takes >60 ms to run.
+    set start [clock microseconds]
+    after 10
+    set end [clock microseconds]
+    expr {($end > $start) && (($end - $start) <= 60000)}
+} {1}
+
+test clock-33.9 {clock clicks test, millis align with seconds} {
+    set t1 [clock seconds]
+    while { 1 } {
+	set t2 [clock clicks -millis]
+	set t3 [clock seconds]
+	if { $t3 == $t1 } break
+	set t1 $t3
+    }
+    expr { $t2 / 1000 == $t3 }
+} {1}
+test clock-33.9a {clock test, millis align with seconds} {
+    set t1 [clock seconds]
+    while { 1 } {
+	set t2 [clock milliseconds]
+	set t3 [clock seconds]
+	if { $t3 == $t1 } break
+	set t1 $t3
+    }
+    expr { $t2 / 1000 == $t3 }
+} {1}
+
+test clock-33.10 {clock clicks test, micros align with seconds} {
+    set t1 [clock seconds]
+    while { 1 } {
+	set t2 [clock clicks -micros]
+	set t3 [clock seconds]
+	if { $t3 == $t1 } break
+	set t1 $t3
+    }
+    expr { $t2 / 1000000 == $t3 }
+} {1}
+test clock-33.10a {clock test, micros align with seconds} {
+    set t1 [clock seconds]
+    while { 1 } {
+	set t2 [clock microseconds]
+	set t3 [clock seconds]
+	if { $t3 == $t1 } break
+	set t1 $t3
+    }
+    expr { $t2 / 1000000 == $t3 }
+} {1}
+
+test clock-33.11 {clock clicks test, millis align with micros} {
+    set t1 [clock clicks -millis]
+    while { 1 } {
+	set t2 [clock clicks -micros]
+	set t3 [clock clicks -millis]
+	if { $t3 == $t1 } break
+	set t1 $t3
+    }
+    expr { $t2 / 1000 == $t3 }
+} {1}
+test clock-33.11a {clock test, millis align with micros} {
+    set t1 [clock milliseconds]
+    while { 1 } {
+	set t2 [clock microseconds]
+	set t3 [clock milliseconds]
+	if { $t3 == $t1 } break
+	set t1 $t3
+    }
+    expr { $t2 / 1000 == $t3 }
+} {1}
+
+# clock scan
+test clock-34.1 {clock scan tests} {
+    list [catch {clock scan} msg] $msg
+} {1 {wrong # args: should be "clock scan string ?-base seconds? ?-format string? ?-gmt boolean? ?-locale LOCALE? ?-timezone ZONE?"}}
+test clock-34.2 {clock scan tests} {*}{
+    -body {clock scan "bad-string"}
+    -returnCodes error
+    -match glob
+    -result {unable to convert date-time string "bad-string"*}
+}
+test clock-34.3 {clock scan tests} {
+    clock format [clock scan "14 Feb 92" -gmt true] \
+      -format {%m/%d/%y %I:%M:%S %p} -gmt true
+} {02/14/92 12:00:00 AM}
+test clock-34.4 {clock scan tests} {
+    clock format [clock scan "Feb 14, 1992 12:20 PM" -gmt true] \
+      -format {%m/%d/%y %I:%M:%S %p} -gmt true
+} {02/14/92 12:20:00 PM}
+test clock-34.5 {clock scan tests} {
+    clock format \
+      [clock scan "Feb 14, 1992 12:20 PM" -base 319363200 -gmt true] \
+      -format {%m/%d/%y %I:%M:%S %p} -gmt true
+} {02/14/92 12:20:00 PM}
+test clock-34.6 {clock scan tests} {
+    set time [clock scan "Oct 23,1992 15:00"]
+    clock format $time -format {%b %d,%Y %H:%M}
+} {Oct 23,1992 15:00}
+test clock-34.7 {clock scan tests} {
+    set time [clock scan "Oct 23,1992 15:00 GMT"]
+    clock format $time -format {%b %d,%Y %H:%M GMT} -gmt true
+} {Oct 23,1992 15:00 GMT}
+test clock-34.8 {clock scan tests} {
+    set time [clock scan "Oct 23,1992 15:00" -gmt true]
+    clock format $time -format {%b %d,%Y %H:%M GMT} -gmt true
+} {Oct 23,1992 15:00 GMT}
+test clock-34.9 {clock scan tests} {
+    list [catch {clock scan "Jan 12" -bad arg} msg] $msg
+} {1 {bad option "-bad", must be -base, -format, -gmt, -locale or -timezone}}
+# The following two two tests test the two year date policy
+test clock-34.10 {clock scan tests} {
+    set time [clock scan "1/1/71" -gmt true]
+    clock format $time -format {%b %d,%Y %H:%M GMT} -gmt true
+} {Jan 01,1971 00:00 GMT}
+test clock-34.11 {clock scan tests} {
+    set time [clock scan "1/1/37" -gmt true]
+    clock format $time -format {%b %d,%Y %H:%M GMT} -gmt true
+} {Jan 01,2037 00:00 GMT}
+
+test clock-34.12 {clock scan, relative times} {
+    set time [clock scan "Oct 23, 1992 -1 day"]
+    clock format $time -format {%b %d, %Y}
+} "Oct 22, 1992"
+test clock-34.13 {clock scan, ISO 8601 base date format} {
+    set time [clock scan "19921023"]
+    clock format $time -format {%b %d, %Y}
+} "Oct 23, 1992"
+test clock-34.14 {clock scan, ISO 8601 expanded date format} {
+    set time [clock scan "1992-10-23"]
+    clock format $time -format {%b %d, %Y}
+} "Oct 23, 1992"
+test clock-34.15 {clock scan, DD-Mon-YYYY format} {
+    set time [clock scan "23-Oct-1992"]
+    clock format $time -format {%b %d, %Y}
+} "Oct 23, 1992"
+test clock-34.16 {clock scan, ISO 8601 point in time format} {
+    set time [clock scan "19921023T235959"]
+    clock format $time -format {%b %d, %Y %H:%M:%S}
+} "Oct 23, 1992 23:59:59"
+test clock-34.17 {clock scan, ISO 8601 point in time format} {
+    set time [clock scan "19921023 235959"]
+    clock format $time -format {%b %d, %Y %H:%M:%S}
+} "Oct 23, 1992 23:59:59"
+test clock-34.18 {clock scan, ISO 8601 point in time format} {
+    set time [clock scan "19921023T000000"]
+    clock format $time -format {%b %d, %Y %H:%M:%S}
+} "Oct 23, 1992 00:00:00"
+
+# CLOCK SCAN REAL TESTS
+# We use 5am PST, 31-12-1999 as the base for these scans because irrespective
+# of your local timezone it should always give us times on December 31, 1999
+set 5amPST 946645200
+test clock-34.19 {clock scan, number meridian} {
+    set t1 [clock scan "5 am" -base $5amPST -gmt true]
+    set t2 [clock scan "5 pm" -base $5amPST -gmt true]
+    set t3 [clock scan "5 a.m." -base $5amPST -gmt true]
+    set t4 [clock scan "5 p.m." -base $5amPST -gmt true]
+    list \
+	    [clock format $t1 -format {%b %d, %Y %H:%M:%S} -gmt true] \
+	    [clock format $t2 -format {%b %d, %Y %H:%M:%S} -gmt true] \
+	    [clock format $t3 -format {%b %d, %Y %H:%M:%S} -gmt true] \
+	    [clock format $t4 -format {%b %d, %Y %H:%M:%S} -gmt true]
+} [list "Dec 31, 1999 05:00:00" "Dec 31, 1999 17:00:00" \
+	"Dec 31, 1999 05:00:00" "Dec 31, 1999 17:00:00"]
+test clock-34.20 {clock scan, number:number meridian} {
+    clock format [clock scan "5:30 pm" -base $5amPST -gmt true] \
+	    -format {%b %d, %Y %H:%M:%S} -gmt true
+} "Dec 31, 1999 17:30:00"
+test clock-34.21 {clock scan, number:number-timezone} {
+    clock format [clock scan "00:00-0800" -gmt true -base $5amPST] \
+	    -format {%b %d, %Y %H:%M:%S} -gmt true
+} "Dec 31, 1999 08:00:00"
+test clock-34.22 {clock scan, number:number:number o_merid} {
+    clock format [clock scan "8:00:00" -gmt true -base $5amPST] \
+	    -format {%b %d, %Y %H:%M:%S} -gmt true
+} "Dec 31, 1999 08:00:00"
+test clock-34.23 {clock scan, number:number:number o_merid} {
+    clock format [clock scan "8:00:00 am" -gmt true -base $5amPST] \
+	    -format {%b %d, %Y %H:%M:%S} -gmt true
+} "Dec 31, 1999 08:00:00"
+test clock-34.24 {clock scan, number:number:number o_merid} {
+    clock format [clock scan "8:00:00 pm" -gmt true -base $5amPST] \
+	    -format {%b %d, %Y %H:%M:%S} -gmt true
+} "Dec 31, 1999 20:00:00"
+test clock-34.25 {clock scan, number:number:number-timezone} {
+    clock format [clock scan "00:00:30-0800" -gmt true -base $5amPST] \
+	    -format {%b %d, %Y %H:%M:%S} -gmt true
+} "Dec 31, 1999 08:00:30"
+test clock-34.26 {clock scan, DST for days} {
+    clock scan "tomorrow" -base [clock scan "19991031 00:00:00"]
+} [clock scan "19991101 00:00:00"]
+test clock-34.27 {clock scan, DST for days} {
+    clock scan "yesterday" -base [clock scan "19991101 00:00:00"]
+} [clock scan "19991031 00:00:00"]
+test clock-34.28 {clock scan, day} {
+    clock format [clock scan "Monday" -gmt true -base 946627200] \
+	    -format {%b %d, %Y %H:%M:%S} -gmt true
+} "Jan 03, 2000 00:00:00"
+test clock-34.29 {clock scan, number/number} {
+    clock format [clock scan "1/1" -gmt true -base 946627200] \
+	    -format {%b %d, %Y %H:%M:%S} -gmt true
+} "Jan 01, 1999 00:00:00"
+test clock-34.30 {clock scan, number/number} {
+    clock format [clock scan "1/1/1999" -gmt true -base 946627200] \
+	    -format {%b %d, %Y %H:%M:%S} -gmt true
+} "Jan 01, 1999 00:00:00"
+test clock-34.31 {clock scan, number/number} {
+    clock format [clock scan "19990101" -gmt true -base 946627200] \
+	    -format {%b %d, %Y %H:%M:%S} -gmt true
+} "Jan 01, 1999 00:00:00"
+test clock-34.32 {clock scan, relative minutes} {
+    clock scan "now + 1 minute" -base 946627200
+} 946627260
+test clock-34.33 {clock scan, relative minutes} {
+    clock scan "now +1 minute" -base 946627200
+} 946627260
+test clock-34.34 {clock scan, relative minutes} {
+    clock scan "now 1 minute" -base 946627200
+} 946627260
+test clock-34.35 {clock scan, relative minutes} {
+    clock scan "now - 1 minute" -base 946627200
+} 946627140
+test clock-34.36 {clock scan, relative minutes} {
+    clock scan "now -1 minute" -base 946627200
+} 946627140
+test clock-34.37 {clock scan, day of week} {
+    clock format [clock scan "wednesday" -base [clock scan 20000112]] \
+	    -format {%b %d, %Y}
+} "Jan 12, 2000"
+test clock-34.38 {clock scan, next day of week} {
+    clock format [clock scan "next wednesday" -base [clock scan 20000112]] \
+	    -format {%b %d, %Y}
+} "Jan 19, 2000"
+test clock-34.39 {clock scan, day of week} {
+    clock format [clock scan "thursday" -base [clock scan 20000112]] \
+	    -format {%b %d, %Y}
+} "Jan 13, 2000"
+test clock-34.40 {clock scan, next day of week} {
+    clock format [clock scan "next thursday" -base [clock scan 20000112]] \
+	    -format {%b %d, %Y}
+} "Jan 20, 2000"
+
+# weekday specification and base.
+test clock-34.41 {2nd monday in november} {
+    set res {}
+    foreach i {91 92 93 94 95 96} {
+      set nov8th [clock scan 11/8/$i]
+      set monday [clock scan monday -base $nov8th]
+      lappend res [clock format $monday -format %Y-%m-%d]
+    }
+    set res
+} {1991-11-11 1992-11-09 1993-11-08 1994-11-14 1995-11-13 1996-11-11}
+test clock-34.42 {2nd monday in november (2nd try)} {
+    set res {}
+    foreach i {91 92 93 94 95 96} {
+      set nov1th [clock scan 11/1/$i]
+      set monday [clock scan "2 monday" -base $nov1th]
+      lappend res [clock format $monday -format %Y-%m-%d]
+    }
+    set res
+} {1991-11-11 1992-11-09 1993-11-08 1994-11-14 1995-11-13 1996-11-11}
+test clock-34.43 {last monday in november} {
+    set res {}
+    foreach i {91 92 93 94 95 96} {
+      set dec1th [clock scan 12/1/$i]
+      set monday [clock scan "monday 1 week ago" -base $dec1th]
+      lappend res [clock format $monday -format %Y-%m-%d]
+    }
+    set res
+} {1991-11-25 1992-11-30 1993-11-29 1994-11-28 1995-11-27 1996-11-25}
+
+test clock-34.44 {2nd monday in november} {
+    set res {}
+    foreach i {91 92 93 94 95 96} {
+      set nov8th [clock scan 11/8/$i -gmt 1]
+      set monday [clock scan monday -base $nov8th -gmt 1]
+      lappend res [clock format $monday -format %Y-%m-%d -gmt 1]
+    }
+    set res
+} {1991-11-11 1992-11-09 1993-11-08 1994-11-14 1995-11-13 1996-11-11}
+test clock-34.45 {2nd monday in november (2nd try)} {
+    set res {}
+    foreach i {91 92 93 94 95 96} {
+      set nov1th [clock scan 11/1/$i -gmt 1]
+      set monday [clock scan "2 monday" -base $nov1th -gmt 1]
+      lappend res [clock format $monday -format %Y-%m-%d -gmt 1]
+    }
+    set res
+} {1991-11-11 1992-11-09 1993-11-08 1994-11-14 1995-11-13 1996-11-11}
+test clock-34.46 {last monday in november} {
+    set res {}
+    foreach i {91 92 93 94 95 96} {
+      set dec1th [clock scan 12/1/$i -gmt 1]
+      set monday [clock scan "monday 1 week ago" -base $dec1th -gmt 1]
+      lappend res [clock format $monday -format %Y-%m-%d -gmt 1]
+    }
+    set res
+} {1991-11-25 1992-11-30 1993-11-29 1994-11-28 1995-11-27 1996-11-25}
+test clock-34.47 {ago with multiple relative units} {
+    set base [clock scan "12/31/1999 00:00:00"]
+    set res [clock scan "2 days 2 hours ago" -base $base]
+    expr {$base - $res}
+} 180000
+
+test clock-34.48 {more than one ToD} {*}{
+    -body {clock scan {10:00 11:00}} 
+    -returnCodes error
+    -result {unable to convert date-time string "10:00 11:00": more than one time of day in string}
+}
+
+test clock-34.49 {more than one date} {*}{
+    -body {clock scan {1/1/2001 2/2/2002}} 
+    -returnCodes error
+    -result {unable to convert date-time string "1/1/2001 2/2/2002": more than one date in string}
+}
+
+test clock-34.50 {more than one time zone} {*}{
+    -body {clock scan {10:00 EST CST}} 
+    -returnCodes error
+    -result {unable to convert date-time string "10:00 EST CST": more than one time zone in string}
+}
+
+test clock-34.51 {more than one weekday} {*}{
+    -body {clock scan {Monday Tuesday}} 
+    -returnCodes error
+    -result {unable to convert date-time string "Monday Tuesday": more than one weekday in string}
+}
+
+test clock-34.52 {more than one ordinal month} {*}{
+    -body {clock scan {next January next March}} 
+    -returnCodes error
+    -result {unable to convert date-time string "next January next March": more than one ordinal month in string}
+}
+
+
+
+# clock seconds
+test clock-35.1 {clock seconds tests} {
+    expr [clock seconds]+1
+    concat {}
+} {}
+test clock-35.2 {clock seconds tests} {
+    list [catch {clock seconds foo} msg] $msg
+} {1 {wrong # args: should be "clock seconds"}}
+test clock-35.3 {clock seconds tests} {
+    set start [clock seconds]
+    after 2000
+    set end [clock seconds]
+    expr "$end > $start"
+} {1}
+
+
+test clock-36.1 {clock scan next monthname} {
+    clock format [clock scan "next june" -base [clock scan "june 1, 2000"]] \
+	    -format %m.%Y
+} "06.2001"
+test clock-36.2 {clock scan next monthname} {
+    clock format [clock scan "next july" -base [clock scan "june 1, 2000"]] \
+	    -format %m.%Y
+} "07.2000"
+test clock-36.3 {clock scan next monthname} {
+    clock format [clock scan "next may" -base [clock scan "june 1, 2000"]] \
+	    -format %m.%Y
+} "05.2001"
+
+test clock-37.1 {%s gmt testing} {
+    set s [clock seconds]
+    set a [clock format $s -format %s -gmt 0]
+    set b [clock format $s -format %s -gmt 1]
+    # %s, being the difference between local and Greenwich, does not
+    # depend on the time zone.
+    set c [expr {$b-$a}]
+} {0}
+
+test clock-38.1 {regression - convertUTCToLocalViaC - east of Greenwich} \
+    -setup {
+	if { [info exists env(TZ)] } {
+	    set oldTZ $env(TZ)
+	}
+	set env(TZ) CET-01:00CEST-02:00,M3.5.0/02:00,M10.5.0/03:00
+    } \
+    -body {
+	clock format 0 -format %H:%M:%S -timezone :localtime
+    } \
+    -cleanup {
+	if { [info exists oldTZ] } {
+	    set env(TZ) $oldTZ
+	    unset oldTZ
+	} else {
+	    unset env(TZ)
+	}
+    } \
+    -result {01:00:00}
+
+test clock-38.2 {make sure TZ is not cached after unset} \
+    -setup {
+	if { [info exists env(TZ)] } {
+	    set oldTZ $env(TZ)
+            unset env(TZ)
+	}
+	if { [info exists env(TCL_TZ)] } {
+	    set oldTCLTZ $env(TCL_TZ)
+            unset env(TCL_TZ)
+	}
+    } \
+    -body {
+        set t1 [clock format 0]
+        # a time zone that is unlikely to anywhere
+        set env(TZ) "+04:20"
+        set t2 [clock format 0]
+        unset env(TZ)
+        set t3 [clock format 0]
+        expr {$t1 eq $t3 && $t1 ne $t2}
+    } \
+    -cleanup {
+        if { [info exists oldTZ] } {
+            set env(TZ) $oldTZ
+            unset oldTZ
+        }
+        if { [info exists oldTclTZ] } {
+            set env(TCL_TZ) $oldTclTZ
+            unset oldTclTZ
+        }
+    } \
+    -result 1
+        
+
+test clock-39.1 {regression - synonym timezones} {
+    clock format 0 -format {%H:%M:%S} -timezone :US/Eastern
+} {19:00:00}
+
+test clock-40.1 {regression - bad month with -timezone :localtime} \
+    -setup {
+	if { [info exists env(TZ)] } {
+	    set oldTZ $env(TZ)
+	}
+	set env(TZ) UTC0
+    } \
+    -body {
+	clock scan 2000-01-01T00:00:00 -timezone :localtime \
+	    -format %Y-%m-%dT%H:%M:%S
+    } \
+    -cleanup {
+	if { [info exists oldTZ] } {
+	    set env(TZ) $oldTZ
+	    unset oldTZ
+	} else {
+	    unset env(TZ)
+	}
+    } \
+    -result 946684800
+
+test clock-41.1 {regression test - format group %k when hour is 0 } {
+    clock format 0 -format %k -gmt true
+} { 0}
+
+test clock-42.1 {regression test - %z in :localtime when west of Greenwich } \
+    -setup {
+	if { [info exists env(TZ)] } {
+	    set oldTZ $env(TZ)
+	}
+	set env(TZ) EST5
+    } \
+    -body {
+	clock format 0 -format %z -timezone :localtime
+    } \
+    -cleanup {
+	if { [info exists oldTZ] } {
+	    set env(TZ) $oldTZ
+	    unset oldTZ
+	} else {
+	    unset env(TZ)
+	}
+    } \
+    -result {-0500}
+
+# 43.1 was a bad test - mktime returning -1 is an error according to posix.
+
+test clock-44.1 {regression test - time zone name containing hyphen } \
+    -setup {
+	if { [info exists env(TZ)] } {
+	    set oldTZ $env(TZ)
+	}
+	set env(TZ) US/East-Indiana
+    } \
+    -body {
+	clock format 1098466496 -format %H:%M:%S%z -timezone US/East-Indiana
+    } \
+    -cleanup {
+	if { [info exists oldTZ] } {
+	    set env(TZ) $oldTZ
+	    unset oldTZ
+	} else {
+	    unset env(TZ)
+	}
+    } \
+    -result {12:34:56-0500}
+    
+test clock-45.1 {regression test - time zone containing only two digits} \
+    -body {
+	clock scan 1985-04-12T10:15:30+04 -format %Y-%m-%dT%H:%M:%S%Z
+    } \
+    -result 482134530
+
+test clock-46.1 {regression test - month zero} \
+    -body {
+	clock scan 2004-00-00 -format %Y-%m-%d
+    } -result [clock scan 2003-11-30 -format %Y-%m-%d]
+test clock-46.2 {regression test - month zero} \
+    -body {
+	clock scan 20040000
+    } -result [clock scan 2003-11-30 -format %Y-%m-%d]
+test clock-46.3 {regression test - month thirteen} \
+    -body {
+	clock scan 2004-13-01 -format %Y-%m-%d
+    } -result [clock scan 2005-01-01 -format %Y-%m-%d]
+test clock-46.4 {regression test - month thirteen} \
+    -body {
+	clock scan 20041301
+    } -result [clock scan 2005-01-01 -format %Y-%m-%d]
+
+test clock-47.1 {regression test - four-digit time} {
+    clock scan 0012
+} [clock scan 0012 -format %H%M]
+test clock-47.2 {regression test - four digit time} {
+    clock scan 0039
+} [clock scan 0039 -format %H%M]
+
+test clock-48.1 {Bug 1185933: 'i' destroyed by clock init} -setup {
+    interp create child
+} -body {
+    interp eval child {
+	set i 12345
+	clock format 0
+	list [catch { set i } result] $result
+    }
+} -cleanup {
+    interp delete child
+} -result {0 12345}
+
+test clock-49.1 {regression test - localtime with negative arg (Bug 1237907)} \
+    -body {
+	list [catch { 
+	    clock format -86400 -timezone :localtime -format %Y
+	} result] $result
+    } \
+    -match regexp \
+    -result {0 1969|1 {localtime failed \(clock value may be too large/small to represent\)}}
+
+test clock-49.2 {regression test - missing time zone file (Bug 1237907)} \
+    -constraints win \
+    -setup {
+	# override the registry so that the test takes place in New York time
+	namespace eval ::tcl::clock {
+	    namespace import -force ::testClock::registry
+	}
+	set noreg [info exists ::tcl::clock::NoRegistry]
+	if {$noreg} {unset ::tcl::clock::NoRegistry}
+	if { [info exists env(TZ)] } {
+	    set oldTZ $env(TZ)
+	    unset env(TZ)
+	}
+	if { [info exists env(TCL_TZ)] } {
+	    set oldTclTZ $env(TCL_TZ)
+	    unset env(TCL_TZ)
+	}
+	# make it so New York time is a missing file
+	dict set ::tcl::clock::WinZoneInfo \
+	    {-18000 0 3600 0 11 0 1 2 0 0 0 0 3 0 2 2 0 0 0} \
+	    :No/Such/File
+	::tcl::clock::ClearCaches
+    } \
+    -body {
+	list [::tcl::clock::GuessWindowsTimeZone] \
+	    [clock format 0 -locale system -format "%H:%M:%S %Z"] \
+	    [clock format -86400 -format "%Y"]
+    } \
+    -cleanup {
+	# restore the registry and environment
+	namespace eval ::tcl::clock {
+	    rename registry {}
+	}
+	if {$noreg} {set ::tcl::clock::NoRegistry {}}
+	if { [info exists oldTclTZ] } {
+	    set env(TCL_TZ) $oldTclTZ
+	}
+	if { [info exists oldTZ] } {
+	    set env(TZ) $oldTZ
+	}
+	# put New York back on the map
+	dict set ::tcl::clock::WinZoneInfo \
+	    {-18000 0 3600 0 11 0 1 2 0 0 0 0 3 0 2 2 0 0 0} \
+	    :America/New_York
+	::tcl::clock::ClearCaches
+    } \
+    -result {<-0500>+05:00:00<-0400>+04:00:00,M3.2.0/02:00:00,M11.1.0/02:00:00 {19:00:00 -0500} 1969}
+
+test clock-50.1 {format / scan -1 as a local time} {
+    if {[catch {
+	clock scan \
+	    [clock format -1 -format %Y%m%d%H%M%S -timezone :localtime] \
+	    -format %Y%m%d%H%M%S -timezone :localtime
+    } result]} {
+	if { [regexp " too large" $result] } {
+	    set result -1
+	}
+    }
+    set result
+} -1
+test clock-50.2 {format / scan -2 as a local time} {
+    if {[catch {
+	clock scan \
+	    [clock format -2 -format %Y%m%d%H%M%S -timezone :localtime] \
+	    -format %Y%m%d%H%M%S -timezone :localtime
+    } result]} {
+	if { [regexp " too large" $result] } {
+	    set result -2
+	}
+    }
+    set result
+} -2
+
+test clock-51.1 {correct conversion of times in Sydney} {
+    # Paul Mackerras reported a bug where DST rollover in New South Wales
+    # was miscalculated.  The problem was that tclZIC.tcl had a
+    # typo in the switch case where DST begins/ends at a given time
+    # Standard Time (that is, winter time).
+    set result {}
+    foreach t {1130601599 1130601600 1130637599 1130637600} {
+	lappend result [clock format $t -format %H:%M:%S \
+			    -timezone :Australia/Sydney]
+    }
+    set result
+} {01:59:59 03:00:00 12:59:59 13:00:00}
+
+test clock-52.1 {Posix timezone and conversion on last Sunday} {
+    # Martin Lemburg reported a bug where if tzdata is missing, then
+    # times are converted incorrectly in locales where DST conversion
+    # happens in the last (nominal 5th) week of a month.
+    set result {}
+    set timezone <MEZ>-01:00:00<MESZ>-02:00:00,M3.5.0/02:00:00,M10.5.0/01:00:00
+    foreach t {1143334799 1143334800} {
+	lappend result [clock format $t -format %H:%M:%S -timezone $timezone] \
+	    [clock format $t -format %H:%M:%S -timezone :Europe/Berlin]
+    }
+    set result
+} {01:59:59 01:59:59 03:00:00 03:00:00}
+
+test clock-52.2 {correct conversion of times in Europe} {
+   # [Bug 2207436]
+   set result {}
+   foreach t [list 1206838799 1206838800 1224982799 1224982800] {
+       lappend result [clock format $t -format %H:%M:%S \
+                           -timezone MET-1METDST]
+       lappend result [clock format $t -format %H:%M:%S \
+                           -timezone MET0METDST]
+   }
+   set result
+} {01:59:59 00:59:59 03:00:00 02:00:00 02:59:59 01:59:59 02:00:00 01:00:00}
+
+test clock-52.3 {correct conversion of times in Russia} {
+   # [Bug 2207436]
+   set result {}
+   foreach t [list 1206799199 1206799200 1224943199 1224943200] {
+       lappend result [clock format $t -format %H:%M:%S \
+                           -timezone WST-12WSTDST]
+   }
+   set result
+} {01:59:59 03:00:00 02:59:59 02:00:00}
+
+test clock-52.4 {correct conversion of times in USA} {
+   # [Bug 2207436]
+   set result {}
+   foreach t [list 1268549999 1268550000 1257055199 1257055200] {
+       lappend result [clock format $t -format %H:%M:%S \
+                           -timezone EST5EDT]
+   }
+   set result
+} {01:59:59 03:00:00 01:59:59 01:00:00}
+
+# Regression test for Bug # 1505383
+
+test clock-53.1 {%EC %Ey} {
+    clock format 0 -gmt true -locale en_US_roman -format %EC%Ey
+} mcmlxx
+
+# Test that glob-special characters can be handled in [clock]
+
+test clock-54.1 {glob specials in [clock format]} \
+    -setup {
+	clock format 0 -gmt 1 -format %Y
+    } \
+    -body {
+	clock format 0 -gmt 1 -format {*[%Y%m%d]*}
+    } \
+    -result {*[19700101]*}
+test clock-54.2 {glob specials in [clock scan]} \
+    -setup {
+	clock scan 1970 -gmt 1 -format %Y
+    } \
+    -body {
+	clock scan {*[19700101]*} -format {*[%Y%m%d]*} -gmt 1
+    } \
+    -result 0
+
+test clock-55.1 {Common Era} {
+    clock format -62135769600 -gmt 1 -format {%d %m %Y %EE}
+} {01 01 0001 C.E.}
+test clock-55.2 {Common Era} {
+    clock format -62135769600 -gmt 1 -format {%d %m %Y %EE} -locale en_US_roman
+} {01 01 0001 Anno Domini}
+test clock-55.3 {Before the Common Era} {
+    clock format -62135769601 -gmt 1 -format {%d %m %Y %EE}
+} {31 12 0001 B.C.E.}
+test clock-55.4 {Before the Common Era} {
+    clock format -62135769601 -gmt 1 -format {%d %m %Y %EE} -locale en_US_roman
+} {31 12 0001 Before Christ}
+test clock-55.5 {Common Era} {
+    clock scan {01 01 0001 C.E.} \
+	-gmt 1 -format {%d %m %Y %EE} -locale en_US_roman
+} -62135769600
+test clock-55.6 {Common Era} {
+    clock scan {01 01 0001 A.D.} \
+	-gmt 1 -format {%d %m %Y %EE} -locale en_US_roman
+} -62135769600
+test clock-55.7 {Common Era} {
+    clock scan {01 01 0001 Anno Domini} \
+	-gmt 1 -format {%d %m %Y %EE} -locale en_US_roman
+} -62135769600
+test clock-55.8 {Before the Common Era} {
+    clock scan {31 12 0001 B.C.E.} \
+	-gmt 1 -format {%d %m %Y %EE} -locale en_US_roman
+} -62135856000
+test clock-55.9 {Common Era} {
+    clock scan {31 12 0001 B.C.} \
+	-gmt 1 -format {%d %m %Y %EE} -locale en_US_roman
+} -62135856000
+test clock-55.10 {Common Era} {
+    clock scan {31 12 0001 Before Christ} \
+	-gmt 1 -format {%d %m %Y %EE} -locale en_US_roman
+} -62135856000
+
+test clock-56.1 {use of zoneinfo, version 1} {*}{
+    -setup {
+	clock format [clock seconds]
+	set tzdir [makeDirectory zoneinfo]
+	set tzdir2 [makeDirectory Test $tzdir]
+	set tzfile [makeFile {} PhoenixOne $tzdir2]
+	set f [open $tzfile wb]
+	puts -nonewline $f [binary format c* {
+	    0x54 0x5a 0x69 0x66 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
+	    0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x03
+	    0x00 0x00 0x00 0x03 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x0a
+	    0x00 0x00 0x00 0x03 0x00 0x00 0x00 0x0c 0x9e 0xa6 0x3a 0x90
+	    0x9f 0xbb 0x07 0x80 0xa0 0x86 0x1c 0x90 0xa1 0x9a 0xe9 0x80
+	    0xcb 0x89 0x0c 0x90 0xcf 0x17 0xdf 0x1c 0xcf 0x8f 0xe5 0xac
+	    0xd0 0x81 0x1a 0x1c 0xfa 0xf8 0x75 0x10 0xfb 0xe8 0x58 0x00
+	    0x00 0x01 0x00 0x01 0x02 0x01 0x02 0x01 0x00 0x01 0xff 0xff
+	    0xab 0xa0 0x01 0x00 0xff 0xff 0x9d 0x90 0x00 0x04 0xff 0xff
+	    0xab 0xa0 0x01 0x08 0x4d 0x44 0x54 0x00 0x4d 0x53 0x54 0x00
+	    0x4d 0x57 0x54 0x00 0x00 0x00 0x00 0x00 0x00 0x00
+	}]
+	close $f
+	set ::tcl::clock::ZoneinfoPaths \
+	    [linsert $::tcl::clock::ZoneinfoPaths 0 $tzdir]
+	::tcl::clock::ClearCaches
+    }
+    -cleanup {
+	set ::tcl::clock::ZoneinfoPaths \
+	    [lrange $::tcl::clock::ZoneinfoPaths 1 end]
+	::tcl::clock::ClearCaches
+	removeFile PhoenixOne $tzdir2
+	removeDirectory Test $tzdir
+	removeDirectory zoneinfo
+    }
+    -body {
+	clock format 1072940400 -timezone :Test/PhoenixOne \
+	    -format {%Y-%m-%d %H:%M:%S %Z}
+    }
+    -result {2004-01-01 00:00:00 MST}
+}
+	    
+test clock-56.2 {use of zoneinfo, version 2} {*}{
+    -setup {
+	clock format [clock seconds]
+	set tzdir [makeDirectory zoneinfo]
+	set tzdir2 [makeDirectory Test $tzdir]
+	set tzfile [makeFile {} PhoenixTwo $tzdir2]
+	set f [open $tzfile wb]
+	puts -nonewline $f [binary format c* {
+	    0x54 0x5a 0x69 0x66 0x32 0x00 0x00 0x00 0x00 0x00 0x00 0x00
+	    0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x03
+	    0x00 0x00 0x00 0x03 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x0a
+	    0x00 0x00 0x00 0x03 0x00 0x00 0x00 0x0c 0x9e 0xa6 0x3a 0x90
+	    0x9f 0xbb 0x07 0x80 0xa0 0x86 0x1c 0x90 0xa1 0x9a 0xe9 0x80
+	    0xcb 0x89 0x0c 0x90 0xcf 0x17 0xdf 0x1c 0xcf 0x8f 0xe5 0xac
+	    0xd0 0x81 0x1a 0x1c 0xfa 0xf8 0x75 0x10 0xfb 0xe8 0x58 0x00
+	    0x00 0x01 0x00 0x01 0x02 0x01 0x02 0x01 0x00 0x01 0xff 0xff
+	    0xab 0xa0 0x01 0x00 0xff 0xff 0x9d 0x90 0x00 0x04 0xff 0xff
+	    0xab 0xa0 0x01 0x08 0x4d 0x44 0x54 0x00 0x4d 0x53 0x54 0x00
+	    0x4d 0x57 0x54 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x54 0x5a
+	    0x69 0x66 0x32 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
+	    0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x04 0x00 0x00
+	    0x00 0x04 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x0b 0x00 0x00
+	    0x00 0x04 0x00 0x00 0x00 0x10 0xff 0xff 0xff 0xff 0x5e 0x04
+	    0x0c 0xb0 0xff 0xff 0xff 0xff 0x9e 0xa6 0x3a 0x90 0xff 0xff
+	    0xff 0xff 0x9f 0xbb 0x07 0x80 0xff 0xff 0xff 0xff 0xa0 0x86
+	    0x1c 0x90 0xff 0xff 0xff 0xff 0xa1 0x9a 0xe9 0x80 0xff 0xff
+	    0xff 0xff 0xcb 0x89 0x0c 0x90 0xff 0xff 0xff 0xff 0xcf 0x17
+	    0xdf 0x1c 0xff 0xff 0xff 0xff 0xcf 0x8f 0xe5 0xac 0xff 0xff
+	    0xff 0xff 0xd0 0x81 0x1a 0x1c 0xff 0xff 0xff 0xff 0xfa 0xf8
+	    0x75 0x10 0xff 0xff 0xff 0xff 0xfb 0xe8 0x58 0x00 0x02 0x01
+	    0x02 0x01 0x02 0x03 0x02 0x03 0x02 0x01 0x02 0xff 0xff 0x96
+	    0xee 0x00 0x00 0xff 0xff 0xab 0xa0 0x01 0x04 0xff 0xff 0x9d
+	    0x90 0x00 0x08 0xff 0xff 0xab 0xa0 0x01 0x0c 0x4c 0x4d 0x54
+	    0x00 0x4d 0x44 0x54 0x00 0x4d 0x53 0x54 0x00 0x4d 0x57 0x54
+	    0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x0a 0x4d 0x53
+	    0x54 0x37 0x0a
+	}]
+	close $f
+	set ::tcl::clock::ZoneinfoPaths \
+	    [linsert $::tcl::clock::ZoneinfoPaths 0 $tzdir]
+	::tcl::clock::ClearCaches
+    }
+    -cleanup {
+	set ::tcl::clock::ZoneinfoPaths \
+	    [lrange $::tcl::clock::ZoneinfoPaths 1 end]
+	::tcl::clock::ClearCaches
+	removeFile PhoenixTwo $tzdir2
+	removeDirectory Test $tzdir
+	removeDirectory zoneinfo
+    } 
+    -body {
+	clock format 1072940400 -timezone :Test/PhoenixTwo \
+	    -format {%Y-%m-%d %H:%M:%S %Z}
+    }
+    -result {2004-01-01 00:00:00 MST}
+}
+
+test clock-56.3 {use of zoneinfo, version 2, Y2038 compliance} {*}{
+    -setup {
+	clock format [clock seconds]
+	set tzdir [makeDirectory zoneinfo]
+	set tzdir2 [makeDirectory Test $tzdir]
+	set tzfile [makeFile {} TijuanaTwo $tzdir2]
+	set f [open $tzfile wb]
+	puts -nonewline $f [binary format c* {
+            0x54 0x5a 0x69 0x66 0x32 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
+            0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x06 0x00 0x00
+            0x00 0x06 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x95 0x00 0x00 0x00
+            0x06 0x00 0x00 0x00 0x18 0xa5 0xb6 0xf6 0x80 0xa9 0x79 0x4f 0x70
+            0xaf 0xf2 0x7c 0xf0 0xb6 0x66 0x64 0x70 0xb7 0x1b 0x10 0x00 0xb8
+            0x0a 0xf2 0xf0 0xcb 0xea 0x8d 0x80 0xd2 0x23 0xf4 0x70 0xd2 0x99
+            0xba 0x70 0xd7 0x1b 0x59 0x00 0xd8 0x91 0xb4 0xf0 0xe2 0x7e 0x59
+            0xa0 0xe3 0x49 0x52 0x90 0xe4 0x5e 0x3b 0xa0 0xe5 0x29 0x34 0x90
+            0xe6 0x47 0x58 0x20 0xe7 0x12 0x51 0x10 0xe8 0x27 0x3a 0x20 0xe8
+            0xf2 0x33 0x10 0xea 0x07 0x1c 0x20 0xea 0xd2 0x15 0x10 0xeb 0xe6
+            0xfe 0x20 0xec 0xb1 0xf7 0x10 0xed 0xc6 0xe0 0x20 0xee 0x91 0xd9
+            0x10 0x0b 0xe0 0xaf 0xa0 0x0c 0xd9 0xcd 0x10 0x0d 0xc0 0x91 0xa0
+            0x0e 0xb9 0xaf 0x10 0x0f 0xa9 0xae 0x20 0x10 0x99 0x91 0x10 0x11
+            0x89 0x90 0x20 0x12 0x79 0x73 0x10 0x13 0x69 0x72 0x20 0x14 0x59
+            0x55 0x10 0x15 0x49 0x54 0x20 0x16 0x39 0x37 0x10 0x17 0x29 0x36
+            0x20 0x18 0x22 0x53 0x90 0x19 0x09 0x18 0x20 0x1a 0x02 0x35 0x90
+            0x1a 0xf2 0x34 0xa0 0x1b 0xe2 0x17 0x90 0x1c 0xd2 0x16 0xa0 0x1d
+            0xc1 0xf9 0x90 0x1e 0xb1 0xf8 0xa0 0x1f 0xa1 0xdb 0x90 0x20 0x76
+            0x2b 0x20 0x21 0x81 0xbd 0x90 0x22 0x56 0x0d 0x20 0x23 0x6a 0xda
+            0x10 0x24 0x35 0xef 0x20 0x25 0x4a 0xbc 0x10 0x26 0x15 0xd1 0x20
+            0x27 0x2a 0x9e 0x10 0x27 0xfe 0xed 0xa0 0x29 0x0a 0x80 0x10 0x29
+            0xde 0xcf 0xa0 0x2a 0xea 0x62 0x10 0x2b 0xbe 0xb1 0xa0 0x2c 0xd3
+            0x7e 0x90 0x2d 0x9e 0x93 0xa0 0x2e 0xb3 0x60 0x90 0x2f 0x7e 0x75
+            0xa0 0x30 0x93 0x42 0x90 0x31 0x67 0x92 0x20 0x32 0x73 0x24 0x90
+            0x33 0x47 0x74 0x20 0x34 0x53 0x06 0x90 0x35 0x27 0x56 0x20 0x36
+            0x32 0xe8 0x90 0x37 0x07 0x38 0x20 0x38 0x1c 0x05 0x10 0x38 0xe7
+            0x1a 0x20 0x39 0xfb 0xe7 0x10 0x3a 0xc6 0xfc 0x20 0x3b 0xdb 0xc9
+            0x10 0x3c 0xb0 0x18 0xa0 0x3d 0xbb 0xab 0x10 0x3e 0x8f 0xfa 0xa0
+            0x3f 0x9b 0x8d 0x10 0x40 0x6f 0xdc 0xa0 0x41 0x84 0xa9 0x90 0x42
+            0x4f 0xbe 0xa0 0x43 0x64 0x8b 0x90 0x44 0x2f 0xa0 0xa0 0x45 0x44
+            0x6d 0x90 0x46 0x0f 0x82 0xa0 0x47 0x24 0x4f 0x90 0x47 0xf8 0x9f
+            0x20 0x49 0x04 0x31 0x90 0x49 0xd8 0x81 0x20 0x4a 0xe4 0x13 0x90
+            0x4b 0xb8 0x63 0x20 0x4c 0xcd 0x30 0x10 0x4d 0x98 0x45 0x20 0x4e
+            0xad 0x12 0x10 0x4f 0x78 0x27 0x20 0x50 0x8c 0xf4 0x10 0x51 0x61
+            0x43 0xa0 0x52 0x6c 0xd6 0x10 0x53 0x41 0x25 0xa0 0x54 0x4c 0xb8
+            0x10 0x55 0x21 0x07 0xa0 0x56 0x2c 0x9a 0x10 0x57 0x00 0xe9 0xa0
+            0x58 0x15 0xb6 0x90 0x58 0xe0 0xcb 0xa0 0x59 0xf5 0x98 0x90 0x5a
+            0xc0 0xad 0xa0 0x5b 0xd5 0x7a 0x90 0x5c 0xa9 0xca 0x20 0x5d 0xb5
+            0x5c 0x90 0x5e 0x89 0xac 0x20 0x5f 0x95 0x3e 0x90 0x60 0x69 0x8e
+            0x20 0x61 0x7e 0x5b 0x10 0x62 0x49 0x70 0x20 0x63 0x5e 0x3d 0x10
+            0x64 0x29 0x52 0x20 0x65 0x3e 0x1f 0x10 0x66 0x12 0x6e 0xa0 0x67
+            0x1e 0x01 0x10 0x67 0xf2 0x50 0xa0 0x68 0xfd 0xe3 0x10 0x69 0xd2
+            0x32 0xa0 0x6a 0xdd 0xc5 0x10 0x6b 0xb2 0x14 0xa0 0x6c 0xc6 0xe1
+            0x90 0x6d 0x91 0xf6 0xa0 0x6e 0xa6 0xc3 0x90 0x6f 0x71 0xd8 0xa0
+            0x70 0x86 0xa5 0x90 0x71 0x5a 0xf5 0x20 0x72 0x66 0x87 0x90 0x73
+            0x3a 0xd7 0x20 0x74 0x46 0x69 0x90 0x75 0x1a 0xb9 0x20 0x76 0x2f
+            0x86 0x10 0x76 0xfa 0x9b 0x20 0x78 0x0f 0x68 0x10 0x78 0xda 0x7d
+            0x20 0x79 0xef 0x4a 0x10 0x7a 0xba 0x5f 0x20 0x7b 0xcf 0x2c 0x10
+            0x7c 0xa3 0x7b 0xa0 0x7d 0xaf 0x0e 0x10 0x7e 0x83 0x5d 0xa0 0x7f
+            0x8e 0xf0 0x10 0x01 0x02 0x01 0x02 0x03 0x02 0x04 0x05 0x02 0x03
+            0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02
+            0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03
+            0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02
+            0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03
+            0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02
+            0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03
+            0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02
+            0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03
+            0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02
+            0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03
+            0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0xff 0xff 0x92 0x4c
+            0x00 0x00 0xff 0xff 0x9d 0x90 0x00 0x04 0xff 0xff 0x8f 0x80 0x00
+            0x08 0xff 0xff 0x9d 0x90 0x01 0x0c 0xff 0xff 0x9d 0x90 0x01 0x10
+            0xff 0xff 0x9d 0x90 0x01 0x14 0x4c 0x4d 0x54 0x00 0x4d 0x53 0x54
+            0x00 0x50 0x53 0x54 0x00 0x50 0x44 0x54 0x00 0x50 0x57 0x54 0x00
+            0x50 0x50 0x54 0x00 0x00 0x00 0x00 0x00 0x00 0x01 0x00 0x00 0x00
+            0x00 0x00 0x01 0x54 0x5a 0x69 0x66 0x32 0x00 0x00 0x00 0x00 0x00
+            0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
+            0x06 0x00 0x00 0x00 0x06 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x95
+            0x00 0x00 0x00 0x06 0x00 0x00 0x00 0x18 0xff 0xff 0xff 0xff 0xa5
+            0xb6 0xf6 0x80 0xff 0xff 0xff 0xff 0xa9 0x79 0x4f 0x70 0xff 0xff
+            0xff 0xff 0xaf 0xf2 0x7c 0xf0 0xff 0xff 0xff 0xff 0xb6 0x66 0x64
+            0x70 0xff 0xff 0xff 0xff 0xb7 0x1b 0x10 0x00 0xff 0xff 0xff 0xff
+            0xb8 0x0a 0xf2 0xf0 0xff 0xff 0xff 0xff 0xcb 0xea 0x8d 0x80 0xff
+            0xff 0xff 0xff 0xd2 0x23 0xf4 0x70 0xff 0xff 0xff 0xff 0xd2 0x99
+            0xba 0x70 0xff 0xff 0xff 0xff 0xd7 0x1b 0x59 0x00 0xff 0xff 0xff
+            0xff 0xd8 0x91 0xb4 0xf0 0xff 0xff 0xff 0xff 0xe2 0x7e 0x59 0xa0
+            0xff 0xff 0xff 0xff 0xe3 0x49 0x52 0x90 0xff 0xff 0xff 0xff 0xe4
+            0x5e 0x3b 0xa0 0xff 0xff 0xff 0xff 0xe5 0x29 0x34 0x90 0xff 0xff
+            0xff 0xff 0xe6 0x47 0x58 0x20 0xff 0xff 0xff 0xff 0xe7 0x12 0x51
+            0x10 0xff 0xff 0xff 0xff 0xe8 0x27 0x3a 0x20 0xff 0xff 0xff 0xff
+            0xe8 0xf2 0x33 0x10 0xff 0xff 0xff 0xff 0xea 0x07 0x1c 0x20 0xff
+            0xff 0xff 0xff 0xea 0xd2 0x15 0x10 0xff 0xff 0xff 0xff 0xeb 0xe6
+            0xfe 0x20 0xff 0xff 0xff 0xff 0xec 0xb1 0xf7 0x10 0xff 0xff 0xff
+            0xff 0xed 0xc6 0xe0 0x20 0xff 0xff 0xff 0xff 0xee 0x91 0xd9 0x10
+            0x00 0x00 0x00 0x00 0x0b 0xe0 0xaf 0xa0 0x00 0x00 0x00 0x00 0x0c
+            0xd9 0xcd 0x10 0x00 0x00 0x00 0x00 0x0d 0xc0 0x91 0xa0 0x00 0x00
+            0x00 0x00 0x0e 0xb9 0xaf 0x10 0x00 0x00 0x00 0x00 0x0f 0xa9 0xae
+            0x20 0x00 0x00 0x00 0x00 0x10 0x99 0x91 0x10 0x00 0x00 0x00 0x00
+            0x11 0x89 0x90 0x20 0x00 0x00 0x00 0x00 0x12 0x79 0x73 0x10 0x00
+            0x00 0x00 0x00 0x13 0x69 0x72 0x20 0x00 0x00 0x00 0x00 0x14 0x59
+            0x55 0x10 0x00 0x00 0x00 0x00 0x15 0x49 0x54 0x20 0x00 0x00 0x00
+            0x00 0x16 0x39 0x37 0x10 0x00 0x00 0x00 0x00 0x17 0x29 0x36 0x20
+            0x00 0x00 0x00 0x00 0x18 0x22 0x53 0x90 0x00 0x00 0x00 0x00 0x19
+            0x09 0x18 0x20 0x00 0x00 0x00 0x00 0x1a 0x02 0x35 0x90 0x00 0x00
+            0x00 0x00 0x1a 0xf2 0x34 0xa0 0x00 0x00 0x00 0x00 0x1b 0xe2 0x17
+            0x90 0x00 0x00 0x00 0x00 0x1c 0xd2 0x16 0xa0 0x00 0x00 0x00 0x00
+            0x1d 0xc1 0xf9 0x90 0x00 0x00 0x00 0x00 0x1e 0xb1 0xf8 0xa0 0x00
+            0x00 0x00 0x00 0x1f 0xa1 0xdb 0x90 0x00 0x00 0x00 0x00 0x20 0x76
+            0x2b 0x20 0x00 0x00 0x00 0x00 0x21 0x81 0xbd 0x90 0x00 0x00 0x00
+            0x00 0x22 0x56 0x0d 0x20 0x00 0x00 0x00 0x00 0x23 0x6a 0xda 0x10
+            0x00 0x00 0x00 0x00 0x24 0x35 0xef 0x20 0x00 0x00 0x00 0x00 0x25
+            0x4a 0xbc 0x10 0x00 0x00 0x00 0x00 0x26 0x15 0xd1 0x20 0x00 0x00
+            0x00 0x00 0x27 0x2a 0x9e 0x10 0x00 0x00 0x00 0x00 0x27 0xfe 0xed
+            0xa0 0x00 0x00 0x00 0x00 0x29 0x0a 0x80 0x10 0x00 0x00 0x00 0x00
+            0x29 0xde 0xcf 0xa0 0x00 0x00 0x00 0x00 0x2a 0xea 0x62 0x10 0x00
+            0x00 0x00 0x00 0x2b 0xbe 0xb1 0xa0 0x00 0x00 0x00 0x00 0x2c 0xd3
+            0x7e 0x90 0x00 0x00 0x00 0x00 0x2d 0x9e 0x93 0xa0 0x00 0x00 0x00
+            0x00 0x2e 0xb3 0x60 0x90 0x00 0x00 0x00 0x00 0x2f 0x7e 0x75 0xa0
+            0x00 0x00 0x00 0x00 0x30 0x93 0x42 0x90 0x00 0x00 0x00 0x00 0x31
+            0x67 0x92 0x20 0x00 0x00 0x00 0x00 0x32 0x73 0x24 0x90 0x00 0x00
+            0x00 0x00 0x33 0x47 0x74 0x20 0x00 0x00 0x00 0x00 0x34 0x53 0x06
+            0x90 0x00 0x00 0x00 0x00 0x35 0x27 0x56 0x20 0x00 0x00 0x00 0x00
+            0x36 0x32 0xe8 0x90 0x00 0x00 0x00 0x00 0x37 0x07 0x38 0x20 0x00
+            0x00 0x00 0x00 0x38 0x1c 0x05 0x10 0x00 0x00 0x00 0x00 0x38 0xe7
+            0x1a 0x20 0x00 0x00 0x00 0x00 0x39 0xfb 0xe7 0x10 0x00 0x00 0x00
+            0x00 0x3a 0xc6 0xfc 0x20 0x00 0x00 0x00 0x00 0x3b 0xdb 0xc9 0x10
+            0x00 0x00 0x00 0x00 0x3c 0xb0 0x18 0xa0 0x00 0x00 0x00 0x00 0x3d
+            0xbb 0xab 0x10 0x00 0x00 0x00 0x00 0x3e 0x8f 0xfa 0xa0 0x00 0x00
+            0x00 0x00 0x3f 0x9b 0x8d 0x10 0x00 0x00 0x00 0x00 0x40 0x6f 0xdc
+            0xa0 0x00 0x00 0x00 0x00 0x41 0x84 0xa9 0x90 0x00 0x00 0x00 0x00
+            0x42 0x4f 0xbe 0xa0 0x00 0x00 0x00 0x00 0x43 0x64 0x8b 0x90 0x00
+            0x00 0x00 0x00 0x44 0x2f 0xa0 0xa0 0x00 0x00 0x00 0x00 0x45 0x44
+            0x6d 0x90 0x00 0x00 0x00 0x00 0x46 0x0f 0x82 0xa0 0x00 0x00 0x00
+            0x00 0x47 0x24 0x4f 0x90 0x00 0x00 0x00 0x00 0x47 0xf8 0x9f 0x20
+            0x00 0x00 0x00 0x00 0x49 0x04 0x31 0x90 0x00 0x00 0x00 0x00 0x49
+            0xd8 0x81 0x20 0x00 0x00 0x00 0x00 0x4a 0xe4 0x13 0x90 0x00 0x00
+            0x00 0x00 0x4b 0xb8 0x63 0x20 0x00 0x00 0x00 0x00 0x4c 0xcd 0x30
+            0x10 0x00 0x00 0x00 0x00 0x4d 0x98 0x45 0x20 0x00 0x00 0x00 0x00
+            0x4e 0xad 0x12 0x10 0x00 0x00 0x00 0x00 0x4f 0x78 0x27 0x20 0x00
+            0x00 0x00 0x00 0x50 0x8c 0xf4 0x10 0x00 0x00 0x00 0x00 0x51 0x61
+            0x43 0xa0 0x00 0x00 0x00 0x00 0x52 0x6c 0xd6 0x10 0x00 0x00 0x00
+            0x00 0x53 0x41 0x25 0xa0 0x00 0x00 0x00 0x00 0x54 0x4c 0xb8 0x10
+            0x00 0x00 0x00 0x00 0x55 0x21 0x07 0xa0 0x00 0x00 0x00 0x00 0x56
+            0x2c 0x9a 0x10 0x00 0x00 0x00 0x00 0x57 0x00 0xe9 0xa0 0x00 0x00
+            0x00 0x00 0x58 0x15 0xb6 0x90 0x00 0x00 0x00 0x00 0x58 0xe0 0xcb
+            0xa0 0x00 0x00 0x00 0x00 0x59 0xf5 0x98 0x90 0x00 0x00 0x00 0x00
+            0x5a 0xc0 0xad 0xa0 0x00 0x00 0x00 0x00 0x5b 0xd5 0x7a 0x90 0x00
+            0x00 0x00 0x00 0x5c 0xa9 0xca 0x20 0x00 0x00 0x00 0x00 0x5d 0xb5
+            0x5c 0x90 0x00 0x00 0x00 0x00 0x5e 0x89 0xac 0x20 0x00 0x00 0x00
+            0x00 0x5f 0x95 0x3e 0x90 0x00 0x00 0x00 0x00 0x60 0x69 0x8e 0x20
+            0x00 0x00 0x00 0x00 0x61 0x7e 0x5b 0x10 0x00 0x00 0x00 0x00 0x62
+            0x49 0x70 0x20 0x00 0x00 0x00 0x00 0x63 0x5e 0x3d 0x10 0x00 0x00
+            0x00 0x00 0x64 0x29 0x52 0x20 0x00 0x00 0x00 0x00 0x65 0x3e 0x1f
+            0x10 0x00 0x00 0x00 0x00 0x66 0x12 0x6e 0xa0 0x00 0x00 0x00 0x00
+            0x67 0x1e 0x01 0x10 0x00 0x00 0x00 0x00 0x67 0xf2 0x50 0xa0 0x00
+            0x00 0x00 0x00 0x68 0xfd 0xe3 0x10 0x00 0x00 0x00 0x00 0x69 0xd2
+            0x32 0xa0 0x00 0x00 0x00 0x00 0x6a 0xdd 0xc5 0x10 0x00 0x00 0x00
+            0x00 0x6b 0xb2 0x14 0xa0 0x00 0x00 0x00 0x00 0x6c 0xc6 0xe1 0x90
+            0x00 0x00 0x00 0x00 0x6d 0x91 0xf6 0xa0 0x00 0x00 0x00 0x00 0x6e
+            0xa6 0xc3 0x90 0x00 0x00 0x00 0x00 0x6f 0x71 0xd8 0xa0 0x00 0x00
+            0x00 0x00 0x70 0x86 0xa5 0x90 0x00 0x00 0x00 0x00 0x71 0x5a 0xf5
+            0x20 0x00 0x00 0x00 0x00 0x72 0x66 0x87 0x90 0x00 0x00 0x00 0x00
+            0x73 0x3a 0xd7 0x20 0x00 0x00 0x00 0x00 0x74 0x46 0x69 0x90 0x00
+            0x00 0x00 0x00 0x75 0x1a 0xb9 0x20 0x00 0x00 0x00 0x00 0x76 0x2f
+            0x86 0x10 0x00 0x00 0x00 0x00 0x76 0xfa 0x9b 0x20 0x00 0x00 0x00
+            0x00 0x78 0x0f 0x68 0x10 0x00 0x00 0x00 0x00 0x78 0xda 0x7d 0x20
+            0x00 0x00 0x00 0x00 0x79 0xef 0x4a 0x10 0x00 0x00 0x00 0x00 0x7a
+            0xba 0x5f 0x20 0x00 0x00 0x00 0x00 0x7b 0xcf 0x2c 0x10 0x00 0x00
+            0x00 0x00 0x7c 0xa3 0x7b 0xa0 0x00 0x00 0x00 0x00 0x7d 0xaf 0x0e
+            0x10 0x00 0x00 0x00 0x00 0x7e 0x83 0x5d 0xa0 0x00 0x00 0x00 0x00
+            0x7f 0x8e 0xf0 0x10 0x01 0x02 0x01 0x02 0x03 0x02 0x04 0x05 0x02
+            0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03
+            0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02
+            0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03
+            0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02
+            0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03
+            0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02
+            0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03
+            0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02
+            0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03
+            0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02
+            0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0x03 0x02 0xff 0xff 0x92
+            0x4c 0x00 0x00 0xff 0xff 0x9d 0x90 0x00 0x04 0xff 0xff 0x8f 0x80
+            0x00 0x08 0xff 0xff 0x9d 0x90 0x01 0x0c 0xff 0xff 0x9d 0x90 0x01
+            0x10 0xff 0xff 0x9d 0x90 0x01 0x14 0x4c 0x4d 0x54 0x00 0x4d 0x53
+            0x54 0x00 0x50 0x53 0x54 0x00 0x50 0x44 0x54 0x00 0x50 0x57 0x54
+            0x00 0x50 0x50 0x54 0x00 0x00 0x00 0x00 0x00 0x00 0x01 0x00 0x00
+            0x00 0x00 0x00 0x01 0x0a 0x50 0x53 0x54 0x38 0x50 0x44 0x54 0x2c
+            0x4d 0x34 0x2e 0x31 0x2e 0x30 0x2c 0x4d 0x31 0x30 0x2e 0x35 0x2e
+            0x30 0x0a
+	}]
+	close $f
+	set ::tcl::clock::ZoneinfoPaths \
+	    [linsert $::tcl::clock::ZoneinfoPaths 0 $tzdir]
+	::tcl::clock::ClearCaches
+    }
+    -cleanup {
+	set ::tcl::clock::ZoneinfoPaths \
+	    [lrange $::tcl::clock::ZoneinfoPaths 1 end]
+	::tcl::clock::ClearCaches
+	removeFile TijuanaTwo $tzdir2
+	removeDirectory Test $tzdir
+	removeDirectory zoneinfo
+    } 
+    -body {
+	clock format 2224738800 -timezone :Test/TijuanaTwo \
+	    -format {%Y-%m-%d %H:%M:%S %Z}
+    }
+    -result {2040-07-01 00:00:00 PDT}
+}
+
+test clock-56.4 {Bug 3470928} {*}{
+    -setup {
+	clock format [clock seconds]
+	set tzdir [makeDirectory zoneinfo]
+	set tzdir2 [makeDirectory Test $tzdir]
+	set tzfile [makeFile {} Windhoek $tzdir2]
+	set f [open $tzfile wb]
+	puts -nonewline $f [binary format c* {
+            0x54 0x5a 0x69 0x66 0x32 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
+            0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x06 0x00 0x00
+            0x00 0x06 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x5c 0x00 0x00 0x00
+            0x06 0x00 0x00 0x00 0x13 0x82 0x46 0xcf 0x68 0xcc 0xae 0x8c 0x80
+            0xcd 0x9e 0x6f 0x70 0x26 0x06 0xa7 0xe0 0x2d 0x9d 0xea 0xe0 0x2e
+            0x69 0x1c 0x10 0x2f 0x7d 0xe9 0x00 0x30 0x48 0xfe 0x10 0x31 0x67
+            0x05 0x80 0x32 0x28 0xe0 0x10 0x33 0x46 0xe7 0x80 0x34 0x11 0xfc
+            0x90 0x35 0x26 0xc9 0x80 0x35 0xf1 0xde 0x90 0x37 0x06 0xab 0x80
+            0x37 0xd1 0xc0 0x90 0x38 0xe6 0x8d 0x80 0x39 0xb1 0xa2 0x90 0x3a
+            0xc6 0x6f 0x80 0x3b 0x91 0x84 0x90 0x3c 0xaf 0x8c 0x00 0x3d 0x71
+            0x66 0x90 0x3e 0x8f 0x6e 0x00 0x3f 0x5a 0x83 0x10 0x40 0x6f 0x50
+            0x00 0x41 0x3a 0x65 0x10 0x42 0x4f 0x32 0x00 0x43 0x1a 0x47 0x10
+            0x44 0x2f 0x14 0x00 0x44 0xfa 0x29 0x10 0x46 0x0e 0xf6 0x00 0x46
+            0xda 0x0b 0x10 0x47 0xf8 0x12 0x80 0x48 0xc3 0x27 0x90 0x49 0xd7
+            0xf4 0x80 0x4a 0xa3 0x09 0x90 0x4b 0xb7 0xd6 0x80 0x4c 0x82 0xeb
+            0x90 0x4d 0x97 0xb8 0x80 0x4e 0x62 0xcd 0x90 0x4f 0x77 0x9a 0x80
+            0x50 0x42 0xaf 0x90 0x51 0x60 0xb7 0x00 0x52 0x22 0x91 0x90 0x53
+            0x40 0x99 0x00 0x54 0x0b 0xae 0x10 0x55 0x20 0x7b 0x00 0x55 0xeb
+            0x90 0x10 0x57 0x00 0x5d 0x00 0x57 0xcb 0x72 0x10 0x58 0xe0 0x3f
+            0x00 0x59 0xab 0x54 0x10 0x5a 0xc0 0x21 0x00 0x5b 0x8b 0x36 0x10
+            0x5c 0xa9 0x3d 0x80 0x5d 0x6b 0x18 0x10 0x5e 0x89 0x1f 0x80 0x5f
+            0x54 0x34 0x90 0x60 0x69 0x01 0x80 0x61 0x34 0x16 0x90 0x62 0x48
+            0xe3 0x80 0x63 0x13 0xf8 0x90 0x64 0x28 0xc5 0x80 0x64 0xf3 0xda
+            0x90 0x66 0x11 0xe2 0x00 0x66 0xd3 0xbc 0x90 0x67 0xf1 0xc4 0x00
+            0x68 0xbc 0xd9 0x10 0x69 0xd1 0xa6 0x00 0x6a 0x9c 0xbb 0x10 0x6b
+            0xb1 0x88 0x00 0x6c 0x7c 0x9d 0x10 0x6d 0x91 0x6a 0x00 0x6e 0x5c
+            0x7f 0x10 0x6f 0x71 0x4c 0x00 0x70 0x3c 0x61 0x10 0x71 0x5a 0x68
+            0x80 0x72 0x1c 0x43 0x10 0x73 0x3a 0x4a 0x80 0x74 0x05 0x5f 0x90
+            0x75 0x1a 0x2c 0x80 0x75 0xe5 0x41 0x90 0x76 0xfa 0x0e 0x80 0x77
+            0xc5 0x23 0x90 0x78 0xd9 0xf0 0x80 0x79 0xa5 0x05 0x90 0x7a 0xb9
+            0xd2 0x80 0x7b 0x84 0xe7 0x90 0x7c 0xa2 0xef 0x00 0x7d 0x6e 0x04
+            0x10 0x7e 0x82 0xd1 0x00 0x7f 0x4d 0xe6 0x10 0x01 0x02 0x01 0x03
+            0x05 0x04 0x05 0x04 0x05 0x04 0x05 0x04 0x05 0x04 0x05 0x04 0x05
+            0x04 0x05 0x04 0x05 0x04 0x05 0x04 0x05 0x04 0x05 0x04 0x05 0x04
+            0x05 0x04 0x05 0x04 0x05 0x04 0x05 0x04 0x05 0x04 0x05 0x04 0x05
+            0x04 0x05 0x04 0x05 0x04 0x05 0x04 0x05 0x04 0x05 0x04 0x05 0x04
+            0x05 0x04 0x05 0x04 0x05 0x04 0x05 0x04 0x05 0x04 0x05 0x04 0x05
+            0x04 0x05 0x04 0x05 0x04 0x05 0x04 0x05 0x04 0x05 0x04 0x05 0x04
+            0x05 0x04 0x05 0x04 0x05 0x04 0x05 0x04 0x05 0x04 0x00 0x00 0x15
+            0x18 0x00 0x00 0x00 0x00 0x1c 0x20 0x00 0x05 0x00 0x00 0x2a 0x30
+            0x01 0x05 0x00 0x00 0x1c 0x20 0x00 0x0a 0x00 0x00 0x1c 0x20 0x01
+            0x0e 0x00 0x00 0x0e 0x10 0x00 0x01 0x53 0x57 0x41 0x54 0x00 0x53
+            0x41 0x53 0x54 0x00 0x43 0x41 0x54 0x00 0x57 0x41 0x53 0x54 0x00
+            0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x54
+            0x5a 0x69 0x66 0x32 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
+            0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x07 0x00 0x00 0x00
+            0x07 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x5d 0x00 0x00 0x00 0x07
+            0x00 0x00 0x00 0x17 0xff 0xff 0xff 0xff 0x6d 0x7b 0x4b 0x78 0xff
+            0xff 0xff 0xff 0x82 0x46 0xcf 0x68 0xff 0xff 0xff 0xff 0xcc 0xae
+            0x8c 0x80 0xff 0xff 0xff 0xff 0xcd 0x9e 0x6f 0x70 0x00 0x00 0x00
+            0x00 0x26 0x06 0xa7 0xe0 0x00 0x00 0x00 0x00 0x2d 0x9d 0xea 0xe0
+            0x00 0x00 0x00 0x00 0x2e 0x69 0x1c 0x10 0x00 0x00 0x00 0x00 0x2f
+            0x7d 0xe9 0x00 0x00 0x00 0x00 0x00 0x30 0x48 0xfe 0x10 0x00 0x00
+            0x00 0x00 0x31 0x67 0x05 0x80 0x00 0x00 0x00 0x00 0x32 0x28 0xe0
+            0x10 0x00 0x00 0x00 0x00 0x33 0x46 0xe7 0x80 0x00 0x00 0x00 0x00
+            0x34 0x11 0xfc 0x90 0x00 0x00 0x00 0x00 0x35 0x26 0xc9 0x80 0x00
+            0x00 0x00 0x00 0x35 0xf1 0xde 0x90 0x00 0x00 0x00 0x00 0x37 0x06
+            0xab 0x80 0x00 0x00 0x00 0x00 0x37 0xd1 0xc0 0x90 0x00 0x00 0x00
+            0x00 0x38 0xe6 0x8d 0x80 0x00 0x00 0x00 0x00 0x39 0xb1 0xa2 0x90
+            0x00 0x00 0x00 0x00 0x3a 0xc6 0x6f 0x80 0x00 0x00 0x00 0x00 0x3b
+            0x91 0x84 0x90 0x00 0x00 0x00 0x00 0x3c 0xaf 0x8c 0x00 0x00 0x00
+            0x00 0x00 0x3d 0x71 0x66 0x90 0x00 0x00 0x00 0x00 0x3e 0x8f 0x6e
+            0x00 0x00 0x00 0x00 0x00 0x3f 0x5a 0x83 0x10 0x00 0x00 0x00 0x00
+            0x40 0x6f 0x50 0x00 0x00 0x00 0x00 0x00 0x41 0x3a 0x65 0x10 0x00
+            0x00 0x00 0x00 0x42 0x4f 0x32 0x00 0x00 0x00 0x00 0x00 0x43 0x1a
+            0x47 0x10 0x00 0x00 0x00 0x00 0x44 0x2f 0x14 0x00 0x00 0x00 0x00
+            0x00 0x44 0xfa 0x29 0x10 0x00 0x00 0x00 0x00 0x46 0x0e 0xf6 0x00
+            0x00 0x00 0x00 0x00 0x46 0xda 0x0b 0x10 0x00 0x00 0x00 0x00 0x47
+            0xf8 0x12 0x80 0x00 0x00 0x00 0x00 0x48 0xc3 0x27 0x90 0x00 0x00
+            0x00 0x00 0x49 0xd7 0xf4 0x80 0x00 0x00 0x00 0x00 0x4a 0xa3 0x09
+            0x90 0x00 0x00 0x00 0x00 0x4b 0xb7 0xd6 0x80 0x00 0x00 0x00 0x00
+            0x4c 0x82 0xeb 0x90 0x00 0x00 0x00 0x00 0x4d 0x97 0xb8 0x80 0x00
+            0x00 0x00 0x00 0x4e 0x62 0xcd 0x90 0x00 0x00 0x00 0x00 0x4f 0x77
+            0x9a 0x80 0x00 0x00 0x00 0x00 0x50 0x42 0xaf 0x90 0x00 0x00 0x00
+            0x00 0x51 0x60 0xb7 0x00 0x00 0x00 0x00 0x00 0x52 0x22 0x91 0x90
+            0x00 0x00 0x00 0x00 0x53 0x40 0x99 0x00 0x00 0x00 0x00 0x00 0x54
+            0x0b 0xae 0x10 0x00 0x00 0x00 0x00 0x55 0x20 0x7b 0x00 0x00 0x00
+            0x00 0x00 0x55 0xeb 0x90 0x10 0x00 0x00 0x00 0x00 0x57 0x00 0x5d
+            0x00 0x00 0x00 0x00 0x00 0x57 0xcb 0x72 0x10 0x00 0x00 0x00 0x00
+            0x58 0xe0 0x3f 0x00 0x00 0x00 0x00 0x00 0x59 0xab 0x54 0x10 0x00
+            0x00 0x00 0x00 0x5a 0xc0 0x21 0x00 0x00 0x00 0x00 0x00 0x5b 0x8b
+            0x36 0x10 0x00 0x00 0x00 0x00 0x5c 0xa9 0x3d 0x80 0x00 0x00 0x00
+            0x00 0x5d 0x6b 0x18 0x10 0x00 0x00 0x00 0x00 0x5e 0x89 0x1f 0x80
+            0x00 0x00 0x00 0x00 0x5f 0x54 0x34 0x90 0x00 0x00 0x00 0x00 0x60
+            0x69 0x01 0x80 0x00 0x00 0x00 0x00 0x61 0x34 0x16 0x90 0x00 0x00
+            0x00 0x00 0x62 0x48 0xe3 0x80 0x00 0x00 0x00 0x00 0x63 0x13 0xf8
+            0x90 0x00 0x00 0x00 0x00 0x64 0x28 0xc5 0x80 0x00 0x00 0x00 0x00
+            0x64 0xf3 0xda 0x90 0x00 0x00 0x00 0x00 0x66 0x11 0xe2 0x00 0x00
+            0x00 0x00 0x00 0x66 0xd3 0xbc 0x90 0x00 0x00 0x00 0x00 0x67 0xf1
+            0xc4 0x00 0x00 0x00 0x00 0x00 0x68 0xbc 0xd9 0x10 0x00 0x00 0x00
+            0x00 0x69 0xd1 0xa6 0x00 0x00 0x00 0x00 0x00 0x6a 0x9c 0xbb 0x10
+            0x00 0x00 0x00 0x00 0x6b 0xb1 0x88 0x00 0x00 0x00 0x00 0x00 0x6c
+            0x7c 0x9d 0x10 0x00 0x00 0x00 0x00 0x6d 0x91 0x6a 0x00 0x00 0x00
+            0x00 0x00 0x6e 0x5c 0x7f 0x10 0x00 0x00 0x00 0x00 0x6f 0x71 0x4c
+            0x00 0x00 0x00 0x00 0x00 0x70 0x3c 0x61 0x10 0x00 0x00 0x00 0x00
+            0x71 0x5a 0x68 0x80 0x00 0x00 0x00 0x00 0x72 0x1c 0x43 0x10 0x00
+            0x00 0x00 0x00 0x73 0x3a 0x4a 0x80 0x00 0x00 0x00 0x00 0x74 0x05
+            0x5f 0x90 0x00 0x00 0x00 0x00 0x75 0x1a 0x2c 0x80 0x00 0x00 0x00
+            0x00 0x75 0xe5 0x41 0x90 0x00 0x00 0x00 0x00 0x76 0xfa 0x0e 0x80
+            0x00 0x00 0x00 0x00 0x77 0xc5 0x23 0x90 0x00 0x00 0x00 0x00 0x78
+            0xd9 0xf0 0x80 0x00 0x00 0x00 0x00 0x79 0xa5 0x05 0x90 0x00 0x00
+            0x00 0x00 0x7a 0xb9 0xd2 0x80 0x00 0x00 0x00 0x00 0x7b 0x84 0xe7
+            0x90 0x00 0x00 0x00 0x00 0x7c 0xa2 0xef 0x00 0x00 0x00 0x00 0x00
+            0x7d 0x6e 0x04 0x10 0x00 0x00 0x00 0x00 0x7e 0x82 0xd1 0x00 0x00
+            0x00 0x00 0x00 0x7f 0x4d 0xe6 0x10 0x01 0x02 0x03 0x02 0x04 0x06
+            0x05 0x06 0x05 0x06 0x05 0x06 0x05 0x06 0x05 0x06 0x05 0x06 0x05
+            0x06 0x05 0x06 0x05 0x06 0x05 0x06 0x05 0x06 0x05 0x06 0x05 0x06
+            0x05 0x06 0x05 0x06 0x05 0x06 0x05 0x06 0x05 0x06 0x05 0x06 0x05
+            0x06 0x05 0x06 0x05 0x06 0x05 0x06 0x05 0x06 0x05 0x06 0x05 0x06
+            0x05 0x06 0x05 0x06 0x05 0x06 0x05 0x06 0x05 0x06 0x05 0x06 0x05
+            0x06 0x05 0x06 0x05 0x06 0x05 0x06 0x05 0x06 0x05 0x06 0x05 0x06
+            0x05 0x06 0x05 0x06 0x05 0x06 0x05 0x06 0x05 0x00 0x00 0x10 0x08
+            0x00 0x00 0x00 0x00 0x15 0x18 0x00 0x04 0x00 0x00 0x1c 0x20 0x00
+            0x09 0x00 0x00 0x2a 0x30 0x01 0x09 0x00 0x00 0x1c 0x20 0x00 0x0e
+            0x00 0x00 0x1c 0x20 0x01 0x12 0x00 0x00 0x0e 0x10 0x00 0x05 0x4c
+            0x4d 0x54 0x00 0x53 0x57 0x41 0x54 0x00 0x53 0x41 0x53 0x54 0x00
+            0x43 0x41 0x54 0x00 0x57 0x41 0x53 0x54 0x00 0x00 0x00 0x00 0x00
+            0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x0a 0x57 0x41
+            0x54 0x2d 0x31 0x57 0x41 0x53 0x54 0x2c 0x4d 0x39 0x2e 0x31 0x2e
+            0x30 0x2c 0x4d 0x34 0x2e 0x31 0x2e 0x30 0x0a
+	}]
+	close $f
+	set ::tcl::clock::ZoneinfoPaths \
+	    [linsert $::tcl::clock::ZoneinfoPaths 0 $tzdir]
+	::tcl::clock::ClearCaches
+    }
+    -body {
+	clock format 1326054606 -timezone :Test/Windhoek
+    }
+    -cleanup {
+	set ::tcl::clock::ZoneinfoPaths \
+	    [lrange $::tcl::clock::ZoneinfoPaths 1 end]
+	::tcl::clock::ClearCaches
+	removeFile Windhoek $tzdir2
+	removeDirectory Test $tzdir
+	removeDirectory zoneinfo
+    } 
+    -result {Sun Jan 08 22:30:06 WAST 2012}
+}
+
+test clock-57.1 {clock scan - abbreviated options} {
+    clock scan 1970-01-01 -f %Y-%m-%d -g true
+} 0
+
+test clock-58.1 {clock l10n - Japanese localisation} {*}{
+    -setup {
+	proc backslashify { string } {
+	    
+	    set retval {}
+	    foreach char [split $string {}] {
+		scan $char %c ccode
+		if { $ccode >= 0x0020 && $ccode < 0x007f
+		     && $char ne "\{" && $char ne "\}" && $char ne "\["
+		     && $char ne "\]" && $char ne "\\" && $char ne "\$" } {
+		    append retval $char
+		} else {
+		    append retval \\u [format %04x $ccode]
+		}
+	    }
+	    return $retval
+	}
+    }
+    -body {
+	set trouble {}
+	foreach {date jdate} [list \
+	    1872-12-31 \u897f\u66a61872\u5e7412\u670831\u65e5 \
+	    1873-01-01 \u660e\u6cbb06\u5e7401\u670801\u65e5 \
+	    1912-07-29 \u660e\u6cbb45\u5e7407\u670829\u65e5 \
+	    1912-07-30 \u5927\u6b6301\u5e7407\u670830\u65e5 \
+	    1926-12-24 \u5927\u6b6315\u5e7412\u670824\u65e5 \
+	    1926-12-25 \u662d\u548c01\u5e7412\u670825\u65e5 \
+	    1989-01-07 \u662d\u548c64\u5e7401\u670807\u65e5 \
+	    1989-01-08 \u5e73\u621001\u5e7401\u670808\u65e5 \
+	] {
+	    set status [catch {
+		set secs [clock scan $date \
+			      -timezone +0900 \
+			      -locale ja_JP \
+			      -format %Y-%m-%d]
+		set jda [clock format $secs \
+			     -timezone +0900 \
+			     -locale ja_JP \
+			     -format %Ex]
+	    } result]
+	    if {$status != 0} {
+		append trouble \n $date " gives error " $result
+	    } elseif {$jda ne $jdate} {
+		append trouble \n $date " converts to " \
+		    [backslashify $jda] " and should be " \
+		    [backslashify $jdate]
+	    }
+	    # There is no code for scanning dates on the locale's
+	    # alternative calendar.
+	    continue
+	    set status [catch {
+		set secs [clock scan $jdate \
+			      -timezone +0900 \
+			      -locale ja_JP \
+			      -format %Ex]
+		set da [clock format $secs \
+			    -timezone +0900 \
+			    -locale ja_JP \
+			    -format %Y-%m-%d]
+	    } result]
+	    if {$status != 0} {
+		append trouble \n [backslashify $jdate] " gives error " $result
+	    } elseif {$da ne $date} {
+		append trouble \n [backslashify $jdate] " converts to " \
+		    $da " and should be " $date
+	    }
+	}
+	set trouble
+    }
+    -cleanup {
+	rename backslashify {}
+    }
+    -result {}
+}
+
+test clock-59.1 {military time zones} {
+    set hour 0
+    set base [clock scan "20000101 000000" -format "%Y%m%d %H%M%S" -gmt 1]
+    set trouble {}
+    foreach {pzone mzone} {
+	Z Z  A N  B O  C P  D Q  E R  F S  G T  H U  I V  K W  L X  M Y
+    } {
+	catch {clock scan "20000101 000000 $pzone" \
+		   -format "%Y%m%d %H%M%S %Z"} ps1
+	catch {clock scan "20000101 000000 $pzone"} ps2
+	catch {clock scan "20000101 000000 $mzone" \
+		   -format "%Y%m%d %H%M%S %Z"} ms1
+	catch {clock scan "20000101 000000 $mzone"} ms2
+	if {$ps1 != $base - 3600 * $hour} {
+	    lappend trouble [list pzone $pzone hour $hour ps1 is $ps1]
+	}
+	if {$ps2 != $base - 3600 * $hour} {
+	    lappend trouble [list pzone $pzone ps2 is $ps2]
+	}
+	if {$ms1 != $base + 3600 * $hour} {
+	    lappend trouble [list mzone $mzone ms1 is $ms1]
+	}
+	if {$ms2 != $base + 3600 * $hour} {
+	    lappend trouble [list mzone $mzone ms2 is $ms2]
+	}
+	incr hour
+    }
+    join $trouble \n
+} {}
+
+# case-insensitive matching of weekday and month names [Bug 1781282]
+
+test clock-60.1 {case insensitive weekday names} {
+    clock scan "2000-W01 monday" -gmt true -format "%G-W%V %a"
+} [clock scan "2000-W01-1" -gmt true -format "%G-W%V-%u"] 
+test clock-60.2 {case insensitive weekday names} {
+    clock scan "2000-W01 Monday" -gmt true -format "%G-W%V %a"
+} [clock scan "2000-W01-1" -gmt true -format "%G-W%V-%u"] 
+test clock-60.3 {case insensitive weekday names} {
+    clock scan "2000-W01 MONDAY" -gmt true -format "%G-W%V %a"
+} [clock scan "2000-W01-1" -gmt true -format "%G-W%V-%u"] 
+test clock-60.4 {case insensitive weekday names} {
+    clock scan "2000-W01 friday" -gmt true -format "%G-W%V %a"
+} [clock scan "2000-W01-5" -gmt true -format "%G-W%V-%u"] 
+test clock-60.5 {case insensitive weekday names} {
+    clock scan "2000-W01 Friday" -gmt true -format "%G-W%V %a"
+} [clock scan "2000-W01-5" -gmt true -format "%G-W%V-%u"] 
+test clock-60.6 {case insensitive weekday names} {
+    clock scan "2000-W01 FRIDAY" -gmt true -format "%G-W%V %a"
+} [clock scan "2000-W01-5" -gmt true -format "%G-W%V-%u"] 
+test clock-60.7 {case insensitive month names} {
+    clock scan "1 january 2000" -gmt true -format "%d %b %Y"
+} [clock scan "2000-01-01" -gmt true -format "%Y-%m-%d"] 
+test clock-60.8 {case insensitive month names} {
+    clock scan "1 January 2000" -gmt true -format "%d %b %Y"
+} [clock scan "2000-01-01" -gmt true -format "%Y-%m-%d"] 
+test clock-60.9 {case insensitive month names} {
+    clock scan "1 JANUARY 2000" -gmt true -format "%d %b %Y"
+} [clock scan "2000-01-01" -gmt true -format "%Y-%m-%d"] 
+test clock-60.10 {case insensitive month names} {
+    clock scan "1 december 2000" -gmt true -format "%d %b %Y"
+} [clock scan "2000-12-01" -gmt true -format "%Y-%m-%d"] 
+test clock-60.11 {case insensitive month names} {
+    clock scan "1 December 2000" -gmt true -format "%d %b %Y"
+} [clock scan "2000-12-01" -gmt true -format "%Y-%m-%d"] 
+test clock-60.12 {case insensitive month names} {
+    clock scan "1 DECEMBER 2000" -gmt true -format "%d %b %Y"
+} [clock scan "2000-12-01" -gmt true -format "%Y-%m-%d"] 
+
+test clock-61.1 {overflow of a wide integer on output} {*}{
+    -body {
+	clock format 0x8000000000000000 -format %s -gmt true
+    } 
+    -result {integer value too large to represent}
+    -returnCodes error
+}
+test clock-61.2 {overflow of a wide integer on output} {*}{
+    -body {
+	clock format -0x8000000000000001 -format %s -gmt true
+    } 
+    -result {integer value too large to represent}
+    -returnCodes error
+}
+test clock-61.3 {near-miss overflow of a wide integer on output} {
+    clock format 0x7fffffffffffffff -format %s -gmt true
+} [expr 0x7fffffffffffffff]
+test clock-61.4 {near-miss overflow of a wide integer on output} {
+    clock format -0x8000000000000000 -format %s -gmt true
+} [expr -0x8000000000000000]
+
+test clock-62.1 {Bug 1902423} {*}{
+    -setup {::tcl::clock::ClearCaches}
+    -body {
+	set s 1204049747
+	set f1 [clock format $s -format {%Y-%m-%d %T} -locale C]
+	set f2 [clock format $s -format {%Y-%m-%d %H:%M:%S} -locale C]
+	if {$f1 ne $f2} {
+	    subst "$f2 is not $f1"
+	} else {
+	    subst "ok"
+	}
+    }
+    -result ok
+}
+
+test clock-63.1 {Incorrect use of internal ConvertLocalToUTC command} {*}{
+    -body {
+	::tcl::clock::ConvertLocalToUTC {immaterial stuff} {} 12345
+    }
+    -returnCodes error
+    -result {key "localseconds" not found in dictionary}
+}
+
+test clock-64.1 {:: in format string [Bug 2362156]} {*}{
+    -body {
+	clock scan 2001-02-03::04:05:06 -gmt 1 -format %Y-%m-%d::%H:%M:%S
+    }
+    -result 981173106
+}
+test clock-64.2 {:: in format string [Bug 2362156]} {*}{
+    -body {
+	clock format 981173106 -gmt 1 -format %Y-%m-%d::%H:%M:%S
+    }
+    -result 2001-02-03::04:05:06
+}
+
+test clock-65.1 {clock add, bad option [Bug 2481670]} {*}{
+    -body {
+	clock add 0 1 year -foo bar
+    }
+    -match glob
+    -returnCodes error
+    -result {bad option "-foo"*}
+}
+
+test clock-66.1 {clock scan, no date, never-before-seen timezone} {*}{
+    -setup {
+	::tcl::clock::ClearCaches
+    }
+    -body {
+	clock scan 1200 \
+	    -timezone {<EST>+05:00:00<EDT>+04:00:00,M3.2.0/02:00:00,M11.1.0/02:00:00} \
+	    -base 1256529600 \
+	    -format %H%M
+    }
+    -result 1256572800
+}
+
+test clock-67.1 {clock format, %% with a letter following [Bug 2819334]} {
+    clock format [clock seconds] -format %%r
+} %r
+
+test clock-67.2 {Bug d19a30db57} -body {
+    # error, not segfault
+    tcl::clock::GetJulianDayFromEraYearMonthDay {} 2361222
+} -returnCodes error -match glob -result *
+
+test clock-67.3 {Bug d19a30db57} -body {
+    # error, not segfault
+    tcl::clock::GetJulianDayFromEraYearWeekDay {} 2361222
+} -returnCodes error -match glob -result *
+
+test clock-67.4 {Change format %x output on global locale change [Bug 4a0c163d24]} -setup {
+    package require msgcat
+    set current [msgcat::mclocale]
+} -body {
+    msgcat::mclocale de_de
+    set res [regexp {^\d{2}\.\d{2}\.\d{4}$} [clock format 1 -locale current -format %x]]
+    msgcat::mclocale en_uk
+    lappend res [regexp {^\d{2}/\d{2}/\d{4}$} [clock format 1 -locale current -format %x]]
+} -cleanup {
+    msgcat::mclocale $current
+} -result {1 1}
+
+test clock-67.5 {Change scan %x output on global locale change [Bug 4a0c163d24]} -setup {
+    package require msgcat
+    set current [msgcat::mclocale]
+} -body {
+    msgcat::mclocale de_de
+    set res [clock scan "01.01.1970" -locale current -format %x]
+    msgcat::mclocale en_uk
+    # This will fail without the bug fix, as still de_de is active
+    expr {$res == [clock scan "01/01/1970" -locale current -format %x]}
+} -cleanup {
+    msgcat::mclocale $current
+} -result {1}
+
+# cleanup
+
+namespace delete ::testClock
+::tcl::clock::ClearCaches
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/tests/cmdAH.test b/tests/cmdAH.test
new file mode 100644
index 0000000..b4ef605
--- /dev/null
+++ b/tests/cmdAH.test
@@ -0,0 +1,1665 @@
+# The file tests the tclCmdAH.c file.
+#
+# This file contains a collection of tests for one or more of the Tcl built-in
+# commands. Sourcing this file into Tcl runs the tests and generates output
+# for errors. No output means no errors were found.
+#
+# Copyright (c) 1996-1998 by Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution of
+# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {"::tcltest" ni [namespace children]} {
+    package require tcltest 2.1
+    namespace import -force ::tcltest::*
+}
+
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
+
+testConstraint testchmod       [llength [info commands testchmod]]
+testConstraint testsetplatform [llength [info commands testsetplatform]]
+testConstraint testvolumetype  [llength [info commands testvolumetype]]
+testConstraint linkDirectory [expr {
+    ![testConstraint win] ||
+    ([string index $tcl_platform(osVersion) 0] >= 5
+     && [lindex [file system [temporaryDirectory]] 1] eq "NTFS")
+}]
+
+global env
+set cmdAHwd [pwd]
+catch {set platform [testgetplatform]}
+
+proc waitForEvenSecondForFAT {} {
+    # Windows 9x uses filesystems (the FAT* family of FSes) without enough
+    # data in its timestamps for even per-second-accurate timings. :^(
+    # This procedure based on work by Helmut Giese
+    if {
+	[testConstraint win] &&
+	[lindex [file system [temporaryDirectory]] 1] ne "NTFS"
+    } then {
+	# Assume non-NTFS means FAT{12,16,32} and hence in need of special
+	# help...
+	set start [clock seconds]
+	while {1} {
+	    set now [clock seconds]
+	    if {$now!=$start && !($now & 1)} {
+		break
+	    }
+	    after 50
+	}
+    }
+}
+
+test cmdAH-0.1 {Tcl_BreakObjCmd, errors} -body {
+    break foo
+} -returnCodes error -result {wrong # args: should be "break"}
+test cmdAH-0.2 {Tcl_BreakObjCmd, success} {
+    list [catch {break} msg] $msg
+} {3 {}}
+
+# Tcl_CaseObjCmd is tested in case.test
+
+test cmdAH-1.1 {Tcl_CatchObjCmd, errors} -returnCodes error -body {
+    catch
+} -result {wrong # args: should be "catch script ?resultVarName? ?optionVarName?"}
+test cmdAH-1.2 {Tcl_CatchObjCmd, errors} {
+    list [catch {catch foo bar baz} msg] $msg
+} {0 1}
+test cmdAH-1.3 {Tcl_CatchObjCmd, errors} -returnCodes error -body {
+    catch foo bar baz spaz
+} -result {wrong # args: should be "catch script ?resultVarName? ?optionVarName?"}
+test cmdAH-1.4 {Bug 3595576} {
+    catch {catch {} -> noSuchNs::var}
+} 1
+test cmdAH-1.5 {Bug 3595576} {
+    catch {catch error -> noSuchNs::var}
+} 1
+
+test cmdAH-2.1 {Tcl_CdObjCmd} -returnCodes error -body {
+    cd foo bar
+} -result {wrong # args: should be "cd ?dirName?"}
+set foodir [file join [temporaryDirectory] foo]
+test cmdAH-2.2 {Tcl_CdObjCmd} -setup {
+    file delete -force $foodir
+    set oldpwd [pwd]
+} -body {
+    file mkdir $foodir
+    cd $foodir
+    file tail [pwd]
+} -cleanup {
+    cd $oldpwd
+    file delete $foodir
+} -result foo
+test cmdAH-2.3 {Tcl_CdObjCmd} -setup {
+    global env
+    set oldpwd [pwd]
+    set temp $env(HOME)
+    file delete -force $foodir
+} -body {
+    set env(HOME) $oldpwd
+    file mkdir $foodir
+    cd $foodir
+    cd ~
+    string equal [pwd] $oldpwd
+} -cleanup {
+    cd $oldpwd
+    file delete $foodir
+    set env(HOME) $temp
+} -result 1
+test cmdAH-2.4 {Tcl_CdObjCmd} -setup {
+    global env
+    set oldpwd [pwd]
+    set temp $env(HOME)
+    file delete -force $foodir
+} -body {
+    set env(HOME) $oldpwd
+    file mkdir $foodir
+    cd $foodir
+    cd
+    string equal [pwd] $oldpwd
+} -cleanup {
+    cd $oldpwd
+    file delete $foodir
+    set env(HOME) $temp
+} -result 1
+test cmdAH-2.5 {Tcl_CdObjCmd} -returnCodes error -body {
+    cd ~~
+} -result {user "~" doesn't exist}
+test cmdAH-2.6 {Tcl_CdObjCmd} -returnCodes error -body {
+    cd _foobar
+} -result {couldn't change working directory to "_foobar": no such file or directory}
+test cmdAH-2.6.1 {Tcl_CdObjCmd} -returnCodes error -body {
+    cd ""
+} -result {couldn't change working directory to "": no such file or directory}
+test cmdAH-2.6.2 {cd} -constraints {unix nonPortable} -setup {
+    set dir [pwd]
+} -body {
+    cd /
+    pwd
+} -cleanup {
+    cd $dir
+} -result {/}
+test cmdAH-2.6.3 {Tcl_CdObjCmd, bug #3118489} -setup {
+    set dir [pwd]
+} -returnCodes error -body {
+    cd .\0
+} -cleanup {
+    cd $dir
+} -match glob -result "couldn't change working directory to \".\0\": *"
+test cmdAH-2.7 {Tcl_ConcatObjCmd} {
+    concat
+} {}
+test cmdAH-2.8 {Tcl_ConcatObjCmd} {
+    concat a
+} a
+test cmdAH-2.9 {Tcl_ConcatObjCmd} {
+    concat a {b c}
+} {a b c}
+
+test cmdAH-3.1 {Tcl_ContinueObjCmd, errors} -returnCodes error -body {
+    continue foo
+} -result {wrong # args: should be "continue"}
+test cmdAH-3.2 {Tcl_ContinueObjCmd, success} {
+    list [catch {continue} msg] $msg
+} {4 {}}
+
+test cmdAH-4.1 {Tcl_EncodingObjCmd} -returnCodes error -body {
+    encoding
+} -result {wrong # args: should be "encoding option ?arg ...?"}
+test cmdAH-4.2 {Tcl_EncodingObjCmd} -returnCodes error -body {
+    encoding foo
+} -result {bad option "foo": must be convertfrom, convertto, dirs, names, or system}
+test cmdAH-4.3 {Tcl_EncodingObjCmd} -returnCodes error -body {
+    encoding convertto
+} -result {wrong # args: should be "encoding convertto ?encoding? data"}
+test cmdAH-4.4 {Tcl_EncodingObjCmd} -returnCodes error -body {
+    encoding convertto foo bar
+} -result {unknown encoding "foo"}
+test cmdAH-4.5 {Tcl_EncodingObjCmd} -setup {
+    set system [encoding system]
+} -body {
+    encoding system jis0208
+    encoding convertto \u4e4e
+} -cleanup {
+    encoding system $system
+} -result 8C
+test cmdAH-4.6 {Tcl_EncodingObjCmd} -setup {
+    set system [encoding system]
+} -body {
+    encoding system identity
+    encoding convertto jis0208 \u4e4e
+} -cleanup {
+    encoding system $system
+} -result 8C
+test cmdAH-4.7 {Tcl_EncodingObjCmd} -returnCodes error -body {
+    encoding convertfrom
+} -result {wrong # args: should be "encoding convertfrom ?encoding? data"}
+test cmdAH-4.8 {Tcl_EncodingObjCmd} -returnCodes error -body {
+    encoding convertfrom foo bar
+} -result {unknown encoding "foo"}
+test cmdAH-4.9 {Tcl_EncodingObjCmd} -setup {
+    set system [encoding system]
+} -body {
+    encoding system jis0208
+    encoding convertfrom 8C
+} -cleanup {
+    encoding system $system
+} -result \u4e4e
+test cmdAH-4.10 {Tcl_EncodingObjCmd} -setup {
+    set system [encoding system]
+} -body {
+    encoding system identity
+    encoding convertfrom jis0208 8C
+} -cleanup {
+    encoding system $system
+} -result \u4e4e
+test cmdAH-4.11 {Tcl_EncodingObjCmd} -returnCodes error -body {
+    encoding names foo
+} -result {wrong # args: should be "encoding names"}
+test cmdAH-4.12 {Tcl_EncodingObjCmd} -returnCodes error -body {
+    encoding system foo bar
+} -result {wrong # args: should be "encoding system ?encoding?"}
+test cmdAH-4.13 {Tcl_EncodingObjCmd} -setup {
+    set system [encoding system]
+} -body {
+    encoding system identity
+    encoding system
+} -cleanup {
+    encoding system $system
+} -result identity
+
+test cmdAH-5.1 {Tcl_FileObjCmd} -returnCodes error -body {
+    file
+} -result {wrong # args: should be "file subcommand ?arg ...?"}
+test cmdAH-5.2 {Tcl_FileObjCmd} -returnCodes error -body {
+    file x
+} -result {unknown or ambiguous subcommand "x": must be atime, attributes, channels, copy, delete, dirname, executable, exists, extension, isdirectory, isfile, join, link, lstat, mkdir, mtime, nativename, normalize, owned, pathtype, readable, readlink, rename, rootname, separator, size, split, stat, system, tail, tempfile, type, volumes, or writable}
+test cmdAH-5.3 {Tcl_FileObjCmd} -returnCodes error -body {
+    file exists
+} -result {wrong # args: should be "file exists name"}
+test cmdAH-5.4 {Tcl_FileObjCmd} {
+    file exists ""
+} 0
+
+# volume
+test cmdAH-6.1 {Tcl_FileObjCmd: volumes} -returnCodes error -body {
+    file volumes x
+} -result {wrong # args: should be "file volumes"}
+test cmdAH-6.2 {Tcl_FileObjCmd: volumes} -body {
+    lindex [file volumes] 0
+} -match glob -result ?*
+test cmdAH-6.3 {Tcl_FileObjCmd: volumes} -constraints unix -body {
+    set volumeList [file volumes]
+    glob -nocomplain [lindex $volumeList 0]*
+} -match glob -result *
+test cmdAH-6.4 {Tcl_FileObjCmd: volumes} -constraints win -body {
+    set volumeList [string tolower [file volumes]]
+    set element [lsearch -exact $volumeList "c:/"]
+    list [expr {$element>-1}] [glob -nocomplain [lindex $volumeList $element]*]
+} -match glob -result {1 *}
+
+# attributes
+test cmdAH-7.1 {Tcl_FileObjCmd - file attrs} -setup {
+    set foofile [makeFile abcde foo.file]
+    catch {file delete -force $foofile}
+} -body {
+    close [open $foofile w]
+    file attributes $foofile
+} -cleanup {
+    # We used [makeFile] so we undo with [removeFile]
+    removeFile $foofile
+} -match glob -result *
+
+# dirname
+test cmdAH-8.1 {Tcl_FileObjCmd: dirname} -returnCodes error -body {
+    file dirname a b
+} -result {wrong # args: should be "file dirname name"}
+test cmdAH-8.2 {Tcl_FileObjCmd: dirname} testsetplatform {
+    testsetplatform unix
+    file dirname /a/b
+} /a
+test cmdAH-8.3 {Tcl_FileObjCmd: dirname} testsetplatform {
+    testsetplatform unix
+    file dirname {}
+} .
+test cmdAH-8.5 {Tcl_FileObjCmd: dirname} testsetplatform {
+    testsetplatform win
+    file dirname {}
+} .
+test cmdAH-8.6 {Tcl_FileObjCmd: dirname} testsetplatform {
+    testsetplatform unix
+    file dirname .def
+} .
+test cmdAH-8.8 {Tcl_FileObjCmd: dirname} testsetplatform {
+    testsetplatform win
+    file dirname a
+} .
+test cmdAH-8.9 {Tcl_FileObjCmd: dirname} testsetplatform {
+    testsetplatform unix
+    file dirname a/b/c.d
+} a/b
+test cmdAH-8.10 {Tcl_FileObjCmd: dirname} testsetplatform {
+    testsetplatform unix
+    file dirname a/b.c/d
+} a/b.c
+test cmdAH-8.11 {Tcl_FileObjCmd: dirname} testsetplatform {
+    testsetplatform unix
+    file dirname /.
+} /
+test cmdAH-8.12 {Tcl_FileObjCmd: dirname} testsetplatform {
+    testsetplatform unix
+    file dirname /
+} /
+test cmdAH-8.13 {Tcl_FileObjCmd: dirname} testsetplatform {
+    testsetplatform unix
+    file dirname /foo
+} /
+test cmdAH-8.14 {Tcl_FileObjCmd: dirname} testsetplatform {
+    testsetplatform unix
+    file dirname //foo
+} /
+test cmdAH-8.15 {Tcl_FileObjCmd: dirname} testsetplatform {
+    testsetplatform unix
+    file dirname //foo/bar
+} /foo
+test cmdAH-8.16 {Tcl_FileObjCmd: dirname} testsetplatform {
+    testsetplatform unix
+    file dirname {//foo\/bar/baz}
+} {/foo\/bar}
+test cmdAH-8.17 {Tcl_FileObjCmd: dirname} testsetplatform {
+    testsetplatform unix
+    file dirname {//foo\/bar/baz/blat}
+} {/foo\/bar/baz}
+test cmdAH-8.18 {Tcl_FileObjCmd: dirname} testsetplatform {
+    testsetplatform unix
+    file dirname /foo//
+} /
+test cmdAH-8.19 {Tcl_FileObjCmd: dirname} testsetplatform {
+    testsetplatform unix
+    file dirname ./a
+} .
+test cmdAH-8.20 {Tcl_FileObjCmd: dirname} testsetplatform {
+    testsetplatform unix
+    file dirname a/.a
+} a
+test cmdAH-8.21 {Tcl_FileObjCmd: dirname} testsetplatform {
+    testsetplatform windows
+    file dirname c:foo
+} c:
+test cmdAH-8.22 {Tcl_FileObjCmd: dirname} testsetplatform {
+    testsetplatform windows
+    file dirname c:
+} c:
+test cmdAH-8.23 {Tcl_FileObjCmd: dirname} testsetplatform {
+    testsetplatform windows
+    file dirname c:/
+} c:/
+test cmdAH-8.24 {Tcl_FileObjCmd: dirname} testsetplatform {
+    testsetplatform windows
+    file dirname {c:\foo}
+} c:/
+test cmdAH-8.25 {Tcl_FileObjCmd: dirname} testsetplatform {
+    testsetplatform windows
+    file dirname {//foo/bar/baz}
+} //foo/bar
+test cmdAH-8.26 {Tcl_FileObjCmd: dirname} testsetplatform {
+    testsetplatform windows
+    file dirname {//foo/bar}
+} //foo/bar
+test cmdAH-8.38 {Tcl_FileObjCmd: dirname} testsetplatform {
+    testsetplatform unix
+    file dirname ~/foo
+} ~
+test cmdAH-8.39 {Tcl_FileObjCmd: dirname} testsetplatform {
+    testsetplatform unix
+    file dirname ~bar/foo
+} ~bar
+test cmdAH-8.43 {Tcl_FileObjCmd: dirname} -setup {
+    global env
+    set temp $env(HOME)
+} -constraints testsetplatform -body {
+    set env(HOME) "/homewontexist/test"
+    testsetplatform unix
+    file dirname ~
+} -cleanup {
+    set env(HOME) $temp
+} -result /homewontexist
+test cmdAH-8.44 {Tcl_FileObjCmd: dirname} -setup {
+    global env
+    set temp $env(HOME)
+} -constraints testsetplatform -body {
+    set env(HOME) "~"
+    testsetplatform unix
+    file dirname ~
+} -cleanup {
+    set env(HOME) $temp
+} -result ~
+test cmdAH-8.45 {Tcl_FileObjCmd: dirname} -setup {
+    set temp $::env(HOME)
+} -constraints {win testsetplatform} -match regexp -body {
+    set ::env(HOME) "/homewontexist/test"
+    testsetplatform windows
+    file dirname ~
+} -cleanup {
+    set ::env(HOME) $temp
+} -result {([a-zA-Z]:?)/homewontexist}
+test cmdAH-8.46 {Tcl_FileObjCmd: dirname} {
+    set f [file normalize [info nameof]]
+    file exists $f
+    set res1 [file dirname [file join $f foo/bar]]
+    set res2 [file dirname "${f}/foo/bar"]
+    if {$res1 eq $res2} {
+	return "ok"
+    }
+    return "file dirname problem, $res1, $res2 not equal"
+} {ok}
+
+# tail
+test cmdAH-9.1 {Tcl_FileObjCmd: tail} -returnCodes error -body {
+    file tail a b
+} -result {wrong # args: should be "file tail name"}
+test cmdAH-9.2 {Tcl_FileObjCmd: tail} testsetplatform {
+    testsetplatform unix
+    file tail /a/b
+} b
+test cmdAH-9.3 {Tcl_FileObjCmd: tail} testsetplatform {
+    testsetplatform unix
+    file tail {}
+} {}
+test cmdAH-9.5 {Tcl_FileObjCmd: tail} testsetplatform {
+    testsetplatform win
+    file tail {}
+} {}
+test cmdAH-9.6 {Tcl_FileObjCmd: tail} testsetplatform {
+    testsetplatform unix
+    file tail .def
+} .def
+test cmdAH-9.8 {Tcl_FileObjCmd: tail} testsetplatform {
+    testsetplatform win
+    file tail a
+} a
+test cmdAH-9.9 {Tcl_FileObjCmd: tail} testsetplatform {
+    testsetplatform unix
+    file ta a/b/c.d
+} c.d
+test cmdAH-9.10 {Tcl_FileObjCmd: tail} testsetplatform {
+    testsetplatform unix
+    file tail a/b.c/d
+} d
+test cmdAH-9.11 {Tcl_FileObjCmd: tail} testsetplatform {
+    testsetplatform unix
+    file tail /.
+} .
+test cmdAH-9.12 {Tcl_FileObjCmd: tail} testsetplatform {
+    testsetplatform unix
+    file tail /
+} {}
+test cmdAH-9.13 {Tcl_FileObjCmd: tail} testsetplatform {
+    testsetplatform unix
+    file tail /foo
+} foo
+test cmdAH-9.14 {Tcl_FileObjCmd: tail} testsetplatform {
+    testsetplatform unix
+    file tail //foo
+} foo
+test cmdAH-9.15 {Tcl_FileObjCmd: tail} testsetplatform {
+    testsetplatform unix
+    file tail //foo/bar
+} bar
+test cmdAH-9.16 {Tcl_FileObjCmd: tail} testsetplatform {
+    testsetplatform unix
+    file tail {//foo\/bar/baz}
+} baz
+test cmdAH-9.17 {Tcl_FileObjCmd: tail} testsetplatform {
+    testsetplatform unix
+    file tail {//foo\/bar/baz/blat}
+} blat
+test cmdAH-9.18 {Tcl_FileObjCmd: tail} testsetplatform {
+    testsetplatform unix
+    file tail /foo//
+} foo
+test cmdAH-9.19 {Tcl_FileObjCmd: tail} testsetplatform {
+    testsetplatform unix
+    file tail ./a
+} a
+test cmdAH-9.20 {Tcl_FileObjCmd: tail} testsetplatform {
+    testsetplatform unix
+    file tail a/.a
+} .a
+test cmdAH-9.21 {Tcl_FileObjCmd: tail} testsetplatform {
+    testsetplatform windows
+    file tail c:foo
+} foo
+test cmdAH-9.22 {Tcl_FileObjCmd: tail} testsetplatform {
+    testsetplatform windows
+    file tail c:
+} {}
+test cmdAH-9.23 {Tcl_FileObjCmd: tail} testsetplatform {
+    testsetplatform windows
+    file tail c:/
+} {}
+test cmdAH-9.24 {Tcl_FileObjCmd: tail} testsetplatform {
+    testsetplatform windows
+    file tail {c:\foo}
+} foo
+test cmdAH-9.25 {Tcl_FileObjCmd: tail} testsetplatform {
+    testsetplatform windows
+    file tail {//foo/bar/baz}
+} baz
+test cmdAH-9.26 {Tcl_FileObjCmd: tail} testsetplatform {
+    testsetplatform windows
+    file tail {//foo/bar}
+} {}
+test cmdAH-9.42 {Tcl_FileObjCmd: tail} -constraints testsetplatform -setup {
+    global env
+    set temp $env(HOME)
+} -body {
+    set env(HOME) "/home/test"
+    testsetplatform unix
+    file tail ~
+} -cleanup {
+    set env(HOME) $temp
+} -result test
+test cmdAH-9.43 {Tcl_FileObjCmd: tail} -constraints testsetplatform -setup {
+    global env
+    set temp $env(HOME)
+} -body {
+    set env(HOME) "~"
+    testsetplatform unix
+    file tail ~
+} -cleanup {
+    set env(HOME) $temp
+} -result {}
+test cmdAH-9.44 {Tcl_FileObjCmd: tail} -constraints testsetplatform -setup {
+    global env
+    set temp $env(HOME)
+} -body {
+    set env(HOME) "/home/test"
+    testsetplatform windows
+    file tail ~
+} -cleanup {
+    set env(HOME) $temp
+} -result test
+test cmdAH-9.46 {Tcl_FileObjCmd: tail} testsetplatform {
+    testsetplatform unix
+    file tail {f.oo\bar/baz.bat}
+} baz.bat
+test cmdAH-9.47 {Tcl_FileObjCmd: tail} testsetplatform {
+    testsetplatform windows
+    file tail c:foo
+} foo
+test cmdAH-9.48 {Tcl_FileObjCmd: tail} testsetplatform {
+    testsetplatform windows
+    file tail c:
+} {}
+test cmdAH-9.49 {Tcl_FileObjCmd: tail} testsetplatform {
+    testsetplatform windows
+    file tail c:/foo
+} foo
+test cmdAH-9.50 {Tcl_FileObjCmd: tail} testsetplatform {
+    testsetplatform windows
+    file tail {c:/foo\bar}
+} bar
+test cmdAH-9.51 {Tcl_FileObjCmd: tail} testsetplatform {
+    testsetplatform windows
+    file tail {foo\bar}
+} bar
+
+# rootname
+test cmdAH-10.1 {Tcl_FileObjCmd: rootname} -returnCodes error -body {
+    file rootname a b
+} -result {wrong # args: should be "file rootname name"}
+test cmdAH-10.2 {Tcl_FileObjCmd: rootname} testsetplatform {
+    testsetplatform unix
+    file rootname {}
+} {}
+test cmdAH-10.3 {Tcl_FileObjCmd: rootname} testsetplatform {
+    testsetplatform unix
+    file ro foo
+} foo
+test cmdAH-10.4 {Tcl_FileObjCmd: rootname} testsetplatform {
+    testsetplatform unix
+    file rootname foo.
+} foo
+test cmdAH-10.5 {Tcl_FileObjCmd: rootname} testsetplatform {
+    testsetplatform unix
+    file rootname .foo
+} {}
+test cmdAH-10.6 {Tcl_FileObjCmd: rootname} testsetplatform {
+    testsetplatform unix
+    file rootname abc.def
+} abc
+test cmdAH-10.7 {Tcl_FileObjCmd: rootname} testsetplatform {
+    testsetplatform unix
+    file rootname abc.def.ghi
+} abc.def
+test cmdAH-10.8 {Tcl_FileObjCmd: rootname} testsetplatform {
+    testsetplatform unix
+    file rootname a/b/c.d
+} a/b/c
+test cmdAH-10.9 {Tcl_FileObjCmd: rootname} testsetplatform {
+    testsetplatform unix
+    file rootname a/b.c/d
+} a/b.c/d
+test cmdAH-10.10 {Tcl_FileObjCmd: rootname} testsetplatform {
+    testsetplatform unix
+    file rootname a/b.c/
+} a/b.c/
+test cmdAH-10.23 {Tcl_FileObjCmd: rootname} testsetplatform {
+    testsetplatform windows
+    file rootname {}
+} {}
+test cmdAH-10.24 {Tcl_FileObjCmd: rootname} testsetplatform {
+    testsetplatform windows
+    file ro foo
+} foo
+test cmdAH-10.25 {Tcl_FileObjCmd: rootname} testsetplatform {
+    testsetplatform windows
+    file rootname foo.
+} foo
+test cmdAH-10.26 {Tcl_FileObjCmd: rootname} testsetplatform {
+    testsetplatform windows
+    file rootname .foo
+} {}
+test cmdAH-10.27 {Tcl_FileObjCmd: rootname} testsetplatform {
+    testsetplatform windows
+    file rootname abc.def
+} abc
+test cmdAH-10.28 {Tcl_FileObjCmd: rootname} testsetplatform {
+    testsetplatform windows
+    file rootname abc.def.ghi
+} abc.def
+test cmdAH-10.29 {Tcl_FileObjCmd: rootname} testsetplatform {
+    testsetplatform windows
+    file rootname a/b/c.d
+} a/b/c
+test cmdAH-10.30 {Tcl_FileObjCmd: rootname} testsetplatform {
+    testsetplatform windows
+    file rootname a/b.c/d
+} a/b.c/d
+test cmdAH-10.31 {Tcl_FileObjCmd: rootname} testsetplatform {
+    testsetplatform windows
+    file rootname a\\b.c\\
+} a\\b.c\\
+test cmdAH-10.32 {Tcl_FileObjCmd: rootname} testsetplatform {
+    testsetplatform windows
+    file rootname a\\b\\c.d
+} a\\b\\c
+test cmdAH-10.33 {Tcl_FileObjCmd: rootname} testsetplatform {
+    testsetplatform windows
+    file rootname a\\b.c\\d
+} a\\b.c\\d
+test cmdAH-10.34 {Tcl_FileObjCmd: rootname} testsetplatform {
+    testsetplatform windows
+    file rootname a\\b.c\\
+} a\\b.c\\
+set num 35
+foreach outer { {} a .a a. a.a } {
+    foreach inner { {} a .a a. a.a } {
+	set thing [format %s/%s $outer $inner]
+	;test cmdAH-10.$num {Tcl_FileObjCmd: rootname and extension options} testsetplatform "
+	    testsetplatform unix
+	    [list format %s%s [file rootname $thing] [file ext $thing]]
+	" $thing
+	incr num
+    }
+}
+
+# extension
+test cmdAH-11.1 {Tcl_FileObjCmd: extension} -returnCodes error -body {
+    file extension a b
+} -result {wrong # args: should be "file extension name"}
+test cmdAH-11.2 {Tcl_FileObjCmd: extension} testsetplatform {
+    testsetplatform unix
+    file extension {}
+} {}
+test cmdAH-11.3 {Tcl_FileObjCmd: extension} testsetplatform {
+    testsetplatform unix
+    file ext foo
+} {}
+test cmdAH-11.4 {Tcl_FileObjCmd: extension} testsetplatform {
+    testsetplatform unix
+    file extension foo.
+} .
+test cmdAH-11.5 {Tcl_FileObjCmd: extension} testsetplatform {
+    testsetplatform unix
+    file extension .foo
+} .foo
+test cmdAH-11.6 {Tcl_FileObjCmd: extension} testsetplatform {
+    testsetplatform unix
+    file extension abc.def
+} .def
+test cmdAH-11.7 {Tcl_FileObjCmd: extension} testsetplatform {
+    testsetplatform unix
+    file extension abc.def.ghi
+} .ghi
+test cmdAH-11.8 {Tcl_FileObjCmd: extension} testsetplatform {
+    testsetplatform unix
+    file extension a/b/c.d
+} .d
+test cmdAH-11.9 {Tcl_FileObjCmd: extension} testsetplatform {
+    testsetplatform unix
+    file extension a/b.c/d
+} {}
+test cmdAH-11.10 {Tcl_FileObjCmd: extension} testsetplatform {
+    testsetplatform unix
+    file extension a/b.c/
+} {}
+test cmdAH-11.23 {Tcl_FileObjCmd: extension} testsetplatform {
+    testsetplatform windows
+    file extension {}
+} {}
+test cmdAH-11.24 {Tcl_FileObjCmd: extension} testsetplatform {
+    testsetplatform windows
+    file ext foo
+} {}
+test cmdAH-11.25 {Tcl_FileObjCmd: extension} testsetplatform {
+    testsetplatform windows
+    file extension foo.
+} .
+test cmdAH-11.26 {Tcl_FileObjCmd: extension} testsetplatform {
+    testsetplatform windows
+    file extension .foo
+} .foo
+test cmdAH-11.27 {Tcl_FileObjCmd: extension} testsetplatform {
+    testsetplatform windows
+    file extension abc.def
+} .def
+test cmdAH-11.28 {Tcl_FileObjCmd: extension} testsetplatform {
+    testsetplatform windows
+    file extension abc.def.ghi
+} .ghi
+test cmdAH-11.29 {Tcl_FileObjCmd: extension} testsetplatform {
+    testsetplatform windows
+    file extension a/b/c.d
+} .d
+test cmdAH-11.30 {Tcl_FileObjCmd: extension} testsetplatform {
+    testsetplatform windows
+    file extension a/b.c/d
+} {}
+test cmdAH-11.31 {Tcl_FileObjCmd: extension} testsetplatform {
+    testsetplatform windows
+    file extension a\\b.c\\
+} {}
+test cmdAH-11.32 {Tcl_FileObjCmd: extension} testsetplatform {
+    testsetplatform windows
+    file extension a\\b\\c.d
+} .d
+test cmdAH-11.33 {Tcl_FileObjCmd: extension} testsetplatform {
+    testsetplatform windows
+    file extension a\\b.c\\d
+} {}
+test cmdAH-11.34 {Tcl_FileObjCmd: extension} testsetplatform {
+    testsetplatform windows
+    file extension a\\b.c\\
+} {}
+foreach {test onPlatform value result} {
+    cmdAH-11.35 unix    a..b   .b
+    cmdAH-11.36 windows a..b   .b
+    cmdAH-11.37 unix    a...b  .b
+    cmdAH-11.38 windows a...b  .b
+    cmdAH-11.39 unix    a.c..b .b
+    cmdAH-11.40 windows a.c..b .b
+    cmdAH-11.41 unix    ..b    .b
+    cmdAH-11.42 windows ..b    .b
+} {
+    test $test {Tcl_FileObjCmd: extension} testsetplatform "
+	testsetplatform $onPlatform
+	file extension $value
+    " $result
+}
+
+# pathtype
+test cmdAH-12.1 {Tcl_FileObjCmd: pathtype} -returnCodes error -body {
+    file pathtype a b
+} -result {wrong # args: should be "file pathtype name"}
+test cmdAH-12.2 {Tcl_FileObjCmd: pathtype} testsetplatform {
+    testsetplatform unix
+    file pathtype /a
+} absolute
+test cmdAH-12.3 {Tcl_FileObjCmd: pathtype} testsetplatform {
+    testsetplatform unix
+    file p a
+} relative
+test cmdAH-12.4 {Tcl_FileObjCmd: pathtype} testsetplatform {
+    testsetplatform windows
+    file pathtype c:a
+} volumerelative
+
+# split
+test cmdAH-13.1 {Tcl_FileObjCmd: split} -returnCodes error -body {
+    file split a b
+} -result {wrong # args: should be "file split name"}
+test cmdAH-13.2 {Tcl_FileObjCmd: split} testsetplatform {
+    testsetplatform unix
+    file split a
+} a
+test cmdAH-13.3 {Tcl_FileObjCmd: split} testsetplatform {
+    testsetplatform unix
+    file split a/b
+} {a b}
+
+# join
+test cmdAH-14.1 {Tcl_FileObjCmd: join} testsetplatform {
+    testsetplatform unix
+    file join a
+} a
+test cmdAH-14.2 {Tcl_FileObjCmd: join} testsetplatform {
+    testsetplatform unix
+    file join a b
+} a/b
+test cmdAH-14.3 {Tcl_FileObjCmd: join} testsetplatform {
+    testsetplatform unix
+    file join a b c d
+} a/b/c/d
+
+# error handling of Tcl_TranslateFileName
+test cmdAH-15.1 {Tcl_FileObjCmd} -constraints testsetplatform -body {
+    testsetplatform unix
+    file atime ~_bad_user
+} -returnCodes error -result {user "_bad_user" doesn't exist}
+
+catch {testsetplatform $platform}
+
+# readable
+set gorpfile [makeFile abcde gorp.file]
+set dirfile [makeDirectory dir.file]
+test cmdAH-16.1 {Tcl_FileObjCmd: readable} {
+    -returnCodes error
+    -body   {file readable a b}
+    -result {wrong # args: should be "file readable name"}
+}
+test cmdAH-16.2 {Tcl_FileObjCmd: readable} {
+    -constraints testchmod
+    -setup  	 {testchmod 0o444 $gorpfile}
+    -body   	 {file readable $gorpfile}
+    -result 	 1
+}
+test cmdAH-16.3 {Tcl_FileObjCmd: readable} {
+    -constraints {unix notRoot testchmod}
+    -setup  	 {testchmod 0o333 $gorpfile}
+    -body   	 {file readable $gorpfile}
+    -result 	 0
+}
+
+# writable
+test cmdAH-17.1 {Tcl_FileObjCmd: writable} {
+    -returnCodes error
+    -body   {file writable a b}
+    -result {wrong # args: should be "file writable name"}
+}
+test cmdAH-17.2 {Tcl_FileObjCmd: writable} {
+    -constraints {notRoot testchmod}
+    -setup  	 {testchmod 0o555 $gorpfile}
+    -body   	 {file writable $gorpfile}
+    -result 	 0
+}
+test cmdAH-17.3 {Tcl_FileObjCmd: writable} {
+    -constraints testchmod
+    -setup  	 {testchmod 0o222 $gorpfile}
+    -body   	 {file writable $gorpfile}
+    -result 	 1
+}
+
+# executable
+removeFile $gorpfile
+removeDirectory $dirfile
+set dirfile [makeDirectory dir.file]
+set gorpfile [makeFile abcde gorp.file]
+test cmdAH-18.1 {Tcl_FileObjCmd: executable} -returnCodes error -body {
+    file executable a b
+} -result {wrong # args: should be "file executable name"}
+test cmdAH-18.2 {Tcl_FileObjCmd: executable} {notRoot} {
+    file executable $gorpfile
+} 0
+test cmdAH-18.3 {Tcl_FileObjCmd: executable} {unix testchmod} {
+    # Only on unix will setting the execute bit on a regular file cause that
+    # file to be executable.
+    testchmod 0o775 $gorpfile
+    file exe $gorpfile
+} 1
+test cmdAH-18.5 {Tcl_FileObjCmd: executable} -constraints {win} -body {
+    # On pc, must be a .exe, .com, etc.
+    set x {}
+    set gorpexes {}
+    foreach ext {exe com cmd bat} {
+        lappend x [file exe nosuchfile.$ext]
+        set gorpexe [makeFile foo gorp.$ext]
+        lappend gorpexes $gorpexe
+        lappend x [file exe $gorpexe] [file exe [string toupper $gorpexe]]
+    }
+    set x
+} -cleanup {
+    foreach gorpexe $gorpexes {
+        removeFile $gorpexe
+    }
+} -result {0 1 1 0 1 1 0 1 1 0 1 1}
+test cmdAH-18.6 {Tcl_FileObjCmd: executable} {} {
+    # Directories are always executable.
+    file exe $dirfile
+} 1
+
+removeDirectory $dirfile
+removeFile $gorpfile
+set linkfile [file join [temporaryDirectory] link.file]
+file delete $linkfile
+
+# exists
+test cmdAH-19.1 {Tcl_FileObjCmd: exists} -returnCodes error -body {
+    file exists a b
+} -result {wrong # args: should be "file exists name"}
+test cmdAH-19.2 {Tcl_FileObjCmd: exists} {file exists $gorpfile} 0
+test cmdAH-19.3 {Tcl_FileObjCmd: exists} {
+    file exists [file join [temporaryDirectory] dir.file gorp.file]
+} 0
+catch {
+    set gorpfile [makeFile abcde gorp.file]
+    set dirfile [makeDirectory dir.file]
+    set subgorp [makeFile 12345 [file join $dirfile gorp.file]]
+}
+test cmdAH-19.4 {Tcl_FileObjCmd: exists} {
+    file exists $gorpfile
+} 1
+test cmdAH-19.5 {Tcl_FileObjCmd: exists} {
+    file exists $subgorp
+} 1
+# nativename
+test cmdAH-19.6 {Tcl_FileObjCmd: nativename} -body {
+    testsetplatform unix
+    file nativename a/b
+} -constraints testsetplatform -cleanup {
+    testsetplatform $platform
+} -result a/b
+test cmdAH-19.7 {Tcl_FileObjCmd: nativename} -body {
+    testsetplatform windows
+    file nativename a/b
+} -constraints testsetplatform -cleanup {
+    testsetplatform $platform
+} -result {a\b}
+test cmdAH-19.9 {Tcl_FileObjCmd: ~ : exists} {
+    file exists ~nOsUcHuSeR
+} 0
+test cmdAH-19.10 {Tcl_FileObjCmd: ~ : nativename} -body {
+    # should probably be a non-error in fact...
+    file nativename ~nOsUcHuSeR
+} -returnCodes error -match glob -result *
+# The test below has to be done in /tmp rather than the current directory in
+# order to guarantee (?) a local file system: some NFS file systems won't do
+# the stuff below correctly.
+test cmdAH-19.11 {Tcl_FileObjCmd: exists} -constraints {unix notRoot} -setup {
+    file delete -force /tmp/tcl.foo.dir/file
+    file delete -force /tmp/tcl.foo.dir
+} -body {
+    makeDirectory /tmp/tcl.foo.dir
+    makeFile 12345 /tmp/tcl.foo.dir/file
+    file attributes /tmp/tcl.foo.dir -permissions 0000
+    file exists /tmp/tcl.foo.dir/file
+} -cleanup {
+    file attributes /tmp/tcl.foo.dir -permissions 0775
+    removeFile /tmp/tcl.foo.dir/file
+    removeDirectory /tmp/tcl.foo.dir
+} -result 0
+test cmdAH-19.12 {Bug 3608360: [file exists] mustn't do globbing} -setup {
+    set newdirfile [makeDirectory newdir.file]
+    set cwd [pwd]
+    cd $newdirfile
+    # Content of file is totally unimportant; name is *not*
+    set innocentBystander [makeFile "abc" [file join $newdirfile foo.bar]]
+} -body {
+    list [file exists foo.bar] [file exists *.bar]
+} -cleanup {
+    cd $cwd
+    removeFile $innocentBystander
+    removeDirectory $newdirfile
+} -result {1 0}
+
+# Stat related commands
+
+catch {testsetplatform $platform}
+removeFile $gorpfile
+set gorpfile [makeFile "Test string" gorp.file]
+catch {file attributes $gorpfile -permissions 0765}
+
+# avoid problems with non-local filesystems
+if {[testConstraint unix] && [file exists /tmp]} {
+    set file [makeFile "data" touch.me /tmp]
+} else {
+    set file [makeFile "data" touch.me]
+}
+
+# atime
+test cmdAH-20.1 {Tcl_FileObjCmd: atime} -returnCodes error -body {
+    file atime a b c
+} -result {wrong # args: should be "file atime name ?time?"}
+test cmdAH-20.2 {Tcl_FileObjCmd: atime} -setup {
+    unset -nocomplain stat
+} -body {
+    file stat $gorpfile stat
+    list [expr {[file mtime $gorpfile] == $stat(mtime)}] \
+	    [expr {[file atime $gorpfile] == $stat(atime)}]
+} -result {1 1}
+test cmdAH-20.3 {Tcl_FileObjCmd: atime} {
+    list [catch {file atime _bogus_} msg] [string tolower $msg] $errorCode
+} {1 {could not read "_bogus_": no such file or directory} {POSIX ENOENT {no such file or directory}}}
+test cmdAH-20.4 {Tcl_FileObjCmd: atime} -returnCodes error -body {
+    file atime $file notint
+} -result {expected integer but got "notint"}
+test cmdAH-20.5 {Tcl_FileObjCmd: atime touch} {unix} {
+    set atime [file atime $file]
+    after 1100; # pause a sec to notice change in atime
+    set newatime [clock seconds]
+    set modatime [file atime $file $newatime]
+    expr {$newatime == $modatime ? 1 : "$newatime != $modatime"}
+} 1
+test cmdAH-20.6 {Tcl_FileObjCmd: atime touch} -setup {
+    set old [pwd]
+    cd $::tcltest::temporaryDirectory
+    set volumetype [testvolumetype]
+    cd $old
+} -constraints {win testvolumetype} -body {
+    if {"NTFS" ne $volumetype} {
+	# Windows FAT doesn't understand atime, but NTFS does. May also fail
+	# for Windows on NFS mounted disks.
+	return 1
+    }
+    cd $old
+    set atime [file atime $file]
+    after 1100; # pause a sec to notice change in atime
+    set newatime [clock seconds]
+    set modatime [file atime $file $newatime]
+    expr {$newatime == $modatime ? 1 : "$newatime != $modatime"}
+} -result 1
+test cmdAH-20.7 {
+    Tcl_FileObjCmd: atime (built-in Windows names)
+} -constraints {win} -body {
+    file atime con
+} -result "could not get access time for file \"con\"" -returnCodes error
+test cmdAH-20.7.1 {
+    Tcl_FileObjCmd: atime (built-in Windows names with dir path and extension)
+} -constraints {win} -body {
+    file atime [file join [temporaryDirectory] CON.txt]
+} -result "could not get access time for file \"[file join [temporaryDirectory] CON.txt]\"" -returnCodes error
+
+if {[testConstraint unix] && [file exists /tmp]} {
+    removeFile touch.me /tmp
+} else {
+    removeFile touch.me
+}
+
+# isdirectory
+test cmdAH-21.1 {Tcl_FileObjCmd: isdirectory} -returnCodes error -body {
+    file isdirectory a b
+} -result {wrong # args: should be "file isdirectory name"}
+test cmdAH-21.2 {Tcl_FileObjCmd: isdirectory} {file isdirectory $gorpfile} 0
+test cmdAH-21.3 {Tcl_FileObjCmd: isdirectory} {file isdirectory $dirfile} 1
+
+# isfile
+test cmdAH-22.1 {Tcl_FileObjCmd: isfile} -returnCodes error -body {
+    file isfile a b
+} -result {wrong # args: should be "file isfile name"}
+test cmdAH-22.2 {Tcl_FileObjCmd: isfile} {file isfile $gorpfile} 1
+test cmdAH-22.3 {Tcl_FileObjCmd: isfile} {file isfile $dirfile} 0
+
+# lstat and readlink: don't run these tests everywhere, since not all sites
+# will have symbolic links
+catch {file link -symbolic $linkfile $gorpfile}
+test cmdAH-23.1 {Tcl_FileObjCmd: lstat} -returnCodes error -body {
+    file lstat a
+} -result {wrong # args: should be "file lstat name varName"}
+test cmdAH-23.2 {Tcl_FileObjCmd: lstat} -returnCodes error -body {
+    file lstat a b c
+} -result {wrong # args: should be "file lstat name varName"}
+test cmdAH-23.3 {Tcl_FileObjCmd: lstat} -setup {
+    unset -nocomplain stat
+} -constraints {unix nonPortable} -body {
+    file lstat $linkfile stat
+    lsort [array names stat]
+} -result {atime ctime dev gid ino mode mtime nlink size type uid}
+test cmdAH-23.4 {Tcl_FileObjCmd: lstat} -setup {
+    unset -nocomplain stat
+} -constraints {unix nonPortable} -body {
+    file lstat $linkfile stat
+    list $stat(nlink) [expr $stat(mode)&0777] $stat(type)
+} -result {1 511 link}
+test cmdAH-23.5 {Tcl_FileObjCmd: lstat errors} {nonPortable} {
+    list [catch {file lstat _bogus_ stat} msg] [string tolower $msg] \
+	$errorCode
+} {1 {could not read "_bogus_": no such file or directory} {POSIX ENOENT {no such file or directory}}}
+test cmdAH-23.6 {Tcl_FileObjCmd: lstat errors} -setup {
+    unset -nocomplain x
+} -body {
+    set x 44
+    list [catch {file lstat $gorpfile x} msg] $msg $errorCode
+} -result {1 {can't set "x(dev)": variable isn't array} {TCL LOOKUP VARNAME x}}
+unset -nocomplain stat
+# mkdir
+set dirA [file join [temporaryDirectory] a]
+set dirB [file join [temporaryDirectory] a]
+test cmdAH-23.7 {Tcl_FileObjCmd: mkdir} -setup {
+    catch {file delete -force $dirA}
+} -body {
+    file mkdir $dirA
+    file isdirectory $dirA
+} -cleanup {
+    file delete $dirA
+} -result {1}
+test cmdAH-23.8 {Tcl_FileObjCmd: mkdir} -setup {
+    catch {file delete -force $dirA}
+} -body {
+    file mkdir $dirA/b
+    file isdirectory $dirA/b
+} -cleanup {
+    file delete -force $dirA
+} -result {1}
+test cmdAH-23.9 {Tcl_FileObjCmd: mkdir} -setup {
+    catch {file delete -force $dirA}
+} -body {
+    file mkdir $dirA/b/c
+    file isdirectory $dirA/b/c
+} -cleanup {
+    file delete -force $dirA
+} -result {1}
+test cmdAH-23.10 {Tcl_FileObjCmd: mkdir} -setup {
+    catch {file delete -force $dirA}
+    catch {file delete -force $dirB}
+} -body {
+    file mkdir $dirA/b $dirB/a/c
+    list [file isdirectory $dirA/b] [file isdirectory $dirB/a/c]
+} -cleanup {
+    file delete -force $dirA
+    file delete -force $dirB
+} -result {1 1}
+test cmdAH-23.11 {Tcl_FileObjCmd: mkdir} {
+    # Allow zero arguments (TIP 323)
+    file mkdir
+} {}
+
+set file [makeFile "data" touch.me]
+# mtime
+test cmdAH-24.1 {Tcl_FileObjCmd: mtime} -returnCodes error -body {
+    file mtime a b c
+} -result {wrong # args: should be "file mtime name ?time?"}
+test cmdAH-24.2 {Tcl_FileObjCmd: mtime} -setup {
+    # Check (allowing for clock-skew and OS interrupts as best we can) that
+    # the change in mtime on a file being written is the time elapsed between
+    # writes. Note that this can still fail on very busy systems if there are
+    # long preemptions between the writes and the reading of the clock, but
+    # there's not much you can do about that other than the completely
+    # horrible "keep on trying to write until you managed to do it all in less
+    # than a second." - DKF
+    waitForEvenSecondForFAT
+} -body {
+    set f [open $gorpfile w]
+    puts $f "More text"
+    close $f
+    set clockOld [clock seconds]
+    set fileOld [file mtime $gorpfile]
+    after 2000
+    set f [open $gorpfile w]
+    puts $f "More text"
+    close $f
+    set clockNew [clock seconds]
+    set fileNew [file mtime $gorpfile]
+    expr {
+	(($fileNew > $fileOld) && ($clockNew > $clockOld) &&
+	(abs(($fileNew-$fileOld) - ($clockNew-$clockOld)) <= 1)) ? "1" :
+	"file:($fileOld=>$fileNew) clock:($clockOld=>$clockNew)"
+    }
+} -result {1}
+test cmdAH-24.3 {Tcl_FileObjCmd: mtime} -setup {
+    unset -nocomplain stat
+} -body {
+    file stat $gorpfile stat
+    list [expr {[file mtime $gorpfile] == $stat(mtime)}] \
+	    [expr {[file atime $gorpfile] == $stat(atime)}]
+} -result {1 1}
+test cmdAH-24.4 {Tcl_FileObjCmd: mtime} {
+    list [catch {file mtime _bogus_} msg] [string tolower $msg] $errorCode
+} {1 {could not read "_bogus_": no such file or directory} {POSIX ENOENT {no such file or directory}}}
+test cmdAH-24.5 {Tcl_FileObjCmd: mtime} -setup {
+    # Under Unix, use a file in /tmp to avoid clock skew due to NFS. On other
+    # platforms, just use a file in the local directory.
+    if {[testConstraint unix]} {
+	set name /tmp/tcl.test.[pid]
+    } else {
+	set name [file join [temporaryDirectory] tf]
+    }
+} -body {
+    # Make sure that a new file's time is correct. 10 seconds variance is
+    # allowed used due to slow networks or clock skew on a network drive.
+    file delete -force $name
+    close [open $name w]
+    expr {abs([clock seconds]-[file mtime $name])<10}
+} -cleanup {
+    file delete $name
+} -result {1}
+test cmdAH-24.7 {Tcl_FileObjCmd: mtime} -returnCodes error -body {
+    file mtime $file notint
+} -result {expected integer but got "notint"}
+test cmdAH-24.8 {Tcl_FileObjCmd: mtime touch} unix {
+    set mtime [file mtime $file]
+    after 1100; # pause a sec to notice change in mtime
+    set newmtime [clock seconds]
+    set modmtime [file mtime $file $newmtime]
+    expr {$newmtime == $modmtime ? 1 : "$newmtime != $modmtime"}
+} 1
+test cmdAH-24.9 {Tcl_FileObjCmd: mtime touch with non-ascii chars} -setup {
+    set oldfile $file
+} -constraints unix -body {
+    # introduce some non-ascii characters.
+    append file \u2022
+    file delete -force $file
+    file rename $oldfile $file
+    set mtime [file mtime $file]
+    after 1100; # pause a sec to notice change in mtime
+    set newmtime [clock seconds]
+    set modmtime [file mtime $file $newmtime]
+    expr {$newmtime == $modmtime ? 1 : "$newmtime != $modmtime"}
+} -cleanup {
+    file rename $file $oldfile
+} -result 1
+test cmdAH-24.10 {Tcl_FileObjCmd: mtime touch} -constraints win -setup {
+    waitForEvenSecondForFAT
+} -body {
+    set mtime [file mtime $file]
+    after 2100; # pause two secs to notice change in mtime on FAT fs'es
+    set newmtime [clock seconds]
+    set modmtime [file mtime $file $newmtime]
+    expr {$newmtime == $modmtime ? 1 : "$newmtime != $modmtime"}
+} -result 1
+test cmdAH-24.11 {Tcl_FileObjCmd: mtime touch with non-ascii chars} -setup {
+    waitForEvenSecondForFAT
+    set oldfile $file
+} -constraints win -body {
+    # introduce some non-ascii characters.
+    append file \u2022
+    file delete -force $file
+    file rename $oldfile $file
+    set mtime [file mtime $file]
+    after 2100; # pause two secs to notice change in mtime on FAT fs'es
+    set newmtime [clock seconds]
+    set modmtime [file mtime $file $newmtime]
+    expr {$newmtime == $modmtime ? 1 : "$newmtime != $modmtime"}
+} -cleanup {
+    file rename $file $oldfile
+} -result 1
+removeFile touch.me
+rename waitForEvenSecondForFAT {}
+test cmdAH-24.12 {Tcl_FileObjCmd: mtime and daylight savings} -setup {
+    set name [file join [temporaryDirectory] clockchange]
+    file delete -force $name
+    close [open $name w]
+} -body {
+    set time [clock scan "21:00:00 October 30 2004 GMT"]
+    file mtime $name $time
+    set newmtime [file mtime $name]
+    expr {$newmtime == $time ? 1 : "$newmtime != $time"}
+} -cleanup {
+    file delete $name
+} -result {1}
+# bug 1420432: setting mtime fails for directories on windows.
+test cmdAH-24.13 {Tcl_FileObjCmd: directory mtime} -setup {
+    set dirname [file join [temporaryDirectory] tmp[pid]]
+    file delete -force $dirname
+} -constraints tempNotWin -body {
+    file mkdir $dirname
+    set old [file mtime $dirname]
+    file mtime $dirname 0
+    set new [file mtime $dirname]
+    list $new [expr {$old != $new}]
+} -cleanup {
+    file delete -force $dirname
+} -result {0 1}
+test cmdAH-24.14 {
+    Tcl_FileObjCmd: mtime (built-in Windows names)
+} -constraints {win} -body {
+    file mtime con
+} -result "could not get modification time for file \"con\"" -returnCodes error
+test cmdAH-24.14.1 {
+    Tcl_FileObjCmd: mtime (built-in Windows names with dir path and extension)
+} -constraints {win} -body {
+    file mtime [file join [temporaryDirectory] CON.txt]
+} -result "could not get modification time for file \"[file join [temporaryDirectory] CON.txt]\"" -returnCodes error
+
+# owned
+test cmdAH-25.1 {Tcl_FileObjCmd: owned} -returnCodes error -body {
+    file owned a b
+} -result {wrong # args: should be "file owned name"}
+test cmdAH-25.2 {Tcl_FileObjCmd: owned} -constraints win -body {
+    file owned $gorpfile
+} -result 1
+test cmdAH-25.2.1 {Tcl_FileObjCmd: owned} -constraints unix -setup {
+    # Avoid problems with AFS
+    set tmpfile [makeFile "data" touch.me /tmp]
+} -body {
+    file owned $tmpfile
+} -cleanup {
+    removeFile touch.me /tmp
+} -result 1
+test cmdAH-25.3 {Tcl_FileObjCmd: owned} {unix notRoot} {
+    file owned /
+} 0
+test cmdAH-25.3.1 {Tcl_FileObjCmd: owned} -constraints win -body {
+    file owned $env(windir)
+} -result 0
+test cmdAH-25.4 {Tcl_FileObjCmd: owned} -body {
+    file owned nosuchfile
+} -result 0
+
+# readlink
+test cmdAH-26.1 {Tcl_FileObjCmd: readlink} -returnCodes error -body {
+    file readlink a b
+} -result {wrong # args: should be "file readlink name"}
+test cmdAH-26.2 {Tcl_FileObjCmd: readlink} {unix nonPortable} {
+    file readlink $linkfile
+} $gorpfile
+test cmdAH-26.3 {Tcl_FileObjCmd: readlink errors} {unix nonPortable} {
+    list [catch {file readlink _bogus_} msg] [string tolower $msg] $errorCode
+} {1 {could not readlink "_bogus_": no such file or directory} {POSIX ENOENT {no such file or directory}}}
+test cmdAH-26.5 {Tcl_FileObjCmd: readlink errors} {win nonPortable} {
+    list [catch {file readlink _bogus_} msg] [string tolower $msg] $errorCode
+} {1 {could not readlink "_bogus_": invalid argument} {POSIX EINVAL {invalid argument}}}
+
+# size
+test cmdAH-27.1 {Tcl_FileObjCmd: size} -returnCodes error -body {
+    file size a b
+} -result {wrong # args: should be "file size name"}
+test cmdAH-27.2 {Tcl_FileObjCmd: size} {
+    set oldsize [file size $gorpfile]
+    set f [open $gorpfile a]
+    fconfigure $f -translation lf -eofchar {}
+    puts $f "More text"
+    close $f
+    expr {[file size $gorpfile] - $oldsize}
+} {10}
+test cmdAH-27.3 {Tcl_FileObjCmd: size} {
+    list [catch {file size _bogus_} msg] [string tolower $msg] $errorCode
+} {1 {could not read "_bogus_": no such file or directory} {POSIX ENOENT {no such file or directory}}}
+test cmdAH-27.4 {
+    Tcl_FileObjCmd: size (built-in Windows names)
+} -constraints {win} -body {
+    file size con
+} -result 0
+test cmdAH-27.4.1 {
+    Tcl_FileObjCmd: size (built-in Windows names with dir path and extension)
+} -constraints {win} -body {
+    file size [file join [temporaryDirectory] con.txt]
+} -result 0
+
+catch {testsetplatform $platform}
+removeFile $gorpfile
+set gorpfile [makeFile "Test string" gorp.file]
+catch {file attributes $gorpfile -permissions 0765}
+
+# stat
+test cmdAH-28.1 {Tcl_FileObjCmd: stat} -returnCodes error -body {
+    file stat _bogus_
+} -result {wrong # args: should be "file stat name varName"}
+test cmdAH-28.2 {Tcl_FileObjCmd: stat} -returnCodes error -body {
+    file stat _bogus_ a b
+} -result {wrong # args: should be "file stat name varName"}
+test cmdAH-28.3 {Tcl_FileObjCmd: stat} -setup {
+    unset -nocomplain stat
+    set stat(blocks) [set stat(blksize) {}]
+} -body {
+    file stat $gorpfile stat
+    unset stat(blocks) stat(blksize); # Ignore these fields; not always set
+    lsort [array names stat]
+} -result {atime ctime dev gid ino mode mtime nlink size type uid}
+test cmdAH-28.4 {Tcl_FileObjCmd: stat} -setup {
+    unset -nocomplain stat
+} -body {
+    file stat $gorpfile stat
+    list $stat(nlink) $stat(size) $stat(type)
+} -result {1 12 file}
+test cmdAH-28.5 {Tcl_FileObjCmd: stat} -constraints {unix} -setup {
+    unset -nocomplain stat
+} -body {
+    file stat $gorpfile stat
+    expr {$stat(mode) & 0o777}
+} -result {501}
+test cmdAH-28.6 {Tcl_FileObjCmd: stat} {
+    list [catch {file stat _bogus_ stat} msg] [string tolower $msg] $errorCode
+} {1 {could not read "_bogus_": no such file or directory} {POSIX ENOENT {no such file or directory}}}
+test cmdAH-28.7 {Tcl_FileObjCmd: stat} -setup {
+    unset -nocomplain x
+} -returnCodes error -body {
+    set x 44
+    file stat $gorpfile x
+} -result {can't set "x(dev)": variable isn't array}
+test cmdAH-28.8 {Tcl_FileObjCmd: stat} -setup {
+    set filename [makeFile "" foo.text]
+} -body {
+    # Sign extension of purported unsigned short to int.
+    file stat $filename stat
+    expr {$stat(mode) > 0}
+} -cleanup {
+    removeFile $filename
+} -result 1
+test cmdAH-28.9 {Tcl_FileObjCmd: stat} win {
+    # stat of root directory was failing. Don't care about answer, just that
+    # test runs. Relative paths that resolve to root
+    set old [pwd]
+    cd c:/
+    file stat c: stat
+    file stat c:. stat
+    file stat . stat
+    cd $old
+    file stat / stat
+    file stat c:/ stat
+    file stat c:/. stat
+} {}
+test cmdAH-28.10 {Tcl_FileObjCmd: stat} {win nonPortable} {
+    # stat of root directory was failing. Don't care about answer, just that
+    # test runs.
+    file stat //pop/$env(USERNAME) stat
+    file stat //pop/$env(USERNAME)/ stat
+    file stat //pop/$env(USERNAME)/. stat
+} {}
+test cmdAH-28.11 {Tcl_FileObjCmd: stat} -setup {
+    set old [pwd]
+} -constraints {win nonPortable} -body {
+    # stat of network directory was returning id of current local drive.
+    cd c:/
+    file stat //pop/$env(USERNAME) stat
+    expr {$stat(dev) == 2}
+} -cleanup {
+    cd $old
+} -result 0
+test cmdAH-28.12 {Tcl_FileObjCmd: stat} -setup {
+    set filename [makeFile "" foo.test]
+} -body {
+    # stat(mode) with S_IFREG flag was returned as a negative number if mode_t
+    # was a short instead of an unsigned short.
+    file stat $filename stat
+    expr {$stat(mode) > 0}
+} -cleanup {
+    removeFile $filename
+} -result 1
+test cmdAH-28.13 {Tcl_FileObjCmd: stat (built-in Windows names)} -constraints {win} -setup {
+    unset -nocomplain stat
+} -body {
+    file stat con stat
+    lmap elem {atime ctime dev gid ino mode mtime nlink size type uid} {set stat($elem)}
+} -result {0 0 -1 0 0 8630 0 0 0 characterSpecial 0}
+test cmdAH-28.13.1 {Tcl_FileObjCmd: stat (built-in Windows names)} -constraints {win} -setup {
+    unset -nocomplain stat
+} -body {
+    file stat [file join [temporaryDirectory] CON.txt] stat
+    lmap elem {atime ctime dev gid ino mode mtime nlink size type uid} {set stat($elem)}
+} -result {0 0 -1 0 0 8630 0 0 0 characterSpecial 0}
+unset -nocomplain stat
+
+# type
+test cmdAH-29.1 {Tcl_FileObjCmd: type} -returnCodes error -body {
+    file type a b
+} -result {wrong # args: should be "file type name"}
+test cmdAH-29.2 {Tcl_FileObjCmd: type} {
+    file type $dirfile
+} directory
+test cmdAH-29.3.0 {Tcl_FileObjCmd: delete removes link not file} {unix nonPortable} {
+    set exists [list [file exists $linkfile] [file exists $gorpfile]]
+    file delete $linkfile
+    set exists2	[list [file exists $linkfile] [file exists $gorpfile]]
+    list $exists $exists2
+} {{1 1} {0 1}}
+test cmdAH-29.3 {Tcl_FileObjCmd: type} {
+    file type $gorpfile
+} file
+test cmdAH-29.4 {Tcl_FileObjCmd: type} -constraints {unix} -setup {
+    catch {file delete $linkfile}
+} -body {
+    # Unlike [exec ln -s], [file link] requires an existing target
+    file link -symbolic $linkfile $gorpfile
+    file type $linkfile
+} -cleanup {
+    file delete $linkfile
+} -result link
+test cmdAH-29.4.1 {Tcl_FileObjCmd: type} -constraints {linkDirectory} -setup {
+    set tempdir [makeDirectory temp]
+} -body {
+    set linkdir [file join [temporaryDirectory] link.dir]
+    file link -symbolic $linkdir $tempdir
+    file type $linkdir
+} -cleanup {
+    file delete $linkdir
+    removeDirectory $tempdir
+} -result link
+test cmdAH-29.5 {Tcl_FileObjCmd: type} {
+    list [catch {file type _bogus_} msg] [string tolower $msg] $errorCode
+} {1 {could not read "_bogus_": no such file or directory} {POSIX ENOENT {no such file or directory}}}
+test cmdAH-29.6 {
+    Tcl_FileObjCmd: type (built-in Windows names)
+} -constraints {win} -body {
+    file type con
+} -result "characterSpecial"
+test cmdAH-29.6.1 {
+    Tcl_FileObjCmd: type (built-in Windows names, with dir path and extension)
+} -constraints {win} -body {
+    file type [file join [temporaryDirectory] CON.txt]
+} -result "characterSpecial"
+
+# Error conditions
+test cmdAH-30.1 {Tcl_FileObjCmd: error conditions} -returnCodes error -body {
+    file gorp x
+} -result {unknown or ambiguous subcommand "gorp": must be atime, attributes, channels, copy, delete, dirname, executable, exists, extension, isdirectory, isfile, join, link, lstat, mkdir, mtime, nativename, normalize, owned, pathtype, readable, readlink, rename, rootname, separator, size, split, stat, system, tail, tempfile, type, volumes, or writable}
+test cmdAH-30.2 {Tcl_FileObjCmd: error conditions} -returnCodes error -body {
+    file ex x
+} -match glob -result {unknown or ambiguous subcommand "ex": must be *}
+test cmdAH-30.3 {Tcl_FileObjCmd: error conditions} -returnCodes error -body {
+    file is x
+} -match glob -result {unknown or ambiguous subcommand "is": must be *}
+test cmdAH-30.4 {Tcl_FileObjCmd: error conditions} -returnCodes error -body {
+    file z x
+} -match glob -result {unknown or ambiguous subcommand "z": must be *}
+test cmdAH-30.5 {Tcl_FileObjCmd: error conditions} -returnCodes error -body {
+    file read x
+} -match glob -result {unknown or ambiguous subcommand "read": must be *}
+test cmdAH-30.6 {Tcl_FileObjCmd: error conditions} -returnCodes error -body {
+    file s x
+} -match glob -result {unknown or ambiguous subcommand "s": must be *}
+test cmdAH-30.7 {Tcl_FileObjCmd: error conditions} -returnCodes error -body {
+    file t x
+} -match glob -result {unknown or ambiguous subcommand "t": must be *}
+test cmdAH-30.8 {Tcl_FileObjCmd: error conditions} -returnCodes error -body {
+    file dirname ~woohgy
+} -result {user "woohgy" doesn't exist}
+
+# channels
+# In testing 'file channels', we need to make sure that a channel created in
+# one interp isn't visible in another.
+
+interp create simpleInterp
+interp create -safe safeInterp
+interp create
+catch {safeInterp expose file file}
+
+test cmdAH-31.1 {Tcl_FileObjCmd: channels, too many args} -body {
+    file channels a b
+} -returnCodes error -result {wrong # args: should be "file channels ?pattern?"}
+test cmdAH-31.2 {Tcl_FileObjCmd: channels, too many args} {
+    # Normal interps start out with only the standard channels
+    lsort [simpleInterp eval [list file chan]]
+} {stderr stdin stdout}
+test cmdAH-31.3 {Tcl_FileObjCmd: channels, globbing} {
+    string equal [file channels] [file channels *]
+} {1}
+test cmdAH-31.4 {Tcl_FileObjCmd: channels, globbing} {
+    lsort [file channels std*]
+} {stderr stdin stdout}
+set newFileId [open $gorpfile w]
+test cmdAH-31.5 {Tcl_FileObjCmd: channels} {
+    set res [file channels $newFileId]
+    string equal $newFileId $res
+} {1}
+test cmdAH-31.6 {Tcl_FileObjCmd: channels in other interp} {
+    # Safe interps start out with no channels
+    safeInterp eval [list file channels]
+} {}
+test cmdAH-31.7 {Tcl_FileObjCmd: channels in other interp} -body {
+    safeInterp eval [list puts $newFileId "hello"]
+} -returnCodes error -result "can not find channel named \"$newFileId\""
+interp share {} $newFileId safeInterp
+interp share {} stdout safeInterp
+test cmdAH-31.8 {Tcl_FileObjCmd: channels in other interp} {
+    # $newFileId should now be visible in both interps
+    list [file channels $newFileId] \
+	    [safeInterp eval [list file channels $newFileId]]
+} [list $newFileId $newFileId]
+test cmdAH-31.9 {Tcl_FileObjCmd: channels in other interp} {
+    lsort [safeInterp eval [list file channels]]
+} [lsort [list stdout $newFileId]]
+test cmdAH-31.10 {Tcl_FileObjCmd: channels in other interp} {
+    # we can now write to $newFileId from slave
+    safeInterp eval [list puts $newFileId "hello"]
+} {}
+interp transfer {} $newFileId safeInterp
+test cmdAH-31.11 {Tcl_FileObjCmd: channels in other interp} {
+    # $newFileId should now be visible only in safeInterp
+    list [file channels $newFileId] \
+	    [safeInterp eval [list file channels $newFileId]]
+} [list {} $newFileId]
+test cmdAH-31.12 {Tcl_FileObjCmd: channels in other interp} {
+    lsort [safeInterp eval [list file channels]]
+} [lsort [list stdout $newFileId]]
+test cmdAH-31.13 {Tcl_FileObjCmd: channels in other interp} {
+    safeInterp eval [list close $newFileId]
+    safeInterp eval [list file channels]
+} {stdout}
+
+# Temp files (TIP#210)
+test cmdAH-32.1 {file tempfile - usage} -returnCodes error -body {
+    file tempfile a b c
+} -result {wrong # args: should be "file tempfile ?nameVar? ?template?"}
+test cmdAH-32.2 {file tempfile - returns a read/write channel} -body {
+    set f [file tempfile]
+    puts $f ok
+    seek $f 0
+    gets $f
+} -cleanup {
+    catch {close $f}
+} -result ok
+test cmdAH-32.3 {file tempfile - makes filenames} -setup {
+    unset -nocomplain name
+} -body {
+    set result [info exists name]
+    set f [file tempfile name]
+    lappend result [info exists name] [file exists $name]
+    close $f
+    lappend result [file exists $name]
+} -cleanup {
+    catch {close $f}
+    catch {file delete $name}
+} -result {0 1 1 1}
+# We try to obey the template on Unix, but don't (currently) bother on Win
+test cmdAH-32.4 {file tempfile - templates} -constraints unix -body {
+    close [file tempfile name foo]
+    expr {[string match foo* [file tail $name]] ? "ok" : "foo produced $name"}
+} -cleanup {
+    catch {file delete $name}
+} -result ok
+test cmdAH-32.5 {file tempfile - templates} -constraints unix -body {
+    set template [file join $dirfile foo]
+    close [file tempfile name $template]
+    expr {[string match $template* $name] ? "ok" : "$template produced $name"}
+} -cleanup {
+    catch {file delete $name}
+} -result ok
+# Not portable; not all unix systems have mkstemps()
+test cmdAH-32.6 {file tempfile - templates} -body {
+    set template [file join $dirfile foo]
+    close [file tempfile name $template.bar]
+    expr {[string match $template*.bar $name] ? "ok" :
+	  "$template.bar produced $name"}
+} -constraints {unix nonPortable} -cleanup {
+    catch {file delete $name}
+} -result ok
+
+# This shouldn't work, but just in case a test above failed...
+catch {close $newFileId}
+
+interp delete safeInterp
+interp delete simpleInterp
+
+# cleanup
+catch {testsetplatform $platform}
+unset -nocomplain platform
+
+# Tcl_ForObjCmd is tested in for.test
+
+catch {file attributes $dirfile -permissions 0777}
+removeDirectory $dirfile
+removeFile $gorpfile
+# No idea how well [removeFile] copes with links...
+file delete $linkfile
+
+cd $cmdAHwd
+
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/tests/cmdIL.test b/tests/cmdIL.test
new file mode 100644
index 0000000..23a5f96
--- /dev/null
+++ b/tests/cmdIL.test
@@ -0,0 +1,745 @@
+# This file contains a collection of tests for the procedures in the file
+# tclCmdIL.c. Sourcing this file into Tcl runs the tests and generates output
+# for errors. No output means no errors were found.
+#
+# Copyright (c) 1997 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution of
+# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+    package require tcltest 2
+    namespace import -force ::tcltest::*
+}
+
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
+
+# Used for constraining memory leak tests
+testConstraint memory [llength [info commands memory]]
+testConstraint testobj [llength [info commands testobj]]
+
+test cmdIL-1.1 {Tcl_LsortObjCmd procedure} -returnCodes error -body {
+    lsort
+} -result {wrong # args: should be "lsort ?-option value ...? list"}
+test cmdIL-1.2 {Tcl_LsortObjCmd procedure} -returnCodes error -body {
+    lsort -foo {1 3 2 5}
+} -result {bad option "-foo": must be -ascii, -command, -decreasing, -dictionary, -increasing, -index, -indices, -integer, -nocase, -real, -stride, or -unique}
+test cmdIL-1.3 {Tcl_LsortObjCmd procedure, default options} {
+    lsort {d e c b a \{ d35 d300}
+} {a b c d d300 d35 e \{}
+test cmdIL-1.4 {Tcl_LsortObjCmd procedure, -ascii option} {
+    lsort -integer -ascii {d e c b a d35 d300}
+} {a b c d d300 d35 e}
+test cmdIL-1.5 {Tcl_LsortObjCmd procedure, -command option} -body {
+    lsort -command {1 3 2 5}
+} -returnCodes error -result {"-command" option must be followed by comparison command}
+test cmdIL-1.6 {Tcl_LsortObjCmd procedure, -command option} -setup {
+    proc cmp {a b} {
+	expr {[string match x* $b] - [string match x* $a]}
+    }
+} -body {
+    lsort -command cmp {x1 abc x2 def x3 x4}
+} -result {x1 x2 x3 x4 abc def} -cleanup {
+    rename cmp ""
+}
+test cmdIL-1.7 {Tcl_LsortObjCmd procedure, -decreasing option} {
+    lsort -decreasing {d e c b a d35 d300}
+} {e d35 d300 d c b a}
+test cmdIL-1.8 {Tcl_LsortObjCmd procedure, -dictionary option} {
+    lsort -dictionary {d e c b a d35 d300}
+} {a b c d d35 d300 e}
+test cmdIL-1.9 {Tcl_LsortObjCmd procedure, -dictionary option} {
+    lsort -dictionary {1k 0k 10k}
+} {0k 1k 10k}
+test cmdIL-1.10 {Tcl_LsortObjCmd procedure, -increasing option} {
+    lsort -decreasing -increasing {d e c b a d35 d300}
+} {a b c d d300 d35 e}
+test cmdIL-1.11 {Tcl_LsortObjCmd procedure, -index option} -body {
+    lsort -index {1 3 2 5}
+} -returnCodes error -result {"-index" option must be followed by list index}
+test cmdIL-1.12 {Tcl_LsortObjCmd procedure, -index option} -body {
+    lsort -index foo {1 3 2 5}
+} -returnCodes error -result {bad index "foo": must be integer?[+-]integer? or end?[+-]integer?}
+test cmdIL-1.13 {Tcl_LsortObjCmd procedure, -index option} {
+    lsort -index end -integer {{2 25} {10 20 50 100} {3 16 42} 1}
+} {1 {2 25} {3 16 42} {10 20 50 100}}
+test cmdIL-1.14 {Tcl_LsortObjCmd procedure, -index option} {
+    lsort -index 1 -integer {{1 25 100} {3 16 42} {10 20 50}}
+} {{3 16 42} {10 20 50} {1 25 100}}
+test cmdIL-1.15 {Tcl_LsortObjCmd procedure, -integer option} {
+    lsort -integer {24 6 300 18}
+} {6 18 24 300}
+test cmdIL-1.16 {Tcl_LsortObjCmd procedure, -integer option} -body {
+    lsort -integer {1 3 2.4}
+} -returnCodes error -result {expected integer but got "2.4"}
+test cmdIL-1.17 {Tcl_LsortObjCmd procedure, -real option} {
+    lsort -real {24.2 6e3 150e-1}
+} {150e-1 24.2 6e3}
+test cmdIL-1.18 {Tcl_LsortObjCmd procedure, bogus list} -body {
+    lsort "1 2 3 \{ 4"
+} -returnCodes error -result {unmatched open brace in list}
+test cmdIL-1.19 {Tcl_LsortObjCmd procedure, empty list} {
+    lsort {}
+} {}
+test cmdIL-1.22 {Tcl_LsortObjCmd procedure, unique sort} {
+    lsort -integer -unique {3 1 2 3 1 4 3}
+} {1 2 3 4}
+test cmdIL-1.23 {Tcl_LsortObjCmd procedure, unique sort with index} {
+    # lsort -unique should return the last unique item
+    lsort -unique -index 0 {{a b} {c b} {a c} {d a}}
+} {{a c} {c b} {d a}}
+test cmdIL-1.24 {Tcl_LsortObjCmd procedure, order of -index and -command} -setup {
+    catch {rename 1 ""}
+    proc testcmp {a b} {return [string compare $a $b]}
+} -body {
+    set l [list [list a b] [list c d]]
+    lsort -command testcmp -index 1 $l
+} -cleanup {
+    rename testcmp ""
+} -result [list [list a b] [list c d]]
+test cmdIL-1.25 {Tcl_LsortObjCmd procedure, order of -index and -command} -setup {
+    catch {rename 1 ""}
+    proc testcmp {a b} {return [string compare $a $b]}
+} -body {
+    set l [list [list a b] [list c d]]
+    lsort -index 1 -command testcmp $l
+} -cleanup {
+    rename testcmp ""
+} -result [list [list a b] [list c d]]
+# Note that the required order only exists in the end-1'th element; indexing
+# using the end element or any fixed offset from the start will not work...
+test cmdIL-1.26 {Tcl_LsortObjCmd procedure, offset indexing from end} {
+    lsort -index end-1 {{a 1 e i} {b 2 3 f g} {c 4 5 6 d h}}
+} {{c 4 5 6 d h} {a 1 e i} {b 2 3 f g}}
+test cmdIL-1.27 {Tcl_LsortObjCmd procedure, returning indices} {
+    lsort -indices {a c b}
+} {0 2 1}
+test cmdIL-1.28 {Tcl_LsortObjCmd procedure, returning indices} {
+    lsort -indices -unique -decreasing -real {1.2 34.5 34.5 5.6}
+} {2 3 0}
+test cmdIL-1.29 {Tcl_LsortObjCmd procedure, loss of list rep during sorting} {
+    set l {1 2 3}
+    string length [lsort -command {apply {args {string length $::l}}} $l]
+} 5
+test cmdIL-1.30 {Tcl_LsortObjCmd procedure, -stride option} {
+    lsort -stride 2 {f e d c b a}
+} {b a d c f e}
+test cmdIL-1.31 {Tcl_LsortObjCmd procedure, -stride option} {
+    lsort -stride 3 {f e d c b a}
+} {c b a f e d}
+test cmdIL-1.32 {lsort -stride errors} -returnCodes error -body {
+    lsort -stride foo bar
+} -result {expected integer but got "foo"}
+test cmdIL-1.33 {lsort -stride errors} -returnCodes error -body {
+    lsort -stride 1 bar
+} -result {stride length must be at least 2}
+test cmdIL-1.34 {lsort -stride errors} -returnCodes error -body {
+    lsort -stride 2 {a b c}
+} -result {list size must be a multiple of the stride length}
+test cmdIL-1.35 {lsort -stride errors} -returnCodes error -body {
+    lsort -stride 2 -index 3 {a b c d}
+} -result {when used with "-stride", the leading "-index" value must be within the group}
+test cmdIL-1.36 {lsort -stride and -index: Bug 2918962} {
+    lsort -stride 2 -index {0 1} {
+	{{c o d e} 54321} {{b l a h} 94729}
+	{{b i g} 12345} {{d e m o} 34512}
+    }
+} {{{b i g} 12345} {{d e m o} 34512} {{c o d e} 54321} {{b l a h} 94729}}
+
+# Can't think of any good tests for the MergeSort and MergeLists procedures,
+# except a bunch of random lists to sort.
+
+test cmdIL-2.1 {MergeSort and MergeLists procedures} -setup {
+    set result {}
+    set r 1435753299
+    proc rand {} {
+	global r
+	set r [expr {(16807 * $r) % (0x7fffffff)}]
+    }
+} -body {
+    for {set i 0} {$i < 150} {incr i} {
+	set x {}
+	for {set j 0} {$j < $i} {incr j} {
+	    lappend x [expr {[rand] & 0xfff}]
+	}
+	set y [lsort -integer $x]
+	set old -1
+	foreach el $y {
+	    if {$el < $old} {
+		append result "list {$x} sorted to {$y}, element $el out of order\n"
+		break
+	    }
+	    set old $el
+	}
+    }
+    string trim $result
+} -cleanup {
+    rename rand ""
+} -result {}
+
+test cmdIL-3.1 {SortCompare procedure, skip comparisons after error} -body {
+    set ::x 0
+    list [catch {
+	lsort -integer -command {apply {{a b} {
+	    incr ::x
+	    error "error #$::x"
+	}}} {48 6 28 190 16 2 3 6 1}
+    } msg] $msg $::x
+} -result {1 {error #1} 1}
+test cmdIL-3.2 {SortCompare procedure, -index option} -body {
+    lsort -integer -index 2 "\\\{ {30 40 50}"
+} -returnCodes error -result {unmatched open brace in list}
+test cmdIL-3.3 {SortCompare procedure, -index option} -body {
+    lsort -integer -index 2 {{20 10} {15 30 40}}
+} -returnCodes error -result {element 2 missing from sublist "20 10"}
+test cmdIL-3.4 {SortCompare procedure, -index option} -body {
+    lsort -integer -index 2 "{a b c} \\\{"
+} -returnCodes error -result {expected integer but got "c"}
+test cmdIL-3.4.1 {SortCompare procedure, -index option} -body {
+    lsort -integer -index 2 "{1 2 3} \\\{"
+} -returnCodes error -result {unmatched open brace in list}
+test cmdIL-3.5 {SortCompare procedure, -index option} -body {
+    lsort -integer -index 2 {{20 10 13} {15}}
+} -returnCodes error -result {element 2 missing from sublist "15"}
+test cmdIL-3.6 {SortCompare procedure, -index option} {
+    lsort -integer -index 2 {{1 15 30} {2 5 25} {3 25 20}}
+} {{3 25 20} {2 5 25} {1 15 30}}
+test cmdIL-3.7 {SortCompare procedure, -ascii option} {
+    lsort -ascii {d e c b a d35 d300 100 20}
+} {100 20 a b c d d300 d35 e}
+test cmdIL-3.8 {SortCompare procedure, -dictionary option} {
+    lsort -dictionary {d e c b a d35 d300 100 20}
+} {20 100 a b c d d35 d300 e}
+test cmdIL-3.9 {SortCompare procedure, -integer option} -body {
+    lsort -integer {x 3}
+} -returnCodes error -result {expected integer but got "x"}
+test cmdIL-3.10 {SortCompare procedure, -integer option} -body {
+    lsort -integer {3 q}
+} -returnCodes error -result {expected integer but got "q"}
+test cmdIL-3.11 {SortCompare procedure, -integer option} {
+    lsort -integer {35 21 0x20 30 0o23 100 8}
+} {8 0o23 21 30 0x20 35 100}
+test cmdIL-3.12 {SortCompare procedure, -real option} -body {
+    lsort -real {6...4 3}
+} -returnCodes error -result {expected floating-point number but got "6...4"}
+test cmdIL-3.13 {SortCompare procedure, -real option} -body {
+    lsort -real {3 1x7}
+} -returnCodes error -result {expected floating-point number but got "1x7"}
+test cmdIL-3.14 {SortCompare procedure, -real option} {
+    lsort -real {24 2.5e01 16.7 85e-1 10.004}
+} {85e-1 10.004 16.7 24 2.5e01}
+test cmdIL-3.15 {SortCompare procedure, -command option} -body {
+    proc cmp {a b} {
+	error "comparison error"
+    }
+    list [catch {lsort -command cmp {48 6}} msg] $msg $::errorInfo
+} -cleanup {
+    rename cmp ""
+} -result {1 {comparison error} {comparison error
+    while executing
+"error "comparison error""
+    (procedure "cmp" line 2)
+    invoked from within
+"cmp 48 6"
+    (-compare command)
+    invoked from within
+"lsort -command cmp {48 6}"}}
+test cmdIL-3.16 {SortCompare procedure, -command option, long command} -body {
+    proc cmp {dummy a b} {
+	string compare $a $b
+    }
+    lsort -command {cmp {this argument is very very long in order to make the dstring overflow its statically allocated space}} {{this first element is also long in order to help expand the dstring} {the second element, last but not least, is quite long also, in order to make absolutely sure that space is allocated dynamically for the dstring}}
+} -cleanup {
+    rename cmp ""
+} -result {{the second element, last but not least, is quite long also, in order to make absolutely sure that space is allocated dynamically for the dstring} {this first element is also long in order to help expand the dstring}}
+test cmdIL-3.17 {SortCompare procedure, -command option, non-integer result} -body {
+    proc cmp {a b} {
+	return foow
+    }
+    lsort -command cmp {48 6}
+} -returnCodes error -cleanup {
+    rename cmp ""
+} -result {-compare command returned non-integer result}
+test cmdIL-3.18 {SortCompare procedure, -command option} -body {
+    proc cmp {a b} {
+	expr {$b - $a}
+    }
+    lsort -command cmp {48 6 18 22 21 35 36}
+} -cleanup {
+    rename cmp ""
+} -result {48 36 35 22 21 18 6}
+test cmdIL-3.19 {SortCompare procedure, -decreasing option} {
+    lsort -decreasing -integer {35 21 0x20 30 0o23 100 8}
+} {100 35 0x20 30 21 0o23 8}
+
+test cmdIL-4.1 {DictionaryCompare procedure, numerics, leading zeros} {
+    lsort -dictionary {a003b a03b}
+} {a03b a003b}
+test cmdIL-4.2 {DictionaryCompare procedure, numerics, leading zeros} {
+    lsort -dictionary {a3b a03b}
+} {a3b a03b}
+test cmdIL-4.3 {DictionaryCompare procedure, numerics, leading zeros} {
+    lsort -dictionary {a3b A03b}
+} {A03b a3b}
+test cmdIL-4.4 {DictionaryCompare procedure, numerics, leading zeros} {
+    lsort -dictionary {a3b a03B}
+} {a3b a03B}
+test cmdIL-4.5 {DictionaryCompare procedure, numerics, leading zeros} {
+    lsort -dictionary {00000 000}
+} {000 00000}
+test cmdIL-4.6 {DictionaryCompare procedure, numerics, different lengths} {
+    lsort -dictionary {a321b a03210b}
+} {a321b a03210b}
+test cmdIL-4.7 {DictionaryCompare procedure, numerics, different lengths} {
+    lsort -dictionary {a03210b a321b}
+} {a321b a03210b}
+test cmdIL-4.8 {DictionaryCompare procedure, numerics} {
+    lsort -dictionary {48 6a 18b 22a 21aa 35 36}
+} {6a 18b 21aa 22a 35 36 48}
+test cmdIL-4.9 {DictionaryCompare procedure, numerics} {
+    lsort -dictionary {a123x a123b}
+} {a123b a123x}
+test cmdIL-4.10 {DictionaryCompare procedure, numerics} {
+    lsort -dictionary {a123b a123x}
+} {a123b a123x}
+test cmdIL-4.11 {DictionaryCompare procedure, numerics} {
+    lsort -dictionary {a1b aab}
+} {a1b aab}
+test cmdIL-4.12 {DictionaryCompare procedure, numerics} {
+    lsort -dictionary {a1b a!b}
+} {a!b a1b}
+test cmdIL-4.13 {DictionaryCompare procedure, numerics} {
+    lsort -dictionary {a1b2c a1b1c}
+} {a1b1c a1b2c}
+test cmdIL-4.14 {DictionaryCompare procedure, numerics} {
+    lsort -dictionary {a1b2c a1b3c}
+} {a1b2c a1b3c}
+test cmdIL-4.15 {DictionaryCompare procedure, long numbers} {
+    lsort -dictionary {a7654884321988762b a7654884321988761b}
+} {a7654884321988761b a7654884321988762b}
+test cmdIL-4.16 {DictionaryCompare procedure, long numbers} {
+    lsort -dictionary {a8765488432198876b a7654884321988761b}
+} {a7654884321988761b a8765488432198876b}
+test cmdIL-4.17 {DictionaryCompare procedure, case} {
+    lsort -dictionary {aBCd abcc}
+} {abcc aBCd}
+test cmdIL-4.18 {DictionaryCompare procedure, case} {
+    lsort -dictionary {aBCd abce}
+} {aBCd abce}
+test cmdIL-4.19 {DictionaryCompare procedure, case} {
+    lsort -dictionary {abcd ABcc}
+} {ABcc abcd}
+test cmdIL-4.20 {DictionaryCompare procedure, case} {
+    lsort -dictionary {abcd ABce}
+} {abcd ABce}
+test cmdIL-4.21 {DictionaryCompare procedure, case} {
+    lsort -dictionary {abCD ABcd}
+} {ABcd abCD}
+test cmdIL-4.22 {DictionaryCompare procedure, case} {
+    lsort -dictionary {ABcd aBCd}
+} {ABcd aBCd}
+test cmdIL-4.23 {DictionaryCompare procedure, case} {
+    lsort -dictionary {ABcd AbCd}
+} {ABcd AbCd}
+test cmdIL-4.24 {DictionaryCompare procedure, international characters} {hasIsoLocale} {
+    ::tcltest::set_iso8859_1_locale
+    set result [lsort -dictionary "a b c A B C \xe3 \xc4"]
+    ::tcltest::restore_locale
+    set result
+} "A a B b C c \xe3 \xc4"
+test cmdIL-4.25 {DictionaryCompare procedure, international characters} {hasIsoLocale} {
+    ::tcltest::set_iso8859_1_locale
+    set result [lsort -dictionary "a23\xe3 a23\xc5 a23\xe4"]
+    ::tcltest::restore_locale
+    set result
+} "a23\xe3 a23\xe4 a23\xc5"
+test cmdIL-4.26 {DefaultCompare procedure, signed characters} {
+    set l [lsort [list "abc\200" "abc"]]
+    set viewlist {}
+    foreach s $l {
+	set viewelem ""
+	set len [string length $s]
+	for {set i 0} {$i < $len} {incr i} {
+	    set c [string index $s $i]
+	    scan $c %c d
+	    if {$d > 0 && $d < 128} {
+		append viewelem $c
+	    } else {
+		append viewelem "\\[format %03o $d]"
+	    }
+	}
+	lappend viewlist $viewelem
+    }
+    set viewlist
+} [list "abc" "abc\\200"]
+test cmdIL-4.27 {DictionaryCompare procedure, signed characters} {
+    set l [lsort -dictionary [list "abc\200" "abc"]]
+    set viewlist {}
+    foreach s $l {
+	set viewelem ""
+	set len [string length $s]
+	for {set i 0} {$i < $len} {incr i} {
+	    set c [string index $s $i]
+	    scan $c %c d
+	    if {$d > 0 && $d < 128} {
+		append viewelem $c
+	    } else {
+		append viewelem "\\[format %03o $d]"
+	    }
+	}
+	lappend viewlist $viewelem
+    }
+    set viewlist
+} [list "abc" "abc\\200"]
+test cmdIL-4.28 {DictionaryCompare procedure, chars between Z and a in ASCII} {
+    lsort -dictionary [list AA ` c CC]
+} [list ` AA c CC]
+test cmdIL-4.29 {DictionaryCompare procedure, chars between Z and a in ASCII} {
+    lsort -dictionary [list AA ` c ^ \\ CC \[ \]]
+} [list \[ \\ \] ^ ` AA c CC]
+test cmdIL-4.30 {DictionaryCompare procedure, chars between Z and a in ASCII} {
+    lsort -dictionary [list AA ` c ^ _ \\ CC \[ dude \] funky]
+} [list \[ \\ \] ^ _ ` AA c CC dude funky]
+test cmdIL-4.31 {DictionaryCompare procedure, chars between Z and a in ASCII} {
+    lsort -dictionary [list AA c ` CC]
+} [list ` AA c CC]
+test cmdIL-4.32 {DictionaryCompare procedure, chars between Z and a in ASCII} {
+    lsort -dictionary [list AA c CC `]
+} [list ` AA c CC]
+test cmdIL-4.33 {DictionaryCompare procedure, chars between Z and a in ASCII} {
+    lsort -dictionary [list AA ! c CC `]
+} [list ! ` AA c CC]
+test cmdIL-4.34 {SortCompare procedure, -ascii option with -nocase option} {
+    lsort -ascii -nocase {d e c b a d35 d300 100 20}
+} {100 20 a b c d d300 d35 e}
+test cmdIL-4.35 {SortCompare procedure, -ascii option with -nocase option} {
+    lsort -ascii -nocase {d E c B a D35 d300 100 20}
+} {100 20 a B c d d300 D35 E}
+test cmdIL-4.36 {SortCompare procedure, UTF-8 with -nocase option} {
+    scan [lsort -ascii -nocase [list \u101 \u100]] %c%c%c
+} {257 32 256}
+test cmdIL-4.37 {SortCompare procedure, UTF-8 with -nocase option} {
+    scan [lsort -ascii -nocase [list a\u0000a a]] %c%c%c%c%c
+} {97 32 97 0 97}
+test cmdIL-4.38 {SortCompare procedure, UTF-8 with -nocase option} {
+    scan [lsort -ascii -nocase [list a a\u0000a]] %c%c%c%c%c
+} {97 32 97 0 97}
+
+test cmdIL-5.1 {lsort with list style index} {
+    lsort -ascii -decreasing -index {0 1} {
+	{{Jim Alpha} 20000410}
+	{{Joe Bravo} 19990320}
+	{{Jacky Charlie} 19390911}
+    }
+} {{{Jacky Charlie} 19390911} {{Joe Bravo} 19990320} {{Jim Alpha} 20000410}}
+test cmdIL-5.2 {lsort with list style index} {
+    lsort -decreasing -index {0 1} {
+	{{Jim Alpha} 20000410}
+	{{Joe Bravo} 19990320}
+	{{Jacky Charlie} 19390911}
+    }
+} {{{Jacky Charlie} 19390911} {{Joe Bravo} 19990320} {{Jim Alpha} 20000410}}
+test cmdIL-5.3 {lsort with list style index} {
+    lsort -integer -increasing -index {1 end} {
+	{{Jim Alpha} 20000410}
+	{{Joe Bravo} 19990320}
+	{{Jacky Charlie} 19390911}
+    }
+} {{{Jacky Charlie} 19390911} {{Joe Bravo} 19990320} {{Jim Alpha} 20000410}}
+test cmdIL-5.4 {lsort with list style index} {
+    lsort -integer -index {1 end-1} {
+	{the {0 1 2 3 4 5} quick}
+	{brown {0 1 2 3 4} fox}
+	{jumps {30 31 2 33} over}
+	{the {0 1 2} lazy}
+	{dogs {0 1}}
+    }
+} {{dogs {0 1}} {the {0 1 2} lazy} {jumps {30 31 2 33} over} {brown {0 1 2 3 4} fox} {the {0 1 2 3 4 5} quick}}
+test cmdIL-5.5 {lsort with list style index and sharing} -body {
+    proc test_lsort {l} {
+	set n $l
+	foreach e $l {lappend n [list [expr {rand()}] $e]}
+	lindex [lsort -real -index $l $n] 1 1
+    }
+    expr srand(1)
+    test_lsort 0
+} -result 0 -cleanup {
+    rename test_lsort ""
+}
+test cmdIL-5.6 {lsort with multiple list-style index options} {
+    lsort -index {1 2 3} -index 0 {{a b} {c d} {b e}}
+} {{a b} {b e} {c d}}
+
+# Compiled version
+test cmdIL-6.1 {lassign command syntax} -returnCodes error -body {
+    apply {{} { lassign }}
+} -result {wrong # args: should be "lassign list ?varName ...?"}
+test cmdIL-6.2 {lassign command syntax} {
+    apply {{} { lassign x }}
+} x
+test cmdIL-6.3 {lassign command} -body {
+    apply {{} {
+	set x FAIL
+	list [lassign a x] $x
+    }}
+} -result {{} a}
+test cmdIL-6.4 {lassign command} -body {
+    apply {{} {
+	set x FAIL
+	set y FAIL
+	list [lassign a x y] $x $y
+    }}
+} -result {{} a {}}
+test cmdIL-6.5 {lassign command} -body {
+    apply {{} {
+	set x FAIL
+	set y FAIL
+	list [lassign {a b} x y] $x $y
+    }}
+} -result {{} a b}
+test cmdIL-6.6 {lassign command} -body {
+    apply {{} {
+	set x FAIL
+	set y FAIL
+	list [lassign {a b c} x y] $x $y
+    }}
+} -result {c a b}
+test cmdIL-6.7 {lassign command} -body {
+    apply {{} {
+	set x FAIL
+	set y FAIL
+	list [lassign {a b c d} x y] $x $y
+    }}
+} -result {{c d} a b}
+test cmdIL-6.8 {lassign command - list format error} -body {
+    apply {{} {
+	set x FAIL
+	set y FAIL
+	list [catch {lassign {a {b}c d} x y} msg] $msg $x $y
+    }}
+} -result {1 {list element in braces followed by "c" instead of space} FAIL FAIL}
+test cmdIL-6.9 {lassign command - assignment to arrays} -body {
+    apply {{} {
+	list [lassign {a b} x(x)] $x(x)
+    }}
+} -result {b a}
+test cmdIL-6.10 {lassign command - variable update error} -body {
+    apply {{} {
+	set x(x) {}
+	lassign a x
+    }}
+} -returnCodes error -result {can't set "x": variable is array}
+test cmdIL-6.11 {lassign command - variable update error} -body {
+    apply {{} {
+	set x(x) {}
+	set y FAIL
+	list [catch {lassign a y x} msg] $msg $y
+    }}
+} -result {1 {can't set "x": variable is array} a}
+test cmdIL-6.12 {lassign command - memory leak testing} -setup {
+    unset -nocomplain x y
+    set x(x) {}
+    set y FAIL
+    proc getbytes {} {
+        set lines [split [memory info] "\n"]
+        lindex [lindex $lines 3] 3
+    }
+    proc stress {} {
+	global x y
+	lassign {} y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y
+	catch {lassign {} y y y y y y y y y y y y y y y y y y y y y y y y y x}
+	catch {lassign {} x}
+    }
+} -constraints memory -body {
+    set end [getbytes]
+    for {set i 0} {$i < 5} {incr i} {
+	stress
+	set tmp $end
+	set end [getbytes]
+    }
+    expr {$end - $tmp}
+} -result 0 -cleanup {
+    unset -nocomplain x y i tmp end
+    rename getbytes {}
+    rename stress {}
+}
+# Force non-compiled version
+test cmdIL-6.13 {lassign command syntax} -returnCodes error -body {
+    apply {{} {
+	set lassign lassign
+	$lassign
+    }}
+} -result {wrong # args: should be "lassign list ?varName ...?"}
+test cmdIL-6.14 {lassign command syntax} {
+    apply {{} {
+	set lassign lassign
+	$lassign x
+    }}
+} x
+test cmdIL-6.15 {lassign command} -body {
+    apply {{} {
+	set lassign lassign
+	set x FAIL
+	list [$lassign a x] $x
+    }}
+} -result {{} a}
+test cmdIL-6.16 {lassign command} -body {
+    apply {{} {
+	set lassign lassign
+	set x FAIL
+	set y FAIL
+	list [$lassign a x y] $x $y
+    }}
+} -result {{} a {}}
+test cmdIL-6.17 {lassign command} -body {
+    apply {{} {
+	set lassign lassign
+	set x FAIL
+	set y FAIL
+	list [$lassign {a b} x y] $x $y
+    }}
+} -result {{} a b}
+test cmdIL-6.18 {lassign command} -body {
+    apply {{} {
+	set lassign lassign
+	set x FAIL
+	set y FAIL
+	list [$lassign {a b c} x y] $x $y
+    }}
+} -result {c a b}
+test cmdIL-6.19 {lassign command} -body {
+    apply {{} {
+	set lassign lassign
+	set x FAIL
+	set y FAIL
+	list [$lassign {a b c d} x y] $x $y
+    }}
+} -result {{c d} a b}
+test cmdIL-6.20 {lassign command - list format error} -body {
+    apply {{} {
+	set lassign lassign
+	set x FAIL
+	set y FAIL
+	list [catch {$lassign {a {b}c d} x y} msg] $msg $x $y
+    }}
+} -result {1 {list element in braces followed by "c" instead of space} FAIL FAIL}
+test cmdIL-6.21 {lassign command - assignment to arrays} -body {
+    apply {{} {
+	set lassign lassign
+	list [$lassign {a b} x(x)] $x(x)
+    }}
+} -result {b a}
+test cmdIL-6.22 {lassign command - variable update error} -body {
+    apply {{} {
+	set lassign lassign
+	set x(x) {}
+	$lassign a x
+    }}
+} -returnCodes 1 -result {can't set "x": variable is array}
+test cmdIL-6.23 {lassign command - variable update error} -body {
+    apply {{} {
+	set lassign lassign
+	set x(x) {}
+	set y FAIL
+	list [catch {$lassign a y x} msg] $msg $y
+    }}
+} -result {1 {can't set "x": variable is array} a}
+test cmdIL-6.24 {lassign command - memory leak testing} -setup {
+    set x(x) {}
+    set y FAIL
+    proc getbytes {} {
+        set lines [split [memory info] "\n"]
+        lindex [lindex $lines 3] 3
+    }
+    proc stress {} {
+	global x y
+	set lassign lassign
+	$lassign {} y y y y y y y y y y y y y y y y y y y y y y y y y y y y y y
+	catch {$lassign {} y y y y y y y y y y y y y y y y y y y y y y y y y x}
+	catch {$lassign {} x}
+    }
+} -constraints memory -body {
+    set end [getbytes]
+    for {set i 0} {$i < 5} {incr i} {
+	stress
+	set tmp $end
+	set end [getbytes]
+    }
+    expr {$end - $tmp}
+} -result 0 -cleanup {
+    unset -nocomplain x y i tmp end
+    rename getbytes {}
+    rename stress {}
+}
+# Assorted shimmering problems
+test cmdIL-6.25 {lassign command - shimmering protection} -body {
+    apply {{} {
+	set x {a b c}
+	list [lassign $x $x y] $x [set $x] $y
+    }}
+} -result {c {a b c} a b}
+test cmdIL-6.26 {lassign command - shimmering protection} -body {
+    apply {{} {
+	set x {a b c}
+	set lassign lassign
+	list [$lassign $x $x y] $x [set $x] $y
+    }}
+} -result {c {a b c} a b}
+
+test cmdIL-7.1 {lreverse command} -body {
+    lreverse
+} -returnCodes error -result "wrong # args: should be \"lreverse list\""
+test cmdIL-7.2 {lreverse command} -body {
+    lreverse a b
+} -returnCodes error -result "wrong # args: should be \"lreverse list\""
+test cmdIL-7.3 {lreverse command} -body {
+    lreverse "not \{a list"
+} -returnCodes error -result {unmatched open brace in list}
+test cmdIL-7.4 {lreverse command - shared object} {
+    set x {a b {c d} e f}
+    lreverse $x
+} {f e {c d} b a}
+test cmdIL-7.5 {lreverse command - unshared object} {
+    lreverse [list a b {c d} e f]
+} {f e {c d} b a}
+test cmdIL-7.6 {lreverse command - unshared object [Bug 1672585]} {
+    lreverse [set x {1 2 3}][unset x]
+} {3 2 1}
+test cmdIL-7.7 {lreverse command - empty object [Bug 1876793]} {
+    lreverse [list]
+} {}
+test cmdIL-7.8 {lreverse command - shared intrep [Bug 1675044]} -setup {
+    teststringobj set 1 {1 2 3}
+    testobj convert 1 list
+    testobj duplicate 1 2
+    variable x [teststringobj get 1]
+    variable y [teststringobj get 2]
+    testobj freeallvars
+    proc K {a b} {return $a}
+} -constraints testobj -body {
+    lreverse [K $y [unset y]]
+    lindex $x 0
+} -cleanup {
+    unset -nocomplain x y
+    rename K {}
+} -result 1
+
+# This belongs in info test, but adding tests there breaks tests
+# that compute source file line numbers.
+test info-20.6 {Bug 3587651} -setup {
+    namespace eval my {namespace eval tcl {namespace eval mathfunc {
+        proc demo x {return 42}
+    }}}} -body {    namespace eval my {expr {"demo" in [info functions]}}} -cleanup {
+    namespace delete my
+} -result 1
+
+
+# cleanup
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/tests/cmdInfo.test b/tests/cmdInfo.test
new file mode 100644
index 0000000..0a587e8
--- /dev/null
+++ b/tests/cmdInfo.test
@@ -0,0 +1,107 @@
+# Commands covered:  none
+#
+# This file contains a collection of tests for Tcl_GetCommandInfo,
+# Tcl_SetCommandInfo, Tcl_CreateCommand, Tcl_DeleteCommand, and
+# Tcl_NameOfCommand.  Sourcing this file into Tcl runs the tests
+# and generates output for errors.  No output means no errors were
+# found.
+#
+# Copyright (c) 1993 The Regents of the University of California.
+# Copyright (c) 1994-1996 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+package require tcltest 2
+namespace import ::tcltest::*
+
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
+
+testConstraint testcmdinfo  [llength [info commands testcmdinfo]]
+testConstraint testcmdtoken [llength [info commands testcmdtoken]]
+
+test cmdinfo-1.1 {command procedure and clientData} {testcmdinfo} {
+    testcmdinfo create x1
+    testcmdinfo get x1
+} {CmdProc1 original CmdDelProc1 original :: stringProc}
+test cmdinfo-1.2 {command procedure and clientData} {testcmdinfo} {
+    testcmdinfo create x1
+    x1
+} {CmdProc1 original}
+test cmdinfo-1.3 {command procedure and clientData} {testcmdinfo} {
+    testcmdinfo create x1
+    testcmdinfo modify x1
+    testcmdinfo get x1
+} {CmdProc2 new_command_data CmdDelProc2 new_delete_data :: stringProc}
+test cmdinfo-1.4 {command procedure and clientData} {testcmdinfo} {
+    testcmdinfo create x1
+    testcmdinfo modify x1
+    x1
+} {CmdProc2 new_command_data}
+
+test cmdinfo-2.1 {command deletion callbacks} {testcmdinfo} {
+    testcmdinfo create x1
+    testcmdinfo delete x1
+} {CmdDelProc1 original}
+test cmdinfo-2.2 {command deletion callbacks} {testcmdinfo} {
+    testcmdinfo create x1
+    testcmdinfo modify x1
+    testcmdinfo delete x1
+} {CmdDelProc2 new_delete_data}
+
+test cmdinfo-3.1 {Tcl_Get/SetCommandInfo return values} {testcmdinfo} {
+    testcmdinfo get non_existent
+} {??}
+test cmdinfo-3.2 {Tcl_Get/SetCommandInfo return values} {testcmdinfo} {
+    testcmdinfo create x1
+    testcmdinfo modify x1
+} 1
+test cmdinfo-3.3 {Tcl_Get/SetCommandInfo return values} {testcmdinfo} {
+    testcmdinfo modify non_existent
+} 0
+
+test cmdinfo-4.1 {Tcl_GetCommandName/Tcl_GetCommandFullName procedures} \
+	{testcmdtoken} {
+    set x [testcmdtoken create x1]
+    rename x1 newName
+    set y [testcmdtoken name $x]
+    rename newName x1
+    lappend y {*}[testcmdtoken name $x]
+} {newName ::newName x1 ::x1}
+
+catch {rename newTestCmd {}}
+catch {rename newTestCmd2 {}}
+
+test cmdinfo-5.1 {Names for commands created when inside namespaces} \
+	{testcmdtoken} {
+    # create namespace cmdInfoNs1
+    namespace eval cmdInfoNs1 {}   ;# creates namespace cmdInfoNs1
+    # create namespace cmdInfoNs1::cmdInfoNs2 and execute a script in it
+    set x [namespace eval cmdInfoNs1::cmdInfoNs2 {
+        # the following creates a cmd in the global namespace
+        testcmdtoken create testCmd
+    }]
+    set y [testcmdtoken name $x]
+    rename ::testCmd newTestCmd
+    lappend y {*}[testcmdtoken name $x]
+} {testCmd ::testCmd newTestCmd ::newTestCmd}
+
+test cmdinfo-6.1 {Names for commands created when outside namespaces} \
+	{testcmdtoken} {
+    set x [testcmdtoken create cmdInfoNs1::cmdInfoNs2::testCmd]
+    set y [testcmdtoken name $x]
+    rename cmdInfoNs1::cmdInfoNs2::testCmd newTestCmd2
+    lappend y {*}[testcmdtoken name $x]
+} {testCmd ::cmdInfoNs1::cmdInfoNs2::testCmd newTestCmd2 ::newTestCmd2}
+
+# cleanup
+catch {namespace delete cmdInfoNs1::cmdInfoNs2 cmdInfoNs1}
+catch {rename x1 ""}
+cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/tests/cmdMZ.test b/tests/cmdMZ.test
new file mode 100644
index 0000000..2d68138
--- /dev/null
+++ b/tests/cmdMZ.test
@@ -0,0 +1,355 @@
+# The tests in this file cover the procedures in tclCmdMZ.c.
+#
+# This file contains a collection of tests for one or more of the Tcl built-in
+# commands. Sourcing this file into Tcl runs the tests and generates output
+# for errors. No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution of
+# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[catch {package require tcltest 2.1}]} {
+    puts stderr "Skipping tests in [info script]. tcltest 2.1 required."
+    return
+}
+
+namespace eval ::tcl::test::cmdMZ {
+    namespace import ::tcltest::cleanupTests
+    namespace import ::tcltest::customMatch
+    namespace import ::tcltest::makeFile
+    namespace import ::tcltest::removeFile
+    namespace import ::tcltest::temporaryDirectory
+    namespace import ::tcltest::test
+
+    proc ListGlobMatch {expected actual} {
+	if {[llength $expected] != [llength $actual]} {
+	    return 0
+	}
+	foreach e $expected a $actual {
+	    if {![string match $e $a]} {
+		return 0
+	    }
+	}
+	return 1
+    }
+    customMatch listGlob [namespace which ListGlobMatch]
+
+# Tcl_PwdObjCmd
+
+test cmdMZ-1.1 {Tcl_PwdObjCmd} -returnCodes error -body {
+    pwd a
+} -result {wrong # args: should be "pwd"}
+test cmdMZ-1.2 {Tcl_PwdObjCmd: simple pwd} {
+    catch pwd
+} 0
+test cmdMZ-1.3 {Tcl_PwdObjCmd: simple pwd} -body {
+    pwd
+} -match glob -result {?*}
+test cmdMZ-1.4 {Tcl_PwdObjCmd: failure} -setup {
+    set cwd [pwd]
+    set foodir [file join [temporaryDirectory] foo]
+    file delete -force $foodir
+    file mkdir $foodir
+    cd $foodir
+} -constraints {unix nonPortable} -body {
+    # This test fails on various unix platforms (eg Linux) where permissions
+    # caching causes this to fail. The caching is strictly incorrect, but we
+    # have no control over that.
+    file attr . -permissions 000
+    pwd
+} -returnCodes error -cleanup {
+    cd $cwd
+    file delete -force $foodir
+} -result {error getting working directory name: permission denied}
+
+# The tests for Tcl_RegexpObjCmd, Tcl_RegsubObjCmd are in regexp.test
+
+# Tcl_RenameObjCmd
+
+test cmdMZ-2.1 {Tcl_RenameObjCmd: error conditions} -returnCodes error -body {
+    rename r1
+} -result {wrong # args: should be "rename oldName newName"}
+test cmdMZ-2.2 {Tcl_RenameObjCmd: error conditions} -returnCodes error -body {
+    rename r1 r2 r3
+} -result {wrong # args: should be "rename oldName newName"}
+test cmdMZ-2.3 {Tcl_RenameObjCmd: success} -setup {
+    catch {rename r2 {}}
+} -body {
+    proc r1 {} {return "r1"}
+    rename r1 r2
+    r2
+} -result {r1}
+test cmdMZ-2.4 {Tcl_RenameObjCmd: success} {
+    proc r1 {} {return "r1"}
+    rename r1 {}
+    list [catch {r1} msg] $msg
+} {1 {invalid command name "r1"}}
+
+# Some tests for Tcl_ReturnObjCmd are in proc-old.test
+
+test cmdMZ-return-1.0 {return checks for bad option values} -body {
+    return -options foo
+} -returnCodes error -match glob -result {bad -options value:*}
+test cmdMZ-return-1.1 {return checks for bad option values} -body {
+    return -code err
+} -returnCodes error -match glob -result {bad completion code "err": must be ok, error, return, break, continue*, or an integer}
+test cmdMZ-return-1.2 {return checks for bad option values} -body {
+    return -code 0x100000000
+} -returnCodes error -match glob -result {bad completion code "0x100000000": must be ok, error, return, break, continue*, or an integer}
+test cmdMZ-return-1.3 {return checks for bad option values} -body {
+    return -level foo
+} -returnCodes error -match glob -result {bad -level value: *}
+test cmdMZ-return-1.4 {return checks for bad option values} -body {
+    return -level -1
+} -returnCodes error -match glob -result {bad -level value: *}
+test cmdMZ-return-1.5 {return checks for bad option values} -body {
+    return -level 3.1415926
+} -returnCodes error -match glob -result {bad -level value: *}
+
+proc dictSort {d} {
+    set result {}
+    foreach k [lsort [dict keys $d]] {
+	dict set result $k [dict get $d $k]
+    }
+    return $result
+}
+
+test cmdMZ-return-2.0 {return option handling} {
+    list [catch return -> foo] [dictSort $foo]
+} {2 {-code 0 -level 1}}
+test cmdMZ-return-2.1 {return option handling} {
+    list [catch {return -bar soom} -> foo] [dictSort $foo]
+} {2 {-bar soom -code 0 -level 1}}
+test cmdMZ-return-2.2 {return option handling} {
+    list [catch {return -code return} -> foo] [dictSort $foo]
+} {2 {-code 0 -level 2}}
+test cmdMZ-return-2.3 {return option handling} {
+    list [catch {return -code return -level 10} -> foo] [dictSort $foo]
+} {2 {-code 0 -level 11}}
+test cmdMZ-return-2.4 {return option handling} -body {
+    return -level 0 -code error
+} -returnCodes error -result {}
+test cmdMZ-return-2.5 {return option handling} -body {
+    return -level 0 -code return
+} -returnCodes return -result {}
+test cmdMZ-return-2.6 {return option handling} -body {
+    return -level 0 -code break
+} -returnCodes break -result {}
+test cmdMZ-return-2.7 {return option handling} -body {
+    return -level 0 -code continue
+} -returnCodes continue -result {}
+test cmdMZ-return-2.8 {return option handling} -body {
+    return -level 0 -code -1
+} -returnCodes -1 -result {}
+test cmdMZ-return-2.9 {return option handling} -body {
+    return -level 0 -code 10
+} -returnCodes 10 -result {}
+test cmdMZ-return-2.10 {return option handling} -body {
+    list [catch {return -level 0 -code error} -> foo] [dictSort $foo]
+} -match glob -result {1 {-code 1 -errorcode NONE -errorinfo {
+    while executing
+"return -level 0 -code error"} -errorline 1 -errorstack * -level 0}}
+test cmdMZ-return-2.11 {return option handling} {
+    list [catch {return -level 0 -code break} -> foo] [dictSort $foo]
+} {3 {-code 3 -level 0}}
+test cmdMZ-return-2.12 {return option handling} -body {
+    return -level 0 -code error -options {-code ok}
+} -returnCodes ok -result {}
+test cmdMZ-return-2.13 {return option handling} -body {
+    return -level 0 -code error -options {-code err}
+} -returnCodes error -match glob -result {bad completion code "err": must be ok, error, return, break, continue*, or an integer}
+test cmdMZ-return-2.14 {return option handling} -body {
+    return -level 0 -code error -options {-code foo -options {-code break}}
+} -returnCodes break -result {}
+test cmdMZ-return-2.15 {return opton handling} {
+    list [catch {
+	apply {{} {
+	    return -code error -errorcode {a b} c
+	}}
+    } result] $result $::errorCode
+} {1 c {a b}}
+test cmdMZ-return-2.16 {return opton handling} {
+    list [catch {
+	apply {{} {
+	    return -code error -errorcode [list a b] c
+	}}
+    } result] $result $::errorCode
+} {1 c {a b}}
+test cmdMZ-return-2.17 {return opton handling} {
+    list [catch {
+	apply {{} {
+	    return -code error -errorcode a\ b c
+	}}
+    } result] $result $::errorCode
+} {1 c {a b}}
+test cmdMZ-return-2.18 {return option handling} {
+    list [catch {
+	return -code error -errorstack [list CALL a CALL b] yo
+    } -> foo] [dictSort $foo] [info errorstack]
+} {2 {-code 1 -errorcode NONE -errorstack {CALL a CALL b} -level 1} {CALL a CALL b}}
+
+# Check that the result of a [return -options $opts $result] is
+# indistinguishable from that of the originally caught script, no matter what
+# the script is/does. (TIP 90)
+foreach {testid script} {
+    cmdMZ-return-3.0 {}
+    cmdMZ-return-3.1 {format x}
+    cmdMZ-return-3.2 {set}
+    cmdMZ-return-3.3 {set a 1}
+    cmdMZ-return-3.4 {error}
+    cmdMZ-return-3.5 {error foo}
+    cmdMZ-return-3.6 {error foo bar}
+    cmdMZ-return-3.7 {error foo bar baz}
+    cmdMZ-return-3.8 {return -level 0}
+    cmdMZ-return-3.9 {return -code error}
+    cmdMZ-return-3.10 {return -code error -errorinfo foo}
+    cmdMZ-return-3.11 {return -code error -errorinfo foo -errorcode bar}
+    cmdMZ-return-3.12 {return -code error -errorinfo foo -errorcode bar -errorline 10}
+    cmdMZ-return-3.12.1 {return -code error -errorinfo foo -errorcode bar -errorline 10 -errorstack baz}
+    cmdMZ-return-3.13 {return -options {x y z 2}}
+    cmdMZ-return-3.14 {return -level 3 -code break sdf}
+} {
+    test $testid "check that return after a catch is same:\n$script" {
+	set one [list [catch $script foo bar] $foo [dictSort $bar] \
+		$::errorCode $::errorInfo]
+	set two [list [catch {return -options $bar $foo} foo2 bar2] \
+		$foo2 [dictSort $bar2] $::errorCode $::errorInfo]
+	string equal $one $two
+    } 1
+}
+
+# The tests for Tcl_ScanObjCmd are in scan.test
+
+# Tcl_SourceObjCmd
+# More tests of Tcl_SourceObjCmd are in source.test
+
+test cmdMZ-3.3 {Tcl_SourceObjCmd: error conditions} -constraints {
+    unixOrPc
+} -returnCodes error -body {
+    source
+} -match glob -result {wrong # args: should be "source*fileName"}
+test cmdMZ-3.4 {Tcl_SourceObjCmd: error conditions} -constraints {
+    unixOrPc
+} -returnCodes error -body {
+    source a b
+} -match glob -result {wrong # args: should be "source*fileName"}
+test cmdMZ-3.5 {Tcl_SourceObjCmd: error in script} -body {
+    set file [makeFile {
+	set x 146
+	error "error in sourced file"
+	set y $x
+    } source.file]
+    list [catch {source $file} msg] $msg $::errorInfo
+} -cleanup {
+    removeFile source.file
+} -match listGlob -result {1 {error in sourced file} {error in sourced file
+    while executing
+"error "error in sourced file""
+    (file "*" line 3)
+    invoked from within
+"source $file"}}
+test cmdMZ-3.6 {Tcl_SourceObjCmd: simple script} -body {
+    set file [makeFile {list ok} source.file]
+    source $file
+} -cleanup {
+    removeFile source.file
+} -result ok
+
+# Tcl_SplitObjCmd
+
+test cmdMZ-4.1 {Tcl_SplitObjCmd: split errors} -returnCodes error -body {
+    split
+} -result {wrong # args: should be "split string ?splitChars?"}
+test cmdMZ-4.2 {Tcl_SplitObjCmd: split errors} -returnCodes error -body {
+    split a b c
+} -result {wrong # args: should be "split string ?splitChars?"}
+test cmdMZ-4.3 {Tcl_SplitObjCmd: basic split commands} {
+    split "a\n b\t\r c\n "
+} {a {} b {} {} c {} {}}
+test cmdMZ-4.4 {Tcl_SplitObjCmd: basic split commands} {
+    split "word 1xyzword 2zword 3" xyz
+} {{word 1} {} {} {word 2} {word 3}}
+test cmdMZ-4.5 {Tcl_SplitObjCmd: basic split commands} {
+    split "12345" {}
+} {1 2 3 4 5}
+test cmdMZ-4.6 {Tcl_SplitObjCmd: basic split commands} {
+    split "a\}b\[c\{\]\$"
+} "a\\\}b\\\[c\\\{\\\]\\\$"
+test cmdMZ-4.7 {Tcl_SplitObjCmd: basic split commands} {
+    split {} {}
+} {}
+test cmdMZ-4.8 {Tcl_SplitObjCmd: basic split commands} {
+    split {}
+} {}
+test cmdMZ-4.9 {Tcl_SplitObjCmd: basic split commands} {
+    split {   }
+} {{} {} {} {}}
+test cmdMZ-4.10 {Tcl_SplitObjCmd: basic split commands} {
+    apply {{} {
+        set x {}
+        foreach f [split {]\n} {}] {
+            append x $f
+        }
+        return $x
+    }}
+} {]\n}
+test cmdMZ-4.11 {Tcl_SplitObjCmd: basic split commands} {
+    apply {{} {
+        set x ab\000c
+        set y [split $x {}]
+	binary scan $y c* z
+        return $z
+    }}
+} {97 32 98 32 0 32 99}
+test cmdMZ-4.12 {Tcl_SplitObjCmd: basic split commands} {
+    split "a0ab1b2bbb3\000c4" ab\000c
+} {{} 0 {} 1 2 {} {} 3 {} 4}
+test cmdMZ-4.13 {Tcl_SplitObjCmd: basic split commands} {
+    # if not UTF-8 aware, result is "a {} {} b qw\xe5 {} N wq"
+    split "a\u4e4eb qw\u5e4e\x4e wq" " \u4e4e"
+} "a b qw\u5e4eN wq"
+
+# The tests for Tcl_StringObjCmd are in string.test
+# The tests for Tcl_SubstObjCmd are in subst.test
+# The tests for Tcl_SwitchObjCmd are in switch.test
+
+test cmdMZ-5.1 {Tcl_TimeObjCmd: basic format of command} -body {
+    time
+} -returnCodes error -result {wrong # args: should be "time command ?count?"}
+test cmdMZ-5.2 {Tcl_TimeObjCmd: basic format of command} -body {
+    time a b c
+} -returnCodes error -result {wrong # args: should be "time command ?count?"}
+test cmdMZ-5.3 {Tcl_TimeObjCmd: basic format of command} -body {
+    time a b
+} -returnCodes error -result {expected integer but got "b"}
+test cmdMZ-5.4 {Tcl_TimeObjCmd: nothing happens with negative iteration counts} {
+    time bogusCmd -12456
+} {0 microseconds per iteration}
+test cmdMZ-5.5 {Tcl_TimeObjCmd: result format} -body {
+    time {format 1}
+} -match regexp -result {^\d+ microseconds per iteration}
+test cmdMZ-5.6 {Tcl_TimeObjCmd: slower commands take longer} {
+    expr {[lindex [time {after 2}] 0] < [lindex [time {after 1000}] 0]}
+} 1
+test cmdMZ-5.7 {Tcl_TimeObjCmd: errors generate right trace} {
+    list [catch {time {error foo}} msg] $msg $::errorInfo
+} {1 foo {foo
+    while executing
+"error foo"
+    invoked from within
+"time {error foo}"}}
+
+# The tests for Tcl_WhileObjCmd are in while.test
+
+# cleanup
+cleanupTests
+}
+namespace delete ::tcl::test::cmdMZ
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/tests/compExpr-old.test b/tests/compExpr-old.test
new file mode 100644
index 0000000..bae26a0
--- /dev/null
+++ b/tests/compExpr-old.test
@@ -0,0 +1,677 @@
+# Commands covered: expr
+#
+# This file contains the original set of tests for the compilation (and
+# indirectly execution) of Tcl's expr command. A new set of tests covering
+# the new implementation are in the files "parseExpr.test" and
+# "compExpr.test". Sourcing this file into Tcl runs the tests and generates
+# output for errors. No output means no errors were found.
+#
+# Copyright (c) 1996-1997 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+    package require tcltest 2
+    namespace import -force ::tcltest::*
+}
+
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
+
+if {[catch {expr T1()} msg] && $msg eq {invalid command name "tcl::mathfunc::T1"}} {
+    testConstraint testmathfunctions 0
+} else {
+    testConstraint testmathfunctions 1
+}
+
+# Big test for correct ordering of data in [expr]
+
+proc testIEEE {} {
+    variable ieeeValues
+    binary scan [binary format dd -1.0 1.0] c* c
+    switch -exact -- $c {
+	{0 0 0 0 0 0 -16 -65 0 0 0 0 0 0 -16 63} {
+	    # little endian
+	    binary scan \x00\x00\x00\x00\x00\x00\xf0\xff d \
+		ieeeValues(-Infinity)
+	    binary scan \x00\x00\x00\x00\x00\x00\xf0\xbf d \
+		ieeeValues(-Normal)
+	    binary scan \x00\x00\x00\x00\x00\x00\x08\x80 d \
+		ieeeValues(-Subnormal)
+	    binary scan \x00\x00\x00\x00\x00\x00\x00\x80 d \
+		ieeeValues(-0)
+	    binary scan \x00\x00\x00\x00\x00\x00\x00\x00 d \
+		ieeeValues(+0)
+	    binary scan \x00\x00\x00\x00\x00\x00\x08\x00 d \
+		ieeeValues(+Subnormal)
+	    binary scan \x00\x00\x00\x00\x00\x00\xf0\x3f d \
+		ieeeValues(+Normal)
+	    binary scan \x00\x00\x00\x00\x00\x00\xf0\x7f d \
+		ieeeValues(+Infinity)
+	    binary scan \x00\x00\x00\x00\x00\x00\xf8\x7f d \
+		ieeeValues(NaN)
+	    set ieeeValues(littleEndian) 1
+	    return 1
+	}
+	{-65 -16 0 0 0 0 0 0 63 -16 0 0 0 0 0 0} {
+	    binary scan \xff\xf0\x00\x00\x00\x00\x00\x00 d \
+		ieeeValues(-Infinity)
+	    binary scan \xbf\xf0\x00\x00\x00\x00\x00\x00 d \
+		ieeeValues(-Normal)
+	    binary scan \x80\x08\x00\x00\x00\x00\x00\x00 d \
+		ieeeValues(-Subnormal)
+	    binary scan \x80\x00\x00\x00\x00\x00\x00\x00 d \
+		ieeeValues(-0)
+	    binary scan \x00\x00\x00\x00\x00\x00\x00\x00 d \
+		ieeeValues(+0)
+	    binary scan \x00\x08\x00\x00\x00\x00\x00\x00 d \
+		ieeeValues(+Subnormal)
+	    binary scan \x3f\xf0\x00\x00\x00\x00\x00\x00 d \
+		ieeeValues(+Normal)
+	    binary scan \x7f\xf0\x00\x00\x00\x00\x00\x00 d \
+		ieeeValues(+Infinity)
+	    binary scan \x7f\xf8\x00\x00\x00\x00\x00\x00 d \
+		ieeeValues(NaN)
+	    set ieeeValues(littleEndian) 0
+	    return 1
+	}
+	default {
+	    return 0
+	}
+    }
+}
+testConstraint ieeeFloatingPoint [testIEEE]
+
+testConstraint longIs32bit [expr {int(0x80000000) < 0}]
+testConstraint longIs64bit [expr {int(0x8000000000000000) < 0}]
+
+# procedures used below
+
+proc put_hello_char {c} {
+    global a
+    append a [format %c $c]
+    return $c
+}
+proc hello_world {} {
+    global a
+    set a ""
+    set L1 [set l0 [set h_1 [set q 0]]]
+    for {put_hello_char [expr [put_hello_char [expr [set h 7]*10+2]]+29]} {$l0?[put_hello_char $l0]
+        :!$h_1} {put_hello_char $ll;expr {$L1==2?[set ll [expr 32+0-0+[set bar 0]]]:0}} {expr {[incr L1]==[expr 1+([string length "abc"]-[string length "abc"])]
+        ?[set ll [set l0 [expr 54<<1]]]:$ll==108&&$L1<3?
+        [incr ll [expr 1|1<<1]; set ll $ll; set ll $ll; set ll $ll; set ll $ll; set l0 [expr ([string length "abc"]-[string length "abc"])+([string length "abc"]-[string length "abc"])-([string length "abc"]-[string length "abc"])+([string length "abc"]-[string length "abc"])]; set l0; set l0 $l0; set l0; set l0]:$L1==4&&$ll==32?[set ll [expr 19+$h1+([string length "abc"]-[string length "abc"])-([string length "abc"]-[string length "abc"])+([string length "abc"]-[string length "abc"])-([string length "abc"]-[string length "abc"])+[set foo [expr ([string length "abc"]-[string length "abc"])+([string length "abc"]-[string length "abc"])+([string length "abc"]-[string length "abc"])]]]]
+        :[set q [expr $q-$h1+([string length "abc"]-[string length "abc"])-([string length "abc"]-[string length "abc"])]]};expr {$L1==5?[incr ll -8; set ll $ll; set ll]:$q&&$h1&&1};expr {$L1==4+2
+        ?[incr ll 3]:[expr ([string length "abc"]-[string length "abc"])+1]};expr {$ll==($h<<4)+2+0&&$L1!=6?[incr ll -6]:[set h1 [expr 100+([string length "abc"]-[string length "abc"])-([string length "abc"]-[string length "abc"])]]}
+        expr {$L1!=1<<3?[incr q [expr ([string length "abc"]-[string length "abc"])-1]]:[set h_1 [set ll $h1]]}
+    }
+    set a
+}
+
+proc 12days {a b c} {
+    global xxx
+    expr {1<$a?[expr {$a<3?[12days -79 -13 [string range $c [12days -87 \
+	[expr 1-$b] [string range $c [12days -86 0 [string range $c 1 end]] \
+	end]] end]]:1};expr {$a<$b?[12days [expr $a+1] $b $c]:3};expr {[12days \
+	-94 [expr $a-27] $c]&&$a==2?$b<13?[12days 2 [expr $b+1] "%s %d %d\n"]:9
+	:16}]:$a<0?$a<-72?[12days $b $a "@n'+,#'/*\{\}w+/w#cdnr/+,\{\}r/*de\}+,/*\{*+,/w\{%+,/w#q#n+,/#\{l+,/n\{n+,/+#n+,/#;#q#n+,/+k#;*+,/'r :'d*'3,\}\{w+K w'K:'+\}e#';dq#'l q#'+d'K#!/+k#;q#'r\}eKK#\}w'r\}eKK\{nl\]'/#;#q#n')\{)#\}w')\{)\{nl\]'/+#n';d\}rw' i;# )\{nl\]!/n\{n#'; r\{#w'r nc\{nl\]'/#\{l,+'K \{rw' iK\{;\[\{nl\]'/w#q#n'wk nw' iwk\{KK\{nl\]!/w\{%'l##w#' i; :\{nl\]'/*\{q#'ld;r'\}\{nlwb!/*de\}'c ;;\{nl'-\{\}rw\]'/+,\}##'*\}#nc,',#nw\]'/+kd'+e\}+;#'rdq#w! nr'/ ') \}+\}\{rl#'\{n' ')# \}'+\}##(!!/"]
+	:$a<-50?[string compare [format %c $b] [string index $c 0]]==0?[append \
+	xxx [string index $c 31];scan [string index $c 31] %c x;set x]
+	:[12days -65 $b [string range $c 1 end]]:[12days [expr ([string compare \
+	[string index $c 0] "/"]==0)+$a] $b [string range $c 1 end]]:0<$a
+	?[12days 2 2 "%s"]:[string compare [string index $c 0] "/"]==0||
+	[12days 0 [12days -61 [scan [string index $c 0] %c x; set x] \
+	"!ek;dc i@bK'(q)-\[w\]*%n+r3#l,\{\}:\nuwloca-O;m .vpbks,fxntdCeghiry"] \
+	[string range $c 1 end]]}
+}
+proc do_twelve_days {} {
+    global xxx
+    set xxx ""
+    12days 1 1 1
+    set result [string length $xxx]
+    unset xxx
+    return $result
+}
+
+# start of tests
+
+catch {unset a b i x}
+
+test compExpr-old-1.1 {TclCompileExprCmd: no expression} {
+    list [catch {expr  } msg] $msg
+} {1 {wrong # args: should be "expr arg ?arg ...?"}}
+test compExpr-old-1.2 {TclCompileExprCmd: one expression word} {
+    expr -25
+} -25
+test compExpr-old-1.3 {TclCompileExprCmd: two expression words} {
+    expr -8.2   -6
+} -14.2
+test compExpr-old-1.4 {TclCompileExprCmd: five expression words} {
+    expr 20 - 5 +10 -7
+} 18
+test compExpr-old-1.5 {TclCompileExprCmd: quoted expression word} {
+    expr "0005"
+} 5
+test compExpr-old-1.6 {TclCompileExprCmd: quoted expression word} {
+    catch {expr "0005"zxy} msg
+    set msg
+} {extra characters after close-quote}
+test compExpr-old-1.7 {TclCompileExprCmd: expression word in braces} {
+    expr {-0005}
+} -5
+test compExpr-old-1.8 {TclCompileExprCmd: expression word in braces} {
+    expr {{-0x1234}}
+} -4660
+test compExpr-old-1.9 {TclCompileExprCmd: expression word in braces} {
+    catch {expr {-0005}foo} msg
+    set msg
+} {extra characters after close-brace}
+test compExpr-old-1.10 {TclCompileExprCmd: other expression word in braces} {
+    expr 4*[llength "6 2"]
+} 8
+test compExpr-old-1.11 {TclCompileExprCmd: expression word terminated by ;} {
+    expr 4*[llength "6 2"];
+} 8
+test compExpr-old-1.12 {TclCompileExprCmd: inlined expr (in "catch") inside other catch} {
+    set a xxx
+    catch {
+	# Might not be a number
+	set a [expr 10*$a]
+    }
+} 1
+test compExpr-old-1.13 {TclCompileExprCmd: second level of substitutions in expr not in braces with single var reference} {
+    set a xxx
+    set x 27;  set bool {$x};  if $bool {set a foo}
+    set a
+} foo
+test compExpr-old-1.14 {TclCompileExprCmd: second level of substitutions in expr with comparison as top-level operator} {
+    set a xxx
+    set x 2;  set b {$x};  set a [expr $b == 2]
+    set a
+} 1
+
+test compExpr-old-2.1 {TclCompileExpr: are builtin functions registered?} {
+    expr double(5*[llength "6 2"])
+} 10.0
+test compExpr-old-2.2 {TclCompileExpr: error in expr} -body {
+    expr 2***3
+} -returnCodes error -match glob -result *
+test compExpr-old-2.3 {TclCompileExpr: junk after legal expr} -body {
+    expr 7*[llength "a b"]foo
+} -returnCodes error -match glob -result *
+test compExpr-old-2.4 {TclCompileExpr: numeric expr string rep == formatted int rep} {
+    expr {0001}
+} 1
+
+test compExpr-old-3.1 {CompileCondExpr: just lor expr} {expr 3||0} 1
+test compExpr-old-3.2 {CompileCondExpr: error in lor expr} -body {
+    expr x||3
+} -returnCodes error -match glob -result *
+test compExpr-old-3.3 {CompileCondExpr: test true arm} {expr 3>2?44:66} 44
+test compExpr-old-3.4 {CompileCondExpr: error compiling true arm} -body {
+    expr 3>2?2***3:66
+} -returnCodes error -match glob -result *
+test compExpr-old-3.5 {CompileCondExpr: test false arm} {expr 2>3?44:66} 66
+test compExpr-old-3.6 {CompileCondExpr: error compiling false arm} -body {
+    expr 2>3?44:2***3
+} -returnCodes error -match glob -result *
+test compExpr-old-3.7 {CompileCondExpr: long arms & nested cond exprs} {
+    hello_world
+} {Hello world}
+test compExpr-old-3.8 {CompileCondExpr: long arms & nested cond exprs} unix {
+    # Fails with a stack overflow on threaded Windows builds
+    do_twelve_days
+} 2358
+
+test compExpr-old-4.1 {CompileLorExpr: just land expr} {expr 1.3&&3.3} 1
+test compExpr-old-4.2 {CompileLorExpr: error in land expr} -body {
+    expr x&&3
+} -returnCodes error -match glob -result *
+test compExpr-old-4.3 {CompileLorExpr: simple lor exprs} {expr 0||1.0} 1
+test compExpr-old-4.4 {CompileLorExpr: simple lor exprs} {expr 3.0||0.0} 1
+test compExpr-old-4.5 {CompileLorExpr: simple lor exprs} {expr 0||0||1} 1
+test compExpr-old-4.6 {CompileLorExpr: error compiling lor arm} -body {
+    expr 2***3||4.0
+} -returnCodes error -match glob -result *
+test compExpr-old-4.7 {CompileLorExpr: error compiling lor arm} -body {
+    expr 1.3||2***3
+} -returnCodes error -match glob -result *
+test compExpr-old-4.8 {CompileLorExpr: error compiling lor arms} {
+    list [catch {expr {"a"||"b"}} msg] $msg
+} {1 {expected boolean value but got "a"}}
+test compExpr-old-4.9 {CompileLorExpr: long lor arm} {
+    set a "abcdefghijkl"
+    set i 7
+    expr {[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]] || [string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]] || [string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]] || [string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]}
+} 1
+
+test compExpr-old-5.1 {CompileLandExpr: just bitor expr} {expr 7|0x13} 23
+test compExpr-old-5.2 {CompileLandExpr: error in bitor expr} -body {
+    expr x|3
+} -returnCodes error -match glob -result *
+test compExpr-old-5.3 {CompileLandExpr: simple land exprs} {expr 0&&1.0} 0
+test compExpr-old-5.4 {CompileLandExpr: simple land exprs} {expr 0&&0} 0
+test compExpr-old-5.5 {CompileLandExpr: simple land exprs} {expr 3.0&&1.2} 1
+test compExpr-old-5.6 {CompileLandExpr: simple land exprs} {expr 1&&1&&2} 1
+test compExpr-old-5.7 {CompileLandExpr: error compiling land arm} -body {
+    expr 2***3&&4.0
+} -returnCodes error -match glob -result *
+test compExpr-old-5.8 {CompileLandExpr: error compiling land arm} -body {
+    expr 1.3&&2***3
+} -returnCodes error -match glob -result *
+test compExpr-old-5.9 {CompileLandExpr: error compiling land arm} {
+    list [catch {expr {"a"&&"b"}} msg] $msg
+} {1 {expected boolean value but got "a"}}
+test compExpr-old-5.10 {CompileLandExpr: long land arms} {
+    set a "abcdefghijkl"
+    set i 7
+    expr {[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]] && [string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]] && [string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]] && [string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]}
+} 1
+
+test compExpr-old-6.1 {CompileBitXorExpr: just bitand expr} {expr 7&0x13} 3
+test compExpr-old-6.2 {CompileBitXorExpr: error in bitand expr} -body {
+    expr x|3
+} -returnCodes error -match glob -result *
+test compExpr-old-6.3 {CompileBitXorExpr: simple bitxor exprs} {expr 7^0x13} 20
+test compExpr-old-6.4 {CompileBitXorExpr: simple bitxor exprs} {expr 3^0x10} 19
+test compExpr-old-6.5 {CompileBitXorExpr: simple bitxor exprs} {expr 0^7} 7
+test compExpr-old-6.6 {CompileBitXorExpr: simple bitxor exprs} {expr -1^7} -8
+test compExpr-old-6.7 {CompileBitXorExpr: error compiling bitxor arm} -body {
+    expr 2***3|6
+} -returnCodes error -match glob -result *
+test compExpr-old-6.8 {CompileBitXorExpr: error compiling bitxor arm} -body {
+    expr 2^x
+} -returnCodes error -match glob -result *
+test compExpr-old-6.9 {CompileBitXorExpr: runtime error in bitxor arm} {
+    list [catch {expr {24.0^3}} msg] $msg
+} {1 {can't use floating-point value as operand of "^"}}
+test compExpr-old-6.10 {CompileBitXorExpr: runtime error in bitxor arm} {
+    list [catch {expr {"a"^"b"}} msg] $msg
+} {1 {can't use non-numeric string as operand of "^"}}
+
+test compExpr-old-7.1 {CompileBitAndExpr: just equality expr} {expr 3==2} 0
+test compExpr-old-7.2 {CompileBitAndExpr: just equality expr} {expr 2.0==2} 1
+test compExpr-old-7.3 {CompileBitAndExpr: just equality expr} {expr 3.2!=2.2} 1
+test compExpr-old-7.4 {CompileBitAndExpr: just equality expr} {expr {"abc" == "abd"}} 0
+test compExpr-old-7.5 {CompileBitAndExpr: error in equality expr} -body {
+    expr x==3
+} -returnCodes error -match glob -result *
+test compExpr-old-7.6 {CompileBitAndExpr: simple bitand exprs} {expr 7&0x13} 3
+test compExpr-old-7.7 {CompileBitAndExpr: simple bitand exprs} {expr 0xf2&0x53} 82
+test compExpr-old-7.8 {CompileBitAndExpr: simple bitand exprs} {expr 3&6} 2
+test compExpr-old-7.9 {CompileBitAndExpr: simple bitand exprs} {expr -1&-7} -7
+test compExpr-old-7.10 {CompileBitAndExpr: error compiling bitand arm} -body {
+    expr 2***3&6
+} -returnCodes error -match glob -result *
+test compExpr-old-7.11 {CompileBitAndExpr: error compiling bitand arm} -body {
+    expr 2&x
+} -returnCodes error -match glob -result *
+test compExpr-old-7.12 {CompileBitAndExpr: runtime error in bitand arm} {
+    list [catch {expr {24.0&3}} msg] $msg
+} {1 {can't use floating-point value as operand of "&"}}
+test compExpr-old-7.13 {CompileBitAndExpr: runtime error in bitand arm} {
+    list [catch {expr {"a"&"b"}} msg] $msg
+} {1 {can't use non-numeric string as operand of "&"}}
+
+test compExpr-old-8.1 {CompileEqualityExpr: just relational expr} {expr 3>=2} 1
+test compExpr-old-8.2 {CompileEqualityExpr: just relational expr} {expr 2<=2.1} 1
+test compExpr-old-8.3 {CompileEqualityExpr: just relational expr} {expr 3.2>"2.2"} 1
+test compExpr-old-8.4 {CompileEqualityExpr: just relational expr} {expr {"0y"<"0x12"}} 0
+test compExpr-old-8.5 {CompileEqualityExpr: error in relational expr} -body {
+    expr x>3
+} -returnCodes error -match glob -result *
+test compExpr-old-8.6 {CompileEqualityExpr: simple equality exprs} {expr 7==0x13} 0
+test compExpr-old-8.7 {CompileEqualityExpr: simple equality exprs} {expr -0xf2!=0x53} 1
+test compExpr-old-8.8 {CompileEqualityExpr: simple equality exprs} {expr {"12398712938788234-1298379" != ""}} 1
+test compExpr-old-8.9 {CompileEqualityExpr: simple equality exprs} {expr -1!="abc"} 1
+test compExpr-old-8.10 {CompileEqualityExpr: error compiling equality arm} -body {
+    expr 2***3==6
+} -returnCodes error -match glob -result *
+test compExpr-old-8.11 {CompileEqualityExpr: error compiling equality arm} -body {
+    expr 2!=x
+} -returnCodes error -match glob -result *
+
+
+test compExpr-old-9.1 {CompileRelationalExpr: just shift expr} {expr 3<<2} 12
+test compExpr-old-9.2 {CompileRelationalExpr: just shift expr} {expr 0xff>>2} 63
+test compExpr-old-9.3 {CompileRelationalExpr: just shift expr} {expr -1>>2} -1
+test compExpr-old-9.4 {CompileRelationalExpr: just shift expr} {expr {1<<3}} 8
+
+# The following test is different for 32-bit versus 64-bit
+# architectures because LONG_MIN is different
+
+test compExpr-old-9.5a {CompileRelationalExpr: shift expr producing LONG_MIN} longIs64bit {
+    expr {int(1<<63)}
+} -9223372036854775808
+test compExpr-old-9.5b {CompileRelationalExpr: shift expr producing LONG_MIN} longIs32bit {
+    expr {int(1<<31)}
+} -2147483648
+
+test compExpr-old-9.6 {CompileRelationalExpr: error in shift expr} -body {
+    expr x>>3
+} -returnCodes error -match glob -result *
+test compExpr-old-9.7 {CompileRelationalExpr: simple relational exprs} {expr 0xff>=+0x3} 1
+test compExpr-old-9.8 {CompileRelationalExpr: simple relational exprs} {expr -0xf2<0x3} 1
+test compExpr-old-9.9 {CompileRelationalExpr: error compiling relational arm} -body {
+    expr 2***3>6
+} -returnCodes error -match glob -result *
+test compExpr-old-9.10 {CompileRelationalExpr: error compiling relational arm} -body {
+    expr 2<x
+} -returnCodes error -match glob -result *
+
+test compExpr-old-10.1 {CompileShiftExpr: just add expr} {expr 4+-2} 2
+test compExpr-old-10.2 {CompileShiftExpr: just add expr} {expr 0xff-2} 253
+test compExpr-old-10.3 {CompileShiftExpr: just add expr} {expr -1--2} 1
+test compExpr-old-10.4 {CompileShiftExpr: just add expr} {expr 1-0o123} -82
+test compExpr-old-10.5 {CompileShiftExpr: error in add expr} -body {
+    expr x+3
+} -returnCodes error -match glob -result *
+test compExpr-old-10.6 {CompileShiftExpr: simple shift exprs} {expr 0xff>>0x3} 31
+test compExpr-old-10.7 {CompileShiftExpr: simple shift exprs} {expr -0xf2<<0x3} -1936
+test compExpr-old-10.8 {CompileShiftExpr: error compiling shift arm} -body {
+    expr 2***3>>6
+} -returnCodes error -match glob -result *
+test compExpr-old-10.9 {CompileShiftExpr: error compiling shift arm} -body {
+    expr 2<<x
+} -returnCodes error -match glob -result *
+test compExpr-old-10.10 {CompileShiftExpr: runtime error} {
+    list [catch {expr {24.0>>43}} msg] $msg
+} {1 {can't use floating-point value as operand of ">>"}}
+test compExpr-old-10.11 {CompileShiftExpr: runtime error} {
+    list [catch {expr {"a"<<"b"}} msg] $msg
+} {1 {can't use non-numeric string as operand of "<<"}}
+
+test compExpr-old-11.1 {CompileAddExpr: just multiply expr} {expr 4*-2} -8
+test compExpr-old-11.2 {CompileAddExpr: just multiply expr} {expr 0xff%2} 1
+test compExpr-old-11.3 {CompileAddExpr: just multiply expr} {expr -1/2} -1
+test compExpr-old-11.4 {CompileAddExpr: just multiply expr} {expr 7891%0o123} 6
+test compExpr-old-11.5 {CompileAddExpr: error in multiply expr} -body {
+    expr x*3
+} -returnCodes error -match glob -result *
+test compExpr-old-11.6 {CompileAddExpr: simple add exprs} {expr 0xff++0x3} 258
+test compExpr-old-11.7 {CompileAddExpr: simple add exprs} {expr -0xf2--0x3} -239
+test compExpr-old-11.8 {CompileAddExpr: error compiling add arm} -body {
+    expr 2***3+6
+} -returnCodes error -match glob -result *
+test compExpr-old-11.9 {CompileAddExpr: error compiling add arm} -body {
+    expr 2-x
+} -returnCodes error -match glob -result *
+test compExpr-old-11.10 {CompileAddExpr: runtime error} {
+    list [catch {expr {24.0+"xx"}} msg] $msg
+} {1 {can't use non-numeric string as operand of "+"}}
+test compExpr-old-11.11 {CompileAddExpr: runtime error} {
+    list [catch {expr {"a"-"b"}} msg] $msg
+} {1 {can't use non-numeric string as operand of "-"}}
+test compExpr-old-11.12 {CompileAddExpr: runtime error} {
+    list [catch {expr {3/0}} msg] $msg
+} {1 {divide by zero}}
+test compExpr-old-11.13a {CompileAddExpr: runtime error} ieeeFloatingPoint {
+    list [catch {expr {2.3/0.0}} msg] $msg
+} {0 Inf}
+test compExpr-old-11.13b {CompileAddExpr: runtime error} !ieeeFloatingPoint {
+    list [catch {expr {2.3/0.0}} msg] $msg
+} {1 {divide by zero}}
+
+test compExpr-old-12.1 {CompileMultiplyExpr: just unary expr} {expr ~4} -5
+test compExpr-old-12.2 {CompileMultiplyExpr: just unary expr} {expr --5} 5
+test compExpr-old-12.3 {CompileMultiplyExpr: just unary expr} {expr !27} 0
+test compExpr-old-12.4 {CompileMultiplyExpr: just unary expr} {expr ~0xff00ff} -16711936
+test compExpr-old-12.5 {CompileMultiplyExpr: error in unary expr} -body {
+    expr ~x
+} -returnCodes error -match glob -result *
+test compExpr-old-12.6 {CompileMultiplyExpr: simple multiply exprs} {expr 0xff*0x3} 765
+test compExpr-old-12.7 {CompileMultiplyExpr: simple multiply exprs} {expr -0xf2%-0x3} -2
+test compExpr-old-12.8 {CompileMultiplyExpr: error compiling multiply arm} -body {
+    expr 2*3%%6
+} -returnCodes error -match glob -result *
+test compExpr-old-12.9 {CompileMultiplyExpr: error compiling multiply arm} -body {
+    expr 2*x
+} -returnCodes error -match glob -result *
+test compExpr-old-12.10 {CompileMultiplyExpr: runtime error} {
+    list [catch {expr {24.0*"xx"}} msg] $msg
+} {1 {can't use non-numeric string as operand of "*"}}
+test compExpr-old-12.11 {CompileMultiplyExpr: runtime error} {
+    list [catch {expr {"a"/"b"}} msg] $msg
+} {1 {can't use non-numeric string as operand of "/"}}
+
+test compExpr-old-13.1 {CompileUnaryExpr: unary exprs} {expr -0xff} -255
+test compExpr-old-13.2 {CompileUnaryExpr: unary exprs} {expr +0o00123} 83
+test compExpr-old-13.3 {CompileUnaryExpr: unary exprs} {expr +--++36} 36
+test compExpr-old-13.4 {CompileUnaryExpr: unary exprs} {expr !2} 0
+test compExpr-old-13.5 {CompileUnaryExpr: unary exprs} {expr +--+-62.0} -62.0
+test compExpr-old-13.6 {CompileUnaryExpr: unary exprs} {expr !0.0} 1
+test compExpr-old-13.7 {CompileUnaryExpr: unary exprs} {expr !0xef} 0
+test compExpr-old-13.8 {CompileUnaryExpr: error compiling unary expr} -body {
+    expr ~x
+} -returnCodes error -match glob -result *
+test compExpr-old-13.9 {CompileUnaryExpr: error compiling unary expr} -body {
+    expr !1.x
+    set msg
+} -returnCodes error -match glob -result *
+test compExpr-old-13.10 {CompileUnaryExpr: runtime error} {
+    list [catch {expr {~"xx"}} msg] $msg
+} {1 {can't use non-numeric string as operand of "~"}}
+test compExpr-old-13.11 {CompileUnaryExpr: runtime error} {
+    list [catch {expr ~4.0} msg] $msg
+} {1 {can't use floating-point value as operand of "~"}}
+test compExpr-old-13.12 {CompileUnaryExpr: just primary expr} {expr 0x123} 291
+test compExpr-old-13.13 {CompileUnaryExpr: just primary expr} {
+    set a 27
+    expr $a
+} 27
+test compExpr-old-13.14 {CompileUnaryExpr: just primary expr} {
+    expr double(27)
+} 27.0
+test compExpr-old-13.15 {CompileUnaryExpr: just primary expr} {expr "123"} 123
+test compExpr-old-13.16 {CompileUnaryExpr: error in primary expr} {
+    catch {expr [set]} msg
+    set msg
+} {wrong # args: should be "set varName ?newValue?"}
+test compExpr-old-14.1 {CompilePrimaryExpr: literal primary} {expr 1} 1
+test compExpr-old-14.2 {CompilePrimaryExpr: literal primary} {expr 123} 123
+test compExpr-old-14.3 {CompilePrimaryExpr: literal primary} {expr 0xff} 255
+test compExpr-old-14.4 {CompilePrimaryExpr: literal primary} {expr 0o0010} 8
+test compExpr-old-14.5 {CompilePrimaryExpr: literal primary} {expr 62.0} 62.0
+test compExpr-old-14.6 {CompilePrimaryExpr: literal primary} {
+    expr 3.1400000
+} 3.14
+test compExpr-old-14.7 {CompilePrimaryExpr: literal primary} {expr {{abcde}<{abcdef}}} 1
+test compExpr-old-14.8 {CompilePrimaryExpr: literal primary} {expr {{abc\
+def} < {abcdef}}} 1
+test compExpr-old-14.9 {CompilePrimaryExpr: literal primary} {expr {{abc\tde} > {abc\tdef}}} 0
+test compExpr-old-14.10 {CompilePrimaryExpr: literal primary} {expr {{123}}} 123
+test compExpr-old-14.11 {CompilePrimaryExpr: var reference primary} {
+    set i 789
+    list [expr {$i}] [expr $i]
+} {789 789}
+test compExpr-old-14.12 {CompilePrimaryExpr: var reference primary} {
+    set i {789}    ;# test expr's aggressive conversion to numeric semantics
+    list [expr {$i}] [expr $i]
+} {789 789}
+test compExpr-old-14.13 {CompilePrimaryExpr: var reference primary} {
+    catch {unset a}
+    set a(foo) foo
+    set a(bar) bar
+    set a(123) 123
+    set result ""
+    lappend result [expr $a(123)] [expr {$a(bar)<$a(foo)}]
+    catch {unset a}
+    set result
+} {123 1}
+test compExpr-old-14.14 {CompilePrimaryExpr: var reference primary} {
+    set i 123    ;# test "$var.0" floating point conversion hack
+    list [expr $i] [expr $i.0] [expr $i.0/12.0]
+} {123 123.0 10.25}
+test compExpr-old-14.15 {CompilePrimaryExpr: var reference primary} {
+    set i 123
+    catch {expr $i.2} msg
+    set msg
+} 123.2
+test compExpr-old-14.16 {CompilePrimaryExpr: error compiling var reference primary} -body {
+    expr {$a(foo}
+} -returnCodes error -match glob -result *
+test compExpr-old-14.17 {CompilePrimaryExpr: string primary that looks like var ref} -body {
+    expr $
+} -returnCodes error -match glob -result *
+test compExpr-old-14.18 {CompilePrimaryExpr: quoted string primary} {
+    expr "21"
+} 21
+test compExpr-old-14.19 {CompilePrimaryExpr: quoted string primary} {
+    set i 123
+    set x 456
+    expr "$i+$x"
+} 579
+test compExpr-old-14.20 {CompilePrimaryExpr: quoted string primary} {
+    set i 3
+    set x 6
+    expr 2+"$i.$x"
+} 5.6
+test compExpr-old-14.21 {CompilePrimaryExpr: error in quoted string primary} {
+    catch {expr "[set]"} msg
+    set msg
+} {wrong # args: should be "set varName ?newValue?"}
+test compExpr-old-14.22 {CompilePrimaryExpr: subcommand primary} {
+    expr {[set i 123; set i]}
+} 123
+test compExpr-old-14.23 {CompilePrimaryExpr: error in subcommand primary} -body {
+    catch {expr {[set]}} msg
+    set ::errorInfo
+} -match glob -result {wrong # args: should be "set varName ?newValue?"
+    while *ing
+"set"*}
+test compExpr-old-14.24 {CompilePrimaryExpr: error in subcommand primary} -body {
+    expr {[set i}
+} -returnCodes error -match glob -result *
+test compExpr-old-14.25 {CompilePrimaryExpr: math function primary} {
+    format %.6g [expr exp(1.0)]
+} 2.71828
+test compExpr-old-14.26 {CompilePrimaryExpr: math function primary} {
+    format %.6g [expr pow(2.0+0.1,3.0+0.1)]
+} 9.97424
+test compExpr-old-14.27 {CompilePrimaryExpr: error in math function primary} -body {
+    expr sinh::(2.0)
+} -returnCodes error -match glob -result *
+test compExpr-old-14.28 {CompilePrimaryExpr: subexpression primary} {
+    expr 2+(3*4)
+} 14
+test compExpr-old-14.29 {CompilePrimaryExpr: error in subexpression primary} -body {
+    catch {expr 2+(3*[set])} msg
+    set ::errorInfo
+} -match glob -result {wrong # args: should be "set varName ?newValue?"
+    while *ing
+"set"*}
+test compExpr-old-14.30 {CompilePrimaryExpr: missing paren in subexpression primary} -body {
+    expr 2+(3*(4+5)
+} -returnCodes error -match glob -result *
+test compExpr-old-14.31 {CompilePrimaryExpr: just var ref in subexpression primary} {
+    set i "5+10"
+    list "[expr $i] == 15" "[expr ($i)] == 15" "[eval expr ($i)] == 15"
+} {{15 == 15} {15 == 15} {15 == 15}}
+test compExpr-old-14.32 {CompilePrimaryExpr: unexpected token} -body {
+    expr @
+} -returnCodes error -match glob -result *
+
+test compExpr-old-15.1 {CompileMathFuncCall: missing parenthesis} -body {
+    expr sinh2.0)
+} -returnCodes error -match glob -result *
+test compExpr-old-15.2 {CompileMathFuncCall: unknown math function} -body {
+    catch {expr whazzathuh(1)} msg
+    set ::errorInfo
+} -match glob -result {* "*whazzathuh"
+    while *ing
+"expr whazzathuh(1)"}
+test compExpr-old-15.3 {CompileMathFuncCall: too many arguments} -body {
+    catch {expr sin(1,2,3)} msg
+    set ::errorInfo
+} -match glob -result {too many arguments for math function*
+    while *ing
+"expr sin(1,2,3)"}
+test compExpr-old-15.4 {CompileMathFuncCall: ')' found before last required arg} -body {
+    catch {expr sin()} msg
+    set ::errorInfo
+} -match glob -result {too few arguments for math function*
+    while *ing
+"expr sin()"}
+test compExpr-old-15.5 {CompileMathFuncCall: too few arguments} -body {
+    catch {expr pow(1)} msg
+    set ::errorInfo
+} -match glob -result {too few arguments for math function*
+    while *ing
+"expr pow(1)"}
+test compExpr-old-15.6 {CompileMathFuncCall: missing ')'} -body {
+    expr sin(1
+} -returnCodes error -match glob -result *
+test compExpr-old-15.7 {CompileMathFuncCall: call registered math function} testmathfunctions {
+    expr 2*T1()
+} 246
+test compExpr-old-15.8 {CompileMathFuncCall: call registered math function} testmathfunctions {
+    expr T2()*3
+} 1035
+test compExpr-old-15.9 {CompileMathFuncCall: call registered math function} testmathfunctions {
+    expr T3(21, 37)
+} 37
+test compExpr-old-15.10 {CompileMathFuncCall: call registered math function} testmathfunctions {
+    expr T3(21.2, 37)
+} 37.0
+test compExpr-old-15.11 {CompileMathFuncCall: call registered math function} testmathfunctions {
+    expr T3(-21.2, -17.5)
+} -17.5
+
+test compExpr-old-16.1 {GetToken: checks whether integer token starting with "0x" (e.g., "0x$") is invalid} {
+    catch {unset a}
+    set a(VALUE) ff15
+    set i 123
+    if {[expr 0x$a(VALUE)] & 16} {
+        set i {}
+    }
+    set i
+} {}
+test compExpr-old-16.2 {GetToken: check for string literal in braces} {
+    expr {{1}}
+} {1}
+
+# Check "expr" and computed command names.
+
+test compExpr-old-17.1 {expr and computed command names} {
+    set i 0
+    set z expr
+    $z 1+2
+} 3
+
+# Check correct conversion of operands to numbers: If the string looks like
+# an integer, convert to integer. Otherwise, if the string looks like a
+# double, convert to double.
+
+test compExpr-old-18.1 {expr and conversion of operands to numbers} {
+    set x [lindex 11 0]
+    catch {expr int($x)}
+    expr {$x}
+} 11
+
+# Check "expr" and interpreter result object resetting before appending
+# an error msg during evaluation of exprs not in {}s
+
+test compExpr-old-19.1 {expr and interpreter result object resetting} {
+    proc p {} {
+        set t  10.0
+        set x  2.0
+        set dx 0.2
+        set f  {$dx-$x/10}
+        set g  {-$x/5}
+        set center 1.0
+        set x  [expr $x-$center]
+        set dx [expr $dx+$g]
+        set x  [expr $x+$f+$center]
+        set x  [expr $x+$f+$center]
+        set y  [expr round($x)]
+    }
+    p
+} 3
+
+# cleanup
+if {[info exists a]} {
+    unset a
+}
+::tcltest::cleanupTests
+return
diff --git a/tests/compExpr.test b/tests/compExpr.test
new file mode 100644
index 0000000..14c875d
--- /dev/null
+++ b/tests/compExpr.test
@@ -0,0 +1,396 @@
+# This file contains a collection of tests for the procedures in the file
+# tclCompExpr.c.  Sourcing this file into Tcl runs the tests and generates
+# output for errors.  No output means no errors were found.
+#
+# Copyright (c) 1997 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution of
+# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {"::tcltest" ni [namespace children]} {
+    package require tcltest 2
+    namespace import -force ::tcltest::*
+}
+
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
+
+if {[catch {expr T1()} msg] && $msg eq {invalid command name "tcl::mathfunc::T1"}} {
+    testConstraint testmathfunctions 0
+} else {
+    testConstraint testmathfunctions 1
+}
+
+# Constrain memory leak tests
+testConstraint memory [llength [info commands memory]]
+
+catch {unset a}
+
+test compExpr-1.1 {TclCompileExpr procedure, successful expr parse and compile} {
+    expr 1+2
+} 3
+test compExpr-1.2 {TclCompileExpr procedure, error parsing expr} -body {
+    expr 1+2+
+} -returnCodes error -match glob -result *
+test compExpr-1.3 {TclCompileExpr procedure, error compiling expr} -body {
+    list [catch {expr "foo(123)"} msg] $msg
+} -match glob -result {1 {* "*foo"}}
+test compExpr-1.4 {TclCompileExpr procedure, expr has no operators} {
+    set a {0o00123}
+    expr {$a}
+} 83
+
+test compExpr-2.1 {CompileSubExpr procedure, TCL_TOKEN_WORD parse token} -setup {
+    unset -nocomplain a
+} -body {
+    set a 27
+    expr {"foo$a" < "bar"}
+} -result 0
+test compExpr-2.2 {CompileSubExpr procedure, error compiling TCL_TOKEN_WORD parse token} -body {
+    expr {"00[expr 1+]" + 17}
+} -returnCodes error -match glob -result *
+test compExpr-2.3 {CompileSubExpr procedure, TCL_TOKEN_TEXT parse token} {
+    expr {{12345}}
+} 12345
+test compExpr-2.4 {CompileSubExpr procedure, empty TCL_TOKEN_TEXT parse token} {
+    expr {{}}
+} {}
+test compExpr-2.5 {CompileSubExpr procedure, TCL_TOKEN_BS parse token} {
+    expr "\{  \\
+ +123 \}"
+} 123
+test compExpr-2.6 {CompileSubExpr procedure, TCL_TOKEN_COMMAND parse token} {
+    expr {[info tclversion] != ""}
+} 1
+test compExpr-2.7 {CompileSubExpr procedure, TCL_TOKEN_COMMAND parse token} {
+    expr {[]}
+} {}
+test compExpr-2.8 {CompileSubExpr procedure, error in TCL_TOKEN_COMMAND parse token} -body {
+    expr {[foo "bar"xxx] + 17}
+} -returnCodes error -match glob -result *
+test compExpr-2.9 {CompileSubExpr procedure, TCL_TOKEN_VARIABLE parse token} -setup {
+    unset -nocomplain a
+} -body {
+    set a 123
+    expr {$a*2}
+} -result 246
+test compExpr-2.10 {CompileSubExpr procedure, TCL_TOKEN_VARIABLE parse token} -setup {
+    unset -nocomplain a
+    unset -nocomplain b
+} -body {
+    set a(george) martha
+    set b geo
+    expr {$a(${b}rge)}
+} -result martha
+test compExpr-2.11 {CompileSubExpr procedure, error in TCL_TOKEN_VARIABLE parse token} -body {
+    unset -nocomplain a
+    expr {$a + 17}
+} -returnCodes error -result {can't read "a": no such variable}
+test compExpr-2.12 {CompileSubExpr procedure, TCL_TOKEN_SUB_EXPR parse token} {
+    expr {27||3? 3<<(1+4) : 4&&9}
+} 96
+test compExpr-2.13 {CompileSubExpr procedure, error in TCL_TOKEN_SUB_EXPR parse token} -setup {
+    unset -nocomplain a
+} -body {
+    set a 15
+    list [catch {expr {27 || "$a[expr 1+]00"}} msg] $msg
+} -result {0 1}
+test compExpr-2.14 {CompileSubExpr procedure, TCL_TOKEN_OPERATOR token, op found} {
+    expr {5*6}
+} 30
+test compExpr-2.15 {CompileSubExpr procedure, TCL_TOKEN_OPERATOR token, math function found} {
+    format %.6g [expr {sin(2.0)}]
+} 0.909297
+test compExpr-2.16 {CompileSubExpr procedure, TCL_TOKEN_OPERATOR token, math function not found} -body {
+    list [catch {expr {fred(2.0)}} msg] $msg
+} -match glob -result {1 {* "*fred"}}
+test compExpr-2.17 {CompileSubExpr procedure, TCL_TOKEN_OPERATOR token, normal operator} {
+    expr {4*2}
+} 8
+test compExpr-2.18 {CompileSubExpr procedure, TCL_TOKEN_OPERATOR token, normal operator} {
+    expr {4/2}
+} 2
+test compExpr-2.19 {CompileSubExpr procedure, TCL_TOKEN_OPERATOR token, normal operator} {
+    expr {4%2}
+} 0
+test compExpr-2.20 {CompileSubExpr procedure, TCL_TOKEN_OPERATOR token, normal operator} {
+    expr {4<<2}
+} 16
+test compExpr-2.21 {CompileSubExpr procedure, TCL_TOKEN_OPERATOR token, normal operator} {
+    expr {4>>2}
+} 1
+test compExpr-2.22 {CompileSubExpr procedure, TCL_TOKEN_OPERATOR token, normal operator} {
+    expr {4<2}
+} 0
+test compExpr-2.23 {CompileSubExpr procedure, TCL_TOKEN_OPERATOR token, normal operator} {
+    expr {4>2}
+} 1
+test compExpr-2.24 {CompileSubExpr procedure, TCL_TOKEN_OPERATOR token, normal operator} {
+    expr {4<=2}
+} 0
+test compExpr-2.25 {CompileSubExpr procedure, TCL_TOKEN_OPERATOR token, normal operator} {
+    expr {4>=2}
+} 1
+test compExpr-2.26 {CompileSubExpr procedure, TCL_TOKEN_OPERATOR token, normal operator} {
+    expr {4==2}
+} 0
+test compExpr-2.27 {CompileSubExpr procedure, TCL_TOKEN_OPERATOR token, normal operator} {
+    expr {4!=2}
+} 1
+test compExpr-2.28 {CompileSubExpr procedure, TCL_TOKEN_OPERATOR token, normal operator} {
+    expr {4&2}
+} 0
+test compExpr-2.29 {CompileSubExpr procedure, TCL_TOKEN_OPERATOR token, normal operator} {
+    expr {4^2}
+} 6
+test compExpr-2.30 {CompileSubExpr procedure, TCL_TOKEN_OPERATOR token, normal operator} {
+    expr {4|2}
+} 6
+test compExpr-2.31 {CompileSubExpr procedure, TCL_TOKEN_OPERATOR token, normal operator, 1 operand} {
+    expr {!4}
+} 0
+test compExpr-2.32 {CompileSubExpr procedure, TCL_TOKEN_OPERATOR token, normal operator, 1 operand} {
+    expr {~4}
+} -5
+test compExpr-2.33 {CompileSubExpr procedure, TCL_TOKEN_OPERATOR token, normal operator, comparison} -setup {
+    unset -nocomplain a
+} -body {
+    set a 15
+    expr {$a==15}  ;# compiled out-of-line to runtime call on Tcl_ExprObjCmd
+} -result 1
+test compExpr-2.34 {CompileSubExpr procedure, TCL_TOKEN_OPERATOR token, special operator} {
+    expr {+2}
+} 2
+test compExpr-2.35 {CompileSubExpr procedure, TCL_TOKEN_OPERATOR token, error in special operator} -body {
+    expr {+[expr 1+]}
+} -returnCodes error -match glob -result *
+test compExpr-2.36 {CompileSubExpr procedure, TCL_TOKEN_OPERATOR token, special operator} {
+    expr {4+2}
+} 6
+test compExpr-2.37 {CompileSubExpr procedure, TCL_TOKEN_OPERATOR token, error in special operator} -body {
+    expr {[expr 1+]+5}
+} -returnCodes error -match glob -result *
+test compExpr-2.38 {CompileSubExpr procedure, TCL_TOKEN_OPERATOR token, error in special operator} -body {
+    expr {5+[expr 1+]}
+} -returnCodes error -match glob -result *
+test compExpr-2.39 {CompileSubExpr procedure, TCL_TOKEN_OPERATOR token, special operator} {
+    expr {-2}
+} -2
+test compExpr-2.40 {CompileSubExpr procedure, TCL_TOKEN_OPERATOR token, special operator} {
+    expr {4-2}
+} 2
+test compExpr-2.41 {CompileSubExpr procedure, TCL_TOKEN_OPERATOR token, special operator} -setup {
+    unset -nocomplain a
+} -body {
+    set a true
+    expr {0||$a}
+} -result 1
+test compExpr-2.42 {CompileSubExpr procedure, error in TCL_TOKEN_SUB_EXPR parse token} -setup {
+    unset -nocomplain a
+} -body {
+    set a 15
+    list [catch {expr {27 || "$a[expr 1+]00"}} msg] $msg
+} -result {0 1}
+test compExpr-2.43 {CompileSubExpr procedure, TCL_TOKEN_OPERATOR token, special operator} -setup {
+    unset -nocomplain a
+} -body {
+    set a false
+    expr {3&&$a}
+} -result 0
+test compExpr-2.44 {CompileSubExpr procedure, TCL_TOKEN_OPERATOR token, special operator} -setup {
+    unset -nocomplain a
+} -body {
+    set a false
+    expr {$a||1? 1 : 0}
+} -result 1
+test compExpr-2.45 {CompileSubExpr procedure, error in TCL_TOKEN_SUB_EXPR parse token} -setup {
+    unset -nocomplain a
+} -body {
+    set a 15
+    list [catch {expr {1? 54 : "$a[expr 1+]00"}} msg] $msg
+} -result {0 54}
+
+test compExpr-3.1 {CompileLandOrLorExpr procedure, numeric 1st operand} -setup {
+    unset -nocomplain a
+} -body {
+    set a 2
+    expr {[set a]||0}
+} -result 1
+test compExpr-3.2 {CompileLandOrLorExpr procedure, nonnumeric 1st operand} -setup {
+    unset -nocomplain a
+} -body {
+    set a no
+    expr {$a&&1}
+} -result 0
+test compExpr-3.3 {CompileSubExpr procedure, error in 1st operand} -body {
+    expr {[expr *2]||0}
+} -returnCodes error -match glob -result *
+test compExpr-3.4 {CompileLandOrLorExpr procedure, result is 1 or 0} -setup {
+    unset -nocomplain a
+    unset -nocomplain b
+} -body {
+    set a no
+    set b true
+    expr {$a || $b}
+} -result 1
+test compExpr-3.5 {CompileLandOrLorExpr procedure, short-circuit semantics} -setup {
+    unset -nocomplain a
+} -body {
+    set a yes
+    expr {$a || [exit]}
+} -result 1
+test compExpr-3.6 {CompileLandOrLorExpr procedure, short-circuit semantics} -setup {
+    unset -nocomplain a
+} -body {
+    set a no
+    expr {$a && [exit]}
+} -result 0
+test compExpr-3.7 {CompileLandOrLorExpr procedure, numeric 2nd operand} -setup {
+    unset -nocomplain a
+} -body {
+    set a 2
+    expr {0||[set a]}
+} -result 1
+test compExpr-3.8 {CompileLandOrLorExpr procedure, nonnumeric 2nd operand} -setup {
+    unset -nocomplain a
+} -body {
+    set a no
+    expr {1&&$a}
+} -result 0
+test compExpr-3.9 {CompileLandOrLorExpr procedure, error in 2nd operand} -body {
+    expr {0||[expr %2]}
+} -returnCodes error -match glob -result *
+test compExpr-3.10 {CompileLandOrLorExpr procedure, long lor/land arm} {
+    set a "abcdefghijkl"
+    set i 7
+    expr {[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]] || [string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]] || [string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]] || [string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]}
+} 1
+
+test compExpr-4.1 {CompileCondExpr procedure, simple test} -setup {
+    unset -nocomplain a
+} -body {
+    set a 2
+    expr {($a > 1)? "ok" : "nope"}
+} -result ok
+test compExpr-4.2 {CompileCondExpr procedure, complex test, convert to numeric} -setup {
+    unset -nocomplain a
+} -body {
+    set a no
+    expr {[set a]? 27 : -54}
+} -result -54
+test compExpr-4.3 {CompileCondExpr procedure, error in test} -body {
+    expr {[expr *2]? +1 : -1}
+} -returnCodes error -match glob -result *
+test compExpr-4.4 {CompileCondExpr procedure, simple "true" clause} -setup {
+    unset -nocomplain a
+} -body {
+    set a no
+    expr {1? (27-2) : -54}
+} -result 25
+test compExpr-4.5 {CompileCondExpr procedure, convert "true" clause to numeric} -setup {
+    unset -nocomplain a
+} -body {
+    set a no
+    expr {1? $a : -54}
+} -result no
+test compExpr-4.6 {CompileCondExpr procedure, error in "true" clause} -body {
+    expr {1? [expr *2] : -127}
+} -returnCodes error -match glob -result *
+test compExpr-4.7 {CompileCondExpr procedure, simple "false" clause} -setup {
+    unset -nocomplain a
+} -body {
+    set a no
+    expr {(2-2)? -3.14159 : "nope"}
+} -result nope
+test compExpr-4.8 {CompileCondExpr procedure, convert "false" clause to numeric} -setup {
+    unset -nocomplain a
+} -body {
+    set a 0o0123
+    expr {0? 42 : $a}
+} -result 83
+test compExpr-4.9 {CompileCondExpr procedure, error in "false" clause} {
+    list [catch {expr {1? 15 : [expr *2]}} msg] $msg
+} {0 15}
+
+test compExpr-5.1 {CompileMathFuncCall procedure, math function found} {
+    format %.6g [expr atan2(1.0, 2.0)]
+} 0.463648
+test compExpr-5.2 {CompileMathFuncCall procedure, math function not found} -body {
+    expr {do_it()}
+} -returnCodes error -match glob -result {* "*do_it"}
+test compExpr-5.3 {CompileMathFuncCall: call registered math function} testmathfunctions {
+    expr 3*T1()-1
+} 368
+test compExpr-5.4 {CompileMathFuncCall: call registered math function} testmathfunctions {
+    expr T2()*3
+} 1035
+test compExpr-5.5 {CompileMathFuncCall procedure, too few arguments} -body {
+    expr {atan2(1.0)}
+} -returnCodes error -match glob -result {too few arguments for math function*}
+test compExpr-5.6 {CompileMathFuncCall procedure, complex argument} {
+    format %.6g [expr pow(2.1, 27.5-(24.4*(5%2)))]
+} 9.97424
+test compExpr-5.7 {CompileMathFuncCall procedure, error in argument} -body {
+    expr {sinh(2.*)}
+} -returnCodes error -match glob -result *
+test compExpr-5.8 {CompileMathFuncCall procedure, too many arguments} -body {
+    expr {sinh(2.0, 3.0)}
+} -returnCodes error -match glob -result {too many arguments for math function*}
+test compExpr-5.9 {CompileMathFuncCall procedure, too many arguments} -body {
+    expr {0 <= rand(5.2)}
+} -returnCodes error -match glob -result {too many arguments for math function*}
+
+test compExpr-6.1 {LogSyntaxError procedure, error in expr longer than 60 chars} -body {
+    expr {(+0123456)*(+0123456)*(+0123456)*(+0123456)*(+0123456)*(+0123456)*(+0123456)/} -1 foo 3
+} -returnCodes error -match glob -result *
+
+test compExpr-7.1 {Memory Leak} -constraints memory -setup {
+    proc getbytes {} {
+	set lines [split [memory info] \n]
+	lindex $lines 3 3
+    }
+} -body {
+    set end [getbytes]
+    for {set i 0} {$i < 5} {incr i} {
+	interp create slave
+	slave eval expr 1+2+3+4+5+6+7+8+9+10+11+12+13
+	interp delete slave
+	set tmp $end
+	set end [getbytes]
+    }
+    set leakedBytes [expr {$end - $tmp}]
+} -cleanup {
+    unset end i tmp
+    rename getbytes {}
+} -result 0
+
+test compExpr-7.2 {[Bug 1869989]: expr parser memleak} -constraints memory -setup {
+    proc getbytes {} {
+        set lines [split [memory info] \n]
+        lindex $lines 3 3
+    }
+} -body {
+    set i 5
+    set end [getbytes]
+    while {[incr i -1]} {
+        expr ${i}000
+        set tmp $end
+        set end [getbytes]
+    }
+    set leakedBytes [expr {$end - $tmp}]
+} -cleanup {
+    unset end i tmp
+    rename getbytes {}
+} -result 0
+
+# cleanup
+catch {unset a}
+catch {unset b}
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# fill-column: 78
+# End:
diff --git a/tests/compile.test b/tests/compile.test
new file mode 100644
index 0000000..f021cf2
--- /dev/null
+++ b/tests/compile.test
@@ -0,0 +1,1056 @@
+# This file contains tests for the files tclCompile.c, tclCompCmds.c and
+# tclLiteral.c
+#
+# This file contains a collection of tests for one or more of the Tcl built-in
+# commands. Sourcing this file into Tcl runs the tests and generates output
+# for errors. No output means no errors were found.
+#
+# Copyright (c) 1997 by Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution of
+# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+package require tcltest 2
+namespace import -force ::tcltest::*
+
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
+
+testConstraint exec       [llength [info commands exec]]
+testConstraint memory     [llength [info commands memory]]
+testConstraint testevalex [llength [info commands testevalex]]
+
+# The following tests are very incomplete, although the rest of the
+# test suite covers this file fairly well.
+
+catch {rename p ""}
+catch {namespace delete test_ns_compile}
+catch {unset x}
+catch {unset y}
+catch {unset a}
+
+test compile-1.1 {TclCompileString: look up cmds in proc ns, not current ns} -setup {
+    catch {namespace delete test_ns_compile}
+    catch {unset x}
+} -body {
+    set x 123
+    namespace eval test_ns_compile {
+        proc set {args} {
+            global x
+            lappend x test_ns_compile::set
+        }
+        proc p {} {
+            set 0
+        }
+    }
+    list [test_ns_compile::p] [set x]
+} -result {{123 test_ns_compile::set} {123 test_ns_compile::set}}
+test compile-1.2 {TclCompileString, error result is reset if TclGetLong determines word isn't an integer} {
+    proc p {x} {info commands 3m}
+    list [catch {p} msg] $msg
+} {1 {wrong # args: should be "p x"}}
+
+test compile-2.1 {TclCompileDollarVar: global scalar name with ::s} -setup {
+    catch {unset x}
+} -body {
+    set x 123
+    list $::x [expr {"x" in [info globals]}]
+} -result {123 1}
+test compile-2.2 {TclCompileDollarVar: global scalar name with ::s} -setup {
+    catch {unset y}
+} -body {
+    proc p {} {
+        set ::y 789
+        return $::y
+    }
+    list [p] $::y [expr {"y" in [info globals]}]
+} -result {789 789 1}
+test compile-2.3 {TclCompileDollarVar: global array name with ::s} -setup {
+    catch {unset a}
+} -body {
+    set ::a(1) 2
+    list $::a(1) [set ::a($::a(1)) 3] $::a(2) [expr {"a" in [info globals]}]
+} -result {2 3 3 1}
+test compile-2.4 {TclCompileDollarVar: global scalar name with ::s} -setup {
+    catch {unset a}
+} -body {
+    proc p {} {
+        set ::a(1) 1
+        return $::a($::a(1))
+    }
+    list [p] $::a(1) [expr {"a" in [info globals]}]
+} -result {1 1 1}
+test compile-2.5 {TclCompileDollarVar: global array, called as ${arrName(0)}} -setup {
+    catch {unset a}
+} -body {
+    proc p {} {
+	global a
+        set a(1) 1
+        return ${a(1)}$::a(1)$a(1)
+    }
+    list [p] $::a(1) [expr {"a" in [info globals]}]
+} -result {111 1 1}
+
+test compile-3.1 {TclCompileCatchCmd: only catch cmds with scalar vars are compiled inline} -setup {
+    catch {unset a}
+} -body {
+    set a(1) xyzzyx
+    proc p {} {
+        global a
+        catch {set x 123} a(1)
+    }
+    list [p] $a(1)
+} -result {0 123}
+test compile-3.2 {TclCompileCatchCmd: non-local variables} {
+    set ::foo 1
+    proc catch-test {} {
+	catch {set x 3} ::foo
+    }
+    catch-test
+    return $::foo
+} 3
+test compile-3.3 {TclCompileCatchCmd: overagressive compiling [bug 219184]} {
+    proc catch-test {str} {
+	catch [eval $str GOOD]
+	error BAD
+    }
+    catch {catch-test error} ::foo
+    return $::foo
+} {GOOD}
+test compile-3.4 {TclCompileCatchCmd: bcc'ed [return] is caught} {
+    proc foo {} {
+	set fail [catch {
+	    return 1
+	}] ; # {}	
+	return 2
+    }
+    foo
+} {2}
+test compile-3.5 {TclCompileCatchCmd: recover from error, [Bug 705406]} {
+    proc foo {} {
+	catch {
+	    if {[a]} {
+		if b {}
+	    }   
+	}   
+    }
+    list [catch foo msg] $msg
+} {0 1}
+test compile-3.6 {TclCompileCatchCmd: error in storing result [Bug 3098302]} {*}{
+     -setup {
+	 namespace eval catchtest {
+	     variable result1 {}
+	 }
+	 trace add variable catchtest::result1 write catchtest::failtrace
+	 proc catchtest::failtrace {n1 n2 op} {
+	     return -code error "trace on $n1 fails by request"
+	 }
+     }
+    -body {
+	proc catchtest::x {} {
+	    variable result1
+	    set count 0
+	    for {set i 0} {$i < 10} {incr i} {
+		set status2 [catch {
+		    set status1 [catch {
+			return -code error -level 0 "original failure"
+		    } result1 options1]
+		} result2 options2]
+		incr count
+	    }
+	    list $count $result2
+	}
+	catchtest::x
+    }
+    -result {10 {can't set "result1": trace on result1 fails by request}}
+    -cleanup {namespace delete catchtest}
+}
+
+test compile-3.7 {TclCompileCatchCmd: error in storing options [Bug 3098302]} {*}{
+     -setup {
+	 namespace eval catchtest {
+	     variable options1 {}
+	 }
+	 trace add variable catchtest::options1 write catchtest::failtrace
+	 proc catchtest::failtrace {n1 n2 op} {
+	     return -code error "trace on $n1 fails by request"
+	 }
+     }
+    -body {
+	proc catchtest::x {} {
+	    variable options1
+	    set count 0
+	    for {set i 0} {$i < 10} {incr i} {
+		set status2 [catch {
+		    set status1 [catch {
+			return -code error -level 0 "original failure"
+		    } result1 options1]
+		} result2 options2]
+		incr count
+	    }
+	    list $count $result2
+	}
+	catchtest::x
+    }
+    -result {10 {can't set "options1": trace on options1 fails by request}}
+    -cleanup {namespace delete catchtest}
+}
+
+test compile-4.1 {TclCompileForCmd: command substituted test expression} {
+    set i 0
+    set j 0
+    # Should be "forever"
+    for {} [expr $i < 3] {} {
+	set j [incr i]
+	if {$j > 3} break
+    }
+    set j
+} {4}
+
+test compile-5.1 {TclCompileForeachCmd: exception stack} {
+    proc foreach-exception-test {} {
+	foreach array(index) [list 1 2 3] break
+	foreach array(index) [list 1 2 3] break
+	foreach scalar [list 1 2 3] break
+    }
+    list [catch foreach-exception-test result] $result
+} {0 {}}
+test compile-5.2 {TclCompileForeachCmd: non-local variables} {
+    set ::foo 1
+    proc foreach-test {} {
+	foreach ::foo {1 2 3} {}
+    }
+    foreach-test
+    set ::foo
+} 3
+test compile-5.3 {TclCompileForeachCmd: [Bug b9b2079e6d]} -setup {
+    proc demo {} {
+	foreach x y {
+	    if 1 break else
+	}
+    }
+} -body {
+    demo
+} -cleanup {
+    rename demo {}
+} -returnCodes error -result {wrong # args: no script following "else" argument}
+
+test compile-6.1 {TclCompileSetCmd: global scalar names with ::s} -setup {
+    catch {unset x}
+    catch {unset y}
+} -body {
+    set x 123
+    proc p {} {
+        set ::y 789
+        return $::y
+    }
+    list $::x [expr {"x" in [info globals]}] \
+         [p] $::y [expr {"y" in [info globals]}]
+} -result {123 1 789 789 1}
+test compile-6.2 {TclCompileSetCmd: global array names with ::s} -setup {
+    catch {unset a}
+} -body {
+    set ::a(1) 2
+    proc p {} {
+        set ::a(1) 1
+        return $::a($::a(1))
+    }
+    list $::a(1) [p] [set ::a($::a(1)) 3] $::a(1) [expr {"a" in [info globals]}]
+} -result {2 1 3 3 1}
+test compile-6.3 {TclCompileSetCmd: namespace var names with ::s} -setup {
+    catch {namespace delete test_ns_compile}
+    catch {unset x}
+} -body {
+    namespace eval test_ns_compile {
+        variable v hello
+        variable arr
+        set ::x $::test_ns_compile::v
+	set ::test_ns_compile::arr(1) 123
+    }
+    list $::x $::test_ns_compile::arr(1)
+} -result {hello 123}
+
+test compile-7.1 {TclCompileWhileCmd: command substituted test expression} {
+    set i 0
+    set j 0
+    # Should be "forever"
+    while [expr $i < 3] {
+	set j [incr i]
+	if {$j > 3} break
+    }
+    set j
+} {4}
+
+test compile-8.1 {CollectArgInfo: binary data} {
+    list [catch "string length \000foo" msg] $msg
+} {0 4}
+test compile-8.2 {CollectArgInfo: binary data} {
+    list [catch "string length foo\000" msg] $msg
+} {0 4}
+test compile-8.3 {CollectArgInfo: handle "]" at end of command properly} {
+    set x ]
+} {]}
+
+test compile-9.1 {UpdateStringOfByteCode: called for duplicate of compiled empty object} {
+    proc p {} {
+        set x {}
+        eval $x
+        append x { }
+        eval $x
+    }
+    p
+} {}
+
+test compile-10.1 {BLACKBOX: exception stack overflow} {
+    set x {{0}}
+    set y 0
+    while {$y < 100} {
+	if !$x {incr y}
+    }
+} {}
+
+test compile-11.1 {Tcl_Append*: ensure Tcl_ResetResult is used properly} -body {
+    apply {{} {
+	# shared object - Interp result && Var 'r'
+	set r [list foobar]
+	# command that will add error to result
+	lindex a bogus
+    }}
+} -returnCodes error -result {bad index "bogus": must be integer?[+-]integer? or end?[+-]integer?}
+test compile-11.2 {Tcl_Append*: ensure Tcl_ResetResult is used properly} -body {
+    apply {{} { set r [list foobar] ; string index a bogus }}
+} -returnCodes error -result {bad index "bogus": must be integer?[+-]integer? or end?[+-]integer?}
+test compile-11.3 {Tcl_Append*: ensure Tcl_ResetResult is used properly} -body {
+    apply {{} { set r [list foobar] ; string index a 0o9 }}
+} -returnCodes error -match glob -result {*invalid octal number*}
+test compile-11.4 {Tcl_Append*: ensure Tcl_ResetResult is used properly} -body {
+    apply {{} { set r [list foobar] ; array set var {one two many} }}
+} -returnCodes error -result {list must have an even number of elements}
+test compile-11.5 {Tcl_Append*: ensure Tcl_ResetResult is used properly} -body {
+    apply {{} { set r [list foobar] ; incr foo bar baz}}
+} -returnCodes error -result {wrong # args: should be "incr varName ?increment?"}
+test compile-11.6 {Tcl_Append*: ensure Tcl_ResetResult is used properly} -body {
+    apply {{} { set r [list foobar] ; incr}}
+} -returnCodes error -result {wrong # args: should be "incr varName ?increment?"}
+test compile-11.7 {Tcl_Append*: ensure Tcl_ResetResult is used properly} -body {
+    apply {{} { set r [list foobar] ; expr !a }}
+} -returnCodes error -match glob -result *
+test compile-11.8 {Tcl_Append*: ensure Tcl_ResetResult is used properly} -body {
+    apply {{} { set r [list foobar] ; expr {!a} }}
+} -returnCodes error -match glob -result *
+test compile-11.9 {Tcl_Append*: ensure Tcl_ResetResult is used properly} -body {
+    apply {{} { set r [list foobar] ; llength "\{" }}
+    list [catch {p} msg] $msg
+} -returnCodes error -result {unmatched open brace in list}
+
+# 
+# Special section for tests of tclLiteral.c
+# The following tests check for incorrect memory handling in
+# TclReleaseLiteral. They are only effective when tcl is compiled with
+# TCL_MEM_DEBUG
+#
+# Special test for leak on interp delete [Bug 467523]. 
+test compile-12.1 {testing literal leak on interp delete} -setup {
+    proc getbytes {} {
+	set lines [split [memory info] "\n"]
+	lindex $lines 3 3
+    }
+} -constraints memory -body {
+    set end [getbytes]
+    for {set i 0} {$i < 5} {incr i} {
+	interp create foo 
+	foo eval { 
+	    namespace eval bar {}
+	} 
+	interp delete foo
+	set tmp $end
+	set end [getbytes]
+    }
+    set leakedBytes [expr {$end - $tmp}]
+} -cleanup {
+    rename getbytes {}
+    unset -nocomplain end i tmp leakedBytes
+} -result 0
+# Special test for a memory error in a preliminary fix of [Bug 467523].  It
+# requires executing a helpfile.  Presumably the child process is used because
+# when this test fails, it crashes.
+test compile-12.2 {testing error on literal deletion} -constraints {memory exec} -body {
+    set sourceFile [makeFile {
+	for {set i 0} {$i < 5} {incr i} {
+	    namespace eval bar {}
+	    namespace delete bar
+	}
+	puts 0
+    } source.file]
+    exec [interpreter] $sourceFile 
+} -cleanup {
+    catch {removeFile $sourceFile}
+} -result 0
+# Test to catch buffer overrun in TclCompileTokens from buf 530320
+test compile-12.3 {check for a buffer overrun} -body {
+    proc crash {} {
+	puts $array([expr {a+2}])
+    }
+    crash
+} -returnCodes error -cleanup {
+    rename crash {}
+} -match glob -result *
+test compile-12.4 {TclCleanupLiteralTable segfault} -body {
+    # Tcl Bug 1001997
+    # Here, we're trying to test a case that causes a crash in
+    # TclCleanupLiteralTable.  The conditions that we're trying to establish
+    # are:
+    # - TclCleanupLiteralTable is attempting to clean up a bytecode object in
+    #   the literal table.
+    # - The bytecode object in question contains the only reference to another
+    #   literal.
+    # - The literal in question is in the same hash bucket as the bytecode
+    #   object, and immediately follows it in the chain.
+    # Since newly registered literals are added at the FRONT of the bucket
+    # chains, and since the bytecode object is registered before its literals,
+    # this is difficult to achieve.  What we do is:
+    #  (a) do a [namespace eval] of a string that's calculated to hash into
+    #      the same bucket as a literal that it contains.  In this case, the
+    #      script and the variable 'bugbug' land in the same bucket.
+    #  (b) do a [namespace eval] of a string that contains enough literals to
+    #      force TclRegisterLiteral to rebuild the global literal table.  The
+    #      newly created hash buckets will contain the literals, IN REVERSE
+    #      ORDER, thus putting the bytecode immediately ahead of 'bugbug' and
+    #      'bug4345bug'.  The bytecode object will contain the only references
+    #      to those two literals.
+    #  (c) Delete the interpreter to invoke TclCleanupLiteralTable and tickle
+    #      the bug.
+    proc foo {} {
+	set i [interp create]
+	$i eval {
+	    namespace eval ::w {concat 4649; variable bugbug}
+	    namespace eval ::w {
+		concat x1 x2 x3 x4 x5 x6 x7 x8 x9 x10 \
+		    x11 x12 x13 x14 x15 x16 x17 x18 x19 x20 \
+		    x21 x22 x23 x24 x25 x26 x27 x28 x29 x30 \
+		    x31 x32 X33 X34 X35 X36 X37 X38 X39 X40 \
+		    x41 x42 x43 x44 x45 x46 x47 x48 x49 x50 \
+		    x51 x52 x53 x54 x55 x56 x57 x58 x59 x60 \
+		    x61 x62 x63 x64
+		concat y1 y2 y3 y4 y5 y6 y7 y8 y9 y10 \
+		    y11 y12 y13 y14 y15 y16 y17 y18 y19 y20 \
+		    y21 y22 y23 y24 y25 y26 y27 y28 y29 y30 \
+		    y31 y32 Y33 Y34 Y35 Y36 Y37 Y38 Y39 Y40 \
+		    y41 y42 y43 y44 y45 y46 y47 y48 y49 y50 \
+		    y51 y52 y53 y54 y55 y56 y57 y58 y59 y60 \
+		    y61 y62 y63 y64
+		concat z1 z2 z3 z4 z5 z6 z7 z8 z9 z10 \
+		    z11 z12 z13 z14 z15 z16 z17 z18 z19 z20 \
+		    z21 z22 z23 z24 z25 z26 z27 z28 z29 z30 \
+		    z31 z32
+	    }
+	}
+	interp delete $i; # must not crash
+	return ok
+    }
+    foo
+} -cleanup {
+    rename foo {}
+} -result ok
+
+# Special test for underestimating the maxStackSize required for a compiled
+# command. A failure will cause a segfault in the child process.
+test compile-13.1 {testing underestimate of maxStackSize in list cmd} {exec} {
+    set body {set x [list}
+    for {set i 0} {$i < 3000} {incr i} {
+	append body " $i"
+    }
+    append body {]; puts OK}
+    regsub BODY {proc crash {} {BODY}; crash} $body script
+    list [catch {exec [interpreter] << $script} msg] $msg
+} {0 OK}
+
+# Tests compile-14.* for [Bug 599788] [Bug 0c043a175a47da8c2342]
+test compile-14.1 {testing errors in element name; segfault?} {} {
+     catch {set a([error])} msg1
+     catch {set bubba([join $abba $jubba]) $vol} msg2
+     list $msg1 $msg2
+} {{wrong # args: should be "error message ?errorInfo? ?errorCode?"} {can't read "abba": no such variable}}
+
+test compile-14.2 {testing element name "$"} -body {
+    unset -nocomplain a
+    set a() 1
+    set a(1) 2 
+    set a($) 3
+    list [set a()] [set a(1)] [set a($)] [unset a() a(1); lindex [array names a] 0]
+} -cleanup {unset a} -result [list 1 2 3 {$}]
+
+
+# Tests compile-15.* cover Tcl Bug 633204
+test compile-15.1 {proper TCL_RETURN code from [return]} {
+    apply {{} {catch return}}
+} 2
+test compile-15.2 {proper TCL_RETURN code from [return]} {
+    apply {{} {catch {return foo}}}
+} 2
+test compile-15.3 {proper TCL_RETURN code from [return]} {
+    apply {{} {catch {return $::tcl_library}}}
+} 2
+test compile-15.4 {proper TCL_RETURN code from [return]} {
+    apply {{} {catch {return [info library]}}}
+} 2
+test compile-15.5 {proper TCL_RETURN code from [return]} {
+    apply {{} {catch {set a 1}; return}}
+} ""
+
+for {set noComp 0} {$noComp <= 1} {incr noComp} {
+
+if $noComp {
+    interp alias {} run {} testevalex
+    set constraints testevalex
+} else {
+    interp alias {} run {} if 1
+    set constraints {}
+}
+
+test compile-16.1.$noComp {TclCompileScript: word expansion} $constraints {
+    run "list [string repeat {{*}a } 255]"
+} [lrepeat 255 a]
+test compile-16.2.$noComp {TclCompileScript: word expansion} $constraints {
+    run "list [string repeat {{*}a } 256]"
+} [lrepeat 256 a]
+test compile-16.3.$noComp {TclCompileScript: word expansion} $constraints {
+    run "list [string repeat {{*}a } 257]"
+} [lrepeat 257 a]
+test compile-16.4.$noComp {TclCompileScript: word expansion} $constraints {
+    run {{*}list}
+} {}
+test compile-16.5.$noComp {TclCompileScript: word expansion} $constraints {
+    run {{*}list {*}{x y z}}
+} {x y z}
+test compile-16.6.$noComp {TclCompileScript: word expansion} $constraints {
+    run {{*}list {*}[list x y z]}
+} {x y z}
+test compile-16.7.$noComp {TclCompileScript: word expansion} $constraints {
+    run {{*}list {*}[list x y z][list x y z]}
+} {x y zx y z}
+test compile-16.8.$noComp {TclCompileScript: word expansion} -body {
+    set l {x y z}
+    run {{*}list {*}$l}
+} -constraints $constraints -cleanup {
+    unset l
+} -result {x y z}
+test compile-16.9.$noComp {TclCompileScript: word expansion} -body {
+    set l {x y z}
+    run {{*}list {*}$l$l}
+} -constraints $constraints -cleanup {
+    unset l
+} -result {x y zx y z}
+test compile-16.10.$noComp {TclCompileScript: word expansion} -body {
+    run {{*}\{}
+} -constraints $constraints -returnCodes error \
+-result {unmatched open brace in list}
+test compile-16.11.$noComp {TclCompileScript: word expansion} -body {
+    proc badList {} {return \{}
+    run {{*}[badList]}
+} -constraints $constraints -cleanup {
+    rename badList {}
+} -returnCodes error  -result {unmatched open brace in list}
+test compile-16.12.$noComp {TclCompileScript: word expansion} $constraints {
+    run {{*}list x y z}
+} {x y z}
+test compile-16.13.$noComp {TclCompileScript: word expansion} $constraints {
+    run {{*}list x y {*}z}
+} {x y z}
+test compile-16.14.$noComp {TclCompileScript: word expansion} $constraints {
+    run {{*}list x {*}y z}
+} {x y z}
+test compile-16.15.$noComp {TclCompileScript: word expansion} $constraints {
+    run {list x y {*}z}
+} {x y z}
+test compile-16.16.$noComp {TclCompileScript: word expansion} $constraints {
+    run {list x {*}y z}
+} {x y z}
+test compile-16.17.$noComp {TclCompileScript: word expansion} $constraints {
+    run {list {*}x y z}
+} {x y z}
+
+# These tests note that expansion can in theory cause the number of arguments
+# to a command to exceed INT_MAX, which is as big as objc is allowed to get.
+#
+# In practice, it seems we will run out of memory before we confront this
+# issue. Note that compiled operations run out of memory at smaller objc
+# values than direct string evaluation.
+#
+# These tests are constrained as knownBug because they are likely to cause
+# memory allocation panics somewhere, and we don't want panics in the test
+# suite.
+#
+test compile-16.18.$noComp {TclCompileScript: word expansion} -body {
+    proc LongList {} {return [lrepeat [expr {1<<10}] x]}
+    llength [run "list [string repeat {{*}[LongList] } [expr {1<<10}]]"]
+} -constraints [linsert $constraints 0 knownBug] -cleanup {
+    rename LongList {}
+} -returnCodes ok  -result [expr {1<<20}]
+test compile-16.19.$noComp {TclCompileScript: word expansion} -body {
+    proc LongList {} {return [lrepeat [expr {1<<11}] x]}
+    llength [run "list [string repeat {{*}[LongList] } [expr {1<<11}]]"]
+} -constraints [linsert $constraints 0 knownBug] -cleanup {
+    rename LongList {}
+} -returnCodes ok  -result [expr {1<<22}]
+test compile-16.20.$noComp {TclCompileScript: word expansion} -body {
+    proc LongList {} {return [lrepeat [expr {1<<12}] x]}
+    llength [run "list [string repeat {{*}[LongList] } [expr {1<<12}]]"]
+} -constraints [linsert $constraints 0 knownBug] -cleanup {
+    rename LongList {}
+} -returnCodes ok  -result [expr {1<<24}]
+# This is the one that should cause overflow
+test compile-16.21.$noComp {TclCompileScript: word expansion} -body {
+    proc LongList {} {return [lrepeat [expr {1<<16}] x]}
+    llength [run "list [string repeat {{*}[LongList] } [expr {1<<16}]]"]
+} -constraints [linsert $constraints 0 knownBug] -cleanup {
+    rename LongList {}
+} -returnCodes ok  -result [expr {wide(1)<<32}]
+test compile-16.22.$noComp {
+    Bug 845412: TclCompileScript: word expansion not mandatory
+} -body {
+    # This test may crash and will fail unless Bug 845412 is fixed.
+    proc ReturnResults args {return $args}
+    run "ReturnResults [string repeat {x } 260]"
+} -constraints $constraints -cleanup {
+    rename ReturnResults {}
+} -returnCodes ok -result [string trim [string repeat {x } 260]]
+test compile-16.23.$noComp {
+    Bug 1032805: defer parse error until run time
+} -constraints $constraints -body {
+    namespace eval x {
+	run {
+	    proc if {a b} {uplevel 1 [list set $a $b]}
+	    if 1 {syntax {}{}}
+	}
+    }
+} -cleanup {
+    namespace delete x
+} -returnCodes ok -result {syntax {}{}}
+test compile-16.24.$noComp {
+    Bug 1638414: bad list constant as first expanded term
+} -constraints $constraints -body {
+    run "{*}\"\{foo bar\""
+} -returnCodes error -result {unmatched open brace in list}
+test compile-16.25.$noComp {TclCompileScript: word expansion, naked backslashes} $constraints {
+    run {list {*}{a \n b}}
+} {a {
+} b}
+test compile-16.26.$noComp {TclCompileScript: word expansion, protected backslashes} $constraints {
+    run {list {*}{a {\n} b}}
+} {a {\n} b}
+}	;# End of noComp loop
+
+# These tests are messy because it wrecks the interpreter it runs in!  They
+# demonstrate issues arising from [FRQ 1101710]
+test compile-17.1 {Command interpretation binding for compiled code} -constraints knownBug -setup {
+    set i [interp create]
+} -body {
+    $i eval {
+	if 1 {
+	    expr [
+		proc expr args {return substituted}
+		format {[subst compiled]}
+	    ]
+	}
+    }
+} -cleanup {
+    interp delete $i
+} -result substituted
+test compile-17.2 {Command interpretation binding for non-compiled code} -setup {
+    set i [interp create]
+} -body {
+    $i eval {
+	if 1 {
+	    [subst expr] [
+		proc expr args {return substituted}
+		format {[subst compiled]}
+	    ]
+	}
+    }
+} -cleanup {
+    interp delete $i
+} -result substituted
+
+# This tests the supported parts of the unsupported [disassemble] command. It
+# does not check the format of disassembled bytecode though; that's liable to
+# change without warning.
+
+set disassemblables [linsert [join {
+    constructor destructor lambda method objmethod proc script
+} ", "] end-1 or]
+test compile-18.1 {disassembler - basics} -returnCodes error -body {
+    tcl::unsupported::disassemble
+} -match glob -result {wrong # args: should be "*"}
+test compile-18.2 {disassembler - basics} -returnCodes error -body {
+    tcl::unsupported::disassemble ?
+} -result "bad type \"?\": must be $disassemblables"
+test compile-18.3 {disassembler - basics} -returnCodes error -body {
+    tcl::unsupported::disassemble lambda
+} -match glob -result {wrong # args: should be "* lambda lambdaTerm"}
+test compile-18.4 {disassembler - basics} -returnCodes error -body {
+    tcl::unsupported::disassemble lambda \{
+} -result "can't interpret \"\{\" as a lambda expression"
+test compile-18.5 {disassembler - basics} -body {
+    # Allow any string: the result format is not defined anywhere!
+    tcl::unsupported::disassemble lambda {{} {}}
+} -match glob -result *
+test compile-18.6 {disassembler - basics} -returnCodes error -body {
+    tcl::unsupported::disassemble proc
+} -match glob -result {wrong # args: should be "* proc procName"}
+test compile-18.7 {disassembler - basics} -returnCodes error -body {
+    tcl::unsupported::disassemble proc nosuchproc
+} -result {"nosuchproc" isn't a procedure}
+test compile-18.8 {disassembler - basics} -setup {
+    proc chewonthis {} {}
+} -body {
+    # Allow any string: the result format is not defined anywhere!
+    tcl::unsupported::disassemble proc chewonthis
+} -cleanup {
+    rename chewonthis {}
+} -match glob -result *
+test compile-18.9 {disassembler - basics} -returnCodes error -body {
+    tcl::unsupported::disassemble script
+} -match glob -result {wrong # args: should be "* script script"}
+test compile-18.10 {disassembler - basics} -body {
+    # Allow any string: the result format is not defined anywhere!
+    tcl::unsupported::disassemble script {}
+} -match glob -result *
+test compile-18.11 {disassembler - basics} -returnCodes error -body {
+    tcl::unsupported::disassemble method
+} -match glob -result {wrong # args: should be "* method className methodName"}
+test compile-18.12 {disassembler - basics} -returnCodes error -body {
+    tcl::unsupported::disassemble method nosuchclass foo
+} -result {nosuchclass does not refer to an object}
+test compile-18.13 {disassembler - basics} -returnCodes error -setup {
+    oo::object create justanobject
+} -body {
+    tcl::unsupported::disassemble method justanobject foo
+} -cleanup {
+    justanobject destroy
+} -result {"justanobject" is not a class}
+test compile-18.14 {disassembler - basics} -returnCodes error -body {
+    tcl::unsupported::disassemble method oo::object nosuchmethod
+} -result {unknown method "nosuchmethod"}
+test compile-18.15 {disassembler - basics} -setup {
+    oo::class create foo {method bar {} {}}
+} -body {
+    # Allow any string: the result format is not defined anywhere!
+    tcl::unsupported::disassemble method foo bar
+} -cleanup {
+    foo destroy
+} -match glob -result *
+test compile-18.16 {disassembler - basics} -returnCodes error -body {
+    tcl::unsupported::disassemble objmethod
+} -match glob -result {wrong # args: should be "* objmethod objectName methodName"}
+test compile-18.17 {disassembler - basics} -returnCodes error -body {
+    tcl::unsupported::disassemble objmethod nosuchobject foo
+} -result {nosuchobject does not refer to an object}
+test compile-18.18 {disassembler - basics} -returnCodes error -body {
+    tcl::unsupported::disassemble objmethod oo::object nosuchmethod
+} -result {unknown method "nosuchmethod"}
+test compile-18.19 {disassembler - basics} -setup {
+    oo::object create foo
+    oo::objdefine foo {method bar {} {}}
+} -body {
+    # Allow any string: the result format is not defined anywhere!
+    tcl::unsupported::disassemble objmethod foo bar
+} -cleanup {
+    foo destroy
+} -match glob -result *
+# There never was a compile-18.20.
+# The keys of the dictionary produced by [getbytecode] are defined.
+set bytecodekeys {literals variables exception instructions auxiliary commands script namespace stackdepth exceptdepth}
+test compile-18.21 {disassembler - basics} -returnCodes error -body {
+    tcl::unsupported::getbytecode
+} -match glob -result {wrong # args: should be "*"}
+test compile-18.22 {disassembler - basics} -returnCodes error -body {
+    tcl::unsupported::getbytecode ?
+} -result "bad type \"?\": must be $disassemblables"
+test compile-18.23 {disassembler - basics} -returnCodes error -body {
+    tcl::unsupported::getbytecode lambda
+} -match glob -result {wrong # args: should be "* lambda lambdaTerm"}
+test compile-18.24 {disassembler - basics} -returnCodes error -body {
+    tcl::unsupported::getbytecode lambda \{
+} -result "can't interpret \"\{\" as a lambda expression"
+test compile-18.25 {disassembler - basics} -body {
+    dict keys [tcl::unsupported::getbytecode lambda {{} {}}]
+} -result "$bytecodekeys initiallinenumber sourcefile"
+test compile-18.26 {disassembler - basics} -returnCodes error -body {
+    tcl::unsupported::getbytecode proc
+} -match glob -result {wrong # args: should be "* proc procName"}
+test compile-18.27 {disassembler - basics} -returnCodes error -body {
+    tcl::unsupported::getbytecode proc nosuchproc
+} -result {"nosuchproc" isn't a procedure}
+test compile-18.28 {disassembler - basics} -setup {
+    proc chewonthis {} {}
+} -body {
+    dict keys [tcl::unsupported::getbytecode proc chewonthis]
+} -cleanup {
+    rename chewonthis {}
+} -result "$bytecodekeys initiallinenumber sourcefile"
+test compile-18.28.1 {disassembler - tricky bit} -setup {
+    eval [list proc chewonthis {} {}]
+} -body {
+    dict keys [tcl::unsupported::getbytecode proc chewonthis]
+} -cleanup {
+    rename chewonthis {}
+} -result $bytecodekeys
+test compile-18.28.2 {disassembler - tricky bit} -setup {
+    eval {proc chewonthis {} {}}
+} -body {
+    dict keys [tcl::unsupported::getbytecode proc chewonthis]
+} -cleanup {
+    rename chewonthis {}
+} -result "$bytecodekeys initiallinenumber sourcefile"
+test compile-18.28.3 {disassembler - tricky bit} -setup {
+    proc Proc {n a b} {
+	proc $n $a $b
+    }
+    Proc chewonthis {} {}
+} -body {
+    dict keys [tcl::unsupported::getbytecode proc chewonthis]
+} -cleanup {
+    rename Proc {}
+    rename chewonthis {}
+} -result $bytecodekeys
+test compile-18.28.4 {disassembler - tricky bit} -setup {
+    proc Proc {n a b} {
+	tailcall proc $n $a $b
+    }
+    Proc chewonthis {} {}
+} -body {
+    dict keys [tcl::unsupported::getbytecode proc chewonthis]
+} -cleanup {
+    rename Proc {}
+    rename chewonthis {}
+} -result "$bytecodekeys initiallinenumber sourcefile"
+test compile-18.29 {disassembler - basics} -returnCodes error -body {
+    tcl::unsupported::getbytecode script
+} -match glob -result {wrong # args: should be "* script script"}
+test compile-18.30 {disassembler - basics} -body {
+    dict keys [tcl::unsupported::getbytecode script {}]
+} -result $bytecodekeys
+test compile-18.31 {disassembler - basics} -returnCodes error -body {
+    tcl::unsupported::getbytecode method
+} -match glob -result {wrong # args: should be "* method className methodName"}
+test compile-18.32 {disassembler - basics} -returnCodes error -body {
+    tcl::unsupported::getbytecode method nosuchclass foo
+} -result {nosuchclass does not refer to an object}
+test compile-18.33 {disassembler - basics} -returnCodes error -setup {
+    oo::object create justanobject
+} -body {
+    tcl::unsupported::getbytecode method justanobject foo
+} -cleanup {
+    justanobject destroy
+} -result {"justanobject" is not a class}
+test compile-18.34 {disassembler - basics} -returnCodes error -body {
+    tcl::unsupported::getbytecode method oo::object nosuchmethod
+} -result {unknown method "nosuchmethod"}
+test compile-18.35 {disassembler - basics} -setup {
+    oo::class create foo {method bar {} {}}
+} -body {
+    dict keys [tcl::unsupported::getbytecode method foo bar]
+} -cleanup {
+    foo destroy
+} -result "$bytecodekeys initiallinenumber sourcefile"
+test compile-18.36 {disassembler - basics} -returnCodes error -body {
+    tcl::unsupported::getbytecode objmethod
+} -match glob -result {wrong # args: should be "* objmethod objectName methodName"}
+test compile-18.37 {disassembler - basics} -returnCodes error -body {
+    tcl::unsupported::getbytecode objmethod nosuchobject foo
+} -result {nosuchobject does not refer to an object}
+test compile-18.38 {disassembler - basics} -returnCodes error -body {
+    tcl::unsupported::getbytecode objmethod oo::object nosuchmethod
+} -result {unknown method "nosuchmethod"}
+test compile-18.39 {disassembler - basics} -setup {
+    oo::object create foo
+    oo::objdefine foo {method bar {} {}}
+} -body {
+    dict keys [tcl::unsupported::getbytecode objmethod foo bar]
+} -cleanup {
+    foo destroy
+} -result "$bytecodekeys initiallinenumber sourcefile"
+test compile-18.40 {disassembler - basics} -returnCodes error -body {
+    tcl::unsupported::disassemble constructor
+} -match glob -result {wrong # args: should be "* constructor className"}
+test compile-18.41 {disassembler - basics} -returnCodes error -body {
+    tcl::unsupported::disassemble constructor nosuchclass
+} -result {nosuchclass does not refer to an object}
+test compile-18.42 {disassembler - basics} -returnCodes error -setup {
+    oo::object create justanobject
+} -body {
+    tcl::unsupported::disassemble constructor justanobject
+} -cleanup {
+    justanobject destroy
+} -result {"justanobject" is not a class}
+test compile-18.43 {disassembler - basics} -returnCodes error -setup {
+    oo::class create constructorless
+} -body {
+    tcl::unsupported::disassemble constructor constructorless
+} -cleanup {
+    constructorless destroy
+} -result {"constructorless" has no defined constructor}
+test compile-18.44 {disassembler - basics} -setup {
+    oo::class create foo {constructor {} {set x 1}}
+} -body {
+    # Allow any string: the result format is not defined anywhere!
+    tcl::unsupported::disassemble constructor foo
+} -cleanup {
+    foo destroy
+} -match glob -result *
+test compile-18.45 {disassembler - basics} -returnCodes error -body {
+    tcl::unsupported::getbytecode constructor
+} -match glob -result {wrong # args: should be "* constructor className"}
+test compile-18.46 {disassembler - basics} -returnCodes error -body {
+    tcl::unsupported::getbytecode constructor nosuchobject
+} -result {nosuchobject does not refer to an object}
+test compile-18.47 {disassembler - basics} -returnCodes error -setup {
+    oo::class create constructorless
+} -body {
+    tcl::unsupported::getbytecode constructor constructorless
+} -cleanup {
+    constructorless destroy
+} -result {"constructorless" has no defined constructor}
+test compile-18.48 {disassembler - basics} -setup {
+    oo::class create foo {constructor {} {set x 1}}
+} -body {
+    dict keys [tcl::unsupported::getbytecode constructor foo]
+} -cleanup {
+    foo destroy
+} -result "$bytecodekeys"
+# There is no compile-18.49
+test compile-18.50 {disassembler - basics} -returnCodes error -body {
+    tcl::unsupported::disassemble destructor
+} -match glob -result {wrong # args: should be "* destructor className"}
+test compile-18.51 {disassembler - basics} -returnCodes error -body {
+    tcl::unsupported::disassemble destructor nosuchclass
+} -result {nosuchclass does not refer to an object}
+test compile-18.52 {disassembler - basics} -returnCodes error -setup {
+    oo::object create justanobject
+} -body {
+    tcl::unsupported::disassemble destructor justanobject
+} -cleanup {
+    justanobject destroy
+} -result {"justanobject" is not a class}
+test compile-18.53 {disassembler - basics} -returnCodes error -setup {
+    oo::class create constructorless
+} -body {
+    tcl::unsupported::disassemble destructor constructorless
+} -cleanup {
+    constructorless destroy
+} -result {"constructorless" has no defined destructor}
+test compile-18.54 {disassembler - basics} -setup {
+    oo::class create foo {destructor {set x 1}}
+} -body {
+    # Allow any string: the result format is not defined anywhere!
+    tcl::unsupported::disassemble destructor foo
+} -cleanup {
+    foo destroy
+} -match glob -result *
+test compile-18.55 {disassembler - basics} -returnCodes error -body {
+    tcl::unsupported::getbytecode destructor
+} -match glob -result {wrong # args: should be "* destructor className"}
+test compile-18.56 {disassembler - basics} -returnCodes error -body {
+    tcl::unsupported::getbytecode destructor nosuchobject
+} -result {nosuchobject does not refer to an object}
+test compile-18.57 {disassembler - basics} -returnCodes error -setup {
+    oo::class create constructorless
+} -body {
+    tcl::unsupported::getbytecode destructor constructorless
+} -cleanup {
+    constructorless destroy
+} -result {"constructorless" has no defined destructor}
+test compile-18.58 {disassembler - basics} -setup {
+    oo::class create foo {destructor {set x 1}}
+} -body {
+    dict keys [tcl::unsupported::getbytecode destructor foo]
+} -cleanup {
+    foo destroy
+} -result "$bytecodekeys"
+
+test compile-19.0 {Bug 3614102: reset stack housekeeping} -body {
+    # This will panic in a --enable-symbols=compile build, unless bug is fixed.
+    apply {{} {list [if 1]}}
+} -returnCodes error -match glob -result *
+
+test compile-20.1 {ensure there are no infinite loops in optimizing} {
+    tcl::unsupported::disassemble script {
+	while 1 {
+	    return -code continue -level 0
+	}
+    }
+    return
+} {}
+test compile-20.2 {ensure there are no infinite loops in optimizing} {
+    tcl::unsupported::disassemble script {
+	while 1 {
+	    while 1 {
+		return -code break -level 0
+	    }
+	}
+    }
+    return
+} {}
+
+test compile-21.1 {stack balance management} {
+    apply {{} {
+	set result {}
+	while 1 {
+	    lappend result a
+	    lappend result [list b [break]]
+	    lappend result c
+	}
+	return $result
+    }}
+} a
+test compile-21.2 {stack balance management} {
+    apply {{} {
+	set result {}
+	while {[incr i] <= 10} {
+	    lappend result $i
+	    lappend result [list b [continue] c]
+	    lappend result c
+	}
+	return $result
+    }}
+} {1 2 3 4 5 6 7 8 9 10}
+test compile-21.3 {stack balance management} {
+    apply {args {
+	set result {}
+	while 1 {
+	    lappend result a
+	    lappend result [concat {*}$args [break]]
+	    lappend result c
+	}
+	return $result
+    }} P Q R S T
+} a
+test compile-21.4 {stack balance management} {
+    apply {args {
+	set result {}
+	while {[incr i] <= 10} {
+	    lappend result $i
+	    lappend result [concat {*}$args [continue] c]
+	    lappend result c
+	}
+	return $result
+    }} P Q R S T
+} {1 2 3 4 5 6 7 8 9 10}
+
+# TODO sometime - check that bytecode from tbcload is *not* disassembled.
+
+# cleanup
+catch {rename p ""}
+catch {namespace delete test_ns_compile}
+catch {unset x}
+catch {unset y}
+catch {unset a}
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# fill-column: 78
+# End:
diff --git a/tests/concat.test b/tests/concat.test
new file mode 100644
index 0000000..eeb11ca
--- /dev/null
+++ b/tests/concat.test
@@ -0,0 +1,57 @@
+# Commands covered:  concat
+#
+# This file contains a collection of tests for one or more of the Tcl built-in
+# commands.  Sourcing this file into Tcl runs the tests and generates output
+# for errors.  No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994-1996 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution of
+# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {"::tcltest" ni [namespace children]} {
+    package require tcltest
+    namespace import -force ::tcltest::*
+}
+
+test concat-1.1 {simple concatenation} {
+    concat a b c d e f g
+} {a b c d e f g}
+test concat-1.2 {merging lists together} {
+    concat a {b c d} {e f g h}
+} {a b c d e f g h}
+test concat-1.3 {merge lists, retain sub-lists} {
+    concat a {b {c d}} {{e f}} g h
+} {a b {c d} {e f} g h}
+test concat-1.4 {special characters} {
+    concat a\{ {b \{c d} \{d
+} "a{ b \\{c d {d"
+
+test concat-2.1 {error: one empty argument} {
+    concat {}
+} {}
+
+test concat-3.1 {error: no arguments} {
+    list [catch concat msg] $msg
+} {0 {}}
+
+test concat-4.1 {pruning off extra white space} {
+    concat {} {a b c}
+} {a b c}
+test concat-4.2 {pruning off extra white space} {
+    concat x y "  a b c	\n\t  " "   "  " def "
+} {x y a b c def}
+test concat-4.3 {pruning off extra white space sets length correctly} {
+    llength [concat { {{a}} }]
+} 1
+
+# cleanup
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# fill-column: 78
+# End:
diff --git a/tests/config.test b/tests/config.test
new file mode 100644
index 0000000..d14837e
--- /dev/null
+++ b/tests/config.test
@@ -0,0 +1,60 @@
+# -*- tcl -*-
+# Commands covered:  pkgconfig
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands.  Sourcing this file into Tcl runs the tests and
+# generates output for errors.  No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994-1996 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+    package require tcltest
+    namespace import -force ::tcltest::*
+}
+
+test pkgconfig-1.1 {query keys} {
+    lsort [::tcl::pkgconfig list]
+} {64bit bindir,install bindir,runtime compile_debug compile_stats debug docdir,install docdir,runtime includedir,install includedir,runtime libdir,install libdir,runtime mem_debug optimized profiled scriptdir,install scriptdir,runtime threaded}
+test pkgconfig-1.2 {query keys multiple times} {
+    string compare [::tcl::pkgconfig list] [::tcl::pkgconfig list]
+} 0
+test pkgconfig-1.3 {query value multiple times} {
+    string compare \
+	    [::tcl::pkgconfig get bindir,install] \
+	    [::tcl::pkgconfig get bindir,install]
+} 0
+
+
+test pkgconfig-2.0 {error: missing subcommand} {
+    catch {::tcl::pkgconfig} msg
+    set msg
+} {wrong # args: should be "::tcl::pkgconfig subcommand ?arg?"}
+test pkgconfig-2.1 {error: illegal subcommand} {
+    catch {::tcl::pkgconfig foo} msg
+    set msg
+} {bad subcommand "foo": must be get or list}
+test pkgconfig-2.2 {error: list with arguments} {
+    catch {::tcl::pkgconfig list foo} msg
+    set msg
+} {wrong # args: should be "::tcl::pkgconfig list"}
+test pkgconfig-2.3 {error: get without arguments} {
+    catch {::tcl::pkgconfig get} msg
+    set msg
+} {wrong # args: should be "::tcl::pkgconfig get key"}
+test pkgconfig-2.4 {error: query unknown key} {
+    catch {::tcl::pkgconfig get foo} msg
+    set msg
+} {key not known}
+test pkgconfig-2.5 {error: query with to many arguments} {
+    catch {::tcl::pkgconfig get foo bar} msg
+    set msg
+} {wrong # args: should be "::tcl::pkgconfig subcommand ?arg?"}
+
+# cleanup
+::tcltest::cleanupTests
+return
diff --git a/tests/coroutine.test b/tests/coroutine.test
new file mode 100644
index 0000000..205da67
--- /dev/null
+++ b/tests/coroutine.test
@@ -0,0 +1,753 @@
+# Commands covered:  coroutine, yield, yieldto, [info coroutine]
+#
+# This file contains a collection of tests for experimental commands that are
+# found in ::tcl::unsupported. The tests will migrate to normal test files
+# if/when the commands find their way into the core.
+#
+# Copyright (c) 2008 by Miguel Sofer.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+    package require tcltest
+    namespace import -force ::tcltest::*
+}
+
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
+
+testConstraint testnrelevels [llength [info commands testnrelevels]]
+testConstraint memory [llength [info commands memory]]
+
+set lambda [list {{start 0} {stop 10}} {
+    # init
+    set i    $start
+    set imax $stop
+    yield
+    while {$i < $imax} {
+	yield [expr {$i*$stop}]
+	incr i
+    }
+}]
+
+test coroutine-1.1 {coroutine basic} -setup {
+    coroutine foo ::apply $lambda
+    set res {}
+} -body {
+    for {set k 1} {$k < 4} {incr k} {
+	lappend res [foo]
+    }
+    set res
+} -cleanup {
+    rename foo {}
+    unset res
+} -result {0 10 20}
+test coroutine-1.2 {coroutine basic} -setup {
+    coroutine foo ::apply $lambda 2 8
+    set res {}
+} -body {
+    for {set k 1} {$k < 4} {incr k} {
+	lappend res [foo]
+    }
+    set res
+} -cleanup {
+    rename foo {}
+    unset res
+} -result {16 24 32}
+test coroutine-1.3 {yield returns new arg} -setup {
+    set body {
+	# init
+	set i    $start
+	set imax $stop
+	yield
+	while {$i < $imax} {
+	    set stop [yield [expr {$i*$stop}]]
+	    incr i
+	}
+    }
+    coroutine foo ::apply [list {{start 2} {stop 10}} $body] 
+    set res {}
+} -body {
+    for {set k 1} {$k < 4} {incr k} {
+	lappend res [foo $k]
+    }
+    set res
+} -cleanup {
+    rename foo {}
+    unset res
+} -result {20 6 12}
+test coroutine-1.4 {yield in nested proc} -setup {
+    proc moo {} {
+	upvar 1 i i stop stop
+	yield [expr {$i*$stop}]
+    }
+    set body {
+	# init
+	set i    $start
+	set imax $stop
+	yield
+	while {$i < $imax} {
+	    moo
+	    incr i
+	}
+    }
+    coroutine foo ::apply [list {{start 0} {stop 10}} $body]
+    set res {}
+} -body {
+    for {set k 1} {$k < 4} {incr k} {
+	lappend res [foo $k]
+    }
+    set res
+} -cleanup {
+    rename foo {}
+    rename moo {}
+    unset body res
+} -result {0 10 20}
+test coroutine-1.5 {just yield} -body {
+    coroutine foo yield
+    list [foo] [catch foo msg] $msg
+} -cleanup {
+    unset msg
+} -result {{} 1 {invalid command name "foo"}}
+test coroutine-1.6 {just yield} -body {
+    coroutine foo [list yield]
+    list [foo] [catch foo msg] $msg
+} -cleanup {
+    unset msg
+} -result {{} 1 {invalid command name "foo"}}
+test coroutine-1.7 {yield in nested uplevel} -setup {
+    set body {
+	# init
+	set i    $start
+	set imax $stop
+	yield
+	while {$i < $imax} {
+	    uplevel 0 [list yield [expr {$i*$stop}]]
+	    incr i
+	}
+    }
+    coroutine foo ::apply [list {{start 0} {stop 10}} $body]
+    set res {}
+} -body {
+    for {set k 1} {$k < 4} {incr k} {
+	lappend res [eval foo $k]
+    }
+    set res
+} -cleanup {
+    rename foo {}
+    unset body res
+} -result {0 10 20}
+test coroutine-1.8 {yield in nested uplevel} -setup {
+    set body {
+	# init
+	set i    $start
+	set imax $stop
+	yield
+	while {$i < $imax} {
+	    uplevel 0 yield [expr {$i*$stop}]
+	    incr i
+	}
+    }
+    coroutine foo ::apply [list {{start 0} {stop 10}} $body]
+    set res {}
+} -body {
+    for {set k 1} {$k < 4} {incr k} {
+	lappend res [eval foo $k]
+    }
+    set res
+} -cleanup {
+    rename foo {}
+    unset body res
+} -result {0 10 20}
+test coroutine-1.9 {yield in nested eval} -setup {
+    proc moo {} {
+	upvar 1 i i stop stop
+	yield [expr {$i*$stop}]
+    }
+    set body {
+	# init
+	set i    $start
+	set imax $stop
+	yield
+	while {$i < $imax} {
+	    eval moo
+	    incr i
+	}
+    }
+    coroutine foo ::apply [list {{start 0} {stop 10}} $body]
+    set res {}
+} -body {
+    for {set k 1} {$k < 4} {incr k} {
+	lappend res [foo $k]
+    }
+    set res
+} -cleanup {
+    rename moo {}
+    unset body res
+} -result {0 10 20}
+test coroutine-1.10 {yield in nested eval} -setup {
+    set body {
+	# init
+	set i    $start
+	set imax $stop
+	yield
+	while {$i < $imax} {
+	    eval yield [expr {$i*$stop}]
+	    incr i
+	}
+    }
+    coroutine foo ::apply [list {{start 0} {stop 10}} $body]
+    set res {}
+} -body {
+    for {set k 1} {$k < 4} {incr k} {
+	lappend res [eval foo $k]
+    }
+    set res
+} -cleanup {
+    unset body res
+} -result {0 10 20}
+test coroutine-1.11 {yield outside coroutine} -setup {
+    proc moo {} {
+	upvar 1 i i stop stop
+	yield [expr {$i*$stop}]
+    }
+} -body {
+    variable i 5 stop 6
+    moo
+} -cleanup {
+    rename moo {}
+    unset i stop
+} -returnCodes error -result {yield can only be called in a coroutine}
+test coroutine-1.12 {proc as coroutine} -setup {
+    set body {
+	# init
+	set i    $start
+	set imax $stop
+	yield
+	while {$i < $imax} {
+	    uplevel 0 [list yield [expr {$i*$stop}]]
+	    incr i
+	}
+    }
+    proc moo {{start 0} {stop 10}} $body
+    coroutine foo moo 2 8
+} -body {
+    list [foo] [foo]
+} -cleanup {
+    unset body
+    rename moo {}
+    rename foo {}
+} -result {16 24}
+test coroutine-1.13 {subst as coroutine: literal} {
+    list [coroutine foo eval {subst {>>[yield a],[yield b]<<}}] [foo x] [foo y]
+} {a b >>x,y<<}
+test coroutine-1.14 {subst as coroutine: in variable} {
+    set pattern {>>[yield c],[yield d]<<}
+    list [coroutine foo eval {subst $pattern}] [foo p] [foo q]
+} {c d >>p,q<<}
+
+test coroutine-2.1 {self deletion on return} -body {
+    coroutine foo set x 3
+    foo
+} -returnCodes error -result {invalid command name "foo"}
+test coroutine-2.2 {self deletion on return} -body {
+    coroutine foo ::apply [list {} {yield; yield 1; return 2}]
+    list [foo] [foo] [catch foo msg] $msg
+} -result {1 2 1 {invalid command name "foo"}}
+test coroutine-2.3 {self deletion on error return} -body {
+    coroutine foo ::apply [list {} {yield;yield 1; error ouch!}]
+    list [foo] [catch foo msg] $msg [catch foo msg] $msg
+} -result {1 1 ouch! 1 {invalid command name "foo"}}
+test coroutine-2.4 {self deletion on other return} -body {
+    coroutine foo ::apply [list {} {yield;yield 1; return -code 100 ouch!}]
+    list [foo] [catch foo msg] $msg [catch foo msg] $msg
+} -result {1 100 ouch! 1 {invalid command name "foo"}}
+test coroutine-2.5 {deletion of suspended coroutine} -body {
+    coroutine foo ::apply [list {} {yield; yield 1; return 2}]
+    list [foo] [rename foo {}] [catch foo msg] $msg
+} -result {1 {} 1 {invalid command name "foo"}}
+test coroutine-2.6 {deletion of running coroutine} -body {
+    coroutine foo ::apply [list {} {yield; rename foo {}; yield 1; return 2}]
+    list [foo] [catch foo msg] $msg
+} -result {1 1 {invalid command name "foo"}}
+
+test coroutine-3.1 {info level computation} -setup {
+    proc a {} {while 1 {yield [info level]}}
+    proc b {} foo
+} -body {
+    # note that coroutines execute in uplevel #0
+    set l0 [coroutine foo a]
+    set l1 [foo]
+    set l2 [b]
+    list $l0 $l1 $l2
+} -cleanup {
+    rename a {}
+    rename b {}
+} -result {1 1 1}
+test coroutine-3.2 {info frame computation} -setup {
+    proc a {} {while 1 {yield [info frame]}}
+    proc b {} foo
+} -body {
+    set l0 [coroutine foo a]
+    set l1 [foo]
+    set l2 [b]
+    expr {$l2 - $l1}
+} -cleanup {
+    rename a {}
+    rename b {}
+} -result 1
+test coroutine-3.3 {info coroutine} -setup {
+    proc a {} {info coroutine}
+    proc b {} a
+} -body {
+    b
+} -cleanup {
+    rename a {}
+    rename b {}
+} -result {}
+test coroutine-3.4 {info coroutine} -setup {
+    proc a {} {info coroutine}
+    proc b {} a
+} -body {
+    coroutine foo b
+} -cleanup {
+    rename a {}
+    rename b {}
+} -result ::foo
+test coroutine-3.5 {info coroutine} -setup {
+    proc a {} {info coroutine}
+    proc b {} {rename [info coroutine] {}; a}
+} -body {
+    coroutine foo b
+} -cleanup {
+    rename a {}
+    rename b {}
+} -result {}
+test coroutine-3.6 {info frame, bug #2910094} -setup {
+    proc stack {} {
+	set res [list "LEVEL:[set lev [info frame]]"]
+	for {set i 1} {$i < $lev} {incr i} {
+	    lappend res [info frame $i]
+	}
+	set res
+	# the precise command depends on line numbers and such, is likely not
+	# to be stable: just check that the test completes!
+	return
+    }
+    proc a {} stack
+} -body {
+    coroutine aa a
+} -cleanup {
+    rename stack {}
+    rename a {}
+} -result {}
+test coroutine-3.7 {bug 0b874c344d} {
+    dict get [coroutine X coroutine Y info frame 0] cmd
+} {coroutine X coroutine Y info frame 0}
+
+test coroutine-4.1 {bug #2093188} -setup {
+    proc foo {} {
+	set v 1
+	trace add variable v {write unset} bar
+	yield
+	set v 2
+	yield
+	set v 3
+    }
+    proc bar args {lappend ::res $args}
+    coroutine a foo
+} -body {
+    list [a] [a] $::res
+} -cleanup {
+    rename foo {}
+    rename bar {}
+    unset ::res
+} -result {{} 3 {{v {} write} {v {} write} {v {} unset}}}
+test coroutine-4.2 {bug #2093188} -setup {
+    proc foo {} {
+	set v 1
+	trace add variable v {read unset} bar
+	yield
+	set v 2
+	set v
+	yield
+	set v 3
+    }
+    proc bar args {lappend ::res $args}
+    coroutine a foo
+} -body {
+    list [a] [a] $::res
+} -cleanup {
+    rename foo {}
+    rename bar {}
+    unset ::res
+} -result {{} 3 {{v {} read} {v {} unset}}}
+
+test coroutine-4.3 {bug #2093947} -setup {
+    proc foo {} {
+	set v 1
+	trace add variable v {write unset} bar
+	yield
+	set v 2
+	yield
+	set v 3
+    }
+    proc bar args {lappend ::res $args}
+} -body {
+    coroutine a foo
+    a
+    a
+    coroutine a foo
+    a
+    rename a {}
+    set ::res
+} -cleanup {
+    rename foo {}
+    rename bar {}
+    unset ::res
+} -result {{v {} write} {v {} write} {v {} unset} {v {} write} {v {} unset}}
+
+test coroutine-4.4 {bug #2917627: cmd resolution} -setup {
+    proc a {} {return global}
+    namespace eval b {proc a {} {return local}}
+} -body {
+    namespace eval b {coroutine foo a}
+} -cleanup {
+    rename a {}
+    namespace delete b
+} -result local
+
+test coroutine-4.5 {bug #2724403} -constraints {memory} \
+-setup {
+    proc getbytes {} {
+	set lines [split [memory info] "\n"]
+	lindex $lines 3 3
+    }
+} -body {
+    set end [getbytes]
+    for {set i 0} {$i < 5} {incr i} {
+	set ns ::y$i
+	namespace eval $ns {}
+	proc ${ns}::start {} {yield; puts hello}
+	coroutine ${ns}::run ${ns}::start
+	namespace delete $ns
+	set start $end
+	set end [getbytes]
+    }
+    set leakedBytes [expr {$end - $start}]
+} -cleanup {
+    rename getbytes {}
+    unset i ns start end
+} -result 0
+
+test coroutine-4.6 {compile context, bug #3282869} -setup {
+    unset -nocomplain ::x
+    proc f x {
+	coroutine D eval {yield X$x;yield Y}
+    }
+} -body {
+    f 12
+} -cleanup {
+    rename f {}
+} -returnCodes error -match glob -result {can't read *}
+
+test coroutine-4.7 {compile context, bug #3282869} -setup {
+    proc f x {
+	coroutine D eval {yield X$x;yield Y$x}
+    }
+} -body {
+    set ::x 15
+    set ::x [f 12]
+    D
+} -cleanup {
+    D
+    unset ::x
+    rename f {}
+} -result YX15
+
+test coroutine-5.1 {right numLevels on coro return} -constraints {testnrelevels} \
+-setup {
+    proc nestedYield {{val {}}} {
+	yield $val
+    }
+    proc getNumLevel {} {
+	# remove the level for this proc's call
+	expr {[lindex [testnrelevels] 1] - 1}
+    }
+    proc relativeLevel base {
+	# remove the level for this proc's call	
+	expr {[getNumLevel] - $base - 1}
+    }
+    proc foo {} {
+	while 1 {
+	    nestedYield
+	}
+    }
+    set res {}
+} -body {
+    set base [getNumLevel]
+    lappend res [relativeLevel $base]
+    eval {coroutine a foo}
+    # back to base level
+    lappend res [relativeLevel $base]
+    a
+    lappend res [relativeLevel $base]
+    eval a
+    lappend res [relativeLevel $base]
+    eval {eval a}
+    lappend res [relativeLevel $base]
+    rename a {}
+    lappend res [relativeLevel $base]
+    set res
+} -cleanup {
+    rename foo {}
+    rename nestedYield {}
+    rename getNumLevel {}
+    rename relativeLevel {}
+    unset res
+} -result {0 0 0 0 0 0}
+test coroutine-5.2 {right numLevels within coro} -constraints {testnrelevels} \
+-setup {
+    proc nestedYield {{val {}}} {
+	yield $val
+    }
+    proc getNumLevel {} {
+	# remove the level for this proc's call
+	expr {[lindex [testnrelevels] 1] - 1}
+    }
+    proc relativeLevel base {
+	# remove the level for this proc's call	
+	expr {[getNumLevel] - $base - 1}
+    }
+    proc foo base {
+	while 1 {
+	    set base [nestedYield [relativeLevel $base]]
+	}
+    }
+    set res {}
+} -body {
+    lappend res [eval {coroutine a foo [getNumLevel]}]
+    lappend res [a [getNumLevel]]
+    lappend res [eval {a [getNumLevel]}]
+    lappend res [eval {eval {a [getNumLevel]}}]
+    set base [lindex $res 0]
+    foreach x $res[set res {}] {
+	lappend res [expr {$x-$base}]
+    }
+    set res
+} -cleanup {
+    rename a {}
+    rename foo {}
+    rename nestedYield {}
+    rename getNumLevel {}
+    rename relativeLevel {}
+    unset res
+} -result {0 0 0 0}
+
+test coroutine-6.1 {coroutine nargs} -body {
+    coroutine a ::apply $lambda
+    a
+} -cleanup {
+    rename a {}
+} -result 0
+test coroutine-6.2 {coroutine nargs} -body {
+    coroutine a ::apply $lambda
+    a a
+} -cleanup {
+    rename a {}
+} -result 0
+test coroutine-6.3 {coroutine nargs} -body {
+    coroutine a ::apply $lambda
+    a a a
+} -cleanup {
+    rename a {}
+} -returnCodes error -result {wrong # args: should be "a ?arg?"}
+
+test coroutine-7.1 {yieldto} -body {
+    coroutine c apply {{} {
+	yield
+	yieldto return -level 0 -code 1 quux
+	return quuy
+    }}
+    set res [list [catch c msg] $msg]
+    lappend res [catch c msg] $msg
+    lappend res [catch c msg] $msg
+} -cleanup {
+    unset res
+} -result [list 1 quux 0 quuy 1 {invalid command name "c"}]
+test coroutine-7.2 {multi-argument yielding with yieldto} -body {
+    proc corobody {} {
+	set a 1
+	while 1 {
+	    set a [yield $a]
+	    set a [yieldto return -level 0 $a]
+	    lappend a [llength $a]
+	}
+    }
+    coroutine a corobody
+    coroutine b corobody
+    list [a x] [a y z] [a \{p] [a \{q r] [a] [a] [rename a {}] \
+	[b ok] [rename b {}] 
+} -cleanup {
+    rename corobody {}
+} -result {x {y z 2} \{p {\{q r 2} {} 0 {} ok {}}
+test coroutine-7.3 {yielding between coroutines} -body {
+    proc juggler {target {value ""}} {
+	if {$value eq ""} {
+	    set value [yield [info coroutine]]
+	}
+	while {[llength $value]} {
+	    lappend ::result $value [info coroutine]
+	    set value [lrange $value 0 end-1]
+	    lassign [yieldto $target $value] value
+	}
+	# Clear nested collection of coroutines
+	catch $target
+    }
+    set result ""
+    coroutine j1 juggler [coroutine j2 juggler [coroutine j3 juggler j1]]\
+	{a b c d e}
+    list $result [info command j1] [info command j2] [info command j3]
+} -cleanup {
+    catch {rename juggler ""}
+} -result {{{a b c d e} ::j1 {a b c d} ::j2 {a b c} ::j3 {a b} ::j1 a ::j2} {} {} {}}
+test coroutine-7.4 {Bug 8ff0cb9fe1} -setup {
+    proc foo {a b} {catch yield; return 1}
+} -cleanup {
+    rename foo {}
+} -body {
+    coroutine demo lsort -command foo {a b}
+} -result {b a}
+test coroutine-7.5 {return codes} {
+    set result {}
+    foreach code {0 1 2 3 4 5} {
+	lappend result [catch {coroutine demo return -level 0 -code $code}]
+    }
+    set result
+} {0 1 2 3 4 5}
+test coroutine-7.6 {Early yield crashes} {
+    proc foo args {}
+    trace add execution foo enter {catch yield}
+    coroutine demo foo
+    rename foo {}
+} {}
+test coroutine-7.7 {Bug 2486550} -setup {
+    interp hide {} yield
+} -body {
+    coroutine demo interp invokehidden {} yield ok
+} -cleanup {
+    demo
+    interp expose {} yield
+} -result ok
+test coroutine-7.8 {yieldto context nuke: Bug a90d9331bc} -setup {
+    namespace eval cotest {}
+    set ::result ""
+} -body {
+    proc cotest::body {} {
+	lappend ::result a
+	yield OUT
+	lappend ::result b
+	yieldto ::return -level 0 123
+	lappend ::result c
+	return
+    }
+    lappend ::result [coroutine cotest cotest::body]
+    namespace delete cotest
+    namespace eval cotest {}
+    lappend ::result [cotest]
+    cotest
+    return $result
+} -returnCodes error -cleanup {
+    catch {namespace delete ::cotest}
+    catch {rename cotest ""}
+} -result {yieldto called in deleted namespace}
+test coroutine-7.9 {yieldto context nuke: Bug a90d9331bc} -setup {
+    namespace eval cotest {}
+    set ::result ""
+} -body {
+    proc cotest::body {} {
+	set y ::yieldto
+	lappend ::result a
+	yield OUT
+	lappend ::result b
+	$y ::return -level 0 123
+	lappend ::result c
+	return
+    }
+    lappend ::result [coroutine cotest cotest::body]
+    namespace delete cotest
+    namespace eval cotest {}
+    lappend ::result [cotest]
+    cotest
+    return $result
+} -returnCodes error -cleanup {
+    catch {namespace delete ::cotest}
+    catch {rename cotest ""}
+} -result {yieldto called in deleted namespace}
+test coroutine-7.10 {yieldto context nuke: Bug a90d9331bc} -setup {
+    namespace eval cotest {}
+    set ::result ""
+} -body {
+    proc cotest::body {} {
+	lappend ::result a
+	yield OUT
+	lappend ::result b
+	yieldto ::return -level 0 -cotest [namespace delete ::cotest] 123
+	lappend ::result c
+	return
+    }
+    lappend ::result [coroutine cotest cotest::body]
+    lappend ::result [cotest]
+    cotest
+    return $result
+} -returnCodes error -cleanup {
+    catch {namespace delete ::cotest}
+    catch {rename cotest ""}
+} -result {yieldto called in deleted namespace}
+test coroutine-7.11 {yieldto context nuke: Bug a90d9331bc} -setup {
+    namespace eval cotest {}
+    set ::result ""
+} -body {
+    proc cotest::body {} {
+	set y ::yieldto
+	lappend ::result a
+	yield OUT
+	lappend ::result b
+	$y ::return -level 0 -cotest [namespace delete ::cotest] 123
+	lappend ::result c
+	return
+    }
+    lappend ::result [coroutine cotest cotest::body]
+    lappend ::result [cotest]
+    cotest
+    return $result
+} -returnCodes error -cleanup {
+    catch {namespace delete ::cotest}
+    catch {rename cotest ""}
+} -result {yieldto called in deleted namespace}
+test coroutine-7.12 {coro floor above street level #3008307} -body {
+    proc c {} {
+	yield
+    }
+    proc cc {} {
+	coroutine C c
+    }
+    proc boom {} {
+	cc ; # coro created at level 2
+	C  ; # and called at level 1
+    }
+    boom   ; # does not crash: the coro floor is a good insulator
+    list
+} -result {}
+
+
+# cleanup
+unset lambda
+::tcltest::cleanupTests
+
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/tests/dcall.test b/tests/dcall.test
new file mode 100644
index 0000000..41dd777
--- /dev/null
+++ b/tests/dcall.test
@@ -0,0 +1,43 @@
+# Commands covered:  none
+#
+# This file contains a collection of tests for Tcl_CallWhenDeleted.
+# Sourcing this file into Tcl runs the tests and generates output for
+# errors.  No output means no errors were found.
+#
+# Copyright (c) 1993 The Regents of the University of California.
+# Copyright (c) 1994 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+package require tcltest 2
+namespace import ::tcltest::*
+
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
+
+testConstraint testdcall [llength [info commands testdcall]]
+
+test dcall-1.1 {deletion callbacks} testdcall {
+    lsort -increasing [testdcall 1 2 3]
+} {1 2 3}
+test dcall-1.2 {deletion callbacks} testdcall {
+    testdcall
+} {}
+test dcall-1.3 {deletion callbacks} testdcall {
+    lsort -increasing [testdcall 20 21 22 -22]
+} {20 21}
+test dcall-1.4 {deletion callbacks} testdcall {
+    lsort -increasing [testdcall 20 21 22 -20]
+} {21 22}
+test dcall-1.5 {deletion callbacks} testdcall {
+    lsort -increasing [testdcall 20 21 22 -21]
+} {20 22}
+test dcall-1.6 {deletion callbacks} testdcall {
+    lsort -increasing [testdcall 20 21 22 -21 -22 -20]
+} {}
+
+# cleanup
+cleanupTests
+return
diff --git a/tests/dict.test b/tests/dict.test
new file mode 100644
index 0000000..a6b0cb4
--- /dev/null
+++ b/tests/dict.test
@@ -0,0 +1,2065 @@
+# This test file covers the dictionary object type and the dict command used
+# to work with values of that type.
+#
+# This file contains a collection of tests for one or more of the Tcl built-in
+# commands. Sourcing this file into Tcl runs the tests and generates output
+# for errors.  No output means no errors were found.
+#
+# Copyright (c) 2003-2009 Donal K. Fellows
+# See the file "license.terms" for information on usage and redistribution of
+# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+    package require tcltest 2
+    namespace import -force ::tcltest::*
+}
+
+# Used for constraining memory leak tests
+testConstraint memory [llength [info commands memory]]
+if {[testConstraint memory]} {
+    proc memtest script {
+	set end [lindex [split [memory info] \n] 3 3]
+	for {set i 0} {$i < 5} {incr i} {
+	    uplevel 1 $script
+	    set tmp $end
+	    set end [lindex [split [memory info] \n] 3 3]
+	}
+	expr {$end - $tmp}
+    }
+}
+
+test dict-1.1 {dict command basic syntax} -returnCodes error -body {
+    dict
+} -result {wrong # args: should be "dict subcommand ?arg ...?"}
+test dict-1.2 {dict command basic syntax} -returnCodes error -body {
+    dict ?
+} -match glob -result {unknown or ambiguous subcommand "?": must be *}
+
+test dict-2.1 {dict create command} {
+    dict create
+} {}
+test dict-2.2 {dict create command} {
+    dict create a b
+} {a b}
+test dict-2.3 {dict create command} -body {
+    set result {}
+    set dict [dict create a b c d]
+    # Can't compare directly as ordering of values is undefined
+    foreach key {a c} {
+	set idx [lsearch -exact $dict $key]
+	if {$idx & 1} {
+	    error "found $key at odd index $idx in $dict"
+	}
+	lappend result [lindex $dict [expr {$idx+1}]]
+    }
+    return $result
+} -cleanup {
+    unset result dict key idx
+} -result {b d}
+test dict-2.4 {dict create command} -returnCodes error -body {
+    dict create a
+} -result {wrong # args: should be "dict create ?key value ...?"}
+test dict-2.5 {dict create command} -returnCodes error -body {
+    dict create a b c
+} -result {wrong # args: should be "dict create ?key value ...?"}
+test dict-2.6 {dict create command - initialse refcount field!} -body {
+    # Bug 715751 will show up in memory debuggers like purify
+    for {set i 0} {$i<10} {incr i} {
+	set dictv [dict create a 0]
+	set share [dict values $dictv]
+	list [dict incr dictv a]
+    }
+} -cleanup {
+    unset i dictv share
+} -result {}
+test dict-2.7 {dict create command - #-quoting in string rep} {
+    dict create # #comment
+} {{#} #comment}
+test dict-2.8 {dict create command - #-quoting in string rep} -body {
+    dict create #a x #b x
+} -match glob -result {{#?} x #? x}
+test dict-2.9 {dict create command: compilation} {
+    apply {{} {dict create [format a] b}}
+} {a b}
+test dict-2.10 {dict create command: compilation} {
+    apply {{} {dict create [format a] b c d}}
+} {a b c d}
+test dict-2.11 {dict create command: compilation} {
+    apply {{} {dict create [format a] b c d a x}}
+} {a x c d}
+test dict-2.12 {dict create command: non-compilation} {
+    dict create [format a] b
+} {a b}
+test dict-2.13 {dict create command: non-compilation} {
+    dict create [format a] b c d
+} {a b c d}
+test dict-2.14 {dict create command: non-compilation} {
+    dict create [format a] b c d a x
+} {a x c d}
+
+test dict-3.1 {dict get command} {dict get {a b} a} b
+test dict-3.2 {dict get command} {dict get {a b c d} a} b
+test dict-3.3 {dict get command} {dict get {a b c d} c} d
+test dict-3.4 {dict get command} -returnCodes error -body {
+    dict get {a b c d} b
+} -result {key "b" not known in dictionary}
+test dict-3.5 {dict get command} {dict get {a {p q r s} b {u v x y}} a p} q
+test dict-3.6 {dict get command} {dict get {a {p q r s} b {u v x y}} a r} s
+test dict-3.7 {dict get command} {dict get {a {p q r s} b {u v x y}} b u} v
+test dict-3.8 {dict get command} {dict get {a {p q r s} b {u v x y}} b x} y
+test dict-3.9 {dict get command} -returnCodes error -body {
+    dict get {a {p q r s} b {u v x y}} a z
+} -result {key "z" not known in dictionary}
+test dict-3.10 {dict get command} -returnCodes error -body {
+    dict get {a {p q r s} b {u v x y}} c z
+} -result {key "c" not known in dictionary}
+test dict-3.11 {dict get command} {dict get [dict create a b c d] a} b
+test dict-3.12 {dict get command} -returnCodes error -body {
+    dict get
+} -result {wrong # args: should be "dict get dictionary ?key ...?"}
+test dict-3.13 {dict get command} -body {
+    set dict [dict get {a b c d}]
+    if {$dict eq "a b c d"} {
+	return OK
+    } elseif {$dict eq "c d a b"} {
+	return reordered
+    } else {
+	return $dict
+    }
+} -cleanup {
+    unset dict
+} -result OK
+test dict-3.14 {dict get command} -returnCodes error -body {
+    dict get {a b c d} a c
+} -result {missing value to go with key}
+test dict-3.15 {compiled dict get error cleanliness - Bug 2431847} -body {
+    apply {{} {
+	dict set a(z) b c
+	dict get $a(z) d
+    }}
+} -returnCodes error -result {key "d" not known in dictionary}
+test dict-3.16 {dict/list shimmering - Bug 3004007} {set l [list p 1 p 2 q 3];dict get $l q;set l} {p 1 p 2 q 3}
+test dict-3.17 {dict/list shimmering - Bug 3004007} {set l [list p 1 p 2 q 3];dict get $l q;llength $l} 6
+
+test dict-4.1 {dict replace command} {
+    dict replace {a b c d}
+} {a b c d}
+test dict-4.2 {dict replace command} {
+    dict replace {a b c d} e f
+} {a b c d e f}
+test dict-4.3 {dict replace command} {
+    dict replace {a b c d} c f
+} {a b c f}
+test dict-4.4 {dict replace command} {
+    dict replace {a b c d} c x a y
+} {a y c x}
+test dict-4.5 {dict replace command} -returnCodes error -body {
+    dict replace
+} -result {wrong # args: should be "dict replace dictionary ?key value ...?"}
+test dict-4.6 {dict replace command} -returnCodes error -body {
+    dict replace {a a} a
+} -result {wrong # args: should be "dict replace dictionary ?key value ...?"}
+test dict-4.7 {dict replace command} -returnCodes error -body {
+    dict replace {a a a} a b
+} -result {missing value to go with key}
+test dict-4.8 {dict replace command} -returnCodes error -body {
+    dict replace [list a a a] a b
+} -result {missing value to go with key}
+test dict-4.9 {dict replace command} {dict replace [list a a] a b} {a b}
+test dict-4.10 {dict replace command} {dict replace [list a a] a b a c} {a c}
+test dict-4.11 {dict replace command: canonicality is forced} {
+    dict replace { a b  c d }
+} {a b c d}
+test dict-4.12 {dict replace command: canonicality is forced} {
+    dict replace {a b c d a e}
+} {a e c d}
+test dict-4.13 {dict replace command: type check is mandatory} -body {
+    dict replace { a b c d e }
+} -returnCodes error -result {missing value to go with key}
+test dict-4.13a {dict replace command: type check is mandatory} {
+    catch {dict replace { a b c d e }} -> opt
+    dict get $opt -errorcode
+} {TCL VALUE DICTIONARY}
+test dict-4.14 {dict replace command: type check is mandatory} -body {
+    dict replace { a b {}c d }
+} -returnCodes error -result {dict element in braces followed by "c" instead of space}
+test dict-4.14a {dict replace command: type check is mandatory} {
+    catch {dict replace { a b {}c d }} -> opt
+    dict get $opt -errorcode
+} {TCL VALUE DICTIONARY JUNK}
+test dict-4.15 {dict replace command: type check is mandatory} -body {
+    dict replace { a b ""c d }
+} -returnCodes error -result {dict element in quotes followed by "c" instead of space}
+test dict-4.15a {dict replace command: type check is mandatory} {
+    catch {dict replace { a b ""c d }} -> opt
+    dict get $opt -errorcode
+} {TCL VALUE DICTIONARY JUNK}
+test dict-4.16 {dict replace command: type check is mandatory} -body {
+    dict replace " a b \"c d "
+} -returnCodes error -result {unmatched open quote in dict}
+test dict-4.16a {dict replace command: type check is mandatory} {
+    catch {dict replace " a b \"c d "} -> opt
+    dict get $opt -errorcode
+} {TCL VALUE DICTIONARY QUOTE}
+test dict-4.17 {dict replace command: type check is mandatory} -body {
+    dict replace " a b \{c d "
+} -returnCodes error -result {unmatched open brace in dict}
+test dict-4.17a {dict replace command: type check is mandatory} {
+    catch {dict replace " a b \{c d "} -> opt
+    dict get $opt -errorcode
+} {TCL VALUE DICTIONARY BRACE}
+test dict-4.18 {dict replace command: canonicality forcing doesn't leak} {
+    set example { a b  c d }
+    list $example [dict replace $example]
+} {{ a b  c d } {a b c d}}
+
+test dict-5.1 {dict remove command} {dict remove {a b c d} a} {c d}
+test dict-5.2 {dict remove command} {dict remove {a b c d} c} {a b}
+test dict-5.3 {dict remove command} {dict remove {a b c d} a c} {}
+test dict-5.4 {dict remove command} {dict remove {a b c d} c a} {}
+test dict-5.5 {dict remove command} {
+    dict remove {a b c d}
+} {a b c d}
+test dict-5.6 {dict remove command} {dict remove {a b} c} {a b}
+test dict-5.7 {dict remove command} -returnCodes error -body {
+    dict remove
+} -result {wrong # args: should be "dict remove dictionary ?key ...?"}
+test dict-5.8 {dict remove command: canonicality is forced} {
+    dict remove { a b  c d }
+} {a b c d}
+test dict-5.9 {dict remove command: canonicality is forced} {
+    dict remove {a b c d a e}
+} {a e c d}
+test dict-5.10 {dict remove command: canonicality forced by update} {
+    dict remove { a b c d } c
+} {a b}
+test dict-5.11 {dict remove command: type check is mandatory} -body {
+    dict remove { a b c d e }
+} -returnCodes error -result {missing value to go with key}
+test dict-5.12 {dict remove command: type check is mandatory} -body {
+    dict remove { a b {}c d }
+} -returnCodes error -result {dict element in braces followed by "c" instead of space}
+test dict-5.13 {dict remove command: canonicality forcing doesn't leak} {
+    set example { a b  c d }
+    list $example [dict remove $example]
+} {{ a b  c d } {a b c d}}
+
+test dict-6.1 {dict keys command} {dict keys {a b}} a
+test dict-6.2 {dict keys command} {dict keys {c d}} c
+test dict-6.3 {dict keys command} {lsort [dict keys {a b c d}]} {a c}
+test dict-6.4 {dict keys command} {dict keys {a b c d} a} a
+test dict-6.5 {dict keys command} {dict keys {a b c d} c} c
+test dict-6.6 {dict keys command} {dict keys {a b c d} e} {}
+test dict-6.7 {dict keys command} {lsort [dict keys {a b c d ca da} c*]} {c ca}
+test dict-6.8 {dict keys command} -returnCodes error -body {
+    dict keys
+} -result {wrong # args: should be "dict keys dictionary ?pattern?"}
+test dict-6.9 {dict keys command} -returnCodes error -body {
+    dict keys {} a b
+} -result {wrong # args: should be "dict keys dictionary ?pattern?"}
+test dict-6.10 {dict keys command} -returnCodes error -body {
+    dict keys a
+} -result {missing value to go with key}
+
+test dict-7.1 {dict values command} {dict values {a b}} b
+test dict-7.2 {dict values command} {dict values {c d}} d
+test dict-7.3 {dict values command} {lsort [dict values {a b c d}]} {b d}
+test dict-7.4 {dict values command} {dict values {a b c d} b} b
+test dict-7.5 {dict values command} {dict values {a b c d} d} d
+test dict-7.6 {dict values command} {dict values {a b c d} e} {}
+test dict-7.7 {dict values command} {lsort [dict values {a b c d ca da} d*]} {d da}
+test dict-7.8 {dict values command} -returnCodes error -body {
+    dict values
+} -result {wrong # args: should be "dict values dictionary ?pattern?"}
+test dict-7.9 {dict values command} -returnCodes error -body {
+    dict values {} a b
+} -result {wrong # args: should be "dict values dictionary ?pattern?"}
+test dict-7.10 {dict values command} -returnCodes error -body {
+    dict values a
+} -result {missing value to go with key}
+
+test dict-8.1 {dict size command} {dict size {}} 0
+test dict-8.2 {dict size command} {dict size {a b}} 1
+test dict-8.3 {dict size command} {dict size {a b c d}} 2
+test dict-8.4 {dict size command} -returnCodes error -body {
+    dict size
+} -result {wrong # args: should be "dict size dictionary"}
+test dict-8.5 {dict size command} -returnCodes error -body {
+    dict size a b
+} -result {wrong # args: should be "dict size dictionary"}
+test dict-8.6 {dict size command} -returnCodes error -body {
+    dict size a
+} -result {missing value to go with key}
+
+test dict-9.1 {dict exists command} {dict exists {a b} a} 1
+test dict-9.2 {dict exists command} {dict exists {a b} b} 0
+test dict-9.3 {dict exists command} {dict exists {a {b c}} a b} 1
+test dict-9.4 {dict exists command} {dict exists {a {b c}} a c} 0
+test dict-9.5 {dict exists command} {dict exists {a {b c}} b c} 0
+test dict-9.6 {dict exists command} {dict exists {a {b c d}} a c} 0
+test dict-9.7 {dict exists command} -returnCodes error -body {
+    dict exists
+} -result {wrong # args: should be "dict exists dictionary key ?key ...?"}
+test dict-9.8 {dict exists command} -returnCodes error -body {
+    dict exists {}
+} -result {wrong # args: should be "dict exists dictionary key ?key ...?"}
+
+test dict-10.1 {dict info command} -body {
+    # Actual string returned by this command is undefined; it is
+    # intended for human consumption and not for use by scripts.
+    dict info {}
+} -match glob -result *
+test dict-10.2 {dict info command} -returnCodes error -body {
+    dict info
+} -result {wrong # args: should be "dict info dictionary"}
+test dict-10.3 {dict info command} -returnCodes error -body {
+    dict info {} x
+} -result {wrong # args: should be "dict info dictionary"}
+test dict-10.4 {dict info command} -returnCodes error -body {
+    dict info x
+} -result {missing value to go with key}
+
+test dict-11.1 {dict incr command: unshared value} -body {
+    set dictv [dict create \
+	    a [string index "=0=" 1] \
+	    b [expr {1+2}] \
+	    c [expr {wide(0x80000000)+1}]]
+    dict incr dictv a
+} -cleanup {
+    unset dictv
+} -result {a 1 b 3 c 2147483649}
+test dict-11.2 {dict incr command: unshared value} -body {
+    set dictv [dict create \
+	    a [string index "=0=" 1] \
+	    b [expr {1+2}] \
+	    c [expr {wide(0x80000000)+1}]]
+    dict incr dictv b
+} -cleanup {
+    unset dictv
+} -result {a 0 b 4 c 2147483649}
+test dict-11.3 {dict incr command: unshared value} -body {
+    set dictv [dict create \
+	    a [string index "=0=" 1] \
+	    b [expr {1+2}] \
+	    c [expr {wide(0x80000000)+1}]]
+    dict incr dictv c
+} -cleanup {
+    unset dictv
+} -result {a 0 b 3 c 2147483650}
+test dict-11.4 {dict incr command: shared value} -body {
+    set dictv [dict create a 0 b [expr {1+2}] c [expr {wide(0x80000000)+1}]]
+    set sharing [dict values $dictv]
+    dict incr dictv a
+} -cleanup {
+    unset dictv sharing
+} -result {a 1 b 3 c 2147483649}
+test dict-11.5 {dict incr command: shared value} -body {
+    set dictv [dict create a 0 b [expr {1+2}] c [expr {wide(0x80000000)+1}]]
+    set sharing [dict values $dictv]
+    dict incr dictv b
+} -cleanup {
+    unset dictv sharing
+} -result {a 0 b 4 c 2147483649}
+test dict-11.6 {dict incr command: shared value} -body {
+    set dictv [dict create a 0 b [expr {1+2}] c [expr {wide(0x80000000)+1}]]
+    set sharing [dict values $dictv]
+    dict incr dictv c
+} -cleanup {
+    unset dictv sharing
+} -result {a 0 b 3 c 2147483650}
+test dict-11.7 {dict incr command: unknown values} -body {
+    set dictv [dict create a 0 b [expr {1+2}] c [expr {wide(0x80000000)+1}]]
+    dict incr dictv d
+} -cleanup {
+    unset dictv
+} -result {a 0 b 3 c 2147483649 d 1}
+test dict-11.8 {dict incr command} -body {
+    set dictv {a 1}
+    dict incr dictv a 2
+} -cleanup {
+    unset dictv
+} -result {a 3}
+test dict-11.9 {dict incr command} -returnCodes error -body {
+    set dictv {a dummy}
+    dict incr dictv a
+} -cleanup {
+    unset dictv
+} -result {expected integer but got "dummy"}
+test dict-11.10 {dict incr command} -returnCodes error -body {
+    set dictv {a 1}
+    dict incr dictv a dummy
+} -cleanup {
+    unset dictv
+} -result {expected integer but got "dummy"}
+test dict-11.11 {dict incr command} -setup {
+    unset -nocomplain dictv
+} -body {
+    dict incr dictv a
+} -cleanup {
+    unset dictv
+} -result {a 1}
+test dict-11.12 {dict incr command} -returnCodes error -body {
+    set dictv a
+    dict incr dictv a
+} -cleanup {
+    unset dictv
+} -result {missing value to go with key}
+test dict-11.13 {dict incr command} -returnCodes error -body {
+    set dictv a
+    dict incr dictv a a a
+} -cleanup {
+    unset dictv
+} -result {wrong # args: should be "dict incr dictVarName key ?increment?"}
+test dict-11.14 {dict incr command} -returnCodes error -body {
+    set dictv a
+    dict incr dictv
+} -cleanup {
+    unset dictv
+} -result {wrong # args: should be "dict incr dictVarName key ?increment?"}
+test dict-11.15 {dict incr command: write failure} -setup {
+    unset -nocomplain dictVar
+} -body {
+    set dictVar(block) {}
+    dict incr dictVar a
+} -returnCodes error -cleanup {
+    unset dictVar
+} -result {can't set "dictVar": variable is array}
+test dict-11.16 {dict incr command: compilation} {
+    apply {{} {
+	set v {a 0 b 0 c 0}
+	dict incr v a
+	dict incr v b 1
+	dict incr v c 2
+	dict incr v d 3
+	list [dict get $v a] [dict get $v b] [dict get $v c] [dict get $v d]
+    }}
+} {1 1 2 3}
+test dict-11.17 {dict incr command: compilation} {
+    apply {{} {
+	set dictv {a 1}
+	dict incr dictv a 2
+    }}
+} {a 3}
+
+test dict-12.1 {dict lappend command} -body {
+    set dictv {a a}
+    dict lappend dictv a
+} -cleanup {
+    unset dictv
+} -result {a a}
+test dict-12.2 {dict lappend command} -body {
+    set dictv {a a}
+    set sharing [dict values $dictv]
+    dict lappend dictv a b
+} -cleanup {
+    unset dictv sharing
+} -result {a {a b}}
+test dict-12.3 {dict lappend command} -body {
+    set dictv {a a}
+    dict lappend dictv a b c
+} -cleanup {
+    unset dictv
+} -result {a {a b c}}
+test dict-12.2.1 {dict lappend command} -body {
+    set dictv [dict create a [string index =a= 1]]
+    dict lappend dictv a b
+} -cleanup {
+    unset dictv
+} -result {a {a b}}
+test dict-12.4 {dict lappend command} -body {
+    set dictv {}
+    dict lappend dictv a x y z
+} -cleanup {
+    unset dictv
+} -result {a {x y z}}
+test dict-12.5 {dict lappend command} -body {
+    unset -nocomplain dictv
+    dict lappend dictv a b
+} -cleanup {
+    unset dictv
+} -result {a b}
+test dict-12.6 {dict lappend command} -returnCodes error -body {
+    set dictv a
+    dict lappend dictv a a
+} -cleanup {
+    unset dictv
+} -result {missing value to go with key}
+test dict-12.7 {dict lappend command} -returnCodes error -body {
+    dict lappend
+} -result {wrong # args: should be "dict lappend dictVarName key ?value ...?"}
+test dict-12.8 {dict lappend command} -returnCodes error -body {
+    dict lappend dictv
+} -result {wrong # args: should be "dict lappend dictVarName key ?value ...?"}
+test dict-12.9 {dict lappend command} -returnCodes error -body {
+    set dictv [dict create a "\{"]
+    dict lappend dictv a a
+} -cleanup {
+    unset dictv
+} -result {unmatched open brace in list}
+test dict-12.10 {dict lappend command: write failure} -setup {
+    unset -nocomplain dictVar
+} -body {
+    set dictVar(block) {}
+    dict lappend dictVar a x
+} -returnCodes error -cleanup {
+    unset dictVar
+} -result {can't set "dictVar": variable is array}
+test dict-12.11 {compiled dict append: invalidate string rep - Bug 3079830} {
+    apply {{} {set d {a 1 b 2 c 3}; dict lappend d b 22}}
+} {a 1 b {2 22} c 3}
+
+test dict-13.1 {dict append command} -body {
+    set dictv {a a}
+    dict append dictv a
+} -cleanup {
+    unset dictv
+} -result {a a}
+test dict-13.2 {dict append command} -body {
+    set dictv {a a}
+    set sharing [dict values $dictv]
+    dict append dictv a b
+} -cleanup {
+    unset dictv sharing
+} -result {a ab}
+test dict-13.3 {dict append command} -body {
+    set dictv {a a}
+    dict append dictv a b c
+} -cleanup {
+    unset dictv
+} -result {a abc}
+test dict-13.2.1 {dict append command} -body {
+    set dictv [dict create a [string index =a= 1]]
+    dict append dictv a b
+} -cleanup {
+    unset dictv
+} -result {a ab}
+test dict-13.4 {dict append command} -body {
+    set dictv {}
+    dict append dictv a x y z
+} -cleanup {
+    unset dictv
+} -result {a xyz}
+test dict-13.5 {dict append command} -body {
+    unset -nocomplain dictv
+    dict append dictv a b
+} -cleanup {
+    unset dictv
+} -result {a b}
+test dict-13.6 {dict append command} -returnCodes error -body {
+    set dictv a
+    dict append dictv a a
+} -cleanup {
+    unset dictv
+} -result {missing value to go with key}
+test dict-13.7 {dict append command} -returnCodes error -body {
+    dict append
+} -result {wrong # args: should be "dict append dictVarName key ?value ...?"}
+test dict-13.8 {dict append command} -returnCodes error -body {
+    dict append dictv
+} -result {wrong # args: should be "dict append dictVarName key ?value ...?"}
+test dict-13.9 {dict append command: write failure} -setup {
+    unset -nocomplain dictVar
+} -body {
+    set dictVar(block) {}
+    dict append dictVar a x
+} -returnCodes error -cleanup {
+    unset dictVar
+} -result {can't set "dictVar": variable is array}
+test dict-13.10 {compiled dict append: crash case} {
+    apply {{} {dict append dictVar a o k}}
+} {a ok}
+test dict-13.11 {compiled dict append: invalidate string rep - Bug 3079830} {
+    apply {{} {set d {a 1 b 2 c 3}; dict append d b 22}}
+} {a 1 b 222 c 3}
+
+test dict-14.1 {dict for command: syntax} -returnCodes error -body {
+    dict for
+} -result {wrong # args: should be "dict for {keyVarName valueVarName} dictionary script"}
+test dict-14.2 {dict for command: syntax} -returnCodes error -body {
+    dict for x
+} -result {wrong # args: should be "dict for {keyVarName valueVarName} dictionary script"}
+test dict-14.3 {dict for command: syntax} -returnCodes error -body {
+    dict for x x
+} -result {wrong # args: should be "dict for {keyVarName valueVarName} dictionary script"}
+test dict-14.4 {dict for command: syntax} -returnCodes error -body {
+    dict for x x x x
+} -result {wrong # args: should be "dict for {keyVarName valueVarName} dictionary script"}
+test dict-14.5 {dict for command: syntax} -returnCodes error -body {
+    dict for x x x
+} -result {must have exactly two variable names}
+test dict-14.6 {dict for command: syntax} -returnCodes error -body {
+    dict for {x x x} x x
+} -result {must have exactly two variable names}
+test dict-14.7 {dict for command: syntax} -returnCodes error -body {
+    dict for "\{x" x x
+} -result {unmatched open brace in list}
+test dict-14.8 {dict for command} -body {
+    # This test confirms that [dict keys], [dict values] and [dict for]
+    # all traverse a dictionary in the same order.
+    set dictv {a A b B c C}
+    set keys {}
+    set values {}
+    dict for {k v} $dictv {
+	lappend keys $k
+	lappend values $v
+    }
+    set result [expr {
+	$keys eq [dict keys $dictv] && $values eq [dict values $dictv]
+    }]
+    expr {$result ? "YES" : [list "NO" $dictv $keys $values]}
+} -cleanup {
+    unset result keys values k v dictv
+} -result YES
+test dict-14.9 {dict for command} {
+    dict for {k v} {} {
+	error "unexpected execution of 'dict for' body"
+    }
+} {}
+test dict-14.10 {dict for command: script results} -body {
+    set times 0
+    dict for {k v} {a a b b} {
+	incr times
+	continue
+	error "shouldn't get here"
+    }
+    return $times
+} -cleanup {
+    unset times k v
+} -result 2
+test dict-14.11 {dict for command: script results} -body {
+    set times 0
+    dict for {k v} {a a b b} {
+	incr times
+	break
+	error "shouldn't get here"
+    }
+    return $times
+} -cleanup {
+    unset times k v
+} -result 1
+test dict-14.12 {dict for command: script results} -body {
+    set times 0
+    list [catch {
+	dict for {k v} {a a b b} {
+	    incr times
+	    error test
+	}
+    } msg] $msg $times $::errorInfo
+} -cleanup {
+    unset times k v msg
+} -result {1 test 1 {test
+    while executing
+"error test"
+    ("dict for" body line 3)
+    invoked from within
+"dict for {k v} {a a b b} {
+	    incr times
+	    error test
+	}"}}
+test dict-14.13 {dict for command: script results} {
+    apply {{} {
+	dict for {k v} {a b} {
+	    return ok,$k,$v
+	    error "skipped return completely"
+	}
+	error "return didn't go far enough"
+    }}
+} ok,a,b
+test dict-14.14 {dict for command: handle representation loss} -body {
+    set dictVar {a b c d e f g h}
+    set keys {}
+    set values {}
+    dict for {k v} $dictVar {
+	if {[llength $dictVar]} {
+	    lappend keys $k
+	    lappend values $v
+	}
+    }
+    list [lsort $keys] [lsort $values]
+} -cleanup {
+    unset dictVar keys values k v
+} -result {{a c e g} {b d f h}}
+test dict-14.15 {dict for command: keys are unique and iterated over once only} -setup {
+    unset -nocomplain accum
+    array set accum {}
+} -body {
+    set dictVar {a1 a a2 b b1 c b2 d foo bar bar foo}
+    dict for {k v} $dictVar {
+	append accum($k) $v,
+    }
+    set result [lsort [array names accum]]
+    lappend result :
+    foreach k $result {
+	catch {lappend result $accum($k)}
+    }
+    return $result
+} -cleanup {
+    unset dictVar k v result accum
+} -result {a1 a2 b1 b2 bar foo : a, b, c, d, foo, bar,}
+test dict-14.16 {dict for command in compilation context} {
+    apply {{} {
+	set res {x x x x x x}
+	dict for {k v} {a 0 b 1 c 2 d 3 e 4 f 5} {
+	    lset res $v $k
+	    continue
+	}
+	return $res
+    }}
+} {a b c d e f}
+test dict-14.17 {dict for command in compilation context} {
+    # Bug 1379349
+    apply {{} {
+	set d [dict create a 1]		;# Dict must be unshared!
+	dict for {k v} $d {
+	    dict set d $k 0		;# Any modification will do
+	}
+	return $d
+    }}
+} {a 0}
+test dict-14.18 {dict for command in compilation context} {
+    # Bug 1382528
+    apply {{} {
+	dict for {k v} {} {}		;# Note empty dict
+	catch { error foo }		;# Note compiled [catch]
+    }}
+} 1
+test dict-14.19 {dict for and invalid dicts: bug 1531184} -body {
+    di[list]ct for {k v} x {}
+} -returnCodes 1 -result {missing value to go with key}
+test dict-14.20 {dict for stack space compilation: bug 1903325} {
+    apply {{x y args} {
+	dict for {a b} $x {}
+	concat "c=$y,$args"
+    }} {} 1 2 3
+} {c=1,2 3}
+test dict-14.21 {compiled dict for and break} {
+    apply {{} {
+	dict for {a b} {c d e f} {
+	    lappend result $a,$b
+	    break
+	}
+	return $result
+    }}
+} c,d
+test dict-14.22 {dict for and exception range depths: Bug 3614382} {
+    apply {{} {
+	dict for {a b} {c d} {
+	    dict for {e f} {g h} {
+		return 5
+	    }
+	}
+    }}
+} 5
+# There's probably a lot more tests to add here. Really ought to use a
+# coverage tool for this job...
+
+test dict-15.1 {dict set command} -body {
+    set dictVar {}
+    dict set dictVar a x
+} -cleanup {
+    unset dictVar
+} -result {a x}
+test dict-15.2 {dict set command} -body {
+    set dictvar {a {}}
+    dict set dictvar a b x
+} -cleanup {
+    unset dictvar
+} -result {a {b x}}
+test dict-15.3 {dict set command} -body {
+    set dictvar {a {b {}}}
+    dict set dictvar a b c x
+} -cleanup {
+    unset dictvar
+} -result {a {b {c x}}}
+test dict-15.4 {dict set command} -body {
+    set dictVar {a y}
+    dict set dictVar a x
+} -cleanup {
+    unset dictVar
+} -result {a x}
+test dict-15.5 {dict set command} -body {
+    set dictVar {a {b y}}
+    dict set dictVar a b x
+} -cleanup {
+    unset dictVar
+} -result {a {b x}}
+test dict-15.6 {dict set command} -body {
+    set dictVar {a {b {c y}}}
+    dict set dictVar a b c x
+} -cleanup {
+    unset dictVar
+} -result {a {b {c x}}}
+test dict-15.7 {dict set command: path creation} -body {
+    set dictVar {}
+    dict set dictVar a b x
+} -cleanup {
+    unset dictVar
+} -result {a {b x}}
+test dict-15.8 {dict set command: creates variables} -setup {
+    unset -nocomplain dictVar
+} -body {
+    dict set dictVar a x
+    return $dictVar
+} -cleanup {
+    unset dictVar
+} -result {a x}
+test dict-15.9 {dict set command: write failure} -setup {
+    unset -nocomplain dictVar
+} -body {
+    set dictVar(block) {}
+    dict set dictVar a x
+} -returnCodes error -cleanup {
+    unset dictVar
+} -result {can't set "dictVar": variable is array}
+test dict-15.10 {dict set command: syntax} -returnCodes error -body {
+    dict set
+} -result {wrong # args: should be "dict set dictVarName key ?key ...? value"}
+test dict-15.11 {dict set command: syntax} -returnCodes error -body {
+    dict set a
+} -result {wrong # args: should be "dict set dictVarName key ?key ...? value"}
+test dict-15.12 {dict set command: syntax} -returnCodes error -body {
+    dict set a a
+} -result {wrong # args: should be "dict set dictVarName key ?key ...? value"}
+test dict-15.13 {dict set command} -returnCodes error -body {
+    set dictVar a
+    dict set dictVar b c
+} -cleanup {
+    unset dictVar
+} -result {missing value to go with key}
+
+test dict-16.1 {dict unset command} -body {
+    set dictVar {a b c d}
+    dict unset dictVar a
+} -cleanup {
+    unset dictVar
+} -result {c d}
+test dict-16.2 {dict unset command} -body {
+    set dictVar {a b c d}
+    dict unset dictVar c
+} -cleanup {
+    unset dictVar
+} -result {a b}
+test dict-16.3 {dict unset command} -body {
+    set dictVar {a b}
+    dict unset dictVar c
+} -cleanup {
+    unset dictVar
+} -result {a b}
+test dict-16.4 {dict unset command} -body {
+    set dictVar {a {b c d e}}
+    dict unset dictVar a b
+} -cleanup {
+    unset dictVar
+} -result {a {d e}}
+test dict-16.5 {dict unset command} -returnCodes error -body {
+    set dictVar a
+    dict unset dictVar a
+} -cleanup {
+    unset dictVar
+} -result {missing value to go with key}
+test dict-16.6 {dict unset command} -returnCodes error -body {
+    set dictVar {a b}
+    dict unset dictVar c d
+} -cleanup {
+    unset dictVar
+} -result {key "c" not known in dictionary}
+test dict-16.7 {dict unset command} -setup {
+    unset -nocomplain dictVar
+} -body {
+    list [info exists dictVar] [dict unset dictVar a] [info exists dictVar]
+} -cleanup {
+    unset dictVar
+} -result {0 {} 1}
+test dict-16.8 {dict unset command} -returnCodes error -body {
+    dict unset dictVar
+} -result {wrong # args: should be "dict unset dictVarName key ?key ...?"}
+test dict-16.9 {dict unset command: write failure} -setup {
+    unset -nocomplain dictVar
+} -body {
+    set dictVar(block) {}
+    dict unset dictVar a
+} -returnCodes error -cleanup {
+    unset dictVar
+} -result {can't set "dictVar": variable is array}
+# Now test with an LVT present (i.e., the bytecoded version).
+test dict-16.10 {dict unset command} -body {
+    apply {{} {
+	set dictVar {a b c d}
+	dict unset dictVar a
+    }}
+} -result {c d}
+test dict-16.11 {dict unset command} -body {
+    apply {{} {
+	set dictVar {a b c d}
+	dict unset dictVar c
+    }}
+} -result {a b}
+test dict-16.12 {dict unset command} -body {
+    apply {{} {
+	set dictVar {a b}
+	dict unset dictVar c
+    }}
+} -result {a b}
+test dict-16.13 {dict unset command} -body {
+    apply {{} {
+	set dictVar {a {b c d e}}
+	dict unset dictVar a b
+    }}
+} -result {a {d e}}
+test dict-16.14 {dict unset command} -returnCodes error -body {
+    apply {{} {
+	set dictVar a
+	dict unset dictVar a
+    }}
+} -result {missing value to go with key}
+test dict-16.15 {dict unset command} -returnCodes error -body {
+    apply {{} {
+	set dictVar {a b}
+	dict unset dictVar c d
+    }}
+} -result {key "c" not known in dictionary}
+test dict-16.16 {dict unset command} -body {
+    apply {{} {list [info exists dictVar] [dict unset dictVar a] [info exists dictVar]}}
+} -result {0 {} 1}
+test dict-16.17 {dict unset command} -returnCodes error -body {
+    apply {{} {dict unset dictVar}}
+} -result {wrong # args: should be "dict unset dictVarName key ?key ...?"}
+test dict-16.18 {dict unset command: write failure} -body {
+    apply {{} {
+	set dictVar(block) {}
+	dict unset dictVar a
+    }}
+} -returnCodes error -result {can't set "dictVar": variable is array}
+
+test dict-17.1 {dict filter command: key} -body {
+    set dictVar {a1 a a2 b b1 c b2 d foo bar bar foo}
+    dict filter $dictVar key a2
+} -cleanup {
+    unset dictVar
+} -result {a2 b}
+test dict-17.2 {dict filter command: key} -body {
+    set dictVar {a1 a a2 b b1 c b2 d foo bar bar foo}
+    dict size [dict filter $dictVar key *]
+} -cleanup {
+    unset dictVar
+} -result 6
+test dict-17.3 {dict filter command: key} -body {
+    set dictVar {a1 a a2 b b1 c b2 d foo bar bar foo}
+    dict filter $dictVar key ???
+} -cleanup {
+    unset dictVar
+} -result {foo bar bar foo}
+test dict-17.4 {dict filter command: key - no patterns} {
+    dict filter {a b c d} key
+} {}
+test dict-17.4.1 {dict filter command: key - many patterns} {
+    dict filter {a1 a a2 b b1 c b2 d foo bar bar foo} key a? b?
+} {a1 a a2 b b1 c b2 d}
+test dict-17.5 {dict filter command: key - bad dict} -returnCodes error -body {
+    dict filter {a b c} key
+} -result {missing value to go with key}
+test dict-17.6 {dict filter command: value} -body {
+    set dictVar {a1 a a2 b b1 c b2 d foo bar bar foo}
+    dict filter $dictVar value c
+} -cleanup {
+    unset dictVar
+} -result {b1 c}
+test dict-17.7 {dict filter command: value} -body {
+    set dictVar {a1 a a2 b b1 c b2 d foo bar bar foo}
+    dict size [dict filter $dictVar value *]
+} -cleanup {
+    unset dictVar
+} -result 6
+test dict-17.8 {dict filter command: value} -body {
+    set dictVar {a1 a a2 b b1 c b2 d foo bar bar foo}
+    dict filter $dictVar value ???
+} -cleanup {
+    unset dictVar
+} -result {foo bar bar foo}
+test dict-17.9 {dict filter command: value - no patterns} {
+    dict filter {a b c d} value
+} {}
+test dict-17.9.1 {dict filter command: value - many patterns} {
+    dict filter {a a1 b a2 c b1 foo bar bar foo d b2} value a? b?
+} {a a1 b a2 c b1 d b2}
+test dict-17.10 {dict filter command: value - bad dict} -body {
+    dict filter {a b c} value a
+} -returnCodes error -result {missing value to go with key}
+test dict-17.11 {dict filter command: script} -body {
+    set dictVar {a1 a a2 b b1 c b2 d foo bar bar foo}
+    set n 0
+    list [dict filter $dictVar script {k v} {
+	incr n
+	expr {[string length $k] == [string length $v]}
+    }] $n
+} -cleanup {
+    unset dictVar n k v
+} -result {{foo bar bar foo} 6}
+test dict-17.12 {dict filter command: script} -returnCodes error -body {
+    dict filter {a b} script {k v} {
+	concat $k $v
+    }
+} -cleanup {
+    unset k v
+} -result {expected boolean value but got "a b"}
+test dict-17.13 {dict filter command: script} -body {
+    list [catch {dict filter {a b} script {k v} {error x}} msg] $msg \
+	    $::errorInfo
+} -cleanup {
+    unset k v msg
+} -result {1 x {x
+    while executing
+"error x"
+    ("dict filter" script line 1)
+    invoked from within
+"dict filter {a b} script {k v} {error x}"}}
+test dict-17.14 {dict filter command: script} -setup {
+    set n 0
+} -body {
+    list [dict filter {a b c d} script {k v} {
+	incr n
+	break
+	error boom!
+    }] $n
+} -cleanup {
+    unset n k v
+} -result {{} 1}
+test dict-17.15 {dict filter command: script} -setup {
+    set n 0
+} -body {
+    list [dict filter {a b c d} script {k v} {
+	incr n
+	continue
+	error boom!
+    }] $n
+} -cleanup {
+    unset n k v
+} -result {{} 2}
+test dict-17.16 {dict filter command: script} {
+    apply {{} {
+	dict filter {a b} script {k v} {
+	    return ok,$k,$v
+	    error "skipped return completely"
+	}
+	error "return didn't go far enough"
+    }}
+} ok,a,b
+test dict-17.17 {dict filter command: script} -body {
+    dict filter {a b} script {k k} {continue}
+    return $k
+} -cleanup {
+    unset k
+} -result b
+test dict-17.18 {dict filter command: script} -returnCodes error -body {
+    dict filter {a b} script {k k}
+} -result {wrong # args: should be "dict filter dictionary script {keyVarName valueVarName} filterScript"}
+test dict-17.19 {dict filter command: script} -returnCodes error -body {
+    dict filter {a b} script k {continue}
+} -result {must have exactly two variable names}
+test dict-17.20 {dict filter command: script} -returnCodes error -body {
+    dict filter {a b} script "\{k v" {continue}
+} -result {unmatched open brace in list}
+test dict-17.21 {dict filter command} -returnCodes error -body {
+    dict filter {a b}
+} -result {wrong # args: should be "dict filter dictionary filterType ?arg ...?"}
+test dict-17.22 {dict filter command} -returnCodes error -body {
+    dict filter {a b} JUNK
+} -result {bad filterType "JUNK": must be key, script, or value}
+test dict-17.23 {dict filter command} -returnCodes error -body {
+    dict filter a key *
+} -result {missing value to go with key}
+
+test dict-18.1 {dict-list relationship} -body {
+    # Test that any internal conversion between list and dict does not change
+    # the object
+    set l [list 1 2 3 4 5 6 7 8 9 0 q w e r t y]
+    dict values $l
+    return $l
+} -cleanup {
+    unset l
+} -result {1 2 3 4 5 6 7 8 9 0 q w e r t y}
+test dict-18.2 {dict-list relationship} -body {
+    # Test that the dictionary is a valid list
+    set d [dict create "abc def" 0 "a\{b" 1 "c\}d" 2]
+    for {set t 0} {$t < 5} {incr t} {
+	llength $d
+	dict lappend d "abc def" "\}\{"
+	dict append  d "a\{b" "\}"
+	dict incr    d "c\}d" 1
+    }
+    llength $d
+} -cleanup {
+    unset d t
+} -result 6
+test dict-18.3 {dict-list relationship} -body {
+    set ld [list a b c d c e f g]
+    list [string length $ld] [dict size $ld] [llength $ld]
+} -cleanup {
+    unset ld
+} -result {15 3 8}
+test dict-18.4 {dict-list relationship} -body {
+    set ld [list a b c d c e f g]
+    list [llength $ld] [dict size $ld] [llength $ld]
+} -cleanup {
+    unset ld
+} -result {8 3 8}
+
+# This is a test for a specific bug.
+# It shows a bad ref counter when running with memdebug on.
+test dict-19.1 {memory bug} {
+    apply {{} {
+        set successors [dict create x {c d}]
+        dict set successors x a b
+        dict get $successors x
+    }}
+} [dict create c d a b]
+test dict-19.2 {dict: testing for leaks} -constraints memory -body {
+    # This test is made to stress object reference management
+    memtest {
+	apply {{} {
+	    # A shared invalid dictinary
+	    set apa {a {}b c d}
+	    set bepa $apa
+	    catch {dict replace $apa e f}
+	    catch {dict remove  $apa c d}
+	    catch {dict incr    apa  a 5}
+	    catch {dict lappend apa  a 5}
+	    catch {dict append  apa  a 5}
+	    catch {dict set     apa  a 5}
+	    catch {dict unset   apa  a}
+
+	    # A shared valid dictionary, invalid incr
+	    set apa {a b c d}
+	    set bepa $apa
+	    catch {dict incr bepa a 5}
+
+	    # An error during write to an unshared object, incr
+	    set apa {a 1 b 2}
+	    set bepa [lrange $apa 0 end]
+	    trace add variable bepa write {error hej}
+	    catch {dict incr bepa a 5}
+	    trace remove variable bepa write {error hej}
+	    unset bepa
+
+	    # An error during write to a shared object, incr
+	    set apa {a 1 b 2}
+	    set bepa $apa
+	    trace add variable bepa write {error hej}
+	    catch {dict incr bepa a 5}
+	    trace remove variable bepa write {error hej}
+	    unset bepa
+
+	    # A shared valid dictionary, invalid lappend
+	    set apa [list a {{}b} c d]
+	    set bepa $apa
+	    catch {dict lappend bepa a 5}
+
+	    # An error during write to an unshared object, lappend
+	    set apa {a 1 b 2}
+	    set bepa [lrange $apa 0 end]
+	    trace add variable bepa write {error hej}
+	    catch {dict lappend bepa a 5}
+	    trace remove variable bepa write {error hej}
+	    unset bepa
+
+	    # An error during write to a shared object, lappend
+	    set apa {a 1 b 2}
+	    set bepa $apa
+	    trace add variable bepa write {error hej}
+	    catch {dict lappend bepa a 5}
+	    trace remove variable bepa write {error hej}
+	    unset bepa
+
+	    # An error during write to an unshared object, append
+	    set apa {a 1 b 2}
+	    set bepa [lrange $apa 0 end]
+	    trace add variable bepa write {error hej}
+	    catch {dict append bepa a 5}
+	    trace remove variable bepa write {error hej}
+	    unset bepa
+
+	    # An error during write to a shared object, append
+	    set apa {a 1 b 2}
+	    set bepa $apa
+	    trace add variable bepa write {error hej}
+	    catch {dict append bepa a 5}
+	    trace remove variable bepa write {error hej}
+	    unset bepa
+
+	    # An error during write to an unshared object, set
+	    set apa {a 1 b 2}
+	    set bepa [lrange $apa 0 end]
+	    trace add variable bepa write {error hej}
+	    catch {dict set bepa a 5}
+	    trace remove variable bepa write {error hej}
+	    unset bepa
+
+	    # An error during write to a shared object, set
+	    set apa {a 1 b 2}
+	    set bepa $apa
+	    trace add variable bepa write {error hej}
+	    catch {dict set bepa a 5}
+	    trace remove variable bepa write {error hej}
+	    unset bepa
+
+	    # An error during write to an unshared object, unset
+	    set apa {a 1 b 2}
+	    set bepa [lrange $apa 0 end]
+	    trace add variable bepa write {error hej}
+	    catch {dict unset bepa a}
+	    trace remove variable bepa write {error hej}
+	    unset bepa
+
+	    # An error during write to a shared object, unset
+	    set apa {a 1 b 2}
+	    set bepa $apa
+	    trace add variable bepa write {error hej}
+	    catch {dict unset bepa a}
+	    trace remove variable bepa write {error hej}
+	    unset bepa
+	}}
+    }
+} -result 0
+test dict-19.3 {testing for leaks - Bug 2874678} -constraints memory -body {
+    set d aDictVar; # Force interpreted [dict incr]
+    memtest {
+	dict incr $d aKey 0
+	unset $d
+    }
+} -cleanup {
+    unset d
+} -result 0
+
+test dict-20.1 {dict merge command} {
+    dict merge
+} {}
+test dict-20.2 {dict merge command} {
+    dict merge {a b c d e f}
+} {a b c d e f}
+test dict-20.3 {dict merge command} -body {
+    dict merge {a b c d e}
+} -result {missing value to go with key} -returnCodes error
+test dict-20.4 {dict merge command} {
+    dict merge {a b c d} {e f g h}
+} {a b c d e f g h}
+test dict-20.5 {dict merge command} -body {
+    dict merge {a b c d e} {e f g h}
+} -result {missing value to go with key} -returnCodes error
+test dict-20.6 {dict merge command} -body {
+    dict merge {a b c d} {e f g h i}
+} -result {missing value to go with key} -returnCodes error
+test dict-20.7 {dict merge command} {
+    dict merge {a b c d e f} {e x g h}
+} {a b c d e x g h}
+test dict-20.8 {dict merge command} {
+    dict merge {a b c d} {a x c y}
+} {a x c y}
+test dict-20.9 {dict merge command} {
+    dict merge {a b c d} {c y a x}
+} {a x c y}
+test dict-20.10 {dict merge command} {
+    dict merge {a b c d e f} {a x 1 2 3 4} {a - 1 -}
+} {a - c d e f 1 - 3 4}
+test dict-20.11 {dict merge command} {
+    apply {{} {dict merge}}
+} {}
+test dict-20.12 {dict merge command} {
+    apply {{} {dict merge {a b c d e f}}}
+} {a b c d e f}
+test dict-20.13 {dict merge command} -body {
+    apply {{} {dict merge {a b c d e}}}
+} -result {missing value to go with key} -returnCodes error
+test dict-20.14 {dict merge command} {
+    apply {{} {dict merge {a b c d} {e f g h}}}
+} {a b c d e f g h}
+test dict-20.15 {dict merge command} -body {
+    apply {{} {dict merge {a b c d e} {e f g h}}}
+} -result {missing value to go with key} -returnCodes error
+test dict-20.16 {dict merge command} -body {
+    apply {{} {dict merge {a b c d} {e f g h i}}}
+} -result {missing value to go with key} -returnCodes error
+test dict-20.17 {dict merge command} {
+    apply {{} {dict merge {a b c d e f} {e x g h}}}
+} {a b c d e x g h}
+test dict-20.18 {dict merge command} {
+    apply {{} {dict merge {a b c d} {a x c y}}}
+} {a x c y}
+test dict-20.19 {dict merge command} {
+    apply {{} {dict merge {a b c d} {c y a x}}}
+} {a x c y}
+test dict-20.20 {dict merge command} {
+    apply {{} {dict merge {a b c d e f} {a x 1 2 3 4} {a - 1 -}}}
+} {a - c d e f 1 - 3 4}
+test dict-20.21 {dict merge command: canonicality not forced} {
+    dict merge { a b c d }
+} { a b c d }
+test dict-20.22 {dict merge command: canonicality not forced} {
+    dict merge { a b c d } {}
+} { a b c d }
+test dict-20.23 {dict merge command: canonicality forced by update} {
+    dict merge { a b c d } {a b}
+} {a b c d}
+test dict-20.24 {dict merge command: type check is mandatory} -body {
+    dict merge { a b c d e }
+} -returnCodes error -result {missing value to go with key}
+test dict-20.25 {dict merge command: type check is mandatory} -body {
+    dict merge { a b {}c d }
+} -returnCodes error -result {dict element in braces followed by "c" instead of space}
+
+test dict-21.1 {dict update command} -returnCodes 1 -body {
+    dict update
+} -result {wrong # args: should be "dict update dictVarName key varName ?key varName ...? script"}
+test dict-21.2 {dict update command} -returnCodes 1 -body {
+    dict update v
+} -result {wrong # args: should be "dict update dictVarName key varName ?key varName ...? script"}
+test dict-21.3 {dict update command} -returnCodes 1 -body {
+    dict update v k
+} -result {wrong # args: should be "dict update dictVarName key varName ?key varName ...? script"}
+test dict-21.4 {dict update command} -returnCodes 1 -body {
+    dict update v k v
+} -result {wrong # args: should be "dict update dictVarName key varName ?key varName ...? script"}
+test dict-21.5 {dict update command} -body {
+    set a {b c}
+    set result {}
+    set bb {}
+    dict update a b bb {
+	lappend result $a $bb
+    }
+    lappend result $a
+} -cleanup {
+    unset a result bb
+} -result {{b c} c {b c}}
+test dict-21.6 {dict update command} -body {
+    set a {b c}
+    set result {}
+    set bb {}
+    dict update a b bb {
+	lappend result $a $bb [set bb d]
+    }
+    lappend result $a
+} -cleanup {
+    unset a result bb
+} -result {{b c} c d {b d}}
+test dict-21.7 {dict update command} -body {
+    set a {b c}
+    set result {}
+    set bb {}
+    dict update a b bb {
+	lappend result $a $bb [unset bb]
+    }
+    lappend result $a
+} -cleanup {
+    unset a result
+} -result {{b c} c {} {}}
+test dict-21.8 {dict update command} -body {
+    set a {b c d e}
+    dict update a b v1 d v2 {
+	lassign "$v1 $v2" v2 v1
+    }
+    return $a
+} -cleanup {
+    unset a v1 v2
+} -result {b e d c}
+test dict-21.9 {dict update command} -body {
+    set a {b c d e}
+    dict update a b v1 d v2 {unset a}
+    info exist a
+} -cleanup {
+    unset v1 v2
+} -result 0
+test dict-21.10 {dict update command} -body {
+    set a {b {c d}}
+    dict update a b v1 {
+	dict update v1 c v2 {
+	    set v2 foo
+	}
+    }
+    return $a
+} -cleanup {
+    unset a v1 v2
+} -result {b {c foo}}
+test dict-21.11 {dict update command} -body {
+    set a {b c d e}
+    dict update a b v1 d v2 {
+	dict set a f g
+    }
+    return $a
+} -cleanup {
+    unset a v1 v2
+} -result {b c d e f g}
+test dict-21.12 {dict update command} -body {
+    set a {b c d e}
+    dict update a b v1 d v2 f v3 {
+	set v3 g
+    }
+    return $a
+} -cleanup {
+    unset a v1 v2 v3
+} -result {b c d e f g}
+test dict-21.13 {dict update command: compilation} {
+    apply {d {
+	while 1 {
+	    dict update d a alpha b beta {
+		set beta $alpha
+		unset alpha
+		break
+	    }
+	}
+	return $d
+    }} {a 1 c 2}
+} {c 2 b 1}
+test dict-21.14 {dict update command: compilation} {
+    apply {x {
+	set indices {2 3}
+	trace add variable aa write "string length \$indices ;#"
+	dict update x k aa l bb {}
+    }} {k 1 l 2}
+} {}
+test dict-21.15 {dict update command: compilation} {
+    apply {x {
+	set indices {2 3}
+	trace add variable aa read "string length \$indices ;#"
+	dict update x k aa l bb {}
+    }} {k 1 l 2}
+} {}
+test dict-21.16 {dict update command: no recursive structures [Bug 1786481]} -body {
+    set foo {a {b {c {d {e 1}}}}}
+    dict update foo a t {
+	dict update t b t {
+	    dict update t c t {
+		dict update t d t {
+		    dict incr t e
+		}
+	    }
+	}
+    }
+    string range [append foo OK] end-1 end
+} -cleanup {
+    unset foo t
+} -result OK
+test dict-21.17 {dict update command: no recursive structures [Bug 1786481]} {
+    apply {{} {
+	set foo {a {b {c {d {e 1}}}}}
+	dict update foo a t {
+	    dict update t b t {
+		dict update t c t {
+		    dict update t d t {
+			dict incr t e
+		    }
+		}
+	    }
+	}
+	string range [append foo OK] end-1 end
+    }}
+} OK
+
+test dict-22.1 {dict with command} -body {
+    dict with
+} -returnCodes 1 -result {wrong # args: should be "dict with dictVarName ?key ...? script"}
+test dict-22.2 {dict with command} -body {
+    dict with v
+} -returnCodes 1 -result {wrong # args: should be "dict with dictVarName ?key ...? script"}
+test dict-22.3 {dict with command} -body {
+    unset -nocomplain v
+    dict with v {error "in body"}
+} -returnCodes 1 -result {can't read "v": no such variable}
+test dict-22.4 {dict with command} -body {
+    set a {b c d e}
+    unset -nocomplain b d
+    set result [list [info exist b] [info exist d]]
+    dict with a {
+	lappend result [info exist b] [info exist d] $b $d
+    }
+    return $result
+} -cleanup {
+    unset a b d result
+} -result {0 0 1 1 c e}
+test dict-22.5 {dict with command} -body {
+    set a {b c d e}
+    dict with a {
+	lassign "$b $d" d b
+    }
+    return $a
+} -cleanup {
+    unset a b d
+} -result {b e d c}
+test dict-22.6 {dict with command} -body {
+    set a {b c d e}
+    dict with a {
+	unset b
+	# This *won't* go into the dict...
+	set f g
+    }
+    return $a
+} -cleanup {
+    unset a d f
+} -result {d e}
+test dict-22.7 {dict with command} -body {
+    set a {b c d e}
+    dict with a {
+	dict unset a b
+    }
+    return $a
+} -cleanup {
+    unset a
+} -result {d e b c}
+test dict-22.8 {dict with command} -body {
+    set a [dict create b c]
+    dict with a {
+	set b $a
+    }
+    return $a
+} -cleanup {
+    unset a b
+} -result {b {b c}}
+test dict-22.9 {dict with command} -body {
+    set a {b {c d}}
+    dict with a b {
+	set c $c$c
+    }
+    return $a
+} -cleanup {
+    unset a c
+} -result {b {c dd}}
+test dict-22.10 {dict with command: result handling tricky case} -body {
+    set a {b {c d}}
+    foreach i {0 1} {
+	if {$i} break
+	dict with a b {
+	    set a {}
+	    # We're checking to see if we lose this break
+	    break
+	}
+    }
+    list $i $a
+} -cleanup {
+    unset a i c
+} -result {0 {}}
+test dict-22.11 {dict with command: no recursive structures [Bug 1786481]} -body {
+    set foo {t {t {t {inner 1}}}}
+    dict with foo {
+	dict with t {
+	    dict with t {
+		dict with t {
+		    incr inner
+		}
+	    }
+	}
+    }
+    string range [append foo OK] end-1 end
+} -cleanup {
+    unset foo t inner
+} -result OK
+test dict-22.12 {dict with: compiled} {
+    apply {{} {
+	set d {a 1 b 2}
+	list [dict with d {
+	    set a $b
+	    unset b
+	    dict set d c 3
+	    list ok
+	}] $d
+    }}
+} {ok {a 2 c 3}}
+test dict-22.13 {dict with: compiled} {
+    apply {i {
+	set d($i) {a 1 b 2}
+	list [dict with d($i) {
+	    set a $b
+	    unset b
+	    dict set d($i) c 3
+	    list ok
+	}] [array get d]
+    }} e
+} {ok {e {a 2 c 3}}}
+test dict-22.14 {dict with: compiled} {
+    apply {{} {
+	set d {a 1 b 2}
+	foreach x {1 2 3} {
+	    dict with d {
+		incr a $b
+		if {$x == 2} break
+	    }
+	    unset a b
+	}
+	list $a $b $x $d
+    }}
+} {5 2 2 {a 5 b 2}}
+test dict-22.15 {dict with: compiled} {
+    apply {i {
+	set d($i) {a 1 b 2}
+	foreach x {1 2 3} {
+	    dict with d($i) {
+		incr a $b
+		if {$x == 2} break
+	    }
+	    unset a b
+	}
+	list $a $b $x [array get d]
+    }} e
+} {5 2 2 {e {a 5 b 2}}}
+test dict-22.16 {dict with: compiled} {
+    apply {{} {
+	set d {p {q {a 1 b 2}}}
+	dict with d p q {
+	    set a $b.$a
+	}
+	return $d
+    }}
+} {p {q {a 2.1 b 2}}}
+test dict-22.17 {dict with: compiled} {
+    apply {i {
+	set d($i) {p {q {a 1 b 2}}}
+	dict with d($i) p q {
+	    set a $b.$a
+	}
+	array get d
+    }} e
+} {e {p {q {a 2.1 b 2}}}}
+test dict-22.18 {dict with: compiled} {
+    set ::d {a 1 b 2}
+    apply {{} {
+	dict with ::d {
+	    set a $b.$a
+	}
+	return $::d
+    }}
+} {a 2.1 b 2}
+test dict-22.19 {dict with: compiled} {
+    set ::d {p {q {r {a 1 b 2}}}}
+    apply {{} {
+	dict with ::d p q r {
+	    set a $b.$a
+	}
+	return $::d
+    }}
+} {p {q {r {a 2.1 b 2}}}}
+test dict-22.20 {dict with: compiled} {
+    apply {d {
+	dict with d {
+	}
+	return $a,$b
+    }} {a 1 b 2}
+} 1,2
+test dict-22.21 {dict with: compiled} {
+    apply {d {
+	dict with d p q {
+	}
+	return $a,$b
+    }} {p {q {a 1 b 2}}}
+} 1,2
+test dict-22.22 {dict with: compiled} {
+    set ::d {a 1 b 2}
+    apply {{} {
+	dict with ::d {
+	}
+	return $a,$b
+    }}
+} 1,2
+test dict-22.23 {dict with: compiled} {
+    set ::d {p {q {a 1 b 2}}}
+    apply {{} {
+	dict with ::d p q {
+	}
+	return $a,$b
+    }}
+} 1,2
+
+proc linenumber {} {
+    dict get [info frame -1] line
+}
+test dict-23.1 {dict compilation crash: Bug 3487626} {
+    apply {{} {apply {n {
+	set e {}
+	set k {}
+	dict for {a b} {c {d {e {f g}}}} {
+	    ::tcl::dict::for {h i} $b {
+		dict update i e j {
+		    ::tcl::dict::update j f k {
+			return [expr {$n - [linenumber]}]
+		    }
+		}
+	    }
+	}
+    }} [linenumber]}}
+} 5
+test dict-23.2 {dict compilation crash: Bug 3487626} {
+    # Something isn't quite right in line number and continuation line
+    # tracking; at time of writing, this test produces 7, not 5, which
+    # indicates that the extra newlines in the non-script argument are
+    # confusing things.
+    apply {{} {apply {n {
+	set e {}
+	set k {}
+	dict for {a {
+b
+}} {c {d {e {f g}}}} {
+	    ::tcl::dict::for {h {
+i
+}} ${
+b
+} {
+		dict update {
+i
+} e {
+j
+} {
+		    ::tcl::dict::update {
+j
+} f k {
+			return [expr {$n - [linenumber]}]
+		    }
+		}
+	    }
+	}
+    }} [linenumber]}}
+} 5
+rename linenumber {}
+
+test dict-24.1 {dict map command: syntax} -returnCodes error -body {
+    dict map
+} -result {wrong # args: should be "dict map {keyVarName valueVarName} dictionary script"}
+test dict-24.2 {dict map command: syntax} -returnCodes error -body {
+    dict map x
+} -result {wrong # args: should be "dict map {keyVarName valueVarName} dictionary script"}
+test dict-24.3 {dict map command: syntax} -returnCodes error -body {
+    dict map x x
+} -result {wrong # args: should be "dict map {keyVarName valueVarName} dictionary script"}
+test dict-24.4 {dict map command: syntax} -returnCodes error -body {
+    dict map x x x x
+} -result {wrong # args: should be "dict map {keyVarName valueVarName} dictionary script"}
+test dict-24.5 {dict map command: syntax} -returnCodes error -body {
+    dict map x x x
+} -result {must have exactly two variable names}
+test dict-24.6 {dict map command: syntax} -returnCodes error -body {
+    dict map {x x x} x x
+} -result {must have exactly two variable names}
+test dict-24.7 {dict map command: syntax} -returnCodes error -body {
+    dict map "\{x" x x
+} -result {unmatched open brace in list}
+test dict-24.8 {dict map command} -setup {
+    set values {}
+    set keys {}
+} -body {
+    # This test confirms that [dict keys], [dict values] and [dict map]
+    # all traverse a dictionary in the same order.
+    set dictv {a A b B c C}
+    dict map {k v} $dictv {
+	lappend keys $k
+	lappend values $v
+    }
+    set result [expr {
+	$keys eq [dict keys $dictv] && $values eq [dict values $dictv]
+    }]
+    expr {$result ? "YES" : [list "NO" $dictv $keys $values]}
+} -cleanup {
+    unset result keys values k v dictv
+} -result YES
+test dict-24.9 {dict map command} {
+    dict map {k v} {} {
+	error "unexpected execution of 'dict map' body"
+    }
+} {}
+test dict-24.10 {dict map command: script results} -body {
+    set times 0
+    dict map {k v} {a a b b} {
+	incr times
+	continue
+	error "shouldn't get here"
+    }
+    return $times
+} -cleanup {
+    unset times k v
+} -result 2
+test dict-24.11 {dict map command: script results} -body {
+    set times 0
+    dict map {k v} {a a b b} {
+	incr times
+	break
+	error "shouldn't get here"
+    }
+    return $times
+} -cleanup {
+    unset times k v
+} -result 1
+test dict-24.12 {dict map command: script results} -body {
+    set times 0
+    list [catch {
+	dict map {k v} {a a b b} {
+	    incr times
+	    error test
+	}
+    } msg] $msg $times $::errorInfo
+} -cleanup {
+    unset times k v msg
+} -result {1 test 1 {test
+    while executing
+"error test"
+    ("dict map" body line 3)
+    invoked from within
+"dict map {k v} {a a b b} {
+	    incr times
+	    error test
+	}"}}
+test dict-24.13 {dict map command: script results} {
+    apply {{} {
+	dict map {k v} {a b} {
+	    return ok,$k,$v
+	    error "skipped return completely"
+	}
+	error "return didn't go far enough"
+    }}
+} ok,a,b
+test dict-24.14 {dict map command: handle representation loss} -setup {
+    set keys {}
+    set values {}
+} -body {
+    set dictVar {a b c d e f g h}
+    list [dict size [dict map {k v} $dictVar {
+	if {[llength $dictVar]} {
+	    lappend keys $k
+	    lappend values $v
+	    return -level 0 $k
+	}
+    }]] [lsort $keys] [lsort $values]
+} -cleanup {
+    unset dictVar keys values k v
+} -result {4 {a c e g} {b d f h}}
+test dict-24.14a {dict map command: handle representation loss} -body {
+    apply {{} {
+	set dictVar {a b c d e f g h}
+	list [dict size [dict map {k v} $dictVar {
+	    if {[llength $dictVar]} {
+		lappend keys $k
+		lappend values $v
+		return -level 0 $k
+	    }
+	}]] [lsort $keys] [lsort $values]
+    }}
+} -result {4 {a c e g} {b d f h}}
+test dict-24.15 {dict map command: keys are unique and iterated over once only} -setup {
+    unset -nocomplain accum
+    array set accum {}
+} -body {
+    set dictVar {a1 a a2 b b1 c b2 d foo bar bar foo}
+    dict map {k v} $dictVar {
+	append accum($k) $v,
+    }
+    set result [lsort [array names accum]]
+    lappend result :
+    foreach k $result {
+	catch {lappend result $accum($k)}
+    }
+    return $result
+} -cleanup {
+    unset dictVar k v result accum
+} -result {a1 a2 b1 b2 bar foo : a, b, c, d, foo, bar,}
+test dict-24.16 {dict map command in compilation context} {
+    apply {{} {
+	set res {x x x x x x}
+	dict map {k v} {a 0 b 1 c 2 d 3 e 4 f 5} {
+	    lset res $v $k
+	    continue
+	}
+	return $res
+    }}
+} {a b c d e f}
+test dict-24.17 {dict map command in compilation context} {
+    # Bug 1379349 (dict for)
+    apply {{} {
+	set d [dict create a 1]		;# Dict must be unshared!
+	dict map {k v} $d {
+	    dict set d $k 0		;# Any modification will do
+	}
+	return $d
+    }}
+} {a 0}
+test dict-24.17a {dict map command in compilation context} {
+    # Bug 1379349 (dict for)
+    apply {{} {
+	set d [dict create a 1]		;# Dict must be unshared!
+	dict map {k v} $d {
+	    dict set d $k 0		;# Any modification will do
+	}
+    }}
+} {a {a 0}}
+test dict-24.18 {dict map command in compilation context} {
+    # Bug 1382528 (dict for)
+    apply {{} {
+	dict map {k v} {} {}		;# Note empty dict
+	catch { error foo }		;# Note compiled [catch]
+    }}
+} 1
+test dict-24.19 {dict map and invalid dicts: 'dict for' bug 1531184} -body {
+    di[list]ct map {k v} x {}
+} -returnCodes 1 -result {missing value to go with key}
+test dict-24.20 {dict map stack space compilation: 'dict for' bug 1903325} {
+    apply {{x y args} {
+	dict map {a b} $x {}
+	concat "c=$y,$args"
+    }} {} 1 2 3
+} {c=1,2 3}
+proc linenumber {} {
+    dict get [info frame -1] line
+}
+test dict-24.20.1 {dict compilation crash: 'dict for' bug 3487626} {
+    apply {{} {apply {n {
+	set e {}
+	set k {}
+	dict map {a b} {c {d {e {f g}}}} {
+	    ::tcl::dict::map {h i} $b {
+		dict update i e j {
+		    ::tcl::dict::update j f k {
+			return [expr {$n - [linenumber]}]
+		    }
+		}
+	    }
+	}
+    }} [linenumber]}}
+} 5
+test dict-24.21 {dict compilation crash: 'dict for' bug 3487626} {
+    apply {{} {apply {n {
+	set e {}
+	set k {}
+	dict map {a {
+b
+}} {c {d {e {f g}}}} {
+	    ::tcl::dict::map {h {
+i
+}} ${
+b
+} {
+		dict update {
+i
+} e {
+j
+} {
+		    ::tcl::dict::update {
+j
+} f k {
+			return [expr {$n - [linenumber]}]
+		    }
+		}
+	    }
+	}
+    }} [linenumber]}}
+} 5
+test dict-23.3 {CompileWord OBOE} {
+    # segfault when buggy
+    apply {{} {tcl::dict::lappend foo bar \
+	[format baz]}}
+} {bar baz}
+test dict-23.4 {CompileWord OBOE} {
+    apply {n {
+	dict set foo {*}{
+	} [return [incr n -[linenumber]]] val
+    }} [linenumber]
+} 1
+test dict-23.5 {CompileWord OBOE} {
+    # segfault when buggy
+    apply {{} {tcl::dict::incr foo \
+	[format bar]}}
+} {bar 1}
+test dict-23.6 {CompileWord OBOE} {
+    apply {n {
+	dict get {a b} {*}{
+	} [return [incr n -[linenumber]]]
+    }} [linenumber]
+} 1
+test dict-23.7 {CompileWord OBOE} {
+    apply {n {
+	dict for {a b} [return [incr n -[linenumber]]] {*}{
+	} {}
+    }} [linenumber]
+} 2
+test dict-23.8 {CompileWord OBOE} {
+    apply {n {
+	dict update foo {*}{
+	} [return [incr n -[linenumber]]] x {}
+    }} [linenumber]
+} 1
+test dict-23.9 {CompileWord OBOE} {
+    apply {n {
+	dict exists {} {*}{
+	} [return [incr n -[linenumber]]]
+    }} [linenumber]
+} 1
+test dict-23.10 {CompileWord OBOE} {
+    apply {n {
+	dict with foo {*}{
+	} [return [incr n -[linenumber]]] {}
+    }} [linenumber]
+} 1
+test dict-23.11 {CompileWord OBOE} {
+    apply {n {
+	dict with ::foo {*}{
+	} [return [incr n -[linenumber]]] {}
+    }} [linenumber]
+} 1
+test dict-23.12 {CompileWord OBOE} {
+    apply {n {
+	dict with {*}{
+	} [return [incr n -[linenumber]]] {}
+    }} [linenumber]
+} 1
+test dict-23.13 {CompileWord OBOE} {
+    apply {n {
+	dict with {*}{
+	} [return [incr n -[linenumber]]] {bar}
+    }} [linenumber]
+} 1
+test dict-23.14 {CompileWord OBOE} {
+    apply {n {
+	dict with foo {*}{
+	} [return [incr n -[linenumber]]] {bar}
+    }} [linenumber]
+} 1
+
+rename linenumber {}
+test dict-24.22 {dict map results (non-compiled)} {
+    dict map {k v} [dict map {k v} {a 1 b 2 c 3 d 4} { list $v $k }] {
+	return -level 0 "$k,$v"
+    }
+} {a {a,1 a} b {b,2 b} c {c,3 c} d {d,4 d}}
+test dict-24.23 {dict map results (compiled)} {
+    apply {{} {
+	dict map {k v} [dict map {k v} {a 1 b 2 c 3 d 4} { list $v $k }] {
+	    return -level 0 "$k,$v"
+	}
+    }}
+} {a {a,1 a} b {b,2 b} c {c,3 c} d {d,4 d}}
+test dict-24.23a {dict map results (compiled)} {
+    apply {{list} {
+	dict map {k v} [dict map {k v} $list { list $v $k }] {
+	    return -level 0 "$k,$v"
+	}
+    }} {a 1 b 2 c 3 d 4}
+} {a {a,1 a} b {b,2 b} c {c,3 c} d {d,4 d}}
+test dict-24.24 {dict map with huge dict (non-compiled)} {
+    tcl::mathop::+ {*}[dict map {k v} [lsearch -all [lrepeat 100000 x] x] {
+	expr { $k * $v }
+    }]
+} 166666666600000
+test dict-24.25 {dict map with huge dict (compiled)} {
+    apply {{n} {
+	tcl::mathop::+ {*}[dict map {k v} [lsearch -all [lrepeat $n y] y] {
+	    expr { $k * $v }
+	}]
+    }} 100000
+} 166666666600000
+
+test dict-25.1 {compiled dict update with low-refcount values [Bug d553228d9f]} {
+    # Test crashes on failure
+    apply {{} {
+	lassign {} item
+	dict update item item item two two {}
+    }}
+} {}
+
+# cleanup
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/tests/dstring.test b/tests/dstring.test
new file mode 100644
index 0000000..06121a3
--- /dev/null
+++ b/tests/dstring.test
@@ -0,0 +1,439 @@
+# Commands covered:  none
+#
+# This file contains a collection of tests for Tcl's dynamic string library
+# procedures. Sourcing this file into Tcl runs the tests and generates output
+# for errors. No output means no errors were found.
+#
+# Copyright (c) 1993 The Regents of the University of California.
+# Copyright (c) 1994 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution of
+# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {"::tcltest" ni [namespace children]} {
+    package require tcltest
+    namespace import -force ::tcltest::*
+}
+
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
+
+testConstraint testdstring [llength [info commands testdstring]]
+if {[testConstraint testdstring]} {
+    testdstring free
+}
+
+test dstring-1.1 {appending and retrieving} -constraints testdstring -setup {
+    testdstring free
+} -body {
+    testdstring append "abc" -1
+    list [testdstring get] [testdstring length]
+} -cleanup {
+    testdstring free
+} -result {abc 3}
+test dstring-1.2 {appending and retrieving} -constraints testdstring -setup {
+    testdstring free
+} -body {
+    testdstring append "abc" -1
+    testdstring append " xyzzy" 3
+    testdstring append " 12345" -1
+    list [testdstring get] [testdstring length]
+} -cleanup {
+    testdstring free
+} -result {{abc xy 12345} 12}
+test dstring-1.3 {appending and retrieving} -constraints testdstring -setup {
+    testdstring free
+} -body {
+    foreach l {a b c d e f g h i j k l m n o p} {
+	testdstring append $l$l$l$l$l$l$l$l$l$l$l$l$l$l$l$l$l$l$l$l$l\n -1
+    }
+    list [testdstring get] [testdstring length]
+} -cleanup {
+    testdstring free
+} -result {{aaaaaaaaaaaaaaaaaaaaa
+bbbbbbbbbbbbbbbbbbbbb
+ccccccccccccccccccccc
+ddddddddddddddddddddd
+eeeeeeeeeeeeeeeeeeeee
+fffffffffffffffffffff
+ggggggggggggggggggggg
+hhhhhhhhhhhhhhhhhhhhh
+iiiiiiiiiiiiiiiiiiiii
+jjjjjjjjjjjjjjjjjjjjj
+kkkkkkkkkkkkkkkkkkkkk
+lllllllllllllllllllll
+mmmmmmmmmmmmmmmmmmmmm
+nnnnnnnnnnnnnnnnnnnnn
+ooooooooooooooooooooo
+ppppppppppppppppppppp
+} 352}
+
+test dstring-2.1 {appending list elements} -constraints testdstring -setup {
+    testdstring free
+} -body {
+    testdstring element "abc"
+    testdstring element "d e f"
+    list [testdstring get] [testdstring length]
+} -cleanup {
+    testdstring free
+} -result {{abc {d e f}} 11}
+test dstring-2.2 {appending list elements} -constraints testdstring -setup {
+    testdstring free
+} -body {
+    testdstring element "x"
+    testdstring element "\{"
+    testdstring element "ab\}"
+    testdstring get
+} -cleanup {
+    testdstring free
+} -result {x \{ ab\}}
+test dstring-2.3 {appending list elements} -constraints testdstring -setup {
+    testdstring free
+} -body {
+    foreach l {a b c d e f g h i j k l m n o p} {
+	testdstring element $l$l$l$l$l$l$l$l$l$l$l$l$l$l$l$l$l$l$l$l$l
+    }
+    testdstring get
+} -cleanup {
+    testdstring free
+} -result {aaaaaaaaaaaaaaaaaaaaa bbbbbbbbbbbbbbbbbbbbb ccccccccccccccccccccc ddddddddddddddddddddd eeeeeeeeeeeeeeeeeeeee fffffffffffffffffffff ggggggggggggggggggggg hhhhhhhhhhhhhhhhhhhhh iiiiiiiiiiiiiiiiiiiii jjjjjjjjjjjjjjjjjjjjj kkkkkkkkkkkkkkkkkkkkk lllllllllllllllllllll mmmmmmmmmmmmmmmmmmmmm nnnnnnnnnnnnnnnnnnnnn ooooooooooooooooooooo ppppppppppppppppppppp}
+test dstring-2.4 {appending list elements} -constraints testdstring -setup {
+    testdstring free
+} -body {
+    testdstring append "a\{" -1
+    testdstring element abc
+    testdstring append "	\{" -1
+    testdstring element xyzzy
+    testdstring get
+} -cleanup {
+    testdstring free
+} -result "a{ abc	{xyzzy"
+test dstring-2.5 {appending list elements} -constraints testdstring -setup {
+    testdstring free
+} -body {
+    testdstring append " \{" -1
+    testdstring element abc
+    testdstring get
+} -cleanup {
+    testdstring free
+} -result " {abc"
+test dstring-2.6 {appending list elements} -constraints testdstring -setup {
+    testdstring free
+} -body {
+    testdstring append " " -1
+    testdstring element abc
+    testdstring get
+} -cleanup {
+    testdstring free
+} -result { abc}
+test dstring-2.7 {appending list elements} -constraints testdstring -setup {
+    testdstring free
+} -body {
+    testdstring append "\\ " -1
+    testdstring element abc
+    testdstring get
+} -cleanup {
+    testdstring free
+} -result "\\  abc"
+test dstring-2.8 {appending list elements} -constraints testdstring -setup {
+    testdstring free
+} -body {
+    testdstring append "x " -1
+    testdstring element abc
+    testdstring get
+} -cleanup {
+    testdstring free
+} -result {x abc}
+test dstring-2.9 {appending list elements} -constraints testdstring -setup {
+    testdstring free
+} -body {
+    testdstring element #
+    testdstring get
+} -cleanup {
+    testdstring free
+} -result {{#}}
+test dstring-2.10 {appending list elements} -constraints testdstring -setup {
+    testdstring free
+} -body {
+    testdstring append " " -1
+    testdstring element #
+    testdstring get
+} -cleanup {
+    testdstring free
+} -result { {#}}
+test dstring-2.11 {appending list elements} -constraints testdstring -setup {
+    testdstring free
+} -body {
+    testdstring append \t -1
+    testdstring element #
+    testdstring get
+} -cleanup {
+    testdstring free
+} -result \t{#}
+test dstring-2.12 {appending list elements} -constraints testdstring -setup {
+    testdstring free
+} -body {
+    testdstring append x -1
+    testdstring element #
+    testdstring get
+} -cleanup {
+    testdstring free
+} -result {x #}
+test dstring-2.13 {appending list elements} -constraints testdstring -body {
+    # This test shows lack of sophistication in Tcl_DStringAppendElement's
+    # decision about whether #-quoting can be disabled.
+    testdstring free
+    testdstring append "x " -1
+    testdstring element #
+    testdstring get
+} -cleanup {
+    testdstring free
+} -result {x {#}}
+
+test dstring-3.1 {nested sublists} -constraints testdstring -setup {
+    testdstring free
+} -body {
+    testdstring start
+    testdstring element foo
+    testdstring element bar
+    testdstring end
+    testdstring element another
+    testdstring get
+} -cleanup {
+    testdstring free
+} -result {{foo bar} another}
+test dstring-3.2 {nested sublists} -constraints testdstring -setup {
+    testdstring free
+} -body {
+    testdstring start
+    testdstring start
+    testdstring element abc
+    testdstring element def
+    testdstring end
+    testdstring end
+    testdstring element ghi
+    testdstring get
+} -cleanup {
+    testdstring free
+} -result {{{abc def}} ghi}
+test dstring-3.3 {nested sublists} -constraints testdstring -setup {
+    testdstring free
+} -body {
+    testdstring start
+    testdstring start
+    testdstring start
+    testdstring element foo
+    testdstring element foo2
+    testdstring end
+    testdstring end
+    testdstring element foo3
+    testdstring end
+    testdstring element foo4
+    testdstring get
+} -cleanup {
+    testdstring free
+} -result {{{{foo foo2}} foo3} foo4}
+test dstring-3.4 {nested sublists} -constraints testdstring -setup {
+    testdstring free
+} -body {
+    testdstring element before
+    testdstring start
+    testdstring element during
+    testdstring element more
+    testdstring end
+    testdstring element last
+    testdstring get
+} -cleanup {
+    testdstring free
+} -result {before {during more} last}
+test dstring-3.5 {nested sublists} -constraints testdstring -setup {
+    testdstring free
+} -body {
+    testdstring element "\{"
+    testdstring start
+    testdstring element first
+    testdstring element second
+    testdstring end
+    testdstring get
+} -cleanup {
+    testdstring free
+} -result {\{ {first second}}
+test dstring-3.6 {appending list elements} -constraints testdstring -setup {
+    testdstring free
+} -body {
+    testdstring append x -1
+    testdstring start
+    testdstring element #
+    testdstring end
+    testdstring get
+} -cleanup {
+    testdstring free
+} -result {x {{#}}}
+test dstring-3.7 {appending list elements} -constraints testdstring -setup {
+    testdstring free
+} -body {
+    testdstring append x -1
+    testdstring start
+    testdstring append " " -1
+    testdstring element #
+    testdstring end
+    testdstring get
+} -cleanup {
+    testdstring free
+} -result {x { {#}}}
+test dstring-3.8 {appending list elements} -constraints testdstring -setup {
+    testdstring free
+} -body {
+    testdstring append x -1
+    testdstring start
+    testdstring append \t -1
+    testdstring element #
+    testdstring end
+    testdstring get
+} -cleanup {
+    testdstring free
+} -result "x {\t{#}}"
+test dstring-3.9 {appending list elements} -constraints testdstring -setup {
+    testdstring free
+} -body {
+    testdstring append x -1
+    testdstring start
+    testdstring append x -1
+    testdstring element #
+    testdstring end
+    testdstring get
+} -cleanup {
+    testdstring free
+} -result {x {x #}}
+test dstring-3.10 {appending list elements} -constraints testdstring -body {
+    # This test shows lack of sophistication in Tcl_DStringAppendElement's
+    # decision about whether #-quoting can be disabled.
+    testdstring free
+    testdstring append x -1
+    testdstring start
+    testdstring append "x " -1
+    testdstring element #
+    testdstring end
+    testdstring get
+} -cleanup {
+    testdstring free
+} -result {x {x {#}}}
+
+test dstring-4.1 {truncation} -constraints testdstring -setup {
+    testdstring free
+} -body {
+    testdstring append "abcdefg" -1
+    testdstring trunc 3
+    list [testdstring get] [testdstring length]
+} -cleanup {
+    testdstring free
+} -result {abc 3}
+test dstring-4.2 {truncation} -constraints testdstring -setup {
+    testdstring free
+} -body {
+    testdstring append "xyzzy" -1
+    testdstring trunc 0
+    list [testdstring get] [testdstring length]
+} -cleanup {
+    testdstring free
+} -result {{} 0}
+
+test dstring-5.1 {copying to result} -constraints testdstring -setup {
+    testdstring free
+} -body {
+    testdstring append xyz -1
+    testdstring result
+} -cleanup {
+    testdstring free
+} -result xyz
+test dstring-5.2 {copying to result} -constraints testdstring -setup {
+    testdstring free
+    unset -nocomplain a
+} -body {
+    foreach l {a b c d e f g h i j k l m n o p} {
+	testdstring append $l$l$l$l$l$l$l$l$l$l$l$l$l$l$l$l$l$l$l$l$l\n -1
+    }
+    set a [testdstring result]
+    testdstring append abc -1
+    list $a [testdstring get]
+} -cleanup {
+    testdstring free
+} -result {{aaaaaaaaaaaaaaaaaaaaa
+bbbbbbbbbbbbbbbbbbbbb
+ccccccccccccccccccccc
+ddddddddddddddddddddd
+eeeeeeeeeeeeeeeeeeeee
+fffffffffffffffffffff
+ggggggggggggggggggggg
+hhhhhhhhhhhhhhhhhhhhh
+iiiiiiiiiiiiiiiiiiiii
+jjjjjjjjjjjjjjjjjjjjj
+kkkkkkkkkkkkkkkkkkkkk
+lllllllllllllllllllll
+mmmmmmmmmmmmmmmmmmmmm
+nnnnnnnnnnnnnnnnnnnnn
+ooooooooooooooooooooo
+ppppppppppppppppppppp
+} abc}
+
+test dstring-6.1 {Tcl_DStringGetResult} -constraints testdstring -setup {
+    testdstring free
+} -body {
+    list [testdstring gresult staticsmall] [testdstring get]
+} -cleanup {
+    testdstring free
+} -result {{} short}
+test dstring-6.2 {Tcl_DStringGetResult} -constraints testdstring -setup {
+    testdstring free
+} -body {
+    foreach l {a b c d e f g h i j k l m n o p} {
+	testdstring append $l$l$l$l$l$l$l$l$l$l$l$l$l$l$l$l$l$l$l$l$l\n -1
+    }
+    list [testdstring gresult staticsmall] [testdstring get]
+} -cleanup {
+    testdstring free
+} -result {{} short}
+test dstring-6.3 {Tcl_DStringGetResult} -constraints testdstring -body {
+    set result {}
+    lappend result [testdstring gresult staticlarge]
+    testdstring append x 1
+    lappend result [testdstring get]
+} -cleanup {
+    testdstring free
+} -result {{} {first0 first1 first2 first3 first4 first5 first6 first7 first8 first9
+second0 second1 second2 second3 second4 second5 second6 second7 second8 second9
+third0 third1 third2 third3 third4 third5 third6 third7 third8 third9
+fourth0 fourth1 fourth2 fourth3 fourth4 fourth5 fourth6 fourth7 fourth8 fourth9
+fifth0 fifth1 fifth2 fifth3 fifth4 fifth5 fifth6 fifth7 fifth8 fifth9
+sixth0 sixth1 sixth2 sixth3 sixth4 sixth5 sixth6 sixth7 sixth8 sixth9
+seventh0 seventh1 seventh2 seventh3 seventh4 seventh5 seventh6 seventh7 seventh8 seventh9
+x}}
+test dstring-6.4 {Tcl_DStringGetResult} -constraints testdstring -body {
+    set result {}
+    lappend result [testdstring gresult free]
+    testdstring append y 1
+    lappend result [testdstring get]
+} -cleanup {
+    testdstring free
+} -result {{} {This is a malloc-ed stringy}}
+test dstring-6.5 {Tcl_DStringGetResult} -constraints testdstring -body {
+    set result {}
+    lappend result [testdstring gresult special]
+    testdstring append z 1
+    lappend result [testdstring get]
+} -cleanup {
+    testdstring free
+} -result {{} {This is a specially-allocated stringz}}
+
+# cleanup
+if {[testConstraint testdstring]} {
+    testdstring free
+}
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# fill-column: 78
+# End:
diff --git a/tests/encoding.test b/tests/encoding.test
new file mode 100644
index 0000000..0374e2d
--- /dev/null
+++ b/tests/encoding.test
@@ -0,0 +1,610 @@
+# This file contains a collection of tests for tclEncoding.c
+# Sourcing this file into Tcl runs the tests and generates output for errors.
+# No output means no errors were found.
+#
+# Copyright (c) 1997 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution of
+# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+package require tcltest 2
+
+namespace eval ::tcl::test::encoding {
+    variable x
+
+namespace import -force ::tcltest::*
+
+catch {
+    ::tcltest::loadTestedCommands
+    package require -exact Tcltest [info patchlevel]
+}
+
+proc toutf {args} {
+    variable x
+    lappend x "toutf $args"
+}
+proc fromutf {args} {
+    variable x
+    lappend x "fromutf $args"
+}
+
+proc runtests {} {
+    variable x
+
+# Some tests require the testencoding command
+testConstraint testencoding [llength [info commands testencoding]]
+testConstraint exec [llength [info commands exec]]
+testConstraint testgetdefenc [llength [info commands testgetdefenc]]
+
+# TclInitEncodingSubsystem is tested by the rest of this file
+# TclFinalizeEncodingSubsystem is not currently tested
+
+test encoding-1.1 {Tcl_GetEncoding: system encoding} -setup {
+    set old [encoding system]
+} -constraints {testencoding} -body {
+    testencoding create foo [namespace origin toutf] [namespace origin fromutf]
+    encoding system foo
+    set x {}
+    encoding convertto abcd
+    return $x
+} -cleanup {
+    encoding system $old
+    testencoding delete foo
+} -result {{fromutf }}
+test encoding-1.2 {Tcl_GetEncoding: existing encoding} {testencoding} {
+    testencoding create foo [namespace origin toutf] [namespace origin fromutf]
+    set x {}
+    encoding convertto foo abcd
+    testencoding delete foo
+    return $x
+} {{fromutf }}
+test encoding-1.3 {Tcl_GetEncoding: load encoding} {
+    list [encoding convertto jis0208 \u4e4e] \
+	[encoding convertfrom jis0208 8C]
+} "8C \u4e4e"
+
+test encoding-2.1 {Tcl_FreeEncoding: refcount == 0} {
+    encoding convertto jis0208 \u4e4e
+} {8C}
+test encoding-2.2 {Tcl_FreeEncoding: refcount != 0} -setup {
+    set system [encoding system]
+    set path [encoding dirs]
+} -constraints {testencoding} -body {
+    encoding system shiftjis		;# incr ref count
+    encoding dirs [list [pwd]]
+    set x [encoding convertto shiftjis \u4e4e]	;# old one found   
+    encoding system identity
+    llength shiftjis		;# Shimmer away any cache of Tcl_Encoding
+    lappend x [catch {encoding convertto shiftjis \u4e4e} msg] $msg
+} -cleanup {
+    encoding system identity
+    encoding dirs $path
+    encoding system $system
+} -result "\u008c\u00c1 1 {unknown encoding \"shiftjis\"}"
+
+test encoding-3.1 {Tcl_GetEncodingName, NULL} -setup {
+    set old [encoding system]
+} -body {
+    encoding system shiftjis
+    encoding system
+} -cleanup {
+    encoding system $old
+} -result {shiftjis}
+test encoding-3.2 {Tcl_GetEncodingName, non-null} -setup {
+    set old [fconfigure stdout -encoding]
+} -body {
+    fconfigure stdout -encoding jis0208
+    fconfigure stdout -encoding
+} -cleanup {
+    fconfigure stdout -encoding $old
+} -result {jis0208}
+
+test encoding-4.1 {Tcl_GetEncodingNames} -constraints {testencoding} -setup {
+    cd [makeDirectory tmp]
+    makeDirectory [file join tmp encoding]
+    set path [encoding dirs]
+    encoding dirs {}
+    catch {unset encodings}
+    catch {unset x}
+} -body {
+    foreach encoding [encoding names] {
+	set encodings($encoding) 1
+    }
+    makeFile {} [file join tmp encoding junk.enc]
+    makeFile {} [file join tmp encoding junk2.enc]
+    encoding dirs [list [file join [pwd] encoding]]
+    foreach encoding [encoding names] {
+	if {![info exists encodings($encoding)]} {
+	    lappend x $encoding
+	}
+    }
+    lsort $x
+} -cleanup {
+    encoding dirs $path
+    cd [workingDirectory]
+    removeFile [file join tmp encoding junk2.enc]
+    removeFile [file join tmp encoding junk.enc]
+    removeDirectory [file join tmp encoding]
+    removeDirectory tmp
+} -result {junk junk2}
+
+test encoding-5.1 {Tcl_SetSystemEncoding} -setup {
+    set old [encoding system]
+} -body {
+    encoding system jis0208
+    encoding convertto \u4e4e
+} -cleanup {
+    encoding system identity
+    encoding system $old
+} -result {8C}
+test encoding-5.2 {Tcl_SetSystemEncoding: test ref count} {
+    set old [encoding system]
+    encoding system $old
+    string compare $old [encoding system]
+} {0}
+
+test encoding-6.1 {Tcl_CreateEncoding: new} {testencoding} {
+    testencoding create foo [namespace code {toutf 1}] \
+	[namespace code {fromutf 2}]
+    set x {}
+    encoding convertfrom foo abcd
+    encoding convertto foo abcd
+    testencoding delete foo
+    return $x
+} {{toutf 1} {fromutf 2}}
+test encoding-6.2 {Tcl_CreateEncoding: replace encoding} {testencoding} {
+    testencoding create foo [namespace code {toutf a}] \
+	[namespace code {fromutf b}]
+    set x {}
+    encoding convertfrom foo abcd
+    encoding convertto foo abcd
+    testencoding delete foo
+    return $x
+} {{toutf a} {fromutf b}}
+
+test encoding-7.1 {Tcl_ExternalToUtfDString: small buffer} {
+    encoding convertfrom jis0208 8c8c8c8c
+} "\u543e\u543e\u543e\u543e"
+test encoding-7.2 {Tcl_UtfToExternalDString: big buffer} {
+    set a 8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C8C
+    append a $a
+    append a $a
+    append a $a
+    append a $a
+    set x [encoding convertfrom jis0208 $a]
+    list [string length $x] [string index $x 0]
+} "512 \u4e4e"
+
+test encoding-8.1 {Tcl_ExternalToUtf} {
+    set f [open [file join [temporaryDirectory] dummy] w]
+    fconfigure $f -translation binary -encoding iso8859-1
+    puts -nonewline $f "ab\x8c\xc1g"
+    close $f
+    set f [open [file join [temporaryDirectory] dummy] r]
+    fconfigure $f -translation binary -encoding shiftjis    
+    set x [read $f]
+    close $f
+    file delete [file join [temporaryDirectory] dummy]
+    return $x
+} "ab\u4e4eg"
+
+test encoding-9.1 {Tcl_UtfToExternalDString: small buffer} {
+    encoding convertto jis0208 "\u543e\u543e\u543e\u543e"
+} {8c8c8c8c}
+test encoding-9.2 {Tcl_UtfToExternalDString: big buffer} {
+    set a \u4e4e\u4e4e\u4e4e\u4e4e\u4e4e\u4e4e\u4e4e\u4e4e
+    append a $a
+    append a $a
+    append a $a
+    append a $a
+    append a $a
+    append a $a
+    set x [encoding convertto jis0208 $a]
+    list [string length $x] [string range $x 0 1]
+} "1024 8C"
+
+test encoding-10.1 {Tcl_UtfToExternal} {
+    set f [open [file join [temporaryDirectory] dummy] w]
+    fconfigure $f -translation binary -encoding shiftjis
+    puts -nonewline $f "ab\u4e4eg"
+    close $f
+    set f [open [file join [temporaryDirectory] dummy] r]
+    fconfigure $f -translation binary -encoding iso8859-1
+    set x [read $f]
+    close $f
+    file delete [file join [temporaryDirectory] dummy]
+    return $x
+} "ab\x8c\xc1g"
+
+proc viewable {str} {
+    set res ""
+    foreach c [split $str {}] {
+	if {[string is print $c] && [string is ascii $c]} {
+	    append res $c
+	} else {
+	    append res "\\u[format %4.4x [scan $c %c]]"
+	}
+    }
+    return "$str ($res)"
+}
+
+test encoding-11.1 {LoadEncodingFile: unknown encoding} {testencoding} {
+    set system [encoding system]
+    set path [encoding dirs]
+    encoding system iso8859-1
+    encoding dirs {}
+    llength jis0208	;# Shimmer any cached Tcl_Encoding in shared literal
+    set x [list [catch {encoding convertto jis0208 \u4e4e} msg] $msg]
+    encoding dirs $path
+    encoding system $system
+    lappend x [encoding convertto jis0208 \u4e4e]
+} {1 {unknown encoding "jis0208"} 8C}
+test encoding-11.2 {LoadEncodingFile: single-byte} {
+    encoding convertfrom jis0201 \xa1
+} "\uff61"
+test encoding-11.3 {LoadEncodingFile: double-byte} {
+    encoding convertfrom jis0208 8C
+} "\u4e4e"
+test encoding-11.4 {LoadEncodingFile: multi-byte} {
+    encoding convertfrom shiftjis \x8c\xc1
+} "\u4e4e"
+test encoding-11.5 {LoadEncodingFile: escape file} {
+    viewable [encoding convertto iso2022 \u4e4e]
+} [viewable "\x1b\$B8C\x1b(B"]
+test encoding-11.5.1 {LoadEncodingFile: escape file} {
+    viewable [encoding convertto iso2022-jp \u4e4e]
+} [viewable "\x1b\$B8C\x1b(B"]
+test encoding-11.6 {LoadEncodingFile: invalid file} -constraints {testencoding} -setup {
+    set system [encoding system]
+    set path [encoding dirs]
+    encoding system identity
+} -body {
+    cd [temporaryDirectory]
+    encoding dirs [file join tmp encoding]
+    makeDirectory tmp
+    makeDirectory [file join tmp encoding]
+    set f [open [file join tmp encoding splat.enc] w]
+    fconfigure $f -translation binary 
+    puts $f "abcdefghijklmnop"
+    close $f
+    encoding convertto splat \u4e4e
+} -returnCodes error -cleanup {
+    file delete [file join [temporaryDirectory] tmp encoding splat.enc]
+    removeDirectory [file join tmp encoding]
+    removeDirectory tmp
+    cd [workingDirectory]
+    encoding dirs $path
+    encoding system $system
+} -result {invalid encoding file "splat"}
+
+# OpenEncodingFile is fully tested by the rest of the tests in this file.
+
+test encoding-12.1 {LoadTableEncoding: normal encoding} {
+    set x [encoding convertto iso8859-3 \u120]
+    append x [encoding convertto iso8859-3 \ud5]
+    append x [encoding convertfrom iso8859-3 \xd5]
+} "\xd5?\u120"
+test encoding-12.2 {LoadTableEncoding: single-byte encoding} {
+    set x [encoding convertto iso8859-3 ab\u0120g] 
+    append x [encoding convertfrom iso8859-3 ab\xd5g]
+} "ab\xd5gab\u120g"
+test encoding-12.3 {LoadTableEncoding: multi-byte encoding} {
+    set x [encoding convertto shiftjis ab\u4e4eg] 
+    append x [encoding convertfrom shiftjis ab\x8c\xc1g]
+} "ab\x8c\xc1gab\u4e4eg"
+test encoding-12.4 {LoadTableEncoding: double-byte encoding} {
+    set x [encoding convertto jis0208 \u4e4e\u3b1]
+    append x [encoding convertfrom jis0208 8C&A]
+} "8C&A\u4e4e\u3b1"
+test encoding-12.5 {LoadTableEncoding: symbol encoding} {
+    set x [encoding convertto symbol \u3b3]
+    append x [encoding convertto symbol \u67]
+    append x [encoding convertfrom symbol \x67]
+} "\x67\x67\u3b3"
+
+test encoding-13.1 {LoadEscapeTable} {
+    viewable [set x [encoding convertto iso2022 ab\u4e4e\u68d9g]]
+} [viewable "ab\x1b\$B8C\x1b\$\(DD%\x1b(Bg"]
+
+test encoding-14.1 {BinaryProc} {
+    encoding convertto identity \x12\x34\x56\xff\x69
+} "\x12\x34\x56\xc3\xbf\x69"
+
+test encoding-15.1 {UtfToUtfProc} {
+    encoding convertto utf-8 \xa3
+} "\xc2\xa3"
+test encoding-15.2 {UtfToUtfProc null character output} {
+    set x \u0000
+    set y [encoding convertto utf-8 \u0000]
+    set y [encoding convertfrom identity $y]
+    binary scan $y H* z
+    list [string bytelength $x] [string bytelength $y] $z
+} {2 1 00}
+test encoding-15.3 {UtfToUtfProc null character input} {
+    set x [encoding convertfrom identity \x00]
+    set y [encoding convertfrom utf-8 $x]
+    binary scan [encoding convertto identity $y] H* z
+    list [string bytelength $x] [string bytelength $y] $z
+} {1 2 c080}
+
+test encoding-16.1 {UnicodeToUtfProc} {
+    set val [encoding convertfrom unicode NN]
+    list $val [format %x [scan $val %c]]
+} "\u4e4e 4e4e"
+
+test encoding-17.1 {UtfToUnicodeProc} {
+} {}
+
+test encoding-18.1 {TableToUtfProc} {
+} {}
+
+test encoding-19.1 {TableFromUtfProc} {
+} {}
+
+test encoding-20.1 {TableFreefProc} {
+} {}
+
+test encoding-21.1 {EscapeToUtfProc} {
+} {}
+
+test encoding-22.1 {EscapeFromUtfProc} {
+} {}
+
+set iso2022encData "\u001b\$B;d\$I\$b\$G\$O!\"%A%C%W\$49XF~;~\$K\$4EPO?\$\$\$?\$@\$\$\$?\$4=;=j\$r%-%c%C%7%e%\"%&%H\$N:]\$N\u001b(B
+\u001b\$B>.@Z<jAwIU@h\$H\$7\$F;HMQ\$7\$F\$*\$j\$^\$9!#62\$lF~\$j\$^\$9\$,!\"@5\$7\$\$=;=j\$r\$4EPO?\$7\$J\$*\u001b(B
+\u001b\$B\$*4j\$\$\$\$\$?\$7\$^\$9!#\$^\$?!\"BgJQ62=L\$G\$9\$,!\"=;=jJQ99\$N\$\"\$H!\"F|K\\8l%5!<%S%9It!J\u001b(B
+casino_japanese@___.com \u001b\$B!K\$^\$G\$4=;=jJQ99:Q\$NO\"Mm\$r\$\$\$?\$@\$1\$J\$\$\$G\u001b(B
+\u001b\$B\$7\$g\$&\$+!)\u001b(B"
+
+set iso2022uniData [encoding convertfrom iso2022-jp $iso2022encData]
+set iso2022uniData2 "\u79c1\u3069\u3082\u3067\u306f\u3001\u30c1\u30c3\u30d7\u3054\u8cfc\u5165\u6642\u306b\u3054\u767b\u9332\u3044\u305f\u3060\u3044\u305f\u3054\u4f4f\u6240\u3092\u30ad\u30e3\u30c3\u30b7\u30e5\u30a2\u30a6\u30c8\u306e\u969b\u306e
+\u5c0f\u5207\u624b\u9001\u4ed8\u5148\u3068\u3057\u3066\u4f7f\u7528\u3057\u3066\u304a\u308a\u307e\u3059\u3002\u6050\u308c\u5165\u308a\u307e\u3059\u304c\u3001\u6b63\u3057\u3044\u4f4f\u6240\u3092\u3054\u767b\u9332\u3057\u306a\u304a
+\u304a\u9858\u3044\u3044\u305f\u3057\u307e\u3059\u3002\u307e\u305f\u3001\u5927\u5909\u6050\u7e2e\u3067\u3059\u304c\u3001\u4f4f\u6240\u5909\u66f4\u306e\u3042\u3068\u3001\u65e5\u672c\u8a9e\u30b5\u30fc\u30d3\u30b9\u90e8\uff08
+\u0063\u0061\u0073\u0069\u006e\u006f\u005f\u006a\u0061\u0070\u0061\u006e\u0065\u0073\u0065\u0040\u005f\u005f\u005f\u002e\u0063\u006f\u006d\u0020\uff09\u307e\u3067\u3054\u4f4f\u6240\u5909\u66f4\u6e08\u306e\u9023\u7d61\u3092\u3044\u305f\u3060\u3051\u306a\u3044\u3067
+\u3057\u3087\u3046\u304b\uff1f"
+
+cd [temporaryDirectory]
+set fid [open iso2022.txt w]
+fconfigure $fid -encoding binary
+puts -nonewline $fid $iso2022encData
+close $fid
+
+test encoding-23.1 {iso2022-jp escape encoding test} {
+    string equal $iso2022uniData $iso2022uniData2
+} 1
+test encoding-23.2 {iso2022-jp escape encoding test} {
+    # This checks that 'gets' isn't resetting the encoding inappropriately.
+    # [Bug #523988]
+    set fid [open iso2022.txt r]
+    fconfigure $fid -encoding iso2022-jp
+    set out ""
+    set count 0
+    while {[set num [gets $fid line]] >= 0} {
+	if {$count} {
+	    incr count 1 ; # account for newline
+	    append out \n
+	}
+	append out $line
+	incr count $num
+    }
+    close $fid
+    if {[string compare $iso2022uniData $out]} {
+	return -code error "iso2022-jp read in doesn't match original"
+    }
+    list $count $out
+} [list [string length $iso2022uniData] $iso2022uniData]
+test encoding-23.3 {iso2022-jp escape encoding test} {
+    # read $fis <size> reads size in chars, not raw bytes.
+    set fid [open iso2022.txt r]
+    fconfigure $fid -encoding iso2022-jp
+    set data [read $fid 50]
+    close $fid
+    return $data
+} [string range $iso2022uniData 0 49] ; # 0 .. 49 inclusive == 50
+cd [workingDirectory]
+
+# Code to make the next few tests more intelligible; the code being tested
+# should be in the body of the test!
+proc runInSubprocess {contents {filename iso2022.tcl}} {
+    set theFile [makeFile $contents $filename]
+    try {
+	exec [interpreter] $theFile
+    } finally {
+	removeFile $theFile
+    }
+}
+
+test encoding-24.1 {EscapeFreeProc on open channels} exec {
+    runInSubprocess {
+	set f [open [file join [file dirname [info script]] iso2022.txt]]
+	fconfigure $f -encoding iso2022-jp
+	gets $f
+    }
+} {}
+test encoding-24.2 {EscapeFreeProc on open channels} {exec} {
+    # Bug #524674 output
+    viewable [runInSubprocess {
+	encoding system cp1252;	# Bug #2891556 crash revelator
+	fconfigure stdout -encoding iso2022-jp
+	puts ab\u4e4e\u68d9g
+	set env(TCL_FINALIZE_ON_EXIT) 1
+	exit
+    }]
+} "ab\x1b\$B8C\x1b\$(DD%\x1b(Bg (ab\\u001b\$B8C\\u001b\$(DD%\\u001b(Bg)"
+test encoding-24.3 {EscapeFreeProc on open channels} {stdio} {
+    # Bug #219314 - if we don't free escape encodings correctly on channel
+    # closure, we go boom
+    set file [makeFile {
+	encoding system iso2022-jp
+	set a "\u4e4e\u4e5e\u4e5f"; # 3 Japanese Kanji letters
+	puts $a
+    } iso2022.tcl]
+    set f [open "|[list [interpreter] $file]"]
+    fconfigure $f -encoding iso2022-jp
+    set count [gets $f line]
+    close $f
+    removeFile iso2022.tcl
+    list $count [viewable $line]
+} [list 3 "\u4e4e\u4e5e\u4e5f (\\u4e4e\\u4e5e\\u4e5f)"]
+
+file delete [file join [temporaryDirectory] iso2022.txt]
+
+#
+# Begin jajp encoding round-trip conformity tests
+#
+proc foreach-jisx0208 {varName command} {
+    upvar 1 $varName code
+    foreach range {
+	{2121 217E}
+	{2221 222E}
+	{223A 2241}
+	{224A 2250}
+	{225C 226A}
+	{2272 2279}
+	{227E 227E}
+	{2330 2339}
+	{2421 2473}
+	{2521 2576}
+	{2821 2821}
+	{282C 282C}
+	{2837 2837}
+
+	{30 21 4E 7E}
+	{4F21 4F53}
+
+	{50 21 73 7E}
+	{7421 7426}
+    } {
+	if {[llength $range] == 2} {
+	    # for adhoc range. simple {first last}. inclusive.
+	    scan $range %x%x first last
+	    for {set i $first} {$i <= $last} {incr i} {
+		set code $i
+		uplevel 1 $command
+	    }
+	} elseif {[llength $range] == 4} {
+	    # for uniform range.
+	    scan $range %x%x%x%x h0 l0 hend lend
+	    for {set hi $h0} {$hi <= $hend} {incr hi} {
+		for {set lo $l0} {$lo <= $lend} {incr lo} {
+		    set code [expr {$hi << 8 | ($lo & 0xff)}]
+		    uplevel 1 $command
+		}
+	    }
+	} else {
+	    error "really?"
+	}
+    }
+}
+proc gen-jisx0208-euc-jp {code} {
+    binary format cc \
+	[expr {($code >> 8) | 0x80}] [expr {($code & 0xff) | 0x80}]
+}
+proc gen-jisx0208-iso2022-jp {code} {
+    binary format a3cca3 \
+	"\x1b\$B" [expr {$code >> 8}] [expr {$code & 0xff}] "\x1b(B"
+}
+proc gen-jisx0208-cp932 {code} {
+    set c1 [expr {($code >> 8) | 0x80}]
+    set c2 [expr {($code & 0xff)| 0x80}]
+    if {$c1 % 2} {
+	set c1 [expr {($c1 >> 1) + ($c1 < 0xdf ? 0x31 : 0x71)}]
+	incr c2 [expr {- (0x60 + ($c2 < 0xe0))}]
+    } else {
+	set c1 [expr {($c1 >> 1) + ($c1 < 0xdf ? 0x30 : 0x70)}]
+	incr c2 -2
+    }
+    binary format cc $c1 $c2
+}
+proc channel-diff {fa fb} {
+    set diff {}
+    while {[gets $fa la] >= 0 && [gets $fb lb] >= 0} {
+	if {[string compare $la $lb] == 0} continue
+	# lappend diff $la $lb
+
+	# For more readable (easy to analyze) output.
+	set code [lindex $la 0]
+	binary scan [lindex $la 1] H* expected
+	binary scan [lindex $lb 1] H* got
+	lappend diff [list $code $expected $got]
+    }
+    return $diff
+}
+
+# Create char tables.
+cd [temporaryDirectory]
+foreach enc {cp932 euc-jp iso2022-jp} {
+    set f [open $enc.chars w]
+    fconfigure $f -encoding binary
+    foreach-jisx0208 code {
+	puts $f [format "%04X %s" $code [gen-jisx0208-$enc $code]]
+    }
+    close $f
+}
+# shiftjis == cp932 for jisx0208.
+file copy -force cp932.chars shiftjis.chars
+
+set NUM 0
+foreach from {cp932 shiftjis euc-jp iso2022-jp} {
+    foreach to {cp932 shiftjis euc-jp iso2022-jp} {
+	test encoding-25.[incr NUM] "jisx0208 $from => $to" -setup {
+	    cd [temporaryDirectory]
+	} -body {
+	    set f [open $from.chars]
+	    fconfigure $f -encoding $from
+	    set out [open $from.$to.tcltestout w]
+	    fconfigure $out -encoding $to
+	    puts -nonewline $out [read $f]
+	    close $out
+	    close $f
+	    # then compare $to.chars <=> $from.to.tcltestout as binary.
+	    set fa [open $to.chars rb]
+	    set fb [open $from.$to.tcltestout rb]
+	    channel-diff $fa $fb
+	    # Difference should be empty.
+	} -cleanup {
+	    close $fa
+	    close $fb
+	} -result {}
+    }
+}
+
+test encoding-26.0 {Tcl_GetDefaultEncodingDir} -constraints {
+    testgetdefenc
+} -setup {
+    set origDir [testgetdefenc]
+    testsetdefenc slappy
+} -body {
+    testgetdefenc
+} -cleanup {
+    testsetdefenc $origDir
+} -result slappy
+
+file delete {*}[glob -directory [temporaryDirectory] *.chars *.tcltestout]
+# ===> Cut here <===
+
+# EscapeFreeProc, GetTableEncoding, unilen are fully tested by the rest of
+# this file.
+
+
+test encoding-27.1 {encoding dirs basic behavior} -returnCodes error -body {
+    encoding dirs ? ?
+} -result {wrong # args: should be "encoding dirs ?dirList?"}
+test encoding-27.2 {encoding dirs basic behavior} -returnCodes error -body {
+    encoding dirs "\{not a list"
+} -result "expected directory list but got \"\{not a list\""
+
+}
+runtests
+
+}
+
+# cleanup
+namespace delete ::tcl::test::encoding
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/tests/env.test b/tests/env.test
new file mode 100644
index 0000000..0dd4f98
--- /dev/null
+++ b/tests/env.test
@@ -0,0 +1,349 @@
+# Commands covered:  none (tests environment variable implementation)
+#
+# This file contains a collection of tests for one or more of the Tcl built-in
+# commands. Sourcing this file into Tcl runs the tests and generates output
+# for errors. No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution of
+# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+    package require tcltest 2
+    namespace import -force ::tcltest::*
+}
+
+# Some tests require the "exec" command.
+# Skip them if exec is not defined.
+testConstraint exec [llength [info commands exec]]
+
+#
+# These tests will run on any platform (and indeed crashed on the Mac). So put
+# them before you test for the existance of exec.
+#
+test env-1.1 {propagation of env values to child interpreters} -setup {
+    catch {interp delete child}
+    catch {unset env(test)}
+} -body {
+    interp create child
+    set env(test) garbage
+    child eval {set env(test)}
+} -cleanup {
+    interp delete child
+    unset env(test)
+} -result {garbage}
+#
+# This one crashed on Solaris under Tcl8.0, so we only want to make sure it
+# runs.
+#
+test env-1.2 {lappend to env value} -setup {
+    catch {unset env(test)}
+} -body {
+    set env(test) aaaaaaaaaaaaaaaa
+    append env(test) bbbbbbbbbbbbbb
+    unset env(test)
+}
+test env-1.3 {reflection of env by "array names"} -setup {
+    catch {interp delete child}
+    catch {unset env(test)}
+} -body {
+    interp create child
+    child eval {set env(test) garbage}
+    expr {"test" in [array names env]}
+} -cleanup {
+    interp delete child
+    catch {unset env(test)}
+} -result {1}
+
+set printenvScript [makeFile {
+    encoding system iso8859-1
+    proc lrem {listname name} {
+	upvar $listname list
+	set i [lsearch -nocase $list $name]
+	if {$i >= 0} {
+	    set list [lreplace $list $i $i]
+	}
+	return $list
+    }
+    proc mangle s {
+	regsub -all {\[|\\|\]} $s {\\&} s
+	regsub -all "\[\u0000-\u001f\u007f-\uffff\]" $s {[manglechar &]} s
+	return [subst -novariables $s]
+    }
+    proc manglechar c {
+	return [format {\u%04x} [scan $c %c]]
+    }
+
+    set names [lsort [array names env]]
+    if {$tcl_platform(platform) eq "windows"} {
+	lrem names HOME
+        lrem names COMSPEC
+	lrem names ComSpec
+	lrem names ""
+    }
+    foreach name {
+	TCL_LIBRARY PATH LD_LIBRARY_PATH LIBPATH PURE_PROG_NAME DISPLAY
+	SHLIB_PATH SYSTEMDRIVE SYSTEMROOT DYLD_LIBRARY_PATH DYLD_FRAMEWORK_PATH
+	DYLD_NEW_LOCAL_SHARED_REGIONS DYLD_NO_FIX_PREBINDING
+	__CF_USER_TEXT_ENCODING SECURITYSESSIONID LANG WINDIR TERM
+	CommonProgramFiles ProgramFiles CommonProgramW6432 ProgramW6432
+    } {
+	lrem names $name
+    }
+    foreach p $names {
+	puts "[mangle $p]=[mangle $env($p)]"
+    }
+    exit
+} printenv]
+
+# [exec] is required here to see the actual environment received by child
+# processes.
+proc getenv {} {
+    global printenvScript tcltest
+    catch {exec [interpreter] $printenvScript} out
+    if {$out eq "child process exited abnormally"} {
+	set out {}
+    }
+    return $out
+}
+
+# Save the current environment variables at the start of the test.
+
+set env2 [array get env]
+foreach name [array names env] {
+    # Keep some environment variables that support operation of the tcltest
+    # package.
+    if {[string toupper $name] ni {
+	TCL_LIBRARY PATH LD_LIBRARY_PATH LIBPATH DISPLAY SHLIB_PATH
+	SYSTEMDRIVE SYSTEMROOT DYLD_LIBRARY_PATH DYLD_FRAMEWORK_PATH
+	DYLD_NEW_LOCAL_SHARED_REGIONS DYLD_NO_FIX_PREBINDING
+	SECURITYSESSIONID LANG WINDIR TERM
+	CONNOMPROGRAMFILES PROGRAMFILES COMMONPROGRAMW6432 PROGRAMW6432
+    }} {
+	unset env($name)
+    }
+}
+
+# Need to run 'getenv' in known encoding, so save the current one here...
+set sysenc [encoding system]
+
+test env-2.1 {adding environment variables} -setup {
+    encoding system iso8859-1
+} -constraints {exec} -body {
+    getenv
+} -cleanup {
+    encoding system $sysenc
+} -result {}
+test env-2.2 {adding environment variables} -setup {
+    encoding system iso8859-1
+} -constraints {exec} -body {
+    set env(NAME1) "test string"
+    getenv
+} -cleanup {
+    encoding system $sysenc
+} -result {NAME1=test string}
+test env-2.3 {adding environment variables} -setup {
+    encoding system iso8859-1
+    set env(NAME1) "test string"
+} -constraints {exec} -body {
+    set env(NAME2) "more"
+    getenv
+} -cleanup {
+    encoding system $sysenc
+} -result {NAME1=test string
+NAME2=more}
+test env-2.4 {adding environment variables} -setup {
+    encoding system iso8859-1
+    set env(NAME1) "test string"
+    set env(NAME2) "more"
+} -constraints {exec} -body {
+    set env(XYZZY) "garbage"
+    getenv
+} -cleanup {
+    encoding system $sysenc
+} -result {NAME1=test string
+NAME2=more
+XYZZY=garbage}
+
+set env(NAME1) "test string"
+set env(NAME2) "new value"
+set env(XYZZY) "garbage"
+test env-3.1 {changing environment variables} -setup {
+    encoding system iso8859-1
+} -constraints {exec} -body {
+    set result [getenv]
+    unset env(NAME2)
+    set result
+} -cleanup {
+    encoding system $sysenc
+} -result {NAME1=test string
+NAME2=new value
+XYZZY=garbage}
+unset -nocomplain env(NAME2)
+
+test env-4.1 {unsetting environment variables: default} -setup {
+    encoding system iso8859-1
+} -constraints {exec} -body {
+    getenv
+} -cleanup {
+    encoding system $sysenc
+} -result {NAME1=test string
+XYZZY=garbage}
+test env-4.2 {unsetting environment variables} -setup {
+    encoding system iso8859-1
+} -constraints {exec} -body {
+    unset env(NAME1)
+    getenv
+} -cleanup {
+    unset env(XYZZY)
+    encoding system $sysenc
+} -result {XYZZY=garbage}
+unset -nocomplain env(NAME1) env(XYZZY)
+test env-4.3 {setting international environment variables} -setup {
+    encoding system iso8859-1
+} -constraints {exec} -body {
+    set env(\ua7) \ub6
+    getenv
+} -cleanup {
+    encoding system $sysenc
+} -result {\u00a7=\u00b6}
+test env-4.4 {changing international environment variables} -setup {
+    encoding system iso8859-1
+} -constraints {exec} -body {
+    set env(\ua7) \ua7
+    getenv
+} -cleanup {
+    encoding system $sysenc
+} -result {\u00a7=\u00a7}
+test env-4.5 {unsetting international environment variables} -setup {
+    encoding system iso8859-1
+    set env(\ua7) \ua7
+} -body {
+    set env(\ub6) \ua7
+    unset env(\ua7)
+    getenv
+} -constraints {exec} -cleanup {
+    unset env(\ub6)
+    encoding system $sysenc
+} -result {\u00b6=\u00a7}
+
+test env-5.0 {corner cases - set a value, it should exist} -body {
+    set env(temp) a
+    set env(temp)
+} -cleanup {
+    unset env(temp)
+} -result {a}
+test env-5.1 {corner cases - remove one elem at a time} -setup {
+    set x [array get env]
+} -body {
+    # When no environment variables exist, the env var will contain no
+    # entries. The "array names" call synchs up the C-level environ array with
+    # the Tcl level env array. Make sure an empty Tcl array is created.
+    foreach e [array names env] {
+	unset env($e)
+    }
+    array size env
+} -cleanup {
+    array set env $x
+} -result {0}
+test env-5.2 {corner cases - unset the env array} -setup {
+    interp create i
+} -body {
+    # Unsetting a variable in an interp detaches the C-level traces from the
+    # Tcl "env" variable.
+    i eval {
+	unset env
+	set env(THIS_SHOULDNT_EXIST) a
+    }
+    info exists env(THIS_SHOULDNT_EXIST)
+} -cleanup {
+    interp delete i
+} -result {0}
+test env-5.3 {corner cases: unset the env in master should unset child} -setup {
+    interp create i
+} -body {
+    # Variables deleted in a master interp should be deleted in child interp
+    # too.
+    i eval { set env(THIS_SHOULD_EXIST) a}
+    set result [set env(THIS_SHOULD_EXIST)]
+    unset env(THIS_SHOULD_EXIST)
+    lappend result [i eval {catch {set env(THIS_SHOULD_EXIST)}}]
+} -cleanup {
+    interp delete i
+} -result {a 1}
+test env-5.4 {corner cases - unset the env array} -setup {
+    interp create i
+} -body {
+    # The info exists command should be in synch with the env array.
+    # Know Bug: 1737
+    i eval { set env(THIS_SHOULD_EXIST) a}
+    set     result [info exists env(THIS_SHOULD_EXIST)]
+    lappend result [set env(THIS_SHOULD_EXIST)]
+    lappend result [info exists env(THIS_SHOULD_EXIST)]
+} -cleanup {
+    interp delete i
+} -result {1 a 1}
+test env-5.5 {corner cases - cannot have null entries on Windows} -constraints win -body {
+    set env() a
+    catch {set env()}
+} -result 1
+
+test env-6.1 {corner cases - add lots of env variables} -body {
+    set size [array size env]
+    for {set i 0} {$i < 100} {incr i} {
+	set env(BOGUS$i) $i
+    }
+    expr {[array size env] - $size}
+} -result 100
+
+test env-7.1 {[219226]: whole env array should not be unset by read} -body {
+    set n [array size env]
+    set s [array startsearch env]
+    while {[array anymore env $s]} {
+	array nextelement env $s
+	incr n -1
+    }
+    array donesearch env $s
+    return $n
+} -result 0
+
+test env-7.2 {[219226]: links to env elements should not be removed by read} -body {
+    apply {{} {
+	set ::env(test7_2) ok
+	upvar env(test7_2) elem
+	set ::env(PATH)
+	return $elem
+    }}
+} -result ok
+
+test env-7.3 {[9b4702]: testing existence of env(some_thing) should not destroy trace} -body {
+    apply {{} {
+      catch {unset ::env(test7_3)}
+      proc foo args {
+        set ::env(test7_3) ok
+      }
+      trace add variable ::env(not_yet_existent) write foo
+      info exists ::env(not_yet_existent)
+      set ::env(not_yet_existent) "Now I'm here";
+      return [info exists ::env(test7_3)]
+    }}
+} -result 1
+
+# Restore the environment variables at the end of the test.
+
+foreach name [array names env] {
+    unset env($name)
+}
+array set env $env2
+
+# cleanup
+removeFile $printenvScript
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/tests/error.test b/tests/error.test
new file mode 100644
index 0000000..af07ed7
--- /dev/null
+++ b/tests/error.test
@@ -0,0 +1,1211 @@
+# Commands covered:  error, catch, throw, try
+#
+# This file contains a collection of tests for one or more of the Tcl built-in
+# commands. Sourcing this file into Tcl runs the tests and generates output
+# for errors. No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994-1996 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution of
+# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+    package require tcltest 2
+    namespace import -force ::tcltest::*
+}
+
+testConstraint memory [llength [info commands memory]]
+customMatch pairwise {apply {{a b} {
+    string equal [lindex $b 0] [lindex $b 1]
+}}}
+namespace eval ::tcl::test::error {
+if {[testConstraint memory]} {
+    proc getbytes {} {
+	set lines [split [memory info] \n]
+	return [lindex $lines 3 3]
+    }
+    proc leaktest {script {iterations 3}} {
+	set end [getbytes]
+	for {set i 0} {$i < $iterations} {incr i} {
+	    uplevel 1 $script
+	    set tmp $end
+	    set end [getbytes]
+	}
+	return [expr {$end - $tmp}]
+    }
+}
+
+proc foo {} {
+    global errorInfo
+    set a [catch {format [error glorp2]} b]
+    error {Human-generated}
+}
+
+proc foo2 {} {
+    global errorInfo
+    set a [catch {format [error glorp2]} b]
+    error {Human-generated} $errorInfo
+}
+
+# Catch errors occurring in commands and errors from "error" command
+
+test error-1.1 {simple errors from commands} {
+    catch {format [string index]} b
+} 1
+test error-1.2 {simple errors from commands} {
+    catch {format [string index]} b
+    set b
+} {wrong # args: should be "string index string charIndex"}
+test error-1.3 {simple errors from commands} {
+    catch {format [string index]} b
+    set ::errorInfo
+    # This used to return '... while executing ...', but string index is fully
+    # compiled as of 8.4a3
+} {wrong # args: should be "string index string charIndex"
+    while executing
+"string index"}
+test error-1.4 {simple errors from commands} {
+    catch {error glorp} b
+} 1
+test error-1.5 {simple errors from commands} {
+    catch {error glorp} b
+    set b
+} glorp
+test error-1.6 {simple errors from commands} {
+    catch {catch a b c d} b
+} 1
+test error-1.7 {simple errors from commands} {
+    catch {catch a b c d} b
+    set b
+} {wrong # args: should be "catch script ?resultVarName? ?optionVarName?"}
+test error-1.8 {simple errors from commands} {
+    # This test is non-portable: it generates a memory fault on machines like
+    # DEC Alphas (infinite recursion overflows stack?)
+    #
+    # That claims sounds like a bug to be fixed rather than a portability
+    # problem. Anyhow, I believe it's out of date (bug's been fixed) so this
+    # test is re-enabled.
+    proc p {} {
+        uplevel 1 catch p error
+    }
+    p
+} 0
+
+# Check errors nested in procedures. Also check the optional argument to
+# "error" to generate a new error trace.
+
+test error-2.1 {errors in nested procedures} {
+    catch foo b
+} 1
+test error-2.2 {errors in nested procedures} {
+    catch foo b
+    set b
+} {Human-generated}
+test error-2.3 {errors in nested procedures} {
+    catch foo b
+    set ::errorInfo
+} {Human-generated
+    while executing
+"error {Human-generated}"
+    (procedure "foo" line 4)
+    invoked from within
+"foo"}
+test error-2.4 {errors in nested procedures} {
+    catch foo2 b
+} 1
+test error-2.5 {errors in nested procedures} {
+    catch foo2 b
+    set b
+} {Human-generated}
+test error-2.6 {errors in nested procedures} {
+    catch foo2 b
+    set ::errorInfo
+} {glorp2
+    while executing
+"error glorp2"
+    (procedure "foo2" line 3)
+    invoked from within
+"foo2"}
+
+# Error conditions related to "catch".
+
+test error-3.1 {errors in catch command} {
+    list [catch {catch} msg] $msg
+} {1 {wrong # args: should be "catch script ?resultVarName? ?optionVarName?"}}
+test error-3.2 {errors in catch command} {
+    list [catch {catch a b c} msg] $msg
+} {0 1}
+test error-3.3 {errors in catch command} {
+    catch {unset a}
+    set a(0) 22
+    list [catch {catch {format 44} a} msg] $msg
+} {1 {can't set "a": variable is array}}
+catch {unset a}
+
+# More tests related to errorInfo and errorCode
+
+test error-4.1 {errorInfo and errorCode variables} {
+    list [catch {error msg1 msg2 msg3} msg] $msg $::errorInfo $::errorCode
+} {1 msg1 msg2 msg3}
+test error-4.2 {errorInfo and errorCode variables} {
+    list [catch {error msg1 {} msg3} msg] $msg $::errorInfo $::errorCode
+} {1 msg1 {msg1
+    while executing
+"error msg1 {} msg3"} msg3}
+test error-4.3 {errorInfo and errorCode variables} {
+    list [catch {error msg1 {}} msg] $msg $::errorInfo $::errorCode
+} {1 msg1 {msg1
+    while executing
+"error msg1 {}"} NONE}
+test error-4.4 {errorInfo and errorCode variables} {
+    set ::errorCode bogus
+    list [catch {error msg1} msg] $msg $::errorInfo $::errorCode
+} {1 msg1 {msg1
+    while executing
+"error msg1"} NONE}
+test error-4.5 {errorInfo and errorCode variables} {
+    set ::errorCode bogus
+    list [catch {error msg1 msg2 {}} msg] $msg $::errorInfo $::errorCode
+} {1 msg1 msg2 {}}
+
+test error-4.6 {errorstack via info } -body {
+    proc f x {g $x$x}
+    proc g x {error G:$x}
+    catch {f 12}
+    info errorstack
+} -match glob -result {INNER * CALL {g 1212} CALL {f 12} UP 1}
+test error-4.7 {errorstack via options dict } -body {
+    proc f x {g $x$x}
+    proc g x {error G:$x}
+    catch {f 12} m d
+    dict get $d -errorstack
+} -match glob -result {INNER * CALL {g 1212} CALL {f 12} UP 1}
+test error-4.8 {errorstack from exec traces} -body {
+    proc foo args {}
+    proc goo {} foo
+    trace add execution foo enter {error bar;#}
+    catch goo m d
+    dict get $d -errorstack
+} -cleanup {
+    rename goo {}; rename foo {}
+    unset -nocomplain m d
+} -result {INNER {error bar} CALL goo UP 1}
+
+# Errors in error command itself
+
+test error-5.1 {errors in error command} {
+    list [catch {error} msg] $msg
+} {1 {wrong # args: should be "error message ?errorInfo? ?errorCode?"}}
+test error-5.2 {errors in error command} {
+    list [catch {error a b c d} msg] $msg
+} {1 {wrong # args: should be "error message ?errorInfo? ?errorCode?"}}
+
+# Make sure that catch resets error information
+
+test error-6.1 {catch must reset error state} {
+    catch {error outer [catch {error inner inner.errorInfo inner.errorCode}]}
+    list $::errorCode $::errorInfo
+} {NONE 1}
+test error-6.2 {catch must reset error state} {
+    catch {error outer [catch {return -level 0 -code error -errorcode BUG}]}
+    list $::errorCode $::errorInfo
+} {NONE 1}
+test error-6.3 {catch must reset error state} {
+    set ::errorCode BUG
+    catch {error outer [catch set]}
+    list $::errorCode $::errorInfo
+} {NONE 1}
+test error-6.4 {catch must reset error state} {
+    catch {error [catch {error foo bar baz}] 1}
+    list $::errorCode $::errorInfo
+} {NONE 1}
+test error-6.5 {catch must reset error state} {
+    catch {error [catch {return -level 0 -code error -errorcode BUG}] 1}
+    list $::errorCode $::errorInfo
+} {NONE 1}
+test error-6.6 {catch must reset error state} {
+    catch {return -level 0 -code error -errorinfo [catch {error foo bar baz}]}
+    list $::errorCode $::errorInfo
+} {NONE 1}
+test error-6.7 {catch must reset error state} {
+    proc foo {} {
+	return -code error -errorinfo [catch {error foo bar baz}]
+    }
+    catch foo
+    list $::errorCode
+} {NONE}
+test error-6.8 {catch must reset error state} {
+    catch {return -level 0 -code error [catch {error foo bar baz}]}
+    list $::errorCode
+} {NONE}
+test error-6.9 {catch must reset error state} {
+    proc foo {} {
+	return -code error [catch {error foo bar baz}]
+    }
+    catch foo
+    list $::errorCode
+} {NONE}
+test error-6.10 {catch must reset errorstack} -body {
+	proc f x {g $x$x}
+	proc g x {error G:$x}
+	catch {f 12}
+	set e1 [info errorstack]
+	catch {f 13}
+	set e2 [info errorstack]
+	list $e1 $e2
+} -match glob -result {{INNER * CALL {g 1212} CALL {f 12} UP 1} {INNER * CALL {g 1313} CALL {f 13} UP 1}}
+
+test error-7.1 {Bug 1397843} -body {
+    variable cmds
+    proc EIWrite args {
+	variable cmds
+	lappend cmds [lindex [info level -2] 0]
+    }
+    proc BadProc {} {
+	set i a
+	incr i
+    }
+    trace add variable ::errorInfo write [namespace code EIWrite]
+    catch BadProc
+    trace remove variable ::errorInfo write [namespace code EIWrite]
+    set cmds
+} -match glob -result {*BadProc*}
+
+# throw tests
+
+test error-8.1 {throw produces error 1 at level 0} {
+    catch { throw FOO bar }
+} {1}
+test error-8.2 {throw behaves as error does at level 0} {
+    catch { throw FOO bar } em1 opts1
+    catch { error bar {} FOO } em2 opts2
+    dict set opts1 -result $em1
+    dict set opts2 -result $em2
+    foreach key {-code -level -result -errorcode} {
+	if { [dict get $opts1 $key] ne [dict get $opts2 $key] } {
+	    error "error/throw outcome differs on '$key'"
+	}
+    }
+} {}
+test error-8.3 {throw produces error 1 at level > 0} {
+    proc throw_foo {} {
+	throw FOO bar
+    }
+    catch { throw_foo }
+} {1}
+test error-8.4 {throw behaves as error does at level > 0} {
+    proc throw_foo {} {
+	throw FOO bar
+    }
+    proc error_foo {} {
+	error bar {} FOO
+    }
+    catch { throw_foo } em1 opts1
+    catch { error_foo } em2 opts2
+    dict set opts1 -result $em1
+    dict set opts2 -result $em2
+    foreach key {-code -level -result -errorcode} {
+	if { [dict get $opts1 $key] ne [dict get $opts2 $key] } {
+	    error "error/throw outcome differs on '$key'"
+	}
+    }
+} {}
+test error-8.5 {throw syntax checks} -returnCodes error -body {
+    throw
+} -result {wrong # args: should be "throw type message"}
+test error-8.6 {throw syntax checks} -returnCodes error -body {
+    throw a
+} -result {wrong # args: should be "throw type message"}
+test error-8.7 {throw syntax checks} -returnCodes error -body {
+    throw a b c
+} -result {wrong # args: should be "throw type message"}
+test error-8.8 {throw syntax checks} -returnCodes error -body {
+    throw "not a \{ list" foo
+} -result {unmatched open brace in list}
+test error-8.9 {throw syntax checks} -returnCodes error -body {
+    throw {} foo
+} -result {type must be non-empty list}
+test error-8.10 {Bug 33b7abb8a2: throw stack usage} -returnCodes error -body {
+    apply {code {throw $code foo}} {}
+} -result {type must be non-empty list}
+test error-8.11 {Bug 7174354ecb: throw error message} -returnCodes error  -body {
+    throw {not {}a list} x[]y
+} -result {list element in braces followed by "a" instead of space}
+
+# simple try tests: body completes with code ok
+
+test error-9.1 {try (ok, empty result) with no handlers} {
+    try list
+} {}
+test error-9.2 {try (ok, non-empty result) with no handlers} {
+    try { list a b c }
+} {a b c}
+test error-9.3 {try (ok, non-empty result) with trap handler} {
+    try { list a b c } trap {} {} { list d e f }
+} {a b c}
+test error-9.4 {try (ok, non-empty result) with on handler} {
+    try { list a b c } on break {} { list d e f }
+} {a b c}
+test error-9.5 {try (ok, non-empty result) with on ok handler} {
+    try { list a b c } on ok {} { list d e f }
+} {d e f}
+
+# simple try tests - "on" handler matching
+
+test error-10.1 {try with on ok} {
+    try { list a b c } on ok {} { list d e f }
+} {d e f}
+test error-10.2 {try with on 0} {
+    try { list a b c } on 0 {} { list d e f }
+} {d e f}
+test error-10.3 {try with on error (using error)} {
+    try { error a b c } on error {} { list d e f }
+} {d e f}
+test error-10.4 {try with on error (using return -code)} {
+    try { return -level 0 -code 1 a } on error {} { list d e f }
+} {d e f}
+test error-10.5 {try with on error (using throw)} {
+    try { throw c a } on error {} { list d e f }
+} {d e f}
+test error-10.6 {try with on 1 (using error)} {
+    try { error a b c } on 1 {} { list d e f }
+} {d e f}
+test error-10.7 {try with on return} {
+    try { return [list a b c] } on return {} { list d e f }
+} {d e f}
+test error-10.8 {try with on break} {
+    try { break } on break {} { list d e f }
+} {d e f}
+test error-10.9 {try with on continue} {
+    try { continue } on continue {} { list d e f }
+} {d e f}
+test error-10.10 {try with on for arbitrary (decimal) return code} {
+    try { return -level 0 -code 123456 } on 123456 {} { list d e f }
+} {d e f}
+test error-10.11 {try with on for arbitrary (hex) return code} {
+    try { return -level 0 -code 0x123456 } on 0x123456 {} { list d e f }
+} {d e f}
+test error-10.12 {try with on for arbitrary return code (mixed number representations)} {
+    try { return -level 0 -code 0x10 } on 16 {} { list d e f }
+} {d e f}
+
+# simple try tests - "trap" handler matching
+
+test error-11.1 {try with trap all} {
+    try { throw FOO bar  } trap {} {} { list d e f }
+} {d e f}
+test error-11.2 {try with trap (exact)} {
+    try { throw FOO bar  } trap {FOO} {} { list d e f }
+} {d e f}
+test error-11.3 {try with trap (prefix 1)} {
+    try { throw [list FOO A B C D] bar  } trap {FOO} {} { list d e f }
+} {d e f}
+test error-11.4 {try with trap (prefix 2)} {
+    try { throw [list FOO A B C D] bar  } trap {FOO A} {} { list d e f }
+} {d e f}
+test error-11.5 {try with trap (prefix 3)} {
+    try { throw [list FOO A B C D] bar  } trap {FOO A B} {} { list d e f }
+} {d e f}
+test error-11.6 {try with trap (prefix 4)} {
+    try { throw [list FOO A B C D] bar  } trap {FOO A B C} {} { list d e f }
+} {d e f}
+test error-11.7 {try with trap (exact, 5 elements)} {
+    try { throw [list FOO A B C D] bar  } trap {FOO A B C D} {} { list d e f }
+} {d e f}
+
+# simple try tests - variable assignment and result handling
+
+test error-12.1 {try with no variable assignment in on handler} {
+    try { throw FOO bar } on error {} { list d e f }
+} {d e f}
+test error-12.2 {try with result variable assignment in on handler} {
+    try { throw FOO bar } on error {res} { set res }
+} {bar}
+test error-12.3 {try with result variable assignment in on handler, var remains in scope} {
+    try { throw FOO bar } on error {res} { list d e f }
+    set res
+} {bar}
+test error-12.4 {try with result/opts variable assignment in on handler} {
+    try {
+	throw FOO bar
+    } on error {res opts} {
+	set r "$res,[dict get $opts -errorcode]"
+    }
+} {bar,FOO}
+test error-12.5 {try with result/opts variable assignment in on handler, vars remain in scope} {
+    try { throw FOO bar } on error {res opts} { list d e f }
+    set r "$res,[dict get $opts -errorcode]"
+} {bar,FOO}
+test error-12.6 {try result is propagated if no matching handler} {
+    try { list a b c } on error {} { list d e f }
+} {a b c}
+test error-12.7 {handler result is propagated if handler executes} {
+    try { throw FOO bar } on error {} { list d e f }
+} {d e f}
+
+# negative case try tests - bad args to try
+
+test error-13.1 {try with no arguments} -body {
+    # warning: error message may change
+    try
+} -returnCodes error -match glob -result {wrong # args: *}
+test error-13.2 {try with body only (ok)} {
+    try list
+} {}
+test error-13.3 {try with missing finally body} -body {
+    # warning: error message may change
+    try list finally
+} -returnCodes error -match glob -result {wrong # args to finally clause: *}
+test error-13.4 {try with bad handler keyword} -body {
+    # warning: error message may change
+    try list then a b c
+} -returnCodes error -match glob -result {bad handler *}
+test error-13.5 {try with partial handler #1} -body {
+    # warning: error message may change
+    try list on
+} -returnCodes error -match glob -result {wrong # args to on clause: *}
+test error-13.6 {try with partial handler #2} -body {
+    # warning: error message may change
+    try list on error
+} -returnCodes error -match glob -result {wrong # args to on clause: *}
+test error-13.7 {try with partial handler #3} -body {
+    # warning: error message may change
+    try list on error {em opts}
+} -returnCodes error -match glob -result {wrong # args to on clause: *}
+test error-13.8 {try with multiple handlers and finally (ok)} {
+    try list on error {} {} trap {} {} {} finally {}
+} {}
+test error-13.9 {last handler body can't be a fallthrough #1} -body {
+    try list on error {} {} on break {} -
+} -returnCodes error -result {last non-finally clause must not have a body of "-"}
+test error-13.10 {last handler body can't be a fallthrough #2} -body {
+    try list on error {} {} on break {} - finally { list d e f }
+} -returnCodes error -result {last non-finally clause must not have a body of "-"}
+
+# try tests - multiple handlers (left-to-right matching, only one runs)
+
+test error-14.1 {try with multiple handlers (only one matches) #1} {
+    try { throw FOO bar } on ok {} { list a b c } trap FOO {} { list d e f }
+} {d e f}
+test error-14.2 {try with multiple handlers (only one matches) #2} {
+    try { throw FOO bar } trap FOO {} { list d e f } on ok {} { list a b c }
+} {d e f}
+test error-14.3 {try with multiple handlers (only one matches) #3} {
+    try {
+	throw FOO bar
+    } on break {} {
+	list x y z
+    } trap FOO {} {
+	list d e f
+    } on ok {} {
+	list a b c
+    }
+} {d e f}
+test error-14.4 {try with multiple matching handlers (only the first in left-to-right order runs) #1} {
+    try { throw FOO bar } on error {} { list a b c } trap FOO {} { list d e f }
+} {a b c}
+test error-14.5 {try with multiple matching handlers (only the first in left-to-right order runs) #2} {
+    try { throw FOO bar } trap FOO {} { list d e f } on error {} { list a b c }
+} {d e f}
+test error-14.6 {try with multiple matching handlers (only the first in left-to-right order runs) #3} {
+    try { throw FOO bar } trap {} {} { list d e f } on 1 {} { list a b c }
+} {d e f}
+test error-14.7 {try with multiple matching handlers (only the first in left-to-right order runs) #4} {
+    try { throw FOO bar } on 1 {} { list a b c } trap {} {} { list d e f }
+} {a b c}
+test error-14.8 {try with handler-of-last-resort "trap {}"} {
+    try { throw FOO bar } trap FOX {} { list a b c } trap {} {} { list d e f }
+} {d e f}
+test error-14.9 {try with handler-of-last-resort "on error"} {
+    try { foo } trap FOX {} { list a b c } on error {} { list d e f }
+} {d e f}
+
+# try tests - propagation (no matching handlers)
+
+test error-15.1 {try with no handler (ok result propagates)} {
+    try { list a b c }
+} {a b c}
+test error-15.2 {try with no matching handler (ok result propagates)} {
+    try { list a b c } on error {} { list d e f }
+} {a b c}
+test error-15.3 {try with no handler (error result propagates)} -body {
+    try { throw FOO bar }
+} -returnCodes error -result {bar}
+test error-15.4 {try with no matching handler (error result propagates)} -body {
+    try { throw FOO bar } trap FOX {} { list a b c }
+} -returnCodes error -result {bar}
+test error-15.5 {try with no handler (return result propagates)} -body {
+    try { return bar }
+} -returnCodes 2 -result {bar}
+test error-15.6 {try with no matching handler (break result propagates)} -body {
+    try { if {1} break } on error {} { list a b c }
+} -returnCodes 3 -result {}
+test error-15.7 {try with no matching handler (unknown integer result propagates)} -body {
+    try { return -level 0 -code 123456 } trap {} {} { list a b c }
+} -returnCodes 123456 -result {}
+
+foreach level {0 1 2 3} {
+    foreach code {0 1 2 3 4 5} {
+
+	# Following cases have different -errorinfo; avoid false alarms
+	# TODO: examine whether these difference are as they ought to be.
+	if {$level == 0 && $code == 1} continue
+
+	foreach extras {{} {-bar soom}} {
+
+test error-15.8.$level.$code.[llength $extras] {[try] coverage} {
+    set script {return -level $level -code $code {*}$extras foo}
+    catch $script m1 o1
+    catch {try $script} m2 o2
+    set o1 [lsort -stride 2 $o1]
+    set o2 [lsort -stride 2 $o2]
+    expr {$o1 eq $o2 ? "ok" : "$o1\n\tis not equal to\n$o2"}
+} ok
+
+test error-15.9.$level.$code.[llength $extras] {[try] coverage} {
+    set script {return -level $level -code $code {*}$extras foo}
+    catch $script m1 o1
+    catch {try $script finally {}} m2 o2
+    set o1 [lsort -stride 2 $o1]
+    set o2 [lsort -stride 2 $o2]
+    expr {$o1 eq $o2 ? "ok" : "$o1\n\tis not equal to\n$o2"}
+} ok
+
+test error-15.10.$level.$code.[llength $extras] {[try] coverage} {
+    set script {return -level $level -code $code {*}$extras foo}
+    catch $script m1 o1
+    catch {try $script on $code {x y} {return -options $y $x}} m2 o2
+    set o1 [lsort -stride 2 $o1]
+    set o2 [lsort -stride 2 $o2]
+    expr {$o1 eq $o2 ? "ok" : "$o1\n\tis not equal to\n$o2"}
+} ok
+
+	}
+    }
+}
+
+# try tests - propagation (exceptions in handlers, exception chaining)
+
+test error-16.1 {try with successfully executed handler} {
+    try { throw FOO bar } trap FOO {} { list a b c }
+} {a b c}
+test error-16.2 {try with exception (error) in handler} -body {
+    try { throw FOO bar } trap FOO {} { throw BAR foo }
+} -returnCodes error -result {foo}
+test error-16.3 {try with exception (return) in handler} -body {
+    try { throw FOO bar } trap FOO {} { return BAR }
+} -returnCodes 2 -result {BAR}
+test error-16.4 {try with exception (break) in handler #1} -body {
+    try { throw FOO bar } trap FOO {} { break }
+} -returnCodes 3 -result {}
+test error-16.5 {try with exception (break) in handler #2} {
+    for { set i 5 } { $i < 10 } { incr i } {
+	try { throw FOO bar } trap FOO {} { break }
+    }
+    set i
+} {5}
+test error-16.6 {try with variable assignment and propagation #1} {
+    # Ensure that the handler variables preserve the exception off the
+    # try-body, and are not modified by the exception off the handler
+    catch {
+	try { throw FOO bar } trap FOO {em} { throw BAR baz }
+    }
+    set em
+} {bar}
+test error-16.7 {try with variable assignment and propagation #2} {
+    catch {
+	try { throw FOO bar } trap FOO {em opts} { throw BAR baz }
+    }
+    list $em [dict get $opts -errorcode]
+} {bar FOO}
+test error-16.8 {exception chaining (try=ok, handler=error)} -body {
+    #FIXME is the intent of this test correct?
+    catch {
+	try { list a b c } on ok {em opts} { throw BAR baz }
+    } tryem tryopts
+    list $opts [dict get $tryopts -during]
+} -match pairwise -result equal
+test error-16.9 {exception chaining (try=error, handler=error)} -body {
+    # The exception off the handler should chain to the exception off the
+    # try-body (using the -during option)
+    catch {
+	try { throw FOO bar } trap {} {em opts} { throw BAR baz }
+    } tryem tryopts
+    list $opts [dict get $tryopts -during]
+} -match pairwise -result equal
+test error-16.10 {no exception chaining when handler is successful} {
+    catch {
+	try { throw FOO bar } trap {} {em opts} { list d e f }
+    } tryem tryopts
+    dict exists $tryopts -during
+} {0}
+test error-16.11 {no exception chaining when handler is a non-error exception} {
+    catch {
+	try { throw FOO bar } trap {} {em opts} { break }
+    } tryem tryopts
+    dict exists $tryopts -during
+} {0}
+test error-16.12 {compiled try with successfully executed handler} {
+    apply {{} {
+	try { throw FOO bar } trap FOO {} { list a b c }
+    }}
+} {a b c}
+test error-16.13 {compiled try with exception (error) in handler} -body {
+    apply {{} {
+	try { throw FOO bar } trap FOO {} { throw BAR foo }
+    }}
+} -returnCodes error -result {foo}
+test error-16.14 {compiled try with exception (return) in handler} -body {
+    apply {{} {
+	list [catch {
+	    try { throw FOO bar } trap FOO {} { return BAR }
+	} msg] $msg
+    }}
+} -result {2 BAR}
+test error-16.15 {compiled try with exception (break) in handler} {
+    apply {{} {
+	for { set i 5 } { $i < 10 } { incr i } {
+	    try { throw FOO bar } trap FOO {} { break }
+	}
+	return $i
+    }}
+} {5}
+test error-16.16 {compiled try with exception (continue) in handler} {
+    apply {{} {
+	for { set i 5 } { $i < 10 } { incr i } {
+	    try { throw FOO bar } trap FOO {} { continue }
+	    incr i 20
+	}
+	return $i
+    }}
+} {10}
+test error-16.17 {compiled try with variable assignment and propagation #1} {
+    # Ensure that the handler variables preserve the exception off the
+    # try-body, and are not modified by the exception off the handler
+    apply {{} {
+	catch {
+	    try { throw FOO bar } trap FOO {em} { throw BAR baz }
+	}
+	return $em
+    }}
+} {bar}
+test error-16.18 {compiled try with variable assignment and propagation #2} {
+    apply {{} {
+	catch {
+	    try { throw FOO bar } trap FOO {em opts} { throw BAR baz }
+	}
+	list $em [dict get $opts -errorcode]
+    }}
+} {bar FOO}
+test error-16.19 {compiled try exception chaining (try=ok, handler=error)} -body {
+    #FIXME is the intent of this test correct?
+    apply {{} {
+	catch {
+	    try { list a b c } on ok {em opts} { throw BAR baz }
+	} tryem tryopts
+	list $opts [dict get $tryopts -during]
+    }}
+} -match pairwise -result equal
+test error-16.20 {compiled try exception chaining (try=error, handler=error)} -body {
+    # The exception off the handler should chain to the exception off the
+    # try-body (using the -during option)
+    apply {{} {
+	catch {
+	    try { throw FOO bar } trap {} {em opts} { throw BAR baz }
+	} tryem tryopts
+	list $opts [dict get $tryopts -during]
+    }}
+} -match pairwise -result equal
+test error-16.21 {compiled try exception chaining (try=error, finally=error)} {
+    # The exception off the handler should chain to the exception off the
+    # try-body (using the -during option)
+    apply {{} {
+	catch {
+	    try { throw FOO bar } finally { throw BAR baz }
+	} tryem tryopts
+	dict get $tryopts -during -errorcode
+    }}
+} FOO
+test error-16.22 {compiled try: no exception chaining when handler is successful} {
+    apply {{} {
+	catch {
+	    try { throw FOO bar } trap {} {em opts} { list d e f }
+	} tryem tryopts
+	dict exists $tryopts -during
+    }}
+} {0}
+test error-16.23 {compiled try: no exception chaining when handler is a non-error exception} {
+    apply {{} {
+	catch {
+	    try { throw FOO bar } trap {} {em opts} { break }
+	} tryem tryopts
+	dict exists $tryopts -during
+    }}
+} {0}
+test error-16.24 {compiled try exception chaining (try=ok, handler=error, finally=error)} -body {
+    apply {{} {
+	catch {
+	    try {
+		list a b c
+	    } on ok {em opts} {
+		throw BAR baz
+	    } finally {
+		throw DING dong
+	    }
+	} tryem tryopts
+	list $opts [dict get $tryopts -during -during]
+    }}
+} -match pairwise -result equal
+test error-16.25 {compiled try exception chaining (all errors)} -body {
+    apply {{} {
+	catch {
+	    try {
+		throw FOO bar
+	    } on error {em opts} {
+		throw BAR baz
+	    } finally {
+		throw DING dong
+	    }
+	} tryem tryopts
+	list $opts [dict get $tryopts -during -during]
+    }}
+} -match pairwise -result equal
+
+# try tests - finally
+
+test error-17.1 {finally always runs (try with ok result)} {
+    set RES {}
+    try { list a b c } finally { set RES done }
+    set RES
+} {done}
+test error-17.2 {finally always runs (try with error result)} {
+    set RES {}
+    catch {
+	try { throw FOO bar } finally { set RES done }
+    }
+    set RES
+} {done}
+test error-17.3 {finally always runs (try with matching handler)} {
+    set RES {}
+    try { throw FOO bar } trap FOO {} { list a b c } finally { set RES done }
+    set RES
+} {done}
+test error-17.4 {finally always runs (try with exception in handler)} {
+    set RES {}
+    catch {
+	try {
+	    throw FOO bar
+	} trap FOO {} {
+	    throw BAR baz
+	} finally {
+	    set RES done
+	}
+    }
+    set RES
+} {done}
+test error-17.5 {successful finally doesn't modify try outcome (try=ok)} {
+    try { list a b c } finally { list d e f }
+} {a b c}
+test error-17.6 {successful finally doesn't modify try outcome (try=return)} -body {
+    try { return c } finally { list d e f }
+} -returnCodes 2 -result {c}
+test error-17.7 {successful finally doesn't modify try outcome (try=error)} -body {
+    try { error bar } finally { list d e f }
+} -returnCodes 1 -result {bar}
+test error-17.8 {successful finally doesn't modify handler outcome (handler=ok)} {
+    try { throw FOO bar } trap FOO {} { list a b c } finally { list d e f }
+} {a b c}
+test error-17.9 {successful finally doesn't modify handler outcome (handler=error)} -body {
+    try { throw FOO bar } trap FOO {} { throw BAR baz } finally { list d e f }
+} -returnCodes error -result {baz}
+test error-17.10 {successful finally doesn't affect variable assignment} {
+    catch {
+	try { throw FOO bar } trap FOO {em opts} { list d e f } finally { list d e f }
+    } result
+    list $em $result
+} {bar {d e f}}
+test error-17.11 {successful finally doesn't affect variable assignment or propagation} {
+    catch {
+	try { throw FOO bar } trap FOO {em opts} { throw BAR baz } finally { list d e f }
+    }
+    list $em [dict get $opts -errorcode]
+} {bar FOO}
+
+# try tests - propagation (exceptions in finally, exception chaining)
+
+test error-18.1 {try (ok) with exception in finally (error)} -body {
+    try { list a b c } finally { throw BAR foo }
+} -returnCodes error -result {foo}
+test error-18.2 {try (error) with exception in finally (break)} -body {
+    try { throw FOO bar } finally { break }
+} -returnCodes 3 -result {}
+test error-18.3 {try (ok) with handler (ok) and exception in finally (error)} -body {
+    try { list a b c } on ok {} { list d e f } finally { throw BAR foo }
+} -returnCodes error -result {foo}
+test error-18.4 {try (error) with exception in handler (error) and in finally (arb code)} -body {
+    try { throw FOO bar } on error {} { throw BAR baz } finally { return -level 0 -code 99 zing }
+} -returnCodes 99 -result {zing}
+test error-18.5 {exception in finally doesn't affect variable assignment} {
+    catch {
+	try { throw FOO bar } trap FOO {em opts} { throw BAR baz } finally { throw BAZ zing }
+    }
+    list $em [dict get $opts -errorcode]
+} {bar FOO}
+test error-18.6 {exception chaining in finally (try=ok)} -body {
+    catch {
+	list a b c
+    } em expopts
+    catch {
+	try { list a b c } finally { throw BAR foo }
+    } em opts
+    list $expopts [dict get $opts -during]
+} -match pairwise -result equal
+test error-18.7 {exception chaining in finally (try=error)} {
+    catch {
+	try { throw FOO bar } finally { throw BAR baz }
+    } em opts
+    dict get $opts -during -errorcode
+} {FOO}
+test error-18.8 {exception chaining in finally (try=ok, handler=ok)} {
+    catch {
+	try { list a b c } on ok {} { list d e f } finally { throw BAR baz }
+    } em opts
+    list [dict get $opts -during -code] [dict exists $opts -during -during]
+} {0 0}
+test error-18.9 {exception chaining in finally (try=error, handler=ok)} {
+    catch {
+	try {
+	    throw FOO bar
+	} on error {} {
+	    list d e f
+	} finally {
+	    throw BAR baz
+	}
+    } em opts
+    list [dict get $opts -during -code] [dict exists $opts -during -during]
+} {0 0}
+test error-18.10 {exception chaining in finally (try=error, handler=error)} {
+    catch {
+	try {
+	    throw FOO bar
+	} on error {} {
+	    throw BAR baz
+	} finally {
+	    throw BAR baz
+	}
+    } em opts
+    list [dict get $opts -during -errorcode] [dict get $opts -during -during -errorcode]
+} {BAR FOO}
+test error-18.11 {no exception chaining if finally produces a non-error exception} {
+    catch {
+	try { throw FOO bar } on error {} { throw BAR baz } finally { break }
+    } em opts
+    dict exists $opts -during
+} {0}
+test error-18.12 {variable assignment unaffected by exception in finally} {
+    catch {
+	try {
+	    throw FOO bar
+	} on error {em opts} {
+	    list a b c
+	} finally {
+	    throw BAR baz
+	}
+    }
+    list $em [dict get $opts -errorcode]
+} {bar FOO}
+
+# try tests - fallthough body cases
+
+test error-19.1 {try with fallthrough body #1} {
+    set RES {}
+    try { list a b c } on ok { set RES 0 } - on error {} { set RES 1 }
+    set RES
+} {1}
+test error-19.2 {try with fallthrough body #2} {
+    set RES {}
+    try {
+	throw FOO bar
+    } trap BAR {} {
+    } trap FOO {} - trap {} {} {
+	set RES foo
+    } on error {} {
+	set RES err
+    }
+    set RES
+} {foo}
+test error-19.3 {try with cascade fallthrough} {
+    set RES {}
+    try {
+	throw FOO bar
+    } trap FOO {} - trap BAR {} - trap {} {} {
+	set RES trap
+    } on error {} { set RES err }
+    set RES
+} {trap}
+test error-19.4 {multiple unrelated fallthroughs #1} {
+    set RES {}
+    try {
+	throw FOO bar
+    } trap FOO {} - trap BAR {} {
+	set RES foo
+    } trap {} {} - on error {} {
+	set RES err
+    }
+    set RES
+} {foo}
+test error-19.5 {multiple unrelated fallthroughs #2} {
+    set RES {}
+    try {
+	throw BAZ zing
+    } trap FOO {} - trap BAR {} {
+	set RES foo
+    } trap {} {} - on error {} {
+	set RES err
+    }
+    set RES
+} {err}
+proc addmsg msg {
+    variable RES
+    lappend RES $msg
+}
+test error-19.6 {compiled try executes all clauses} -setup {
+    set RES {}
+} -body {
+    apply {{} {
+	try {
+	    addmsg a
+	    throw bar hello
+	} trap bar {res opt} {
+	    addmsg b
+	} finally {
+	    addmsg c
+	}
+	addmsg d
+    } ::tcl::test::error}
+} -cleanup {
+    unset RES
+} -result {a b c d}
+test error-19.7 {compiled try executes all clauses} -setup {
+    set RES {}
+} -body {
+    apply {{} {
+	try {
+	    addmsg a
+	} on error {res opt} {
+	    addmsg b
+	} on ok {} {
+	    addmsg c
+	} finally {
+	    addmsg d
+	}
+	addmsg e
+    } ::tcl::test::error}
+} -cleanup {
+    unset RES
+} -result {a c d e}
+test error-19.8 {compiled try executes all clauses} -setup {
+    set RES {}
+} -body {
+    apply {{} {
+	try {
+	    addmsg a
+	    throw bar hello
+	} trap bar {res opt} {
+	    addmsg b
+	}
+	addmsg c
+    } ::tcl::test::error}
+} -cleanup {
+    unset RES
+} -result {a b c}
+test error-19.9 {compiled try executes all clauses} -setup {
+    set RES {}
+} -body {
+    apply {{} {
+	try {
+	    addmsg a
+	} on error {res opt} {
+	    addmsg b
+	} on ok {} {
+	    addmsg c
+	}
+	addmsg d
+    } ::tcl::test::error}
+} -cleanup {
+    unset RES
+} -result {a c d}
+test error-19.10 {compiled try with chained clauses} -setup {
+    set RES {}
+} -body {
+    list [apply {{} {
+	try {
+	    return good
+	} on return {res} - on ok {res} {
+	    addmsg ok
+	    addmsg $res
+	    return handler
+	} finally {
+	    addmsg finally
+	}
+    } ::tcl::test::error}] $RES
+} -cleanup {
+    unset RES
+} -result {handler {ok good finally}}
+test error-19.11 {compiled try and errors on variable write} -setup {
+    set RES {}
+} -body {
+    apply {{} {
+	array set foo {bar boo}
+	set bar unset
+	catch {
+	    try {
+		addmsg body
+		return a
+	    } on return {bar foo} {
+		addmsg handler
+		return b
+	    } finally {
+		addmsg finally,$bar
+	    }
+	} msg
+	addmsg $msg
+    } ::tcl::test::error}
+} -cleanup {
+    unset RES
+} -result {body finally,a {can't set "foo": variable is array}}
+test error-19.12 {interpreted try and errors on variable write} -setup {
+    set RES {}
+} -body {
+    apply {try {
+	array set foo {bar boo}
+	set bar unset
+	catch {
+	    $try {
+		addmsg body
+		return a
+	    } on return {bar foo} {
+		addmsg handler
+		return b
+	    } finally {
+		addmsg finally,$bar
+	    }
+	} msg
+	addmsg $msg
+    } ::tcl::test::error} try
+} -cleanup {
+    unset RES
+} -result {body finally,a {can't set "foo": variable is array}}
+test error-19.13 {compiled try and errors on variable write} -setup {
+    set RES {}
+} -body {
+    apply {{} {
+	array set foo {bar boo}
+	set bar unset
+	catch {
+	    try {
+		addmsg body
+		return a
+	    } on return {bar foo} - on error {bar foo} {
+		addmsg handler
+		return b
+	    } finally {
+		addmsg finally,$bar
+	    }
+	} msg
+	addmsg $msg
+    } ::tcl::test::error}
+} -cleanup {
+    unset RES
+} -result {body finally,a {can't set "foo": variable is array}}
+rename addmsg {}
+
+# FIXME test what vars get set on fallthough ... what is the correct behavior?
+# It would seem appropriate to set at least those for the matching handler and
+# the executed body; possibly for each handler we fall through as well?
+
+# negative case try tests - bad "on" handler
+
+test error-20.1 {bad code name in on handler} -body {
+    try { list a b c } on err {} {}
+} -returnCodes error -match glob -result {bad completion code "err": must be ok, error, return, break, continue*, or an integer}
+test error-20.2 {bad code value in on handler} -body {
+    try { list a b c } on 34985723094872345 {} {}
+} -returnCodes error -match glob -result {bad completion code "34985723094872345": must be ok, error, return, break, continue*, or an integer}
+
+test error-21.1 {memory leaks in try: Bug 2910044} memory {
+    leaktest {
+	try {string repeat x 10} on ok {} {}
+    }
+} 0
+test error-21.2 {memory leaks in try: Bug 2910044} memory {
+    leaktest {
+	try {error [string repeat x 10]} on error {} {}
+    }
+} 0
+test error-21.3 {memory leaks in try: Bug 2910044} memory {
+    leaktest {
+	try {throw FOO [string repeat x 10]} trap FOO {} {}
+    }
+} 0
+test error-21.4 {memory leaks in try: Bug 2910044} memory {
+    leaktest {
+	try {string repeat x 10}
+    }
+} 0
+test error-21.5 {memory leaks in try: Bug 2910044} memory {
+    leaktest {
+	try {string repeat x 10} on ok {} {} finally {string repeat y 10}
+    }
+} 0
+test error-21.6 {memory leaks in try: Bug 2910044} memory {
+    leaktest {
+	try {
+	    error [string repeat x 10]
+	} on error {} {} finally {
+	    string repeat y 10
+	}
+    }
+} 0
+test error-21.7 {memory leaks in try: Bug 2910044} memory {
+    leaktest {
+	try {
+	    throw FOO [string repeat x 10]
+	} trap FOO {} {} finally {
+	    string repeat y 10
+	}
+    }
+} 0
+test error-21.8 {memory leaks in try: Bug 2910044} memory {
+    leaktest {
+	try {string repeat x 10} finally {string repeat y 10}
+    }
+} 0
+
+test error-21.9 {Bug cee90e4e88} {
+    # Just don't panic.
+    apply {{} {try {} on ok {} - on return {} {}}}
+} {}
+
+
+# negative case try tests - bad "trap" handler
+# what is the effect if we attempt to trap an errorcode that is not a list?
+# nested try
+# catch inside try
+# no tests for bad varslist?
+# -errorcode but code!=1 doesn't trap
+# throw negative case tests (no args, too many args, etc)
+
+}
+namespace delete ::tcl::test::error
+
+# cleanup
+catch {rename p ""}
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/tests/eval.test b/tests/eval.test
new file mode 100644
index 0000000..70ceac8
--- /dev/null
+++ b/tests/eval.test
@@ -0,0 +1,89 @@
+# Commands covered:  eval
+#
+# This file contains a collection of tests for one or more of the Tcl built-in
+# commands.  Sourcing this file into Tcl runs the tests and generates output
+# for errors.  No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution of
+# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {"::tcltest" ni [namespace children]} {
+    package require tcltest
+    namespace import -force ::tcltest::*
+}
+
+test eval-1.1 {single argument} {
+    eval {format 22}
+} 22
+test eval-1.2 {multiple arguments} {
+    set a {$b}
+    set b xyzzy
+    eval format $a
+} xyzzy
+test eval-1.3 {single argument} {
+    eval concat a b c d e f g
+} {a b c d e f g}
+
+test eval-2.1 {error: not enough arguments} {catch eval} 1
+test eval-2.2 {error: not enough arguments} {
+    catch eval msg
+    set msg
+} {wrong # args: should be "eval arg ?arg ...?"}
+test eval-2.3 {error in eval'ed command} {
+    catch {eval {error "test error"}}
+} 1
+test eval-2.4 {error in eval'ed command} {
+    catch {eval {error "test error"}} msg
+    set msg
+} {test error}
+test eval-2.5 {error in eval'ed command: setting errorInfo} {
+    catch {eval {
+	set a 1
+	error "test error"
+    }} msg
+    set ::errorInfo
+} "test error
+    while executing
+\"error \"test error\"\"
+    (\"eval\" body line 3)
+    invoked from within
+\"eval {
+	set a 1
+	error \"test error\"
+    }\""
+
+test eval-3.1 {eval and pure lists} {
+    eval [list list 1 2 3 4 5]
+} {1 2 3 4 5}
+test eval-3.2 {concatenating eval and pure lists} {
+    eval [list list 1] [list 2 3 4 5]
+} {1 2 3 4 5}
+test eval-3.3 {eval and canonical lists} {
+    set cmd [list list 1 2 3 4 5]
+    # Force existance of utf-8 rep
+    set dummy($cmd) $cmd
+    unset dummy
+    eval $cmd
+} {1 2 3 4 5}
+test eval-3.4 {concatenating eval and canonical lists} {
+    set cmd  [list list 1]
+    set cmd2 [list 2 3 4 5]
+    # Force existance of utf-8 rep
+    set dummy($cmd) $cmd
+    set dummy($cmd2) $cmd2
+    unset dummy
+    eval $cmd $cmd2
+} {1 2 3 4 5}
+
+# cleanup
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# fill-column: 78
+# End:
diff --git a/tests/event.test b/tests/event.test
new file mode 100644
index 0000000..207c799
--- /dev/null
+++ b/tests/event.test
@@ -0,0 +1,961 @@
+# This file contains a collection of tests for the procedures in the file
+# tclEvent.c, which includes the "update", and "vwait" Tcl commands.  Sourcing
+# this file into Tcl runs the tests and generates output for errors.  No
+# output means no errors were found.
+#
+# Copyright (c) 1995-1997 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+package require tcltest 2
+namespace import -force ::tcltest::*
+
+catch {
+    ::tcltest::loadTestedCommands
+    package require -exact Tcltest [info patchlevel]
+    set ::tcltestlib [lindex [package ifneeded Tcltest [info patchlevel]] 1]
+}
+
+
+testConstraint testfilehandler [llength [info commands testfilehandler]]
+testConstraint testexithandler [llength [info commands testexithandler]]
+testConstraint testfilewait [llength [info commands testfilewait]]
+testConstraint exec [llength [info commands exec]]
+
+test event-1.1 {Tcl_CreateFileHandler, reading} -setup {
+    testfilehandler close
+    set result ""
+} -constraints {testfilehandler} -body {
+    testfilehandler create 0 readable off
+    testfilehandler clear 0
+    testfilehandler oneevent
+    lappend result [testfilehandler counts 0]
+    testfilehandler fillpartial 0
+    testfilehandler oneevent
+    lappend result [testfilehandler counts 0]
+    testfilehandler oneevent
+    lappend result [testfilehandler counts 0]
+} -cleanup {
+    testfilehandler close
+} -result {{0 0} {1 0} {2 0}}
+test event-1.2 {Tcl_CreateFileHandler, writing} -setup {
+    testfilehandler close
+    set result ""
+} -constraints {testfilehandler nonPortable} -body {
+    # This test is non-portable because on some systems (e.g., SunOS 4.1.3)
+    # pipes seem to be writable always.
+    testfilehandler create 0 off writable
+    testfilehandler clear 0
+    testfilehandler oneevent
+    lappend result [testfilehandler counts 0]
+    testfilehandler fillpartial 0
+    testfilehandler oneevent
+    lappend result [testfilehandler counts 0]
+    testfilehandler fill 0
+    testfilehandler oneevent
+    lappend result [testfilehandler counts 0]
+} -cleanup {
+    testfilehandler close
+} -result {{0 1} {0 2} {0 2}}
+test event-1.3 {Tcl_DeleteFileHandler} -setup {
+    testfilehandler close
+    set result ""
+} -constraints {testfilehandler nonPortable} -body {
+    testfilehandler create 2 disabled disabled
+    testfilehandler create 1 readable writable
+    testfilehandler create 0 disabled disabled
+    testfilehandler fillpartial 1
+    testfilehandler oneevent
+    lappend result [testfilehandler counts 1]
+    testfilehandler oneevent
+    lappend result [testfilehandler counts 1]
+    testfilehandler oneevent
+    lappend result [testfilehandler counts 1]
+    testfilehandler create 1 off off
+    testfilehandler oneevent
+    lappend result [testfilehandler counts 1]
+} -cleanup {
+    testfilehandler close
+} -result {{0 1} {1 1} {1 2} {0 0}}
+
+test event-2.1 {Tcl_DeleteFileHandler} -setup {
+    testfilehandler close
+    set result ""
+} -constraints {testfilehandler nonPortable} -body {
+    testfilehandler create 2 disabled disabled
+    testfilehandler create 1 readable writable
+    testfilehandler fillpartial 1
+    testfilehandler oneevent
+    lappend result [testfilehandler counts 1]
+    testfilehandler oneevent
+    lappend result [testfilehandler counts 1]
+    testfilehandler oneevent
+    lappend result [testfilehandler counts 1]
+    testfilehandler create 1 off off
+    testfilehandler oneevent
+    lappend result [testfilehandler counts 1]
+} -cleanup {
+    testfilehandler close
+} -result {{0 1} {1 1} {1 2} {0 0}}
+test event-2.2 {Tcl_DeleteFileHandler, fd reused & events still pending} -setup {
+    testfilehandler close
+    set result ""
+} -constraints {testfilehandler nonPortable} -body {
+    testfilehandler create 0 readable writable
+    testfilehandler fillpartial 0
+    testfilehandler oneevent
+    lappend result [testfilehandler counts 0]
+    testfilehandler close
+    testfilehandler create 0 readable writable
+    testfilehandler oneevent
+    lappend result [testfilehandler counts 0]
+} -cleanup {
+    testfilehandler close
+} -result {{0 1} {0 0}}
+
+test event-3.1 {FileHandlerCheckProc, TCL_FILE_EVENTS off} -setup {
+    testfilehandler close
+} -constraints {testfilehandler} -body {
+    testfilehandler create 1 readable writable
+    testfilehandler fillpartial 1
+    testfilehandler windowevent
+    testfilehandler counts 1
+} -cleanup {
+    testfilehandler close
+} -result {0 0}
+
+test event-4.1 {FileHandlerEventProc, race between event and disabling} -setup {
+    update
+    testfilehandler close
+    set result ""
+} -constraints {testfilehandler nonPortable} -body {
+    testfilehandler create 2 disabled disabled
+    testfilehandler create 1 readable writable
+    testfilehandler fillpartial 1
+    testfilehandler oneevent
+    lappend result [testfilehandler counts 1]
+    testfilehandler oneevent
+    lappend result [testfilehandler counts 1]
+    testfilehandler oneevent
+    lappend result [testfilehandler counts 1]
+    testfilehandler create 1 disabled disabled
+    testfilehandler oneevent
+    lappend result [testfilehandler counts 1]
+} -cleanup {
+    testfilehandler close
+} -result {{0 1} {1 1} {1 2} {0 0}}
+test event-4.2 {FileHandlerEventProc, TCL_FILE_EVENTS off} -setup {
+    update
+    testfilehandler close
+} -constraints {testfilehandler nonPortable} -body {
+    testfilehandler create 1 readable writable
+    testfilehandler create 2 readable writable
+    testfilehandler fillpartial 1
+    testfilehandler fillpartial 2
+    testfilehandler oneevent
+    set result ""
+    lappend result [testfilehandler counts 1] [testfilehandler counts 2]
+    testfilehandler windowevent
+    lappend result [testfilehandler counts 1] [testfilehandler counts 2]
+} -cleanup {
+    testfilehandler close
+} -result {{0 0} {0 1} {0 0} {0 1}}
+update
+
+test event-5.1 {Tcl_BackgroundError, HandleBgErrors procedures} -setup {
+    catch {rename bgerror {}}
+} -body {
+    proc bgerror msg {
+	global errorInfo errorCode x
+	lappend x [list $msg $errorInfo $errorCode]
+    }
+    after idle {error "a simple error"}
+    after idle {open non_existent}
+    after idle {set errorInfo foobar; set errorCode xyzzy}
+    set x {}
+    update idletasks
+    regsub -all [file join {} non_existent] $x "non_existent"
+} -cleanup {
+    rename bgerror {}
+} -result {{{a simple error} {a simple error
+    while executing
+"error "a simple error""
+    ("after" script)} NONE} {{couldn't open "non_existent": no such file or directory} {couldn't open "non_existent": no such file or directory
+    while executing
+"open non_existent"
+    ("after" script)} {POSIX ENOENT {no such file or directory}}}}
+test event-5.2 {Tcl_BackgroundError, HandleBgErrors procedures} -setup {
+    catch {rename bgerror {}}
+} -body {
+    proc bgerror msg {
+	global x
+	lappend x $msg
+	return -code break
+    }
+    after idle {error "a simple error"}
+    after idle {open non_existent}
+    set x {}
+    update idletasks
+    return $x
+} -cleanup {
+    rename bgerror {}
+} -result {{a simple error}}
+test event-5.3 {HandleBgErrors: [Bug 1670155]} -setup {
+    variable x
+    proc demo args {variable x done}
+    variable target [list [namespace which demo] x]
+    proc trial args {variable target; string length $target}
+    trace add execution demo enter [namespace code trial]
+    variable save [interp bgerror {}]
+    interp bgerror {} $target
+} -body {
+    after 0 {error bar}
+    vwait [namespace which -variable x]
+} -cleanup {
+    interp bgerror {} $save
+    unset x target save
+    rename demo {}
+    rename trial {}
+} -result {}
+test event-5.3.1 {Default [interp bgerror] handler} -body {
+    ::tcl::Bgerror
+} -returnCodes error -match glob -result {*msg options*}
+test event-5.4 {Default [interp bgerror] handler} -body {
+    ::tcl::Bgerror {}
+} -returnCodes error -match glob -result {*msg options*}
+test event-5.5 {Default [interp bgerror] handler} -body {
+    ::tcl::Bgerror {} {} {}
+} -returnCodes error -match glob -result {*msg options*}
+test event-5.6 {Default [interp bgerror] handler} -body {
+    ::tcl::Bgerror {} {}
+} -returnCodes error -match glob -result {*-level*}
+test event-5.7 {Default [interp bgerror] handler} -body {
+    ::tcl::Bgerror {} {-level foo}
+} -returnCodes error -match glob -result {*expected integer*}
+test event-5.8 {Default [interp bgerror] handler} -body {
+    ::tcl::Bgerror {} {-level 0}
+} -returnCodes error -match glob -result {*-code*}
+test event-5.9 {Default [interp bgerror] handler} -body {
+    ::tcl::Bgerror {} {-level 0 -code ok}
+} -returnCodes error -match glob -result {*expected integer*}
+test event-5.10 {Default [interp bgerror] handler} -body {
+    proc bgerror {m} {append ::res $m}
+    set ::res {}
+    ::tcl::Bgerror {} {-level 0 -code 0}
+    return $::res
+} -cleanup {
+    rename bgerror {}
+} -result {}
+test event-5.11 {Default [interp bgerror] handler} -body {
+    proc bgerror {m} {append ::res $m}
+    set ::res {}
+    ::tcl::Bgerror msg {-level 0 -code 1}
+    return $::res
+} -cleanup {
+    rename bgerror {}
+} -result {msg}
+test event-5.12 {Default [interp bgerror] handler} -body {
+    proc bgerror {m} {append ::res $m}
+    set ::res {}
+    ::tcl::Bgerror msg {-level 0 -code 2}
+    return $::res
+} -cleanup {
+    rename bgerror {}
+} -result {command returned bad code: 2}
+test event-5.13 {Default [interp bgerror] handler} -body {
+    proc bgerror {m} {append ::res $m}
+    set ::res {}
+    ::tcl::Bgerror msg {-level 0 -code 3}
+    return $::res
+} -cleanup {
+    rename bgerror {}
+} -result {invoked "break" outside of a loop}
+test event-5.14 {Default [interp bgerror] handler} -body {
+    proc bgerror {m} {append ::res $m}
+    set ::res {}
+    ::tcl::Bgerror msg {-level 0 -code 4}
+    return $::res
+} -cleanup {
+    rename bgerror {}
+} -result {invoked "continue" outside of a loop}
+test event-5.15 {Default [interp bgerror] handler} -body {
+    proc bgerror {m} {append ::res $m}
+    set ::res {}
+    ::tcl::Bgerror msg {-level 0 -code 5}
+    return $::res
+} -cleanup {
+    rename bgerror {}
+} -result {command returned bad code: 5}
+
+test event-6.1 {BgErrorDeleteProc procedure} -setup {
+    catch {interp delete foo}
+    interp create foo
+    set erroutfile [makeFile Unmodified err.out]
+} -body {
+    foo eval [list set erroutfile $erroutfile]
+    foo eval {
+	proc bgerror args {
+	    global errorInfo erroutfile
+	    set f [open $erroutfile r+]
+	    seek $f 0 end
+	    puts $f "$args $errorInfo"
+	    close $f
+	}
+	after 100 {error "first error"}
+	after 100 {error "second error"}
+    }
+    after 100 {interp delete foo}
+    after 200
+    update
+    set f [open $erroutfile r]
+    set result [read $f]
+    close $f
+    return $result
+} -cleanup {
+    removeFile $erroutfile
+} -result {Unmodified
+}
+
+test event-7.1 {bgerror / regular} {
+    set errRes {}
+    proc bgerror {err} {
+	global errRes
+	set errRes $err
+    }
+    after 0 {error err1}
+    vwait errRes
+    return $errRes
+} err1
+test event-7.2 {bgerror / accumulation} {
+    set errRes {}
+    proc bgerror {err} {
+	global errRes
+	lappend errRes $err
+    }
+    after 0 {error err1}
+    after 0 {error err2}
+    after 0 {error err3}
+    update
+    return $errRes
+} {err1 err2 err3}
+test event-7.3 {bgerror / accumulation / break} {
+    set errRes {}
+    proc bgerror {err} {
+	global errRes
+	lappend errRes $err
+	return -code break "skip!"
+    }
+    after 0 {error err1}
+    after 0 {error err2}
+    after 0 {error err3}
+    update
+    return $errRes
+} err1
+test event-7.4 {tkerror is nothing special anymore to tcl} -body {
+    set errRes {}
+    # we don't just rename bgerror to empty because it could then
+    # be autoloaded...
+    proc bgerror {err} {
+	global errRes
+	lappend errRes "bg:$err"
+    }
+    proc tkerror {err} {
+	global errRes
+	lappend errRes "tk:$err"
+    }
+    after 0 {error err1}
+    update
+    return $errRes
+} -cleanup {
+    rename tkerror {}
+} -result bg:err1
+test event-7.5 {correct behaviour when there is no bgerror [Bug 219142]} -body {
+    exec [interpreter] << {
+	after 1000 error hello
+	after 2000 set a 0
+	vwait a
+    }
+} -constraints {exec} -returnCodes error -result {hello
+    while executing
+"error hello"
+    ("after" script)}
+test event-7.6 {safe hidden bgerror fallback} -setup {
+    variable result {}
+    interp create -safe safe
+} -body {
+    safe alias puts puts
+    safe alias result ::append [namespace which -variable result]
+    safe eval {proc bgerror m {result $m\n$::errorCode\n$::errorInfo\n}}
+    safe hide bgerror
+    safe eval after 0 error foo
+    update
+    return $result
+} -cleanup {
+    interp delete safe
+} -result {foo
+NONE
+foo
+    while executing
+"error foo"
+    ("after" script)
+}
+test event-7.7 {safe hidden bgerror fallback} -setup {
+    variable result {}
+    interp create -safe safe
+} -body {
+    safe alias puts puts
+    safe alias result ::append [namespace which -variable result]
+    safe eval {proc bgerror m {result $m\n$::errorCode\n$::errorInfo\n}}
+    safe hide bgerror
+    safe eval {proc bgerror m {error bar soom baz}}
+    safe eval after 0 error foo
+    update
+    return $result
+} -cleanup {
+    interp delete safe
+} -result {foo
+NONE
+foo
+    while executing
+"error foo"
+    ("after" script)
+}
+
+# someday : add a test checking that when there is no bgerror, an error msg
+# goes to stderr ideally one would use sub interp and transfer a fake stderr
+# to it, unfortunatly the current interp tcl API does not allow that. The
+# other option would be to use fork a test but it then becomes more a
+# file/exec test than a bgerror test.
+
+# end of bgerror tests
+catch {rename bgerror {}}
+
+test event-8.1 {Tcl_CreateExitHandler procedure} {stdio testexithandler} {
+    set child [open |[list [interpreter]] r+]
+    puts $child "catch {load $::tcltestlib Tcltest}"
+    puts $child "testexithandler create 41; testexithandler create 4"
+    puts $child "testexithandler create 6; exit"
+    flush $child
+    set result [read $child]
+    close $child
+    return $result
+} {even 6
+even 4
+odd 41
+}
+
+test event-9.1 {Tcl_DeleteExitHandler procedure} {stdio testexithandler} {
+    set child [open |[list [interpreter]] r+]
+    puts $child "catch {load $::tcltestlib Tcltest}"
+    puts $child "testexithandler create 41; testexithandler create 4"
+    puts $child "testexithandler create 6; testexithandler delete 41"
+    puts $child "testexithandler create 16; exit"
+    flush $child
+    set result [read $child]
+    close $child
+    return $result
+} {even 16
+even 6
+even 4
+}
+test event-9.2 {Tcl_DeleteExitHandler procedure} {stdio testexithandler} {
+    set child [open |[list [interpreter]] r+]
+    puts $child "catch {load $::tcltestlib Tcltest}"
+    puts $child "testexithandler create 41; testexithandler create 4"
+    puts $child "testexithandler create 6; testexithandler delete 4"
+    puts $child "testexithandler create 16; exit"
+    flush $child
+    set result [read $child]
+    close $child
+    return $result
+} {even 16
+even 6
+odd 41
+}
+test event-9.3 {Tcl_DeleteExitHandler procedure} {stdio testexithandler} {
+    set child [open |[list [interpreter]] r+]
+    puts $child "catch {load $::tcltestlib Tcltest}"
+    puts $child "testexithandler create 41; testexithandler create 4"
+    puts $child "testexithandler create 6; testexithandler delete 6"
+    puts $child "testexithandler create 16; exit"
+    flush $child
+    set result [read $child]
+    close $child
+    return $result
+} {even 16
+even 4
+odd 41
+}
+test event-9.4 {Tcl_DeleteExitHandler procedure} {stdio testexithandler} {
+    set child [open |[list [interpreter]] r+]
+    puts $child "catch {load $::tcltestlib Tcltest}"
+    puts $child "testexithandler create 41; testexithandler delete 41"
+    puts $child "testexithandler create 16; exit"
+    flush $child
+    set result [read $child]
+    close $child
+    return $result
+} {even 16
+}
+
+test event-10.1 {Tcl_Exit procedure} {stdio} {
+    set child [open |[list [interpreter]] r+]
+    puts $child "exit 3"
+    list [catch {close $child} msg] $msg [lindex $::errorCode 0] \
+        [lindex $::errorCode 2]
+} {1 {child process exited abnormally} CHILDSTATUS 3}
+
+test event-11.1 {Tcl_VwaitCmd procedure} -returnCodes error -body {
+    vwait
+} -result {wrong # args: should be "vwait name"}
+test event-11.2 {Tcl_VwaitCmd procedure} -returnCodes error -body {
+    vwait a b
+} -result {wrong # args: should be "vwait name"}
+test event-11.3 {Tcl_VwaitCmd procedure} -setup {
+    catch {unset x}
+} -body {
+    set x 1
+    vwait x(1)
+} -returnCodes error -result {can't trace "x(1)": variable isn't array}
+test event-11.4 {Tcl_VwaitCmd procedure} -setup {
+    foreach i [after info] {
+	after cancel $i
+    }
+    after 10; update; # On Mac make sure update won't take long
+} -body {
+    after 100 {set x x-done}
+    after 200 {set y y-done}
+    after 300 {set z z-done}
+    after idle {set q q-done}
+    set x before
+    set y before
+    set z before
+    set q before
+    list [vwait y] $x $y $z $q
+} -cleanup {
+    foreach i [after info] {
+	after cancel $i
+    }
+} -result {{} x-done y-done before q-done}
+test event-11.5 {Tcl_VwaitCmd procedure: round robin scheduling, 2 sources} -setup {
+    set test1file [makeFile "" test1]
+} -constraints {socket} -body {
+    set f1 [open $test1file w]
+    proc accept {s args} {
+	puts $s foobar
+	close $s
+    }
+    set s1 [socket -server accept -myaddr 127.0.0.1 0]
+    after 1000
+    set s2 [socket 127.0.0.1 [lindex [fconfigure $s1 -sockname] 2]]
+    close $s1
+    set x 0
+    set y 0
+    set z 0
+    fileevent $s2 readable {incr z}
+    vwait z
+    fileevent $f1 writable {incr x; if {$y == 3} {set z done}}
+    fileevent $s2 readable {incr y; if {$x == 3} {set z done}}
+    vwait z
+    close $f1
+    close $s2
+    list $x $y $z
+} -cleanup {
+    removeFile $test1file
+} -result {3 3 done}
+test event-11.6 {Tcl_VwaitCmd procedure: round robin scheduling, same source} {
+    set test1file [makeFile "" test1]
+    set test2file [makeFile "" test2]
+    set f1 [open $test1file w]
+    set f2 [open $test2file w]
+    set x 0
+    set y 0
+    set z 0
+    update
+    fileevent $f1 writable {incr x; if {$y == 3} {set z done}}
+    fileevent $f2 writable {incr y; if {$x == 3} {set z done}}
+    vwait z
+    close $f1
+    close $f2
+    removeFile $test1file
+    removeFile $test2file
+    list $x $y $z
+} {3 3 done}
+test event-11.7 {Bug 16828b3744} {
+    after idle {
+	set ::t::v 1
+	namespace delete ::t
+    }
+    namespace eval ::t {
+	vwait ::t::v
+    }
+} {}
+test event-11.8 {Bug 16828b3744} -setup {
+    oo::class create A {
+	variable continue
+    
+	method start {} {
+           after idle [self] destroy
+        
+           set continue 0
+           vwait [namespace current]::continue
+	}
+	destructor {
+           set continue 1
+	}	
+    }
+} -body {
+    [A new] start
+} -cleanup {
+    A destroy
+} -result {}
+
+test event-12.1 {Tcl_UpdateCmd procedure} -returnCodes error -body {
+    update a b
+} -result {wrong # args: should be "update ?idletasks?"}
+test event-12.2 {Tcl_UpdateCmd procedure} -returnCodes error -body {
+    update bogus
+} -result {bad option "bogus": must be idletasks}
+test event-12.3 {Tcl_UpdateCmd procedure} -setup {
+    foreach i [after info] {
+	after cancel $i
+    }
+} -body {
+    after 500 {set x after}
+    after idle {set y after}
+    after idle {set z "after, y = $y"}
+    set x before
+    set y before
+    set z before
+    update idletasks
+    list $x $y $z
+} -cleanup {
+    foreach i [after info] {
+	after cancel $i
+    }
+} -result {before after {after, y = after}}
+test event-12.4 {Tcl_UpdateCmd procedure} -setup {
+    foreach i [after info] {
+	after cancel $i
+    }
+} -body {
+    after 10; update; # On Mac make sure update won't take long
+    after 200 {set x x-done}
+    after 600 {set y y-done}
+    after idle {set z z-done}
+    set x before
+    set y before
+    set z before
+    after 300
+    update
+    list $x $y $z
+} -cleanup {
+    foreach i [after info] {
+	after cancel $i
+    }
+} -result {x-done before z-done}
+
+test event-13.1 {Tcl_WaitForFile procedure, readable} -setup {
+    foreach i [after info] {
+	after cancel $i
+    }
+    testfilehandler close
+} -constraints {testfilehandler} -body {
+    after 100 set x timeout
+    testfilehandler create 1 off off
+    set x "no timeout"
+    set result [testfilehandler wait 1 readable 0]
+    update
+    list $result $x
+} -cleanup {
+    testfilehandler close
+    foreach i [after info] {
+	after cancel $i
+    }
+} -result {{} {no timeout}}
+test event-13.2 {Tcl_WaitForFile procedure, readable} -setup {
+    foreach i [after info] {
+	after cancel $i
+    }
+    testfilehandler close
+} -constraints testfilehandler -body {
+    after 100 set x timeout
+    testfilehandler create 1 off off
+    set x "no timeout"
+    set result [testfilehandler wait 1 readable 100]
+    update
+    list $result $x
+} -cleanup {
+    testfilehandler close
+    foreach i [after info] {
+	after cancel $i
+    }
+} -result {{} timeout}
+test event-13.3 {Tcl_WaitForFile procedure, readable} -setup {
+    foreach i [after info] {
+	after cancel $i
+    }
+    testfilehandler close
+} -constraints testfilehandler -body {
+    after 100 set x timeout
+    testfilehandler create 1 off off
+    testfilehandler fillpartial 1
+    set x "no timeout"
+    set result [testfilehandler wait 1 readable 100]
+    update
+    list $result $x
+} -cleanup {
+    testfilehandler close
+    foreach i [after info] {
+	after cancel $i
+    }
+} -result {readable {no timeout}}
+test event-13.4 {Tcl_WaitForFile procedure, writable} -setup {
+    foreach i [after info] {
+	after cancel $i
+    }
+    testfilehandler close
+} -constraints {testfilehandler nonPortable} -body {
+    after 100 set x timeout
+    testfilehandler create 1 off off
+    testfilehandler fill 1
+    set x "no timeout"
+    set result [testfilehandler wait 1 writable 0]
+    update
+    list $result $x
+} -cleanup {
+    testfilehandler close
+    foreach i [after info] {
+	after cancel $i
+    }
+} -result {{} {no timeout}}
+test event-13.5 {Tcl_WaitForFile procedure, writable} -setup {
+    foreach i [after info] {
+	after cancel $i
+    }
+    testfilehandler close
+} -constraints {testfilehandler nonPortable} -body {
+    after 100 set x timeout
+    testfilehandler create 1 off off
+    testfilehandler fill 1
+    set x "no timeout"
+    set result [testfilehandler wait 1 writable 100]
+    update
+    list $result $x
+} -cleanup {
+    testfilehandler close
+    foreach i [after info] {
+	after cancel $i
+    }
+} -result {{} timeout}
+test event-13.6 {Tcl_WaitForFile procedure, writable} -setup {
+    foreach i [after info] {
+	after cancel $i
+    }
+    testfilehandler close
+} -constraints testfilehandler -body {
+    after 100 set x timeout
+    testfilehandler create 1 off off
+    set x "no timeout"
+    set result [testfilehandler wait 1 writable 100]
+    update
+    list $result $x
+} -cleanup {
+    testfilehandler close
+    foreach i [after info] {
+	after cancel $i
+    }
+} -result {writable {no timeout}}
+test event-13.7 {Tcl_WaitForFile procedure, don't call other event handlers} -setup {
+    foreach i [after info] {
+	after cancel $i
+    }
+    testfilehandler close
+} -constraints testfilehandler -body {
+    after 100 lappend x timeout
+    after idle lappend x idle
+    testfilehandler create 1 off off
+    set x ""
+    set result [list [testfilehandler wait 1 readable 200] $x]
+    update
+    lappend result $x
+} -cleanup {
+    testfilehandler close
+    foreach i [after info] {
+	after cancel $i
+    }
+} -result {{} {} {timeout idle}}
+test event-13.8 {Tcl_WaitForFile procedure, waiting indefinitely} testfilewait {
+    set f [open "|sleep 2" r]
+    set result ""
+    lappend result [testfilewait $f readable 100]
+    lappend result [testfilewait $f readable -1]
+    close $f
+    return $result
+} {{} readable}
+
+test event-14.1 {Tcl_WaitForFile procedure, readable, big fd} -setup {
+    set chanList {}
+    for {set i 0} {$i < 32} {incr i} {
+	lappend chanList [open /dev/null r]
+    }
+    foreach i [after info] {after cancel $i}
+    testfilehandler close
+} -constraints {testfilehandler unix} -body {
+    after 100 set x timeout
+    testfilehandler create 1 off off
+    set x "no timeout"
+    set result [testfilehandler wait 1 readable 0]
+    update
+    list $result $x
+} -cleanup {
+    testfilehandler close
+    foreach chan $chanList {close $chan}
+    foreach i [after info] {after cancel $i}
+} -result {{} {no timeout}}
+test event-14.2 {Tcl_WaitForFile procedure, readable, big fd} -setup {
+    set chanList {}
+    for {set i 0} {$i < 32} {incr i} {
+	lappend chanList [open /dev/null r]
+    }
+    foreach i [after info] {after cancel $i}
+    testfilehandler close
+} -constraints {testfilehandler unix} -body {
+    after 100 set x timeout
+    testfilehandler create 1 off off
+    set x "no timeout"
+    set result [testfilehandler wait 1 readable 100]
+    update
+    list $result $x
+} -cleanup {
+    testfilehandler close
+    foreach chan $chanList {close $chan}
+    foreach i [after info] {after cancel $i}
+} -result {{} timeout}
+test event-14.3 {Tcl_WaitForFile procedure, readable, big fd} -setup {
+    set chanList {}
+    for {set i 0} {$i < 32} {incr i} {
+	lappend chanList [open /dev/null r]
+    }
+    foreach i [after info] {after cancel $i}
+    testfilehandler close
+} -constraints {testfilehandler unix} -body {
+    after 100 set x timeout
+    testfilehandler create 1 off off
+    testfilehandler fillpartial 1
+    set x "no timeout"
+    set result [testfilehandler wait 1 readable 100]
+    update
+    list $result $x
+} -cleanup {
+    testfilehandler close
+    foreach chan $chanList {close $chan}
+    foreach i [after info] {after cancel $i}
+} -result {readable {no timeout}}
+test event-14.4 {Tcl_WaitForFile procedure, writable, big fd} -setup {
+    set chanList {}
+    for {set i 0} {$i < 32} {incr i} {
+	lappend chanList [open /dev/null r]
+    }
+    foreach i [after info] {after cancel $i}
+    testfilehandler close
+} -constraints {testfilehandler unix nonPortable} -body {
+    after 100 set x timeout
+    testfilehandler create 1 off off
+    testfilehandler fill 1
+    set x "no timeout"
+    set result [testfilehandler wait 1 writable 0]
+    update
+    list $result $x
+} -cleanup {
+    testfilehandler close
+    foreach chan $chanList {close $chan}
+    foreach i [after info] {after cancel $i}
+} -result {{} {no timeout}}
+test event-14.5 {Tcl_WaitForFile procedure, writable, big fd} -setup {
+    set chanList {}
+    for {set i 0} {$i < 32} {incr i} {
+	lappend chanList [open /dev/null r]
+    }
+    foreach i [after info] {after cancel $i}
+    testfilehandler close
+} -constraints {testfilehandler unix nonPortable} -body {
+    after 100 set x timeout
+    testfilehandler create 1 off off
+    testfilehandler fill 1
+    set x "no timeout"
+    set result [testfilehandler wait 1 writable 100]
+    update
+    list $result $x
+} -cleanup {
+    testfilehandler close
+    foreach chan $chanList {close $chan}
+    foreach i [after info] {after cancel $i}
+} -result {{} timeout}
+test event-14.6 {Tcl_WaitForFile procedure, writable, big fd} -setup {
+    set chanList {}
+    for {set i 0} {$i < 32} {incr i} {
+	lappend chanList [open /dev/null r]
+    }
+    foreach i [after info] {after cancel $i}
+    testfilehandler close
+} -constraints {testfilehandler unix} -body {
+    after 100 set x timeout
+    testfilehandler create 1 off off
+    set x "no timeout"
+    set result [testfilehandler wait 1 writable 100]
+    update
+    list $result $x
+} -cleanup {
+    testfilehandler close
+    foreach chan $chanList {close $chan}
+    foreach i [after info] {after cancel $i}
+} -result {writable {no timeout}}
+test event-14.7 {Tcl_WaitForFile, don't call other event handlers, big fd} -setup {
+    set chanList {}
+    for {set i 0} {$i < 32} {incr i} {
+	lappend chanList [open /dev/null r]
+    }
+    foreach i [after info] {after cancel $i}
+    testfilehandler close
+} -constraints {testfilehandler unix} -body {
+    after 100 lappend x timeout
+    after idle lappend x idle
+    testfilehandler create 1 off off
+    set x ""
+    set result [list [testfilehandler wait 1 readable 200] $x]
+    update
+    lappend result $x
+} -cleanup {
+    testfilehandler close
+    foreach chan $chanList {close $chan}
+    foreach i [after info] {after cancel $i}
+} -result {{} {} {timeout idle}}
+test event-14.8 {Tcl_WaitForFile procedure, waiting indefinitely, big fd} -setup {
+    set chanList {}
+    for {set i 0} {$i < 32} {incr i} {
+	lappend chanList [open /dev/null r]
+    }
+} -constraints {testfilewait unix} -body {
+    set f [open "|sleep 2" r]
+    set result ""
+    lappend result [testfilewait $f readable 100]
+    lappend result [testfilewait $f readable -1]
+    close $f
+    return $result
+} -cleanup {
+    foreach chan $chanList {close $chan}
+} -result {{} readable}
+
+# cleanup
+foreach i [after info] {
+    after cancel $i
+}
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/tests/exec.test b/tests/exec.test
new file mode 100644
index 0000000..38927d3
--- /dev/null
+++ b/tests/exec.test
@@ -0,0 +1,715 @@
+# Commands covered:  exec
+#
+# This file contains a collection of tests for one or more of the Tcl built-in
+# commands. Sourcing this file into Tcl runs the tests and generates output
+# for errors. No output means no errors were found.
+#
+# Copyright (c) 1991-1994 The Regents of the University of California.
+# Copyright (c) 1994-1997 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution of
+# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+package require tcltest 2
+namespace import -force ::tcltest::*
+
+# All tests require the "exec" command.
+# Skip them if exec is not defined.
+testConstraint exec [llength [info commands exec]]
+unset -nocomplain path
+
+# Utilities that are like bourne shell stalwarts, but cross-platform.
+set path(echo) [makeFile {
+    puts -nonewline [lindex $argv 0]
+    foreach str [lrange $argv 1 end] {
+	puts -nonewline " $str"
+    }
+    puts {}
+    exit
+} echo]
+set path(echo2) [makeFile {
+    puts stdout [join $argv]
+    puts stderr [lindex $argv 1]
+    exit
+} echo2]
+set path(cat) [makeFile {
+    if {$argv eq ""} {
+	set argv -
+    }
+    fconfigure stdout -translation binary
+    foreach name $argv {
+	if {$name eq "-"} {
+	    set f stdin
+	} elseif {[catch {open $name r} f] != 0} {
+	    puts stderr $f
+	    continue
+	}
+	fconfigure $f -translation binary
+	while {[eof $f] == 0} {
+	    puts -nonewline [read $f]
+	}
+	if {$f ne "stdin"} {
+	    close $f
+	}
+    }
+    exit
+} cat]
+set path(wc) [makeFile {
+    set data [read stdin]
+    set lines [regsub -all "\n" $data {} dummy]
+    set words [regsub -all "\[^ \t\n]+" $data {} dummy]
+    set chars [string length $data]
+    puts [format "%8.d%8.d%8.d" $lines $words $chars]
+    exit
+} wc]
+set path(sh) [makeFile {
+    if {[lindex $argv 0] ne "-c"} {
+	error "sh: unexpected arguments $argv"
+    }
+    set cmd [lindex $argv 1]
+    lappend cmd ";"
+    set newcmd {}
+    foreach arg $cmd {
+	if {$arg eq ";"} {
+	    exec >@stdout 2>@stderr [info nameofexecutable] {*}$newcmd
+	    set newcmd {}
+	    continue
+	}
+	if {$arg eq "1>&2"} {
+	    set arg >@stderr
+	}
+	lappend newcmd $arg
+    }
+    exit
+} sh]
+set path(sh2) [makeFile {
+    if {[lindex $argv 0] ne "-c"} {
+	error "sh: unexpected arguments $argv"
+    }
+    set cmd [lindex $argv 1]
+    lappend cmd ";"
+    set newcmd {}
+    foreach arg $cmd {
+	if {$arg eq ";"} {
+	    exec -ignorestderr >@stdout [info nameofexecutable] {*}$newcmd
+	    set newcmd {}
+	    continue
+	}
+	lappend newcmd $arg
+    }
+    exit
+} sh2]
+set path(sleep) [makeFile {
+    after [expr $argv*1000]
+    exit
+} sleep]
+set path(exit) [makeFile {
+    exit $argv
+} exit]
+
+proc readfile filename {
+    set f [open $filename]
+    set d [read $f]
+    close $f
+    return [string trimright $d \n]
+}
+
+# ----------------------------------------------------------------------
+# Basic operations.
+
+test exec-1.1 {basic exec operation} {exec} {
+    exec [interpreter] $path(echo) a b c
+} "a b c"
+test exec-1.2 {pipelining} {exec stdio} {
+    exec [interpreter] $path(echo) a b c d | [interpreter] $path(cat) | [interpreter] $path(cat)
+} "a b c d"
+test exec-1.3 {pipelining} {exec stdio} {
+    set a [exec [interpreter] $path(echo) a b c d | [interpreter] $path(cat) | [interpreter] $path(wc)]
+    list [scan $a "%d %d %d" b c d] $b $c
+} {3 1 4}
+set arg {12345678901234567890123456789012345678901234567890}
+set arg "$arg$arg$arg$arg$arg$arg"
+test exec-1.4 {long command lines} {exec} {
+    exec [interpreter] $path(echo) $arg
+} $arg
+set arg {}
+
+# I/O redirection: input from Tcl command.
+
+test exec-2.1 {redirecting input from immediate source} {exec stdio} {
+    exec [interpreter] $path(cat) << "Sample text"
+} {Sample text}
+test exec-2.2 {redirecting input from immediate source} {exec stdio} {
+    exec << "Sample text" [interpreter] $path(cat) | [interpreter] $path(cat)
+} {Sample text}
+test exec-2.3 {redirecting input from immediate source} {exec stdio} {
+    exec [interpreter] $path(cat) << "Sample text" | [interpreter] $path(cat)
+} {Sample text}
+test exec-2.4 {redirecting input from immediate source} {exec stdio} {
+    exec [interpreter] $path(cat) | [interpreter] $path(cat) << "Sample text"
+} {Sample text}
+test exec-2.5 {redirecting input from immediate source} {exec} {
+    exec [interpreter] $path(cat) "<<Joined to arrows"
+} {Joined to arrows}
+test exec-2.6 {redirecting input from immediate source, with UTF} -setup {
+    set sysenc [encoding system]
+    encoding system iso8859-1
+    proc quotenonascii s {
+	regsub -all {\[|\\|\]} $s {\\&} s
+	regsub -all "\[\u007f-\uffff\]" $s \
+	    {[apply {c {format {\u%04x} [scan $c %c]}} &]} s
+	return [subst -novariables $s]
+    }
+} -constraints {exec} -body {
+    # If this fails, it may give back: "\uC3\uA9\uC3\uA0\uC3\uBC\uC3\uB1"
+    # If it does, this means that the UTF -> external conversion did not occur
+    # before writing out the temp file.
+    quotenonascii [exec [interpreter] $path(cat) << "\uE9\uE0\uFC\uF1"]
+} -cleanup {
+    encoding system $sysenc
+    rename quotenonascii {}
+} -result {\u00e9\u00e0\u00fc\u00f1}
+
+# I/O redirection: output to file.
+
+set path(gorp.file) [makeFile {} gorp.file]
+file delete $path(gorp.file)
+
+test exec-3.1 {redirecting output to file} {exec} {
+    exec [interpreter] $path(echo) "Some simple words" > $path(gorp.file)
+    exec [interpreter] $path(cat) $path(gorp.file)
+} "Some simple words"
+test exec-3.2 {redirecting output to file} {exec stdio} {
+    exec [interpreter] $path(echo) "More simple words" | >$path(gorp.file) [interpreter] $path(cat) | [interpreter] $path(cat)
+    exec [interpreter] $path(cat) $path(gorp.file)
+} "More simple words"
+test exec-3.3 {redirecting output to file} {exec stdio} {
+    exec > $path(gorp.file) [interpreter] $path(echo) "Different simple words" | [interpreter] $path(cat) | [interpreter] $path(cat)
+    exec [interpreter] $path(cat) $path(gorp.file)
+} "Different simple words"
+test exec-3.4 {redirecting output to file} {exec} {
+    exec [interpreter] $path(echo) "Some simple words" >$path(gorp.file)
+    exec [interpreter] $path(cat) $path(gorp.file)
+} "Some simple words"
+test exec-3.5 {redirecting output to file} {exec} {
+    exec [interpreter] $path(echo) "First line" >$path(gorp.file)
+    exec [interpreter] $path(echo) "Second line" >> $path(gorp.file)
+    exec [interpreter] $path(cat) $path(gorp.file)
+} "First line\nSecond line"
+test exec-3.6 {redirecting output to file} {exec} {
+    exec [interpreter] $path(echo) "First line" >$path(gorp.file)
+    exec [interpreter] $path(echo) "Second line" >>$path(gorp.file)
+    exec [interpreter] $path(cat) $path(gorp.file)
+} "First line\nSecond line"
+test exec-3.7 {redirecting output to file} {exec} {
+    set f [open $path(gorp.file) w]
+    puts $f "Line 1"
+    flush $f
+    exec [interpreter] $path(echo) "More text" >@ $f
+    exec [interpreter] $path(echo) >@$f "Even more"
+    puts $f "Line 3"
+    close $f
+    exec [interpreter] $path(cat) $path(gorp.file)
+} "Line 1\nMore text\nEven more\nLine 3"
+
+# I/O redirection: output and stderr to file.
+
+file delete $path(gorp.file)
+
+test exec-4.1 {redirecting output and stderr to file} {exec} {
+    exec [interpreter] $path(echo) "test output" >& $path(gorp.file)
+    exec [interpreter] $path(cat) $path(gorp.file)
+} "test output"
+test exec-4.2 {redirecting output and stderr to file} {exec} {
+    list [exec [interpreter] $path(sh) -c "\"$path(echo)\" foo bar 1>&2" >&$path(gorp.file)] \
+	    [exec [interpreter] $path(cat) $path(gorp.file)]
+} {{} {foo bar}}
+test exec-4.3 {redirecting output and stderr to file} {exec} {
+    exec [interpreter] $path(echo) "first line" > $path(gorp.file)
+    list [exec [interpreter] $path(sh) -c "\"$path(echo)\" foo bar 1>&2" >>&$path(gorp.file)] \
+	    [exec [interpreter] $path(cat) $path(gorp.file)]
+} "{} {first line\nfoo bar}"
+test exec-4.4 {redirecting output and stderr to file} {exec} {
+    set f [open $path(gorp.file) w]
+    puts $f "Line 1"
+    flush $f
+    exec [interpreter] $path(echo) "More text" >&@ $f
+    exec [interpreter] $path(echo) >&@$f "Even more"
+    puts $f "Line 3"
+    close $f
+    exec [interpreter] $path(cat) $path(gorp.file)
+} "Line 1\nMore text\nEven more\nLine 3"
+test exec-4.5 {redirecting output and stderr to file} {exec} {
+    set f [open $path(gorp.file) w]
+    puts $f "Line 1"
+    flush $f
+    exec >&@ $f [interpreter] $path(sh) -c "\"$path(echo)\" foo bar 1>&2"
+    exec >&@$f [interpreter] $path(sh) -c "\"$path(echo)\" xyzzy 1>&2"
+    puts $f "Line 3"
+    close $f
+    exec [interpreter] $path(cat) $path(gorp.file)
+} "Line 1\nfoo bar\nxyzzy\nLine 3"
+
+# I/O redirection: input from file.
+
+if {[testConstraint exec]} {
+    exec [interpreter] $path(echo) "Just a few thoughts" > $path(gorp.file)
+}
+test exec-5.1 {redirecting input from file} {exec} {
+    exec [interpreter] $path(cat) < $path(gorp.file)
+} {Just a few thoughts}
+test exec-5.2 {redirecting input from file} {exec stdio} {
+    exec [interpreter] $path(cat) | [interpreter] $path(cat) < $path(gorp.file)
+} {Just a few thoughts}
+test exec-5.3 {redirecting input from file} {exec stdio} {
+    exec [interpreter] $path(cat) < $path(gorp.file) | [interpreter] $path(cat)
+} {Just a few thoughts}
+test exec-5.4 {redirecting input from file} {exec stdio} {
+    exec < $path(gorp.file) [interpreter] $path(cat) | [interpreter] $path(cat)
+} {Just a few thoughts}
+test exec-5.5 {redirecting input from file} {exec} {
+    exec [interpreter] $path(cat) <$path(gorp.file)
+} {Just a few thoughts}
+test exec-5.6 {redirecting input from file} -constraints {exec} -body {
+    set f [open $path(gorp.file) r]
+    exec [interpreter] $path(cat) <@ $f
+} -cleanup {
+    close $f
+} -result {Just a few thoughts}
+test exec-5.7 {redirecting input from file} -constraints {exec} -body {
+    set f [open $path(gorp.file) r]
+    exec <@$f [interpreter] $path(cat)
+} -cleanup {
+    close $f
+} -result {Just a few thoughts}
+
+# I/O redirection: standard error through a pipeline.
+
+test exec-6.1 {redirecting stderr through a pipeline} {exec stdio} {
+    exec [interpreter] $path(sh) -c "\"$path(echo)\" foo bar" |& [interpreter] $path(cat)
+} "foo bar"
+test exec-6.2 {redirecting stderr through a pipeline} {exec stdio} {
+    exec [interpreter] $path(sh) -c "\"$path(echo)\" foo bar 1>&2" |& [interpreter] $path(cat)
+} "foo bar"
+test exec-6.3 {redirecting stderr through a pipeline} {exec stdio} {
+    exec [interpreter] $path(sh) -c "\"$path(echo)\" foo bar 1>&2" \
+	|& [interpreter] $path(sh) -c "\"$path(echo)\" second msg 1>&2 ; \"$path(cat)\"" |& [interpreter] $path(cat)
+} "second msg\nfoo bar"
+
+# I/O redirection: combinations.
+
+set path(gorp.file2) [makeFile {} gorp.file2]
+file delete $path(gorp.file2)
+
+test exec-7.1 {multiple I/O redirections} {exec} {
+    exec << "command input" > $path(gorp.file2) [interpreter] $path(cat) < $path(gorp.file)
+    exec [interpreter] $path(cat) $path(gorp.file2)
+} {Just a few thoughts}
+test exec-7.2 {multiple I/O redirections} {exec} {
+    exec < $path(gorp.file) << "command input" [interpreter] $path(cat)
+} {command input}
+
+# Long input to command and output from command.
+set a "0123456789 xxxxxxxxx abcdefghi ABCDEFGHIJK\n"
+set a [concat $a $a $a $a]
+set a [concat $a $a $a $a]
+set a [concat $a $a $a $a]
+set a [concat $a $a $a $a]
+test exec-8.1 {long input and output} {exec} {
+    exec [interpreter] $path(cat) << $a
+} $a
+# More than 20 arguments to exec.
+test exec-8.2 {long input and output} {exec} {
+    exec [interpreter] $path(echo) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
+} {1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23}
+
+# Commands that return errors.
+
+test exec-9.1 {commands returning errors} {exec} {
+    set x [catch {exec gorp456} msg]
+    list $x [string tolower $msg] [string tolower $errorCode]
+} {1 {couldn't execute "gorp456": no such file or directory} {posix enoent {no such file or directory}}}
+test exec-9.2 {commands returning errors} {exec} {
+    string tolower [list [catch {exec [interpreter] echo foo | foo123} msg] $msg $errorCode]
+} {1 {couldn't execute "foo123": no such file or directory} {posix enoent {no such file or directory}}}
+test exec-9.3 {commands returning errors} -constraints {exec stdio} -body {
+    exec [interpreter] $path(sleep) 1 | [interpreter] $path(exit) 43 | [interpreter] $path(sleep) 1
+} -returnCodes error -result {child process exited abnormally}
+test exec-9.4 {commands returning errors} -constraints {exec stdio} -body {
+    exec [interpreter] $path(exit) 43 | [interpreter] $path(echo) "foo bar"
+} -returnCodes error -result {foo bar
+child process exited abnormally}
+test exec-9.5 {commands returning errors} -constraints {exec stdio} -body {
+    exec gorp456 | [interpreter] echo a b c
+} -returnCodes error -result {couldn't execute "gorp456": no such file or directory}
+test exec-9.6 {commands returning errors} -constraints {exec} -body {
+    exec [interpreter] $path(sh) -c "\"$path(echo)\" error msg 1>&2"
+} -returnCodes error -result {error msg}
+test exec-9.7 {commands returning errors} -constraints {exec stdio nonPortable} -body {
+    # This test can fail easily on multiprocessor machines
+    exec [interpreter] $path(sh) -c "\"$path(echo)\" error msg 1>&2 ; \"$path(sleep)\" 1" \
+	| [interpreter] $path(sh) -c "\"$path(echo)\" error msg 1>&2 ; \"$path(sleep)\" 1"
+} -returnCodes error -result {error msg
+error msg}
+set path(err) [makeFile {} err]
+test exec-9.8 {commands returning errors} -constraints {exec} -setup {
+    set f [open $path(err) w]
+    puts $f {
+	puts stdout out
+	puts stderr err
+    }
+    close $f
+} -body {
+    exec [interpreter] $path(err)
+} -returnCodes error -result {out
+err}
+
+# Errors in executing the Tcl command, as opposed to errors in the processes
+# that are invoked.
+
+test exec-10.1 {errors in exec invocation} -constraints {exec} -body {
+    exec
+} -returnCodes error -result {wrong # args: should be "exec ?-option ...? arg ?arg ...?"}
+test exec-10.2 {errors in exec invocation} -constraints {exec} -body {
+    exec | cat
+} -returnCodes error -result {illegal use of | or |& in command}
+test exec-10.3 {errors in exec invocation} -constraints {exec} -body {
+    exec cat |
+} -returnCodes error -result {illegal use of | or |& in command}
+test exec-10.4 {errors in exec invocation} -constraints {exec} -body {
+    exec cat | | cat
+} -returnCodes error -result {illegal use of | or |& in command}
+test exec-10.5 {errors in exec invocation} -constraints {exec} -body {
+    exec cat | |& cat
+} -returnCodes error -result {illegal use of | or |& in command}
+test exec-10.6 {errors in exec invocation} -constraints {exec} -body {
+    exec cat |&
+} -returnCodes error -result {illegal use of | or |& in command}
+test exec-10.7 {errors in exec invocation} -constraints {exec} -body {
+    exec cat <
+} -returnCodes error -result {can't specify "<" as last word in command}
+test exec-10.8 {errors in exec invocation} -constraints {exec} -body {
+    exec cat >
+} -returnCodes error -result {can't specify ">" as last word in command}
+test exec-10.9 {errors in exec invocation} -constraints {exec} -body {
+    exec cat <<
+} -returnCodes error -result {can't specify "<<" as last word in command}
+test exec-10.10 {errors in exec invocation} -constraints {exec} -body {
+    exec cat >>
+} -returnCodes error -result {can't specify ">>" as last word in command}
+test exec-10.11 {errors in exec invocation} -constraints {exec} -body {
+    exec cat >&
+} -returnCodes error -result {can't specify ">&" as last word in command}
+test exec-10.12 {errors in exec invocation} -constraints {exec} -body {
+    exec cat >>&
+} -returnCodes error -result {can't specify ">>&" as last word in command}
+test exec-10.13 {errors in exec invocation} -constraints {exec} -body {
+    exec cat >@
+} -returnCodes error -result {can't specify ">@" as last word in command}
+test exec-10.14 {errors in exec invocation} -constraints {exec} -body {
+    exec cat <@
+} -returnCodes error -result {can't specify "<@" as last word in command}
+test exec-10.15 {errors in exec invocation} -constraints {exec} -body {
+    exec cat < a/b/c
+} -returnCodes error -result {couldn't read file "a/b/c": no such file or directory}
+test exec-10.16 {errors in exec invocation} -constraints {exec} -body {
+    exec cat << foo > a/b/c
+} -returnCodes error -result {couldn't write file "a/b/c": no such file or directory}
+test exec-10.17 {errors in exec invocation} -constraints {exec} -body {
+    exec cat << foo > a/b/c
+} -returnCodes error -result {couldn't write file "a/b/c": no such file or directory}
+set f [open $path(gorp.file) w]
+test exec-10.18 {errors in exec invocation} -constraints {exec} -body {
+    exec cat <@ $f
+} -returnCodes error -result "channel \"$f\" wasn't opened for reading"
+close $f
+set f [open $path(gorp.file) r]
+test exec-10.19 {errors in exec invocation} -constraints {exec} -body {
+    exec cat >@ $f
+} -returnCodes error -result "channel \"$f\" wasn't opened for writing"
+close $f
+test exec-10.20 {errors in exec invocation} -constraints {exec} -body {
+    exec ~non_existent_user/foo/bar
+} -returnCodes error -result {user "non_existent_user" doesn't exist}
+test exec-10.21 {errors in exec invocation} -constraints {exec} -body {
+    exec [interpreter] true | ~xyzzy_bad_user/x | false
+} -returnCodes error -result {user "xyzzy_bad_user" doesn't exist}
+test exec-10.22 {errors in exec invocation} -constraints exec -body {
+    exec echo test > ~non_existent_user/foo/bar
+} -returnCodes error -result {user "non_existent_user" doesn't exist}
+# Commands in background.
+
+test exec-11.1 {commands in background} {exec} {
+    set time [time {exec [interpreter] $path(sleep) 2 &}]
+    expr {[lindex $time 0] < 1000000}
+} 1
+test exec-11.2 {commands in background} -constraints {exec} -body {
+    exec [interpreter] $path(echo) a &b
+} -result {a &b}
+test exec-11.3 {commands in background} {exec} {
+    llength [exec [interpreter] $path(sleep) 1 &]
+} 1
+test exec-11.4 {commands in background} {exec stdio} {
+    llength [exec [interpreter] $path(sleep) 1 | [interpreter] $path(sleep) 1 | [interpreter] $path(sleep) 1 &]
+} 3
+test exec-11.5 {commands in background} {exec} {
+    set f [open $path(gorp.file) w]
+    puts $f [list catch [list exec [info nameofexecutable] $path(echo) foo &]]
+    close $f
+    exec [interpreter] $path(gorp.file)
+} foo
+
+# Make sure that background commands are properly reaped when they
+# eventually die.
+
+if {[testConstraint exec] && [testConstraint nonPortable]} {
+    after 1300
+    exec [interpreter] $path(sleep) 1
+}
+test exec-12.1 {reaping background processes} {exec unix nonPortable} {
+    for {set i 0} {$i < 20} {incr i} {
+	exec echo foo > /dev/null &
+    }
+    after 1000
+    catch {exec ps | fgrep "echo foo" | fgrep -v fgrep | wc} msg
+    lindex $msg 0
+} 0
+test exec-12.2 {reaping background processes} {exec unix nonPortable} {
+    exec sleep 2 | sleep 2 | sleep 2 &
+    catch {exec ps | fgrep -i "sleep" | fgrep -i -v fgrep | wc} msg
+    set x [lindex $msg 0]
+    after 3000
+    catch {exec ps | fgrep -i "sleep" | fgrep -i -v fgrep | wc} msg
+    list $x [lindex $msg 0]
+} {3 0}
+test exec-12.3 {reaping background processes} {exec unix nonPortable} {
+    exec sleep 1000 &
+    exec sleep 1000 &
+    set x [exec ps | fgrep "sleep" | fgrep -v fgrep]
+    set pids {}
+    foreach i [split $x \n] {
+	lappend pids [lindex $i 0]
+    }
+    foreach i $pids {
+	catch {exec kill -STOP $i}
+    }
+    catch {exec ps | fgrep "sleep" | fgrep -v fgrep | wc} msg
+    set x [lindex $msg 0]
+    foreach i $pids {
+	catch {exec kill -KILL $i}
+    }
+    catch {exec ps | fgrep "sleep" | fgrep -v fgrep | wc} msg
+    list $x [lindex $msg 0]
+} {2 0}
+
+# Make sure "errorCode" is set correctly.
+
+test exec-13.1 {setting errorCode variable} {exec} {
+    list [catch {exec [interpreter] $path(cat) < a/b/c} msg] [string tolower $errorCode]
+} {1 {posix enoent {no such file or directory}}}
+test exec-13.2 {setting errorCode variable} {exec} {
+    list [catch {exec [interpreter] $path(cat) > a/b/c} msg] [string tolower $errorCode]
+} {1 {posix enoent {no such file or directory}}}
+test exec-13.3 {setting errorCode variable} {exec} {
+    set x [catch {exec _weird_cmd_} msg]
+    list $x [string tolower $msg] [lindex $errorCode 0] \
+	    [string tolower [lrange $errorCode 2 end]]
+} {1 {couldn't execute "_weird_cmd_": no such file or directory} POSIX {{no such file or directory}}}
+test exec-13.4 {extended exit result codes} -setup {
+    set tmp [makeFile {exit 0x00000101} tmpfile.exec-13.4]
+} -constraints {win} -body {
+    list [catch {exec [interpreter] $tmp} err] [lreplace $::errorCode 1 1 {}]
+} -cleanup {
+    removeFile $tmp
+} -result {1 {CHILDSTATUS {} 257}}
+test exec-13.5 {extended exit result codes: max value} -setup {
+    set tmp [makeFile {exit 0x3fffffff} tmpfile.exec-13.5]
+} -constraints {win} -body {
+    list [catch {exec [interpreter] $tmp} err] [lreplace $::errorCode 1 1 {}]
+} -cleanup {
+    removeFile $tmp
+} -result {1 {CHILDSTATUS {} 1073741823}}
+test exec-13.6 {extended exit result codes: signalled} -setup {
+    set tmp [makeFile {exit 0xC0000016} tmpfile.exec-13.6]
+} -constraints {win} -body {
+    list [catch {exec [interpreter] $tmp} err] [lreplace $::errorCode 1 1 {}]
+} -cleanup {
+    removeFile $tmp
+} -result {1 {CHILDKILLED {} SIGABRT SIGABRT}}
+
+# Switches before the first argument
+
+test exec-14.1 {-keepnewline switch} {exec} {
+    exec -keepnewline [interpreter] $path(echo) foo
+} "foo\n"
+test exec-14.2 {-keepnewline switch} -constraints {exec} -body {
+    exec -keepnewline
+} -returnCodes error -result {wrong # args: should be "exec ?-option ...? arg ?arg ...?"}
+test exec-14.3 {unknown switch} -constraints {exec} -body {
+    exec -gorp
+} -returnCodes error -result {bad option "-gorp": must be -ignorestderr, -keepnewline, or --}
+test exec-14.4 {-- switch} -constraints {exec} -body {
+    exec -- -gorp
+} -returnCodes error -result {couldn't execute "-gorp": no such file or directory}
+test exec-14.5 {-ignorestderr switch} {exec} {
+    # Alas, the use of -ignorestderr is buried here :-(
+    exec [interpreter] $path(sh2) -c [list $path(echo2) foo bar] 2>@1
+} "foo bar\nbar"
+
+# Redirecting standard error separately from standard output
+
+test exec-15.1 {standard error redirection} {exec} {
+    exec [interpreter] $path(echo) "First line" > $path(gorp.file)
+    list [exec [interpreter] $path(sh) -c "\"$path(echo)\" foo bar 1>&2" 2> $path(gorp.file)] \
+	    [exec [interpreter] $path(cat) $path(gorp.file)]
+} {{} {foo bar}}
+test exec-15.2 {standard error redirection} {exec stdio} {
+    list [exec [interpreter] $path(sh) -c "\"$path(echo)\" foo bar 1>&2" \
+	      | [interpreter] $path(echo) biz baz >$path(gorp.file) 2> $path(gorp.file2)] \
+	[exec [interpreter] $path(cat) $path(gorp.file)] \
+	[exec [interpreter] $path(cat) $path(gorp.file2)]
+} {{} {biz baz} {foo bar}}
+test exec-15.3 {standard error redirection} {exec stdio} {
+    list [exec [interpreter] $path(sh) -c "\"$path(echo)\" foo bar 1>&2" \
+	      | [interpreter] $path(echo) biz baz 2>$path(gorp.file) > $path(gorp.file2)] \
+	[exec [interpreter] $path(cat) $path(gorp.file)] \
+	[exec [interpreter] $path(cat) $path(gorp.file2)]
+} {{} {foo bar} {biz baz}}
+test exec-15.4 {standard error redirection} {exec} {
+    set f [open $path(gorp.file) w]
+    puts $f "Line 1"
+    flush $f
+    exec [interpreter] $path(sh) -c "\"$path(echo)\" foo bar 1>&2" 2>@ $f
+    puts $f "Line 3"
+    close $f
+    readfile $path(gorp.file)
+} {Line 1
+foo bar
+Line 3}
+test exec-15.5 {standard error redirection} {exec} {
+    exec [interpreter] $path(echo) "First line" > "$path(gorp.file)"
+    exec [interpreter] "$path(sh)" -c "\"$path(echo)\" foo bar 1>&2" 2>> "$path(gorp.file)"
+    readfile $path(gorp.file)
+} {First line
+foo bar}
+test exec-15.6 {standard error redirection} {exec stdio} {
+    exec [interpreter] "$path(sh)" -c "\"$path(echo)\" foo bar 1>&2" > "$path(gorp.file2)" 2> "$path(gorp.file)" \
+	    >& "$path(gorp.file)" 2> "$path(gorp.file2)" | [interpreter] $path(echo) biz baz
+    list [readfile $path(gorp.file)] [readfile $path(gorp.file2)]
+} {{biz baz} {foo bar}}
+test exec-15.7 {standard error redirection 2>@1} {exec stdio} {
+    # This redirects stderr output into normal result output from exec
+    exec [interpreter] "$path(sh)" -c "\"$path(echo)\" foo bar 1>&2" 2>@1
+} {foo bar}
+
+test exec-16.1 {flush output before exec} {exec} {
+    set f [open $path(gorp.file) w]
+    puts $f "First line"
+    exec [interpreter] $path(echo) "Second line" >@ $f
+    puts $f "Third line"
+    close $f
+    readfile $path(gorp.file)
+} {First line
+Second line
+Third line}
+test exec-16.2 {flush output before exec} {exec} {
+    set f [open $path(gorp.file) w]
+    puts $f "First line"
+    exec [interpreter] << {puts stderr {Second line}} >&@ $f > $path(gorp.file2)
+    puts $f "Third line"
+    close $f
+    readfile $path(gorp.file)
+} {First line
+Second line
+Third line}
+
+test exec-17.1 {inheriting standard I/O} -constraints {exec} -setup {
+    set path(script) [makeFile {} script]
+    set f [open $path(script) w]
+    puts $f [list lassign [list \
+	    [info nameofexecutable] $path(gorp.file) $path(echo) $path(sleep) \
+        ] exe file echo sleep]
+    puts $f {
+	close stdout
+	set f [open $file w]
+	catch {exec $exe $echo foobar &}
+	exec $exe $sleep 2
+	close $f
+    }
+    close $f
+} -body {
+    catch {exec [interpreter] $path(script)} result
+    list $result [readfile $path(gorp.file)]
+} -cleanup {
+    removeFile $path(script)
+} -result {{} foobar}
+
+test exec-18.1 {exec deals with weird file names} -body {
+    set path(fooblah) [makeFile {contents} "foo\[\{blah"]
+    exec [interpreter] $path(cat) $path(fooblah)
+} -constraints {exec} -cleanup {
+    removeFile $path(fooblah)
+} -result contents
+test exec-18.2 {exec cat deals with weird file names} -body {
+    # This is cross-platform, but the cat isn't predictably correct on
+    # Windows.
+    set path(fooblah) [makeFile {contents} "foo\[\{blah"]
+    exec cat $path(fooblah)
+} -constraints {exec tempNotWin} -cleanup {
+    removeFile $path(fooblah)
+} -result contents
+
+# Note that this test cannot be adapted to work on Windows; that platform has
+# no kernel support for an analog of O_APPEND. OTOH, that means we can assume
+# that there is a POSIX shell...
+test exec-19.1 {exec >> uses O_APPEND} -constraints {exec unix} -setup {
+    set tmpfile [makeFile {0} tmpfile.exec-19.1]
+} -body {
+    # Note that we have to allow for the current contents of the temporary
+    # file, which is why the result is 14 and not 12
+    exec /bin/sh -c \
+	    {for a in 1 2 3; do sleep 1; echo $a; done} >>$tmpfile &
+    exec /bin/sh -c \
+	    {for a in a b c; do sleep 1; echo $a; done} >>$tmpfile &
+    # The above two shell invokations take about 3 seconds to finish, so allow
+    # 5s (in case the machine is busy)
+    after 5000
+    # Check that no bytes have got lost through mixups with overlapping
+    # appends, which is only guaranteed to work when we set O_APPEND on the
+    # file descriptor in the [exec >>...]
+    file size $tmpfile
+} -cleanup {
+    removeFile $tmpfile
+} -result 14
+
+# Tests to ensure batch files and .CMD (Bug 9ece99d58b)
+# can be executed on Windows
+test exec-20.0 {exec .bat file} -constraints {win} -body {
+    set log [makeFile {} exec20.log]
+    exec [makeFile "echo %1> $log" exec20.bat] "Testing exec-20.0"
+    viewFile $log
+} -result "\"Testing exec-20.0\""
+test exec-20.1 {exec .CMD file} -constraints {win} -body {
+    set log [makeFile {} exec201.log]
+    exec [makeFile "echo %1> $log" exec201.CMD] "Testing exec-20.1"
+    viewFile $log
+} -result "\"Testing exec-20.1\""
+    
+
+
+
+# ----------------------------------------------------------------------
+# cleanup
+
+foreach file {gorp.file gorp.file2 echo echo2 cat wc sh sh2 sleep exit err} {
+    removeFile $file
+}
+unset -nocomplain path
+
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/tests/execute.test b/tests/execute.test
new file mode 100644
index 0000000..9a2ffbd
--- /dev/null
+++ b/tests/execute.test
@@ -0,0 +1,1088 @@
+# This file contains tests for the tclExecute.c source file. Tests appear in
+# the same order as the C code that they test. The set of tests is currently
+# incomplete since it currently includes only new tests for code changed for
+# the addition of Tcl namespaces. Other execution-related tests appear in
+# several other test files including namespace.test, basic.test, eval.test,
+# for.test, etc.
+#
+# Sourcing this file into Tcl runs the tests and generates output for errors.
+# No output means no errors were found.
+#
+# Copyright (c) 1997 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution of
+# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {"::tcltest" ni [namespace children]} {
+    package require tcltest 2
+    namespace import -force ::tcltest::*
+}
+
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
+
+catch {namespace delete {*}[namespace children :: test_ns_*]}
+catch {rename foo ""}
+catch {unset x}
+catch {unset y}
+catch {unset msg}
+
+testConstraint testobj [expr {
+    [llength [info commands testobj]]
+    && [llength [info commands testdoubleobj]]
+    && [llength [info commands teststringobj]]
+}]
+
+testConstraint longIs32bit [expr {int(0x80000000) < 0}]
+testConstraint testexprlongobj [llength [info commands testexprlongobj]]
+
+# Tests for the omnibus TclExecuteByteCode function:
+
+# INST_DONE not tested
+# INST_PUSH1 not tested
+# INST_PUSH4 not tested
+# INST_POP not tested
+# INST_DUP not tested
+# INST_INVOKE_STK4 not tested
+# INST_INVOKE_STK1 not tested
+# INST_EVAL_STK not tested
+# INST_EXPR_STK not tested
+
+# INST_LOAD_SCALAR1
+test execute-1.1 {TclExecuteByteCode, INST_LOAD_SCALAR1, small opnd} {
+    proc foo {} {
+	set x 1
+	return $x
+    }
+    foo
+} 1
+test execute-1.2 {TclExecuteByteCode, INST_LOAD_SCALAR1, large opnd} {
+    # Bug: 2243
+    set body {}
+    for {set i 0} {$i < 129} {incr i} {
+	append body "set x$i x\n"
+    }
+    append body {
+	set y 1
+	return $y
+    }
+    proc foo {} $body
+    foo
+} 1
+test execute-1.3 {TclExecuteByteCode, INST_LOAD_SCALAR1, error} {
+    proc foo {} {
+	set x 1
+	unset x
+	return $x
+    }
+    list [catch {foo} msg] $msg
+} {1 {can't read "x": no such variable}}
+
+# INST_LOAD_SCALAR4
+test execute-2.1 {TclExecuteByteCode, INST_LOAD_SCALAR4, simple case} {
+    set body {}
+    for {set i 0} {$i < 256} {incr i} {
+	append body "set x$i x\n"
+    }
+    append body {
+	set y 1
+	return $y
+    }
+    proc foo {} $body
+    foo
+} 1
+test execute-2.2 {TclExecuteByteCode, INST_LOAD_SCALAR4, error} {
+    set body {}
+    for {set i 0} {$i < 256} {incr i} {
+	append body "set x$i x\n"
+    }
+    append body {
+	set y 1
+	unset y
+	return $y
+    }
+    proc foo {} $body
+    list [catch {foo} msg] $msg
+} {1 {can't read "y": no such variable}}
+
+# INST_LOAD_SCALAR_STK not tested
+# INST_LOAD_ARRAY4 not tested
+# INST_LOAD_ARRAY1 not tested
+# INST_LOAD_ARRAY_STK not tested
+# INST_LOAD_STK not tested
+# INST_STORE_SCALAR4 not tested
+# INST_STORE_SCALAR1 not tested
+# INST_STORE_SCALAR_STK not tested
+# INST_STORE_ARRAY4 not tested
+# INST_STORE_ARRAY1 not tested
+# INST_STORE_ARRAY_STK not tested
+# INST_STORE_STK not tested
+# INST_INCR_SCALAR1 not tested
+# INST_INCR_SCALAR_STK not tested
+# INST_INCR_STK not tested
+# INST_INCR_ARRAY1 not tested
+# INST_INCR_ARRAY_STK not tested
+# INST_INCR_SCALAR1_IMM not tested
+# INST_INCR_SCALAR_STK_IMM not tested
+# INST_INCR_STK_IMM not tested
+# INST_INCR_ARRAY1_IMM not tested
+# INST_INCR_ARRAY_STK_IMM not tested
+# INST_JUMP1 not tested
+# INST_JUMP4 not tested
+# INST_JUMP_TRUE4 not tested
+# INST_JUMP_TRUE1 not tested
+# INST_JUMP_FALSE4 not tested
+# INST_JUMP_FALSE1 not tested
+# INST_LOR not tested
+# INST_LAND not tested
+# INST_EQ not tested
+# INST_NEQ not tested
+# INST_LT not tested
+# INST_GT not tested
+# INST_LE not tested
+# INST_GE not tested
+# INST_MOD not tested
+# INST_LSHIFT not tested
+# INST_RSHIFT not tested
+# INST_BITOR not tested
+# INST_BITXOR not tested
+# INST_BITAND not tested
+
+# INST_ADD is partially tested:
+test execute-3.1 {TclExecuteByteCode, INST_ADD, op1 is int} {testobj} {
+    set x [testintobj set 0 1]
+    expr {$x + 1}
+} 2
+test execute-3.2 {TclExecuteByteCode, INST_ADD, op1 is double} {testobj} {
+    set x [testdoubleobj set 0 1]
+    expr {$x + 1}
+} 2.0
+test execute-3.3 {TclExecuteByteCode, INST_ADD, op1 is double with string} {testobj} {
+    set x [testintobj set 0 1]
+    testobj convert 0 double
+    expr {$x + 1}
+} 2
+test execute-3.4 {TclExecuteByteCode, INST_ADD, op1 is string int} {testobj} {
+    set x [teststringobj set 0 1]
+    expr {$x + 1}
+} 2
+test execute-3.5 {TclExecuteByteCode, INST_ADD, op1 is string double} {testobj} {
+    set x [teststringobj set 0 1.0]
+    expr {$x + 1}
+} 2.0
+test execute-3.6 {TclExecuteByteCode, INST_ADD, op1 is non-numeric} {testobj} {
+    set x [teststringobj set 0 foo]
+    list [catch {expr {$x + 1}} msg] $msg
+} {1 {can't use non-numeric string as operand of "+"}}
+test execute-3.7 {TclExecuteByteCode, INST_ADD, op2 is int} {testobj} {
+    set x [testintobj set 0 1]
+    expr {1 + $x}
+} 2
+test execute-3.8 {TclExecuteByteCode, INST_ADD, op2 is double} {testobj} {
+    set x [testdoubleobj set 0 1]
+    expr {1 + $x}
+} 2.0
+test execute-3.9 {TclExecuteByteCode, INST_ADD, op2 is double with string} {testobj} {
+    set x [testintobj set 0 1]
+    testobj convert 0 double
+    expr {1 + $x}
+} 2
+test execute-3.10 {TclExecuteByteCode, INST_ADD, op2 is string int} {testobj} {
+    set x [teststringobj set 0 1]
+    expr {1 + $x}
+} 2
+test execute-3.11 {TclExecuteByteCode, INST_ADD, op2 is string double} {testobj} {
+    set x [teststringobj set 0 1.0]
+    expr {1 + $x}
+} 2.0
+test execute-3.12 {TclExecuteByteCode, INST_ADD, op2 is non-numeric} {testobj} {
+    set x [teststringobj set 0 foo]
+    list [catch {expr {1 + $x}} msg] $msg
+} {1 {can't use non-numeric string as operand of "+"}}
+
+# INST_SUB is partially tested:
+test execute-3.13 {TclExecuteByteCode, INST_SUB, op1 is int} {testobj} {
+    set x [testintobj set 0 1]
+    expr {$x - 1}
+} 0
+test execute-3.14 {TclExecuteByteCode, INST_SUB, op1 is double} {testobj} {
+    set x [testdoubleobj set 0 1]
+    expr {$x - 1}
+} 0.0
+test execute-3.15 {TclExecuteByteCode, INST_SUB, op1 is double with string} {testobj} {
+    set x [testintobj set 0 1]
+    testobj convert 0 double
+    expr {$x - 1}
+} 0
+test execute-3.16 {TclExecuteByteCode, INST_SUB, op1 is string int} {testobj} {
+    set x [teststringobj set 0 1]
+    expr {$x - 1}
+} 0
+test execute-3.17 {TclExecuteByteCode, INST_SUB, op1 is string double} {testobj} {
+    set x [teststringobj set 0 1.0]
+    expr {$x - 1}
+} 0.0
+test execute-3.18 {TclExecuteByteCode, INST_SUB, op1 is non-numeric} {testobj} {
+    set x [teststringobj set 0 foo]
+    list [catch {expr {$x - 1}} msg] $msg
+} {1 {can't use non-numeric string as operand of "-"}}
+test execute-3.19 {TclExecuteByteCode, INST_SUB, op2 is int} {testobj} {
+    set x [testintobj set 0 1]
+    expr {1 - $x}
+} 0
+test execute-3.20 {TclExecuteByteCode, INST_SUB, op2 is double} {testobj} {
+    set x [testdoubleobj set 0 1]
+    expr {1 - $x}
+} 0.0
+test execute-3.21 {TclExecuteByteCode, INST_SUB, op2 is double with string} {testobj} {
+    set x [testintobj set 0 1]
+    testobj convert 0 double
+    expr {1 - $x}
+} 0
+test execute-3.22 {TclExecuteByteCode, INST_SUB, op2 is string int} {testobj} {
+    set x [teststringobj set 0 1]
+    expr {1 - $x}
+} 0
+test execute-3.23 {TclExecuteByteCode, INST_SUB, op2 is string double} {testobj} {
+    set x [teststringobj set 0 1.0]
+    expr {1 - $x}
+} 0.0
+test execute-3.24 {TclExecuteByteCode, INST_SUB, op2 is non-numeric} {testobj} {
+    set x [teststringobj set 0 foo]
+    list [catch {expr {1 - $x}} msg] $msg
+} {1 {can't use non-numeric string as operand of "-"}}
+
+# INST_MULT is partially tested:
+test execute-3.25 {TclExecuteByteCode, INST_MULT, op1 is int} {testobj} {
+    set x [testintobj set 1 1]
+    expr {$x * 1}
+} 1
+test execute-3.26 {TclExecuteByteCode, INST_MULT, op1 is double} {testobj} {
+    set x [testdoubleobj set 1 2.0]
+    expr {$x * 1}
+} 2.0
+test execute-3.27 {TclExecuteByteCode, INST_MULT, op1 is double with string} {testobj} {
+    set x [testintobj set 1 2]
+    testobj convert 1 double
+    expr {$x * 1}
+} 2
+test execute-3.28 {TclExecuteByteCode, INST_MULT, op1 is string int} {testobj} {
+    set x [teststringobj set 1 1]
+    expr {$x * 1}
+} 1
+test execute-3.29 {TclExecuteByteCode, INST_MULT, op1 is string double} {testobj} {
+    set x [teststringobj set 1 1.0]
+    expr {$x * 1}
+} 1.0
+test execute-3.30 {TclExecuteByteCode, INST_MULT, op1 is non-numeric} {testobj} {
+    set x [teststringobj set 1 foo]
+    list [catch {expr {$x * 1}} msg] $msg
+} {1 {can't use non-numeric string as operand of "*"}}
+test execute-3.31 {TclExecuteByteCode, INST_MULT, op2 is int} {testobj} {
+    set x [testintobj set 1 1]
+    expr {1 * $x}
+} 1
+test execute-3.32 {TclExecuteByteCode, INST_MULT, op2 is double} {testobj} {
+    set x [testdoubleobj set 1 2.0]
+    expr {1 * $x}
+} 2.0
+test execute-3.33 {TclExecuteByteCode, INST_MULT, op2 is double with string} {testobj} {
+    set x [testintobj set 1 2]
+    testobj convert 1 double
+    expr {1 * $x}
+} 2
+test execute-3.34 {TclExecuteByteCode, INST_MULT, op2 is string int} {testobj} {
+    set x [teststringobj set 1 1]
+    expr {1 * $x}
+} 1
+test execute-3.35 {TclExecuteByteCode, INST_MULT, op2 is string double} {testobj} {
+    set x [teststringobj set 1 1.0]
+    expr {1 * $x}
+} 1.0
+test execute-3.36 {TclExecuteByteCode, INST_MULT, op2 is non-numeric} {testobj} {
+    set x [teststringobj set 1 foo]
+    list [catch {expr {1 * $x}} msg] $msg
+} {1 {can't use non-numeric string as operand of "*"}}
+
+# INST_DIV is partially tested:
+test execute-3.37 {TclExecuteByteCode, INST_DIV, op1 is int} {testobj} {
+    set x [testintobj set 1 1]
+    expr {$x / 1}
+} 1
+test execute-3.38 {TclExecuteByteCode, INST_DIV, op1 is double} {testobj} {
+    set x [testdoubleobj set 1 2.0]
+    expr {$x / 1}
+} 2.0
+test execute-3.39 {TclExecuteByteCode, INST_DIV, op1 is double with string} {testobj} {
+    set x [testintobj set 1 2]
+    testobj convert 1 double
+    expr {$x / 1}
+} 2
+test execute-3.40 {TclExecuteByteCode, INST_DIV, op1 is string int} {testobj} {
+    set x [teststringobj set 1 1]
+    expr {$x / 1}
+} 1
+test execute-3.41 {TclExecuteByteCode, INST_DIV, op1 is string double} {testobj} {
+    set x [teststringobj set 1 1.0]
+    expr {$x / 1}
+} 1.0
+test execute-3.42 {TclExecuteByteCode, INST_DIV, op1 is non-numeric} {testobj} {
+    set x [teststringobj set 1 foo]
+    list [catch {expr {$x / 1}} msg] $msg
+} {1 {can't use non-numeric string as operand of "/"}}
+test execute-3.43 {TclExecuteByteCode, INST_DIV, op2 is int} {testobj} {
+    set x [testintobj set 1 1]
+    expr {2 / $x}
+} 2
+test execute-3.44 {TclExecuteByteCode, INST_DIV, op2 is double} {testobj} {
+    set x [testdoubleobj set 1 1.0]
+    expr {2 / $x}
+} 2.0
+test execute-3.45 {TclExecuteByteCode, INST_DIV, op2 is double with string} {testobj} {
+    set x [testintobj set 1 1]
+    testobj convert 1 double
+    expr {2 / $x}
+} 2
+test execute-3.46 {TclExecuteByteCode, INST_DIV, op2 is string int} {testobj} {
+    set x [teststringobj set 1 1]
+    expr {2 / $x}
+} 2
+test execute-3.47 {TclExecuteByteCode, INST_DIV, op2 is string double} {testobj} {
+    set x [teststringobj set 1 1.0]
+    expr {2 / $x}
+} 2.0
+test execute-3.48 {TclExecuteByteCode, INST_DIV, op2 is non-numeric} {testobj} {
+    set x [teststringobj set 1 foo]
+    list [catch {expr {1 / $x}} msg] $msg
+} {1 {can't use non-numeric string as operand of "/"}}
+
+# INST_UPLUS is partially tested:
+test execute-3.49 {TclExecuteByteCode, INST_UPLUS, op is int} {testobj} {
+    set x [testintobj set 1 1]
+    expr {+ $x}
+} 1
+test execute-3.50 {TclExecuteByteCode, INST_UPLUS, op is double} {testobj} {
+    set x [testdoubleobj set 1 1.0]
+    expr {+ $x}
+} 1.0
+test execute-3.51 {TclExecuteByteCode, INST_UPLUS, op is double with string} {testobj} {
+    set x [testintobj set 1 1]
+    testobj convert 1 double
+    expr {+ $x}
+} 1
+test execute-3.52 {TclExecuteByteCode, INST_UPLUS, op is string int} {testobj} {
+    set x [teststringobj set 1 1]
+    expr {+ $x}
+} 1
+test execute-3.53 {TclExecuteByteCode, INST_UPLUS, op is string double} {testobj} {
+    set x [teststringobj set 1 1.0]
+    expr {+ $x}
+} 1.0
+test execute-3.54 {TclExecuteByteCode, INST_UPLUS, op is non-numeric} {testobj} {
+    set x [teststringobj set 1 foo]
+    list [catch {expr {+ $x}} msg] $msg
+} {1 {can't use non-numeric string as operand of "+"}}
+
+# INST_UMINUS is partially tested:
+test execute-3.55 {TclExecuteByteCode, INST_UMINUS, op is int} {testobj} {
+    set x [testintobj set 1 1]
+    expr {- $x}
+} -1
+test execute-3.56 {TclExecuteByteCode, INST_UMINUS, op is double} {testobj} {
+    set x [testdoubleobj set 1 1.0]
+    expr {- $x}
+} -1.0
+test execute-3.57 {TclExecuteByteCode, INST_UMINUS, op is double with string} {testobj} {
+    set x [testintobj set 1 1]
+    testobj convert 1 double
+    expr {- $x}
+} -1
+test execute-3.58 {TclExecuteByteCode, INST_UMINUS, op is string int} {testobj} {
+    set x [teststringobj set 1 1]
+    expr {- $x}
+} -1
+test execute-3.59 {TclExecuteByteCode, INST_UMINUS, op is string double} {testobj} {
+    set x [teststringobj set 1 1.0]
+    expr {- $x}
+} -1.0
+test execute-3.60 {TclExecuteByteCode, INST_UMINUS, op is non-numeric} {testobj} {
+    set x [teststringobj set 1 foo]
+    list [catch {expr {- $x}} msg] $msg
+} {1 {can't use non-numeric string as operand of "-"}}
+
+# INST_LNOT is partially tested:
+test execute-3.61 {TclExecuteByteCode, INST_LNOT, op is int} {testobj} {
+    set x [testintobj set 1 2]
+    expr {! $x}
+} 0
+test execute-3.62 {TclExecuteByteCode, INST_LNOT, op is int} {testobj} {
+    set x [testintobj set 1 0]
+    expr {! $x}
+} 1
+test execute-3.63 {TclExecuteByteCode, INST_LNOT, op is double} {testobj} {
+    set x [testdoubleobj set 1 1.0]
+    expr {! $x}
+} 0
+test execute-3.64 {TclExecuteByteCode, INST_LNOT, op is double} {testobj} {
+    set x [testdoubleobj set 1 0.0]
+    expr {! $x}
+} 1
+test execute-3.65 {TclExecuteByteCode, INST_LNOT, op is double with string} {testobj} {
+    set x [testintobj set 1 1]
+    testobj convert 1 double
+    expr {! $x}
+} 0
+test execute-3.66 {TclExecuteByteCode, INST_LNOT, op is double with string} {testobj} {
+    set x [testintobj set 1 0]
+    testobj convert 1 double
+    expr {! $x}
+} 1
+test execute-3.67 {TclExecuteByteCode, INST_LNOT, op is string int} {testobj} {
+    set x [teststringobj set 1 1]
+    expr {! $x}
+} 0
+test execute-3.68 {TclExecuteByteCode, INST_LNOT, op is string int} {testobj} {
+    set x [teststringobj set 1 0]
+    expr {! $x}
+} 1
+test execute-3.69 {TclExecuteByteCode, INST_LNOT, op is string double} {testobj} {
+    set x [teststringobj set 1 1.0]
+    expr {! $x}
+} 0
+test execute-3.70 {TclExecuteByteCode, INST_LNOT, op is string double} {testobj} {
+    set x [teststringobj set 1 0.0]
+    expr {! $x}
+} 1
+test execute-3.71 {TclExecuteByteCode, INST_LNOT, op is non-numeric} {testobj} {
+    set x [teststringobj set 1 foo]
+    list [catch {expr {! $x}} msg] $msg
+} {1 {can't use non-numeric string as operand of "!"}}
+
+# INST_BITNOT not tested
+# INST_CALL_BUILTIN_FUNC1 not tested
+# INST_CALL_FUNC1 not tested
+
+# INST_TRY_CVT_TO_NUMERIC is partially tested:
+test execute-3.72 {TclExecuteByteCode, INST_TRY_CVT_TO_NUMERIC, op is int} {testobj} {
+    set x [testintobj set 1 1]
+    expr {$x}
+} 1
+test execute-3.73 {TclExecuteByteCode, INST_TRY_CVT_TO_NUMERIC, op is double} {testobj} {
+    set x [testdoubleobj set 1 1.0]
+    expr {$x}
+} 1.0
+test execute-3.74 {TclExecuteByteCode, INST_TRY_CVT_TO_NUMERIC, op is double with string} {testobj} {
+    set x [testintobj set 1 1]
+    testobj convert 1 double
+    expr {$x}
+} 1
+test execute-3.75 {TclExecuteByteCode, INST_TRY_CVT_TO_NUMERIC, op is string int} {testobj} {
+    set x [teststringobj set 1 1]
+    expr {$x}
+} 1
+test execute-3.76 {TclExecuteByteCode, INST_TRY_CVT_TO_NUMERIC, op is string double} {testobj} {
+    set x [teststringobj set 1 1.0]
+    expr {$x}
+} 1.0
+test execute-3.77 {TclExecuteByteCode, INST_TRY_CVT_TO_NUMERIC, op is non-numeric} {testobj} {
+    set x [teststringobj set 1 foo]
+    expr {$x}
+} foo
+
+# INST_BREAK not tested
+# INST_CONTINUE not tested
+# INST_FOREACH_START4 not tested
+# INST_FOREACH_STEP4 not tested
+# INST_BEGIN_CATCH4 not tested
+# INST_END_CATCH not tested
+# INST_PUSH_RESULT not tested
+# INST_PUSH_RETURN_CODE not tested
+
+test execute-4.1 {Tcl_GetCommandFromObj, convert to tclCmdNameType} -setup {
+    catch {namespace delete {*}[namespace children :: test_ns_*]}
+    unset -nocomplain x
+    unset -nocomplain y
+} -body {
+    namespace eval test_ns_1 {
+        namespace export cmd1
+        proc cmd1 {args} {return "cmd1: $args"}
+        proc cmd2 {args} {return "cmd2: $args"}
+    }
+    namespace eval test_ns_1::test_ns_2 {
+        namespace import ::test_ns_1::*
+    }
+    set x "test_ns_1::"
+    set y "test_ns_2::"
+    list [namespace which -command ${x}${y}cmd1] \
+         [catch {namespace which -command ${x}${y}cmd2} msg] $msg \
+         [catch {namespace which -command ${x}${y}:cmd2} msg] $msg
+} -result {::test_ns_1::test_ns_2::cmd1 0 {} 0 {}}
+test execute-4.2 {Tcl_GetCommandFromObj, check if cached tclCmdNameType is invalid} -setup {
+    catch {namespace delete {*}[namespace children :: test_ns_*]}
+    catch {rename foo ""}
+    unset -nocomplain l
+} -body {
+    proc foo {} {
+        return "global foo"
+    }
+    namespace eval test_ns_1 {
+        proc whichFoo {} {
+            return [namespace which -command foo]
+        }
+    }
+    set l ""
+    lappend l [test_ns_1::whichFoo]
+    namespace eval test_ns_1 {
+        proc foo {} {
+            return "namespace foo"
+        }
+    }
+    lappend l [test_ns_1::whichFoo]
+} -result {::foo ::test_ns_1::foo}
+test execute-4.3 {Tcl_GetCommandFromObj, command never found} -setup {
+    catch {namespace delete {*}[namespace children :: test_ns_*]}
+    catch {rename foo ""}
+} -body {
+    namespace eval test_ns_1 {
+        proc foo {} {
+            return "namespace foo"
+        }
+    }
+    namespace eval test_ns_1 {
+        proc foo {} {
+            return "namespace foo"
+        }
+    }
+    list [namespace eval test_ns_1 {namespace which -command foo}] \
+         [rename test_ns_1::foo ""] \
+         [catch {namespace eval test_ns_1 {namespace which -command foo}} msg] $msg
+} -result {::test_ns_1::foo {} 0 {}}
+
+test execute-5.1 {SetCmdNameFromAny, set cmd name to empty heap string if NULL} -setup {
+    catch {namespace delete {*}[namespace children :: test_ns_*]}
+    unset -nocomplain l
+} -body {
+    proc {} {} {return {}}
+    {}
+    set l {}
+    lindex {} 0
+    {}
+} -result {}
+
+test execute-6.1 {UpdateStringOfCmdName: called for duplicate of empty cmdName object} {
+    proc {} {} {}
+    proc { } {} {}
+    proc p {} {
+        set x {}
+        $x
+        append x { }
+        $x
+    }
+    p
+} {}
+test execute-6.2 {Evaluate an expression in a variable; compile the first time, do not the second} {
+    set w {3*5}
+    proc a {obj} {expr $obj}
+    set res "[a $w]:[a $w]"
+} {15:15}
+test execute-6.3 {Tcl_ExprObj: don't use cached script bytecode [Bug 1899164]} -setup {
+    proc 0+0 {} {return SCRIPT}
+} -body {
+    set e { 0+0 }
+    if 1 $e
+    if 1 {expr $e}
+} -cleanup {
+    rename 0+0 {}
+} -result 0
+test execute-6.4 {TclCompEvalObj: don't use cached expr bytecode [Bug 1899164]} -setup {
+    proc 0+0 {} {return SCRIPT}
+} -body {
+    set e { 0+0 }
+    if 1 {expr $e}
+    if 1 $e
+} -cleanup {
+    rename 0+0 {}
+} -result SCRIPT
+test execute-6.5 {TclCompEvalObj: bytecode epoch validation} -body {
+    set script { llength {} }
+    set result {}
+    lappend result [if 1 $script]
+    set origName [namespace which llength]
+    rename $origName llength.orig
+    proc $origName {args} {return AHA!}
+    lappend result [if 1 $script]
+} -cleanup {
+    rename $origName {}
+    rename llength.orig $origName
+} -result {0 AHA!}
+test execute-6.6 {TclCompEvalObj: proc-body bytecode invalid for script} -body {
+    proc foo {} {set a 1}
+    set a untouched
+    set result {}
+    lappend result [foo] $a
+    lappend result [if 1 [info body foo]] $a
+} -cleanup {
+    rename foo {}
+} -result {1 untouched 1 1}
+test execute-6.7 {TclCompEvalObj: bytecode context validation} -setup {
+    namespace eval foo {}
+} -body {
+    set script { llength {} }
+    namespace eval foo {
+	proc llength {args} {return AHA!}
+    }
+    set result {}
+    lappend result [if 1 $script]
+    lappend result [namespace eval foo $script]
+} -cleanup {
+    namespace delete foo
+} -result {0 AHA!}
+test execute-6.8 {TclCompEvalObj: bytecode name resolution epoch validation} -setup {
+    namespace eval foo {}
+} -body {
+    set script { llength {} }
+    set result {}
+    lappend result [namespace eval foo $script]
+    namespace eval foo {
+	proc llength {args} {return AHA!}
+    }
+    lappend result [namespace eval foo $script]
+} -cleanup {
+    namespace delete foo
+} -result {0 AHA!}
+test execute-6.9 {TclCompEvalObj: bytecode interp validation} -setup {
+    interp create slave
+} -body {
+    set script { llength {} }
+    slave eval {proc llength args {return AHA!}}
+    set result {}
+    lappend result [if 1 $script]
+    lappend result [slave eval $script]
+} -cleanup {
+    interp delete slave
+} -result {0 AHA!}
+test execute-6.10 {TclCompEvalObj: bytecode interp validation} -body {
+    set script { llength {} }
+    interp create slave
+    set result {}
+    lappend result [slave eval $script]
+    interp delete slave
+    interp create slave
+    lappend result [slave eval $script]
+} -cleanup {
+    catch {interp delete slave}
+} -result {0 0}
+test execute-6.11 {Tcl_ExprObj: exprcode interp validation} -setup {
+    interp create slave
+} -constraints testexprlongobj -body {
+    set e { [llength {}]+1 }
+    set result {}
+    load {} Tcltest slave
+    interp alias {} e slave testexprlongobj
+    lappend result [e $e]
+    interp delete slave
+    interp create slave
+    load {} Tcltest slave
+    interp alias {} e slave testexprlongobj
+    lappend result [e $e]
+} -cleanup {
+    interp delete slave
+} -result {{This is a result: 1} {This is a result: 1}}
+test execute-6.12 {Tcl_ExprObj: exprcode interp validation} -setup {
+    interp create slave
+} -body {
+    set e { [llength {}]+1 }
+    set result {}
+    interp alias {} e slave expr
+    lappend result [e $e]
+    interp delete slave
+    interp create slave
+    interp alias {} e slave expr 
+    lappend result [e $e]
+} -cleanup {
+    interp delete slave
+} -result {1 1}
+test execute-6.13 {Tcl_ExprObj: exprcode epoch validation} -body {
+    set e { [llength {}]+1 }
+    set result {}
+    lappend result [expr $e]
+    set origName [namespace which llength]
+    rename $origName llength.orig
+    proc $origName {args} {return 1}
+    lappend result [expr $e]
+} -cleanup {
+    rename $origName {}
+    rename llength.orig $origName
+} -result {1 2}
+test execute-6.14 {Tcl_ExprObj: exprcode context validation} -setup {
+    namespace eval foo {}
+} -body {
+    set e { [llength {}]+1 }
+    namespace eval foo {
+	proc llength {args} {return 1}
+    }
+    set result {}
+    lappend result [expr $e]
+    lappend result [namespace eval foo {expr $e}]
+} -cleanup {
+    namespace delete foo
+} -result {1 2}
+test execute-6.15 {Tcl_ExprObj: exprcode name resolution epoch validation} -setup {
+    namespace eval foo {}
+} -body {
+    set e { [llength {}]+1 }
+    set result {}
+    lappend result [namespace eval foo {expr $e}]
+    namespace eval foo {
+	proc llength {args} {return 1}
+    }
+    lappend result [namespace eval foo {expr $e}]
+} -cleanup {
+    namespace delete foo
+} -result {1 2}
+test execute-6.16 {Tcl_ExprObj: exprcode interp validation} -setup {
+    interp create slave
+} -body {
+    set e { [llength {}]+1 }
+    interp alias {} e slave expr
+    slave eval {proc llength args {return 1}}
+    set result {}
+    lappend result [expr $e]
+    lappend result [e $e]
+} -cleanup {
+    interp delete slave
+} -result {1 2}
+test execute-6.17 {Tcl_ExprObj: exprcode context validation} -body {
+    proc foo e {set v 0; expr $e}
+    proc bar e {set v 1; expr $e}
+    set e { $v }
+    set result {}
+    lappend result [foo $e]
+    lappend result [bar $e]
+} -cleanup {
+    rename foo {}
+    rename bar {}
+} -result {0 1}
+test execute-6.18 {Tcl_ExprObj: exprcode context validation} -body {
+    proc foo e {set v {}; expr $e}
+    proc bar e {set v v; expr $e}
+    set e { [llength $v] }
+    set result {}
+    lappend result [foo $e]
+    lappend result [bar $e]
+} -cleanup {
+    rename foo {}
+    rename bar {}
+} -result {0 1}
+
+test execute-7.0 {Wide int handling in INST_JUMP_FALSE/LAND} {
+    set x 0x100000000
+    expr {$x && 1}
+} 1
+test execute-7.1 {Wide int handling in INST_JUMP_FALSE/LAND} {
+    expr {0x100000000 && 1}
+} 1
+test execute-7.2 {Wide int handling in INST_JUMP_FALSE/LAND} {
+    expr {1 && 0x100000000}
+} 1
+test execute-7.3 {Wide int handling in INST_JUMP_FALSE/LAND} {
+    expr {wide(0x100000000) && 1}
+} 1
+test execute-7.4 {Wide int handling in INST_JUMP_FALSE/LAND} {
+    expr {1 && wide(0x100000000)}
+} 1
+test execute-7.5 {Wide int handling in INST_EQ} {
+    expr {4 == (wide(1)+wide(3))}
+} 1
+test execute-7.6 {Wide int handling in INST_EQ and [incr]} {
+    set x 399999999999
+    expr {400000000000 == [incr x]}
+} 1
+# wide ints have more bits of precision than doubles, but we convert anyway
+test execute-7.7 {Wide int handling in INST_EQ and [incr]} {
+    set x [expr {wide(1)<<62}]
+    set y [expr {$x+1}]
+    expr {double($x) == double($y)}
+} 1
+test execute-7.8 {Wide int conversions can change sign} longIs32bit {
+    set x 0x80000000
+    expr {int($x) < wide($x)}
+} 1
+test execute-7.9 {Wide int handling in INST_MOD} {
+    expr {(wide(1)<<60) % ((wide(47)<<45)-1)}
+} 316659348800185
+test execute-7.10 {Wide int handling in INST_MOD} {
+    expr {((wide(1)<<60)-1) % 0x400000000}
+} 17179869183
+test execute-7.11 {Wide int handling in INST_LSHIFT} {
+    expr wide(42)<<30
+} 45097156608
+test execute-7.12 {Wide int handling in INST_LSHIFT} {
+    expr 12345678901<<3
+} 98765431208
+test execute-7.13 {Wide int handling in INST_RSHIFT} {
+    expr 0x543210febcda9876>>7
+} 47397893236700464
+test execute-7.14 {Wide int handling in INST_RSHIFT} {
+    expr wide(0x9876543210febcda)>>7
+} -58286587177206407
+test execute-7.15 {Wide int handling in INST_BITOR} {
+    expr wide(0x9876543210febcda) | 0x543210febcda9876
+} -2560765885044310786
+test execute-7.16 {Wide int handling in INST_BITXOR} {
+    expr wide(0x9876543210febcda) ^ 0x543210febcda9876
+} -3727778945703861076
+test execute-7.17 {Wide int handling in INST_BITAND} {
+    expr wide(0x9876543210febcda) & 0x543210febcda9876
+} 1167013060659550290
+test execute-7.18 {Wide int handling in INST_ADD} {
+    expr wide(0x7fffffff)+wide(0x7fffffff)
+} 4294967294
+test execute-7.19 {Wide int handling in INST_ADD} {
+    expr 0x7fffffff+wide(0x7fffffff)
+} 4294967294
+test execute-7.20 {Wide int handling in INST_ADD} {
+    expr wide(0x7fffffff)+0x7fffffff
+} 4294967294
+test execute-7.21 {Wide int handling in INST_ADD} {
+    expr double(0x7fffffff)+wide(0x7fffffff)
+} 4294967294.0
+test execute-7.22 {Wide int handling in INST_ADD} {
+    expr wide(0x7fffffff)+double(0x7fffffff)
+} 4294967294.0
+test execute-7.23 {Wide int handling in INST_SUB} {
+    expr 0x123456789a-0x20406080a
+} 69530054800
+test execute-7.24 {Wide int handling in INST_MULT} {
+    expr 0x123456789a*193
+} 15090186251290
+test execute-7.25 {Wide int handling in INST_DIV} {
+    expr 0x123456789a/193
+} 405116546
+test execute-7.26 {Wide int handling in INST_UPLUS} {
+    set x 0x123456871234568
+    expr {+ $x}
+} 81985533099853160
+test execute-7.27 {Wide int handling in INST_UMINUS} {
+    set x 0x123456871234568
+    expr {- $x}
+} -81985533099853160
+test execute-7.28 {Wide int handling in INST_LNOT} {
+    set x 0x123456871234568
+    expr {! $x}
+} 0
+test execute-7.29 {Wide int handling in INST_BITNOT} {
+    set x 0x123456871234568
+    expr {~ $x}
+} -81985533099853161
+test execute-7.30 {Wide int handling in function call} {
+    set x 0x12345687123456
+    incr x
+    expr {log($x) == log(double($x))}
+} 1
+test execute-7.31 {Wide int handling in abs()} {
+    set x 0xa23456871234568
+    incr x
+    set y 0x123456871234568
+    concat [expr {abs($x)}] [expr {abs($y)}]
+} {730503879441204585 81985533099853160}
+test execute-7.32 {Wide int handling} longIs32bit {
+    expr {int(1024 * 1024 * 1024 * 1024)}
+} 0
+test execute-7.33 {Wide int handling} longIs32bit {
+    expr {int(0x1 * 1024 * 1024 * 1024 * 1024)}
+} 0
+test execute-7.34 {Wide int handling} {
+    expr {wide(0x1) * 1024 * 1024 * 1024 * 1024}
+} 1099511627776
+
+test execute-8.1 {Stack protection} -setup {
+    # If [Bug #804681] has not been properly taken care of, this should
+    # segfault
+    proc whatever args {llength $args}
+    trace add variable ::errorInfo {write unset} whatever
+} -body {
+    expr {1+9/0}
+} -cleanup {
+    trace remove variable ::errorInfo {write unset} whatever
+    rename whatever {}
+} -returnCodes error -match glob -result *
+test execute-8.2 {Stack restoration} -setup {
+    # Avoid crashes when system stack size is limited (thread-enabled!)
+    set limit [interp recursionlimit {}]
+    interp recursionlimit {} 100
+} -body {
+    # Test for [Bug #816641], correct restoration of the stack top after the
+    # stack is grown
+    proc f {args} { f bee bop }
+    catch f msg
+    set msg
+} -cleanup {
+    interp recursionlimit {} $limit
+} -result {too many nested evaluations (infinite loop?)}
+test execute-8.3 {Stack restoration} -setup {
+    # Avoid crashes when system stack size is limited (thread-enabled!)
+    set limit [interp recursionlimit {}]
+    interp recursionlimit {} 100
+} -body {
+    # Test for [Bug #1055676], correct restoration of the stack top after the
+    # epoch is bumped and the stack is grown in a call from a nested
+    # evaluation
+    set arglst [string repeat "a " 1000]
+    proc f {args} "f $arglst"
+    proc run {} {
+	# bump the interp's epoch
+	rename ::set ::dummy
+	rename ::dummy ::set
+	catch f msg
+	set msg
+    }
+    run
+} -cleanup {
+    interp recursionlimit {} $limit
+} -result {too many nested evaluations (infinite loop?)}
+test execute-8.4 {Compile epoch bump effect on stack trace} -setup {
+    proc foo {} {
+	error bar
+    }
+    proc FOO {} {
+	catch {error bar} m o
+	rename ::set ::dummy
+	rename ::dummy ::set
+	return -options $o $m
+    }
+} -body {
+    catch foo m o
+    set stack1 [dict get $o -errorinfo]
+    catch FOO m o
+    set stack2 [string map {FOO foo} [dict get $o -errorinfo]]
+    expr {$stack1 eq $stack2 ? {} : "These differ:\n$stack1\n$stack2"}
+} -cleanup {
+    rename foo {}
+    rename FOO {}
+    unset -nocomplain m o stack1 stack2
+} -result {}
+test execute-8.5 {Bug 2038069} -setup {
+    proc demo {} {
+	catch [list error FOO] m o
+	return $o
+    }
+} -body {
+    demo
+} -cleanup {
+    rename demo {}
+} -match glob -result {-code 1 -level 0 -errorstack * -errorcode NONE -errorinfo {FOO
+    while executing
+"error FOO"
+    invoked from within
+"catch \[list error FOO\] m o"} -errorline 2}
+
+test execute-9.1 {Interp result resetting [Bug 1522803]} {
+    set c 0
+    catch {
+	catch {set foo}
+	expr {1/$c}
+    }
+    if {[string match *foo* $::errorInfo]} {
+	set result "Bad errorInfo: $::errorInfo"
+    } else {
+	set result SUCCESS
+    }
+    set result
+} SUCCESS
+
+test execute-10.1 {TclExecuteByteCode, INST_CONCAT1, bytearrays} {
+    apply {s {binary scan $s c x; list $x [scan $s$s %c%c]}} \u0130
+} {48 {304 304}}
+test execute-10.2 {Bug 2802881} -setup {
+    interp create slave
+} -body {
+    # If [Bug 2802881] is not fixed, this will segfault
+    slave eval {
+	trace add variable ::errorInfo write {expr {$foo} ;#}
+	proc demo {} {a {}{}}
+	demo
+    }
+} -cleanup {
+    interp delete slave
+} -returnCodes error -match glob -result *
+test execute-10.3 {Bug 3072640} -setup {
+    proc generate {n} {
+	for {set i 0} {$i < $n} {incr i} {
+	    yield $i
+	}
+    }
+    proc t {args} { 
+	incr ::foo 
+    }
+    trace add execution ::generate enterstep ::t
+} -body {
+    coroutine coro generate 5
+    trace remove execution ::generate enterstep ::t
+    set ::foo
+} -cleanup {
+    unset ::foo
+    rename generate {}
+    rename t {}
+    rename coro {}
+} -result 4
+
+test execute-11.1 {Bug 3142026: GrowEvaluationStack off-by-one} -setup {
+    interp create slave
+} -body {
+    slave eval {
+	set x [lrepeat 1320 199]
+	for {set i 0} {$i < 20} {incr i} {
+	    lappend x $i
+	    lsort -integer $x
+	}
+	# Crashes on failure
+	return ok
+    }
+} -cleanup {
+    interp delete slave
+} -result ok
+
+test execute-11.2 {Bug 268b23df11} -setup {
+    proc zero {} {return 0}
+    proc crash {} {expr {abs([zero])}}
+    proc noop args {}
+    trace add execution crash enterstep noop
+} -body {
+    crash
+} -cleanup {
+    trace remove execution crash enterstep noop
+    rename noop {}
+    rename crash {}
+    rename zero {}
+} -result 0
+test execute-11.3 {Bug a0ece9d6d4} -setup {
+    proc crash {} {expr {rand()}}
+    trace add execution crash enterstep {apply {args {info frame -2}}}
+} -body {
+    string is double [crash]
+} -cleanup {
+    trace remove execution crash enterstep {apply {args {info frame -2}}}
+    rename crash {}
+} -result 1
+
+# cleanup
+if {[info commands testobj] != {}} {
+   testobj freeallvars
+}
+catch {namespace delete {*}[namespace children :: test_ns_*]}
+catch {rename foo ""}
+catch {rename p ""}
+catch {rename {} ""}
+catch {rename { } ""}
+catch {unset x}
+catch {unset y}
+catch {unset msg}
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# fill-column: 78
+# End:
diff --git a/tests/expr-old.test b/tests/expr-old.test
new file mode 100644
index 0000000..06a00ba
--- /dev/null
+++ b/tests/expr-old.test
@@ -0,0 +1,1208 @@
+# Commands covered: expr
+#
+# This file contains the original set of tests for Tcl's expr command.
+# Since the expr command is now compiled, a new set of tests covering
+# the new implementation are in the files "parseExpr.test" and
+# "compExpr.test". Sourcing this file into Tcl runs the tests and generates
+# output for errors. No output means no errors were found.
+#
+# Copyright (c) 1991-1994 The Regents of the University of California.
+# Copyright (c) 1994-1997 Sun Microsystems, Inc.
+# Copyright (c) 1998-2000 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+package require tcltest 2.1
+namespace import ::tcltest::*
+
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
+
+testConstraint testexprlong   [llength [info commands testexprlong]]
+testConstraint testexprdouble [llength [info commands testexprdouble]]
+testConstraint testexprstring [llength [info commands testexprstring]]
+testConstraint longIs32bit    [expr {int(0x80000000) < 0}]
+
+if {[catch {expr T1()} msg] && $msg eq {invalid command name "tcl::mathfunc::T1"}} {
+    testConstraint testmathfunctions 0
+} else {
+    testConstraint testmathfunctions 1
+}
+
+# Big test for correct ordering of data in [expr]
+
+proc testIEEE {} {
+    variable ieeeValues
+    binary scan [binary format dd -1.0 1.0] c* c
+    switch -exact -- $c {
+	{0 0 0 0 0 0 -16 -65 0 0 0 0 0 0 -16 63} {
+	    # little endian
+	    binary scan \x00\x00\x00\x00\x00\x00\xf0\xff d \
+		ieeeValues(-Infinity)
+	    binary scan \x00\x00\x00\x00\x00\x00\xf0\xbf d \
+		ieeeValues(-Normal)
+	    binary scan \x00\x00\x00\x00\x00\x00\x08\x80 d \
+		ieeeValues(-Subnormal)
+	    binary scan \x00\x00\x00\x00\x00\x00\x00\x80 d \
+		ieeeValues(-0)
+	    binary scan \x00\x00\x00\x00\x00\x00\x00\x00 d \
+		ieeeValues(+0)
+	    binary scan \x00\x00\x00\x00\x00\x00\x08\x00 d \
+		ieeeValues(+Subnormal)
+	    binary scan \x00\x00\x00\x00\x00\x00\xf0\x3f d \
+		ieeeValues(+Normal)
+	    binary scan \x00\x00\x00\x00\x00\x00\xf0\x7f d \
+		ieeeValues(+Infinity)
+	    binary scan \x00\x00\x00\x00\x00\x00\xf8\x7f d \
+		ieeeValues(NaN)
+	    set ieeeValues(littleEndian) 1
+	    return 1
+	}
+	{-65 -16 0 0 0 0 0 0 63 -16 0 0 0 0 0 0} {
+	    binary scan \xff\xf0\x00\x00\x00\x00\x00\x00 d \
+		ieeeValues(-Infinity)
+	    binary scan \xbf\xf0\x00\x00\x00\x00\x00\x00 d \
+		ieeeValues(-Normal)
+	    binary scan \x80\x08\x00\x00\x00\x00\x00\x00 d \
+		ieeeValues(-Subnormal)
+	    binary scan \x80\x00\x00\x00\x00\x00\x00\x00 d \
+		ieeeValues(-0)
+	    binary scan \x00\x00\x00\x00\x00\x00\x00\x00 d \
+		ieeeValues(+0)
+	    binary scan \x00\x08\x00\x00\x00\x00\x00\x00 d \
+		ieeeValues(+Subnormal)
+	    binary scan \x3f\xf0\x00\x00\x00\x00\x00\x00 d \
+		ieeeValues(+Normal)
+	    binary scan \x7f\xf0\x00\x00\x00\x00\x00\x00 d \
+		ieeeValues(+Infinity)
+	    binary scan \x7f\xf8\x00\x00\x00\x00\x00\x00 d \
+		ieeeValues(NaN)
+	    set ieeeValues(littleEndian) 0
+	    return 1
+	}
+	default {
+	    return 0
+	}
+    }
+}
+testConstraint ieeeFloatingPoint [testIEEE]
+
+# First, test all of the integer operators individually.
+
+test expr-old-1.1 {integer operators} {expr -4} -4
+test expr-old-1.2 {integer operators} {expr -(1+4)} -5
+test expr-old-1.3 {integer operators} {expr ~3} -4
+test expr-old-1.4 {integer operators} {expr !2} 0
+test expr-old-1.5 {integer operators} {expr !0} 1
+test expr-old-1.6 {integer operators} {expr 4*6} 24
+test expr-old-1.7 {integer operators} {expr 36/12} 3
+test expr-old-1.8 {integer operators} {expr 27/4} 6
+test expr-old-1.9 {integer operators} {expr 27%4} 3
+test expr-old-1.10 {integer operators} {expr 2+2} 4
+test expr-old-1.11 {integer operators} {expr 2-6} -4
+test expr-old-1.12 {integer operators} {expr 1<<3} 8
+test expr-old-1.13 {integer operators} {expr 0xff>>2} 63
+test expr-old-1.14 {integer operators} {expr -1>>2} -1
+test expr-old-1.15 {integer operators} {expr 3>2} 1
+test expr-old-1.16 {integer operators} {expr 2>2} 0
+test expr-old-1.17 {integer operators} {expr 1>2} 0
+test expr-old-1.18 {integer operators} {expr 3<2} 0
+test expr-old-1.19 {integer operators} {expr 2<2} 0
+test expr-old-1.20 {integer operators} {expr 1<2} 1
+test expr-old-1.21 {integer operators} {expr 3>=2} 1
+test expr-old-1.22 {integer operators} {expr 2>=2} 1
+test expr-old-1.23 {integer operators} {expr 1>=2} 0
+test expr-old-1.24 {integer operators} {expr 3<=2} 0
+test expr-old-1.25 {integer operators} {expr 2<=2} 1
+test expr-old-1.26 {integer operators} {expr 1<=2} 1
+test expr-old-1.27 {integer operators} {expr 3==2} 0
+test expr-old-1.28 {integer operators} {expr 2==2} 1
+test expr-old-1.29 {integer operators} {expr 3!=2} 1
+test expr-old-1.30 {integer operators} {expr 2!=2} 0
+test expr-old-1.31 {integer operators} {expr 7&0x13} 3
+test expr-old-1.32 {integer operators} {expr 7^0x13} 20
+test expr-old-1.33 {integer operators} {expr 7|0x13} 23
+test expr-old-1.34 {integer operators} {expr 0&&1} 0
+test expr-old-1.35 {integer operators} {expr 0&&0} 0
+test expr-old-1.36 {integer operators} {expr 1&&3} 1
+test expr-old-1.37 {integer operators} {expr 0||1} 1
+test expr-old-1.38 {integer operators} {expr 3||0} 1
+test expr-old-1.39 {integer operators} {expr 0||0} 0
+test expr-old-1.40 {integer operators} {expr 3>2?44:66} 44
+test expr-old-1.41 {integer operators} {expr 2>3?44:66} 66
+test expr-old-1.42 {integer operators} {expr 36/5} 7
+test expr-old-1.43 {integer operators} {expr 36%5} 1
+test expr-old-1.44 {integer operators} {expr -36/5} -8
+test expr-old-1.45 {integer operators} {expr -36%5} 4
+test expr-old-1.46 {integer operators} {expr 36/-5} -8
+test expr-old-1.47 {integer operators} {expr 36%-5} -4
+test expr-old-1.48 {integer operators} {expr -36/-5} 7
+test expr-old-1.49 {integer operators} {expr -36%-5} -1
+test expr-old-1.50 {integer operators} {expr +36} 36
+test expr-old-1.51 {integer operators} {expr +--++36} 36
+test expr-old-1.52 {integer operators} {expr +36%+5} 1
+test expr-old-1.53 {integer operators} {
+    unset -nocomplain x
+    set x yes
+    list [expr {1 && $x}] [expr {$x && 1}] \
+         [expr {0 || $x}] [expr {$x || 0}]
+} {1 1 1 1}
+
+# Check the floating-point operators individually, along with
+# automatic conversion to integers where needed.
+
+test expr-old-2.1 {floating-point operators} {expr -4.2} -4.2
+test expr-old-2.2 {floating-point operators} {expr -(1.125+4.25)} -5.375
+test expr-old-2.3 {floating-point operators} {expr +5.7} 5.7
+test expr-old-2.4 {floating-point operators} {expr +--+-62.0} -62.0
+test expr-old-2.5 {floating-point operators} {expr !2.1} 0
+test expr-old-2.6 {floating-point operators} {expr !0.0} 1
+test expr-old-2.7 {floating-point operators} {expr 4.2*6.3} 26.46
+test expr-old-2.8 {floating-point operators} {expr 36.0/12.0} 3.0
+test expr-old-2.9 {floating-point operators} {expr 27/4.0} 6.75
+test expr-old-2.10 {floating-point operators} {expr 2.3+2.1} 4.4
+test expr-old-2.11 {floating-point operators} {expr 2.3-6.5} -4.2
+test expr-old-2.12 {floating-point operators} {expr 3.1>2.1} 1
+test expr-old-2.13 {floating-point operators} {expr {2.1 > 2.1}} 0
+test expr-old-2.14 {floating-point operators} {expr 1.23>2.34e+1} 0
+test expr-old-2.15 {floating-point operators} {expr 3.45<2.34} 0
+test expr-old-2.16 {floating-point operators} {expr 0.002e3<--200e-2} 0
+test expr-old-2.17 {floating-point operators} {expr 1.1<2.1} 1
+test expr-old-2.18 {floating-point operators} {expr 3.1>=2.2} 1
+test expr-old-2.19 {floating-point operators} {expr 2.345>=2.345} 1
+test expr-old-2.20 {floating-point operators} {expr 1.1>=2.2} 0
+test expr-old-2.21 {floating-point operators} {expr 3.0<=2.0} 0
+test expr-old-2.22 {floating-point operators} {expr 2.2<=2.2} 1
+test expr-old-2.23 {floating-point operators} {expr 2.2<=2.2001} 1
+test expr-old-2.24 {floating-point operators} {expr 3.2==2.2} 0
+test expr-old-2.25 {floating-point operators} {expr 2.2==2.2} 1
+test expr-old-2.26 {floating-point operators} {expr 3.2!=2.2} 1
+test expr-old-2.27 {floating-point operators} {expr 2.2!=2.2} 0
+test expr-old-2.28 {floating-point operators} {expr 0.0&&0.0} 0
+test expr-old-2.29 {floating-point operators} {expr 0.0&&1.3} 0
+test expr-old-2.30 {floating-point operators} {expr 1.3&&0.0} 0
+test expr-old-2.31 {floating-point operators} {expr 1.3&&3.3} 1
+test expr-old-2.32 {floating-point operators} {expr 0.0||0.0} 0
+test expr-old-2.33 {floating-point operators} {expr 0.0||1.3} 1
+test expr-old-2.34 {floating-point operators} {expr 1.3||0.0} 1
+test expr-old-2.35 {floating-point operators} {expr 3.3||0.0} 1
+test expr-old-2.36 {floating-point operators} {expr 3.3>2.3?44.3:66.3} 44.3
+test expr-old-2.37 {floating-point operators} {expr 2.3>3.3?44.3:66.3} 66.3
+test expr-old-2.38 {floating-point operators} {
+    list [catch {expr 028.1 + 09.2} msg] $msg
+} {0 37.3}
+
+# Operators that aren't legal on floating-point numbers
+
+test expr-old-3.1 {illegal floating-point operations} {
+    list [catch {expr ~4.0} msg] $msg
+} {1 {can't use floating-point value as operand of "~"}}
+test expr-old-3.2 {illegal floating-point operations} {
+    list [catch {expr 27%4.0} msg] $msg
+} {1 {can't use floating-point value as operand of "%"}}
+test expr-old-3.3 {illegal floating-point operations} {
+    list [catch {expr 27.0%4} msg] $msg
+} {1 {can't use floating-point value as operand of "%"}}
+test expr-old-3.4 {illegal floating-point operations} {
+    list [catch {expr 1.0<<3} msg] $msg
+} {1 {can't use floating-point value as operand of "<<"}}
+test expr-old-3.5 {illegal floating-point operations} {
+    list [catch {expr 3<<1.0} msg] $msg
+} {1 {can't use floating-point value as operand of "<<"}}
+test expr-old-3.6 {illegal floating-point operations} {
+    list [catch {expr 24.0>>3} msg] $msg
+} {1 {can't use floating-point value as operand of ">>"}}
+test expr-old-3.7 {illegal floating-point operations} {
+    list [catch {expr 24>>3.0} msg] $msg
+} {1 {can't use floating-point value as operand of ">>"}}
+test expr-old-3.8 {illegal floating-point operations} {
+    list [catch {expr 24&3.0} msg] $msg
+} {1 {can't use floating-point value as operand of "&"}}
+test expr-old-3.9 {illegal floating-point operations} {
+    list [catch {expr 24.0|3} msg] $msg
+} {1 {can't use floating-point value as operand of "|"}}
+test expr-old-3.10 {illegal floating-point operations} {
+    list [catch {expr 24.0^3} msg] $msg
+} {1 {can't use floating-point value as operand of "^"}}
+
+# Check the string operators individually.
+
+test expr-old-4.1 {string operators} {expr {"abc" > "def"}} 0
+test expr-old-4.2 {string operators} {expr {"def" > "def"}} 0
+test expr-old-4.3 {string operators} {expr {"g" > "def"}} 1
+test expr-old-4.4 {string operators} {expr {"abc" < "abd"}} 1
+test expr-old-4.5 {string operators} {expr {"abd" < "abd"}} 0
+test expr-old-4.6 {string operators} {expr {"abe" < "abd"}} 0
+test expr-old-4.7 {string operators} {expr {"abc" >= "def"}} 0
+test expr-old-4.8 {string operators} {expr {"def" >= "def"}} 1
+test expr-old-4.9 {string operators} {expr {"g" >= "def"}} 1
+test expr-old-4.10 {string operators} {expr {"abc" <= "abd"}} 1
+test expr-old-4.11 {string operators} {expr {"abd" <= "abd"}} 1
+test expr-old-4.12 {string operators} {expr {"abe" <= "abd"}} 0
+test expr-old-4.13 {string operators} {expr {"abc" == "abd"}} 0
+test expr-old-4.14 {string operators} {expr {"abd" == "abd"}} 1
+test expr-old-4.15 {string operators} {expr {"abc" != "abd"}} 1
+test expr-old-4.16 {string operators} {expr {"abd" != "abd"}} 0
+test expr-old-4.17 {string operators} {expr {"0y" < "0x12"}} 0
+test expr-old-4.18 {string operators} {expr {"." < " "}} 0
+test expr-old-4.19 {string operators} {expr {"abc" eq "abd"}} 0
+test expr-old-4.20 {string operators} {expr {"abd" eq "abd"}} 1
+test expr-old-4.21 {string operators} {expr {"abc" ne "abd"}} 1
+test expr-old-4.22 {string operators} {expr {"abd" ne "abd"}} 0
+test expr-old-4.23 {string operators} {expr {"" eq "abd"}} 0
+test expr-old-4.24 {string operators} {expr {"" eq ""}} 1
+test expr-old-4.25 {string operators} {expr {"abd" ne ""}} 1
+test expr-old-4.26 {string operators} {expr {"" ne ""}} 0
+test expr-old-4.27 {string operators} {expr {"longerstring" eq "shorter"}} 0
+test expr-old-4.28 {string operators} {expr {"longerstring" ne "shorter"}} 1
+test expr-old-4.29 {string operators} {expr {"0" == "+"}} 0
+test expr-old-4.30 {string operators} {expr {"0" == "-"}} 0
+test expr-old-4.31 {string operators} {expr {1?"foo":"bar"}} foo
+test expr-old-4.32 {string operators} {expr {0?"foo":"bar"}} bar
+
+# Operators that aren't legal on string operands.
+
+test expr-old-5.1 {illegal string operations} {
+    list [catch {expr {-"a"}} msg] $msg
+} {1 {can't use non-numeric string as operand of "-"}}
+test expr-old-5.2 {illegal string operations} {
+    list [catch {expr {+"a"}} msg] $msg
+} {1 {can't use non-numeric string as operand of "+"}}
+test expr-old-5.3 {illegal string operations} {
+    list [catch {expr {~"a"}} msg] $msg
+} {1 {can't use non-numeric string as operand of "~"}}
+test expr-old-5.4 {illegal string operations} {
+    list [catch {expr {!"a"}} msg] $msg
+} {1 {can't use non-numeric string as operand of "!"}}
+test expr-old-5.5 {illegal string operations} {
+    list [catch {expr {"a"*"b"}} msg] $msg
+} {1 {can't use non-numeric string as operand of "*"}}
+test expr-old-5.6 {illegal string operations} {
+    list [catch {expr {"a"/"b"}} msg] $msg
+} {1 {can't use non-numeric string as operand of "/"}}
+test expr-old-5.7 {illegal string operations} {
+    list [catch {expr {"a"%"b"}} msg] $msg
+} {1 {can't use non-numeric string as operand of "%"}}
+test expr-old-5.8 {illegal string operations} {
+    list [catch {expr {"a"+"b"}} msg] $msg
+} {1 {can't use non-numeric string as operand of "+"}}
+test expr-old-5.9 {illegal string operations} {
+    list [catch {expr {"a"-"b"}} msg] $msg
+} {1 {can't use non-numeric string as operand of "-"}}
+test expr-old-5.10 {illegal string operations} {
+    list [catch {expr {"a"<<"b"}} msg] $msg
+} {1 {can't use non-numeric string as operand of "<<"}}
+test expr-old-5.11 {illegal string operations} {
+    list [catch {expr {"a">>"b"}} msg] $msg
+} {1 {can't use non-numeric string as operand of ">>"}}
+test expr-old-5.12 {illegal string operations} {
+    list [catch {expr {"a"&"b"}} msg] $msg
+} {1 {can't use non-numeric string as operand of "&"}}
+test expr-old-5.13 {illegal string operations} {
+    list [catch {expr {"a"^"b"}} msg] $msg
+} {1 {can't use non-numeric string as operand of "^"}}
+test expr-old-5.14 {illegal string operations} {
+    list [catch {expr {"a"|"b"}} msg] $msg
+} {1 {can't use non-numeric string as operand of "|"}}
+test expr-old-5.15 {illegal string operations} {
+    list [catch {expr {"a"&&"b"}} msg] $msg
+} {1 {expected boolean value but got "a"}}
+test expr-old-5.16 {illegal string operations} {
+    list [catch {expr {"a"||"b"}} msg] $msg
+} {1 {expected boolean value but got "a"}}
+test expr-old-5.17 {illegal string operations} {
+    list [catch {expr {"a"?4:2}} msg] $msg
+} {1 {expected boolean value but got "a"}}
+
+# Check precedence pairwise.
+
+test expr-old-6.1 {precedence checks} {expr -~3} 4
+test expr-old-6.2 {precedence checks} {expr -!3} 0
+test expr-old-6.3 {precedence checks} {expr -~0} 1
+
+test expr-old-7.1 {precedence checks} {expr 2*4/6} 1
+test expr-old-7.2 {precedence checks} {expr 24/6*3} 12
+test expr-old-7.3 {precedence checks} {expr 24/6/2} 2
+
+test expr-old-8.1 {precedence checks} {expr -2+4} 2
+test expr-old-8.2 {precedence checks} {expr -2-4} -6
+test expr-old-8.3 {precedence checks} {expr +2-4} -2
+
+test expr-old-9.1 {precedence checks} {expr 2*3+4} 10
+test expr-old-9.2 {precedence checks} {expr 8/2+4} 8
+test expr-old-9.3 {precedence checks} {expr 8%3+4} 6
+test expr-old-9.4 {precedence checks} {expr 2*3-1} 5
+test expr-old-9.5 {precedence checks} {expr 8/2-1} 3
+test expr-old-9.6 {precedence checks} {expr 8%3-1} 1
+
+test expr-old-10.1 {precedence checks} {expr 6-3-2} 1
+
+test expr-old-11.1 {precedence checks} {expr 7+1>>2} 2
+test expr-old-11.2 {precedence checks} {expr 7+1<<2} 32
+test expr-old-11.3 {precedence checks} {expr 7>>3-2} 3
+test expr-old-11.4 {precedence checks} {expr 7<<3-2} 14
+
+test expr-old-12.1 {precedence checks} {expr 6>>1>4} 0
+test expr-old-12.2 {precedence checks} {expr 6>>1<2} 0
+test expr-old-12.3 {precedence checks} {expr 6>>1>=3} 1
+test expr-old-12.4 {precedence checks} {expr 6>>1<=2} 0
+test expr-old-12.5 {precedence checks} {expr 6<<1>5} 1
+test expr-old-12.6 {precedence checks} {expr 6<<1<5} 0
+test expr-old-12.7 {precedence checks} {expr 5<=6<<1} 1
+test expr-old-12.8 {precedence checks} {expr 5>=6<<1} 0
+
+test expr-old-13.1 {precedence checks} {expr 2<3<4} 1
+test expr-old-13.2 {precedence checks} {expr 0<4>2} 0
+test expr-old-13.3 {precedence checks} {expr 4>2<1} 0
+test expr-old-13.4 {precedence checks} {expr 4>3>2} 0
+test expr-old-13.5 {precedence checks} {expr 4>3>=2} 0
+test expr-old-13.6 {precedence checks} {expr 4>=3>2} 0
+test expr-old-13.7 {precedence checks} {expr 4>=3>=2} 0
+test expr-old-13.8 {precedence checks} {expr 0<=4>=2} 0
+test expr-old-13.9 {precedence checks} {expr 4>=2<=0} 0
+test expr-old-13.10 {precedence checks} {expr 2<=3<=4} 1
+
+test expr-old-14.1 {precedence checks} {expr 1==4>3} 1
+test expr-old-14.2 {precedence checks} {expr 0!=4>3} 1
+test expr-old-14.3 {precedence checks} {expr 1==3<4} 1
+test expr-old-14.4 {precedence checks} {expr 0!=3<4} 1
+test expr-old-14.5 {precedence checks} {expr 1==4>=3} 1
+test expr-old-14.6 {precedence checks} {expr 0!=4>=3} 1
+test expr-old-14.7 {precedence checks} {expr 1==3<=4} 1
+test expr-old-14.8 {precedence checks} {expr 0!=3<=4} 1
+test expr-old-14.9 {precedence checks} {expr 1eq4>3} 1
+test expr-old-14.10 {precedence checks} {expr 0ne4>3} 1
+test expr-old-14.11 {precedence checks} {expr 1eq3<4} 1
+test expr-old-14.12 {precedence checks} {expr 0ne3<4} 1
+test expr-old-14.13 {precedence checks} {expr 1eq4>=3} 1
+test expr-old-14.14 {precedence checks} {expr 0ne4>=3} 1
+test expr-old-14.15 {precedence checks} {expr 1eq3<=4} 1
+test expr-old-14.16 {precedence checks} {expr 0ne3<=4} 1
+
+test expr-old-15.1 {precedence checks} {expr 1==3==3} 0
+test expr-old-15.2 {precedence checks} {expr 3==3!=2} 1
+test expr-old-15.3 {precedence checks} {expr 2!=3==3} 0
+test expr-old-15.4 {precedence checks} {expr 2!=1!=1} 0
+test expr-old-15.5 {precedence checks} {expr 1eq3eq3} 0
+test expr-old-15.6 {precedence checks} {expr 3eq3ne2} 1
+test expr-old-15.7 {precedence checks} {expr 2ne3eq3} 0
+test expr-old-15.8 {precedence checks} {expr 2ne1ne1} 0
+
+test expr-old-16.1 {precedence checks} {expr 2&3eq2} 0
+test expr-old-16.2 {precedence checks} {expr 1&3ne3} 0
+test expr-old-16.3 {precedence checks} {expr 2&3eq2} 0
+test expr-old-16.4 {precedence checks} {expr 1&3ne3} 0
+
+test expr-old-17.1 {precedence checks} {expr 7&3^0x10} 19
+test expr-old-17.2 {precedence checks} {expr 7^0x10&3} 7
+
+test expr-old-18.1 {precedence checks} {expr 7^0x10|3} 23
+test expr-old-18.2 {precedence checks} {expr 7|0x10^3} 23
+
+test expr-old-19.1 {precedence checks} {expr 7|3&&1} 1
+test expr-old-19.2 {precedence checks} {expr 1&&3|7} 1
+test expr-old-19.3 {precedence checks} {expr 0&&1||1} 1
+test expr-old-19.4 {precedence checks} {expr 1||1&&0} 1
+
+test expr-old-20.1 {precedence checks} {expr 1||0?3:4} 3
+test expr-old-20.2 {precedence checks} {expr 1?0:4||1} 0
+test expr-old-20.3 {precedence checks} {expr 1?2:0?3:4} 2
+test expr-old-20.4 {precedence checks} {expr 0?2:0?3:4} 4
+test expr-old-20.5 {precedence checks} {expr 1?2?3:4:0} 3
+test expr-old-20.6 {precedence checks} {expr 0?2?3:4:0} 0
+
+# Parentheses.
+
+test expr-old-21.1 {parenthesization} {expr (2+4)*6} 36
+test expr-old-21.2 {parenthesization} {expr (1?0:4)||1} 1
+test expr-old-21.3 {parenthesization} {expr +(3-4)} -1
+
+# Embedded commands and variable names.
+
+set a 16 
+test expr-old-22.1 {embedded variables} {expr {2*$a}} 32 
+test expr-old-22.2 {embedded variables} {
+    set x -5
+    set y 10
+    expr {$x + $y}
+} {5} 
+test expr-old-22.3 {embedded variables} {
+    set x "  -5"
+    set y "  +10"
+    expr {$x + $y}
+} {5}
+test expr-old-22.4 {embedded commands and variables} {expr {[set a] - 14}} 2
+test expr-old-22.5 {embedded commands and variables} {
+    list [catch {expr {12 - [bad_command_name]}} msg] $msg
+} {1 {invalid command name "bad_command_name"}}
+
+# Double-quotes and things inside them.
+
+test expr-old-23.1 {double quotes} {expr {"abc"}} abc
+test expr-old-23.2 {double quotes} {
+    set a 189
+    expr {"$a.bc"}
+} 189.bc
+test expr-old-23.3 {double quotes} {
+    set b2 xyx
+    expr {"$b2$b2$b2.[set b2].[set b2]"}
+} xyxxyxxyx.xyx.xyx
+test expr-old-23.4 {double quotes} {expr {"11\}\}22"}} 11}}22
+test expr-old-23.5 {double quotes} {expr {"\*bc"}} {*bc}
+test expr-old-23.6 {double quotes} {
+    unset -nocomplain bogus__
+    list [catch {expr {"$bogus__"}} msg] $msg
+} {1 {can't read "bogus__": no such variable}}
+test expr-old-23.7 {double quotes} {
+    list [catch {expr {"a[error Testing]bc"}} msg] $msg
+} {1 Testing}
+test expr-old-23.8 {double quotes} {
+    list [catch {expr {"12398712938788234-1298379" != ""}} msg] $msg
+} {0 1}
+
+# Numbers in various bases.
+
+test expr-old-24.1 {numbers in different bases} {expr 0x20} 32
+test expr-old-24.2 {numbers in different bases} {expr 0o15} 13
+
+# Conversions between various data types.
+
+test expr-old-25.1 {type conversions} {expr 2+2.5} 4.5
+test expr-old-25.2 {type conversions} {expr 2.5+2} 4.5
+test expr-old-25.3 {type conversions} {expr 2-2.5} -0.5
+test expr-old-25.4 {type conversions} {expr 2/2.5} 0.8
+test expr-old-25.5 {type conversions} {expr 2>2.5} 0
+test expr-old-25.6 {type conversions} {expr 2.5>2} 1
+test expr-old-25.7 {type conversions} {expr 2<2.5} 1
+test expr-old-25.8 {type conversions} {expr 2>=2.5} 0
+test expr-old-25.9 {type conversions} {expr 2<=2.5} 1
+test expr-old-25.10 {type conversions} {expr 2==2.5} 0
+test expr-old-25.11 {type conversions} {expr 2!=2.5} 1
+test expr-old-25.12 {type conversions} {expr 2>"ab"} 0
+test expr-old-25.13 {type conversions} {expr {2>" "}} 1
+test expr-old-25.14 {type conversions} {expr {"24.1a" > 24.1}} 1
+test expr-old-25.15 {type conversions} {expr {24.1 > "24.1a"}} 0
+test expr-old-25.16 {type conversions} {expr 2+2.5} 4.5
+test expr-old-25.17 {type conversions} {expr 2+2.5} 4.5
+test expr-old-25.18 {type conversions} {expr 2.0e2} 200.0
+test expr-old-25.19 {type conversions} {expr 2.0e15} 2000000000000000.0
+test expr-old-25.20 {type conversions} {expr 10.0} 10.0
+
+# Various error conditions.
+
+test expr-old-26.1 {error conditions} {
+    list [catch {expr 2+"a"} msg] $msg
+} {1 {can't use non-numeric string as operand of "+"}}
+test expr-old-26.2 {error conditions} -body {
+    expr 2+4*
+} -returnCodes error -match glob -result *
+test expr-old-26.3 {error conditions} -body {
+    expr 2+4*(
+} -returnCodes error -match glob -result *
+unset -nocomplain _non_existent_
+test expr-old-26.4 {error conditions} {
+    list [catch {expr 2+$_non_existent_} msg] $msg
+} {1 {can't read "_non_existent_": no such variable}}
+set a xx
+test expr-old-26.5 {error conditions} {
+    list [catch {expr {2+$a}} msg] $msg
+} {1 {can't use non-numeric string as operand of "+"}}
+test expr-old-26.6 {error conditions} {
+    list [catch {expr {2+[set a]}} msg] $msg
+} {1 {can't use non-numeric string as operand of "+"}}
+test expr-old-26.7 {error conditions} -body {
+    expr {2+(4}
+} -returnCodes error -match glob -result *
+test expr-old-26.8 {error conditions} {
+    list [catch {expr 2/0} msg] $msg $errorCode
+} {1 {divide by zero} {ARITH DIVZERO {divide by zero}}}
+test expr-old-26.9 {error conditions} {
+    list [catch {expr 2%0} msg] $msg $errorCode
+} {1 {divide by zero} {ARITH DIVZERO {divide by zero}}}
+test expr-old-26.10a {error conditions} !ieeeFloatingPoint {
+    list [catch {expr 2.0/0.0} msg] $msg $errorCode
+} {1 {divide by zero} {ARITH DIVZERO {divide by zero}}}
+test expr-old-26.10b {error conditions} ieeeFloatingPoint {
+    list [catch {expr 2.0/0.0} msg] $msg
+} {0 Inf}
+test expr-old-26.11 {error conditions} -body {
+    expr 2#
+} -returnCodes error -match glob -result *
+test expr-old-26.12 {error conditions} -body {
+    expr a.b
+} -returnCodes error -match glob -result *
+test expr-old-26.13 {error conditions} {
+    list [catch {expr {"a"/"b"}} msg] $msg
+} {1 {can't use non-numeric string as operand of "/"}}
+test expr-old-26.14 {error conditions} -body {
+    expr 2:3
+} -returnCodes error -match glob -result *
+test expr-old-26.15 {error conditions} -body {
+    expr a@b
+} -returnCodes error -match glob -result *
+test expr-old-26.16 {error conditions} {
+    list [catch {expr a[b} msg] $msg
+} {1 {missing close-bracket}}
+test expr-old-26.17 {error conditions} -body {
+    expr a`b
+} -returnCodes error -match glob -result *
+test expr-old-26.18 {error conditions} -body {
+    expr \"a\"\{b
+} -returnCodes error -match glob -result *
+test expr-old-26.19 {error conditions} -body {
+    expr a
+} -returnCodes error -match glob -result *
+test expr-old-26.20 {error conditions} {
+    list [catch expr msg] $msg
+} {1 {wrong # args: should be "expr arg ?arg ...?"}}
+
+# Cancelled evaluation.
+
+test expr-old-27.1 {cancelled evaluation} {
+    set a 1
+    expr {0&&[set a 2]}
+    set a
+} 1
+test expr-old-27.2 {cancelled evaluation} {
+    set a 1
+    expr {1||[set a 2]}
+    set a
+} 1
+test expr-old-27.3 {cancelled evaluation} {
+    set a 1
+    expr {0?[set a 2]:1}
+    set a
+} 1
+test expr-old-27.4 {cancelled evaluation} {
+    set a 1
+    expr {1?2:[set a 2]}
+    set a
+} 1
+unset -nocomplain x
+test expr-old-27.5 {cancelled evaluation} {
+    list [catch {expr {[info exists x] && $x}} msg] $msg
+} {0 0}
+test expr-old-27.6 {cancelled evaluation} {
+    list [catch {expr {0 && [concat $x]}} msg] $msg
+} {0 0}
+test expr-old-27.7 {cancelled evaluation} {
+    set one 1
+    list [catch {expr {1 || 1/$one}} msg] $msg
+} {0 1}
+test expr-old-27.8 {cancelled evaluation} {
+    list [catch {expr {1 || -"string"}} msg] $msg
+} {0 1}
+test expr-old-27.9 {cancelled evaluation} {
+    list [catch {expr {1 || ("string" * ("x" && "y"))}} msg] $msg
+} {0 1}
+test expr-old-27.10 {cancelled evaluation} {
+    set x -1.0
+    list [catch {expr {($x > 0) ? round(log($x)) : 0}} msg] $msg
+} {0 0}
+test expr-old-27.11 {cancelled evaluation} -body {
+    expr {0 && foo}
+} -returnCodes error -match glob -result *
+test expr-old-27.12 {cancelled evaluation} -body {
+    expr {0 ? 1 : foo}
+} -returnCodes error -match glob -result *
+
+# Tcl_ExprBool as used in "if" statements
+
+test expr-old-28.1 {Tcl_ExprBoolean usage} {
+    set a 1
+    if {2} {set a 2}
+    set a
+} 2
+test expr-old-28.2 {Tcl_ExprBoolean usage} {
+    set a 1
+    if {0} {set a 2}
+    set a
+} 1
+test expr-old-28.3 {Tcl_ExprBoolean usage} {
+    set a 1
+    if {1.2} {set a 2}
+    set a
+} 2
+test expr-old-28.4 {Tcl_ExprBoolean usage} {
+    set a 1
+    if {-1.1} {set a 2}
+    set a
+} 2
+test expr-old-28.5 {Tcl_ExprBoolean usage} {
+    set a 1
+    if {0.0} {set a 2}
+    set a
+} 1
+test expr-old-28.6 {Tcl_ExprBoolean usage} {
+    set a 1
+    if {"YES"} {set a 2}
+    set a
+} 2
+test expr-old-28.7 {Tcl_ExprBoolean usage} {
+    set a 1
+    if {"no"} {set a 2}
+    set a
+} 1
+test expr-old-28.8 {Tcl_ExprBoolean usage} {
+    set a 1
+    if {"true"} {set a 2}
+    set a
+} 2
+test expr-old-28.9 {Tcl_ExprBoolean usage} {
+    set a 1
+    if {"fAlse"} {set a 2}
+    set a
+} 1
+test expr-old-28.10 {Tcl_ExprBoolean usage} {
+    set a 1
+    if {"on"} {set a 2}
+    set a
+} 2
+test expr-old-28.11 {Tcl_ExprBoolean usage} {
+    set a 1
+    if {"Off"} {set a 2}
+    set a
+} 1
+test expr-old-28.12 {Tcl_ExprBool usage} {
+    list [catch {if {"abc"} {}} msg] $msg
+} {1 {expected boolean value but got "abc"}}
+test expr-old-28.13 {Tcl_ExprBool usage} {
+    list [catch {if {"ogle"} {}} msg] $msg
+} {1 {expected boolean value but got "ogle"}}
+test expr-old-28.14 {Tcl_ExprBool usage} {
+    list [catch {if {"o"} {}} msg] $msg
+} {1 {expected boolean value but got "o"}}
+
+# Operands enclosed in braces
+
+test expr-old-29.1 {braces} {expr {{abc}}} abc
+test expr-old-29.2 {braces} {expr {{0o0010}}} 8
+test expr-old-29.3 {braces} {expr {{3.1200000}}} 3.12
+test expr-old-29.4 {braces} {expr {{a{b}{1 {2 3}}c}}} "a{b}{1 {2 3}}c"
+test expr-old-29.5 {braces} -body {
+    expr "\{abc"
+} -returnCodes error -match glob -result *
+
+# Very long values
+
+test expr-old-30.1 {long values} {
+    set a "0000 1111 2222 3333 4444"
+    set a "$a | $a | $a | $a | $a"
+    set a "$a || $a || $a || $a || $a"
+    expr {$a}
+} {0000 1111 2222 3333 4444 | 0000 1111 2222 3333 4444 | 0000 1111 2222 3333 4444 | 0000 1111 2222 3333 4444 | 0000 1111 2222 3333 4444 || 0000 1111 2222 3333 4444 | 0000 1111 2222 3333 4444 | 0000 1111 2222 3333 4444 | 0000 1111 2222 3333 4444 | 0000 1111 2222 3333 4444 || 0000 1111 2222 3333 4444 | 0000 1111 2222 3333 4444 | 0000 1111 2222 3333 4444 | 0000 1111 2222 3333 4444 | 0000 1111 2222 3333 4444 || 0000 1111 2222 3333 4444 | 0000 1111 2222 3333 4444 | 0000 1111 2222 3333 4444 | 0000 1111 2222 3333 4444 | 0000 1111 2222 3333 4444 || 0000 1111 2222 3333 4444 | 0000 1111 2222 3333 4444 | 0000 1111 2222 3333 4444 | 0000 1111 2222 3333 4444 | 0000 1111 2222 3333 4444}
+test expr-old-30.2 {long values} {
+    set a "000000000000000000000000000000"
+    set a "$a$a$a$a$a$a$a$a$a$a$a$a$a$a$a$a${a}5"
+    expr $a
+} 5
+
+# Expressions spanning multiple arguments
+
+test expr-old-31.1 {multiple arguments to expr command} {
+    expr 4 + ( 6 *12) -3
+} 73
+test expr-old-31.2 {multiple arguments to expr command} -body {
+    expr 2 + (3 + 4
+} -returnCodes error -match glob -result *
+test expr-old-31.3 {multiple arguments to expr command} -body {
+    expr 2 + 3 +
+} -returnCodes error -match glob -result *
+test expr-old-31.4 {multiple arguments to expr command} -body {
+    expr 2 + 3 )
+} -returnCodes error -match glob -result *
+
+# Math functions
+
+test expr-old-32.1 {math functions in expressions} {
+    format %.6g [expr acos(0.5)]
+} {1.0472}
+test expr-old-32.2 {math functions in expressions} {
+    format %.6g [expr asin(0.5)]
+} {0.523599}
+test expr-old-32.3 {math functions in expressions} {
+    format %.6g [expr atan(1.0)]
+} {0.785398}
+test expr-old-32.4 {math functions in expressions} {
+    format %.6g [expr atan2(2.0, 2.0)]
+} {0.785398}
+test expr-old-32.5 {math functions in expressions} {
+    format %.6g [expr ceil(1.999)]
+} {2}
+test expr-old-32.6 {math functions in expressions} {
+    format %.6g [expr cos(.1)]
+} {0.995004}
+test expr-old-32.7 {math functions in expressions} {
+    format %.6g [expr cosh(.1)]
+} {1.005}
+test expr-old-32.8 {math functions in expressions} {
+    format %.6g [expr exp(1.0)]
+} {2.71828}
+test expr-old-32.9 {math functions in expressions} {
+    format %.6g [expr floor(2.000)]
+} {2}
+test expr-old-32.10 {math functions in expressions} {
+    format %.6g [expr floor(2.001)]
+} {2}
+test expr-old-32.11 {math functions in expressions} {
+    format %.6g [expr fmod(7.3, 3.2)]
+} {0.9}
+test expr-old-32.12 {math functions in expressions} {
+    format %.6g [expr hypot(3.0, 4.0)]
+} {5}
+test expr-old-32.13 {math functions in expressions} {
+    format %.6g [expr log(2.8)]
+} {1.02962}
+test expr-old-32.14 {math functions in expressions} {
+    format %.6g [expr log10(2.8)]
+} {0.447158}
+test expr-old-32.15 {math functions in expressions} {
+    format %.6g [expr pow(2.1, 3.1)]
+} {9.97424}
+test expr-old-32.16 {math functions in expressions} {
+    format %.6g [expr sin(.1)]
+} {0.0998334}
+test expr-old-32.17 {math functions in expressions} {
+    format %.6g [expr sinh(.1)]
+} {0.100167}
+test expr-old-32.18 {math functions in expressions} {
+    format %.6g [expr sqrt(2.0)]
+} {1.41421}
+test expr-old-32.19 {math functions in expressions} {
+    format %.6g [expr tan(0.8)]
+} {1.02964}
+test expr-old-32.20 {math functions in expressions} {
+    format %.6g [expr tanh(0.8)]
+} {0.664037}
+test expr-old-32.21 {math functions in expressions} {
+    format %.6g [expr abs(-1.8)]
+} {1.8}
+test expr-old-32.22 {math functions in expressions} {
+    expr abs(10.0)
+} {10.0}
+test expr-old-32.23 {math functions in expressions} {
+    format %.6g [expr abs(-4)]
+} {4}
+test expr-old-32.24 {math functions in expressions} {
+    format %.6g [expr abs(66)]
+} {66}
+
+test expr-old-32.25a {math functions in expressions} {
+    expr abs(0x8000000000000000)
+} [expr 1<<63]
+
+test expr-old-32.25b {math functions in expressions} {
+    expr abs(0x80000000)
+} 2147483648
+
+test expr-old-32.26 {math functions in expressions} {
+    expr double(1)
+} {1.0}
+test expr-old-32.27 {math functions in expressions} {
+    expr double(1.1)
+} {1.1}
+test expr-old-32.28 {math functions in expressions} {
+    expr int(1)
+} {1}
+test expr-old-32.29 {math functions in expressions} {
+    expr int(1.4)
+} {1}
+test expr-old-32.30 {math functions in expressions} {
+    expr int(1.6)
+} {1}
+test expr-old-32.31 {math functions in expressions} {
+    expr int(-1.4)
+} {-1}
+test expr-old-32.32 {math functions in expressions} {
+    expr int(-1.6)
+} {-1}
+test expr-old-32.33 {math functions in expressions} {
+    expr int(1e60)
+} 0
+test expr-old-32.34 {math functions in expressions} {
+    expr int(-1e60)
+} 0
+test expr-old-32.35 {math functions in expressions} {
+    expr round(1.49)
+} {1}
+test expr-old-32.36 {math functions in expressions} {
+    expr round(1.51)
+} {2}
+test expr-old-32.37 {math functions in expressions} {
+    expr round(-1.49)
+} {-1}
+test expr-old-32.38 {math functions in expressions} {
+    expr round(-1.51)
+} {-2}
+test expr-old-32.39 {math functions in expressions} {
+    expr round(1e60)
+} 999999999999999949387135297074018866963645011013410073083904
+test expr-old-32.40 {math functions in expressions} {
+    expr round(-1e60)
+} -999999999999999949387135297074018866963645011013410073083904
+test expr-old-32.41 {math functions in expressions} {
+    list [catch {expr pow(1.0 + 3.0 - 2, .8 * 5)} msg] $msg
+} {0 16.0}
+test expr-old-32.42 {math functions in expressions} {
+    list [catch {expr hypot(5*.8,3)} msg] $msg
+} {0 5.0}
+test expr-old-32.43 {math functions in expressions} testmathfunctions {
+    expr 2*T1()
+} 246
+test expr-old-32.44 {math functions in expressions} testmathfunctions {
+    expr T2()*3
+} 1035
+test expr-old-32.45 {math functions in expressions} {
+    expr (0 <= rand()) && (rand() < 1)
+} {1}
+test expr-old-32.46 {math functions in expressions} -body {
+    list [catch {expr rand(24)} msg] $msg
+} -match glob -result {1 {too many arguments for math function*}}
+test expr-old-32.47 {math functions in expressions} -body {
+    list [catch {expr srand()} msg] $msg
+} -match glob -result {1 {too few arguments for math function*}}
+test expr-old-32.48 {math functions in expressions} -body {
+    expr srand(3.79)
+} -returnCodes error -match glob -result *
+test expr-old-32.49 {math functions in expressions} -body {
+    expr srand("")
+} -returnCodes error -match glob -result *
+test expr-old-32.50 {math functions in expressions} {
+    set result [expr round(srand(12345) * 1000)]
+    for {set i 0} {$i < 10} {incr i} {
+	lappend result [expr round(rand() * 1000)]
+    }
+    set result
+} {97 834 948 36 12 51 766 585 914 784 333}
+test expr-old-32.51 {math functions in expressions} -body {
+    expr {srand([lindex "6ty" 0])}
+} -returnCodes error -match glob -result *
+test expr-old-32.52 {math functions in expressions} {
+    expr {srand(int(1<<37)) < 1}
+} {1}
+test expr-old-32.53 {math functions in expressions} {
+    expr {srand((1<<31) - 1) > 0}
+} {1}
+
+test expr-old-33.1 {conversions and fancy args to math functions} {
+    expr hypot ( 3 , 4 )
+} 5.0
+test expr-old-33.2 {conversions and fancy args to math functions} {
+    expr hypot ( (2.0+1.0) , 4 )
+} 5.0
+test expr-old-33.3 {conversions and fancy args to math functions} {
+    expr hypot ( 3 , (3.0 + 1.0) )
+} 5.0
+test expr-old-33.4 {conversions and fancy args to math functions} {
+    format %.6g [expr cos(acos(0.1))]
+} 0.1
+
+test expr-old-34.1 {errors in math functions} -body {
+    list [catch {expr func_2(1.0)} msg] $msg
+} -match glob -result {1 {* "*func_2"}}
+test expr-old-34.2 {errors in math functions} -body {
+    expr func|(1.0)
+} -returnCodes error -match glob -result *
+test expr-old-34.3 {errors in math functions} {
+    list [catch {expr {hypot("a b", 2.0)}} msg] $msg
+} {1 {expected floating-point number but got "a b"}}
+test expr-old-34.4 {errors in math functions} -body {
+    expr hypot(1.0 2.0)
+} -returnCodes error -match glob -result *
+test expr-old-34.5 {errors in math functions} -body {
+    expr hypot(1.0, 2.0
+} -returnCodes error -match glob -result *
+test expr-old-34.6 {errors in math functions} -body {
+    expr hypot(1.0 ,
+} -returnCodes error -match glob -result *
+test expr-old-34.7 {errors in math functions} -body {
+    list [catch {expr hypot(1.0)} msg] $msg
+} -match glob -result {1 {too few arguments for math function*}}
+test expr-old-34.8 {errors in math functions} -body {
+    list [catch {expr hypot(1.0, 2.0, 3.0)} msg] $msg
+} -match glob -result {1 {too many arguments for math function*}}
+test expr-old-34.9 {errors in math functions} {
+    list [catch {expr acos(-2.0)} msg] $msg $errorCode
+} {1 {domain error: argument not in valid range} {ARITH DOMAIN {domain error: argument not in valid range}}}
+test expr-old-34.10 {errors in math functions} {
+    list [catch {expr pow(-3, 1000001)} msg] $msg
+} {0 -Inf}
+test expr-old-34.11a {errors in math functions} !ieeeFloatingPoint {
+    list [catch {expr pow(3, 1000001)} msg] $msg $errorCode
+} {1 {floating-point value too large to represent} {ARITH OVERFLOW {floating-point value too large to represent}}}
+test expr-old-34.11b {errors in math functions} ieeeFloatingPoint {
+    list [catch {expr pow(3, 1000001)} msg] $msg
+} {0 Inf}
+test expr-old-34.12a {errors in math functions} !ieeeFloatingPoint {
+    list [catch {expr -14.0*exp(100000)} msg] $msg $errorCode
+} {1 {floating-point value too large to represent} {ARITH OVERFLOW {floating-point value too large to represent}}}
+test expr-old-34.12b {errors in math functions} ieeeFloatingPoint {
+    list [catch {expr -14.0*exp(100000)} msg] $msg
+} {0 -Inf}
+test expr-old-34.13 {errors in math functions} {
+    expr wide(1.0e30)
+} 5076964154930102272
+test expr-old-34.14 {errors in math functions} {
+    expr wide(-1.0e30)
+} -5076964154930102272
+test expr-old-34.15 {errors in math functions} {
+    expr round(1.0e30)
+} 1000000000000000019884624838656
+test expr-old-34.16 {errors in math functions} {
+    expr round(-1.0e30)
+} -1000000000000000019884624838656
+test expr-old-34.17 {errors in math functions} -constraints testmathfunctions \
+    -body {
+        list [catch {expr T1(4)} msg] $msg
+    } -match glob -result {1 {too many arguments for math function*}}
+
+test expr-old-36.1 {ExprLooksLikeInt procedure} -body {
+    expr 0o289
+} -returnCodes error -match glob -result {*invalid octal number*}
+test expr-old-36.2 {ExprLooksLikeInt procedure} {
+    set x 0o289
+    list [catch {expr {$x+1}} msg] $msg
+} {1 {can't use invalid octal number as operand of "+"}}
+test expr-old-36.3 {ExprLooksLikeInt procedure} {
+    list [catch {expr 0289.1} msg] $msg
+} {0 289.1}
+test expr-old-36.4 {ExprLooksLikeInt procedure} {
+    set x 0289.1
+    list [catch {expr {$x+1}} msg] $msg
+} {0 290.1}
+test expr-old-36.5 {ExprLooksLikeInt procedure} {
+    set x {  +22}
+    list [catch {expr {$x+1}} msg] $msg
+} {0 23}
+test expr-old-36.6 {ExprLooksLikeInt procedure} {
+    set x {	-22}
+    list [catch {expr {$x+1}} msg] $msg
+} {0 -21}
+test expr-old-36.7 {ExprLooksLikeInt procedure} {
+    list [catch {expr nan} msg] $msg
+} {1 {domain error: argument not in valid range}}
+test expr-old-36.8 {ExprLooksLikeInt procedure} {
+    list [catch {expr 78e1} msg] $msg
+} {0 780.0}
+test expr-old-36.9 {ExprLooksLikeInt procedure} {
+    list [catch {expr 24E1} msg] $msg
+} {0 240.0}
+test expr-old-36.10 {ExprLooksLikeInt procedure} -body {
+    expr 78e
+} -returnCodes error -match glob -result *
+
+# test for [Bug #542588]
+test expr-old-36.11 {ExprLooksLikeInt procedure} {
+    # define a "too large integer"; this one works also for 64bit arith
+    set x 665802003400000000000000
+    expr {$x+1}
+} 665802003400000000000001
+
+# tests for [Bug #587140]
+test expr-old-36.12 {ExprLooksLikeInt procedure} {
+    set x "10;"
+    list [catch {expr {$x+1}} msg] $msg
+} {1 {can't use non-numeric string as operand of "+"}}
+test expr-old-36.13 {ExprLooksLikeInt procedure} {
+    set x " +"
+    list [catch {expr {$x+1}} msg] $msg
+} {1 {can't use non-numeric string as operand of "+"}}
+test expr-old-36.14 {ExprLooksLikeInt procedure} {
+    set x "123456789012345678901234567890 "
+    expr {$x+1}
+} 123456789012345678901234567891
+test expr-old-36.15 {ExprLooksLikeInt procedure} {
+    set x "0o99 "
+    list [catch {expr {$x+1}} msg] $msg
+} {1 {can't use invalid octal number as operand of "+"}}
+test expr-old-36.16 {ExprLooksLikeInt procedure} {
+    set x " 0xffffffffffffffffffffffffffffffffffffff  "
+    expr {$x+1}
+} [expr 0x100000000000000000000000000000000000000]
+
+test expr-old-37.1 {Check that Tcl_ExprLong doesn't modify interpreter result if no error} testexprlong {
+    testexprlong 4+1
+} {This is a result: 5}
+#Check for [Bug 1109484]
+test expr-old-37.2 {Tcl_ExprLong handles wide ints gracefully} testexprlong {
+    testexprlong wide(1)+2
+} {This is a result: 3}
+
+test expr-old-37.3 {Tcl_ExprLong on the empty string} testexprlong {
+    testexprlong ""
+} {This is a result: 0}
+test expr-old-37.4 {Tcl_ExprLong coerces doubles} testexprlong {
+    testexprlong 3+.14159
+} {This is a result: 3}
+test expr-old-37.5 {Tcl_ExprLong handles overflows} {testexprlong longIs32bit} {
+    testexprlong 0x80000000
+} {This is a result: -2147483648}
+test expr-old-37.6 {Tcl_ExprLong handles overflows} {testexprlong longIs32bit} {
+    testexprlong 0xffffffff
+} {This is a result: -1}
+test expr-old-37.7 {Tcl_ExprLong handles overflows} \
+    -constraints {testexprlong longIs32bit} \
+    -match glob \
+    -body {
+	list [catch {testexprlong 0x100000000} result] $result
+    } \
+    -result {1 {integer value too large to represent*}}
+test expr-old-37.8 {Tcl_ExprLong handles overflows} testexprlong {
+    testexprlong -0x80000000
+} {This is a result: -2147483648}
+test expr-old-37.9 {Tcl_ExprLong handles overflows} {testexprlong longIs32bit} {
+    testexprlong -0xffffffff
+} {This is a result: 1}
+test expr-old-37.10 {Tcl_ExprLong handles overflows} \
+    -constraints {testexprlong longIs32bit} \
+    -match glob \
+    -body {
+	list [catch {testexprlong -0x100000000} result] $result
+    } \
+    -result {1 {integer value too large to represent*}}
+test expr-old-37.11 {Tcl_ExprLong handles overflows} {testexprlong longIs32bit}  {
+    testexprlong 2147483648.
+} {This is a result: -2147483648}
+test expr-old-37.12 {Tcl_ExprLong handles overflows} {testexprlong longIs32bit} {
+    testexprlong 4294967295.
+} {This is a result: -1}
+test expr-old-37.13 {Tcl_ExprLong handles overflows} \
+    -constraints {testexprlong longIs32bit} \
+    -match glob \
+    -body {
+	list [catch {testexprlong 4294967296.} result] $result
+    } \
+    -result {1 {integer value too large to represent*}}
+test expr-old-37.14 {Tcl_ExprLong handles overflows} testexprlong {
+    testexprlong -2147483648.
+} {This is a result: -2147483648}
+test expr-old-37.15 {Tcl_ExprLong handles overflows} {testexprlong longIs32bit} {
+    testexprlong -4294967295.
+} {This is a result: 1}
+test expr-old-37.16 {Tcl_ExprLong handles overflows} \
+    -constraints {testexprlong longIs32bit} \
+    -match glob \
+    -body {
+	list [catch {testexprlong 4294967296.} result] $result
+    } \
+    -result {1 {integer value too large to represent*}}
+
+test expr-old-37.17 {Check that Tcl_ExprDouble doesn't modify interpreter result if no error} testexprdouble {
+    testexprdouble 4.+1.
+} {This is a result: 5.0}
+#Check for [Bug 1109484]
+test expr-old-37.18 {Tcl_ExprDouble on the empty string} testexprdouble {
+    testexprdouble ""
+} {This is a result: 0.0}
+test expr-old-37.19 {Tcl_ExprDouble coerces wides} testexprdouble {
+    testexprdouble 1[string repeat 0 17]
+} {This is a result: 1e+17}
+test expr-old-37.20 {Tcl_ExprDouble coerces bignums} testexprdouble {
+    testexprdouble 1[string repeat 0 38]
+} {This is a result: 1e+38}
+test expr-old-37.21 {Tcl_ExprDouble handles overflows} testexprdouble {
+    testexprdouble 17976931348623157[string repeat 0 292].
+} {This is a result: 1.7976931348623157e+308}
+test expr-old-37.22 {Tcl_ExprDouble handles overflows that look like int} \
+    testexprdouble {
+	testexprdouble 17976931348623157[string repeat 0 292]
+    } {This is a result: 1.7976931348623157e+308}
+test expr-old-37.23 {Tcl_ExprDouble handles overflows} \
+    ieeeFloatingPoint&&testexprdouble {
+	testexprdouble 17976931348623165[string repeat 0 292].
+    } {This is a result: Inf}
+test expr-old-37.24 {Tcl_ExprDouble handles overflows that look like int} \
+    ieeeFloatingPoint&&testexprdouble {
+	testexprdouble 17976931348623165[string repeat 0 292]
+    } {This is a result: Inf}
+test expr-old-37.25 {Tcl_ExprDouble and NaN} \
+    {ieeeFloatingPoint testexprdouble} {
+	list [catch {testexprdouble 0.0/0.0} result] $result
+    } {1 {domain error: argument not in valid range}}
+    
+test expr-old-38.1 {Verify Tcl_ExprString's basic operation} -constraints {testexprstring} -body {
+    list [testexprstring "1+4"] [testexprstring "2*3+4.2"] \
+	    [catch {testexprstring "1+"} msg] $msg
+} -match glob -result {5 10.2 1 *}
+test expr-old-38.2 {Tcl_ExprString} testexprstring {
+    # This one is "magical"
+    testexprstring {}
+} 0
+test expr-old-38.3 {Tcl_ExprString} -constraints testexprstring -body {
+    testexprstring { }
+} -returnCodes error -match glob -result *
+
+#
+# Test for bug #908375: rounding numbers that do not fit in a
+# long but do fit in a wide
+#
+
+test expr-old-39.1 {Rounding with wide result} {
+    set x 1.0e10
+    set y [expr $x + 0.1]
+    catch {
+	set x [list [expr {$x == round($y)}] [expr $x == -round(-$y)]]
+    }
+    set x
+} {1 1}
+unset -nocomplain x y
+
+#
+# TIP #255 min and max math functions
+#
+
+test expr-old-40.1 {min math function} -body {
+    expr {min(0)}
+} -result 0
+test expr-old-40.2 {min math function} -body {
+    expr {min(0.0)}
+} -result 0.0
+test expr-old-40.3 {min math function} -body {
+    list [catch {expr {min()}} msg] $msg
+} -result {1 {too few arguments to math function "min"}}
+test expr-old-40.4 {min math function} -body {
+    expr {min(wide(-1) << 30, 4.5, -10)}
+} -result [expr {wide(-1) << 30}]
+test expr-old-40.5 {min math function} -body {
+    expr {min("a", 0)}
+} -returnCodes error -match glob -result *
+test expr-old-40.6 {min math function} -body {
+    expr {min(300, "0xFF")}
+} -result 255
+
+test expr-old-41.1 {max math function} -body {
+    expr {max(0)}
+} -result 0
+test expr-old-41.2 {max math function} -body {
+    expr {max(0.0)}
+} -result 0.0
+test expr-old-41.3 {max math function} -body {
+    list [catch {expr {max()}} msg] $msg
+} -result {1 {too few arguments to math function "max"}}
+test expr-old-41.4 {max math function} -body {
+    expr {max(wide(1) << 30, 4.5, -10)}
+} -result [expr {wide(1) << 30}]
+test expr-old-41.5 {max math function} -body {
+    expr {max("a", 0)}
+} -returnCodes error -match glob -result *
+test expr-old-41.6 {max math function} -body {
+    expr {max(200, "0xFF")}
+} -result 255
+
+# Special test for Pentium arithmetic bug of 1994:
+
+if {(4195835.0 - (4195835.0/3145727.0)*3145727.0) == 256.0} {
+    puts "Warning: this machine contains a defective Pentium processor"
+    puts "that performs arithmetic incorrectly.  I recommend that you"
+    puts "call Intel customer service immediately at 1-800-628-8686"
+    puts "to request a replacement processor."
+}
+
+# cleanup
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/tests/expr.test b/tests/expr.test
new file mode 100644
index 0000000..4c03262
--- /dev/null
+++ b/tests/expr.test
@@ -0,0 +1,7194 @@
+# Commands covered: expr
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors.  No output means no errors were found.
+#
+# Copyright (c) 1996-1997 Sun Microsystems, Inc.
+# Copyright (c) 1998-2000 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+    package require tcltest 2.1
+    namespace import -force ::tcltest::*
+}
+
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
+
+testConstraint testmathfunctions [expr {
+    ([catch {expr T1()} msg] != 1) || ($msg ne {invalid command name "tcl::mathfunc::T1"})
+}]
+
+# Determine if "long int" type is a 32 bit number and if the wide
+# type is a 64 bit number on this machine.
+
+testConstraint longIs32bit [expr {int(0x80000000) < 0}]
+testConstraint longIs64bit [expr {int(0x8000000000000000) < 0}]
+testConstraint wideIs64bit \
+	[expr {(wide(0x80000000) > 0) && (wide(0x8000000000000000) < 0)}]
+
+# Big test for correct ordering of data in [expr]
+
+proc testIEEE {} {
+    variable ieeeValues
+    binary scan [binary format dd -1.0 1.0] c* c
+    switch -exact -- $c {
+	{0 0 0 0 0 0 -16 -65 0 0 0 0 0 0 -16 63} {
+	    # little endian
+	    binary scan \x00\x00\x00\x00\x00\x00\xf0\xff d \
+		ieeeValues(-Infinity)
+	    binary scan \x00\x00\x00\x00\x00\x00\xf0\xbf d \
+		ieeeValues(-Normal)
+	    binary scan \x00\x00\x00\x00\x00\x00\x08\x80 d \
+		ieeeValues(-Subnormal)
+	    binary scan \x00\x00\x00\x00\x00\x00\x00\x80 d \
+		ieeeValues(-0)
+	    binary scan \x00\x00\x00\x00\x00\x00\x00\x00 d \
+		ieeeValues(+0)
+	    binary scan \x00\x00\x00\x00\x00\x00\x08\x00 d \
+		ieeeValues(+Subnormal)
+	    binary scan \x00\x00\x00\x00\x00\x00\xf0\x3f d \
+		ieeeValues(+Normal)
+	    binary scan \x00\x00\x00\x00\x00\x00\xf0\x7f d \
+		ieeeValues(+Infinity)
+	    binary scan \x00\x00\x00\x00\x00\x00\xf8\x7f d \
+		ieeeValues(NaN)
+	    binary scan \x00\x00\x00\x00\x00\x00\xf8\xff d \
+		ieeeValues(-NaN)
+	    set ieeeValues(littleEndian) 1
+	    return 1
+	}
+	{-65 -16 0 0 0 0 0 0 63 -16 0 0 0 0 0 0} {
+	    binary scan \xff\xf0\x00\x00\x00\x00\x00\x00 d \
+		ieeeValues(-Infinity)
+	    binary scan \xbf\xf0\x00\x00\x00\x00\x00\x00 d \
+		ieeeValues(-Normal)
+	    binary scan \x80\x08\x00\x00\x00\x00\x00\x00 d \
+		ieeeValues(-Subnormal)
+	    binary scan \x80\x00\x00\x00\x00\x00\x00\x00 d \
+		ieeeValues(-0)
+	    binary scan \x00\x00\x00\x00\x00\x00\x00\x00 d \
+		ieeeValues(+0)
+	    binary scan \x00\x08\x00\x00\x00\x00\x00\x00 d \
+		ieeeValues(+Subnormal)
+	    binary scan \x3f\xf0\x00\x00\x00\x00\x00\x00 d \
+		ieeeValues(+Normal)
+	    binary scan \x7f\xf0\x00\x00\x00\x00\x00\x00 d \
+		ieeeValues(+Infinity)
+	    binary scan \x7f\xf8\x00\x00\x00\x00\x00\x00 d \
+		ieeeValues(NaN)
+	    binary scan \xff\xf8\x00\x00\x00\x00\x00\x00 d \
+		ieeeValues(-NaN)
+	    set ieeeValues(littleEndian) 0
+	    return 1
+	}
+	default {
+	    return 0
+	}
+    }
+}
+
+testConstraint ieeeFloatingPoint [testIEEE]
+# procedures used below
+
+proc put_hello_char {c} {
+    global a
+    append a [format %c $c]
+    return $c
+}
+proc hello_world {} {
+    global a
+    set a ""
+    set L1 [set l0 [set h_1 [set q 0]]]
+    for {put_hello_char [expr [put_hello_char [expr [set h 7]*10+2]]+29]} {$l0?[put_hello_char $l0]
+        :!$h_1} {put_hello_char $ll;expr {$L1==2?[set ll [expr 32+0-0+[set bar 0]]]:0}} {expr {[incr L1]==[expr 1+([string length "abc"]-[string length "abc"])]
+        ?[set ll [set l0 [expr 54<<1]]]:$ll==108&&$L1<3?
+        [incr ll [expr 1|1<<1]; set ll $ll; set ll $ll; set ll $ll; set ll $ll; set l0 [expr ([string length "abc"]-[string length "abc"])+([string length "abc"]-[string length "abc"])-([string length "abc"]-[string length "abc"])+([string length "abc"]-[string length "abc"])]; set l0; set l0 $l0; set l0; set l0]:$L1==4&&$ll==32?[set ll [expr 19+$h1+([string length "abc"]-[string length "abc"])-([string length "abc"]-[string length "abc"])+([string length "abc"]-[string length "abc"])-([string length "abc"]-[string length "abc"])+[set foo [expr ([string length "abc"]-[string length "abc"])+([string length "abc"]-[string length "abc"])+([string length "abc"]-[string length "abc"])]]]]
+        :[set q [expr $q-$h1+([string length "abc"]-[string length "abc"])-([string length "abc"]-[string length "abc"])]]};expr {$L1==5?[incr ll -8; set ll $ll; set ll]:$q&&$h1&&1};expr {$L1==4+2
+        ?[incr ll 3]:[expr ([string length "abc"]-[string length "abc"])+1]};expr {$ll==($h<<4)+2+0&&$L1!=6?[incr ll -6]:[set h1 [expr 100+([string length "abc"]-[string length "abc"])-([string length "abc"]-[string length "abc"])]]}
+        expr {$L1!=1<<3?[incr q [expr ([string length "abc"]-[string length "abc"])-1]]:[set h_1 [set ll $h1]]}
+    }
+    set a
+}
+
+proc 12days {a b c} {
+    global xxx
+    expr {1<$a?[expr {$a<3?[12days -79 -13 [string range $c [12days -87 \
+	[expr 1-$b] [string range $c [12days -86 0 [string range $c 1 end]] \
+	end]] end]]:1};expr {$a<$b?[12days [expr $a+1] $b $c]:3};expr {[12days \
+	-94 [expr $a-27] $c]&&$a==2?$b<13?[12days 2 [expr $b+1] "%s %d %d\n"]:9
+	:16}]:$a<0?$a<-72?[12days $b $a "@n'+,#'/*\{\}w+/w#cdnr/+,\{\}r/*de\}+,/*\{*+,/w\{%+,/w#q#n+,/#\{l+,/n\{n+,/+#n+,/#;#q#n+,/+k#;*+,/'r :'d*'3,\}\{w+K w'K:'+\}e#';dq#'l q#'+d'K#!/+k#;q#'r\}eKK#\}w'r\}eKK\{nl\]'/#;#q#n')\{)#\}w')\{)\{nl\]'/+#n';d\}rw' i;# )\{nl\]!/n\{n#'; r\{#w'r nc\{nl\]'/#\{l,+'K \{rw' iK\{;\[\{nl\]'/w#q#n'wk nw' iwk\{KK\{nl\]!/w\{%'l##w#' i; :\{nl\]'/*\{q#'ld;r'\}\{nlwb!/*de\}'c ;;\{nl'-\{\}rw\]'/+,\}##'*\}#nc,',#nw\]'/+kd'+e\}+;#'rdq#w! nr'/ ') \}+\}\{rl#'\{n' ')# \}'+\}##(!!/"]
+	:$a<-50?[string compare [format %c $b] [string index $c 0]]==0?[append \
+	xxx [string index $c 31];scan [string index $c 31] %c x;set x]
+	:[12days -65 $b [string range $c 1 end]]:[12days [expr ([string compare \
+	[string index $c 0] "/"]==0)+$a] $b [string range $c 1 end]]:0<$a
+	?[12days 2 2 "%s"]:[string compare [string index $c 0] "/"]==0||
+	[12days 0 [12days -61 [scan [string index $c 0] %c x; set x] \
+	"!ek;dc i@bK'(q)-\[w\]*%n+r3#l,\{\}:\nuwloca-O;m .vpbks,fxntdCeghiry"] \
+	[string range $c 1 end]]}
+}
+proc do_twelve_days {} {
+    global xxx
+    set xxx ""
+    12days 1 1 1
+    set result [string length $xxx]
+    unset xxx
+    return $result
+}
+
+# start of tests
+
+catch {unset a b i x}
+
+test expr-1.1 {TclCompileExprCmd: no expression} {
+    list [catch {expr  } msg] $msg
+} {1 {wrong # args: should be "expr arg ?arg ...?"}}
+test expr-1.2 {TclCompileExprCmd: one expression word} {
+    expr -25
+} -25
+test expr-1.3 {TclCompileExprCmd: two expression words} {
+    expr -8.2   -6
+} -14.2
+test expr-1.4 {TclCompileExprCmd: five expression words} {
+    expr 20 - 5 +10 -7
+} 18
+test expr-1.5 {TclCompileExprCmd: quoted expression word} {
+    expr "0005"
+} 5
+test expr-1.6 {TclCompileExprCmd: quoted expression word} {
+    catch {expr "0005"zxy} msg
+    set msg
+} {extra characters after close-quote}
+test expr-1.7 {TclCompileExprCmd: expression word in braces} {
+    expr {-0005}
+} -5
+test expr-1.8 {TclCompileExprCmd: expression word in braces} {
+    expr {{-0x1234}}
+} -4660
+test expr-1.9 {TclCompileExprCmd: expression word in braces} {
+    catch {expr {-0005}foo} msg
+    set msg
+} {extra characters after close-brace}
+test expr-1.10 {TclCompileExprCmd: other expression word in braces} {
+    expr 4*[llength "6 2"]
+} 8
+test expr-1.11 {TclCompileExprCmd: expression word terminated by ;} {
+    expr 4*[llength "6 2"];
+} 8
+test expr-1.12 {TclCompileExprCmd: inlined expr (in "catch") inside other catch} {
+    set a xxx
+    catch {
+	# Might not be a number
+	set a [expr 10*$a]
+    }
+} 1
+test expr-1.13 {TclCompileExprCmd: second level of substitutions in expr not in braces with single var reference} {
+    set a xxx
+    set x 27;  set bool {$x};  if $bool {set a foo}
+    set a
+} foo
+test expr-1.14 {TclCompileExprCmd: second level of substitutions in expr with comparison as top-level operator} {
+    set a xxx
+    set x 2;  set b {$x};  set a [expr $b == 2]
+    set a
+} 1
+test expr-1.15 {TclCompileExprCmd: second level of substitutions in expr with comparison as top-level operator} {
+    set a xxx
+    set x 2;  set b {$x};  set a [expr $b eq 2]
+    set a
+} 1
+
+test expr-2.1 {TclCompileExpr: are builtin functions registered?} {
+    expr double(5*[llength "6 2"])
+} 10.0
+test expr-2.2 {TclCompileExpr: error in expr} -body {
+    expr 2***3
+} -returnCodes error -match glob -result *
+test expr-2.3 {TclCompileExpr: junk after legal expr} -body {
+    expr 7*[llength "a b"]foo
+} -returnCodes error -match glob -result *
+test expr-2.4 {TclCompileExpr: numeric expr string rep == formatted int rep} {
+    expr {0001}
+} 1
+
+test expr-3.1 {CompileCondExpr: just lor expr} {expr 3||0} 1
+test expr-3.2 {CompileCondExpr: error in lor expr} -body {
+    expr x||3
+} -returnCodes error -match glob -result *
+test expr-3.3 {CompileCondExpr: test true arm} {expr 3>2?44:66} 44
+test expr-3.4 {CompileCondExpr: error compiling true arm} -body {
+    expr 3>2?2***3:66
+} -returnCodes error -match glob -result *
+test expr-3.5 {CompileCondExpr: test false arm} {expr 2>3?44:66} 66
+test expr-3.6 {CompileCondExpr: error compiling false arm} -body {
+    expr 2>3?44:2***3
+} -returnCodes error -match glob -result *
+test expr-3.7 {CompileCondExpr: long arms & nested cond exprs} {
+    hello_world
+} {Hello world}
+test expr-3.8 {CompileCondExpr: long arms & nested cond exprs} unix {
+    # Fails with a stack overflow on threaded Windows builds
+    do_twelve_days
+} 2358
+
+test expr-4.1 {CompileLorExpr: just land expr} {expr 1.3&&3.3} 1
+test expr-4.2 {CompileLorExpr: error in land expr} -body {
+    expr x&&3
+} -returnCodes error -match glob -result *
+test expr-4.3 {CompileLorExpr: simple lor exprs} {expr 0||1.0} 1
+test expr-4.4 {CompileLorExpr: simple lor exprs} {expr 3.0||0.0} 1
+test expr-4.5 {CompileLorExpr: simple lor exprs} {expr 0||0||1} 1
+test expr-4.6 {CompileLorExpr: error compiling lor arm} -body {
+    expr 2***3||4.0
+} -returnCodes error -match glob -result *
+test expr-4.7 {CompileLorExpr: error compiling lor arm} -body {
+    expr 1.3||2***3
+} -returnCodes error -match glob -result *
+test expr-4.8 {CompileLorExpr: error compiling lor arms} {
+    list [catch {expr {"a"||"b"}} msg] $msg
+} {1 {expected boolean value but got "a"}}
+test expr-4.9 {CompileLorExpr: long lor arm} {
+    set a "abcdefghijkl"
+    set i 7
+    expr {[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]] || [string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]] || [string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]] || [string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]}
+} 1
+test expr-4.10 {CompileLorExpr: error compiling ! operand} {
+    list [catch {expr {!"a"}} msg] $msg
+} {1 {can't use non-numeric string as operand of "!"}}
+test expr-4.11 {CompileLorExpr: error compiling land arms} {
+    list [catch {expr {"a"||0}} msg] $msg
+} {1 {expected boolean value but got "a"}}
+test expr-4.12 {CompileLorExpr: error compiling land arms} {
+    list [catch {expr {0||"a"}} msg] $msg
+} {1 {expected boolean value but got "a"}}
+
+test expr-5.1 {CompileLandExpr: just bitor expr} {expr 7|0x13} 23
+test expr-5.2 {CompileLandExpr: error in bitor expr} -body {
+    expr x|3
+} -returnCodes error -match glob -result *
+test expr-5.3 {CompileLandExpr: simple land exprs} {expr 0&&1.0} 0
+test expr-5.4 {CompileLandExpr: simple land exprs} {expr 0&&0} 0
+test expr-5.5 {CompileLandExpr: simple land exprs} {expr 3.0&&1.2} 1
+test expr-5.6 {CompileLandExpr: simple land exprs} {expr 1&&1&&2} 1
+test expr-5.7 {CompileLandExpr: error compiling land arm} -body {
+    expr 2***3&&4.0
+} -returnCodes error -match glob -result *
+test expr-5.8 {CompileLandExpr: error compiling land arm} -body {
+    expr 1.3&&2***3
+} -returnCodes error -match glob -result *
+test expr-5.9 {CompileLandExpr: error compiling land arm} {
+    list [catch {expr {"a"&&"b"}} msg] $msg
+} {1 {expected boolean value but got "a"}}
+test expr-5.10 {CompileLandExpr: long land arms} {
+    set a "abcdefghijkl"
+    set i 7
+    expr {[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]] && [string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]] && [string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]] && [string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]^[string compare [format %c 103] [string index $a $i]]^[string compare [format %c 105] [string index $a $i]]}
+} 1
+
+test expr-6.1 {CompileBitXorExpr: just bitand expr} {expr 7&0x13} 3
+test expr-6.2 {CompileBitXorExpr: error in bitand expr} -body {
+    expr x|3
+} -returnCodes error -match glob -result *
+test expr-6.3 {CompileBitXorExpr: simple bitxor exprs} {expr 7^0x13} 20
+test expr-6.4 {CompileBitXorExpr: simple bitxor exprs} {expr 3^0x10} 19
+test expr-6.5 {CompileBitXorExpr: simple bitxor exprs} {expr 0^7} 7
+test expr-6.6 {CompileBitXorExpr: simple bitxor exprs} {expr -1^7} -8
+test expr-6.7 {CompileBitXorExpr: error compiling bitxor arm} -body {
+    expr 2***3|6
+} -returnCodes error -match glob -result *
+test expr-6.8 {CompileBitXorExpr: error compiling bitxor arm} -body {
+    expr 2^x
+} -returnCodes error -match glob -result *
+test expr-6.9 {CompileBitXorExpr: runtime error in bitxor arm} {
+    list [catch {expr {24.0^3}} msg] $msg
+} {1 {can't use floating-point value as operand of "^"}}
+test expr-6.10 {CompileBitXorExpr: runtime error in bitxor arm} {
+    list [catch {expr {"a"^"b"}} msg] $msg
+} {1 {can't use non-numeric string as operand of "^"}}
+
+test expr-7.1 {CompileBitAndExpr: just equality expr} {expr 3==2} 0
+test expr-7.2 {CompileBitAndExpr: just equality expr} {expr 2.0==2} 1
+test expr-7.3 {CompileBitAndExpr: just equality expr} {expr 3.2!=2.2} 1
+test expr-7.4 {CompileBitAndExpr: just equality expr} {expr {"abc" == "abd"}} 0
+test expr-7.5 {CompileBitAndExpr: error in equality expr} -body {
+    expr x==3
+} -returnCodes error -match glob -result *
+test expr-7.6 {CompileBitAndExpr: simple bitand exprs} {expr 7&0x13} 3
+test expr-7.7 {CompileBitAndExpr: simple bitand exprs} {expr 0xf2&0x53} 82
+test expr-7.8 {CompileBitAndExpr: simple bitand exprs} {expr 3&6} 2
+test expr-7.9 {CompileBitAndExpr: simple bitand exprs} {expr -1&-7} -7
+test expr-7.10 {CompileBitAndExpr: error compiling bitand arm} -body {
+    expr 2***3&6
+} -returnCodes error -match glob -result *
+test expr-7.11 {CompileBitAndExpr: error compiling bitand arm} -body {
+    expr 2&x
+} -returnCodes error -match glob -result *
+test expr-7.12 {CompileBitAndExpr: runtime error in bitand arm} {
+    list [catch {expr {24.0&3}} msg] $msg
+} {1 {can't use floating-point value as operand of "&"}}
+test expr-7.13 {CompileBitAndExpr: runtime error in bitand arm} {
+    list [catch {expr {"a"&"b"}} msg] $msg
+} {1 {can't use non-numeric string as operand of "&"}}
+test expr-7.14 {CompileBitAndExpr: equality expr} {expr 3eq2} 0
+test expr-7.18 {CompileBitAndExpr: equality expr} {expr {"abc" eq "abd"}} 0
+test expr-7.20 {CompileBitAndExpr: error in equality expr} -body {
+    expr xne3
+} -returnCodes error -match glob -result *
+
+test expr-8.1 {CompileEqualityExpr: just relational expr} {expr 3>=2} 1
+test expr-8.2 {CompileEqualityExpr: just relational expr} {expr 2<=2.1} 1
+test expr-8.3 {CompileEqualityExpr: just relational expr} {expr 3.2>"2.2"} 1
+test expr-8.4 {CompileEqualityExpr: just relational expr} {expr {"0y"<"0x12"}} 0
+test expr-8.5 {CompileEqualityExpr: error in relational expr} -body {
+    expr x>3
+} -returnCodes error -match glob -result *
+test expr-8.6 {CompileEqualityExpr: simple equality exprs} {expr 7==0x13} 0
+test expr-8.7 {CompileEqualityExpr: simple equality exprs} {expr -0xf2!=0x53} 1
+test expr-8.8 {CompileEqualityExpr: simple equality exprs} {expr {"12398712938788234-1298379" != ""}} 1
+test expr-8.9 {CompileEqualityExpr: simple equality exprs} {expr -1!="abc"} 1
+test expr-8.10 {CompileEqualityExpr: error compiling equality arm} -body {
+    expr 2***3==6
+} -returnCodes error -match glob -result *
+test expr-8.11 {CompileEqualityExpr: error compiling equality arm} -body {
+    expr 2!=x
+} -returnCodes error -match glob -result *
+test expr-8.12 {CompileBitAndExpr: equality expr} {expr {"a"eq"a"}} 1
+test expr-8.13 {CompileBitAndExpr: equality expr} {expr {"\374" eq [set s \u00fc]}} 1
+test expr-8.14 {CompileBitAndExpr: equality expr} {expr 3eq2} 0
+test expr-8.15 {CompileBitAndExpr: equality expr} {expr 2.0eq2} 0
+test expr-8.16 {CompileBitAndExpr: equality expr} {expr 3.2ne2.2} 1
+test expr-8.17 {CompileBitAndExpr: equality expr} {expr 01eq1} 0
+test expr-8.18 {CompileBitAndExpr: equality expr} {expr {"abc" eq "abd"}} 0
+test expr-8.19 {CompileBitAndExpr: equality expr} {expr {"abc" ne "abd"}} 1
+test expr-8.20 {CompileBitAndExpr: error in equality expr} -body {
+    expr x ne3
+} -returnCodes error -match glob -result *
+test expr-8.21 {CompileBitAndExpr: error in equality expr} -body {
+    # These should be ""ed to avoid the error
+    expr a eq b
+} -returnCodes error -match glob -result *
+test expr-8.22 {CompileBitAndExpr: error in equality expr} -body {
+    expr {false eqfalse}
+} -returnCodes error -match glob -result *
+test expr-8.23 {CompileBitAndExpr: error in equality expr} -body {
+    expr {false nefalse}
+} -returnCodes error -match glob -result *
+test expr-8.24 {CompileEqualityExpr: simple equality exprs} {
+    set x 12398712938788234
+    expr {$x == 100}
+} 0
+test expr-8.25 {CompileEqualityExpr: simple equality exprs} {
+    expr {"0x12 " == "0x12"}
+} 1
+test expr-8.26 {CompileEqualityExpr: simple equality exprs} {
+    expr {"0x12 " eq "0x12"}
+} 0
+test expr-8.27 {CompileEqualityExpr: simple equality exprs} {
+    expr {"1.0e100000000" == "0.0"}
+} 0
+test expr-8.28 {CompileEqualityExpr: just relational expr} {
+    expr {"0y" == "0x0"}
+} 0
+test expr-8.29 {CompileEqualityExpr: just relational expr} {
+    # Compare original strings from variables.
+    set v1 "0y"
+    set v2 "0x12"
+    expr {$v1 < $v2}
+} 0
+test expr-8.30 {CompileEqualityExpr: simple equality exprs} {
+    expr {"fake" != "bob"}
+} 1
+test expr-8.31 {expr edge cases} -body {
+    expr {1e}
+} -returnCodes error -match glob -result *
+test expr-8.32 {expr edge cases} -body {
+    expr {1E}
+} -returnCodes error -match glob -result *
+test expr-8.33 {expr edge cases} -body {
+    expr {1e+}
+} -returnCodes error -match glob -result *
+test expr-8.34 {expr edge cases} -body {
+    expr {1E+}
+} -returnCodes error -match glob -result *
+test expr-8.35 {expr edge cases} -body {
+    expr {1ea}
+} -returnCodes error -match glob -result *
+
+test expr-9.1 {CompileRelationalExpr: just shift expr} {expr 3<<2} 12
+test expr-9.2 {CompileRelationalExpr: just shift expr} {expr 0xff>>2} 63
+test expr-9.3 {CompileRelationalExpr: just shift expr} {expr -1>>2} -1
+test expr-9.4 {CompileRelationalExpr: just shift expr} {expr {1<<3}} 8
+test expr-9.5a {CompileRelationalExpr: shift expr producing LONG_MIN} longIs64bit {
+    expr {int(1<<63)}
+} -9223372036854775808
+test expr-9.5b {CompileRelationalExpr: shift expr producing LONG_MIN} longIs32bit {
+    expr {int(1<<31)}
+} -2147483648
+test expr-9.6 {CompileRelationalExpr: error in shift expr} -body {
+    expr x>>3
+} -returnCodes error -match glob -result *
+test expr-9.7 {CompileRelationalExpr: simple relational exprs} {expr 0xff>=+0x3} 1
+test expr-9.8 {CompileRelationalExpr: simple relational exprs} {expr -0xf2<0x3} 1
+test expr-9.9 {CompileRelationalExpr: error compiling relational arm} -body {
+    expr 2***3>6
+} -returnCodes error -match glob -result *
+test expr-9.10 {CompileRelationalExpr: error compiling relational arm} -body {
+    expr 2<x
+} -returnCodes error -match glob -result *
+
+test expr-10.1 {CompileShiftExpr: just add expr} {expr 4+-2} 2
+test expr-10.2 {CompileShiftExpr: just add expr} {expr 0xff-2} 253
+test expr-10.3 {CompileShiftExpr: just add expr} {expr -1--2} 1
+test expr-10.4 {CompileShiftExpr: just add expr} {expr 1-0o123} -82
+test expr-10.5 {CompileShiftExpr: error in add expr} -body {
+    expr x+3
+} -returnCodes error -match glob -result *
+test expr-10.6 {CompileShiftExpr: simple shift exprs} {expr 0xff>>0x3} 31
+test expr-10.7 {CompileShiftExpr: simple shift exprs} {expr -0xf2<<0x3} -1936
+test expr-10.8 {CompileShiftExpr: error compiling shift arm} -body {
+    expr 2***3>>6
+} -returnCodes error -match glob -result *
+test expr-10.9 {CompileShiftExpr: error compiling shift arm} -body {
+    expr 2<<x
+} -returnCodes error -match glob -result *
+test expr-10.10 {CompileShiftExpr: runtime error} {
+    list [catch {expr {24.0>>43}} msg] $msg
+} {1 {can't use floating-point value as operand of ">>"}}
+test expr-10.11 {CompileShiftExpr: runtime error} {
+    list [catch {expr {"a"<<"b"}} msg] $msg
+} {1 {can't use non-numeric string as operand of "<<"}}
+
+test expr-11.1 {CompileAddExpr: just multiply expr} {expr 4*-2} -8
+test expr-11.2 {CompileAddExpr: just multiply expr} {expr 0xff%2} 1
+test expr-11.3 {CompileAddExpr: just multiply expr} {expr -1/2} -1
+test expr-11.4 {CompileAddExpr: just multiply expr} {expr 7891%0o123} 6
+test expr-11.5 {CompileAddExpr: error in multiply expr} -body {
+    expr x*3
+} -returnCodes error -match glob -result *
+test expr-11.6 {CompileAddExpr: simple add exprs} {expr 0xff++0x3} 258
+test expr-11.7 {CompileAddExpr: simple add exprs} {expr -0xf2--0x3} -239
+test expr-11.8 {CompileAddExpr: error compiling add arm} -body {
+    expr 2***3+6
+} -returnCodes error -match glob -result *
+test expr-11.9 {CompileAddExpr: error compiling add arm} -body {
+    expr 2-x
+} -returnCodes error -match glob -result *
+test expr-11.10 {CompileAddExpr: runtime error} {
+    list [catch {expr {24.0+"xx"}} msg] $msg
+} {1 {can't use non-numeric string as operand of "+"}}
+test expr-11.11 {CompileAddExpr: runtime error} {
+    list [catch {expr {"a"-"b"}} msg] $msg
+} {1 {can't use non-numeric string as operand of "-"}}
+test expr-11.12 {CompileAddExpr: runtime error} {
+    list [catch {expr {3/0}} msg] $msg
+} {1 {divide by zero}}
+test expr-11.13a {CompileAddExpr: runtime error} !ieeeFloatingPoint {
+    list [catch {expr {2.3/0.0}} msg] $msg
+} {1 {divide by zero}}
+test expr-11.13b {CompileAddExpr: runtime error} ieeeFloatingPoint {
+    list [catch {expr {2.3/0.0}} msg] $msg
+} {0 Inf}
+
+test expr-12.1 {CompileMultiplyExpr: just unary expr} {expr ~4} -5
+test expr-12.2 {CompileMultiplyExpr: just unary expr} {expr --5} 5
+test expr-12.3 {CompileMultiplyExpr: just unary expr} {expr !27} 0
+test expr-12.4 {CompileMultiplyExpr: just unary expr} {expr ~0xff00ff} -16711936
+test expr-12.5 {CompileMultiplyExpr: error in unary expr} -body {
+    expr ~x
+} -returnCodes error -match glob -result *
+test expr-12.6 {CompileMultiplyExpr: simple multiply exprs} {expr 0xff*0x3} 765
+test expr-12.7 {CompileMultiplyExpr: simple multiply exprs} {expr -0xf2%-0x3} -2
+test expr-12.8 {CompileMultiplyExpr: error compiling multiply arm} -body {
+    expr 2*3%%6
+} -returnCodes error -match glob -result *
+test expr-12.9 {CompileMultiplyExpr: error compiling multiply arm} -body {
+    expr 2*x
+} -returnCodes error -match glob -result *
+test expr-12.10 {CompileMultiplyExpr: runtime error} {
+    list [catch {expr {24.0*"xx"}} msg] $msg
+} {1 {can't use non-numeric string as operand of "*"}}
+test expr-12.11 {CompileMultiplyExpr: runtime error} {
+    list [catch {expr {"a"/"b"}} msg] $msg
+} {1 {can't use non-numeric string as operand of "/"}}
+
+test expr-13.1 {CompileUnaryExpr: unary exprs} {expr -0xff} -255
+test expr-13.2 {CompileUnaryExpr: unary exprs} {expr +0o00123} 83
+test expr-13.3 {CompileUnaryExpr: unary exprs} {expr +--++36} 36
+test expr-13.4 {CompileUnaryExpr: unary exprs} {expr !2} 0
+test expr-13.5 {CompileUnaryExpr: unary exprs} {expr +--+-62.0} -62.0
+test expr-13.6 {CompileUnaryExpr: unary exprs} {expr !0.0} 1
+test expr-13.7 {CompileUnaryExpr: unary exprs} {expr !0xef} 0
+test expr-13.8 {CompileUnaryExpr: error compiling unary expr} -body {
+    expr ~x
+} -returnCodes error -match glob -result *
+test expr-13.9 {CompileUnaryExpr: error compiling unary expr} -body {
+    expr !1.x
+} -returnCodes error -match glob -result *
+test expr-13.10 {CompileUnaryExpr: runtime error} {
+    list [catch {expr {~"xx"}} msg] $msg
+} {1 {can't use non-numeric string as operand of "~"}}
+test expr-13.11 {CompileUnaryExpr: runtime error} {
+    list [catch {expr ~4.0} msg] $msg
+} {1 {can't use floating-point value as operand of "~"}}
+test expr-13.12 {CompileUnaryExpr: just primary expr} {expr 0x123} 291
+test expr-13.13 {CompileUnaryExpr: just primary expr} {
+    set a 27
+    expr $a
+} 27
+test expr-13.14 {CompileUnaryExpr: just primary expr} {
+    expr double(27)
+} 27.0
+test expr-13.15 {CompileUnaryExpr: just primary expr} {expr "123"} 123
+test expr-13.16 {CompileUnaryExpr: error in primary expr} {
+    catch {expr [set]} msg
+    set msg
+} {wrong # args: should be "set varName ?newValue?"}
+test expr-13.17 {CompileUnaryExpr: negating non-numeric boolean literals} {
+    set a1 yes; set a0 no; set b1 true; set b0 false
+    list [expr {!$a1}] [expr {!$a0}] [expr {!$b1}] [expr {!$b0}]
+} {0 1 0 1}
+
+test expr-14.1 {CompilePrimaryExpr: literal primary} {expr 1} 1
+test expr-14.2 {CompilePrimaryExpr: literal primary} {expr 123} 123
+test expr-14.3 {CompilePrimaryExpr: literal primary} {expr 0xff} 255
+test expr-14.4 {CompilePrimaryExpr: literal primary} {expr 0o0010} 8
+test expr-14.5 {CompilePrimaryExpr: literal primary} {expr 62.0} 62.0
+test expr-14.6 {CompilePrimaryExpr: literal primary} {
+    expr 3.1400000
+} 3.14
+test expr-14.7 {CompilePrimaryExpr: literal primary} {expr {{abcde}<{abcdef}}} 1
+test expr-14.8 {CompilePrimaryExpr: literal primary} {expr {{abc\
+def} < {abcdef}}} 1
+test expr-14.9 {CompilePrimaryExpr: literal primary} {expr {{abc\tde} > {abc\tdef}}} 0
+test expr-14.10 {CompilePrimaryExpr: literal primary} {expr {{123}}} 123
+test expr-14.11 {CompilePrimaryExpr: var reference primary} {
+    set i 789
+    list [expr {$i}] [expr $i]
+} {789 789}
+test expr-14.12 {CompilePrimaryExpr: var reference primary} {
+    set i {789}    ;# test expr's aggressive conversion to numeric semantics
+    list [expr {$i}] [expr $i]
+} {789 789}
+test expr-14.13 {CompilePrimaryExpr: var reference primary} {
+    catch {unset a}
+    set a(foo) foo
+    set a(bar) bar
+    set a(123) 123
+    set result ""
+    lappend result [expr $a(123)] [expr {$a(bar)<$a(foo)}]
+    catch {unset a}
+    set result
+} {123 1}
+test expr-14.14 {CompilePrimaryExpr: var reference primary} {
+    set i 123    ;# test "$var.0" floating point conversion hack
+    list [expr $i] [expr $i.0] [expr $i.0/12.0]
+} {123 123.0 10.25}
+test expr-14.15 {CompilePrimaryExpr: var reference primary} {
+    set i 123
+    catch {expr $i.2} msg
+    set msg
+} 123.2
+test expr-14.16 {CompilePrimaryExpr: error compiling var reference primary} -body {
+    expr {$a(foo}
+} -returnCodes error -match glob -result *
+test expr-14.17 {CompilePrimaryExpr: string primary that looks like var ref} -body {
+    expr $
+} -returnCodes error -match glob -result *
+test expr-14.18 {CompilePrimaryExpr: quoted string primary} {
+    expr "21"
+} 21
+test expr-14.19 {CompilePrimaryExpr: quoted string primary} {
+    set i 123
+    set x 456
+    expr "$i+$x"
+} 579
+test expr-14.20 {CompilePrimaryExpr: quoted string primary} {
+    set i 3
+    set x 6
+    expr 2+"$i.$x"
+} 5.6
+test expr-14.21 {CompilePrimaryExpr: error in quoted string primary} {
+    catch {expr "[set]"} msg
+    set msg
+} {wrong # args: should be "set varName ?newValue?"}
+test expr-14.22 {CompilePrimaryExpr: subcommand primary} {
+    expr {[set i 123; set i]}
+} 123
+test expr-14.23 {CompilePrimaryExpr: error in subcommand primary} -body {
+    catch {expr {[set]}} msg
+    set ::errorInfo
+} -match glob -result {wrong # args: should be "set varName ?newValue?"
+    while *ing
+"set"*}
+test expr-14.24 {CompilePrimaryExpr: error in subcommand primary} -body {
+    expr {[set i}
+} -returnCodes error -match glob -result *
+test expr-14.25 {CompilePrimaryExpr: math function primary} {
+    format %.6g [expr exp(1.0)]
+} 2.71828
+test expr-14.26 {CompilePrimaryExpr: math function primary} {
+    format %.6g [expr pow(2.0+0.1,3.0+0.1)]
+} 9.97424
+test expr-14.27 {CompilePrimaryExpr: error in math function primary} -body {
+    expr sinh::(2.0)
+} -returnCodes error -match glob -result *
+test expr-14.28 {CompilePrimaryExpr: subexpression primary} {
+    expr 2+(3*4)
+} 14
+test expr-14.29 {CompilePrimaryExpr: error in subexpression primary} -body {
+    catch {expr 2+(3*[set])} msg
+    set ::errorInfo
+} -match glob -result {wrong # args: should be "set varName ?newValue?"
+    while *ing
+"set"*}
+test expr-14.30 {CompilePrimaryExpr: missing paren in subexpression primary} -body {
+    expr 2+(3*(4+5)
+} -returnCodes error -match glob -result *
+test expr-14.31 {CompilePrimaryExpr: just var ref in subexpression primary} {
+    set i "5+10"
+    list "[expr $i] == 15" "[expr ($i)] == 15" "[eval expr ($i)] == 15"
+} {{15 == 15} {15 == 15} {15 == 15}}
+test expr-14.32 {CompilePrimaryExpr: unexpected token} -body {
+    expr @
+} -returnCodes error -match glob -result *
+
+test expr-15.1 {CompileMathFuncCall: missing parenthesis} -body {
+    expr sinh2.0)
+} -returnCodes error -match glob -result *
+test expr-15.2 {CompileMathFuncCall: unknown math function} -body {
+    catch {expr whazzathuh(1)} msg
+    set ::errorInfo
+} -match glob -result {* "*whazzathuh"
+    while *ing
+"expr whazzathuh(1)"}
+test expr-15.3 {CompileMathFuncCall: too many arguments} -body {
+    catch {expr sin(1,2,3)} msg
+    set ::errorInfo
+} -match glob -result {too many arguments for math function*
+    while *ing
+"expr sin(1,2,3)"}
+test expr-15.4 {CompileMathFuncCall: ')' found before last required arg} -body {
+    catch {expr sin()} msg
+    set ::errorInfo
+} -match glob -result {too few arguments for math function*
+    while *ing
+"expr sin()"}
+test expr-15.5 {CompileMathFuncCall: too few arguments} -body {
+    catch {expr pow(1)} msg
+    set ::errorInfo
+} -match glob -result {too few arguments for math function*
+    while *ing
+"expr pow(1)"}
+test expr-15.6 {CompileMathFuncCall: missing ')'} -body {
+    expr sin(1
+} -returnCodes error -match glob -result *
+test expr-15.7 {CompileMathFuncCall: call registered math function} {testmathfunctions} {
+    expr 2*T1()
+} 246
+test expr-15.8 {CompileMathFuncCall: call registered math function} {testmathfunctions} {
+    expr T2()*3
+} 1035
+test expr-15.9 {CompileMathFuncCall: call registered math function} {testmathfunctions} {
+    expr T3(21, 37)
+} 37
+test expr-15.10 {CompileMathFuncCall: call registered math function} {testmathfunctions} {
+    expr T3(21.2, 37)
+} 37.0
+test expr-15.11 {CompileMathFuncCall: call registered math function} {testmathfunctions} {
+    expr T3(-21.2, -17.5)
+} -17.5
+test expr-15.12 {ExprCallMathFunc: call registered math function} {testmathfunctions} {
+    expr T3(21, wide(37))
+} 37
+test expr=15.13 {ExprCallMathFunc: call registered math function} {testmathfunctions} {
+    expr T3(wide(21), 37)
+} 37
+test expr=15.14 {ExprCallMathFunc: call registered math function} {testmathfunctions} {
+    expr T3(wide(21), wide(37))
+} 37
+test expr-15.15 {ExprCallMathFunc: call registered math function} {testmathfunctions} {
+    expr T3(21.0, wide(37))
+} 37.0
+test expr-15.16 {ExprCallMathFunc: call registered math function} {testmathfunctions} {
+    expr T3(wide(21), 37.0)
+} 37.0
+test expr-15.17 {ExprCallMathFunc: non-numeric arg} -constraints {
+    testmathfunctions
+} -body {
+    expr T3(0,"a")
+} -returnCodes error -result {argument to math function didn't have numeric value}
+
+
+test expr-16.1 {GetToken: checks whether integer token starting with "0x" (e.g., "0x$") is invalid} {
+    catch {unset a}
+    set a(VALUE) ff15
+    set i 123
+    if {[expr 0x$a(VALUE)] & 16} {
+        set i {}
+    }
+    set i
+} {}
+test expr-16.2 {GetToken: check for string literal in braces} {
+    expr {{1}}
+} {1}
+
+# Check "expr" and computed command names.
+
+test expr-17.1 {expr and computed command names} {
+    set i 0
+    set z expr
+    $z 1+2
+} 3
+
+# Check correct conversion of operands to numbers: If the string looks like
+# an integer, convert to integer. Otherwise, if the string looks like a
+# double, convert to double.
+
+test expr-18.1 {expr and conversion of operands to numbers} {
+    set x [lindex 11 0]
+    catch {expr int($x)}
+    expr {$x}
+} 11
+test expr-18.2 {whitespace strings should not be == 0 (buggy strtod)} {
+    expr {" "}
+} { }
+
+# Check "expr" and interpreter result object resetting before appending
+# an error msg during evaluation of exprs not in {}s
+
+test expr-19.1 {expr and interpreter result object resetting} {
+    proc p {} {
+        set t  10.0
+        set x  2.0
+        set dx 0.2
+        set f  {$dx-$x/10}
+        set g  {-$x/5}
+        set center 1.0
+        set x  [expr $x-$center]
+        set dx [expr $dx+$g]
+        set x  [expr $x+$f+$center]
+        set x  [expr $x+$f+$center]
+        set y  [expr round($x)]
+    }
+    p
+} 3
+
+# Test for incorrect "double evaluation" semantics
+
+test expr-20.1 {wrong brace matching} {
+    catch {unset l}
+    catch {unset r}
+    catch {unset q}
+    catch {unset cmd}
+    catch {unset a}
+    set l "\{"; set r "\}"; set q "\""
+    set cmd "expr $l$q|$q == $q$r$q$r"
+    list [catch $cmd a] $a
+} {1 {extra characters after close-brace}}
+test expr-20.2 {double invocation of variable traces} -body {
+    set exprtracecounter 0
+    proc exprtraceproc {args} {
+       upvar #0 exprtracecounter counter
+       set argc [llength $args]
+       set extraargs [lrange $args 0 [expr {$argc - 4}]]
+       set name [lindex $args [expr {$argc - 3}]]
+       upvar 1 $name var
+       if {[incr counter] % 2 == 1} {
+           set var "$counter oops [concat $extraargs]"
+       } else {
+           set var "$counter + [concat $extraargs]"
+       }
+    }
+    trace variable exprtracevar r [list exprtraceproc 10]
+    list [catch {expr "$exprtracevar + 20"} a] $a \
+        [catch {expr "$exprtracevar + 20"} b] $b \
+        [unset exprtracevar exprtracecounter]
+} -match glob -result {1 * 0 32 {}}
+test expr-20.3 {broken substitution of integer digits} {
+    # fails with 8.0.x, but not 8.1b2
+    list [set a 000; expr 0x1$a] [set a 1; expr ${a}000]
+} {4096 1000}
+test expr-20.4 {proper double evaluation compilation, error case} {
+    catch {unset a}; # make sure $a doesn't exist
+    list [catch {expr 1?{$a}:0} msg] $msg
+} {1 {can't read "a": no such variable}}
+test expr-20.5 {proper double evaluation compilation, working case} {
+    set a yellow
+    expr 1?{$a}:0
+} yellow
+test expr-20.6 {handling of compile error in trial compile} {
+    list [catch {expr + {[incr]}} msg] $msg
+} {1 {wrong # args: should be "incr varName ?increment?"}}
+test expr-20.7 {handling of compile error in runtime case} {
+    list [catch {expr + {[error foo]}} msg] $msg
+} {1 foo}
+
+# Test for non-numeric boolean literal handling
+test expr-21.1 	{non-numeric boolean literals} {expr false } false
+test expr-21.2 	{non-numeric boolean literals} {expr true  } true
+test expr-21.3 	{non-numeric boolean literals} {expr off   } off
+test expr-21.4 	{non-numeric boolean literals} {expr on    } on
+test expr-21.5 	{non-numeric boolean literals} {expr no    } no
+test expr-21.6 	{non-numeric boolean literals} {expr yes   } yes
+test expr-21.7 	{non-numeric boolean literals} {expr !false} 1
+test expr-21.8 	{non-numeric boolean literals} {expr !true } 0
+test expr-21.9 	{non-numeric boolean literals} {expr !off  } 1
+test expr-21.10 {non-numeric boolean literals} {expr !on   } 0
+test expr-21.11 {non-numeric boolean literals} {expr !no   } 1
+test expr-21.12 {non-numeric boolean literals} {expr !yes  } 0
+test expr-21.13 {non-numeric boolean literals} -body {
+    expr !truef
+} -returnCodes error -match glob -result *
+test expr-21.14 {non-numeric boolean literals} {
+    list [catch {expr !"truef"} err] $err
+} {1 {can't use non-numeric string as operand of "!"}}
+test expr-21.15 {non-numeric boolean variables} {
+    set v truef
+    list [catch {expr {!$v}} err] $err
+} {1 {can't use non-numeric string as operand of "!"}}
+test expr-21.16 {non-numeric boolean variables} {
+    set v "true "
+    list [catch {expr {!$v}} err] $err
+} {1 {can't use non-numeric string as operand of "!"}}
+test expr-21.17 {non-numeric boolean variables} {
+    set v "tru"
+    list [catch {expr {!$v}} err] $err
+} {0 0}
+test expr-21.18 {non-numeric boolean variables} {
+    set v "fal"
+    list [catch {expr {!$v}} err] $err
+} {0 1}
+test expr-21.19 {non-numeric boolean variables} {
+    set v "y"
+    list [catch {expr {!$v}} err] $err
+} {0 0}
+test expr-21.20 {non-numeric boolean variables} {
+    set v "of"
+    list [catch {expr {!$v}} err] $err
+} {0 1}
+test expr-21.21 {non-numeric boolean variables} {
+    set v "o"
+    list [catch {expr {!$v}} err] $err
+} {1 {can't use non-numeric string as operand of "!"}}
+test expr-21.22 {non-numeric boolean variables} {
+    set v ""
+    list [catch {expr {!$v}} err] $err
+} {1 {can't use empty string as operand of "!"}}
+
+# Test for non-numeric float handling.
+test expr-22.1 {non-numeric floats} {
+    list [catch {expr {NaN + 1}} msg] $msg
+} {1 {can't use non-numeric floating-point value as operand of "+"}}
+test expr-22.2 {non-numeric floats} !ieeeFloatingPoint {
+    list [catch {expr {Inf + 1}} msg] $msg
+} {1 {can't use infinite floating-point value as operand of "+"}}
+test expr-22.3 {non-numeric floats} {
+    set nan NaN
+    list [catch {expr {$nan + 1}} msg] $msg
+} {1 {can't use non-numeric floating-point value as operand of "+"}}
+test expr-22.4 {non-numeric floats} !ieeeFloatingPoint {
+    set inf Inf
+    list [catch {expr {$inf + 1}} msg] $msg
+} {1 {can't use infinite floating-point value as operand of "+"}}
+test expr-22.5 {non-numeric floats} {
+    list [catch {expr NaN} msg] $msg
+} {1 {domain error: argument not in valid range}}
+test expr-22.6 {non-numeric floats} !ieeeFloatingPoint {
+    list [catch {expr Inf} msg] $msg
+} {1 {floating-point value too large to represent}}
+test expr-22.7 {non-numeric floats} {
+    list [catch {expr {1 / NaN}} msg] $msg
+} {1 {can't use non-numeric floating-point value as operand of "/"}}
+test expr-22.8 {non-numeric floats} !ieeeFloatingPoint {
+    list [catch {expr {1 / Inf}} msg] $msg
+} {1 {can't use infinite floating-point value as operand of "/"}}
+# Make sure [Bug 761471] stays fixed.
+test expr-22.9 {non-numeric floats: shared object equality and NaN} {
+    set x NaN
+    expr {$x == $x}
+} 0
+
+# Tests for exponentiation handling
+test expr-23.1 {CompileExponentialExpr: just exponential expr} {expr 4**2} 16
+test expr-23.2 {CompileExponentialExpr: just exponential expr} {expr 0xff**2} 65025
+test expr-23.3 {CompileExponentialExpr: just exponential expr} {expr -1**2} 1
+test expr-23.4 {CompileExponentialExpr: just exponential expr} {expr 18**07} 612220032
+test expr-23.5 {CompileExponentialExpr: error in exponential expr} -body {
+    expr x**3
+} -returnCodes error -match glob -result *
+test expr-23.6 {CompileExponentialExpr: simple expo exprs} {expr 0xff**0x3} 16581375
+test expr-23.7 {CompileExponentialExpr: error compiling expo arm} -body {
+    expr (-3-)**6
+} -returnCodes error -match glob -result *
+test expr-23.8 {CompileExponentialExpr: error compiling expo arm} -body {
+    expr 2**x
+} -returnCodes error -match glob -result *
+test expr-23.9 {CompileExponentialExpr: runtime error} {
+    list [catch {expr {24.0**"xx"}} msg] $msg
+} {1 {can't use non-numeric string as operand of "**"}}
+test expr-23.10 {CompileExponentialExpr: runtime error} {
+    list [catch {expr {"a"**2}} msg] $msg
+} {1 {can't use non-numeric string as operand of "**"}}
+test expr-23.11 {CompileExponentialExpr: runtime error} {
+    list [catch {expr {0**-1}} msg] $msg
+} {1 {exponentiation of zero by negative power}}
+test expr-23.12 {CompileExponentialExpr: runtime error} {
+    list [catch {expr {0.0**-1.0}} msg] $msg
+} {1 {exponentiation of zero by negative power}}
+test expr-23.13 {CompileExponentialExpr: runtime error} {
+    list [catch {expr {wide(0)**wide(-1)}} msg] $msg
+} {1 {exponentiation of zero by negative power}}
+test expr-23.14 {INST_EXPON: special cases} {expr {0**1}} 0
+test expr-23.15 {INST_EXPON: special cases} {expr {0**0}} 1
+test expr-23.16 {INST_EXPON: special cases} {expr {-2**-1}} 0
+test expr-23.17 {INST_EXPON: special cases} {expr {-2**0}} 1
+test expr-23.18 {INST_EXPON: special cases} {expr {-1**1}} -1
+test expr-23.19 {INST_EXPON: special cases} {expr {-1**0}} 1
+test expr-23.20 {INST_EXPON: special cases} {expr {-1**2}} 1
+test expr-23.21 {INST_EXPON: special cases} {expr {-1**-1}} -1
+test expr-23.22 {INST_EXPON: special cases} {expr {1**1234567}} 1
+test expr-23.23 {INST_EXPON: special cases} {expr {2**-2}} 0
+test expr-23.24 {INST_EXPON: special cases} {expr {wide(0)**wide(1)}} 0
+test expr-23.25 {INST_EXPON: special cases} {expr {wide(0)**wide(0)}} 1
+test expr-23.26 {INST_EXPON: special cases} {expr {wide(-2)**wide(-1)}} 0
+test expr-23.27 {INST_EXPON: special cases} {expr {wide(-2)**wide(0)}} 1
+test expr-23.28 {INST_EXPON: special cases} {expr {wide(-1)**wide(1)}} -1
+test expr-23.29 {INST_EXPON: special cases} {expr {wide(-1)**wide(0)}} 1
+test expr-23.30 {INST_EXPON: special cases} {expr {wide(-1)**wide(2)}} 1
+test expr-23.31 {INST_EXPON: special cases} {expr {wide(-1)**wide(-1)}} -1
+test expr-23.32 {INST_EXPON: special cases} {expr {wide(1)**wide(1234567)}} 1
+test expr-23.33 {INST_EXPON: special cases} {expr {wide(2)**wide(-2)}} 0
+test expr-23.34 {INST_EXPON: special cases} {expr {2**0}} 1
+test expr-23.35 {INST_EXPON: special cases} {expr {wide(2)**0}} 1
+test expr-23.36 {INST_EXPON: big integer} {expr {10**17}} 1[string repeat 0 17]
+test expr-23.37 {INST_EXPON: big integer} {expr {10**18}} 1[string repeat 0 18]
+test expr-23.38 {INST_EXPON: big integer} {expr {10**19}} 1[string repeat 0 19]
+test expr-23.39 {INST_EXPON: big integer} {
+    expr 1[string repeat 0 30]**2
+} 1[string repeat 0 60]
+test expr-23.40 {INST_EXPON: overflow to big integer} {expr {(-10)**3}} -1000
+test expr-23.41 {INST_EXPON: overflow to big integer} {expr 2**64} [expr 1<<64]
+test expr-23.42 {INST_EXPON: overflow to big integer} {expr 4**32} [expr 1<<64]
+test expr-23.43 {INST_EXPON: overflow to big integer} {expr 16**16} [expr 1<<64]
+test expr-23.44 {INST_EXPON: overflow to big integer} {expr 256**8} [expr 1<<64]
+test expr-23.45 {INST_EXPON: Bug 1555371} {expr 2**1} 2
+test expr-23.46 {INST_EXPON: Bug 1561260} -body {
+    expr 5**28
+} -match glob -result *5
+test expr-23.47 {INST_EXPON: Bug 1561260} {
+    expr 2**32*5**32
+} 1[string repeat 0 32]
+test expr-23.48 {INST_EXPON: TIP 274: right assoc} {
+expr 2**3**4
+} 2417851639229258349412352
+test expr-23.49 {INST_EXPON: optimize powers of 2} {
+    set trouble {test powers of 2}
+    for {set tval 0} {$tval <= 66} {incr tval} {
+	set is [expr {2 ** $tval}]
+	set sb [expr {1 << $tval}]
+	if {$is != $sb} {
+	    append trouble \n "2**" $tval " is " $is " should be " $sb
+	}
+	if {$tval >= 1} {
+	    set is [expr {-2 ** $tval}]
+	    set sb [expr {1 << $tval}]
+	    if {$tval & 1} {
+		set sb [expr {-$sb}]
+	    }
+	    if {$is != $sb} {
+		append trouble \n "-2**" $tval " is " $is " should be " $sb
+	    }
+	}
+    }
+    set trouble
+} {test powers of 2}
+test expr-23.50 {INST_EXPON: small powers of 32-bit integers} {
+    set trouble {test small powers of 32-bit ints}
+    for {set base 3} {$base <= 45} {incr base} {
+	set sb $base
+	set sbm [expr {-$base}]
+	for {set expt 2} {$expt <= 8} {incr expt} {
+	    set sb [expr {$sb * $base}]
+	    set is [expr {$base ** $expt}]
+	    if {$sb != $is} {
+		append trouble \n $base ** $expt " is " $is " should be " $sb
+	    }
+	    set sbm [expr {-$sbm * $base}]
+	    set ism [expr {(-$base) ** $expt}]
+	    if {$sbm != $ism} {
+		append trouble \n - $base ** $expt " is " $ism \
+		    " should be " $sbm
+	    }
+	}
+    }
+    set trouble
+} {test small powers of 32-bit ints}
+test expr-23.51 {INST_EXPON: intermediate powers of 32-bit integers} {
+    set trouble {test intermediate powers of 32-bit ints}
+    for {set base 3} {$base <= 11} {incr base} {
+	set sb [expr {$base ** 8}]
+	set sbm $sb
+	for {set expt 9} {$expt <= 21} {incr expt} {
+	    set sb [expr {$sb * $base}]
+	    set sbm [expr {$sbm * -$base}]
+	    set is [expr {$base ** $expt}]
+	    set ism [expr {-$base ** $expt}]
+	    if {$sb != $is} {
+		append trouble \n $base ** $expt " is " $is " should be " $sb
+	    }
+	    if {$sbm != $ism} {
+		append trouble \n - $base ** $expt " is " $ism  \
+		    " should be " $sbm
+	    }
+	}
+    }
+    set trouble
+} {test intermediate powers of 32-bit ints}
+test expr-23.52 {INST_EXPON: small integer powers with 64-bit results} {
+    set trouble {test small int powers with 64-bit results}
+    for {set exp 2} {$exp <= 16} {incr exp} {
+	set base [expr {entier(pow(double(0x7fffffffffffffff),(1.0/$exp)))}]
+	set sb 1
+	set sbm 1
+	for {set i 0} {$i < $exp} {incr i} {
+	    set sb [expr {$sb * $base}]
+	    set sbm [expr {$sbm * -$base}]
+	}
+	set is [expr {$base ** $exp}]
+	set ism [expr {-$base ** $exp}]
+	if {$sb != $is} {
+	    append trouble \n $base ** $exp " is " $is " should be " $sb
+	}
+	if {$sbm != $ism} {
+	    append trouble \n - $base ** $exp " is " $ism " should be " $sbm
+	}
+	incr base
+	set sb 1
+	set sbm 1
+	for {set i 0} {$i < $exp} {incr i} {
+	    set sb [expr {$sb * $base}]
+	    set sbm [expr {$sbm * -$base}]
+	}
+	set is [expr {$base ** $exp}]
+	set ism [expr {-$base ** $exp}]
+	if {$sb != $is} {
+	    append trouble \n $base ** $exp " is " $is " should be " $sb
+	}
+	if {$sbm != $ism} {
+	    append trouble \n - $base ** $exp " is " $ism " should be " $sbm
+	}
+    }
+    set trouble
+} {test small int powers with 64-bit results}
+test expr-23.53 {INST_EXPON: intermediate powers of 64-bit integers} {
+    set trouble {test intermediate powers of 64-bit ints}
+    for {set base 3} {$base <= 13} {incr base} {
+	set sb [expr {$base ** 15}]
+	set sbm [expr {-$sb}]
+	for {set expt 16} {$expt <= 39} {incr expt} {
+	    set sb [expr {$sb * $base}]
+	    set sbm [expr {$sbm * -$base}]
+	    set is [expr {$base ** $expt}]
+	    set ism [expr {-$base ** $expt}]
+	    if {$sb != $is} {
+		append trouble \n $base ** $expt " is " $is " should be " $sb
+	    }
+	    if {$sbm != $ism} {
+		append trouble \n - $base ** $expt " is " $ism  \
+		    " should be " $sbm
+	    }
+	}
+    }
+    set trouble
+} {test intermediate powers of 64-bit ints}
+test expr-23.54.0 {INST_EXPON: Bug 2798543} {
+    expr {3**9 == 3**65545}
+} 0
+test expr-23.54.1 {INST_EXPON: Bug 2798543} {
+    expr {3**10 == 3**65546}
+} 0
+test expr-23.54.2 {INST_EXPON: Bug 2798543} {
+    expr {3**11 == 3**65547}
+} 0
+test expr-23.54.3 {INST_EXPON: Bug 2798543} {
+    expr {3**12 == 3**65548}
+} 0
+test expr-23.54.4 {INST_EXPON: Bug 2798543} {
+    expr {3**13 == 3**65549}
+} 0
+test expr-23.54.5 {INST_EXPON: Bug 2798543} {
+    expr {3**14 == 3**65550}
+} 0
+test expr-23.54.6 {INST_EXPON: Bug 2798543} {
+    expr {3**15 == 3**65551}
+} 0
+test expr-23.54.7 {INST_EXPON: Bug 2798543} {
+    expr {3**16 == 3**65552}
+} 0
+test expr-23.54.8 {INST_EXPON: Bug 2798543} {
+    expr {3**17 == 3**65553}
+} 0
+test expr-23.54.9 {INST_EXPON: Bug 2798543} {
+    expr {3**18 == 3**65554}
+} 0
+test expr-23.54.10 {INST_EXPON: Bug 2798543} {
+    expr {3**19 == 3**65555}
+} 0
+test expr-23.54.11 {INST_EXPON: Bug 2798543} {
+    expr {3**9 == 3**131081}
+} 0
+test expr-23.54.12 {INST_EXPON: Bug 2798543} -body {
+    expr {3**9 == 3**268435465}
+} -returnCodes error -result {exponent too large}
+test expr-23.54.13 {INST_EXPON: Bug 2798543} {
+    expr {(-3)**9 == (-3)**65545}
+} 0
+test expr-23.55.0 {INST_EXPON: Bug 2798543} {
+    expr {4**9 == 4**65545}
+} 0
+test expr-23.55.1 {INST_EXPON: Bug 2798543} {
+    expr {4**15 == 4**65551}
+} 0
+test expr-23.55.2 {INST_EXPON: Bug 2798543} {
+    expr {4**9 == 4**131081}
+} 0
+test expr-23.55.3 {INST_EXPON: Bug 2798543} -body {
+    expr {4**9 == 4**268435465}
+} -returnCodes error -result {exponent too large}
+test expr-23.55.4 {INST_EXPON: Bug 2798543} {
+    expr {(-4)**9 == (-4)**65545}
+} 0
+test expr-23.56.0 {INST_EXPON: Bug 2798543} {
+    expr {5**9 == 5**65545}
+} 0
+test expr-23.56.1 {INST_EXPON: Bug 2798543} {
+    expr {5**13 == 5**65549}
+} 0
+test expr-23.56.2 {INST_EXPON: Bug 2798543} {
+    expr {5**9 == 5**131081}
+} 0
+test expr-23.56.3 {INST_EXPON: Bug 2798543} -body {
+    expr {5**9 == 5**268435465}
+} -returnCodes error -result {exponent too large}
+test expr-23.56.4 {INST_EXPON: Bug 2798543} {
+    expr {(-5)**9 == (-5)**65545}
+} 0
+test expr-23.57.0 {INST_EXPON: Bug 2798543} {
+    expr {6**9 == 6**65545}
+} 0
+test expr-23.57.1 {INST_EXPON: Bug 2798543} {
+    expr {6**11 == 6**65547}
+} 0
+test expr-23.57.2 {INST_EXPON: Bug 2798543} {
+    expr {6**9 == 6**131081}
+} 0
+test expr-23.57.3 {INST_EXPON: Bug 2798543} -body {
+    expr {6**9 == 6**268435465}
+} -returnCodes error -result {exponent too large}
+test expr-23.57.4 {INST_EXPON: Bug 2798543} {
+    expr {(-6)**9 == (-6)**65545}
+} 0
+test expr-23.58.0 {INST_EXPON: Bug 2798543} {
+    expr {7**9 == 7**65545}
+} 0
+test expr-23.58.1 {INST_EXPON: Bug 2798543} {
+    expr {7**11 == 7**65547}
+} 0
+test expr-23.58.2 {INST_EXPON: Bug 2798543} {
+    expr {7**9 == 7**131081}
+} 0
+test expr-23.58.3 {INST_EXPON: Bug 2798543} -body {
+    expr {7**9 == 7**268435465}
+} -returnCodes error -result {exponent too large}
+test expr-23.58.4 {INST_EXPON: Bug 2798543} {
+    expr {(-7)**9 == (-7)**65545}
+} 0
+test expr-23.59.0 {INST_EXPON: Bug 2798543} {
+    expr {8**9 == 8**65545}
+} 0
+test expr-23.59.1 {INST_EXPON: Bug 2798543} {
+    expr {8**10 == 8**65546}
+} 0
+test expr-23.59.2 {INST_EXPON: Bug 2798543} {
+    expr {8**9 == 8**131081}
+} 0
+test expr-23.59.3 {INST_EXPON: Bug 2798543} -body {
+    expr {8**9 == 8**268435465}
+} -returnCodes error -result {exponent too large}
+test expr-23.59.4 {INST_EXPON: Bug 2798543} {
+    expr {(-8)**9 == (-8)**65545}
+} 0
+test expr-23.60.0 {INST_EXPON: Bug 2798543} {
+    expr {9**9 == 9**65545}
+} 0
+test expr-23.60.1 {INST_EXPON: Bug 2798543} {
+    expr {9**9 == 9**131081}
+} 0
+test expr-23.60.2 {INST_EXPON: Bug 2798543} -body {
+    expr {9**9 == 9**268435465}
+} -returnCodes error -result {exponent too large}
+test expr-23.60.3 {INST_EXPON: Bug 2798543} {
+    expr {(-9)**9 == (-9)**65545}
+} 0
+test expr-23.61.0 {INST_EXPON: Bug 2798543} {
+    expr {10**9 == 10**65545}
+} 0
+test expr-23.61.1 {INST_EXPON: Bug 2798543} {
+    expr {10**9 == 10**131081}
+} 0
+test expr-23.61.2 {INST_EXPON: Bug 2798543} -body {
+    expr {10**9 == 10**268435465}
+} -returnCodes error -result {exponent too large}
+test expr-23.61.3 {INST_EXPON: Bug 2798543} {
+    expr {(-10)**9 == (-10)**65545}
+} 0
+test expr-23.62.0 {INST_EXPON: Bug 2798543} {
+    expr {11**9 == 11**65545}
+} 0
+test expr-23.62.1 {INST_EXPON: Bug 2798543} {
+    expr {11**9 == 11**131081}
+} 0
+test expr-23.62.2 {INST_EXPON: Bug 2798543} -body {
+    expr {11**9 == 11**268435465}
+} -returnCodes error -result {exponent too large}
+test expr-23.62.3 {INST_EXPON: Bug 2798543} {
+    expr {(-11)**9 == (-11)**65545}
+} 0
+test expr-23.63.0 {INST_EXPON: Bug 2798543} {
+    expr {3**20 == 3**65556}
+} 0
+test expr-23.63.1 {INST_EXPON: Bug 2798543} {
+    expr {3**39 == 3**65575}
+} 0
+test expr-23.63.2 {INST_EXPON: Bug 2798543} {
+    expr {3**20 == 3**131092}
+} 0
+test expr-23.63.3 {INST_EXPON: Bug 2798543} -body {
+    expr {3**20 == 3**268435476}
+} -returnCodes error -result {exponent too large}
+test expr-23.63.4 {INST_EXPON: Bug 2798543} {
+    expr {(-3)**20 == (-3)**65556}
+} 0
+test expr-23.64.0 {INST_EXPON: Bug 2798543} {
+    expr {4**17 == 4**65553}
+} 0
+test expr-23.64.1 {INST_EXPON: Bug 2798543} {
+    expr {4**31 == 4**65567}
+} 0
+test expr-23.64.2 {INST_EXPON: Bug 2798543} {
+    expr {4**17 == 4**131089}
+} 0
+test expr-23.64.3 {INST_EXPON: Bug 2798543} -body {
+    expr {4**17 == 4**268435473}
+} -returnCodes error -result {exponent too large}
+test expr-23.64.4 {INST_EXPON: Bug 2798543} {
+    expr {(-4)**17 == (-4)**65553}
+} 0
+test expr-23.65.0 {INST_EXPON: Bug 2798543} {
+    expr {5**17 == 5**65553}
+} 0
+test expr-23.65.1 {INST_EXPON: Bug 2798543} {
+    expr {5**27 == 5**65563}
+} 0
+test expr-23.65.2 {INST_EXPON: Bug 2798543} {
+    expr {5**17 == 5**131089}
+} 0
+test expr-23.65.3 {INST_EXPON: Bug 2798543} -body {
+    expr {5**17 == 5**268435473}
+} -returnCodes error -result {exponent too large}
+test expr-23.65.4 {INST_EXPON: Bug 2798543} {
+    expr {(-5)**17 == (-5)**65553}
+} 0
+test expr-23.66.0 {INST_EXPON: Bug 2798543} {
+    expr {6**17 == 6**65553}
+} 0
+test expr-23.66.1 {INST_EXPON: Bug 2798543} {
+    expr {6**24 == 6**65560}
+} 0
+test expr-23.66.2 {INST_EXPON: Bug 2798543} {
+    expr {6**17 == 6**131089}
+} 0
+test expr-23.66.3 {INST_EXPON: Bug 2798543} -body {
+    expr {6**17 == 6**268435473}
+} -returnCodes error -result {exponent too large}
+test expr-23.66.4 {INST_EXPON: Bug 2798543} {
+    expr {(-6)**17 == (-6)**65553}
+} 0
+test expr-23.67.0 {INST_EXPON: Bug 2798543} {
+    expr {7**17 == 7**65553}
+} 0
+test expr-23.67.1 {INST_EXPON: Bug 2798543} {
+    expr {7**22 == 7**65558}
+} 0
+test expr-23.67.2 {INST_EXPON: Bug 2798543} {
+    expr {7**17 == 7**131089}
+} 0
+test expr-23.67.3 {INST_EXPON: Bug 2798543} -body {
+    expr {7**17 == 7**268435473}
+} -returnCodes error -result {exponent too large}
+test expr-23.67.4 {INST_EXPON: Bug 2798543} {
+    expr {(-7)**17 == (-7)**65553}
+} 0
+test expr-23.68.0 {INST_EXPON: Bug 2798543} {
+    expr {8**17 == 8**65553}
+} 0
+test expr-23.68.1 {INST_EXPON: Bug 2798543} {
+    expr {8**20 == 8**65556}
+} 0
+test expr-23.68.2 {INST_EXPON: Bug 2798543} {
+    expr {8**17 == 8**131089}
+} 0
+test expr-23.68.3 {INST_EXPON: Bug 2798543} -body {
+    expr {8**17 == 8**268435473}
+} -returnCodes error -result {exponent too large}
+test expr-23.68.4 {INST_EXPON: Bug 2798543} {
+    expr {(-8)**17 == (-8)**65553}
+} 0
+test expr-23.69.0 {INST_EXPON: Bug 2798543} {
+    expr {9**17 == 9**65553}
+} 0
+test expr-23.69.1 {INST_EXPON: Bug 2798543} {
+    expr {9**19 == 9**65555}
+} 0
+test expr-23.69.2 {INST_EXPON: Bug 2798543} {
+    expr {9**17 == 9**131089}
+} 0
+test expr-23.69.3 {INST_EXPON: Bug 2798543} -body {
+    expr {9**17 == 9**268435473}
+} -returnCodes error -result {exponent too large}
+test expr-23.69.4 {INST_EXPON: Bug 2798543} {
+    expr {(-9)**17 == (-9)**65553}
+} 0
+test expr-23.70.0 {INST_EXPON: Bug 2798543} {
+    expr {10**17 == 10**65553}
+} 0
+test expr-23.70.1 {INST_EXPON: Bug 2798543} {
+    expr {10**18 == 10**65554}
+} 0
+test expr-23.70.2 {INST_EXPON: Bug 2798543} {
+    expr {10**17 == 10**131089}
+} 0
+test expr-23.70.3 {INST_EXPON: Bug 2798543} -body {
+    expr {10**17 == 10**268435473}
+} -returnCodes error -result {exponent too large}
+test expr-23.70.4 {INST_EXPON: Bug 2798543} {
+    expr {(-10)**17 == (-10)**65553}
+} 0
+test expr-23.71.0 {INST_EXPON: Bug 2798543} {
+    expr {11**17 == 11**65553}
+} 0
+test expr-23.71.1 {INST_EXPON: Bug 2798543} {
+    expr {11**18 == 11**65554}
+} 0
+test expr-23.71.2 {INST_EXPON: Bug 2798543} {
+    expr {11**17 == 11**131089}
+} 0
+test expr-23.71.3 {INST_EXPON: Bug 2798543} -body {
+    expr {11**17 == 11**268435473}
+} -returnCodes error -result {exponent too large}
+test expr-23.71.4 {INST_EXPON: Bug 2798543} {
+    expr {(-11)**17 == (-11)**65553}
+} 0
+test expr-23.72.0 {INST_EXPON: Bug 2798543} {
+    expr {12**17 == 12**65553}
+} 0
+test expr-23.72.1 {INST_EXPON: Bug 2798543} {
+    expr {12**17 == 12**131089}
+} 0
+test expr-23.72.2 {INST_EXPON: Bug 2798543} -body {
+    expr {12**17 == 12**268435473}
+} -returnCodes error -result {exponent too large}
+test expr-23.72.3 {INST_EXPON: Bug 2798543} {
+    expr {(-12)**17 == (-12)**65553}
+} 0
+test expr-23.73.0 {INST_EXPON: Bug 2798543} {
+    expr {13**17 == 13**65553}
+} 0
+test expr-23.73.1 {INST_EXPON: Bug 2798543} {
+    expr {13**17 == 13**131089}
+} 0
+test expr-23.73.2 {INST_EXPON: Bug 2798543} -body {
+    expr {13**17 == 13**268435473}
+} -returnCodes error -result {exponent too large}
+test expr-23.73.3 {INST_EXPON: Bug 2798543} {
+    expr {(-13)**17 == (-13)**65553}
+} 0
+test expr-23.74.0 {INST_EXPON: Bug 2798543} {
+    expr {14**17 == 14**65553}
+} 0
+test expr-23.74.1 {INST_EXPON: Bug 2798543} {
+    expr {14**17 == 14**131089}
+} 0
+test expr-23.74.2 {INST_EXPON: Bug 2798543} -body {
+    expr {14**17 == 14**268435473}
+} -returnCodes error -result {exponent too large}
+test expr-23.74.3 {INST_EXPON: Bug 2798543} {
+    expr {(-14)**17 == (-14)**65553}
+} 0
+
+	
+# Some compilers get this wrong; ensure that we work around it correctly
+test expr-24.1 {expr edge cases; shifting} {expr int(5)>>32} 0
+test expr-24.2 {expr edge cases; shifting} {expr int(5)>>63} 0
+test expr-24.3 {expr edge cases; shifting} {expr wide(5)>>32} 0
+test expr-24.4 {expr edge cases; shifting} {expr wide(5)>>63} 0
+test expr-24.5 {expr edge cases; shifting} longIs32bit {expr int(5<<32)} 0
+test expr-24.6 {expr edge cases; shifting} longIs32bit {expr int(5<<63)} 0
+test expr-24.7 {expr edge cases; shifting} {expr wide(5)<<32} 21474836480
+test expr-24.8 {expr edge cases; shifting} {expr wide(10<<63)} 0
+test expr-24.9 {expr edge cases; shifting} {expr 5>>32} 0
+
+test expr-24.10 {INST_LSHIFT: Bug 1567222} {expr 500000000000000<<28} 134217728000000000000000
+
+# List membership tests
+test expr-25.1 {'in' operator} {expr {"a" in "a b c"}} 1
+test expr-25.2 {'in' operator} {expr {"a" in "b a c"}} 1
+test expr-25.3 {'in' operator} {expr {"a" in "b c a"}} 1
+test expr-25.4 {'in' operator} {expr {"a" in ""}} 0
+test expr-25.5 {'in' operator} {expr {"" in {a b c ""}}} 1
+test expr-25.6 {'in' operator} {expr {"" in "a b c"}} 0
+test expr-25.7 {'in' operator} {expr {"" in ""}} 0
+
+test expr-26.1 {'ni' operator} {expr {"a" ni "a b c"}} 0
+test expr-26.2 {'ni' operator} {expr {"a" ni "b a c"}} 0
+test expr-26.3 {'ni' operator} {expr {"a" ni "b c a"}} 0
+test expr-26.4 {'ni' operator} {expr {"a" ni ""}} 1
+test expr-26.5 {'ni' operator} {expr {"" ni {a b c ""}}} 0
+test expr-26.6 {'ni' operator} {expr {"" ni "a b c"}} 1
+test expr-26.7 {'ni' operator} {expr {"" ni ""}} 1
+
+foreach op {< <= == != > >=} {
+    proc test$op {a b} [list expr "\$a $op \$b"]
+}
+
+test expr-27.1 {expr - correct ordering - not compiled} ieeeFloatingPoint {
+    set problems {}
+    # Ordering should be: -Infinity < -Normal < Subnormal < -0
+    #                     < +0 < +Subnormal < +Normal < +Infinity
+    # with equality within each class.
+    set names {
+	-Infinity -Normal -Subnormal -0 +0 +Subnormal +Normal +Infinity
+    }
+    set weights {
+	-3 -2 -1 0 0 1 2 3
+    }
+    foreach name1 $names weight1 $weights {
+	foreach name2 $names weight2 $weights {
+	    foreach op {< <= == != >= >} {
+		set shouldBe [expr "$weight1 $op $weight2"]
+		set is [expr "\$ieeeValues($name1) $op \$ieeeValues($name2)"]
+		if { $is != $shouldBe } {
+		    append problems $name1 { } $op { } $name2 \
+			":result is " $is ", should be $shouldBe" \n
+		}
+	    }
+	}
+    }
+    set problems
+} {}
+test expr-27.2 {expr - correct ordering - compiled} ieeeFloatingPoint {
+    set problems {}
+    # Ordering should be: -Infinity < -Normal < Subnormal < -0
+    #                     < +0 < +Subnormal < +Normal < +Infinity
+    # with equality within each class.
+    set names {
+	-Infinity -Normal -Subnormal -0 +0 +Subnormal +Normal +Infinity
+    }
+    set weights {
+	-3 -2 -1 0 0 1 2 3
+    }
+    foreach name1 $names weight1 $weights {
+	foreach name2 $names weight2 $weights {
+	    foreach op {< <= == != >= >} {
+		set shouldBe [expr "$weight1 $op $weight2"]
+		set is [test$op $ieeeValues($name1) $ieeeValues($name2)]
+		if { $is != $shouldBe } {
+		    append problems $name1 { } $op { } $name2 \
+			":result is " $is ", should be $shouldBe" \n
+		}
+	    }
+	}
+    }
+    set problems
+} {}
+test expr-27.3 {expr - NaN is unordered - not compiled} {
+    set problems {}
+    set names {
+	-Infinity -Normal -Subnormal -0 +0 +Subnormal +Normal +Infinity NaN
+    }
+    foreach name1 $names {
+	foreach op {< <= == != >= >} sb {0 0 0 1 0 0} {
+	    if "(\$ieeeValues($name1) $op \$ieeeValues(NaN)) != $sb " {
+		append problems $name1 { } $op { } NaN \
+		    ": result is 1, should be $sb" \n
+	    }
+	    if "(\$ieeeValues(NaN) $op \$ieeeValues($name1)) != $sb" {
+		append problems NaN { } $op { } $name1 \
+		    ": result is 1, should be $sb" \n
+	    }
+	}
+    }
+    set problems
+} {}
+test expr-27.4 {expr - NaN is unordered - compiled} {
+    set problems {}
+    set names {
+	-Infinity -Normal -Subnormal -0 +0 +Subnormal +Normal +Infinity NaN
+    }
+    foreach name1 $names {
+	foreach op {< <= == != >= >} sb {0 0 0 1 0 0} {
+	    if { [test$op $ieeeValues($name1) $ieeeValues(NaN)] != $sb } {
+		append problems $ieeeValues($name1) { } $op { } $ieeeValues(NaN) \
+		    ": result is 1, should be $sb" \n
+	    }
+	    if { [test$op $ieeeValues(NaN) $ieeeValues($name1)] != $sb } {
+		append problems NaN { } $op { } $ieeeValues($name1) \
+		    ": result is 1, should be $sb" \n
+	    }
+	}
+    }
+    set problems
+} {}
+
+proc convertToDouble { x } {
+    variable ieeeValues
+    binary scan [binary format d $x] c* bytes
+    set result 0x
+    if { $ieeeValues(littleEndian) } {
+	for { set i 7 } { $i >= 0 } { incr i -1 } {
+	    append result [format %02x [expr { [lindex $bytes $i] & 0xff }]]
+	}
+    } else {
+	foreach byte $bytes {
+	    append result [format %02x [expr { $byte & 0xff }]]
+	}
+    }
+    return $result
+}
+
+test expr-28.1 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d ALL 0 E0 OK 00000000000000 E-1023
+    convertToDouble 0E0
+} 0x0000000000000000
+test expr-28.2 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d ALL -0 E0 OK -0000000000000 E-1023
+    convertToDouble -0E0
+} 0x8000000000000000
+test expr-28.3 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d ALL 1 E0 OK 10000000000000 E0
+    convertToDouble 1E0
+} 0x3ff0000000000000
+test expr-28.4 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d ALL 15 E-1 OK 18000000000000 E0
+    convertToDouble 15E-1
+} 0x3ff8000000000000
+test expr-28.5 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d ALL 125 E-2 OK 14000000000000 E0
+    convertToDouble 125E-2
+} 0x3ff4000000000000
+test expr-28.6 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d ALL 1125 E-3 OK 12000000000000 E0
+    convertToDouble 1125E-3
+} 0x3ff2000000000000
+test expr-28.7 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d ALL 10625 E-4 OK 11000000000000 E0
+    convertToDouble 10625E-4
+} 0x3ff1000000000000
+test expr-28.8 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d ALL 103125 E-5 OK 10800000000000 E0
+    convertToDouble 103125E-5
+} 0x3ff0800000000000
+test expr-28.9 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d ALL 1015625 E-6 OK 10400000000000 E0
+    convertToDouble 1015625E-6
+} 0x3ff0400000000000
+test expr-28.10 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d ALL 10078125 E-7 OK 10200000000000 E0
+    convertToDouble 10078125E-7
+} 0x3ff0200000000000
+test expr-28.11 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d ALL 100390625 E-8 OK 10100000000000 E0
+    convertToDouble 100390625E-8
+} 0x3ff0100000000000
+test expr-28.12 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee ALL 1001953125 E-9 OK 10080000000000 E0
+    convertToDouble 1001953125E-9
+} 0x3ff0080000000000
+test expr-28.13 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee ALL 10009765625 E-10 OK 10040000000000 E0
+    convertToDouble 10009765625E-10
+} 0x3ff0040000000000
+test expr-28.14 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee ALL 100048828125 E-11 OK 10020000000000 E0
+    convertToDouble 100048828125E-11
+} 0x3ff0020000000000
+test expr-28.15 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee ALL 1000244140625 E-12 OK 10010000000000 E0
+    convertToDouble 1000244140625E-12
+} 0x3ff0010000000000
+test expr-28.16 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee ALL 10001220703125 E-13 OK 10008000000000 E0
+    convertToDouble 10001220703125E-13
+} 0x3ff0008000000000
+test expr-28.17 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee ALL 100006103515625 E-14 OK 10004000000000 E0
+    convertToDouble 100006103515625E-14
+} 0x3ff0004000000000
+test expr-28.18 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee ALL 1000030517578125 E-15 OK 10002000000000 E0
+    convertToDouble 1000030517578125E-15
+} 0x3ff0002000000000
+test expr-28.19 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee ALL 10000152587890625 E-16 OK 10001000000000 E0
+    convertToDouble 10000152587890625E-16
+} 0x3ff0001000000000
+test expr-28.20 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +8 E153 x 1317e5ef3ab327_0000000001& E511
+    convertToDouble +8E153
+} 0x5fe317e5ef3ab327
+test expr-28.21 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -1 E153 x -1317e5ef3ab327_0000000001& E508
+    convertToDouble -1E153
+} 0xdfb317e5ef3ab327
+test expr-28.22 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +9 E306 x 19a2028368022e_00000000001& E1019
+    convertToDouble +9E306
+} 0x7fa9a2028368022e
+test expr-28.23 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -2 E153 x -1317e5ef3ab327_0000000001& E509
+    convertToDouble -2E153
+} 0xdfc317e5ef3ab327
+test expr-28.24 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +7 E-304 x 1eb8e84fa0b278_00000000001& E-1008
+    convertToDouble +7E-304
+} 0x00feb8e84fa0b278
+test expr-28.25 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -3 E-49 x -1c0f92a6276c9d_000000001& E-162
+    convertToDouble -3E-49
+} 0xb5dc0f92a6276c9d
+test expr-28.26 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +7 E-303 x 13339131c46f8b_00000000001& E-1004
+    convertToDouble +7E-303
+} 0x0133339131c46f8b
+test expr-28.27 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -6 E-49 x -1c0f92a6276c9d_000000001& E-161
+    convertToDouble -6E-49
+} 0xb5ec0f92a6276c9d
+test expr-28.28 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +9 E43 x 102498ea6df0c3_11111111110& E146
+    convertToDouble +9E43
+} 0x49102498ea6df0c4
+test expr-28.29 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -9 E44 x -142dbf25096cf4_1111111110& E149
+    convertToDouble -9E44
+} 0xc9442dbf25096cf5
+test expr-28.30 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +8 E303 x 1754e31cd072d9_1111111110& E1009
+    convertToDouble +8E303
+} 0x7f0754e31cd072da
+test expr-28.31 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -1 E303 x -1754e31cd072d9_1111111110& E1006
+    convertToDouble -1E303
+} 0xfed754e31cd072da
+test expr-28.32 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +7 E-287 x 1551603777f798_111111110& E-951
+    convertToDouble +7E-287
+} 0x048551603777f799
+test expr-28.33 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -2 E-204 x -1410d9f9b2f7f2_11111110& E-677
+    convertToDouble -2E-204
+} 0x95a410d9f9b2f7f3
+test expr-28.34 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +2 E-205 x 100d7b2e28c65b_11111110& E-680
+    convertToDouble +2E-205
+} 0x15700d7b2e28c65c
+test expr-28.35 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -9 E-47 x -10711fed5b19a3_11111110& E-153
+    convertToDouble -9E-47
+} 0xb660711fed5b19a4
+test expr-28.36 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +34 E195 x 1d1c26db7d0dae_000000000001& E652
+    convertToDouble +34E195
+} 0x68bd1c26db7d0dae
+test expr-28.37 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -68 E195 x -1d1c26db7d0dae_000000000001& E653
+    convertToDouble -68E195
+} 0xe8cd1c26db7d0dae
+test expr-28.38 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +85 E194 x 1d1c26db7d0dae_000000000001& E650
+    convertToDouble +85E194
+} 0x689d1c26db7d0dae
+test expr-28.39 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -67 E97 x -139ac1ce2cc95f_000000000001& E328
+    convertToDouble -67E97
+} 0xd4739ac1ce2cc95f
+test expr-28.40 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +93 E-234 x 127b2e4f210075_0000000000000001& E-771
+    convertToDouble +93E-234
+} 0x0fc27b2e4f210075
+test expr-28.41 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -19 E-87 x -12e5f5dfa4fe9d_00000000000001& E-285
+    convertToDouble -19E-87
+} 0xae22e5f5dfa4fe9d
+test expr-28.42 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +38 E-87 x 12e5f5dfa4fe9d_00000000000001& E-284
+    convertToDouble +38E-87
+} 0x2e32e5f5dfa4fe9d
+test expr-28.43 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -38 E-88 x -1e3cbc9907fdc8_00000000000001& E-288
+    convertToDouble -38E-88
+} 0xadfe3cbc9907fdc8
+test expr-28.44 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -69 E220 x -1e8aa8823a5db3_11111111110& E736
+    convertToDouble -69E220
+} 0xedfe8aa8823a5db4
+test expr-28.45 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +18 E43 x 102498ea6df0c3_11111111110& E147
+    convertToDouble +18E43
+} 0x49202498ea6df0c4
+test expr-28.46 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -36 E43 x -102498ea6df0c3_11111111110& E148
+    convertToDouble -36E43
+} 0xc9302498ea6df0c4
+test expr-28.47 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +61 E-99 x 10ad836f269a16_11111111111110& E-323
+    convertToDouble +61E-99
+} 0x2bc0ad836f269a17
+test expr-28.48 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -43 E-92 x -1c0794d9d40e95_111111111111110& E-301
+    convertToDouble -43E-92
+} 0xad2c0794d9d40e96
+test expr-28.49 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +86 E-92 x 1c0794d9d40e95_111111111111110& E-300
+    convertToDouble +86E-92
+} 0x2d3c0794d9d40e96
+test expr-28.50 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -51 E-74 x -1cd5bee57763e5_1111111111111110& E-241
+    convertToDouble -51E-74
+} 0xb0ecd5bee57763e6
+test expr-28.51 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +283 E85 x 16c309024bab4b_00000000000000001& E290
+    convertToDouble +283E85
+} 0x5216c309024bab4b
+test expr-28.52 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -566 E85 x -16c309024bab4b_00000000000000001& E291
+    convertToDouble -566E85
+} 0xd226c309024bab4b
+test expr-28.53 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +589 E187 x 1526be9c22eb17_00000000000000001& E630
+    convertToDouble +589E187
+} 0x675526be9c22eb17
+test expr-28.54 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -839 E143 x -1ae03f245703e2_000000000000001& E484
+    convertToDouble -839E143
+} 0xde3ae03f245703e2
+test expr-28.55 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -744 E-234 x -127b2e4f210075_0000000000000001& E-768
+    convertToDouble -744E-234
+} 0x8ff27b2e4f210075
+test expr-28.56 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +930 E-235 x 127b2e4f210075_0000000000000001& E-771
+    convertToDouble +930E-235
+} 0x0fc27b2e4f210075
+test expr-28.57 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -186 E-234 x -127b2e4f210075_0000000000000001& E-770
+    convertToDouble -186E-234
+} 0x8fd27b2e4f210075
+test expr-28.58 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +604 E175 x 17d93193f78fc5_1111111111111111110& E590
+    convertToDouble +604E175
+} 0x64d7d93193f78fc6
+test expr-28.59 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -302 E175 x -17d93193f78fc5_1111111111111111110& E589
+    convertToDouble -302E175
+} 0xe4c7d93193f78fc6
+test expr-28.60 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +755 E174 x 17d93193f78fc5_1111111111111111110& E587
+    convertToDouble +755E174
+} 0x64a7d93193f78fc6
+test expr-28.61 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -151 E175 x -17d93193f78fc5_1111111111111111110& E588
+    convertToDouble -151E175
+} 0xe4b7d93193f78fc6
+test expr-28.62 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +662 E-213 x 1bdb90e62a8cbc_1111111111111110& E-699
+    convertToDouble +662E-213
+} 0x144bdb90e62a8cbd
+test expr-28.63 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -408 E-74 x -1cd5bee57763e5_1111111111111110& E-238
+    convertToDouble -408E-74
+} 0xb11cd5bee57763e6
+test expr-28.64 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +510 E-75 x 1cd5bee57763e5_1111111111111110& E-241
+    convertToDouble +510E-75
+} 0x30ecd5bee57763e6
+test expr-28.65 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +6782 E55 x 159bd3ad46e346_0000000000000000001& E195
+    convertToDouble +6782E55
+} 0x4c259bd3ad46e346
+test expr-28.66 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -2309 E92 x -1bac6f7d64d119_000000000000000001& E316
+    convertToDouble -2309E92
+} 0xd3bbac6f7d64d119
+test expr-28.67 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +7963 E34 x 1df4170f0fdecc_00000000000000000001& E125
+    convertToDouble +7963E34
+} 0x47cdf4170f0fdecc
+test expr-28.68 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -3391 E55 x -159bd3ad46e346_0000000000000000001& E194
+    convertToDouble -3391E55
+} 0xcc159bd3ad46e346
+test expr-28.69 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +7903 E-96 x 107c2d27a5b989_0000000000000000001& E-306
+    convertToDouble +7903E-96
+} 0x2cd07c2d27a5b989
+test expr-28.70 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -7611 E-226 x -119b8744033457_0000000000000000001& E-738
+    convertToDouble -7611E-226
+} 0x91d19b8744033457
+test expr-28.71 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +4907 E-196 x 11e90a8711440f_000000000000000001& E-639
+    convertToDouble +4907E-196
+} 0x1801e90a8711440f
+test expr-28.72 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -5547 E-311 x -13f190452a29f4_000000000000000001& E-1021
+    convertToDouble -5547E-311
+} 0x8023f190452a29f4
+test expr-28.73 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +5311 E241 x 1f1ce3c887c25f_11111111111111111110& E812
+    convertToDouble +5311E241
+} 0x72bf1ce3c887c260
+test expr-28.74 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -5311 E243 x -184e91f4aa0fda_11111111111111111110& E819
+    convertToDouble -5311E243
+} 0xf3284e91f4aa0fdb
+test expr-28.75 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +5311 E242 x 13720e5d54d97b_11111111111111111110& E816
+    convertToDouble +5311E242
+} 0x72f3720e5d54d97c
+test expr-28.76 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +9269 E-45 x 19d69455a53bd8_111111111111111111110& E-137
+    convertToDouble +9269E-45
+} 0x3769d69455a53bd9
+test expr-28.77 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -8559 E-289 x -104a81d35952fe_11111111111111111110& E-947
+    convertToDouble -8559E-289
+} 0x84c04a81d35952ff
+test expr-28.78 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +8699 E-276 x 12d2df246ecd2c_1111111111111111111110& E-904
+    convertToDouble +8699E-276
+} 0x0772d2df246ecd2d
+test expr-28.79 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -8085 E-64 x -14c98fce16152d_1111111111111111110& E-200
+    convertToDouble -8085E-64
+} 0xb374c98fce16152e
+test expr-28.80 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +74819 E201 x 1dd455061eb3f1_0000000000000000000001& E683
+    convertToDouble +74819E201
+} 0x6aadd455061eb3f1
+test expr-28.81 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -82081 E41 x -170105df3d47cb_000000000000000000000000001& E152
+    convertToDouble -82081E41
+} 0xc9770105df3d47cb
+test expr-28.82 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +51881 E37 x 17d2950dc76da4_000000000000000000001& E138
+    convertToDouble +51881E37
+} 0x4897d2950dc76da4
+test expr-28.83 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -55061 E157 x -1394fc0f33536c_000000000000000000001& E537
+    convertToDouble -55061E157
+} 0xe18394fc0f33536c
+test expr-28.84 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +77402 E-215 x 10492a4a8a37fd_0000000000000000000000001& E-698
+    convertToDouble +77402E-215
+} 0x1450492a4a8a37fd
+test expr-28.85 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -33891 E-92 x -1592f9932c06bd_00000000000000000000001& E-291
+    convertToDouble -33891E-92
+} 0xadc592f9932c06bd
+test expr-28.86 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +38701 E-215 x 10492a4a8a37fd_0000000000000000000000001& E-699
+    convertToDouble +38701E-215
+} 0x1440492a4a8a37fd
+test expr-28.87 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -82139 E-76 x -1d0681489839d5_00000000000000000000001& E-237
+    convertToDouble -82139E-76
+} 0xb12d0681489839d5
+test expr-28.88 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +75859 E25 x 132645e1ba93ef_11111111111111111111110& E99
+    convertToDouble +75859E25
+} 0x46232645e1ba93f0
+test expr-28.89 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +89509 E140 x 16f02bee68670c_1111111111111111111110& E481
+    convertToDouble +89509E140
+} 0x5e06f02bee68670d
+test expr-28.90 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -57533 E287 x -1272ed2307f569_1111111111111111111110& E969
+    convertToDouble -57533E287
+} 0xfc8272ed2307f56a
+test expr-28.91 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +46073 E-32 x 12405b773fbdf2_11111111111111111111110& E-91
+    convertToDouble +46073E-32
+} 0x3a42405b773fbdf3
+test expr-28.92 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -92146 E-32 x -12405b773fbdf2_11111111111111111111110& E-90
+    convertToDouble -92146E-32
+} 0xba52405b773fbdf3
+test expr-28.93 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +83771 E-74 x 17206bfc4ccabd_11111111111111111111110& E-230
+    convertToDouble +83771E-74
+} 0x3197206bfc4ccabe
+test expr-28.94 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -34796 E-276 x -12d2df246ecd2c_1111111111111111111110& E-902
+    convertToDouble -34796E-276
+} 0x8792d2df246ecd2d
+test expr-28.95 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +584169 E229 x 1d657059dc79aa_00000000000000000000000000001& E779
+    convertToDouble +584169E229
+} 0x70ad657059dc79aa
+test expr-28.96 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +164162 E41 x 170105df3d47cb_000000000000000000000000001& E153
+    convertToDouble +164162E41
+} 0x49870105df3d47cb
+test expr-28.97 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -328324 E41 x -170105df3d47cb_000000000000000000000000001& E154
+    convertToDouble -328324E41
+} 0xc9970105df3d47cb
+test expr-28.98 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +209901 E-11 x 119b96f36ec68b_00000000000000000000000001& E-19
+    convertToDouble +209901E-11
+} 0x3ec19b96f36ec68b
+test expr-28.99 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -419802 E-11 x -119b96f36ec68b_00000000000000000000000001& E-18
+    convertToDouble -419802E-11
+} 0xbed19b96f36ec68b
+test expr-28.100 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +940189 E-112 x 1b99d6240c1a28_00000000000000000000000001& E-353
+    convertToDouble +940189E-112
+} 0x29eb99d6240c1a28
+test expr-28.101 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -892771 E-213 x -125818c7294f27_0000000000000000000000000001& E-688
+    convertToDouble -892771E-213
+} 0x94f25818c7294f27
+test expr-28.102 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +757803 E120 x 11e968b555bb80_11111111111111111111111111110& E418
+    convertToDouble +757803E120
+} 0x5a11e968b555bb81
+test expr-28.103 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -252601 E120 x -17e1e0f1c7a4ab_11111111111111111111111111110& E416
+    convertToDouble -252601E120
+} 0xd9f7e1e0f1c7a4ac
+test expr-28.104 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +252601 E121 x 1dda592e398dd6_1111111111111111111111111110& E419
+    convertToDouble +252601E121
+} 0x5a2dda592e398dd7
+test expr-28.105 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -505202 E120 x -17e1e0f1c7a4ab_11111111111111111111111111110& E417
+    convertToDouble -505202E120
+} 0xda07e1e0f1c7a4ac
+test expr-28.106 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +970811 E-264 x 1dda6b965c9629_11111111111111111111111110& E-858
+    convertToDouble +970811E-264
+} 0x0a5dda6b965c962a
+test expr-28.107 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -654839 E-60 x -100e7db3b3f241_111111111111111111111111110& E-180
+    convertToDouble -654839E-60
+} 0xb4b00e7db3b3f242
+test expr-28.108 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +289767 E-178 x 1caad28f23a100_11111111111111111111111110& E-574
+    convertToDouble +289767E-178
+} 0x1c1caad28f23a101
+test expr-28.109 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -579534 E-178 x -1caad28f23a100_11111111111111111111111110& E-573
+    convertToDouble -579534E-178
+} 0x9c2caad28f23a101
+test expr-28.110 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -8823691 E130 x -1e597c0b94b7ae_00000000000000000000000000000001& E454
+    convertToDouble -8823691E130
+} 0xdc5e597c0b94b7ae
+test expr-28.111 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +9346704 E229 x 1d657059dc79aa_00000000000000000000000000001& E783
+    convertToDouble +9346704E229
+} 0x70ed657059dc79aa
+test expr-28.112 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -1168338 E229 x -1d657059dc79aa_00000000000000000000000000001& E780
+    convertToDouble -1168338E229
+} 0xf0bd657059dc79aa
+test expr-28.113 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -6063369 E-136 x -1ae6148e3902b3_000000000000000000000000000001& E-430
+    convertToDouble -6063369E-136
+} 0xa51ae6148e3902b3
+test expr-28.114 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +3865421 E-225 x 15d4fe53afec65_00000000000000000000000000001& E-726
+    convertToDouble +3865421E-225
+} 0x1295d4fe53afec65
+test expr-28.115 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -5783893 E-127 x -17e5902ce0e151_000000000000000000000000000000001& E-400
+    convertToDouble -5783893E-127
+} 0xa6f7e5902ce0e151
+test expr-28.116 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +2572231 E223 x 10f73be1dff9ac_111111111111111111111111111110& E762
+    convertToDouble +2572231E223
+} 0x6f90f73be1dff9ad
+test expr-28.117 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -5144462 E223 x -10f73be1dff9ac_111111111111111111111111111110& E763
+    convertToDouble -5144462E223
+} 0xefa0f73be1dff9ad
+test expr-28.118 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +1817623 E109 x 1d85f96f3fe659_11111111111111111111111111110& E382
+    convertToDouble +1817623E109
+} 0x57dd85f96f3fe65a
+test expr-28.119 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +6431543 E-97 x 14f6493f34a0bc_11111111111111111111111111110& E-300
+    convertToDouble +6431543E-97
+} 0x2d34f6493f34a0bd
+test expr-28.120 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -5444097 E-21 x -18849dd33c95ae_11111111111111111111111111110& E-48
+    convertToDouble -5444097E-21
+} 0xbcf8849dd33c95af
+test expr-28.121 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +8076999 E-121 x 1fd332f7e2e3b2_11111111111111111111111111110& E-380
+    convertToDouble +8076999E-121
+} 0x283fd332f7e2e3b3
+test expr-28.122 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -9997649 E-270 x -1425e9d29e558d_1111111111111111111111111110& E-874
+    convertToDouble -9997649E-270
+} 0x895425e9d29e558e
+test expr-28.123 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +50609263 E157 x 1193aff1f1c8e3_000000000000000000000000000000001& E547
+    convertToDouble +50609263E157
+} 0x622193aff1f1c8e3
+test expr-28.124 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +70589528 E130 x 1e597c0b94b7ae_00000000000000000000000000000001& E457
+    convertToDouble +70589528E130
+} 0x5c8e597c0b94b7ae
+test expr-28.125 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -88236910 E129 x -1e597c0b94b7ae_00000000000000000000000000000001& E454
+    convertToDouble -88236910E129
+} 0xdc5e597c0b94b7ae
+test expr-28.126 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +87575437 E-310 x 1805c19e680456_0000000000000000000000000000000000001& E-1004
+    convertToDouble +87575437E-310
+} 0x013805c19e680456
+test expr-28.127 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -23135572 E-127 x -17e5902ce0e151_000000000000000000000000000000001& E-398
+    convertToDouble -23135572E-127
+} 0xa717e5902ce0e151
+test expr-28.128 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +85900881 E177 x 14375b2214e1b4_111111111111111111111111111111110& E614
+    convertToDouble +85900881E177
+} 0x6654375b2214e1b5
+test expr-28.129 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -84863171 E113 x -1a4a8e56474b8b_111111111111111111111111111111110& E401
+    convertToDouble -84863171E113
+} 0xd90a4a8e56474b8c
+test expr-28.130 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +68761586 E232 x 1a662c350f37f2_1111111111111111111111111111110& E796
+    convertToDouble +68761586E232
+} 0x71ba662c350f37f3
+test expr-28.131 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -50464069 E286 x -1948dd06de561e_1111111111111111111111111111110& E975
+    convertToDouble -50464069E286
+} 0xfce948dd06de561f
+test expr-28.132 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +27869147 E-248 x 1dbbac6f83a820_111111111111111111111111111111111110& E-800
+    convertToDouble +27869147E-248
+} 0x0dfdbbac6f83a821
+test expr-28.133 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -55738294 E-248 x -1dbbac6f83a820_111111111111111111111111111111111110& E-799
+    convertToDouble -55738294E-248
+} 0x8e0dbbac6f83a821
+test expr-28.134 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +70176353 E-53 x 100683a21de854_1111111111111111111111111111111110& E-150
+    convertToDouble +70176353E-53
+} 0x36900683a21de855
+test expr-28.135 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -80555086 E-32 x -1f29ca0ff893b0_111111111111111111111111111111110& E-81
+    convertToDouble -80555086E-32
+} 0xbaef29ca0ff893b1
+test expr-28.136 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -491080654 E121 x -1c569e968e0944_00000000000000000000000000000000000000001& E430
+    convertToDouble -491080654E121
+} 0xdadc569e968e0944
+test expr-28.137 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +526250918 E287 x 14997a298b2f2e_0000000000000000000000000000000000001& E982
+    convertToDouble +526250918E287
+} 0x7d54997a298b2f2e
+test expr-28.138 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -245540327 E121 x -1c569e968e0944_00000000000000000000000000000000000000001& E429
+    convertToDouble -245540327E121
+} 0xdacc569e968e0944
+test expr-28.139 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -175150874 E-310 x -1805c19e680456_0000000000000000000000000000000000001& E-1003
+    convertToDouble -175150874E-310
+} 0x814805c19e680456
+test expr-28.140 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +350301748 E-310 x 1805c19e680456_0000000000000000000000000000000000001& E-1002
+    convertToDouble +350301748E-310
+} 0x015805c19e680456
+test expr-28.141 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -437877185 E-311 x -1805c19e680456_0000000000000000000000000000000000001& E-1005
+    convertToDouble -437877185E-311
+} 0x812805c19e680456
+test expr-28.142 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +458117166 E52 x 16ce94febdc7a4_1111111111111111111111111111111111110& E201
+    convertToDouble +458117166E52
+} 0x4c86ce94febdc7a5
+test expr-28.143 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -916234332 E52 x -16ce94febdc7a4_1111111111111111111111111111111111110& E202
+    convertToDouble -916234332E52
+} 0xcc96ce94febdc7a5
+test expr-28.144 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +229058583 E52 x 16ce94febdc7a4_1111111111111111111111111111111111110& E200
+    convertToDouble +229058583E52
+} 0x4c76ce94febdc7a5
+test expr-28.145 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -525789935 E98 x -16ecdc2a58fc64_11111111111111111111111111111111110& E354
+    convertToDouble -525789935E98
+} 0xd616ecdc2a58fc65
+test expr-28.146 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +282926897 E-227 x 1ff5a70d3d2fee_1111111111111111111111111111111111110& E-727
+    convertToDouble +282926897E-227
+} 0x128ff5a70d3d2fef
+test expr-28.147 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -565853794 E-227 x -1ff5a70d3d2fee_1111111111111111111111111111111111110& E-726
+    convertToDouble -565853794E-227
+} 0x929ff5a70d3d2fef
+test expr-28.148 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +667284113 E-240 x 109355f8050c01_111111111111111111111111111111111110& E-768
+    convertToDouble +667284113E-240
+} 0x0ff09355f8050c02
+test expr-28.149 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -971212611 E-126 x -1397d3c9745d2e_111111111111111111111111111111111111110& E-389
+    convertToDouble -971212611E-126
+} 0xa7a397d3c9745d2f
+test expr-28.150 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +9981396317 E-182 x 18afe10a2a66aa_0000000000000000000000000000000000000001& E-572
+    convertToDouble +9981396317E-182
+} 0x1c38afe10a2a66aa
+test expr-28.151 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -5035231965 E-156 x -101891fc4717fd_00000000000000000000000000000000000001& E-486
+    convertToDouble -5035231965E-156
+} 0xa1901891fc4717fd
+test expr-28.152 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +8336960483 E-153 x 1a06a1024b95e1_000000000000000000000000000000000000001& E-476
+    convertToDouble +8336960483E-153
+} 0x223a06a1024b95e1
+test expr-28.153 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -8056371144 E-155 x -101891fc4717fd_00000000000000000000000000000000000001& E-482
+    convertToDouble -8056371144E-155
+} 0xa1d01891fc4717fd
+test expr-28.154 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +6418488827 E79 x 1021f14ed7b3f9_11111111111111111111111111111111111111110& E295
+    convertToDouble +6418488827E79
+} 0x526021f14ed7b3fa
+test expr-28.155 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -3981006983 E252 x -102ebaf189d5f1_1111111111111111111111111111111111111110& E869
+    convertToDouble -3981006983E252
+} 0xf6402ebaf189d5f2
+test expr-28.156 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +7962013966 E252 x 102ebaf189d5f1_1111111111111111111111111111111111111110& E870
+    convertToDouble +7962013966E252
+} 0x76502ebaf189d5f2
+test expr-28.157 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -4713898551 E261 x -11d8813536e0df_11111111111111111111111111111111111110& E899
+    convertToDouble -4713898551E261
+} 0xf821d8813536e0e0
+test expr-28.158 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +8715380633 E-58 x 14614c3219891e_11111111111111111111111111111111111111110& E-160
+    convertToDouble +8715380633E-58
+} 0x35f4614c3219891f
+test expr-28.159 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -9078555839 E-109 x -1fc575867314ed_111111111111111111111111111111111111111111110& E-330
+    convertToDouble -9078555839E-109
+} 0xab5fc575867314ee
+test expr-28.160 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +9712126110 E-127 x 1397d3c9745d2e_111111111111111111111111111111111111110& E-389
+    convertToDouble +9712126110E-127
+} 0x27a397d3c9745d2f
+test expr-28.161 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +42333842451 E201 x 10189a26df575f_000000000000000000000000000000000000000000001& E703
+    convertToDouble +42333842451E201
+} 0x6be0189a26df575f
+test expr-28.162 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -84667684902 E201 x -10189a26df575f_000000000000000000000000000000000000000000001& E704
+    convertToDouble -84667684902E201
+} 0xebf0189a26df575f
+test expr-28.163 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +23792120709 E-315 x 10b517dc5d3212_00000000000000000000000000000000000000001& E-1012
+    convertToDouble +23792120709E-315
+} 0x00b0b517dc5d3212
+test expr-28.164 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -78564021519 E-227 x -1155515fd37265_00000000000000000000000000000000000000000001& E-718
+    convertToDouble -78564021519E-227
+} 0x931155515fd37265
+test expr-28.165 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +71812054883 E-188 x 1747b46d78c6fe_00000000000000000000000000000000000000001& E-589
+    convertToDouble +71812054883E-188
+} 0x1b2747b46d78c6fe
+test expr-28.166 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -30311163631 E-116 x -163ef6f560afe7_00000000000000000000000000000000000000001& E-351
+    convertToDouble -30311163631E-116
+} 0xaa063ef6f560afe7
+test expr-28.167 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +71803914657 E292 x 10c0c44cdc2c05_11111111111111111111111111111111111111111110& E1006
+    convertToDouble +71803914657E292
+} 0x7ed0c0c44cdc2c06
+test expr-28.168 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +36314223356 E-109 x 1fc575867314ed_111111111111111111111111111111111111111111110& E-328
+    convertToDouble +36314223356E-109
+} 0x2b7fc575867314ee
+test expr-28.169 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +18157111678 E-109 x 1fc575867314ed_111111111111111111111111111111111111111111110& E-329
+    convertToDouble +18157111678E-109
+} 0x2b6fc575867314ee
+test expr-28.170 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -45392779195 E-110 x -1fc575867314ed_111111111111111111111111111111111111111111110& E-331
+    convertToDouble -45392779195E-110
+} 0xab4fc575867314ee
+test expr-28.171 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +778380362293 E218 x 19ab8261990292_0000000000000000000000000000000000000000000000000001& E763
+    convertToDouble +778380362293E218
+} 0x6fa9ab8261990292
+test expr-28.172 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -685763015669 E280 x -15fd7aa44d9477_000000000000000000000000000000000000000000000001& E969
+    convertToDouble -685763015669E280
+} 0xfc85fd7aa44d9477
+test expr-28.173 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +952918668151 E70 x 14177a9915fbf8_00000000000000000000000000000000000000000000001& E272
+    convertToDouble +952918668151E70
+} 0x50f4177a9915fbf8
+test expr-28.174 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -548357443505 E32 x -13abde2775e9b5_0000000000000000000000000000000000000000000001& E145
+    convertToDouble -548357443505E32
+} 0xc903abde2775e9b5
+test expr-28.175 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +384865004907 E-285 x 1aa65b58639e69_00000000000000000000000000000000000000000000001& E-909
+    convertToDouble +384865004907E-285
+} 0x072aa65b58639e69
+test expr-28.176 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -769730009814 E-285 x -1aa65b58639e69_00000000000000000000000000000000000000000000001& E-908
+    convertToDouble -769730009814E-285
+} 0x873aa65b58639e69
+test expr-28.177 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +697015418417 E-93 x 152847dad80453_0000000000000000000000000000000000000000000001& E-270
+    convertToDouble +697015418417E-93
+} 0x2f152847dad80453
+test expr-28.178 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -915654049301 E-28 x -1a645598d05989_0000000000000000000000000000000000000000000001& E-54
+    convertToDouble -915654049301E-28
+} 0xbc9a645598d05989
+test expr-28.179 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +178548656339 E169 x 1b89d67c5b6d24_111111111111111111111111111111111111111111110& E598
+    convertToDouble +178548656339E169
+} 0x655b89d67c5b6d25
+test expr-28.180 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -742522891517 E259 x -1c1c352fc3c308_11111111111111111111111111111111111111111111110& E899
+    convertToDouble -742522891517E259
+} 0xf82c1c352fc3c309
+test expr-28.181 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +742522891517 E258 x 167cf7596968d3_11111111111111111111111111111111111111111111110& E896
+    convertToDouble +742522891517E258
+} 0x77f67cf7596968d4
+test expr-28.182 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -357097312678 E169 x -1b89d67c5b6d24_111111111111111111111111111111111111111111110& E599
+    convertToDouble -357097312678E169
+} 0xe56b89d67c5b6d25
+test expr-28.183 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -3113521449172 E218 x -19ab8261990292_0000000000000000000000000000000000000000000000000001& E765
+    convertToDouble -3113521449172E218
+} 0xefc9ab8261990292
+test expr-28.184 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +3891901811465 E217 x 19ab8261990292_0000000000000000000000000000000000000000000000000001& E762
+    convertToDouble +3891901811465E217
+} 0x6f99ab8261990292
+test expr-28.185 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -1556760724586 E218 x -19ab8261990292_0000000000000000000000000000000000000000000000000001& E764
+    convertToDouble -1556760724586E218
+} 0xefb9ab8261990292
+test expr-28.186 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +9997878507563 E-195 x 153db2fea1ea31_0000000000000000000000000000000000000000000000001& E-605
+    convertToDouble +9997878507563E-195
+} 0x1a253db2fea1ea31
+test expr-28.187 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -7247563029154 E-319 x -10493f056e9ef3_0000000000000000000000000000000000000000000000001& E-1017
+    convertToDouble -7247563029154E-319
+} 0x8060493f056e9ef3
+test expr-28.188 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +3623781514577 E-319 x 10493f056e9ef3_0000000000000000000000000000000000000000000000001& E-1018
+    convertToDouble +3623781514577E-319
+} 0x0050493f056e9ef3
+test expr-28.189 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -3092446298323 E-200 x -113918353bbc47_0000000000000000000000000000000000000000000000001& E-623
+    convertToDouble -3092446298323E-200
+} 0x99013918353bbc47
+test expr-28.190 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +6363857920591 E145 x 128a61cf9483b6_1111111111111111111111111111111111111111111111111110& E524
+    convertToDouble +6363857920591E145
+} 0x60b28a61cf9483b7
+test expr-28.191 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -8233559360849 E94 x -11f324d11d4861_1111111111111111111111111111111111111111111111110& E355
+    convertToDouble -8233559360849E94
+} 0xd621f324d11d4862
+test expr-28.192 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +2689845954547 E49 x 10bd2bfd34f98a_1111111111111111111111111111111111111111111111110& E204
+    convertToDouble +2689845954547E49
+} 0x4cb0bd2bfd34f98b
+test expr-28.193 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -5379691909094 E49 x -10bd2bfd34f98a_1111111111111111111111111111111111111111111111110& E205
+    convertToDouble -5379691909094E49
+} 0xccc0bd2bfd34f98b
+test expr-28.194 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +5560322501926 E-301 x 15acc2053064c1_11111111111111111111111111111111111111111111111110& E-958
+    convertToDouble +5560322501926E-301
+} 0x0415acc2053064c2
+test expr-28.195 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -7812878489261 E-179 x -126dae7bbeda74_11111111111111111111111111111111111111111111111111110& E-552
+    convertToDouble -7812878489261E-179
+} 0x9d726dae7bbeda75
+test expr-28.196 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +8439398533053 E-256 x 170cc285f2d209_1111111111111111111111111111111111111111111111110& E-808
+    convertToDouble +8439398533053E-256
+} 0x0d770cc285f2d20a
+test expr-28.197 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -2780161250963 E-301 x -15acc2053064c1_11111111111111111111111111111111111111111111111110& E-959
+    convertToDouble -2780161250963E-301
+} 0x8405acc2053064c2
+test expr-28.198 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -87605699161665 E155 x -12920f96e7f9ef_00000000000000000000000000000000000000000000000000001& E561
+    convertToDouble -87605699161665E155
+} 0xe302920f96e7f9ef
+test expr-28.199 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -17521139832333 E156 x -12920f96e7f9ef_00000000000000000000000000000000000000000000000000001& E562
+    convertToDouble -17521139832333E156
+} 0xe312920f96e7f9ef
+test expr-28.200 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -88218101363513 E-170 x -18395688592faf_0000000000000000000000000000000000000000000000000001& E-519
+    convertToDouble -88218101363513E-170
+} 0x9f88395688592faf
+test expr-28.201 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +38639244311627 E-115 x 114ef3e205c817_0000000000000000000000000000000000000000000000000001& E-337
+    convertToDouble +38639244311627E-115
+} 0x2ae14ef3e205c817
+test expr-28.202 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +35593959807306 E261 x 1072f3819c1320_11111111111111111111111111111111111111111111111111110& E912
+    convertToDouble +35593959807306E261
+} 0x78f072f3819c1321
+test expr-28.203 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -53390939710959 E260 x -13bd243521b08d_11111111111111111111111111111111111111111111111111110& E909
+    convertToDouble -53390939710959E260
+} 0xf8c3bd243521b08e
+test expr-28.204 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +71187919614612 E261 x 1072f3819c1320_11111111111111111111111111111111111111111111111111110& E913
+    convertToDouble +71187919614612E261
+} 0x790072f3819c1321
+test expr-28.205 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -88984899518265 E260 x -1072f3819c1320_11111111111111111111111111111111111111111111111111110& E910
+    convertToDouble -88984899518265E260
+} 0xf8d072f3819c1321
+test expr-28.206 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +77003665618895 E-73 x 18bf7e7fa6f029_111111111111111111111111111111111111111111111111111111110& E-197
+    convertToDouble +77003665618895E-73
+} 0x33a8bf7e7fa6f02a
+test expr-28.207 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -15400733123779 E-72 x -18bf7e7fa6f029_111111111111111111111111111111111111111111111111111111110& E-196
+    convertToDouble -15400733123779E-72
+} 0xb3b8bf7e7fa6f02a
+test expr-28.208 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +61602932495116 E-72 x 18bf7e7fa6f029_111111111111111111111111111111111111111111111111111111110& E-194
+    convertToDouble +61602932495116E-72
+} 0x33d8bf7e7fa6f02a
+test expr-28.209 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -30801466247558 E-72 x -18bf7e7fa6f029_111111111111111111111111111111111111111111111111111111110& E-195
+    convertToDouble -30801466247558E-72
+} 0xb3c8bf7e7fa6f02a
+test expr-28.210 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +834735494917063 E-300 x 1fc6c26f899dd1_0000000000000000000000000000000000000000000000000000000001& E-948
+    convertToDouble +834735494917063E-300
+} 0x04bfc6c26f899dd1
+test expr-28.211 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -589795149206434 E-151 x -15f2df5e675a0f_0000000000000000000000000000000000000000000000000000000001& E-453
+    convertToDouble -589795149206434E-151
+} 0xa3a5f2df5e675a0f
+test expr-28.212 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +475603213226859 E-42 x 12d73088f4050a_000000000000000000000000000000000000000000000000000000001& E-91
+    convertToDouble +475603213226859E-42
+} 0x3a42d73088f4050a
+test expr-28.213 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -294897574603217 E-151 x -15f2df5e675a0f_0000000000000000000000000000000000000000000000000000000001& E-454
+    convertToDouble -294897574603217E-151
+} 0xa395f2df5e675a0f
+test expr-28.214 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +850813008001913 E93 x 172f7a1831ad70_11111111111111111111111111111111111111111111111111111110& E358
+    convertToDouble +850813008001913E93
+} 0x56572f7a1831ad71
+test expr-28.215 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -203449172043339 E185 x -1102b47e4af987_11111111111111111111111111111111111111111111111111111110& E662
+    convertToDouble -203449172043339E185
+} 0xe95102b47e4af988
+test expr-28.216 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +406898344086678 E185 x 1102b47e4af987_11111111111111111111111111111111111111111111111111111110& E663
+    convertToDouble +406898344086678E185
+} 0x696102b47e4af988
+test expr-28.217 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -813796688173356 E185 x -1102b47e4af987_11111111111111111111111111111111111111111111111111111110& E664
+    convertToDouble -813796688173356E185
+} 0xe97102b47e4af988
+test expr-28.218 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +6045338514609393 E244 x 1f746182e6cd5d_00000000000000000000000000000000000000000000000000000000001& E862
+    convertToDouble +6045338514609393E244
+} 0x75df746182e6cd5d
+test expr-28.219 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -5145963778954906 E142 x -1dfc11fbf46087_00000000000000000000000000000000000000000000000000000000001& E523
+    convertToDouble -5145963778954906E142
+} 0xe0adfc11fbf46087
+test expr-28.220 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +2572981889477453 E142 x 1dfc11fbf46087_00000000000000000000000000000000000000000000000000000000001& E522
+    convertToDouble +2572981889477453E142
+} 0x609dfc11fbf46087
+test expr-28.221 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -6965949469487146 E74 x -15e2c10ad970b0_0000000000000000000000000000000000000000000000000000000001& E298
+    convertToDouble -6965949469487146E74
+} 0xd295e2c10ad970b0
+test expr-28.222 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +6182410494241627 E-119 x 11b96458445d07_0000000000000000000000000000000000000000000000000000000000001& E-343
+    convertToDouble +6182410494241627E-119
+} 0x2a81b96458445d07
+test expr-28.223 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -8510309498186985 E-277 x -1acc46749dccfe_000000000000000000000000000000000000000000000000000000000001& E-868
+    convertToDouble -8510309498186985E-277
+} 0x89bacc46749dccfe
+test expr-28.224 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +6647704637273331 E-212 x 13e07d2c0cb1e9_0000000000000000000000000000000000000000000000000000000000001& E-652
+    convertToDouble +6647704637273331E-212
+} 0x1733e07d2c0cb1e9
+test expr-28.225 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -2215901545757777 E-212 x -1a80a6e566428c_000000000000000000000000000000000000000000000000000000000001& E-654
+    convertToDouble -2215901545757777E-212
+} 0x971a80a6e566428c
+test expr-28.226 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +3771476185376383 E276 x 183010aba78a53_111111111111111111111111111111111111111111111111111111111110& E968
+    convertToDouble +3771476185376383E276
+} 0x7c783010aba78a54
+test expr-28.227 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -3729901848043846 E212 x -1f7d6721f7f143_111111111111111111111111111111111111111111111111111111111110& E755
+    convertToDouble -3729901848043846E212
+} 0xef2f7d6721f7f144
+test expr-28.228 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +3771476185376383 E277 x 1e3c14d6916ce8_111111111111111111111111111111111111111111111111111111111110& E971
+    convertToDouble +3771476185376383E277
+} 0x7cae3c14d6916ce9
+test expr-28.229 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -9977830465649166 E119 x -15f6de9d5d6b5a_111111111111111111111111111111111111111111111111111111111110& E448
+    convertToDouble -9977830465649166E119
+} 0xdbf5f6de9d5d6b5b
+test expr-28.230 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +8439928496349319 E-142 x 12483a0f125699_111111111111111111111111111111111111111111111111111111111110& E-419
+    convertToDouble +8439928496349319E-142
+} 0x25c2483a0f12569a
+test expr-28.231 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -8204230082070882 E-59 x -1d460f4fca1d36_1111111111111111111111111111111111111111111111111111111110& E-144
+    convertToDouble -8204230082070882E-59
+} 0xb6fd460f4fca1d37
+test expr-28.232 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +8853686434843997 E-244 x 157a340eb5d4f0_11111111111111111111111111111111111111111111111111111111110& E-758
+    convertToDouble +8853686434843997E-244
+} 0x10957a340eb5d4f1
+test expr-28.233 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -5553274272288559 E-104 x -1c47d20a19d1ed_1111111111111111111111111111111111111111111111111111111110& E-294
+    convertToDouble -5553274272288559E-104
+} 0xad9c47d20a19d1ee
+test expr-28.234 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +36149023611096162 E144 x 1491daad0ba280_0000000000000000000000000000000000000000000000000000000000000001& E533
+    convertToDouble +36149023611096162E144
+} 0x614491daad0ba280
+test expr-28.235 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -36149023611096162 E147 x -14166f8cfd5cb1_0000000000000000000000000000000000000000000000000000000000000001& E543
+    convertToDouble -36149023611096162E147
+} 0xe1e4166f8cfd5cb1
+test expr-28.236 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +18074511805548081 E146 x 1011f2d73116f4_0000000000000000000000000000000000000000000000000000000000000001& E539
+    convertToDouble +18074511805548081E146
+} 0x61a011f2d73116f4
+test expr-28.237 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -18074511805548081 E147 x -14166f8cfd5cb1_0000000000000000000000000000000000000000000000000000000000000001& E542
+    convertToDouble -18074511805548081E147
+} 0xe1d4166f8cfd5cb1
+test expr-28.238 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +97338774138954421 E-290 x 10d9b828199006_0000000000000000000000000000000000000000000000000000000000000001& E-907
+    convertToDouble +97338774138954421E-290
+} 0x0740d9b828199006
+test expr-28.239 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -88133809804950961 E-308 x -119710dc581911_000000000000000000000000000000000000000000000000000000000000001& E-967
+    convertToDouble -88133809804950961E-308
+} 0x83819710dc581911
+test expr-28.240 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +94080055902682397 E-243 x 11d467e94b856e_0000000000000000000000000000000000000000000000000000000000000001& E-751
+    convertToDouble +94080055902682397E-243
+} 0x1101d467e94b856e
+test expr-28.241 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -24691002732654881 E-115 x -159a2783ce70ab_000000000000000000000000000000000000000000000000000000000000001& E-328
+    convertToDouble -24691002732654881E-115
+} 0xab759a2783ce70ab
+test expr-28.242 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +52306490527514614 E49 x 13de005bd620de_111111111111111111111111111111111111111111111111111111111111111110& E218
+    convertToDouble +52306490527514614E49
+} 0x4d93de005bd620df
+test expr-28.243 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -26153245263757307 E49 x -13de005bd620de_111111111111111111111111111111111111111111111111111111111111111110& E217
+    convertToDouble -26153245263757307E49
+} 0xcd83de005bd620df
+test expr-28.244 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +55188692254193604 E165 x 1a999ddec72ac9_11111111111111111111111111111111111111111111111111111111111110& E603
+    convertToDouble +55188692254193604E165
+} 0x65aa999ddec72aca
+test expr-28.245 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -68985865317742005 E164 x -1a999ddec72ac9_11111111111111111111111111111111111111111111111111111111111110& E600
+    convertToDouble -68985865317742005E164
+} 0xe57a999ddec72aca
+test expr-28.246 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +27176258005319167 E-261 x 17c0747bd76fa0_11111111111111111111111111111111111111111111111111111111111111110& E-813
+    convertToDouble +27176258005319167E-261
+} 0x0d27c0747bd76fa1
+test expr-28.247 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -73169230107256116 E-248 x -122cea327fa99c_1111111111111111111111111111111111111111111111111111111111110& E-768
+    convertToDouble -73169230107256116E-248
+} 0x8ff22cea327fa99d
+test expr-28.248 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +91461537634070145 E-249 x 122cea327fa99c_1111111111111111111111111111111111111111111111111111111111110& E-771
+    convertToDouble +91461537634070145E-249
+} 0x0fc22cea327fa99d
+test expr-28.249 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -54352516010638334 E-261 x -17c0747bd76fa0_11111111111111111111111111111111111111111111111111111111111111110& E-812
+    convertToDouble -54352516010638334E-261
+} 0x8d37c0747bd76fa1
+test expr-28.250 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +586144289638535878 E280 x 11eccbd6f62709_0000000000000000000000000000000000000000000000000000000000000000001& E989
+    convertToDouble +586144289638535878E280
+} 0x7dc1eccbd6f62709
+test expr-28.251 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -601117006785295431 E245 x -1e8b3525b3737e_000000000000000000000000000000000000000000000000000000000000000001& E872
+    convertToDouble -601117006785295431E245
+} 0xf67e8b3525b3737e
+test expr-28.252 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +293072144819267939 E280 x 11eccbd6f62709_0000000000000000000000000000000000000000000000000000000000000000001& E988
+    convertToDouble +293072144819267939E280
+} 0x7db1eccbd6f62709
+test expr-28.253 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -953184713238516652 E272 x -138fd93f1f5342_00000000000000000000000000000000000000000000000000000000000000001& E963
+    convertToDouble -953184713238516652E272
+} 0xfc238fd93f1f5342
+test expr-28.254 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +902042358290366539 E-281 x 122dc01ca1cb8c_0000000000000000000000000000000000000000000000000000000000000000001& E-874
+    convertToDouble +902042358290366539E-281
+} 0x09522dc01ca1cb8c
+test expr-28.255 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -557035730189854663 E-294 x -13bfac6bc4767b_00000000000000000000000000000000000000000000000000000000000000000001& E-918
+    convertToDouble -557035730189854663E-294
+} 0x8693bfac6bc4767b
+test expr-28.256 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +902042358290366539 E-280 x 16b93023ca3e6f_0000000000000000000000000000000000000000000000000000000000000000001& E-871
+    convertToDouble +902042358290366539E-280
+} 0x0986b93023ca3e6f
+test expr-28.257 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -354944100507554393 E-238 x -19a91cece6ad07_000000000000000000000000000000000000000000000000000000000000000001& E-733
+    convertToDouble -354944100507554393E-238
+} 0x9229a91cece6ad07
+test expr-28.258 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +272104041512242479 E199 x 1f92bacb3cb40b_11111111111111111111111111111111111111111111111111111111111111111111110& E718
+    convertToDouble +272104041512242479E199
+} 0x6cdf92bacb3cb40c
+test expr-28.259 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -816312124536727437 E199 x -17ae0c186d8708_11111111111111111111111111111111111111111111111111111111111111111111110& E720
+    convertToDouble -816312124536727437E199
+} 0xecf7ae0c186d8709
+test expr-28.260 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +544208083024484958 E199 x 1f92bacb3cb40b_11111111111111111111111111111111111111111111111111111111111111111111110& E719
+    convertToDouble +544208083024484958E199
+} 0x6cef92bacb3cb40c
+test expr-28.261 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -792644927852378159 E78 x -17bff336d8ff05_111111111111111111111111111111111111111111111111111111111111111111110& E318
+    convertToDouble -792644927852378159E78
+} 0xd3d7bff336d8ff06
+test expr-28.262 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -679406450132979175 E-263 x -17c0747bd76fa0_11111111111111111111111111111111111111111111111111111111111111110& E-815
+    convertToDouble -679406450132979175E-263
+} 0x8d07c0747bd76fa1
+test expr-28.263 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +543525160106383340 E-262 x 17c0747bd76fa0_11111111111111111111111111111111111111111111111111111111111111110& E-812
+    convertToDouble +543525160106383340E-262
+} 0x0d37c0747bd76fa1
+test expr-28.264 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +7400253695682920196 E215 x 1dca94e3990085_00000000000000000000000000000000000000000000000000000000000000000000001& E776
+    convertToDouble +7400253695682920196E215
+} 0x707dca94e3990085
+test expr-28.265 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -1850063423920730049 E215 x -1dca94e3990085_00000000000000000000000000000000000000000000000000000000000000000000001& E774
+    convertToDouble -1850063423920730049E215
+} 0xf05dca94e3990085
+test expr-28.266 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +3700126847841460098 E215 x 1dca94e3990085_00000000000000000000000000000000000000000000000000000000000000000000001& E775
+    convertToDouble +3700126847841460098E215
+} 0x706dca94e3990085
+test expr-28.267 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -9250317119603650245 E214 x -1dca94e3990085_00000000000000000000000000000000000000000000000000000000000000000000001& E773
+    convertToDouble -9250317119603650245E214
+} 0xf04dca94e3990085
+test expr-28.268 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +8396094300569779681 E-252 x 1ab223efcee35a_0000000000000000000000000000000000000000000000000000000000000000000000001& E-775
+    convertToDouble +8396094300569779681E-252
+} 0x0f8ab223efcee35a
+test expr-28.269 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -3507665085003296281 E-75 x -160499b881ea50_00000000000000000000000000000000000000000000000000000000000000000000001& E-188
+    convertToDouble -3507665085003296281E-75
+} 0xb4360499b881ea50
+test expr-28.270 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +7015330170006592562 E-75 x 160499b881ea50_00000000000000000000000000000000000000000000000000000000000000000000001& E-187
+    convertToDouble +7015330170006592562E-75
+} 0x34460499b881ea50
+test expr-28.271 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -7015330170006592562 E-74 x -1b85c026a264e4_00000000000000000000000000000000000000000000000000000000000000000000001& E-184
+    convertToDouble -7015330170006592562E-74
+} 0xb47b85c026a264e4
+test expr-28.272 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +7185620434951919351 E205 x 18d92d2bcc7a80_1111111111111111111111111111111111111111111111111111111111111111111111110& E743
+    convertToDouble +7185620434951919351E205
+} 0x6e68d92d2bcc7a81
+test expr-28.273 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -1360520207561212395 E198 x -1f92bacb3cb40b_11111111111111111111111111111111111111111111111111111111111111111111110& E717
+    convertToDouble -1360520207561212395E198
+} 0xeccf92bacb3cb40c
+test expr-28.274 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +2178999185345151731 E-184 x 19b2c4d2a82335_1111111111111111111111111111111111111111111111111111111111111111111110& E-551
+    convertToDouble +2178999185345151731E-184
+} 0x1d89b2c4d2a82336
+test expr-28.275 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -8691089486201567102 E-218 x -1a9c42e5b6d89e_1111111111111111111111111111111111111111111111111111111111111111111110& E-662
+    convertToDouble -8691089486201567102E-218
+} 0x969a9c42e5b6d89f
+test expr-28.276 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +4345544743100783551 E-218 x 1a9c42e5b6d89e_1111111111111111111111111111111111111111111111111111111111111111111110& E-663
+    convertToDouble +4345544743100783551E-218
+} 0x168a9c42e5b6d89f
+test expr-28.277 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -4357998370690303462 E-184 x -19b2c4d2a82335_1111111111111111111111111111111111111111111111111111111111111111111110& E-550
+    convertToDouble -4357998370690303462E-184
+} 0x9d99b2c4d2a82336
+test expr-28.278 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +59825267349106892461 E177 x 199c476d7868df_000000000000000000000000000000000000000000000000000000000000000000000001& E653
+    convertToDouble +59825267349106892461E177
+} 0x68c99c476d7868df
+test expr-28.279 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -62259110684423957791 E47 x -1d8f2cfc20d6e8_0000000000000000000000000000000000000000000000000000000000000000000000001& E221
+    convertToDouble -62259110684423957791E47
+} 0xcdcd8f2cfc20d6e8
+test expr-28.280 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +58380168477038565599 E265 x 1f686e9efbe48d_00000000000000000000000000000000000000000000000000000000000000000000000001& E945
+    convertToDouble +58380168477038565599E265
+} 0x7b0f686e9efbe48d
+test expr-28.281 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -62259110684423957791 E48 x -12797c1d948651_0000000000000000000000000000000000000000000000000000000000000000000000001& E225
+    convertToDouble -62259110684423957791E48
+} 0xce02797c1d948651
+test expr-28.282 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -33584377202279118724 E-252 x -1ab223efcee35a_0000000000000000000000000000000000000000000000000000000000000000000000001& E-773
+    convertToDouble -33584377202279118724E-252
+} 0x8faab223efcee35a
+test expr-28.283 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -57484963479615354808 E205 x -18d92d2bcc7a80_1111111111111111111111111111111111111111111111111111111111111111111111110& E746
+    convertToDouble -57484963479615354808E205
+} 0xee98d92d2bcc7a81
+test expr-28.284 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +71856204349519193510 E204 x 18d92d2bcc7a80_1111111111111111111111111111111111111111111111111111111111111111111111110& E743
+    convertToDouble +71856204349519193510E204
+} 0x6e68d92d2bcc7a81
+test expr-28.285 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -14371240869903838702 E205 x -18d92d2bcc7a80_1111111111111111111111111111111111111111111111111111111111111111111111110& E744
+    convertToDouble -14371240869903838702E205
+} 0xee78d92d2bcc7a81
+test expr-28.286 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +36992084760177624177 E-318 x 18c5f9551c2f99_111111111111111111111111111111111111111111111111111111111111111111111110& E-992
+    convertToDouble +36992084760177624177E-318
+} 0x01f8c5f9551c2f9a
+test expr-28.287 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -73984169520355248354 E-318 x -18c5f9551c2f99_111111111111111111111111111111111111111111111111111111111111111111111110& E-991
+    convertToDouble -73984169520355248354E-318
+} 0x8208c5f9551c2f9a
+test expr-28.288 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +99257763227713890244 E-115 x 15338a554b9ce0_11111111111111111111111111111111111111111111111111111111111111111111110& E-316
+    convertToDouble +99257763227713890244E-115
+} 0x2c35338a554b9ce1
+test expr-28.289 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -87336362425182547697 E-280 x -1130304e7d9c32_11111111111111111111111111111111111111111111111111111111111111111111110& E-864
+    convertToDouble -87336362425182547697E-280
+} 0x89f130304e7d9c33
+test expr-28.290 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +7 E289 x 1cbb547777a284_10000000001& E962
+    convertToDouble +7E289
+} 0x7c1cbb547777a285
+test expr-28.291 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -3 E153 x -1ca3d8e6d80cba_100000001& E509
+    convertToDouble -3E153
+} 0xdfcca3d8e6d80cbb
+test expr-28.292 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +6 E153 x 1ca3d8e6d80cba_100000001& E510
+    convertToDouble +6E153
+} 0x5fdca3d8e6d80cbb
+test expr-28.293 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -5 E243 x -176ec98994f488_10000001& E809
+    convertToDouble -5E243
+} 0xf2876ec98994f489
+test expr-28.294 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +7 E-161 x 1f7e0db3799aa2_10000000001& E-533
+    convertToDouble +7E-161
+} 0x1eaf7e0db3799aa3
+test expr-28.295 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -7 E-172 x -15a4337446ef2a_1000000001& E-569
+    convertToDouble -7E-172
+} 0x9c65a4337446ef2b
+test expr-28.296 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +8 E-63 x 1a53fc9631d10c_10000001& E-207
+    convertToDouble +8E-63
+} 0x330a53fc9631d10d
+test expr-28.297 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -7 E-113 x -158c47e6eea282_10000001& E-373
+    convertToDouble -7E-113
+} 0xa8a58c47e6eea283
+test expr-28.298 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +8 E126 x 17a2ecc414a03f_0111111111110& E421
+    convertToDouble +8E126
+} 0x5a47a2ecc414a03f
+test expr-28.299 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -4 E126 x -17a2ecc414a03f_0111111111110& E420
+    convertToDouble -4E126
+} 0xda37a2ecc414a03f
+test expr-28.300 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +5 E125 x 17a2ecc414a03f_0111111111110& E417
+    convertToDouble +5E125
+} 0x5a07a2ecc414a03f
+test expr-28.301 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -1 E126 x -17a2ecc414a03f_0111111111110& E418
+    convertToDouble -1E126
+} 0xda17a2ecc414a03f
+test expr-28.302 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +8 E-163 x 1708d0f84d3de7_011111110& E-539
+    convertToDouble +8E-163
+} 0x1e4708d0f84d3de7
+test expr-28.303 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -1 E-163 x -1708d0f84d3de7_011111110& E-542
+    convertToDouble -1E-163
+} 0x9e1708d0f84d3de7
+test expr-28.304 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +2 E-163 x 1708d0f84d3de7_011111110& E-541
+    convertToDouble +2E-163
+} 0x1e2708d0f84d3de7
+test expr-28.305 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -4 E-163 x -1708d0f84d3de7_011111110& E-540
+    convertToDouble -4E-163
+} 0x9e3708d0f84d3de7
+test expr-28.306 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +51 E195 x 15d51d249dca42_1000000000001& E653
+    convertToDouble +51E195
+} 0x68c5d51d249dca43
+test expr-28.307 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -37 E46 x -1033d7eca0adee_100000000000001& E158
+    convertToDouble -37E46
+} 0xc9d033d7eca0adef
+test expr-28.308 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +74 E46 x 1033d7eca0adee_100000000000001& E159
+    convertToDouble +74E46
+} 0x49e033d7eca0adef
+test expr-28.309 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -56 E289 x -1cbb547777a284_10000000001& E965
+    convertToDouble -56E289
+} 0xfc4cbb547777a285
+test expr-28.310 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +69 E-145 x 158a41b31c9a9a_100000000001& E-476
+    convertToDouble +69E-145
+} 0x22358a41b31c9a9b
+test expr-28.311 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -70 E-162 x -1f7e0db3799aa2_10000000001& E-533
+    convertToDouble -70E-162
+} 0x9eaf7e0db3799aa3
+test expr-28.312 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +56 E-161 x 1f7e0db3799aa2_10000000001& E-530
+    convertToDouble +56E-161
+} 0x1edf7e0db3799aa3
+test expr-28.313 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -21 E-303 x -1ccd59caa6a750_10000000001& E-1003
+    convertToDouble -21E-303
+} 0x814ccd59caa6a751
+test expr-28.314 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +34 E-276 x 12d5a4350d30ff_011111111110& E-912
+    convertToDouble +34E-276
+} 0x06f2d5a4350d30ff
+test expr-28.315 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -68 E-276 x -12d5a4350d30ff_011111111110& E-911
+    convertToDouble -68E-276
+} 0x8702d5a4350d30ff
+test expr-28.316 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +85 E-277 x 12d5a4350d30ff_011111111110& E-914
+    convertToDouble +85E-277
+} 0x06d2d5a4350d30ff
+test expr-28.317 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -87 E-274 x -12d36cf48e7abd_011111111111110& E-904
+    convertToDouble -87E-274
+} 0x8772d36cf48e7abd
+test expr-28.318 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +829 E102 x 17221a79cdd1d8_1000000000000001& E348
+    convertToDouble +829E102
+} 0x55b7221a79cdd1d9
+test expr-28.319 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -623 E100 x -1640a62f3a83de_10000000000000000001& E341
+    convertToDouble -623E100
+} 0xd54640a62f3a83df
+test expr-28.320 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +723 E-162 x 145457ee24abd2_1000000000000001& E-529
+    convertToDouble +723E-162
+} 0x1ee45457ee24abd3
+test expr-28.321 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -457 E-102 x -1ffc81bc29f02a_100000000000000001& E-331
+    convertToDouble -457E-102
+} 0xab4ffc81bc29f02b
+test expr-28.322 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +914 E-102 x 1ffc81bc29f02a_100000000000000001& E-330
+    convertToDouble +914E-102
+} 0x2b5ffc81bc29f02b
+test expr-28.323 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -323 E-135 x -1d589ae4d70218_10000000000001& E-441
+    convertToDouble -323E-135
+} 0xa46d589ae4d70219
+test expr-28.324 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +151 E176 x 1dcf7df8f573b7_0111111111111111110& E591
+    convertToDouble +151E176
+} 0x64edcf7df8f573b7
+test expr-28.325 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -302 E176 x -1dcf7df8f573b7_0111111111111111110& E592
+    convertToDouble -302E176
+} 0xe4fdcf7df8f573b7
+test expr-28.326 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +921 E90 x 1c420a45fd70ff_0111111111111110& E308
+    convertToDouble +921E90
+} 0x533c420a45fd70ff
+test expr-28.327 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -604 E176 x -1dcf7df8f573b7_0111111111111111110& E593
+    convertToDouble -604E176
+} 0xe50dcf7df8f573b7
+test expr-28.328 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +823 E-206 x 14a48933c208ad_0111111111111110& E-675
+    convertToDouble +823E-206
+} 0x15c4a48933c208ad
+test expr-28.329 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -463 E-114 x -11d0c83f6378a5_011111111111110& E-370
+    convertToDouble -463E-114
+} 0xa8d1d0c83f6378a5
+test expr-28.330 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +348 E-274 x 12d36cf48e7abd_011111111111110& E-902
+    convertToDouble +348E-274
+} 0x0792d36cf48e7abd
+test expr-28.331 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +9968 E100 x 1640a62f3a83de_10000000000000000001& E345
+    convertToDouble +9968E100
+} 0x558640a62f3a83df
+test expr-28.332 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -6230 E99 x -1640a62f3a83de_10000000000000000001& E341
+    convertToDouble -6230E99
+} 0xd54640a62f3a83df
+test expr-28.333 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +1246 E100 x 1640a62f3a83de_10000000000000000001& E342
+    convertToDouble +1246E100
+} 0x555640a62f3a83df
+test expr-28.334 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +6676 E-296 x 15519ac5142aaa_1000000000000000000001& E-971
+    convertToDouble +6676E-296
+} 0x0345519ac5142aab
+test expr-28.335 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -8345 E-297 x -15519ac5142aaa_1000000000000000000001& E-974
+    convertToDouble -8345E-297
+} 0x8315519ac5142aab
+test expr-28.336 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +1669 E-296 x 15519ac5142aaa_1000000000000000000001& E-973
+    convertToDouble +1669E-296
+} 0x0325519ac5142aab
+test expr-28.337 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -3338 E-296 x -15519ac5142aaa_1000000000000000000001& E-972
+    convertToDouble -3338E-296
+} 0x8335519ac5142aab
+test expr-28.338 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +3257 E58 x 1444b34a6fb3eb_01111111111111111110& E204
+    convertToDouble +3257E58
+} 0x4cb444b34a6fb3eb
+test expr-28.339 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -6514 E58 x -1444b34a6fb3eb_01111111111111111110& E205
+    convertToDouble -6514E58
+} 0xccc444b34a6fb3eb
+test expr-28.340 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +2416 E176 x 1dcf7df8f573b7_0111111111111111110& E595
+    convertToDouble +2416E176
+} 0x652dcf7df8f573b7
+test expr-28.341 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +8085 E-63 x 19fbf3c19b9a79_0111111111111111110& E-197
+    convertToDouble +8085E-63
+} 0x33a9fbf3c19b9a79
+test expr-28.342 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -3234 E-62 x -19fbf3c19b9a79_0111111111111111110& E-195
+    convertToDouble -3234E-62
+} 0xb3c9fbf3c19b9a79
+test expr-28.343 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +1617 E-62 x 19fbf3c19b9a79_0111111111111111110& E-196
+    convertToDouble +1617E-62
+} 0x33b9fbf3c19b9a79
+test expr-28.344 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -6468 E-62 x -19fbf3c19b9a79_0111111111111111110& E-194
+    convertToDouble -6468E-62
+} 0xb3d9fbf3c19b9a79
+test expr-28.345 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +53418 E111 x 15b1051df943a8_1000000000000000000001& E384
+    convertToDouble +53418E111
+} 0x57f5b1051df943a9
+test expr-28.346 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -60513 E160 x -15043b64e56c72_1000000000000000000001& E547
+    convertToDouble -60513E160
+} 0xe225043b64e56c73
+test expr-28.347 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +26709 E111 x 15b1051df943a8_1000000000000000000001& E383
+    convertToDouble +26709E111
+} 0x57e5b1051df943a9
+test expr-28.348 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -99447 E166 x -10782189b336ae_1000000000000000000001& E568
+    convertToDouble -99447E166
+} 0xe370782189b336af
+test expr-28.349 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +12549 E48 x 10c52fe6dc6a1b_011111111111111111111110& E173
+    convertToDouble +12549E48
+} 0x4ac0c52fe6dc6a1b
+test expr-28.350 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -25098 E48 x -10c52fe6dc6a1b_011111111111111111111110& E174
+    convertToDouble -25098E48
+} 0xcad0c52fe6dc6a1b
+test expr-28.351 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +50196 E48 x 10c52fe6dc6a1b_011111111111111111111110& E175
+    convertToDouble +50196E48
+} 0x4ae0c52fe6dc6a1b
+test expr-28.352 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -62745 E47 x -10c52fe6dc6a1b_011111111111111111111110& E172
+    convertToDouble -62745E47
+} 0xcab0c52fe6dc6a1b
+test expr-28.353 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +83771 E-73 x 1ce886fb5ffd6d_0111111111111111111110& E-227
+    convertToDouble +83771E-73
+} 0x31cce886fb5ffd6d
+test expr-28.354 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -97451 E-167 x -1c0f220fb1c70d_01111111111111111111110& E-539
+    convertToDouble -97451E-167
+} 0x9e4c0f220fb1c70d
+test expr-28.355 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +86637 E-203 x 10943edb4e81db_0111111111111111111110& E-658
+    convertToDouble +86637E-203
+} 0x16d0943edb4e81db
+test expr-28.356 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -75569 E-254 x -15a462d91c6ab3_0111111111111111111111111110& E-828
+    convertToDouble -75569E-254
+} 0x8c35a462d91c6ab3
+test expr-28.357 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +473806 E83 x 17d15bf3186080_1000000000000000000000001& E294
+    convertToDouble +473806E83
+} 0x5257d15bf3186081
+test expr-28.358 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -947612 E83 x -17d15bf3186080_1000000000000000000000001& E295
+    convertToDouble -947612E83
+} 0xd267d15bf3186081
+test expr-28.359 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +292369 E76 x 18a85eb277e644_100000000000000000000000001& E270
+    convertToDouble +292369E76
+} 0x50d8a85eb277e645
+test expr-28.360 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -584738 E76 x -18a85eb277e644_100000000000000000000000001& E271
+    convertToDouble -584738E76
+} 0xd0e8a85eb277e645
+test expr-28.361 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +933587 E-140 x 1b248728b9c116_100000000000000000000000001& E-446
+    convertToDouble +933587E-140
+} 0x241b248728b9c117
+test expr-28.362 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -720919 E-14 x -1ef696965cbf04_10000000000000000000000001& E-28
+    convertToDouble -720919E-14
+} 0xbe3ef696965cbf05
+test expr-28.363 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +535001 E-149 x 10b38e07c745ae_1000000000000000000000001& E-476
+    convertToDouble +535001E-149
+} 0x2230b38e07c745af
+test expr-28.364 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -890521 E-235 x -114828ee39c852_1000000000000000000000001& E-761
+    convertToDouble -890521E-235
+} 0x90614828ee39c853
+test expr-28.365 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +548057 E81 x 11a1d9135cca53_0111111111111111111111110& E288
+    convertToDouble +548057E81
+} 0x51f1a1d9135cca53
+test expr-28.366 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -706181 E88 x -1b156ac4c2d1e5_0111111111111111111111110& E311
+    convertToDouble -706181E88
+} 0xd36b156ac4c2d1e5
+test expr-28.367 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +820997 E106 x 1b4f8b64fa125d_0111111111111111111111110& E371
+    convertToDouble +820997E106
+} 0x572b4f8b64fa125d
+test expr-28.368 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -320681 E63 x -17ca18a876c5ef_0111111111111111111111110& E227
+    convertToDouble -320681E63
+} 0xce27ca18a876c5ef
+test expr-28.369 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +928609 E-261 x 1be2dd66200bef_011111111111111111111111111110& E-848
+    convertToDouble +928609E-261
+} 0x0afbe2dd66200bef
+test expr-28.370 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -302276 E-254 x -15a462d91c6ab3_0111111111111111111111111110& E-826
+    convertToDouble -302276E-254
+} 0x8c55a462d91c6ab3
+test expr-28.371 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +151138 E-254 x 15a462d91c6ab3_0111111111111111111111111110& E-827
+    convertToDouble +151138E-254
+} 0x0c45a462d91c6ab3
+test expr-28.372 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +4691773 E45 x 19147b9330eaae_1000000000000000000000000001& E171
+    convertToDouble +4691773E45
+} 0x4aa9147b9330eaaf
+test expr-28.373 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -9383546 E45 x -19147b9330eaae_1000000000000000000000000001& E172
+    convertToDouble -9383546E45
+} 0xcab9147b9330eaaf
+test expr-28.374 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +3059949 E-243 x 13ecf22ea07862_10000000000000000000000000001& E-786
+    convertToDouble +3059949E-243
+} 0x0ed3ecf22ea07863
+test expr-28.375 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -6119898 E-243 x -13ecf22ea07862_10000000000000000000000000001& E-785
+    convertToDouble -6119898E-243
+} 0x8ee3ecf22ea07863
+test expr-28.376 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +5356626 E-213 x 1b84252abdf6ba_100000000000000000000000001& E-686
+    convertToDouble +5356626E-213
+} 0x151b84252abdf6bb
+test expr-28.377 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -4877378 E-199 x -11cd5cd90cb200_100000000000000000000000001& E-639
+    convertToDouble -4877378E-199
+} 0x9801cd5cd90cb201
+test expr-28.378 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +7716693 E223 x 1972d9d2cff683_01111111111111111111111111110& E763
+    convertToDouble +7716693E223
+} 0x6fa972d9d2cff683
+test expr-28.379 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -5452869 E109 x -16247b136fecc3_01111111111111111111111111110& E384
+    convertToDouble -5452869E109
+} 0xd7f6247b136fecc3
+test expr-28.380 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +4590831 E156 x 14689b4a5fa201_011111111111111111111111111110& E540
+    convertToDouble +4590831E156
+} 0x61b4689b4a5fa201
+test expr-28.381 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -9181662 E156 x -14689b4a5fa201_011111111111111111111111111110& E541
+    convertToDouble -9181662E156
+} 0xe1c4689b4a5fa201
+test expr-28.382 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -3714436 E-261 x -1be2dd66200bef_011111111111111111111111111110& E-846
+    convertToDouble -3714436E-261
+} 0x8b1be2dd66200bef
+test expr-28.383 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +4643045 E-262 x 1be2dd66200bef_011111111111111111111111111110& E-849
+    convertToDouble +4643045E-262
+} 0x0aebe2dd66200bef
+test expr-28.384 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -7428872 E-261 x -1be2dd66200bef_011111111111111111111111111110& E-845
+    convertToDouble -7428872E-261
+} 0x8b2be2dd66200bef
+test expr-28.385 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +52942146 E130 x 16c31d08af89c2_10000000000000000000000000000001& E457
+    convertToDouble +52942146E130
+} 0x5c86c31d08af89c3
+test expr-28.386 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -27966061 E145 x -155bcf72fd10f8_1000000000000000000000000000000001& E506
+    convertToDouble -27966061E145
+} 0xdf955bcf72fd10f9
+test expr-28.387 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +26471073 E130 x 16c31d08af89c2_10000000000000000000000000000001& E456
+    convertToDouble +26471073E130
+} 0x5c76c31d08af89c3
+test expr-28.388 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -55932122 E145 x -155bcf72fd10f8_1000000000000000000000000000000001& E507
+    convertToDouble -55932122E145
+} 0xdfa55bcf72fd10f9
+test expr-28.389 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +95412548 E-99 x 18e0bfb98864c8_100000000000000000000000000000001& E-303
+    convertToDouble +95412548E-99
+} 0x2d08e0bfb98864c9
+test expr-28.390 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -47706274 E-99 x -18e0bfb98864c8_100000000000000000000000000000001& E-304
+    convertToDouble -47706274E-99
+} 0xacf8e0bfb98864c9
+test expr-28.391 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +23853137 E-99 x 18e0bfb98864c8_100000000000000000000000000000001& E-305
+    convertToDouble +23853137E-99
+} 0x2ce8e0bfb98864c9
+test expr-28.392 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -78493654 E-301 x -140d76077b648e_10000000000000000000000000000001& E-974
+    convertToDouble -78493654E-301
+} 0x83140d76077b648f
+test expr-28.393 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +65346417 E29 x 13aa1ad778f23b_0111111111111111111111111111110& E122
+    convertToDouble +65346417E29
+} 0x4793aa1ad778f23b
+test expr-28.394 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -51083099 E167 x -14a75eb58df47b_0111111111111111111111111111110& E580
+    convertToDouble -51083099E167
+} 0xe434a75eb58df47b
+test expr-28.395 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +89396333 E264 x 1526f061ca9053_0111111111111111111111111111111110& E903
+    convertToDouble +89396333E264
+} 0x786526f061ca9053
+test expr-28.396 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -84863171 E114 x -106e98f5ec8f37_0111111111111111111111111111111110& E405
+    convertToDouble -84863171E114
+} 0xd9406e98f5ec8f37
+test expr-28.397 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +59540836 E-251 x 10430c2d075c07_011111111111111111111111111111110& E-808
+    convertToDouble +59540836E-251
+} 0x0d70430c2d075c07
+test expr-28.398 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -74426045 E-252 x -10430c2d075c07_011111111111111111111111111111110& E-811
+    convertToDouble -74426045E-252
+} 0x8d40430c2d075c07
+test expr-28.399 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +14885209 E-251 x 10430c2d075c07_011111111111111111111111111111110& E-810
+    convertToDouble +14885209E-251
+} 0x0d50430c2d075c07
+test expr-28.400 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -29770418 E-251 x -10430c2d075c07_011111111111111111111111111111110& E-809
+    convertToDouble -29770418E-251
+} 0x8d60430c2d075c07
+test expr-28.401 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +982161308 E122 x 11b6231e18c5ca_100000000000000000000000000000000000000001& E435
+    convertToDouble +982161308E122
+} 0x5b21b6231e18c5cb
+test expr-28.402 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -245540327 E122 x -11b6231e18c5ca_100000000000000000000000000000000000000001& E433
+    convertToDouble -245540327E122
+} 0xdb01b6231e18c5cb
+test expr-28.403 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +491080654 E122 x 11b6231e18c5ca_100000000000000000000000000000000000000001& E434
+    convertToDouble +491080654E122
+} 0x5b11b6231e18c5cb
+test expr-28.404 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +525452622 E-310 x 12045136ce0340_1000000000000000000000000000000000001& E-1001
+    convertToDouble +525452622E-310
+} 0x0162045136ce0341
+test expr-28.405 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -771837113 E-134 x -14e61f991c4ed0_100000000000000000000000000000000001& E-416
+    convertToDouble -771837113E-134
+} 0xa5f4e61f991c4ed1
+test expr-28.406 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +820858081 E-150 x 14050669985a86_10000000000000000000000000000000001& E-469
+    convertToDouble +820858081E-150
+} 0x22a4050669985a87
+test expr-28.407 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -262726311 E-310 x -12045136ce0340_1000000000000000000000000000000000001& E-1002
+    convertToDouble -262726311E-310
+} 0x8152045136ce0341
+test expr-28.408 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +923091487 E209 x 10bc60e6896717_011111111111111111111111111111111110& E724
+    convertToDouble +923091487E209
+} 0x6d30bc60e6896717
+test expr-28.409 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -653777767 E273 x -120223f2b3a881_0111111111111111111111111111111111111110& E936
+    convertToDouble -653777767E273
+} 0xfa720223f2b3a881
+test expr-28.410 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +842116236 E-53 x 1809c5732cdc7f_0111111111111111111111111111111110& E-147
+    convertToDouble +842116236E-53
+} 0x36c809c5732cdc7f
+test expr-28.411 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -741111169 E-202 x -15a3e1d1b73099_01111111111111111111111111111111110& E-642
+    convertToDouble -741111169E-202
+} 0x97d5a3e1d1b73099
+test expr-28.412 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +839507247 E-284 x 129a1effc50859_0111111111111111111111111111111110& E-914
+    convertToDouble +839507247E-284
+} 0x06d29a1effc50859
+test expr-28.413 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -951487269 E-264 x -1c92befccb5f59_0111111111111111111111111111111110& E-848
+    convertToDouble -951487269E-264
+} 0x8afc92befccb5f59
+test expr-28.414 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -9821613080 E121 x -11b6231e18c5ca_100000000000000000000000000000000000000001& E435
+    convertToDouble -9821613080E121
+} 0xdb21b6231e18c5cb
+test expr-28.415 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +6677856011 E-31 x 193a6d11077292_100000000000000000000000000000000000001& E-71
+    convertToDouble +6677856011E-31
+} 0x3b893a6d11077293
+test expr-28.416 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -3573796826 E-266 x -112be2041a79fc_100000000000000000000000000000000000001& E-852
+    convertToDouble -3573796826E-266
+} 0x8ab12be2041a79fd
+test expr-28.417 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +7147593652 E-266 x 112be2041a79fc_100000000000000000000000000000000000001& E-851
+    convertToDouble +7147593652E-266
+} 0x0ac12be2041a79fd
+test expr-28.418 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -9981396317 E-181 x -1edbd94cb50054_100000000000000000000000000000000000001& E-569
+    convertToDouble -9981396317E-181
+} 0x9c6edbd94cb50055
+test expr-28.419 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +3268888835 E272 x 120223f2b3a881_0111111111111111111111111111111111111110& E935
+    convertToDouble +3268888835E272
+} 0x7a620223f2b3a881
+test expr-28.420 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -2615111068 E273 x -120223f2b3a881_0111111111111111111111111111111111111110& E938
+    convertToDouble -2615111068E273
+} 0xfa920223f2b3a881
+test expr-28.421 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +1307555534 E273 x 120223f2b3a881_0111111111111111111111111111111111111110& E937
+    convertToDouble +1307555534E273
+} 0x7a820223f2b3a881
+test expr-28.422 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +2990671154 E-190 x 13db11ac608107_01111111111111111111111111111111111111110& E-600
+    convertToDouble +2990671154E-190
+} 0x1a73db11ac608107
+test expr-28.423 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -1495335577 E-190 x -13db11ac608107_01111111111111111111111111111111111111110& E-601
+    convertToDouble -1495335577E-190
+} 0x9a63db11ac608107
+test expr-28.424 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +5981342308 E-190 x 13db11ac608107_01111111111111111111111111111111111111110& E-599
+    convertToDouble +5981342308E-190
+} 0x1a83db11ac608107
+test expr-28.425 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -7476677885 E-191 x -13db11ac608107_01111111111111111111111111111111111111110& E-602
+    convertToDouble -7476677885E-191
+} 0x9a53db11ac608107
+test expr-28.426 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +82259684194 E-202 x 12c3e72d179606_1000000000000000000000000000000000000000001& E-635
+    convertToDouble +82259684194E-202
+} 0x1842c3e72d179607
+test expr-28.427 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -93227267727 E-49 x -1960fe08d5847e_100000000000000000000000000000000000000001& E-127
+    convertToDouble -93227267727E-49
+} 0xb80960fe08d5847f
+test expr-28.428 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +41129842097 E-202 x 12c3e72d179606_1000000000000000000000000000000000000000001& E-636
+    convertToDouble +41129842097E-202
+} 0x1832c3e72d179607
+test expr-28.429 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -47584241418 E-314 x -14e25dd3747e96_10000000000000000000000000000000000000001& E-1008
+    convertToDouble -47584241418E-314
+} 0x80f4e25dd3747e97
+test expr-28.430 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -79360293406 E92 x -1c58a00bb31863_01111111111111111111111111111111111111110& E341
+    convertToDouble -79360293406E92
+} 0xd54c58a00bb31863
+test expr-28.431 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +57332259349 E225 x 120811f528378b_01111111111111111111111111111111111111110& E783
+    convertToDouble +57332259349E225
+} 0x70e20811f528378b
+test expr-28.432 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -57202326162 E111 x -1626f1c480545b_01111111111111111111111111111111111111110& E404
+    convertToDouble -57202326162E111
+} 0xd93626f1c480545b
+test expr-28.433 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +86860597053 E-206 x 103b77d2b969d9_0111111111111111111111111111111111111111110& E-648
+    convertToDouble +86860597053E-206
+} 0x17703b77d2b969d9
+test expr-28.434 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -53827010643 E-200 x -132fa69a69bd6d_0111111111111111111111111111111111111111110& E-629
+    convertToDouble -53827010643E-200
+} 0x98a32fa69a69bd6d
+test expr-28.435 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +53587107423 E-61 x 100a19a3ffd981_011111111111111111111111111111111111111111110& E-167
+    convertToDouble +53587107423E-61
+} 0x35800a19a3ffd981
+test expr-28.436 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +635007636765 E200 x 1824e73a4f030e_100000000000000000000000000000000000000000001& E703
+    convertToDouble +635007636765E200
+} 0x6be824e73a4f030f
+test expr-28.437 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +508006109412 E201 x 1824e73a4f030e_100000000000000000000000000000000000000000001& E706
+    convertToDouble +508006109412E201
+} 0x6c1824e73a4f030f
+test expr-28.438 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -254003054706 E201 x -1824e73a4f030e_100000000000000000000000000000000000000000001& E705
+    convertToDouble -254003054706E201
+} 0xec0824e73a4f030f
+test expr-28.439 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +561029718715 E-72 x 1cd96a6972a14a_100000000000000000000000000000000000000000001& E-201
+    convertToDouble +561029718715E-72
+} 0x336cd96a6972a14b
+test expr-28.440 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -897647549944 E-71 x -1cd96a6972a14a_100000000000000000000000000000000000000000001& E-197
+    convertToDouble -897647549944E-71
+} 0xb3acd96a6972a14b
+test expr-28.441 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +112205943743 E-71 x 1cd96a6972a14a_100000000000000000000000000000000000000000001& E-200
+    convertToDouble +112205943743E-71
+} 0x337cd96a6972a14b
+test expr-28.442 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -873947086081 E-236 x -19e117541d04e6_1000000000000000000000000000000000000000000001& E-745
+    convertToDouble -873947086081E-236
+} 0x9169e117541d04e7
+test expr-28.443 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +809184709177 E116 x 1de27e59fb0679_011111111111111111111111111111111111111111110& E424
+    convertToDouble +809184709177E116
+} 0x5a7de27e59fb0679
+test expr-28.444 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -573112917422 E81 x -11958b36c5102b_01111111111111111111111111111111111111111111110& E308
+    convertToDouble -573112917422E81
+} 0xd331958b36c5102b
+test expr-28.445 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +286556458711 E81 x 11958b36c5102b_01111111111111111111111111111111111111111111110& E307
+    convertToDouble +286556458711E81
+} 0x5321958b36c5102b
+test expr-28.446 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +952805821491 E-259 x 1551767ef8a9a3_011111111111111111111111111111111111111111110& E-821
+    convertToDouble +952805821491E-259
+} 0x0ca551767ef8a9a3
+test expr-28.447 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -132189992873 E-44 x -1b746cf242410b_011111111111111111111111111111111111111111110& E-110
+    convertToDouble -132189992873E-44
+} 0xb91b746cf242410b
+test expr-28.448 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -173696038493 E-144 x -1f8fefbb3249d3_011111111111111111111111111111111111111111110& E-442
+    convertToDouble -173696038493E-144
+} 0xa45f8fefbb3249d3
+test expr-28.449 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +1831132757599 E-107 x 138e6edd48f2a2_1000000000000000000000000000000000000000000000001& E-315
+    convertToDouble +1831132757599E-107
+} 0x2c438e6edd48f2a3
+test expr-28.450 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -9155663787995 E-108 x -138e6edd48f2a2_1000000000000000000000000000000000000000000000001& E-316
+    convertToDouble -9155663787995E-108
+} 0xac338e6edd48f2a3
+test expr-28.451 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +7324531030396 E-107 x 138e6edd48f2a2_1000000000000000000000000000000000000000000000001& E-313
+    convertToDouble +7324531030396E-107
+} 0x2c638e6edd48f2a3
+test expr-28.452 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -9277338894969 E-200 x -19d5a44fd99a6a_1000000000000000000000000000000000000000000000001& E-622
+    convertToDouble -9277338894969E-200
+} 0x9919d5a44fd99a6b
+test expr-28.453 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +8188292423973 E287 x 1390273bf8f983_0111111111111111111111111111111111111111111111110& E996
+    convertToDouble +8188292423973E287
+} 0x7e3390273bf8f983
+test expr-28.454 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -5672557437938 E59 x -148c2bd60a1523_011111111111111111111111111111111111111111111110& E238
+    convertToDouble -5672557437938E59
+} 0xced48c2bd60a1523
+test expr-28.455 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +2836278718969 E59 x 148c2bd60a1523_011111111111111111111111111111111111111111111110& E237
+    convertToDouble +2836278718969E59
+} 0x4ec48c2bd60a1523
+test expr-28.456 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -9995153153494 E54 x -17ba37c4fbe993_01111111111111111111111111111111111111111111110& E222
+    convertToDouble -9995153153494E54
+} 0xcdd7ba37c4fbe993
+test expr-28.457 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +9224786422069 E-291 x 14ee5d56b32957_011111111111111111111111111111111111111111111111110& E-924
+    convertToDouble +9224786422069E-291
+} 0x0634ee5d56b32957
+test expr-28.458 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -3142213164987 E-294 x -1d3409dfbca26f_011111111111111111111111111111111111111111111111110& E-936
+    convertToDouble -3142213164987E-294
+} 0x857d3409dfbca26f
+test expr-28.459 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +6284426329974 E-294 x 1d3409dfbca26f_011111111111111111111111111111111111111111111111110& E-935
+    convertToDouble +6284426329974E-294
+} 0x058d3409dfbca26f
+test expr-28.460 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -8340483752889 E-301 x -10419183e44b91_01111111111111111111111111111111111111111111111110& E-957
+    convertToDouble -8340483752889E-301
+} 0x8420419183e44b91
+test expr-28.461 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +67039371486466 E89 x 17f203339c9628_10000000000000000000000000000000000000000000000000001& E341
+    convertToDouble +67039371486466E89
+} 0x5547f203339c9629
+test expr-28.462 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -62150786615239 E197 x -12e79a035b9714_1000000000000000000000000000000000000000000000000001& E700
+    convertToDouble -62150786615239E197
+} 0xebb2e79a035b9715
+test expr-28.463 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +33519685743233 E89 x 17f203339c9628_10000000000000000000000000000000000000000000000000001& E340
+    convertToDouble +33519685743233E89
+} 0x5537f203339c9629
+test expr-28.464 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -52563419496999 E156 x -1bdb17625bf6e6_1000000000000000000000000000000000000000000000000001& E563
+    convertToDouble -52563419496999E156
+} 0xe32bdb17625bf6e7
+test expr-28.465 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +32599460466991 E-65 x 1f395d4c779d8e_1000000000000000000000000000000000000000000000000001& E-172
+    convertToDouble +32599460466991E-65
+} 0x353f395d4c779d8f
+test expr-28.466 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -41010988798007 E-133 x -152e1c9e04ee06_100000000000000000000000000000000000000000000000001& E-397
+    convertToDouble -41010988798007E-133
+} 0xa7252e1c9e04ee07
+test expr-28.467 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +65198920933982 E-65 x 1f395d4c779d8e_1000000000000000000000000000000000000000000000000001& E-171
+    convertToDouble +65198920933982E-65
+} 0x354f395d4c779d8f
+test expr-28.468 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -82021977596014 E-133 x -152e1c9e04ee06_100000000000000000000000000000000000000000000000001& E-396
+    convertToDouble -82021977596014E-133
+} 0xa7352e1c9e04ee07
+test expr-28.469 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +80527976643809 E61 x 1c7c5aea080a49_0111111111111111111111111111111111111111111111111110& E248
+    convertToDouble +80527976643809E61
+} 0x4f7c7c5aea080a49
+test expr-28.470 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -74712611505209 E158 x -1eeebe9ea010f3_011111111111111111111111111111111111111111111111110& E570
+    convertToDouble -74712611505209E158
+} 0xe39eeebe9ea010f3
+test expr-28.471 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +53390939710959 E261 x 18ac6d426a1cb1_0111111111111111111111111111111111111111111111111110& E912
+    convertToDouble +53390939710959E261
+} 0x78f8ac6d426a1cb1
+test expr-28.472 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -69277302659155 E225 x -1547166a3a2b0f_011111111111111111111111111111111111111111111111110& E793
+    convertToDouble -69277302659155E225
+} 0xf18547166a3a2b0f
+test expr-28.473 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +46202199371337 E-72 x 128f9edfbd341f_0111111111111111111111111111111111111111111111111111111110& E-194
+    convertToDouble +46202199371337E-72
+} 0x33d28f9edfbd341f
+test expr-28.474 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -23438635467783 E-179 x -1ba485b99e47af_0111111111111111111111111111111111111111111111111110& E-551
+    convertToDouble -23438635467783E-179
+} 0x9d8ba485b99e47af
+test expr-28.475 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +41921560615349 E-67 x 19b2a5c4041e4b_0111111111111111111111111111111111111111111111111110& E-178
+    convertToDouble +41921560615349E-67
+} 0x34d9b2a5c4041e4b
+test expr-28.476 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -92404398742674 E-72 x -128f9edfbd341f_0111111111111111111111111111111111111111111111111111111110& E-193
+    convertToDouble -92404398742674E-72
+} 0xb3e28f9edfbd341f
+test expr-28.477 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +738545606647197 E124 x 13d8886a766a20_100000000000000000000000000000000000000000000000000001& E461
+    convertToDouble +738545606647197E124
+} 0x5cc3d8886a766a21
+test expr-28.478 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -972708181182949 E117 x -15ed1f039cebfe_1000000000000000000000000000000000000000000000000000001& E438
+    convertToDouble -972708181182949E117
+} 0xdb55ed1f039cebff
+test expr-28.479 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -837992143580825 E87 x -17f203339c9628_10000000000000000000000000000000000000000000000000001& E338
+    convertToDouble -837992143580825E87
+} 0xd517f203339c9629
+test expr-28.480 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +609610927149051 E-255 x 104273b18918b0_100000000000000000000000000000000000000000000000000000001& E-798
+    convertToDouble +609610927149051E-255
+} 0x0e104273b18918b1
+test expr-28.481 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -475603213226859 E-41 x -178cfcab31064c_10000000000000000000000000000000000000000000000000000001& E-88
+    convertToDouble -475603213226859E-41
+} 0xba778cfcab31064d
+test expr-28.482 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +563002800671023 E-177 x 1035e7b5183922_10000000000000000000000000000000000000000000000000000001& E-539
+    convertToDouble +563002800671023E-177
+} 0x1e4035e7b5183923
+test expr-28.483 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -951206426453718 E-41 x -178cfcab31064c_10000000000000000000000000000000000000000000000000000001& E-87
+    convertToDouble -951206426453718E-41
+} 0xba878cfcab31064d
+test expr-28.484 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +805416432656519 E202 x 175d226331d039_01111111111111111111111111111111111111111111111111111110& E720
+    convertToDouble +805416432656519E202
+} 0x6cf75d226331d039
+test expr-28.485 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -530658674694337 E159 x -112a13daa46fe3_0111111111111111111111111111111111111111111111111111110& E577
+    convertToDouble -530658674694337E159
+} 0xe4012a13daa46fe3
+test expr-28.486 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +946574173863918 E208 x 1a2fbffdb7580b_011111111111111111111111111111111111111111111111111110& E740
+    convertToDouble +946574173863918E208
+} 0x6e3a2fbffdb7580b
+test expr-28.487 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -318329953318553 E113 x -178358811cbc95_011111111111111111111111111111111111111111111111111110& E423
+    convertToDouble -318329953318553E113
+} 0xda678358811cbc95
+test expr-28.488 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -462021993713370 E-73 x -128f9edfbd341f_0111111111111111111111111111111111111111111111111111111110& E-194
+    convertToDouble -462021993713370E-73
+} 0xb3d28f9edfbd341f
+test expr-28.489 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +369617594970696 E-72 x 128f9edfbd341f_0111111111111111111111111111111111111111111111111111111110& E-191
+    convertToDouble +369617594970696E-72
+} 0x34028f9edfbd341f
+test expr-28.490 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +3666156212014994 E233 x 1a37935f3b71c8_100000000000000000000000000000000000000000000000000000001& E825
+    convertToDouble +3666156212014994E233
+} 0x738a37935f3b71c9
+test expr-28.491 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -1833078106007497 E233 x -1a37935f3b71c8_100000000000000000000000000000000000000000000000000000001& E824
+    convertToDouble -1833078106007497E233
+} 0xf37a37935f3b71c9
+test expr-28.492 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +8301790508624232 E174 x 1dcfee6690ffc6_100000000000000000000000000000000000000000000000000000001& E630
+    convertToDouble +8301790508624232E174
+} 0x675dcfee6690ffc7
+test expr-28.493 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -1037723813578029 E174 x -1dcfee6690ffc6_100000000000000000000000000000000000000000000000000000001& E627
+    convertToDouble -1037723813578029E174
+} 0xe72dcfee6690ffc7
+test expr-28.494 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +7297662880581139 E-286 x 18ac8c79e1ff18_1000000000000000000000000000000000000000000000000000000000001& E-898
+    convertToDouble +7297662880581139E-286
+} 0x07d8ac8c79e1ff19
+test expr-28.495 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -5106185698912191 E-276 x -141934d77659be_1000000000000000000000000000000000000000000000000000000000001& E-865
+    convertToDouble -5106185698912191E-276
+} 0x89e41934d77659bf
+test expr-28.496 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +7487252720986826 E-165 x 18823a57adbef8_100000000000000000000000000000000000000000000000000000000000001& E-496
+    convertToDouble +7487252720986826E-165
+} 0x20f8823a57adbef9
+test expr-28.497 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -3743626360493413 E-165 x -18823a57adbef8_100000000000000000000000000000000000000000000000000000000000001& E-497
+    convertToDouble -3743626360493413E-165
+} 0xa0e8823a57adbef9
+test expr-28.498 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +3773057430100257 E230 x 1ba10d818fdafd_0111111111111111111111111111111111111111111111111111111110& E815
+    convertToDouble +3773057430100257E230
+} 0x72eba10d818fdafd
+test expr-28.499 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -7546114860200514 E230 x -1ba10d818fdafd_0111111111111111111111111111111111111111111111111111111110& E816
+    convertToDouble -7546114860200514E230
+} 0xf2fba10d818fdafd
+test expr-28.500 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +4321222892463822 E58 x 18750ea732fdad_011111111111111111111111111111111111111111111111111111110& E244
+    convertToDouble +4321222892463822E58
+} 0x4f38750ea732fdad
+test expr-28.501 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -7793560217139653 E51 x -1280461b856ec5_0111111111111111111111111111111111111111111111111111111110& E222
+    convertToDouble -7793560217139653E51
+} 0xcdd280461b856ec5
+test expr-28.502 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +26525993941010681 E112 x 187dcbf6ad5cf8_10000000000000000000000000000000000000000000000000000000000001& E426
+    convertToDouble +26525993941010681E112
+} 0x5a987dcbf6ad5cf9
+test expr-28.503 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -53051987882021362 E112 x -187dcbf6ad5cf8_10000000000000000000000000000000000000000000000000000000000001& E427
+    convertToDouble -53051987882021362E112
+} 0xdaa87dcbf6ad5cf9
+test expr-28.504 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +72844871414247907 E77 x 1bf00baf60b70c_100000000000000000000000000000000000000000000000000000000001& E311
+    convertToDouble +72844871414247907E77
+} 0x536bf00baf60b70d
+test expr-28.505 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -88839359596763261 E105 x -1133b1a33a1108_100000000000000000000000000000000000000000000000000000000001& E405
+    convertToDouble -88839359596763261E105
+} 0xd94133b1a33a1109
+test expr-28.506 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +18718131802467065 E-166 x 18823a57adbef8_100000000000000000000000000000000000000000000000000000000000001& E-498
+    convertToDouble +18718131802467065E-166
+} 0x20d8823a57adbef9
+test expr-28.507 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -14974505441973652 E-165 x -18823a57adbef8_100000000000000000000000000000000000000000000000000000000000001& E-495
+    convertToDouble -14974505441973652E-165
+} 0xa108823a57adbef9
+test expr-28.508 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +73429396004640239 E106 x 11c5cb19ef3451_01111111111111111111111111111111111111111111111111111111111110& E408
+    convertToDouble +73429396004640239E106
+} 0x5971c5cb19ef3451
+test expr-28.509 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -58483921078398283 E57 x -108ce499519ce3_0111111111111111111111111111111111111111111111111111111111111110& E245
+    convertToDouble -58483921078398283E57
+} 0xcf408ce499519ce3
+test expr-28.510 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +41391519190645203 E165 x 13f33667156017_011111111111111111111111111111111111111111111111111111111111110& E603
+    convertToDouble +41391519190645203E165
+} 0x65a3f33667156017
+test expr-28.511 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -82783038381290406 E165 x -13f33667156017_011111111111111111111111111111111111111111111111111111111111110& E604
+    convertToDouble -82783038381290406E165
+} 0xe5b3f33667156017
+test expr-28.512 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +58767043776702677 E-163 x 12c92fee3a3867_0111111111111111111111111111111111111111111111111111111111110& E-486
+    convertToDouble +58767043776702677E-163
+} 0x2192c92fee3a3867
+test expr-28.513 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -90506231831231999 E-129 x -1bdc4114397ff3_01111111111111111111111111111111111111111111111111111111111110& E-373
+    convertToDouble -90506231831231999E-129
+} 0xa8abdc4114397ff3
+test expr-28.514 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +64409240769861689 E-159 x 192238f7987779_011111111111111111111111111111111111111111111111111111111111110& E-473
+    convertToDouble +64409240769861689E-159
+} 0x22692238f7987779
+test expr-28.515 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -77305427432277771 E-190 x -1e978b7780b613_0111111111111111111111111111111111111111111111111111111111110& E-576
+    convertToDouble -77305427432277771E-190
+} 0x9bfe978b7780b613
+test expr-28.516 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +476592356619258326 E273 x 1873cf8ee72812_10000000000000000000000000000000000000000000000000000000000000001& E965
+    convertToDouble +476592356619258326E273
+} 0x7c4873cf8ee72813
+test expr-28.517 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -953184713238516652 E273 x -1873cf8ee72812_10000000000000000000000000000000000000000000000000000000000000001& E966
+    convertToDouble -953184713238516652E273
+} 0xfc5873cf8ee72813
+test expr-28.518 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +899810892172646163 E283 x 1adf51fa055e02_100000000000000000000000000000000000000000000000000000000000000000001& E999
+    convertToDouble +899810892172646163E283
+} 0x7e6adf51fa055e03
+test expr-28.519 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -929167076892018333 E187 x -1da2c42fce2bc4_10000000000000000000000000000000000000000000000000000000000000000001& E680
+    convertToDouble -929167076892018333E187
+} 0xea7da2c42fce2bc5
+test expr-28.520 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +647761278967534239 E-312 x 1a7a2476ec0b3e_10000000000000000000000000000000000000000000000000000000000000001& E-978
+    convertToDouble +647761278967534239E-312
+} 0x02da7a2476ec0b3f
+test expr-28.521 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -644290479820542942 E-180 x -128d1407dfa832_10000000000000000000000000000000000000000000000000000000000000001& E-539
+    convertToDouble -644290479820542942E-180
+} 0x9e428d1407dfa833
+test expr-28.522 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +926145344610700019 E-225 x 1307a67f1f69fe_10000000000000000000000000000000000000000000000000000000000000000001& E-688
+    convertToDouble +926145344610700019E-225
+} 0x14f307a67f1f69ff
+test expr-28.523 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -958507931896511964 E-246 x -17406753df2f0c_10000000000000000000000000000000000000000000000000000000000000001& E-758
+    convertToDouble -958507931896511964E-246
+} 0x9097406753df2f0d
+test expr-28.524 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +272104041512242479 E200 x 13bbb4bf05f087_011111111111111111111111111111111111111111111111111111111111111111111110& E722
+    convertToDouble +272104041512242479E200
+} 0x6d13bbb4bf05f087
+test expr-28.525 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -792644927852378159 E79 x -1daff0048f3ec7_011111111111111111111111111111111111111111111111111111111111111111110& E321
+    convertToDouble -792644927852378159E79
+} 0xd40daff0048f3ec7
+test expr-28.526 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +544208083024484958 E200 x 13bbb4bf05f087_011111111111111111111111111111111111111111111111111111111111111111111110& E723
+    convertToDouble +544208083024484958E200
+} 0x6d23bbb4bf05f087
+test expr-28.527 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -929963218616126365 E290 x -108dcc0c505461_01111111111111111111111111111111111111111111111111111111111111110& E1023
+    convertToDouble -929963218616126365E290
+} 0xffe08dcc0c505461
+test expr-28.528 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +305574339166810102 E-219 x 17f399fe02c4b9_011111111111111111111111111111111111111111111111111111111111111110& E-670
+    convertToDouble +305574339166810102E-219
+} 0x1617f399fe02c4b9
+test expr-28.529 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -152787169583405051 E-219 x -17f399fe02c4b9_011111111111111111111111111111111111111111111111111111111111111110& E-671
+    convertToDouble -152787169583405051E-219
+} 0x9607f399fe02c4b9
+test expr-28.530 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +611148678333620204 E-219 x 17f399fe02c4b9_011111111111111111111111111111111111111111111111111111111111111110& E-669
+    convertToDouble +611148678333620204E-219
+} 0x1627f399fe02c4b9
+test expr-28.531 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -763935847917025255 E-220 x -17f399fe02c4b9_011111111111111111111111111111111111111111111111111111111111111110& E-672
+    convertToDouble -763935847917025255E-220
+} 0x95f7f399fe02c4b9
+test expr-28.532 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +7439550220920798612 E158 x 177fe14f40159a_10000000000000000000000000000000000000000000000000000000000000000000001& E587
+    convertToDouble +7439550220920798612E158
+} 0x64a77fe14f40159b
+test expr-28.533 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -3719775110460399306 E158 x -177fe14f40159a_10000000000000000000000000000000000000000000000000000000000000000000001& E586
+    convertToDouble -3719775110460399306E158
+} 0xe4977fe14f40159b
+test expr-28.534 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +9299437776150998265 E157 x 177fe14f40159a_10000000000000000000000000000000000000000000000000000000000000000000001& E584
+    convertToDouble +9299437776150998265E157
+} 0x64777fe14f40159b
+test expr-28.535 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -7120190517612959703 E120 x -13220dcd5899fc_1000000000000000000000000000000000000000000000000000000000000000000000001& E461
+    convertToDouble -7120190517612959703E120
+} 0xdcc3220dcd5899fd
+test expr-28.536 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +3507665085003296281 E-73 x 11339818257f0e_100000000000000000000000000000000000000000000000000000000000000000000001& E-181
+    convertToDouble +3507665085003296281E-73
+} 0x34a1339818257f0f
+test expr-28.537 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -7015330170006592562 E-73 x -11339818257f0e_100000000000000000000000000000000000000000000000000000000000000000000001& E-180
+    convertToDouble -7015330170006592562E-73
+} 0xb4b1339818257f0f
+test expr-28.538 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -6684428762278255956 E-294 x -1d9f82a1a6b1b8_10000000000000000000000000000000000000000000000000000000000000000001& E-915
+    convertToDouble -6684428762278255956E-294
+} 0x86cd9f82a1a6b1b9
+test expr-28.539 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -1088416166048969916 E200 x -13bbb4bf05f087_011111111111111111111111111111111111111111111111111111111111111111111110& E724
+    convertToDouble -1088416166048969916E200
+} 0xed33bbb4bf05f087
+test expr-28.540 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -8707329328391759328 E200 x -13bbb4bf05f087_011111111111111111111111111111111111111111111111111111111111111111111110& E727
+    convertToDouble -8707329328391759328E200
+} 0xed63bbb4bf05f087
+test expr-28.541 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +4439021781608558002 E-65 x 1038168b71e2c9_01111111111111111111111111111111111111111111111111111111111111111110& E-154
+    convertToDouble +4439021781608558002E-65
+} 0x365038168b71e2c9
+test expr-28.542 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -8878043563217116004 E-65 x -1038168b71e2c9_01111111111111111111111111111111111111111111111111111111111111111110& E-153
+    convertToDouble -8878043563217116004E-65
+} 0xb66038168b71e2c9
+test expr-28.543 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +2219510890804279001 E-65 x 1038168b71e2c9_01111111111111111111111111111111111111111111111111111111111111111110& E-155
+    convertToDouble +2219510890804279001E-65
+} 0x364038168b71e2c9
+test expr-28.544 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +33051223951904955802 E55 x 1762068a24fd54_1000000000000000000000000000000000000000000000000000000000000000000000001& E247
+    convertToDouble +33051223951904955802E55
+} 0x4f6762068a24fd55
+test expr-28.545 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -56961524140903677624 E120 x -13220dcd5899fc_1000000000000000000000000000000000000000000000000000000000000000000000001& E464
+    convertToDouble -56961524140903677624E120
+} 0xdcf3220dcd5899fd
+test expr-28.546 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +71201905176129597030 E119 x 13220dcd5899fc_1000000000000000000000000000000000000000000000000000000000000000000000001& E461
+    convertToDouble +71201905176129597030E119
+} 0x5cc3220dcd5899fd
+test expr-28.547 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +14030660340013185124 E-73 x 11339818257f0e_100000000000000000000000000000000000000000000000000000000000000000000001& E-179
+    convertToDouble +14030660340013185124E-73
+} 0x34c1339818257f0f
+test expr-28.548 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -17538325425016481405 E-74 x -11339818257f0e_100000000000000000000000000000000000000000000000000000000000000000000001& E-182
+    convertToDouble -17538325425016481405E-74
+} 0xb491339818257f0f
+test expr-28.549 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +67536228609141569109 E-133 x 10a1b35cf2a635_01111111111111111111111111111111111111111111111111111111111111111111110& E-376
+    convertToDouble +67536228609141569109E-133
+} 0x2870a1b35cf2a635
+test expr-28.550 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -35620497849450218807 E-306 x -15b22082529425_0111111111111111111111111111111111111111111111111111111111111111111111110& E-952
+    convertToDouble -35620497849450218807E-306
+} 0x8475b22082529425
+test expr-28.551 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN +66550376797582521751 E-126 x 13897c0ede6c69_01111111111111111111111111111111111111111111111111111111111111111111110& E-353
+    convertToDouble +66550376797582521751E-126
+} 0x29e3897c0ede6c69
+test expr-28.552 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b d UN -71240995698900437614 E-306 x -15b22082529425_0111111111111111111111111111111111111111111111111111111111111111111111110& E-951
+    convertToDouble -71240995698900437614E-306
+} 0x8485b22082529425
+test expr-28.553 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +3 E24 x 13da329b633647_0001& E81
+    convertToDouble +3E24
+} 0x4503da329b633647
+test expr-28.554 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -6 E24 x -13da329b633647_0001& E82
+    convertToDouble -6E24
+} 0xc513da329b633647
+test expr-28.555 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +6 E26 x 1f04ef12cb04cf_0001& E88
+    convertToDouble +6E26
+} 0x457f04ef12cb04cf
+test expr-28.556 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -7 E25 x -1cf389cd46047d_0000001& E85
+    convertToDouble -7E25
+} 0xc54cf389cd46047d
+test expr-28.557 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +1 E-14 x 16849b86a12b9b_00000001& E-47
+    convertToDouble +1E-14
+} 0x3d06849b86a12b9b
+test expr-28.558 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -2 E-14 x -16849b86a12b9b_00000001& E-46
+    convertToDouble -2E-14
+} 0xbd16849b86a12b9b
+test expr-28.559 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +4 E-14 x 16849b86a12b9b_00000001& E-45
+    convertToDouble +4E-14
+} 0x3d26849b86a12b9b
+test expr-28.560 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -8 E-14 x -16849b86a12b9b_00000001& E-44
+    convertToDouble -8E-14
+} 0xbd36849b86a12b9b
+test expr-28.561 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +5 E26 x 19d971e4fe8401_1110& E88
+    convertToDouble +5E26
+} 0x4579d971e4fe8402
+test expr-28.562 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -8 E27 x -19d971e4fe8401_1110& E92
+    convertToDouble -8E27
+} 0xc5b9d971e4fe8402
+test expr-28.563 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +1 E27 x 19d971e4fe8401_1110& E89
+    convertToDouble +1E27
+} 0x4589d971e4fe8402
+test expr-28.564 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -4 E27 x -19d971e4fe8401_1110& E91
+    convertToDouble -4E27
+} 0xc5a9d971e4fe8402
+test expr-28.565 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +9 E-13 x 1faa7ab552a551_111110& E-41
+    convertToDouble +9E-13
+} 0x3d6faa7ab552a552
+test expr-28.566 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -7 E-20 x -14a90ceafff9de_11110& E-64
+    convertToDouble -7E-20
+} 0xbbf4a90ceafff9df
+test expr-28.567 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +56 E25 x 1cf389cd46047d_0000001& E88
+    convertToDouble +56E25
+} 0x457cf389cd46047d
+test expr-28.568 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -70 E24 x -1cf389cd46047d_0000001& E85
+    convertToDouble -70E24
+} 0xc54cf389cd46047d
+test expr-28.569 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +51 E26 x 107a9f01fbda8e_0000001& E92
+    convertToDouble +51E26
+} 0x45b07a9f01fbda8e
+test expr-28.570 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +71 E-17 x 19949819f693d7_00000000001& E-51
+    convertToDouble +71E-17
+} 0x3cc9949819f693d7
+test expr-28.571 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -31 E-5 x -1450efdc9c4da9_00000000001& E-12
+    convertToDouble -31E-5
+} 0xbf3450efdc9c4da9
+test expr-28.572 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +62 E-5 x 1450efdc9c4da9_00000000001& E-11
+    convertToDouble +62E-5
+} 0x3f4450efdc9c4da9
+test expr-28.573 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -94 E-8 x -1f8a89dc374df5_0000000001& E-21
+    convertToDouble -94E-8
+} 0xbeaf8a89dc374df5
+test expr-28.574 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +67 E27 x 1b0fa33bba7231_11111110& E95
+    convertToDouble +67E27
+} 0x45eb0fa33bba7232
+test expr-28.575 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -81 E24 x -10c01ab31bb5cb_1111110& E86
+    convertToDouble -81E24
+} 0xc550c01ab31bb5cc
+test expr-28.576 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +54 E23 x 11ddfa58a6173f_111110& E82
+    convertToDouble +54E23
+} 0x4511ddfa58a61740
+test expr-28.577 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -54 E25 x -1bead72a838453_111110& E88
+    convertToDouble -54E25
+} 0xc57bead72a838454
+test expr-28.578 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +63 E-22 x 1dc03b8fd70169_11111111110& E-68
+    convertToDouble +63E-22
+} 0x3bbdc03b8fd7016a
+test expr-28.579 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -63 E-23 x -17ccfc73126787_11111111110& E-71
+    convertToDouble -63E-23
+} 0xbb87ccfc73126788
+test expr-28.580 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +43 E-4 x 119ce075f6fd21_111111110& E-8
+    convertToDouble +43E-4
+} 0x3f719ce075f6fd22
+test expr-28.581 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -86 E-4 x -119ce075f6fd21_111111110& E-7
+    convertToDouble -86E-4
+} 0xbf819ce075f6fd22
+test expr-28.582 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +942 E26 x 1306069e8681f3_00000000001& E96
+    convertToDouble +942E26
+} 0x45f306069e8681f3
+test expr-28.583 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -471 E25 x -1e700a973d9cb8_0000000001& E91
+    convertToDouble -471E25
+} 0xc5ae700a973d9cb8
+test expr-28.584 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +803 E24 x 14c1cee9cd666b_000000000001& E89
+    convertToDouble +803E24
+} 0x4584c1cee9cd666b
+test expr-28.585 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -471 E26 x -1306069e8681f3_00000000001& E95
+    convertToDouble -471E26
+} 0xc5e306069e8681f3
+test expr-28.586 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -409 E-21 x -1e2dcaa4115622_000000000001& E-62
+    convertToDouble -409E-21
+} 0xbc1e2dcaa4115622
+test expr-28.587 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +818 E-21 x 1e2dcaa4115622_000000000001& E-61
+    convertToDouble +818E-21
+} 0x3c2e2dcaa4115622
+test expr-28.588 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -867 E-8 x -122eabba029aba_000000000001& E-17
+    convertToDouble -867E-8
+} 0xbee22eabba029aba
+test expr-28.589 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +538 E27 x 1b297cad9f70b5_1111111111111110& E98
+    convertToDouble +538E27
+} 0x461b297cad9f70b6
+test expr-28.590 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -857 E24 x -16272678ba603b_11111111110& E89
+    convertToDouble -857E24
+} 0xc586272678ba603c
+test expr-28.591 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +269 E27 x 1b297cad9f70b5_1111111111111110& E97
+    convertToDouble +269E27
+} 0x460b297cad9f70b6
+test expr-28.592 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -403 E26 x -1046ec1e31dd85_1111111110& E95
+    convertToDouble -403E26
+} 0xc5e046ec1e31dd86
+test expr-28.593 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +959 E-7 x 1923bd746a3527_11111111111110& E-14
+    convertToDouble +959E-7
+} 0x3f1923bd746a3528
+test expr-28.594 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -959 E-6 x -1f6cacd184c271_1111111111110& E-11
+    convertToDouble -959E-6
+} 0xbf4f6cacd184c272
+test expr-28.595 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +373 E-27 x 1cdc06b20ef182_1111111111110& E-82
+    convertToDouble +373E-27
+} 0x3adcdc06b20ef183
+test expr-28.596 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -746 E-27 x -1cdc06b20ef182_1111111111110& E-81
+    convertToDouble -746E-27
+} 0xbaecdc06b20ef183
+test expr-28.597 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +4069 E24 x 1a4b9887fbfe7a_0000000000001& E91
+    convertToDouble +4069E24
+} 0x45aa4b9887fbfe7a
+test expr-28.598 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -4069 E23 x -150946d32ffec8_0000000000001& E88
+    convertToDouble -4069E23
+} 0xc5750946d32ffec8
+test expr-28.599 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -8138 E24 x -1a4b9887fbfe7a_0000000000001& E92
+    convertToDouble -8138E24
+} 0xc5ba4b9887fbfe7a
+test expr-28.600 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +8294 E-15 x 123d1b5eb1d778_000000000000000001& E-37
+    convertToDouble +8294E-15
+} 0x3da23d1b5eb1d778
+test expr-28.601 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -4147 E-14 x -16cc62365e4d56_00000000000000001& E-35
+    convertToDouble -4147E-14
+} 0xbdc6cc62365e4d56
+test expr-28.602 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +4147 E-15 x 123d1b5eb1d778_000000000000000001& E-38
+    convertToDouble +4147E-15
+} 0x3d923d1b5eb1d778
+test expr-28.603 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -8294 E-14 x -16cc62365e4d56_00000000000000001& E-34
+    convertToDouble -8294E-14
+} 0xbdd6cc62365e4d56
+test expr-28.604 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +538 E27 x 1b297cad9f70b5_1111111111111110& E98
+    convertToDouble +538E27
+} 0x461b297cad9f70b6
+test expr-28.605 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -2690 E26 x -1b297cad9f70b5_1111111111111110& E97
+    convertToDouble -2690E26
+} 0xc60b297cad9f70b6
+test expr-28.606 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +269 E27 x 1b297cad9f70b5_1111111111111110& E97
+    convertToDouble +269E27
+} 0x460b297cad9f70b6
+test expr-28.607 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -2152 E27 x -1b297cad9f70b5_1111111111111110& E100
+    convertToDouble -2152E27
+} 0xc63b297cad9f70b6
+test expr-28.608 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +1721 E-17 x 136071dcae4564_111111111111110& E-46
+    convertToDouble +1721E-17
+} 0x3d136071dcae4565
+test expr-28.609 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -7979 E-27 x -134ac304747faf_111111111111110& E-77
+    convertToDouble -7979E-27
+} 0xbb234ac304747fb0
+test expr-28.610 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +6884 E-17 x 136071dcae4564_111111111111110& E-44
+    convertToDouble +6884E-17
+} 0x3d336071dcae4565
+test expr-28.611 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -8605 E-18 x -136071dcae4564_111111111111110& E-47
+    convertToDouble -8605E-18
+} 0xbd036071dcae4565
+test expr-28.612 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +82854 E27 x 10570ed9e3cecc_00000000000000001& E106
+    convertToDouble +82854E27
+} 0x4690570ed9e3cecc
+test expr-28.613 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -55684 E24 x -167d9735144ae3_00000000000000001& E95
+    convertToDouble -55684E24
+} 0xc5e67d9735144ae3
+test expr-28.614 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +27842 E24 x 167d9735144ae3_00000000000000001& E94
+    convertToDouble +27842E24
+} 0x45d67d9735144ae3
+test expr-28.615 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -48959 E25 x -18b7cd6ca56f85_00000000000000001& E98
+    convertToDouble -48959E25
+} 0xc618b7cd6ca56f85
+test expr-28.616 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +81921 E-17 x 1cd2c9a6cdd003_000000000000000000001& E-41
+    convertToDouble +81921E-17
+} 0x3d6cd2c9a6cdd003
+test expr-28.617 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -76207 E-8 x -18f8b4dd16f1df_0000000000000000001& E-11
+    convertToDouble -76207E-8
+} 0xbf48f8b4dd16f1df
+test expr-28.618 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +4147 E-15 x 123d1b5eb1d778_000000000000000001& E-38
+    convertToDouble +4147E-15
+} 0x3d923d1b5eb1d778
+test expr-28.619 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -41470 E-16 x -123d1b5eb1d778_000000000000000001& E-38
+    convertToDouble -41470E-16
+} 0xbd923d1b5eb1d778
+test expr-28.620 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +89309 E24 x 12092ac5f2019e_1111111111111111110& E96
+    convertToDouble +89309E24
+} 0x45f2092ac5f2019f
+test expr-28.621 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +75859 E26 x 17efd75a2938eb_1111111111111111111110& E102
+    convertToDouble +75859E26
+} 0x4657efd75a2938ec
+test expr-28.622 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -75859 E25 x -132645e1ba93ef_1111111111111111111110& E99
+    convertToDouble -75859E25
+} 0xc6232645e1ba93f0
+test expr-28.623 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +14257 E-23 x 150a246ecd44f2_1111111111111111110& E-63
+    convertToDouble +14257E-23
+} 0x3c050a246ecd44f3
+test expr-28.624 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -28514 E-23 x -150a246ecd44f2_1111111111111111110& E-62
+    convertToDouble -28514E-23
+} 0xbc150a246ecd44f3
+test expr-28.625 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +57028 E-23 x 150a246ecd44f2_1111111111111111110& E-61
+    convertToDouble +57028E-23
+} 0x3c250a246ecd44f3
+test expr-28.626 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -71285 E-24 x -150a246ecd44f2_1111111111111111110& E-64
+    convertToDouble -71285E-24
+} 0xbbf50a246ecd44f3
+test expr-28.627 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +344863 E27 x 1100c873963d6d_00000000000000000001& E108
+    convertToDouble +344863E27
+} 0x46b100c873963d6d
+test expr-28.628 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -951735 E27 x -17764ad224e24a_000000000000000000001& E109
+    convertToDouble -951735E27
+} 0xc6c7764ad224e24a
+test expr-28.629 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +200677 E23 x 1035e73135b834_0000000000000000001& E94
+    convertToDouble +200677E23
+} 0x45d035e73135b834
+test expr-28.630 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -401354 E24 x -144360fd832641_0000000000000000001& E98
+    convertToDouble -401354E24
+} 0xc6144360fd832641
+test expr-28.631 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +839604 E-11 x 119b96f36ec68b_00000000000000000000000001& E-17
+    convertToDouble +839604E-11
+} 0x3ee19b96f36ec68b
+test expr-28.632 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -209901 E-11 x -119b96f36ec68b_00000000000000000000000001& E-19
+    convertToDouble -209901E-11
+} 0xbec19b96f36ec68b
+test expr-28.633 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +419802 E-11 x 119b96f36ec68b_00000000000000000000000001& E-18
+    convertToDouble +419802E-11
+} 0x3ed19b96f36ec68b
+test expr-28.634 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -537734 E-24 x -13d6c1088ae40e_0000000000000000000001& E-61
+    convertToDouble -537734E-24
+} 0xbc23d6c1088ae40e
+test expr-28.635 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +910308 E26 x 11f3e1839eeab0_11111111111111111111110& E106
+    convertToDouble +910308E26
+} 0x4691f3e1839eeab1
+test expr-28.636 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -227577 E26 x -11f3e1839eeab0_11111111111111111111110& E104
+    convertToDouble -227577E26
+} 0xc671f3e1839eeab1
+test expr-28.637 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +455154 E26 x 11f3e1839eeab0_11111111111111111111110& E105
+    convertToDouble +455154E26
+} 0x4681f3e1839eeab1
+test expr-28.638 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -531013 E25 x -10c17d25834171_11111111111111111111110& E102
+    convertToDouble -531013E25
+} 0xc650c17d25834172
+test expr-28.639 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +963019 E-21 x 11592429784914_11111111111111111111110& E-50
+    convertToDouble +963019E-21
+} 0x3cd1592429784915
+test expr-28.640 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -519827 E-13 x -1be872a8b30d7c_11111111111111111111110& E-25
+    convertToDouble -519827E-13
+} 0xbe6be872a8b30d7d
+test expr-28.641 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +623402 E-27 x 178d2c97bde2a0_11111111111111111111110& E-71
+    convertToDouble +623402E-27
+} 0x3b878d2c97bde2a1
+test expr-28.642 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -311701 E-27 x -178d2c97bde2a0_11111111111111111111110& E-72
+    convertToDouble -311701E-27
+} 0xbb778d2c97bde2a1
+test expr-28.643 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +9613651 E26 x 17b31116270d9b_000000000000000000000001& E109
+    convertToDouble +9613651E26
+} 0x46c7b31116270d9b
+test expr-28.644 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -9191316 E23 x -1733bfae0801fd_0000000000000000000001& E99
+    convertToDouble -9191316E23
+} 0xc62733bfae0801fd
+test expr-28.645 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +4595658 E23 x 1733bfae0801fd_0000000000000000000001& E98
+    convertToDouble +4595658E23
+} 0x461733bfae0801fd
+test expr-28.646 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -2297829 E23 x -1733bfae0801fd_0000000000000000000001& E97
+    convertToDouble -2297829E23
+} 0xc60733bfae0801fd
+test expr-28.647 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -1679208 E-11 x -119b96f36ec68b_00000000000000000000000001& E-16
+    convertToDouble -1679208E-11
+} 0xbef19b96f36ec68b
+test expr-28.648 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +3379223 E27 x 14d3794ce2fc25_1111111111111111111111110& E111
+    convertToDouble +3379223E27
+} 0x46e4d3794ce2fc26
+test expr-28.649 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -6758446 E27 x -14d3794ce2fc25_1111111111111111111111110& E112
+    convertToDouble -6758446E27
+} 0xc6f4d3794ce2fc26
+test expr-28.650 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +5444097 E-21 x 18849dd33c95ae_11111111111111111111111111110& E-48
+    convertToDouble +5444097E-21
+} 0x3cf8849dd33c95af
+test expr-28.651 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -8399969 E-27 x -13d5783e85fcf7_1111111111111111111111110& E-67
+    convertToDouble -8399969E-27
+} 0xbbc3d5783e85fcf8
+test expr-28.652 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +8366487 E-16 x 1cbf3d630403af_1111111111111111111111110& E-31
+    convertToDouble +8366487E-16
+} 0x3e0cbf3d630403b0
+test expr-28.653 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -8366487 E-15 x -11f7865de2824d_11111111111111111111111110& E-27
+    convertToDouble -8366487E-15
+} 0xbe41f7865de2824e
+test expr-28.654 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +65060671 E25 x 1009e7d474572a_0000000000000000000000000001& E109
+    convertToDouble +65060671E25
+} 0x46c009e7d474572a
+test expr-28.655 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +65212389 E23 x 1493d098d37657_000000000000000000000000001& E102
+    convertToDouble +65212389E23
+} 0x465493d098d37657
+test expr-28.656 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +55544957 E-13 x 174c1826f3010c_00000000000000000000000000001& E-18
+    convertToDouble +55544957E-13
+} 0x3ed74c1826f3010c
+test expr-28.657 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -51040905 E-20 x -11f55b23c8bf2d_0000000000000000000000000001& E-41
+    convertToDouble -51040905E-20
+} 0xbd61f55b23c8bf2d
+test expr-28.658 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +99585767 E-22 x 166cba8699f0f2_0000000000000000000000000001& E-47
+    convertToDouble +99585767E-22
+} 0x3d066cba8699f0f2
+test expr-28.659 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -99585767 E-23 x -11f095387b2728_0000000000000000000000000001& E-50
+    convertToDouble -99585767E-23
+} 0xbcd1f095387b2728
+test expr-28.660 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +40978393 E26 x 1941401cca2bfd_1111111111111111111111111110& E111
+    convertToDouble +40978393E26
+} 0x46e941401cca2bfe
+test expr-28.661 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -67488159 E24 x -1a9e90059d12db_11111111111111111111111111110& E105
+    convertToDouble -67488159E24
+} 0xc68a9e90059d12dc
+test expr-28.662 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +69005339 E23 x 15c634f6ef1f95_111111111111111111111111110& E102
+    convertToDouble +69005339E23
+} 0x4655c634f6ef1f96
+test expr-28.663 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -81956786 E26 x -1941401cca2bfd_1111111111111111111111111110& E112
+    convertToDouble -81956786E26
+} 0xc6f941401cca2bfe
+test expr-28.664 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -87105552 E-21 x -18849dd33c95ae_11111111111111111111111111110& E-44
+    convertToDouble -87105552E-21
+} 0xbd38849dd33c95af
+test expr-28.665 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +10888194 E-21 x 18849dd33c95ae_11111111111111111111111111110& E-47
+    convertToDouble +10888194E-21
+} 0x3d08849dd33c95af
+test expr-28.666 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -21776388 E-21 x -18849dd33c95ae_11111111111111111111111111110& E-46
+    convertToDouble -21776388E-21
+} 0xbd18849dd33c95af
+test expr-28.667 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +635806667 E27 x 1e9cec176c96f8_000000000000000000000000000000001& E118
+    convertToDouble +635806667E27
+} 0x475e9cec176c96f8
+test expr-28.668 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -670026614 E25 x -14a593f89f4194_00000000000000000000000000000001& E112
+    convertToDouble -670026614E25
+} 0xc6f4a593f89f4194
+test expr-28.669 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +335013307 E26 x 19cef8f6c711f9_0000000000000000000000000000001& E114
+    convertToDouble +335013307E26
+} 0x4719cef8f6c711f9
+test expr-28.670 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -335013307 E25 x -14a593f89f4194_00000000000000000000000000000001& E111
+    convertToDouble -335013307E25
+} 0xc6e4a593f89f4194
+test expr-28.671 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +371790617 E-24 x 1aca538c61ba9c_000000000000000000000000000000001& E-52
+    convertToDouble +371790617E-24
+} 0x3cbaca538c61ba9c
+test expr-28.672 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -371790617 E-25 x -156ea93d1afbb0_0000000000000000000000000000000001& E-55
+    convertToDouble -371790617E-25
+} 0xbc856ea93d1afbb0
+test expr-28.673 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +743581234 E-24 x 1aca538c61ba9c_000000000000000000000000000000001& E-51
+    convertToDouble +743581234E-24
+} 0x3ccaca538c61ba9c
+test expr-28.674 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -743581234 E-25 x -156ea93d1afbb0_0000000000000000000000000000000001& E-54
+    convertToDouble -743581234E-25
+} 0xbc956ea93d1afbb0
+test expr-28.675 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +202464477 E24 x 13f6ec0435ce24_111111111111111111111111111110& E107
+    convertToDouble +202464477E24
+} 0x46a3f6ec0435ce25
+test expr-28.676 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -404928954 E24 x -13f6ec0435ce24_111111111111111111111111111110& E108
+    convertToDouble -404928954E24
+} 0xc6b3f6ec0435ce25
+test expr-28.677 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +997853758 E27 x 1805bfa33b98fa_111111111111111111111111111110& E119
+    convertToDouble +997853758E27
+} 0x476805bfa33b98fb
+test expr-28.678 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -997853758 E26 x -1337cc829613fb_111111111111111111111111111110& E116
+    convertToDouble -997853758E26
+} 0xc73337cc829613fc
+test expr-28.679 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +405498418 E-17 x 116a8093df66a6_111111111111111111111111111111110& E-28
+    convertToDouble +405498418E-17
+} 0x3e316a8093df66a7
+test expr-28.680 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -582579084 E-14 x -186f653140a658_111111111111111111111111111111110& E-18
+    convertToDouble -582579084E-14
+} 0xbed86f653140a659
+test expr-28.681 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +608247627 E-18 x 14e633e4a5ae61_111111111111111111111111111111110& E-31
+    convertToDouble +608247627E-18
+} 0x3e04e633e4a5ae62
+test expr-28.682 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -291289542 E-14 x -186f653140a658_111111111111111111111111111111110& E-19
+    convertToDouble -291289542E-14
+} 0xbec86f653140a659
+test expr-28.683 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -9537100005 E26 x -16f5b11191713a_000000000000000000000000000000001& E119
+    convertToDouble -9537100005E26
+} 0xc766f5b11191713a
+test expr-28.684 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +6358066670 E27 x 1322138ea3de5b_000000000000000000000000000000001& E122
+    convertToDouble +6358066670E27
+} 0x479322138ea3de5b
+test expr-28.685 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -1271613334 E27 x -1e9cec176c96f8_000000000000000000000000000000001& E119
+    convertToDouble -1271613334E27
+} 0xc76e9cec176c96f8
+test expr-28.686 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +5229646999 E-16 x 118c3b89731f3d_000000000000000000000000000000000001& E-21
+    convertToDouble +5229646999E-16
+} 0x3ea18c3b89731f3d
+test expr-28.687 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +5229646999 E-17 x 1c13927584fec8_00000000000000000000000000000000001& E-25
+    convertToDouble +5229646999E-17
+} 0x3e6c13927584fec8
+test expr-28.688 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +4429943614 E24 x 1b4d37fa06864a_1111111111111111111111111111111110& E111
+    convertToDouble +4429943614E24
+} 0x46eb4d37fa06864b
+test expr-28.689 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -8859887228 E24 x -1b4d37fa06864a_1111111111111111111111111111111110& E112
+    convertToDouble -8859887228E24
+} 0xc6fb4d37fa06864b
+test expr-28.690 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +2214971807 E24 x 1b4d37fa06864a_1111111111111111111111111111111110& E110
+    convertToDouble +2214971807E24
+} 0x46db4d37fa06864b
+test expr-28.691 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -4176887093 E26 x -141c692c5bd07a_111111111111111111111111111111110& E118
+    convertToDouble -4176887093E26
+} 0xc7541c692c5bd07b
+test expr-28.692 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +4003495257 E-20 x 16026b2e07ec06_111111111111111111111111111111111110& E-35
+    convertToDouble +4003495257E-20
+} 0x3dc6026b2e07ec07
+test expr-28.693 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -4361901637 E-23 x -188e29a9d7c5b8_11111111111111111111111111111111110& E-45
+    convertToDouble -4361901637E-23
+} 0xbd288e29a9d7c5b9
+test expr-28.694 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +8723803274 E-23 x 188e29a9d7c5b8_11111111111111111111111111111111110& E-44
+    convertToDouble +8723803274E-23
+} 0x3d388e29a9d7c5b9
+test expr-28.695 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -8006990514 E-20 x -16026b2e07ec06_111111111111111111111111111111111110& E-34
+    convertToDouble -8006990514E-20
+} 0xbdd6026b2e07ec07
+test expr-28.696 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +72835110098 E27 x 1b65c41711fb6d_0000000000000000000000000000000000001& E125
+    convertToDouble +72835110098E27
+} 0x47cb65c41711fb6d
+test expr-28.697 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -36417555049 E27 x -1b65c41711fb6d_0000000000000000000000000000000000001& E124
+    convertToDouble -36417555049E27
+} 0xc7bb65c41711fb6d
+test expr-28.698 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +84279630104 E25 x 144a221b1cf62e_000000000000000000000000000000000001& E119
+    convertToDouble +84279630104E25
+} 0x47644a221b1cf62e
+test expr-28.699 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -84279630104 E24 x -103b4e7c172b58_000000000000000000000000000000000001& E116
+    convertToDouble -84279630104E24
+} 0xc7303b4e7c172b58
+test expr-28.700 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +21206176437 E-27 x 1872f563ae0cc9_0000000000000000000000000000000000001& E-56
+    convertToDouble +21206176437E-27
+} 0x3c7872f563ae0cc9
+test expr-28.701 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -66461566917 E-22 x -1d3ae83e4322b3_00000000000000000000000000000000000001& E-38
+    convertToDouble -66461566917E-22
+} 0xbd9d3ae83e4322b3
+test expr-28.702 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +64808355539 E-16 x 1b2ebe83265fbf_00000000000000000000000000000000000001& E-18
+    convertToDouble +64808355539E-16
+} 0x3edb2ebe83265fbf
+test expr-28.703 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -84932679673 E-19 x -123d39339f1bf6_00000000000000000000000000000000000001& E-27
+    convertToDouble -84932679673E-19
+} 0xbe423d39339f1bf6
+test expr-28.704 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +65205430094 E26 x 139f3e5d7fd76a_1111111111111111111111111111111111110& E122
+    convertToDouble +65205430094E26
+} 0x47939f3e5d7fd76b
+test expr-28.705 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -68384463429 E25 x -107684982f634e_1111111111111111111111111111111111111110& E119
+    convertToDouble -68384463429E25
+} 0xc7607684982f634f
+test expr-28.706 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +32602715047 E26 x 139f3e5d7fd76a_1111111111111111111111111111111111110& E121
+    convertToDouble +32602715047E26
+} 0x47839f3e5d7fd76b
+test expr-28.707 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -62662203426 E27 x -1792269424688d_111111111111111111111111111111111110& E125
+    convertToDouble -62662203426E27
+} 0xc7c792269424688e
+test expr-28.708 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +58784444678 E-18 x 1f8f45c64b4682_111111111111111111111111111111111111110& E-25
+    convertToDouble +58784444678E-18
+} 0x3e6f8f45c64b4683
+test expr-28.709 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -50980203373 E-21 x -1c06d366394440_11111111111111111111111111111111111111111110& E-35
+    convertToDouble -50980203373E-21
+} 0xbdcc06d366394441
+test expr-28.710 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +29392222339 E-18 x 1f8f45c64b4682_111111111111111111111111111111111111110& E-26
+    convertToDouble +29392222339E-18
+} 0x3e5f8f45c64b4683
+test expr-28.711 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -75529940323 E-27 x -15c5203c0aad52_1111111111111111111111111111111111111110& E-54
+    convertToDouble -75529940323E-27
+} 0xbc95c5203c0aad53
+test expr-28.712 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -937495906299 E26 x -11a1e0ebb6af11_000000000000000000000000000000000000000001& E126
+    convertToDouble -937495906299E26
+} 0xc7d1a1e0ebb6af11
+test expr-28.713 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +842642485799 E-20 x 121879decdd7cb_000000000000000000000000000000000000000001& E-27
+    convertToDouble +842642485799E-20
+} 0x3e421879decdd7cb
+test expr-28.714 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -387824150699 E-23 x -110e8302245571_00000000000000000000000000000000000000001& E-38
+    convertToDouble -387824150699E-23
+} 0xbd910e8302245571
+test expr-28.715 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +924948814726 E-27 x 10a992d1fc6ded_00000000000000000000000000000000000000001& E-50
+    convertToDouble +924948814726E-27
+} 0x3cd0a992d1fc6ded
+test expr-28.716 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -775648301398 E-23 x -110e8302245571_00000000000000000000000000000000000000001& E-37
+    convertToDouble -775648301398E-23
+} 0xbda10e8302245571
+test expr-28.717 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +547075707432 E25 x 107684982f634e_1111111111111111111111111111111111111110& E122
+    convertToDouble +547075707432E25
+} 0x47907684982f634f
+test expr-28.718 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +683844634290 E24 x 107684982f634e_1111111111111111111111111111111111111110& E119
+    convertToDouble +683844634290E24
+} 0x47607684982f634f
+test expr-28.719 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -136768926858 E25 x -107684982f634e_1111111111111111111111111111111111111110& E120
+    convertToDouble -136768926858E25
+} 0xc7707684982f634f
+test expr-28.720 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +509802033730 E-22 x 1c06d366394440_11111111111111111111111111111111111111111110& E-35
+    convertToDouble +509802033730E-22
+} 0x3dcc06d366394441
+test expr-28.721 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +101960406746 E-21 x 1c06d366394440_11111111111111111111111111111111111111111110& E-34
+    convertToDouble +101960406746E-21
+} 0x3ddc06d366394441
+test expr-28.722 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -815683253968 E-21 x -1c06d366394440_11111111111111111111111111111111111111111110& E-31
+    convertToDouble -815683253968E-21
+} 0xbe0c06d366394441
+test expr-28.723 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +7344124123524 E24 x 1619b519dd6833_00000000000000000000000000000000000000000001& E122
+    convertToDouble +7344124123524E24
+} 0x479619b519dd6833
+test expr-28.724 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -9180155154405 E23 x -1619b519dd6833_00000000000000000000000000000000000000000001& E119
+    convertToDouble -9180155154405E23
+} 0xc76619b519dd6833
+test expr-28.725 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +6479463327323 E27 x 130a9b3e9bd05e_00000000000000000000000000000000000000000001& E132
+    convertToDouble +6479463327323E27
+} 0x48330a9b3e9bd05e
+test expr-28.726 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -1836031030881 E24 x -1619b519dd6833_00000000000000000000000000000000000000000001& E120
+    convertToDouble -1836031030881E24
+} 0xc77619b519dd6833
+test expr-28.727 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +4337269293039 E-19 x 1d1b5f354c63d6_00000000000000000000000000000000000000000001& E-22
+    convertToDouble +4337269293039E-19
+} 0x3e9d1b5f354c63d6
+test expr-28.728 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -4599163554373 E-23 x -1948bf4d34088d_00000000000000000000000000000000000000000001& E-35
+    convertToDouble -4599163554373E-23
+} 0xbdc948bf4d34088d
+test expr-28.729 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +9198327108746 E-23 x 1948bf4d34088d_00000000000000000000000000000000000000000001& E-34
+    convertToDouble +9198327108746E-23
+} 0x3dd948bf4d34088d
+test expr-28.730 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +4812803938347 E27 x 1c4980a4ee94ce_111111111111111111111111111111111111111111110& E131
+    convertToDouble +4812803938347E27
+} 0x482c4980a4ee94cf
+test expr-28.731 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -8412030890011 E23 x -14405075e52db9_11111111111111111111111111111111111111111110& E119
+    convertToDouble -8412030890011E23
+} 0xc764405075e52dba
+test expr-28.732 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +9625607876694 E27 x 1c4980a4ee94ce_111111111111111111111111111111111111111111110& E132
+    convertToDouble +9625607876694E27
+} 0x483c4980a4ee94cf
+test expr-28.733 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -4739968828249 E24 x -1c87140cdf8a1d_1111111111111111111111111111111111111111110& E121
+    convertToDouble -4739968828249E24
+} 0xc78c87140cdf8a1e
+test expr-28.734 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +9697183891673 E-23 x 1aa7c959b6a666_11111111111111111111111111111111111111111111110& E-34
+    convertToDouble +9697183891673E-23
+} 0x3ddaa7c959b6a667
+test expr-28.735 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -7368108517543 E-20 x -13c7535bbd85a1_1111111111111111111111111111111111111111111110& E-24
+    convertToDouble -7368108517543E-20
+} 0xbe73c7535bbd85a2
+test expr-28.736 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +51461358161422 E25 x 18326f87d4cae0_0000000000000000000000000000000000000000000000001& E128
+    convertToDouble +51461358161422E25
+} 0x47f8326f87d4cae0
+test expr-28.737 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -77192037242133 E26 x -16af488f577e32_0000000000000000000000000000000000000000000000001& E132
+    convertToDouble -77192037242133E26
+} 0xc836af488f577e32
+test expr-28.738 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +77192037242133 E25 x 1225d3a5df9828_0000000000000000000000000000000000000000000000001& E129
+    convertToDouble +77192037242133E25
+} 0x480225d3a5df9828
+test expr-28.739 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -51461358161422 E27 x -12e767221e3e7f_0000000000000000000000000000000000000000000000001& E135
+    convertToDouble -51461358161422E27
+} 0xc862e767221e3e7f
+test expr-28.740 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +43999661561541 E-21 x 179f4476d372a3_0000000000000000000000000000000000000000000000001& E-25
+    convertToDouble +43999661561541E-21
+} 0x3e679f4476d372a3
+test expr-28.741 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -87999323123082 E-21 x -179f4476d372a3_0000000000000000000000000000000000000000000000001& E-24
+    convertToDouble -87999323123082E-21
+} 0xbe779f4476d372a3
+test expr-28.742 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +48374886826137 E-26 x 110538f23350d5_00000000000000000000000000000000000000000000001& E-41
+    convertToDouble +48374886826137E-26
+} 0x3d610538f23350d5
+test expr-28.743 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -57684246567111 E-23 x -13d1f5c1b8a912_00000000000000000000000000000000000000000000001& E-31
+    convertToDouble -57684246567111E-23
+} 0xbe03d1f5c1b8a912
+test expr-28.744 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +87192805957686 E23 x 1a3d16e55a9664_1111111111111111111111111111111111111111111110& E122
+    convertToDouble +87192805957686E23
+} 0x479a3d16e55a9665
+test expr-28.745 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -75108713005913 E24 x -1c40b4baa79655_11111111111111111111111111111111111111111111110& E125
+    convertToDouble -75108713005913E24
+} 0xc7cc40b4baa79656
+test expr-28.746 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +64233110587487 E27 x 179873e38669a6_1111111111111111111111111111111111111111111110& E135
+    convertToDouble +64233110587487E27
+} 0x48679873e38669a7
+test expr-28.747 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -77577471133384 E-23 x -1aa7c959b6a666_11111111111111111111111111111111111111111111110& E-31
+    convertToDouble -77577471133384E-23
+} 0xbe0aa7c959b6a667
+test expr-28.748 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +48485919458365 E-24 x 1aa7c959b6a666_11111111111111111111111111111111111111111111110& E-35
+    convertToDouble +48485919458365E-24
+} 0x3dcaa7c959b6a667
+test expr-28.749 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -56908598265713 E-26 x -1405deef4bdef5_111111111111111111111111111111111111111111111110& E-41
+    convertToDouble -56908598265713E-26
+} 0xbd6405deef4bdef6
+test expr-28.750 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +589722294620133 E23 x 162ed1b287caef_00000000000000000000000000000000000000000000000001& E125
+    convertToDouble +589722294620133E23
+} 0x47c62ed1b287caef
+test expr-28.751 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +652835804449289 E-22 x 118640e490b087_0000000000000000000000000000000000000000000000000001& E-24
+    convertToDouble +652835804449289E-22
+} 0x3e718640e490b087
+test expr-28.752 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -656415363936202 E-23 x -1c315cfe25d201_00000000000000000000000000000000000000000000000001& E-28
+    convertToDouble -656415363936202E-23
+} 0xbe3c315cfe25d201
+test expr-28.753 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +579336749585745 E-25 x 1fd9709d9aeb19_00000000000000000000000000000000000000000000000001& E-35
+    convertToDouble +579336749585745E-25
+} 0x3dcfd9709d9aeb19
+test expr-28.754 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -381292764980839 E-26 x -10c4f9921c3f8f_00000000000000000000000000000000000000000000000001& E-38
+    convertToDouble -381292764980839E-26
+} 0xbd90c4f9921c3f8f
+test expr-28.755 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +965265859649698 E23 x 12279607edcb0c_1111111111111111111111111111111111111111111111110& E126
+    convertToDouble +965265859649698E23
+} 0x47d2279607edcb0d
+test expr-28.756 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -848925235434882 E27 x -137d88ba4b43e3_1111111111111111111111111111111111111111111111111110& E139
+    convertToDouble -848925235434882E27
+} 0xc8a37d88ba4b43e4
+test expr-28.757 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +536177612222491 E23 x 142b33dd3acafd_11111111111111111111111111111111111111111111111110& E125
+    convertToDouble +536177612222491E23
+} 0x47c42b33dd3acafe
+test expr-28.758 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -424462617717441 E27 x -137d88ba4b43e3_1111111111111111111111111111111111111111111111111110& E138
+    convertToDouble -424462617717441E27
+} 0xc8937d88ba4b43e4
+test expr-28.759 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +276009279888989 E-27 x 136c242313c288_111111111111111111111111111111111111111111111111110& E-42
+    convertToDouble +276009279888989E-27
+} 0x3d536c242313c289
+test expr-28.760 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -608927158043691 E-26 x -1ac7e909c22f09_11111111111111111111111111111111111111111111111110& E-38
+    convertToDouble -608927158043691E-26
+} 0xbd9ac7e909c22f0a
+test expr-28.761 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +552018559777978 E-27 x 136c242313c288_111111111111111111111111111111111111111111111111110& E-41
+    convertToDouble +552018559777978E-27
+} 0x3d636c242313c289
+test expr-28.762 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -425678377667758 E-22 x -16da7aa49bdcd5_1111111111111111111111111111111111111111111111110& E-25
+    convertToDouble -425678377667758E-22
+} 0xbe66da7aa49bdcd6
+test expr-28.763 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +8013702726927119 E26 x 126607f8f1b29e_00000000000000000000000000000000000000000000000000001& E139
+    convertToDouble +8013702726927119E26
+} 0x48a26607f8f1b29e
+test expr-28.764 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +8862627962362001 E27 x 196f3b0e7787c2_00000000000000000000000000000000000000000000000000001& E142
+    convertToDouble +8862627962362001E27
+} 0x48d96f3b0e7787c2
+test expr-28.765 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -5068007907757162 E26 x -17456a27848397_00000000000000000000000000000000000000000000000000001& E138
+    convertToDouble -5068007907757162E26
+} 0xc897456a27848397
+test expr-28.766 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -7379714799828406 E-23 x -13cf4d2839e036_00000000000000000000000000000000000000000000000000001& E-24
+    convertToDouble -7379714799828406E-23
+} 0xbe73cf4d2839e036
+test expr-28.767 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +4114538064016107 E-27 x 12188eda98010c_0000000000000000000000000000000000000000000000000001& E-38
+    convertToDouble +4114538064016107E-27
+} 0x3d92188eda98010c
+test expr-28.768 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -3689857399914203 E-23 x -13cf4d2839e036_00000000000000000000000000000000000000000000000000001& E-25
+    convertToDouble -3689857399914203E-23
+} 0xbe63cf4d2839e036
+test expr-28.769 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +5575954851815478 E23 x 1a37cfbf2ffdb5_1111111111111111111111111111111111111111111111111110& E128
+    convertToDouble +5575954851815478E23
+} 0x47fa37cfbf2ffdb6
+test expr-28.770 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +3395700941739528 E27 x 137d88ba4b43e3_1111111111111111111111111111111111111111111111111110& E141
+    convertToDouble +3395700941739528E27
+} 0x48c37d88ba4b43e4
+test expr-28.771 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +4115535777581961 E-23 x 1618596be30fe4_111111111111111111111111111111111111111111111111111110& E-25
+    convertToDouble +4115535777581961E-23
+} 0x3e6618596be30fe5
+test expr-28.772 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -8231071555163922 E-23 x -1618596be30fe4_111111111111111111111111111111111111111111111111111110& E-24
+    convertToDouble -8231071555163922E-23
+} 0xbe7618596be30fe5
+test expr-28.773 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +6550246696190871 E-26 x 1201538b0f8c69_111111111111111111111111111111111111111111111111111110& E-34
+    convertToDouble +6550246696190871E-26
+} 0x3dd201538b0f8c6a
+test expr-28.774 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -68083046403986701 E27 x -186c70ba8ba28d_000000000000000000000000000000000000000000000000000000001& E145
+    convertToDouble -68083046403986701E27
+} 0xc9086c70ba8ba28d
+test expr-28.775 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +43566388595783643 E27 x 1f41e1bf48b03f_111111111111111111111111111111111111111111111111111111110& E144
+    convertToDouble +43566388595783643E27
+} 0x48ff41e1bf48b040
+test expr-28.776 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -87132777191567286 E27 x -1f41e1bf48b03f_111111111111111111111111111111111111111111111111111111110& E145
+    convertToDouble -87132777191567286E27
+} 0xc90f41e1bf48b040
+test expr-28.777 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +59644881059342141 E25 x 1b6338d9d8ae38_11111111111111111111111111111111111111111111111111111110& E138
+    convertToDouble +59644881059342141E25
+} 0x489b6338d9d8ae39
+test expr-28.778 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -83852770718576667 E23 x -18a4619ed6f442_111111111111111111111111111111111111111111111111111111110& E132
+    convertToDouble -83852770718576667E23
+} 0xc838a4619ed6f443
+test expr-28.779 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +99482967418206961 E-25 x 155d224bfed7ac_11111111111111111111111111111111111111111111111111111111110& E-27
+    convertToDouble +99482967418206961E-25
+} 0x3e455d224bfed7ad
+test expr-28.780 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -99482967418206961 E-26 x -11174ea3324623_11111111111111111111111111111111111111111111111111111111110& E-30
+    convertToDouble -99482967418206961E-26
+} 0xbe11174ea3324624
+test expr-28.781 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +87446669969994614 E-27 x 1809832942376d_11111111111111111111111111111111111111111111111111111110& E-34
+    convertToDouble +87446669969994614E-27
+} 0x3dd809832942376e
+test expr-28.782 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -43723334984997307 E-27 x -1809832942376d_11111111111111111111111111111111111111111111111111111110& E-35
+    convertToDouble -43723334984997307E-27
+} 0xbdc809832942376e
+test expr-28.783 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +5 E24 x 108b2a2c280290_1001& E82
+    convertToDouble +5E24
+} 0x45108b2a2c280291
+test expr-28.784 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -8 E25 x -108b2a2c280290_1001& E86
+    convertToDouble -8E25
+} 0xc5508b2a2c280291
+test expr-28.785 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +1 E25 x 108b2a2c280290_1001& E83
+    convertToDouble +1E25
+} 0x45208b2a2c280291
+test expr-28.786 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -4 E25 x -108b2a2c280290_1001& E85
+    convertToDouble -4E25
+} 0xc5408b2a2c280291
+test expr-28.787 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +2 E-5 x 14f8b588e368f0_100001& E-16
+    convertToDouble +2E-5
+} 0x3ef4f8b588e368f1
+test expr-28.788 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -5 E-6 x -14f8b588e368f0_100001& E-18
+    convertToDouble -5E-6
+} 0xbed4f8b588e368f1
+test expr-28.789 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +4 E-5 x 14f8b588e368f0_100001& E-15
+    convertToDouble +4E-5
+} 0x3f04f8b588e368f1
+test expr-28.790 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -3 E-20 x -11b578c96db19a_100001& E-65
+    convertToDouble -3E-20
+} 0xbbe1b578c96db19b
+test expr-28.791 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +3 E27 x 1363156bbee301_0110& E91
+    convertToDouble +3E27
+} 0x45a363156bbee301
+test expr-28.792 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -9 E26 x -1743b34e18439b_010& E89
+    convertToDouble -9E26
+} 0xc58743b34e18439b
+test expr-28.793 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +7 E25 x 1cf389cd46047d_00& E85
+    convertToDouble +7E25
+} 0x454cf389cd46047d
+test expr-28.794 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -6 E27 x -1363156bbee301_0110& E92
+    convertToDouble -6E27
+} 0xc5b363156bbee301
+test expr-28.795 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +2 E-21 x 12e3b40a0e9b4f_0111110& E-69
+    convertToDouble +2E-21
+} 0x3ba2e3b40a0e9b4f
+test expr-28.796 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -5 E-22 x -12e3b40a0e9b4f_0111110& E-71
+    convertToDouble -5E-22
+} 0xbb82e3b40a0e9b4f
+test expr-28.797 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -4 E-21 x -12e3b40a0e9b4f_0111110& E-68
+    convertToDouble -4E-21
+} 0xbbb2e3b40a0e9b4f
+test expr-28.798 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +87 E25 x 167d2d5406637c_10001& E89
+    convertToDouble +87E25
+} 0x45867d2d5406637d
+test expr-28.799 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -97 E24 x -140f232256e982_1000000001& E86
+    convertToDouble -97E24
+} 0xc5540f232256e983
+test expr-28.800 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +82 E-24 x 18c87154dff6c6_1000000001& E-74
+    convertToDouble +82E-24
+} 0x3b58c87154dff6c7
+test expr-28.801 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -41 E-24 x -18c87154dff6c6_1000000001& E-75
+    convertToDouble -41E-24
+} 0xbb48c87154dff6c7
+test expr-28.802 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +76 E-23 x 1cb644dc1633c0_10000001& E-71
+    convertToDouble +76E-23
+} 0x3b8cb644dc1633c1
+test expr-28.803 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +83 E25 x 15747ab143e353_011111111110& E89
+    convertToDouble +83E25
+} 0x4585747ab143e353
+test expr-28.804 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -50 E27 x -1431e0fae6d721_0111110& E95
+    convertToDouble -50E27
+} 0xc5e431e0fae6d721
+test expr-28.805 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +25 E27 x 1431e0fae6d721_0111110& E94
+    convertToDouble +25E27
+} 0x45d431e0fae6d721
+test expr-28.806 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -99 E27 x -13fe2e171cda19_011110& E96
+    convertToDouble -99E27
+} 0xc5f3fe2e171cda19
+test expr-28.807 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +97 E-10 x 14d4a1a3157dc7_011111110& E-27
+    convertToDouble +97E-10
+} 0x3e44d4a1a3157dc7
+test expr-28.808 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -57 E-20 x -15077f6f3242e7_011111110& E-61
+    convertToDouble -57E-20
+} 0xbc25077f6f3242e7
+test expr-28.809 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +997 E23 x 149e12f51c1a3c_10000000001& E86
+    convertToDouble +997E23
+} 0x45549e12f51c1a3d
+test expr-28.810 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +776 E24 x 140f232256e982_1000000001& E89
+    convertToDouble +776E24
+} 0x45840f232256e983
+test expr-28.811 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -388 E24 x -140f232256e982_1000000001& E88
+    convertToDouble -388E24
+} 0xc5740f232256e983
+test expr-28.812 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +521 E-10 x 1bf891c92c0890_100000000001& E-25
+    convertToDouble +521E-10
+} 0x3e6bf891c92c0891
+test expr-28.813 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -506 E-26 x -1877fa0260beb2_10000000001& E-78
+    convertToDouble -506E-26
+} 0xbb1877fa0260beb3
+test expr-28.814 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +739 E-10 x 13d65e8c76722c_10000000001& E-24
+    convertToDouble +739E-10
+} 0x3e73d65e8c76722d
+test expr-28.815 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -867 E-7 x -16ba56a8834168_100000000001& E-14
+    convertToDouble -867E-7
+} 0xbf16ba56a8834169
+test expr-28.816 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -415 E24 x -15747ab143e353_011111111110& E88
+    convertToDouble -415E24
+} 0xc575747ab143e353
+test expr-28.817 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +332 E25 x 15747ab143e353_011111111110& E91
+    convertToDouble +332E25
+} 0x45a5747ab143e353
+test expr-28.818 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -664 E25 x -15747ab143e353_011111111110& E92
+    convertToDouble -664E25
+} 0xc5b5747ab143e353
+test expr-28.819 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +291 E-13 x 1ffeebfc8b81b5_01111111111110& E-36
+    convertToDouble +291E-13
+} 0x3dbffeebfc8b81b5
+test expr-28.820 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -982 E-8 x -14981285e98e79_0111111111110& E-17
+    convertToDouble -982E-8
+} 0xbee4981285e98e79
+test expr-28.821 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +582 E-13 x 1ffeebfc8b81b5_01111111111110& E-35
+    convertToDouble +582E-13
+} 0x3dcffeebfc8b81b5
+test expr-28.822 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -491 E-8 x -14981285e98e79_0111111111110& E-18
+    convertToDouble -491E-8
+} 0xbed4981285e98e79
+test expr-28.823 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +4574 E26 x 1717c1a612f954_100000000001& E98
+    convertToDouble +4574E26
+} 0x461717c1a612f955
+test expr-28.824 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -8609 E26 x -15bb6f942546ee_1000000000001& E99
+    convertToDouble -8609E26
+} 0xc625bb6f942546ef
+test expr-28.825 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +2287 E26 x 1717c1a612f954_100000000001& E97
+    convertToDouble +2287E26
+} 0x460717c1a612f955
+test expr-28.826 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -4818 E24 x -1f22b65eb419a0_10000000001& E91
+    convertToDouble -4818E24
+} 0xc5af22b65eb419a1
+test expr-28.827 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +6529 E-8 x 111d89a8b5c142_100000000000001& E-14
+    convertToDouble +6529E-8
+} 0x3f111d89a8b5c143
+test expr-28.828 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -8151 E-21 x -12cb804b61b898_1000000000000001& E-57
+    convertToDouble -8151E-21
+} 0xbc62cb804b61b899
+test expr-28.829 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +1557 E-12 x 1abfc227ab1026_10000000000001& E-30
+    convertToDouble +1557E-12
+} 0x3e1abfc227ab1027
+test expr-28.830 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -2573 E-18 x -172cef1ebbca44_10000000000001& E-49
+    convertToDouble -2573E-18
+} 0xbce72cef1ebbca45
+test expr-28.831 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +4929 E-16 x 1157a604ed019f_0111111111111110& E-41
+    convertToDouble +4929E-16
+} 0x3d6157a604ed019f
+test expr-28.832 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -3053 E-22 x -1686f435fe6b6b_011111111111110& E-62
+    convertToDouble -3053E-22
+} 0xbc1686f435fe6b6b
+test expr-28.833 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +9858 E-16 x 1157a604ed019f_0111111111111110& E-40
+    convertToDouble +9858E-16
+} 0x3d7157a604ed019f
+test expr-28.834 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -7767 E-11 x -14d971170ed055_011111111111110& E-24
+    convertToDouble -7767E-11
+} 0xbe74d971170ed055
+test expr-28.835 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +54339 E26 x 1125782ec15cbe_100000000000000001& E102
+    convertToDouble +54339E26
+} 0x465125782ec15cbf
+test expr-28.836 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -62409 E25 x -1f822c980d4bb2_100000000000000001& E98
+    convertToDouble -62409E25
+} 0xc61f822c980d4bb3
+test expr-28.837 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +32819 E27 x 19e3be885fc16a_100000000000001& E104
+    convertToDouble +32819E27
+} 0x4679e3be885fc16b
+test expr-28.838 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -89849 E27 x -11b8371b6dda04_1000000000000001& E106
+    convertToDouble -89849E27
+} 0xc691b8371b6dda05
+test expr-28.839 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +63876 E-20 x 1703856844bdbe_1000000000000000000001& E-51
+    convertToDouble +63876E-20
+} 0x3cc703856844bdbf
+test expr-28.840 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -15969 E-20 x -1703856844bdbe_1000000000000000000001& E-53
+    convertToDouble -15969E-20
+} 0xbca703856844bdbf
+test expr-28.841 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +31938 E-20 x 1703856844bdbe_1000000000000000000001& E-52
+    convertToDouble +31938E-20
+} 0x3cb703856844bdbf
+test expr-28.842 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -79845 E-21 x -1703856844bdbe_1000000000000000000001& E-54
+    convertToDouble -79845E-21
+} 0xbc9703856844bdbf
+test expr-28.843 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +89306 E27 x 119cccff237e17_011111111111110& E106
+    convertToDouble +89306E27
+} 0x46919cccff237e17
+test expr-28.844 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -25487 E24 x -1496968ba07117_01111111111110& E94
+    convertToDouble -25487E24
+} 0xc5d496968ba07117
+test expr-28.845 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +79889 E24 x 10222a1c7e27d3_01111111111110& E96
+    convertToDouble +79889E24
+} 0x45f0222a1c7e27d3
+test expr-28.846 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -97379 E26 x -1eba3685911519_011111111111111110& E102
+    convertToDouble -97379E26
+} 0xc65eba3685911519
+test expr-28.847 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +81002 E-8 x 1a8af0b45d9531_0111111111111111110& E-11
+    convertToDouble +81002E-8
+} 0x3f4a8af0b45d9531
+test expr-28.848 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -43149 E-25 x -146064de6ecbed_011111111111111110& E-68
+    convertToDouble -43149E-25
+} 0xbbb46064de6ecbed
+test expr-28.849 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +40501 E-8 x 1a8af0b45d9531_0111111111111111110& E-12
+    convertToDouble +40501E-8
+} 0x3f3a8af0b45d9531
+test expr-28.850 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -60318 E-10 x -194c988f217e51_011111111111111110& E-18
+    convertToDouble -60318E-10
+} 0xbed94c988f217e51
+test expr-28.851 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -648299 E27 x -1ff6af0bf00100_10000000000000000001& E108
+    convertToDouble -648299E27
+} 0xc6bff6af0bf00101
+test expr-28.852 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +780649 E24 x 13b4d36f9edd18_10000000000000000001& E99
+    convertToDouble +780649E24
+} 0x4623b4d36f9edd19
+test expr-28.853 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +720919 E-14 x 1ef696965cbf04_10000000000000000000000001& E-28
+    convertToDouble +720919E-14
+} 0x3e3ef696965cbf05
+test expr-28.854 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -629703 E-11 x -1a69626d2629d0_1000000000000000000000001& E-18
+    convertToDouble -629703E-11
+} 0xbeda69626d2629d1
+test expr-28.855 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +557913 E24 x 1c2adb44b394bf_01111111111111111110& E98
+    convertToDouble +557913E24
+} 0x461c2adb44b394bf
+test expr-28.856 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -847899 E23 x -111f88fb93dce9_011111111111111111110& E96
+    convertToDouble -847899E23
+} 0xc5f11f88fb93dce9
+test expr-28.857 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +565445 E27 x 1be0eb55770d4d_0111111111111111110& E108
+    convertToDouble +565445E27
+} 0x46bbe0eb55770d4d
+test expr-28.858 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -736531 E24 x -1297b853d64ac7_01111111111111111110& E99
+    convertToDouble -736531E24
+} 0xc62297b853d64ac7
+test expr-28.859 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +680013 E-19 x 13240293e95c3b_01111111111111111111110& E-44
+    convertToDouble +680013E-19
+} 0x3d33240293e95c3b
+test expr-28.860 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -529981 E-10 x -1bc948d999ac11_011111111111111111110& E-15
+    convertToDouble -529981E-10
+} 0xbf0bc948d999ac11
+test expr-28.861 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +382923 E-23 x 11a8c1c10a1fc5_011111111111111111110& E-58
+    convertToDouble +382923E-23
+} 0x3c51a8c1c10a1fc5
+test expr-28.862 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -633614 E-18 x -164b166995a9b7_011111111111111111110& E-41
+    convertToDouble -633614E-18
+} 0xbd664b166995a9b7
+test expr-28.863 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +2165479 E27 x 1ab10c016c34b8_100000000000000000000001& E110
+    convertToDouble +2165479E27
+} 0x46dab10c016c34b9
+test expr-28.864 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -8661916 E27 x -1ab10c016c34b8_100000000000000000000001& E112
+    convertToDouble -8661916E27
+} 0xc6fab10c016c34b9
+test expr-28.865 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +4330958 E27 x 1ab10c016c34b8_100000000000000000000001& E111
+    convertToDouble +4330958E27
+} 0x46eab10c016c34b9
+test expr-28.866 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -9391993 E22 x -12f78bec748c98_1000000000000000000001& E96
+    convertToDouble -9391993E22
+} 0xc5f2f78bec748c99
+test expr-28.867 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -5767352 E-14 x -1ef696965cbf04_10000000000000000000000001& E-25
+    convertToDouble -5767352E-14
+} 0xbe6ef696965cbf05
+test expr-28.868 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +7209190 E-15 x 1ef696965cbf04_10000000000000000000000001& E-28
+    convertToDouble +7209190E-15
+} 0x3e3ef696965cbf05
+test expr-28.869 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -1441838 E-14 x -1ef696965cbf04_10000000000000000000000001& E-27
+    convertToDouble -1441838E-14
+} 0xbe4ef696965cbf05
+test expr-28.870 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +8478990 E22 x 111f88fb93dce9_011111111111111111110& E96
+    convertToDouble +8478990E22
+} 0x45f11f88fb93dce9
+test expr-28.871 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +1473062 E24 x 1297b853d64ac7_01111111111111111110& E100
+    convertToDouble +1473062E24
+} 0x463297b853d64ac7
+test expr-28.872 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +8366487 E-14 x 167567f55b22e1_0111111111111111111111110& E-24
+    convertToDouble +8366487E-14
+} 0x3e767567f55b22e1
+test expr-28.873 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -8399969 E-25 x -1efd8be1b15b43_011111111111111111111110& E-61
+    convertToDouble -8399969E-25
+} 0xbc2efd8be1b15b43
+test expr-28.874 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +9366737 E-12 x 13a4ba87ddc13f_011111111111111111111110& E-17
+    convertToDouble +9366737E-12
+} 0x3ee3a4ba87ddc13f
+test expr-28.875 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -9406141 E-13 x -1f8fd047c84d49_0111111111111111111111110& E-21
+    convertToDouble -9406141E-13
+} 0xbeaf8fd047c84d49
+test expr-28.876 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +65970979 E24 x 1a055dd68f3e3c_1000000000000000000000000001& E105
+    convertToDouble +65970979E24
+} 0x468a055dd68f3e3d
+test expr-28.877 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -65060671 E26 x -140c61c9916cf4_100000000000000000000000001& E112
+    convertToDouble -65060671E26
+} 0xc6f40c61c9916cf5
+test expr-28.878 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +54923002 E27 x 1527d37d8b38ea_10000000000000000000000001& E115
+    convertToDouble +54923002E27
+} 0x472527d37d8b38eb
+test expr-28.879 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -63846927 E25 x -1f7a9d79dad9b4_10000000000000000000000001& E108
+    convertToDouble -63846927E25
+} 0xc6bf7a9d79dad9b5
+test expr-28.880 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +99585767 E-21 x 1c07e928406d2e_100000000000000000000000001& E-44
+    convertToDouble +99585767E-21
+} 0x3d3c07e928406d2f
+test expr-28.881 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +67488159 E25 x 10a31a03822bc9_011111111111111111111111111110& E109
+    convertToDouble +67488159E25
+} 0x46c0a31a03822bc9
+test expr-28.882 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -69005339 E24 x -1b37c234aae77b_011111111111111111111111110& E105
+    convertToDouble -69005339E24
+} 0xc68b37c234aae77b
+test expr-28.883 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +81956786 E27 x 1f919023fcb6fd_0111111111111111111111111110& E115
+    convertToDouble +81956786E27
+} 0x472f919023fcb6fd
+test expr-28.884 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -40978393 E27 x -1f919023fcb6fd_0111111111111111111111111110& E114
+    convertToDouble -40978393E27
+} 0xc71f919023fcb6fd
+test expr-28.885 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +77505754 E-12 x 145152b6f85e09_0111111111111111111111111110& E-14
+    convertToDouble +77505754E-12
+} 0x3f145152b6f85e09
+test expr-28.886 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -38752877 E-12 x -145152b6f85e09_0111111111111111111111111110& E-15
+    convertToDouble -38752877E-12
+} 0xbf045152b6f85e09
+test expr-28.887 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +82772981 E-15 x 16381dae63505f_0111111111111111111111111111110& E-24
+    convertToDouble +82772981E-15
+} 0x3e76381dae63505f
+test expr-28.888 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -95593517 E-25 x -160ad862d8537d_0111111111111111111111111110& E-57
+    convertToDouble -95593517E-25
+} 0xbc660ad862d8537d
+test expr-28.889 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +200036989 E25 x 18a80dedbc575e_10000000000000000000000000001& E110
+    convertToDouble +200036989E25
+} 0x46d8a80dedbc575f
+test expr-28.890 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -772686455 E27 x -129a0c45ceca7a_1000000000000000000000000000001& E119
+    convertToDouble -772686455E27
+} 0xc7629a0c45ceca7b
+test expr-28.891 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +859139907 E23 x 10f18c4dd0ffe2_10000000000000000000000000001& E106
+    convertToDouble +859139907E23
+} 0x4690f18c4dd0ffe3
+test expr-28.892 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -400073978 E25 x -18a80dedbc575e_10000000000000000000000000001& E111
+    convertToDouble -400073978E25
+} 0xc6e8a80dedbc575f
+test expr-28.893 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +569014327 E-14 x 17ddbeac19d3b2_100000000000000000000000000001& E-18
+    convertToDouble +569014327E-14
+} 0x3ed7ddbeac19d3b3
+test expr-28.894 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -794263862 E-15 x -1aa6acb41dfc52_1000000000000000000000000000001& E-21
+    convertToDouble -794263862E-15
+} 0xbeaaa6acb41dfc53
+test expr-28.895 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +397131931 E-15 x 1aa6acb41dfc52_1000000000000000000000000000001& E-22
+    convertToDouble +397131931E-15
+} 0x3e9aa6acb41dfc53
+test expr-28.896 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -380398957 E-16 x -146c29d8331024_100000000000000000000000000001& E-25
+    convertToDouble -380398957E-16
+} 0xbe646c29d8331025
+test expr-28.897 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +567366773 E27 x 1b5155dd5417f9_0111111111111111111111111111110& E118
+    convertToDouble +567366773E27
+} 0x475b5155dd5417f9
+test expr-28.898 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -337440795 E24 x -10a31a03822bc9_011111111111111111111111111110& E108
+    convertToDouble -337440795E24
+} 0xc6b0a31a03822bc9
+test expr-28.899 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +134976318 E25 x 10a31a03822bc9_011111111111111111111111111110& E110
+    convertToDouble +134976318E25
+} 0x46d0a31a03822bc9
+test expr-28.900 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -269952636 E25 x -10a31a03822bc9_011111111111111111111111111110& E111
+    convertToDouble -269952636E25
+} 0xc6e0a31a03822bc9
+test expr-28.901 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +932080597 E-20 x 147f25b4941e5b_0111111111111111111111111111110& E-37
+    convertToDouble +932080597E-20
+} 0x3da47f25b4941e5b
+test expr-28.902 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -331091924 E-15 x -16381dae63505f_0111111111111111111111111111110& E-22
+    convertToDouble -331091924E-15
+} 0xbe96381dae63505f
+test expr-28.903 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -413864905 E-16 x -16381dae63505f_0111111111111111111111111111110& E-25
+    convertToDouble -413864905E-16
+} 0xbe66381dae63505f
+test expr-28.904 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +8539246247 E26 x 148eb7813eaeba_10000000000000000000000000000001& E119
+    convertToDouble +8539246247E26
+} 0x47648eb7813eaebb
+test expr-28.905 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -5859139791 E26 x -1c35f28719d478_10000000000000000000000000000001& E118
+    convertToDouble -5859139791E26
+} 0xc75c35f28719d479
+test expr-28.906 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +6105010149 E24 x 12d000fb2b138a_1000000000000000000000000000000001& E112
+    convertToDouble +6105010149E24
+} 0x46f2d000fb2b138b
+test expr-28.907 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -3090745820 E27 x -129a0c45ceca7a_1000000000000000000000000000001& E121
+    convertToDouble -3090745820E27
+} 0xc7829a0c45ceca7b
+test expr-28.908 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +3470877773 E-20 x 1314d381f2c31e_1000000000000000000000000000000001& E-35
+    convertToDouble +3470877773E-20
+} 0x3dc314d381f2c31f
+test expr-28.909 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -6136309089 E-27 x -1c4c799fab4328_1000000000000000000000000000000001& E-58
+    convertToDouble -6136309089E-27
+} 0xbc5c4c799fab4329
+test expr-28.910 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +8917758713 E-19 x 1ea424bda7d7f4_100000000000000000000000000000001& E-31
+    convertToDouble +8917758713E-19
+} 0x3e0ea424bda7d7f5
+test expr-28.911 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -6941755546 E-20 x -1314d381f2c31e_1000000000000000000000000000000001& E-34
+    convertToDouble -6941755546E-20
+} 0xbdd314d381f2c31f
+test expr-28.912 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +9194900535 E25 x 11b56f9c090dfb_011111111111111111111111111111111110& E116
+    convertToDouble +9194900535E25
+} 0x4731b56f9c090dfb
+test expr-28.913 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -1838980107 E26 x -11b56f9c090dfb_011111111111111111111111111111111110& E117
+    convertToDouble -1838980107E26
+} 0xc741b56f9c090dfb
+test expr-28.914 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +7355920428 E26 x 11b56f9c090dfb_011111111111111111111111111111111110& E119
+    convertToDouble +7355920428E26
+} 0x4761b56f9c090dfb
+test expr-28.915 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -3677960214 E26 x -11b56f9c090dfb_011111111111111111111111111111111110& E118
+    convertToDouble -3677960214E26
+} 0xc751b56f9c090dfb
+test expr-28.916 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +8473634343 E-17 x 16bf0984b232b7_0111111111111111111111111111111110& E-24
+    convertToDouble +8473634343E-17
+} 0x3e76bf0984b232b7
+test expr-28.917 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -8870766274 E-16 x -1dc3ee22137269_0111111111111111111111111111111110& E-21
+    convertToDouble -8870766274E-16
+} 0xbeadc3ee22137269
+test expr-28.918 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +4435383137 E-16 x 1dc3ee22137269_0111111111111111111111111111111110& E-22
+    convertToDouble +4435383137E-16
+} 0x3e9dc3ee22137269
+test expr-28.919 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -9598990129 E-15 x -14216b286031e7_01111111111111111111111111111111110& E-17
+    convertToDouble -9598990129E-15
+} 0xbee4216b286031e7
+test expr-28.920 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +71563496764 E26 x 15890d1ef6a0da_10000000000000000000000000000000000001& E122
+    convertToDouble +71563496764E26
+} 0x4795890d1ef6a0db
+test expr-28.921 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -89454370955 E25 x -15890d1ef6a0da_10000000000000000000000000000000000001& E119
+    convertToDouble -89454370955E25
+} 0xc765890d1ef6a0db
+test expr-28.922 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +17890874191 E26 x 15890d1ef6a0da_10000000000000000000000000000000000001& E120
+    convertToDouble +17890874191E26
+} 0x4775890d1ef6a0db
+test expr-28.923 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -35781748382 E26 x -15890d1ef6a0da_10000000000000000000000000000000000001& E121
+    convertToDouble -35781748382E26
+} 0xc785890d1ef6a0db
+test expr-28.924 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +57973447842 E-19 x 18e63f7cf5313c_1000000000000000000000000000000000000001& E-28
+    convertToDouble +57973447842E-19
+} 0x3e38e63f7cf5313d
+test expr-28.925 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -28986723921 E-19 x -18e63f7cf5313c_1000000000000000000000000000000000000001& E-29
+    convertToDouble -28986723921E-19
+} 0xbe28e63f7cf5313d
+test expr-28.926 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +76822711313 E-19 x 107f5f8b3bf818_100000000000000000000000000000000001& E-27
+    convertToDouble +76822711313E-19
+} 0x3e407f5f8b3bf819
+test expr-28.927 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -97699466874 E-20 x -10c8de34de806e_10000000000000000000000000000000001& E-30
+    convertToDouble -97699466874E-20
+} 0xbe10c8de34de806f
+test expr-28.928 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +67748656762 E27 x 197bf5559b31fd_01111111111111111111111111111111111110& E125
+    convertToDouble +67748656762E27
+} 0x47c97bf5559b31fd
+test expr-28.929 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -19394840991 E24 x -1de1ea791a6e7d_0111111111111111111111111111111111110& E113
+    convertToDouble -19394840991E24
+} 0xc70de1ea791a6e7d
+test expr-28.930 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +38789681982 E24 x 1de1ea791a6e7d_0111111111111111111111111111111111110& E114
+    convertToDouble +38789681982E24
+} 0x471de1ea791a6e7d
+test expr-28.931 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -33874328381 E27 x -197bf5559b31fd_01111111111111111111111111111111111110& E124
+    convertToDouble -33874328381E27
+} 0xc7b97bf5559b31fd
+test expr-28.932 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +54323763886 E-27 x 1f50c5c63e5441_0111111111111111111111111111111111110& E-55
+    convertToDouble +54323763886E-27
+} 0x3c8f50c5c63e5441
+test expr-28.933 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -58987193887 E-20 x -14449185a4c829_011111111111111111111111111111111111110& E-31
+    convertToDouble -58987193887E-20
+} 0xbe04449185a4c829
+test expr-28.934 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +27161881943 E-27 x 1f50c5c63e5441_0111111111111111111111111111111111110& E-56
+    convertToDouble +27161881943E-27
+} 0x3c7f50c5c63e5441
+test expr-28.935 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -93042648033 E-19 x -13fb12dc023fd3_0111111111111111111111111111111111110& E-27
+    convertToDouble -93042648033E-19
+} 0xbe43fb12dc023fd3
+test expr-28.936 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +520831059055 E27 x 187d469cb69dd0_10000000000000000000000000000000000000001& E128
+    convertToDouble +520831059055E27
+} 0x47f87d469cb69dd1
+test expr-28.937 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -768124264394 E25 x -171d6a019edae8_1000000000000000000000000000000000000001& E122
+    convertToDouble -768124264394E25
+} 0xc7971d6a019edae9
+test expr-28.938 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +384062132197 E25 x 171d6a019edae8_1000000000000000000000000000000000000001& E121
+    convertToDouble +384062132197E25
+} 0x47871d6a019edae9
+test expr-28.939 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +765337749889 E-25 x 158ad6f5d0a854_100000000000000000000000000000000000000001& E-44
+    convertToDouble +765337749889E-25
+} 0x3d358ad6f5d0a855
+test expr-28.940 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +794368912771 E25 x 17e79872f2f7ef_01111111111111111111111111111111111111110& E122
+    convertToDouble +794368912771E25
+} 0x4797e79872f2f7ef
+test expr-28.941 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -994162090146 E23 x -132598f85e658b_011111111111111111111111111111111111110& E116
+    convertToDouble -994162090146E23
+} 0xc7332598f85e658b
+test expr-28.942 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +781652779431 E26 x 1d670adf52038f_01111111111111111111111111111111111110& E125
+    convertToDouble +781652779431E26
+} 0x47cd670adf52038f
+test expr-28.943 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +910077190046 E-26 x 147e3ce1871d79_01111111111111111111111111111111111111110& E-47
+    convertToDouble +910077190046E-26
+} 0x3d047e3ce1871d79
+test expr-28.944 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -455038595023 E-26 x -147e3ce1871d79_01111111111111111111111111111111111111110& E-48
+    convertToDouble -455038595023E-26
+} 0xbcf47e3ce1871d79
+test expr-28.945 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +471897551096 E-20 x 14449185a4c829_011111111111111111111111111111111111110& E-28
+    convertToDouble +471897551096E-20
+} 0x3e34449185a4c829
+test expr-28.946 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -906698409911 E-21 x -1f27674f7d5745_0111111111111111111111111111111111111110& E-31
+    convertToDouble -906698409911E-21
+} 0xbe0f27674f7d5745
+test expr-28.947 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +8854128003935 E25 x 10a71b8948faac_100000000000000000000000000000000000000001& E126
+    convertToDouble +8854128003935E25
+} 0x47d0a71b8948faad
+test expr-28.948 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -8146122716299 E27 x -17f0762ac05654_1000000000000000000000000000000000000000001& E132
+    convertToDouble -8146122716299E27
+} 0xc837f0762ac05655
+test expr-28.949 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +7083302403148 E26 x 10a71b8948faac_100000000000000000000000000000000000000001& E129
+    convertToDouble +7083302403148E26
+} 0x4800a71b8948faad
+test expr-28.950 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -3541651201574 E26 x -10a71b8948faac_100000000000000000000000000000000000000001& E128
+    convertToDouble -3541651201574E26
+} 0xc7f0a71b8948faad
+test expr-28.951 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +8394920649291 E-25 x 1d8978e8c1cc78_100000000000000000000000000000000000000000001& E-41
+    convertToDouble +8394920649291E-25
+} 0x3d6d8978e8c1cc79
+test expr-28.952 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -7657975756753 E-22 x -1a5006d695fef0_1000000000000000000000000000000000000000000001& E-31
+    convertToDouble -7657975756753E-22
+} 0xbe0a5006d695fef1
+test expr-28.953 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +5473834002228 E-20 x 1d632e1f745624_100000000000000000000000000000000000000000001& E-25
+    convertToDouble +5473834002228E-20
+} 0x3e6d632e1f745625
+test expr-28.954 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -6842292502785 E-21 x -1d632e1f745624_100000000000000000000000000000000000000000001& E-28
+    convertToDouble -6842292502785E-21
+} 0xbe3d632e1f745625
+test expr-28.955 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -2109568884597 E25 x -1fbdc386609b13_011111111111111111111111111111111111111110& E123
+    convertToDouble -2109568884597E25
+} 0xc7afbdc386609b13
+test expr-28.956 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +8438275538388 E25 x 1fbdc386609b13_011111111111111111111111111111111111111110& E125
+    convertToDouble +8438275538388E25
+} 0x47cfbdc386609b13
+test expr-28.957 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -4219137769194 E25 x -1fbdc386609b13_011111111111111111111111111111111111111110& E124
+    convertToDouble -4219137769194E25
+} 0xc7bfbdc386609b13
+test expr-28.958 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +3200141789841 E-25 x 1684dcea3829f7_0111111111111111111111111111111111111111110& E-42
+    convertToDouble +3200141789841E-25
+} 0x3d5684dcea3829f7
+test expr-28.959 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -8655689322607 E-22 x -1dbd9ff5dc8991_011111111111111111111111111111111111111110& E-31
+    convertToDouble -8655689322607E-22
+} 0xbe0dbd9ff5dc8991
+test expr-28.960 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +6400283579682 E-25 x 1684dcea3829f7_0111111111111111111111111111111111111111110& E-41
+    convertToDouble +6400283579682E-25
+} 0x3d6684dcea3829f7
+test expr-28.961 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -8837719634493 E-21 x -12fa9676d2585b_011111111111111111111111111111111111111110& E-27
+    convertToDouble -8837719634493E-21
+} 0xbe42fa9676d2585b
+test expr-28.962 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +19428217075297 E24 x 1d3b7a1d154aba_10000000000000000000000000000000000000000000001& E123
+    convertToDouble +19428217075297E24
+} 0x47ad3b7a1d154abb
+test expr-28.963 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -38856434150594 E24 x -1d3b7a1d154aba_10000000000000000000000000000000000000000000001& E124
+    convertToDouble -38856434150594E24
+} 0xc7bd3b7a1d154abb
+test expr-28.964 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +77712868301188 E24 x 1d3b7a1d154aba_10000000000000000000000000000000000000000000001& E125
+    convertToDouble +77712868301188E24
+} 0x47cd3b7a1d154abb
+test expr-28.965 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -77192037242133 E27 x -1c5b1ab32d5dbe_1000000000000000000000000000000000000000000000001& E135
+    convertToDouble -77192037242133E27
+} 0xc86c5b1ab32d5dbf
+test expr-28.966 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +76579757567530 E-23 x 1a5006d695fef0_1000000000000000000000000000000000000000000001& E-31
+    convertToDouble +76579757567530E-23
+} 0x3e0a5006d695fef1
+test expr-28.967 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +15315951513506 E-22 x 1a5006d695fef0_1000000000000000000000000000000000000000000001& E-30
+    convertToDouble +15315951513506E-22
+} 0x3e1a5006d695fef1
+test expr-28.968 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -38289878783765 E-23 x -1a5006d695fef0_1000000000000000000000000000000000000000000001& E-32
+    convertToDouble -38289878783765E-23
+} 0xbdfa5006d695fef1
+test expr-28.969 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +49378033925202 E25 x 1737aa2567167b_0111111111111111111111111111111111111111111110& E128
+    convertToDouble +49378033925202E25
+} 0x47f737aa2567167b
+test expr-28.970 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -50940527102367 E24 x -132964f2944b05_0111111111111111111111111111111111111111111111110& E125
+    convertToDouble -50940527102367E24
+} 0xc7c32964f2944b05
+test expr-28.971 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +98756067850404 E25 x 1737aa2567167b_0111111111111111111111111111111111111111111110& E129
+    convertToDouble +98756067850404E25
+} 0x480737aa2567167b
+test expr-28.972 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -99589397544892 E26 x -1d4446075c4933_0111111111111111111111111111111111111111111110& E132
+    convertToDouble -99589397544892E26
+} 0xc83d4446075c4933
+test expr-28.973 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -56908598265713 E-25 x -190756ab1ed6b3_011111111111111111111111111111111111111111111110& E-38
+    convertToDouble -56908598265713E-25
+} 0xbd990756ab1ed6b3
+test expr-28.974 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +97470695699657 E-22 x 14ee821710e655_01111111111111111111111111111111111111111111110& E-27
+    convertToDouble +97470695699657E-22
+} 0x3e44ee821710e655
+test expr-28.975 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -35851901247343 E-25 x -1f8921657e1581_0111111111111111111111111111111111111111111110& E-39
+    convertToDouble -35851901247343E-25
+} 0xbd8f8921657e1581
+test expr-28.976 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +154384074484266 E27 x 1c5b1ab32d5dbe_1000000000000000000000000000000000000000000000001& E136
+    convertToDouble +154384074484266E27
+} 0x487c5b1ab32d5dbf
+test expr-28.977 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -308768148968532 E27 x -1c5b1ab32d5dbe_1000000000000000000000000000000000000000000000001& E137
+    convertToDouble -308768148968532E27
+} 0xc88c5b1ab32d5dbf
+test expr-28.978 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +910990389005985 E23 x 112242592ae54a_100000000000000000000000000000000000000000000001& E126
+    convertToDouble +910990389005985E23
+} 0x47d12242592ae54b
+test expr-28.979 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +271742424169201 E-27 x 131f46bcf7b452_10000000000000000000000000000000000000000000000001& E-42
+    convertToDouble +271742424169201E-27
+} 0x3d531f46bcf7b453
+test expr-28.980 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -543484848338402 E-27 x -131f46bcf7b452_10000000000000000000000000000000000000000000000001& E-41
+    convertToDouble -543484848338402E-27
+} 0xbd631f46bcf7b453
+test expr-28.981 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +162192083357563 E-26 x 1c887b68658760_1000000000000000000000000000000000000000000000001& E-40
+    convertToDouble +162192083357563E-26
+} 0x3d7c887b68658761
+test expr-28.982 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -869254552770081 E-23 x -12aac70665485e_1000000000000000000000000000000000000000000000000001& E-27
+    convertToDouble -869254552770081E-23
+} 0xbe42aac70665485f
+test expr-28.983 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +664831007626046 E24 x 1f429cb67eb075_011111111111111111111111111111111111111111111111110& E128
+    convertToDouble +664831007626046E24
+} 0x47ff429cb67eb075
+test expr-28.984 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -332415503813023 E24 x -1f429cb67eb075_011111111111111111111111111111111111111111111111110& E127
+    convertToDouble -332415503813023E24
+} 0xc7ef429cb67eb075
+test expr-28.985 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +943701829041427 E24 x 162fb2e38ee461_01111111111111111111111111111111111111111111111110& E129
+    convertToDouble +943701829041427E24
+} 0x48062fb2e38ee461
+test expr-28.986 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -101881054204734 E24 x -132964f2944b05_0111111111111111111111111111111111111111111111110& E126
+    convertToDouble -101881054204734E24
+} 0xc7d32964f2944b05
+test expr-28.987 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +828027839666967 E-27 x 1d2236349da3cd_011111111111111111111111111111111111111111111111110& E-41
+    convertToDouble +828027839666967E-27
+} 0x3d6d2236349da3cd
+test expr-28.988 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -280276135608777 E-27 x -13b901892fd0bf_0111111111111111111111111111111111111111111111110& E-42
+    convertToDouble -280276135608777E-27
+} 0xbd53b901892fd0bf
+test expr-28.989 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +212839188833879 E-21 x 1c91194dc2d40b_0111111111111111111111111111111111111111111111110& E-23
+    convertToDouble +212839188833879E-21
+} 0x3e8c91194dc2d40b
+test expr-28.990 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -113817196531426 E-25 x -190756ab1ed6b3_011111111111111111111111111111111111111111111110& E-37
+    convertToDouble -113817196531426E-25
+} 0xbda90756ab1ed6b3
+test expr-28.991 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +9711553197796883 E27 x 1bdeec25c0f03e_10000000000000000000000000000000000000000000000000001& E142
+    convertToDouble +9711553197796883E27
+} 0x48dbdeec25c0f03f
+test expr-28.992 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -2739849386524269 E26 x -19295ade212370_1000000000000000000000000000000000000000000000000001& E137
+    convertToDouble -2739849386524269E26
+} 0xc889295ade212371
+test expr-28.993 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +5479698773048538 E26 x 19295ade212370_1000000000000000000000000000000000000000000000000001& E138
+    convertToDouble +5479698773048538E26
+} 0x4899295ade212371
+test expr-28.994 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +6124568318523113 E-25 x 150b3a2e0aff14_1000000000000000000000000000000000000000000000000000001& E-31
+    convertToDouble +6124568318523113E-25
+} 0x3e050b3a2e0aff15
+test expr-28.995 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -1139777988171071 E-24 x -1394cbee428ea4_10000000000000000000000000000000000000000000000000001& E-30
+    convertToDouble -1139777988171071E-24
+} 0xbe1394cbee428ea5
+test expr-28.996 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +6322612303128019 E-27 x 1bcea0ec21e250_1000000000000000000000000000000000000000000000000000001& E-38
+    convertToDouble +6322612303128019E-27
+} 0x3d9bcea0ec21e251
+test expr-28.997 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -2955864564844617 E-25 x -1450030e26c6dc_10000000000000000000000000000000000000000000000000001& E-32
+    convertToDouble -2955864564844617E-25
+} 0xbdf450030e26c6dd
+test expr-28.998 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -9994029144998961 E25 x -125b2b7fed4a61_0111111111111111111111111111111111111111111111111110& E136
+    convertToDouble -9994029144998961E25
+} 0xc8725b2b7fed4a61
+test expr-28.999 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -2971238324022087 E27 x -110dd7a301db67_0111111111111111111111111111111111111111111111111110& E141
+    convertToDouble -2971238324022087E27
+} 0xc8c10dd7a301db67
+test expr-28.1000 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -1656055679333934 E-27 x -1d2236349da3cd_011111111111111111111111111111111111111111111111110& E-40
+    convertToDouble -1656055679333934E-27
+} 0xbd7d2236349da3cd
+test expr-28.1001 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -1445488709150234 E-26 x -1fc960c59526c7_0111111111111111111111111111111111111111111111110& E-37
+    convertToDouble -1445488709150234E-26
+} 0xbdafc960c59526c7
+test expr-28.1002 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +55824717499885172 E27 x 1406b0cd17fd56_1000000000000000000000000000000000000000000000000000000001& E145
+    convertToDouble +55824717499885172E27
+} 0x490406b0cd17fd57
+test expr-28.1003 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -69780896874856465 E26 x -1406b0cd17fd56_1000000000000000000000000000000000000000000000000000000001& E142
+    convertToDouble -69780896874856465E26
+} 0xc8d406b0cd17fd57
+test expr-28.1004 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +84161538867545199 E25 x 13529217bdce6c_10000000000000000000000000000000000000000000000000000000001& E139
+    convertToDouble +84161538867545199E25
+} 0x48a3529217bdce6d
+test expr-28.1005 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -27912358749942586 E27 x -1406b0cd17fd56_1000000000000000000000000000000000000000000000000000000001& E144
+    convertToDouble -27912358749942586E27
+} 0xc8f406b0cd17fd57
+test expr-28.1006 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +24711112462926331 E-25 x 153a07f6040d22_100000000000000000000000000000000000000000000000000000001& E-29
+    convertToDouble +24711112462926331E-25
+} 0x3e253a07f6040d23
+test expr-28.1007 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -12645224606256038 E-27 x -1bcea0ec21e250_1000000000000000000000000000000000000000000000000000001& E-37
+    convertToDouble -12645224606256038E-27
+} 0xbdabcea0ec21e251
+test expr-28.1008 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -12249136637046226 E-25 x -150b3a2e0aff14_1000000000000000000000000000000000000000000000000000001& E-30
+    convertToDouble -12249136637046226E-25
+} 0xbe150b3a2e0aff15
+test expr-28.1009 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +74874448287465757 E27 x 1adc21d1d50b09_01111111111111111111111111111111111111111111111111111110& E145
+    convertToDouble +74874448287465757E27
+} 0x490adc21d1d50b09
+test expr-28.1010 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -35642836832753303 E24 x -1a2fac2b421f53_0111111111111111111111111111111111111111111111111111110& E134
+    convertToDouble -35642836832753303E24
+} 0xc85a2fac2b421f53
+test expr-28.1011 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -71285673665506606 E24 x -1a2fac2b421f53_0111111111111111111111111111111111111111111111111111110& E135
+    convertToDouble -71285673665506606E24
+} 0xc86a2fac2b421f53
+test expr-28.1012 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +43723334984997307 E-26 x 1e0be3f392c549_01111111111111111111111111111111111111111111111111111110& E-32
+    convertToDouble +43723334984997307E-26
+} 0x3dfe0be3f392c549
+test expr-28.1013 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN +10182419849537963 E-24 x 15ddd831ebbe53_011111111111111111111111111111111111111111111111111110& E-27
+    convertToDouble +10182419849537963E-24
+} 0x3e45ddd831ebbe53
+test expr-28.1014 {input floating-point conversion} {ieeeFloatingPoint} {
+    # Ad2b dieee UN -93501703572661982 E-26 x -10103f97ea6e13_0111111111111111111111111111111111111111111111111110& E-30
+    convertToDouble -93501703572661982E-26
+} 0xbe10103f97ea6e13
+
+test expr-29.1 {smallest representible number} {ieeeFloatingPoint} {
+    list [catch {convertToDouble 4.9406564584124654e-324} result] \
+	$result \
+	[catch {convertToDouble 2.4703282292062327e-324} result] \
+	$result \
+	[catch {convertToDouble 2.47032822920623e-324} result] \
+	$result
+} {0 0x0000000000000001 0 0x0000000000000001 0 0x0000000000000000}
+test expr-29.2 {smallest representible number} {ieeeFloatingPoint} {
+    list [catch {convertToDouble -4.9406564584124654e-324} result] \
+	$result \
+	[catch {convertToDouble -2.4703282292062327e-324} result] \
+	$result \
+	[catch {convertToDouble -2.47032822920623e-324} result] \
+	$result
+} {0 0x8000000000000001 0 0x8000000000000001 0 0x8000000000000000}
+test expr-29.3 {silent underflow on input conversion} {ieeeFloatingPoint} {
+    set v ?
+    list [scan 2.47032822920623e-324 %g v] $v
+} {1 0.0}
+test expr-29.4 {silent underflow on input conversion} {ieeeFloatingPoint} {
+    set v ?
+    list [scan -2.47032822920623e-324 %g v] $v
+} {1 -0.0}
+
+test expr-30.1 {largest representible number} {ieeeFloatingPoint} {
+    list [catch {convertToDouble 1.7976931348623155e+308} result] \
+	$result \
+	[catch {convertToDouble 1.7976931348623157e+308} result] \
+	$result \
+	[catch {convertToDouble 1.7976931348623159e+308} result] \
+	$result
+} {0 0x7feffffffffffffe 0 0x7fefffffffffffff 0 0x7ff0000000000000}
+test expr-30.2 {largest representible number} {ieeeFloatingPoint} {
+    list [catch {convertToDouble -1.7976931348623155e+308} result] \
+	$result \
+	[catch {convertToDouble -1.7976931348623157e+308} result] \
+	$result \
+	[catch {convertToDouble -1.7976931348623159e+308} result] \
+	$result
+} {0 0xffeffffffffffffe 0 0xffefffffffffffff 0 0xfff0000000000000}
+test expr-30.3 {silent overflow on input conversion} {ieeeFloatingPoint} {
+    set v ?
+    list [scan 1.7976931348623159e+308 %f v] $v
+} {1 Inf}
+test expr-30.4 {silent overflow on input conversion} {ieeeFloatingPoint} {
+    set v ?
+    list [scan -1.7976931348623159e+308 %f v] $v
+} {1 -Inf}
+
+# bool() tests (TIP #182)
+set i 0
+foreach s {yes true on} {
+    test expr-31.$i.0 {boolean conversion} {expr bool($s)} 1
+    test expr-31.$i.1 {boolean conversion} {expr bool(!$s)} 0
+    test expr-31.$i.2 {boolean conversion} {expr bool("$s")} 1
+    test expr-31.$i.3 {boolean conversion} {expr bool(!"$s")} 0
+    set j 1
+    while {$j < [string length $s]-1} {
+	test expr-31.$i.4.$j {boolean conversion} {
+	    expr bool([string range $s 0 $j])
+	} 1
+	test expr-31.$i.5.$j {boolean conversion} {
+	    expr bool("[string range $s 0 $j]")
+	} 1
+	incr j
+    }
+    incr i
+}
+test expr-31.0.4.0 {boolean conversion} {expr bool(y)} 1
+test expr-31.0.5.0 {boolean conversion} {expr bool("y")} 1
+test expr-31.1.4.0 {boolean conversion} {expr bool(t)} 1
+test expr-31.1.5.0 {boolean conversion} {expr bool("t")} 1
+test expr-31.2.4.0 {boolean conversion} -body {
+    expr bool(o)
+} -returnCodes error -match glob -result *
+test expr-31.2.5.0 {boolean conversion} -body {
+    expr bool("o")
+} -returnCodes error -match glob -result *
+foreach s {no false off} {
+    test expr-31.$i.0 {boolean conversion} {expr bool($s)} 0
+    test expr-31.$i.1 {boolean conversion} {expr bool(!$s)} 1
+    test expr-31.$i.2 {boolean conversion} {expr bool("$s")} 0
+    test expr-31.$i.3 {boolean conversion} {expr bool(!"$s")} 1
+    set j 1
+    while {$j < [string length $s]-1} {
+	test expr-31.$i.4.$j {boolean conversion} {
+	    expr bool([string range $s 0 $j])
+	} 0
+	test expr-31.$i.5.$j {boolean conversion} {
+	    expr bool("[string range $s 0 $j]")
+	} 0
+	incr j
+    }
+    incr i
+}
+test expr-31.3.4.0 {boolean conversion} {expr bool(n)} 0
+test expr-31.3.5.0 {boolean conversion} {expr bool("n")} 0
+test expr-31.4.4.0 {boolean conversion} {expr bool(f)} 0
+test expr-31.4.5.0 {boolean conversion} {expr bool("f")} 0
+test expr-31.6  {boolean conversion} {expr bool(-1 + 1)} 0
+test expr-31.7  {boolean conversion} {expr bool(0 + 1)} 1
+test expr-31.8  {boolean conversion} {expr bool(0.0)} 0
+test expr-31.9  {boolean conversion} {expr bool(0x0)} 0
+test expr-31.10 {boolean conversion} {expr bool(wide(0))} 0
+test expr-31.11 {boolean conversion} {expr bool(5.0)} 1
+test expr-31.12 {boolean conversion} {expr bool(5)} 1
+test expr-31.13 {boolean conversion} {expr bool(0x5)} 1
+test expr-31.14 {boolean conversion} {expr bool(wide(5))} 1
+test expr-31.15 {boolean conversion} -body {
+    expr bool("fred")
+} -returnCodes error -match glob -result *
+
+test expr-32.1 {expr mod basics} {
+    set mod_nums [list \
+        {-3 1} {-3 2} {-3 3} {-3 4} {-3 5} \
+        {-3 -1} {-3 -2} {-3 -3} {-3 -4} {-3 -5} \
+        {-2 1} {-2 2} {-2 3} {-2 4} {-2 5} \
+        {-2 -1} {-2 -2} {-2 -3} {-2 -4} {-2 -5} \
+        {-1 1} {-1 2} {-1 3} {-1 4} {-1 5} \
+        {-1 -1} {-1 -2} {-1 -3} {-1 -4} {-1 -5} \
+        {0 -100} {0 -1} {0 1} {0 100} \
+        {1 1} {1 2} {1 3} {1 4} {1 5} \
+        {1 -1} {1 -2} {1 -3} {1 -4} {1 -5} \
+        {2 1} {2 2} {2 3} {2 4} {2 5} \
+        {2 -1} {2 -2} {2 -3} {2 -4} {2 -5} \
+        {3 1} {3 2} {3 3} {3 4} {3 5} \
+        {3 -1} {3 -2} {3 -3} {3 -4} {3 -5} \
+        ]
+    set results [list]
+    foreach pair $mod_nums {
+        set dividend [lindex $pair 0]
+        set divisor [lindex $pair 1]
+        lappend results [expr {$dividend % $divisor}]
+    }
+    set results
+} [list \
+    0 1 0 1 2 \
+    0 -1 0 -3 -3 \
+    0 0 1 2 3 \
+    0 0 -2 -2 -2 \
+    0 1 2 3 4 \
+    0 -1 -1 -1 -1 \
+    0 0 0 0 \
+    0 1 1 1 1 \
+    0 -1 -2 -3 -4 \
+    0 0 2 2 2 \
+    0 0 -1 -2 -3 \
+    0 1 0 3 3 \
+    0 -1 0 -1 -2 \
+    ]
+        
+test expr-32.2 {expr div basics} {
+    set mod_nums [list \
+        {-3 1} {-3 2} {-3 3} {-3 4} {-3 5} \
+        {-3 -1} {-3 -2} {-3 -3} {-3 -4} {-3 -5} \
+        {-2 1} {-2 2} {-2 3} {-2 4} {-2 5} \
+        {-2 -1} {-2 -2} {-2 -3} {-2 -4} {-2 -5} \
+        {-1 1} {-1 2} {-1 3} {-1 4} {-1 5} \
+        {-1 -1} {-1 -2} {-1 -3} {-1 -4} {-1 -5} \
+        {0 -100} {0 -1} {0 1} {0 100} \
+        {1 1} {1 2} {1 3} {1 4} {1 5} \
+        {1 -1} {1 -2} {1 -3} {1 -4} {1 -5} \
+        {2 1} {2 2} {2 3} {2 4} {2 5} \
+        {2 -1} {2 -2} {2 -3} {2 -4} {2 -5} \
+        {3 1} {3 2} {3 3} {3 4} {3 5} \
+        {3 -1} {3 -2} {3 -3} {3 -4} {3 -5} \
+        ]
+    set results [list]
+    foreach pair $mod_nums {
+        set dividend [lindex $pair 0]
+        set divisor [lindex $pair 1]
+        lappend results [expr {$dividend / $divisor}]
+    }
+    set results
+} [list \
+    -3 -2 -1 -1 -1 \
+    3 1 1 0 0 \
+    -2 -1 -1 -1 -1 \
+    2 1 0 0 0 \
+    -1 -1 -1 -1 -1 \
+    1 0 0 0 0 \
+    0 0 0 0 \
+    1 0 0 0 0 \
+    -1 -1 -1 -1 -1 \
+    2 1 0 0 0 \
+    -2 -1 -1 -1 -1 \
+    3 1 1 0 0 \
+    -3 -2 -1 -1 -1 \
+    ]
+
+test expr-32.3 {Bug 1585704} {
+    expr 1%(1<<63)
+} 1
+test expr-32.4 {Bug 1585704} {
+    expr -1%(1<<63)
+} [expr (1<<63)-1]
+test expr-32.5 {Bug 1585704} {
+    expr (1<<32)%(1<<63)
+} [expr 1<<32]
+test expr-32.6 {Bug 1585704} {
+    expr -(1<<32)%(1<<63)
+} [expr (1<<63)-(1<<32)]
+
+test expr-33.1 {parse largest long value} longIs32bit {
+    set max_long_str 2147483647
+    set max_long_hex "0x7FFFFFFF "
+
+    # Convert to integer (long, not wide) internal rep
+    set max_long 2147483647
+    string is integer $max_long
+
+    list \
+        [expr {" $max_long_str "}] \
+        [expr {$max_long_str + 0}] \
+        [expr {$max_long + 0}] \
+        [expr {2147483647 + 0}] \
+        [expr {$max_long == $max_long_hex}] \
+        [expr {int(2147483647 + 1) < 0}] \
+
+} {2147483647 2147483647 2147483647 2147483647 1 1}
+test expr-33.2 {parse smallest long value} longIs32bit {
+    set min_long_str -2147483648
+    set min_long_hex "-0x80000000 "
+
+    set min_long -2147483648
+    # This will convert to integer (not wide) internal rep
+    string is integer $min_long
+
+    # Note: If the final expression returns 0 then the
+    # expression literal is being promoted to a wide type
+    # when it should be parsed as a long type.
+    list \
+        [expr {" $min_long_str "}] \
+        [expr {$min_long_str + 0}] \
+        [expr {$min_long + 0}] \
+        [expr {-2147483648 + 0}] \
+        [expr {$min_long == $min_long_hex}] \
+        [expr {int(-2147483648 - 1) == 0x7FFFFFFF}] \
+
+} {-2147483648 -2147483648 -2147483648 -2147483648 1 1}
+test expr-33.3 {parse largest wide value} wideIs64bit {
+    set max_wide_str 9223372036854775807
+    set max_wide_hex "0x7FFFFFFFFFFFFFFF "
+
+    # Convert to wide integer
+    set max_wide 9223372036854775807
+    string is integer $max_wide
+
+    list \
+        [expr {" $max_wide_str "}] \
+        [expr {$max_wide_str + 0}] \
+        [expr {$max_wide + 0}] \
+        [expr {9223372036854775807 + 0}] \
+        [expr {$max_wide == $max_wide_hex}] \
+        [expr {wide(9223372036854775807 + 1) < 0}] \
+
+} {9223372036854775807 9223372036854775807 9223372036854775807 9223372036854775807 1 1}
+test expr-33.4 {parse smallest wide value} wideIs64bit {
+    set min_wide_str -9223372036854775808
+    set min_wide_hex "-0x8000000000000000 "
+
+    set min_wide -9223372036854775808
+    # Convert to wide integer
+    string is integer $min_wide
+
+    # Note: If the final expression returns 0 then the
+    # wide integer is not being parsed correctly with
+    # the leading - sign.
+    list \
+        [expr {" $min_wide_str "}] \
+        [expr {$min_wide_str + 0}] \
+        [expr {$min_wide + 0}] \
+        [expr {-9223372036854775808 + 0}] \
+        [expr {$min_wide == $min_wide_hex}] \
+        [expr {wide(-9223372036854775808 - 1) == 0x7FFFFFFFFFFFFFFF}] \
+
+} {-9223372036854775808 -9223372036854775808 -9223372036854775808 -9223372036854775808 1 1}
+
+set min -2147483648
+set max 2147483647
+
+test expr-34.1 {expr edge cases} {
+    expr {$min / $min}
+} {1}
+test expr-34.2 {expr edge cases} {
+    expr {$min % $min}
+} {0}
+test expr-34.3 {expr edge cases} {
+    expr {$min / ($min + 1)}
+} {1}
+test expr-34.4 {expr edge cases} {
+    expr {$min % ($min + 1)}
+} {-1}
+test expr-34.5 {expr edge cases} {
+    expr {$min / ($min + 2)}
+} {1}
+test expr-34.6 {expr edge cases} {
+    expr {$min % ($min + 2)}
+} {-2}
+test expr-34.7 {expr edge cases} {
+    expr {$min / ($min + 3)}
+} {1}
+test expr-34.8 {expr edge cases} {
+    expr {$min % ($min + 3)}
+} {-3}
+test expr-34.9 {expr edge cases} {
+    expr {$min / -3}
+} {715827882}
+test expr-34.10 {expr edge cases} {
+    expr {$min % -3}
+} {-2}
+test expr-34.11 {expr edge cases} {
+    expr {$min / -2}
+} {1073741824}
+test expr-34.12 {expr edge cases} {
+    expr {$min % -2}
+} {0}
+test expr-34.13 {expr edge cases} longIs32bit {
+    expr {int($min / -1)}
+} {-2147483648}
+test expr-34.14 {expr edge cases} {
+    expr {$min % -1}
+} {0}
+test expr-34.15 {expr edge cases} longIs32bit {
+    expr {int($min * -1)}
+} $min
+test expr-34.16 {expr edge cases} longIs32bit {
+    expr {int(-$min)}
+} $min
+test expr-34.17 {expr edge cases} {
+    expr {$min / 1}
+} $min
+test expr-34.18 {expr edge cases} {
+    expr {$min % 1}
+} {0}
+test expr-34.19 {expr edge cases} {
+    expr {$min / 2}
+} {-1073741824}
+test expr-34.20 {expr edge cases} {
+    expr {$min % 2}
+} {0}
+test expr-34.21 {expr edge cases} {
+    expr {$min / 3}
+} {-715827883}
+test expr-34.22 {expr edge cases} {
+    expr {$min % 3}
+} {1}
+test expr-34.23 {expr edge cases} {
+    expr {$min / ($max - 3)}
+} {-2}
+test expr-34.24 {expr edge cases} {
+    expr {$min % ($max - 3)}
+} {2147483640}
+test expr-34.25 {expr edge cases} {
+    expr {$min / ($max - 2)}
+} {-2}
+test expr-34.26 {expr edge cases} {
+    expr {$min % ($max - 2)}
+} {2147483642}
+test expr-34.27 {expr edge cases} {
+    expr {$min / ($max - 1)}
+} {-2}
+test expr-34.28 {expr edge cases} {
+    expr {$min % ($max - 1)}
+} {2147483644}
+test expr-34.29 {expr edge cases} {
+    expr {$min / $max}
+} {-2}
+test expr-34.30 {expr edge cases} {
+    expr {$min % $max}
+} {2147483646}
+test expr-34.31 {expr edge cases} {
+    expr {$max / $max}
+} {1}
+test expr-34.32 {expr edge cases} {
+    expr {$max % $max}
+} {0}
+test expr-34.33 {expr edge cases} {
+    expr {$max / ($max - 1)}
+} {1}
+test expr-34.34 {expr edge cases} {
+    expr {$max % ($max - 1)}
+} {1}
+test expr-34.35 {expr edge cases} {
+    expr {$max / ($max - 2)}
+} {1}
+test expr-34.36 {expr edge cases} {
+    expr {$max % ($max - 2)}
+} {2}
+test expr-34.37 {expr edge cases} {
+    expr {$max / ($max - 3)}
+} {1}
+test expr-34.38 {expr edge cases} {
+    expr {$max % ($max - 3)}
+} {3}
+test expr-34.39 {expr edge cases} {
+    expr {$max / 3}
+} {715827882}
+test expr-34.40 {expr edge cases} {
+    expr {$max % 3}
+} {1}
+test expr-34.41 {expr edge cases} {
+    expr {$max / 2}
+} {1073741823}
+test expr-34.42 {expr edge cases} {
+    expr {$max % 2}
+} {1}
+test expr-34.43 {expr edge cases} {
+    expr {$max / 1}
+} $max
+test expr-34.44 {expr edge cases} {
+    expr {$max % 1}
+} {0}
+test expr-34.45 {expr edge cases} {
+    expr {$max / -1}
+} "-$max"
+test expr-34.46 {expr edge cases} {
+    expr {$max % -1}
+} {0}
+test expr-34.47 {expr edge cases} {
+    expr {$max / -2}
+} {-1073741824}
+test expr-34.48 {expr edge cases} {
+    expr {$max % -2}
+} {-1}
+test expr-34.49 {expr edge cases} {
+    expr {$max / -3}
+} {-715827883}
+test expr-34.50 {expr edge cases} {
+    expr {$max % -3}
+} {-2}
+test expr-34.51 {expr edge cases} {
+    expr {$max / ($min + 3)}
+} {-2}
+test expr-34.52 {expr edge cases} {
+    expr {$max % ($min + 3)}
+} {-2147483643}
+test expr-34.53 {expr edge cases} {
+    expr {$max / ($min + 2)}
+} {-2}
+test expr-34.54 {expr edge cases} {
+    expr {$max % ($min + 2)}
+} {-2147483645}
+test expr-34.55 {expr edge cases} {
+    expr {$max / ($min + 1)}
+} {-1}
+test expr-34.56 {expr edge cases} {
+    expr {$max % ($min + 1)}
+} {0}
+test expr-34.57 {expr edge cases} {
+    expr {$max / $min}
+} {-1}
+test expr-34.58 {expr edge cases} {
+    expr {$max % $min}
+} {-1}
+test expr-34.59 {expr edge cases} {
+    expr {($min + 1) / ($max - 1)}
+} {-2}
+test expr-34.60 {expr edge cases} {
+    expr {($min + 1) % ($max - 1)}
+} {2147483645}
+test expr-34.61 {expr edge cases} {
+    expr {($max - 1) / ($min + 1)}
+} {-1}
+test expr-34.62 {expr edge cases} {
+    expr {($max - 1) % ($min + 1)}
+} {-1}
+test expr-34.63 {expr edge cases} {
+    expr {($max - 1) / $min}
+} {-1}
+test expr-34.64 {expr edge cases} {
+    expr {($max - 1) % $min}
+} {-2}
+test expr-34.65 {expr edge cases} {
+    expr {($max - 2) / $min}
+} {-1}
+test expr-34.66 {expr edge cases} {
+    expr {($max - 2) % $min}
+} {-3}
+test expr-34.67 {expr edge cases} {
+    expr {($max - 3) / $min}
+} {-1}
+test expr-34.68 {expr edge cases} {
+    expr {($max - 3) % $min}
+} {-4}
+test expr-34.69 {expr edge cases} {
+    expr {-3 / $min}
+} {0}
+test expr-34.70 {expr edge cases} {
+    expr {-3 % $min}
+} {-3}
+test expr-34.71 {expr edge cases} {
+    expr {-2 / $min}
+} {0}
+test expr-34.72 {expr edge cases} {
+    expr {-2 % $min}
+} {-2}
+test expr-34.73 {expr edge cases} {
+    expr {-1 / $min}
+} {0}
+test expr-34.74 {expr edge cases} {
+    expr {-1 % $min}
+} {-1}
+test expr-34.75 {expr edge cases} {
+    expr {0 / $min}
+} {0}
+test expr-34.76 {expr edge cases} {
+    expr {0 % $min}
+} {0}
+test expr-34.77 {expr edge cases} {
+    expr {0 / ($min + 1)}
+} {0}
+test expr-34.78 {expr edge cases} {
+    expr {0 % ($min + 1)}
+} {0}
+test expr-34.79 {expr edge cases} {
+    expr {1 / $min}
+} {-1}
+test expr-34.80 {expr edge cases} {
+    expr {1 % $min}
+} {-2147483647}
+test expr-34.81 {expr edge cases} {
+    expr {1 / ($min + 1)}
+} {-1}
+test expr-34.82 {expr edge cases} {
+    expr {1 % ($min + 1)}
+} {-2147483646}
+test expr-34.83 {expr edge cases} {
+    expr {2 / $min}
+} {-1}
+test expr-34.84 {expr edge cases} {
+    expr {2 % $min}
+} {-2147483646}
+test expr-34.85 {expr edge cases} {
+    expr {2 / ($min + 1)}
+} {-1}
+test expr-34.86 {expr edge cases} {
+    expr {2 % ($min + 1)}
+} {-2147483645}
+test expr-34.87 {expr edge cases} {
+    expr {3 / $min}
+} {-1}
+test expr-34.88 {expr edge cases} {
+    expr {3 % $min}
+} {-2147483645}
+test expr-34.89 {expr edge cases} {
+    expr {3 / ($min + 1)}
+} {-1}
+test expr-34.90 {expr edge cases} {
+    expr {3 % ($min + 1)}
+} {-2147483644}
+
+# Euclidean property:
+# quotient * divisor + remainder = dividend
+
+test expr-35.1 {expr edge cases} {
+    set dividend $max
+    set divisor 2
+    set q [expr {$dividend / $divisor}]
+    set r [expr {$dividend % $divisor}]
+    list $q * $divisor + $r = [expr {($divisor * $q) + $r}]
+} {1073741823 * 2 + 1 = 2147483647}
+test expr-35.2 {expr edge cases} {
+    set dividend [expr {$max - 1}]
+    set divisor 2
+    set q [expr {$dividend / $divisor}]
+    set r [expr {$dividend % $divisor}]
+    list $q * $divisor + $r = [expr {($q * $divisor) + $r}]
+} {1073741823 * 2 + 0 = 2147483646}
+test expr-35.3 {expr edge cases} {
+    set dividend [expr {$max - 2}]
+    set divisor 2
+    set q [expr {$dividend / $divisor}]
+    set r [expr {$dividend % $divisor}]
+    list $q * $divisor + $r = [expr {($q * $divisor) + $r}]
+} {1073741822 * 2 + 1 = 2147483645}
+test expr-35.4 {expr edge cases} {
+    set dividend $max
+    set divisor 3
+    set q [expr {$dividend / $divisor}]
+    set r [expr {$dividend % $divisor}]
+    list $q * $divisor + $r = [expr {($q * $divisor) + $r}]
+} {715827882 * 3 + 1 = 2147483647}
+test expr-35.5 {expr edge cases} {
+    set dividend [expr {$max - 1}]
+    set divisor 3
+    set q [expr {$dividend / $divisor}]
+    set r [expr {$dividend % $divisor}]
+    list $q * $divisor + $r = [expr {($q * $divisor) + $r}]
+} {715827882 * 3 + 0 = 2147483646}
+test expr-35.6 {expr edge cases} {
+    set dividend [expr {$max - 2}]
+    set divisor 3
+    set q [expr {$dividend / $divisor}]
+    set r [expr {$dividend % $divisor}]
+    list $q * $divisor + $r = [expr {($q * $divisor) + $r}]
+} {715827881 * 3 + 2 = 2147483645}
+test expr-35.7 {expr edge cases} {
+    set dividend $min
+    set divisor 2
+    set q [expr {$dividend / $divisor}]
+    set r [expr {$dividend % $divisor}]
+    list $q * $divisor + $r = [expr {($q * $divisor) + $r}]
+} {-1073741824 * 2 + 0 = -2147483648}
+test expr-35.8 {expr edge cases} {
+    set dividend [expr {$min + 1}]
+    set divisor 2
+    set q [expr {$dividend / $divisor}]
+    set r [expr {$dividend % $divisor}]
+    list $q * $divisor + $r = [expr {($q * $divisor) + $r}]
+} {-1073741824 * 2 + 1 = -2147483647}
+test expr-35.9 {expr edge cases} {
+    set dividend [expr {$min + 2}]
+    set divisor 2
+    set q [expr {$dividend / $divisor}]
+    set r [expr {$dividend % $divisor}]
+    list $q * $divisor + $r = [expr {($q * $divisor) + $r}]
+} {-1073741823 * 2 + 0 = -2147483646}
+test expr-35.10 {expr edge cases} {
+    # Two things could happen here. The multiplication
+    # could overflow a 32 bit type, so that when
+    # 1 is added it overflows again back to min.
+    # The multiplication could also use a wide type
+    # to hold ($min - 1) until 1 is added and
+    # the number becomes $min again.
+    set dividend $min
+    set divisor 3
+    set q [expr {$dividend / $divisor}]
+    set r [expr {$dividend % $divisor}]
+    list $q * $divisor + $r = [expr {($q * $divisor) + $r}]
+} {-715827883 * 3 + 1 = -2147483648}
+test expr-35.11 {expr edge cases} {
+    set dividend $min
+    set divisor -3
+    set q [expr {$dividend / $divisor}]
+    set r [expr {$dividend % $divisor}]
+    list $q * $divisor + $r = [expr {($q * $divisor) + $r}]
+} {715827882 * -3 + -2 = -2147483648}
+test expr-35.12 {expr edge cases} {
+    set dividend $min
+    set divisor $min
+    set q [expr {$dividend / $divisor}]
+    set r [expr {$dividend % $divisor}]
+    list $q * $divisor + $r = [expr {($q * $divisor) + $r}]
+} {1 * -2147483648 + 0 = -2147483648}
+test expr-35.13 {expr edge cases} {
+    set dividend $min
+    set divisor [expr {$min + 1}]
+    set q [expr {$dividend / $divisor}]
+    set r [expr {$dividend % $divisor}]
+    list $q * $divisor + $r = [expr {($q * $divisor) + $r}]
+} {1 * -2147483647 + -1 = -2147483648}
+test expr-35.14 {expr edge cases} {
+    set dividend $min
+    set divisor [expr {$min + 2}]
+    set q [expr {$dividend / $divisor}]
+    set r [expr {$dividend % $divisor}]
+    list $q * $divisor + $r = [expr {($q * $divisor) + $r}]
+} {1 * -2147483646 + -2 = -2147483648}
+
+# 64bit wide integer checks
+
+set min -9223372036854775808
+set max 9223372036854775807
+
+test expr-36.1 {expr edge cases} {wideIs64bit} {
+    expr {$min / $min}
+} {1}
+test expr-36.2 {expr edge cases} {wideIs64bit} {
+    expr {$min % $min}
+} {0}
+test expr-36.3 {expr edge cases} {wideIs64bit} {
+    expr {$min / ($min + 1)}
+} {1}
+test expr-36.4 {expr edge cases} {wideIs64bit} {
+    expr {$min % ($min + 1)}
+} {-1}
+test expr-36.5 {expr edge cases} {wideIs64bit} {
+    expr {$min / ($min + 2)}
+} {1}
+test expr-36.6 {expr edge cases} {wideIs64bit} {
+    expr {$min % ($min + 2)}
+} {-2}
+test expr-36.7 {expr edge cases} {wideIs64bit} {
+    expr {$min / ($min + 3)}
+} {1}
+test expr-36.8 {expr edge cases} {wideIs64bit} {
+    expr {$min % ($min + 3)}
+} {-3}
+test expr-36.9 {expr edge cases} {wideIs64bit} {
+    expr {$min / -3}
+} {3074457345618258602}
+test expr-36.10 {expr edge cases} {wideIs64bit} {
+    expr {$min % -3}
+} {-2}
+test expr-36.11 {expr edge cases} {wideIs64bit} {
+    expr {$min / -2}
+} {4611686018427387904}
+test expr-36.12 {expr edge cases} {wideIs64bit} {
+    expr {$min % -2}
+} {0}
+test expr-36.13 {expr edge cases} wideIs64bit {
+    expr {wide($min / -1)}
+} $min
+test expr-36.14 {expr edge cases} {wideIs64bit} {
+    expr {$min % -1}
+} {0}
+test expr-36.15 {expr edge cases} wideIs64bit {
+    expr {wide($min * -1)}
+} $min
+test expr-36.16 {expr edge cases} wideIs64bit {
+    expr {wide(-$min)}
+} $min
+test expr-36.17 {expr edge cases} {wideIs64bit} {
+    expr {$min / 1}
+} $min
+test expr-36.18 {expr edge cases} {wideIs64bit} {
+    expr {$min % 1}
+} {0}
+test expr-36.19 {expr edge cases} {wideIs64bit} {
+    expr {$min / 2}
+} {-4611686018427387904}
+test expr-36.20 {expr edge cases} {wideIs64bit} {
+    expr {$min % 2}
+} {0}
+test expr-36.21 {expr edge cases} {wideIs64bit} {
+    expr {$min / 3}
+} {-3074457345618258603}
+test expr-36.22 {expr edge cases} {wideIs64bit} {
+    expr {$min % 3}
+} {1}
+test expr-36.23 {expr edge cases} {wideIs64bit} {
+    expr {$min / ($max - 3)}
+} {-2}
+test expr-36.24 {expr edge cases} {wideIs64bit} {
+    expr {$min % ($max - 3)}
+} {9223372036854775800}
+test expr-36.25 {expr edge cases} {wideIs64bit} {
+    expr {$min / ($max - 2)}
+} {-2}
+test expr-36.26 {expr edge cases} {wideIs64bit} {
+    expr {$min % ($max - 2)}
+} {9223372036854775802}
+test expr-36.27 {expr edge cases} {wideIs64bit} {
+    expr {$min / ($max - 1)}
+} {-2}
+test expr-36.28 {expr edge cases} {wideIs64bit} {
+    expr {$min % ($max - 1)}
+} {9223372036854775804}
+test expr-36.29 {expr edge cases} {wideIs64bit} {
+    expr {$min / $max}
+} {-2}
+test expr-36.30 {expr edge cases} {wideIs64bit} {
+    expr {$min % $max}
+} {9223372036854775806}
+test expr-36.31 {expr edge cases} {wideIs64bit} {
+    expr {$max / $max}
+} {1}
+test expr-36.32 {expr edge cases} {wideIs64bit} {
+    expr {$max % $max}
+} {0}
+test expr-36.33 {expr edge cases} {wideIs64bit} {
+    expr {$max / ($max - 1)}
+} {1}
+test expr-36.34 {expr edge cases} {wideIs64bit} {
+    expr {$max % ($max - 1)}
+} {1}
+test expr-36.35 {expr edge cases} {wideIs64bit} {
+    expr {$max / ($max - 2)}
+} {1}
+test expr-36.36 {expr edge cases} {wideIs64bit} {
+    expr {$max % ($max - 2)}
+} {2}
+test expr-36.37 {expr edge cases} {wideIs64bit} {
+    expr {$max / ($max - 3)}
+} {1}
+test expr-36.38 {expr edge cases} {wideIs64bit} {
+    expr {$max % ($max - 3)}
+} {3}
+test expr-36.39 {expr edge cases} {wideIs64bit} {
+    expr {$max / 3}
+} {3074457345618258602}
+test expr-36.40 {expr edge cases} {wideIs64bit} {
+    expr {$max % 3}
+} {1}
+test expr-36.41 {expr edge cases} {wideIs64bit} {
+    expr {$max / 2}
+} {4611686018427387903}
+test expr-36.42 {expr edge cases} {wideIs64bit} {
+    expr {$max % 2}
+} {1}
+test expr-36.43 {expr edge cases} {wideIs64bit} {
+    expr {$max / 1}
+} $max
+test expr-36.44 {expr edge cases} {wideIs64bit} {
+    expr {$max % 1}
+} {0}
+test expr-36.45 {expr edge cases} {wideIs64bit} {
+    expr {$max / -1}
+} "-$max"
+test expr-36.46 {expr edge cases} {wideIs64bit} {
+    expr {$max % -1}
+} {0}
+test expr-36.47 {expr edge cases} {wideIs64bit} {
+    expr {$max / -2}
+} {-4611686018427387904}
+test expr-36.48 {expr edge cases} {wideIs64bit} {
+    expr {$max % -2}
+} {-1}
+test expr-36.49 {expr edge cases} {wideIs64bit} {
+    expr {$max / -3}
+} {-3074457345618258603}
+test expr-36.50 {expr edge cases} {wideIs64bit} {
+    expr {$max % -3}
+} {-2}
+test expr-36.51 {expr edge cases} {wideIs64bit} {
+    expr {$max / ($min + 3)}
+} {-2}
+test expr-36.52 {expr edge cases} {wideIs64bit} {
+    expr {$max % ($min + 3)}
+} {-9223372036854775803}
+test expr-36.53 {expr edge cases} {wideIs64bit} {
+    expr {$max / ($min + 2)}
+} {-2}
+test expr-36.54 {expr edge cases} {wideIs64bit} {
+    expr {$max % ($min + 2)}
+} {-9223372036854775805}
+test expr-36.55 {expr edge cases} {wideIs64bit} {
+    expr {$max / ($min + 1)}
+} {-1}
+test expr-36.56 {expr edge cases} {wideIs64bit} {
+    expr {$max % ($min + 1)}
+} {0}
+test expr-36.57 {expr edge cases} {wideIs64bit} {
+    expr {$max / $min}
+} {-1}
+test expr-36.58 {expr edge cases} {wideIs64bit} {
+    expr {$max % $min}
+} {-1}
+test expr-36.59 {expr edge cases} {wideIs64bit} {
+    expr {($min + 1) / ($max - 1)}
+} {-2}
+test expr-36.60 {expr edge cases} {wideIs64bit} {
+    expr {($min + 1) % ($max - 1)}
+} {9223372036854775805}
+test expr-36.61 {expr edge cases} {wideIs64bit} {
+    expr {($max - 1) / ($min + 1)}
+} {-1}
+test expr-36.62 {expr edge cases} {wideIs64bit} {
+    expr {($max - 1) % ($min + 1)}
+} {-1}
+test expr-36.63 {expr edge cases} {wideIs64bit} {
+    expr {($max - 1) / $min}
+} {-1}
+test expr-36.64 {expr edge cases} {wideIs64bit} {
+    expr {($max - 1) % $min}
+} {-2}
+test expr-36.65 {expr edge cases} {wideIs64bit} {
+    expr {($max - 2) / $min}
+} {-1}
+test expr-36.66 {expr edge cases} {wideIs64bit} {
+    expr {($max - 2) % $min}
+} {-3}
+test expr-36.67 {expr edge cases} {wideIs64bit} {
+    expr {($max - 3) / $min}
+} {-1}
+test expr-36.68 {expr edge cases} {wideIs64bit} {
+    expr {($max - 3) % $min}
+} {-4}
+test expr-36.69 {expr edge cases} {wideIs64bit} {
+    expr {-3 / $min}
+} {0}
+test expr-36.70 {expr edge cases} {wideIs64bit} {
+    expr {-3 % $min}
+} {-3}
+test expr-36.71 {expr edge cases} {wideIs64bit} {
+    expr {-2 / $min}
+} {0}
+test expr-36.72 {expr edge cases} {wideIs64bit} {
+    expr {-2 % $min}
+} {-2}
+test expr-36.73 {expr edge cases} {wideIs64bit} {
+    expr {-1 / $min}
+} {0}
+test expr-36.74 {expr edge cases} {wideIs64bit} {
+    expr {-1 % $min}
+} {-1}
+test expr-36.75 {expr edge cases} {wideIs64bit} {
+    expr {0 / $min}
+} {0}
+test expr-36.76 {expr edge cases} {wideIs64bit} {
+    expr {0 % $min}
+} {0}
+test expr-36.77 {expr edge cases} {wideIs64bit} {
+    expr {0 / ($min + 1)}
+} {0}
+test expr-36.78 {expr edge cases} {wideIs64bit} {
+    expr {0 % ($min + 1)}
+} {0}
+test expr-36.79 {expr edge cases} {wideIs64bit} {
+    expr {1 / $min}
+} {-1}
+test expr-36.80 {expr edge cases} {wideIs64bit} {
+    expr {1 % $min}
+} {-9223372036854775807}
+test expr-36.81 {expr edge cases} {wideIs64bit} {
+    expr {1 / ($min + 1)}
+} {-1}
+test expr-36.82 {expr edge cases} {wideIs64bit} {
+    expr {1 % ($min + 1)}
+} {-9223372036854775806}
+test expr-36.83 {expr edge cases} {wideIs64bit} {
+    expr {2 / $min}
+} {-1}
+test expr-36.84 {expr edge cases} {wideIs64bit} {
+    expr {2 % $min}
+} {-9223372036854775806}
+test expr-36.85 {expr edge cases} {wideIs64bit} {
+    expr {2 / ($min + 1)}
+} {-1}
+test expr-36.86 {expr edge cases} {wideIs64bit} {
+    expr {2 % ($min + 1)}
+} {-9223372036854775805}
+test expr-36.87 {expr edge cases} {wideIs64bit} {
+    expr {3 / $min}
+} {-1}
+test expr-36.88 {expr edge cases} {wideIs64bit} {
+    expr {3 % $min}
+} {-9223372036854775805}
+test expr-36.89 {expr edge cases} {wideIs64bit} {
+    expr {3 / ($min + 1)}
+} {-1}
+test expr-36.90 {expr edge cases} {wideIs64bit} {
+    expr {3 % ($min + 1)}
+} {-9223372036854775804}
+
+test expr-37.1 {expr edge cases} {wideIs64bit} {
+    set dividend $max
+    set divisor 2
+    set q [expr {$dividend / $divisor}]
+    set r [expr {$dividend % $divisor}]
+    list $q * $divisor + $r = [expr {($divisor * $q) + $r}]
+} {4611686018427387903 * 2 + 1 = 9223372036854775807}
+test expr-37.2 {expr edge cases} {wideIs64bit} {
+    set dividend [expr {$max - 1}]
+    set divisor 2
+    set q [expr {$dividend / $divisor}]
+    set r [expr {$dividend % $divisor}]
+    list $q * $divisor + $r = [expr {($q * $divisor) + $r}]
+} {4611686018427387903 * 2 + 0 = 9223372036854775806}
+test expr-37.3 {expr edge cases} {wideIs64bit} {
+    set dividend [expr {$max - 2}]
+    set divisor 2
+    set q [expr {$dividend / $divisor}]
+    set r [expr {$dividend % $divisor}]
+    list $q * $divisor + $r = [expr {($q * $divisor) + $r}]
+} {4611686018427387902 * 2 + 1 = 9223372036854775805}
+test expr-37.4 {expr edge cases} {wideIs64bit} {
+    set dividend $max
+    set divisor 3
+    set q [expr {$dividend / $divisor}]
+    set r [expr {$dividend % $divisor}]
+    list $q * $divisor + $r = [expr {($q * $divisor) + $r}]
+} {3074457345618258602 * 3 + 1 = 9223372036854775807}
+test expr-37.5 {expr edge cases} {wideIs64bit} {
+    set dividend [expr {$max - 1}]
+    set divisor 3
+    set q [expr {$dividend / $divisor}]
+    set r [expr {$dividend % $divisor}]
+    list $q * $divisor + $r = [expr {($q * $divisor) + $r}]
+} {3074457345618258602 * 3 + 0 = 9223372036854775806}
+test expr-37.6 {expr edge cases} {wideIs64bit} {
+    set dividend [expr {$max - 2}]
+    set divisor 3
+    set q [expr {$dividend / $divisor}]
+    set r [expr {$dividend % $divisor}]
+    list $q * $divisor + $r = [expr {($q * $divisor) + $r}]
+} {3074457345618258601 * 3 + 2 = 9223372036854775805}
+test expr-37.7 {expr edge cases} {wideIs64bit} {
+    set dividend $min
+    set divisor 2
+    set q [expr {$dividend / $divisor}]
+    set r [expr {$dividend % $divisor}]
+    list $q * $divisor + $r = [expr {($q * $divisor) + $r}]
+} {-4611686018427387904 * 2 + 0 = -9223372036854775808}
+test expr-37.8 {expr edge cases} {wideIs64bit} {
+    set dividend [expr {$min + 1}]
+    set divisor 2
+    set q [expr {$dividend / $divisor}]
+    set r [expr {$dividend % $divisor}]
+    list $q * $divisor + $r = [expr {($q * $divisor) + $r}]
+} {-4611686018427387904 * 2 + 1 = -9223372036854775807}
+test expr-37.9 {expr edge cases} {wideIs64bit} {
+    set dividend [expr {$min + 2}]
+    set divisor 2
+    set q [expr {$dividend / $divisor}]
+    set r [expr {$dividend % $divisor}]
+    list $q * $divisor + $r = [expr {($q * $divisor) + $r}]
+} {-4611686018427387903 * 2 + 0 = -9223372036854775806}
+test expr-37.10 {expr edge cases} {wideIs64bit} {
+    # Multiplication overflows 64 bit type here,
+    # so when the 1 is added it overflows
+    # again and we end up back at min.
+    set dividend $min
+    set divisor 3
+    set q [expr {$dividend / $divisor}]
+    set r [expr {$dividend % $divisor}]
+    list $q * $divisor + $r = [expr {($q * $divisor) + $r}]
+} {-3074457345618258603 * 3 + 1 = -9223372036854775808}
+test expr-37.11 {expr edge cases} {wideIs64bit} {
+    set dividend $min
+    set divisor -3
+    set q [expr {$dividend / $divisor}]
+    set r [expr {$dividend % $divisor}]
+    list $q * $divisor + $r = [expr {($q * $divisor) + $r}]
+} {3074457345618258602 * -3 + -2 = -9223372036854775808}
+test expr-37.12 {expr edge cases} {wideIs64bit} {
+    set dividend $min
+    set divisor $min
+    set q [expr {$dividend / $divisor}]
+    set r [expr {$dividend % $divisor}]
+    list $q * $divisor + $r = [expr {($q * $divisor) + $r}]
+} {1 * -9223372036854775808 + 0 = -9223372036854775808}
+test expr-37.13 {expr edge cases} {wideIs64bit} {
+    set dividend $min
+    set divisor [expr {$min + 1}]
+    set q [expr {$dividend / $divisor}]
+    set r [expr {$dividend % $divisor}]
+    list $q * $divisor + $r = [expr {($q * $divisor) + $r}]
+} {1 * -9223372036854775807 + -1 = -9223372036854775808}
+test expr-37.14 {expr edge cases} {wideIs64bit} {
+    set dividend $min
+    set divisor [expr {$min + 2}]
+    set q [expr {$dividend / $divisor}]
+    set r [expr {$dividend % $divisor}]
+    list $q * $divisor + $r = [expr {($q * $divisor) + $r}]
+} {1 * -9223372036854775806 + -2 = -9223372036854775808}
+
+test expr-38.1 {abs of smallest 32-bit integer [Bug 1241572]} {wideIs64bit} {
+    expr {abs(-2147483648)}
+} 2147483648
+test expr-38.2 {abs and -0 [Bug 1893815]} {
+    expr {abs(-0)}
+} 0
+test expr-38.3 {abs and -0 [Bug 1893815]} {
+    expr {abs(-0.0)}
+} 0.0
+test expr-38.4 {abs and -0 [Bug 1893815]} {
+    expr {abs(-1e-324)}
+} 0.0
+test expr-38.5 {abs and -0 [Bug 1893815]} {
+    ::tcl::mathfunc::abs -0
+} 0
+test expr-38.6 {abs and -0 [Bug 1893815]} {
+    ::tcl::mathfunc::abs -0.0
+} 0.0
+test expr-38.7 {abs and -0 [Bug 1893815]} {
+    ::tcl::mathfunc::abs -1e-324
+} 0.0
+test expr-38.8 {abs and 0.0 [Bug 2954959]} {
+    ::tcl::mathfunc::abs 0.0
+} 0.0
+test expr-38.9 {abs and 0.0 [Bug 2954959]} {
+    expr {abs(0.0)}
+} 0.0
+test expr-38.10 {abs and -0x0 [Bug 2954959]} {
+    expr {abs(-0x0)}
+} 0
+test expr-38.11 {abs and 0x0 [Bug 2954959]} {
+    ::tcl::mathfunc::abs { 	0x0}
+} { 	0x0}
+test expr-38.12 {abs and -0x0 [Bug 2954959]} {
+    ::tcl::mathfunc::abs { 	-0x0}
+} 0
+test expr-38.13 {abs and 0.0 [Bug 2954959]} {
+    ::tcl::mathfunc::abs 1e-324
+} 1e-324
+
+testConstraint testexprlongobj   [llength [info commands testexprlongobj]]
+testConstraint testexprdoubleobj [llength [info commands testexprdoubleobj]]
+
+test expr-39.1 {Check that Tcl_ExprLongObj doesn't modify interpreter result if no error} testexprlongobj {
+    testexprlongobj 4+1
+} {This is a result: 5}
+#Check for [Bug 1109484]
+test expr-39.2 {Tcl_ExprLongObj handles wide ints gracefully} testexprlongobj {
+    testexprlongobj wide(1)+2
+} {This is a result: 3}
+
+test expr-39.3 {Tcl_ExprLongObj on the empty string} \
+    -constraints {testexprlongobj}\
+    -body {testexprlongobj ""} \
+    -match glob \
+    -returnCodes error -result *
+test expr-39.4 {Tcl_ExprLongObj coerces doubles} testexprlongobj {
+    testexprlongobj 3+.14159
+} {This is a result: 3}
+test expr-39.5 {Tcl_ExprLongObj handles overflows} {testexprlongobj longIs32bit} {
+    testexprlongobj 0x80000000
+} {This is a result: -2147483648}
+test expr-39.6 {Tcl_ExprLongObj handles overflows} {testexprlongobj longIs32bit} {
+    testexprlongobj 0xffffffff
+} {This is a result: -1}
+test expr-39.7 {Tcl_ExprLongObj handles overflows} \
+    -constraints {testexprlongobj longIs32bit} \
+    -match glob \
+    -body {
+	list [catch {testexprlongobj 0x100000000} result] $result
+    } \
+    -result {1 {integer value too large to represent*}}
+test expr-39.8 {Tcl_ExprLongObj handles overflows} testexprlongobj {
+    testexprlongobj -0x80000000
+} {This is a result: -2147483648}
+test expr-39.9 {Tcl_ExprLongObj handles overflows} {testexprlongobj longIs32bit} {
+    testexprlongobj -0xffffffff
+} {This is a result: 1}
+test expr-39.10 {Tcl_ExprLongObj handles overflows} \
+    -constraints {testexprlongobj longIs32bit} \
+    -match glob \
+    -body {
+	list [catch {testexprlongobj -0x100000000} result] $result
+    } \
+    -result {1 {integer value too large to represent*}}
+test expr-39.11 {Tcl_ExprLongObj handles overflows} {testexprlongobj longIs32bit} {
+    testexprlongobj 2147483648.
+} {This is a result: -2147483648}
+test expr-39.12 {Tcl_ExprLongObj handles overflows} {testexprlongobj longIs32bit} {
+    testexprlongobj 4294967295.
+} {This is a result: -1}
+test expr-39.13 {Tcl_ExprLongObj handles overflows} \
+    -constraints {testexprlongobj longIs32bit} \
+    -match glob \
+    -body {
+	list [catch {testexprlongobj 4294967296.} result] $result
+    } \
+    -result {1 {integer value too large to represent*}}
+test expr-39.14 {Tcl_ExprLongObj handles overflows} testexprlongobj {
+    testexprlongobj -2147483648.
+} {This is a result: -2147483648}
+test expr-39.15 {Tcl_ExprLongObj handles overflows} {testexprlongobj longIs32bit} {
+    testexprlongobj -4294967295.
+} {This is a result: 1}
+test expr-39.16 {Tcl_ExprLongObj handles overflows} \
+    -constraints {testexprlongobj longIs32bit} \
+    -match glob \
+    -body {
+	list [catch {testexprlongobj 4294967296.} result] $result
+    } \
+    -result {1 {integer value too large to represent*}}
+    
+test expr-39.17 {Check that Tcl_ExprDoubleObj doesn't modify interpreter result if no error} testexprdoubleobj {
+    testexprdoubleobj 4.+1.
+} {This is a result: 5.0}
+#Check for [Bug 1109484]
+test expr-39.18 {Tcl_ExprDoubleObj on the empty string} \
+    -constraints {testexprdoubleobj} \
+    -match glob \
+    -body {testexprdoubleobj ""} \
+    -returnCodes error -result *
+test expr-39.19 {Tcl_ExprDoubleObj coerces wides} testexprdoubleobj {
+    testexprdoubleobj 1[string repeat 0 17]
+} {This is a result: 1e+17}
+test expr-39.20 {Tcl_ExprDoubleObj coerces bignums} testexprdoubleobj {
+    testexprdoubleobj 1[string repeat 0 38]
+} {This is a result: 1e+38}
+test expr-39.21 {Tcl_ExprDoubleObj handles overflows} \
+    testexprdoubleobj&&ieeeFloatingPoint {
+	testexprdoubleobj 17976931348623157[string repeat 0 292].
+    } {This is a result: 1.7976931348623157e+308}
+test expr-39.22 {Tcl_ExprDoubleObj handles overflows that look like int} \
+    testexprdoubleobj&&ieeeFloatingPoint {
+	testexprdoubleobj 17976931348623157[string repeat 0 292]
+    } {This is a result: 1.7976931348623157e+308}
+test expr-39.23 {Tcl_ExprDoubleObj handles overflows} \
+    testexprdoubleobj&&ieeeFloatingPoint {
+	testexprdoubleobj 17976931348623165[string repeat 0 292].
+    } {This is a result: Inf}
+test expr-39.24 {Tcl_ExprDoubleObj handles overflows that look like int} \
+    testexprdoubleobj&&ieeeFloatingPoint {
+	testexprdoubleobj 17976931348623165[string repeat 0 292]
+    } {This is a result: Inf}
+test expr-39.25 {Tcl_ExprDoubleObj and NaN} \
+    {testexprdoubleobj ieeeFloatingPoint} {
+	list [catch {testexprdoubleobj 0.0/0.0} result] $result
+    } {1 {domain error: argument not in valid range}}
+
+test expr-40.1 {large octal shift} {
+    expr 0o100000000000000000000000000000000
+} [expr 0x1000000000000000000000000]
+test expr-40.2 {large octal shift} {
+    expr 0o100000000000000000000000000000001
+} [expr 0x1000000000000000000000001]
+
+test expr-41.1 {exponent overflow} {
+    expr 1.0e2147483630
+} Inf
+test expr-41.2 {exponent underflow} {
+    expr 1.0e-2147483630
+} 0.0
+
+test expr-42.1 {denormals} ieeeFloatingPoint {
+    expr 7e-324
+} 5e-324
+
+# TIP 114
+
+test expr-43.1 {0b notation} {
+    expr 0b0
+} 0
+test expr-43.2 {0b notation} {
+    expr 0b1
+} 1
+test expr-43.3 {0b notation} {
+    expr 0b10
+} 2
+test expr-43.4 {0b notation} {
+    expr 0b11
+} 3
+test expr-43.5 {0b notation} {
+    expr 0b100
+} 4
+test expr-43.6 {0b notation} {
+    expr 0b101
+} 5
+test expr-43.7 {0b notation} {
+    expr 0b1000
+} 8
+test expr-43.8 {0b notation} {
+    expr 0b1001
+} 9
+test expr-43.9 {0b notation} {
+    expr 0b1[string repeat 0 31]
+} 2147483648
+test expr-43.10 {0b notation} {
+    expr 0b1[string repeat 0 30]1
+} 2147483649
+test expr-43.11 {0b notation} {
+    expr 0b[string repeat 1 64]
+} 18446744073709551615
+test expr-43.12 {0b notation} {
+    expr 0b1[string repeat 0 64]
+} 18446744073709551616
+test expr-43.13 {0b notation} {
+    expr 0b1[string repeat 0 63]1
+} 18446744073709551617
+
+test expr-44.1 {0o notation} {
+    expr 0o0
+} 0
+test expr-44.2 {0o notation} {
+    expr 0o1
+} 1
+test expr-44.3 {0o notation} {
+    expr 0o7
+} 7
+test expr-44.4 {0o notation} {
+    expr 0o10
+} 8
+test expr-44.5 {0o notation} {
+    expr 0o11
+} 9
+test expr-44.6 {0o notation} {
+    expr 0o100
+} 64
+test expr-44.7 {0o notation} {
+    expr 0o101
+} 65
+test expr-44.8 {0o notation} {
+    expr 0o1000
+} 512
+test expr-44.9 {0o notation} {
+    expr 0o1001
+} 513
+test expr-44.10 {0o notation} {
+    expr 0o1[string repeat 7 21]
+} 18446744073709551615
+test expr-44.11 {0o notation} {
+    expr 0o2[string repeat 0 21]
+} 18446744073709551616
+test expr-44.12 {0o notation} {
+    expr 0o2[string repeat 0 20]1
+} 18446744073709551617
+
+# TIP 237 again
+
+test expr-45.1 {entier} {
+    expr entier(0)
+} 0
+test expr-45.2 {entier} {
+    expr entier(0.5)
+} 0
+test expr-45.3 {entier} {
+    expr entier(1.0)
+} 1
+test expr-45.4 {entier} {
+    expr entier(1.5)
+} 1
+test expr-45.5 {entier} {
+    expr entier(2.0)
+} 2
+test expr-45.6 {entier} {
+    expr entier(1e+22)
+} 10000000000000000000000
+test expr-45.7 {entier} {
+    list [catch {expr entier(Inf)} result] $result
+} {1 {integer value too large to represent}}
+test expr-45.8 {entier} ieeeFloatingPoint {
+    list [catch {expr {entier($ieeeValues(NaN))}} result] $result
+} {1 {floating point value is Not a Number}}
+test expr-45.9 {entier} ieeeFloatingPoint {
+    list [catch {expr {entier($ieeeValues(-NaN))}} result] $result
+} {1 {floating point value is Not a Number}}
+
+test expr-46.1 {round() rounds to +-infinity} {
+    expr round(0.5)
+} 1
+test expr-46.2 {round() rounds to +-infinity} {
+    expr round(1.5)
+} 2
+test expr-46.3 {round() rounds to +-infinity} {
+    expr round(-0.5)
+} -1
+test expr-46.4 {round() rounds to +-infinity} {
+    expr round(-1.5)
+} -2
+test expr-46.5 {round() overflow} {
+    expr round(9.2233720368547758e+018)
+} 9223372036854775808
+test expr-46.6 {round() overflow} {
+    expr round(-9.2233720368547758e+018)
+} -9223372036854775808
+test expr-46.7 {round() bad value} -body {
+    set x trash
+    expr {round($x)}
+} -returnCodes error -match glob -result *
+test expr-46.8 {round() already an integer} {
+    set x 123456789012
+    incr x
+    expr round($x)
+} 123456789013
+test expr-46.9 {round() boundary case - 1/2 - 1 ulp} {
+    set x 0.25
+    set bit 0.125
+    while 1 {
+	set newx [expr {$x + $bit}]
+	if { $newx == $x || $newx == 0.5 } break
+	set x $newx
+	set bit [expr { $bit / 2.0 }]
+    }
+    expr {round($x)}
+} 0
+test expr-46.10 {round() boundary case - 1/2 + 1 ulp} {
+    set x 0.75
+    set bit 0.125
+    while 1 {
+	set newx [expr {$x - $bit}]
+	if { $newx == $x || $newx == 0.5 } break
+	set x $newx
+	set bit [expr { $bit / 2.0 }]
+    }
+    expr {round($x)}
+} 1
+test expr-46.11 {round() boundary case - -1/2 - 1 ulp} {
+    set x -0.75
+    set bit 0.125
+    while 1 {
+	set newx [expr {$x + $bit}]
+	if { $newx == $x || $newx == -0.5 } break
+	set x $newx
+	set bit [expr { $bit / 2.0 }]
+    }
+    expr {round($x)}
+} -1
+test expr-46.12 {round() boundary case - -1/2 + 1 ulp} {
+    set x -0.25
+    set bit 0.125
+    while 1 {
+	set newx [expr {$x - $bit}]
+	if { $newx == $x || $newx == -0.5 } break
+	set x $newx
+	set bit [expr { $bit / 2.0 }]
+    }
+    expr {round($x)}
+} 0
+test expr-46.13 {round() boundary case - round down} {
+    expr {round(2147483647 - 0.51)}
+} 2147483646
+
+test expr-46.14 {round() boundary case - round up} {
+    expr {round(2147483647 - 0.50)}
+} 2147483647
+
+test expr-46.15 {round() boundary case - round up to wide} {
+    expr {round(2147483647 + 0.50)}
+} [expr {wide(2147483647) + 1}]
+
+test expr-46.16 {round() boundary case - round up} {
+    expr {round(-2147483648 + 0.51)}
+} -2147483647
+
+test expr-46.17 {round() boundary case - round down} {
+    expr {round(-2147483648 + 0.50)}
+} -2147483648
+test expr-46.18 {round() boundary case - round down to wide} {
+    expr {round(-2147483648 - 0.50)}
+} [expr {wide(-2147483648) - 1}]
+
+test expr-46.19 {round() handling of long/bignum boundary} {
+    expr {round(double(0x7fffffffffffffff))}
+} 9223372036854775808
+
+test expr-47.1 {isqrt() - arg count} {
+    list [catch {expr {isqrt(1,2)}} result] $result
+} {1 {too many arguments for math function "isqrt"}}
+
+test expr-47.2 {isqrt() - non-number} {
+    list [catch {expr {isqrt({rubbish})}} result] $result
+} {1 {expected number but got "rubbish"}}
+
+test expr-47.3 {isqrt() - NaN} ieeeFloatingPoint {
+    list [catch {expr {isqrt(NaN)}} result] $result
+} {1 {floating point value is Not a Number}}
+
+test expr-47.4 {isqrt() of negative floating point number} {
+    list [catch {expr {isqrt(-1.0)}} result] $result
+} {1 {square root of negative argument}}
+
+test expr-47.5 {isqrt() of floating point zero} {
+    expr isqrt(0.0)
+} 0
+
+test expr-47.6 {isqrt() of exact floating point numbers} {
+    set trouble {}
+    for {set i 0} {$i < 16} {incr i} {
+	set root [expr {1 << $i}]
+	set rm1 [expr {$root - 1}]
+	set arg [expr {pow(2., (2 * $i))}]
+	if {isqrt($arg-1) != $rm1} {
+	    append trouble "i = " $i ": isqrt( " $arg "-1) != " $rm1 "\n"
+	}
+	if {isqrt($arg) != $root} {
+	    append trouble "i = " $i ": isqrt( " $arg ") != " $root "\n"
+	}
+	if {isqrt($arg+1) != $root} {
+	    append trouble "i = " $i ": isqrt( " $arg "+1) != " $root "\n"
+	}
+    }
+    set trouble
+} {}
+
+test expr-47.7 {isqrt() of exact floating point numbers} ieeeFloatingPoint {
+    set trouble {}
+    for {set i 17} {$i < 27} {incr i} {
+	set root [expr {1 << $i}]
+	set rm1 [expr {$root - 1}]
+	set arg [expr {pow(2., (2 * $i))}]
+	if {isqrt($arg-1.0) != $rm1} {
+	    append trouble "i = " $i ": isqrt( " $arg "-1) != " $rm1 "\n"
+	}
+	if {isqrt($arg) != $root} {
+	    append trouble "i = " $i ": isqrt( " $arg ") != " $root "\n"
+	}
+	if {isqrt($arg+1.0) != $root} {
+	    append trouble "i = " $i ": isqrt( " $arg "+1) != " $root "\n"
+	}
+    }
+    set trouble
+} {}
+
+test expr-47.8 {isqrt of inexact floating point number} ieeeFloatingPoint {
+    expr isqrt(2[string repeat 0 34])
+} 141421356237309504
+
+test expr-47.9 {isqrt of negative int} {
+    list [catch {expr isqrt(-1)} result] $result
+} {1 {square root of negative argument}}
+
+test expr-47.10 {isqrt of negative bignum} {
+    list [catch {expr isqrt(-1[string repeat 0 1000])} result] $result
+} {1 {square root of negative argument}}
+
+test expr-47.11 {isqrt of zero} {
+    expr {isqrt(0)}
+} 0
+
+test expr-47.12 {isqrt of various sizes of integer} {
+    set faults 0
+    set trouble {}
+    for {set i 0} {$faults < 10 && $i <= 1024} {incr i} {
+	set root [expr {1 << $i}]
+	set rm1 [expr {$root - 1}]
+	set arg [expr {1 << (2 * $i)}]
+	set tval [expr {isqrt($arg-1)}]
+	if {$tval != $rm1} {
+	    append trouble "i = " $i ": isqrt(" $arg "-1) == " $tval \
+		" != " $rm1 "\n"
+	    incr faults
+	}
+	set tval [expr {isqrt($arg)}]
+	if {$tval != $root} {
+	    append trouble "i = " $i ": isqrt(" $arg ") == " $tval \
+		" != " $root "\n"
+	    incr faults
+	}
+	set tval [expr {isqrt($arg+1)}]
+	if {$tval != $root} {
+	    append trouble "i = " $i ": isqrt(" $arg "+1) == " $tval \
+		" != " $root "\n"
+	    incr faults
+	}
+    }
+    set trouble
+} {}
+
+test expr-47.13 {isqrt and floating point rounding (Bug 2143288)} {
+    set trouble {}
+    set faults 0
+    for {set i 0} {$i < 29 && $faults < 10} {incr i} {
+	for {set j 0} {$j <= $i} {incr j} {
+	    set k [expr {isqrt((1<<56)+(1<<$i)+(1<<$j))}]
+	    if {$k != (1<<28)} {
+		append trouble "i = $i, j = $j, k = $k\n"
+		incr faults
+	    }
+	}
+	set k [expr {isqrt((1<<56)+(1<<29)+(1<<$i))}]
+	if {$k != (1<<28)+1} {
+	    append trouble "i = $i, k = $k\n"
+	    incr faults
+	}
+    }
+    set trouble
+} {}
+
+test expr-48.1 {Bug 1770224} {
+    expr {-0x8000000000000001 >> 0x8000000000000000}
+} -1
+
+test expr-49.1 {Bug 2823282} {
+    coroutine foo apply {{} {set expr expr; $expr {[yield]}}}
+    foo 1
+} 1
+
+test expr-50.1 {test sqrt() of bignums with non-Inf answer} {
+    expr {sqrt("1[string repeat 0 616]") == 1e308}
+} 1
+
+test expr-51.1 {test round-to-even on input} {
+    expr 6.9294956446009195e15
+} 6929495644600920.0
+
+
+
+# cleanup
+if {[info exists a]} {
+    unset a
+}
+catch {unset min}
+catch {unset max}
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/tests/fCmd.test b/tests/fCmd.test
new file mode 100644
index 0000000..c8264b2
--- /dev/null
+++ b/tests/fCmd.test
@@ -0,0 +1,2608 @@
+# This file tests the tclFCmd.c file.
+#
+# This file contains a collection of tests for one or more of the Tcl built-in
+# commands. Sourcing this file into Tcl runs the tests and generates output
+# for errors. No output means no errors were found.
+#
+# Copyright (c) 1996-1997 Sun Microsystems, Inc.
+# Copyright (c) 1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution of
+# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {"::tcltest" ni [namespace children]} {
+    package require tcltest 2
+    namespace import -force ::tcltest::*
+}
+
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
+
+cd [temporaryDirectory]
+
+testConstraint testsetplatform [llength [info commands testsetplatform]]
+testConstraint testchmod [llength [info commands testchmod]]
+testConstraint winVista 0
+testConstraint win2000orXP 0
+# Don't know how to determine this constraint correctly
+testConstraint notNetworkFilesystem 0
+testConstraint reg 0
+if {[testConstraint win]} {
+    catch {
+	# Is the registry extension already static to this shell?
+	try {
+	    load {} Registry
+	    set ::reglib {}
+	} on error {} {
+	    # try the location given to use on the commandline to tcltest
+	    ::tcltest::loadTestedCommands
+	    load $::reglib Registry
+	}
+	testConstraint reg 1
+    }
+}
+
+set tmpspace /tmp;# default value
+# Find a group that exists on this Unix system, or else skip tests that
+# require Unix groups.
+testConstraint foundGroup [expr {![testConstraint unix]}]
+if {[testConstraint unix]} {
+    catch {
+	set groupList [exec groups]
+	set group [lindex $groupList 0]
+	testConstraint foundGroup 1
+    }
+
+    proc dev dir {
+	file stat $dir stat
+	return $stat(dev)
+    }
+
+    if {[catch {makeDirectory tcl[pid] /tmp} tmpspace] == 0} {
+	testConstraint xdev [expr {([dev .] != [dev $tmpspace])}]
+    }
+}
+
+# Also used in winFCmd...
+if {[testConstraint win]} {
+    set major [string index $tcl_platform(osVersion) 0]
+    if {[testConstraint nt] && $major > 4} {
+        if {$major > 5} {
+            testConstraint winVista 1
+        } elseif {$major == 5} {
+            testConstraint win2000orXP 1
+        }
+    }
+}
+
+testConstraint darwin9 [expr {
+    [testConstraint unix]
+    && $tcl_platform(os) eq "Darwin"
+    && [package vsatisfies 1.$tcl_platform(osVersion) 1.9]
+}]
+testConstraint notDarwin9 [expr {![testConstraint darwin9]}]
+
+testConstraint fileSharing 0
+testConstraint notFileSharing 1
+testConstraint linkFile 1
+testConstraint linkDirectory 1
+
+# Several tests require need to match results against the unix username
+set user {}
+if {[testConstraint unix]} {
+    catch {
+	set user [exec whoami]
+    }
+    if {$user eq ""} {
+	catch {
+	    regexp {^[^(]*\(([^)]*)\)} [exec id] -> user
+	}
+    }
+    if {$user eq ""} {
+	set user "root"
+    }
+}
+
+proc createfile {file {string a}} {
+    set f [open $file w]
+    puts -nonewline $f $string
+    close $f
+    return $string
+}
+
+#
+# checkcontent --
+#
+#  Ensures that file "file" contains only the string "matchString" returns 0
+#  if the file does not exist, or has a different content
+#
+proc checkcontent {file matchString} {
+    try {
+	set f [open $file]
+	set fileString [read $f]
+	close $f
+    } on error {} {
+	return 0
+    }
+    return [string match $matchString $fileString]
+}
+
+proc openup {path} {
+    testchmod 0o777 $path
+    if {[file isdirectory $path]} {
+	catch {
+	    foreach p [glob -directory $path *] {
+		openup $p
+	    }
+	}
+    }
+}
+
+proc cleanup {args} {
+    set wd [list .]
+    foreach p [concat $wd $args] {
+	set x ""
+	catch {
+	    set x [glob -directory $p tf* td*]
+	}
+	foreach file $x {
+	    if {
+		[catch {file delete -force -- $file}]
+		&& [testConstraint testchmod]
+	    } then {
+		catch {openup $file}
+		catch {file delete -force -- $file}
+	    }
+	}
+    }
+}
+
+proc contents {file} {
+    set f [open $file]
+    set r [read $f]
+    close $f
+    return $r
+}
+
+
+set root [lindex [file split [pwd]] 0]
+
+# A really long file name.
+# Length of long is 1216 chars, which should be greater than any static buffer
+# or allowable filename.
+
+set long "abcdefghihjllmnopqrstuvwxyz01234567890"
+append long $long
+append long $long
+append long $long
+append long $long
+append long $long
+
+test fCmd-1.1 {TclFileRenameCmd} -constraints {notRoot} -setup {
+    cleanup
+} -body {
+    createfile tf1
+    file rename tf1 tf2
+    glob tf*
+} -result {tf2}
+
+test fCmd-2.1 {TclFileCopyCmd} -constraints {notRoot} -setup {
+    cleanup
+} -body {
+    createfile tf1
+    file copy tf1 tf2
+    lsort [glob tf*]
+} -result {tf1 tf2}
+
+test fCmd-3.1 {FileCopyRename: FileForceOption fails} -constraints {notRoot} -body {
+    file rename -xyz
+} -returnCodes error -result {bad option "-xyz": must be -force or --}
+test fCmd-3.2 {FileCopyRename: not enough args} -constraints {notRoot} -body {
+    file rename xyz
+} -returnCodes error -result {wrong # args: should be "file rename ?-option value ...? source ?source ...? target"}
+test fCmd-3.3 {FileCopyRename: Tcl_TranslateFileName fails} -constraints {notRoot} -body {
+    file rename xyz ~_totally_bogus_user
+} -returnCodes error -result {user "_totally_bogus_user" doesn't exist}
+test fCmd-3.4 {FileCopyRename: Tcl_TranslateFileName passes} -setup {
+    cleanup
+} -constraints {notRoot} -returnCodes error -body {
+    file copy tf1 ~
+} -result {error copying "tf1": no such file or directory}
+test fCmd-3.5 {FileCopyRename: target doesn't exist: stat(target) != 0} -setup {
+    cleanup
+} -constraints {notRoot} -returnCodes error -body {
+    file rename tf1 tf2 tf3
+} -result {error renaming: target "tf3" is not a directory}
+test fCmd-3.6 {FileCopyRename: target tf3 is not a dir: !S_ISDIR(target)} -setup {
+    cleanup
+} -constraints {notRoot} -returnCodes error -body {
+    createfile tf3
+    file rename tf1 tf2 tf3
+} -result {error renaming: target "tf3" is not a directory}
+test fCmd-3.7 {FileCopyRename: target exists & is directory} -setup {
+    cleanup
+} -constraints {notRoot} -body {
+    file mkdir td1
+    createfile tf1 tf1
+    file rename tf1 td1
+    contents [file join td1 tf1]
+} -result {tf1}
+test fCmd-3.8 {FileCopyRename: too many arguments: argc - i > 2} -setup {
+    cleanup
+} -constraints {notRoot} -returnCodes error -body {
+    file rename tf1 tf2 tf3
+} -result {error renaming: target "tf3" is not a directory}
+test fCmd-3.9 {FileCopyRename: too many arguments: argc - i > 2} -setup {
+    cleanup
+} -constraints {notRoot} -returnCodes error -body {
+    file copy -force -- tf1 tf2 tf3
+} -result {error copying: target "tf3" is not a directory}
+test fCmd-3.10 {FileCopyRename: just 2 arguments} -constraints notRoot -setup {
+    cleanup
+} -body {
+    createfile tf1 tf1
+    file rename tf1 tf2
+    contents tf2
+} -result {tf1}
+test fCmd-3.11 {FileCopyRename: just 2 arguments} -constraints notRoot -setup {
+    cleanup
+} -body {
+    createfile tf1 tf1
+    file rename -force -force -- tf1 tf2
+    contents tf2
+} -result {tf1}
+test fCmd-3.12 {FileCopyRename: move each source: 1 source} -setup {
+    cleanup
+} -constraints {notRoot} -body {
+    createfile tf1 tf1
+    file mkdir td1
+    file rename tf1 td1
+    contents [file join td1 tf1]
+} -result {tf1}
+test fCmd-3.13 {FileCopyRename: move each source: multiple sources} -setup {
+    cleanup
+} -constraints {notRoot} -body {
+    createfile tf1 tf1
+    createfile tf2 tf2
+    createfile tf3 tf3
+    createfile tf4 tf4
+    file mkdir td1
+    file rename tf1 tf2 tf3 tf4 td1
+    list [contents [file join td1 tf1]] [contents [file join td1 tf2]] \
+	[contents [file join td1 tf3]] [contents [file join td1 tf4]]
+} -result {tf1 tf2 tf3 tf4}
+test fCmd-3.14 {FileCopyRename: FileBasename fails} -setup {
+    cleanup
+} -constraints {notRoot} -returnCodes error -body {
+    file mkdir td1
+    file rename ~_totally_bogus_user td1
+} -result {user "_totally_bogus_user" doesn't exist}
+test fCmd-3.15 {FileCopyRename: source[0] == '\0'} -setup {
+    cleanup
+} -constraints {notRoot unixOrPc} -returnCodes error -body {
+    file mkdir td1
+    file rename / td1
+} -result {error renaming "/" to "td1": file already exists}
+test fCmd-3.16 {FileCopyRename: break on first error} -setup {
+    cleanup
+} -constraints {notRoot} -returnCodes error -body {
+    createfile tf1
+    createfile tf2
+    createfile tf3
+    createfile tf4
+    file mkdir td1
+    createfile [file join td1 tf3]
+    file rename tf1 tf2 tf3 tf4 td1
+} -result [subst {error renaming "tf3" to "[file join td1 tf3]": file already exists}]
+
+test fCmd-4.1 {TclFileMakeDirsCmd: make each dir: 1 dir} -setup {
+    cleanup
+} -constraints {notRoot} -body {
+    file mkdir td1
+    glob td*
+} -result {td1}
+test fCmd-4.2 {TclFileMakeDirsCmd: make each dir: multiple dirs} -setup {
+    cleanup
+} -constraints {notRoot} -body {
+    file mkdir td1 td2 td3
+    lsort [glob td*]
+} -result {td1 td2 td3}
+test fCmd-4.3 {TclFileMakeDirsCmd: stops on first error} -setup {
+    cleanup
+} -constraints {notRoot} -body {
+    createfile tf1
+    catch {file mkdir td1 td2 tf1 td3 td4}
+    glob td1 td2 tf1 td3 td4
+} -result {td1 td2 tf1}
+test fCmd-4.4 {TclFileMakeDirsCmd: Tcl_TranslateFileName fails} -setup {
+    cleanup
+} -constraints {notRoot} -returnCodes error -body {
+    file mkdir ~_totally_bogus_user
+} -result {user "_totally_bogus_user" doesn't exist}
+test fCmd-4.5 {TclFileMakeDirsCmd: Tcl_SplitPath returns 0: *name == '\0'} -setup {
+    cleanup
+} -constraints {notRoot} -returnCodes error -body {
+    file mkdir ""
+} -result {can't create directory "": no such file or directory}
+test fCmd-4.6 {TclFileMakeDirsCmd: one level deep} -setup {
+    cleanup
+} -constraints {notRoot} -body {
+    file mkdir td1
+    glob td1
+} -result {td1}
+test fCmd-4.7 {TclFileMakeDirsCmd: multi levels deep} -setup {
+    cleanup
+} -constraints {notRoot} -body {
+    file mkdir [file join td1 td2 td3 td4]
+    glob td1 [file join td1 td2]
+} -result "td1 [file join td1 td2]"
+test fCmd-4.8 {TclFileMakeDirsCmd: already exist: lstat(target) == 0} -setup {
+    cleanup
+} -constraints {notRoot} -body {
+    file mkdir td1
+    set x [file exists td1]
+    file mkdir td1
+    list $x [file exists td1]
+} -result {1 1}
+test fCmd-4.9 {TclFileMakeDirsCmd: exists, not dir} -setup {
+    cleanup
+} -constraints {notRoot} -returnCodes error -body {
+    createfile tf1
+    file mkdir tf1
+} -result [subst {can't create directory "[file join tf1]": file already exists}]
+test fCmd-4.10 {TclFileMakeDirsCmd: exists, is dir} -setup {
+    cleanup
+} -constraints {notRoot} -body {
+    file mkdir td1
+    set x [file exists td1]
+    file mkdir td1
+    list $x [file exists td1]
+} -result {1 1}
+test fCmd-4.11 {TclFileMakeDirsCmd: doesn't exist: errno != ENOENT} -setup {
+    cleanup
+} -constraints {unix notRoot testchmod} -returnCodes error -body {
+    file mkdir td1/td2/td3
+    testchmod 0 td1/td2
+    file mkdir td1/td2/td3/td4
+} -cleanup {
+    testchmod 0o755 td1/td2
+    cleanup
+} -result {can't create directory "td1/td2/td3": permission denied}
+test fCmd-4.13 {TclFileMakeDirsCmd: doesn't exist: errno == ENOENT} -setup {
+    cleanup
+} -constraints {notRoot} -body {
+    set x [file exists td1]
+    file mkdir td1
+    list $x [file exists td1]
+} -result {0 1}
+test fCmd-4.14 {TclFileMakeDirsCmd: TclpCreateDirectory fails} -setup {
+    cleanup
+    file delete -force foo
+} -constraints {unix notRoot} -body {
+    file mkdir foo
+    file attr foo -perm 040000
+    file mkdir foo/tf1
+} -returnCodes error -cleanup {
+    file delete -force foo
+} -result {can't create directory "foo/tf1": permission denied}
+test fCmd-4.16 {TclFileMakeDirsCmd: TclpCreateDirectory succeeds} -setup {
+    cleanup
+} -constraints {notRoot} -body {
+    file mkdir tf1
+    file exists tf1
+} -result {1}
+
+test fCmd-5.1 {TclFileDeleteCmd: FileForceOption fails} -constraints {notRoot} -body {
+    file delete -xyz
+} -returnCodes error -result {bad option "-xyz": must be -force or --}
+test fCmd-5.2 {TclFileDeleteCmd: accept 0 files (TIP 323)} -body {
+    file delete -force -force
+} -result {}
+test fCmd-5.3 {TclFileDeleteCmd: 1 file} -constraints {notRoot} -setup {
+    cleanup
+} -body {
+    createfile tf1
+    createfile tf2
+    file mkdir td1
+    file delete tf2
+    glob tf* td*
+} -result {tf1 td1}
+test fCmd-5.4 {TclFileDeleteCmd: multiple files} -constraints notRoot -setup {
+    cleanup
+} -body {
+    createfile tf1
+    createfile tf2
+    file mkdir td1
+    set x [list [file exists tf1] [file exists tf2] [file exists td1]]
+    file delete tf1 td1 tf2
+    lappend x [file exists tf1] [file exists tf2] [file exists tf3]
+} -cleanup {cleanup} -result {1 1 1 0 0 0}
+test fCmd-5.5 {TclFileDeleteCmd: stop at first error} -setup {
+    cleanup
+} -constraints {notRoot unixOrPc} -body {
+    createfile tf1
+    createfile tf2
+    file mkdir td1
+    catch {file delete tf1 td1 $root tf2}
+    list [file exists tf1] [file exists tf2] [file exists td1]
+} -cleanup {cleanup} -result {0 1 0}
+test fCmd-5.6 {TclFileDeleteCmd: Tcl_TranslateFileName fails} -constraints {notRoot} -body {
+    file delete ~_totally_bogus_user
+} -returnCodes error -result {user "_totally_bogus_user" doesn't exist}
+test fCmd-5.7 {TclFileDeleteCmd: Tcl_TranslateFileName succeeds} -setup {
+    catch {file delete ~/tf1}
+} -constraints {notRoot} -body {
+    createfile ~/tf1
+    file delete ~/tf1
+} -result {}
+test fCmd-5.8 {TclFileDeleteCmd: file doesn't exist: lstat(name) != 0} -setup {
+    cleanup
+} -constraints {notRoot} -body {
+    set x [file exists tf1]
+    file delete tf1
+    list $x [file exists tf1]
+} -result {0 0}
+test fCmd-5.9 {TclFileDeleteCmd: is directory} -constraints {notRoot} -setup {
+    cleanup
+} -body {
+    file mkdir td1
+    file delete td1
+    file exists td1
+} -result {0}
+test fCmd-5.10 {TclFileDeleteCmd: TclpRemoveDirectory fails} -setup {
+    cleanup
+} -constraints {notRoot} -returnCodes error -body {
+    file mkdir [file join td1 td2]
+    file delete td1
+} -result {error deleting "td1": directory not empty}
+test fCmd-5.11 {TclFileDeleteCmd: TclpRemoveDirectory with cwd inside} -setup {
+    cleanup
+    set dir [pwd]
+} -constraints {notRoot} -body {
+    file mkdir [file join td1 td2]
+    cd [file join td1 td2]
+    set res [list [catch {file delete -force [file dirname [pwd]]} msg]]
+    cd $dir
+    lappend res [file exists td1] $msg
+} -cleanup {
+    cd $dir
+} -result {0 0 {}}
+test fCmd-5.12 {TclFileDeleteCmd: TclpRemoveDirectory with bad perms} -setup {
+    cleanup
+} -constraints {unix} -body {
+    file mkdir [file join td1 td2]
+    file attributes [file join td1 td2] -permissions u+rwx
+    set res [list [catch {file delete -force td1} msg]]
+    lappend res [file exists td1] $msg
+} -result {0 0 {}}
+
+test fCmd-6.1 {CopyRenameOneFile: bad source} {notRoot emptyTest} {
+    # can't test this, because it's caught by FileCopyRename
+} {}
+test fCmd-6.2 {CopyRenameOneFile: bad target} {notRoot emptyTest} {
+    # can't test this, because it's caught by FileCopyRename
+} {}
+test fCmd-6.3 {CopyRenameOneFile: lstat(source) != 0} -setup {
+    cleanup
+} -constraints {notRoot} -returnCodes error -body {
+    file rename tf1 tf2
+} -result {error renaming "tf1": no such file or directory}
+test fCmd-6.4 {CopyRenameOneFile: lstat(source) == 0} -setup {
+    cleanup
+} -constraints {notRoot} -body {
+    createfile tf1
+    file rename tf1 tf2
+    glob tf*
+} -result {tf2}
+test fCmd-6.5 {CopyRenameOneFile: lstat(target) != 0} -setup {
+    cleanup
+} -constraints {notRoot} -body {
+    createfile tf1
+    file rename tf1 tf2
+    glob tf*
+} -result {tf2}
+test fCmd-6.6 {CopyRenameOneFile: errno != ENOENT} -setup {
+    cleanup
+} -constraints {unix notRoot testchmod} -body {
+    file mkdir td1
+    testchmod 0 td1
+    createfile tf1
+    file rename tf1 td1
+} -returnCodes error -cleanup {
+    testchmod 0o755 td1
+} -result {error renaming "tf1" to "td1/tf1": permission denied}
+test fCmd-6.9 {CopyRenameOneFile: errno == ENOENT} -setup {
+    cleanup
+} -constraints {unix notRoot} -body {
+    createfile tf1
+    file rename tf1 tf2
+    glob tf*
+} -result {tf2}
+test fCmd-6.10 {CopyRenameOneFile: lstat(target) == 0} -setup {
+    cleanup
+} -constraints {notRoot} -returnCodes error -body {
+    createfile tf1
+    createfile tf2
+    file rename tf1 tf2
+} -result {error renaming "tf1" to "tf2": file already exists}
+test fCmd-6.11 {CopyRenameOneFile: force == 0} -setup {
+    cleanup
+} -constraints {notRoot} -returnCodes error -body {
+    createfile tf1
+    createfile tf2
+    file rename tf1 tf2
+} -result {error renaming "tf1" to "tf2": file already exists}
+test fCmd-6.12 {CopyRenameOneFile: force != 0} -setup {
+    cleanup
+} -constraints {notRoot} -body {
+    createfile tf1
+    createfile tf2
+    file rename -force tf1 tf2
+    glob tf*
+} -result {tf2}
+test fCmd-6.13 {CopyRenameOneFile: source is dir, target is file} -setup {
+    cleanup
+} -constraints {notRoot} -returnCodes error -body {
+    file mkdir td1
+    file mkdir td2
+    createfile [file join td2 td1]
+    file rename -force td1 td2
+} -result [subst {can't overwrite file "[file join td2 td1]" with directory "td1"}]
+test fCmd-6.14 {CopyRenameOneFile: source is file, target is dir} -setup {
+    cleanup
+} -constraints {notRoot} -returnCodes error -body {
+    createfile tf1
+    file mkdir [file join td1 tf1]
+    file rename -force tf1 td1
+} -result [subst {can't overwrite directory "[file join td1 tf1]" with file "tf1"}]
+test fCmd-6.15 {CopyRenameOneFile: TclpRenameFile succeeds} -setup {
+    cleanup
+} -constraints {notRoot notNetworkFilesystem} -body {
+    file mkdir [file join td1 td2]
+    file mkdir td2
+    createfile [file join td2 tf1]
+    file rename -force td2 td1
+    file exists [file join td1 td2 tf1]
+} -result 1
+test fCmd-6.16 {CopyRenameOneFile: TclpCopyRenameOneFile fails} -setup {
+    cleanup
+} -constraints {notRoot} -body {
+    file mkdir [file join td1 td2]
+    createfile [file join td1 td2 tf1]
+    file mkdir td2
+    file rename -force td2 td1
+} -returnCodes error -match glob -result \
+    [subst {error renaming "td2" to "[file join td1 td2]": file *}]
+test fCmd-6.17 {CopyRenameOneFile: errno == EINVAL} -setup {
+    cleanup
+} -constraints {notRoot} -returnCodes error -body {
+    file rename -force $root tf1
+} -result [subst {error renaming "$root" to "tf1": trying to rename a volume or move a directory into itself}]
+test fCmd-6.18 {CopyRenameOneFile: errno != EXDEV} -setup {
+    cleanup
+} -constraints {notRoot} -body {
+    file mkdir [file join td1 td2]
+    createfile [file join td1 td2 tf1]
+    file mkdir td2
+    file rename -force td2 td1
+} -returnCodes error -match glob -result \
+    [subst {error renaming "td2" to "[file join td1 td2]": file *}]
+test fCmd-6.19 {CopyRenameOneFile: errno == EXDEV} -setup {
+    cleanup $tmpspace
+} -constraints {unix notRoot} -body {
+    createfile tf1
+    file rename tf1 $tmpspace
+    glob -nocomplain tf* [file join $tmpspace tf1]
+} -result [file join $tmpspace tf1]
+test fCmd-6.20 {CopyRenameOneFile: errno == EXDEV} -constraints {win} -setup {
+    catch {file delete -force c:/tcl8975@ d:/tcl8975@}
+} -body {
+    file mkdir c:/tcl8975@
+    if {[catch {file rename c:/tcl8975@ d:/}]} {
+	return d:/tcl8975@
+    }
+    glob c:/tcl8975@ d:/tcl8975@
+} -cleanup {
+    file delete -force c:/tcl8975@
+    catch {file delete -force d:/tcl8975@}
+} -result {d:/tcl8975@}
+test fCmd-6.21 {CopyRenameOneFile: copy/rename: S_ISDIR(source)} -setup {
+    cleanup $tmpspace
+} -constraints {unix notRoot} -body {
+    file mkdir td1
+    file rename td1 $tmpspace
+    glob -nocomplain td* [file join $tmpspace td*]
+} -result [file join $tmpspace td1]
+test fCmd-6.22 {CopyRenameOneFile: copy/rename: !S_ISDIR(source)} -setup {
+    cleanup $tmpspace
+} -constraints {unix notRoot} -body {
+    createfile tf1
+    file rename tf1 $tmpspace
+    glob -nocomplain tf* [file join $tmpspace tf*]
+} -result [file join $tmpspace tf1]
+test fCmd-6.23 {CopyRenameOneFile: TclpCopyDirectory failed} -setup {
+    cleanup $tmpspace
+} -constraints {xdev notRoot} -body {
+    file mkdir td1/td2/td3
+    file attributes td1 -permissions 0000
+    file rename td1 $tmpspace
+} -returnCodes error -cleanup {
+    file attributes td1 -permissions 0755
+    cleanup
+} -match regexp -result {^error renaming "td1"( to "/tmp/tcl\d+/td1")?: permission denied$}
+test fCmd-6.24 {CopyRenameOneFile: error uses original name} -setup {
+    cleanup
+} -constraints {unix notRoot} -body {
+    file mkdir ~/td1/td2
+    set td1name [file join [file dirname ~] [file tail ~] td1]
+    file attributes $td1name -permissions 0000
+    file copy ~/td1 td1
+} -returnCodes error -cleanup {
+    file attributes $td1name -permissions 0755
+    file delete -force ~/td1
+} -result {error copying "~/td1": permission denied}
+test fCmd-6.25 {CopyRenameOneFile: error uses original name} -setup {
+    cleanup
+} -constraints {unix notRoot} -body {
+    file mkdir td2
+    file mkdir ~/td1
+    set td1name [file join [file dirname ~] [file tail ~] td1]
+    file attributes $td1name -permissions 0000
+    file copy td2 ~/td1
+} -returnCodes error -cleanup {
+    file attributes $td1name -permissions 0755
+    file delete -force ~/td1
+} -result {error copying "td2" to "~/td1/td2": permission denied}
+test fCmd-6.26 {CopyRenameOneFile: doesn't use original name} -setup {
+    cleanup
+} -constraints {unix notRoot} -body {
+    file mkdir ~/td1/td2
+    set td2name [file join [file dirname ~] [file tail ~] td1 td2]
+    file attributes $td2name -permissions 0000
+    file copy ~/td1 td1
+} -returnCodes error -cleanup {
+    file attributes $td2name -permissions 0755
+    file delete -force ~/td1
+} -result "error copying \"~/td1\" to \"td1\": \"[file join $::env(HOME) td1 td2]\": permission denied"
+test fCmd-6.27 {CopyRenameOneFile: TclpCopyDirectory failed} -setup {
+    cleanup $tmpspace
+} -constraints {notRoot xdev} -returnCodes error -body {
+    file mkdir td1/td2/td3
+    file mkdir [file join $tmpspace td1]
+    createfile [file join $tmpspace td1 tf1]
+    file rename -force td1 $tmpspace
+} -match glob -result {error renaming "td1" to "/tmp/tcl*/td1": file already exists}
+test fCmd-6.28 {CopyRenameOneFile: TclpCopyDirectory failed} -setup {
+    cleanup $tmpspace
+} -constraints {notRoot xdev} -body {
+    file mkdir td1/td2/td3
+    file attributes td1/td2/td3 -permissions 0000
+    file rename td1 $tmpspace
+} -returnCodes error -cleanup {
+    file attributes td1/td2/td3 -permissions 0755
+    cleanup $tmpspace
+} -match glob -result {error renaming "td1" to "/tmp/tcl*/td1": "td1/td2/td3": permission denied}
+test fCmd-6.29 {CopyRenameOneFile: TclpCopyDirectory passed} -setup {
+    cleanup $tmpspace
+} -constraints {notRoot xdev} -body {
+    file mkdir td1/td2/td3
+    file rename td1 $tmpspace
+    glob td* [file join $tmpspace td1 t*]
+} -result [file join $tmpspace td1 td2]
+test fCmd-6.30 {CopyRenameOneFile: TclpRemoveDirectory failed} -setup {
+    cleanup $tmpspace
+} -constraints {unix notRoot} -body {
+    file mkdir foo/bar
+    file attr foo -perm 040555
+    file rename foo/bar $tmpspace
+} -returnCodes error -cleanup {
+    catch {file delete [file join $tmpspace bar]}
+    catch {file attr foo -perm 040777}
+    catch {file delete -force foo}
+} -match glob -result {*: permission denied}
+test fCmd-6.31 {CopyRenameOneFile: TclpDeleteFile passed} -setup {
+    cleanup $tmpspace
+} -constraints {notRoot xdev} -body {
+    file mkdir [file join $tmpspace td1]
+    createfile [file join $tmpspace td1 tf1]
+    file rename [file join $tmpspace td1 tf1] tf1
+    list [file exists [file join $tmpspace td1 tf1]] [file exists tf1]
+} -result {0 1}
+test fCmd-6.32 {CopyRenameOneFile: copy} -constraints {notRoot} -setup {
+    cleanup
+} -returnCodes error -body {
+    file copy tf1 tf2
+} -result {error copying "tf1": no such file or directory}
+
+test fCmd-7.1 {FileForceOption: none} -constraints {notRoot} -setup {
+    cleanup
+} -returnCodes error -body {
+    file mkdir [file join tf1 tf2]
+    file delete tf1
+} -result {error deleting "tf1": directory not empty}
+test fCmd-7.2 {FileForceOption: -force} -constraints {notRoot} -setup {
+    cleanup
+} -body {
+    file mkdir [file join tf1 tf2]
+    file delete -force tf1
+} -result {}
+test fCmd-7.3 {FileForceOption: --} -constraints {notRoot} -body {
+    createfile -tf1
+    file delete -- -tf1
+} -result {}
+test fCmd-7.4 {FileForceOption: bad option} -constraints {notRoot} -setup {
+    createfile -tf1
+} -body {
+    file delete -tf1
+} -returnCodes error -cleanup {
+    file delete -- -tf1
+} -result {bad option "-tf1": must be -force or --}
+test fCmd-7.5 {FileForceOption: multiple times through loop} -setup {
+    cleanup
+} -constraints {notRoot} -returnCodes error -body {
+    createfile --
+    createfile -force
+    file delete -force -force -- -- -force
+    glob -- -- -force
+} -result {no files matched glob patterns "-- -force"}
+
+test fCmd-8.1 {FileBasename: basename of ~user: argc == 1 && *path == ~} \
+    -constraints {unix notRoot knownBug} -body {
+    # Labelled knownBug because it is dangerous [Bug: 3881]
+    file mkdir td1
+    file attr td1 -perm 040000
+    file rename ~$user td1
+} -returnCodes error -cleanup {
+    file delete -force td1
+} -result "error renaming \"~$user\" to \"td1/[file tail ~$user]\": permission denied"
+test fCmd-8.2 {FileBasename: basename of ~user: argc == 1 && *path == ~} \
+	-constraints {unix notRoot} -body {
+    string equal [file tail ~$user] ~$user
+} -result 0
+test fCmd-8.3 {file copy and path translation: ensure correct error} -body {
+    file copy ~ [file join this file doesnt exist]
+} -returnCodes error -result [subst \
+	{error copying "~" to "[file join this file doesnt exist]": no such file or directory}]
+
+test fCmd-9.1 {file rename: comprehensive: EACCES} -setup {
+    cleanup
+} -constraints {unix notRoot} -body {
+    file mkdir td1
+    file mkdir td2
+    file attr td2 -perm 040000
+    file rename td1 td2/
+} -returnCodes error -cleanup {
+    file delete -force td2
+    file delete -force td1
+} -result {error renaming "td1" to "td2/td1": permission denied}
+test fCmd-9.2 {file rename: comprehensive: source doesn't exist} -setup {
+    cleanup
+} -constraints {notRoot} -returnCodes error -body {
+    file rename tf1 tf2
+} -result {error renaming "tf1": no such file or directory}
+test fCmd-9.3 {file rename: comprehensive: file to new name} -setup {
+    cleanup
+} -constraints {notRoot testchmod} -body {
+    createfile tf1
+    createfile tf2
+    testchmod 0o444 tf2
+    file rename tf1 tf3
+    file rename tf2 tf4
+    list [lsort [glob tf*]] [file writable tf3] [file writable tf4]
+} -result {{tf3 tf4} 1 0}
+test fCmd-9.4.a {file rename: comprehensive: dir to new name} -setup {
+    cleanup
+} -constraints {win win2000orXP testchmod} -body {
+    file mkdir td1 td2
+    testchmod 0o555 td2
+    file rename td1 td3
+    file rename td2 td4
+    list [lsort [glob td*]] [file writable td3] [file writable td4]
+} -cleanup {
+    cleanup
+} -result {{td3 td4} 1 0}
+test fCmd-9.4.b {file rename: comprehensive: dir to new name} -setup {
+    cleanup
+} -constraints {unix notRoot testchmod notDarwin9} -body {
+    file mkdir td1 td2
+    testchmod 0o555 td2
+    file rename td1 td3
+    file rename td2 td4
+    list [lsort [glob td*]] [file writable td3] [file writable td4]
+} -cleanup {
+    cleanup
+} -result {{td3 td4} 1 0}
+test fCmd-9.5 {file rename: comprehensive: file to self} -setup {
+    cleanup
+} -constraints {notRoot testchmod} -body {
+    createfile tf1 tf1
+    createfile tf2 tf2
+    testchmod 0o444 tf2
+    file rename -force tf1 tf1
+    file rename -force tf2 tf2
+    list [contents tf1] [contents tf2] [file writable tf1] [file writable tf2]
+} -result {tf1 tf2 1 0}
+test fCmd-9.6.a {file rename: comprehensive: dir to self} -setup {
+    cleanup
+} -constraints {win win2000orXP testchmod} -body {
+    file mkdir td1
+    file mkdir td2
+    testchmod 0o555 td2
+    file rename -force td1 .
+    file rename -force td2 .
+    list [lsort [glob td*]] [file writable td1] [file writable td2]
+} -result {{td1 td2} 1 0}
+test fCmd-9.6.b {file rename: comprehensive: dir to self} -setup {
+    cleanup
+} -constraints {unix notRoot testchmod} -body {
+    file mkdir td1
+    file mkdir td2
+    testchmod 0o555 td2
+    file rename -force td1 .
+    file rename -force td2 .
+    list [lsort [glob td*]] [file writable td1] [file writable td2]
+} -result {{td1 td2} 1 0}
+test fCmd-9.7 {file rename: comprehensive: file to existing file} -setup {
+    cleanup
+} -constraints {notRoot testchmod} -body {
+    createfile tf1
+    createfile tf2
+    createfile tfs1
+    createfile tfs2
+    createfile tfs3
+    createfile tfs4
+    createfile tfd1
+    createfile tfd2
+    createfile tfd3
+    createfile tfd4
+    testchmod 0o444 tfs3
+    testchmod 0o444 tfs4
+    testchmod 0o444 tfd2
+    testchmod 0o444 tfd4
+    set msg [list [catch {file rename tf1 tf2} msg] $msg]
+    file rename -force tfs1 tfd1
+    file rename -force tfs2 tfd2
+    file rename -force tfs3 tfd3
+    file rename -force tfs4 tfd4
+    list [lsort [glob tf*]] $msg [file writable tfd1] [file writable tfd2] [file writable tfd3] [file writable tfd4]
+} -result {{tf1 tf2 tfd1 tfd2 tfd3 tfd4} {1 {error renaming "tf1" to "tf2": file already exists}} 1 1 0 0}
+test fCmd-9.8 {file rename: comprehensive: dir to empty dir} -setup {
+    cleanup
+} -constraints {notRoot testchmod notNetworkFilesystem} -body {
+    # Under unix, you can rename a read-only directory, but you can't move it
+    # into another directory.
+    file mkdir td1
+    file mkdir [file join td2 td1]
+    file mkdir tds1
+    file mkdir tds2
+    file mkdir tds3
+    file mkdir tds4
+    file mkdir [file join tdd1 tds1]
+    file mkdir [file join tdd2 tds2]
+    file mkdir [file join tdd3 tds3]
+    file mkdir [file join tdd4 tds4]
+    if {![testConstraint unix]} {
+	testchmod 0o555 tds3
+	testchmod 0o555 tds4
+    }
+    testchmod 0o555 [file join tdd2 tds2]
+    testchmod 0o555 [file join tdd4 tds4]
+    set msg [list [catch {file rename td1 td2} msg] $msg]
+    file rename -force tds1 tdd1
+    file rename -force tds2 tdd2
+    file rename -force tds3 tdd3
+    file rename -force tds4 tdd4
+    if {[testConstraint unix]} {
+	set w3 0
+	set w4 0
+    } else {
+	set w3 [file writable [file join tdd3 tds3]]
+	set w4 [file writable [file join tdd4 tds4]]
+    }
+    list [lsort [glob td*]] $msg [file writable [file join tdd1 tds1]] \
+    [file writable [file join tdd2 tds2]] $w3 $w4
+} -result [subst {{td1 td2 tdd1 tdd2 tdd3 tdd4} {1 {error renaming "td1" to "[file join td2 td1]": file already exists}} 1 1 0 0}]
+# Test can hit EEXIST or EBUSY, depending on underlying filesystem
+test fCmd-9.9 {file rename: comprehensive: dir to non-empty dir} -setup {
+    cleanup
+} -constraints {notRoot testchmod} -body {
+    file mkdir tds1
+    file mkdir tds2
+    file mkdir [file join tdd1 tds1 xxx]
+    file mkdir [file join tdd2 tds2 xxx]
+    if {!([testConstraint unix] || [testConstraint winVista])} {
+	testchmod 0o555 tds2
+    }
+    set a1 [list [catch {file rename -force tds1 tdd1} msg] $msg]
+    set a2 [list [catch {file rename -force tds2 tdd2} msg] $msg]
+    if {[testConstraint unix] || [testConstraint winVista]} {
+	set w2 0
+    } else {
+	set w2 [file writable tds2]
+    }
+    list [lsort [glob td*]] $a1 $a2 [file writable tds1] $w2
+} -match glob -result \
+    [subst {{tdd1 tdd2 tds1 tds2} {1 {error renaming "tds1" to "[file join tdd1 tds1]": file *}} {1 {error renaming "tds2" to "[file join tdd2 tds2]": file *}} 1 0}]
+test fCmd-9.10 {file rename: comprehensive: file to new name and dir} -setup {
+    cleanup
+} -constraints {notRoot testchmod} -body {
+    createfile tf1
+    createfile tf2
+    file mkdir td1
+    testchmod 0o444 tf2
+    file rename tf1 [file join td1 tf3]
+    file rename tf2 [file join td1 tf4]
+    list [catch {glob tf*}] [lsort [glob -directory td1 t*]] \
+    [file writable [file join td1 tf3]] [file writable [file join td1 tf4]]
+} -result [subst {1 {[file join td1 tf3] [file join td1 tf4]} 1 0}]
+test fCmd-9.11 {file rename: comprehensive: dir to new name and dir} -setup {
+    cleanup
+} -constraints {notRoot testchmod} -body {
+    file mkdir td1
+    file mkdir td2
+    file mkdir td3
+    if {!([testConstraint unix] || [testConstraint winVista])} {
+	testchmod 0o555 td2
+    }
+    file rename td1 [file join td3 td3]
+    file rename td2 [file join td3 td4]
+    if {[testConstraint unix] || [testConstraint winVista]} {
+        set w4 0
+    } else {
+	set w4 [file writable [file join td3 td4]]
+    }
+    list [lsort [glob td*]] [lsort [glob -directory td3 t*]] \
+    [file writable [file join td3 td3]] $w4
+} -result [subst {td3 {[file join td3 td3] [file join td3 td4]} 1 0}]
+test fCmd-9.12 {file rename: comprehensive: target exists} -setup {
+    cleanup
+} -constraints {notRoot testchmod notNetworkFilesystem} -body {
+    file mkdir [file join td1 td2] [file join td2 td1]
+    testchmod 0o555 [file join td2 td1]
+    file mkdir [file join td3 td4] [file join td4 td3]
+    file rename -force td3 td4
+    list [file exists td3] [file exists [file join td4 td3 td4]] \
+	[catch {file rename td1 td2} msg] $msg
+} -cleanup {
+    testchmod 0o755 [file join td2 td1]
+} -result [subst {0 1 1 {error renaming "td1" to "[file join td2 td1]": file already exists}}]
+# Test can hit EEXIST or EBUSY, depending on underlying filesystem
+test fCmd-9.13 {file rename: comprehensive: can't overwrite target} -setup {
+    cleanup
+} -constraints {notRoot} -body {
+    file mkdir [file join td1 td2] [file join td2 td1 td4]
+    file rename -force td1 td2
+} -returnCodes error -match glob -result \
+    [subst {error renaming "td1" to "[file join td2 td1]": file *}]
+test fCmd-9.14 {file rename: comprehensive: dir into self} -setup {
+    cleanup
+} -constraints {notRoot} -body {
+    file mkdir td1
+    list [glob td*] [list [catch {file rename td1 td1} msg] $msg]
+} -result [subst {td1 {1 {error renaming "td1" to "[file join td1 td1]": trying to rename a volume or move a directory into itself}}}]
+test fCmd-9.14.1 {file rename: comprehensive: dir into self} -setup {
+    cleanup
+} -constraints {notRoot} -body {
+    file mkdir td1
+    file rename td1 td1x
+    file rename td1x td1
+    set msg "ok"
+} -result {ok}
+test fCmd-9.14.2 {file rename: comprehensive: dir into self} -setup {
+    cleanup
+    set dir [pwd]
+} -constraints {nonPortable notRoot} -body {
+    file mkdir td1
+    cd td1
+    file rename [file join .. td1] [file join .. td1x]
+} -returnCodes error -cleanup {
+    cd $dir
+} -result [subst {error renaming "[file join .. td1]" to "[file join .. td1x]": permission denied}]
+test fCmd-9.14.3 {file rename: comprehensive: dir into self} -setup {
+    cleanup
+    set dir [pwd]
+} -constraints {notRoot} -body {
+    file mkdir td1
+    cd td1
+    file rename [file join .. td1] [file join .. td1 foo]
+} -returnCodes error -cleanup {
+    cd $dir
+} -result [subst {error renaming "[file join .. td1]" to "[file join .. td1 foo]": trying to rename a volume or move a directory into itself}]
+test fCmd-9.15 {file rename: comprehensive: source and target incompatible} -setup {
+    cleanup
+} -constraints {notRoot} -returnCodes error -body {
+    file mkdir td1
+    createfile tf1
+    file rename -force td1 tf1
+} -cleanup {
+    cleanup
+} -result {can't overwrite file "tf1" with directory "td1"}
+test fCmd-9.16 {file rename: comprehensive: source and target incompatible} -setup {
+    cleanup
+} -constraints {notRoot} -returnCodes error -body {
+    file mkdir td1/tf1
+    createfile tf1
+    file rename -force tf1 td1
+} -result [subst {can't overwrite directory "[file join td1 tf1]" with file "tf1"}]
+
+test fCmd-10.1 {file copy: comprehensive: source doesn't exist} -setup {
+    cleanup
+} -constraints {notRoot} -returnCodes error -body {
+    file copy tf1 tf2
+} -result {error copying "tf1": no such file or directory}
+test fCmd-10.2 {file copy: comprehensive: file to new name} -setup {
+    cleanup
+} -constraints {notRoot testchmod} -body {
+    createfile tf1 tf1
+    createfile tf2 tf2
+    testchmod 0o444 tf2
+    file copy tf1 tf3
+    file copy tf2 tf4
+    list [lsort [glob tf*]] [contents tf3] [contents tf4] [file writable tf3] [file writable tf4]
+} -result {{tf1 tf2 tf3 tf4} tf1 tf2 1 0}
+test fCmd-10.3 {file copy: comprehensive: dir to new name} -setup {
+    cleanup
+} -constraints {unix notRoot testchmod} -body {
+    file mkdir [file join td1 tdx]
+    file mkdir [file join td2 tdy]
+    testchmod 0o555 td2
+    file copy td1 td3
+    file copy td2 td4
+    list [lsort [glob td*]] [glob -directory td3 t*] \
+	    [glob -directory td4 t*] [file writable td3] [file writable td4]
+} -cleanup {
+    testchmod 0o755 td2
+    testchmod 0o755 td4
+} -result [list {td1 td2 td3 td4} [file join td3 tdx] [file join td4 tdy] 1 0]
+test fCmd-10.3.1 {file copy: comprehensive: dir to new name} -setup {
+    cleanup
+} -constraints {win notRoot testchmod} -body {
+    # On Windows with ACLs, copying a directory is defined like this
+    file mkdir [file join td1 tdx]
+    file mkdir [file join td2 tdy]
+    testchmod 0o555 td2
+    file copy td1 td3
+    file copy td2 td4
+    list [lsort [glob td*]] [glob -directory td3 t*] \
+	    [glob -directory td4 t*] [file writable td3] [file writable td4]
+} -cleanup {
+    testchmod 0o755 td2
+    testchmod 0o755 td4
+} -result [list {td1 td2 td3 td4} [file join td3 tdx] [file join td4 tdy] 1 1]
+test fCmd-10.4 {file copy: comprehensive: file to existing file} -setup {
+    cleanup
+} -constraints {notRoot testchmod} -body {
+    createfile tf1
+    createfile tf2
+    createfile tfs1
+    createfile tfs2
+    createfile tfs3
+    createfile tfs4
+    createfile tfd1
+    createfile tfd2
+    createfile tfd3
+    createfile tfd4
+    testchmod 0o444 tfs3
+    testchmod 0o444 tfs4
+    testchmod 0o444 tfd2
+    testchmod 0o444 tfd4
+    set msg [list [catch {file copy tf1 tf2} msg] $msg]
+    file copy -force tfs1 tfd1
+    file copy -force tfs2 tfd2
+    file copy -force tfs3 tfd3
+    file copy -force tfs4 tfd4
+    list [lsort [glob tf*]] $msg [file writable tfd1] [file writable tfd2] [file writable tfd3] [file writable tfd4]
+} -result {{tf1 tf2 tfd1 tfd2 tfd3 tfd4 tfs1 tfs2 tfs3 tfs4} {1 {error copying "tf1" to "tf2": file already exists}} 1 1 0 0}
+test fCmd-10.5 {file copy: comprehensive: dir to empty dir} -setup {
+    cleanup
+} -constraints {notRoot testchmod} -body {
+    file mkdir td1
+    file mkdir [file join td2 td1]
+    file mkdir tds1
+    file mkdir tds2
+    file mkdir tds3
+    file mkdir tds4
+    file mkdir [file join tdd1 tds1]
+    file mkdir [file join tdd2 tds2]
+    file mkdir [file join tdd3 tds3]
+    file mkdir [file join tdd4 tds4]
+    testchmod 0o555 tds3
+    testchmod 0o555 tds4
+    testchmod 0o555 [file join tdd2 tds2]
+    testchmod 0o555 [file join tdd4 tds4]
+    set a1 [list [catch {file copy td1 td2} msg] $msg]
+    set a2 [list [catch {file copy -force tds1 tdd1} msg] $msg]
+    set a3 [catch {file copy -force tds2 tdd2}]
+    set a4 [catch {file copy -force tds3 tdd3}]
+    set a5 [catch {file copy -force tds4 tdd4}]
+    list [lsort [glob td*]] $a1 $a2 $a3 $a4 $a5
+} -result [subst {{td1 td2 tdd1 tdd2 tdd3 tdd4 tds1 tds2 tds3 tds4} {1 {error copying "td1" to "[file join td2 td1]": file already exists}} {1 {error copying "tds1" to "[file join tdd1 tds1]": file already exists}} 1 1 1}]
+test fCmd-10.6 {file copy: comprehensive: dir to non-empty dir} -setup {
+    cleanup
+} -constraints {notRoot unixOrPc testchmod} -body {
+    file mkdir tds1
+    file mkdir tds2
+    file mkdir [file join tdd1 tds1 xxx]
+    file mkdir [file join tdd2 tds2 xxx]
+    testchmod 0o555 tds2
+    set a1 [list [catch {file copy -force tds1 tdd1} msg] $msg]
+    set a2 [list [catch {file copy -force tds2 tdd2} msg] $msg]
+    list [lsort [glob td*]] $a1 $a2 [file writable tds1] [file writable tds2]
+} -result [subst {{tdd1 tdd2 tds1 tds2} {1 {error copying "tds1" to "[file join tdd1 tds1]": file already exists}} {1 {error copying "tds2" to "[file join tdd2 tds2]": file already exists}} 1 0}]
+test fCmd-10.7 {file rename: comprehensive: file to new name and dir} -setup {
+    cleanup
+} -constraints {notRoot testchmod} -body {
+    createfile tf1
+    createfile tf2
+    file mkdir td1
+    testchmod 0o444 tf2
+    file copy tf1 [file join td1 tf3]
+    file copy tf2 [file join td1 tf4]
+    list [lsort [glob tf*]] [lsort [glob -directory td1 t*]] \
+    [file writable [file join td1 tf3]] [file writable [file join td1 tf4]]
+} -result [subst {{tf1 tf2} {[file join td1 tf3] [file join td1 tf4]} 1 0}]
+test fCmd-10.8 {file rename: comprehensive: dir to new name and dir} -setup {
+    cleanup
+} -constraints {unix notRoot testchmod} -body {
+    file mkdir td1
+    file mkdir td2
+    file mkdir td3
+    testchmod 0o555 td2
+    file copy td1 [file join td3 td3]
+    file copy td2 [file join td3 td4]
+    list [lsort [glob td*]] [lsort [glob -directory td3 t*]] \
+    [file writable [file join td3 td3]] [file writable [file join td3 td4]]
+} -result [subst {{td1 td2 td3} {[file join td3 td3] [file join td3 td4]} 1 0}]
+test fCmd-10.8.1 {file rename: comprehensive: dir to new name and dir} -setup {
+    cleanup
+} -constraints {win notRoot testchmod} -body {
+    # On Windows with ACLs, copying a directory is defined like this
+    file mkdir td1
+    file mkdir td2
+    file mkdir td3
+    testchmod 0o555 td2
+    file copy td1 [file join td3 td3]
+    file copy td2 [file join td3 td4]
+    list [lsort [glob td*]] [lsort [glob -directory td3 t*]] \
+    [file writable [file join td3 td3]] [file writable [file join td3 td4]]
+} -result [subst {{td1 td2 td3} {[file join td3 td3] [file join td3 td4]} 1 1}]
+test fCmd-10.9 {file copy: comprehensive: source and target incompatible} -setup {
+    cleanup
+} -constraints {notRoot} -returnCodes error -body {
+    file mkdir td1
+    createfile tf1
+    file copy -force td1 tf1
+} -result {can't overwrite file "tf1" with directory "td1"}
+test fCmd-10.10 {file copy: comprehensive: source and target incompatible} -setup {
+    cleanup
+} -constraints {notRoot} -returnCodes error -body {
+    file mkdir [file join td1 tf1]
+    createfile tf1
+    file copy -force tf1 td1
+} -result [subst {can't overwrite directory "[file join td1 tf1]" with file "tf1"}]
+test fCmd-10.11 {file copy: copy to empty file name} -setup {
+    cleanup
+} -returnCodes error -body {
+    createfile tf1
+    file copy tf1 ""
+} -result {error copying "tf1" to "": no such file or directory}
+test fCmd-10.12 {file rename: rename to empty file name} -setup {
+    cleanup
+} -returnCodes error -body {
+    createfile tf1
+    file rename tf1 ""
+} -result {error renaming "tf1" to "": no such file or directory}
+cleanup
+
+# old tests
+
+test fCmd-11.1 {TclFileRenameCmd: -- option} -constraints notRoot -setup {
+    catch {file delete -force -- -tfa1}
+} -body {
+    set s [createfile -tfa1]
+    file rename -- -tfa1 tfa2
+    list [checkcontent tfa2 $s] [file exists -tfa1]
+} -cleanup {
+    file delete tfa2
+} -result {1 0}
+test fCmd-11.2 {TclFileRenameCmd: bad option} -constraints notRoot -setup {
+    catch {file delete -force -- tfa1}
+} -body {
+    set s [createfile tfa1]
+    list [catch {file rename -x tfa1 tfa2}] \
+	[checkcontent tfa1 $s] [file exists tfa2]
+} -cleanup {
+    file delete tfa1
+} -result {1 1 0}
+test fCmd-11.3 {TclFileRenameCmd: bad \# args} -returnCodes error -body {
+    file rename --
+} -match glob -result *
+test fCmd-11.4 {TclFileRenameCmd: target filename translation failing} -setup {
+    set temp $::env(HOME)
+} -constraints notRoot -body {
+    global env
+    unset env(HOME)
+    catch { file rename tfa ~/foobar }
+} -cleanup {
+    set ::env(HOME) $temp
+} -result 1
+test fCmd-11.5 {TclFileRenameCmd: > 1 source & target is not a dir} -setup {
+    catch {file delete -force -- tfa1 tfa2 tfa3}
+} -constraints {notRoot} -body {
+    createfile tfa1
+    createfile tfa2
+    createfile tfa3
+    catch {file rename tfa1 tfa2 tfa3}
+} -cleanup {
+    file delete tfa1 tfa2 tfa3
+} -result {1}
+test fCmd-11.6 {TclFileRenameCmd: : single file into directory} -setup {
+    catch {file delete -force -- tfa1 tfad}
+} -constraints {notRoot} -body {
+    set s [createfile tfa1]
+    file mkdir tfad
+    file rename tfa1 tfad
+    list [checkcontent tfad/tfa1 $s] [file exists tfa1]
+} -cleanup {
+    file delete -force tfad
+} -result {1 0}
+test fCmd-11.7 {TclFileRenameCmd: : multiple files into directory} -setup {
+    catch {file delete -force -- tfa1 tfa2 tfad}
+} -constraints {notRoot} -body {
+    set s1 [createfile tfa1]
+    set s2 [createfile tfa2]
+    file mkdir tfad
+    file rename tfa1 tfa2 tfad
+    list [checkcontent tfad/tfa1 $s1] [checkcontent tfad/tfa2 $s2] \
+	[file exists tfa1] [file exists tfa2]
+} -cleanup {
+    file delete -force tfad
+} -result {1 1 0 0}
+test fCmd-11.8 {TclFileRenameCmd: error renaming file to directory} -setup {
+    catch {file delete -force -- tfa tfad}
+} -constraints {notRoot} -body {
+    set s [createfile tfa]
+    file mkdir tfad
+    file mkdir tfad/tfa
+    list [catch {file rename tfa tfad}] [checkcontent tfa $s] [file isdir tfad]
+} -cleanup {
+    file delete -force tfa tfad
+} -result {1 1 1}
+
+#
+# Coverage tests for renamefile() ;
+#
+test fCmd-12.1 {renamefile: source filename translation failing} -setup {
+    set temp $::env(HOME)
+} -constraints {notRoot} -body {
+    global env
+    unset env(HOME)
+    catch {file rename ~/tfa1 tfa2}
+} -cleanup {
+    set ::env(HOME) $temp
+} -result {1}
+test fCmd-12.2 {renamefile: src filename translation failing} -setup {
+    set temp $::env(HOME)
+} -constraints {notRoot} -body {
+    global env
+    unset env(HOME)
+    set s [createfile tfa1]
+    file mkdir tfad
+    catch {file rename tfa1 ~/tfa2 tfad}
+} -cleanup {
+    set ::env(HOME) $temp
+    file delete -force tfad
+} -result {1}
+test fCmd-12.3 {renamefile: stat failing on source} -setup {
+    catch {file delete -force -- tfa1 tfa2}
+} -constraints {notRoot} -body {
+    list [catch {file rename tfa1 tfa2}] [file exists tfa1] [file exists tfa2]
+} -result {1 0 0}
+test fCmd-12.4 {renamefile: error renaming file to directory} -setup {
+    catch {file delete -force -- tfa tfad}
+} -constraints {notRoot} -body {
+    set s1 [createfile tfa]
+    file mkdir tfad
+    file mkdir tfad/tfa
+    list [catch {file rename tfa tfad}] [checkcontent tfa $s1] \
+	[file isdir tfad/tfa]
+} -cleanup {
+    file delete -force tfa tfad
+} -result {1 1 1}
+test fCmd-12.5 {renamefile: error renaming directory to file} -setup {
+    catch {file delete -force -- tfa tfad}
+} -constraints {notRoot} -body {
+    file mkdir tfa
+    file mkdir tfad
+    set s [createfile tfad/tfa]
+    list [catch {file rename tfa tfad}] [checkcontent tfad/tfa $s] \
+	[file isdir tfad] [file isdir tfa]
+} -cleanup {
+    file delete -force tfa tfad
+} -result {1 1 1 1}
+test fCmd-12.6 {renamefile: TclRenameFile succeeding} -setup {
+    catch {file delete -force -- tfa1 tfa2}
+} -constraints {notRoot} -body {
+    set s [createfile tfa1]
+    file rename tfa1 tfa2
+    list [checkcontent tfa2 $s] [file exists tfa1]
+} -cleanup {
+    file delete tfa2
+} -result {1 0}
+test fCmd-12.7 {renamefile: renaming directory into offspring} -setup {
+    catch {file delete -force -- tfad}
+} -constraints {notRoot} -body {
+    file mkdir tfad
+    file mkdir tfad/dir
+    catch {file rename tfad tfad/dir}
+} -cleanup {
+    file delete -force tfad
+} -result {1}
+test fCmd-12.8 {renamefile: generic error} -setup {
+    catch {file delete -force -- tfa}
+} -constraints {unix notRoot} -body {
+    file mkdir tfa
+    file mkdir tfa/dir
+    file attributes tfa -permissions 0555
+    catch {file rename tfa/dir tfa2}
+} -cleanup {
+    catch {file attributes tfa -permissions 0777}
+    file delete -force tfa
+} -result {1}
+test fCmd-12.9 {renamefile: moving a file across volumes} -setup {
+    cleanup $tmpspace
+} -constraints {unix notRoot} -body {
+    set s [createfile tfa]
+    file rename tfa $tmpspace
+    list [checkcontent [file join $tmpspace tfa] $s] [file exists tfa]
+} -cleanup {
+    cleanup $tmpspace
+} -result {1 0}
+test fCmd-12.10 {renamefile: moving a directory across volumes} -setup {
+    cleanup $tmpspace
+} -constraints {xdev notRoot} -body {
+    file mkdir tfad
+    set s [createfile tfad/a]
+    file rename tfad $tmpspace
+    list [checkcontent [file join $tmpspace tfad a] $s] [file exists tfad]
+} -cleanup {
+    cleanup $tmpspace
+} -result {1 0}
+
+#
+# Coverage tests for TclCopyFilesCmd()
+#
+test fCmd-13.1 {TclCopyFilesCmd: -force option} -constraints notRoot -setup {
+    catch {file delete -force -- tfa1}
+} -body {
+    set s [createfile tfa1]
+    file copy -force  tfa1 tfa2
+    list [checkcontent tfa2 $s] [checkcontent tfa1 $s]
+} -cleanup {
+    file delete tfa1 tfa2
+} -result {1 1}
+test fCmd-13.2 {TclCopyFilesCmd: -- option} -constraints {notRoot} -setup {
+    catch {file delete -force -- tfa1}
+} -body {
+    set s [createfile -tfa1]
+    file copy --  -tfa1 tfa2
+    list [checkcontent tfa2 $s] [checkcontent -tfa1 $s]
+} -cleanup {
+    file delete -- -tfa1 tfa2
+} -result {1 1}
+test fCmd-13.3 {TclCopyFilesCmd: bad option} -constraints {notRoot} -setup {
+    catch {file delete -force -- tfa1}
+} -body {
+    set s [createfile tfa1]
+    list [catch {file copy -x tfa1 tfa2}] \
+	[checkcontent tfa1 $s] [file exists tfa2]
+} -cleanup {
+    file delete tfa1
+} -result {1 1 0}
+test fCmd-13.4 {TclCopyFilesCmd: bad \# args} -constraints {notRoot} -body {
+    file copy --
+} -returnCodes error -match glob -result *
+test fCmd-13.5 {TclCopyFilesCmd: target filename translation failing} -setup {
+    set temp $::env(HOME)
+} -body {
+    global env
+    unset env(HOME)
+    catch { file copy tfa ~/foobar }
+} -cleanup {
+    set ::env(HOME) $temp
+} -result {1}
+test fCmd-13.6 {TclCopyFilesCmd: > 1 source & target is not a dir} -setup {
+    catch {file delete -force -- tfa1 tfa2 tfa3}
+} -constraints {notRoot} -body {
+    createfile tfa1
+    createfile tfa2
+    createfile tfa3
+    catch {file copy tfa1 tfa2 tfa3}
+} -cleanup {
+    file delete tfa1 tfa2 tfa3
+} -result {1}
+test fCmd-13.7 {TclCopyFilesCmd: single file into directory} -setup {
+    catch {file delete -force -- tfa1 tfad}
+} -constraints {notRoot} -body {
+    set s [createfile tfa1]
+    file mkdir tfad
+    file copy tfa1 tfad
+    list [checkcontent tfad/tfa1 $s] [checkcontent tfa1 $s]
+} -cleanup {
+    file delete -force tfad tfa1
+} -result {1 1}
+test fCmd-13.8 {TclCopyFilesCmd: multiple files into directory} -setup {
+    catch {file delete -force -- tfa1 tfa2 tfad}
+} -constraints {notRoot} -body {
+    set s1 [createfile tfa1]
+    set s2 [createfile tfa2]
+    file mkdir tfad
+    file copy tfa1 tfa2 tfad
+    list [checkcontent tfad/tfa1 $s1] [checkcontent tfad/tfa2 $s2] \
+	[checkcontent tfa1 $s1] [checkcontent tfa2 $s2]
+} -cleanup {
+    file delete -force tfad tfa1 tfa2
+} -result {1 1 1 1}
+test fCmd-13.9 {TclCopyFilesCmd: error copying file to directory} -setup {
+    catch {file delete -force -- tfa tfad}
+} -constraints {notRoot} -body {
+    set s [createfile tfa]
+    file mkdir tfad
+    file mkdir tfad/tfa
+    list [catch {file copy tfa tfad}] [checkcontent tfa $s] \
+	[file isdir tfad/tfa] [file isdir tfad]
+} -cleanup {
+    file delete -force tfa tfad
+} -result {1 1 1 1}
+
+#
+# Coverage tests for copyfile()
+#
+test fCmd-14.1 {copyfile: source filename translation failing} -setup {
+    set temp $::env(HOME)
+} -constraints {notRoot} -body {
+    global env
+    unset env(HOME)
+    catch {file copy ~/tfa1 tfa2}
+} -cleanup {
+    set ::env(HOME) $temp
+} -result {1}
+test fCmd-14.2 {copyfile: dst filename translation failing} -setup {
+    set temp $::env(HOME)
+} -constraints {notRoot} -body {
+    global env
+    unset env(HOME)
+    set s [createfile tfa1]
+    file mkdir tfad
+    list [catch {file copy tfa1 ~/tfa2 tfad}] [checkcontent tfad/tfa1 $s]
+} -cleanup {
+    set ::env(HOME) $temp
+    file delete -force tfa1 tfad
+} -result {1 1}
+test fCmd-14.3 {copyfile: stat failing on source} -setup {
+    catch {file delete -force -- tfa1 tfa2}
+} -constraints notRoot -body {
+    list [catch {file copy tfa1 tfa2}] [file exists tfa1] [file exists tfa2]
+} -result {1 0 0}
+test fCmd-14.4 {copyfile: error copying file to directory} -setup {
+    catch {file delete -force -- tfa tfad}
+} -constraints {notRoot} -body {
+    set s1 [createfile tfa]
+    file mkdir tfad
+    file mkdir tfad/tfa
+    list [catch {file copy tfa tfad}] [checkcontent tfa $s1] \
+	[file isdir tfad] [file isdir tfad/tfa]
+} -cleanup {
+    file delete -force tfa tfad
+} -result {1 1 1 1}
+test fCmd-14.5 {copyfile: error copying directory to file} -setup {
+    catch {file delete -force -- tfa tfad}
+} -constraints {notRoot} -body {
+    file mkdir tfa
+    file mkdir tfad
+    set s [createfile tfad/tfa]
+    list [catch {file copy tfa tfad}] [checkcontent tfad/tfa $s] \
+	[file isdir tfad] [file isdir tfa]
+} -cleanup {
+     file delete -force tfa tfad
+} -result {1 1 1 1}
+test fCmd-14.6 {copyfile: copy file succeeding} -constraints notRoot -setup {
+    catch {file delete -force -- tfa tfa2}
+} -body {
+    set s [createfile tfa]
+    file copy tfa tfa2
+    list [checkcontent tfa $s] [checkcontent tfa2 $s]
+} -cleanup {
+    file delete tfa tfa2
+} -result {1 1}
+test fCmd-14.7 {copyfile: copy directory succeeding} -setup {
+    catch {file delete -force -- tfa tfa2}
+} -constraints {notRoot} -body {
+    file mkdir tfa
+    set s [createfile tfa/file]
+    file copy tfa tfa2
+    list [checkcontent tfa/file $s] [checkcontent tfa2/file $s]
+} -cleanup {
+    file delete -force tfa tfa2
+} -result {1 1}
+test fCmd-14.8 {copyfile: copy directory failing} -setup {
+    catch {file delete -force -- tfa}
+} -constraints {unix notRoot} -body {
+    file mkdir tfa/dir/a/b/c
+    file attributes tfa/dir -permissions 0000
+    catch {file copy tfa tfa2}
+} -cleanup {
+    file attributes tfa/dir -permissions 0777
+    file delete -force tfa tfa2
+} -result {1}
+
+#
+# Coverage tests for TclMkdirCmd()
+#
+test fCmd-15.1 {TclMakeDirsCmd: target filename translation failing} -setup {
+    set temp $::env(HOME)
+} -constraints {notRoot} -body {
+    global env
+    unset env(HOME)
+    catch {file mkdir ~/tfa}
+} -cleanup {
+    set ::env(HOME) $temp
+} -result {1}
+#
+# Can Tcl_SplitPath return argc == 0? If so them we need a test for that code.
+#
+test fCmd-15.2 {TclMakeDirsCmd - one directory} -setup {
+    catch {file delete -force -- tfa}
+} -constraints {notRoot} -body {
+    file mkdir tfa
+    file isdirectory tfa
+} -cleanup {
+    file delete tfa
+} -result {1}
+test fCmd-15.3 {TclMakeDirsCmd: - two directories} -setup {
+    catch {file delete -force -- tfa1 tfa2}
+} -constraints {notRoot} -body {
+    file mkdir tfa1 tfa2
+    list [file isdirectory tfa1] [file isdirectory tfa2]
+} -cleanup {
+    file delete tfa1 tfa2
+} -result {1 1}
+test fCmd-15.4 {TclMakeDirsCmd - stat failing} -setup {
+    catch {file delete -force -- tfa}
+} -constraints {unix notRoot} -body {
+    file mkdir tfa
+    createfile tfa/file
+    file attributes tfa -permissions 0000
+    catch {file mkdir tfa/file}
+} -cleanup {
+    file attributes tfa -permissions 0777
+    file delete -force tfa
+} -result {1}
+test fCmd-15.5 {TclMakeDirsCmd: - making a directory several levels deep} -setup {
+    catch {file delete -force -- tfa}
+} -constraints {notRoot} -body {
+    file mkdir tfa/a/b/c
+    file isdir tfa/a/b/c
+} -cleanup {
+    file delete -force tfa
+} -result {1}
+test fCmd-15.6 {TclMakeDirsCmd: - trying to overwrite a file} -setup {
+    catch {file delete -force -- tfa}
+} -constraints {notRoot} -body {
+    set s [createfile tfa]
+    list [catch {file mkdir tfa}] [file isdir tfa] [file exists tfa] \
+	[checkcontent tfa $s]
+} -cleanup {
+    file delete tfa
+} -result {1 0 1 1}
+test fCmd-15.7 {TclMakeDirsCmd - making several directories} -setup {
+    catch {file delete -force -- tfa1 tfa2}
+} -constraints {notRoot} -body {
+    file mkdir tfa1 tfa2/a/b/c
+    list [file isdir tfa1] [file isdir tfa2/a/b/c]
+} -cleanup {
+    file delete -force tfa1 tfa2
+} -result {1 1}
+test fCmd-15.8 {TclFileMakeDirsCmd: trying to create an existing dir} -body {
+    file mkdir tfa
+    file mkdir tfa
+    file isdir tfa
+} -constraints {notRoot} -cleanup {
+    file delete tfa
+} -result {1}
+
+# Coverage tests for TclDeleteFilesCommand()
+test fCmd-16.1 {test the -- argument} -constraints {notRoot} -setup {
+    catch {file delete -force -- tfa}
+} -body {
+    createfile tfa
+    file delete -- tfa
+    file exists tfa
+} -result 0
+test fCmd-16.2 {test the -force and -- arguments} -constraints notRoot -setup {
+    catch {file delete -force -- tfa}
+} -body {
+    createfile tfa
+    file delete -force -- tfa
+    file exists tfa
+} -result 0
+test fCmd-16.3 {test bad option} -constraints {notRoot} -setup {
+    catch {file delete -force -- tfa}
+} -body {
+    createfile tfa
+    catch {file delete -dog tfa}
+} -cleanup {
+    file delete tfa
+} -result {1}
+test fCmd-16.4 {accept zero files (TIP 323)} -body {
+    file delete
+} -result {}
+test fCmd-16.5 {accept zero files (TIP 323)} -body {
+    file delete --
+} -result {}
+test fCmd-16.6 {delete: source filename translation failing} -setup {
+    set temp $::env(HOME)
+} -constraints {notRoot} -body {
+    global env
+    unset env(HOME)
+    catch {file delete ~/tfa}
+} -cleanup {
+    set ::env(HOME) $temp
+} -result {1}
+test fCmd-16.7 {remove a non-empty directory without -force} -setup {
+    catch {file delete -force -- tfa}
+} -constraints {notRoot} -body {
+    file mkdir tfa
+    createfile tfa/a
+    catch {file delete tfa}
+} -cleanup {
+    file delete -force tfa
+} -result {1}
+test fCmd-16.8 {remove a normal file} -constraints {notRoot} -setup {
+    catch {file delete -force -- tfa}
+} -body {
+    file mkdir tfa
+    createfile tfa/a
+    catch {file delete tfa}
+} -cleanup {
+    file delete -force tfa
+} -result {1}
+test fCmd-16.9 {error while deleting file} -setup {
+    catch {file delete -force -- tfa}
+} -constraints {unix notRoot} -body {
+    file mkdir tfa
+    createfile tfa/a
+    file attributes tfa -permissions 0555
+    catch {file delete tfa/a}
+    #######
+    #######  If any directory in a tree that is being removed does not have
+    #######  write permission, the process will fail! This is also the case
+    #######  with "rm -rf"
+    #######
+} -cleanup {
+    file attributes tfa -permissions 0777
+    file delete -force tfa
+} -result {1}
+test fCmd-16.10 {deleting multiple files} -constraints {notRoot} -setup {
+    catch {file delete -force -- tfa1 tfa2}
+} -body {
+    createfile tfa1
+    createfile tfa2
+    file delete tfa1 tfa2
+    list [file exists tfa1] [file exists tfa2]
+} -result {0 0}
+test fCmd-16.11 {TclFileDeleteCmd: removing a nonexistant file} -setup {
+    catch {file delete -force -- tfa}
+} -constraints {notRoot} -body {
+    file delete tfa
+} -result {}
+
+# More coverage tests for mkpath()
+test fCmd-17.1 {mkdir stat failing on target but not ENOENT} -setup {
+     catch {file delete -force -- tfa1}
+} -constraints {unix notRoot} -body {
+     file mkdir tfa1
+     file attributes tfa1 -permissions 0555
+     catch {file mkdir tfa1/tfa2}
+} -cleanup {
+     file attributes tfa1 -permissions 0777
+     file delete -force tfa1
+} -result {1}
+test fCmd-17.2 {mkdir several levels deep - relative} -setup {
+    catch {file delete -force -- tfa}
+} -constraints {notRoot} -body {
+    file mkdir tfa/a/b
+    file isdir tfa/a/b
+} -cleanup {
+    file delete tfa/a/b tfa/a tfa
+} -result 1
+test fCmd-17.3 {mkdir several levels deep - absolute} -setup {
+    catch {file delete -force -- tfa}
+} -constraints {notRoot} -body {
+    set f [file join [pwd] tfa a]
+    file mkdir $f
+    file isdir $f
+} -cleanup {
+    file delete $f [file join [pwd] tfa]
+} -result {1}
+
+#
+# Functionality tests for TclFileRenameCmd()
+#
+test fCmd-18.1 {TclFileRenameCmd: rename (first form) in the same directory} \
+	-setup {
+    catch {file delete -force -- tfad}
+    set savedDir [pwd]
+} -constraints {notRoot} -body {
+    file mkdir tfad/dir
+    cd tfad/dir
+    set s [createfile foo]
+    file rename  foo bar
+    file rename bar ./foo
+    file rename ./foo bar
+    file rename ./bar ./foo
+    file rename foo ../dir/bar
+    file rename ../dir/bar ./foo
+    file rename ../../tfad/dir/foo ../../tfad/dir/bar
+    file rename [file join [pwd] bar] foo
+    file rename foo [file join [pwd] bar]
+    list [checkcontent bar $s] [file exists foo]
+} -cleanup {
+    cd $savedDir
+    file delete -force tfad
+} -result {1 0}
+test fCmd-18.2 {TclFileRenameCmd: single dir to nonexistant} -setup {
+    catch {file delete -force -- tfa1 tfa2}
+} -constraints {notRoot} -body {
+    file mkdir tfa1
+    file rename tfa1 tfa2
+    list [file exists tfa2] [file exists tfa1]
+} -cleanup {
+    file delete tfa2
+} -result {1 0}
+test fCmd-18.3 {TclFileRenameCmd: mixed dirs and files into directory} -setup {
+    catch {file delete -force -- tfa1 tfad1 tfad2}
+} -constraints {notRoot} -body {
+    set s [createfile tfa1]
+    file mkdir tfad1 tfad2
+    file rename tfa1 tfad1 tfad2
+    list [checkcontent tfad2/tfa1 $s] [file isdir tfad2/tfad1] \
+	[file exists tfa1] [file exists tfad1]
+} -cleanup {
+    file delete tfad2/tfa1
+    file delete -force tfad2
+} -result {1 1 0 0}
+test fCmd-18.4 {TclFileRenameCmd: attempt to replace non-dir with dir} -setup {
+    catch {file delete -force -- tfa tfad}
+} -constraints {notRoot} -body {
+    set s [createfile tfa]
+    file mkdir tfad
+    list [catch {file rename tfad tfa}] [checkcontent tfa $s] [file isdir tfad]
+} -cleanup {
+    file delete tfa tfad
+} -result {1 1 1}
+test fCmd-18.5 {TclFileRenameCmd: attempt to replace dir with non-dir} -setup {
+    catch {file delete -force -- tfa tfad}
+} -constraints {notRoot} -body {
+    set s [createfile tfa]
+    file mkdir tfad/tfa
+    list [catch {file rename tfa tfad}] [checkcontent tfa $s] \
+	[file isdir tfad/tfa]
+} -cleanup {
+    file delete -force tfa tfad
+} -result {1 1 1}
+#
+# On Windows there is no easy way to determine if two files are the same
+#
+test fCmd-18.6 {TclFileRenameCmd: rename a file to itself} -setup {
+    catch {file delete -force -- tfa}
+} -constraints {unix notRoot} -body {
+    set s [createfile tfa]
+    list [catch {file rename tfa tfa}] [checkcontent tfa $s]
+} -cleanup {
+    file delete tfa
+} -result {1 1}
+test fCmd-18.7 {TclFileRenameCmd: rename dir on top of another empty dir w/o -force} -setup {
+    catch {file delete -force -- tfa tfad}
+} -constraints {notRoot} -body {
+    file mkdir tfa tfad/tfa
+    list [catch {file rename tfa tfad}] [file isdir tfa]
+} -cleanup {
+    file delete -force tfa tfad
+} -result {1 1}
+test fCmd-18.8 {TclFileRenameCmd: rename dir on top of another empty dir w/ -force} -setup {
+    catch {file delete -force -- tfa tfad}
+} -constraints {notRoot notNetworkFilesystem} -body {
+    file mkdir tfa tfad/tfa
+    file rename -force tfa tfad
+    file isdir tfa
+} -cleanup {
+    file delete -force tfad
+} -result 0
+test fCmd-18.9 {TclFileRenameCmd: rename dir on top of a non-empty dir w/o -force} -setup {
+    catch {file delete -force -- tfa tfad}
+} -constraints {notRoot} -body {
+    file mkdir tfa tfad/tfa/file
+    list [catch {file rename tfa tfad}] [file isdir tfa] \
+	[file isdir tfad/tfa/file]
+} -cleanup {
+    file delete -force tfa tfad
+} -result {1 1 1}
+test fCmd-18.10 {TclFileRenameCmd: rename dir on top of a non-empty dir w/ -force} -setup {
+    catch {file delete -force -- tfa tfad}
+} -constraints {notRoot notNetworkFilesystem} -body {
+    file mkdir tfa tfad/tfa/file
+    list [catch {file rename -force tfa tfad}] [file isdir tfa] \
+	[file isdir tfad/tfa/file]
+} -cleanup {
+    file delete -force tfa tfad
+} -result {1 1 1}
+test fCmd-18.11 {TclFileRenameCmd: rename a non-existant file} -setup {
+    catch {file delete -force -- tfa1}
+} -constraints {notRoot} -body {
+    list [catch {file rename tfa1 tfa2}] [file exists tfa1] [file exists tfa2]
+} -result {1 0 0}
+test fCmd-18.12 {TclFileRenameCmd : rename a symbolic link to file} -setup {
+    catch {file delete -force -- tfa1 tfa2 tfa3}
+} -constraints {unix notRoot} -body {
+    set s [createfile tfa1]
+    file link -symbolic tfa2 tfa1
+    file rename tfa2 tfa3
+    file type tfa3
+} -cleanup {
+    file delete tfa1 tfa3
+} -result link
+test fCmd-18.13 {TclFileRenameCmd : rename a symbolic link to dir} -setup {
+    catch {file delete -force -- tfa1 tfa2 tfa3}
+} -constraints {unix notRoot} -body {
+    file mkdir tfa1
+    file link -symbolic tfa2 tfa1
+    file rename tfa2 tfa3
+    file type tfa3
+} -cleanup {
+    file delete tfa1 tfa3
+} -result link
+test fCmd-18.14 {TclFileRenameCmd : rename a path with sym link} -setup {
+    catch {file delete -force -- tfa1 tfa2 tfa3}
+} -constraints {unix notRoot} -body {
+    file mkdir tfa1/a/b/c/d
+    file mkdir tfa2
+    set f [file join [pwd] tfa1/a/b]
+    set f2 [file join [pwd] {tfa2/b alias}]
+    file link -symbolic $f2 $f
+    file rename {tfa2/b alias/c} tfa3
+    list [file isdir tfa3] [file exists tfa1/a/b/c]
+} -cleanup {
+    file delete -force tfa1 tfa2 tfa3
+} -result {1 0}
+test fCmd-18.15 {TclFileRenameCmd : rename a file to a symlink dir} -setup {
+    catch {file delete -force -- tfa1 tfa2 tfalink}
+} -constraints {unix notRoot} -body {
+    file mkdir tfa1
+    set s [createfile tfa2]
+    file link -symbolic tfalink tfa1
+    file rename tfa2 tfalink
+    checkcontent tfa1/tfa2 $s
+} -cleanup {
+    file delete -force tfa1 tfalink
+} -result {1}
+test fCmd-18.16 {TclFileRenameCmd: rename a dangling symlink} -setup {
+    catch {file delete -force -- tfa1 tfalink}
+} -constraints {unix notRoot} -body {
+    file mkdir tfa1
+    file link -symbolic tfalink tfa1
+    file delete tfa1
+    file rename tfalink tfa2
+    file type tfa2
+} -cleanup {
+    file delete tfa2
+} -result link
+
+#
+# Coverage tests for TclUnixRmdir
+#
+test fCmd-19.1 {remove empty directory} -constraints {notRoot} -setup {
+    catch {file delete -force -- tfa}
+} -body {
+    file mkdir tfa
+    file delete tfa
+    file exists tfa
+} -result {0}
+test fCmd-19.2 {rmdir error besides EEXIST} -setup {
+    catch {file delete -force -- tfa}
+} -constraints {unix notRoot} -body {
+    file mkdir tfa
+    file mkdir tfa/a
+    file attributes tfa -permissions 0555
+    catch {file delete tfa/a}
+} -cleanup {
+    file attributes tfa -permissions 0777
+    file delete -force tfa
+} -result {1}
+test fCmd-19.3 {recursive remove} -constraints {notRoot} -setup {
+    catch {file delete -force -- tfa}
+} -body {
+    file mkdir tfa
+    file mkdir tfa/a
+    file delete -force tfa
+    file exists tfa
+} -result {0}
+
+#
+# TclUnixDeleteFile and TraversalDelete are covered by tests from the
+# TclDeleteFilesCmd suite
+#
+
+#
+# Coverage tests for TraverseUnixTree(), called from TclDeleteFilesCmd
+#
+test fCmd-20.1 {TraverseUnixTree : failure opening a subdirectory directory} -setup {
+    catch {file delete -force -- tfa}
+} -constraints {unix notRoot} -body {
+    file mkdir tfa
+    file mkdir tfa/a
+    file attributes tfa/a -permissions 0000
+    catch {file delete -force tfa}
+} -cleanup {
+    file attributes tfa/a -permissions 0777
+    file delete -force tfa
+} -result {1}
+test fCmd-20.2 {TraverseUnixTree : recursive delete of large directory: Bug 1034337} -setup {
+    catch {file delete -force -- tfa}
+} -constraints {unix notRoot} -body {
+    file mkdir tfa
+    for {set i 1} {$i <= 300} {incr i} {
+	createfile tfa/testfile_$i
+    }
+    file delete -force tfa
+} -cleanup {
+    while {[catch {file delete -force tfa}]} {}
+} -result {}
+
+#
+# Feature testing for TclCopyFilesCmd
+#
+test fCmd-21.1 {copy : single file to nonexistant} -setup {
+    catch {file delete -force -- tfa1 tfa2}
+} -constraints {notRoot} -body {
+    set s [createfile tfa1]
+    file copy tfa1 tfa2
+    list [checkcontent tfa2 $s] [checkcontent tfa1 $s]
+} -cleanup {
+    file delete tfa1 tfa2
+} -result {1 1}
+test fCmd-21.2 {copy : single dir to nonexistant} -setup {
+    catch {file delete -force -- tfa1 tfa2}
+} -constraints {notRoot} -body {
+    file mkdir tfa1
+    file copy tfa1 tfa2
+    list [file isdir tfa2] [file isdir tfa1]
+} -cleanup {
+    file delete tfa1 tfa2
+} -result {1 1}
+test fCmd-21.3 {copy : single file into directory} -setup {
+    catch {file delete -force -- tfa1 tfad}
+} -constraints {notRoot} -body {
+    set s [createfile tfa1]
+    file mkdir tfad
+    file copy tfa1 tfad
+    list [checkcontent tfad/tfa1 $s] [checkcontent tfa1 $s]
+} -cleanup {
+    file delete -force tfa1 tfad
+} -result {1 1}
+test fCmd-21.4 {copy : more than one source and target is not a directory} -setup {
+    catch {file delete -force -- tfa1 tfa2 tfa3}
+} -constraints {notRoot} -body {
+    createfile tfa1
+    createfile tfa2
+    createfile tfa3
+    catch {file copy tfa1 tfa2 tfa3}
+} -cleanup {
+    file delete tfa1 tfa2 tfa3
+} -result {1}
+test fCmd-21.5 {copy : multiple files into directory} -constraints {notRoot} -setup {
+    catch {file delete -force -- tfa1 tfa2 tfad}
+} -body {
+    set s1 [createfile tfa1]
+    set s2 [createfile tfa2]
+    file mkdir tfad
+    file copy tfa1 tfa2 tfad
+    list [checkcontent tfad/tfa1 $s1] [checkcontent tfad/tfa2 $s2] \
+	[checkcontent tfa1 $s1] [checkcontent tfa2 $s2]
+} -cleanup {
+    file delete -force tfa1 tfa2 tfad
+} -result {1 1 1 1}
+test fCmd-21.6 {copy: mixed dirs and files into directory} -setup {
+    catch {file delete -force -- tfa1 tfad1 tfad2}
+} -constraints {notRoot notFileSharing} -body {
+    set s [createfile tfa1]
+    file mkdir tfad1 tfad2
+    file copy tfa1 tfad1 tfad2
+    list [checkcontent [file join tfad2 tfa1] $s] \
+	[file isdir [file join tfad2 tfad1]] \
+	[checkcontent tfa1 $s] [file isdir tfad1]
+} -cleanup {
+    file delete -force tfa1 tfad1 tfad2
+} -result {1 1 1 1}
+test fCmd-21.7.1 {TclCopyFilesCmd: copy a dangling link} -setup {
+    catch {file delete -force tfad1 tfalink tfalink2}
+} -constraints {unix notRoot dontCopyLinks} -body {
+    file mkdir tfad1
+    file link -symbolic tfalink tfad1
+    file delete tfad1
+    file copy tfalink tfalink2
+} -returnCodes error -cleanup {
+    file delete -force tfalink tfalink2
+} -result {error copying "tfalink": the target of this link doesn't exist}
+test fCmd-21.7.2 {TclCopyFilesCmd: copy a dangling link} -setup {
+    catch {file delete -force tfad1 tfalink tfalink2}
+} -constraints {unix notRoot} -body {
+    file mkdir tfad1
+    file link -symbolic tfalink tfad1
+    file delete tfad1
+    file copy tfalink tfalink2
+    file type tfalink2
+} -cleanup {
+    file delete tfalink tfalink2
+} -result link
+test fCmd-21.8.1 {TclCopyFilesCmd: copy a link} -setup {
+    catch {file delete -force tfad1 tfalink tfalink2}
+} -constraints {unix notRoot dontCopyLinks} -body {
+    file mkdir tfad1
+    file link -symbolic tfalink tfad1
+    file copy tfalink tfalink2
+    list [file type tfalink] [file type tfalink2] [file isdir tfad1]
+} -cleanup {
+    file delete -force tfad1 tfalink tfalink2
+} -result {link directory 1}
+test fCmd-21.8.2 {TclCopyFilesCmd: copy a link} -setup {
+    catch {file delete -force tfad1 tfalink tfalink2}
+} -constraints {unix notRoot} -body {
+    file mkdir tfad1
+    file link -symbolic tfalink tfad1
+    file copy tfalink tfalink2
+    list [file type tfalink] [file type tfalink2] [file isdir tfad1]
+} -cleanup {
+    file delete -force tfad1 tfalink tfalink2
+} -result {link link 1}
+test fCmd-21.9 {TclCopyFilesCmd: copy dir with a link in it} -setup {
+    catch {file delete -force tfad1 tfad2}
+} -constraints {unix notRoot} -body {
+    file mkdir tfad1
+    file link -symbolic tfad1/tfalink "[pwd]/tfad1"
+    file copy tfad1 tfad2
+    file type tfad2/tfalink
+} -cleanup {
+    file delete -force tfad1 tfad2
+} -result link
+test fCmd-21.10 {TclFileCopyCmd: copy dir on top of another empty dir w/o -force} -setup {
+    catch {file delete -force -- tfa tfad}
+} -constraints {notRoot} -body {
+    file mkdir tfa [file join tfad tfa]
+    list [catch {file copy tfa tfad}] [file isdir tfa]
+} -cleanup {
+    file delete -force tfa tfad
+} -result {1 1}
+test fCmd-21.11 {TclFileCopyCmd: copy dir on top of a dir w/o -force} -setup {
+    catch {file delete -force -- tfa tfad}
+} -constraints {notRoot} -body {
+    file mkdir tfa [file join tfad tfa file]
+    list [catch {file copy tfa tfad}] [file isdir tfa] \
+	[file isdir [file join tfad tfa file]]
+} -cleanup {
+    file delete -force tfa tfad
+} -result {1 1 1}
+test fCmd-21.12 {TclFileCopyCmd: copy dir on top of a non-empty dir w/ -force} -setup {
+    catch {file delete -force -- tfa tfad}
+} -constraints {notRoot} -body {
+    file mkdir tfa [file join tfad tfa file]
+    list [catch {file copy -force tfa tfad}] [file isdir tfa] \
+	[file isdir [file join tfad tfa file]]
+} -cleanup {
+    file delete -force tfa tfad
+} -result {1 1 1}
+
+#
+# Coverage testing for TclpRenameFile
+#
+test fCmd-22.1 {TclpRenameFile: rename and overwrite in a single dir} -setup {
+    catch {file delete -force -- tfa1 tfa2}
+} -constraints {notRoot} -body {
+    set s [createfile tfa1]
+    set s2 [createfile tfa2 q]
+    set result [catch {file rename tfa1 tfa2}]
+    file rename -force tfa1 tfa2
+    lappend result [checkcontent tfa2 $s]
+} -cleanup {
+    file delete [glob tfa1 tfa2]
+} -result {1 1}
+test fCmd-22.2 {TclpRenameFile: attempt to overwrite itself} -setup {
+    catch {file delete -force -- tfa1}
+} -constraints {unix notRoot} -body {
+    set s [createfile tfa1]
+    file rename -force tfa1 tfa1
+    checkcontent tfa1 $s
+} -cleanup {
+    file delete tfa1
+} -result {1}
+test fCmd-22.3 {TclpRenameFile: rename dir to existing dir} -setup {
+    catch {file delete -force -- d1 tfad}
+} -constraints {notRoot} -body {
+    file mkdir d1 [file join tfad d1]
+    list [catch {file rename d1 tfad}] [file isdir d1] \
+	[file isdir [file join tfad d1]]
+} -cleanup {
+    file delete -force d1 tfad
+} -result {1 1 1}
+test fCmd-22.4 {TclpRenameFile: rename dir to dir several levels deep} -setup {
+    catch {file delete -force -- d1 tfad}
+} -constraints {notRoot} -body {
+    file mkdir d1 [file join tfad a b c]
+    file rename d1 [file join tfad a b c d1]
+    list [file isdir d1] [file isdir [file join tfad a b c d1]]
+} -cleanup {
+    file delete -force [glob d1 tfad]
+} -result {0 1}
+#
+# TclMacCopyFile needs to be redone.
+#
+test fCmd-22.5 {TclMacCopyFile: copy and overwrite in a single dir} -setup {
+    catch {file delete -force -- tfa1 tfa2}
+} -constraints {notRoot} -body {
+    set s [createfile tfa1]
+    set s2 [createfile tfa2 q]
+    set result [catch {file copy tfa1 tfa2}]
+    file copy -force tfa1 tfa2
+    lappend result [checkcontent tfa2 $s] [checkcontent tfa1 $s]
+} -cleanup {
+    file delete tfa1 tfa2
+} -result {1 1 1}
+
+#
+# TclMacMkdir - basic cases are covered elsewhere.
+# Error cases are not covered.
+#
+
+#
+# TclMacRmdir
+# Error cases are not covered.
+#
+test fCmd-23.1 {TclMacRmdir: trying to remove a nonempty directory} -setup {
+    catch {file delete -force -- tfad}
+} -constraints {notRoot} -body {
+    file mkdir [file join tfad dir]
+    list [catch {file delete tfad}] [file delete -force tfad]
+} -cleanup {
+    catch {file delete -force tfad}
+} -result {1 {}}
+
+#
+# TclMacDeleteFile
+# Error cases are not covered.
+#
+test fCmd-24.1 {TclMacDeleteFile: deleting a normal file} -setup {
+    catch {file delete -force -- tfa1}
+} -constraints {notRoot} -body {
+    createfile tfa1
+    file delete tfa1
+    file exists tfa1
+} -cleanup {
+    catch {file delete -force tfa1}
+} -result {0}
+
+#
+# TclMacCopyDirectory
+# Error cases are not covered.
+#
+test fCmd-25.1 {TclMacCopyDirectory: copying a normal directory} -setup {
+    catch {file delete -force -- tfad1 tfad2}
+} -constraints {notRoot notFileSharing} -body {
+    file mkdir [file join tfad1 a b c]
+    file copy tfad1 tfad2
+    list [file isdir [file join tfad1 a b c]] \
+	[file isdir [file join tfad2 a b c]]
+} -cleanup {
+    file delete -force tfad1 tfad2
+} -result {1 1}
+test fCmd-25.2 {TclMacCopyDirectory: copying a short path normal directory} -setup {
+    catch {file delete -force -- tfad1 tfad2}
+} -constraints {notRoot notFileSharing} -body {
+    file mkdir tfad1
+    file copy tfad1 tfad2
+    list [file isdir tfad1] [file isdir tfad2]
+} -cleanup {
+    file delete tfad1 tfad2
+} -result {1 1}
+test fCmd-25.3 {TclMacCopyDirectory: copying dirs between different dirs} -setup {
+    catch {file delete -force -- tfad1 tfad2}
+} -constraints {notRoot notFileSharing} -body {
+    file mkdir [file join tfad1 x y z]
+    file mkdir [file join tfad2 dir]
+    file copy tfad1 [file join tfad2 dir]
+    list [file isdir [file join tfad1 x y z]] \
+	[file isdir [file join tfad2 dir tfad1 x y z]]
+} -cleanup {
+    file delete -force tfad1 tfad2
+} -result {1 1}
+
+#
+# Functionality tests for TclDeleteFilesCmd
+#
+test fCmd-26.1 {TclDeleteFilesCmd: delete symlink} -setup {
+    catch {file delete -force -- tfad1 tfad2}
+} -constraints {unix notRoot} -body {
+    file mkdir tfad1
+    file link -symbolic tfalink tfad1
+    file delete tfalink
+    list [file isdir tfad1] [file exists tfalink]
+} -cleanup {
+    file delete tfad1
+    catch {file delete tfalink}
+} -result {1 0}
+test fCmd-26.2 {TclDeleteFilesCmd: delete dir with symlink} -setup {
+    catch {file delete -force -- tfad1 tfad2}
+} -constraints {unix notRoot} -body {
+    file mkdir tfad1
+    file mkdir tfad2
+    file link -symbolic [file join tfad2 link] [file join .. tfad1]
+    file delete -force tfad2
+    list [file isdir tfad1] [file exists tfad2]
+} -cleanup {
+    file delete tfad1
+} -result {1 0}
+test fCmd-26.3 {TclDeleteFilesCmd: delete dangling symlink} -setup {
+    catch {file delete -force -- tfad1 tfad2}
+} -constraints {unix notRoot} -body {
+    file mkdir tfad1
+    file link -symbolic tfad2 tfad1
+    file delete tfad1
+    file delete tfad2
+    list [file exists tfad1] [file exists tfad2]
+} -result {0 0}
+
+# There is no fCmd-27.1
+test fCmd-27.2 {TclFileAttrsCmd - Tcl_TranslateFileName fails} -setup {
+    set platform [testgetplatform]
+} -constraints {testsetplatform} -body {
+    testsetplatform unix
+    file attributes ~_totally_bogus_user
+} -returnCodes error -cleanup {
+    testsetplatform $platform
+} -result {user "_totally_bogus_user" doesn't exist}
+test fCmd-27.3 {TclFileAttrsCmd - all attributes} -setup {
+    catch {file delete -force -- foo.tmp}
+} -body {
+    createfile foo.tmp
+    file attributes foo.tmp
+    # Must be non-empty result
+} -cleanup {
+    file delete -force -- foo.tmp
+} -match glob -result {?*}
+test fCmd-27.4 {TclFileAttrsCmd - getting one option} -setup {
+    catch {file delete -force -- foo.tmp}
+} -body {
+    createfile foo.tmp
+    set attrs [file attributes foo.tmp]
+    file attributes foo.tmp {*}[lindex $attrs 0]
+    # Any successful result will do
+} -cleanup {
+    file delete -force -- foo.tmp
+} -match glob -result *
+test fCmd-27.5 {TclFileAttrsCmd - setting one option} -setup {
+    catch {file delete -force -- foo.tmp}
+} -constraints {foundGroup} -body {
+    createfile foo.tmp
+    set attrs [file attributes foo.tmp]
+    file attributes foo.tmp {*}[lrange $attrs 0 1]
+} -cleanup {
+    file delete -force -- foo.tmp
+} -result {}
+test fCmd-27.6 {TclFileAttrsCmd - setting more than one option} -setup {
+    catch {file delete -force -- foo.tmp}
+} -constraints {foundGroup} -body {
+    createfile foo.tmp
+    set attrs [file attributes foo.tmp]
+    file attributes foo.tmp {*}[lrange $attrs 0 3]
+} -cleanup {
+    file delete -force -- foo.tmp
+} -result {}
+
+if {
+    [testConstraint win] &&
+    ([string index $tcl_platform(osVersion) 0] < 5
+     || [lindex [file system [temporaryDirectory]] 1] ne "NTFS")
+} then {
+    testConstraint linkDirectory 0
+    testConstraint linkFile 0
+}
+
+test fCmd-28.1 {file link} -returnCodes error -body {
+    file link
+} -result {wrong # args: should be "file link ?-linktype? linkname ?target?"}
+test fCmd-28.2 {file link} -returnCodes error -body {
+    file link a b c d
+} -result {wrong # args: should be "file link ?-linktype? linkname ?target?"}
+test fCmd-28.3 {file link} -returnCodes error -body {
+    file link abc b c
+} -result {bad option "abc": must be -symbolic or -hard}
+test fCmd-28.4 {file link} -returnCodes error -body {
+    file link -abc b c
+} -result {bad option "-abc": must be -symbolic or -hard}
+cd [workingDirectory]
+makeDirectory abc.dir
+makeDirectory abc2.dir
+makeFile contents abc.file
+makeFile contents abc2.file
+cd [temporaryDirectory]
+test fCmd-28.5 {file link: source already exists} -setup {
+    cd [temporaryDirectory]
+} -constraints {linkDirectory} -body {
+    file link abc.dir abc2.dir
+} -returnCodes error -cleanup {
+    cd [workingDirectory]
+} -result {could not create new link "abc.dir": that path already exists}
+test fCmd-28.6 {file link: unsupported operation} -setup {
+    cd [temporaryDirectory]
+} -constraints {linkDirectory win} -body {
+    file link -hard abc.link abc.dir
+} -returnCodes error -cleanup {
+    cd [workingDirectory]
+} -result {could not create new link "abc.link" pointing to "abc.dir": illegal operation on a directory}
+test fCmd-28.7 {file link: source already exists} -setup {
+    cd [temporaryDirectory]
+} -constraints {linkFile} -body {
+    file link abc.file abc2.file
+} -returnCodes error -cleanup {
+    cd [workingDirectory]
+} -result {could not create new link "abc.file": that path already exists}
+test fCmd-28.8 {file link} -constraints {linkFile win} -setup {
+    cd [temporaryDirectory]
+} -body {
+    file link -symbolic abc.link abc.file
+} -returnCodes error -cleanup {
+    cd [workingDirectory]
+} -result {could not create new link "abc.link" pointing to "abc.file": not a directory}
+test fCmd-28.9 {file link: success with file} -constraints {linkFile} -setup {
+    cd [temporaryDirectory]
+    file delete -force abc.link
+} -body {
+    file link abc.link abc.file
+} -cleanup {
+    cd [workingDirectory]
+} -result abc.file
+test fCmd-28.9.1 {file link: success with file} -setup {
+    cd [temporaryDirectory]
+    file delete -force abc.link
+} -constraints {linkFile win} -body {
+    file stat abc.file arr
+    set res $arr(nlink)
+    lappend res [catch {file link abc.link abc.file} msg] $msg
+    file stat abc.file arr
+    lappend res $arr(nlink)
+} -cleanup {
+    cd [workingDirectory]
+} -result {1 0 abc.file 2}
+cd [temporaryDirectory]
+catch {file delete -force abc.link}
+cd [workingDirectory]
+test fCmd-28.10 {file link: linking to nonexistent path} -setup {
+    cd [temporaryDirectory]
+    file delete -force abc.link
+} -constraints {linkDirectory} -body {
+    file link abc.link abc2.doesnt
+} -returnCodes error -cleanup {
+    cd [workingDirectory]
+} -result {could not create new link "abc.link": target "abc2.doesnt" doesn't exist}
+test fCmd-28.10.1 {file link: linking to nonexistent path} -setup {
+    cd [temporaryDirectory]
+    file delete -force abc.link
+} -constraints {linkDirectory} -body {
+    file link doesnt/abc.link abc.dir
+} -returnCodes error -cleanup {
+    cd [workingDirectory]
+} -result {could not create new link "doesnt/abc.link": no such file or directory}
+test fCmd-28.11 {file link: success with directory} -setup {
+    cd [temporaryDirectory]
+    file delete -force abc.link
+} -constraints {linkDirectory} -body {
+    file link abc.link abc.dir
+} -cleanup {
+    cd [workingDirectory]
+} -result abc.dir
+test fCmd-28.12 {file link: cd into a link} -setup {
+    cd [temporaryDirectory]
+    file delete -force abc.link
+} -constraints {linkDirectory} -body {
+    file link abc.link abc.dir
+    set orig [pwd]
+    cd abc.link
+    set dir [pwd]
+    cd ..
+    set up [pwd]
+    cd $orig
+    # Now '$up' should be either $orig or [file dirname abc.dir], depending on
+    # whether 'cd' actually moves to the destination of a link, or simply
+    # treats the link as a directory. (On windows the former, on unix the
+    # latter, I believe)
+    if {
+	([file normalize $up] ne [file normalize $orig]) &&
+	([file normalize $up] ne [file normalize [file dirname abc.dir]])
+    } then {
+	return "wrong directory with 'cd abc.link ; cd ..': \
+		\"[file normalize $up]\" should be \"[file normalize $orig]\"\
+		or \"[file normalize [file dirname abc.dir]]\""
+    } else {
+	return "ok"
+    }
+} -cleanup {
+    file delete -force abc.link
+    cd [workingDirectory]
+} -result ok
+test fCmd-28.13 {file link} -constraints {linkDirectory} -setup {
+    cd [temporaryDirectory]
+    file link abc.link abc.dir
+} -body {
+    # duplicate link throws error
+    file link abc.link abc.dir
+} -returnCodes error -cleanup {
+    file delete -force abc.link
+    cd [workingDirectory]
+} -result {could not create new link "abc.link": that path already exists}
+test fCmd-28.14 {file link: deletes link not dir} -setup {
+    cd [temporaryDirectory]
+} -constraints {linkDirectory} -body {
+    file delete -force abc.link
+    list [file exists abc.link] [file exists abc.dir]
+} -cleanup {
+    cd [workingDirectory]
+} -result {0 1}
+test fCmd-28.15.1 {file link: copies link not dir} -setup {
+    cd [temporaryDirectory]
+    file delete -force abc.link
+} -constraints {linkDirectory dontCopyLinks} -body {
+    file link abc.link abc.dir
+    file copy abc.link abc2.link
+    # abc2.linkdir was a copy of a link to a dir, so it should end up as a
+    # directory, not a link (links trace to endpoint).
+    list [file type abc2.link] [file tail [file link abc.link]]
+} -cleanup {
+    file delete -force abc.link
+    cd [workingDirectory]
+} -result {directory abc.dir}
+test fCmd-28.15.2 {file link: copies link not dir} -setup {
+    cd [temporaryDirectory]
+    file delete -force abc.link
+} -constraints {linkDirectory} -body {
+    file link abc.link abc.dir
+    file copy abc.link abc2.link
+    list [file type abc2.link] [file tail [file link abc2.link]]
+} -cleanup {
+    file delete -force abc.link
+    cd [workingDirectory]
+} -result {link abc.dir}
+cd [temporaryDirectory]
+file delete -force abc.link
+file delete -force abc2.link
+cd abc.dir
+file delete -force abc.file
+file delete -force abc2.file
+cd ..
+file copy abc.file abc.dir
+file copy abc2.file abc.dir
+cd [workingDirectory]
+test fCmd-28.16 {file link: glob inside link} -setup {
+    cd [temporaryDirectory]
+    file delete -force abc.link
+} -constraints {linkDirectory} -body {
+    file link abc.link abc.dir
+    lsort [glob -dir abc.link -tails *]
+} -cleanup {
+    file delete -force abc.link
+    cd [workingDirectory]
+} -result {abc.file abc2.file}
+test fCmd-28.17 {file link: glob -type l} -setup {
+    cd [temporaryDirectory]
+    file link abc.link abc.dir
+} -constraints {linkDirectory} -body {
+    glob -dir [pwd] -type l -tails abc*
+} -cleanup {
+    file delete -force abc.link
+    cd [workingDirectory]
+} -result {abc.link}
+test fCmd-28.18 {file link: glob -type d} -constraints linkDirectory -setup {
+    cd [temporaryDirectory]
+    file link abc.link abc.dir
+} -body {
+    lsort [glob -dir [pwd] -type d -tails abc*]
+} -cleanup {
+    file delete -force abc.link
+    cd [workingDirectory]
+} -result [lsort [list abc.link abc.dir abc2.dir]]
+test fCmd-28.19 {file link: relative paths} -setup {
+    cd [temporaryDirectory]
+} -constraints {win linkDirectory} -body {
+    file mkdir d1/d2/d3
+    file link d1/l2 d1/d2
+} -cleanup {
+    catch {file delete -force d1}
+    cd [workingDirectory]
+} -result d1/d2
+test fCmd-28.20 {file link: relative paths} -setup {
+    cd [temporaryDirectory]
+} -constraints {unix linkDirectory} -body {
+    file mkdir d1/d2/d3
+    file link d1/l2 d1/d2
+} -returnCodes error -cleanup {
+    catch {file delete -force d1}
+    cd [workingDirectory]
+} -result {could not create new link "d1/l2": target "d1/d2" doesn't exist}
+test fCmd-28.21 {file link: relative paths} -setup {
+    cd [temporaryDirectory]
+} -constraints {unix linkDirectory} -body {
+    file mkdir d1/d2/d3
+    file link d1/l2 d2
+} -cleanup {
+    catch {file delete -force d1}
+    cd [workingDirectory]
+} -result d2
+test fCmd-28.22 {file link: relative paths} -setup {
+    cd [temporaryDirectory]
+} -constraints {unix linkDirectory} -body {
+    file mkdir d1/d2/d3
+    catch {file delete -force d1/l2}
+    file link d1/l2 d2/d3
+} -cleanup {
+    catch {file delete -force d1}
+    cd [workingDirectory]
+} -result d2/d3
+try {
+    cd [temporaryDirectory]
+    file delete -force abc.link
+    file delete -force d1/d2
+    file delete -force d1
+} finally {
+    cd [workingDirectory]
+}
+removeFile abc2.file
+removeFile abc.file
+removeDirectory abc2.dir
+removeDirectory abc.dir
+
+test fCmd-29.1 {weird memory corruption fault} -body {
+    open [file join ~a_totally_bogus_user_id/foo bar]
+} -returnCodes error -match glob -result *
+
+test fCmd-30.1 {file writable on 'My Documents'} -setup {
+    # Get the localized version of the folder name by looking in the registry.
+    set mydocsname [registry get {HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders} Personal]
+} -constraints {win reg} -body {
+    file writable $mydocsname
+} -result 1
+test fCmd-30.2 {file readable on 'NTUSER.DAT'} -constraints {win} -body {
+    expr {[info exists env(USERPROFILE)]
+          && [file exists $env(USERPROFILE)/NTUSER.DAT]
+          && [file readable $env(USERPROFILE)/NTUSER.DAT]}
+} -result {1}
+test fCmd-30.3 {file readable on 'pagefile.sys'} -constraints {win} -body {
+    set r {}
+    if {[info exists env(SystemDrive)]} {
+        set path $env(SystemDrive)/pagefile.sys
+        lappend r exists [file exists $path]
+        lappend r readable [file readable $path]
+        lappend r stat [catch {file stat $path a} e] $e
+    }
+    return $r
+} -result {exists 1 readable 0 stat 0 {}}
+
+# cleanup
+cleanup
+if {[testConstraint unix]} {
+    removeDirectory tcl[pid] /tmp
+}
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# fill-column: 78
+# End:
diff --git a/tests/fileName.test b/tests/fileName.test
new file mode 100644
index 0000000..387d844
--- /dev/null
+++ b/tests/fileName.test
@@ -0,0 +1,1633 @@
+# This file tests the filename manipulation routines.
+#
+# This file contains a collection of tests for one or more of the Tcl built-in
+# commands. Sourcing this file into Tcl runs the tests and generates output
+# for errors. No output means no errors were found.
+#
+# Copyright (c) 1995-1996 Sun Microsystems, Inc.
+# Copyright (c) 1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution of
+# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {"::tcltest" ni [namespace children]} {
+    package require tcltest 2
+    namespace import -force ::tcltest::*
+}
+
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
+
+testConstraint testsetplatform [llength [info commands testsetplatform]]
+testConstraint testtranslatefilename [llength [info commands testtranslatefilename]]
+testConstraint linkDirectory 1
+testConstraint symbolicLinkFile 1
+if {[testConstraint win]} {
+    if {[string index $tcl_platform(osVersion) 0] < 5 \
+	    || [lindex [file system [temporaryDirectory]] 1] ne "NTFS"} {
+	testConstraint linkDirectory 0
+    }
+    testConstraint symbolicLinkFile 0
+    testConstraint sharedCdrive [expr {![catch {cd //[info hostname]/c}]}]
+}
+# This match compares the first two words of the result. If the wanted result
+# is "equal", then this is successful if the words are equal. If the wanted
+# result is "not equal", then this is successful if the words are different.
+customMatch compareWords {apply {{a b} {
+    lassign $b w1 w2
+    expr {$a eq "equal" ? $w1 eq $w2 : $w1 ne $w2}
+}}}
+
+proc touch filename {catch {close [open $filename w]}}
+global env
+if {[testConstraint testsetplatform]} {
+    set platform [testgetplatform]
+}
+
+# Caution: when using 'testsetplatform' to test different file name platform
+# descriptions in this file, one must be very careful not to combine such
+# platform manipulation with commands like 'cd', 'pwd'. That is because the
+# latter commands operate on the real filesystem but will potentially have
+# their logic routed through the wrong generic code paths if we've used
+# 'testsetplatform'. This can lead to serious problems, even crashes.
+test filename-1.1 {Tcl_GetPathType: unix} {testsetplatform} {
+    testsetplatform unix
+    file pathtype /
+} absolute
+test filename-1.2 {Tcl_GetPathType: unix} {testsetplatform} {
+    testsetplatform unix
+    file pathtype /foo
+} absolute
+test filename-1.3 {Tcl_GetPathType: unix} {testsetplatform} {
+    testsetplatform unix
+    file pathtype foo
+} relative
+test filename-1.4 {Tcl_GetPathType: unix} {testsetplatform} {
+    testsetplatform unix
+    file pathtype c:/foo
+} relative
+test filename-1.5 {Tcl_GetPathType: unix} {testsetplatform} {
+    testsetplatform unix
+    file pathtype ~
+} absolute
+test filename-1.6 {Tcl_GetPathType: unix} {testsetplatform} {
+    testsetplatform unix
+    file pathtype ~/foo
+} absolute
+test filename-1.7 {Tcl_GetPathType: unix} {testsetplatform} {
+    testsetplatform unix
+    file pathtype ~foo
+} absolute
+test filename-1.8 {Tcl_GetPathType: unix} {testsetplatform} {
+    testsetplatform unix
+    file pathtype ./~foo
+} relative
+
+test filename-3.1 {Tcl_GetPathType: windows} {testsetplatform} {
+    testsetplatform windows
+    file pathtype /
+} volumerelative
+test filename-3.2 {Tcl_GetPathType: windows} {testsetplatform} {
+    testsetplatform windows
+    file pathtype \\
+} volumerelative
+test filename-3.3 {Tcl_GetPathType: windows} {testsetplatform} {
+    testsetplatform windows
+    file pathtype /foo
+} volumerelative
+test filename-3.4 {Tcl_GetPathType: windows} {testsetplatform} {
+    testsetplatform windows
+    file pathtype \\foo
+} volumerelative
+test filename-3.5 {Tcl_GetPathType: windows} {testsetplatform} {
+    testsetplatform windows
+    file pathtype c:/
+} absolute
+test filename-3.6 {Tcl_GetPathType: windows} {testsetplatform} {
+    testsetplatform windows
+    file pathtype c:\\
+} absolute
+test filename-3.7 {Tcl_GetPathType: windows} {testsetplatform} {
+    testsetplatform windows
+    file pathtype c:/foo
+} absolute
+test filename-3.8 {Tcl_GetPathType: windows} {testsetplatform} {
+    testsetplatform windows
+    file pathtype c:\\foo
+} absolute
+test filename-3.9 {Tcl_GetPathType: windows} {testsetplatform} {
+    testsetplatform windows
+    file pathtype c:
+} volumerelative
+test filename-3.10 {Tcl_GetPathType: windows} {testsetplatform} {
+    testsetplatform windows
+    file pathtype c:foo
+} volumerelative
+test filename-3.11 {Tcl_GetPathType: windows} {testsetplatform} {
+    testsetplatform windows
+    file pathtype foo
+} relative
+test filename-3.12 {Tcl_GetPathType: windows} {testsetplatform} {
+    testsetplatform windows
+    file pathtype //foo/bar
+} absolute
+test filename-3.13 {Tcl_GetPathType: windows} {testsetplatform} {
+    testsetplatform windows
+    file pathtype ~foo
+} absolute
+test filename-3.14 {Tcl_GetPathType: windows} {testsetplatform} {
+    testsetplatform windows
+    file pathtype ~
+} absolute
+test filename-3.15 {Tcl_GetPathType: windows} {testsetplatform} {
+    testsetplatform windows
+    file pathtype ~/foo
+} absolute
+test filename-3.16 {Tcl_GetPathType: windows} {testsetplatform} {
+    testsetplatform windows
+    file pathtype ./~foo
+} relative
+
+test filename-4.1 {Tcl_SplitPath: unix} {testsetplatform} {
+    testsetplatform unix
+    file split /
+} {/}
+test filename-4.2 {Tcl_SplitPath: unix} {testsetplatform} {
+    testsetplatform unix
+    file split /foo
+} {/ foo}
+test filename-4.3 {Tcl_SplitPath: unix} {testsetplatform} {
+    testsetplatform unix
+    file split /foo/bar
+} {/ foo bar}
+test filename-4.4 {Tcl_SplitPath: unix} {testsetplatform} {
+    testsetplatform unix
+    file split /foo/bar/baz
+} {/ foo bar baz}
+test filename-4.5 {Tcl_SplitPath: unix} {testsetplatform} {
+    testsetplatform unix
+    file split foo/bar
+} {foo bar}
+test filename-4.6 {Tcl_SplitPath: unix} {testsetplatform} {
+    testsetplatform unix
+    file split ./foo/bar
+} {. foo bar}
+test filename-4.7 {Tcl_SplitPath: unix} {testsetplatform} {
+    testsetplatform unix
+    file split /foo/../././foo/bar
+} {/ foo .. . . foo bar}
+test filename-4.8 {Tcl_SplitPath: unix} {testsetplatform} {
+    testsetplatform unix
+    file split ../foo/bar
+} {.. foo bar}
+test filename-4.9 {Tcl_SplitPath: unix} {testsetplatform} {
+    testsetplatform unix
+    file split {}
+} {}
+test filename-4.10 {Tcl_SplitPath: unix} {testsetplatform} {
+    testsetplatform unix
+    file split .
+} {.}
+test filename-4.11 {Tcl_SplitPath: unix} {testsetplatform} {
+    testsetplatform unix
+    file split ../
+} {..}
+test filename-4.12 {Tcl_SplitPath: unix} {testsetplatform} {
+    testsetplatform unix
+    file split ../..
+} {.. ..}
+test filename-4.13 {Tcl_SplitPath: unix} {testsetplatform} {
+    testsetplatform unix
+    file split //foo
+} "/ foo"
+test filename-4.14 {Tcl_SplitPath: unix} {testsetplatform} {
+    testsetplatform unix
+    file split foo//bar
+} {foo bar}
+test filename-4.15 {Tcl_SplitPath: unix} {testsetplatform} {
+    testsetplatform unix
+    file split ~foo
+} {~foo}
+test filename-4.16 {Tcl_SplitPath: unix} {testsetplatform} {
+    testsetplatform unix
+    file split ~foo/~bar
+} {~foo ./~bar}
+test filename-4.17 {Tcl_SplitPath: unix} {testsetplatform} {
+    testsetplatform unix
+    file split ~foo/~bar/~baz
+} {~foo ./~bar ./~baz}
+test filename-4.18 {Tcl_SplitPath: unix} {testsetplatform} {
+    testsetplatform unix
+    file split foo/bar~/baz
+} {foo bar~ baz}
+if {[testConstraint testsetplatform]} {
+    testsetplatform $platform
+}
+test filename-4.19 {Tcl_SplitPath} -setup {
+    set oldDir [pwd]
+    cd [temporaryDirectory]
+} -body {
+    file mkdir tildetmp
+    set nastydir [file join tildetmp ./~tilde]
+    file mkdir $nastydir
+    set norm [file normalize $nastydir]
+    cd tildetmp
+    cd ./~tilde
+    glob -nocomplain *
+    set idx [string first tildetmp $norm]
+    set norm [string range $norm $idx end]
+    # fix path away so all platforms are the same
+    regsub {(.*):$} $norm {\1} norm
+    regsub -all ":" $norm "/" norm
+    # make sure we can delete the directory we created
+    cd $oldDir
+    file delete -force $nastydir
+    return $norm
+} -cleanup {
+    cd $oldDir
+    catch {file delete -force [file join [temporaryDirectory] tildetmp]}
+} -result {tildetmp/~tilde}
+
+test filename-6.1 {Tcl_SplitPath: win} {testsetplatform} {
+    testsetplatform win
+    file split /
+} {/}
+test filename-6.2 {Tcl_SplitPath: win} {testsetplatform} {
+    testsetplatform win
+    file split /foo
+} {/ foo}
+test filename-6.3 {Tcl_SplitPath: win} {testsetplatform} {
+    testsetplatform win
+    file split /foo/bar
+} {/ foo bar}
+test filename-6.4 {Tcl_SplitPath: win} {testsetplatform} {
+    testsetplatform win
+    file split /foo/bar/baz
+} {/ foo bar baz}
+test filename-6.5 {Tcl_SplitPath: win} {testsetplatform} {
+    testsetplatform win
+    file split foo/bar
+} {foo bar}
+test filename-6.6 {Tcl_SplitPath: win} {testsetplatform} {
+    testsetplatform win
+    file split ./foo/bar
+} {. foo bar}
+test filename-6.7 {Tcl_SplitPath: win} {testsetplatform} {
+    testsetplatform win
+    file split /foo/../././foo/bar
+} {/ foo .. . . foo bar}
+test filename-6.8 {Tcl_SplitPath: win} {testsetplatform} {
+    testsetplatform win
+    file split ../foo/bar
+} {.. foo bar}
+test filename-6.9 {Tcl_SplitPath: win} {testsetplatform} {
+    testsetplatform win
+    file split {}
+} {}
+test filename-6.10 {Tcl_SplitPath: win} {testsetplatform} {
+    testsetplatform win
+    file split .
+} {.}
+test filename-6.11 {Tcl_SplitPath: win} {testsetplatform} {
+    testsetplatform win
+    file split ../
+} {..}
+test filename-6.12 {Tcl_SplitPath: win} {testsetplatform} {
+    testsetplatform win
+    file split ../..
+} {.. ..}
+test filename-6.13 {Tcl_SplitPath: win} {testsetplatform} {
+    testsetplatform win
+    file split //foo
+} {/ foo}
+test filename-6.14 {Tcl_SplitPath: win} {testsetplatform} {
+    testsetplatform win
+    file split foo//bar
+} {foo bar}
+test filename-6.15 {Tcl_SplitPath: win} {testsetplatform} {
+    testsetplatform win
+    file split /\\/foo//bar
+} {//foo/bar}
+test filename-6.16 {Tcl_SplitPath: win} {testsetplatform} {
+    testsetplatform win
+    file split /\\/foo//bar
+} {//foo/bar}
+test filename-6.17 {Tcl_SplitPath: win} {testsetplatform} {
+    testsetplatform win
+    file split /\\/foo//bar
+} {//foo/bar}
+test filename-6.18 {Tcl_SplitPath: win} {testsetplatform} {
+    testsetplatform win
+    file split \\\\foo\\bar
+} {//foo/bar}
+test filename-6.19 {Tcl_SplitPath: win} {testsetplatform} {
+    testsetplatform win
+    file split \\\\foo\\bar/baz
+} {//foo/bar baz}
+test filename-6.20 {Tcl_SplitPath: win} {testsetplatform} {
+    testsetplatform win
+    file split c:/foo
+} {c:/ foo}
+test filename-6.21 {Tcl_SplitPath: win} {testsetplatform} {
+    testsetplatform win
+    file split c:foo
+} {c: foo}
+test filename-6.22 {Tcl_SplitPath: win} {testsetplatform} {
+    testsetplatform win
+    file split c:
+} {c:}
+test filename-6.23 {Tcl_SplitPath: win} {testsetplatform} {
+    testsetplatform win
+    file split c:\\
+} {c:/}
+test filename-6.24 {Tcl_SplitPath: win} {testsetplatform} {
+    testsetplatform win
+    file split c:/
+} {c:/}
+test filename-6.25 {Tcl_SplitPath: win} {testsetplatform} {
+    testsetplatform win
+    file split c:/./..
+} {c:/ . ..}
+test filename-6.26 {Tcl_SplitPath: win} {testsetplatform} {
+    testsetplatform win
+    file split ~foo
+} {~foo}
+test filename-6.27 {Tcl_SplitPath: win} {testsetplatform} {
+    testsetplatform win
+    file split ~foo/~bar
+} {~foo ./~bar}
+test filename-6.28 {Tcl_SplitPath: win} {testsetplatform} {
+    testsetplatform win
+    file split ~foo/~bar/~baz
+} {~foo ./~bar ./~baz}
+test filename-6.29 {Tcl_SplitPath: win} {testsetplatform} {
+    testsetplatform win
+    file split foo/bar~/baz
+} {foo bar~ baz}
+test filename-6.30 {Tcl_SplitPath: win} {testsetplatform} {
+    testsetplatform win
+    file split c:~foo
+} {c: ./~foo}
+
+test filename-7.1 {Tcl_JoinPath: unix} {testsetplatform} {
+    testsetplatform unix
+    file join / a
+} {/a}
+test filename-7.2 {Tcl_JoinPath: unix} {testsetplatform} {
+    testsetplatform unix
+    file join a b
+} {a/b}
+test filename-7.3 {Tcl_JoinPath: unix} {testsetplatform} {
+    testsetplatform unix
+    file join /a c /b d
+} {/b/d}
+test filename-7.4 {Tcl_JoinPath: unix} {testsetplatform} {
+    testsetplatform unix
+    file join /
+} {/}
+test filename-7.5 {Tcl_JoinPath: unix} {testsetplatform} {
+    testsetplatform unix
+    file join a
+} {a}
+test filename-7.6 {Tcl_JoinPath: unix} {testsetplatform} {
+    testsetplatform unix
+    file join {}
+} {}
+test filename-7.7 {Tcl_JoinPath: unix} {testsetplatform} {
+    testsetplatform unix
+    file join /a/ b
+} {/a/b}
+test filename-7.8 {Tcl_JoinPath: unix} {testsetplatform} {
+    testsetplatform unix
+    file join /a// b
+} {/a/b}
+test filename-7.9 {Tcl_JoinPath: unix} {testsetplatform} {
+    testsetplatform unix
+    file join /a/./../. b
+} {/a/./.././b}
+test filename-7.10 {Tcl_JoinPath: unix} {testsetplatform} {
+    testsetplatform unix
+    file join ~ a
+} {~/a}
+test filename-7.11 {Tcl_JoinPath: unix} {testsetplatform} {
+    testsetplatform unix
+    file join ~a ~b
+} {~b}
+test filename-7.12 {Tcl_JoinPath: unix} {testsetplatform} {
+    testsetplatform unix
+    file join ./~a b
+} {./~a/b}
+test filename-7.13 {Tcl_JoinPath: unix} {testsetplatform} {
+    testsetplatform unix
+    file join ./~a ~b
+} {~b}
+test filename-7.14 {Tcl_JoinPath: unix} {testsetplatform} {
+    testsetplatform unix
+    file join ./~a ./~b
+} {./~a/~b}
+test filename-7.15 {Tcl_JoinPath: unix} {testsetplatform} {
+    testsetplatform unix
+    file join a . b
+} {a/./b}
+test filename-7.16 {Tcl_JoinPath: unix} {testsetplatform} {
+    testsetplatform unix
+    file join a . ./~b
+} {a/./~b}
+test filename-7.17 {Tcl_JoinPath: unix} {testsetplatform} {
+    testsetplatform unix
+    file join //a b
+} "/a/b"
+test filename-7.18 {Tcl_JoinPath: unix} {testsetplatform} {
+    testsetplatform unix
+    file join /// a b
+} "/a/b"
+
+test filename-9.1 {Tcl_JoinPath: win} {testsetplatform} {
+    testsetplatform win
+    file join a b
+} {a/b}
+test filename-9.2 {Tcl_JoinPath: win} {testsetplatform} {
+    testsetplatform win
+    file join /a b
+} {/a/b}
+test filename-9.3 {Tcl_JoinPath: win} {testsetplatform} {
+    testsetplatform win
+    file join /a /b
+} {/b}
+test filename-9.4 {Tcl_JoinPath: win} {testsetplatform} {
+    testsetplatform win
+    file join c: foo
+} {c:foo}
+test filename-9.5 {Tcl_JoinPath: win} {testsetplatform} {
+    testsetplatform win
+    file join c:/ foo
+} {c:/foo}
+test filename-9.6 {Tcl_JoinPath: win} {testsetplatform} {
+    testsetplatform win
+    file join c:\\bar foo
+} {c:/bar/foo}
+test filename-9.7 {Tcl_JoinPath: win} {testsetplatform} {
+    testsetplatform win
+    file join /foo c:bar
+} {c:bar}
+test filename-9.8 {Tcl_JoinPath: win} {testsetplatform} {
+    testsetplatform win
+    file join ///host//share dir
+} {//host/share/dir}
+test filename-9.9 {Tcl_JoinPath: win} {testsetplatform} {
+    testsetplatform win
+    file join ~ foo
+} {~/foo}
+test filename-9.10 {Tcl_JoinPath: win} {testsetplatform} {
+    testsetplatform win
+    file join ~/~foo
+} {~/~foo}
+test filename-9.11 {Tcl_JoinPath: win} {testsetplatform} {
+    testsetplatform win
+    file join ~ ./~foo
+} {~/~foo}
+test filename-9.12 {Tcl_JoinPath: win} {testsetplatform} {
+    testsetplatform win
+    file join / ~foo
+} {~foo}
+test filename-9.13 {Tcl_JoinPath: win} {testsetplatform} {
+    testsetplatform win
+    file join ./a/ b c
+} {./a/b/c}
+test filename-9.14 {Tcl_JoinPath: win} {testsetplatform} {
+    testsetplatform win
+    file join ./~a/ b c
+} {./~a/b/c}
+test filename-9.15 {Tcl_JoinPath: win} {testsetplatform} {
+    testsetplatform win
+    file join // host share path
+} {/host/share/path}
+test filename-9.16 {Tcl_JoinPath: win} {testsetplatform} {
+    testsetplatform win
+    file join foo . bar
+} {foo/./bar}
+test filename-9.17 {Tcl_JoinPath: win} {testsetplatform} {
+    testsetplatform win
+    file join foo .. bar
+} {foo/../bar}
+test filename-9.18 {Tcl_JoinPath: win} {testsetplatform} {
+    testsetplatform win
+    file join foo/./bar
+} {foo/./bar}
+test filename-9.19 {Tcl_JoinPath: win} {testsetplatform} {
+    testsetplatform win
+    set res {}
+    lappend res \
+	[file join {C:\foo\bar}] \
+	[file join C:/blah {C:\foo\bar}] \
+	[file join C:/blah C:/blah {C:\foo\bar}]
+} {C:/foo/bar C:/foo/bar C:/foo/bar}
+test filename-9.19.1 {Tcl_JoinPath: win} {testsetplatform} {
+    testsetplatform win
+    set res {}
+    lappend res \
+	[file join {foo\bar}] \
+	[file join C:/blah {foo\bar}] \
+	[file join C:/blah C:/blah {foo\bar}]
+} {foo/bar C:/blah/foo/bar C:/blah/foo/bar}
+test filename-9.19.2 {Tcl_JoinPath: win} {testsetplatform win} {
+    testsetplatform win
+    set res {}
+    lappend res \
+	[file join {foo\bar}] \
+	[file join [pwd] {foo\bar}] \
+	[file join [pwd] [pwd] {foo\bar}]
+    set nres {}
+    foreach elt $res {
+	lappend nres [string map [list [pwd] pwd] $elt]
+    }
+    set nres
+} {foo/bar pwd/foo/bar pwd/foo/bar}
+test filename-9.20 {Tcl_JoinPath: unix} {testsetplatform} {
+    testsetplatform unix
+    set res {}
+    lappend res \
+	[file join {/foo/bar}] \
+	[file join /x {/foo/bar}] \
+	[file join /x /x {/foo/bar}]
+} {/foo/bar /foo/bar /foo/bar}
+test filename-9.23 {Tcl_JoinPath: win} {testsetplatform} {
+    testsetplatform win
+    set res {}
+    lappend res \
+	[file join {foo\bar}] \
+	[file join C:/blah {foo\bar}] \
+	[file join C:/blah C:/blah {foo\bar}]
+    string map [list C:/blah ""] $res
+} {foo/bar /foo/bar /foo/bar}
+test filename-9.24 {Tcl_JoinPath: unix} {testsetplatform} {
+    testsetplatform unix
+    set res {}
+    lappend res \
+	[file join {foo/bar}] \
+	[file join /x {foo/bar}] \
+	[file join /x /x {foo/bar}]
+    string map [list /x ""] $res
+} {foo/bar /foo/bar /foo/bar}
+
+test filename-10.1 {Tcl_TranslateFileName} -body {
+    testsetplatform unix
+    testtranslatefilename foo
+} -result {foo} -constraints {testsetplatform testtranslatefilename}
+test filename-10.2 {Tcl_TranslateFileName} -body {
+    testsetplatform windows
+    testtranslatefilename {c:/foo}
+} -result {c:\foo} -constraints {testsetplatform testtranslatefilename}
+test filename-10.3 {Tcl_TranslateFileName} -body {
+    testsetplatform windows
+    testtranslatefilename {c:/\\foo/}
+} -result {c:\foo} -constraints {testsetplatform testtranslatefilename}
+test filename-10.3.1 {Tcl_TranslateFileName} -body {
+    testsetplatform windows
+    testtranslatefilename {c://///}
+} -result c:\\ -constraints {testsetplatform testtranslatefilename}
+test filename-10.6 {Tcl_TranslateFileName} -setup {
+    global env
+    set temp $env(HOME)
+} -constraints {testsetplatform testtranslatefilename} -body {
+    set env(HOME) "/home/test"
+    testsetplatform unix
+    testtranslatefilename ~/foo
+} -cleanup {
+    set env(HOME) $temp
+} -result {/home/test/foo}
+test filename-10.7 {Tcl_TranslateFileName} -setup {
+    global env
+    set temp $env(HOME)
+} -constraints {testsetplatform testtranslatefilename} -body {
+    unset env(HOME)
+    testsetplatform unix
+    testtranslatefilename ~/foo
+} -returnCodes error -cleanup {
+    set env(HOME) $temp
+} -result {couldn't find HOME environment variable to expand path}
+test filename-10.8 {Tcl_TranslateFileName} -setup {
+    global env
+    set temp $env(HOME)
+} -constraints {testsetplatform testtranslatefilename} -body {
+    set env(HOME) "/home/test"
+    testsetplatform unix
+    testtranslatefilename ~
+} -cleanup {
+    set env(HOME) $temp
+} -result {/home/test}
+test filename-10.9 {Tcl_TranslateFileName} -setup {
+    global env
+    set temp $env(HOME)
+} -constraints {testsetplatform testtranslatefilename} -body {
+    set env(HOME) "/home/test/"
+    testsetplatform unix
+    testtranslatefilename ~
+} -cleanup {
+    set env(HOME) $temp
+} -result {/home/test}
+test filename-10.10 {Tcl_TranslateFileName} -setup {
+    global env
+    set temp $env(HOME)
+} -constraints {testsetplatform testtranslatefilename} -body {
+    set env(HOME) "/home/test/"
+    testsetplatform unix
+    testtranslatefilename ~/foo
+} -cleanup {
+    set env(HOME) $temp
+} -result {/home/test/foo}
+test filename-10.17 {Tcl_TranslateFileName} -setup {
+    global env
+    set temp $env(HOME)
+} -constraints {testsetplatform testtranslatefilename} -body {
+    set env(HOME) "\\home\\"
+    testsetplatform windows
+    testtranslatefilename ~/foo
+} -cleanup {
+    set env(HOME) $temp
+} -result {\home\foo}
+test filename-10.18 {Tcl_TranslateFileName} -setup {
+    global env
+    set temp $env(HOME)
+} -constraints {testsetplatform testtranslatefilename} -body {
+    set env(HOME) "\\home\\"
+    testsetplatform windows
+    testtranslatefilename ~/foo\\bar
+} -cleanup {
+    set env(HOME) $temp
+} -result {\home\foo\bar}
+test filename-10.19 {Tcl_TranslateFileName} -setup {
+    global env
+    set temp $env(HOME)
+} -constraints {testsetplatform testtranslatefilename} -body {
+    set env(HOME) "c:"
+    testsetplatform windows
+    testtranslatefilename ~/foo
+} -cleanup {
+    set env(HOME) $temp
+} -result {c:foo}
+test filename-10.20 {Tcl_TranslateFileName} -returnCodes error -body {
+    testtranslatefilename ~blorp/foo
+} -constraints {testtranslatefilename testtranslatefilename} \
+    -result {user "blorp" doesn't exist}
+test filename-10.21 {Tcl_TranslateFileName} -setup {
+    global env
+    set temp $env(HOME)
+} -constraints {testsetplatform testtranslatefilename} -body {
+    set env(HOME) "c:\\"
+    testsetplatform windows
+    testtranslatefilename ~/foo
+} -cleanup {
+    set env(HOME) $temp
+} -result {c:\foo}
+test filename-10.22 {Tcl_TranslateFileName} -body {
+    testsetplatform windows
+    testtranslatefilename foo//bar
+} -constraints {testsetplatform testtranslatefilename} -result {foo\bar}
+if {[testConstraint testsetplatform]} {
+    testsetplatform $platform
+}
+test filename-10.23 {Tcl_TranslateFileName} -body {
+    # this test fails if ~ouster is not /home/ouster
+    testtranslatefilename ~ouster
+} -constraints {nonPortable testtranslatefilename} -result {/home/ouster}
+test filename-10.24 {Tcl_TranslateFileName} -body {
+    # this test fails if ~ouster is not /home/ouster
+    testtranslatefilename ~ouster/foo
+} -result {/home/ouster/foo} -constraints {nonPortable testtranslatefilename}
+
+test filename-11.1 {Tcl_GlobCmd} -returnCodes error -body {
+    glob
+} -result {no files matched glob patterns ""}
+test filename-11.2 {Tcl_GlobCmd} -returnCodes error -body {
+    glob -gorp
+} -result {bad option "-gorp": must be -directory, -join, -nocomplain, -path, -tails, -types, or --}
+test filename-11.3 {Tcl_GlobCmd} -body {
+    glob -nocomplai
+} -result {}
+test filename-11.4 {Tcl_GlobCmd} -body {
+    glob -nocomplain
+} -result {}
+test filename-11.5 {Tcl_GlobCmd} -returnCodes error -body {
+    glob -nocomplain * ~xyqrszzz
+} -result {user "xyqrszzz" doesn't exist}
+test filename-11.6 {Tcl_GlobCmd} -returnCodes error -body {
+    glob ~xyqrszzz
+} -result {user "xyqrszzz" doesn't exist}
+test filename-11.7 {Tcl_GlobCmd} -returnCodes error -body {
+    glob -- -nocomplain
+} -result {no files matched glob pattern "-nocomplain"}
+test filename-11.8 {Tcl_GlobCmd} -body {
+    glob -nocomplain -- -nocomplain
+} -result {}
+test filename-11.9 {Tcl_GlobCmd} -constraints {testsetplatform} -body {
+    testsetplatform unix
+    glob ~\\xyqrszzz/bar
+} -returnCodes error -result {user "\xyqrszzz" doesn't exist}
+test filename-11.10 {Tcl_GlobCmd} -constraints {testsetplatform} -body {
+    testsetplatform unix
+    glob -nocomplain ~\\xyqrszzz/bar
+} -returnCodes error -result {user "\xyqrszzz" doesn't exist}
+test filename-11.11 {Tcl_GlobCmd} -constraints {testsetplatform} -body {
+    testsetplatform unix
+    glob ~xyqrszzz\\/\\bar
+} -returnCodes error -result {user "xyqrszzz" doesn't exist}
+test filename-11.12 {Tcl_GlobCmd} -constraints {testsetplatform} -setup {
+    testsetplatform unix
+    set home $env(HOME)
+} -body {
+    unset env(HOME)
+    glob ~/*
+} -returnCodes error -cleanup {
+    set env(HOME) $home
+} -result {couldn't find HOME environment variable to expand path}
+if {[testConstraint testsetplatform]} {
+    testsetplatform $platform
+}
+test filename-11.13 {Tcl_GlobCmd} {
+    file join [lindex [glob ~] 0]
+} [file join $env(HOME)]
+set oldpwd [pwd]
+set oldhome $env(HOME)
+catch {cd [makeDirectory tcl[pid]]}
+set env(HOME) [pwd]
+file delete -force globTest
+file mkdir globTest/a1/b1
+file mkdir globTest/a1/b2
+file mkdir globTest/a2/b3
+file mkdir globTest/a3
+touch globTest/x1.c
+touch globTest/y1.c
+touch globTest/z1.c
+touch "globTest/weird name.c"
+touch globTest/a1/b1/x2.c
+touch globTest/a1/b2/y2.c
+touch globTest/.1
+touch globTest/x,z1.c
+test filename-11.14 {Tcl_GlobCmd} {
+    glob ~/globTest
+} [list [file join $env(HOME) globTest]]
+test filename-11.15 {Tcl_GlobCmd} {
+    glob ~\\/globTest
+} [list [file join $env(HOME) globTest]]
+test filename-11.16 {Tcl_GlobCmd} {
+    glob globTest
+} {globTest}
+set globname "globTest"
+set horribleglobname "glob\[\{Test"
+test filename-11.17 {Tcl_GlobCmd} {unix} {
+    lsort [glob -directory $globname *]
+} [lsort [list [file join $globname a1] [file join $globname a2]\
+	[file join $globname a3]\
+	[file join $globname "weird name.c"]\
+	[file join $globname x,z1.c]\
+	[file join $globname x1.c]\
+	[file join $globname y1.c] [file join $globname z1.c]]]
+test filename-11.17.1 {Tcl_GlobCmd} {win} {
+    lsort [glob -directory $globname *]
+} [lsort [list [file join $globname a1] [file join $globname a2]\
+	[file join $globname .1]\
+	[file join $globname a3]\
+	[file join $globname "weird name.c"]\
+	[file join $globname x,z1.c]\
+	[file join $globname x1.c]\
+	[file join $globname y1.c] [file join $globname z1.c]]]
+test filename-11.17.2 {Tcl_GlobCmd} -setup {
+    set dir [pwd]
+} -constraints {notRoot linkDirectory} -body {
+    cd $globname
+    file link -symbolic link a1
+    cd $dir
+    lsort [glob -directory $globname -join * b1]
+} -cleanup {
+    cd $dir
+    file delete [file join $globname link]
+} -result [list [file join $globname a1 b1] \
+	[file join $globname link b1]]
+# Simpler version of the above test to illustrate a given bug.
+test filename-11.17.3 {Tcl_GlobCmd} -setup {
+    set dir [pwd]
+} -constraints {notRoot linkDirectory} -body {
+    cd $globname
+    file link -symbolic link a1
+    cd $dir
+    lsort [glob -directory $globname -type d *]
+} -cleanup {
+    cd $dir
+    file delete [file join $globname link]
+} -result [list [file join $globname a1] \
+	[file join $globname a2] \
+	[file join $globname a3] \
+	[file join $globname link]]
+# Make sure the bugfix isn't too simple. We don't want to break 'glob -type l'
+test filename-11.17.4 {Tcl_GlobCmd} -setup {
+    set dir [pwd]
+} -constraints {notRoot linkDirectory} -body {
+    cd $globname
+    file link -symbolic link a1
+    cd $dir
+    lsort [glob -directory $globname -type l *]
+} -cleanup {
+    cd $dir
+    file delete [file join $globname link]
+} -result [list [file join $globname link]]
+test filename-11.17.5 {Tcl_GlobCmd} {
+    lsort [glob -directory $globname -tails *.c]
+} [lsort [list "weird name.c" x,z1.c x1.c y1.c z1.c]]
+test filename-11.17.6 {Tcl_GlobCmd} {
+    lsort [glob -directory $globname -tails *.c *.c]
+} [lsort [concat [list "weird name.c" x,z1.c x1.c y1.c z1.c] \
+	[list "weird name.c" x,z1.c x1.c y1.c z1.c]]]
+test filename-11.17.7 {Tcl_GlobCmd: broken link and glob -l} -setup {
+    set dir [pwd]
+} -constraints {linkDirectory} -body {
+    cd $globname
+    file mkdir nonexistent
+    file link -symbolic link nonexistent
+    file delete nonexistent
+    cd $dir
+    lsort [glob -nocomplain -directory $globname -type l *]
+} -cleanup {
+    cd $dir
+    file delete [file join $globname link]
+} -result [list [file join $globname link]]
+test filename-11.17.8 {Tcl_GlobCmd: broken link and glob -l} -setup {
+    set dir [pwd]
+} -constraints {symbolicLinkFile} -body {
+    cd $globname
+    touch "nonexistent"
+    file link -symbolic link nonexistent
+    file delete nonexistent
+    cd $dir
+    lsort [glob -nocomplain -directory $globname -type l *]
+} -cleanup {
+    cd $dir
+    file delete [file join $globname link]
+} -result [list [file join $globname link]]
+test filename-11.18 {Tcl_GlobCmd} {unix} {
+    lsort [glob -path $globname/ *]
+} [lsort [list [file join $globname a1] [file join $globname a2]\
+	[file join $globname a3]\
+	[file join $globname "weird name.c"]\
+	[file join $globname x,z1.c]\
+	[file join $globname x1.c]\
+	[file join $globname y1.c] [file join $globname z1.c]]]
+test filename-11.18.1 {Tcl_GlobCmd} {win} {
+    lsort [glob -path $globname/ *]
+} [lsort [list [file join $globname a1] [file join $globname a2]\
+	[file join $globname .1]\
+	[file join $globname a3]\
+	[file join $globname "weird name.c"]\
+	[file join $globname x,z1.c]\
+	[file join $globname x1.c]\
+	[file join $globname y1.c] [file join $globname z1.c]]]
+test filename-11.19 {Tcl_GlobCmd} {unix} {
+    lsort [glob -join -path [string range $globname 0 5] * *]
+} [lsort [list [file join $globname a1] [file join $globname a2]\
+	[file join $globname a3]\
+	[file join $globname "weird name.c"]\
+	[file join $globname x,z1.c]\
+	[file join $globname x1.c]\
+	[file join $globname y1.c] [file join $globname z1.c]]]
+test filename-11.19.1 {Tcl_GlobCmd} {win} {
+    lsort [glob -join -path [string range $globname 0 5] * *]
+} [lsort [list [file join $globname a1] [file join $globname a2]\
+	[file join $globname .1]\
+	[file join $globname a3]\
+	[file join $globname "weird name.c"]\
+	[file join $globname x,z1.c]\
+	[file join $globname x1.c]\
+	[file join $globname y1.c] [file join $globname z1.c]]]
+test filename-11.20 {Tcl_GlobCmd} {
+    lsort [glob -type d -dir $globname *]
+} [lsort [list [file join $globname a1]\
+	[file join $globname a2]\
+	[file join $globname a3]]]
+test filename-11.21 {Tcl_GlobCmd} {
+    lsort [glob -type d -path $globname *]
+} [list $globname]
+test filename-11.21.1 {Tcl_GlobCmd} -body {
+    touch {[tcl].testremains}
+    lsort [glob -path {[tcl]} *]
+} -cleanup {
+    file delete -force {[tcl].testremains}
+} -result {{[tcl].testremains}}
+# Get rid of file/dir if it exists, since it will have been left behind by a
+# previous failed run.
+if {[file exists $horribleglobname]} {
+    file delete -force $horribleglobname
+}
+file rename globTest $horribleglobname
+set globname $horribleglobname
+test filename-11.22 {Tcl_GlobCmd} {unix} {
+    lsort [glob -dir $globname *]
+} [lsort [list [file join $globname a1] [file join $globname a2]\
+	[file join $globname a3]\
+	[file join $globname "weird name.c"]\
+	[file join $globname x,z1.c]\
+	[file join $globname x1.c]\
+	[file join $globname y1.c] [file join $globname z1.c]]]
+test filename-11.22.1 {Tcl_GlobCmd} {win} {
+    lsort [glob -dir $globname *]
+} [lsort [list [file join $globname a1] [file join $globname a2]\
+	[file join $globname .1]\
+	[file join $globname a3]\
+	[file join $globname "weird name.c"]\
+	[file join $globname x,z1.c]\
+	[file join $globname x1.c]\
+	[file join $globname y1.c] [file join $globname z1.c]]]
+test filename-11.23 {Tcl_GlobCmd} {unix} {
+    lsort [glob -path $globname/ *]
+} [lsort [list [file join $globname a1] [file join $globname a2]\
+	[file join $globname a3]\
+	[file join $globname "weird name.c"]\
+	[file join $globname x,z1.c]\
+	[file join $globname x1.c]\
+	[file join $globname y1.c] [file join $globname z1.c]]]
+test filename-11.23.1 {Tcl_GlobCmd} {win} {
+    lsort [glob -path $globname/ *]
+} [lsort [list [file join $globname a1] [file join $globname a2]\
+	[file join $globname .1]\
+	[file join $globname a3]\
+	[file join $globname "weird name.c"]\
+	[file join $globname x,z1.c]\
+	[file join $globname x1.c]\
+	[file join $globname y1.c] [file join $globname z1.c]]]
+test filename-11.24 {Tcl_GlobCmd} {unix} {
+    lsort [glob -join -path [string range $globname 0 5] * *]
+} [lsort [list [file join $globname a1] [file join $globname a2]\
+	[file join $globname a3]\
+	[file join $globname "weird name.c"]\
+	[file join $globname x,z1.c]\
+	[file join $globname x1.c]\
+	[file join $globname y1.c] [file join $globname z1.c]]]
+test filename-11.24.1 {Tcl_GlobCmd} {win} {
+    lsort [glob -join -path [string range $globname 0 5] * *]
+} [lsort [list [file join $globname a1] [file join $globname a2]\
+	[file join $globname .1]\
+	[file join $globname a3]\
+	[file join $globname "weird name.c"]\
+	[file join $globname x,z1.c]\
+	[file join $globname x1.c]\
+	[file join $globname y1.c] [file join $globname z1.c]]]
+test filename-11.25 {Tcl_GlobCmd} {
+    lsort [glob -type d -dir $globname *]
+} [lsort [list [file join $globname a1]\
+	[file join $globname a2]\
+	[file join $globname a3]]]
+test filename-11.25.1 {Tcl_GlobCmd} {
+    lsort [glob -type {d r} -dir $globname *]
+} [lsort [list [file join $globname a1]\
+	[file join $globname a2]\
+	[file join $globname a3]]]
+test filename-11.25.2 {Tcl_GlobCmd} {
+    lsort [glob -type {d r w} -dir $globname *]
+} [lsort [list [file join $globname a1]\
+	[file join $globname a2]\
+	[file join $globname a3]]]
+test filename-11.26 {Tcl_GlobCmd} {
+    glob -type d -path $globname *
+} [list $globname]
+test filename-11.27 {Tcl_GlobCmd} -returnCodes error -body {
+    glob -types abcde *
+} -result {bad argument to "-types": abcde}
+test filename-11.28 {Tcl_GlobCmd} -returnCodes error -body {
+    glob -types z *
+} -result {bad argument to "-types": z}
+test filename-11.29 {Tcl_GlobCmd} -returnCodes error -body {
+    glob -types {abcd efgh} *
+} -result {only one MacOS type or creator argument to "-types" allowed}
+test filename-11.30 {Tcl_GlobCmd} -returnCodes error -body {
+    glob -types {{macintosh type TEXT} {macintosh creator ALFA} efgh} *
+} -result {only one MacOS type or creator argument to "-types" allowed}
+test filename-11.31 {Tcl_GlobCmd} -returnCodes error -body {
+    glob -types
+} -result {missing argument to "-types"}
+test filename-11.32 {Tcl_GlobCmd} -returnCodes error -body {
+    glob -path hello -dir hello *
+} -result {"-directory" cannot be used with "-path"}
+test filename-11.33 {Tcl_GlobCmd} -returnCodes error -body {
+    glob -path
+} -result {missing argument to "-path"}
+test filename-11.34 {Tcl_GlobCmd} -returnCodes error -body {
+    glob -direct
+} -result {missing argument to "-directory"}
+test filename-11.35 {Tcl_GlobCmd} -returnCodes error -body {
+    glob -paths *
+} -result {bad option "-paths": must be -directory, -join, -nocomplain, -path, -tails, -types, or --}
+# Test '-tails' flag to glob.
+test filename-11.36 {Tcl_GlobCmd} -returnCodes error -body {
+    glob -tails *
+} -result {"-tails" must be used with either "-directory" or "-path"}
+test filename-11.37 {Tcl_GlobCmd} {
+    glob -type d -tails -path $globname *
+} [list $globname]
+test filename-11.38 {Tcl_GlobCmd} {
+    glob -tails -path $globname *
+} [list $globname]
+test filename-11.39 {Tcl_GlobCmd} {
+    glob -tails -join -path $globname *
+} [list $globname]
+test filename-11.40 {Tcl_GlobCmd} -body {
+    list [glob -dir [pwd] -tails *] [glob *]
+} -match compareWords -result equal
+test filename-11.41 {Tcl_GlobCmd} -body {
+    list [glob -dir [pwd] -tails *] [glob -dir [pwd] *]
+} -match compareWords -result "not equal"
+test filename-11.42 {Tcl_GlobCmd} -body {
+    set res [list]
+    foreach f [glob -dir [pwd] *] {
+	lappend res [file tail $f]
+    }
+    list $res [glob *]
+} -match compareWords -result equal
+test filename-11.43 {Tcl_GlobCmd} -returnCodes error -body {
+    glob -t *
+} -result {ambiguous option "-t": must be -directory, -join, -nocomplain, -path, -tails, -types, or --}
+test filename-11.44 {Tcl_GlobCmd} -returnCodes error -body {
+    glob -tails -path hello -directory hello *
+} -result {"-directory" cannot be used with "-path"}
+test filename-11.45 {Tcl_GlobCmd on root volume} -setup {
+    set res1 ""
+    set res2 ""
+    set tmpd [pwd]
+} -body {
+    catch {
+	set res1 [glob -dir [lindex [file volumes] 0] -tails *]
+    }
+    catch {
+	cd [lindex [file volumes] 0]
+	set res2 [glob *]
+    }
+    list $res1 $res2
+} -cleanup {
+    cd $tmpd
+} -match compareWords -result equal
+test filename-11.46 {Tcl_GlobCmd} -returnCodes error -body {
+    glob -types abcde -dir foo *
+} -result {bad argument to "-types": abcde}
+test filename-11.47 {Tcl_GlobCmd} -returnCodes error -body {
+    glob -types abcde -path foo *
+} -result {bad argument to "-types": abcde}
+test filename-11.48 {Tcl_GlobCmd} -returnCodes error -body {
+    glob -types abcde -dir foo -join * *
+} -result {bad argument to "-types": abcde}
+test filename-11.49 {Tcl_GlobCmd} -returnCodes error -body {
+    glob -types abcde -path foo -join * *
+} -result {bad argument to "-types": abcde}
+
+file rename $horribleglobname globTest
+set globname globTest
+unset horribleglobname
+
+test filename-12.1 {simple globbing} {unixOrPc} {
+    glob {}
+} {.}
+test filename-12.1.1 {simple globbing} -constraints {unixOrPc} -body {
+    glob -types f {}
+} -returnCodes error -result {no files matched glob pattern ""}
+test filename-12.1.2 {simple globbing} {unixOrPc} {
+    glob -types d {}
+} {.}
+test filename-12.1.3 {simple globbing} {unix} {
+    glob -types hidden {}
+} {.}
+test filename-12.1.4 {simple globbing} -constraints {win} -body {
+    glob -types hidden {}
+} -returnCodes error -result {no files matched glob pattern ""}
+test filename-12.1.5 {simple globbing} -constraints {win} -body {
+    glob -types hidden c:/
+} -returnCodes error -result {no files matched glob pattern "c:/"}
+test filename-12.1.6 {simple globbing} {win} {
+    glob c:/
+} {c:/}
+test filename-12.3 {simple globbing} {
+    glob -nocomplain \{a1,a2\}
+} {}
+set globPreResult globTest/
+set x1 x1.c
+set y1 y1.c
+test filename-12.4 {simple globbing} {unixOrPc} {
+    lsort [glob globTest/x1.c globTest/y1.c globTest/foo]
+} "$globPreResult$x1 $globPreResult$y1"
+test filename-12.5 {simple globbing} {
+    glob globTest\\/x1.c
+} "$globPreResult$x1"
+test filename-12.6 {simple globbing} {
+    glob globTest\\/\\x1.c
+} "$globPreResult$x1"
+test filename-12.7 {globbing at filesystem root} -constraints {unix} -body {
+    list [glob -nocomplain /*] [glob -path / *]
+} -match compareWords -result equal
+test filename-12.8 {globbing at filesystem root} -constraints {unix} -body {
+    set first [string range [lindex [glob -type d /*] 0] 0 1]
+    list [glob -nocomplain ${first}*] [glob -path $first *]
+} -match compareWords -result equal
+test filename-12.9 {globbing at filesystem root} -constraints {win} -body {
+    # Can't grab just anything from 'file volumes' because we need a dir that
+    # has subdirs - assume that C:/ exists across Windows machines.
+    set first [string range [lindex [glob -type d C:/*] 0] 0 3]
+    list [glob -nocomplain ${first}*] [glob -path $first *]
+} -match compareWords -result equal
+test filename-12.10 {globbing with volume relative paths} -setup {
+    set pwd [pwd]
+} -body {
+    set dir [lindex [glob -type d C:/*] 0]
+    cd C:/
+    list [glob -nocomplain [string range $dir 2 end]] [list $dir]
+} -cleanup {
+    cd $pwd
+} -constraints {win} -match compareWords -result equal
+
+test filename-13.1 {globbing with brace substitution} {
+    glob globTest/\{\}
+} "$globPreResult"
+test filename-13.2 {globbing with brace substitution} -body {
+    glob globTest/\{
+} -returnCodes error -result {unmatched open-brace in file name}
+test filename-13.3 {globbing with brace substitution} -body {
+    glob globTest/\{\\\}
+} -returnCodes error -result {unmatched open-brace in file name}
+test filename-13.4 {globbing with brace substitution} -body {
+    glob globTest/\{\\
+} -returnCodes error -result {unmatched open-brace in file name}
+test filename-13.5 {globbing with brace substitution} -body {
+    glob globTest/\}
+} -returnCodes error -result {unmatched close-brace in file name}
+test filename-13.6 {globbing with brace substitution} {
+    glob globTest/\{\}x1.c
+} "$globPreResult$x1"
+test filename-13.7 {globbing with brace substitution} {
+    glob globTest/\{x\}1.c
+} "$globPreResult$x1"
+test filename-13.8 {globbing with brace substitution} {
+    glob globTest/\{x\{\}\}1.c
+} "$globPreResult$x1"
+test filename-13.9 {globbing with brace substitution} {
+    lsort [glob globTest/\{x,y\}1.c]
+} [list $globPreResult$x1 $globPreResult$y1]
+test filename-13.10 {globbing with brace substitution} {
+    lsort [glob globTest/\{x,,y\}1.c]
+} [list $globPreResult$x1 $globPreResult$y1]
+test filename-13.11 {globbing with brace substitution} {unixOrPc} {
+    lsort [glob globTest/\{x,x\\,z,z\}1.c]
+} [lsort {globTest/x1.c globTest/x,z1.c globTest/z1.c}]
+test filename-13.13 {globbing with brace substitution} {
+    lsort [glob globTest/{a,b,x,y}1.c]
+} [list $globPreResult$x1 $globPreResult$y1]
+test filename-13.14 {globbing with brace substitution} {unixOrPc} {
+    lsort [glob {globTest/{x1,y2,weird name}.c}]
+} {{globTest/weird name.c} globTest/x1.c}
+test filename-13.16 {globbing with brace substitution} {unixOrPc} {
+    lsort [glob globTest/{x1.c,a1/*}]
+} {globTest/a1/b1 globTest/a1/b2 globTest/x1.c}
+test filename-13.18 {globbing with brace substitution} {unixOrPc} {
+    lsort [glob globTest/{x1.c,{a},a1/*}]
+} {globTest/a1/b1 globTest/a1/b2 globTest/x1.c}
+test filename-13.20 {globbing with brace substitution} {unixOrPc} {
+    lsort [glob globTest/{a,x}1/*/{x,y}*]
+} {globTest/a1/b1/x2.c globTest/a1/b2/y2.c}
+test filename-13.22 {globbing with brace substitution} -body {
+    glob globTest/\{a,x\}1/*/\{
+} -returnCodes error -result {unmatched open-brace in file name}
+
+test filename-14.1 {asterisks, question marks, and brackets} {unixOrPc} {
+    lsort [glob glo*/*.c]
+} {{globTest/weird name.c} globTest/x,z1.c globTest/x1.c globTest/y1.c globTest/z1.c}
+test filename-14.3 {asterisks, question marks, and brackets} {unixOrPc} {
+    lsort [glob globTest/?1.c]
+} {globTest/x1.c globTest/y1.c globTest/z1.c}
+test filename-14.5 {asterisks, question marks, and brackets} -setup {
+    # The current directory could be anywhere; do this to stop spurious
+    # matches
+    file mkdir globTestContext
+    file rename globTest [file join globTestContext globTest]
+    set savepwd [pwd]
+    cd globTestContext
+} -constraints {unixOrPc} -body {
+    lsort [glob */*/*/*.c]
+} -cleanup {
+    # Reset to where we were
+    cd $savepwd
+    file rename [file join globTestContext globTest] globTest
+    file delete globTestContext
+} -result {globTest/a1/b1/x2.c globTest/a1/b2/y2.c}
+test filename-14.7 {asterisks, question marks, and brackets} {unix} {
+    lsort [glob globTest/*]
+} {globTest/a1 globTest/a2 globTest/a3 {globTest/weird name.c} globTest/x,z1.c globTest/x1.c globTest/y1.c globTest/z1.c}
+test filename-14.7.1 {asterisks, question marks, and brackets} {win} {
+    lsort [glob globTest/*]
+} {globTest/.1 globTest/a1 globTest/a2 globTest/a3 {globTest/weird name.c} globTest/x,z1.c globTest/x1.c globTest/y1.c globTest/z1.c}
+test filename-14.9 {asterisks, question marks, and brackets} {unixOrPc} {
+    lsort [glob globTest/.*]
+} {globTest/. globTest/.. globTest/.1}
+test filename-14.11 {asterisks, question marks, and brackets} {unixOrPc} {
+    lsort [glob globTest/*/*]
+} {globTest/a1/b1 globTest/a1/b2 globTest/a2/b3}
+test filename-14.13 {asterisks, question marks, and brackets} {unixOrPc} {
+    lsort [glob {globTest/[xyab]1.*}]
+} {globTest/x1.c globTest/y1.c}
+test filename-14.15 {asterisks, question marks, and brackets} {unixOrPc} {
+    lsort [glob globTest/*/]
+} {globTest/a1/ globTest/a2/ globTest/a3/}
+test filename-14.17 {asterisks, question marks, and brackets} -setup {
+    global env
+    set temp $env(HOME)
+} -body {
+    set env(HOME) [file join $env(HOME) globTest]
+    glob ~/z*
+} -cleanup {
+    set env(HOME) $temp
+} -result [list [file join $env(HOME) globTest z1.c]]
+test filename-14.18 {asterisks, question marks, and brackets} {unixOrPc} {
+    lsort [glob globTest/*.c goo/*]
+} {{globTest/weird name.c} globTest/x,z1.c globTest/x1.c globTest/y1.c globTest/z1.c}
+test filename-14.20 {asterisks, question marks, and brackets} {
+    glob -nocomplain goo/*
+} {}
+test filename-14.21 {asterisks, question marks, and brackets} -body {
+    glob globTest/*/gorp
+} -returnCodes error -result {no files matched glob pattern "globTest/*/gorp"}
+test filename-14.22 {asterisks, question marks, and brackets} -body {
+    glob goo/* x*z foo?q
+} -returnCodes error -result {no files matched glob patterns "goo/* x*z foo?q"}
+test filename-14.23 {slash globbing} {unix} {
+    glob /
+} /
+test filename-14.23.2 {slash globbing} {win} {
+    glob /
+} [file norm /]
+test filename-14.24 {slash globbing} {win} {
+    glob {\\}
+} [file norm /]
+test filename-14.25 {type specific globbing} {unix} {
+    lsort [glob -dir globTest -types f *]
+} [lsort [list \
+	[file join $globname "weird name.c"]\
+	[file join $globname x,z1.c]\
+	[file join $globname x1.c]\
+	[file join $globname y1.c] [file join $globname z1.c]]]
+test filename-14.25.1 {type specific globbing} {win} {
+    lsort [glob -dir globTest -types f *]
+} [lsort [list \
+	[file join $globname .1]\
+	[file join $globname "weird name.c"]\
+	[file join $globname x,z1.c]\
+	[file join $globname x1.c]\
+	[file join $globname y1.c] [file join $globname z1.c]]]
+test filename-14.26 {type specific globbing} {
+    glob -nocomplain -dir globTest -types {readonly} *
+} {}
+test filename-14.27 {Bug 2710920} {unixOrPc} {
+    file tail [lindex [lsort [glob globTest/*/]] 0]
+} a1
+test filename-14.28 {Bug 2710920} {unixOrPc} {
+    file dirname [lindex [lsort [glob globTest/*/]] 0]
+} globTest
+test filename-14.29 {Bug 2710920} {unixOrPc} {
+    file extension [lindex [lsort [glob globTest/*/]] 0]
+} {}
+test filename-14.30 {Bug 2710920} {unixOrPc} {
+    file rootname [lindex [lsort [glob globTest/*/]] 0]
+} globTest/a1/
+
+test filename-14.31 {Bug 2918610} -setup {
+    set d [makeDirectory foo]
+    makeFile {} bar.soom $d
+} -body {
+    foreach fn [glob $d/bar.soom] {
+        set root [file rootname $fn]
+        close [open $root {WRONLY CREAT}]
+    }
+    llength [glob -directory $d *]
+} -cleanup {
+    file delete -force $d/bar
+    removeFile bar.soom $d
+    removeDirectory foo
+} -result 2
+
+unset globname
+
+# The following tests are only valid for Unix systems. On some systems, like
+# AFS, "000" protection doesn't prevent access by owner, so the following test
+# is not portable.
+
+catch {file attributes globTest/a1 -permissions 0000}
+test filename-15.1 {unix specific globbing} {unix nonPortable} {
+    string tolower [list [catch {glob globTest/a1/*} msg] $msg $errorCode]
+} {1 {couldn't read directory "globtest/a1": permission denied} {posix eacces {permission denied}}}
+test filename-15.2 {unix specific no complain: no errors} {unix nonPortable} {
+    glob -nocomplain globTest/a1/*
+} {}
+test filename-15.3 {unix specific no complain: no errors, good result} \
+	{unix nonPortable} {
+    # test fails because if an error occurs, the interp's result is reset...
+    glob -nocomplain globTest/a2 globTest/a1/* globTest/a3
+} {globTest/a2 globTest/a3}
+catch {file attributes globTest/a1 -permissions 0755}
+test filename-15.4 {unix specific no complain: no errors, good result} \
+	{unix nonPortable} {
+    # test fails because if an error occurs, the interp's result is reset...
+    # or you don't run at scriptics where the outser and welch users exists
+    glob -nocomplain ~ouster ~foo ~welch
+} {/home/ouster /home/welch}
+test filename-15.4.1 {no complain: errors, sequencing} {
+    # test used to fail because if an error occurs, the interp's result is
+    # reset... But, the sequence means we throw a different error first.
+    list [catch {glob -nocomplain ~wontexist ~blahxyz ~} res1] $res1 \
+	[catch {glob -nocomplain ~ ~blahxyz ~wontexist} res2] $res2
+} {1 {user "wontexist" doesn't exist} 1 {user "blahxyz" doesn't exist}}
+test filename-15.4.2 {no complain: errors, sequencing} -body {
+    # test used to fail because if an error occurs, the interp's result is
+    # reset...
+    list [list [catch {glob -nocomplain ~wontexist *} res1] $res1] \
+	[list [catch {glob -nocomplain * ~wontexist} res2] $res2]
+} -match compareWords -result equal
+test filename-15.5 {unix specific globbing} {unix nonPortable} {
+    glob ~ouster/.csh*
+} "/home/ouster/.cshrc"
+touch globTest/odd\\\[\]*?\{\}name
+test filename-15.6 {unix specific globbing} -constraints {unix} -setup {
+    global env
+    set temp $env(HOME)
+} -body {
+    set env(HOME) $env(HOME)/globTest/odd\\\[\]*?\{\}name
+    glob ~
+} -cleanup {
+    set env(HOME) $temp
+} -result [list [lindex [glob ~] 0]/globTest/odd\\\[\]*?\{\}name]
+catch {file delete -force globTest/odd\\\[\]*?\{\}name}
+test filename-15.7 {win specific globbing} -constraints {win} -body {
+    glob ~
+} -match regexp -result {[^/]$}
+test filename-15.8 {win and unix specific globbing} -constraints {unixOrWin} -setup {
+    global env
+    set temp $env(HOME)
+} -body {
+    touch $env(HOME)/globTest/anyname
+    set env(HOME) $env(HOME)/globTest/anyname
+    glob ~
+} -cleanup {
+    set env(HOME) $temp
+    catch {file delete -force $env(HOME)/globTest/anyname}
+} -result [list [lindex [glob ~] 0]/globTest/anyname]
+
+# The following tests are only valid for Windows systems.
+set oldDir [pwd]
+if {[testConstraint win]} {
+    cd c:/
+    file delete -force globTest
+    file mkdir globTest
+    touch globTest/x1.BAT
+    touch globTest/y1.Bat
+    touch globTest/z1.bat
+}
+
+test filename-16.1 {windows specific globbing} {win} {
+    lsort [glob globTest/*.bat]
+} {globTest/x1.BAT globTest/y1.Bat globTest/z1.bat}
+test filename-16.2 {windows specific globbing} {win} {
+    glob c:
+} c:
+test filename-16.2.1 {windows specific globbing} -constraints {win} -setup {
+    set dir [pwd]
+} -body {
+    cd C:/
+    glob c:
+} -cleanup {
+    cd $dir
+} -result c:
+test filename-16.3 {windows specific globbing} {win} {
+    glob -nocomplain c:\\\\
+} c:/
+test filename-16.4 {windows specific globbing} {win} {
+    glob -nocomplain c:/
+} c:/
+test filename-16.5 {windows specific globbing} {win} {
+    glob -nocomplain c:*bTest
+} c:globTest
+test filename-16.6 {windows specific globbing} {win} {
+    glob -nocomplain c:\\\\*bTest
+} c:/globTest
+test filename-16.7 {windows specific globbing} {win} {
+    glob -nocomplain c:/*bTest
+} c:/globTest
+test filename-16.8 {windows specific globbing} {win} {
+    lsort [glob -nocomplain c:globTest/*.bat]
+} {c:globTest/x1.BAT c:globTest/y1.Bat c:globTest/z1.bat}
+test filename-16.9 {windows specific globbing} {win} {
+    lsort [glob -nocomplain c:/globTest/*.bat]
+} {c:/globTest/x1.BAT c:/globTest/y1.Bat c:/globTest/z1.bat}
+test filename-16.10 {windows specific globbing} {win} {
+    lsort [glob -nocomplain c:globTest\\\\*.bat]
+} {c:globTest/x1.BAT c:globTest/y1.Bat c:globTest/z1.bat}
+test filename-16.11 {windows specific globbing} {win} {
+    lsort [glob -nocomplain c:\\\\globTest\\\\*.bat]
+} {c:/globTest/x1.BAT c:/globTest/y1.Bat c:/globTest/z1.bat}
+# some tests require a shared C drive
+test filename-16.12 {windows specific globbing} {win sharedCdrive} {
+    cd //[info hostname]/c
+    glob //[info hostname]/c/*Test
+} //[info hostname]/c/globTest
+test filename-16.13 {windows specific globbing} {win sharedCdrive} {
+    cd //[info hostname]/c
+    glob "\\\\\\\\[info hostname]\\\\c\\\\*Test"
+} //[info hostname]/c/globTest
+test filename-16.14 {windows specific globbing} {win} {
+    cd [lindex [glob -types d -dir C:/ *] 0]
+    expr {".." in [glob {{.,*}*}]}
+} {1}
+test filename-16.15 {windows specific globbing} {win} {
+    cd [lindex [glob -types d -dir C:/ *] 0]
+    glob ..
+} {..}
+test filename-16.16 {windows specific globbing} {win} {
+    file tail [lindex [glob -nocomplain "[lindex [glob -types d -dir C:/ *] 0]/.."] 0]
+} {..}
+test filename-16.17 {windows specific globbing} -constraints {win} -body {
+    cd C:/
+    # Ensure correct trimming of tails with absolute and volume relative
+    # globbing.
+    list [glob -nocomplain -tails -dir C:/ *] \
+	[glob -nocomplain -tails -dir C: *]
+} -match compareWords -result equal
+
+# Put the working directory back now that we're done with globbing in C:/
+if {[testConstraint win]} {
+    cd $oldDir
+}
+
+test filename-17.1 {windows specific special files} {testsetplatform} {
+    testsetplatform win
+    list [file pathtype com1] [file pathtype con] [file pathtype lpt3] \
+	[file pathtype prn] [file pathtype nul] [file pathtype aux] \
+	[file pathtype foo]
+} {absolute absolute absolute absolute absolute absolute relative}
+if {[testConstraint testsetplatform]} {
+    testsetplatform $platform
+}
+test filename-17.2 {windows specific glob with executable} -body {
+    makeDirectory execglob
+    foreach ext {exe com cmd bat notexecutable} {
+        makeFile contents execglob/abc.$ext
+    }
+    lsort [glob -nocomplain -dir [temporaryDirectory]/execglob -tails -types x *]
+} -constraints {win} -cleanup {
+    foreach ext {exe com cmd bat ps1 notexecutable} {
+        removeFile execglob/abc.$ext
+    }
+    removeDirectory execglob
+} -result {abc.bat abc.cmd abc.com abc.exe}
+test filename-17.3 {Bug 2571597} win {
+    set p /a
+    file pathtype $p
+    file normalize $p
+    file pathtype $p
+} volumerelative
+
+test fileName-18.1 {windows - split ADS name correctly} {win} {
+    # bug 1194458
+    set x [file split c:/c:d]
+    list $x [file join {*}$x]
+} {{c:/ ./c:d} c:/c:d}
+
+test fileName-19.1 {ensure that [Bug 1325099] stays fixed} {
+    # Any non-crashing result is OK
+    list [file exists ~//.nonexistant_file] [file exists ~///.nonexistant_file]
+} {0 0}
+
+test fileName-20.1 {Bug 1750300} -setup {
+    set d [makeDirectory foo]
+    makeFile {} TAGS $d
+} -body {
+    llength [glob -nocomplain -directory $d -- TAGS one two]
+} -cleanup {
+    removeFile TAGS $d
+    removeDirectory foo
+} -result 1
+test fileName-20.2 {Bug 1750300} -setup {
+    set d [makeDirectory foo]
+    makeFile {} TAGS $d
+} -body {
+    llength [glob -nocomplain -directory $d -types {} -- TAGS one two]
+} -cleanup {
+    removeFile TAGS $d
+    removeDirectory foo
+} -result 1
+test fileName-20.3 {Bug 1750300} -setup {
+    set d [makeDirectory foo]
+    makeFile {} TAGS $d
+} -body {
+    llength [glob -nocomplain -directory $d -types {} -- *U*]
+} -cleanup {
+    removeFile TAGS $d
+    removeDirectory foo
+} -result 0
+test fileName-20.4 {Bug 1750300} -setup {
+    set d [makeDirectory foo]
+    makeFile {} TAGS $d
+} -body {
+    llength [glob -nocomplain -directory $d -types {} -- URGENT Urkle]
+} -cleanup {
+    removeFile TAGS $d
+    removeDirectory foo
+} -result 0
+test fileName-20.5 {Bug 2837800} -setup {
+    set dd [makeDirectory isolate]
+    set d [makeDirectory ./~foo $dd]
+    makeFile {} test $d
+    set savewd [pwd]
+    cd $dd
+} -body {
+    glob -nocomplain */test
+} -cleanup {
+    cd $savewd
+    removeFile test $d
+    removeDirectory ./~foo $dd
+    removeDirectory isolate
+} -result ~foo/test
+test fileName-20.6 {Bug 2837800} -setup {
+    # Recall that we have $env(HOME) set so that references
+    # to ~ point to [temporaryDirectory]
+    makeFile {} test ~
+    set dd [makeDirectory isolate]
+    set d [makeDirectory ./~ $dd]
+    set savewd [pwd]
+    cd $dd
+} -body {
+    glob -nocomplain */test
+} -cleanup {
+    cd $savewd
+    removeDirectory ./~ $dd
+    removeDirectory isolate
+    removeFile test ~
+} -result {}
+test fileName-20.7 {Bug 2806250} -setup {
+    set savewd [pwd]
+    cd [temporaryDirectory]
+    set d [makeDirectory isolate]
+    makeFile {} ./~test $d
+} -body {
+    file exists [lindex [glob -nocomplain isolate/*] 0]
+} -cleanup {
+    removeFile ./~test $d
+    removeDirectory isolate
+    cd $savewd
+} -result 1
+test fileName-20.8 {Bug 2806250} -setup {
+    set savewd [pwd]
+    cd [temporaryDirectory]
+    set d [makeDirectory isolate]
+    makeFile {} ./~test $d
+} -body {
+    file tail [lindex [glob -nocomplain isolate/*] 0]
+} -cleanup {
+    removeFile ./~test $d
+    removeDirectory isolate
+    cd $savewd
+} -result ./~test
+test fileName-20.9 {globbing for special chars} -setup {
+    makeFile {} test ~
+    set d [makeDirectory isolate]
+    set savewd [pwd]
+    cd $d
+} -body {
+   glob -nocomplain -directory ~ test
+} -cleanup {
+    cd $savewd
+    removeDirectory isolate
+    removeFile test ~
+} -result ~/test
+test fileName-20.10 {globbing for special chars} -setup {
+    set s [makeDirectory sub ~]
+    makeFile {} fileName-20.10 $s
+    set d [makeDirectory isolate]
+    set savewd [pwd]
+    cd $d
+} -body {
+   glob -nocomplain -directory ~ -join * fileName-20.10
+} -cleanup {
+    cd $savewd
+    removeDirectory isolate
+    removeFile fileName-20.10 $s
+    removeDirectory sub ~
+} -result ~/sub/fileName-20.10
+
+# cleanup
+catch {file delete -force C:/globTest}
+cd [temporaryDirectory]
+file delete -force globTest
+cd $oldpwd
+catch {removeDirectory tcl[pid]}
+set env(HOME) $oldhome
+if {[testConstraint testsetplatform]} {
+    testsetplatform $platform
+    catch {unset platform}
+}
+catch {unset oldhome temp result globPreResult}
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/tests/fileSystem.test b/tests/fileSystem.test
new file mode 100644
index 0000000..9fe4fe9
--- /dev/null
+++ b/tests/fileSystem.test
@@ -0,0 +1,956 @@
+# This file tests the filesystem and vfs internals.
+#
+# This file contains a collection of tests for one or more of the Tcl built-in
+# commands. Sourcing this file into Tcl runs the tests and generates output
+# for errors. No output means no errors were found.
+#
+# Copyright (c) 2002 Vincent Darley.
+#
+# See the file "license.terms" for information on usage and redistribution of
+# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+package require tcltest 2
+namespace eval ::tcl::test::fileSystem {
+    namespace import ::tcltest::*
+
+    catch {
+	file delete -force link.file
+	file delete -force dir.link
+	file delete -force [file join dir.dir linkinside.file]
+    }
+
+testConstraint loaddll 0
+catch {
+    ::tcltest::loadTestedCommands
+    package require -exact Tcltest [info patchlevel]
+    set ::ddever [package require dde]
+    set ::ddelib [lindex [package ifneeded dde $::ddever] 1]
+    set ::regver  [package require registry]
+    set ::reglib [lindex [package ifneeded registry $::regver] 1]
+    testConstraint loaddll 1
+}
+
+# Test for commands defined in Tcltest executable
+testConstraint testfilesystem  	    [llength [info commands ::testfilesystem]]
+testConstraint testsetplatform 	    [llength [info commands ::testsetplatform]]
+testConstraint testsimplefilesystem [llength [info commands ::testsimplefilesystem]]
+
+cd [tcltest::temporaryDirectory]
+makeFile "test file" gorp.file
+makeDirectory dir.dir
+makeDirectory [file join dir.dir dirinside.dir]
+makeFile "test file in directory" [file join dir.dir inside.file]
+
+testConstraint unusedDrive 0
+testConstraint moreThanOneDrive 0
+apply {{} {
+    # The variables 'drive' and 'drives' will be used below.
+    variable drive {} drives {}
+    if {[testConstraint win]} {
+	set vols [string map [list :/ {}] [file volumes]]
+	for {set i 0} {$i < 26} {incr i} {
+	    set drive [format %c [expr {$i + 65}]]
+	    if {$drive ni $vols} {
+		testConstraint unusedDrive 1
+		break
+	    }
+	}
+
+	set dir [pwd]
+	try {
+	    foreach vol [file volumes] {
+		if {![catch {cd $vol}]} {
+		    lappend drives $vol
+		}
+	    }
+	    testConstraint moreThanOneDrive [llength $drives]
+	} finally {
+	    cd $dir
+	}
+    }
+} ::tcl::test::fileSystem}
+
+proc testPathEqual {one two} {
+    if {$one eq $two} {
+	return "ok"
+    }
+    return "not equal: $one $two"
+}
+
+testConstraint hasLinks [expr {![catch {
+    file link link.file gorp.file
+    cd dir.dir
+    file link \
+	[file join linkinside.file] \
+	[file join inside.file]
+    cd ..
+    file link dir.link dir.dir
+    cd dir.dir
+    file link [file join dirinside.link] \
+	[file join dirinside.dir]
+    cd ..
+}]}]
+
+if {[testConstraint testsetplatform]} {
+    set platform [testgetplatform]
+}
+
+# ----------------------------------------------------------------------
+
+test filesystem-1.0 {link normalisation} {hasLinks} {
+   string equal [file normalize gorp.file] [file normalize link.file]
+} {0}
+test filesystem-1.1 {link normalisation} {hasLinks} {
+   string equal [file normalize dir.dir] [file normalize dir.link]
+} {0}
+test filesystem-1.2 {link normalisation} {hasLinks unix} {
+    testPathEqual [file normalize [file join gorp.file foo]] \
+	[file normalize [file join link.file foo]]
+} ok
+test filesystem-1.3 {link normalisation} {hasLinks} {
+    testPathEqual [file normalize [file join dir.dir foo]] \
+	[file normalize [file join dir.link foo]]
+} ok
+test filesystem-1.4 {link normalisation} {hasLinks} {
+    testPathEqual [file normalize [file join dir.dir inside.file]] \
+	[file normalize [file join dir.link inside.file]]
+} ok
+test filesystem-1.5 {link normalisation} {hasLinks} {
+    testPathEqual [file normalize [file join dir.dir linkinside.file]] \
+	[file normalize [file join dir.dir linkinside.file]]
+} ok
+test filesystem-1.6 {link normalisation} {hasLinks} {
+    string equal [file normalize [file join dir.dir linkinside.file]] \
+	[file normalize [file join dir.link inside.file]]
+} {0}
+test filesystem-1.7 {link normalisation} {hasLinks unix} {
+    testPathEqual [file normalize [file join dir.link linkinside.file foo]] \
+	[file normalize [file join dir.dir inside.file foo]]
+} ok
+test filesystem-1.8 {link normalisation} {hasLinks} {
+    string equal [file normalize [file join dir.dir linkinside.filefoo]] \
+	[file normalize [file join dir.link inside.filefoo]]
+} {0}
+test filesystem-1.9 {link normalisation} -setup {
+    file delete -force dir.link
+} -constraints {unix hasLinks} -body {
+    file link dir.link [file nativename dir.dir]
+    testPathEqual [file normalize [file join dir.dir linkinside.file foo]] \
+	[file normalize [file join dir.link inside.file foo]]
+} -result ok
+test filesystem-1.10 {link normalisation: double link} -constraints {
+    unix hasLinks
+} -body {
+    file link dir2.link dir.link
+    testPathEqual [file normalize [file join dir.dir linkinside.file foo]] \
+	[file normalize [file join dir2.link inside.file foo]]
+} -cleanup {
+    file delete dir2.link
+} -result ok 
+makeDirectory dir2.file
+test filesystem-1.11 {link normalisation: double link, back in tree} {unix hasLinks} {
+    file link dir2.link dir.link
+    file link [file join dir2.file dir2.link] [file join .. dir2.link]
+    testPathEqual [file normalize [file join dir.dir linkinside.file foo]] \
+	[file normalize [file join dir2.file dir2.link inside.file foo]]
+} ok
+test filesystem-1.12 {file new native path} {} {
+    for {set i 0} {$i < 10} {incr i} {
+	foreach f [lsort [glob -nocomplain -type l *]] {
+	    catch {file readlink $f}
+	}
+    }
+    # If we reach here we've succeeded. We used to crash above.
+    expr 1
+} {1}
+test filesystem-1.13 {file normalisation} {win} {
+    # This used to be broken
+    file normalize C:/thislongnamedoesntexist
+} {C:/thislongnamedoesntexist}
+test filesystem-1.14 {file normalisation} {win} {
+    # This used to be broken
+    file normalize c:/
+} {C:/}
+test filesystem-1.15 {file normalisation} {win} {
+    file normalize c:/../
+} {C:/}
+test filesystem-1.16 {file normalisation} {win} {
+    file normalize c:/.
+} {C:/}
+test filesystem-1.17 {file normalisation} {win} {
+    file normalize c:/..
+} {C:/}
+test filesystem-1.17.1 {file normalisation} {win} {
+    file normalize c:\\..
+} {C:/}
+test filesystem-1.18 {file normalisation} {win} {
+    file normalize c:/./
+} {C:/}
+test filesystem-1.19 {file normalisation} {win unusedDrive} {
+    file normalize ${drive}:/./../../..
+} "${drive}:/"
+test filesystem-1.20 {file normalisation} {win} {
+    file normalize //name/foo/../
+} {//name/foo}
+test filesystem-1.21 {file normalisation} {win} {
+    file normalize C:///foo/./
+} {C:/foo}
+test filesystem-1.22 {file normalisation} {win} {
+    file normalize //name/foo/.
+} {//name/foo}
+test filesystem-1.23 {file normalisation} {win} {
+    file normalize c:/./foo
+} {C:/foo}
+test filesystem-1.24 {file normalisation} {win unusedDrive} {
+    file normalize ${drive}:/./../../../a
+} "${drive}:/a"
+test filesystem-1.25 {file normalisation} {win unusedDrive} {
+    file normalize ${drive}:/./.././../../a
+} "${drive}:/a"
+test filesystem-1.25.1 {file normalisation} {win unusedDrive} {
+    file normalize ${drive}:/./.././..\\..\\a\\bb
+} "${drive}:/a/bb"
+test filesystem-1.26 {link normalisation: link and ..} -setup {
+    file delete -force dir2.link
+} -constraints {hasLinks} -body {
+    set dir [file join dir2 foo bar]
+    file mkdir $dir
+    file link dir2.link [file join dir2 foo bar]
+    testPathEqual [file normalize [file join dir2 foo x]] \
+	    [file normalize [file join dir2.link .. x]]
+} -result ok
+test filesystem-1.27 {file normalisation: up and down with ..} {
+    set dir [file join dir2 foo bar]
+    file mkdir $dir
+    set dir2 [file join dir2 .. dir2 foo .. foo bar]
+    list [testPathEqual [file normalize $dir] [file normalize $dir2]] \
+	[file exists $dir] [file exists $dir2]
+} {ok 1 1}
+test filesystem-1.28 {link normalisation: link with .. and ..} -setup {
+    file delete -force dir2.link
+} -constraints {hasLinks} -body {
+    set dir [file join dir2 foo bar]
+    file mkdir $dir
+    set to [file join dir2 .. dir2 foo .. foo bar]
+    file link dir2.link $to
+    testPathEqual [file normalize [file join dir2 foo x]] \
+	    [file normalize [file join dir2.link .. x]]
+} -result ok
+test filesystem-1.29 {link normalisation: link with ..} -setup {
+    file delete -force dir2.link
+} -constraints {hasLinks} -body {
+    set dir [file join dir2 foo bar]
+    file mkdir $dir
+    set to [file join dir2 .. dir2 foo .. foo bar]
+    file link dir2.link $to
+    set res [file normalize [file join dir2.link x yyy z]]
+    if {[string match *..* $res]} {
+	return "$res must not contain '..'"
+    }
+    return "ok"
+} -result {ok}
+test filesystem-1.29.1 {link normalisation with two consecutive links} {hasLinks} {
+    testPathEqual [file normalize [file join dir.link dirinside.link abc]] \
+	[file normalize [file join dir.dir dirinside.dir abc]]
+} ok
+file delete -force dir2.file
+file delete -force dir2.link
+file delete -force link.file dir.link
+file delete -force dir2
+file delete -force [file join dir.dir dirinside.link]
+removeFile [file join dir.dir inside.file]
+removeDirectory [file join dir.dir dirinside.dir]
+removeDirectory dir.dir
+test filesystem-1.30 {normalisation of nonexistent user} -body {
+    file normalize ~noonewiththisname
+} -returnCodes error -result {user "noonewiththisname" doesn't exist}
+test filesystem-1.31 {link normalisation: link near filesystem root} {testsetplatform} {
+    testsetplatform unix
+    file normalize /foo/../bar
+} {/bar}
+test filesystem-1.32 {link normalisation: link near filesystem root} {testsetplatform} {
+    testsetplatform unix
+    file normalize /../bar
+} {/bar}
+test filesystem-1.33 {link normalisation: link near filesystem root} {testsetplatform} {
+    testsetplatform windows
+    set res [file normalize C:/../bar]
+    if {[testConstraint unix]} {
+	# Some unices go further in normalizing this -- not really a problem
+	# since this is a Windows test.
+	regexp {C:/bar$} $res res
+    }
+    set res
+} {C:/bar}
+if {[testConstraint testsetplatform]} {
+    testsetplatform $platform
+}
+test filesystem-1.34 {file normalisation with '/./'} -body {
+    file normalize /foo/bar/anc/./.tml
+} -match regexp -result {^(?:(?!/\./).)*$}
+test filesystem-1.35a {file normalisation with '/./'} -body {
+    file normalize /ffo/bar/anc/./foo/.tml
+} -match regexp -result {^(?:(?!/\./).)*$}
+test filesystem-1.35b {file normalisation with '/./'} {
+    llength [regexp -all foo [file normalize /ffo/bar/anc/./foo/.tml]]
+} 1
+test filesystem-1.36a {file normalisation with '/./'} -body {
+    file normalize /foo/bar/anc/././asdasd/.tml
+} -match regexp -result {^(?:(?!/\./).)*$}
+test filesystem-1.36b {file normalisation with '/./'} {
+    llength [regexp -all asdasd [file normalize /foo/bar/anc/././asdasd/.tml]]
+} 1
+test filesystem-1.37 {file normalisation with '/./'} -body {
+    set fname "/abc/./def/./ghi/./asda/.././.././asd/x/../../../../....."
+    file norm $fname
+} -match regexp -result {^(?:[^/]|/(?:[^/]|$))+$}
+test filesystem-1.38 {file normalisation with volume relative} -setup {
+    set dir [pwd]
+} -constraints {win moreThanOneDrive} -body {
+    set path "[string range [lindex $drives 0] 0 1]foo"
+    cd [lindex $drives 1]
+    file norm $path
+} -cleanup {
+    cd $dir
+} -result "[lindex $drives 0]foo"
+test filesystem-1.39 {file normalisation with volume relative} -setup {
+    set old [pwd]
+} -constraints {win} -body {
+    set drv C:/
+    cd [lindex [glob -type d -dir $drv *] 0]
+    file norm [string range $drv 0 1]
+} -cleanup {
+    cd $old
+} -match regexp -result {.*[^/]}
+test filesystem-1.40 {file normalisation with repeated separators} {
+    testPathEqual [file norm foo////bar] [file norm foo/bar]
+} ok
+test filesystem-1.41 {file normalisation with repeated separators} {win} {
+    testPathEqual [file norm foo\\\\\\bar] [file norm foo/bar]
+} ok
+test filesystem-1.42 {file normalisation .. beyond root (Bug 1379287)} {
+    testPathEqual [file norm /xxx/..] [file norm /]
+} ok
+test filesystem-1.42.1 {file normalisation .. beyond root (Bug 1379287)} {
+    testPathEqual [file norm /xxx/../] [file norm /]
+} ok
+test filesystem-1.43 {file normalisation .. beyond root (Bug 1379287)} {
+    testPathEqual [file norm /xxx/foo/../..] [file norm /]
+} ok
+test filesystem-1.43.1 {file normalisation .. beyond root (Bug 1379287)} {
+    testPathEqual [file norm /xxx/foo/../../] [file norm /]
+} ok
+test filesystem-1.44 {file normalisation .. beyond root (Bug 1379287)} {
+    testPathEqual [file norm /xxx/foo/../../bar] [file norm /bar]
+} ok
+test filesystem-1.45 {file normalisation .. beyond root (Bug 1379287)} {
+    testPathEqual [file norm /xxx/../../bar] [file norm /bar]
+} ok
+test filesystem-1.46 {file normalisation .. beyond root (Bug 1379287)} {
+    testPathEqual [file norm /xxx/../bar] [file norm /bar]
+} ok
+test filesystem-1.47 {file normalisation .. beyond root (Bug 1379287)} {
+    testPathEqual [file norm /..] [file norm /]
+} ok
+test filesystem-1.48 {file normalisation .. beyond root (Bug 1379287)} {
+    testPathEqual [file norm /../] [file norm /]
+} ok
+test filesystem-1.49 {file normalisation .. beyond root (Bug 1379287)} {
+    testPathEqual [file norm /.] [file norm /]
+} ok
+test filesystem-1.50 {file normalisation .. beyond root (Bug 1379287)} {
+    testPathEqual [file norm /./] [file norm /]
+} ok
+test filesystem-1.51 {file normalisation .. beyond root (Bug 1379287)} {
+    testPathEqual [file norm /../..] [file norm /]
+} ok
+test filesystem-1.51.1 {file normalisation .. beyond root (Bug 1379287)} {
+    testPathEqual [file norm /../../] [file norm /]
+} ok
+
+test filesystem-2.0 {new native path} {unix} {
+   foreach f [lsort [glob -nocomplain /usr/bin/c*]] {
+       catch {file readlink $f}
+   }
+   # If we reach here we've succeeded. We used to crash above.
+   return ok
+} ok
+
+# Make sure the testfilesystem hasn't been registered.
+if {[testConstraint testfilesystem]} {
+  proc resetfs {} {
+    while {![catch {testfilesystem 0}]} {}
+  }
+}
+
+test filesystem-3.1 {Tcl_FSRegister & Tcl_FSUnregister} testfilesystem {
+    set result {}
+    lappend result [testfilesystem 1]
+    lappend result [testfilesystem 0]
+    lappend result [catch {testfilesystem 0} msg] $msg
+} {registered unregistered 1 failed}
+test filesystem-3.3 {Tcl_FSRegister} testfilesystem {
+    testfilesystem 1
+    testfilesystem 1
+    testfilesystem 0
+    testfilesystem 0
+} {unregistered}
+test filesystem-3.4 {Tcl_FSRegister} -constraints testfilesystem -body {
+    testfilesystem 1
+    file system bar
+} -cleanup {
+    testfilesystem 0
+} -result {reporting}
+test filesystem-3.5 {Tcl_FSUnregister} testfilesystem {
+    resetfs
+    lindex [file system bar] 0
+} {native}
+
+test filesystem-4.0 {testfilesystem} -constraints testfilesystem -body {
+    testfilesystem 1
+    set filesystemReport {}
+    file exists foo
+    testfilesystem 0
+    return $filesystemReport
+} -match glob -result {*{access foo}}
+test filesystem-4.1 {testfilesystem} -constraints testfilesystem -body {
+    testfilesystem 1
+    set filesystemReport {}
+    catch {file stat foo bar}
+    testfilesystem 0
+    return $filesystemReport
+} -match glob -result {*{stat foo}}
+test filesystem-4.2 {testfilesystem} -constraints testfilesystem -body {
+    testfilesystem 1
+    set filesystemReport {}
+    catch {file lstat foo bar}
+    testfilesystem 0
+    return $filesystemReport
+} -match glob -result {*{lstat foo}}
+test filesystem-4.3 {testfilesystem} -constraints testfilesystem -body {
+    testfilesystem 1
+    set filesystemReport {}
+    catch {glob *}
+    testfilesystem 0
+    return $filesystemReport
+} -match glob -result {*{matchindirectory *}*}
+
+test filesystem-5.1 {cache and ~} -constraints testfilesystem -setup {
+    set orig $::env(HOME)
+} -body {
+    set ::env(HOME) /foo/bar/blah
+    set testdir ~
+    set res1 "Parent of ~ (/foo/bar/blah) is [file dirname $testdir]"
+    set ::env(HOME) /a/b/c
+    set res2 "Parent of ~ (/a/b/c) is [file dirname $testdir]"
+    list $res1 $res2
+} -cleanup {
+    set ::env(HOME) $orig
+} -match regexp -result {{Parent of ~ \(/foo/bar/blah\) is ([a-zA-Z]:)?(/cygwin)?(/foo/bar|foo:bar)} {Parent of ~ \(/a/b/c\) is ([a-zA-Z]:)?(/cygwin)?(/a/b|a:b)}}
+
+test filesystem-6.1 {empty file name} -returnCodes error -body {
+    open ""
+} -result {couldn't open "": no such file or directory}
+test filesystem-6.2 {empty file name} -returnCodes error -body {
+    file stat "" arr
+} -result {could not read "": no such file or directory}
+test filesystem-6.3 {empty file name} -returnCodes error -body {
+    file atime ""
+} -result {could not read "": no such file or directory}
+test filesystem-6.4 {empty file name} -returnCodes error -body {
+    file attributes ""
+} -result {could not read "": no such file or directory}
+test filesystem-6.5 {empty file name} -returnCodes error -body {
+    file copy "" ""
+} -result {error copying "": no such file or directory}
+test filesystem-6.6 {empty file name} {file delete ""} {}
+test filesystem-6.7 {empty file name} {file dirname ""} .
+test filesystem-6.8 {empty file name} {file executable ""} 0
+test filesystem-6.9 {empty file name} {file exists ""} 0
+test filesystem-6.10 {empty file name} {file extension ""} {}
+test filesystem-6.11 {empty file name} {file isdirectory ""} 0
+test filesystem-6.12 {empty file name} {file isfile ""} 0
+test filesystem-6.13 {empty file name} {file join ""} {}
+test filesystem-6.14 {empty file name} -returnCodes error -body {
+    file link ""
+} -result {could not read link "": no such file or directory}
+test filesystem-6.15 {empty file name} -returnCodes error -body {
+    file lstat "" arr
+} -result {could not read "": no such file or directory}
+test filesystem-6.16 {empty file name} -returnCodes error -body {
+    file mtime ""
+} -result {could not read "": no such file or directory}
+test filesystem-6.17 {empty file name} -returnCodes error -body {
+    file mtime "" 0
+} -result {could not read "": no such file or directory}
+test filesystem-6.18 {empty file name} -returnCodes error -body {
+    file mkdir ""
+} -result {can't create directory "": no such file or directory}
+test filesystem-6.19 {empty file name} {file nativename ""} {}
+test filesystem-6.20 {empty file name} {file normalize ""} {}
+test filesystem-6.21 {empty file name} {file owned ""} 0
+test filesystem-6.22 {empty file name} {file pathtype ""} relative
+test filesystem-6.23 {empty file name} {file readable ""} 0
+test filesystem-6.24 {empty file name} -returnCodes error -body {
+    file readlink ""
+} -result {could not read link "": no such file or directory}
+test filesystem-6.25 {empty file name} -returnCodes error -body {
+    file rename "" ""
+} -result {error renaming "": no such file or directory}
+test filesystem-6.26 {empty file name} {file rootname ""} {}
+test filesystem-6.27 {empty file name} -returnCodes error -body {
+    file separator ""
+} -result {unrecognised path}
+test filesystem-6.28 {empty file name} -returnCodes error -body {
+    file size ""
+} -result {could not read "": no such file or directory}
+test filesystem-6.29 {empty file name} {file split ""} {}
+test filesystem-6.30 {empty file name} -returnCodes error -body {
+    file system ""
+} -result {unrecognised path}
+test filesystem-6.31 {empty file name} {file tail ""} {}
+test filesystem-6.32 {empty file name} -returnCodes error -body {
+    file type ""
+} -result {could not read "": no such file or directory}
+test filesystem-6.33 {empty file name} {file writable ""} 0
+test filesystem-6.34 {file name with (invalid) nul character} {
+    list [catch "open foo\x00" msg] $msg
+} [list 1 "couldn't open \"foo\x00\": filename is invalid on this platform"]
+
+# Make sure the testfilesystem hasn't been registered.
+if {[testConstraint testfilesystem]} {
+    while {![catch {testfilesystem 0}]} {}
+}
+
+test filesystem-7.1.1 {load from vfs} -setup {
+    set dir [pwd]
+} -constraints {win testsimplefilesystem loaddll} -body {
+    # This may cause a crash on exit
+    cd [file dirname $::ddelib]
+    testsimplefilesystem 1
+    # This loads dde via a complex copy-to-temp operation
+    load simplefs:/[file tail $::ddelib] dde
+    testsimplefilesystem 0
+    return ok
+    # The real result of this test is what happens when Tcl exits.
+} -cleanup {
+    cd $dir
+} -result ok
+test filesystem-7.1.2 {load from vfs, and then unload again} -setup {
+    set dir [pwd]
+} -constraints {win testsimplefilesystem loaddll} -body {
+    # This may cause a crash on exit
+    cd [file dirname $::reglib]
+    testsimplefilesystem 1
+    # This loads reg via a complex copy-to-temp operation
+    load simplefs:/[file tail $::reglib] Registry
+    unload simplefs:/[file tail $::reglib]
+    testsimplefilesystem 0
+    return ok
+    # The real result of this test is what happens when Tcl exits.
+} -cleanup {
+    cd $dir
+} -result ok
+test filesystem-7.2 {cross-filesystem copy from vfs maintains mtime} -setup {
+    set dir [pwd]
+    cd [tcltest::temporaryDirectory]
+} -constraints testsimplefilesystem -body {
+    # We created this file several tests ago.
+    set origtime [file mtime gorp.file]
+    set res [file exists gorp.file]
+    testsimplefilesystem 1
+    file delete -force theCopy
+    file copy simplefs:/gorp.file theCopy
+    testsimplefilesystem 0
+    set newtime [file mtime theCopy]
+    lappend res [expr {$origtime == $newtime ? 1 : "$origtime != $newtime"}]
+} -cleanup {
+    catch {file delete theCopy}
+    cd $dir
+} -result {1 1}
+test filesystem-7.3 {glob in simplefs} -setup {
+    set dir [pwd]
+    cd [tcltest::temporaryDirectory]
+} -constraints testsimplefilesystem -body {
+    file mkdir simpledir
+    close [open [file join simpledir simplefile] w]
+    testsimplefilesystem 1
+    glob -nocomplain -dir simplefs:/simpledir *
+} -cleanup {
+    catch {testsimplefilesystem 0}
+    file delete -force simpledir
+    cd $dir
+} -result {simplefs:/simpledir/simplefile}
+test filesystem-7.3.1 {glob in simplefs: no path/dir} -setup {
+    set dir [pwd]
+    cd [tcltest::temporaryDirectory]
+} -constraints testsimplefilesystem -body {
+    file mkdir simpledir
+    close [open [file join simpledir simplefile] w]
+    testsimplefilesystem 1
+    set res [glob -nocomplain simplefs:/simpledir/*]
+    lappend res {*}[glob -nocomplain simplefs:/simpledir]
+} -cleanup {
+    catch {testsimplefilesystem 0}
+    file delete -force simpledir
+    cd $dir
+} -result {simplefs:/simpledir/simplefile simplefs:/simpledir}
+test filesystem-7.3.2 {glob in simplefs: no path/dir, no subdirectory} -setup {
+    set dir [pwd]
+    cd [tcltest::temporaryDirectory]
+} -constraints testsimplefilesystem -body {
+    file mkdir simpledir
+    close [open [file join simpledir simplefile] w]
+    testsimplefilesystem 1
+    glob -nocomplain simplefs:/s*
+} -cleanup {
+    catch {testsimplefilesystem 0}
+    file delete -force simpledir
+    cd $dir
+} -match glob -result ?*
+test filesystem-7.3.3 {glob in simplefs: pattern is a volume} -setup {
+    set dir [pwd]
+    cd [tcltest::temporaryDirectory]
+} -constraints testsimplefilesystem -body {
+    file mkdir simpledir
+    close [open [file join simpledir simplefile] w]
+    testsimplefilesystem 1
+    glob -nocomplain simplefs:/*
+} -cleanup {
+    testsimplefilesystem 0
+    file delete -force simpledir
+    cd $dir
+} -match glob -result ?*
+test filesystem-7.4 {cross-filesystem file copy with -force} -setup {
+    set dir [pwd]
+    cd [tcltest::temporaryDirectory]
+    set fout [open [file join simplefile] w]
+    puts -nonewline $fout "1234567890"
+    close $fout
+    testsimplefilesystem 1
+} -constraints testsimplefilesystem -body {
+    # First copy should succeed
+    set res [catch {file copy simplefs:/simplefile file2} err]
+    lappend res $err
+    # Second copy should fail (no -force)
+    lappend res [catch {file copy simplefs:/simplefile file2} err]
+    lappend res $err
+    # Third copy should succeed (-force)
+    lappend res [catch {file copy -force simplefs:/simplefile file2} err]
+    lappend res $err
+    lappend res [file exists file2]
+} -cleanup {
+    catch {testsimplefilesystem 0}
+    file delete -force simplefile
+    file delete -force file2
+    cd $dir
+} -result {0 {} 1 {error copying "simplefs:/simplefile" to "file2": file already exists} 0 {} 1}
+test filesystem-7.5 {cross-filesystem file copy with -force} -setup {
+    set dir [pwd]
+    cd [tcltest::temporaryDirectory]
+    set fout [open [file join simplefile] w]
+    puts -nonewline $fout "1234567890"
+    close $fout
+    testsimplefilesystem 1
+} -constraints {testsimplefilesystem unix} -body {
+    # First copy should succeed
+    set res [catch {file copy simplefs:/simplefile file2} err]
+    lappend res $err
+    file attributes file2 -permissions 0000
+    # Second copy should fail (no -force)
+    lappend res [catch {file copy simplefs:/simplefile file2} err]
+    lappend res $err
+    # Third copy should succeed (-force)
+    lappend res [catch {file copy -force simplefs:/simplefile file2} err]
+    lappend res $err
+    lappend res [file exists file2]
+} -cleanup {
+    testsimplefilesystem 0
+    file delete -force simplefile
+    file delete -force file2
+    cd $dir
+} -result {0 {} 1 {error copying "simplefs:/simplefile" to "file2": file already exists} 0 {} 1}
+test filesystem-7.6 {cross-filesystem dir copy with -force} -setup {
+    set dir [pwd]
+    cd [tcltest::temporaryDirectory]
+    file delete -force simpledir
+    file mkdir simpledir
+    file mkdir dir2
+    set fout [open [file join simpledir simplefile] w]
+    puts -nonewline $fout "1234567890"
+    close $fout
+    testsimplefilesystem 1
+} -constraints testsimplefilesystem -body {
+    # First copy should succeed
+    set res [catch {file copy simplefs:/simpledir dir2} err]
+    lappend res $err
+    # Second copy should fail (no -force)
+    lappend res [catch {file copy simplefs:/simpledir dir2} err]
+    lappend res $err
+    # Third copy should succeed (-force)
+    lappend res [catch {file copy -force simplefs:/simpledir dir2} err]
+    lappend res $err
+    lappend res [file exists [file join dir2 simpledir]] \
+	    [file exists [file join dir2 simpledir simplefile]]
+} -cleanup {
+    testsimplefilesystem 0
+    file delete -force simpledir
+    file delete -force dir2
+    cd $dir
+} -result {0 {} 1 {error copying "simplefs:/simpledir" to "dir2/simpledir": file already exists} 0 {} 1 1}
+test filesystem-7.7 {cross-filesystem dir copy with -force} -setup {
+    set dir [pwd]
+    cd [tcltest::temporaryDirectory]
+    file delete -force simpledir
+    file mkdir simpledir
+    file mkdir dir2
+    set fout [open [file join simpledir simplefile] w]
+    puts -nonewline $fout "1234567890"
+    close $fout
+    testsimplefilesystem 1
+} -constraints {testsimplefilesystem unix} -body {
+    # First copy should succeed
+    set res [catch {file copy simplefs:/simpledir dir2} err]
+    lappend res $err
+    # Second copy should fail (no -force)
+    lappend res [catch {file copy simplefs:/simpledir dir2} err]
+    lappend res $err
+    # Third copy should succeed (-force)
+    # I've noticed on some Unices that this only succeeds intermittently (some
+    # runs work, some fail). This needs examining further.
+    lappend res [catch {file copy -force simplefs:/simpledir dir2} err]
+    lappend res $err
+    lappend res [file exists [file join dir2 simpledir]] \
+	    [file exists [file join dir2 simpledir simplefile]]
+} -cleanup {
+    testsimplefilesystem 0
+    file delete -force simpledir
+    file delete -force dir2
+    cd $dir
+} -result {0 {} 1 {error copying "simplefs:/simpledir" to "dir2/simpledir": file already exists} 0 {} 1 1}
+removeFile gorp.file
+test filesystem-7.8 {vfs cd} -setup {
+    set dir [pwd]
+    cd [tcltest::temporaryDirectory]
+    file delete -force simpledir
+    file mkdir simpledir
+    testsimplefilesystem 1
+} -constraints testsimplefilesystem -body {
+    # This can variously cause an infinite loop or simply have no effect at
+    # all (before certain bugs were fixed, of course).
+    cd simplefs:/simpledir
+    pwd
+} -cleanup {
+    cd [tcltest::temporaryDirectory]
+    testsimplefilesystem 0
+    file delete -force simpledir
+    cd $dir
+} -result {simplefs:/simpledir}
+
+test filesystem-8.1 {relative path objects and caching of pwd} -setup {
+    set dir [pwd]
+    cd [tcltest::temporaryDirectory]
+} -body {
+    makeDirectory abc
+    makeDirectory def
+    makeFile "contents" [file join abc foo]
+    cd abc
+    set f "foo"
+    set res {}
+    lappend res [file exists $f]
+    lappend res [file exists $f]
+    cd ..
+    cd def
+    # If we haven't cleared the object's cwd cache, Tcl will think it still
+    # exists.
+    lappend res [file exists $f]
+    lappend res [file exists $f]
+} -cleanup {
+    removeFile [file join abc foo]
+    removeDirectory abc
+    removeDirectory def
+    cd $dir
+} -result {1 1 0 0}
+test filesystem-8.2 {relative path objects and use of pwd} -setup {
+    set origdir [pwd]
+    cd [tcltest::temporaryDirectory]
+} -body {
+    set dir "abc"
+    makeDirectory $dir
+    makeFile "contents" [file join abc foo]
+    cd $dir
+    file exists [lindex [glob *] 0]
+} -cleanup {
+    cd [tcltest::temporaryDirectory]
+    removeFile [file join abc foo]
+    removeDirectory abc
+    cd $origdir
+} -result 1
+test filesystem-8.3 {path objects and empty string} {
+    set anchor ""
+    set dst foo
+    set res $dst
+    set yyy [file split $anchor]
+    set dst [file join  $anchor $dst]
+    lappend res $dst $yyy
+} {foo foo {}}
+
+proc TestFind1 {d f} {
+    set r1 [file exists [file join $d $f]]
+    lappend res "[file join $d $f] found: $r1"
+    lappend res "is dir a dir? [file isdirectory $d]"
+    set r2 [file exists [file join $d $f]]
+    lappend res "[file join $d $f] found: $r2"
+    return $res
+}
+proc TestFind2 {d f} {
+    set r1 [file exists [file join $d $f]]
+    lappend res "[file join $d $f] found: $r1"
+    lappend res "is dir a dir? [file isdirectory [file join $d]]"
+    set r2 [file exists [file join $d $f]]
+    lappend res "[file join $d $f] found: $r2"
+    return $res
+}
+
+test filesystem-9.1 {path objects and join and object rep} -setup {
+    set origdir [pwd]
+    cd [tcltest::temporaryDirectory]
+} -body {
+    file mkdir [file join a b c]
+    TestFind1 a [file join b . c]
+} -cleanup {
+    file delete -force a
+    cd $origdir
+} -result {{a/b/./c found: 1} {is dir a dir? 1} {a/b/./c found: 1}}
+test filesystem-9.2 {path objects and join and object rep} -setup {
+    set origdir [pwd]
+    cd [tcltest::temporaryDirectory]
+} -body {
+    file mkdir [file join a b c]
+    TestFind2 a [file join b . c]
+} -cleanup {
+    file delete -force a
+    cd $origdir
+} -result {{a/b/./c found: 1} {is dir a dir? 1} {a/b/./c found: 1}}
+test filesystem-9.2.1 {path objects and join and object rep} -setup {
+    set origdir [pwd]
+    cd [tcltest::temporaryDirectory]
+} -body {
+    file mkdir [file join a b c]
+    TestFind2 a [file join b .]
+} -cleanup {
+    file delete -force a
+    cd $origdir
+} -result {{a/b/. found: 1} {is dir a dir? 1} {a/b/. found: 1}}
+test filesystem-9.3 {path objects and join and object rep} -setup {
+    set origdir [pwd]
+    cd [tcltest::temporaryDirectory]
+} -body {
+    file mkdir [file join a b c]
+    TestFind1 a [file join b .. b c]
+} -cleanup {
+    file delete -force a
+    cd $origdir
+} -result {{a/b/../b/c found: 1} {is dir a dir? 1} {a/b/../b/c found: 1}}
+test filesystem-9.4 {path objects and join and object rep} -setup {
+    set origdir [pwd]
+    cd [tcltest::temporaryDirectory]
+} -body {
+    file mkdir [file join a b c]
+    TestFind2 a [file join b .. b c]
+} -cleanup {
+    file delete -force a
+    cd $origdir
+} -result {{a/b/../b/c found: 1} {is dir a dir? 1} {a/b/../b/c found: 1}}
+test filesystem-9.5 {path objects and file tail and object rep} -setup {
+    set origdir [pwd]
+    cd [tcltest::temporaryDirectory]
+} -body {
+    file mkdir dgp
+    close [open dgp/test w]
+    foreach relative [glob -nocomplain [file join * test]] {
+	set absolute [file join [pwd] $relative]
+	set res [list [file tail $absolute] "test"]
+    }
+    return $res
+} -cleanup {
+    file delete -force dgp 
+    cd $origdir
+} -result {test test}
+test filesystem-9.6 {path objects and file tail and object rep} win {
+    set res {}
+    set p "C:\\toto"
+    lappend res [file join $p toto]
+    file isdirectory $p
+    lappend res [file join $p toto]
+} {C:/toto/toto C:/toto/toto}
+test filesystem-9.7 {path objects and glob and file tail and tilde} -setup {
+    set res {}
+    set origdir [pwd]
+    cd [tcltest::temporaryDirectory]
+} -body {
+    file mkdir tilde
+    close [open tilde/~testNotExist w]
+    cd tilde
+    set file [lindex [glob *test*] 0]
+    lappend res [file exists $file] [catch {file tail $file} r] $r
+    lappend res $file
+    lappend res [file exists $file] [catch {file tail $file} r] $r
+    lappend res [catch {file tail $file} r] $r
+} -cleanup {
+    cd [tcltest::temporaryDirectory]
+    file delete -force tilde
+    cd $origdir
+} -result {0 1 {user "testNotExist" doesn't exist} ~testNotExist 0 1 {user "testNotExist" doesn't exist} 1 {user "testNotExist" doesn't exist}}
+test filesystem-9.8 {path objects and glob and file tail and tilde} -setup {
+    set res {}
+    set origdir [pwd]
+    cd [tcltest::temporaryDirectory]
+} -body {
+    file mkdir tilde
+    close [open tilde/~testNotExist w]
+    cd tilde
+    set file1 [lindex [glob *test*] 0]
+    set file2 "~testNotExist"
+    lappend res $file1 $file2
+    lappend res [catch {file tail $file1} r] $r
+    lappend res [catch {file tail $file2} r] $r
+} -cleanup {
+    cd [tcltest::temporaryDirectory]
+    file delete -force tilde
+    cd $origdir
+} -result {~testNotExist ~testNotExist 1 {user "testNotExist" doesn't exist} 1 {user "testNotExist" doesn't exist}}
+test filesystem-9.9 {path objects and glob and file tail and tilde} -setup {
+    set res {}
+    set origdir [pwd]
+    cd [tcltest::temporaryDirectory]
+} -body {
+    file mkdir tilde
+    close [open tilde/~testNotExist w]
+    cd tilde
+    set file1 [lindex [glob *test*] 0]
+    set file2 "~testNotExist"
+    lappend res [catch {file exists $file1} r] $r
+    lappend res [catch {file exists $file2} r] $r
+    lappend res [string equal $file1 $file2]
+} -cleanup {
+    cd [tcltest::temporaryDirectory]
+    file delete -force tilde
+    cd $origdir
+} -result {0 0 0 0 1}
+
+# ----------------------------------------------------------------------
+
+test filesystem-10.1 {Bug 3414754} {
+    string match */ [file join [pwd] foo/]
+} 0
+
+cleanupTests
+unset -nocomplain drive drives
+}
+namespace delete ::tcl::test::fileSystem
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/tests/for-old.test b/tests/for-old.test
new file mode 100644
index 0000000..a11a791
--- /dev/null
+++ b/tests/for-old.test
@@ -0,0 +1,71 @@
+# Commands covered:  for, continue, break
+#
+# This file contains the original set of tests for Tcl's for command.
+# Since the for command is now compiled, a new set of tests covering
+# the new implementation is in the file "for.test". Sourcing this file
+# into Tcl runs the tests and generates output for errors.
+# No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994-1996 Sun Microsystems, Inc.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+    package require tcltest
+    namespace import -force ::tcltest::*
+}
+
+# Check "for" and its use of continue and break.
+
+catch {unset a i}
+test for-old-1.1 {for tests} {
+    set a {}
+    for {set i 1} {$i<6} {set i [expr $i+1]} {
+	set a [concat $a $i]
+    }
+    set a
+} {1 2 3 4 5}
+test for-old-1.2 {for tests} {
+    set a {}
+    for {set i 1} {$i<6} {set i [expr $i+1]} {
+	if $i==4 continue
+	set a [concat $a $i]
+    }
+    set a
+} {1 2 3 5}
+test for-old-1.3 {for tests} {
+    set a {}
+    for {set i 1} {$i<6} {set i [expr $i+1]} {
+	if $i==4 break
+	set a [concat $a $i]
+    }
+    set a
+} {1 2 3}
+test for-old-1.4 {for tests} {catch {for 1 2 3} msg} 1
+test for-old-1.5 {for tests} {
+    catch {for 1 2 3} msg
+    set msg
+} {wrong # args: should be "for start test next command"}
+test for-old-1.6 {for tests} {catch {for 1 2 3 4 5} msg} 1
+test for-old-1.7 {for tests} {
+    catch {for 1 2 3 4 5} msg
+    set msg
+} {wrong # args: should be "for start test next command"}
+test for-old-1.8 {for tests} {
+    set a {xyz}
+    for {set i 1} {$i<6} {set i [expr $i+1]} {}
+    set a
+} xyz
+test for-old-1.9 {for tests} {
+    set a {}
+    for {set i 1} {$i<6} {set i [expr $i+1]; if $i==4 break} {
+	set a [concat $a $i]
+    }
+    set a
+} {1 2 3}
+
+# cleanup
+::tcltest::cleanupTests
+return
diff --git a/tests/for.test b/tests/for.test
new file mode 100644
index 0000000..1a65274
--- /dev/null
+++ b/tests/for.test
@@ -0,0 +1,1360 @@
+# Commands covered:  for, continue, break
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands.  Sourcing this file into Tcl runs the tests and
+# generates output for errors.  No output means no errors were found.
+#
+# Copyright (c) 1996 Sun Microsystems, Inc.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+    package require tcltest 2
+    namespace import -force ::tcltest::*
+}
+
+# Used for constraining memory leak tests
+testConstraint memory [llength [info commands memory]]
+if {[testConstraint memory]} {
+    proc meminfo {} {lindex [split [memory info] "\n"] 3 3}
+}
+
+# Basic "for" operation.
+
+test for-1.1 {TclCompileForCmd: missing initial command} {
+    list [catch {for} msg] $msg
+} {1 {wrong # args: should be "for start test next command"}}
+test for-1.2 {TclCompileForCmd: error in initial command} -body {
+    list [catch {for {set}} msg] $msg $::errorInfo
+} -match glob -result {1 {wrong # args: should be "for start test next command"} {wrong # args: should be "for start test next command"
+    while *ing
+"for {set}"}}
+catch {unset i}
+test for-1.3 {TclCompileForCmd: missing test expression} {
+    catch {for {set i 0}} msg
+    set msg
+} {wrong # args: should be "for start test next command"}
+test for-1.4 {TclCompileForCmd: error in test expression} -body {
+    catch {for {set i 0} {$i<}} msg
+    set ::errorInfo
+} -match glob -result {wrong # args: should be "for start test next command"
+    while *ing
+"for {set i 0} {$i<}"}
+test for-1.5 {TclCompileForCmd: test expression is enclosed in quotes} {
+    set i 0
+    for {} "$i > 5" {incr i} {}
+} {}
+test for-1.6 {TclCompileForCmd: missing "next" command} {
+    catch {for {set i 0} {$i < 5}} msg
+    set msg
+} {wrong # args: should be "for start test next command"}
+test for-1.7 {TclCompileForCmd: missing command body} {
+    catch {for {set i 0} {$i < 5} {incr i}} msg
+    set msg
+} {wrong # args: should be "for start test next command"}
+test for-1.8 {TclCompileForCmd: error compiling command body} -body {
+    catch {for {set i 0} {$i < 5} {incr i} {set}} msg
+    set ::errorInfo
+} -match glob -result {wrong # args: should be "set varName ?newValue?"
+    while *ing
+"set"*}
+catch {unset a}
+test for-1.9 {TclCompileForCmd: simple command body} {
+    set a {}
+    for {set i 1} {$i<6} {set i [expr $i+1]} {
+	if $i==4 break
+	set a [concat $a $i]
+    }
+    set a
+} {1 2 3}
+test for-1.10 {TclCompileForCmd: command body in quotes} {
+    set a {}
+    for {set i 1} {$i<6} {set i [expr $i+1]} "append a x"
+    set a
+} {xxxxx}
+test for-1.11 {TclCompileForCmd: computed command body} {
+    catch {unset x1}
+    catch {unset bb}
+    catch {unset x2}
+    set x1 {append a x1; }
+    set bb {break}
+    set x2 {; append a x2}
+    set a {}
+    for {set i 1} {$i<6} {set i [expr $i+1]} $x1$bb$x2
+    set a
+} {x1}
+test for-1.12 {TclCompileForCmd: error in "next" command} -body {
+    catch {for {set i 0} {$i < 5} {set} {format $i}} msg
+    set ::errorInfo
+} -match glob -result {wrong # args: should be "set varName ?newValue?"
+    while *ing
+"set"*}
+test for-1.13 {TclCompileForCmd: long command body} {
+    set a {}
+    for {set i 1} {$i<6} {set i [expr $i+1]} {
+	if $i==4 break
+	if $i>5 continue
+	if {$i>6 && $tcl_platform(machine)=="xxx"} {
+	    catch {set a $a} msg
+	    catch {incr i 5} msg
+	    catch {incr i -5} msg
+	}
+	if {$i>6 && $tcl_platform(machine)=="xxx"} {
+	    catch {set a $a} msg
+	    catch {incr i 5} msg
+	    catch {incr i -5} msg
+	}
+	if {$i>6 && $tcl_platform(machine)=="xxx"} {
+	    catch {set a $a} msg
+	    catch {incr i 5} msg
+	    catch {incr i -5} msg
+	}
+	if {$i>6 && $tcl_platform(machine)=="xxx"} {
+	    catch {set a $a} msg
+	    catch {incr i 5} msg
+	    catch {incr i -5} msg
+	}
+	if {$i>6 && $tcl_platform(machine)=="xxx"} {
+	    catch {set a $a} msg
+	    catch {incr i 5} msg
+	    catch {incr i -5} msg
+	}
+	set a [concat $a $i]
+    }
+    set a
+} {1 2 3}
+test for-1.14 {TclCompileForCmd: for command result} {
+    set a [for {set i 0} {$i < 5} {incr i} {}]
+    set a
+} {}
+test for-1.15 {TclCompileForCmd: for command result} {
+    set a [for {set i 0} {$i < 5} {incr i} {if $i==3 break}]
+    set a
+} {}
+
+# Check "for" and "continue".
+
+test for-2.1 {TclCompileContinueCmd: arguments after "continue"} {
+    catch {continue foo} msg
+    set msg
+} {wrong # args: should be "continue"}
+test for-2.2 {TclCompileContinueCmd: continue result} {
+    catch continue
+} 4
+test for-2.3 {continue tests} {
+    set a {}
+    for {set i 1} {$i <= 4} {set i [expr $i+1]} {
+	if {$i == 2} continue
+	set a [concat $a $i]
+    }
+    set a
+} {1 3 4}
+test for-2.4 {continue tests} {
+    set a {}
+    for {set i 1} {$i <= 4} {set i [expr $i+1]} {
+	if {$i != 2} continue
+	set a [concat $a $i]
+    }
+    set a
+} {2}
+test for-2.5 {continue tests, nested loops} {
+    set msg {}
+    for {set i 1} {$i <= 4} {incr i} {
+	for {set a 1} {$a <= 2} {incr a} {
+            if {$i>=2 && $a>=2} continue
+            set msg [concat $msg "$i.$a"]
+        }
+    }
+    set msg
+} {1.1 1.2 2.1 3.1 4.1}
+test for-2.6 {continue tests, long command body} {
+    set a {}
+    for {set i 1} {$i<6} {set i [expr $i+1]} {
+	if $i==2 continue
+	if $i==4 break
+	if $i>5 continue
+	if {$i>6 && $tcl_platform(machine)=="xxx"} {
+	    catch {set a $a} msg
+	    catch {incr i 5} msg
+	    catch {incr i -5} msg
+	}
+	if {$i>6 && $tcl_platform(machine)=="xxx"} {
+	    catch {set a $a} msg
+	    catch {incr i 5} msg
+	    catch {incr i -5} msg
+	}
+	if {$i>6 && $tcl_platform(machine)=="xxx"} {
+	    catch {set a $a} msg
+	    catch {incr i 5} msg
+	    catch {incr i -5} msg
+	}
+	if {$i>6 && $tcl_platform(machine)=="xxx"} {
+	    catch {set a $a} msg
+	    catch {incr i 5} msg
+	    catch {incr i -5} msg
+	}
+	if {$i>6 && $tcl_platform(machine)=="xxx"} {
+	    catch {set a $a} msg
+	    catch {incr i 5} msg
+	    catch {incr i -5} msg
+	}
+	set a [concat $a $i]
+    }
+    set a
+} {1 3}
+test for-2.7 {continue tests, uncompiled [for]} -body {
+    set file [makeFile {
+    	set guard 0
+	for {set i 20} {$i > 0} {incr i -1} {
+	    if {[incr guard]>30} {return BAD}
+	    continue
+	}
+	return GOOD
+    } source.file]
+    source $file
+} -cleanup {
+    removeFile source.file
+} -result GOOD
+
+# Check "for" and "break".
+
+test for-3.1 {TclCompileBreakCmd: arguments after "break"} {
+    catch {break foo} msg
+    set msg
+} {wrong # args: should be "break"}
+test for-3.2 {TclCompileBreakCmd: break result} {
+    catch break
+} 3
+test for-3.3 {break tests} {
+    set a {}
+    for {set i 1} {$i <= 4} {incr i} {
+	if {$i == 3} break
+	set a [concat $a $i]
+    }
+    set a
+} {1 2}
+test for-3.4 {break tests, nested loops} {
+    set msg {}
+    for {set i 1} {$i <= 4} {incr i} {
+	for {set a 1} {$a <= 2} {incr a} {
+            if {$i>=2 && $a>=2} break
+            set msg [concat $msg "$i.$a"]
+        }
+    }
+    set msg
+} {1.1 1.2 2.1 3.1 4.1}
+test for-3.5 {break tests, long command body} {
+    set a {}
+    for {set i 1} {$i<6} {set i [expr $i+1]} {
+	if $i==2 continue
+	if $i==5 break
+	if $i>5 continue
+	if {$i>6 && $tcl_platform(machine)=="xxx"} {
+	    catch {set a $a} msg
+	    catch {incr i 5} msg
+	    catch {incr i -5} msg
+	}
+	if {$i>6 && $tcl_platform(machine)=="xxx"} {
+	    catch {set a $a} msg
+	    catch {incr i 5} msg
+	    catch {incr i -5} msg
+	}
+	if {$i>6 && $tcl_platform(machine)=="xxx"} {
+	    catch {set a $a} msg
+	    catch {incr i 5} msg
+	    catch {incr i -5} msg
+	}
+	if $i==4 break
+	if {$i>6 && $tcl_platform(machine)=="xxx"} {
+	    catch {set a $a} msg
+	    catch {incr i 5} msg
+	    catch {incr i -5} msg
+	}
+	if {$i>6 && $tcl_platform(machine)=="xxx"} {
+	    catch {set a $a} msg
+	    catch {incr i 5} msg
+	    catch {incr i -5} msg
+	}
+	set a [concat $a $i]
+    }
+    set a
+} {1 3}
+# A simplified version of exmh's mail formatting routine to stress "for",
+# "break", "while", and "if".
+proc formatMail {} {
+    array set lines {
+        0 {Return-path: george@tcl} \
+        1 {Return-path: <george@tcl>} \
+        2 {Received: from tcl by tcl.Somewhere.COM (SMI-8.6/SMI-SVR4)} \
+        3 {	id LAA10027; Wed, 11 Sep 1996 11:14:53 -0700} \
+        4 {Message-id: <199609111814.LAA10027@tcl.Somewhere.COM>} \
+        5 {X-mailer: exmh version 1.6.9 8/22/96} \
+        6 {Mime-version: 1.0} \
+        7 {Content-type: text/plain; charset=iso-8859-1} \
+        8 {Content-transfer-encoding: quoted-printable} \
+        9 {Content-length: 2162} \
+        10 {To: fred} \
+        11 {Subject: tcl7.6} \
+        12 {Date: Wed, 11 Sep 1996 11:14:53 -0700} \
+        13 {From: George <george@tcl>} \
+        14 {The Tcl 7.6 and Tk 4.2 releases} \
+        15 {} \
+        16 {This page contains information about Tcl 7.6 and Tk4.2, which are the most recent} \
+        17 {releases of the Tcl scripting language and the Tk toolkit. The first beta versions of these} \
+        18 {releases were released on August 30, 1996. These releases contain only minor changes,} \
+        19 {so we hope to have only a single beta release and to go final in early October, 1996. } \
+        20 {} \
+        21 {} \
+        22 {What's new } \
+        23 {} \
+        24 {The most important changes in the releases are summarized below. See the README} \
+        25 {and changes files in the distributions for more complete information on what has} \
+        26 {changed, including both feature changes and bug fixes. } \
+        27 {} \
+        28 {     There are new options to the file command for copying files (file copy),} \
+        29 {     deleting files and directories (file delete), creating directories (file} \
+        30 {     mkdir), and renaming files (file rename). } \
+        31 {     The implementation of exec has been improved greatly for Windows 95 and} \
+        32 {     Windows NT. } \
+        33 {     There is a new memory allocator for the Macintosh version, which should be} \
+        34 {     more efficient than the old one. } \
+        35 {     Tk's grid geometry manager has been completely rewritten. The layout} \
+        36 {     algorithm produces much better layouts than before, especially where rows or} \
+        37 {     columns were stretchable. } \
+        38 {     There are new commands for creating common dialog boxes:} \
+        39 {     tk_chooseColor, tk_getOpenFile, tk_getSaveFile and} \
+        40 {     tk_messageBox. These use native dialog boxes if they are available. } \
+        41 {     There is a new virtual event mechanism for handling events in a more portable} \
+        42 {     way. See the new command event. It also allows events (both physical and} \
+        43 {     virtual) to be generated dynamically. } \
+        44 {} \
+        45 {Tcl 7.6 and Tk 4.2 are backwards-compatible with Tcl 7.5 and Tk 4.1 except for} \
+        46 {changes in the C APIs for custom channel drivers. Scripts written for earlier releases} \
+        47 {should work on these new releases as well. } \
+        48 {} \
+        49 {Obtaining The Releases} \
+        50 {} \
+        51 {Binary Releases} \
+        52 {} \
+        53 {Pre-compiled releases are available for the following platforms: } \
+        54 {} \
+        55 {     Windows 3.1, Windows 95, and Windows NT: Fetch} \
+        56 {     ftp://ftp.sunlabs.com/pub/tcl/win42b1.exe, then execute it. The file is a} \
+        57 {     self-extracting executable. It will install the Tcl and Tk libraries, the wish and} \
+        58 {     tclsh programs, and documentation. } \
+        59 {     Macintosh (both 68K and PowerPC): Fetch} \
+        60 {     ftp://ftp.sunlabs.com/pub/tcl/mactk4.2b1.sea.hqx. The file is in binhex format,} \
+        61 {     which is understood by Fetch, StuffIt, and many other Mac utilities. The} \
+        62 {     unpacked file is a self-installing executable: double-click on it and it will create a} \
+        63 {     folder containing all that you need to run Tcl and Tk. } \
+        64 {        UNIX (Solaris 2.* and SunOS, other systems soon to follow). Easy to install} \
+        65 {     binary packages are now for sale at the Sun Labs Tcl/Tk Shop. Check it out!} \
+    }
+    set result ""
+    set NL "
+"
+    set tag {level= type=text/plain part=0 sel Charset}
+    set ix [lsearch -regexp $tag text/enriched]
+    if {$ix < 0} {
+	set ranges {}
+	set quote 0
+    }
+    set breakrange {6.42 78.0}
+    set F1 [lindex $breakrange 0]
+    set F2 [lindex $breakrange 1]
+    set breakrange [lrange $breakrange 2 end]
+    if {[string length $F1] == 0} {
+	set F1 -1
+	set break 0
+    } else {
+	set break 1
+    }
+    set xmailer 0
+    set inheaders 1
+    set last [array size lines]
+    set plen 2
+    for {set L 1} {$L < $last} {incr L} {
+	set line $lines($L)
+	if {$inheaders} {
+	    # Blank or empty line terminates headers
+	    # Leading --- terminates headers
+	    if {[regexp {^[ 	]*$} $line] || [regexp {^--+} $line]} {
+		set inheaders 0
+	    }
+	    if {[regexp -nocase {^x-mailer:} $line]} {
+		continue
+	    }
+	}
+	if $inheaders {
+	    set limit 55
+	} else {
+	    set limit 55
+	    # Decide whether or not to break the body line
+	    if {$plen > 0} {
+		if {[string first {> } $line] == 0} {
+		    # This is quoted text from previous message, don't reformat
+		    append result $line $NL
+		    if {$quote && !$inheaders} {
+			# Fix from <sarr@umich.edu> to handle text/enriched
+			if {$L > $L1 && $L < $L2 && $line != {}} {
+			    # enriched requires two newlines for each one.
+			    append result $NL
+			} elseif {$L > $L2} {
+			    set L1 [lindex $ranges 0]
+			    set L2 [lindex $ranges 1]
+			    set ranges [lrange $ranges 2 end]
+			    set quote [llength $L1]
+			}
+		    }
+		    continue
+		}
+	    }
+	    if {$F1 < 0} {
+		# Nothing left to format
+		append result $line $NL
+		continue
+	    } elseif {$L < $F1} {
+		# Not yet to formatted block
+		append result $line $NL
+		continue
+	    } elseif {$L > $F2} {
+		# Past formatted block
+		set F1 [lindex $breakrange 0]
+		set F2 [lindex $breakrange 1]
+		set breakrange [lrange $breakrange 2 end]
+		append result $line $NL
+		if {[string length $F1] == 0} {
+		    set F1 -1
+		}
+		continue
+	    }
+	}
+	set climit [expr $limit-1]
+	set cutoff 50
+	set continuation 0
+
+	while {[string length $line] > $limit} {
+	    for {set c [expr $limit-1]} {$c >= $cutoff} {incr c -1} {
+		set char [string index $line $c]
+		if {$char == " " || $char == "\t"} {
+		    break
+		}
+		if {$char == ">"} {	;# Hack for enriched formatting
+		    break
+		}
+	    }
+	    if {$c < $cutoff} {
+		if {! $inheaders} {
+		    set c [expr $limit-1]
+		} else {
+		    set c [string length $line]
+		}
+	    }
+	    set newline [string range $line 0 $c]
+	    if {! $continuation} {
+		append result $newline $NL
+	    } else {
+		append result \ $newline $NL
+	    }
+	    incr c
+	    set line [string trimright [string range $line $c end]]
+	    if {$inheaders} {
+		set continuation 1
+		set limit $climit
+	    }
+	}
+	if {$continuation} {
+	    if {[string length $line] != 0} {
+		append result \ $line $NL
+	    }
+	} else {
+	    append result $line $NL
+	    if {$quote && !$inheaders} {
+		if {$L > $L1 && $L < $L2 && $line != {}} {
+		    # enriched requires two newlines for each one.
+		    append result "" $NL
+		} elseif {$L > $L2} {
+		    set L1 [lindex $ranges 0]
+		    set L2 [lindex $ranges 1]
+		    set ranges [lrange $ranges 2 end]
+		    set quote [llength $L1]
+		}
+	    }
+	}
+    }
+    return $result
+}
+test for-3.6 {break tests} {
+    formatMail
+} {Return-path: <george@tcl>
+Received: from tcl by tcl.Somewhere.COM (SMI-8.6/SMI-SVR4)
+	id LAA10027; Wed, 11 Sep 1996 11:14:53 -0700
+Message-id: <199609111814.LAA10027@tcl.Somewhere.COM>
+Mime-version: 1.0
+Content-type: text/plain; charset=iso-8859-1
+Content-transfer-encoding: quoted-printable
+Content-length: 2162
+To: fred
+Subject: tcl7.6
+Date: Wed, 11 Sep 1996 11:14:53 -0700
+From: George <george@tcl>
+The Tcl 7.6 and Tk 4.2 releases
+
+This page contains information about Tcl 7.6 and Tk4.2,
+ which are the most recent
+releases of the Tcl scripting language and the Tk toolk
+it. The first beta versions of these
+releases were released on August 30, 1996. These releas
+es contain only minor changes,
+so we hope to have only a single beta release and to 
+go final in early October, 1996.
+
+
+What's new 
+
+The most important changes in the releases are summariz
+ed below. See the README
+and changes files in the distributions for more complet
+e information on what has
+changed, including both feature changes and bug fixes. 
+
+     There are new options to the file command for 
+copying files (file copy),
+     deleting files and directories (file delete), 
+creating directories (file
+     mkdir), and renaming files (file rename). 
+     The implementation of exec has been improved great
+ly for Windows 95 and
+     Windows NT. 
+     There is a new memory allocator for the Macintosh 
+version, which should be
+     more efficient than the old one. 
+     Tk's grid geometry manager has been completely 
+rewritten. The layout
+     algorithm produces much better layouts than before
+, especially where rows or
+     columns were stretchable. 
+     There are new commands for creating common dialog 
+boxes:
+     tk_chooseColor, tk_getOpenFile, tk_getSaveFile and
+     tk_messageBox. These use native dialog boxes if 
+they are available.
+     There is a new virtual event mechanism for handlin
+g events in a more portable
+     way. See the new command event. It also allows 
+events (both physical and
+     virtual) to be generated dynamically. 
+
+Tcl 7.6 and Tk 4.2 are backwards-compatible with Tcl 
+7.5 and Tk 4.1 except for
+changes in the C APIs for custom channel drivers. Scrip
+ts written for earlier releases
+should work on these new releases as well. 
+
+Obtaining The Releases
+
+Binary Releases
+
+Pre-compiled releases are available for the following 
+platforms:
+
+     Windows 3.1, Windows 95, and Windows NT: Fetch
+     ftp://ftp.sunlabs.com/pub/tcl/win42b1.exe, then 
+execute it. The file is a
+     self-extracting executable. It will install the 
+Tcl and Tk libraries, the wish and
+     tclsh programs, and documentation. 
+     Macintosh (both 68K and PowerPC): Fetch
+     ftp://ftp.sunlabs.com/pub/tcl/mactk4.2b1.sea.hqx. 
+The file is in binhex format,
+     which is understood by Fetch, StuffIt, and many 
+other Mac utilities. The
+     unpacked file is a self-installing executable: 
+double-click on it and it will create a
+     folder containing all that you need to run Tcl 
+and Tk.
+        UNIX (Solaris 2.* and SunOS, other systems 
+soon to follow). Easy to install
+     binary packages are now for sale at the Sun Labs 
+Tcl/Tk Shop. Check it out!
+}
+
+# Check that "break" resets the interpreter's result
+
+test for-4.1 {break must reset the interp result} {
+    catch {
+        set z GLOBTESTDIR/dir2/file2.c
+        if [string match GLOBTESTDIR/dir2/* $z] {
+            break
+        }
+    } j
+    set j
+} {}
+
+# Test for incorrect "double evaluation" semantics
+
+test for-5.1 {possible delayed substitution of increment command} {
+    # Increment should be 5, and lappend should always append $a
+    catch {unset a}
+    catch {unset i}
+    set a 5
+    set i {}
+    for {set a 1} {$a < 12} "incr a $a" {lappend i $a}
+    set i
+} {1 6 11}
+
+test for-5.2 {possible delayed substitution of increment command} {
+    # Increment should be 5, and lappend should always append $a
+    catch {rename p ""}
+    proc p {} {
+	set a 5
+	set i {}
+	for {set a 1} {$a < 12} "incr a $a" {lappend i $a}
+	set i
+    }
+    p
+} {1 6 11}
+test for-5.3 {possible delayed substitution of body command} {
+    # Increment should be $a, and lappend should always append 5
+    set a 5
+    set i {}
+    for {set a 1} {$a < 12} {incr a $a} "lappend i $a"
+    set i
+} {5 5 5 5}
+test for-5.4 {possible delayed substitution of body command} {
+    # Increment should be $a, and lappend should always append 5
+    catch {rename p ""}
+    proc p {} {
+	set a 5
+	set i {}
+	for {set a 1} {$a < 12} {incr a $a} "lappend i $a"
+	set i
+    }
+    p
+} {5 5 5 5}
+
+# In the following tests we need to bypass the bytecode compiler by
+# substituting the command from a variable.  This ensures that command
+# procedure is invoked directly.
+
+test for-6.1 {Tcl_ForObjCmd: number of args} {
+    set z for
+    catch {$z} msg
+    set msg
+} {wrong # args: should be "for start test next command"}
+test for-6.2 {Tcl_ForObjCmd: number of args} {
+    set z for
+    catch {$z {set i 0}} msg
+    set msg
+} {wrong # args: should be "for start test next command"}
+test for-6.3 {Tcl_ForObjCmd: number of args} {
+    set z for
+    catch {$z {set i 0} {$i < 5}} msg
+    set msg
+} {wrong # args: should be "for start test next command"}
+test for-6.4 {Tcl_ForObjCmd: number of args} {
+    set z for
+    catch {$z {set i 0} {$i < 5} {incr i}} msg
+    set msg
+} {wrong # args: should be "for start test next command"}
+test for-6.5 {Tcl_ForObjCmd: number of args} {
+    set z for
+    catch {$z {set i 0} {$i < 5} {incr i} {body} extra} msg
+    set msg
+} {wrong # args: should be "for start test next command"}
+test for-6.6 {Tcl_ForObjCmd: error in initial command} -body {
+    set z for
+    list [catch {$z {set} {$i < 5} {incr i} {body}} msg] $msg $::errorInfo
+} -match glob -result {1 {wrong # args: should be "set varName ?newValue?"} {wrong # args: should be "set varName ?newValue?"
+    while *ing
+"set"
+    ("for" initial command)
+    invoked from within
+"$z {set} {$i < 5} {incr i} {body}"}}
+test for-6.7 {Tcl_ForObjCmd: error in test expression} -body {
+    set z for
+    catch {$z {set i 0} {i < 5} {incr i} {body}}
+    set ::errorInfo
+} -match glob -result {*"$z {set i 0} {i < 5} {incr i} {body}"}
+test for-6.8 {Tcl_ForObjCmd: test expression is enclosed in quotes} {
+    set z for
+    set i 0
+    $z {set i 6} "$i > 5" {incr i} {set y $i}
+    set i
+} 6
+test for-6.9 {Tcl_ForObjCmd: error executing command body} -body {
+    set z for
+    catch {$z {set i 0} {$i < 5} {incr i} {set}} msg
+    set ::errorInfo
+} -match glob -result {wrong # args: should be "set varName ?newValue?"
+    while *ing
+"set"
+    ("for" body line 1)
+    invoked from within
+"$z {set i 0} {$i < 5} {incr i} {set}"}
+test for-6.10 {Tcl_ForObjCmd: simple command body} {
+    set z for
+    set a {}
+    $z {set i 1} {$i<6} {set i [expr $i+1]} {
+	if $i==4 break
+	set a [concat $a $i]
+    }
+    set a
+} {1 2 3}
+test for-6.11 {Tcl_ForObjCmd: command body in quotes} {
+    set z for
+    set a {}
+    $z {set i 1} {$i<6} {set i [expr $i+1]} "append a x"
+    set a
+} {xxxxx}
+test for-6.12 {Tcl_ForObjCmd: computed command body} {
+    set z for
+    catch {unset x1}
+    catch {unset bb}
+    catch {unset x2}
+    set x1 {append a x1; }
+    set bb {break}
+    set x2 {; append a x2}
+    set a {}
+    $z {set i 1} {$i<6} {set i [expr $i+1]} $x1$bb$x2
+    set a
+} {x1}
+test for-6.13 {Tcl_ForObjCmd: error in "next" command} -body {
+    set z for
+    catch {$z {set i 0} {$i < 5} {set} {set j 4}} msg
+    set ::errorInfo
+} -match glob -result {wrong # args: should be "set varName ?newValue?"
+    while *ing
+"set"
+    ("for" loop-end command)
+    invoked from within
+"$z {set i 0} {$i < 5} {set} {set j 4}"}
+test for-6.14 {Tcl_ForObjCmd: long command body} {
+    set z for
+    set a {}
+    $z {set i 1} {$i<6} {set i [expr $i+1]} {
+	if $i==4 break
+	if $i>5 continue
+	if {$i>6 && $tcl_platform(machine)=="xxx"} {
+	    catch {set a $a} msg
+	    catch {incr i 5} msg
+	    catch {incr i -5} msg
+	}
+	if {$i>6 && $tcl_platform(machine)=="xxx"} {
+	    catch {set a $a} msg
+	    catch {incr i 5} msg
+	    catch {incr i -5} msg
+	}
+	if {$i>6 && $tcl_platform(machine)=="xxx"} {
+	    catch {set a $a} msg
+	    catch {incr i 5} msg
+	    catch {incr i -5} msg
+	}
+	if {$i>6 && $tcl_platform(machine)=="xxx"} {
+	    catch {set a $a} msg
+	    catch {incr i 5} msg
+	    catch {incr i -5} msg
+	}
+	if {$i>6 && $tcl_platform(machine)=="xxx"} {
+	    catch {set a $a} msg
+	    catch {incr i 5} msg
+	    catch {incr i -5} msg
+	}
+	set a [concat $a $i]
+    }
+    set a
+} {1 2 3}
+test for-6.15 {Tcl_ForObjCmd: for command result} {
+    set z for
+    set a [$z {set i 0} {$i < 5} {incr i} {}]
+    set a
+} {}
+test for-6.16 {Tcl_ForObjCmd: for command result} {
+    set z for
+    set a [$z {set i 0} {$i < 5} {incr i} {if $i==3 break}]
+    set a
+} {}
+test for-6.17 {Tcl_ForObjCmd: for command result} {
+    list \
+        [catch {for {break} {1} {} {}} err] $err \
+        [catch {for {continue} {1} {} {}} err] $err \
+        [catch {for {} {[break]} {} {}} err] $err \
+        [catch {for {} {[continue]} {} {}} err] $err \
+        [catch {for {} {1} {break} {}} err] $err \
+        [catch {for {} {1} {continue} {}} err] $err \
+} [list \
+    3 {} \
+    4 {} \
+    3 {} \
+    4 {} \
+    0 {} \
+    4 {} \
+    ]
+test for-6.18 {Tcl_ForObjCmd: for command result} {
+    proc p6181 {} {
+        for {break} {1} {} {}
+    }
+    proc p6182 {} {
+        for {continue} {1} {} {}
+    }
+    proc p6183 {} {
+        for {} {[break]} {} {}
+    }
+    proc p6184 {} {
+        for {} {[continue]} {} {}
+    }
+    proc p6185 {} {
+        for {} {1} {break} {}
+    }
+    proc p6186 {} {
+        for {} {1} {continue} {}
+    }
+    list \
+        [catch {p6181} err] $err \
+        [catch {p6182} err] $err \
+        [catch {p6183} err] $err \
+        [catch {p6184} err] $err \
+        [catch {p6185} err] $err \
+        [catch {p6186} err] $err
+} [list \
+    1 {invoked "break" outside of a loop} \
+    1 {invoked "continue" outside of a loop} \
+    1 {invoked "break" outside of a loop} \
+    1 {invoked "continue" outside of a loop} \
+    0 {} \
+    1 {invoked "continue" outside of a loop} \
+    ]
+
+test for-7.1 {Bug 3614226: ensure that break cleans up the stack} memory {
+    apply {{} {
+	# Can't use [memtest]; must be careful when we change stack frames
+	set end [meminfo]
+	for {set i 0} {$i < 5} {incr i} {
+	    for {set x 0} {$x < 5} {incr x} {
+		list a b c [break] d e f
+	    }
+	    set tmp $end
+	    set end [meminfo]
+	}
+	expr {$end - $tmp}
+    }}
+} 0
+test for-7.2 {Bug 3614226: ensure that continue cleans up the stack} memory {
+    apply {{} {
+	# Can't use [memtest]; must be careful when we change stack frames
+	set end [meminfo]
+	for {set i 0} {$i < 5} {incr i} {
+	    for {set x 0} {$x < 5} {incr x} {
+		list a b c [continue] d e f
+	    }
+	    set tmp $end
+	    set end [meminfo]
+	}
+	expr {$end - $tmp}
+    }}
+} 0
+test for-7.3 {Bug 3614226: ensure that break cleans up the expansion stack} memory {
+    apply {{} {
+	# Can't use [memtest]; must be careful when we change stack frames
+	set end [meminfo]
+	for {set i 0} {$i < 5} {incr i} {
+	    for {set x 0} {[incr x]<50} {} {
+		puts {*}[puts a b c {*}[break] d e f]
+	    }
+	    set tmp $end
+	    set end [meminfo]
+	}
+	expr {$end - $tmp}
+    }}
+} 0
+test for-7.4 {Bug 3614226: ensure that continue cleans up the expansion stack} memory {
+    apply {{} {
+	# Can't use [memtest]; must be careful when we change stack frames
+	set end [meminfo]
+	for {set i 0} {$i < 5} {incr i} {
+	    for {set x 0} {[incr x]<50} {} {
+		puts {*}[puts a b c {*}[continue] d e f]
+	    }
+	    set tmp $end
+	    set end [meminfo]
+	}
+	expr {$end - $tmp}
+    }}
+} 0
+test for-7.5 {Bug 3614226: ensure that break cleans up the combination of main and expansion stack} memory {
+    apply {{} {
+	set l [lrepeat 50 p q r]
+	# Can't use [memtest]; must be careful when we change stack frames
+	set end [meminfo]
+	for {set i 0} {$i < 5} {incr i} {
+	    for {set x 0} {[incr x]<50} {} {
+		puts [puts {*}$l {*}[puts a b c {*}$l {*}[break] d e f]]
+	    }
+	    set tmp $end
+	    set end [meminfo]
+	}
+	expr {$end - $tmp}
+    }}
+} 0
+test for-7.6 {Bug 3614226: ensure that continue cleans up the combination of main and expansion stack} memory {
+    apply {{} {
+	set l [lrepeat 50 p q r]
+	# Can't use [memtest]; must be careful when we change stack frames
+	set end [meminfo]
+	for {set i 0} {$i < 5} {incr i} {
+	    for {set x 0} {[incr x]<50} {} {
+		puts [puts {*}$l {*}[puts a b c {*}$l {*}[continue] d e f]]
+	    }
+	    set tmp $end
+	    set end [meminfo]
+	}
+	expr {$end - $tmp}
+    }}
+} 0
+test for-7.7 {Bug 3614226: ensure that break only cleans up the right amount} memory {
+    apply {{} {
+	set l [lrepeat 50 p q r]
+	# Can't use [memtest]; must be careful when we change stack frames
+	set end [meminfo]
+	for {set i 0} {$i < 5} {incr i} {
+	    unset -nocomplain {*}[for {set x 0} {[incr x]<50} {} {
+		puts [puts {*}$l {*}[puts a b c {*}$l {*}[break] d e f]]
+	    }]
+	    set tmp $end
+	    set end [meminfo]
+	}
+	expr {$end - $tmp}
+    }}
+} 0
+test for-7.8 {Bug 3614226: ensure that continue only cleans up the right amount} memory {
+    apply {{} {
+	set l [lrepeat 50 p q r]
+	# Can't use [memtest]; must be careful when we change stack frames
+	set end [meminfo]
+	for {set i 0} {$i < 5} {incr i} {
+	    unset -nocomplain {*}[for {set x 0} {[incr x]<50} {} {
+		puts [puts {*}$l {*}[puts a b c {*}$l {*}[continue] d e f]]
+	    }]
+	    set tmp $end
+	    set end [meminfo]
+	}
+	expr {$end - $tmp}
+    }}
+} 0
+test for-7.9 {Bug 3614226: ensure that break from invoked command cleans up the stack} memory {
+    apply {{} {
+	# Can't use [memtest]; must be careful when we change stack frames
+	set end [meminfo]
+	for {set i 0} {$i < 5} {incr i} {
+	    for {set x 0} {$x < 5} {incr x} {
+		list a b c [apply {{} {return -code break}}] d e f
+	    }
+	    set tmp $end
+	    set end [meminfo]
+	}
+	expr {$end - $tmp}
+    }}
+} 0
+test for-7.10 {Bug 3614226: ensure that continue from invoked command cleans up the stack} memory {
+    apply {{} {
+	# Can't use [memtest]; must be careful when we change stack frames
+	set end [meminfo]
+	for {set i 0} {$i < 5} {incr i} {
+	    for {set x 0} {$x < 5} {incr x} {
+		list a b c [apply {{} {return -code continue}}] d e f
+	    }
+	    set tmp $end
+	    set end [meminfo]
+	}
+	expr {$end - $tmp}
+    }}
+} 0
+test for-7.11 {Bug 3614226: ensure that break from invoked command cleans up the expansion stack} memory {
+    apply {{} {
+	# Can't use [memtest]; must be careful when we change stack frames
+	set end [meminfo]
+	for {set i 0} {$i < 5} {incr i} {
+	    for {set x 0} {[incr x]<50} {} {
+		puts {*}[puts a b c {*}[apply {{} {return -code break}}] d e f]
+	    }
+	    set tmp $end
+	    set end [meminfo]
+	}
+	expr {$end - $tmp}
+    }}
+} 0
+test for-7.12 {Bug 3614226: ensure that continue from invoked command cleans up the expansion stack} memory {
+    apply {{} {
+	# Can't use [memtest]; must be careful when we change stack frames
+	set end [meminfo]
+	for {set i 0} {$i < 5} {incr i} {
+	    for {set x 0} {[incr x]<50} {} {
+		puts {*}[puts a b c {*}[apply {{} {
+		    return -code continue
+		}}] d e f]
+	    }
+	    set tmp $end
+	    set end [meminfo]
+	}
+	expr {$end - $tmp}
+    }}
+} 0
+test for-7.13 {Bug 3614226: ensure that break from invoked command cleans up the combination of main and expansion stack} memory {
+    apply {{} {
+	set l [lrepeat 50 p q r]
+	# Can't use [memtest]; must be careful when we change stack frames
+	set end [meminfo]
+	for {set i 0} {$i < 5} {incr i} {
+	    for {set x 0} {[incr x]<50} {} {
+		puts [puts {*}$l {*}[puts a b c {*}$l {*}[apply {{} {
+		    return -code break
+		}}] d e f]]
+	    }
+	    set tmp $end
+	    set end [meminfo]
+	}
+	expr {$end - $tmp}
+    }}
+} 0
+test for-7.14 {Bug 3614226: ensure that continue from invoked command cleans up the combination of main and expansion stack} memory {
+    apply {{} {
+	set l [lrepeat 50 p q r]
+	# Can't use [memtest]; must be careful when we change stack frames
+	set end [meminfo]
+	for {set i 0} {$i < 5} {incr i} {
+	    for {set x 0} {[incr x]<50} {} {
+		puts [puts {*}$l {*}[puts a b c {*}$l {*}[apply {{} {
+		    return -code continue
+		}}] d e f]]
+	    }
+	    set tmp $end
+	    set end [meminfo]
+	}
+	expr {$end - $tmp}
+    }}
+} 0
+test for-7.15 {Bug 3614226: ensure that break from invoked command only cleans up the right amount} memory {
+    apply {{} {
+	set l [lrepeat 50 p q r]
+	# Can't use [memtest]; must be careful when we change stack frames
+	set end [meminfo]
+	for {set i 0} {$i < 5} {incr i} {
+	    unset -nocomplain {*}[for {set x 0} {[incr x]<50} {} {
+		puts [puts {*}$l {*}[puts a b c {*}$l {*}[apply {{} {
+		    return -code break
+		}}] d e f]]
+	    }]
+	    set tmp $end
+	    set end [meminfo]
+	}
+	expr {$end - $tmp}
+    }}
+} 0
+test for-7.16 {Bug 3614226: ensure that continue from invoked command only cleans up the right amount} memory {
+    apply {{} {
+	set l [lrepeat 50 p q r]
+	# Can't use [memtest]; must be careful when we change stack frames
+	set end [meminfo]
+	for {set i 0} {$i < 5} {incr i} {
+	    unset -nocomplain {*}[for {set x 0} {[incr x]<50} {} {
+		puts [puts {*}$l {*}[puts a b c {*}$l {*}[apply {{} {
+		    return -code continue
+		}}] d e f]]
+	    }]
+	    set tmp $end
+	    set end [meminfo]
+	}
+	expr {$end - $tmp}
+    }}
+} 0
+test for-7.17 {Bug 3614226: ensure that break from expanded command cleans up the stack} memory {
+    apply {op {
+	# Can't use [memtest]; must be careful when we change stack frames
+	set end [meminfo]
+	for {set i 0} {$i < 5} {incr i} {
+	    for {set x 0} {$x < 5} {incr x} {
+		list a b c [{*}$op] d e f
+	    }
+	    set tmp $end
+	    set end [meminfo]
+	}
+	expr {$end - $tmp}
+    }} {return -level 0 -code break}
+} 0
+test for-7.18 {Bug 3614226: ensure that continue from expanded command cleans up the stack} memory {
+    apply {op {
+	# Can't use [memtest]; must be careful when we change stack frames
+	set end [meminfo]
+	for {set i 0} {$i < 5} {incr i} {
+	    for {set x 0} {$x < 5} {incr x} {
+		list a b c [{*}$op] d e f
+	    }
+	    set tmp $end
+	    set end [meminfo]
+	}
+	expr {$end - $tmp}
+    }} {return -level 0 -code continue}
+} 0
+test for-7.19 {Bug 3614226: ensure that break from expanded command cleans up the expansion stack} memory {
+    apply {op {
+	# Can't use [memtest]; must be careful when we change stack frames
+	set end [meminfo]
+	for {set i 0} {$i < 5} {incr i} {
+	    for {set x 0} {[incr x]<50} {} {
+		puts {*}[puts a b c {*}[{*}$op] d e f]
+	    }
+	    set tmp $end
+	    set end [meminfo]
+	}
+	expr {$end - $tmp}
+    }} {return -level 0 -code break}
+} 0
+test for-7.20 {Bug 3614226: ensure that continue from expanded command cleans up the expansion stack} memory {
+    apply {op {
+	# Can't use [memtest]; must be careful when we change stack frames
+	set end [meminfo]
+	for {set i 0} {$i < 5} {incr i} {
+	    for {set x 0} {[incr x]<50} {} {
+		puts {*}[puts a b c {*}[{*}$op] d e f]
+	    }
+	    set tmp $end
+	    set end [meminfo]
+	}
+	expr {$end - $tmp}
+    }} {return -level 0 -code continue}
+} 0
+test for-7.21 {Bug 3614226: ensure that break from expanded command cleans up the combination of main and expansion stack} memory {
+    apply {op {
+	set l [lrepeat 50 p q r]
+	# Can't use [memtest]; must be careful when we change stack frames
+	set end [meminfo]
+	for {set i 0} {$i < 5} {incr i} {
+	    for {set x 0} {[incr x]<50} {} {
+		puts [puts {*}$l {*}[puts a b c {*}$l {*}[{*}$op] d e f]]
+	    }
+	    set tmp $end
+	    set end [meminfo]
+	}
+	expr {$end - $tmp}
+    }} {return -level 0 -code break}
+} 0
+test for-7.22 {Bug 3614226: ensure that continue from expanded command cleans up the combination of main and expansion stack} memory {
+    apply {op {
+	set l [lrepeat 50 p q r]
+	# Can't use [memtest]; must be careful when we change stack frames
+	set end [meminfo]
+	for {set i 0} {$i < 5} {incr i} {
+	    for {set x 0} {[incr x]<50} {} {
+		puts [puts {*}$l {*}[puts a b c {*}$l {*}[{*}$op] d e f]]
+	    }
+	    set tmp $end
+	    set end [meminfo]
+	}
+	expr {$end - $tmp}
+    }} {return -level 0 -code continue}
+} 0
+test for-7.23 {Bug 3614226: ensure that break from expanded command only cleans up the right amount} memory {
+    apply {op {
+	set l [lrepeat 50 p q r]
+	# Can't use [memtest]; must be careful when we change stack frames
+	set end [meminfo]
+	for {set i 0} {$i < 5} {incr i} {
+	    unset -nocomplain {*}[for {set x 0} {[incr x]<50} {} {
+		puts [puts {*}$l {*}[puts a b c {*}$l {*}[{*}$op] d e f]]
+	    }]
+	    set tmp $end
+	    set end [meminfo]
+	}
+	expr {$end - $tmp}
+    }} {return -level 0 -code break}
+} 0
+test for-7.24 {Bug 3614226: ensure that continue from expanded command only cleans up the right amount} memory {
+    apply {op {
+	set l [lrepeat 50 p q r]
+	# Can't use [memtest]; must be careful when we change stack frames
+	set end [meminfo]
+	for {set i 0} {$i < 5} {incr i} {
+	    unset -nocomplain {*}[for {set x 0} {[incr x]<50} {} {
+		puts [puts {*}$l {*}[puts a b c {*}$l {*}[{*}$op] d e f]]
+	    }]
+	    set tmp $end
+	    set end [meminfo]
+	}
+	expr {$end - $tmp}
+    }} {return -level 0 -code continue}
+} 0
+
+test for-8.0 {Coverity CID 1251203: break vs continue in for-step clause} {
+    apply {{} {
+	for {set k 0} {$k < 3} {incr k} {
+	    set j 0
+	    list a [\
+	    for {set i 0} {$i < 5} {incr i; list a [eval {}]} {
+		incr j
+	    }]
+	    incr i
+	}
+	list $i $j $k
+    }}
+} {6 5 3}
+test for-8.1 {Coverity CID 1251203: break vs continue in for-step clause} {
+    apply {{} {
+	for {set k 0} {$k < 3} {incr k} {
+	    set j 0
+	    list a [\
+	    for {set i 0} {$i < 5} {incr i;list a [eval break]} {
+		incr j
+	    }]
+	    incr i
+	}
+	list $i $j $k
+    }}
+} {2 1 3}
+test for-8.2 {Coverity CID 1251203: break vs continue in for-step clause} {
+    apply {{} {
+	for {set k 0} {$k < 3} {incr k} {
+	    set j 0
+	    list a [\
+	    for {set i 0} {$i < 5} {incr i;list a [eval continue]} {
+		incr j
+	    }]
+	    incr i
+	}
+	list $i $j $k
+    }}
+} {1 1 3}
+test for-8.3 {break in for-step clause} {
+    apply {{} {
+	for {set k 0} {$k < 3} {incr k} {
+	    set j 0
+	    list a [\
+	    for {set i 0} {$i < 5} {incr i; break} {
+		incr j
+	    }]
+	    incr i
+	}
+	list $i $j $k
+    }}
+} {2 1 3}
+test for-8.4 {continue in for-step clause} {
+    apply {{} {
+	for {set k 0} {$k < 3} {incr k} {
+	    set j 0
+	    list a [\
+	    for {set i 0} {$i < 5} {incr i; continue} {
+		incr j
+	    }]
+	    incr i
+	}
+	list $i $j $k
+    }}
+} {1 1 3}
+test for-8.5 {break in for-step clause} {
+    apply {{} {
+	for {set k 0} {$k < 3} {incr k} {
+	    set j 0
+	    list a [\
+	    for {set i 0} {$i < 5} {incr i; list a [break]} {
+		incr j
+	    }]
+	    incr i
+	}
+	list $i $j $k
+    }}
+} {2 1 3}
+test for-8.6 {continue in for-step clause} {
+    apply {{} {
+	for {set k 0} {$k < 3} {incr k} {
+	    set j 0
+	    list a [\
+	    for {set i 0} {$i < 5} {incr i; list a [continue]} {
+		incr j
+	    }]
+	    incr i
+	}
+	list $i $j $k
+    }}
+} {1 1 3}
+test for-8.7 {break in for-step clause} {
+    apply {{} {
+	for {set k 0} {$k < 3} {incr k} {
+	    set j 0
+	    list a [\
+	    for {set i 0} {$i < 5} {incr i;eval break} {
+		incr j
+	    }]
+	    incr i
+	}
+	list $i $j $k
+    }}
+} {2 1 3}
+test for-8.8 {continue in for-step clause} {
+    apply {{} {
+	for {set k 0} {$k < 3} {incr k} {
+	    set j 0
+	    list a [\
+	    for {set i 0} {$i < 5} {incr i;eval continue} {
+		incr j
+	    }]
+	    incr i
+	}
+	list $i $j $k
+    }}
+} {1 1 3}
+test for-8.9 {break in for-step clause} {
+    apply {{} {
+	for {set k 0} {$k < 3} {incr k} {
+	    set j 0
+	    for {set i 0} {$i < 5} {incr i;eval break} {
+		incr j
+	    }
+	    incr i
+	}
+	list $i $j $k
+    }}
+} {2 1 3}
+test for-8.10 {continue in for-step clause} {
+    apply {{} {
+	for {set k 0} {$k < 3} {incr k} {
+	    set j 0
+	    for {set i 0} {$i < 5} {incr i;eval continue} {
+		incr j
+	    }
+	    incr i
+	}
+	list $i $j $k
+    }}
+} {1 1 3}
+test for-8.11 {break in for-step clause} {
+    apply {{} {
+	for {set k 0} {$k < 3} {incr k} {
+	    set j 0
+	    for {set i 0} {$i < 5} {incr i;break} {
+		incr j
+	    }
+	    incr i
+	}
+	list $i $j $k
+    }}
+} {2 1 3}
+test for-8.12 {continue in for-step clause} {
+    apply {{} {
+	for {set k 0} {$k < 3} {incr k} {
+	    set j 0
+	    for {set i 0} {$i < 5} {incr i;continue} {
+		incr j
+	    }
+	    incr i
+	}
+	list $i $j $k
+    }}
+} {1 1 3}
+
+# cleanup
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/tests/foreach.test b/tests/foreach.test
new file mode 100644
index 0000000..6fd5476
--- /dev/null
+++ b/tests/foreach.test
@@ -0,0 +1,294 @@
+# Commands covered:  foreach, continue, break
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands.  Sourcing this file into Tcl runs the tests and
+# generates output for errors.  No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994-1997 Sun Microsystems, Inc.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+    package require tcltest
+    namespace import -force ::tcltest::*
+}
+
+catch {unset a}
+catch {unset x}
+
+# Basic "foreach" operation.
+
+test foreach-1.1 {basic foreach tests} {
+    set a {}
+    foreach i {a b c d} {
+	set a [concat $a $i]
+    }
+    set a
+} {a b c d}
+test foreach-1.2 {basic foreach tests} {
+    set a {}
+    foreach i {a b {{c d} e} {123 {{x}}}} {
+	set a [concat $a $i]
+    }
+    set a
+} {a b {c d} e 123 {{x}}}
+test foreach-1.3 {basic foreach tests} {catch {foreach} msg} 1
+test foreach-1.4 {basic foreach tests} {
+    catch {foreach} msg
+    set msg
+} {wrong # args: should be "foreach varList list ?varList list ...? command"}
+test foreach-1.5 {basic foreach tests} {catch {foreach i} msg} 1
+test foreach-1.6 {basic foreach tests} {
+    catch {foreach i} msg
+    set msg
+} {wrong # args: should be "foreach varList list ?varList list ...? command"}
+test foreach-1.7 {basic foreach tests} {catch {foreach i j} msg} 1
+test foreach-1.8 {basic foreach tests} {
+    catch {foreach i j} msg
+    set msg
+} {wrong # args: should be "foreach varList list ?varList list ...? command"}
+test foreach-1.9 {basic foreach tests} {catch {foreach i j k l} msg} 1
+test foreach-1.10 {basic foreach tests} {
+    catch {foreach i j k l} msg
+    set msg
+} {wrong # args: should be "foreach varList list ?varList list ...? command"}
+test foreach-1.11 {basic foreach tests} {
+    set a {}
+    foreach i {} {
+	set a [concat $a $i]
+    }
+    set a
+} {}
+test foreach-1.12 {foreach errors} {
+    list [catch {foreach {{a}{b}} {1 2 3} {}} msg] $msg
+} {1 {list element in braces followed by "{b}" instead of space}}
+test foreach-1.13 {foreach errors} {
+    list [catch {foreach a {{1 2}3} {}} msg] $msg
+} {1 {list element in braces followed by "3" instead of space}}
+catch {unset a}
+test foreach-1.14 {foreach errors} {
+    catch {unset a}
+    set a(0) 44
+    list [catch {foreach a {1 2 3} {}} msg o] $msg $::errorInfo
+} {1 {can't set "a": variable is array} {can't set "a": variable is array
+    (setting foreach loop variable "a")
+    invoked from within
+"foreach a {1 2 3} {}"}}
+test foreach-1.15 {foreach errors} {
+    list [catch {foreach {} {} {}} msg] $msg
+} {1 {foreach varlist is empty}}
+catch {unset a}
+
+test foreach-2.1 {parallel foreach tests} {
+    set x {}
+    foreach {a b} {1 2 3 4} {
+	append x $b $a
+    }
+    set x
+} {2143}
+test foreach-2.2 {parallel foreach tests} {
+    set x {}
+    foreach {a b} {1 2 3 4 5} {
+	append x $b $a
+    }
+    set x
+} {21435}
+test foreach-2.3 {parallel foreach tests} {
+    set x {}
+    foreach a {1 2 3} b {4 5 6} {
+	append x $b $a
+    }
+    set x
+} {415263}
+test foreach-2.4 {parallel foreach tests} {
+    set x {}
+    foreach a {1 2 3} b {4 5 6 7 8} {
+	append x $b $a
+    }
+    set x
+} {41526378}
+test foreach-2.5 {parallel foreach tests} {
+    set x {}
+    foreach {a b} {a b A B aa bb} c {c C cc CC} {
+	append x $a $b $c
+    }
+    set x
+} {abcABCaabbccCC}
+test foreach-2.6 {parallel foreach tests} {
+    set x {}
+    foreach a {1 2 3} b {1 2 3} c {1 2 3} d {1 2 3} e {1 2 3} {
+	append x $a $b $c $d $e
+    }
+    set x
+} {111112222233333}
+test foreach-2.7 {parallel foreach tests} {
+    set x {}
+    foreach a {} b {1 2 3} c {1 2} d {1 2 3 4} e {{1 2}} {
+	append x $a $b $c $d $e
+    }
+    set x
+} {1111 2222334}
+test foreach-2.8 {foreach only sets vars if repeating loop} {
+    proc foo {} {
+        set rgb {65535 0 0}
+        foreach {r g b} [set rgb] {}
+        return "r=$r, g=$g, b=$b"
+    }
+    foo
+} {r=65535, g=0, b=0}
+test foreach-2.9 {foreach only supports local scalar variables} {
+    proc foo {} {
+        set x {}
+        foreach {a(3)} {1 2 3 4} {lappend x [set {a(3)}]}
+        set x
+    }
+    foo
+} {1 2 3 4}
+
+test foreach-3.1 {compiled foreach backward jump works correctly} {
+    catch {unset x}
+    proc foo {arrayName} {
+        upvar 1 $arrayName a
+        set l {}
+        foreach member [array names a] {
+            lappend l [list $member [set a($member)]]
+        }
+        return $l
+    }
+    array set x {0 zero 1 one 2 two 3 three}
+    lsort [foo x]
+} [lsort {{0 zero} {1 one} {2 two} {3 three}}]
+
+test foreach-4.1 {noncompiled foreach and shared variable or value list objects that are converted to another type} {
+    catch {unset x}
+    foreach {12.0} {a b c} {
+        set x 12.0
+        set x [expr $x + 1]
+    }
+    set x
+} 13.0
+
+# Check "continue".
+
+test foreach-5.1 {continue tests} {catch continue} 4
+test foreach-5.2 {continue tests} {
+    set a {}
+    foreach i {a b c d} {
+	if {[string compare $i "b"] == 0} continue
+	set a [concat $a $i]
+    }
+    set a
+} {a c d}
+test foreach-5.3 {continue tests} {
+    set a {}
+    foreach i {a b c d} {
+	if {[string compare $i "b"] != 0} continue
+	set a [concat $a $i]
+    }
+    set a
+} {b}
+test foreach-5.4 {continue tests} {catch {continue foo} msg} 1
+test foreach-5.5 {continue tests} {
+    catch {continue foo} msg
+    set msg
+} {wrong # args: should be "continue"}
+
+# Check "break".
+
+test foreach-6.1 {break tests} {catch break} 3
+test foreach-6.2 {break tests} {
+    set a {}
+    foreach i {a b c d} {
+	if {[string compare $i "c"] == 0} break
+	set a [concat $a $i]
+    }
+    set a
+} {a b}
+test foreach-6.3 {break tests} {catch {break foo} msg} 1
+test foreach-6.4 {break tests} {
+    catch {break foo} msg
+    set msg
+} {wrong # args: should be "break"}
+# Check for bug #406709
+test foreach-6.5 {break tests} {
+    proc a {} {
+	set a 1
+	foreach b b {list [concat a; break]; incr a}
+	incr a
+    }
+    a
+} {2}
+
+# Test for incorrect "double evaluation" semantics
+test foreach-7.1 {delayed substitution of body} {
+    proc foo {} {
+       set a 0
+       foreach a [list 1 2 3] "
+           set x $a
+       "
+       set x
+    }
+    foo
+} {0}
+
+# Test for [Bug 1189274]; crash on failure
+test foreach-8.1 {empty list handling} {
+    proc crash {} {
+	rename crash {}
+	set a "x y z"
+	set b ""
+	foreach aa $a bb $b { set x "aa = $aa bb = $bb" }
+    }
+    crash
+} {}
+
+# [Bug 1671138]; infinite loop with empty var list in bytecompiled version
+test foreach-9.1 {compiled empty var list} {
+    proc foo {} {
+	foreach {} x {
+	    error "reached body"
+	}
+    }
+    list [catch { foo } msg] $msg
+} {1 {foreach varlist is empty}}
+
+test foreach-9.2 {line numbers} -setup {
+    proc linenumber {} {dict get [info frame -1] line}
+} -body {
+    apply {n {
+        foreach x y {*}{
+        } {return [incr n -[linenumber]]}
+    }} [linenumber]
+} -cleanup {
+    rename linenumber {}
+} -result 1
+
+test foreach-10.1 {foreach: [Bug 1671087]} -setup {
+    proc demo {} {
+	set vals {1 2 3 4}
+	trace add variable x write {string length $vals ;# }
+	foreach {x y} $vals {format $y}
+    }
+} -body {
+    demo
+} -cleanup {
+    rename demo {}
+} -result {}
+
+test foreach-11.1 {error then dereference loop var (dev bug)} {
+  catch { foreach a 0 b {1 2 3} { error x } }
+  set a
+} 0
+test foreach-11.2 {error then dereference loop var (dev bug)} {
+  catch { foreach a 0 b {1 2 3} { incr a $b; error x } }
+  set a
+} 1
+
+# cleanup
+catch {unset a}
+catch {unset x}
+catch {rename foo {}}
+::tcltest::cleanupTests
+return
diff --git a/tests/format.test b/tests/format.test
new file mode 100644
index 0000000..27eac31
--- /dev/null
+++ b/tests/format.test
@@ -0,0 +1,581 @@
+# Commands covered:  format
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands.  Sourcing this file into Tcl runs the tests and
+# generates output for errors.  No output means no errors were found.
+#
+# Copyright (c) 1991-1994 The Regents of the University of California.
+# Copyright (c) 1994-1998 Sun Microsystems, Inc.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+    package require tcltest 2
+    namespace import -force ::tcltest::*
+}
+
+# %u output depends on word length, so this test is not portable.
+testConstraint longIs32bit [expr {int(0x80000000) < 0}]
+testConstraint longIs64bit [expr {int(0x8000000000000000) < 0}]
+testConstraint wideIs64bit \
+	[expr {(wide(0x80000000) > 0) && (wide(0x8000000000000000) < 0)}]
+testConstraint wideBiggerThanInt [expr {wide(0x80000000) != int(0x80000000)}]
+
+test format-1.1 {integer formatting} {
+    format "%*d %d %d %d" 6 34 16923 -12 -1
+} {    34 16923 -12 -1}
+test format-1.2 {integer formatting} {
+    format "%4d %4d %4d %4d %d %#x %#X" 6 34 16923 -12 -1 14 12
+} {   6   34 16923  -12 -1 0xe 0XC}
+test format-1.3 {integer formatting} longIs32bit {
+    format "%4u %4u %4u %4u %d %#o" 6 34 16923 -12 -1 0
+} {   6   34 16923 4294967284 -1 0}
+test format-1.3.1 {integer formatting} longIs64bit {
+    format "%4u %4u %4u %4u %d %#o" 6 34 16923 -12 -1 0
+} {   6   34 16923 18446744073709551604 -1 0}
+test format-1.4 {integer formatting} {
+    format "%-4d %-4i %-4d %-4ld" 6 34 16923 -12 -1
+} {6    34   16923 -12 }
+test format-1.5 {integer formatting} {
+    format "%04d %04d %04d %04i" 6 34 16923 -12 -1
+} {0006 0034 16923 -012}
+test format-1.6 {integer formatting} {
+    format "%00*d" 6 34
+} {000034}
+# Printing negative numbers in hex or octal format depends on word
+# length, so these tests are not portable.
+test format-1.7 {integer formatting} longIs32bit {
+    format "%4x %4x %4x %4x" 6 34 16923 -12 -1
+} {   6   22 421b fffffff4}
+test format-1.7.1 {integer formatting} longIs64bit {
+    format "%4x %4x %4x %4x" 6 34 16923 -12 -1
+} {   6   22 421b fffffffffffffff4}
+test format-1.8 {integer formatting} longIs32bit {
+    format "%#x %#X %#X %#x" 6 34 16923 -12 -1
+} {0x6 0X22 0X421B 0xfffffff4}
+test format-1.8.1 {integer formatting} longIs64bit {
+    format "%#x %#X %#X %#x" 6 34 16923 -12 -1
+} {0x6 0X22 0X421B 0xfffffffffffffff4}
+test format-1.9 {integer formatting} longIs32bit {
+    format "%#20x %#20x %#20x %#20x" 6 34 16923 -12 -1
+} {                 0x6                 0x22               0x421b           0xfffffff4}
+test format-1.9.1 {integer formatting} longIs64bit {
+    format "%#20x %#20x %#20x %#20x" 6 34 16923 -12 -1
+} {                 0x6                 0x22               0x421b   0xfffffffffffffff4}
+test format-1.10 {integer formatting} longIs32bit {
+    format "%-#20x %-#20x %-#20x %-#20x" 6 34 16923 -12 -1
+} {0x6                  0x22                 0x421b               0xfffffff4          }
+test format-1.10.1 {integer formatting} longIs64bit {
+    format "%-#20x %-#20x %-#20x %-#20x" 6 34 16923 -12 -1
+} {0x6                  0x22                 0x421b               0xfffffffffffffff4  }
+test format-1.11 {integer formatting} longIs32bit {
+    format "%-#20o %#-20o %#-20o %#-20o" 6 34 16923 -12 -1
+} {06                   042                  041033               037777777764        }
+test format-1.11.1 {integer formatting} longIs64bit {
+    format "%-#20o %#-20o %#-20o %#-20o" 6 34 16923 -12 -1
+} {06                   042                  041033               01777777777777777777764}
+test format-1.12 {integer formatting} {
+    format "%b %#b %llb" 5 5 [expr {2**100}]
+} {101 0b101 10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000}
+
+test format-2.1 {string formatting} {
+    format "%s %s %c %s" abcd {This is a very long test string.} 120 x
+} {abcd This is a very long test string. x x}
+test format-2.2 {string formatting} {
+    format "%20s %20s %20c %20s" abcd {This is a very long test string.} 120 x
+} {                abcd This is a very long test string.                    x                    x}
+test format-2.3 {string formatting} {
+    format "%.10s %.10s %c %.10s" abcd {This is a very long test string.} 120 x
+} {abcd This is a  x x}
+test format-2.4 {string formatting} {
+    format "%s %s %% %c %s" abcd {This is a very long test string.} 120 x
+} {abcd This is a very long test string. % x x}
+test format-2.5 {string formatting, embedded nulls} {
+    format "%10s" abc\0def
+} "   abc\0def"
+test format-2.6 {string formatting, international chars} {
+    format "%10s" abc\ufeffdef
+} "   abc\ufeffdef"
+test format-2.7 {string formatting, international chars} {
+    format "%.5s" abc\ufeffdef
+} "abc\ufeffd"
+test format-2.8 {string formatting, international chars} {
+    format "foo\ufeffbar%s" baz
+} "foo\ufeffbarbaz"
+test format-2.9 {string formatting, width} {
+    format "a%5sa" f
+} "a    fa"
+test format-2.10 {string formatting, width} {
+    format "a%-5sa" f
+} "af    a"
+test format-2.11 {string formatting, width} {
+    format "a%2sa" foo
+} "afooa"
+test format-2.12 {string formatting, width} {
+    format "a%0sa" foo
+} "afooa"
+test format-2.13 {string formatting, precision} {
+    format "a%.2sa" foobarbaz
+} "afoa"
+test format-2.14 {string formatting, precision} {
+    format "a%.sa" foobarbaz
+} "aa"
+test format-2.15 {string formatting, precision} {
+    list [catch {format "a%.-2sa" foobarbaz} msg] $msg
+} {1 {bad field specifier "-"}}
+test format-2.16 {string formatting, width and precision} {
+    format "a%5.2sa" foobarbaz
+} "a   foa"
+test format-2.17 {string formatting, width and precision} {
+    format "a%5.7sa" foobarbaz
+} "afoobarba"
+
+test format-3.1 {Tcl_FormatObjCmd: character formatting} {
+    format "|%c|%0c|%-1c|%1c|%-6c|%6c|%*c|%*c|" 65 65 65 65 65 65 3 65 -4 65
+} "|A|A|A|A|A     |     A|  A|A   |"
+test format-3.2 {Tcl_FormatObjCmd: international character formatting} {
+    format "|%c|%0c|%-1c|%1c|%-6c|%6c|%*c|%*c|" 0xa2 0x4e4e 0x25a 0xc3 0xff08 0 3 0x6575 -4 0x4e4f
+} "|\ua2|\u4e4e|\u25a|\uc3|\uff08     |     \0|  \u6575|\u4e4f   |"
+
+test format-4.1 {e and f formats} {eformat} {
+    format "%e %e %e %e" 34.2e12 68.514 -.125 -16000. .000053
+} {3.420000e+13 6.851400e+01 -1.250000e-01 -1.600000e+04}
+test format-4.2 {e and f formats} {eformat} {
+    format "%20e %20e %20e %20e" 34.2e12 68.514 -.125 -16000. .000053
+} {        3.420000e+13         6.851400e+01        -1.250000e-01        -1.600000e+04}
+test format-4.3 {e and f formats} {eformat} {
+    format "%.1e %.1e %.1e %.1e" 34.2e12 68.514 -.126 -16000. .000053
+} {3.4e+13 6.9e+01 -1.3e-01 -1.6e+04}
+test format-4.4 {e and f formats} {eformat} {
+    format "%020e %020e %020e %020e" 34.2e12 68.514 -.126 -16000. .000053
+} {000000003.420000e+13 000000006.851400e+01 -00000001.260000e-01 -00000001.600000e+04}
+test format-4.5 {e and f formats} {eformat} {
+    format "%7.1e %7.1e %7.1e %7.1e" 34.2e12 68.514 -.126 -16000. .000053
+} {3.4e+13 6.9e+01 -1.3e-01 -1.6e+04}
+test format-4.6 {e and f formats} {
+    format "%f %f %f %f" 34.2e12 68.514 -.125 -16000. .000053
+} {34200000000000.000000 68.514000 -0.125000 -16000.000000}
+test format-4.7 {e and f formats} {
+    format "%.4f %.4f %.4f %.4f %.4f" 34.2e12 68.514 -.125 -16000. .000053
+} {34200000000000.0000 68.5140 -0.1250 -16000.0000 0.0001}
+test format-4.8 {e and f formats} {eformat} {
+    format "%.4e %.5e %.6e" -9.99996 -9.99996 9.99996
+} {-1.0000e+01 -9.99996e+00 9.999960e+00}
+test format-4.9 {e and f formats} {
+    format "%.4f %.5f %.6f" -9.99996 -9.99996 9.99996
+} {-10.0000 -9.99996 9.999960}
+test format-4.10 {e and f formats} {
+    format "%20f %-20f %020f" -9.99996 -9.99996 9.99996
+} {           -9.999960 -9.999960            0000000000009.999960}
+test format-4.11 {e and f formats} {
+    format "%-020f %020f" -9.99996 -9.99996 9.99996
+} {-9.999960            -000000000009.999960}
+test format-4.12 {e and f formats} {eformat} {
+    format "%.0e %#.0e" -9.99996 -9.99996 9.99996
+} {-1e+01 -1.e+01}
+test format-4.13 {e and f formats} {
+    format "%.0f %#.0f" -9.99996 -9.99996 9.99996
+} {-10 -10.}
+test format-4.14 {e and f formats} {
+    format "%.4f %.5f %.6f" -9.99996 -9.99996 9.99996
+} {-10.0000 -9.99996 9.999960}
+test format-4.15 {e and f formats} {
+    format "%3.0f %3.0f %3.0f %3.0f" 1.0 1.1 1.01 1.001
+} {  1   1   1   1}
+test format-4.16 {e and f formats} {
+    format "%3.1f %3.1f %3.1f %3.1f" 0.0 0.1 0.01 0.001
+} {0.0 0.1 0.0 0.0}
+
+test format-5.1 {g-format} {eformat} {
+    format "%.3g" 12341.0
+} {1.23e+04}
+test format-5.2 {g-format} {eformat} {
+    format "%.3G" 1234.12345
+} {1.23E+03}
+test format-5.3 {g-format} {
+    format "%.3g" 123.412345
+} {123}
+test format-5.4 {g-format} {
+    format "%.3g" 12.3412345
+} {12.3}
+test format-5.5 {g-format} {
+    format "%.3g" 1.23412345
+} {1.23}
+test format-5.6 {g-format} {
+    format "%.3g" 1.23412345
+} {1.23}
+test format-5.7 {g-format} {
+    format "%.3g" .123412345
+} {0.123}
+test format-5.8 {g-format} {
+    format "%.3g" .012341
+} {0.0123}
+test format-5.9 {g-format} {
+    format "%.3g" .0012341
+} {0.00123}
+test format-5.10 {g-format} {
+    format "%.3g" .00012341
+} {0.000123}
+test format-5.11 {g-format} {eformat} {
+    format "%.3g" .00001234
+} {1.23e-05}
+test format-5.12 {g-format} {eformat} {
+    format "%.4g" 9999.6
+} {1e+04}
+test format-5.13 {g-format} {
+    format "%.4g" 999.96
+} {1000}
+test format-5.14 {g-format} {
+    format "%.3g" 1.0
+} {1}
+test format-5.15 {g-format} {
+    format "%.3g" .1
+} {0.1}
+test format-5.16 {g-format} {
+    format "%.3g" .01
+} {0.01}
+test format-5.17 {g-format} {
+    format "%.3g" .001
+} {0.001}
+test format-5.18 {g-format} {eformat} {
+    format "%.3g" .00001
+} {1e-05}
+test format-5.19 {g-format} {eformat} {
+    format "%#.3g" 1234.0
+} {1.23e+03}
+test format-5.20 {g-format} {eformat} {
+    format "%#.3G" 9999.5
+} {1.00E+04}
+
+test format-6.1 {floating-point zeroes} {eformat} {
+    format "%e %f %g" 0.0 0.0 0.0 0.0
+} {0.000000e+00 0.000000 0}
+test format-6.2 {floating-point zeroes} {eformat} {
+    format "%.4e %.4f %.4g" 0.0 0.0 0.0 0.0
+} {0.0000e+00 0.0000 0}
+test format-6.3 {floating-point zeroes} {eformat} {
+    format "%#.4e %#.4f %#.4g" 0.0 0.0 0.0 0.0
+} {0.0000e+00 0.0000 0.000}
+test format-6.4 {floating-point zeroes} {eformat} {
+    format "%.0e %.0f %.0g" 0.0 0.0 0.0 0.0
+} {0e+00 0 0}
+test format-6.5 {floating-point zeroes} {eformat} {
+    format "%#.0e %#.0f %#.0g" 0.0 0.0 0.0 0.0
+} {0.e+00 0. 0.}
+test format-6.6 {floating-point zeroes} {
+    format "%3.0f %3.0f %3.0f %3.0f" 0.0 0.0 0.0 0.0
+} {  0   0   0   0}
+test format-6.7 {floating-point zeroes} {
+    format "%3.0f %3.0f %3.0f %3.0f" 1.0 1.1 1.01 1.001
+} {  1   1   1   1}
+test format-6.8 {floating-point zeroes} {
+    format "%3.1f %3.1f %3.1f %3.1f" 0.0 0.1 0.01 0.001
+} {0.0 0.1 0.0 0.0}
+
+test format-7.1 {various syntax features} {
+    format "%*.*f" 12 3 12.345678901
+} {      12.346}
+test format-7.2 {various syntax features} {
+    format "%0*.*f" 12 3 12.345678901
+} {00000012.346}
+test format-7.3 {various syntax features} {
+    format "\*\t\\n"
+} {*	\n}
+
+test format-8.1 {error conditions} {
+    catch format
+} 1
+test format-8.2 {error conditions} {
+    catch format msg
+    set msg
+} {wrong # args: should be "format formatString ?arg ...?"}
+test format-8.3 {error conditions} {
+    catch {format %*d}
+} 1
+test format-8.4 {error conditions} {
+    catch {format %*d} msg
+    set msg
+} {not enough arguments for all format specifiers}
+test format-8.5 {error conditions} {
+    catch {format %*.*f 12}
+} 1
+test format-8.6 {error conditions} {
+    catch {format %*.*f 12} msg
+    set msg
+} {not enough arguments for all format specifiers}
+test format-8.7 {error conditions} {
+    catch {format %*.*f 12 3}
+} 1
+test format-8.8 {error conditions} {
+    catch {format %*.*f 12 3} msg
+    set msg
+} {not enough arguments for all format specifiers}
+test format-8.9 {error conditions} {
+    list [catch {format %*d x 3} msg] $msg
+} {1 {expected integer but got "x"}}
+test format-8.10 {error conditions} {
+    list [catch {format %*.*f 2 xyz 3} msg] $msg
+} {1 {expected integer but got "xyz"}}
+test format-8.11 {error conditions} {
+    catch {format %d 2a}
+} 1
+test format-8.12 {error conditions} {
+    catch {format %d 2a} msg
+    set msg
+} {expected integer but got "2a"}
+test format-8.13 {error conditions} {
+    catch {format %c 2x}
+} 1
+test format-8.14 {error conditions} {
+    catch {format %c 2x} msg
+    set msg
+} {expected integer but got "2x"}
+test format-8.15 {error conditions} {
+    catch {format %f 2.1z}
+} 1
+test format-8.16 {error conditions} {
+    catch {format %f 2.1z} msg
+    set msg
+} {expected floating-point number but got "2.1z"}
+test format-8.17 {error conditions} {
+    catch {format ab%}
+} 1
+test format-8.18 {error conditions} {
+    catch {format ab% 12} msg
+    set msg
+} {format string ended in middle of field specifier}
+test format-8.19 {error conditions} {
+    catch {format %q x}
+} 1
+test format-8.20 {error conditions} {
+    catch {format %q x} msg
+    set msg
+} {bad field specifier "q"}
+test format-8.21 {error conditions} {
+    catch {format %d}
+} 1
+test format-8.22 {error conditions} {
+    catch {format %d} msg
+    set msg
+} {not enough arguments for all format specifiers}
+test format-8.23 {error conditions} {
+    catch {format "%d %d" 24 xyz} msg
+    set msg
+} {expected integer but got "xyz"}
+
+test format-9.1 {long result} {
+    set a {1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ 1 2 3 4 5 6 7 8 9 0 a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z}
+    format {1111 2222 3333 4444 5555 6666 7777 8888 9999 aaaa bbbb cccc dddd eeee ffff gggg hhhh iiii jjjj kkkk llll mmmm nnnn oooo pppp qqqq rrrr ssss tttt uuuu vvvv wwww xxxx yyyy zzzz AAAA BBBB CCCC DDDD EEEE FFFF GGGG %s %s} $a $a
+} {1111 2222 3333 4444 5555 6666 7777 8888 9999 aaaa bbbb cccc dddd eeee ffff gggg hhhh iiii jjjj kkkk llll mmmm nnnn oooo pppp qqqq rrrr ssss tttt uuuu vvvv wwww xxxx yyyy zzzz AAAA BBBB CCCC DDDD EEEE FFFF GGGG 1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ 1 2 3 4 5 6 7 8 9 0 a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ 1 2 3 4 5 6 7 8 9 0 a b c d e f g h i j k l m n o p q r s t u v w x y z A B C D E F G H I J K L M N O P Q R S T U V W X Y Z}
+
+test format-10.1 {"h" format specifier} {
+    format %hd 0xffff
+} -1
+test format-10.2 {"h" format specifier} {
+    format %hx 0x10fff
+} fff
+test format-10.3 {"h" format specifier} {
+    format %hd 0x10000
+} 0
+test format-10.4 {"h" format specifier} {
+    # Bug 1154163: This is minimal behaviour for %hx specifier!
+    format %hx 1
+} 1
+test format-10.5 {"h" format specifier} {
+    # Bug 1284178: Highly out-of-range values shouldn't cause errors
+    format %hu 0x100000000
+} 0
+
+test format-11.1 {XPG3 %$n specifiers} {
+    format {%2$d %1$d} 4 5
+} {5 4}
+test format-11.2 {XPG3 %$n specifiers} {
+    format {%2$d %1$d %1$d %3$d} 4 5 6
+} {5 4 4 6}
+test format-11.3 {XPG3 %$n specifiers} {
+    list [catch {format {%2$d %3$d} 4 5} msg] $msg
+} {1 {"%n$" argument index out of range}}
+test format-11.4 {XPG3 %$n specifiers} {
+    list [catch {format {%2$d %0$d} 4 5 6} msg] $msg
+} {1 {"%n$" argument index out of range}}
+test format-11.5 {XPG3 %$n specifiers} {
+    list [catch {format {%d %1$d} 4 5 6} msg] $msg
+} {1 {cannot mix "%" and "%n$" conversion specifiers}}
+test format-11.6 {XPG3 %$n specifiers} {
+    list [catch {format {%2$d %d} 4 5 6} msg] $msg
+} {1 {cannot mix "%" and "%n$" conversion specifiers}}
+test format-11.7 {XPG3 %$n specifiers} {
+    list [catch {format {%2$d %3d} 4 5 6} msg] $msg
+} {1 {cannot mix "%" and "%n$" conversion specifiers}}
+test format-11.8 {XPG3 %$n specifiers} {
+    format {%2$*d %3$d} 1 10 4
+} {         4 4}
+test format-11.9 {XPG3 %$n specifiers} {
+    format {%2$.*s %4$d} 1 5 abcdefghijklmnop 44
+} {abcde 44}
+test format-11.10 {XPG3 %$n specifiers} {
+    list [catch {format {%2$*d} 4} msg] $msg
+} {1 {"%n$" argument index out of range}}
+test format-11.11 {XPG3 %$n specifiers} {
+    list [catch {format {%2$*d} 4 5} msg] $msg
+} {1 {"%n$" argument index out of range}}
+test format-11.12 {XPG3 %$n specifiers} {
+    list [catch {format {%2$*d} 4 5 6} msg] $msg
+} {0 {    6}}
+
+test format-12.1 {negative width specifiers} {
+    format "%*d" -47 25
+} {25                                             }
+
+test format-13.1 {tcl_precision fuzzy comparison} {
+    catch {unset a}
+    catch {unset b}
+    catch {unset c}
+    catch {unset d}
+    set a 0.0000000000001
+    set b 0.00000000000001
+    set c 0.00000000000000001
+    set d [expr $a + $b + $c]
+    format {%0.10f %0.12f %0.15f %0.17f} $d $d $d $d
+} {0.0000000000 0.000000000000 0.000000000000110 0.00000000000011001}
+test format-13.2 {tcl_precision fuzzy comparison} {
+    catch {unset a}
+    catch {unset b}
+    catch {unset c}
+    catch {unset d}
+    set a 0.000000000001
+    set b 0.000000000000005
+    set c 0.0000000000000008
+    set d [expr $a + $b + $c]
+    format {%0.10f %0.12f %0.15f %0.17f} $d $d $d $d
+} {0.0000000000 0.000000000001 0.000000000001006 0.00000000000100580}
+test format-13.3 {tcl_precision fuzzy comparison} {
+    catch {unset a}
+    catch {unset b}
+    catch {unset c}
+    set a 0.00000000000099
+    set b 0.000000000000011
+    set c [expr $a + $b]
+    format {%0.10f %0.12f %0.15f %0.17f} $c $c $c $c
+} {0.0000000000 0.000000000001 0.000000000001001 0.00000000000100100}
+test format-13.4 {tcl_precision fuzzy comparison} {
+    catch {unset a}
+    catch {unset b}
+    catch {unset c}
+    set a 0.444444444444
+    set b 0.33333333333333
+    set c [expr $a + $b]
+    format {%0.10f %0.12f %0.15f %0.16f} $c $c $c $c
+} {0.7777777778 0.777777777777 0.777777777777330 0.7777777777773300}
+test format-13.5 {tcl_precision fuzzy comparison} {
+    catch {unset a}
+    catch {unset b}
+    catch {unset c}
+    set a 0.444444444444
+    set b 0.99999999999999
+    set c [expr $a + $b]
+    format {%0.10f %0.12f %0.15f} $c $c $c
+} {1.4444444444 1.444444444444 1.444444444443990}
+
+test format-14.1 {testing MAX_FLOAT_SIZE for 0 and 1} {
+    format {%s} ""
+} {}
+test format-14.2 {testing MAX_FLOAT_SIZE for 0 and 1} {
+    format {%s} "a"
+} {a}
+
+test format-15.1 {testing %0..s 0 padding for chars/strings} {
+    format %05s a
+} {0000a}
+test format-15.2 {testing %0..s 0 padding for chars/strings} {
+    format "% 5s" a
+} {    a}
+test format-15.3 {testing %0..s 0 padding for chars/strings} {
+    format %5s a
+} {    a}
+test format-15.4 {testing %0..s 0 padding for chars/strings} {
+    format %05c 61
+} {0000=}
+test format-15.5 {testing %d space padding for integers} {
+    format "(% 1d) (% 1d)" 10 -10
+} {( 10) (-10)}
+test format-15.6 {testing %d plus padding for integers} {
+    format "(%+1d) (%+1d)" 10 -10
+} {(+10) (-10)}
+
+set a "0123456789"
+set b ""
+for {set i 0} {$i < 290} {incr i} {
+    append b $a
+}
+for {set i 290} {$i < 400} {incr i} {
+    test format-16.[expr $i -289] {testing MAX_FLOAT_SIZE} {
+        format {%s} $b
+    } $b
+    append b "x"
+}
+
+test format-17.1 {testing %d with wide} {wideIs64bit wideBiggerThanInt} {
+    format %d 7810179016327718216
+} 1819043144
+test format-17.2 {testing %ld with wide} {wideIs64bit} {
+    format %ld 7810179016327718216
+} 7810179016327718216
+test format-17.3 {testing %ld with non-wide} {wideIs64bit} {
+    format %ld 42
+} 42
+test format-17.4 {testing %l with non-integer} {
+    format %lf 1
+} 1.000000
+
+test format-18.1 {do not demote existing numeric values} {
+    set a 0xaaaaaaaa
+    # Ensure $a and $b are separate objects
+    set b 0xaaaa
+    append b aaaa
+    set result [expr {$a == $b}]
+    format %08lx $b
+    lappend result [expr {$a == $b}]
+    set b 0xaaaa
+    append b aaaa
+    lappend result [expr {$a == $b}]
+    format %08x $b
+    lappend result [expr {$a == $b}]
+} {1 1 1 1}
+test format-18.2 {do not demote existing numeric values} {wideBiggerThanInt} {
+    set a [expr {0xaaaaaaaaaa + 1}]
+    set b 0xaaaaaaaaab
+    list [format %08x $a] [expr {$a == $b}]
+} {aaaaaaab 1}
+
+test format-19.1 {regression test - tcl-core message by Brian Griffin on 26 0ctober 2004} -body {
+    set x 0x8fedc654
+    list [expr { ~ $x }] [format %08x [expr { ~$x }]]
+} -match regexp -result {-2414724693 f*701239ab}
+test format-19.2 {Bug 1867855} {
+    format %llx 0
+} 0
+test format-19.3 {Bug 2830354} {
+    string length [format %340f 0]
+} 340
+
+# Note that this test may fail in future versions
+test format-20.1 {Bug 2932421: plain %s caused intrep change of args} -body {
+    set x [dict create a b c d]
+    format %s $x
+    # After this, obj in $x should be a dict with a non-NULL bytes field
+    tcl::unsupported::representation $x
+} -match glob -result {value is a dict with *, string representation "*"}
+
+# cleanup
+catch {unset a}
+catch {unset b}
+catch {unset c}
+catch {unset d}
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/tests/get.test b/tests/get.test
new file mode 100644
index 0000000..d51ec6d
--- /dev/null
+++ b/tests/get.test
@@ -0,0 +1,101 @@
+# Commands covered:  none
+#
+# This file contains a collection of tests for the procedures in the
+# file tclGet.c.  Sourcing this file into Tcl runs the tests and
+# generates output for errors.  No output means no errors were found.
+#
+# Copyright (c) 1995-1996 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+    package require tcltest
+    namespace import -force ::tcltest::*
+}
+
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
+
+testConstraint testgetint [llength [info commands testgetint]]
+testConstraint longIs32bit [expr {int(0x80000000) < 0}]
+testConstraint longIs64bit [expr {int(0x8000000000000000) < 0}]
+
+test get-1.1 {Tcl_GetInt procedure} testgetint {
+    testgetint 44 { 	  22}
+} {66}
+test get-1.2 {Tcl_GetInt procedure} testgetint {
+    testgetint 44 -3
+} {41}
+test get-1.3 {Tcl_GetInt procedure} testgetint {
+    testgetint 44 +8
+} {52}
+test get-1.4 {Tcl_GetInt procedure} testgetint {
+    list [catch {testgetint 44 foo} msg] $msg
+} {1 {expected integer but got "foo"}}
+test get-1.5 {Tcl_GetInt procedure} testgetint {
+    list [catch {testgetint 44 {16	 }} msg] $msg
+} {0 60}
+test get-1.6 {Tcl_GetInt procedure} testgetint {
+    list [catch {testgetint 44 {16	 x}} msg] $msg
+} {1 {expected integer but got "16	 x"}}
+test get-1.7 {Tcl_GetInt procedure} {testgetint longIs64bit} {
+    list [catch {testgetint 44 18446744073709551616} msg] $msg $errorCode
+} {1 {integer value too large to represent} {ARITH IOVERFLOW {integer value too large to represent}}}
+test get-1.8 {Tcl_GetInt procedure} {testgetint longIs64bit} {
+    list [catch {testgetint 18446744073709551614} msg] $msg
+} {0 -2}
+test get-1.9 {Tcl_GetInt procedure} {testgetint longIs64bit} {
+    list [catch {testgetint +18446744073709551614} msg] $msg
+} {0 -2}
+test get-1.10 {Tcl_GetInt procedure} {testgetint longIs64bit} {
+    list [catch {testgetint -18446744073709551614} msg] $msg
+} {0 2}
+test get-1.11 {Tcl_GetInt procedure} {testgetint longIs32bit} {
+    list [catch {testgetint 44 4294967296} msg] $msg $errorCode
+} {1 {integer value too large to represent} {ARITH IOVERFLOW {integer value too large to represent}}}
+test get-1.12 {Tcl_GetInt procedure} {testgetint longIs32bit} {
+    list [catch {testgetint 4294967294} msg] $msg
+} {0 -2}
+test get-1.13 {Tcl_GetInt procedure} {testgetint longIs32bit} {
+    list [catch {testgetint +4294967294} msg] $msg
+} {0 -2}
+test get-1.14 {Tcl_GetInt procedure} {testgetint longIs32bit} {
+    list [catch {testgetint -4294967294} msg] $msg
+} {0 2}
+
+test get-2.1 {Tcl_GetInt procedure} {
+    format %g 1.23
+} {1.23}
+test get-2.2 {Tcl_GetInt procedure} {
+    format %g { 	 1.23 	}
+} {1.23}
+test get-2.3 {Tcl_GetInt procedure} {
+    list [catch {format %g clip} msg] $msg
+} {1 {expected floating-point number but got "clip"}}
+test get-2.4 {Tcl_GetInt procedure} {
+    format %g .000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001
+} 0
+
+test get-3.1 {Tcl_GetInt(FromObj), bad numbers} {
+    # SF bug #634856
+    set result ""
+    set numbers [list 1 +1 ++1 +-1 -+1 -1 --1 "- +1" "+12345678987654321" "++12345678987654321"]
+    foreach num $numbers {
+	lappend result [catch {format %ld $num} msg] $msg
+    }
+    set result
+} {0 1 0 1 1 {expected integer but got "++1"} 1 {expected integer but got "+-1"} 1 {expected integer but got "-+1"} 0 -1 1 {expected integer but got "--1"} 1 {expected integer but got "- +1"} 0 12345678987654321 1 {expected integer but got "++12345678987654321"}}
+test get-3.2 {Tcl_GetDouble(FromObj), bad numbers} {
+    set result ""
+    set numbers [list 1.0 +1.0 ++1.0 +-1.0 -+1.0 -1.0 --1.0 "- +1.0"]
+    foreach num $numbers {
+	lappend result [catch {format %g $num} msg] $msg
+    }
+    set result
+} {0 1 0 1 1 {expected floating-point number but got "++1.0"} 1 {expected floating-point number but got "+-1.0"} 1 {expected floating-point number but got "-+1.0"} 0 -1 1 {expected floating-point number but got "--1.0"} 1 {expected floating-point number but got "- +1.0"}}
+
+# cleanup
+::tcltest::cleanupTests
+return
diff --git a/tests/history.test b/tests/history.test
new file mode 100644
index 0000000..7549beb
--- /dev/null
+++ b/tests/history.test
@@ -0,0 +1,255 @@
+# Commands covered:  history
+#
+# This file contains a collection of tests for one or more of the Tcl built-in
+# commands.  Sourcing this file into Tcl runs the tests and generates output
+# for errors.  No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution of
+# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+  
+if {[lsearch [namespace children] ::tcltest] == -1} {
+    package require tcltest
+    namespace import -force ::tcltest::*
+}
+
+# The history command might be autoloaded...
+if {[catch {history}]} {
+    testConstraint history 0
+} else {
+    testConstraint history 1
+}
+
+if {[testConstraint history]} {
+    set num [history nextid]
+    history keep 3
+    history add {set a 12345}
+    history add {set b [format {A test %s} string]}
+    history add {Another test}
+} else {
+    # Dummy value, must be numeric
+    set num 0
+}
+
+# "history event"
+
+test history-1.1 {event option} history {history event -1} \
+	{set b [format {A test %s} string]}
+test history-1.2 {event option} history {history event $num} \
+	{set a 12345}
+test history-1.3 {event option} history {history event [expr $num+2]} \
+	{Another test}
+test history-1.4 {event option} history {history event set} \
+	{set b [format {A test %s} string]}
+test history-1.5 {event option} history {history e "* a*"} \
+	{set a 12345}
+test history-1.6 {event option} history {catch {history event *gorp} msg} 1
+test history-1.7 {event option} history {
+    catch {history event *gorp} msg
+    set msg
+} {no event matches "*gorp"}
+test history-1.8 {event option} history {history event} \
+	{set b [format {A test %s} string]}
+test history-1.9 {event option} history {catch {history event 123 456} msg} 1
+test history-1.10 {event option} history {
+    catch {history event 123 456} msg
+    set msg
+} {wrong # args: should be "history event ?event?"}
+
+# "history redo"
+
+if {[testConstraint history]} {
+    set a 0
+    history redo -2
+}
+test history-2.1 {redo option} history {set a} 12345
+if {[testConstraint history]} {
+    set b 0
+    history redo
+}
+test history-2.2 {redo option} history {set b} {A test string}
+test history-2.3 {redo option} history {catch {history redo -3 -4}} 1
+test history-2.4 {redo option} history {
+    catch {history redo -3 -4} msg
+    set msg
+} {wrong # args: should be "history redo ?event?"}
+
+# "history add"
+
+if {[testConstraint history]} {
+    history add "set a 444" exec
+}
+test history-3.1 {add option} history {set a} 444
+test history-3.2 {add option} history {catch {history add "set a 444" execGorp}} 1
+test history-3.3 {add option} history {
+    catch {history add "set a 444" execGorp} msg
+    set msg
+} {bad argument "execGorp": should be "exec"}
+test history-3.4 {add option} history {catch {history add "set a 444" a} msg} 1
+test history-3.5 {add option} history {
+    catch {history add "set a 444" a} msg
+    set msg
+} {bad argument "a": should be "exec"}
+if {[testConstraint history]} {
+    history add "set a 555" e
+}
+test history-3.6 {add option} history {set a} 555
+if {[testConstraint history]} {
+    history add "set a 666"
+}
+test history-3.7 {add option} history {set a} 555
+test history-3.8 {add option} history {catch {history add "set a 666" e f} msg} 1
+test history-3.9 {add option} history {
+    catch {history add "set a 666" e f} msg
+    set msg
+} {wrong # args: should be "history add event ?exec?"}
+
+# "history change"
+
+if {[testConstraint history]} {
+    history change "A test value"
+}
+test history-4.1 {change option} history {history event [expr {[history n]-1}]} \
+	"A test value"
+if {[testConstraint history]} {
+    history ch "Another test" -1
+}
+test history-4.2 {change option} history {history e} "Another test"
+test history-4.3 {change option} history {history event [expr {[history n]-1}]} \
+	"A test value"
+test history-4.4 {change option} history {catch {history change Foo 4 10}} 1
+test history-4.5 {change option} history {
+    catch {history change Foo 4 10} msg
+    set msg
+} {wrong # args: should be "history change newValue ?event?"}
+test history-4.6 {change option} history {
+    catch {history change Foo [expr {[history n]-4}]}
+} 1
+if {[testConstraint history]} {
+    set num [expr {[history n]-4}]
+}
+test history-4.7 {change option} history {
+    catch {history change Foo $num} msg
+    set msg
+} "event \"$num\" is too far in the past"
+
+# "history info"
+
+if {[testConstraint history]} {
+    set num [history n]
+    history add set\ a\ {b\nc\ d\ e}
+    history add {set b 1234}
+    history add set\ c\ {a\nb\nc}
+}
+test history-5.1 {info option} history {history info} [format {%6d  set a {b
+	c d e}
+%6d  set b 1234
+%6d  set c {a
+	b
+	c}} $num [expr $num+1] [expr $num+2]]
+test history-5.2 {info option} history {history i 2} [format {%6d  set b 1234
+%6d  set c {a
+	b
+	c}} [expr $num+1] [expr $num+2]]
+test history-5.3 {info option} history {catch {history i 2 3}} 1
+test history-5.4 {info option} history {
+    catch {history i 2 3} msg
+    set msg
+} {wrong # args: should be "history info ?count?"}
+test history-5.5 {info option} history {history} [format {%6d  set a {b
+	c d e}
+%6d  set b 1234
+%6d  set c {a
+	b
+	c}} $num [expr $num+1] [expr $num+2]]
+
+# "history keep"
+
+if {[testConstraint history]} {
+    history add "foo1"
+    history add "foo2"
+    history add "foo3"
+    history keep 2
+}
+test history-6.1 {keep option} history {history event [expr [history n]-1]} foo3
+test history-6.2 {keep option} history {history event -1} foo2
+test history-6.3 {keep option} history {catch {history event -3}} 1
+test history-6.4 {keep option} history {
+    catch {history event -3} msg
+    set msg
+} {event "-3" is too far in the past}
+if {[testConstraint history]} {
+    history k 5
+}
+test history-6.5 {keep option} history {history event -1} foo2
+test history-6.6 {keep option} history {history event -2} {}
+test history-6.7 {keep option} history {history event -3} {}
+test history-6.8 {keep option} history {history event -4} {}
+test history-6.9 {keep option} history {catch {history event -5}} 1
+test history-6.10 {keep option} history {catch {history keep 4 6}} 1
+test history-6.11 {keep option} history {
+    catch {history keep 4 6} msg
+    set msg
+} {wrong # args: should be "history keep ?count?"}
+test history-6.12 {keep option} history {catch {history keep}} 0
+test history-6.13 {keep option} history {
+    history keep
+} {5}
+test history-6.14 {keep option} history {catch {history keep -3}} 1
+test history-6.15 {keep option} history {
+    catch {history keep -3} msg
+    set msg
+} {illegal keep count "-3"}
+test history-6.16 {keep option} history {
+    catch {history keep butter} msg
+    set msg
+} {illegal keep count "butter"}
+
+# "history nextid"
+
+if {[testConstraint history]} {
+    set num [history n]
+    history add "Testing"
+    history add "Testing2"
+}
+test history-7.1 {nextid option} history {history event} "Testing"
+test history-7.2 {nextid option} history {history next} [expr $num+2]
+test history-7.3 {nextid option} history {catch {history nextid garbage}} 1
+test history-7.4 {nextid option} history {
+    catch {history nextid garbage} msg
+    set msg
+} {wrong # args: should be "history nextid"}
+
+# "history clear"
+
+if {[testConstraint history]} {
+    set num [history n]
+    history add "Testing"
+    history add "Testing2"
+}
+test history-8.1 {clear option} history {catch {history clear junk}} 1
+test history-8.2 {clear option} history {history clear} {}
+if {[testConstraint history]} {
+    history clear
+    history add "Testing"
+}
+test history-8.3 {clear option} history {history} {     1  Testing}
+
+# miscellaneous
+
+test history-9.1 {miscellaneous} history {catch {history gorp} msg} 1
+test history-9.2 {miscellaneous} history {
+    catch {history gorp} msg
+    set msg
+} {unknown or ambiguous subcommand "gorp": must be add, change, clear, event, info, keep, nextid, or redo}
+
+# cleanup
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/tests/http.test b/tests/http.test
new file mode 100644
index 0000000..41820cb
--- /dev/null
+++ b/tests/http.test
@@ -0,0 +1,668 @@
+# Commands covered:  http::config, http::geturl, http::wait, http::reset
+#
+# This file contains a collection of tests for the http script library.
+# Sourcing this file into Tcl runs the tests and generates output for errors.
+# No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994-1996 Sun Microsystems, Inc.
+# Copyright (c) 1998-2000 by Ajuba Solutions.
+#
+# See the file "license.terms" for information on usage and redistribution of
+# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+package require tcltest 2
+namespace import -force ::tcltest::*
+
+if {[catch {package require http 2} version]} {
+    if {[info exists http2]} {
+	catch {puts "Cannot load http 2.* package"}
+	return
+    } else {
+	catch {puts "Running http 2.* tests in slave interp"}
+	set interp [interp create http2]
+	$interp eval [list set http2 "running"]
+	$interp eval [list set argv $argv]
+	$interp eval [list source [info script]]
+	interp delete $interp
+	return
+    }
+}
+
+proc bgerror {args} {
+    global errorInfo
+    puts stderr "http.test bgerror"
+    puts stderr [join $args]
+    puts stderr $errorInfo
+}
+
+set port 8010
+set bindata "This is binary data\x0d\x0amore\x0dmore\x0amore\x00null"
+catch {unset data}
+
+# Ensure httpd file exists
+
+set origFile [file join [pwd] [file dirname [info script]] httpd]
+set httpdFile [file join [temporaryDirectory] httpd_[pid]]
+if {![file exists $httpdFile]} {
+    makeFile "" $httpdFile
+    file delete $httpdFile
+    file copy $origFile $httpdFile
+    set removeHttpd 1
+}
+
+catch {package require Thread 2.7-}
+if {[catch {package present Thread}] == 0 && [file exists $httpdFile]} {
+    set httpthread [thread::create -preserved]
+    thread::send $httpthread [list source $httpdFile]
+    thread::send $httpthread [list set port $port]
+    thread::send $httpthread [list set bindata $bindata]
+    thread::send $httpthread {httpd_init $port}
+    puts "Running httpd in thread $httpthread"
+} else {
+    if {![file exists $httpdFile]} {
+	puts "Cannot read $httpdFile script, http test skipped"
+	unset port
+	return
+    }
+    source $httpdFile
+    # Let the OS pick the port; that's much more flexible
+    if {[catch {httpd_init 0} listen]} {
+	puts "Cannot start http server, http test skipped"
+	unset port
+	return
+    } else {
+	set port [lindex [fconfigure $listen -sockname] 2]
+    }
+}
+
+test http-1.1 {http::config} {
+    http::config -useragent UserAgent
+    http::config
+} [list -accept */* -proxyfilter http::ProxyRequired -proxyhost {} -proxyport {} -urlencoding utf-8 -useragent "UserAgent"]
+test http-1.2 {http::config} {
+    http::config -proxyfilter
+} http::ProxyRequired
+test http-1.3 {http::config} {
+    catch {http::config -junk}
+} 1
+test http-1.4 {http::config} {
+    set savedconf [http::config]
+    http::config -proxyhost nowhere.come -proxyport 8080 \
+	-proxyfilter myFilter -useragent "Tcl Test Suite" \
+	-urlencoding iso8859-1
+    set x [http::config]
+    http::config {*}$savedconf
+    set x
+} {-accept */* -proxyfilter myFilter -proxyhost nowhere.come -proxyport 8080 -urlencoding iso8859-1 -useragent {Tcl Test Suite}}
+test http-1.5 {http::config} -returnCodes error -body {
+    http::config -proxyhost {} -junk 8080
+} -result {Unknown option -junk, must be: -accept, -proxyfilter, -proxyhost, -proxyport, -urlencoding, -useragent}
+test http-1.6 {http::config} -setup {
+    set oldenc [http::config -urlencoding]
+} -body {
+    set enc [list [http::config -urlencoding]]
+    http::config -urlencoding iso8859-1
+    lappend enc [http::config -urlencoding]
+} -cleanup {
+    http::config -urlencoding $oldenc
+} -result {utf-8 iso8859-1}
+
+test http-2.1 {http::reset} {
+    catch {http::reset http#1}
+} 0
+
+test http-3.1 {http::geturl} -returnCodes error -body {
+    http::geturl -bogus flag
+} -result {Unknown option flag, can be: -binary, -blocksize, -channel, -command, -handler, -headers, -keepalive, -method, -myaddr, -progress, -protocol, -query, -queryblocksize, -querychannel, -queryprogress, -strict, -timeout, -type, -validate}
+test http-3.2 {http::geturl} -returnCodes error -body {
+    http::geturl http:junk
+} -result {Unsupported URL: http:junk}
+set url //[info hostname]:$port
+set badurl //[info hostname]:[expr $port+1]
+test http-3.3 {http::geturl} -body {
+    set token [http::geturl $url]
+    http::data $token
+} -cleanup {
+    http::cleanup $token
+} -result "<html><head><title>HTTP/1.0 TEST</title></head><body>
+<h1>Hello, World!</h1>
+<h2>GET /</h2>
+</body></html>"
+set tail /a/b/c
+set url //[info hostname]:$port/a/b/c
+set fullurl HTTP://user:pass@[info hostname]:$port/a/b/c
+set binurl //[info hostname]:$port/binary
+set posturl //[info hostname]:$port/post
+set badposturl //[info hostname]:$port/droppost
+set authorityurl //[info hostname]:$port
+set ipv6url http://\[::1\]:$port/
+test http-3.4 {http::geturl} -body {
+    set token [http::geturl $url]
+    http::data $token
+} -cleanup {
+    http::cleanup $token
+} -result "<html><head><title>HTTP/1.0 TEST</title></head><body>
+<h1>Hello, World!</h1>
+<h2>GET $tail</h2>
+</body></html>"
+proc selfproxy {host} {
+    global port
+    return [list [info hostname] $port]
+}
+test http-3.5 {http::geturl} -body {
+    http::config -proxyfilter selfproxy
+    set token [http::geturl $url]
+    http::data $token
+} -cleanup {
+    http::config -proxyfilter http::ProxyRequired
+    http::cleanup $token
+} -result "<html><head><title>HTTP/1.0 TEST</title></head><body>
+<h1>Hello, World!</h1>
+<h2>GET http:$url</h2>
+</body></html>"
+test http-3.6 {http::geturl} -body {
+    http::config -proxyfilter bogus
+    set token [http::geturl $url]
+    http::data $token
+} -cleanup {
+    http::config -proxyfilter http::ProxyRequired
+    http::cleanup $token
+} -result "<html><head><title>HTTP/1.0 TEST</title></head><body>
+<h1>Hello, World!</h1>
+<h2>GET $tail</h2>
+</body></html>"
+test http-3.7 {http::geturl} -body {
+    set token [http::geturl $url -headers {Pragma no-cache}]
+    http::data $token
+} -cleanup {
+    http::cleanup $token
+} -result "<html><head><title>HTTP/1.0 TEST</title></head><body>
+<h1>Hello, World!</h1>
+<h2>GET $tail</h2>
+</body></html>"
+test http-3.8 {http::geturl} -body {
+    set token [http::geturl $url -query Name=Value&Foo=Bar -timeout 2000]
+    http::data $token
+} -cleanup {
+    http::cleanup $token
+} -result "<html><head><title>HTTP/1.0 TEST</title></head><body>
+<h1>Hello, World!</h1>
+<h2>POST $tail</h2>
+<h2>Query</h2>
+<dl>
+<dt>Name<dd>Value
+<dt>Foo<dd>Bar
+</dl>
+</body></html>"
+test http-3.9 {http::geturl} -body {
+    set token [http::geturl $url -validate 1]
+    http::code $token
+} -cleanup {
+    http::cleanup $token
+} -result "HTTP/1.0 200 OK"
+test http-3.10 {http::geturl queryprogress} -setup {
+    set query foo=bar
+    set sep ""
+    set i 0
+    # Create about 120K of query data
+    while {$i < 14} {
+	incr i
+	append query $sep$query
+	set sep &
+    }
+} -body {
+    proc postProgress {token x y} {
+	global postProgress
+	lappend postProgress $y
+    }
+    set postProgress {}
+    set t [http::geturl $posturl -keepalive 0 -query $query \
+	    -queryprogress postProgress -queryblocksize 16384]
+    http::wait $t
+    list [http::status $t] [string length $query] $postProgress [http::data $t]
+} -cleanup {
+    http::cleanup $t
+} -result {ok 122879 {16384 32768 49152 65536 81920 98304 114688 122879} {Got 122879 bytes}}
+test http-3.11 {http::geturl querychannel with -command} -setup {
+    set query foo=bar
+    set sep ""
+    set i 0
+    # Create about 120K of query data
+    while {$i < 14} {
+	incr i
+	append query $sep$query
+	set sep &
+    }
+    set file [makeFile $query outdata]
+} -body {
+    set fp [open $file]
+    proc asyncCB {token} {
+	global postResult
+	lappend postResult [http::data $token]
+    }
+    set postResult [list ]
+    set t [http::geturl $posturl -querychannel $fp]
+    http::wait $t
+    set testRes [list [http::status $t] [string length $query] [http::data $t]]
+    # Now do async
+    http::cleanup $t
+    close $fp
+    set fp [open $file]
+    set t [http::geturl $posturl -querychannel $fp -command asyncCB]
+    set postResult [list PostStart]
+    http::wait $t
+    close $fp
+    lappend testRes [http::status $t] $postResult
+} -cleanup {
+    removeFile outdata
+    http::cleanup $t
+} -result {ok 122879 {Got 122880 bytes} ok {PostStart {Got 122880 bytes}}}
+# On Linux platforms when the client and server are on the same host, the
+# client is unable to read the server's response one it hits the write error.
+# The status is "eof".
+# On Windows, the http::wait procedure gets a "connection reset by peer" error
+# while reading the reply.
+test http-3.12 {http::geturl querychannel with aborted request} -setup {
+    set query foo=bar
+    set sep ""
+    set i 0
+    # Create about 120K of query data
+    while {$i < 14} {
+	incr i
+	append query $sep$query
+	set sep &
+    }
+    set file [makeFile $query outdata]
+} -constraints {nonPortable} -body {
+    set fp [open $file]
+    proc asyncCB {token} {
+	global postResult
+	lappend postResult [http::data $token]
+    }
+    proc postProgress {token x y} {
+	global postProgress
+	lappend postProgress $y
+    }
+    set postProgress {}
+    # Now do async
+    set postResult [list PostStart]
+    if {[catch {
+	set t [http::geturl $badposturl -querychannel $fp -command asyncCB \
+		-queryprogress postProgress]
+	http::wait $t
+	upvar #0 $t state
+    } err]} {
+	puts $::errorInfo
+	error $err
+    }
+    list [http::status $t] [http::code $t]
+} -cleanup {
+    removeFile outdata
+    http::cleanup $t
+} -result {ok {HTTP/1.0 200 Data follows}}
+test http-3.13 {http::geturl socket leak test} {
+    set chanCount [llength [file channels]]
+    for {set i 0} {$i < 3} {incr i} {
+	catch {http::geturl $badurl -timeout 5000}
+    }
+    # No extra channels should be taken
+    expr {[llength [file channels]] == $chanCount}
+} 1
+test http-3.14 "http::geturl $fullurl" -body {
+    set token [http::geturl $fullurl -validate 1]
+    http::code $token
+} -cleanup {
+    http::cleanup $token
+} -result "HTTP/1.0 200 OK"
+test http-3.15 {http::geturl parse failures} -body {
+    http::geturl "{invalid}:url"
+} -returnCodes error -result {Unsupported URL: {invalid}:url}
+test http-3.16 {http::geturl parse failures} -body {
+    http::geturl http:relative/url
+} -returnCodes error -result {Unsupported URL: http:relative/url}
+test http-3.17 {http::geturl parse failures} -body {
+    http::geturl /absolute/url
+} -returnCodes error -result {Missing host part: /absolute/url}
+test http-3.18 {http::geturl parse failures} -body {
+    http::geturl http://somewhere:123456789/
+} -returnCodes error -result {Invalid port number: 123456789}
+test http-3.19 {http::geturl parse failures} -body {
+    http::geturl http://{user}@somewhere
+} -returnCodes error -result {Illegal characters in URL user}
+test http-3.20 {http::geturl parse failures} -body {
+    http::geturl http://%user@somewhere
+} -returnCodes error -result {Illegal encoding character usage "%us" in URL user}
+test http-3.21 {http::geturl parse failures} -body {
+    http::geturl http://somewhere/{path}
+} -returnCodes error -result {Illegal characters in URL path}
+test http-3.22 {http::geturl parse failures} -body {
+    http::geturl http://somewhere/%path
+} -returnCodes error -result {Illegal encoding character usage "%pa" in URL path}
+test http-3.23 {http::geturl parse failures} -body {
+    http::geturl http://somewhere/path?{query}?
+} -returnCodes error -result {Illegal characters in URL path}
+test http-3.24 {http::geturl parse failures} -body {
+    http::geturl http://somewhere/path?%query
+} -returnCodes error -result {Illegal encoding character usage "%qu" in URL path}
+test http-3.25 {http::meta} -setup {
+    unset -nocomplain m token
+} -body {
+    set token [http::geturl $url -timeout 2000]
+    array set m [http::meta $token]
+    lsort [array names m]
+} -cleanup {
+    http::cleanup $token
+    unset -nocomplain m token
+} -result {Content-Length Content-Type Date}
+test http-3.26 {http::meta} -setup {
+    unset -nocomplain m token
+} -body {
+    set token [http::geturl $url -headers {X-Check 1} -timeout 2000]
+    array set m [http::meta $token]
+    lsort [array names m]
+} -cleanup {
+    http::cleanup $token
+    unset -nocomplain m token
+} -result {Content-Length Content-Type Date X-Check}
+test http-3.27 {http::geturl: -headers override -type} -body {
+    set token [http::geturl $url/headers -type "text/plain" -query dummy \
+	    -headers [list "Content-Type" "text/plain;charset=utf-8"]]
+    http::data $token
+} -cleanup {
+    http::cleanup $token
+} -match regexp -result {(?n)Host .*
+User-Agent .*
+Connection close
+Content-Type {text/plain;charset=utf-8}
+Accept \*/\*
+Accept-Encoding .*
+Content-Length 5}
+test http-3.28 {http::geturl: -headers override -type default} -body {
+    set token [http::geturl $url/headers -query dummy \
+	    -headers [list "Content-Type" "text/plain;charset=utf-8"]]
+    http::data $token
+} -cleanup {
+    http::cleanup $token
+} -match regexp -result {(?n)Host .*
+User-Agent .*
+Connection close
+Content-Type {text/plain;charset=utf-8}
+Accept \*/\*
+Accept-Encoding .*
+Content-Length 5}
+test http-3.29 {http::geturl IPv6 address} -body {
+    # We only want to see if the URL gets parsed correctly. This is
+    # the case if http::geturl succeeds or returns a socket related
+    # error. If the parsing is wrong, we'll get a parse error.
+    # It'd be better to separate the URL parser from http::geturl, so
+    # that it can be tested without also trying to make a connection.
+    set error [catch {http::geturl $ipv6url -validate 1} token]
+    if {$error && [string match "couldn't open socket: *" $token]} {
+            set error 0
+    }
+    set error
+} -cleanup {
+    catch { http::cleanup $token }
+} -result 0
+test http-3.30 {http::geturl query without path} -body {
+    set token [http::geturl $authorityurl?var=val]
+    http::ncode $token
+} -cleanup {
+    catch { http::cleanup $token }
+} -result 200
+test http-3.31 {http::geturl fragment without path} -body {
+    set token [http::geturl "$authorityurl#fragment42"]
+    http::ncode $token
+} -cleanup {
+    catch { http::cleanup $token }
+} -result 200
+# Bug c11a51c482
+test http-3.32 {http::geturl: -headers override -accept default} -body {
+    set token [http::geturl $url/headers -query dummy \
+	    -headers [list "Accept" "text/plain,application/tcl-test-value"]]
+    http::data $token
+} -cleanup {
+    http::cleanup $token
+} -match regexp -result {(?n)Host .*
+User-Agent .*
+Connection close
+Accept text/plain,application/tcl-test-value
+Accept-Encoding .*
+Content-Type application/x-www-form-urlencoded
+Content-Length 5}
+
+test http-4.1 {http::Event} -body {
+    set token [http::geturl $url -keepalive 0]
+    upvar #0 $token data
+    array set meta $data(meta)
+    expr {($data(totalsize) == $meta(Content-Length))}
+} -cleanup {
+    http::cleanup $token
+} -result 1
+test http-4.2 {http::Event} -body {
+    set token [http::geturl $url]
+    upvar #0 $token data
+    array set meta $data(meta)
+    string compare $data(type) [string trim $meta(Content-Type)]
+} -cleanup {
+    http::cleanup $token
+} -result 0
+test http-4.3 {http::Event} -body {
+    set token [http::geturl $url]
+    http::code $token
+} -cleanup {
+    http::cleanup $token
+} -result {HTTP/1.0 200 Data follows}
+test http-4.4 {http::Event} -setup {
+    set testfile [makeFile "" testfile]
+} -body {
+    set out [open $testfile w]
+    set token [http::geturl $url -channel $out]
+    close $out
+    set in [open $testfile]
+    set x [read $in]
+} -cleanup {
+    catch {close $in}
+    catch {close $out}
+    removeFile $testfile
+    http::cleanup $token
+} -result "<html><head><title>HTTP/1.0 TEST</title></head><body>
+<h1>Hello, World!</h1>
+<h2>GET $tail</h2>
+</body></html>"
+test http-4.5 {http::Event} -setup {
+    set testfile [makeFile "" testfile]
+} -body {
+    set out [open $testfile w]
+    fconfigure $out -translation lf
+    set token [http::geturl $url -channel $out]
+    close $out
+    upvar #0 $token data
+    expr {$data(currentsize) == $data(totalsize)}
+} -cleanup {
+    removeFile $testfile
+    http::cleanup $token
+} -result 1
+test http-4.6 {http::Event} -setup {
+    set testfile [makeFile "" testfile]
+} -body {
+    set out [open $testfile w]
+    set token [http::geturl $binurl -channel $out]
+    close $out
+    set in [open $testfile]
+    fconfigure $in -translation binary
+    read $in
+} -cleanup {
+    catch {close $in}
+    catch {close $out}
+    removeFile $testfile
+    http::cleanup $token
+} -result "$bindata[string trimleft $binurl /]"
+proc myProgress {token total current} {
+    global progress httpLog
+    if {[info exists httpLog] && $httpLog} {
+	puts "progress $total $current"
+    }
+    set progress [list $total $current]
+}
+test http-4.6.1 {http::Event} knownBug {
+    set token [http::geturl $url -blocksize 50 -progress myProgress]
+    return $progress
+} {111 111}
+test http-4.7 {http::Event} -body {
+    set token [http::geturl $url -keepalive 0 -progress myProgress]
+    return $progress
+} -cleanup {
+    http::cleanup $token
+} -result {111 111}
+test http-4.8 {http::Event} -body {
+    set token [http::geturl $url]
+    http::status $token
+} -cleanup {
+    http::cleanup $token
+} -result {ok}
+test http-4.9 {http::Event} -body {
+    set token [http::geturl $url -progress myProgress]
+    http::code $token
+} -cleanup {
+    http::cleanup $token
+} -result {HTTP/1.0 200 Data follows}
+test http-4.10 {http::Event} -body {
+    set token [http::geturl $url -progress myProgress]
+    http::size $token
+} -cleanup {
+    http::cleanup $token
+} -result {111}
+# Timeout cases
+#	Short timeout to working server (the test server). This lets us try a
+#	reset during the connection.
+test http-4.11 {http::Event} -body {
+    set token [http::geturl $url -timeout 1 -keepalive 0 -command \#]
+    http::reset $token
+    http::status $token
+} -cleanup {
+    http::cleanup $token
+} -result {reset}
+#	Longer timeout with reset.
+test http-4.12 {http::Event} -body {
+    set token [http::geturl $url/?timeout=10 -keepalive 0 -command \#]
+    http::reset $token
+    http::status $token
+} -cleanup {
+    http::cleanup $token
+} -result {reset}
+#	Medium timeout to working server that waits even longer. The timeout
+#	hits while waiting for a reply.
+test http-4.13 {http::Event} -body {
+    set token [http::geturl $url?timeout=30 -keepalive 0 -timeout 10 -command \#]
+    http::wait $token
+    http::status $token
+} -cleanup {
+    http::cleanup $token
+} -result {timeout}
+#	Longer timeout to good host, bad port, gets an error after the
+#	connection "completes" but the socket is bad.
+test http-4.14 {http::Event} -body {
+    set token [http::geturl $badurl/?timeout=10 -timeout 10000 -command \#]
+    if {$token eq ""} {
+	error "bogus return from http::geturl"
+    }
+    http::wait $token
+    lindex [http::error $token] 0
+} -cleanup {
+    catch {http::cleanup $token}
+} -result {connect failed connection refused}
+# Bogus host
+test http-4.15 {http::Event} -body {
+    # This test may fail if you use a proxy server. That is to be
+    # expected and is not a problem with Tcl.
+    set token [http::geturl //not_a_host.tcl.tk -timeout 1000 -command \#]
+    http::wait $token
+    http::status $token
+    # error codes vary among platforms.
+} -cleanup {
+    catch {http::cleanup $token}
+} -returnCodes 1 -match glob -result "couldn't open socket*"
+
+test http-5.1 {http::formatQuery} {
+    http::formatQuery name1 value1 name2 "value two"
+} {name1=value1&name2=value%20two}
+# test http-5.2 obsoleted by 5.4 and 5.5 with http 2.5
+test http-5.3 {http::formatQuery} {
+    http::formatQuery lines "line1\nline2\nline3"
+} {lines=line1%0D%0Aline2%0D%0Aline3}
+test http-5.4 {http::formatQuery} {
+    http::formatQuery name1 ~bwelch name2 \xa1\xa2\xa2
+} {name1=~bwelch&name2=%C2%A1%C2%A2%C2%A2}
+test http-5.5 {http::formatQuery} {
+    set enc [http::config -urlencoding]
+    http::config -urlencoding iso8859-1
+    set res [http::formatQuery name1 ~bwelch name2 \xa1\xa2\xa2]
+    http::config -urlencoding $enc
+    set res
+} {name1=~bwelch&name2=%A1%A2%A2}
+
+test http-6.1 {http::ProxyRequired} -body {
+    http::config -proxyhost [info hostname] -proxyport $port
+    set token [http::geturl $url]
+    http::wait $token
+    upvar #0 $token data
+    set data(body)
+} -cleanup {
+    http::config -proxyhost {} -proxyport {}
+    http::cleanup $token
+} -result "<html><head><title>HTTP/1.0 TEST</title></head><body>
+<h1>Hello, World!</h1>
+<h2>GET http:$url</h2>
+</body></html>"
+
+test http-7.1 {http::mapReply} {
+    http::mapReply "abc\$\[\]\"\\()\}\{"
+} {abc%24%5B%5D%22%5C%28%29%7D%7B}
+test http-7.2 {http::mapReply} {
+    # RFC 2718 specifies that we pass urlencoding on utf-8 chars by default,
+    # so make sure this gets converted to utf-8 then urlencoded.
+    http::mapReply "\u2208"
+} {%E2%88%88}
+test http-7.3 {http::formatQuery} -setup {
+    set enc [http::config -urlencoding]
+} -returnCodes error -body {
+    # this would be reverting to http <=2.4 behavior
+    http::config -urlencoding ""
+    http::mapReply "\u2208"
+} -cleanup {
+    http::config -urlencoding $enc
+} -result "can't read \"formMap(\u2208)\": no such element in array"
+test http-7.4 {http::formatQuery} -setup {
+    set enc [http::config -urlencoding]
+} -body {
+    # this would be reverting to http <=2.4 behavior w/o errors
+    # (unknown chars become '?')
+    http::config -urlencoding "iso8859-1"
+    http::mapReply "\u2208"
+} -cleanup {
+    http::config -urlencoding $enc
+} -result {%3F}
+
+# cleanup
+catch {unset url}
+catch {unset badurl}
+catch {unset port}
+catch {unset data}
+if {[info exists httpthread]} {
+    thread::release $httpthread
+} else {
+    close $listen
+}
+
+if {[info exists removeHttpd]} {
+    removeFile $httpdFile
+}
+
+rename bgerror {}
+::tcltest::cleanupTests
+
+# Local variables:
+# mode: tcl
+# End:
diff --git a/tests/http11.test b/tests/http11.test
new file mode 100644
index 0000000..c9ded0b
--- /dev/null
+++ b/tests/http11.test
@@ -0,0 +1,675 @@
+# http11.test --                                                -*- tcl-*-
+#
+#	Test HTTP/1.1 features.
+#
+# Copyright (C) 2009 Pat Thoyts <patthoyts@users.sourceforge.net>
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+package require tcltest 2
+namespace import -force ::tcltest::*
+
+package require http 2.8
+
+# start the server
+variable httpd_output
+proc create_httpd {} {
+    proc httpd_read {chan} {
+        variable httpd_output
+        if {[gets $chan line] != -1} {
+            #puts stderr "read '$line'"
+            set httpd_output $line
+        }
+        if {[eof $chan]} {
+            puts stderr "eof from httpd"
+            fileevent $chan readable {}
+            close $chan
+        }
+    }
+    variable httpd_output
+    set httpd_script [file join [pwd] [file dirname [info script]] httpd11.tcl]
+    set httpd [open "|[list [interpreter] -encoding utf-8 $httpd_script]" r+]
+    fconfigure $httpd -buffering line -blocking 0
+    fileevent $httpd readable [list httpd_read $httpd]
+    vwait httpd_output
+    variable httpd_port [lindex $httpd_output 2]
+    return $httpd
+}
+
+proc halt_httpd {} {
+    variable httpd_output
+    variable httpd
+    if {[info exists httpd]} {
+        puts $httpd "quit"
+        vwait httpd_output
+        close $httpd
+    }
+    unset -nocomplain httpd_output httpd
+}
+
+proc meta {tok {key ""}} {
+    set meta [http::meta $tok]
+    if {$key ne ""} {
+        if {[dict exists $meta $key]} {
+            return [dict get $meta $key]
+        } else {
+            return ""
+        }
+    }
+    return $meta
+}
+
+proc check_crc {tok args} {
+    set crc [meta $tok x-crc32]
+    set data [expr {[llength $args] ? [lindex $args 0] : [http::data $tok]}]
+    set chk [format %x [zlib crc32 $data]]
+    if {$crc ne $chk} {
+        return  "crc32 mismatch: $crc ne $chk"
+    }
+    return "ok"
+}
+
+makeFile "<html><head><title>test</title></head><body><p>this is a test</p>\n[string repeat {<p>This is a tcl test file.</p>} 4192]\n</body></html>" testdoc.html
+
+# -------------------------------------------------------------------------
+
+test http11-1.0 "normal request for document " -setup {
+    variable httpd [create_httpd]
+} -body {
+    set tok [http::geturl http://localhost:$httpd_port/testdoc.html -timeout 10000]
+    http::wait $tok
+    list [http::status $tok] [http::code $tok] [check_crc $tok] [meta $tok connection]
+} -cleanup {
+    http::cleanup $tok
+    halt_httpd
+} -result {ok {HTTP/1.1 200 OK} ok close}
+
+test http11-1.1 "normal,gzip,non-chunked" -setup {
+    variable httpd [create_httpd]
+} -body {
+    set tok [http::geturl http://localhost:$httpd_port/testdoc.html?close=1 \
+                 -timeout 10000 -headers {accept-encoding gzip}]
+    http::wait $tok
+    list [http::status $tok] [http::code $tok] [check_crc $tok] \
+        [meta $tok content-encoding] [meta $tok transfer-encoding]
+} -cleanup {
+    http::cleanup $tok
+    halt_httpd
+} -result {ok {HTTP/1.1 200 OK} ok gzip {}}
+
+test http11-1.2 "normal,deflated,non-chunked" -setup {
+    variable httpd [create_httpd]
+} -body {
+    set tok [http::geturl http://localhost:$httpd_port/testdoc.html?close=1 \
+                 -timeout 10000 -headers {accept-encoding deflate}]
+    http::wait $tok
+    list [http::status $tok] [http::code $tok] [check_crc $tok] \
+        [meta $tok content-encoding] [meta $tok transfer-encoding]
+} -cleanup {
+    http::cleanup $tok
+    halt_httpd
+} -result {ok {HTTP/1.1 200 OK} ok deflate {}}
+
+test http11-1.3 "normal,compressed,non-chunked" -setup {
+    variable httpd [create_httpd]
+} -body {
+    set tok [http::geturl http://localhost:$httpd_port/testdoc.html?close=1 \
+                 -timeout 10000 -headers {accept-encoding compress}]
+    http::wait $tok
+    list [http::status $tok] [http::code $tok] [check_crc $tok] \
+        [meta $tok content-encoding] [meta $tok transfer-encoding]
+} -cleanup {
+    http::cleanup $tok
+    halt_httpd
+} -result {ok {HTTP/1.1 200 OK} ok compress {}}
+
+test http11-1.4 "normal,identity,non-chunked" -setup {
+    variable httpd [create_httpd]
+} -body {
+    set tok [http::geturl http://localhost:$httpd_port/testdoc.html?close=1 \
+                 -timeout 10000 -headers {accept-encoding identity}]
+    http::wait $tok
+    list [http::status $tok] [http::code $tok] [check_crc $tok] \
+        [meta $tok content-encoding] [meta $tok transfer-encoding]
+} -cleanup {
+    http::cleanup $tok
+    halt_httpd
+} -result {ok {HTTP/1.1 200 OK} ok {} {}}
+
+test http11-1.5 "normal request for document, unsupported coding" -setup {
+    variable httpd [create_httpd]
+} -body {
+    set tok [http::geturl http://localhost:$httpd_port/testdoc.html \
+                 -timeout 10000 -headers {accept-encoding unsupported}]
+    http::wait $tok
+    list [http::status $tok] [http::code $tok] [check_crc $tok] \
+        [meta $tok content-encoding]
+} -cleanup {
+    http::cleanup $tok
+    halt_httpd
+} -result {ok {HTTP/1.1 200 OK} ok {}}
+
+test http11-1.6 "normal, specify 1.1 " -setup {
+    variable httpd [create_httpd]
+} -body {
+    set tok [http::geturl http://localhost:$httpd_port/testdoc.html \
+                 -protocol 1.1 -timeout 10000]
+    http::wait $tok
+    list [http::status $tok] [http::code $tok] [check_crc $tok] \
+        [meta $tok connection] [meta $tok transfer-encoding]
+} -cleanup {
+    http::cleanup $tok
+    halt_httpd
+} -result {ok {HTTP/1.1 200 OK} ok close chunked}
+
+test http11-1.7 "normal, 1.1 and keepalive " -setup {
+    variable httpd [create_httpd]
+} -body {
+    set tok [http::geturl http://localhost:$httpd_port/testdoc.html \
+                 -protocol 1.1 -keepalive 1 -timeout 10000]
+    http::wait $tok
+    list [http::status $tok] [http::code $tok] [check_crc $tok] \
+        [meta $tok connection] [meta $tok transfer-encoding]
+} -cleanup {
+    http::cleanup $tok
+    halt_httpd
+} -result {ok {HTTP/1.1 200 OK} ok {} chunked}
+
+test http11-1.8 "normal, 1.1 and keepalive, server close" -setup {
+    variable httpd [create_httpd]
+} -body {
+    set tok [http::geturl http://localhost:$httpd_port/testdoc.html?close=1 \
+                 -protocol 1.1 -keepalive 1 -timeout 10000]
+    http::wait $tok
+    list [http::status $tok] [http::code $tok] [check_crc $tok] \
+        [meta $tok connection] [meta $tok transfer-encoding]
+} -cleanup {
+    http::cleanup $tok
+    halt_httpd
+} -result {ok {HTTP/1.1 200 OK} ok close {}}
+
+test http11-1.9 "normal,gzip,chunked" -setup {
+    variable httpd [create_httpd]
+} -body {
+    set tok [http::geturl http://localhost:$httpd_port/testdoc.html \
+                 -timeout 10000 -headers {accept-encoding gzip}]
+    http::wait $tok
+    list [http::status $tok] [http::code $tok] [check_crc $tok] \
+        [meta $tok content-encoding] [meta $tok transfer-encoding]
+} -cleanup {
+    http::cleanup $tok
+    halt_httpd
+} -result {ok {HTTP/1.1 200 OK} ok gzip chunked}
+
+test http11-1.10 "normal,deflate,chunked" -setup {
+    variable httpd [create_httpd]
+} -body {
+    set tok [http::geturl http://localhost:$httpd_port/testdoc.html \
+                 -timeout 10000 -headers {accept-encoding deflate}]
+    http::wait $tok
+    list [http::status $tok] [http::code $tok] [check_crc $tok] \
+        [meta $tok content-encoding] [meta $tok transfer-encoding]
+} -cleanup {
+    http::cleanup $tok
+    halt_httpd
+} -result {ok {HTTP/1.1 200 OK} ok deflate chunked}
+
+test http11-1.11 "normal,compress,chunked" -setup {
+    variable httpd [create_httpd]
+} -body {
+    set tok [http::geturl http://localhost:$httpd_port/testdoc.html \
+                 -timeout 10000 -headers {accept-encoding compress}]
+    http::wait $tok
+    list [http::status $tok] [http::code $tok] [check_crc $tok] \
+        [meta $tok content-encoding] [meta $tok transfer-encoding]
+} -cleanup {
+    http::cleanup $tok
+    halt_httpd
+} -result {ok {HTTP/1.1 200 OK} ok compress chunked}
+
+test http11-1.12 "normal,identity,chunked" -setup {
+    variable httpd [create_httpd]
+} -body {
+    set tok [http::geturl http://localhost:$httpd_port/testdoc.html \
+                 -timeout 10000 -headers {accept-encoding identity}]
+    http::wait $tok
+    list [http::status $tok] [http::code $tok] [check_crc $tok] \
+        [meta $tok content-encoding] [meta $tok transfer-encoding]
+} -cleanup {
+    http::cleanup $tok
+    halt_httpd
+} -result {ok {HTTP/1.1 200 OK} ok {} chunked}
+
+# -------------------------------------------------------------------------
+
+test http11-2.0 "-channel" -setup {
+    variable httpd [create_httpd]
+    set chan [open [makeFile {} testfile.tmp] wb+]
+} -body {
+    set tok [http::geturl http://localhost:$httpd_port/testdoc.html \
+                 -timeout 5000 -channel $chan]
+    http::wait $tok
+    seek $chan 0
+    set data [read $chan]
+    list [http::status $tok] [http::code $tok] [check_crc $tok $data]\
+        [meta $tok connection] [meta $tok transfer-encoding]
+} -cleanup {
+    http::cleanup $tok
+    close $chan
+    removeFile testfile.tmp
+    halt_httpd
+} -result {ok {HTTP/1.1 200 OK} ok close chunked}
+
+test http11-2.1 "-channel, encoding gzip" -setup {
+    variable httpd [create_httpd]
+    set chan [open [makeFile {} testfile.tmp] wb+]
+} -body {
+    set tok [http::geturl http://localhost:$httpd_port/testdoc.html \
+                 -timeout 5000 -channel $chan -headers {accept-encoding gzip}]
+    http::wait $tok
+    seek $chan 0
+    set data [read $chan]
+    list [http::status $tok] [http::code $tok] [check_crc $tok $data]\
+        [meta $tok connection] [meta $tok content-encoding]\
+        [meta $tok transfer-encoding]
+} -cleanup {
+    http::cleanup $tok
+    close $chan
+    removeFile testfile.tmp
+    halt_httpd
+} -result {ok {HTTP/1.1 200 OK} ok close gzip chunked}
+
+test http11-2.2 "-channel, encoding deflate" -setup {
+    variable httpd [create_httpd]
+    set chan [open [makeFile {} testfile.tmp] wb+]
+} -body {
+    set tok [http::geturl http://localhost:$httpd_port/testdoc.html \
+                 -timeout 5000 -channel $chan -headers {accept-encoding deflate}]
+    http::wait $tok
+    seek $chan 0
+    set data [read $chan]
+    list [http::status $tok] [http::code $tok] [check_crc $tok $data]\
+        [meta $tok connection] [meta $tok content-encoding]\
+        [meta $tok transfer-encoding]
+} -cleanup {
+    http::cleanup $tok
+    close $chan
+    removeFile testfile.tmp
+    halt_httpd
+} -result {ok {HTTP/1.1 200 OK} ok close deflate chunked}
+
+test http11-2.3 "-channel,encoding compress" -setup {
+    variable httpd [create_httpd]
+    set chan [open [makeFile {} testfile.tmp] wb+]
+} -body {
+    set tok [http::geturl http://localhost:$httpd_port/testdoc.html \
+                 -timeout 5000 -channel $chan \
+                 -headers {accept-encoding compress}]
+    http::wait $tok
+    seek $chan 0
+    set data [read $chan]
+    list [http::status $tok] [http::code $tok] [check_crc $tok $data]\
+        [meta $tok connection] [meta $tok content-encoding]\
+        [meta $tok transfer-encoding]
+} -cleanup {
+    http::cleanup $tok
+    close $chan
+    removeFile testfile.tmp
+    halt_httpd
+} -result {ok {HTTP/1.1 200 OK} ok close compress chunked}
+
+test http11-2.4 "-channel,encoding identity" -setup {
+    variable httpd [create_httpd]
+    set chan [open [makeFile {} testfile.tmp] wb+]
+} -body {
+    set tok [http::geturl http://localhost:$httpd_port/testdoc.html \
+                 -timeout 5000 -channel $chan \
+                 -headers {accept-encoding identity}]
+    http::wait $tok
+    seek $chan 0
+    set data [read $chan]
+    list [http::status $tok] [http::code $tok] [check_crc $tok $data]\
+        [meta $tok connection] [meta $tok content-encoding]\
+        [meta $tok transfer-encoding]
+} -cleanup {
+    http::cleanup $tok
+    close $chan
+    removeFile testfile.tmp
+    halt_httpd
+} -result {ok {HTTP/1.1 200 OK} ok close {} chunked}
+
+test http11-2.5 "-channel,encoding unsupported" -setup {
+    variable httpd [create_httpd]
+    set chan [open [makeFile {} testfile.tmp] wb+]
+} -body {
+    set tok [http::geturl http://localhost:$httpd_port/testdoc.html \
+                 -timeout 5000 -channel $chan \
+                 -headers {accept-encoding unsupported}]
+    http::wait $tok
+    seek $chan 0
+    set data [read $chan]
+    list [http::status $tok] [http::code $tok] [check_crc $tok $data]\
+        [meta $tok connection] [meta $tok content-encoding]\
+        [meta $tok transfer-encoding]
+} -cleanup {
+    http::cleanup $tok
+    close $chan
+    removeFile testfile.tmp
+    halt_httpd
+} -result {ok {HTTP/1.1 200 OK} ok close {} chunked}
+
+test http11-2.6 "-channel,encoding gzip,non-chunked" -setup {
+    variable httpd [create_httpd]
+    set chan [open [makeFile {} testfile.tmp] wb+]
+} -body {
+    set tok [http::geturl http://localhost:$httpd_port/testdoc.html?close=1 \
+                 -timeout 5000 -channel $chan -headers {accept-encoding gzip}]
+    http::wait $tok
+    seek $chan 0
+    set data [read $chan]
+    list [http::status $tok] [http::code $tok] [check_crc $tok $data]\
+        [meta $tok connection] [meta $tok content-encoding]\
+        [meta $tok transfer-encoding]\
+        [expr {[file size testdoc.html]-[file size testfile.tmp]}]
+} -cleanup {
+    http::cleanup $tok
+    close $chan
+    removeFile testfile.tmp
+    halt_httpd
+} -result {ok {HTTP/1.1 200 OK} ok close gzip {} 0}
+
+test http11-2.7 "-channel,encoding deflate,non-chunked" -setup {
+    variable httpd [create_httpd]
+    set chan [open [makeFile {} testfile.tmp] wb+]
+} -body {
+    set tok [http::geturl http://localhost:$httpd_port/testdoc.html?close=1 \
+                 -timeout 5000 -channel $chan -headers {accept-encoding deflate}]
+    http::wait $tok
+    seek $chan 0
+    set data [read $chan]
+    list [http::status $tok] [http::code $tok] [check_crc $tok $data]\
+        [meta $tok connection] [meta $tok content-encoding]\
+        [meta $tok transfer-encoding]\
+        [expr {[file size testdoc.html]-[file size testfile.tmp]}]
+} -cleanup {
+    http::cleanup $tok
+    close $chan
+    removeFile testfile.tmp
+    halt_httpd
+} -result {ok {HTTP/1.1 200 OK} ok close deflate {} 0}
+
+test http11-2.8 "-channel,encoding compress,non-chunked" -setup {
+    variable httpd [create_httpd]
+    set chan [open [makeFile {} testfile.tmp] wb+]
+} -body {
+    set tok [http::geturl http://localhost:$httpd_port/testdoc.html?close=1 \
+                 -timeout 5000 -channel $chan -headers {accept-encoding compress}]
+    http::wait $tok
+    seek $chan 0
+    set data [read $chan]
+    list [http::status $tok] [http::code $tok] [check_crc $tok $data]\
+        [meta $tok connection] [meta $tok content-encoding]\
+        [meta $tok transfer-encoding]\
+        [expr {[file size testdoc.html]-[file size testfile.tmp]}]
+} -cleanup {
+    http::cleanup $tok
+    close $chan
+    removeFile testfile.tmp
+    halt_httpd
+} -result {ok {HTTP/1.1 200 OK} ok close compress {} 0}
+
+test http11-2.9 "-channel,encoding identity,non-chunked" -setup {
+    variable httpd [create_httpd]
+    set chan [open [makeFile {} testfile.tmp] wb+]
+} -body {
+    set tok [http::geturl http://localhost:$httpd_port/testdoc.html?close=1 \
+                 -timeout 5000 -channel $chan -headers {accept-encoding identity}]
+    http::wait $tok
+    seek $chan 0
+    set data [read $chan]
+    list [http::status $tok] [http::code $tok] [check_crc $tok $data]\
+        [meta $tok connection] [meta $tok content-encoding]\
+        [meta $tok transfer-encoding]\
+        [expr {[file size testdoc.html]-[file size testfile.tmp]}]
+} -cleanup {
+    http::cleanup $tok
+    close $chan
+    removeFile testfile.tmp
+    halt_httpd
+} -result {ok {HTTP/1.1 200 OK} ok close {} {} 0}
+
+test http11-2.10 "-channel,deflate,keepalive" -setup {
+    variable httpd [create_httpd]
+    set chan [open [makeFile {} testfile.tmp] wb+]
+} -body {
+    set tok [http::geturl http://localhost:$httpd_port/testdoc.html \
+                 -timeout 5000 -channel $chan -keepalive 1 \
+		 -headers {accept-encoding deflate}]
+    http::wait $tok
+    seek $chan 0
+    set data [read $chan]
+    list [http::status $tok] [http::code $tok] [check_crc $tok $data]\
+        [meta $tok connection] [meta $tok content-encoding]\
+        [meta $tok transfer-encoding]\
+        [expr {[file size testdoc.html]-[file size testfile.tmp]}]
+} -cleanup {
+    http::cleanup $tok
+    close $chan
+    removeFile testfile.tmp
+    halt_httpd
+} -result {ok {HTTP/1.1 200 OK} ok {} deflate chunked 0}
+
+test http11-2.11 "-channel,identity,keepalive" -setup {
+    variable httpd [create_httpd]
+    set chan [open [makeFile {} testfile.tmp] wb+]
+} -body {
+    set tok [http::geturl http://localhost:$httpd_port/testdoc.html \
+                 -headers {accept-encoding identity} \
+                 -timeout 5000 -channel $chan -keepalive 1]
+    http::wait $tok
+    seek $chan 0
+    set data [read $chan]
+    list [http::status $tok] [http::code $tok] [check_crc $tok $data]\
+        [meta $tok connection] [meta $tok content-encoding]\
+        [meta $tok transfer-encoding]
+} -cleanup {
+    http::cleanup $tok
+    close $chan
+    removeFile testfile.tmp
+    halt_httpd
+} -result {ok {HTTP/1.1 200 OK} ok {} {} chunked}
+
+test http11-2.12 "-channel,negotiate,keepalive" -setup {
+    variable httpd [create_httpd]
+    set chan [open [makeFile {} testfile.tmp] wb+]
+} -body {
+    set tok [http::geturl http://localhost:$httpd_port/testdoc.html \
+                 -timeout 5000 -channel $chan -keepalive 1]
+    http::wait $tok
+    seek $chan 0
+    set data [read $chan]
+    list [http::status $tok] [http::code $tok] [check_crc $tok $data]\
+        [meta $tok connection] [meta $tok content-encoding]\
+        [meta $tok transfer-encoding] [meta $tok x-requested-encodings]\
+        [expr {[file size testdoc.html]-[file size testfile.tmp]}]
+} -cleanup {
+    http::cleanup $tok
+    close $chan
+    removeFile testfile.tmp
+    halt_httpd
+} -result {ok {HTTP/1.1 200 OK} ok {} gzip chunked gzip,deflate,compress 0}
+
+
+# -------------------------------------------------------------------------
+#
+# The following tests for the -handler option will require changes in
+# the future. At the moment we cannot handler chunked data with this
+# option. Therefore we currently force HTTP/1.0 protocol version.
+#
+# Once this is solved, these tests should be fixed to assume chunked
+# returns in 3.2 and 3.3 and HTTP/1.1 in all but test 3.1
+
+proc handler {var sock token} {
+    upvar #0 $var data
+    set chunk [read $sock]
+    append data $chunk
+    #::http::Log "handler read [string length $chunk] ([chan configure $sock -buffersize])"
+    if {[eof $sock]} {
+        #::http::Log "handler eof $sock"
+	chan event $sock readable {}
+    }
+}
+
+test http11-3.0 "-handler,close,identity" -setup {
+    variable httpd [create_httpd]
+    set testdata ""
+} -body {
+    set tok [http::geturl http://localhost:$httpd_port/testdoc.html?close=1 \
+                 -timeout 10000 -handler [namespace code [list handler testdata]]]
+    http::wait $tok
+    list [http::status $tok] [http::code $tok] [check_crc $tok $testdata]\
+        [meta $tok connection] [meta $tok content-encoding] \
+        [meta $tok transfer-encoding] \
+        [expr {[file size testdoc.html]-[string length $testdata]}]
+} -cleanup {
+    http::cleanup $tok
+    unset -nocomplain testdata
+    halt_httpd
+} -result {ok {HTTP/1.0 200 OK} ok close {} {} 0}
+
+test http11-3.1 "-handler,protocol1.0" -setup {
+    variable httpd [create_httpd]
+    set testdata ""
+} -body {
+    set tok [http::geturl http://localhost:$httpd_port/testdoc.html?close=1 \
+                 -timeout 10000 -protocol 1.0 \
+                 -handler [namespace code [list handler testdata]]]
+    http::wait $tok
+    list [http::status $tok] [http::code $tok] [check_crc $tok $testdata]\
+        [meta $tok connection] [meta $tok content-encoding] \
+        [meta $tok transfer-encoding] \
+        [expr {[file size testdoc.html]-[string length $testdata]}]
+} -cleanup {
+    http::cleanup $tok
+    unset -nocomplain testdata
+    halt_httpd
+} -result {ok {HTTP/1.0 200 OK} ok close {} {} 0}
+
+test http11-3.2 "-handler,close,chunked" -setup {
+    variable httpd [create_httpd]
+    set testdata ""
+} -body {
+    set tok [http::geturl http://localhost:$httpd_port/testdoc.html \
+                 -timeout 10000 -keepalive 0 -binary 1\
+                 -handler [namespace code [list handler testdata]]]
+    http::wait $tok
+    list [http::status $tok] [http::code $tok] [check_crc $tok $testdata]\
+        [meta $tok connection] [meta $tok content-encoding] \
+        [meta $tok transfer-encoding] \
+        [expr {[file size testdoc.html]-[string length $testdata]}]
+} -cleanup {
+    http::cleanup $tok
+    unset -nocomplain testdata
+    halt_httpd
+} -result {ok {HTTP/1.0 200 OK} ok close {} {} 0}
+
+test http11-3.3 "-handler,keepalive,chunked" -setup {
+    variable httpd [create_httpd]
+    set testdata ""
+} -body {
+    set tok [http::geturl http://localhost:$httpd_port/testdoc.html \
+                 -timeout 10000 -keepalive 1 -binary 1\
+                 -handler [namespace code [list handler testdata]]]
+    http::wait $tok
+    list [http::status $tok] [http::code $tok] [check_crc $tok $testdata]\
+        [meta $tok connection] [meta $tok content-encoding] \
+        [meta $tok transfer-encoding] \
+        [expr {[file size testdoc.html]-[string length $testdata]}]
+} -cleanup {
+    http::cleanup $tok
+    unset -nocomplain testdata
+    halt_httpd
+} -result {ok {HTTP/1.0 200 OK} ok close {} {} 0}
+
+test http11-4.0 "normal post request" -setup {
+    variable httpd [create_httpd]
+} -body {
+    set query [http::formatQuery q 1 z 2]
+    set tok [http::geturl http://localhost:$httpd_port/testdoc.html \
+                 -query $query -timeout 10000]
+    http::wait $tok
+    list status [http::status $tok] code [http::code $tok]\
+        crc [check_crc $tok]\
+        connection [meta $tok connection]\
+        query-length [meta $tok x-query-length]
+} -cleanup {
+    http::cleanup $tok
+    halt_httpd
+} -result {status ok code {HTTP/1.1 200 OK} crc ok connection close query-length 7}
+
+test http11-4.1 "normal post request, check query length" -setup {
+    variable httpd [create_httpd]
+} -body {
+    set query [http::formatQuery q 1 z 2]
+    set tok [http::geturl http://localhost:$httpd_port/testdoc.html \
+                 -headers [list x-check-query yes] \
+                 -query $query -timeout 10000]
+    http::wait $tok
+    list status [http::status $tok] code [http::code $tok]\
+        crc [check_crc $tok]\
+        connection [meta $tok connection]\
+        query-length [meta $tok x-query-length]
+} -cleanup {
+    http::cleanup $tok
+    halt_httpd
+} -result {status ok code {HTTP/1.1 200 OK} crc ok connection close query-length 7}
+
+test http11-4.2 "normal post request, check long query length" -setup {
+    variable httpd [create_httpd]
+} -body {
+    set query [string repeat a 24576]
+    set tok [http::geturl http://localhost:$httpd_port/testdoc.html\
+                 -headers [list x-check-query yes]\
+                 -query $query -timeout 10000]
+    http::wait $tok
+    list status [http::status $tok] code [http::code $tok]\
+        crc [check_crc $tok]\
+        connection [meta $tok connection]\
+        query-length [meta $tok x-query-length]
+} -cleanup {
+    http::cleanup $tok
+    halt_httpd
+} -result {status ok code {HTTP/1.1 200 OK} crc ok connection close query-length 24576}
+
+test http11-4.3 "normal post request, check channel query length" -setup {
+    variable httpd [create_httpd]
+    set chan [open [makeFile {} testfile.tmp] wb+]
+    puts -nonewline $chan [string repeat [encoding convertto utf-8 "This is a test\n"] 8192]
+    flush $chan
+    seek $chan 0
+} -body {
+    set tok [http::geturl http://localhost:$httpd_port/testdoc.html\
+                 -headers [list x-check-query yes]\
+                 -querychannel $chan -timeout 10000]
+    http::wait $tok
+    list status [http::status $tok] code [http::code $tok]\
+        crc [check_crc $tok]\
+        connection [meta $tok connection]\
+        query-length [meta $tok x-query-length]
+} -cleanup {
+    http::cleanup $tok
+    close $chan
+    removeFile testfile.tmp
+    halt_httpd
+} -result {status ok code {HTTP/1.1 200 OK} crc ok connection close query-length 122880}
+
+# -------------------------------------------------------------------------
+
+foreach p {create_httpd httpd_read halt_httpd meta check_crc} {
+    if {[llength [info proc $p]]} {rename $p {}}
+}
+removeFile testdoc.html
+unset -nocomplain httpd_port httpd p
+
+::tcltest::cleanupTests
diff --git a/tests/httpd b/tests/httpd
new file mode 100644
index 0000000..232e80a
--- /dev/null
+++ b/tests/httpd
@@ -0,0 +1,236 @@
+# -*- tcl -*-
+#
+# The httpd_ procedures implement a stub http server.
+#
+# Copyright (c) 1997-1998 Sun Microsystems, Inc.
+# Copyright (c) 1999-2000 Scriptics Corporation
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+#set httpLog 1
+
+proc httpd_init {{port 8015}} {
+    socket -server httpdAccept $port
+}
+proc httpd_log {args} {
+    global httpLog
+    if {[info exists httpLog] && $httpLog} {
+	puts stderr "httpd: [join $args { }]"
+    }
+}
+array set httpdErrors {
+    204 {No Content}
+    400 {Bad Request}
+    401 {Authorization Required}
+    404 {Not Found}
+    503 {Service Unavailable}
+    504 {Service Temporarily Unavailable}
+}
+
+proc httpdError {sock code args} {
+    global httpdErrors
+    puts $sock "$code $httpdErrors($code)"
+    httpd_log "error: [join $args { }]"
+}
+proc httpdAccept {newsock ipaddr port} {
+    global httpd
+    upvar #0 httpd$newsock data
+
+    fconfigure $newsock -blocking 0 -translation {auto crlf}
+    httpd_log $newsock Connect $ipaddr $port
+    set data(ipaddr) $ipaddr
+    after 50 [list fileevent $newsock readable [list httpdRead $newsock]]
+}
+
+# read data from a client request
+
+proc httpdRead { sock } {
+    upvar #0 httpd$sock data
+
+    if {[eof $sock]} {
+	set readCount -1
+    } elseif {![info exists data(state)]} {
+
+	# Read the protocol line and parse out the URL and query
+
+	set readCount [gets $sock line]
+	if {[regexp {(POST|GET|HEAD) ([^?]+)\??([^ ]*) HTTP/(1.[01])} $line \
+		-> data(proto) data(url) data(query) data(httpversion)]} {
+	    set data(state) mime
+	    httpd_log $sock Query $line
+	} else {
+	    httpdError $sock 400
+	    httpd_log $sock Error "bad first line:$line"
+	    httpdSockDone $sock
+	}
+	return
+    } elseif {$data(state) == "mime"} {
+
+	# Read the HTTP headers
+
+	set readCount [gets $sock line]
+        if {[regexp {^([^:]+):(.*)$} $line -> key val]} {
+            lappend data(meta) $key [string trim $val]
+        }
+
+    } elseif {$data(state) == "query"} {
+
+	# Read the query data
+
+	if {![info exists data(length_orig)]} {
+	    set data(length_orig) $data(length)
+	}
+	set line [read $sock $data(length)]
+	set readCount [string length $line]
+	incr data(length) -$readCount
+    }
+
+    # string compare $readCount 0 maps -1 to -1, 0 to 0, and > 0 to 1
+
+    set state [string compare $readCount 0],$data(state),$data(proto)
+    httpd_log $sock $state
+    switch -- $state {
+	-1,mime,HEAD	-
+	-1,mime,GET	-
+	-1,mime,POST	{
+	    # gets would block
+	    return
+	}
+	0,mime,HEAD	-
+	0,mime,GET	-
+	0,query,POST	{
+	    # Empty line at end of headers,
+	    # or eof after query data
+	    httpdRespond $sock
+	}
+	0,mime,POST	{
+	    # Empty line between headers and query data
+	    if {![info exists data(mime,content-length)]} {
+		httpd_log $sock Error "No Content-Length for POST"
+		httpdError $sock 400
+		httpdSockDone $sock
+	    } else {
+		set data(state) query
+		set data(length) $data(mime,content-length)
+
+		# Special case to simulate servers that respond
+		# without reading the post data.
+
+		if {[string match *droppost* $data(url)]} {
+		    fileevent $sock readable {}
+		    httpdRespond $sock
+		}
+	    }
+	}
+	1,mime,HEAD	-
+	1,mime,POST	-
+	1,mime,GET	{
+	    # A line of HTTP headers
+	    if {[regexp {([^:]+):[ 	]*(.*)}  $line dummy key value]} {
+		set data(mime,[string tolower $key]) $value
+	    }
+	}
+	-1,query,POST	{
+	    httpd_log $sock Error "unexpected eof on <$data(url)> request"
+	    httpdError $sock 400
+	    httpdSockDone $sock
+	}
+	1,query,POST	{
+	    append data(query) $line
+	    if {$data(length) <= 0} {
+		set data(length) $data(length_orig)
+		httpdRespond $sock
+	    }
+	}
+	default {
+	    if {[eof $sock]} {
+		httpd_log $sock Error "unexpected eof on <$data(url)> request"
+	    } else {
+		httpd_log $sock Error "unhandled state <$state> fetching <$data(url)>"
+	    }
+	    httpdError $sock 404
+	    httpdSockDone $sock
+	}
+    }
+}
+proc httpdSockDone { sock } {
+    upvar #0 httpd$sock data
+    unset data
+    catch {close $sock}
+}
+
+# Respond to the query.
+
+proc httpdRespond { sock } {
+    global httpd bindata port
+    upvar #0 httpd$sock data
+
+    switch -glob -- $data(url) {
+	*binary* {
+	    set html "$bindata[info hostname]:$port$data(url)"
+	    set type application/octet-stream
+	}
+	*post* {
+	    set html "Got [string length $data(query)] bytes"
+	    set type text/plain
+	}
+	*headers* {
+	    set html ""
+	    set type text/plain
+	    foreach {key value} $data(meta) {
+		append html [list $key $value] "\n"
+	    }
+	    set html [string trim $html]
+	}
+	default {
+	    set type text/html
+
+	    set html "<html><head><title>HTTP/1.0 TEST</title></head><body>
+<h1>Hello, World!</h1>
+<h2>$data(proto) $data(url)</h2>
+"
+	    if {[info exists data(query)] && [string length $data(query)]} {
+		append html "<h2>Query</h2>\n<dl>\n"
+		foreach {key value} [split $data(query) &=] {
+		    append html "<dt>$key<dd>$value\n"
+		    if {$key == "timeout"} {
+			after $value	;# pause
+		    }
+		}
+		append html </dl>\n
+	    }
+	    append html </body></html>
+	}
+    }
+
+    # Catch errors from premature client closes
+    
+    catch {
+	if {$data(proto) == "HEAD"} {
+	    puts $sock "HTTP/1.0 200 OK"
+	} else {
+            # Split the response to test for [Bug 26245326]
+	    puts -nonewline $sock "HT"
+            flush $sock
+            puts $sock "TP/1.0 200 Data follows"
+	}
+	puts $sock "Date: [clock format [clock seconds] \
+                              -format {%a, %d %b %Y %H:%M:%S %Z}]"
+	puts $sock "Content-Type: $type"
+	puts $sock "Content-Length: [string length $html]"
+        foreach {key val} $data(meta) {
+            if {[string match "X-*" $key]} {
+                puts $sock "$key: $val"
+            }
+        }
+	puts $sock ""
+	flush $sock
+	if {$data(proto) != "HEAD"} {
+	    fconfigure $sock -translation binary
+	    puts -nonewline $sock $html
+	}
+    }
+    httpd_log $sock Done ""
+    httpdSockDone $sock
+}
diff --git a/tests/httpd11.tcl b/tests/httpd11.tcl
new file mode 100644
index 0000000..6eae2b71f
--- /dev/null
+++ b/tests/httpd11.tcl
@@ -0,0 +1,255 @@
+# httpd11.tcl --                                                -*- tcl -*-
+#
+#	A simple httpd for testing HTTP/1.1 client features.
+#	Not suitable for use on a internet connected port.
+#
+# Copyright (C) 2009 Pat Thoyts <patthoyts@users.sourceforge.net>
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+package require Tcl 8.6
+
+proc ::tcl::dict::get? {dict key} {
+    if {[dict exists $dict $key]} {
+        return [dict get $dict $key]
+    }
+    return
+}
+namespace ensemble configure dict \
+    -map [linsert [namespace ensemble configure dict -map] end get? ::tcl::dict::get?]
+
+proc make-chunk-generator {data {size 4096}} {
+    variable _chunk_gen_uid
+    if {![info exists _chunk_gen_uid]} {set _chunk_gen_uid 0}
+    set lambda {{data size} {
+        set pos 0
+        yield
+        while {1} {
+            set payload [string range $data $pos [expr {$pos + $size - 1}]]
+            incr pos $size
+            set chunk [format %x [string length $payload]]\r\n$payload\r\n
+            yield $chunk
+            if {![string length $payload]} {return}
+        }
+    }}
+    set name chunker[incr _chunk_gen_uid]
+    coroutine $name ::apply $lambda $data $size
+    return $name
+}
+
+proc get-chunks {data {compression gzip}} {
+    switch -exact -- $compression {
+        gzip     { set data [zlib gzip $data] }
+        deflate  { set data [zlib deflate $data] }
+        compress { set data [zlib compress $data] }
+    }
+
+    set data ""
+    set chunker [make-chunk-generator $data 512]
+    while {[string length [set chunk [$chunker]]]} {
+        append data $chunk
+    }
+    return $data
+}
+
+proc blow-chunks {data {ochan stdout} {compression gzip}} {
+    switch -exact -- $compression {
+        gzip     { set data [zlib gzip $data] }
+        deflate  { set data [zlib deflate $data] }
+        compress { set data [zlib compress $data] }
+    }
+
+    set chunker [make-chunk-generator $data 512]
+    while {[string length [set chunk [$chunker]]]} {
+        puts -nonewline $ochan $chunk
+    }
+    return
+}
+
+proc mime-type {filename} {
+    switch -exact -- [file extension $filename] {
+        .htm - .html { return {text text/html}}
+        .png { return {binary image/png} }
+        .jpg { return {binary image/jpeg} }
+        .gif { return {binary image/gif} }
+        .css { return {text   text/css} }
+        .xml { return {text   text/xml} }
+        .xhtml {return {text  application/xml+html} }
+        .svg { return {text image/svg+xml} }
+        .txt - .tcl - .c - .h { return {text text/plain}}
+    }
+    return {binary text/plain}
+}
+
+proc Puts {chan s} {puts $chan $s; puts $s}
+
+proc Service {chan addr port} {
+    chan event $chan readable [info coroutine]
+    while {1} {
+        set meta {}
+        chan configure $chan -buffering line -encoding iso8859-1 -translation crlf
+        chan configure $chan -blocking 0
+        yield
+        while {[gets $chan line] < 0} {
+            if {[eof $chan]} {chan event $chan readable {}; close $chan; return}
+            yield
+        }
+        if {[eof $chan]} {chan event $chan readable {}; close $chan; return}
+        foreach {req url protocol} {GET {} HTTP/1.1} break
+        regexp {^(\S+)\s+(.*)\s(\S+)?$} $line -> req url protocol
+
+        puts $line
+        while {[gets $chan line] > 0} {
+            if {[regexp {^([^:]+):(.*)$} $line -> key val]} {
+                puts [list $key [string trim $val]]
+                lappend meta [string tolower $key] [string trim $val]
+            }
+            yield
+        }
+
+        set encoding identity
+        set transfer ""
+        set close 1
+        set type text/html
+        set code "404 Not Found"
+        set data "<html><head><title>Error 404</title></head>"
+        append data "<body><h1>Not Found</h1><p>Try again.</p></body></html>"
+
+        if {[scan $url {%[^?]?%s} path query] < 2} {
+            set query ""
+        }
+
+        switch -exact -- $req {
+            GET - HEAD {
+            }
+            POST {
+                # Read the query.
+                set qlen [dict get? $meta content-length]
+                if {[string is integer -strict $qlen]} {
+                    chan configure $chan -buffering none -translation binary
+                    while {[string length $query] < $qlen} {
+                        append query [read $chan $qlen]
+                        if {[string length $query] < $qlen} {yield}
+                    }
+                    # Check for excess query bytes [Bug 2715421]
+                    if {[dict get? $meta x-check-query] eq "yes"} {
+                        chan configure $chan -blocking 0
+                        append query [read $chan]
+                    }
+                }
+            }
+            default {
+                # invalid request error 5??
+            }
+        }
+        if {$query ne ""} {puts $query}
+
+        set path [string trimleft $path /]
+        set path [file join [pwd] $path]
+        if {[file exists $path] && [file isfile $path]} {
+            foreach {what type} [mime-type $path] break
+            set f [open $path r]
+            if {$what eq "binary"} {chan configure $f -translation binary}
+            set data [read $f]
+            close $f
+            set code "200 OK"
+            set close [expr {[dict get? $meta connection] eq "close"}]
+        }
+
+        if {$protocol eq "HTTP/1.1"} {
+	    foreach enc [split [dict get? $meta accept-encoding] ,] {
+		set enc [string trim $enc]
+		if {$enc in {deflate gzip compress}} {
+		    set encoding $enc
+		    break
+		}
+	    }
+            set transfer chunked
+        } else {
+            set close 1
+        }
+
+        foreach pair [split $query &] {
+            if {[scan $pair {%[^=]=%s} key val] != 2} {set val ""}
+            switch -exact -- $key {
+                close        {set close 1 ; set transfer 0}
+                transfer     {set transfer $val}
+                content-type {set type $val}
+            }
+        }
+
+        chan configure $chan -buffering line -encoding iso8859-1 -translation crlf
+        Puts $chan "$protocol $code"
+        Puts $chan "content-type: $type"
+        Puts $chan [format "x-crc32: %08x" [zlib crc32 $data]]
+        if {$req eq "POST"} {
+            Puts $chan [format "x-query-length: %d" [string length $query]]
+        }
+        if {$close} {
+            Puts $chan "connection: close"
+        }
+	Puts $chan "x-requested-encodings: [dict get? $meta accept-encoding]"
+        if {$encoding eq "identity"} {
+            Puts $chan "content-length: [string length $data]"
+        } else {
+            Puts $chan "content-encoding: $encoding"
+        }
+        if {$transfer eq "chunked"} {
+            Puts $chan "transfer-encoding: chunked"
+        }
+        puts $chan ""
+        flush $chan
+
+        chan configure $chan -buffering full -translation binary
+        if {$transfer eq "chunked"} {
+            blow-chunks $data $chan $encoding
+        } elseif {$encoding ne "identity"} {
+            puts -nonewline $chan [zlib $encoding $data]
+        } else {
+            puts -nonewline $chan $data
+        }
+
+        if {$close} {
+            chan event $chan readable {}
+            close $chan
+            puts "close $chan"
+            return
+        } else {
+            flush $chan
+        }
+        puts "pipeline $chan"
+    }
+}
+
+proc Accept {chan addr port} {
+    coroutine client$chan Service $chan $addr $port
+    return
+}
+
+proc Control {chan} {
+    if {[gets $chan line] != -1} {
+        if {[string trim $line] eq "quit"} {
+            set ::forever 1
+        }
+    }
+    if {[eof $chan]} {
+        chan event $chan readable {}
+    }
+}
+
+proc Main {{port 0}} {
+    set server [socket -server Accept -myaddr localhost $port]
+    puts [chan configure $server -sockname]
+    flush stdout
+    chan event stdin readable [list Control stdin]
+    vwait ::forever
+    close $server
+    return "done"
+}
+
+if {!$tcl_interactive} {
+    set r [catch [linsert $argv 0 Main] err]
+    if {$r} {puts stderr $errorInfo} elseif {[string length $err]} {puts $err}
+    exit $r
+}
diff --git a/tests/httpold.test b/tests/httpold.test
new file mode 100644
index 0000000..aeba311
--- /dev/null
+++ b/tests/httpold.test
@@ -0,0 +1,293 @@
+# Commands covered:  http_config, http_get, http_wait, http_reset
+#
+# This file contains a collection of tests for the http script library.
+# Sourcing this file into Tcl runs the tests and
+# generates output for errors.  No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994-1996 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+    package require tcltest
+    namespace import -force ::tcltest::*
+}
+
+if {[catch {package require http 1.0}]} {
+    if {[info exists httpold]} {
+	catch {puts "Cannot load http 1.0 package"}
+	::tcltest::cleanupTests
+	return
+    } else {
+	catch {puts "Running http 1.0 tests in slave interp"}
+	set interp [interp create httpold]
+	$interp eval [list set httpold "running"]
+	$interp eval [list set argv $argv]
+	$interp eval [list source [info script]]
+	interp delete $interp
+	::tcltest::cleanupTests
+	return
+    }
+}
+
+set bindata "This is binary data\x0d\x0amore\x0dmore\x0amore\x00null"
+catch {unset data}
+
+## 
+## The httpd script implement a stub http server
+##
+source [file join [file dirname [info script]] httpd]
+
+set port 8010
+if [catch {httpd_init $port} listen] {
+    puts "Cannot start http server, http test skipped"
+    unset port
+    ::tcltest::cleanupTests
+    return
+}
+
+test httpold-1.1 {http_config} {
+    http_config
+} {-accept */* -proxyfilter httpProxyRequired -proxyhost {} -proxyport {} -useragent {Tcl http client package 1.0}}
+
+test httpold-1.2 {http_config} {
+    http_config -proxyfilter
+} httpProxyRequired
+
+test httpold-1.3 {http_config} {
+    catch {http_config -junk}
+} 1
+
+test httpold-1.4 {http_config} {
+    http_config -proxyhost nowhere.come -proxyport 8080 -proxyfilter myFilter -useragent "Tcl Test Suite"
+    set x [http_config]
+    http_config -proxyhost {} -proxyport {} -proxyfilter httpProxyRequired \
+	-useragent "Tcl http client package 1.0"
+    set x
+} {-accept */* -proxyfilter myFilter -proxyhost nowhere.come -proxyport 8080 -useragent {Tcl Test Suite}}
+
+test httpold-1.5 {http_config} {
+    catch {http_config -proxyhost {} -junk 8080}
+} 1
+
+test httpold-2.1 {http_reset} {
+    catch {http_reset http#1}
+} 0
+
+test httpold-3.1 {http_get} {
+    catch {http_get -bogus flag}
+} 1
+test httpold-3.2 {http_get} {
+    catch {http_get http:junk} err
+    set err
+} {Unsupported URL: http:junk}
+
+set url [info hostname]:$port
+test httpold-3.3 {http_get} {
+    set token [http_get $url]
+    http_data $token
+} "<html><head><title>HTTP/1.0 TEST</title></head><body>
+<h1>Hello, World!</h1>
+<h2>GET /</h2>
+</body></html>"
+
+set tail /a/b/c
+set url [info hostname]:$port/a/b/c
+set binurl [info hostname]:$port/binary
+
+test httpold-3.4 {http_get} {
+    set token [http_get $url]
+    http_data $token
+} "<html><head><title>HTTP/1.0 TEST</title></head><body>
+<h1>Hello, World!</h1>
+<h2>GET $tail</h2>
+</body></html>"
+
+proc selfproxy {host} {
+    global port
+    return [list [info hostname] $port]
+}
+test httpold-3.5 {http_get} {
+    http_config -proxyfilter selfproxy
+    set token [http_get $url]
+    http_config -proxyfilter httpProxyRequired
+    http_data $token
+} "<html><head><title>HTTP/1.0 TEST</title></head><body>
+<h1>Hello, World!</h1>
+<h2>GET http://$url</h2>
+</body></html>"
+
+test httpold-3.6 {http_get} {
+    http_config -proxyfilter bogus
+    set token [http_get $url]
+    http_config -proxyfilter httpProxyRequired
+    http_data $token
+} "<html><head><title>HTTP/1.0 TEST</title></head><body>
+<h1>Hello, World!</h1>
+<h2>GET $tail</h2>
+</body></html>"
+
+test httpold-3.7 {http_get} {
+    set token [http_get $url -headers {Pragma no-cache}]
+    http_data $token
+} "<html><head><title>HTTP/1.0 TEST</title></head><body>
+<h1>Hello, World!</h1>
+<h2>GET $tail</h2>
+</body></html>"
+
+test httpold-3.8 {http_get} {
+    set token [http_get $url -query Name=Value&Foo=Bar]
+    http_data $token
+} "<html><head><title>HTTP/1.0 TEST</title></head><body>
+<h1>Hello, World!</h1>
+<h2>POST $tail</h2>
+<h2>Query</h2>
+<dl>
+<dt>Name<dd>Value
+<dt>Foo<dd>Bar
+</dl>
+</body></html>"
+
+test httpold-3.9 {http_get} {
+    set token [http_get $url -validate 1]
+    http_code $token
+} "HTTP/1.0 200 OK"
+
+
+test httpold-4.1 {httpEvent} {
+    set token [http_get $url]
+    upvar #0 $token data
+    array set meta $data(meta)
+    expr ($data(totalsize) == $meta(Content-Length))
+} 1
+
+test httpold-4.2 {httpEvent} {
+    set token [http_get $url]
+    upvar #0 $token data
+    array set meta $data(meta)
+    string compare $data(type) [string trim $meta(Content-Type)]
+} 0
+
+test httpold-4.3 {httpEvent} {
+    set token [http_get $url]
+    http_code $token
+} {HTTP/1.0 200 Data follows}
+
+test httpold-4.4 {httpEvent} {
+    set testfile [makeFile "" testfile]
+    set out [open $testfile w]
+    set token [http_get $url -channel $out]
+    close $out
+    set in [open $testfile]
+    set x [read $in]
+    close $in
+    removeFile $testfile
+    set x
+} "<html><head><title>HTTP/1.0 TEST</title></head><body>
+<h1>Hello, World!</h1>
+<h2>GET $tail</h2>
+</body></html>"
+
+test httpold-4.5 {httpEvent} {
+    set testfile [makeFile "" testfile]
+    set out [open $testfile w]
+    set token [http_get $url -channel $out]
+    close $out
+    upvar #0 $token data
+    removeFile $testfile
+    expr $data(currentsize) == $data(totalsize)
+} 1
+
+test httpold-4.6 {httpEvent} {
+    set testfile [makeFile "" testfile]
+    set out [open $testfile w]
+    set token [http_get $binurl -channel $out]
+    close $out
+    set in [open $testfile]
+    fconfigure $in -translation binary
+    set x [read $in]
+    close $in
+    removeFile $testfile
+    set x
+} "$bindata$binurl"
+
+proc myProgress {token total current} {
+    global progress httpLog
+    if {[info exists httpLog] && $httpLog} {
+	puts "progress $total $current"
+    }
+    set progress [list $total $current]
+}
+if 0 {
+    # This test hangs on Windows95 because the client never gets EOF
+    set httpLog 1
+    test httpold-4.6 {httpEvent} {
+	set token [http_get $url -blocksize 50 -progress myProgress]
+	set progress
+    } {111 111}
+}
+test httpold-4.7 {httpEvent} {
+    set token [http_get $url -progress myProgress]
+    set progress
+} {111 111}
+test httpold-4.8 {httpEvent} {
+    set token [http_get $url]
+    http_status $token
+} {ok}
+test httpold-4.9 {httpEvent} {
+    set token [http_get $url -progress myProgress]
+    http_code $token
+} {HTTP/1.0 200 Data follows}
+test httpold-4.10 {httpEvent} {
+    set token [http_get $url -progress myProgress]
+    http_size $token
+} {111}
+test httpold-4.11 {httpEvent} {
+    set token [http_get $url -timeout 1 -command {#}]
+    http_reset $token
+    http_status $token
+} {reset}
+test httpold-4.12 {httpEvent} {
+    update
+    set x {}
+    after 500 {lappend x ok}
+    set token [http_get $url -timeout 1 -command {lappend x fail}]
+    vwait x
+    list [http_status $token] $x
+} {timeout ok}
+
+test httpold-5.1 {http_formatQuery} {
+    http_formatQuery name1 value1 name2 "value two"
+} {name1=value1&name2=value+two}
+
+test httpold-5.2 {http_formatQuery} {
+    http_formatQuery name1 ~bwelch name2 \xa1\xa2\xa2
+} {name1=%7ebwelch&name2=%a1%a2%a2}
+
+test httpold-5.3 {http_formatQuery} {
+    http_formatQuery lines "line1\nline2\nline3"
+} {lines=line1%0d%0aline2%0d%0aline3}
+
+test httpold-6.1 {httpProxyRequired} {
+    update
+    http_config -proxyhost [info hostname] -proxyport $port
+    set token [http_get $url]
+    http_wait $token
+    http_config -proxyhost {} -proxyport {}
+    upvar #0 $token data
+    set data(body)
+} "<html><head><title>HTTP/1.0 TEST</title></head><body>
+<h1>Hello, World!</h1>
+<h2>GET http://$url</h2>
+</body></html>"
+
+# cleanup
+catch {unset url}
+catch {unset port}
+catch {unset data}
+close $listen
+::tcltest::cleanupTests
+return
diff --git a/tests/if-old.test b/tests/if-old.test
new file mode 100644
index 0000000..fbcf56c
--- /dev/null
+++ b/tests/if-old.test
@@ -0,0 +1,162 @@
+# Commands covered:  if
+#
+# This file contains the original set of tests for Tcl's if command.
+# Since the if command is now compiled, a new set of tests covering
+# the new implementation is in the file "if.test". Sourcing this file
+# into Tcl runs the tests and generates output for errors.
+# No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994-1996 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+    package require tcltest
+    namespace import -force ::tcltest::*
+}
+
+test if-old-1.1 {taking proper branch} {
+    set a {}
+    if 0 {set a 1} else {set a 2}
+    set a
+} 2
+test if-old-1.2 {taking proper branch} {
+    set a {}
+    if 1 {set a 1} else {set a 2}
+    set a
+} 1
+test if-old-1.3 {taking proper branch} {
+    set a {}
+    if 1<2 {set a 1}
+    set a
+} 1
+test if-old-1.4 {taking proper branch} {
+    set a {}
+    if 1>2 {set a 1}
+    set a
+} {}
+test if-old-1.5 {taking proper branch} {
+    set a {}
+    if 0 {set a 1} else {}
+    set a
+} {}
+test if-old-1.6 {taking proper branch} {
+    set a {}
+    if 0 {set a 1} elseif 1 {set a 2} elseif 1 {set a 3} else {set a 4}
+    set a
+} {2}
+test if-old-1.7 {taking proper branch} {
+    set a {}
+    if 0 {set a 1} elseif 0 {set a 2} elseif 1 {set a 3} else {set a 4}
+    set a
+} {3}
+test if-old-1.8 {taking proper branch} {
+    set a {}
+    if 0 {set a 1} elseif 0 {set a 2} elseif 0 {set a 3} else {set a 4}
+    set a
+} {4}
+test if-old-1.9 {taking proper branch, multiline test expr} {
+    set a {}
+    if {($tcl_platform(platform) != "foobar1") && \
+	($tcl_platform(platform) != "foobar2")} {set a 3} else {set a 4}
+    set a
+} {3}
+
+
+test if-old-2.1 {optional then-else args} {
+    set a 44
+    if 0 then {set a 1} elseif 0 then {set a 3} else {set a 2}
+    set a
+} 2
+test if-old-2.2 {optional then-else args} {
+    set a 44
+    if 1 then {set a 1} else {set a 2}
+    set a
+} 1
+test if-old-2.3 {optional then-else args} {
+    set a 44
+    if 0 {set a 1} else {set a 2}
+    set a
+} 2
+test if-old-2.4 {optional then-else args} {
+    set a 44
+    if 1 {set a 1} else {set a 2}
+    set a
+} 1
+test if-old-2.5 {optional then-else args} {
+    set a 44
+    if 0 then {set a 1} {set a 2}
+    set a
+} 2
+test if-old-2.6 {optional then-else args} {
+    set a 44
+    if 1 then {set a 1} {set a 2}
+    set a
+} 1
+test if-old-2.7 {optional then-else args} {
+    set a 44
+    if 0 then {set a 1} else {set a 2}
+    set a
+} 2
+test if-old-2.8 {optional then-else args} {
+    set a 44
+    if 0 then {set a 1} elseif 0 {set a 2} elseif 0 {set a 3} {set a 4}
+    set a
+} 4
+
+test if-old-3.1 {return value} {
+    if 1 then {set a 22; concat abc}
+} abc
+test if-old-3.2 {return value} {
+    if 0 then {set a 22; concat abc} elseif 1 {concat def} {concat ghi}
+} def
+test if-old-3.3 {return value} {
+    if 0 then {set a 22; concat abc} else {concat def}
+} def
+test if-old-3.4 {return value} {
+    if 0 then {set a 22; concat abc}
+} {}
+test if-old-3.5 {return value} {
+    if 0 then {set a 22; concat abc} elseif 0 {concat def}
+} {}
+
+test if-old-4.1 {error conditions} {
+    list [catch {if} msg] $msg
+} {1 {wrong # args: no expression after "if" argument}}
+test if-old-4.2 {error conditions} {
+    list [catch {if {[error "error in condition"]} foo} msg] $msg
+} {1 {error in condition}}
+test if-old-4.3 {error conditions} {
+    list [catch {if 2} msg] $msg
+} {1 {wrong # args: no script following "2" argument}}
+test if-old-4.4 {error conditions} {
+    list [catch {if 2 then} msg] $msg
+} {1 {wrong # args: no script following "then" argument}}
+test if-old-4.5 {error conditions} {
+    list [catch {if 2 the} msg] $msg
+} {1 {invalid command name "the"}}
+test if-old-4.6 {error conditions} {
+    list [catch {if 2 then {[error "error in then clause"]}} msg] $msg
+} {1 {error in then clause}}
+test if-old-4.7 {error conditions} {
+    list [catch {if 0 then foo elseif} msg] $msg
+} {1 {wrong # args: no expression after "elseif" argument}}
+test if-old-4.8 {error conditions} {
+    list [catch {if 0 then foo elsei} msg] $msg
+} {1 {invalid command name "elsei"}}
+test if-old-4.9 {error conditions} {
+    list [catch {if 0 then foo elseif 0 bar else} msg] $msg
+} {1 {wrong # args: no script following "else" argument}}
+test if-old-4.10 {error conditions} {
+    list [catch {if 0 then foo elseif 0 bar els} msg] $msg
+} {1 {invalid command name "els"}}
+test if-old-4.11 {error conditions} {
+    list [catch {if 0 then foo elseif 0 bar else {[error "error in else clause"]}} msg] $msg
+} {1 {error in else clause}}
+
+# cleanup
+::tcltest::cleanupTests
+return
diff --git a/tests/if.test b/tests/if.test
new file mode 100644
index 0000000..040364a
--- /dev/null
+++ b/tests/if.test
@@ -0,0 +1,1282 @@
+# Commands covered:  if
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands.  Sourcing this file into Tcl runs the tests and
+# generates output for errors.  No output means no errors were found.
+#
+# Copyright (c) 1996 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+    package require tcltest 2
+    namespace import -force ::tcltest::*
+}
+
+# Basic "if" operation.
+
+catch {unset a}
+test if-1.1 {TclCompileIfCmd: missing if/elseif test} -body {
+    if
+} -returnCodes error -result {wrong # args: no expression after "if" argument}
+test if-1.2 {TclCompileIfCmd: error in if/elseif test} -body {
+    if {[error "error in condition"]} foo
+} -returnCodes error -result {error in condition}
+test if-1.3 {TclCompileIfCmd: error in if/elseif test} -body {
+    list [catch {if {1+}} msg] $msg $::errorInfo
+} -match glob -cleanup {
+    unset msg
+} -result {1 * {*"if {1+}"}}
+test if-1.4 {TclCompileIfCmd: if/elseif test in braces} -body {
+    set a {}
+    if {1<2} {set a 1}
+    return $a
+} -cleanup {
+    unset a
+} -result {1}
+test if-1.5 {TclCompileIfCmd: if/elseif test not in braces} -body {
+    set a {}
+    if 1<2 {set a 1}
+    return $a
+} -cleanup {
+    unset a
+} -result {1}
+test if-1.6 {TclCompileIfCmd: multiline test expr} -setup {
+    set a {}
+} -body {
+    if {($tcl_platform(platform) != "foobar1") && \
+	($tcl_platform(platform) != "foobar2")} {set a 3} else {set a 4}
+    return $a
+} -cleanup {
+    unset a
+} -result 3
+test if-1.7 {TclCompileIfCmd: "then" after if/elseif test} -body {
+    set a {}
+    if 4>3 then {set a 1}
+    return $a
+} -cleanup {
+    unset a
+} -result {1}
+test if-1.8 {TclCompileIfCmd: keyword other than "then" after if/elseif test} -setup {
+    set a {}
+} -body {
+    if 1<2 therefore {set a 1}
+} -cleanup {
+    unset a
+} -returnCodes error -result {invalid command name "therefore"}
+test if-1.9 {TclCompileIfCmd: missing "then" body} -setup {
+    set a {}
+} -body {
+    if 1<2 then
+} -cleanup {
+    unset a
+} -returnCodes error -result {wrong # args: no script following "then" argument}
+test if-1.10 {TclCompileIfCmd: error in "then" body} -body {
+    set a {}
+    list [catch {if {$a!="xxx"} then {set}} msg] $msg $::errorInfo
+} -match glob -cleanup {
+    unset a msg
+} -result {1 {wrong # args: should be "set varName ?newValue?"} {wrong # args: should be "set varName ?newValue?"
+    while *ing
+"set"*}}
+test if-1.11 {TclCompileIfCmd: error in "then" body} -body {
+    if 2 then {[error "error in then clause"]}
+} -returnCodes error -result {error in then clause}
+test if-1.12 {TclCompileIfCmd: "then" body in quotes} -body {
+    set a {}
+    if 27>17 "append a x"
+    return $a
+} -cleanup {
+    unset a
+} -result {x}
+test if-1.13 {TclCompileIfCmd: computed "then" body} -setup {
+    catch {unset x1}
+    catch {unset x2}
+} -body {
+    set x1 {append a x1}
+    set x2 {; append a x2}
+    set a {}
+    if 1 $x1$x2
+    return $a
+} -cleanup {
+    unset a x1 x2
+} -result {x1x2}
+test if-1.14 {TclCompileIfCmd: taking proper branch} -body {
+    set a {}
+    if 1<2 {set a 1}
+    return $a
+} -cleanup {
+    unset a
+} -result 1
+test if-1.15 {TclCompileIfCmd: taking proper branch} -body {
+    set a {}
+    if 1>2 {set a 1}
+    return $a
+} -cleanup {
+    unset a
+} -result {}
+test if-1.16 {TclCompileIfCmd: test jumpFalse instruction replacement after long "then" body} -setup {
+    catch {unset i}
+    set a {}
+} -body {
+    if 1<2 {
+	set a 1
+	while {$a != "xxx"} {
+	    break;
+	    while {$i >= 0} {
+		if {[string compare $a "bar"] < 0} {
+		    set i $i
+		    set i [lindex $s $i]
+		}
+		if {[string compare $a "bar"] < 0} {
+		    set i $i
+		    set i [lindex $s $i]
+		}
+		if {[string compare $a "bar"] < 0} {
+		    set i $i
+		    set i [lindex $s $i]
+		}
+		if {[string compare $a "bar"] < 0} {
+		    set i $i
+		    set i [lindex $s $i]
+		}
+		set i [expr $i-1]
+	    }
+	}
+	set a 2
+	while {$a != "xxx"} {
+	    break;
+	    while {$i >= 0} {
+		if {[string compare $a "bar"] < 0} {
+		    set i $i
+		    set i [lindex $s $i]
+		}
+		if {[string compare $a "bar"] < 0} {
+		    set i $i
+		    set i [lindex $s $i]
+		}
+		if {[string compare $a "bar"] < 0} {
+		    set i $i
+		    set i [lindex $s $i]
+		}
+		if {[string compare $a "bar"] < 0} {
+		    set i $i
+		    set i [lindex $s $i]
+		}
+		set i [expr $i-1]
+	    }
+	}
+	set a 3
+    }
+    return $a
+} -cleanup {
+    unset a
+    unset -nocomplain i
+} -result 3
+test if-1.17 {TclCompileIfCmd: if/elseif test in quotes} -setup {
+    set a {}
+} -body {
+    if {"0 < 3"} {set a 1}
+} -returnCodes error -cleanup {
+    unset a
+} -result {expected boolean value but got "0 < 3"}
+
+test if-2.1 {TclCompileIfCmd: "elseif" after if/elseif test} -setup {
+    set a {}
+} -body {
+    if 3>4 {set a 1} elseif 1 {set a 2}
+    return $a
+} -cleanup {
+    unset a
+} -result {2}
+# Since "else" is optional, the "elwood" below is treated as a command.
+# But then there shouldn't be any additional argument words for the "if".
+test if-2.2 {TclCompileIfCmd: keyword other than "elseif"} -setup {
+    set a {}
+} -body {
+    if 1<2 {set a 1} elwood {set a 2}
+} -returnCodes error -cleanup {
+    unset a
+} -result {wrong # args: extra words after "else" clause in "if" command}
+test if-2.3 {TclCompileIfCmd: missing expression after "elseif"} -setup {
+    set a {}
+} -body {
+    if 1<2 {set a 1} elseif
+} -returnCodes error -cleanup {
+    unset a
+} -result {wrong # args: no expression after "elseif" argument}
+test if-2.4 {TclCompileIfCmd: error in expression after "elseif"} -setup {
+    set a {}
+} -body {
+    list [catch {if 3>4 {set a 1} elseif {1>}} msg] $msg $::errorInfo
+} -match glob -cleanup {
+    unset a msg
+} -result {1 * {*"if 3>4 {set a 1} elseif {1>}"}}
+test if-2.5 {TclCompileIfCmd: test jumpFalse instruction replacement after long "elseif" body} -setup {
+    catch {unset i}
+    set a {}
+} -body {
+    if 1>2 {
+	set a 1
+	while {$a != "xxx"} {
+	    break;
+	    while {$i >= 0} {
+		if {[string compare $a "bar"] < 0} {
+		    set i $i
+		    set i [lindex $s $i]
+		}
+		if {[string compare $a "bar"] < 0} {
+		    set i $i
+		    set i [lindex $s $i]
+		}
+		if {[string compare $a "bar"] < 0} {
+		    set i $i
+		    set i [lindex $s $i]
+		}
+		if {[string compare $a "bar"] < 0} {
+		    set i $i
+		    set i [lindex $s $i]
+		}
+		set i [expr $i-1]
+	    }
+	}
+	set a 2
+	while {$a != "xxx"} {
+	    break;
+	    while {$i >= 0} {
+		if {[string compare $a "bar"] < 0} {
+		    set i $i
+		    set i [lindex $s $i]
+		}
+		if {[string compare $a "bar"] < 0} {
+		    set i $i
+		    set i [lindex $s $i]
+		}
+		if {[string compare $a "bar"] < 0} {
+		    set i $i
+		    set i [lindex $s $i]
+		}
+		if {[string compare $a "bar"] < 0} {
+		    set i $i
+		    set i [lindex $s $i]
+		}
+		set i [expr $i-1]
+	    }
+	}
+	set a 3
+    } elseif 1<2 then { #; this if arm should be taken
+	set a 4
+	while {$a != "xxx"} {
+	    break;
+	    while {$i >= 0} {
+		if {[string compare $a "bar"] < 0} {
+		    set i $i
+		    set i [lindex $s $i]
+		}
+		if {[string compare $a "bar"] < 0} {
+		    set i $i
+		    set i [lindex $s $i]
+		}
+		if {[string compare $a "bar"] < 0} {
+		    set i $i
+		    set i [lindex $s $i]
+		}
+		if {[string compare $a "bar"] < 0} {
+		    set i $i
+		    set i [lindex $s $i]
+		}
+		set i [expr $i-1]
+	    }
+	}
+	set a 5
+	while {$a != "xxx"} {
+	    break;
+	    while {$i >= 0} {
+		if {[string compare $a "bar"] < 0} {
+		    set i $i
+		    set i [lindex $s $i]
+		}
+		if {[string compare $a "bar"] < 0} {
+		    set i $i
+		    set i [lindex $s $i]
+		}
+		if {[string compare $a "bar"] < 0} {
+		    set i $i
+		    set i [lindex $s $i]
+		}
+		if {[string compare $a "bar"] < 0} {
+		    set i $i
+		    set i [lindex $s $i]
+		}
+		set i [expr $i-1]
+	    }
+	}
+	set a 6
+    }
+    return $a
+} -cleanup {
+    unset a
+    unset -nocomplain i
+} -result 6
+
+test if-3.1 {TclCompileIfCmd: "else" clause} -body {
+    set a {}
+    if 3>4 {set a 1} elseif {$a == "foo"} {set a 2} else {set a 3}
+    return $a
+} -cleanup {
+    unset a
+} -result 3
+# Since "else" is optional, the "elsex" below is treated as a command.
+# But then there shouldn't be any additional argument words for the "if".
+test if-3.2 {TclCompileIfCmd: keyword other than "else"} -setup {
+    set a {}
+} -body {
+    if 1<2 then {set a 1} elsex {set a 2}
+} -returnCodes error -cleanup {
+    unset a
+} -result {wrong # args: extra words after "else" clause in "if" command}
+test if-3.3 {TclCompileIfCmd: missing body after "else"} -setup {
+    set a {}
+} -body {
+    if 2<1 {set a 1} else
+} -returnCodes error -cleanup {
+    unset a
+} -result {wrong # args: no script following "else" argument}
+test if-3.4 {TclCompileIfCmd: error compiling body after "else"} -setup {
+    set a {}
+} -body {
+    catch {if 2<1 {set a 1} else {set}}
+    set ::errorInfo
+} -match glob -cleanup {
+    unset a
+} -result {wrong # args: should be "set varName ?newValue?"
+    while *ing
+"set"*}
+test if-3.5 {TclCompileIfCmd: extra arguments after "else" argument} -setup {
+    set a {}
+} -body {
+    if 2<1 {set a 1} else {set a 2} or something
+} -returnCodes error -cleanup {
+    unset a
+} -result {wrong # args: extra words after "else" clause in "if" command}
+# The following test also checks whether contained loops and other
+# commands are properly relocated because a short jump must be replaced
+# by a "long distance" one.
+test if-3.6 {TclCompileIfCmd: test jumpFalse instruction replacement after long "else" clause} -setup {
+    catch {unset i}
+    set a {}
+} -body {
+    if 1>2 {
+	set a 1
+	while {$a != "xxx"} {
+	    break;
+	    while {$i >= 0} {
+		if {[string compare $a "bar"] < 0} {
+		    set i $i
+		    set i [lindex $s $i]
+		}
+		if {[string compare $a "bar"] < 0} {
+		    set i $i
+		    set i [lindex $s $i]
+		}
+		if {[string compare $a "bar"] < 0} {
+		    set i $i
+		    set i [lindex $s $i]
+		}
+		if {[string compare $a "bar"] < 0} {
+		    set i $i
+		    set i [lindex $s $i]
+		}
+		set i [expr $i-1]
+	    }
+	}
+	set a 2
+	while {$a != "xxx"} {
+	    break;
+	    while {$i >= 0} {
+		if {[string compare $a "bar"] < 0} {
+		    set i $i
+		    set i [lindex $s $i]
+		}
+		if {[string compare $a "bar"] < 0} {
+		    set i $i
+		    set i [lindex $s $i]
+		}
+		if {[string compare $a "bar"] < 0} {
+		    set i $i
+		    set i [lindex $s $i]
+		}
+		if {[string compare $a "bar"] < 0} {
+		    set i $i
+		    set i [lindex $s $i]
+		}
+		set i [expr $i-1]
+	    }
+	}
+	set a 3
+    } elseif 1==2 then { #; this if arm should be taken
+	set a 4
+	while {$a != "xxx"} {
+	    break;
+	    while {$i >= 0} {
+		if {[string compare $a "bar"] < 0} {
+		    set i $i
+		    set i [lindex $s $i]
+		}
+		if {[string compare $a "bar"] < 0} {
+		    set i $i
+		    set i [lindex $s $i]
+		}
+		if {[string compare $a "bar"] < 0} {
+		    set i $i
+		    set i [lindex $s $i]
+		}
+		if {[string compare $a "bar"] < 0} {
+		    set i $i
+		    set i [lindex $s $i]
+		}
+		set i [expr $i-1]
+	    }
+	}
+	set a 5
+	while {$a != "xxx"} {
+	    break;
+	    while {$i >= 0} {
+		if {[string compare $a "bar"] < 0} {
+		    set i $i
+		    set i [lindex $s $i]
+		}
+		if {[string compare $a "bar"] < 0} {
+		    set i $i
+		    set i [lindex $s $i]
+		}
+		if {[string compare $a "bar"] < 0} {
+		    set i $i
+		    set i [lindex $s $i]
+		}
+		if {[string compare $a "bar"] < 0} {
+		    set i $i
+		    set i [lindex $s $i]
+		}
+		set i [expr $i-1]
+	    }
+	}
+	set a 6
+    } else {
+	set a 7
+	while {$a != "xxx"} {
+	    break;
+	    while {$i >= 0} {
+		if {[string compare $a "bar"] < 0} {
+		    set i $i
+		    set i [lindex $s $i]
+		}
+		if {[string compare $a "bar"] < 0} {
+		    set i $i
+		    set i [lindex $s $i]
+		}
+		if {[string compare $a "bar"] < 0} {
+		    set i $i
+		    set i [lindex $s $i]
+		}
+		if {[string compare $a "bar"] < 0} {
+		    set i $i
+		    set i [lindex $s $i]
+		}
+		set i [expr $i-1]
+	    }
+	}
+	set a 8
+	while {$a != "xxx"} {
+	    break;
+	    while {$i >= 0} {
+		if {[string compare $a "bar"] < 0} {
+		    set i $i
+		    set i [lindex $s $i]
+		}
+		if {[string compare $a "bar"] < 0} {
+		    set i $i
+		    set i [lindex $s $i]
+		}
+		if {[string compare $a "bar"] < 0} {
+		    set i $i
+		    set i [lindex $s $i]
+		}
+		if {[string compare $a "bar"] < 0} {
+		    set i $i
+		    set i [lindex $s $i]
+		}
+		set i [expr $i-1]
+	    }
+	}
+	set a 9
+    }
+    return $a
+} -cleanup {
+    unset a
+    unset -nocomplain i
+} -result 9
+
+test if-4.1 {TclCompileIfCmd: "if" command result} -setup {
+    set a {}
+} -body {
+    set a [if 3<4 {set i 27}]
+    return $a
+} -cleanup {
+    unset a
+    unset -nocomplain i
+} -result 27
+test if-4.2 {TclCompileIfCmd: "if" command result} -setup {
+    set a {}
+} -body {
+    set a [if 3>4 {set i 27}]
+    return $a
+} -cleanup {
+    unset a
+    unset -nocomplain i
+} -result {}
+test if-4.3 {TclCompileIfCmd: "if" command result} -setup {
+    set a {}
+} -body {
+    set a [if 0 {set i 1} elseif 1 {set i 2}]
+    return $a
+} -cleanup {
+    unset a
+    unset -nocomplain i
+} -result 2
+test if-4.4 {TclCompileIfCmd: "if" command result} -setup {
+    set a {}
+} -body {
+    set a [if 0 {set i 1} elseif 0 {set i 2} elseif 2>5 {set i 3} else {set i 4}]
+    return $a
+} -cleanup {
+    unset a i
+} -result 4
+test if-4.5 {TclCompileIfCmd: return value} -body {
+    if 0 then {set a 22; concat abc} elseif 1 {concat def} {concat ghi}
+} -cleanup {
+    unset -nocomplain a
+} -result def
+
+# Check "if" and computed command names.
+
+test if-5.1 {if cmd with computed command names: missing if/elseif test} -body {
+    set z if
+    $z
+} -returnCodes error -cleanup {
+    unset z
+} -result {wrong # args: no expression after "if" argument}
+test if-5.2 {if cmd with computed command names: error in if/elseif test} -body {
+    set z if
+    $z {[error "error in condition"]} foo
+} -returnCodes error -cleanup {
+    unset z
+} -result {error in condition}
+test if-5.3 {if cmd with computed command names: error in if/elseif test} -body {
+    set z if
+    list [catch {$z {1+}}] $::errorInfo
+} -match glob -cleanup {
+    unset z
+} -result {1 {*"$z {1+}"}}
+test if-5.4 {if cmd with computed command names: if/elseif test in braces} -setup {
+    set a {}
+} -body {
+    set z if
+    $z {1<2} {set a 1}
+    return $a
+} -cleanup {
+    unset a z
+} -result {1}
+test if-5.5 {if cmd with computed command names: if/elseif test not in braces} -setup {
+    set a {}
+} -body {
+    set z if
+    $z 1<2 {set a 1}
+    return $a
+} -cleanup {
+    unset a z
+} -result {1}
+test if-5.6 {if cmd with computed command names: multiline test expr} -body {
+    set z if
+    $z {($tcl_platform(platform) != "foobar1") && \
+	($tcl_platform(platform) != "foobar2")} {set a 3} else {set a 4}
+    return $a
+} -cleanup {
+    unset a z
+} -result 3
+test if-5.7 {if cmd with computed command names: "then" after if/elseif test} -setup {
+    set a {}
+} -body {
+    set z if
+    $z 4>3 then {set a 1}
+    return $a
+} -cleanup {
+    unset a z
+} -result {1}
+test if-5.8 {if cmd with computed command names: keyword other than "then" after if/elseif test} -setup {
+    set a {}
+} -body {
+    set z if
+    $z 1<2 therefore {set a 1}
+} -returnCodes error -cleanup {
+    unset a z
+} -result {invalid command name "therefore"}
+test if-5.9 {if cmd with computed command names: missing "then" body} -setup {
+    set a {}
+} -body {
+    set z if
+    $z 1<2 then
+} -returnCodes error -cleanup {
+    unset a z
+} -result {wrong # args: no script following "then" argument}
+test if-5.10 {if cmd with computed command names: error in "then" body} -body {
+    set z if
+    set a {}
+    list [catch {$z {$a!="xxx"} then {set}} msg] $msg $::errorInfo
+} -match glob -cleanup {
+    unset a z msg
+} -result {1 {wrong # args: should be "set varName ?newValue?"} {wrong # args: should be "set varName ?newValue?"
+    while *ing
+"set"
+    invoked from within
+"$z {$a!="xxx"} then {set}"}}
+test if-5.11 {if cmd with computed command names: error in "then" body} -body {
+    set z if
+    $z 2 then {[error "error in then clause"]}
+} -returnCodes error -cleanup {
+    unset z
+} -result {error in then clause}
+test if-5.12 {if cmd with computed command names: "then" body in quotes} -setup {
+    set a {}
+} -body {
+    set z if
+    $z 27>17 "append a x"
+    return $a
+} -cleanup {
+    unset a z
+} -result {x}
+test if-5.13 {if cmd with computed command names: computed "then" body} -setup {
+    catch {unset x1}
+    catch {unset x2}
+} -body {
+    set z if
+    set x1 {append a x1}
+    set x2 {; append a x2}
+    set a {}
+    $z 1 $x1$x2
+    return $a
+} -cleanup {
+    unset a z x1 x2
+} -result {x1x2}
+test if-5.14 {if cmd with computed command names: taking proper branch} -setup {
+    set a {}
+} -body {
+    set z if
+    $z 1<2 {set a 1}
+    return $a
+} -cleanup {
+    unset a z
+} -result 1
+test if-5.15 {if cmd with computed command names: taking proper branch} -body {
+    set a {}
+    set z if
+    $z 1>2 {set a 1}
+    return $a
+} -cleanup {
+    unset a z
+} -result {}
+test if-5.16 {if cmd with computed command names: test jumpFalse instruction replacement after long "then" body} -setup {
+    catch {unset i}
+    set a {}
+} -body {
+    set z if
+    $z 1<2 {
+	set a 1
+	while {$a != "xxx"} {
+	    break;
+	    while {$i >= 0} {
+		$z {[string compare $a "bar"] < 0} {
+		    set i $i
+		    set i [lindex $s $i]
+		}
+		$z {[string compare $a "bar"] < 0} {
+		    set i $i
+		    set i [lindex $s $i]
+		}
+		$z {[string compare $a "bar"] < 0} {
+		    set i $i
+		    set i [lindex $s $i]
+		}
+		$z {[string compare $a "bar"] < 0} {
+		    set i $i
+		    set i [lindex $s $i]
+		}
+		set i [expr $i-1]
+	    }
+	}
+	set a 2
+	while {$a != "xxx"} {
+	    break;
+	    while {$i >= 0} {
+		$z {[string compare $a "bar"] < 0} {
+		    set i $i
+		    set i [lindex $s $i]
+		}
+		$z {[string compare $a "bar"] < 0} {
+		    set i $i
+		    set i [lindex $s $i]
+		}
+		$z {[string compare $a "bar"] < 0} {
+		    set i $i
+		    set i [lindex $s $i]
+		}
+		$z {[string compare $a "bar"] < 0} {
+		    set i $i
+		    set i [lindex $s $i]
+		}
+		set i [expr $i-1]
+	    }
+	}
+	set a 3
+    }
+    return $a
+} -cleanup {
+    unset a z
+    unset -nocomplain i
+} -result 3
+test if-5.17 {if cmd with computed command names: if/elseif test in quotes} -setup {
+    set a {}
+} -body {
+    set z if
+    $z {"0 < 3"} {set a 1}
+} -returnCodes error -cleanup {
+    unset a z
+} -result {expected boolean value but got "0 < 3"}
+
+test if-6.1 {if cmd with computed command names: "elseif" after if/elseif test} -setup {
+    set a {}
+} -body {
+    set z if
+    $z 3>4 {set a 1} elseif 1 {set a 2}
+    return $a
+} -cleanup {
+    unset a z
+} -result {2}
+# Since "else" is optional, the "elwood" below is treated as a command.
+# But then there shouldn't be any additional argument words for the "if".
+test if-6.2 {if cmd with computed command names: keyword other than "elseif"} -setup {
+    set a {}
+} -body {
+    set z if
+    $z 1<2 {set a 1} elwood {set a 2}
+} -returnCodes error -cleanup {
+    unset a z
+} -result {wrong # args: extra words after "else" clause in "if" command}
+test if-6.3 {if cmd with computed command names: missing expression after "elseif"} -setup {
+    set a {}
+} -body {
+    set z if
+    $z 1<2 {set a 1} elseif
+} -returnCodes error -cleanup {
+    unset a z
+} -result {wrong # args: no expression after "elseif" argument}
+test if-6.4 {if cmd with computed command names: error in expression after "elseif"} -setup {
+    set a {}
+} -body {
+    set z if
+    list [catch {$z 3>4 {set a 1} elseif {1>}}] $::errorInfo
+} -match glob -cleanup {
+    unset a z
+} -result {1 {*"$z 3>4 {set a 1} elseif {1>}"}}
+test if-6.5 {if cmd with computed command names: test jumpFalse instruction replacement after long "elseif" body} -setup {
+    catch {unset i}
+    set a {}
+} -body {
+    set z if
+    $z 1>2 {
+	set a 1
+	while {$a != "xxx"} {
+	    break;
+	    while {$i >= 0} {
+		$z {[string compare $a "bar"] < 0} {
+		    set i $i
+		    set i [lindex $s $i]
+		}
+		$z {[string compare $a "bar"] < 0} {
+		    set i $i
+		    set i [lindex $s $i]
+		}
+		$z {[string compare $a "bar"] < 0} {
+		    set i $i
+		    set i [lindex $s $i]
+		}
+		$z {[string compare $a "bar"] < 0} {
+		    set i $i
+		    set i [lindex $s $i]
+		}
+		set i [expr $i-1]
+	    }
+	}
+	set a 2
+	while {$a != "xxx"} {
+	    break;
+	    while {$i >= 0} {
+		$z {[string compare $a "bar"] < 0} {
+		    set i $i
+		    set i [lindex $s $i]
+		}
+		$z {[string compare $a "bar"] < 0} {
+		    set i $i
+		    set i [lindex $s $i]
+		}
+		$z {[string compare $a "bar"] < 0} {
+		    set i $i
+		    set i [lindex $s $i]
+		}
+		$z {[string compare $a "bar"] < 0} {
+		    set i $i
+		    set i [lindex $s $i]
+		}
+		set i [expr $i-1]
+	    }
+	}
+	set a 3
+    } elseif 1<2 then { #; this if arm should be taken
+	set a 4
+	while {$a != "xxx"} {
+	    break;
+	    while {$i >= 0} {
+		$z {[string compare $a "bar"] < 0} {
+		    set i $i
+		    set i [lindex $s $i]
+		}
+		$z {[string compare $a "bar"] < 0} {
+		    set i $i
+		    set i [lindex $s $i]
+		}
+		$z {[string compare $a "bar"] < 0} {
+		    set i $i
+		    set i [lindex $s $i]
+		}
+		$z {[string compare $a "bar"] < 0} {
+		    set i $i
+		    set i [lindex $s $i]
+		}
+		set i [expr $i-1]
+	    }
+	}
+	set a 5
+	while {$a != "xxx"} {
+	    break;
+	    while {$i >= 0} {
+		$z {[string compare $a "bar"] < 0} {
+		    set i $i
+		    set i [lindex $s $i]
+		}
+		$z {[string compare $a "bar"] < 0} {
+		    set i $i
+		    set i [lindex $s $i]
+		}
+		$z {[string compare $a "bar"] < 0} {
+		    set i $i
+		    set i [lindex $s $i]
+		}
+		$z {[string compare $a "bar"] < 0} {
+		    set i $i
+		    set i [lindex $s $i]
+		}
+		set i [expr $i-1]
+	    }
+	}
+	set a 6
+    }
+    return $a
+} -cleanup {
+    unset a z
+    unset -nocomplain i
+} -result 6
+
+test if-7.1 {if cmd with computed command names: "else" clause} -setup {
+    set a {}
+} -body {
+    set z if
+    $z 3>4 {set a 1} elseif {$a == "foo"} {set a 2} else {set a 3}
+    return $a
+} -cleanup {
+    unset a z
+} -result 3
+# Since "else" is optional, the "elsex" below is treated as a command.
+# But then there shouldn't be any additional argument words for the "if".
+test if-7.2 {if cmd with computed command names: keyword other than "else"} -setup {
+    set a {}
+} -body {
+    set z if
+    $z 1<2 then {set a 1} elsex {set a 2}
+} -returnCodes error -cleanup {
+    unset a z
+} -result {wrong # args: extra words after "else" clause in "if" command}
+test if-7.3 {if cmd with computed command names: missing body after "else"} -setup {
+    set a {}
+} -body {
+    set z if
+    $z 2<1 {set a 1} else
+} -returnCodes error -cleanup {
+    unset a z
+} -result {wrong # args: no script following "else" argument}
+test if-7.4 {if cmd with computed command names: error compiling body after "else"} -setup {
+    set a {}
+} -body {
+    set z if
+    catch {$z 2<1 {set a 1} else {set}}
+    return $::errorInfo
+} -match glob -cleanup {
+    unset a z
+} -result {wrong # args: should be "set varName ?newValue?"
+    while *ing
+"set"
+    invoked from within
+"$z 2<1 {set a 1} else {set}"}
+test if-7.5 {if cmd with computed command names: extra arguments after "else" argument} -setup {
+    set a {}
+} -body {
+    set z if
+    $z 2<1 {set a 1} else {set a 2} or something
+} -returnCodes error -cleanup {
+    unset a z
+} -result {wrong # args: extra words after "else" clause in "if" command}
+# The following test also checks whether contained loops and other
+# commands are properly relocated because a short jump must be replaced
+# by a "long distance" one.
+test if-7.6 {if cmd with computed command names: test jumpFalse instruction replacement after long "else" clause} -setup {
+    catch {unset i}
+    set a {}
+} -body {
+    set z if
+    $z 1>2 {
+	set a 1
+	while {$a != "xxx"} {
+	    break;
+	    while {$i >= 0} {
+		$z {[string compare $a "bar"] < 0} {
+		    set i $i
+		    set i [lindex $s $i]
+		}
+		$z {[string compare $a "bar"] < 0} {
+		    set i $i
+		    set i [lindex $s $i]
+		}
+		$z {[string compare $a "bar"] < 0} {
+		    set i $i
+		    set i [lindex $s $i]
+		}
+		$z {[string compare $a "bar"] < 0} {
+		    set i $i
+		    set i [lindex $s $i]
+		}
+		set i [expr $i-1]
+	    }
+	}
+	set a 2
+	while {$a != "xxx"} {
+	    break;
+	    while {$i >= 0} {
+		$z {[string compare $a "bar"] < 0} {
+		    set i $i
+		    set i [lindex $s $i]
+		}
+		$z {[string compare $a "bar"] < 0} {
+		    set i $i
+		    set i [lindex $s $i]
+		}
+		$z {[string compare $a "bar"] < 0} {
+		    set i $i
+		    set i [lindex $s $i]
+		}
+		$z {[string compare $a "bar"] < 0} {
+		    set i $i
+		    set i [lindex $s $i]
+		}
+		set i [expr $i-1]
+	    }
+	}
+	set a 3
+    } elseif 1==2 then { #; this if arm should be taken
+	set a 4
+	while {$a != "xxx"} {
+	    break;
+	    while {$i >= 0} {
+		$z {[string compare $a "bar"] < 0} {
+		    set i $i
+		    set i [lindex $s $i]
+		}
+		$z {[string compare $a "bar"] < 0} {
+		    set i $i
+		    set i [lindex $s $i]
+		}
+		$z {[string compare $a "bar"] < 0} {
+		    set i $i
+		    set i [lindex $s $i]
+		}
+		$z {[string compare $a "bar"] < 0} {
+		    set i $i
+		    set i [lindex $s $i]
+		}
+		set i [expr $i-1]
+	    }
+	}
+	set a 5
+	while {$a != "xxx"} {
+	    break;
+	    while {$i >= 0} {
+		$z {[string compare $a "bar"] < 0} {
+		    set i $i
+		    set i [lindex $s $i]
+		}
+		$z {[string compare $a "bar"] < 0} {
+		    set i $i
+		    set i [lindex $s $i]
+		}
+		$z {[string compare $a "bar"] < 0} {
+		    set i $i
+		    set i [lindex $s $i]
+		}
+		$z {[string compare $a "bar"] < 0} {
+		    set i $i
+		    set i [lindex $s $i]
+		}
+		set i [expr $i-1]
+	    }
+	}
+	set a 6
+    } else {
+	set a 7
+	while {$a != "xxx"} {
+	    break;
+	    while {$i >= 0} {
+		$z {[string compare $a "bar"] < 0} {
+		    set i $i
+		    set i [lindex $s $i]
+		}
+		$z {[string compare $a "bar"] < 0} {
+		    set i $i
+		    set i [lindex $s $i]
+		}
+		$z {[string compare $a "bar"] < 0} {
+		    set i $i
+		    set i [lindex $s $i]
+		}
+		$z {[string compare $a "bar"] < 0} {
+		    set i $i
+		    set i [lindex $s $i]
+		}
+		set i [expr $i-1]
+	    }
+	}
+	set a 8
+	while {$a != "xxx"} {
+	    break;
+	    while {$i >= 0} {
+		$z {[string compare $a "bar"] < 0} {
+		    set i $i
+		    set i [lindex $s $i]
+		}
+		$z {[string compare $a "bar"] < 0} {
+		    set i $i
+		    set i [lindex $s $i]
+		}
+		$z {[string compare $a "bar"] < 0} {
+		    set i $i
+		    set i [lindex $s $i]
+		}
+		$z {[string compare $a "bar"] < 0} {
+		    set i $i
+		    set i [lindex $s $i]
+		}
+		set i [expr $i-1]
+	    }
+	}
+	set a 9
+    }
+    return $a
+} -cleanup {
+    unset a z
+    unset -nocomplain i
+} -result 9
+
+test if-8.1 {if cmd with computed command names: "if" command result} -setup {
+    set a {}
+} -body {
+    set z if
+    set a [$z 3<4 {set i 27}]
+    return $a
+} -cleanup {
+    unset a z
+    unset -nocomplain i
+} -result 27
+test if-8.2 {if cmd with computed command names: "if" command result} -setup {
+    set a {}
+} -body {
+    set z if
+    set a [$z 3>4 {set i 27}]
+    return $a
+} -cleanup {
+    unset a z
+    unset -nocomplain i
+} -result {}
+test if-8.3 {if cmd with computed command names: "if" command result} -setup {
+    set a {}
+} -body {
+    set z if
+    set a [$z 0 {set i 1} elseif 1 {set i 2}]
+    return $a
+} -cleanup {
+    unset a z
+    unset -nocomplain i
+} -result 2
+test if-8.4 {if cmd with computed command names: "if" command result} -setup {
+    set a {}
+} -body {
+    set z if
+    set a [$z 0 {set i 1} elseif 0 {set i 2} elseif 2>5 {set i 3} else {set i 4}]
+    return $a
+} -cleanup {
+    unset a z
+    unset -nocomplain i
+} -result 4
+test if-8.5 {if cmd with computed command names: return value} -body {
+    set z if
+    $z 0 then {set a 22; concat abc} elseif 1 {concat def} {concat ghi}
+} -cleanup {
+    unset z
+    unset -nocomplain a
+} -result def
+
+test if-9.1 {if cmd with namespace qualifiers} -body {
+    ::if {1} {set x 4}
+} -cleanup {
+    unset x
+} -result 4
+
+# Test for incorrect "double evaluation semantics"
+
+test if-10.1 {delayed substitution of then body} -body {
+    set j 0
+    set if if
+    # this is not compiled
+    $if {[incr j] == 1} "
+       set result $j
+    "
+    # this will be compiled
+    proc p {} {
+	set j 0
+	if {[incr j]} "
+	    set result $j
+	"
+	set result
+    }
+    append result [p]
+} -cleanup {
+    unset j if result
+    rename p {}
+} -result {00}
+test if-10.2 {delayed substitution of elseif expression} -body {
+    set j 0
+    set if if
+    # this is not compiled
+    $if {[incr j] == 0} {
+       set result badthen
+    } elseif "$j == 1" {
+       set result badelseif
+    } else {
+       set result 0
+    }
+    # this will be compiled
+    proc p {} {
+	set j 0
+	if {[incr j] == 0} {
+	    set result badthen
+	} elseif "$j == 1" {
+	    set result badelseif
+	} else {
+	    set result 0
+	}
+	set result
+    }
+    append result [p]
+} -cleanup {
+    unset j if result
+    rename p {}
+} -result {00}
+test if-10.3 {delayed substitution of elseif body} -body {
+    set j 0
+    set if if
+    # this is not compiled
+    $if {[incr j] == 0} {
+       set result badthen
+    } elseif {1} "
+       set result $j
+    "
+    # this will be compiled
+    proc p {} {
+	set j 0
+	if {[incr j] == 0} {
+	    set result badthen
+	} elseif {1} "
+	    set result $j
+	"
+    }
+    append result [p]
+} -cleanup {
+    unset j if result
+    rename p {}
+} -result {00}
+test if-10.4 {delayed substitution of else body} -body {
+    set j 0
+    if {[incr j] == 0} {
+       set result badthen
+    } else "
+       set result $j
+    "
+    return $result
+} -cleanup {
+    unset j result
+} -result {0}
+test if-10.5 {substituted control words} -body {
+    set then then; proc then {} {return badthen}
+    set else else; proc else {} {return badelse}
+    set elseif elseif; proc elseif {} {return badelseif}
+    list [catch {if 1 $then {if 0 {} $elseif 1 {if 0 {} $else {list ok}}}} a] $a
+} -cleanup {
+    unset then else elseif a
+} -result {0 ok}
+test if-10.6 {double invocation of variable traces} -body {
+    set iftracecounter 0
+    proc iftraceproc {args} {
+       upvar #0 iftracecounter counter
+       set argc [llength $args]
+       set extraargs [lrange $args 0 [expr {$argc - 4}]]
+       set name [lindex $args [expr {$argc - 3}]]
+       upvar 1 $name var
+       if {[incr counter] % 2 == 1} {
+           set var "$counter oops [concat $extraargs]"
+       } else {
+           set var "$counter + [concat $extraargs]"
+       }
+    }
+    trace variable iftracevar r [list iftraceproc 10]
+    list [catch {if "$iftracevar + 20" {}} a] $a \
+        [catch {if "$iftracevar + 20" {}} b] $b
+} -cleanup {
+    unset iftracevar iftracecounter a b
+} -match glob -result {1 {*} 0 {}}
+
+# cleanup
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# fill-column: 78
+# End:
diff --git a/tests/incr-old.test b/tests/incr-old.test
new file mode 100644
index 0000000..ed457cf
--- /dev/null
+++ b/tests/incr-old.test
@@ -0,0 +1,92 @@
+# Commands covered:  incr
+#
+# This file contains the original set of tests for Tcl's incr command.
+# Since the incr command is now compiled, a new set of tests covering
+# the new implementation is in the file "incr.test". Sourcing this file
+# into Tcl runs the tests and generates output for errors.
+# No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994-1996 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+    package require tcltest 2
+    namespace import -force ::tcltest::*
+}
+
+catch {unset x}
+
+test incr-old-1.1 {basic incr operation} {
+    set x 23
+    list [incr x] $x
+} {24 24}
+test incr-old-1.2 {basic incr operation} {
+    set x 106
+    list [incr x -5] $x
+} {101 101}
+test incr-old-1.3 {basic incr operation} {
+    set x "  -106"
+    list [incr x 1] $x
+} {-105 -105}
+test incr-old-1.4 {basic incr operation} {
+    set x "  +106"
+    list [incr x 1] $x
+} {107 107}
+
+test incr-old-2.1 {incr errors} {
+    list [catch incr msg] $msg
+} {1 {wrong # args: should be "incr varName ?increment?"}}
+test incr-old-2.2 {incr errors} {
+    list [catch {incr a b c} msg] $msg
+} {1 {wrong # args: should be "incr varName ?increment?"}}
+test incr-old-2.3 {incr errors} {
+    catch {unset x}
+    incr x
+} 1
+test incr-old-2.4 {incr errors} {
+    set x abc
+    list [catch {incr x} msg] $msg $::errorInfo
+} {1 {expected integer but got "abc"} {expected integer but got "abc"
+    while executing
+"incr x"}}
+test incr-old-2.5 {incr errors} {
+    set x 123
+    list [catch {incr x 1a} msg] $msg $::errorInfo
+} {1 {expected integer but got "1a"} {expected integer but got "1a"
+    (reading increment)
+    invoked from within
+"incr x 1a"}}
+test incr-old-2.6 {incr errors} -body {
+    proc readonly args {error "variable is read-only"}
+    set x 123
+    trace var x w readonly
+    list [catch {incr x 1} msg] $msg $::errorInfo
+} -match glob -result {1 {can't set "x": variable is read-only} {*variable is read-only
+    while executing
+*
+"incr x 1"}}
+catch {unset x}
+test incr-old-2.7 {incr errors} {
+    set x -
+    list [catch {incr x 1} msg] $msg
+} {1 {expected integer but got "-"}}
+test incr-old-2.8 {incr errors} {
+    set x {  -  }
+    list [catch {incr x 1} msg] $msg
+} {1 {expected integer but got "  -  "}}
+test incr-old-2.9 {incr errors} {
+    set x +
+    list [catch {incr x 1} msg] $msg
+} {1 {expected integer but got "+"}}
+test incr-old-2.10 {incr errors} {
+    set x {20 x}
+    list [catch {incr x 1} msg] $msg
+} {1 {expected integer but got "20 x"}}
+
+# cleanup
+::tcltest::cleanupTests
+return
diff --git a/tests/incr.test b/tests/incr.test
new file mode 100644
index 0000000..9243be0
--- /dev/null
+++ b/tests/incr.test
@@ -0,0 +1,522 @@
+# Commands covered:  incr
+#
+# This file contains a collection of tests for one or more of the Tcl built-in
+# commands. Sourcing this file into Tcl runs the tests and generates output
+# for errors. No output means no errors were found.
+#
+# Copyright (c) 1996 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution of
+# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {"::tcltest" ni [namespace children]} {
+    package require tcltest 2
+    namespace import -force ::tcltest::*
+}
+
+unset -nocomplain x i
+proc readonly varName {
+    upvar 1 $varName var
+    trace add variable var write \
+	{apply {{args} {error "variable is read-only"}}}
+}
+
+# Basic "incr" operation.
+
+test incr-1.1 {TclCompileIncrCmd: missing variable name} -returnCodes error -body {
+    incr
+} -result {wrong # args: should be "incr varName ?increment?"}
+test incr-1.2 {TclCompileIncrCmd: simple variable name} {
+    set i 10
+    list [incr i] $i
+} {11 11}
+test incr-1.3 {TclCompileIncrCmd: error compiling variable name} -body {
+    set i 10
+    incr "i"xxx
+} -returnCodes error -result {extra characters after close-quote}
+test incr-1.4 {TclCompileIncrCmd: simple variable name in quotes} {
+    set i 17
+    list [incr "i"] $i
+} {18 18}
+test incr-1.5 {TclCompileIncrCmd: simple variable name in braces} -setup {
+    unset -nocomplain {a simple var}
+} -body {
+    set {a simple var} 27
+    list [incr {a simple var}] ${a simple var}
+} -result {28 28}
+test incr-1.6 {TclCompileIncrCmd: simple array variable name} -setup {
+    unset -nocomplain a
+} -body {
+    set a(foo) 37
+    list [incr a(foo)] $a(foo)
+} -result {38 38}
+test incr-1.7 {TclCompileIncrCmd: non-simple (computed) variable name} {
+    set x "i"
+    set i 77
+    list [incr $x 2] $i
+} {79 79}
+test incr-1.8 {TclCompileIncrCmd: non-simple (computed) variable name} {
+    set x "i"
+    set i 77
+    list [incr [set x] +2] $i
+} {79 79}
+test incr-1.9 {TclCompileIncrCmd: increment given} {
+    set i 10
+    list [incr i +07] $i
+} {17 17}
+test incr-1.10 {TclCompileIncrCmd: no increment given} {
+    set i 10
+    list [incr i] $i
+} {11 11}
+test incr-1.11 {TclCompileIncrCmd: simple global name} {
+    proc p {} {
+        global i
+        set i 54
+        incr i
+    }
+    p
+} {55}
+test incr-1.12 {TclCompileIncrCmd: simple local name} {
+    proc p {} {
+        set foo 100
+        incr foo
+    }
+    p
+} {101}
+test incr-1.13 {TclCompileIncrCmd: simple but new (unknown) local name} {
+    proc p {} {
+        incr bar
+    }
+    p
+} 1
+test incr-1.14 {TclCompileIncrCmd: simple local name, >255 locals} {
+    proc 260locals {} {
+        # create 260 locals
+        set a0 0; set a1 0; set a2 0; set a3 0; set a4 0
+        set a5 0; set a6 0; set a7 0; set a8 0; set a9 0
+        set b0 0; set b1 0; set b2 0; set b3 0; set b4 0
+        set b5 0; set b6 0; set b7 0; set b8 0; set b9 0
+        set c0 0; set c1 0; set c2 0; set c3 0; set c4 0
+        set c5 0; set c6 0; set c7 0; set c8 0; set c9 0
+        set d0 0; set d1 0; set d2 0; set d3 0; set d4 0
+        set d5 0; set d6 0; set d7 0; set d8 0; set d9 0
+        set e0 0; set e1 0; set e2 0; set e3 0; set e4 0
+        set e5 0; set e6 0; set e7 0; set e8 0; set e9 0
+        set f0 0; set f1 0; set f2 0; set f3 0; set f4 0
+        set f5 0; set f6 0; set f7 0; set f8 0; set f9 0
+        set g0 0; set g1 0; set g2 0; set g3 0; set g4 0
+        set g5 0; set g6 0; set g7 0; set g8 0; set g9 0
+        set h0 0; set h1 0; set h2 0; set h3 0; set h4 0
+        set h5 0; set h6 0; set h7 0; set h8 0; set h9 0
+        set i0 0; set i1 0; set i2 0; set i3 0; set i4 0
+        set i5 0; set i6 0; set i7 0; set i8 0; set i9 0
+        set j0 0; set j1 0; set j2 0; set j3 0; set j4 0
+        set j5 0; set j6 0; set j7 0; set j8 0; set j9 0
+        set k0 0; set k1 0; set k2 0; set k3 0; set k4 0
+        set k5 0; set k6 0; set k7 0; set k8 0; set k9 0
+        set l0 0; set l1 0; set l2 0; set l3 0; set l4 0
+        set l5 0; set l6 0; set l7 0; set l8 0; set l9 0
+        set m0 0; set m1 0; set m2 0; set m3 0; set m4 0
+        set m5 0; set m6 0; set m7 0; set m8 0; set m9 0
+        set n0 0; set n1 0; set n2 0; set n3 0; set n4 0
+        set n5 0; set n6 0; set n7 0; set n8 0; set n9 0
+        set o0 0; set o1 0; set o2 0; set o3 0; set o4 0
+        set o5 0; set o6 0; set o7 0; set o8 0; set o9 0
+        set p0 0; set p1 0; set p2 0; set p3 0; set p4 0
+        set p5 0; set p6 0; set p7 0; set p8 0; set p9 0
+        set q0 0; set q1 0; set q2 0; set q3 0; set q4 0
+        set q5 0; set q6 0; set q7 0; set q8 0; set q9 0
+        set r0 0; set r1 0; set r2 0; set r3 0; set r4 0
+        set r5 0; set r6 0; set r7 0; set r8 0; set r9 0
+        set s0 0; set s1 0; set s2 0; set s3 0; set s4 0
+        set s5 0; set s6 0; set s7 0; set s8 0; set s9 0
+        set t0 0; set t1 0; set t2 0; set t3 0; set t4 0
+        set t5 0; set t6 0; set t7 0; set t8 0; set t9 0
+        set u0 0; set u1 0; set u2 0; set u3 0; set u4 0
+        set u5 0; set u6 0; set u7 0; set u8 0; set u9 0
+        set v0 0; set v1 0; set v2 0; set v3 0; set v4 0
+        set v5 0; set v6 0; set v7 0; set v8 0; set v9 0
+        set w0 0; set w1 0; set w2 0; set w3 0; set w4 0
+        set w5 0; set w6 0; set w7 0; set w8 0; set w9 0
+        set x0 0; set x1 0; set x2 0; set x3 0; set x4 0
+        set x5 0; set x6 0; set x7 0; set x8 0; set x9 0
+        set y0 0; set y1 0; set y2 0; set y3 0; set y4 0
+        set y5 0; set y6 0; set y7 0; set y8 0; set y9 0
+        set z0 0; set z1 0; set z2 0; set z3 0; set z4 0
+        set z5 0; set z6 0; set z7 0; set z8 0; set z9 0
+        # now increment the last one (local var index > 255)
+        incr z9
+    }
+    260locals
+} {1}
+test incr-1.15 {TclCompileIncrCmd: variable is array} -setup {
+    unset -nocomplain a
+} -body {
+    set a(foo) 27
+    incr a(foo) 11
+} -cleanup {
+    unset -nocomplain a
+} -result 38
+test incr-1.16 {TclCompileIncrCmd: variable is array, elem substitutions} -setup {
+    unset -nocomplain a
+} -body {
+    set i 5
+    set a(foo5) 27
+    incr a(foo$i) 11
+} -cleanup {
+    unset -nocomplain a
+} -result 38
+test incr-1.17 {TclCompileIncrCmd: increment given, simple int} {
+    set i 5
+    incr i 123
+} 128
+test incr-1.18 {TclCompileIncrCmd: increment given, simple int} {
+    set i 5
+    incr i -100
+} -95
+test incr-1.19 {TclCompileIncrCmd: increment given, but erroneous} -body {
+    set i 5
+    catch {incr i [set]} -> opts
+    dict get $opts -errorinfo
+} -match glob -result {wrong # args: should be "set varName ?newValue?"
+    while *ing
+"set"*}
+test incr-1.20 {TclCompileIncrCmd: increment given, in quotes} {
+    set i 25
+    incr i "-100"
+} -75
+test incr-1.21 {TclCompileIncrCmd: increment given, in braces} {
+    set i 24
+    incr i {126}
+} 150
+test incr-1.22 {TclCompileIncrCmd: increment given, large int} {
+    set i 5
+    incr i 200000
+} 200005
+test incr-1.23 {TclCompileIncrCmd: increment given, formatted int != int} {
+    set i 25
+    incr i 0o00012345     ;# an octal literal
+} 5374
+test incr-1.24 {TclCompileIncrCmd: increment given, formatted int != int} -body {
+    set i 25
+    incr i 1a
+} -returnCodes error -result {expected integer but got "1a"}
+test incr-1.25 {TclCompileIncrCmd: too many arguments} -body {
+    set i 10
+    incr i 10 20
+} -returnCodes error -result {wrong # args: should be "incr varName ?increment?"}
+test incr-1.26 {TclCompileIncrCmd: runtime error, bad variable name} {
+    unset -nocomplain {"foo}
+    incr {"foo}
+} 1
+test incr-1.27 {TclCompileIncrCmd: runtime error, bad variable name} -body {
+    list [catch {incr [set]} msg] $msg $::errorInfo
+} -match glob -result {1 {wrong # args: should be "set varName ?newValue?"} {wrong # args: should be "set varName ?newValue?"
+    while *ing
+"set"*}}
+test incr-1.28 {TclCompileIncrCmd: runtime error, readonly variable} -body {
+    set x 123
+    readonly x
+    list [catch {incr x 1} msg] $msg $::errorInfo
+} -match glob -cleanup {
+    unset -nocomplain x
+} -result {1 {can't set "x": variable is read-only} {*variable is read-only
+    while executing
+*
+"incr x 1"}}
+test incr-1.29 {TclCompileIncrCmd: runtime error, bad variable value} -body {
+    set x "  -  "
+    incr x 1
+} -returnCodes error -result {expected integer but got "  -  "}
+test incr-1.30 {TclCompileIncrCmd: array var, braced (no subs)} -setup {
+    catch {unset array}
+} -body {
+    set array(\$foo) 4
+    incr {array($foo)}
+} -result 5
+
+# Check "incr" and computed command names.
+
+unset -nocomplain x i
+test incr-2.0 {incr and computed command names} {
+    set i 5
+    set z incr
+    $z i -1
+    return $i
+} 4
+test incr-2.1 {incr command (not compiled): missing variable name} -body {
+    set z incr
+    $z
+} -returnCodes error -result {wrong # args: should be "incr varName ?increment?"}
+test incr-2.2 {incr command (not compiled): simple variable name} {
+    set z incr
+    set i 10
+    list [$z i] $i
+} {11 11}
+test incr-2.3 {incr command (not compiled): error compiling variable name} -body {
+    set z incr
+    set i 10
+    $z "i"xxx
+} -returnCodes error -result {extra characters after close-quote}
+test incr-2.4 {incr command (not compiled): simple variable name in quotes} {
+    set z incr
+    set i 17
+    list [$z "i"] $i
+} {18 18}
+test incr-2.5 {incr command (not compiled): simple variable name in braces} -setup {
+    unset -nocomplain {a simple var}
+} -body {
+    set z incr
+    set {a simple var} 27
+    list [$z {a simple var}] ${a simple var}
+} -result {28 28}
+test incr-2.6 {incr command (not compiled): simple array variable name} -setup {
+    unset -nocomplain a
+} -body {
+    set z incr
+    set a(foo) 37
+    list [$z a(foo)] $a(foo)
+} -result {38 38}
+test incr-2.7 {incr command (not compiled): non-simple (computed) variable name} {
+    set z incr
+    set x "i"
+    set i 77
+    list [$z $x 2] $i
+} {79 79}
+test incr-2.8 {incr command (not compiled): non-simple (computed) variable name} {
+    set z incr
+    set x "i"
+    set i 77
+    list [$z [set x] +2] $i
+} {79 79}
+test incr-2.9 {incr command (not compiled): increment given} {
+    set z incr
+    set i 10
+    list [$z i +07] $i
+} {17 17}
+test incr-2.10 {incr command (not compiled): no increment given} {
+    set z incr
+    set i 10
+    list [$z i] $i
+} {11 11}
+test incr-2.11 {incr command (not compiled): simple global name} {
+    proc p {} {
+	set z incr
+        global i
+        set i 54
+        $z i
+    }
+    p
+} {55}
+test incr-2.12 {incr command (not compiled): simple local name} {
+    proc p {} {
+	set z incr
+        set foo 100
+        $z foo
+    }
+    p
+} {101}
+test incr-2.13 {incr command (not compiled): simple but new (unknown) local name} {
+    proc p {} {
+	set z incr
+        $z bar
+    }
+    p
+} 1
+test incr-2.14 {incr command (not compiled): simple local name, >255 locals} {
+   proc 260locals {} {
+        set z incr
+        # create 260 locals
+        set a0 0; set a1 0; set a2 0; set a3 0; set a4 0
+        set a5 0; set a6 0; set a7 0; set a8 0; set a9 0
+        set b0 0; set b1 0; set b2 0; set b3 0; set b4 0
+        set b5 0; set b6 0; set b7 0; set b8 0; set b9 0
+        set c0 0; set c1 0; set c2 0; set c3 0; set c4 0
+        set c5 0; set c6 0; set c7 0; set c8 0; set c9 0
+        set d0 0; set d1 0; set d2 0; set d3 0; set d4 0
+        set d5 0; set d6 0; set d7 0; set d8 0; set d9 0
+        set e0 0; set e1 0; set e2 0; set e3 0; set e4 0
+        set e5 0; set e6 0; set e7 0; set e8 0; set e9 0
+        set f0 0; set f1 0; set f2 0; set f3 0; set f4 0
+        set f5 0; set f6 0; set f7 0; set f8 0; set f9 0
+        set g0 0; set g1 0; set g2 0; set g3 0; set g4 0
+        set g5 0; set g6 0; set g7 0; set g8 0; set g9 0
+        set h0 0; set h1 0; set h2 0; set h3 0; set h4 0
+        set h5 0; set h6 0; set h7 0; set h8 0; set h9 0
+        set i0 0; set i1 0; set i2 0; set i3 0; set i4 0
+        set i5 0; set i6 0; set i7 0; set i8 0; set i9 0
+        set j0 0; set j1 0; set j2 0; set j3 0; set j4 0
+        set j5 0; set j6 0; set j7 0; set j8 0; set j9 0
+        set k0 0; set k1 0; set k2 0; set k3 0; set k4 0
+        set k5 0; set k6 0; set k7 0; set k8 0; set k9 0
+        set l0 0; set l1 0; set l2 0; set l3 0; set l4 0
+        set l5 0; set l6 0; set l7 0; set l8 0; set l9 0
+        set m0 0; set m1 0; set m2 0; set m3 0; set m4 0
+        set m5 0; set m6 0; set m7 0; set m8 0; set m9 0
+        set n0 0; set n1 0; set n2 0; set n3 0; set n4 0
+        set n5 0; set n6 0; set n7 0; set n8 0; set n9 0
+        set o0 0; set o1 0; set o2 0; set o3 0; set o4 0
+        set o5 0; set o6 0; set o7 0; set o8 0; set o9 0
+        set p0 0; set p1 0; set p2 0; set p3 0; set p4 0
+        set p5 0; set p6 0; set p7 0; set p8 0; set p9 0
+        set q0 0; set q1 0; set q2 0; set q3 0; set q4 0
+        set q5 0; set q6 0; set q7 0; set q8 0; set q9 0
+        set r0 0; set r1 0; set r2 0; set r3 0; set r4 0
+        set r5 0; set r6 0; set r7 0; set r8 0; set r9 0
+        set s0 0; set s1 0; set s2 0; set s3 0; set s4 0
+        set s5 0; set s6 0; set s7 0; set s8 0; set s9 0
+        set t0 0; set t1 0; set t2 0; set t3 0; set t4 0
+        set t5 0; set t6 0; set t7 0; set t8 0; set t9 0
+        set u0 0; set u1 0; set u2 0; set u3 0; set u4 0
+        set u5 0; set u6 0; set u7 0; set u8 0; set u9 0
+        set v0 0; set v1 0; set v2 0; set v3 0; set v4 0
+        set v5 0; set v6 0; set v7 0; set v8 0; set v9 0
+        set w0 0; set w1 0; set w2 0; set w3 0; set w4 0
+        set w5 0; set w6 0; set w7 0; set w8 0; set w9 0
+        set x0 0; set x1 0; set x2 0; set x3 0; set x4 0
+        set x5 0; set x6 0; set x7 0; set x8 0; set x9 0
+        set y0 0; set y1 0; set y2 0; set y3 0; set y4 0
+        set y5 0; set y6 0; set y7 0; set y8 0; set y9 0
+        set z0 0; set z1 0; set z2 0; set z3 0; set z4 0
+        set z5 0; set z6 0; set z7 0; set z8 0; set z9 0
+        # now increment the last one (local var index > 255)
+        $z z9
+    }
+    260locals
+} {1}
+test incr-2.15 {incr command (not compiled): variable is array} -setup {
+    unset -nocomplain a
+} -body {
+    set z incr
+    set a(foo) 27
+    $z a(foo) 11
+} -cleanup {
+    unset -nocomplain a
+} -result 38
+test incr-2.16 {incr command (not compiled): variable is array, elem substitutions} -setup {
+    unset -nocomplain a
+} -body {
+    set z incr
+    set i 5
+    set a(foo5) 27
+    $z a(foo$i) 11
+} -cleanup {
+    unset -nocomplain a
+} -result 38
+test incr-2.17 {incr command (not compiled): increment given, simple int} {
+    set z incr
+    set i 5
+    $z i 123
+} 128
+test incr-2.18 {incr command (not compiled): increment given, simple int} {
+    set z incr
+    set i 5
+    $z i -100
+} -95
+test incr-2.19 {incr command (not compiled): increment given, but erroneous} -body {
+    set z incr
+    set i 5
+    catch {$z i [set]} -> opts
+    dict get $opts -errorinfo
+} -match glob -result {wrong # args: should be "set varName ?newValue?"
+    while *ing
+"set"*}
+test incr-2.20 {incr command (not compiled): increment given, in quotes} {
+    set z incr
+    set i 25
+    $z i "-100"
+} -75
+test incr-2.21 {incr command (not compiled): increment given, in braces} {
+    set z incr
+    set i 24
+    $z i {126}
+} 150
+test incr-2.22 {incr command (not compiled): increment given, large int} {
+    set z incr
+    set i 5
+    $z i 200000
+} 200005
+test incr-2.23 {incr command (not compiled): increment given, formatted int != int} {
+    set z incr
+    set i 25
+    $z i 0o00012345     ;# an octal literal
+} 5374
+test incr-2.24 {incr command (not compiled): increment given, formatted int != int} -body {
+    set z incr
+    set i 25
+    $z i 1a
+} -returnCodes error -result {expected integer but got "1a"}
+test incr-2.25 {incr command (not compiled): too many arguments} -body {
+    set z incr
+    set i 10
+    $z i 10 20
+} -returnCodes error -result {wrong # args: should be "incr varName ?increment?"}
+test incr-2.26 {incr command (not compiled): runtime error, bad variable name} -setup {
+    unset -nocomplain {"foo}
+} -body {
+    set z incr
+    $z {"foo}
+} -result 1
+test incr-2.27 {incr command (not compiled): runtime error, bad variable name} -body {
+    set z incr
+    list [catch {$z [set]} msg] $msg $::errorInfo
+} -match glob -result {1 {wrong # args: should be "set varName ?newValue?"} {wrong # args: should be "set varName ?newValue?"
+    while *ing
+"set"*}}
+test incr-2.28 {incr command (not compiled): runtime error, readonly variable} -body {
+    set z incr
+    set x 123
+    readonly x
+    list [catch {$z x 1} msg] $msg $::errorInfo
+} -match glob -cleanup {
+    unset -nocomplain x
+} -result {1 {can't set "x": variable is read-only} {*variable is read-only
+    while executing
+*
+"$z x 1"}}
+test incr-2.29 {incr command (not compiled): runtime error, bad variable value} -body {
+    set z incr
+    set x "  -  "
+    $z x 1
+} -returnCodes error -result {expected integer but got "  -  "}
+test incr-2.30 {incr command (not compiled): bad increment} {
+    set z incr
+    set x 0
+    list [catch {$z x 1a} msg] $msg $::errorInfo
+} {1 {expected integer but got "1a"} {expected integer but got "1a"
+    (reading increment)
+    invoked from within
+"$z x 1a"}}
+test incr-2.31 {incr command (compiled): bad increment} {
+    list [catch {incr x 1a} msg] $msg $::errorInfo
+} {1 {expected integer but got "1a"} {expected integer but got "1a"
+    (reading increment)
+    invoked from within
+"incr x 1a"}}
+
+test incr-3.1 {increment by wide amount: bytecode route} {
+    set x 0
+    incr x 123123123123
+} 123123123123
+test incr-3.2 {increment by wide amount: command route} {
+    set z incr
+    set x 0
+    $z x 123123123123
+} 123123123123
+
+test incr-4.1 {increment non-existing array element [Bug 1445454]} -body {
+    proc x {} {incr a(1)}
+    x
+} -cleanup {
+    rename x {}
+} -result 1
+
+# cleanup
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# fill-column: 78
+# End:
diff --git a/tests/indexObj.test b/tests/indexObj.test
new file mode 100644
index 0000000..646cb02
--- /dev/null
+++ b/tests/indexObj.test
@@ -0,0 +1,166 @@
+# This file is a Tcl script to test out the the procedures in file
+# tkIndexObj.c, which implement indexed table lookups.  The tests here are
+# organized in the standard fashion for Tcl tests.
+#
+# Copyright (c) 1997 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution of
+# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+    package require tcltest 2
+    namespace import -force ::tcltest::*
+}
+
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
+
+testConstraint testindexobj [llength [info commands testindexobj]]
+testConstraint testparseargs [llength [info commands testparseargs]]
+
+test indexObj-1.1 {exact match} testindexobj {
+    testindexobj 1 1 xyz abc def xyz alm
+} {2}
+test indexObj-1.2 {exact match} testindexobj {
+    testindexobj 1 1 abc abc def xyz alm
+} {0}
+test indexObj-1.3 {exact match} testindexobj {
+    testindexobj 1 1 alm abc def xyz alm
+} {3}
+test indexObj-1.4 {unique abbreviation} testindexobj {
+    testindexobj 1 1 xy abc def xalb xyz alm
+} {3}
+test indexObj-1.5 {multiple abbreviations and exact match} testindexobj {
+    testindexobj 1 1 x abc def xalb xyz alm x
+} {5}
+test indexObj-1.6 {forced exact match} testindexobj {
+    testindexobj 1 0 xy abc def xalb xy alm
+} {3}
+test indexObj-1.7 {forced exact match} testindexobj {
+    testindexobj 1 0 x abc def xalb xyz alm x
+} {5}
+test indexObj-1.8 {exact match of empty values} testindexobj {
+    testindexobj 1 1 {} a aa aaa {} b bb bbb
+} 3
+test indexObj-1.9 {exact match of empty values} testindexobj {
+    testindexobj 1 0 {} a aa aaa {} b bb bbb
+} 3
+
+test indexObj-2.1 {no match} testindexobj {
+    list [catch {testindexobj 1 1 dddd abc def xalb xyz alm x} msg] $msg
+} {1 {bad token "dddd": must be abc, def, xalb, xyz, alm, or x}}
+test indexObj-2.2 {no match} testindexobj {
+    list [catch {testindexobj 1 1 dddd abc} msg] $msg
+} {1 {bad token "dddd": must be abc}}
+test indexObj-2.3 {no match: no abbreviations} testindexobj {
+    list [catch {testindexobj 1 0 xy abc def xalb xyz alm} msg] $msg
+} {1 {bad token "xy": must be abc, def, xalb, xyz, or alm}}
+test indexObj-2.4 {ambiguous value} testindexobj {
+    list [catch {testindexobj 1 1 d dumb daughter a c} msg] $msg
+} {1 {ambiguous token "d": must be dumb, daughter, a, or c}}
+test indexObj-2.5 {omit error message} testindexobj {
+    list [catch {testindexobj 0 1 d x} msg] $msg
+} {1 {}}
+test indexObj-2.6 {TCL_EXACT => no "ambiguous" error message} testindexobj {
+    list [catch {testindexobj 1 0 d dumb daughter a c} msg] $msg
+} {1 {bad token "d": must be dumb, daughter, a, or c}}
+test indexObj-2.7 {exact match of empty values} testindexobj {
+    list [catch {testindexobj 1 1 {} a b c} msg] $msg
+} {1 {ambiguous token "": must be a, b, or c}}
+test indexObj-2.8 {exact match of empty values: singleton case} testindexobj {
+    list [catch {testindexobj 1 0 {} a} msg] $msg
+} {1 {bad token "": must be a}}
+test indexObj-2.9 {non-exact match of empty values: singleton case} testindexobj {
+    # NOTE this is a special case.  Although the empty string is a
+    # unique prefix, we have an established history of rejecting
+    # empty lookup keys, requiring any unique prefix match to have
+    # at least one character.
+    list [catch {testindexobj 1 1 {} a} msg] $msg
+} {1 {bad token "": must be a}}
+
+test indexObj-3.1 {cache result to skip next lookup} testindexobj {
+    testindexobj check 42
+} {42}
+
+test indexObj-4.1 {free old internal representation} testindexobj {
+    set x {a b}
+    lindex $x 1
+    testindexobj 1 1 $x abc def {a b} zzz
+} {2}
+
+test indexObj-5.1 {Tcl_WrongNumArgs} testindexobj {
+    testwrongnumargs 1 "?-switch?" mycmd
+} "wrong # args: should be \"mycmd ?-switch?\""
+test indexObj-5.2 {Tcl_WrongNumArgs} testindexobj {
+    testwrongnumargs 2 "bar" mycmd foo
+} "wrong # args: should be \"mycmd foo bar\""
+test indexObj-5.3 {Tcl_WrongNumArgs} testindexobj {
+    testwrongnumargs 0 "bar" mycmd foo
+} "wrong # args: should be \"bar\""
+test indexObj-5.4 {Tcl_WrongNumArgs} testindexobj {
+    testwrongnumargs 0 "" mycmd foo
+} "wrong # args: should be \"\""
+test indexObj-5.5 {Tcl_WrongNumArgs} testindexobj {
+    testwrongnumargs 1 "" mycmd foo
+} "wrong # args: should be \"mycmd\""
+test indexObj-5.6 {Tcl_WrongNumArgs} testindexobj {
+    testwrongnumargs 2 "" mycmd foo
+} "wrong # args: should be \"mycmd foo\""
+# Contrast this with test proc-3.6; they have to be like this because
+# of [Bug 1066837] so Itcl won't break.
+test indexObj-5.7 {Tcl_WrongNumArgs} testindexobj {
+    testwrongnumargs 2 "fee fi" "fo fum" foo bar
+} "wrong # args: should be \"fo fum foo fee fi\""
+
+test indexObj-6.1 {Tcl_GetIndexFromObjStruct} testindexobj {
+    set x a
+    testgetindexfromobjstruct $x 0
+} "wrong # args: should be \"testgetindexfromobjstruct a 0\""
+test indexObj-6.2 {Tcl_GetIndexFromObjStruct} testindexobj {
+    set x a
+    testgetindexfromobjstruct $x 0
+    testgetindexfromobjstruct $x 0
+} "wrong # args: should be \"testgetindexfromobjstruct a 0\""
+test indexObj-6.3 {Tcl_GetIndexFromObjStruct} testindexobj {
+    set x c
+    testgetindexfromobjstruct $x 1
+} "wrong # args: should be \"testgetindexfromobjstruct c 1\""
+test indexObj-6.4 {Tcl_GetIndexFromObjStruct} testindexobj {
+    set x c
+    testgetindexfromobjstruct $x 1
+    testgetindexfromobjstruct $x 1
+} "wrong # args: should be \"testgetindexfromobjstruct c 1\""
+
+test indexObj-7.1 {Tcl_ParseArgsObjv} testparseargs {
+    testparseargs
+} {0 1 testparseargs}
+test indexObj-7.2 {Tcl_ParseArgsObjv} testparseargs {
+    testparseargs -bool
+} {1 1 testparseargs}
+test indexObj-7.3 {Tcl_ParseArgsObjv} testparseargs {
+    testparseargs -bool bar
+} {1 2 {testparseargs bar}}
+test indexObj-7.4 {Tcl_ParseArgsObjv} testparseargs {
+    testparseargs bar
+} {0 2 {testparseargs bar}}
+test indexObj-7.5 {Tcl_ParseArgsObjv} -constraints testparseargs -body {
+    testparseargs -help
+} -returnCodes error -result {Command-specific options:
+ -bool: booltest
+ --:    Marks the end of the options
+ -help: Print summary of command-line options and abort}
+test indexObj-7.6 {Tcl_ParseArgsObjv} testparseargs {
+    testparseargs -- -bool -help
+} {0 3 {testparseargs -bool -help}}
+test indexObj-7.7 {Tcl_ParseArgsObjv memory management} testparseargs {
+    testparseargs 1 2 3 4 5 6 7 8 9 0 -bool 1 2 3 4 5 6 7 8 9 0
+} {1 21 {testparseargs 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0}}
+
+# cleanup
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/tests/info.test b/tests/info.test
new file mode 100644
index 0000000..42f5a96
--- /dev/null
+++ b/tests/info.test
@@ -0,0 +1,2421 @@
+# -*- tcl -*-
+# Commands covered:  info
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands.  Sourcing this file into Tcl runs the tests and
+# generates output for errors.  No output means no errors were found.
+#
+# Copyright (c) 1991-1994 The Regents of the University of California.
+# Copyright (c) 1994-1997 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+# Copyright (c) 2006      ActiveState
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+# DO NOT DELETE THIS LINE
+
+if {{::tcltest} ni [namespace children]} {
+    package require tcltest 2
+    namespace import -force ::tcltest::*
+}
+
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
+
+# Set up namespaces needed to test operation of "info args", "info body",
+# "info default", and "info procs" with imported procedures.
+
+catch {namespace delete test_ns_info1 test_ns_info2}
+
+namespace eval test_ns_info1 {
+    namespace export *
+    proc p {x} {return "x=$x"}
+    proc q {{y 27} {z {}}} {return "y=$y"}
+}
+
+test info-1.1 {info args option} {
+    proc t1 {a bbb c} {return foo}
+    info args t1
+} {a bbb c}
+test info-1.2 {info args option} {
+    proc t1 {{a default1} {bbb default2} {c default3} args} {return foo}
+    info a t1
+} {a bbb c args}
+test info-1.3 {info args option} {
+    proc t1 "" {return foo}
+    info args t1
+} {}
+test info-1.4 {info args option} -body {
+    catch {rename t1 {}}
+    info args t1
+} -returnCodes error -result {"t1" isn't a procedure}
+test info-1.5 {info args option} -body {
+    info args set
+} -returnCodes error -result {"set" isn't a procedure}
+test info-1.6 {info args option} {
+    proc t1 {a b} {set c 123; set d $c}
+    t1 1 2
+    info args t1
+} {a b}
+test info-1.7 {info args option} {
+    catch {namespace delete test_ns_info2}
+    namespace eval test_ns_info2 {
+        namespace import ::test_ns_info1::*
+        list [info args p] [info args q]
+    }
+} {x {y z}}
+
+test info-2.1 {info body option} {
+    proc t1 {} {body of t1}
+    info body t1
+} {body of t1}
+test info-2.2 {info body option} -body {
+    info body set
+} -returnCodes error -result {"set" isn't a procedure}
+test info-2.3 {info body option} -body {
+    info args set 1
+} -returnCodes error -result {wrong # args: should be "info args procname"}
+test info-2.4 {info body option} {
+    catch {namespace delete test_ns_info2}
+    namespace eval test_ns_info2 {
+        namespace import ::test_ns_info1::*
+        list [info body p] [info body q]
+    }
+} {{return "x=$x"} {return "y=$y"}}
+# Prior to 8.3.0 this would cause a crash because [info body]
+# would return the bytecompiled version of foo, which the catch
+# would then try and eval out of the foo context, accessing
+# compiled local indices
+test info-2.5 {info body option, returning bytecompiled bodies} -body {
+    catch {unset args}
+    proc foo {args} {
+	foreach v $args {
+	    upvar $v var
+	    return "variable $v existence: [info exists var]"
+	}
+    }
+    foo a
+    eval [info body foo]
+} -returnCodes error -result {can't read "args": no such variable}
+# Fix for problem tested for in info-2.5 caused problems when
+# procedure body had no string rep (i.e. was not yet bytecode)
+# causing an empty string to be returned [Bug #545644]
+test info-2.6 {info body option, returning list bodies} {
+    proc foo args [list subst bar]
+    list [string bytelength [info body foo]] \
+	    [foo; string bytelength [info body foo]]
+} {9 9}
+
+proc testinfocmdcount {} {
+    set x [info cmdcount]
+    set y 12345
+    set z [info cm]
+    expr {$z-$x}
+}
+test info-3.1 {info cmdcount compiled} {
+    testinfocmdcount
+} 4
+test info-3.2 {info cmdcount evaled} -body {
+    set x [info cmdcount]
+    set y 12345
+    set z [info cm]
+    expr {$z-$x}
+} -cleanup {unset x y z} -result 4
+test info-3.3 {info cmdcount evaled} -body [info body testinfocmdcount] -cleanup {unset x y z} -result 4
+test info-3.4 {info cmdcount option} -body {
+    info cmdcount 1
+} -returnCodes error -result {wrong # args: should be "info cmdcount"}
+
+test info-4.1 {info commands option} -body {
+    proc t1 {} {}
+    proc t2 {} {}
+    set x " [info commands] "
+    list [string match {* t1 *} $x] [string match {* t2 *} $x] \
+            [string match {* set *} $x] [string match {* list *} $x]
+} -cleanup {unset x} -result {1 1 1 1}
+test info-4.2 {info commands option} -body {
+    proc t1 {} {}
+    rename t1 {}
+    string match {* t1 *} \
+	[info comm]
+} -result 0
+test info-4.3 {info commands option} {
+    proc _t1_ {} {}
+    proc _t2_ {} {}
+    info commands _t1_
+} _t1_
+test info-4.4 {info commands option} {
+    proc _t1_ {} {}
+    proc _t2_ {} {}
+    lsort [info commands _t*]
+} {_t1_ _t2_}
+catch {rename _t1_ {}}
+catch {rename _t2_ {}}
+test info-4.5 {info commands option} -returnCodes error -body {
+    info commands a b
+} -result {wrong # args: should be "info commands ?pattern?"}
+# Also some tests in namespace.test
+
+test info-5.1 {info complete option} -body {
+    info complete
+} -returnCodes error -result {wrong # args: should be "info complete command"}
+test info-5.2 {info complete option} {
+    info complete abc
+} 1
+test info-5.3 {info complete option} {
+    info complete "\{abcd "
+} 0
+test info-5.4 {info complete option} {
+    info complete {# Comment should be complete command}
+} 1
+test info-5.5 {info complete option} {
+    info complete {[a [b] }
+} 0
+test info-5.6 {info complete option} {
+    info complete {[a [b]}
+} 0
+
+test info-6.1 {info default option} {
+    proc t1 {a b {c d} {e "long default value"}} {}
+    info default t1 a value
+} 0
+test info-6.2 {info default option} -body {
+    proc t1 {a b {c d} {e "long default value"}} {}
+    set value 12345
+    info d t1 a value
+    return $value
+} -cleanup {unset value} -result {}
+test info-6.3 {info default option} -body {
+    proc t1 {a b {c d} {e "long default value"}} {}
+    info default t1 c value
+} -cleanup {unset value} -result 1
+test info-6.4 {info default option} -body {
+    proc t1 {a b {c d} {e "long default value"}} {}
+    set value 12345
+    info default t1 c value
+    return $value
+} -cleanup {unset value} -result d
+test info-6.5 {info default option} -body {
+    proc t1 {a b {c d} {e "long default value"}} {}
+    set value 12345
+    set x [info default t1 e value]
+    list $x $value
+} -cleanup {unset x value} -result {1 {long default value}}
+test info-6.6 {info default option} -returnCodes error -body {
+    info default a b
+} -result {wrong # args: should be "info default procname arg varname"}
+test info-6.7 {info default option} -returnCodes error -body {
+    info default _nonexistent_ a b
+} -result {"_nonexistent_" isn't a procedure}
+test info-6.8 {info default option} -returnCodes error -body {
+    proc t1 {a b} {}
+    info default t1 x value
+} -result {procedure "t1" doesn't have an argument "x"}
+test info-6.9 {info default option} -returnCodes error -setup {
+    catch {unset a}
+} -cleanup {unset a} -body {
+    set a(0) 88
+    proc t1 {a b} {}
+    info default t1 a a
+} -returnCodes error -result {can't set "a": variable is array}
+test info-6.10 {info default option} -setup {
+    catch {unset a}
+} -cleanup {unset a} -body {
+    set a(0) 88
+    proc t1 {{a 18} b} {}
+    info default t1 a a
+} -returnCodes error -result {can't set "a": variable is array}
+test info-6.11 {info default option} {
+    catch {namespace delete test_ns_info2}
+    namespace eval test_ns_info2 {
+        namespace import ::test_ns_info1::*
+        list [info default p x foo] $foo [info default q y bar] $bar
+    }
+} {0 {} 1 27}
+
+test info-7.1 {info exists option} -body {
+    set value foo
+    info exists value
+} -cleanup {unset value} -result 1
+
+test info-7.2 {info exists option} -setup {catch {unset _nonexistent_}} -body {
+    info exists _nonexistent_
+} -result 0
+test info-7.3 {info exists option} {
+    proc t1 {x} {return [info exists x]}
+    t1 2
+} 1
+test info-7.4 {info exists option} -body {
+    proc t1 {x} {
+        global _nonexistent_
+        return [info exists _nonexistent_]
+    }
+    t1 2
+} -setup {unset -nocomplain _nonexistent_} -result 0
+test info-7.5 {info exists option} {
+    proc t1 {x} {
+        set y 47
+        return [info exists y]
+    }
+    t1 2
+} 1
+test info-7.6 {info exists option} {
+    proc t1 {x} {return [info exists value]}
+    t1 2
+} 0
+test info-7.7 {info exists option} -setup {
+    catch {unset x}
+} -body {
+    set x(2) 44
+    list [info exists x] [info exists x(1)] [info exists x(2)]
+} -result {1 0 1}
+catch {unset x}
+test info-7.8 {info exists option} -body {
+    info exists
+} -returnCodes error -result {wrong # args: should be "info exists varName"}
+test info-7.9 {info exists option} -body {
+    info exists 1 2
+} -returnCodes error -result {wrong # args: should be "info exists varName"}
+
+test info-8.1 {info globals option} -body {
+    set x 1
+    set y 2
+    set value 23
+    set a " [info globals] "
+    list [string match {* x *} $a] [string match {* y *} $a] \
+            [string match {* value *} $a] [string match {* _foobar_ *} $a]
+} -cleanup {unset x y value a} -result {1 1 1 0}
+test info-8.2 {info globals option} -body {
+    set _xxx1 1
+    set _xxx2 2
+    lsort [info g _xxx*]
+} -cleanup {unset _xxx1 _xxx2} -result {_xxx1 _xxx2}
+test info-8.3 {info globals option} -returnCodes error -body {
+    info globals 1 2
+} -result {wrong # args: should be "info globals ?pattern?"}
+test info-8.4 {info globals option: may have leading namespace qualifiers} -body {
+    set x 0
+    list [info globals x] [info globals :x] [info globals ::x] [info globals :::x] [info globals ::::x]
+} -cleanup {unset x} -result {x {} x x x}
+test info-8.5 {info globals option: only return existing global variables} {
+    -setup {
+	unset -nocomplain ::NO_SUCH_VAR
+	proc evalInProc script {eval $script}
+    }
+    -body {
+	evalInProc {global NO_SUCH_VAR; info globals NO_SUCH_VAR}
+    }
+    -cleanup {
+	rename evalInProc {}
+    }
+    -result {}
+}
+
+test info-9.1 {info level option} {
+    info level
+} 0
+test info-9.2 {info level option} {
+    proc t1 {a b} {
+        set x [info le]
+        set y [info level 1]
+        list $x $y
+    }
+    t1 146 testString
+} {1 {t1 146 testString}}
+test info-9.3 {info level option} {
+    proc t1 {a b} {
+        t2 [expr $a*2] $b
+    }
+    proc t2 {x y} {
+        list [info level] [info level 1] [info level 2] [info level -1] \
+                [info level 0]
+    }
+    t1 146 {a {b c} {{{c}}}}
+} {2 {t1 146 {a {b c} {{{c}}}}} {t2 292 {a {b c} {{{c}}}}} {t1 146 {a {b c} {{{c}}}}} {t2 292 {a {b c} {{{c}}}}}}
+test info-9.4 {info level option} {
+    proc t1 {} {
+        set x [info level]
+        set y [info level 1]
+        list $x $y
+    }
+    t1
+} {1 t1}
+test info-9.5 {info level option} -body {
+    info level 1 2
+} -returnCodes error -result {wrong # args: should be "info level ?number?"}
+test info-9.6 {info level option} -body {
+    info level 123a
+} -returnCodes error -result {expected integer but got "123a"}
+test info-9.7 {info level option} -body {
+    info level 0
+} -returnCodes error -result {bad level "0"}
+test info-9.8 {info level option} -body {
+    proc t1 {} {info level -1}
+    t1
+} -returnCodes error -result {bad level "-1"}
+test info-9.9 {info level option} -body {
+    proc t1 {x} {info level $x}
+    t1 -3
+} -returnCodes error -result {bad level "-3"}
+test info-9.10 {info level option, namespaces} -body {
+    namespace eval t {info level 0}
+} -cleanup {
+    namespace delete t
+} -result {namespace eval t {info level 0}}
+test info-9.11 {info level option, aliases} -constraints knownBug -setup {
+    proc w {x y z} {info level 0}
+    interp alias {} a {} w a b
+} -body {
+    a c
+} -cleanup {
+    rename a {}
+    rename w {}
+} -result {a c}
+test info-9.12 {info level option, ensembles} -constraints knownBug -setup {
+    proc w {x y z} {info level 0}
+    namespace ensemble create -command a -map {foo ::w}
+} -body {
+    a foo 1 2 3
+} -cleanup {
+    rename a {}
+    rename w {}
+} -result {a foo 1 2 3}
+
+set savedLibrary $tcl_library
+test info-10.1 {info library option} -body {
+    info library x
+} -returnCodes error -result {wrong # args: should be "info library"}
+test info-10.2 {info library option} {
+    set tcl_library 12345
+    info library
+} {12345}
+test info-10.3 {info library option} -body {
+    unset tcl_library
+    info library
+} -returnCodes error -result {no library has been specified for Tcl}
+set tcl_library $savedLibrary; unset savedLibrary
+
+test info-11.1 {info loaded option} -body {
+    info loaded a b
+} -returnCodes error -result {wrong # args: should be "info loaded ?interp?"}
+test info-11.2 {info loaded option} -body {
+    info loaded {}; info loaded gorp
+} -returnCodes error -result {could not find interpreter "gorp"}
+
+test info-12.1 {info locals option} -body {
+    set a 22
+    proc t1 {x y} {
+        set b 13
+        set c testing
+        global a
+	global aa
+	set aa 23
+        return [info locals]
+    }
+    lsort [t1 23 24]
+} -cleanup {unset a aa} -result {b c x y}
+test info-12.2 {info locals option} {
+    proc t1 {x y} {
+        set xx1 2
+        set xx2 3
+        set y 4
+        return [info loc x*]
+    }
+    lsort [t1 2 3]
+} {x xx1 xx2}
+test info-12.3 {info locals option} -body {
+    info locals 1 2
+} -returnCodes error -result {wrong # args: should be "info locals ?pattern?"}
+test info-12.4 {info locals option} {
+    info locals
+} {}
+test info-12.5 {info locals option} {
+    proc t1 {} {return [info locals]}
+    t1
+} {}
+test info-12.6 {info locals vs unset compiled locals} {
+    proc t1 {lst} {
+        foreach $lst $lst {}
+        unset lst
+        return [info locals]
+    }
+    lsort [t1 {a b c c d e f}]
+} {a b c d e f}
+test info-12.7 {info locals with temporary variables} {
+    proc t1 {} {
+        foreach a {b c} {}
+        info locals
+    }
+    t1
+} {a}
+
+test info-13.1 {info nameofexecutable option} -returnCodes error -body {
+    info nameofexecutable foo
+} -result {wrong # args: should be "info nameofexecutable"}
+
+test info-14.1 {info patchlevel option} -body {
+    set a [info patchlevel]
+    regexp {[0-9]+\.[0-9]+([p[0-9]+)?} $a
+} -cleanup {unset a} -result 1
+test info-14.2 {info patchlevel option} -returnCodes error -body {
+    info patchlevel a
+} -result {wrong # args: should be "info patchlevel"}
+test info-14.3 {info patchlevel option} -setup {
+    set t $tcl_patchLevel
+} -body {
+    unset tcl_patchLevel
+    info patchlevel
+} -cleanup {
+    set tcl_patchLevel $t; unset t
+} -returnCodes error -result {can't read "tcl_patchLevel": no such variable}
+
+test info-15.1 {info procs option} -body {
+    proc t1 {} {}
+    proc t2 {} {}
+    set x " [info procs] "
+    list [string match {* t1 *} $x] [string match {* t2 *} $x] \
+            [string match {* _undefined_ *} $x]
+} -cleanup {unset x} -result {1 1 0}
+test info-15.2 {info procs option} {
+    proc _tt1 {} {}
+    proc _tt2 {} {}
+    lsort [info pr _tt*]
+} {_tt1 _tt2}
+catch {rename _tt1 {}}
+catch {rename _tt2 {}}
+test info-15.3 {info procs option} -body {
+    info procs 2 3
+} -returnCodes error -result {wrong # args: should be "info procs ?pattern?"}
+test info-15.4 {info procs option} -setup {
+    catch {namespace delete test_ns_info2}
+} -body {
+    namespace eval test_ns_info2 {
+        namespace import ::test_ns_info1::*
+        proc r {} {}
+        list [lsort [info procs]] [info procs p*]
+    }
+} -result {{p q r} p}
+test info-15.5 {info procs option with a proc in a namespace} -setup {
+    catch {namespace delete test_ns_info2}
+} -body {
+    namespace eval test_ns_info2 {
+	proc p1 { arg } {
+	    puts cmd
+	}
+        proc p2 { arg } {
+	    puts cmd
+	}
+    }
+    info procs ::test_ns_info2::p1
+} -result {::test_ns_info2::p1}
+test info-15.6 {info procs option with a pattern in a namespace} -setup {
+    catch {namespace delete test_ns_info2}
+} -body {
+    namespace eval test_ns_info2 {
+	proc p1 { arg } {
+	    puts cmd
+	}
+        proc p2 { arg } {
+	    puts cmd
+	}
+    }
+    lsort [info procs ::test_ns_info2::p*]
+} -result [lsort [list ::test_ns_info2::p1 ::test_ns_info2::p2]]
+test info-15.7 {info procs option with a global shadowing proc} -setup {
+    catch {namespace delete test_ns_info2}
+} -body {
+    proc string_cmd { arg } {
+        puts cmd
+    }
+    namespace eval test_ns_info2 {
+	proc string_cmd { arg } {
+	    puts cmd
+	}
+    }
+    info procs test_ns_info2::string*
+} -result {::test_ns_info2::string_cmd}
+# This regression test is currently commented out because it requires
+# that the implementation of "info procs" looks into the global namespace,
+# which it does not (in contrast to "info commands")
+test info-15.8 {info procs option with a global shadowing proc} -setup {
+    catch {namespace delete test_ns_info2}
+} -constraints knownBug -body {
+    proc string_cmd { arg } {
+        puts cmd
+    }
+    proc string_cmd2 { arg } {
+        puts cmd
+    }
+    namespace eval test_ns_info2 {
+	proc string_cmd { arg } {
+	    puts cmd
+	}
+    }
+    namespace eval test_ns_info2 {
+        lsort [info procs string*]
+    }
+} -result [lsort [list string_cmd string_cmd2]]
+
+test info-16.1 {info script option} -returnCodes error -body {
+    info script x x
+} -result {wrong # args: should be "info script ?filename?"}
+test info-16.2 {info script option} {
+    file tail [info sc]
+} "info.test"
+set gorpfile [makeFile "info script\n" gorp.info]
+test info-16.3 {info script option} {
+    list [source $gorpfile] [file tail [info script]]
+} [list $gorpfile info.test]
+test info-16.4 {resetting "info script" after errors} {
+    catch {source ~_nobody_/foo}
+    file tail [info script]
+} "info.test"
+test info-16.5 {resetting "info script" after errors} {
+    catch {source _nonexistent_}
+    file tail [info script]
+} "info.test"
+test info-16.6 {info script option} -body {
+    set script [info script]
+    list [file tail [info script]] \
+	    [info script newname.txt] \
+	    [file tail [info script $script]]
+} -result [list info.test newname.txt info.test] -cleanup {unset script}
+test info-16.7 {info script option} -body {
+    set script [info script]
+    info script newname.txt
+    list [source $gorpfile] [file tail [info script]] \
+	    [file tail [info script $script]]
+} -result [list $gorpfile newname.txt info.test] -cleanup {unset script}
+removeFile gorp.info
+set gorpfile [makeFile {list [info script] [info script foo.bar]} gorp.info]
+test info-16.8 {info script option} {
+    list [source $gorpfile] [file tail [info script]]
+} [list [list $gorpfile foo.bar] info.test]
+removeFile gorp.info; unset gorpfile
+
+test info-17.1 {info sharedlibextension option} -returnCodes error -body {
+    info sharedlibextension foo
+} -result {wrong # args: should be "info sharedlibextension"}
+
+test info-18.1 {info tclversion option} -body {
+    scan [info tclversion] "%d.%d%c" a b c
+} -cleanup {unset -nocomplain a b c} -result 2
+test info-18.2 {info tclversion option} -body {
+    info t 2
+} -returnCodes error -result {wrong # args: should be "info tclversion"}
+test info-18.3 {info tclversion option} -body {
+    unset tcl_version
+    info tclversion
+} -returnCodes error -setup {
+    set t $tcl_version
+} -cleanup {
+    set tcl_version $t; unset t
+} -result {can't read "tcl_version": no such variable}
+
+test info-19.1 {info vars option} -body {
+    set a 1
+    set b 2
+    proc t1 {x y} {
+        global a b
+        set c 33
+        return [info vars]
+    }
+    lsort [t1 18 19]
+} -cleanup {unset a b} -result {a b c x y}
+test info-19.2 {info vars option} -body {
+    set xxx1 1
+    set xxx2 2
+    proc t1 {xxa y} {
+        global xxx1 xxx2
+        set c 33
+        return [info vars x*]
+    }
+    lsort [t1 18 19]
+} -cleanup {unset xxx1 xxx2} -result {xxa xxx1 xxx2}
+test info-19.3 {info vars option} {
+    lsort [info vars]
+} [lsort [info globals]]
+test info-19.4 {info vars option} -returnCodes error -body {
+    info vars a b
+} -result {wrong # args: should be "info vars ?pattern?"}
+test info-19.5 {info vars with temporary variables} {
+    proc t1 {} {
+        foreach a {b c} {}
+        info vars
+    }
+    t1
+} {a}
+test info-19.6 {info vars: Bug 1072654} -setup {
+    namespace eval :: unset -nocomplain foo
+    catch {namespace delete x}
+} -body {
+    namespace eval x info vars foo
+} -cleanup {
+    namespace delete x
+} -result {}
+
+set functions {abs acos asin atan atan2 bool ceil cos cosh double entier exp floor fmod hypot int isqrt log log10 max min pow rand round sin sinh sqrt srand tan tanh wide}
+# Check whether the extra testing functions are defined...
+if {!([catch {expr T1()} msg] && ($msg eq {invalid command name "tcl::mathfunc::T1"}))} {
+    set functions "T1 T2 T3 $functions"  ;# A lazy way of prepending!
+}
+test info-20.1 {info functions option} {info functions sin} sin
+test info-20.2 {info functions option} {lsort [info functions]} $functions
+test info-20.3 {info functions option} {
+    lsort [info functions a*]
+} {abs acos asin atan atan2}
+test info-20.4 {info functions option} {
+    lsort [info functions *tan*]
+} {atan atan2 tan tanh}
+test info-20.5 {info functions option} -returnCodes error -body {
+    info functions raise an error
+} -result {wrong # args: should be "info functions ?pattern?"}
+unset functions msg
+
+test info-21.1 {miscellaneous error conditions} -returnCodes error -body {
+    info
+} -result {wrong # args: should be "info subcommand ?arg ...?"}
+test info-21.2 {miscellaneous error conditions} -returnCodes error -body {
+    info gorp
+} -result {unknown or ambiguous subcommand "gorp": must be args, body, class, cmdcount, commands, complete, coroutine, default, errorstack, exists, frame, functions, globals, hostname, level, library, loaded, locals, nameofexecutable, object, patchlevel, procs, script, sharedlibextension, tclversion, or vars}
+test info-21.3 {miscellaneous error conditions} -returnCodes error -body {
+    info c
+} -result {unknown or ambiguous subcommand "c": must be args, body, class, cmdcount, commands, complete, coroutine, default, errorstack, exists, frame, functions, globals, hostname, level, library, loaded, locals, nameofexecutable, object, patchlevel, procs, script, sharedlibextension, tclversion, or vars}
+test info-21.4 {miscellaneous error conditions} -returnCodes error -body {
+    info l
+} -result {unknown or ambiguous subcommand "l": must be args, body, class, cmdcount, commands, complete, coroutine, default, errorstack, exists, frame, functions, globals, hostname, level, library, loaded, locals, nameofexecutable, object, patchlevel, procs, script, sharedlibextension, tclversion, or vars}
+test info-21.5 {miscellaneous error conditions} -returnCodes error -body {
+    info s
+} -result {unknown or ambiguous subcommand "s": must be args, body, class, cmdcount, commands, complete, coroutine, default, errorstack, exists, frame, functions, globals, hostname, level, library, loaded, locals, nameofexecutable, object, patchlevel, procs, script, sharedlibextension, tclversion, or vars}
+
+##
+# ### ### ### ######### ######### #########
+## info frame
+
+## Helper
+# For the more complex results we cut the file name down to remove path
+# dependencies, and we use only part of the first line of the reported
+# command. The latter is required because otherwise the whole test case may
+# appear in some results, but the result is part of the testcase. An infinite
+# string would be required to describe that. The cutting-down breaks this.
+
+proc reduce {frame} {
+    set cmd [dict get $frame cmd]
+    if {[regexp \n $cmd]} {
+	dict set frame cmd \
+	    [string range [lindex [split $cmd \n] 0] 0 end-4]
+    }
+    if {[dict exists $frame file]} {
+	dict set frame file \
+	    [file tail [dict get $frame file]]
+    }
+    return $frame
+}
+
+proc subinterp {} { interp create sub ; interp debug sub -frame 1;
+    interp eval sub [list proc reduce [info args reduce] [info body reduce]]
+}
+
+## Helper
+# Generate a stacktrace from the current location to top.  This code
+# not only depends on the exact location of things, but also on the
+# implementation of tcltest. Any changes and these tests will have to
+# be updated.
+
+proc etrace {} {
+    set res {}
+    set level [info frame]
+    while {$level} {
+	lappend res [list $level [reduce [info frame $level]]]
+	incr level -1
+    }
+    return $res
+}
+
+test info-22.0 {info frame, levels} {!singleTestInterp} {
+    info frame
+} 7
+test info-22.1 {info frame, bad level relative} {!singleTestInterp} {
+    # catch is another level!, i.e. we have 8, not 7
+    catch {info frame -8} msg
+    set msg
+} {bad level "-8"}
+test info-22.2 {info frame, bad level absolute} {!singleTestInterp} {
+    # catch is another level!, i.e. we have 8, not 7
+    catch {info frame 9} msg
+    set msg
+} {bad level "9"}
+test info-22.3 {info frame, current, relative} -match glob -body {
+    info frame 0
+} -result {type source line 750 file */info.test cmd {info frame 0} proc ::tcltest::RunTest}
+test info-22.4 {info frame, current, relative, nested} -match glob -body {
+    set res [info frame 0]
+} -result {type source line 753 file */info.test cmd {info frame 0} proc ::tcltest::RunTest} -cleanup {unset res}
+test info-22.5 {info frame, current, absolute} -constraints {!singleTestInterp} -match glob -body {
+    reduce [info frame 7]
+} -result {type source line 756 file info.test cmd {info frame 7} proc ::tcltest::RunTest}
+test info-22.6 {info frame, global, relative} {!singleTestInterp} {
+    reduce [info frame -6]
+} {type source line 758 file info.test cmd test\ info-22.6\ \{info\ frame,\ global,\ relative\}\ \{!singleTestInter level 0}
+test info-22.7 {info frame, global, absolute} {!singleTestInterp} {
+    reduce [info frame 1]
+} {type source line 761 file info.test cmd test\ info-22.7\ \{info\ frame,\ global,\ absolute\}\ \{!singleTestInter level 0}
+test info-22.8 {info frame, basic trace} -match glob -body {
+    join [lrange [etrace] 0 2] \n
+} -result {* {type source line 730 file info.test cmd {info frame $level} proc ::etrace level 0}
+* {type source line 765 file info.test cmd etrace proc ::tcltest::RunTest}
+* {type source line * file tcltest* cmd {uplevel 1 $script} proc ::tcltest::RunTest}}
+unset -nocomplain msg
+
+test info-23.0.0 {eval'd info frame} {!singleTestInterp} {
+    eval {info frame}
+} 8
+test info-23.0.1 {eval'd info frame} -constraints {singleTestInterp} -match glob -body {
+    eval {info frame}
+} -result {1[12]} ;# SingleTestInterp results changes depending on running the whole suite, or info.test alone.
+test info-23.1.0 {eval'd info frame, semi-dynamic} {!singleTestInterp} {
+    eval info frame
+} 8
+test info-23.1.1 {eval'd info frame, semi-dynamic} -constraints {singleTestInterp} -match glob -body {
+    eval info frame
+} -result {1[12]}
+test info-23.2.0 {eval'd info frame, dynamic} -constraints {!singleTestInterp} -body {
+    set script {info frame}
+    eval $script
+} -cleanup {unset script} -result 8
+test info-23.2.1 {eval'd info frame, dynamic} -constraints {singleTestInterp} -match glob -body {
+    set script {info frame}
+    eval $script
+} -cleanup {unset script} -result {1[12]}
+test info-23.3 {eval'd info frame, literal} -match glob -body {
+    eval {
+	info frame 0
+    }
+} -result {type source line 793 file * cmd {info frame 0} proc ::tcltest::RunTest}
+test info-23.4 {eval'd info frame, semi-dynamic} {
+    eval info frame 0
+} {type eval line 1 cmd {info frame 0} proc ::tcltest::RunTest}
+test info-23.5 {eval'd info frame, dynamic} -cleanup {unset script} -body {
+    set script {info frame 0}
+    eval $script
+} -result {type eval line 1 cmd {info frame 0} proc ::tcltest::RunTest}
+test info-23.6 {eval'd info frame, trace} -match glob -cleanup {unset script} -body {
+    set script {etrace}
+    join [lrange [eval $script] 0 2] \n
+} -result {* {type source line 730 file info.test cmd {info frame $level} proc ::etrace level 0}
+* {type eval line 1 cmd etrace proc ::tcltest::RunTest}
+* {type source line 805 file info.test cmd {eval $script} proc ::tcltest::RunTest}}
+
+# -------------------------------------------------------------------------
+
+# Procedures defined in scripts which are arguments to control
+# structures (like 'namespace eval', 'interp eval', 'if', 'while',
+# 'switch', 'catch', 'for', 'foreach', etc.) have no absolute
+# location. The command implementations execute such scripts through
+# Tcl_EvalObjEx. Flag 0 causes it to use the bytecode compiler. This
+# causes the connection to the context to be lost. Currently only
+# procedure bodies are able to remember their context.
+
+# NOTE THAT THESE DO NOT USE THE -setup OPTION TO [test]
+
+# -------------------------------------------------------------------------
+
+namespace eval foo {
+    proc bar {} {info frame 0}
+}
+
+test info-24.0 {info frame, interaction, namespace eval} -body {
+    reduce [foo::bar]
+} -cleanup {
+    namespace delete foo
+} -result {type source line 825 file info.test cmd {info frame 0} proc ::foo::bar level 0}
+
+# -------------------------------------------------------------------------
+
+set flag 1
+if {$flag} {
+    namespace eval foo {}
+    proc ::foo::bar {} {info frame 0}
+}
+
+test info-24.1 {info frame, interaction, if} -body {
+    reduce [foo::bar]
+} -cleanup {
+    namespace delete foo
+} -result {type source line 839 file info.test cmd {info frame 0} proc ::foo::bar level 0}
+
+# -------------------------------------------------------------------------
+
+set flag 1
+while {$flag} {
+    namespace eval foo {}
+    proc ::foo::bar {} {info frame 0}
+    set flag 0
+};unset flag
+
+test info-24.2 {info frame, interaction, while} -body {
+    reduce [foo::bar]
+} -cleanup {
+    namespace delete foo
+} -result {type source line 853 file info.test cmd {info frame 0} proc ::foo::bar level 0}
+
+# -------------------------------------------------------------------------
+
+catch {
+    namespace eval foo {}
+    proc ::foo::bar {} {info frame 0}
+}
+
+test info-24.3 {info frame, interaction, catch} -body {
+    reduce [foo::bar]
+} -cleanup {
+    namespace delete foo
+} -result {type source line 867 file info.test cmd {info frame 0} proc ::foo::bar level 0}
+
+# -------------------------------------------------------------------------
+
+foreach var val {
+    namespace eval foo {}
+    proc ::foo::bar {} {info frame 0}
+    break
+}; unset var
+
+test info-24.4 {info frame, interaction, foreach} -body {
+    reduce [foo::bar]
+} -cleanup {
+    namespace delete foo
+} -result {type source line 880 file info.test cmd {info frame 0} proc ::foo::bar level 0}
+
+# -------------------------------------------------------------------------
+
+for {} {1} {} {
+    namespace eval foo {}
+    proc ::foo::bar {} {info frame 0}
+    break
+}
+
+test info-24.5 {info frame, interaction, for} -body {
+    reduce [foo::bar]
+} -cleanup {
+    namespace delete foo
+} -result {type source line 894 file info.test cmd {info frame 0} proc ::foo::bar level 0}
+
+# -------------------------------------------------------------------------
+
+namespace eval foo {}
+set x foo
+switch -exact -- $x {
+    foo {
+	proc ::foo::bar {} {info frame 0}
+    }
+}
+
+test info-24.6.0 {info frame, interaction, switch, list body} -body {
+    reduce [foo::bar]
+} -cleanup {
+    namespace delete foo
+    unset x
+} -result {type source line 910 file info.test cmd {info frame 0} proc ::foo::bar level 0}
+
+# -------------------------------------------------------------------------
+
+namespace eval foo {}
+set x foo
+switch -exact -- $x foo {
+    proc ::foo::bar {} {info frame 0}
+}
+
+test info-24.6.1 {info frame, interaction, switch, multi-body} -body {
+    reduce [foo::bar]
+} -cleanup {
+    namespace delete foo
+    unset x
+} -result {type source line 926 file info.test cmd {info frame 0} proc ::foo::bar level 0}
+
+# -------------------------------------------------------------------------
+
+namespace eval foo {}
+set x foo
+switch -exact -- $x [list foo {
+    proc ::foo::bar {} {info frame 0}
+}]
+
+test info-24.6.2 {info frame, interaction, switch, list body, dynamic} -body {
+    reduce [foo::bar]
+} -cleanup {
+    namespace delete foo
+    unset x
+} -result {type proc line 1 cmd {info frame 0} proc ::foo::bar level 0}
+
+# -------------------------------------------------------------------------
+
+namespace eval foo {}
+dict for {k v} {foo bar} {
+    proc ::foo::bar {} {info frame 0}
+}
+
+test info-24.7 {info frame, interaction, dict for} {
+    reduce [foo::bar]
+} {type source line 955 file info.test cmd {info frame 0} proc ::foo::bar level 0}
+
+namespace delete foo; unset k v
+
+# -------------------------------------------------------------------------
+
+namespace eval foo {}
+set thedict {foo bar}
+dict with thedict {
+    proc ::foo::bar {} {info frame 0}
+}
+
+test info-24.8 {info frame, interaction, dict with} {
+    reduce [foo::bar]
+} {type source line 969 file info.test cmd {info frame 0} proc ::foo::bar level 0}
+
+namespace delete foo
+unset thedict foo
+
+# -------------------------------------------------------------------------
+
+namespace eval foo {}
+dict filter {foo bar} script {k v} {
+    proc ::foo::bar {} {info frame 0}
+    set x 1
+}; unset k v x
+
+test info-24.9 {info frame, interaction, dict filter} {
+    reduce [foo::bar]
+} {type source line 983 file info.test cmd {info frame 0} proc ::foo::bar level 0}
+
+namespace delete foo
+#unset x
+
+# -------------------------------------------------------------------------
+
+eval {
+    proc bar {} {info frame 0}
+}
+
+test info-25.0 {info frame, proc in eval} {
+    reduce [bar]
+} {type source line 997 file info.test cmd {info frame 0} proc ::bar level 0}
+# Don't need to clean up yet...
+
+proc bar {} {info frame 0}
+
+test info-25.1 {info frame, regular proc} {
+    reduce [bar]
+} {type source line 1005 file info.test cmd {info frame 0} proc ::bar level 0}
+
+rename bar {}
+
+# -------------------------------------------------------------------------
+# More info-30.x test cases at the end of the file.
+test info-30.0 {bs+nl in literal words} -cleanup {unset res} -body {
+    if {1} {
+	set res \
+	    [reduce [info frame 0]];#1018
+    }
+    return $res
+    # This was reporting line 3 instead of the correct 4 because the
+    # bs+nl combination is subst by the parser before the 'if'
+    # command, and the bcc, see the word. Fixed by recording the
+    # offsets of all bs+nl sequences in literal words, then using the
+    # information in the bcc and other places to bump line numbers when
+    # parsing over the location. Also affected: testcases 22.8 and 23.6.
+} -result {type source line 1018 file info.test cmd {info frame 0} proc ::tcltest::RunTest}
+
+# -------------------------------------------------------------------------
+# See 24.0 - 24.5 for similar situations, using literal scripts.
+
+set body {set flag 0
+    set a c
+    set res [info frame 0]} ;# line 3!
+
+test info-31.0 {ns eval, script in variable} -body {namespace eval foo {variable res {}}
+    namespace eval foo $body
+    return $foo::res
+} -result {type eval line 3 cmd {info frame 0} level 0} -cleanup {
+    catch {namespace delete foo}
+}
+test info-31.1 {if, script in variable} -cleanup {unset res a flag} -body {
+    if 1 $body
+    return $res
+} -result {type eval line 3 cmd {info frame 0} proc ::tcltest::RunTest}
+
+test info-31.1a {if, script in variable} -cleanup {unset res a flag} -body {
+    if 1 then $body
+    return $res
+} -result {type eval line 3 cmd {info frame 0} proc ::tcltest::RunTest}
+
+test info-31.2 {while, script in variable} -cleanup {unset flag res a} -body {
+    set flag 1
+    while {$flag} $body
+    return $res
+} -result {type eval line 3 cmd {info frame 0} proc ::tcltest::RunTest}
+
+# .3 - proc - scoping prevent return of result ...
+
+test info-31.4 {foreach, script in variable} -cleanup {unset var res a flag} -body {
+    foreach var val $body
+    set res
+} -result {type eval line 3 cmd {info frame 0} proc ::tcltest::RunTest}
+
+test info-31.5 {for, script in variable} -cleanup {unset flag res a} -body {
+    set flag 1
+    for {} {$flag} {} $body
+    return $res
+} -result {type eval line 3 cmd {info frame 0} proc ::tcltest::RunTest}
+
+test info-31.6 {eval, script in variable} -cleanup {unset res a flag} -body {
+    eval $body
+    return $res
+} -result {type eval line 3 cmd {info frame 0} proc ::tcltest::RunTest}
+
+# -------------------------------------------------------------------------
+
+set body {
+    foo {
+	proc ::foo::bar {} {info frame 0}
+    }
+}
+
+namespace eval foo {}
+set x foo
+switch -exact -- $x $body; unset body
+
+test info-31.7 {info frame, interaction, switch, dynamic} -body {
+    reduce [foo::bar]
+} -cleanup {
+    namespace delete foo
+    unset x
+} -result {type proc line 1 cmd {info frame 0} proc ::foo::bar level 0}
+
+# -------------------------------------------------------------------------
+
+set body {
+    proc ::foo::bar {} {info frame 0}
+}
+
+namespace eval foo {}
+eval $body
+
+test info-32.0 {info frame, dynamic procedure} -body {
+    reduce [foo::bar]
+} -cleanup {
+    namespace delete foo
+} -result {type proc line 1 cmd {info frame 0} proc ::foo::bar level 0}
+
+# -------------------------------------------------------------------------
+
+namespace {*}{
+    eval
+    foo
+    {proc bar {} {info frame 0}}
+}
+test info-33.0 {{*}, literal, direct} -body {
+    reduce [foo::bar]
+} -cleanup {
+    namespace delete foo
+} -result {type source line 1115 file info.test cmd {info frame 0} proc ::foo::bar level 0}
+
+# -------------------------------------------------------------------------
+
+namespace eval foo {}
+proc foo::bar {} {
+    set flag 1
+    if {*}{
+	{$flag}
+	{info frame 0}
+    }
+}
+test info-33.1 {{*}, literal, simple, bytecompiled} -body {
+    reduce [foo::bar]
+} -cleanup {
+    namespace delete foo
+} -result {type source line 1130 file info.test cmd {info frame 0} proc ::foo::bar level 0}
+
+# -------------------------------------------------------------------------
+
+namespace {*}"
+    eval
+    foo
+    {proc bar {} {info frame 0}}
+"
+test info-33.2 {{*}, literal, direct} {
+    reduce [foo::bar]
+} {type source line 1144 file info.test cmd {info frame 0} proc ::foo::bar level 0}
+
+namespace delete foo
+
+# -------------------------------------------------------------------------
+
+namespace {*}"eval\nfoo\n{proc bar {} {info frame 0}}\n"
+
+test info-33.2a {{*}, literal, not simple, direct} {
+    reduce [foo::bar]
+} {type proc line 1 cmd {info frame 0} proc ::foo::bar level 0}
+
+namespace delete foo
+
+# -------------------------------------------------------------------------
+
+namespace eval foo {}
+proc foo::bar {} {
+    set flag 1
+    if {*}"
+	{1}
+	{info frame 0}
+    "
+}
+test info-33.3 {{*}, literal, simple, bytecompiled} {
+    reduce [foo::bar]
+} {type source line 1169 file info.test cmd {info frame 0} proc ::foo::bar level 0}
+
+namespace delete foo
+
+# -------------------------------------------------------------------------
+
+namespace eval foo {}
+proc foo::bar {} {
+    set flag 1
+    if {*}"\n{1}\n{info frame 0}"
+}
+test info-33.3a {{*}, literal, not simple, bytecompiled} {
+    reduce [foo::bar]
+} {type eval line 1 cmd {info frame 0} proc ::foo::bar level 0}
+
+namespace delete foo
+
+# -------------------------------------------------------------------------
+
+set body {
+    eval
+    foo
+    {proc bar {} {
+	info frame 0
+    }}
+}
+namespace {*}$body
+test info-34.0 {{*}, dynamic, direct} {
+    reduce [foo::bar]
+} {type proc line 2 cmd {info frame 0} proc ::foo::bar level 0}
+
+unset body
+namespace delete foo
+
+# -------------------------------------------------------------------------
+
+namespace eval foo {}
+set body {
+    {$flag}
+    {info frame 0}
+}
+proc foo::bar {} {
+    global body ; set flag 1
+    if {*}$body
+}
+test info-34.1 {{*}, literal, bytecompiled} {
+    reduce [foo::bar]
+} {type eval line 1 cmd {info frame 0} proc ::foo::bar level 0}
+
+unset body
+namespace delete foo
+
+# -------------------------------------------------------------------------
+
+proc foo {} {
+    apply {
+	{x y}
+	{info frame 0}
+    } 0 0
+}
+test info-35.0 {apply, literal} {
+    reduce [foo]
+} {type source line 1231 file info.test cmd {info frame 0} lambda {
+	{x y}
+	{info frame 0}
+    } level 0}
+rename foo {}
+
+set lambda {
+    {x y}
+    {info frame 0}
+}
+test info-35.1 {apply, dynamic} {
+    reduce [apply $lambda 0 0]
+} {type proc line 1 cmd {info frame 0} lambda {
+    {x y}
+    {info frame 0}
+} level 0}
+unset lambda
+
+# -------------------------------------------------------------------------
+
+namespace eval foo {}
+proc foo::bar {} {
+    dict for {k v} {foo bar} {
+	set x [info frame 0]
+    }
+    set x
+}
+test info-36.0 {info frame, dict for, bcc} -body {
+    reduce [foo::bar]
+} -result {type source line 1259 file info.test cmd {info frame 0} proc ::foo::bar level 0}
+
+namespace delete foo
+
+# -------------------------------------------------------------------------
+
+namespace eval foo {}
+proc foo::bar {} {
+    set x foo
+    switch -exact -- $x {
+	foo {set y [info frame 0]}
+    }
+    set y
+}
+
+test info-36.1.0 {switch, list literal, bcc} -body {
+    reduce [foo::bar]
+} -result {type source line 1275 file info.test cmd {info frame 0} proc ::foo::bar level 0}
+
+namespace delete foo
+
+# -------------------------------------------------------------------------
+
+namespace eval foo {}
+proc foo::bar {} {
+    set x foo
+    switch -exact -- $x foo {set y [info frame 0]}
+    set y
+}
+
+test info-36.1.1 {switch, multi-body literals, bcc} -body {
+    reduce [foo::bar]
+} -result {type source line 1291 file info.test cmd {info frame 0} proc ::foo::bar level 0}
+
+namespace delete foo
+
+# -------------------------------------------------------------------------
+
+test info-37.0 {eval pure list, single line} -match glob -body {
+    # Basically, counting the newline in the word seen through $foo
+    # doesn't really make sense. It makes a bit of sense if the word
+    # would have been a string literal in the command list.
+    #
+    # Problem: At the point where we see the list elements we cannot
+    # distinguish the two cases, thus we cannot switch between
+    # count/not-count, it is has to be one or the other for all
+    # cases. Of the two possibilities miguel convinced me that 'not
+    # counting' is the more proper.
+    set foo {b
+	c}
+    set cmd [list foreach $foo {x y} {
+	set res [join [lrange [etrace] 0 2] \n]
+	break
+    }]
+    eval $cmd
+    return $res
+} -result {* {type source line 730 file info.test cmd {info frame $level} proc ::etrace level 0}
+* {type eval line 2 cmd etrace proc ::tcltest::RunTest}
+* {type eval line 1 cmd foreac proc ::tcltest::RunTest}} -cleanup {unset foo cmd res b c}
+
+# -------------------------------------------------------------------------
+
+# 6 cases.
+## DV. direct-var          - unchanged
+## DPV direct-proc-var     - ditto
+## PPV proc-proc-var       - ditto
+## DL. direct-literal      - now tracking absolute location
+## DPL direct-proc-literal - ditto
+## PPL proc-proc-literal   - ditto
+## ### ### ### ######### ######### #########"
+
+proc control {vv script} {
+    upvar 1 $vv var
+    return [uplevel 1 $script]
+}
+
+proc datal {} {
+    control y {
+	set y PPL
+	etrace
+    }
+}
+
+proc datav {} {
+    set script {
+	set y PPV
+	etrace
+    }
+    control y $script
+}
+
+test info-38.1 {location information for uplevel, dv, direct-var} -match glob -body {
+    set script {
+	set y DV.
+	etrace
+    }
+    join [lrange [uplevel \#0 $script] 0 2] \n
+} -result {* {type source line 730 file info.test cmd {info frame $level} proc ::etrace level 0}
+* {type eval line 3 cmd etrace proc ::tcltest::RunTest}
+* {type source line 1361 file info.test cmd {uplevel \\#0 $script} proc ::tcltest::RunTest}} -cleanup {unset script y}
+
+# 38.2 moved to bottom to not disturb other tests with the necessary changes to this one.
+
+
+
+
+
+
+
+
+test info-38.3 {location information for uplevel, dpv, direct-proc-var} -match glob -body {
+    set script {
+	set y DPV
+	etrace
+    }
+    join [lrange [control y $script] 0 3] \n
+} -result {* {type source line 730 file info.test cmd {info frame $level} proc ::etrace level 0}
+* {type eval line 3 cmd etrace proc ::control}
+* {type source line 1338 file info.test cmd {uplevel 1 $script} proc ::control}
+* {type source line 1380 file info.test cmd {control y $script} proc ::tcltest::RunTest}} -cleanup {unset script y}
+
+# 38.4 moved to bottom to not disturb other tests with the necessary changes to this one.
+
+
+
+
+
+
+
+
+
+test info-38.5 {location information for uplevel, ppv, proc-proc-var} -match glob -body {
+    join [lrange [datav] 0 4] \n
+} -result {* {type source line 730 file info.test cmd {info frame $level} proc ::etrace level 0}
+* {type eval line 3 cmd etrace proc ::control}
+* {type source line 1338 file info.test cmd {uplevel 1 $script} proc ::control}
+* {type source line 1353 file info.test cmd {control y $script} proc ::datav level 1}
+* {type source line 1397 file info.test cmd datav proc ::tcltest::RunTest}}
+
+# 38.6 moved to bottom to not disturb other tests with the necessary changes to this one.
+
+
+
+
+
+
+
+testConstraint testevalex [llength [info commands testevalex]]
+test info-38.7 {location information for arg substitution} -constraints testevalex -match glob -body {
+    join [lrange [testevalex {return -level 0 [etrace]}] 0 3] \n
+} -result {* {type source line 730 file info.test cmd {info frame \$level} proc ::etrace level 0}
+* {type eval line 1 cmd etrace proc ::tcltest::RunTest}
+* {type source line 1414 file info.test cmd {testevalex {return -level 0 \[etrace]}} proc ::tcltest::RunTest}
+* {type source line * file tcltest* cmd {uplevel 1 $script} proc ::tcltest::RunTest}}
+
+# -------------------------------------------------------------------------
+# literal sharing
+
+test info-39.0 {location information not confused by literal sharing} -body {
+    namespace eval ::foo {}
+    proc ::foo::bar {} {
+	lappend res {}
+	lappend res [reduce [eval {info frame 0}]]
+	lappend res [reduce [eval {info frame 0}]]
+	return $res
+    }
+    set res [::foo::bar]
+    namespace delete ::foo
+    join $res \n
+} -cleanup {unset res} -result {
+type source line 1427 file info.test cmd {info frame 0} proc ::foo::bar level 0
+type source line 1428 file info.test cmd {info frame 0} proc ::foo::bar level 0}
+
+# -------------------------------------------------------------------------
+# Additional tests for info-30.*, handling of continuation lines (bs+nl sequences).
+
+test info-30.1 {bs+nl in literal words, procedure body, compiled} -body {
+    proc abra {} {
+	if {1} \
+	    {
+		return \
+		    [reduce [info frame 0]];# line 1446
+	    }
+    }
+    abra
+} -cleanup {
+    rename abra {}
+} -result {type source line 1446 file info.test cmd {info frame 0} proc ::abra level 0}
+
+test info-30.2 {bs+nl in literal words, namespace script} {
+    namespace eval xxx {
+	variable res \
+	    [info frame 0];# line 1457
+    }
+    return [reduce $xxx::res]
+} {type source line 1457 file info.test cmd {info frame 0} level 0}
+
+test info-30.3 {bs+nl in literal words, namespace multi-word script} {
+    namespace eval xxx variable res \
+	[list [reduce [info frame 0]]];# line 1464
+    return $xxx::res
+} {type source line 1464 file info.test cmd {info frame 0} proc ::tcltest::RunTest}
+
+test info-30.4 {bs+nl in literal words, eval script} -cleanup {unset res} -body {
+    eval {
+	set ::res \
+	    [reduce [info frame 0]];# line 1471
+    }
+    return $res
+} -result {type source line 1471 file info.test cmd {info frame 0} proc ::tcltest::RunTest}
+
+test info-30.5 {bs+nl in literal words, eval script, with nested words} -body {
+    eval {
+	if {1} \
+	    {
+		set ::res \
+		    [reduce [info frame 0]];# line 1481
+	    }
+    }
+    return $res
+} -cleanup {unset res} -result {type source line 1481 file info.test cmd {info frame 0} proc ::tcltest::RunTest}
+
+test info-30.6 {bs+nl in computed word} -cleanup {unset res} -body {
+    set res "\
+[reduce [info frame 0]]";# line 1489
+} -result { type source line 1489 file info.test cmd {info frame 0} proc ::tcltest::RunTest}
+
+test info-30.7 {bs+nl in computed word, in proc} -body {
+    proc abra {} {
+	return "\
+[reduce [info frame 0]]";# line 1495
+    }
+    abra
+} -cleanup {
+    rename abra {}
+} -result { type source line 1495 file info.test cmd {info frame 0} proc ::abra level 0}
+
+test info-30.8 {bs+nl in computed word, nested eval} -body {
+    eval {
+	set \
+	    res "\
+[reduce [info frame 0]]";# line 1506
+}
+} -cleanup {unset res} -result { type source line 1506 file info.test cmd {info frame 0} proc ::tcltest::RunTest}
+
+test info-30.9 {bs+nl in computed word, nested eval} -body {
+    eval {
+	set \
+	    res "\
+[reduce \
+     [info frame 0]]";# line 1515
+}
+} -cleanup {unset res} -result { type source line 1515 file info.test cmd {info frame 0} proc ::tcltest::RunTest}
+
+test info-30.10 {bs+nl in computed word, key to array} -body {
+    set tmp([set \
+	    res "\
+[reduce \
+     [info frame 0]]"]) x ; #1523
+    unset tmp
+    set res
+} -cleanup {unset res} -result { type source line 1523 file info.test cmd {info frame 0} proc ::tcltest::RunTest}
+
+test info-30.11 {bs+nl in subst arguments} -body {
+    subst {[set \
+	    res "\
+[reduce \
+     [info frame 0]]"]} ; #1532
+} -cleanup {unset res} -result { type source line 1532 file info.test cmd {info frame 0} proc ::tcltest::RunTest}
+
+test info-30.12 {bs+nl in computed word, nested eval} -body {
+    eval {
+	set \
+	    res "\
+[set x {}] \
+[reduce \
+     [info frame 0]]";# line 1541
+}
+} -cleanup {unset res x} -result {   type source line 1541 file info.test cmd {info frame 0} proc ::tcltest::RunTest}
+
+test info-30.13 {bs+nl in literal words, uplevel script, with nested words} -body {
+    subinterp ; set res [interp eval sub { uplevel #0 {
+	if {1} \
+	    {
+		set ::res \
+		    [reduce [info frame 0]];# line 1550
+	    }
+    }
+    set res }] ; interp delete sub ; set res
+} -cleanup {unset res} -result {type source line 1550 file info.test cmd {info frame 0} level 0}
+
+test info-30.14 {bs+nl, literal word, uplevel through proc} {
+    subinterp ; set res [interp eval sub { proc abra {script} {
+	uplevel 1 $script
+    }
+    set res [abra {
+	return "\
+[reduce [info frame 0]]";# line 1562
+    }]
+    rename abra {}
+    set res }] ; interp delete sub ; set res
+} { type source line 1562 file info.test cmd {info frame 0} proc ::abra}
+
+test info-30.15 {bs+nl in literal words, nested proc body, compiled} {
+    proc a {} {
+	proc b {} {
+	    if {1} \
+		{
+		    return \
+			[reduce [info frame 0]];# line 1574
+		}
+	}
+    }
+    a ; set res [b]
+    rename a {}
+    rename b {}
+    set res
+} {type source line 1574 file info.test cmd {info frame 0} proc ::b level 0}
+
+test info-30.16 {bs+nl in multi-body switch, compiled} {
+    proc a {value} {
+	switch -regexp -- $value \
+	    ^key     { info frame 0; # 1587 } \
+	    \t###    { info frame 0; # 1588 } \
+	    {[0-9]*} { info frame 0; # 1589 }
+    }
+    set res {}
+    lappend res [reduce [a {key   }]]
+    lappend res [reduce [a {1alpha}]]
+    set res "\n[join $res \n]"
+} {
+type source line 1587 file info.test cmd {info frame 0} proc ::a level 0
+type source line 1589 file info.test cmd {info frame 0} proc ::a level 0}
+
+test info-30.17 {bs+nl in multi-body switch, direct} {
+    switch -regexp -- {key    } \
+	^key     { reduce [info frame 0] ;# 1601 } \
+        \t###    { } \
+        {[0-9]*} { }
+} {type source line 1601 file info.test cmd {info frame 0} proc ::tcltest::RunTest}
+
+test info-30.18 {bs+nl, literal word, uplevel through proc, appended, loss of primary tracking data} {
+    proc abra {script} {
+	append script "\n# end of script"
+	uplevel 1 $script
+    }
+    set res [abra {
+	return "\
+[reduce [info frame 0]]";# line 1613, still line of 3 appended script
+    }]
+    rename abra {}
+    set res
+} { type eval line 3 cmd {info frame 0} proc ::abra}
+# { type source line 1606 file info.test cmd {info frame 0} proc ::abra}
+
+test info-30.19 {bs+nl in single-body switch, compiled} {
+    proc a {value} {
+	switch -regexp -- $value {
+	    ^key     { reduce \
+			   [info frame 0] }
+	    \t       { reduce \
+			   [info frame 0] }
+	    {[0-9]*} { reduce \
+			   [info frame 0] }
+	}
+    }
+    set res {}
+    lappend res [a {key   }]
+    lappend res [a {1alpha}]
+    set res "\n[join $res \n]"
+} {
+type source line 1624 file info.test cmd {info frame 0} proc ::a level 0
+type source line 1628 file info.test cmd {info frame 0} proc ::a level 0}
+
+test info-30.20 {bs+nl in single-body switch, direct} {
+    switch -regexp -- {key    } { \
+
+	^key     { reduce \
+		       [info frame 0] }
+	\t###    { }
+        {[0-9]*} { }
+    }
+} {type source line 1643 file info.test cmd {info frame 0} proc ::tcltest::RunTest}
+
+test info-30.21 {bs+nl in if, full compiled} {
+    proc a {value} {
+	if {$value} \
+	    {info frame 0} \
+	    {info frame 0} ; # 1653
+    }
+    set res {}
+    lappend res [reduce [a 1]]
+    lappend res [reduce [a 0]]
+    set res "\n[join $res \n]"
+} {
+type source line 1652 file info.test cmd {info frame 0} proc ::a level 0
+type source line 1653 file info.test cmd {info frame 0} proc ::a level 0}
+
+test info-30.22 {bs+nl in computed word, key to array, compiled} {
+    proc a {} {
+	set tmp([set \
+		     res "\
+[reduce \
+     [info frame 0]]"]) x ; #1668
+    unset tmp
+    set res
+    }
+    set res [a]
+    rename a {}
+    set res
+} { type source line 1668 file info.test cmd {info frame 0} proc ::a level 0}
+
+test info-30.23 {bs+nl in multi-body switch, full compiled} {
+    proc a {value} {
+	switch -exact -- $value \
+	    key     { info frame 0; # 1680 } \
+	    xxx     { info frame 0; # 1681 } \
+	    000     { info frame 0; # 1682 }
+    }
+    set res {}
+    lappend res [reduce [a key]]
+    lappend res [reduce [a 000]]
+    set res "\n[join $res \n]"
+} {
+type source line 1680 file info.test cmd {info frame 0} proc ::a level 0
+type source line 1682 file info.test cmd {info frame 0} proc ::a level 0}
+
+test info-30.24 {bs+nl in single-body switch, full compiled} {
+    proc a {value} {
+	switch -exact -- $value {
+	    key { reduce \
+		      [info frame 0] }
+	    xxx { reduce \
+		      [info frame 0] }
+	    000 { reduce \
+		      [info frame 0] }
+	}
+    }
+    set res {}
+    lappend res [a key]
+    lappend res [a 000]
+    set res "\n[join $res \n]"
+} {
+type source line 1696 file info.test cmd {info frame 0} proc ::a level 0
+type source line 1700 file info.test cmd {info frame 0} proc ::a level 0}
+
+test info-30.25 {TIP 280 for compiled [subst]} {
+    subst {[reduce [info frame 0]]} ; # 1712
+} {type source line 1712 file info.test cmd {info frame 0} proc ::tcltest::RunTest}
+test info-30.26 {TIP 280 for compiled [subst]} {
+    subst \
+	    {[reduce [info frame 0]]} ; # 1716
+} {type source line 1716 file info.test cmd {info frame 0} proc ::tcltest::RunTest}
+test info-30.27 {TIP 280 for compiled [subst]} {
+    subst {
+[reduce [info frame 0]]} ; # 1720
+} {
+type source line 1720 file info.test cmd {info frame 0} proc ::tcltest::RunTest}
+test info-30.28 {TIP 280 for compiled [subst]} {
+    subst {\
+[reduce [info frame 0]]} ; # 1725
+} { type source line 1725 file info.test cmd {info frame 0} proc ::tcltest::RunTest}
+test info-30.29 {TIP 280 for compiled [subst]} {
+    subst {foo\
+[reduce [info frame 0]]} ; # 1729
+} {foo type source line 1729 file info.test cmd {info frame 0} proc ::tcltest::RunTest}
+test info-30.30 {TIP 280 for compiled [subst]} {
+    subst {foo
+[reduce [info frame 0]]} ; # 1733
+} {foo
+type source line 1733 file info.test cmd {info frame 0} proc ::tcltest::RunTest}
+test info-30.31 {TIP 280 for compiled [subst]} {
+    subst {[][reduce [info frame 0]]} ; # 1737
+} {type source line 1737 file info.test cmd {info frame 0} proc ::tcltest::RunTest}
+test info-30.32 {TIP 280 for compiled [subst]} {
+    subst {[\
+][reduce [info frame 0]]} ; # 1741
+} {type source line 1741 file info.test cmd {info frame 0} proc ::tcltest::RunTest}
+test info-30.33 {TIP 280 for compiled [subst]} {
+    subst {[
+][reduce [info frame 0]]} ; # 1745
+} {type source line 1745 file info.test cmd {info frame 0} proc ::tcltest::RunTest}
+test info-30.34 {TIP 280 for compiled [subst]} {
+    subst {[format %s {}
+][reduce [info frame 0]]} ; # 1749
+} {type source line 1749 file info.test cmd {info frame 0} proc ::tcltest::RunTest}
+test info-30.35 {TIP 280 for compiled [subst]} {
+    subst {[format %s {}
+]
+[reduce [info frame 0]]} ; # 1754
+} {
+type source line 1754 file info.test cmd {info frame 0} proc ::tcltest::RunTest}
+test info-30.36 {TIP 280 for compiled [subst]} {
+    subst {
+[format %s {}][reduce [info frame 0]]} ; # 1759
+} {
+type source line 1759 file info.test cmd {info frame 0} proc ::tcltest::RunTest}
+test info-30.37 {TIP 280 for compiled [subst]} {
+    subst {
+[format %s {}]
+[reduce [info frame 0]]} ; # 1765
+} {
+
+type source line 1765 file info.test cmd {info frame 0} proc ::tcltest::RunTest}
+test info-30.38 {TIP 280 for compiled [subst]} {
+    subst {\
+[format %s {}][reduce [info frame 0]]} ; # 1771
+} { type source line 1771 file info.test cmd {info frame 0} proc ::tcltest::RunTest}
+test info-30.39 {TIP 280 for compiled [subst]} {
+    subst {\
+[format %s {}]\
+[reduce [info frame 0]]} ; # 1776
+} {  type source line 1776 file info.test cmd {info frame 0} proc ::tcltest::RunTest}
+test info-30.40 {TIP 280 for compiled [subst]} -setup {
+    unset -nocomplain empty
+} -body {
+    set empty {}
+    subst {$empty[reduce [info frame 0]]} ; # 1782
+} -cleanup {
+    unset empty
+} -result {type source line 1782 file info.test cmd {info frame 0} proc ::tcltest::RunTest}
+test info-30.41 {TIP 280 for compiled [subst]} -setup {
+    unset -nocomplain empty
+} -body {
+    set empty {}
+    subst {$empty
+[reduce [info frame 0]]} ; # 1791
+} -cleanup {
+    unset empty
+} -result {
+type source line 1791 file info.test cmd {info frame 0} proc ::tcltest::RunTest}
+test info-30.42 {TIP 280 for compiled [subst]} -setup {
+    unset -nocomplain empty
+} -body {
+    set empty {}; subst {$empty\
+[reduce [info frame 0]]} ; # 1800
+} -cleanup {
+    unset empty
+} -result { type source line 1800 file info.test cmd {info frame 0} proc ::tcltest::RunTest}
+test info-30.43 {TIP 280 for compiled [subst]} -body {
+    unset -nocomplain a\nb
+    set a\nb {}
+    subst {${a
+b}[reduce [info frame 0]]} ; # 1808
+} -cleanup {unset a\nb} -result {type source line 1808 file info.test cmd {info frame 0} proc ::tcltest::RunTest}
+test info-30.44 {TIP 280 for compiled [subst]} {
+    unset -nocomplain a
+    set a(\n) {}
+    subst {$a(
+)[reduce [info frame 0]]} ; # 1814
+} {type source line 1814 file info.test cmd {info frame 0} proc ::tcltest::RunTest}
+test info-30.45 {TIP 280 for compiled [subst]} {
+    unset -nocomplain a
+    set a() {}
+    subst {$a([
+return -level 0])[reduce [info frame 0]]} ; # 1820
+} {type source line 1820 file info.test cmd {info frame 0} proc ::tcltest::RunTest}
+test info-30.46 {TIP 280 for compiled [subst]} {
+    unset -nocomplain a
+    set a(1825) YES;  set a(1824) 1824; set a(1826) 1826
+    subst {$a([dict get [info frame 0] line])} ; # 1825
+} YES
+test info-30.47 {TIP 280 for compiled [subst]} {
+    unset -nocomplain a
+    set a(\n1831) YES;  set a(\n1830) 1830; set a(\n1832) 1832
+    subst {$a(
+[dict get [info frame 0] line])} ; # 1831
+} YES
+unset -nocomplain a
+
+test info-30.48 {Bug 2850901} testevalex {
+    testevalex {return -level 0 [format %s {}
+][reduce [info frame 0]]} ; # line 2 of the eval
+} {type eval line 2 cmd {info frame 0} proc ::tcltest::RunTest}
+
+
+# -------------------------------------------------------------------------
+# literal sharing 2, bug 2933089
+
+test info-40.1 {location information not confused by literal sharing, bug 2933089} -setup {
+    set result {}
+
+    proc print_one {} {}
+    proc test_info_frame {} {
+	set x 1
+	set y x
+
+	if "$x != 1" {
+	} else {
+	    print_one
+	} ;#line 1854^
+
+	if "$$y != 1" {
+	} else {
+	    print_one
+	} ;#line 1859^
+	# Do not put the comments listing the line numbers into the
+	# branches. We need shared literals, and the comments would
+	# make them different, thus unshared.
+    }
+
+    proc get_frame_info { cmd_str op } {
+	lappend ::result [reduce [eval {info frame -3}]]
+    }
+    trace add execution print_one enter get_frame_info
+} -body {
+    test_info_frame;
+    join $result \n
+} -cleanup {
+    trace remove execution print_one enter get_frame_info
+    rename get_frame_info {}
+    rename test_info_frame {}
+    rename print_one {}
+} -result {type source line 1854 file info.test cmd print_one proc ::test_info_frame level 1
+type source line 1859 file info.test cmd print_one proc ::test_info_frame level 1}
+
+# -------------------------------------------------------------------------
+# Tests moved to the end to not disturb other tests and their locations.
+
+test info-38.6 {location information for uplevel, ppl, proc-proc-literal} -match glob -setup {subinterp} -body {
+    interp eval sub {
+	proc etrace {} {
+	    set res {}
+	    set level [info frame]
+	    while {$level} {
+		lappend res [list $level [reduce [info frame $level]]]
+		incr level -1
+	    }
+	    return $res
+	}
+	proc control {vv script} {
+	    upvar 1 $vv var
+	    return [uplevel 1 $script]
+	}
+	proc datal {} {
+	    control y {
+		set y PPL
+		etrace
+	    }
+	}
+	join [lrange [datal] 0 4] \n
+    }
+} -result {* {type source line 1890 file info.test cmd {info frame $level} proc ::etrace level 0}
+* {type source line 1902 file info.test cmd etrace proc ::control}
+* {type source line 1897 file info.test cmd {uplevel 1 $script} proc ::control}
+* {type source line 1900 file info.test cmd control proc ::datal level 1}
+* {type source line 1905 file info.test cmd datal level 2}} -cleanup {interp delete sub}
+
+test info-38.4 {location information for uplevel, dpv, direct-proc-literal} -match glob -setup {subinterp} -body {
+    interp eval sub {
+	proc etrace {} {
+	    set res {}
+	    set level [info frame]
+	    while {$level} {
+		lappend res [list $level [reduce [info frame $level]]]
+		incr level -1
+	    }
+	    return $res
+	}
+	proc control {vv script} {
+	    upvar 1 $vv var
+	    return [uplevel 1 $script]
+	}
+	join [lrange [control y {
+	    set y DPL
+	    etrace
+	}] 0 3] \n
+    }
+} -result {* {type source line 1919 file info.test cmd {info frame $level} proc ::etrace level 0}
+* {type source line 1930 file info.test cmd etrace proc ::control}
+* {type source line 1926 file info.test cmd {uplevel 1 $script} proc ::control}
+* {type source line 1928 file info.test cmd control level 1}} -cleanup {interp delete sub}
+
+test info-38.2 {location information for uplevel, dl, direct-literal} -match glob -setup {subinterp} -body {
+    interp eval sub {
+	proc etrace {} {
+	    set res {}
+	    set level [info frame]
+	    while {$level} {
+		lappend res [list $level [reduce [info frame $level]]]
+		incr level -1
+	    }
+	    return $res
+	}
+	join [lrange [uplevel \#0 {
+	    set y DL.
+	    etrace
+	}] 0 2] \n
+    }
+} -result {* {type source line 1944 file info.test cmd {info frame $level} proc ::etrace level 0}
+* {type source line 1951 file info.test cmd etrace level 1}
+* {type source line 1949 file info.test cmd uplevel\\ \\\\ level 1}} -cleanup {interp delete sub}
+
+# This test at the end of this file _only_ to avoid disturbing above line
+# numbers. It _belongs_ after info-9.12
+test info-9.13 {info level option, value in global context} -body {
+    uplevel #0 {info level 2}
+} -returnCodes error -result {bad level "2"}
+
+# -------------------------------------------------------------------------
+namespace eval foo {}
+proc foo::bar {} {
+    catch {*}{
+	{info frame 0}
+	res
+    }
+    return $res
+}
+test info-33.4 {{*}, literal, simple, bytecompiled} -body {
+    reduce [foo::bar]
+} -cleanup {
+    namespace delete foo
+} -result {type source line 1968 file info.test cmd {info frame 0} proc ::foo::bar level 0}
+
+# -------------------------------------------------------------------------
+namespace eval foo {}
+proc foo::bar {} {
+    dict for {a b} {c d} {*}{
+	{set res [info frame 0]}
+    }
+    return $res
+}
+test info-33.5 {{*}, literal, simple, bytecompiled} -body {
+    reduce [foo::bar]
+} -cleanup {
+    namespace delete foo
+} -result {type source line 1983 file info.test cmd {info frame 0} proc ::foo::bar level 0}
+
+# -------------------------------------------------------------------------
+namespace eval foo {}
+proc foo::bar {} {
+    set d {a b}
+    dict update d x y {*}{
+	{set res [info frame 0]}
+    }
+    return $res
+}
+test info-33.6 {{*}, literal, simple, bytecompiled} -body {
+    reduce [foo::bar]
+} -cleanup {
+    namespace delete foo
+} -result {type source line 1998 file info.test cmd {info frame 0} proc ::foo::bar level 0}
+
+# -------------------------------------------------------------------------
+namespace eval foo {}
+proc foo::bar {} {
+    set d {}
+    dict with d {*}{
+	{set res [info frame 0]}
+    }
+    return $res
+}
+test info-33.7 {{*}, literal, simple, bytecompiled} -body {
+    reduce [foo::bar]
+} -cleanup {
+    namespace delete foo
+} -result {type source line 2013 file info.test cmd {info frame 0} proc ::foo::bar level 0}
+
+# -------------------------------------------------------------------------
+namespace eval foo {}
+proc foo::bar {} {
+    for {*}{
+	{set res [info frame 0]}
+	{1} {} {break}
+    }
+    return $res
+}
+test info-33.8 {{*}, literal, simple, bytecompiled} -body {
+    reduce [foo::bar]
+} -cleanup {
+    namespace delete foo
+} -result {type source line 2027 file info.test cmd {info frame 0} proc ::foo::bar level 0}
+
+# -------------------------------------------------------------------------
+namespace eval foo {}
+proc foo::bar {} {
+    for {*}{
+	{} {1} {}
+	{set res [info frame 0]; break}
+    }
+    return $res
+}
+test info-33.9 {{*}, literal, simple, bytecompiled} -body {
+    reduce [foo::bar]
+} -cleanup {
+    namespace delete foo
+} -result {type source line 2043 file info.test cmd {info frame 0} proc ::foo::bar level 0}
+
+# -------------------------------------------------------------------------
+namespace eval foo {}
+proc foo::bar {} {
+    for {*}{
+	{} {1}
+	{return [info frame 0]}
+	{}
+    }
+}
+test info-33.10 {{*}, literal, simple, bytecompiled} -body {
+    reduce [foo::bar]
+} -cleanup {
+    namespace delete foo
+} -result {type source line 2058 file info.test cmd {info frame 0} proc ::foo::bar level 0}
+
+# -------------------------------------------------------------------------
+namespace eval foo {}
+proc foo::bar {} {
+    for {*}{
+	{}
+	{[return [info frame 0]]}
+	{} {}
+    }
+}
+test info-33.11 {{*}, literal, simple, bytecompiled} -body {
+    reduce [foo::bar]
+} -cleanup {
+    namespace delete foo
+} -result {type source line 2073 file info.test cmd {info frame 0} proc ::foo::bar level 0}
+
+# -------------------------------------------------------------------------
+namespace eval foo {}
+proc foo::bar {} {
+    foreach {*}{
+	x
+    } [return [info frame 0]] {}
+}
+test info-33.12 {{*}, literal, simple, bytecompiled} -body {
+    reduce [foo::bar]
+} -cleanup {
+    namespace delete foo
+} -result {type source line 2088 file info.test cmd {info frame 0} proc ::foo::bar level 0}
+
+# -------------------------------------------------------------------------
+namespace eval foo {}
+proc foo::bar {} {
+    foreach {*}{
+	x y
+	{set res [info frame 0]}
+    } 
+    return $res
+}
+test info-33.13 {{*}, literal, simple, bytecompiled} -body {
+    reduce [foo::bar]
+} -cleanup {
+    namespace delete foo
+} -result {type source line 2101 file info.test cmd {info frame 0} proc ::foo::bar level 0}
+
+# -------------------------------------------------------------------------
+namespace eval foo {}
+proc foo::bar {} {
+    if {*}{
+	{[return [info frame 0]]}
+	{}
+    } 
+}
+test info-33.14 {{*}, literal, simple, bytecompiled} -body {
+    reduce [foo::bar]
+} -cleanup {
+    namespace delete foo
+} -result {type source line 2115 file info.test cmd {info frame 0} proc ::foo::bar level 0}
+
+# -------------------------------------------------------------------------
+namespace eval foo {}
+proc foo::bar {} {
+    if 0 {*}{
+	{} else
+	{return [info frame 0]}
+    } 
+}
+test info-33.15 {{*}, literal, simple, bytecompiled} -body {
+    reduce [foo::bar]
+} -cleanup {
+    namespace delete foo
+} -result {type source line 2130 file info.test cmd {info frame 0} proc ::foo::bar level 0}
+
+# -------------------------------------------------------------------------
+namespace eval foo {}
+proc foo::bar {} {
+    incr {*}{
+	x
+    } [return [info frame 0]]
+}
+test info-33.16 {{*}, literal, simple, bytecompiled} -body {
+    reduce [foo::bar]
+} -cleanup {
+    namespace delete foo
+} -result {type source line 2144 file info.test cmd {info frame 0} proc ::foo::bar level 0}
+
+# -------------------------------------------------------------------------
+namespace eval foo {}
+proc foo::bar {} {
+    info level {*}{
+    } [return [info frame 0]]
+}
+test info-33.17 {{*}, literal, simple, bytecompiled} -body {
+    reduce [foo::bar]
+} -cleanup {
+    namespace delete foo
+} -result {type source line 2156 file info.test cmd {info frame 0} proc ::foo::bar level 0}
+
+# -------------------------------------------------------------------------
+namespace eval foo {}
+proc foo::bar {} {
+    string match {*}{
+    } [return [info frame 0]] {}
+}
+test info-33.18 {{*}, literal, simple, bytecompiled} -body {
+    reduce [foo::bar]
+} -cleanup {
+    namespace delete foo
+} -result {type source line 2168 file info.test cmd {info frame 0} proc ::foo::bar level 0}
+
+# -------------------------------------------------------------------------
+namespace eval foo {}
+proc foo::bar {} {
+    string match {*}{
+	{}
+    } [return [info frame 0]]
+}
+test info-33.19 {{*}, literal, simple, bytecompiled} -body {
+    reduce [foo::bar]
+} -cleanup {
+    namespace delete foo
+} -result {type source line 2181 file info.test cmd {info frame 0} proc ::foo::bar level 0}
+
+# -------------------------------------------------------------------------
+namespace eval foo {}
+proc foo::bar {} {
+    string length {*}{
+    } [return [info frame 0]]
+}
+test info-33.20 {{*}, literal, simple, bytecompiled} -body {
+    reduce [foo::bar]
+} -cleanup {
+    namespace delete foo
+} -result {type source line 2193 file info.test cmd {info frame 0} proc ::foo::bar level 0}
+
+# -------------------------------------------------------------------------
+namespace eval foo {}
+proc foo::bar {} {
+    while {*}{
+	{[return [info frame 0]]}
+    } {}
+}
+test info-33.21 {{*}, literal, simple, bytecompiled} -body {
+    reduce [foo::bar]
+} -cleanup {
+    namespace delete foo
+} -result {type source line 2205 file info.test cmd {info frame 0} proc ::foo::bar level 0}
+
+# -------------------------------------------------------------------------
+namespace eval foo {}
+proc foo::bar {} {
+    switch -- {*}{
+    } [return [info frame 0]] {*}{
+    } x y
+}
+test info-33.22 {{*}, literal, simple, bytecompiled} -body {
+    reduce [foo::bar]
+} -cleanup {
+    namespace delete foo
+} -result {type source line 2218 file info.test cmd {info frame 0} proc ::foo::bar level 0}
+
+# -------------------------------------------------------------------------
+namespace eval foo {}
+proc foo::bar {} {
+    try {*}{
+	{set res [info frame 0]}
+    } 
+    return $res
+}
+test info-33.23 {{*}, literal, simple, bytecompiled} -body {
+    reduce [foo::bar]
+} -cleanup {
+    namespace delete foo
+} -result {type source line 2231 file info.test cmd {info frame 0} proc ::foo::bar level 0}
+
+# -------------------------------------------------------------------------
+namespace eval foo {}
+proc foo::bar {} {
+    try {*}{
+	{set res [info frame 0]}
+    } finally {}
+    return $res
+}
+test info-33.24 {{*}, literal, simple, bytecompiled} -body {
+    reduce [foo::bar]
+} -cleanup {
+    namespace delete foo
+} -result {type source line 2245 file info.test cmd {info frame 0} proc ::foo::bar level 0}
+
+# -------------------------------------------------------------------------
+namespace eval foo {}
+proc foo::bar {} {
+    try {*}{
+	{set res [info frame 0]}
+    } on ok {} {}
+    return $res
+}
+test info-33.25 {{*}, literal, simple, bytecompiled} -body {
+    reduce [foo::bar]
+} -cleanup {
+    namespace delete foo
+} -result {type source line 2259 file info.test cmd {info frame 0} proc ::foo::bar level 0}
+
+# -------------------------------------------------------------------------
+namespace eval foo {}
+proc foo::bar {} {
+    try {*}{
+	{set res [info frame 0]}
+    } on ok {} {} finally {}
+    return $res
+}
+test info-33.26 {{*}, literal, simple, bytecompiled} -body {
+    reduce [foo::bar]
+} -cleanup {
+    namespace delete foo
+} -result {type source line 2273 file info.test cmd {info frame 0} proc ::foo::bar level 0}
+
+# -------------------------------------------------------------------------
+namespace eval foo {}
+proc foo::bar {} {
+    while 1 {*}{
+	{return [info frame 0]}
+    }
+}
+test info-33.27 {{*}, literal, simple, bytecompiled} -body {
+    reduce [foo::bar]
+} -cleanup {
+    namespace delete foo
+} -result {type source line 2287 file info.test cmd {info frame 0} proc ::foo::bar level 0}
+
+# -------------------------------------------------------------------------
+namespace eval foo {}
+proc foo::bar {} {
+    try {} finally {*}{
+	{return [info frame 0]}
+    }
+}
+test info-33.28 {{*}, literal, simple, bytecompiled} -body {
+    reduce [foo::bar]
+} -cleanup {
+    namespace delete foo
+} -result {type source line 2300 file info.test cmd {info frame 0} proc ::foo::bar level 0}
+
+# -------------------------------------------------------------------------
+namespace eval foo {}
+proc foo::bar {} {
+    try {} on ok {} {} finally {*}{
+	{return [info frame 0]}
+    }
+}
+test info-33.29 {{*}, literal, simple, bytecompiled} -body {
+    reduce [foo::bar]
+} -cleanup {
+    namespace delete foo
+} -result {type source line 2313 file info.test cmd {info frame 0} proc ::foo::bar level 0}
+
+# -------------------------------------------------------------------------
+namespace eval foo {}
+proc foo::bar {} {
+    try {} on ok {} {*}{
+	{return [info frame 0]}
+    }
+}
+test info-33.30 {{*}, literal, simple, bytecompiled} -body {
+    reduce [foo::bar]
+} -cleanup {
+    namespace delete foo
+} -result {type source line 2326 file info.test cmd {info frame 0} proc ::foo::bar level 0}
+
+# -------------------------------------------------------------------------
+namespace eval foo {}
+proc foo::bar {} {
+    try {} on ok {} {*}{
+	{return [info frame 0]}
+    } finally {}
+}
+test info-33.31 {{*}, literal, simple, bytecompiled} -body {
+    reduce [foo::bar]
+} -cleanup {
+    namespace delete foo
+} -result {type source line 2339 file info.test cmd {info frame 0} proc ::foo::bar level 0}
+
+# -------------------------------------------------------------------------
+namespace eval foo {}
+proc foo::bar {} {
+    binary format {*}{
+    } [return [info frame 0]]
+}
+test info-33.32 {{*}, literal, simple, bytecompiled} -body {
+    reduce [foo::bar]
+} -cleanup {
+    namespace delete foo
+} -result {type source line 2352 file info.test cmd {info frame 0} proc ::foo::bar level 0}
+
+# -------------------------------------------------------------------------
+namespace eval foo {}
+proc foo::bar {} {
+    set format format
+    binary $format {*}{
+    } [return [info frame 0]]
+}
+test info-33.33 {{*}, literal, simple, bytecompiled} -body {
+    reduce [foo::bar]
+} -cleanup {
+    namespace delete foo
+} -result {type source line 2365 file info.test cmd {info frame 0} proc ::foo::bar level 0}
+
+# -------------------------------------------------------------------------
+namespace eval foo {}
+proc foo::bar {} {
+    append x {*}{
+    } [return [info frame 0]]
+}
+test info-33.34 {{*}, literal, simple, bytecompiled} -body {
+    reduce [foo::bar]
+} -cleanup {
+    namespace delete foo
+} -result {type source line 2377 file info.test cmd {info frame 0} proc ::foo::bar level 0}
+
+# -------------------------------------------------------------------------
+namespace eval foo {}
+proc foo::bar {} {
+    append {*}{
+    } x([return [info frame 0]]) {*}{
+    } a
+}
+test info-33.35 {{*}, literal, simple, bytecompiled} -body {
+    reduce [foo::bar]
+} -cleanup {
+    namespace delete foo
+} -result {type source line 2389 file info.test cmd {info frame 0} proc ::foo::bar level 0}
+
+# -------------------------------------------------------------------------
+unset -nocomplain res
+
+test info-39.1 {Bug 4b61afd660} -setup {
+    proc probe {} {
+	return [dict get [info frame -1] line]
+    }
+    set body {
+	set cmd probe
+	$cmd
+    }
+    proc demo {} $body
+} -body {
+    demo
+} -cleanup {
+    unset -nocomplain body
+    rename demo {}
+    rename probe {}
+} -result 3
+
+# cleanup
+catch {namespace delete test_ns_info1 test_ns_info2}
+::tcltest::cleanupTests
+return
diff --git a/tests/init.test b/tests/init.test
new file mode 100644
index 0000000..41b8624
--- /dev/null
+++ b/tests/init.test
@@ -0,0 +1,195 @@
+# Functionality covered: this file contains a collection of tests for the auto
+# loading and namespaces.
+#
+# Sourcing this file into Tcl runs the tests and generates output for errors.
+# No output means no errors were found.
+#
+# Copyright (c) 1997 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution of
+# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {"::tcltest" ni [namespace children]} {
+    package require tcltest 2.3.4
+    namespace import -force ::tcltest::*
+}
+
+# Clear out any namespaces called test_ns_*
+catch {namespace delete {*}[namespace children :: test_ns_*]}
+
+# Six cases - white box testing
+
+test init-1.1 {auto_qualify - absolute cmd - namespace} {
+    auto_qualify ::foo::bar ::blue
+} ::foo::bar
+test init-1.2 {auto_qualify - absolute cmd - global} {
+    auto_qualify ::global ::sub
+} global
+test init-1.3 {auto_qualify - no colons cmd - global} {
+    auto_qualify nocolons ::
+} nocolons 
+test init-1.4 {auto_qualify - no colons cmd - namespace} {
+    auto_qualify nocolons ::sub
+} {::sub::nocolons nocolons}
+test init-1.5 {auto_qualify - colons in cmd - global} {
+    auto_qualify foo::bar ::
+} ::foo::bar
+test init-1.6 {auto_qualify - colons in cmd - namespace} {
+    auto_qualify foo::bar ::sub
+} {::sub::foo::bar ::foo::bar}
+# Some additional tests
+test init-1.7 {auto_qualify - multiples colons 1} {
+    auto_qualify :::foo::::bar ::blue
+} ::foo::bar
+test init-1.8 {auto_qualify - multiple colons 2} {
+    auto_qualify :::foo ::bar
+} foo
+
+# We use a sub-interp and auto_reset and double the tests because there is 2
+# places where auto_loading occur (before loading the indexes files and after)
+
+set testInterp [interp create]
+tcltest::loadIntoSlaveInterpreter $testInterp {*}$argv
+interp eval $testInterp {
+    namespace import -force ::tcltest::*
+    customMatch pairwise {apply {{mode pair} {
+	if {[llength $pair] != 2} {error "need a pair of values to check"}
+	string $mode [lindex $pair 0] [lindex $pair 1]
+    }}}
+
+    auto_reset
+    catch {rename parray {}}
+
+test init-2.0 {load parray - stage 1} -body {
+    parray
+} -returnCodes error -cleanup {
+    rename parray {}  ;# remove it, for the next test - that should not fail.
+} -result {wrong # args: should be "parray a ?pattern?"}
+test init-2.1 {load parray - stage 2} -body {
+    parray
+} -returnCodes error -result {wrong # args: should be "parray a ?pattern?"}
+auto_reset
+catch {rename ::safe::setLogCmd {}}
+#unset -nocomplain auto_index(::safe::setLogCmd) auto_oldpath
+test init-2.2 {load ::safe::setLogCmd - stage 1} {
+    ::safe::setLogCmd
+    rename ::safe::setLogCmd {}  ;# should not fail
+} {}
+test init-2.3 {load ::safe::setLogCmd - stage 2} {
+    ::safe::setLogCmd
+    rename ::safe::setLogCmd {}  ;# should not fail
+} {}
+auto_reset
+catch {rename ::safe::setLogCmd {}}
+test init-2.4 {load safe:::setLogCmd - stage 1} {
+    safe:::setLogCmd  ;# intentionally 3 :
+    rename ::safe::setLogCmd {}  ;# should not fail
+} {}
+test init-2.5 {load safe:::setLogCmd - stage 2} {
+    safe:::setLogCmd  ;# intentionally 3 :
+    rename ::safe::setLogCmd {}  ;# should not fail
+} {}
+auto_reset
+catch {rename ::safe::setLogCmd {}}
+test init-2.6 {load setLogCmd from safe:: - stage 1} {
+    namespace eval safe setLogCmd 
+    rename ::safe::setLogCmd {}  ;# should not fail
+} {}
+test init-2.7 {oad setLogCmd from safe::  - stage 2} {
+    namespace eval safe setLogCmd 
+    rename ::safe::setLogCmd {}  ;# should not fail
+} {}
+test init-2.8 {load tcl::HistAdd} -setup {
+    auto_reset
+    catch {rename ::tcl::HistAdd {}}
+} -body {
+    # 3 ':' on purpose
+    tcl:::HistAdd
+} -returnCodes error -cleanup {
+    rename ::tcl::HistAdd {}
+} -result {wrong # args: should be "tcl:::HistAdd event ?exec?"}
+
+test init-3.0 {random stuff in the auto_index, should still work} {
+    set auto_index(foo:::bar::blah) {
+        namespace eval foo {namespace eval bar {proc blah {} {return 1}}}
+    }
+    foo:::bar::blah
+} 1
+
+# Tests that compare the error stack trace generated when autoloading with
+# that generated when no autoloading is necessary.  Ideally they should be the
+# same.
+
+set count 0
+foreach arg [subst -nocommands -novariables {
+    c
+    {argument
+                which spans
+                multiple lines}
+    {argument which is all on one line but which is of such great length that the Tcl C library will truncate it when appending it onto the global error stack}
+    {argument which spans multiple lines
+                and is long enough to be truncated and
+"               <- includes a false lead in the prune point search
+                and must be longer still to force truncation}
+                {contrived example: rare circumstance 
+		where the point at which to prune the
+		error stack cannot be uniquely determined.
+		foo bar foo
+"}
+    {contrived example: rare circumstance 
+		where the point at which to prune the
+		error stack cannot be uniquely determined.
+		foo bar
+"}
+    {argument that contains non-ASCII character, \u20ac, and which is of such great length that it will be longer than 150 bytes so it will be truncated by the Tcl C library}
+	}] {    ;# emacs needs -> "
+
+    test init-4.$count.0 {::errorInfo produced by [unknown]} -setup {
+	auto_reset
+    } -body {
+	catch {parray a b $arg}
+	set first $::errorInfo
+	catch {parray a b $arg}
+	list $first $::errorInfo
+    } -match pairwise -result equal
+    test init-4.$count.1 {::errorInfo produced by [unknown]} -setup {
+	auto_reset
+    } -body {
+	namespace eval junk [list array set $arg [list 1 2 3 4]]
+	trace variable ::junk::$arg r \
+		"[list error [subst {Variable \"$arg\" is write-only}]] ;# "
+	catch {parray ::junk::$arg}
+	set first $::errorInfo
+	catch {parray ::junk::$arg}
+	list $first $::errorInfo
+    } -match pairwise -result equal
+
+    incr count
+}
+
+test init-5.0 {return options passed through ::unknown} -setup {
+    catch {rename xxx {}}
+    set ::auto_index(::xxx) {proc ::xxx {} {
+	return -code error -level 2 xxx
+    }}
+} -body {
+    set code [catch {::xxx} foo bar]
+    set code2 [catch {::xxx} foo2 bar2]
+    list $code $foo $bar $code2 $foo2 $bar2
+} -cleanup {
+    unset ::auto_index(::xxx)
+} -match glob -result {2 xxx {-errorcode NONE -code 1 -level 1} 2 xxx {-code 1 -level 1 -errorcode NONE}}
+
+cleanupTests
+}	;#  End of [interp eval $testInterp]
+
+# cleanup
+interp delete $testInterp
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# fill-column: 78
+# End:
diff --git a/tests/interp.test b/tests/interp.test
new file mode 100644
index 0000000..f9c1aec
--- /dev/null
+++ b/tests/interp.test
@@ -0,0 +1,3666 @@
+# This file tests the multiple interpreter facility of Tcl
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands.  Sourcing this file into Tcl runs the tests and
+# generates output for errors.  No output means no errors were found.
+#
+# Copyright (c) 1995-1996 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {"::tcltest" ni [namespace children]} {
+    package require tcltest 2.1
+    namespace import -force ::tcltest::*
+}
+
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
+
+testConstraint testinterpdelete [llength [info commands testinterpdelete]]
+
+set hidden_cmds {cd encoding exec exit fconfigure file glob load open pwd socket source tcl:file:atime tcl:file:attributes tcl:file:copy tcl:file:delete tcl:file:dirname tcl:file:executable tcl:file:exists tcl:file:extension tcl:file:isdirectory tcl:file:isfile tcl:file:link tcl:file:lstat tcl:file:mkdir tcl:file:mtime tcl:file:nativename tcl:file:normalize tcl:file:owned tcl:file:readable tcl:file:readlink tcl:file:rename tcl:file:rootname tcl:file:size tcl:file:stat tcl:file:tail tcl:file:tempfile tcl:file:type tcl:file:volumes tcl:file:writable unload}
+
+foreach i [interp slaves] {
+  interp delete $i
+}
+
+# Part 0: Check out options for interp command
+test interp-1.1 {options for interp command} -returnCodes error -body {
+    interp
+} -result {wrong # args: should be "interp cmd ?arg ...?"}
+test interp-1.2 {options for interp command} -returnCodes error -body {
+    interp frobox
+} -result {bad option "frobox": must be alias, aliases, bgerror, cancel, create, debug, delete, eval, exists, expose, hide, hidden, issafe, invokehidden, limit, marktrusted, recursionlimit, slaves, share, target, or transfer}
+test interp-1.3 {options for interp command} {
+    interp delete
+} ""
+test interp-1.4 {options for interp command} -returnCodes error -body {
+    interp delete foo bar
+} -result {could not find interpreter "foo"}
+test interp-1.5 {options for interp command} -returnCodes error -body {
+    interp exists foo bar
+} -result {wrong # args: should be "interp exists ?path?"}
+#
+# test interp-0.6 was removed
+#
+test interp-1.6 {options for interp command} -returnCodes error -body {
+    interp slaves foo bar zop
+} -result {wrong # args: should be "interp slaves ?path?"}
+test interp-1.7 {options for interp command} -returnCodes error -body {
+    interp hello
+} -result {bad option "hello": must be alias, aliases, bgerror, cancel, create, debug, delete, eval, exists, expose, hide, hidden, issafe, invokehidden, limit, marktrusted, recursionlimit, slaves, share, target, or transfer}
+test interp-1.8 {options for interp command} -returnCodes error -body {
+    interp -froboz
+} -result {bad option "-froboz": must be alias, aliases, bgerror, cancel, create, debug, delete, eval, exists, expose, hide, hidden, issafe, invokehidden, limit, marktrusted, recursionlimit, slaves, share, target, or transfer}
+test interp-1.9 {options for interp command} -returnCodes error -body {
+    interp -froboz -safe
+} -result {bad option "-froboz": must be alias, aliases, bgerror, cancel, create, debug, delete, eval, exists, expose, hide, hidden, issafe, invokehidden, limit, marktrusted, recursionlimit, slaves, share, target, or transfer} 
+test interp-1.10 {options for interp command} -returnCodes error -body {
+    interp target
+} -result {wrong # args: should be "interp target path alias"}
+
+# Part 1: Basic interpreter creation tests:
+test interp-2.1 {basic interpreter creation} {
+    interp create a
+} a
+test interp-2.2 {basic interpreter creation} {
+    catch {interp create}
+} 0
+test interp-2.3 {basic interpreter creation} {
+    catch {interp create -safe}
+} 0 
+test interp-2.4 {basic interpreter creation} -setup {
+    catch {interp create a}
+} -returnCodes error -body {
+    interp create a
+} -result {interpreter named "a" already exists, cannot create}
+test interp-2.5 {basic interpreter creation} {
+    interp create b -safe
+} b
+test interp-2.6 {basic interpreter creation} {
+    interp create d -safe
+} d
+test interp-2.7 {basic interpreter creation} {
+    list [catch {interp create -froboz} msg] $msg
+} {1 {bad option "-froboz": must be -safe or --}}
+test interp-2.8 {basic interpreter creation} {
+    interp create -- -froboz
+} -froboz
+test interp-2.9 {basic interpreter creation} {
+    interp create -safe -- -froboz1
+} -froboz1
+test interp-2.10 {basic interpreter creation} -setup {
+    catch {interp create a}
+} -body {
+    interp create {a x1}
+    interp create {a x2}
+    interp create {a x3} -safe
+} -result {a x3}
+test interp-2.11 {anonymous interps vs existing procs} {
+    set x [interp create]
+    regexp "interp(\[0-9]+)" $x dummy thenum
+    interp delete $x
+    proc interp$thenum {} {}
+    set x [interp create]
+    regexp "interp(\[0-9]+)" $x dummy anothernum
+    expr $anothernum > $thenum
+} 1    
+test interp-2.12 {anonymous interps vs existing procs} {
+    set x [interp create -safe]
+    regexp "interp(\[0-9]+)" $x dummy thenum
+    interp delete $x
+    proc interp$thenum {} {}
+    set x [interp create -safe]
+    regexp "interp(\[0-9]+)" $x dummy anothernum
+    expr $anothernum - $thenum
+} 1
+test interp-2.13 {correct default when no $path arg is given} -body {
+    interp create --
+} -match regexp -result {interp[0-9]+}
+
+foreach i [interp slaves] {
+    interp delete $i
+}
+
+# Part 2: Testing "interp slaves" and "interp exists"
+test interp-3.1 {testing interp exists and interp slaves} {
+    interp slaves
+} ""
+test interp-3.2 {testing interp exists and interp slaves} {
+    interp create a
+    interp exists a
+} 1
+test interp-3.3 {testing interp exists and interp slaves} {
+    interp exists nonexistent
+} 0
+test interp-3.4 {testing interp exists and interp slaves} -body {
+    interp slaves a b c
+} -returnCodes error -result {wrong # args: should be "interp slaves ?path?"}
+test interp-3.5 {testing interp exists and interp slaves} -body {
+    interp exists a b c
+} -returnCodes error -result {wrong # args: should be "interp exists ?path?"}
+test interp-3.6 {testing interp exists and interp slaves} {
+    interp exists
+} 1
+test interp-3.7 {testing interp exists and interp slaves} -setup {
+    catch {interp create a}
+} -body {
+    interp slaves
+} -result a
+test interp-3.8 {testing interp exists and interp slaves} -body {
+    interp slaves a b c
+} -returnCodes error -result {wrong # args: should be "interp slaves ?path?"}
+test interp-3.9 {testing interp exists and interp slaves} -setup {
+    catch {interp create a}
+} -body {
+    interp create {a a2} -safe
+    expr {"a2" in [interp slaves a]}
+} -result 1
+test interp-3.10 {testing interp exists and interp slaves} -setup {
+    catch {interp create a}
+    catch {interp create {a a2}}
+} -body {
+    interp exists {a a2}
+} -result 1
+
+# Part 3: Testing "interp delete"
+test interp-3.11 {testing interp delete} {
+    interp delete
+} ""
+test interp-4.1 {testing interp delete} {
+    catch {interp create a}
+    interp delete a
+} ""
+test interp-4.2 {testing interp delete} -returnCodes error -body {
+    interp delete nonexistent
+} -result {could not find interpreter "nonexistent"}
+test interp-4.3 {testing interp delete} -returnCodes error -body {
+    interp delete x y z
+} -result {could not find interpreter "x"}
+test interp-4.4 {testing interp delete} {
+    interp delete
+} ""
+test interp-4.5 {testing interp delete} {
+    interp create a
+    interp create {a x1}
+    interp delete {a x1}
+    expr {"x1" in [interp slaves a]}
+} 0
+test interp-4.6 {testing interp delete} {
+    interp create c1
+    interp create c2
+    interp create c3
+    interp delete c1 c2 c3
+} ""
+test interp-4.7 {testing interp delete} -returnCodes error -body {
+    interp create c1
+    interp create c2
+    interp delete c1 c2 c3
+} -result {could not find interpreter "c3"}
+test interp-4.8 {testing interp delete} -returnCodes error -body {
+    interp delete {}
+} -result {cannot delete the current interpreter}
+
+foreach i [interp slaves] {
+    interp delete $i
+}
+
+# Part 4: Consistency checking - all nondeleted interpreters should be
+# there:
+test interp-5.1 {testing consistency} {
+    interp slaves
+} ""
+test interp-5.2 {testing consistency} {
+    interp exists a
+} 0
+test interp-5.3 {testing consistency} {
+    interp exists nonexistent
+} 0
+
+# Recreate interpreter "a"
+interp create a
+
+# Part 5: Testing eval in interpreter object command and with interp command
+test interp-6.1 {testing eval} {
+    a eval expr 3 + 5
+} 8
+test interp-6.2 {testing eval} -returnCodes error -body {
+    a eval foo
+} -result {invalid command name "foo"}
+test interp-6.3 {testing eval} {
+    a eval {proc foo {} {expr 3 + 5}}
+    a eval foo
+} 8
+catch {a eval {proc foo {} {expr 3 + 5}}}
+test interp-6.4 {testing eval} {
+    interp eval a foo
+} 8
+test interp-6.5 {testing eval} {
+    interp create {a x2}
+    interp eval {a x2} {proc frob {} {expr 4 * 9}}
+    interp eval {a x2} frob
+} 36
+catch {interp create {a x2}}
+test interp-6.6 {testing eval} -returnCodes error -body {
+    interp eval {a x2} foo
+} -result {invalid command name "foo"}
+
+# UTILITY PROCEDURE RUNNING IN MASTER INTERPRETER:
+proc in_master {args} {
+     return [list seen in master: $args]
+}
+
+# Part 6: Testing basic alias creation
+test interp-7.1 {testing basic alias creation} {
+    a alias foo in_master
+} foo
+catch {a alias foo in_master}
+test interp-7.2 {testing basic alias creation} {
+    a alias bar in_master a1 a2 a3
+} bar
+catch {a alias bar in_master a1 a2 a3}
+# Test 6.3 has been deleted.
+test interp-7.3 {testing basic alias creation} {
+    a alias foo
+} in_master
+test interp-7.4 {testing basic alias creation} {
+    a alias bar
+} {in_master a1 a2 a3}
+test interp-7.5 {testing basic alias creation} {
+    lsort [a aliases]
+} {bar foo}
+test interp-7.6 {testing basic aliases arg checking} -returnCodes error -body {
+    a aliases too many args
+} -result {wrong # args: should be "a aliases"}
+
+# Part 7: testing basic alias invocation
+test interp-8.1 {testing basic alias invocation} {
+    catch {interp create a}
+    a alias foo in_master
+    a eval foo s1 s2 s3
+} {seen in master: {s1 s2 s3}}
+test interp-8.2 {testing basic alias invocation} {
+    catch {interp create a}
+    a alias bar in_master a1 a2 a3
+    a eval bar s1 s2 s3
+} {seen in master: {a1 a2 a3 s1 s2 s3}}
+test interp-8.3 {testing basic alias invocation} -returnCodes error -body {
+   catch {interp create a}
+   a alias
+} -result {wrong # args: should be "a alias aliasName ?targetName? ?arg ...?"}
+
+# Part 8: Testing aliases for non-existent or hidden targets
+test interp-9.1 {testing aliases for non-existent targets} {
+    catch {interp create a}
+    a alias zop nonexistent-command-in-master
+    list [catch {a eval zop} msg] $msg
+} {1 {invalid command name "nonexistent-command-in-master"}}
+test interp-9.2 {testing aliases for non-existent targets} {
+    catch {interp create a}
+    a alias zop nonexistent-command-in-master
+    proc nonexistent-command-in-master {} {return i_exist!}
+    a eval zop
+} i_exist!
+test interp-9.3 {testing aliases for hidden commands} {
+    catch {interp create a}
+    a eval {proc p {} {return ENTER_A}}
+    interp alias {} p a p
+    set res {}
+    lappend res [list [catch p msg] $msg]
+    interp hide a p
+    lappend res [list [catch p msg] $msg]
+    rename p {}
+    interp delete a
+    set res
+ } {{0 ENTER_A} {1 {invalid command name "p"}}}
+test interp-9.4 {testing aliases and namespace commands} {
+    proc p {} {return GLOBAL}
+    namespace eval tst {
+	proc p {} {return NAMESPACE}
+    }
+    interp alias {} a {} p
+    set res [a]
+    lappend res [namespace eval tst a]
+    rename p {}
+    rename a {}
+    namespace delete tst
+    set res
+ } {GLOBAL GLOBAL}
+
+if {[info command nonexistent-command-in-master] != ""} {
+    rename nonexistent-command-in-master {}
+}
+
+# Part 9: Aliasing between interpreters
+test interp-10.1 {testing aliasing between interpreters} {
+    catch {interp delete a}
+    catch {interp delete b}
+    interp create a
+    interp create b
+    interp alias a a_alias b b_alias 1 2 3
+} a_alias
+test interp-10.2 {testing aliasing between interpreters} {
+    catch {interp delete a}
+    catch {interp delete b}
+    interp create a
+    interp create b
+    b eval {proc b_alias {args} {return [list got $args]}}
+    interp alias a a_alias b b_alias 1 2 3
+    a eval a_alias a b c
+} {got {1 2 3 a b c}}
+test interp-10.3 {testing aliasing between interpreters} {
+    catch {interp delete a}
+    catch {interp delete b}
+    interp create a
+    interp create b
+    interp alias a a_alias b b_alias 1 2 3
+    list [catch {a eval a_alias a b c} msg] $msg
+} {1 {invalid command name "b_alias"}}
+test interp-10.4 {testing aliasing between interpreters} {
+    catch {interp delete a}
+    interp create a
+    a alias a_alias puts
+    a aliases
+} a_alias
+test interp-10.5 {testing aliasing between interpreters} {
+    catch {interp delete a}
+    catch {interp delete b}
+    interp create a
+    interp create b
+    a alias a_alias puts
+    interp alias a a_del b b_del
+    interp delete b
+    a aliases
+} a_alias
+test interp-10.6 {testing aliasing between interpreters} {
+    catch {interp delete a}
+    catch {interp delete b}
+    interp create a
+    interp create b
+    interp alias a a_command b b_command a1 a2 a3
+    b alias b_command in_master b1 b2 b3
+    a eval a_command m1 m2 m3
+} {seen in master: {b1 b2 b3 a1 a2 a3 m1 m2 m3}}
+test interp-10.7 {testing aliases between interpreters} {
+    catch {interp delete a}
+    interp create a
+    interp alias "" foo a zoppo
+    a eval {proc zoppo {x} {list $x $x $x}}
+    set x [foo 33]
+    a eval {rename zoppo {}}
+    interp alias "" foo a {}
+    return $x
+} {33 33 33}
+
+# Part 10: Testing "interp target"
+test interp-11.1 {testing interp target} {
+    list [catch {interp target} msg] $msg
+} {1 {wrong # args: should be "interp target path alias"}}
+test interp-11.2 {testing interp target} {
+    list [catch {interp target nosuchinterpreter foo} msg] $msg
+} {1 {could not find interpreter "nosuchinterpreter"}}
+test interp-11.3 {testing interp target} {
+    catch {interp delete a}
+    interp create a
+    a alias boo no_command
+    interp target a boo
+} ""
+test interp-11.4 {testing interp target} {
+    catch {interp delete x1}
+    interp create x1
+    x1 eval interp create x2
+    x1 eval x2 eval interp create x3
+    catch {interp delete y1}
+    interp create y1
+    y1 eval interp create y2
+    y1 eval y2 eval interp create y3
+    interp alias {x1 x2 x3} xcommand {y1 y2 y3} ycommand
+    interp target {x1 x2 x3} xcommand
+} {y1 y2 y3}
+test interp-11.5 {testing interp target} {
+    catch {interp delete x1}
+    interp create x1
+    interp create {x1 x2}
+    interp create {x1 x2 x3}
+    catch {interp delete y1}
+    interp create y1
+    interp create {y1 y2}
+    interp create {y1 y2 y3}
+    interp alias {x1 x2 x3} xcommand {y1 y2 y3} ycommand
+    list [catch {x1 eval {interp target {x2 x3} xcommand}} msg] $msg
+} {1 {target interpreter for alias "xcommand" in path "x2 x3" is not my descendant}}
+test interp-11.6 {testing interp target} {
+    foreach a [interp aliases] {
+	rename $a {}
+    }
+    list [catch {interp target {} foo} msg] $msg
+} {1 {alias "foo" in path "" not found}}
+test interp-11.7 {testing interp target} {
+    catch {interp delete a}
+    interp create a
+    list [catch {interp target a foo} msg] $msg
+} {1 {alias "foo" in path "a" not found}}
+
+# Part 11: testing "interp issafe"
+test interp-12.1 {testing interp issafe} {
+    interp issafe
+} 0
+test interp-12.2 {testing interp issafe} {
+    catch {interp delete a}
+    interp create a
+    interp issafe a
+} 0
+test interp-12.3 {testing interp issafe} {
+    catch {interp delete a}
+    interp create a
+    interp create {a x3} -safe
+    interp issafe {a x3}
+} 1
+test interp-12.4 {testing interp issafe} {
+    catch {interp delete a}
+    interp create a
+    interp create {a x3} -safe
+    interp create {a x3 foo}
+    interp issafe {a x3 foo}
+} 1
+
+# Part 12: testing interpreter object command "issafe" sub-command
+test interp-13.1 {testing foo issafe} {
+    catch {interp delete a}
+    interp create a
+    a issafe
+} 0
+test interp-13.2 {testing foo issafe} {
+    catch {interp delete a}
+    interp create a
+    interp create {a x3} -safe
+    a eval x3 issafe
+} 1
+test interp-13.3 {testing foo issafe} {
+    catch {interp delete a}
+    interp create a
+    interp create {a x3} -safe
+    interp create {a x3 foo}
+    a eval x3 eval foo issafe
+} 1
+test interp-13.4 {testing issafe arg checking} {
+    catch {interp create a}
+    list [catch {a issafe too many args} msg] $msg
+} {1 {wrong # args: should be "a issafe"}}
+
+# part 14: testing interp aliases
+test interp-14.1 {testing interp aliases} -setup {
+    interp create abc
+} -body {
+    interp eval abc {interp aliases}
+} -cleanup {
+    interp delete abc
+} -result ""
+test interp-14.2 {testing interp aliases} {
+    catch {interp delete a}
+    interp create a
+    a alias a1 puts
+    a alias a2 puts
+    a alias a3 puts
+    lsort [interp aliases a]
+} {a1 a2 a3}
+test interp-14.3 {testing interp aliases} {
+    catch {interp delete a}
+    interp create a
+    interp create {a x3}
+    interp alias {a x3} froboz "" puts
+    interp aliases {a x3}
+} froboz
+test interp-14.4 {testing interp alias - alias over master} {
+    # SF Bug 641195
+    catch {interp delete a}
+    interp create a
+    list [catch {interp alias "" a a eval} msg] $msg [info commands a]
+} {1 {cannot define or rename alias "a": interpreter deleted} {}}
+test interp-14.5 {testing interp-alias: wrong # args} -body {
+    proc setx x {set x}
+    interp alias {} a {} setx
+    catch {a 1 2}
+    set ::errorInfo
+} -cleanup {
+    rename setx {}
+    rename a {}
+} -result {wrong # args: should be "a x"
+    while executing
+"a 1 2"}
+test interp-14.6 {testing interp-alias: wrong # args} -setup {
+    proc setx x {set x}
+    catch {interp delete a}
+    interp create a
+} -body {
+    interp alias a a {} setx
+    catch {a eval a 1 2}
+    set ::errorInfo
+} -cleanup {
+    rename setx {}
+    interp delete a
+} -result {wrong # args: should be "a x"
+    invoked from within
+"a 1 2"
+    invoked from within
+"a eval a 1 2"}
+test interp-14.7 {testing interp-alias: wrong # args} -setup {
+    proc setx x {set x}
+    catch {interp delete a}
+    interp create a
+} -body {
+    interp alias a a {} setx
+    a eval {
+	catch {a 1 2}
+	set ::errorInfo
+    }
+} -cleanup {
+    rename setx {}
+    interp delete a
+} -result {wrong # args: should be "a x"
+    invoked from within
+"a 1 2"}
+test interp-14.8 {testing interp-alias: error messages} -body {
+    proc setx x {return -code error x}
+    interp alias {} a {} setx
+    catch {a 1}
+    set ::errorInfo
+} -cleanup {
+    rename setx {}
+    rename a {}
+} -result {x
+    while executing
+"a 1"}
+test interp-14.9 {testing interp-alias: error messages} -setup {
+    proc setx x {return -code error x}
+    catch {interp delete a}
+    interp create a
+} -body {
+    interp alias a a {} setx
+    catch {a eval a 1}
+    set ::errorInfo
+} -cleanup {
+    rename setx {}
+    interp delete a
+} -result {x
+    invoked from within
+"a 1"
+    invoked from within
+"a eval a 1"}
+test interp-14.10 {testing interp-alias: error messages} -setup {
+    proc setx x {return -code error x}
+    catch {interp delete a}
+    interp create a
+} -body {
+    interp alias a a {} setx
+    a eval {
+	catch {a 1}
+	set ::errorInfo
+    }
+} -cleanup {
+    rename setx {}
+    interp delete a
+} -result {x
+    invoked from within
+"a 1"}
+
+# part 15: testing file sharing
+test interp-15.1 {testing file sharing} {
+    catch {interp delete z}
+    interp create z
+    z eval close stdout
+    list [catch {z eval puts hello} msg] $msg
+} {1 {can not find channel named "stdout"}}
+test interp-15.2 {testing file sharing} -body {
+    catch {interp delete z}
+    interp create z
+    set f [open [makeFile {} file-15.2] w]
+    interp share "" $f z
+    z eval puts $f hello
+    z eval close $f
+    close $f
+} -cleanup {
+    removeFile file-15.2
+} -result ""
+test interp-15.3 {testing file sharing} {
+    catch {interp delete xsafe}
+    interp create xsafe -safe
+    list [catch {xsafe eval puts hello} msg] $msg
+} {1 {can not find channel named "stdout"}}
+test interp-15.4 {testing file sharing} -body {
+    catch {interp delete xsafe}
+    interp create xsafe -safe
+    set f [open [makeFile {} file-15.4] w]
+    interp share "" $f xsafe
+    xsafe eval puts $f hello
+    xsafe eval close $f
+    close $f
+} -cleanup {
+    removeFile file-15.4
+} -result ""
+test interp-15.5 {testing file sharing} {
+    catch {interp delete xsafe}
+    interp create xsafe -safe
+    interp share "" stdout xsafe
+    list [catch {xsafe eval gets stdout} msg] $msg
+} {1 {channel "stdout" wasn't opened for reading}}
+test interp-15.6 {testing file sharing} -body {
+    catch {interp delete xsafe}
+    interp create xsafe -safe
+    set f [open [makeFile {} file-15.6] w]
+    interp share "" $f xsafe
+    set x [list [catch [list xsafe eval gets $f] msg] $msg]
+    xsafe eval close $f
+    close $f
+    string compare [string tolower $x] \
+		[list 1 [format "channel \"%s\" wasn't opened for reading" $f]]
+} -cleanup {
+    removeFile file-15.6
+} -result 0
+test interp-15.7 {testing file transferring} -body {
+    catch {interp delete xsafe}
+    interp create xsafe -safe
+    set f [open [makeFile {} file-15.7] w]
+    interp transfer "" $f xsafe
+    xsafe eval puts $f hello
+    xsafe eval close $f
+} -cleanup {
+    removeFile file-15.7
+} -result ""
+test interp-15.8 {testing file transferring} -body {
+    catch {interp delete xsafe}
+    interp create xsafe -safe
+    set f [open [makeFile {} file-15.8] w]
+    interp transfer "" $f xsafe
+    xsafe eval close $f
+    set x [list [catch {close $f} msg] $msg]
+    string compare [string tolower $x] \
+		[list 1 [format "can not find channel named \"%s\"" $f]]
+} -cleanup {
+    removeFile file-15.8
+} -result 0
+
+#
+# Torture tests for interpreter deletion order
+#
+proc kill {} {interp delete xxx}
+test interp-16.0 {testing deletion order} {
+    catch {interp delete xxx}
+    interp create xxx
+    xxx alias kill kill
+    list [catch {xxx eval kill} msg] $msg
+} {0 {}}
+test interp-16.1 {testing deletion order} {
+    catch {interp delete xxx}
+    interp create xxx
+    interp create {xxx yyy}
+    interp alias {xxx yyy} kill "" kill
+    list [catch {interp eval {xxx yyy} kill} msg] $msg
+} {0 {}}
+test interp-16.2 {testing deletion order} {
+    catch {interp delete xxx}
+    interp create xxx
+    interp create {xxx yyy}
+    interp alias {xxx yyy} kill "" kill
+    list [catch {xxx eval yyy eval kill} msg] $msg
+} {0 {}}
+test interp-16.3 {testing deletion order} {
+    catch {interp delete xxx}
+    interp create xxx
+    interp create ddd
+    xxx alias kill kill
+    interp alias ddd kill xxx kill
+    set x [ddd eval kill]
+    interp delete ddd
+    set x
+} ""
+test interp-16.4 {testing deletion order} {
+    catch {interp delete xxx}
+    interp create xxx
+    interp create {xxx yyy}
+    interp alias {xxx yyy} kill "" kill
+    interp create ddd
+    interp alias ddd kill {xxx yyy} kill
+    set x [ddd eval kill]
+    interp delete ddd
+    set x
+} ""
+test interp-16.5 {testing deletion order, bgerror} {
+    catch {interp delete xxx}
+    interp create xxx
+    xxx eval {proc bgerror {args} {exit}}
+    xxx alias exit kill xxx
+    proc kill {i} {interp delete $i}
+    xxx eval after 100 expr a + b
+    after 200
+    update
+    interp exists xxx
+} 0
+
+#
+# Alias loop prevention testing.
+#
+
+test interp-17.1 {alias loop prevention} {
+    list [catch {interp alias {} a {} a} msg] $msg
+} {1 {cannot define or rename alias "a": would create a loop}}
+test interp-17.2 {alias loop prevention} {
+    catch {interp delete x}
+    interp create x
+    x alias a loop
+    list [catch {interp alias {} loop x a} msg] $msg
+} {1 {cannot define or rename alias "loop": would create a loop}}
+test interp-17.3 {alias loop prevention} {
+    catch {interp delete x}
+    interp create x
+    interp alias x a x b
+    list [catch {interp alias x b x a} msg] $msg
+} {1 {cannot define or rename alias "b": would create a loop}}
+test interp-17.4 {alias loop prevention} {
+    catch {interp delete x}
+    interp create x
+    interp alias x b x a
+    list [catch {x eval rename b a} msg] $msg
+} {1 {cannot define or rename alias "a": would create a loop}}
+test interp-17.5 {alias loop prevention} {
+    catch {interp delete x}
+    interp create x
+    x alias z l1
+    interp alias {} l2 x z
+    list [catch {rename l2 l1} msg] $msg
+} {1 {cannot define or rename alias "l1": would create a loop}}
+test interp-17.6 {alias loop prevention} {
+    catch {interp delete x}
+    interp create x
+    interp alias x a x b
+    x eval rename a c
+    list [catch {x eval rename c b} msg] $msg
+} {1 {cannot define or rename alias "b": would create a loop}}
+
+#
+# Test robustness of Tcl_DeleteInterp when applied to a slave interpreter.
+# If there are bugs in the implementation these tests are likely to expose
+# the bugs as a core dump.
+#
+
+test interp-18.1 {testing Tcl_DeleteInterp vs slaves} testinterpdelete {
+    list [catch {testinterpdelete} msg] $msg
+} {1 {wrong # args: should be "testinterpdelete path"}}
+test interp-18.2 {testing Tcl_DeleteInterp vs slaves} testinterpdelete {
+    catch {interp delete a}
+    interp create a
+    testinterpdelete a
+} ""
+test interp-18.3 {testing Tcl_DeleteInterp vs slaves} testinterpdelete {
+    catch {interp delete a}
+    interp create a
+    interp create {a b}
+    testinterpdelete {a b}
+} ""
+test interp-18.4 {testing Tcl_DeleteInterp vs slaves} testinterpdelete {
+    catch {interp delete a}
+    interp create a
+    interp create {a b}
+    testinterpdelete a
+} ""
+test interp-18.5 {testing Tcl_DeleteInterp vs slaves} testinterpdelete {
+    catch {interp delete a}
+    interp create a
+    interp create {a b}
+    interp alias {a b} dodel {} dodel
+    proc dodel {x} {testinterpdelete $x}
+    list [catch {interp eval {a b} {dodel {a b}}} msg] $msg
+} {0 {}}
+test interp-18.6 {testing Tcl_DeleteInterp vs slaves} testinterpdelete {
+    catch {interp delete a}
+    interp create a
+    interp create {a b}
+    interp alias {a b} dodel {} dodel
+    proc dodel {x} {testinterpdelete $x}
+    list [catch {interp eval {a b} {dodel a}} msg] $msg
+} {0 {}}
+test interp-18.7 {eval in deleted interp} {
+    catch {interp delete a}
+    interp create a
+    a eval {
+	proc dodel {} {
+	    delme
+	    dosomething else
+	}
+	proc dosomething args {
+	    puts "I should not have been called!!"
+	}
+    }
+    a alias delme dela
+    proc dela {} {interp delete a}
+    list [catch {a eval dodel} msg] $msg
+} {1 {attempt to call eval in deleted interpreter}}
+test interp-18.8 {eval in deleted interp} {
+    catch {interp delete a}
+    interp create a
+    a eval {
+	interp create b
+	b eval {
+	    proc dodel {} {
+		dela
+	    }
+	}
+	proc foo {} {
+	    b eval dela
+	    dosomething else
+	}
+	proc dosomething args {
+	    puts "I should not have been called!!"
+	}
+    }
+    interp alias {a b} dela {} dela
+    proc dela {} {interp delete a}
+    list [catch {a eval foo} msg] $msg
+} {1 {attempt to call eval in deleted interpreter}}
+test interp-18.9 {eval in deleted interp, bug 495830} {
+    interp create tst
+    interp alias tst suicide {} interp delete tst
+    list [catch {tst eval {suicide; set a 5}} msg] $msg
+} {1 {attempt to call eval in deleted interpreter}}     
+test interp-18.10 {eval in deleted interp, bug 495830} {
+    interp create tst
+    interp alias tst suicide {} interp delete tst
+    list [catch {tst eval {set set set; suicide; $set a 5}} msg] $msg
+} {1 {attempt to call eval in deleted interpreter}}     
+
+# Test alias deletion
+
+test interp-19.1 {alias deletion} {
+    catch {interp delete a}
+    interp create a
+    interp alias a foo a bar
+    set s [interp alias a foo {}]
+    interp delete a
+    set s
+} {}
+test interp-19.2 {alias deletion} {
+    catch {interp delete a}
+    interp create a
+    catch {interp alias a foo {}} msg
+    interp delete a
+    set msg
+} {alias "foo" not found}
+test interp-19.3 {alias deletion} {
+    catch {interp delete a}
+    interp create a
+    interp alias a foo a bar
+    interp eval a {rename foo zop}
+    interp alias a foo a zop
+    catch {interp eval a foo} msg
+    interp delete a
+    set msg
+} {invalid command name "bar"}
+test interp-19.4 {alias deletion} {
+    catch {interp delete a}
+    interp create a
+    interp alias a foo a bar
+    interp eval a {rename foo zop}
+    catch {interp eval a foo} msg
+    interp delete a
+    set msg
+} {invalid command name "foo"}
+test interp-19.5 {alias deletion} {
+    catch {interp delete a}
+    interp create a
+    interp eval a {proc bar {} {return 1}}
+    interp alias a foo a bar
+    interp eval a {rename foo zop}
+    catch {interp eval a zop} msg
+    interp delete a
+    set msg
+} 1
+test interp-19.6 {alias deletion} {
+    catch {interp delete a}
+    interp create a
+    interp alias a foo a bar
+    interp eval a {rename foo zop}
+    interp alias a foo a zop
+    set s [interp aliases a]
+    interp delete a
+    set s
+} {::foo foo}
+test interp-19.7 {alias deletion, renaming} {
+    catch {interp delete a}
+    interp create a
+    interp alias a foo a bar
+    interp eval a rename foo blotz
+    interp alias a foo {}
+    set s [interp aliases a]
+    interp delete a
+    set s
+} {}
+test interp-19.8 {alias deletion, renaming} {
+    catch {interp delete a}
+    interp create a
+    interp alias a foo a bar
+    interp eval a rename foo blotz
+    set l ""
+    lappend l [interp aliases a]
+    interp alias a foo {}
+    lappend l [interp aliases a]
+    interp delete a
+    set l
+} {foo {}}
+test interp-19.9 {alias deletion, renaming} {
+    catch {interp delete a}
+    interp create a
+    interp alias a foo a bar
+    interp eval a rename foo blotz
+    interp eval a {proc foo {} {expr 34 * 34}}
+    interp alias a foo {}
+    set l [interp eval a foo]
+    interp delete a
+    set l
+} 1156    
+
+test interp-20.1 {interp hide, interp expose and interp invokehidden} {
+    set a [interp create]
+    $a eval {proc unknown {x args} {error "invalid command name \"$x\""}}
+    $a eval {proc foo {} {}}
+    $a hide foo
+    catch {$a eval foo something} msg
+    interp delete $a
+    set msg
+} {invalid command name "foo"}
+test interp-20.2 {interp hide, interp expose and interp invokehidden} {
+    set a [interp create]
+    $a eval {proc unknown {x args} {error "invalid command name \"$x\""}}
+    $a hide list
+    set l ""
+    lappend l [catch {$a eval {list 1 2 3}} msg] $msg
+    $a expose list
+    lappend l [catch {$a eval {list 1 2 3}} msg] $msg
+    interp delete $a
+    set l
+} {1 {invalid command name "list"} 0 {1 2 3}}
+test interp-20.3 {interp hide, interp expose and interp invokehidden} {
+    set a [interp create]
+    $a eval {proc unknown {x args} {error "invalid command name \"$x\""}}
+    $a hide list
+    set l ""
+    lappend l [catch { $a eval {list 1 2 3}       } msg] $msg
+    lappend l [catch { $a invokehidden list 1 2 3 } msg] $msg
+    $a expose list
+    lappend l [catch { $a eval {list 1 2 3}       } msg] $msg
+    interp delete $a
+    set l
+} {1 {invalid command name "list"} 0 {1 2 3} 0 {1 2 3}}
+test interp-20.4 {interp hide, interp expose and interp invokehidden -- passing {}} {
+    set a [interp create]
+    $a eval {proc unknown {x args} {error "invalid command name \"$x\""}}
+    $a hide list
+    set l ""
+    lappend l [catch { $a eval {list 1 2 3}            } msg] $msg
+    lappend l [catch { $a invokehidden list {"" 1 2 3} } msg] $msg
+    $a expose list
+    lappend l [catch { $a eval {list 1 2 3}            } msg] $msg
+    interp delete $a
+    set l
+} {1 {invalid command name "list"} 0 {{"" 1 2 3}} 0 {1 2 3}}
+test interp-20.5 {interp hide, interp expose and interp invokehidden -- passing {}} {
+    set a [interp create]
+    $a eval {proc unknown {x args} {error "invalid command name \"$x\""}}
+    $a hide list
+    set l ""
+    lappend l [catch { $a eval {list 1 2 3}            } msg] $msg
+    lappend l [catch { $a invokehidden list {{} 1 2 3} } msg] $msg
+    $a expose list
+    lappend l [catch { $a eval {list 1 2 3}            } msg] $msg
+    interp delete $a
+    set l
+} {1 {invalid command name "list"} 0 {{{} 1 2 3}} 0 {1 2 3}}
+test interp-20.6 {interp invokehidden -- eval args} {
+    set a [interp create]
+    $a hide list
+    set l ""
+    set z 45
+    lappend l [catch { $a invokehidden list $z 1 2 3 } msg] $msg
+    $a expose list
+    lappend l [catch { $a eval list $z 1 2 3         } msg] $msg
+    interp delete $a
+    set l
+} {0 {45 1 2 3} 0 {45 1 2 3}}
+test interp-20.7 {interp invokehidden vs variable eval} {
+    set a [interp create]
+    $a hide list
+    set z 45
+    set l [list [catch {$a invokehidden list {$z a b c}} msg] $msg]
+    interp delete $a
+    set l
+} {0 {{$z a b c}}}
+test interp-20.8 {interp invokehidden vs variable eval} {
+    set a [interp create]
+    $a hide list
+    $a eval set z 89
+    set z 45
+    set l [list [catch {$a invokehidden list {$z a b c}} msg] $msg]
+    interp delete $a
+    set l
+} {0 {{$z a b c}}}
+test interp-20.9 {interp invokehidden vs variable eval} {
+    set a [interp create]
+    $a hide list
+    $a eval set z 89
+    set z 45
+    set l ""
+    lappend l [catch {$a invokehidden list $z {$z a b c}} msg] $msg
+    interp delete $a
+    set l
+} {0 {45 {$z a b c}}}
+test interp-20.10 {interp hide, interp expose and interp invokehidden} {
+    set a [interp create]
+    $a eval {proc unknown {x args} {error "invalid command name \"$x\""}}
+    $a eval {proc foo {} {}}
+    interp hide $a foo
+    catch {interp eval $a foo something} msg
+    interp delete $a
+    set msg
+} {invalid command name "foo"}
+test interp-20.11 {interp hide, interp expose and interp invokehidden} {
+    set a [interp create]
+    $a eval {proc unknown {x args} {error "invalid command name \"$x\""}}
+    interp hide $a list
+    set l ""
+    lappend l [catch {interp eval $a {list 1 2 3}} msg] $msg
+    interp expose $a list
+    lappend l [catch {interp eval $a {list 1 2 3}} msg] $msg
+    interp delete $a
+    set l
+} {1 {invalid command name "list"} 0 {1 2 3}}
+test interp-20.12 {interp hide, interp expose and interp invokehidden} {
+    set a [interp create]
+    $a eval {proc unknown {x args} {error "invalid command name \"$x\""}}
+    interp hide $a list
+    set l ""
+    lappend l [catch {interp eval $a {list 1 2 3}      } msg] $msg
+    lappend l [catch {interp invokehidden $a list 1 2 3} msg] $msg
+    interp expose $a list
+    lappend l [catch {interp eval $a {list 1 2 3}      } msg] $msg
+    interp delete $a
+    set l
+} {1 {invalid command name "list"} 0 {1 2 3} 0 {1 2 3}}
+test interp-20.13 {interp hide, interp expose, interp invokehidden -- passing {}} {
+    set a [interp create]
+    $a eval {proc unknown {x args} {error "invalid command name \"$x\""}}
+    interp hide $a list
+    set l ""
+    lappend l [catch {interp eval $a {list 1 2 3}           } msg] $msg
+    lappend l [catch {interp invokehidden $a list {"" 1 2 3}} msg] $msg
+    interp expose $a list
+    lappend l [catch {interp eval $a {list 1 2 3}           } msg] $msg
+    interp delete $a
+    set l
+} {1 {invalid command name "list"} 0 {{"" 1 2 3}} 0 {1 2 3}}
+test interp-20.14 {interp hide, interp expose, interp invokehidden -- passing {}} {
+    set a [interp create]
+    $a eval {proc unknown {x args} {error "invalid command name \"$x\""}}
+    interp hide $a list
+    set l ""
+    lappend l [catch {interp eval $a {list 1 2 3}           } msg] $msg
+    lappend l [catch {interp invokehidden $a list {{} 1 2 3}} msg] $msg
+    interp expose $a list
+    lappend l [catch {$a eval {list 1 2 3}                  } msg] $msg
+    interp delete $a
+    set l
+} {1 {invalid command name "list"} 0 {{{} 1 2 3}} 0 {1 2 3}}
+test interp-20.15 {interp invokehidden -- eval args} {
+    catch {interp delete a}
+    interp create a
+    interp hide a list
+    set l ""
+    set z 45
+    lappend l [catch {interp invokehidden a list $z 1 2 3} msg]
+    lappend l $msg
+    a expose list
+    lappend l [catch {interp eval a list $z 1 2 3} msg]
+    lappend l $msg
+    interp delete a
+    set l
+} {0 {45 1 2 3} 0 {45 1 2 3}}
+test interp-20.16 {interp invokehidden vs variable eval} {
+    catch {interp delete a}
+    interp create a
+    interp hide a list
+    set z 45
+    set l ""
+    lappend l [catch {interp invokehidden a list {$z a b c}} msg]
+    lappend l $msg
+    interp delete a
+    set l
+} {0 {{$z a b c}}}
+test interp-20.17 {interp invokehidden vs variable eval} {
+    catch {interp delete a}
+    interp create a
+    interp hide a list
+    a eval set z 89
+    set z 45
+    set l ""
+    lappend l [catch {interp invokehidden a list {$z a b c}} msg]
+    lappend l $msg
+    interp delete a
+    set l
+} {0 {{$z a b c}}}
+test interp-20.18 {interp invokehidden vs variable eval} {
+    catch {interp delete a}
+    interp create a
+    interp hide a list
+    a eval set z 89
+    set z 45
+    set l ""
+    lappend l [catch {interp invokehidden a list $z {$z a b c}} msg]
+    lappend l $msg
+    interp delete a
+    set l
+} {0 {45 {$z a b c}}}
+test interp-20.19 {interp invokehidden vs nested commands} {
+    catch {interp delete a}
+    interp create a
+    a hide list
+    set l [a invokehidden list {[list x y z] f g h} z]
+    interp delete a
+    set l
+} {{[list x y z] f g h} z}
+test interp-20.20 {interp invokehidden vs nested commands} {
+    catch {interp delete a}
+    interp create a
+    a hide list
+    set l [interp invokehidden a list {[list x y z] f g h} z]
+    interp delete a
+    set l
+} {{[list x y z] f g h} z}
+test interp-20.21 {interp hide vs safety} {
+    catch {interp delete a}
+    interp create a -safe
+    set l ""
+    lappend l [catch {a hide list} msg]    
+    lappend l $msg
+    interp delete a
+    set l
+} {0 {}}
+test interp-20.22 {interp hide vs safety} {
+    catch {interp delete a}
+    interp create a -safe
+    set l ""
+    lappend l [catch {interp hide a list} msg]    
+    lappend l $msg
+    interp delete a
+    set l
+} {0 {}}
+test interp-20.23 {interp hide vs safety} {
+    catch {interp delete a}
+    interp create a -safe
+    set l ""
+    lappend l [catch {a eval {interp hide {} list}} msg]    
+    lappend l $msg
+    interp delete a
+    set l
+} {1 {permission denied: safe interpreter cannot hide commands}}
+test interp-20.24 {interp hide vs safety} {
+    catch {interp delete a}
+    interp create a -safe
+    interp create {a b}
+    set l ""
+    lappend l [catch {a eval {interp hide b list}} msg]    
+    lappend l $msg
+    interp delete a
+    set l
+} {1 {permission denied: safe interpreter cannot hide commands}}
+test interp-20.25 {interp hide vs safety} {
+    catch {interp delete a}
+    interp create a -safe
+    interp create {a b}
+    set l ""
+    lappend l [catch {interp hide {a b} list} msg]
+    lappend l $msg
+    interp delete a
+    set l
+} {0 {}}
+test interp-20.26 {interp expoose vs safety} {
+    catch {interp delete a}
+    interp create a -safe
+    set l ""
+    lappend l [catch {a hide list} msg]    
+    lappend l $msg
+    lappend l [catch {a expose list} msg]
+    lappend l $msg
+    interp delete a
+    set l
+} {0 {} 0 {}}
+test interp-20.27 {interp expose vs safety} {
+    catch {interp delete a}
+    interp create a -safe
+    set l ""
+    lappend l [catch {interp hide a list} msg]    
+    lappend l $msg
+    lappend l [catch {interp expose a list} msg]    
+    lappend l $msg
+    interp delete a
+    set l
+} {0 {} 0 {}}
+test interp-20.28 {interp expose vs safety} {
+    catch {interp delete a}
+    interp create a -safe
+    set l ""
+    lappend l [catch {a hide list} msg]    
+    lappend l $msg
+    lappend l [catch {a eval {interp expose {} list}} msg]
+    lappend l $msg
+    interp delete a
+    set l
+} {0 {} 1 {permission denied: safe interpreter cannot expose commands}}
+test interp-20.29 {interp expose vs safety} {
+    catch {interp delete a}
+    interp create a -safe
+    set l ""
+    lappend l [catch {interp hide a list} msg]    
+    lappend l $msg
+    lappend l [catch {a eval {interp expose {} list}} msg]    
+    lappend l $msg
+    interp delete a
+    set l
+} {0 {} 1 {permission denied: safe interpreter cannot expose commands}}
+test interp-20.30 {interp expose vs safety} {
+    catch {interp delete a}
+    interp create a -safe
+    interp create {a b}
+    set l ""
+    lappend l [catch {interp hide {a b} list} msg]    
+    lappend l $msg
+    lappend l [catch {a eval {interp expose b list}} msg]    
+    lappend l $msg
+    interp delete a
+    set l
+} {0 {} 1 {permission denied: safe interpreter cannot expose commands}}
+test interp-20.31 {interp expose vs safety} {
+    catch {interp delete a}
+    interp create a -safe
+    interp create {a b}
+    set l ""
+    lappend l [catch {interp hide {a b} list} msg]    
+    lappend l $msg
+    lappend l [catch {interp expose {a b} list} msg]
+    lappend l $msg
+    interp delete a
+    set l
+} {0 {} 0 {}}
+test interp-20.32 {interp invokehidden vs safety} {
+    catch {interp delete a}
+    interp create a -safe
+    interp hide a list
+    set l ""
+    lappend l [catch {a eval {interp invokehidden {} list a b c}} msg]
+    lappend l $msg
+    interp delete a
+    set l
+} {1 {not allowed to invoke hidden commands from safe interpreter}}
+test interp-20.33 {interp invokehidden vs safety} {
+    catch {interp delete a}
+    interp create a -safe
+    interp hide a list
+    set l ""
+    lappend l [catch {a eval {interp invokehidden {} list a b c}} msg]
+    lappend l $msg
+    lappend l [catch {a invokehidden list a b c} msg]
+    lappend l $msg
+    interp delete a
+    set l
+} {1 {not allowed to invoke hidden commands from safe interpreter}\
+0 {a b c}}
+test interp-20.34 {interp invokehidden vs safety} {
+    catch {interp delete a}
+    interp create a -safe
+    interp create {a b}
+    interp hide {a b} list
+    set l ""
+    lappend l [catch {a eval {interp invokehidden b list a b c}} msg]
+    lappend l $msg
+    lappend l [catch {interp invokehidden {a b} list a b c} msg]
+    lappend l $msg
+    interp delete a
+    set l
+} {1 {not allowed to invoke hidden commands from safe interpreter}\
+0 {a b c}}
+test interp-20.35 {invokehidden at local level} {
+    catch {interp delete a}
+    interp create a
+    a eval {
+	proc p1 {} {
+	    set z 90
+	    a1
+	    set z
+	}
+	proc h1 {} {
+	    upvar z z
+	    set z 91
+	}
+    }
+    a hide h1
+    a alias a1 a1
+    proc a1 {} {
+	interp invokehidden a h1
+    }
+    set r [interp eval a p1]
+    interp delete a
+    set r
+} 91
+test interp-20.36 {invokehidden at local level} {
+    catch {interp delete a}
+    interp create a
+    a eval {
+	set z 90
+	proc p1 {} {
+	    global z
+	    a1
+	    set z
+	}
+	proc h1 {} {
+	    upvar z z
+	    set z 91
+	}
+    }
+    a hide h1
+    a alias a1 a1
+    proc a1 {} {
+	interp invokehidden a h1
+    }
+    set r [interp eval a p1]
+    interp delete a
+    set r
+} 91
+test interp-20.37 {invokehidden at local level} {
+    catch {interp delete a}
+    interp create a
+    a eval {
+	proc p1 {} {
+	    a1
+	    set z
+	}
+	proc h1 {} {
+	    upvar z z
+	    set z 91
+	}
+    }
+    a hide h1
+    a alias a1 a1
+    proc a1 {} {
+	interp invokehidden a h1
+    }
+    set r [interp eval a p1]
+    interp delete a
+    set r
+} 91
+test interp-20.38 {invokehidden at global level} {
+    catch {interp delete a}
+    interp create a
+    a eval {
+	proc p1 {} {
+	    a1
+	    set z
+	}
+	proc h1 {} {
+	    upvar z z
+	    set z 91
+	}
+    }
+    a hide h1
+    a alias a1 a1
+    proc a1 {} {
+	interp invokehidden a -global h1
+    }
+    set r [catch {interp eval a p1} msg]
+    interp delete a
+    list $r $msg
+} {1 {can't read "z": no such variable}}
+test interp-20.39 {invokehidden at global level} {
+    catch {interp delete a}
+    interp create a
+    a eval {
+	proc p1 {} {
+	    global z
+	    a1
+	    set z
+	}
+	proc h1 {} {
+	    upvar z z
+	    set z 91
+	}
+    }
+    a hide h1
+    a alias a1 a1
+    proc a1 {} {
+	interp invokehidden a -global h1
+    }
+    set r [catch {interp eval a p1} msg]
+    interp delete a
+    list $r $msg
+} {0 91}
+test interp-20.40 {safe, invokehidden at local level} {
+    catch {interp delete a}
+    interp create a -safe
+    a eval {
+	proc p1 {} {
+	    set z 90
+	    a1
+	    set z
+	}
+	proc h1 {} {
+	    upvar z z
+	    set z 91
+	}
+    }
+    a hide h1
+    a alias a1 a1
+    proc a1 {} {
+	interp invokehidden a h1
+    }
+    set r [interp eval a p1]
+    interp delete a
+    set r
+} 91
+test interp-20.41 {safe, invokehidden at local level} {
+    catch {interp delete a}
+    interp create a -safe
+    a eval {
+	set z 90
+	proc p1 {} {
+	    global z
+	    a1
+	    set z
+	}
+	proc h1 {} {
+	    upvar z z
+	    set z 91
+	}
+    }
+    a hide h1
+    a alias a1 a1
+    proc a1 {} {
+	interp invokehidden a h1
+    }
+    set r [interp eval a p1]
+    interp delete a
+    set r
+} 91
+test interp-20.42 {safe, invokehidden at local level} {
+    catch {interp delete a}
+    interp create a -safe
+    a eval {
+	proc p1 {} {
+	    a1
+	    set z
+	}
+	proc h1 {} {
+	    upvar z z
+	    set z 91
+	}
+    }
+    a hide h1
+    a alias a1 a1
+    proc a1 {} {
+	interp invokehidden a h1
+    }
+    set r [interp eval a p1]
+    interp delete a
+    set r
+} 91
+test interp-20.43 {invokehidden at global level} {
+    catch {interp delete a}
+    interp create a
+    a eval {
+	proc p1 {} {
+	    a1
+	    set z
+	}
+	proc h1 {} {
+	    upvar z z
+	    set z 91
+	}
+    }
+    a hide h1
+    a alias a1 a1
+    proc a1 {} {
+	interp invokehidden a -global h1
+    }
+    set r [catch {interp eval a p1} msg]
+    interp delete a
+    list $r $msg
+} {1 {can't read "z": no such variable}}
+test interp-20.44 {invokehidden at global level} {
+    catch {interp delete a}
+    interp create a
+    a eval {
+	proc p1 {} {
+	    global z
+	    a1
+	    set z
+	}
+	proc h1 {} {
+	    upvar z z
+	    set z 91
+	}
+    }
+    a hide h1
+    a alias a1 a1
+    proc a1 {} {
+	interp invokehidden a -global h1
+    }
+    set r [catch {interp eval a p1} msg]
+    interp delete a
+    list $r $msg
+} {0 91}
+test interp-20.45 {interp hide vs namespaces} {
+    catch {interp delete a}
+    interp create a
+    a eval {
+        namespace eval foo {}
+	proc foo::x {} {}
+    }
+    set l [list [catch {interp hide a foo::x} msg] $msg]
+    interp delete a
+    set l
+} {1 {cannot use namespace qualifiers in hidden command token (rename)}}
+test interp-20.46 {interp hide vs namespaces} {
+    catch {interp delete a}
+    interp create a
+    a eval {
+        namespace eval foo {}
+	proc foo::x {} {}
+    }
+    set l [list [catch {interp hide a foo::x x} msg] $msg]
+    interp delete a
+    set l
+} {1 {can only hide global namespace commands (use rename then hide)}}
+test interp-20.47 {interp hide vs namespaces} {
+    catch {interp delete a}
+    interp create a
+    a eval {
+	proc x {} {}
+    }
+    set l [list [catch {interp hide a x foo::x} msg] $msg]
+    interp delete a
+    set l
+} {1 {cannot use namespace qualifiers in hidden command token (rename)}}
+test interp-20.48 {interp hide vs namespaces} {
+    catch {interp delete a}
+    interp create a
+    a eval {
+        namespace eval foo {}
+	proc foo::x {} {}
+    }
+    set l [list [catch {interp hide a foo::x bar::x} msg] $msg]
+    interp delete a
+    set l
+} {1 {cannot use namespace qualifiers in hidden command token (rename)}}
+test interp-20.49 {interp invokehidden -namespace} -setup {
+    set script [makeFile {
+	set x [namespace current]
+    } script]
+    interp create -safe slave
+} -body {
+    slave invokehidden -namespace ::foo source $script
+    slave eval {set ::foo::x}
+} -cleanup {
+    interp delete slave
+    removeFile script
+} -result ::foo
+test interp-20.50 {Bug 2486550} -setup {
+    interp create slave
+} -body {
+    slave hide coroutine
+    slave invokehidden coroutine
+} -cleanup {
+    interp delete slave
+} -returnCodes error -match glob -result *
+test interp-20.50.1 {Bug 2486550} -setup {
+    interp create slave
+} -body {
+    slave hide coroutine
+    catch {slave invokehidden coroutine} m o
+    dict get $o -errorinfo
+} -cleanup {
+    unset -nocomplain m 0
+    interp delete slave
+} -returnCodes ok -result {wrong # args: should be "coroutine name cmd ?arg ...?"
+    while executing
+"coroutine"
+    invoked from within
+"slave invokehidden coroutine"}
+
+test interp-21.1 {interp hidden} {
+    interp hidden {}
+} ""
+test interp-21.2 {interp hidden} {
+    interp hidden
+} ""
+test interp-21.3 {interp hidden vs interp hide, interp expose} -setup {
+    set l ""
+} -body {
+    lappend l [interp hidden]
+    interp hide {} pwd
+    lappend l [interp hidden]
+    interp expose {} pwd
+    lappend l [interp hidden]
+} -result {{} pwd {}}
+test interp-21.4 {interp hidden} -setup {
+    catch {interp delete a}
+} -body {
+    interp create a
+    interp hidden a
+} -cleanup {
+    interp delete a
+} -result ""
+test interp-21.5 {interp hidden} -setup {
+    catch {interp delete a}
+} -body {
+    interp create -safe a
+    lsort [interp hidden a]
+} -cleanup {
+    interp delete a
+} -result $hidden_cmds 
+test interp-21.6 {interp hidden vs interp hide, interp expose} -setup {
+    catch {interp delete a}
+    set l ""
+} -body {
+    interp create a
+    lappend l [interp hidden a]
+    interp hide a pwd
+    lappend l [interp hidden a]
+    interp expose a pwd
+    lappend l [interp hidden a]
+} -cleanup {
+    interp delete a
+} -result {{} pwd {}}
+test interp-21.7 {interp hidden} -setup {
+    catch {interp delete a}
+} -body {
+    interp create a
+    a hidden
+} -cleanup {
+    interp delete a
+} -result ""
+test interp-21.8 {interp hidden} -setup {
+    catch {interp delete a}
+} -body {
+    interp create a -safe
+    lsort [a hidden]
+} -cleanup {
+    interp delete a
+} -result $hidden_cmds
+test interp-21.9 {interp hidden vs interp hide, interp expose} -setup {
+    catch {interp delete a}
+    set l ""
+} -body {
+    interp create a
+    lappend l [a hidden]
+    a hide pwd
+    lappend l [a hidden]
+    a expose pwd
+    lappend l [a hidden]
+} -cleanup {
+    interp delete a
+} -result {{} pwd {}}
+
+test interp-22.1 {testing interp marktrusted} {
+    catch {interp delete a}
+    interp create a
+    set l ""
+    lappend l [a issafe]
+    lappend l [a marktrusted]
+    lappend l [a issafe]
+    interp delete a
+    set l
+} {0 {} 0}
+test interp-22.2 {testing interp marktrusted} {
+    catch {interp delete a}
+    interp create a
+    set l ""
+    lappend l [interp issafe a]
+    lappend l [interp marktrusted a]
+    lappend l [interp issafe a]
+    interp delete a
+    set l
+} {0 {} 0}
+test interp-22.3 {testing interp marktrusted} {
+    catch {interp delete a}
+    interp create a -safe
+    set l ""
+    lappend l [a issafe]
+    lappend l [a marktrusted]
+    lappend l [a issafe]
+    interp delete a
+    set l
+} {1 {} 0}
+test interp-22.4 {testing interp marktrusted} {
+    catch {interp delete a}
+    interp create a -safe
+    set l ""
+    lappend l [interp issafe a]
+    lappend l [interp marktrusted a]
+    lappend l [interp issafe a]
+    interp delete a
+    set l
+} {1 {} 0}
+test interp-22.5 {testing interp marktrusted} {
+    catch {interp delete a}
+    interp create a -safe
+    interp create {a b}
+    catch {a eval {interp marktrusted b}} msg
+    interp delete a
+    set msg
+} {permission denied: safe interpreter cannot mark trusted}
+test interp-22.6 {testing interp marktrusted} {
+    catch {interp delete a}
+    interp create a -safe
+    interp create {a b}
+    catch {a eval {b marktrusted}} msg
+    interp delete a
+    set msg
+} {permission denied: safe interpreter cannot mark trusted}
+test interp-22.7 {testing interp marktrusted} {
+    catch {interp delete a}
+    interp create a -safe
+    set l ""
+    lappend l [interp issafe a]
+    interp marktrusted a
+    interp create {a b}
+    lappend l [interp issafe a]
+    lappend l [interp issafe {a b}]
+    interp delete a
+    set l
+} {1 0 0}
+test interp-22.8 {testing interp marktrusted} {
+    catch {interp delete a}
+    interp create a -safe
+    set l ""
+    lappend l [interp issafe a]
+    interp create {a b}
+    lappend l [interp issafe {a b}]
+    interp marktrusted a
+    interp create {a c}
+    lappend l [interp issafe a]
+    lappend l [interp issafe {a c}]
+    interp delete a
+    set l
+} {1 1 0 0}
+test interp-22.9 {testing interp marktrusted} {
+    catch {interp delete a}
+    interp create a -safe
+    set l ""
+    lappend l [interp issafe a]
+    interp create {a b}
+    lappend l [interp issafe {a b}]
+    interp marktrusted {a b}
+    lappend l [interp issafe a]
+    lappend l [interp issafe {a b}]
+    interp create {a b c}
+    lappend l [interp issafe {a b c}]
+    interp delete a
+    set l
+} {1 1 1 0 0}
+
+test interp-23.1 {testing hiding vs aliases: unsafe interp} -setup {
+    catch {interp delete a}
+    set l ""
+} -body {
+    interp create a
+    lappend l [interp hidden a]
+    a alias bar bar
+    lappend l [interp aliases a] [interp hidden a]
+    a hide bar
+    lappend l [interp aliases a] [interp hidden a]
+    a alias bar {}
+    lappend l [interp aliases a] [interp hidden a]
+} -cleanup {
+    interp delete a
+} -result {{} bar {} bar bar {} {}}
+test interp-23.2 {testing hiding vs aliases: safe interp} -setup {
+    catch {interp delete a}
+    set l ""
+} -constraints {unixOrPc} -body {
+    interp create a -safe
+    lappend l [lsort [interp hidden a]]
+    a alias bar bar
+    lappend l [lsort [interp aliases a]] [lsort [interp hidden a]]
+    a hide bar
+    lappend l [lsort [interp aliases a]] [lsort [interp hidden a]]
+    a alias bar {}
+    lappend l [lsort [interp aliases a]] [lsort [interp hidden a]]
+} -cleanup {
+    interp delete a
+} -result [list $hidden_cmds {::tcl::mathfunc::max ::tcl::mathfunc::min bar clock} $hidden_cmds {::tcl::mathfunc::max ::tcl::mathfunc::min bar clock} [lsort [concat $hidden_cmds bar]] {::tcl::mathfunc::max ::tcl::mathfunc::min clock} $hidden_cmds]
+
+test interp-24.1 {result resetting on error} -setup {
+    catch {interp delete a}
+} -body {
+    interp create a
+    interp alias a foo {} apply {args {error $args}}
+    interp eval a {
+	lappend l [catch {foo 1 2 3} msg] $msg
+	lappend l [catch {foo 3 4 5} msg] $msg
+    }
+} -cleanup {
+    interp delete a
+} -result {1 {1 2 3} 1 {3 4 5}}
+test interp-24.2 {result resetting on error} -setup {
+    catch {interp delete a}
+} -body {
+    interp create a -safe
+    interp alias a foo {} apply {args {error $args}}
+    interp eval a {
+	lappend l [catch {foo 1 2 3} msg] $msg
+	lappend l [catch {foo 3 4 5} msg] $msg
+    }
+} -cleanup {
+    interp delete a
+} -result {1 {1 2 3} 1 {3 4 5}}
+test interp-24.3 {result resetting on error} -setup {
+    catch {interp delete a}
+} -body {
+    interp create a
+    interp create {a b}
+    interp eval a {
+	proc foo args {error $args}
+    }
+    interp alias {a b} foo a foo
+    interp eval {a b} {
+	lappend l [catch {foo 1 2 3} msg] $msg
+	lappend l [catch {foo 3 4 5} msg] $msg
+    }
+} -cleanup {
+    interp delete a
+} -result {1 {1 2 3} 1 {3 4 5}}
+test interp-24.4 {result resetting on error} -setup {
+    catch {interp delete a}
+} -body {
+    interp create a -safe
+    interp create {a b}
+    interp eval a {
+	proc foo args {error $args}
+    }
+    interp alias {a b} foo a foo
+    interp eval {a b} {
+	lappend l [catch {foo 1 2 3} msg]
+	lappend l $msg
+	lappend l [catch {foo 3 4 5} msg]
+	lappend l $msg
+    }
+} -cleanup {
+    interp delete a
+} -result {1 {1 2 3} 1 {3 4 5}}
+test interp-24.5 {result resetting on error} -setup {
+    catch {interp delete a}
+    catch {interp delete b}
+} -body {
+    interp create a
+    interp create b
+    interp eval a {
+	proc foo args {error $args}
+    }
+    interp alias b foo a foo
+    interp eval b {
+	lappend l [catch {foo 1 2 3} msg] $msg
+	lappend l [catch {foo 3 4 5} msg] $msg
+    }
+} -cleanup {
+    interp delete a
+    interp delete b
+} -result {1 {1 2 3} 1 {3 4 5}}
+test interp-24.6 {result resetting on error} -setup {
+    catch {interp delete a}
+    catch {interp delete b}
+} -body {
+    interp create a -safe
+    interp create b -safe
+    interp eval a {
+	proc foo args {error $args}
+    }
+    interp alias b foo a foo
+    interp eval b {
+	lappend l [catch {foo 1 2 3} msg] $msg
+	lappend l [catch {foo 3 4 5} msg] $msg
+    }
+} -cleanup {
+    interp delete a
+    interp delete b
+} -result {1 {1 2 3} 1 {3 4 5}}
+test interp-24.7 {result resetting on error} -setup {
+    catch {interp delete a}
+    set l {}
+} -body {
+    interp create a
+    interp eval a {
+	proc foo args {error $args}
+    }
+    lappend l [catch {interp eval a foo 1 2 3} msg] $msg
+    lappend l [catch {interp eval a foo 3 4 5} msg] $msg
+} -cleanup {
+    interp delete a
+} -result {1 {1 2 3} 1 {3 4 5}}
+test interp-24.8 {result resetting on error} -setup {
+    catch {interp delete a}
+    set l {}
+} -body {
+    interp create a -safe
+    interp eval a {
+	proc foo args {error $args}
+    }
+    lappend l [catch {interp eval a foo 1 2 3} msg] $msg
+    lappend l [catch {interp eval a foo 3 4 5} msg] $msg
+} -cleanup {
+    interp delete a
+} -result {1 {1 2 3} 1 {3 4 5}}
+test interp-24.9 {result resetting on error} -setup {
+    catch {interp delete a}
+    set l {}
+} -body {
+    interp create a
+    interp create {a b}
+    interp eval {a b} {
+	proc foo args {error $args}
+    }
+    interp eval a {
+	proc foo args {
+	    eval interp eval b foo $args
+	}
+    }
+    lappend l [catch {interp eval a foo 1 2 3} msg] $msg
+    lappend l [catch {interp eval a foo 3 4 5} msg] $msg
+} -cleanup {
+    interp delete a
+} -result {1 {1 2 3} 1 {3 4 5}}
+test interp-24.10 {result resetting on error} -setup {
+    catch {interp delete a}
+    set l {}
+} -body {
+    interp create a -safe
+    interp create {a b}
+    interp eval {a b} {
+	proc foo args {error $args}
+    }
+    interp eval a {
+	proc foo args {
+	    eval interp eval b foo $args
+	}
+    }
+    lappend l [catch {interp eval a foo 1 2 3} msg] $msg
+    lappend l [catch {interp eval a foo 3 4 5} msg] $msg
+} -cleanup {
+    interp delete a
+} -result {1 {1 2 3} 1 {3 4 5}}
+test interp-24.11 {result resetting on error} -setup {
+    catch {interp delete a}
+} -body {
+    interp create a
+    interp create {a b}
+    interp eval {a b} {
+	proc foo args {error $args}
+    }
+    interp eval a {
+	proc foo args {
+	    lappend l [catch {eval interp eval b foo $args} msg] $msg
+	    lappend l [catch {eval interp eval b foo $args} msg] $msg
+	}
+    }
+    interp eval a foo 1 2 3
+} -cleanup {
+    interp delete a
+} -result {1 {1 2 3} 1 {1 2 3}}
+test interp-24.12 {result resetting on error} -setup {
+    catch {interp delete a}
+} -body {
+    interp create a -safe
+    interp create {a b}
+    interp eval {a b} {
+	proc foo args {error $args}
+    }
+    interp eval a {
+	proc foo args {
+	    lappend l [catch {eval interp eval b foo $args} msg] $msg
+	    lappend l [catch {eval interp eval b foo $args} msg] $msg
+	}
+    }
+    interp eval a foo 1 2 3
+} -cleanup {
+    interp delete a
+} -result {1 {1 2 3} 1 {1 2 3}}
+
+test interp-25.1 {testing aliasing of string commands} -setup {
+    catch {interp delete a}
+} -body {
+    interp create a
+    a alias exec foo		;# Relies on exec being a string command!
+    interp delete a
+} -result ""
+
+#
+# Interps result transmission
+#
+
+test interp-26.1 {result code transmission : interp eval direct} {
+    # Test that all the possibles error codes from Tcl get passed up
+    # from the slave interp's context to the master, even though the
+    # slave nominally thinks the command is running at the root level.
+    catch {interp delete a}
+    interp create a
+    set res {}
+    # use a for so if a return -code break 'escapes' we would notice
+    for {set code -1} {$code<=5} {incr code} {
+	lappend res [catch {interp eval a return -code $code} msg]
+    }
+    interp delete a
+    set res
+} {-1 0 1 2 3 4 5}
+test interp-26.2 {result code transmission : interp eval indirect} {
+    # retcode == 2 == return is special
+    catch {interp delete a}
+    interp create a
+    interp eval a {proc retcode {code} {return -code $code ret$code}}
+    set res {}
+    # use a for so if a return -code break 'escapes' we would notice
+    for {set code -1} {$code<=5} {incr code} {
+	lappend res [catch {interp eval a retcode $code} msg] $msg
+    }
+    interp delete a
+    set res
+} {-1 ret-1 0 ret0 1 ret1 0 ret2 3 ret3 4 ret4 5 ret5}
+test interp-26.3 {result code transmission : aliases} {
+    # Test that all the possibles error codes from Tcl get passed up from the
+    # slave interp's context to the master, even though the slave nominally
+    # thinks the command is running at the root level.
+    catch {interp delete a}
+    interp create a
+    set res {}
+    proc MyTestAlias {code} {
+	return -code $code ret$code
+    }
+    interp alias a Test {} MyTestAlias
+    for {set code -1} {$code<=5} {incr code} {
+	lappend res [interp eval a [list catch [list Test $code] msg]]
+    }
+    interp delete a
+    set res
+} {-1 0 1 2 3 4 5}
+test interp-26.4 {result code transmission: invoke hidden direct--bug 1637} \
+	{knownBug} {
+    # The known bug is that code 2 is returned, not the -code argument
+    catch {interp delete a}
+    interp create a
+    set res {}
+    interp hide a return
+    for {set code -1} {$code<=5} {incr code} {
+	lappend res [catch {interp invokehidden a return -code $code ret$code}]
+    }
+    interp delete a
+    set res
+} {-1 0 1 2 3 4 5}
+test interp-26.5 {result code transmission: invoke hidden indirect--bug 1637} -setup {
+    catch {interp delete a}
+    interp create a
+} -body {
+    # The known bug is that the break and continue should raise errors that
+    # they are used outside a loop.
+    set res {}
+    interp eval a {proc retcode {code} {return -code $code ret$code}}
+    interp hide a retcode
+    for {set code -1} {$code<=5} {incr code} {
+	lappend res [catch {interp invokehidden a retcode $code} msg] $msg
+    }
+    return $res
+} -cleanup {
+    interp delete a
+} -result {-1 ret-1 0 ret0 1 ret1 2 ret2 3 ret3 4 ret4 5 ret5}
+test interp-26.6 {result code transmission: all combined--bug 1637} -setup {
+    set interp [interp create]
+} -constraints knownBug -body {
+    # Test that all the possibles error codes from Tcl get passed in both
+    # directions.  This doesn't work.
+    proc MyTestAlias {interp args} {
+	global aliasTrace
+	lappend aliasTrace $args
+	interp invokehidden $interp {*}$args
+    }
+    foreach c {return} {
+	interp hide $interp  $c
+        interp alias $interp $c {} MyTestAlias $interp $c
+    }
+    interp eval $interp {proc ret {code} {return -code $code ret$code}}
+    set res {}
+    set aliasTrace {}
+    for {set code -1} {$code<=5} {incr code} {
+	lappend res [catch {interp eval $interp ret $code} msg] $msg
+    }
+    return $res
+} -cleanup {
+    interp delete $interp
+} -result {-1 ret-1 0 ret0 1 ret1 0 ret2 3 ret3 4 ret4 5 ret5}
+# Some tests might need to be added to check for difference between toplevel
+# and non-toplevel evals.
+# End of return code transmission section
+test interp-26.7 {errorInfo transmission: regular interps} -setup {
+    set interp [interp create]
+} -body {
+    proc MyError {secret} {
+	return -code error "msg"
+    }
+    proc MyTestAlias {interp args} {
+	MyError "some secret"
+    }
+    interp alias $interp test {} MyTestAlias $interp
+    interp eval $interp {catch test;set ::errorInfo}
+} -cleanup {
+    interp delete $interp
+} -result {msg
+    while executing
+"MyError "some secret""
+    (procedure "MyTestAlias" line 2)
+    invoked from within
+"test"}
+test interp-26.8 {errorInfo transmission: safe interps--bug 1637} -setup {
+    set interp [interp create -safe]
+} -constraints knownBug -body {
+    # this test fails because the errorInfo is fully transmitted whether the
+    # interp is safe or not.  The errorInfo should never report data from the
+    # master interpreter because it could contain sensitive information.
+    proc MyError {secret} {
+	return -code error "msg"
+    }
+    proc MyTestAlias {interp args} {
+	MyError "some secret"
+    }
+    interp alias $interp test {} MyTestAlias $interp
+    interp eval $interp {catch test;set ::errorInfo}
+} -cleanup {
+    interp delete $interp
+} -result {msg
+    while executing
+"test"}
+
+# Interps & Namespaces
+test interp-27.1 {interp aliases & namespaces} -setup {
+    set i [interp create]
+} -body {
+    set aliasTrace {}
+    proc tstAlias {args} { 
+	global aliasTrace
+	lappend aliasTrace [list [namespace current] $args]
+    }
+    $i alias foo::bar tstAlias foo::bar
+    $i eval foo::bar test
+    return $aliasTrace
+} -cleanup {
+    interp delete $i
+} -result {{:: {foo::bar test}}}
+test interp-27.2 {interp aliases & namespaces} -setup {
+    set i [interp create]
+} -body {
+    set aliasTrace {}
+    proc tstAlias {args} { 
+	global aliasTrace
+	lappend aliasTrace [list [namespace current] $args]
+    }
+    $i alias foo::bar tstAlias foo::bar
+    $i eval namespace eval foo {bar test}
+    return $aliasTrace
+} -cleanup {
+    interp delete $i
+} -result {{:: {foo::bar test}}}
+test interp-27.3 {interp aliases & namespaces} -setup {
+    set i [interp create]
+} -body {
+    set aliasTrace {}
+    proc tstAlias {args} { 
+	global aliasTrace
+	lappend aliasTrace [list [namespace current] $args]
+    }
+    interp eval $i {namespace eval foo {proc bar {} {error "bar called"}}}
+    interp alias $i foo::bar {} tstAlias foo::bar
+    interp eval $i {namespace eval foo {bar test}}
+    return $aliasTrace
+} -cleanup {
+    interp delete $i
+} -result {{:: {foo::bar test}}}
+test interp-27.4 {interp aliases & namespaces} -setup {
+    set i [interp create]
+} -body {
+    namespace eval foo2 {
+	variable aliasTrace {}
+	proc bar {args} { 
+	    variable aliasTrace
+	    lappend aliasTrace [list [namespace current] $args]
+	}
+    }
+    $i alias foo::bar foo2::bar foo::bar
+    $i eval namespace eval foo {bar test}
+    return $foo2::aliasTrace
+} -cleanup {
+    namespace delete foo2
+    interp delete $i
+} -result {{::foo2 {foo::bar test}}}
+test interp-27.5 {interp hidden & namespaces} -setup {
+    set i [interp create]
+} -constraints knownBug -body {
+    interp eval $i {
+	namespace eval foo {
+	    proc bar {args} {
+		return "bar called ([namespace current]) ($args)"
+	    }
+	}
+    }
+    set res [list [interp eval $i {namespace eval foo {bar test1}}]]
+    interp hide $i foo::bar
+    lappend res [list [catch {interp eval $i {namespace eval foo {bar test2}}} msg] $msg]
+} -cleanup {
+    interp delete $i
+} -result {{bar called (::foo) (test1)} {1 {invalid command name "bar"}}}
+test interp-27.6 {interp hidden & aliases & namespaces} -setup {
+    set i [interp create]
+} -constraints knownBug -body {
+    set v root-master
+    namespace eval foo {
+	variable v foo-master
+	proc bar {interp args} {
+	    variable v
+	    list "master bar called ($v) ([namespace current]) ($args)"\
+		[interp invokehidden $interp foo::bar $args]
+	}
+    }
+    interp eval $i {
+	namespace eval foo {
+	    namespace export *
+	    variable v foo-slave
+	    proc bar {args} {
+		variable v
+		return "slave bar called ($v) ([namespace current]) ($args)"
+	    }
+	}
+    }
+    set res [list [interp eval $i {namespace eval foo {bar test1}}]]
+    $i hide foo::bar
+    $i alias foo::bar foo::bar $i
+    set res [concat $res [interp eval $i {
+	set v root-slave
+	namespace eval test {
+	    variable v foo-test
+	    namespace import ::foo::*
+	    bar test2
+	}
+    }]]
+} -cleanup {
+    namespace delete foo
+    interp delete $i
+} -result {{slave bar called (foo-slave) (::foo) (test1)} {master bar called (foo-master) (::foo) (test2)} {slave bar called (foo-slave) (::foo) (test2)}}
+test interp-27.7 {interp hidden & aliases & imports & namespaces} -setup {
+    set i [interp create]
+} -constraints knownBug -body {
+    set v root-master
+    namespace eval mfoo {
+	variable v foo-master
+	proc bar {interp args} {
+	    variable v
+	    list "master bar called ($v) ([namespace current]) ($args)"\
+		[interp invokehidden $interp test::bar $args]
+	}
+    }
+    interp eval $i {
+	namespace eval foo {
+	    namespace export *
+	    variable v foo-slave
+	    proc bar {args} {
+		variable v
+		return "slave bar called ($v) ([info level 0]) ([uplevel namespace current]) ([namespace current]) ($args)"
+	    }
+	}
+	set v root-slave
+	namespace eval test {
+	    variable v foo-test
+	    namespace import ::foo::*
+	}
+    }
+    set res [list [interp eval $i {namespace eval test {bar test1}}]]
+    $i hide test::bar
+    $i alias test::bar mfoo::bar $i
+    set res [concat $res [interp eval $i {test::bar test2}]]
+} -cleanup {
+    namespace delete mfoo
+    interp delete $i
+} -result {{slave bar called (foo-slave) (bar test1) (::tcltest) (::foo) (test1)} {master bar called (foo-master) (::mfoo) (test2)} {slave bar called (foo-slave) (test::bar test2) (::) (::foo) (test2)}}
+test interp-27.8 {hiding, namespaces and integrity} knownBug {
+    namespace eval foo {
+	variable v 3
+	proc bar {} {variable v; set v}
+	# next command would currently generate an unknown command "bar" error.
+	interp hide {} bar
+    }
+    namespace delete foo
+    list [catch {interp invokehidden {} foo::bar} msg] $msg
+} {1 {invalid hidden command name "foo"}}
+
+test interp-28.1 {getting fooled by slave's namespace ?} -setup {
+    set i [interp create -safe]
+    proc master {interp args} {interp hide $interp list}
+} -body {
+    $i alias master master $i
+    set r [interp eval $i {
+        namespace eval foo {
+	    proc list {args} {
+		return "dummy foo::list"
+	    }
+	    master
+	}
+	info commands list
+    }]
+} -cleanup {
+    rename master {}
+    interp delete $i
+} -result {}
+test interp-28.2 {master's nsName cache should not cross} -setup {
+    set i [interp create]
+    $i eval {proc filter lst {lsearch -all -inline -not $lst "::tcl"}}
+} -body {
+    $i eval {
+	set x {namespace children ::}
+	set y [list namespace children ::]
+	namespace delete {*}[filter [{*}$y]]
+	set j [interp create]
+	$j alias filter filter
+	$j eval {namespace delete {*}[filter [namespace children ::]]}
+	namespace eval foo {}
+	list [filter [eval $x]] [filter [eval $y]] [filter [$j eval $x]] [filter [$j eval $y]]
+    }
+} -cleanup {
+    interp delete $i
+} -result {::foo ::foo {} {}}
+
+# Part 29: recursion limit
+#  29.1.*  Argument checking
+#  29.2.*  Reading and setting the recursion limit
+#  29.3.*  Does the recursion limit work?
+#  29.4.*  Recursion limit inheritance by sub-interpreters
+#  29.5.*  Confirming the recursionlimit command does not affect the parent
+#  29.6.*  Safe interpreter restriction
+
+test interp-29.1.1 {interp recursionlimit argument checking} {
+    list [catch {interp recursionlimit} msg] $msg
+} {1 {wrong # args: should be "interp recursionlimit path ?newlimit?"}}
+test interp-29.1.2 {interp recursionlimit argument checking} {
+    list [catch {interp recursionlimit foo bar} msg] $msg
+} {1 {could not find interpreter "foo"}}
+test interp-29.1.3 {interp recursionlimit argument checking} {
+    list [catch {interp recursionlimit foo bar baz} msg] $msg
+} {1 {wrong # args: should be "interp recursionlimit path ?newlimit?"}}
+test interp-29.1.4 {interp recursionlimit argument checking} {
+    interp create moo
+    set result [catch {interp recursionlimit moo bar} msg]
+    interp delete moo
+    list $result $msg
+} {1 {expected integer but got "bar"}}
+test interp-29.1.5 {interp recursionlimit argument checking} {
+    interp create moo
+    set result [catch {interp recursionlimit moo 0} msg]
+    interp delete moo
+    list $result $msg
+} {1 {recursion limit must be > 0}}
+test interp-29.1.6 {interp recursionlimit argument checking} {
+    interp create moo
+    set result [catch {interp recursionlimit moo -1} msg]
+    interp delete moo
+    list $result $msg
+} {1 {recursion limit must be > 0}}
+test interp-29.1.7 {interp recursionlimit argument checking} {
+    interp create moo
+    set result [catch {interp recursionlimit moo [expr {wide(1)<<32}]} msg]
+    interp delete moo
+    list $result [string range $msg 0 35]
+} {1 {integer value too large to represent}}
+test interp-29.1.8 {slave recursionlimit argument checking} {
+    interp create moo
+    set result [catch {moo recursionlimit foo bar} msg]
+    interp delete moo
+    list $result $msg
+} {1 {wrong # args: should be "moo recursionlimit ?newlimit?"}}
+test interp-29.1.9 {slave recursionlimit argument checking} {
+    interp create moo
+    set result [catch {moo recursionlimit foo} msg]
+    interp delete moo
+    list $result $msg
+} {1 {expected integer but got "foo"}}
+test interp-29.1.10 {slave recursionlimit argument checking} {
+    interp create moo
+    set result [catch {moo recursionlimit 0} msg]
+    interp delete moo
+    list $result $msg
+} {1 {recursion limit must be > 0}}
+test interp-29.1.11 {slave recursionlimit argument checking} {
+    interp create moo
+    set result [catch {moo recursionlimit -1} msg]
+    interp delete moo
+    list $result $msg
+} {1 {recursion limit must be > 0}}
+test interp-29.1.12 {slave recursionlimit argument checking} {
+    interp create moo
+    set result [catch {moo recursionlimit [expr {wide(1)<<32}]} msg]
+    interp delete moo
+    list $result [string range $msg 0 35]
+} {1 {integer value too large to represent}}
+test interp-29.2.1 {query recursion limit} {
+    interp recursionlimit {}
+} 1000
+test interp-29.2.2 {query recursion limit} {
+    set i [interp create]
+    set n [interp recursionlimit $i]
+    interp delete $i
+    set n
+} 1000
+test interp-29.2.3 {query recursion limit} {
+    set i [interp create]
+    set n [$i recursionlimit]
+    interp delete $i
+    set n
+} 1000
+test interp-29.2.4 {query recursion limit} {
+    set i [interp create]
+    set r [$i eval {
+	set n1 [interp recursionlimit {} 42]
+	set n2 [interp recursionlimit {}]
+	list $n1 $n2
+    }]
+    interp delete $i
+    set r
+} {42 42}
+test interp-29.2.5 {query recursion limit} {
+    set i [interp create]
+    set n1 [interp recursionlimit $i 42]
+    set n2 [interp recursionlimit $i]
+    interp delete $i
+    list $n1 $n2
+} {42 42}
+test interp-29.2.6 {query recursion limit} {
+    set i [interp create]
+    set n1 [interp recursionlimit $i 42]
+    set n2 [$i recursionlimit]
+    interp delete $i
+    list $n1 $n2
+} {42 42}
+test interp-29.2.7 {query recursion limit} {
+    set i [interp create]
+    set n1 [$i recursionlimit 42]
+    set n2 [interp recursionlimit $i]
+    interp delete $i
+    list $n1 $n2
+} {42 42}
+test interp-29.2.8 {query recursion limit} {
+    set i [interp create]
+    set n1 [$i recursionlimit 42]
+    set n2 [$i recursionlimit]
+    interp delete $i
+    list $n1 $n2
+} {42 42}
+test interp-29.3.1 {recursion limit} {
+    set i [interp create]
+    set r [interp eval $i {
+	interp recursionlimit {} 50
+	proc p {} {incr ::i; p}
+	set i 0
+	list [catch p msg] $msg $i
+    }]
+    interp delete $i
+    set r
+} {1 {too many nested evaluations (infinite loop?)} 49}
+test interp-29.3.2 {recursion limit} {
+    set i [interp create]
+    interp recursionlimit $i 50
+    set r [interp eval $i {
+	proc p {} {incr ::i; p}
+	set i 0
+	list [catch p msg] $msg $i
+    }]
+   interp delete $i
+   set r
+} {1 {too many nested evaluations (infinite loop?)} 49}
+test interp-29.3.3 {recursion limit} {
+    set i [interp create]
+    $i recursionlimit 50
+    set r [interp eval $i {
+	proc p {} {incr ::i; p}
+	set i 0
+	list [catch p msg] $msg $i
+    }]
+   interp delete $i
+   set r
+} {1 {too many nested evaluations (infinite loop?)} 49}
+test interp-29.3.4 {recursion limit error reporting} {
+    interp create slave
+    set r1 [slave eval {
+        catch { 		# nesting level 1
+	    eval {		# 2
+	        eval {		# 3
+		    eval {	# 4
+		        eval {	# 5
+			     interp recursionlimit {} 5
+			     set x ok
+			}
+		    }
+		}
+	    }
+	} msg
+    }]
+    set r2 [slave eval { set msg }]
+    interp delete slave
+    list $r1 $r2
+} {1 {falling back due to new recursion limit}}
+test interp-29.3.5 {recursion limit error reporting} {
+    interp create slave
+    set r1 [slave eval {
+        catch {			# nesting level 1
+	    eval {		# 2
+	        eval {		# 3
+		    eval {	# 4
+		        eval {	# 5
+			    interp recursionlimit {} 4
+			    set x ok
+			}
+		    }
+		}
+	    }
+	} msg
+    }]
+    set r2 [slave eval { set msg }]
+    interp delete slave
+    list $r1 $r2
+} {1 {falling back due to new recursion limit}}
+test interp-29.3.6 {recursion limit error reporting} {
+    interp create slave
+    set r1 [slave eval {
+        catch {			# nesting level 1
+	    eval {		# 2
+	        eval {		# 3
+		    eval {	# 4
+		        eval {	# 5
+			    interp recursionlimit {} 6
+			    set x ok
+			}
+		    }
+		}
+	    }
+	} msg
+    }]
+    set r2 [slave eval { set msg }]
+    interp delete slave
+    list $r1 $r2
+} {0 ok}
+#
+# Note that TEBC does not verify the interp's nesting level itself; the nesting
+# level will only be verified when it invokes a non-bcc'd command.
+#
+test interp-29.3.7a {recursion limit error reporting} {
+    interp create slave
+    after 0 {interp recursionlimit slave 5}
+    set r1 [slave eval {
+        catch { 		# nesting level 1
+	    eval {		# 2
+	        eval {		# 3
+		    eval {	# 4
+		        eval {	# 5
+			    update
+			    set x ok
+			}
+		    }
+		}
+	    }
+	} msg
+    }]
+    set r2 [slave eval { set msg }]
+    interp delete slave
+    list $r1 $r2
+} {0 ok}
+test interp-29.3.7b {recursion limit error reporting} {
+    interp create slave
+    after 0 {interp recursionlimit slave 5}
+    set r1 [slave eval {
+        catch { 		# nesting level 1
+	    eval {		# 2
+	        eval {		# 3
+		    eval {	# 4
+			update
+		        eval {	# 5
+			    set x ok
+			}
+		    }
+		}
+	    }
+	} msg
+    }]
+    set r2 [slave eval { set msg }]
+    interp delete slave
+    list $r1 $r2
+} {0 ok}
+test interp-29.3.7c {recursion limit error reporting} {
+    interp create slave
+    after 0 {interp recursionlimit slave 5}
+    set r1 [slave eval {
+        catch { 		# nesting level 1
+	    eval {		# 2
+	        eval {		# 3
+		    eval {	# 4
+		        eval {	# 5
+			    update
+			    set set set
+			    $set x ok
+			}
+		    }
+		}
+	    }
+	} msg
+    }]
+    set r2 [slave eval { set msg }]
+    interp delete slave
+    list $r1 $r2
+} {1 {too many nested evaluations (infinite loop?)}}
+test interp-29.3.8a {recursion limit error reporting} {
+    interp create slave
+    after 0 {interp recursionlimit slave 4}
+    set r1 [slave eval {
+        catch { 		# nesting level 1
+	    eval {		# 2
+	        eval {		# 3
+		    eval {	# 4
+		        eval {	# 5
+			    update
+			    set x ok
+			}
+		    }
+		}
+	    }
+	} msg
+    }]
+    set r2 [slave eval { set msg }]
+    interp delete slave
+    list $r1 $r2
+} {0 ok}
+test interp-29.3.8b {recursion limit error reporting} {
+    interp create slave
+    after 0 {interp recursionlimit slave 4}
+    set r1 [slave eval {
+        catch { 		# nesting level 1
+	    eval {		# 2
+	        eval {		# 3
+		    eval {	# 4
+			update
+		        eval {	# 5
+			    set x ok
+			}
+		    }
+		}
+	    }
+	} msg
+    }]
+    set r2 [slave eval { set msg }]
+    interp delete slave
+    list $r1 $r2
+} {1 {too many nested evaluations (infinite loop?)}}
+test interp-29.3.9a {recursion limit error reporting} {
+    interp create slave
+    after 0 {interp recursionlimit slave 6}
+    set r1 [slave eval {
+        catch { 		# nesting level 1
+	    eval {		# 2
+	        eval {		# 3
+		    eval {	# 4
+		        eval {	# 5
+			    update
+			    set x ok
+			}
+		    }
+		}
+	    }
+	} msg
+    }]
+    set r2 [slave eval { set msg }]
+    interp delete slave
+    list $r1 $r2
+} {0 ok}
+test interp-29.3.9b {recursion limit error reporting} {
+    interp create slave
+    after 0 {interp recursionlimit slave 6}
+    set r1 [slave eval {
+        catch { 		# nesting level 1
+	    eval {		# 2
+	        eval {		# 3
+		    eval {	# 4
+		        eval {	# 5
+			    set set set
+			    $set x ok
+			}
+		    }
+		}
+	    }
+	} msg
+    }]
+    set r2 [slave eval { set msg }]
+    interp delete slave
+    list $r1 $r2
+} {0 ok}
+test interp-29.3.10a {recursion limit error reporting} {
+    interp create slave
+    after 0 {slave recursionlimit 4}
+    set r1 [slave eval {
+        catch { 		# nesting level 1
+	    eval {		# 2
+	        eval {		# 3
+		    eval {	# 4
+		        eval {	# 5
+			     update
+			     set x ok
+			}
+		    }
+		}
+	    }
+	} msg
+    }]
+    set r2 [slave eval { set msg }]
+    interp delete slave
+    list $r1 $r2
+} {0 ok}
+test interp-29.3.10b {recursion limit error reporting} {
+    interp create slave
+    after 0 {slave recursionlimit 4}
+    set r1 [slave eval {
+        catch { 		# nesting level 1
+	    eval {		# 2
+	        eval {		# 3
+		    eval {	# 4
+			update
+		        eval {	# 5
+			    set x ok
+			}
+		    }
+		}
+	    }
+	} msg
+    }]
+    set r2 [slave eval { set msg }]
+    interp delete slave
+    list $r1 $r2
+} {1 {too many nested evaluations (infinite loop?)}}
+test interp-29.3.11a {recursion limit error reporting} {
+    interp create slave
+    after 0 {slave recursionlimit 5}
+    set r1 [slave eval {
+        catch { 		# nesting level 1
+	    eval {		# 2
+	        eval {		# 3
+		    eval {	# 4
+		        eval {	# 5
+			    update
+			    set x ok
+			}
+		    }
+		}
+	    }
+	} msg
+    }]
+    set r2 [slave eval { set msg }]
+    interp delete slave
+    list $r1 $r2
+} {0 ok}
+test interp-29.3.11b {recursion limit error reporting} {
+    interp create slave
+    after 0 {slave recursionlimit 5}
+    set r1 [slave eval {
+        catch { 		# nesting level 1
+	    eval {		# 2
+	        eval {		# 3
+		    eval {	# 4
+		        eval {	# 5
+			    update
+			    set set set
+			    $set x ok
+			}
+		    }
+		}
+	    }
+	} msg
+    }]
+    set r2 [slave eval { set msg }]
+    interp delete slave
+    list $r1 $r2
+} {1 {too many nested evaluations (infinite loop?)}}
+test interp-29.3.12a {recursion limit error reporting} {
+    interp create slave
+    after 0 {slave recursionlimit 6}
+    set r1 [slave eval {
+        catch { 		# nesting level 1
+	    eval {		# 2
+	        eval {		# 3
+		    eval {	# 4
+		        eval {	# 5
+			    update
+			    set x ok
+			}
+		    }
+		}
+	    }
+	} msg
+    }]
+    set r2 [slave eval { set msg }]
+    interp delete slave
+    list $r1 $r2
+} {0 ok}
+test interp-29.3.12b {recursion limit error reporting} {
+    interp create slave
+    after 0 {slave recursionlimit 6}
+    set r1 [slave eval {
+        catch { 		# nesting level 1
+	    eval {		# 2
+	        eval {		# 3
+		    eval {	# 4
+		        eval {	# 5
+			    update
+			    set set set
+			    $set x ok
+			}
+		    }
+		}
+	    }
+	} msg
+    }]
+    set r2 [slave eval { set msg }]
+    interp delete slave
+    list $r1 $r2
+} {0 ok}
+test interp-29.4.1 {recursion limit inheritance} {
+    set i [interp create]
+    set ii [interp eval $i {
+	interp recursionlimit {} 50
+	interp create
+    }]
+    set r [interp eval [list $i $ii] {
+	proc p {} {incr ::i; p}
+	set i 0
+	catch p
+	set i
+    }]
+   interp delete $i
+   set r
+} 50
+test interp-29.4.2 {recursion limit inheritance} {
+    set i [interp create]
+    $i recursionlimit 50
+    set ii [interp eval $i {interp create}]
+    set r [interp eval [list $i $ii] {
+	proc p {} {incr ::i; p}
+	set i 0
+	catch p
+	set i
+    }]
+   interp delete $i
+   set r
+} 50
+test interp-29.5.1 {does slave recursion limit affect master?} {
+    set before [interp recursionlimit {}]
+    set i [interp create]
+    interp recursionlimit $i 20000
+    set after [interp recursionlimit {}]
+    set slavelimit [interp recursionlimit $i]
+    interp delete $i
+    list [expr {$before == $after}] $slavelimit
+} {1 20000}
+test interp-29.5.2 {does slave recursion limit affect master?} {
+    set before [interp recursionlimit {}]
+    set i [interp create]
+    interp recursionlimit $i 20000
+    set after [interp recursionlimit {}]
+    set slavelimit [$i recursionlimit]
+    interp delete $i
+    list [expr {$before == $after}] $slavelimit
+} {1 20000}
+test interp-29.5.3 {does slave recursion limit affect master?} {
+    set before [interp recursionlimit {}]
+    set i [interp create]
+    $i recursionlimit 20000
+    set after [interp recursionlimit {}]
+    set slavelimit [interp recursionlimit $i]
+    interp delete $i
+    list [expr {$before == $after}] $slavelimit
+} {1 20000}
+test interp-29.5.4 {does slave recursion limit affect master?} {
+    set before [interp recursionlimit {}]
+    set i [interp create]
+    $i recursionlimit 20000
+    set after [interp recursionlimit {}]
+    set slavelimit [$i recursionlimit]
+    interp delete $i
+    list [expr {$before == $after}] $slavelimit
+} {1 20000}
+test interp-29.6.1 {safe interpreter recursion limit} {
+    interp create slave -safe
+    set n [interp recursionlimit slave]
+    interp delete slave
+    set n
+} 1000
+test interp-29.6.2 {safe interpreter recursion limit} {
+    interp create slave -safe
+    set n [slave recursionlimit]
+    interp delete slave
+    set n
+} 1000
+test interp-29.6.3 {safe interpreter recursion limit} {
+    interp create slave -safe
+    set n1 [interp recursionlimit slave 42]
+    set n2 [interp recursionlimit slave]
+    interp delete slave
+    list $n1 $n2
+} {42 42}
+test interp-29.6.4 {safe interpreter recursion limit} {
+    interp create slave -safe
+    set n1 [slave recursionlimit 42]
+    set n2 [interp recursionlimit slave]
+    interp delete slave
+    list $n1 $n2
+} {42 42}
+test interp-29.6.5 {safe interpreter recursion limit} {
+    interp create slave -safe
+    set n1 [interp recursionlimit slave 42]
+    set n2 [slave recursionlimit]
+    interp delete slave
+    list $n1 $n2
+} {42 42}
+test interp-29.6.6 {safe interpreter recursion limit} {
+    interp create slave -safe
+    set n1 [slave recursionlimit 42]
+    set n2 [slave recursionlimit]
+    interp delete slave
+    list $n1 $n2
+} {42 42}
+test interp-29.6.7 {safe interpreter recursion limit} {
+    interp create slave -safe
+    set n1 [slave recursionlimit 42]
+    set n2 [slave recursionlimit]
+    interp delete slave
+    list $n1 $n2
+} {42 42}
+test interp-29.6.8 {safe interpreter recursion limit} {
+    interp create slave -safe
+    set n [catch {slave eval {interp recursionlimit {} 42}} msg]
+    interp delete slave
+    list $n $msg
+} {1 {permission denied: safe interpreters cannot change recursion limit}}
+test interp-29.6.9 {safe interpreter recursion limit} {
+    interp create slave -safe
+    set result [
+	slave eval {
+	    interp create slave2 -safe
+	    set n [catch {
+	        interp recursionlimit slave2 42
+            } msg]
+            list $n $msg
+        }
+    ]
+    interp delete slave
+    set result
+} {1 {permission denied: safe interpreters cannot change recursion limit}}
+test interp-29.6.10 {safe interpreter recursion limit} {
+    interp create slave -safe
+    set result [
+        slave eval {
+	    interp create slave2 -safe
+	    set n [catch {
+	        slave2 recursionlimit 42
+            } msg]
+            list $n $msg
+        }
+    ]
+    interp delete slave
+    set result
+} {1 {permission denied: safe interpreters cannot change recursion limit}}
+
+
+#    # Deep recursion (into interps when the regular one fails):
+#    # still crashes...
+#    proc p {} {
+#	if {[catch p ret]} {
+#	    catch {
+#		set i [interp create]
+#		interp eval $i [list proc p {} [info body p]]
+#		interp eval $i p
+#	    }
+#	    interp delete $i
+#	    return ok
+#	}
+#	return $ret
+#    }
+#    p
+
+# more tests needed...
+
+# Interp & stack
+#test interp-29.1 {interp and stack (info level)} {
+#} {}
+
+# End of stack-recursion tests
+
+# This test dumps core in Tcl 8.0.3!
+test interp-30.1 {deletion of aliases inside namespaces} {
+    set i [interp create]
+    $i alias ns::cmd list
+    $i alias ns::cmd {}
+} {}
+
+test interp-31.1 {alias invocation scope} {
+    proc mySet {varName value} {
+	upvar 1 $varName localVar
+	set localVar $value
+    }
+    interp alias {} myNewSet {} mySet
+    proc testMyNewSet {value} {
+	myNewSet a $value
+	return $a
+    }
+    unset -nocomplain a
+    set result [testMyNewSet "ok"]
+    rename testMyNewSet {}
+    rename mySet {}
+    rename myNewSet {}
+    set result
+} ok
+
+test interp-32.1 {parent's working directory should be inherited by a child interp} -setup {
+    cd [temporaryDirectory]
+} -body {
+    set parent [pwd]
+    set i [interp create]
+    set child [$i eval pwd]
+    interp delete $i
+    file mkdir cwd_test
+    cd cwd_test
+    lappend parent [pwd]
+    set i [interp create]
+    lappend child [$i eval pwd]
+    cd ..
+    file delete cwd_test
+    interp delete $i
+    expr {[string equal $parent $child] ? 1 :
+             "\{$parent\} != \{$child\}"}
+} -cleanup {
+    cd [workingDirectory]
+} -result 1
+
+test interp-33.1 {refCounting for target words of alias [Bug 730244]} {
+    # This test will panic if Bug 730244 is not fixed.
+    set i [interp create]
+    proc testHelper args {rename testHelper {}; return $args}
+    # Note: interp names are simple words by default
+    trace add execution testHelper enter "interp alias $i alias {} ;#"
+    interp alias $i alias {} testHelper this
+    $i eval alias
+} this
+
+test interp-34.1 {basic test of limits - calling commands} -body {
+    set i [interp create]
+    $i eval {
+	proc foobar {} {
+	    for {set x 0} {$x<1000000} {incr x} {
+		# Calls to this are not bytecoded away
+		pid
+	    }
+	}
+    }
+    $i limit command -value 1000
+    $i eval foobar
+} -returnCodes error -result {command count limit exceeded} -cleanup {
+    interp delete $i
+}
+test interp-34.2 {basic test of limits - bytecoded commands} -body {
+    set i [interp create]
+    $i eval {
+	proc foobar {} {
+	    for {set x 0} {$x<1000000} {incr x} {
+		# Calls to this *are* bytecoded away
+		expr {1+2+3}
+	    }
+	}
+    }
+    $i limit command -value 1000
+    $i eval foobar
+} -returnCodes error -result {command count limit exceeded} -cleanup {
+    interp delete $i
+}
+test interp-34.3 {basic test of limits - pure bytecode loop} -body {
+    set i [interp create]
+    $i eval {
+	proc foobar {} {
+	    while {1} {
+		# No bytecode at all here...
+	    }
+	}
+    }
+    # We use a time limit here; command limits don't trap this case
+    $i limit time -seconds [expr {[clock seconds]+2}]
+    $i eval foobar
+} -returnCodes error -result {time limit exceeded} -cleanup {
+    interp delete $i
+}
+test interp-34.3.1 {basic test of limits - pure inside-command loop} -body {
+    set i [interp create]
+    $i eval {
+	proc foobar {} {
+	    set while while
+	    $while {1} {
+		# No bytecode at all here...
+	    }
+	}
+    }
+    # We use a time limit here; command limits don't trap this case
+    $i limit time -seconds [expr {[clock seconds]+2}]
+    $i eval foobar
+} -returnCodes error -result {time limit exceeded} -cleanup {
+    interp delete $i
+}
+test interp-34.4 {limits with callbacks: extending limits} -setup {
+    set i [interp create]
+    set a 0
+    set b 0
+    set c a
+    proc cb1 {} {
+	global c
+	incr ::$c
+    }
+    proc cb2 {newlimit args} {
+	global c i
+	set c b
+	$i limit command -value $newlimit
+    }
+} -body {
+    interp alias $i foo {} cb1
+    set curlim [$i eval info cmdcount]
+    $i limit command -command "cb2 [expr $curlim+100]" \
+	    -value [expr {$curlim+10}]
+    $i eval {for {set i 0} {$i<10} {incr i} {foo}}
+    list $a $b $c
+} -result {6 4 b} -cleanup {
+    interp delete $i
+    rename cb1 {}
+    rename cb2 {}
+}
+# The next three tests exercise all the three ways that limit handlers
+# can be deleted.  Fully verifying this requires additional source
+# code instrumentation.
+test interp-34.5 {limits with callbacks: removing limits} -setup {
+    set i [interp create]
+    set a 0
+    set b 0
+    set c a
+    proc cb1 {} {
+	global c
+	incr ::$c
+    }
+    proc cb2 {newlimit args} {
+	global c i
+	set c b
+	$i limit command -value $newlimit
+    }
+} -body {
+    interp alias $i foo {} cb1
+    set curlim [$i eval info cmdcount]
+    $i limit command -command "cb2 {}" -value [expr {$curlim+10}]
+    $i eval {for {set i 0} {$i<10} {incr i} {foo}}
+    list $a $b $c
+} -result {6 4 b} -cleanup {
+    interp delete $i
+    rename cb1 {}
+    rename cb2 {}
+}
+test interp-34.6 {limits with callbacks: removing limits and handlers} -setup {
+    set i [interp create]
+    set a 0
+    set b 0
+    set c a
+    proc cb1 {} {
+	global c
+	incr ::$c
+    }
+    proc cb2 {args} {
+	global c i
+	set c b
+	$i limit command -value {} -command {}
+    }
+} -body {
+    interp alias $i foo {} cb1
+    set curlim [$i eval info cmdcount]
+    $i limit command -command cb2 -value [expr {$curlim+10}]
+    $i eval {for {set i 0} {$i<10} {incr i} {foo}}
+    list $a $b $c
+} -result {6 4 b} -cleanup {
+    interp delete $i
+    rename cb1 {}
+    rename cb2 {}
+}
+test interp-34.7 {limits with callbacks: deleting the handler interp} -setup {
+    set i [interp create]
+    $i eval {
+	set i [interp create]
+	proc cb1 {} {
+	    global c
+	    incr ::$c
+	}
+	proc cb2 {args} {
+	    global c i curlim
+	    set c b
+	    $i limit command -value [expr {$curlim+1000}]
+	    trapToParent
+	}
+    }
+    proc cb3 {} {
+	global i subi
+	interp alias [list $i $subi] foo {} cb4
+	interp delete $i
+    }
+    proc cb4 {} {
+	global n
+	incr n
+    }
+} -body {
+    set subi [$i eval set i]
+    interp alias $i trapToParent {} cb3
+    set n 0
+    $i eval {
+	set a 0
+	set b 0
+	set c a
+	interp alias $i foo {} cb1
+	set curlim [$i eval info cmdcount]
+	$i limit command -command cb2 -value [expr {$curlim+10}]
+    }
+    $i eval {
+	$i eval {
+	    for {set i 0} {$i<10} {incr i} {foo}
+	}
+    }
+    list $n [interp exists $i]
+} -result {4 0} -cleanup {
+    rename cb3 {}
+    rename cb4 {}
+}
+# Bug 1085023
+test interp-34.8 {time limits trigger in vwaits} -body {
+    set i [interp create]
+    interp limit $i time -seconds [expr {[clock seconds]+1}] -granularity 1
+    $i eval {
+	set x {}
+	vwait x
+    }
+} -cleanup {
+    interp delete $i
+} -returnCodes error -result {limit exceeded}
+test interp-34.9 {time limits trigger in blocking after} {
+    set i [interp create]
+    set t0 [clock seconds]
+    interp limit $i time -seconds [expr {$t0 + 1}] -granularity 1
+    set code [catch {
+	$i eval {after 10000}
+    } msg]
+    set t1 [clock seconds]
+    interp delete $i
+    list $code $msg [expr {($t1-$t0) < 3 ? "OK" : $t1-$t0}] 
+} {1 {time limit exceeded} OK}
+test interp-34.10 {time limits trigger in vwaits: Bug 1221395} -body {
+    set i [interp create]
+    # Assume someone hasn't set the clock to early 1970!
+    $i limit time -seconds 1 -granularity 4
+    interp alias $i log {} lappend result
+    set result {}
+    catch {
+	$i eval {
+	    log 1
+	    after 100
+	    log 2
+	}
+    } msg
+    interp delete $i
+    lappend result $msg
+} -result {1 {time limit exceeded}}
+test interp-34.11 {time limit extension in callbacks} -setup {
+    proc cb1 {i t} {
+	global result
+	lappend result cb1
+	$i limit time -seconds $t -command cb2
+    }
+    proc cb2 {} {
+	global result
+	lappend result cb2
+    }
+} -body {
+    set i [interp create]
+    set t0 [clock seconds]
+    $i limit time -seconds [expr {$t0+1}] -granularity 1 \
+	-command "cb1 $i [expr {$t0+2}]"
+    set ::result {}
+    lappend ::result [catch {
+	$i eval {
+	    for {set i 0} {$i<30} {incr i} {
+		after 100
+	    }
+	}
+    } msg] $msg
+    set t1 [clock seconds]
+    lappend ::result [expr {$t1-$t0>=2 ? "ok" : "$t0,$t1"}]
+    interp delete $i
+    return $::result
+} -result {cb1 cb2 1 {time limit exceeded} ok} -cleanup {
+    rename cb1 {}
+    rename cb2 {}
+}
+test interp-34.12 {time limit extension in callbacks} -setup {
+    proc cb1 {i} {
+	global result times
+	lappend result cb1
+	set times [lassign $times t]
+	$i limit time -seconds $t
+    }
+} -body {
+    set i [interp create]
+    set t0 [clock seconds]
+    set ::times "[expr {$t0+2}] [expr {$t0+100}]"
+    $i limit time -seconds [expr {$t0+1}] -granularity 1 -command "cb1 $i"
+    set ::result {}
+    lappend ::result [catch {
+	$i eval {
+	    for {set i 0} {$i<30} {incr i} {
+		after 100
+	    }
+	}
+    } msg] $msg
+    set t1 [clock seconds]
+    lappend ::result [expr {$t1-$t0>=2 ? "ok" : "$t0,$t1"}]
+    interp delete $i
+    return $::result
+} -result {cb1 cb1 0 {} ok} -cleanup {
+    rename cb1 {}
+}
+test interp-34.13 {time limit granularity and vwait: Bug 2891362} -setup {
+    set i [interp create -safe]
+} -body {
+    $i limit time -seconds [clock add [clock seconds] 1 second]
+    $i eval {
+	after 2000 set x timeout
+	vwait x
+	return $x
+    }
+} -cleanup {
+    interp delete $i
+} -returnCodes error -result {limit exceeded}
+
+test interp-35.1 {interp limit syntax} -body {
+    interp limit
+} -returnCodes error -result {wrong # args: should be "interp limit path limitType ?-option value ...?"}
+test interp-35.2 {interp limit syntax} -body {
+    interp limit {}
+} -returnCodes error -result {wrong # args: should be "interp limit path limitType ?-option value ...?"}
+test interp-35.3 {interp limit syntax} -body {
+    interp limit {} foo
+} -returnCodes error -result {bad limit type "foo": must be commands or time}
+test interp-35.4 {interp limit syntax} -body {
+    set i [interp create]
+    set dict [interp limit $i commands]
+    set result {}
+    foreach key [lsort [dict keys $dict]] {
+	lappend result $key [dict get $dict $key]
+    }
+    set result
+} -cleanup {
+    interp delete $i
+} -result {-command {} -granularity 1 -value {}}
+test interp-35.5 {interp limit syntax} -body {
+    set i [interp create]
+    interp limit $i commands -granularity
+} -cleanup {
+    interp delete $i
+} -result 1
+test interp-35.6 {interp limit syntax} -body {
+    set i [interp create]
+    interp limit $i commands -granularity 2
+} -cleanup {
+    interp delete $i
+} -result {}
+test interp-35.7 {interp limit syntax} -body {
+    set i [interp create]
+    interp limit $i commands -foobar
+} -cleanup {
+    interp delete $i
+} -returnCodes error -result {bad option "-foobar": must be -command, -granularity, or -value}
+test interp-35.8 {interp limit syntax} -body {
+    set i [interp create]
+    interp limit $i commands -granularity foobar
+} -cleanup {
+    interp delete $i
+} -returnCodes error -result {expected integer but got "foobar"}
+test interp-35.9 {interp limit syntax} -body {
+    set i [interp create]
+    interp limit $i commands -granularity 0
+} -cleanup {
+    interp delete $i
+} -returnCodes error -result {granularity must be at least 1}
+test interp-35.10 {interp limit syntax} -body {
+    set i [interp create]
+    interp limit $i commands -value foobar
+} -cleanup {
+    interp delete $i
+} -returnCodes error -result {expected integer but got "foobar"}
+test interp-35.11 {interp limit syntax} -body {
+    set i [interp create]
+    interp limit $i commands -value -1
+} -cleanup {
+    interp delete $i
+} -returnCodes error -result {command limit value must be at least 0}
+test interp-35.12 {interp limit syntax} -body {
+    set i [interp create]
+    set dict [interp limit $i time]
+    set result {}
+    foreach key [lsort [dict keys $dict]] {
+	lappend result $key [dict get $dict $key]
+    }
+    set result
+} -cleanup {
+    interp delete $i
+} -result {-command {} -granularity 10 -milliseconds {} -seconds {}}
+test interp-35.13 {interp limit syntax} -body {
+    set i [interp create]
+    interp limit $i time -granularity
+} -cleanup {
+    interp delete $i
+} -result 10
+test interp-35.14 {interp limit syntax} -body {
+    set i [interp create]
+    interp limit $i time -granularity 2
+} -cleanup {
+    interp delete $i
+} -result {}
+test interp-35.15 {interp limit syntax} -body {
+    set i [interp create]
+    interp limit $i time -foobar
+} -cleanup {
+    interp delete $i
+} -returnCodes error -result {bad option "-foobar": must be -command, -granularity, -milliseconds, or -seconds}
+test interp-35.16 {interp limit syntax} -body {
+    set i [interp create]
+    interp limit $i time -granularity foobar
+} -cleanup {
+    interp delete $i
+} -returnCodes error -result {expected integer but got "foobar"}
+test interp-35.17 {interp limit syntax} -body {
+    set i [interp create]
+    interp limit $i time -granularity 0
+} -cleanup {
+    interp delete $i
+} -returnCodes error -result {granularity must be at least 1}
+test interp-35.18 {interp limit syntax} -body {
+    set i [interp create]
+    interp limit $i time -seconds foobar
+} -cleanup {
+    interp delete $i
+} -returnCodes error -result {expected integer but got "foobar"}
+test interp-35.19 {interp limit syntax} -body {
+    set i [interp create]
+    interp limit $i time -seconds -1
+} -cleanup {
+    interp delete $i
+} -returnCodes error -result {seconds must be at least 0}
+test interp-35.20 {interp limit syntax} -body {
+    set i [interp create]
+    interp limit $i time -millis foobar
+} -cleanup {
+    interp delete $i
+} -returnCodes error -result {expected integer but got "foobar"}
+test interp-35.21 {interp limit syntax} -body {
+    set i [interp create]
+    interp limit $i time -millis -1
+} -cleanup {
+    interp delete $i
+} -returnCodes error -result {milliseconds must be at least 0}
+test interp-35.22 {interp time limits normalize milliseconds} -body {
+    set i [interp create]
+    interp limit $i time -seconds 1 -millis 1500
+    list [$i limit time -seconds] [$i limit time -millis]
+} -cleanup {
+    interp delete $i
+} -result {2 500}
+# Bug 3398794
+test interp-35.23 {interp command limits can't touch current interp} -body {
+    interp limit {} commands -value 10
+} -returnCodes error -result {limits on current interpreter inaccessible}
+test interp-35.24 {interp time limits can't touch current interp} -body {
+    interp limit {} time -seconds 2
+} -returnCodes error -result {limits on current interpreter inaccessible}
+
+test interp-36.1 {interp bgerror syntax} -body {
+    interp bgerror
+} -returnCodes error -result {wrong # args: should be "interp bgerror path ?cmdPrefix?"}
+test interp-36.2 {interp bgerror syntax} -body { 
+    interp bgerror x y z
+} -returnCodes error -result {wrong # args: should be "interp bgerror path ?cmdPrefix?"}
+test interp-36.3 {interp bgerror syntax} -setup {
+    interp create slave
+} -body {
+    slave bgerror x y
+} -cleanup {
+    interp delete slave
+} -returnCodes error -result {wrong # args: should be "slave bgerror ?cmdPrefix?"}
+test interp-36.4 {SlaveBgerror syntax} -setup {
+    interp create slave
+} -body {
+    slave bgerror \{
+} -cleanup {
+    interp delete slave
+} -returnCodes error -result {cmdPrefix must be list of length >= 1}
+test interp-36.5 {SlaveBgerror syntax} -setup {
+    interp create slave
+} -body {
+    slave bgerror {}
+} -cleanup {
+    interp delete slave
+} -returnCodes error -result {cmdPrefix must be list of length >= 1}
+test interp-36.6 {SlaveBgerror returns handler} -setup {
+    interp create slave
+} -body {
+    slave bgerror {foo bar soom}
+} -cleanup {
+    interp delete slave
+} -result {foo bar soom}
+test interp-36.7 {SlaveBgerror sets error handler of slave [1999035]} -setup {
+    interp create slave
+    slave alias handler handler
+    slave bgerror handler
+    variable result {untouched}
+    proc handler {args} {
+        variable result
+        set result [lindex $args 0]
+    }
+} -body {
+    slave eval {
+        variable done {}
+        after 0 error foo
+        after 10 [list ::set [namespace which -variable done] {}]
+        vwait [namespace which -variable done]
+    }
+    set result
+} -cleanup {
+    variable result {}
+    unset -nocomplain result
+    interp delete slave
+} -result foo
+
+test interp-37.1 {safe interps and min() and max(): Bug 2895741} -setup {
+    catch {interp delete a}
+    interp create a
+    set result {}
+} -body {
+    interp create {a b} -safe
+    lappend result [interp eval a {expr min(5,2,3)*max(7,13,11)}]
+    lappend result [interp eval {a b} {expr min(5,2,3)*max(7,13,11)}]
+} -cleanup {
+    unset -nocomplain result
+    interp delete a
+} -result {26 26}
+
+test interp-38.1 {interp debug one-way switch} -setup {
+    catch {interp delete a}
+    interp create a
+    interp debug a -frame 1
+} -body {
+    # TIP #3xx interp debug frame is a one-way switch
+    interp debug a -frame 0
+} -cleanup {
+    interp delete a
+} -result {1}
+test interp-38.2 {interp debug env var} -setup {
+    catch {interp delete a}
+    set ::env(TCL_INTERP_DEBUG_FRAME) 1
+    interp create a
+} -body {
+    interp debug a
+} -cleanup {
+    unset -nocomplain ::env(TCL_INTERP_DEBUG_FRAME)
+    interp delete a
+} -result {-frame 1}
+test interp-38.3 {interp debug wrong args} -body {
+    interp debug
+} -returnCodes {
+    error
+} -result {wrong # args: should be "interp debug path ?-frame ?bool??"}
+test interp-38.4 {interp debug basic setup} -constraints {!singleTestInterp} -body {
+    interp debug {}
+} -result {-frame 0}
+test interp-38.5 {interp debug basic setup} -constraints {!singleTestInterp} -body {
+    interp debug {} -f
+} -result {0}
+test interp-38.6 {interp debug basic setup} -body {
+    interp debug -frames
+} -returnCodes error -result {could not find interpreter "-frames"}
+test interp-38.7 {interp debug basic setup} -body {
+    interp debug {} -frames
+} -returnCodes error -result {bad debug option "-frames": must be -frame}
+test interp-38.8 {interp debug basic setup} -body {
+    interp debug {} -frame 0 bogus
+} -returnCodes {
+    error
+} -result {wrong # args: should be "interp debug path ?-frame ?bool??"}
+
+# cleanup
+unset -nocomplain hidden_cmds
+foreach i [interp slaves] {
+    interp delete $i
+}
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# fill-column: 78
+# End:
diff --git a/tests/io.test b/tests/io.test
new file mode 100644
index 0000000..e2a05dc
--- /dev/null
+++ b/tests/io.test
@@ -0,0 +1,8670 @@
+# -*- tcl -*-
+# Functionality covered: operation of all IO commands, and all procedures
+# defined in generic/tclIO.c.
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands.  Sourcing this file into Tcl runs the tests and
+# generates output for errors.  No output means no errors were found.
+#
+# Copyright (c) 1991-1994 The Regents of the University of California.
+# Copyright (c) 1994-1997 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+    package require tcltest 2
+    namespace import -force ::tcltest::*
+}
+
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
+
+testConstraint testbytestring [llength [info commands testbytestring]]
+
+namespace eval ::tcl::test::io {
+    namespace import ::tcltest::*
+
+    variable umaskValue
+    variable path
+    variable f
+    variable i
+    variable n
+    variable v
+    variable msg
+    variable expected
+
+testConstraint testchannel      [llength [info commands testchannel]]
+testConstraint exec             [llength [info commands exec]]
+testConstraint openpipe         1
+testConstraint fileevent        [llength [info commands fileevent]]
+testConstraint fcopy            [llength [info commands fcopy]]
+testConstraint testfevent       [llength [info commands testfevent]]
+testConstraint testchannelevent [llength [info commands testchannelevent]]
+testConstraint testmainthread   [llength [info commands testmainthread]]
+testConstraint thread [expr {0 == [catch {package require Thread 2.7-}]}]
+testConstraint testobj		[llength [info commands testobj]]
+
+# You need a *very* special environment to do some tests.  In
+# particular, many file systems do not support large-files...
+testConstraint largefileSupport [expr {$::tcl_platform(os) ne "Darwin"}]
+
+# some tests can only be run is umask is 2
+# if "umask" cannot be run, the tests will be skipped.
+set umaskValue 0
+testConstraint umask [expr {![catch {set umaskValue [scan [exec /bin/sh -c umask] %o]}]}]
+
+testConstraint makeFileInHome [expr {![file exists ~/_test_] && [file writable ~]}]
+
+# set up a long data file for some of the following tests
+
+set path(longfile) [makeFile {} longfile]
+set f [open $path(longfile) w]
+fconfigure $f -eofchar {} -translation lf
+for { set i 0 } { $i < 100 } { incr i} {
+    puts $f "#123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef
+\#123456789abcdef01
+\#"
+    }
+close $f
+
+set path(cat) [makeFile {
+    set f stdin
+    if {$argv != ""} {
+	set f [open [lindex $argv 0]]
+    }
+    fconfigure $f -encoding binary -translation lf -blocking 0 -eofchar \x1a
+    fconfigure stdout -encoding binary -translation lf -buffering none
+    fileevent $f readable "foo $f"
+    proc foo {f} {
+	set x [read $f]
+	catch {puts -nonewline $x}
+	if {[eof $f]} {
+	    close $f
+	    exit 0
+	}
+    }
+    vwait forever
+} cat]
+
+set thisScript [file join [pwd] [info script]]
+
+proc contents {file} {
+    set f [open $file]
+    fconfigure $f -translation binary
+    set a [read $f]
+    close $f
+    return $a
+}
+
+test io-1.5 {Tcl_WriteChars: CheckChannelErrors} {emptyTest} {
+    # no test, need to cause an async error.
+} {}
+set path(test1) [makeFile {} test1]
+test io-1.6 {Tcl_WriteChars: WriteBytes} {
+    set f [open $path(test1) w]
+    fconfigure $f -encoding binary
+    puts -nonewline $f "a\u4e4d\0"
+    close $f
+    contents $path(test1)
+} "a\x4d\x00"
+test io-1.7 {Tcl_WriteChars: WriteChars} {
+    set f [open $path(test1) w]
+    fconfigure $f -encoding shiftjis
+    puts -nonewline $f "a\u4e4d\0"
+    close $f
+    contents $path(test1)
+} "a\x93\xe1\x00"
+set path(test2) [makeFile {} test2]
+test io-1.8 {Tcl_WriteChars: WriteChars} {
+    # This test written for SF bug #506297.
+    #
+    # Executing this test without the fix for the referenced bug
+    # applied to tcl will cause tcl, more specifically WriteChars, to
+    # go into an infinite loop.
+
+    set f [open $path(test2) w] 
+    fconfigure      $f -encoding iso2022-jp 
+    puts -nonewline $f [format %s%c [string repeat " " 4] 12399] 
+    close           $f 
+    contents $path(test2)
+} "    \x1b\$B\$O\x1b(B"
+
+test io-1.9 {Tcl_WriteChars: WriteChars} {
+    # When closing a channel with an encoding that appends
+    # escape bytes, check for the case where the escape
+    # bytes overflow the current IO buffer. The bytes
+    # should be moved into a new buffer.
+
+    set data "1234567890 [format %c 12399]"
+
+    set sizes [list]
+
+    # With default buffer size
+    set f [open $path(test2) w]
+    fconfigure      $f -encoding iso2022-jp
+    puts -nonewline $f $data
+    close           $f
+    lappend sizes [file size $path(test2)]
+
+    # With buffer size equal to the length
+    # of the data, the escape bytes would
+    # go into the next buffer.
+
+    set f [open $path(test2) w]
+    fconfigure      $f -encoding iso2022-jp -buffersize 16
+    puts -nonewline $f $data
+    close           $f
+    lappend sizes [file size $path(test2)]
+
+    # With buffer size that is large enough
+    # to hold 1 byte of escaped data, but
+    # not all 3. This should not write
+    # the escape bytes to the first buffer
+    # and then again to the second buffer.
+
+    set f [open $path(test2) w]
+    fconfigure      $f -encoding iso2022-jp -buffersize 17
+    puts -nonewline $f $data
+    close           $f
+    lappend sizes [file size $path(test2)]
+
+    # With buffer size that can hold 2 out of
+    # 3 bytes of escaped data.
+
+    set f [open $path(test2) w]
+    fconfigure      $f -encoding iso2022-jp -buffersize 18
+    puts -nonewline $f $data
+    close           $f
+    lappend sizes [file size $path(test2)]
+
+    # With buffer size that can hold all the
+    # data and escape bytes.
+
+    set f [open $path(test2) w]
+    fconfigure      $f -encoding iso2022-jp -buffersize 19
+    puts -nonewline $f $data
+    close           $f
+    lappend sizes [file size $path(test2)]
+
+    set sizes
+} {19 19 19 19 19}
+
+test io-2.1 {WriteBytes} {
+    # loop until all bytes are written
+    
+    set f [open $path(test1) w]
+    fconfigure $f  -encoding binary -buffersize 16 -translation crlf
+    puts $f "abcdefghijklmnopqrstuvwxyz"
+    close $f
+    contents $path(test1)
+} "abcdefghijklmnopqrstuvwxyz\r\n"
+test io-2.2 {WriteBytes: savedLF > 0} {
+    # After flushing buffer, there was a \n left over from the last
+    # \n -> \r\n expansion.  It gets stuck at beginning of this buffer.
+
+    set f [open $path(test1) w]
+    fconfigure $f -encoding binary -buffersize 16 -translation crlf
+    puts -nonewline $f "123456789012345\n12"
+    set x [list [contents $path(test1)]]
+    close $f
+    lappend x [contents $path(test1)]
+} [list "123456789012345\r" "123456789012345\r\n12"]
+test io-2.3 {WriteBytes: flush on line} {
+    # Tcl "line" buffering has weird behavior: if current buffer contains
+    # a \n, entire buffer gets flushed.  Logical behavior would be to flush
+    # only up to the \n.
+    
+    set f [open $path(test1) w]
+    fconfigure $f -encoding binary -buffering line -translation crlf
+    puts -nonewline $f "\n12"
+    set x [contents $path(test1)]
+    close $f
+    set x
+} "\r\n12"
+test io-2.4 {WriteBytes: reset sawLF after each buffer} {
+    set f [open $path(test1) w]
+     fconfigure $f -encoding binary -buffering line -translation lf \
+	     -buffersize 16
+    puts -nonewline $f "abcdefg\nhijklmnopqrstuvwxyz"
+    set x [list [contents $path(test1)]]
+    close $f
+    lappend x [contents $path(test1)]
+} [list "abcdefg\nhijklmno" "abcdefg\nhijklmnopqrstuvwxyz"]
+
+test io-3.1 {WriteChars: compatibility with WriteBytes} {
+    # loop until all bytes are written
+    
+    set f [open $path(test1) w]
+    fconfigure $f -encoding ascii -buffersize 16 -translation crlf
+    puts $f "abcdefghijklmnopqrstuvwxyz"
+    close $f
+    contents $path(test1)
+} "abcdefghijklmnopqrstuvwxyz\r\n"
+test io-3.2 {WriteChars: compatibility with WriteBytes: savedLF > 0} {
+    # After flushing buffer, there was a \n left over from the last
+    # \n -> \r\n expansion.  It gets stuck at beginning of this buffer.
+
+    set f [open $path(test1) w]
+    fconfigure $f -encoding ascii -buffersize 16 -translation crlf
+    puts -nonewline $f "123456789012345\n12"
+    set x [list [contents $path(test1)]]
+    close $f
+    lappend x [contents $path(test1)]
+} [list "123456789012345\r" "123456789012345\r\n12"]
+test io-3.3 {WriteChars: compatibility with WriteBytes: flush on line} {
+    # Tcl "line" buffering has weird behavior: if current buffer contains
+    # a \n, entire buffer gets flushed.  Logical behavior would be to flush
+    # only up to the \n.
+    
+    set f [open $path(test1) w]
+    fconfigure $f -encoding ascii -buffering line -translation crlf
+    puts -nonewline $f "\n12"
+    set x [contents $path(test1)]
+    close $f
+    set x
+} "\r\n12"
+test io-3.4 {WriteChars: loop over stage buffer} {
+    # stage buffer maps to more than can be queued at once.
+
+    set f [open $path(test1) w]
+    fconfigure $f -encoding jis0208 -buffersize 16 
+    puts -nonewline $f "\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"
+    set x [list [contents $path(test1)]]
+    close $f
+    lappend x [contents $path(test1)]
+} [list "!)!)!)!)!)!)!)!)" "!)!)!)!)!)!)!)!)!)!)!)!)!)!)!)"]
+test io-3.5 {WriteChars: saved != 0} {
+    # Bytes produced by UtfToExternal from end of last channel buffer
+    # had to be moved to beginning of next channel buffer to preserve
+    # requested buffersize.
+
+    set f [open $path(test1) w]
+    fconfigure $f -encoding jis0208 -buffersize 17 
+    puts -nonewline $f "\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"
+    set x [list [contents $path(test1)]]
+    close $f
+    lappend x [contents $path(test1)]
+} [list "!)!)!)!)!)!)!)!)!" "!)!)!)!)!)!)!)!)!)!)!)!)!)!)!)"]
+test io-3.6 {WriteChars: (stageRead + dstWrote == 0)} {
+    # One incomplete UTF-8 character at end of staging buffer.  Backup
+    # in src to the beginning of that UTF-8 character and try again.
+    #
+    # Translate the first 16 bytes, produce 14 bytes of output, 2 left over
+    # (first two bytes of \uff21 in UTF-8).  Given those two bytes try
+    # translating them again, find that no bytes are read produced, and break
+    # to outer loop where those two bytes will have the remaining 4 bytes
+    # (the last byte of \uff21 plus the all of \uff22) appended.
+
+    set f [open $path(test1) w]
+    fconfigure $f -encoding shiftjis -buffersize 16
+    puts -nonewline $f "12345678901234\uff21\uff22"
+    set x [list [contents $path(test1)]]
+    close $f
+    lappend x [contents $path(test1)]
+} [list "12345678901234\x82\x60" "12345678901234\x82\x60\x82\x61"]
+test io-3.7 {WriteChars: (bufPtr->nextAdded > bufPtr->length)} {
+    # When translating UTF-8 to external, the produced bytes went past end
+    # of the channel buffer.  This is done purpose -- we then truncate the
+    # bytes at the end of the partial character to preserve the requested
+    # blocksize on flush.  The truncated bytes are moved to the beginning
+    # of the next channel buffer.
+
+    set f [open $path(test1) w]
+    fconfigure $f -encoding jis0208 -buffersize 17 
+    puts -nonewline $f "\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\"
+    set x [list [contents $path(test1)]]
+    close $f
+    lappend x [contents $path(test1)]
+} [list "!)!)!)!)!)!)!)!)!" "!)!)!)!)!)!)!)!)!)!)!)!)!)!)!)"]
+test io-3.8 {WriteChars: reset sawLF after each buffer} {
+    set f [open $path(test1) w]
+    fconfigure $f -encoding ascii -buffering line -translation lf \
+	     -buffersize 16
+    puts -nonewline $f "abcdefg\nhijklmnopqrstuvwxyz"
+    set x [list [contents $path(test1)]]
+    close $f
+    lappend x [contents $path(test1)]
+} [list "abcdefg\nhijklmno" "abcdefg\nhijklmnopqrstuvwxyz"]
+
+test io-4.1 {TranslateOutputEOL: lf} {
+    # search for \n
+
+    set f [open $path(test1) w]
+    fconfigure $f -buffering line -translation lf
+    puts $f "abcde"
+    set x [list [contents $path(test1)]]
+    close $f
+    lappend x [contents $path(test1)]
+} [list "abcde\n" "abcde\n"]
+test io-4.2 {TranslateOutputEOL: cr} {
+    # search for \n, replace with \r
+
+    set f [open $path(test1) w]
+    fconfigure $f -buffering line -translation cr
+    puts $f "abcde"
+    set x [list [contents $path(test1)]]
+    close $f
+    lappend x [contents $path(test1)]
+} [list "abcde\r" "abcde\r"]
+test io-4.3 {TranslateOutputEOL: crlf} {
+    # simple case: search for \n, replace with \r
+
+    set f [open $path(test1) w]
+    fconfigure $f -buffering line -translation crlf
+    puts $f "abcde"
+    set x [list [contents $path(test1)]]
+    close $f
+    lappend x [contents $path(test1)]
+} [list "abcde\r\n" "abcde\r\n"]
+test io-4.4 {TranslateOutputEOL: crlf} {
+    # keep storing more bytes in output buffer until output buffer is full.
+    # We have 13 bytes initially that would turn into 18 bytes.  Fill
+    # dest buffer while (dstEnd < dstMax).
+
+    set f [open $path(test1) w]
+    fconfigure $f -translation crlf -buffersize 16
+    puts -nonewline $f "1234567\n\n\n\n\nA"
+    set x [list [contents $path(test1)]]
+    close $f
+    lappend x [contents $path(test1)]
+} [list "1234567\r\n\r\n\r\n\r\n\r" "1234567\r\n\r\n\r\n\r\n\r\nA"]
+test io-4.5 {TranslateOutputEOL: crlf} {
+    # Check for overflow of the destination buffer
+
+    set f [open $path(test1) w]
+    fconfigure $f -translation crlf -buffersize 12
+    puts -nonewline $f "12345678901\n456789012345678901234"
+    close $f
+    set x [contents $path(test1)]
+} "12345678901\r\n456789012345678901234"
+
+test io-5.1 {CheckFlush: not full} {
+    set f [open $path(test1) w]
+    fconfigure $f 
+    puts -nonewline $f "12345678901234567890"
+    set x [list [contents $path(test1)]]
+    close $f
+    lappend x [contents $path(test1)]
+} [list "" "12345678901234567890"]
+test io-5.2 {CheckFlush: full} {
+    set f [open $path(test1) w]
+    fconfigure $f -buffersize 16
+    puts -nonewline $f "12345678901234567890"
+    set x [list [contents $path(test1)]]
+    close $f
+    lappend x [contents $path(test1)]
+} [list "1234567890123456" "12345678901234567890"]
+test io-5.3 {CheckFlush: not line} {
+    set f [open $path(test1) w]
+    fconfigure $f -buffering line
+    puts -nonewline $f "12345678901234567890"
+    set x [list [contents $path(test1)]]
+    close $f
+    lappend x [contents $path(test1)]
+} [list "" "12345678901234567890"]
+test io-5.4 {CheckFlush: line} {
+    set f [open $path(test1) w]
+    fconfigure $f -buffering line -translation lf -encoding ascii
+    puts -nonewline $f "1234567890\n1234567890"
+    set x [list [contents $path(test1)]]
+    close $f
+    lappend x [contents $path(test1)]
+} [list "1234567890\n1234567890" "1234567890\n1234567890"]
+test io-5.5 {CheckFlush: none} {
+    set f [open $path(test1) w]
+    fconfigure $f -buffering none
+    puts -nonewline $f "1234567890"
+    set x [list [contents $path(test1)]]
+    close $f
+    lappend x [contents $path(test1)]
+} [list "1234567890" "1234567890"]
+
+test io-6.1 {Tcl_GetsObj: working} {
+    set f [open $path(test1) w]
+    puts $f "foo\nboo"
+    close $f
+    set f [open $path(test1)]
+    set x [gets $f]
+    close $f
+    set x
+} {foo}
+test io-6.2 {Tcl_GetsObj: CheckChannelErrors() != 0} emptyTest {
+    # no test, need to cause an async error.
+} {}
+test io-6.3 {Tcl_GetsObj: how many have we used?} {
+    # if (bufPtr != NULL) {oldRemoved = bufPtr->nextRemoved}
+
+    set f [open $path(test1) w]
+    fconfigure $f -translation crlf
+    puts $f "abc\ndefg"
+    close $f
+    set f [open $path(test1)]
+    set x [list [tell $f] [gets $f line] [tell $f] [gets $f line] $line]
+    close $f
+    set x
+} {0 3 5 4 defg}
+test io-6.4 {Tcl_GetsObj: encoding == NULL} {
+    set f [open $path(test1) w]
+    fconfigure $f -translation binary
+    puts $f "\x81\u1234\0"
+    close $f
+    set f [open $path(test1)]
+    fconfigure $f -translation binary
+    set x [list [gets $f line] $line]
+    close $f
+    set x
+} [list 3 "\x81\x34\x00"]
+test io-6.5 {Tcl_GetsObj: encoding != NULL} {
+    set f [open $path(test1) w]
+    fconfigure $f -translation binary
+    puts $f "\x88\xea\x92\x9a"
+    close $f
+    set f [open $path(test1)]
+    fconfigure $f -encoding shiftjis
+    set x [list [gets $f line] $line]
+    close $f
+    set x
+} [list 2 "\u4e00\u4e01"]
+set a "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
+append a $a
+append a $a
+test io-6.6 {Tcl_GetsObj: loop test} {
+    # if (dst >= dstEnd) 
+
+    set f [open $path(test1) w]
+    puts $f $a
+    puts $f hi
+    close $f
+    set f [open $path(test1)]
+    set x [list [gets $f line] $line]
+    close $f
+    set x
+} [list 256 $a]
+test io-6.7 {Tcl_GetsObj: error in input} {stdio openpipe} {
+    # if (FilterInputBytes(chanPtr, &gs) != 0)
+
+    set f [open "|[list [interpreter] $path(cat)]" w+]
+    puts -nonewline $f "hi\nwould"
+    flush $f
+    gets $f
+    fconfigure $f -blocking 0
+    set x [gets $f line]
+    close $f
+    set x
+} {-1}
+test io-6.8 {Tcl_GetsObj: remember if EOF is seen} {
+    set f [open $path(test1) w]
+    puts $f "abcdef\x1aghijk\nwombat"
+    close $f
+    set f [open $path(test1)]
+    fconfigure $f -eofchar \x1a
+    set x [list [gets $f line] $line [gets $f line] $line]
+    close $f
+    set x
+} {6 abcdef -1 {}}
+test io-6.9 {Tcl_GetsObj: remember if EOF is seen} {
+    set f [open $path(test1) w]
+    puts $f "abcdefghijk\nwom\u001abat"
+    close $f
+    set f [open $path(test1)]
+    fconfigure $f -eofchar \x1a
+    set x [list [gets $f line] $line [gets $f line] $line]
+    close $f
+    set x
+} {11 abcdefghijk 3 wom}
+# Comprehensive tests
+test io-6.10 {Tcl_GetsObj: lf mode: no chars} {
+    set f [open $path(test1) w]
+    close $f
+    set f [open $path(test1)]
+    fconfigure $f -translation lf
+    set x [list [gets $f line] $line]
+    close $f
+    set x
+} {-1 {}}
+test io-6.11 {Tcl_GetsObj: lf mode: lone \n} {
+    set f [open $path(test1) w]
+    fconfigure $f -translation lf
+    puts -nonewline $f "\n"
+    close $f
+    set f [open $path(test1)]
+    fconfigure $f -translation lf
+    set x [list [gets $f line] $line [gets $f line] $line]
+    close $f
+    set x
+} {0 {} -1 {}}
+test io-6.12 {Tcl_GetsObj: lf mode: lone \r} {
+    set f [open $path(test1) w]
+    fconfigure $f -translation lf
+    puts -nonewline $f "\r"
+    close $f
+    set f [open $path(test1)]
+    fconfigure $f -translation lf
+    set x [list [gets $f line] $line [gets $f line] $line]
+    close $f
+    set x
+} [list 1 "\r" -1 ""]
+test io-6.13 {Tcl_GetsObj: lf mode: 1 char} {
+    set f [open $path(test1) w]
+    fconfigure $f -translation lf
+    puts -nonewline $f a
+    close $f
+    set f [open $path(test1)]
+    fconfigure $f -translation lf
+    set x [list [gets $f line] $line [gets $f line] $line]
+    close $f
+    set x
+} {1 a -1 {}}
+test io-6.14 {Tcl_GetsObj: lf mode: 1 char followed by EOL} {
+    set f [open $path(test1) w]
+    fconfigure $f -translation lf
+    puts -nonewline $f "a\n"
+    close $f
+    set f [open $path(test1)]
+    fconfigure $f -translation lf
+    set x [list [gets $f line] $line [gets $f line] $line]
+    close $f
+    set x
+} {1 a -1 {}}
+test io-6.15 {Tcl_GetsObj: lf mode: several chars} {
+    set f [open $path(test1) w]
+    fconfigure $f -translation lf
+    puts -nonewline $f "abcd\nefgh\rijkl\r\nmnop"
+    close $f
+    set f [open $path(test1)]
+    fconfigure $f -translation lf
+    set x [list [gets $f line] $line [gets $f line] $line [gets $f line] $line [gets $f line] $line]
+    close $f
+    set x
+} [list 4 "abcd" 10 "efgh\rijkl\r" 4 "mnop" -1 ""]
+test io-6.16 {Tcl_GetsObj: cr mode: no chars} {
+    set f [open $path(test1) w]
+    close $f
+    set f [open $path(test1)]
+    fconfigure $f -translation cr
+    set x [list [gets $f line] $line]
+    close $f
+    set x
+} {-1 {}}
+test io-6.17 {Tcl_GetsObj: cr mode: lone \n} {
+    set f [open $path(test1) w]
+    fconfigure $f -translation lf
+    puts -nonewline $f "\n"
+    close $f
+    set f [open $path(test1)]
+    fconfigure $f -translation cr
+    set x [list [gets $f line] $line [gets $f line] $line]
+    close $f
+    set x
+} [list 1 "\n" -1 ""]
+test io-6.18 {Tcl_GetsObj: cr mode: lone \r} {
+    set f [open $path(test1) w]
+    fconfigure $f -translation lf
+    puts -nonewline $f "\r"
+    close $f
+    set f [open $path(test1)]
+    fconfigure $f -translation cr
+    set x [list [gets $f line] $line [gets $f line] $line]
+    close $f
+    set x
+} {0 {} -1 {}}
+test io-6.19 {Tcl_GetsObj: cr mode: 1 char} {
+    set f [open $path(test1) w]
+    fconfigure $f -translation lf
+    puts -nonewline $f a
+    close $f
+    set f [open $path(test1)]
+    fconfigure $f -translation cr
+    set x [list [gets $f line] $line [gets $f line] $line]
+    close $f
+    set x
+} {1 a -1 {}}
+test io-6.20 {Tcl_GetsObj: cr mode: 1 char followed by EOL} {
+    set f [open $path(test1) w]
+    fconfigure $f -translation lf
+    puts -nonewline $f "a\r"
+    close $f
+    set f [open $path(test1)]
+    fconfigure $f -translation cr
+    set x [list [gets $f line] $line [gets $f line] $line]
+    close $f
+    set x
+} {1 a -1 {}}
+test io-6.21 {Tcl_GetsObj: cr mode: several chars} {
+    set f [open $path(test1) w]
+    fconfigure $f -translation lf
+    puts -nonewline $f "abcd\nefgh\rijkl\r\nmnop"
+    close $f
+    set f [open $path(test1)]
+    fconfigure $f -translation cr
+    set x [list [gets $f line] $line [gets $f line] $line [gets $f line] $line [gets $f line] $line]
+    close $f
+    set x
+} [list 9 "abcd\nefgh" 4 "ijkl" 5 "\nmnop" -1 ""]
+test io-6.22 {Tcl_GetsObj: crlf mode: no chars} {
+    set f [open $path(test1) w]
+    close $f
+    set f [open $path(test1)]
+    fconfigure $f -translation crlf
+    set x [list [gets $f line] $line]
+    close $f
+    set x
+} {-1 {}}
+test io-6.23 {Tcl_GetsObj: crlf mode: lone \n} {
+    set f [open $path(test1) w]
+    fconfigure $f -translation lf
+    puts -nonewline $f "\n"
+    close $f
+    set f [open $path(test1)]
+    fconfigure $f -translation crlf
+    set x [list [gets $f line] $line [gets $f line] $line]
+    close $f
+    set x
+} [list 1 "\n" -1 ""]
+test io-6.24 {Tcl_GetsObj: crlf mode: lone \r} {
+    set f [open $path(test1) w]
+    fconfigure $f -translation lf
+    puts -nonewline $f "\r"
+    close $f
+    set f [open $path(test1)]
+    fconfigure $f -translation crlf
+    set x [list [gets $f line] $line [gets $f line] $line]
+    close $f
+    set x
+} [list 1 "\r" -1 ""]
+test io-6.25 {Tcl_GetsObj: crlf mode: \r\r} {
+    set f [open $path(test1) w]
+    fconfigure $f -translation lf
+    puts -nonewline $f "\r\r"
+    close $f
+    set f [open $path(test1)]
+    fconfigure $f -translation crlf
+    set x [list [gets $f line] $line [gets $f line] $line]
+    close $f
+    set x
+} [list 2 "\r\r" -1 ""]
+test io-6.26 {Tcl_GetsObj: crlf mode: \r\n} {
+    set f [open $path(test1) w]
+    fconfigure $f -translation lf
+    puts -nonewline $f "\r\n"
+    close $f
+    set f [open $path(test1)]
+    fconfigure $f -translation crlf
+    set x [list [gets $f line] $line [gets $f line] $line]
+    close $f
+    set x
+} [list 0 "" -1 ""]
+test io-6.27 {Tcl_GetsObj: crlf mode: 1 char} {
+    set f [open $path(test1) w]
+    fconfigure $f -translation lf
+    puts -nonewline $f a
+    close $f
+    set f [open $path(test1)]
+    fconfigure $f -translation crlf
+    set x [list [gets $f line] $line [gets $f line] $line]
+    close $f
+    set x
+} {1 a -1 {}}
+test io-6.28 {Tcl_GetsObj: crlf mode: 1 char followed by EOL} {
+    set f [open $path(test1) w]
+    fconfigure $f -translation lf
+    puts -nonewline $f "a\r\n"
+    close $f
+    set f [open $path(test1)]
+    fconfigure $f -translation crlf
+    set x [list [gets $f line] $line [gets $f line] $line]
+    close $f
+    set x
+} {1 a -1 {}}
+test io-6.29 {Tcl_GetsObj: crlf mode: several chars} {
+    set f [open $path(test1) w]
+    fconfigure $f -translation lf
+    puts -nonewline $f "abcd\nefgh\rijkl\r\nmnop"
+    close $f
+    set f [open $path(test1)]
+    fconfigure $f -translation crlf
+    set x [list [gets $f line] $line [gets $f line] $line [gets $f line] $line]
+    close $f
+    set x
+} [list 14 "abcd\nefgh\rijkl" 4 "mnop" -1 ""]
+test io-6.30 {Tcl_GetsObj: crlf mode: buffer exhausted} {testchannel} {
+    # if (eol >= dstEnd)
+
+    set f [open $path(test1) w]
+    fconfigure $f -translation lf
+    puts -nonewline $f "123456789012345\r\nabcdefghijklmnoprstuvwxyz"
+    close $f
+    set f [open $path(test1)]
+    fconfigure $f -translation crlf -buffersize 16
+    set x [list [gets $f line] $line [testchannel inputbuffered $f]]
+    close $f
+    set x
+} [list 15 "123456789012345" 15]
+test io-6.31 {Tcl_GetsObj: crlf mode: buffer exhausted, blocked} {stdio testchannel openpipe fileevent} {
+    # (FilterInputBytes() != 0)
+
+    set f [open "|[list [interpreter] $path(cat)]" w+]
+    fconfigure $f -translation {crlf lf} -buffering none
+    puts -nonewline $f "bbbbbbbbbbbbbb\r\n123456789012345\r"
+    fconfigure $f -buffersize 16
+    set x [gets $f]
+    fconfigure $f -blocking 0
+    lappend x [gets $f line] $line [fblocked $f] [testchannel inputbuffered $f]
+    close $f
+    set x
+} [list "bbbbbbbbbbbbbb" -1 "" 1 16]
+test io-6.32 {Tcl_GetsObj: crlf mode: buffer exhausted, more data} {testchannel} {
+    # not (FilterInputBytes() != 0)
+
+    set f [open $path(test1) w]
+    fconfigure $f -translation lf
+    puts -nonewline $f "123456789012345\r\n123"
+    close $f
+    set f [open $path(test1)]
+    fconfigure $f -translation crlf -buffersize 16
+    set x [list [gets $f line] $line [tell $f] [testchannel inputbuffered $f]]
+    close $f
+    set x
+} [list 15 "123456789012345" 17 3]
+test io-6.33 {Tcl_GetsObj: crlf mode: buffer exhausted, at eof} {
+    # eol still equals dstEnd
+    
+    set f [open $path(test1) w]
+    fconfigure $f -translation lf
+    puts -nonewline $f "123456789012345\r"
+    close $f
+    set f [open $path(test1)]
+    fconfigure $f -translation crlf -buffersize 16
+    set x [list [gets $f line] $line [eof $f]]
+    close $f
+    set x
+} [list 16 "123456789012345\r" 1]
+test io-6.34 {Tcl_GetsObj: crlf mode: buffer exhausted, not followed by \n} {
+    # not (*eol == '\n') 
+    
+    set f [open $path(test1) w]
+    fconfigure $f -translation lf
+    puts -nonewline $f "123456789012345\rabcd\r\nefg"
+    close $f
+    set f [open $path(test1)]
+    fconfigure $f -translation crlf -buffersize 16
+    set x [list [gets $f line] $line [tell $f]]
+    close $f
+    set x
+} [list 20 "123456789012345\rabcd" 22]
+test io-6.35 {Tcl_GetsObj: auto mode: no chars} {
+    set f [open $path(test1) w]
+    close $f
+    set f [open $path(test1)]
+    fconfigure $f -translation auto
+    set x [list [gets $f line] $line]
+    close $f
+    set x
+} {-1 {}}
+test io-6.36 {Tcl_GetsObj: auto mode: lone \n} {
+    set f [open $path(test1) w]
+    fconfigure $f -translation lf
+    puts -nonewline $f "\n"
+    close $f
+    set f [open $path(test1)]
+    fconfigure $f -translation auto
+    set x [list [gets $f line] $line [gets $f line] $line]
+    close $f
+    set x
+} [list 0 "" -1 ""]
+test io-6.37 {Tcl_GetsObj: auto mode: lone \r} {
+    set f [open $path(test1) w]
+    fconfigure $f -translation lf
+    puts -nonewline $f "\r"
+    close $f
+    set f [open $path(test1)]
+    fconfigure $f -translation auto
+    set x [list [gets $f line] $line [gets $f line] $line]
+    close $f
+    set x
+} [list 0 "" -1 ""]
+test io-6.38 {Tcl_GetsObj: auto mode: \r\r} {
+    set f [open $path(test1) w]
+    fconfigure $f -translation lf
+    puts -nonewline $f "\r\r"
+    close $f
+    set f [open $path(test1)]
+    fconfigure $f -translation auto
+    set x [list [gets $f line] $line [gets $f line] $line [gets $f line] $line]
+    close $f
+    set x
+} [list 0 "" 0 "" -1 ""]
+test io-6.39 {Tcl_GetsObj: auto mode: \r\n} {
+    set f [open $path(test1) w]
+    fconfigure $f -translation lf
+    puts -nonewline $f "\r\n"
+    close $f
+    set f [open $path(test1)]
+    fconfigure $f -translation auto
+    set x [list [gets $f line] $line [gets $f line] $line]
+    close $f
+    set x
+} [list 0 "" -1 ""]
+test io-6.40 {Tcl_GetsObj: auto mode: 1 char} {
+    set f [open $path(test1) w]
+    fconfigure $f -translation lf
+    puts -nonewline $f a
+    close $f
+    set f [open $path(test1)]
+    fconfigure $f -translation auto
+    set x [list [gets $f line] $line [gets $f line] $line]
+    close $f
+    set x
+} {1 a -1 {}}
+test io-6.41 {Tcl_GetsObj: auto mode: 1 char followed by EOL} {
+    set f [open $path(test1) w]
+    fconfigure $f -translation lf
+    puts -nonewline $f "a\r\n"
+    close $f
+    set f [open $path(test1)]
+    fconfigure $f -translation auto
+    set x [list [gets $f line] $line [gets $f line] $line]
+    close $f
+    set x
+} {1 a -1 {}}
+test io-6.42 {Tcl_GetsObj: auto mode: several chars} {
+    set f [open $path(test1) w]
+    fconfigure $f -translation lf
+    puts -nonewline $f "abcd\nefgh\rijkl\r\nmnop"
+    close $f
+    set f [open $path(test1)]
+    fconfigure $f -translation auto
+    set x [list [gets $f line] $line [gets $f line] $line]
+    lappend x [gets $f line] $line [gets $f line] $line [gets $f line] $line
+    close $f
+    set x
+} [list 4 "abcd" 4 "efgh" 4 "ijkl" 4 "mnop" -1 ""]
+test io-6.43 {Tcl_GetsObj: input saw cr} {stdio testchannel openpipe fileevent} {
+    # if (chanPtr->flags & INPUT_SAW_CR)
+
+    set f [open "|[list [interpreter] $path(cat)]" w+]
+    fconfigure $f -translation {auto lf} -buffering none
+    puts -nonewline $f "bbbbbbbbbbbbbbb\n123456789abcdef\r"
+    fconfigure $f -buffersize 16
+    set x [list [gets $f]]
+    fconfigure $f -blocking 0
+    lappend x [gets $f line] $line [testchannel queuedcr $f] 
+    fconfigure $f -blocking 1
+    puts -nonewline $f "\nabcd\refg\x1a"
+    lappend x [gets $f line] $line [testchannel queuedcr $f]
+    lappend x [gets $f line] $line
+    close $f
+    set x
+} [list "bbbbbbbbbbbbbbb" 15 "123456789abcdef" 1 4 "abcd" 0 3 "efg"]
+test io-6.44 {Tcl_GetsObj: input saw cr, not followed by cr} {stdio testchannel openpipe fileevent} {
+    # not (*eol == '\n') 
+
+    set f [open "|[list [interpreter] $path(cat)]" w+]
+    fconfigure $f -translation {auto lf} -buffering none
+    puts -nonewline $f "bbbbbbbbbbbbbbb\n123456789abcdef\r"
+    fconfigure $f -buffersize 16
+    set x [list [gets $f]]
+    fconfigure $f -blocking 0
+    lappend x [gets $f line] $line [testchannel queuedcr $f] 
+    fconfigure $f -blocking 1
+    puts -nonewline $f "abcd\refg\x1a"
+    lappend x [gets $f line] $line [testchannel queuedcr $f]
+    lappend x [gets $f line] $line
+    close $f
+    set x
+} [list "bbbbbbbbbbbbbbb" 15 "123456789abcdef" 1 4 "abcd" 0 3 "efg"]
+test io-6.45 {Tcl_GetsObj: input saw cr, skip right number of bytes} {stdio testchannel openpipe fileevent} {
+    # Tcl_ExternalToUtf()
+
+    set f [open "|[list [interpreter] $path(cat)]" w+]
+    fconfigure $f -translation {auto lf} -buffering none
+    fconfigure $f -encoding unicode
+    puts -nonewline $f "bbbbbbbbbbbbbbb\n123456789abcdef\r"
+    fconfigure $f -buffersize 16
+    gets $f
+    fconfigure $f -blocking 0
+    set x [list [gets $f line] $line [testchannel queuedcr $f]]
+    fconfigure $f -blocking 1
+    puts -nonewline $f "\nabcd\refg"
+    lappend x [gets $f line] $line [testchannel queuedcr $f]
+    close $f
+    set x
+} [list 15 "123456789abcdef" 1 4 "abcd" 0]
+test io-6.46 {Tcl_GetsObj: input saw cr, followed by just \n should give eof} {stdio testchannel openpipe fileevent} {
+    # memmove()
+
+    set f [open "|[list [interpreter] $path(cat)]" w+]
+    fconfigure $f -translation {auto lf} -buffering none
+    puts -nonewline $f "bbbbbbbbbbbbbbb\n123456789abcdef\r"
+    fconfigure $f -buffersize 16
+    gets $f
+    fconfigure $f -blocking 0
+    set x [list [gets $f line] $line [testchannel queuedcr $f]]
+    fconfigure $f -blocking 1
+    puts -nonewline $f "\n\x1a"
+    lappend x [gets $f line] $line [testchannel queuedcr $f]
+    close $f
+    set x
+} [list 15 "123456789abcdef" 1 -1 "" 0]
+test io-6.47 {Tcl_GetsObj: auto mode: \r at end of buffer, peek for \n} {testchannel} {
+    # (eol == dstEnd)
+
+    set f [open $path(test1) w]
+    fconfigure $f -translation lf
+    puts -nonewline $f "123456789012345\r\nabcdefghijklmnopq"
+    close $f
+    set f [open $path(test1)]
+    fconfigure $f -translation auto -buffersize 16
+    set x [list [gets $f] [testchannel inputbuffered $f]]
+    close $f
+    set x
+} [list "123456789012345" 15]    
+test io-6.48 {Tcl_GetsObj: auto mode: \r at end of buffer, no more avail} {testchannel} {
+    # PeekAhead() did not get any, so (eol >= dstEnd)
+    
+    set f [open $path(test1) w]
+    fconfigure $f -translation lf
+    puts -nonewline $f "123456789012345\r"
+    close $f
+    set f [open $path(test1)]
+    fconfigure $f -translation auto -buffersize 16
+    set x [list [gets $f] [testchannel queuedcr $f]]
+    close $f
+    set x
+} [list "123456789012345" 1]
+test io-6.49 {Tcl_GetsObj: auto mode: \r followed by \n} {testchannel} {
+    # if (*eol == '\n') {skip++}
+    
+    set f [open $path(test1) w]
+    fconfigure $f -translation lf
+    puts -nonewline $f "123456\r\n78901"
+    close $f
+    set f [open $path(test1)]
+    set x [list [gets $f] [testchannel queuedcr $f] [tell $f] [gets $f]]
+    close $f
+    set x
+} [list "123456" 0 8 "78901"]
+test io-6.50 {Tcl_GetsObj: auto mode: \r not followed by \n} {testchannel} {
+    # not (*eol == '\n') 
+    
+    set f [open $path(test1) w]
+    fconfigure $f -translation lf
+    puts -nonewline $f "123456\r78901"
+    close $f
+    set f [open $path(test1)]
+    set x [list [gets $f] [testchannel queuedcr $f] [tell $f] [gets $f]]
+    close $f
+    set x
+} [list "123456" 0 7 "78901"]
+test io-6.51 {Tcl_GetsObj: auto mode: \n} {
+    # else if (*eol == '\n') {goto gotoeol;}
+    
+    set f [open $path(test1) w]
+    fconfigure $f -translation lf
+    puts -nonewline $f "123456\n78901"
+    close $f
+    set f [open $path(test1)]
+    set x [list [gets $f] [tell $f] [gets $f]]
+    close $f
+    set x
+} [list "123456" 7 "78901"]
+test io-6.52 {Tcl_GetsObj: saw EOF character} {testchannel} {
+    # if (eof != NULL)
+
+    set f [open $path(test1) w]
+    fconfigure $f -translation lf
+    puts -nonewline $f "123456\x1ak9012345\r"
+    close $f
+    set f [open $path(test1)]
+    fconfigure $f -eofchar \x1a
+    set x [list [gets $f] [testchannel queuedcr $f] [tell $f] [gets $f]]
+    close $f
+    set x
+} [list "123456" 0 6 ""]
+test io-6.53 {Tcl_GetsObj: device EOF} {
+    # didn't produce any bytes
+
+    set f [open $path(test1) w]
+    close $f
+    set f [open $path(test1)]
+    set x [list [gets $f line] $line [eof $f]]
+    close $f
+    set x
+} {-1 {} 1}
+test io-6.54 {Tcl_GetsObj: device EOF} {
+    # got some bytes before EOF.
+
+    set f [open $path(test1) w]
+    puts -nonewline $f abc
+    close $f
+    set f [open $path(test1)]
+    set x [list [gets $f line] $line [eof $f]]
+    close $f
+    set x
+} {3 abc 1}
+test io-6.55 {Tcl_GetsObj: overconverted} {
+    # Tcl_ExternalToUtf(), make sure state updated
+
+    set f [open $path(test1) w]
+    fconfigure $f -encoding iso2022-jp
+    puts $f "there\u4e00ok\n\u4e01more bytes\nhere"
+    close $f
+    set f [open $path(test1)]
+    fconfigure $f -encoding iso2022-jp
+    set x [list [gets $f line] $line [gets $f line] $line [gets $f line] $line]
+    close $f
+    set x
+} [list 8 "there\u4e00ok" 11 "\u4e01more bytes" 4 "here"]
+test io-6.56 {Tcl_GetsObj: incomplete lines should disable file events} {stdio openpipe fileevent} {
+    update
+    set f [open "|[list [interpreter] $path(cat)]" w+]
+    fconfigure $f -buffering none
+    puts -nonewline $f "foobar"
+    fconfigure $f -blocking 0
+    variable x {}
+    after 500 [namespace code { lappend x timeout }]
+    fileevent $f readable [namespace code { lappend x [gets $f] }]
+    vwait [namespace which -variable x]
+    vwait [namespace which -variable x]
+    fconfigure $f -blocking 1
+    puts -nonewline $f "baz\n"
+    after 500 [namespace code { lappend x timeout }]
+    fconfigure $f -blocking 0
+    vwait [namespace which -variable x]
+    vwait [namespace which -variable x]
+    close $f
+    set x
+} {{} timeout foobarbaz timeout}
+
+test io-7.1 {FilterInputBytes: split up character at end of buffer} {
+    # (result == TCL_CONVERT_MULTIBYTE)
+
+    set f [open $path(test1) w]
+    fconfigure $f -encoding shiftjis
+    puts $f "1234567890123\uff10\uff11\uff12\uff13\uff14\nend"
+    close $f
+    set f [open $path(test1)]
+    fconfigure $f -encoding shiftjis -buffersize 16
+    set x [gets $f]
+    close $f
+    set x
+} "1234567890123\uff10\uff11\uff12\uff13\uff14"
+test io-7.2 {FilterInputBytes: split up character in middle of buffer} {
+    # (bufPtr->nextAdded < bufPtr->bufLength)
+    
+    set f [open $path(test1) w]
+    fconfigure $f -encoding binary
+    puts -nonewline $f "1234567890\n123\x82\x4f\x82\x50\x82"
+    close $f
+    set f [open $path(test1)]
+    fconfigure $f -encoding shiftjis
+    set x [list [gets $f line] $line [eof $f]]
+    close $f
+    set x
+} [list 10 "1234567890" 0]
+test io-7.3 {FilterInputBytes: split up character at EOF} {testchannel} {
+    set f [open $path(test1) w]
+    fconfigure $f -encoding binary
+    puts -nonewline $f "1234567890123\x82\x4f\x82\x50\x82"
+    close $f
+    set f [open $path(test1)]
+    fconfigure $f -encoding shiftjis
+    set x [list [gets $f line] $line]
+    lappend x [tell $f] [testchannel inputbuffered $f] [eof $f]
+    lappend x [gets $f line] $line
+    close $f
+    set x
+} [list 15 "1234567890123\uff10\uff11" 18 0 1 -1 ""]
+test io-7.4 {FilterInputBytes: recover from split up character} {stdio openpipe fileevent} {
+    set f [open "|[list [interpreter] $path(cat)]" w+]
+    fconfigure $f -encoding binary -buffering none
+    puts -nonewline $f "1234567890123\x82\x4f\x82\x50\x82"
+    fconfigure $f -encoding shiftjis -blocking 0
+    fileevent $f read [namespace code "ready $f"]
+    variable x {}
+    proc ready {f} {
+	variable x
+	lappend x [gets $f line] $line [fblocked $f]
+    }
+    vwait [namespace which -variable x]
+    fconfigure $f -encoding binary -blocking 1
+    puts $f "\x51\x82\x52"
+    fconfigure $f -encoding shiftjis
+    vwait [namespace which -variable x]
+    close $f
+    set x
+} [list -1 "" 1 17 "1234567890123\uff10\uff11\uff12\uff13" 0]
+
+test io-8.1 {PeekAhead: only go to device if no more cached data} {testchannel} {
+    # (bufPtr->nextPtr == NULL)
+
+    set f [open $path(test1) w]
+    fconfigure $f -encoding ascii -translation lf
+    puts -nonewline $f "123456789012345\r\n2345678"
+    close $f
+    set f [open $path(test1)]
+    fconfigure $f -encoding ascii -translation auto -buffersize 16
+    # here
+    gets $f
+    set x [testchannel inputbuffered $f]
+    close $f
+    set x
+} "7"
+test io-8.2 {PeekAhead: only go to device if no more cached data} {stdio testchannel openpipe fileevent} {
+    # not (bufPtr->nextPtr == NULL)
+
+    set f [open "|[list [interpreter] $path(cat)]" w+]
+    fconfigure $f -translation lf -encoding ascii -buffering none
+    puts -nonewline $f "123456789012345\r\nbcdefghijklmnopqrstuvwxyz"
+    variable x {}
+    fileevent $f read [namespace code "ready $f"]
+    proc ready {f} {
+	variable x
+	lappend x [gets $f line] $line [testchannel inputbuffered $f]
+    }
+    fconfigure $f -encoding unicode -buffersize 16 -blocking 0
+    vwait [namespace which -variable x]
+    fconfigure $f -translation auto -encoding ascii -blocking 1
+    # here
+    vwait [namespace which -variable x]
+    close $f
+    set x
+} [list -1 "" 42 15 "123456789012345" 25]
+test io-8.3 {PeekAhead: no cached data available} {stdio testchannel openpipe fileevent} {
+    # (bytesLeft == 0)
+
+    set f [open "|[list [interpreter] $path(cat)]" w+]
+    fconfigure $f -translation {auto binary}
+    puts -nonewline $f "abcdefghijklmno\r"
+    flush $f
+    set x [list [gets $f line] $line [testchannel queuedcr $f]]
+    close $f
+    set x
+} [list 15 "abcdefghijklmno" 1]
+set a "123456789012345678901234567890"
+append a "123456789012345678901234567890"
+append a "1234567890123456789012345678901"
+test io-8.4 {PeekAhead: cached data available in this buffer} {
+    # not (bytesLeft == 0)
+
+    set f [open $path(test1) w+]
+    fconfigure $f -translation binary
+    puts $f "${a}\r\nabcdef"
+    close $f
+    set f [open $path(test1)]
+    fconfigure $f -encoding binary -translation auto
+
+    # "${a}\r" was converted in one operation (because ENCODING_LINESIZE
+    # is 30).  To check if "\n" follows, calls PeekAhead and determines
+    # that cached data is available in buffer w/o having to call driver.
+
+    set x [gets $f]
+    close $f
+    set x    
+} $a
+unset a
+test io-8.5 {PeekAhead: don't peek if last read was short} {stdio testchannel openpipe fileevent} {
+    # (bufPtr->nextAdded < bufPtr->length)
+
+    set f [open "|[list [interpreter] $path(cat)]" w+]
+    fconfigure $f -translation {auto binary}
+    puts -nonewline $f "abcdefghijklmno\r"
+    flush $f
+    # here
+    set x [list [gets $f line] $line [testchannel queuedcr $f]]
+    close $f
+    set x
+} {15 abcdefghijklmno 1}
+test io-8.6 {PeekAhead: change to non-blocking mode} {stdio testchannel openpipe fileevent} {
+    # ((chanPtr->flags & CHANNEL_NONBLOCKING) == 0) 
+
+    set f [open "|[list [interpreter] $path(cat)]" w+]
+    fconfigure $f -translation {auto binary} -buffersize 16
+    puts -nonewline $f "abcdefghijklmno\r"
+    flush $f
+    # here
+    set x [list [gets $f line] $line [testchannel queuedcr $f]]
+    close $f
+    set x
+} {15 abcdefghijklmno 1}
+test io-8.7 {PeekAhead: cleanup} {stdio testchannel openpipe fileevent} {
+    # Make sure bytes are removed from buffer.
+
+    set f [open "|[list [interpreter] $path(cat)]" w+]
+    fconfigure $f -translation {auto binary} -buffering none
+    puts -nonewline $f "abcdefghijklmno\r"
+    # here
+    set x [list [gets $f line] $line [testchannel queuedcr $f]]
+    puts -nonewline $f "\x1a"
+    lappend x [gets $f line] $line
+    close $f
+    set x
+} {15 abcdefghijklmno 1 -1 {}}
+
+test io-9.1 {CommonGetsCleanup} emptyTest {
+} {}
+
+test io-10.1 {Tcl_ReadChars: CheckChannelErrors} emptyTest {
+    # no test, need to cause an async error.
+} {}
+test io-10.2 {Tcl_ReadChars: loop until enough copied} {
+    # one time
+    # for (copied = 0; (unsigned) toRead > 0; )
+
+    set f [open $path(test1) w]
+    puts $f abcdefghijklmnop
+    close $f
+
+    set f [open $path(test1)]
+    set x [read $f 5]
+    close $f
+    set x
+} {abcde}
+test io-10.3 {Tcl_ReadChars: loop until enough copied} {
+    # multiple times
+    # for (copied = 0; (unsigned) toRead > 0; )
+
+    set f [open $path(test1) w]
+    puts $f abcdefghijklmnopqrstuvwxyz
+    close $f
+
+    set f [open $path(test1)]
+    fconfigure $f -buffersize 16
+    # here
+    set x [read $f 19]
+    close $f
+    set x
+} {abcdefghijklmnopqrs}
+test io-10.4 {Tcl_ReadChars: no more in channel buffer} {
+    # (copiedNow < 0)
+
+    set f [open $path(test1) w]
+    puts -nonewline $f abcdefghijkl
+    close $f
+
+    set f [open $path(test1)]
+    # here
+    set x [read $f 1000]
+    close $f
+    set x
+} {abcdefghijkl}
+test io-10.5 {Tcl_ReadChars: stop on EOF} {
+    # (chanPtr->flags & CHANNEL_EOF)
+
+    set f [open $path(test1) w]
+    puts -nonewline $f abcdefghijkl
+    close $f
+
+    set f [open $path(test1)]
+    # here
+    set x [read $f 1000]
+    close $f
+    set x
+} {abcdefghijkl}
+
+test io-11.1 {ReadBytes: want to read a lot} {
+    # ((unsigned) toRead > (unsigned) srcLen)
+
+    set f [open $path(test1) w]
+    puts -nonewline $f abcdefghijkl
+    close $f
+    set f [open $path(test1)]
+    fconfigure $f -encoding binary
+    # here
+    set x [read $f 1000]
+    close $f
+    set x
+} {abcdefghijkl}
+test io-11.2 {ReadBytes: want to read all} {
+    # ((unsigned) toRead > (unsigned) srcLen)
+
+    set f [open $path(test1) w]
+    puts -nonewline $f abcdefghijkl
+    close $f
+    set f [open $path(test1)]
+    fconfigure $f -encoding binary
+    # here
+    set x [read $f]
+    close $f
+    set x
+} {abcdefghijkl}
+test io-11.3 {ReadBytes: allocate more space} {
+    # (toRead > length - offset - 1)
+
+    set f [open $path(test1) w]
+    puts -nonewline $f abcdefghijklmnopqrstuvwxyz
+    close $f
+    set f [open $path(test1)]
+    fconfigure $f -buffersize 16 -encoding binary
+    # here
+    set x [read $f]
+    close $f
+    set x
+} {abcdefghijklmnopqrstuvwxyz}
+test io-11.4 {ReadBytes: EOF char found} {
+    # (TranslateInputEOL() != 0)
+
+    set f [open $path(test1) w]
+    puts $f abcdefghijklmnopqrstuvwxyz
+    close $f
+    set f [open $path(test1)]
+    fconfigure $f -eofchar m -encoding binary
+    # here
+    set x [list [read $f] [eof $f] [read $f] [eof $f]]
+    close $f
+    set x
+} [list "abcdefghijkl" 1 "" 1]
+
+test io-12.1 {ReadChars: want to read a lot} {
+    # ((unsigned) toRead > (unsigned) srcLen)
+
+    set f [open $path(test1) w]
+    puts -nonewline $f abcdefghijkl
+    close $f
+    set f [open $path(test1)]
+    # here
+    set x [read $f 1000]
+    close $f
+    set x
+} {abcdefghijkl}
+test io-12.2 {ReadChars: want to read all} {
+    # ((unsigned) toRead > (unsigned) srcLen)
+
+    set f [open $path(test1) w]
+    puts -nonewline $f abcdefghijkl
+    close $f
+    set f [open $path(test1)]
+    # here
+    set x [read $f]
+    close $f
+    set x
+} {abcdefghijkl}
+test io-12.3 {ReadChars: allocate more space} {
+    # (toRead > length - offset - 1)
+
+    set f [open $path(test1) w]
+    puts -nonewline $f abcdefghijklmnopqrstuvwxyz
+    close $f
+    set f [open $path(test1)]
+    fconfigure $f -buffersize 16
+    # here
+    set x [read $f]
+    close $f
+    set x
+} {abcdefghijklmnopqrstuvwxyz}
+test io-12.4 {ReadChars: split-up char} {stdio testchannel openpipe fileevent} {
+    # (srcRead == 0)
+
+    set f [open "|[list [interpreter] $path(cat)]" w+]
+    fconfigure $f -encoding binary -buffering none -buffersize 16
+    puts -nonewline $f "123456789012345\x96"
+    fconfigure $f -encoding shiftjis -blocking 0
+
+    fileevent $f read [namespace code "ready $f"]
+    proc ready {f} {
+	variable x
+	lappend x [read $f] [testchannel inputbuffered $f]
+    }
+    variable x {}
+
+    fconfigure $f -encoding shiftjis
+    vwait [namespace which -variable x]
+    fconfigure $f -encoding binary -blocking 1
+    puts -nonewline $f "\x7b"
+    after 500			;# Give the cat process time to catch up
+    fconfigure $f -encoding shiftjis -blocking 0
+    vwait [namespace which -variable x]
+    close $f
+    set x
+} [list "123456789012345" 1 "\u672c" 0]
+test io-12.5 {ReadChars: fileevents on partial characters} {stdio openpipe fileevent} {
+    set path(test1) [makeFile {
+	fconfigure stdout -encoding binary -buffering none
+	gets stdin; puts -nonewline "\xe7"
+	gets stdin; puts -nonewline "\x89"
+	gets stdin; puts -nonewline "\xa6"
+    } test1]
+    set f [open "|[list [interpreter] $path(test1)]" r+]
+    fileevent $f readable [namespace code {
+	lappend x [read $f]
+	if {[eof $f]} {
+	    lappend x eof
+	}
+    }]
+    puts $f "go1"
+    flush $f
+    fconfigure $f -blocking 0 -encoding utf-8
+    variable x {}
+    vwait [namespace which -variable x]
+    after 500 [namespace code { lappend x timeout }]
+    vwait [namespace which -variable x]
+    puts $f "go2"
+    flush $f
+    vwait [namespace which -variable x]
+    after 500 [namespace code { lappend x timeout }]
+    vwait [namespace which -variable x]
+    puts $f "go3"
+    flush $f
+    vwait [namespace which -variable x]
+    vwait [namespace which -variable x]
+    lappend x [catch {close $f} msg] $msg
+    set x
+} "{} timeout {} timeout \u7266 {} eof 0 {}"
+test io-12.6 {ReadChars: too many chars read} {
+    proc driver {cmd args} {
+        variable buffer
+        variable index
+        set chan [lindex $args 0]
+        switch -- $cmd {
+            initialize {
+                set index($chan) 0
+                set buffer($chan) [encoding convertto utf-8 \
+                        [string repeat \uBEEF 20][string repeat . 20]]
+                return {initialize finalize watch read}
+            }
+            finalize {
+                unset index($chan) buffer($chan)
+                return
+            }
+            watch {}
+            read {
+                set n [lindex $args 1]
+                set new [expr {$index($chan) + $n}]
+                set result [string range $buffer($chan) $index($chan) $new-1]
+                set index($chan) $new
+                return $result
+            }
+        }
+    }
+    set c [chan create read [namespace which driver]]
+    chan configure $c -encoding utf-8
+    while {![eof $c]} {
+        read $c 15
+    }
+    close $c
+} {}
+test io-12.7 {ReadChars: too many chars read [bc5b790099]} {
+    proc driver {cmd args} {
+        variable buffer
+        variable index
+        set chan [lindex $args 0]
+        switch -- $cmd {
+            initialize {
+                set index($chan) 0
+                set buffer($chan) [encoding convertto utf-8 \
+                        [string repeat \uBEEF 10]....\uBEEF]
+                return {initialize finalize watch read}
+            }
+            finalize {
+                unset index($chan) buffer($chan)
+                return
+            }
+            watch {}
+            read {
+                set n [lindex $args 1]
+                set new [expr {$index($chan) + $n}]
+                set result [string range $buffer($chan) $index($chan) $new-1]
+                set index($chan) $new
+                return $result
+            }
+        }
+    }
+    set c [chan create read [namespace which driver]]
+    chan configure $c -encoding utf-8
+    while {![eof $c]} {
+        read $c 7
+    }
+    close $c
+} {}
+test io-12.8 {ReadChars: multibyte chars split} {
+    set f [open $path(test1) w]
+    fconfigure $f -translation binary
+    puts -nonewline $f [string repeat a 9]\xc2\xa0
+    close $f
+    set f [open $path(test1)]
+    fconfigure $f -encoding utf-8 -buffersize 10
+    set in [read $f]
+    close $f
+    scan [string index $in end] %c
+} 160
+test io-12.9 {ReadChars: multibyte chars split} {
+    set f [open $path(test1) w]
+    fconfigure $f -translation binary
+    puts -nonewline $f [string repeat a 9]\xc2
+    close $f
+    set f [open $path(test1)]
+    fconfigure $f -encoding utf-8 -buffersize 10
+    set in [read $f]
+    close $f
+    scan [string index $in end] %c
+} 194
+test io-12.10 {ReadChars: multibyte chars split} {
+    set f [open $path(test1) w]
+    fconfigure $f -translation binary
+    puts -nonewline $f [string repeat a 9]\xc2
+    close $f
+    set f [open $path(test1)]
+    fconfigure $f -encoding utf-8 -buffersize 11
+    set in [read $f]
+    close $f
+    scan [string index $in end] %c
+} 194
+
+test io-13.1 {TranslateInputEOL: cr mode} {} {
+    set f [open $path(test1) w]
+    fconfigure $f -translation lf
+    puts -nonewline $f "abcd\rdef\r"
+    close $f
+    set f [open $path(test1)]
+    fconfigure $f -translation cr
+    set x [read $f]
+    close $f
+    set x
+} "abcd\ndef\n"
+test io-13.2 {TranslateInputEOL: crlf mode} {
+    set f [open $path(test1) w]
+    fconfigure $f -translation lf
+    puts -nonewline $f "abcd\r\ndef\r\n"
+    close $f
+    set f [open $path(test1)]
+    fconfigure $f -translation crlf
+    set x [read $f]
+    close $f
+    set x
+} "abcd\ndef\n"
+test io-13.3 {TranslateInputEOL: crlf mode: naked cr} {
+    # (src >= srcMax) 
+
+    set f [open $path(test1) w]
+    fconfigure $f -translation lf
+    puts -nonewline $f "abcd\r\ndef\r"
+    close $f
+    set f [open $path(test1)]
+    fconfigure $f -translation crlf
+    set x [read $f]
+    close $f
+    set x
+} "abcd\ndef\r"
+test io-13.4 {TranslateInputEOL: crlf mode: cr followed by not \n} {
+    # (src >= srcMax) 
+
+    set f [open $path(test1) w]
+    fconfigure $f -translation lf
+    puts -nonewline $f "abcd\r\ndef\rfgh"
+    close $f
+    set f [open $path(test1)]
+    fconfigure $f -translation crlf
+    set x [read $f]
+    close $f
+    set x
+} "abcd\ndef\rfgh"
+test io-13.5 {TranslateInputEOL: crlf mode: naked lf} {
+    # (src >= srcMax) 
+
+    set f [open $path(test1) w]
+    fconfigure $f -translation lf
+    puts -nonewline $f "abcd\r\ndef\nfgh"
+    close $f
+    set f [open $path(test1)]
+    fconfigure $f -translation crlf
+    set x [read $f]
+    close $f
+    set x
+} "abcd\ndef\nfgh"
+test io-13.6 {TranslateInputEOL: auto mode: saw cr in last segment} {stdio testchannel openpipe fileevent} {
+    # (chanPtr->flags & INPUT_SAW_CR)
+    # This test may fail on slower machines.
+
+    set f [open "|[list [interpreter] $path(cat)]" w+]
+    fconfigure $f -blocking 0 -buffering none -translation {auto lf}
+
+    fileevent $f read [namespace code "ready $f"]
+    proc ready {f} {
+	variable x
+	lappend x [read $f] [testchannel queuedcr $f]
+    }
+    variable x {}
+    variable y {}
+
+    puts -nonewline $f "abcdefghj\r"
+    after 500 [namespace code {set y ok}]
+    vwait [namespace which -variable y]
+
+    puts -nonewline $f "\n01234"
+    after 500 [namespace code {set y ok}]
+    vwait [namespace which -variable y]
+
+    close $f
+    set x
+} [list "abcdefghj\n" 1 "01234" 0]
+test io-13.7 {TranslateInputEOL: auto mode: naked \r} {testchannel openpipe} {
+    # (src >= srcMax)
+
+    set f [open $path(test1) w]
+    fconfigure $f -translation lf
+    puts -nonewline $f "abcd\r"
+    close $f
+    set f [open $path(test1)]
+    fconfigure $f -translation auto
+    set x [list [read $f] [testchannel queuedcr $f]]
+    close $f
+    set x
+} [list "abcd\n" 1]
+test io-13.8 {TranslateInputEOL: auto mode: \r\n} {
+    # (*src == '\n')
+
+    set f [open $path(test1) w]
+    fconfigure $f -translation lf
+    puts -nonewline $f "abcd\r\ndef"
+    close $f
+    set f [open $path(test1)]
+    fconfigure $f -translation auto
+    set x [read $f]
+    close $f
+    set x
+} "abcd\ndef"
+test io-13.8.1 {TranslateInputEOL: auto mode: \r\n} {
+    set f [open $path(test1) w]
+    fconfigure $f -translation lf
+    puts -nonewline $f "abcd\r\ndef"
+    close $f
+    set f [open $path(test1)]
+    fconfigure $f -translation auto
+    set x {}
+    lappend x [read $f 5]
+    lappend x [read $f]
+    close $f
+    set x
+} [list "abcd\n" "def"]
+test io-13.8.2 {TranslateInputEOL: auto mode: \r\n} {
+    set f [open $path(test1) w]
+    fconfigure $f -translation lf
+    puts -nonewline $f "abcd\r\ndef"
+    close $f
+    set f [open $path(test1)]
+    fconfigure $f -translation auto -buffersize 6
+    set x {}
+    lappend x [read $f 5]
+    lappend x [read $f]
+    close $f
+    set x
+} [list "abcd\n" "def"]
+test io-13.8.3 {TranslateInputEOL: auto mode: \r\n} {
+    set f [open $path(test1) w]
+    fconfigure $f -translation lf
+    puts -nonewline $f "abcd\r\n\r\ndef"
+    close $f
+    set f [open $path(test1)]
+    fconfigure $f -translation auto -buffersize 7
+    set x {}
+    lappend x [read $f 5]
+    lappend x [read $f]
+    close $f
+    set x
+} [list "abcd\n" "\ndef"]
+test io-13.9 {TranslateInputEOL: auto mode: \r followed by not \n} {
+    set f [open $path(test1) w]
+    fconfigure $f -translation lf
+    puts -nonewline $f "abcd\rdef"
+    close $f
+    set f [open $path(test1)]
+    fconfigure $f -translation auto
+    set x [read $f]
+    close $f
+    set x
+} "abcd\ndef"
+test io-13.10 {TranslateInputEOL: auto mode: \n} {
+    # not (*src == '\r') 
+
+    set f [open $path(test1) w]
+    fconfigure $f -translation lf
+    puts -nonewline $f "abcd\ndef"
+    close $f
+    set f [open $path(test1)]
+    fconfigure $f -translation auto
+    set x [read $f]
+    close $f
+    set x
+} "abcd\ndef"
+test io-13.11 {TranslateInputEOL: EOF char} {
+    # (*chanPtr->inEofChar != '\0')
+
+    set f [open $path(test1) w]
+    fconfigure $f -translation lf
+    puts -nonewline $f "abcd\ndefgh"
+    close $f
+    set f [open $path(test1)]
+    fconfigure $f -translation auto -eofchar e
+    set x [read $f]
+    close $f
+    set x
+} "abcd\nd"
+test io-13.12 {TranslateInputEOL: find EOF char in src} {
+    # (*chanPtr->inEofChar != '\0')
+
+    set f [open $path(test1) w]
+    fconfigure $f -translation lf
+    puts -nonewline $f "\r\n\r\n\r\nab\r\n\r\ndef\r\n\r\n\r\n"
+    close $f
+    set f [open $path(test1)]
+    fconfigure $f -translation auto -eofchar e
+    set x [read $f]
+    close $f
+    set x
+} "\n\n\nab\n\nd"
+
+# Test standard handle management. The functions tested are
+# Tcl_SetStdChannel and Tcl_GetStdChannel. Incidentally we are
+# also testing channel table management.
+
+if {[info commands testchannel] != ""} {
+    set consoleFileNames [lsort [testchannel open]]
+} else {
+    # just to avoid an error
+    set consoleFileNames [list]
+}
+
+test io-14.1 {Tcl_SetStdChannel and Tcl_GetStdChannel} {testchannel} {
+    set l ""
+    lappend l [fconfigure stdin -buffering]
+    lappend l [fconfigure stdout -buffering]
+    lappend l [fconfigure stderr -buffering]
+    lappend l [lsort [testchannel open]]
+    set l
+} [list line line none $consoleFileNames]
+test io-14.2 {Tcl_SetStdChannel and Tcl_GetStdChannel} {
+    interp create x
+    set l ""
+    lappend l [x eval {fconfigure stdin -buffering}]
+    lappend l [x eval {fconfigure stdout -buffering}]
+    lappend l [x eval {fconfigure stderr -buffering}]
+    interp delete x
+    set l
+} {line line none}
+set path(test3) [makeFile {} test3]
+test io-14.3 {Tcl_SetStdChannel & Tcl_GetStdChannel} {exec openpipe} {
+    set f [open $path(test1) w]
+    puts -nonewline $f {
+	close stdin
+	close stdout
+	close stderr
+	set f  [}
+    puts $f [list open $path(test1) r]]
+    puts $f "set f2 \[[list open $path(test2) w]]"
+    puts $f "set f3 \[[list open $path(test3) w]]"
+    puts $f {	puts stdout [gets stdin]
+	puts stdout out
+	puts stderr err
+	close $f
+	close $f2
+	close $f3
+    }
+    close $f
+    set result [exec [interpreter] $path(test1)]
+    set f  [open $path(test2) r]
+    set f2 [open $path(test3) r]
+    lappend result [read $f] [read $f2]
+    close $f
+    close $f2
+    set result
+} {{
+out
+} {err
+}}
+# This test relies on the fact that stdout is used before stderr
+test io-14.4 {Tcl_SetStdChannel & Tcl_GetStdChannel} {exec} {
+    set f [open $path(test1) w]
+    puts -nonewline $f { close stdin
+	close stdout
+	close stderr
+	set f  [}
+    puts $f [list open $path(test1) r]]
+    puts $f "set f2 \[[list open $path(test2) w]]"
+    puts $f "set f3 \[[list open $path(test3) w]]"
+    puts $f {	puts stdout [gets stdin]
+	puts stdout $f2
+	puts stderr $f3
+	close $f
+	close $f2
+	close $f3
+    }
+    close $f
+    set result [exec [interpreter] $path(test1)]
+    set f  [open $path(test2) r]
+    set f2 [open $path(test3) r]
+    lappend result [read $f] [read $f2]
+    close $f
+    close $f2
+    set result
+} {{ close stdin
+stdout
+} {stderr
+}}
+catch {interp delete z}
+test io-14.5 {Tcl_GetChannel: stdio name translation} {
+    interp create z
+    eof stdin
+    catch {z eval flush stdin} msg1
+    catch {z eval close stdin} msg2
+    catch {z eval flush stdin} msg3
+    set result [list $msg1 $msg2 $msg3]
+    interp delete z
+    set result
+} {{channel "stdin" wasn't opened for writing} {} {can not find channel named "stdin"}}
+test io-14.6 {Tcl_GetChannel: stdio name translation} {
+    interp create z
+    eof stdout
+    catch {z eval flush stdout} msg1
+    catch {z eval close stdout} msg2
+    catch {z eval flush stdout} msg3
+    set result [list $msg1 $msg2 $msg3]
+    interp delete z
+    set result
+} {{} {} {can not find channel named "stdout"}}
+test io-14.7 {Tcl_GetChannel: stdio name translation} {
+    interp create z
+    eof stderr
+    catch {z eval flush stderr} msg1
+    catch {z eval close stderr} msg2
+    catch {z eval flush stderr} msg3
+    set result [list $msg1 $msg2 $msg3]
+    interp delete z
+    set result
+} {{} {} {can not find channel named "stderr"}}
+set path(script) [makeFile {} script]
+test io-14.8 {reuse of stdio special channels} {stdio openpipe} {
+    file delete $path(script)
+    file delete $path(test1)
+    set f [open $path(script) w]
+    puts -nonewline $f {
+	close stderr
+	set f [}
+    puts $f [list open $path(test1) w]]
+    puts -nonewline $f {
+	puts stderr hello
+	close $f
+	set f [}
+    puts $f [list open $path(test1) r]]
+    puts $f {
+	puts [gets $f]
+    }
+    close $f
+    set f [open "|[list [interpreter] $path(script)]" r]
+    set c [gets $f]
+    close $f
+    set c
+} hello
+test io-14.9 {reuse of stdio special channels} {stdio openpipe fileevent} {
+    file delete $path(script)
+    file delete $path(test1)
+    set f [open $path(script) w]
+    puts $f {
+        array set path [lindex $argv 0]
+	set f [open $path(test1) w]
+	puts $f hello
+	close $f
+	close stderr
+	set f [open "|[list [info nameofexecutable] $path(cat) $path(test1)]" r]
+	puts [gets $f]
+    }
+    close $f
+    set f [open "|[list [interpreter] $path(script) [array get path]]" r]
+    set c [gets $f]
+    close $f
+    # Added delay to give Windows time to stop the spawned process and clean
+    # up its grip on the file test1. Added delete as proper test cleanup.
+    # The failing tests were 18.1 and 18.2 as first re-users of file "test1".
+    after 10000
+    file delete $path(script)
+    file delete $path(test1)
+    set c
+} hello
+
+test io-15.1 {Tcl_CreateCloseHandler} emptyTest {
+} {}
+
+test io-16.1 {Tcl_DeleteCloseHandler} emptyTest {
+} {}
+
+# Test channel table management. The functions tested are
+# GetChannelTable, DeleteChannelTable, Tcl_RegisterChannel,
+# Tcl_UnregisterChannel, Tcl_GetChannel and Tcl_CreateChannel.
+#
+# These functions use "eof stdin" to ensure that the standard
+# channels are added to the channel table of the interpreter.
+
+test io-17.1 {GetChannelTable, DeleteChannelTable on std handles} {testchannel} {
+    set l1 [testchannel refcount stdin]
+    eof stdin
+    interp create x
+    set l ""
+    lappend l [expr [testchannel refcount stdin] - $l1]
+    x eval {eof stdin}
+    lappend l [expr [testchannel refcount stdin] - $l1]
+    interp delete x
+    lappend l [expr [testchannel refcount stdin] - $l1]
+    set l
+} {0 1 0}
+test io-17.2 {GetChannelTable, DeleteChannelTable on std handles} {testchannel} {
+    set l1 [testchannel refcount stdout]
+    eof stdin
+    interp create x
+    set l ""
+    lappend l [expr [testchannel refcount stdout] - $l1]
+    x eval {eof stdout}
+    lappend l [expr [testchannel refcount stdout] - $l1]
+    interp delete x
+    lappend l [expr [testchannel refcount stdout] - $l1]
+    set l
+} {0 1 0}
+test io-17.3 {GetChannelTable, DeleteChannelTable on std handles} {testchannel} {
+    set l1 [testchannel refcount stderr]
+    eof stdin
+    interp create x
+    set l ""
+    lappend l [expr [testchannel refcount stderr] - $l1]
+    x eval {eof stderr}
+    lappend l [expr [testchannel refcount stderr] - $l1]
+    interp delete x
+    lappend l [expr [testchannel refcount stderr] - $l1]
+    set l
+} {0 1 0}
+
+test io-18.1 {Tcl_RegisterChannel, Tcl_UnregisterChannel} {testchannel} {
+    file delete -force $path(test1)
+    set l ""
+    set f [open $path(test1) w]
+    lappend l [lindex [testchannel info $f] 15]
+    close $f
+    if {[catch {lindex [testchannel info $f] 15} msg]} {
+	lappend l $msg
+    } else {
+	lappend l "very broken: $f found after being closed"
+    }
+    string compare [string tolower $l] \
+	[list 1 [format "can not find channel named \"%s\"" $f]]
+} 0
+test io-18.2 {Tcl_RegisterChannel, Tcl_UnregisterChannel} {testchannel} {
+    file delete -force $path(test1)
+    set l ""
+    set f [open $path(test1) w]
+    lappend l [lindex [testchannel info $f] 15]
+    interp create x
+    interp share "" $f x
+    lappend l [lindex [testchannel info $f] 15]
+    x eval close $f
+    lappend l [lindex [testchannel info $f] 15]
+    interp delete x
+    lappend l [lindex [testchannel info $f] 15]
+    close $f
+    if {[catch {lindex [testchannel info $f] 15} msg]} {
+	lappend l $msg
+    } else {
+	lappend l "very broken: $f found after being closed"
+    }
+    string compare [string tolower $l] \
+	[list 1 2 1 1 [format "can not find channel named \"%s\"" $f]]
+} 0
+test io-18.3 {Tcl_RegisterChannel, Tcl_UnregisterChannel} {testchannel} {
+    file delete $path(test1)
+    set l ""
+    set f [open $path(test1) w]
+    lappend l [lindex [testchannel info $f] 15]
+    interp create x
+    interp share "" $f x
+    lappend l [lindex [testchannel info $f] 15]
+    interp delete x
+    lappend l [lindex [testchannel info $f] 15]
+    close $f
+    if {[catch {lindex [testchannel info $f] 15} msg]} {
+	lappend l $msg
+    } else {
+	lappend l "very broken: $f found after being closed"
+    }
+    string compare [string tolower $l] \
+	[list 1 2 1 [format "can not find channel named \"%s\"" $f]]
+} 0
+
+test io-19.1 {Tcl_GetChannel->Tcl_GetStdChannel, standard handles} {
+    eof stdin
+} 0
+test io-19.2 {testing Tcl_GetChannel, user opened handle} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    set x [eof $f]
+    close $f
+    set x
+} 0
+test io-19.3 {Tcl_GetChannel, channel not found} {
+    list [catch {eof file34} msg] $msg
+} {1 {can not find channel named "file34"}}
+test io-19.4 {Tcl_CreateChannel, insertion into channel table} {testchannel} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    set l ""
+    lappend l [eof $f]
+    close $f
+    if {[catch {lindex [testchannel info $f] 15} msg]} {
+	lappend l $msg
+    } else {
+	lappend l "very broken: $f found after being closed"
+    }
+    string compare [string tolower $l] \
+	[list 0 [format "can not find channel named \"%s\"" $f]]
+} 0
+
+test io-20.1 {Tcl_CreateChannel: initial settings} {
+	set a [open $path(test2) w]
+    set old [encoding system]
+    encoding system ascii
+    set f [open $path(test1) w]
+    set x [fconfigure $f -encoding]
+    close $f
+    encoding system $old
+	close $a
+    set x
+} {ascii}    
+test io-20.2 {Tcl_CreateChannel: initial settings} {win} {
+    set f [open $path(test1) w+]
+    set x [list [fconfigure $f -eofchar] [fconfigure $f -translation]]
+    close $f
+    set x
+} [list [list \x1a ""] {auto crlf}]
+test io-20.3 {Tcl_CreateChannel: initial settings} {unix} {
+    set f [open $path(test1) w+]
+    set x [list [fconfigure $f -eofchar] [fconfigure $f -translation]]
+    close $f
+    set x
+} {{{} {}} {auto lf}}
+set path(stdout) [makeFile {} stdout]
+test io-20.5 {Tcl_CreateChannel: install channel in empty slot} {stdio openpipe} {
+    set f [open $path(script) w]
+    puts -nonewline $f {
+	close stdout
+	set f1 [}
+    puts $f [list open $path(stdout) w]]
+    puts $f {
+	fconfigure $f1 -buffersize 777
+	puts stderr [fconfigure stdout -buffersize]
+    }
+    close $f
+    set f [open "|[list [interpreter] $path(script)]"]
+    catch {close $f} msg
+    set msg
+} {777}
+
+test io-21.1 {CloseChannelsOnExit} emptyTest {
+} {}
+
+# Test management of attributes associated with a channel, such as
+# its default translation, its name and type, etc. The functions
+# tested in this group are Tcl_GetChannelName,
+# Tcl_GetChannelType and Tcl_GetChannelFile. Tcl_GetChannelInstanceData
+# not tested because files do not use the instance data.
+
+test io-22.1 {Tcl_GetChannelMode} emptyTest {
+    # Not used anywhere in Tcl.
+} {}
+
+test io-23.1 {Tcl_GetChannelName} {testchannel} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    set n [testchannel name $f]
+    close $f
+    string compare $n $f
+} 0
+
+test io-24.1 {Tcl_GetChannelType} {testchannel} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    set t [testchannel type $f]
+    close $f
+    string compare $t file
+} 0
+
+test io-25.1 {Tcl_GetChannelHandle, input} {testchannel} {
+    set f [open $path(test1) w]
+    fconfigure $f -translation lf -eofchar {}
+    puts $f "1234567890\n098765432"
+    close $f
+    set f [open $path(test1) r]
+    gets $f
+    set l ""
+    lappend l [testchannel inputbuffered $f]
+    lappend l [tell $f]
+    close $f
+    set l
+} {10 11}
+test io-25.2 {Tcl_GetChannelHandle, output} {testchannel} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    fconfigure $f -translation lf
+    puts $f hello
+    set l ""
+    lappend l [testchannel outputbuffered $f]
+    lappend l [tell $f]
+    flush $f
+    lappend l [testchannel outputbuffered $f]
+    lappend l [tell $f]
+    close $f
+    file delete $path(test1)
+    set l
+} {6 6 0 6}
+
+test io-26.1 {Tcl_GetChannelInstanceData} {stdio openpipe} {
+    # "pid" command uses Tcl_GetChannelInstanceData
+    # Don't care what pid is (but must be a number), just want to exercise it.
+
+    set f [open "|[list [interpreter] << exit]"]
+    expr [pid $f]
+    close $f
+} {}    
+
+# Test flushing. The functions tested here are FlushChannel.
+
+test io-27.1 {FlushChannel, no output buffered} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    flush $f
+    set s [file size $path(test1)]
+    close $f
+    set s
+} 0
+test io-27.2 {FlushChannel, some output buffered} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    fconfigure $f -translation lf -eofchar {}
+    set l ""
+    puts $f hello
+    lappend l [file size $path(test1)]
+    flush $f
+    lappend l [file size $path(test1)]
+    close $f
+    lappend l [file size $path(test1)]
+    set l
+} {0 6 6}
+test io-27.3 {FlushChannel, implicit flush on close} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    fconfigure $f -translation lf -eofchar {}
+    set l ""
+    puts $f hello
+    lappend l [file size $path(test1)]
+    close $f
+    lappend l [file size $path(test1)]
+    set l
+} {0 6}
+test io-27.4 {FlushChannel, implicit flush when buffer fills} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    fconfigure $f -translation lf -eofchar {}
+    fconfigure $f -buffersize 60
+    set l ""
+    lappend l [file size $path(test1)]
+    for {set i 0} {$i < 12} {incr i} {
+	puts $f hello
+    }
+    lappend l [file size $path(test1)]
+    flush $f
+    lappend l [file size $path(test1)]
+    close $f
+    set l
+} {0 60 72}
+test io-27.5 {FlushChannel, implicit flush when buffer fills and on close} \
+	{unixOrPc} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    fconfigure $f -translation lf -buffersize 60 -eofchar {}
+    set l ""
+    lappend l [file size $path(test1)]
+    for {set i 0} {$i < 12} {incr i} {
+	puts $f hello
+    }
+    lappend l [file size $path(test1)]
+    close $f
+    lappend l [file size $path(test1)]
+    set l
+} {0 60 72}
+set path(pipe)   [makeFile {} pipe]
+set path(output) [makeFile {} output]
+test io-27.6 {FlushChannel, async flushing, async close} \
+	{stdio asyncPipeClose openpipe} {
+    # This test may fail on old Unix systems (seen on IRIX64 6.5) with
+    # obsolete gettimeofday() calls.  See Tcl Bugs 3530533, 1942197.
+    file delete $path(pipe)
+    file delete $path(output)
+    set f [open $path(pipe) w]
+    puts $f "set f \[[list open $path(output) w]]"
+    puts $f {
+	fconfigure $f -translation lf -buffering none -eofchar {}
+	while {![eof stdin]} {
+	    after 20
+	    puts -nonewline $f [read stdin 1024]
+	}
+	close $f
+    }
+    close $f
+    set x 01234567890123456789012345678901
+    for {set i 0} {$i < 11} {incr i} {
+        set x "$x$x"
+    }
+    set f [open $path(output) w]
+    close $f
+    set f [open "|[list [interpreter] $path(pipe)]" w]
+    fconfigure $f -blocking off
+    puts -nonewline $f $x
+    close $f
+    set counter 0
+    while {([file size $path(output)] < 65536) && ($counter < 1000)} {
+	after 20 [list incr [namespace which -variable counter]]
+	vwait [namespace which -variable counter]
+    }
+    if {$counter == 1000} {
+        set result "file size only [file size $path(output)]"
+    } else {
+        set result ok
+    }
+} ok
+
+# Tests closing a channel. The functions tested are CloseChannel and Tcl_Close.
+
+test io-28.1 {CloseChannel called when all references are dropped} {testchannel} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    interp create x
+    interp share "" $f x
+    set l ""
+    lappend l [testchannel refcount $f]
+    x eval close $f
+    interp delete x
+    lappend l [testchannel refcount $f]
+    close $f
+    set l
+} {2 1}
+test io-28.2 {CloseChannel called when all references are dropped} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    interp create x
+    interp share "" $f x
+    puts -nonewline $f abc
+    close $f
+    x eval puts $f def
+    x eval close $f
+    interp delete x
+    set f [open $path(test1) r]
+    set l [gets $f]
+    close $f
+    set l
+} abcdef
+test io-28.3 {CloseChannel, not called before output queue is empty} \
+	{stdio asyncPipeClose nonPortable openpipe} {
+    file delete $path(pipe)
+    file delete $path(output)
+    set f [open $path(pipe) w]
+    puts $f {
+
+	# Need to not have eof char appended on close, because the other
+	# side of the pipe already closed, so that writing would cause an
+	# error "invalid file".
+
+	fconfigure stdout -eofchar {}
+	fconfigure stderr -eofchar {}
+
+	set f [open $path(output) w]
+	fconfigure $f -translation lf -buffering none
+	for {set x 0} {$x < 20} {incr x} {
+	    after 20
+	    puts -nonewline $f [read stdin 1024]
+	}
+	close $f
+    }
+    close $f
+    set x 01234567890123456789012345678901
+    for {set i 0} {$i < 11} {incr i} {
+        set x "$x$x"
+    }
+    set f [open $path(output) w]
+    close $f
+    set f [open "|[list [interpreter] pipe]" r+]
+    fconfigure $f -blocking off -eofchar {}
+
+    puts -nonewline $f $x
+    close $f
+    set counter 0
+    while {([file size $path(output)] < 20480) && ($counter < 1000)} {
+	after 20 [list incr [namespace which -variable counter]]
+	vwait [namespace which -variable counter]
+    }
+    if {$counter == 1000} {
+        set result probably_broken
+    } else {
+        set result ok
+    }
+} ok
+test io-28.4 {Tcl_Close} {testchannel} {
+    file delete $path(test1)
+    set l ""
+    lappend l [lsort [testchannel open]]
+    set f [open $path(test1) w]
+    lappend l [lsort [testchannel open]]
+    close $f
+    lappend l [lsort [testchannel open]]
+    set x [list $consoleFileNames \
+		[lsort [list {*}$consoleFileNames $f]] \
+		$consoleFileNames]
+    string compare $l $x
+} 0
+test io-28.5 {Tcl_Close vs standard handles} {stdio unix testchannel openpipe} {
+    file delete $path(script)
+    set f [open $path(script) w]
+    puts $f {
+	close stdin
+	puts [testchannel open]
+    }
+    close $f
+    set f [open "|[list [interpreter] $path(script)]" r]
+    set l [gets $f]
+    close $f
+    lsort $l
+} {file1 file2}
+
+test io-29.1 {Tcl_WriteChars, channel not writable} {
+    list [catch {puts stdin hello} msg] $msg
+} {1 {channel "stdin" wasn't opened for writing}}
+test io-29.2 {Tcl_WriteChars, empty string} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    fconfigure $f -eofchar {}
+    puts -nonewline $f ""
+    close $f
+    file size $path(test1)
+} 0
+test io-29.3 {Tcl_WriteChars, nonempty string} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    fconfigure $f -eofchar {}
+    puts -nonewline $f hello
+    close $f
+    file size $path(test1)
+} 5
+test io-29.4 {Tcl_WriteChars, buffering in full buffering mode} {testchannel} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    fconfigure $f -translation lf -buffering full -eofchar {}
+    puts $f hello
+    set l ""
+    lappend l [testchannel outputbuffered $f]
+    lappend l [file size $path(test1)]
+    flush $f
+    lappend l [testchannel outputbuffered $f]
+    lappend l [file size $path(test1)]
+    close $f
+    set l
+} {6 0 0 6}
+test io-29.5 {Tcl_WriteChars, buffering in line buffering mode} {testchannel} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    fconfigure $f -translation lf -buffering line -eofchar {}
+    puts -nonewline $f hello
+    set l ""
+    lappend l [testchannel outputbuffered $f]
+    lappend l [file size $path(test1)]
+    puts $f hello
+    lappend l [testchannel outputbuffered $f]
+    lappend l [file size $path(test1)]
+    close $f
+    set l
+} {5 0 0 11}
+test io-29.6 {Tcl_WriteChars, buffering in no buffering mode} {testchannel} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    fconfigure $f -translation lf -buffering none -eofchar {}
+    puts -nonewline $f hello
+    set l ""
+    lappend l [testchannel outputbuffered $f]
+    lappend l [file size $path(test1)]
+    puts $f hello
+    lappend l [testchannel outputbuffered $f]
+    lappend l [file size $path(test1)]
+    close $f
+    set l
+} {0 5 0 11}
+test io-29.7 {Tcl_Flush, full buffering} {testchannel} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    fconfigure $f -translation lf -buffering full -eofchar {}
+    puts -nonewline $f hello
+    set l ""
+    lappend l [testchannel outputbuffered $f]
+    lappend l [file size $path(test1)]
+    puts $f hello
+    lappend l [testchannel outputbuffered $f]
+    lappend l [file size $path(test1)]
+    flush $f
+    lappend l [testchannel outputbuffered $f]
+    lappend l [file size $path(test1)]
+    close $f
+    set l
+} {5 0 11 0 0 11}
+test io-29.8 {Tcl_Flush, full buffering} {testchannel} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    fconfigure $f -translation lf -buffering line
+    puts -nonewline $f hello
+    set l ""
+    lappend l [testchannel outputbuffered $f]
+    lappend l [file size $path(test1)]
+    flush $f
+    lappend l [testchannel outputbuffered $f]
+    lappend l [file size $path(test1)]
+    puts $f hello
+    lappend l [testchannel outputbuffered $f]
+    lappend l [file size $path(test1)]
+    flush $f
+    lappend l [testchannel outputbuffered $f]
+    lappend l [file size $path(test1)]
+    close $f
+    set l
+} {5 0 0 5 0 11 0 11}
+test io-29.9 {Tcl_Flush, channel not writable} {
+    list [catch {flush stdin} msg] $msg
+} {1 {channel "stdin" wasn't opened for writing}}
+test io-29.10 {Tcl_WriteChars, looping and buffering} {
+    file delete $path(test1)
+    set f1 [open $path(test1) w]
+    fconfigure $f1 -translation lf -eofchar {}
+    set f2 [open $path(longfile) r]
+    for {set x 0} {$x < 10} {incr x} {
+	puts $f1 [gets $f2]
+    }
+    close $f2
+    close $f1
+    file size $path(test1)
+} 387
+test io-29.11 {Tcl_WriteChars, no newline, implicit flush} {
+    file delete $path(test1)
+    set f1 [open $path(test1) w]
+    fconfigure $f1 -eofchar {}
+    set f2 [open $path(longfile) r]
+    for {set x 0} {$x < 10} {incr x} {
+	puts -nonewline $f1 [gets $f2]
+    }
+    close $f1
+    close $f2
+    file size $path(test1)
+} 377
+test io-29.12 {Tcl_WriteChars on a pipe} {stdio openpipe} {
+    file delete $path(test1)
+    file delete $path(pipe)
+    set f1 [open $path(pipe) w]
+    puts $f1 "set f1 \[[list open $path(longfile) r]]"
+    puts $f1 {
+	for {set x 0} {$x < 10} {incr x} {
+	    puts [gets $f1]
+	}
+    }
+    close $f1
+    set f1 [open "|[list [interpreter] $path(pipe)]" r]
+    set f2 [open $path(longfile) r]
+    set y ok
+    for {set x 0} {$x < 10} {incr x} {
+	set l1 [gets $f1]
+	set l2 [gets $f2]
+	if {"$l1" != "$l2"} {
+	    set y broken
+	}
+    }
+    close $f1
+    close $f2
+    set y
+} ok
+test io-29.13 {Tcl_WriteChars to a pipe, line buffered} {stdio openpipe} {
+    file delete $path(test1)
+    file delete $path(pipe)
+    set f1 [open $path(pipe) w]
+    puts $f1 {
+	puts [gets stdin]
+	puts [gets stdin]
+    }
+    close $f1
+    set y ok
+    set f1 [open "|[list [interpreter] $path(pipe)]" r+]
+    fconfigure $f1 -buffering line
+    set f2 [open $path(longfile) r]
+    set line [gets $f2]
+    puts $f1 $line
+    set backline [gets $f1]
+    if {"$line" != "$backline"} {
+	set y broken
+    }
+    set line [gets $f2]
+    puts $f1 $line
+    set backline [gets $f1]
+    if {"$line" != "$backline"} {
+	set y broken
+    }
+    close $f1
+    close $f2
+    set y
+} ok
+test io-29.14 {Tcl_WriteChars, buffering and implicit flush at close} {
+    file delete $path(test3)
+    set f [open $path(test3) w]
+    puts -nonewline $f "Text1"
+    puts -nonewline $f " Text 2"
+    puts $f " Text 3"
+    close $f
+    set f [open $path(test3) r]
+    set x [gets $f]
+    close $f
+    set x
+} {Text1 Text 2 Text 3}
+test io-29.15 {Tcl_Flush, channel not open for writing} {
+    file delete $path(test1)
+    set fd [open $path(test1) w]
+    close $fd
+    set fd [open $path(test1) r]
+    set x [list [catch {flush $fd} msg] $msg]
+    close $fd
+    string compare $x \
+	[list 1 "channel \"$fd\" wasn't opened for writing"]
+} 0
+test io-29.16 {Tcl_Flush on pipe opened only for reading} {stdio openpipe} {
+    set fd [open "|[list [interpreter] cat longfile]" r]
+    set x [list [catch {flush $fd} msg] $msg]
+    catch {close $fd}
+    string compare $x \
+	[list 1 "channel \"$fd\" wasn't opened for writing"]
+} 0
+test io-29.17 {Tcl_WriteChars buffers, then Tcl_Flush flushes} {
+    file delete $path(test1)
+    set f1 [open $path(test1) w]
+    fconfigure $f1 -translation lf
+    puts $f1 hello
+    puts $f1 hello
+    puts $f1 hello
+    flush $f1
+    set x [file size $path(test1)]
+    close $f1
+    set x
+} 18
+test io-29.18 {Tcl_WriteChars and Tcl_Flush intermixed} {
+    file delete $path(test1)
+    set x ""
+    set f1 [open $path(test1) w]
+    fconfigure $f1 -translation lf
+    puts $f1 hello
+    puts $f1 hello
+    puts $f1 hello
+    flush $f1
+    lappend x [file size $path(test1)]
+    puts $f1 hello
+    flush $f1
+    lappend x [file size $path(test1)]
+    puts $f1 hello
+    flush $f1
+    lappend x [file size $path(test1)]
+    close $f1
+    set x
+} {18 24 30}
+test io-29.19 {Explicit and implicit flushes} {
+    file delete $path(test1)
+    set f1 [open $path(test1) w]
+    fconfigure $f1 -translation lf -eofchar {}
+    set x ""
+    puts $f1 hello
+    puts $f1 hello
+    puts $f1 hello
+    flush $f1
+    lappend x [file size $path(test1)]
+    puts $f1 hello
+    flush $f1
+    lappend x [file size $path(test1)]
+    puts $f1 hello
+    close $f1
+    lappend x [file size $path(test1)]
+    set x
+} {18 24 30}
+test io-29.20 {Implicit flush when buffer is full} {
+    file delete $path(test1)
+    set f1 [open $path(test1) w]
+    fconfigure $f1 -translation lf -eofchar {}
+    set line "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
+    for {set x 0} {$x < 100} {incr x} {
+      puts $f1 $line
+    }
+    set z ""
+    lappend z [file size $path(test1)]
+    for {set x 0} {$x < 100} {incr x} {
+	puts $f1 $line
+    }
+    lappend z [file size $path(test1)]
+    close $f1
+    lappend z [file size $path(test1)]
+    set z
+} {4096 12288 12600}
+test io-29.21 {Tcl_Flush to pipe} {stdio openpipe} {
+    file delete $path(pipe)
+    set f1 [open $path(pipe) w]
+    puts $f1 {set x [read stdin 6]}
+    puts $f1 {set cnt [string length $x]}
+    puts $f1 {puts "read $cnt characters"}
+    close $f1
+    set f1 [open "|[list [interpreter] $path(pipe)]" r+]
+    puts $f1 hello
+    flush $f1
+    set x [gets $f1]
+    catch {close $f1}
+    set x
+} "read 6 characters"
+test io-29.22 {Tcl_Flush called at other end of pipe} {stdio openpipe} {
+    file delete $path(pipe)
+    set f1 [open $path(pipe) w]
+    puts $f1 {
+	fconfigure stdout -buffering full
+	puts hello
+	puts hello
+	flush stdout
+	gets stdin
+	puts bye
+	flush stdout
+    }
+    close $f1
+    set f1 [open "|[list [interpreter] $path(pipe)]" r+]
+    set x ""
+    lappend x [gets $f1]
+    lappend x [gets $f1]
+    puts $f1 hello
+    flush $f1
+    lappend x [gets $f1]
+    close $f1
+    set x
+} {hello hello bye}
+test io-29.23 {Tcl_Flush and line buffering at end of pipe} {stdio openpipe} {
+    file delete $path(pipe)
+    set f1 [open $path(pipe) w]
+    puts $f1 {
+	puts hello
+	puts hello
+	gets stdin
+	puts bye
+    }
+    close $f1
+    set f1 [open "|[list [interpreter] $path(pipe)]" r+]
+    set x ""
+    lappend x [gets $f1]
+    lappend x [gets $f1]
+    puts $f1 hello
+    flush $f1
+    lappend x [gets $f1]
+    close $f1
+    set x
+} {hello hello bye}
+test io-29.24 {Tcl_WriteChars and Tcl_Flush move end of file} {
+    set f [open $path(test3) w]
+    puts $f "Line 1"
+    puts $f "Line 2"
+    set f2 [open $path(test3)]
+    set x {}
+    lappend x [read -nonewline $f2]
+    close $f2
+    flush $f
+    set f2 [open $path(test3)]
+    lappend x [read -nonewline $f2]
+    close $f2
+    close $f
+    set x
+} "{} {Line 1\nLine 2}"
+test io-29.25 {Implicit flush with Tcl_Flush to command pipelines} {stdio openpipe fileevent} {
+    file delete $path(test3)
+    set f [open "|[list [interpreter] $path(cat) | [interpreter] $path(cat) > $path(test3)]" w]
+    puts $f "Line 1"
+    puts $f "Line 2"
+    close $f
+    after 100
+    set f [open $path(test3) r]
+    set x [read $f]
+    close $f
+    set x
+} "Line 1\nLine 2\n"
+test io-29.26 {Tcl_Flush, Tcl_Write on bidirectional pipelines} {stdio unixExecs openpipe} {
+    set f [open "|[list cat -u]" r+]
+    puts $f "Line1"
+    flush $f
+    set x [gets $f]
+    close $f
+    set x
+} {Line1}
+test io-29.27 {Tcl_Flush on closed pipeline} {stdio openpipe} {
+    file delete $path(pipe)
+    set f [open $path(pipe) w]
+    puts $f {exit}
+    close $f
+    set f [open "|[list [interpreter] $path(pipe)]" r+]
+    gets $f
+    puts $f output
+    after 50
+    #
+    # The flush below will get a SIGPIPE. This is an expected part of
+    # test and indicates that the test operates correctly. If you run
+    # this test under a debugger, the signal will by intercepted unless
+    # you disable the debugger's signal interception.
+    #
+    if {[catch {flush $f} msg]} {
+	set x [list 1 $msg $::errorCode]
+	catch {close $f}
+    } else {
+	if {[catch {close $f} msg]} {
+	    set x [list 1 $msg $::errorCode]
+	} else {
+	    set x {this was supposed to fail and did not}
+	}
+    }
+    regsub {".*":} $x {"":} x
+    string tolower $x
+} {1 {error flushing "": broken pipe} {posix epipe {broken pipe}}}
+test io-29.28 {Tcl_WriteChars, lf mode} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    fconfigure $f -translation lf -eofchar {}
+    puts $f hello\nthere\nand\nhere
+    flush $f
+    set s [file size $path(test1)]
+    close $f
+    set s
+} 21
+test io-29.29 {Tcl_WriteChars, cr mode} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    fconfigure $f -translation cr -eofchar {}
+    puts $f hello\nthere\nand\nhere
+    close $f
+    file size $path(test1)
+} 21
+test io-29.30 {Tcl_WriteChars, crlf mode} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    fconfigure $f -translation crlf -eofchar {}
+    puts $f hello\nthere\nand\nhere
+    close $f
+    file size $path(test1)
+} 25
+test io-29.31 {Tcl_WriteChars, background flush} {stdio openpipe} {
+    # This test may fail on old Unix systems (seen on IRIX64 6.5) with
+    # obsolete gettimeofday() calls.  See Tcl Bugs 3530533, 1942197.
+    file delete $path(pipe)
+    file delete $path(output)
+    set f [open $path(pipe) w]
+    puts $f "set f \[[list open $path(output)  w]]"
+    puts $f {fconfigure $f -translation lf}
+    set x [list while {![eof stdin]}]
+    set x "$x {"
+    puts $f $x
+    puts $f {  puts -nonewline $f [read stdin 4096]}
+    puts $f {  flush $f}
+    puts $f "}"
+    puts $f {close $f}
+    close $f
+    set x 01234567890123456789012345678901
+    for {set i 0} {$i < 11} {incr i} {
+	set x "$x$x"
+    }
+    set f [open $path(output) w]
+    close $f
+    set f [open "|[list [interpreter] $path(pipe)]" r+]
+    fconfigure $f -blocking off
+    puts -nonewline $f $x
+    close $f
+    set counter 0
+    while {([file size $path(output)] < 65536) && ($counter < 1000)} {
+	after 10 [list incr [namespace which -variable counter]]
+	vwait [namespace which -variable counter]
+    }
+    if {$counter == 1000} {
+	set result "file size only [file size $path(output)]"
+    } else {
+	set result ok
+    }
+    # allow a little time for the background process to close.
+    # otherwise, the following test fails on the [file delete $path(output)
+    # on Windows because a process still has the file open.
+    after 100 set v 1; vwait v
+    set result
+} ok
+test io-29.32 {Tcl_WriteChars, background flush to slow reader} \
+	{stdio asyncPipeClose openpipe} {
+    # This test may fail on old Unix systems (seen on IRIX64 6.5) with
+    # obsolete gettimeofday() calls.  See Tcl Bugs 3530533, 1942197.
+    file delete $path(pipe)
+    file delete $path(output)
+    set f [open $path(pipe) w]
+    puts $f "set f \[[list open $path(output) w]]"
+    puts $f {fconfigure $f -translation lf}
+    set x [list while {![eof stdin]}]
+    set x "$x \{"
+    puts $f $x
+    puts $f {  after 20}
+    puts $f {  puts -nonewline $f [read stdin 1024]}
+    puts $f {  flush $f}
+    puts $f "\}"
+    puts $f {close $f}
+    close $f
+    set x 01234567890123456789012345678901
+    for {set i 0} {$i < 11} {incr i} {
+	set x "$x$x"
+    }
+    set f [open $path(output) w]
+    close $f
+    set f [open "|[list [interpreter] $path(pipe)]" r+]
+    fconfigure $f -blocking off
+    puts -nonewline $f $x
+    close $f
+    set counter 0
+    while {([file size $path(output)] < 65536) && ($counter < 1000)} {
+	after 20 [list incr [namespace which -variable counter]]
+	vwait [namespace which -variable counter]
+    }
+    if {$counter == 1000} {
+	set result "file size only [file size $path(output)]"
+    } else {
+	set result ok
+    }
+} ok
+test io-29.33 {Tcl_Flush, implicit flush on exit} {exec} {
+    set f [open $path(script) w]
+    puts $f "set f \[[list open $path(test1) w]]"
+    puts $f {fconfigure $f -translation lf
+	puts $f hello
+	puts $f bye
+	puts $f strange
+    }
+    close $f
+    exec [interpreter] $path(script)
+    set f [open $path(test1) r]
+    set r [read $f]
+    close $f
+    set r
+} "hello\nbye\nstrange\n"
+set path(script2) [makeFile {} script2]
+test io-29.33b {TIP#398, no implicit flush of nonblocking on exit} {exec} {
+    set f [open $path(script) w]
+    puts $f {
+		fconfigure stdout -blocking 0
+		puts -nonewline stdout [string repeat A 655360]
+		flush stdout
+	}
+    close $f
+    set f [open $path(script2) w]
+    puts $f {after 2000}
+    close $f
+	set t1 [clock milliseconds]
+	set ff [open "|[list [interpreter] $path(script2)]" w]
+	catch {unset ::env(TCL_FLUSH_NONBLOCKING_ON_EXIT)}
+	exec [interpreter] $path(script) >@ $ff
+	set t2 [clock milliseconds]
+	close $ff
+	expr {($t2-$t1)/2000 ? $t2-$t1 : 0}
+} 0
+test io-29.34 {Tcl_Close, async flush on close, using sockets} {socket tempNotMac fileevent} {
+    variable c 0
+    variable x running
+    set l abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz
+    proc writelots {s l} {
+	for {set i 0} {$i < 9000} {incr i} {
+	    puts $s $l
+	}
+    }
+    proc accept {s a p} {
+	variable x
+	fileevent $s readable [namespace code [list readit $s]]
+	fconfigure $s -blocking off
+	set x accepted
+    }
+    proc readit {s} {
+	variable c
+	variable x
+	set l [gets $s]
+
+	if {[eof $s]} {
+	    close $s
+	    set x done
+	} elseif {([string length $l] > 0) || ![fblocked $s]} {
+	    incr c
+	}
+    }
+    set ss [socket -server [namespace code accept] -myaddr 127.0.0.1 0]
+    set cs [socket 127.0.0.1 [lindex [fconfigure $ss -sockname] 2]]
+    vwait [namespace which -variable x]
+    fconfigure $cs -blocking off
+    writelots $cs $l
+    close $cs
+    close $ss
+    vwait [namespace which -variable x]
+    set c
+} 9000
+test io-29.35 {Tcl_Close vs fileevent vs multiple interpreters} {socket tempNotMac fileevent} {
+    # On Mac, this test screws up sockets such that subsequent tests using port 2828
+    # either cause errors or panic().
+
+    catch {interp delete x}
+    catch {interp delete y}
+    interp create x
+    interp create y
+    set s [socket -server [namespace code accept] -myaddr 127.0.0.1 0]
+    proc accept {s a p} {
+	puts $s hello
+	close $s
+    }
+    set c [socket 127.0.0.1 [lindex [fconfigure $s -sockname] 2]]
+    interp share {} $c x
+    interp share {} $c y
+    close $c
+    x eval {
+	proc readit {s} {
+	    gets $s
+	    if {[eof $s]} {
+		close $s
+	    }
+	}
+    }
+    y eval {
+	proc readit {s} {
+	    gets $s
+	    if {[eof $s]} {
+		close $s
+	    }
+	}
+    }
+    x eval "fileevent $c readable \{readit $c\}"
+    y eval "fileevent $c readable \{readit $c\}"
+    y eval [list close $c]
+    update
+    close $s
+    interp delete x
+    interp delete y
+} ""
+
+# Test end of line translations. Procedures tested are Tcl_Write, Tcl_Read.
+
+test io-30.1 {Tcl_Write lf, Tcl_Read lf} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    fconfigure $f -translation lf
+    puts $f hello\nthere\nand\nhere
+    close $f
+    set f [open $path(test1) r]
+    fconfigure $f -translation lf
+    set x [read $f]
+    close $f
+    set x
+} "hello\nthere\nand\nhere\n"
+test io-30.2 {Tcl_Write lf, Tcl_Read cr} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    fconfigure $f -translation lf
+    puts $f hello\nthere\nand\nhere
+    close $f
+    set f [open $path(test1) r]
+    fconfigure $f -translation cr
+    set x [read $f]
+    close $f
+    set x
+} "hello\nthere\nand\nhere\n"
+test io-30.3 {Tcl_Write lf, Tcl_Read crlf} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    fconfigure $f -translation lf
+    puts $f hello\nthere\nand\nhere
+    close $f
+    set f [open $path(test1) r]
+    fconfigure $f -translation crlf
+    set x [read $f]
+    close $f
+    set x
+} "hello\nthere\nand\nhere\n"
+test io-30.4 {Tcl_Write cr, Tcl_Read cr} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    fconfigure $f -translation cr
+    puts $f hello\nthere\nand\nhere
+    close $f
+    set f [open $path(test1) r]
+    fconfigure $f -translation cr
+    set x [read $f]
+    close $f
+    set x
+} "hello\nthere\nand\nhere\n"
+test io-30.5 {Tcl_Write cr, Tcl_Read lf} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    fconfigure $f -translation cr
+    puts $f hello\nthere\nand\nhere
+    close $f
+    set f [open $path(test1) r]
+    fconfigure $f -translation lf
+    set x [read $f]
+    close $f
+    set x
+} "hello\rthere\rand\rhere\r"
+test io-30.6 {Tcl_Write cr, Tcl_Read crlf} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    fconfigure $f -translation cr
+    puts $f hello\nthere\nand\nhere
+    close $f
+    set f [open $path(test1) r]
+    fconfigure $f -translation crlf
+    set x [read $f]
+    close $f
+    set x 
+} "hello\rthere\rand\rhere\r"
+test io-30.7 {Tcl_Write crlf, Tcl_Read crlf} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    fconfigure $f -translation crlf
+    puts $f hello\nthere\nand\nhere
+    close $f
+    set f [open $path(test1) r]
+    fconfigure $f -translation crlf
+    set x [read $f]
+    close $f
+    set x
+} "hello\nthere\nand\nhere\n"
+test io-30.8 {Tcl_Write crlf, Tcl_Read lf} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    fconfigure $f -translation crlf
+    puts $f hello\nthere\nand\nhere
+    close $f
+    set f [open $path(test1) r]
+    fconfigure $f -translation lf
+    set x [read $f]
+    close $f
+    set x
+} "hello\r\nthere\r\nand\r\nhere\r\n"
+test io-30.9 {Tcl_Write crlf, Tcl_Read cr} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    fconfigure $f -translation crlf
+    puts $f hello\nthere\nand\nhere
+    close $f
+    set f [open $path(test1) r]
+    fconfigure $f -translation cr
+    set x [read $f]
+    close $f
+    set x
+} "hello\n\nthere\n\nand\n\nhere\n\n"
+test io-30.10 {Tcl_Write lf, Tcl_Read auto} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    fconfigure $f -translation lf
+    puts $f hello\nthere\nand\nhere
+    close $f
+    set f [open $path(test1) r]
+    set c [read $f]
+    set x [fconfigure $f -translation]
+    close $f
+    list $c $x
+} {{hello
+there
+and
+here
+} auto}
+test io-30.11 {Tcl_Write cr, Tcl_Read auto} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    fconfigure $f -translation cr
+    puts $f hello\nthere\nand\nhere
+    close $f
+    set f [open $path(test1) r]
+    set c [read $f]
+    set x [fconfigure $f -translation]
+    close $f
+    list $c $x
+} {{hello
+there
+and
+here
+} auto}
+test io-30.12 {Tcl_Write crlf, Tcl_Read auto} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    fconfigure $f -translation crlf
+    puts $f hello\nthere\nand\nhere
+    close $f
+    set f [open $path(test1) r]
+    set c [read $f]
+    set x [fconfigure $f -translation]
+    close $f
+    list $c $x
+} {{hello
+there
+and
+here
+} auto}
+test io-30.13 {Tcl_Write crlf on block boundary, Tcl_Read auto} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    fconfigure $f -translation crlf
+    set line "123456789ABCDE"	;# 14 char plus crlf
+    puts -nonewline $f x	;# shift crlf across block boundary
+    for {set i 0} {$i < 700} {incr i} {
+	puts $f $line
+    }
+    close $f
+    set f [open $path(test1) r]
+    fconfigure $f -translation auto
+    set c [read $f]
+    close $f
+    string length $c
+} [expr 700*15+1]
+test io-30.14 {Tcl_Write crlf on block boundary, Tcl_Read crlf} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    fconfigure $f -translation crlf
+    set line "123456789ABCDE"	;# 14 char plus crlf
+    puts -nonewline $f x	;# shift crlf across block boundary
+    for {set i 0} {$i < 700} {incr i} {
+	puts $f $line
+    }
+    close $f
+    set f [open $path(test1) r]
+    fconfigure $f -translation crlf
+    set c [read $f]
+    close $f
+    string length $c
+} [expr 700*15+1]
+test io-30.15 {Tcl_Write mixed, Tcl_Read auto} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    fconfigure $f -translation lf
+    puts $f hello\nthere\nand\rhere
+    close $f
+    set f [open $path(test1) r]
+    fconfigure $f -translation auto
+    set c [read $f]
+    close $f
+    set c
+} {hello
+there
+and
+here
+}
+test io-30.16 {Tcl_Write ^Z at end, Tcl_Read auto} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    fconfigure $f -translation lf
+    puts -nonewline $f hello\nthere\nand\rhere\n\x1a
+    close $f
+    set f [open $path(test1) r]
+    fconfigure $f -eofchar \x1a -translation auto
+    set c [read $f]
+    close $f
+    set c
+} {hello
+there
+and
+here
+}
+test io-30.17 {Tcl_Write, implicit ^Z at end, Tcl_Read auto} {win} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    fconfigure $f -eofchar \x1a -translation lf
+    puts $f hello\nthere\nand\rhere
+    close $f
+    set f [open $path(test1) r]
+    fconfigure $f -eofchar \x1a -translation auto
+    set c [read $f]
+    close $f
+    set c
+} {hello
+there
+and
+here
+}
+test io-30.18 {Tcl_Write, ^Z in middle, Tcl_Read auto} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    fconfigure $f -translation lf
+    set s [format "abc\ndef\n%cghi\nqrs" 26]
+    puts $f $s
+    close $f
+    set f [open $path(test1) r]
+    fconfigure $f -eofchar \x1a -translation auto
+    set l ""
+    lappend l [gets $f]
+    lappend l [gets $f]
+    lappend l [eof $f]
+    lappend l [gets $f]
+    lappend l [eof $f]
+    lappend l [gets $f]
+    lappend l [eof $f]
+    close $f
+    set l
+} {abc def 0 {} 1 {} 1}
+test io-30.19 {Tcl_Write, ^Z no newline in middle, Tcl_Read auto} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    fconfigure $f -translation lf
+    set s [format "abc\ndef\n%cghi\nqrs" 26]
+    puts $f $s
+    close $f
+    set f [open $path(test1) r]
+    fconfigure $f -eofchar \x1a -translation auto
+    set l ""
+    lappend l [gets $f]
+    lappend l [gets $f]
+    lappend l [eof $f]
+    lappend l [gets $f]
+    lappend l [eof $f]
+    lappend l [gets $f]
+    lappend l [eof $f]
+    close $f
+    set l
+} {abc def 0 {} 1 {} 1}
+test io-30.20 {Tcl_Write, ^Z in middle ignored, Tcl_Read lf} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    fconfigure $f -translation lf -eofchar {}
+    set s [format "abc\ndef\n%cghi\nqrs" 26]
+    puts $f $s
+    close $f
+    set f [open $path(test1) r]
+    fconfigure $f -translation lf -eofchar {}
+    set l ""
+    lappend l [gets $f]
+    lappend l [gets $f]
+    lappend l [eof $f]
+    lappend l [gets $f]
+    lappend l [eof $f]
+    lappend l [gets $f]
+    lappend l [eof $f]
+    lappend l [gets $f]
+    lappend l [eof $f]
+    close $f
+    set l
+} "abc def 0 \x1aghi 0 qrs 0 {} 1"
+test io-30.21 {Tcl_Write, ^Z in middle ignored, Tcl_Read cr} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    fconfigure $f -translation lf -eofchar {}
+    set s [format "abc\ndef\n%cghi\nqrs" 26]
+    puts $f $s
+    close $f
+    set f [open $path(test1) r]
+    fconfigure $f -translation cr -eofchar {}
+    set l ""
+    set x [gets $f]
+    lappend l [string compare $x "abc\ndef\n\x1aghi\nqrs\n"]
+    lappend l [eof $f]
+    lappend l [gets $f]
+    lappend l [eof $f]
+    close $f
+    set l
+} {0 1 {} 1}
+test io-30.22 {Tcl_Write, ^Z in middle ignored, Tcl_Read crlf} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    fconfigure $f -translation lf -eofchar {}
+    set s [format "abc\ndef\n%cghi\nqrs" 26]
+    puts $f $s
+    close $f
+    set f [open $path(test1) r]
+    fconfigure $f -translation crlf -eofchar {}
+    set l ""
+    set x [gets $f]
+    lappend l [string compare $x "abc\ndef\n\x1aghi\nqrs\n"]
+    lappend l [eof $f]
+    lappend l [gets $f]
+    lappend l [eof $f]
+    close $f
+    set l
+} {0 1 {} 1}
+test io-30.23 {Tcl_Write lf, ^Z in middle, Tcl_Read auto} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    fconfigure $f -translation lf
+    set c [format abc\ndef\n%cqrs\ntuv 26]
+    puts $f $c
+    close $f
+    set f [open $path(test1) r]
+    fconfigure $f -translation auto -eofchar \x1a
+    set c [string length [read $f]]
+    set e [eof $f]
+    close $f
+    list $c $e
+} {8 1}
+test io-30.24 {Tcl_Write lf, ^Z in middle, Tcl_Read lf} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    fconfigure $f -translation lf
+    set c [format abc\ndef\n%cqrs\ntuv 26]
+    puts $f $c
+    close $f
+    set f [open $path(test1) r]
+    fconfigure $f -translation lf -eofchar \x1a
+    set c [string length [read $f]]
+    set e [eof $f]
+    close $f
+    list $c $e
+} {8 1}
+test io-30.25 {Tcl_Write cr, ^Z in middle, Tcl_Read auto} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    fconfigure $f -translation cr
+    set c [format abc\ndef\n%cqrs\ntuv 26]
+    puts $f $c
+    close $f
+    set f [open $path(test1) r]
+    fconfigure $f -translation auto -eofchar \x1a
+    set c [string length [read $f]]
+    set e [eof $f]
+    close $f
+    list $c $e
+} {8 1}
+test io-30.26 {Tcl_Write cr, ^Z in middle, Tcl_Read cr} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    fconfigure $f -translation cr
+    set c [format abc\ndef\n%cqrs\ntuv 26]
+    puts $f $c
+    close $f
+    set f [open $path(test1) r]
+    fconfigure $f -translation cr -eofchar \x1a
+    set c [string length [read $f]]
+    set e [eof $f]
+    close $f
+    list $c $e
+} {8 1}
+test io-30.27 {Tcl_Write crlf, ^Z in middle, Tcl_Read auto} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    fconfigure $f -translation crlf
+    set c [format abc\ndef\n%cqrs\ntuv 26]
+    puts $f $c
+    close $f
+    set f [open $path(test1) r]
+    fconfigure $f -translation auto -eofchar \x1a
+    set c [string length [read $f]]
+    set e [eof $f]
+    close $f
+    list $c $e
+} {8 1}
+test io-30.28 {Tcl_Write crlf, ^Z in middle, Tcl_Read crlf} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    fconfigure $f -translation crlf
+    set c [format abc\ndef\n%cqrs\ntuv 26]
+    puts $f $c
+    close $f
+    set f [open $path(test1) r]
+    fconfigure $f -translation crlf -eofchar \x1a
+    set c [string length [read $f]]
+    set e [eof $f]
+    close $f
+    list $c $e
+} {8 1}
+
+# Test end of line translations. Functions tested are Tcl_Write and Tcl_Gets.
+
+test io-31.1 {Tcl_Write lf, Tcl_Gets auto} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    fconfigure $f -translation lf
+    puts $f hello\nthere\nand\nhere
+    close $f
+    set f [open $path(test1) r]
+    set l ""
+    lappend l [gets $f]
+    lappend l [tell $f]
+    lappend l [fconfigure $f -translation]
+    lappend l [gets $f]
+    lappend l [tell $f]
+    lappend l [fconfigure $f -translation]
+    close $f
+    set l
+} {hello 6 auto there 12 auto}
+test io-31.2 {Tcl_Write cr, Tcl_Gets auto} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    fconfigure $f -translation cr
+    puts $f hello\nthere\nand\nhere
+    close $f
+    set f [open $path(test1) r]
+    set l ""
+    lappend l [gets $f]
+    lappend l [tell $f]
+    lappend l [fconfigure $f -translation]
+    lappend l [gets $f]
+    lappend l [tell $f]
+    lappend l [fconfigure $f -translation]
+    close $f
+    set l
+} {hello 6 auto there 12 auto}
+test io-31.3 {Tcl_Write crlf, Tcl_Gets auto} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    fconfigure $f -translation crlf
+    puts $f hello\nthere\nand\nhere
+    close $f
+    set f [open $path(test1) r]
+    set l ""
+    lappend l [gets $f]
+    lappend l [tell $f]
+    lappend l [fconfigure $f -translation]
+    lappend l [gets $f]
+    lappend l [tell $f]
+    lappend l [fconfigure $f -translation]
+    close $f
+    set l
+} {hello 7 auto there 14 auto}
+test io-31.4 {Tcl_Write lf, Tcl_Gets lf} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    fconfigure $f -translation lf
+    puts $f hello\nthere\nand\nhere
+    close $f
+    set f [open $path(test1) r]
+    fconfigure $f -translation lf
+    set l ""
+    lappend l [gets $f]
+    lappend l [tell $f]
+    lappend l [fconfigure $f -translation]
+    lappend l [gets $f]
+    lappend l [tell $f]
+    lappend l [fconfigure $f -translation]
+    close $f
+    set l
+} {hello 6 lf there 12 lf}
+test io-31.5 {Tcl_Write lf, Tcl_Gets cr} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    fconfigure $f -translation lf
+    puts $f hello\nthere\nand\nhere
+    close $f
+    set f [open $path(test1) r]
+    fconfigure $f -translation cr
+    set l ""
+    lappend l [string length [gets $f]]
+    lappend l [tell $f]
+    lappend l [fconfigure $f -translation]
+    lappend l [eof $f]
+    lappend l [gets $f]
+    lappend l [tell $f]
+    lappend l [fconfigure $f -translation]
+    lappend l [eof $f]
+    close $f
+    set l
+} {21 21 cr 1 {} 21 cr 1}
+test io-31.6 {Tcl_Write lf, Tcl_Gets crlf} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    fconfigure $f -translation lf
+    puts $f hello\nthere\nand\nhere
+    close $f
+    set f [open $path(test1) r]
+    fconfigure $f -translation crlf
+    set l ""
+    lappend l [string length [gets $f]]
+    lappend l [tell $f]
+    lappend l [fconfigure $f -translation]
+    lappend l [eof $f]
+    lappend l [gets $f]
+    lappend l [tell $f]
+    lappend l [fconfigure $f -translation]
+    lappend l [eof $f]
+    close $f
+    set l
+} {21 21 crlf 1 {} 21 crlf 1}
+test io-31.7 {Tcl_Write cr, Tcl_Gets cr} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    fconfigure $f -translation cr
+    puts $f hello\nthere\nand\nhere
+    close $f
+    set f [open $path(test1) r]
+    fconfigure $f -translation cr
+    set l ""
+    lappend l [gets $f]
+    lappend l [tell $f]
+    lappend l [fconfigure $f -translation]
+    lappend l [eof $f]
+    lappend l [gets $f]
+    lappend l [tell $f]
+    lappend l [fconfigure $f -translation]
+    lappend l [eof $f]
+    close $f
+    set l
+} {hello 6 cr 0 there 12 cr 0}
+test io-31.8 {Tcl_Write cr, Tcl_Gets lf} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    fconfigure $f -translation cr
+    puts $f hello\nthere\nand\nhere
+    close $f
+    set f [open $path(test1) r]
+    fconfigure $f -translation lf
+    set l ""
+    lappend l [string length [gets $f]]
+    lappend l [tell $f]
+    lappend l [fconfigure $f -translation]
+    lappend l [eof $f]
+    lappend l [gets $f]
+    lappend l [tell $f]
+    lappend l [fconfigure $f -translation]
+    lappend l [eof $f]
+    close $f
+    set l
+} {21 21 lf 1 {} 21 lf 1}
+test io-31.9 {Tcl_Write cr, Tcl_Gets crlf} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    fconfigure $f -translation cr
+    puts $f hello\nthere\nand\nhere
+    close $f
+    set f [open $path(test1) r]
+    fconfigure $f -translation crlf
+    set l ""
+    lappend l [string length [gets $f]]
+    lappend l [tell $f]
+    lappend l [fconfigure $f -translation]
+    lappend l [eof $f]
+    lappend l [gets $f]
+    lappend l [tell $f]
+    lappend l [fconfigure $f -translation]
+    lappend l [eof $f]
+    close $f
+    set l
+} {21 21 crlf 1 {} 21 crlf 1}
+test io-31.10 {Tcl_Write crlf, Tcl_Gets crlf} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    fconfigure $f -translation crlf
+    puts $f hello\nthere\nand\nhere
+    close $f
+    set f [open $path(test1) r]
+    fconfigure $f -translation crlf
+    set l ""
+    lappend l [gets $f]
+    lappend l [tell $f]
+    lappend l [fconfigure $f -translation]
+    lappend l [eof $f]
+    lappend l [gets $f]
+    lappend l [tell $f]
+    lappend l [fconfigure $f -translation]
+    lappend l [eof $f]
+    close $f
+    set l
+} {hello 7 crlf 0 there 14 crlf 0}
+test io-31.11 {Tcl_Write crlf, Tcl_Gets cr} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    fconfigure $f -translation crlf
+    puts $f hello\nthere\nand\nhere
+    close $f
+    set f [open $path(test1) r]
+    fconfigure $f -translation cr
+    set l ""
+    lappend l [gets $f]
+    lappend l [tell $f]
+    lappend l [fconfigure $f -translation]
+    lappend l [eof $f]
+    lappend l [string length [gets $f]]
+    lappend l [tell $f]
+    lappend l [fconfigure $f -translation]
+    lappend l [eof $f]
+    close $f
+    set l
+} {hello 6 cr 0 6 13 cr 0}
+test io-31.12 {Tcl_Write crlf, Tcl_Gets lf} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    fconfigure $f -translation crlf
+    puts $f hello\nthere\nand\nhere
+    close $f
+    set f [open $path(test1) r]
+    fconfigure $f -translation lf
+    set l ""
+    lappend l [string length [gets $f]]
+    lappend l [tell $f]
+    lappend l [fconfigure $f -translation]
+    lappend l [eof $f]
+    lappend l [string length [gets $f]]
+    lappend l [tell $f]
+    lappend l [fconfigure $f -translation]
+    lappend l [eof $f]
+    close $f
+    set l
+} {6 7 lf 0 6 14 lf 0}
+test io-31.13 {binary mode is synonym of lf mode} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    fconfigure $f -translation binary
+    set x [fconfigure $f -translation]
+    close $f
+    set x
+} lf
+#
+# Test io-9.14 has been removed because "auto" output translation mode is
+# not supoprted.
+#
+test io-31.14 {Tcl_Write mixed, Tcl_Gets auto} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    fconfigure $f -translation lf
+    puts $f hello\nthere\rand\r\nhere
+    close $f
+    set f [open $path(test1) r]
+    fconfigure $f -translation auto
+    set l ""
+    lappend l [gets $f]
+    lappend l [gets $f]
+    lappend l [gets $f]
+    lappend l [gets $f]
+    lappend l [eof $f]
+    lappend l [gets $f]
+    lappend l [eof $f]
+    close $f
+    set l
+} {hello there and here 0 {} 1}
+test io-31.15 {Tcl_Write mixed, Tcl_Gets auto} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    fconfigure $f -translation lf
+    puts -nonewline $f hello\nthere\rand\r\nhere\r
+    close $f
+    set f [open $path(test1) r]
+    fconfigure $f -translation auto
+    set l ""
+    lappend l [gets $f]
+    lappend l [gets $f]
+    lappend l [gets $f]
+    lappend l [gets $f]
+    lappend l [eof $f]
+    lappend l [gets $f]
+    lappend l [eof $f]
+    close $f
+    set l
+} {hello there and here 0 {} 1}
+test io-31.16 {Tcl_Write mixed, Tcl_Gets auto} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    fconfigure $f -translation lf
+    puts -nonewline $f hello\nthere\rand\r\nhere\n
+    close $f
+    set f [open $path(test1) r]
+    set l ""
+    lappend l [gets $f]
+    lappend l [gets $f]
+    lappend l [gets $f]
+    lappend l [gets $f]
+    lappend l [eof $f]
+    lappend l [gets $f]
+    lappend l [eof $f]
+    close $f
+    set l
+} {hello there and here 0 {} 1}
+test io-31.17 {Tcl_Write mixed, Tcl_Gets auto} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    fconfigure $f -translation lf
+    puts -nonewline $f hello\nthere\rand\r\nhere\r\n
+    close $f
+    set f [open $path(test1) r]
+    fconfigure $f -translation auto
+    set l ""
+    lappend l [gets $f]
+    lappend l [gets $f]
+    lappend l [gets $f]
+    lappend l [gets $f]
+    lappend l [eof $f]
+    lappend l [gets $f]
+    lappend l [eof $f]
+    close $f
+    set l
+} {hello there and here 0 {} 1}
+test io-31.18 {Tcl_Write ^Z at end, Tcl_Gets auto} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    fconfigure $f -translation lf
+    set s [format "hello\nthere\nand\rhere\n\%c" 26]
+    puts $f $s
+    close $f
+    set f [open $path(test1) r]
+    fconfigure $f -eofchar \x1a -translation auto
+    set l ""
+    lappend l [gets $f]
+    lappend l [gets $f]
+    lappend l [gets $f]
+    lappend l [gets $f]
+    lappend l [eof $f]
+    lappend l [gets $f]
+    lappend l [eof $f]
+    close $f
+    set l
+} {hello there and here 0 {} 1}
+test io-31.19 {Tcl_Write, implicit ^Z at end, Tcl_Gets auto} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    fconfigure $f -eofchar \x1a -translation lf
+    puts $f hello\nthere\nand\rhere
+    close $f
+    set f [open $path(test1) r]
+    fconfigure $f -eofchar \x1a -translation auto
+    set l ""
+    lappend l [gets $f]
+    lappend l [gets $f]
+    lappend l [gets $f]
+    lappend l [gets $f]
+    lappend l [eof $f]
+    lappend l [gets $f]
+    lappend l [eof $f]
+    close $f
+    set l
+} {hello there and here 0 {} 1}
+test io-31.20 {Tcl_Write, ^Z in middle, Tcl_Gets auto, eofChar} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    fconfigure $f -translation lf
+    set s [format "abc\ndef\n%cqrs\ntuv" 26]
+    puts $f $s
+    close $f
+    set f [open $path(test1) r]
+    fconfigure $f -eofchar \x1a
+    fconfigure $f -translation auto
+    set l ""
+    lappend l [gets $f]
+    lappend l [gets $f]
+    lappend l [eof $f]
+    lappend l [gets $f]
+    lappend l [eof $f]
+    close $f
+    set l
+} {abc def 0 {} 1}
+test io-31.21 {Tcl_Write, no newline ^Z in middle, Tcl_Gets auto, eofChar} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    fconfigure $f -translation lf
+    set s [format "abc\ndef\n%cqrs\ntuv" 26]
+    puts $f $s
+    close $f
+    set f [open $path(test1) r]
+    fconfigure $f -eofchar \x1a -translation auto
+    set l ""
+    lappend l [gets $f]
+    lappend l [gets $f]
+    lappend l [eof $f]
+    lappend l [gets $f]
+    lappend l [eof $f]
+    close $f
+    set l
+} {abc def 0 {} 1}
+test io-31.22 {Tcl_Write, ^Z in middle ignored, Tcl_Gets lf} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    fconfigure $f -translation lf -eofchar {}
+    set s [format "abc\ndef\n%cqrs\ntuv" 26]
+    puts $f $s
+    close $f
+    set f [open $path(test1) r]
+    fconfigure $f -translation lf -eofchar {}
+    set l ""
+    lappend l [gets $f]
+    lappend l [gets $f]
+    lappend l [eof $f]
+    lappend l [gets $f]
+    lappend l [eof $f]
+    lappend l [gets $f]
+    lappend l [eof $f]
+    lappend l [gets $f]
+    lappend l [eof $f]
+    close $f
+    set l
+} "abc def 0 \x1aqrs 0 tuv 0 {} 1"
+test io-31.23 {Tcl_Write, ^Z in middle ignored, Tcl_Gets cr} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    fconfigure $f -translation cr -eofchar {}
+    set s [format "abc\ndef\n%cqrs\ntuv" 26]
+    puts $f $s
+    close $f
+    set f [open $path(test1) r]
+    fconfigure $f -translation cr -eofchar {}
+    set l ""
+    lappend l [gets $f]
+    lappend l [gets $f]
+    lappend l [eof $f]
+    lappend l [gets $f]
+    lappend l [eof $f]
+    lappend l [gets $f]
+    lappend l [eof $f]
+    lappend l [gets $f]
+    lappend l [eof $f]
+    close $f
+    set l
+} "abc def 0 \x1aqrs 0 tuv 0 {} 1"
+test io-31.24 {Tcl_Write, ^Z in middle ignored, Tcl_Gets crlf} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    fconfigure $f -translation crlf -eofchar {}
+    set s [format "abc\ndef\n%cqrs\ntuv" 26]
+    puts $f $s
+    close $f
+    set f [open $path(test1) r]
+    fconfigure $f -translation crlf -eofchar {}
+    set l ""
+    lappend l [gets $f]
+    lappend l [gets $f]
+    lappend l [eof $f]
+    lappend l [gets $f]
+    lappend l [eof $f]
+    lappend l [gets $f]
+    lappend l [eof $f]
+    lappend l [gets $f]
+    lappend l [eof $f]
+    close $f
+    set l
+} "abc def 0 \x1aqrs 0 tuv 0 {} 1"
+test io-31.25 {Tcl_Write lf, ^Z in middle, Tcl_Gets auto} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    fconfigure $f -translation lf
+    set s [format "abc\ndef\n%cqrs\ntuv" 26]
+    puts $f $s
+    close $f
+    set f [open $path(test1) r]
+    fconfigure $f -translation auto -eofchar \x1a
+    set l ""
+    lappend l [gets $f]
+    lappend l [gets $f]
+    lappend l [eof $f]
+    lappend l [gets $f]
+    lappend l [eof $f]
+    close $f
+    set l
+} {abc def 0 {} 1}
+test io-31.26 {Tcl_Write lf, ^Z in middle, Tcl_Gets lf} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    fconfigure $f -translation lf
+    set s [format "abc\ndef\n%cqrs\ntuv" 26]
+    puts $f $s
+    close $f
+    set f [open $path(test1) r]
+    fconfigure $f -translation lf -eofchar \x1a
+    set l ""
+    lappend l [gets $f]
+    lappend l [gets $f]
+    lappend l [eof $f]
+    lappend l [gets $f]
+    lappend l [eof $f]
+    close $f
+    set l
+} {abc def 0 {} 1}
+test io-31.27 {Tcl_Write cr, ^Z in middle, Tcl_Gets auto} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    fconfigure $f -translation cr -eofchar {}
+    set s [format "abc\ndef\n%cqrs\ntuv" 26]
+    puts $f $s
+    close $f
+    set f [open $path(test1) r]
+    fconfigure $f -translation auto -eofchar \x1a
+    set l ""
+    lappend l [gets $f]
+    lappend l [gets $f]
+    lappend l [eof $f]
+    lappend l [gets $f]
+    lappend l [eof $f]
+    close $f
+    set l
+} {abc def 0 {} 1}
+test io-31.28 {Tcl_Write cr, ^Z in middle, Tcl_Gets cr} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    fconfigure $f -translation cr -eofchar {}
+    set s [format "abc\ndef\n%cqrs\ntuv" 26]
+    puts $f $s
+    close $f
+    set f [open $path(test1) r]
+    fconfigure $f -translation cr -eofchar \x1a
+    set l ""
+    lappend l [gets $f]
+    lappend l [gets $f]
+    lappend l [eof $f]
+    lappend l [gets $f]
+    lappend l [eof $f]
+    close $f
+    set l
+} {abc def 0 {} 1}
+test io-31.29 {Tcl_Write crlf, ^Z in middle, Tcl_Gets auto} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    fconfigure $f -translation crlf -eofchar {}
+    set s [format "abc\ndef\n%cqrs\ntuv" 26]
+    puts $f $s
+    close $f
+    set f [open $path(test1) r]
+    fconfigure $f -translation auto -eofchar \x1a
+    set l ""
+    lappend l [gets $f]
+    lappend l [gets $f]
+    lappend l [eof $f]
+    lappend l [gets $f]
+    lappend l [eof $f]
+    close $f
+    set l
+} {abc def 0 {} 1}
+test io-31.30 {Tcl_Write crlf, ^Z in middle, Tcl_Gets crlf} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    fconfigure $f -translation crlf -eofchar {}
+    set s [format "abc\ndef\n%cqrs\ntuv" 26]
+    puts $f $s
+    close $f
+    set f [open $path(test1) r]
+    fconfigure $f -translation crlf -eofchar \x1a
+    set l ""
+    lappend l [gets $f]
+    lappend l [gets $f]
+    lappend l [eof $f]
+    lappend l [gets $f]
+    lappend l [eof $f]
+    close $f
+    set l
+} {abc def 0 {} 1}
+test io-31.31 {Tcl_Write crlf on block boundary, Tcl_Gets crlf} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    fconfigure $f -translation crlf
+    set line "123456789ABCDE"	;# 14 char plus crlf
+    puts -nonewline $f x	;# shift crlf across block boundary
+    for {set i 0} {$i < 700} {incr i} {
+	puts $f $line
+    }
+    close $f
+    set f [open $path(test1) r]
+    fconfigure $f -translation crlf 
+    set c ""
+    while {[gets $f line] >= 0} {
+	append c $line\n
+    }
+    close $f
+    string length $c
+} [expr 700*15+1]
+test io-31.32 {Tcl_Write crlf on block boundary, Tcl_Gets auto} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    fconfigure $f -translation crlf
+    set line "123456789ABCDE"	;# 14 char plus crlf
+    puts -nonewline $f x	;# shift crlf across block boundary
+    for {set i 0} {$i < 700} {incr i} {
+	puts $f $line
+    }
+    close $f
+    set f [open $path(test1) r]
+    fconfigure $f -translation auto
+    set c ""
+    while {[gets $f line] >= 0} {
+	append c $line\n
+    }
+    close $f
+    string length $c
+} [expr 700*15+1]
+
+# Test Tcl_Read and buffering.
+
+test io-32.1 {Tcl_Read, channel not readable} {
+    list [catch {read stdout} msg] $msg
+} {1 {channel "stdout" wasn't opened for reading}}
+test io-32.2 {Tcl_Read, zero byte count} {
+    read stdin 0
+} ""
+test io-32.3 {Tcl_Read, negative byte count} {
+    set f [open $path(longfile) r]
+    set l [list [catch {read $f -1} msg] $msg]
+    close $f
+    set l
+} {1 {expected non-negative integer but got "-1"}}
+test io-32.4 {Tcl_Read, positive byte count} {
+    set f [open $path(longfile) r]
+    set x [read $f 1024]
+    set s [string length $x]
+    unset x
+    close $f
+    set s
+} 1024
+test io-32.5 {Tcl_Read, multiple buffers} {
+    set f [open $path(longfile) r]
+    fconfigure $f -buffersize 100
+    set x [read $f 1024]
+    set s [string length $x]
+    unset x
+    close $f
+    set s
+} 1024
+test io-32.6 {Tcl_Read, very large read} {
+    set f1 [open $path(longfile) r]
+    set z [read $f1 1000000]
+    close $f1
+    set l [string length $z]
+    set x ok
+    set z [file size $path(longfile)]
+    if {$z != $l} {
+	set x broken
+    }
+    set x
+} ok
+test io-32.7 {Tcl_Read, nonblocking, file} {nonBlockFiles} {
+    set f1 [open $path(longfile) r]
+    fconfigure $f1 -blocking off
+    set z [read $f1 20]
+    close $f1
+    set l [string length $z]
+    set x ok
+    if {$l != 20} {
+	set x broken
+    }
+    set x
+} ok
+test io-32.8 {Tcl_Read, nonblocking, file} {nonBlockFiles} {
+    set f1 [open $path(longfile) r]
+    fconfigure $f1 -blocking off
+    set z [read $f1 1000000]
+    close $f1
+    set x ok
+    set l [string length $z]
+    set z [file size $path(longfile)]
+    if {$z != $l} {
+	set x broken
+    }
+    set x
+} ok
+test io-32.9 {Tcl_Read, read to end of file} {
+    set f1 [open $path(longfile) r]
+    set z [read $f1]
+    close $f1
+    set l [string length $z]
+    set x ok
+    set z [file size $path(longfile)]
+    if {$z != $l} {
+	set x broken
+    }
+    set x
+} ok
+test io-32.10 {Tcl_Read from a pipe} {stdio openpipe} {
+    file delete $path(pipe)
+    set f1 [open $path(pipe) w]
+    puts $f1 {puts [gets stdin]}
+    close $f1
+    set f1 [open "|[list [interpreter] $path(pipe)]" r+]
+    puts $f1 hello
+    flush $f1
+    set x [read $f1]
+    close $f1
+    set x
+} "hello\n"
+test io-32.11 {Tcl_Read from a pipe} {stdio openpipe} {
+    file delete $path(pipe)
+    set f1 [open $path(pipe) w]
+    puts $f1 {puts [gets stdin]}
+    puts $f1 {puts [gets stdin]}
+    close $f1
+    set f1 [open "|[list [interpreter] $path(pipe)]" r+]
+    puts $f1 hello
+    flush $f1
+    set x ""
+    lappend x [read $f1 6]
+    puts $f1 hello
+    flush $f1
+    lappend x [read $f1]
+    close $f1
+    set x
+} {{hello
+} {hello
+}}
+test io-32.11.1 {Tcl_Read from a pipe} {stdio openpipe} {
+    file delete $path(pipe)
+    set f1 [open $path(pipe) w]
+    puts $f1 {chan configure stdout -translation crlf}
+    puts $f1 {puts [gets stdin]}
+    puts $f1 {puts [gets stdin]}
+    close $f1
+    set f1 [open "|[list [interpreter] $path(pipe)]" r+]
+    puts $f1 hello
+    flush $f1
+    set x ""
+    lappend x [read $f1 6]
+    puts $f1 hello
+    flush $f1
+    lappend x [read $f1]
+    close $f1
+    set x
+} {{hello
+} {hello
+}}
+test io-32.11.2 {Tcl_Read from a pipe} {stdio openpipe} {
+    file delete $path(pipe)
+    set f1 [open $path(pipe) w]
+    puts $f1 {chan configure stdout -translation crlf}
+    puts $f1 {puts [gets stdin]}
+    puts $f1 {puts [gets stdin]}
+    close $f1
+    set f1 [open "|[list [interpreter] $path(pipe)]" r+]
+    puts $f1 hello
+    flush $f1
+    set x ""
+    lappend x [read $f1 6]
+    puts $f1 hello
+    flush $f1
+    lappend x [read $f1]
+    close $f1
+    set x
+} {{hello
+} {hello
+}}
+test io-32.12 {Tcl_Read, -nonewline} {
+    file delete $path(test1)
+    set f1 [open $path(test1) w]
+    puts $f1 hello
+    puts $f1 bye
+    close $f1
+    set f1 [open $path(test1) r]
+    set c [read -nonewline $f1]
+    close $f1
+    set c
+} {hello
+bye}
+test io-32.13 {Tcl_Read, -nonewline} {
+    file delete $path(test1)
+    set f1 [open $path(test1) w]
+    puts $f1 hello
+    puts $f1 bye
+    close $f1
+    set f1 [open $path(test1) r]
+    set c [read -nonewline $f1]
+    close $f1
+    list [string length $c] $c
+} {9 {hello
+bye}}
+test io-32.14 {Tcl_Read, reading in small chunks} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    puts $f "Two lines: this one"
+    puts $f "and this one"
+    close $f
+    set f [open $path(test1)]
+    set x [list [read $f 1] [read $f 2] [read $f]]
+    close $f
+    set x
+} {T wo { lines: this one
+and this one
+}}
+test io-32.15 {Tcl_Read, asking for more input than available} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    puts $f "Two lines: this one"
+    puts $f "and this one"
+    close $f
+    set f [open $path(test1)]
+    set x [read $f 100]
+    close $f
+    set x
+} {Two lines: this one
+and this one
+}
+test io-32.16 {Tcl_Read, read to end of file with -nonewline} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    puts $f "Two lines: this one"
+    puts $f "and this one"
+    close $f
+    set f [open $path(test1)]
+    set x [read -nonewline $f]
+    close $f
+    set x
+} {Two lines: this one
+and this one}
+
+# Test Tcl_Gets.
+
+test io-33.1 {Tcl_Gets, reading what was written} {
+    file delete $path(test1)
+    set f1 [open $path(test1) w]
+    set y "first line"
+    puts $f1 $y
+    close $f1
+    set f1 [open $path(test1) r]
+    set x [gets $f1]
+    set z ok
+    if {"$x" != "$y"} {
+	set z broken
+    }
+    close $f1
+    set z
+} ok
+test io-33.2 {Tcl_Gets into variable} {
+    set f1 [open $path(longfile) r]
+    set c [gets $f1 x]
+    set l [string length x]
+    set z ok
+    if {$l != $l} {
+	set z broken
+    }
+    close $f1
+    set z
+} ok
+test io-33.3 {Tcl_Gets from pipe} {stdio openpipe} {
+    file delete $path(pipe)
+    set f1 [open $path(pipe) w]
+    puts $f1 {puts [gets stdin]}
+    close $f1
+    set f1 [open "|[list [interpreter] $path(pipe)]" r+]
+    puts $f1 hello
+    flush $f1
+    set x [gets $f1]
+    close $f1
+    set z ok
+    if {"$x" != "hello"} {
+	set z broken
+    }
+    set z
+} ok
+test io-33.4 {Tcl_Gets with long line} {
+    file delete $path(test3)
+    set f [open $path(test3) w]
+    puts -nonewline $f "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
+    puts -nonewline $f "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
+    puts -nonewline $f "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
+    puts -nonewline $f "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
+    puts $f "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
+    close $f
+    set f [open $path(test3)]
+    set x [gets $f]
+    close $f
+    set x
+} {abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ}
+set f [open $path(test3) w]
+puts -nonewline $f "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
+puts -nonewline $f "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
+puts -nonewline $f "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
+puts -nonewline $f "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
+puts $f "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
+close $f
+test io-33.5 {Tcl_Gets with long line} {
+    set f [open $path(test3)]
+    set x [gets $f y]
+    close $f
+    list $x $y
+} {260 abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ}
+test io-33.6 {Tcl_Gets and end of file} {
+    file delete $path(test3)
+    set f [open $path(test3) w]
+    puts -nonewline $f "Test1\nTest2"
+    close $f
+    set f [open $path(test3)]
+    set x {}
+    set y {}
+    lappend x [gets $f y] $y
+    set y {}
+    lappend x [gets $f y] $y
+    set y {}
+    lappend x [gets $f y] $y
+    close $f
+    set x
+} {5 Test1 5 Test2 -1 {}}
+test io-33.7 {Tcl_Gets and bad variable} {
+    set f [open $path(test3) w]
+    puts $f "Line 1"
+    puts $f "Line 2"
+    close $f
+    catch {unset x}
+    set x 24
+    set f [open $path(test3) r]
+    set result [list [catch {gets $f x(0)} msg] $msg]
+    close $f
+    set result
+} {1 {can't set "x(0)": variable isn't array}}
+test io-33.8 {Tcl_Gets, exercising double buffering} {
+    set f [open $path(test3) w]
+    fconfigure $f -translation lf -eofchar {}
+    set x ""
+    for {set y 0} {$y < 99} {incr y} {set x "a$x"}
+    for {set y 0} {$y < 100} {incr y} {puts $f $x}
+    close $f
+    set f [open $path(test3) r]
+    fconfigure $f -translation lf
+    for {set y 0} {$y < 100} {incr y} {gets $f}
+    close $f
+    set y
+} 100
+test io-33.9 {Tcl_Gets, exercising double buffering} {
+    set f [open $path(test3) w]
+    fconfigure $f -translation lf -eofchar {}
+    set x ""
+    for {set y 0} {$y < 99} {incr y} {set x "a$x"}
+    for {set y 0} {$y < 200} {incr y} {puts $f $x}
+    close $f
+    set f [open $path(test3) r]
+    fconfigure $f -translation lf
+    for {set y 0} {$y < 200} {incr y} {gets $f}
+    close $f
+    set y
+} 200
+test io-33.10 {Tcl_Gets, exercising double buffering} {
+    set f [open $path(test3) w]
+    fconfigure $f -translation lf -eofchar {}
+    set x ""
+    for {set y 0} {$y < 99} {incr y} {set x "a$x"}
+    for {set y 0} {$y < 300} {incr y} {puts $f $x}
+    close $f
+    set f [open $path(test3) r]
+    fconfigure $f -translation lf
+    for {set y 0} {$y < 300} {incr y} {gets $f}
+    close $f
+    set y
+} 300
+test io-33.11 {TclGetsObjBinary, [10dc6daa37]} -setup {
+    proc driver {cmd args} {
+        variable buffer
+        variable index
+        set chan [lindex $args 0]
+        switch -- $cmd {
+            initialize {
+                set index($chan) 0
+                set buffer($chan) .......
+                return {initialize finalize watch read}
+            }
+            finalize {
+                unset index($chan) buffer($chan)
+                return
+            }
+            watch {}
+            read {
+                set n [lindex $args 1]
+		if {$n > 3} {set n 3}
+                set new [expr {$index($chan) + $n}]
+                set result [string range $buffer($chan) $index($chan) $new-1]
+                set index($chan) $new
+                return $result
+            }
+        }
+    }
+} -body {
+    set c [chan create read [namespace which driver]]
+    chan configure $c -translation binary -blocking 0
+    list [gets $c] [gets $c] [gets $c] [gets $c]
+} -cleanup {
+    close $c
+    rename driver {}
+} -result {{} {} {} .......}
+test io-33.12 {Tcl_GetsObj, [10dc6daa37]} -setup {
+    proc driver {cmd args} {
+        variable buffer
+        variable index
+        set chan [lindex $args 0]
+        switch -- $cmd {
+            initialize {
+                set index($chan) 0
+                set buffer($chan) .......
+                return {initialize finalize watch read}
+            }
+            finalize {
+                unset index($chan) buffer($chan)
+                return
+            }
+            watch {}
+            read {
+                set n [lindex $args 1]
+		if {$n > 3} {set n 3}
+                set new [expr {$index($chan) + $n}]
+                set result [string range $buffer($chan) $index($chan) $new-1]
+                set index($chan) $new
+                return $result
+            }
+        }
+    }
+} -body {
+    set c [chan create read [namespace which driver]]
+    chan configure $c -blocking 0
+    list [gets $c] [gets $c] [gets $c] [gets $c]
+} -cleanup {
+    close $c
+    rename driver {}
+} -result {{} {} {} .......}
+test io-33.13 {Tcl_GetsObj, [10dc6daa37]} -setup {
+    proc driver {cmd args} {
+        variable buffer
+        variable index
+        set chan [lindex $args 0]
+        switch -- $cmd {
+            initialize {
+                set index($chan) 0
+                set buffer($chan) [string repeat \
+                        [string repeat . 64]\n[string repeat . 25] 2]
+                return {initialize finalize watch read}
+            }
+            finalize {
+                unset index($chan) buffer($chan)
+                return
+            }
+            watch {}
+            read {
+                set n [lindex $args 1]
+                if {$n > 65} {set n 65}
+                set new [expr {$index($chan) + $n}]
+                set result [string range $buffer($chan) $index($chan) $new-1]
+                set index($chan) $new
+                return $result
+            }
+        }
+    }
+} -body {
+    set c [chan create read [namespace which driver]]
+    chan configure $c -blocking 0
+    list [gets $c] [gets $c] [gets $c] [gets $c] [gets $c]
+} -cleanup {
+    close $c
+    rename driver {}
+} -result [list [string repeat . 64] {} [string repeat . 89] \
+	[string repeat . 25] {}]
+
+# Test Tcl_Seek and Tcl_Tell.
+
+test io-34.1 {Tcl_Seek to current position at start of file} {
+    set f1 [open $path(longfile) r]
+    seek $f1 0 current
+    set c [tell $f1]
+    close $f1
+    set c
+} 0
+test io-34.2 {Tcl_Seek to offset from start} {
+    file delete $path(test1)
+    set f1 [open $path(test1) w]
+    fconfigure $f1 -translation lf -eofchar {}
+    puts $f1 "abcdefghijklmnopqrstuvwxyz"
+    puts $f1 "abcdefghijklmnopqrstuvwxyz"
+    close $f1
+    set f1 [open $path(test1) r]
+    seek $f1 10 start
+    set c [tell $f1]
+    close $f1
+    set c
+} 10
+test io-34.3 {Tcl_Seek to end of file} {
+    file delete $path(test1)
+    set f1 [open $path(test1) w]
+    fconfigure $f1 -translation lf -eofchar {}
+    puts $f1 "abcdefghijklmnopqrstuvwxyz"
+    puts $f1 "abcdefghijklmnopqrstuvwxyz"
+    close $f1
+    set f1 [open $path(test1) r]
+    seek $f1 0 end
+    set c [tell $f1]
+    close $f1
+    set c
+} 54
+test io-34.4 {Tcl_Seek to offset from end of file} {
+    file delete $path(test1)
+    set f1 [open $path(test1) w]
+    fconfigure $f1 -translation lf -eofchar {}
+    puts $f1 "abcdefghijklmnopqrstuvwxyz"
+    puts $f1 "abcdefghijklmnopqrstuvwxyz"
+    close $f1
+    set f1 [open $path(test1) r]
+    seek $f1 -10 end
+    set c [tell $f1]
+    close $f1
+    set c
+} 44
+test io-34.5 {Tcl_Seek to offset from current position} {
+    file delete $path(test1)
+    set f1 [open $path(test1) w]
+    fconfigure $f1 -translation lf -eofchar {}
+    puts $f1 "abcdefghijklmnopqrstuvwxyz"
+    puts $f1 "abcdefghijklmnopqrstuvwxyz"
+    close $f1
+    set f1 [open $path(test1) r]
+    seek $f1 10 current
+    seek $f1 10 current
+    set c [tell $f1]
+    close $f1
+    set c
+} 20
+test io-34.6 {Tcl_Seek to offset from end of file} {
+    file delete $path(test1)
+    set f1 [open $path(test1) w]
+    fconfigure $f1 -translation lf -eofchar {}
+    puts $f1 "abcdefghijklmnopqrstuvwxyz"
+    puts $f1 "abcdefghijklmnopqrstuvwxyz"
+    close $f1
+    set f1 [open $path(test1) r]
+    seek $f1 -10 end
+    set c [tell $f1]
+    set r [read $f1]
+    close $f1
+    list $c $r
+} {44 {rstuvwxyz
+}}
+test io-34.7 {Tcl_Seek to offset from end of file, then to current position} {
+    file delete $path(test1)
+    set f1 [open $path(test1) w]
+    fconfigure $f1 -translation lf -eofchar {}
+    puts $f1 "abcdefghijklmnopqrstuvwxyz"
+    puts $f1 "abcdefghijklmnopqrstuvwxyz"
+    close $f1
+    set f1 [open $path(test1) r]
+    seek $f1 -10 end
+    set c1 [tell $f1]
+    set r1 [read $f1 5]
+    seek $f1 0 current
+    set c2 [tell $f1]
+    close $f1
+    list $c1 $r1 $c2
+} {44 rstuv 49}
+test io-34.8 {Tcl_Seek on pipes: not supported} {stdio openpipe} {
+    set f1 [open "|[list [interpreter]]" r+]
+    set x [list [catch {seek $f1 0 current} msg] $msg]
+    close $f1
+    regsub {".*":} $x {"":} x
+    string tolower $x
+} {1 {error during seek on "": invalid argument}}
+test io-34.9 {Tcl_Seek, testing buffered input flushing} {
+    file delete $path(test3)
+    set f [open $path(test3) w]
+    fconfigure $f -eofchar {}
+    puts -nonewline $f "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
+    close $f
+    set f [open $path(test3) RDWR]
+    set x [read $f 1]
+    seek $f 3
+    lappend x [read $f 1]
+    seek $f 0 start
+    lappend x [read $f 1]
+    seek $f 10 current
+    lappend x [read $f 1]
+    seek $f -2 end
+    lappend x [read $f 1]
+    seek $f 50 end
+    lappend x [read $f 1]
+    seek $f 1
+    lappend x [read $f 1]
+    close $f
+    set x
+} {a d a l Y {} b}
+set path(test3) [makeFile {} test3]
+test io-34.10 {Tcl_Seek testing flushing of buffered input} {
+    set f [open $path(test3) w]
+    fconfigure $f -translation lf
+    puts $f xyz\n123
+    close $f
+    set f [open $path(test3) r+]
+    fconfigure $f -translation lf
+    set x [gets $f]
+    seek $f 0 current
+    puts $f 456
+    close $f
+    list $x [viewFile test3]
+} "xyz {xyz
+456}"
+test io-34.11 {Tcl_Seek testing flushing of buffered output} {
+    set f [open $path(test3) w]
+    puts $f xyz\n123
+    close $f
+    set f [open $path(test3) w+]
+    puts $f xyzzy
+    seek $f 2
+    set x [gets $f]
+    close $f
+    list $x [viewFile test3]
+} "zzy xyzzy"
+test io-34.12 {Tcl_Seek testing combination of write, seek back and read} {
+    set f [open $path(test3) w]
+    fconfigure $f -translation lf -eofchar {}
+    puts $f xyz\n123
+    close $f
+    set f [open $path(test3) a+]
+    fconfigure $f -translation lf -eofchar {}
+    puts $f xyzzy
+    flush $f
+    set x [tell $f]
+    seek $f -4 cur
+    set y [gets $f]
+    close $f
+    list $x [viewFile test3] $y
+} {14 {xyz
+123
+xyzzy} zzy}
+test io-34.13 {Tcl_Tell at start of file} {
+    file delete $path(test1)
+    set f1 [open $path(test1) w]
+    set p [tell $f1]
+    close $f1
+    set p
+} 0
+test io-34.14 {Tcl_Tell after seek to end of file} {
+    file delete $path(test1)
+    set f1 [open $path(test1) w]
+    fconfigure $f1 -translation lf -eofchar {}
+    puts $f1 "abcdefghijklmnopqrstuvwxyz"
+    puts $f1 "abcdefghijklmnopqrstuvwxyz"
+    close $f1
+    set f1 [open $path(test1) r]
+    seek $f1 0 end
+    set c1 [tell $f1]
+    close $f1
+    set c1
+} 54
+test io-34.15 {Tcl_Tell combined with seeking} {
+    file delete $path(test1)
+    set f1 [open $path(test1) w]
+    fconfigure $f1 -translation lf -eofchar {}
+    puts $f1 "abcdefghijklmnopqrstuvwxyz"
+    puts $f1 "abcdefghijklmnopqrstuvwxyz"
+    close $f1
+    set f1 [open $path(test1) r]
+    seek $f1 10 start
+    set c1 [tell $f1]
+    seek $f1 10 current
+    set c2 [tell $f1]
+    close $f1
+    list $c1 $c2
+} {10 20}
+test io-34.16 {Tcl_Tell on pipe: always -1} {stdio openpipe} {
+    set f1 [open "|[list [interpreter]]" r+]
+    set c [tell $f1]
+    close $f1
+    set c
+} -1
+test io-34.17 {Tcl_Tell on pipe: always -1} {stdio openpipe} {
+    set f1 [open "|[list [interpreter]]" r+]
+    puts $f1 {puts hello}
+    flush $f1
+    set c [tell $f1]
+    gets $f1
+    close $f1
+    set c
+} -1
+test io-34.18 {Tcl_Tell combined with seeking and reading} {
+    file delete $path(test2)
+    set f [open $path(test2) w]
+    fconfigure $f -translation lf -eofchar {}
+    puts -nonewline $f "line1\nline2\nline3\nline4\nline5\n"
+    close $f
+    set f [open $path(test2)]
+    fconfigure $f -translation lf
+    set x [tell $f]
+    read $f 3
+    lappend x [tell $f]
+    seek $f 2
+    lappend x [tell $f]
+    seek $f 10 current
+    lappend x [tell $f]
+    seek $f 0 end
+    lappend x [tell $f]
+    close $f
+    set x
+} {0 3 2 12 30}
+test io-34.19 {Tcl_Tell combined with opening in append mode} {
+    set f [open $path(test3) w]
+    fconfigure $f -translation lf -eofchar {}
+    puts $f "abcdefghijklmnopqrstuvwxyz"
+    puts $f "abcdefghijklmnopqrstuvwxyz"
+    close $f
+    set f [open $path(test3) a]
+    set c [tell $f]
+    close $f
+    set c
+} 54
+test io-34.20 {Tcl_Tell combined with writing} {
+    set f [open $path(test3) w]
+    set l ""
+    seek $f 29 start
+    lappend l [tell $f]
+    puts -nonewline $f a
+    seek $f 39 start
+    lappend l [tell $f]
+    puts -nonewline $f a
+    lappend l [tell $f]
+    seek $f 407 end
+    lappend l [tell $f]
+    close $f
+    set l
+} {29 39 40 447}
+test io-34.21 {Tcl_Seek and Tcl_Tell on large files} {largefileSupport} {
+    file delete $path(test3)
+    set f [open $path(test3) w]
+    fconfigure $f -encoding binary
+    set l ""
+    lappend l [tell $f]
+    puts -nonewline $f abcdef
+    lappend l [tell $f]
+    flush $f
+    lappend l [tell $f]
+    # 4GB offset!
+    seek $f 0x100000000
+    lappend l [tell $f]
+    puts -nonewline $f abcdef
+    lappend l [tell $f]
+    close $f
+    lappend l [file size $path(test3)]
+    # truncate...
+    close [open $path(test3) w]
+    lappend l [file size $path(test3)]
+    set l
+} {0 6 6 4294967296 4294967302 4294967302 0}
+
+# Test Tcl_Eof
+
+test io-35.1 {Tcl_Eof} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    puts $f hello
+    puts $f hello
+    close $f
+    set f [open $path(test1)]
+    set x [eof $f]
+    lappend x [eof $f]
+    gets $f
+    lappend x [eof $f]
+    gets $f
+    lappend x [eof $f]
+    gets $f
+    lappend x [eof $f]
+    lappend x [eof $f]
+    close $f
+    set x
+} {0 0 0 0 1 1}
+test io-35.2 {Tcl_Eof with pipe} {stdio openpipe} {
+    file delete $path(pipe)
+    set f1 [open $path(pipe) w]
+    puts $f1 {gets stdin}
+    puts $f1 {puts hello}
+    close $f1
+    set f1 [open "|[list [interpreter] $path(pipe)]" r+]
+    puts $f1 hello
+    set x [eof $f1]
+    flush $f1
+    lappend x [eof $f1]
+    gets $f1
+    lappend x [eof $f1]
+    gets $f1
+    lappend x [eof $f1]
+    close $f1
+    set x
+} {0 0 0 1}
+test io-35.3 {Tcl_Eof with pipe} {stdio openpipe} {
+    file delete $path(pipe)
+    set f1 [open $path(pipe) w]
+    puts $f1 {gets stdin}
+    puts $f1 {puts hello}
+    close $f1
+    set f1 [open "|[list [interpreter] $path(pipe)]" r+]
+    puts $f1 hello
+    set x [eof $f1]
+    flush $f1
+    lappend x [eof $f1]
+    gets $f1
+    lappend x [eof $f1]
+    gets $f1
+    lappend x [eof $f1]
+    gets $f1
+    lappend x [eof $f1]
+    gets $f1
+    lappend x [eof $f1]
+    close $f1
+    set x
+} {0 0 0 1 1 1}
+test io-35.4 {Tcl_Eof, eof detection on nonblocking file} {nonBlockFiles} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    close $f
+    set f [open $path(test1) r]
+    fconfigure $f -blocking off
+    set l ""
+    lappend l [gets $f]
+    lappend l [eof $f]
+    close $f
+    set l
+} {{} 1}
+test io-35.5 {Tcl_Eof, eof detection on nonblocking pipe} {stdio openpipe} {
+    file delete $path(pipe)
+    set f [open $path(pipe) w]
+    puts $f {
+	exit
+    }
+    close $f
+    set f [open "|[list [interpreter] $path(pipe)]" r]
+    set l ""
+    lappend l [gets $f]
+    lappend l [eof $f]
+    close $f
+    set l
+} {{} 1}
+test io-35.6 {Tcl_Eof, eof char, lf write, auto read} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    fconfigure $f -translation lf -eofchar \x1a
+    puts $f abc\ndef
+    close $f
+    set s [file size $path(test1)]
+    set f [open $path(test1) r]
+    fconfigure $f -translation auto -eofchar \x1a
+    set l [string length [read $f]]
+    set e [eof $f]
+    close $f
+    list $s $l $e
+} {9 8 1}
+test io-35.7 {Tcl_Eof, eof char, lf write, lf read} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    fconfigure $f -translation lf -eofchar \x1a
+    puts $f abc\ndef
+    close $f
+    set s [file size $path(test1)]
+    set f [open $path(test1) r]
+    fconfigure $f -translation lf -eofchar \x1a
+    set l [string length [read $f]]
+    set e [eof $f]
+    close $f
+    list $s $l $e
+} {9 8 1}
+test io-35.8 {Tcl_Eof, eof char, cr write, auto read} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    fconfigure $f -translation cr -eofchar \x1a
+    puts $f abc\ndef
+    close $f
+    set s [file size $path(test1)]
+    set f [open $path(test1) r]
+    fconfigure $f -translation auto -eofchar \x1a
+    set l [string length [read $f]]
+    set e [eof $f]
+    close $f
+    list $s $l $e
+} {9 8 1}
+test io-35.9 {Tcl_Eof, eof char, cr write, cr read} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    fconfigure $f -translation cr -eofchar \x1a
+    puts $f abc\ndef
+    close $f
+    set s [file size $path(test1)]
+    set f [open $path(test1) r]
+    fconfigure $f -translation cr -eofchar \x1a
+    set l [string length [read $f]]
+    set e [eof $f]
+    close $f
+    list $s $l $e
+} {9 8 1}
+test io-35.10 {Tcl_Eof, eof char, crlf write, auto read} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    fconfigure $f -translation crlf -eofchar \x1a
+    puts $f abc\ndef
+    close $f
+    set s [file size $path(test1)]
+    set f [open $path(test1) r]
+    fconfigure $f -translation auto -eofchar \x1a
+    set l [string length [read $f]]
+    set e [eof $f]
+    close $f
+    list $s $l $e
+} {11 8 1}
+test io-35.11 {Tcl_Eof, eof char, crlf write, crlf read} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    fconfigure $f -translation crlf -eofchar \x1a
+    puts $f abc\ndef
+    close $f
+    set s [file size $path(test1)]
+    set f [open $path(test1) r]
+    fconfigure $f -translation crlf -eofchar \x1a
+    set l [string length [read $f]]
+    set e [eof $f]
+    close $f
+    list $s $l $e
+} {11 8 1}
+test io-35.12 {Tcl_Eof, eof char in middle, lf write, auto read} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    fconfigure $f -translation lf -eofchar {}
+    set i [format abc\ndef\n%cqrs\nuvw 26]
+    puts $f $i
+    close $f
+    set c [file size $path(test1)]
+    set f [open $path(test1) r]
+    fconfigure $f -translation auto -eofchar \x1a
+    set l [string length [read $f]]
+    set e [eof $f]
+    close $f
+    list $c $l $e
+} {17 8 1}
+test io-35.13 {Tcl_Eof, eof char in middle, lf write, lf read} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    fconfigure $f -translation lf -eofchar {}
+    set i [format abc\ndef\n%cqrs\nuvw 26]
+    puts $f $i
+    close $f
+    set c [file size $path(test1)]
+    set f [open $path(test1) r]
+    fconfigure $f -translation lf -eofchar \x1a
+    set l [string length [read $f]]
+    set e [eof $f]
+    close $f
+    list $c $l $e
+} {17 8 1}
+test io-35.14 {Tcl_Eof, eof char in middle, cr write, auto read} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    fconfigure $f -translation cr -eofchar {}
+    set i [format abc\ndef\n%cqrs\nuvw 26]
+    puts $f $i
+    close $f
+    set c [file size $path(test1)]
+    set f [open $path(test1) r]
+    fconfigure $f -translation auto -eofchar \x1a
+    set l [string length [read $f]]
+    set e [eof $f]
+    close $f
+    list $c $l $e
+} {17 8 1}
+test io-35.15 {Tcl_Eof, eof char in middle, cr write, cr read} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    fconfigure $f -translation cr -eofchar {}
+    set i [format abc\ndef\n%cqrs\nuvw 26]
+    puts $f $i
+    close $f
+    set c [file size $path(test1)]
+    set f [open $path(test1) r]
+    fconfigure $f -translation cr -eofchar \x1a
+    set l [string length [read $f]]
+    set e [eof $f]
+    close $f
+    list $c $l $e
+} {17 8 1}
+test io-35.16 {Tcl_Eof, eof char in middle, crlf write, auto read} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    fconfigure $f -translation crlf -eofchar {}
+    set i [format abc\ndef\n%cqrs\nuvw 26]
+    puts $f $i
+    close $f
+    set c [file size $path(test1)]
+    set f [open $path(test1) r]
+    fconfigure $f -translation auto -eofchar \x1a
+    set l [string length [read $f]]
+    set e [eof $f]
+    close $f
+    list $c $l $e
+} {21 8 1}
+test io-35.17 {Tcl_Eof, eof char in middle, crlf write, crlf read} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    fconfigure $f -translation crlf -eofchar {}
+    set i [format abc\ndef\n%cqrs\nuvw 26]
+    puts $f $i
+    close $f
+    set c [file size $path(test1)]
+    set f [open $path(test1) r]
+    fconfigure $f -translation crlf -eofchar \x1a
+    set l [string length [read $f]]
+    set e [eof $f]
+    close $f
+    list $c $l $e
+} {21 8 1}
+test io-35.18 {Tcl_Eof, eof char, cr write, crlf read} -body {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    fconfigure $f -translation cr
+    puts $f abc\ndef
+    close $f
+    set s [file size $path(test1)]
+    set f [open $path(test1) r]
+    fconfigure $f -translation crlf
+    set l [string length [set in [read $f]]]
+    set e [eof $f]
+    close $f
+    list $s $l $e [scan [string index $in end] %c]
+} -result {8 8 1 13}
+test io-35.18a {Tcl_Eof, eof char, cr write, crlf read} -body {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    fconfigure $f -translation cr -eofchar \x1a
+    puts $f abc\ndef
+    close $f
+    set s [file size $path(test1)]
+    set f [open $path(test1) r]
+    fconfigure $f -translation crlf -eofchar \x1a
+    set l [string length [set in [read $f]]]
+    set e [eof $f]
+    close $f
+    list $s $l $e [scan [string index $in end] %c]
+} -result {9 8 1 13}
+test io-35.18b {Tcl_Eof, eof char, cr write, crlf read} -body {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    fconfigure $f -translation cr -eofchar \x1a
+    puts $f {}
+    close $f
+    set s [file size $path(test1)]
+    set f [open $path(test1) r]
+    fconfigure $f -translation crlf -eofchar \x1a
+    set l [string length [set in [read $f]]]
+    set e [eof $f]
+    close $f
+    list $s $l $e [scan [string index $in end] %c]
+} -result {2 1 1 13}
+test io-35.18c {Tcl_Eof, eof char, cr write, crlf read} -body {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    fconfigure $f -translation cr
+    puts $f {}
+    close $f
+    set s [file size $path(test1)]
+    set f [open $path(test1) r]
+    fconfigure $f -translation crlf
+    set l [string length [set in [read $f]]]
+    set e [eof $f]
+    close $f
+    list $s $l $e [scan [string index $in end] %c]
+} -result {1 1 1 13}
+test io-35.19 {Tcl_Eof, eof char in middle, cr write, crlf read} -body {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    fconfigure $f -translation cr -eofchar {}
+    set i [format abc\ndef\n%cqrs\nuvw 26]
+    puts $f $i
+    close $f
+    set c [file size $path(test1)]
+    set f [open $path(test1) r]
+    fconfigure $f -translation crlf -eofchar \x1a
+    set l [string length [set in [read $f]]]
+    set e [eof $f]
+    close $f
+    list $c $l $e [scan [string index $in end] %c]
+} -result {17 8 1 13}
+test io-35.20 {Tcl_Eof, eof char in middle, cr write, crlf read} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    fconfigure $f -translation cr -eofchar {}
+    set i [format \n%cqrsuvw 26]
+    puts $f $i
+    close $f
+    set c [file size $path(test1)]
+    set f [open $path(test1) r]
+    fconfigure $f -translation crlf -eofchar \x1a
+    set l [string length [set in [read $f]]]
+    set e [eof $f]
+    close $f
+    list $c $l $e [scan [string index $in end] %c]
+} {9 1 1 13}
+
+# Test Tcl_InputBlocked
+
+test io-36.1 {Tcl_InputBlocked on nonblocking pipe} {stdio openpipe} {
+    set f1 [open "|[list [interpreter]]" r+]
+    puts $f1 {puts hello_from_pipe}
+    flush $f1
+    gets $f1
+    fconfigure $f1 -blocking off -buffering full
+    puts $f1 {puts hello}
+    set x ""
+    lappend x [gets $f1]
+    lappend x [fblocked $f1]
+    flush $f1
+    after 200
+    lappend x [gets $f1]
+    lappend x [fblocked $f1]
+    lappend x [gets $f1]
+    lappend x [fblocked $f1]
+    close $f1
+    set x
+} {{} 1 hello 0 {} 1}
+test io-36.1.1 {Tcl_InputBlocked on nonblocking binary pipe} {stdio openpipe} {
+    set f1 [open "|[list [interpreter]]" r+]
+    chan configure $f1 -encoding binary -translation lf -eofchar {}
+    puts $f1 {
+	chan configure stdout -encoding binary -translation lf -eofchar {}
+	puts hello_from_pipe
+    }
+    flush $f1
+    gets $f1
+    fconfigure $f1 -blocking off -buffering full
+    puts $f1 {puts hello}
+    set x ""
+    lappend x [gets $f1]
+    lappend x [fblocked $f1]
+    flush $f1
+    after 200
+    lappend x [gets $f1]
+    lappend x [fblocked $f1]
+    lappend x [gets $f1]
+    lappend x [fblocked $f1]
+    close $f1
+    set x
+} {{} 1 hello 0 {} 1}
+test io-36.2 {Tcl_InputBlocked on blocking pipe} {stdio openpipe} {
+    set f1 [open "|[list [interpreter]]" r+]
+    fconfigure $f1 -buffering line
+    puts $f1 {puts hello_from_pipe}
+    set x ""
+    lappend x [gets $f1]
+    lappend x [fblocked $f1]
+    puts $f1 {exit}
+    lappend x [gets $f1]
+    lappend x [fblocked $f1]
+    lappend x [eof $f1]
+    close $f1
+    set x
+} {hello_from_pipe 0 {} 0 1}
+test io-36.3 {Tcl_InputBlocked vs files, short read} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    puts $f abcdefghijklmnop
+    close $f
+    set f [open $path(test1) r]
+    set l ""
+    lappend l [fblocked $f]
+    lappend l [read $f 3]
+    lappend l [fblocked $f]
+    lappend l [read -nonewline $f]
+    lappend l [fblocked $f]
+    lappend l [eof $f]
+    close $f
+    set l
+} {0 abc 0 defghijklmnop 0 1}
+test io-36.4 {Tcl_InputBlocked vs files, event driven read} {fileevent} {
+    proc in {f} {
+        variable l
+        variable x
+	lappend l [read $f 3]
+	if {[eof $f]} {lappend l eof; close $f; set x done}
+    }
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    puts $f abcdefghijklmnop
+    close $f
+    set f [open $path(test1) r]
+    set l ""
+    fileevent $f readable [namespace code [list in $f]]
+    variable x
+    vwait [namespace which -variable x]
+    set l
+} {abc def ghi jkl mno {p
+} eof}
+test io-36.5 {Tcl_InputBlocked vs files, short read, nonblocking} {nonBlockFiles} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    puts $f abcdefghijklmnop
+    close $f
+    set f [open $path(test1) r]
+    fconfigure $f -blocking off
+    set l ""
+    lappend l [fblocked $f]
+    lappend l [read $f 3]
+    lappend l [fblocked $f]
+    lappend l [read -nonewline $f]
+    lappend l [fblocked $f]
+    lappend l [eof $f]
+    close $f
+    set l
+} {0 abc 0 defghijklmnop 0 1}
+test io-36.6 {Tcl_InputBlocked vs files, event driven read} {nonBlockFiles fileevent} {
+    proc in {f} {
+        variable l
+        variable x
+	lappend l [read $f 3]
+	if {[eof $f]} {lappend l eof; close $f; set x done}
+    }
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    puts $f abcdefghijklmnop
+    close $f
+    set f [open $path(test1) r]
+    fconfigure $f -blocking off
+    set l ""
+    fileevent $f readable [namespace code [list in $f]]
+    variable x
+    vwait [namespace which -variable x]
+    set l
+} {abc def ghi jkl mno {p
+} eof}
+
+# Test Tcl_InputBuffered
+
+test io-37.1 {Tcl_InputBuffered} {testchannel} {
+    set f [open $path(longfile) r]
+    fconfigure $f -buffersize 4096
+    read $f 3
+    set l ""
+    lappend l [testchannel inputbuffered $f]
+    lappend l [tell $f]
+    close $f
+    set l
+} {4093 3}
+test io-37.2 {Tcl_InputBuffered, test input flushing on seek} {testchannel} {
+    set f [open $path(longfile) r]
+    fconfigure $f -buffersize 4096
+    read $f 3
+    set l ""
+    lappend l [testchannel inputbuffered $f]
+    lappend l [tell $f]
+    seek $f 0 current
+    lappend l [testchannel inputbuffered $f]
+    lappend l [tell $f]
+    close $f
+    set l
+} {4093 3 0 3}
+
+# Test Tcl_SetChannelBufferSize, Tcl_GetChannelBufferSize
+
+test io-38.1 {Tcl_GetChannelBufferSize, default buffer size} {
+    set f [open $path(longfile) r]
+    set s [fconfigure $f -buffersize]
+    close $f
+    set s
+} 4096
+test io-38.2 {Tcl_SetChannelBufferSize, Tcl_GetChannelBufferSize} {
+    set f [open $path(longfile) r]
+    set l ""
+    lappend l [fconfigure $f -buffersize]
+    fconfigure $f -buffersize 10000
+    lappend l [fconfigure $f -buffersize]
+    fconfigure $f -buffersize 1
+    lappend l [fconfigure $f -buffersize]
+    fconfigure $f -buffersize -1
+    lappend l [fconfigure $f -buffersize]
+    fconfigure $f -buffersize 0
+    lappend l [fconfigure $f -buffersize]
+    fconfigure $f -buffersize 100000
+    lappend l [fconfigure $f -buffersize]
+    fconfigure $f -buffersize 10000000
+    lappend l [fconfigure $f -buffersize]
+    close $f
+    set l
+} {4096 10000 1 1 1 100000 1048576}
+test io-38.3 {Tcl_SetChannelBufferSize, changing buffersize between reads} {
+    # This test crashes the interp if Bug #427196 is not fixed
+
+    set chan [open [info script] r]
+    fconfigure $chan -buffersize 10
+    set var [read $chan 2]
+    fconfigure $chan -buffersize 32
+    append var [read $chan]
+    close $chan
+} {}
+
+# Test Tcl_SetChannelOption, Tcl_GetChannelOption
+
+test io-39.1 {Tcl_GetChannelOption} {
+    file delete $path(test1)
+    set f1 [open $path(test1) w]
+    set x [fconfigure $f1 -blocking]
+    close $f1
+    set x
+} 1
+#
+# Test 17.2 was removed.
+#
+test io-39.2 {Tcl_GetChannelOption} {
+    file delete $path(test1)
+    set f1 [open $path(test1) w]
+    set x [fconfigure $f1 -buffering]
+    close $f1
+    set x
+} full
+test io-39.3 {Tcl_GetChannelOption} {
+    file delete $path(test1)
+    set f1 [open $path(test1) w]
+    fconfigure $f1 -buffering line
+    set x [fconfigure $f1 -buffering]
+    close $f1
+    set x
+} line
+test io-39.4 {Tcl_GetChannelOption, Tcl_SetChannelOption} {
+    file delete $path(test1)
+    set f1 [open $path(test1) w]
+    set l ""
+    lappend l [fconfigure $f1 -buffering]
+    fconfigure $f1 -buffering line
+    lappend l [fconfigure $f1 -buffering]
+    fconfigure $f1 -buffering none
+    lappend l [fconfigure $f1 -buffering]
+    fconfigure $f1 -buffering line
+    lappend l [fconfigure $f1 -buffering]
+    fconfigure $f1 -buffering full
+    lappend l [fconfigure $f1 -buffering]
+    close $f1
+    set l
+} {full line none line full}
+test io-39.5 {Tcl_GetChannelOption, invariance} {
+    file delete $path(test1)
+    set f1 [open $path(test1) w]
+    set l ""
+    lappend l [fconfigure $f1 -buffering]
+    lappend l [list [catch {fconfigure $f1 -buffering green} msg] $msg]
+    lappend l [fconfigure $f1 -buffering]
+    close $f1
+    set l
+} {full {1 {bad value for -buffering: must be one of full, line, or none}} full}
+test io-39.6 {Tcl_SetChannelOption, multiple options} {
+    file delete $path(test1)
+    set f1 [open $path(test1) w]
+    fconfigure $f1 -translation lf -buffering line
+    puts $f1 hello
+    puts $f1 bye
+    set x [file size $path(test1)]
+    close $f1
+    set x
+} 10
+test io-39.7 {Tcl_SetChannelOption, buffering, translation} {
+    file delete $path(test1)
+    set f1 [open $path(test1) w]
+    fconfigure $f1 -translation lf
+    puts $f1 hello
+    puts $f1 bye
+    set x ""
+    fconfigure $f1 -buffering line
+    lappend x [file size $path(test1)]
+    puts $f1 really_bye
+    lappend x [file size $path(test1)]
+    close $f1
+    set x
+} {0 21}
+test io-39.8 {Tcl_SetChannelOption, different buffering options} {
+    file delete $path(test1)
+    set f1 [open $path(test1) w]
+    set l ""
+    fconfigure $f1 -translation lf -buffering none -eofchar {}
+    puts -nonewline $f1 hello
+    lappend l [file size $path(test1)]
+    puts -nonewline $f1 hello
+    lappend l [file size $path(test1)]
+    fconfigure $f1 -buffering full
+    puts -nonewline $f1 hello
+    lappend l [file size $path(test1)]
+    fconfigure $f1 -buffering none
+    lappend l [file size $path(test1)]
+    puts -nonewline $f1 hello
+    lappend l [file size $path(test1)]
+    close $f1
+    lappend l [file size $path(test1)]
+    set l
+} {5 10 10 10 20 20}
+test io-39.9 {Tcl_SetChannelOption, blocking mode} {nonBlockFiles} {
+    file delete $path(test1)
+    set f1 [open $path(test1) w]
+    close $f1
+    set f1 [open $path(test1) r]
+    set x ""
+    lappend x [fconfigure $f1 -blocking]
+    fconfigure $f1 -blocking off
+    lappend x [fconfigure $f1 -blocking]
+    lappend x [gets $f1]
+    lappend x [read $f1 1000]
+    lappend x [fblocked $f1]
+    lappend x [eof $f1]
+    close $f1
+    set x
+} {1 0 {} {} 0 1}
+test io-39.10 {Tcl_SetChannelOption, blocking mode} {stdio openpipe} {
+    file delete $path(pipe)
+    set f1 [open $path(pipe) w]
+    puts $f1 {
+	gets stdin
+	after 100
+	puts hi
+	gets stdin
+    }
+    close $f1
+    set x ""
+    set f1 [open "|[list [interpreter] $path(pipe)]" r+]
+    fconfigure $f1 -blocking off -buffering line
+    lappend x [fconfigure $f1 -blocking]
+    lappend x [gets $f1]
+    lappend x [fblocked $f1]
+    fconfigure $f1 -blocking on
+    puts $f1 hello
+    fconfigure $f1 -blocking off
+    lappend x [gets $f1]
+    lappend x [fblocked $f1]
+    fconfigure $f1 -blocking on
+    puts $f1 bye
+    fconfigure $f1 -blocking off
+    lappend x [gets $f1]
+    lappend x [fblocked $f1]
+    fconfigure $f1 -blocking on
+    lappend x [fconfigure $f1 -blocking]
+    lappend x [gets $f1]
+    lappend x [fblocked $f1]
+    lappend x [eof $f1]
+    lappend x [gets $f1]
+    lappend x [eof $f1]
+    close $f1
+    set x
+} {0 {} 1 {} 1 {} 1 1 hi 0 0 {} 1}
+test io-39.11 {Tcl_SetChannelOption, Tcl_GetChannelOption, buffer size clipped to lower bound} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    fconfigure $f -buffersize -10
+    set x [fconfigure $f -buffersize]
+    close $f
+    set x
+} 1
+test io-39.12 {Tcl_SetChannelOption, Tcl_GetChannelOption buffer size clipped to upper bound} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    fconfigure $f -buffersize 10000000
+    set x [fconfigure $f -buffersize]
+    close $f
+    set x
+} 1048576
+test io-39.13 {Tcl_SetChannelOption, Tcl_GetChannelOption, buffer size} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    fconfigure $f -buffersize 40000
+    set x [fconfigure $f -buffersize]
+    close $f
+    set x
+} 40000
+test io-39.14 {Tcl_SetChannelOption: -encoding, binary & utf-8} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    fconfigure $f -encoding {} 
+    puts -nonewline $f \xe7\x89\xa6
+    close $f
+    set f [open $path(test1) r]
+    fconfigure $f -encoding utf-8
+    set x [read $f]
+    close $f
+    set x
+} \u7266
+test io-39.15 {Tcl_SetChannelOption: -encoding, binary & utf-8} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    fconfigure $f -encoding binary
+    puts -nonewline $f \xe7\x89\xa6
+    close $f
+    set f [open $path(test1) r]
+    fconfigure $f -encoding utf-8
+    set x [read $f]
+    close $f
+    set x
+} \u7266
+test io-39.16 {Tcl_SetChannelOption: -encoding, errors} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    set result [list [catch {fconfigure $f -encoding foobar} msg] $msg]
+    close $f
+    set result
+} {1 {unknown encoding "foobar"}}
+test io-39.17 {Tcl_SetChannelOption: -encoding, clearing CHANNEL_NEED_MORE_DATA} {stdio openpipe fileevent} {
+    set f [open "|[list [interpreter] $path(cat)]" r+]
+    fconfigure $f -encoding binary
+    puts -nonewline $f "\xe7"
+    flush $f
+    fconfigure $f -encoding utf-8 -blocking 0
+    variable x {}
+    fileevent $f readable [namespace code { lappend x [read $f] }]
+    vwait [namespace which -variable x]
+    after 300 [namespace code { lappend x timeout }]
+    vwait [namespace which -variable x]
+    fconfigure $f -encoding utf-8
+    vwait [namespace which -variable x]
+    after 300 [namespace code { lappend x timeout }]
+    vwait [namespace which -variable x]
+    fconfigure $f -encoding binary
+    vwait [namespace which -variable x]
+    after 300 [namespace code { lappend x timeout }]
+    vwait [namespace which -variable x]
+    close $f
+    set x
+} "{} timeout {} timeout \xe7 timeout"
+test io-39.18 {Tcl_SetChannelOption, setting read mode independently} \
+	{socket} {
+    proc accept {s a p} {close $s}
+    set s1 [socket -server [namespace code accept] -myaddr 127.0.0.1 0]
+    set port [lindex [fconfigure $s1 -sockname] 2]
+    set s2 [socket 127.0.0.1 $port]
+    update
+    fconfigure $s2 -translation {auto lf}
+    set modes [fconfigure $s2 -translation]
+    close $s1
+    close $s2
+    set modes
+} {auto lf}
+test io-39.19 {Tcl_SetChannelOption, setting read mode independently} \
+	{socket} {
+    proc accept {s a p} {close $s}
+    set s1 [socket -server [namespace code accept] -myaddr 127.0.0.1 0]
+    set port [lindex [fconfigure $s1 -sockname] 2]
+    set s2 [socket 127.0.0.1 $port]
+    update
+    fconfigure $s2 -translation {auto crlf}
+    set modes [fconfigure $s2 -translation]
+    close $s1
+    close $s2
+    set modes
+} {auto crlf}
+test io-39.20 {Tcl_SetChannelOption, setting read mode independently} \
+	{socket} {
+    proc accept {s a p} {close $s}
+    set s1 [socket -server [namespace code accept] -myaddr 127.0.0.1 0]
+    set port [lindex [fconfigure $s1 -sockname] 2]
+    set s2 [socket 127.0.0.1 $port]
+    update
+    fconfigure $s2 -translation {auto cr}
+    set modes [fconfigure $s2 -translation]
+    close $s1
+    close $s2
+    set modes
+} {auto cr}
+test io-39.21 {Tcl_SetChannelOption, setting read mode independently} \
+	{socket} {
+    proc accept {s a p} {close $s}
+    set s1 [socket -server [namespace code accept] -myaddr 127.0.0.1 0]
+    set port [lindex [fconfigure $s1 -sockname] 2]
+    set s2 [socket 127.0.0.1 $port]
+    update
+    fconfigure $s2 -translation {auto auto}
+    set modes [fconfigure $s2 -translation]
+    close $s1
+    close $s2
+    set modes
+} {auto crlf}
+test io-39.22 {Tcl_SetChannelOption, invariance} {unix} {
+    file delete $path(test1)
+    set f1 [open $path(test1) w+]
+    set l ""
+    lappend l [fconfigure $f1 -eofchar]
+    fconfigure $f1 -eofchar {ON GO}
+    lappend l [fconfigure $f1 -eofchar]
+    fconfigure $f1 -eofchar D
+    lappend l [fconfigure $f1 -eofchar]
+    close $f1
+    set l
+} {{{} {}} {O G} {D D}}
+test io-39.22a {Tcl_SetChannelOption, invariance} {
+    file delete $path(test1)
+    set f1 [open $path(test1) w+]
+    set l [list]
+    fconfigure $f1 -eofchar {ON GO}
+    lappend l [fconfigure $f1 -eofchar]
+    fconfigure $f1 -eofchar D
+    lappend l [fconfigure $f1 -eofchar]
+    lappend l [list [catch {fconfigure $f1 -eofchar {1 2 3}} msg] $msg]
+    close $f1
+    set l
+} {{O G} {D D} {1 {bad value for -eofchar: should be a list of zero, one, or two elements}}}
+test io-39.23 {Tcl_GetChannelOption, server socket is not readable or
+        writeable, it should still have valid -eofchar and -translation options } {
+    set l [list]
+    set sock [socket -server [namespace code accept] -myaddr 127.0.0.1 0]
+    lappend l [fconfigure $sock -eofchar] [fconfigure $sock -translation]
+    close $sock
+    set l
+} {{{}} auto}
+test io-39.24 {Tcl_SetChannelOption, server socket is not readable or
+        writable so we can't change -eofchar or -translation } {
+    set l [list]
+    set sock [socket -server [namespace code accept] -myaddr 127.0.0.1 0]
+    fconfigure $sock -eofchar D -translation lf
+    lappend l [fconfigure $sock -eofchar] [fconfigure $sock -translation]
+    close $sock
+    set l
+} {{{}} auto}
+
+test io-40.1 {POSIX open access modes: RDWR} {
+    file delete $path(test3)
+    set f [open $path(test3) w]
+    puts $f xyzzy
+    close $f
+    set f [open $path(test3) RDWR]
+    puts -nonewline $f "ab"
+    seek $f 0 current
+    set x [gets $f]
+    close $f
+    set f [open $path(test3) r]
+    lappend x [gets $f]
+    close $f
+    set x
+} {zzy abzzy}
+test io-40.2 {POSIX open access modes: CREAT} {unix} {
+    file delete $path(test3)
+    set f [open $path(test3) {WRONLY CREAT} 0o600]
+    file stat $path(test3) stats
+    set x [format "0o%o" [expr $stats(mode)&0o777]]
+    puts $f "line 1"
+    close $f
+    set f [open $path(test3) r]
+    lappend x [gets $f]
+    close $f
+    set x
+} {0o600 {line 1}}
+test io-40.3 {POSIX open access modes: CREAT} {unix umask} {
+    # This test only works if your umask is 2, like ouster's.
+    file delete $path(test3)
+    set f [open $path(test3) {WRONLY CREAT}]
+    close $f
+    file stat $path(test3) stats
+    format "0%o" [expr $stats(mode)&0o777]
+} [format %04o [expr {0o666 & ~ $umaskValue}]]
+test io-40.4 {POSIX open access modes: CREAT} {
+    file delete $path(test3)
+    set f [open $path(test3) w]
+    fconfigure $f -eofchar {}
+    puts $f xyzzy
+    close $f
+    set f [open $path(test3) {WRONLY CREAT}]
+    fconfigure $f -eofchar {}
+    puts -nonewline $f "ab"
+    close $f
+    set f [open $path(test3) r]
+    set x [gets $f]
+    close $f
+    set x
+} abzzy
+test io-40.5 {POSIX open access modes: APPEND} {
+    file delete $path(test3)
+    set f [open $path(test3) w]
+    fconfigure $f -translation lf -eofchar {}
+    puts $f xyzzy
+    close $f
+    set f [open $path(test3) {WRONLY APPEND}]
+    fconfigure $f -translation lf
+    puts $f "new line"
+    seek $f 0
+    puts $f "abc"
+    close $f
+    set f [open $path(test3) r]
+    fconfigure $f -translation lf
+    set x ""
+    seek $f 6 current
+    lappend x [gets $f]
+    lappend x [gets $f]
+    close $f
+    set x
+} {{new line} abc}
+test io-40.6 {POSIX open access modes: EXCL} -match regexp -body {
+    file delete $path(test3)
+    set f [open $path(test3) w]
+    puts $f xyzzy
+    close $f
+    open $path(test3) {WRONLY CREAT EXCL}
+} -returnCodes error -result {(?i)couldn't open ".*test3": file (already )?exists}
+test io-40.7 {POSIX open access modes: EXCL} {
+    file delete $path(test3)
+    set f [open $path(test3) {WRONLY CREAT EXCL}]
+    fconfigure $f -eofchar {}
+    puts $f "A test line"
+    close $f
+    viewFile test3
+} {A test line}
+test io-40.8 {POSIX open access modes: TRUNC} {
+    file delete $path(test3)
+    set f [open $path(test3) w]
+    puts $f xyzzy
+    close $f
+    set f [open $path(test3) {WRONLY TRUNC}]
+    puts $f abc
+    close $f
+    set f [open $path(test3) r]
+    set x [gets $f]
+    close $f
+    set x
+} abc
+test io-40.9 {POSIX open access modes: NONBLOCK} {nonPortable unix} {
+    file delete $path(test3)
+    set f [open $path(test3) {WRONLY NONBLOCK CREAT}]
+    puts $f "NONBLOCK test"
+    close $f
+    set f [open $path(test3) r]
+    set x [gets $f]
+    close $f
+    set x
+} {NONBLOCK test}
+test io-40.10 {POSIX open access modes: RDONLY} {
+    set f [open $path(test1) w]
+    puts $f "two lines: this one"
+    puts $f "and this"
+    close $f
+    set f [open $path(test1) RDONLY]
+    set x [list [gets $f] [catch {puts $f Test} msg] $msg]
+    close $f
+    string compare [string tolower $x] \
+	[list {two lines: this one} 1 \
+		[format "channel \"%s\" wasn't opened for writing" $f]]
+} 0
+test io-40.11 {POSIX open access modes: RDONLY} -match regexp -body {
+    file delete $path(test3)
+    open $path(test3) RDONLY
+} -returnCodes error -result {(?i)couldn't open ".*test3": no such file or directory}
+test io-40.12 {POSIX open access modes: WRONLY} -match regexp -body {
+    file delete $path(test3)
+    open $path(test3) WRONLY
+} -returnCodes error -result {(?i)couldn't open ".*test3": no such file or directory}
+test io-40.13 {POSIX open access modes: WRONLY} {
+    makeFile xyzzy test3
+    set f [open $path(test3) WRONLY]
+    fconfigure $f -eofchar {}
+    puts -nonewline $f "ab"
+    seek $f 0 current
+    set x [list [catch {gets $f} msg] $msg]
+    close $f
+    lappend x [viewFile test3]
+    string compare [string tolower $x] \
+	[list 1 "channel \"$f\" wasn't opened for reading" abzzy]
+} 0
+test io-40.14 {POSIX open access modes: RDWR} -match regexp -body {
+    file delete $path(test3)
+    open $path(test3) RDWR
+} -returnCodes error -result {(?i)couldn't open ".*test3": no such file or directory}
+test io-40.15 {POSIX open access modes: RDWR} {
+    makeFile xyzzy test3
+    set f [open $path(test3) RDWR]
+    puts -nonewline $f "ab"
+    seek $f 0 current
+    set x [gets $f]
+    close $f
+    lappend x [viewFile test3]
+} {zzy abzzy}
+test io-40.16 {tilde substitution in open} -constraints makeFileInHome -setup {
+    makeFile {Some text} _test_ ~
+} -body {
+    file exists [file join $::env(HOME) _test_]
+} -cleanup {
+    removeFile _test_ ~
+} -result 1
+test io-40.17 {tilde substitution in open} {
+    set home $::env(HOME)
+    unset ::env(HOME)
+    set x [list [catch {open ~/foo} msg] $msg]
+    set ::env(HOME) $home
+    set x
+} {1 {couldn't find HOME environment variable to expand path}}
+
+test io-41.1 {Tcl_FileeventCmd: errors} {fileevent} {
+    list [catch {fileevent foo} msg] $msg
+} {1 {wrong # args: should be "fileevent channelId event ?script?"}}
+test io-41.2 {Tcl_FileeventCmd: errors} {fileevent} {
+    list [catch {fileevent foo bar baz q} msg] $msg
+} {1 {wrong # args: should be "fileevent channelId event ?script?"}}
+test io-41.3 {Tcl_FileeventCmd: errors} {fileevent} {
+    list [catch {fileevent gorp readable} msg] $msg
+} {1 {can not find channel named "gorp"}}
+test io-41.4 {Tcl_FileeventCmd: errors} {fileevent} {
+    list [catch {fileevent gorp writable} msg] $msg
+} {1 {can not find channel named "gorp"}}
+test io-41.5 {Tcl_FileeventCmd: errors} {fileevent} {
+    list [catch {fileevent gorp who-knows} msg] $msg
+} {1 {bad event name "who-knows": must be readable or writable}}
+
+#
+# Test fileevent on a file
+#
+
+set path(foo) [makeFile {} foo]
+set f [open $path(foo) w+]
+
+test io-42.1 {Tcl_FileeventCmd: creating, deleting, querying} {fileevent} {
+    list [fileevent $f readable] [fileevent $f writable]
+} {{} {}}
+test io-42.2 {Tcl_FileeventCmd: replacing} {fileevent} {
+    set result {}
+    fileevent $f r "first script"
+    lappend result [fileevent $f readable]
+    fileevent $f r "new script"
+    lappend result [fileevent $f readable]
+    fileevent $f r "yet another"
+    lappend result [fileevent $f readable]
+    fileevent $f r ""
+    lappend result [fileevent $f readable]
+} {{first script} {new script} {yet another} {}}
+test io-42.3 {Tcl_FileeventCmd: replacing, with NULL chars in script} {fileevent} {
+    set result {}
+    fileevent $f r "first scr\0ipt"
+    lappend result [string length [fileevent $f readable]]
+    fileevent $f r "new scr\0ipt"
+    lappend result [string length [fileevent $f readable]]
+    fileevent $f r "yet ano\0ther"
+    lappend result [string length [fileevent $f readable]]
+    fileevent $f r ""
+    lappend result [fileevent $f readable]
+} {13 11 12 {}}
+
+
+test io-43.1 {Tcl_FileeventCmd: creating, deleting, querying} {stdio unixExecs fileevent} {
+    set result {}
+    fileevent $f readable "script 1"
+    lappend result [fileevent $f readable] [fileevent $f writable]
+    fileevent $f writable "write script"
+    lappend result [fileevent $f readable] [fileevent $f writable]
+    fileevent $f readable {}
+    lappend result [fileevent $f readable] [fileevent $f writable]
+    fileevent $f writable {}
+    lappend result [fileevent $f readable] [fileevent $f writable]
+} {{script 1} {} {script 1} {write script} {} {write script} {} {}}
+test io-43.2 {Tcl_FileeventCmd: deleting when many present} -setup {
+    set f2 [open "|[list cat -u]" r+]
+    set f3 [open "|[list cat -u]" r+]
+} -constraints {stdio unixExecs fileevent openpipe} -body {
+    set result {}
+    lappend result [fileevent $f r] [fileevent $f2 r] [fileevent $f3 r]
+    fileevent $f r "read f"
+    fileevent $f2 r "read f2"
+    fileevent $f3 r "read f3"
+    lappend result [fileevent $f r] [fileevent $f2 r] [fileevent $f3 r]
+    fileevent $f2 r {}
+    lappend result [fileevent $f r] [fileevent $f2 r] [fileevent $f3 r]
+    fileevent $f3 r {}
+    lappend result [fileevent $f r] [fileevent $f2 r] [fileevent $f3 r]
+    fileevent $f r {}
+    lappend result [fileevent $f r] [fileevent $f2 r] [fileevent $f3 r]
+} -cleanup {
+    catch {close $f2}
+    catch {close $f3}
+} -result {{} {} {} {read f} {read f2} {read f3} {read f} {} {read f3} {read f} {} {} {} {} {}}
+
+test io-44.1 {FileEventProc procedure: normal read event} -setup {
+    set f2 [open "|[list cat -u]" r+]
+    set f3 [open "|[list cat -u]" r+]
+} -constraints {stdio unixExecs fileevent openpipe} -body {
+    fileevent $f2 readable [namespace code {
+	set x [gets $f2]; fileevent $f2 readable {}
+    }]
+    puts $f2 text; flush $f2
+    variable x initial
+    vwait [namespace which -variable x]
+    set x
+} -cleanup {
+    catch {close $f2}
+    catch {close $f3}
+} -result {text}
+test io-44.2 {FileEventProc procedure: error in read event} -constraints {
+    stdio unixExecs fileevent openpipe
+} -setup {
+    set f2 [open "|[list cat -u]" r+]
+    set f3 [open "|[list cat -u]" r+]
+    proc myHandler {msg options} {
+	variable x $msg
+    }
+    set handler [interp bgerror {}]
+    interp bgerror {} [namespace which myHandler]
+} -body {
+    fileevent $f2 readable {error bogus}
+    puts $f2 text; flush $f2
+    variable x initial
+    vwait [namespace which -variable x]
+    list $x [fileevent $f2 readable]
+} -cleanup {
+    interp bgerror {} $handler
+    catch {close $f2}
+    catch {close $f3}
+} -result {bogus {}}
+test io-44.3 {FileEventProc procedure: normal write event} -setup {
+    set f2 [open "|[list cat -u]" r+]
+    set f3 [open "|[list cat -u]" r+]
+} -constraints {stdio unixExecs fileevent openpipe} -body {
+    fileevent $f2 writable [namespace code {
+	lappend x "triggered"
+	incr count -1
+	if {$count <= 0} {
+	    fileevent $f2 writable {}
+	}
+    }]
+    variable x initial
+    set count 3
+    vwait [namespace which -variable x]
+    vwait [namespace which -variable x]
+    vwait [namespace which -variable x]
+    set x
+} -cleanup {
+    catch {close $f2}
+    catch {close $f3}
+} -result {initial triggered triggered triggered}
+test io-44.4 {FileEventProc procedure: eror in write event} -constraints {
+    stdio unixExecs fileevent openpipe
+} -setup {
+    set f2 [open "|[list cat -u]" r+]
+    set f3 [open "|[list cat -u]" r+]
+    proc myHandler {msg options} {
+	variable x $msg
+    }
+    set handler [interp bgerror {}]
+    interp bgerror {} [namespace which myHandler]
+} -body {
+    fileevent $f2 writable {error bad-write}
+    variable x initial
+    vwait [namespace which -variable x]
+    list $x [fileevent $f2 writable]
+} -cleanup {
+    interp bgerror {} $handler
+    catch {close $f2}
+    catch {close $f3}
+} -result {bad-write {}}
+test io-44.5 {FileEventProc procedure: end of file} {stdio unixExecs openpipe fileevent} {
+    set f4 [open "|[list [interpreter] $path(cat) << foo]" r]
+    fileevent $f4 readable [namespace code {
+	if {[gets $f4 line] < 0} {
+	    lappend x eof
+	    fileevent $f4 readable {}
+	} else {
+	    lappend x $line
+	}
+    }]
+    variable x initial
+    vwait [namespace which -variable x]
+    vwait [namespace which -variable x]
+    close $f4
+    set x
+} {initial foo eof}
+
+close $f
+makeFile "foo bar" foo
+
+test io-45.1 {DeleteFileEvent, cleanup on close} {fileevent} {
+    set f [open $path(foo) r]
+    fileevent $f readable [namespace code {
+	lappend x "binding triggered: \"[gets $f]\""
+	fileevent $f readable {}
+    }]
+    close $f
+    set x initial
+    after 100 [namespace code { set y done }]
+    variable y
+    vwait [namespace which -variable y]
+    set x
+} {initial}
+test io-45.2 {DeleteFileEvent, cleanup on close} {fileevent} {
+    set f  [open $path(foo) r]
+    set f2 [open $path(foo) r]
+    fileevent $f readable [namespace code {
+	    lappend x "f triggered: \"[gets $f]\""
+	    fileevent $f readable {}
+	}]
+    fileevent $f2 readable [namespace code {
+	lappend x "f2 triggered: \"[gets $f2]\""
+	fileevent $f2 readable {}
+    }]
+    close $f
+    variable x initial
+    vwait [namespace which -variable x]
+    close $f2
+    set x
+} {initial {f2 triggered: "foo bar"}}
+test io-45.3 {DeleteFileEvent, cleanup on close} {fileevent} {
+    set f  [open $path(foo) r]
+    set f2 [open $path(foo) r]
+    set f3 [open $path(foo) r]
+    fileevent $f readable {f script}
+    fileevent $f2 readable {f2 script}
+    fileevent $f3 readable {f3 script}
+    set x {}
+    close $f2
+    lappend x [catch {fileevent $f readable} msg] $msg \
+	    [catch {fileevent $f2 readable}] \
+	    [catch {fileevent $f3 readable} msg] $msg
+    close $f3
+    lappend x [catch {fileevent $f readable} msg] $msg \
+	    [catch {fileevent $f2 readable}] \
+	    [catch {fileevent $f3 readable}]
+    close $f
+    lappend x [catch {fileevent $f readable}] \
+	    [catch {fileevent $f2 readable}] \
+	    [catch {fileevent $f3 readable}]
+} {0 {f script} 1 0 {f3 script} 0 {f script} 1 1 1 1 1}
+
+# Execute these tests only if the "testfevent" command is present.
+
+test io-46.1 {Tcl event loop vs multiple interpreters} {testfevent fileevent} {
+    testfevent create
+    set script "set f \[[list open $path(foo) r]]\n"
+    append script {
+	set x "no event"
+	fileevent $f readable [namespace code {
+	    set x "f triggered: [gets $f]"
+	    fileevent $f readable {}
+	}]
+    }
+    testfevent cmd $script
+    after 1	;# We must delay because Windows takes a little time to notice
+    update
+    testfevent cmd {close $f}
+    list [testfevent cmd {set x}] [testfevent cmd {info commands after}]
+} {{f triggered: foo bar} after}
+test io-46.2 {Tcl event loop vs multiple interpreters} testfevent {
+    testfevent create
+    testfevent cmd {
+        variable x 0
+        after 100 {set x triggered}
+        vwait [namespace which -variable x]
+        set x
+    }
+} {triggered}
+test io-46.3 {Tcl event loop vs multiple interpreters} testfevent {
+    testfevent create
+    testfevent cmd {
+        set x 0
+        after 10 {lappend x timer}
+        after 30
+        set result $x
+        update idletasks
+        lappend result $x
+        update
+        lappend result $x
+    }
+} {0 0 {0 timer}}
+
+test io-47.1 {fileevent vs multiple interpreters} {testfevent fileevent} {
+    set f  [open $path(foo) r]
+    set f2 [open $path(foo) r]
+    set f3 [open $path(foo) r]
+    fileevent $f readable {script 1}
+    testfevent create
+    testfevent share $f2
+    testfevent cmd "fileevent $f2 readable {script 2}"
+    fileevent $f3 readable {sript 3}
+    set x {}
+    lappend x [fileevent $f2 readable]
+    testfevent delete
+    lappend x [fileevent $f readable] [fileevent $f2 readable] \
+        [fileevent $f3 readable]
+    close $f
+    close $f2
+    close $f3
+    set x
+} {{} {script 1} {} {sript 3}}
+test io-47.2 {deleting fileevent on interpreter delete} {testfevent fileevent} {
+    set f  [open $path(foo) r]
+    set f2 [open $path(foo) r]
+    set f3 [open $path(foo) r]
+    set f4 [open $path(foo) r]
+    fileevent $f readable {script 1}
+    testfevent create
+    testfevent share $f2
+    testfevent share $f3
+    testfevent cmd "fileevent $f2 readable {script 2}
+        fileevent $f3 readable {script 3}"
+    fileevent $f4 readable {script 4}
+    testfevent delete
+    set x [list [fileevent $f readable] [fileevent $f2 readable] \
+                [fileevent $f3 readable] [fileevent $f4 readable]]
+    close $f
+    close $f2
+    close $f3
+    close $f4
+    set x
+} {{script 1} {} {} {script 4}}
+test io-47.3 {deleting fileevent on interpreter delete} {testfevent fileevent} {
+    set f  [open $path(foo) r]
+    set f2 [open $path(foo) r]
+    set f3 [open $path(foo) r]
+    set f4 [open $path(foo) r]
+    testfevent create
+    testfevent share $f3
+    testfevent share $f4
+    fileevent $f readable {script 1}
+    fileevent $f2 readable {script 2}
+    testfevent cmd "fileevent $f3 readable {script 3}
+      fileevent $f4 readable {script 4}"
+    testfevent delete
+    set x [list [fileevent $f readable] [fileevent $f2 readable] \
+                [fileevent $f3 readable] [fileevent $f4 readable]]
+    close $f
+    close $f2
+    close $f3
+    close $f4
+    set x
+} {{script 1} {script 2} {} {}}
+test io-47.4 {file events on shared files and multiple interpreters} {testfevent fileevent} {
+    set f  [open $path(foo) r]
+    set f2 [open $path(foo) r]
+    testfevent create
+    testfevent share $f
+    testfevent cmd "fileevent $f readable {script 1}"
+    fileevent $f readable {script 2}
+    fileevent $f2 readable {script 3}
+    set x [list [fileevent $f2 readable] \
+                [testfevent cmd "fileevent $f readable"] \
+                [fileevent $f readable]]
+    testfevent delete
+    close $f
+    close $f2
+    set x
+} {{script 3} {script 1} {script 2}}
+test io-47.5 {file events on shared files, deleting file events} {testfevent fileevent} {
+    set f [open $path(foo) r]
+    testfevent create
+    testfevent share $f
+    testfevent cmd "fileevent $f readable {script 1}"
+    fileevent $f readable {script 2}
+    testfevent cmd "fileevent $f readable {}"
+    set x [list [testfevent cmd "fileevent $f readable"] \
+                [fileevent $f readable]]
+    testfevent delete
+    close $f
+    set x
+} {{} {script 2}}
+test io-47.6 {file events on shared files, deleting file events} {testfevent fileevent} {
+    set f [open $path(foo) r]
+    testfevent create
+    testfevent share $f
+    testfevent cmd "fileevent $f readable {script 1}"
+    fileevent $f readable {script 2}
+    fileevent $f readable {}
+    set x [list [testfevent cmd "fileevent $f readable"] \
+                [fileevent $f readable]]
+    testfevent delete
+    close $f
+    set x
+} {{script 1} {}}
+
+set path(bar) [makeFile {} bar]
+
+test io-48.1 {testing readability conditions} {fileevent} {
+    set f [open $path(bar) w]
+    puts $f abcdefg
+    puts $f abcdefg
+    puts $f abcdefg
+    puts $f abcdefg
+    puts $f abcdefg
+    close $f
+    set f [open $path(bar) r]
+    fileevent $f readable [namespace code [list consume $f]]
+    proc consume {f} {
+	variable l
+	variable x
+	lappend l called
+	if {[eof $f]} {
+	    close $f
+	    set x done
+	} else {
+	    gets $f
+	}
+    }
+    set l ""
+    variable x not_done
+    vwait [namespace which -variable x]
+    list $x $l
+} {done {called called called called called called called}}
+test io-48.2 {testing readability conditions} {nonBlockFiles fileevent} {
+    set f [open $path(bar) w]
+    puts $f abcdefg
+    puts $f abcdefg
+    puts $f abcdefg
+    puts $f abcdefg
+    puts $f abcdefg
+    close $f
+    set f [open $path(bar) r]
+    fileevent $f readable [namespace code [list consume $f]]
+    fconfigure $f -blocking off
+    proc consume {f} {
+	variable x
+	variable l
+	lappend l called
+	if {[eof $f]} {
+	    close $f
+	    set x done
+	} else {
+	    gets $f
+	}
+    }
+    set l ""
+    variable x not_done
+    vwait [namespace which -variable x]
+    list $x $l
+} {done {called called called called called called called}}
+set path(my_script) [makeFile {} my_script]
+test io-48.3 {testing readability conditions} {stdio unix nonBlockFiles openpipe fileevent} {
+    set f [open $path(bar) w]
+    puts $f abcdefg
+    puts $f abcdefg
+    puts $f abcdefg
+    puts $f abcdefg
+    puts $f abcdefg
+    close $f
+    set f [open $path(my_script) w]
+    puts $f {
+	proc copy_slowly {f} {
+	    while {![eof $f]} {
+		puts [gets $f]
+		after 200
+	    }
+	    close $f
+	}
+    }
+    close $f
+    set f [open "|[list [interpreter]]" r+]
+    fileevent  $f readable [namespace code [list consume $f]]
+    fconfigure $f -buffering line
+    fconfigure $f -blocking off
+    proc consume {f} {
+	variable l
+	variable x
+	if {[eof $f]} {
+	    set x done
+	} else {
+	    gets $f
+	    lappend l [fblocked $f]
+	    gets $f
+	    lappend l [fblocked $f]
+	}
+    }
+    set l ""
+    variable x not_done
+    puts $f [list source $path(my_script)]
+    puts $f "set f \[[list open $path(bar) r]]"
+    puts $f {copy_slowly $f}
+    puts $f {exit}
+    vwait [namespace which -variable x]
+    close $f
+    list $x $l
+} {done {0 1 0 1 0 1 0 1 0 1 0 1 0 0}}
+test io-48.4 {lf write, testing readability, ^Z termination, auto read mode} {fileevent} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    fconfigure $f -translation lf
+    variable c [format "abc\ndef\n%c" 26]
+    puts -nonewline $f $c
+    close $f
+    proc consume {f} {
+	variable l
+	variable c
+	variable x
+	if {[eof $f]} {
+	   set x done
+	   close $f
+	} else {
+	   lappend l [gets $f]
+	   incr c
+	}
+    }
+    set c 0
+    set l ""
+    set f [open $path(test1) r]
+    fconfigure $f -translation auto -eofchar \x1a
+    fileevent $f readable [namespace code [list consume $f]]
+    variable x
+    vwait [namespace which -variable x]
+    list $c $l
+} {3 {abc def {}}}
+test io-48.5 {lf write, testing readability, ^Z in middle, auto read mode} {fileevent} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    fconfigure $f -translation lf
+    set c [format "abc\ndef\n%cfoo\nbar\n" 26]
+    puts -nonewline $f $c
+    close $f
+    proc consume {f} {
+	variable l
+	variable x
+	variable c
+	if {[eof $f]} {
+	   set x done
+	   close $f
+	} else {
+	   lappend l [gets $f]
+	   incr c
+	}
+    }
+    set c 0
+    set l ""
+    set f [open $path(test1) r]
+    fconfigure $f -eofchar \x1a -translation auto
+    fileevent $f readable [namespace code [list consume $f]]
+    variable x
+    vwait [namespace which -variable x]
+    list $c $l
+} {3 {abc def {}}}
+test io-48.6 {cr write, testing readability, ^Z termination, auto read mode} {fileevent} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    fconfigure $f -translation cr
+    set c [format "abc\ndef\n%c" 26]
+    puts -nonewline $f $c
+    close $f
+    proc consume {f} {
+	variable l
+	variable x
+	variable c
+	if {[eof $f]} {
+	   set x done
+	   close $f
+	} else {
+	   lappend l [gets $f]
+	   incr c
+	}
+    }
+    set c 0
+    set l ""
+    set f [open $path(test1) r]
+    fconfigure $f -translation auto -eofchar \x1a
+    fileevent $f readable [namespace code [list consume $f]]
+    variable x
+    vwait [namespace which -variable x]
+    list $c $l
+} {3 {abc def {}}}
+test io-48.7 {cr write, testing readability, ^Z in middle, auto read mode} {fileevent} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    fconfigure $f -translation cr
+    set c [format "abc\ndef\n%cfoo\nbar\n" 26]
+    puts -nonewline $f $c
+    close $f
+    proc consume {f} {
+	variable l
+	variable c
+	variable x
+	if {[eof $f]} {
+	   set x done
+	   close $f
+	} else {
+	   lappend l [gets $f]
+	   incr c
+	}
+    }
+    set c 0
+    set l ""
+    set f [open $path(test1) r]
+    fconfigure $f -eofchar \x1a -translation auto
+    fileevent $f readable [namespace code [list consume $f]]
+    variable x
+    vwait [namespace which -variable x]
+    list $c $l
+} {3 {abc def {}}}
+test io-48.8 {crlf write, testing readability, ^Z termination, auto read mode} {fileevent} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    fconfigure $f -translation crlf
+    set c [format "abc\ndef\n%c" 26]
+    puts -nonewline $f $c
+    close $f
+    proc consume {f} {
+	variable l
+	variable x
+	variable c
+	if {[eof $f]} {
+	   set x done
+	   close $f
+	} else {
+	   lappend l [gets $f]
+	   incr c
+	}
+    }
+    set c 0
+    set l ""
+    set f [open $path(test1) r]
+    fconfigure $f -translation auto -eofchar \x1a
+    fileevent $f readable [namespace code [list consume $f]]
+    variable x
+    vwait [namespace which -variable x]
+    list $c $l
+} {3 {abc def {}}}
+test io-48.9 {crlf write, testing readability, ^Z in middle, auto read mode} {fileevent} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    fconfigure $f -translation crlf
+    set c [format "abc\ndef\n%cfoo\nbar\n" 26]
+    puts -nonewline $f $c
+    close $f
+    proc consume {f} {
+	variable l
+	variable c
+	variable x
+	if {[eof $f]} {
+	   set x done
+	   close $f
+	} else {
+	   lappend l [gets $f]
+	   incr c
+	}
+    }
+    set c 0
+    set l ""
+    set f [open $path(test1) r]
+    fconfigure $f -eofchar \x1a -translation auto
+    fileevent $f readable [namespace code [list consume $f]]
+    variable x
+    vwait [namespace which -variable x]
+    list $c $l
+} {3 {abc def {}}}
+test io-48.10 {lf write, testing readability, ^Z in middle, lf read mode} {fileevent} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    fconfigure $f -translation lf
+    set c [format "abc\ndef\n%cfoo\nbar\n" 26]
+    puts -nonewline $f $c
+    close $f
+    proc consume {f} {
+	variable l
+	variable c
+	variable x
+	if {[eof $f]} {
+	   set x done
+	   close $f
+	} else {
+	   lappend l [gets $f]
+	   incr c
+	}
+    }
+    set c 0
+    set l ""
+    set f [open $path(test1) r]
+    fconfigure $f -eofchar \x1a -translation lf
+    fileevent $f readable [namespace code [list consume $f]]
+    variable x
+    vwait [namespace which -variable x]
+    list $c $l
+} {3 {abc def {}}}
+test io-48.11 {lf write, testing readability, ^Z termination, lf read mode} {fileevent} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    fconfigure $f -translation lf
+    set c [format "abc\ndef\n%c" 26]
+    puts -nonewline $f $c
+    close $f
+    proc consume {f} {
+	variable l
+	variable x
+	variable c
+	if {[eof $f]} {
+	   set x done
+	   close $f
+	} else {
+	   lappend l [gets $f]
+	   incr c
+	}
+    }
+    set c 0
+    set l ""
+    set f [open $path(test1) r]
+    fconfigure $f -translation lf -eofchar \x1a
+    fileevent $f readable [namespace code [list consume $f]]
+    variable x
+    vwait [namespace which -variable x]
+    list $c $l
+} {3 {abc def {}}}
+test io-48.12 {cr write, testing readability, ^Z in middle, cr read mode} {fileevent} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    fconfigure $f -translation cr
+    set c [format "abc\ndef\n%cfoo\nbar\n" 26]
+    puts -nonewline $f $c
+    close $f
+    proc consume {f} {
+	variable l
+	variable x
+	variable c
+	if {[eof $f]} {
+	   set x done
+	   close $f
+	} else {
+	   lappend l [gets $f]
+	   incr c
+	}
+    }
+    set c 0
+    set l ""
+    set f [open $path(test1) r]
+    fconfigure $f -eofchar \x1a -translation cr
+    fileevent $f readable [namespace code [list consume $f]]
+    variable x
+    vwait [namespace which -variable x]
+    list $c $l
+} {3 {abc def {}}}
+test io-48.13 {cr write, testing readability, ^Z termination, cr read mode} {fileevent} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    fconfigure $f -translation cr
+    set c [format "abc\ndef\n%c" 26]
+    puts -nonewline $f $c
+    close $f
+    proc consume {f} {
+	variable c
+	variable x
+	variable l
+	if {[eof $f]} {
+	   set x done
+	   close $f
+	} else {
+	   lappend l [gets $f]
+	   incr c
+	}
+    }
+    set c 0
+    set l ""
+    set f [open $path(test1) r]
+    fconfigure $f -translation cr -eofchar \x1a
+    fileevent $f readable [namespace code [list consume $f]]
+    variable x
+    vwait [namespace which -variable x]
+    list $c $l
+} {3 {abc def {}}}
+test io-48.14 {crlf write, testing readability, ^Z in middle, crlf read mode} {fileevent} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    fconfigure $f -translation crlf
+    set c [format "abc\ndef\n%cfoo\nbar\n" 26]
+    puts -nonewline $f $c
+    close $f
+    proc consume {f} {
+	variable c
+	variable x
+	variable l
+	if {[eof $f]} {
+	   set x done
+	   close $f
+	} else {
+	   lappend l [gets $f]
+	   incr c
+	}
+    }
+    set c 0
+    set l ""
+    set f [open $path(test1) r]
+    fconfigure $f -eofchar \x1a -translation crlf
+    fileevent $f readable [namespace code [list consume $f]]
+    variable x
+    vwait [namespace which -variable x]
+    list $c $l
+} {3 {abc def {}}}
+test io-48.15 {crlf write, testing readability, ^Z termi, crlf read mode} {fileevent} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    fconfigure $f -translation crlf
+    set c [format "abc\ndef\n%c" 26]
+    puts -nonewline $f $c
+    close $f
+    proc consume {f} {
+	variable c
+	variable x
+	variable l
+	if {[eof $f]} {
+	   set x done
+	   close $f
+	} else {
+	   lappend l [gets $f]
+	   incr c
+	}
+    }
+    set c 0
+    set l ""
+    set f [open $path(test1) r]
+    fconfigure $f -translation crlf -eofchar \x1a
+    fileevent $f readable [namespace code [list consume $f]]
+    variable x
+    vwait [namespace which -variable x]
+    list $c $l
+} {3 {abc def {}}}
+
+test io-49.1 {testing crlf reading, leftover cr disgorgment} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    fconfigure $f -translation lf
+    puts -nonewline $f "a\rb\rc\r\n"
+    close $f
+    set f [open $path(test1) r]
+    set l ""
+    lappend l [file size $path(test1)]
+    fconfigure $f -translation crlf
+    lappend l [read $f 1]
+    lappend l [tell $f]
+    lappend l [read $f 1]
+    lappend l [tell $f]
+    lappend l [read $f 1]
+    lappend l [tell $f]
+    lappend l [read $f 1]
+    lappend l [tell $f]
+    lappend l [read $f 1]
+    lappend l [tell $f]
+    lappend l [read $f 1]
+    lappend l [tell $f]
+    lappend l [eof $f]
+    lappend l [read $f 1]
+    lappend l [eof $f]
+    close $f
+    set l
+} "7 a 1 [list \r] 2 b 3 [list \r] 4 c 5 {
+} 7 0 {} 1"
+test io-49.2 {testing crlf reading, leftover cr disgorgment} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    fconfigure $f -translation lf
+    puts -nonewline $f "a\rb\rc\r\n"
+    close $f
+    set f [open $path(test1) r]
+    set l ""
+    lappend l [file size $path(test1)]
+    fconfigure $f -translation crlf
+    lappend l [read $f 2]
+    lappend l [tell $f]
+    lappend l [read $f 2]
+    lappend l [tell $f]
+    lappend l [read $f 2]
+    lappend l [tell $f]
+    lappend l [eof $f]
+    lappend l [read $f 2]
+    lappend l [tell $f]
+    lappend l [eof $f]
+    close $f
+    set l
+} "7 [list a\r] 2 [list b\r] 4 [list c\n] 7 0 {} 7 1"
+test io-49.3 {testing crlf reading, leftover cr disgorgment} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    fconfigure $f -translation lf
+    puts -nonewline $f "a\rb\rc\r\n"
+    close $f
+    set f [open $path(test1) r]
+    set l ""
+    lappend l [file size $path(test1)]
+    fconfigure $f -translation crlf
+    lappend l [read $f 3]
+    lappend l [tell $f]
+    lappend l [read $f 3]
+    lappend l [tell $f]
+    lappend l [eof $f]
+    lappend l [read $f 3]
+    lappend l [tell $f]
+    lappend l [eof $f]
+    close $f
+    set l
+} "7 [list a\rb] 3 [list \rc\n] 7 0 {} 7 1"
+test io-49.4 {testing crlf reading, leftover cr disgorgment} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    fconfigure $f -translation lf
+    puts -nonewline $f "a\rb\rc\r\n"
+    close $f
+    set f [open $path(test1) r]
+    set l ""
+    lappend l [file size $path(test1)]
+    fconfigure $f -translation crlf
+    lappend l [read $f 3]
+    lappend l [tell $f]
+    lappend l [gets $f]
+    lappend l [tell $f]
+    lappend l [eof $f]
+    lappend l [gets $f]
+    lappend l [tell $f]
+    lappend l [eof $f]
+    close $f
+    set l
+} "7 [list a\rb] 3 [list \rc] 7 0 {} 7 1"
+test io-49.5 {testing crlf reading, leftover cr disgorgment} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    fconfigure $f -translation lf
+    puts -nonewline $f "a\rb\rc\r\n"
+    close $f
+    set f [open $path(test1) r]
+    set l ""
+    lappend l [file size $path(test1)]
+    fconfigure $f -translation crlf
+    lappend l [set x [gets $f]]
+    lappend l [tell $f]
+    lappend l [gets $f]
+    lappend l [tell $f]
+    lappend l [eof $f]
+    close $f
+    set l
+} [list 7 a\rb\rc 7 {} 7 1]
+
+test io-50.1 {testing handler deletion} {testchannelevent} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    close $f
+    set f [open $path(test1) r]
+    testchannelevent $f add readable [namespace code [list delhandler $f]]
+    proc delhandler {f} {
+	variable z
+	set z called
+	testchannelevent $f delete 0
+    }
+    set z not_called
+    update
+    close $f
+    set z
+} called
+test io-50.2 {testing handler deletion with multiple handlers} {testchannelevent} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    close $f
+    set f [open $path(test1) r]
+    testchannelevent $f add readable [namespace code [list delhandler $f 1]]
+    testchannelevent $f add readable [namespace code [list delhandler $f 0]]
+    proc delhandler {f i} {
+	variable z
+	lappend z "called delhandler $f $i"
+	testchannelevent $f delete 0
+    }
+    set z ""
+    update
+    close $f
+    string compare [string tolower $z] \
+	[list [list called delhandler $f 0] [list called delhandler $f 1]]
+} 0
+test io-50.3 {testing handler deletion with multiple handlers} {testchannelevent} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    close $f
+    set f [open $path(test1) r]
+    testchannelevent $f add readable [namespace code [list notcalled $f 1]]
+    testchannelevent $f add readable [namespace code [list delhandler $f 0]]
+    set z ""
+    proc notcalled {f i} {
+	variable z
+	lappend z "notcalled was called!! $f $i"
+    }
+    proc delhandler {f i} {
+	variable z
+	testchannelevent $f delete 1
+	lappend z "delhandler $f $i called"
+	testchannelevent $f delete 0
+	lappend z "delhandler $f $i deleted myself"
+    }
+    set z ""
+    update
+    close $f
+    string compare [string tolower $z] \
+	[list [list delhandler $f 0 called] \
+	      [list delhandler $f 0 deleted myself]]
+} 0
+test io-50.4 {testing handler deletion vs reentrant calls} {testchannelevent} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    close $f
+    set f [open $path(test1) r]
+    testchannelevent $f add readable [namespace code [list delrecursive $f]]
+    proc delrecursive {f} {
+	variable z
+	variable u
+	if {"$u" == "recursive"} {
+	    testchannelevent $f delete 0
+	    lappend z "delrecursive deleting recursive"
+	} else {
+	    lappend z "delrecursive calling recursive"
+	    set u recursive
+	    update
+	}
+    }
+    variable u toplevel
+    variable z ""
+    update
+    close $f
+    string compare [string tolower $z] \
+	{{delrecursive calling recursive} {delrecursive deleting recursive}}
+} 0
+test io-50.5 {testing handler deletion vs reentrant calls} {testchannelevent} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    close $f
+    set f [open $path(test1) r]
+    testchannelevent $f add readable [namespace code [list notcalled $f]]
+    testchannelevent $f add readable [namespace code [list del $f]]
+    proc notcalled {f} {
+	variable z
+	lappend z "notcalled was called!! $f"
+    }
+    proc del {f} {
+	variable u
+	variable z
+	if {"$u" == "recursive"} {
+	    testchannelevent $f delete 1
+	    testchannelevent $f delete 0
+	    lappend z "del deleted notcalled"
+	    lappend z "del deleted myself"
+	} else {
+	    set u recursive
+	    lappend z "del calling recursive"
+	    update
+	    lappend z "del after update"
+	}
+    }
+    set z ""
+    set u toplevel
+    update
+    close $f
+    string compare [string tolower $z] \
+	[list {del calling recursive} {del deleted notcalled} \
+	      {del deleted myself} {del after update}]
+} 0
+test io-50.6 {testing handler deletion vs reentrant calls} {testchannelevent} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    close $f
+    set f [open $path(test1) r]
+    testchannelevent $f add readable [namespace code [list second $f]]
+    testchannelevent $f add readable [namespace code [list first $f]]
+    proc first {f} {
+	variable u
+	variable z
+	if {"$u" == "toplevel"} {
+	    lappend z "first called"
+	    set u first
+	    update
+	    lappend z "first after update"
+	} else {
+	    lappend z "first called not toplevel"
+	}
+    }
+    proc second {f} {
+	variable u
+	variable z
+	if {"$u" == "first"} {
+	    lappend z "second called, first time"
+	    set u second
+	    testchannelevent $f delete 0
+	} elseif {"$u" == "second"} {
+	    lappend z "second called, second time"
+	    testchannelevent $f delete 0
+	} else {
+	    lappend z "second called, cannot happen!"
+	    testchannelevent $f removeall
+	}
+    }
+    set z ""
+    set u toplevel
+    update
+    close $f
+    string compare [string tolower $z] \
+	[list {first called} {first called not toplevel} \
+	      {second called, first time} {second called, second time} \
+	      {first after update}]
+} 0
+
+test io-51.1 {Test old socket deletion on Macintosh} {socket} {
+    set x 0
+    set result ""
+    proc accept {s a p} {
+	variable x
+	variable wait
+	fconfigure $s -blocking off
+	puts $s "sock[incr x]"
+	close $s
+	set wait done
+    }
+    set ss [socket -server [namespace code accept] -myaddr 127.0.0.1 0]
+    set port [lindex [fconfigure $ss -sockname] 2]
+
+    variable wait ""
+    set cs [socket 127.0.0.1 $port]
+    vwait [namespace which -variable wait]
+    lappend result [gets $cs]
+    close $cs
+
+    set wait ""
+    set cs [socket 127.0.0.1 $port]
+    vwait [namespace which -variable wait]
+    lappend result [gets $cs]
+    close $cs
+
+    set wait ""
+    set cs [socket 127.0.0.1 $port]
+    vwait [namespace which -variable wait]
+    lappend result [gets $cs]
+    close $cs
+
+    set wait ""
+    set cs [socket 127.0.0.1 $port]
+    vwait [namespace which -variable wait]
+    lappend result [gets $cs]
+    close $cs
+    close $ss
+    set result
+} {sock1 sock2 sock3 sock4}
+
+test io-52.1 {TclCopyChannel} {fcopy} {
+    file delete $path(test1)
+    set f1 [open $thisScript]
+    set f2 [open $path(test1) w]
+    fcopy $f1 $f2 -command { # }
+    catch { fcopy $f1 $f2 } msg
+    close $f1
+    close $f2
+    string compare $msg "channel \"$f1\" is busy"
+} {0}
+test io-52.2 {TclCopyChannel} {fcopy} {
+    file delete $path(test1)
+    set f1 [open $thisScript]
+    set f2 [open $path(test1) w]
+    set f3 [open $thisScript]
+    fcopy $f1 $f2 -command { # }
+    catch { fcopy $f3 $f2 } msg
+    close $f1
+    close $f2
+    close $f3
+    string compare $msg "channel \"$f2\" is busy"
+} {0}
+test io-52.3 {TclCopyChannel} {fcopy} {
+    file delete $path(test1)
+    set f1 [open $thisScript]
+    set f2 [open $path(test1) w]
+    fconfigure $f1 -translation lf -blocking 0
+    fconfigure $f2 -translation cr -blocking 0
+    set s0 [fcopy $f1 $f2]
+    set result [list [fconfigure $f1 -blocking] [fconfigure $f2 -blocking]]
+    close $f1
+    close $f2
+    set s1 [file size $thisScript]
+    set s2 [file size $path(test1)]
+    if {("$s1" == "$s2") && ($s0 == $s1)} {
+        lappend result ok
+    }
+    set result
+} {0 0 ok}
+test io-52.4 {TclCopyChannel} {fcopy} {
+    file delete $path(test1)
+    set f1 [open $thisScript]
+    set f2 [open $path(test1) w]
+    fconfigure $f1 -translation lf -blocking 0
+    fconfigure $f2 -translation cr -blocking 0
+    fcopy $f1 $f2 -size 40
+    set result [list [fblocked $f1] [fconfigure $f1 -blocking] [fconfigure $f2 -blocking]]
+    close $f1
+    close $f2
+    lappend result [file size $path(test1)]
+} {0 0 0 40}
+test io-52.4.1 {TclCopyChannel} {fcopy} {
+    file delete $path(test1)
+    set f1 [open $thisScript]
+    set f2 [open $path(test1) w]
+    fconfigure $f1 -translation lf -blocking 0 -buffersize 10000000
+    fconfigure $f2 -translation cr -blocking 0
+    fcopy $f1 $f2 -size 40
+    set result [list [fblocked $f1] [fconfigure $f1 -blocking] [fconfigure $f2 -blocking]]
+    close $f1
+    close $f2
+    lappend result [file size $path(test1)]
+} {0 0 0 40}
+test io-52.5 {TclCopyChannel, all} {fcopy} {
+    file delete $path(test1)
+    set f1 [open $thisScript]
+    set f2 [open $path(test1) w]
+    fconfigure $f1 -translation lf -blocking 0
+    fconfigure $f2 -translation lf -blocking 0
+    fcopy $f1 $f2 -size -1 ;# -1 means 'copy all', same as if no -size specified.
+    set result [list [fconfigure $f1 -blocking] [fconfigure $f2 -blocking]]
+    close $f1
+    close $f2
+    set s1 [file size $thisScript]
+    set s2 [file size $path(test1)]
+    if {"$s1" == "$s2"} {
+        lappend result ok
+    }
+    set result
+} {0 0 ok}
+test io-52.5a {TclCopyChannel, all, other negative value} {fcopy} {
+    file delete $path(test1)
+    set f1 [open $thisScript]
+    set f2 [open $path(test1) w]
+    fconfigure $f1 -translation lf -blocking 0
+    fconfigure $f2 -translation lf -blocking 0
+    fcopy $f1 $f2 -size -2 ;# < 0 behaves like -1, copy all
+    set result [list [fconfigure $f1 -blocking] [fconfigure $f2 -blocking]]
+    close $f1
+    close $f2
+    set s1 [file size $thisScript]
+    set s2 [file size $path(test1)]
+    if {"$s1" == "$s2"} {
+        lappend result ok
+    }
+    set result
+} {0 0 ok}
+test io-52.5b {TclCopyChannel, all, wrap to negative value} {fcopy} {
+    file delete $path(test1)
+    set f1 [open $thisScript]
+    set f2 [open $path(test1) w]
+    fconfigure $f1 -translation lf -blocking 0
+    fconfigure $f2 -translation lf -blocking 0
+    fcopy $f1 $f2 -size 3221176172 ;# Wrapped to < 0, behaves like -1, copy all
+    set result [list [fconfigure $f1 -blocking] [fconfigure $f2 -blocking]]
+    close $f1
+    close $f2
+    set s1 [file size $thisScript]
+    set s2 [file size $path(test1)]
+    if {"$s1" == "$s2"} {
+        lappend result ok
+    }
+    set result
+} {0 0 ok}
+test io-52.6 {TclCopyChannel} {fcopy} {
+    file delete $path(test1)
+    set f1 [open $thisScript]
+    set f2 [open $path(test1) w]
+    fconfigure $f1 -translation lf -blocking 0
+    fconfigure $f2 -translation lf -blocking 0
+    set s0 [fcopy $f1 $f2 -size [expr [file size $thisScript] + 5]]
+    set result [list [fconfigure $f1 -blocking] [fconfigure $f2 -blocking]]
+    close $f1
+    close $f2
+    set s1 [file size $thisScript]
+    set s2 [file size $path(test1)]
+    if {("$s1" == "$s2") && ($s0 == $s1)} {
+        lappend result ok
+    }
+    set result
+} {0 0 ok}
+test io-52.7 {TclCopyChannel} {fcopy} {
+    file delete $path(test1)
+    set f1 [open $thisScript]
+    set f2 [open $path(test1) w]
+    fconfigure $f1 -translation lf -blocking 0
+    fconfigure $f2 -translation lf -blocking 0
+    fcopy $f1 $f2
+    set result [list [fconfigure $f1 -blocking] [fconfigure $f2 -blocking]]
+    set s1 [file size $thisScript]
+    set s2 [file size $path(test1)]
+    close $f1
+    close $f2
+    if {"$s1" == "$s2"} {
+        lappend result ok
+    }
+    set result
+} {0 0 ok}
+test io-52.8 {TclCopyChannel} {stdio openpipe fcopy} {
+    file delete $path(test1)
+    file delete $path(pipe)
+    set f1 [open $path(pipe) w]
+    fconfigure $f1 -translation lf
+    puts $f1 "
+	puts ready
+	gets stdin
+	set f1 \[open [list $thisScript] r\]
+	fconfigure \$f1 -translation lf
+	puts \[read \$f1 100\]
+	close \$f1
+    "
+    close $f1
+    set f1 [open "|[list [interpreter] $path(pipe)]" r+]
+    fconfigure $f1 -translation lf
+    gets $f1
+    puts $f1 ready
+    flush $f1
+    set f2 [open $path(test1) w]
+    fconfigure $f2 -translation lf
+    set s0 [fcopy $f1 $f2 -size 40]
+    catch {close $f1}
+    close $f2
+    list $s0 [file size $path(test1)]
+} {40 40}
+# Empty files, to register them with the test facility
+set path(kyrillic.txt)   [makeFile {} kyrillic.txt]
+set path(utf8-fcopy.txt) [makeFile {} utf8-fcopy.txt]
+set path(utf8-rp.txt)    [makeFile {} utf8-rp.txt]
+# Create kyrillic file, use lf translation to avoid os eol issues
+set out [open $path(kyrillic.txt) w]
+fconfigure $out -encoding koi8-r -translation lf
+puts       $out "\u0410\u0410"
+close      $out
+test io-52.9 {TclCopyChannel & encodings} {fcopy} {
+    # Copy kyrillic to UTF-8, using fcopy.
+
+    set in  [open $path(kyrillic.txt) r]
+    set out [open $path(utf8-fcopy.txt) w]
+
+    fconfigure $in  -encoding koi8-r -translation lf
+    fconfigure $out -encoding utf-8 -translation lf
+
+    fcopy $in $out
+    close $in
+    close $out
+
+    # Do the same again, but differently (read/puts).
+
+    set in  [open $path(kyrillic.txt) r]
+    set out [open $path(utf8-rp.txt) w]
+
+    fconfigure $in  -encoding koi8-r -translation lf
+    fconfigure $out -encoding utf-8 -translation lf
+
+    puts -nonewline $out [read $in]
+
+    close $in
+    close $out
+
+    list [file size $path(kyrillic.txt)] \
+	    [file size $path(utf8-fcopy.txt)] \
+	    [file size $path(utf8-rp.txt)]
+} {3 5 5}
+test io-52.10 {TclCopyChannel & encodings} {fcopy} {
+    # encoding to binary (=> implies that the
+    # internal utf-8 is written)
+
+    set in  [open $path(kyrillic.txt) r]
+    set out [open $path(utf8-fcopy.txt) w]
+
+    fconfigure $in  -encoding koi8-r -translation lf
+    # -translation binary is also -encoding binary
+    fconfigure $out -translation binary
+
+    fcopy $in $out
+    close $in
+    close $out
+
+    file size $path(utf8-fcopy.txt)
+} 5
+test io-52.11 {TclCopyChannel & encodings} -setup {
+    set out [open $path(utf8-fcopy.txt) w]
+    fconfigure $out -encoding utf-8 -translation lf
+    puts $out "\u0410\u0410"
+    close $out
+} -constraints {fcopy} -body {
+    # binary to encoding => the input has to be
+    # in utf-8 to make sense to the encoder
+
+    set in  [open $path(utf8-fcopy.txt) r]
+    set out [open $path(kyrillic.txt) w]
+
+    # -translation binary is also -encoding binary
+    fconfigure $in  -translation binary
+    fconfigure $out -encoding koi8-r -translation lf
+
+    fcopy $in $out
+    close $in
+    close $out
+
+    file size $path(kyrillic.txt)
+} -result 3
+
+test io-52.12 {coverage of -translation auto} {
+    file delete $path(test1) $path(test2)
+    set out [open $path(test1) wb]
+    chan configure $out -translation lf
+    puts -nonewline $out abcdefg\rhijklmn\nopqrstu\r\nvwxyz
+    close $out
+    set in [open $path(test1)]
+    chan configure $in -buffersize 8
+    set out [open $path(test2) w]
+    chan configure $out -translation lf
+    fcopy $in $out
+    close $in
+    close $out
+    file size $path(test2)
+} 29
+test io-52.13 {coverage of -translation cr} {
+    file delete $path(test1) $path(test2)
+    set out [open $path(test1) wb]
+    chan configure $out -translation lf
+    puts -nonewline $out abcdefg\rhijklmn\nopqrstu\r\nvwxyz
+    close $out
+    set in [open $path(test1)]
+    chan configure $in -buffersize 8 -translation cr
+    set out [open $path(test2) w]
+    chan configure $out -translation lf
+    fcopy $in $out
+    close $in
+    close $out
+    file size $path(test2)
+} 30
+test io-52.14 {coverage of -translation crlf} {
+    file delete $path(test1) $path(test2)
+    set out [open $path(test1) wb]
+    chan configure $out -translation lf
+    puts -nonewline $out abcdefg\rhijklmn\nopqrstu\r\nvwxyz
+    close $out
+    set in [open $path(test1)]
+    chan configure $in -buffersize 8 -translation crlf
+    set out [open $path(test2) w]
+    chan configure $out -translation lf
+    fcopy $in $out
+    close $in
+    close $out
+    file size $path(test2)
+} 29
+test io-52.14.1 {coverage of -translation crlf} {
+    file delete $path(test1) $path(test2)
+    set out [open $path(test1) wb]
+    chan configure $out -translation lf
+    puts -nonewline $out abcdefg\rhijklmn\nopqrstu\r\nvwxyz
+    close $out
+    set in [open $path(test1)]
+    chan configure $in -buffersize 8 -translation crlf
+    set out [open $path(test2) w]
+    fcopy $in $out -size 2
+    close $in
+    close $out
+    file size $path(test2)
+} 2
+test io-52.14.2 {coverage of -translation crlf} {
+    file delete $path(test1) $path(test2)
+    set out [open $path(test1) wb]
+    chan configure $out -translation lf
+    puts -nonewline $out abcdefg\rhijklmn\nopqrstu\r\nvwxyz
+    close $out
+    set in [open $path(test1)]
+    chan configure $in -translation crlf
+    set out [open $path(test2) w]
+    fcopy $in $out -size 9
+    close $in
+    close $out
+    file size $path(test2)
+} 9
+test io-52.15 {coverage of -translation crlf} {
+    file delete $path(test1) $path(test2)
+    set out [open $path(test1) wb]
+    chan configure $out -translation lf
+    puts -nonewline $out abcdefg\r
+    close $out
+    set in [open $path(test1)]
+    chan configure $in -buffersize 8 -translation crlf
+    set out [open $path(test2) w]
+    fcopy $in $out
+    close $in
+    close $out
+    file size $path(test2)
+} 8
+test io-52.16 {coverage of eofChar handling} {
+    file delete $path(test1) $path(test2)
+    set out [open $path(test1) wb]
+    chan configure $out -translation lf
+    puts -nonewline $out abcdefg\rhijklmn\nopqrstu\r\nvwxyz
+    close $out
+    set in [open $path(test1)]
+    chan configure $in -buffersize 8 -translation lf -eofchar a
+    set out [open $path(test2) w]
+    fcopy $in $out
+    close $in
+    close $out
+    file size $path(test2)
+} 0
+test io-52.17 {coverage of eofChar handling} {
+    file delete $path(test1) $path(test2)
+    set out [open $path(test1) wb]
+    chan configure $out -translation lf
+    puts -nonewline $out abcdefg\rhijklmn\nopqrstu\r\nvwxyz
+    close $out
+    set in [open $path(test1)]
+    chan configure $in -buffersize 8 -translation lf -eofchar d
+    set out [open $path(test2) w]
+    fcopy $in $out
+    close $in
+    close $out
+    file size $path(test2)
+} 3
+test io-52.18 {coverage of eofChar handling} {
+    file delete $path(test1) $path(test2)
+    set out [open $path(test1) wb]
+    chan configure $out -translation lf
+    puts -nonewline $out abcdefg\rhijklmn\nopqrstu\r\nvwxyz
+    close $out
+    set in [open $path(test1)]
+    chan configure $in -buffersize 8 -translation crlf -eofchar h
+    set out [open $path(test2) w]
+    fcopy $in $out
+    close $in
+    close $out
+    file size $path(test2)
+} 8
+test io-52.19 {coverage of eofChar handling} {
+    file delete $path(test1) $path(test2)
+    set out [open $path(test1) wb]
+    chan configure $out -translation lf
+    puts -nonewline $out abcdefg\rhijklmn\nopqrstu\r\nvwxyz
+    close $out
+    set in [open $path(test1)]
+    chan configure $in -buffersize 10 -translation crlf -eofchar h
+    set out [open $path(test2) w]
+    fcopy $in $out
+    close $in
+    close $out
+    file size $path(test2)
+} 8
+
+test io-53.1 {CopyData} {fcopy} {
+    file delete $path(test1)
+    set f1 [open $thisScript]
+    set f2 [open $path(test1) w]
+    fconfigure $f1 -translation lf -blocking 0
+    fconfigure $f2 -translation cr -blocking 0
+    fcopy $f1 $f2 -size 0
+    set result [list [fconfigure $f1 -blocking] [fconfigure $f2 -blocking]]
+    close $f1
+    close $f2
+    lappend result [file size $path(test1)]
+} {0 0 0}
+test io-53.2 {CopyData} {fcopy} {
+    file delete $path(test1)
+    set f1 [open $thisScript]
+    set f2 [open $path(test1) w]
+    fconfigure $f1 -translation lf -blocking 0
+    fconfigure $f2 -translation cr -blocking 0
+    fcopy $f1 $f2 -command [namespace code {set s0}]
+    set result [list [fconfigure $f1 -blocking] [fconfigure $f2 -blocking]]
+    variable s0
+    vwait [namespace which -variable s0]
+    close $f1
+    close $f2
+    set s1 [file size $thisScript]
+    set s2 [file size $path(test1)]
+    if {("$s1" == "$s2") && ($s0 == $s1)} {
+        lappend result ok
+    }
+    set result
+} {0 0 ok}
+test io-53.3 {CopyData: background read underflow} {stdio unix openpipe fcopy} {
+    file delete $path(test1)
+    file delete $path(pipe)
+    set f1 [open $path(pipe) w]
+    puts -nonewline $f1 {
+	puts ready
+	flush stdout				;# Don't assume line buffered!
+	fcopy stdin stdout -command { set x }
+	vwait x
+	set f [}
+    puts $f1 [list open $path(test1) w]]
+    puts $f1 {
+	fconfigure $f -translation lf
+	puts $f "done"
+	close $f
+    }
+    close $f1
+    set f1 [open "|[list [interpreter] $path(pipe)]" r+]
+    set result [gets $f1]
+    puts $f1 line1
+    flush $f1
+    lappend result [gets $f1]
+    puts $f1 line2
+    flush $f1
+    lappend result [gets $f1]
+    close $f1
+    after 500
+    set f [open $path(test1)]
+    lappend result [read $f]
+    close $f
+    set result
+} "ready line1 line2 {done\n}"
+test io-53.4 {CopyData: background write overflow} {stdio unix openpipe fileevent fcopy} {
+    set big bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\n
+    variable x
+    for {set x 0} {$x < 12} {incr x} {
+	append big $big
+    }
+    file delete $path(pipe)
+    set f1 [open $path(pipe) w]
+    puts $f1 {
+	puts ready
+	fcopy stdin stdout -command { set x }
+	vwait x
+    }
+    close $f1
+    set f1 [open "|[list [interpreter] $path(pipe)]" r+]
+    set result [gets $f1]
+    fconfigure $f1 -blocking 0
+    puts $f1 $big
+    flush $f1
+    set result ""
+    fileevent $f1 read [namespace code {
+	append result [read $f1 1024]
+	if {[string length $result] >= [string length $big]+1} {
+	    set x done
+	}
+    }]
+    vwait [namespace which -variable x]
+    close $f1
+    set big {}
+    set x
+} done
+test io-53.4.1 {Bug 894da183c8} {stdio fcopy} {
+    set big bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\n
+    variable x
+    for {set x 0} {$x < 12} {incr x} {
+	append big $big
+    }
+    file delete $path(pipe)
+    set f1 [open $path(pipe) w]
+    puts $f1 [list file delete $path(test1)]
+    puts $f1 {
+	puts ready
+	set f [open io-53.4.1 w]
+	chan configure $f -translation lf
+	fcopy stdin $f -command { set x }
+	vwait x
+	close $f
+    }
+    puts $f1 "close \[[list open $path(test1) w]]"
+    close $f1
+    set f1 [open "|[list [interpreter] $path(pipe)]" r+]
+    set result [gets $f1]
+    fconfigure $f1 -blocking 0 -buffersize 125000 -translation lf
+    puts $f1 $big
+    fconfigure $f1 -blocking 1
+    close $f1
+    set big {}
+    while {[catch {glob $path(test1)}]} {after 50}
+    file delete $path(test1)
+    set check [file size io-53.4.1]
+    file delete io-53.4.1
+    set check
+} 266241
+set result {}
+proc FcopyTestAccept {sock args} {
+    after 1000 "close $sock"
+}
+proc FcopyTestDone {bytes {error {}}} {
+    variable fcopyTestDone
+    if {[string length $error]} {
+	set fcopyTestDone 1
+    } else {
+	set fcopyTestDone 0
+    }
+}
+test io-53.5 {CopyData: error during fcopy} {socket fcopy} {
+    variable fcopyTestDone
+    set listen [socket -server [namespace code FcopyTestAccept] -myaddr 127.0.0.1 0]
+    set in [open $thisScript]	;# 126 K
+    set out [socket 127.0.0.1 [lindex [fconfigure $listen -sockname] 2]]
+    catch {unset fcopyTestDone}
+    close $listen	;# This means the socket open never really succeeds
+    fcopy $in $out -command [namespace code FcopyTestDone]
+    variable fcopyTestDone
+    if ![info exists fcopyTestDone] {
+	vwait [namespace which -variable fcopyTestDone]		;# The error occurs here in the b.g.
+    }
+    close $in
+    close $out
+    set fcopyTestDone	;# 1 for error condition
+} 1
+test io-53.6 {CopyData: error during fcopy} {stdio openpipe fcopy} {
+    variable fcopyTestDone
+    file delete $path(pipe)
+    file delete $path(test1)
+    catch {unset fcopyTestDone}
+    set f1 [open $path(pipe) w]
+    puts $f1 "exit 1"
+    close $f1
+    set in [open "|[list [interpreter] $path(pipe)]" r+]
+    set out [open $path(test1) w]
+    fcopy $in $out -command [namespace code FcopyTestDone]
+    variable fcopyTestDone
+    if ![info exists fcopyTestDone] {
+	vwait [namespace which -variable fcopyTestDone]
+    }
+    catch {close $in}
+    close $out
+    set fcopyTestDone	;# 0 for plain end of file
+} {0}
+proc doFcopy {in out {bytes 0} {error {}}} {
+    variable fcopyTestDone
+    variable fcopyTestCount
+    incr fcopyTestCount $bytes
+    if {[string length $error]} {
+	set fcopyTestDone 1
+    } elseif {[eof $in]} {
+	set fcopyTestDone 0
+    } else {
+        # Delay next fcopy to wait for size>0 input bytes
+        after 100 [list fcopy $in $out -size 1000 \
+		-command [namespace code [list doFcopy $in $out]]]
+    }
+}
+test io-53.7 {CopyData: Flooding fcopy from pipe} {stdio openpipe fcopy} {
+    variable fcopyTestDone
+    file delete $path(pipe)
+    catch {unset fcopyTestDone}
+    set fcopyTestCount 0
+    set f1 [open $path(pipe) w]
+    puts $f1 {
+	# Write  10 bytes / 10 msec
+	proc Write {count} {
+	    puts -nonewline "1234567890"
+	    if {[incr count -1]} {
+	        after 10 [list Write $count]
+	    } else {
+	        set ::ready 1
+	    }
+	}
+	fconfigure stdout -buffering none
+	Write 345 ;# 3450 bytes ~3.45 sec
+	vwait ready
+	exit 0
+    }
+    close $f1
+    set in [open "|[list [interpreter] $path(pipe) &]" r+]
+    set out [open $path(test1) w]
+    doFcopy $in $out
+    variable fcopyTestDone
+    if ![info exists fcopyTestDone] {
+	vwait [namespace which -variable fcopyTestDone]
+    }
+    catch {close $in}
+    close $out
+    # -1=error 0=script error N=number of bytes
+    expr ($fcopyTestDone == 0) ? $fcopyTestCount : -1
+} {3450}
+test io-53.8 {CopyData: async callback and error handling, Bug 1932639} -setup {
+    # copy progress callback. errors out intentionally
+    proc ::cmd args {
+	lappend ::RES "CMD $args"
+	error !STOP
+    }
+    # capture callback error here
+    proc ::bgerror args {
+	lappend ::RES "bgerror/OK $args"
+	set ::forever has-been-reached
+	return
+    }
+    # Files we use for our channels
+    set foo [makeFile ashgdfashdgfasdhgfasdhgf foo]
+    set bar [makeFile {} bar]
+    # Channels to copy between
+    set f [open $foo r] ; fconfigure $f -translation binary
+    set g [open $bar w] ; fconfigure $g -translation binary -buffering none
+} -constraints {stdio openpipe fcopy} -body {
+    # Record input size, so that result is always defined
+    lappend ::RES [file size $bar]
+    # Run the copy. Should not invoke -command now.
+    fcopy $f $g -size 2 -command ::cmd
+    # Check that -command was not called synchronously
+    set sbs [file size $bar]
+    lappend ::RES [expr {($sbs > 0) ? "sync/FAIL" : "sync/OK"}] $sbs
+    # Now let the async part happen. Should capture the error in cmd
+    # via bgerror. If not break the event loop via timer.
+    set token [after 1000 {
+	lappend ::RES {bgerror/FAIL timeout}
+	set ::forever has-been-reached
+    }]
+    vwait ::forever
+    catch {after cancel $token}
+    # Report
+    set ::RES
+} -cleanup {
+    close $f
+    close $g
+    catch {unset ::RES}
+    catch {unset ::forever}
+    rename ::cmd {}
+    rename ::bgerror {}
+    removeFile foo
+    removeFile bar
+} -result {0 sync/OK 0 {CMD 2} {bgerror/OK !STOP}}
+test io-53.8a {CopyData: async callback and error handling, Bug 1932639, at eof} -setup {
+    # copy progress callback. errors out intentionally
+    proc ::cmd args {
+	lappend ::RES "CMD $args"
+	set ::forever has-been-reached
+	return
+    }
+    # Files we use for our channels
+    set foo [makeFile ashgdfashdgfasdhgfasdhgf foo]
+    set bar [makeFile {} bar]
+    # Channels to copy between
+    set f [open $foo r] ; fconfigure $f -translation binary
+    set g [open $bar w] ; fconfigure $g -translation binary -buffering none
+} -constraints {stdio openpipe fcopy} -body {
+    # Initialize and force eof on the input.
+    seek $f 0 end ; read $f 1
+    set ::RES [eof $f]
+    # Run the copy. Should not invoke -command now.
+    fcopy $f $g -size 2 -command ::cmd
+    # Check that -command was not called synchronously
+    lappend ::RES [expr {([llength $::RES] > 1) ? "sync/FAIL" : "sync/OK"}]
+    # Now let the async part happen. Should capture the eof in cmd
+    # If not break the event loop via timer.
+    set token [after 1000 {
+	lappend ::RES {cmd/FAIL timeout}
+	set ::forever has-been-reached
+    }]
+    vwait ::forever
+    catch {after cancel $token}
+    # Report
+    set ::RES
+} -cleanup {
+    close $f
+    close $g
+    catch {unset ::RES}
+    catch {unset ::forever}
+    rename ::cmd {}
+    removeFile foo
+    removeFile bar
+} -result {1 sync/OK {CMD 0}}
+test io-53.8b {CopyData: async callback and -size 0} -setup {
+    # copy progress callback. errors out intentionally
+    proc ::cmd args {
+	lappend ::RES "CMD $args"
+	set ::forever has-been-reached
+	return
+    }
+    # Files we use for our channels
+    set foo [makeFile ashgdfashdgfasdhgfasdhgf foo]
+    set bar [makeFile {} bar]
+    # Channels to copy between
+    set f [open $foo r] ; fconfigure $f -translation binary
+    set g [open $bar w] ; fconfigure $g -translation binary -buffering none
+} -constraints {stdio openpipe fcopy} -body {
+	set ::RES {}
+    # Run the copy. Should not invoke -command now.
+    fcopy $f $g -size 0 -command ::cmd
+    # Check that -command was not called synchronously
+    lappend ::RES [expr {([llength $::RES] > 1) ? "sync/FAIL" : "sync/OK"}]
+    # Now let the async part happen. Should capture the eof in cmd
+    # If not break the event loop via timer.
+    set token [after 1000 {
+	lappend ::RES {cmd/FAIL timeout}
+	set ::forever has-been-reached
+    }]
+    vwait ::forever
+    catch {after cancel $token}
+    # Report
+    set ::RES
+} -cleanup {
+    close $f
+    close $g
+    catch {unset ::RES}
+    catch {unset ::forever}
+    rename ::cmd {}
+    removeFile foo
+    removeFile bar
+} -result {sync/OK {CMD 0}}
+test io-53.9 {CopyData: -size and event interaction, Bug 780533} -setup {
+    set out [makeFile {} out]
+    set err [makeFile {} err]
+    set pipe [open "|[list [info nameofexecutable] 2> $err]" r+]
+    fconfigure $pipe -translation binary -buffering line
+    puts $pipe {
+	fconfigure stdout -translation binary -buffering line
+	puts stderr Waiting...
+	after 1000
+	foreach x {a b c} {
+	    puts stderr Looping...
+	    puts $x
+	    after 500
+	}
+	proc bye args {
+	    if {[gets stdin line]<0} {
+		puts stderr "CHILD: EOF detected, exiting"
+		exit
+	    } else {
+		puts stderr "CHILD: ignoring line: $line"
+	    }
+	}
+	puts stderr Now-sleeping-forever
+	fileevent stdin readable bye
+	vwait forever
+    }
+    proc ::done args {
+	set ::forever OK
+	return
+    }
+    set ::forever {}
+    set out [open $out w]
+} -constraints {stdio openpipe fcopy} -body {
+    fcopy $pipe $out -size 6 -command ::done
+    set token [after 5000 {
+	set ::forever {fcopy hangs}
+    }]
+    vwait ::forever
+    catch {after cancel $token}
+    set ::forever
+} -cleanup {
+    close $pipe
+    rename ::done {}
+    after 1000;			# Give Windows time to kill the process
+    catch {close $out}
+    catch {removeFile out}
+    catch {removeFile err}
+    catch {unset ::forever}
+} -result OK
+test io-53.10 {Bug 1350564, multi-directional fcopy} -setup {
+    set err [makeFile {} err]
+    set pipe [open "|[list [info nameofexecutable] 2> $err]" r+]
+    fconfigure $pipe -translation binary -buffering line
+    puts $pipe {
+	fconfigure stderr -buffering line
+	# Kill server when pipe closed by invoker.
+	proc bye args {
+	    if {![eof stdin]} { gets stdin ; return }
+	    puts stderr BYE
+	    exit
+	}
+	# Server code. Bi-directional copy between 2 sockets.
+	proc geof {sok} {
+	    puts stderr DONE/$sok
+	    close $sok
+	}
+	proc new {sok args} {
+	    puts stderr NEW/$sok
+	    global l srv
+	    fconfigure $sok -translation binary -buffering none
+	    lappend l $sok
+	    if {[llength $l]==2} {
+		close $srv
+		foreach {a b} $l break
+		fcopy $a $b -command [list geof $a]
+		fcopy $b $a -command [list geof $b]
+		puts stderr 2COPY
+	    }
+	    puts stderr ...
+	}
+	puts stderr SRV
+	set l {}
+	set srv [socket -server new 9999]
+	puts stderr WAITING
+	fileevent stdin readable bye
+	puts OK
+	vwait forever
+    }
+    # wait for OK from server.
+    gets $pipe
+    # Now the two clients.
+    proc ::done {sock} {
+	if {[eof $sock]} { close $sock ; return }
+	lappend ::forever [gets $sock]
+	return
+    }
+    set a [socket 127.0.0.1 9999]
+    set b [socket 127.0.0.1 9999]
+    fconfigure $a -translation binary -buffering none
+    fconfigure $b -translation binary -buffering none
+    fileevent  $a readable [list ::done $a]
+    fileevent  $b readable [list ::done $b]
+} -constraints {stdio openpipe fcopy} -body {
+    # Now pass data through the server in both directions.
+    set ::forever {}
+    puts $a AB
+    vwait ::forever
+    puts $b BA
+    vwait ::forever
+    set ::forever
+} -cleanup {
+    catch {close $a}
+    catch {close $b}
+    close $pipe
+    rename ::done {}
+    after 1000 ;# Give Windows time to kill the process
+    removeFile err
+    catch {unset ::forever}
+} -result {AB BA}
+test io-53.11 {Bug 2895565} -setup {
+    set in [makeFile {} in]
+    set f [open $in w]
+    fconfigure $f -encoding utf-8 -translation binary
+    puts -nonewline $f [string repeat "Ho hum\n" 11]
+    close $f
+    set inChan [open $in r]
+    fconfigure $inChan -translation binary
+    set out [makeFile {} out]
+    set outChan [open $out w]
+    fconfigure $outChan -encoding cp1252 -translation crlf
+    proc CopyDone {bytes args} {
+	variable done
+	if {[llength $args]} {
+	    set done "Error: '[lindex $args 0]' after $bytes bytes copied"
+	} else {
+	    set done "$bytes bytes copied"
+	}
+    }
+} -body {
+    variable done
+    after 2000 [list set [namespace which -variable done] timeout]
+    fcopy $inChan $outChan -size 40 -command [namespace which CopyDone]
+    vwait [namespace which -variable done]
+    set done
+} -cleanup {
+    close $outChan
+    close $inChan
+    removeFile out
+    removeFile in
+} -result {40 bytes copied}
+test io-53.12 {CopyData: foreground short reads, aka bug 3096275} {stdio unix openpipe fcopy} {
+    file delete $path(pipe)
+    set f1 [open $path(pipe) w]
+    puts -nonewline $f1 {
+	fconfigure stdin -translation binary -blocking 0
+	fconfigure stdout -buffering none -translation binary
+	fcopy stdin stdout
+    }
+    close $f1
+    set f1 [open "|[list [interpreter] $path(pipe)]" r+]
+    fconfigure $f1 -translation binary -buffering none
+    puts -nonewline $f1 A
+    after 2000 {set ::done timeout}
+    fileevent $f1 readable {set ::done ok}
+    vwait ::done
+    set ch [read $f1 1]
+    close $f1
+    list $::done $ch
+} {ok A}
+test io-53.13 {TclCopyChannel: read error reporting} -setup {
+    proc driver {cmd args} {
+        variable buffer
+        variable index
+        set chan [lindex $args 0]
+        switch -- $cmd {
+            initialize {
+                return {initialize finalize watch read}
+            }
+            finalize {
+                return
+            }
+            watch {}
+            read {
+		error FAIL
+            }
+        }
+    }
+    set outFile [makeFile {} out]
+} -body {
+    set in [chan create read [namespace which driver]]
+    chan configure $in -translation binary
+    set out [open $outFile wb]
+    chan copy $in $out
+} -cleanup {
+    catch {close $in}
+    catch {close $out}
+    removeFile out
+    rename driver {}
+} -result {error reading "*": *} -returnCodes error -match glob
+test io-53.14 {TclCopyChannel: write error reporting} -setup {
+    proc driver {cmd args} {
+        variable buffer
+        variable index
+        set chan [lindex $args 0]
+        switch -- $cmd {
+            initialize {
+                return {initialize finalize watch write}
+            }
+            finalize {
+                return
+            }
+            watch {}
+            write {
+                error FAIL
+            }
+        }
+    }
+    set inFile [makeFile {aaa} in]
+} -body {
+    set in [open $inFile rb]
+    set out [chan create write [namespace which driver]]
+    chan configure $out -translation binary
+    chan copy $in $out
+} -cleanup {
+    catch {close $in}
+    catch {close $out}
+    removeFile in
+    rename driver {}
+} -result {error writing "*": *} -returnCodes error -match glob
+test io-53.15 {[ed29c4da21] DoRead: fblocked seen as error} -setup {
+    proc driver {cmd args} {
+        variable buffer
+        variable index
+        variable blocked
+        set chan [lindex $args 0]
+        switch -- $cmd {
+            initialize {
+                set index($chan) 0
+                set buffer($chan) [encoding convertto utf-8 \
+                        [string repeat a 100]]
+                set blocked($chan) 1
+                return {initialize finalize watch read}
+            }
+            finalize {
+                unset index($chan) buffer($chan) blocked($chan)
+                return
+            }
+            watch {}
+            read {
+                if {$blocked($chan)} {
+                    set blocked($chan) [expr {!$blocked($chan)}]
+                    return -code error EAGAIN
+                }
+                set n [lindex $args 1]
+                set new [expr {$index($chan) + $n}]
+                set result [string range $buffer($chan) $index($chan) $new-1]
+                set index($chan) $new
+                return $result
+            }
+        }
+    }
+    set c [chan create read [namespace which driver]]
+    chan configure $c -encoding utf-8
+    set out [makeFile {} out]
+    set outChan [open $out w]
+    chan configure $outChan -encoding utf-8
+} -body {
+    chan copy $c $outChan
+} -cleanup {
+    close $outChan
+    close $c
+    removeFile out
+} -result 100
+test io-53.16 {[ed29c4da21] MBRead: fblocked seen as error} -setup {
+    proc driver {cmd args} {
+        variable buffer
+        variable index
+        variable blocked
+        set chan [lindex $args 0]
+        switch -- $cmd {
+            initialize {
+                set index($chan) 0
+                set buffer($chan) [encoding convertto utf-8 \
+                        [string repeat a 100]]
+                set blocked($chan) 1
+                return {initialize finalize watch read}
+            }
+            finalize {
+                unset index($chan) buffer($chan) blocked($chan)
+                return
+            }
+            watch {}
+            read {
+                if {$blocked($chan)} {
+                    set blocked($chan) [expr {!$blocked($chan)}]
+                    return -code error EAGAIN
+                }
+                set n [lindex $args 1]
+                set new [expr {$index($chan) + $n}]
+                set result [string range $buffer($chan) $index($chan) $new-1]
+                set index($chan) $new
+                return $result
+            }
+        }
+    }
+    set c [chan create read [namespace which driver]]
+    chan configure $c -encoding utf-8 -translation lf
+    set out [makeFile {} out]
+    set outChan [open $out w]
+    chan configure $outChan -encoding utf-8 -translation lf
+} -body {
+    chan copy $c $outChan
+} -cleanup {
+    close $outChan
+    close $c
+    removeFile out
+} -result 100
+test io-53.17 {[7c187a3773] MBWrite: proper inQueueTail handling} -setup {
+    proc driver {cmd args} {
+        variable buffer
+        variable index
+        set chan [lindex $args 0]
+        switch -- $cmd {
+            initialize {
+                set index($chan) 0
+                set buffer($chan) [encoding convertto utf-8 \
+                        line\n[string repeat a 100]line\n]
+                return {initialize finalize watch read}
+            }
+            finalize {
+                unset index($chan) buffer($chan)
+                return
+            }
+            watch {}
+            read {
+                set n [lindex $args 1]
+                set new [expr {$index($chan) + $n}]
+                set result [string range $buffer($chan) $index($chan) $new-1]
+                set index($chan) $new
+                return $result
+            }
+        }
+    }
+    set c [chan create read [namespace which driver]]
+    chan configure $c -encoding utf-8 -translation lf -buffersize 107
+    set out [makeFile {} out]
+    set outChan [open $out w]
+    chan configure $outChan -encoding utf-8 -translation lf
+} -body {
+    list [gets $c] [chan copy $c $outChan -size 100] [gets $c]
+} -cleanup {
+    close $outChan
+    close $c
+    removeFile out
+} -result {line 100 line}
+
+test io-54.1 {Recursive channel events} {socket fileevent} {
+    # This test checks to see if file events are delivered during recursive
+    # event loops when there is buffered data on the channel.
+
+    proc accept {s a p} {
+	variable as
+	fconfigure $s -translation lf
+	puts $s "line 1\nline2\nline3"
+	flush $s
+	set as $s
+    }
+    proc readit {s next} {
+	variable x
+	variable result
+	lappend result $next
+	if {$next == 1} {
+	    fileevent $s readable [namespace code [list readit $s 2]]
+	    vwait [namespace which -variable x]
+	}
+	incr x
+    }
+    set ss [socket -server [namespace code accept] -myaddr 127.0.0.1 0]
+
+    # We need to delay on some systems until the creation of the
+    # server socket completes.
+
+    set done 0
+    for {set i 0} {$i < 10} {incr i} {
+	if {![catch {set cs [socket 127.0.0.1 [lindex [fconfigure $ss -sockname] 2]]}]} {
+	    set done 1
+	    break
+	}
+	after 100
+    }
+    if {$done == 0} {
+	close $ss
+	error "failed to connect to server"
+    }
+    variable result {}
+    variable x 0
+    variable as
+    vwait [namespace which -variable as]
+    fconfigure $cs -translation lf
+    lappend result [gets $cs]
+    fconfigure $cs -blocking off
+    fileevent $cs readable [namespace code [list readit $cs 1]]
+    set a [after 2000 [namespace code { set x failure }]]
+    vwait [namespace which -variable x]
+    after cancel $a
+    close $as
+    close $ss
+    close $cs
+    list $result $x
+} {{{line 1} 1 2} 2}
+test io-54.2 {Testing for busy-wait in recursive channel events} {socket fileevent} {
+    set accept {}
+    set after {}
+    variable s [socket -server [namespace code accept] -myaddr 127.0.0.1 0]
+    proc accept {s a p} {
+	variable counter
+	variable accept
+
+	set accept $s
+	set counter 0
+	fconfigure $s -blocking off -buffering line -translation lf
+	fileevent $s readable [namespace code "doit $s"]
+    }
+    proc doit {s} {
+	variable counter
+	variable after
+
+	incr counter
+	set l [gets $s]
+	if {"$l" == ""} {
+	    fileevent $s readable [namespace code "doit1 $s"]
+	    set after [after 1000 [namespace code newline]]
+	}
+    }
+    proc doit1 {s} {
+	variable counter
+	variable accept
+
+	incr counter
+	set l [gets $s]
+	close $s
+	set accept {}
+    }
+    proc producer {} {
+	variable s
+	variable writer
+
+	set writer [socket 127.0.0.1 [lindex [fconfigure $s -sockname] 2]]
+	fconfigure $writer -buffering line
+	puts -nonewline $writer hello
+	flush $writer
+    }
+    proc newline {} {
+	variable done
+	variable writer
+
+	puts $writer hello
+	flush $writer
+	set done 1
+    }
+    producer
+    variable done
+    vwait [namespace which -variable done]
+    close $writer
+    close $s
+    after cancel $after
+    if {$accept != {}} {close $accept}
+    set counter
+} 1
+
+set path(fooBar) [makeFile {} fooBar]
+
+test io-55.1 {ChannelEventScriptInvoker: deletion} -constraints {
+    fileevent
+} -setup {
+    variable x
+    proc eventScript {fd} {
+	variable x
+	close $fd
+	error "planned error"
+	set x whoops
+    }
+    proc myHandler args {
+	variable x got_error
+    }
+    set handler [interp bgerror {}]
+    interp bgerror {} [namespace which myHandler]
+} -body {
+    set f [open $path(fooBar) w]
+    fileevent $f writable [namespace code [list eventScript $f]]
+    variable x not_done
+    vwait [namespace which -variable x]
+    set x
+} -cleanup {
+    interp bgerror {} $handler
+} -result {got_error}
+
+test io-56.1 {ChannelTimerProc} {testchannelevent} {
+    set f [open $path(fooBar) w]
+    puts $f "this is a test"
+    close $f
+    set f [open $path(fooBar) r]
+    testchannelevent $f add readable [namespace code {
+	read $f 1
+	incr x
+    }]
+    variable x 0
+    vwait [namespace which -variable x]
+    vwait [namespace which -variable x]
+    set result $x
+    testchannelevent $f set 0 none
+    after idle [namespace code {set y done}]
+    variable y
+    vwait [namespace which -variable y]
+    close $f
+    lappend result $y
+} {2 done}
+
+test io-57.1 {buffered data and file events, gets} {fileevent} {
+    proc accept {sock args} {
+	variable s2
+	set s2 $sock
+    }
+    set server [socket -server [namespace code accept] -myaddr 127.0.0.1 0]
+    set s [socket 127.0.0.1 [lindex [fconfigure $server -sockname] 2]]
+    variable s2
+    vwait [namespace which -variable s2]
+    update
+    fileevent $s2 readable [namespace code {lappend result readable}]
+    puts $s "12\n34567890"
+    flush $s
+    variable result [gets $s2]
+    after 1000 [namespace code {lappend result timer}]
+    vwait [namespace which -variable result]
+    lappend result [gets $s2]
+    vwait [namespace which -variable result]
+    close $s
+    close $s2
+    close $server
+    set result
+} {12 readable 34567890 timer}
+test io-57.2 {buffered data and file events, read} {fileevent} {
+    proc accept {sock args} {
+	variable s2
+	set s2 $sock
+    }
+    set server [socket -server [namespace code accept] -myaddr 127.0.0.1 0]
+    set s [socket 127.0.0.1 [lindex [fconfigure $server -sockname] 2]]
+    variable s2
+    vwait [namespace which -variable s2]
+    update
+    fileevent $s2 readable [namespace code {lappend result readable}]
+    puts -nonewline $s "1234567890"
+    flush $s
+    variable result [read $s2 1]
+    after 1000 [namespace code {lappend result timer}]
+    vwait [namespace which -variable result]
+    lappend result [read $s2 9]
+    vwait [namespace which -variable result]
+    close $s
+    close $s2
+    close $server
+    set result
+} {1 readable 234567890 timer}
+
+test io-58.1 {Tcl_NotifyChannel and error when closing} {stdio unixOrPc openpipe fileevent} {
+    set out [open $path(script) w]
+    puts $out {
+	puts "normal message from pipe"
+	puts stderr "error message from pipe"
+	exit 1
+    }
+    proc readit {pipe} {
+	variable x
+	variable result
+	if {[eof $pipe]} {
+	    set x [catch {close $pipe} line]
+	    lappend result catch $line
+	} else {
+	    gets $pipe line
+	    lappend result gets $line
+	}
+    }
+    close $out
+    set pipe [open "|[list [interpreter] $path(script)]" r]
+    fileevent $pipe readable [namespace code [list readit $pipe]]
+    variable x ""
+    set result ""
+    vwait [namespace which -variable x]
+    list $x $result
+} {1 {gets {normal message from pipe} gets {} catch {error message from pipe}}}
+
+test io-59.1 {Thread reference of channels} {testmainthread testchannel} {
+    # TIP #10
+    # More complicated tests (like that the reference changes as a
+    # channel is moved from thread to thread) can be done only in the
+    # extension which fully implements the moving of channels between
+    # threads, i.e. 'Threads'.
+
+    set f [open $path(longfile) r]
+    set result [testchannel mthread $f]
+    close $f
+    string equal $result [testmainthread]
+} {1}
+
+test io-60.1 {writing illegal utf sequences} {openpipe fileevent testbytestring} {
+    # This test will hang in older revisions of the core.
+
+    set out [open $path(script) w]
+    puts $out {
+	puts [testbytestring \xe2]
+	exit 1
+    }
+    proc readit {pipe} {
+	variable x
+	variable result
+	if {[eof $pipe]} {
+	    set x [catch {close $pipe} line]
+	    lappend result catch $line
+	} else {
+	    gets $pipe line
+	    lappend result gets $line
+	}
+    }
+    close $out
+    set pipe [open "|[list [interpreter] $path(script)]" r]
+    fileevent $pipe readable [namespace code [list readit $pipe]]
+    variable x ""
+    set result ""
+    vwait [namespace which -variable x]
+
+    # cut of the remainder of the error stack, especially the filename
+    set result [lreplace $result 3 3 [lindex [split [lindex $result 3] \n] 0]]
+    list $x $result
+} {1 {gets {} catch {error writing "stdout": invalid argument}}}
+
+test io-61.1 {Reset eof state after changing the eof char} -setup {
+    set datafile [makeFile {} eofchar]
+    set f [open $datafile w]
+    fconfigure $f -translation binary
+    puts -nonewline $f [string repeat "Ho hum\n" 11]
+    puts $f =
+    set line [string repeat "Ge gla " 4]
+    puts -nonewline $f [string repeat [string trimright $line]\n 834]
+    close $f
+} -body {
+    set f [open $datafile r]
+    fconfigure $f -eofchar =
+    set res {}
+    lappend res [read $f; tell $f]
+    fconfigure $f -eofchar {}
+    lappend res [read $f 1]
+    lappend res [read $f; tell $f]
+    # Any seek zaps the internals into a good state.
+    #seek $f 0 start
+    #seek $f 0 current
+    #lappend res [read $f; tell $f]
+    close $f
+    set res
+} -cleanup {
+    removeFile eofchar
+} -result {77 = 23431}
+
+
+# Test the cutting and splicing of channels, this is incidentially the
+# attach/detach facility of package Thread, but __without any
+# safeguards__. It can also be used to emulate transfer of channels
+# between threads, and is used for that here.
+
+test io-70.0 {Cutting & Splicing channels} {testchannel} {
+    set f [makeFile {... dummy ...} cutsplice]
+    set c [open $f r]
+
+    set     res {}
+    lappend res [catch {seek $c 0 start}]
+    testchannel cut $c
+
+    lappend res [catch {seek $c 0 start}]
+    testchannel splice $c
+
+    lappend res [catch {seek $c 0 start}]
+    close $c
+
+    removeFile cutsplice
+
+    set res
+} {0 1 0}
+
+
+test io-70.1 {Transfer channel} {testchannel thread} {
+    set f [makeFile {... dummy ...} cutsplice]
+    set c [open $f r]
+
+    set     res {}
+    lappend res [catch {seek $c 0 start}]
+    testchannel cut $c
+    lappend res [catch {seek $c 0 start}]
+
+    set tid [thread::create -preserved]
+    thread::send $tid [list set c $c]
+    thread::send $tid {load {} Tcltest}
+    lappend res [thread::send $tid {
+	testchannel splice $c
+	set res [catch {seek $c 0 start}]
+	close $c
+	set res
+    }]
+
+    thread::release $tid
+    removeFile cutsplice
+
+    set res
+} {0 1 0}
+
+# ### ### ### ######### ######### #########
+
+foreach {n msg expected} {
+     0 {}                                 {}
+     1 {{message only}}                   {{message only}}
+     2 {-options x}                       {-options x}
+     3 {-options {x y} {the message}}     {-options {x y} {the message}}
+
+     4 {-code 1     -level 0 -f ba snarf} {-code 1     -level 0 -f ba snarf}
+     5 {-code 0     -level 0 -f ba snarf} {-code 1     -level 0 -f ba snarf}
+     6 {-code 1     -level 5 -f ba snarf} {-code 1     -level 0 -f ba snarf}
+     7 {-code 0     -level 5 -f ba snarf} {-code 1     -level 0 -f ba snarf}
+     8 {-code error -level 0 -f ba snarf} {-code error -level 0 -f ba snarf}
+     9 {-code ok    -level 0 -f ba snarf} {-code 1     -level 0 -f ba snarf}
+    10 {-code error -level 5 -f ba snarf} {-code error -level 0 -f ba snarf}
+    11 {-code ok    -level 5 -f ba snarf} {-code 1     -level 0 -f ba snarf}
+    12 {-code boss  -level 0 -f ba snarf} {-code 1     -level 0 -f ba snarf}
+    13 {-code boss  -level 5 -f ba snarf} {-code 1     -level 0 -f ba snarf}
+    14 {-code 1     -level 0 -f ba}       {-code 1     -level 0 -f ba}
+    15 {-code 0     -level 0 -f ba}       {-code 1     -level 0 -f ba}
+    16 {-code 1     -level 5 -f ba}       {-code 1     -level 0 -f ba}
+    17 {-code 0     -level 5 -f ba}       {-code 1     -level 0 -f ba}
+    18 {-code error -level 0 -f ba}       {-code error -level 0 -f ba}
+    19 {-code ok    -level 0 -f ba}       {-code 1     -level 0 -f ba}
+    20 {-code error -level 5 -f ba}       {-code error -level 0 -f ba}
+    21 {-code ok    -level 5 -f ba}       {-code 1     -level 0 -f ba}
+    22 {-code boss  -level 0 -f ba}       {-code 1     -level 0 -f ba}
+    23 {-code boss  -level 5 -f ba}       {-code 1     -level 0 -f ba}
+    24 {-code 1     -level X -f ba snarf} {-code 1     -level 0 -f ba snarf}
+    25 {-code 0     -level X -f ba snarf} {-code 1     -level 0 -f ba snarf}
+    26 {-code error -level X -f ba snarf} {-code error -level 0 -f ba snarf}
+    27 {-code ok    -level X -f ba snarf} {-code 1     -level 0 -f ba snarf}
+    28 {-code boss  -level X -f ba snarf} {-code 1     -level 0 -f ba snarf}
+    29 {-code 1     -level X -f ba}       {-code 1     -level 0 -f ba}
+    30 {-code 0     -level X -f ba}       {-code 1     -level 0 -f ba}
+    31 {-code error -level X -f ba}       {-code error -level 0 -f ba}
+    32 {-code ok    -level X -f ba}       {-code 1     -level 0 -f ba}
+    33 {-code boss  -level X -f ba}       {-code 1     -level 0 -f ba}
+
+    34 {-code 1 -code 1     -level 0 -f ba snarf} {-code 1 -code 1     -level 0 -f ba snarf}
+    35 {-code 1 -code 0     -level 0 -f ba snarf} {-code 1             -level 0 -f ba snarf}
+    36 {-code 1 -code 1     -level 5 -f ba snarf} {-code 1 -code 1     -level 0 -f ba snarf}
+    37 {-code 1 -code 0     -level 5 -f ba snarf} {-code 1             -level 0 -f ba snarf}
+    38 {-code 1 -code error -level 0 -f ba snarf} {-code 1 -code error -level 0 -f ba snarf}
+    39 {-code 1 -code ok    -level 0 -f ba snarf} {-code 1             -level 0 -f ba snarf}
+    40 {-code 1 -code error -level 5 -f ba snarf} {-code 1 -code error -level 0 -f ba snarf}
+    41 {-code 1 -code ok    -level 5 -f ba snarf} {-code 1             -level 0 -f ba snarf}
+    42 {-code 1 -code boss  -level 0 -f ba snarf} {-code 1             -level 0 -f ba snarf}
+    43 {-code 1 -code boss  -level 5 -f ba snarf} {-code 1             -level 0 -f ba snarf}
+    44 {-code 1 -code 1     -level 0 -f ba}       {-code 1 -code 1     -level 0 -f ba}
+    45 {-code 1 -code 0     -level 0 -f ba}       {-code 1             -level 0 -f ba}
+    46 {-code 1 -code 1     -level 5 -f ba}       {-code 1 -code 1     -level 0 -f ba}
+    47 {-code 1 -code 0     -level 5 -f ba}       {-code 1             -level 0 -f ba}
+    48 {-code 1 -code error -level 0 -f ba}       {-code 1 -code error -level 0 -f ba}
+    49 {-code 1 -code ok    -level 0 -f ba}       {-code 1             -level 0 -f ba}
+    50 {-code 1 -code error -level 5 -f ba}       {-code 1 -code error -level 0 -f ba}
+    51 {-code 1 -code ok    -level 5 -f ba}       {-code 1             -level 0 -f ba}
+    52 {-code 1 -code boss  -level 0 -f ba}       {-code 1             -level 0 -f ba}
+    53 {-code 1 -code boss  -level 5 -f ba}       {-code 1             -level 0 -f ba}
+    54 {-code 1 -code 1     -level X -f ba snarf} {-code 1 -code 1     -level 0 -f ba snarf}
+    55 {-code 1 -code 0     -level X -f ba snarf} {-code 1             -level 0 -f ba snarf}
+    56 {-code 1 -code error -level X -f ba snarf} {-code 1 -code error -level 0 -f ba snarf}
+    57 {-code 1 -code ok    -level X -f ba snarf} {-code 1             -level 0 -f ba snarf}
+    58 {-code 1 -code boss  -level X -f ba snarf} {-code 1             -level 0 -f ba snarf}
+    59 {-code 1 -code 1     -level X -f ba}       {-code 1 -code 1     -level 0 -f ba}
+    60 {-code 1 -code 0     -level X -f ba}       {-code 1             -level 0 -f ba}
+    61 {-code 1 -code error -level X -f ba}       {-code 1 -code error -level 0 -f ba}
+    62 {-code 1 -code ok    -level X -f ba}       {-code 1             -level 0 -f ba}
+    63 {-code 1 -code boss  -level X -f ba}       {-code 1             -level 0 -f ba}
+
+    64 {-code 0 -code 1     -level 0 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+    65 {-code 0 -code 0     -level 0 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+    66 {-code 0 -code 1     -level 5 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+    67 {-code 0 -code 0     -level 5 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+    68 {-code 0 -code error -level 0 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+    69 {-code 0 -code ok    -level 0 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+    70 {-code 0 -code error -level 5 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+    71 {-code 0 -code ok    -level 5 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+    72 {-code 0 -code boss  -level 0 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+    73 {-code 0 -code boss  -level 5 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+    74 {-code 0 -code 1     -level 0 -f ba}       {-code 1 -level 0 -f ba}
+    75 {-code 0 -code 0     -level 0 -f ba}       {-code 1 -level 0 -f ba}
+    76 {-code 0 -code 1     -level 5 -f ba}       {-code 1 -level 0 -f ba}
+    77 {-code 0 -code 0     -level 5 -f ba}       {-code 1 -level 0 -f ba}
+    78 {-code 0 -code error -level 0 -f ba}       {-code 1 -level 0 -f ba}
+    79 {-code 0 -code ok    -level 0 -f ba}       {-code 1 -level 0 -f ba}
+    80 {-code 0 -code error -level 5 -f ba}       {-code 1 -level 0 -f ba}
+    81 {-code 0 -code ok    -level 5 -f ba}       {-code 1 -level 0 -f ba}
+    82 {-code 0 -code boss  -level 0 -f ba}       {-code 1 -level 0 -f ba}
+    83 {-code 0 -code boss  -level 5 -f ba}       {-code 1 -level 0 -f ba}
+    84 {-code 0 -code 1     -level X -f ba snarf} {-code 1 -level 0 -f ba snarf}
+    85 {-code 0 -code 0     -level X -f ba snarf} {-code 1 -level 0 -f ba snarf}
+    86 {-code 0 -code error -level X -f ba snarf} {-code 1 -level 0 -f ba snarf}
+    87 {-code 0 -code ok    -level X -f ba snarf} {-code 1 -level 0 -f ba snarf}
+    88 {-code 0 -code boss  -level X -f ba snarf} {-code 1 -level 0 -f ba snarf}
+    89 {-code 0 -code 1     -level X -f ba}       {-code 1 -level 0 -f ba}
+    90 {-code 0 -code 0     -level X -f ba}       {-code 1 -level 0 -f ba}
+    91 {-code 0 -code error -level X -f ba}       {-code 1 -level 0 -f ba}
+    92 {-code 0 -code ok    -level X -f ba}       {-code 1 -level 0 -f ba}
+    93 {-code 0 -code boss  -level X -f ba}       {-code 1 -level 0 -f ba}
+
+    94 {-code 1     -code 1 -level 0 -f ba snarf} {-code 1 -code 1     -level 0 -f ba snarf}
+    95 {-code 0     -code 1 -level 0 -f ba snarf} {-code 1             -level 0 -f ba snarf}
+    96 {-code 1     -code 1 -level 5 -f ba snarf} {-code 1 -code 1     -level 0 -f ba snarf}
+    97 {-code 0     -code 1 -level 5 -f ba snarf} {-code 1             -level 0 -f ba snarf}
+    98 {-code error -code 1 -level 0 -f ba snarf} {-code error -code 1 -level 0 -f ba snarf}
+    99 {-code ok    -code 1 -level 0 -f ba snarf} {-code 1             -level 0 -f ba snarf}
+    a0 {-code error -code 1 -level 5 -f ba snarf} {-code error -code 1 -level 0 -f ba snarf}
+    a1 {-code ok    -code 1 -level 5 -f ba snarf} {-code 1             -level 0 -f ba snarf}
+    a2 {-code boss  -code 1 -level 0 -f ba snarf} {-code 1             -level 0 -f ba snarf}
+    a3 {-code boss  -code 1 -level 5 -f ba snarf} {-code 1             -level 0 -f ba snarf}
+    a4 {-code 1     -code 1 -level 0 -f ba}       {-code 1 -code 1     -level 0 -f ba}
+    a5 {-code 0     -code 1 -level 0 -f ba}       {-code 1             -level 0 -f ba}
+    a6 {-code 1     -code 1 -level 5 -f ba}       {-code 1 -code 1     -level 0 -f ba}
+    a7 {-code 0     -code 1 -level 5 -f ba}       {-code 1             -level 0 -f ba}
+    a8 {-code error -code 1 -level 0 -f ba}       {-code error -code 1 -level 0 -f ba}
+    a9 {-code ok    -code 1 -level 0 -f ba}       {-code 1             -level 0 -f ba}
+    b0 {-code error -code 1 -level 5 -f ba}       {-code error -code 1 -level 0 -f ba}
+    b1 {-code ok    -code 1 -level 5 -f ba}       {-code 1             -level 0 -f ba}
+    b2 {-code boss  -code 1 -level 0 -f ba}       {-code 1             -level 0 -f ba}
+    b3 {-code boss  -code 1 -level 5 -f ba}       {-code 1             -level 0 -f ba}
+    b4 {-code 1     -code 1 -level X -f ba snarf} {-code 1 -code 1     -level 0 -f ba snarf}
+    b5 {-code 0     -code 1 -level X -f ba snarf} {-code 1             -level 0 -f ba snarf}
+    b6 {-code error -code 1 -level X -f ba snarf} {-code error -code 1 -level 0 -f ba snarf}
+    b7 {-code ok    -code 1 -level X -f ba snarf} {-code 1             -level 0 -f ba snarf}
+    b8 {-code boss  -code 1 -level X -f ba snarf} {-code 1             -level 0 -f ba snarf}
+    b9 {-code 1     -code 1 -level X -f ba}       {-code 1 -code 1     -level 0 -f ba}
+    c0 {-code 0     -code 1 -level X -f ba}       {-code 1             -level 0 -f ba}
+    c1 {-code error -code 1 -level X -f ba}       {-code error -code 1 -level 0 -f ba}
+    c2 {-code ok    -code 1 -level X -f ba}       {-code 1             -level 0 -f ba}
+    c3 {-code boss  -code 1 -level X -f ba}       {-code 1             -level 0 -f ba}
+
+    c4 {-code 1     -code 0 -level 0 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+    c5 {-code 0     -code 0 -level 0 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+    c6 {-code 1     -code 0 -level 5 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+    c7 {-code 0     -code 0 -level 5 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+    c8 {-code error -code 0 -level 0 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+    c9 {-code ok    -code 0 -level 0 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+    d0 {-code error -code 0 -level 5 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+    d1 {-code ok    -code 0 -level 5 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+    d2 {-code boss  -code 0 -level 0 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+    d3 {-code boss  -code 0 -level 5 -f ba snarf} {-code 1 -level 0 -f ba snarf}
+    d4 {-code 1     -code 0 -level 0 -f ba}       {-code 1 -level 0 -f ba}
+    d5 {-code 0     -code 0 -level 0 -f ba}       {-code 1 -level 0 -f ba}
+    d6 {-code 1     -code 0 -level 5 -f ba}       {-code 1 -level 0 -f ba}
+    d7 {-code 0     -code 0 -level 5 -f ba}       {-code 1 -level 0 -f ba}
+    d8 {-code error -code 0 -level 0 -f ba}       {-code 1 -level 0 -f ba}
+    d9 {-code ok    -code 0 -level 0 -f ba}       {-code 1 -level 0 -f ba}
+    e0 {-code error -code 0 -level 5 -f ba}       {-code 1 -level 0 -f ba}
+    e1 {-code ok    -code 0 -level 5 -f ba}       {-code 1 -level 0 -f ba}
+    e2 {-code boss  -code 0 -level 0 -f ba}       {-code 1 -level 0 -f ba}
+    e3 {-code boss  -code 0 -level 5 -f ba}       {-code 1 -level 0 -f ba}
+    e4 {-code 1     -code 0 -level X -f ba snarf} {-code 1 -level 0 -f ba snarf}
+    e5 {-code 0     -code 0 -level X -f ba snarf} {-code 1 -level 0 -f ba snarf}
+    e6 {-code error -code 0 -level X -f ba snarf} {-code 1 -level 0 -f ba snarf}
+    e7 {-code ok    -code 0 -level X -f ba snarf} {-code 1 -level 0 -f ba snarf}
+    e8 {-code boss  -code 0 -level X -f ba snarf} {-code 1 -level 0 -f ba snarf}
+    e9 {-code 1     -code 0 -level X -f ba}       {-code 1 -level 0 -f ba}
+    f0 {-code 0     -code 0 -level X -f ba}       {-code 1 -level 0 -f ba}
+    f1 {-code error -code 0 -level X -f ba}       {-code 1 -level 0 -f ba}
+    f2 {-code ok    -code 0 -level X -f ba}       {-code 1 -level 0 -f ba}
+    f3 {-code boss  -code 0 -level X -f ba}       {-code 1 -level 0 -f ba}
+} {
+    test io-71.$n {Tcl_SetChannelError} {testchannel} {
+
+	set f [makeFile {... dummy ...} cutsplice]
+	set c [open $f r]
+
+	set res [testchannel setchannelerror $c [lrange $msg 0 end]]
+	close $c
+	removeFile cutsplice
+
+	set res
+    } [lrange $expected 0 end]
+
+    test io-72.$n {Tcl_SetChannelErrorInterp} {testchannel} {
+
+	set f [makeFile {... dummy ...} cutsplice]
+	set c [open $f r]
+
+	set res [testchannel setchannelerrorinterp $c [lrange $msg 0 end]]
+	close $c
+	removeFile cutsplice
+
+	set res
+    } [lrange $expected 0 end]
+}
+
+test io-73.1 {channel Tcl_Obj SetChannelFromAny} {} {
+    # Test for Bug 1847044 - don't spoil type unless we have a valid channel
+    catch {close [lreplace [list a] 0 end]}
+} {1}
+
+test io-73.2 {channel Tcl_Obj SetChannelFromAny, bug 2407783} -setup {
+    # Invalidate intrep of 'channel' Tcl_Obj when transiting between interpreters.
+    set f [open [info script] r]
+} -body {
+    interp create foo
+    seek $f 0
+    set code [catch {interp eval foo [list seek $f 0]} msg]
+    # The string map converts the changing channel handle to a fixed string
+    list $code [string map [list $f @@] $msg]
+} -cleanup {
+    close $f
+} -result {1 {can not find channel named "@@"}}
+
+test io-73.3 {[5adc350683] [gets] after EOF} -setup {
+    set fn [makeFile {} io-73.3]
+    set rfd [open $fn r]
+    set wfd [open $fn a]
+    chan configure $wfd -buffering line
+    read $rfd
+} -body {
+    set result [eof $rfd]
+    puts $wfd "more data"
+    lappend result [eof $rfd]
+    lappend result [gets $rfd]
+    lappend result [eof $rfd]
+    lappend result [gets $rfd]
+    lappend result [eof $rfd]
+} -cleanup {
+    close $wfd
+    close $rfd
+    removeFile io-73.3
+} -result {1 1 {more data} 0 {} 1}
+
+test io-73.4 {[5adc350683] [read] after EOF} -setup {
+    set fn [makeFile {} io-73.4]
+    set rfd [open $fn r]
+    set wfd [open $fn a]
+    chan configure $wfd -buffering line
+    read $rfd
+} -body {
+    set result [eof $rfd]
+    puts $wfd "more data"
+    lappend result [eof $rfd]
+    lappend result [read $rfd]
+    lappend result [eof $rfd]
+} -cleanup {
+    close $wfd
+    close $rfd
+    removeFile io-73.4
+} -result {1 1 {more data
+} 1}
+
+test io-73.5 {effect of eof on encoding end flags} -setup {
+    set fn [makeFile {} io-73.5]
+    set rfd [open $fn r]
+    set wfd [open $fn a]
+    chan configure $wfd -buffering none -translation binary
+    chan configure $rfd -buffersize 5 -encoding utf-8
+    read $rfd
+} -body {
+    set result [eof $rfd]
+    puts -nonewline $wfd "more\u00c2\u00a0data"
+    lappend result [eof $rfd]
+    lappend result [read $rfd]
+    lappend result [eof $rfd]
+} -cleanup {
+    close $wfd
+    close $rfd
+    removeFile io-73.5
+} -result [list 1 1 more\u00a0data 1]
+
+test io-74.1 {[104f2885bb] improper cache validity check} -setup {
+    set fn [makeFile {} io-74.1]
+    set rfd [open $fn r]
+    testobj freeallvars
+    interp create slave
+} -constraints testobj -body {
+    teststringobj set 1 [string range $rfd 0 end]
+    read [teststringobj get 1]		
+    testobj duplicate 1 2
+    interp transfer {} $rfd slave
+    catch {read [teststringobj get 1]}
+    read [teststringobj get 2]		
+} -cleanup {
+    interp delete slave
+    testobj freeallvars
+    removeFile io-74.1
+} -returnCodes error -match glob -result {can not find channel named "*"}
+
+# ### ### ### ######### ######### #########
+
+# cleanup
+foreach file [list fooBar longfile script script2 output test1 pipe my_script \
+	test2 test3 cat stdout kyrillic.txt utf8-fcopy.txt utf8-rp.txt] {
+    removeFile $file
+}
+cleanupTests
+}
+namespace delete ::tcl::test::io
+return
diff --git a/tests/ioCmd.test b/tests/ioCmd.test
new file mode 100644
index 0000000..cd89a02
--- /dev/null
+++ b/tests/ioCmd.test
@@ -0,0 +1,3843 @@
+# -*- tcl -*-
+# Commands covered: open, close, gets, read, puts, seek, tell, eof, flush,
+#		    fblocked, fconfigure, open, channel, fcopy
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands.  Sourcing this file into Tcl runs the tests and
+# generates output for errors.  No output means no errors were found.
+#
+# Copyright (c) 1991-1994 The Regents of the University of California.
+# Copyright (c) 1994-1996 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+    package require tcltest 2
+    namespace import -force ::tcltest::*
+}
+
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
+
+# Custom constraints used in this file
+testConstraint fcopy		[llength [info commands fcopy]]
+testConstraint testchannel	[llength [info commands testchannel]]
+testConstraint thread [expr {0 == [catch {package require Thread 2.7-}]}]
+
+#----------------------------------------------------------------------
+
+test iocmd-1.1 {puts command} {
+   list [catch {puts} msg] $msg
+} {1 {wrong # args: should be "puts ?-nonewline? ?channelId? string"}}
+test iocmd-1.2 {puts command} {
+   list [catch {puts a b c d e f g} msg] $msg
+} {1 {wrong # args: should be "puts ?-nonewline? ?channelId? string"}}
+test iocmd-1.3 {puts command} {
+   list [catch {puts froboz -nonewline kablooie} msg] $msg
+} {1 {wrong # args: should be "puts ?-nonewline? ?channelId? string"}}
+test iocmd-1.4 {puts command} {
+   list [catch {puts froboz hello} msg] $msg
+} {1 {can not find channel named "froboz"}}
+test iocmd-1.5 {puts command} {
+   list [catch {puts stdin hello} msg] $msg
+} {1 {channel "stdin" wasn't opened for writing}}
+
+set path(test1) [makeFile {} test1]
+
+test iocmd-1.6 {puts command} {
+    set f [open $path(test1) w]
+    fconfigure $f -translation lf -eofchar {}
+    puts -nonewline $f foobar
+    close $f
+    file size $path(test1)
+} 6
+test iocmd-1.7 {puts command} {
+    set f [open $path(test1) w]
+    fconfigure $f -translation lf -eofchar {}
+    puts $f foobar
+    close $f
+    file size $path(test1)
+} 7
+test iocmd-1.8 {puts command} {
+    set f [open $path(test1) w]
+    fconfigure $f -translation lf -eofchar {} -encoding iso8859-1
+    puts -nonewline $f [binary format a4a5 foo bar]
+    close $f
+    file size $path(test1)
+} 9
+
+test iocmd-2.1 {flush command} {
+   list [catch {flush} msg] $msg
+} {1 {wrong # args: should be "flush channelId"}}
+test iocmd-2.2 {flush command} {
+   list [catch {flush a b c d e} msg] $msg
+} {1 {wrong # args: should be "flush channelId"}}
+test iocmd-2.3 {flush command} {
+   list [catch {flush foo} msg] $msg
+} {1 {can not find channel named "foo"}}
+test iocmd-2.4 {flush command} {
+   list [catch {flush stdin} msg] $msg
+} {1 {channel "stdin" wasn't opened for writing}}
+
+test iocmd-3.1 {gets command} {
+   list [catch {gets} msg] $msg
+} {1 {wrong # args: should be "gets channelId ?varName?"}}
+test iocmd-3.2 {gets command} {
+   list [catch {gets a b c d e f g} msg] $msg
+} {1 {wrong # args: should be "gets channelId ?varName?"}}
+test iocmd-3.3 {gets command} {
+   list [catch {gets aaa} msg] $msg
+} {1 {can not find channel named "aaa"}}
+test iocmd-3.4 {gets command} {
+   list [catch {gets stdout} msg] $msg
+} {1 {channel "stdout" wasn't opened for reading}}
+test iocmd-3.5 {gets command} {
+    set f [open $path(test1) w]
+    puts $f [binary format a4a5 foo bar]
+    close $f
+    set f [open $path(test1) r]
+    set result [gets $f]
+    close $f
+    set x foo\x00
+    set x "${x}bar\x00\x00"
+    string compare $x $result
+} 0
+
+test iocmd-4.1 {read command} {
+   list [catch {read} msg] $msg
+} {1 {wrong # args: should be "read channelId ?numChars?" or "read ?-nonewline? channelId"}}
+test iocmd-4.2 {read command} {
+   list [catch {read a b c d e f g h} msg] $msg
+} {1 {wrong # args: should be "read channelId ?numChars?" or "read ?-nonewline? channelId"}}
+test iocmd-4.3 {read command} {
+   list [catch {read aaa} msg] $msg
+} {1 {can not find channel named "aaa"}}
+test iocmd-4.4 {read command} {
+   list [catch {read -nonewline} msg] $msg
+} {1 {wrong # args: should be "read channelId ?numChars?" or "read ?-nonewline? channelId"}}
+test iocmd-4.5 {read command} {
+   list [catch {read -nonew file4} msg] $msg $::errorCode
+} {1 {can not find channel named "-nonew"} {TCL LOOKUP CHANNEL -nonew}}
+test iocmd-4.6 {read command} {
+   list [catch {read stdout} msg] $msg
+} {1 {channel "stdout" wasn't opened for reading}}
+test iocmd-4.7 {read command} {
+   list [catch {read -nonewline stdout} msg] $msg
+} {1 {channel "stdout" wasn't opened for reading}}
+test iocmd-4.8 {read command with incorrect combination of arguments} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    puts $f "Two lines: this one"
+    puts $f "and this one"
+    close $f
+    set f [open $path(test1)]
+    set x [list [catch {read -nonewline $f 20 z} msg] $msg $::errorCode]
+    close $f
+    set x
+} {1 {wrong # args: should be "read channelId ?numChars?" or "read ?-nonewline? channelId"} {TCL WRONGARGS}}
+test iocmd-4.9 {read command} {
+    list [catch {read stdin foo} msg] $msg $::errorCode
+} {1 {expected non-negative integer but got "foo"} {TCL VALUE NUMBER}}
+test iocmd-4.10 {read command} {
+    list [catch {read file107} msg] $msg $::errorCode
+} {1 {can not find channel named "file107"} {TCL LOOKUP CHANNEL file107}}
+set path(test3) [makeFile {} test3]
+test iocmd-4.11 {read command} {
+    set f [open $path(test3) w]
+    set x [list [catch {read $f} msg] $msg $::errorCode]
+    close $f
+    string compare [string tolower $x] \
+	[list 1 [format "channel \"%s\" wasn't opened for reading" $f] none]
+} 0
+test iocmd-4.12 {read command} -setup {
+    set f [open $path(test1)]
+} -body {
+    list [catch {read $f 12z} msg] $msg $::errorCode
+} -cleanup {
+    close $f
+} -result {1 {expected non-negative integer but got "12z"} {TCL VALUE NUMBER}}
+
+test iocmd-5.1 {seek command} -returnCodes error -body {
+    seek
+} -result {wrong # args: should be "seek channelId offset ?origin?"}
+test iocmd-5.2 {seek command} -returnCodes error -body {
+    seek a b c d e f g
+} -result {wrong # args: should be "seek channelId offset ?origin?"}
+test iocmd-5.3 {seek command} -returnCodes error -body {
+    seek stdin gugu
+} -result {expected integer but got "gugu"}
+test iocmd-5.4 {seek command} -returnCodes error -body {
+    seek stdin 100 gugu
+} -result {bad origin "gugu": must be start, current, or end}
+
+test iocmd-6.1 {tell command} {
+    list [catch {tell} msg] $msg
+} {1 {wrong # args: should be "tell channelId"}}
+test iocmd-6.2 {tell command} {
+    list [catch {tell a b c d e} msg] $msg
+} {1 {wrong # args: should be "tell channelId"}}
+test iocmd-6.3 {tell command} {
+    list [catch {tell aaa} msg] $msg
+} {1 {can not find channel named "aaa"}}
+
+test iocmd-7.1 {close command} {
+    list [catch {close} msg] $msg
+} {1 {wrong # args: should be "close channelId ?direction?"}}
+test iocmd-7.2 {close command} {
+    list [catch {close a b c d e} msg] $msg
+} {1 {wrong # args: should be "close channelId ?direction?"}}
+test iocmd-7.3 {close command} {
+    list [catch {close aaa} msg] $msg
+} {1 {can not find channel named "aaa"}}
+test iocmd-7.4 {close command} -setup {
+    set chan [open [info script] r]
+} -body {
+    chan close $chan bar
+} -cleanup {
+    close $chan
+} -returnCodes error -result "bad direction \"bar\": must be read or write"
+test iocmd-7.5 {close command} -setup {
+    set chan [open [info script] r]
+} -body {
+    chan close $chan write
+} -cleanup {
+    close $chan
+} -returnCodes error -result "Half-close of write-side not possible, side not opened or already closed"
+
+test iocmd-8.1 {fconfigure command} {
+    list [catch {fconfigure} msg] $msg
+} {1 {wrong # args: should be "fconfigure channelId ?-option value ...?"}}
+test iocmd-8.2 {fconfigure command} {
+    list [catch {fconfigure a b c d e f} msg] $msg
+} {1 {wrong # args: should be "fconfigure channelId ?-option value ...?"}}
+test iocmd-8.3 {fconfigure command} {
+    list [catch {fconfigure a b} msg] $msg
+} {1 {can not find channel named "a"}}
+test iocmd-8.4 {fconfigure command} {
+    file delete $path(test1)
+    set f1 [open $path(test1) w]
+    set x [list [catch {fconfigure $f1 froboz} msg] $msg]
+    close $f1
+    set x
+} {1 {bad option "froboz": should be one of -blocking, -buffering, -buffersize, -encoding, -eofchar, or -translation}}
+test iocmd-8.5 {fconfigure command} {
+    list [catch {fconfigure stdin -buffering froboz} msg] $msg
+} {1 {bad value for -buffering: must be one of full, line, or none}}
+test iocmd-8.6 {fconfigure command} {
+    list [catch {fconfigure stdin -translation froboz} msg] $msg
+} {1 {bad value for -translation: must be one of auto, binary, cr, lf, crlf, or platform}}
+test iocmd-8.7 {fconfigure command} {
+    file delete $path(test1)
+    set f1 [open $path(test1) w]
+    fconfigure $f1 -translation lf -eofchar {} -encoding unicode
+    set x [fconfigure $f1]
+    close $f1
+    set x
+} {-blocking 1 -buffering full -buffersize 4096 -encoding unicode -eofchar {} -translation lf}
+test iocmd-8.8 {fconfigure command} {
+    file delete $path(test1)
+    set f1 [open $path(test1) w]
+    fconfigure $f1 -translation lf -buffering line -buffersize 3030 \
+		-eofchar {} -encoding unicode
+    set x ""
+    lappend x [fconfigure $f1 -buffering]
+    lappend x [fconfigure $f1]
+    close $f1
+    set x
+} {line {-blocking 1 -buffering line -buffersize 3030 -encoding unicode -eofchar {} -translation lf}}
+test iocmd-8.9 {fconfigure command} {
+    file delete $path(test1)
+    set f1 [open $path(test1) w]
+    fconfigure $f1 -translation binary -buffering none -buffersize 4040 \
+		-eofchar {} -encoding binary
+    set x [fconfigure $f1]
+    close $f1
+    set x
+} {-blocking 1 -buffering none -buffersize 4040 -encoding binary -eofchar {} -translation lf}
+test iocmd-8.10 {fconfigure command} {
+    list [catch {fconfigure a b} msg] $msg
+} {1 {can not find channel named "a"}}
+set path(fconfigure.dummy) [makeFile {} fconfigure.dummy]
+test iocmd-8.11 {fconfigure command} {
+    set chan [open $path(fconfigure.dummy) r]
+    set res [list [catch {fconfigure $chan -froboz blarfo} msg] $msg]
+    close $chan
+    set res
+} {1 {bad option "-froboz": should be one of -blocking, -buffering, -buffersize, -encoding, -eofchar, or -translation}}
+test iocmd-8.12 {fconfigure command} {
+    set chan [open $path(fconfigure.dummy) r]
+    set res [list [catch {fconfigure $chan -b blarfo} msg] $msg]
+    close $chan
+    set res
+} {1 {bad option "-b": should be one of -blocking, -buffering, -buffersize, -encoding, -eofchar, or -translation}}
+test iocmd-8.13 {fconfigure command} {
+    set chan [open $path(fconfigure.dummy) r]
+    set res [list [catch {fconfigure $chan -buffer blarfo} msg] $msg]
+    close $chan
+    set res
+} {1 {bad option "-buffer": should be one of -blocking, -buffering, -buffersize, -encoding, -eofchar, or -translation}}
+removeFile fconfigure.dummy
+test iocmd-8.14 {fconfigure command} {
+    fconfigure stdin -buffers
+} 4096
+test iocmd-8.15.1 {fconfigure command / tcp channel} -constraints {socket unixOrPc} -setup {
+    set srv [socket -server iocmdSRV -myaddr 127.0.0.1 0]
+    set port [lindex [fconfigure $srv -sockname] 2]
+    proc iocmdSRV {sock ip port} {close $sock}
+    set cli [socket 127.0.0.1 $port]
+} -body {
+    fconfigure $cli -blah
+} -cleanup {
+    close $cli
+    close $srv
+    unset cli srv port
+    rename iocmdSRV {}
+} -returnCodes error -result {bad option "-blah": should be one of -blocking, -buffering, -buffersize, -encoding, -eofchar, -translation, -connecting, -peername, or -sockname}
+test iocmd-8.16 {fconfigure command / tcp channel} -constraints socket -setup {
+    set srv [socket -server iocmdSRV -myaddr 127.0.0.1 0]
+    set port [lindex [fconfigure $srv -sockname] 2]
+    proc iocmdSRV {sock ip port} {close $sock}
+    set cli [socket 127.0.0.1 $port]
+} -body {
+    expr {[lindex [fconfigure $cli -peername] 2] == $port}
+} -cleanup {
+    close $cli
+    close $srv
+    unset cli srv port
+    rename iocmdSRV {}
+} -result 1
+test iocmd-8.17 {fconfigure command / tcp channel} -constraints nonPortable -setup {
+    set srv [socket -server iocmdSRV -myaddr 127.0.0.1 0]
+    set port [lindex [fconfigure $srv -sockname] 2]
+    proc iocmdSRV {sock ip port} {close $sock}
+    set cli [socket 127.0.0.1 $port]
+} -body {
+    # It is possible that you don't get the connection reset by peer
+    # error but rather a valid answer. Depends on the tcp implementation
+    update
+    puts $cli "blah"
+    flush $cli;			# that flush could/should fail too
+    update
+    regsub -all {can([^:])+: } [catch {fconfigure $cli -peername} msg] {}
+} -cleanup {
+    close $cli
+    close $srv
+    unset cli srv port
+    rename iocmdSRV {}
+} -result 1
+test iocmd-8.18 {fconfigure command / unix tty channel} -constraints {nonPortable unix} -setup {
+    set tty ""
+} -body {
+    # might fail if /dev/ttya is unavailable
+    set tty [open /dev/ttya]
+    fconfigure $tty -blah blih
+} -cleanup {
+    if {$tty ne ""} {
+	close $tty
+    }
+} -returnCodes error -result {bad option "-blah": should be one of -blocking, -buffering, -buffersize, -encoding, -eofchar, -translation, or -mode}
+test iocmd-8.19 {fconfigure command / win tty channel} -constraints {nonPortable win} -setup {
+    set tty ""
+} -body {
+    # might fail early if com1 is unavailable
+    set tty [open com1]
+    fconfigure $tty -blah blih
+} -cleanup {
+    if {$tty ne ""} {
+	close $tty
+    }
+} -returnCodes error -result {bad option "-blah": should be one of -blocking, -buffering, -buffersize, -encoding, -eofchar, -translation, -mode, -handshake, -pollinterval, -sysbuffer, -timeout, -ttycontrol, or -xchar}
+# TODO: Test parsing of serial channel options (nonPortable, since requires an
+# open channel to work with).
+
+test iocmd-9.1 {eof command} {
+    list [catch {eof} msg] $msg $::errorCode
+} {1 {wrong # args: should be "eof channelId"} {TCL WRONGARGS}}
+test iocmd-9.2 {eof command} {
+    list [catch {eof a b} msg] $msg $::errorCode
+} {1 {wrong # args: should be "eof channelId"} {TCL WRONGARGS}}
+test iocmd-9.3 {eof command} {
+    catch {close file100}
+    list [catch {eof file100} msg] $msg $::errorCode
+} {1 {can not find channel named "file100"} {TCL LOOKUP CHANNEL file100}}
+
+# The tests for Tcl_ExecObjCmd are in exec.test
+
+test iocmd-10.1 {fblocked command} {
+    list [catch {fblocked} msg] $msg
+} {1 {wrong # args: should be "fblocked channelId"}}
+test iocmd-10.2 {fblocked command} {
+    list [catch {fblocked a b c d e f g} msg] $msg
+} {1 {wrong # args: should be "fblocked channelId"}}
+test iocmd-10.3 {fblocked command} {
+    list [catch {fblocked file1000} msg] $msg
+} {1 {can not find channel named "file1000"}}
+test iocmd-10.4 {fblocked command} {
+    list [catch {fblocked stdout} msg] $msg
+} {1 {channel "stdout" wasn't opened for reading}}
+test iocmd-10.5 {fblocked command} {
+    fblocked stdin
+} 0
+
+set path(test4) [makeFile {} test4]
+set path(test5) [makeFile {} test5]
+
+file delete $path(test5)
+test iocmd-11.1 {I/O to command pipelines} {unixOrPc unixExecs} {
+    set f [open $path(test4) w]
+    close $f
+    list [catch {open "| cat < \"$path(test4)\" > \"$path(test5)\"" w} msg] $msg $::errorCode
+} {1 {can't write input to command: standard input was redirected} {TCL OPERATION EXEC BADREDIRECT}}
+test iocmd-11.2 {I/O to command pipelines} {unixOrPc unixExecs} {
+    list [catch {open "| echo > \"$path(test5)\"" r} msg] $msg $::errorCode
+} {1 {can't read output from command: standard output was redirected} {TCL OPERATION EXEC BADREDIRECT}}
+test iocmd-11.3 {I/O to command pipelines} {unixOrPc unixExecs} {
+    list [catch {open "| echo > \"$path(test5)\"" r+} msg] $msg $::errorCode
+} {1 {can't read output from command: standard output was redirected} {TCL OPERATION EXEC BADREDIRECT}}
+test iocmd-11.4 {I/O to command pipelines} unixOrPc {
+    list [catch {open "| no_such_command_exists" rb} msg] $msg $::errorCode
+} {1 {couldn't execute "no_such_command_exists": no such file or directory} {POSIX ENOENT {no such file or directory}}}
+
+test iocmd-12.1 {POSIX open access modes: RDONLY} {
+    file delete $path(test1)
+    set f [open $path(test1) w]
+    puts $f "Two lines: this one"
+    puts $f "and this one"
+    close $f
+    set f [open $path(test1) RDONLY]
+    set x [list [gets $f] [catch {puts $f Test} msg] $msg]
+    close $f
+    string compare $x \
+	"{Two lines: this one} 1 [list [format "channel \"%s\" wasn't opened for writing" $f]]"
+} 0
+test iocmd-12.2 {POSIX open access modes: RDONLY} -match regexp -body {
+    file delete $path(test3)
+    open $path(test3) RDONLY
+} -returnCodes error -result {(?i)couldn't open ".*test3": no such file or directory}
+test iocmd-12.3 {POSIX open access modes: WRONLY} -match regexp -body {
+    file delete $path(test3)
+    open $path(test3) WRONLY
+} -returnCodes error -result {(?i)couldn't open ".*test3": no such file or directory}
+#
+# Test 13.4 relies on assigning the same channel name twice.
+#
+test iocmd-12.4 {POSIX open access modes: WRONLY} {unix} {
+    file delete $path(test3)
+    set f [open $path(test3) w]
+    fconfigure $f -eofchar {}
+    puts $f xyzzy
+    close $f
+    set f [open $path(test3) WRONLY]
+    fconfigure $f -eofchar {}
+    puts -nonewline $f "ab"
+    seek $f 0 current
+    set x [list [catch {gets $f} msg] $msg]
+    close $f
+    set f [open $path(test3) r]
+    fconfigure $f -eofchar {}
+    lappend x [gets $f]
+    close $f
+    set y [list 1 [format "channel \"%s\" wasn't opened for reading" $f] abzzy]
+    string compare $x $y
+} 0
+test iocmd-12.5 {POSIX open access modes: RDWR} -match regexp -body {
+    file delete $path(test3)
+    open $path(test3) RDWR
+} -returnCodes error -result {(?i)couldn't open ".*test3": no such file or directory}
+test iocmd-12.6 {POSIX open access modes: errors} {
+    concat [catch {open $path(test3) "FOO \{BAR BAZ"} msg] $msg\n$::errorInfo
+} "1 unmatched open brace in list
+unmatched open brace in list
+    while processing open access modes \"FOO {BAR BAZ\"
+    invoked from within
+\"open \$path(test3) \"FOO \\{BAR BAZ\"\""
+test iocmd-12.7 {POSIX open access modes: errors} {
+  list [catch {open $path(test3) {FOO BAR BAZ}} msg] $msg
+} {1 {invalid access mode "FOO": must be RDONLY, WRONLY, RDWR, APPEND, BINARY, CREAT, EXCL, NOCTTY, NONBLOCK, or TRUNC}}
+test iocmd-12.8 {POSIX open access modes: errors} {
+    list [catch {open $path(test3) {TRUNC CREAT}} msg] $msg
+} {1 {access mode must include either RDONLY, WRONLY, or RDWR}}
+close [open $path(test3) w]
+test iocmd-12.9 {POSIX open access modes: BINARY} {
+    list [catch {open $path(test1) BINARY} msg] $msg
+} {1 {access mode must include either RDONLY, WRONLY, or RDWR}}
+test iocmd-12.10 {POSIX open access modes: BINARY} {
+    set f [open $path(test1) {WRONLY BINARY TRUNC}]
+    puts $f a
+    puts $f b
+    puts -nonewline $f c	;# contents are now 5 bytes: a\nb\nc
+    close $f
+    set f [open $path(test1) r]
+    fconfigure $f -translation binary
+    set result [string length [read $f]]
+    close $f
+    set result
+} 5
+test iocmd-12.11 {POSIX open access modes: BINARY} {
+    set f [open $path(test1) {WRONLY BINARY TRUNC}]
+    puts $f \u0248		;# gets truncated to \u0048
+    close $f
+    set f [open $path(test1) r]
+    fconfigure $f -translation binary
+    set result [read -nonewline $f]
+    close $f
+    set result
+} \u0048
+
+test iocmd-13.1 {errors in open command} {
+    list [catch {open} msg] $msg
+} {1 {wrong # args: should be "open fileName ?access? ?permissions?"}}
+test iocmd-13.2 {errors in open command} {
+    list [catch {open a b c d} msg] $msg
+} {1 {wrong # args: should be "open fileName ?access? ?permissions?"}}
+test iocmd-13.3 {errors in open command} {
+    list [catch {open $path(test1) x} msg] $msg
+} {1 {illegal access mode "x"}}
+test iocmd-13.4 {errors in open command} {
+    list [catch {open $path(test1) rw} msg] $msg
+} {1 {illegal access mode "rw"}}
+test iocmd-13.5 {errors in open command} {
+    list [catch {open $path(test1) r+1} msg] $msg
+} {1 {illegal access mode "r+1"}}
+test iocmd-13.6 {errors in open command} {
+    set msg [list [catch {open _non_existent_} msg] $msg $::errorCode]
+    regsub [file join {} _non_existent_] $msg "_non_existent_" msg
+    string tolower $msg
+} {1 {couldn't open "_non_existent_": no such file or directory} {posix enoent {no such file or directory}}}
+test iocmd-13.7 {errors in open command} {
+    list [catch {open $path(test1) b} msg] $msg
+} {1 {illegal access mode "b"}}
+test iocmd-13.8 {errors in open command} {
+    list [catch {open $path(test1) rbb} msg] $msg
+} {1 {illegal access mode "rbb"}}
+test iocmd-13.9 {errors in open command} {
+    list [catch {open $path(test1) r++} msg] $msg
+} {1 {illegal access mode "r++"}}
+test iocmd-13.10.1 {open for append, a mode} -setup {
+    set log   [makeFile {} out]
+    set chans {}
+} -body {
+    foreach i { 0 1 2 3 4 5 6 7 8 9 } {
+	puts [set ch [open $log a]] $i
+	lappend chans $ch
+    }
+    foreach ch $chans {catch {close $ch}}
+    lsort [split [string trim [viewFile out]] \n]
+} -cleanup {
+    removeFile out
+    # Ensure that channels are gone, even if body failed to do so
+    foreach ch $chans {catch {close $ch}}
+} -result {0 1 2 3 4 5 6 7 8 9}
+test iocmd-13.10.2 {open for append, O_APPEND} -setup {
+    set log   [makeFile {} out]
+    set chans {}
+} -body {
+    foreach i { 0 1 2 3 4 5 6 7 8 9 } {
+	puts [set ch [open $log {WRONLY CREAT APPEND}]] $i
+	lappend chans $ch
+    }
+    foreach ch $chans {catch {close $ch}}
+    lsort [split [string trim [viewFile out]] \n]
+} -cleanup {
+    removeFile out
+    # Ensure that channels are gone, even if body failed to do so
+    foreach ch $chans {catch {close $ch}}
+} -result {0 1 2 3 4 5 6 7 8 9}
+test ioCmd-13.11 {open ... a+ must not use O_APPEND: Bug 1773127} -setup {
+    set f [makeFile {} ioutil41.tmp]
+    set fid [open $f wb]
+    puts -nonewline $fid 123
+    close $fid
+} -body {
+    set fid [open $f ab+]
+    puts -nonewline $fid 456
+    seek $fid 2
+    set d [read $fid 2]
+    seek $fid 4
+    puts -nonewline $fid x
+    close $fid
+    set fid [open $f rb]
+    append d [read $fid]
+    close $fid
+    return $d
+} -cleanup {
+    removeFile $f
+} -result 341234x6
+
+
+test iocmd-14.1 {file id parsing errors} {
+    list [catch {eof gorp} msg] $msg $::errorCode
+} {1 {can not find channel named "gorp"} {TCL LOOKUP CHANNEL gorp}}
+test iocmd-14.2 {file id parsing errors} {
+    list [catch {eof filex} msg] $msg
+} {1 {can not find channel named "filex"}}
+test iocmd-14.3 {file id parsing errors} {
+    list [catch {eof file12a} msg] $msg
+} {1 {can not find channel named "file12a"}}
+test iocmd-14.4 {file id parsing errors} {
+    list [catch {eof file123} msg] $msg
+} {1 {can not find channel named "file123"}}
+test iocmd-14.5 {file id parsing errors} {
+    list [catch {eof stdout} msg] $msg
+} {0 0}
+test iocmd-14.6 {file id parsing errors} {
+    list [catch {eof stdin} msg] $msg
+} {0 0}
+test iocmd-14.7 {file id parsing errors} {
+    list [catch {eof stdout} msg] $msg
+} {0 0}
+test iocmd-14.8 {file id parsing errors} {
+    list [catch {eof stderr} msg] $msg
+} {0 0}
+test iocmd-14.9 {file id parsing errors} {
+    list [catch {eof stderr1} msg] $msg
+} {1 {can not find channel named "stderr1"}}
+
+set f [open $path(test1) w]
+close $f
+
+set expect "1 {can not find channel named \"$f\"}"
+test iocmd-14.10 {file id parsing errors} {
+    list [catch {eof $f} msg] $msg
+} $expect
+
+test iocmd-15.1 {Tcl_FcopyObjCmd} {fcopy} {
+    list [catch {fcopy} msg] $msg
+} {1 {wrong # args: should be "fcopy input output ?-size size? ?-command callback?"}}
+test iocmd-15.2 {Tcl_FcopyObjCmd} {fcopy} {
+    list [catch {fcopy 1} msg] $msg
+} {1 {wrong # args: should be "fcopy input output ?-size size? ?-command callback?"}}
+test iocmd-15.3 {Tcl_FcopyObjCmd} {fcopy} {
+    list [catch {fcopy 1 2 3 4 5 6 7} msg] $msg
+} {1 {wrong # args: should be "fcopy input output ?-size size? ?-command callback?"}}
+test iocmd-15.4 {Tcl_FcopyObjCmd} {fcopy} {
+    list [catch {fcopy 1 2 3} msg] $msg
+} {1 {wrong # args: should be "fcopy input output ?-size size? ?-command callback?"}}
+test iocmd-15.5 {Tcl_FcopyObjCmd} {fcopy} {
+    list [catch {fcopy 1 2 3 4 5} msg] $msg
+} {1 {wrong # args: should be "fcopy input output ?-size size? ?-command callback?"}}
+
+set path(test2) [makeFile {} test2]
+set f [open $path(test1) w]
+close $f
+set rfile [open $path(test1) r]
+set wfile [open $path(test2) w]
+
+test iocmd-15.6 {Tcl_FcopyObjCmd} {fcopy} {
+    list [catch {fcopy foo $wfile} msg] $msg
+} {1 {can not find channel named "foo"}}
+test iocmd-15.7 {Tcl_FcopyObjCmd} {fcopy} {
+    list [catch {fcopy $rfile foo} msg] $msg
+} {1 {can not find channel named "foo"}}
+test iocmd-15.8 {Tcl_FcopyObjCmd} {fcopy} {
+    list [catch {fcopy $wfile $wfile} msg] $msg
+} "1 {channel \"$wfile\" wasn't opened for reading}"
+test iocmd-15.9 {Tcl_FcopyObjCmd} {fcopy} {
+    list [catch {fcopy $rfile $rfile} msg] $msg
+} "1 {channel \"$rfile\" wasn't opened for writing}"
+test iocmd-15.10 {Tcl_FcopyObjCmd} {fcopy} {
+    list [catch {fcopy $rfile $wfile foo bar} msg] $msg
+} {1 {bad option "foo": must be -size or -command}}
+test iocmd-15.11 {Tcl_FcopyObjCmd} {fcopy} {
+    list [catch {fcopy $rfile $wfile -size foo} msg] $msg
+} {1 {expected integer but got "foo"}}
+test iocmd-15.12 {Tcl_FcopyObjCmd} {fcopy} {
+    list [catch {fcopy $rfile $wfile -command bar -size foo} msg] $msg
+} {1 {expected integer but got "foo"}}
+
+close $rfile
+close $wfile
+
+# ### ### ### ######### ######### #########
+## Testing the reflected channel.
+
+test iocmd-20.0 {chan, wrong#args} {
+    catch {chan} msg
+    set msg
+} {wrong # args: should be "chan subcommand ?arg ...?"}
+test iocmd-20.1 {chan, unknown method} -body {
+    chan foo
+} -returnCodes error -match glob -result {unknown or ambiguous subcommand "foo": must be *}
+
+# --- --- --- --------- --------- ---------
+# chan create, and method "initalize"
+
+test iocmd-21.0 {chan create, wrong#args, not enough} {
+    catch {chan create} msg
+    set msg
+} {wrong # args: should be "chan create mode cmdprefix"}
+test iocmd-21.1 {chan create, wrong#args, too many} {
+    catch {chan create a b c} msg
+    set msg
+} {wrong # args: should be "chan create mode cmdprefix"}
+test iocmd-21.2 {chan create, invalid r/w mode, empty} {
+    proc foo {} {}
+    catch {chan create {} foo} msg
+    rename foo {}
+    set msg
+} {bad mode list: is empty}
+test iocmd-21.3 {chan create, invalid r/w mode, bad string} {
+    proc foo {} {}
+    catch {chan create {c} foo} msg
+    rename foo {}
+    set msg
+} {bad mode "c": must be read or write}
+test iocmd-21.4 {chan create, bad handler, not a list} {
+    catch {chan create {r w} "foo \{"} msg
+    set msg
+} {unmatched open brace in list}
+test iocmd-21.5 {chan create, bad handler, not a command} {
+    catch {chan create {r w} foo} msg
+    set msg
+} {invalid command name "foo"}
+test iocmd-21.6 {chan create, initialize failed, bad signature} {
+    proc foo {} {}
+    catch {chan create {r w} foo} msg
+    rename foo {}
+    set msg
+} {wrong # args: should be "foo"}
+test iocmd-21.7 {chan create, initialize failed, bad signature} {
+    proc foo {} {}
+    catch {chan create {r w} ::foo} msg
+    rename foo {}
+    set msg
+} {wrong # args: should be "::foo"}
+test iocmd-21.8 {chan create, initialize failed, bad result, not a list} -body {
+    proc foo {args} {return "\{"}
+    catch {chan create {r w} foo} msg
+    rename foo {}
+    set ::errorInfo
+} -match glob -result {chan handler "foo initialize" returned non-list: *}
+test iocmd-21.9 {chan create, initialize failed, bad result, not a list} -body {
+    proc foo {args} {return \{\{\}}
+    catch {chan create {r w} foo} msg
+    rename foo {}
+    set msg
+} -match glob -result {chan handler "foo initialize" returned non-list: *}
+test iocmd-21.10 {chan create, initialize failed, bad result, empty list} -body {
+    proc foo {args} {}
+    catch {chan create {r w} foo} msg
+    rename foo {}
+    set msg
+} -match glob -result {*all required methods*}
+test iocmd-21.11 {chan create, initialize failed, bad result, bogus method name} -body {
+    proc foo {args} {return 1}
+    catch {chan create {r w} foo} msg
+    rename foo {}
+    set msg
+} -match glob -result {*bad method "1": must be *}
+test iocmd-21.12 {chan create, initialize failed, bad result, bogus method name} -body {
+    proc foo {args} {return {a b c}}
+    catch {chan create {r w} foo} msg
+    rename foo {}
+    set msg
+} -match glob -result {*bad method "c": must be *}
+test iocmd-21.13 {chan create, initialize failed, bad result, required methods missing} -body {
+    proc foo {args} {return {initialize finalize}}
+    catch {chan create {r w} foo} msg
+    rename foo {}
+    set msg
+} -match glob -result {*all required methods*}
+test iocmd-21.14 {chan create, initialize failed, bad result, mode/handler mismatch} -body {
+    proc foo {args} {return {initialize finalize watch read}}
+    catch {chan create {r w} foo} msg
+    rename foo {}
+    set msg
+} -match glob -result {*lacks a "write" method}
+test iocmd-21.15 {chan create, initialize failed, bad result, mode/handler mismatch} -body {
+    proc foo {args} {return {initialize finalize watch write}}
+    catch {chan create {r w} foo} msg
+    rename foo {}
+    set msg
+} -match glob -result {*lacks a "read" method}
+test iocmd-21.16 {chan create, initialize failed, bad result, cget(all) mismatch} -body {
+    proc foo {args} {return {initialize finalize watch cget write read}}
+    catch {chan create {r w} foo} msg
+    rename foo {}
+    set msg
+} -match glob -result {*supports "cget" but not "cgetall"}
+test iocmd-21.17 {chan create, initialize failed, bad result, cget(all) mismatch} -body {
+    proc foo {args} {return {initialize finalize watch cgetall read write}}
+    catch {chan create {r w} foo} msg
+    rename foo {}
+    set msg
+} -match glob -result {*supports "cgetall" but not "cget"}
+test iocmd-21.18 {chan create, initialize ok, creates channel} -match glob -body {
+    proc foo {args} {
+	global  res
+	lappend res $args
+	if {[lindex $args 0] ne "initialize"} {return}
+	return {initialize finalize watch read write}
+    }
+    set res {}
+    lappend res [file channel rc*]
+    lappend res [chan create {r w} foo]
+    lappend res [close [lindex $res end]]
+    lappend res [file channel rc*]
+    rename foo {}
+    set res
+} -result {{} {initialize rc* {read write}} rc* {finalize rc*} {} {}}
+test iocmd-21.19 {chan create, init failure -> no channel, no finalize} -match glob -body {
+    proc foo {args} {
+	global  res
+	lappend res $args
+	return {}
+    }
+    set res {}
+    lappend res [file channel rc*]
+    lappend res [catch {chan create {r w} foo} msg]
+    lappend res $msg
+    lappend res [file channel rc*]
+    rename foo {}
+    set res
+} -result {{} {initialize rc* {read write}} 1 {*all required methods*} {}}
+test iocmd-21.20 {Bug 88aef05cda} -setup {
+    proc foo {method chan args} {
+	switch -- $method blocking {
+	    chan configure $chan -blocking [lindex $args 0]
+	    return
+	} initialize {
+	    return {initialize finalize watch blocking read write
+		    configure cget cgetall}
+	} finalize {
+	    return
+	}
+    }
+    set ch [chan create {read write} foo]
+} -body {
+    list [catch {chan configure $ch -blocking 0} m] $m
+} -cleanup {
+    close $ch
+    rename foo {}
+} -match glob -result {1 {*nested eval*}}
+test iocmd-21.21 {[close] in [read] segfaults} -setup {
+    proc foo {method chan args} {
+	switch -- $method initialize {
+	    return {initialize finalize watch read}
+	} finalize {} watch {} read {
+	    close $chan
+	    return a
+	}
+    }
+    set ch [chan create read foo]
+} -body {
+    read $ch 0
+} -cleanup {
+    close $ch
+    rename foo {}
+} -result {}
+test iocmd-21.22 {[close] in [read] segfaults} -setup {
+    proc foo {method chan args} {
+	switch -- $method initialize {
+	    return {initialize finalize watch read}
+	} finalize {} watch {} read {
+	    catch {close $chan}
+	    return a
+	}
+    }
+    set ch [chan create read foo]
+} -body {
+    read $ch 1
+} -returnCodes error -cleanup {
+    catch {close $ch}
+    rename foo {}
+} -match glob -result {*invalid argument*}
+test iocmd-21.23 {[close] in [gets] segfaults} -setup {
+    proc foo {method chan args} {
+	switch -- $method initialize {
+	    return {initialize finalize watch read}
+	} finalize {} watch {} read {
+	    catch {close $chan}
+	    return \n
+	}
+    }
+    set ch [chan create read foo]
+} -body {
+    gets $ch
+} -cleanup {
+    catch {close $ch}
+    rename foo {}
+} -result {}
+test iocmd-21.24 {[close] in binary [gets] segfaults} -setup {
+    proc foo {method chan args} {
+	switch -- $method initialize {
+	    return {initialize finalize watch read}
+	} finalize {} watch {} read {
+	    catch {close $chan}
+	    return \n
+	}
+    }
+    set ch [chan create read foo]
+} -body {
+    chan configure $ch -translation binary
+    gets $ch
+} -cleanup {
+    catch {close $ch}
+    rename foo {}
+} -result {}
+
+# --- --- --- --------- --------- ---------
+# Helper commands to record the arguments to handler methods.
+
+# Stored in a script so that the threads and interpreters needing this
+# code do not need their own copy but can access this variable.
+
+set helperscript {
+
+proc note  {item}  {global res; lappend res $item; return}
+proc track {}      {upvar args item; note $item; return}
+proc notes {items} {foreach i $items {note $i}}
+# This forces the return options to be in the order that the test expects!
+proc noteOpts opts {global res; lappend res [dict merge {
+    -code !?! -level !?! -errorcode !?! -errorline !?! -errorinfo !?!
+} $opts]; return}
+
+# Helper command, canned result for 'initialize' method.
+# Gets the optional methods as arguments. Use return features
+# to post the result higher up.
+
+proc init {args} {
+    lappend args initialize finalize watch read write
+    return -code return $args
+}
+proc oninit {args} {
+    upvar args hargs
+    if {[lindex $hargs 0] ne "initialize"} {return}
+    lappend args initialize finalize watch read write
+    return -code return $args
+}
+proc onfinal {} {
+    upvar args hargs
+    if {[lindex $hargs 0] ne "finalize"} {return}
+    return -code return ""
+}
+}
+
+# Set everything up in the main thread.
+eval $helperscript
+
+# --- --- --- --------- --------- ---------
+# method finalize
+
+test iocmd-22.1 {chan finalize, handler destruction has no effect on channel} -match glob -body {
+    set res {}
+    proc foo {args} {track; oninit; return}
+    note [set c [chan create {r w} foo]]
+    rename foo {}
+    note [file channels rc*]
+    note [catch {close $c} msg]; note $msg
+    note [file channels rc*]
+    set res
+} -result {{initialize rc* {read write}} rc* rc* 1 {invalid command name "foo"} {}}
+test iocmd-22.2 {chan finalize, for close} -match glob -body {
+    set res {}
+    proc foo {args} {track; oninit; return {}}
+    note [set c [chan create {r w} foo]]
+    close $c
+    # Close deleted the channel.
+    note [file channels rc*]
+    # Channel destruction does not kill handler command!
+    note [info command foo]
+    rename foo {}
+    set res
+} -result {{initialize rc* {read write}} rc* {finalize rc*} {} foo}
+test iocmd-22.3 {chan finalize, for close, error, close error} -match glob -body {
+    set res {}
+    proc foo {args} {track; oninit; return -code error 5}
+    note [set c [chan create {r w} foo]]
+    note [catch {close $c} msg]; note $msg
+    # Channel is gone despite error.
+    note [file channels rc*]
+    rename foo {}
+    set res
+} -result {{initialize rc* {read write}} rc* {finalize rc*} 1 5 {}}
+test iocmd-22.4 {chan finalize, for close, error, close error} -match glob -body {
+    set res {}
+    proc foo {args} {track; oninit; error FOO}
+    note [set c [chan create {r w} foo]]
+    note [catch {close $c} msg]; note $msg; note $::errorInfo
+    rename foo {}
+    set res
+} -result {{initialize rc* {read write}} rc* {finalize rc*} 1 FOO {FOO
+*"close $c"}}
+test iocmd-22.5 {chan finalize, for close, arbitrary result, ignored} -match glob -body {
+    set res {}
+    proc foo {args} {track; oninit; return SOMETHING}
+    note [set c [chan create {r w} foo]]
+    note [catch {close $c} msg]; note $msg
+    rename foo {}
+    set res
+} -result {{initialize rc* {read write}} rc* {finalize rc*} 0 {}}
+test iocmd-22.6 {chan finalize, for close, break, close error} -match glob -body {
+    set res {}
+    proc foo {args} {track; oninit; return -code 3}
+    note [set c [chan create {r w} foo]]
+    note [catch {close $c} msg]; note $msg
+    rename foo {}
+    set res
+} -result {{initialize rc* {read write}} rc* {finalize rc*} 1 *bad code*}
+test iocmd-22.7 {chan finalize, for close, continue, close error} -match glob -body {
+    set res {}
+    proc foo {args} {track; oninit; return -code 4}
+    note [set c [chan create {r w} foo]]
+    note [catch {close $c} msg]; note $msg
+    rename foo {}
+    set res
+} -result {{initialize rc* {read write}} rc* {finalize rc*} 1 *bad code*}
+test iocmd-22.8 {chan finalize, for close, custom code, close error} -match glob -body {
+    set res {}
+    proc foo {args} {track; oninit; return -code 777 BANG}
+    note [set c [chan create {r w} foo]]
+    note [catch {close $c} msg]; note $msg
+    rename foo {}
+    set res
+} -result {{initialize rc* {read write}} rc* {finalize rc*} 1 *bad code*}
+test iocmd-22.9 {chan finalize, for close, ignore level, close error} -match glob -setup {
+    set res {}
+} -body {
+    proc foo {args} {track; oninit; return -level 5 -code 777 BANG}
+    note [set c [chan create {r w} foo]]
+    note [catch {close $c} msg opt]; note $msg; noteOpts $opt
+    return $res
+} -cleanup {
+    rename foo {}
+} -result {{initialize rc* {read write}} rc* {finalize rc*} 1 *bad code* {-code 1 -level 0 -errorcode NONE -errorline 1 -errorinfo *bad code*subcommand "finalize"*}}
+
+# --- === *** ###########################
+# method read
+
+test iocmd-23.1 {chan read, regular data return} -match glob -body {
+    set res {}
+    proc foo {args} {
+	oninit; onfinal; track
+	return snarf
+    }
+    set c [chan create {r w} foo]
+    note [read $c 10]
+    close $c
+    rename foo {}
+    set res
+} -result {{read rc* 4096} {read rc* 4096} snarfsnarf}
+test iocmd-23.2 {chan read, bad data return, to much} -match glob -body {
+    set res {}
+    proc foo {args} {
+	oninit; onfinal; track
+	return [string repeat snarf 1000]
+    }
+    set c [chan create {r w} foo]
+    note [catch {read $c 2} msg]; note $msg
+    close $c
+    rename foo {}
+    set res
+} -result {{read rc* 4096} 1 {read delivered more than requested}}
+test iocmd-23.3 {chan read, for non-readable channel} -match glob -body {
+    set res {}
+    proc foo {args} {
+	oninit; onfinal; track; note MUST_NOT_HAPPEN
+    }
+    set c [chan create {w} foo]
+    note [catch {read $c 2} msg]; note $msg
+    close $c
+    rename foo {}
+    set res
+} -result {1 {channel "rc*" wasn't opened for reading}}
+test iocmd-23.4 {chan read, error return} -match glob -body {
+    set res {}
+    proc foo {args} {
+	oninit; onfinal; track
+	return -code error BOOM!
+    }
+    set c [chan create {r w} foo]
+    note [catch {read $c 2} msg]; note $msg
+    close $c
+    rename foo {}
+    set res
+} -result {{read rc* 4096} 1 BOOM!}
+test iocmd-23.5 {chan read, break return is error} -match glob -body {
+    set res {}
+    proc foo {args} {
+	oninit; onfinal; track
+	return -code break BOOM!
+    }
+    set c [chan create {r w} foo]
+    note [catch {read $c 2} msg]; note $msg
+    close $c
+    rename foo {}
+    set res
+} -result {{read rc* 4096} 1 *bad code*}
+test iocmd-23.6 {chan read, continue return is error} -match glob -body {
+    set res {}
+    proc foo {args} {
+	oninit; onfinal; track
+	return -code continue BOOM!
+    }
+    set c [chan create {r w} foo]
+    note [catch {read $c 2} msg]; note $msg
+    close $c
+    rename foo {}
+    set res
+} -result {{read rc* 4096} 1 *bad code*}
+test iocmd-23.7 {chan read, custom return is error} -match glob -body {
+    set res {}
+    proc foo {args} {
+	oninit; onfinal; track
+	return -code 777 BOOM!
+    }
+    set c [chan create {r w} foo]
+    note [catch {read $c 2} msg]; note $msg
+    close $c
+    rename foo {}
+    set res
+} -result {{read rc* 4096} 1 *bad code*}
+test iocmd-23.8 {chan read, level is squashed} -match glob -body {
+    set res {}
+    proc foo {args} {
+	oninit; onfinal; track
+	return -level 55 -code 777 BOOM!
+    }
+    set c [chan create {r w} foo]
+    note [catch {read $c 2} msg opt]; note $msg; noteOpts $opt
+    close $c
+    rename foo {}
+    set res
+} -result {{read rc* 4096} 1 *bad code* {-code 1 -level 0 -errorcode NONE -errorline 1 -errorinfo *bad code*subcommand "read"*}}
+test iocmd-23.9 {chan read, no data means eof} -match glob -setup {
+    set res {}
+    proc foo {args} {
+	oninit; onfinal; track
+	return ""
+    }
+    set c [chan create {r w} foo]
+} -body {
+    note [read $c 2]
+    note [eof $c]
+    set res
+} -cleanup {
+    close $c
+    rename foo {}
+    unset res
+} -result {{read rc* 4096} {} 1}
+test iocmd-23.10 {chan read, EAGAIN means no data, yet no eof either} -match glob -setup {
+    set res {}
+    proc foo {args} {
+	oninit; onfinal; track
+	error EAGAIN
+    }
+    set c [chan create {r w} foo]
+} -body {
+    note [read $c 2]
+    note [eof $c]
+    set res
+} -cleanup {
+    close $c
+    rename foo {}
+    unset res
+} -result {{read rc* 4096} {} 0}
+test iocmd-23.11 {chan read, close pulls the rug out} -match glob -body {
+    set res {}
+    proc foo {args} {
+	oninit; onfinal; track
+	set args [lassign $args sub id]
+	if {$sub ne "read"} {return}
+	close $id
+	return {}
+    }
+    set c [chan create {r} foo]
+    note [read $c]
+    rename foo {}
+    set res
+} -result {{read rc* 4096} {}}
+
+# --- === *** ###########################
+# method write
+
+test iocmd-24.1 {chan write, regular write} -match glob -body {
+    set res {}
+    proc foo {args} {
+	oninit; onfinal; track
+	set     written [string length [lindex $args 2]]
+	note   $written
+	return $written
+    }
+    set c [chan create {r w} foo]
+    puts -nonewline $c snarf; flush $c
+    close $c
+    rename foo {}
+    set res
+} -result {{write rc* snarf} 5}
+test iocmd-24.2 {chan write, partial write is ok} -match glob -body {
+    set res {}
+    proc foo {args} {
+	oninit; onfinal; track
+	set     written [string length [lindex $args 2]]
+	if {$written > 10} {set written [expr {$written / 2}]}
+	note   $written
+	return $written
+    }
+    set c [chan create {r w} foo]
+    puts -nonewline $c snarfsnarfsnarf; flush $c
+    close $c
+    rename foo {}
+    set res
+} -result {{write rc* snarfsnarfsnarf} 7 {write rc* arfsnarf} 8}
+test iocmd-24.3 {chan write, failed write} -match glob -body {
+    set res {}
+    proc foo {args} {oninit; onfinal; track; note -1; return -1}
+    set c [chan create {r w} foo]
+    puts -nonewline $c snarfsnarfsnarf; flush $c
+    close $c
+    rename foo {}
+    set res
+} -result {{write rc* snarfsnarfsnarf} -1}
+test iocmd-24.4 {chan write, non-writable channel} -match glob -body {
+    set res {}
+    proc foo {args} {oninit; onfinal; track; note MUST_NOT_HAPPEN; return}
+    set c [chan create {r} foo]
+    note [catch {puts -nonewline $c snarfsnarfsnarf; flush $c} msg]; note $msg
+    close $c
+    rename foo {}
+    set res
+} -result {1 {channel "rc*" wasn't opened for writing}}
+test iocmd-24.5 {chan write, bad result, more written than data} -match glob -body {
+    set res {}
+    proc foo {args} {oninit; onfinal; track; return 10000}
+    set c [chan create {r w} foo]
+    note [catch {puts -nonewline $c snarf; flush $c} msg]; note $msg
+    close $c
+    rename foo {}
+    set res
+} -result {{write rc* snarf} 1 {write wrote more than requested}}
+test iocmd-24.6 {chan write, bad result, zero-length write} -match glob -body {
+    set res {}
+    proc foo {args} {oninit; onfinal; track; return 0}
+    set c [chan create {r w} foo]
+    note [catch {puts -nonewline $c snarf; flush $c} msg]; note $msg
+    close $c
+    rename foo {}
+    set res
+} -result {{write rc* snarf} 1 {write wrote nothing}}
+test iocmd-24.7 {chan write, failed write, error return} -match glob -body {
+    set res {}
+    proc foo {args} {oninit; onfinal; track; return -code error BOOM!}
+    set c [chan create {r w} foo]
+    note [catch {puts -nonewline $c snarfsnarfsnarf; flush $c} msg]
+    note $msg
+    close $c
+    rename foo {}
+    set res
+} -result {{write rc* snarfsnarfsnarf} 1 BOOM!}
+test iocmd-24.8 {chan write, failed write, error return} -match glob -body {
+    set res {}
+    proc foo {args} {oninit; onfinal; track; error BOOM!}
+    set c [chan create {r w} foo]
+    notes [catch {puts -nonewline $c snarfsnarfsnarf; flush $c} msg]
+    note $msg
+    close $c
+    rename foo {}
+    set res
+} -result {{write rc* snarfsnarfsnarf} 1 BOOM!}
+test iocmd-24.9 {chan write, failed write, break return is error} -match glob -body {
+    set res {}
+    proc foo {args} {oninit; onfinal; track; return -code break BOOM!}
+    set c [chan create {r w} foo]
+    note [catch {puts -nonewline $c snarfsnarfsnarf; flush $c} msg]
+    note $msg
+    close $c
+    rename foo {}
+    set res
+} -result {{write rc* snarfsnarfsnarf} 1 *bad code*}
+test iocmd-24.10 {chan write, failed write, continue return is error} -match glob -body {
+    set res {}
+    proc foo {args} {oninit; onfinal; track; return -code continue BOOM!}
+    set c [chan create {r w} foo]
+    note [catch {puts -nonewline $c snarfsnarfsnarf; flush $c} msg]
+    note $msg
+    close $c
+    rename foo {}
+    set res
+} -result {{write rc* snarfsnarfsnarf} 1 *bad code*}
+test iocmd-24.11 {chan write, failed write, custom return is error} -match glob -body {
+    set res {}
+    proc foo {args} {oninit; onfinal; track; return -code 777 BOOM!}
+    set c [chan create {r w} foo]
+    note [catch {puts -nonewline $c snarfsnarfsnarf; flush $c} msg]
+    note $msg
+    close $c
+    rename foo {}
+    set res
+} -result {{write rc* snarfsnarfsnarf} 1 *bad code*}
+test iocmd-24.12 {chan write, failed write, non-numeric return is error} -match glob -body {
+    set res {}
+    proc foo {args} {oninit; onfinal; track; return BANG}
+    set c [chan create {r w} foo]
+    note [catch {puts -nonewline $c snarfsnarfsnarf; flush $c} msg]
+    note $msg
+    close $c
+    rename foo {}
+    set res
+} -result {{write rc* snarfsnarfsnarf} 1 {expected integer but got "BANG"}}
+test iocmd-24.13 {chan write, failed write, level is ignored} -match glob -body {
+    set res {}
+    proc foo {args} {oninit; onfinal; track; return -level 55 -code 777 BOOM!}
+    set c [chan create {r w} foo]
+    note [catch {puts -nonewline $c snarfsnarfsnarf; flush $c} msg opt]
+    note $msg
+    noteOpts $opt
+    close $c
+    rename foo {}
+    set res
+} -result {{write rc* snarfsnarfsnarf} 1 *bad code* {-code 1 -level 0 -errorcode NONE -errorline 1 -errorinfo *bad code*subcommand "write"*}}
+test iocmd-24.14 {chan write, no EAGAIN means that writing is allowed at this time, bug 2936225} -match glob -setup {
+    set res {}
+    proc foo {args} {
+	oninit; onfinal; track
+	return 3
+    }
+    set c [chan create {r w} foo]
+} -body {
+    note [puts -nonewline $c ABC ; flush $c]
+    set res
+} -cleanup {
+    close $c
+    rename foo {}
+    unset res
+} -result {{write rc* ABC} {}}
+test iocmd-24.15 {chan write, EAGAIN means that writing is not allowed at this time, bug 2936225} -match glob -setup {
+    set res {}
+    proc foo {args} {
+	oninit; onfinal; track
+	# Note: The EAGAIN signals that the channel cannot accept
+	# write requests right now, this in turn causes the IO core to
+	# request the generation of writable events (see expected
+	# result below, and compare to case 24.14 above).
+	error EAGAIN
+    }
+    set c [chan create {r w} foo]
+} -body {
+    note [puts -nonewline $c ABC ; flush $c]
+    set res
+} -cleanup {
+    close $c
+    rename foo {}
+    unset res
+} -result {{write rc* ABC} {watch rc* write} {}}
+
+# --- === *** ###########################
+# method cgetall
+
+test iocmd-25.1 {chan configure, cgetall, standard options} -match glob -body {
+    set res {}
+    proc foo {args} {oninit; onfinal; track; note MUST_NOT_HAPPEN; return}
+    set c [chan create {r w} foo]
+    note [fconfigure $c]
+    close $c
+    rename foo {}
+    set res
+} -result {{-blocking 1 -buffering full -buffersize 4096 -encoding * -eofchar {{} {}} -translation {auto *}}}
+test iocmd-25.2 {chan configure, cgetall, no options} -match glob -body {
+    set res {}
+    proc foo {args} {oninit cget cgetall; onfinal; track; return ""}
+    set c [chan create {r w} foo]
+    note [fconfigure $c]
+    close $c
+    rename foo {}
+    set res
+} -result {{cgetall rc*} {-blocking 1 -buffering full -buffersize 4096 -encoding * -eofchar {{} {}} -translation {auto *}}}
+test iocmd-25.3 {chan configure, cgetall, regular result} -match glob -body {
+    set res {}
+    proc foo {args} {
+	oninit cget cgetall; onfinal; track
+	return "-bar foo -snarf x"
+    }
+    set c [chan create {r w} foo]
+    note [fconfigure $c]
+    close $c
+    rename foo {}
+    set res
+} -result {{cgetall rc*} {-blocking 1 -buffering full -buffersize 4096 -encoding * -eofchar {{} {}} -translation {auto *} -bar foo -snarf x}}
+test iocmd-25.4 {chan configure, cgetall, bad result, list of uneven length} -match glob -body {
+    set res {}
+    proc foo {args} {
+	oninit cget cgetall; onfinal; track
+	return "-bar"
+    }
+    set c [chan create {r w} foo]
+    note [catch {fconfigure $c} msg]; note $msg
+    close $c
+    rename foo {}
+    set res
+} -result {{cgetall rc*} 1 {Expected list with even number of elements, got 1 element instead}}
+test iocmd-25.5 {chan configure, cgetall, bad result, not a list} -match glob -body {
+    set res {}
+    proc foo {args} {
+	oninit cget cgetall; onfinal; track
+	return "\{"
+    }
+    set c [chan create {r w} foo]
+    note [catch {fconfigure $c} msg]; note $msg
+    close $c
+    rename foo {}
+    set res
+} -result {{cgetall rc*} 1 {unmatched open brace in list}}
+test iocmd-25.6 {chan configure, cgetall, error return} -match glob -body {
+    set res {}
+    proc foo {args} {
+	oninit cget cgetall; onfinal; track
+	return -code error BOOM!
+    }
+    set c [chan create {r w} foo]
+    note [catch {fconfigure $c} msg]; note $msg
+    close $c
+    rename foo {}
+    set res
+} -result {{cgetall rc*} 1 BOOM!}
+test iocmd-25.7 {chan configure, cgetall, break return is error} -match glob -body {
+    set res {}
+    proc foo {args} {
+	oninit cget cgetall; onfinal; track
+	return -code break BOOM!
+    }
+    set c [chan create {r w} foo]
+    note [catch {fconfigure $c} msg]; note $msg
+    close $c
+    rename foo {}
+    set res
+} -result {{cgetall rc*} 1 *bad code*}
+test iocmd-25.8 {chan configure, cgetall, continue return is error} -match glob -body {
+    set res {}
+    proc foo {args} {
+	oninit cget cgetall; onfinal; track
+	return -code continue BOOM!
+    }
+    set c [chan create {r w} foo]
+    note [catch {fconfigure $c} msg]; note $msg
+    close $c
+    rename foo {}
+    set res
+} -result {{cgetall rc*} 1 *bad code*}
+test iocmd-25.9 {chan configure, cgetall, custom return is error} -match glob -body {
+    set res {}
+    proc foo {args} {
+	oninit cget cgetall; onfinal; track
+	return -code 777 BOOM!
+    }
+    set c [chan create {r w} foo]
+    note [catch {fconfigure $c} msg]; note $msg
+    close $c
+    rename foo {}
+    set res
+} -result {{cgetall rc*} 1 *bad code*}
+test iocmd-25.10 {chan configure, cgetall, level is ignored} -match glob -body {
+    set res {}
+    proc foo {args} {
+	oninit cget cgetall; onfinal; track
+	return -level 55 -code 777 BANG
+    }
+    set c [chan create {r w} foo]
+    note [catch {fconfigure $c} msg opt]; note $msg; noteOpts $opt
+    close $c
+    rename foo {}
+    set res
+} -result {{cgetall rc*} 1 *bad code* {-code 1 -level 0 -errorcode NONE -errorline 1 -errorinfo *bad code*subcommand "cgetall"*}}
+
+# --- === *** ###########################
+# method configure
+
+test iocmd-26.1 {chan configure, set standard option} -match glob -body {
+    set res {}
+    proc foo {args} {
+	oninit configure; onfinal; track; note MUST_NOT_HAPPEN; return
+    }
+    set c [chan create {r w} foo]
+    note [fconfigure $c -translation lf]
+    close $c
+    rename foo {}
+    set res
+} -result {{}}
+test iocmd-26.2 {chan configure, set option, error return} -match glob -body {
+    set res {}
+    proc foo {args} {
+	oninit configure; onfinal; track
+	return -code error BOOM!
+    }
+    set c [chan create {r w} foo]
+    note [catch {fconfigure $c -rc-foo bar} msg]; note $msg
+    close $c
+    rename foo {}
+    set res
+} -result {{configure rc* -rc-foo bar} 1 BOOM!}
+test iocmd-26.3 {chan configure, set option, ok return} -match glob -body {
+    set res {}
+    proc foo {args} {oninit configure; onfinal; track; return}
+    set c [chan create {r w} foo]
+    note [fconfigure $c -rc-foo bar]
+    close $c
+    rename foo {}
+    set res
+} -result {{configure rc* -rc-foo bar} {}}
+test iocmd-26.4 {chan configure, set option, break return is error} -match glob -body {
+    set res {}
+    proc foo {args} {
+	oninit configure; onfinal; track
+	return -code break BOOM!
+    }
+    set c [chan create {r w} foo]
+    note [catch {fconfigure $c -rc-foo bar} msg]; note $msg
+    close $c
+    rename foo {}
+    set res
+} -result {{configure rc* -rc-foo bar} 1 *bad code*}
+test iocmd-26.5 {chan configure, set option, continue return is error} -match glob -body {
+    set res {}
+    proc foo {args} {
+	oninit configure; onfinal; track
+	return -code continue BOOM!
+    }
+    set c [chan create {r w} foo]
+    note [catch {fconfigure $c -rc-foo bar} msg]; note $msg
+    close $c
+    rename foo {}
+    set res
+} -result {{configure rc* -rc-foo bar} 1 *bad code*}
+test iocmd-26.6 {chan configure, set option, custom return is error} -match glob -body {
+    set res {}
+    proc foo {args} {
+	oninit configure; onfinal; track
+	return -code 444 BOOM!
+    }
+    set c [chan create {r w} foo]
+    note [catch {fconfigure $c -rc-foo bar} msg]; note $msg
+    close $c
+    rename foo {}
+    set res
+} -result {{configure rc* -rc-foo bar} 1 *bad code*}
+test iocmd-26.7 {chan configure, set option, level is ignored} -match glob -body {
+    set res {}
+    proc foo {args} {
+	oninit configure; onfinal; track
+	return -level 55 -code 444 BANG
+    }
+    set c [chan create {r w} foo]
+    note [catch {fconfigure $c -rc-foo bar} msg opt]; note $msg; noteOpts $opt
+    close $c
+    rename foo {}
+    set res
+} -result {{configure rc* -rc-foo bar} 1 *bad code* {-code 1 -level 0 -errorcode NONE -errorline 1 -errorinfo *bad code*subcommand "configure"*}}
+
+# --- === *** ###########################
+# method cget
+
+test iocmd-27.1 {chan configure, get option, ok return} -match glob -body {
+    set res {}
+    proc foo {args} {oninit cget cgetall; onfinal; track; return foo}
+    set c [chan create {r w} foo]
+    note [fconfigure $c -rc-foo]
+    close $c
+    rename foo {}
+    set res
+} -result {{cget rc* -rc-foo} foo}
+test iocmd-27.2 {chan configure, get option, error return} -match glob -body {
+    set res {}
+    proc foo {args} {
+	oninit cget cgetall; onfinal; track
+	return -code error BOOM!
+    }
+    set c [chan create {r w} foo]
+    note [catch {fconfigure $c -rc-foo} msg]; note $msg
+    close $c
+    rename foo {}
+    set res
+} -result {{cget rc* -rc-foo} 1 BOOM!}
+test iocmd-27.3 {chan configure, get option, break return is error} -match glob -body {
+    set res {}
+    proc foo {args} {
+	oninit cget cgetall; onfinal; track
+	return -code error BOOM!
+    }
+    set c [chan create {r w} foo]
+    note [catch {fconfigure $c -rc-foo} msg]; note $msg
+    close $c
+    rename foo {}
+    set res
+} -result {{cget rc* -rc-foo} 1 BOOM!}
+test iocmd-27.4 {chan configure, get option, continue return is error} -match glob -body {
+    set res {}
+    proc foo {args} {
+	oninit cget cgetall; onfinal; track
+	return -code continue BOOM!
+    }
+    set c [chan create {r w} foo]
+    note [catch {fconfigure $c -rc-foo} msg]; note $msg
+    close $c
+    rename foo {}
+    set res
+} -result {{cget rc* -rc-foo} 1 *bad code*}
+test iocmd-27.5 {chan configure, get option, custom return is error} -match glob -body {
+    set res {}
+    proc foo {args} {
+	oninit cget cgetall; onfinal; track
+	return -code 333 BOOM!
+    }
+    set c [chan create {r w} foo]
+    note [catch {fconfigure $c -rc-foo} msg]; note $msg
+    close $c
+    rename foo {}
+    set res
+} -result {{cget rc* -rc-foo} 1 *bad code*}
+test iocmd-27.6 {chan configure, get option, level is ignored} -match glob -body {
+    set res {}
+    proc foo {args} {
+	oninit cget cgetall; onfinal; track
+	return -level 77 -code 333 BANG
+    }
+    set c [chan create {r w} foo]
+    note [catch {fconfigure $c -rc-foo} msg opt]; note $msg; noteOpts $opt
+    close $c
+    rename foo {}
+    set res
+} -result {{cget rc* -rc-foo} 1 *bad code* {-code 1 -level 0 -errorcode NONE -errorline 1 -errorinfo *bad code*subcommand "cget"*}}
+
+# --- === *** ###########################
+# method seek
+
+test iocmd-28.1 {chan tell, not supported by handler} -match glob -body {
+    set res {}
+    proc foo {args} {oninit; onfinal; track; note MUST_NOT_HAPPEN; return}
+    set c [chan create {r w} foo]
+    note [tell $c]
+    close $c
+    rename foo {}
+    set res
+} -result {-1}
+test iocmd-28.2 {chan tell, error return} -match glob -body {
+    set res {}
+    proc foo {args} {oninit seek; onfinal; track; return -code error BOOM!}
+    set c [chan create {r w} foo]
+    note [catch {tell $c} msg]; note $msg
+    close $c
+    rename foo {}
+    set res
+} -result {{seek rc* 0 current} 1 BOOM!}
+test iocmd-28.3 {chan tell, break return is error} -match glob -body {
+    set res {}
+    proc foo {args} {oninit seek; onfinal; track; return -code break BOOM!}
+    set c [chan create {r w} foo]
+    note [catch {tell $c} msg]; note $msg
+    close $c
+    rename foo {}
+    set res
+} -result {{seek rc* 0 current} 1 *bad code*}
+test iocmd-28.4 {chan tell, continue return is error} -match glob -body {
+    set res {}
+    proc foo {args} {oninit seek; onfinal; track; return -code continue BOOM!}
+    set c [chan create {r w} foo]
+    note [catch {tell $c} msg]; note $msg
+    close $c
+    rename foo {}
+    set res
+} -result {{seek rc* 0 current} 1 *bad code*}
+test iocmd-28.5 {chan tell, custom return is error} -match glob -body {
+    set res {}
+    proc foo {args} {oninit seek; onfinal; track; return -code 222 BOOM!}
+    set c [chan create {r w} foo]
+    note [catch {tell $c} msg]; note $msg
+    close $c
+    rename foo {}
+    set res
+} -result {{seek rc* 0 current} 1 *bad code*}
+test iocmd-28.6 {chan tell, level is ignored} -match glob -body {
+    set res {}
+    proc foo {args} {oninit seek; onfinal; track; return -level 11 -code 222 BANG}
+    set c [chan create {r w} foo]
+    note [catch {tell $c} msg opt]; note $msg; noteOpts $opt
+    close $c
+    rename foo {}
+    set res
+} -result {{seek rc* 0 current} 1 *bad code* {-code 1 -level 0 -errorcode NONE -errorline 1 -errorinfo *bad code*subcommand "seek"*}}
+test iocmd-28.7 {chan tell, regular return} -match glob -body {
+    set res {}
+    proc foo {args} {oninit seek; onfinal; track; return 88}
+    set c [chan create {r w} foo]
+    note [tell $c]
+    close $c
+    rename foo {}
+    set res
+} -result {{seek rc* 0 current} 88}
+test iocmd-28.8 {chan tell, negative return} -match glob -body {
+    set res {}
+    proc foo {args} {oninit seek; onfinal; track; return -1}
+    set c [chan create {r w} foo]
+    note [catch {tell $c} msg]; note $msg
+    close $c
+    rename foo {}
+    set res
+} -result {{seek rc* 0 current} 1 {Tried to seek before origin}}
+test iocmd-28.9 {chan tell, string return} -match glob -body {
+    set res {}
+    proc foo {args} {oninit seek; onfinal; track; return BOGUS}
+    set c [chan create {r w} foo]
+    note [catch {tell $c} msg]; note $msg
+    close $c
+    rename foo {}
+    set res
+} -result {{seek rc* 0 current} 1 {expected integer but got "BOGUS"}}
+test iocmd-28.10 {chan seek, not supported by handler} -match glob -body {
+    set res {}
+    proc foo {args} {oninit; onfinal; track; note MUST_NOT_HAPPEN; return}
+    set c [chan create {r w} foo]
+    note [catch {seek $c 0 start} msg]; note $msg
+    close $c
+    rename foo {}
+    set res
+} -result {1 {error during seek on "rc*": invalid argument}}
+test iocmd-28.11 {chan seek, error return} -match glob -body {
+    set res {}
+    proc foo {args} {oninit seek; onfinal; track; return -code error BOOM!}
+    set c [chan create {r w} foo]
+    note [catch {seek $c 0 start} msg]; note $msg
+    close $c
+    rename foo {}
+    set res
+} -result {{seek rc* 0 start} 1 BOOM!}
+test iocmd-28.12 {chan seek, break return is error} -match glob -body {
+    set res {}
+    proc foo {args} {oninit seek; onfinal; track; return -code break BOOM!}
+    set c [chan create {r w} foo]
+    note [catch {seek $c 0 start} msg]; note $msg
+    close $c
+    rename foo {}
+    set res
+} -result {{seek rc* 0 start} 1 *bad code*}
+test iocmd-28.13 {chan seek, continue return is error} -match glob -body {
+    set res {}
+    proc foo {args} {oninit seek; onfinal; track; return -code continue BOOM!}
+    set c [chan create {r w} foo]
+    note [catch {seek $c 0 start} msg]; note $msg
+    close $c
+    rename foo {}
+    set res
+} -result {{seek rc* 0 start} 1 *bad code*}
+test iocmd-28.14 {chan seek, custom return is error} -match glob -body {
+    set res {}
+    proc foo {args} {oninit seek; onfinal; track; return -code 99 BOOM!}
+    set c [chan create {r w} foo]
+    note [catch {seek $c 0 start} msg]; note $msg
+    close $c
+    rename foo {}
+    set res
+} -result {{seek rc* 0 start} 1 *bad code*}
+test iocmd-28.15 {chan seek, level is ignored} -match glob -body {
+    set res {}
+    proc foo {args} {oninit seek; onfinal; track; return -level 33 -code 99 BANG}
+    set c [chan create {r w} foo]
+    note [catch {seek $c 0 start} msg opt]; note $msg; noteOpts $opt
+    close $c
+    rename foo {}
+    set res
+} -result {{seek rc* 0 start} 1 *bad code* {-code 1 -level 0 -errorcode NONE -errorline 1 -errorinfo *bad code*subcommand "seek"*}}
+test iocmd-28.16 {chan seek, bogus return, negative location} -match glob -body {
+    set res {}
+    proc foo {args} {oninit seek; onfinal; track; return -45}
+    set c [chan create {r w} foo]
+    note [catch {seek $c 0 start} msg]; note $msg
+    close $c
+    rename foo {}
+    set res
+} -result {{seek rc* 0 start} 1 {Tried to seek before origin}}
+test iocmd-28.17 {chan seek, bogus return, string return} -match glob -body {
+    set res {}
+    proc foo {args} {oninit seek; onfinal; track; return BOGUS}
+    set c [chan create {r w} foo]
+    note [catch {seek $c 0 start} msg]; note $msg
+    close $c
+    rename foo {}
+    set res
+} -result {{seek rc* 0 start} 1 {expected integer but got "BOGUS"}}
+test iocmd-28.18 {chan seek, ok result} -match glob -body {
+    set res {}
+    proc foo {args} {oninit seek; onfinal; track; return 23}
+    set c [chan create {r w} foo]
+    note [seek $c 0 current]
+    close $c
+    rename foo {}
+    set res
+} -result {{seek rc* 0 current} {}}
+foreach {testname code} {
+    iocmd-28.19.0 start
+    iocmd-28.19.1 current
+    iocmd-28.19.2 end
+} {
+    test $testname "chan seek, base conversion, $code" -match glob -body {
+	set res {}
+	proc foo {args} {oninit seek; onfinal; track; return 0}
+	set c [chan create {r w} foo]
+	note [seek $c 0 $code]
+	close $c
+	rename foo {}
+	set res
+    } -result [list [list seek rc* 0 $code] {}]
+}
+
+# --- === *** ###########################
+# method blocking
+
+test iocmd-29.1 {chan blocking, no handler support} -match glob -body {
+    set res {}
+    proc foo {args} {oninit; onfinal; track; note MUST_NOT_HAPPEN; return}
+    set c [chan create {r w} foo]
+    note [fconfigure $c -blocking]
+    close $c
+    rename foo {}
+    set res
+} -result {1}
+test iocmd-29.2 {chan blocking, no handler support} -match glob -body {
+    set res {}
+    proc foo {args} {oninit; onfinal; track; note MUST_NOT_HAPPEN; return}
+    set c [chan create {r w} foo]
+    note [fconfigure $c -blocking 0]
+    note [fconfigure $c -blocking]
+    close $c
+    rename foo {}
+    set res
+} -result {{} 0}
+test iocmd-29.3 {chan blocking, retrieval, handler support} -match glob -body {
+    set res {}
+    proc foo {args} {oninit blocking; onfinal; track; note MUST_NOT_HAPPEN; return}
+    set c [chan create {r w} foo]
+    note [fconfigure $c -blocking]
+    close $c
+    rename foo {}
+    set res
+} -result {1}
+test iocmd-29.4 {chan blocking, resetting, handler support} -match glob -body {
+    set res {}
+    proc foo {args} {oninit blocking; onfinal; track; return}
+    set c [chan create {r w} foo]
+    note [fconfigure $c -blocking 0]
+    note [fconfigure $c -blocking]
+    close $c
+    rename foo {}
+    set res
+} -result {{blocking rc* 0} {} 0}
+test iocmd-29.5 {chan blocking, setting, handler support} -match glob -body {
+    set res {}
+    proc foo {args} {oninit blocking; onfinal; track; return}
+    set c [chan create {r w} foo]
+    note [fconfigure $c -blocking 1]
+    note [fconfigure $c -blocking]
+    close $c
+    rename foo {}
+    set res
+} -result {{blocking rc* 1} {} 1}
+test iocmd-29.6 {chan blocking, error return} -match glob -body {
+    set res {}
+    proc foo {args} {oninit blocking; onfinal; track; error BOOM!}
+    set c [chan create {r w} foo]
+    note [catch {fconfigure $c -blocking 0} msg]; note $msg
+    # Catch the close. It changes blocking mode internally, and runs into the error result.
+    catch {close $c}
+    rename foo {}
+    set res
+} -result {{blocking rc* 0} 1 BOOM!}
+test iocmd-29.7 {chan blocking, break return is error} -match glob -body {
+    set res {}
+    proc foo {args} {oninit blocking; onfinal; track; return -code break BOOM!}
+    set c [chan create {r w} foo]
+    note [catch {fconfigure $c -blocking 0} msg]; note $msg
+    catch {close $c}
+    rename foo {}
+    set res
+} -result {{blocking rc* 0} 1 *bad code*}
+test iocmd-29.8 {chan blocking, continue return is error} -match glob -body {
+    set res {}
+    proc foo {args} {oninit blocking; onfinal; track; return -code continue BOOM!}
+    set c [chan create {r w} foo]
+    note [catch {fconfigure $c -blocking 0} msg]; note $msg
+    catch {close $c}
+    rename foo {}
+    set res
+} -result {{blocking rc* 0} 1 *bad code*}
+test iocmd-29.9 {chan blocking, custom return is error} -match glob -body {
+    set res {}
+    proc foo {args} {oninit blocking; onfinal; track; return -code 44 BOOM!}
+    set c [chan create {r w} foo]
+    note [catch {fconfigure $c -blocking 0} msg]; note $msg
+    catch {close $c}
+    rename foo {}
+    set res
+} -result {{blocking rc* 0} 1 *bad code*}
+test iocmd-29.10 {chan blocking, level is ignored} -match glob -setup {
+    set res {}
+} -body {
+    proc foo {args} {oninit blocking; onfinal; track; return -level 99 -code 44 BANG}
+    set c [chan create {r w} foo]
+    note [catch {fconfigure $c -blocking 0} msg opt]; note $msg; noteOpts $opt
+    catch {close $c}
+    return $res
+} -cleanup {
+    rename foo {}
+} -result {{blocking rc* 0} 1 *bad code* {-code 1 -level 0 -errorcode NONE -errorline 1 -errorinfo *bad code*subcommand "blocking"*}}
+test iocmd-29.11 {chan blocking, regular return ok, value ignored} -match glob -body {
+    set res {}
+    proc foo {args} {oninit blocking; onfinal; track; return BOGUS}
+    set c [chan create {r w} foo]
+    note [catch {fconfigure $c -blocking 0} msg]; note $msg
+    catch {close $c}
+    rename foo {}
+    set res
+} -result {{blocking rc* 0} 0 {}}
+
+# --- === *** ###########################
+# method watch
+
+test iocmd-30.1 {chan watch, read interest, some return} -match glob -body {
+    set res {}
+    proc foo {args} {oninit; onfinal; track; return IGNORED}
+    set c [chan create {r w} foo]
+    note [fileevent $c readable {set tick $tick}]
+    close $c			;# 2nd watch, interest zero.
+    rename foo {}
+    set res
+} -result {{watch rc* read} {} {watch rc* {}}}
+test iocmd-30.2 {chan watch, write interest, error return} -match glob -body {
+    set res {}
+    proc foo {args} {oninit; onfinal; track; return -code error BOOM!_IGNORED}
+    set c [chan create {r w} foo]
+    note [fileevent $c writable {set tick $tick}]
+    note [fileevent $c writable {}]
+    close $c
+    rename foo {}
+    set res
+} -result {{watch rc* write} {} {watch rc* {}} {}}
+test iocmd-30.3 {chan watch, accumulated interests} -match glob -body {
+    set res {}
+    proc foo {args} {oninit; onfinal; track; return}
+    set c [chan create {r w} foo]
+    note [fileevent $c writable {set tick $tick}]
+    note [fileevent $c readable {set tick $tick}]
+    note [fileevent $c writable {}]
+    note [fileevent $c readable {}]
+    close $c
+    rename foo {}
+    set res
+} -result {{watch rc* write} {} {watch rc* {read write}} {} {watch rc* read} {} {watch rc* {}} {}}
+test iocmd-30.4 {chan watch, unchanged interest not forwarded} -match glob -body {
+    set res {}
+    proc foo {args} {oninit; onfinal; track; return}
+    set c [chan create {r w} foo]
+    note [fileevent $c writable {set tick $tick}]
+    note [fileevent $c readable {set tick $tick}] ;# Script is changing,
+    note [fileevent $c readable {set tock $tock}] ;# interest does not.
+    close $c		;# 3rd and 4th watch, removing the event handlers.
+    rename foo {}
+    set res
+} -result {{watch rc* write} {} {watch rc* {read write}} {} {} {watch rc* write} {watch rc* {}}}
+
+# --- === *** ###########################
+# chan postevent
+
+test iocmd-31.1 {chan postevent, restricted to reflected channels} -match glob -body {
+    set c [open [makeFile {} goo] r]
+    catch {chan postevent $c {r w}} msg
+    close $c
+    removeFile goo
+    set msg
+} -result {can not find reflected channel named "file*"}
+test iocmd-31.2 {chan postevent, unwanted events} -match glob -body {
+    set res {}
+    proc foo {args} {oninit; onfinal; track; return}
+    set c [chan create {r w} foo]
+    catch {chan postevent $c {r w}} msg; note $msg
+    close $c
+    rename foo {}
+    set res
+} -result {{tried to post events channel "rc*" is not interested in}}
+test iocmd-31.3 {chan postevent, bad input, empty list} -match glob -body {
+    set res {}
+    proc foo {args} {oninit; onfinal; track; return}
+    set c [chan create {r w} foo]
+    catch {chan postevent $c {}} msg; note $msg
+    close $c
+    rename foo {}
+    set res
+} -result {{bad event list: is empty}}
+test iocmd-31.4 {chan postevent, bad input, illlegal keyword} -match glob -body {
+    set res {}
+    proc foo {args} {oninit; onfinal; track; return}
+    set c [chan create {r w} foo]
+    catch {chan postevent $c goo} msg; note $msg
+    close $c
+    rename foo {}
+    set res
+} -result {{bad event "goo": must be read or write}}
+test iocmd-31.5 {chan postevent, bad input, not a list} -match glob -body {
+    set res {}
+    proc foo {args} {oninit; onfinal; track; return}
+    set c [chan create {r w} foo]
+    catch {chan postevent $c "\{"} msg; note $msg
+    close $c
+    rename foo {}
+    set res
+} -result {{unmatched open brace in list}}
+test iocmd-31.6 {chan postevent, posted events do happen} -match glob -body {
+    set res {}
+    proc foo {args} {oninit; onfinal; track; return}
+    set c [chan create {r w} foo]
+    note [fileevent $c readable {note TOCK}]
+    set stop [after 10000 {note TIMEOUT}]
+    after  1000 {note [chan postevent $c r]}
+    vwait ::res
+    catch {after cancel $stop}
+    close $c
+    rename foo {}
+    set res
+} -result {{watch rc* read} {} TOCK {} {watch rc* {}}}
+test iocmd-31.7 {chan postevent, posted events do happen} -match glob -body {
+    set res {}
+    proc foo {args} {oninit; onfinal; track; return}
+    set c [chan create {r w} foo]
+    note [fileevent $c writable {note TOCK}]
+    set stop [after 10000 {note TIMEOUT}]
+    after  1000 {note [chan postevent $c w]}
+    vwait ::res
+    catch {after cancel $stop}
+    close $c
+    rename foo {}
+    set res
+} -result {{watch rc* write} {} TOCK {} {watch rc* {}}}
+test iocmd-31.8 {chan postevent after close throws error} -match glob -setup {
+    proc foo {args} {oninit; onfinal; track; return}
+    proc dummy args { return }
+    set c [chan create {r w} foo]
+    fileevent $c readable dummy
+} -body {
+    close $c
+    chan postevent $c read
+} -cleanup {
+    rename foo   {}
+    rename dummy {}
+} -returnCodes error -result {can not find reflected channel named "rc*"}
+
+# --- === *** ###########################
+# 'Pull the rug' tests. Create channel in a interpreter A, move to
+# other interpreter B, destroy the origin interpreter (A) before or
+# during access from B. Must not crash, must return proper errors.
+
+test iocmd-32.0 {origin interpreter of moved channel gone} -match glob -body {
+
+    set ida [interp create];#puts <<$ida>>
+    set idb [interp create];#puts <<$idb>>
+
+    # Magic to get the test* commands in the slaves
+    load {} Tcltest $ida
+    load {} Tcltest $idb
+
+    # Set up channel in interpreter
+    interp eval $ida $helperscript
+    set chan [interp eval $ida {
+	proc foo {args} {oninit seek; onfinal; track; return}
+	set chan [chan create {r w} foo]
+	fconfigure $chan -buffering none
+	set chan
+    }]
+
+    # Move channel to 2nd interpreter.
+    interp eval $ida [list testchannel cut    $chan]
+    interp eval $idb [list testchannel splice $chan]
+
+    # Kill origin interpreter, then access channel from 2nd interpreter.
+    interp delete $ida
+
+    set     res {}
+    lappend res [catch {interp eval $idb [list puts  $chan shoo]} msg] $msg
+    lappend res [catch {interp eval $idb [list tell  $chan]}      msg] $msg
+    lappend res [catch {interp eval $idb [list seek  $chan 1]}    msg] $msg
+    lappend res [catch {interp eval $idb [list gets  $chan]}      msg] $msg
+    lappend res [catch {interp eval $idb [list close $chan]}      msg] $msg
+    set res
+
+} -constraints {testchannel} \
+    -result {1 {Owner lost} 1 {Owner lost} 1 {Owner lost} 1 {Owner lost} 1 {Owner lost}}
+
+test iocmd-32.1 {origin interpreter of moved channel destroyed during access} -match glob -body {
+
+    set ida [interp create];#puts <<$ida>>
+    set idb [interp create];#puts <<$idb>>
+
+    # Magic to get the test* commands in the slaves
+    load {} Tcltest $ida
+    load {} Tcltest $idb
+
+    # Set up channel in thread
+    set chan [interp eval $ida $helperscript]
+    set chan [interp eval $ida {
+	proc foo {args} {
+	    oninit; onfinal; track;
+	    # destroy interpreter during channel access
+	    suicide
+	}
+	set chan [chan create {r w} foo]
+	fconfigure $chan -buffering none
+	set chan
+    }]
+    interp alias $ida suicide {} interp delete $ida
+
+    # Move channel to 2nd thread.
+    interp eval $ida [list testchannel cut    $chan]
+    interp eval $idb [list testchannel splice $chan]
+
+    # Run access from interpreter B, this will give us a synchronous
+    # response.
+
+    interp eval $idb [list set chan $chan]
+    set res [interp eval $idb {
+	# wait a bit, give the main thread the time to start its event
+	# loop to wait for the response from B
+	after 2000
+	catch { puts $chan shoo } res
+	set res
+    }]
+    set res
+} -constraints {testchannel} -result {Owner lost}
+
+test iocmd-32.2 {delete interp of reflected chan} {
+    # Bug 3034840
+    # Run this test in an interp with memory debugging to panic
+    # on the double free
+    interp create slave
+    slave eval {
+        proc no-op args {}
+        proc driver {sub args} {return {initialize finalize watch read}}
+        chan event [chan create read driver] readable no-op
+    }
+    interp delete slave
+} {}
+
+# ### ### ### ######### ######### #########
+## Same tests as above, but exercising the code forwarding and
+## receiving driver operations to the originator thread.
+
+# -*- tcl -*-
+# ### ### ### ######### ######### #########
+## Testing the reflected channel (Thread forwarding).
+#
+## The id numbers refer to the original test without thread
+## forwarding, and gaps due to tests not applicable to forwarding are
+## left to keep this asociation.
+
+# ### ### ### ######### ######### #########
+## Helper command. Runs a script in a separate thread and returns the
+## result. A channel is transfered into the thread as well, and list of
+## configuation variables
+
+proc inthread {chan script args} {
+    # Test thread.
+
+    set tid [thread::create -preserved]
+    thread::send $tid {load {} Tcltest}
+
+    # Init thread configuration.
+    # - Listed variables
+    # - Id of main thread
+    # - A number of helper commands
+
+    foreach v $args {
+	upvar 1 $v x
+	thread::send $tid [list set $v $x]
+
+    }
+    thread::send $tid [list set mid [thread::id]]
+    thread::send $tid {
+	proc note {item} {global notes; lappend notes $item}
+	proc notes {} {global notes; return $notes}
+	proc noteOpts opts {global notes; lappend notes [dict merge {
+	    -code !?! -level !?! -errorcode !?! -errorline !?! -errorinfo !?!
+	} $opts]}
+    }
+    thread::send $tid [list proc s {} [list uplevel 1 $script]]; # (*)
+
+    # Transfer channel (cut/splice aka detach/attach)
+
+    testchannel cut $chan
+    thread::send $tid [list testchannel splice $chan]
+
+    # Run test script, also run local event loop!
+    # The local event loop waits for the result to come back.
+    # It is also necessary for the execution of forwarded channel
+    # operations.
+
+    set ::tres ""
+    thread::send -async $tid {
+	after 500
+	catch {s} res; # This runs the script, 's' was defined at (*)
+	thread::send -async $mid [list set ::tres $res]
+    }
+    vwait ::tres
+    # Remove test thread, and return the captured result.
+
+    thread::release $tid
+    return $::tres
+}
+
+# ### ### ### ######### ######### #########
+
+# ### ### ### ######### ######### #########
+
+test iocmd.tf-22.2 {chan finalize, for close} -match glob -body {
+    set res {}
+    proc foo {args} {track; oninit; return {}}
+    note [set c [chan create {r w} foo]]
+    note [inthread $c {
+	close $c
+	# Close the deleted the channel.
+	file channels rc*
+    } c]
+    # Channel destruction does not kill handler command!
+    note [info command foo]
+    rename foo {}
+    set res
+} -constraints {testchannel thread} -result {{initialize rc* {read write}} rc* {finalize rc*} {} foo}
+test iocmd.tf-22.3 {chan finalize, for close, error, close error} -match glob -body {
+    set res {}
+    proc foo {args} {track; oninit; return -code error 5}
+    note [set c [chan create {r w} foo]]
+    notes [inthread $c {
+	note [catch {close $c} msg]; note $msg
+	# Channel is gone despite error.
+	note [file channels rc*]
+	notes
+    } c]
+    rename foo {}
+    set res
+} -constraints {testchannel thread} -result {{initialize rc* {read write}} rc* {finalize rc*} 1 5 {}}
+test iocmd.tf-22.4 {chan finalize, for close, error, close errror} -match glob -body {
+    set res {}
+    proc foo {args} {track; oninit; error FOO}
+    note [set c [chan create {r w} foo]]
+    notes [inthread $c {
+	note [catch {close $c} msg]; note $msg
+	notes
+    } c]
+    rename foo {}
+    set res
+} -constraints {testchannel thread} -result {{initialize rc* {read write}} rc* {finalize rc*} 1 FOO}
+test iocmd.tf-22.5 {chan finalize, for close, arbitrary result} -match glob -body {
+    set res {}
+    proc foo {args} {track; oninit; return SOMETHING}
+    note [set c [chan create {r w} foo]]
+    notes [inthread $c {
+	note [catch {close $c} msg]; note $msg
+	notes
+    } c]
+    rename foo {}
+    set res
+} -constraints {testchannel thread} -result {{initialize rc* {read write}} rc* {finalize rc*} 0 {}}
+test iocmd.tf-22.6 {chan finalize, for close, break, close error} -match glob -body {
+    set res {}
+    proc foo {args} {track; oninit; return -code 3}
+    note [set c [chan create {r w} foo]]
+    notes [inthread $c {
+	note [catch {close $c} msg]; note $msg
+	notes
+    } c]
+    rename foo {}
+    set res
+} -result {{initialize rc* {read write}} rc* {finalize rc*} 1 *bad code*} \
+    -constraints {testchannel thread}
+test iocmd.tf-22.7 {chan finalize, for close, continue, close error} -match glob -body {
+    set res {}
+    proc foo {args} {track; oninit; return -code 4}
+    note [set c [chan create {r w} foo]]
+    notes [inthread $c {
+	note [catch {close $c} msg]; note $msg
+	notes
+    } c]
+    rename foo {}
+    set res
+} -result {{initialize rc* {read write}} rc* {finalize rc*} 1 *bad code*} \
+    -constraints {testchannel thread}
+test iocmd.tf-22.8 {chan finalize, for close, custom code, close error} -match glob -body {
+    set res {}
+    proc foo {args} {track; oninit; return -code 777 BANG}
+    note [set c [chan create {r w} foo]]
+    notes [inthread $c {
+	note [catch {close $c} msg]; note $msg
+	notes
+    } c]
+    rename foo {}
+    set res
+} -result {{initialize rc* {read write}} rc* {finalize rc*} 1 *bad code*} \
+    -constraints {testchannel thread}
+test iocmd.tf-22.9 {chan finalize, for close, ignore level, close error} -match glob -body {
+    set res {}
+    proc foo {args} {track; oninit; return -level 5 -code 777 BANG}
+    note [set c [chan create {r w} foo]]
+    notes [inthread $c {
+	note [catch {close $c} msg opt]; note $msg; noteOpts $opt
+	notes
+    } c]
+    rename foo {}
+    set res
+} -result {{initialize rc* {read write}} rc* {finalize rc*} 1 *bad code* {-code 1 -level 0 -errorcode NONE -errorline 1 -errorinfo *bad code*subcommand "finalize"*}} \
+    -constraints {testchannel thread}
+
+# --- === *** ###########################
+# method read
+
+test iocmd.tf-23.1 {chan read, regular data return} -match glob -body {
+    set res {}
+    proc foo {args} {
+	oninit; onfinal; track
+	return snarf
+    }
+    set c [chan create {r w} foo]
+    notes [inthread $c {
+	note [read $c 10]
+	close $c
+	notes
+    } c]
+    rename foo {}
+    set res
+} -constraints {testchannel thread} -result {{read rc* 4096} {read rc* 4096} snarfsnarf}
+test iocmd.tf-23.2 {chan read, bad data return, to much} -match glob -body {
+    set res {}
+    proc foo {args} {
+	oninit; onfinal; track
+	return [string repeat snarf 1000]
+    }
+    set c [chan create {r w} foo]
+    notes [inthread $c {
+	note [catch {[read $c 2]} msg]; note $msg
+	close $c
+	notes
+    } c]
+    rename foo {}
+    set res
+} -constraints {testchannel thread} -result {{read rc* 4096} 1 {read delivered more than requested}}
+test iocmd.tf-23.3 {chan read, for non-readable channel} -match glob -body {
+    set res {}
+    proc foo {args} {
+	oninit; onfinal; track; note MUST_NOT_HAPPEN
+    }
+    set c [chan create {w} foo]
+    notes [inthread $c {
+	note [catch {[read $c 2]} msg]; note $msg
+	close $c
+	notes
+    } c]
+    rename foo {}
+    set res
+} -constraints {testchannel thread} -result {1 {channel "rc*" wasn't opened for reading}}
+test iocmd.tf-23.4 {chan read, error return} -match glob -body {
+    set res {}
+    proc foo {args} {
+	oninit; onfinal; track
+	return -code error BOOM!
+    }
+    set c [chan create {r w} foo]
+    notes [inthread $c {
+	note [catch {read $c 2} msg]; note $msg
+	close $c
+	notes
+    } c]
+    rename foo {}
+    set res
+} -result {{read rc* 4096} 1 BOOM!} \
+    -constraints {testchannel thread}
+test iocmd.tf-23.5 {chan read, break return is error} -match glob -body {
+    set res {}
+    proc foo {args} {
+	oninit; onfinal; track
+	return -code break BOOM!
+    }
+    set c [chan create {r w} foo]
+    notes [inthread $c {
+	note [catch {read $c 2} msg]; note $msg
+	close $c
+	notes
+    } c]
+    rename foo {}
+    set res
+} -result {{read rc* 4096} 1 *bad code*} \
+    -constraints {testchannel thread}
+test iocmd.tf-23.6 {chan read, continue return is error} -match glob -body {
+    set res {}
+    proc foo {args} {
+	oninit; onfinal; track
+	return -code continue BOOM!
+    }
+    set c [chan create {r w} foo]
+    notes [inthread $c {
+	note [catch {read $c 2} msg]; note $msg
+	close $c
+	notes
+    } c]
+    rename foo {}
+    set res
+} -result {{read rc* 4096} 1 *bad code*} \
+    -constraints {testchannel thread}
+test iocmd.tf-23.7 {chan read, custom return is error} -match glob -body {
+    set res {}
+    proc foo {args} {
+	oninit; onfinal; track
+	return -code 777 BOOM!
+    }
+    set c [chan create {r w} foo]
+    notes [inthread $c {
+	note [catch {read $c 2} msg]; note $msg
+	close $c
+	notes
+    } c]
+    rename foo {}
+    set res
+} -result {{read rc* 4096} 1 *bad code*} \
+    -constraints {testchannel thread}
+test iocmd.tf-23.8 {chan read, level is squashed} -match glob -body {
+    set res {}
+    proc foo {args} {
+	oninit; onfinal; track
+	return -level 55 -code 777 BOOM!
+    }
+    set c [chan create {r w} foo]
+    notes [inthread $c {
+	note [catch {read $c 2} msg opt]; note $msg; noteOpts $opt
+	close $c
+	notes
+    } c]
+    rename foo {}
+    set res
+} -result {{read rc* 4096} 1 *bad code* {-code 1 -level 0 -errorcode NONE -errorline 1 -errorinfo *bad code*subcommand "read"*}} \
+    -constraints {testchannel thread}
+test iocmd.tf-23.9 {chan read, no data means eof} -match glob -setup {
+    set res {}
+    proc foo {args} {
+	oninit; onfinal; track
+	return ""
+    }
+    set c [chan create {r w} foo]
+} -body {
+    notes [inthread $c {
+	note [read $c 2]
+	note [eof $c]
+	close $c
+	notes
+    } c]
+    set res
+} -cleanup {
+    rename foo {}
+    unset res
+} -result {{read rc* 4096} {} 1} \
+    -constraints {testchannel thread}
+test iocmd.tf-23.10 {chan read, EAGAIN means no data, yet no eof either} -match glob -setup {
+    set res {}
+    proc foo {args} {
+	oninit; onfinal; track
+	error EAGAIN
+    }
+    set c [chan create {r w} foo]
+} -body {
+    notes [inthread $c {
+	note [read $c 2]
+	note [eof $c]
+	close $c
+	notes
+    } c]
+    set res
+} -cleanup {
+    rename foo {}
+    unset res
+} -result {{read rc* 4096} {} 0} \
+    -constraints {testchannel thread}
+
+# --- === *** ###########################
+# method write
+
+test iocmd.tf-24.1 {chan write, regular write} -match glob -body {
+    set res {}
+    proc foo {args} {
+	oninit; onfinal; track
+	set     written [string length [lindex $args 2]]
+	note   $written
+	return $written
+    }
+    set c [chan create {r w} foo]
+    inthread $c {
+	puts -nonewline $c snarf; flush $c
+	close $c
+    } c
+    rename foo {}
+    set res
+} -constraints {testchannel thread} -result {{write rc* snarf} 5}
+test iocmd.tf-24.2 {chan write, ack partial writes} -match glob -body {
+    set res {}
+    proc foo {args} {
+	oninit; onfinal; track
+	set     written [string length [lindex $args 2]]
+	if {$written > 10} {set written [expr {$written / 2}]}
+	note   $written
+	return $written
+    }
+    set c [chan create {r w} foo]
+    inthread $c {
+	puts -nonewline $c snarfsnarfsnarf; flush $c
+	close $c
+    } c
+    rename foo {}
+    set res
+} -constraints {testchannel thread} -result {{write rc* snarfsnarfsnarf} 7 {write rc* arfsnarf} 8}
+test iocmd.tf-24.3 {chan write, failed write} -match glob -body {
+    set res {}
+    proc foo {args} {oninit; onfinal; track; note -1; return -1}
+    set c [chan create {r w} foo]
+    inthread $c {
+	puts -nonewline $c snarfsnarfsnarf; flush $c
+	close $c
+    } c
+    rename foo {}
+    set res
+} -constraints {testchannel thread} -result {{write rc* snarfsnarfsnarf} -1}
+test iocmd.tf-24.4 {chan write, non-writable channel} -match glob -body {
+    set res {}
+    proc foo {args} {oninit; onfinal; track; note MUST_NOT_HAPPEN; return}
+    set c [chan create {r} foo]
+    notes [inthread $c {
+	note [catch {puts -nonewline $c snarfsnarfsnarf; flush $c} msg]
+	note $msg
+	close $c
+	notes
+    } c]
+    rename foo {}
+    set res
+} -constraints {testchannel thread} -result {1 {channel "rc*" wasn't opened for writing}}
+test iocmd.tf-24.5 {chan write, bad result, more written than data} -match glob -body {
+    set res {}
+    proc foo {args} {oninit; onfinal; track; return 10000}
+    set c [chan create {r w} foo]
+    notes [inthread $c {
+	note [catch {puts -nonewline $c snarf; flush $c} msg]
+	note $msg
+	close $c
+	notes
+    } c]
+    rename foo {}
+    set res
+} -constraints {testchannel thread} -result {{write rc* snarf} 1 {write wrote more than requested}}
+test iocmd.tf-24.6 {chan write, zero writes} -match glob -body {
+    set res {}
+    proc foo {args} {oninit; onfinal; track; return 0}
+    set c [chan create {r w} foo]
+    notes [inthread $c {
+	note [catch {puts -nonewline $c snarf; flush $c} msg]
+	note $msg
+	close $c
+	notes
+    } c]
+    rename foo {}
+    set res
+} -constraints {testchannel thread} -result {{write rc* snarf} 1 {write wrote more than requested}}
+test iocmd.tf-24.7 {chan write, failed write, error return} -match glob -body {
+    set res {}
+    proc foo {args} {oninit; onfinal; track; return -code error BOOM!}
+    set c [chan create {r w} foo]
+    notes [inthread $c {
+	note [catch {puts -nonewline $c snarfsnarfsnarf; flush $c} msg]
+	note $msg
+	close $c
+	notes
+    } c]
+    rename foo {}
+    set res
+} -result {{write rc* snarfsnarfsnarf} 1 BOOM!} \
+    -constraints {testchannel thread}
+test iocmd.tf-24.8 {chan write, failed write, error return} -match glob -body {
+    set res {}
+    proc foo {args} {oninit; onfinal; track; error BOOM!}
+    set c [chan create {r w} foo]
+    notes [inthread $c {
+	note [catch {puts -nonewline $c snarfsnarfsnarf; flush $c} msg]
+	note $msg
+	close $c
+	notes
+    } c]
+    rename foo {}
+    set res
+} -result {{write rc* snarfsnarfsnarf} 1 BOOM!} \
+    -constraints {testchannel thread}
+test iocmd.tf-24.9 {chan write, failed write, break return is error} -match glob -body {
+    set res {}
+    proc foo {args} {oninit; onfinal; track; return -code break BOOM!}
+    set c [chan create {r w} foo]
+    notes [inthread $c {
+	note [catch {puts -nonewline $c snarfsnarfsnarf; flush $c} msg]
+	note $msg
+	close $c
+	notes
+    } c]
+    rename foo {}
+    set res
+} -result {{write rc* snarfsnarfsnarf} 1 *bad code*} \
+    -constraints {testchannel thread}
+test iocmd.tf-24.10 {chan write, failed write, continue return is error} -match glob -body {
+    set res {}
+    proc foo {args} {oninit; onfinal; track; return -code continue BOOM!}
+    set c [chan create {r w} foo]
+    notes [inthread $c {
+	note [catch {puts -nonewline $c snarfsnarfsnarf; flush $c} msg]
+	note $msg
+	close $c
+	notes
+    } c]
+    rename foo {}
+    set res
+} -result {{write rc* snarfsnarfsnarf} 1 *bad code*} \
+    -constraints {testchannel thread}
+test iocmd.tf-24.11 {chan write, failed write, custom return is error} -match glob -body {
+    set res {}
+    proc foo {args} {oninit; onfinal; track; return -code 777 BOOM!}
+    set c [chan create {r w} foo]
+    notes [inthread $c {
+	note [catch {puts -nonewline $c snarfsnarfsnarf; flush $c} msg]
+	note $msg
+	close $c
+	notes
+    } c]
+    rename foo {}
+    set res
+} -result {{write rc* snarfsnarfsnarf} 1 *bad code*} \
+    -constraints {testchannel thread}
+test iocmd.tf-24.12 {chan write, failed write, non-numeric return is error} -match glob -body {
+    set res {}
+    proc foo {args} {oninit; onfinal; track; return BANG}
+    set c [chan create {r w} foo]
+    notes [inthread $c {
+	note [catch {puts -nonewline $c snarfsnarfsnarf; flush $c} msg]
+	note $msg
+	close $c
+	notes
+    } c]
+    rename foo {}
+    set res
+} -result {{write rc* snarfsnarfsnarf} 1 {expected integer but got "BANG"}} \
+    -constraints {testchannel thread}
+test iocmd.tf-24.13 {chan write, failed write, level is ignored} -match glob -body {
+    set res {}
+    proc foo {args} {oninit; onfinal; track; return -level 55 -code 777 BOOM!}
+    set c [chan create {r w} foo]
+    notes [inthread $c {
+	note [catch {puts -nonewline $c snarfsnarfsnarf; flush $c} msg opt]
+	note $msg
+	noteOpts $opt
+	close $c
+	notes
+    } c]
+    rename foo {}
+    set res
+} -result {{write rc* snarfsnarfsnarf} 1 *bad code* {-code 1 -level 0 -errorcode NONE -errorline 1 -errorinfo *bad code*subcommand "write"*}} \
+    -constraints {testchannel thread}
+test iocmd.tf-24.14 {chan write, no EAGAIN means that writing is allowed at this time, bug 2936225} -match glob -setup {
+    set res {}
+    proc foo {args} {
+	oninit; onfinal; track
+	return 3
+    }
+    set c [chan create {r w} foo]
+} -body {
+    notes [inthread $c {
+	note [puts -nonewline $c ABC ; flush $c]
+	close $c
+	notes
+    } c]
+    set res
+} -cleanup {
+    rename foo {}
+    unset res
+} -result {{write rc* ABC} {}} \
+    -constraints {testchannel thread}
+test iocmd.tf-24.15 {chan write, EAGAIN means that writing is not allowed at this time, bug 2936225} -match glob -setup {
+    set res {}
+    proc foo {args} {
+	oninit; onfinal; track
+	# Note: The EAGAIN signals that the channel cannot accept
+	# write requests right now, this in turn causes the IO core to
+	# request the generation of writable events (see expected
+	# result below, and compare to case 24.14 above).
+	error EAGAIN
+    }
+    set c [chan create {r w} foo]
+} -body {
+    notes [inthread $c {
+	note [puts -nonewline $c ABC ; flush $c]
+	close $c
+	notes
+    } c]
+    set res
+} -cleanup {
+    proc foo {args} {onfinal; set ::done-24.15 1; return 3}
+    after 1000 {set ::done-24.15 2}
+    vwait done-24.15
+    rename foo {}
+    unset res
+} -result {{write rc* ABC} {watch rc* write} {}} \
+    -constraints {testchannel thread}
+
+test iocmd.tf-24.16 {chan write, note the background flush setup by close due to the EAGAIN leaving data in buffers.} -match glob -setup {
+    set res {}
+    proc foo {args} {
+	oninit; onfinal; track
+	# Note: The EAGAIN signals that the channel cannot accept
+	# write requests right now, this in turn causes the IO core to
+	# request the generation of writable events (see expected
+	# result below, and compare to case 24.14 above).
+	error EAGAIN
+    }
+    set c [chan create {r w} foo]
+} -body {
+    notes [inthread $c {
+	note [puts -nonewline $c ABC ; flush $c]
+	close $c
+	notes
+    } c]
+    # Replace handler with all-tracking one which doesn't error.
+    # This will tell us if a write-due-flush is there.
+    proc foo {args} { onfinal; note BG ; track ; set ::endbody-24.16 1}
+    # Flush (sic!) the event-queue to capture the write from a
+    # BG-flush.
+    after 1000 {set ::endbody-24.16 2}
+    vwait endbody-24.16
+    set res
+} -cleanup {
+    proc foo {args} {onfinal; set ::done-24.16 1; return 3}
+    after 1000 {set ::done-24.16 2}
+    vwait done-24.16
+    rename foo {}
+    unset res
+} -result {{write rc* ABC} {watch rc* write} {} BG {write rc* ABC}} \
+    -constraints {testchannel thread}
+
+test iocmd.tf-24.17.bug3522560 {postevent for transfered channel} \
+    -constraints {testchannel thread} -setup {
+    # This test exposes how the execution of postevent in the handler thread causes
+    # a crash if we are not properly injecting the events into the owning thread instead.
+    # With the injection the test will simply complete without crash.
+
+    set beat 10000
+    set drive 999
+    set data ...---...
+
+    proc LOG {text} {
+	#puts stderr "[thread::id]: $text"
+	return
+    }
+
+    proc POST {hi} {
+	LOG "-> [info level 0]"
+	chan postevent $hi read
+	LOG "<- [info level 0]"
+
+	set ::timer [after $::drive [info level 0]]
+	return
+    }
+
+    proc HANDLER {op ch args} {
+	lappend ::res [lrange [info level 0] 1 end]
+	LOG "-> [info level 0]"
+	set ret {}
+	switch -glob -- $op {
+	    init* {set ret {initialize finalize watch read}}
+	    watch {
+		set l [lindex $args 0]
+		catch {after cancel $::timer}
+		if {[llength $l]} {
+		    set ::timer [after $::drive [list POST $ch]]
+		}
+	    }
+	    finalize {
+		catch { after cancel $::timer }
+		after 500 {set ::forever now}
+	    }
+	    read {
+		set ret $::data
+		set ::data {} ; # Next is EOF.
+	    }
+	}
+	LOG "<- [info level 0] : $ret"
+	return $ret
+    }
+} -body {
+    LOG BEGIN
+    set ch [chan create {read} HANDLER]
+
+    set tid [thread::create {
+	proc LOG {text} {
+	    #puts stderr "\t\t\t\t\t\t[thread::id]: $text"
+	    return
+	}
+	LOG THREAD-STARTED
+	load {} Tcltest
+	proc bgerror s {
+	    LOG BGERROR:$s
+	}
+	vwait forever
+	LOG THREAD-DONE
+    }]
+
+    testchannel cut $ch
+    thread::send $tid [list set thech $ch]
+    thread::send $tid [list set beat $beat]
+    thread::send -async $tid {
+	LOG SPLICE-BEG
+	testchannel splice $thech
+	LOG SPLICE-END
+	proc PROCESS {ch} {
+	    LOG "-> [info level 0]"
+	    if {[eof $ch]} {
+		close $ch
+		set ::done 1
+		set c <<EOF>>
+	    } else {
+		set c [read $ch 1]
+	    }
+	    LOG "GOTCHAR: $c"
+	    LOG "<- [info level 0]"
+	}
+	LOG THREAD-FILEEVENT
+	fconfigure $thech -translation binary -blocking 0
+	fileevent  $thech readable [list PROCESS $thech]
+	LOG THREAD-NOEVENT-LOOP
+	set done 0
+	while {!$done} {
+	    after $beat
+	    LOG THREAD-HEARTBEAT
+	    update
+	}
+	LOG THREAD-LOOP-DONE
+	#thread::exit
+	# Thread exits cause leaks;  Use clean thread shutdown
+	set forever yourGirl
+    }
+
+    LOG MAIN_WAITING
+    vwait forever
+    LOG MAIN_DONE
+
+    set res
+} -cleanup {
+    after cancel $::timer
+    rename LOG {}
+    rename POST {}
+    rename HANDLER {}
+    unset beat drive data forever res tid ch timer
+} -match glob \
+    -result {{initialize rc* read} {watch rc* read} {read rc* 4096} {watch rc* {}} {watch rc* read} {read rc* 4096} {watch rc* {}} {finalize rc*}}
+
+# --- === *** ###########################
+# method cgetall
+
+test iocmd.tf-25.1 {chan configure, cgetall, standard options} -match glob -body {
+    set res {}
+    proc foo {args} {oninit; onfinal; track; note MUST_NOT_HAPPEN; return}
+    set c [chan create {r w} foo]
+    notes [inthread $c {
+	note [fconfigure $c]
+	close $c
+	notes
+    } c]
+    rename foo {}
+    set res
+} -constraints {testchannel thread} \
+    -result {{-blocking 1 -buffering full -buffersize 4096 -encoding * -eofchar {{} {}} -translation {auto *}}}
+test iocmd.tf-25.2 {chan configure, cgetall, no options} -match glob -body {
+    set res {}
+    proc foo {args} {oninit cget cgetall; onfinal; track; return ""}
+    set c [chan create {r w} foo]
+    notes [inthread $c {
+	note [fconfigure $c]
+	close $c
+	notes
+    } c]
+    rename foo {}
+    set res
+} -constraints {testchannel thread} \
+    -result {{cgetall rc*} {-blocking 1 -buffering full -buffersize 4096 -encoding * -eofchar {{} {}} -translation {auto *}}}
+test iocmd.tf-25.3 {chan configure, cgetall, regular result} -match glob -body {
+    set res {}
+    proc foo {args} {
+	oninit cget cgetall; onfinal; track
+	return "-bar foo -snarf x"
+    }
+    set c [chan create {r w} foo]
+    notes [inthread $c {
+	note [fconfigure $c]
+	close $c
+	notes
+    } c]
+    rename foo {}
+    set res
+} -constraints {testchannel thread} \
+    -result {{cgetall rc*} {-blocking 1 -buffering full -buffersize 4096 -encoding * -eofchar {{} {}} -translation {auto *} -bar foo -snarf x}}
+test iocmd.tf-25.4 {chan configure, cgetall, bad result, list of uneven length} -match glob -body {
+    set res {}
+    proc foo {args} {
+	oninit cget cgetall; onfinal; track
+	return "-bar"
+    }
+    set c [chan create {r w} foo]
+    notes [inthread $c {
+	note [catch {fconfigure $c} msg]
+	note $msg
+	close $c
+	notes
+    } c]
+    rename foo {}
+    set res
+} -constraints {testchannel thread} -result {{cgetall rc*} 1 {Expected list with even number of elements, got 1 element instead}}
+test iocmd.tf-25.5 {chan configure, cgetall, bad result, not a list} -match glob -body {
+    set res {}
+    proc foo {args} {
+	oninit cget cgetall; onfinal; track
+	return "\{"
+    }
+    set c [chan create {r w} foo]
+    notes [inthread $c {
+	note [catch {fconfigure $c} msg]
+	note $msg
+	close $c
+	notes
+    } c]
+    rename foo {}
+    set res
+} -constraints {testchannel thread} -result {{cgetall rc*} 1 {unmatched open brace in list}}
+test iocmd.tf-25.6 {chan configure, cgetall, error return} -match glob -body {
+    set res {}
+    proc foo {args} {
+	oninit cget cgetall; onfinal; track
+	return -code error BOOM!
+    }
+    set c [chan create {r w} foo]
+    notes [inthread $c {
+	note [catch {fconfigure $c} msg]
+	note $msg
+	close $c
+	notes
+    } c]
+    rename foo {}
+    set res
+} -constraints {testchannel thread} -result {{cgetall rc*} 1 BOOM!}
+test iocmd.tf-25.7 {chan configure, cgetall, break return is error} -match glob -body {
+    set res {}
+    proc foo {args} {
+	oninit cget cgetall; onfinal; track
+	return -code break BOOM!
+    }
+    set c [chan create {r w} foo]
+    notes [inthread $c {
+	note [catch {fconfigure $c} msg]
+	note $msg
+	close $c
+	notes
+    } c]
+    rename foo {}
+    set res
+} -result {{cgetall rc*} 1 *bad code*} \
+    -constraints {testchannel thread}
+test iocmd.tf-25.8 {chan configure, cgetall, continue return is error} -match glob -body {
+    set res {}
+    proc foo {args} {
+	oninit cget cgetall; onfinal; track
+	return -code continue BOOM!
+    }
+    set c [chan create {r w} foo]
+    notes [inthread $c {
+	note [catch {fconfigure $c} msg]
+	note $msg
+	close $c
+	notes
+    } c]
+    rename foo {}
+    set res
+} -result {{cgetall rc*} 1 *bad code*} \
+    -constraints {testchannel thread}
+test iocmd.tf-25.9 {chan configure, cgetall, custom return is error} -match glob -body {
+    set res {}
+    proc foo {args} {
+	oninit cget cgetall; onfinal; track
+	return -code 777 BOOM!
+    }
+    set c [chan create {r w} foo]
+    notes [inthread $c {
+	note [catch {fconfigure $c} msg]
+	note $msg
+	close $c
+	notes
+    } c]
+    rename foo {}
+    set res
+} -result {{cgetall rc*} 1 *bad code*} \
+    -constraints {testchannel thread}
+test iocmd.tf-25.10 {chan configure, cgetall, level is ignored} -match glob -body {
+    set res {}
+    proc foo {args} {
+	oninit cget cgetall; onfinal; track
+	return -level 55 -code 777 BANG
+    }
+    set c [chan create {r w} foo]
+    notes [inthread $c {
+	note [catch {fconfigure $c} msg opt]
+	note $msg
+	noteOpts $opt
+	close $c
+	notes
+    } c]
+    rename foo {}
+    set res
+} -result {{cgetall rc*} 1 *bad code* {-code 1 -level 0 -errorcode NONE -errorline 1 -errorinfo *bad code*subcommand "cgetall"*}} \
+    -constraints {testchannel thread}
+
+# --- === *** ###########################
+# method configure
+
+test iocmd.tf-26.1 {chan configure, set standard option} -match glob -body {
+    set res {}
+    proc foo {args} {
+	oninit configure; onfinal; track; note MUST_NOT_HAPPEN; return
+    }
+    set c [chan create {r w} foo]
+    notes [inthread $c {
+	note [fconfigure $c -translation lf]
+	close $c
+	notes
+    } c]
+    rename foo {}
+    set res
+} -constraints {testchannel thread} -result {{}}
+test iocmd.tf-26.2 {chan configure, set option, error return} -match glob -body {
+    set res {}
+    proc foo {args} {
+	oninit configure; onfinal; track
+	return -code error BOOM!
+    }
+    set c [chan create {r w} foo]
+    notes [inthread $c {
+	note [catch {fconfigure $c -rc-foo bar} msg]
+	note $msg
+	close $c
+	notes
+    } c]
+    rename foo {}
+    set res
+} -constraints {testchannel thread} -result {{configure rc* -rc-foo bar} 1 BOOM!}
+test iocmd.tf-26.3 {chan configure, set option, ok return} -match glob -body {
+    set res {}
+    proc foo {args} {oninit configure; onfinal; track; return}
+    set c [chan create {r w} foo]
+    notes [inthread $c {
+	note [fconfigure $c -rc-foo bar]
+	close $c
+	notes
+    } c]
+    rename foo {}
+    set res
+} -constraints {testchannel thread} -result {{configure rc* -rc-foo bar} {}}
+test iocmd.tf-26.4 {chan configure, set option, break return is error} -match glob -body {
+    set res {}
+    proc foo {args} {
+	oninit configure; onfinal; track
+	return -code break BOOM!
+    }
+    set c [chan create {r w} foo]
+    notes [inthread $c {
+	note [catch {fconfigure $c -rc-foo bar} msg]
+	note $msg
+	close $c
+	notes
+    } c]
+    rename foo {}
+    set res
+} -result {{configure rc* -rc-foo bar} 1 *bad code*} \
+    -constraints {testchannel thread}
+test iocmd.tf-26.5 {chan configure, set option, continue return is error} -match glob -body {
+    set res {}
+    proc foo {args} {
+	oninit configure; onfinal; track
+	return -code continue BOOM!
+    }
+    set c [chan create {r w} foo]
+    notes [inthread $c {
+	note [catch {fconfigure $c -rc-foo bar} msg]
+	note $msg
+	close $c
+	notes
+    } c]
+    rename foo {}
+    set res
+} -result {{configure rc* -rc-foo bar} 1 *bad code*} \
+    -constraints {testchannel thread}
+test iocmd.tf-26.6 {chan configure, set option, custom return is error} -match glob -body {
+    set res {}
+    proc foo {args} {
+	oninit configure; onfinal; track
+	return -code 444 BOOM!
+    }
+    set c [chan create {r w} foo]
+    notes [inthread $c {
+	note [catch {fconfigure $c -rc-foo bar} msg]
+	note $msg
+	close $c
+	notes
+    } c]
+    rename foo {}
+    set res
+} -result {{configure rc* -rc-foo bar} 1 *bad code*} \
+    -constraints {testchannel thread}
+test iocmd.tf-26.7 {chan configure, set option, level is ignored} -match glob -body {
+    set res {}
+    proc foo {args} {
+	oninit configure; onfinal; track
+	return -level 55 -code 444 BANG
+    }
+    set c [chan create {r w} foo]
+    notes [inthread $c {
+	note [catch {fconfigure $c -rc-foo bar} msg opt]
+	note $msg
+	noteOpts $opt
+	close $c
+	notes
+    } c]
+    rename foo {}
+    set res
+} -result {{configure rc* -rc-foo bar} 1 *bad code* {-code 1 -level 0 -errorcode NONE -errorline 1 -errorinfo *bad code*subcommand "configure"*}} \
+    -constraints {testchannel thread}
+
+# --- === *** ###########################
+# method cget
+
+test iocmd.tf-27.1 {chan configure, get option, ok return} -match glob -body {
+    set res {}
+    proc foo {args} {oninit cget cgetall; onfinal; track; return foo}
+    set c [chan create {r w} foo]
+    notes [inthread $c {
+	note [fconfigure $c -rc-foo]
+	close $c
+	notes
+    } c]
+    rename foo {}
+    set res
+} -constraints {testchannel thread} -result {{cget rc* -rc-foo} foo}
+test iocmd.tf-27.2 {chan configure, get option, error return} -match glob -body {
+    set res {}
+    proc foo {args} {
+	oninit cget cgetall; onfinal; track
+	return -code error BOOM!
+    }
+    set c [chan create {r w} foo]
+    notes [inthread $c {
+	note [catch {fconfigure $c -rc-foo} msg]
+	note $msg
+	close $c
+	notes
+    } c]
+    rename foo {}
+    set res
+} -constraints {testchannel thread} -result {{cget rc* -rc-foo} 1 BOOM!}
+test iocmd.tf-27.3 {chan configure, get option, break return is error} -match glob -body {
+    set res {}
+    proc foo {args} {
+	oninit cget cgetall; onfinal; track
+	return -code error BOOM!
+    }
+    set c [chan create {r w} foo]
+    notes [inthread $c {
+	note [catch {fconfigure $c -rc-foo} msg]
+	note $msg
+	close $c
+	notes
+    } c]
+    rename foo {}
+    set res
+} -result {{cget rc* -rc-foo} 1 BOOM!} \
+    -constraints {testchannel thread}
+test iocmd.tf-27.4 {chan configure, get option, continue return is error} -match glob -body {
+    set res {}
+    proc foo {args} {
+	oninit cget cgetall; onfinal; track
+	return -code continue BOOM!
+    }
+    set c [chan create {r w} foo]
+    notes [inthread $c {
+	note [catch {fconfigure $c -rc-foo} msg]
+	note $msg
+	close $c
+	notes
+    } c]
+    rename foo {}
+    set res
+} -result {{cget rc* -rc-foo} 1 *bad code*} \
+    -constraints {testchannel thread}
+test iocmd.tf-27.5 {chan configure, get option, custom return is error} -match glob -body {
+    set res {}
+    proc foo {args} {
+	oninit cget cgetall; onfinal; track
+	return -code 333 BOOM!
+    }
+    set c [chan create {r w} foo]
+    notes [inthread $c {
+	note [catch {fconfigure $c -rc-foo} msg]
+	note $msg
+	close $c
+	notes
+    } c]
+    rename foo {}
+    set res
+} -result {{cget rc* -rc-foo} 1 *bad code*} \
+    -constraints {testchannel thread}
+test iocmd.tf-27.6 {chan configure, get option, level is ignored} -match glob -body {
+    set res {}
+    proc foo {args} {
+	oninit cget cgetall; onfinal; track
+	return -level 77 -code 333 BANG
+    }
+    set c [chan create {r w} foo]
+    notes [inthread $c {
+	note [catch {fconfigure $c -rc-foo} msg opt]
+	note $msg
+	noteOpts $opt
+	close $c
+	notes
+    } c]
+    rename foo {}
+    set res
+} -result {{cget rc* -rc-foo} 1 *bad code* {-code 1 -level 0 -errorcode NONE -errorline 1 -errorinfo *bad code*subcommand "cget"*}} \
+    -constraints {testchannel thread}
+
+# --- === *** ###########################
+# method seek
+
+test iocmd.tf-28.1 {chan tell, not supported by handler} -match glob -body {
+    set res {}
+    proc foo {args} {oninit; onfinal; track; note MUST_NOT_HAPPEN; return}
+    set c [chan create {r w} foo]
+    notes [inthread $c {
+	note [tell $c]
+	close $c
+	notes
+    } c]
+    rename foo {}
+    set res
+} -result {-1} \
+    -constraints {testchannel thread}
+test iocmd.tf-28.2 {chan tell, error return} -match glob -body {
+    set res {}
+    proc foo {args} {oninit seek; onfinal; track; return -code error BOOM!}
+    set c [chan create {r w} foo]
+    notes [inthread $c {
+	note [catch {tell $c} msg]
+	note $msg
+	close $c
+	notes
+    } c]
+    rename foo {}
+    set res
+} -result {{seek rc* 0 current} 1 BOOM!} \
+    -constraints {testchannel thread}
+test iocmd.tf-28.3 {chan tell, break return is error} -match glob -body {
+    set res {}
+    proc foo {args} {oninit seek; onfinal; track; return -code break BOOM!}
+    set c [chan create {r w} foo]
+    notes [inthread $c {
+	note [catch {tell $c} msg]
+	note $msg
+	close $c
+	notes
+    } c]
+    rename foo {}
+    set res
+} -result {{seek rc* 0 current} 1 *bad code*} \
+    -constraints {testchannel thread}
+test iocmd.tf-28.4 {chan tell, continue return is error} -match glob -body {
+    set res {}
+    proc foo {args} {oninit seek; onfinal; track; return -code continue BOOM!}
+    set c [chan create {r w} foo]
+    notes [inthread $c {
+	note [catch {tell $c} msg]
+	note $msg
+	close $c
+	notes
+    } c]
+    rename foo {}
+    set res
+} -result {{seek rc* 0 current} 1 *bad code*} \
+    -constraints {testchannel thread}
+test iocmd.tf-28.5 {chan tell, custom return is error} -match glob -body {
+    set res {}
+    proc foo {args} {oninit seek; onfinal; track; return -code 222 BOOM!}
+    set c [chan create {r w} foo]
+    notes [inthread $c {
+	note [catch {tell $c} msg]
+	note $msg
+	close $c
+	notes
+    } c]
+    rename foo {}
+    set res
+} -result {{seek rc* 0 current} 1 *bad code*} \
+    -constraints {testchannel thread}
+test iocmd.tf-28.6 {chan tell, level is ignored} -match glob -body {
+    set res {}
+    proc foo {args} {oninit seek; onfinal; track; return -level 11 -code 222 BANG}
+    set c [chan create {r w} foo]
+    notes [inthread $c {
+	note [catch {tell $c} msg opt]
+	note $msg
+	noteOpts $opt
+	close $c
+	notes
+    } c]
+    rename foo {}
+    set res
+} -result {{seek rc* 0 current} 1 *bad code* {-code 1 -level 0 -errorcode NONE -errorline 1 -errorinfo *bad code*subcommand "seek"*}} \
+    -constraints {testchannel thread}
+test iocmd.tf-28.7 {chan tell, regular return} -match glob -body {
+    set res {}
+    proc foo {args} {oninit seek; onfinal; track; return 88}
+    set c [chan create {r w} foo]
+    notes [inthread $c {
+	note [tell $c]
+	close $c
+	notes
+    } c]
+    rename foo {}
+    set res
+} -result {{seek rc* 0 current} 88} \
+    -constraints {testchannel thread}
+test iocmd.tf-28.8 {chan tell, negative return} -match glob -body {
+    set res {}
+    proc foo {args} {oninit seek; onfinal; track; return -1}
+    set c [chan create {r w} foo]
+    notes [inthread $c {
+	note [catch {tell $c} msg]
+	note $msg
+	close $c
+	notes
+    } c]
+    rename foo {}
+    set res
+} -result {{seek rc* 0 current} 1 {Tried to seek before origin}} \
+    -constraints {testchannel thread}
+test iocmd.tf-28.9 {chan tell, string return} -match glob -body {
+    set res {}
+    proc foo {args} {oninit seek; onfinal; track; return BOGUS}
+    set c [chan create {r w} foo]
+    notes [inthread $c {
+	note [catch {tell $c} msg]
+	note $msg
+	close $c
+	notes
+    } c]
+    rename foo {}
+    set res
+} -result {{seek rc* 0 current} 1 {expected integer but got "BOGUS"}} \
+    -constraints {testchannel thread}
+test iocmd.tf-28.10 {chan seek, not supported by handler} -match glob -body {
+    set res {}
+    proc foo {args} {oninit; onfinal; track; note MUST_NOT_HAPPEN; return}
+    set c [chan create {r w} foo]
+    notes [inthread $c {
+	note [catch {seek $c 0 start} msg]
+	note $msg
+	close $c
+	notes
+    } c]
+    rename foo {}
+    set res
+} -result {1 {error during seek on "rc*": invalid argument}} \
+    -constraints {testchannel thread}
+test iocmd.tf-28.11 {chan seek, error return} -match glob -body {
+    set res {}
+    proc foo {args} {oninit seek; onfinal; track; return -code error BOOM!}
+    set c [chan create {r w} foo]
+    notes [inthread $c {
+	note [catch {seek $c 0 start} msg]
+	note $msg
+	close $c
+	notes
+    } c]
+    rename foo {}
+    set res
+} -result {{seek rc* 0 start} 1 BOOM!} \
+    -constraints {testchannel thread}
+test iocmd.tf-28.12 {chan seek, break return is error} -match glob -body {
+    set res {}
+    proc foo {args} {oninit seek; onfinal; track; return -code break BOOM!}
+    set c [chan create {r w} foo]
+    notes [inthread $c {
+	note [catch {seek $c 0 start} msg]
+	note $msg
+	close $c
+	notes
+    } c]
+    rename foo {}
+    set res
+} -result {{seek rc* 0 start} 1 *bad code*} \
+    -constraints {testchannel thread}
+test iocmd.tf-28.13 {chan seek, continue return is error} -match glob -body {
+    set res {}
+    proc foo {args} {oninit seek; onfinal; track; return -code continue BOOM!}
+    set c [chan create {r w} foo]
+    notes [inthread $c {
+	note [catch {seek $c 0 start} msg]
+	note $msg
+	close $c
+	notes
+    } c]
+    rename foo {}
+    set res
+} -result {{seek rc* 0 start} 1 *bad code*} \
+    -constraints {testchannel thread}
+test iocmd.tf-28.14 {chan seek, custom return is error} -match glob -body {
+    set res {}
+    proc foo {args} {oninit seek; onfinal; track; return -code 99 BOOM!}
+    set c [chan create {r w} foo]
+    notes [inthread $c {
+	note [catch {seek $c 0 start} msg]
+	note $msg
+	close $c
+	notes
+    } c]
+    rename foo {}
+    set res
+} -result {{seek rc* 0 start} 1 *bad code*} \
+    -constraints {testchannel thread}
+test iocmd.tf-28.15 {chan seek, level is ignored} -match glob -body {
+    set res {}
+    proc foo {args} {oninit seek; onfinal; track; return -level 33 -code 99 BANG}
+    set c [chan create {r w} foo]
+    notes [inthread $c {
+	note [catch {seek $c 0 start} msg opt]
+	note $msg
+	noteOpts $opt
+	close $c
+	notes
+    } c]
+    rename foo {}
+    set res
+} -result {{seek rc* 0 start} 1 *bad code* {-code 1 -level 0 -errorcode NONE -errorline 1 -errorinfo *bad code*subcommand "seek"*}} \
+    -constraints {testchannel thread}
+test iocmd.tf-28.16 {chan seek, bogus return, negative location} -match glob -body {
+    set res {}
+    proc foo {args} {oninit seek; onfinal; track; return -45}
+    set c [chan create {r w} foo]
+    notes [inthread $c {
+	note [catch {seek $c 0 start} msg]
+	note $msg
+	close $c
+	notes
+    } c]
+    rename foo {}
+    set res
+} -result {{seek rc* 0 start} 1 {Tried to seek before origin}} \
+    -constraints {testchannel thread}
+test iocmd.tf-28.17 {chan seek, bogus return, string return} -match glob -body {
+    set res {}
+    proc foo {args} {oninit seek; onfinal; track; return BOGUS}
+    set c [chan create {r w} foo]
+    notes [inthread $c {
+	note [catch {seek $c 0 start} msg]
+	note $msg
+	close $c
+	notes
+    } c]
+    rename foo {}
+    set res
+} -result {{seek rc* 0 start} 1 {expected integer but got "BOGUS"}} \
+    -constraints {testchannel thread}
+test iocmd.tf-28.18 {chan seek, ok result} -match glob -body {
+    set res {}
+    proc foo {args} {oninit seek; onfinal; track; return 23}
+    set c [chan create {r w} foo]
+    notes [inthread $c {
+	note [seek $c 0 current]
+	close $c
+	notes
+    } c]
+    rename foo {}
+    set res
+} -result {{seek rc* 0 current} {}} \
+    -constraints {testchannel thread}
+foreach {testname code} {
+    iocmd.tf-28.19.0 start
+    iocmd.tf-28.19.1 current
+    iocmd.tf-28.19.2 end
+} {
+    test $testname "chan seek, base conversion, $code" -match glob -body {
+	set res {}
+	proc foo {args} {oninit seek; onfinal; track; return 0}
+	set c [chan create {r w} foo]
+	notes [inthread $c {
+	    note [seek $c 0 $code]
+	    close $c
+	    notes
+	} c code]
+	rename foo {}
+	set res
+    } -result [list [list seek rc* 0 $code] {}] \
+	-constraints {testchannel thread}
+}
+
+# --- === *** ###########################
+# method blocking
+
+test iocmd.tf-29.1 {chan blocking, no handler support} -match glob -body {
+    set res {}
+    proc foo {args} {oninit; onfinal; track; note MUST_NOT_HAPPEN; return}
+    set c [chan create {r w} foo]
+    notes [inthread $c {
+	note [fconfigure $c -blocking]
+	close $c
+	notes
+    } c]
+    rename foo {}
+    set res
+} -result {1} \
+    -constraints {testchannel thread}
+test iocmd.tf-29.2 {chan blocking, no handler support} -match glob -body {
+    set res {}
+    proc foo {args} {oninit; onfinal; track; note MUST_NOT_HAPPEN; return}
+    set c [chan create {r w} foo]
+    notes [inthread $c {
+	note [fconfigure $c -blocking 0]
+	note [fconfigure $c -blocking]
+	close $c
+	notes
+    } c]
+    rename foo {}
+    set res
+} -result {{} 0} \
+    -constraints {testchannel thread}
+test iocmd.tf-29.3 {chan blocking, retrieval, handler support} -match glob -body {
+    set res {}
+    proc foo {args} {oninit blocking; onfinal; track; note MUST_NOT_HAPPEN; return}
+    set c [chan create {r w} foo]
+    notes [inthread $c {
+	note [fconfigure $c -blocking]
+	close $c
+	notes
+    } c]
+    rename foo {}
+    set res
+} -result {1} \
+    -constraints {testchannel thread}
+test iocmd.tf-29.4 {chan blocking, resetting, handler support} -match glob -body {
+    set res {}
+    proc foo {args} {oninit blocking; onfinal; track; return}
+    set c [chan create {r w} foo]
+    notes [inthread $c {
+	note [fconfigure $c -blocking 0]
+	note [fconfigure $c -blocking]
+	close $c
+	notes
+    } c]
+    rename foo {}
+    set res
+} -result {{blocking rc* 0} {} 0} \
+    -constraints {testchannel thread}
+test iocmd.tf-29.5 {chan blocking, setting, handler support} -match glob -body {
+    set res {}
+    proc foo {args} {oninit blocking; onfinal; track; return}
+    set c [chan create {r w} foo]
+    notes [inthread $c {
+	note [fconfigure $c -blocking 1]
+	note [fconfigure $c -blocking]
+	close $c
+	notes
+    } c]
+    rename foo {}
+    set res
+} -result {{blocking rc* 1} {} 1} \
+    -constraints {testchannel thread}
+test iocmd.tf-29.6 {chan blocking, error return} -match glob -body {
+    set res {}
+    proc foo {args} {oninit blocking; onfinal; track; error BOOM!}
+    set c [chan create {r w} foo]
+    notes [inthread $c {
+	note [catch {fconfigure $c -blocking 0} msg]
+	note $msg
+	# Catch the close. It changes blocking mode internally, and runs into the error result.
+	catch {close $c}
+	notes
+    } c]
+    rename foo {}
+    set res
+} -result {{blocking rc* 0} 1 BOOM!} \
+    -constraints {testchannel thread}
+test iocmd.tf-29.7 {chan blocking, break return is error} -match glob -body {
+    set res {}
+    proc foo {args} {oninit blocking; onfinal; track; return -code break BOOM!}
+    set c [chan create {r w} foo]
+    notes [inthread $c {
+	note [catch {fconfigure $c -blocking 0} msg]
+	note $msg
+	catch {close $c}
+	notes
+    } c]
+    rename foo {}
+    set res
+} -result {{blocking rc* 0} 1 *bad code*} \
+    -constraints {testchannel thread}
+test iocmd.tf-29.8 {chan blocking, continue return is error} -match glob -body {
+    set res {}
+    proc foo {args} {oninit blocking; onfinal; track; return -code continue BOOM!}
+    set c [chan create {r w} foo]
+    notes [inthread $c {
+	note [catch {fconfigure $c -blocking 0} msg]
+	note $msg
+	catch {close $c}
+	notes
+    } c]
+    rename foo {}
+    set res
+} -result {{blocking rc* 0} 1 *bad code*} \
+    -constraints {testchannel thread}
+test iocmd.tf-29.9 {chan blocking, custom return is error} -match glob -body {
+    set res {}
+    proc foo {args} {oninit blocking; onfinal; track; return -code 44 BOOM!}
+    set c [chan create {r w} foo]
+    notes [inthread $c {
+	note [catch {fconfigure $c -blocking 0} msg]
+	note $msg
+	catch {close $c}
+	notes
+    } c]
+    rename foo {}
+    set res
+} -result {{blocking rc* 0} 1 *bad code*} \
+    -constraints {testchannel thread}
+test iocmd.tf-29.10 {chan blocking, level is ignored} -match glob -body {
+    set res {}
+    proc foo {args} {oninit blocking; onfinal; track; return -level 99 -code 44 BANG}
+    set c [chan create {r w} foo]
+    notes [inthread $c {
+	note [catch {fconfigure $c -blocking 0} msg opt]
+	note $msg
+	noteOpts $opt
+	catch {close $c}
+	notes
+    } c]
+    rename foo {}
+    set res
+} -result {{blocking rc* 0} 1 *bad code* {-code 1 -level 0 -errorcode NONE -errorline 1 -errorinfo *bad code*subcommand "blocking"*}} \
+    -constraints {testchannel thread}
+test iocmd.tf-29.11 {chan blocking, regular return ok, value ignored} -match glob -body {
+    set res {}
+    proc foo {args} {oninit blocking; onfinal; track; return BOGUS}
+    set c [chan create {r w} foo]
+    notes [inthread $c {
+	note [catch {fconfigure $c -blocking 0} msg]
+	note $msg
+	catch {close $c}
+	notes
+    } c]
+    rename foo {}
+    set res
+} -result {{blocking rc* 0} 0 {}} \
+    -constraints {testchannel thread}
+
+# --- === *** ###########################
+# method watch
+
+test iocmd.tf-30.1 {chan watch, read interest, some return} -match glob -body {
+    set res {}
+    proc foo {args} {oninit; onfinal; track; return IGNORED}
+    set c [chan create {r w} foo]
+    notes [inthread $c {
+	note [fileevent $c readable {set tick $tick}]
+	close $c		;# 2nd watch, interest zero.
+	notes
+    } c]
+    rename foo {}
+    set res
+} -constraints {testchannel thread} -result {{watch rc* read} {watch rc* {}} {}}
+test iocmd.tf-30.2 {chan watch, write interest, error return} -match glob -body {
+    set res {}
+    proc foo {args} {oninit; onfinal; track; return -code error BOOM!_IGNORED}
+    set c [chan create {r w} foo]
+    notes [inthread $c {
+	note [fileevent $c writable {set tick $tick}]
+	note [fileevent $c writable {}]
+	close $c
+	notes
+    } c]
+    rename foo {}
+    set res
+} -constraints {testchannel thread} -result {{watch rc* write} {watch rc* {}} {} {}}
+test iocmd.tf-30.3 {chan watch, accumulated interests} -match glob -body {
+    set res {}
+    proc foo {args} {oninit; onfinal; track; return}
+    set c [chan create {r w} foo]
+    notes [inthread $c {
+	note [fileevent $c writable {set tick $tick}]
+	note [fileevent $c readable {set tick $tick}]
+	note [fileevent $c writable {}]
+	note [fileevent $c readable {}]
+	close $c
+	notes
+    } c]
+    rename foo {}
+    set res
+} -constraints {testchannel thread} \
+    -result {{watch rc* write} {watch rc* {read write}} {watch rc* read} {watch rc* {}} {} {} {} {}}
+test iocmd.tf-30.4 {chan watch, unchanged interest not forwarded} -match glob -body {
+    set res {}
+    proc foo {args} {oninit; onfinal; track; return}
+    set c [chan create {r w} foo]
+    notes [inthread $c {
+	note [fileevent $c writable {set tick $tick}]
+	note [fileevent $c readable {set tick $tick}] ;# Script is changing,
+	note [fileevent $c readable {set tock $tock}] ;# interest does not.
+	close $c	;# 3rd and 4th watch, removing the event handlers.
+	notes
+    } c]
+    rename foo {}
+    set res
+} -constraints {testchannel thread} \
+    -result {{watch rc* write} {watch rc* {read write}} {watch rc* write} {watch rc* {}} {} {} {}}
+
+# --- === *** ###########################
+# postevent
+# Not possible from a thread not containing the command handler.
+# Check that this is rejected.
+
+test iocmd.tf-31.8 {chan postevent, bad input} -match glob -body {
+    set res {}
+    proc foo {args} {oninit; onfinal; track; return}
+    set c [chan create {r w} foo]
+    notes [inthread $c {
+	catch {chan postevent $c r} msg
+	note $msg
+	close $c
+	notes
+    } c]
+    rename foo {}
+    set res
+} -constraints {testchannel thread} \
+    -result {{can not find reflected channel named "rc*"}}
+
+# --- === *** ###########################
+# 'Pull the rug' tests. Create channel in a thread A, move to other
+# thread B, destroy the origin thread (A) before or during access from
+# B. Must not crash, must return proper errors.
+
+test iocmd.tf-32.0 {origin thread of moved channel gone} -match glob -body {
+
+    #puts <<$tcltest::mainThread>>main
+    set tida [thread::create -preserved];#puts <<$tida>>
+    thread::send $tida {load {} Tcltest}
+
+    set tidb [thread::create -preserved];#puts <<$tidb>>
+    thread::send $tidb {load {} Tcltest}
+
+    # Set up channel in thread
+    thread::send $tida $helperscript
+    set chan [thread::send $tida {
+	proc foo {args} {oninit seek; onfinal; track; return}
+	set chan [chan create {r w} foo]
+	fconfigure $chan -buffering none
+	set chan
+    }]
+
+    # Move channel to 2nd thread.
+    thread::send $tida [list testchannel cut $chan]
+    thread::send $tidb [list testchannel splice $chan]
+
+    # Kill origin thread, then access channel from 2nd thread.
+    thread::release $tida
+
+    set     res {}
+    lappend res [catch {thread::send $tidb [list puts  $chan shoo]} msg] $msg
+
+    lappend res [catch {thread::send $tidb [list tell  $chan]}      msg] $msg
+    lappend res [catch {thread::send $tidb [list seek  $chan 1]}    msg] $msg
+    lappend res [catch {thread::send $tidb [list gets  $chan]}      msg] $msg
+    lappend res [catch {thread::send $tidb [list close $chan]}      msg] $msg
+    thread::release $tidb
+    set res
+
+} -constraints {testchannel thread} \
+    -result {1 {Owner lost} 1 {Owner lost} 1 {Owner lost} 1 {Owner lost} 1 {Owner lost}}
+
+
+# The test iocmd.tf-32.1 unavoidably exhibits a memory leak.  We are testing
+# the ability of the reflected channel system to react to the situation where
+# the thread in which the driver routines runs exits during driver operations.
+# In this case, thread exit handlers signal back to the owner thread so that the
+# channel operation does not hang.  There's no way to test this without actually
+# exiting a thread in mid-operation, and that action is unavoidably leaky (which
+# is why [thread::exit] is advised against).
+#
+# Use constraints to skip this test while valgrinding so this expected leak
+# doesn't prevent a finding of "leak-free".
+#
+testConstraint notValgrind [expr {![testConstraint valgrind]}]
+test iocmd.tf-32.1 {origin thread of moved channel destroyed during access} -match glob -body {
+
+    #puts <<$tcltest::mainThread>>main
+    set tida [thread::create -preserved];#puts <<$tida>>
+    thread::send $tida {load {} Tcltest}
+    set tidb [thread::create -preserved];#puts <<$tidb>>
+    thread::send $tidb {load {} Tcltest}
+
+    # Set up channel in thread
+    thread::send $tida $helperscript
+    set chan [thread::send $tida {
+	proc foo {args} {
+	    oninit; onfinal; track;
+	    # destroy thread during channel access
+	    thread::exit
+	    }
+	set chan [chan create {r w} foo]
+	fconfigure $chan -buffering none
+	set chan
+    }]
+
+    # Move channel to 2nd thread.
+    thread::send $tida [list testchannel cut    $chan]
+    thread::send $tidb [list testchannel splice $chan]
+
+    # Run access from thread B, wait for response from A (A is not
+    # using event loop at this point, so the event pile up in the
+    # queue.
+
+    thread::send $tidb [list set chan $chan]
+    thread::send $tidb [list set mid [thread::id]]
+    thread::send -async $tidb {
+	# wait a bit, give the main thread the time to start its event
+	# loop to wait for the response from B
+	after 2000
+	catch { puts $chan shoo } res
+	thread::send -async $mid [list set ::res $res]
+    }
+    vwait ::res
+
+    catch {thread::release $tida}
+    thread::release $tidb
+    set res
+} -constraints {testchannel thread notValgrind} \
+    -result {Owner lost}
+
+# ### ### ### ######### ######### #########
+
+# ### ### ### ######### ######### #########
+
+rename track {}
+# cleanup
+foreach file [list test1 test2 test3 test4] {
+    removeFile $file
+}
+# delay long enough for background processes to finish
+after 500
+foreach file [list test5] {
+    removeFile $file
+}
+cleanupTests
+return
diff --git a/tests/ioTrans.test b/tests/ioTrans.test
new file mode 100644
index 0000000..e179eab
--- /dev/null
+++ b/tests/ioTrans.test
@@ -0,0 +1,2093 @@
+# -*- tcl -*-
+# Functionality covered: operation of the reflected transformation
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands.  Sourcing this file into Tcl runs the tests and
+# generates output for errors.  No output means no errors were found.
+#
+# Copyright (c) 2007 Andreas Kupries <andreask@activestate.com>
+#                                    <akupries@shaw.ca>
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+    package require tcltest 2
+    namespace import -force ::tcltest::*
+}
+
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
+
+# Custom constraints used in this file
+testConstraint testchannel [llength [info commands testchannel]]
+testConstraint thread [expr {0 == [catch {package require Thread 2.7-}]}]
+
+# testchannel cut|splice  Both needed to test the reflection in threads.
+# thread::send
+
+#----------------------------------------------------------------------
+
+# ### ### ### ######### ######### #########
+## Testing the reflected transformation.
+
+# Helper commands to record the arguments to handler methods.  Stored in a
+# script so that the tests needing this code do not need their own copy but
+# can access this variable.
+
+set helperscript {
+    if {[lsearch [namespace children] ::tcltest] == -1} {
+	package require tcltest 2
+	namespace import -force ::tcltest::*
+    }
+
+    # This forces the return options to be in the order that the test expects!
+    variable optorder {
+	-code !?! -level !?! -errorcode !?! -errorline !?! -errorinfo !?!
+	-errorstack !?!
+    }
+    proc noteOpts opts {
+	variable optorder
+	lappend ::res [dict merge $optorder $opts]
+    }
+
+    # Helper command, canned result for 'initialize' method.  Gets the
+    # optional methods as arguments. Use return features to post the result
+    # higher up.
+
+    proc handle.initialize {args} {
+	upvar args hargs
+	if {[lindex $hargs 0] eq "initialize"} {
+	    return -code return [list {*}$args initialize finalize read write]
+	}
+    }
+    proc handle.finalize {} {
+	upvar args hargs
+	if {[lindex $hargs 0] eq "finalize"} {
+	    return -code return ""
+	}
+    }
+    proc handle.read {} {
+	upvar args hargs
+	if {[lindex $hargs 0] eq "read"} {
+	    return -code return "@"
+	}
+    }
+    proc handle.drain {} {
+	upvar args hargs
+	if {[lindex $hargs 0] eq "drain"} {
+	    return -code return "<>"
+	}
+    }
+    proc handle.clear {} {
+	upvar args hargs
+	if {[lindex $hargs 0] eq "clear"} {
+	    return -code return ""
+	}
+    }
+
+    proc tempchan {{mode r+}} {
+	global tempchan
+	return [set tempchan [open [makeFile {test data} tempchanfile] $mode]]
+    }
+    proc tempdone {} {
+	global tempchan
+	catch {close $tempchan}
+	removeFile tempchanfile
+	return
+    }
+    proc tempview {} { viewFile tempchanfile }
+}
+
+# Set everything up in the main thread.
+eval $helperscript
+
+#puts <<[file channels]>>
+
+# ### ### ### ######### ######### #########
+
+test iortrans-1.0 {chan, wrong#args} -returnCodes error -body {
+    chan
+} -result {wrong # args: should be "chan subcommand ?arg ...?"}
+test iortrans-1.1 {chan, unknown method} -returnCodes error -body {
+    chan foo
+} -match glob -result {unknown or ambiguous subcommand "foo": must be*}
+
+# --- --- --- --------- --------- ---------
+# chan push, and method "initalize"
+
+test iortrans-2.0 {chan push, wrong#args, not enough} -returnCodes error -body {
+    chan push
+} -result {wrong # args: should be "chan push channel cmdprefix"}
+test iortrans-2.1 {chan push, wrong#args, too many} -returnCodes error -body {
+    chan push a b c
+} -result {wrong # args: should be "chan push channel cmdprefix"}
+test iortrans-2.2 {chan push, invalid channel} -setup {
+    proc foo {} {}
+} -returnCodes error -body {
+    chan push {} foo
+} -cleanup {
+    rename foo {}
+} -result {can not find channel named ""}
+test iortrans-2.3 {chan push, bad handler, not a list} -body {
+    chan push [tempchan] "foo \{"
+} -returnCodes error -cleanup {
+    tempdone
+} -result {unmatched open brace in list}
+test iortrans-2.4 {chan push, bad handler, not a command} -body {
+    chan push [tempchan] foo
+} -returnCodes error -cleanup {
+    tempdone
+} -result {invalid command name "foo"}
+test iortrans-2.5 {chan push, initialize failed, bad signature} -body {
+    proc foo {} {}
+    chan push [tempchan] foo
+} -returnCodes error -cleanup {
+    tempdone
+    rename foo {}
+} -result {wrong # args: should be "foo"}
+test iortrans-2.6 {chan push, initialize failed, bad signature} -body {
+    proc foo {} {}
+    chan push [tempchan] ::foo
+} -returnCodes error -cleanup {
+    tempdone
+    rename foo {}
+} -result {wrong # args: should be "::foo"}
+test iortrans-2.7 {chan push, initialize failed, bad result, not a list} -body {
+    proc foo {args} {return "\{"}
+    catch {chan push [tempchan] foo}
+    return $::errorInfo
+} -cleanup {
+    tempdone
+    rename foo {}
+} -match glob -result {chan handler "foo initialize" returned non-list: *}
+test iortrans-2.8 {chan push, initialize failed, bad result, not a list} -body {
+    proc foo {args} {return \{\{\}}
+    chan push [tempchan] foo
+} -returnCodes error -cleanup {
+    tempdone
+    rename foo {}
+} -match glob -result {chan handler "foo initialize" returned non-list: *}
+test iortrans-2.9 {chan push, initialize failed, bad result, empty list} -body {
+    proc foo {args} {}
+    chan push [tempchan] foo
+} -returnCodes error -cleanup {
+    tempdone
+    rename foo {}
+} -match glob -result {*all required methods*}
+test iortrans-2.10 {chan push, initialize failed, bad result, bogus method name} -body {
+    proc foo {args} {return 1}
+    chan push [tempchan] foo
+} -returnCodes error -cleanup {
+    tempdone
+    rename foo {}
+} -match glob -result {*bad method "1": must be *}
+test iortrans-2.11 {chan push, initialize failed, bad result, bogus method name} -body {
+    proc foo {args} {return {a b c}}
+    chan push [tempchan] foo
+} -returnCodes error -cleanup {
+    tempdone
+    rename foo {}
+} -match glob -result {*bad method "c": must be *}
+test iortrans-2.12 {chan push, initialize failed, bad result, required methods missing} -body {
+    # Required: initialize, and finalize.
+    proc foo {args} {return {initialize}}
+    chan push [tempchan] foo
+} -returnCodes error -cleanup {
+    tempdone
+    rename foo {}
+} -match glob -result {*all required methods*}
+test iortrans-2.13 {chan push, initialize failed, bad result, illegal method name} -body {
+    proc foo {args} {return {initialize finalize BOGUS}}
+    chan push [tempchan] foo
+} -returnCodes error -cleanup {
+    tempdone
+    rename foo {}
+} -match glob -result {*returned bad method "BOGUS": must be clear, drain, finalize, flush, initialize, limit?, read, or write}
+test iortrans-2.14 {chan push, initialize failed, bad result, mode/handler mismatch} -body {
+    proc foo {args} {return {initialize finalize}}
+    chan push [tempchan] foo
+} -returnCodes error -cleanup {
+    tempdone
+    rename foo {}
+} -match glob -result {*makes the channel inaccessible}
+# iortrans-2.15 event/watch methods elimimated, removed these tests.
+# iortrans-2.16
+test iortrans-2.17 {chan push, initialize failed, bad result, drain/read mismatch} -body {
+    proc foo {args} {return {initialize finalize drain write}}
+    chan push [tempchan] foo
+} -returnCodes error -cleanup {
+    tempdone
+    rename foo {}
+} -match glob -result {*supports "drain" but not "read"}
+test iortrans-2.18 {chan push, initialize failed, bad result, flush/write mismatch} -body {
+    proc foo {args} {return {initialize finalize flush read}}
+    chan push [tempchan] foo
+} -returnCodes error -cleanup {
+    tempdone
+    rename foo {}
+} -match glob -result {*supports "flush" but not "write"}
+test iortrans-2.19 {chan push, initialize ok, creates channel} -setup {
+    set res {}
+} -match glob -body {
+    proc foo {args} {
+	global res
+	lappend res $args
+	if {[lindex $args 0] ne "initialize"} {return}
+	return {initialize finalize drain flush read write}
+    }
+    lappend res [file channel rt*]
+    lappend res [chan push [tempchan] foo]
+    lappend res [close [lindex $res end]]
+    lappend res [file channel rt*]
+} -cleanup {
+    tempdone
+    rename foo {}
+} -result {{} {initialize rt* {read write}} file* {drain rt*} {flush rt*} {finalize rt*} {} {}}
+test iortrans-2.20 {chan push, init failure -> no channel, no finalize} -setup {
+    set res {}
+} -match glob -body {
+    proc foo {args} {
+	global res
+	lappend res $args
+	return
+    }
+    lappend res [file channel rt*]
+    lappend res [catch {chan push [tempchan] foo} msg] $msg
+    lappend res [file channel rt*]
+} -cleanup {
+    tempdone
+    rename foo {}
+} -result {{} {initialize rt* {read write}} 1 {*all required methods*} {}}
+
+# --- --- --- --------- --------- ---------
+# method finalize (via close)
+
+# General note: file channels rt* finds the transform channel, however the
+# name reported will be that of the underlying base driver, fileXX here.  This
+# actually allows us to see if the whole channel is gone, or only the
+# transformation, but not the base.
+
+test iortrans-3.1 {chan finalize, handler destruction has no effect on channel} -setup {
+    set res {}
+} -match glob -body {
+    proc foo {args} {
+	lappend ::res $args
+	handle.initialize
+	return
+    }
+    lappend res [set c [chan push [tempchan] foo]]
+    rename foo {}
+    lappend res [file channels file*]
+    lappend res [file channels rt*]
+    lappend res [catch {close $c} msg] $msg
+    lappend res [file channels file*]
+    lappend res [file channels rt*]
+} -cleanup {
+    tempdone
+} -result {{initialize rt* {read write}} file* file* {} 1 {invalid command name "foo"} {} {}}
+test iortrans-3.2 {chan finalize, for close} -setup {
+    set res {}
+} -match glob -body {
+    proc foo {args} {
+	lappend ::res $args
+	handle.initialize
+	return
+    }
+    lappend res [set c [chan push [tempchan] foo]]
+    close $c
+    # Close deleted the channel.
+    lappend res [file channels rt*]
+    # Channel destruction does not kill handler command!
+    lappend res [info command foo]
+} -cleanup {
+    rename foo {}
+    tempdone
+} -result {{initialize rt* {read write}} file* {finalize rt*} {} foo}
+test iortrans-3.3 {chan finalize, for close, error, close error} -setup {
+    set res {}
+} -match glob -body {
+    proc foo {args} {
+	lappend ::res $args
+	handle.initialize
+	return -code error 5
+    }
+    lappend res [set c [chan push [tempchan] foo]]
+    lappend res [catch {close $c} msg] $msg
+    # Channel is gone despite error.
+    lappend res [file channels rt*]
+} -cleanup {
+    rename foo {}
+    tempdone
+} -result {{initialize rt* {read write}} file* {finalize rt*} 1 5 {}}
+test iortrans-3.4 {chan finalize, for close, error, close error} -setup {
+    set res {}
+} -match glob -body {
+    proc foo {args} {
+	lappend ::res $args
+	handle.initialize
+	error FOO
+    }
+    lappend res [set c [chan push [tempchan] foo]]
+    lappend res [catch {close $c} msg] $msg $::errorInfo
+} -cleanup {
+    rename foo {}
+    tempdone
+} -result {{initialize rt* {read write}} file* {finalize rt*} 1 FOO {FOO
+*"close $c"}}
+test iortrans-3.5 {chan finalize, for close, arbitrary result, ignored} -setup {
+    set res {}
+} -match glob -body {
+    proc foo {args} {
+	lappend ::res $args
+	handle.initialize
+	return SOMETHING
+    }
+    lappend res [set c [chan push [tempchan] foo]]
+    lappend res [catch {close $c} msg] $msg
+} -cleanup {
+    rename foo {}
+    tempdone
+} -result {{initialize rt* {read write}} file* {finalize rt*} 0 {}}
+test iortrans-3.6 {chan finalize, for close, break, close error} -setup {
+    set res {}
+} -match glob -body {
+    proc foo {args} {
+	lappend ::res $args
+	handle.initialize
+	return -code 3
+    }
+    lappend res [set c [chan push [tempchan] foo]]
+    lappend res [catch {close $c} msg] $msg
+} -cleanup {
+    rename foo {}
+    tempdone
+} -result {{initialize rt* {read write}} file* {finalize rt*} 1 *bad code*}
+test iortrans-3.7 {chan finalize, for close, continue, close error} -setup {
+    set res {}
+} -match glob -body {
+    proc foo {args} {
+	lappend ::res $args
+	handle.initialize
+	return -code 4
+    }
+    lappend res [set c [chan push [tempchan] foo]]
+    lappend res [catch {close $c} msg] $msg
+} -cleanup {
+    rename foo {}
+    tempdone
+} -result {{initialize rt* {read write}} file* {finalize rt*} 1 *bad code*}
+test iortrans-3.8 {chan finalize, for close, custom code, close error} -setup {
+    set res {}
+} -match glob -body {
+    proc foo {args} {
+	lappend ::res $args
+	handle.initialize
+	return -code 777 BANG
+    }
+    lappend res [set c [chan push [tempchan] foo]]
+    lappend res [catch {close $c} msg] $msg
+} -cleanup {
+    rename foo {}
+    tempdone
+} -result {{initialize rt* {read write}} file* {finalize rt*} 1 *bad code*}
+test iortrans-3.9 {chan finalize, for close, ignore level, close error} -setup {
+    set res {}
+} -body {
+    proc foo {args} {
+	lappend ::res $args
+	handle.initialize
+	return -level 5 -code 777 BANG
+    }
+    lappend res [set c [chan push [tempchan] foo]]
+    lappend res [catch {close $c} msg opt] $msg
+    noteOpts $opt
+} -match glob -cleanup {
+    rename foo {}
+    tempdone
+} -result {{initialize rt* {read write}} file* {finalize rt*} 1 *bad code* {-code 1 -level 0 -errorcode NONE -errorline 1 -errorinfo *bad code*subcommand "finalize"*}}
+
+# --- === *** ###########################
+# method read (via read)
+
+test iortrans-4.1 {chan read, transform call and return} -setup {
+    set res {}
+} -match glob -body {
+    proc foo {args} {
+	handle.initialize
+	handle.finalize
+	lappend ::res $args
+	return snarf
+    }
+    set c [chan push [tempchan] foo]
+    lappend res [read $c 10]
+} -cleanup {
+    tempdone
+    rename foo {}
+} -result {{read rt* {test data
+}} snarf}
+test iortrans-4.2 {chan read, for non-readable channel} -setup {
+    set res {}
+} -match glob -body {
+    proc foo {args} {
+	handle.initialize
+	handle.finalize
+	lappend ::res $args MUST_NOT_HAPPEN
+    }
+    set c [chan push [tempchan w] foo]
+    lappend res [catch {read $c 2} msg] $msg
+} -cleanup {
+    tempdone
+    rename foo {}
+} -result {1 {channel "file*" wasn't opened for reading}}
+test iortrans-4.3 {chan read, error return} -setup {
+    set res {}
+} -match glob -body {
+    proc foo {args} {
+	handle.initialize
+	handle.finalize
+	lappend ::res $args
+	return -code error BOOM!
+    }
+    set c [chan push [tempchan] foo]
+    lappend res [catch {read $c 2} msg] $msg
+} -cleanup {
+    tempdone
+    rename foo {}
+} -result {{read rt* {test data
+}} 1 BOOM!}
+test iortrans-4.4 {chan read, break return is error} -setup {
+    set res {}
+} -match glob -body {
+    proc foo {args} {
+	handle.initialize
+	handle.finalize
+	lappend ::res $args
+	return -code break BOOM!
+    }
+    set c [chan push [tempchan] foo]
+    lappend res [catch {read $c 2} msg] $msg
+} -cleanup {
+    tempdone
+    rename foo {}
+} -result {{read rt* {test data
+}} 1 *bad code*}
+test iortrans-4.5 {chan read, continue return is error} -setup {
+    set res {}
+} -match glob -body {
+    proc foo {args} {
+	handle.initialize
+	handle.finalize
+	lappend ::res $args
+	return -code continue BOOM!
+    }
+    set c [chan push [tempchan] foo]
+    lappend res [catch {read $c 2} msg] $msg
+} -cleanup {
+    tempdone
+    rename foo {}
+} -result {{read rt* {test data
+}} 1 *bad code*}
+test iortrans-4.6 {chan read, custom return is error} -setup {
+    set res {}
+} -match glob -body {
+    proc foo {args} {
+	handle.initialize
+	handle.finalize
+	lappend ::res $args
+	return -code 777 BOOM!
+    }
+    set c [chan push [tempchan] foo]
+    lappend res [catch {read $c 2} msg] $msg
+} -cleanup {
+    tempdone
+    rename foo {}
+} -result {{read rt* {test data
+}} 1 *bad code*}
+test iortrans-4.7 {chan read, level is squashed} -setup {
+    set res {}
+} -match glob -body {
+    proc foo {args} {
+	handle.initialize
+	handle.finalize
+	lappend ::res $args
+	return -level 55 -code 777 BOOM!
+    }
+    set c [chan push [tempchan] foo]
+    lappend res [catch {read $c 2} msg opt] $msg
+    noteOpts $opt
+} -cleanup {
+    tempdone
+    rename foo {}
+} -result {{read rt* {test data
+}} 1 *bad code* {-code 1 -level 0 -errorcode NONE -errorline 1 -errorinfo *bad code*subcommand "read"*}}
+test iortrans-4.8 {chan read, read, bug 2921116} -setup {
+    set res {}
+} -match glob -body {
+    proc foo {fd args} {
+	handle.initialize
+	handle.finalize
+	lappend ::res $args
+	# Kill and recreate transform while it is operating
+	chan pop $fd
+	chan push $fd [list foo $fd]
+    }
+    set c [chan push [set c [tempchan]] [list foo $c]]
+    lappend res [read $c]
+    #lappend res [gets $c]
+} -cleanup {
+    tempdone
+    rename foo {}
+} -result {{read rt* {test data
+}} {}}
+test iortrans-4.8.1 {chan read, bug 721ec69271} -setup {
+    set res {}
+} -match glob -body {
+    proc foo {fd args} {
+	handle.initialize
+	handle.finalize
+	lappend ::res $args
+	# Kill and recreate transform while it is operating
+	chan pop $fd
+	chan push $fd [list foo $fd]
+    }
+    set c [chan push [set c [tempchan]] [list foo $c]]
+    chan configure $c -buffersize 2
+    lappend res [read $c]
+} -cleanup {
+    tempdone
+    rename foo {}
+} -result {{read rt* te} {read rt* st} {read rt* { d}} {read rt* at} {read rt* {a
+}} {}}
+test iortrans-4.8.2 {chan read, bug 721ec69271} -setup {
+    set res {}
+} -match glob -body {
+    proc foo {fd args} {
+	handle.initialize
+	handle.finalize
+	lappend ::res $args
+	# Kill and recreate transform while it is operating
+	chan pop $fd
+	chan push $fd [list foo $fd]
+	return x
+    }
+    set c [chan push [set c [tempchan]] [list foo $c]]
+    chan configure $c -buffersize 1
+    lappend res [read $c]
+} -cleanup {
+    tempdone
+    rename foo {}
+} -result {{read rt* t} {read rt* e} {read rt* s} {read rt* t} {read rt* { }} {read rt* d} {read rt* a} {read rt* t} {read rt* a} {read rt* {
+}} {}}
+test iortrans-4.9 {chan read, gets, bug 2921116} -setup {
+    set res {}
+} -match glob -body {
+    proc foo {fd args} {
+	handle.initialize
+	handle.finalize
+	lappend ::res $args
+	# Kill and recreate transform while it is operating
+	chan pop $fd
+	chan push $fd [list foo $fd]
+    }
+    set c [chan push [set c [tempchan]] [list foo $c]]
+    lappend res [gets $c]
+} -cleanup {
+    tempdone
+    rename foo {}
+} -result {{read rt* {test data
+}} {}}
+
+# Driver for a base channel that emits several short "files"
+# with each terminated by a fleeting EOF
+    proc driver {cmd args} {
+        variable ::tcl::buffer
+        variable ::tcl::index
+        set chan [lindex $args 0]
+        switch -- $cmd {
+            initialize {
+                set index($chan) 0
+                set buffer($chan) .....
+                return {initialize finalize watch read}
+            }
+            finalize {
+                if {![info exists index($chan)]} {return}
+                unset index($chan) buffer($chan)
+		array unset index
+		array unset buffer
+                return
+            }
+            watch {}
+            read {
+                set n [lindex $args 1]
+                if {![info exists index($chan)]} {
+                    driver initialize $chan
+                }
+                set new [expr {$index($chan) + $n}]
+                set result [string range $buffer($chan) $index($chan) $new-1]
+                set index($chan) $new
+                if {[string length $result] == 0} {
+                    driver finalize $chan
+                }
+                return $result
+            }
+        }
+    }
+
+# Channel read transform that is just the identity - pass all through
+    proc idxform {cmd handle args} {
+      switch -- $cmd {
+        initialize {
+            return {initialize finalize read}
+        }
+        finalize {
+            return
+        }
+        read {
+            lassign $args buffer
+            return $buffer
+        }
+      }
+    }
+
+# Test that all EOFs pass through full xform stack.  Proper data boundaries.
+# Check robustness against buffer sizes.
+test iortrans-4.10 {[5adbc350683] chan read, handle fleeting EOF} -body {
+    set chan [chan push [chan create read driver] idxform]
+    list [eof $chan] [read $chan] [eof $chan] [read $chan 0] [eof $chan] \
+        [read $chan] [eof $chan]
+} -cleanup {
+    close $chan
+} -result {0 ..... 1 {} 0 ..... 1}
+test iortrans-4.10.1 {[5adbc350683] chan read, handle fleeting EOF} -body {
+    set chan [chan push [chan create read driver] idxform]
+    chan configure $chan -buffersize 3
+    list [eof $chan] [read $chan] [eof $chan] [read $chan 0] [eof $chan] \
+        [read $chan] [eof $chan]
+} -cleanup {
+    close $chan
+} -result {0 ..... 1 {} 0 ..... 1}
+test iortrans-4.10.2 {[5adbc350683] chan read, handle fleeting EOF} -body {
+    set chan [chan push [chan create read driver] idxform]
+    chan configure $chan -buffersize 5
+    list [eof $chan] [read $chan] [eof $chan] [read $chan 0] [eof $chan] \
+        [read $chan] [eof $chan]
+} -cleanup {
+    close $chan
+} -result {0 ..... 1 {} 0 ..... 1}
+
+rename idxform {}
+
+# Channel read transform that delays the data and always returns something
+    proc delayxform {cmd handle args} {
+      variable store
+      switch -- $cmd {
+        initialize {
+	    set store($handle) {}
+            return {initialize finalize read drain}
+        }
+        finalize {
+	    unset store($handle)
+            return
+        }
+        read {
+            lassign $args buffer
+	    if {$store($handle) eq {}} {
+		set reply [string index $buffer 0]
+		set store($handle) [string range $buffer 1 end]
+	    } else {
+		set reply $store($handle)
+		set store($handle) $buffer
+	    }
+            return $reply
+        }
+	drain {
+	    delayxform read $handle {}
+	}
+      }
+    }
+
+# Test that all EOFs pass through full xform stack.  Proper data boundaries.
+# Check robustness against buffer sizes.
+test iortrans-4.11 {[5adbc350683] chan read, handle fleeting EOF} -body {
+    set chan [chan push [chan create read driver] delayxform]
+    list [eof $chan] [read $chan] [eof $chan] [read $chan 0] [eof $chan] \
+        [read $chan] [eof $chan]
+} -cleanup {
+    close $chan
+} -result {0 ..... 1 {} 0 ..... 1}
+test iortrans-4.11.1 {[5adbc350683] chan read, handle fleeting EOF} -body {
+    set chan [chan push [chan create read driver] delayxform]
+    chan configure $chan -buffersize 3
+    list [eof $chan] [read $chan] [eof $chan] [read $chan 0] [eof $chan] \
+        [read $chan] [eof $chan]
+} -cleanup {
+    close $chan
+} -result {0 ..... 1 {} 0 ..... 1}
+test iortrans-4.11.2 {[5adbc350683] chan read, handle fleeting EOF} -body {
+    set chan [chan push [chan create read driver] delayxform]
+    chan configure $chan -buffersize 5
+    list [eof $chan] [read $chan] [eof $chan] [read $chan 0] [eof $chan] \
+        [read $chan] [eof $chan]
+} -cleanup {
+    close $chan
+} -result {0 ..... 1 {} 0 ..... 1}
+
+    rename delayxform {}
+
+# Channel read transform that delays the data and may return {}
+    proc delay2xform {cmd handle args} {
+      variable store
+      switch -- $cmd {
+        initialize {
+	    set store($handle) {}
+            return {initialize finalize read drain}
+        }
+        finalize {
+	    unset store($handle)
+            return
+        }
+        read {
+            lassign $args buffer
+		set reply $store($handle)
+		set store($handle) $buffer
+            return $reply
+        }
+	drain {
+	    delay2xform read $handle {}
+	}
+      }
+    }
+
+test iortrans-4.12 {[5adbc350683] chan read, handle fleeting EOF} -body {
+    set chan [chan push [chan create read driver] delay2xform]
+    list [eof $chan] [read $chan] [eof $chan] [read $chan 0] [eof $chan] \
+        [read $chan] [eof $chan]
+} -cleanup {
+    close $chan
+} -result {0 ..... 1 {} 0 ..... 1}
+
+    rename delay2xform {}
+    rename driver {}
+
+
+# --- === *** ###########################
+# method write (via puts)
+
+test iortrans-5.1 {chan write, regular write} -setup {
+    set res {}
+} -match glob -body {
+    proc foo {args} {
+	handle.initialize
+	handle.finalize
+	lappend ::res $args
+	return transformresult
+    }
+    set c [chan push [tempchan] foo]
+    puts -nonewline $c snarf
+    flush $c
+    close $c
+    lappend res [tempview]
+} -cleanup {
+    tempdone
+    rename foo {}
+} -result {{write rt* snarf} transformresult}
+test iortrans-5.2 {chan write, no write is ok, no change to file} -setup {
+    set res {}
+} -match glob -body {
+    proc foo {args} {
+	handle.initialize
+	handle.finalize
+	lappend ::res $args
+	return
+    }
+    set c [chan push [tempchan] foo]
+    puts -nonewline $c snarfsnarfsnarf
+    flush $c
+    close $c
+    lappend res [tempview];	# This has to show the original data, as nothing was written
+} -cleanup {
+    tempdone
+    rename foo {}
+} -result {{write rt* snarfsnarfsnarf} {test data}}
+test iortrans-5.3 {chan write, failed write} -setup {
+    set res {}
+} -match glob -body {
+    proc foo {args} {
+	handle.initialize
+	handle.finalize
+	lappend ::res $args
+	return -code error FAIL!
+    }
+    set c [chan push [tempchan] foo]
+    puts -nonewline $c snarfsnarfsnarf
+    lappend res [catch {flush $c} msg] $msg
+} -cleanup {
+    tempdone
+    rename foo {}
+} -result {{write rt* snarfsnarfsnarf} 1 FAIL!}
+test iortrans-5.4 {chan write, non-writable channel} -setup {
+    set res {}
+} -match glob -body {
+    proc foo {args} {
+	handle.initialize
+	handle.finalize
+	lappend ::res $args MUST_NOT_HAPPEN
+	return
+    }
+    set c [chan push [tempchan r] foo]
+    lappend res [catch {
+	puts -nonewline $c snarfsnarfsnarf
+	flush $c
+    } msg] $msg
+} -cleanup {
+    close $c
+    tempdone
+    rename foo {}
+} -result {1 {channel "file*" wasn't opened for writing}}
+test iortrans-5.5 {chan write, failed write, error return} -setup {
+    set res {}
+} -match glob -body {
+    proc foo {args} {
+	handle.initialize
+	handle.finalize
+	lappend ::res $args
+	return -code error BOOM!
+    }
+    set c [chan push [tempchan] foo]
+    lappend res [catch {
+	puts -nonewline $c snarfsnarfsnarf
+	flush $c
+    } msg] $msg
+} -cleanup {
+    tempdone
+    rename foo {}
+} -result {{write rt* snarfsnarfsnarf} 1 BOOM!}
+test iortrans-5.6 {chan write, failed write, error return} -setup {
+    set res {}
+} -match glob -body {
+    proc foo {args} {
+	handle.initialize
+	handle.finalize
+	lappend ::res $args
+	error BOOM!
+    }
+    set c [chan push [tempchan] foo]
+    lappend res {*}[catch {
+	puts -nonewline $c snarfsnarfsnarf
+	flush $c
+    } msg] $msg
+} -cleanup {
+    tempdone
+    rename foo {}
+} -result {{write rt* snarfsnarfsnarf} 1 BOOM!}
+test iortrans-5.7 {chan write, failed write, break return is error} -setup {
+    set res {}
+} -match glob -body {
+    proc foo {args} {
+	handle.initialize
+	handle.finalize
+	lappend ::res $args
+	return -code break BOOM!
+    }
+    set c [chan push [tempchan] foo]
+    lappend res [catch {
+	puts -nonewline $c snarfsnarfsnarf
+	flush $c
+    } msg] $msg
+} -cleanup {
+    tempdone
+    rename foo {}
+} -result {{write rt* snarfsnarfsnarf} 1 *bad code*}
+test iortrans-5.8 {chan write, failed write, continue return is error} -setup {
+    set res {}
+} -match glob -body {
+    proc foo {args} {
+	handle.initialize
+	handle.finalize
+	lappend ::res $args
+	return -code continue BOOM!
+    }
+    set c [chan push [tempchan] foo]
+    lappend res [catch {
+	puts -nonewline $c snarfsnarfsnarf
+	flush $c
+    } msg] $msg
+} -cleanup {
+    tempdone
+    rename foo {}
+} -result {{write rt* snarfsnarfsnarf} 1 *bad code*}
+test iortrans-5.9 {chan write, failed write, custom return is error} -setup {
+    set res {}
+} -match glob -body {
+    proc foo {args} {
+	handle.initialize
+	handle.finalize
+	lappend ::res $args
+	return -code 777 BOOM!
+    }
+    set c [chan push [tempchan] foo]
+    lappend res [catch {
+	puts -nonewline $c snarfsnarfsnarf
+	flush $c
+    } msg] $msg
+} -cleanup {
+    tempdone
+    rename foo {}
+} -result {{write rt* snarfsnarfsnarf} 1 *bad code*}
+test iortrans-5.10 {chan write, failed write, level is ignored} -setup {
+    set res {}
+} -match glob -body {
+    proc foo {args} {
+	handle.initialize
+	handle.finalize
+	lappend ::res $args
+	return -level 55 -code 777 BOOM!
+    }
+    set c [chan push [tempchan] foo]
+    lappend res [catch {
+	puts -nonewline $c snarfsnarfsnarf
+	flush $c
+    } msg opt] $msg
+    noteOpts $opt
+} -cleanup {
+    tempdone
+    rename foo {}
+} -result {{write rt* snarfsnarfsnarf} 1 *bad code* {-code 1 -level 0 -errorcode NONE -errorline * -errorinfo *bad code*subcommand "write"*}}
+test iortrans-5.11 {chan write, bug 2921116} -match glob -setup {
+    set res {}
+    set level 0
+} -body {
+    proc foo {fd args} {
+	handle.initialize
+	handle.finalize
+	lappend ::res $args
+	# pop - invokes flush - invokes 'foo write' - infinite recursion - stop it
+	global level
+	if {$level} {
+	    return
+	}
+	incr level
+	# Kill and recreate transform while it is operating
+	chan pop $fd
+	chan push $fd [list foo $fd]
+    }
+    set c [chan push [set c [tempchan]] [list foo $c]]
+    lappend res [puts -nonewline $c abcdef]
+    lappend res [flush $c]
+} -cleanup {
+    tempdone
+    rename foo {}
+} -result {{} {write rt* abcdef} {write rt* abcdef} {}}
+
+# --- === *** ###########################
+# method limit?, drain (via read)
+
+test iortrans-6.1 {chan read, read limits} -setup {
+    set res {}
+} -match glob -body {
+    proc foo {args} {
+	handle.initialize limit?
+	handle.finalize
+	lappend ::res $args
+	handle.read
+	return 6
+    }
+    set c [chan push [tempchan] foo]
+    lappend res [read $c 10]
+} -cleanup {
+    tempdone
+    rename foo {}
+} -result {{limit? rt*} {read rt* {test d}} {limit? rt*} {read rt* {ata
+}} {limit? rt*} @@}
+test iortrans-6.2 {chan read, read transform drain on eof} -setup {
+    set res {}
+} -match glob -body {
+    proc foo {args} {
+	handle.initialize drain
+	handle.finalize
+	lappend ::res $args
+	handle.read
+	handle.drain
+	return
+    }
+    set c [chan push [tempchan] foo]
+    lappend res [read $c]
+    lappend res [close $c]
+} -cleanup {
+    tempdone
+    rename foo {}
+} -result {{read rt* {test data
+}} {drain rt*} @<> {}}
+
+# --- === *** ###########################
+# method clear (via puts, seek)
+
+test iortrans-7.1 {chan write, write clears read buffers} -setup {
+    set res {}
+} -match glob -body {
+    proc foo {args} {
+	handle.initialize clear
+	handle.finalize
+	lappend ::res $args
+	handle.clear
+	return transformresult
+    }
+    set c [chan push [tempchan] foo]
+    puts -nonewline $c snarf
+    flush $c
+    return $res
+} -cleanup {
+    tempdone
+    rename foo {}
+} -result {{clear rt*} {write rt* snarf}}
+test iortrans-7.2 {seek clears read buffers} -setup {
+    set res {}
+} -match glob -body {
+    proc foo {args} {
+	handle.initialize clear
+	handle.finalize
+	lappend ::res $args
+	return
+    }
+    set c [chan push [tempchan] foo]
+    seek $c 2
+    return $res
+} -cleanup {
+    tempdone
+    rename foo {}
+} -result {{clear rt*}}
+test iortrans-7.3 {clear, any result is ignored} -setup {
+    set res {}
+} -match glob -body {
+    proc foo {args} {
+	handle.initialize clear
+	handle.finalize
+	lappend ::res $args
+	return -code error "X"
+    }
+    set c [chan push [tempchan] foo]
+    seek $c 2
+    return $res
+} -cleanup {
+    tempdone
+    rename foo {}
+} -result {{clear rt*}}
+test iortrans-7.4 {chan clear, bug 2921116} -match glob -setup {
+    set res {}
+} -body {
+    proc foo {fd args} {
+	handle.initialize clear
+	handle.finalize
+	lappend ::res $args
+	# Kill and recreate transform while it is operating
+	chan pop $fd
+	chan push $fd [list foo $fd]
+    }
+    set c [chan push [set c [tempchan]] [list foo $c]]
+    seek $c 2
+    return $res
+} -cleanup {
+    tempdone
+    rename foo {}
+} -result {{clear rt*}}
+
+# --- === *** ###########################
+# method flush (via seek, close)
+
+test iortrans-8.1 {seek flushes write buffers, ignores data} -setup {
+    set res {}
+} -match glob -body {
+    proc foo {args} {
+	handle.initialize flush
+	handle.finalize
+	lappend ::res $args
+	return X
+    }
+    set c [chan push [tempchan] foo]
+    # Flush, no writing
+    seek $c 2
+    # The close flushes again, this modifies the file!
+    lappend res |
+    lappend res [close $c] | [tempview]
+} -cleanup {
+    tempdone
+    rename foo {}
+} -result {{flush rt*} | {flush rt*} {} | {teXt data}}
+test iortrans-8.2 {close flushes write buffers, writes data} -setup {
+    set res {}
+} -match glob -body {
+    proc foo {args} {
+	handle.initialize flush
+	lappend ::res $args
+	handle.finalize
+	return .flushed.
+    }
+    set c [chan push [tempchan] foo]
+    close $c
+    lappend res [tempview]
+} -cleanup {
+    tempdone
+    rename foo {}
+} -result {{flush rt*} {finalize rt*} .flushed.}
+test iortrans-8.3 {chan flush, bug 2921116} -match glob -setup {
+    set res {}
+} -body {
+    proc foo {fd args} {
+	handle.initialize flush
+	handle.finalize
+	lappend ::res $args
+	# Kill and recreate transform while it is operating
+	chan pop $fd
+	chan push $fd [list foo $fd]
+    }
+    set c [chan push [set c [tempchan]] [list foo $c]]
+    seek $c 2
+    set res
+} -cleanup {
+    tempdone
+    rename foo {}
+} -result {{flush rt*}}
+
+# --- === *** ###########################
+# method watch - removed from TIP (rev 1.12+)
+
+# --- === *** ###########################
+# method event - removed from TIP (rev 1.12+)
+
+# --- === *** ###########################
+# 'Pull the rug' tests. Create channel in a interpreter A, move to other
+# interpreter B, destroy the origin interpreter (A) before or during access
+# from B. Must not crash, must return proper errors.
+test iortrans-11.0 {origin interpreter of moved transform gone} -setup {
+    set ida [interp create];	#puts <<$ida>>
+    set idb [interp create];	#puts <<$idb>>
+    # Magic to get the test* commands in the slaves
+    load {} Tcltest $ida
+    load {} Tcltest $idb
+} -constraints {testchannel} -match glob -body {
+    # Set up channel and transform in interpreter
+    interp eval $ida $helperscript
+    interp eval $ida [list ::variable tempchan [tempchan]]
+    interp transfer {} $::tempchan $ida
+    set chan [interp eval $ida {
+	variable tempchan
+	proc foo {args} {
+	    handle.initialize clear drain flush limit? read write
+	    handle.finalize
+	    lappend ::res $args
+	    return
+	}
+	set chan [chan push $tempchan foo]
+	fconfigure $chan -buffering none
+	set chan
+    }]
+    # Move channel to 2nd interpreter, transform goes with it.
+    interp eval $ida [list testchannel cut $chan]
+    interp eval $idb [list testchannel splice $chan]
+    # Kill origin interpreter, then access channel from 2nd interpreter.
+    interp delete $ida
+    set res {}
+    lappend res \
+	[catch {interp eval $idb [list puts $chan shoo]} msg] $msg \
+	[catch {interp eval $idb [list tell $chan]} msg] $msg \
+	[catch {interp eval $idb [list seek $chan 1]} msg] $msg \
+	[catch {interp eval $idb [list gets $chan]} msg] $msg \
+	[catch {interp eval $idb [list close $chan]} msg] $msg
+    #lappend res [interp eval $ida {set res}]
+    # actions: clear|write|clear|write|clear|flush|limit?|drain|flush
+    # The 'tell' is ok, as it passed through the transform to the base channel
+    # without invoking the transform handler.
+} -cleanup {
+    tempdone
+} -result {1 {Owner lost} 0 0 1 {Owner lost} 1 {Owner lost} 1 {Owner lost}}
+test iortrans-11.1 {origin interpreter of moved transform destroyed during access} -setup {
+    set ida [interp create];	#puts <<$ida>>
+    set idb [interp create];	#puts <<$idb>>
+    # Magic to get the test* commands in the slaves
+    load {} Tcltest $ida
+    load {} Tcltest $idb
+} -constraints {testchannel} -match glob -body {
+    # Set up channel in thread
+    set chan [interp eval $ida $helperscript]
+    interp eval $ida [list ::variable tempchan [tempchan]]
+    interp transfer {} $::tempchan $ida
+    set chan [interp eval $ida {
+	proc foo {args} {
+	    handle.initialize clear drain flush limit? read write
+	    handle.finalize
+	    lappend ::res $args
+	    # Destroy interpreter during channel access.
+	    suicide
+	}
+	set chan [chan push $tempchan foo]
+	fconfigure $chan -buffering none
+	set chan
+    }]
+    interp alias $ida suicide {} interp delete $ida
+    # Move channel to 2nd thread, transform goes with it.
+    interp eval $ida [list testchannel cut $chan]
+    interp eval $idb [list testchannel splice $chan]
+    # Run access from interpreter B, this will give us a synchronous response.
+    interp eval $idb [list set chan $chan]
+    interp eval $idb [list set mid $tcltest::mainThread]
+    set res [interp eval $idb {
+	# Wait a bit, give the main thread the time to start its event loop to
+	# wait for the response from B
+	after 50
+	catch { puts $chan shoo } res
+	set res
+    }]
+} -cleanup {
+    tempdone
+} -result {Owner lost}
+test iortrans-11.2 {delete interp of reflected transform} -setup {
+    interp create slave
+    # Magic to get the test* commands into the slave
+    load {} Tcltest slave
+} -constraints {testchannel} -body {
+    # Get base channel into the slave
+    set c [tempchan]
+    testchannel cut $c
+    interp eval slave [list testchannel splice $c]
+    interp eval slave [list set c $c]
+    slave eval {
+	proc no-op args {}
+	proc driver {c sub args} {
+	    return {initialize finalize read write}
+	}
+	set t [chan push $c [list driver $c]]
+	chan event $c readable no-op
+    }
+    interp delete slave
+} -cleanup {
+    tempdone
+} -result {}
+
+# ### ### ### ######### ######### #########
+## Same tests as above, but exercising the code forwarding and receiving
+## driver operations to the originator thread.
+
+# ### ### ### ######### ######### #########
+## Testing the reflected channel (Thread forwarding).
+#
+## The id numbers refer to the original test without thread forwarding, and
+## gaps due to tests not applicable to forwarding are left to keep this
+## association.
+
+# ### ### ### ######### ######### #########
+## Helper command. Runs a script in a separate thread and returns the result.
+## A channel is transfered into the thread as well, and a list of configuation
+## variables
+
+proc inthread {chan script args} {
+    # Test thread.
+    set tid [thread::create -preserved]
+    thread::send $tid {load {} Tcltest}
+
+    # Init thread configuration.
+    # - Listed variables
+    # - Id of main thread
+    # - A number of helper commands
+
+    foreach v $args {
+	upvar 1 $v x
+	thread::send $tid [list set $v $x]
+    }
+    thread::send $tid [list set mid [thread::id]]
+    thread::send $tid {
+	proc notes {} {
+	    return $::notes
+	}
+	proc noteOpts opts {
+	    lappend ::notes [dict merge {
+		-code !?! -level !?! -errorcode !?! -errorline !?!
+		-errorinfo !?! -errorstack !?!
+	    } $opts]
+	}
+    }
+    thread::send $tid [list proc s {} [list uplevel 1 $script]]; # (*)
+
+    # Transfer channel (cut/splice aka detach/attach)
+
+    testchannel cut $chan
+    thread::send $tid [list testchannel splice $chan]
+
+    # Run test script, also run local event loop!  The local event loop waits
+    # for the result to come back.  It is also necessary for the execution of
+    # forwarded channel operations.
+
+    set ::tres ""
+    thread::send -async $tid {	
+	after 50
+	catch {s} res;	# This runs the script, 's' was defined at (*)
+	thread::send -async $mid [list set ::tres $res]
+    }
+    vwait ::tres
+    # Remove test thread, and return the captured result.
+
+    thread::release $tid
+    return $::tres
+}
+
+# ### ### ### ######### ######### #########
+
+test iortrans.tf-3.2 {chan finalize, for close} -setup {
+    set res {}
+} -constraints {testchannel thread} -match glob -body {
+    proc foo {args} {
+	lappend ::res $args
+	handle.initialize
+	return {}
+    }
+    lappend res [set c [chan push [tempchan] foo]]
+    lappend res [inthread $c {
+	close $c
+	# Close the deleted the channel.
+	file channels rt*
+    } c]
+    # Channel destruction does not kill handler command!
+    lappend res [info command foo]
+} -cleanup {
+    rename foo {}
+} -result {{initialize rt* {read write}} file* {finalize rt*} {} foo}
+test iortrans.tf-3.3 {chan finalize, for close, error, close error} -setup {
+    set res {}
+} -constraints {testchannel thread} -match glob -body {
+    proc foo {args} {
+	lappend ::res $args
+	handle.initialize
+	return -code error 5
+    }
+    lappend res [set c [chan push [tempchan] foo]]
+    lappend res {*}[inthread $c {
+	lappend notes [catch {close $c} msg] $msg
+	# Channel is gone despite error.
+	lappend notes [file channels rt*]
+	notes
+    } c]
+} -cleanup {
+    rename foo {}
+} -result {{initialize rt* {read write}} file* {finalize rt*} 1 5 {}}
+test iortrans.tf-3.4 {chan finalize, for close, error, close errror} -setup {
+    set res {}
+} -constraints {testchannel thread} -body {
+    proc foo {args} {
+	lappend ::res $args
+	handle.initialize
+	error FOO
+    }
+    lappend res [set c [chan push [tempchan] foo]]
+    lappend res {*}[inthread $c {
+	lappend notes [catch {close $c} msg] $msg
+	notes
+    } c]
+} -match glob -cleanup {
+    rename foo {}
+} -result {{initialize rt* {read write}} file* {finalize rt*} 1 FOO}
+test iortrans.tf-3.5 {chan finalize, for close, arbitrary result} -setup {
+    set res {}
+} -constraints {testchannel thread} -match glob -body {
+    proc foo {args} {
+	lappend ::res $args
+	handle.initialize
+	return SOMETHING
+    }
+    lappend res [set c [chan push [tempchan] foo]]
+    lappend res {*}[inthread $c {
+	lappend notes [catch {close $c} msg] $msg
+	notes
+    } c]
+} -cleanup {
+    rename foo {}
+} -result {{initialize rt* {read write}} file* {finalize rt*} 0 {}}
+test iortrans.tf-3.6 {chan finalize, for close, break, close error} -setup {
+    set res {}
+} -constraints {testchannel thread} -match glob -body {
+    proc foo {args} {
+	lappend ::res $args
+	handle.initialize
+	return -code 3
+    }
+    lappend res [set c [chan push [tempchan] foo]]
+    lappend res {*}[inthread $c {
+	lappend notes [catch {close $c} msg] $msg
+	notes
+    } c]
+} -cleanup {
+    rename foo {}
+} -result {{initialize rt* {read write}} file* {finalize rt*} 1 *bad code*}
+test iortrans.tf-3.7 {chan finalize, for close, continue, close error} -setup {
+    set res {}
+} -constraints {testchannel thread} -match glob -body {
+    proc foo {args} {
+	lappend ::res $args
+	handle.initialize
+	return -code 4
+    }
+    lappend res [set c [chan push [tempchan] foo]]
+    lappend res {*}[inthread $c {
+	lappend notes [catch {close $c} msg] $msg
+	notes
+    } c]
+} -cleanup {
+    rename foo {}
+} -result {{initialize rt* {read write}} file* {finalize rt*} 1 *bad code*}
+test iortrans.tf-3.8 {chan finalize, for close, custom code, close error} -setup {
+    set res {}
+} -constraints {testchannel thread} -match glob -body {
+    proc foo {args} {
+	lappend ::res $args
+	handle.initialize
+	return -code 777 BANG
+    }
+    lappend res [set c [chan push [tempchan] foo]]
+    lappend res {*}[inthread $c {
+	lappend notes [catch {close $c} msg] $msg
+	notes
+    } c]
+} -cleanup {
+    rename foo {}
+} -result {{initialize rt* {read write}} file* {finalize rt*} 1 *bad code*}
+test iortrans.tf-3.9 {chan finalize, for close, ignore level, close error} -setup {
+    set res {}
+} -constraints {testchannel thread} -match glob -body {
+    proc foo {args} {
+	lappend ::res $args
+	handle.initialize
+	return -level 5 -code 777 BANG
+    }
+    lappend res [set c [chan push [tempchan] foo]]
+    lappend res {*}[inthread $c {
+	lappend notes [catch {close $c} msg opt] $msg
+	noteOpts $opt
+	notes
+    } c]
+} -cleanup {
+    rename foo {}
+} -result {{initialize rt* {read write}} file* {finalize rt*} 1 *bad code* {-code 1 -level 0 -errorcode NONE -errorline 1 -errorinfo *bad code*subcommand "finalize"*}}
+
+# --- === *** ###########################
+# method read
+
+test iortrans.tf-4.1 {chan read, transform call and return} -setup {
+    set res {}
+} -constraints {testchannel thread} -body {
+    proc foo {args} {
+	handle.initialize
+	handle.finalize
+	lappend ::res $args
+	return snarf
+    }
+    set c [chan push [tempchan] foo]
+    lappend res {*}[inthread $c {
+	lappend notes [read $c 10]
+	close $c
+	notes
+    } c]
+} -cleanup {
+    tempdone
+    rename foo {}
+} -match glob -result {{read rt* {test data
+}} snarf}
+test iortrans.tf-4.2 {chan read, for non-readable channel} -setup {
+    set res {}
+} -constraints {testchannel thread} -body {
+    proc foo {args} {
+	handle.initialize
+	handle.finalize
+	lappend ::res $args MUST_NOT_HAPPEN
+    }
+    set c [chan push [tempchan w] foo]
+    lappend res {*}[inthread $c {
+	lappend notes [catch {[read $c 2]} msg] $msg
+	close $c
+	notes
+    } c]
+} -cleanup {
+    tempdone
+    rename foo {}
+} -match glob -result {1 {channel "file*" wasn't opened for reading}}
+test iortrans.tf-4.3 {chan read, error return} -setup {
+    set res {}
+} -constraints {testchannel thread} -body {
+    proc foo {args} {
+	handle.initialize
+	handle.finalize
+	lappend ::res $args
+	return -code error BOOM!
+    }
+    set c [chan push [tempchan] foo]
+    lappend res {*}[inthread $c {
+	lappend notes [catch {read $c 2} msg] $msg
+	close $c
+	notes
+    } c]
+} -cleanup {
+    tempdone
+    rename foo {}
+} -match glob -result {{read rt* {test data
+}} 1 BOOM!}
+test iortrans.tf-4.4 {chan read, break return is error} -setup {
+    set res {}
+} -constraints {testchannel thread} -body {
+    proc foo {args} {
+	handle.initialize
+	handle.finalize
+	lappend ::res $args
+	return -code break BOOM!
+    }
+    set c [chan push [tempchan] foo]
+    lappend res {*}[inthread $c {
+	lappend notes [catch {read $c 2} msg] $msg
+	close $c
+	notes
+    } c]
+} -cleanup {
+    tempdone
+    rename foo {}
+} -match glob -result {{read rt* {test data
+}} 1 *bad code*}
+test iortrans.tf-4.5 {chan read, continue return is error} -setup {
+    set res {}
+} -constraints {testchannel thread} -body {
+    proc foo {args} {
+	handle.initialize
+	handle.finalize
+	lappend ::res $args
+	return -code continue BOOM!
+    }
+    set c [chan push [tempchan] foo]
+    lappend res {*}[inthread $c {
+	lappend notes [catch {read $c 2} msg] $msg
+	close $c
+	notes
+    } c]
+} -cleanup {
+    tempdone
+    rename foo {}
+} -match glob -result {{read rt* {test data
+}} 1 *bad code*}
+test iortrans.tf-4.6 {chan read, custom return is error} -setup {
+    set res {}
+} -constraints {testchannel thread} -body {
+    proc foo {args} {
+	handle.initialize
+	handle.finalize
+	lappend ::res $args
+	return -code 777 BOOM!
+    }
+    set c [chan push [tempchan] foo]
+    lappend res {*}[inthread $c {
+	lappend notes [catch {read $c 2} msg] $msg
+	close $c
+	notes
+    } c]
+} -cleanup {
+    tempdone
+    rename foo {}
+} -match glob -result {{read rt* {test data
+}} 1 *bad code*}
+test iortrans.tf-4.7 {chan read, level is squashed} -setup {
+    set res {}
+} -constraints {testchannel thread} -body {
+    proc foo {args} {
+	handle.initialize
+	handle.finalize
+	lappend ::res $args
+	return -level 55 -code 777 BOOM!
+    }
+    set c [chan push [tempchan] foo]
+    lappend res {*}[inthread $c {
+	lappend notes [catch {read $c 2} msg opt] $msg
+	noteOpts $opt
+	close $c
+	notes
+    } c]
+} -cleanup {
+    tempdone
+    rename foo {}
+} -match glob -result {{read rt* {test data
+}} 1 *bad code* {-code 1 -level 0 -errorcode NONE -errorline 1 -errorinfo *bad code*subcommand "read"*}}
+
+# --- === *** ###########################
+# method write
+
+test iortrans.tf-5.1 {chan write, regular write} -setup {
+    set res {}
+} -constraints {testchannel thread} -match glob -body {
+    proc foo {args} {
+	handle.initialize
+	handle.finalize
+	lappend ::res $args
+	return transformresult
+    }
+    set c [chan push [tempchan] foo]
+    inthread $c {
+	puts -nonewline $c snarf
+	flush $c
+	close $c
+    } c
+    lappend res [tempview]
+} -cleanup {
+    tempdone
+    rename foo {}
+} -result {{write rt* snarf} transformresult}
+test iortrans.tf-5.2 {chan write, no write is ok, no change to file} -setup {
+    set res {}
+} -constraints {testchannel thread} -match glob -body {
+    proc foo {args} {
+	handle.initialize
+	handle.finalize
+	lappend ::res $args
+	return
+    }
+    set c [chan push [tempchan] foo]
+    inthread $c {
+	puts -nonewline $c snarfsnarfsnarf
+	flush $c
+	close $c
+    } c
+    lappend res [tempview];	# This has to show the original data, as nothing was written
+} -cleanup {
+    tempdone
+    rename foo {}
+} -result {{write rt* snarfsnarfsnarf} {test data}}
+test iortrans.tf-5.3 {chan write, failed write} -setup {
+    set res {}
+} -constraints {testchannel thread} -match glob -body {
+    proc foo {args} {
+	handle.initialize
+	handle.finalize
+	lappend ::res $args
+	return -code error FAIL!
+    }
+    set c [chan push [tempchan] foo]
+    lappend res {*}[inthread $c {
+	puts -nonewline $c snarfsnarfsnarf
+	lappend notes [catch {flush $c} msg] $msg
+	close $c
+	notes
+    } c]
+} -cleanup {
+    tempdone
+    rename foo {}
+} -result {{write rt* snarfsnarfsnarf} 1 FAIL!}
+test iortrans.tf-5.4 {chan write, non-writable channel} -setup {
+    set res {}
+} -constraints {testchannel thread} -match glob -body {
+    proc foo {args} {
+	handle.initialize
+	handle.finalize
+	lappend ::res $args MUST_NOT_HAPPEN
+	return
+    }
+    set c [chan push [tempchan r] foo]
+    lappend res {*}[inthread $c {
+	lappend notes [catch {
+	    puts -nonewline $c snarfsnarfsnarf
+	    flush $c
+	} msg] $msg
+	close $c
+	notes
+    } c]
+} -cleanup {
+    tempdone
+    rename foo {}
+} -result {1 {channel "file*" wasn't opened for writing}}
+test iortrans.tf-5.5 {chan write, failed write, error return} -setup {
+    set res {}
+} -constraints {testchannel thread} -match glob -body {
+    proc foo {args} {
+	handle.initialize
+	handle.finalize
+	lappend ::res $args
+	return -code error BOOM!
+    }
+    set c [chan push [tempchan] foo]
+    lappend res {*}[inthread $c {
+	lappend notes [catch {
+	    puts -nonewline $c snarfsnarfsnarf
+	    flush $c
+	} msg] $msg
+	close $c
+	notes
+    } c]
+} -cleanup {
+    tempdone
+    rename foo {}
+} -result {{write rt* snarfsnarfsnarf} 1 BOOM!}
+test iortrans.tf-5.6 {chan write, failed write, error return} -setup {
+    set res {}
+} -constraints {testchannel thread} -match glob -body {
+    proc foo {args} {
+	handle.initialize
+	handle.finalize
+	lappend ::res $args
+	error BOOM!
+    }
+    set c [chan push [tempchan] foo]
+    lappend res {*}[inthread $c {
+	lappend notes [catch {
+	    puts -nonewline $c snarfsnarfsnarf
+	    flush $c
+	} msg] $msg
+	close $c
+	notes
+    } c]
+} -cleanup {
+    tempdone
+    rename foo {}
+} -result {{write rt* snarfsnarfsnarf} 1 BOOM!}
+test iortrans.tf-5.7 {chan write, failed write, break return is error} -setup {
+    set res {}
+} -constraints {testchannel thread} -match glob -body {
+    proc foo {args} {
+	handle.initialize
+	handle.finalize
+	lappend ::res $args
+	return -code break BOOM!
+    }
+    set c [chan push [tempchan] foo]
+    lappend res {*}[inthread $c {
+	lappend notes [catch {
+	    puts -nonewline $c snarfsnarfsnarf
+	    flush $c
+	} msg] $msg
+	close $c
+	notes
+    } c]
+} -cleanup {
+    tempdone
+    rename foo {}
+} -result {{write rt* snarfsnarfsnarf} 1 *bad code*}
+test iortrans.tf-5.8 {chan write, failed write, continue return is error} -setup {
+    set res {}
+} -constraints {testchannel thread} -match glob -body {
+    proc foo {args} {
+	handle.initialize
+	handle.finalize
+	lappend ::res $args
+	return -code continue BOOM!
+    }
+    set c [chan push [tempchan] foo]
+    lappend res {*}[inthread $c {
+	lappend notes [catch {
+	    puts -nonewline $c snarfsnarfsnarf
+	    flush $c
+	} msg] $msg
+	close $c
+	notes
+    } c]
+} -cleanup {
+    rename foo {}
+} -result {{write rt* snarfsnarfsnarf} 1 *bad code*}
+test iortrans.tf-5.9 {chan write, failed write, custom return is error} -setup {
+    set res {}
+} -constraints {testchannel thread} -body {
+    proc foo {args} {
+	handle.initialize
+	handle.finalize
+	lappend ::res $args
+	return -code 777 BOOM!
+    }
+    set c [chan push [tempchan] foo]
+    lappend res {*}[inthread $c {
+	lappend notes [catch {
+	    puts -nonewline $c snarfsnarfsnarf
+	    flush $c
+	} msg] $msg
+	close $c
+	notes
+    } c]
+} -cleanup {
+    tempdone
+    rename foo {}
+} -match glob -result {{write rt* snarfsnarfsnarf} 1 *bad code*}
+test iortrans.tf-5.10 {chan write, failed write, level is ignored} -setup {
+    set res {}
+} -constraints {testchannel thread} -match glob -body {
+    proc foo {args} {
+	handle.initialize
+	handle.finalize
+	lappend ::res $args
+	return -level 55 -code 777 BOOM!
+    }
+    set c [chan push [tempchan] foo]
+    lappend res {*}[inthread $c {
+	lappend notes [catch {
+	    puts -nonewline $c snarfsnarfsnarf
+	    flush $c
+	} msg opt] $msg
+	noteOpts $opt
+	close $c
+	notes
+    } c]
+} -cleanup {
+    tempdone
+    rename foo {}
+} -result {{write rt* snarfsnarfsnarf} 1 *bad code* {-code 1 -level 0 -errorcode NONE -errorline * -errorinfo *bad code*subcommand "write"*}}
+
+# --- === *** ###########################
+# method limit?, drain (via read)
+
+test iortrans.tf-6.1 {chan read, read limits} -setup {
+    set res {}
+} -constraints {testchannel thread} -match glob -body {
+    proc foo {args} {
+	handle.initialize limit?
+	handle.finalize
+	lappend ::res $args
+	handle.read
+	return 6
+    }
+    set c [chan push [tempchan] foo]
+    lappend res {*}[inthread $c {
+	lappend notes [read $c 10]
+	close $c
+	notes
+    } c]
+} -cleanup {
+    tempdone
+    rename foo {}
+} -result {{limit? rt*} {read rt* {test d}} {limit? rt*} {read rt* {ata
+}} {limit? rt*} @@}
+test iortrans.tf-6.2 {chan read, read transform drain on eof} -setup {
+    set res {}
+} -constraints {testchannel thread} -match glob -body {
+    proc foo {args} {
+	handle.initialize drain
+	handle.finalize
+	lappend ::res $args
+	handle.read
+	handle.drain
+	return
+    }
+    set c [chan push [tempchan] foo]
+    lappend res {*}[inthread $c {
+	lappend notes [read $c]
+	lappend notes [close $c]
+    } c]
+} -cleanup {
+    tempdone
+    rename foo {}
+} -result {{read rt* {test data
+}} {drain rt*} @<> {}}
+
+# --- === *** ###########################
+# method clear (via puts, seek)
+
+test iortrans.tf-7.1 {chan write, write clears read buffers} -setup {
+    set res {}
+} -constraints {testchannel thread} -match glob -body {
+    proc foo {args} {
+	handle.initialize clear
+	handle.finalize
+	lappend ::res $args
+	handle.clear
+	return transformresult
+    }
+    set c [chan push [tempchan] foo]
+    inthread $c {
+	puts -nonewline $c snarf
+	flush $c
+	close $c
+    } c
+    return $res
+} -cleanup {
+    tempdone
+    rename foo {}
+} -result {{clear rt*} {write rt* snarf}}
+test iortrans.tf-7.2 {seek clears read buffers} -setup {
+    set res {}
+} -constraints {testchannel thread} -match glob -body {
+    proc foo {args} {
+	handle.initialize clear
+	handle.finalize
+	lappend ::res $args
+	return
+    }
+    set c [chan push [tempchan] foo]
+    inthread $c {
+	seek $c 2
+	close $c
+    } c
+    return $res
+} -cleanup {
+    tempdone
+    rename foo {}
+} -result {{clear rt*}}
+test iortrans.tf-7.3 {clear, any result is ignored} -setup {
+    set res {}
+} -constraints {testchannel thread} -match glob -body {
+    proc foo {args} {
+	handle.initialize clear
+	handle.finalize
+	lappend ::res $args
+	return -code error "X"
+    }
+    set c [chan push [tempchan] foo]
+    inthread $c {
+	seek $c 2
+	close $c
+    } c
+    return $res
+} -cleanup {
+    tempdone
+    rename foo {}
+} -result {{clear rt*}}
+
+# --- === *** ###########################
+# method flush (via seek, close)
+
+test iortrans.tf-8.1 {seek flushes write buffers, ignores data} -setup {
+    set res {}
+} -constraints {testchannel thread} -match glob -body {
+    proc foo {args} {
+	handle.initialize flush
+	handle.finalize
+	lappend ::res $args
+	return X
+    }
+    set c [chan push [tempchan] foo]
+    lappend res {*}[inthread $c {
+	# Flush, no writing
+	seek $c 2
+	# The close flushes again, this modifies the file!
+	lappend notes | [close $c] |
+	# NOTE: The flush generated by the close is recorded immediately, the
+	# other note's here are defered until after the thread is done. This
+	# changes the order of the result a bit from the non-threaded case
+	# (The first | moves one to the right). This is an artifact of the
+	# 'inthread' framework, not of the transformation itself.
+	notes
+    } c]
+    lappend res [tempview]
+} -cleanup {
+    tempdone
+    rename foo {}
+} -result {{flush rt*} {flush rt*} | {} | {teXt data}}
+test iortrans.tf-8.2 {close flushes write buffers, writes data} -setup {
+    set res {}
+} -constraints {testchannel thread} -match glob -body {
+    proc foo {args} {
+	handle.initialize flush
+	lappend ::res $args
+	handle.finalize
+	return .flushed.
+    }
+    set c [chan push [tempchan] foo]
+    inthread $c {
+	close $c
+    } c
+    lappend res [tempview]
+} -cleanup {
+    tempdone
+    rename foo {}
+} -result {{flush rt*} {finalize rt*} .flushed.}
+
+# --- === *** ###########################
+# method watch - removed from TIP (rev 1.12+)
+
+# --- === *** ###########################
+# method event - removed from TIP (rev 1.12+)
+
+# --- === *** ###########################
+# 'Pull the rug' tests. Create channel in a thread A, move to other thread B,
+# destroy the origin thread (A) before or during access from B. Must not
+# crash, must return proper errors.
+
+test iortrans.tf-11.0 {origin thread of moved transform gone} -setup {
+    #puts <<$tcltest::mainThread>>main
+    set tida [thread::create -preserved];	#puts <<$tida>>
+    thread::send $tida {load {} Tcltest}
+    set tidb [thread::create -preserved];	#puts <<$tida>>
+    thread::send $tidb {load {} Tcltest}
+} -constraints {testchannel thread} -match glob -body {
+    # Set up channel in thread
+    thread::send $tida $helperscript
+    thread::send $tidb $helperscript
+    set chan [thread::send $tida {
+	proc foo {args} {
+	    handle.initialize clear drain flush limit? read write
+	    handle.finalize
+	    lappend ::res $args
+	    return
+	}
+	set chan [chan push [tempchan] foo]
+	fconfigure $chan -buffering none
+	set chan
+    }]
+
+    # Move channel to 2nd thread, transform goes with it.
+    thread::send $tida [list testchannel cut $chan]
+    thread::send $tidb [list testchannel splice $chan]
+
+    # Kill origin thread, then access channel from 2nd thread.
+    thread::release -wait $tida
+
+    set res {}
+    lappend res [catch {thread::send $tidb [list puts $chan shoo]} msg] $msg
+    lappend res [catch {thread::send $tidb [list tell $chan]} msg] $msg
+    lappend res [catch {thread::send $tidb [list seek $chan 1]} msg] $msg
+    lappend res [catch {thread::send $tidb [list gets $chan]} msg] $msg
+    lappend res [catch {thread::send $tidb [list close $chan]} msg] $msg
+    # The 'tell' is ok, as it passed through the transform to the base
+    # channel without invoking the transform handler.
+} -cleanup {
+    thread::send $tidb tempdone
+    thread::release $tidb
+} -result {1 {Owner lost} 0 0 1 {Owner lost} 1 {Owner lost} 1 {Owner lost}}
+
+testConstraint notValgrind [expr {![testConstraint valgrind]}]
+
+test iortrans.tf-11.1 {origin thread of moved transform destroyed during access} -setup {
+    #puts <<$tcltest::mainThread>>main
+    set tida [thread::create -preserved];	#puts <<$tida>>
+    thread::send $tida {load {} Tcltest}
+    set tidb [thread::create -preserved];	#puts <<$tidb>>
+    thread::send $tidb {load {} Tcltest}
+} -constraints {testchannel thread notValgrind} -match glob -body {
+    # Set up channel in thread
+    thread::send $tida $helperscript
+    thread::send $tidb $helperscript
+    set chan [thread::send $tida {
+	proc foo {args} {
+	    handle.initialize clear drain flush limit? read write
+	    handle.finalize
+	    lappend ::res $args
+	    # destroy thread during channel access
+	    thread::exit
+	}
+	set chan [chan push [tempchan] foo]
+	fconfigure $chan -buffering none
+	set chan
+    }]
+
+    # Move channel to 2nd thread, transform goes with it.
+    thread::send $tida [list testchannel cut $chan]
+    thread::send $tidb [list testchannel splice $chan]
+
+    # Run access from thread B, wait for response from A (A is not using event
+    # loop at this point, so the event pile up in the queue.
+    thread::send $tidb [list set chan $chan]
+    thread::send $tidb [list set mid [thread::id]]
+    thread::send -async $tidb {
+	# Wait a bit, give the main thread the time to start its event loop to
+	# wait for the response from B
+	after 50
+	catch { puts $chan shoo } res
+	catch { close $chan }
+	thread::send -async $mid [list set ::res $res]
+    }
+    vwait ::res
+    set res
+} -cleanup {
+    thread::send $tidb tempdone
+    thread::release $tidb
+} -result {Owner lost}
+
+# ### ### ### ######### ######### #########
+
+cleanupTests
+return
diff --git a/tests/iogt.test b/tests/iogt.test
new file mode 100644
index 0000000..1ed89f7
--- /dev/null
+++ b/tests/iogt.test
@@ -0,0 +1,955 @@
+# -*- tcl -*-
+# Commands covered:  transform, and stacking in general
+#
+# This file contains a collection of tests for Giot
+#
+# See the file "license.terms" for information on usage and redistribution of
+# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+# 
+# Copyright (c) 2000 Ajuba Solutions.
+# Copyright (c) 2000 Andreas Kupries.
+# All rights reserved.
+
+if {[catch {package require tcltest 2.1}]} {
+    puts stderr "Skipping tests in [info script].  tcltest 2.1 required."
+    return
+}
+
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
+
+namespace eval ::tcl::test::iogt {
+    namespace import ::tcltest::*
+
+testConstraint testchannel [llength [info commands testchannel]]
+
+set path(dummy) [makeFile {abcdefghijklmnopqrstuvwxyz0123456789,./?><;'\|":[]\}\{`~!@#$%^&*()_+-=
+} dummy]
+
+# " capture coloring of quotes
+
+set path(dummyout) [makeFile {} dummyout]
+
+set path(__echo_srv__.tcl) [makeFile {
+#!/usr/local/bin/tclsh
+# -*- tcl -*-
+# echo server
+#
+# arguments, options: port to listen on for connections.
+#                     delay till echo of first block
+#                     delay between blocks
+#                     blocksize ...
+
+set port [lindex $argv 0]
+set fdelay [lindex $argv 1]
+set idelay [lindex $argv 2]
+set bsizes [lrange $argv 3 end]
+set c 0
+
+proc newconn {sock rhost rport} {
+    variable fdelay
+    variable c
+    incr c
+    namespace upvar [namespace current] c$c conn
+
+    #puts stdout "C $sock $rhost $rport / $fdelay" ; flush stdout
+
+    set conn(after) {}
+    set conn(state) 0
+    set conn(size) 0
+    set conn(data) ""
+    set conn(delay) $fdelay
+
+    fileevent $sock readable [list echoGet $c $sock]
+    fconfigure $sock -translation binary -buffering none -blocking 0
+}
+
+proc echoGet {c sock} {
+    variable fdelay
+    namespace upvar [namespace current] c$c conn
+
+    if {[eof $sock]} {
+	# one-shot echo
+	exit
+    }
+    append conn(data) [read $sock]
+
+    #puts stdout "G $c $sock $conn(data) <<$conn(data)>>" ; flush stdout
+
+    if {$conn(after) == {}} {
+	set conn(after) [after $conn(delay) [list echoPut $c $sock]]
+    }
+}
+
+proc echoPut {c sock} {
+    variable idelay
+    variable fdelay
+    variable bsizes
+    namespace upvar [namespace current] c$c conn
+
+    if {[string length $conn(data)] == 0} {
+	#puts stdout "C $c $sock" ; flush stdout
+	# auto terminate
+	close $sock
+	exit
+	#set conn(delay) $fdelay
+	return
+    }
+
+    set conn(delay) $idelay
+    set n [lindex $bsizes $conn(size)]
+
+    #puts stdout "P $c $sock $n >>" ; flush stdout
+
+    #puts __________________________________________
+    #parray conn
+    #puts n=<$n>
+
+    if {[string length $conn(data)] >= $n} {
+	puts -nonewline $sock [string range $conn(data) 0 $n]
+	set conn(data) [string range $conn(data) [incr n] end]
+    }
+
+    incr conn(size)
+    if {$conn(size) >= [llength $bsizes]} {
+	set conn(size) [expr {[llength $bsizes]-1}]
+    }
+
+    set conn(after) [after $conn(delay) [list echoPut $c $sock]]
+}
+
+#fileevent stdin readable {exit ;#cut}
+
+# main
+socket -server newconn -myaddr 127.0.0.1 $port
+vwait forever
+} __echo_srv__.tcl]
+
+########################################################################
+
+proc fevent {fdelay idelay blocks script data} {
+    # Start and initialize an echo server, prepare data transmission, then
+    # hand over to the test script.  This has to start real transmission via
+    # 'flush'.  The server is stopped after completion of the test.
+
+    upvar 1 sock sk
+
+    # Fixed port, not so good. Lets hope for the best, for now.
+    set port 4000
+
+    exec tclsh __echo_srv__.tcl $port $fdelay $idelay {*}$blocks >@stdout &
+    after 500
+
+    #puts stdout "> $port"; flush stdout
+
+    set sk [socket localhost $port]
+    fconfigure $sk -blocking 0 -buffering full \
+	-buffersize [expr {10+[llength $data]}]
+    puts -nonewline $sk $data
+
+    # The channel is prepared to go off.
+
+    #puts stdout ">>>>>"; flush stdout
+
+    set res [uplevel 1 $script]
+    catch {close $sk}
+    return $res
+}
+
+# --------------------------------------------------------------
+# utility transformations ...
+
+proc id {op data} {
+    switch -- $op {
+	create/write - create/read - delete/write - delete/read - clear_read {
+	    #ignore
+	}
+	flush/write - flush/read - write - read {
+	    return $data
+	}
+	query/maxRead {
+	    return -1
+	}
+    }
+}
+
+proc id_optrail {var op data} {
+    variable $var
+    upvar 0 $var trail
+
+    lappend trail $op
+    switch -- $op {
+	create/write - create/read - delete/write - delete/read -
+	flush/read - clear/read {
+	    #ignore
+	}
+	flush/write - write - read {
+	    return $data
+	}
+	query/maxRead {
+	    return -1
+	}
+	default {
+	    lappend trail "error $op"
+	    error $op
+	}
+    }
+}
+
+proc id_fulltrail {var op data} {
+    namespace upvar [namespace current] $var trail
+
+    #puts stdout ">> $var $op $data" ; flush stdout
+
+    switch -- $op {
+	create/write - create/read - delete/write - delete/read - clear_read {
+	    set res *ignored*
+	}
+	flush/write - flush/read - write - read {
+	    set res $data
+	}
+	query/maxRead {
+	    set res -1
+	}
+    }
+
+    #catch {puts stdout "\t>* $res" ; flush stdout}
+    #catch {puts stdout "x$res"} msg
+
+    lappend trail [list $op $data $res]
+    return $res
+}
+
+proc id_torture {chan op data} {
+    switch -- $op {
+	create/write -
+	create/read  -
+	delete/write -
+	delete/read  -
+	clear_read   {;#ignore}
+	flush/write -
+	flush/read  {}
+	write       {
+	    global level
+	    if {$level} {
+		return
+	    }
+	    incr level
+	    testchannel unstack $chan
+	    testchannel transform $chan \
+		-command [namespace code [list id_torture $chan]]
+	    return $data
+	}
+	read        {
+	    testchannel unstack $chan
+	    testchannel transform $chan \
+		-command [namespace code [list id_torture $chan]]
+	    return $data
+	}
+	query/maxRead {return -1}
+    }
+}
+
+proc counter {var op data} {
+    namespace upvar [namespace current] $var n
+
+    switch -- $op {
+	create/write - create/read - delete/write - delete/read - clear_read {
+	    #ignore
+	}
+	flush/write - flush/read {
+	    return {}
+	}
+	write {
+	    return $data
+	}
+	read {
+	    if {$n > 0} {
+		incr n -[string length $data]
+		if {$n < 0} {
+		    set n 0
+		}
+	    }
+	    return $data
+	}
+	query/maxRead {
+	    return $n
+	}
+    }
+}
+
+proc counter_audit {var vtrail op data} {
+    namespace upvar [namespace current] $var n $vtrail trail
+
+    switch -- $op {
+	create/write - create/read - delete/write - delete/read - clear_read {
+	    set res {}
+	}
+	flush/write - flush/read {
+	    set res {}
+	}
+	write {
+	    set res $data
+	}
+	read {
+	    if {$n > 0} {
+		incr n -[string length $data]
+		if {$n < 0} {
+		    set n 0
+		}
+	    }
+	    set res $data
+	}
+	query/maxRead {
+	    set res $n
+	}
+    }
+
+    lappend trail [list counter:$op $data $res]
+    return $res
+}
+
+proc rblocks {var vtrail n op data} {
+    namespace upvar [namespace current] $var buf $vtrail trail
+
+    set res {}
+
+    switch -- $op {
+	create/write - create/read - delete/write - delete/read - clear_read {
+	    set buf {}
+	}
+	flush/write {
+	}
+	flush/read {
+	    set res $buf
+	    set buf {}
+	}
+	write {
+	    set data
+	}
+	read {
+	    append buf $data
+	    set b [expr {$n * ([string length $buf] / $n)}]
+	    append op " $n [string length $buf] :- $b"
+	    set res [string range $buf 0 [incr b -1]]
+	    set buf [string range $buf [incr b] end]
+	    #return $res
+	}
+	query/maxRead {
+	    set res -1
+	}
+    }
+
+    lappend trail [list rblock | $op $data $res | $buf]
+    return $res
+}
+
+# --------------------------------------------------------------
+# ... and convenience procedures to stack them
+
+proc identity {-attach channel} {
+    testchannel transform $channel -command [namespace code id]
+}
+proc audit_ops {var -attach channel} {
+    testchannel transform $channel -command [namespace code [list id_optrail $var]]
+}
+proc audit_flow {var -attach channel} {
+    testchannel transform $channel -command [namespace code [list id_fulltrail $var]]
+}
+
+proc torture {-attach channel} {
+    testchannel transform $channel -command [namespace code [list id_torture $channel]]
+}
+
+proc stopafter {var n -attach channel} {
+    namespace upvar [namespace current] $var vn
+    set vn $n
+    testchannel transform $channel -command [namespace code [list counter $var]]
+}
+proc stopafter_audit {var trail n -attach channel} {
+    namespace upvar [namespace current] $var vn
+    set vn $n
+    testchannel transform $channel -command [namespace code [list counter_audit $var $trail]]
+}
+proc rblocks_t {var trail n -attach channel} {
+    testchannel transform $channel -command [namespace code [list rblocks $var $trail $n]]
+}
+
+# --------------------------------------------------------------
+# serialize an array, with keys in sorted order.
+
+proc array_sget {v} {
+    upvar $v a
+    set res [list]
+    foreach n [lsort [array names a]] {
+	lappend res $n $a($n)
+    }
+    set res
+}
+proc asort {alist} {
+    # sort a list of key/value pairs by key, removes duplicates too.
+    array set a $alist
+    array_sget a
+}
+
+########################################################################
+
+test iogt-1.1 {stack/unstack} testchannel {
+    set fh [open $path(dummy) r]
+    identity -attach $fh
+    testchannel unstack $fh
+    close $fh
+} {}
+test iogt-1.2 {stack/close} testchannel {
+    set fh [open $path(dummy) r]
+    identity -attach $fh
+    close $fh
+} {}
+test iogt-1.3 {stack/unstack, configuration, options} testchannel {
+    set fh [open $path(dummy) r]
+    set ca [asort [fconfigure $fh]]
+    identity -attach $fh
+    set cb [asort [fconfigure $fh]]
+    testchannel unstack $fh
+    set cc [asort [fconfigure $fh]]
+    close $fh
+    # With this system none of the buffering, translation and encoding option
+    # may change their values with channels stacked upon each other or not.
+    # cb == ca == cc
+    list [string equal $ca $cb] [string equal $cb $cc] [string equal $ca $cc]
+} {1 1 1}
+test iogt-1.4 {stack/unstack, configuration} -setup {
+    set fh [open $path(dummy) r]
+} -constraints testchannel -body {
+    set ca [asort [fconfigure $fh]]
+    identity -attach $fh
+    fconfigure $fh -buffering line -translation cr -encoding shiftjis
+    testchannel unstack $fh
+    set cc [asort [fconfigure $fh]]
+    list [string equal $ca $cc] [fconfigure $fh -buffering] \
+	[fconfigure $fh -translation] [fconfigure $fh -encoding]
+} -cleanup {
+    close $fh
+} -result {0 line cr shiftjis}
+
+test iogt-2.0 {basic I/O going through transform} -setup {
+    set fin [open $path(dummy) r]
+    set fout [open $path(dummyout) w]
+} -constraints testchannel -body {
+    identity -attach $fin
+    identity -attach $fout
+    fcopy $fin $fout
+    close $fin
+    close $fout
+    set fin [open $path(dummy) r]
+    set fout [open $path(dummyout) r]
+    list [string equal [set in [read $fin]] [set out [read $fout]]] \
+	[string length $in] [string length $out]
+} -cleanup {
+    close $fin
+    close $fout
+} -result {1 71 71}
+test iogt-2.1 {basic I/O, operation trail} {testchannel unix} {
+    set fin [open $path(dummy) r]
+    set fout [open $path(dummyout) w]
+    set ain [list]; set aout [list]
+    audit_ops ain -attach $fin
+    audit_ops aout -attach $fout
+    fconfigure $fin -buffersize 10
+    fconfigure $fout -buffersize 10
+    fcopy $fin $fout
+    close $fin
+    close $fout
+    set res "[join $ain \n]\n--------\n[join $aout \n]"
+} {create/read
+query/maxRead
+read
+query/maxRead
+read
+query/maxRead
+read
+query/maxRead
+read
+query/maxRead
+read
+query/maxRead
+read
+query/maxRead
+read
+query/maxRead
+read
+query/maxRead
+flush/read
+query/maxRead
+delete/read
+--------
+create/write
+write
+write
+write
+write
+write
+write
+write
+write
+flush/write
+delete/write}
+test iogt-2.2 {basic I/O, data trail} {testchannel unix} {
+    set fin [open $path(dummy) r]
+    set fout [open $path(dummyout) w]
+    set ain [list]; set aout [list]
+    audit_flow ain -attach $fin
+    audit_flow aout -attach $fout
+    fconfigure $fin -buffersize 10
+    fconfigure $fout -buffersize 10
+    fcopy $fin $fout
+    close $fin
+    close $fout
+    set res "[join $ain \n]\n--------\n[join $aout \n]"
+} {create/read {} *ignored*
+query/maxRead {} -1
+read abcdefghij abcdefghij
+query/maxRead {} -1
+read klmnopqrst klmnopqrst
+query/maxRead {} -1
+read uvwxyz0123 uvwxyz0123
+query/maxRead {} -1
+read 456789,./? 456789,./?
+query/maxRead {} -1
+read {><;'\|":[]} {><;'\|":[]}
+query/maxRead {} -1
+read {\}\{`~!@#$} {\}\{`~!@#$}
+query/maxRead {} -1
+read %^&*()_+-= %^&*()_+-=
+query/maxRead {} -1
+read {
+} {
+}
+query/maxRead {} -1
+flush/read {} {}
+query/maxRead {} -1
+delete/read {} *ignored*
+--------
+create/write {} *ignored*
+write abcdefghij abcdefghij
+write klmnopqrst klmnopqrst
+write uvwxyz0123 uvwxyz0123
+write 456789,./? 456789,./?
+write {><;'\|":[]} {><;'\|":[]}
+write {\}\{`~!@#$} {\}\{`~!@#$}
+write %^&*()_+-= %^&*()_+-=
+write {
+} {
+}
+flush/write {} {}
+delete/write {} *ignored*}
+test iogt-2.3 {basic I/O, mixed trail} {testchannel unix} {
+    set fin [open $path(dummy) r]
+    set fout [open $path(dummyout) w]
+    set trail [list]
+    audit_flow trail -attach $fin
+    audit_flow trail -attach $fout
+    fconfigure $fin -buffersize 20
+    fconfigure $fout -buffersize 10
+    fcopy $fin $fout
+    close $fin
+    close $fout
+    join $trail \n
+} {create/read {} *ignored*
+create/write {} *ignored*
+query/maxRead {} -1
+read abcdefghijklmnopqrst abcdefghijklmnopqrst
+write abcdefghij abcdefghij
+write klmnopqrst klmnopqrst
+query/maxRead {} -1
+read uvwxyz0123456789,./? uvwxyz0123456789,./?
+write uvwxyz0123 uvwxyz0123
+write 456789,./? 456789,./?
+query/maxRead {} -1
+read {><;'\|":[]\}\{`~!@#$} {><;'\|":[]\}\{`~!@#$}
+write {><;'\|":[]} {><;'\|":[]}
+write {\}\{`~!@#$} {\}\{`~!@#$}
+query/maxRead {} -1
+read {%^&*()_+-=
+} {%^&*()_+-=
+}
+query/maxRead {} -1
+flush/read {} {}
+write %^&*()_+-= %^&*()_+-=
+write {
+} {
+}
+query/maxRead {} -1
+delete/read {} *ignored*
+flush/write {} {}
+delete/write {} *ignored*}
+
+test iogt-2.4 {basic I/O, mixed trail} {testchannel} {
+    set fh [open $path(dummy) r]
+    torture -attach $fh
+    chan configure $fh -buffersize 2
+    set x [read $fh]
+    testchannel unstack $fh
+    close   $fh
+    set x
+} {}
+test iogt-2.5 {basic I/O, mixed trail} {testchannel} {
+    set ::level 0
+    set fh [open $path(dummyout) w]
+    torture -attach $fh
+    puts -nonewline $fh abcdef
+    flush $fh
+    testchannel unstack $fh
+    close   $fh
+} {}
+
+test iogt-3.0 {Tcl_Channel valid after stack/unstack, fevent handling} -setup {
+    proc DoneCopy {n {err {}}} {
+	variable copy 1
+    }
+} -constraints {testchannel knownBug} -body {
+    # This test to check the validity of aquired Tcl_Channel references is not
+    # possible because even a backgrounded fcopy will immediately start to
+    # copy data, without waiting for the event loop. This is done only in case
+    # of an underflow on the read size!. So stacking transforms after the
+    # fcopy will miss information, or are not used at all.
+    #
+    # I was able to circumvent this by using the echo.tcl server with a big
+    # delay, causing the fcopy to underflow immediately.
+    set fin [open $path(dummy) r]
+    fevent 1000 500 {20 20 20 10 1 1} {
+	variable copy
+	close $fin
+	set fout [open dummyout w]
+	flush $sock;	# now, or fcopy will error us out
+	# But the 1 second delay should be enough to initialize everything
+	# else here.
+	fcopy $sock $fout -command [namespace code DoneCopy]
+	# Transform after fcopy got its handles!  They should be still valid
+	# for fcopy.
+	set trail [list]
+	audit_ops trail -attach $fout
+	vwait [namespace which -variable copy]
+    } [read $fin];	# {}
+    close $fout
+    # Check result of copy.
+    set fin [open $path(dummy) r]
+    set fout [open $path(dummyout) r]
+    set res [string equal [read $fin] [read $fout]]
+    close $fin
+    close $fout
+    list $res $trail
+} -cleanup {
+    rename DoneCopy {}
+} -result {1 {create/write create/read write flush/write flush/read delete/write delete/read}}
+
+test iogt-4.0 {fileevent readable, after transform} -setup {
+    set fin [open $path(dummy) r]
+    set data [read $fin]
+    close $fin
+    set trail [list]
+    set got [list]
+    proc Done {args} {
+	variable stop 1
+    }
+    proc Get {sock} {
+        variable trail
+        variable got
+        if {[eof $sock]} {
+            Done
+            lappend trail "xxxxxxxxxxxxx"
+            close $sock
+            return
+        }
+        lappend trail "vvvvvvvvvvvvv"
+        lappend trail "\tgot: [lappend got "\[\[[read $sock]\]\]"]"
+        lappend trail "============="
+        #puts stdout $__ ; flush stdout
+        #read $sock
+    }
+
+} -constraints {testchannel knownBug} -body {
+    fevent 1000 500 {20 20 20 10 1} {
+	variable stop
+	audit_flow trail -attach $sock
+	rblocks_t rbuf trail 23 -attach $sock
+
+	fileevent $sock readable [namespace code [list Get $sock]]
+
+	flush $sock;		# Now, or fcopy will error us out
+	# But the 1 second delay should be enough to initialize everything
+	# else here.
+	vwait [namespace which -variable stop]
+    } $data
+    join [list [join $got \n] ~~~~~~~~ [join $trail \n]] \n
+} -cleanup {
+    rename Done {}
+    rename Get {}
+} -result {[[]]
+[[abcdefghijklmnopqrstuvw]]
+[[xyz0123456789,./?><;'\|]]
+[[]]
+[[]]
+[[":[]\}\{`~!@#$%^&*()]]
+[[]]
+~~~~~~~~
+create/write {} *ignored*
+create/read {} *ignored*
+rblock | create/write {} {} | {}
+rblock | create/read {} {} | {}
+vvvvvvvvvvvvv
+rblock | query/maxRead {} -1 | {}
+query/maxRead {} -1
+read abcdefghijklmnopqrstu abcdefghijklmnopqrstu
+query/maxRead {} -1
+rblock | {read 23 21 :- 0} abcdefghijklmnopqrstu {} | abcdefghijklmnopqrstu
+rblock | query/maxRead {} -1 | abcdefghijklmnopqrstu
+query/maxRead {} -1
+	got: {[[]]}
+=============
+vvvvvvvvvvvvv
+rblock | query/maxRead {} -1 | abcdefghijklmnopqrstu
+query/maxRead {} -1
+read vwxyz0123456789,./?>< vwxyz0123456789,./?><
+query/maxRead {} -1
+rblock | {read 23 42 :- 23} vwxyz0123456789,./?>< abcdefghijklmnopqrstuvw | xyz0123456789,./?><
+rblock | query/maxRead {} -1 | xyz0123456789,./?><
+query/maxRead {} -1
+	got: {[[]]} {[[abcdefghijklmnopqrstuvw]]}
+=============
+vvvvvvvvvvvvv
+rblock | query/maxRead {} -1 | xyz0123456789,./?><
+query/maxRead {} -1
+read {;'\|":[]\}\{`~!@#$%^&} {;'\|":[]\}\{`~!@#$%^&}
+query/maxRead {} -1
+rblock | {read 23 40 :- 23} {;'\|":[]\}\{`~!@#$%^&} {xyz0123456789,./?><;'\|} | {":[]\}\{`~!@#$%^&}
+rblock | query/maxRead {} -1 | {":[]\}\{`~!@#$%^&}
+query/maxRead {} -1
+	got: {[[]]} {[[abcdefghijklmnopqrstuvw]]} {[[xyz0123456789,./?><;'\|]]}
+=============
+vvvvvvvvvvvvv
+rblock | query/maxRead {} -1 | {":[]\}\{`~!@#$%^&}
+query/maxRead {} -1
+read *( *(
+query/maxRead {} -1
+rblock | {read 23 19 :- 0} *( {} | {":[]\}\{`~!@#$%^&*(}
+rblock | query/maxRead {} -1 | {":[]\}\{`~!@#$%^&*(}
+query/maxRead {} -1
+	got: {[[]]} {[[abcdefghijklmnopqrstuvw]]} {[[xyz0123456789,./?><;'\|]]} {[[]]}
+=============
+vvvvvvvvvvvvv
+rblock | query/maxRead {} -1 | {":[]\}\{`~!@#$%^&*(}
+query/maxRead {} -1
+read ) )
+query/maxRead {} -1
+rblock | {read 23 20 :- 0} ) {} | {":[]\}\{`~!@#$%^&*()}
+rblock | query/maxRead {} -1 | {":[]\}\{`~!@#$%^&*()}
+query/maxRead {} -1
+	got: {[[]]} {[[abcdefghijklmnopqrstuvw]]} {[[xyz0123456789,./?><;'\|]]} {[[]]} {[[]]}
+=============
+vvvvvvvvvvvvv
+rblock | query/maxRead {} -1 | {":[]\}\{`~!@#$%^&*()}
+query/maxRead {} -1
+flush/read {} {}
+rblock | flush/read {} {":[]\}\{`~!@#$%^&*()} | {}
+rblock | query/maxRead {} -1 | {}
+query/maxRead {} -1
+	got: {[[]]} {[[abcdefghijklmnopqrstuvw]]} {[[xyz0123456789,./?><;'\|]]} {[[]]} {[[]]} {[[":[]\}\{`~!@#$%^&*()]]}
+=============
+vvvvvvvvvvvvv
+rblock | query/maxRead {} -1 | {}
+query/maxRead {} -1
+	got: {[[]]} {[[abcdefghijklmnopqrstuvw]]} {[[xyz0123456789,./?><;'\|]]} {[[]]} {[[]]} {[[":[]\}\{`~!@#$%^&*()]]} {[[]]}
+xxxxxxxxxxxxx
+rblock | flush/write {} {} | {}
+rblock | delete/write {} {} | {}
+rblock | delete/read {} {} | {}
+flush/write {} {}
+delete/write {} *ignored*
+delete/read {} *ignored*};	# catch unescaped quote "
+
+test iogt-5.0 {EOF simulation} -setup {
+    set fin [open $path(dummy) r]
+    set fout [open $path(dummyout) w]
+    set trail [list]
+} -constraints {testchannel knownBug} -result {
+    audit_flow trail -attach $fin
+    stopafter_audit d trail 20 -attach $fin
+    audit_flow trail -attach $fout
+    fconfigure $fin -buffersize 20
+    fconfigure $fout -buffersize 10
+    fcopy $fin $fout
+    testchannel unstack $fin
+    # now copy the rest in the channel
+    lappend trail {**after unstack**}
+    fcopy $fin $fout
+    close $fin
+    close $fout
+    join $trail \n
+} -result {create/read {} *ignored*
+counter:create/read {} {}
+create/write {} *ignored*
+counter:query/maxRead {} 20
+query/maxRead {} -1
+read {abcdefghijklmnopqrstuvwxyz0123456789,./?><;'\|":[]\}\{`~!@#$%^&*()_+-=
+} {abcdefghijklmnopqrstuvwxyz0123456789,./?><;'\|":[]\}\{`~!@#$%^&*()_+-=
+}
+query/maxRead {} -1
+flush/read {} {}
+counter:read abcdefghijklmnopqrst abcdefghijklmnopqrst
+write abcdefghij abcdefghij
+write klmnopqrst klmnopqrst
+counter:query/maxRead {} 0
+counter:flush/read {} {}
+counter:delete/read {} {}
+**after unstack**
+query/maxRead {} -1
+write uvwxyz0123 uvwxyz0123
+write 456789,./? 456789,./?
+write {><;'\|":[]} {><;'\|":[]}
+write {\}\{`~!@#$} {\}\{`~!@#$}
+write %^&*()_+-= %^&*()_+-=
+write {
+} {
+}
+query/maxRead {} -1
+delete/read {} *ignored*
+flush/write {} {}
+delete/write {} *ignored*}
+
+proc constX {op data} {
+    # replace anything coming in with a same-length string of x'es.
+    switch -- $op {
+	create/write - create/read - delete/write - delete/read - clear_read {
+	    #ignore
+	}
+	flush/write - flush/read - write - read {
+	    return [string repeat x [string length $data]]
+	}
+	query/maxRead {
+	    return -1
+	}
+    }
+}
+proc constx {-attach channel} {
+    testchannel transform $channel -command [namespace code constX]
+}
+
+test iogt-6.0 {Push back} -constraints testchannel -body {
+    set f [open $path(dummy) r]
+    # contents of dummy = "abcdefghi..."
+    read $f 3;		# skip behind "abc"
+    constx -attach $f
+    # expect to get "xxx" from the transform because of unread "def" input to
+    # transform which returns "xxx".
+    #
+    # Actually the IO layer pre-read the whole file and will read "def"
+    # directly from the buffer without bothering to consult the newly stacked
+    # transformation. This is wrong.
+    read $f 3
+} -cleanup {
+    close $f
+} -result {xxx}
+test iogt-6.1 {Push back and up} -constraints {testchannel knownBug} -body {
+
+    # This test demonstrates the bug/misfeature in the stacked
+    # channel implementation that data can be discarded if it is
+    # read into the buffers of one channel in the stack, and then
+    # that channel is popped before anything above it reads.
+    #
+    # This bug can be worked around by always setting -buffersize
+    # to 1, but who wants to do that?
+
+    set f [open $path(dummy) r]
+    # contents of dummy = "abcdefghi..."
+    read $f 3;		# skip behind "abc"
+    constx -attach $f
+    set res [read $f 3]
+    testchannel unstack $f
+    append res [read $f 3]
+} -cleanup {
+    close $f
+} -result {xxxghi}
+
+
+# Driver for a base channel that emits several short "files"
+# with each terminated by a fleeting EOF
+    proc driver {cmd args} {
+        variable buffer
+        variable index
+        set chan [lindex $args 0]
+        switch -- $cmd {
+            initialize {
+                set index($chan) 0
+                set buffer($chan) .....
+                return {initialize finalize watch read}
+            }
+            finalize {
+                if {![info exists index($chan)]} {return}
+                unset index($chan) buffer($chan)
+                return
+            }
+            watch {}
+            read {
+                set n [lindex $args 1]
+                if {![info exists index($chan)]} {
+                    driver initialize $chan
+                }
+                set new [expr {$index($chan) + $n}]
+                set result [string range $buffer($chan) $index($chan) $new-1]
+                set index($chan) $new
+                if {[string length $result] == 0} {
+                    driver finalize $chan
+                }
+                return $result
+            }
+        }
+    }
+
+test iogt-7.0 {Handle fleeting EOF} -constraints {testchannel} -body {
+    set chan [chan create read [namespace which driver]]
+    identity -attach $chan
+    list [eof $chan] [read $chan] [eof $chan] [read $chan 0] [eof $chan] \
+        [read $chan] [eof $chan]
+} -cleanup {
+    close $chan
+} -result {0 ..... 1 {} 0 ..... 1}
+
+proc delay {op data} {
+    variable store
+    switch -- $op {
+	create/write -	create/read  -
+	delete/write -	delete/read  -
+	flush/write -	write -
+	clear_read   {;#ignore}
+	flush/read  -
+	read        {
+	    if {![info exists store]} {set store {}}
+	    set reply $store
+	    set store $data
+	    return $reply
+	}
+	query/maxRead {return -1}
+    }
+}
+
+test iogt-7.1 {Handle fleeting EOF} -constraints {testchannel} -body {
+    set chan [chan create read [namespace which driver]]
+    testchannel transform $chan -command [namespace code delay]
+    list [eof $chan] [read $chan] [eof $chan] [read $chan 0] [eof $chan] \
+        [read $chan] [eof $chan]
+} -cleanup {
+    close $chan
+} -result {0 ..... 1 {} 0 ..... 1}
+
+rename delay {}
+rename driver {}
+
+# cleanup
+foreach file [list dummy dummyout __echo_srv__.tcl] {
+    removeFile $file
+}
+cleanupTests
+}
+namespace delete ::tcl::test::iogt
+return
diff --git a/tests/join.test b/tests/join.test
new file mode 100644
index 0000000..4abe233
--- /dev/null
+++ b/tests/join.test
@@ -0,0 +1,55 @@
+# Commands covered:  join
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands.  Sourcing this file into Tcl runs the tests and
+# generates output for errors.  No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+    package require tcltest
+    namespace import -force ::tcltest::*
+}
+
+test join-1.1 {basic join commands} {
+    join {a b c} xyz
+} axyzbxyzc
+test join-1.2 {basic join commands} {
+    join {a b c} {}
+} abc
+test join-1.3 {basic join commands} {
+    join {} xyz
+} {}
+test join-1.4 {basic join commands} {
+    join {12 34 56}
+} {12 34 56}
+
+test join-2.1 {join errors} {
+    list [catch join msg] $msg $errorCode
+} {1 {wrong # args: should be "join list ?joinString?"} {TCL WRONGARGS}}
+test join-2.2 {join errors} {
+    list [catch {join a b c} msg] $msg $errorCode
+} {1 {wrong # args: should be "join list ?joinString?"} {TCL WRONGARGS}}
+test join-2.3 {join errors} {
+    list [catch {join "a \{ c" 111} msg] $msg $errorCode
+} {1 {unmatched open brace in list} {TCL VALUE LIST BRACE}}
+
+test join-3.1 {joinString is binary ok} {
+  string length [join {a b c} a\0b]
+} 9
+test join-3.2 {join is binary ok} {
+  string length [join "a\0b a\0b a\0b"]
+} 11
+
+# cleanup
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/tests/lindex.test b/tests/lindex.test
new file mode 100644
index 0000000..b86e2e0
--- /dev/null
+++ b/tests/lindex.test
@@ -0,0 +1,458 @@
+# Commands covered:  lindex
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands.  Sourcing this file into Tcl runs the tests and
+# generates output for errors.  No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+# Copyright (c) 2001 by Kevin B. Kenny.  All rights reserved.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+    package require tcltest 2.2
+    namespace import -force ::tcltest::*
+}
+
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
+
+set minus -
+testConstraint testevalex [llength [info commands testevalex]]
+
+# Tests of Tcl_LindexObjCmd, NOT COMPILED
+
+test lindex-1.1 {wrong # args} testevalex {
+    list [catch {testevalex lindex} result] $result
+} "1 {wrong # args: should be \"lindex list ?index ...?\"}"
+
+# Indices that are lists or convertible to lists
+
+test lindex-2.1 {empty index list} testevalex {
+    set x {}
+    list [testevalex {lindex {a b c} $x}] [testevalex {lindex {a b c} $x}]
+} {{a b c} {a b c}}
+test lindex-2.2 {singleton index list} testevalex {
+    set x { 1 }
+    list [testevalex {lindex {a b c} $x}] [testevalex {lindex {a b c} $x}]
+} {b b}
+test lindex-2.3 {multiple indices in list} testevalex {
+    set x {1 2}
+    list [testevalex {lindex {{a b c} {d e f}} $x}] \
+	[testevalex {lindex {{a b c} {d e f}} $x}]
+} {f f}
+test lindex-2.4 {malformed index list} testevalex {
+    set x \{
+    list [catch { testevalex {lindex {a b c} $x} } result] $result
+} {1 bad\ index\ \"\{\":\ must\ be\ integer?\[+-\]integer?\ or\ end?\[+-\]integer?}
+
+# Indices that are integers or convertible to integers
+
+test lindex-3.1 {integer -1} testevalex {
+    set x ${minus}1
+    list [testevalex {lindex {a b c} $x}] [testevalex {lindex {a b c} $x}]
+} {{} {}}
+test lindex-3.2 {integer 0} testevalex {
+    set x [string range 00 0 0]
+    list [testevalex {lindex {a b c} $x}] [testevalex {lindex {a b c} $x}]
+} {a a}
+test lindex-3.3 {integer 2} testevalex {
+    set x [string range 22 0 0]
+    list [testevalex {lindex {a b c} $x}] [testevalex {lindex {a b c} $x}]
+} {c c}
+test lindex-3.4 {integer 3} testevalex {
+    set x [string range 33 0 0]
+    list [testevalex {lindex {a b c} $x}] [testevalex {lindex {a b c} $x}]
+} {{} {}}
+test lindex-3.5 {bad octal} -constraints testevalex -body {
+    set x 0o8
+    list [catch { testevalex {lindex {a b c} $x} } result] $result
+} -match glob -result {1 {*invalid octal number*}}
+test lindex-3.6 {bad octal} -constraints testevalex -body {
+    set x -0o9
+    list [catch { testevalex {lindex {a b c} $x} } result] $result
+} -match glob -result {1 {*invalid octal number*}}
+test lindex-3.7 {indexes don't shimmer wide ints} {
+    set x [expr {(wide(1)<<31) - 2}]
+    list $x [lindex {1 2 3} $x] [incr x] [incr x]
+} {2147483646 {} 2147483647 2147483648}
+
+# Indices relative to end
+
+test lindex-4.1 {index = end} testevalex {
+    set x end
+    list [testevalex {lindex {a b c} $x}] [testevalex {lindex {a b c} $x}]
+} {c c}
+test lindex-4.2 {index = end--1} testevalex {
+    set x end--1
+    list [testevalex {lindex {a b c} $x}] [testevalex {lindex {a b c} $x}]
+} {{} {}}
+test lindex-4.3 {index = end-0} testevalex {
+    set x end-0
+    list [testevalex {lindex {a b c} $x}] [testevalex {lindex {a b c} $x}]
+} {c c}
+test lindex-4.4 {index = end-2} testevalex {
+    set x end-2
+    list [testevalex {lindex {a b c} $x}] [testevalex {lindex {a b c} $x}]
+} {a a}
+test lindex-4.5 {index = end-3} testevalex {
+    set x end-3
+    list [testevalex {lindex {a b c} $x}] [testevalex {lindex {a b c} $x}]
+} {{} {}}
+test lindex-4.6 {bad octal} -constraints testevalex -body {
+    set x end-0o8
+    list [catch { testevalex {lindex {a b c} $x} } result] $result
+} -match glob -result {1 {*invalid octal number*}}
+test lindex-4.7 {bad octal} -constraints testevalex -body {
+    set x end--0o9
+    list [catch { testevalex {lindex {a b c} $x} } result] $result
+} -match glob -result {1 {*invalid octal number*}}
+test lindex-4.8 {bad integer, not octal} testevalex {
+    set x end-0a2
+    list [catch { testevalex {lindex {a b c} $x} } result] $result
+} {1 {bad index "end-0a2": must be integer?[+-]integer? or end?[+-]integer?}}
+test lindex-4.9 {obsolete test} testevalex {
+    set x end
+    list [testevalex {lindex {a b c} $x}] [testevalex {lindex {a b c} $x}]
+} {c c}
+test lindex-4.10 {incomplete end-} testevalex {
+    set x end-
+    list [catch { testevalex {lindex {a b c} $x} } result] $result
+} {1 {bad index "end-": must be integer?[+-]integer? or end?[+-]integer?}}
+
+test lindex-5.1 {bad second index} testevalex {
+    list [catch { testevalex {lindex {a b c} 0 0a2} } result] $result
+} {1 {bad index "0a2": must be integer?[+-]integer? or end?[+-]integer?}}
+test lindex-5.2 {good second index} testevalex {
+    testevalex {lindex {{a b c} {d e f} {g h i}} 1 2}
+} f
+test lindex-5.3 {three indices} testevalex {
+    testevalex {lindex {{{a b} {c d}} {{e f} {g h}}} 1 0 1}
+} f
+
+test lindex-6.1 {error conditions in parsing list} testevalex {
+    list [catch {testevalex {lindex "a \{" 2}} msg] $msg
+} {1 {unmatched open brace in list}}
+test lindex-6.2 {error conditions in parsing list} testevalex {
+    list [catch {testevalex {lindex {a {b c}d e} 2}} msg] $msg
+} {1 {list element in braces followed by "d" instead of space}}
+test lindex-6.3 {error conditions in parsing list} testevalex {
+    list [catch {testevalex {lindex {a "b c"def ghi} 2}} msg] $msg
+} {1 {list element in quotes followed by "def" instead of space}}
+
+test lindex-7.1 {quoted elements} testevalex {
+    testevalex {lindex {a "b c" d} 1}
+} {b c}
+test lindex-7.2 {quoted elements} testevalex {
+    testevalex {lindex {"{}" b c} 0}
+} {{}}
+test lindex-7.3 {quoted elements} testevalex {
+    testevalex {lindex {ab "c d \" x" y} 1}
+} {c d " x}
+test lindex-7.4 {quoted elements} {
+    lindex {a b {c d "e} {f g"}} 2
+} {c d "e}
+
+test lindex-8.1 {data reuse} testevalex {
+    set x 0
+    testevalex {lindex $x $x}
+} {0}
+test lindex-8.2 {data reuse} testevalex {
+    set a 0
+    testevalex {lindex $a $a $a}
+} 0
+test lindex-8.3 {data reuse} testevalex {
+    set a 1
+    testevalex {lindex $a $a $a}
+} {}
+test lindex-8.4 {data reuse} testevalex {
+    set x [list 0 0]
+    testevalex {lindex $x $x}
+} {0}
+test lindex-8.5 {data reuse} testevalex {
+    set x 0
+    testevalex {lindex $x [list $x $x]}
+} {0}
+test lindex-8.6 {data reuse} testevalex {
+    set x [list 1 1]
+    testevalex {lindex $x $x}
+} {}
+test lindex-8.7 {data reuse} testevalex {
+    set x 1
+    testevalex {lindex $x [list $x $x]}
+} {}
+
+#----------------------------------------------------------------------
+
+# Compilation tests for lindex
+
+test lindex-9.1 {wrong # args} {
+    list [catch {lindex} result] $result
+} "1 {wrong # args: should be \"lindex list ?index ...?\"}"
+test lindex-9.2 {ensure that compilation works in the right order} {
+    proc foo {} {
+	rename foo {}
+	lindex 1 0
+    }
+    foo
+} 1
+
+# Indices that are lists or convertible to lists
+
+test lindex-10.1 {empty index list} {
+    set x {}
+    catch {
+	list [lindex {a b c} $x] [lindex {a b c} $x]
+    } result
+    set result
+} {{a b c} {a b c}}
+test lindex-10.2 {singleton index list} {
+    set x { 1 }
+    catch {
+	list [lindex {a b c} $x] [lindex {a b c} $x]
+    } result
+    set result
+} {b b}
+test lindex-10.3 {multiple indices in list} {
+    set x {1 2}
+    catch {
+	list [lindex {{a b c} {d e f}} $x] [lindex {{a b c} {d e f}} $x]
+    } result
+    set result
+} {f f}
+test lindex-10.4 {malformed index list} {
+    set x \{
+    list [catch { lindex {a b c} $x } result] $result
+} {1 bad\ index\ \"\{\":\ must\ be\ integer?\[+-\]integer?\ or\ end?\[+-\]integer?}
+
+# Indices that are integers or convertible to integers
+
+test lindex-11.1 {integer -1} {
+    set x ${minus}1
+    catch {
+	list [lindex {a b c} $x] [lindex {a b c} $x]
+    } result
+    set result
+} {{} {}}
+test lindex-11.2 {integer 0} {
+    set x [string range 00 0 0]
+    catch {
+	list [lindex {a b c} $x] [lindex {a b c} $x]
+    } result
+    set result
+} {a a}
+test lindex-11.3 {integer 2} {
+    set x [string range 22 0 0]
+    catch {
+	list [lindex {a b c} $x] [lindex {a b c} $x]
+    } result
+    set result
+} {c c}
+test lindex-11.4 {integer 3} {
+    set x [string range 33 0 0]
+    catch {
+	list [lindex {a b c} $x] [lindex {a b c} $x]
+    } result
+    set result
+} {{} {}}
+test lindex-11.5 {bad octal} -body {
+    set x 0o8
+    list [catch { lindex {a b c} $x } result] $result
+} -match glob -result {1 {*invalid octal number*}}
+test lindex-11.6 {bad octal} -body {
+    set x -0o9
+    list [catch { lindex {a b c} $x } result] $result
+} -match glob -result {1 {*invalid octal number*}}
+
+# Indices relative to end
+
+test lindex-12.1 {index = end} {
+    set x end
+    catch {
+	list [lindex {a b c} $x] [lindex {a b c} $x]
+    } result
+    set result
+} {c c}
+test lindex-12.2 {index = end--1} {
+    set x end--1
+    catch {
+	list [lindex {a b c} $x] [lindex {a b c} $x]
+    } result
+    set result
+} {{} {}}
+test lindex-12.3 {index = end-0} {
+    set x end-0
+    catch {
+	list [lindex {a b c} $x] [lindex {a b c} $x]
+    } result
+    set result
+} {c c}
+test lindex-12.4 {index = end-2} {
+    set x end-2
+    catch {
+	list [lindex {a b c} $x] [lindex {a b c} $x]
+    } result
+    set result
+} {a a}
+test lindex-12.5 {index = end-3} {
+    set x end-3
+    catch {
+	list [lindex {a b c} $x] [lindex {a b c} $x]
+    } result
+    set result
+} {{} {}}
+test lindex-12.6 {bad octal} -body {
+    set x end-0o8
+    list [catch { lindex {a b c} $x } result] $result
+} -match glob -result {1 {*invalid octal number*}}
+test lindex-12.7 {bad octal} -body {
+    set x end--0o9
+    list [catch { lindex {a b c} $x } result] $result
+} -match glob -result {1 {*invalid octal number*}}
+test lindex-12.8 {bad integer, not octal} {
+    set x end-0a2
+    list [catch { lindex {a b c} $x } result] $result
+} {1 {bad index "end-0a2": must be integer?[+-]integer? or end?[+-]integer?}}
+test lindex-12.9 {obsolete test} {
+    set x end
+    catch {
+	list [lindex {a b c} $x] [lindex {a b c} $x]
+    } result
+    set result
+} {c c}
+test lindex-12.10 {incomplete end-} {
+    set x end-
+    list [catch { lindex {a b c} $x } result] $result
+} {1 {bad index "end-": must be integer?[+-]integer? or end?[+-]integer?}}
+
+test lindex-13.1 {bad second index} {
+    list [catch { lindex {a b c} 0 0a2 } result] $result
+} {1 {bad index "0a2": must be integer?[+-]integer? or end?[+-]integer?}}
+test lindex-13.2 {good second index} {
+    catch {
+	lindex {{a b c} {d e f} {g h i}} 1 2
+    } result
+    set result
+} f
+test lindex-13.3 {three indices} {
+    catch {
+	lindex {{{a b} {c d}} {{e f} {g h}}} 1 0 1
+    } result
+    set result
+} f
+
+test lindex-14.1 {error conditions in parsing list} {
+    list [catch { lindex "a \{" 2 } msg] $msg
+} {1 {unmatched open brace in list}}
+test lindex-14.2 {error conditions in parsing list} {
+    list [catch { lindex {a {b c}d e} 2 } msg] $msg
+} {1 {list element in braces followed by "d" instead of space}}
+test lindex-14.3 {error conditions in parsing list} {
+    list [catch { lindex {a "b c"def ghi} 2 } msg] $msg
+} {1 {list element in quotes followed by "def" instead of space}}
+
+test lindex-15.1 {quoted elements} {
+    catch {
+	lindex {a "b c" d} 1
+    } result
+    set result
+} {b c}
+test lindex-15.2 {quoted elements} {
+    catch {
+	lindex {"{}" b c} 0
+    } result
+    set result
+} {{}}
+test lindex-15.3 {quoted elements} {
+    catch {
+	lindex {ab "c d \" x" y} 1
+    } result
+    set result
+} {c d " x}
+test lindex-15.4 {quoted elements} {
+    catch {
+	lindex {a b {c d "e} {f g"}} 2
+    } result
+    set result
+} {c d "e}
+
+test lindex-16.1 {data reuse} {
+    set x 0
+    catch {
+	lindex $x $x
+    } result
+    set result
+} {0}
+test lindex-16.2 {data reuse} {
+    set a 0
+    catch {
+	lindex $a $a $a
+    } result
+    set result
+} 0
+test lindex-16.3 {data reuse} {
+    set a 1
+    catch {
+	lindex $a $a $a
+    } result
+    set result
+} {}
+test lindex-16.4 {data reuse} {
+    set x [list 0 0]
+    catch {
+	lindex $x $x
+    } result
+    set result
+} {0}
+test lindex-16.5 {data reuse} {
+    set x 0
+    catch {
+	lindex $x [list $x $x]
+    } result
+    set result
+} {0}
+test lindex-16.6 {data reuse} {
+    set x [list 1 1]
+    catch {
+	lindex $x $x
+    } result
+    set result
+} {}
+test lindex-16.7 {data reuse} {
+    set x 1
+    catch {
+	lindex $x [list $x $x]
+    } result
+    set result
+} {}
+
+test lindex-17.0 {Bug 1718580} {*}{
+    -body {
+        lindex {} end foo
+    } 
+    -match glob
+    -result {bad index "foo"*}
+    -returnCodes 1
+}
+
+test lindex-17.1 {Bug 1718580} {*}{
+    -body {
+        lindex a end foo
+    } 
+    -match glob
+    -result {bad index "foo"*}
+    -returnCodes 1
+}
+
+catch { unset minus }
+
+# cleanup
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/tests/link.test b/tests/link.test
new file mode 100644
index 0000000..00e490c
--- /dev/null
+++ b/tests/link.test
@@ -0,0 +1,310 @@
+# Commands covered:  none
+#
+# This file contains a collection of tests for Tcl_LinkVar and related library
+# procedures. Sourcing this file into Tcl runs the tests and generates output
+# for errors. No output means no errors were found.
+#
+# Copyright (c) 1993 The Regents of the University of California.
+# Copyright (c) 1994 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution of
+# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {"::tcltest" ni [namespace children]} {
+    package require tcltest 2
+    namespace import -force ::tcltest::*
+}
+
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
+
+testConstraint testlink [llength [info commands testlink]]
+
+foreach i {int real bool string} {
+    unset -nocomplain $i
+}
+
+test link-1.1 {reading C variables from Tcl} -constraints {testlink} -setup {
+    testlink delete
+} -body {
+    testlink set 43 1.23 4 - 12341234 64 250 30000 60000 0xbeefbabe 12321 32123 3.25 1231231234
+    testlink create 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+    list $int $real $bool $string $wide
+} -result {43 1.23 1 NULL 12341234}
+test link-1.2 {reading C variables from Tcl} -constraints {testlink} -setup {
+    testlink delete
+} -body {
+    testlink create 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+    testlink set -3 2 0 "A long string with spaces"  43214321 64 250 30000 60000 0xbeefbabe 12321 32123 3.25 1231231234
+    list $int $real $bool $string $wide $int $real $bool $string $wide
+} -result {-3 2.0 0 {A long string with spaces} 43214321 -3 2.0 0 {A long string with spaces} 43214321}
+
+test link-2.1 {writing C variables from Tcl} -constraints {testlink} -setup {
+    testlink delete
+} -body {
+    testlink set 43 1.21 4 - 56785678 64 250 30000 60000 0xbaadbeef 12321 32123 3.25 1231231234
+    testlink create 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+    set int "0o0721"
+    set real -10.5
+    set bool true
+    set string abcdef
+    set wide 135135
+    set char 79
+    set uchar 161
+    set short 8000
+    set ushort 40000
+    set uint 0xc001babe
+    set long 34543
+    set ulong 567890
+    set float 1.0987654321
+    set uwide 357357357357
+    concat [testlink get] | $int $real $bool $string $wide $char $uchar $short $ushort $uint $long $ulong $float $uwide
+} -result {465 -10.5 1 abcdef 135135 79 161 8000 40000 -1073628482 34543 567890 1.0987653732299805 357357357357 | 0o0721 -10.5 true abcdef 135135 79 161 8000 40000 0xc001babe 34543 567890 1.0987654321 357357357357}
+test link-2.2 {writing bad values into variables} -setup {
+    testlink delete
+} -constraints {testlink} -body {
+    testlink set 43 1.23 4 - 56785678 64 250 30000 60000 0xbeefbabe 12321 32123 3.25 1231231234
+    testlink create 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+    list [catch {set int 09a} msg] $msg $int
+} -result {1 {can't set "int": variable must have integer value} 43}
+test link-2.3 {writing bad values into variables} -setup {
+    testlink delete
+} -constraints {testlink} -body {
+    testlink set 43 1.23 4 - 56785678 64 250 30000 60000 0xbeefbabe 12321 32123 3.25 1231231234
+    testlink create 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+    list [catch {set real 1.x3} msg] $msg $real
+} -result {1 {can't set "real": variable must have real value} 1.23}
+test link-2.4 {writing bad values into variables} -setup {
+    testlink delete
+} -constraints {testlink} -body {
+    testlink set 43 1.23 4 - 56785678 64 250 30000 60000 0xbeefbabe 12321 32123 3.25 1231231234
+    testlink create 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+    list [catch {set bool gorp} msg] $msg $bool
+} -result {1 {can't set "bool": variable must have boolean value} 1}
+test link-2.5 {writing bad values into variables} -setup {
+    testlink delete
+} -constraints {testlink} -body {
+    testlink set 43 1.23 4 - 56785678 64 250 30000 60000 0xbeefbabe 12321 32123 3.25 1231231234
+    testlink create 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+    list [catch {set wide gorp} msg] $msg $bool
+} -result {1 {can't set "wide": variable must have integer value} 1}
+
+test link-3.1 {read-only variables} -constraints {testlink} -setup {
+    testlink delete
+} -body {
+    testlink set 43 1.23 4 - 56785678 64 250 30000 60000 0xbeefbabe 12321 32123 3.25 1231231234
+    testlink create 0 1 1 0 0 0 0 0 0 0 0 0 0 0
+    list [catch {set int 4} msg] $msg $int \
+	[catch {set real 10.6} msg] $msg $real \
+	[catch {set bool no} msg] $msg $bool \
+	[catch {set string "new value"} msg] $msg $string \
+	[catch {set wide 12341234} msg] $msg $wide
+} -result {1 {can't set "int": linked variable is read-only} 43 0 10.6 10.6 0 no no 1 {can't set "string": linked variable is read-only} NULL 1 {can't set "wide": linked variable is read-only} 56785678}
+test link-3.2 {read-only variables} -constraints {testlink} -setup {
+    testlink delete
+} -body {
+    testlink set 43 1.23 4 - 56785678 64 250 30000 60000 0xbeefbabe 12321 32123 3.25 1231231234
+    testlink create 1 0 0 1 1 0 0 0 0 0 0 0 0 0
+    list [catch {set int 4} msg] $msg $int \
+	[catch {set real 10.6} msg] $msg $real \
+	[catch {set bool no} msg] $msg $bool \
+	[catch {set string "new value"} msg] $msg $string\
+	[catch {set wide 12341234} msg] $msg $wide
+} -result {0 4 4 1 {can't set "real": linked variable is read-only} 1.23 1 {can't set "bool": linked variable is read-only} 1 0 {new value} {new value} 0 12341234 12341234}
+
+test link-4.1 {unsetting linked variables} -constraints {testlink} -setup {
+    testlink delete
+} -body {
+    testlink set -6 -2.5 0 stringValue 13579 64 250 30000 60000 0xbeefbabe 12321 32123 3.25 1231231234
+    testlink create 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+    unset int real bool string wide
+    list [catch {set int} msg] $msg [catch {set real} msg] $msg \
+	    [catch {set bool} msg] $msg [catch {set string} msg] $msg \
+	    [catch {set wide} msg] $msg
+} -result {0 -6 0 -2.5 0 0 0 stringValue 0 13579}
+test link-4.2 {unsetting linked variables} -constraints {testlink} -setup {
+    testlink delete
+} -body {
+    testlink set -6 -2.1 0 stringValue 97531 64 250 30000 60000 0xbeefbabe 12321 32123 3.25 1231231234
+    testlink create 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+    unset int real bool string wide
+    set int 102
+    set real 16
+    set bool true
+    set string newValue
+    set wide 333555
+    lrange [testlink get] 0 4
+} -result {102 16.0 1 newValue 333555}
+
+test link-5.1 {unlinking variables} -constraints {testlink} -setup {
+    testlink delete
+} -body {
+    testlink set -6 -2.25 0 stringValue 13579 64 250 30000 60000 0xbeefbabe 12321 32123 3.25 1231231234
+    testlink delete
+    set int xx1
+    set real qrst
+    set bool bogus
+    set string 12345
+    set wide 875421
+    set char skjdf
+    set uchar dslfjk
+    set short slkf
+    set ushort skrh
+    set uint sfdkfkh
+    set long srkjh
+    set ulong sjkg
+    set float dskjfbjfd
+    set uwide isdfsngs
+    testlink get
+} -result {-6 -2.25 0 stringValue 13579 64 250 30000 60000 -1091585346 12321 32123 3.25 1231231234}
+test link-5.2 {unlinking variables} -constraints {testlink} -setup {
+    testlink delete
+} -body {
+    testlink set -6 -2.25 0 stringValue 97531 64 250 30000 60000 0xbeefbabe 12321 32123 3.25 1231231234
+    testlink create 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+    testlink delete
+    testlink set 25 14.7 7 - 999999 65 251 30001 60001 0xbabebeef 12322 32124 3.125 12312312340
+    list $int $real $bool $string $wide $char $uchar $short $ushort $uint $long $ulong $float $uwide
+} -result {-6 -2.25 0 stringValue 97531 64 250 30000 60000 3203381950 12321 32123 3.25 1231231234}
+
+test link-6.1 {errors in setting up link} -setup {
+    testlink delete
+    unset -nocomplain int
+} -constraints {testlink} -body {
+    set int(44) 1
+    testlink create 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+} -cleanup {
+    unset -nocomplain int
+} -returnCodes error -result {can't set "int": variable is array}
+
+test link-7.1 {access to linked variables via upvar} -setup {
+    testlink delete
+} -constraints {testlink} -body {
+    proc x {} {
+	upvar int y
+	unset y
+    }
+    testlink create 1 0 0 0 0 0 0 0 0 0 0 0 0 0
+    testlink set 14 {} {} {} {} {} {} {} {} {} {} {} {} {}
+    x
+    list [catch {set int} msg] $msg
+} -result {0 14}
+test link-7.2 {access to linked variables via upvar} -setup {
+    testlink delete
+} -constraints {testlink} -body {
+    proc x {} {
+	upvar int y
+	return [set y]
+    }
+    testlink create 1 0 0 0 0 0 0 0 0 0 0 0 0 0
+    testlink set 0 {} {} {} {} {} {} {} {} {} {} {} {} {}
+    set int
+    testlink set 23 {} {} {} {} {} {} {} {} {} {} {} {} {}
+    x
+    list [x] $int
+} -result {23 23}
+test link-7.3 {access to linked variables via upvar} -setup {
+    testlink delete
+} -constraints {testlink} -body {
+    proc x {} {
+	upvar int y
+	set y 44
+    }
+    testlink create 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+    testlink set 11 {} {} {} {} {} {} {} {} {} {} {} {} {}
+    list [catch x msg] $msg $int
+} -result {1 {can't set "y": linked variable is read-only} 11}
+test link-7.4 {access to linked variables via upvar} -setup {
+    testlink delete
+} -constraints {testlink} -body {
+    proc x {} {
+	upvar int y
+	set y abc
+    }
+    testlink create 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+    testlink set -4 {} {} {} {} {} {} {} {} {} {} {} {} {}
+    list [catch x msg] $msg $int
+} -result {1 {can't set "y": variable must have integer value} -4}
+test link-7.5 {access to linked variables via upvar} -setup {
+    testlink delete
+} -constraints {testlink} -body {
+    proc x {} {
+	upvar real y
+	set y abc
+    }
+    testlink create 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+    testlink set -4 16.75 {} {} {} {} {} {} {} {} {} {} {} {}
+    list [catch x msg] $msg $real
+} -result {1 {can't set "y": variable must have real value} 16.75}
+test link-7.6 {access to linked variables via upvar} -setup {
+    testlink delete
+} -constraints {testlink} -body {
+    proc x {} {
+	upvar bool y
+	set y abc
+    }
+    testlink create 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+    testlink set -4 16.3 1 {} {} {} {} {} {} {} {} {} {} {}
+    list [catch x msg] $msg $bool
+} -result {1 {can't set "y": variable must have boolean value} 1}
+test link-7.7 {access to linked variables via upvar} -setup {
+    testlink delete
+} -constraints {testlink} -body {
+    proc x {} {
+	upvar wide y
+	set y abc
+    }
+    testlink create 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+    testlink set -4 16.3 1 {} 778899 {} {} {} {} {} {} {} {} {}
+    list [catch x msg] $msg $wide
+} -result {1 {can't set "y": variable must have integer value} 778899}
+
+test link-8.1 {Tcl_UpdateLinkedVar procedure} {testlink} {
+    proc x args {
+	global x int real bool string wide
+	lappend x $args $int $real $bool $string $wide
+    }
+    set x {}
+    testlink create 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+    testlink set 14 -2.0 0 xyzzy 995511 64 250 30000 60000 0xbeefbabe 12321 32123 3.25 1231231234
+    trace var int w x
+    testlink update 32 4.0 3 abcd 113355 65 251 30001 60001 0xbabebeef 12322 32124 3.125 12312312340
+    trace vdelete int w x
+    return $x
+} {{int {} w} 32 -2.0 0 xyzzy 995511}
+test link-8.2 {Tcl_UpdateLinkedVar procedure} {testlink} {
+    proc x args {
+	global x int real bool string wide
+	lappend x $args $int $real $bool $string $wide
+    }
+    set x {}
+    testlink create 1 1 1 1 1 1 1 1 1 1 1 1 1 1
+    testlink set 14 -2.0 0 xyzzy 995511 64 250 30000 60000 0xbeefbabe 12321 32123 3.25 1231231234
+    testlink delete
+    trace var int w x
+    testlink update 32 4.0 6 abcd 113355 65 251 30001 60001 0xbabebeef 12322 32124 3.125 12312312340
+    trace vdelete int w x
+    return $x
+} {}
+test link-8.3 {Tcl_UpdateLinkedVar procedure, read-only variable} {testlink} {
+    testlink create 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+    list [catch {
+	testlink update 47 {} {} {} {} {} {} {} {} {} {} {} {} {}
+    } msg] $msg $int
+} {0 {} 47}
+
+catch {testlink set 0 0 0 - 0 0 0 0 0 0 0 0 0 0}
+catch {testlink delete}
+foreach i {int real bool string wide} {
+    unset -nocomplain $i
+}
+
+# cleanup
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# fill-column: 78
+# End:
diff --git a/tests/linsert.test b/tests/linsert.test
new file mode 100644
index 0000000..4939e5c
--- /dev/null
+++ b/tests/linsert.test
@@ -0,0 +1,119 @@
+# Commands covered:  linsert
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands.  Sourcing this file into Tcl runs the tests and
+# generates output for errors.  No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+    package require tcltest
+    namespace import -force ::tcltest::*
+}
+
+catch {unset lis}
+catch {rename p ""}
+
+test linsert-1.1 {linsert command} {
+    linsert {1 2 3 4 5} 0 a
+} {a 1 2 3 4 5}
+test linsert-1.2 {linsert command} {
+    linsert {1 2 3 4 5} 1 a
+} {1 a 2 3 4 5}
+test linsert-1.3 {linsert command} {
+    linsert {1 2 3 4 5} 2 a
+} {1 2 a 3 4 5}
+test linsert-1.4 {linsert command} {
+    linsert {1 2 3 4 5} 3 a
+} {1 2 3 a 4 5}
+test linsert-1.5 {linsert command} {
+    linsert {1 2 3 4 5} 4 a
+} {1 2 3 4 a 5}
+test linsert-1.6 {linsert command} {
+    linsert {1 2 3 4 5} 5 a
+} {1 2 3 4 5 a}
+test linsert-1.7 {linsert command} {
+    linsert {1 2 3 4 5} 2 one two \{three \$four
+} {1 2 one two \{three {$four} 3 4 5}
+test linsert-1.8 {linsert command} {
+    linsert {\{one \$two \{three \ four \ five} 2 a b c
+} {\{one {$two} a b c \{three { four} { five}}
+test linsert-1.9 {linsert command} {
+    linsert {{1 2} {3 4} {5 6} {7 8}} 2 {x y} {a b}
+} {{1 2} {3 4} {x y} {a b} {5 6} {7 8}}
+test linsert-1.10 {linsert command} {
+    linsert {} 2 a b c
+} {a b c}
+test linsert-1.11 {linsert command} {
+    linsert {} 2 {}
+} {{}}
+test linsert-1.12 {linsert command} {
+    linsert {a b "c c" d e} 3 1
+} {a b {c c} 1 d e}
+test linsert-1.13 {linsert command} {
+    linsert { a b c d} 0 1 2
+} {1 2 a b c d}
+test linsert-1.14 {linsert command} {
+    linsert {a b c {d e f}} 4 1 2
+} {a b c {d e f} 1 2}
+test linsert-1.15 {linsert command} {
+    linsert {a b c \{\  abc} 4 q r
+} {a b c \{\  q r abc}
+test linsert-1.16 {linsert command} {
+    linsert {a b c \{ abc} 4 q r
+} {a b c \{ q r abc}
+test linsert-1.17 {linsert command} {
+    linsert {a b c} end q r
+} {a b c q r}
+test linsert-1.18 {linsert command} {
+    linsert {a} end q r
+} {a q r}
+test linsert-1.19 {linsert command} {
+    linsert {} end q r
+} {q r}
+test linsert-1.20 {linsert command, use of end-int index} {
+    linsert {a b c d} end-2 e f
+} {a b e f c d}
+
+test linsert-2.1 {linsert errors} {
+    list [catch linsert msg] $msg
+} {1 {wrong # args: should be "linsert list index ?element ...?"}}
+test linsert-2.2 {linsert errors} {
+    list [catch {linsert a b} msg] $msg
+} {1 {bad index "b": must be integer?[+-]integer? or end?[+-]integer?}}
+test linsert-2.3 {linsert errors} {
+    list [catch {linsert a 12x 2} msg] $msg
+} {1 {bad index "12x": must be integer?[+-]integer? or end?[+-]integer?}}
+test linsert-2.4 {linsert errors} {
+    list [catch {linsert \{ 12 2} msg] $msg
+} {1 {unmatched open brace in list}}
+test linsert-2.5 {syntax (TIP 323)} {
+    linsert {a b c} 0
+} [list a b c]
+test linsert-2.6 {syntax (TIP 323)} {
+    linsert "a\nb\nc" 0
+} [list a b c]
+
+test linsert-3.1 {linsert won't modify shared argument objects} {
+    proc p {} {
+        linsert "a b c" 1 "x y"
+        return "a b c"
+    }
+    p
+} "a b c"
+test linsert-3.2 {linsert won't modify shared argument objects} {
+    catch {unset lis}
+    set lis [format "a \"%s\" c" "b"]
+    linsert $lis 0 [string length $lis]
+} "7 a b c"
+
+# cleanup
+catch {unset lis}
+catch {rename p ""}
+::tcltest::cleanupTests
+return
diff --git a/tests/list.test b/tests/list.test
new file mode 100644
index 0000000..dff5d50
--- /dev/null
+++ b/tests/list.test
@@ -0,0 +1,134 @@
+# Commands covered:  list
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands.  Sourcing this file into Tcl runs the tests and
+# generates output for errors.  No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+    package require tcltest
+    namespace import -force ::tcltest::*
+}
+
+# First, a bunch of individual tests
+
+test list-1.1 {basic tests} {list a b c} {a b c}
+test list-1.2 {basic tests} {list {a b} c} {{a b} c}
+test list-1.3 {basic tests} {list \{a b c} {\{a b c}
+test list-1.4 {basic tests} "list a{}} b{} c}" "a\\{\\}\\} b{} c\\}"
+test list-1.5 {basic tests} {list a\[ b\] } "{a\[} b\\]"
+test list-1.6 {basic tests} {list c\  d\t } "{c } {d\t}"
+test list-1.7 {basic tests} {list e\n f\$ } "{e\n} {f\$}"
+test list-1.8 {basic tests} {list g\; h\\} {{g;} h\\}
+test list-1.9 {basic tests} "list a\\\[} b\\\]} " "a\\\[\\\} b\\\]\\\}"
+test list-1.10 {basic tests} "list c\\\} d\\t} " "c\\} d\\t\\}"
+test list-1.11 {basic tests} "list e\\n} f\\$} " "e\\n\\} f\\$\\}"
+test list-1.12 {basic tests} "list g\\;} h\\\\} " "g\\;\\} {h\\}}"
+test list-1.13 {basic tests} {list a {{}} b} {a {{}} b}
+test list-1.14 {basic tests} {list a b xy\\} "a b xy\\\\"
+test list-1.15 {basic tests} "list a b\} e\\" "a b\\} e\\\\"
+test list-1.16 {basic tests} "list a b\}\\\$ e\\\$\\" "a b\\}\\\$ e\\\$\\\\"
+test list-1.17 {basic tests} {list a\f \{\f} "{a\f} \\\{\\f"
+test list-1.18 {basic tests} {list a\r \{\r} "{a\r} \\\{\\r"
+test list-1.19 {basic tests} {list a\v \{\v} "{a\v} \\\{\\v"
+test list-1.20 {basic tests} {list \"\}\{} "\\\"\\}\\{"
+test list-1.21 {basic tests} {list a b c\\\nd} "a b c\\\\\\nd"
+test list-1.22 {basic tests} {list "{ab}\\"} \\{ab\\}\\\\
+test list-1.23 {basic tests} {list \{} "\\{"
+test list-1.24 {basic tests} {list} {}
+test list-1.25 {basic tests} {list # #} {{#} #}
+test list-1.26 {basic tests} {list #\{ #\{} {\#\{ #\{}
+test list-1.27 {basic null treatment} {
+    set l [list "" "\0" "\0\0"]
+    set e "{} \0 \0\0"
+    string equal $l $e
+} 1
+test list-1.28 {basic null treatment} {
+    set result "\0a\0b"
+    list $result [string length $result]
+} "\0a\0b 4"
+test list-1.29 {basic null treatment} {
+    set result "\0a\0b"
+    set srep "$result 4"
+    set lrep [list $result [string length $result]]
+    string equal $srep $lrep
+} 1
+test list-1.30 {basic null treatment} {
+    set l [list "\0abc" "xyz"]
+    set e "\0abc xyz"
+    string equal $l $e
+} 1
+
+# For the next round of tests create a list and then pick it apart
+# with "index" to make sure that we get back exactly what went in.
+
+set num 0
+proc lcheck {testid a b c} {
+    global num d
+    set d [list $a $b $c]
+    test ${testid}-0 {what goes in must come out} {lindex $d 0} $a
+    test ${testid}-1 {what goes in must come out} {lindex $d 1} $b
+    test ${testid}-2 {what goes in must come out} {lindex $d 2} $c
+}
+lcheck list-2.1  a b c
+lcheck list-2.2  "a b" c\td e\nf
+lcheck list-2.3  {{a b}} {} {  }
+lcheck list-2.4  \$ \$ab ab\$
+lcheck list-2.5  \; \;ab ab\;
+lcheck list-2.6  \[ \[ab ab\[
+lcheck list-2.7  \\ \\ab ab\\
+lcheck list-2.8  {"} {"ab} {ab"}	;#" Stupid emacs highlighting!
+lcheck list-2.9  {a b} { ab} {ab }
+lcheck list-2.10 a{ a{b \{ab
+lcheck list-2.11 a} a}b }ab
+lcheck list-2.12 a\\} {a \}b} {a \{c}
+lcheck list-2.13 xyz \\ 1\\\n2
+lcheck list-2.14 "{ab}\\" "{ab}xy" abc
+
+concat {}
+
+# Check that tclListObj.c's SetListFromAny handles possible overlarge
+# string rep lengths in the source object.
+
+proc slowsort list {
+    set result {}
+    set last [expr [llength $list] - 1]
+    while {$last > 0} {
+	set minIndex [expr [llength $list] - 1]
+	set min [lindex $list $last]
+	set i [expr $minIndex-1]
+	while {$i >= 0} {
+	    if {[string compare [lindex $list $i] $min] < 0} {
+		set minIndex $i
+		set min [lindex $list $i]
+	    }
+	    set i [expr $i-1]
+	}
+	set result [concat $result [list $min]]
+	if {$minIndex == 0} {
+	    set list [lrange $list 1 end]
+	} else {
+	    set list [concat [lrange $list 0 [expr $minIndex-1]] \
+			  [lrange $list [expr $minIndex+1] end]]
+	}
+	set last [expr $last-1]
+    }
+    return [concat $result $list]
+}
+test list-3.1 {SetListFromAny and lrange/concat results} {
+    slowsort {fred julie alex carol bill annie}
+} {alex annie bill carol fred julie}
+
+test list-4.1 {Bug 3173086} {
+    string is list "{[list \\\\\}]}"
+} 1
+
+# cleanup
+::tcltest::cleanupTests
+return
diff --git a/tests/listObj.test b/tests/listObj.test
new file mode 100644
index 0000000..d7fb46c
--- /dev/null
+++ b/tests/listObj.test
@@ -0,0 +1,209 @@
+# Functionality covered: operation of the procedures in tclListObj.c that
+# implement the Tcl type manager for the list object type.
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands. Sourcing this file into Tcl runs the tests and
+# generates output for errors.  No output means no errors were found.
+#
+# Copyright (c) 1995-1996 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+    package require tcltest
+    namespace import -force ::tcltest::*
+}
+
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
+
+testConstraint testobj [llength [info commands testobj]]
+
+catch {unset x}
+test listobj-1.1 {Tcl_GetListObjType} emptyTest {
+    # Test removed; tested an internal detail
+    # that's no longer correct, and duplicated test obj-1.1
+} {}
+
+test listobj-2.1 {Tcl_SetListObj, use in lappend} {
+    catch {unset x}
+    list [lappend x 1 abc def] [lappend x 1 ghi jkl] $x
+} {{1 abc def} {1 abc def 1 ghi jkl} {1 abc def 1 ghi jkl}}
+test listobj-2.2 {Tcl_SetListObj, use in ObjInterpProc} {
+    proc return_args {args} {
+        return $args
+    }
+    list [return_args] [return_args x] [return_args x y]
+} {{} x {x y}}
+test listobj-2.3 {Tcl_SetListObj, zero element count} {
+    list
+} {}
+
+test listobj-3.1 {Tcl_ListObjAppend, list conversion} {
+    catch {unset x}
+    list [lappend x 1 2 abc "long string"] $x
+} {{1 2 abc {long string}} {1 2 abc {long string}}}
+test listobj-3.2 {Tcl_ListObjAppend, list conversion} {
+    set x ""
+    list [lappend x first second] [lappend x third fourth] $x
+} {{first second} {first second third fourth} {first second third fourth}}
+test listobj-3.3 {Tcl_ListObjAppend, list conversion} {
+    set x "abc def"
+    list [lappend x first second] $x
+} {{abc def first second} {abc def first second}}
+test listobj-3.4 {Tcl_ListObjAppend, error in conversion} {
+    set x " \{"
+    list [catch {lappend x abc def} msg] $msg
+} {1 {unmatched open brace in list}}
+test listobj-3.5 {Tcl_ListObjAppend, force internal rep array to grow} {
+    set x ""
+    list [lappend x 1 1] [lappend x 2 2] [lappend x 3 3] [lappend x 4 4] \
+        [lappend x 5 5] [lappend x 6 6] [lappend x 7 7] [lappend x 8 8] $x
+} {{1 1} {1 1 2 2} {1 1 2 2 3 3} {1 1 2 2 3 3 4 4} {1 1 2 2 3 3 4 4 5 5} {1 1 2 2 3 3 4 4 5 5 6 6} {1 1 2 2 3 3 4 4 5 5 6 6 7 7} {1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8} {1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8}}
+
+test listobj-4.1 {Tcl_ListObjAppendElement, list conversion} {
+    catch {unset x}
+    list [lappend x 1] $x
+} {1 1}
+test listobj-4.2 {Tcl_ListObjAppendElement, list conversion} {
+    set x ""
+    list [lappend x first] [lappend x second] $x
+} {first {first second} {first second}}
+test listobj-4.3 {Tcl_ListObjAppendElement, list conversion} {
+    set x "abc def"
+    list [lappend x first] $x
+} {{abc def first} {abc def first}}
+test listobj-4.4 {Tcl_ListObjAppendElement, error in conversion} {
+    set x " \{"
+    list [catch {lappend x abc} msg] $msg
+} {1 {unmatched open brace in list}}
+test listobj-4.5 {Tcl_ListObjAppendElement, force internal rep array to grow} {
+    set x ""
+    list [lappend x 1] [lappend x 2] [lappend x 3] [lappend x 4] \
+        [lappend x 5] [lappend x 6] [lappend x 7] [lappend x 8] $x
+} {1 {1 2} {1 2 3} {1 2 3 4} {1 2 3 4 5} {1 2 3 4 5 6} {1 2 3 4 5 6 7} {1 2 3 4 5 6 7 8} {1 2 3 4 5 6 7 8}}
+
+test listobj-5.1 {Tcl_ListObjIndex, basic tests} {
+    lindex {a b c} 0
+} a
+test listobj-5.2 {Tcl_ListObjIndex, basic tests} {
+    lindex a 0
+} a
+test listobj-5.3 {Tcl_ListObjIndex, basic tests} {
+    lindex {a {b c d} x} 1
+} {b c d}
+test listobj-5.4 {Tcl_ListObjIndex, basic tests} {
+    lindex {a b c} 3
+} {}
+test listobj-5.5 {Tcl_ListObjIndex, basic tests} {
+    lindex {a b c} 100
+} {}
+test listobj-5.6 {Tcl_ListObjIndex, basic tests} {
+    lindex a 100
+} {}
+test listobj-5.7 {Tcl_ListObjIndex, basic tests} {
+    lindex {} -1
+} {}
+test listobj-5.8 {Tcl_ListObjIndex, error in conversion} {
+    set x " \{"
+    list [catch {lindex $x 0} msg] $msg
+} {1 {unmatched open brace in list}}
+
+test listobj-6.1 {Tcl_ListObjLength} {
+    llength {a b c d}
+} 4
+test listobj-6.2 {Tcl_ListObjLength} {
+    llength {a b c {a b {c d}} d}
+} 5
+test listobj-6.3 {Tcl_ListObjLength} {
+    llength {}
+} 0
+test listobj-6.4 {Tcl_ListObjLength, convert from non-list} {
+    llength 123
+} 1
+test listobj-6.5 {Tcl_ListObjLength, error converting from non-list} {
+    list [catch {llength "a b c \{"} msg] $msg
+} {1 {unmatched open brace in list}}
+test listobj-6.6 {Tcl_ListObjLength, error converting from non-list} {
+    list [catch {llength "a {b}c"} msg] $msg
+} {1 {list element in braces followed by "c" instead of space}}
+
+test listobj-7.1 {Tcl_ListObjReplace, conversion from non-list} {
+    lreplace 123 0 0 x
+} {x}
+test listobj-7.2 {Tcl_ListObjReplace, error converting from non-list} {
+    list [catch {lreplace "a b c \{" 1 1 x} msg] $msg
+} {1 {unmatched open brace in list}}
+test listobj-7.3 {Tcl_ListObjReplace, error converting from non-list} {
+    list [catch {lreplace "a {b}c" 1 2 x} msg] $msg
+} {1 {list element in braces followed by "c" instead of space}}
+test listobj-7.4 {Tcl_ListObjReplace, negative first element index} {
+    lreplace {1 2 3 4 5} -1 1 a
+} {a 3 4 5}
+test listobj-7.5 {Tcl_ListObjReplace, last element index >= num elems} {
+    lreplace {1 2 3 4 5} 3 7 a b c
+} {1 2 3 a b c}
+test listobj-7.6 {Tcl_ListObjReplace, first element index > last index} {
+    lreplace {1 2 3 4 5} 3 1 a b c
+} {1 2 3 a b c 4 5}
+test listobj-7.7 {Tcl_ListObjReplace, no new elements} {
+    lreplace {1 2 3 4 5} 1 1
+} {1 3 4 5}
+test listobj-7.8 {Tcl_ListObjReplace, shrink array in place} {
+    lreplace {1 2 3 4 5 6 7} 4 5
+} {1 2 3 4 7}
+test listobj-7.9 {Tcl_ListObjReplace, grow array in place} {
+    lreplace {1 2 3 4 5 6 7} 1 3 a b c d e
+} {1 a b c d e 5 6 7}
+test listobj-7.10 {Tcl_ListObjReplace, replace tail of array} {
+    lreplace {1 2 3 4 5 6 7} 3 6 a
+} {1 2 3 a}
+test listobj-7.11 {Tcl_ListObjReplace, must grow internal array} {
+    lreplace {1 2 3 4 5} 2 3 a b c d e f g h i j k l
+} {1 2 a b c d e f g h i j k l 5}
+test listobj-7.12 {Tcl_ListObjReplace, grow array, insert at start} {
+    lreplace {1 2 3 4 5} -1 -1 a b c d e f g h i j k l
+} {a b c d e f g h i j k l 1 2 3 4 5}
+test listobj-7.13 {Tcl_ListObjReplace, grow array, insert at end} {
+    lreplace {1 2 3 4 5} 4 1 a b c d e f g h i j k l
+} {1 2 3 4 a b c d e f g h i j k l 5}
+
+test listobj-8.1 {SetListFromAny} {
+    lindex {0 foo\x00help 2} 1
+} "foo\x00help"
+
+test listobj-9.1 {UpdateStringOfList} {
+    string length [list foo\x00help]
+} 8
+
+test listobj-10.1 {Bug [2971669]} {*}{
+    -constraints testobj
+    -setup {
+	testobj freeallvars
+    }
+    -body {
+	set result {}
+	lappend result \
+	    [testlistobj set 1 a b c d e] \
+	    [testlistobj replace 1 0x7fffffff 0x7fffffff f] \
+	    [testlistobj get 1]
+    }
+    -cleanup {
+	testobj freeallvars
+    }
+    -result {{a b c d e} {} {a b c d e f}}
+}
+
+test listobj-11.1 {Bug 3598580: Tcl_ListObjReplace refcount management} testobj {
+    testobj bug3598580
+} 123
+
+# cleanup
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/tests/llength.test b/tests/llength.test
new file mode 100644
index 0000000..169c7ca
--- /dev/null
+++ b/tests/llength.test
@@ -0,0 +1,41 @@
+# Commands covered:  llength
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands.  Sourcing this file into Tcl runs the tests and
+# generates output for errors.  No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+    package require tcltest
+    namespace import -force ::tcltest::*
+}
+
+test llength-1.1 {length of list} {
+    llength {a b c d}
+} 4
+test llength-1.2 {length of list} {
+    llength {a b c {a b {c d}} d}
+} 5
+test llength-1.3 {length of list} {
+    llength {}
+} 0
+
+test llength-2.1 {error conditions} {
+    list [catch {llength} msg] $msg
+} {1 {wrong # args: should be "llength list"}}
+test llength-2.2 {error conditions} {
+    list [catch {llength 123 2} msg] $msg
+} {1 {wrong # args: should be "llength list"}}
+test llength-2.3 {error conditions} {
+    list [catch {llength "a b c \{"} msg] $msg
+} {1 {unmatched open brace in list}}
+
+# cleanup
+::tcltest::cleanupTests
+return
diff --git a/tests/lmap.test b/tests/lmap.test
new file mode 100644
index 0000000..08035d9
--- /dev/null
+++ b/tests/lmap.test
@@ -0,0 +1,471 @@
+# Commands covered:  lmap, continue, break
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands.  Sourcing this file into Tcl runs the tests and
+# generates output for errors.  No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994-1997 Sun Microsystems, Inc.
+# Copyright (c) 2011 Trevor Davel
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+# RCS: @(#) $Id: $
+
+if {"::tcltest" ni [namespace children]} {
+    package require tcltest 2
+    namespace import -force ::tcltest::*
+}
+
+unset -nocomplain a b i x
+
+# ----- Non-compiled operation -----------------------------------------------
+
+# Basic "lmap" operation (non-compiled)
+test lmap-1.1 {basic lmap tests} {
+    set a {}
+    lmap i {a b c d} {
+	set a [concat $a $i]
+    }
+} {a {a b} {a b c} {a b c d}}
+test lmap-1.2 {basic lmap tests} {
+    lmap i {a b {{c d} e} {123 {{x}}}} {
+	set i
+    }
+} {a b {{c d} e} {123 {{x}}}}
+test lmap-1.2a {basic lmap tests} {
+    lmap i {a b {{c d} e} {123 {{x}}}} {
+	return -level 0 $i
+    }
+} {a b {{c d} e} {123 {{x}}}}
+test lmap-1.4 {basic lmap tests} -returnCodes error -body {
+    lmap
+} -result {wrong # args: should be "lmap varList list ?varList list ...? command"}
+test lmap-1.6 {basic lmap tests} -returnCodes error -body {
+    lmap i
+} -result {wrong # args: should be "lmap varList list ?varList list ...? command"}
+test lmap-1.8 {basic lmap tests} -returnCodes error -body {
+    lmap i j
+} -result {wrong # args: should be "lmap varList list ?varList list ...? command"}
+test lmap-1.10 {basic lmap tests} -returnCodes error -body {
+    lmap i j k l
+} -result {wrong # args: should be "lmap varList list ?varList list ...? command"}
+test lmap-1.11 {basic lmap tests} {
+    lmap i {} {
+	set i
+    }
+} {}
+test lmap-1.12 {basic lmap tests} {
+    lmap i {} {
+	return -level 0 x
+    }
+} {}
+test lmap-1.13 {lmap errors} -returnCodes error -body {
+    lmap {{a}{b}} {1 2 3} {}
+} -result {list element in braces followed by "{b}" instead of space}
+test lmap-1.14 {lmap errors} -returnCodes error -body {
+    lmap a {{1 2}3} {}
+} -result {list element in braces followed by "3" instead of space}
+unset -nocomplain a
+test lmap-1.15 {lmap errors} -setup {
+    unset -nocomplain a
+} -body {
+    set a(0) 44
+    list [catch {lmap a {1 2 3} {}} msg o] $msg $::errorInfo
+} -result {1 {can't set "a": variable is array} {can't set "a": variable is array
+    (setting lmap loop variable "a")
+    invoked from within
+"lmap a {1 2 3} {}"}}
+test lmap-1.16 {lmap errors} -returnCodes error -body {
+    lmap {} {} {}
+} -result {lmap varlist is empty}
+unset -nocomplain a
+
+# Parallel "lmap" operation (non-compiled)
+test lmap-2.1 {parallel lmap tests} {
+    lmap {a b} {1 2 3 4} {
+	list $b $a
+    }
+} {{2 1} {4 3}}
+test lmap-2.2 {parallel lmap tests} {
+    lmap {a b} {1 2 3 4 5} {
+	list $b $a
+    }
+} {{2 1} {4 3} {{} 5}}
+test lmap-2.3 {parallel lmap tests} {
+    lmap a {1 2 3} b {4 5 6} {
+	list $b $a
+    }
+} {{4 1} {5 2} {6 3}}
+test lmap-2.4 {parallel lmap tests} {
+    lmap a {1 2 3} b {4 5 6 7 8} {
+	list $b $a
+    }
+} {{4 1} {5 2} {6 3} {7 {}} {8 {}}}
+test lmap-2.5 {parallel lmap tests} {
+    lmap {a b} {a b A B aa bb} c {c C cc CC} {
+	list $a $b $c
+    }
+} {{a b c} {A B C} {aa bb cc} {{} {} CC}}
+test lmap-2.6 {parallel lmap tests} {
+    lmap a {1 2 3} b {1 2 3} c {1 2 3} d {1 2 3} e {1 2 3} {
+	list $a$b$c$d$e
+    }
+} {11111 22222 33333}
+test lmap-2.7 {parallel lmap tests} {
+    lmap a {} b {1 2 3} c {1 2} d {1 2 3 4} e {{1 2}} {
+	set x $a$b$c$d$e
+    }
+} {{1111 2} 222 33 4}
+test lmap-2.8 {parallel lmap tests} {
+    lmap a {} b {1 2 3} c {1 2} d {1 2 3 4} e {{1 2}} {
+	join [list $a $b $c $d $e] .
+    }
+} {{.1.1.1.1 2} .2.2.2. .3..3. ...4.}
+test lmap-2.9 {lmap only sets vars if repeating loop} {
+    namespace eval ::lmap_test {
+	set rgb {65535 0 0}
+	lmap {r g b} [set rgb] {}
+	set ::x "r=$r, g=$g, b=$b"
+    }
+    namespace delete ::lmap_test
+    set x
+} {r=65535, g=0, b=0}
+test lmap-2.10 {lmap only supports local scalar variables} -setup {
+    unset -nocomplain a
+} -body {
+    lmap {a(3)} {1 2 3 4} {set {a(3)}}
+} -result {1 2 3 4}
+unset -nocomplain a
+
+# "lmap" with "continue" and "break" (non-compiled)
+test lmap-3.1 {continue tests} {
+    lmap i {a b c d} {
+	if {[string compare $i "b"] == 0} continue
+	set i
+    }
+} {a c d}
+test lmap-3.2 {continue tests} {
+    set x 0
+    list [lmap i {a b c d} {
+    	incr x
+    	if {[string compare $i "b"] != 0} continue
+    	set i
+    }] $x
+} {b 4}
+test lmap-3.3 {break tests} {
+    set x 0
+    list [lmap i {a b c d} {
+	incr x
+    	if {[string compare $i "c"] == 0} break
+    	set i
+    }] $x
+} {{a b} 3}
+# Check for bug similar to #406709
+test lmap-3.4 {break tests} {
+    set a 1
+    lmap b b {list [concat a; break]; incr a}
+    incr a
+} {2}
+
+# ----- Compiled operation ---------------------------------------------------
+
+# Basic "lmap" operation (compiled)
+test lmap-4.1 {basic lmap tests} {
+    apply {{} {
+	set a {}
+	lmap i {a b c d} {
+	    set a [concat $a $i]
+	}
+    }}
+} {a {a b} {a b c} {a b c d}}
+test lmap-4.2 {basic lmap tests} {
+    apply {{} {
+	lmap i {a b {{c d} e} {123 {{x}}}} {
+	    set i
+	}
+    }}
+} {a b {{c d} e} {123 {{x}}}}
+test lmap-4.2a {basic lmap tests} {
+    apply {{} {
+	lmap i {a b {{c d} e} {123 {{x}}}} {
+	    return -level 0 $i
+	}
+    }}
+} {a b {{c d} e} {123 {{x}}}}
+test lmap-4.4 {basic lmap tests} -returnCodes error -body {
+    apply {{} { lmap }}
+} -result {wrong # args: should be "lmap varList list ?varList list ...? command"}
+test lmap-4.6 {basic lmap tests} -returnCodes error -body {
+    apply {{} { lmap i }}
+} -result {wrong # args: should be "lmap varList list ?varList list ...? command"}
+test lmap-4.8 {basic lmap tests} -returnCodes error -body {
+    apply {{} { lmap i j }}
+} -result {wrong # args: should be "lmap varList list ?varList list ...? command"}
+test lmap-4.10 {basic lmap tests} -returnCodes error -body {
+    apply {{} { lmap i j k l }}
+} -result {wrong # args: should be "lmap varList list ?varList list ...? command"}
+test lmap-4.11 {basic lmap tests} {
+    apply {{} { lmap i {} { set i } }}
+} {}
+test lmap-4.12 {basic lmap tests} {
+    apply {{} { lmap i {} { return -level 0 x } }}
+} {}
+test lmap-4.13 {lmap errors} -returnCodes error -body {
+    apply {{} { lmap {{a}{b}} {1 2 3} {} }}
+} -result {list element in braces followed by "{b}" instead of space}
+test lmap-4.14 {lmap errors} -returnCodes error -body {
+    apply {{} { lmap a {{1 2}3} {} }}
+} -result {list element in braces followed by "3" instead of space}
+unset -nocomplain a
+test lmap-4.15 {lmap errors} {
+    apply {{} { 
+	set a(0) 44
+	list [catch {lmap a {1 2 3} {}} msg o] $msg $::errorInfo 
+    }} 
+} {1 {can't set "a": variable is array} {can't set "a": variable is array
+    while executing
+"lmap a {1 2 3} {}"}}
+test lmap-4.16 {lmap errors} -returnCodes error -body {
+    apply {{} {
+	lmap {} {} {}
+    }}
+} -result {lmap varlist is empty}
+unset -nocomplain a
+
+# Parallel "lmap" operation (compiled)
+test lmap-5.1 {parallel lmap tests} {
+    apply {{} {
+	lmap {a b} {1 2 3 4} {
+	    list $b $a
+	}
+    }}
+} {{2 1} {4 3}}
+test lmap-5.2 {parallel lmap tests} {
+    apply {{} {
+	lmap {a b} {1 2 3 4 5} {
+	    list $b $a
+	}
+    }}
+} {{2 1} {4 3} {{} 5}}
+test lmap-5.3 {parallel lmap tests} {
+    apply {{} {
+	lmap a {1 2 3} b {4 5 6} {
+	    list $b $a
+	}
+    }}
+} {{4 1} {5 2} {6 3}}
+test lmap-5.4 {parallel lmap tests} {
+    apply {{} {
+	lmap a {1 2 3} b {4 5 6 7 8} {
+	    list $b $a
+	}
+    }}
+} {{4 1} {5 2} {6 3} {7 {}} {8 {}}}
+test lmap-5.5 {parallel lmap tests} {
+    apply {{} {
+	lmap {a b} {a b A B aa bb} c {c C cc CC} {
+	    list $a $b $c
+	}
+    }}
+} {{a b c} {A B C} {aa bb cc} {{} {} CC}}
+test lmap-5.6 {parallel lmap tests} {
+    apply {{} {
+	lmap a {1 2 3} b {1 2 3} c {1 2 3} d {1 2 3} e {1 2 3} {
+	    list $a$b$c$d$e
+	}
+    }}
+} {11111 22222 33333}
+test lmap-5.7 {parallel lmap tests} {
+    apply {{} {
+	lmap a {} b {1 2 3} c {1 2} d {1 2 3 4} e {{1 2}} {
+	    set x $a$b$c$d$e
+	}
+    }}
+} {{1111 2} 222 33 4}
+test lmap-5.8 {parallel lmap tests} {
+    apply {{} {
+	lmap a {} b {1 2 3} c {1 2} d {1 2 3 4} e {{1 2}} {
+	    join [list $a $b $c $d $e] .
+	}
+    }}
+} {{.1.1.1.1 2} .2.2.2. .3..3. ...4.}
+test lmap-5.9 {lmap only sets vars if repeating loop} {
+    apply {{} {
+        set rgb {65535 0 0}
+        lmap {r g b} [set rgb] {}
+        return "r=$r, g=$g, b=$b"
+    }}
+} {r=65535, g=0, b=0}
+test lmap-5.10 {lmap only supports local scalar variables} {
+    apply {{} {
+        lmap {a(3)} {1 2 3 4} {set {a(3)}}
+    }}
+} {1 2 3 4}
+
+# "lmap" with "continue" and "break" (compiled)
+test lmap-6.1 {continue tests} {
+    apply {{} {
+	lmap i {a b c d} {
+	    if {[string compare $i "b"] == 0} continue
+	    set i
+	}
+    }}
+} {a c d}
+test lmap-6.2 {continue tests} {
+    apply {{} {
+	list [lmap i {a b c d} {
+	    incr x
+	    if {[string compare $i "b"] != 0} continue
+	    set i
+	}] $x
+    }}
+} {b 4}
+test lmap-6.3 {break tests} {
+    apply {{} {
+	list [lmap i {a b c d} {
+	    incr x
+	    if {[string compare $i "c"] == 0} break
+	    set i
+	}] $x
+    }}
+} {{a b} 3}
+# Check for bug similar to #406709
+test lmap-6.4 {break tests} {
+    apply {{} {
+	set a 1
+	lmap b b {list [concat a; break]; incr a}
+	incr a
+    }}
+} {2}
+
+# ----- Special cases and bugs -----------------------------------------------
+test lmap-7.1 {compiled lmap backward jump works correctly} -setup {
+    unset -nocomplain x
+} -body {
+    array set x {0 zero 1 one 2 two 3 three}
+    lsort [apply {{arrayName} {
+        upvar 1 $arrayName a
+        lmap member [array names a] {
+            list $member [set a($member)]
+        }
+    }} x]
+} -result [lsort {{0 zero} {1 one} {2 two} {3 three}}]
+test lmap-7.2 {noncompiled lmap and shared variable or value list objects that are converted to another type} -setup {
+    unset -nocomplain x
+} -body {
+    lmap {12.0} {a b c} {
+        set x 12.0
+        set x [expr $x + 1]
+    }
+} -result {13.0 13.0 13.0}
+# Test for incorrect "double evaluation" semantics
+test lmap-7.3 {delayed substitution of body} {
+    apply {{} {
+       set a 0
+       lmap a [list 1 2 3] "
+           set x $a
+       "
+       return $x
+    }}
+} {0}
+# Related to "foreach" test for [Bug 1189274]; crash on failure
+test lmap-7.4 {empty list handling} {
+    proc crash {} {
+	rename crash {}
+	set a "x y z"
+	set b ""
+	lmap aa $a bb $b { set x "aa = $aa bb = $bb" }
+    }
+    crash
+} {{aa = x bb = } {aa = y bb = } {aa = z bb = }}
+# Related to [Bug 1671138]; infinite loop with empty var list in bytecompiled
+# version.
+test lmap-7.5 {compiled empty var list} -returnCodes error -body {
+    proc foo {} {
+	lmap {} x {
+	    error "reached body"
+	}
+    }
+    foo
+} -cleanup {
+    catch {rename foo ""}
+} -result {lmap varlist is empty}
+test lmap-7.6 {lmap: related to "foreach" [Bug 1671087]} -setup {
+    proc demo {} {
+	set vals {1 2 3 4}
+	trace add variable x write {string length $vals ;# }
+	lmap {x y} $vals {format $y}
+    }
+} -body {
+    demo
+} -cleanup {
+    rename demo {}
+} -result {2 4}
+# Huge lists must not overflow the bytecode interpreter (development bug)
+test lmap-7.7 {huge list non-compiled} -setup {
+    unset -nocomplain a b x
+} -body {
+    set x [lmap a [lrepeat 1000000 x] { set b y$a }]
+    list $b [llength $x] [string length $x]
+} -result {yx 1000000 2999999}
+test lmap-7.8 {huge list compiled} -setup {
+    unset -nocomplain a b x
+} -body {
+    set x [apply {{times} {
+	global b
+	lmap a [lrepeat $times x] { set b Y$a }
+    }} 1000000]
+    list $b [llength $x] [string length $x]
+} -result {Yx 1000000 2999999}
+test lmap-7.9 {error then dereference loop var (dev bug)} {
+    catch { lmap a 0 b {1 2 3} { error x } }
+    set a
+} 0
+test lmap-7.9a {error then dereference loop var (dev bug)} {
+    catch { lmap a 0 b {1 2 3} { incr a $b; error x } }
+    set a
+} 1
+
+# ----- Coroutines -----------------------------------------------------------
+test lmap-8.1 {lmap non-compiled with coroutines} -body {
+    coroutine coro apply {{} {
+	set values [yield [info coroutine]]
+	eval lmap i [list $values] {{ yield $i }}
+    }} ;# returns 'coro'
+    coro {a b c d e f} ;# -> a
+    coro 1 ;# -> b
+    coro 2 ;# -> c
+    coro 3 ;# -> d
+    coro 4 ;# -> e
+    coro 5 ;# -> f
+    list [coro 6] [info commands coro]
+} -cleanup {
+    catch {rename coro ""}
+} -result {{1 2 3 4 5 6} {}}
+test lmap-8.2 {lmap compiled with coroutines} -body {
+    coroutine coro apply {{} {
+	set values [yield [info coroutine]]
+	lmap i $values { yield $i }
+    }} ;# returns 'coro'
+    coro {a b c d e f} ;# -> a
+    coro 1 ;# -> b
+    coro 2 ;# -> c
+    coro 3 ;# -> d
+    coro 4 ;# -> e
+    coro 5 ;# -> f
+    list [coro 6] [info commands coro]
+} -cleanup {
+    catch {rename coro ""}
+} -result {{1 2 3 4 5 6} {}}
+
+# cleanup
+unset -nocomplain a x
+catch {rename foo {}}
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/tests/load.test b/tests/load.test
new file mode 100644
index 0000000..7c4b47f
--- /dev/null
+++ b/tests/load.test
@@ -0,0 +1,248 @@
+# Commands covered:  load
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands.  Sourcing this file into Tcl runs the tests and
+# generates output for errors.  No output means no errors were found.
+#
+# Copyright (c) 1995 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+    package require tcltest 2
+    namespace import -force ::tcltest::*
+}
+
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
+
+# Figure out what extension is used for shared libraries on this
+# platform.
+if {![info exists ext]} {
+    set ext [info sharedlibextension]
+}
+# Tests require the existence of one of the DLLs in the dltest directory.
+set testDir [file join [file dirname [info nameofexecutable]] dltest]
+set x [file join $testDir pkga$ext]
+set dll "[file tail $x]Required"
+testConstraint $dll [file readable $x]
+
+# Tests also require that this DLL has not already been loaded.
+set loaded "[file tail $x]Loaded"
+set alreadyLoaded [info loaded]
+testConstraint $loaded [expr {![string match *pkga* $alreadyLoaded]}]
+
+set alreadyTotalLoaded [info loaded]
+
+# Certain tests require the 'teststaticpkg' command from tcltest
+
+testConstraint teststaticpkg [llength [info commands teststaticpkg]]
+
+# Test load-10.1 requires the 'testsimplefilesystem' command from tcltest
+
+testConstraint testsimplefilesystem \
+	[llength [info commands testsimplefilesystem]]
+
+test load-1.1 {basic errors} {} {
+    list [catch {load} msg] $msg
+} "1 {wrong \# args: should be \"load ?-global? ?-lazy? ?--? fileName ?packageName? ?interp?\"}"
+test load-1.2 {basic errors} {} {
+    list [catch {load a b c d} msg] $msg
+} "1 {wrong \# args: should be \"load ?-global? ?-lazy? ?--? fileName ?packageName? ?interp?\"}"
+test load-1.3 {basic errors} {} {
+    list [catch {load a b foobar} msg] $msg
+} {1 {could not find interpreter "foobar"}}
+test load-1.4 {basic errors} {} {
+    list [catch {load -global {}} msg] $msg
+} {1 {must specify either file name or package name}}
+test load-1.5 {basic errors} {} {
+    list [catch {load -lazy {} {}} msg] $msg
+} {1 {must specify either file name or package name}}
+test load-1.6 {basic errors} {} {
+    list [catch {load {} Unknown} msg] $msg
+} {1 {package "Unknown" isn't loaded statically}}
+test load-1.7 {basic errors} {} {
+    list [catch {load -abc foo} msg] $msg
+} "1 {bad option \"-abc\": must be -global, -lazy, or --}"
+test load-1.8 {basic errors} {} {
+    list [catch {load -global} msg] $msg
+} "1 {couldn't figure out package name for -global}"
+
+test load-2.1 {basic loading, with guess for package name} \
+	[list $dll $loaded] {
+    load -global [file join $testDir pkga$ext]
+    list [pkga_eq abc def] [lsort [info commands pkga_*]]
+} {0 {pkga_eq pkga_quote}}
+interp create -safe child
+test load-2.2 {loading into a safe interpreter, with package name conversion} \
+	[list $dll $loaded] {
+    load -lazy [file join $testDir pkgb$ext] pKgB child
+    list [child eval pkgb_sub 44 13] [catch {child eval pkgb_unsafe} msg] $msg \
+	    [catch {pkgb_sub 12 10} msg2] $msg2
+} {31 1 {invalid command name "pkgb_unsafe"} 1 {invalid command name "pkgb_sub"}}
+test load-2.3 {loading with no _Init procedure} -constraints [list $dll $loaded] \
+-body {
+    list [catch {load [file join $testDir pkgc$ext] foo} msg] $msg $errorCode
+} -match glob \
+    -result [list 1 {cannot find symbol "Foo_Init"*} \
+		 {TCL LOOKUP LOAD_SYMBOL *Foo_Init}]
+test load-2.4 {loading with no _SafeInit procedure} [list $dll $loaded] {
+    list [catch {load [file join $testDir pkga$ext] {} child} msg] $msg
+} {1 {can't use package in a safe interpreter: no Pkga_SafeInit procedure}}
+
+test load-3.1 {error in _Init procedure, same interpreter} \
+	[list $dll $loaded] {
+    list [catch {load [file join $testDir pkge$ext] pkge} msg] \
+	    $msg $::errorInfo $::errorCode
+} {1 {couldn't open "non_existent": no such file or directory} {couldn't open "non_existent": no such file or directory
+    while executing
+"open non_existent"
+    invoked from within
+"if 44 {open non_existent}"
+    invoked from within
+"load [file join $testDir pkge$ext] pkge"} {POSIX ENOENT {no such file or directory}}}
+test load-3.2 {error in _Init procedure, slave interpreter} \
+	[list $dll $loaded] {
+    catch {interp delete x}
+    interp create x
+    set ::errorCode foo
+    set ::errorInfo bar
+    set result [list [catch {load [file join $testDir pkge$ext] pkge x} msg] \
+	    $msg $::errorInfo $::errorCode]
+    interp delete x
+    set result
+} {1 {couldn't open "non_existent": no such file or directory} {couldn't open "non_existent": no such file or directory
+    while executing
+"open non_existent"
+    invoked from within
+"if 44 {open non_existent}"
+    invoked from within
+"load [file join $testDir pkge$ext] pkge x"} {POSIX ENOENT {no such file or directory}}}
+
+test load-4.1 {reloading package into same interpreter} [list $dll $loaded] {
+    list [catch {load [file join $testDir pkga$ext] pkga} msg] $msg
+} {0 {}}
+test load-4.2 {reloading package into same interpreter} -setup {
+    catch {load [file join $testDir pkga$ext] pkga}
+} -constraints [list $dll $loaded] -returnCodes error -body {
+    load [file join $testDir pkga$ext] pkgb
+} -result "file \"[file join $testDir pkga$ext]\" is already loaded for package \"Pkga\""
+
+test load-5.1 {file name not specified and no static package: pick default} \
+	[list $dll $loaded] {
+    catch {interp delete x}
+    interp create x
+    load -global [file join $testDir pkga$ext] pkga
+    load {} pkga x
+    set result [info loaded x]
+    interp delete x
+    set result
+} [list [list [file join $testDir pkga$ext] Pkga]]
+
+# On some platforms, like SunOS 4.1.3, these tests can't be run because
+# they cause the process to exit.
+#
+# As of 2005, such ancient broken systems no longer matter.
+
+test load-6.1 {errors loading file} [list $dll $loaded] {
+    catch {load foo foo}
+} {1}
+
+test load-7.1 {Tcl_StaticPackage procedure} [list teststaticpkg] {
+    set x "not loaded"
+    teststaticpkg Test 1 0
+    load {} Test
+    load {} Test child
+    list [set x] [child eval set x]
+} {loaded loaded}
+test load-7.2 {Tcl_StaticPackage procedure} [list teststaticpkg] {
+    set x "not loaded"
+    teststaticpkg Another 0 0
+    load {} Another
+    child eval {set x "not loaded"}
+    list [catch {load {} Another child} msg] $msg \
+	[child eval set x] [set x]
+} {1 {can't use package in a safe interpreter: no Another_SafeInit procedure} {not loaded} loaded}
+test load-7.3 {Tcl_StaticPackage procedure} [list teststaticpkg] {
+    set x "not loaded"
+    teststaticpkg More 0 1
+    load {} More
+    set x
+} {not loaded}
+catch {load [file join $testDir pkga$ext] pkga}
+catch {load [file join $testDir pkgb$ext] pkgb}
+catch {load [file join $testDir pkge$ext] pkge}
+set currentRealPackages [list [list [file join $testDir pkge$ext] Pkge] [list [file join $testDir pkgb$ext] Pkgb] [list [file join $testDir pkga$ext] Pkga]]
+test load-7.4 {Tcl_StaticPackage procedure, redundant calls} -setup {
+    teststaticpkg Test 1 0
+    teststaticpkg Another 0 0
+    teststaticpkg More 0 1
+} -constraints [list teststaticpkg $dll $loaded] -body {
+    teststaticpkg Double 0 1
+    teststaticpkg Double 0 1
+    info loaded
+} -result [list {{} Double} {{} More} {{} Another} {{} Test} {*}$currentRealPackages {*}$alreadyTotalLoaded]
+
+teststaticpkg Test 1 1
+teststaticpkg Another 0 1
+teststaticpkg More 0 1
+teststaticpkg Double 0 1
+test load-8.1 {TclGetLoadedPackages procedure} [list teststaticpkg $dll $loaded] {
+    lsort -index 1 [info loaded]
+} [lsort -index 1 [list {{} Double} {{} More} {{} Another} {{} Test} {*}$currentRealPackages {*}$alreadyTotalLoaded]]
+test load-8.2 {TclGetLoadedPackages procedure} -body {
+    info loaded gorp
+} -returnCodes error -result {could not find interpreter "gorp"}
+test load-8.3a {TclGetLoadedPackages procedure} [list teststaticpkg $dll $loaded] {
+    lsort -index 1 [info loaded {}]
+} [lsort -index 1 [list {{} Double} {{} More} {{} Another} {{} Test} [list [file join $testDir pkga$ext] Pkga] [list [file join $testDir pkgb$ext] Pkgb] {*}$alreadyLoaded]]
+test load-8.3b {TclGetLoadedPackages procedure} [list teststaticpkg $dll $loaded] {
+    lsort -index 1 [info loaded child]
+} [lsort -index 1 [list {{} Test} [list [file join $testDir pkgb$ext] Pkgb]]]
+test load-8.4 {TclGetLoadedPackages procedure} [list $dll $loaded teststaticpkg] {
+    load [file join $testDir pkgb$ext] pkgb
+    list [lsort -index 1 [info loaded {}]] [lsort [info commands pkgb_*]]
+} [list [lsort -index 1 [concat [list [list [file join $testDir pkgb$ext] Pkgb] {{} Double} {{} More} {{} Another} {{} Test} [list [file join $testDir pkga$ext] Pkga]] $alreadyLoaded]] {pkgb_demo pkgb_sub pkgb_unsafe}]
+interp delete child
+
+test load-9.1 {Tcl_StaticPackage, load already-loaded package into another interp} \
+    -constraints {teststaticpkg} \
+    -setup {
+	interp create child1
+	interp create child2
+	load {} Tcltest child1
+	load {} Tcltest child2
+    } \
+    -body {
+	child1 eval { teststaticpkg Loadninepointone 0 1 }
+	child2 eval { teststaticpkg Loadninepointone 0 1 }
+	list \
+	    [child1 eval { info loaded {} }] \
+	    [child2 eval { info loaded {} }]
+    } \
+    -match glob -result {{{{} Loadninepointone} {* Tcltest}} {{{} Loadninepointone} {* Tcltest}}} \
+    -cleanup { interp delete child1 ; interp delete child2 }
+
+test load-10.1 {load from vfs} \
+    -constraints [list $dll $loaded testsimplefilesystem] \
+    -setup {set dir [pwd]; cd $testDir; testsimplefilesystem 1} \
+    -body {list [catch {load simplefs:/pkgd$ext pkgd} msg] $msg} \
+    -result {0 {}} \
+    -cleanup {testsimplefilesystem 0; cd $dir; unset dir}
+
+test load-11.1 {Load TclOO extension using Stubs (Bug [f51efe99a7])} \
+	[list $dll $loaded] {
+    load [file join $testDir pkgooa$ext]
+    list [pkgooa_stubsok] [lsort [info commands pkgooa_*]]
+} {1 pkgooa_stubsok}
+
+# cleanup
+unset ext
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/tests/lrange.test b/tests/lrange.test
new file mode 100644
index 0000000..17a757e
--- /dev/null
+++ b/tests/lrange.test
@@ -0,0 +1,100 @@
+# Commands covered:  lrange
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands.  Sourcing this file into Tcl runs the tests and
+# generates output for errors.  No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+    package require tcltest
+    namespace import -force ::tcltest::*
+}
+
+test lrange-1.1 {range of list elements} {
+    lrange {a b c d} 1 2
+} {b c}
+test lrange-1.2 {range of list elements} {
+    lrange {a {bcd e {f g {}}} l14 l15 d} 1 1
+} {{bcd e {f g {}}}}
+test lrange-1.3 {range of list elements} {
+    lrange {a {bcd e {f g {}}} l14 l15 d} 3 end
+} {l15 d}
+test lrange-1.4 {range of list elements} {
+    lrange {a {bcd e {f g {}}} l14 l15 d} 4 10000
+} {d}
+test lrange-1.5 {range of list elements} {
+    lrange {a {bcd e {f g {}}} l14 l15 d} 4 3
+} {}
+test lrange-1.6 {range of list elements} {
+    lrange {a {bcd e {f g {}}} l14 l15 d} 10 11
+} {}
+test lrange-1.7 {range of list elements} {
+    lrange {a b c d e} -1 2
+} {a b c}
+test lrange-1.8 {range of list elements} {
+    lrange {a b c d e} -2 -1
+} {}
+test lrange-1.9 {range of list elements} {
+    lrange {a b c d e} -2 end
+} {a b c d e}
+test lrange-1.10 {range of list elements} {
+    lrange "a b\{c d" 1 2
+} "b\\{c d"
+test lrange-1.11 {range of list elements} {
+    lrange "a b c d" end end
+} d
+test lrange-1.12 {range of list elements} {
+    lrange "a b c d" end 100000
+} d
+test lrange-1.13 {range of list elements} {
+    lrange "a b c d" end 3
+} d
+test lrange-1.14 {range of list elements} {
+    lrange "a b c d" end 2
+} {}
+test lrange-1.15 {range of list elements} {
+    concat \"[lrange {a b \{\   	} 0 2]"
+} {"a b \{\ "}
+# emacs highlighting bug workaround --> "
+test lrange-1.16 {list element quoting} {
+    lrange {[append a .b]} 0 end    
+} {{[append} a .b\]}
+
+test lrange-2.1 {error conditions} {
+    list [catch {lrange a b} msg] $msg
+} {1 {wrong # args: should be "lrange list first last"}}
+test lrange-2.2 {error conditions} {
+    list [catch {lrange a b 6 7} msg] $msg
+} {1 {wrong # args: should be "lrange list first last"}}
+test lrange-2.3 {error conditions} {
+    list [catch {lrange a b 6} msg] $msg
+} {1 {bad index "b": must be integer?[+-]integer? or end?[+-]integer?}}
+test lrange-2.4 {error conditions} {
+    list [catch {lrange a 0 enigma} msg] $msg
+} {1 {bad index "enigma": must be integer?[+-]integer? or end?[+-]integer?}}
+test lrange-2.5 {error conditions} {
+    list [catch {lrange "a \{b c" 3 4} msg] $msg
+} {1 {unmatched open brace in list}}
+test lrange-2.6 {error conditions} {
+    list [catch {lrange "a b c \{ d e" 1 4} msg] $msg
+} {1 {unmatched open brace in list}}
+
+test lrange-3.1 {Bug 3588366: end-offsets before start} {
+    apply {l {
+	lrange $l 0 end-5
+    }} {1 2 3 4 5}
+} {}
+
+# cleanup
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/tests/lrepeat.test b/tests/lrepeat.test
new file mode 100644
index 0000000..788bb9b
--- /dev/null
+++ b/tests/lrepeat.test
@@ -0,0 +1,84 @@
+# Commands covered:  lrepeat
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands.  Sourcing this file into Tcl runs the tests and
+# generates output for errors.  No output means no errors were found.
+#
+# Copyright (c) 2003 by Simon Geard.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+    package require tcltest 2
+    namespace import -force ::tcltest::*
+}
+
+## Arg errors
+test lrepeat-1.1 {error cases} {
+    -body {
+	lrepeat
+    }
+    -returnCodes 1
+    -result {wrong # args: should be "lrepeat count ?value ...?"}
+}
+test lrepeat-1.2 {Accept zero elements(TIP 323)} {
+    -body {
+	lrepeat 1
+    }
+    -result {}
+}
+test lrepeat-1.3 {error cases} {
+    -body {
+	lrepeat a 1
+    }
+    -returnCodes 1
+    -result {expected integer but got "a"}
+}
+test lrepeat-1.4 {error cases} {
+    -body {
+	lrepeat -3 1
+    }
+    -returnCodes 1
+    -result {bad count "-3": must be integer >= 0} 
+}
+test lrepeat-1.5 {Accept zero repetitions (TIP 323)} {
+    -body {
+	lrepeat 0
+    }
+    -result {}
+}
+test lrepeat-1.6 {error cases} {
+    -body {
+	lrepeat 3.5 1
+    }
+    -returnCodes 1
+    -result {expected integer but got "3.5"} 
+}
+test lrepeat-1.7 {Accept zero repetitions (TIP 323)} {
+    -body {
+	lrepeat 0 a b c
+    }
+    -result {}
+}
+test lrepeat-1.8 {Do not build enormous lists - Bug 2130992} -body {
+     lrepeat 0x10000000 a b c d e f g h
+} -returnCodes error -match glob -result *
+
+## Okay
+test lrepeat-2.1 {normal cases} {
+    lrepeat 10 a
+} {a a a a a a a a a a}
+test lrepeat-2.2 {normal cases} {
+    lrepeat 3 [lrepeat 3 0]
+} {{0 0 0} {0 0 0} {0 0 0}}
+test lrepeat-2.3 {normal cases} {
+    lrepeat 3 a b c
+} {a b c a b c a b c}
+test lrepeat-2.4 {normal cases} {
+    lrepeat 3 [lrepeat 2 a] b c
+} {{a a} b c {a a} b c {a a} b c}
+
+# cleanup
+::tcltest::cleanupTests
+return
diff --git a/tests/lreplace.test b/tests/lreplace.test
new file mode 100644
index 0000000..d7f8226
--- /dev/null
+++ b/tests/lreplace.test
@@ -0,0 +1,240 @@
+# Commands covered:  lreplace
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands.  Sourcing this file into Tcl runs the tests and
+# generates output for errors.  No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+    package require tcltest
+    namespace import -force ::tcltest::*
+}
+
+test lreplace-1.1 {lreplace command} {
+    lreplace {1 2 3 4 5} 0 0 a
+} {a 2 3 4 5}
+test lreplace-1.2 {lreplace command} {
+    lreplace {1 2 3 4 5} 1 1 a
+} {1 a 3 4 5}
+test lreplace-1.3 {lreplace command} {
+    lreplace {1 2 3 4 5} 2 2 a
+} {1 2 a 4 5}
+test lreplace-1.4 {lreplace command} {
+    lreplace {1 2 3 4 5} 3 3 a
+} {1 2 3 a 5}
+test lreplace-1.5 {lreplace command} {
+    lreplace {1 2 3 4 5} 4 4 a
+} {1 2 3 4 a}
+test lreplace-1.6 {lreplace command} {
+    lreplace {1 2 3 4 5} 4 5 a
+} {1 2 3 4 a}
+test lreplace-1.7 {lreplace command} {
+    lreplace {1 2 3 4 5} -1 -1 a
+} {a 1 2 3 4 5}
+test lreplace-1.8 {lreplace command} {
+    lreplace {1 2 3 4 5} 2 end a b c d
+} {1 2 a b c d}
+test lreplace-1.9 {lreplace command} {
+    lreplace {1 2 3 4 5} 0 3
+} {5}
+test lreplace-1.10 {lreplace command} {
+    lreplace {1 2 3 4 5} 0 4
+} {}
+test lreplace-1.11 {lreplace command} {
+    lreplace {1 2 3 4 5} 0 1
+} {3 4 5}
+test lreplace-1.12 {lreplace command} {
+    lreplace {1 2 3 4 5} 2 3
+} {1 2 5}
+test lreplace-1.13 {lreplace command} {
+    lreplace {1 2 3 4 5} 3 end
+} {1 2 3}
+test lreplace-1.14 {lreplace command} {
+    lreplace {1 2 3 4 5} -1 4 a b c
+} {a b c}
+test lreplace-1.15 {lreplace command} {
+    lreplace {a b "c c" d e f} 3 3
+} {a b {c c} e f}
+test lreplace-1.16 {lreplace command} {
+    lreplace { 1 2 3 4 5} 0 0 a
+} {a 2 3 4 5}
+test lreplace-1.17 {lreplace command} {
+    lreplace {1 2 3 4 "5 6"} 4 4 a
+} {1 2 3 4 a}
+test lreplace-1.18 {lreplace command} {
+    lreplace {1 2 3 4 {5 6}} 4 4 a
+} {1 2 3 4 a}
+test lreplace-1.19 {lreplace command} {
+    lreplace {1 2 3 4} 2 end x y z
+} {1 2 x y z}
+test lreplace-1.20 {lreplace command} {
+    lreplace {1 2 3 4} end end a
+} {1 2 3 a}
+test lreplace-1.21 {lreplace command} {
+    lreplace {1 2 3 4} end 3 a
+} {1 2 3 a}
+test lreplace-1.22 {lreplace command} {
+    lreplace {1 2 3 4} end end
+} {1 2 3}
+test lreplace-1.23 {lreplace command} {
+    lreplace {1 2 3 4} 2 -1 xy
+} {1 2 xy 3 4}
+test lreplace-1.24 {lreplace command} {
+    lreplace {1 2 3 4} end -1 z
+} {1 2 3 z 4}
+test lreplace-1.25 {lreplace command} {
+    concat \"[lreplace {\}\     hello} end end]\"
+} {"\}\ "}
+test lreplace-1.26 {lreplace command} {
+    catch {unset foo}
+    set foo {a b}
+    list [set foo [lreplace $foo end end]] \
+        [set foo [lreplace $foo end end]] \
+        [set foo [lreplace $foo end end]]
+} {a {} {}}
+test lreplace-1.27 {lreplace command} {
+    lreplace x 1 1
+} x
+test lreplace-1.28 {lreplace command} {
+    lreplace x 1 1 y
+} {x y}
+
+test lreplace-2.1 {lreplace errors} {
+    list [catch lreplace msg] $msg
+} {1 {wrong # args: should be "lreplace list first last ?element ...?"}}
+test lreplace-2.2 {lreplace errors} {
+    list [catch {lreplace a b} msg] $msg
+} {1 {wrong # args: should be "lreplace list first last ?element ...?"}}
+test lreplace-2.3 {lreplace errors} {
+    list [catch {lreplace x a 10} msg] $msg
+} {1 {bad index "a": must be integer?[+-]integer? or end?[+-]integer?}}
+test lreplace-2.4 {lreplace errors} {
+    list [catch {lreplace x 10 x} msg] $msg
+} {1 {bad index "x": must be integer?[+-]integer? or end?[+-]integer?}}
+test lreplace-2.5 {lreplace errors} {
+    list [catch {lreplace x 10 1x} msg] $msg
+} {1 {bad index "1x": must be integer?[+-]integer? or end?[+-]integer?}}
+test lreplace-2.6 {lreplace errors} {
+    list [catch {lreplace x 3 2} msg] $msg
+} {1 {list doesn't contain element 3}}
+test lreplace-2.7 {lreplace errors} {
+    list [catch {lreplace x 2 2} msg] $msg
+} {1 {list doesn't contain element 2}}
+
+test lreplace-3.1 {lreplace won't modify shared argument objects} {
+    proc p {} {
+        lreplace "a b c" 1 1 "x y"
+        return "a b c"
+    }
+    p
+} "a b c"
+
+test lreplace-4.1 {Bug ccc2c2cc98: lreplace edge case} {
+    lreplace {} 1 1
+} {}
+test lreplace-4.2 {Bug ccc2c2cc98: lreplace edge case} {
+    lreplace { } 1 1
+} {}
+test lreplace-4.3 {lreplace edge case} {
+    lreplace {1 2 3} 2 0
+} {1 2 3}
+test lreplace-4.4 {lreplace edge case} {
+    lreplace {1 2 3 4 5} 3 1
+} {1 2 3 4 5}
+test lreplace-4.5 {lreplace edge case} {
+    lreplace {1 2 3 4 5} 3 0 _
+} {1 2 3 _ 4 5}
+test lreplace-4.6 {lreplace end-x: bug a4cb3f06c4} {
+    lreplace {0 1 2 3 4} 0 end-2
+} {3 4}
+test lreplace-4.6.1 {lreplace end-x: bug a4cb3f06c4} {
+    lreplace {0 1 2 3 4} 0 end-2 a b c
+} {a b c 3 4}
+test lreplace-4.7 {lreplace with two end-indexes: increasing} {
+    lreplace {0 1 2 3 4} end-2 end-1
+} {0 1 4}
+test lreplace-4.7.1 {lreplace with two end-indexes: increasing} {
+    lreplace {0 1 2 3 4} end-2 end-1 a b c
+} {0 1 a b c 4}
+test lreplace-4.8 {lreplace with two end-indexes: equal} {
+    lreplace {0 1 2 3 4} end-2 end-2
+} {0 1 3 4}
+test lreplace-4.8.1 {lreplace with two end-indexes: equal} {
+    lreplace {0 1 2 3 4} end-2 end-2 a b c
+} {0 1 a b c 3 4}
+test lreplace-4.9 {lreplace with two end-indexes: decreasing} {
+    lreplace {0 1 2 3 4} end-2 end-3
+} {0 1 2 3 4}
+test lreplace-4.9.1 {lreplace with two end-indexes: decreasing} {
+    lreplace {0 1 2 3 4} end-2 end-3 a b c
+} {0 1 a b c 2 3 4}
+test lreplace-4.10 {lreplace with two equal indexes} {
+    lreplace {0 1 2 3 4} 2 2
+} {0 1 3 4}
+test lreplace-4.10.1 {lreplace with two equal indexes} {
+    lreplace {0 1 2 3 4} 2 2 a b c
+} {0 1 a b c 3 4}
+test lreplace-4.11 {lreplace end index first} {
+    lreplace {0 1 2 3 4} end-2 1 a b c
+} {0 1 a b c 2 3 4}
+test lreplace-4.12 {lreplace end index first} {
+    lreplace {0 1 2 3 4} end-2 2 a b c
+} {0 1 a b c 3 4}
+test lreplace-4.13 {lreplace empty list} {
+    lreplace {} 1 1 1
+} 1
+test lreplace-4.14 {lreplace empty list} {
+    lreplace {} 2 2 2
+} 2
+
+test lreplace-5.1 {compiled lreplace: Bug 47ac84309b} {
+    apply {x {
+	lreplace $x end 0
+    }} {a b c}
+} {a b c}
+test lreplace-5.2 {compiled lreplace: Bug 47ac84309b} {
+    apply {x {
+	lreplace $x end 0 A
+    }} {a b c}
+} {a b A c}
+
+# Testing for compiled behaviour. Far too many variations to check with
+# spelt-out tests. Note that this *just* checks whether the compiled version
+# and the interpreted version are the same, not whether the interpreted
+# version is correct.
+apply {{} {
+    set lss     {{} {a} {a b c} {a b c d}}
+    set ins     {{} A {A B}}
+    set idxs    {-2 -1 0 1 2 3 end-3 end-2 end-1 end end+1 end+2}
+    set lreplace lreplace
+
+    foreach ls $lss {
+	foreach a $idxs {
+	    foreach b $idxs {
+		foreach i $ins {
+		    set expected [list [catch {$lreplace $ls $a $b {*}$i} m] $m]
+		    set tester [list lreplace $ls $a $b {*}$i]
+		    set script [list catch $tester m]
+		    set script "list \[$script\] \$m"
+		    test lreplace-6.[incr n] {lreplace battery} \
+			[list apply [list {} $script]] $expected
+		}
+	    }
+	}
+    }
+}}
+
+# cleanup
+catch {unset foo}
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/tests/lsearch.test b/tests/lsearch.test
new file mode 100644
index 0000000..f36e987
--- /dev/null
+++ b/tests/lsearch.test
@@ -0,0 +1,528 @@
+# Commands covered:  lsearch
+#
+# This file contains a collection of tests for one or more of the Tcl built-in
+# commands.  Sourcing this file into Tcl runs the tests and generates output
+# for errors.  No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution of
+# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {"::tcltest" ni [namespace children]} {
+    package require tcltest 2
+    namespace import -force ::tcltest::*
+}
+
+set x {abcd bbcd 123 234 345}
+test lsearch-1.1 {lsearch command} {
+    lsearch $x 123
+} 2
+test lsearch-1.2 {lsearch command} {
+    lsearch $x 3456
+} -1
+test lsearch-1.3 {lsearch command} {
+    lsearch $x *5
+} 4
+test lsearch-1.4 {lsearch command} {
+    lsearch $x *bc*
+} 0
+
+test lsearch-2.1 {search modes} {
+    lsearch -exact {xyz bbcc *bc*} *bc*
+} 2
+test lsearch-2.2 {search modes} {
+    lsearch -exact {b.x ^bc xy bcx} ^bc
+} 1
+test lsearch-2.3 {search modes} {
+    lsearch -exact {foo bar cat} ba
+} -1
+test lsearch-2.4 {search modes} {
+    lsearch -exact {foo bar cat} bart
+} -1
+test lsearch-2.5 {search modes} {
+    lsearch -exact {foo bar cat} bar
+} 1
+test lsearch-2.6 {search modes} -returnCodes error -body {
+    lsearch -regexp {xyz bbcc *bc*} *bc*
+} -result {couldn't compile regular expression pattern: quantifier operand invalid}
+test lsearch-2.7 {search modes} {
+    lsearch -regexp {b.x ^bc xy bcx} ^bc
+} 3
+test lsearch-2.8 {search modes} {
+    lsearch -glob {xyz bbcc *bc*} *bc*
+} 1
+test lsearch-2.9 {search modes} {
+    lsearch -glob {b.x ^bc xy bcx} ^bc
+} 1
+test lsearch-2.10 {search modes} -returnCodes error -body {
+    lsearch -glib {b.x bx xy bcx} b.x
+} -result {bad option "-glib": must be -all, -ascii, -bisect, -decreasing, -dictionary, -exact, -glob, -increasing, -index, -inline, -integer, -nocase, -not, -real, -regexp, -sorted, -start, or -subindices}
+test lsearch-2.11 {search modes with -nocase} {
+    lsearch -exact -nocase {a b c A B C} A
+} 0
+test lsearch-2.12 {search modes with -nocase} {
+    lsearch -glob -nocase {a b c A B C} A*
+} 0
+test lsearch-2.13 {search modes with -nocase} {
+    lsearch -regexp -nocase {a b c A B C} ^A\$
+} 0
+test lsearch-2.14 {search modes without -nocase} {
+    lsearch -exact {a b c A B C} A
+} 3
+test lsearch-2.15 {search modes without -nocase} {
+    lsearch -glob {a b c A B C} A*
+} 3
+test lsearch-2.16 {search modes without -nocase} {
+    lsearch -regexp {a b c A B C} ^A\$
+} 3
+
+test lsearch-3.1 {lsearch errors} -returnCodes error -body {
+    lsearch
+} -result {wrong # args: should be "lsearch ?-option value ...? list pattern"}
+test lsearch-3.2 {lsearch errors} -returnCodes error -body {
+    lsearch a
+} -result {wrong # args: should be "lsearch ?-option value ...? list pattern"}
+test lsearch-3.3 {lsearch errors} -returnCodes error -body {
+    lsearch a b c
+} -result {bad option "a": must be -all, -ascii, -bisect, -decreasing, -dictionary, -exact, -glob, -increasing, -index, -inline, -integer, -nocase, -not, -real, -regexp, -sorted, -start, or -subindices}
+test lsearch-3.4 {lsearch errors} -returnCodes error -body {
+    lsearch a b c d
+} -result {bad option "a": must be -all, -ascii, -bisect, -decreasing, -dictionary, -exact, -glob, -increasing, -index, -inline, -integer, -nocase, -not, -real, -regexp, -sorted, -start, or -subindices}
+test lsearch-3.5 {lsearch errors} -returnCodes error -body {
+    lsearch "\{" b
+} -result {unmatched open brace in list}
+test lsearch-3.6 {lsearch errors} -returnCodes error -body {
+    lsearch -index a b
+} -result {"-index" option must be followed by list index}
+test lsearch-3.7 {lsearch errors} -returnCodes error -body {
+    lsearch -subindices -exact a b
+} -result {-subindices cannot be used without -index option}
+
+test lsearch-4.1 {binary data} {
+    lsearch -exact [list foo one\000two bar] bar
+} 2
+test lsearch-4.2 {binary data} {
+    set x one
+    append x \x00
+    append x two
+    lsearch -exact [list foo one\000two bar] $x
+} 1
+
+# Make a sorted list
+set l {}
+set l2 {}
+for {set i 0} {$i < 100} {incr i} {
+    lappend l $i
+    lappend l2 [expr {double($i)/2}]
+}
+set increasingIntegers [lsort -integer $l]
+set decreasingIntegers [lsort -decreasing -integer $l]
+set increasingDoubles [lsort -real $l2]
+set decreasingDoubles [lsort -decreasing -real $l2]
+set increasingStrings [lsort {48 6a 18b 22a 21aa 35 36}]
+set decreasingStrings [lsort -decreasing {48 6a 18b 22a 21aa 35 36}]
+set increasingDictionary [lsort -dictionary {48 6a 18b 22a 21aa 35 36}]
+set decreasingDictionary [lsort -dictionary -decreasing $increasingDictionary]
+
+set l {}
+for {set i 0} {$i < 10} {incr i} {
+    lappend l $i $i $i $i $i
+}
+set repeatingIncreasingIntegers [lsort -integer $l]
+set repeatingDecreasingIntegers [lsort -integer -decreasing $l]
+
+test lsearch-5.1 {binary search} {
+    set res {}
+    for {set i 0} {$i < 100} {incr i} {
+	lappend res [lsearch -integer -sorted $increasingIntegers $i]
+    }
+    set res
+} $increasingIntegers
+test lsearch-5.2 {binary search} {
+    set res {}
+    for {set i 0} {$i < 100} {incr i} {
+	lappend res [lsearch -integer -decreasing -sorted \
+		$decreasingIntegers $i]
+    }
+    set res
+} $decreasingIntegers
+test lsearch-5.3 {binary search finds leftmost occurances} {
+    set res {}
+    for {set i 0} {$i < 10} {incr i} {
+	lappend res [lsearch -integer -sorted $repeatingIncreasingIntegers $i]
+    }
+    set res
+} [list 0 5 10 15 20 25 30 35 40 45]
+test lsearch-5.4 {binary search -decreasing finds leftmost occurances} {
+    set res {}
+    for {set i 9} {$i >= 0} {incr i -1} {
+	lappend res [lsearch -sorted -integer -decreasing \
+		$repeatingDecreasingIntegers $i]
+    }
+    set res
+} [list 0 5 10 15 20 25 30 35 40 45]
+
+test lsearch-6.1 {integer search} {
+    set res {}
+    for {set i 0} {$i < 100} {incr i} {
+	lappend res [lsearch -exact -integer $increasingIntegers $i]
+    }
+    set res
+} [lrange $increasingIntegers 0 99]
+test lsearch-6.2 {decreasing integer search} {
+    set res {}
+    for {set i 0} {$i < 100} {incr i} {
+	lappend res [lsearch -exact -integer -decreasing \
+		$decreasingIntegers $i]
+    }
+    set res
+} [lrange $decreasingIntegers 0 99]
+test lsearch-6.3 {sorted integer search} {
+    set res {}
+    for {set i 0} {$i < 100} {incr i} {
+	lappend res [lsearch -sorted -integer $increasingIntegers $i]
+    }
+    set res
+} [lrange $increasingIntegers 0 99]
+test lsearch-6.4 {sorted decreasing integer search} {
+    set res {}
+    for {set i 0} {$i < 100} {incr i} {
+	lappend res [lsearch -integer -sorted -decreasing \
+		$decreasingIntegers $i]
+    }
+    set res
+} [lrange $decreasingIntegers 0 99]
+
+test lsearch-7.1 {double search} {
+    set res {}
+    for {set i 0} {$i < 100} {incr i} {
+	lappend res [lsearch -exact -real $increasingDoubles \
+		[expr {double($i)/2}]]
+    }
+    set res
+} [lrange $increasingIntegers 0 99]
+test lsearch-7.2 {decreasing double search} {
+    set res {}
+    for {set i 0} {$i < 100} {incr i} {
+	lappend res [lsearch -exact -real -decreasing \
+		$decreasingDoubles [expr {double($i)/2}]]
+    }
+    set res
+} [lrange $decreasingIntegers 0 99]
+test lsearch-7.3 {sorted double search} {
+    set res {}
+    for {set i 0} {$i < 100} {incr i} {
+	lappend res [lsearch -sorted -real \
+		$increasingDoubles [expr {double($i)/2}]]
+    }
+    set res
+} [lrange $increasingIntegers 0 99]
+test lsearch-7.4 {sorted decreasing double search} {
+    set res {}
+    for {set i 0} {$i < 100} {incr i} {
+	lappend res [lsearch -sorted -real -decreasing \
+		$decreasingDoubles [expr {double($i)/2}]]
+    }
+    set res
+} [lrange $decreasingIntegers 0 99]
+
+test lsearch-8.1 {dictionary search} {
+    set res {}
+    foreach val {6a 18b 21aa 22a 35 36 48} {
+	lappend res [lsearch -exact -dictionary $increasingDictionary $val]
+    }
+    set res
+} [list 0 1 2 3 4 5 6]
+test lsearch-8.2 {decreasing dictionary search} {
+    set res {}
+    foreach val {6a 18b 21aa 22a 35 36 48} {
+	lappend res [lsearch -exact -dictionary $decreasingDictionary $val]
+    }
+    set res
+} [list 6 5 4 3 2 1 0]
+test lsearch-8.3 {sorted dictionary search} {
+    set res {}
+    foreach val {6a 18b 21aa 22a 35 36 48} {
+	lappend res [lsearch -sorted -dictionary $increasingDictionary $val]
+    }
+    set res
+} [list 0 1 2 3 4 5 6]
+test lsearch-8.4 {decreasing sorted dictionary search} {
+    set res {}
+    foreach val {6a 18b 21aa 22a 35 36 48} {
+	lappend res [lsearch -decreasing -sorted -dictionary \
+		$decreasingDictionary $val]
+    }
+    set res
+} [list 6 5 4 3 2 1 0]
+
+test lsearch-9.1 {ascii search} {
+    set res {}
+    foreach val {18b 21aa 22a 35 36 48 6a} {
+	lappend res [lsearch -exact -ascii $increasingStrings $val]
+    }
+    set res
+} [list 0 1 2 3 4 5 6]
+test lsearch-9.2 {decreasing ascii search} {
+    set res {}
+    foreach val {18b 21aa 22a 35 36 48 6a} {
+	lappend res [lsearch -exact -ascii $decreasingStrings $val]
+    }
+    set res
+} [list 6 5 4 3 2 1 0]
+test lsearch-9.3 {sorted ascii search} {
+    set res {}
+    foreach val {18b 21aa 22a 35 36 48 6a} {
+	lappend res [lsearch -sorted -ascii $increasingStrings $val]
+    }
+    set res
+} [list 0 1 2 3 4 5 6]
+test lsearch-9.4 {decreasing sorted ascii search} {
+    set res {}
+    foreach val {18b 21aa 22a 35 36 48 6a} {
+	lappend res [lsearch -decreasing -sorted -ascii \
+		$decreasingStrings $val]
+    }
+    set res
+} [list 6 5 4 3 2 1 0]
+
+test lsearch-10.1 {offset searching} {
+    lsearch -start 2 {a b c a b c} a
+} 3
+test lsearch-10.2 {offset searching} {
+    lsearch -start 2 {a b c d e f} a
+} -1
+test lsearch-10.3 {offset searching} {
+    lsearch -start end-4 {a b c a b c} a
+} 3
+test lsearch-10.4 {offset searching} -returnCodes error -body {
+    lsearch -start foobar {a b c a b c} a
+} -result {bad index "foobar": must be integer?[+-]integer? or end?[+-]integer?}
+test lsearch-10.5 {offset searching} -returnCodes error -body {
+    lsearch -start 1 2
+} -result {missing starting index}
+test lsearch-10.6 {binary search with offset} {
+    set res {}
+    for {set i 0} {$i < 100} {incr i} {
+	lappend res [lsearch -integer -start 2 -sorted $increasingIntegers $i]
+    }
+    set res
+} [concat -1 -1 [lrange $increasingIntegers 2 end]]
+test lsearch-10.7 {offset searching with an empty list} {
+    # Stop bug #694232 from reocurring
+    lsearch -start 0 {} x
+} -1
+test lsearch-10.8 {offset searching past the end of the list} {
+    # Stop [Bug 1374778] from reoccurring
+    lsearch -start 10 {a b c} c
+} -1
+test lsearch-10.9 {offset searching past the end of the list} {
+    # Stop [Bug 1374778] from reoccurring
+    lsearch -start 10 -all {a b c} c
+} {}
+test lsearch-10.10 {offset searching past the end of the list} {
+    # Stop [Bug 1374778] from reoccurring
+    lsearch -start 10 -inline {a b c} c
+} {}
+
+test lsearch-11.1 {negated searches} {
+    lsearch -not {a a a b a a a} a
+} 3
+test lsearch-11.2 {negated searches} {
+    lsearch -not {a a a a a a a} a
+} -1
+
+test lsearch-12.1 {return values instead of indices} {
+    lsearch -glob -inline {a1 b2 c3 d4} c*
+} c3
+test lsearch-12.2 {return values instead of indices} {
+    lsearch -glob -inline {a1 b2 c3 d4} e*
+} {}
+
+test lsearch-13.1 {search for all matches} {
+    lsearch -all {a b a c a d} 1
+} {}
+test lsearch-13.2 {search for all matches} {
+    lsearch -all {a b a c a d} a
+} {0 2 4}
+test lsearch-13.3 {search for all matches with -nocase} {
+    lsearch -all -exact -nocase {a b c A B C} A
+} {0 3}
+test lsearch-13.4 {search for all matches with -nocase} {
+    lsearch -all -glob -nocase {a b c A B C} A*
+} {0 3}
+test lsearch-13.5 {search for all matches with -nocase} {
+    lsearch -all -regexp -nocase {a b c A B C} ^A\$
+} {0 3}
+
+test lsearch-14.1 {combinations: -all and -inline} {
+    lsearch -all -inline -glob {a1 b2 a3 c4 a5 d6} a*
+} {a1 a3 a5}
+test lsearch-14.2 {combinations: -all, -inline and -not} {
+    lsearch -all -inline -not -glob {a1 b2 a3 c4 a5 d6} a*
+} {b2 c4 d6}
+test lsearch-14.3 {combinations: -all and -not} {
+    lsearch -all -not -glob {a1 b2 a3 c4 a5 d6} a*
+} {1 3 5}
+test lsearch-14.4 {combinations: -inline and -not} {
+    lsearch -inline -not -glob {a1 b2 a3 c4 a5 d6} a*
+} {b2}
+test lsearch-14.5 {combinations: -start, -all and -inline} {
+    lsearch -start 2 -all -inline -glob {a1 b2 a3 c4 a5 d6} a*
+} {a3 a5}
+test lsearch-14.6 {combinations: -start, -all, -inline and -not} {
+    lsearch -start 2 -all -inline -not -glob {a1 b2 a3 c4 a5 d6} a*
+} {c4 d6}
+test lsearch-14.7 {combinations: -start, -all and -not} {
+    lsearch -start 2 -all -not -glob {a1 b2 a3 c4 a5 d6} a*
+} {3 5}
+test lsearch-14.8 {combinations: -start, -inline and -not} {
+    lsearch -start 2 -inline -not -glob {a1 b2 a3 c4 a5 d6} a*
+} {c4}
+
+test lsearch-15.1 {make sure no shimmering occurs} {
+    set x [expr int(sin(0))]
+    lsearch -start $x $x $x
+} 0
+
+test lsearch-16.1 {lsearch -regexp shared object} {
+    set str a
+    lsearch -regexp $str $str
+} 0
+# Bug 1366683
+test lsearch-16.2 {lsearch -regexp allows internal backrefs} {
+    lsearch -regexp {a aa b} {(.)\1}
+} 1
+
+test lsearch-17.1 {lsearch -index option, basic functionality} {
+    lsearch -index 1 {{a c} {a b} {a a}} a
+} 2
+test lsearch-17.2 {lsearch -index option, basic functionality} {
+    lsearch -index 1 -exact {{a c} {a b} {a a}} a
+} 2
+test lsearch-17.3 {lsearch -index option, basic functionality} {
+    lsearch -index 1 -glob {{ab cb} {ab bb} {ab ab}} b* 
+} 1
+test lsearch-17.4 {lsearch -index option, basic functionality} {
+    lsearch -index 1 -regexp {{ab cb} {ab bb} {ab ab}} {[cb]b}
+} 0 
+test lsearch-17.5 {lsearch -index option, basic functionality} {
+    lsearch -all -index 0 -exact {{a c} {a b} {d a}} a
+} {0 1}
+test lsearch-17.6 {lsearch -index option, basic functionality} {
+    lsearch -all -index 1 -glob {{ab cb} {ab bb} {db bx}} b* 
+} {1 2}
+test lsearch-17.7 {lsearch -index option, basic functionality} {
+    lsearch -all -index 1 -regexp {{ab cb} {ab bb} {ab ab}} {[cb]b}
+} {0 1}
+
+test lsearch-18.1 {lsearch -index option, list as index basic functionality} {
+    lsearch -index {0 0} {{{x x} {x b} {a d}} {{a c} {a b} {a a}}} a
+} 1
+test lsearch-18.2 {lsearch -index option, list as index basic functionality} {
+    lsearch -index {2 0} -exact {{{x x} {x b} {a d}} {{a c} {a b} {a a}}} a
+} 0
+test lsearch-18.3 {lsearch -index option, list as index basic functionality} {
+    lsearch -index {1 1} -glob {{{ab cb} {ab bb} {ab ab}} {{ab cb} {ab bb} {ab ab}}} b* 
+} 0
+test lsearch-18.4 {lsearch -index option, list as index basic functionality} {
+    lsearch -index {0 1} -regexp {{{ab cb} {ab bb} {ab ab}} {{ab cb} {ab bb} {ab ab}}} {[cb]b}
+} 0 
+test lsearch-18.5 {lsearch -index option, list as index basic functionality} {
+    lsearch -all -index {0 0} -exact {{{a c} {a b} {d a}} {{a c} {a b} {d a}}} a
+} {0 1}
+
+test lsearch-19.1 {lsearch -sunindices option} {
+    lsearch -subindices -index {0 0} {{{x x} {x b} {a d}} {{a c} {a b} {a a}}} a
+} {1 0 0}
+test lsearch-19.2 {lsearch -sunindices option} {
+    lsearch -subindices -index {2 0} -exact {{{x x} {x b} {a d}} {{a c} {a b} {a a}}} a
+} {0 2 0}
+test lsearch-19.3 {lsearch -sunindices option} {
+    lsearch -subindices -index {1 1} -glob {{{ab cb} {ab bb} {ab ab}} {{ab cb} {ab bb} {ab ab}}} b* 
+} {0 1 1}
+test lsearch-19.4 {lsearch -sunindices option} {
+    lsearch -subindices -index {0 1} -regexp {{{ab cb} {ab bb} {ab ab}} {{ab cb} {ab bb} {ab ab}}} {[cb]b}
+} {0 0 1} 
+test lsearch-19.5 {lsearch -sunindices option} {
+    lsearch -subindices -all -index {0 0} -exact {{{a c} {a b} {d a}} {{a c} {a b} {d a}}} a
+} {{0 0 0} {1 0 0}}
+
+test lsearch-20.1 {lsearch -index option, index larger than sublists} -body {
+    lsearch -index 2 {{a c} {a b} {a a}} a
+} -returnCodes error -result {element 2 missing from sublist "a c"}
+test lsearch-20.2 {lsearch -index option, malformed index} -body {
+    lsearch -index foo {{a c} {a b} {a a}} a
+} -returnCodes error -result {bad index "foo": must be integer?[+-]integer? or end?[+-]integer?}
+test lsearch-20.3 {lsearch -index option, malformed index} -body {
+    lsearch -index \{ {{a c} {a b} {a a}} a
+} -returnCodes error -result {unmatched open brace in list}
+
+test lsearch-21.1 {lsearch shimmering crash} {
+    set x 0
+    lsearch -exact -integer $x $x
+} 0
+test lsearch-21.2 {lsearch shimmering crash} {
+    set x 0.5
+    lsearch -exact -real $x $x
+} 0
+
+test lsearch-22.1 {lsearch -bisect} -setup {
+    set res {}
+} -body {
+    foreach i {0 1 5 6 7 8 15 16} {
+	lappend res [lsearch -bisect -integer {1 4 5 7 9 15} $i]
+    }
+    return $res
+} -result {-1 0 2 2 3 3 5 5}
+test lsearch-22.2 {lsearch -bisect, last of equals} -setup {
+    set res {}
+} -body {
+    foreach i {0 1 2 3} {
+	lappend res [lsearch -bisect -integer {0 0 1 1 1 2 2 2 3 3 3} $i]
+    }
+    return $res
+} -result {1 4 7 10}
+test lsearch-22.3 {lsearch -bisect decreasing order} -setup {
+    set res {}
+} -body {
+    foreach i {0 1 5 6 7 8 15 16} {
+	lappend res [lsearch -bisect -integer -decreasing {15 9 7 5 4 1} $i]
+    }
+    return $res
+} -result {5 5 3 2 2 1 0 -1}
+test lsearch-22.4 {lsearch -bisect, last of equals, decreasing} -setup {
+    set res {}
+} -body {
+    foreach i {0 1 2 3} {
+	lappend res [lsearch -bisect -integer -decreasing \
+		{3 3 3 2 2 2 1 1 1 0 0} $i]
+    }
+    return $res
+} -result {10 8 5 2}
+test lsearch-22.5 {lsearch -bisect, all equal} {
+    lsearch -bisect -integer {5 5 5 5} 5
+} {3}
+test lsearch-22.6 {lsearch -sorted, all equal} {
+    lsearch -sorted -integer {5 5 5 5} 5
+} {0}
+
+# cleanup
+catch {unset res}
+catch {unset increasingIntegers}
+catch {unset decreasingIntegers}
+catch {unset increasingDoubles}
+catch {unset decreasingDoubles}
+catch {unset increasingStrings}
+catch {unset decreasingStrings}
+catch {unset increasingDictionary}
+catch {unset decreasingDictionary}
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/tests/lset.test b/tests/lset.test
new file mode 100644
index 0000000..1c1300b
--- /dev/null
+++ b/tests/lset.test
@@ -0,0 +1,481 @@
+# This file is a -*- tcl -*- test script
+
+# Commands covered: lset
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands.  Sourcing this file into Tcl runs the tests and
+# generates output for errors.  No output means no errors were found.
+#
+# Copyright (c) 2001 by Kevin B. Kenny.  All rights reserved.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+    package require tcltest
+    namespace import -force ::tcltest::*
+}
+
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
+
+proc failTrace {name1 name2 op} {
+    error "trace failed"
+}
+
+testConstraint testevalex [llength [info commands testevalex]]
+
+set noRead {}
+trace add variable noRead read failTrace
+set noWrite {a b c}
+trace add variable noWrite write failTrace
+
+test lset-1.1 {lset, not compiled, arg count} testevalex {
+    list [catch {testevalex lset} msg] $msg
+} "1 {wrong \# args: should be \"lset listVar ?index? ?index ...? value\"}"
+test lset-1.2 {lset, not compiled, no such var} testevalex {
+    list [catch {testevalex {lset noSuchVar 0 {}}} msg] $msg
+} "1 {can't read \"noSuchVar\": no such variable}"
+test lset-1.3 {lset, not compiled, var not readable} testevalex {
+    list [catch {testevalex {lset noRead 0 {}}} msg] $msg
+} "1 {can't read \"noRead\": trace failed}"
+
+test lset-2.1 {lset, not compiled, 3 args, second arg a plain index} testevalex {
+    set x {0 1 2}
+    list [testevalex {lset x 0 3}] $x
+} {{3 1 2} {3 1 2}}
+test lset-2.2 {lset, not compiled, 3 args, second arg neither index nor list} testevalex {
+    set x {0 1 2}
+    list [catch {
+	testevalex {lset x {{bad}1} 3}
+    } msg] $msg
+} {1 {bad index "{bad}1": must be integer?[+-]integer? or end?[+-]integer?}}
+
+test lset-3.1 {lset, not compiled, 3 args, data duplicated} testevalex {
+    set x {0 1 2}
+    list [testevalex {lset x 0 $x}] $x
+} {{{0 1 2} 1 2} {{0 1 2} 1 2}}
+test lset-3.2 {lset, not compiled, 3 args, data duplicated} testevalex {
+    set x {0 1}
+    set y $x
+    list [testevalex {lset x 0 2}] $x $y
+} {{2 1} {2 1} {0 1}}
+test lset-3.3 {lset, not compiled, 3 args, data duplicated} testevalex {
+    set x {0 1}
+    set y $x
+    list [testevalex {lset x 0 $x}] $x $y
+} {{{0 1} 1} {{0 1} 1} {0 1}}
+test lset-3.4 {lset, not compiled, 3 args, data duplicated} testevalex {
+    set x {0 1 2}
+    list [testevalex {lset x [list 0] $x}] $x
+} {{{0 1 2} 1 2} {{0 1 2} 1 2}}
+test lset-3.5 {lset, not compiled, 3 args, data duplicated} testevalex {
+    set x {0 1}
+    set y $x
+    list [testevalex {lset x [list 0] 2}] $x $y
+} {{2 1} {2 1} {0 1}}
+test lset-3.6 {lset, not compiled, 3 args, data duplicated} testevalex {
+    set x {0 1}
+    set y $x
+    list [testevalex {lset x [list 0] $x}] $x $y
+} {{{0 1} 1} {{0 1} 1} {0 1}}
+
+test lset-4.1 {lset, not compiled, 3 args, not a list} testevalex {
+    set a "x \{"
+    list [catch {
+	testevalex {lset a [list 0] y}
+    } msg] $msg
+} {1 {unmatched open brace in list}}
+test lset-4.2 {lset, not compiled, 3 args, bad index} testevalex {
+    set a {x y z}
+    list [catch {
+	testevalex {lset a [list 2a2] w}
+    } msg] $msg
+} {1 {bad index "2a2": must be integer?[+-]integer? or end?[+-]integer?}}
+test lset-4.3 {lset, not compiled, 3 args, index out of range} testevalex {
+    set a {x y z}
+    list [catch {
+	testevalex {lset a [list -1] w}
+    } msg] $msg
+} {1 {list index out of range}}
+test lset-4.4 {lset, not compiled, 3 args, index out of range} testevalex {
+    set a {x y z}
+    list [catch {
+	testevalex {lset a [list 4] w}
+    } msg] $msg
+} {1 {list index out of range}}
+test lset-4.5a {lset, not compiled, 3 args, index out of range} testevalex {
+    set a {x y z}
+    list [catch {
+	testevalex {lset a [list end--2] w}
+    } msg] $msg
+} {1 {list index out of range}}
+test lset-4.5b {lset, not compiled, 3 args, index out of range} testevalex {
+    set a {x y z}
+    list [catch {
+	testevalex {lset a [list end+2] w}
+    } msg] $msg
+} {1 {list index out of range}}
+test lset-4.6 {lset, not compiled, 3 args, index out of range} testevalex {
+    set a {x y z}
+    list [catch {
+	testevalex {lset a [list end-3] w}
+    } msg] $msg
+} {1 {list index out of range}}
+test lset-4.7 {lset, not compiled, 3 args, not a list} testevalex {
+    set a "x \{"
+    list [catch {
+	testevalex {lset a 0 y}
+    } msg] $msg
+} {1 {unmatched open brace in list}}
+test lset-4.8 {lset, not compiled, 3 args, bad index} testevalex {
+    set a {x y z}
+    list [catch {
+	testevalex {lset a 2a2 w}
+    } msg] $msg
+} {1 {bad index "2a2": must be integer?[+-]integer? or end?[+-]integer?}}
+test lset-4.9 {lset, not compiled, 3 args, index out of range} testevalex {
+    set a {x y z}
+    list [catch {
+	testevalex {lset a -1 w}
+    } msg] $msg
+} {1 {list index out of range}}
+test lset-4.10 {lset, not compiled, 3 args, index out of range} testevalex {
+    set a {x y z}
+    list [catch {
+	testevalex {lset a 4 w}
+    } msg] $msg
+} {1 {list index out of range}}
+test lset-4.11a {lset, not compiled, 3 args, index out of range} testevalex {
+    set a {x y z}
+    list [catch {
+	testevalex {lset a end--2 w}
+    } msg] $msg
+} {1 {list index out of range}}
+test lset-4.11 {lset, not compiled, 3 args, index out of range} testevalex {
+    set a {x y z}
+    list [catch {
+	testevalex {lset a end+2 w}
+    } msg] $msg
+} {1 {list index out of range}}
+test lset-4.12 {lset, not compiled, 3 args, index out of range} testevalex {
+    set a {x y z}
+    list [catch {
+	testevalex {lset a end-3 w}
+    } msg] $msg
+} {1 {list index out of range}}
+
+test lset-5.1 {lset, not compiled, 3 args, can't set variable} testevalex {
+    list [catch {
+	testevalex {lset noWrite 0 d}
+    } msg] $msg $noWrite
+} {1 {can't set "noWrite": trace failed} {d b c}}
+test lset-5.2 {lset, not compiled, 3 args, can't set variable} testevalex {
+    list [catch {
+	testevalex {lset noWrite [list 0] d}
+    } msg] $msg $noWrite
+} {1 {can't set "noWrite": trace failed} {d b c}}
+
+test lset-6.1 {lset, not compiled, 3 args, 1-d list basics} testevalex {
+    set a {x y z}
+    list [testevalex {lset a 0 a}] $a
+} {{a y z} {a y z}}
+test lset-6.2 {lset, not compiled, 3 args, 1-d list basics} testevalex {
+    set a {x y z}
+    list [testevalex {lset a [list 0] a}] $a
+} {{a y z} {a y z}}
+test lset-6.3 {lset, not compiled, 1-d list basics} testevalex {
+    set a {x y z}
+    list [testevalex {lset a 2 a}] $a
+} {{x y a} {x y a}}
+test lset-6.4 {lset, not compiled, 1-d list basics} testevalex {
+    set a {x y z}
+    list [testevalex {lset a [list 2] a}] $a
+} {{x y a} {x y a}}
+test lset-6.5 {lset, not compiled, 1-d list basics} testevalex {
+    set a {x y z}
+    list [testevalex {lset a end a}] $a
+} {{x y a} {x y a}}
+test lset-6.6 {lset, not compiled, 1-d list basics} testevalex {
+    set a {x y z}
+    list [testevalex {lset a [list end] a}] $a
+} {{x y a} {x y a}}
+test lset-6.7 {lset, not compiled, 1-d list basics} testevalex {
+    set a {x y z}
+    list [testevalex {lset a end-0 a}] $a
+} {{x y a} {x y a}}
+test lset-6.8 {lset, not compiled, 1-d list basics} testevalex {
+    set a {x y z}
+    list [testevalex {lset a [list end-0] a}] $a
+} {{x y a} {x y a}}
+test lset-6.9 {lset, not compiled, 1-d list basics} testevalex {
+    set a {x y z}
+    list [testevalex {lset a end-2 a}] $a
+} {{a y z} {a y z}}
+test lset-6.10 {lset, not compiled, 1-d list basics} testevalex {
+    set a {x y z}
+    list [testevalex {lset a [list end-2] a}] $a
+} {{a y z} {a y z}}
+
+test lset-7.1 {lset, not compiled, data sharing} testevalex {
+    set a 0
+    list [testevalex {lset a $a {gag me}}] $a
+} {{{gag me}} {{gag me}}}
+test lset-7.2 {lset, not compiled, data sharing} testevalex {
+    set a [list 0]
+    list [testevalex {lset a $a {gag me}}] $a
+} {{{gag me}} {{gag me}}}
+test lset-7.3 {lset, not compiled, data sharing} testevalex {
+    set a {x y}
+    list [testevalex {lset a 0 $a}] $a
+} {{{x y} y} {{x y} y}}
+test lset-7.4 {lset, not compiled, data sharing} testevalex {
+    set a {x y}
+    list [testevalex {lset a [list 0] $a}] $a
+} {{{x y} y} {{x y} y}}
+test lset-7.5 {lset, not compiled, data sharing} testevalex {
+    set n 0
+    set a {x y}
+    list [testevalex {lset a $n $n}] $a $n
+} {{0 y} {0 y} 0}
+test lset-7.6 {lset, not compiled, data sharing} testevalex {
+    set n [list 0]
+    set a {x y}
+    list [testevalex {lset a $n $n}] $a $n
+} {{0 y} {0 y} 0}
+test lset-7.7 {lset, not compiled, data sharing} testevalex {
+    set n 0
+    set a [list $n $n]
+    list [testevalex {lset a $n 1}] $a $n
+} {{1 0} {1 0} 0}
+test lset-7.8 {lset, not compiled, data sharing} testevalex {
+    set n [list 0]
+    set a [list $n $n]
+    list [testevalex {lset a $n 1}] $a $n
+} {{1 0} {1 0} 0}
+test lset-7.9 {lset, not compiled, data sharing} testevalex {
+    set a 0
+    list [testevalex {lset a $a $a}] $a
+} {0 0}
+test lset-7.10 {lset, not compiled, data sharing} testevalex {
+    set a [list 0]
+    list [testevalex {lset a $a $a}] $a
+} {0 0}
+
+test lset-8.1 {lset, not compiled, malformed sublist} testevalex {
+    set a [list "a \{" b]
+    list [catch {testevalex {lset a 0 1 c}} msg] $msg
+} {1 {unmatched open brace in list}}
+test lset-8.2 {lset, not compiled, malformed sublist} testevalex {
+    set a [list "a \{" b]
+    list [catch {testevalex {lset a {0 1} c}} msg] $msg
+} {1 {unmatched open brace in list}}
+test lset-8.3 {lset, not compiled, bad second index} testevalex {
+    set a {{b c} {d e}}
+    list [catch {testevalex {lset a 0 2a2 f}} msg] $msg
+} {1 {bad index "2a2": must be integer?[+-]integer? or end?[+-]integer?}}
+test lset-8.4 {lset, not compiled, bad second index} testevalex {
+    set a {{b c} {d e}}
+    list [catch {testevalex {lset a {0 2a2} f}} msg] $msg
+} {1 {bad index "2a2": must be integer?[+-]integer? or end?[+-]integer?}}
+test lset-8.5 {lset, not compiled, second index out of range} testevalex {
+    set a {{b c} {d e} {f g}}
+    list [catch {testevalex {lset a 2 -1 h}} msg] $msg
+} {1 {list index out of range}}
+test lset-8.6 {lset, not compiled, second index out of range} testevalex {
+    set a {{b c} {d e} {f g}}
+    list [catch {testevalex {lset a {2 -1} h}} msg] $msg
+} {1 {list index out of range}}
+test lset-8.7 {lset, not compiled, second index out of range} testevalex {
+    set a {{b c} {d e} {f g}}
+    list [catch {testevalex {lset a 2 3 h}} msg] $msg
+} {1 {list index out of range}}
+test lset-8.8 {lset, not compiled, second index out of range} testevalex {
+    set a {{b c} {d e} {f g}}
+    list [catch {testevalex {lset a {2 3} h}} msg] $msg
+} {1 {list index out of range}}
+test lset-8.9a {lset, not compiled, second index out of range} testevalex {
+    set a {{b c} {d e} {f g}}
+    list [catch {testevalex {lset a 2 end--2 h}} msg] $msg
+} {1 {list index out of range}}
+test lset-8.9b {lset, not compiled, second index out of range} testevalex {
+    set a {{b c} {d e} {f g}}
+    list [catch {testevalex {lset a 2 end+2 h}} msg] $msg
+} {1 {list index out of range}}
+test lset-8.10a {lset, not compiled, second index out of range} testevalex {
+    set a {{b c} {d e} {f g}}
+    list [catch {testevalex {lset a {2 end--2} h}} msg] $msg
+} {1 {list index out of range}}
+test lset-8.10b {lset, not compiled, second index out of range} testevalex {
+    set a {{b c} {d e} {f g}}
+    list [catch {testevalex {lset a {2 end+2} h}} msg] $msg
+} {1 {list index out of range}}
+test lset-8.11 {lset, not compiled, second index out of range} testevalex {
+    set a {{b c} {d e} {f g}}
+    list [catch {testevalex {lset a 2 end-2 h}} msg] $msg
+} {1 {list index out of range}}
+test lset-8.12 {lset, not compiled, second index out of range} testevalex {
+    set a {{b c} {d e} {f g}}
+    list [catch {testevalex {lset a {2 end-2} h}} msg] $msg
+} {1 {list index out of range}}
+
+test lset-9.1 {lset, not compiled, entire variable} testevalex {
+    set a x
+    list [testevalex {lset a y}] $a
+} {y y}
+test lset-9.2 {lset, not compiled, entire variable} testevalex {
+    set a x
+    list [testevalex {lset a {} y}] $a
+} {y y}
+
+test lset-10.1 {lset, not compiled, shared data} testevalex {
+    set row {p q}
+    set a [list $row $row]
+    list [testevalex {lset a 0 0 x}] $a
+} {{{x q} {p q}} {{x q} {p q}}}
+test lset-10.2 {lset, not compiled, shared data} testevalex {
+    set row {p q}
+    set a [list $row $row]
+    list [testevalex {lset a {0 0} x}] $a
+} {{{x q} {p q}} {{x q} {p q}}}
+test lset-10.3 {lset, not compiled, shared data, [Bug 1333036]} testevalex {
+    set a [list [list p q] [list r s]]
+    set b $a
+    list [testevalex {lset b {0 0} x}] $a
+} {{{x q} {r s}} {{p q} {r s}}}
+
+test lset-11.1 {lset, not compiled, 2-d basics} testevalex {
+    set a {{b c} {d e}}
+    list [testevalex {lset a 0 0 f}] $a
+} {{{f c} {d e}} {{f c} {d e}}}
+test lset-11.2 {lset, not compiled, 2-d basics} testevalex {
+    set a {{b c} {d e}}
+    list [testevalex {lset a {0 0} f}] $a
+} {{{f c} {d e}} {{f c} {d e}}}
+test lset-11.3 {lset, not compiled, 2-d basics} testevalex {
+    set a {{b c} {d e}}
+    list [testevalex {lset a 0 1 f}] $a
+} {{{b f} {d e}} {{b f} {d e}}}
+test lset-11.4 {lset, not compiled, 2-d basics} testevalex {
+    set a {{b c} {d e}}
+    list [testevalex {lset a {0 1} f}] $a
+} {{{b f} {d e}} {{b f} {d e}}}
+test lset-11.5 {lset, not compiled, 2-d basics} testevalex {
+    set a {{b c} {d e}}
+    list [testevalex {lset a 1 0 f}] $a
+} {{{b c} {f e}} {{b c} {f e}}}
+test lset-11.6 {lset, not compiled, 2-d basics} testevalex {
+    set a {{b c} {d e}}
+    list [testevalex {lset a {1 0} f}] $a
+} {{{b c} {f e}} {{b c} {f e}}}
+test lset-11.7 {lset, not compiled, 2-d basics} testevalex {
+    set a {{b c} {d e}}
+    list [testevalex {lset a 1 1 f}] $a
+} {{{b c} {d f}} {{b c} {d f}}}
+test lset-11.8 {lset, not compiled, 2-d basics} testevalex {
+    set a {{b c} {d e}}
+    list [testevalex {lset a {1 1} f}] $a
+} {{{b c} {d f}} {{b c} {d f}}}
+
+test lset-12.0 {lset, not compiled, typical sharing pattern} testevalex {
+    set zero 0
+    set row [list $zero $zero $zero $zero]
+    set ident [list $row $row $row $row]
+    for { set i 0 } { $i < 4 } { incr i } {
+	testevalex {lset ident $i $i 1}
+    }
+    set ident
+} {{1 0 0 0} {0 1 0 0} {0 0 1 0} {0 0 0 1}}
+
+test lset-13.0 {lset, not compiled, shimmering hell} testevalex {
+    set a 0
+    list [testevalex {lset a $a $a $a $a {gag me}}] $a
+} {{{{{{gag me}}}}} {{{{{gag me}}}}}}
+test lset-13.1 {lset, not compiled, shimmering hell} testevalex {
+    set a [list 0]
+    list [testevalex {lset a $a $a $a $a {gag me}}] $a
+} {{{{{{gag me}}}}} {{{{{gag me}}}}}}
+test lset-13.2 {lset, not compiled, shimmering hell} testevalex {
+    set a [list 0 0 0 0]
+    list [testevalex {lset a $a {gag me}}] $a
+} {{{{{{gag me}}}} 0 0 0} {{{{{gag me}}}} 0 0 0}}
+
+test lset-14.1 {lset, not compiled, list args, is string rep preserved?} testevalex {
+    set a { { 1 2 } { 3 4 } }
+    catch { testevalex {lset a {1 5} 5} }
+    list $a [lindex $a 1]
+} "{ { 1 2 } { 3 4 } } { 3 4 }"
+test lset-14.2 {lset, not compiled, flat args, is string rep preserved?} testevalex {
+    set a { { 1 2 } { 3 4 } }
+    catch { testevalex {lset a 1 5 5} }
+    list $a [lindex $a 1]
+} "{ { 1 2 } { 3 4 } } { 3 4 }"
+
+testConstraint testobj [llength [info commands testobj]]
+test lset-15.1 {lset: shared intrep [Bug 1677512]} -setup {
+    teststringobj set 1 {{1 2} 3}
+    testobj convert 1 list
+    testobj duplicate 1 2
+    variable x [teststringobj get 1]
+    variable y [teststringobj get 2]
+    testobj freeallvars
+    set l [list $y z]
+    unset y
+} -constraints testobj -body {
+    lset l 0 0 0 5
+    lindex $x 0 0
+} -cleanup {
+    unset -nocomplain x l
+} -result 1
+
+test lset-16.1 {lset - grow a variable} testevalex {
+    set x {}
+    testevalex {lset x 0 {test 1}}
+    testevalex {lset x 1 {test 2}}
+    set x
+} {{test 1} {test 2}}
+test lset-16.2 {lset - multiple created sublists} testevalex {
+    set x {}
+    testevalex {lset x 0 0 {test 1}}
+} {{{test 1}}}
+test lset-16.3 {lset - sublists 3 deep} testevalex {
+    set x {}
+    testevalex {lset x 0 0 0 {test 1}}
+} {{{{test 1}}}}
+test lset-16.4 {lset - append to inner list} testevalex {
+    set x {test 1}
+    testevalex {lset x 1 1 2}
+    testevalex {lset x 1 2 3}
+    testevalex {lset x 1 2 1 4}
+} {test {1 2 {3 4}}}
+
+test lset-16.5 {lset - grow a variable} testevalex {
+    set x {}
+    testevalex {lset x end+1 {test 1}}
+    testevalex {lset x end+1 {test 2}}
+    set x
+} {{test 1} {test 2}}
+test lset-16.6 {lset - multiple created sublists} testevalex {
+    set x {}
+    testevalex {lset x end+1 end+1 {test 1}}
+} {{{test 1}}}
+test lset-16.7 {lset - sublists 3 deep} testevalex {
+    set x {}
+    testevalex {lset x end+1 end+1 end+1 {test 1}}
+} {{{{test 1}}}}
+test lset-16.8 {lset - append to inner list} testevalex {
+    set x {test 1}
+    testevalex {lset x end end+1 2}
+    testevalex {lset x end end+1 3}
+    testevalex {lset x end end end+1 4}
+} {test {1 2 {3 4}}}
+
+catch {unset noRead}
+catch {unset noWrite}
+catch {rename failTrace {}}
+catch {unset ::x}
+catch {unset ::y}
+
+# cleanup
+::tcltest::cleanupTests
+return
diff --git a/tests/lsetComp.test b/tests/lsetComp.test
new file mode 100644
index 0000000..6846cbf
--- /dev/null
+++ b/tests/lsetComp.test
@@ -0,0 +1,431 @@
+# This file is a -*- tcl -*- test script
+
+# Commands covered: lset
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands.  Sourcing this file into Tcl runs the tests and
+# generates output for errors.  No output means no errors were found.
+#
+# Copyright (c) 2001 by Kevin B. Kenny.  All rights reserved.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+    package require tcltest
+    namespace import -force ::tcltest::*
+}
+
+# Procedure to evaluate a script within a proc, to test compilation
+# functionality
+
+proc evalInProc { script } {
+    proc testProc {} $script
+    set status [catch {
+	testProc 
+    } result]
+    rename testProc {}
+    return [list $status $result]
+}
+
+# Tests for the bytecode compilation of the 'lset' command
+
+test lsetComp-1.1 {lset, compiled, wrong \# args} {
+    evalInProc {
+	lset
+    }
+} "1 {wrong \# args: should be \"lset listVar ?index? ?index ...? value\"}"
+
+test lsetComp-2.1 {lset, compiled, list of args, not a simple var name} {
+    evalInProc {
+	set y x
+	set x {{1 2} {3 4}}
+	lset $y {1 1} 5
+    }
+} "0 {{1 2} {3 5}}"
+
+test lsetComp-2.2 {lset, compiled, list of args, scalar on stack} {
+    evalInProc {
+	set ::x {{1 2} {3 4}}
+	lset ::x {1 1} 5
+    }
+} "0 {{1 2} {3 5}}"
+
+test lsetComp-2.3 {lset, compiled, list of args, scalar, one-byte offset} {
+    evalInProc {
+	set x {{1 2} {3 4}}
+	lset x {1 1} 5
+    }
+} "0 {{1 2} {3 5}}"
+
+test lsetComp-2.4 {lset, compiled, list of args, scalar, four-byte offset} {
+    evalInProc {
+	set x0 0; set x1 0; set x2 0; set x3 0; 
+	set x4 0; set x5 0; set x6 0; set x7 0; 
+	set x8 0; set x9 0; set x10 0; set x11 0; 
+	set x12 0; set x13 0; set x14 0; set x15 0; 
+	set x16 0; set x17 0; set x18 0; set x19 0; 
+	set x20 0; set x21 0; set x22 0; set x23 0; 
+	set x24 0; set x25 0; set x26 0; set x27 0; 
+	set x28 0; set x29 0; set x30 0; set x31 0; 
+	set x32 0; set x33 0; set x34 0; set x35 0; 
+	set x36 0; set x37 0; set x38 0; set x39 0; 
+	set x40 0; set x41 0; set x42 0; set x43 0; 
+	set x44 0; set x45 0; set x46 0; set x47 0; 
+	set x48 0; set x49 0; set x50 0; set x51 0; 
+	set x52 0; set x53 0; set x54 0; set x55 0; 
+	set x56 0; set x57 0; set x58 0; set x59 0; 
+	set x60 0; set x61 0; set x62 0; set x63 0; 
+	set x64 0; set x65 0; set x66 0; set x67 0; 
+	set x68 0; set x69 0; set x70 0; set x71 0; 
+	set x72 0; set x73 0; set x74 0; set x75 0; 
+	set x76 0; set x77 0; set x78 0; set x79 0; 
+	set x80 0; set x81 0; set x82 0; set x83 0; 
+	set x84 0; set x85 0; set x86 0; set x87 0; 
+	set x88 0; set x89 0; set x90 0; set x91 0; 
+	set x92 0; set x93 0; set x94 0; set x95 0; 
+	set x96 0; set x97 0; set x98 0; set x99 0; 
+	set x100 0; set x101 0; set x102 0; set x103 0; 
+	set x104 0; set x105 0; set x106 0; set x107 0; 
+	set x108 0; set x109 0; set x110 0; set x111 0; 
+	set x112 0; set x113 0; set x114 0; set x115 0; 
+	set x116 0; set x117 0; set x118 0; set x119 0; 
+	set x120 0; set x121 0; set x122 0; set x123 0; 
+	set x124 0; set x125 0; set x126 0; set x127 0; 
+	set x128 0; set x129 0; set x130 0; set x131 0; 
+	set x132 0; set x133 0; set x134 0; set x135 0; 
+	set x136 0; set x137 0; set x138 0; set x139 0; 
+	set x140 0; set x141 0; set x142 0; set x143 0; 
+	set x144 0; set x145 0; set x146 0; set x147 0; 
+	set x148 0; set x149 0; set x150 0; set x151 0; 
+	set x152 0; set x153 0; set x154 0; set x155 0; 
+	set x156 0; set x157 0; set x158 0; set x159 0; 
+	set x160 0; set x161 0; set x162 0; set x163 0; 
+	set x164 0; set x165 0; set x166 0; set x167 0; 
+	set x168 0; set x169 0; set x170 0; set x171 0; 
+	set x172 0; set x173 0; set x174 0; set x175 0; 
+	set x176 0; set x177 0; set x178 0; set x179 0; 
+	set x180 0; set x181 0; set x182 0; set x183 0; 
+	set x184 0; set x185 0; set x186 0; set x187 0; 
+	set x188 0; set x189 0; set x190 0; set x191 0; 
+	set x192 0; set x193 0; set x194 0; set x195 0; 
+	set x196 0; set x197 0; set x198 0; set x199 0; 
+	set x200 0; set x201 0; set x202 0; set x203 0; 
+	set x204 0; set x205 0; set x206 0; set x207 0; 
+	set x208 0; set x209 0; set x210 0; set x211 0; 
+	set x212 0; set x213 0; set x214 0; set x215 0; 
+	set x216 0; set x217 0; set x218 0; set x219 0; 
+	set x220 0; set x221 0; set x222 0; set x223 0; 
+	set x224 0; set x225 0; set x226 0; set x227 0; 
+	set x228 0; set x229 0; set x230 0; set x231 0; 
+	set x232 0; set x233 0; set x234 0; set x235 0; 
+	set x236 0; set x237 0; set x238 0; set x239 0; 
+	set x240 0; set x241 0; set x242 0; set x243 0; 
+	set x244 0; set x245 0; set x246 0; set x247 0; 
+	set x248 0; set x249 0; set x250 0; set x251 0; 
+	set x252 0; set x253 0; set x254 0; set x255 0;
+	set x {{1 2} {3 4}}
+	lset x {1 1} 5
+    }
+} "0 {{1 2} {3 5}}"
+
+test lsetComp-2.5 {lset, compiled, list of args, array on stack} {
+    evalInProc {
+	set ::y(0) {{1 2} {3 4}}
+	lset ::y(0) {1 1} 5
+    }
+} "0 {{1 2} {3 5}}"
+
+test lsetComp-2.6 {lset, compiled, list of args, array, one-byte offset} {
+    evalInProc {
+	set y(0) {{1 2} {3 4}}
+	lset y(0) {1 1} 5
+    }
+} "0 {{1 2} {3 5}}"
+
+test lsetComp-2.7 {lset, compiled, list of args, array, four-byte offset} {
+    evalInProc {
+	set x0 0; set x1 0; set x2 0; set x3 0; 
+	set x4 0; set x5 0; set x6 0; set x7 0; 
+	set x8 0; set x9 0; set x10 0; set x11 0; 
+	set x12 0; set x13 0; set x14 0; set x15 0; 
+	set x16 0; set x17 0; set x18 0; set x19 0; 
+	set x20 0; set x21 0; set x22 0; set x23 0; 
+	set x24 0; set x25 0; set x26 0; set x27 0; 
+	set x28 0; set x29 0; set x30 0; set x31 0; 
+	set x32 0; set x33 0; set x34 0; set x35 0; 
+	set x36 0; set x37 0; set x38 0; set x39 0; 
+	set x40 0; set x41 0; set x42 0; set x43 0; 
+	set x44 0; set x45 0; set x46 0; set x47 0; 
+	set x48 0; set x49 0; set x50 0; set x51 0; 
+	set x52 0; set x53 0; set x54 0; set x55 0; 
+	set x56 0; set x57 0; set x58 0; set x59 0; 
+	set x60 0; set x61 0; set x62 0; set x63 0; 
+	set x64 0; set x65 0; set x66 0; set x67 0; 
+	set x68 0; set x69 0; set x70 0; set x71 0; 
+	set x72 0; set x73 0; set x74 0; set x75 0; 
+	set x76 0; set x77 0; set x78 0; set x79 0; 
+	set x80 0; set x81 0; set x82 0; set x83 0; 
+	set x84 0; set x85 0; set x86 0; set x87 0; 
+	set x88 0; set x89 0; set x90 0; set x91 0; 
+	set x92 0; set x93 0; set x94 0; set x95 0; 
+	set x96 0; set x97 0; set x98 0; set x99 0; 
+	set x100 0; set x101 0; set x102 0; set x103 0; 
+	set x104 0; set x105 0; set x106 0; set x107 0; 
+	set x108 0; set x109 0; set x110 0; set x111 0; 
+	set x112 0; set x113 0; set x114 0; set x115 0; 
+	set x116 0; set x117 0; set x118 0; set x119 0; 
+	set x120 0; set x121 0; set x122 0; set x123 0; 
+	set x124 0; set x125 0; set x126 0; set x127 0; 
+	set x128 0; set x129 0; set x130 0; set x131 0; 
+	set x132 0; set x133 0; set x134 0; set x135 0; 
+	set x136 0; set x137 0; set x138 0; set x139 0; 
+	set x140 0; set x141 0; set x142 0; set x143 0; 
+	set x144 0; set x145 0; set x146 0; set x147 0; 
+	set x148 0; set x149 0; set x150 0; set x151 0; 
+	set x152 0; set x153 0; set x154 0; set x155 0; 
+	set x156 0; set x157 0; set x158 0; set x159 0; 
+	set x160 0; set x161 0; set x162 0; set x163 0; 
+	set x164 0; set x165 0; set x166 0; set x167 0; 
+	set x168 0; set x169 0; set x170 0; set x171 0; 
+	set x172 0; set x173 0; set x174 0; set x175 0; 
+	set x176 0; set x177 0; set x178 0; set x179 0; 
+	set x180 0; set x181 0; set x182 0; set x183 0; 
+	set x184 0; set x185 0; set x186 0; set x187 0; 
+	set x188 0; set x189 0; set x190 0; set x191 0; 
+	set x192 0; set x193 0; set x194 0; set x195 0; 
+	set x196 0; set x197 0; set x198 0; set x199 0; 
+	set x200 0; set x201 0; set x202 0; set x203 0; 
+	set x204 0; set x205 0; set x206 0; set x207 0; 
+	set x208 0; set x209 0; set x210 0; set x211 0; 
+	set x212 0; set x213 0; set x214 0; set x215 0; 
+	set x216 0; set x217 0; set x218 0; set x219 0; 
+	set x220 0; set x221 0; set x222 0; set x223 0; 
+	set x224 0; set x225 0; set x226 0; set x227 0; 
+	set x228 0; set x229 0; set x230 0; set x231 0; 
+	set x232 0; set x233 0; set x234 0; set x235 0; 
+	set x236 0; set x237 0; set x238 0; set x239 0; 
+	set x240 0; set x241 0; set x242 0; set x243 0; 
+	set x244 0; set x245 0; set x246 0; set x247 0; 
+	set x248 0; set x249 0; set x250 0; set x251 0; 
+	set x252 0; set x253 0; set x254 0; set x255 0;
+	set y(0) {{1 2} {3 4}}
+	lset y(0) {1 1} 5
+    }
+} "0 {{1 2} {3 5}}"
+
+test lsetComp-2.8 {lset, compiled, list of args, error } {
+    evalInProc {
+	set x { {1 2} {3 4} }
+	lset x {1 5} 5
+    }
+} "1 {list index out of range}"
+
+test lsetComp-2.9 {lset, compiled, list of args, error - is string preserved} {
+    set ::x { { 1 2 } { 3 4 } }
+    evalInProc {
+	lset ::x { 1 5 } 5
+    }
+    list $::x [lindex $::x 1]
+} "{ { 1 2 } { 3 4 } } { 3 4 }"
+
+test lsetComp-3.1 {lset, compiled, flat args, not a simple var name} {
+    evalInProc {
+	set y x
+	set x {{1 2} {3 4}}
+	lset $y 1 1 5
+    }
+} "0 {{1 2} {3 5}}"
+
+test lsetComp-3.2 {lset, compiled, flat args, scalar on stack} {
+    evalInProc {
+	set ::x {{1 2} {3 4}}
+	lset ::x 1 1 5
+    }
+} "0 {{1 2} {3 5}}"
+
+test lsetComp-3.3 {lset, compiled, flat args, scalar, one-byte offset} {
+    evalInProc {
+	set x {{1 2} {3 4}}
+	lset x 1 1 5
+    }
+} "0 {{1 2} {3 5}}"
+
+test lsetComp-3.4 {lset, compiled, scalar, four-byte offset} {
+    evalInProc {
+	set x0 0; set x1 0; set x2 0; set x3 0; 
+	set x4 0; set x5 0; set x6 0; set x7 0; 
+	set x8 0; set x9 0; set x10 0; set x11 0; 
+	set x12 0; set x13 0; set x14 0; set x15 0; 
+	set x16 0; set x17 0; set x18 0; set x19 0; 
+	set x20 0; set x21 0; set x22 0; set x23 0; 
+	set x24 0; set x25 0; set x26 0; set x27 0; 
+	set x28 0; set x29 0; set x30 0; set x31 0; 
+	set x32 0; set x33 0; set x34 0; set x35 0; 
+	set x36 0; set x37 0; set x38 0; set x39 0; 
+	set x40 0; set x41 0; set x42 0; set x43 0; 
+	set x44 0; set x45 0; set x46 0; set x47 0; 
+	set x48 0; set x49 0; set x50 0; set x51 0; 
+	set x52 0; set x53 0; set x54 0; set x55 0; 
+	set x56 0; set x57 0; set x58 0; set x59 0; 
+	set x60 0; set x61 0; set x62 0; set x63 0; 
+	set x64 0; set x65 0; set x66 0; set x67 0; 
+	set x68 0; set x69 0; set x70 0; set x71 0; 
+	set x72 0; set x73 0; set x74 0; set x75 0; 
+	set x76 0; set x77 0; set x78 0; set x79 0; 
+	set x80 0; set x81 0; set x82 0; set x83 0; 
+	set x84 0; set x85 0; set x86 0; set x87 0; 
+	set x88 0; set x89 0; set x90 0; set x91 0; 
+	set x92 0; set x93 0; set x94 0; set x95 0; 
+	set x96 0; set x97 0; set x98 0; set x99 0; 
+	set x100 0; set x101 0; set x102 0; set x103 0; 
+	set x104 0; set x105 0; set x106 0; set x107 0; 
+	set x108 0; set x109 0; set x110 0; set x111 0; 
+	set x112 0; set x113 0; set x114 0; set x115 0; 
+	set x116 0; set x117 0; set x118 0; set x119 0; 
+	set x120 0; set x121 0; set x122 0; set x123 0; 
+	set x124 0; set x125 0; set x126 0; set x127 0; 
+	set x128 0; set x129 0; set x130 0; set x131 0; 
+	set x132 0; set x133 0; set x134 0; set x135 0; 
+	set x136 0; set x137 0; set x138 0; set x139 0; 
+	set x140 0; set x141 0; set x142 0; set x143 0; 
+	set x144 0; set x145 0; set x146 0; set x147 0; 
+	set x148 0; set x149 0; set x150 0; set x151 0; 
+	set x152 0; set x153 0; set x154 0; set x155 0; 
+	set x156 0; set x157 0; set x158 0; set x159 0; 
+	set x160 0; set x161 0; set x162 0; set x163 0; 
+	set x164 0; set x165 0; set x166 0; set x167 0; 
+	set x168 0; set x169 0; set x170 0; set x171 0; 
+	set x172 0; set x173 0; set x174 0; set x175 0; 
+	set x176 0; set x177 0; set x178 0; set x179 0; 
+	set x180 0; set x181 0; set x182 0; set x183 0; 
+	set x184 0; set x185 0; set x186 0; set x187 0; 
+	set x188 0; set x189 0; set x190 0; set x191 0; 
+	set x192 0; set x193 0; set x194 0; set x195 0; 
+	set x196 0; set x197 0; set x198 0; set x199 0; 
+	set x200 0; set x201 0; set x202 0; set x203 0; 
+	set x204 0; set x205 0; set x206 0; set x207 0; 
+	set x208 0; set x209 0; set x210 0; set x211 0; 
+	set x212 0; set x213 0; set x214 0; set x215 0; 
+	set x216 0; set x217 0; set x218 0; set x219 0; 
+	set x220 0; set x221 0; set x222 0; set x223 0; 
+	set x224 0; set x225 0; set x226 0; set x227 0; 
+	set x228 0; set x229 0; set x230 0; set x231 0; 
+	set x232 0; set x233 0; set x234 0; set x235 0; 
+	set x236 0; set x237 0; set x238 0; set x239 0; 
+	set x240 0; set x241 0; set x242 0; set x243 0; 
+	set x244 0; set x245 0; set x246 0; set x247 0; 
+	set x248 0; set x249 0; set x250 0; set x251 0; 
+	set x252 0; set x253 0; set x254 0; set x255 0;
+	set x {{1 2} {3 4}}
+	lset x 1 1 5
+    }
+} "0 {{1 2} {3 5}}"
+
+test lsetComp-3.5 {lset, compiled, flat args, array on stack} {
+    evalInProc {
+	set ::y(0) {{1 2} {3 4}}
+	lset ::y(0) 1 1 5
+    }
+} "0 {{1 2} {3 5}}"
+
+test lsetComp-3.6 {lset, compiled, flat args, array, one-byte offset} {
+    evalInProc {
+	set y(0) {{1 2} {3 4}}
+	lset y(0) 1 1 5
+    }
+} "0 {{1 2} {3 5}}"
+
+test lsetComp-3.7 {lset, compiled, flat args, array, four-byte offset} {
+    evalInProc {
+	set x0 0; set x1 0; set x2 0; set x3 0; 
+	set x4 0; set x5 0; set x6 0; set x7 0; 
+	set x8 0; set x9 0; set x10 0; set x11 0; 
+	set x12 0; set x13 0; set x14 0; set x15 0; 
+	set x16 0; set x17 0; set x18 0; set x19 0; 
+	set x20 0; set x21 0; set x22 0; set x23 0; 
+	set x24 0; set x25 0; set x26 0; set x27 0; 
+	set x28 0; set x29 0; set x30 0; set x31 0; 
+	set x32 0; set x33 0; set x34 0; set x35 0; 
+	set x36 0; set x37 0; set x38 0; set x39 0; 
+	set x40 0; set x41 0; set x42 0; set x43 0; 
+	set x44 0; set x45 0; set x46 0; set x47 0; 
+	set x48 0; set x49 0; set x50 0; set x51 0; 
+	set x52 0; set x53 0; set x54 0; set x55 0; 
+	set x56 0; set x57 0; set x58 0; set x59 0; 
+	set x60 0; set x61 0; set x62 0; set x63 0; 
+	set x64 0; set x65 0; set x66 0; set x67 0; 
+	set x68 0; set x69 0; set x70 0; set x71 0; 
+	set x72 0; set x73 0; set x74 0; set x75 0; 
+	set x76 0; set x77 0; set x78 0; set x79 0; 
+	set x80 0; set x81 0; set x82 0; set x83 0; 
+	set x84 0; set x85 0; set x86 0; set x87 0; 
+	set x88 0; set x89 0; set x90 0; set x91 0; 
+	set x92 0; set x93 0; set x94 0; set x95 0; 
+	set x96 0; set x97 0; set x98 0; set x99 0; 
+	set x100 0; set x101 0; set x102 0; set x103 0; 
+	set x104 0; set x105 0; set x106 0; set x107 0; 
+	set x108 0; set x109 0; set x110 0; set x111 0; 
+	set x112 0; set x113 0; set x114 0; set x115 0; 
+	set x116 0; set x117 0; set x118 0; set x119 0; 
+	set x120 0; set x121 0; set x122 0; set x123 0; 
+	set x124 0; set x125 0; set x126 0; set x127 0; 
+	set x128 0; set x129 0; set x130 0; set x131 0; 
+	set x132 0; set x133 0; set x134 0; set x135 0; 
+	set x136 0; set x137 0; set x138 0; set x139 0; 
+	set x140 0; set x141 0; set x142 0; set x143 0; 
+	set x144 0; set x145 0; set x146 0; set x147 0; 
+	set x148 0; set x149 0; set x150 0; set x151 0; 
+	set x152 0; set x153 0; set x154 0; set x155 0; 
+	set x156 0; set x157 0; set x158 0; set x159 0; 
+	set x160 0; set x161 0; set x162 0; set x163 0; 
+	set x164 0; set x165 0; set x166 0; set x167 0; 
+	set x168 0; set x169 0; set x170 0; set x171 0; 
+	set x172 0; set x173 0; set x174 0; set x175 0; 
+	set x176 0; set x177 0; set x178 0; set x179 0; 
+	set x180 0; set x181 0; set x182 0; set x183 0; 
+	set x184 0; set x185 0; set x186 0; set x187 0; 
+	set x188 0; set x189 0; set x190 0; set x191 0; 
+	set x192 0; set x193 0; set x194 0; set x195 0; 
+	set x196 0; set x197 0; set x198 0; set x199 0; 
+	set x200 0; set x201 0; set x202 0; set x203 0; 
+	set x204 0; set x205 0; set x206 0; set x207 0; 
+	set x208 0; set x209 0; set x210 0; set x211 0; 
+	set x212 0; set x213 0; set x214 0; set x215 0; 
+	set x216 0; set x217 0; set x218 0; set x219 0; 
+	set x220 0; set x221 0; set x222 0; set x223 0; 
+	set x224 0; set x225 0; set x226 0; set x227 0; 
+	set x228 0; set x229 0; set x230 0; set x231 0; 
+	set x232 0; set x233 0; set x234 0; set x235 0; 
+	set x236 0; set x237 0; set x238 0; set x239 0; 
+	set x240 0; set x241 0; set x242 0; set x243 0; 
+	set x244 0; set x245 0; set x246 0; set x247 0; 
+	set x248 0; set x249 0; set x250 0; set x251 0; 
+	set x252 0; set x253 0; set x254 0; set x255 0;
+	set y(0) {{1 2} {3 4}}
+	lset y(0) 1 1 5
+    }
+} "0 {{1 2} {3 5}}"
+
+test lsetComp-3.8 {lset, compiled, flat args, error } {
+    evalInProc {
+	set x { {1 2} {3 4} }
+	lset x 1 5 5
+    }
+} "1 {list index out of range}"
+
+test lsetComp-3.9 {lset, compiled, flat args, error - is string preserved} {
+    set ::x { { 1 2 } { 3 4 } }
+    evalInProc {
+	lset ::x 1 5 5
+    }
+    list $::x [lindex $::x 1]
+} "{ { 1 2 } { 3 4 } } { 3 4 }"
+
+catch { rename evalInProc {} }
+catch { unset ::x }
+catch { unset ::y }
+
+# cleanup
+::tcltest::cleanupTests
+return
diff --git a/tests/macOSXFCmd.test b/tests/macOSXFCmd.test
new file mode 100644
index 0000000..071f11b
--- /dev/null
+++ b/tests/macOSXFCmd.test
@@ -0,0 +1,181 @@
+# This file tests the tclMacOSXFCmd.c file.
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands.  Sourcing this file into Tcl runs the tests and
+# generates output for errors.  No output means no errors were found.
+#
+# Copyright (c) 2003 Tcl Core Team.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+    package require tcltest
+    namespace import -force ::tcltest::*
+}
+
+# These tests really need to be run from a writable directory, which
+# it is assumed [temporaryDirectory] is.
+set oldcwd [pwd]
+cd [temporaryDirectory]
+
+# check whether macosx file attributes are supported
+testConstraint macosxFileAttr 0
+if {[testConstraint unix] && $tcl_platform(os) eq "Darwin"} {
+    catch {file delete -force -- foo.test}
+    close [open foo.test w]
+    catch {
+	file attributes foo.test -creator
+	testConstraint macosxFileAttr 1
+    }
+    file delete -force -- foo.test
+}
+
+test macOSXFCmd-1.1 {MacOSXGetFileAttribute - file not found} {macosxFileAttr notRoot} {
+    catch {file delete -force -- foo.test}
+    list [catch {file attributes foo.test -creator} msg] $msg
+} {1 {could not read "foo.test": no such file or directory}}
+test macOSXFCmd-1.2 {MacOSXGetFileAttribute - creator} {macosxFileAttr notRoot} {
+    catch {file delete -force -- foo.test}
+    close [open foo.test w]
+    list [catch {file attributes foo.test -creator} msg] $msg \
+	    [file delete -force -- foo.test]
+} {0 {} {}}
+test macOSXFCmd-1.3 {MacOSXGetFileAttribute - type} {macosxFileAttr notRoot} {
+    catch {file delete -force -- foo.test}
+    close [open foo.test w]
+    list [catch {file attributes foo.test -type} msg] $msg \
+	    [file delete -force -- foo.test]
+} {0 {} {}}
+test macOSXFCmd-1.4 {MacOSXGetFileAttribute - hidden} {macosxFileAttr notRoot} {
+    catch {file delete -force -- foo.test}
+    close [open foo.test w]
+    list [catch {file attributes foo.test -hidden} msg] $msg \
+	    [file delete -force -- foo.test]
+} {0 0 {}}
+test macOSXFCmd-1.5 {MacOSXGetFileAttribute - rsrclength} {macosxFileAttr notRoot} {
+    catch {file delete -force -- foo.test}
+    close [open foo.test w]
+    list [catch {file attributes foo.test -rsrclength} msg] $msg \
+	    [file delete -force -- foo.test]
+} {0 0 {}}
+
+test macOSXFCmd-2.1 {MacOSXSetFileAttribute - file not found} {macosxFileAttr notRoot} {
+    catch {file delete -force -- foo.test}
+    list [catch {file attributes foo.test -creator FOOC} msg] $msg
+} {1 {could not read "foo.test": no such file or directory}}
+test macOSXFCmd-2.2 {MacOSXSetFileAttribute - creator} {macosxFileAttr notRoot} {
+    catch {file delete -force -- foo.test}
+    close [open foo.test w]
+    list [catch {file attributes foo.test -creator FOOC} msg] $msg \
+	    [catch {file attributes foo.test -creator} msg] $msg \
+	    [file delete -force -- foo.test]
+} {0 {} 0 FOOC {}}
+test macOSXFCmd-2.3 {MacOSXSetFileAttribute - empty creator} {macosxFileAttr notRoot} {
+    catch {file delete -force -- foo.test}
+    close [open foo.test w]
+    list [catch {file attributes foo.test -creator {}} msg] $msg \
+	    [catch {file attributes foo.test -creator} msg] $msg \
+	    [file delete -force -- foo.test]
+} {0 {} 0 {} {}}
+test macOSXFCmd-2.4 {MacOSXSetFileAttribute - type} {macosxFileAttr notRoot} {
+    catch {file delete -force -- foo.test}
+    close [open foo.test w]
+    list [catch {file attributes foo.test -type FOOT} msg] $msg \
+	    [catch {file attributes foo.test -type} msg] $msg \
+	    [file delete -force -- foo.test]
+} {0 {} 0 FOOT {}}
+test macOSXFCmd-2.5 {MacOSXSetFileAttribute - empty type} {macosxFileAttr notRoot} {
+    catch {file delete -force -- foo.test}
+    close [open foo.test w]
+    list [catch {file attributes foo.test -type {}} msg] $msg \
+	    [catch {file attributes foo.test -type} msg] $msg \
+	    [file delete -force -- foo.test]
+} {0 {} 0 {} {}}
+test macOSXFCmd-2.6 {MacOSXSetFileAttribute - hidden} {macosxFileAttr notRoot} {
+    catch {file delete -force -- foo.test}
+    close [open foo.test w]
+    list [catch {file attributes foo.test -hidden 1} msg] $msg \
+	    [catch {file attributes foo.test -hidden} msg] $msg \
+	    [file delete -force -- foo.test]
+} {0 {} 0 1 {}}
+test macOSXFCmd-2.7 {MacOSXSetFileAttribute - rsrclength} {macosxFileAttr notRoot} {
+    catch {file delete -force -- foo.test}
+    close [open foo.test w]
+    catch {
+	set f [open foo.test/..namedfork/rsrc w]
+	fconfigure $f -translation lf -eofchar {}
+	puts -nonewline $f "foo"
+	close $f
+    }
+    list [catch {file attributes foo.test -rsrclength} msg] $msg \
+	    [catch {file attributes foo.test -rsrclength 0} msg] $msg \
+	    [catch {file attributes foo.test -rsrclength} msg] $msg \
+	    [file delete -force -- foo.test]
+} {0 3 0 {} 0 0 {}}
+
+test macOSXFCmd-3.1 {MacOSXCopyFileAttributes} {macosxFileAttr notRoot} {
+    catch {file delete -force -- foo.test}
+    catch {file delete -force -- bar.test}
+    close [open foo.test w]
+    catch {
+	file attributes foo.test -creator FOOC -type FOOT -hidden 1
+	set f [open foo.test/..namedfork/rsrc w]
+	fconfigure $f -translation lf -eofchar {}
+	puts -nonewline $f "foo"
+	close $f
+	file copy foo.test bar.test
+    }
+    list [catch {file attributes bar.test -creator} msg] $msg \
+	    [catch {file attributes bar.test -type} msg] $msg \
+	    [catch {file attributes bar.test -hidden} msg] $msg \
+	    [catch {file attributes bar.test -rsrclength} msg] $msg \
+	    [file delete -force -- foo.test bar.test]
+} {0 FOOC 0 FOOT 0 1 0 3 {}}
+
+test macOSXFCmd-4.1 {TclMacOSXMatchType} {macosxFileAttr notRoot} {
+    file mkdir globtest
+    cd globtest
+    foreach f {bar baz foo inv inw .nv reg} {
+	catch {file delete -force -- $f.test}
+	close [open $f.test w]
+    }
+    catch {file delete -force -- dir.test}
+    file mkdir dir.test
+    catch {
+	file attributes bar.test -type FOOT
+	file attributes baz.test -creator FOOC -type FOOT
+	file attributes foo.test -creator FOOC
+	file attributes inv.test -hidden 1
+	file attributes inw.test -hidden 1 -type FOOT
+	file attributes dir.test -hidden 1
+    }
+    set res [list \
+	    [catch {glob *.test} msg] $msg \
+	    [catch {glob -types FOOT *.test} msg] $msg \
+	    [catch {glob -types {{macintosh type FOOT}} *.test} msg] $msg \
+	    [catch {glob -types FOOTT *.test} msg] $msg \
+	    [catch {glob -types {{macintosh type FOOTT}} *.test} msg] $msg \
+	    [catch {glob -types {{macintosh type {}}} *.test} msg] $msg \
+	    [catch {glob -types {{macintosh creator FOOC}} *.test} msg] $msg \
+	    [catch {glob -types {{macintosh creator FOOC} {macintosh type FOOT}} *.test} msg] $msg \
+	    [catch {glob -types hidden *.test} msg] $msg \
+	    [catch {glob -types {hidden FOOT} *.test} msg] $msg \
+	]
+    cd ..
+    file delete -force globtest
+    set res
+} [list \
+	0 {bar.test baz.test dir.test foo.test inv.test inw.test reg.test} \
+	0 {bar.test baz.test inw.test} 0 {bar.test baz.test inw.test} \
+	1 {bad argument to "-types": FOOTT} \
+	1 {expected Macintosh OS type but got "FOOTT": } \
+	0 {foo.test inv.test reg.test} 0 {baz.test foo.test} \
+	0 baz.test 0 {.nv.test dir.test inv.test inw.test} \
+	0 inw.test
+]
+
+# cleanup
+cd $oldcwd
+::tcltest::cleanupTests
+return
diff --git a/tests/macOSXLoad.test b/tests/macOSXLoad.test
new file mode 100644
index 0000000..12c77e0
--- /dev/null
+++ b/tests/macOSXLoad.test
@@ -0,0 +1,33 @@
+# Commands covered:  load unload
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands.  Sourcing this file into Tcl runs the tests and
+# generates output for errors.  No output means no errors were found.
+#
+# Copyright (c) 1995 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+    package require tcltest 2
+    namespace import -force ::tcltest::*
+}
+set oldTSF $::tcltest::testSingleFile
+set ::tcltest::testSingleFile false
+
+if {[testConstraint unix] && $tcl_platform(os) eq "Darwin" &&
+	![string match *pkga* [info loaded]]} {
+    # On Darwin, test .bundle (un)loading in addition to .dylib
+    set ext .bundle
+    source [file join [file dirname [info script]] load.test]
+    set ext .bundle
+    source [file join [file dirname [info script]] unload.test]
+    unset -nocomplain ext
+}
+
+set ::tcltest::testSingleFile $oldTSF
+unset oldTSF
+::tcltest::cleanupTests
+return
diff --git a/tests/main.test b/tests/main.test
new file mode 100644
index 0000000..351fd4f
--- /dev/null
+++ b/tests/main.test
@@ -0,0 +1,1297 @@
+# This file contains a collection of tests for generic/tclMain.c.
+
+if {[catch {package require tcltest 2.0.2}]} {
+    puts stderr "Skipping tests in [info script]. tcltest 2.0.2 required."
+    return
+}
+
+namespace eval ::tcl::test::main {
+    namespace import ::tcltest::*
+
+    # Is [exec] defined?
+    testConstraint exec [llength [info commands exec]]
+
+    # Is the Tcltest package loaded?
+    #	- that is, the special C-coded testing commands in tclTest.c
+    #   - tests use testing commands introduced in Tcltest 8.4
+    testConstraint Tcltest [expr {
+	[llength [package provide Tcltest]]
+	&& [package vsatisfies [package provide Tcltest] 8.4]}]
+
+    # Procedure to simulate interactive typing of commands, line by line
+    proc type {chan script} {
+	foreach line [split $script \n] {
+	    if {[catch {
+	        puts $chan $line
+	        flush $chan
+	    }]} {
+		return
+	    }
+	    # Grrr... Behavior depends on this value.
+	    after 1000
+	}
+    }
+
+    cd [temporaryDirectory]
+    # Tests Tcl_Main-1.*: variable initializations
+
+    test Tcl_Main-1.1 {
+	Tcl_Main: startup script - normal
+    } -constraints {
+	stdio
+    } -setup {
+	makeFile {puts [list $argv0 $argv $tcl_interactive]} script
+	catch {set f [open "|[list [interpreter] script]" r]}
+    } -body {
+	read $f
+    } -cleanup {
+	close $f
+	removeFile script
+    } -result [list script {} 0]\n
+
+    test Tcl_Main-1.2 {
+	Tcl_Main: startup script - can't begin with '-'
+    } -constraints {
+	stdio
+    } -setup {
+	makeFile {puts [list $argv0 $argv $tcl_interactive]} -script
+	catch {set f [open "|[list [interpreter] -script]" w+]}
+    } -body {
+	puts $f {puts [list $argv0 $argv $tcl_interactive]; exit}
+	flush $f
+	read $f
+    } -cleanup {
+	close $f
+	removeFile -script
+    } -result [list [interpreter] -script 0]\n
+
+    test Tcl_Main-1.3 {
+    } -constraints {
+	stdio
+    } -setup {
+	makeFile {puts [list $argv0 $argv $tcl_interactive]} script
+	catch {set f [open "|[list [interpreter] script \u00c0]" r]}
+    } -body {
+	read $f
+    } -cleanup {
+	close $f
+	removeFile script
+    } -result [list script [list [encoding convertfrom [encoding system] \
+	[encoding convertto [encoding system] \u00c0]]] 0]\n
+
+    test Tcl_Main-1.4 {
+    } -constraints {
+	stdio
+    } -setup {
+	makeFile {puts [list $argv0 $argv $tcl_interactive]} script
+	catch {set f [open "|[list [interpreter] script \u20ac]" r]}
+    } -body {
+	read $f
+    } -cleanup {
+	close $f
+	removeFile script
+    } -result [list script [list [encoding convertfrom [encoding system] \
+	[encoding convertto [encoding system] \u20ac]]] 0]\n
+
+    test Tcl_Main-1.5 {
+    } -constraints {
+	stdio
+    } -setup {
+	makeFile {puts [list $argv0 $argv $tcl_interactive]} \u00c0
+	catch {set f [open "|[list [interpreter] \u00c0]" r]}
+    } -body {
+	read $f
+    } -cleanup {
+	close $f
+	removeFile \u00c0
+    } -result [list [list [encoding convertfrom [encoding system] \
+	[encoding convertto [encoding system] \u00c0]]] {} 0]\n
+
+    test Tcl_Main-1.6 {
+    } -constraints {
+	stdio
+    } -setup {
+	makeFile {puts [list $argv0 $argv $tcl_interactive]} \u20ac
+	catch {set f [open "|[list [interpreter] \u20ac]" r]}
+    } -body {
+	read $f
+    } -cleanup {
+	close $f
+	removeFile \u20ac
+    } -result [list [list [encoding convertfrom [encoding system] \
+	[encoding convertto [encoding system] \u20ac]]] {} 0]\n
+
+    test Tcl_Main-1.7 {
+	Tcl_Main: startup script - -encoding option
+    } -constraints {
+	stdio
+    } -setup {
+	set script [makeFile {} script]
+	file delete $script
+	set f [open $script w]
+	chan configure $f -encoding utf-8
+	puts $f {puts [list $argv0 $argv $tcl_interactive]}
+	puts -nonewline $f {puts [string equal \u20ac }
+	puts $f "\u20ac]"
+	close $f
+	catch {set f [open "|[list [interpreter] -encoding utf-8 script]" r]}
+    } -body {
+	read $f
+    } -cleanup {
+	close $f
+	removeFile script
+    } -result [list script {} 0]\n1\n
+
+    test Tcl_Main-1.8 {
+	Tcl_Main: startup script - -encoding option - mismatched encodings
+    } -constraints {
+	stdio
+    } -setup {
+	set script [makeFile {} script]
+	file delete $script
+	set f [open $script w]
+	chan configure $f -encoding utf-8
+	puts $f {puts [list $argv0 $argv $tcl_interactive]}
+	puts -nonewline $f {puts [string equal \u20ac }
+	puts $f "\u20ac]"
+	close $f
+	catch {set f [open "|[list [interpreter] -encoding ascii script]" r]}
+    } -body {
+	read $f
+    } -cleanup {
+	close $f
+	removeFile script
+    } -result [list script {} 0]\n0\n
+
+    test Tcl_Main-1.9 {
+	Tcl_Main: startup script - -encoding option - no abbrevation
+    } -constraints {
+	stdio
+    } -setup {
+	set script [makeFile {} script]
+	file delete $script
+	set f [open $script w]
+	chan configure $f -encoding utf-8
+	puts $f {puts [list $argv0 $argv $tcl_interactive]}
+	puts -nonewline $f {puts [string equal \u20ac }
+	puts $f "\u20ac]"
+	close $f
+	catch {set f [open "|[list [interpreter] -enc utf-8 script]" r+]}
+    } -body {
+	type $f {
+	    puts $argv
+	}
+	list [catch {gets $f} line] $line
+    } -cleanup {
+	close $f
+	removeFile script
+    } -result {0 {-enc utf-8 script}}
+
+    # Tests Tcl_Main-2.*: application-initialization procedure
+
+    test Tcl_Main-2.1 {
+	Tcl_Main: appInitProc returns error
+    } -constraints {
+	exec Tcltest
+    } -setup {
+	makeFile {puts "In script"} script
+    } -body {
+	exec [interpreter] script -appinitprocerror >& result
+	set f [open result]
+	read $f
+    } -cleanup {
+	close $f
+	file delete result
+	removeFile script
+    } -result "application-specific initialization failed: \nIn script\n"
+
+    test Tcl_Main-2.2 {
+	Tcl_Main: appInitProc returns error
+    } -constraints {
+	exec Tcltest
+    } -body {
+	exec [interpreter] << {puts "In script"} -appinitprocerror >& result
+	set f [open result]
+	read $f
+    } -cleanup {
+	close $f
+	file delete result
+    } -result "application-specific initialization failed: \nIn script\n"
+
+    test Tcl_Main-2.3 {
+	Tcl_Main: appInitProc deletes interp
+    } -constraints {
+	exec Tcltest
+    } -setup {
+	makeFile {puts "In script"} script
+    } -body {
+	exec [interpreter] script -appinitprocdeleteinterp >& result
+	set f [open result]
+	read $f
+    } -cleanup {
+	close $f
+	file delete result
+	removeFile script
+    } -result "application-specific initialization failed: \n"
+
+    test Tcl_Main-2.4 {
+	Tcl_Main: appInitProc deletes interp
+    } -constraints {
+	exec Tcltest
+    } -body {
+	exec [interpreter] << {puts "In script"} \
+		-appinitprocdeleteinterp >& result
+	set f [open result]
+	read $f
+    } -cleanup {
+	close $f
+	file delete result
+    } -result "application-specific initialization failed: \n"
+
+    test Tcl_Main-2.5 {
+	Tcl_Main: appInitProc closes stderr
+    } -constraints {
+	exec Tcltest
+    } -body {
+	exec [interpreter] << {puts "In script"} \
+		-appinitprocclosestderr >& result
+	set f [open result]
+	read $f
+    } -cleanup {
+	close $f
+	file delete result
+    } -result "In script\n"
+
+    # Tests Tcl_Main-3.*: startup script evaluation
+
+    test Tcl_Main-3.1 {
+	Tcl_Main: startup script does not exist
+    } -constraints {
+	exec
+    } -setup {
+	if {[file exists no-such-file]} {
+	    error "Can't run test Tcl_Main-3.1\
+		    where a file named \"no-such-file\" exists"
+	}
+    } -body {
+	set code [catch {exec [interpreter] no-such-file >& result} result]
+	set f [open result]
+	list $code $result [read $f]
+    } -cleanup {
+	close $f
+	file delete result
+    } -match glob -result [list 1 {child process exited abnormally} \
+	{couldn't read file "no-such-file":*}]
+
+    test Tcl_Main-3.2 {
+	Tcl_Main: startup script raises error
+    } -constraints {
+	exec
+    } -setup {
+	makeFile {error ERROR} script
+    } -body {
+	set code [catch {exec [interpreter] script >& result} result]
+	set f [open result]
+	list $code $result [read $f]
+    } -cleanup {
+	close $f
+	file delete result
+	removeFile script
+    } -match glob -result [list 1 {child process exited abnormally} \
+	"ERROR\n    while executing*"]
+
+    test Tcl_Main-3.3 {
+	Tcl_Main: startup script closes stderr
+    } -constraints {
+	exec
+    } -setup {
+	makeFile {close stderr; error ERROR} script
+    } -body {
+	set code [catch {exec [interpreter] script >& result} result]
+	set f [open result]
+	list $code $result [read $f]
+    } -cleanup {
+	close $f
+	file delete result
+	removeFile script
+    } -result [list 1 {child process exited abnormally} {}]
+
+    test Tcl_Main-3.4 {
+	Tcl_Main: startup script holds incomplete script
+    } -constraints {
+	exec
+    } -setup {
+	makeFile "if 1 \{" script
+    } -body {
+	set code [catch {exec [interpreter] script >& result} result]
+	set f [open result]
+	join [list $code $result [read $f]] \n
+    } -cleanup {
+	close $f
+	file delete result
+	removeFile script
+    } -match glob -result [join [list 1 {child process exited abnormally}\
+	"missing close-brace\n    while executing*"] \n]
+
+    test Tcl_Main-3.5 {
+	Tcl_Main: startup script sets main loop
+    } -constraints {
+	exec Tcltest
+    } -setup {
+	makeFile {
+		rename exit _exit
+		proc exit {code} {
+		    puts "In exit"
+		    _exit $code
+		}
+		after 0 {
+			puts event
+			testexitmainloop
+		}
+		testexithandler create 0
+		testsetmainloop
+	} script
+    } -body {
+	exec [interpreter] script >& result
+	set f [open result]
+	read $f
+    } -cleanup {
+	close $f
+	file delete result
+	removeFile script
+    } -result "event\nExit MainLoop\nIn exit\neven 0\n"
+
+    test Tcl_Main-3.6 {
+	Tcl_Main: startup script sets main loop and closes stdin
+    } -constraints {
+	exec Tcltest
+    } -setup {
+	makeFile {
+		close stdin
+		testsetmainloop
+		rename exit _exit
+		proc exit {code} {
+		    puts "In exit"
+		    _exit $code
+		}
+		after 0 {
+			puts event
+			testexitmainloop
+		}
+		testexithandler create 0
+	} script
+    } -body {
+	exec [interpreter] script >& result
+	set f [open result]
+	read $f
+    } -cleanup {
+	close $f
+	file delete result
+	removeFile script
+    } -result "event\nExit MainLoop\nIn exit\neven 0\n"
+
+    test Tcl_Main-3.7 {
+	Tcl_Main: startup script deletes interp
+    } -constraints {
+	exec Tcltest
+    } -setup {
+	makeFile {
+		rename exit _exit
+		proc exit {code} {
+		    puts "In exit"
+		    _exit $code
+		}
+		testexithandler create 0
+		testinterpdelete {}
+	} script
+    } -body {
+	exec [interpreter] script >& result
+	set f [open result]
+	read $f
+    } -cleanup {
+	close $f
+	file delete result
+	removeFile script
+    } -result "even 0\n"
+
+    test Tcl_Main-3.8 {
+	Tcl_Main: startup script deletes interp and sets mainloop
+    } -constraints {
+	exec Tcltest
+    } -setup {
+	makeFile {
+		testsetmainloop
+		rename exit _exit
+		proc exit {code} {
+		    puts "In exit"
+		    _exit $code
+		}
+		testexitmainloop
+		testexithandler create 0
+		testinterpdelete {}
+	} script
+    } -body {
+	exec [interpreter] script >& result
+	set f [open result]
+	read $f
+    } -cleanup {
+	close $f
+	file delete result
+	removeFile script
+    } -result "Exit MainLoop\neven 0\n"
+
+    test Tcl_Main-3.9 {
+	Tcl_Main: startup script can set tcl_interactive without limit
+    } -constraints {
+	exec
+    } -setup {
+	makeFile {set tcl_interactive foo} script
+    } -body {
+	exec [interpreter] script >& result
+	set f [open result]
+	read $f
+    } -cleanup {
+	close $f
+	file delete result
+	removeFile script
+    } -result {}
+
+    # Tests Tcl_Main-4.*: rc file evaluation
+
+    test Tcl_Main-4.1 {
+	Tcl_Main: rcFile evaluation deletes interp
+    } -constraints {
+	exec Tcltest
+    } -setup {
+	set rc [makeFile {testinterpdelete {}} rc]
+    } -body {
+	exec [interpreter] << {puts "In script"} \
+		-appinitprocsetrcfile $rc >& result
+	set f [open result]
+	read $f
+    } -cleanup {
+	close $f
+	file delete result
+	removeFile rc
+    } -result "application-specific initialization failed: \n"
+
+    test Tcl_Main-4.2 {
+	Tcl_Main: rcFile evaluation closes stdin
+    } -constraints {
+	exec Tcltest
+    } -setup {
+	set rc [makeFile {close stdin} rc]
+    } -body {
+	exec [interpreter] << {puts "In script"} \
+		-appinitprocsetrcfile $rc >& result
+	set f [open result]
+	read $f
+    } -cleanup {
+	close $f
+	file delete result
+	removeFile rc
+    } -result "application-specific initialization failed: \n"
+
+    test Tcl_Main-4.3 {
+	Tcl_Main: rcFile evaluation closes stdin and sets main loop
+    } -constraints {
+	exec Tcltest
+    } -setup {
+	set rc [makeFile {
+		close stdin
+		testsetmainloop
+		after 0 testexitmainloop
+		testexithandler create 0
+		rename exit _exit
+		proc exit code {
+		    puts "In exit"
+		    _exit $code
+		}
+	} rc]
+    } -body {
+	exec [interpreter] << {puts "In script"} \
+		-appinitprocsetrcfile $rc >& result
+	set f [open result]
+	read $f
+    } -cleanup {
+	close $f
+	file delete result
+	removeFile rc
+    } -result "application-specific initialization failed:\
+	\nExit MainLoop\nIn exit\neven 0\n"
+
+    test Tcl_Main-4.4 {
+	Tcl_Main: rcFile evaluation sets main loop
+    } -constraints {
+	exec Tcltest
+    } -setup {
+	set rc [makeFile {
+		testsetmainloop
+		after 0 testexitmainloop
+		testexithandler create 0
+		rename exit _exit
+		proc exit code {
+		    puts "In exit"
+		    _exit $code
+		}
+	} rc]
+    } -body {
+	exec [interpreter] << {} \
+		-appinitprocsetrcfile $rc >& result
+	set f [open result]
+	read $f
+    } -cleanup {
+	close $f
+	file delete result
+	removeFile rc
+    } -result "application-specific initialization failed:\
+	\nExit MainLoop\nIn exit\neven 0\n"
+
+    test Tcl_Main-4.5 {
+        Tcl_Main: Bug 1481986
+    } -constraints {
+        exec Tcltest
+    } -setup {
+        set rc [makeFile {
+                testsetmainloop
+                after 0 {puts "Event callback"}
+        } rc]
+    } -body {
+        set f [open "|[list [interpreter] -appinitprocsetrcfile $rc]" w+]
+        after 1000
+        type $f {puts {Interactive output}
+            exit
+        }
+        read $f
+    } -cleanup {
+        catch {close $f}
+        removeFile rc
+    } -result "Event callback\nInteractive output\n"
+
+    # Tests Tcl_Main-5.*: interactive operations
+
+    test Tcl_Main-5.1 {
+	Tcl_Main: tcl_interactive must be boolean
+    } -constraints {
+	exec
+    } -body {
+	exec [interpreter] << {set tcl_interactive foo} >& result
+	set f [open result]
+	read $f
+    } -cleanup {
+	close $f
+	file delete result
+    } -result "can't set \"tcl_interactive\":\
+	     variable must have boolean value\n"
+
+    test Tcl_Main-5.2 {
+	Tcl_Main able to handle non-blocking stdin
+    } -constraints {
+	exec
+    } -setup {
+	catch {set f [open "|[list [interpreter]]" w+]}
+    } -body {
+	type $f {
+	    chan configure stdin -blocking 0
+	    puts SUCCESS
+	}
+	list [catch {gets $f} line] $line
+    } -cleanup {
+	close $f
+    } -result [list 0 SUCCESS]
+
+    test Tcl_Main-5.3 {
+	Tcl_Main handles stdin EOF in mid-command
+    } -constraints {
+	exec
+    } -setup {
+	catch {set f [open "|[list [interpreter]]" w+]}
+	catch {chan configure $f -blocking 0}
+    } -body {
+	type $f "chan configure stdin -eofchar \\032
+	    if 1 \{\n\032"
+	variable wait
+	chan event $f readable \
+		[list set [namespace which -variable wait] "child exit"]
+	set id [after 2000 [list set [namespace which -variable wait] timeout]]
+	vwait [namespace which -variable wait]
+	after cancel $id
+	set wait
+    } -cleanup {
+	if {$wait eq "timeout" && [testConstraint unix]} {
+	    exec kill [pid $f]
+	}
+	close $f
+    } -result {child exit}
+
+    test Tcl_Main-5.4 {
+	Tcl_Main handles stdin EOF in mid-command
+    } -constraints {
+	exec
+    } -setup {
+	set cmd {makeFile "if 1 \{" script}
+	catch {set f [open "|[list [interpreter]] < [list [eval $cmd]]" r]}
+	catch {chan configure $f -blocking 0}
+    } -body {
+	variable wait
+	chan event $f readable \
+		[list set [namespace which -variable wait] "child exit"]
+	set id [after 2000 [list set [namespace which -variable wait] timeout]]
+	vwait [namespace which -variable wait]
+	after cancel $id
+	set wait
+    } -cleanup {
+	if {$wait eq "timeout" && [testConstraint unix]} {
+	    exec kill [pid $f]
+	}
+	close $f
+	removeFile script
+    } -result {child exit}
+
+    test Tcl_Main-5.5 {
+	Tcl_Main: error raised in interactive mode
+    } -constraints {
+	exec
+    } -body {
+	exec [interpreter] << {error foo} >& result
+	set f [open result]
+	read $f
+    } -cleanup {
+	close $f
+	file delete result
+    } -result "foo\n"
+
+    test Tcl_Main-5.6 {
+	Tcl_Main: interactive mode: errors don't stop command loop
+    } -constraints {
+	exec
+    } -body {
+	exec [interpreter] << {
+		error foo
+		puts bar
+	} >& result
+	set f [open result]
+	read $f
+    } -cleanup {
+	close $f
+	file delete result
+    } -result "foo\nbar\n"
+
+    test Tcl_Main-5.7 {
+	Tcl_Main: interactive mode: closed stderr
+    } -constraints {
+	exec
+    } -body {
+	exec [interpreter] << {
+		close stderr
+		error foo
+		puts bar
+	} >& result
+	set f [open result]
+	read $f
+    } -cleanup {
+	close $f
+	file delete result
+    } -result "bar\n"
+
+    test Tcl_Main-5.8 {
+	Tcl_Main: interactive mode: close stdin
+		-> main loop & [exit] & exit handlers
+    } -constraints {
+	exec Tcltest
+    } -body {
+	exec [interpreter] << {
+		rename exit _exit
+		proc exit code {
+		    puts "In exit"
+		    _exit $code
+		}
+		testsetmainloop
+		testexitmainloop
+		testexithandler create 0
+		close stdin
+	} >& result
+	set f [open result]
+	read $f
+    } -cleanup {
+	close $f
+	file delete result
+    } -result "Exit MainLoop\nIn exit\neven 0\n"
+
+    test Tcl_Main-5.9 {
+	Tcl_Main: interactive mode: delete interp 
+		-> main loop & exit handlers, but no [exit]
+    } -constraints {
+	exec Tcltest
+    } -body {
+	exec [interpreter] << {
+		rename exit _exit
+		proc exit code {
+		    puts "In exit"
+		    _exit $code
+		}
+		testsetmainloop
+		testexitmainloop
+		testexithandler create 0
+		testinterpdelete {}
+	} >& result
+	set f [open result]
+	read $f
+    } -cleanup {
+	close $f
+	file delete result
+    } -result "Exit MainLoop\neven 0\n"
+
+    test Tcl_Main-5.10 {
+	Tcl_Main: exit main loop in mid-interactive command
+    } -constraints {
+	exec Tcltest
+    } -setup {
+	catch {set f [open "|[list [interpreter]]" w+]}
+	catch {chan configure $f -blocking 0}
+    } -body {
+	type $f "testsetmainloop
+	         after 2000 testexitmainloop
+	         puts \{1 2"
+	after 4000
+	type $f "3 4\}"
+	set code1 [catch {gets $f} line1]
+	set code2 [catch {gets $f} line2]
+	set code3 [catch {gets $f} line3]
+	list $code1 $line1 $code2 $line2 $code3 $line3
+    } -cleanup {
+	close $f
+    } -result [list 0 {Exit MainLoop} 0 {1 2} 0 {3 4}]
+
+    test Tcl_Main-5.11 {
+	Tcl_Main: EOF in interactive main loop
+    } -constraints {
+	exec Tcltest
+    } -body {
+	exec [interpreter] << {
+		rename exit _exit
+		proc exit code {
+		    puts "In exit"
+		    _exit $code
+		}
+		testexithandler create 0
+		after 0 testexitmainloop
+		testsetmainloop
+	} >& result
+	set f [open result]
+	read $f
+    } -cleanup {
+	close $f
+	file delete result
+    } -result "Exit MainLoop\nIn exit\neven 0\n"
+
+    test Tcl_Main-5.12 {
+	Tcl_Main: close stdin in interactive main loop
+    } -constraints {
+	exec Tcltest
+    } -body {
+	exec [interpreter] << {
+		rename exit _exit
+		proc exit code {
+		    puts "In exit"
+		    _exit $code
+		}
+		testexithandler create 0
+		after 100 testexitmainloop
+		testsetmainloop
+		close stdin
+		puts "don't reach this"
+	} >& result
+	set f [open result]
+	read $f
+    } -cleanup {
+	close $f
+	file delete result
+    } -result "Exit MainLoop\nIn exit\neven 0\n"
+
+    test Tcl_Main-5.13 {
+	Bug 1775878
+    } -constraints {
+	exec
+    } -setup {
+	catch {set f [open "|[list [interpreter]]" w+]}
+    } -body {
+	type $f "puts \\"
+	type $f return
+	list [catch {gets $f} line] $line
+    } -cleanup {
+	close $f
+    } -result [list 0 return]
+
+    # Tests Tcl_Main-6.*: interactive operations with prompts
+
+    test Tcl_Main-6.1 {
+	Tcl_Main: enable prompts with tcl_interactive
+    } -constraints {
+	exec
+    } -body {
+	exec [interpreter] << {set tcl_interactive 1} >& result
+	set f [open result]
+	read $f
+    } -cleanup {
+	close $f
+	file delete result
+    } -result "1\n% "
+
+    test Tcl_Main-6.2 {
+	Tcl_Main: prompt deletes interp
+    } -constraints {
+	exec Tcltest
+    } -body {
+	exec [interpreter] << {
+		set tcl_prompt1 {testinterpdelete {}}
+		set tcl_interactive 1
+		puts "not reached"
+	} >& result
+	set f [open result]
+	read $f
+    } -cleanup {
+	close $f
+	file delete result
+    } -result "1\n"
+
+    test Tcl_Main-6.3 {
+	Tcl_Main: prompt closes stdin
+    } -constraints {
+	exec
+    } -body {
+	exec [interpreter] << {
+		set tcl_prompt1 {close stdin}
+		set tcl_interactive 1
+		puts "not reached"
+	} >& result
+	set f [open result]
+	read $f
+    } -cleanup {
+	close $f
+	file delete result
+    } -result "1\n"
+
+    test Tcl_Main-6.4 {
+	Tcl_Main: interactive output, closed stdout
+    } -constraints {
+	exec
+    } -body {
+	exec [interpreter] << {
+		set tcl_interactive 1
+		close stdout
+		set a NO
+		puts stderr YES
+	} >& result
+	set f [open result]
+	read $f
+    } -cleanup {
+	close $f
+	file delete result
+    } -result "1\n% YES\n"
+
+    test Tcl_Main-6.5 {
+	Tcl_Main: interactive entry to main loop
+    } -constraints {
+	exec Tcltest
+    } -body {
+	exec [interpreter] << {
+		set tcl_interactive 1
+		testsetmainloop
+		testexitmainloop} >& result
+	set f [open result]
+	read $f
+    } -cleanup {
+	close $f
+	file delete result
+    } -result "1\n% % % Exit MainLoop\n"
+
+    test Tcl_Main-6.6 {
+	Tcl_Main: number of prompts during stdin close exit
+    } -constraints {
+	exec
+    } -body {
+	exec [interpreter] << {
+		set tcl_interactive 1
+		close stdin} >& result
+	set f [open result]
+	read $f
+    } -cleanup {
+	close $f
+	file delete result
+    } -result "1\n% "
+
+    test Tcl_Main-6.7 {
+	[unknown]: interactive auto-completion.
+    } -constraints {
+	exec
+    } -body {
+	exec [interpreter] << {
+		proc foo\{ x {}
+		set ::auto_noexec xxx
+		set tcl_interactive 1
+		foo y} >& result
+	set f [open result]
+	read $f
+    } -cleanup {
+	close $f
+	file delete result
+    } -result "1\n% % "
+
+    # Tests Tcl_Main-7.*: exiting
+
+    test Tcl_Main-7.1 {
+	Tcl_Main: [exit] defined as no-op -> still have exithandlers
+    } -constraints {
+	exec Tcltest
+    } -body {
+	exec [interpreter] << {
+		proc exit args {}
+		testexithandler create 0
+	} >& result
+	set f [open result]
+	read $f
+    } -cleanup {
+	close $f
+	file delete result
+    } -result "even 0\n"
+
+    test Tcl_Main-7.2 {
+	Tcl_Main: [exit] defined as no-op -> still have exithandlers
+    } -constraints {
+	exec Tcltest
+    } -body {
+	exec [interpreter] << {
+		proc exit args {}
+		testexithandler create 0
+		after 0 testexitmainloop
+		testsetmainloop
+	} >& result
+	set f [open result]
+	read $f
+    } -cleanup {
+	close $f
+	file delete result
+    } -result "Exit MainLoop\neven 0\n"
+
+    # Tests Tcl_Main-8.*: StdinProc operations
+
+    test Tcl_Main-8.1 {
+	StdinProc: handles non-blocking stdin
+    } -constraints {
+	exec Tcltest
+    } -body {
+	exec [interpreter] << {
+		testsetmainloop
+		chan configure stdin -blocking 0
+		testexitmainloop
+	} >& result
+	set f [open result]
+	read $f
+    } -cleanup {
+	close $f
+	file delete result
+    } -result "Exit MainLoop\n"
+
+    test Tcl_Main-8.2 {
+	StdinProc: handles stdin EOF
+    } -constraints {
+	exec Tcltest
+    } -body {
+	exec [interpreter] << {
+		testsetmainloop
+		testexithandler create 0
+		rename exit _exit
+		proc exit code {
+		    puts "In exit"
+		    _exit $code
+		}
+		after 100 testexitmainloop
+	} >& result
+	set f [open result]
+	read $f
+    } -cleanup {
+	close $f
+	file delete result
+    } -result "Exit MainLoop\nIn exit\neven 0\n"
+
+    test Tcl_Main-8.3 {
+	StdinProc: handles interactive stdin EOF
+    } -constraints {
+	exec Tcltest
+    } -body {
+	exec [interpreter] << {
+		testsetmainloop
+		testexithandler create 0
+		rename exit _exit
+		proc exit code {
+		    puts "In exit"
+		    _exit $code
+		}
+		set tcl_interactive 1} >& result
+	set f [open result]
+	read $f
+    } -cleanup {
+	close $f
+	file delete result
+    } -result "1\n% even 0\n"
+
+    test Tcl_Main-8.4 {
+	StdinProc: handles stdin close
+    } -constraints {
+	exec Tcltest
+    } -body {
+	exec [interpreter] << {
+		testsetmainloop
+		rename exit _exit
+		proc exit code {
+		    puts "In exit"
+		    _exit $code
+		}
+		after 100 testexitmainloop
+		after 0 puts 1
+		close stdin
+	} >& result
+	set f [open result]
+	read $f
+    } -cleanup {
+	close $f
+	file delete result
+    } -result "1\nExit MainLoop\nIn exit\n"
+
+    test Tcl_Main-8.5 {
+	StdinProc: handles interactive stdin close
+    } -constraints {
+	exec Tcltest
+    } -body {
+	exec [interpreter] << {
+		testsetmainloop
+		set tcl_interactive 1
+		rename exit _exit
+		proc exit code {
+		    puts "In exit"
+		    _exit $code
+		}
+		after 100 testexitmainloop
+		after 0 puts 1
+		close stdin
+	} >& result
+	set f [open result]
+	read $f
+    } -cleanup {
+	close $f
+	file delete result
+    } -result "1\n% % % after#0\n% after#1\n% 1\nExit MainLoop\nIn exit\n"
+
+    test Tcl_Main-8.6 {
+	StdinProc: handles event loop re-entry
+    } -constraints {
+	exec Tcltest
+    } -body {
+	exec [interpreter] << {
+		testsetmainloop
+		after 100 {puts 1; set delay 1}
+		vwait delay
+		puts 2
+		testexitmainloop
+	} >& result
+	set f [open result]
+	read $f
+    } -cleanup {
+	close $f
+	file delete result
+    } -result "1\n2\nExit MainLoop\n"
+
+    test Tcl_Main-8.7 {
+	StdinProc: handling of errors
+    } -constraints {
+	exec Tcltest
+    } -body {
+	exec [interpreter] << {
+		testsetmainloop
+		error foo
+		testexitmainloop
+	} >& result
+	set f [open result]
+	read $f
+    } -cleanup {
+	close $f
+	file delete result
+    } -result "foo\nExit MainLoop\n"
+
+    test Tcl_Main-8.8 {
+	StdinProc: handling of errors, closed stderr
+    } -constraints {
+	exec Tcltest
+    } -body {
+	exec [interpreter] << {
+		testsetmainloop
+		close stderr
+		error foo
+		testexitmainloop
+	} >& result
+	set f [open result]
+	read $f
+    } -cleanup {
+	close $f
+	file delete result
+    } -result "Exit MainLoop\n"
+
+    test Tcl_Main-8.9 {
+	StdinProc: interactive output
+    } -constraints {
+	exec Tcltest
+    } -body {
+	exec [interpreter] << {
+		testsetmainloop
+		set tcl_interactive 1
+		testexitmainloop} >& result
+	set f [open result]
+	read $f
+    } -cleanup {
+	close $f
+	file delete result
+    } -result "1\n% % Exit MainLoop\n"
+
+    test Tcl_Main-8.10 {
+	StdinProc: interactive output, closed stdout
+    } -constraints {
+	exec Tcltest
+    } -body {
+	exec [interpreter] << {
+		testsetmainloop
+		close stdout
+		set tcl_interactive 1
+		testexitmainloop
+	} >& result
+	set f [open result]
+	read $f
+    } -cleanup {
+	close $f
+	file delete result
+    } -result {}
+
+    test Tcl_Main-8.11 {
+	StdinProc: prompt deletes interp
+    } -constraints {
+	exec Tcltest
+    } -body {
+	exec [interpreter] << {
+		testsetmainloop
+		set tcl_prompt1 {testinterpdelete {}}
+		set tcl_interactive 1} >& result
+	set f [open result]
+	read $f
+    } -cleanup {
+	close $f
+	file delete result
+    } -result "1\n"
+
+    test Tcl_Main-8.12 {
+	StdinProc: prompt closes stdin
+    } -constraints {
+	exec Tcltest
+    } -body {
+	exec [interpreter] << {
+		testsetmainloop
+		set tcl_prompt1 {close stdin}
+		after 100 testexitmainloop
+		set tcl_interactive 1
+		puts "not reached"
+	} >& result
+	set f [open result]
+	read $f
+    } -cleanup {
+	close $f
+	file delete result
+    } -result "1\nExit MainLoop\n"
+
+    test Tcl_Main-8.13 {
+	Bug 1775878
+    } -constraints {
+	exec Tcltest
+    } -setup {
+	catch {set f [open "|[list [interpreter]]" w+]}
+    } -body {
+	exec [interpreter] << "testsetmainloop\nputs \\\npwd\ntestexitmainloop" >& result
+	set f [open result]
+	read $f
+    } -cleanup {
+	close $f
+	file delete result
+    } -result "pwd\nExit MainLoop\n"
+
+    # Tests Tcl_Main-9.*: Prompt operations
+
+    test Tcl_Main-9.1 {
+	Prompt: custom prompt variables
+    } -constraints {
+	exec
+    } -body {
+	exec [interpreter] << {
+		set tcl_prompt1 {puts -nonewline stdout "one "}
+		set tcl_prompt2 {puts -nonewline stdout "two "}
+		set tcl_interactive 1
+		puts {This is
+		a test}} >& result
+	set f [open result]
+	read $f
+    } -cleanup {
+	close $f
+	file delete result
+    } -result "1\none two This is\n\t\ta test\none "
+
+    test Tcl_Main-9.2 {
+	Prompt: error in custom prompt variables
+    } -constraints {
+	exec
+    } -body {
+	exec [interpreter] << {
+		set tcl_prompt1 {error foo}
+		set tcl_interactive 1
+		set errorInfo} >& result
+	set f [open result]
+	read $f
+    } -cleanup {
+	close $f
+	file delete result
+    } -result "1\nfoo\n% foo\n    while executing\n\"error foo\"\n    (script\
+	that generates prompt)\nfoo\n% "
+
+    test Tcl_Main-9.3 {
+	Prompt: error in custom prompt variables, closed stderr
+    } -constraints {
+	exec
+    } -body {
+	exec [interpreter] << {
+		set tcl_prompt1 {close stderr; error foo}
+		set tcl_interactive 1} >& result
+	set f [open result]
+	read $f
+    } -cleanup {
+	close $f
+	file delete result
+    } -result "1\n% "
+
+    test Tcl_Main-9.4 {
+	Prompt: error in custom prompt variables, closed stdout
+    } -constraints {
+	exec
+    } -body {
+	exec [interpreter] << {
+		set tcl_prompt1 {close stdout; error foo}
+		set tcl_interactive 1} >& result
+	set f [open result]
+	read $f
+    } -cleanup {
+	close $f
+	file delete result
+    } -result "1\nfoo\n"
+
+    cd [workingDirectory]
+
+    cleanupTests
+}
+
+namespace delete ::tcl::test::main
+return
diff --git a/tests/mathop.test b/tests/mathop.test
new file mode 100644
index 0000000..f122b7b
--- /dev/null
+++ b/tests/mathop.test
@@ -0,0 +1,1340 @@
+# Commands covered: ::tcl::mathop::...
+#
+# This file contains a collection of tests for one or more of the Tcl built-in
+# commands. Sourcing this file into Tcl runs the tests and generates output
+# for errors. No output means no errors were found.
+#
+# Copyright (c) 2006 Donal K. Fellows
+# Copyright (c) 2006 Peter Spjuth
+#
+# See the file "license.terms" for information on usage and redistribution of
+# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+    package require tcltest 2.1
+    namespace import -force ::tcltest::*
+}
+
+# A namespace to test that operators are exported and that they
+# work when imported
+namespace eval ::testmathop2 {
+    namespace import ::tcl::mathop::*
+}
+
+# Helper to test math ops.
+# Test different invokation variants and see that they do the same thing.
+# Byte compiled / non byte compiled version
+# Shared / unshared arguments
+# Original / imported
+proc TestOp {op args} {
+    set results {}
+
+    # Non byte compiled version, shared args
+    if {[catch {::tcl::mathop::$op {*}$args} res]} {
+        append res " $::errorCode"
+    }
+    lappend results $res
+
+    # Non byte compiled version, unshared args
+    set cmd ::tcl::mathop::\$op
+    foreach arg $args {
+        append cmd " \[format %s [list $arg]\]"
+    }
+    if {[catch $cmd res]} {
+        append res " $::errorCode"
+    }
+    lappend results $res
+
+    # Non byte compiled imported
+    if {[catch {::testmathop2::$op {*}$args} res]} {
+        append res " $::errorCode"
+    }
+    lappend results [string map {testmathop2 tcl::mathop} $res]
+
+    # BC version
+    set argList1 {}
+    set argList2 {}
+    set argList3 {}
+    for {set t 0} {$t < [llength $args]} {incr t} {
+        lappend argList1 a$t
+        lappend argList2 \$a$t
+        lappend argList3 "\[format %s \$a$t\]"
+    }
+    # Shared args
+    proc _TestOp  $argList1 "::tcl::mathop::$op [join $argList2]"
+    # Unshared args
+    proc _TestOp2 $argList1 "::tcl::mathop::$op [join $argList3]"
+    # Imported
+    proc _TestOp3 $argList1 "::testmathop2::$op [join $argList2]"
+
+    set ::tcl_traceCompile 0  ;# Set to 2 to help with debug
+    if {[catch {_TestOp {*}$args} res]} {
+        append res " $::errorCode"
+    }
+    set ::tcl_traceCompile 0
+    lappend results $res
+
+    if {[catch {_TestOp2 {*}$args} res]} {
+        append res " $::errorCode"
+    }
+    lappend results $res
+
+    if {[catch {_TestOp3 {*}$args} res]} {
+        append res " $::errorCode"
+    }
+    lappend results [string map {testmathop2 tcl::mathop} $res]
+
+    # Check that they do the same
+    set len [llength $results]
+    for {set i 0} {$i < ($len - 1)} {incr i} {
+        set res1 [lindex $results $i]
+        set res2 [lindex $results $i+1]
+        if {$res1 ne $res2} {
+            return "$i:($res1 != $res2)"
+        }
+    }
+    return [lindex $results 0]
+}
+
+# start of tests
+
+namespace eval ::testmathop {
+    namespace path ::tcl::mathop
+    variable op ;# stop surprises!
+
+    test mathop-1.1 {compiled +} { + } 0
+    test mathop-1.2 {compiled +} { + 1 } 1
+    test mathop-1.3 {compiled +} { + 1 2 } 3
+    test mathop-1.4 {compiled +} { + 1 2 3 } 6
+    test mathop-1.5 {compiled +} { + 1.0 2 3 } 6.0
+    test mathop-1.6 {compiled +} { + 1 2 3.0 } 6.0
+    test mathop-1.7 {compiled +} { + 100000000000 2 3 } 100000000005
+    test mathop-1.8 {compiled +} { + 1 2 300000000000 } 300000000003
+    test mathop-1.9 {compiled +} { + 1000000000000000000000 2 3 } 1000000000000000000005
+    test mathop-1.10 {compiled +} { + 1 2 3000000000000000000000 } 3000000000000000000003
+    test mathop-1.11 {compiled +: errors} -returnCodes error -body {
+	+ x 0
+    } -result {can't use non-numeric string as operand of "+"}
+    test mathop-1.12 {compiled +: errors} -returnCodes error -body {
+	+ nan 0
+    } -result {can't use non-numeric floating-point value as operand of "+"}
+    test mathop-1.13 {compiled +: errors} -returnCodes error -body {
+	+ 0 x
+    } -result {can't use non-numeric string as operand of "+"}
+    test mathop-1.14 {compiled +: errors} -returnCodes error -body {
+	+ 0 nan
+    } -result {can't use non-numeric floating-point value as operand of "+"}
+    test mathop-1.15 {compiled +: errors} -returnCodes error -body {
+	+ 0o8 0
+    } -result {can't use invalid octal number as operand of "+"}
+    test mathop-1.16 {compiled +: errors} -returnCodes error -body {
+	+ 0 0o8
+    } -result {can't use invalid octal number as operand of "+"}
+    test mathop-1.17 {compiled +: errors} -returnCodes error -body {
+	+ 0 [error expectedError]
+    } -result expectedError
+    test mathop-1.18 {compiled +: argument processing order} -body {
+	# Bytecode compilation known hard for 3+ arguments
+	list [catch {
+	    + [set x 0] [incr x] NaN [incr x] [error expected] [incr x]
+	} msg] $msg $x
+    } -result {1 expected 2}
+    set op +
+    test mathop-1.19 {interpreted +} { $op } 0
+    test mathop-1.20 {interpreted +} { $op 1 } 1
+    test mathop-1.21 {interpreted +} { $op 1 2 } 3
+    test mathop-1.22 {interpreted +} { $op 1 2 3 } 6
+    test mathop-1.23 {interpreted +} { $op 1.0 2 3 } 6.0
+    test mathop-1.24 {interpreted +} { $op 1 2 3.0 } 6.0
+    test mathop-1.25 {interpreted +} { $op 100000000000 2 3 } 100000000005
+    test mathop-1.26 {interpreted +} { $op 1 2 300000000000 } 300000000003
+    test mathop-1.27 {interpreted +} { $op 1000000000000000000000 2 3 } 1000000000000000000005
+    test mathop-1.28 {interpreted +} { $op 1 2 3000000000000000000000 } 3000000000000000000003
+    test mathop-1.29 {interpreted +: errors} -returnCodes error -body {
+	$op x 0
+    } -result {can't use non-numeric string as operand of "+"}
+    test mathop-1.30 {interpreted +: errors} -returnCodes error -body {
+	$op nan 0
+    } -result {can't use non-numeric floating-point value as operand of "+"}
+    test mathop-1.31 {interpreted +: errors} -returnCodes error -body {
+	$op 0 x
+    } -result {can't use non-numeric string as operand of "+"}
+    test mathop-1.32 {interpreted +: errors} -returnCodes error -body {
+	$op 0 nan
+    } -result {can't use non-numeric floating-point value as operand of "+"}
+    test mathop-1.33 {interpreted +: errors} -returnCodes error -body {
+	$op 0o8 0
+    } -result {can't use invalid octal number as operand of "+"}
+    test mathop-1.34 {interpreted +: errors} -returnCodes error -body {
+	$op 0 0o8
+    } -result {can't use invalid octal number as operand of "+"}
+    test mathop-1.35 {interpreted +: errors} -returnCodes error -body {
+	$op 0 [error expectedError]
+    } -result expectedError
+    test mathop-1.36 {interpreted +: argument processing order} -body {
+	list [catch {
+	    $op [set x 0] [incr x] NaN [incr x] [error expected] [incr x]
+	} msg] $msg $x
+    } -result {1 expected 2}
+
+    test mathop-2.1 {compiled *} { * } 1
+    test mathop-2.2 {compiled *} { * 2 } 2
+    test mathop-2.3 {compiled *} { * 2 3 } 6
+    test mathop-2.4 {compiled *} { * 2 3 4 } 24
+    test mathop-2.5 {compiled *} { * 1.0 2 3 } 6.0
+    test mathop-2.6 {compiled *} { * 1 2 3.0 } 6.0
+    test mathop-2.7 {compiled *} { * 100000000000 2 3 } 600000000000
+    test mathop-2.8 {compiled *} { * 1 2 300000000000 } 600000000000
+    test mathop-2.9 {compiled *} { * 1000000000000000000000 2 3 } 6000000000000000000000
+    test mathop-2.10 {compiled *} { * 1 2 3000000000000000000000 } 6000000000000000000000
+    test mathop-2.11 {compiled *: errors} -returnCodes error -body {
+	* x 0
+    } -result {can't use non-numeric string as operand of "*"}
+    test mathop-2.12 {compiled *: errors} -returnCodes error -body {
+	* nan 0
+    } -result {can't use non-numeric floating-point value as operand of "*"}
+    test mathop-2.13 {compiled *: errors} -returnCodes error -body {
+	* 0 x
+    } -result {can't use non-numeric string as operand of "*"}
+    test mathop-2.14 {compiled *: errors} -returnCodes error -body {
+	* 0 nan
+    } -result {can't use non-numeric floating-point value as operand of "*"}
+    test mathop-2.15 {compiled *: errors} -returnCodes error -body {
+	* 0o8 0
+    } -result {can't use invalid octal number as operand of "*"}
+    test mathop-2.16 {compiled *: errors} -returnCodes error -body {
+	* 0 0o8
+    } -result {can't use invalid octal number as operand of "*"}
+    test mathop-2.17 {compiled *: errors} -returnCodes error -body {
+	* 0 [error expectedError]
+    } -result expectedError
+    test mathop-2.18 {compiled *: argument processing order} -body {
+	# Bytecode compilation known hard for 3+ arguments
+	list [catch {
+	    * [set x 0] [incr x] NaN [incr x] [error expected] [incr x]
+	} msg] $msg $x
+    } -result {1 expected 2}
+    set op *
+    test mathop-2.19 {interpreted *} { $op } 1
+    test mathop-2.20 {interpreted *} { $op 2 } 2
+    test mathop-2.21 {interpreted *} { $op 2 3 } 6
+    test mathop-2.22 {interpreted *} { $op 2 3 4 } 24
+    test mathop-2.23 {interpreted *} { $op 1.0 2 3 } 6.0
+    test mathop-2.24 {interpreted *} { $op 1 2 3.0 } 6.0
+    test mathop-2.25 {interpreted *} { $op 100000000000 2 3 } 600000000000
+    test mathop-2.26 {interpreted *} { $op 1 2 300000000000 } 600000000000
+    test mathop-2.27 {interpreted *} { $op 1000000000000000000000 2 3 } 6000000000000000000000
+    test mathop-2.28 {interpreted *} { $op 1 2 3000000000000000000000 } 6000000000000000000000
+    test mathop-2.29 {interpreted *: errors} -returnCodes error -body {
+	$op x 0
+    } -result {can't use non-numeric string as operand of "*"}
+    test mathop-2.30 {interpreted *: errors} -returnCodes error -body {
+	$op nan 0
+    } -result {can't use non-numeric floating-point value as operand of "*"}
+    test mathop-2.31 {interpreted *: errors} -returnCodes error -body {
+	$op 0 x
+    } -result {can't use non-numeric string as operand of "*"}
+    test mathop-2.32 {interpreted *: errors} -returnCodes error -body {
+	$op 0 nan
+    } -result {can't use non-numeric floating-point value as operand of "*"}
+    test mathop-2.33 {interpreted *: errors} -returnCodes error -body {
+	$op 0o8 0
+    } -result {can't use invalid octal number as operand of "*"}
+    test mathop-2.34 {interpreted *: errors} -returnCodes error -body {
+	$op 0 0o8
+    } -result {can't use invalid octal number as operand of "*"}
+    test mathop-2.35 {interpreted *: errors} -returnCodes error -body {
+	$op 0 [error expectedError]
+    } -result expectedError
+    test mathop-2.36 {interpreted *: argument processing order} -body {
+	list [catch {
+	    $op [set x 0] [incr x] NaN [incr x] [error expected] [incr x]
+	} msg] $msg $x
+    } -result {1 expected 2}
+
+    test mathop-3.1 {compiled !} {! 0} 1
+    test mathop-3.2 {compiled !} {! 1} 0
+    test mathop-3.3 {compiled !} {! false} 1
+    test mathop-3.4 {compiled !} {! true} 0
+    test mathop-3.5 {compiled !} {! 0.0} 1
+    test mathop-3.6 {compiled !} {! 10000000000} 0
+    test mathop-3.7 {compiled !} {! 10000000000000000000000000} 0
+    test mathop-3.8 {compiled !: errors} -body {
+	! foobar
+    } -returnCodes error -result {can't use non-numeric string as operand of "!"}
+    test mathop-3.9 {compiled !: errors} -body {
+	! 0 0
+    } -returnCodes error -result "wrong # args: should be \"! boolean\""
+    test mathop-3.10 {compiled !: errors} -body {
+	!
+    } -returnCodes error -result "wrong # args: should be \"! boolean\""
+    set op !
+    test mathop-3.11 {interpreted !} {$op 0} 1
+    test mathop-3.12 {interpreted !} {$op 1} 0
+    test mathop-3.13 {interpreted !} {$op false} 1
+    test mathop-3.14 {interpreted !} {$op true} 0
+    test mathop-3.15 {interpreted !} {$op 0.0} 1
+    test mathop-3.16 {interpreted !} {$op 10000000000} 0
+    test mathop-3.17 {interpreted !} {$op 10000000000000000000000000} 0
+    test mathop-3.18 {interpreted !: errors} -body {
+	$op foobar
+    } -returnCodes error -result {can't use non-numeric string as operand of "!"}
+    test mathop-3.19 {interpreted !: errors} -body {
+	$op 0 0
+    } -returnCodes error -result "wrong # args: should be \"! boolean\""
+    test mathop-3.20 {interpreted !: errors} -body {
+	$op
+    } -returnCodes error -result "wrong # args: should be \"! boolean\""
+    test mathop-3.21 {compiled !: error} -returnCodes error -body {
+	! NaN
+    } -result {can't use non-numeric floating-point value as operand of "!"}
+    test mathop-3.22 {interpreted !: error} -returnCodes error -body {
+	$op NaN
+    } -result {can't use non-numeric floating-point value as operand of "!"}
+
+    test mathop-4.1 {compiled ~} {~ 0} -1
+    test mathop-4.2 {compiled ~} {~ 1} -2
+    test mathop-4.3 {compiled ~} {~ 31} -32
+    test mathop-4.4 {compiled ~} {~ -127} 126
+    test mathop-4.5 {compiled ~} {~ -0} -1
+    test mathop-4.6 {compiled ~} {~ 10000000000} -10000000001
+    test mathop-4.7 {compiled ~} {~ 10000000000000000000000000} -10000000000000000000000001
+    test mathop-4.8 {compiled ~: errors} -body {
+	~ foobar
+    } -returnCodes error -result {can't use non-numeric string as operand of "~"}
+    test mathop-4.9 {compiled ~: errors} -body {
+	~ 0 0
+    } -returnCodes error -result "wrong # args: should be \"~ integer\""
+    test mathop-4.10 {compiled ~: errors} -body {
+	~
+    } -returnCodes error -result "wrong # args: should be \"~ integer\""
+    test mathop-4.11 {compiled ~: errors} -returnCodes error -body {
+	~ 0.0
+    } -result {can't use floating-point value as operand of "~"}
+    test mathop-4.12 {compiled ~: errors} -returnCodes error -body {
+	~ NaN
+    } -result {can't use non-numeric floating-point value as operand of "~"}
+    set op ~
+    test mathop-4.13 {interpreted ~} {$op 0} -1
+    test mathop-4.14 {interpreted ~} {$op 1} -2
+    test mathop-4.15 {interpreted ~} {$op 31} -32
+    test mathop-4.16 {interpreted ~} {$op -127} 126
+    test mathop-4.17 {interpreted ~} {$op -0} -1
+    test mathop-4.18 {interpreted ~} {$op 10000000000} -10000000001
+    test mathop-4.19 {interpreted ~} {$op 10000000000000000000000000} -10000000000000000000000001
+    test mathop-4.20 {interpreted ~: errors} -body {
+	$op foobar
+    } -returnCodes error -result {can't use non-numeric string as operand of "~"}
+    test mathop-4.21 {interpreted ~: errors} -body {
+	$op 0 0
+    } -returnCodes error -result "wrong # args: should be \"~ integer\""
+    test mathop-4.22 {interpreted ~: errors} -body {
+	$op
+    } -returnCodes error -result "wrong # args: should be \"~ integer\""
+    test mathop-4.23 {interpreted ~: errors} -returnCodes error -body {
+	$op 0.0
+    } -result {can't use floating-point value as operand of "~"}
+    test mathop-4.24 {interpreted ~: errors} -returnCodes error -body {
+	$op NaN
+    } -result {can't use non-numeric floating-point value as operand of "~"}
+
+    test mathop-5.1 {compiled eq} {eq {} a} 0
+    test mathop-5.2 {compiled eq} {eq a a} 1
+    test mathop-5.3 {compiled eq} {eq a {}} 0
+    test mathop-5.4 {compiled eq} {eq a b} 0
+    test mathop-5.5 {compiled eq} { eq } 1
+    test mathop-5.6 {compiled eq} {eq a} 1
+    test mathop-5.7 {compiled eq} {eq a a a} 1
+    test mathop-5.8 {compiled eq} {eq a a b} 0
+    test mathop-5.9 {compiled eq} -body {
+	eq a b [error foobar]
+    } -returnCodes error -result foobar
+    test mathop-5.10 {compiled eq} {eq NaN Na NaN} 0
+    set op eq
+    test mathop-5.11 {interpreted eq} {$op {} a} 0
+    test mathop-5.12 {interpreted eq} {$op a a} 1
+    test mathop-5.13 {interpreted eq} {$op a {}} 0
+    test mathop-5.14 {interpreted eq} {$op a b} 0
+    test mathop-5.15 {interpreted eq} { $op } 1
+    test mathop-5.16 {interpreted eq} {$op a} 1
+    test mathop-5.17 {interpreted eq} {$op a a a} 1
+    test mathop-5.18 {interpreted eq} {$op a a b} 0
+    test mathop-5.19 {interpreted eq} -body {
+	$op a b [error foobar]
+    } -returnCodes error -result foobar
+    test mathop-5.20 {interpreted eq} {$op NaN Na NaN} 0
+
+    variable big1      12135435435354435435342423948763867876
+    variable big2       2746237174783836746262564892918327847
+    variable wide1                             12345678912345
+    variable wide2                             87321847232215
+    variable small1                                     87345
+    variable small2                                     16753
+
+    test mathop-6.1 {compiled &} { & } -1
+    test mathop-6.2 {compiled &} { & 1 } 1
+    test mathop-6.3 {compiled &} { & 1 2 } 0
+    test mathop-6.4 {compiled &} { & 3 7 6 } 2
+    test mathop-6.5 {compiled &} -returnCodes error -body {
+	& 1.0 2 3
+    } -result {can't use floating-point value as operand of "&"}
+    test mathop-6.6 {compiled &} -returnCodes error -body {
+	& 1 2 3.0
+    } -result {can't use floating-point value as operand of "&"}
+    test mathop-6.7 {compiled &} { & 100000000002 18 -126 } 2
+    test mathop-6.8 {compiled &} { & 0xff 0o377 333333333333 } 85
+    test mathop-6.9 {compiled &} { & 1000000000000000000002 18 -126 } 2
+    test mathop-6.10 {compiled &} { & 0xff 0o377 3333333333333333333333 } 85
+    test mathop-6.11 {compiled &: errors} -returnCodes error -body {
+	& x 0
+    } -result {can't use non-numeric string as operand of "&"}
+    test mathop-6.12 {compiled &: errors} -returnCodes error -body {
+	& nan 0
+    } -result {can't use non-numeric floating-point value as operand of "&"}
+    test mathop-6.13 {compiled &: errors} -returnCodes error -body {
+	& 0 x
+    } -result {can't use non-numeric string as operand of "&"}
+    test mathop-6.14 {compiled &: errors} -returnCodes error -body {
+	& 0 nan
+    } -result {can't use non-numeric floating-point value as operand of "&"}
+    test mathop-6.15 {compiled &: errors} -returnCodes error -body {
+	& 0o8 0
+    } -result {can't use invalid octal number as operand of "&"}
+    test mathop-6.16 {compiled &: errors} -returnCodes error -body {
+	& 0 0o8
+    } -result {can't use invalid octal number as operand of "&"}
+    test mathop-6.17 {compiled &: errors} -returnCodes error -body {
+	& 0 [error expectedError]
+    } -result expectedError
+    test mathop-6.18 {compiled &: argument processing order} -body {
+	# Bytecode compilation known hard for 3+ arguments
+	list [catch {
+	    & [set x 0] [incr x] NaN [incr x] [error expected] [incr x]
+	} msg] $msg $x
+    } -result {1 expected 2}
+    set op &
+    test mathop-6.19 {interpreted &} { $op } -1
+    test mathop-6.20 {interpreted &} { $op 1 } 1
+    test mathop-6.21 {interpreted &} { $op 1 2 } 0
+    test mathop-6.22 {interpreted &} { $op 3 7 6 } 2
+    test mathop-6.23 {interpreted &} -returnCodes error -body {
+	$op 1.0 2 3
+    } -result {can't use floating-point value as operand of "&"}
+    test mathop-6.24 {interpreted &} -returnCodes error -body {
+	$op 1 2 3.0
+    } -result {can't use floating-point value as operand of "&"}
+    test mathop-6.25 {interpreted &} { $op 100000000002 18 -126 } 2
+    test mathop-6.26 {interpreted &} { $op 0xff 0o377 333333333333 } 85
+    test mathop-6.27 {interpreted &} { $op 1000000000000000000002 18 -126 } 2
+    test mathop-6.28 {interpreted &} { $op 0xff 0o377 3333333333333333333333 } 85
+    test mathop-6.29 {interpreted &: errors} -returnCodes error -body {
+	$op x 0
+    } -result {can't use non-numeric string as operand of "&"}
+    test mathop-6.30 {interpreted &: errors} -returnCodes error -body {
+	$op nan 0
+    } -result {can't use non-numeric floating-point value as operand of "&"}
+    test mathop-6.31 {interpreted &: errors} -returnCodes error -body {
+	$op 0 x
+    } -result {can't use non-numeric string as operand of "&"}
+    test mathop-6.32 {interpreted &: errors} -returnCodes error -body {
+	$op 0 nan
+    } -result {can't use non-numeric floating-point value as operand of "&"}
+    test mathop-6.33 {interpreted &: errors} -returnCodes error -body {
+	$op 0o8 0
+    } -result {can't use invalid octal number as operand of "&"}
+    test mathop-6.34 {interpreted &: errors} -returnCodes error -body {
+	$op 0 0o8
+    } -result {can't use invalid octal number as operand of "&"}
+    test mathop-6.35 {interpreted &: errors} -returnCodes error -body {
+	$op 0 [error expectedError]
+    } -result expectedError
+    test mathop-6.36 {interpreted &: argument processing order} -body {
+	list [catch {
+	    $op [set x 0] [incr x] NaN [incr x] [error expected] [incr x]
+	} msg] $msg $x
+    } -result {1 expected 2}
+    test mathop-6.37 {& and bignums} {
+	list [& $big1 $big2] [$op $big1 $big2]
+    } {712439449294653815890598856501796 712439449294653815890598856501796}
+    test mathop-6.38 {& and bignums} {
+	list [& $big1 $wide2] [$op $big1 $wide2]
+    } {78521450111684 78521450111684}
+    test mathop-6.39 {& and bignums} {
+	list [& $big1 $small2] [$op $big1 $small2]
+    } {96 96}
+    test mathop-6.40 {& and bignums} {
+	list [& $wide1 $big2] [$op $wide1 $big2]
+    } {2371422390785 2371422390785}
+    test mathop-6.41 {& and bignums} {
+	list [& $wide1 $wide2] [$op $wide1 $wide2]
+    } {12275881497169 12275881497169}
+    test mathop-6.42 {& and bignums} {
+	list [& $wide1 $small2] [$op $wide1 $small2]
+    } {16721 16721}
+    test mathop-6.43 {& and bignums} {
+	list [& $small1 $big2] [$op $small1 $big2]
+    } {33 33}
+    test mathop-6.44 {& and bignums} {
+	list [& $small1 $wide2] [$op $small1 $wide2]
+    } {87057 87057}
+    test mathop-6.45 {& and bignums} {
+	list [& $small1 $small2] [$op $small1 $small2]
+    } {16689 16689}
+
+    test mathop-7.1 {compiled |} { | } 0
+    test mathop-7.2 {compiled |} { | 1 } 1
+    test mathop-7.3 {compiled |} { | 1 2 } 3
+    test mathop-7.4 {compiled |} { | 3 7 6 } 7
+    test mathop-7.5 {compiled |} -returnCodes error -body {
+	| 1.0 2 3
+    } -result {can't use floating-point value as operand of "|"}
+    test mathop-7.6 {compiled |} -returnCodes error -body {
+	| 1 2 3.0
+    } -result {can't use floating-point value as operand of "|"}
+    test mathop-7.7 {compiled |} { | 100000000002 18 -126 } -110
+    test mathop-7.8 {compiled |} { | 0xff 0o377 333333333333 } 333333333503
+    test mathop-7.9 {compiled |} { | 1000000000000000000002 18 -126 } -110
+    test mathop-7.10 {compiled |} { | 0xff 0o377 3333333333333333333333 } 3333333333333333333503
+    test mathop-7.11 {compiled |: errors} -returnCodes error -body {
+	| x 0
+    } -result {can't use non-numeric string as operand of "|"}
+    test mathop-7.12 {compiled |: errors} -returnCodes error -body {
+	| nan 0
+    } -result {can't use non-numeric floating-point value as operand of "|"}
+    test mathop-7.13 {compiled |: errors} -returnCodes error -body {
+	| 0 x
+    } -result {can't use non-numeric string as operand of "|"}
+    test mathop-7.14 {compiled |: errors} -returnCodes error -body {
+	| 0 nan
+    } -result {can't use non-numeric floating-point value as operand of "|"}
+    test mathop-7.15 {compiled |: errors} -returnCodes error -body {
+	| 0o8 0
+    } -result {can't use invalid octal number as operand of "|"}
+    test mathop-7.16 {compiled |: errors} -returnCodes error -body {
+	| 0 0o8
+    } -result {can't use invalid octal number as operand of "|"}
+    test mathop-7.17 {compiled |: errors} -returnCodes error -body {
+	| 0 [error expectedError]
+    } -result expectedError
+    test mathop-7.18 {compiled |: argument processing order} -body {
+	# Bytecode compilation known hard for 3+ arguments
+	list [catch {
+	    | [set x 0] [incr x] NaN [incr x] [error expected] [incr x]
+	} msg] $msg $x
+    } -result {1 expected 2}
+    set op |
+    test mathop-7.19 {interpreted |} { $op } 0
+    test mathop-7.20 {interpreted |} { $op 1 } 1
+    test mathop-7.21 {interpreted |} { $op 1 2 } 3
+    test mathop-7.22 {interpreted |} { $op 3 7 6 } 7
+    test mathop-7.23 {interpreted |} -returnCodes error -body {
+	$op 1.0 2 3
+    } -result {can't use floating-point value as operand of "|"}
+    test mathop-7.24 {interpreted |} -returnCodes error -body {
+	$op 1 2 3.0
+    } -result {can't use floating-point value as operand of "|"}
+    test mathop-7.25 {interpreted |} { $op 100000000002 18 -126 } -110
+    test mathop-7.26 {interpreted |} { $op 0xff 0o377 333333333333 } 333333333503
+    test mathop-7.27 {interpreted |} { $op 1000000000000000000002 18 -126 } -110
+    test mathop-7.28 {interpreted |} { $op 0xff 0o377 3333333333333333333333 } 3333333333333333333503
+    test mathop-7.29 {interpreted |: errors} -returnCodes error -body {
+	$op x 0
+    } -result {can't use non-numeric string as operand of "|"}
+    test mathop-7.30 {interpreted |: errors} -returnCodes error -body {
+	$op nan 0
+    } -result {can't use non-numeric floating-point value as operand of "|"}
+    test mathop-7.31 {interpreted |: errors} -returnCodes error -body {
+	$op 0 x
+    } -result {can't use non-numeric string as operand of "|"}
+    test mathop-7.32 {interpreted |: errors} -returnCodes error -body {
+	$op 0 nan
+    } -result {can't use non-numeric floating-point value as operand of "|"}
+    test mathop-7.33 {interpreted |: errors} -returnCodes error -body {
+	$op 0o8 0
+    } -result {can't use invalid octal number as operand of "|"}
+    test mathop-7.34 {interpreted |: errors} -returnCodes error -body {
+	$op 0 0o8
+    } -result {can't use invalid octal number as operand of "|"}
+    test mathop-7.35 {interpreted |: errors} -returnCodes error -body {
+	$op 0 [error expectedError]
+    } -result expectedError
+    test mathop-7.36 {interpreted |: argument processing order} -body {
+	list [catch {
+	    $op [set x 0] [incr x] NaN [incr x] [error expected] [incr x]
+	} msg] $msg $x
+    } -result {1 expected 2}
+    test mathop-7.37 {| and bignums} {
+	list [| $big1 $big2] [$op $big1 $big2]
+    } {14880960170688977527789098242825693927 14880960170688977527789098242825693927}
+    test mathop-7.38 {| and bignums} {
+	list [| $big1 $wide2] [$op $big1 $wide2]
+    } {12135435435354435435342432749160988407 12135435435354435435342432749160988407}
+    test mathop-7.39 {| and bignums} {
+	list [| $big1 $small2] [$op $big1 $small2]
+    } {12135435435354435435342423948763884533 12135435435354435435342423948763884533}
+    test mathop-7.40 {| and bignums} {
+	list [| $wide1 $big2] [$op $wide1 $big2]
+    } {2746237174783836746262574867174849407 2746237174783836746262574867174849407}
+    test mathop-7.41 {| and bignums} {
+	list [| $wide1 $wide2] [$op $wide1 $wide2]
+    } {87391644647391 87391644647391}
+    test mathop-7.42 {| and bignums} {
+	list [| $wide1 $small2] [$op $wide1 $small2]
+    } {12345678912377 12345678912377}
+    test mathop-7.43 {| and bignums} {
+	list [| $small1 $big2] [$op $small1 $big2]
+    } {2746237174783836746262564892918415159 2746237174783836746262564892918415159}
+    test mathop-7.44 {| and bignums} {
+	list [| $small1 $wide2] [$op $small1 $wide2]
+    } {87321847232503 87321847232503}
+    test mathop-7.45 {| and bignums} {
+	list [| $small1 $small2] [$op $small1 $small2]
+    } {87409 87409}
+
+    test mathop-8.1 {compiled ^} { ^ } 0
+    test mathop-8.2 {compiled ^} { ^ 1 } 1
+    test mathop-8.3 {compiled ^} { ^ 1 2 } 3
+    test mathop-8.4 {compiled ^} { ^ 3 7 6 } 2
+    test mathop-8.5 {compiled ^} -returnCodes error -body {
+	^ 1.0 2 3
+    } -result {can't use floating-point value as operand of "^"}
+    test mathop-8.6 {compiled ^} -returnCodes error -body {
+	^ 1 2 3.0
+    } -result {can't use floating-point value as operand of "^"}
+    test mathop-8.7 {compiled ^} { ^ 100000000002 18 -126 } -100000000110
+    test mathop-8.8 {compiled ^} { ^ 0xff 0o377 333333333333 } 333333333333
+    test mathop-8.9 {compiled ^} { ^ 1000000000000000000002 18 -126 } -1000000000000000000110
+    test mathop-8.10 {compiled ^} { ^ 0xff 0o377 3333333333333333333333 } 3333333333333333333333
+    test mathop-8.11 {compiled ^: errors} -returnCodes error -body {
+	^ x 0
+    } -result {can't use non-numeric string as operand of "^"}
+    test mathop-8.12 {compiled ^: errors} -returnCodes error -body {
+	^ nan 0
+    } -result {can't use non-numeric floating-point value as operand of "^"}
+    test mathop-8.13 {compiled ^: errors} -returnCodes error -body {
+	^ 0 x
+    } -result {can't use non-numeric string as operand of "^"}
+    test mathop-8.14 {compiled ^: errors} -returnCodes error -body {
+	^ 0 nan
+    } -result {can't use non-numeric floating-point value as operand of "^"}
+    test mathop-8.15 {compiled ^: errors} -returnCodes error -body {
+	^ 0o8 0
+    } -result {can't use invalid octal number as operand of "^"}
+    test mathop-8.16 {compiled ^: errors} -returnCodes error -body {
+	^ 0 0o8
+    } -result {can't use invalid octal number as operand of "^"}
+    test mathop-8.17 {compiled ^: errors} -returnCodes error -body {
+	^ 0 [error expectedError]
+    } -result expectedError
+    test mathop-8.18 {compiled ^: argument processing order} -body {
+	# Bytecode compilation known hard for 3+ arguments
+	list [catch {
+	    ^ [set x 0] [incr x] NaN [incr x] [error expected] [incr x]
+	} msg] $msg $x
+    } -result {1 expected 2}
+    set op ^
+    test mathop-8.19 {interpreted ^} { $op } 0
+    test mathop-8.20 {interpreted ^} { $op 1 } 1
+    test mathop-8.21 {interpreted ^} { $op 1 2 } 3
+    test mathop-8.22 {interpreted ^} { $op 3 7 6 } 2
+    test mathop-8.23 {interpreted ^} -returnCodes error -body {
+	$op 1.0 2 3
+    } -result {can't use floating-point value as operand of "^"}
+    test mathop-8.24 {interpreted ^} -returnCodes error -body {
+	$op 1 2 3.0
+    } -result {can't use floating-point value as operand of "^"}
+    test mathop-8.25 {interpreted ^} { $op 100000000002 18 -126 } -100000000110
+    test mathop-8.26 {interpreted ^} { $op 0xff 0o377 333333333333 } 333333333333
+    test mathop-8.27 {interpreted ^} { $op 1000000000000000000002 18 -126 } -1000000000000000000110
+    test mathop-8.28 {interpreted ^} { $op 0xff 0o377 3333333333333333333333 } 3333333333333333333333
+    test mathop-8.29 {interpreted ^: errors} -returnCodes error -body {
+	$op x 0
+    } -result {can't use non-numeric string as operand of "^"}
+    test mathop-8.30 {interpreted ^: errors} -returnCodes error -body {
+	$op nan 0
+    } -result {can't use non-numeric floating-point value as operand of "^"}
+    test mathop-8.31 {interpreted ^: errors} -returnCodes error -body {
+	$op 0 x
+    } -result {can't use non-numeric string as operand of "^"}
+    test mathop-8.32 {interpreted ^: errors} -returnCodes error -body {
+	$op 0 nan
+    } -result {can't use non-numeric floating-point value as operand of "^"}
+    test mathop-8.33 {interpreted ^: errors} -returnCodes error -body {
+	$op 0o8 0
+    } -result {can't use invalid octal number as operand of "^"}
+    test mathop-8.34 {interpreted ^: errors} -returnCodes error -body {
+	$op 0 0o8
+    } -result {can't use invalid octal number as operand of "^"}
+    test mathop-8.35 {interpreted ^: errors} -returnCodes error -body {
+	$op 0 [error expectedError]
+    } -result expectedError
+    test mathop-8.36 {interpreted ^: argument processing order} -body {
+	list [catch {
+	    $op [set x 0] [incr x] NaN [incr x] [error expected] [incr x]
+	} msg] $msg $x
+    } -result {1 expected 2}
+    test mathop-8.37 {^ and bignums} {
+	list [^ $big1 $big2] [$op $big1 $big2]
+    } {14880247731239682873973207643969192131 14880247731239682873973207643969192131}
+    test mathop-8.38 {^ and bignums} {
+	list [^ $big1 $wide2] [$op $big1 $wide2]
+    } {12135435435354435435342354227710876723 12135435435354435435342354227710876723}
+    test mathop-8.39 {^ and bignums} {
+	list [^ $big1 $small2] [$op $big1 $small2]
+    } {12135435435354435435342423948763884437 12135435435354435435342423948763884437}
+    test mathop-8.40 {^ and bignums} {
+	list [^ $wide1 $big2] [$op $wide1 $big2]
+    } {2746237174783836746262572495752458622 2746237174783836746262572495752458622}
+    test mathop-8.41 {^ and bignums} {
+	list [^ $wide1 $wide2] [$op $wide1 $wide2]
+    } {75115763150222 75115763150222}
+    test mathop-8.42 {^ and bignums} {
+	list [^ $wide1 $small2] [$op $wide1 $small2]
+    } {12345678895656 12345678895656}
+    test mathop-8.43 {^ and bignums} {
+	list [^ $small1 $big2] [$op $small1 $big2]
+    } {2746237174783836746262564892918415126 2746237174783836746262564892918415126}
+    test mathop-8.44 {^ and bignums} {
+	list [^ $small1 $wide2] [$op $small1 $wide2]
+    } {87321847145446 87321847145446}
+    test mathop-8.45 {^ and bignums} {
+	list [^ $small1 $small2] [$op $small1 $small2]
+    } {70720 70720}
+
+    # TODO: % ** << >>  - /  == != < <= > >=  ne  in ni
+
+    test mathop-13.100 {compiled -: argument processing order} -body {
+      # Bytecode compilation known hard for 3+ arguments
+      list [catch {
+          - [set x 0] [incr x] NaN [incr x] [error expected] [incr x]
+      } msg] $msg $x
+    } -result {1 expected 2}
+
+    test mathop-14.100 {compiled /: argument processing order} -body {
+      # Bytecode compilation known hard for 3+ arguments
+      list [catch {
+          / [set x 0] [incr x] NaN [incr x] [error expected] [incr x]
+      } msg] $msg $x
+    } -result {1 expected 2}
+}
+
+test mathop-20.1 { zero args, return unit } {
+    set res {}
+    foreach op {+ * & ^ | ** < <= > >= == eq} {
+        lappend res [TestOp $op]
+    }
+    set res
+} {0 1 -1 0 0 1 1 1 1 1 1 1}
+test mathop-20.2 { zero args, not allowed } {
+    set exp {}
+    foreach op {~ ! << >> % != ne in ni - /} {
+        set res [TestOp $op]
+        if {[string match "wrong # args: should be * TCL WRONGARGS" $res]} {
+            lappend exp 0
+        } else {
+            lappend exp $res
+        }
+    }
+    set exp
+} {0 0 0 0 0 0 0 0 0 0 0}
+test mathop-20.3 { one arg } {
+    set res {}
+    foreach val {7 8.3} {
+        foreach op {+ ** - * / < <= > >= == eq !} {
+            lappend res [TestOp $op $val]
+        }
+    }
+    set res
+} [list 7   7   -7   7   [expr {1.0/7.0}] 1 1 1 1 1 1 0 \
+        8.3 8.3 -8.3 8.3 [expr {1.0/8.3}] 1 1 1 1 1 1 0]
+test mathop-20.4 { one arg, integer only ops } {
+    set res {}
+    foreach val {23} {
+        foreach op {& | ^ ~} {
+            lappend res [TestOp $op $val]
+        }
+    }
+    set res
+} [list 23 23 23 -24]
+test mathop-20.5 { one arg, not allowed } {
+    set exp {}
+    foreach op {% != ne in ni << >>} {
+        set res [TestOp $op 1]
+        if {[string match "wrong # args: should be * TCL WRONGARGS" $res]} {
+            lappend exp 0
+        } else {
+            lappend exp $res
+        }
+    }
+    set exp
+} {0 0 0 0 0 0 0}
+test mathop-20.6 { one arg, error } {
+    set res {}
+    set exp {}
+    foreach vals {x {1 x} {1 1 x} {1 x 1}} {
+        # skipping - for now, knownbug...
+        foreach op {+ * / & | ^ **} {
+            lappend res [TestOp $op {*}$vals]
+            lappend exp "can't use non-numeric string as operand of \"$op\"\
+		ARITH DOMAIN {non-numeric string}"
+        }
+    }
+    foreach op {+ * / & | ^ **} {
+	lappend res [TestOp $op NaN 1]
+	lappend exp "can't use non-numeric floating-point value as operand of \"$op\"\
+	    ARITH DOMAIN {non-numeric floating-point value}"
+    }
+    expr {$res eq $exp ? 0 : $res}
+} 0
+test mathop-20.7 { multi arg } {
+    set res {}
+    foreach vals {{1 2} {3 4 5} {4 3 2 1}} {
+        foreach op {+ - * /} {
+            lappend res [TestOp $op {*}$vals]
+        }
+    }
+    set res
+} [list 3 -1 2 0  12 -6 60 0  10 -2 24 0]
+test mathop-20.8 { multi arg, double } {
+    set res {}
+    foreach vals {{1.0 2} {3.0 4 5} {4 3.0 2 1}
+	    {1.0 -1.0 1e-18} {1.0 1.0 1e-18}} {
+        foreach op {+ - * /} {
+            lappend res [TestOp $op {*}$vals]
+        }
+    }
+    set res
+} [list 3.0 -1.0 2.0 0.5  12.0 -6.0 60.0 0.15  10.0 -2.0 24.0 [expr {2.0/3}] 1e-18 2.0 -1e-18 [expr {-1.0/1e-18}] 2.0 -1e-18 1e-18 [expr {1.0/1e-18}]]
+
+test mathop-21.1 { unary ops, bitnot } {
+    set res {}
+    lappend res [TestOp ~ 7]
+    lappend res [TestOp ~ -5]
+    lappend res [TestOp ~ 354657483923456]
+    lappend res [TestOp ~ 123456789123456789123456789]
+    set res
+} [list -8 4 -354657483923457 -123456789123456789123456790]
+test mathop-21.2 { unary ops, logical not } {
+    set res {}
+    lappend res [TestOp ! 0]
+    lappend res [TestOp ! 1]
+    lappend res [TestOp ! true]
+    lappend res [TestOp ! false]
+    lappend res [TestOp ! 37]
+    lappend res [TestOp ! 8.5]
+    set res
+} [list 1 0 0 1 0 0]
+test mathop-21.3 { unary ops, negation } {
+    set res {}
+    lappend res [TestOp -  7.2]
+    lappend res [TestOp - -5]
+    lappend res [TestOp - -2147483648]                  ;# -2**31
+    lappend res [TestOp - -9223372036854775808]         ;# -2**63
+    lappend res [TestOp -  354657483923456]             ;# wide
+    lappend res [TestOp -  123456789123456789123456789] ;# big
+    set res
+} [list -7.2 5 2147483648 9223372036854775808 -354657483923456 \
+           -123456789123456789123456789]
+test mathop-21.4 { unary ops, inversion } {
+    set res {}
+    lappend res [TestOp / 1]
+    lappend res [TestOp / 5]
+    lappend res [TestOp / 5.6]
+    lappend res [TestOp / -8]
+    lappend res [TestOp /  354657483923456]             ;# wide
+    lappend res [TestOp /  123456789123456789123456789] ;# big
+    set res
+} [list 1.0 0.2 0.17857142857142858 -0.125 \
+           2.8196218755553604e-15 8.10000006561e-27]
+test mathop-21.5 { unary ops, bad values } {
+    set res {}
+    set exp {}
+    lappend res [TestOp / x]
+    lappend exp "can't use non-numeric string as operand of \"/\" ARITH DOMAIN {non-numeric string}"
+    lappend res [TestOp - x]
+    lappend exp "can't use non-numeric string as operand of \"-\" ARITH DOMAIN {non-numeric string}"
+    lappend res [TestOp ~ x]
+    lappend exp "can't use non-numeric string as operand of \"~\" ARITH DOMAIN {non-numeric string}"
+    lappend res [TestOp ! x]
+    lappend exp "can't use non-numeric string as operand of \"!\" ARITH DOMAIN {non-numeric string}"
+    lappend res [TestOp ~ 5.0]
+    lappend exp "can't use floating-point value as operand of \"~\" ARITH DOMAIN {floating-point value}"
+    expr {$res eq $exp ? 0 : $res}
+} 0
+test mathop-21.6 { unary ops, too many } {
+    set exp {}
+    foreach op {~ !} {
+        set res [TestOp $op 7 8]
+        if {[string match "wrong # args: should be * TCL WRONGARGS" $res]} {
+            lappend exp 0
+        } else {
+            lappend exp $res
+        }
+    }
+    set exp
+} {0 0}
+
+test mathop-22.1 { bitwise ops } {
+    set res {}
+    foreach vals {5 {1 6} {1 2 3} {1 2 3 4}} {
+        foreach op {& | ^} {
+            lappend res [TestOp $op {*}$vals]
+        }
+    }
+    set res
+} [list 5 5 5  0 7 7  0 3 0  0 7 4]
+test mathop-22.2 { bitwise ops on bignums } {
+    set dig 50
+    set a 0x[string repeat 5 $dig]
+    set b 0x[string repeat 7 $dig]
+    set c 0x[string repeat 9 $dig]
+    set bn [expr {~$b}]
+    set cn [expr {~$c}]
+
+    set res {}
+    foreach vals [list [list $a $b] [list $a $c] [list $b $c] \
+                          [list $a $bn] [list $bn $c] [list $bn $cn]] {
+        foreach op {& | ^} {
+            lappend res [TestOp $op {*}$vals]
+        }
+    }
+    set exp {}
+    foreach d {5 7 2  1 D C  1 F E  0 -D -D  8 -9 -1  -0 -E E} {
+        if {[string match "-*" $d]} {
+            set d [format %X [expr 15-0x[string range $d 1 end]]]
+            set val [expr -0x[string repeat $d $dig]-1]
+        } else {
+            set val [expr 0x[string repeat $d $dig]]
+        }
+        lappend exp $val
+    }
+    expr {$exp eq $res ? 1 : "($res != $exp"}
+} 1
+test mathop-22.3 { bitwise ops } {
+    set big1      12135435435354435435342423948763867876
+    set big2       2746237174783836746262564892918327847
+    set wide1                             12345678912345
+    set wide2                             87321847232215
+    set small1                                     87345
+    set small2                                     16753
+
+    set res {}
+    foreach op {& | ^} {
+        lappend res [TestOp $op $big1   $big2]
+        lappend res [TestOp $op $big1   $wide2]
+        lappend res [TestOp $op $big1   $small2]
+        lappend res [TestOp $op $wide1  $big2]
+        lappend res [TestOp $op $wide1  $wide2]
+        lappend res [TestOp $op $wide1  $small2]
+        lappend res [TestOp $op $small1 $big2]
+        lappend res [TestOp $op $small1 $wide2]
+        lappend res [TestOp $op $small1 $small2]
+    }
+    set res
+} [list \
+           712439449294653815890598856501796 \
+           78521450111684 \
+           96 \
+           2371422390785 \
+           12275881497169 \
+           16721 \
+           33 \
+           87057 \
+           16689 \
+           14880960170688977527789098242825693927 \
+           12135435435354435435342432749160988407 \
+           12135435435354435435342423948763884533 \
+           2746237174783836746262574867174849407 \
+           87391644647391 \
+           12345678912377 \
+           2746237174783836746262564892918415159 \
+           87321847232503 \
+           87409 \
+           14880247731239682873973207643969192131 \
+           12135435435354435435342354227710876723 \
+           12135435435354435435342423948763884437 \
+           2746237174783836746262572495752458622 \
+           75115763150222 \
+           12345678895656 \
+           2746237174783836746262564892918415126 \
+           87321847145446 \
+           70720 \
+          ]
+test mathop-22.4 { unary ops, bad values } {
+    set res {}
+    set exp {}
+    foreach op {& | ^} {
+        lappend res [TestOp $op x 5]
+        lappend exp "can't use non-numeric string as operand of \"$op\" ARITH DOMAIN {non-numeric string}"
+        lappend res [TestOp $op 5 x]
+        lappend exp "can't use non-numeric string as operand of \"$op\" ARITH DOMAIN {non-numeric string}"
+    }
+    expr {$res eq $exp ? 0 : $res}
+} 0
+
+test mathop-23.1 { comparison ops, numerical } {
+    set res {}
+    set todo {5 {1 6} {1 2 2 3} {4 3 2 1} {5.0 5.0} {6 3 3 1} {5.0 5}}
+    lappend todo [list 2342476234762482734623842342 234827463876473 3434]
+    lappend todo [list 2653 453735910264536 453735910264537 2384762472634982746239847637]
+    lappend todo [list 2653 2384762472634982746239847637]
+    lappend todo [list 2653 -2384762472634982746239847637]
+    lappend todo [list 3789253678212653 -2384762472634982746239847637]
+    lappend todo [list 5.0 6 7.0 8 1e13 1945628567352654 1.1e20 \
+                          6734253647589123456784564378 2.3e50]
+    set a 7
+    lappend todo [list $a $a] ;# Same object
+    foreach vals $todo {
+        foreach op {< <= > >= == eq} {
+            lappend res [TestOp $op {*}$vals]
+        }
+    }
+    set res
+} [list 1 1 1 1 1 1 \
+        1 1 0 0 0 0 \
+        0 1 0 0 0 0 \
+        0 0 1 1 0 0 \
+        0 1 0 1 1 1 \
+        0 0 0 1 0 0 \
+        0 1 0 1 1 0 \
+        0 0 1 1 0 0 \
+        1 1 0 0 0 0 \
+        1 1 0 0 0 0 \
+        0 0 1 1 0 0 \
+        0 0 1 1 0 0 \
+        1 1 0 0 0 0 \
+        0 1 0 1 1 1 \
+       ]
+test mathop-23.2 { comparison ops, string } {
+    set res {}
+    set todo {a {a b} {5 b b c} {d c b a} {xy xy} {gy ef ef ab}}
+    set a x
+    lappend todo [list $a $a]
+    foreach vals $todo {
+        foreach op {< <= > >= == eq} {
+            lappend res [TestOp $op {*}$vals]
+        }
+    }
+    set res
+} [list 1 1 1 1 1 1 \
+        1 1 0 0 0 0 \
+        0 1 0 0 0 0 \
+        0 0 1 1 0 0 \
+        0 1 0 1 1 1 \
+        0 0 0 1 0 0 \
+        0 1 0 1 1 1 \
+       ]
+test mathop-23.3 { comparison ops, nonequal} {
+    set res {}
+    foreach vals {{a b} {17.0 0x11} {foo foo} {10 10}} {
+        foreach op {!= ne} {
+            lappend res [TestOp $op {*}$vals]
+        }
+    }
+    set res
+} [list 1 1  0 1  0 0  0 0 ]
+
+test mathop-24.1 { binary ops } {
+    set res {}
+    foreach vals {{3 5} {17 7} {199 5} {293234675763434238476239486 17} \
+                  {5 1} {0 7}} {
+        foreach op {% << >> in ni} {
+            lappend res [TestOp $op {*}$vals]
+        }
+    }
+    set res
+} [list 3 96 0 0 1  3 2176 0 0 1  4 6368 6 0 1 \
+        14 38434855421664852505557661908992 2237203031642412097749 0 1 \
+        0 10 2 0 1  0 0 0 0 1]
+test mathop-24.2 { binary ops, modulo } {
+    # Test different combinations to get all code paths
+    set res {}
+
+    set bigbig 14372423674564535234543545248972634923869
+    set big       12135435435354435435342423948763867876
+    set wide                              12345678912345
+    set negwide                          -12345678912345
+    set small                                          5
+    set neg                                           -5
+
+    lappend res [TestOp % $bigbig  $big]
+    lappend res [TestOp % $wide    $big]
+    lappend res [TestOp % $negwide $big]
+    lappend res [TestOp % $small   $big]
+    lappend res [TestOp % $neg     $big]
+    lappend res [TestOp % $small  $wide]
+    lappend res [TestOp % $neg    $wide]
+    lappend res [TestOp % $wide  $small]
+    set res
+} [list   4068119104883679098115293636215358685 \
+                                 12345678912345 \
+         12135435435354435435342411603084955531 \
+                                              5 \
+         12135435435354435435342423948763867871 \
+                                              5 \
+                                 12345678912340 \
+                                              0 \
+          ]
+test mathop-24.3 { binary ops, bad values } {
+    set res {}
+    set exp {}
+    foreach op {% << >>} {
+        lappend res [TestOp $op x 1]
+        lappend exp "can't use non-numeric string as operand of \"$op\" ARITH DOMAIN {non-numeric string}"
+        lappend res [TestOp $op 1 x]
+        lappend exp "can't use non-numeric string as operand of \"$op\" ARITH DOMAIN {non-numeric string}"
+    }
+    foreach op {% << >>} {
+        lappend res [TestOp $op 5.0 1]
+        lappend exp "can't use floating-point value as operand of \"$op\" ARITH DOMAIN {floating-point value}"
+        lappend res [TestOp $op 1 5.0]
+        lappend exp "can't use floating-point value as operand of \"$op\" ARITH DOMAIN {floating-point value}"
+    }
+    foreach op {in ni} {
+        lappend res [TestOp $op 5 "a b \{ c"]
+        lappend exp "unmatched open brace in list TCL VALUE LIST BRACE"
+    }
+    lappend res [TestOp % 5 0]
+    lappend exp "divide by zero ARITH DIVZERO {divide by zero}"
+    lappend res [TestOp % 9838923468297346238478737647637375 0]
+    lappend exp "divide by zero ARITH DIVZERO {divide by zero}"
+    lappend res [TestOp / 5 0]
+    lappend exp "divide by zero ARITH DIVZERO {divide by zero}"
+    lappend res [TestOp / 9838923468297346238478737647637375 0]
+    lappend exp "divide by zero ARITH DIVZERO {divide by zero}"
+    expr {$res eq $exp ? 0 : $res}
+} 0
+test mathop-24.4 { binary ops, negative shift } {
+    set res {}
+
+    set big      -12135435435354435435342423948763867876
+    set wide                             -12345678912345
+    set small                                         -1
+
+    lappend res [TestOp << 10 $big]
+    lappend res [TestOp << 10 $wide]
+    lappend res [TestOp << 10 $small]
+    lappend res [TestOp >> 10 $big]
+    lappend res [TestOp >> 10 $wide]
+    lappend res [TestOp >> 10 $small]
+
+    set exp [lrepeat 6 "negative shift argument NONE"]
+    expr {$res eq $exp ? 0 : $res}
+} 0
+test mathop-24.5 { binary ops, large shift } {
+    set res {}
+    set exp {}
+
+    set big      12135435435354435435342423948763867876
+    set wide                             12345678912345
+    set small                                         1
+
+    lappend res [TestOp << 1 2147483648]
+    lappend exp "integer value too large to represent NONE"
+    lappend res [TestOp << 1 4294967296]
+    lappend exp "integer value too large to represent NONE"
+    lappend res [TestOp << $small $wide]
+    lappend exp "integer value too large to represent NONE"
+    lappend res [TestOp << $small $big]
+    lappend exp "integer value too large to represent NONE"
+    lappend res [TestOp >> $big $wide]
+    lappend exp 0
+    lappend res [TestOp >> $big $big]
+    lappend exp 0
+    lappend res [TestOp >> $small 70]
+    lappend exp 0
+    lappend res [TestOp >> $wide 70]
+    lappend exp 0
+    lappend res [TestOp >> -$big $wide]
+    lappend exp -1
+    lappend res [TestOp >> -$wide $wide]
+    lappend exp -1
+    lappend res [TestOp >> -$small $wide]
+    lappend exp -1
+    lappend res [TestOp >> -$small 70]
+    lappend exp -1
+    lappend res [TestOp >> -$wide 70]
+    lappend exp -1
+
+    expr {$res eq $exp ? 0 : $res}
+} 0
+test mathop-24.6 { binary ops, shift } {
+    # Test different combinations to get all code paths
+    set res {}
+
+    set bigbig 14372423674564535234543545248972634923869
+    set big       12135435435354435435342423948763867876
+    set wide                              12345678912345
+    set negwide                          -12345678912345
+    set small                                          5
+    set neg                                           -5
+
+    lappend res [TestOp << $wide $small]
+    lappend res [TestOp >> $wide $small]
+    set res
+} [list   395061725195040 \
+             385802466010 \
+          ]
+test mathop-24.7 { binary ops, list search } {
+    set res {}
+
+    foreach op {in ni} {
+        lappend res [TestOp $op 5 {7 5 8}]
+        lappend res [TestOp $op hej {foo bar hej}]
+        lappend res [TestOp $op 5 {7 0x5 8}]
+    }
+    set res
+} [list 1 1 0  0 0 1]
+test mathop-24.8 { binary ops, too many } {
+    set exp {}
+    foreach op {<< >> % != ne in ni ~ !} {
+        set res [TestOp $op 7 8 9]
+        if {[string match "wrong # args: should be * TCL WRONGARGS" $res]} {
+            lappend exp 0
+        } else {
+            lappend exp $res
+        }
+    }
+    set exp
+} {0 0 0 0 0 0 0 0 0}
+
+test mathop-25.1  { exp operator } {TestOp **        } 1
+test mathop-25.2  { exp operator } {TestOp **   0    } 0
+test mathop-25.3  { exp operator } {TestOp **   0   5} 0
+test mathop-25.4  { exp operator } {TestOp ** 7.5    } 7.5
+test mathop-25.5  { exp operator } {TestOp **   1   5} 1
+test mathop-25.6  { exp operator } {TestOp **   5   1} 5
+test mathop-25.7  { exp operator } {TestOp ** 4 3 2 1} 262144
+test mathop-25.8  { exp operator } {TestOp ** 5.5   4} 915.0625
+test mathop-25.9  { exp operator } {TestOp **  16 3.5} 16384.0
+test mathop-25.10 { exp operator } {TestOp ** 3.5   0} 1.0
+test mathop-25.11 { exp operator } {TestOp ** 378   0} 1
+test mathop-25.12 { exp operator } {TestOp ** 7.8   1} 7.8
+test mathop-25.13 { exp operator } {TestOp ** 748   1} 748
+test mathop-25.14 { exp operator } {TestOp ** 1.6  -1} 0.625
+test mathop-25.15 { exp operator } {TestOp ** 683  -1} 0
+test mathop-25.16 { exp operator } {TestOp **   1  -1} 1
+test mathop-25.17 { exp operator } {TestOp **  -1  -1} -1
+test mathop-25.18 { exp operator } {TestOp **  -1  -2} 1
+test mathop-25.19 { exp operator } {TestOp **  -1   3} -1
+test mathop-25.20 { exp operator } {TestOp **  -1   4} 1
+test mathop-25.21 { exp operator } {TestOp **   2  63} 9223372036854775808
+test mathop-25.22 { exp operator } {TestOp ** 83756485763458746358734658473567847567473 2} 7015148907444467657897585474493757781161998914521537835809623408157343003287605729
+test mathop-25.23 { exp operator errors } {
+    set res {}
+    set exp {}
+
+    set huge     [string repeat 145782 1000]
+    set big      12135435435354435435342423948763867876
+    set wide                             12345678912345
+    set small                                         2
+
+    lappend res [TestOp ** 0 -5]
+    lappend exp "exponentiation of zero by negative power ARITH DOMAIN {exponentiation of zero by negative power}"
+    lappend res [TestOp ** 0.0 -5.0]
+    lappend exp "exponentiation of zero by negative power ARITH DOMAIN {exponentiation of zero by negative power}"
+    lappend res [TestOp ** $small $wide]
+    lappend exp "exponent too large NONE"
+    lappend res [TestOp ** 2 $big]
+    lappend exp "exponent too large NONE"
+    lappend res [TestOp ** $huge 2.1]
+    lappend exp "Inf"
+    lappend res [TestOp ** 2 foo]
+    lappend exp "can't use non-numeric string as operand of \"**\" ARITH DOMAIN {non-numeric string}"
+    lappend res [TestOp ** foo 2]
+    lappend exp "can't use non-numeric string as operand of \"**\" ARITH DOMAIN {non-numeric string}"
+
+    expr {$res eq $exp ? 0 : $res}
+} 0
+
+test mathop-26.1 { misc ops, size combinations } {
+    set big1      12135435435354435435342423948763867876
+    set big2       2746237174783836746262564892918327847
+    set wide1                             87321847232215
+    set wide2                             12345678912345
+    set small1                                     87345
+    set small2                                     16753
+
+    set res {}
+    foreach op {+ * - /} {
+        lappend res [TestOp $op $big1   $big2]
+        lappend res [TestOp $op $big1   $wide2]
+        lappend res [TestOp $op $big1   $small2]
+        lappend res [TestOp $op $wide1  $big2]
+        lappend res [TestOp $op $wide1  $wide2]
+        lappend res [TestOp $op $wide1  $small2]
+        lappend res [TestOp $op $small1 $big2]
+        lappend res [TestOp $op $small1 $wide2]
+        lappend res [TestOp $op $small1 $small2]
+    }
+    set res
+} [list \
+           14881672610138272181604988841682195723 \
+           12135435435354435435342436294442780221 \
+           12135435435354435435342423948763884629 \
+           2746237174783836746262652214765560062 \
+           99667526144560 \
+           87321847248968 \
+           2746237174783836746262564892918415192 \
+           12345678999690 \
+           104098 \
+           33326783924759424684447891401270222910405366244661685890993770489959542972 \
+           149820189346379518024969783068410988366610965329220 \
+           203304949848492856848291628413641078526628 \
+           239806503039903915972546163440347114360602909991105 \
+           1078047487961768329845194175 \
+           1462902906681297895 \
+           239870086031494220602303730571951345796215 \
+           1078333324598774025 \
+           1463290785 \
+           9389198260570598689079859055845540029 \
+           12135435435354435435342411603084955531 \
+           12135435435354435435342423948763851123 \
+           -2746237174783836746262477571071095632 \
+           74976168319870 \
+           87321847215462 \
+           -2746237174783836746262564892918240502 \
+           -12345678825000 \
+           70592 \
+           4 \
+           982970278225822587257201 \
+           724373869477373332259441529801460 \
+           0 \
+           7 \
+           5212311062 \
+           0 \
+           0 \
+           5 \
+          ]
+test mathop-26.2 { misc ops, corner cases } {
+    set res {}
+    lappend res [TestOp - 0 -2147483648]                  ;# -2**31
+    lappend res [TestOp - 0 -9223372036854775808]         ;# -2**63
+    lappend res [TestOp / -9223372036854775808 -1]
+    lappend res [TestOp * 2147483648 2]
+    lappend res [TestOp * 9223372036854775808 2]
+    set res
+} [list 2147483648 9223372036854775808 9223372036854775808 4294967296 18446744073709551616]
+
+if 0 {
+    # Compare ops to expr bytecodes
+    namespace import ::tcl::mathop::*
+    proc _X {a b c} {
+        set x [+ $a [- $b $c]]
+        set y [expr {$a + ($b - $c)}]
+        set z [< $a $b $c]
+    }
+    set ::tcl_traceCompile 2
+    _X 3 4 5
+    set ::tcl_traceCompile 0
+}
+
+# cleanup
+namespace delete ::testmathop
+namespace delete ::testmathop2
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/tests/misc.test b/tests/misc.test
new file mode 100644
index 0000000..d4ece74
--- /dev/null
+++ b/tests/misc.test
@@ -0,0 +1,74 @@
+# Commands covered:  various
+#
+# This file contains a collection of miscellaneous Tcl tests that
+# don't fit naturally in any of the other test files.  Many of these
+# tests are pathological cases that caused bugs in earlier Tcl
+# releases.
+#
+# Copyright (c) 1992-1993 The Regents of the University of California.
+# Copyright (c) 1994-1996 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+    package require tcltest
+    namespace import -force ::tcltest::*
+}
+
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
+
+testConstraint testhashsystemhash [llength [info commands testhashsystemhash]]
+
+test misc-1.1 {error in variable ref. in command in array reference} {
+    proc tstProc {} {
+	global a
+    
+	set tst $a([winfo name $zz])
+	# this is a bogus comment
+	# this is a bogus comment
+	# this is a bogus comment
+	# this is a bogus comment
+	# this is a bogus comment
+	# this is a bogus comment
+	# this is a bogus comment
+	# this is a bogus comment
+    }
+    set msg {}
+    list [catch tstProc msg] $msg
+} {1 {can't read "zz": no such variable}}
+test misc-1.2 {error in variable ref. in command in array reference} {
+    proc tstProc {} "
+	global a
+    
+	set tst \$a(\[winfo name \$\{zz)
+	# this is a bogus comment
+	# this is a bogus comment
+	# this is a bogus comment
+	# this is a bogus comment
+	# this is a bogus comment
+	# this is a bogus comment
+	# this is a bogus comment
+	# this is a bogus comment
+    "
+    set msg {}
+    join [list [catch tstProc msg] $msg $::errorInfo] \n
+} [subst -novariables -nocommands {1
+missing close-brace for variable name
+missing close-brace for variable name
+    while executing
+"set tst $a([winfo name $\{"
+    (procedure "tstProc" line 4)
+    invoked from within
+"tstProc"}]
+
+for {set i 1} {$i<300} {incr i} {
+    test misc-2.$i {hash table with sys-alloc} testhashsystemhash \
+	    "testhashsystemhash $i" OK
+}
+
+# cleanup
+::tcltest::cleanupTests
+return
diff --git a/tests/msgcat.test b/tests/msgcat.test
new file mode 100644
index 0000000..ae35272
--- /dev/null
+++ b/tests/msgcat.test
@@ -0,0 +1,1085 @@
+# This file contains a collection of tests for the msgcat package.
+# Sourcing this file into Tcl runs the tests and
+# generates output for errors.  No output means no errors were found.
+#
+# Copyright (c) 1998 Mark Harrison.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+# Contributions from Don Porter, NIST, 2002.  (not subject to US copyright)
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+# Note that after running these tests, entries will be left behind in the
+# message catalogs for locales foo, foo_BAR, and foo_BAR_baz.
+
+package require Tcl 8.5
+if {[catch {package require tcltest 2}]} {
+    puts stderr "Skipping tests in [info script].  tcltest 2 required."
+    return
+}
+if {[catch {package require msgcat 1.6}]} {
+    puts stderr "Skipping tests in [info script].  No msgcat 1.6 found to test."
+    return
+}
+
+namespace eval ::msgcat::test {
+    namespace import ::msgcat::*
+    namespace import ::tcltest::test
+    namespace import ::tcltest::cleanupTests
+    namespace import ::tcltest::temporaryDirectory
+    namespace import ::tcltest::make*
+    namespace import ::tcltest::remove*
+
+    # Tests msgcat-0.*: locale initialization
+
+    # Calculate set of all permutations of a list
+    # PowerSet {1 2 3} -> {1 2 3} {2 3} {1 3} 3 {1 2} 2 1 {}
+    proc PowerSet {l} {
+	if {[llength $l] == 0} {return [list [list]]}
+	set element [lindex $l 0]
+	set rest [lrange $l 1 end]
+	set result [list]
+	foreach x [PowerSet $rest] {
+	    lappend result [linsert $x 0 $element]
+	    lappend result $x
+	}
+	return $result
+    }
+
+    variable envVars {LC_ALL LC_MESSAGES LANG}
+    variable count 0
+    variable body
+    variable result
+    variable setVars
+    foreach setVars [PowerSet $envVars] { 
+	set result [string tolower [lindex $setVars 0]]
+	if {[string length $result] == 0} {
+	    if {[info exists ::tcl::mac::locale]} {
+		set result [string tolower \
+			[msgcat::ConvertLocale $::tcl::mac::locale]]
+	    } else {
+		if {([info sharedlibextension] eq ".dll")
+			&& ![catch {package require registry}]} {
+		    # Windows and Cygwin have other ways to determine the
+		    # locale when the environment variables are missing
+		    # and the registry package is present
+		    continue
+		}
+		set result c
+	    }
+	}
+
+	test msgcat-0.$count [list \
+	    locale initialization from environment variables $setVars \
+	] -setup {
+	    variable var
+	    foreach var $envVars {
+		catch {variable $var $::env($var)}
+		unset -nocomplain ::env($var)
+	    }
+	    foreach var $setVars {
+		set ::env($var) $var
+	    }
+	    interp create [namespace current]::i
+	    i eval [list package ifneeded msgcat [package provide msgcat] \
+		    [package ifneeded msgcat [package provide msgcat]]]
+	    i eval package require msgcat
+	} -cleanup {
+	    interp delete [namespace current]::i
+	    foreach var $envVars {
+		unset -nocomplain ::env($var)
+		catch {set ::env($var) [set [namespace current]::$var]}
+	    }
+	} -body {i eval msgcat::mclocale} -result $result
+	incr count
+    }
+    unset -nocomplain result
+    
+    # Could add tests of initialization from Windows registry here.
+    # Use a fake registry package.
+
+    # Tests msgcat-1.*: [mclocale], [mcpreferences]
+
+    test msgcat-1.3 {mclocale set, single element} -setup {
+	variable locale [mclocale]
+    } -cleanup {
+	mclocale $locale
+    } -body {
+	mclocale en
+    } -result en
+
+    test msgcat-1.4 {mclocale get, single element} -setup {
+	variable locale [mclocale]
+	mclocale en
+    } -cleanup {
+	mclocale $locale
+    } -body {
+	mclocale
+    } -result en
+
+    test msgcat-1.5 {mcpreferences, single element} -setup {
+	variable locale [mclocale]
+	mclocale en
+    } -cleanup {
+	mclocale $locale
+    } -body {
+	mcpreferences
+    } -result {en {}}
+
+    test msgcat-1.6 {mclocale set, two elements} -setup {
+	variable locale [mclocale]
+    } -cleanup {
+	mclocale $locale
+    } -body {
+	mclocale en_US
+    } -result en_us
+
+    test msgcat-1.7 {mclocale get, two elements} -setup {
+	variable locale [mclocale]
+	mclocale en_US
+    } -cleanup {
+	mclocale $locale
+    } -body {
+	mclocale
+    } -result en_us
+
+    test msgcat-1.8 {mcpreferences, two elements} -setup {
+	variable locale [mclocale]
+	mclocale en_US
+    } -cleanup {
+	mclocale $locale
+    } -body {
+	mcpreferences
+    } -result {en_us en {}}
+
+    test msgcat-1.9 {mclocale set, three elements} -setup {
+	variable locale [mclocale]
+    } -cleanup {
+	mclocale $locale
+    } -body {
+	mclocale en_US_funky
+    } -result en_us_funky
+
+    test msgcat-1.10 {mclocale get, three elements} -setup {
+	variable locale [mclocale]
+	mclocale en_US_funky
+    } -cleanup {
+	mclocale $locale
+    } -body {
+	mclocale
+    } -result en_us_funky
+
+    test msgcat-1.11 {mcpreferences, three elements} -setup {
+	variable locale [mclocale]
+	mclocale en_US_funky
+    } -cleanup {
+	mclocale $locale
+    } -body {
+	mcpreferences
+    } -result {en_us_funky en_us en {}}
+
+    test msgcat-1.12 {mclocale set, reject evil input} -setup {
+	variable locale [mclocale]
+    } -cleanup {
+	mclocale $locale
+    } -body {
+	mclocale /path/to/evil/code
+    } -returnCodes error -match glob -result {invalid newLocale value *}
+
+    test msgcat-1.13 {mclocale set, reject evil input} -setup {
+	variable locale [mclocale]
+    } -cleanup {
+	mclocale $locale
+    } -body {
+	mclocale looks/ok/../../../../but/is/path/to/evil/code
+    } -returnCodes error -match glob -result {invalid newLocale value *}
+
+    # Tests msgcat-2.*: [mcset], [mcmset], namespace partitioning
+
+    test msgcat-2.1 {mcset, global scope} {
+	namespace eval :: ::msgcat::mcset  foo_BAR text1 text2
+    } {text2}
+
+    test msgcat-2.2 {mcset, global scope, default} {
+	namespace eval :: ::msgcat::mcset foo_BAR text3
+    } {text3}
+
+    test msgcat-2.2.1 {mcset, namespace overlap} {
+	namespace eval baz {::msgcat::mcset  foo_BAR con1 con1baz}
+    } {con1baz}
+
+    test msgcat-2.3 {mcset, namespace overlap} -setup {
+	namespace eval bar {::msgcat::mcset  foo_BAR con1 con1bar}
+	namespace eval baz {::msgcat::mcset  foo_BAR con1 con1baz}
+	variable locale [mclocale]
+	mclocale foo_BAR
+    } -cleanup {
+	mclocale $locale
+    } -body {
+	namespace eval bar {::msgcat::mc con1}
+    } -result con1bar
+
+    test msgcat-2.4 {mcset, namespace overlap} -setup {
+	namespace eval bar {::msgcat::mcset  foo_BAR con1 con1bar}
+	namespace eval baz {::msgcat::mcset  foo_BAR con1 con1baz}
+	variable locale [mclocale]
+	mclocale foo_BAR
+    } -cleanup {
+	mclocale $locale
+    } -body {
+	namespace eval baz {::msgcat::mc con1}
+    } -result con1baz
+
+    test msgcat-2.5 {mcmset, global scope} -setup {
+	namespace eval :: {
+	    ::msgcat::mcmset  foo_BAR {
+	        src1 trans1
+	        src2 trans2
+	    }
+	}
+	variable locale [mclocale]
+	mclocale foo_BAR
+    } -cleanup {
+	mclocale $locale
+    } -body {
+	namespace eval :: {
+	    ::msgcat::mc src1
+	}
+    } -result trans1
+
+    test msgcat-2.6 {mcmset, namespace overlap} -setup {
+	namespace eval bar {::msgcat::mcmset  foo_BAR {con2 con2bar}}
+	namespace eval baz {::msgcat::mcmset  foo_BAR {con2 con2baz}}
+	variable locale [mclocale]
+	mclocale foo_BAR
+    } -cleanup {
+	mclocale $locale
+    } -body {
+	namespace eval bar {::msgcat::mc con2}
+    } -result con2bar
+
+    test msgcat-2.7 {mcmset, namespace overlap} -setup {
+	namespace eval bar {::msgcat::mcmset  foo_BAR {con2 con2bar}}
+	namespace eval baz {::msgcat::mcmset  foo_BAR {con2 con2baz}}
+	variable locale [mclocale]
+	mclocale foo_BAR
+    } -cleanup {
+	mclocale $locale
+    } -body {
+	namespace eval baz {::msgcat::mc con2}
+    } -result con2baz
+
+    # Tests msgcat-3.*: [mcset], [mc], catalog "inheritance"
+    #
+    # Test mcset and mc, ensuring that more specific locales
+    # (e.g. en_UK) will search less specific locales
+    # (e.g. en) for translation strings.
+    #
+    # Do this for the 15 permutations of
+    #     locales: {foo foo_BAR foo_BAR_baz}
+    #     strings: {ov0 ov1 ov2 ov3 ov4}
+    #	  locale ROOT        defines ov0, ov1, ov2, ov3
+    #     locale foo         defines      ov1, ov2, ov3
+    #     locale foo_BAR     defines           ov2, ov3
+    #     locale foo_BAR_BAZ defines                ov3
+    #     (ov4 is defined in none)
+    # So,
+    #     ov3 should be resolved in foo, foo_BAR, foo_BAR_baz
+    #     ov2 should be resolved in foo, foo_BAR
+    #     ov2 should resolve to foo_BAR in foo_BAR_baz
+    #     ov1 should be resolved in foo
+    #     ov1 should resolve to foo in foo_BAR, foo_BAR_baz
+    #     ov4 should be resolved in none, and call mcunknown
+    #
+    variable count 2
+    variable result
+    array set result {
+	foo,ov0 ov0_ROOT foo,ov1 ov1_foo foo,ov2 ov2_foo 
+        foo,ov3 ov3_foo foo,ov4 ov4
+	foo_BAR,ov0 ov0_ROOT foo_BAR,ov1 ov1_foo foo_BAR,ov2 ov2_foo_BAR 
+        foo_BAR,ov3 ov3_foo_BAR	foo_BAR,ov4 ov4 
+        foo_BAR_baz,ov0 ov0_ROOT foo_BAR_baz,ov1 ov1_foo 
+        foo_BAR_baz,ov2 ov2_foo_BAR
+	foo_BAR_baz,ov3 ov3_foo_BAR_baz foo_BAR_baz,ov4 ov4
+    }
+    variable loc
+    variable string
+    foreach loc {foo foo_BAR foo_BAR_baz} {
+	foreach string {ov0 ov1 ov2 ov3 ov4} {
+	    test msgcat-3.$count {mcset, overlap} -setup {
+		mcset {} ov0 ov0_ROOT
+		mcset {} ov1 ov1_ROOT
+		mcset {} ov2 ov2_ROOT
+		mcset {} ov3 ov3_ROOT
+		mcset foo ov1 ov1_foo
+		mcset foo ov2 ov2_foo
+		mcset foo ov3 ov3_foo
+		mcset foo_BAR ov2 ov2_foo_BAR
+		mcset foo_BAR ov3 ov3_foo_BAR
+		mcset foo_BAR_baz ov3 ov3_foo_BAR_baz
+		variable locale [mclocale]
+		mclocale $loc
+	    } -cleanup {
+		mclocale $locale
+	    } -body {
+		mc $string
+	    } -result $result($loc,$string)
+	    incr count
+	}
+    }
+    unset -nocomplain result
+
+    # Tests msgcat-4.*: [mcunknown]
+
+    test msgcat-4.2 {mcunknown, default} -setup {
+	mcset foo unk1 "unknown 1"
+	variable locale [mclocale]
+	mclocale foo
+    } -cleanup {
+	mclocale $locale
+    } -body {
+	mc unk1
+    } -result {unknown 1}
+
+    test msgcat-4.3 {mcunknown, default} -setup {
+	mcset foo unk1 "unknown 1"
+	variable locale [mclocale]
+	mclocale foo
+    } -cleanup {
+	mclocale $locale
+    } -body {
+	mc unk2
+    } -result unk2
+
+    test msgcat-4.4 {mcunknown, overridden} -setup {
+	rename ::msgcat::mcunknown SavedMcunknown
+	proc ::msgcat::mcunknown {dom s} {
+            return unknown:$dom:$s
+	}
+	mcset foo unk1 "unknown 1"
+	variable locale [mclocale]
+	mclocale foo
+    } -cleanup {
+	mclocale $locale
+	rename ::msgcat::mcunknown {}
+	rename SavedMcunknown ::msgcat::mcunknown
+    } -body {
+	mc unk1
+    } -result {unknown 1}
+
+    test msgcat-4.5 {mcunknown, overridden} -setup {
+	rename ::msgcat::mcunknown SavedMcunknown
+	proc ::msgcat::mcunknown {dom s} {
+            return unknown:$dom:$s
+	}
+	mcset foo unk1 "unknown 1"
+	variable locale [mclocale]
+	mclocale foo
+    } -cleanup {
+	mclocale $locale
+	rename ::msgcat::mcunknown {}
+	rename SavedMcunknown ::msgcat::mcunknown
+    } -body {
+	mc unk2
+    } -result {unknown:foo:unk2}
+
+    test msgcat-4.6 {mcunknown, uplevel context} -setup {
+	rename ::msgcat::mcunknown SavedMcunknown
+	proc ::msgcat::mcunknown {dom s} {
+            return "unknown:$dom:$s:[expr {[info level] - 1}]"
+	}
+	mcset foo unk1 "unknown 1"
+	variable locale [mclocale]
+	mclocale foo
+    } -cleanup {
+	mclocale $locale
+	rename ::msgcat::mcunknown {}
+	rename SavedMcunknown ::msgcat::mcunknown
+    } -body {
+	mc unk2
+    } -result unknown:foo:unk2:[info level]
+
+    # Tests msgcat-5.*: [mcload]
+
+    variable locales {{} foo foo_BAR foo_BAR_baz}
+    set msgdir [makeDirectory msgdir]
+    foreach loc $locales {
+	if { $loc eq {} } {
+	    set msg ROOT
+        } else {
+	    set msg [string tolower $loc]
+	}
+	makeFile [list ::msgcat::mcset $loc abc abc-$loc] $msg.msg $msgdir
+    }
+    variable count 1
+    foreach loc {foo foo_BAR foo_BAR_baz} {
+	test msgcat-5.$count {mcload} -setup {
+	    variable locale [mclocale]
+	    ::msgcat::mclocale ""
+	    ::msgcat::mcloadedlocales clear
+	    ::msgcat::mcpackageconfig unset mcfolder 
+	    mclocale $loc
+	} -cleanup {
+	    mclocale $locale
+	    ::msgcat::mcloadedlocales clear
+	    ::msgcat::mcpackageconfig unset mcfolder 
+	} -body {
+	    mcload $msgdir
+	} -result [expr { $count+1 }]
+	incr count
+    }
+
+    # Even though foo_BAR_notexist does not exist,
+    # foo_BAR, foo and the root should be loaded.
+	test msgcat-5.4 {mcload} -setup {
+	    variable locale [mclocale]
+	    mclocale foo_BAR_notexist
+	} -cleanup {
+	    mclocale $locale
+	    mcloadedlocales clear
+	    mcpackageconfig unset mcfolder 
+	} -body {
+	    mcload $msgdir
+	} -result 3
+
+	test msgcat-5.5 {mcload} -setup {
+	    variable locale [mclocale]
+	    mclocale no_FI_notexist
+	} -cleanup {
+	    mclocale $locale
+	    mcloadedlocales clear
+	    mcpackageconfig unset mcfolder 
+	} -body {
+	    mcload $msgdir
+	} -result 1
+
+	test msgcat-5.6 {mcload} -setup {
+	    variable locale [mclocale]
+	    mclocale foo
+	    mcload $msgdir
+	} -cleanup {
+	    mclocale $locale
+	} -body {
+	    mc abc
+	} -result abc-foo
+
+	test msgcat-5.7 {mcload} -setup {
+	    variable locale [mclocale]
+	    mclocale foo_BAR
+	    mcload $msgdir
+	} -cleanup {
+	    mclocale $locale
+	} -body {
+	    mc abc
+	} -result abc-foo_BAR
+
+	test msgcat-5.8 {mcload} -setup {
+	    variable locale [mclocale]
+	    mclocale foo_BAR_baz
+	    mcload $msgdir
+	} -cleanup {
+	    mclocale $locale
+	} -body {
+	    mc abc
+	} -result abc-foo_BAR_baz
+
+	test msgcat-5.9 {mcload} -setup {
+	    variable locale [mclocale]
+	    mclocale no_FI_notexist
+	    mcload $msgdir
+	} -cleanup {
+	    mclocale $locale
+	} -body {
+	    mc abc
+	} -result abc-
+
+	test msgcat-5.10 {mcload} -setup {
+	    rename ::msgcat::mcunknown SavedMcunknown
+	    proc ::msgcat::mcunknown {dom s} {
+		return unknown:$dom:$s
+	    }
+	    variable locale [mclocale]
+	    mclocale no_FI_notexist
+	    mcload $msgdir
+	} -cleanup {
+	    mclocale $locale
+	    rename ::msgcat::mcunknown {}
+	    rename SavedMcunknown ::msgcat::mcunknown
+	} -body {
+	    mc def
+	} -result unknown:no_fi_notexist:def
+
+	test msgcat-5.11 {mcpackageconfig mcfolder} -setup {
+	    variable locale [mclocale]
+	    mclocale ""
+	    mcloadedlocales clear
+	    mcpackageconfig unset mcfolder
+	} -cleanup {
+	    mclocale $locale
+	    mcloadedlocales clear
+	    mcpackageconfig unset mcfolder 
+	} -body {
+	    mclocale foo
+	    mcpackageconfig set mcfolder $msgdir
+	} -result 2
+
+    foreach loc $locales {
+	if { $loc eq {} } {
+	    set msg ROOT
+        } else {
+	    set msg [string tolower $loc]
+	}
+	removeFile $msg.msg $msgdir
+    }
+    removeDirectory msgdir
+
+    # Tests msgcat-6.*: [mcset], [mc] namespace inheritance
+#
+# Test mcset and mc, ensuring that resolution for messages
+# proceeds from the current ns to its parent and so on to the 
+# global ns.
+#
+# Do this for the 12 permutations of
+#     locales: foo
+#     namespaces: foo foo::bar foo::bar::baz
+#     strings: {ov1 ov2 ov3 ov4}
+#     namespace ::foo            defines ov1, ov2, ov3
+#     namespace ::foo::bar       defines      ov2, ov3
+#     namespace ::foo::bar::baz  defines           ov3
+#
+#     ov4 is not defined in any namespace.
+#
+# So,
+#     ov3 should be resolved in ::foo::bar::baz, ::foo::bar, ::foo;
+#     ov2 should be resolved in ::foo, ::foo::bar
+#     ov1 should be resolved in ::foo
+#     ov4 should be resolved in none, and call mcunknown
+#
+
+    variable result
+    array set result {
+	foo,ov1 ov1_foo foo,ov2 ov2_foo foo,ov3 ov3_foo foo,ov4 ov4
+	foo::bar,ov1 ov1_foo foo::bar,ov2 ov2_foo_bar
+	foo::bar,ov3 ov3_foo_bar foo::bar,ov4 ov4 foo::bar::baz,ov1 ov1_foo
+	foo::bar::baz,ov2 ov2_foo_bar foo::bar::baz,ov3 ov3_foo_bar_baz
+	foo::bar::baz,ov4 ov4
+    }
+    variable count 1
+    variable ns
+    foreach ns {foo foo::bar foo::bar::baz} {
+	foreach string {ov1 ov2 ov3 ov4} {
+	    test msgcat-6.$count {mcset, overlap} -setup {
+		namespace eval foo {
+		    ::msgcat::mcset foo ov1 ov1_foo
+		    ::msgcat::mcset foo ov2 ov2_foo
+		    ::msgcat::mcset foo ov3 ov3_foo
+		    namespace eval bar {
+			::msgcat::mcset foo ov2 ov2_foo_bar
+			::msgcat::mcset foo ov3 ov3_foo_bar
+			namespace eval baz {
+			    ::msgcat::mcset foo ov3 "ov3_foo_bar_baz"
+			}
+		    }
+		    
+		}
+		variable locale [mclocale]
+		mclocale foo
+	    } -cleanup {
+		mclocale $locale
+		namespace delete foo
+	    } -body {
+		namespace eval $ns [list ::msgcat::mc $string]
+	    } -result $result($ns,$string)
+	    incr count
+	}
+    }
+
+    # Tests msgcat-7.*: [mc] extra args processed by [format]
+
+    test msgcat-7.1 {mc extra args go through to format} -setup {
+	mcset foo format1 "this is a test"
+	mcset foo format2 "this is a %s"
+	mcset foo format3 "this is a %s %s"
+	variable locale [mclocale]
+	mclocale foo
+    } -cleanup {
+	mclocale $locale
+    } -body {
+	mc format1 "good test"
+    } -result "this is a test"
+
+    test msgcat-7.2 {mc extra args go through to format} -setup {
+	mcset foo format1 "this is a test"
+	mcset foo format2 "this is a %s"
+	mcset foo format3 "this is a %s %s"
+	variable locale [mclocale]
+	mclocale foo
+    } -cleanup {
+	mclocale $locale
+    } -body {
+	mc format2 "good test"
+    } -result "this is a good test"
+
+    test msgcat-7.3 {mc errors from format are propagated} -setup {
+	mcset foo format1 "this is a test"
+	mcset foo format2 "this is a %s"
+	mcset foo format3 "this is a %s %s"
+	variable locale [mclocale]
+	mclocale foo
+    } -cleanup {
+	mclocale $locale
+    } -body {
+	catch {mc format3 "good test"}
+    } -result 1
+
+    test msgcat-7.4 {mc, extra args are given to unknown} -setup {
+	mcset foo format1 "this is a test"
+	mcset foo format2 "this is a %s"
+	mcset foo format3 "this is a %s %s"
+	variable locale [mclocale]
+	mclocale foo
+    } -cleanup {
+	mclocale $locale
+    } -body {
+	mc "this is a %s" "good test"
+    } -result "this is a good test"
+
+    # Tests msgcat-8.*: [mcflset]
+
+    set msgdir1 [makeDirectory msgdir1]
+    makeFile {::msgcat::mcflset k1 v1} l1.msg $msgdir1
+
+	test msgcat-8.1 {mcflset} -setup {
+	    variable locale [mclocale]
+	    mclocale l1
+	    mcload $msgdir1
+	} -cleanup {
+	    mclocale $locale
+	} -body {
+	    mc k1
+	} -result v1
+
+    removeFile l1.msg $msgdir1
+    removeDirectory msgdir1
+
+    set msgdir2 [makeDirectory msgdir2]
+    set msgdir3 [makeDirectory msgdir3]
+    makeFile "::msgcat::mcflset k2 v2 ; ::msgcat::mcload [list $msgdir3]"\
+	    l2.msg $msgdir2
+    makeFile {::msgcat::mcflset k3 v3} l2.msg $msgdir3
+
+	# chained mcload
+	test msgcat-8.2 {mcflset} -setup {
+	    variable locale [mclocale]
+	    mclocale l2
+	    mcload $msgdir2
+	} -cleanup {
+	    mclocale $locale
+	} -body {
+	    return [mc k2][mc k3]
+	} -result v2v3
+
+    removeFile l2.msg $msgdir2
+    removeDirectory msgdir2
+    removeDirectory msgdir3
+
+    # Tests msgcat-9.*: [mcexists]
+
+	test msgcat-9.1 {mcexists no parameter} -body {
+	    mcexists
+	} -returnCodes 1\
+	-result {wrong # args: should be "mcexists ?-exactnamespace? ?-exactlocale? src"}
+    
+	test msgcat-9.2 {mcexists unknown option} -body {
+	    mcexists -unknown src 
+	} -returnCodes 1\
+	-result {unknown option "-unknown"}
+    
+	test msgcat-9.3 {mcexists} -setup {
+	    mcforgetpackage
+	    variable locale [mclocale]
+	    mclocale foo
+	    mcset foo k1 v1
+	} -cleanup {
+	    mclocale $locale
+	} -body {
+	    list [mcexists k1] [mcexists k2]
+	} -result {1 0}
+
+	test msgcat-9.4 {mcexists descendent preference} -setup {
+	    mcforgetpackage
+	    variable locale [mclocale]
+	    mclocale foo_bar
+	    mcset foo k1 v1
+	} -cleanup {
+	    mclocale $locale
+	} -body {
+	    list [mcexists k1] [mcexists -exactlocale k1]
+	} -result {1 0}
+    
+	test msgcat-9.5 {mcexists parent namespace} -setup {
+	    mcforgetpackage
+	    variable locale [mclocale]
+	    mclocale foo_bar
+	    mcset foo k1 v1
+	} -cleanup {
+	    mclocale $locale
+	} -body {
+	    namespace eval ::msgcat::test::sub {
+		list [::msgcat::mcexists k1]\
+			[::msgcat::mcexists -exactnamespace k1]
+	    }
+	} -result {1 0}
+    
+    # Tests msgcat-10.*: [mcloadedlocales]
+
+	test msgcat-10.1 {mcloadedlocales no arg} -body {
+	    mcloadedlocales
+	} -returnCodes 1\
+	-result {wrong # args: should be "mcloadedlocales subcommand"}
+    
+	test msgcat-10.2 {mcloadedlocales wrong subcommand} -body {
+	    mcloadedlocales junk
+	} -returnCodes 1\
+	-result {unknown subcommand "junk": must be clear, or loaded}
+    
+	test msgcat-10.3 {mcloadedlocales loaded} -setup {
+	    mcforgetpackage
+	    variable locale [mclocale]
+	    mclocale {}
+	    mcloadedlocales clear
+	} -cleanup {
+	    mclocale $locale
+	} -body {
+	    mclocale foo_bar
+	    # The result is position independent so sort
+	    set resultlist [lsort [mcloadedlocales loaded]]
+	} -result {{} foo foo_bar}
+    
+	test msgcat-10.4 {mcloadedlocales clear} -setup {
+	    mcforgetpackage
+	    variable locale [mclocale]
+	    mclocale {}
+	    mcloadedlocales clear
+	} -cleanup {
+	    mclocale $locale
+	} -body {
+	    mclocale foo
+	    mcset foo k1 v1
+	    set res [mcexists k1]
+	    mclocale ""
+	    mcloadedlocales clear
+	    mclocale foo
+	    lappend res [mcexists k1]
+	} -result {1 0}
+
+    # Tests msgcat-11.*: [mcforgetpackage]
+
+	test msgcat-11.1 {mcforgetpackage translation} -setup {
+	    variable locale [mclocale]
+	} -cleanup {
+	    mclocale $locale
+	} -body {
+	    mclocale foo
+	    mcset foo k1 v1
+	    set res [mcexists k1]
+	    mcforgetpackage
+	    lappend res [mcexists k1]
+	} -result {1 0}
+
+	test msgcat-11.2 {mcforgetpackage locale} -setup {
+	    variable locale [mclocale]
+	} -cleanup {
+	    mclocale $locale
+	} -body {
+	    mclocale foo
+	    mcpackagelocale set bar
+	    set res [mcpackagelocale get]
+	    mcforgetpackage
+	    lappend res [mcpackagelocale get]
+	} -result {bar foo}
+
+	test msgcat-11.3 {mcforgetpackage options} -body {
+	    mcpackageconfig set loadcmd ""
+	    set res [mcpackageconfig isset loadcmd]
+	    mcforgetpackage
+	    lappend res [mcpackageconfig isset loadcmd]
+	} -result {1 0}
+
+    # Tests msgcat-12.*: [mcpackagelocale]
+
+	test msgcat-12.1 {mcpackagelocale no subcommand} -body {
+	    mcpackagelocale
+	} -returnCodes 1\
+	-result {wrong # args: should be "mcpackagelocale subcommand ?locale?"}
+
+	test msgcat-12.2 {mclpackagelocale wrong subcommand} -body {
+	    mcpackagelocale junk
+	} -returnCodes 1\
+	-result {unknown subcommand "junk": must be clear, get, isset, loaded, present, set, or unset}
+
+	test msgcat-12.3 {mcpackagelocale set} -setup {
+	    variable locale [mclocale]
+	} -cleanup {
+	    mclocale $locale
+	    mcforgetpackage
+	} -body {
+	    mclocale foo
+	    mcpackagelocale set bar
+	    list [mcpackagelocale get] [mclocale]
+	} -result {bar foo}
+
+	test msgcat-12.4 {mcpackagelocale get} -setup {
+	    variable locale [mclocale]
+	} -cleanup {
+	    mclocale $locale
+	    mcforgetpackage
+	} -body {
+	    mclocale foo
+	    set res [mcpackagelocale get]
+	    mcpackagelocale set bar
+	    lappend res [mcpackagelocale get]
+	} -result {foo bar}
+
+	test msgcat-12.5 {mcpackagelocale preferences} -setup {
+	    variable locale [mclocale]
+	} -cleanup {
+	    mclocale $locale
+	    mcforgetpackage
+	} -body {
+	    mclocale foo
+	    set res [list [mcpackagelocale preferences]]
+	    mcpackagelocale set bar
+	    lappend res [mcpackagelocale preferences]
+	} -result {{foo {}} {bar {}}}
+
+	test msgcat-12.6 {mcpackagelocale loaded} -setup {
+	    variable locale [mclocale]
+	} -cleanup {
+	    mclocale $locale
+	    mcforgetpackage
+	} -body {
+	    mclocale ""
+	    mcloadedlocales clear
+	    mclocale foo
+	    # The result is position independent so sort
+	    set res [list [lsort [mcpackagelocale loaded]]]
+	    mcpackagelocale set bar
+	    lappend res [lsort [mcpackagelocale loaded]]
+	} -result {{{} foo} {{} bar foo}}
+
+	test msgcat-12.7 {mcpackagelocale isset} -setup {
+	    variable locale [mclocale]
+	} -cleanup {
+	    mclocale $locale
+	    mcforgetpackage
+	} -body {
+	    mclocale foo
+	    set res [mcpackagelocale isset]
+	    mcpackagelocale set bar
+	    lappend res [mcpackagelocale isset]
+	} -result {0 1}
+
+	test msgcat-12.8 {mcpackagelocale unset} -setup {
+	    variable locale [mclocale]
+	} -cleanup {
+	    mclocale $locale
+	    mcforgetpackage
+	} -body {
+	    mcpackagelocale set bar
+	    set res [mcpackagelocale isset]
+	    mcpackagelocale unset
+	    lappend res [mcpackagelocale isset]
+	} -result {1 0}
+
+	test msgcat-12.9 {mcpackagelocale present} -setup {
+	    variable locale [mclocale]
+	} -cleanup {
+	    mclocale $locale
+	    mcforgetpackage
+	} -body {
+	    mclocale ""
+	    mcloadedlocales clear
+	    mclocale foo
+	    set res [mcpackagelocale present foo]
+	    lappend res [mcpackagelocale present bar]
+	    mcpackagelocale set bar
+	    lappend res [mcpackagelocale present foo]\
+		    [mcpackagelocale present bar]
+	} -result {1 0 1 1}
+
+	test msgcat-12.10 {mcpackagelocale clear} -setup {
+	    variable locale [mclocale]
+	} -cleanup {
+	    mclocale $locale
+	    mcforgetpackage
+	} -body {
+	    mclocale ""
+	    mcloadedlocales clear
+	    mclocale foo
+	    mcpackagelocale set bar
+	    mcpackagelocale clear
+	    list [mcpackagelocale present foo] [mcpackagelocale present bar]
+	} -result {0 1}
+
+    # Tests msgcat-13.*: [mcpackageconfig subcmds]
+
+	test msgcat-13.1 {mcpackageconfig no subcommand} -body {
+	    mcpackageconfig
+	} -returnCodes 1\
+	-result {wrong # args: should be "mcpackageconfig subcommand option ?value?"}
+
+	test msgcat-13.2 {mclpackageconfig wrong subcommand} -body {
+	    mcpackageconfig junk mcfolder
+	} -returnCodes 1\
+	-result {unknown subcommand "junk": must be get, isset, set, or unset}
+
+	test msgcat-13.3 {mclpackageconfig wrong option} -body {
+	    mcpackageconfig get junk
+	} -returnCodes 1\
+	-result {bad option "junk": must be mcfolder, loadcmd, changecmd, or unknowncmd}
+
+	test msgcat-13.4 {mcpackageconfig get} -setup {
+	    mcforgetpackage
+	} -cleanup {
+	    mcforgetpackage
+	} -body {
+	    mcpackageconfig set loadcmd ""
+	    mcpackageconfig get loadcmd
+	} -result {}
+
+	test msgcat-13.5 {mcpackageconfig (is/un)set} -setup {
+	    mcforgetpackage
+	} -cleanup {
+	    mcforgetpackage
+	} -body {
+	    set res [mcpackageconfig isset loadcmd]
+	    lappend res [mcpackageconfig set loadcmd ""]
+	    lappend res [mcpackageconfig isset loadcmd]
+	    mcpackageconfig unset loadcmd
+	    lappend res [mcpackageconfig isset loadcmd]
+	} -result {0 0 1 0}
+
+    # option mcfolder is already tested with 5.11
+    
+    # Tests msgcat-14.*: callbacks: loadcmd, changecmd, unknowncmd
+    
+    # This routine is used as bgerror and by direct callback invocation
+    proc callbackproc args {
+	variable resultvariable
+	set resultvariable $args
+    }
+    proc callbackfailproc args {
+	return -code error fail
+    }
+    set bgerrorsaved [interp bgerror {}]
+    interp bgerror {} [namespace code callbackproc]
+
+    variable locale
+    if {![info exist locale]} { set locale [mclocale] }
+
+	test msgcat-14.1 {invokation loadcmd} -setup {
+	    mcforgetpackage
+    	    mclocale $locale
+	    mclocale ""
+	    mcloadedlocales clear
+	    set resultvariable ""
+	} -cleanup {
+	    mcforgetpackage
+	} -body {
+	    mcpackageconfig set loadcmd [namespace code callbackproc]
+	    mclocale foo_bar
+	    lsort $resultvariable
+	} -result {foo foo_bar}
+
+	test msgcat-14.2 {invokation failed in loadcmd} -setup {
+	    mcforgetpackage
+    	    mclocale $locale
+	    mclocale ""
+	    mcloadedlocales clear
+	} -cleanup {
+	    mcforgetpackage
+	    after cancel set [namespace current]::resultvariable timeout
+	} -body {
+	    mcpackageconfig set loadcmd [namespace code callbackfailproc]
+	    mclocale foo_bar
+	    # let the bgerror run
+	    after 100 set [namespace current]::resultvariable timeout
+	    vwait [namespace current]::resultvariable
+	    lassign $resultvariable err errdict
+	    list $err [dict get $errdict -code]
+	} -result {fail 1}
+
+	test msgcat-14.3 {invokation changecmd} -setup {
+	    mcforgetpackage
+    	    mclocale $locale
+	    mclocale ""
+	    set resultvariable ""
+	} -cleanup {
+	    mcforgetpackage
+	} -body {
+	    mcpackageconfig set changecmd [namespace code callbackproc]
+	    mclocale foo_bar
+	    set resultvariable
+	} -result {foo_bar foo {}}
+
+	test msgcat-14.4 {invokation unknowncmd} -setup {
+	    mcforgetpackage
+    	    mclocale $locale
+	    mclocale ""
+	    mcloadedlocales clear
+	    set resultvariable ""
+	} -cleanup {
+	    mcforgetpackage
+	} -body {
+	    mcpackageconfig set unknowncmd [namespace code callbackproc]
+	    mclocale foo_bar
+	    mc k1 p1
+	    set resultvariable
+	} -result {foo_bar k1 p1}
+
+	test msgcat-14.5 {disable global unknowncmd} -setup {
+	    mcforgetpackage
+    	    mclocale $locale
+	    mclocale ""
+	    mcloadedlocales clear
+	    set resultvariable ""
+	    rename ::msgcat::mcunknown SavedMcunknown
+	    proc ::msgcat::mcunknown {dom s} {
+		return unknown:$dom:$s
+	    }
+	} -cleanup {
+	    mcforgetpackage
+	    rename ::msgcat::mcunknown {}
+	    rename SavedMcunknown ::msgcat::mcunknown
+	} -body {
+	    mcpackageconfig set unknowncmd ""
+	    mclocale foo_bar
+	    mc k1%s p1
+	} -result {k1p1}
+
+	test msgcat-14.6 {unknowncmd failing} -setup {
+	    mcforgetpackage
+    	    mclocale $locale
+	    mclocale ""
+	    mcloadedlocales clear
+	    set resultvariable ""
+	} -cleanup {
+	    mcforgetpackage
+	} -body {
+	    mcpackageconfig set unknowncmd [namespace code callbackfailproc]
+	    mclocale foo_bar
+	    mc k1
+	} -returnCodes 1\
+	-result {fail}
+
+    interp bgerror {} $bgerrorsaved
+
+    cleanupTests
+}
+namespace delete ::msgcat::test
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/tests/namespace-old.test b/tests/namespace-old.test
new file mode 100644
index 0000000..1d6a805
--- /dev/null
+++ b/tests/namespace-old.test
@@ -0,0 +1,861 @@
+# Functionality covered: this file contains slightly modified versions of
+# the original tests written by Mike McLennan of Lucent Technologies for
+# the procedures in tclNamesp.c that implement Tcl's basic support for
+# namespaces. Other namespace-related tests appear in namespace.test
+# and variable.test.
+#
+# Sourcing this file into Tcl runs the tests and generates output for
+# errors. No output means no errors were found.
+#
+# Copyright (c) 1997 Sun Microsystems, Inc.
+# Copyright (c) 1997 Lucent Technologies
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {"::tcltest" ni [namespace children]} {
+    package require tcltest 2.2
+    namespace import -force ::tcltest::*
+}
+
+# Clear out any namespaces called test_ns_*
+catch {namespace delete {*}[namespace children :: test_ns_*]}
+
+test namespace-old-1.1 {usage for "namespace" command} {
+    list [catch {namespace} msg] $msg
+} {1 {wrong # args: should be "namespace subcommand ?arg ...?"}}
+test namespace-old-1.2 {global namespace's name is "::" or {}} {
+    list [namespace current] [namespace eval {} {namespace current}]
+} {:: ::}
+test namespace-old-1.3 {usage for "namespace eval"} {
+    list [catch {namespace eval} msg] $msg
+} {1 {wrong # args: should be "namespace eval name arg ?arg...?"}}
+test namespace-old-1.4 {create new namespaces} {
+    list [lsort [namespace children :: test_ns_simple*]] \
+	 [namespace eval test_ns_simple {}] \
+	 [namespace eval test_ns_simple2 {}] \
+         [lsort [namespace children :: test_ns_simple*]]
+} {{} {} {} {::test_ns_simple ::test_ns_simple2}}
+test namespace-old-1.5 {access a new namespace} {
+    namespace eval test_ns_simple { namespace current }
+} {::test_ns_simple}
+test namespace-old-1.6 {usage for "namespace eval"} {
+    list [catch {namespace eval} msg] $msg
+} {1 {wrong # args: should be "namespace eval name arg ?arg...?"}}
+test namespace-old-1.7 {usage for "namespace eval"} {
+    list [catch {namespace eval test_ns_xyzzy} msg] $msg
+} {1 {wrong # args: should be "namespace eval name arg ?arg...?"}}
+test namespace-old-1.8 {command "namespace eval" concatenates args} {
+    namespace eval test_ns_simple namespace current
+} {::test_ns_simple}
+test namespace-old-1.9 {add elements to a namespace} {
+    namespace eval test_ns_simple {
+        variable test_ns_x 0
+        proc test {test_ns_x} {
+            return "test: $test_ns_x"
+        }
+    }
+} {}
+namespace eval test_ns_simple {
+    variable test_ns_x 0
+    proc test {test_ns_x} {
+	return "test: $test_ns_x"
+    }
+}
+test namespace-old-1.10 {commands in a namespace} {
+    namespace eval test_ns_simple { info commands [namespace current]::*}
+} {::test_ns_simple::test}
+test namespace-old-1.11 {variables in a namespace} {
+    namespace eval test_ns_simple { info vars [namespace current]::* }
+} {::test_ns_simple::test_ns_x}
+test namespace-old-1.12 {global vars are separate from locals vars} {
+    list [test_ns_simple::test 123] [set test_ns_simple::test_ns_x]
+} {{test: 123} 0}
+test namespace-old-1.13 {add to an existing namespace} {
+    namespace eval test_ns_simple {
+        variable test_ns_y 123
+        proc _backdoor {cmd} {
+            eval $cmd
+        }
+    }
+} ""
+namespace eval test_ns_simple {
+    variable test_ns_y 123
+    proc _backdoor {cmd} {
+	eval $cmd
+    }
+}
+test namespace-old-1.14 {commands in a namespace} {
+    lsort [namespace eval test_ns_simple {info commands [namespace current]::*}]
+} {::test_ns_simple::_backdoor ::test_ns_simple::test}
+test namespace-old-1.15 {variables in a namespace} {
+    lsort [namespace eval test_ns_simple {info vars [namespace current]::*}]
+} {::test_ns_simple::test_ns_x ::test_ns_simple::test_ns_y}
+test namespace-old-1.16 {variables in a namespace} {
+    lsort [info vars test_ns_simple::*]
+} {::test_ns_simple::test_ns_x ::test_ns_simple::test_ns_y}
+test namespace-old-1.17 {commands in a namespace are hidden} {
+    list [catch "_backdoor {return yes!}" msg] $msg
+} {1 {invalid command name "_backdoor"}}
+test namespace-old-1.18 {using namespace qualifiers} {
+    list [catch "test_ns_simple::_backdoor {return yes!}" msg] $msg
+} {0 yes!}
+test namespace-old-1.19 {using absolute namespace qualifiers} {
+    list [catch "::test_ns_simple::_backdoor {return yes!}" msg] $msg
+} {0 yes!}
+test namespace-old-1.20 {variables in a namespace are hidden} {
+    list [catch "set test_ns_x" msg] $msg [catch "set test_ns_y" msg] $msg
+} {1 {can't read "test_ns_x": no such variable} 1 {can't read "test_ns_y": no such variable}}
+test namespace-old-1.21 {using namespace qualifiers} {
+    list [catch "set test_ns_simple::test_ns_x" msg] $msg \
+         [catch "set test_ns_simple::test_ns_y" msg] $msg
+} {0 0 0 123}
+test namespace-old-1.22 {using absolute namespace qualifiers} {
+    list [catch "set ::test_ns_simple::test_ns_x" msg] $msg \
+         [catch "set ::test_ns_simple::test_ns_y" msg] $msg
+} {0 0 0 123}
+test namespace-old-1.23 {variables can be accessed within a namespace} {
+    test_ns_simple::_backdoor {
+        variable test_ns_x
+        variable test_ns_y
+        return "$test_ns_x $test_ns_y"
+    }
+} {0 123}
+test namespace-old-1.24 {setting global variables} {
+    test_ns_simple::_backdoor {variable test_ns_x;  set test_ns_x "new val"}
+    namespace eval test_ns_simple {set test_ns_x}
+} {new val}
+test namespace-old-1.25 {qualified variables don't need a global declaration} {
+    namespace eval test_ns_another { variable test_ns_x 456 }
+    set cmd {set ::test_ns_another::test_ns_x}
+    list [catch {test_ns_simple::_backdoor "$cmd some-value"} msg] $msg \
+         [eval $cmd]
+} {0 some-value some-value}
+test namespace-old-1.26 {namespace qualifiers are okay after $'s} {
+    namespace eval test_ns_simple { set test_ns_x 12; set test_ns_y 34 }
+    set cmd {list $::test_ns_simple::test_ns_x $::test_ns_simple::test_ns_y}
+    list [test_ns_simple::_backdoor $cmd] [eval $cmd]
+} {{12 34} {12 34}}
+test namespace-old-1.27 {can create commands with null names} {
+    proc test_ns_simple:: {args} {return $args}
+} {}
+# Redeclare; later tests depend on it
+proc test_ns_simple:: {args} {return $args}
+
+# -----------------------------------------------------------------------
+# TEST: using "info" in namespace contexts
+# -----------------------------------------------------------------------
+test namespace-old-2.1 {querying:  info commands} {
+    lsort [test_ns_simple::_backdoor {info commands [namespace current]::*}]
+} {::test_ns_simple:: ::test_ns_simple::_backdoor ::test_ns_simple::test}
+test namespace-old-2.2 {querying:  info procs} {
+    lsort [test_ns_simple::_backdoor {info procs}]
+} {{} _backdoor test}
+test namespace-old-2.3 {querying:  info vars} {
+    lsort [info vars test_ns_simple::*]
+} {::test_ns_simple::test_ns_x ::test_ns_simple::test_ns_y}
+test namespace-old-2.4 {querying:  info vars} {
+    lsort [test_ns_simple::_backdoor {info vars [namespace current]::*}]
+} {::test_ns_simple::test_ns_x ::test_ns_simple::test_ns_y}
+test namespace-old-2.5 {querying:  info locals} {
+    lsort [test_ns_simple::_backdoor {info locals}]
+} {cmd}
+test namespace-old-2.6 {querying:  info exists} {
+    test_ns_simple::_backdoor {info exists test_ns_x}
+} {0}
+test namespace-old-2.7 {querying:  info exists} {
+    test_ns_simple::_backdoor {info exists cmd}
+} {1}
+test namespace-old-2.8 {querying:  info args} {
+    info args test_ns_simple::_backdoor
+} {cmd}
+test namespace-old-2.9 {querying:  info body} {
+    string trim [info body test_ns_simple::test]
+} {return "test: $test_ns_x"}
+
+# -----------------------------------------------------------------------
+# TEST: namespace qualifiers, namespace tail
+# -----------------------------------------------------------------------
+test namespace-old-3.1 {usage for "namespace qualifiers"} {
+    list [catch "namespace qualifiers" msg] $msg
+} {1 {wrong # args: should be "namespace qualifiers string"}}
+test namespace-old-3.2 {querying:  namespace qualifiers} {
+    list [namespace qualifiers ""] \
+         [namespace qualifiers ::] \
+         [namespace qualifiers x] \
+         [namespace qualifiers ::x] \
+         [namespace qualifiers foo::x] \
+         [namespace qualifiers ::foo::bar::xyz]
+} {{} {} {} {} foo ::foo::bar}
+test namespace-old-3.3 {usage for "namespace tail"} {
+    list [catch "namespace tail" msg] $msg
+} {1 {wrong # args: should be "namespace tail string"}}
+test namespace-old-3.4 {querying:  namespace tail} {
+    list [namespace tail ""] \
+         [namespace tail ::] \
+         [namespace tail x] \
+         [namespace tail ::x] \
+         [namespace tail foo::x] \
+         [namespace tail ::foo::bar::xyz]
+} {{} {} x x x xyz}
+
+# -----------------------------------------------------------------------
+# TEST: delete commands and namespaces
+# -----------------------------------------------------------------------
+test namespace-old-4.1 {define test namespaces} {
+    namespace eval test_ns_delete {
+        namespace eval ns1 {
+            variable var1 1
+            proc cmd1 {} {return "cmd1"}
+        }
+        namespace eval ns2 {
+            variable var2 2
+            proc cmd2 {} {return "cmd2"}
+        }
+        namespace eval another {}
+        lsort [namespace children]
+    }
+} {::test_ns_delete::another ::test_ns_delete::ns1 ::test_ns_delete::ns2}
+test namespace-old-4.2 {it's okay to invoke "namespace delete" with no args} {
+    list [catch {namespace delete} msg] $msg
+} {0 {}}
+test namespace-old-4.3 {command "namespace delete" doesn't support patterns} {
+    set cmd {
+        namespace eval test_ns_delete {namespace delete ns*}
+    }
+    list [catch $cmd msg] $msg
+} {1 {unknown namespace "ns*" in namespace delete command}}
+namespace eval test_ns_delete {
+    namespace eval ns1 {}
+    namespace eval ns2 {}
+    namespace eval another {}
+}
+test namespace-old-4.4 {command "namespace delete" handles multiple args} {
+    set cmd {
+        namespace eval test_ns_delete {
+            namespace delete \
+                {*}[namespace children [namespace current] ns?]
+        }
+    }
+    list [catch $cmd msg] $msg [namespace children test_ns_delete]
+} {0 {} ::test_ns_delete::another}
+
+# -----------------------------------------------------------------------
+# TEST: namespace hierarchy
+# -----------------------------------------------------------------------
+test namespace-old-5.1 {define nested namespaces} {
+    set test_ns_var_global "var in ::"
+    proc test_ns_cmd_global {} {return "cmd in ::"}
+    namespace eval test_ns_hier1 {
+        set test_ns_var_hier1 "particular to hier1"
+        proc test_ns_cmd_hier1 {} {return "particular to hier1"}
+        set test_ns_level 1
+        proc test_ns_show {} {return "[namespace current]: 1"}
+        namespace eval test_ns_hier2 {
+            set test_ns_var_hier2 "particular to hier2"
+            proc test_ns_cmd_hier2 {} {return "particular to hier2"}
+            set test_ns_level 2
+            proc test_ns_show {} {return "[namespace current]: 2"}
+            namespace eval test_ns_hier3a {}
+            namespace eval test_ns_hier3b {}
+        }
+        namespace eval test_ns_hier2a {}
+        namespace eval test_ns_hier2b {}
+    }
+} {}
+test namespace-old-5.2 {namespaces can be nested} {
+    list [namespace eval test_ns_hier1 {namespace current}] \
+         [namespace eval test_ns_hier1 {
+              namespace eval test_ns_hier2 {namespace current}
+          }]
+} {::test_ns_hier1 ::test_ns_hier1::test_ns_hier2}
+test namespace-old-5.3 {namespace qualifiers work in namespace command} {
+    list [namespace eval ::test_ns_hier1 {namespace current}] \
+         [namespace eval test_ns_hier1::test_ns_hier2 {namespace current}] \
+         [namespace eval ::test_ns_hier1::test_ns_hier2 {namespace current}]
+} {::test_ns_hier1 ::test_ns_hier1::test_ns_hier2 ::test_ns_hier1::test_ns_hier2}
+set ::test_ns_var_global "var in ::"
+proc test_ns_cmd_global {} {return "cmd in ::"}
+namespace eval test_ns_hier1 {
+    variable test_ns_var_hier1 "particular to hier1"
+    proc test_ns_cmd_hier1 {} {return "particular to hier1"}
+    variable test_ns_level 1
+    proc test_ns_show {} {return "[namespace current]: 1"}
+    namespace eval test_ns_hier2 {
+	variable test_ns_var_hier2 "particular to hier2"
+	proc test_ns_cmd_hier2 {} {return "particular to hier2"}
+	variable test_ns_level 2
+        proc test_ns_show {} {return "[namespace current]: 2"}
+	namespace eval test_ns_hier3a {}
+	namespace eval test_ns_hier3b {}
+    }
+    namespace eval test_ns_hier2a {}
+    namespace eval test_ns_hier2b {}
+}
+test namespace-old-5.4 {nested namespaces can access global namespace} {
+    list [namespace eval test_ns_hier1 {set test_ns_var_global}] \
+         [namespace eval test_ns_hier1 {test_ns_cmd_global}] \
+         [namespace eval test_ns_hier1::test_ns_hier2 {set test_ns_var_global}] \
+         [namespace eval test_ns_hier1::test_ns_hier2 {test_ns_cmd_global}]
+} {{var in ::} {cmd in ::} {var in ::} {cmd in ::}}
+test namespace-old-5.5 {variables in different namespaces don't conflict} {
+    list [set test_ns_hier1::test_ns_level] \
+         [set test_ns_hier1::test_ns_hier2::test_ns_level]
+} {1 2}
+test namespace-old-5.6 {commands in different namespaces don't conflict} {
+    list [test_ns_hier1::test_ns_show] \
+         [test_ns_hier1::test_ns_hier2::test_ns_show]
+} {{::test_ns_hier1: 1} {::test_ns_hier1::test_ns_hier2: 2}}
+test namespace-old-5.7 {nested namespaces don't see variables in parent} {
+    set cmd {
+        namespace eval test_ns_hier1::test_ns_hier2 {set test_ns_var_hier1}
+    }
+    list [catch $cmd msg] $msg
+} {1 {can't read "test_ns_var_hier1": no such variable}}
+test namespace-old-5.8 {nested namespaces don't see commands in parent} {
+    set cmd {
+        namespace eval test_ns_hier1::test_ns_hier2 {test_ns_cmd_hier1}
+    }
+    list [catch $cmd msg] $msg
+} {1 {invalid command name "test_ns_cmd_hier1"}}
+test namespace-old-5.9 {usage for "namespace children"} {
+    list [catch {namespace children test_ns_hier1 y z} msg] $msg
+} {1 {wrong # args: should be "namespace children ?name? ?pattern?"}}
+test namespace-old-5.10 {command "namespace children" must get valid namespace} -body {
+    namespace children xyzzy
+} -returnCodes error -result {namespace "xyzzy" not found in "::"}
+test namespace-old-5.11 {querying namespace children} {
+    lsort [namespace children :: test_ns_hier*]
+} {::test_ns_hier1}
+test namespace-old-5.12 {querying namespace children} {
+    lsort [namespace children test_ns_hier1]
+} {::test_ns_hier1::test_ns_hier2 ::test_ns_hier1::test_ns_hier2a ::test_ns_hier1::test_ns_hier2b}
+test namespace-old-5.13 {querying namespace children} {
+    lsort [namespace eval test_ns_hier1 {namespace children}]
+} {::test_ns_hier1::test_ns_hier2 ::test_ns_hier1::test_ns_hier2a ::test_ns_hier1::test_ns_hier2b}
+test namespace-old-5.14 {querying namespace children} {
+    lsort [namespace children test_ns_hier1::test_ns_hier2]
+} {::test_ns_hier1::test_ns_hier2::test_ns_hier3a ::test_ns_hier1::test_ns_hier2::test_ns_hier3b}
+test namespace-old-5.15 {querying namespace children} {
+    lsort [namespace eval test_ns_hier1::test_ns_hier2 {namespace children}]
+} {::test_ns_hier1::test_ns_hier2::test_ns_hier3a ::test_ns_hier1::test_ns_hier2::test_ns_hier3b}
+test namespace-old-5.16 {querying namespace children with patterns} {
+    lsort [namespace children test_ns_hier1::test_ns_hier2 test_ns_*]
+} {::test_ns_hier1::test_ns_hier2::test_ns_hier3a ::test_ns_hier1::test_ns_hier2::test_ns_hier3b}
+test namespace-old-5.17 {querying namespace children with patterns} {
+    lsort [namespace children test_ns_hier1::test_ns_hier2 *b]
+} {::test_ns_hier1::test_ns_hier2::test_ns_hier3b}
+test namespace-old-5.18 {usage for "namespace parent"} {
+    list [catch {namespace parent x y} msg] $msg
+} {1 {wrong # args: should be "namespace parent ?name?"}}
+test namespace-old-5.19 {command "namespace parent" must get valid namespace} -body {
+    namespace parent xyzzy
+} -returnCodes error -result {namespace "xyzzy" not found in "::"}
+test namespace-old-5.20 {querying namespace parent} {
+    list [namespace eval :: {namespace parent}] \
+        [namespace eval test_ns_hier1 {namespace parent}] \
+        [namespace eval test_ns_hier1::test_ns_hier2 {namespace parent}] \
+        [namespace eval test_ns_hier1::test_ns_hier2::test_ns_hier3a {namespace parent}] \
+} {{} :: ::test_ns_hier1 ::test_ns_hier1::test_ns_hier2}
+test namespace-old-5.21 {querying namespace parent for explicit namespace} {
+    list [namespace parent ::] \
+         [namespace parent test_ns_hier1] \
+         [namespace parent test_ns_hier1::test_ns_hier2] \
+         [namespace parent test_ns_hier1::test_ns_hier2::test_ns_hier3a]
+} {{} :: ::test_ns_hier1 ::test_ns_hier1::test_ns_hier2}
+
+# -----------------------------------------------------------------------
+# TEST: name resolution and caching
+# -----------------------------------------------------------------------
+set trigger {namespace eval test_ns_cache2 {namespace current}}
+set trigger2 {namespace eval test_ns_cache2::test_ns_cache3 {namespace current}}
+test namespace-old-6.1 {relative ns names only looked up in current ns} {
+    namespace eval test_ns_cache1 {}
+    namespace eval test_ns_cache2 {}
+    namespace eval test_ns_cache2::test_ns_cache3 {}
+    list [namespace eval test_ns_cache1 $trigger] \
+         [namespace eval test_ns_cache1 $trigger2]
+} {::test_ns_cache1::test_ns_cache2 ::test_ns_cache1::test_ns_cache2::test_ns_cache3}
+test namespace-old-6.2 {relative ns names only looked up in current ns} {
+    namespace eval test_ns_cache1::test_ns_cache2 {}
+    list [namespace eval test_ns_cache1 $trigger] \
+         [namespace eval test_ns_cache1 $trigger2]
+} {::test_ns_cache1::test_ns_cache2 ::test_ns_cache1::test_ns_cache2::test_ns_cache3}
+test namespace-old-6.3 {relative ns names only looked up in current ns} {
+    namespace eval test_ns_cache1::test_ns_cache2::test_ns_cache3 {}
+    list [namespace eval test_ns_cache1 $trigger] \
+         [namespace eval test_ns_cache1 $trigger2]
+} {::test_ns_cache1::test_ns_cache2 ::test_ns_cache1::test_ns_cache2::test_ns_cache3}
+namespace eval test_ns_cache1::test_ns_cache2 {}
+test namespace-old-6.4 {relative ns names only looked up in current ns} {
+    namespace delete test_ns_cache1::test_ns_cache2
+    list [namespace eval test_ns_cache1 $trigger] \
+         [namespace eval test_ns_cache1 $trigger2]
+} {::test_ns_cache1::test_ns_cache2 ::test_ns_cache1::test_ns_cache2::test_ns_cache3}
+namespace eval test_ns_cache1 {
+    proc trigger {} {test_ns_cache_cmd}
+}
+test namespace-old-6.5 {define test commands} {
+    proc test_ns_cache_cmd {} {
+        return "global version"
+    }
+    test_ns_cache1::trigger
+} {global version}
+test namespace-old-6.6 {one-level check for command shadowing} {
+    proc test_ns_cache1::test_ns_cache_cmd {} {
+        return "cache1 version"
+    }
+    test_ns_cache1::trigger
+} {cache1 version}
+proc test_ns_cache_cmd {} {
+    return "global version"
+}
+test namespace-old-6.7 {renaming commands changes command epoch} -setup {
+    proc test_ns_cache1::test_ns_cache_cmd {} {
+        return "cache1 version"
+    }
+} -body {
+    list [test_ns_cache1::trigger] \
+	[namespace eval test_ns_cache1 {rename test_ns_cache_cmd test_ns_new}]\
+	[test_ns_cache1::trigger]
+} -result {{cache1 version} {} {global version}}
+test namespace-old-6.8 {renaming back handles shadowing} -setup {
+    proc test_ns_cache1::test_ns_new {} {
+        return "cache1 version"
+    }
+} -body {
+    list [test_ns_cache1::trigger] \
+	[namespace eval test_ns_cache1 {rename test_ns_new test_ns_cache_cmd}]\
+	[test_ns_cache1::trigger]
+} -result {{global version} {} {cache1 version}}
+test namespace-old-6.9 {deleting commands changes command epoch} -setup {
+    proc test_ns_cache1::test_ns_cache_cmd {} {
+        return "cache1 version"
+    }
+} -body {
+    list [test_ns_cache1::trigger] \
+	[namespace eval test_ns_cache1 {rename test_ns_cache_cmd ""}] \
+	[test_ns_cache1::trigger]
+} -result {{cache1 version} {} {global version}}
+test namespace-old-6.10 {define test namespaces} {
+    namespace eval test_ns_cache2 {
+        proc test_ns_cache_cmd {} {
+            return "global cache2 version"
+        }
+    }
+    namespace eval test_ns_cache1 {
+        proc trigger {} {
+            test_ns_cache2::test_ns_cache_cmd
+        }
+    }
+    namespace eval test_ns_cache1::test_ns_cache2 {
+        proc trigger {} {
+            test_ns_cache_cmd
+        }
+    }
+    list [test_ns_cache1::trigger] [test_ns_cache1::test_ns_cache2::trigger]
+} {{global cache2 version} {global version}}
+namespace eval test_ns_cache1 {
+    proc trigger {} { test_ns_cache2::test_ns_cache_cmd }
+    namespace eval test_ns_cache2 {
+	proc trigger {} { test_ns_cache_cmd }
+    }
+}
+test namespace-old-6.11 {commands affect all parent namespaces} {
+    proc test_ns_cache1::test_ns_cache2::test_ns_cache_cmd {} {
+        return "cache2 version"
+    }
+    list [test_ns_cache1::trigger] [test_ns_cache1::test_ns_cache2::trigger]
+} {{cache2 version} {cache2 version}}
+test namespace-old-6.12 {define test variables} {
+    variable test_ns_cache_var "global version"
+    set trigger {set test_ns_cache_var}
+    namespace eval test_ns_cache1 $trigger
+} {global version}
+    set trigger {set test_ns_cache_var}
+test namespace-old-6.13 {one-level check for variable shadowing} {
+    namespace eval test_ns_cache1 {
+        variable test_ns_cache_var "cache1 version"
+    }
+    namespace eval test_ns_cache1 $trigger
+} {cache1 version}
+variable ::test_ns_cache_var "global version"
+test namespace-old-6.14 {deleting variables changes variable epoch} {
+    namespace eval test_ns_cache1 {
+        variable test_ns_cache_var "cache1 version"
+    }
+    list [namespace eval test_ns_cache1 $trigger] \
+	[namespace eval test_ns_cache1 {unset test_ns_cache_var}] \
+	[namespace eval test_ns_cache1 $trigger]
+} {{cache1 version} {} {global version}}
+test namespace-old-6.15 {define test namespaces} {
+    namespace eval test_ns_cache2 {
+        variable test_ns_cache_var "global cache2 version"
+    }
+    set trigger2 {set test_ns_cache2::test_ns_cache_var}
+    list [namespace eval test_ns_cache1 $trigger2] \
+         [namespace eval test_ns_cache1::test_ns_cache2 $trigger]
+} {{global cache2 version} {global version}}
+set trigger2 {set test_ns_cache2::test_ns_cache_var}
+test namespace-old-6.16 {public variables affect all parent namespaces} {
+    variable test_ns_cache1::test_ns_cache2::test_ns_cache_var "cache2 version"
+    list [namespace eval test_ns_cache1 $trigger2] \
+         [namespace eval test_ns_cache1::test_ns_cache2 $trigger]
+} {{cache2 version} {cache2 version}}
+test namespace-old-6.17 {usage for "namespace which"} {
+    list [catch "namespace which -baz x" msg] $msg
+} {1 {wrong # args: should be "namespace which ?-command? ?-variable? name"}}
+test namespace-old-6.18 {usage for "namespace which"} {
+    # Presume no imported command called -command ;^)
+    namespace which -command
+} {}
+test namespace-old-6.19 {querying:  namespace which -command} {
+    proc test_ns_cache1::test_ns_cache_cmd {} {
+        return "cache1 version"
+    }
+    list [namespace eval :: {namespace which test_ns_cache_cmd}] \
+         [namespace eval test_ns_cache1 {namespace which test_ns_cache_cmd}] \
+         [namespace eval :: {namespace which -command test_ns_cache_cmd}] \
+         [namespace eval test_ns_cache1 {namespace which -command test_ns_cache_cmd}]
+} {::test_ns_cache_cmd ::test_ns_cache1::test_ns_cache_cmd ::test_ns_cache_cmd ::test_ns_cache1::test_ns_cache_cmd}
+test namespace-old-6.20 {command "namespace which" may not find commands} {
+    namespace eval test_ns_cache1 {namespace which -command xyzzy}
+} {}
+variable test_ns_cache1::test_ns_cache2::test_ns_cache_var "cache2 version"
+test namespace-old-6.21 {querying:  namespace which -variable} {
+    namespace eval test_ns_cache1::test_ns_cache2 {
+        namespace which -variable test_ns_cache_var
+    }
+} {::test_ns_cache1::test_ns_cache2::test_ns_cache_var}
+test namespace-old-6.22 {command "namespace which" may not find variables} {
+    namespace eval test_ns_cache1 {namespace which -variable xyzzy}
+} {}
+
+# -----------------------------------------------------------------------
+# TEST: uplevel/upvar across namespace boundaries
+# -----------------------------------------------------------------------
+test namespace-old-7.1 {define test namespace} {
+    namespace eval test_ns_uplevel {
+        variable x 0
+        variable y 1
+        proc show_vars {num} {
+            return [uplevel $num {info vars}]
+        }
+        proc test_uplevel {num} {
+            set a 0
+            set b 1
+            namespace eval ::test_ns_uplevel " return \[show_vars $num\] "
+        }
+    }
+} {}
+namespace eval test_ns_uplevel {
+    variable x 0
+    variable y 1
+    proc show_vars {num} {
+	return [uplevel $num {info vars}]
+    }
+    proc test_uplevel {num} {
+	set a 0
+	set b 1
+	namespace eval ::test_ns_uplevel " return \[show_vars $num\] "
+    }
+}
+test namespace-old-7.2 {uplevel can access namespace call frame} {
+    list [expr {"x" in [test_ns_uplevel::test_uplevel 1]}] \
+         [expr {"y" in [test_ns_uplevel::test_uplevel 1]}]
+} {1 1}
+test namespace-old-7.3 {uplevel can go beyond namespace call frame} {
+    lsort [test_ns_uplevel::test_uplevel 2]
+} {a b num}
+test namespace-old-7.4 {uplevel can go up to global context} {
+    expr {[test_ns_uplevel::test_uplevel 3] == [info globals]}
+} {1}
+test namespace-old-7.5 {absolute call frame references work too} {
+    list [expr {"x" in [test_ns_uplevel::test_uplevel #2]}] \
+         [expr {"y" in [test_ns_uplevel::test_uplevel #2]}]
+} {1 1}
+test namespace-old-7.6 {absolute call frame references work too} {
+    lsort [test_ns_uplevel::test_uplevel #1]
+} {a b num}
+test namespace-old-7.7 {absolute call frame references work too} {
+    expr {[test_ns_uplevel::test_uplevel #0] == [info globals]}
+} {1}
+test namespace-old-7.8 {namespaces are included in the call stack} {
+    namespace eval test_ns_upvar {
+        variable scope "test_ns_upvar"
+        proc show_val {var num} {
+            upvar $num $var x
+            return $x
+        }
+        proc test_upvar {num} {
+            set scope "test_ns_upvar::test_upvar"
+            namespace eval ::test_ns_upvar " return \[show_val scope $num\] "
+        }
+    }
+} {}
+namespace eval test_ns_upvar {
+    variable scope "test_ns_upvar"
+    proc show_val {var num} {
+	upvar $num $var x
+	return $x
+    }
+    proc test_upvar {num} {
+	set scope "test_ns_upvar::test_upvar"
+	namespace eval ::test_ns_upvar " return \[show_val scope $num\] "
+    }
+}
+test namespace-old-7.9 {upvar can access namespace call frame} {
+    test_ns_upvar::test_upvar 1
+} {test_ns_upvar}
+test namespace-old-7.10 {upvar can go beyond namespace call frame} {
+    test_ns_upvar::test_upvar 2
+} {test_ns_upvar::test_upvar}
+test namespace-old-7.11 {absolute call frame references work too} {
+    test_ns_upvar::test_upvar #2
+} {test_ns_upvar}
+test namespace-old-7.12 {absolute call frame references work too} {
+    test_ns_upvar::test_upvar #1
+} {test_ns_upvar::test_upvar}
+
+# -----------------------------------------------------------------------
+# TEST: variable traces across namespace boundaries
+# -----------------------------------------------------------------------
+test namespace-old-8.1 {traces work across namespace boundaries} {
+    namespace eval test_ns_trace {
+        namespace eval foo {
+            variable x ""
+        }
+        variable status ""
+        proc monitor {name1 name2 op} {
+            variable status
+            lappend status "$op: $name1"
+        }
+        trace variable foo::x rwu [namespace code monitor]
+    }
+    set test_ns_trace::foo::x "yes!"
+    set test_ns_trace::foo::x
+    unset test_ns_trace::foo::x
+    namespace eval test_ns_trace { set status }
+} {{w: test_ns_trace::foo::x} {r: test_ns_trace::foo::x} {u: test_ns_trace::foo::x}}
+
+# -----------------------------------------------------------------------
+# TEST: imported commands
+# -----------------------------------------------------------------------
+test namespace-old-9.1 {empty "namespace export" list} {
+    list [catch "namespace export" msg] $msg
+} {0 {}}
+test namespace-old-9.2 {usage for "namespace export" command} {
+    list [catch "namespace export test_ns_trace::zzz" msg] $msg
+} {1 {invalid export pattern "test_ns_trace::zzz": pattern can't specify a namespace}}
+test namespace-old-9.3 {define test namespaces for import} {
+    namespace eval test_ns_export {
+        namespace export cmd1 cmd2 cmd3
+        proc cmd1 {args} {return "cmd1: $args"}
+        proc cmd2 {args} {return "cmd2: $args"}
+        proc cmd3 {args} {return "cmd3: $args"}
+        proc cmd4 {args} {return "cmd4: $args"}
+        proc cmd5 {args} {return "cmd5: $args"}
+        proc cmd6 {args} {return "cmd6: $args"}
+    }
+    lsort [info commands test_ns_export::*]
+} {::test_ns_export::cmd1 ::test_ns_export::cmd2 ::test_ns_export::cmd3 ::test_ns_export::cmd4 ::test_ns_export::cmd5 ::test_ns_export::cmd6}
+namespace eval test_ns_export {
+    namespace export cmd1 cmd2 cmd3
+    proc cmd1 {args} {return "cmd1: $args"}
+    proc cmd2 {args} {return "cmd2: $args"}
+    proc cmd3 {args} {return "cmd3: $args"}
+    proc cmd4 {args} {return "cmd4: $args"}
+    proc cmd5 {args} {return "cmd5: $args"}
+    proc cmd6 {args} {return "cmd6: $args"}
+}
+test namespace-old-9.4 {check export status} {
+    set x ""
+    namespace eval test_ns_import {
+        namespace export cmd1 cmd2
+        namespace import ::test_ns_export::*
+    }
+    foreach cmd [lsort [info commands test_ns_import::*]] {
+        lappend x $cmd
+    }
+    set x
+} {::test_ns_import::cmd1 ::test_ns_import::cmd2 ::test_ns_import::cmd3}
+namespace eval test_ns_import {
+    namespace export cmd1 cmd2
+    namespace import ::test_ns_export::*
+}
+test namespace-old-9.5 {empty import list in "namespace import" command} {
+    namespace eval test_ns_import_empty {
+	namespace import ::test_ns_export::*
+	try {
+	    lsort [namespace import]
+	} finally {
+	    namespace delete [namespace current]
+	}
+    }
+} {cmd1 cmd2 cmd3}
+# there is no namespace-old-9.6
+test namespace-old-9.7 {empty forget list for "namespace forget" command} {
+    namespace forget
+} {}
+catch {rename cmd1 {}}
+catch {rename cmd2 {}}
+catch {rename ncmd {}}
+catch {rename ncmd1 {}}
+catch {rename ncmd2 {}}
+test namespace-old-9.8 {only exported commands are imported} {
+    namespace import test_ns_import::cmd*
+    set x [lsort [info commands cmd*]]
+} {cmd1 cmd2}
+namespace import test_ns_import::cmd*
+test namespace-old-9.9 {imported commands work just the same as original} {
+    list [cmd1 test 1 2 3] [test_ns_import::cmd1 test 4 5 6]
+} {{cmd1: test 1 2 3} {cmd1: test 4 5 6}}
+test namespace-old-9.10 {commands can be imported from many namespaces} {
+    namespace eval test_ns_import2 {
+        namespace export ncmd ncmd1 ncmd2
+        proc ncmd  {args} {return "ncmd: $args"}
+        proc ncmd1 {args} {return "ncmd1: $args"}
+        proc ncmd2 {args} {return "ncmd2: $args"}
+        proc ncmd3 {args} {return "ncmd3: $args"}
+    }
+    namespace import test_ns_import2::*
+    lsort [concat [info commands cmd*] [info commands ncmd*]]
+} {cmd1 cmd2 ncmd ncmd1 ncmd2}
+namespace eval test_ns_import2 {
+    namespace export ncmd ncmd1 ncmd2
+    proc ncmd  {args} {return "ncmd: $args"}
+    proc ncmd1 {args} {return "ncmd1: $args"}
+    proc ncmd2 {args} {return "ncmd2: $args"}
+    proc ncmd3 {args} {return "ncmd3: $args"}
+}
+namespace import test_ns_import2::*
+test namespace-old-9.11 {imported commands can be removed by deleting them} {
+    rename cmd1 ""
+    lsort [concat [info commands cmd*] [info commands ncmd*]]
+} {cmd2 ncmd ncmd1 ncmd2}
+catch { rename cmd1 "" }
+test namespace-old-9.12 {command "namespace forget" checks for valid namespaces} {
+    list [catch {namespace forget xyzzy::*} msg] $msg
+} {1 {unknown namespace in namespace forget pattern "xyzzy::*"}}
+test namespace-old-9.13 {command "namespace forget" ignores patterns that don't match} {
+    list [catch {namespace forget test_ns_import::xy*zzy} msg] $msg \
+         [lsort [info commands cmd?]]
+} {0 {} cmd2}
+test namespace-old-9.14 {imported commands can be removed} {
+    namespace forget test_ns_import::cmd?
+    list [lsort [info commands cmd?]] \
+         [catch {cmd1 another test} msg] $msg
+} {{} 1 {invalid command name "cmd1"}}
+test namespace-old-9.15 {existing commands can't be overwritten} {
+    proc cmd1 {x y} {
+        return [expr $x+$y]
+    }
+    list [catch {namespace import test_ns_import::cmd?} msg] $msg \
+         [cmd1 3 5]
+} {1 {can't import command "cmd1": already exists} 8}
+test namespace-old-9.16 {use "-force" option to override existing commands} {
+    proc cmd1 {x y} { return [expr $x+$y] }
+    list [cmd1 3 5] \
+         [namespace import -force test_ns_import::cmd?] \
+         [cmd1 3 5]
+} {8 {} {cmd1: 3 5}}
+test namespace-old-9.17 {commands can be imported into many namespaces} {
+    namespace eval test_ns_import_use {
+        namespace import ::test_ns_import::* ::test_ns_import2::ncmd?
+        lsort [concat [info commands ::test_ns_import_use::cmd*] \
+                      [info commands ::test_ns_import_use::ncmd*]]
+    }
+} {::test_ns_import_use::cmd1 ::test_ns_import_use::cmd2 ::test_ns_import_use::ncmd1 ::test_ns_import_use::ncmd2}
+test namespace-old-9.18 {when command is deleted, imported commands go away} {
+    namespace eval test_ns_import { rename cmd1 "" }
+    list [info commands cmd1] \
+         [namespace eval test_ns_import_use {info commands cmd1}]
+} {{} {}}
+test namespace-old-9.19 {when namesp is deleted, all imported commands go away} {
+    namespace delete test_ns_import test_ns_import2
+    list [info commands cmd*] \
+         [info commands ncmd*] \
+         [namespace eval test_ns_import_use {info commands cmd*}] \
+         [namespace eval test_ns_import_use {info commands ncmd*}] \
+} {{} {} {} {}}
+
+# -----------------------------------------------------------------------
+# TEST: scoped values
+# -----------------------------------------------------------------------
+test namespace-old-10.1 {define namespace for scope test} {
+    namespace eval test_ns_inscope {
+        variable x "x-value"
+        proc show {args} {
+            return "show: $args"
+        }
+        proc do {args} {
+            return [eval $args]
+        }
+        list [set x] [show test]
+    }
+} {x-value {show: test}}
+test namespace-old-10.2 {command "namespace code" requires one argument} {
+    list [catch {namespace code} msg] $msg
+} {1 {wrong # args: should be "namespace code arg"}}
+test namespace-old-10.3 {command "namespace code" requires one argument} {
+    list [catch {namespace code first "second arg" third} msg] $msg
+} {1 {wrong # args: should be "namespace code arg"}}
+test namespace-old-10.4 {command "namespace code" gets current namesp context} {
+    namespace eval test_ns_inscope {
+        namespace code {"1 2 3" "4 5" 6}
+    }
+} {::namespace inscope ::test_ns_inscope {"1 2 3" "4 5" 6}}
+test namespace-old-10.5 {with one arg, first "scope" sticks} {
+    set sval [namespace eval test_ns_inscope {namespace code {one two}}]
+    namespace code $sval
+} {::namespace inscope ::test_ns_inscope {one two}}
+test namespace-old-10.6 {with many args, each "scope" adds new args} {
+    set sval [namespace eval test_ns_inscope {namespace code {one two}}]
+    namespace code "$sval three"
+} {::namespace inscope ::test_ns_inscope {one two} three}
+namespace eval test_ns_inscope {
+    proc show {args} {
+	return "show: $args"
+    }
+}
+test namespace-old-10.7 {scoped commands work with eval} {
+    set cref [namespace eval test_ns_inscope {namespace code show}]
+    list [eval $cref "a" "b c" "d e f"]
+} {{show: a b c d e f}}
+namespace eval test_ns_inscope {
+    variable x "x-value"
+}
+test namespace-old-10.8 {scoped commands execute in namespace context} {
+    set cref [namespace eval test_ns_inscope {
+        namespace code {set x "some new value"}
+    }]
+    list [set test_ns_inscope::x] [eval $cref] [set test_ns_inscope::x]
+} {x-value {some new value} {some new value}}
+
+foreach cmd [info commands test_ns_*] {
+    rename $cmd ""
+}
+catch {rename cmd {}}
+catch {rename cmd1 {}}
+catch {rename cmd2 {}}
+catch {rename ncmd {}}
+catch {rename ncmd1 {}}
+catch {rename ncmd2 {}}
+catch {unset cref}
+catch {unset trigger}
+catch {unset trigger2}
+catch {unset sval}
+catch {unset msg}
+catch {unset x}
+catch {unset test_ns_var_global}
+catch {unset cmd}
+eval namespace delete [namespace children :: test_ns_*]
+
+# cleanup
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/tests/namespace.test b/tests/namespace.test
new file mode 100644
index 0000000..de7009d
--- /dev/null
+++ b/tests/namespace.test
@@ -0,0 +1,3282 @@
+# Functionality covered: this file contains a collection of tests for the
+# procedures in tclNamesp.c and tclEnsemble.c that implement Tcl's basic
+# support for namespaces.  Other namespace-related tests appear in
+# variable.test.
+#
+# Sourcing this file into Tcl runs the tests and generates output for errors.
+# No output means no errors were found.
+#
+# Copyright (c) 1997 Sun Microsystems, Inc.
+# Copyright (c) 1998-2000 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution of
+# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+package require tcltest 2
+namespace import -force ::tcltest::*
+testConstraint memory [llength [info commands memory]]
+
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
+
+#
+# REMARK: the tests for 'namespace upvar' are not done here. They are to be
+# found in the file 'upvar.test'.
+#
+
+# Clear out any namespaces called test_ns_*
+catch {namespace delete {*}[namespace children :: test_ns_*]}
+
+proc fq {ns} {
+    if {[string match ::* $ns]} {return $ns}
+    set current [uplevel 1 {namespace current}]
+    return [string trimright $current :]::[string trimleft $ns :]
+}
+
+test namespace-1.1 {TclInitNamespaces, GetNamespaceFromObj, NamespaceChildrenCmd} {
+    namespace children :: test_ns_*
+} {}
+
+catch {unset l}
+test namespace-2.1 {Tcl_GetCurrentNamespace} {
+    list [namespace current] [namespace eval {} {namespace current}] \
+        [namespace eval {} {namespace current}]
+} {:: :: ::}
+test namespace-2.2 {Tcl_GetCurrentNamespace} {
+    set l {}
+    lappend l [namespace current]
+    namespace eval test_ns_1 {
+        lappend l [namespace current]
+        namespace eval foo {
+            lappend l [namespace current]
+        }
+    }
+    lappend l [namespace current]
+} {:: ::test_ns_1 ::test_ns_1::foo ::}
+
+test namespace-3.1 {Tcl_GetGlobalNamespace} {
+    namespace eval test_ns_1 {namespace eval foo {namespace eval bar {} } }
+    # namespace children uses Tcl_GetGlobalNamespace 
+    namespace eval test_ns_1 {namespace children foo b*}
+} {::test_ns_1::foo::bar}
+
+test namespace-4.1 {Tcl_PushCallFrame with isProcCallFrame=1} {
+    namespace eval test_ns_1 {
+        variable v 123
+        proc p {} {
+            variable v
+            return $v
+        }
+    }
+    test_ns_1::p    ;# does Tcl_PushCallFrame to push p's namespace
+} {123}
+test namespace-4.2 {Tcl_PushCallFrame with isProcCallFrame=0} {
+    namespace eval test_ns_1::baz {}  ;# does Tcl_PushCallFrame to create baz
+    proc test_ns_1::baz::p {} {
+        variable v
+        set v 789
+        set v}
+    test_ns_1::baz::p
+} {789}
+
+test namespace-5.1 {Tcl_PopCallFrame, no vars} {
+    namespace eval test_ns_1::blodge {}  ;# pushes then pops frame
+} {}
+test namespace-5.2 {Tcl_PopCallFrame, local vars must be deleted} -setup {
+    namespace eval test_ns_1 {}
+} -body {
+    proc test_ns_1::r {} {
+        set a 123
+    }
+    test_ns_1::r   ;# pushes then pop's r's frame
+} -result {123}
+
+test namespace-6.1 {Tcl_CreateNamespace} {
+    catch {namespace delete {*}[namespace children :: test_ns_*]}
+    list [lsort [namespace children :: test_ns_*]] \
+        [namespace eval test_ns_1 {namespace current}] \
+	[namespace eval test_ns_2 {namespace current}] \
+	[namespace eval ::test_ns_3 {namespace current}] \
+	[namespace eval ::test_ns_4 \
+            {namespace eval foo {namespace current}}] \
+	[namespace eval ::test_ns_5 \
+            {namespace eval ::test_ns_6 {namespace current}}] \
+        [lsort [namespace children :: test_ns_*]]
+} {{} ::test_ns_1 ::test_ns_2 ::test_ns_3 ::test_ns_4::foo ::test_ns_6 {::test_ns_1 ::test_ns_2 ::test_ns_3 ::test_ns_4 ::test_ns_5 ::test_ns_6}}
+test namespace-6.2 {Tcl_CreateNamespace, odd number of :'s in name is okay} {
+    list [namespace eval :::test_ns_1::::foo {namespace current}] \
+         [namespace eval test_ns_2:::::foo {namespace current}]
+} {::test_ns_1::foo ::test_ns_2::foo}
+test namespace-6.3 {Tcl_CreateNamespace, trailing ::s in ns name are ignored} {
+    list [catch {namespace eval test_ns_7::: {namespace current}} msg] $msg 
+} {0 ::test_ns_7}
+test namespace-6.4 {Tcl_CreateNamespace, trailing ::s in ns name are ignored} {
+    catch {namespace delete {*}[namespace children :: test_ns_*]}
+    namespace eval test_ns_1:: {
+        namespace eval test_ns_2:: {}
+        namespace eval test_ns_3:: {}
+    }
+    lsort [namespace children ::test_ns_1]
+} [lsort {::test_ns_1::test_ns_2 ::test_ns_1::test_ns_3}]
+test namespace-6.5 {Tcl_CreateNamespace, relative ns names now only looked up in current ns} {
+    set trigger {
+        namespace eval test_ns_2 {namespace current}
+    }
+    set l {}
+    lappend l [namespace eval test_ns_1 $trigger]
+    namespace eval test_ns_1::test_ns_2 {}
+    lappend l [namespace eval test_ns_1 $trigger]
+} {::test_ns_1::test_ns_2 ::test_ns_1::test_ns_2}
+
+test namespace-7.1 {Tcl_DeleteNamespace, active call frames in ns} {
+    catch {namespace delete {*}[namespace children :: test_ns_*]}
+    namespace eval test_ns_1 {
+        proc p {} {
+            namespace delete [namespace current]
+            return [namespace current]
+        }
+    }
+    list [test_ns_1::p] [catch {test_ns_1::p} msg] $msg
+} {::test_ns_1 1 {invalid command name "test_ns_1::p"}}
+test namespace-7.2 {Tcl_DeleteNamespace, no active call frames in ns} {
+    namespace eval test_ns_2 {
+        proc p {} {
+            return [namespace current]
+        }
+    }
+    list [test_ns_2::p] [namespace delete test_ns_2]
+} {::test_ns_2 {}}
+test namespace-7.3 {recursive Tcl_DeleteNamespace, active call frames in ns} {
+    # [Bug 1355942]
+    namespace eval test_ns_2 {
+        set x 1
+	trace add variable x unset "namespace delete [namespace current];#"
+	namespace delete [namespace current]
+    }
+} {}
+test namespace-7.4 {recursive Tcl_DeleteNamespace, active call frames in ns} {
+    # [Bug 1355942]
+    namespace eval test_ns_2 {
+        proc x {} {}
+	trace add command x delete "namespace delete [namespace current];#"
+	namespace delete [namespace current]
+    }
+} {}
+test namespace-7.5 {recursive Tcl_DeleteNamespace, no active call frames in ns} {
+    # [Bug 1355942]
+    namespace eval test_ns_2 {
+        set x 1
+	trace add variable x unset "namespace delete [namespace current];#"
+    }
+    namespace delete test_ns_2
+} {}
+test namespace-7.6 {recursive Tcl_DeleteNamespace, no active call frames in ns} {
+    # [Bug 1355942]
+    namespace eval test_ns_2 {
+        proc x {} {}
+	trace add command x delete "namespace delete [namespace current];#"
+    }
+    namespace delete test_ns_2
+} {}
+test namespace-7.7 {Bug 1655305} -setup {
+    interp create slave
+    # Can't invoke through the ensemble, since deleting the global namespace
+    # (indirectly, via deleting ::tcl) deletes the ensemble.
+    slave eval {rename ::tcl::info::commands ::infocommands}
+    slave hide infocommands
+    slave eval {
+	proc foo {} {
+	    namespace delete ::
+	}
+    }
+} -body {
+    slave eval foo
+    slave invokehidden infocommands
+} -cleanup {
+    interp delete slave
+} -result {}
+
+test namespace-8.1 {TclTeardownNamespace, delete global namespace} {
+    catch {interp delete test_interp}
+    interp create test_interp
+    interp eval test_interp {
+        namespace eval test_ns_1 {
+            namespace export p
+            proc p {} {
+                return [namespace current]
+            }
+        }
+        namespace eval test_ns_2 {
+            namespace import ::test_ns_1::p
+            variable v 27
+            proc q {} {
+                variable v
+                return "[p] $v"
+            }
+        }
+        set x [test_ns_2::q]
+        catch {set xxxx}
+    }
+    list [interp eval test_interp {test_ns_2::q}] \
+         [interp eval test_interp {namespace delete ::}] \
+         [catch {interp eval test_interp {set a 123}} msg] $msg \
+         [interp delete test_interp]
+} {{::test_ns_1 27} {} 1 {invalid command name "set"} {}}
+test namespace-8.2 {TclTeardownNamespace, remove deleted ns from parent} {
+    catch {namespace delete {*}[namespace children :: test_ns_*]}
+    namespace eval test_ns_1::test_ns_2::test_ns_3a {proc p {} {}}
+    namespace eval test_ns_1::test_ns_2::test_ns_3b {proc q {} {}}
+    list [namespace children test_ns_1] \
+         [namespace delete test_ns_1::test_ns_2] \
+         [namespace children test_ns_1]
+} {::test_ns_1::test_ns_2 {} {}}
+test namespace-8.3 {TclTeardownNamespace, delete child namespaces} {
+    catch {namespace delete {*}[namespace children :: test_ns_*]}
+    namespace eval test_ns_1::test_ns_2::test_ns_3a {proc p {} {}}
+    namespace eval test_ns_1::test_ns_2::test_ns_3b {proc q {} {}}
+    list [namespace children test_ns_1] \
+         [namespace delete test_ns_1::test_ns_2] \
+         [namespace children test_ns_1] \
+         [catch {namespace children test_ns_1::test_ns_2} msg] $msg \
+         [info commands test_ns_1::test_ns_2::test_ns_3a::*]
+} {::test_ns_1::test_ns_2 {} {} 1 {namespace "test_ns_1::test_ns_2" not found in "::"} {}}
+test namespace-8.4 {TclTeardownNamespace, cmds imported from deleted ns go away} {
+    catch {namespace delete {*}[namespace children :: test_ns_*]}
+    namespace eval test_ns_export {
+        namespace export cmd1 cmd2
+        proc cmd1 {args} {return "cmd1: $args"}
+        proc cmd2 {args} {return "cmd2: $args"}
+    }
+    namespace eval test_ns_import {
+        namespace import ::test_ns_export::*
+        proc p {} {return foo}
+    }
+    list [lsort [info commands test_ns_import::*]] \
+         [namespace delete test_ns_export] \
+         [info commands test_ns_import::*]
+} [list [lsort {::test_ns_import::p ::test_ns_import::cmd1 ::test_ns_import::cmd2}] {} ::test_ns_import::p]
+test namespace-8.5 {TclTeardownNamespace: preserve errorInfo; errorCode values} {
+    interp create slave
+    slave eval {trace add execution error leave {namespace delete :: ;#}}
+    catch {slave eval error foo bar baz}
+    interp delete slave
+    set ::errorInfo
+} {bar
+    invoked from within
+"slave eval error foo bar baz"}
+test namespace-8.6 {TclTeardownNamespace: preserve errorInfo; errorCode values} {
+    interp create slave 
+    slave eval {trace add variable errorCode write {namespace delete :: ;#}}
+    catch {slave eval error foo bar baz}
+    interp delete slave
+    set ::errorInfo
+} {bar
+    invoked from within
+"slave eval error foo bar baz"}
+test namespace-8.7 {TclTeardownNamespace: preserve errorInfo; errorCode values} {
+    interp create slave
+    slave eval {trace add execution error leave {namespace delete :: ;#}}
+    catch {slave eval error foo bar baz}
+    interp delete slave
+    set ::errorCode
+} baz
+
+test namespace-9.1 {Tcl_Import, empty import pattern} {
+    catch {namespace delete {*}[namespace children :: test_ns_*]}
+    list [catch {namespace eval test_ns_import {namespace import {}}} msg] $msg
+} {1 {empty import pattern}}
+test namespace-9.2 {Tcl_Import, unknown namespace in import pattern} {
+    list [catch {namespace eval test_ns_import {namespace import fred::x}} msg] $msg
+} {1 {unknown namespace in import pattern "fred::x"}}
+test namespace-9.3 {Tcl_Import, import ns == export ns} {
+    list [catch {namespace eval test_ns_import {namespace import ::test_ns_import::puts}} msg] $msg
+} {1 {import pattern "::test_ns_import::puts" tries to import from namespace "test_ns_import" into itself}}
+test namespace-9.4 {Tcl_Import, simple import} {
+    catch {namespace delete {*}[namespace children :: test_ns_*]}
+    namespace eval test_ns_export {
+        namespace export cmd1
+        proc cmd1 {args} {return "cmd1: $args"}
+        proc cmd2 {args} {return "cmd2: $args"}
+    }
+    namespace eval test_ns_import {
+        namespace import ::test_ns_export::*
+        proc p {} {return [cmd1 123]}
+    }
+    test_ns_import::p
+} {cmd1: 123}
+test namespace-9.5 {Tcl_Import, RFE 1230597} -setup {
+    namespace eval test_ns_import {}
+    namespace eval test_ns_export {}
+} -body {
+    list [catch {namespace eval test_ns_import {namespace import ::test_ns_export::*}} msg] $msg
+} -result {0 {}}
+test namespace-9.6 {Tcl_Import, cmd redefinition ok if allowOverwrite!=0} -setup {
+    namespace eval test_ns_import {}
+    namespace eval ::test_ns_export {
+        proc cmd1 {args} {return "cmd1: $args"}
+	namespace export cmd1
+    }
+} -body {
+    namespace eval test_ns_import {
+        namespace import -force ::test_ns_export::*
+        cmd1 555
+    }
+} -result {cmd1: 555}
+test namespace-9.7 {Tcl_Import, links are preserved if cmd is redefined} {
+    catch {namespace delete {*}[namespace children :: test_ns_*]}
+    namespace eval test_ns_export {
+        namespace export cmd1
+        proc cmd1 {args} {return "cmd1: $args"}
+    }
+    namespace eval test_ns_import {
+        namespace import -force ::test_ns_export::*
+    }
+    list [test_ns_import::cmd1 a b c] \
+         [test_ns_export::cmd1 d e f] \
+         [proc test_ns_export::cmd1 {args} {return "new1: $args"}] \
+         [namespace origin test_ns_import::cmd1] \
+         [namespace origin test_ns_export::cmd1] \
+         [test_ns_import::cmd1 g h i] \
+         [test_ns_export::cmd1 j k l]
+} {{cmd1: a b c} {cmd1: d e f} {} ::test_ns_export::cmd1 ::test_ns_export::cmd1 {new1: g h i} {new1: j k l}}
+test namespace-9.8 {Tcl_Import: Bug 1017299} -setup {
+    namespace eval one {
+	namespace export cmd
+	proc cmd {} {}
+    }
+    namespace eval two {
+	namespace export cmd
+	proc other args {}
+    }
+    namespace eval two \
+	    [list namespace import [namespace current]::one::cmd]
+    namespace eval three \
+	    [list namespace import [namespace current]::two::cmd]
+    namespace eval three {
+	rename cmd other
+	namespace export other
+    }
+} -body {
+    namespace eval two [list namespace import -force \
+	    [namespace current]::three::other]
+    namespace origin two::other
+} -cleanup {
+    namespace delete one two three
+} -match glob -result *::one::cmd
+test namespace-9.9 {Tcl_Import: Bug 1017299} -setup {
+    namespace eval one {
+	namespace export cmd
+	proc cmd {} {}
+    }
+    namespace eval two namespace export cmd
+    namespace eval two \
+	    [list namespace import [namespace current]::one::cmd]
+    namespace eval three namespace export cmd
+    namespace eval three \
+	    [list namespace import [namespace current]::two::cmd]
+} -body {
+    namespace eval two [list namespace import -force \
+	    [namespace current]::three::cmd]
+    namespace origin two::cmd
+} -cleanup {
+    namespace delete one two three
+} -returnCodes error -match glob -result {import pattern * would create a loop*}
+
+test namespace-10.1 {Tcl_ForgetImport, check for valid namespaces} {
+    catch {namespace delete {*}[namespace children :: test_ns_*]}
+    list [catch {namespace forget xyzzy::*} msg] $msg
+} {1 {unknown namespace in namespace forget pattern "xyzzy::*"}}
+test namespace-10.2 {Tcl_ForgetImport, ignores patterns that don't match} {
+    namespace eval test_ns_export {
+        namespace export cmd1
+        proc cmd1 {args} {return "cmd1: $args"}
+        proc cmd2 {args} {return "cmd2: $args"}
+    }
+    namespace eval test_ns_import {
+        namespace forget ::test_ns_export::wombat
+    }
+} {}
+test namespace-10.3 {Tcl_ForgetImport, deletes matching imported cmds} -setup {
+    namespace eval test_ns_export {
+        namespace export cmd1
+        proc cmd1 {args} {return "cmd1: $args"}
+        proc cmd2 {args} {return "cmd2: $args"}
+    }
+} -body {
+    namespace eval test_ns_import {
+        namespace import ::test_ns_export::*
+        proc p {} {return [cmd1 123]}
+        set l {}
+        lappend l [lsort [info commands ::test_ns_import::*]]
+        namespace forget ::test_ns_export::cmd1
+        lappend l [info commands ::test_ns_import::*]
+        lappend l [catch {cmd1 777} msg] $msg
+    }
+} -result [list [lsort {::test_ns_import::p ::test_ns_import::cmd1}] ::test_ns_import::p 1 {invalid command name "cmd1"}]
+test namespace-10.4 {Tcl_ForgetImport: Bug 560297} -setup {
+    namespace eval origin {
+	namespace export cmd
+	proc cmd {} {}
+    }
+    namespace eval unrelated {
+	proc cmd {} {}
+    }
+    namespace eval my \
+	    [list namespace import [namespace current]::origin::cmd]
+} -body {
+    namespace eval my \
+	    [list namespace forget [namespace current]::unrelated::cmd]
+    my::cmd
+} -cleanup {
+    namespace delete origin unrelated my
+}
+test namespace-10.5 {Tcl_ForgetImport: Bug 560297} -setup {
+    namespace eval origin {
+	namespace export cmd
+	proc cmd {} {}
+    }
+    namespace eval my \
+	    [list namespace import [namespace current]::origin::cmd]
+    namespace eval my rename cmd newname
+} -body {
+    namespace eval my \
+	    [list namespace forget [namespace current]::origin::cmd]
+    my::newname
+} -cleanup {
+    namespace delete origin my
+} -returnCodes error -match glob -result *
+test namespace-10.6 {Tcl_ForgetImport: Bug 560297} -setup {
+    namespace eval origin {
+	namespace export cmd
+	proc cmd {} {}
+    }
+    namespace eval my \
+	    [list namespace import [namespace current]::origin::cmd]
+    namespace eval your {}
+    namespace eval my \
+	    [list rename cmd [namespace current]::your::newname]
+} -body {
+    namespace eval your namespace forget newname
+    your::newname
+} -cleanup {
+    namespace delete origin my your
+} -returnCodes error -match glob -result *
+test namespace-10.7 {Tcl_ForgetImport: Bug 560297} -setup {
+    namespace eval origin {
+	namespace export cmd
+	proc cmd {} {}
+    }
+    namespace eval link namespace export cmd
+    namespace eval link \
+	    [list namespace import [namespace current]::origin::cmd]
+    namespace eval link2 namespace export cmd
+    namespace eval link2 \
+	    [list namespace import [namespace current]::link::cmd]
+    namespace eval my \
+	    [list namespace import [namespace current]::link2::cmd]
+} -body {
+    namespace eval my \
+	    [list namespace forget [namespace current]::origin::cmd]
+    my::cmd
+} -cleanup {
+    namespace delete origin link link2 my
+} -returnCodes error -match glob -result *
+test namespace-10.8 {Tcl_ForgetImport: Bug 560297} -setup {
+    namespace eval origin {
+	namespace export cmd
+	proc cmd {} {}
+    }
+    namespace eval link namespace export cmd
+    namespace eval link \
+	    [list namespace import [namespace current]::origin::cmd]
+    namespace eval link2 namespace export cmd
+    namespace eval link2 \
+	    [list namespace import [namespace current]::link::cmd]
+    namespace eval my \
+	    [list namespace import [namespace current]::link2::cmd]
+} -body {
+    namespace eval my \
+	    [list namespace forget [namespace current]::link::cmd]
+    my::cmd
+} -cleanup {
+    namespace delete origin link link2 my
+}
+test namespace-10.9 {Tcl_ForgetImport: Bug 560297} -setup {
+    namespace eval origin {
+	namespace export cmd
+	proc cmd {} {}
+    }
+    namespace eval link namespace export cmd
+    namespace eval link \
+	    [list namespace import [namespace current]::origin::cmd]
+    namespace eval link2 namespace export cmd
+    namespace eval link2 \
+	    [list namespace import [namespace current]::link::cmd]
+    namespace eval my \
+	    [list namespace import [namespace current]::link2::cmd]
+} -body {
+    namespace eval my \
+	    [list namespace forget [namespace current]::link2::cmd]
+    my::cmd
+} -cleanup {
+    namespace delete origin link link2 my
+} -returnCodes error -match glob -result *
+
+test namespace-11.1 {TclGetOriginalCommand, check if not imported cmd} -setup {
+    catch {namespace delete {*}[namespace children :: test_ns_*]}
+} -body {
+    namespace eval test_ns_export {
+        namespace export cmd1
+        proc cmd1 {args} {return "cmd1: $args"}
+    }
+    list [namespace origin set] [namespace origin test_ns_export::cmd1]
+} -result {::set ::test_ns_export::cmd1}
+test namespace-11.2 {TclGetOriginalCommand, directly imported cmd} -setup {
+    catch {namespace delete {*}[namespace children :: test_ns_*]}
+    namespace eval test_ns_export {
+        namespace export cmd1
+        proc cmd1 {args} {return "cmd1: $args"}
+    }
+} -body {
+    namespace eval test_ns_import1 {
+        namespace import ::test_ns_export::*
+        namespace export *
+        proc p {} {namespace origin cmd1}
+    }
+    list [test_ns_import1::p] [namespace origin test_ns_import1::cmd1]
+} -result {::test_ns_export::cmd1 ::test_ns_export::cmd1}
+test namespace-11.3 {TclGetOriginalCommand, indirectly imported cmd} -setup {
+    catch {namespace delete {*}[namespace children :: test_ns_*]}
+    namespace eval test_ns_export {
+        namespace export cmd1
+        proc cmd1 {args} {return "cmd1: $args"}
+    }
+    namespace eval test_ns_import1 {
+        namespace import ::test_ns_export::*
+        namespace export *
+        proc p {} {namespace origin cmd1}
+    }
+} -body {
+    namespace eval test_ns_import2 {
+        namespace import ::test_ns_import1::*
+        proc q {} {return [cmd1 123]}
+    }
+    list [test_ns_import2::q] [namespace origin test_ns_import2::cmd1]
+} -result {{cmd1: 123} ::test_ns_export::cmd1}
+
+test namespace-12.1 {InvokeImportedCmd} {
+    catch {namespace delete {*}[namespace children :: test_ns_*]}
+    namespace eval test_ns_export {
+        namespace export cmd1
+        proc cmd1 {args} {namespace current}
+    }
+    namespace eval test_ns_import {
+        namespace import ::test_ns_export::*
+    }
+    list [test_ns_import::cmd1]
+} {::test_ns_export}
+
+test namespace-13.1 {DeleteImportedCmd, deletes imported cmds} -setup {
+    catch {namespace delete {*}[namespace children :: test_ns_*]}
+    namespace eval test_ns_export {
+        namespace export cmd1
+        proc cmd1 {args} {namespace current}
+    }
+    namespace eval test_ns_import {
+        namespace import ::test_ns_export::*
+    }
+} -body {
+    namespace eval test_ns_import {
+        set l {}
+        lappend l [info commands ::test_ns_import::*]
+        namespace forget ::test_ns_export::cmd1
+        lappend l [info commands ::test_ns_import::*]
+    }
+} -result {::test_ns_import::cmd1 {}}
+test namespace-13.2 {DeleteImportedCmd, Bug a4494e28ed} {
+    # Will panic if still buggy
+    namespace eval src {namespace export foo; proc foo {} {}}
+    namespace eval dst {namespace import [namespace parent]::src::foo}
+    trace add command src::foo delete \
+        "[list namespace delete [namespace current]::dst] ;#"
+    proc src::foo {} {}
+    namespace delete src
+} {}
+
+test namespace-14.1 {TclGetNamespaceForQualName, absolute names} -setup {
+    catch {namespace delete {*}[namespace children :: test_ns_*]}
+    variable v 10
+    namespace eval test_ns_1::test_ns_2 {
+        variable v 20
+    }
+    namespace eval test_ns_2 {
+        variable v 30
+    }
+} -body {
+    namespace eval test_ns_1 {
+        list $::v $::test_ns_2::v $::test_ns_1::test_ns_2::v \
+		[lsort [namespace children :: test_ns_*]]
+    }
+} -result [list 10 30 20 [lsort {::test_ns_1 ::test_ns_2}]]
+test namespace-14.2 {TclGetNamespaceForQualName, invalid absolute names} -setup {
+    catch {namespace delete {*}[namespace children :: test_ns_*]}
+    variable v 10
+    namespace eval test_ns_1::test_ns_2 {
+        variable v 20
+    }
+    namespace eval test_ns_2 {
+        variable v 30
+    }
+} -body {
+    namespace eval test_ns_1 {
+        list [catch {set ::test_ns_777::v} msg] $msg \
+             [catch {namespace children test_ns_777} msg] $msg
+    }
+} -result {1 {can't read "::test_ns_777::v": no such variable} 1 {namespace "test_ns_777" not found in "::test_ns_1"}}
+test namespace-14.3 {TclGetNamespaceForQualName, relative names} -setup {
+    catch {namespace delete {*}[namespace children :: test_ns_*]}
+    variable v 10
+    namespace eval test_ns_1::test_ns_2 {
+        variable v 20
+    }
+    namespace eval test_ns_2 {
+        variable v 30
+    }
+} -body {
+    namespace eval test_ns_1 {
+        list $v $test_ns_2::v
+    }
+} -result {10 20}
+test namespace-14.4 {TclGetNamespaceForQualName, relative ns names looked up only in current ns} {
+    namespace eval test_ns_1::test_ns_2 {
+        namespace eval foo {}
+    }
+    namespace eval test_ns_1 {
+        list [namespace children test_ns_2] \
+             [catch {namespace children test_ns_1} msg] $msg
+    }
+} {::test_ns_1::test_ns_2::foo 1 {namespace "test_ns_1" not found in "::test_ns_1"}}
+test namespace-14.5 {TclGetNamespaceForQualName, relative ns names looked up only in current ns} {
+    namespace eval ::test_ns_2 {
+        namespace eval bar {}
+    }
+    namespace eval test_ns_1 {
+        list [catch {namespace delete test_ns_2::bar} msg] $msg
+    }
+} {1 {unknown namespace "test_ns_2::bar" in namespace delete command}}
+test namespace-14.6 {TclGetNamespaceForQualName, relative ns names looked up only in current ns} {
+    namespace eval test_ns_1::test_ns_2 {
+        namespace eval foo {}
+    }
+    namespace eval test_ns_1 {
+        list [namespace children test_ns_2] \
+             [catch {namespace children test_ns_1} msg] $msg
+    }
+} {::test_ns_1::test_ns_2::foo 1 {namespace "test_ns_1" not found in "::test_ns_1"}}
+test namespace-14.7 {TclGetNamespaceForQualName, ignore extra :s if ns} -setup {
+    namespace eval test_ns_1::test_ns_2::foo {}
+} -body {
+    namespace children test_ns_1:::
+} -result {::test_ns_1::test_ns_2}
+test namespace-14.8 {TclGetNamespaceForQualName, ignore extra :s if ns} -setup {
+    namespace eval test_ns_1::test_ns_2::foo {}
+} -body {
+    namespace children :::test_ns_1:::::test_ns_2:::
+} -result {::test_ns_1::test_ns_2::foo}
+test namespace-14.9 {TclGetNamespaceForQualName, extra ::s are significant for vars} {
+    set l {}
+    lappend l [catch {set test_ns_1::test_ns_2::} msg] $msg
+    namespace eval test_ns_1::test_ns_2 {variable {} 2525}
+    lappend l [set test_ns_1::test_ns_2::]
+} {1 {can't read "test_ns_1::test_ns_2::": no such variable} 2525}
+test namespace-14.10 {TclGetNamespaceForQualName, extra ::s are significant for vars} -setup {
+    namespace eval test_ns_1::test_ns_2::foo {}
+    unset -nocomplain test_ns_1::test_ns_2::
+    set l {}
+} -body {
+    lappend l [catch {set test_ns_1::test_ns_2::} msg] $msg
+    set test_ns_1::test_ns_2:: 314159
+    lappend l [set test_ns_1::test_ns_2::]
+} -result {1 {can't read "test_ns_1::test_ns_2::": no such variable} 314159}
+test namespace-14.11 {TclGetNamespaceForQualName, extra ::s are significant for commands} -setup {
+    namespace eval test_ns_1::test_ns_2::foo {}
+    catch {rename test_ns_1::test_ns_2:: {}}
+    set l {}
+} -body {
+    lappend l [catch {test_ns_1::test_ns_2:: hello} msg] $msg
+    proc test_ns_1::test_ns_2:: {args} {return "\{\}: $args"}
+    lappend l [test_ns_1::test_ns_2:: hello]
+} -result {1 {invalid command name "test_ns_1::test_ns_2::"} {{}: hello}}
+test namespace-14.12 {TclGetNamespaceForQualName, extra ::s are significant for vars} -setup {
+    catch {namespace delete {*}[namespace children :: test_ns_*]}
+} -body {
+    namespace eval test_ns_1 {
+        variable {}
+        set test_ns_1::(x) y
+    }
+    set test_ns_1::(x)
+} -result y
+test namespace-14.13 {TclGetNamespaceForQualName, namespace other than global ns can't have empty name} -setup {
+    catch {namespace delete {*}[namespace children :: test_ns_*]}
+} -returnCodes error -body {
+    namespace eval test_ns_1 {
+	proc {} {} {}
+	namespace eval {} {}
+	{}
+    }
+} -result {can't create namespace "": only global namespace can have empty name}
+
+test namespace-15.1 {Tcl_FindNamespace, absolute name found} -setup {
+    catch {namespace delete {*}[namespace children :: test_ns_*]}
+} -body {
+    namespace eval test_ns_delete {
+        namespace eval test_ns_delete2 {}
+        proc cmd {args} {namespace current}
+    }
+    list [namespace delete ::test_ns_delete::test_ns_delete2] \
+         [namespace children ::test_ns_delete]
+} -result {{} {}}
+test namespace-15.2 {Tcl_FindNamespace, absolute name not found} -body {
+    namespace delete ::test_ns_delete::test_ns_delete2
+} -returnCodes error -result {unknown namespace "::test_ns_delete::test_ns_delete2" in namespace delete command}
+test namespace-15.3 {Tcl_FindNamespace, relative name found} {
+    namespace eval test_ns_delete {
+        namespace eval test_ns_delete2 {}
+        namespace eval test_ns_delete3 {}
+        list [namespace delete test_ns_delete2] \
+             [namespace children [namespace current]]
+    }
+} {{} ::test_ns_delete::test_ns_delete3}
+test namespace-15.4 {Tcl_FindNamespace, relative name not found} {
+    namespace eval test_ns_delete2 {}
+    namespace eval test_ns_delete {
+        list [catch {namespace delete test_ns_delete2} msg] $msg
+    }
+} {1 {unknown namespace "test_ns_delete2" in namespace delete command}}
+
+test namespace-16.1 {Tcl_FindCommand, absolute name found} -setup {
+    catch {namespace delete {*}[namespace children :: test_ns_*]}
+} -body {
+    namespace eval test_ns_1 {
+        proc cmd {args} {return "[namespace current]::cmd: $args"}
+        variable v "::test_ns_1::cmd"
+        eval $v one
+    }
+} -result {::test_ns_1::cmd: one}
+test namespace-16.2 {Tcl_FindCommand, absolute name found} -setup {
+    catch {namespace delete {*}[namespace children :: test_ns_*]}
+    namespace eval test_ns_1 {
+        proc cmd {args} {return "[namespace current]::cmd: $args"}
+        variable v "::test_ns_1::cmd"
+    }
+} -body {
+    eval $test_ns_1::v two
+} -result {::test_ns_1::cmd: two}
+test namespace-16.3 {Tcl_FindCommand, absolute name not found} {
+    namespace eval test_ns_1 {
+        variable v2 "::test_ns_1::ladidah"
+        list [catch {eval $v2} msg] $msg
+    }
+} {1 {invalid command name "::test_ns_1::ladidah"}}
+
+# save the "unknown" proc, which is redefined by the following two tests
+catch {rename unknown unknown.old}
+proc unknown {args} {
+    return "unknown: $args"
+}
+test namespace-16.4 {Tcl_FindCommand, absolute name and TCL_GLOBAL_ONLY} {
+    ::test_ns_1::foobar x y z
+} {unknown: ::test_ns_1::foobar x y z}
+test namespace-16.5 {Tcl_FindCommand, absolute name and TCL_GLOBAL_ONLY} {
+    ::foobar 1 2 3 4 5
+} {unknown: ::foobar 1 2 3 4 5}
+test namespace-16.6 {Tcl_FindCommand, relative name and TCL_GLOBAL_ONLY} {
+    test_ns_1::foobar x y z
+} {unknown: test_ns_1::foobar x y z}
+test namespace-16.7 {Tcl_FindCommand, relative name and TCL_GLOBAL_ONLY} {
+    foobar 1 2 3 4 5
+} {unknown: foobar 1 2 3 4 5}
+# restore the "unknown" proc saved previously
+catch {rename unknown {}}
+catch {rename unknown.old unknown}
+
+test namespace-16.8 {Tcl_FindCommand, relative name found} -setup {
+    catch {namespace delete {*}[namespace children :: test_ns_*]}
+    namespace eval test_ns_1 {
+        proc cmd {args} {return "[namespace current]::cmd: $args"}
+    }
+} -body {
+    namespace eval test_ns_1 {
+        cmd a b c
+    }
+} -result {::test_ns_1::cmd: a b c}
+test namespace-16.9 {Tcl_FindCommand, relative name found} -body {
+    proc cmd2 {args} {return "[namespace current]::cmd2: $args"}
+    namespace eval test_ns_1 {
+       cmd2 a b c
+    }
+} -cleanup {
+    catch {rename cmd2 {}}
+} -result {::::cmd2: a b c}
+test namespace-16.10 {Tcl_FindCommand, relative name found, only look in current then global ns} -body {
+    proc cmd2 {args} {return "[namespace current]::cmd2: $args"}
+    namespace eval test_ns_1 {
+        proc cmd2 {args} {
+            return "[namespace current]::cmd2 in test_ns_1: $args"
+        }
+        namespace eval test_ns_12 {
+            cmd2 a b c
+        }
+    }
+} -cleanup {
+    catch {rename cmd2 {}}
+} -result {::::cmd2: a b c}
+test namespace-16.11 {Tcl_FindCommand, relative name not found} -body {
+    namespace eval test_ns_1 {
+       cmd3 a b c
+    }
+} -returnCodes error -result {invalid command name "cmd3"}
+
+unset -nocomplain x
+test namespace-17.1 {Tcl_FindNamespaceVar, absolute name found} -setup {
+    catch {namespace delete {*}[namespace children :: test_ns_*]}
+} -body {
+    set x 314159
+    namespace eval test_ns_1 {
+        set ::x
+    }
+} -result {314159}
+variable ::x 314159
+test namespace-17.2 {Tcl_FindNamespaceVar, absolute name found} {
+    namespace eval test_ns_1 {
+        variable x 777
+        set ::test_ns_1::x
+    }
+} {777}
+test namespace-17.3 {Tcl_FindNamespaceVar, absolute name found} {
+    namespace eval test_ns_1 {
+        namespace eval test_ns_2 {
+            variable x 1111
+        }
+        set ::test_ns_1::test_ns_2::x
+    }
+} {1111}
+test namespace-17.4 {Tcl_FindNamespaceVar, absolute name not found} -body {
+    namespace eval test_ns_1 {
+        namespace eval test_ns_2 {
+            variable x 1111
+        }
+        set ::test_ns_1::test_ns_2::y
+    }
+} -returnCodes error -result {can't read "::test_ns_1::test_ns_2::y": no such variable}
+test namespace-17.5 {Tcl_FindNamespaceVar, absolute name and TCL_GLOBAL_ONLY} -setup {
+    namespace eval ::test_ns_1::test_ns_2 {}
+} -body {
+    namespace eval test_ns_1 {
+        namespace eval test_ns_3 {
+            variable ::test_ns_1::test_ns_2::x 2222
+        }
+    }
+    set ::test_ns_1::test_ns_2::x
+} -result {2222}
+test namespace-17.6 {Tcl_FindNamespaceVar, relative name found} -setup {
+    namespace eval test_ns_1 {
+        variable x 777
+    }
+} -body {
+    namespace eval test_ns_1 {
+        set x
+    }
+} -result {777}
+test namespace-17.7 {Tcl_FindNamespaceVar, relative name found} {
+    namespace eval test_ns_1 {
+	variable x 777
+        unset x
+        set x  ;# must be global x now
+    }
+} {314159}
+test namespace-17.8 {Tcl_FindNamespaceVar, relative name not found} -body {
+    namespace eval test_ns_1 {
+        set wuzzat
+    }
+} -returnCodes error -result {can't read "wuzzat": no such variable}
+test namespace-17.9 {Tcl_FindNamespaceVar, relative name and TCL_GLOBAL_ONLY} {
+    namespace eval test_ns_1 {
+        variable a hello
+    }
+    set test_ns_1::a
+} {hello}
+test namespace-17.10 {Tcl_FindNamespaceVar, interference with cached varNames} -setup {
+    namespace eval test_ns_1 {}
+} -body {
+    proc test_ns {} {
+	set ::test_ns_1::a 0
+    }
+    test_ns
+    rename test_ns {}
+    namespace eval test_ns_1 unset a
+    set a 0
+    namespace eval test_ns_1 set a 1
+    namespace delete test_ns_1
+    return $a
+} -result 1
+catch {unset a}
+catch {unset x}
+
+catch {unset l}
+catch {rename foo {}}
+test namespace-18.1 {TclResetShadowedCmdRefs, one-level check for command shadowing} -setup {
+    catch {namespace delete {*}[namespace children :: test_ns_*]}
+} -body {
+    proc foo {} {return "global foo"}
+    namespace eval test_ns_1 {
+        proc trigger {} {
+            return [foo]
+        }
+    }
+    set l ""
+    lappend l [test_ns_1::trigger]
+    namespace eval test_ns_1 {
+        # force invalidation of cached ref to "foo" in proc trigger
+        proc foo {} {return "foo in test_ns_1"}
+    }
+    lappend l [test_ns_1::trigger]
+} -result {{global foo} {foo in test_ns_1}}
+test namespace-18.2 {TclResetShadowedCmdRefs, multilevel check for command shadowing} {
+    namespace eval test_ns_2 {
+        proc foo {} {return "foo in ::test_ns_2"}
+    }
+    namespace eval test_ns_1 {
+        namespace eval test_ns_2 {}
+        proc trigger {} {
+            return [test_ns_2::foo]
+        }
+    }
+    set l ""
+    lappend l [test_ns_1::trigger]
+    namespace eval test_ns_1 {
+        namespace eval test_ns_2 {
+            # force invalidation of cached ref to "foo" in proc trigger
+            proc foo {} {return "foo in ::test_ns_1::test_ns_2"}
+        }
+    }
+    lappend l [test_ns_1::trigger]
+} {{foo in ::test_ns_2} {foo in ::test_ns_1::test_ns_2}}
+catch {unset l}
+catch {rename foo {}}
+
+test namespace-19.1 {GetNamespaceFromObj, global name found} -setup {
+    catch {namespace delete {*}[namespace children :: test_ns_*]}
+} -body {
+    namespace eval test_ns_1::test_ns_2 {}
+    namespace children ::test_ns_1
+} -result {::test_ns_1::test_ns_2}
+test namespace-19.2 {GetNamespaceFromObj, relative name found} -setup {
+    catch {namespace delete {*}[namespace children :: test_ns_*]}
+    namespace eval test_ns_1::test_ns_2 {}
+} -body {
+    namespace eval test_ns_1 {
+        namespace children test_ns_2
+    }
+} -result {}
+test namespace-19.3 {GetNamespaceFromObj, name not found} -setup {
+    catch {namespace delete {*}[namespace children :: test_ns_*]}
+} -body {
+    namespace eval test_ns_1 {
+        namespace children test_ns_99
+    }
+} -returnCodes error -result {namespace "test_ns_99" not found in "::test_ns_1"}
+test namespace-19.4 {GetNamespaceFromObj, invalidation of cached ns refs} -setup {
+    catch {namespace delete {*}[namespace children :: test_ns_*]}
+    namespace eval test_ns_1::test_ns_2 {}
+} -body {
+    namespace eval test_ns_1 {
+        proc foo {} {
+            return [namespace children test_ns_2]
+        }
+        list [catch {namespace children test_ns_99} msg] $msg
+    }
+    set l {}
+    lappend l [test_ns_1::foo]
+    namespace delete test_ns_1::test_ns_2
+    namespace eval test_ns_1::test_ns_2::test_ns_3 {}
+    lappend l [test_ns_1::foo]
+} -result {{} ::test_ns_1::test_ns_2::test_ns_3}
+
+test namespace-20.1 {Tcl_NamespaceObjCmd, bad subcommand} {
+    catch {namespace delete {*}[namespace children :: test_ns_*]}
+    list [catch {namespace} msg] $msg
+} {1 {wrong # args: should be "namespace subcommand ?arg ...?"}}
+test namespace-20.2 {Tcl_NamespaceObjCmd, bad subcommand} -body {
+    namespace wombat {}
+} -returnCodes error -match glob -result {unknown or ambiguous subcommand "wombat": must be *}
+test namespace-20.3 {Tcl_NamespaceObjCmd, abbreviations are okay} {
+    namespace ch :: test_ns_*
+} {}
+
+test namespace-21.1 {NamespaceChildrenCmd, no args} -setup {
+    catch {namespace delete {*}[namespace children :: test_ns_*]}
+} -body {
+    namespace eval test_ns_1::test_ns_2 {}
+    expr {"::test_ns_1" in [namespace children]}
+} -result {1}
+test namespace-21.2 {NamespaceChildrenCmd, no args} -setup {
+    catch {namespace delete {*}[namespace children :: test_ns_*]}
+    namespace eval test_ns_1::test_ns_2 {}
+} -body {
+    namespace eval test_ns_1 {
+        namespace children
+    }
+} -result {::test_ns_1::test_ns_2}
+test namespace-21.3 {NamespaceChildrenCmd, ns name given} -setup {
+    catch {namespace delete {*}[namespace children :: test_ns_*]}
+    namespace eval test_ns_1::test_ns_2 {}
+} -body {
+    namespace children ::test_ns_1
+} -result {::test_ns_1::test_ns_2}
+test namespace-21.4 {NamespaceChildrenCmd, ns name given} -setup {
+    catch {namespace delete {*}[namespace children :: test_ns_*]}
+    namespace eval test_ns_1::test_ns_2 {}
+} -body {
+    namespace eval test_ns_1 {
+        namespace children test_ns_2
+    }
+} -result {}
+test namespace-21.5 {NamespaceChildrenCmd, too many args} {
+    namespace eval test_ns_1 {
+        list [catch {namespace children test_ns_2 xxx yyy} msg] $msg
+    }
+} {1 {wrong # args: should be "namespace children ?name? ?pattern?"}}
+test namespace-21.6 {NamespaceChildrenCmd, glob-style pattern given} {
+    namespace eval test_ns_1::test_ns_foo {}
+    namespace children test_ns_1 *f*
+} {::test_ns_1::test_ns_foo}
+test namespace-21.7 {NamespaceChildrenCmd, glob-style pattern given} -setup {
+    catch {namespace delete {*}[namespace children :: test_ns_*]}
+    namespace eval test_ns_1::test_ns_2 {}
+} -body {
+    namespace eval test_ns_1::test_ns_foo {}
+    lsort [namespace children test_ns_1 test*]
+} -result {::test_ns_1::test_ns_2 ::test_ns_1::test_ns_foo}
+test namespace-21.8 {NamespaceChildrenCmd, trivial pattern starting with ::} {
+    namespace eval test_ns_1 {}
+    namespace children [namespace current] [fq test_ns_1]
+} [fq test_ns_1]
+
+test namespace-22.1 {NamespaceCodeCmd, bad args} {
+    catch {namespace delete {*}[namespace children :: test_ns_*]}
+    list [catch {namespace code} msg] $msg \
+         [catch {namespace code xxx yyy} msg] $msg
+} {1 {wrong # args: should be "namespace code arg"} 1 {wrong # args: should be "namespace code arg"}}
+test namespace-22.2 {NamespaceCodeCmd, arg is already scoped value} {
+    namespace eval test_ns_1 {
+        proc cmd {} {return "test_ns_1::cmd"}
+    }
+    namespace code {::namespace inscope ::test_ns_1 cmd}
+} {::namespace inscope ::test_ns_1 cmd}
+test namespace-22.3 {NamespaceCodeCmd, arg is already scoped value} {
+    namespace code {namespace     inscope     ::test_ns_1 cmd}
+} {::namespace inscope :: {namespace     inscope     ::test_ns_1 cmd}}
+test namespace-22.4 {NamespaceCodeCmd, in :: namespace} {
+    namespace code unknown
+} {::namespace inscope :: unknown}
+test namespace-22.5 {NamespaceCodeCmd, in other namespace} {
+    namespace eval test_ns_1 {
+        namespace code cmd
+    }
+} {::namespace inscope ::test_ns_1 cmd}
+test namespace-22.6 {NamespaceCodeCmd, in other namespace} { 
+    namespace eval test_ns_1 { 
+	variable v 42 
+    } 
+    namespace eval test_ns_2 { 
+	proc namespace args {} 
+    } 
+    namespace eval test_ns_2 [namespace eval test_ns_1 { 
+	namespace code {set v} 
+    }] 
+} {42} 
+test namespace-22.7 {NamespaceCodeCmd, Bug 3202171} {
+    namespace eval demo {
+	proc namespace args {puts $args}
+	::namespace code {namespace inscope foo}
+    }
+} [list ::namespace inscope [fq demo] {namespace inscope foo}]
+
+test namespace-23.1 {NamespaceCurrentCmd, bad args} {
+    catch {namespace delete {*}[namespace children :: test_ns_*]}
+    list [catch {namespace current xxx} msg] $msg \
+         [catch {namespace current xxx yyy} msg] $msg
+} {1 {wrong # args: should be "namespace current"} 1 {wrong # args: should be "namespace current"}}
+test namespace-23.2 {NamespaceCurrentCmd, at global level} {
+    namespace current
+} {::}
+test namespace-23.3 {NamespaceCurrentCmd, in nested ns} {
+    namespace eval test_ns_1::test_ns_2 {
+        namespace current
+    }
+} {::test_ns_1::test_ns_2}
+
+test namespace-24.1 {NamespaceDeleteCmd, no args} {
+    catch {namespace delete {*}[namespace children :: test_ns_*]}
+    namespace delete
+} {}
+test namespace-24.2 {NamespaceDeleteCmd, one arg} {
+    namespace eval test_ns_1::test_ns_2 {}
+    namespace delete ::test_ns_1
+} {}
+test namespace-24.3 {NamespaceDeleteCmd, two args} {
+    namespace eval test_ns_1::test_ns_2 {}
+    list [namespace delete ::test_ns_1::test_ns_2] [namespace delete ::test_ns_1]
+} {{} {}}
+test namespace-24.4 {NamespaceDeleteCmd, unknown ns} {
+    list [catch {namespace delete ::test_ns_foo} msg] $msg
+} {1 {unknown namespace "::test_ns_foo" in namespace delete command}}
+
+test namespace-25.1 {NamespaceEvalCmd, bad args} {
+    catch {namespace delete {*}[namespace children :: test_ns_*]}
+    list [catch {namespace eval} msg] $msg
+} {1 {wrong # args: should be "namespace eval name arg ?arg...?"}}
+test namespace-25.2 {NamespaceEvalCmd, bad args} -body {
+    namespace test_ns_1
+} -returnCodes error -match glob -result {unknown or ambiguous subcommand "test_ns_1": must be *}
+catch {unset v}
+test namespace-25.3 {NamespaceEvalCmd, new namespace} {
+    set v 123
+    namespace eval test_ns_1 {
+        variable v 314159
+        proc p {} {
+            variable v
+            return $v
+        }
+    }
+    test_ns_1::p
+} {314159}
+test namespace-25.4 {NamespaceEvalCmd, existing namespace} -setup {
+    namespace eval test_ns_1 {
+        variable v 314159
+        proc p {} {
+            variable v
+            return $v
+        }
+    }
+} -body {
+    namespace eval test_ns_1 {
+        proc q {} {return [expr {[p]+1}]}
+    }
+    test_ns_1::q
+} -result {314160}
+test namespace-25.5 {NamespaceEvalCmd, multiple args} -setup {
+    namespace eval test_ns_1 {variable v 314159}
+} -body {
+    namespace eval test_ns_1 "set" "v"
+} -result {314159}
+test namespace-25.6 {NamespaceEvalCmd, error in eval'd script} {
+    list [catch {namespace eval test_ns_1 {xxxx}} msg] $msg $::errorInfo
+} {1 {invalid command name "xxxx"} {invalid command name "xxxx"
+    while executing
+"xxxx"
+    (in namespace eval "::test_ns_1" script line 1)
+    invoked from within
+"namespace eval test_ns_1 {xxxx}"}}
+test namespace-25.7 {NamespaceEvalCmd, error in eval'd script} {
+    list [catch {namespace eval test_ns_1 {error foo bar baz}} msg] $msg $::errorInfo
+} {1 foo {bar
+    (in namespace eval "::test_ns_1" script line 1)
+    invoked from within
+"namespace eval test_ns_1 {error foo bar baz}"}}
+test namespace-25.8 {NamespaceEvalCmd, error in eval'd script} {
+    list [catch {namespace eval test_ns_1 error foo bar baz} msg] $msg $::errorInfo
+} {1 foo {bar
+    (in namespace eval "::test_ns_1" script line 1)
+    invoked from within
+"namespace eval test_ns_1 error foo bar baz"}}
+catch {unset v}
+test namespace-25.9 {NamespaceEvalCmd, 545325} {
+    namespace eval test_ns_1 info level 0
+} {namespace eval test_ns_1 info level 0}
+
+test namespace-26.1 {NamespaceExportCmd, no args and new ns} {
+    catch {namespace delete {*}[namespace children :: test_ns_*]}
+    namespace export
+} {}
+test namespace-26.2 {NamespaceExportCmd, just -clear arg} {
+    namespace export -clear
+} {}
+test namespace-26.3 {NamespaceExportCmd, pattern can't specify a namespace} {
+    namespace eval test_ns_1 {
+        list [catch {namespace export ::zzz} msg] $msg
+    }
+} {1 {invalid export pattern "::zzz": pattern can't specify a namespace}}
+test namespace-26.4 {NamespaceExportCmd, one pattern} {
+    namespace eval test_ns_1 {
+        namespace export cmd1
+        proc cmd1 {args} {return "cmd1: $args"}
+        proc cmd2 {args} {return "cmd2: $args"}
+        proc cmd3 {args} {return "cmd3: $args"}
+        proc cmd4 {args} {return "cmd4: $args"}
+    }
+    namespace eval test_ns_2 {
+        namespace import ::test_ns_1::*
+    }
+    list [info commands test_ns_2::*] [test_ns_2::cmd1 hello]
+} {::test_ns_2::cmd1 {cmd1: hello}}
+test namespace-26.5 {NamespaceExportCmd, sequence of patterns, patterns accumulate} -setup {
+    catch {namespace delete {*}[namespace children test_ns_*]}
+    namespace eval test_ns_1 {
+        proc cmd1 {args} {return "cmd1: $args"}
+        proc cmd2 {args} {return "cmd2: $args"}
+        proc cmd3 {args} {return "cmd3: $args"}
+        proc cmd4 {args} {return "cmd4: $args"}
+        namespace export cmd1 cmd3
+    }
+} -body {
+    namespace eval test_ns_2 {
+        namespace import -force ::test_ns_1::*
+    }
+    list [lsort [info commands test_ns_2::*]] [test_ns_2::cmd3 hello]
+} -result {{::test_ns_2::cmd1 ::test_ns_2::cmd3} {cmd3: hello}}
+test namespace-26.6 {NamespaceExportCmd, no patterns means return uniq'ed export list} -setup {
+    catch {namespace delete {*}[namespace children test_ns_*]}
+    namespace eval test_ns_1 {
+        proc cmd1 {args} {return "cmd1: $args"}
+        proc cmd2 {args} {return "cmd2: $args"}
+        proc cmd3 {args} {return "cmd3: $args"}
+        proc cmd4 {args} {return "cmd4: $args"}
+        namespace export cmd1 cmd3
+    }
+} -body {
+    namespace eval test_ns_1 {
+        namespace export
+    }
+} -result {cmd1 cmd3}
+test namespace-26.7 {NamespaceExportCmd, -clear resets export list} -setup {
+    catch {namespace delete {*}[namespace children test_ns_*]}
+    namespace eval test_ns_1 {
+        proc cmd1 {args} {return "cmd1: $args"}
+        proc cmd2 {args} {return "cmd2: $args"}
+        proc cmd3 {args} {return "cmd3: $args"}
+        proc cmd4 {args} {return "cmd4: $args"}
+    }
+} -body {
+    namespace eval test_ns_1 {
+        namespace export cmd1 cmd3
+    }
+    namespace eval test_ns_2 {
+        namespace import ::test_ns_1::*
+    }
+    namespace eval test_ns_1 {
+        namespace export -clear cmd4
+    }
+    namespace eval test_ns_2 {
+        namespace import ::test_ns_1::*
+    }
+    list [lsort [info commands test_ns_2::*]] [test_ns_2::cmd4 hello]
+} -result [list [lsort {::test_ns_2::cmd4 ::test_ns_2::cmd1 ::test_ns_2::cmd3}] {cmd4: hello}]
+test namespace-26.8 {NamespaceExportCmd, -clear resets export list} {
+    catch {namespace delete foo}
+    namespace eval foo {
+	namespace export x
+	namespace export -clear
+    }
+    list [namespace eval foo namespace export] [namespace delete foo]
+} {{} {}}
+
+test namespace-27.1 {NamespaceForgetCmd, no args} {
+    catch {namespace delete {*}[namespace children :: test_ns_*]}
+    namespace forget
+} {}
+test namespace-27.2 {NamespaceForgetCmd, args must be valid namespaces} {
+    list [catch {namespace forget ::test_ns_1::xxx} msg] $msg
+} {1 {unknown namespace in namespace forget pattern "::test_ns_1::xxx"}}
+test namespace-27.3 {NamespaceForgetCmd, arg is forgotten} {
+    namespace eval test_ns_1 {
+        namespace export cmd*
+        proc cmd1 {args} {return "cmd1: $args"}
+        proc cmd2 {args} {return "cmd2: $args"}
+    }
+    namespace eval test_ns_2 {
+        namespace import ::test_ns_1::*
+        namespace forget ::test_ns_1::cmd1
+    }
+    info commands ::test_ns_2::*
+} {::test_ns_2::cmd2}
+
+test namespace-28.1 {NamespaceImportCmd, no args} -setup {
+    catch {namespace delete {*}[namespace children :: test_ns_*]}
+} -body {
+    namespace eval ::test_ns_1 {
+	proc foo {} {}
+	proc bar {} {}
+	proc boo {} {}
+	proc glorp {} {}
+	namespace export foo b*
+    }
+    namespace eval ::test_ns_2 {
+	namespace import ::test_ns_1::*
+	lsort [namespace import]
+    }
+} -cleanup {
+    catch {namespace delete {*}[namespace children :: test_ns_*]}
+} -result {bar boo foo}
+test namespace-28.2 {NamespaceImportCmd, no args and just "-force"} {
+    namespace import -force
+} {}
+test namespace-28.3 {NamespaceImportCmd, arg is imported} {
+    namespace eval test_ns_1 {
+        namespace export cmd2
+        proc cmd1 {args} {return "cmd1: $args"}
+        proc cmd2 {args} {return "cmd2: $args"}
+    }
+    namespace eval test_ns_2 {
+        namespace import ::test_ns_1::*
+        namespace forget ::test_ns_1::cmd1
+    }
+    info commands test_ns_2::*
+} {::test_ns_2::cmd2}
+
+test namespace-29.1 {NamespaceInscopeCmd, bad args} {
+    catch {namespace delete {*}[namespace children :: test_ns_*]}
+    list [catch {namespace inscope} msg] $msg
+} {1 {wrong # args: should be "namespace inscope name arg ?arg...?"}}
+test namespace-29.2 {NamespaceInscopeCmd, bad args} {
+    list [catch {namespace inscope ::} msg] $msg
+} {1 {wrong # args: should be "namespace inscope name arg ?arg...?"}}
+test namespace-29.3 {NamespaceInscopeCmd, specified ns must exist} -body {
+    namespace inscope test_ns_1 {set v}
+} -returnCodes error -result {namespace "test_ns_1" not found in "::"}
+test namespace-29.4 {NamespaceInscopeCmd, simple case} {
+    namespace eval test_ns_1 {
+        variable v 747
+        proc cmd {args} {
+            variable v
+            return "[namespace current]::cmd: v=$v, args=$args"
+        }
+    }
+    namespace inscope test_ns_1 cmd
+} {::test_ns_1::cmd: v=747, args=}
+test namespace-29.5 {NamespaceInscopeCmd, has lappend semantics} -setup {
+    namespace eval test_ns_1 {
+        variable v 747
+        proc cmd {args} {
+            variable v
+            return "[namespace current]::cmd: v=$v, args=$args"
+        }
+    }
+} -body {
+    list [namespace inscope test_ns_1 cmd x y z] \
+         [namespace eval test_ns_1 [concat cmd [list x y z]]]
+} -result {{::test_ns_1::cmd: v=747, args=x y z} {::test_ns_1::cmd: v=747, args=x y z}}
+test namespace-29.6 {NamespaceInscopeCmd, 1400572} -setup {
+    namespace eval test_ns_1 {}
+} -body {
+    namespace inscope test_ns_1 {info level 0}
+} -result {namespace inscope test_ns_1 {info level 0}}
+
+test namespace-30.1 {NamespaceOriginCmd, bad args} {
+    catch {namespace delete {*}[namespace children :: test_ns_*]}
+    list [catch {namespace origin} msg] $msg
+} {1 {wrong # args: should be "namespace origin name"}}
+test namespace-30.2 {NamespaceOriginCmd, bad args} {
+    list [catch {namespace origin x y} msg] $msg
+} {1 {wrong # args: should be "namespace origin name"}}
+test namespace-30.3 {NamespaceOriginCmd, command not found} {
+    list [catch {namespace origin fred} msg] $msg
+} {1 {invalid command name "fred"}}
+test namespace-30.4 {NamespaceOriginCmd, command isn't imported} {
+    namespace origin set
+} {::set}
+test namespace-30.5 {NamespaceOriginCmd, imported command} {
+    namespace eval test_ns_1 {
+        namespace export cmd*
+        proc cmd1 {args} {return "cmd1: $args"}
+        proc cmd2 {args} {return "cmd2: $args"}
+    }
+    namespace eval test_ns_2 {
+        namespace export *
+        namespace import ::test_ns_1::*
+        proc p {} {}
+    }
+    namespace eval test_ns_3 {
+        namespace import ::test_ns_2::*
+        list [namespace origin foreach] \
+             [namespace origin p] \
+             [namespace origin cmd1] \
+             [namespace origin ::test_ns_2::cmd2]
+    }
+} {::foreach ::test_ns_2::p ::test_ns_1::cmd1 ::test_ns_1::cmd2}
+
+test namespace-31.1 {NamespaceParentCmd, bad args} {
+    catch {namespace delete {*}[namespace children :: test_ns_*]}
+    list [catch {namespace parent a b} msg] $msg
+} {1 {wrong # args: should be "namespace parent ?name?"}}
+test namespace-31.2 {NamespaceParentCmd, no args} {
+    namespace parent
+} {}
+test namespace-31.3 {NamespaceParentCmd, namespace specified} {
+    namespace eval test_ns_1 {
+        namespace eval test_ns_2 {
+            namespace eval test_ns_3 {}
+        }
+    }
+    list [namespace parent ::] \
+         [namespace parent test_ns_1::test_ns_2] \
+         [namespace eval test_ns_1::test_ns_2::test_ns_3 {namespace parent ::test_ns_1::test_ns_2}]
+} {{} ::test_ns_1 ::test_ns_1}
+test namespace-31.4 {NamespaceParentCmd, bad namespace specified} -body {
+    namespace parent test_ns_1::test_ns_foo
+} -returnCodes error -result {namespace "test_ns_1::test_ns_foo" not found in "::"}
+
+test namespace-32.1 {NamespaceQualifiersCmd, bad args} {
+    catch {namespace delete {*}[namespace children :: test_ns_*]}
+    list [catch {namespace qualifiers} msg] $msg
+} {1 {wrong # args: should be "namespace qualifiers string"}}
+test namespace-32.2 {NamespaceQualifiersCmd, bad args} {
+    list [catch {namespace qualifiers x y} msg] $msg
+} {1 {wrong # args: should be "namespace qualifiers string"}}
+test namespace-32.3 {NamespaceQualifiersCmd, simple name} {
+    namespace qualifiers foo
+} {}
+test namespace-32.4 {NamespaceQualifiersCmd, leading ::} {
+    namespace qualifiers ::x::y::z
+} {::x::y}
+test namespace-32.5 {NamespaceQualifiersCmd, no leading ::} {
+    namespace qualifiers a::b
+} {a}
+test namespace-32.6 {NamespaceQualifiersCmd, :: argument} {
+    namespace qualifiers ::
+} {}
+test namespace-32.7 {NamespaceQualifiersCmd, odd number of :s} {
+    namespace qualifiers :::::
+} {}
+test namespace-32.8 {NamespaceQualifiersCmd, odd number of :s} {
+    namespace qualifiers foo:::
+} {foo}
+
+test namespace-33.1 {NamespaceTailCmd, bad args} {
+    catch {namespace delete {*}[namespace children :: test_ns_*]}
+    list [catch {namespace tail} msg] $msg
+} {1 {wrong # args: should be "namespace tail string"}}
+test namespace-33.2 {NamespaceTailCmd, bad args} {
+    list [catch {namespace tail x y} msg] $msg
+} {1 {wrong # args: should be "namespace tail string"}}
+test namespace-33.3 {NamespaceTailCmd, simple name} {
+    namespace tail foo
+} {foo}
+test namespace-33.4 {NamespaceTailCmd, leading ::} {
+    namespace tail ::x::y::z
+} {z}
+test namespace-33.5 {NamespaceTailCmd, no leading ::} {
+    namespace tail a::b
+} {b}
+test namespace-33.6 {NamespaceTailCmd, :: argument} {
+    namespace tail ::
+} {}
+test namespace-33.7 {NamespaceTailCmd, odd number of :s} {
+    namespace tail :::::
+} {}
+test namespace-33.8 {NamespaceTailCmd, odd number of :s} {
+    namespace tail foo:::
+} {}
+
+test namespace-34.1 {NamespaceWhichCmd, bad args} {
+    catch {namespace delete {*}[namespace children :: test_ns_*]}
+    list [catch {namespace which} msg] $msg
+} {1 {wrong # args: should be "namespace which ?-command? ?-variable? name"}}
+test namespace-34.2 {NamespaceWhichCmd, bad args} {
+    list [catch {namespace which -fred x} msg] $msg
+} {1 {wrong # args: should be "namespace which ?-command? ?-variable? name"}}
+test namespace-34.3 {NamespaceWhichCmd, single arg is always command name} {
+    namespace which -command
+} {}
+test namespace-34.4 {NamespaceWhichCmd, bad args} {
+    list [catch {namespace which a b} msg] $msg
+} {1 {wrong # args: should be "namespace which ?-command? ?-variable? name"}}
+test namespace-34.5 {NamespaceWhichCmd, command lookup} -setup {
+    catch {namespace delete {*}[namespace children test_ns_*]}
+    namespace eval test_ns_1 {
+        namespace export cmd*
+        variable v1 111
+        proc cmd1 {args} {return "cmd1: $args"}
+        proc cmd2 {args} {return "cmd2: $args"}
+    }
+    namespace eval test_ns_2 {
+        namespace export *
+        namespace import ::test_ns_1::*
+        variable v2 222
+        proc p {} {}
+    }
+} -body {
+    namespace eval test_ns_3 {
+        namespace import ::test_ns_2::*
+        variable v3 333
+        list [namespace which -command foreach] \
+             [namespace which -command p] \
+             [namespace which -command cmd1] \
+             [namespace which -command ::test_ns_2::cmd2] \
+             [catch {namespace which -command ::test_ns_2::noSuchCmd} msg] $msg
+    }
+} -result {::foreach ::test_ns_3::p ::test_ns_3::cmd1 ::test_ns_2::cmd2 0 {}}
+test namespace-34.6 {NamespaceWhichCmd, -command is default} -setup {
+    catch {namespace delete {*}[namespace children test_ns_*]}
+    namespace eval test_ns_1 {
+        namespace export cmd*
+        proc cmd1 {args} {return "cmd1: $args"}
+        proc cmd2 {args} {return "cmd2: $args"}
+    }
+    namespace eval test_ns_2 {
+        namespace export *
+        namespace import ::test_ns_1::*
+        proc p {} {}
+    }
+    namespace eval test_ns_3 {
+        namespace import ::test_ns_2::*
+    }
+} -body {
+    namespace eval test_ns_3 {
+        list [namespace which foreach] \
+             [namespace which p] \
+             [namespace which cmd1] \
+             [namespace which ::test_ns_2::cmd2]
+    }
+} -result {::foreach ::test_ns_3::p ::test_ns_3::cmd1 ::test_ns_2::cmd2}
+test namespace-34.7 {NamespaceWhichCmd, variable lookup} -setup {
+    catch {namespace delete {*}[namespace children test_ns_*]}
+    namespace eval test_ns_1 {
+        namespace export cmd*
+        proc cmd1 {args} {return "cmd1: $args"}
+        proc cmd2 {args} {return "cmd2: $args"}
+    }
+    namespace eval test_ns_2 {
+        namespace export *
+        namespace import ::test_ns_1::*
+        variable v2 222
+        proc p {} {}
+    }
+    namespace eval test_ns_3 {
+        variable v3 333
+        namespace import ::test_ns_2::*
+    }
+} -body {
+    namespace eval test_ns_3 {
+        list [namespace which -variable env] \
+             [namespace which -variable v3] \
+             [namespace which -variable ::test_ns_2::v2] \
+             [catch {namespace which -variable ::test_ns_2::noSuchVar} msg] $msg
+    }
+} -result {::env ::test_ns_3::v3 ::test_ns_2::v2 0 {}}
+
+test namespace-35.1 {FreeNsNameInternalRep, resulting ref count > 0} -setup {
+    catch {namespace delete {*}[namespace children :: test_ns_*]}
+} -body {
+    namespace eval test_ns_1 {
+        proc p {} {
+            namespace delete [namespace current]
+            return [namespace current]
+        }
+    }
+    test_ns_1::p
+} -result {::test_ns_1}
+test namespace-35.2 {FreeNsNameInternalRep, resulting ref count == 0} {
+    namespace eval test_ns_1 {
+        proc q {} {
+            return [namespace current]
+        }
+    }
+    list [test_ns_1::q] \
+         [namespace delete test_ns_1] \
+         [catch {test_ns_1::q} msg] $msg
+} {::test_ns_1 {} 1 {invalid command name "test_ns_1::q"}}
+
+catch {unset x}
+catch {unset y}
+test namespace-36.1 {DupNsNameInternalRep} {
+    catch {namespace delete {*}[namespace children :: test_ns_*]}
+    namespace eval test_ns_1 {}
+    set x "::test_ns_1"
+    list [namespace parent $x] [set y $x] [namespace parent $y]
+} {:: ::test_ns_1 ::}
+catch {unset x}
+catch {unset y}
+
+test namespace-37.1 {SetNsNameFromAny, ns name found} {
+    catch {namespace delete {*}[namespace children :: test_ns_*]}
+    namespace eval test_ns_1::test_ns_2 {}
+    namespace eval test_ns_1 {
+        namespace children ::test_ns_1
+    }
+} {::test_ns_1::test_ns_2}
+test namespace-37.2 {SetNsNameFromAny, ns name not found} -body {
+    namespace eval test_ns_1 {
+        namespace children ::test_ns_1::test_ns_foo
+    }
+} -returnCodes error -result {namespace "::test_ns_1::test_ns_foo" not found}
+
+test namespace-38.1 {UpdateStringOfNsName} {
+    catch {namespace delete {*}[namespace children :: test_ns_*]}
+    ;# Tcl_NamespaceObjCmd calls UpdateStringOfNsName to get subcmd name
+    list [namespace eval {} {namespace current}] \
+         [namespace eval {} {namespace current}]
+} {:: ::}
+
+test namespace-39.1 {NamespaceExistsCmd} {
+    catch {namespace delete {*}[namespace children :: test_ns_*]}
+    namespace eval ::test_ns_z::test_me { variable foo }
+    list [namespace exists ::] \
+	    [namespace exists ::bogus_namespace] \
+	    [namespace exists ::test_ns_z] \
+	    [namespace exists test_ns_z] \
+	    [namespace exists ::test_ns_z::foo] \
+	    [namespace exists ::test_ns_z::test_me] \
+	    [namespace eval ::test_ns_z { namespace exists ::test_me }] \
+	    [namespace eval ::test_ns_z { namespace exists test_me }] \
+	    [namespace exists :::::test_ns_z]
+} {1 0 1 1 0 1 0 1 1}
+test namespace-39.2 {NamespaceExistsCmd error} {
+    list [catch {namespace exists} msg] $msg
+} {1 {wrong # args: should be "namespace exists name"}}
+test namespace-39.3 {NamespaceExistsCmd error} {
+    list [catch {namespace exists a b} msg] $msg
+} {1 {wrong # args: should be "namespace exists name"}}
+
+test namespace-40.1 {Ignoring namespace proc "unknown"} -setup {
+    rename unknown _unknown
+} -body {
+    proc unknown args {return global}
+    namespace eval ns {proc unknown args {return local}}
+    list [namespace eval ns aaa bbb] [namespace eval ns aaa]
+} -cleanup {
+    rename unknown {}   
+    rename _unknown unknown
+    namespace delete ns
+} -result {global global}
+
+test namespace-41.1 {Shadowing byte-compiled commands, Bug: 231259} {
+    set res {}
+    namespace eval ns {
+	set res {}
+	proc test {} {
+	    set ::g 0
+	}  
+	lappend ::res [test]
+	proc set {a b} {
+	    ::set a [incr b]
+	}
+	lappend ::res [test]
+    }
+    namespace delete ns
+    set res
+} {0 1}
+test namespace-41.2 {Shadowing byte-compiled commands, Bug: 231259} {
+    set res {}
+    namespace eval ns {}
+    proc ns::a {i} {
+	variable b
+	proc set args {return "New proc is called"}
+	return [set b $i]
+    }
+    ns::a 1
+    set res [ns::a 2]
+    namespace delete ns
+    set res
+} {New proc is called}
+test namespace-41.3 {Shadowing byte-compiled commands, Bugs: 231259, 729692} {
+    set res {}
+    namespace eval ns {
+	variable b 0
+    }
+    proc ns::a {i} {
+	variable b
+	proc set args {return "New proc is called"}
+	return [set b $i]
+    }
+    set res [list [ns::a 1] $ns::b]
+    namespace delete ns
+    set res
+} {{New proc is called} 0}
+
+# Ensembles (TIP#112)
+
+test namespace-42.1 {ensembles: basic} {
+    namespace eval ns {
+	namespace export x
+	proc x {} {format 1}
+	namespace ensemble create
+    }
+    list [info command ns] [ns x] [namespace delete ns] [info command ns]
+} {ns 1 {} {}}
+test namespace-42.2 {ensembles: basic} {
+    namespace eval ns {
+	namespace export x
+	proc x {} {format 1}
+	namespace ensemble create
+    }
+    rename ns foo
+    list [info command foo] [foo x] [namespace delete ns] [info command foo]
+} {foo 1 {} {}}
+test namespace-42.3 {ensembles: basic} {
+    namespace eval ns {
+	namespace export x*
+	proc x1 {} {format 1}
+	proc x2 {} {format 2}
+	namespace ensemble create
+    }
+    set result [list [ns x1] [ns x2]]
+    lappend result [catch {ns x} msg] $msg
+    rename ns {}
+    lappend result [info command ns::x1]
+    namespace delete ns
+    lappend result [info command ns::x1]
+} {1 2 1 {unknown or ambiguous subcommand "x": must be x1, or x2} ::ns::x1 {}}
+test namespace-42.4 {ensembles: basic} -body {
+    namespace eval ns {
+	namespace export y*
+	proc x1 {} {format 1}
+	proc x2 {} {format 2}
+	namespace ensemble create
+    }
+    list [catch {ns x} msg] $msg
+} -cleanup {
+    namespace delete ns
+} -result {1 {unknown subcommand "x": namespace ::ns does not export any commands}}
+test namespace-42.5 {ensembles: basic} -body {
+    namespace eval ns {
+	namespace export x*
+	proc x1 {} {format 1}
+	proc x2 {} {format 2}
+	proc x3 {} {format 3}
+	namespace ensemble create
+    }
+    list [catch {ns x} msg] $msg
+} -cleanup {
+    namespace delete ns
+} -result {1 {unknown or ambiguous subcommand "x": must be x1, x2, or x3}}
+test namespace-42.6 {ensembles: nested} -body {
+    namespace eval ns {
+	namespace export x*
+	namespace eval x0 {
+	    proc z {} {format 0}
+	    namespace export z
+	    namespace ensemble create
+	}
+	proc x1 {} {format 1}
+	proc x2 {} {format 2}
+	proc x3 {} {format 3}
+	namespace ensemble create
+    }
+    list [ns x0 z] [ns x1] [ns x2] [ns x3]
+} -cleanup {
+    namespace delete ns
+} -result {0 1 2 3}
+test namespace-42.7 {ensembles: nested} -body {
+    namespace eval ns {
+	namespace export x*
+	namespace eval x0 {
+	    proc z {} {list [info level] [info level 1]}
+	    namespace export z
+	    namespace ensemble create
+	}
+	proc x1 {} {format 1}
+	proc x2 {} {format 2}
+	proc x3 {} {format 3}
+	namespace ensemble create
+    }
+    list [ns x0 z] [ns x1] [ns x2] [ns x3]
+} -cleanup {
+    namespace delete ns
+} -result {{1 ::ns::x0::z} 1 2 3}
+test namespace-42.8 {ensembles: [Bug 1670091]} -setup {
+    proc demo args {}
+    variable target [list [namespace which demo] x]
+    proc trial args {variable target; string length $target}
+    trace add execution demo enter [namespace code trial]
+    namespace ensemble create -command foo -map [list bar $target]
+} -body {
+    foo bar
+} -cleanup {
+    unset target
+    rename demo {}
+    rename trial {}
+    rename foo {}
+} -result {}
+
+test namespace-43.1 {ensembles: dict-driven} {
+    namespace eval ns {
+	namespace export x*
+	proc x1 {} {format 1}
+	proc x2 {} {format 2}
+	namespace ensemble create -map {a x1 b x2}
+    }
+    set result [list [catch {ns c} msg] $msg [namespace ensemble exists ns]]
+    rename ns {}
+    lappend result [namespace ensemble exists ns]
+} {1 {unknown or ambiguous subcommand "c": must be a, or b} 1 0}
+test namespace-43.2 {ensembles: dict-driven} -body {
+    namespace eval ns {
+	namespace export x*
+	proc x1 {args} {list 1 $args}
+	proc x2 {args} {list 2 [llength $args]}
+	namespace ensemble create -map {
+	    a ::ns::x1 b ::ns::x2 c {::ns::x1 .} d {::ns::x2 .}
+	}
+    }
+    list [ns a] [ns b] [ns c] [ns c foo] [ns d] [ns d foo]
+} -cleanup {
+    namespace delete ns
+} -result {{1 {}} {2 0} {1 .} {1 {. foo}} {2 1} {2 2}}
+set SETUP {
+    namespace eval ns {
+	namespace export a b
+	proc a args {format 1,[llength $args]}
+	proc b args {format 2,[llength $args]}
+	proc c args {format 3,[llength $args]}
+	proc d args {format 4,[llength $args]}
+	namespace ensemble create -subcommands {b c}
+    }
+}
+test namespace-43.3 {ensembles: list-driven} -setup $SETUP -body {
+    namespace delete ns
+} -result {}
+test namespace-43.4 {ensembles: list-driven} -setup $SETUP -body {
+    ns a foo bar boo spong wibble
+} -cleanup {namespace delete ns} -returnCodes error -result {unknown or ambiguous subcommand "a": must be b, or c}
+test namespace-43.5 {ensembles: list-driven} -setup $SETUP -body {
+    ns b foo bar boo spong wibble
+} -cleanup {namespace delete ns} -result 2,5
+test namespace-43.6 {ensembles: list-driven} -setup $SETUP -body {
+    ns c foo bar boo spong wibble
+} -cleanup {namespace delete ns} -result 3,5
+test namespace-43.7 {ensembles: list-driven} -setup $SETUP -body {
+    ns d foo bar boo spong wibble
+} -cleanup {namespace delete ns} -returnCodes error -result {unknown or ambiguous subcommand "d": must be b, or c}
+set SETUP {
+    namespace eval ns {
+	namespace export a b
+	proc a args {format 1,[llength $args]}
+	proc b args {format 2,[llength $args]}
+	proc c args {format 3,[llength $args]}
+	proc d args {format 4,[llength $args]}
+	namespace ensemble create -subcommands {b c} -map {c ::ns::d}
+    }
+}
+test namespace-43.8 {ensembles: list-and-map-driven} -setup $SETUP -body {
+    namespace delete ns
+} -result {}
+test namespace-43.9 {ensembles: list-and-map-driven} -setup $SETUP -body {
+    ns a foo bar boo spong wibble
+} -cleanup {namespace delete ns} -returnCodes error -result {unknown or ambiguous subcommand "a": must be b, or c}
+test namespace-43.10 {ensembles: list-and-map-driven} -setup $SETUP -body {
+    ns b foo bar boo spong wibble
+} -cleanup {namespace delete ns} -result 2,5
+test namespace-43.11 {ensembles: list-and-map-driven} -setup $SETUP -body {
+    ns c foo bar boo spong wibble
+} -cleanup {namespace delete ns} -result 4,5
+test namespace-43.12 {ensembles: list-and-map-driven} -setup $SETUP -body {
+    ns d foo bar boo spong wibble
+} -cleanup {namespace delete ns} -returnCodes error -result {unknown or ambiguous subcommand "d": must be b, or c}
+set SETUP {
+    namespace eval ns {
+	namespace export *
+	proc foo args {format bar}
+	proc spong args {format wibble}
+	namespace ensemble create -prefixes off
+    }
+}
+test namespace-43.13 {ensembles: turn off prefixes} -setup $SETUP -body {
+    namespace delete ns
+} -result {}
+test namespace-43.14 {ensembles: turn off prefixes} -setup $SETUP -body {
+    ns fo
+} -cleanup {namespace delete ns} -returnCodes error -result {unknown subcommand "fo": must be foo, or spong}
+test namespace-43.15 {ensembles: turn off prefixes} -setup $SETUP -body {
+    ns foo
+} -cleanup {namespace delete ns} -result bar
+test namespace-43.16 {ensembles: turn off prefixes} -setup $SETUP -body {
+    ns s
+} -cleanup {namespace delete ns} -returnCodes error -result {unknown subcommand "s": must be foo, or spong}
+test namespace-43.17 {ensembles: turn off prefixes} -setup $SETUP -body {
+    ns spong
+} -cleanup {namespace delete ns} -result wibble
+
+test namespace-44.1 {ensemble: errors} {
+    list [catch {namespace ensemble} msg] $msg
+} {1 {wrong # args: should be "namespace ensemble subcommand ?arg ...?"}}
+test namespace-44.2 {ensemble: errors} {
+    list [catch {namespace ensemble ?} msg] $msg
+} {1 {bad subcommand "?": must be configure, create, or exists}}
+test namespace-44.3 {ensemble: errors} {
+    namespace eval ns {
+	list [catch {namespace ensemble create -map x} msg] $msg
+    }
+} {1 {missing value to go with key}}
+test namespace-44.4 {ensemble: errors} {
+    namespace eval ns {
+	list [catch {namespace ensemble create -map {x {}}} msg] $msg
+    }
+} {1 {ensemble subcommand implementations must be non-empty lists}}
+test namespace-44.5 {ensemble: errors} -setup {
+    namespace ensemble create -command foobar -subcommands {foobarcget foobarconfigure}
+} -body {
+    foobar foobarcon
+} -cleanup {
+    rename foobar {}
+} -returnCodes error -result {invalid command name "::foobarconfigure"}
+test namespace-44.6 {ensemble: errors} -returnCodes error -body {
+    namespace ensemble create gorp
+} -result {wrong # args: should be "namespace ensemble create ?option value ...?"}
+
+test namespace-45.1 {ensemble: introspection} {
+    namespace eval ns {
+	namespace export x
+	proc x {} {}
+	namespace ensemble create
+	set ::result [namespace ensemble configure ::ns]
+    }
+    namespace delete ns
+    set result
+} {-map {} -namespace ::ns -parameters {} -prefixes 1 -subcommands {} -unknown {}}
+test namespace-45.2 {ensemble: introspection} {
+    namespace eval ns {
+	namespace export x
+	proc x {} {}
+	namespace ensemble create -map {A x}
+	set ::result [namespace ensemble configure ::ns -map]
+    }
+    namespace delete ns
+    set result
+} {A ::ns::x}
+
+test namespace-46.1 {ensemble: modification} {
+    namespace eval ns {
+	namespace export x
+	proc x {} {format 123}
+	# Ensemble maps A->x
+	namespace ensemble create -command ns -map {A ::ns::x}
+	set ::result [list [namespace ensemble configure ns -map] [ns A]]
+	# Ensemble maps B->x
+	namespace ensemble configure ns -map {B ::ns::x}
+	lappend ::result [namespace ensemble configure ns -map] [ns B]
+	# Ensemble maps x->x
+	namespace ensemble configure ns -map {}
+	lappend ::result [namespace ensemble configure ns -map] [ns x]
+    }
+    namespace delete ns
+    set result
+} {{A ::ns::x} 123 {B ::ns::x} 123 {} 123}
+test namespace-46.2 {ensemble: ensembles really use current export list} {
+    namespace eval ns {
+	namespace export x1
+	proc x1 {} {format 1}
+	proc x2 {} {format 1}
+	namespace ensemble create
+    }
+    catch {ns ?} msg; set result [list $msg]
+    namespace eval ns {namespace export x*}
+    catch {ns ?} msg; lappend result $msg
+    rename ns::x1 {}
+    catch {ns ?} msg; lappend result $msg
+    namespace delete ns
+    set result
+} {{unknown or ambiguous subcommand "?": must be x1} {unknown or ambiguous subcommand "?": must be x1, or x2} {unknown or ambiguous subcommand "?": must be x2}}
+test namespace-46.3 {ensemble: implementation errors} {
+    namespace eval ns {
+	variable count 0
+	namespace ensemble create -map {
+	    a {::lappend ::result}
+	    b {::incr ::ns::count}
+	}
+    }
+    set result {}
+    lappend result [catch { ns } msg] $msg
+    ns a [ns b 10]
+    catch {rename p {}}
+    rename ns p
+    p a [p b 3000]
+    lappend result $ns::count
+    namespace delete ns
+    lappend result [info command p]
+} {1 {wrong # args: should be "ns subcommand ?arg ...?"} 10 3010 3010 {}}
+test namespace-46.4 {ensemble: implementation errors} {
+    namespace eval ns {
+	namespace ensemble create
+    }
+    set result [info command ns]
+    lappend result [catch {ns ?} msg] $msg
+    namespace delete ns
+    set result
+} {ns 1 {unknown subcommand "?": namespace ::ns does not export any commands}}
+test namespace-46.5 {ensemble: implementation errors} {
+    namespace eval ns {
+	namespace ensemble create -map {makeError ::error}
+    }
+    list [catch {ns makeError "an error happened"} msg] $msg $::errorInfo [namespace delete ns]
+} {1 {an error happened} {an error happened
+    while executing
+"ns makeError "an error happened""} {}}
+test namespace-46.6 {ensemble: implementation renames/deletes itself} {
+    namespace eval ns {
+	namespace ensemble create -map {to ::rename}
+    }
+    ns to ns foo
+    foo to foo bar
+    bar to bar spong
+    spong to spong {}
+    namespace delete ns
+} {}
+test namespace-46.7 {ensemble: implementation deletes its namespace} {
+    namespace eval ns {
+	namespace ensemble create -map {kill {::namespace delete}}
+    }
+    ns kill ns
+} {}
+test namespace-46.8 {ensemble: implementation deletes its namespace} {
+    namespace eval ns {
+	namespace export *
+	proc foo {} {
+	    variable x 1
+	    bar
+	    # Tricky; what is the correct return value anyway?
+	    info exist x
+	}
+	proc bar {} {
+	    namespace delete [namespace current]
+	}
+	namespace ensemble create
+    }
+    list [ns foo] [info exist ns::x]
+} {1 0}
+test namespace-46.9 {ensemble: configuring really configures things} {
+    namespace eval ns {
+	namespace ensemble create -map {a a} -prefixes 0
+    }
+    set result [list [catch {ns x} msg] $msg]
+    namespace ensemble configure ns -map {b b}
+    lappend result [catch {ns x} msg] $msg
+    namespace delete ns
+    set result
+} {1 {unknown subcommand "x": must be a} 1 {unknown subcommand "x": must be b}}
+
+test namespace-47.1 {ensemble: unknown handler} {
+    set log {}
+    namespace eval ns {
+	namespace export {[a-z]*}
+	proc Magic {ensemble subcmd args} {
+	    global log
+	    if {[string match {[a-z]*} $subcmd]} {
+		lappend log "making $subcmd"
+		proc $subcmd args {
+		    global log
+		    lappend log "running [info level 0]"
+		    llength $args
+		}
+	    } else {
+		lappend log "unknown $subcmd - args = $args"
+		return -code error \
+			"unknown or protected subcommand \"$subcmd\""
+	    }
+	}
+	namespace ensemble create -unknown ::ns::Magic
+    }
+    set result {}
+    lappend result [catch {ns a b c} msg] $msg
+    lappend result [catch {ns a b c} msg] $msg
+    lappend result [catch {ns b c d} msg] $msg
+    lappend result [catch {ns c d e} msg] $msg
+    lappend result [catch {ns Magic foo bar spong wibble} msg] $msg
+    list $result [lsort [info commands ::ns::*]] $log [namespace delete ns]
+} {{0 2 0 2 0 2 0 2 1 {unknown or protected subcommand "Magic"}} {::ns::Magic ::ns::a ::ns::b ::ns::c} {{making a} {running ::ns::a b c} {running ::ns::a b c} {making b} {running ::ns::b c d} {making c} {running ::ns::c d e} {unknown Magic - args = foo bar spong wibble}} {}}
+test namespace-47.2 {ensemble: unknown handler} {
+    namespace eval ns {
+	namespace export {[a-z]*}
+	proc Magic {ensemble subcmd args} {
+	    error foobar
+	}
+	namespace ensemble create -unknown ::ns::Magic
+    }
+    list [catch {ns spong} msg] $msg $::errorInfo [namespace delete ns]
+} {1 foobar {foobar
+    while executing
+"error foobar"
+    (procedure "::ns::Magic" line 2)
+    invoked from within
+"::ns::Magic ::ns spong"
+    (ensemble unknown subcommand handler)
+    invoked from within
+"ns spong"} {}}
+test namespace-47.3 {ensemble: unknown handler} {
+    namespace eval ns {
+	variable count 0
+	namespace export {[a-z]*}
+	proc a {} {}
+	proc c {} {}
+	proc Magic {ensemble subcmd args} {
+	    variable count
+	    incr count
+	    proc b {} {}
+	}
+	namespace ensemble create -unknown ::ns::Magic
+    }
+    list [catch {ns spong} msg] $msg $ns::count [namespace delete ns]
+} {1 {unknown or ambiguous subcommand "spong": must be a, b, or c} 1 {}}
+test namespace-47.4 {ensemble: unknown handler} {
+    namespace eval ns {
+	namespace export {[a-z]*}
+	proc Magic {ensemble subcmd args} {
+	    return -code break
+	}
+	namespace ensemble create -unknown ::ns::Magic
+    }
+    list [catch {ns spong} msg] $msg $::errorInfo [namespace delete ns]
+} {1 {unknown subcommand handler returned bad code: break} {unknown subcommand handler returned bad code: break
+    result of ensemble unknown subcommand handler: ::ns::Magic ::ns spong
+    invoked from within
+"ns spong"} {}}
+test namespace-47.5 {ensemble: unknown handler} {
+    namespace ensemble create -command foo -unknown bar
+    proc bar {args} {
+	global result target
+	lappend result "LOG $args"
+	return $target
+    }
+    set result {}
+    set target {}
+    lappend result [catch {foo bar} msg] $msg
+    set target {lappend result boo hoo}
+    lappend result [catch {foo bar} msg] $msg [namespace ensemble config foo]
+    rename foo {}
+    set result
+} {{LOG ::foo bar} 1 {unknown subcommand "bar": namespace :: does not export any commands} {LOG ::foo bar} boo hoo 0 {{LOG ::foo bar} 1 {unknown subcommand "bar": namespace :: does not export any commands} {LOG ::foo bar} boo hoo} {-map {} -namespace :: -parameters {} -prefixes 1 -subcommands {} -unknown bar}}
+test namespace-47.6 {ensemble: unknown handler} {
+    namespace ensemble create -command foo -unknown bar
+    proc bar {args} {
+	return "\{"
+    }
+    set result [list [catch {foo bar} msg] $msg $::errorInfo]
+    rename foo {}
+    set result
+} {1 {unmatched open brace in list} {unmatched open brace in list
+    while parsing result of ensemble unknown subcommand handler
+    invoked from within
+"foo bar"}}
+test namespace-47.7 {ensemble: unknown handler, commands with spaces} {
+    namespace ensemble create -command foo -unknown bar
+    proc bar {args} {
+	list ::set ::x [join $args |]
+    }
+    set result [foo {one two three}]
+    rename foo {}
+    set result
+} {::foo|one two three}
+test namespace-47.8 {ensemble: unknown handler, commands with spaces} {
+    namespace ensemble create -command foo -unknown {bar boo}
+    proc bar {args} {
+	list ::set ::x [join $args |]
+    }
+    set result [foo {one two three}]
+    rename foo {}
+    set result
+} {boo|::foo|one two three}
+
+test namespace-48.1 {ensembles and namespace import: unknown handler} {
+    namespace eval foo {
+	namespace export bar
+	namespace ensemble create -command bar -unknown ::foo::u -subcomm x
+	proc u {ens args} {
+	    global result
+	    lappend result $ens $args
+	    namespace ensemble config $ens -subcommand {x y}
+	}
+	proc u2 {ens args} {
+	    global result
+	    lappend result $ens $args
+	    namespace ensemble config ::bar -subcommand {x y z}
+	}
+	proc x args {
+	    global result
+	    lappend result XXX $args
+	}
+	proc y args {
+	    global result
+	    lappend result YYY $args
+	}
+	proc z args {
+	    global result
+	    lappend result ZZZ $args
+	}
+    }
+    namespace import -force foo::bar
+    set result [list [namespace ensemble config bar]]
+    bar x 123
+    bar y 456
+    namespace ensemble config bar -unknown ::foo::u2
+    bar z 789
+    namespace delete foo
+    set result
+} {{-map {} -namespace ::foo -parameters {} -prefixes 1 -subcommands x -unknown ::foo::u} XXX 123 ::foo::bar {y 456} YYY 456 ::foo::bar {z 789} ZZZ 789}
+test namespace-48.2 {ensembles and namespace import: exists} {
+    namespace eval foo {
+	namespace ensemble create -command ::foo::bar
+	namespace export bar
+    }
+    set result     [namespace ensemble exist foo::bar]
+    lappend result [namespace ensemble exist bar]
+    namespace import foo::bar
+    lappend result [namespace ensemble exist bar]
+    rename foo::bar foo::bar2
+    lappend result [namespace ensemble exist bar] \
+	    [namespace ensemble exist spong]
+    rename bar spong
+    lappend result [namespace ensemble exist bar] \
+	    [namespace ensemble exist spong]
+    rename foo::bar2 {}
+    lappend result [namespace ensemble exist spong]
+    namespace delete foo
+    set result
+} {1 0 1 1 0 0 1 0}
+test namespace-48.3 {ensembles and namespace import: config} {
+    catch {rename spong {}}
+    namespace eval foo {
+	namespace ensemble create -command ::foo::bar
+	namespace export bar boo
+	proc boo {} {}
+    }
+    namespace import foo::bar foo::boo
+    set result [namespace ensemble config bar -namespace]
+    lappend result [catch {namespace ensemble config boo} msg] $msg
+    lappend result [catch {namespace ensemble config spong} msg] $msg
+    namespace delete foo
+    set result
+} {::foo 1 {"boo" is not an ensemble command} 1 {unknown command "spong"}}
+
+test namespace-49.1 {ensemble subcommand caching} -body {
+    namespace ens cre -command a -map {b {lappend result 1}}
+    namespace ens cre -command c -map {b {lappend result 2}}
+    proc x {} {a b; c b; a b; c b}
+    x
+} -result {1 2 1 2} -cleanup {
+    rename a {}
+    rename c {}
+    rename x {}
+}
+test namespace-49.2 {strange delete crash} -body {
+    namespace eval foo {namespace ensemble create -command ::bar}
+    trace add command ::bar delete DeleteTrace
+    proc DeleteTrace {old new op} {
+	trace remove command ::bar delete DeleteTrace
+	rename $old ""
+	# This next line caused a bus error in [Bug 1220058]
+	namespace delete foo
+    }
+    rename ::bar ""
+} -result "" -cleanup {
+    rename DeleteTrace ""
+}
+
+test namespace-50.1 {ensembles affect proc arguments error messages} -body {
+    namespace ens cre -command a -map {b {bb foo}}
+    proc bb {c d {e f} args} {list $c $args}
+    a b
+} -returnCodes error -result "wrong # args: should be \"a b d ?e? ?arg ...?\"" -cleanup {
+    rename a {}
+    rename bb {}
+}
+test namespace-50.2 {ensembles affect WrongNumArgs error messages} -body {
+    namespace ens cre -command a -map {b {string is}}
+    a b boolean
+} -returnCodes error -result "wrong # args: should be \"a b class ?-strict? ?-failindex var? str\"" -cleanup {
+    rename a {}
+}
+test namespace-50.3 {chained ensembles affect error messages} -body {
+    namespace ens cre -command a -map {b c}
+    namespace ens cre -command c -map {d e}
+    proc e f {}
+    a b d
+} -returnCodes error -result "wrong # args: should be \"a b d f\"" -cleanup {
+    rename a {}
+    rename c {}
+}
+test namespace-50.4 {chained ensembles affect error messages} -body {
+    namespace ens cre -command a -map {b {c d}}
+    namespace ens cre -command c -map {d {e f}}
+    proc e f {}
+    a b d
+} -returnCodes error -result "wrong # args: should be \"a b\"" -cleanup {
+    rename a {}
+    rename c {}
+}
+test namespace-50.5 {[4402cfa58c]} -setup {
+    proc bar {ev} {}
+    proc bingo {xx} {}
+    namespace ensemble create -command launch -map {foo bar event bingo}
+    set result {}
+} -body {
+    catch {launch foo} m; lappend result $m
+    catch {launch ev} m; lappend result $m
+    catch {launch foo} m; lappend result $m
+} -cleanup {
+    rename launch {}
+    rename bingo {}
+    rename bar {}
+} -result {{wrong # args: should be "launch foo ev"} {wrong # args: should be "launch event xx"} {wrong # args: should be "launch foo ev"}}
+test namespace-50.6 {[4402cfa58c]} -setup {
+    proc target {x y} {}
+    namespace ensemble create -command e2 -map {s2 target}
+    namespace ensemble create -command e1 -map {s1 e2}
+    set result {}
+} -body {
+    set s s
+    catch {e1 s1 s2 a} m; lappend result $m
+    catch {e1 $s s2 a} m; lappend result $m
+    catch {e1 s1 $s a} m; lappend result $m
+    catch {e1 $s $s a} m; lappend result $m
+} -cleanup {
+    rename e1 {}
+    rename e2 {}
+    rename target {}
+} -result {{wrong # args: should be "e1 s1 s2 x y"} {wrong # args: should be "e1 s1 s2 x y"} {wrong # args: should be "e1 s1 s2 x y"} {wrong # args: should be "e1 s1 s2 x y"}}
+test namespace-50.7 {[4402cfa58c]} -setup {
+    proc target {x y} {}
+    namespace ensemble create -command e2 -map {s2 target}
+    namespace ensemble create -command e1 -map {s1 e2} -parameters foo
+    set result {}
+} -body {
+    set s s
+    catch {e1 s2 s1 a} m; lappend result $m
+    catch {e1 $s s1 a} m; lappend result $m
+    catch {e1 s2 $s a} m; lappend result $m
+    catch {e1 $s $s a} m; lappend result $m
+} -cleanup {
+    rename e1 {}
+    rename e2 {}
+    rename target {}
+} -result {{wrong # args: should be "e1 s2 s1 x y"} {wrong # args: should be "e1 s2 s1 x y"} {wrong # args: should be "e1 s2 s1 x y"} {wrong # args: should be "e1 s2 s1 x y"}}
+test namespace-50.8 {[f961d7d1dd]} -setup {
+    proc target {} {}
+    namespace ensemble create -command e -map {s target} -parameters {{a b}}
+} -body {
+    e
+} -returnCodes error -result {wrong # args: should be "e {a b} subcommand ?arg ...?"} -cleanup {
+    rename e {}
+    rename target {}
+}
+test namespace-50.9 {[cea0344a51]} -body {
+    namespace eval foo {
+	namespace eval bar {
+	    namespace delete foo
+	}
+    }
+} -returnCodes error -result {unknown namespace "foo" in namespace delete command}
+
+test namespace-51.1 {name resolution path control} -body {
+    namespace eval ::test_ns_1 {
+	namespace eval test_ns_2 {
+	    proc pathtestA {} {
+		::return [pathtestB],[pathtestC],[pathtestD],[namespace path]
+	    }
+	    proc pathtestC {} {
+		::return 2
+	    }
+	}
+	proc pathtestB {} {
+	    return 1
+	}
+	proc pathtestC {} {
+	    return 1
+	}
+	namespace path ::test_ns_1
+    }
+    proc ::pathtestB {} {
+	return global
+    }
+    proc ::pathtestD {} {
+	return global
+    }
+    test_ns_1::test_ns_2::pathtestA
+} -result "global,2,global," -cleanup {
+    namespace delete ::test_ns_1
+    catch {rename ::pathtestB {}}
+    catch {rename ::pathtestD {}}
+}
+test namespace-51.2 {name resolution path control} -body {
+    namespace eval ::test_ns_1 {
+	namespace eval test_ns_2 {
+	    namespace path ::test_ns_1
+	    proc pathtestA {} {
+		::return [pathtestB],[pathtestC],[pathtestD],[namespace path]
+	    }
+	    proc pathtestC {} {
+		::return 2
+	    }
+	}
+	proc pathtestB {} {
+	    return 1
+	}
+	proc pathtestC {} {
+	    return 1
+	}
+    }
+    proc ::pathtestB {} {
+	return global
+    }
+    proc ::pathtestD {} {
+	return global
+    }
+    ::test_ns_1::test_ns_2::pathtestA
+} -result "1,2,global,::test_ns_1" -cleanup {
+    namespace delete ::test_ns_1
+    catch {rename ::pathtestB {}}
+    catch {rename ::pathtestD {}}
+}
+test namespace-51.3 {name resolution path control} -body {
+    namespace eval ::test_ns_1 {
+	namespace eval test_ns_2 {
+	    proc pathtestA {} {
+		::return [pathtestB],[pathtestC],[pathtestD],[namespace path]
+	    }
+	    proc pathtestC {} {
+		::return 2
+	    }
+	}
+	proc pathtestB {} {
+	    return 1
+	}
+	proc pathtestC {} {
+	    return 1
+	}
+    }
+    proc ::pathtestB {} {
+	return global
+    }
+    proc ::pathtestD {} {
+	return global
+    }
+    set result [::test_ns_1::test_ns_2::pathtestA]
+    namespace eval ::test_ns_1::test_ns_2 {
+	namespace path ::test_ns_1
+    }
+    lappend result [::test_ns_1::test_ns_2::pathtestA]
+    rename ::test_ns_1::pathtestB {}
+    lappend result [::test_ns_1::test_ns_2::pathtestA]
+} -result "global,2,global, 1,2,global,::test_ns_1 global,2,global,::test_ns_1" -cleanup {
+    namespace delete ::test_ns_1
+    catch {rename ::pathtestB {}}
+    catch {rename ::pathtestD {}}
+}
+test namespace-51.4 {name resolution path control} -body {
+    namespace eval ::test_ns_1 {
+	namespace eval test_ns_2 {
+	    proc pathtestA {} {
+		::return [pathtestB],[pathtestC],[pathtestD],[namespace path]
+	    }
+	    proc pathtestC {} {
+		::return 2
+	    }
+	}
+	proc pathtestB {} {
+	    return 1
+	}
+	proc pathtestC {} {
+	    return 1
+	}
+    }
+    proc ::pathtestB {} {
+	return global
+    }
+    proc ::pathtestD {} {
+	return global
+    }
+    set result [::test_ns_1::test_ns_2::pathtestA]
+    namespace eval ::test_ns_1::test_ns_2 {
+	namespace path ::test_ns_1
+    }
+    lappend result [::test_ns_1::test_ns_2::pathtestA]
+    namespace eval ::test_ns_1::test_ns_2 {
+	namespace path {}
+    }
+    lappend result [::test_ns_1::test_ns_2::pathtestA]
+} -result "global,2,global, 1,2,global,::test_ns_1 global,2,global," -cleanup {
+    namespace delete ::test_ns_1
+    catch {rename ::pathtestB {}}
+    catch {rename ::pathtestD {}}
+}
+test namespace-51.5 {name resolution path control} -body {
+    namespace eval ::test_ns_1 {
+	namespace eval test_ns_2 {
+	    proc pathtestA {} {
+		::return [pathtestB],[pathtestC],[pathtestD],[namespace path]
+	    }
+	    proc pathtestC {} {
+		::return 2
+	    }
+	    namespace path ::test_ns_1
+	}
+	proc pathtestB {} {
+	    return 1
+	}
+	proc pathtestC {} {
+	    return 1
+	}
+	proc pathtestD {} {
+	    return 1
+	}
+    }
+    proc ::pathtestB {} {
+	return global
+    }
+    proc ::pathtestD {} {
+	return global
+    }
+    set result [::test_ns_1::test_ns_2::pathtestA]
+    namespace eval ::test_ns_1::test_ns_2 {
+	namespace path {:: ::test_ns_1}
+    }
+    lappend result [::test_ns_1::test_ns_2::pathtestA]
+    rename ::test_ns_1::test_ns_2::pathtestC {}
+    lappend result [::test_ns_1::test_ns_2::pathtestA]
+} -result "1,2,1,::test_ns_1 {global,2,global,:: ::test_ns_1} {global,1,global,:: ::test_ns_1}" -cleanup {
+    namespace delete ::test_ns_1
+    catch {rename ::pathtestB {}}
+    catch {rename ::pathtestD {}}
+}
+test namespace-51.6 {name resolution path control} -body {
+    namespace eval ::test_ns_1 {
+	namespace eval test_ns_2 {
+	    proc pathtestA {} {
+		::return [pathtestB],[pathtestC],[pathtestD],[namespace path]
+	    }
+	    proc pathtestC {} {
+		::return 2
+	    }
+	    namespace path ::test_ns_1
+	}
+	proc pathtestB {} {
+	    return 1
+	}
+	proc pathtestC {} {
+	    return 1
+	}
+	proc pathtestD {} {
+	    return 1
+	}
+    }
+    proc ::pathtestB {} {
+	return global
+    }
+    proc ::pathtestD {} {
+	return global
+    }
+    set result [::test_ns_1::test_ns_2::pathtestA]
+    namespace eval ::test_ns_1::test_ns_2 {
+	namespace path {:: ::test_ns_1}
+    }
+    lappend result [::test_ns_1::test_ns_2::pathtestA]
+    rename ::test_ns_1::test_ns_2::pathtestC {}
+    lappend result [::test_ns_1::test_ns_2::pathtestA]
+    proc ::pathtestC {} {
+	return global
+    }
+    lappend result [::test_ns_1::test_ns_2::pathtestA]
+} -result "1,2,1,::test_ns_1 {global,2,global,:: ::test_ns_1} {global,1,global,:: ::test_ns_1} {global,global,global,:: ::test_ns_1}" -cleanup {
+    namespace delete ::test_ns_1
+    catch {rename ::pathtestB {}}
+    catch {rename ::pathtestD {}}
+}
+test namespace-51.7 {name resolution path control} -body {
+    namespace eval ::test_ns_1 {
+    }
+    namespace eval ::test_ns_2 {
+	namespace path ::test_ns_1
+	proc getpath {} {namespace path}
+    }
+    list [::test_ns_2::getpath] [namespace delete ::test_ns_1] [::test_ns_2::getpath]
+} -result {::test_ns_1 {} {}} -cleanup {
+    catch {namespace delete ::test_ns_1}
+    namespace delete ::test_ns_2
+}
+test namespace-51.8 {name resolution path control} -body {
+    namespace eval ::test_ns_1 {
+    }
+    namespace eval ::test_ns_2 {
+    }
+    namespace eval ::test_ns_3 {
+    }
+    namespace eval ::test_ns_4 {
+	namespace path {::test_ns_1 ::test_ns_2 ::test_ns_3}
+	proc getpath {} {namespace path}
+    }
+    list [::test_ns_4::getpath] [namespace delete ::test_ns_2] [::test_ns_4::getpath]
+} -result {{::test_ns_1 ::test_ns_2 ::test_ns_3} {} {::test_ns_1 ::test_ns_3}} -cleanup {
+    catch {namespace delete ::test_ns_1}
+    catch {namespace delete ::test_ns_2}
+    catch {namespace delete ::test_ns_3}
+    catch {namespace delete ::test_ns_4}
+}
+test namespace-51.9 {name resolution path control} -body {
+    namespace eval ::test_ns_1 {
+    }
+    namespace eval ::test_ns_2 {
+    }
+    namespace eval ::test_ns_3 {
+    }
+    namespace eval ::test_ns_4 {
+	namespace path {::test_ns_1 ::test_ns_2 ::test_ns_3}
+	proc getpath {} {namespace path}
+    }
+    list [::test_ns_4::getpath] [namespace delete ::test_ns_2] [namespace eval ::test_ns_2 {}] [::test_ns_4::getpath]
+} -result {{::test_ns_1 ::test_ns_2 ::test_ns_3} {} {} {::test_ns_1 ::test_ns_3}} -cleanup {
+    catch {namespace delete ::test_ns_1}
+    catch {namespace delete ::test_ns_2}
+    catch {namespace delete ::test_ns_3}
+    catch {namespace delete ::test_ns_4}
+}
+test namespace-51.10 {name resolution path control} -body {
+    namespace eval ::test_ns_1 {
+	namespace path does::not::exist
+    }
+} -returnCodes error -result {namespace "does::not::exist" not found in "::test_ns_1"} -cleanup {
+    catch {namespace delete ::test_ns_1}
+}
+test namespace-51.11 {name resolution path control} -body {
+    namespace eval ::test_ns_1 {
+	proc foo {} {return 1}
+    }
+    namespace eval ::test_ns_2 {
+	proc foo {} {return 2}
+    }
+    namespace eval ::test_ns_3 {
+	namespace path ::test_ns_1
+    }
+    namespace eval ::test_ns_4 {
+	namespace path {::test_ns_3 ::test_ns_2}
+	foo
+    }
+} -result 2 -cleanup {
+    catch {namespace delete ::test_ns_1}
+    catch {namespace delete ::test_ns_2}
+    catch {namespace delete ::test_ns_3}
+    catch {namespace delete ::test_ns_4}
+}
+test namespace-51.12 {name resolution path control} -body {
+    namespace eval ::test_ns_1 {
+	proc foo {} {return 1}
+    }
+    namespace eval ::test_ns_2 {
+	proc foo {} {return 2}
+    }
+    namespace eval ::test_ns_3 {
+	namespace path ::test_ns_1
+    }
+    namespace eval ::test_ns_4 {
+	namespace path {::test_ns_3 ::test_ns_2}
+	list [foo] [namespace delete ::test_ns_3] [foo]
+    }
+} -result {2 {} 2} -cleanup {
+    catch {namespace delete ::test_ns_1}
+    catch {namespace delete ::test_ns_2}
+    catch {namespace delete ::test_ns_3}
+    catch {namespace delete ::test_ns_4}
+}
+test namespace-51.13 {name resolution path control} -body {
+    set ::result {}
+    namespace eval ::test_ns_1 {
+	proc foo {} {lappend ::result 1}
+    }
+    namespace eval ::test_ns_2 {
+	proc foo {} {lappend ::result 2}
+	trace add command foo delete "namespace eval ::test_ns_3 foo;#"
+    }
+    namespace eval ::test_ns_3 {
+	proc foo {} {
+	    lappend ::result 3
+	    namespace delete [namespace current]
+	    ::test_ns_4::bar
+	}
+    }
+    namespace eval ::test_ns_4 {
+	namespace path {::test_ns_2 ::test_ns_3 ::test_ns_1}
+	proc bar {} {
+	    list [foo] [namespace delete ::test_ns_2] [foo]
+	}
+	bar
+    }
+    # Should the result be "2 {} {2 3 2 1}" instead?
+} -result {2 {} {2 3 1 1}} -cleanup {
+    catch {namespace delete ::test_ns_1}
+    catch {namespace delete ::test_ns_2}
+    catch {namespace delete ::test_ns_3}
+    catch {namespace delete ::test_ns_4}
+}
+test namespace-51.14 {name resolution path control} -setup {
+    foreach cmd [info commands foo*] {
+	rename $cmd {}
+    }
+    namespace eval ::test_ns_1 {}
+    namespace eval ::test_ns_2 {}
+    namespace eval ::test_ns_3 {}
+} -body {
+    proc foo0 {} {}
+    proc ::test_ns_1::foo1 {} {}
+    proc ::test_ns_2::foo2 {} {}
+    namespace eval ::test_ns_3 {
+	variable result {}
+	lappend result [info commands foo*]
+	namespace path {::test_ns_1 ::test_ns_2}
+	lappend result [info commands foo*]
+	proc foo2 {} {}
+	lappend result [info commands foo*]
+	rename foo2 {}
+	lappend result [info commands foo*]
+	namespace delete ::test_ns_1
+	lappend result [info commands foo*]
+    }
+} -cleanup {
+    catch {namespace delete ::test_ns_1}
+    catch {namespace delete ::test_ns_2}
+    catch {namespace delete ::test_ns_3}
+} -result {foo0 {foo1 foo2 foo0} {foo2 foo1 foo0} {foo1 foo2 foo0} {foo2 foo0}}
+test namespace-51.15 {namespace resolution path control} -body {
+    namespace eval ::test_ns_2 {
+	proc foo {} {return 2}
+    }
+    namespace eval ::test_ns_1 {
+	namespace eval test_ns_2 {
+	    proc foo {} {return 1_2}
+	}
+	namespace eval test_ns_3 {
+	    namespace path ::test_ns_1
+	    test_ns_2::foo
+	}
+    }
+} -result 1_2 -cleanup {
+    namespace delete ::test_ns_1
+    namespace delete ::test_ns_2
+}
+test namespace-51.16 {Bug 1566526} {
+    interp create slave
+    slave eval namespace eval demo namespace path ::
+    interp delete slave
+} {}
+test namespace-51.17 {resolution epoch handling: Bug 2898722} -setup {
+    set result {}
+    catch {namespace delete ::a}
+} -body {
+    namespace eval ::a {
+	proc c {} {lappend ::result A}
+	c
+	namespace eval b {
+	    variable d c
+	    lappend ::result [catch { $d }]
+	}
+	lappend ::result .
+	namespace eval b {
+	    namespace path [namespace parent]
+	    $d;[format %c 99]
+	}
+	lappend ::result .
+	namespace eval b {
+	    proc c {} {lappend ::result B}
+	    $d;[format %c 99]
+	}
+	lappend ::result .
+    }
+    namespace eval ::a::b {
+	$d;[format %c 99]
+	lappend ::result .
+	proc ::c {} {lappend ::result G}
+	$d;[format %c 99]
+	lappend ::result .
+	rename ::a::c {}
+	$d;[format %c 99]
+	lappend ::result .
+	rename ::a::b::c {}
+	$d;[format %c 99]
+    }
+} -cleanup {
+    namespace delete ::a
+    catch {rename ::c {}}
+    unset result
+} -result {A 1 . A A . B B . B B . B B . B B . G G}
+test namespace-51.18 {Bug 3185407} -setup {
+    namespace eval ::test_ns_1 {}
+} -body {
+    namespace eval ::test_ns_1 {
+	variable result {}
+	namespace eval ns {proc foo {} {}}
+	namespace eval ns2 {proc foo {} {}}
+	namespace path {ns ns2}
+	variable x foo
+	lappend result [namespace which $x]
+	proc foo {} {}
+	lappend result [namespace which $x]
+    }
+} -cleanup {
+    namespace delete ::test_ns_1
+} -result {::test_ns_1::ns::foo ::test_ns_1::foo}
+
+# TIP 181 - namespace unknown tests
+test namespace-52.1 {unknown: default handler ::unknown} {
+    set result [list [namespace eval foobar { namespace unknown }]]
+    lappend result [namespace eval :: { namespace unknown }]
+    namespace delete foobar
+    set result
+} {{} ::unknown}
+test namespace-52.2 {unknown: default resolution global} {
+    proc ::foo {} { return "GLOBAL" }
+    namespace eval ::bar { proc foo {} { return "NAMESPACE" } }
+    namespace eval ::bar::jim { proc test {} { foo } }
+    set result [::bar::jim::test]
+    namespace delete ::bar
+    rename ::foo {}
+    set result
+} {GLOBAL}
+test namespace-52.3 {unknown: default resolution local} {
+    proc ::foo {} { return "GLOBAL" }
+    namespace eval ::bar {
+	proc foo {} { return "NAMESPACE" }
+	proc test {} { foo }
+    }
+    set result [::bar::test]
+    namespace delete ::bar
+    rename ::foo {}
+    set result
+} {NAMESPACE}
+test namespace-52.4 {unknown: set handler} {
+    namespace eval foo {
+	namespace unknown [list dispatch]
+	proc dispatch {args} { return $args }
+	proc test {} {
+	    UnknownCmd a b c
+	}
+    }
+    set result [foo::test]
+    namespace delete foo
+    set result
+} {UnknownCmd a b c}
+test namespace-52.5 {unknown: search path before unknown is unaltered} {
+    proc ::test2 {args} { return "TEST2: $args" }
+    namespace eval foo {
+	namespace unknown [list dispatch]
+	proc dispatch {args} { return "UNKNOWN: $args" }
+	proc test1 {args} { return "TEST1: $args" }
+	proc test {} {
+	    set result [list [test1 a b c]]
+	    lappend result [test2 a b c]
+	    lappend result [test3 a b c]
+	    return $result
+	}
+    }
+    set result [foo::test]
+    namespace delete foo
+    rename ::test2 {}
+    set result
+} {{TEST1: a b c} {TEST2: a b c} {UNKNOWN: test3 a b c}}
+test namespace-52.6 {unknown: deleting handler restores default} {
+    rename ::unknown ::_unknown_orig
+    proc ::unknown {args} { return "DEFAULT: $args" }
+    namespace eval foo {
+	namespace unknown dummy
+	namespace unknown {}
+    }
+    set result [namespace eval foo { dummy a b c }]
+    rename ::unknown {}
+    rename ::_unknown_orig ::unknown
+    namespace delete foo
+    set result
+} {DEFAULT: dummy a b c}
+test namespace-52.7 {unknown: setting global unknown handler} {
+    proc ::myunknown {args} { return "MYUNKNOWN: $args" }
+    namespace eval :: { namespace unknown ::myunknown }
+    set result [namespace eval foo { dummy a b c }]
+    namespace eval :: { namespace unknown {} }
+    rename ::myunknown {}
+    namespace delete foo
+    set result
+} {MYUNKNOWN: dummy a b c}
+test namespace-52.8 {unknown: destroying and redefining global namespace} {
+    set i [interp create]
+    $i hide proc
+    $i hide namespace
+    $i hide return
+    $i invokehidden namespace delete ::
+    $i expose return
+    $i invokehidden proc unknown args { return "FINE" }
+    $i eval { foo bar bob }
+} {FINE}
+test namespace-52.9 {unknown: refcounting} -setup {
+    proc this args {
+	unset args		;# stop sharing
+	set copy [namespace unknown]
+	string length $copy	;# shimmer away list rep
+	info level 0
+    }
+    set handler [namespace unknown]
+    namespace unknown {this is a test}
+    catch {rename noSuchCommand {}}
+} -body {
+    noSuchCommand
+} -cleanup {
+    namespace unknown $handler
+    rename this {}
+} -result {this is a test noSuchCommand}
+testConstraint testevalobjv [llength [info commands testevalobjv]]
+test namespace-52.10 {unknown: with TCL_EVAL_GLOBAL} -constraints {
+    testevalobjv
+} -setup {
+    rename ::unknown unknown.save
+    proc ::unknown args {
+	set caller [uplevel 1 {namespace current}]
+	namespace eval $caller {
+	    variable foo
+	    return $foo
+	}
+    }
+    catch {rename ::noSuchCommand {}}
+} -body {
+    namespace eval :: {
+	variable foo SUCCESS
+    }
+    namespace eval test_ns_1 {
+	variable foo FAIL
+	testevalobjv 1 noSuchCommand
+    }
+} -cleanup {
+    unset -nocomplain ::foo
+    namespace delete test_ns_1
+    rename ::unknown {}
+    rename unknown.save ::unknown
+} -result SUCCESS
+test namespace-52.11 {unknown: with TCL_EVAL_INVOKE} -setup {
+    set handler [namespace eval :: {namespace unknown}]
+    namespace eval :: {namespace unknown unknown}
+    rename ::unknown unknown.save
+    namespace eval :: {
+	proc unknown args {
+	    return SUCCESS
+	}
+    }
+    catch {rename ::noSuchCommand {}}
+    set ::slave [interp create]
+} -body {
+    $::slave alias bar noSuchCommand
+    namespace eval test_ns_1 {
+	namespace unknown unknown
+	proc unknown args {
+	    return FAIL
+	}
+	$::slave eval bar
+    }
+} -cleanup {
+    interp delete $::slave
+    unset ::slave
+    namespace delete test_ns_1
+    rename ::unknown {}
+    rename unknown.save ::unknown
+    namespace eval :: [list namespace unknown $handler]
+} -result SUCCESS
+test namespace-52.12 {unknown: error case must not reset handler} -body {
+    namespace eval foo {
+	namespace unknown ok
+	catch {namespace unknown {{}{}{}}}
+	namespace unknown
+    }
+} -cleanup {
+    namespace delete foo
+} -result ok
+
+# TIP 314 - ensembles with parameters
+test namespace-53.1 {ensembles: parameters} {
+    namespace eval ns {
+	namespace export x
+	proc x {para} {list 1 $para}
+	namespace ensemble create -parameters {para1}
+    }
+    list [info command ns] [ns bar x] [namespace delete ns] [info command ns]
+} {ns {1 bar} {} {}}
+test namespace-53.2 {ensembles: parameters} -setup {
+    namespace eval ns {
+	namespace export x
+	proc x {para} {list 1 $para}
+	namespace ensemble create
+    }
+} -body {
+    namespace ensemble configure ns -parameters {para1}
+    rename ns foo
+    list [info command foo] [foo bar x] [namespace delete ns] [info command foo]
+} -result {foo {1 bar} {} {}}
+test namespace-53.3 {ensembles: parameters} -setup {
+    namespace eval ns {
+	namespace export x*
+	proc x1 {para} {list 1 $para}
+	proc x2 {para} {list 2 $para}
+	namespace ensemble create -parameters param1
+    }
+} -body {
+    set result [list [ns x2 x1] [ns x1 x2]]
+    lappend result [catch {ns x} msg] $msg
+    lappend result [catch {ns x x} msg] $msg
+    rename ns {}
+    lappend result [info command ns::x1]
+    namespace delete ns
+    lappend result [info command ns::x1]
+} -result\
+   {{1 x2} {2 x1}\
+    1 {wrong # args: should be "ns param1 subcommand ?arg ...?"}\
+    1 {unknown or ambiguous subcommand "x": must be x1, or x2}\
+    ::ns::x1 {}}
+test namespace-53.4 {ensembles: parameters} -setup {
+    namespace eval ns {
+	namespace export x*
+	proc x1 {a1 a2} {list 1 $a1 $a2}
+	proc x2 {a1 a2} {list 2 $a1 $a2}
+	proc x3 {a1 a2} {list 3 $a1 $a2}
+	namespace ensemble create
+    }
+} -body {
+    set result {}
+    lappend result [ns x1 x2 x3]
+    namespace ensemble configure ns -parameters p1
+    lappend result [ns x1 x2 x3]
+    namespace ensemble configure ns -parameters {p1 p2}
+    lappend result [ns x1 x2 x3]
+} -cleanup {
+    namespace delete ns
+} -result {{1 x2 x3} {2 x1 x3} {3 x1 x2}}
+test namespace-53.5 {ensembles: parameters} -setup {
+    namespace eval ns {
+	namespace export x*
+	proc x1 {para} {list 1 $para}
+	proc x2 {para} {list 2 $para}
+	proc x3 {para} {list 3 $para}
+	namespace ensemble create
+    }
+} -body {
+    set result [list [catch {ns x x1} msg] $msg]
+    lappend result [catch {ns x1 x} msg] $msg
+    namespace ensemble configure ns -parameters p1
+    lappend result [catch {ns x1 x} msg] $msg
+    lappend result [catch {ns x x1} msg] $msg
+} -cleanup {
+    namespace delete ns
+} -result\
+   {1 {unknown or ambiguous subcommand "x": must be x1, x2, or x3}\
+    0 {1 x}\
+    1 {unknown or ambiguous subcommand "x": must be x1, x2, or x3}\
+    0 {1 x}}
+test namespace-53.6 {ensembles: nested} -setup {
+    namespace eval ns {
+	namespace export x*
+	namespace eval x0 {
+	    proc z {args} {list 0 $args}
+	    namespace export z
+	    namespace ensemble create
+	}
+	proc x1 {args} {list 1 $args}
+	proc x2 {args} {list 2 $args}
+	proc x3 {args} {list 3 $args}
+	namespace ensemble create -parameters p
+    }
+} -body {
+    list [ns z x0] [ns z x1] [ns z x2] [ns z x3]
+} -cleanup {
+    namespace delete ns
+} -result {{0 {}} {1 z} {2 z} {3 z}}
+test namespace-53.7 {ensembles: parameters & wrong # args} -setup {
+    namespace eval ns {
+	namespace export x*
+	proc x1 {a1 a2 a3 a4} {list x1 $a1 $a2 $a3 $a4}
+	namespace ensemble create -parameters p1
+    }
+} -body {
+    set result {}
+    lappend result [catch {ns} msg] $msg
+    lappend result [catch {ns x1} msg] $msg
+    lappend result [catch {ns x1 x1} msg] $msg
+    lappend result [catch {ns x1 x1 x1} msg] $msg
+    lappend result [catch {ns x1 x1 x1 x1} msg] $msg
+    lappend result [catch {ns x1 x1 x1 x1 x1} msg] $msg
+} -cleanup {
+    namespace delete ns
+} -result\
+   {1 {wrong # args: should be "ns p1 subcommand ?arg ...?"}\
+    1 {wrong # args: should be "ns p1 subcommand ?arg ...?"}\
+    1 {wrong # args: should be "ns x1 x1 a2 a3 a4"}\
+    1 {wrong # args: should be "ns x1 x1 a2 a3 a4"}\
+    1 {wrong # args: should be "ns x1 x1 a2 a3 a4"}\
+    0 {x1 x1 x1 x1 x1}}
+test namespace-53.8 {ensemble: unknown handler changing -parameters} -setup {
+    namespace eval ns {
+	namespace export x*
+	proc x1 {a1} {list 1 $a1}
+	proc Magic {ensemble subcmd args} {
+	    namespace ensemble configure $ensemble\
+              -parameters [lrange p1 [llength [
+                namespace ensemble configure $ensemble -parameters
+              ]] 0]
+            list
+	}
+	namespace ensemble create -unknown ::ns::Magic
+    }
+} -body {
+    set result {}
+    lappend result [catch {ns x1 x2} msg] $msg [namespace ensemble configure ns -parameters]
+    lappend result [catch {ns x2 x1} msg] $msg [namespace ensemble configure ns -parameters]
+    lappend result [catch {ns x2 x3} msg] $msg [namespace ensemble configure ns -parameters]
+} -cleanup {
+    namespace delete ns
+} -result\
+   {0 {1 x2} {}\
+    0 {1 x2} p1\
+    1 {unknown or ambiguous subcommand "x2": must be x1} {}}
+test namespace-53.9 {ensemble: unknown handler changing -parameters,\
+  thereby eating all args} -setup {
+    namespace eval ns {
+	namespace export x*
+	proc x1 {args} {list 1 $args}
+	proc Magic {ensemble subcmd args} {
+	    namespace ensemble configure $ensemble\
+              -parameters {p1 p2 p3 p4 p5}
+            list
+	}
+	namespace ensemble create -unknown ::ns::Magic
+    }
+} -body {
+    set result {}
+    lappend result [catch {ns x1 x2} msg] $msg [namespace ensemble configure ns -parameters]
+    lappend result [catch {ns x2 x1} msg] $msg [namespace ensemble configure ns -parameters]
+    lappend result [catch {ns a1 a2 a3 a4 a5 x1} msg] $msg [namespace ensemble configure ns -parameters]
+} -cleanup {
+    namespace delete ns
+} -result\
+   {0 {1 x2} {}\
+    1 {wrong # args: should be "ns p1 p2 p3 p4 p5 subcommand ?arg ...?"} {p1 p2 p3 p4 p5}\
+    0 {1 {a1 a2 a3 a4 a5}} {p1 p2 p3 p4 p5}}
+test namespace-53.10 {ensembles: nested rewrite} -setup {
+    namespace eval ns {
+	namespace export x
+	namespace eval x {
+	    proc z0 {} {list 0}
+	    proc z1 {a1} {list 1 $a1}
+	    proc z2 {a1 a2} {list 2 $a1 $a2}
+	    proc z3 {a1 a2 a3} {list 3 $a1 $a2 $a3}
+	    namespace export z*
+	    namespace ensemble create
+	}
+	namespace ensemble create -parameters p
+    }
+} -body {
+    set result {}
+    # In these cases, parsing the subensemble does not grab a new word.
+    lappend result [catch {ns z0 x} msg] $msg
+    lappend result [catch {ns z1 x} msg] $msg
+    lappend result [catch {ns z2 x} msg] $msg
+    lappend result [catch {ns z2 x v} msg] $msg
+    namespace ensemble configure ns::x -parameters q1
+    # In these cases, parsing the subensemble grabs a new word.
+    lappend result [catch {ns v x z0} msg] $msg
+    lappend result [catch {ns v x z1} msg] $msg
+    lappend result [catch {ns v x z2} msg] $msg
+    lappend result [catch {ns v x z2 v2} msg] $msg
+} -cleanup {
+    namespace delete ns
+} -result\
+   {0 0\
+    1 {wrong # args: should be "ns z1 x a1"}\
+    1 {wrong # args: should be "ns z2 x a1 a2"}\
+    1 {wrong # args: should be "ns z2 x a1 a2"}\
+    1 {wrong # args: should be "::ns::x::z0"}\
+    0 {1 v}\
+    1 {wrong # args: should be "ns v x z2 a2"}\
+    0 {2 v v2}}
+test namespace-53.11 {ensembles: nested rewrite} -setup {
+    namespace eval ns {
+	namespace export x
+	namespace eval x {
+	    proc z2 {a1 a2} {list 2 $a1 $a2}
+	    namespace export z*
+	    namespace ensemble create -parameter p
+	}
+	namespace ensemble create
+    }
+} -body {
+    list [catch {ns x 1 z2} msg] $msg
+} -cleanup {
+    namespace delete ns
+    unset -nocomplain msg
+} -result {1 {wrong # args: should be "ns x 1 z2 a2"}}
+
+test namespace-54.1 {leak on namespace deletion} -constraints {memory} \
+-setup {
+    proc getbytes {} {
+	set lines [split [memory info] "\n"]
+	lindex $lines 3 3
+    }
+} -body {
+    set end [getbytes]
+    for {set i 0} {$i < 5} {incr i} {
+	set ns ::y$i
+	namespace eval $ns {}
+	namespace delete $ns
+	set start $end
+	set end [getbytes]
+    }
+    set leakedBytes [expr {$end - $start}]
+} -cleanup {
+    rename getbytes {}
+    unset i ns start end
+} -result 0
+
+test namespace-55.1 {compiled ensembles inside compiled ensembles: Bug 6d2f249a01} {
+    info class [format %s constructor] oo::object
+} ""
+
+test namespace-56.1 {bug f97d4ee020: mutually-entangled deletion} {
+    namespace eval ::testing {
+	proc abc {} {}
+	proc def {} {}
+	trace add command abc delete "rename ::testing::def {}; #"
+	trace add command def delete "rename ::testing::abc {}; #"
+    }
+    namespace delete ::testing
+} {}
+test namespace-56.2 {bug f97d4ee020: mutually-entangled deletion} {
+    namespace eval ::testing {
+	namespace eval abc {proc xyz {} {}}
+	namespace eval def {proc xyz {} {}}
+	trace add command abc::xyz delete "namespace delete ::testing::def {}; #"
+	trace add command def::xyz delete "namespace delete ::testing::abc {}; #"
+    }
+    namespace delete ::testing
+} {}
+test namespace-56.3 {bug f97d4ee020: mutually-entangled deletion} {
+    namespace eval ::testing {
+	variable gone {}
+	oo::class create CB {
+	    variable cmd
+	    constructor other {set cmd $other}
+	    destructor {rename $cmd {}; lappend ::testing::gone $cmd}
+	}
+	namespace eval abc {
+	    ::testing::CB create def ::testing::abc::ghi
+	    ::testing::CB create ghi ::testing::abc::def
+	}
+	namespace delete abc
+	try {
+	    return [lsort $gone]
+	} finally {
+	    namespace delete ::testing
+	}
+    }
+} {::testing::abc::def ::testing::abc::ghi}
+
+# cleanup
+catch {rename cmd1 {}}
+catch {unset l}
+catch {unset msg}
+catch {unset trigger}
+namespace delete {*}[namespace children :: test_ns_*]
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/tests/notify.test b/tests/notify.test
new file mode 100644
index 0000000..d2b9123
--- /dev/null
+++ b/tests/notify.test
@@ -0,0 +1,327 @@
+#  -*- tcl -*-
+#
+# notify.test --
+#
+# This file tests several functions in the file, 'generic/tclNotify.c'.
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands.  Sourcing this file into Tcl runs the tests and
+# generates output for errors.  No output means no errors were found.
+#
+# Copyright (c) 2003 by Kevin B. Kenny.  All rights reserved.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+    package require tcltest 2
+    namespace import -force ::tcltest::*
+}
+
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
+
+testConstraint testevent [llength [info commands testevent]]
+
+test notify-1.1 {Tcl_QueueEvent and delivery of a single event} \
+    -constraints {testevent} \
+    -body {
+	set delivered {}
+	after 10 set done 1
+	testevent queue one tail {lappend delivered one; expr 1}
+	vwait done
+	set delivered
+    } \
+    -result {one}
+
+test notify-1.2 {Tcl_QueueEvent and delivery of events in order} \
+    -constraints {testevent} \
+    -body {
+	set delivered {}
+	after 10 set done 1
+	testevent queue one tail {lappend delivered one; expr 1}
+	testevent queue two tail {lappend delivered two; expr 1}
+	testevent queue three tail {lappend delivered three; expr 1}
+	vwait done
+	set delivered
+    } \
+    -result {one two three}
+
+test notify-1.3 {Tcl_QueueEvent at head} \
+    -constraints {testevent} \
+    -body {
+	set delivered {}
+	after 10 set done 1
+	testevent queue one head {lappend delivered one; expr 1}
+	vwait done
+	set delivered
+    } \
+    -result one
+
+test notify-1.4 {Tcl_QueueEvent multiple events at head} \
+    -constraints {testevent} \
+    -body {
+	set delivered {}
+	after 10 set done 1
+	testevent queue one head {lappend delivered one; expr 1}
+	testevent queue two head {lappend delivered two; expr 1}
+	testevent queue three head {lappend delivered three; expr 1}
+	vwait done
+	set delivered
+    } \
+    -result {three two one}
+
+test notify-1.5 {Tcl_QueueEvent marker event into an empty queue} \
+    -constraints {testevent} \
+    -body {
+	set delivered {}
+	after 10 set done 1
+	testevent queue one mark {lappend delivered one; expr 1}
+	vwait done
+	set delivered
+    } \
+    -result one
+
+test notify-1.6 {Tcl_QueueEvent first marker event in a nonempty queue} \
+    -constraints {testevent}  \
+    -body {
+	set delivered {}
+	after 10 set done 1
+	testevent queue one tail {lappend delivered one; expr 1}
+	testevent queue two mark {lappend delivered two; expr 1}
+	testevent queue three head {lappend delivered three; expr 1}
+	vwait done
+	set delivered
+    } \
+    -result {three two one}
+
+test notify-1.7 {Tcl_QueueEvent second marker event} \
+    -constraints {testevent} \
+    -body {
+	set delivered {}
+	after 10 set done 1
+	testevent queue one mark {lappend delivered one; expr 1}
+	testevent queue two mark {lappend delivered two; expr 1}
+	vwait done
+	set delivered
+    } \
+    -result {one two}
+
+test notify-1.8 {Tcl_QueueEvent preexisting event following second marker} \
+    -constraints {testevent} \
+    -body {
+	set delivered {}
+	after 10 set done 1
+	testevent queue one mark {lappend delivered one; expr 1}
+	testevent queue two tail {lappend delivered two; expr 1}
+	testevent queue three mark {lappend delivered three; expr 1}
+	vwait done
+	set delivered
+    } \
+    -result {one three two}
+
+test notify-2.1 {remove sole element, don't replace } \
+    -constraints {testevent} \
+    -body {
+	set delivered {}
+	after 10 set done 1
+	testevent queue one tail {lappend delivered one; expr 1}
+	testevent delete one
+	vwait done
+	set delivered
+    } \
+    -result {}
+
+test notify-2.2 {remove and replace sole element} \
+    -constraints {testevent} \
+    -body {
+	set delivered {}
+	after 10 set done 1
+	testevent queue one tail {lappend delivered one; expr 1}
+	testevent delete one
+	testevent queue two tail {lappend delivered two; expr 1}
+	vwait done
+	set delivered
+    } \
+    -result two
+
+test notify-2.3 {remove first element} \
+    -constraints {testevent} \
+    -body {
+	set delivered {}
+	after 10 set done 1
+	testevent queue one tail {lappend delivered one; expr 1}
+	testevent queue two tail {lappend delivered two; expr 1}
+	testevent delete one
+	vwait done
+	set delivered
+    } \
+    -result {two}
+
+test notify-2.4 {remove and replace first element} \
+    -constraints {testevent} \
+    -body {
+	set delivered {}
+	after 10 set done 1
+	testevent queue one tail {lappend delivered one; expr 1}
+	testevent queue two tail {lappend delivered two; expr 1}
+	testevent delete one
+	testevent queue three head {lappend delivered three; expr 1};
+	vwait done
+	set delivered
+    } \
+    -result {three two}
+
+test notify-2.5 {remove last element} \
+    -constraints {testevent} \
+    -body {
+	set delivered {}
+	after 10 set done 1
+	testevent queue one tail {lappend delivered one; expr 1}
+	testevent queue two tail {lappend delivered two; expr 1}
+	testevent delete two
+	vwait done
+	set delivered
+    } \
+    -result {one}
+
+
+test notify-2.6 {remove and replace last element} \
+    -constraints {testevent} \
+    -body {
+	set delivered {}
+	after 10 set done 1
+	testevent queue one tail {lappend delivered one; expr 1}
+	testevent queue two tail {lappend delivered two; expr 1}
+	testevent delete two
+	testevent queue three tail {lappend delivered three; expr 1};
+	vwait done
+	set delivered
+    } \
+    -result {one three}
+
+test notify-2.7 {remove a middle element} \
+    -constraints {testevent} \
+    -body {
+	set delivered {}
+	after 10 set done 1
+	testevent queue one tail {lappend delivered one; expr 1}
+	testevent queue two tail {lappend delivered two; expr 1}
+	testevent queue three tail {lappend delivered three; expr 1}
+	testevent delete two
+	vwait done
+	set delivered
+    } \
+    -result {one three}
+
+test notify-2.8 {remove a marker event that's the sole event in the queue} \
+    -constraints {testevent} \
+    -body {
+	set delivered {}
+	after 10 set done 1
+	testevent queue one mark {lappend delivered one; expr 1}
+	testevent delete one
+	vwait done
+	set delivered
+    } \
+    -result {}
+
+test notify-2.9 {remove and replace a marker event that's the sole event} \
+    -constraints {testevent} \
+    -body {
+	set delivered {}
+	after 10 set done 1
+	testevent queue one mark {lappend delivered one; expr 1}
+	testevent delete one
+	testevent queue two mark {lappend delivered two; expr 1}
+	vwait done
+	set delivered
+    } \
+    -result two
+
+test notify-2.10 {remove marker event from head} \
+    -constraints {testevent} \
+    -body {
+	set delivered {}
+	after 10 set done 1
+	testevent queue one mark {lappend delivered one; expr 1}
+	testevent queue two mark {lappend delivered two; expr 1}
+	testevent delete one
+	vwait done
+	set delivered
+    } \
+    -result two
+
+test notify-2.11 {remove and replace marker event at head} \
+    -constraints {testevent} \
+    -body {
+	set delivered {}
+	after 10 set done 1
+	testevent queue one mark {lappend delivered one; expr 1}
+	testevent queue two tail {lappend delivered two; expr 1}
+	testevent delete one
+	testevent queue three mark {lappend delivered three; expr 1}
+	vwait done
+	set delivered
+    } \
+    -result {three two}
+
+test notify-2.12 {remove marker event at tail} \
+    -constraints {testevent} \
+    -body {
+	set delivered {}
+	after 10 set done 1
+	testevent queue one mark {lappend delivered one; expr 1}
+	testevent queue two mark {lappend delivered two; expr 1}
+	testevent delete two
+	vwait done
+	set delivered
+    } \
+    -result {one}
+
+test notify-2.13 {remove and replace marker event at tail} \
+    -constraints {testevent} \
+    -body {
+	set delivered {}
+	after 10 set done 1
+	testevent queue one mark {lappend delivered one; expr 1}
+	testevent queue two mark {lappend delivered two; expr 1}
+	testevent delete two
+	testevent queue three mark {lappend delivered three; expr 1}
+	vwait done
+	set delivered
+    } \
+    -result {one three}
+
+test notify-2.14 {remove marker event from middle} \
+    -constraints {testevent} \
+    -body {
+	set delivered {}
+	after 10 set done 1
+	testevent queue one mark {lappend delivered one; expr 1}
+	testevent queue two mark {lappend delivered two; expr 1}
+	testevent queue three mark {lappend delivered three; expr 1}
+	testevent delete two
+	vwait done
+	set delivered
+    } \
+    -result {one three}
+
+test notify-2.15 {remove and replace marker event at middle} \
+    -constraints {testevent} \
+    -body {
+	set delivered {}
+	after 10 set done 1
+	testevent queue one mark {lappend delivered one; expr 1}
+	testevent queue two mark {lappend delivered two; expr 1}
+	testevent queue three tail {lappend delivered three; expr 1}
+	testevent delete two
+	testevent queue four mark {lappend delivered four; expr 1};
+	vwait done
+	set delivered
+    } \
+    -result {one four three}
+
+# cleanup
+::tcltest::cleanupTests
+return
diff --git a/tests/nre.test b/tests/nre.test
new file mode 100644
index 0000000..9df5eb1
--- /dev/null
+++ b/tests/nre.test
@@ -0,0 +1,451 @@
+# Commands covered:  proc, apply, [interp alias], [namespce import]
+#
+# This file contains a collection of tests for the non-recursive executor that
+# avoids recursive calls to TEBC. Only the NRE behaviour is tested here, the
+# actual command functionality is tested in the specific test file.
+#
+# Copyright (c) 2008 by Miguel Sofer.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+    package require tcltest
+    namespace import -force ::tcltest::*
+}
+
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
+
+testConstraint testnrelevels [llength [info commands testnrelevels]]
+
+#
+# The tests that risked blowing the C stack on failure have been removed: we
+# can now actually measure using testnrelevels.
+#
+
+if {[testConstraint testnrelevels]} {
+    namespace eval testnre {
+	namespace path ::tcl::mathop
+	#
+	# [testnrelevels] returns a 6-list with: C-stack depth, iPtr->numlevels,
+	# cmdFrame level, callFrame level, tosPtr and callback depth 
+	#
+	variable last [testnrelevels] 
+	proc depthDiff {} {
+	    variable last
+	    set depth [testnrelevels]
+	    set res {}
+	    foreach t $depth l $last {
+		lappend res [expr {$t-$l}]
+	    }
+	    set last $depth
+	    return $res
+	}
+	proc setabs {} {
+	    variable abs [- [lindex [testnrelevels] 0]]
+	}
+
+	variable body0 {
+	    set x [depthDiff]
+	    if {[incr i] > 10} {
+		namespace upvar [namespace qualifiers \
+			[namespace origin depthDiff]] abs abs
+		incr abs [lindex [testnrelevels] 0]
+		return [list [lrange $x 0 3] $abs]
+	    }
+	}
+	proc makebody txt {
+	    variable body0
+	    return "$body0; $txt"
+	}
+	namespace export *
+    }
+    namespace import testnre::*
+}
+
+test nre-0.1 {levels while unwinding} {
+    testnreunwind
+} {0 0 0}
+
+test nre-1.1 {self-recursive procs} -setup {
+    proc a i [makebody {a $i}]
+} -body {
+    setabs
+    a 0
+} -cleanup {
+    rename a {}
+} -constraints {
+    testnrelevels
+} -result {{0 1 1 1} 0}
+test nre-1.2 {self-recursive lambdas} -setup {
+    set a [list i [makebody {apply $::a $i}]]
+} -body {
+    setabs
+    apply $a 0
+} -cleanup {
+    unset a
+} -constraints {
+    testnrelevels
+} -result {{0 1 1 1} 0}
+test nre-1.3 {mutually recursive procs and lambdas} -setup {
+    proc a i {
+	apply $::b [incr i]
+    }
+    set b [list i [makebody {a $i}]]
+} -body {
+    setabs
+    a 0
+} -cleanup {
+    rename a {}
+    unset b
+} -constraints {
+    testnrelevels
+} -result {{0 2 2 2} 0}
+
+#
+# Test that aliases are non-recursive
+#
+
+test nre-2.1 {alias is not recursive} -setup {
+    proc a i [makebody {b $i}]
+    interp alias {} b {} a
+} -body {
+    setabs
+    a 0
+} -cleanup {
+    rename a {}
+    rename b {}
+} -constraints {
+    testnrelevels
+} -result {{0 2 1 1} 0}
+
+#
+# Test that imports are non-recursive
+#
+
+test nre-3.1 {imports are not recursive} -setup {
+    namespace eval foo {
+	setabs
+	namespace export a
+    }
+    proc foo::a i [makebody {::a $i}]
+    namespace import foo::a
+} -body {
+    a 0
+} -cleanup {
+    rename a {}
+    namespace delete ::foo
+} -constraints {
+    testnrelevels
+} -result {{0 2 1 1} 0}
+
+test nre-4.1 {ensembles are not recursive} -setup {
+    proc a i [makebody {b foo $i}]
+    namespace ensemble create \
+	-command b \
+	-map [list foo a]
+} -body {
+    setabs
+    a 0
+} -cleanup {
+    rename a {}
+    rename b {}
+} -constraints {
+    testnrelevels
+} -result {{0 2 1 1} 0}
+
+test nre-4.2 {(compiled) ensembles do not break tailcall} -setup {
+    # Fix Bug d87cb18205
+    proc b {} {
+	tailcall append result first
+    }
+    set map [namespace ensemble configure ::dict -map]
+    dict set map a b
+    namespace ensemble configure ::dict -map $map
+    proc demo {} {
+	dict a
+	append result second
+    }
+} -body {
+    demo
+} -cleanup {
+    rename demo {}
+    namespace ensemble configure ::dict -map [dict remove $map a]
+    unset map
+    rename b {}
+} -result firstsecond
+
+test nre-5.1 {[namespace eval] is not recursive} -setup {
+    namespace eval ::foo {
+	setabs
+    }
+    proc foo::a i [makebody {namespace eval ::foo [list a $i]}]
+} -body {
+    ::foo::a 0
+} -cleanup {
+    namespace delete ::foo
+} -constraints {
+    testnrelevels
+} -result {{0 2 2 2} 0}
+test nre-5.2 {[namespace eval] is not recursive} -setup {
+    namespace eval ::foo {
+	setabs
+    }
+    proc foo::a i [makebody {namespace eval ::foo "set x $i; a $i"}]
+} -body {
+    foo::a 0
+} -cleanup {
+    namespace delete ::foo
+} -constraints {
+    testnrelevels
+} -result {{0 2 2 2} 0}
+
+test nre-6.1 {[uplevel] is not recursive} -setup {
+    proc a i [makebody {uplevel 1 [list a $i]}]
+} -body {
+    setabs
+    a 0
+} -cleanup {
+    rename a {}
+} -constraints {
+    testnrelevels
+} -result {{0 2 2 0} 0}
+test nre-6.2 {[uplevel] is not recursive} -setup {
+    setabs
+    proc a i [makebody {uplevel 1 "set x $i; a $i"}]
+} -body {
+    a 0
+} -cleanup {
+    rename a {}
+} -constraints {
+    testnrelevels
+} -result {{0 2 2 0} 0}
+
+test nre-7.1 {[catch] is not recursive} -setup {
+    setabs
+    proc a i [makebody {uplevel 1 "catch {a $i} msg; set msg"}]
+} -body {
+    a 0
+} -cleanup {
+    rename a {}
+} -constraints {
+    testnrelevels
+} -result {{0 3 3 0} 0}
+test nre-7.2 {[if] is not recursive} -setup {
+    setabs
+    proc a i [makebody {uplevel 1 "if 1 {a $i}"}]
+} -body {
+    a 0
+} -cleanup {
+    rename a {}
+} -constraints {
+    testnrelevels
+} -result {{0 2 2 0} 0}
+test nre-7.3 {[while] is not recursive} -setup {
+    setabs
+    proc a i [makebody {uplevel 1 "while 1 {set res \[a $i\]; break}; set res"}]
+} -body {
+    a 0
+} -cleanup {
+    rename a {}
+} -constraints {
+    testnrelevels
+} -result {{0 2 2 0} 0}
+test nre-7.4 {[for] is not recursive} -setup {
+    setabs
+    proc a i [makebody {uplevel 1 "for {set j 0} {\$j < 10} {incr j} {set res \[a $i\]; break}; set res"}]
+} -body {
+    a 0
+} -cleanup {
+    rename a {}
+} -constraints {
+    testnrelevels
+} -result {{0 2 2 0} 0}
+test nre-7.5 {[foreach] is not recursive} -setup {
+    #
+    # Enable once [foreach] is NR-enabled
+    #
+    setabs
+    proc a i [makebody {uplevel 1 "foreach j {1 2 3 4 5 6} {set res \[a $i\]; break}; set res"}]
+} -body {
+    a 0
+} -cleanup {
+    rename a {}
+} -constraints {
+    testnrelevels
+} -result {{0 3 3 0} 0}
+test nre-7.6 {[eval] is not recursive} -setup {
+    proc a i [makebody {eval [list a $i]}]
+} -body {
+    setabs
+    a 0
+} -cleanup {
+    rename a {}
+} -constraints {
+    testnrelevels
+} -result {{0 2 2 1} 0}
+test nre-7.7 {[eval] is not recursive} -setup {
+    proc a i [makebody {eval "a $i"}]
+} -body {
+    setabs
+    a 0
+} -cleanup {
+    rename a {}
+} -constraints {
+    testnrelevels
+} -result {{0 2 2 1} 0}
+test nre-7.8 {bug #2910748: switch out of stale BC is not nre-aware} -setup {
+    proc foo args {}
+    foo
+    coroutine bar apply {{} {
+	yield
+	proc foo args {return ok}
+	while 1 {
+	    yield [incr i]
+	    foo
+	}
+    }}
+} -body {
+    # if switching to plain eval is not nre aware, this will cause a "cannot
+    # yield" error
+    list [bar] [bar] [bar]
+} -cleanup {
+    rename bar {}
+    rename foo {}
+} -result {1 2 3}
+
+test nre-8.1 {nre and {*}} -body {
+    # force an expansion that grows the evaluation stack, check that nre
+    # adapts the TEBCdataPtr. This crashes on failure.
+    proc inner {} {
+	set long [lrepeat 1000000 1]
+	list {*}$long
+    }
+    proc outer {} inner
+    lrange [outer] 0 2
+} -cleanup {
+    rename inner {}
+    rename outer {}
+} -result {1 1 1} 
+test nre-8.2 {nre and {*}, [Bug 2415422]} -body {
+    # force an expansion that grows the evaluation stack, check that nre
+    # adapts the bcFramePtr. This causes an NRE assertion to fail if it is not
+    # done properly.
+    proc nop {} {}
+    proc crash {} {
+	foreach val [list {*}[lrepeat 100000 x]] {
+	    nop
+	}
+    }
+    crash
+} -cleanup {
+    rename nop {}
+    rename crash {}
+}
+
+#
+#  Basic TclOO tests
+#
+
+test nre-oo.1 {really deep calls in oo - direct} -setup {
+    oo::object create foo
+    oo::objdefine foo method bar i [makebody {foo bar $i}]
+} -body {
+    setabs
+    foo bar 0
+} -cleanup {
+    foo destroy
+} -constraints {
+    testnrelevels
+} -result {{0 1 1 1} 0}
+test nre-oo.2 {really deep calls in oo - call via [self]} -setup {
+    oo::object create foo
+    oo::objdefine foo method bar i [makebody {[self] bar $i}]
+} -body {
+    setabs
+    foo bar 0
+} -cleanup {
+    foo destroy
+} -constraints {
+    testnrelevels
+} -result {{0 1 1 1} 0}
+test nre-oo.3 {really deep calls in oo - private calls} -setup {
+    oo::object create foo
+    oo::objdefine foo method bar i [makebody {my bar $i}]
+} -body {
+    setabs
+    foo bar 0
+} -cleanup {
+    foo destroy
+} -constraints {
+    testnrelevels
+} -result {{0 1 1 1} 0}
+test nre-oo.4 {really deep calls in oo - overriding} -setup {
+    oo::class create foo {
+	method bar i [makebody {my bar $i}]
+    }
+    oo::class create boo {
+	superclass foo
+	method bar i [makebody {next $i}]
+    }
+} -body {
+    setabs
+    [boo new] bar 0
+} -cleanup {
+    foo destroy
+} -constraints {
+    testnrelevels
+} -result {{0 1 1 1} 0}
+test nre-oo.5 {really deep calls in oo - forwards} -setup {
+    oo::object create foo
+    set body [makebody {my boo $i}]
+    oo::objdefine foo "
+	method bar i {$body}
+	forward boo ::foo bar
+    "
+} -body {
+    setabs
+    foo bar 0
+} -cleanup {
+    foo destroy
+} -constraints {
+    testnrelevels
+} -result {{0 2 1 1} 0}
+
+#
+# NASTY BUG found by tcllib's interp package
+#
+
+test nre-X.1 {eval in wrong interp} -setup {
+    set i [interp create]
+    $i eval {proc filter lst {lsearch -all -inline -not $lst "::tcl"}}
+} -body {
+    $i eval {
+	set x {namespace children ::}
+	set y [list namespace children ::]
+	namespace delete {*}[filter [{*}$y]]
+	set j [interp create]
+	$j alias filter filter
+	$j eval {namespace delete {*}[filter [namespace children ::]]}
+	namespace eval foo {}
+	list [filter [eval $x]] [filter [eval $y]] [filter [$j eval $x]] [filter [$j eval $y]]
+    }
+} -cleanup {
+    interp delete $i
+} -result {::foo ::foo {} {}}
+
+# cleanup
+::tcltest::cleanupTests
+
+if {[testConstraint testnrelevels]} {
+    namespace forget testnre::*
+    namespace delete testnre
+}
+
+return
+
+# Local Variables:
+# mode: tcl
+# fill-column: 78
+# End:
diff --git a/tests/obj.test b/tests/obj.test
new file mode 100644
index 0000000..151abfb
--- /dev/null
+++ b/tests/obj.test
@@ -0,0 +1,635 @@
+# Functionality covered: this file contains a collection of tests for the
+# procedures in tclObj.c that implement Tcl's basic type support and the
+# type managers for the types boolean, double, and integer.
+#
+# Sourcing this file into Tcl runs the tests and generates output for
+# errors. No output means no errors were found.
+#
+# Copyright (c) 1995-1996 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+    package require tcltest
+    namespace import -force ::tcltest::*
+}
+
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
+
+testConstraint testobj [llength [info commands testobj]]
+testConstraint longIs32bit	[expr {int(0x80000000) < 0}]
+testConstraint wideBiggerThanInt [expr {wide(0x80000000) != int(0x80000000)}]
+
+test obj-1.1 {Tcl_AppendAllObjTypes, and InitTypeTable, Tcl_RegisterObjType} testobj {
+    set r 1
+    foreach {t} {
+	{array search} 
+	bytearray
+	bytecode
+	cmdName
+	dict
+	end-offset
+	regexp
+	string
+    } {
+        set first [string first $t [testobj types]]
+        set r [expr {$r && ($first != -1)}]
+    }
+    set result $r
+} {1}
+
+test obj-2.1 {Tcl_GetObjType error} testobj {
+    list [testintobj set 1 0] [catch {testobj convert 1 foo} msg] $msg
+} {0 1 {no type foo found}}
+test obj-2.2 {Tcl_GetObjType and Tcl_ConvertToType} testobj {
+    set result ""
+    lappend result [testobj freeallvars]
+    lappend result [testintobj set 1 12]
+    lappend result [testobj convert 1 bytearray]
+    lappend result [testobj type 1]
+    lappend result [testobj refcount 1]
+} {{} 12 12 bytearray 3}
+
+test obj-3.1 {Tcl_ConvertToType error} testobj {
+    list [testdoubleobj set 1 12.34] \
+	[catch {testobj convert 1 end-offset} msg] \
+	 $msg
+} {12.34 1 {bad index "12.34": must be end?[+-]integer?}}
+test obj-3.2 {Tcl_ConvertToType error, "empty string" object} testobj {
+    list [testobj newobj 1] [catch {testobj convert 1 end-offset} msg] $msg
+} {{} 1 {bad index "": must be end?[+-]integer?}}
+
+test obj-4.1 {Tcl_NewObj and AllocateFreeObjects} testobj {
+    set result ""
+    lappend result [testobj freeallvars]
+    lappend result [testobj newobj 1]
+    lappend result [testobj type 1]
+    lappend result [testobj refcount 1]
+} {{} {} string 2}
+
+test obj-5.1 {Tcl_FreeObj} testobj {
+    set result ""
+    lappend result [testintobj set 1 12345]
+    lappend result [testobj freeallvars]
+    lappend result [catch {testintobj get 1} msg]
+    lappend result $msg
+} {12345 {} 1 {variable 1 is unset (NULL)}}
+
+test obj-6.1 {Tcl_DuplicateObj, object has internal rep} testobj {
+    set result ""
+    lappend result [testobj freeallvars]
+    lappend result [testintobj set 1 47]
+    lappend result [testobj duplicate 1 2]    
+    lappend result [testintobj get 2]
+    lappend result [testobj refcount 1]
+    lappend result [testobj refcount 2]
+} {{} 47 47 47 2 3}
+test obj-6.2 {Tcl_DuplicateObj, "empty string" object} testobj {
+    set result ""
+    lappend result [testobj freeallvars]
+    lappend result [testobj newobj 1]
+    lappend result [testobj duplicate 1 2]    
+    lappend result [testintobj get 2]
+    lappend result [testobj refcount 1]
+    lappend result [testobj refcount 2]
+} {{} {} {} {} 2 3}
+
+# We assume that testobj is an indicator for test*obj as well
+
+test obj-7.1 {Tcl_GetString, return existing string rep} testobj {
+    set result ""
+    lappend result [testintobj set 1 47]
+    lappend result [testintobj get2 1]
+} {47 47}
+test obj-7.2 {Tcl_GetString, "empty string" object} testobj {
+    set result ""
+    lappend result [testobj newobj 1]
+    lappend result [teststringobj append 1 abc -1]
+    lappend result [teststringobj get2 1]
+} {{} abc abc}
+test obj-7.3 {Tcl_GetString, returns string internal rep (DString)} testobj {
+    set result ""
+    lappend result [teststringobj set 1 xyz]
+    lappend result [teststringobj append 1 abc -1]
+    lappend result [teststringobj get2 1]
+} {xyz xyzabc xyzabc}
+test obj-7.4 {Tcl_GetString, recompute string rep from internal rep} testobj {
+    set result ""
+    lappend result [testintobj set 1 77]
+    lappend result [testintobj mult10 1]
+    lappend result [teststringobj get2 1]
+} {77 770 770}
+
+test obj-8.1 {Tcl_GetStringFromObj, return existing string rep} testobj {
+    set result ""
+    lappend result [testintobj set 1 47]
+    lappend result [testintobj get 1]
+} {47 47}
+test obj-8.2 {Tcl_GetStringFromObj, "empty string" object} testobj {
+    set result ""
+    lappend result [testobj newobj 1]
+    lappend result [teststringobj append 1 abc -1]
+    lappend result [teststringobj get 1]
+} {{} abc abc}
+test obj-8.3 {Tcl_GetStringFromObj, returns string internal rep (DString)} testobj {
+    set result ""
+    lappend result [teststringobj set 1 xyz]
+    lappend result [teststringobj append 1 abc -1]
+    lappend result [teststringobj get 1]
+} {xyz xyzabc xyzabc}
+test obj-8.4 {Tcl_GetStringFromObj, recompute string rep from internal rep} testobj {
+    set result ""
+    lappend result [testintobj set 1 77]
+    lappend result [testintobj mult10 1]
+    lappend result [teststringobj get 1]
+} {77 770 770}
+
+test obj-9.1 {Tcl_NewBooleanObj} testobj {
+    set result ""
+    lappend result [testobj freeallvars]
+    lappend result [testbooleanobj set 1 0]
+    lappend result [testobj type 1]
+    lappend result [testobj refcount 1]
+} {{} 0 int 2}
+
+test obj-10.1 {Tcl_SetBooleanObj, existing "empty string" object} testobj {
+    set result ""
+    lappend result [testobj freeallvars]
+    lappend result [testobj newobj 1]
+    lappend result [testbooleanobj set 1 0]  ;# makes existing obj boolean
+    lappend result [testobj type 1]
+    lappend result [testobj refcount 1]
+} {{} {} 0 int 2}
+test obj-10.2 {Tcl_SetBooleanObj, existing non-"empty string" object} testobj {
+    set result ""
+    lappend result [testobj freeallvars]
+    lappend result [testintobj set 1 98765]
+    lappend result [testbooleanobj set 1 1]  ;# makes existing obj boolean
+    lappend result [testobj type 1]
+    lappend result [testobj refcount 1]
+} {{} 98765 1 int 2}
+
+test obj-11.1 {Tcl_GetBooleanFromObj, existing boolean object} testobj {
+    set result ""
+    lappend result [testbooleanobj set 1 1]
+    lappend result [testbooleanobj not 1]    ;# gets existing boolean rep
+} {1 0}
+test obj-11.2 {Tcl_GetBooleanFromObj, convert to boolean} testobj {
+    set result ""
+    lappend result [testintobj set 1 47]
+    lappend result [testbooleanobj not 1]    ;# must convert to bool
+    lappend result [testobj type 1]
+} {47 0 int}
+test obj-11.3 {Tcl_GetBooleanFromObj, error converting to boolean} testobj {
+    set result ""
+    lappend result [teststringobj set 1 abc]
+    lappend result [catch {testbooleanobj not 1} msg]
+    lappend result $msg
+} {abc 1 {expected boolean value but got "abc"}}
+test obj-11.4 {Tcl_GetBooleanFromObj, error converting from "empty string"} testobj {
+    set result ""
+    lappend result [testobj newobj 1]
+    lappend result [catch {testbooleanobj not 1} msg]
+    lappend result $msg
+} {{} 1 {expected boolean value but got ""}}
+test obj-11.5 {Tcl_GetBooleanFromObj, convert hex to boolean} testobj {
+    set result ""
+    lappend result [teststringobj set 1 0xac]
+    lappend result [testbooleanobj not 1]
+    lappend result [testobj type 1]
+} {0xac 0 int}
+test obj-11.6 {Tcl_GetBooleanFromObj, convert float to boolean} testobj {
+    set result ""
+    lappend result [teststringobj set 1 5.42]
+    lappend result [testbooleanobj not 1]
+    lappend result [testobj type 1]
+} {5.42 0 int}
+
+test obj-12.1 {DupBooleanInternalRep} testobj {
+    set result ""
+    lappend result [testbooleanobj set 1 1]
+    lappend result [testobj duplicate 1 2]   ;# uses DupBooleanInternalRep
+    lappend result [testbooleanobj get 2]
+} {1 1 1}
+
+test obj-13.1 {SetBooleanFromAny, int to boolean special case} testobj {
+    set result ""
+    lappend result [testintobj set 1 1234]
+    lappend result [testbooleanobj not 1]    ;# converts with SetBooleanFromAny
+    lappend result [testobj type 1]
+} {1234 0 int}
+test obj-13.2 {SetBooleanFromAny, double to boolean special case} testobj {
+    set result ""
+    lappend result [testdoubleobj set 1 3.14159]
+    lappend result [testbooleanobj not 1]    ;# converts with SetBooleanFromAny
+    lappend result [testobj type 1]
+} {3.14159 0 int}
+test obj-13.3 {SetBooleanFromAny, special case strings representing booleans} testobj {
+    set result ""
+    foreach s {yes no true false on off} {
+        teststringobj set 1 $s
+        lappend result [testbooleanobj not 1]
+    }
+    lappend result [testobj type 1]
+} {0 1 0 1 0 1 int}
+test obj-13.4 {SetBooleanFromAny, recompute string rep then parse it} testobj {
+    set result ""
+    lappend result [testintobj set 1 456]
+    lappend result [testintobj div10 1]
+    lappend result [testbooleanobj not 1]    ;# converts with SetBooleanFromAny
+    lappend result [testobj type 1]
+} {456 45 0 int}
+test obj-13.5 {SetBooleanFromAny, error parsing string} testobj {
+    set result ""
+    lappend result [teststringobj set 1 abc]
+    lappend result [catch {testbooleanobj not 1} msg]
+    lappend result $msg
+} {abc 1 {expected boolean value but got "abc"}}
+test obj-13.6 {SetBooleanFromAny, error parsing string} testobj {
+    set result ""
+    lappend result [teststringobj set 1 x1.0]
+    lappend result [catch {testbooleanobj not 1} msg]
+    lappend result $msg
+} {x1.0 1 {expected boolean value but got "x1.0"}}
+test obj-13.7 {SetBooleanFromAny, error converting from "empty string"} testobj {
+    set result ""
+    lappend result [testobj newobj 1]
+    lappend result [catch {testbooleanobj not 1} msg]
+    lappend result $msg
+} {{} 1 {expected boolean value but got ""}}
+test obj-13.8 {SetBooleanFromAny, unicode strings} testobj {
+    set result ""
+    lappend result [teststringobj set 1 1\u7777]
+    lappend result [catch {testbooleanobj not 1} msg]
+    lappend result $msg
+} "1\u7777 1 {expected boolean value but got \"1\u7777\"}"
+
+test obj-14.1 {UpdateStringOfBoolean} testobj {
+    set result ""
+    lappend result [testbooleanobj set 1 0]
+    lappend result [testbooleanobj not 1]
+    lappend result [testbooleanobj get 1]    ;# must update string rep
+} {0 1 1}
+
+test obj-15.1 {Tcl_NewDoubleObj} testobj {
+    set result ""
+    lappend result [testobj freeallvars]
+    lappend result [testdoubleobj set 1 3.1459]
+    lappend result [testobj type 1]
+    lappend result [testobj refcount 1]
+} {{} 3.1459 double 2}
+
+test obj-16.1 {Tcl_SetDoubleObj, existing "empty string" object} testobj {
+    set result ""
+    lappend result [testobj freeallvars]
+    lappend result [testobj newobj 1]
+    lappend result [testdoubleobj set 1 0.123]  ;# makes existing obj boolean
+    lappend result [testobj type 1]
+    lappend result [testobj refcount 1]
+} {{} {} 0.123 double 2}
+test obj-16.2 {Tcl_SetDoubleObj, existing non-"empty string" object} testobj {
+    set result ""
+    lappend result [testobj freeallvars]
+    lappend result [testintobj set 1 98765]
+    lappend result [testdoubleobj set 1 27.56]  ;# makes existing obj double
+    lappend result [testobj type 1]
+    lappend result [testobj refcount 1]
+} {{} 98765 27.56 double 2}
+
+test obj-17.1 {Tcl_GetDoubleFromObj, existing double object} testobj {
+    set result ""
+    lappend result [testdoubleobj set 1 16.1]
+    lappend result [testdoubleobj mult10 1]   ;# gets existing double rep
+} {16.1 161.0}
+test obj-17.2 {Tcl_GetDoubleFromObj, convert to double} testobj {
+    set result ""
+    lappend result [testintobj set 1 477]
+    lappend result [testdoubleobj div10 1]    ;# must convert to bool
+    lappend result [testobj type 1]
+} {477 47.7 double}
+test obj-17.3 {Tcl_GetDoubleFromObj, error converting to double} testobj {
+    set result ""
+    lappend result [teststringobj set 1 abc]
+    lappend result [catch {testdoubleobj mult10 1} msg]
+    lappend result $msg
+} {abc 1 {expected floating-point number but got "abc"}}
+test obj-17.4 {Tcl_GetDoubleFromObj, error converting from "empty string"} testobj {
+    set result ""
+    lappend result [testobj newobj 1]
+    lappend result [catch {testdoubleobj div10 1} msg]
+    lappend result $msg
+} {{} 1 {expected floating-point number but got ""}}
+
+test obj-18.1 {DupDoubleInternalRep} testobj {
+    set result ""
+    lappend result [testdoubleobj set 1 17.1]
+    lappend result [testobj duplicate 1 2]      ;# uses DupDoubleInternalRep
+    lappend result [testdoubleobj get 2]
+} {17.1 17.1 17.1}
+
+test obj-19.1 {SetDoubleFromAny, int to double special case} testobj {
+    set result ""
+    lappend result [testintobj set 1 1234]
+    lappend result [testdoubleobj mult10 1] ;# converts with SetDoubleFromAny
+    lappend result [testobj type 1]
+} {1234 12340.0 double}
+test obj-19.2 {SetDoubleFromAny, boolean to double special case} testobj {
+    set result ""
+    lappend result [testbooleanobj set 1 1]
+    lappend result [testdoubleobj mult10 1] ;# converts with SetDoubleFromAny
+    lappend result [testobj type 1]
+} {1 10.0 double}
+test obj-19.3 {SetDoubleFromAny, recompute string rep then parse it} testobj {
+    set result ""
+    lappend result [testintobj set 1 456]
+    lappend result [testintobj div10 1]
+    lappend result [testdoubleobj mult10 1] ;# converts with SetDoubleFromAny
+    lappend result [testobj type 1]
+} {456 45 450.0 double}
+test obj-19.4 {SetDoubleFromAny, error parsing string} testobj {
+    set result ""
+    lappend result [teststringobj set 1 abc]
+    lappend result [catch {testdoubleobj mult10 1} msg]
+    lappend result $msg
+} {abc 1 {expected floating-point number but got "abc"}}
+test obj-19.5 {SetDoubleFromAny, error parsing string} testobj {
+    set result ""
+    lappend result [teststringobj set 1 x1.0]
+    lappend result [catch {testdoubleobj mult10 1} msg]
+    lappend result $msg
+} {x1.0 1 {expected floating-point number but got "x1.0"}}
+test obj-19.6 {SetDoubleFromAny, error converting from "empty string"} testobj {
+    set result ""
+    lappend result [testobj newobj 1]
+    lappend result [catch {testdoubleobj div10 1} msg]
+    lappend result $msg
+} {{} 1 {expected floating-point number but got ""}}
+
+test obj-20.1 {UpdateStringOfDouble} testobj {
+    set result ""
+    lappend result [testdoubleobj set 1 3.14159]
+    lappend result [testdoubleobj mult10 1]
+    lappend result [testdoubleobj get 1]   ;# must update string rep
+} {3.14159 31.4159 31.4159}
+
+test obj-21.1 {Tcl_NewIntObj} testobj {
+    set result ""
+    lappend result [testobj freeallvars]
+    lappend result [testintobj set 1 55]
+    lappend result [testobj type 1]
+    lappend result [testobj refcount 1]
+} {{} 55 int 2}
+
+test obj-22.1 {Tcl_SetIntObj, existing "empty string" object} testobj {
+    set result ""
+    lappend result [testobj freeallvars]
+    lappend result [testobj newobj 1]
+    lappend result [testintobj set 1 77]  ;# makes existing obj int
+    lappend result [testobj type 1]
+    lappend result [testobj refcount 1]
+} {{} {} 77 int 2}
+test obj-22.2 {Tcl_SetIntObj, existing non-"empty string" object} testobj {
+    set result ""
+    lappend result [testobj freeallvars]
+    lappend result [testdoubleobj set 1 12.34]
+    lappend result [testintobj set 1 77]  ;# makes existing obj int
+    lappend result [testobj type 1]
+    lappend result [testobj refcount 1]
+} {{} 12.34 77 int 2}
+
+test obj-23.1 {Tcl_GetIntFromObj, existing int object} testobj {
+    set result ""
+    lappend result [testintobj set 1 22]
+    lappend result [testintobj mult10 1]   ;# gets existing int rep
+} {22 220}
+test obj-23.2 {Tcl_GetIntFromObj, convert to int} testobj {
+    set result ""
+    lappend result [testintobj set 1 477]
+    lappend result [testintobj div10 1]    ;# must convert to bool
+    lappend result [testobj type 1]
+} {477 47 int}
+test obj-23.3 {Tcl_GetIntFromObj, error converting to int} testobj {
+    set result ""
+    lappend result [teststringobj set 1 abc]
+    lappend result [catch {testintobj mult10 1} msg]
+    lappend result $msg
+} {abc 1 {expected integer but got "abc"}}
+test obj-23.4 {Tcl_GetIntFromObj, error converting from "empty string"} testobj {
+    set result ""
+    lappend result [testobj newobj 1]
+    lappend result [catch {testintobj div10 1} msg]
+    lappend result $msg
+} {{} 1 {expected integer but got ""}}
+test obj-23.5 {Tcl_GetIntFromObj, integer too large to represent as non-long error} {testobj} {
+    set result ""
+    lappend result [testobj newobj 1]
+    lappend result [testintobj inttoobigtest 1]
+} {{} 1}
+
+test obj-24.1 {DupIntInternalRep} testobj {
+    set result ""
+    lappend result [testintobj set 1 23]
+    lappend result [testobj duplicate 1 2]    ;# uses DupIntInternalRep
+    lappend result [testintobj get 2]
+} {23 23 23}
+
+test obj-25.1 {SetIntFromAny, int to int special case} testobj {
+    set result ""
+    lappend result [testintobj set 1 1234]
+    lappend result [testintobj mult10 1]  ;# converts with SetIntFromAny
+    lappend result [testobj type 1]
+} {1234 12340 int}
+test obj-25.2 {SetIntFromAny, boolean to int special case} testobj {
+    set result ""
+    lappend result [testbooleanobj set 1 1]
+    lappend result [testintobj mult10 1]  ;# converts with SetIntFromAny
+    lappend result [testobj type 1]
+} {1 10 int}
+test obj-25.3 {SetIntFromAny, recompute string rep then parse it} testobj {
+    set result ""
+    lappend result [testintobj set 1 456]
+    lappend result [testintobj div10 1]
+    lappend result [testintobj mult10 1]  ;# converts with SetIntFromAny
+    lappend result [testobj type 1]
+} {456 45 450 int}
+test obj-25.4 {SetIntFromAny, error parsing string} testobj {
+    set result ""
+    lappend result [teststringobj set 1 abc]
+    lappend result [catch {testintobj mult10 1} msg]
+    lappend result $msg
+} {abc 1 {expected integer but got "abc"}}
+test obj-25.5 {SetIntFromAny, error parsing string} testobj {
+    set result ""
+    lappend result [teststringobj set 1 x17]
+    lappend result [catch {testintobj mult10 1} msg]
+    lappend result $msg
+} {x17 1 {expected integer but got "x17"}}
+test obj-25.6 {SetIntFromAny, integer too large} {testobj} {
+    set result ""
+    lappend result [teststringobj set 1 123456789012345678901]
+    lappend result [catch {testintobj mult10 1} msg]
+    lappend result $msg
+} {123456789012345678901 1 {integer value too large to represent}}
+test obj-25.7 {SetIntFromAny, error converting from "empty string"} testobj {
+    set result ""
+    lappend result [testobj newobj 1]
+    lappend result [catch {testintobj div10 1} msg]
+    lappend result $msg
+} {{} 1 {expected integer but got ""}}
+
+test obj-26.1 {UpdateStringOfInt} testobj {
+    set result ""
+    lappend result [testintobj set 1 512]
+    lappend result [testintobj mult10 1]
+    lappend result [testintobj get 1]       ;# must update string rep
+} {512 5120 5120}
+
+test obj-27.1 {Tcl_NewLongObj} testobj {
+    set result ""
+    lappend result [testobj freeallvars]
+    testintobj setmaxlong 1
+    lappend result [testintobj ismaxlong 1]
+    lappend result [testobj type 1]
+    lappend result [testobj refcount 1]
+} {{} 1 int 1}
+
+test obj-28.1 {Tcl_SetLongObj, existing "empty string" object} testobj {
+    set result ""
+    lappend result [testobj freeallvars]
+    lappend result [testobj newobj 1]
+    lappend result [testintobj setlong 1 77]  ;# makes existing obj long int
+    lappend result [testobj type 1]
+    lappend result [testobj refcount 1]
+} {{} {} 77 int 2}
+test obj-28.2 {Tcl_SetLongObj, existing non-"empty string" object} testobj {
+    set result ""
+    lappend result [testobj freeallvars]
+    lappend result [testdoubleobj set 1 12.34]
+    lappend result [testintobj setlong 1 77]  ;# makes existing obj long int
+    lappend result [testobj type 1]
+    lappend result [testobj refcount 1]
+} {{} 12.34 77 int 2}
+
+test obj-29.1 {Tcl_GetLongFromObj, existing long integer object} testobj {
+    set result ""
+    lappend result [testintobj setlong 1 22]
+    lappend result [testintobj mult10 1]   ;# gets existing long int rep
+} {22 220}
+test obj-29.2 {Tcl_GetLongFromObj, convert to long} testobj {
+    set result ""
+    lappend result [testintobj setlong 1 477]
+    lappend result [testintobj div10 1]    ;# must convert to bool
+    lappend result [testobj type 1]
+} {477 47 int}
+test obj-29.3 {Tcl_GetLongFromObj, error converting to long integer} testobj {
+    set result ""
+    lappend result [teststringobj set 1 abc]
+    lappend result [catch {testintobj ismaxlong 1} msg] ;# cvts to long int
+    lappend result $msg
+} {abc 1 {expected integer but got "abc"}}
+test obj-29.4 {Tcl_GetLongFromObj, error converting from "empty string"} testobj {
+    set result ""
+    lappend result [testobj newobj 1]
+    lappend result [catch {testintobj ismaxlong 1} msg] ;# cvts to long int
+    lappend result $msg
+} {{} 1 {expected integer but got ""}}
+
+test obj-30.1 {Ref counting and object deletion, simple types} testobj {
+    set result ""
+    lappend result [testobj freeallvars]
+    lappend result [testintobj set 1 1024]
+    lappend result [testobj assign 1 2]     ;# vars 1 and 2 share the int obj
+    lappend result [testobj type 2]
+    lappend result [testobj refcount 1]
+    lappend result [testobj refcount 2]
+    lappend result [testbooleanobj set 2 0] ;# must copy on write, now 2 objs
+    lappend result [testobj type 2]
+    lappend result [testobj refcount 1]
+    lappend result [testobj refcount 2]
+} {{} 1024 1024 int 4 4 0 int 3 2}
+
+
+test obj-31.1 {regenerate string rep of "end"} testobj {
+    testobj freeallvars
+    teststringobj set 1 end
+    testobj convert 1 end-offset
+    testobj invalidateStringRep 1
+} end
+test obj-31.2 {regenerate string rep of "end-1"} testobj {
+    testobj freeallvars
+    teststringobj set 1 end-0x1
+    testobj convert 1 end-offset
+    testobj invalidateStringRep 1
+} end-1
+test obj-31.3 {regenerate string rep of "end--1"} testobj {
+    testobj freeallvars
+    teststringobj set 1 end--0x1
+    testobj convert 1 end-offset
+    testobj invalidateStringRep 1
+} end--1
+test obj-31.4 {regenerate string rep of "end-bigInteger"} testobj {
+    testobj freeallvars
+    teststringobj set 1 end-0x7fffffff
+    testobj convert 1 end-offset
+    testobj invalidateStringRep 1
+} end-2147483647
+test obj-31.5 {regenerate string rep of "end--bigInteger"} testobj {
+    testobj freeallvars
+    teststringobj set 1 end--0x7fffffff
+    testobj convert 1 end-offset
+    testobj invalidateStringRep 1
+} end--2147483647
+test obj-31.6 {regenerate string rep of "end--bigInteger"} {testobj longIs32bit} {
+    testobj freeallvars
+    teststringobj set 1 end--0x80000000
+    testobj convert 1 end-offset
+    testobj invalidateStringRep 1
+} end--2147483648
+
+test obj-32.1 {freeing very large object trees} {
+    set x {}
+    for {set i 0} {$i<100000} {incr i} {
+	set x [list $x {}]
+    }
+    unset x
+} {}
+
+test obj-33.1 {integer overflow on input} {longIs32bit wideBiggerThanInt} {
+    set x 0x8000; append x 0000
+    list [string is integer $x] [expr { wide($x) }]
+} {1 2147483648}
+test obj-33.2 {integer overflow on input} {longIs32bit wideBiggerThanInt} {
+    set x 0xffff; append x ffff
+    list [string is integer $x] [expr { wide($x) }]
+} {1 4294967295}
+test obj-33.3 {integer overflow on input} {
+    set x 0x10000; append x 0000
+    list [string is integer $x] [expr { wide($x) }]
+} {0 4294967296}
+test obj-33.4 {integer overflow on input} {longIs32bit wideBiggerThanInt} {
+    set x -0x8000; append x 0000
+    list [string is integer $x] [expr { wide($x) }]
+} {1 -2147483648}
+test obj-33.5 {integer overflow on input} {longIs32bit wideBiggerThanInt} {
+    set x -0x8000; append x 0001
+    list [string is integer $x] [expr { wide($x) }]
+} {1 -2147483649}
+test obj-33.6 {integer overflow on input} {longIs32bit wideBiggerThanInt} {
+    set x -0xffff; append x ffff
+    list [string is integer $x] [expr { wide($x) }]
+} {1 -4294967295}
+test obj-33.7 {integer overflow on input} {
+    set x -0x10000; append x 0000
+    list [string is integer $x] [expr { wide($x) }]
+} {0 -4294967296}
+
+if {[testConstraint testobj]} {
+    testobj freeallvars
+}
+
+# cleanup
+::tcltest::cleanupTests
+return
diff --git a/tests/oo.test b/tests/oo.test
new file mode 100644
index 0000000..2601c37
--- /dev/null
+++ b/tests/oo.test
@@ -0,0 +1,3737 @@
+# This file contains a collection of tests for Tcl's built-in object system.
+# Sourcing this file into Tcl runs the tests and generates output for errors.
+# No output means no errors were found.
+#
+# Copyright (c) 2006-2013 Donal K. Fellows
+#
+# See the file "license.terms" for information on usage and redistribution of
+# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+package require TclOO 1.0.3
+package require tcltest 2
+if {"::tcltest" in [namespace children]} {
+    namespace import -force ::tcltest::*
+}
+
+testConstraint memory [llength [info commands memory]]
+if {[testConstraint memory]} {
+    proc getbytes {} {
+	set lines [split [memory info] \n]
+	return [lindex $lines 3 3]
+    }
+    proc leaktest {script {iterations 3}} {
+	set end [getbytes]
+	for {set i 0} {$i < $iterations} {incr i} {
+	    uplevel 1 $script
+	    set tmp $end
+	    set end [getbytes]
+	}
+	return [expr {$end - $tmp}]
+    }
+}
+
+test oo-0.1 {basic test of OO's ability to clean up its initial state} {
+    interp create t
+    t eval {
+	package require TclOO
+    }
+    interp delete t
+} {}
+test oo-0.2 {basic test of OO's ability to clean up its initial state} {
+    set i [interp create]
+    interp eval $i {
+	package require TclOO
+	namespace delete ::
+    }
+    interp delete $i
+} {}
+test oo-0.3 {basic test of OO's ability to clean up its initial state} -body {
+    leaktest {
+	[oo::object new] destroy
+    }
+} -constraints memory -result 0
+test oo-0.4 {basic test of OO's ability to clean up its initial state} -body {
+    leaktest {
+	oo::class create foo
+	foo new
+	foo destroy
+    }
+} -constraints memory -result 0
+test oo-0.5 {testing literal leak on interp delete} memory {
+    leaktest {
+	interp create foo
+	foo eval {oo::object new}
+	interp delete foo
+    }
+} 0
+test oo-0.6 {cleaning the core class pair; way #1} -setup {
+    interp create t
+} -body {
+    t eval {
+	package require TclOO
+	namespace path oo
+	list [catch {class destroy} m] $m [catch {object destroy} m] $m
+    }
+} -cleanup {
+    interp delete t
+} -result {0 {} 1 {invalid command name "object"}}
+test oo-0.7 {cleaning the core class pair; way #2} -setup {
+    interp create t
+} -body {
+    t eval {
+	package require TclOO
+	namespace path oo
+	list [catch {object destroy} m] $m [catch {class destroy} m] $m
+    }
+} -cleanup {
+    interp delete t
+} -result {0 {} 1 {invalid command name "class"}}
+test oo-0.8 {leak in variable management} -setup {
+    oo::class create foo
+} -constraints memory -body {
+    oo::define foo {
+	constructor {} {
+	    variable v 0
+	}
+    }
+    leaktest {[foo new] destroy}
+} -cleanup {
+    foo destroy
+} -result 0
+test oo-0.9 {various types of presence of the TclOO package} {
+    list [lsearch -nocase -all -inline [package names] tcloo] \
+	[package present TclOO] [package versions TclOO]
+} [list TclOO $::oo::patchlevel $::oo::patchlevel]
+
+test oo-1.1 {basic test of OO functionality: no classes} {
+    set result {}
+    lappend result [oo::object create foo]
+    lappend result [oo::objdefine foo {
+	method bar args {
+	    global result
+	    lappend result {*}$args
+	    return [llength $args]
+	}
+    }]
+    lappend result [foo bar a b c]
+    lappend result [foo destroy] [info commands foo]
+} {::foo {} a b c 3 {} {}}
+test oo-1.2 {basic test of OO functionality: no classes} -body {
+    oo::define oo::object method missingArgs
+} -returnCodes 1 -result "wrong # args: should be \"oo::define oo::object method name args body\""
+test oo-1.3 {basic test of OO functionality: no classes} {
+    catch {oo::define oo::object method missingArgs}
+    set errorInfo
+} "wrong # args: should be \"oo::define oo::object method name args body\"
+    while executing
+\"oo::define oo::object method missingArgs\""
+test oo-1.4 {basic test of OO functionality} -body {
+    oo::object create {}
+} -returnCodes 1 -result {object name must not be empty}
+test oo-1.5 {basic test of OO functionality} -body {
+    oo::object doesnotexist
+} -returnCodes 1 -result {unknown method "doesnotexist": must be create, destroy or new}
+test oo-1.5.1 {basic test of OO functionality} -setup {
+    oo::object create aninstance
+} -returnCodes error -body {
+    aninstance
+} -cleanup {
+    rename aninstance {}
+} -result {wrong # args: should be "aninstance method ?arg ...?"}
+test oo-1.6 {basic test of OO functionality} -setup {
+    oo::object create aninstance
+} -body {
+    oo::objdefine aninstance unexport destroy
+    aninstance doesnotexist
+} -cleanup {
+    rename aninstance {}
+} -returnCodes 1 -result {object "::aninstance" has no visible methods}
+test oo-1.7 {basic test of OO functionality} -setup {
+    oo::object create aninstance
+} -body {
+    oo::objdefine aninstance {
+	# Do not do this in real code! Ever! This is *not* supported!
+	::oo::define::method ha ha ha
+    }
+} -returnCodes error -cleanup {
+    aninstance destroy
+} -result {attempt to misuse API}
+test oo-1.8 {basic test of OO functionality} -setup {
+    oo::object create obj
+    set result {}
+} -cleanup {
+    obj destroy
+} -body {
+    oo::objdefine obj method foo {} {return bar}
+    lappend result [obj foo]
+    oo::objdefine obj method foo {} {}
+    lappend result [obj foo]
+} -result {bar {}}
+test oo-1.9 {basic test of OO functionality} -setup {
+    oo::object create a
+    oo::object create b
+} -cleanup {
+    catch {a destroy}
+    b destroy
+} -body {
+    oo::objdefine a method foo {} { return A }
+    oo::objdefine b method foo {} { return B }
+    apply {{} {
+	set m foo
+	return [a $m],[a destroy],[b $m]
+    }}
+} -result A,,B
+test oo-1.10 {basic test of OO functionality} -body {
+    namespace eval foo {
+	namespace eval bar {
+	    oo::object create o
+	    namespace export o
+	}
+	namespace import bar::o
+    }
+    list [info object isa object foo::bar::o] [info object isa object foo::o]
+} -cleanup {
+    namespace delete foo
+} -result {1 1}
+test oo-1.11 {basic test of OO functionality: abbreviating} -setup {
+    oo::class create c
+} -cleanup {
+    c destroy
+} -body {
+    oo::define c super oo::class
+    info class super c
+} -result ::oo::class
+test oo-1.12 {basic test of OO functionality: abbreviating} -setup {
+    oo::class create c
+} -cleanup {
+    c destroy
+} -body {
+    oo::define c {super oo::class}
+    info class super c
+} -result ::oo::class
+test oo-1.13 {basic test of OO functionality: abbreviating} -setup {
+    oo::class create c
+} -cleanup {
+    c destroy
+} -body {
+    oo::define c self {forw a b}
+    info object forw c a
+} -result b
+test oo-1.14 {basic test of OO functionality: abbreviating} -setup {
+    oo::class create c
+} -cleanup {
+    c destroy
+} -body {
+    oo::define c self forw a b
+    info object forw c a
+} -result b
+test oo-1.15 {basic test of OO functionality: abbreviating} -setup {
+    oo::object create o
+} -cleanup {
+    o destroy
+} -body {
+    oo::objdefine o {forw a b}
+    info object forw o a
+} -result b
+test oo-1.16 {basic test of OO functionality: abbreviating} -setup {
+    oo::object create o
+} -cleanup {
+    o destroy
+} -body {
+    oo::objdefine o forw a b
+    info object forw o a
+} -result b
+test oo-1.17 {basic test of OO functionality: Bug 2481109} -body {
+    namespace eval ::foo {oo::object create lreplace}
+} -cleanup {
+    namespace delete ::foo
+} -result ::foo::lreplace
+# Check for Bug 2519474; problem in tclNamesp.c, but tested here...
+test oo-1.18 {OO: create object in NS with same name as global cmd} -setup {
+    proc test-oo-1.18 {} return
+    oo::class create A
+    oo::class create B {superclass A}
+} -body {
+    oo::define B constructor {} {A create test-oo-1.18}
+    B create C
+} -cleanup {
+    rename test-oo-1.18 {}
+    A destroy
+} -result ::C
+test oo-1.18.1 {Bug 75b8433707: memory leak in oo-1.18} -setup {
+    proc test-oo-1.18 {} return
+} -constraints memory -body {
+    leaktest {
+	oo::class create A
+	oo::class create B {superclass A}
+	oo::define B constructor {} {A create test-oo-1.18}
+	B create C
+	A destroy
+    }
+} -cleanup {
+    rename test-oo-1.18 {}
+} -result 0
+test oo-1.18.2 {Bug 21c144f0f5} -setup {
+    interp create slave
+} -body {
+    slave eval {
+	oo::define [oo::class create foo] superclass oo::class
+	oo::class destroy
+    }
+} -cleanup {
+    interp delete slave
+} 
+test oo-1.19 {basic test of OO functionality: teardown order} -body {
+    oo::object create o
+    namespace delete [info object namespace o]
+    o destroy
+    # Crashes on error
+} -returnCodes error -result {invalid command name "o"}
+test oo-1.20 {basic test of OO functionality: my teardown post rename} -body {
+    oo::object create obj
+    rename [info object namespace obj]::my ::AGlobalName
+    obj destroy
+    info commands ::AGlobalName
+} -result {}
+test oo-1.21 {basic test of OO functionality: default relations} -setup {
+    set fresh [interp create]
+} -body {
+    lmap x [$fresh eval {
+	foreach cmd {instances subclasses mixins superclass} {
+	    foreach initial {object class Slot} {
+		lappend x [info class $cmd ::oo::$initial]
+	    }
+	}
+	foreach initial {object class Slot} {
+	    lappend x [info object class ::oo::$initial]
+	}
+	return $x
+    }] {lsort $x}
+} -cleanup {
+    interp delete $fresh
+} -result {{} {::oo::Slot ::oo::class ::oo::object} {::oo::define::filter ::oo::define::mixin ::oo::define::superclass ::oo::define::variable ::oo::objdefine::filter ::oo::objdefine::mixin ::oo::objdefine::variable} {::oo::Slot ::oo::class} {} {} {} {} {} {} ::oo::object ::oo::object ::oo::class ::oo::class ::oo::class}
+
+test oo-2.1 {basic test of OO functionality: constructor} -setup {
+    # This is a bit complex because it needs to run in a sub-interp as
+    # we're modifying the root object class's constructor
+    interp create subinterp
+    subinterp eval {
+	package require TclOO
+    }
+} -body {
+    subinterp eval {
+	oo::define oo::object constructor {} {
+	    lappend ::result [info level 0]
+	}
+	lappend result 1
+	lappend result 2 [oo::object create foo]
+    }
+} -cleanup {
+    interp delete subinterp
+} -result {1 {oo::object create foo} 2 ::foo}
+test oo-2.2 {basic test of OO functionality: constructor} {
+    oo::class create testClass {
+	constructor {} {
+	    global result
+	    lappend result "[self]->construct"
+	}
+	method bar {} {
+	    global result
+	    lappend result "[self]->bar"
+	}
+    }
+    set result {}
+    [testClass create foo] bar
+    testClass destroy
+    return $result
+} {::foo->construct ::foo->bar}
+test oo-2.4 {OO constructor - Bug 2531577} -setup {
+    oo::class create foo
+} -body {
+    oo::define foo constructor {} return
+    [foo new] destroy
+    oo::define foo constructor {} {}
+    llength [info command [foo new]]
+} -cleanup {
+    foo destroy
+} -result 1
+test oo-2.5 {OO constructor - Bug 2531577} -setup {
+    oo::class create foo
+    set result {}
+} -body {
+    oo::define foo constructor {} {error x}
+    lappend result [catch {foo new}]
+    oo::define foo constructor {} {}
+    lappend result [llength [info command [foo new]]]
+} -cleanup {
+    foo destroy
+} -result {1 1}
+test oo-2.6 {OO constructor and tailcall - Bug 2414858} -setup {
+    oo::class create foo
+} -body {
+    oo::define foo {
+	constructor {} { tailcall my bar }
+	method bar {}  { return bad }
+    }
+    namespace tail [foo create good]
+} -cleanup {
+    foo destroy
+} -result good
+test oo-2.7 {construction, method calls and ensembles - Bug 3514761} -setup {
+    namespace eval k {}
+} -body {
+    namespace eval k {
+	oo::class create s {
+	    constructor {j} {
+		# nothing
+	    }
+	}
+	namespace export s
+	namespace ensemble create
+    }
+    k s create X
+} -returnCodes error -cleanup {
+    namespace delete k
+} -result {wrong # args: should be "k s create X j"}
+test oo-2.8 {construction, method calls and ensembles - Bug 3514761} -setup {
+    namespace eval k {}
+} -body {
+    namespace eval k {
+	oo::class create s {
+	    constructor {j} {
+		# nothing
+	    }
+	}
+	oo::class create t {
+	    superclass s
+	    constructor args {
+		k next {*}$args
+	    }
+	}
+	interp alias {} ::k::next {} ::oo::Helpers::next
+	namespace export t next
+	namespace ensemble create
+    }
+    k t create X
+} -returnCodes error -cleanup {
+    namespace delete k
+} -result {wrong # args: should be "k next j"}
+test oo-2.9 {construction failures and self creation} -setup {
+    set ::result {}
+    oo::class create Root
+} -body {
+    oo::class create A {
+	superclass Root
+	constructor {} {
+	    lappend ::result "in A"
+	    error "failure in A"
+	}
+	destructor {lappend ::result [self]}
+    }
+    oo::class create B {
+	superclass Root
+	constructor {} {
+	    lappend ::result "in B [self]"
+	    error "failure in B"
+	}
+	destructor {lappend ::result [self]}
+    }
+    lappend ::result [catch {A create a} msg] $msg
+    lappend ::result [catch {B create b} msg] $msg
+} -cleanup {
+    Root destroy
+} -result {{in A} ::a 1 {failure in A} {in B ::b} ::b 1 {failure in B}}
+
+test oo-3.1 {basic test of OO functionality: destructor} -setup {
+    # This is a bit complex because it needs to run in a sub-interp as we're
+    # modifying the root object class's constructor
+    interp create subinterp
+    subinterp eval {
+	package require TclOO
+    }
+} -body {
+    subinterp eval {
+	oo::define oo::object destructor {
+	    lappend ::result died
+	}
+	lappend result 1 [oo::object create foo]
+	lappend result 2 [rename foo {}]
+	oo::define oo::object destructor {}
+	return $result
+    }
+} -cleanup {
+    interp delete subinterp
+} -result {1 ::foo died 2 {}}
+test oo-3.2 {basic test of OO functionality: destructor} -setup {
+    # This is a bit complex because it needs to run in a sub-interp as
+    # we're modifying the root object class's constructor
+    interp create subinterp
+    subinterp eval {
+	package require TclOO
+    }
+} -body {
+    subinterp eval {
+	oo::define oo::object destructor {
+	    lappend ::result died
+	}
+	lappend result 1 [oo::object create foo]
+	lappend result 2 [rename foo {}]
+    }
+} -cleanup {
+    interp delete subinterp
+} -result {1 ::foo died 2 {}}
+test oo-3.3 {basic test of OO functionality: destructor} -setup {
+    oo::class create foo
+    set result {}
+} -cleanup {
+    foo destroy
+} -body {
+    oo::define foo {
+	constructor {} {lappend ::result made}
+	destructor {lappend ::result died}
+    }
+    namespace delete [info object namespace [foo new]]
+    return $result
+} -result {made died}
+test oo-3.4 {basic test of OO functionality: my exists in destructor} -setup {
+    oo::class create cls
+    set result {}
+} -cleanup {
+    cls destroy
+} -body {
+    oo::define cls {
+	variable state
+	constructor {} {
+	    proc localcmdexists {} {}
+	    set state ok
+	}
+	forward Report lappend ::result
+	destructor {
+	    objmy Report [catch {set state} msg] $msg
+	    objmy Report [namespace which -var state]
+	    objmy Report [info commands localcmdexists]
+	}
+    }
+    cls create obj
+    rename [info object namespace obj]::my ::objmy
+    obj destroy
+    lappend result [info commands ::objmy]
+} -match glob -result {0 ok *::state localcmdexists {}}
+test oo-3.4a {basic test of OO functionality: my exists in destructor} -setup {
+    oo::class create cls
+    set result {}
+} -cleanup {
+    cls destroy
+} -body {
+    oo::define cls {
+	variable state
+	constructor {} {
+	    proc localcmdexists {} {}
+	    set state ok
+	}
+	forward Report lappend ::result
+	destructor {
+	    objmy Report [catch {set state} msg] $msg
+	    objmy Report [namespace which -var state]
+	    objmy Report [info commands localcmdexists]
+	}
+    }
+    cls create obj
+    rename [info object namespace obj]::my ::objmy
+    rename obj {}
+    lappend result [info commands ::objmy]
+} -match glob -result {0 ok *::state localcmdexists {}}
+test oo-3.5 {basic test of OO functionality: destructor: evil case for Itcl} -setup {
+    oo::class create cls
+    set result {}
+} -cleanup {
+    cls destroy
+} -body {
+    oo::define cls {
+	variable state
+	constructor {} {
+	    proc localcmdexists {} {}
+	    set state ok
+	}
+	forward Report lappend ::result
+	destructor {
+	    objmy Report [catch {set state} msg] $msg
+	    objmy Report [namespace which -var state]
+	    objmy Report [info commands localcmdexists]
+	}
+    }
+    cls create obj
+    rename [info object namespace obj]::my ::objmy
+    namespace delete [info object namespace obj]
+    lappend result [info commands ::objmy]
+} -match glob -result {0 ok *::state localcmdexists {}}
+test oo-3.5a {basic test of OO functionality: destructor: evil case for Itcl} -setup {
+    oo::class create cls
+    set result {}
+} -cleanup {
+    cls destroy
+} -body {
+    oo::define cls {
+	variable state result
+	constructor {} {
+	    proc localcmdexists {} {}
+	    set state ok
+	    my eval {upvar 0 ::result result}
+	}
+	method nuke {} {
+	    namespace delete [namespace current]
+	    return $result
+	}
+	destructor {
+	    lappend result [self] $state [info commands localcmdexists]
+	}
+    }
+    cls create obj
+    namespace delete [info object namespace obj]
+    [cls create obj2] nuke
+} -match glob -result {::obj ok localcmdexists ::obj2 ok localcmdexists}
+test oo-3.6 {basic test of OO functionality: errors in destructor} -setup {
+    oo::class create cls
+} -cleanup {
+    cls destroy
+} -body {
+    oo::define cls destructor {error foo}
+    list [catch {[cls create obj] destroy} msg] $msg [info commands obj]
+} -result {1 foo {}}
+test oo-3.7 {basic test of OO functionality: errors in destructor} -setup {
+    oo::class create cls
+    set result {}
+    proc bgerror msg {lappend ::result $msg}
+} -cleanup {
+    cls destroy
+    rename bgerror {}
+} -body {
+    oo::define cls destructor {error foo}
+    list [rename [cls create obj] {}] \
+	[update idletasks] $result [info commands obj]
+} -result {{} {} foo {}}
+test oo-3.8 {basic test of OO functionality: errors in destructor} -setup {
+    oo::class create cls
+    set result {}
+    proc bgerror msg {lappend ::result $msg}
+} -cleanup {
+    cls destroy
+    rename bgerror {}
+} -body {
+    oo::define cls destructor {error foo}
+    list [namespace delete [info object namespace [cls create obj]]] \
+	[update idletasks] $result [info commands obj]
+} -result {{} {} foo {}}
+test oo-3.9 {Bug 2944404: deleting the object in the destructor} -setup {
+    oo::class create cls
+    set result {}
+} -body {
+    oo::define cls {
+	destructor {
+	    lappend ::result in destructor
+	    [self] destroy
+	}
+    }
+    # This used to crash
+    [cls new] destroy
+    return $result
+} -cleanup {
+    cls destroy
+} -result {in destructor}
+test oo-3.10 {Bug 3d96b7076e: killing the object's class in a method call} -setup {
+    oo::class create Super
+} -body {
+    # Only reliably failed in a memdebug build
+    oo::class create Cls {
+	superclass Super
+	method mthd {} {
+	    [self class] destroy
+	    return ok
+	}
+    }
+    [Cls new] mthd
+} -cleanup {
+    Super destroy
+} -result ok
+test oo-3.11 {Bug 3d96b7076e: killing the object's class in a method call} -setup {
+    oo::class create Super
+    oo::class create Sub {
+	superclass Super
+    }
+} -body {
+    # Only reliably failed in a memdebug build
+    oo::class create Cls {
+	superclass Super
+	method mthd {} {
+	    oo::objdefine [self] class Sub
+	    Cls destroy
+	    return ok
+	}
+    }
+    [Cls new] mthd
+} -cleanup {
+    Super destroy
+} -result ok
+test oo-3.12 {Bug 3d96b7076e: killing the object's class in a method call} -setup {
+    oo::class create Super
+} -body {
+    # Only reliably failed in a memdebug build
+    oo::class create Cls {
+	superclass Super
+	method mthd {} {
+	    [self class] destroy
+	    return ok
+	}
+    }
+    set o [Super new]
+    oo::objdefine $o mixin Cls
+    $o mthd
+} -cleanup {
+    Super destroy
+} -result ok
+
+test oo-4.1 {basic test of OO functionality: export} {
+    set o [oo::object new]
+    set result {}
+    oo::objdefine $o method Foo {} {lappend ::result Foo; return}
+    lappend result [catch {$o Foo} msg] $msg
+    oo::objdefine $o export Foo
+    lappend result [$o Foo] [$o destroy]
+} {1 {unknown method "Foo": must be destroy} Foo {} {}}
+test oo-4.2 {basic test of OO functionality: unexport} {
+    set o [oo::object new]
+    set result {}
+    oo::objdefine $o method foo {} {lappend ::result foo; return}
+    lappend result [$o foo]
+    oo::objdefine $o unexport foo
+    lappend result [catch {$o foo} msg] $msg [$o destroy]
+} {foo {} 1 {unknown method "foo": must be destroy} {}}
+test oo-4.3 {exporting and error messages, Bug 1824958} -setup {
+    oo::class create testClass
+} -cleanup {
+    testClass destroy
+} -body {
+    oo::define testClass self export Bad
+    testClass Bad
+} -returnCodes 1 -result {unknown method "Bad": must be create, destroy or new}
+test oo-4.4 {exporting a class method from an object} -setup {
+    oo::class create testClass
+    testClass create testObject
+} -cleanup {
+    testClass destroy
+} -body {
+    oo::define testClass method Good {} { return ok }
+    oo::objdefine testObject export Good
+    testObject Good
+} -result ok
+test oo-4.5 {export creates proper method entries} -setup {
+    oo::class create testClass
+} -body {
+    oo::define testClass {
+	export foo
+	method foo {} {return ok}
+    }
+    [testClass new] foo
+} -cleanup {
+    testClass destroy
+} -result ok
+test oo-4.6 {export creates proper method entries} -setup {
+    oo::class create testClass
+} -body {
+    oo::define testClass {
+	unexport foo
+	method foo {} {return ok}
+    }
+    [testClass new] foo
+} -cleanup {
+    testClass destroy
+} -result ok
+
+test oo-5.1 {OO: manipulation of classes as objects} -setup {
+    set obj [oo::object new]
+} -body {
+    oo::objdefine oo::object method foo {} { return "in object" }
+    catch {$obj foo} result
+    list [catch {$obj foo} result] $result [oo::object foo]
+} -cleanup {
+    oo::objdefine oo::object deletemethod foo
+    $obj destroy
+} -result {1 {unknown method "foo": must be destroy} {in object}}
+test oo-5.2 {OO: manipulation of classes as objects} -setup {
+    set obj [oo::object new]
+} -body {
+    oo::define oo::object self method foo {} { return "in object" }
+    catch {$obj foo} result
+    list [catch {$obj foo} result] $result [oo::object foo]
+} -cleanup {
+    oo::objdefine oo::object deletemethod foo
+    $obj destroy
+} -result {1 {unknown method "foo": must be destroy} {in object}}
+test oo-5.3 {OO: manipulation of classes as objects} -setup {
+    set obj [oo::object new]
+} -body {
+    oo::objdefine oo::object {
+	method foo {} { return "in object" }
+    }
+    catch {$obj foo} result
+    list [catch {$obj foo} result] $result [oo::object foo]
+} -cleanup {
+    oo::objdefine oo::object deletemethod foo
+    $obj destroy
+} -result {1 {unknown method "foo": must be destroy} {in object}}
+test oo-5.4 {OO: manipulation of classes as objects} -setup {
+    set obj [oo::object new]
+} -body {
+    oo::define oo::object {
+	self method foo {} { return "in object" }
+    }
+    catch {$obj foo} result
+    list [catch {$obj foo} result] $result [oo::object foo]
+} -cleanup {
+    oo::objdefine oo::object deletemethod foo
+    $obj destroy
+} -result {1 {unknown method "foo": must be destroy} {in object}}
+test oo-5.5 {OO: manipulation of classes as objects} -setup {
+    set obj [oo::object new]
+} -body {
+    oo::define oo::object {
+	self {
+	    method foo {} { return "in object" }
+	}
+    }
+    catch {$obj foo} result
+    list [catch {$obj foo} result] $result [oo::object foo]
+} -cleanup {
+    oo::objdefine oo::object deletemethod foo
+    $obj destroy
+} -result {1 {unknown method "foo": must be destroy} {in object}}
+
+test oo-6.1 {OO: forward} {
+    oo::object create foo
+    oo::objdefine foo {
+	forward a lappend
+	forward b lappend result
+    }
+    set result {}
+    foo a result 1
+    foo b 2
+    foo destroy
+    return $result
+} {1 2}
+test oo-6.2 {OO: forward resolution scope} -setup {
+    oo::class create fooClass
+} -body {
+    proc foo {} {return bad}
+    oo::define fooClass {
+	constructor {} {
+	    proc foo {} {return good}
+	}
+	forward bar foo
+    }
+    [fooClass new] bar
+} -cleanup {
+    fooClass destroy
+    rename foo {}
+} -result good
+test oo-6.3 {OO: forward resolution scope} -setup {
+    oo::class create fooClass
+} -body {
+    proc foo {} {return bad}
+    oo::define fooClass {
+	constructor {} {
+	    proc foo {} {return good}
+	}
+    }
+    oo::define fooClass forward bar foo
+    [fooClass new] bar
+} -cleanup {
+    fooClass destroy
+    rename foo {}
+} -result good
+test oo-6.4 {OO: forward resolution scope} -setup {
+    oo::class create fooClass
+} -body {
+    proc foo {} {return good}
+    oo::define fooClass {
+	constructor {} {
+	    proc foo {} {return bad}
+	}
+	forward bar ::foo
+    }
+    [fooClass new] bar
+} -cleanup {
+    fooClass destroy
+    rename foo {}
+} -result good
+test oo-6.5 {OO: forward resolution scope} -setup {
+    oo::class create fooClass
+    namespace eval foo {}
+} -body {
+    proc foo::foo {} {return good}
+    oo::define fooClass {
+	constructor {} {
+	    proc foo {} {return bad}
+	}
+	forward bar foo::foo
+    }
+    [fooClass new] bar
+} -cleanup {
+    fooClass destroy
+    namespace delete foo
+} -result good
+test oo-6.6 {OO: forward resolution scope} -setup {
+    oo::class create fooClass
+    namespace eval foo {}
+} -body {
+    proc foo::foo {} {return bad}
+    oo::define fooClass {
+	constructor {} {
+	    namespace eval foo {
+		proc foo {} {return good}
+	    }
+	}
+	forward bar foo::foo
+    }
+    [fooClass new] bar
+} -cleanup {
+    fooClass destroy
+    namespace delete foo
+} -result good
+test oo-6.7 {OO: forward resolution scope is per-object} -setup {
+    oo::class create fooClass
+} -body {
+    oo::define fooClass {
+	constructor {} {
+	    proc curns {} {namespace current}
+	}
+	forward ns curns
+    }
+    expr {[[fooClass new] ns] ne [[fooClass new] ns]}
+} -cleanup {
+    fooClass destroy
+} -result 1
+test oo-6.8 {Bug 3400658: forwarding and wrongargs rewriting} -setup {
+    oo::class create fooClass
+} -body {
+    oo::define fooClass {
+	forward test my handler
+	method handler {a b c} {}
+    }
+    fooClass create ::foo
+    foo test
+} -returnCodes error -cleanup {
+    fooClass destroy
+} -result {wrong # args: should be "foo test a b c"}
+test oo-6.9 {Bug 3400658: forwarding and wrongargs rewriting} -setup {
+    oo::class create fooClass
+} -body {
+    oo::define fooClass {
+	forward test my handler
+	method handler {a b c} {list $a,$b,$c}
+    }
+    fooClass create ::foo
+    foo test 1 2 3
+} -cleanup {
+    fooClass destroy
+} -result 1,2,3
+test oo-6.10 {Bug 3400658: forwarding and wrongargs rewriting} -setup {
+    oo::class create fooClass
+} -body {
+    oo::define fooClass {
+	forward test my handler
+	method handler {a b c} {list $a,$b,$c}
+    }
+    fooClass create ::foo
+    foo test 1 2
+} -returnCodes error -cleanup {
+    fooClass destroy
+} -result {wrong # args: should be "foo test a b c"}
+test oo-6.11 {Bug 3400658: forwarding and wrongargs rewriting} -setup {
+    oo::object create foo
+} -body {
+    oo::objdefine foo {
+	forward test my handler
+	method handler {a b c} {}
+    }
+    foo test
+} -returnCodes error -cleanup {
+    foo destroy
+} -result {wrong # args: should be "foo test a b c"}
+test oo-6.12 {Bug 3400658: forwarding and wrongargs rewriting} -setup {
+    oo::object create foo
+} -body {
+    oo::objdefine foo {
+	forward test my handler
+	method handler {a b c} {list $a,$b,$c}
+    }
+    foo test 1 2 3
+} -cleanup {
+    foo destroy
+} -result 1,2,3
+test oo-6.13 {Bug 3400658: forwarding and wrongargs rewriting} -setup {
+    oo::object create foo
+} -body {
+    oo::objdefine foo {
+	forward test my handler
+	method handler {a b c} {list $a,$b,$c}
+    }
+    foo test 1 2
+} -returnCodes error -cleanup {
+    foo destroy
+} -result {wrong # args: should be "foo test a b c"}
+test oo-6.14 {Bug 3400658: forwarding and wrongargs rewriting - multistep} -setup {
+    oo::class create fooClass
+} -body {
+    oo::define fooClass {
+	forward test my handler1 p
+	forward handler1 my handler q
+	method handler {a b c} {}
+    }
+    fooClass create ::foo
+    foo test
+} -returnCodes error -cleanup {
+    fooClass destroy
+} -result {wrong # args: should be "foo test c"}
+test oo-6.15 {Bug 3400658: forwarding and wrongargs rewriting - multistep} -setup {
+    oo::class create fooClass
+} -body {
+    oo::define fooClass {
+	forward test my handler1 p
+	forward handler1 my handler q
+	method handler {a b c} {list $a,$b,$c}
+    }
+    fooClass create ::foo
+    foo test 1
+} -cleanup {
+    fooClass destroy
+} -result q,p,1
+test oo-6.16 {Bug 3400658: forwarding and wrongargs rewriting - via alias} -setup {
+    oo::class create fooClass
+} -body {
+    oo::define fooClass {
+	forward test handler1 foo bar
+	forward handler2 my handler x
+	method handler {a b c d} {list $a,$b,$c,$d}
+	export eval
+    }
+    fooClass create ::foo
+    foo eval {
+	interp alias {} [namespace current]::handler1 \
+	    {} [namespace current]::my handler2
+    }
+    foo test 1 2 3
+} -returnCodes error -cleanup {
+    fooClass destroy
+} -result {wrong # args: should be "foo test d"}
+test oo-6.17 {Bug 3400658: forwarding and wrongargs rewriting - via ensemble} -setup {
+    oo::class create fooClass
+} -body {
+    oo::define fooClass {
+	forward test handler1 foo bar boo
+	forward handler2 my handler
+	method handler {a b c d} {list $a,$b,$c,$d}
+	export eval
+    }
+    fooClass create ::foo
+    foo eval {
+	namespace ensemble create \
+	    -command [namespace current]::handler1 -parameters {p q} \
+	    -map [list boo [list [namespace current]::my handler2]]
+    }
+    foo test 1 2 3
+} -returnCodes error -cleanup {
+    fooClass destroy
+} -result {wrong # args: should be "foo test c d"}
+test oo-6.18 {Bug 3408830: more forwarding cases} -setup {
+    oo::class create fooClass
+} -body {
+    oo::define fooClass {
+	forward len  string length
+    }
+    [fooClass create foo] len a b
+} -returnCodes error -cleanup {
+    fooClass destroy
+} -result {wrong # args: should be "::foo len string"}
+test oo-6.19 {Bug 3610404: forwarding resolution + traces} -setup {
+    oo::object create foo
+    unset -nocomplain ::result
+    set ::result {}
+} -body {
+    proc ::my {method} {lappend ::result global}
+    oo::objdefine foo {
+	method target {} {lappend ::result instance}
+	forward bar my target
+	method bump {} {
+	    set ns [info object namespace ::foo]
+	    rename ${ns}::my ${ns}::
+	    rename ${ns}:: ${ns}::my
+	}
+    }
+    proc harness {} {
+	foo target
+	foo bar
+	foo target
+    }
+    trace add execution harness enterstep {apply {{cmd args} {foo bump}}}
+    foo target
+    foo bar
+    foo bump
+    foo bar
+    harness
+} -cleanup {
+    catch {rename harness {}}
+    catch {rename ::my {}}
+    foo destroy
+} -result {instance instance instance instance instance instance}
+test oo-6.20 {Bug 3610404: forwarding resolution + traces} -setup {
+    oo::class create fooClass
+    fooClass create foo
+    unset -nocomplain ::result
+    set ::result {}
+} -body {
+    proc ::my {method} {lappend ::result global}
+    oo::define fooClass {
+	method target {} {lappend ::result class}
+	forward bar my target
+	method bump {} {
+	    set ns [info object namespace [self]]
+	    rename ${ns}::my ${ns}::
+	    rename ${ns}:: ${ns}::my
+	}
+    }
+    proc harness {} {
+	foo target
+	foo bar
+	foo target
+    }
+    trace add execution harness enterstep {apply {{cmd args} {foo bump}}}
+    foo target
+    foo bar
+    foo bump
+    foo bar
+    harness
+} -cleanup {
+    catch {rename harness {}}
+    catch {rename ::my {}}
+    fooClass destroy
+} -result {class class class class class class}
+
+test oo-7.1 {OO: inheritance 101} -setup {
+    oo::class create superClass
+    oo::class create subClass
+    subClass create instance
+} -body {
+    oo::define superClass method doit x {lappend ::result $x}
+    oo::define subClass superclass superClass
+    set result [list [catch {subClass doit bad} msg] $msg]
+    instance doit ok
+    return $result
+} -cleanup {
+    subClass destroy
+    superClass destroy
+} -result {1 {unknown method "doit": must be create, destroy or new} ok}
+test oo-7.2 {OO: inheritance 101} -setup {
+    oo::class create superClass
+    oo::class create subClass
+    subClass create instance
+} -body {
+    oo::define superClass method doit x {
+	lappend ::result |$x|
+    }
+    oo::define subClass superclass superClass
+    oo::objdefine instance method doit x {
+	lappend ::result =$x=
+	next [incr x]
+    }
+    set result {}
+    instance doit 1
+    return $result
+} -cleanup {
+    subClass destroy
+    superClass destroy
+} -result {=1= |2|}
+test oo-7.3 {OO: inheritance 101} -setup {
+    oo::class create superClass
+    oo::class create subClass
+    subClass create instance
+} -body {
+    oo::define superClass method doit x {
+	lappend ::result |$x|
+    }
+    oo::define subClass {
+	superclass superClass
+	method doit x {lappend ::result -$x-; next [incr x]}
+    }
+    oo::objdefine instance method doit x {
+	lappend ::result =$x=;
+	next [incr x]
+    }
+    set result {}
+    instance doit 1
+    return $result
+} -cleanup {
+    subClass destroy
+    superClass destroy
+} -result {=1= -2- |3|}
+test oo-7.4 {OO: inheritance from oo::class} -body {
+    oo::class create meta {
+	superclass oo::class
+	self {
+	    unexport create new
+	    method make {x {definitions {}}} {
+		if {![string match ::* $x]} {
+		    set ns [uplevel 1 {::namespace current}]
+		    set x ${ns}::$x
+		}
+		set o [my create $x]
+		lappend ::result "made $o"
+		oo::define $o $definitions
+		return $o
+	    }
+	}
+    }
+    set result [list [catch {meta create foo} msg] $msg]
+    lappend result [meta make classinstance {
+	lappend ::result "in definition script in [namespace current]"
+    }]
+    lappend result [classinstance create instance]
+} -cleanup {
+    catch {classinstance destroy}
+    catch {meta destroy}
+} -result {1 {unknown method "create": must be destroy or make} {made ::classinstance} {in definition script in ::oo::define} ::classinstance ::instance}
+test oo-7.5 {OO: inheritance from oo::class in the secondary chain} -body {
+    oo::class create other
+    oo::class create meta {
+	superclass other oo::class
+	self {
+	    unexport create new
+	    method make {x {definitions {}}} {
+		if {![string match ::* $x]} {
+		    set ns [uplevel 1 {::namespace current}]
+		    set x ${ns}::$x
+		}
+		set o [my create $x]
+		lappend ::result "made $o"
+		oo::define $o $definitions
+		return $o
+	    }
+	}
+    }
+    set result [list [catch {meta create foo} msg] $msg]
+    lappend result [meta make classinstance {
+	lappend ::result "in definition script in [namespace current]"
+    }]
+    lappend result [classinstance create instance]
+} -cleanup {
+    catch {classinstance destroy}
+    catch {meta destroy}
+    catch {other destroy}
+} -result {1 {unknown method "create": must be destroy or make} {made ::classinstance} {in definition script in ::oo::define} ::classinstance ::instance}
+test oo-7.6 {OO: inheritance 101 - overridden methods should be oblivious} -setup {
+    oo::class create Aclass
+    oo::class create Bclass
+    Bclass create Binstance
+} -body {
+    oo::define Aclass {
+	method incr {var step} {
+	    upvar 1 $var v
+	    ::incr v $step
+	}
+    }
+    oo::define Bclass {
+	superclass Aclass
+	method incr {var {step 1}} {
+	    global result
+	    lappend result $var $step
+	    set r [next $var $step]
+	    lappend result returning:$r
+	    return $r
+	}
+    }
+    set result {}
+    set x 10
+    lappend result x=$x
+    lappend result [Binstance incr x]
+    lappend result x=$x
+} -result {x=10 x 1 returning:11 11 x=11} -cleanup {
+    unset -nocomplain x
+    Aclass destroy
+}
+test oo-7.7 {OO: inheritance and errorInfo} -setup {
+    oo::class create A
+    oo::class create B
+    B create c
+} -body {
+    oo::define A method foo {} {error foo!}
+    oo::define B {
+	superclass A
+	method foo {} { next }
+    }
+    oo::objdefine c method foo {} { next }
+    catch {c ?} msg
+    set result [list $msg]
+    catch {c foo} msg
+    lappend result $msg $errorInfo
+} -cleanup {
+    A destroy
+} -result {{unknown method "?": must be destroy or foo} foo! {foo!
+    while executing
+"error foo!"
+    (class "::A" method "foo" line 1)
+    invoked from within
+"next "
+    (class "::B" method "foo" line 1)
+    invoked from within
+"next "
+    (object "::c" method "foo" line 1)
+    invoked from within
+"c foo"}}
+test oo-7.8 {OO: next at the end of the method chain} -setup {
+    set ::result ""
+} -cleanup {
+    foo destroy
+} -body {
+    oo::class create foo {
+	method bar {} {lappend ::result foo; lappend ::result [next] foo}
+    }
+    oo::class create foo2 {
+	superclass foo
+	method bar {} {lappend ::result foo2; lappend ::result [next] foo2}
+    }
+    lappend result [catch {[foo2 new] bar} msg] $msg
+} -result {foo2 foo 1 {no next method implementation}}
+test oo-7.9 {OO: defining inheritance in namespaces} -setup {
+    set ::result {}
+    oo::class create ::master
+    namespace eval ::foo {
+	oo::class create mixin {superclass ::master}
+    }
+} -cleanup {
+    ::master destroy
+    namespace delete ::foo
+} -body {
+    namespace eval ::foo {
+	oo::class create bar {superclass master}
+	oo::class create boo
+	oo::define boo {superclass bar}
+	oo::define boo {mixin mixin}
+	oo::class create spong {superclass boo}
+	return
+    }
+} -result {}
+
+test oo-8.1 {OO: global must work in methods} {
+    oo::object create foo
+    oo::objdefine foo method bar x {global result; lappend result $x}
+    set result {}
+    foo bar this
+    foo bar is
+    lappend result a
+    foo bar test
+    foo destroy
+    return $result
+} {this is a test}
+
+test oo-9.1 {OO: multiple inheritance} -setup {
+    oo::class create A
+    oo::class create B
+    oo::class create C
+    oo::class create D
+    D create foo
+} -body {
+    oo::define A method test {} {lappend ::result A; return ok}
+    oo::define B {
+	superclass A
+	method test {} {lappend ::result B; next}
+    }
+    oo::define C {
+	superclass A
+	method test {} {lappend ::result C; next}
+    }
+    oo::define D {
+	superclass B C
+	method test {} {lappend ::result D; next}
+    }
+    set result {}
+    lappend result [foo test]
+} -cleanup {
+    D destroy
+    C destroy
+    B destroy
+    A destroy
+} -result {D B C A ok}
+test oo-9.2 {OO: multiple inheritance} -setup {
+    oo::class create A
+    oo::class create B
+    oo::class create C
+    oo::class create D
+    D create foo
+} -body {
+    oo::define A method test {} {lappend ::result A; return ok}
+    oo::define B {
+	superclass A
+	method test {} {lappend ::result B; next}
+    }
+    oo::define C {
+	superclass A
+	method test {} {lappend ::result C; next}
+    }
+    oo::define D {
+	superclass B C
+	method test {} {lappend ::result D; next}
+    }
+    set result {}
+    lappend result [foo test]
+} -cleanup {
+    A destroy
+} -result {D B C A ok}
+
+test oo-10.1 {OO: recursive invoke and modify} -setup {
+    [oo::class create C] create O
+} -cleanup {
+    C destroy
+} -body {
+    oo::define C method foo x {
+	lappend ::result $x
+	if {$x} {
+	    [self object] foo [incr x -1]
+	}
+    }
+    oo::objdefine O method foo x {
+	lappend ::result -$x-
+	if {$x == 1} {
+	    oo::objdefine O deletemethod foo
+	}
+	next $x
+    }
+    set result {}
+    O foo 2
+    return $result
+} -result {-2- 2 -1- 1 0}
+test oo-10.2 {OO: recursive invoke and modify} -setup {
+    oo::object create O
+} -cleanup {
+    O destroy
+} -body {
+    oo::objdefine O method foo {} {
+	oo::objdefine [self] method foo {} {
+	    error "not called"
+	}
+	return [format %s%s call ed]
+    }
+    O foo
+} -result called
+test oo-10.3 {OO: invoke and modify} -setup {
+    oo::class create A {
+	method a {} {return A.a}
+	method b {} {return A.b}
+	method c {} {return A.c}
+    }
+    oo::class create B {
+	superclass A
+	method a {} {return [next],B.a}
+	method b {} {return [next],B.b}
+	method c {} {return [next],B.c}
+    }
+    B create C
+    set result {}
+} -cleanup {
+    A destroy
+} -body {
+    lappend result [C a] [C b] [C c] -
+    oo::define B deletemethod b
+    lappend result [C a] [C b] [C c] -
+    oo::define B renamemethod a b
+    lappend result [C a] [C b] [C c] -
+    oo::define B deletemethod b c
+    lappend result [C a] [C b] [C c]
+} -result {A.a,B.a A.b,B.b A.c,B.c - A.a,B.a A.b A.c,B.c - A.a A.b,B.a A.c,B.c - A.a A.b A.c}
+
+test oo-11.1 {OO: cleanup} {
+    oo::object create foo
+    set result [list [catch {oo::object create foo} msg] $msg]
+    lappend result [foo destroy] [oo::object create foo] [foo destroy]
+} {1 {can't create object "foo": command already exists with that name} {} ::foo {}}
+test oo-11.2 {OO: cleanup} {
+    oo::class create bar
+    bar create foo
+    set result [list [catch {bar create foo} msg] $msg]
+    lappend result [bar destroy] [oo::object create foo] [foo destroy]
+} {1 {can't create object "foo": command already exists with that name} {} ::foo {}}
+test oo-11.3 {OO: cleanup} {
+    oo::class create bar0
+    oo::class create bar
+    oo::define bar superclass bar0
+    bar create foo
+    set result [list [catch {bar create foo} msg] $msg]
+    lappend result [bar0 destroy] [oo::object create foo] [foo destroy]
+} {1 {can't create object "foo": command already exists with that name} {} ::foo {}}
+test oo-11.4 {OO: cleanup} {
+    oo::class create bar0
+    oo::class create bar1
+    oo::define bar1 superclass bar0
+    oo::class create bar2
+    oo::define bar2 {
+	superclass bar0
+	destructor {lappend ::result destroyed}
+    }
+    oo::class create bar
+    oo::define bar superclass bar1 bar2
+    bar create foo
+    set result [list [catch {bar create foo} msg] $msg]
+    lappend result [bar0 destroy] [oo::object create foo] [foo destroy] \
+	[oo::object create bar2] [bar2 destroy]
+} {1 {can't create object "foo": command already exists with that name} destroyed {} ::foo {} ::bar2 {}}
+
+test oo-12.1 {OO: filters} {
+    oo::class create Aclass
+    Aclass create Aobject
+    oo::define Aclass {
+	method concatenate args {
+	    global result
+	    lappend result {*}$args
+	    join $args {}
+	}
+	method logFilter args {
+	    global result
+	    lappend result "calling [self object]->[self method] $args"
+	    set r [next {*}$args]
+	    lappend result "result=$r"
+	    return $r
+	}
+    }
+    oo::objdefine Aobject filter logFilter
+    set result {}
+    lappend result [Aobject concatenate 1 2 3 4 5]
+    Aclass destroy
+    return $result
+} {{calling ::Aobject->logFilter 1 2 3 4 5} 1 2 3 4 5 result=12345 12345}
+test oo-12.2 {OO: filters} -setup {
+    oo::class create Aclass
+    Aclass create Aobject
+} -body {
+    oo::define Aclass {
+	method concatenate args {
+	    global result
+	    lappend result {*}$args
+	    join $args {}
+	}
+	method logFilter args {
+	    global result
+	    lappend result "calling [self object]->[self method] $args"
+	    set r [next {*}$args]
+	    lappend result "result=$r"
+	    return $r
+	}
+    }
+    oo::objdefine Aobject filter logFilter
+    set result {}
+    lappend result [Aobject concatenate 1 2 3 4 5] [Aobject destroy]
+} -cleanup {
+    Aclass destroy
+} -result {{calling ::Aobject->logFilter 1 2 3 4 5} 1 2 3 4 5 result=12345 {calling ::Aobject->logFilter } result= 12345 {}}
+test oo-12.3 {OO: filters} -setup {
+    oo::class create Aclass
+    Aclass create Aobject
+} -body {
+    oo::define Aclass {
+	method concatenate args {
+	    global result
+	    lappend result {*}$args
+	    join $args {}
+	}
+	method logFilter args {
+	    global result
+	    lappend result "calling [self object]->[self method] $args"
+	    set r [next {*}$args]
+	    lappend result "result=$r"
+	    return $r
+	}
+	filter logFilter
+    }
+    set result {}
+    lappend result [Aobject concatenate 1 2 3 4 5] [Aobject destroy]
+} -cleanup {
+    Aclass destroy
+} -result {{calling ::Aobject->logFilter 1 2 3 4 5} 1 2 3 4 5 result=12345 {calling ::Aobject->logFilter } result= 12345 {}}
+test oo-12.4 {OO: filters} -setup {
+    oo::class create Aclass
+    Aclass create Aobject
+} -body {
+    oo::define Aclass {
+	method foo {} { return foo }
+	method Bar {} { return 1 }
+	method boo {} { if {[my Bar]} { next } { error forbidden } }
+	filter boo
+    }
+    Aobject foo
+} -cleanup {
+    Aclass destroy
+} -result foo
+test oo-12.5 {OO: filters} -setup {
+    oo::class create Aclass
+    Aclass create Aobject
+} -body {
+    oo::define Aclass {
+	method foo {} { return foo }
+	method Bar {} { return [my Bar2] }
+	method Bar2 {} { return 1 }
+	method boo {} { if {[my Bar]} { next } { error forbidden } }
+	filter boo
+    }
+    Aobject foo
+} -cleanup {
+    Aclass destroy
+} -result foo
+test oo-12.6 {OO: filters} -setup {
+    oo::class create Aclass
+    Aclass create Aobject
+} -body {
+    oo::define Aclass {
+	method foo {} { return foo }
+	method Bar {} { return [my Bar2] }
+	method Bar2 {} { return [my Bar3] }
+	method Bar3 {} { return 1 }
+	method boo {} { if {[my Bar]} { next } { error forbidden } }
+	filter boo
+    }
+    Aobject foo
+} -cleanup {
+    Aclass destroy
+} -result foo
+test oo-12.7 {OO: filters} -setup {
+    oo::class create Aclass
+    Aclass create Aobject
+} -body {
+    oo::define Aclass {
+	method outerfoo {} { return [my InnerFoo] }
+	method InnerFoo {} { return foo }
+	method Bar {} { return [my Bar2] }
+	method Bar2 {} { return [my Bar3] }
+	method Bar3 {} { return 1 }
+	method boo {} {
+	    lappend ::log [self target]
+	    if {[my Bar]} { next } else { error forbidden }
+	}
+	filter boo
+    }
+    set log {}
+    list [Aobject outerfoo] $log
+} -cleanup {
+    Aclass destroy
+} -result {foo {{::Aclass outerfoo} {::Aclass InnerFoo}}}
+test oo-12.8 {OO: filters and destructors} -setup {
+    oo::class create Aclass
+    Aclass create Aobject
+    set ::log {}
+} -body {
+    oo::define Aclass {
+	constructor {} {
+	    lappend ::log "in constructor"
+	}
+	destructor {
+	    lappend ::log "in destructor"
+	}
+	method bar {} {
+	    lappend ::log "in method"
+	}
+	method Boo args {
+	    lappend ::log [self target]
+	    next {*}$args
+	}
+	filter Boo
+    }
+    set obj [Aclass new]
+    $obj bar
+    $obj destroy
+    return $::log
+} -cleanup {
+    Aclass destroy
+} -result {{in constructor} {::Aclass bar} {in method} {::oo::object destroy} {in destructor}}
+
+test oo-13.1 {OO: changing an object's class} {
+    oo::class create Aclass
+    oo::define Aclass {method bar {} {lappend ::result "in A [self object]"}}
+    oo::class create Bclass
+    oo::define Bclass {method bar {} {lappend ::result "in B [self object]"}}
+    set result [Aclass create foo]
+    foo bar
+    oo::objdefine foo class Bclass
+    foo bar
+    Aclass destroy
+    lappend result [info command foo]
+    Bclass destroy
+    return $result
+} {::foo {in A ::foo} {in B ::foo} foo}
+test oo-13.2 {OO: changing an object's class} -body {
+    oo::object create foo
+    oo::objdefine foo class oo::class
+} -cleanup {
+    foo destroy
+} -returnCodes 1 -result {may not change a non-class object into a class object}
+test oo-13.3 {OO: changing an object's class} -body {
+    oo::class create foo
+    oo::objdefine foo class oo::object
+} -cleanup {
+    foo destroy
+} -returnCodes 1 -result {may not change a class object into a non-class object}
+test oo-13.4 {OO: changing an object's class} -body {
+    oo::class create foo {
+	method m {} {
+	    set result [list [self class] [info object class [self]]]
+	    oo::objdefine [self] class ::bar
+	    lappend result [self class] [info object class [self]]
+	}
+    }
+    oo::class create bar
+    [foo new] m
+} -cleanup {
+    foo destroy
+    bar destroy
+} -result {::foo ::foo ::foo ::bar}
+# todo: changing a class subtype (metaclass) to another class subtype
+
+test oo-14.1 {OO: mixins} {
+    oo::class create Aclass
+    oo::define Aclass method bar {} {lappend ::result "[self object] in bar"}
+    oo::class create Bclass
+    oo::define Bclass method boo {} {lappend ::result "[self object] in boo"}
+    oo::objdefine [Aclass create fooTest] mixin Bclass
+    oo::objdefine [Aclass create fooTest2] mixin Bclass
+    set result [list [catch {fooTest ?} msg] $msg]
+    fooTest bar
+    fooTest boo
+    fooTest2 bar
+    fooTest2 boo
+    oo::objdefine fooTest2 mixin
+    lappend result [Bclass destroy] [info command fooTest*] [Aclass destroy]
+} {1 {unknown method "?": must be bar, boo or destroy} {::fooTest in bar} {::fooTest in boo} {::fooTest2 in bar} {::fooTest2 in boo} {} fooTest2 {}}
+test oo-14.2 {OO: mixins} {
+    oo::class create Aclass {
+	method bar {} {return "[self object] in bar"}
+    }
+    oo::class create Bclass {
+	method boo {} {return "[self object] in boo"}
+    }
+    oo::define Aclass mixin Bclass
+    Aclass create fooTest
+    set result [list [catch {fooTest ?} msg] $msg]
+    lappend result [catch {fooTest bar} msg] $msg
+    lappend result [catch {fooTest boo} msg] $msg
+    lappend result [Bclass destroy] [info commands Aclass]
+} {1 {unknown method "?": must be bar, boo or destroy} 0 {::fooTest in bar} 0 {::fooTest in boo} {} {}}
+test oo-14.3 {OO and mixins and filters - advanced case} -setup {
+    oo::class create mix
+    oo::class create c {
+	mixin mix
+    }
+    c create i
+} -body {
+    oo::define mix {
+	method foo {} {return >>[next]<<}
+	filter foo
+    }
+    oo::objdefine i method bar {} {return foobar}
+    i bar
+} -cleanup {
+    mix destroy
+    if {[info object isa object i]} {
+	error "mixin deletion failed to destroy dependent instance"
+    }
+} -result >>foobar<<
+test oo-14.4 {OO: mixin error case} -setup {
+    oo::class create c
+} -body {
+    oo::define c mixin c
+} -returnCodes error -cleanup {
+    c destroy
+} -result {may not mix a class into itself}
+test oo-14.5 {OO and mixins and filters - advanced case} -setup {
+    oo::class create mix
+    oo::class create c {
+	mixin mix
+    }
+    c create i
+} -body {
+    oo::define mix {
+	method foo {} {return >>[next]<<}
+	filter foo
+    }
+    oo::objdefine i method bar {} {return foobar}
+    i bar
+} -cleanup {
+    c destroy
+    mix destroy
+} -result >>foobar<<
+test oo-14.6 {OO and mixins of mixins - Bug 1960703} -setup {
+    oo::class create master
+} -cleanup {
+    master destroy
+} -body {
+    oo::class create A {
+	superclass master
+	method egg {} {
+	    return chicken
+	}
+    }
+    oo::class create B {
+	superclass master
+	mixin A
+	method bar {} {
+	    # mixin from A
+	    my egg
+	}
+    }
+    oo::class create C {
+	superclass master
+	mixin B
+	method foo {} {
+	    # mixin from B
+	    my bar
+	}
+    }
+    [C new] foo
+} -result chicken
+test oo-14.7 {OO and filters from mixins of mixins} -setup {
+    oo::class create master
+} -cleanup {
+    master destroy
+} -body {
+    oo::class create A {
+	superclass master
+	method egg {} {
+	    return chicken
+	}
+	filter f
+	method f args {
+	    set m [lindex [self target] 1]
+	    return "($m) [next {*}$args] ($m)"
+	}
+    }
+    oo::class create B {
+	superclass master
+	mixin A
+	filter f
+	method bar {} {
+	    # mixin from A
+	    my egg
+	}
+    }
+    oo::class create C {
+	superclass master
+	mixin B
+	filter f
+	method foo {} {
+	    # mixin from B
+	    my bar
+	}
+    }
+    [C new] foo
+} -result {(foo) (bar) (egg) chicken (egg) (bar) (foo)}
+test oo-14.8 {OO: class mixin order - Bug 1998221} -setup {
+    set ::result {}
+    oo::class create master {
+	method test {} {}
+    }
+} -cleanup {
+    master destroy
+} -body {
+    oo::class create mix {
+	superclass master
+	method test {} {lappend ::result mix; next; return $::result}
+    }
+    oo::class create cls {
+	superclass master
+	mixin mix
+	method test {} {lappend ::result cls; next; return $::result}
+    }
+    [cls new] test
+} -result {mix cls}
+
+test oo-15.1 {OO: object cloning} {
+    oo::class create Aclass
+    oo::define Aclass method test {} {lappend ::result [self object]->test}
+    Aclass create Ainstance
+    set result {}
+    Ainstance test
+    oo::copy Ainstance Binstance
+    Binstance test
+    Ainstance test
+    Ainstance destroy
+    namespace eval foo {
+	oo::copy Binstance Cinstance
+	Cinstance test
+    }
+    Aclass destroy
+    namespace delete foo
+    lappend result [info commands Binstance]
+} {::Ainstance->test ::Binstance->test ::Ainstance->test ::foo::Cinstance->test {}}
+test oo-15.2 {OO: object cloning} {
+    oo::object create foo
+    oo::objdefine foo {
+	method m x {lappend ::result [self object] >$x<}
+	forward f ::lappend ::result fwd
+    }
+    set result {}
+    foo m 1
+    foo f 2
+    lappend result [oo::copy foo bar]
+    foo m 3
+    foo f 4
+    bar m 5
+    bar f 6
+    lappend result [foo destroy]
+    bar m 7
+    bar f 8
+    lappend result [bar destroy]
+} {::foo >1< fwd 2 ::bar ::foo >3< fwd 4 ::bar >5< fwd 6 {} ::bar >7< fwd 8 {}}
+catch {foo destroy}
+catch {bar destroy}
+test oo-15.3 {OO: class cloning} {
+    oo::class create foo {
+	method testme {} {lappend ::result [self class]->[self object]}
+    }
+    set result {}
+    foo create baseline
+    baseline testme
+    oo::copy foo bar
+    baseline testme
+    bar create tester
+    tester testme
+    foo destroy
+    tester testme
+    bar destroy
+    return $result
+} {::foo->::baseline ::foo->::baseline ::bar->::tester ::bar->::tester}
+test oo-15.4 {OO: object cloning - Bug 3474460} -setup {
+    oo::class create ArbitraryClass
+} -body {
+    ArbitraryClass create foo
+    oo::objdefine foo variable a b c
+    oo::copy foo bar
+    info object variable bar
+} -cleanup {
+    ArbitraryClass destroy
+} -result {a b c}
+test oo-15.5 {OO: class cloning - Bug 3474460} -setup {
+    oo::class create ArbitraryClass
+} -body {
+    oo::class create Foo {
+	superclass ArbitraryClass
+	variable a b c
+    }
+    oo::copy Foo Bar
+    info class variable Bar
+} -cleanup {
+    ArbitraryClass destroy
+} -result {a b c}
+test oo-15.6 {OO: object cloning copies namespace contents} -setup {
+    oo::class create ArbitraryClass {export eval}
+} -body {
+    ArbitraryClass create a
+    a eval {proc foo x {
+	variable y
+	return [string repeat $x [incr y]]
+    }}
+    set result [list [a eval {foo 2}] [a eval {foo 3}]]
+    oo::copy a b
+    a eval {rename foo bar}
+    lappend result [b eval {foo 2}] [b eval {foo 3}] [a eval {bar 4}]
+} -cleanup {
+    ArbitraryClass destroy
+} -result {2 33 222 3333 444}
+test oo-15.7 {OO: classes can be cloned anonymously} -setup {
+    oo::class create ArbitraryClassA
+    oo::class create ArbitraryClassB {superclass ArbitraryClassA}
+} -body {
+    info object isa class [oo::copy ArbitraryClassB]
+} -cleanup {
+    ArbitraryClassA destroy
+} -result 1
+test oo-15.8 {OO: intercept object cloning} -setup {
+    oo::class create Foo
+    set result {}
+} -body {
+    oo::define Foo {
+	constructor {msg} {
+	    variable v $msg
+	}
+	method <cloned> {from} {
+	    next $from
+	    lappend ::result cloned $from [self]
+	}
+	method check {} {
+	    variable v
+	    lappend ::result check [self] $v
+	}
+    }
+    Foo create foo ok
+    oo::copy foo bar
+    foo check
+    bar check
+} -cleanup {
+    Foo destroy
+} -result {cloned ::foo ::bar check ::foo ok check ::bar ok}
+test oo-15.9 {ensemble rewriting must not bleed through oo::copy} -setup {
+    oo::class create Foo
+} -body {
+    oo::define Foo {
+	method <cloned> {a b} {}
+    }
+    interp alias {} Bar {} oo::copy [Foo create foo]
+    Bar bar
+} -returnCodes error -cleanup {
+    Foo destroy
+} -result {wrong # args: should be "::bar <cloned> a b"}
+test oo-15.10 {variable binding must not bleed through oo::copy} -setup {
+    oo::class create FooClass
+    set result {}
+} -body {
+    set obj1 [FooClass new]
+    oo::objdefine $obj1 {
+	variable var 
+	method m {} {
+	    set var foo
+	}
+	method get {} {
+	    return $var
+	}
+	export eval
+    }
+
+    $obj1 m
+    lappend result [$obj1 get]
+    set obj2 [oo::copy $obj1]
+    $obj2 eval {
+	set var bar
+    }
+    lappend result [$obj2 get]
+    $obj1 eval {
+	set var grill
+    }
+    lappend result [$obj1 get] [$obj2 get]
+} -cleanup {
+    FooClass destroy
+} -result {foo bar grill bar}
+
+test oo-16.1 {OO: object introspection} -body {
+    info object
+} -returnCodes 1 -result "wrong \# args: should be \"info object subcommand ?arg ...?\""
+test oo-16.1.1 {OO: object introspection} -body {
+    catch {info object} m o
+    dict get $o -errorinfo
+} -result "wrong \# args: should be \"info object subcommand ?arg ...?\"
+    while executing
+\"info object\""
+test oo-16.2 {OO: object introspection} -body {
+    info object class NOTANOBJECT
+} -returnCodes 1 -result {NOTANOBJECT does not refer to an object}
+test oo-16.3 {OO: object introspection} -body {
+    info object gorp oo::object
+} -returnCodes 1 -result {unknown or ambiguous subcommand "gorp": must be call, class, definition, filters, forward, isa, methods, methodtype, mixins, namespace, variables, or vars}
+test oo-16.4 {OO: object introspection} -setup {
+    oo::class create meta { superclass oo::class }
+    [meta create instance1] create instance2
+} -body {
+    list [list [info object class oo::object] \
+	      [info object class oo::class] \
+	      [info object class meta] \
+	      [info object class instance1] \
+	      [info object class instance2]] \
+	[list [info object isa class oo::object] \
+	     [info object isa class meta] \
+	     [info object isa class instance1] \
+	     [info object isa class instance2]] \
+	[list [info object isa metaclass oo::object] \
+	     [info object isa metaclass oo::class] \
+	     [info object isa metaclass meta] \
+	     [info object isa metaclass instance1] \
+	     [info object isa metaclass instance2]] \
+	[list [info object isa object oo::object] \
+	     [info object isa object oo::class] \
+	     [info object isa object meta] \
+	     [info object isa object instance1] \
+	     [info object isa object instance2] \
+	     [info object isa object oo::define] \
+	     [info object isa object NOTANOBJECT]]
+} -cleanup {
+    meta destroy
+} -result {{::oo::class ::oo::class ::oo::class ::meta ::instance1} {1 1 1 0} {0 1 1 0 0} {1 1 1 1 1 0 0}}
+test oo-16.5 {OO: object introspection} {info object methods oo::object} {}
+test oo-16.6 {OO: object introspection} {
+    oo::object create foo
+    set result [list [info object methods foo]]
+    oo::objdefine foo method bar {} {...}
+    lappend result [info object methods foo] [foo destroy]
+} {{} bar {}}
+test oo-16.7 {OO: object introspection} -setup {
+    oo::object create foo
+} -body {
+    oo::objdefine foo method bar {a {b c} args} {the body}
+    set result [info object methods foo]
+    lappend result [info object methodtype foo bar] \
+	[info object definition foo bar]
+} -cleanup {
+    foo destroy
+} -result {bar method {{a {b c} args} {the body}}}
+test oo-16.8 {OO: object introspection} {
+    oo::object create foo
+    oo::class create bar
+    oo::objdefine foo mixin bar
+    set result [list [info object mixins foo] \
+		    [info object isa mixin foo bar] \
+		    [info object isa mixin foo oo::class]]
+    foo destroy
+    bar destroy
+    return $result
+} {::bar 1 0}
+test oo-16.9 {OO: object introspection} -body {
+    oo::class create Ac
+    oo::class create Bc; oo::define Bc superclass Ac
+    oo::class create Cc; oo::define Cc superclass Bc
+    oo::class create Dc; oo::define Dc mixin Cc
+    Cc create E
+    Dc create F
+    list [info object isa    typeof E oo::class] \
+	    [info object isa typeof E Ac] \
+	    [info object isa typeof F Bc] \
+	    [info object isa typeof F Cc]
+} -cleanup {
+    catch {Ac destroy}
+} -result {0 1 1 1}
+test oo-16.10 {OO: object introspection} -setup {
+    oo::object create foo
+} -body {
+    oo::objdefine foo export eval
+    foo eval {variable c 3 a 1 b 2 ddd 4 e}
+    lsort [info object vars foo ?]
+} -cleanup {
+    foo destroy
+} -result {a b c}
+test oo-16.11 {OO: object introspection} -setup {
+    oo::class create foo
+    foo create bar
+} -body {
+    oo::define foo method spong {} {...}
+    oo::objdefine bar method boo {a {b c} args} {the body}
+    list [lsort [info object methods bar -all]] [lsort [info object methods bar -all -private]]
+} -cleanup {
+    foo destroy
+} -result {{boo destroy spong} {<cloned> boo destroy eval spong unknown variable varname}}
+test oo-16.12 {OO: object introspection} -setup {
+    oo::object create foo
+} -cleanup {
+    rename foo {}
+} -body {
+    oo::objdefine foo unexport {*}[info object methods foo -all]
+    info object methods foo -all
+} -result {}
+test oo-16.13 {OO: object introspection} -setup {
+    oo::object create foo
+} -cleanup {
+    rename foo {}
+} -body {
+    oo::objdefine foo method Bar {} {return "ok in foo"}
+    [info object namespace foo]::my Bar
+} -result "ok in foo"
+test oo-16.14 {OO: object introspection: TIP #436} -setup {
+    oo::class create meta { superclass oo::class }
+    [meta create instance1] create instance2
+} -body {
+    list class [list [info object isa class NOTANOBJECT] \
+		    [info object isa class list]] \
+	meta [list [info object isa metaclass NOTANOBJECT] \
+		  [info object isa metaclass list] \
+		  [info object isa metaclass oo::object]] \
+	type [list [info object isa typeof oo::object NOTANOBJECT] \
+		  [info object isa typeof NOTANOBJECT oo::object] \
+		  [info object isa typeof list NOTANOBJECT] \
+		  [info object isa typeof NOTANOBJECT list] \
+		  [info object isa typeof oo::object list] \
+		  [info object isa typeof list oo::object]] \
+	mix [list [info object isa mixin oo::object NOTANOBJECT] \
+		 [info object isa mixin NOTANOBJECT oo::object] \
+		 [info object isa mixin list NOTANOBJECT] \
+		 [info object isa mixin NOTANOBJECT list] \
+		 [info object isa mixin oo::object list] \
+		 [info object isa mixin list oo::object]]
+} -cleanup {
+    meta destroy
+} -result {class {0 0} meta {0 0 0} type {0 0 0 0 0 0} mix {0 0 0 0 0 0}}
+
+test oo-17.1 {OO: class introspection} -body {
+    info class
+} -returnCodes 1 -result "wrong \# args: should be \"info class subcommand ?arg ...?\""
+test oo-17.1.1 {OO: class introspection} -body {
+    catch {info class} m o
+    dict get $o -errorinfo
+} -result "wrong \# args: should be \"info class subcommand ?arg ...?\"
+    while executing
+\"info class\""
+test oo-17.2 {OO: class introspection} -body {
+    info class superclass NOTANOBJECT
+} -returnCodes 1 -result {NOTANOBJECT does not refer to an object}
+test oo-17.3 {OO: class introspection} -setup {
+    oo::object create foo
+} -body {
+    info class superclass foo
+} -returnCodes 1 -cleanup {
+    foo destroy
+} -result {"foo" is not a class}
+test oo-17.4 {OO: class introspection} -body {
+    info class gorp oo::object
+} -returnCodes 1 -result {unknown or ambiguous subcommand "gorp": must be call, constructor, definition, destructor, filters, forward, instances, methods, methodtype, mixins, subclasses, superclasses, or variables}
+test oo-17.5 {OO: class introspection} -setup {
+    oo::class create testClass
+} -body {
+    testClass create foo
+    testClass create bar
+    testClass create spong
+    lsort [info class instances testClass]
+} -cleanup {
+    testClass destroy
+} -result {::bar ::foo ::spong}
+test oo-17.6 {OO: class introspection} -setup {
+    oo::class create foo
+} -body {
+    oo::define foo method bar {a {b c} args} {the body}
+    set result [info class methods foo]
+    lappend result [info class methodtype foo bar] \
+	[info class definition foo bar]
+} -cleanup {
+    foo destroy
+} -result {bar method {{a {b c} args} {the body}}}
+test oo-17.7 {OO: class introspection} {
+    info class superclasses oo::class
+} ::oo::object
+test oo-17.8 {OO: class introspection} -setup {
+    oo::class create testClass
+    oo::class create superClass1
+    oo::class create superClass2
+} -body {
+    oo::define testClass superclass superClass1 superClass2
+    list [info class superclasses testClass] \
+	[lsort [info class subclass oo::object ::superClass?]]
+} -cleanup {
+    testClass destroy
+    superClass1 destroy
+    superClass2 destroy
+} -result {{::superClass1 ::superClass2} {::superClass1 ::superClass2}}
+test oo-17.9 {OO: class introspection} -setup {
+    oo::class create foo
+    oo::class create subfoo {superclass foo}
+} -body {
+    oo::define foo {
+	method bar {a {b c} args} {the body}
+	self {
+	    method bad {} {...}
+	}
+    }
+    oo::define subfoo method boo {a {b c} args} {the body}
+    list [lsort [info class methods subfoo -all]] \
+	[lsort [info class methods subfoo -all -private]]
+} -cleanup {
+    foo destroy
+} -result {{bar boo destroy} {<cloned> bar boo destroy eval unknown variable varname}}
+test oo-17.10 {OO: class introspection} -setup {
+    oo::class create foo
+} -cleanup {
+    rename foo {}
+} -body {
+    oo::define foo unexport {*}[info class methods foo -all]
+    info class methods foo -all
+} -result {}
+
+test oo-18.1 {OO: define command support} {
+    list [catch {oo::define oo::object {error foo}} msg] $msg $errorInfo
+} {1 foo {foo
+    while executing
+"error foo"
+    (in definition script for class "::oo::object" line 1)
+    invoked from within
+"oo::define oo::object {error foo}"}}
+test oo-18.2 {OO: define command support} {
+    list [catch {oo::define oo::object error foo} msg] $msg $errorInfo
+} {1 foo {foo
+    while executing
+"oo::define oo::object error foo"}}
+test oo-18.3 {OO: define command support} {
+    list [catch {oo::class create foo {error bar}} msg] $msg $errorInfo
+} {1 bar {bar
+    while executing
+"error bar"
+    (in definition script for class "::foo" line 1)
+    invoked from within
+"oo::class create foo {error bar}"}}
+test oo-18.3a {OO: define command support} {
+    list [catch {oo::class create foo {
+    error bar
+}} msg] $msg $errorInfo
+} {1 bar {bar
+    while executing
+"error bar"
+    (in definition script for class "::foo" line 2)
+    invoked from within
+"oo::class create foo {
+    error bar
+}"}}
+test oo-18.3b {OO: define command support} {
+    list [catch {oo::class create foo {
+    eval eval error bar
+}} msg] $msg $errorInfo
+} {1 bar {bar
+    while executing
+"error bar"
+    ("eval" body line 1)
+    invoked from within
+"eval error bar"
+    ("eval" body line 1)
+    invoked from within
+"eval eval error bar"
+    (in definition script for class "::foo" line 2)
+    invoked from within
+"oo::class create foo {
+    eval eval error bar
+}"}}
+test oo-18.4 {OO: more error traces from the guts} -setup {
+    oo::object create obj
+} -body {
+    oo::objdefine obj method bar {} {my eval {error foo}}
+    list [catch {obj bar} msg] $msg $errorInfo
+} -cleanup {
+    obj destroy
+} -result {1 foo {foo
+    while executing
+"error foo"
+    (in "my eval" script line 1)
+    invoked from within
+"my eval {error foo}"
+    (object "::obj" method "bar" line 1)
+    invoked from within
+"obj bar"}}
+test oo-18.5 {OO: more error traces from the guts} -setup {
+    [oo::class create cls] create obj
+    set errorInfo {}
+} -body {
+    oo::define cls {
+	method eval script {next $script}
+	export eval
+    }
+    oo::objdefine obj method bar {} {my eval {error foo}}
+    set result {}
+    lappend result [catch {obj bar} msg] $msg $errorInfo
+    lappend result [catch {obj eval {error bar}} msg] $msg $errorInfo
+} -cleanup {
+    cls destroy
+} -result {1 foo {foo
+    while executing
+"error foo"
+    (in "my eval" script line 1)
+    invoked from within
+"next $script"
+    (class "::cls" method "eval" line 1)
+    invoked from within
+"my eval {error foo}"
+    (object "::obj" method "bar" line 1)
+    invoked from within
+"obj bar"} 1 bar {bar
+    while executing
+"error bar"
+    (in "::obj eval" script line 1)
+    invoked from within
+"next $script"
+    (class "::cls" method "eval" line 1)
+    invoked from within
+"obj eval {error bar}"}}
+test oo-18.6 {class construction reference management and errors} -setup {
+    oo::class create super_abc
+} -body {
+    catch {
+oo::class create abc {
+    superclass super_abc
+    ::rename abc ::def
+    ::error foo
+}
+    } msg opt
+    dict get $opt -errorinfo
+} -cleanup {
+    super_abc destroy
+} -result {foo
+    while executing
+"::error foo"
+    (in definition script for class "::def" line 4)
+    invoked from within
+"oo::class create abc {
+    superclass super_abc
+    ::rename abc ::def
+    ::error foo
+}"}
+test oo-18.7 {OO: objdefine command support} -setup {
+    oo::object create ::inst
+} -body {
+    list [catch {oo::objdefine inst {rename ::inst ::INST;error foo}} msg] $msg $errorInfo
+} -cleanup {
+    catch {::inst destroy}
+    catch {::INST destroy}
+} -result {1 foo {foo
+    while executing
+"error foo"
+    (in definition script for object "::INST" line 1)
+    invoked from within
+"oo::objdefine inst {rename ::inst ::INST;error foo}"}}
+test oo-18.8 {OO: define/self command support} -setup {
+    oo::class create master
+    oo::class create ::foo {superclass master}
+} -body {
+    catch {oo::define foo {rename ::foo ::bar; self {error foobar}}} msg opt
+    dict get $opt -errorinfo
+} -cleanup {
+    master destroy
+} -result {foobar
+    while executing
+"error foobar"
+    (in definition script for class object "::bar" line 1)
+    invoked from within
+"self {error foobar}"
+    (in definition script for class "::bar" line 1)
+    invoked from within
+"oo::define foo {rename ::foo ::bar; self {error foobar}}"}
+test oo-18.9 {OO: define/self command support} -setup {
+    oo::class create master
+    set c [oo::class create now_this_is_a_very_very_long_class_name_indeed {
+        superclass master
+    }]
+} -body {
+    catch {oo::define $c {error err}} msg opt
+    dict get $opt -errorinfo
+} -cleanup {
+    master destroy
+} -result {err
+    while executing
+"error err"
+    (in definition script for class "::now_this_is_a_very_very_long..." line 1)
+    invoked from within
+"oo::define $c {error err}"}
+test oo-18.10 {OO: define/self command support} -setup {
+    oo::class create master
+    oo::class create ::foo {superclass master}
+} -body {
+    catch {oo::define foo {self {rename ::foo {}; error foobar}}} msg opt
+    dict get $opt -errorinfo
+} -cleanup {
+    master destroy
+} -result {foobar
+    while executing
+"error foobar"
+    (in definition script for class object "::foo" line 1)
+    invoked from within
+"self {rename ::foo {}; error foobar}"
+    (in definition script for class "::foo" line 1)
+    invoked from within
+"oo::define foo {self {rename ::foo {}; error foobar}}"}
+test oo-18.11 {OO: define/self command support} -setup {
+    oo::class create master
+    oo::class create ::foo {superclass master}
+} -body {
+    catch {oo::define foo {rename ::foo {}; self {error foobar}}} msg opt
+    dict get $opt -errorinfo
+} -cleanup {
+    master destroy
+} -result {this command cannot be called when the object has been deleted
+    while executing
+"self {error foobar}"
+    (in definition script for class "::foo" line 1)
+    invoked from within
+"oo::define foo {rename ::foo {}; self {error foobar}}"}
+
+test oo-19.1 {OO: varname method} -setup {
+    oo::object create inst
+    oo::objdefine inst export eval
+    set result {}
+    inst eval { variable x }
+} -body {
+    inst eval {trace add variable x write foo}
+    set ns [inst eval namespace current]
+    proc foo args {
+	global ns result
+	set context [uplevel 1 namespace current]
+	lappend result $args [expr {
+	    $ns eq $context ? "ok" : [list $ns ne $context]
+	}] [expr {
+	    "${ns}::x" eq [uplevel 1 my varname x] ? "ok" : [list ${ns}::x ne [uplevel 1 my varname x]]
+	}]
+    }
+    lappend result [inst eval set x 0]
+} -cleanup {
+    inst destroy
+    rename foo {}
+} -result {{x {} write} ok ok 0}
+test oo-19.2 {OO: varname method: Bug 2883857} -setup {
+    oo::class create SpecialClass
+    oo::objdefine SpecialClass export createWithNamespace
+    SpecialClass createWithNamespace inst ::oo_test
+    oo::objdefine inst export varname eval
+} -body {
+    inst eval { variable x; array set x {y z} }
+    inst varname x(y)
+} -cleanup {
+    SpecialClass destroy
+} -result ::oo_test::x(y)
+test oo-19.3 {OO: varname method and variable decl: Bug 3603695} -setup {
+    oo::class create testClass {
+	variable foo
+	export varname
+	constructor {} {
+	    variable foo x
+	}
+	method bar {obj} {
+	    my varname foo
+	    $obj varname foo
+	}
+    }
+} -body {
+    testClass create A
+    testClass create B
+    lsearch [list [A varname foo] [B varname foo]] [B bar A]
+} -cleanup {
+    testClass destroy
+} -result 0
+
+test oo-20.1 {OO: variable method} -body {
+    oo::class create testClass {
+	constructor {} {
+	    my variable ok
+	    set ok {}
+	}
+    }
+    lsort [info object vars [testClass new]]
+} -cleanup {
+    catch {testClass destroy}
+} -result ok
+test oo-20.2 {OO: variable method} -body {
+    oo::class create testClass {
+	constructor {} {
+	    my variable a b c
+	    set a [set b [set c {}]]
+	}
+    }
+    lsort [info object vars [testClass new]]
+} -cleanup {
+    catch {testClass destroy}
+} -result {a b c}
+test oo-20.3 {OO: variable method} -body {
+    oo::class create testClass {
+	export varname
+	method bar {} {
+	    my variable a(b)
+	}
+    }
+    testClass create foo
+    array set [foo varname a] {b c}
+    foo bar
+} -returnCodes 1 -cleanup {
+    catch {testClass destroy}
+} -result {can't define "a(b)": name refers to an element in an array}
+test oo-20.4 {OO: variable method} -body {
+    oo::class create testClass {
+	export varname
+	method bar {} {
+	    my variable a(b)
+	}
+    }
+    testClass create foo
+    set [foo varname a] b
+    foo bar
+} -returnCodes 1 -cleanup {
+    catch {testClass destroy}
+} -result {can't define "a(b)": name refers to an element in an array}
+test oo-20.5 {OO: variable method} -body {
+    oo::class create testClass {
+	method bar {} {
+	    my variable a::b
+	}
+    }
+    testClass create foo
+    foo bar
+} -returnCodes 1 -cleanup {
+    catch {testClass destroy}
+} -result {variable name "a::b" illegal: must not contain namespace separator}
+test oo-20.6 {OO: variable method} -setup {
+    oo::class create testClass {
+	export varname
+	self export eval
+    }
+} -body {
+    testClass eval variable a 0
+    oo::objdefine [testClass create foo] method bar {other} {
+	$other variable a
+	set a 3
+    }
+    oo::objdefine [testClass create boo] export variable
+    set [foo varname a] 1
+    set [boo varname a] 2
+    foo bar boo
+    list [testClass eval set a] [set [foo varname a]] [set [boo varname a]]
+} -cleanup {
+    testClass destroy
+} -result {0 1 3}
+test oo-20.7 {OO: variable method} -setup {
+    oo::class create cls
+} -body {
+    oo::define cls {
+	method a {} {
+	    my variable d b
+	    lappend b $d
+	}
+	method e {} {
+	    my variable b d
+	    return [list $b $d]
+	}
+	method f {x y} {
+	    my variable b d
+	    set b $x
+	    set d $y
+	}
+    }
+    cls create obj
+    obj f p q
+    obj a
+    obj a
+    obj e
+} -cleanup {
+    cls destroy
+} -result {{p q q} q}
+# oo-20.8 tested explicitly for functionality removed due to [Bug 1959457]
+test oo-20.9 {OO: variable method} -setup {
+    oo::object create obj
+} -body {
+    oo::objdefine obj {
+	method a {} {
+	    my variable ::b
+	}
+    }
+    obj a
+} -returnCodes 1 -cleanup {
+    obj destroy
+} -result {variable name "::b" illegal: must not contain namespace separator}
+test oo-20.10 {OO: variable and varname methods refer to same things} -setup {
+    oo::object create obj
+} -body {
+    oo::objdefine obj {
+	method a {} {
+	    my variable b
+	    set b [self]
+	    return [my varname b]
+	}
+    }
+    list [set [obj a]] [namespace tail [obj a]]
+} -cleanup {
+    obj destroy
+} -result {::obj b}
+test oo-20.11 {OO: variable mustn't crash when recursing} -body {
+    oo::class create A {
+	constructor {name} {
+	    my variable np_name 
+	    set np_name $name
+	}
+	method copy {nm} {
+	    set cpy [[info object class [self]] new $nm]
+	    foreach var [info object vars [self]] {
+		my variable $var
+		set val [set $var]
+		if {[string match o_* $var]} {
+		    set objs {}
+		    foreach ref $val {
+			# call to "copy" crashes
+			lappend objs [$ref copy {}]
+		    }
+		    $cpy prop $var $objs
+		} else { 
+		    $cpy prop $var $val
+		}
+	    }
+	    return $cpy
+	}
+	method prop {name val} {
+	    my variable $name
+	    set $name $val
+	}
+    }
+    set o1 [A new {}]
+    set o2 [A new {}]
+    $o1 prop o_object $o2
+    $o1 copy aa
+} -cleanup {
+    catch {A destroy}
+} -match glob -result *
+test oo-20.12 {OO: variable method accept zero args (TIP 323)} -setup {
+    oo::object create foo
+} -cleanup {
+    foo destroy
+} -body {
+    oo::objdefine foo method demo {} {
+	my variable
+    }
+    foo demo
+} -result {}
+test oo-20.13 {OO: variable method use in non-methods [Bug 2903811]} -setup {
+    oo::object create fooObj
+    oo::objdefine fooObj export variable
+} -cleanup {
+    fooObj destroy
+} -body {
+    apply {{} {fooObj variable x; set x ok; return}}
+    apply {{} {fooObj variable x; return $x}}
+} -result ok
+test oo-20.14 {OO: variable method use in non-methods [Bug 2903811]} -setup {
+    oo::object create fooObj
+    oo::objdefine fooObj export variable
+    namespace eval ns1 {}
+    namespace eval ns2 {}
+    set x bad
+} -cleanup {
+    fooObj destroy
+    namespace delete ns1 ns2
+    unset x
+} -body {
+    namespace eval ns1 {fooObj variable x; set x ok; subst ""}
+    set x bad
+    namespace eval ns2 {fooObj variable x; return $x}
+} -result ok
+test oo-20.15 {OO: variable method use in non-methods [Bug 2903811]} -setup {
+    oo::object create fooObj
+    oo::objdefine fooObj export variable varname
+} -cleanup {
+    fooObj destroy
+} -body {
+    apply {{} {fooObj variable x; set x ok; return}}
+    return [set [fooObj varname x]]
+} -result ok
+test oo-20.16 {variable method: leak per instance} -setup {
+    oo::class create foo
+} -constraints memory -body {
+    oo::define foo {
+	constructor {} {
+	    set [my variable v] 0
+	}
+    }
+    leaktest {[foo new] destroy}
+} -cleanup {
+    foo destroy
+} -result 0
+
+test oo-21.1 {OO: inheritance ordering} -setup {
+    oo::class create A
+} -body {
+    oo::define A method m {} {lappend ::result A}
+    oo::class create B {
+	superclass A
+	method m {} {lappend ::result B;next}
+    }
+    oo::class create C {
+	superclass A
+	method m {} {lappend ::result C;next}
+    }
+    oo::class create D {
+	superclass B C
+	method m {} {lappend ::result D;next}
+    }
+    D create o
+    oo::objdefine o method m {} {lappend ::result o;next}
+    set result {}
+    o m
+    return $result
+} -cleanup {
+    A destroy
+} -result {o D B C A}
+test oo-21.2 {OO: inheritance ordering} -setup {
+    oo::class create A
+} -body {
+    oo::define A method m {} {lappend ::result A}
+    oo::class create B {
+	superclass A
+	method m {} {lappend ::result B;next}
+    }
+    oo::class create C {
+	superclass A
+	method m {} {lappend ::result C;next}
+    }
+    oo::class create D {
+	superclass B C
+	method m {} {lappend ::result D;next}
+    }
+    oo::class create Emix {
+	superclass C
+	method m {} {lappend ::result Emix;next}
+    }
+    oo::class create Fmix {
+	superclass Emix
+	method m {} {lappend ::result Fmix;next}
+    }
+    D create o
+    oo::objdefine o {
+	method m {} {lappend ::result o;next}
+	mixin Fmix
+    }
+    set result {}
+    o m
+    return $result
+} -cleanup {
+    A destroy
+} -result {Fmix Emix o D B C A}
+test oo-21.3 {OO: inheritance ordering} -setup {
+    oo::class create A
+} -body {
+    oo::define A method m {} {lappend ::result A}
+    oo::class create B {
+	superclass A
+	method m {} {lappend ::result B;next}
+	method f {} {lappend ::result B-filt;next}
+    }
+    oo::class create C {
+	superclass A
+	method m {} {lappend ::result C;next}
+    }
+    oo::class create D {
+	superclass B C
+	method m {} {lappend ::result D;next}
+    }
+    oo::class create Emix {
+	superclass C
+	method m {} {lappend ::result Emix;next}
+	method f {} {lappend ::result Emix-filt;next}
+    }
+    oo::class create Fmix {
+	superclass Emix
+	method m {} {lappend ::result Fmix;next}
+    }
+    D create o
+    oo::objdefine o {
+	method m {} {lappend ::result o;next}
+	mixin Fmix
+	filter f
+    }
+    set result {}
+    o m
+    return $result
+} -cleanup {
+    A destroy
+} -result {Emix-filt B-filt Fmix Emix o D B C A}
+test oo-21.4 {OO: inheritance ordering} -setup {
+    oo::class create A
+} -body {
+    oo::define A method m {} {lappend ::result A}
+    oo::class create B {
+	superclass A
+	method m {} {lappend ::result B;next}
+	method f {} {lappend ::result B-filt;next}
+	method g {} {lappend ::result B-cfilt;next}
+    }
+    oo::class create C {
+	superclass A
+	method m {} {lappend ::result C;next}
+    }
+    oo::class create D {
+	superclass B C
+	method m {} {lappend ::result D;next}
+	method g {} {lappend ::result D-cfilt;next}
+	filter g
+    }
+    oo::class create Emix {
+	superclass C
+	method m {} {lappend ::result Emix;next}
+	method f {} {lappend ::result Emix-filt;next}
+    }
+    oo::class create Fmix {
+	superclass Emix
+	method m {} {lappend ::result Fmix;next}
+    }
+    D create o
+    oo::objdefine o {
+	method m {} {lappend ::result o;next}
+	mixin Fmix
+	filter f
+    }
+    set result {}
+    o m
+    return $result
+} -cleanup {
+    A destroy
+} -result {Emix-filt B-filt D-cfilt B-cfilt Fmix Emix o D B C A}
+
+test oo-22.1 {OO and info frame} -setup {
+    oo::class create c
+    c create i
+} -match glob -body {
+    oo::define c self method frame {} {
+	info frame 0
+    }
+    oo::define c {
+	method frames {} {
+	    info frame 0
+	}
+	method level {} {
+	    info frame
+	}
+    }
+    oo::objdefine i {
+	method frames {} {
+	    list [next] [info frame 0]
+	}
+	method level {} {
+	    expr {[next] - [info frame]}
+	}
+    }
+    list [i level] [i frames] [dict get [c frame] object]
+} -cleanup {
+    c destroy
+} -result {1 {{* cmd {info frame 0} method frames class ::c level 0} {* cmd {info frame 0} method frames object ::i level 0}} ::c}
+test oo-22.2 {OO and info frame: Bug 3001438} -setup {
+    oo::class create c
+} -body {
+    oo::define c method test {{x 1}} {
+	if {$x} {my test 0}
+	lsort {q w e r t y u i o p}; # Overwrite the Tcl stack
+	info frame 0
+    }
+    [c new] test
+} -match glob -cleanup {
+    c destroy
+} -result {* cmd {info frame 0} method test class ::c level 0}
+
+# Prove that the issue in [Bug 1865054] isn't an issue any more
+test oo-23.1 {Self-like derivation; complex case!} -setup {
+    oo::class create SELF {
+	superclass oo::class
+	unexport create new
+	# Next is just a convenience
+	method method args {oo::define [self] method {*}$args}
+	method derive {name} {
+	    set o [my new [list superclass [self]]]
+	    oo::objdefine $o mixin $o
+	    uplevel 1 [list rename $o $name]\;[list namespace which $name]
+	}
+	self mixin SELF
+    }
+    set result {}
+} -body {
+    [SELF derive foo1] method bar1 {} {return 1}
+    lappend result [foo1 bar1]
+    [foo1 derive foo2] method bar2 {} {return [my bar1],2}
+    lappend result [foo2 bar2]
+    [foo2 derive foo3] method bar3 {} {return [my bar2],3}
+    lappend result [foo3 bar3]
+    [foo3 derive foo4] method bar4 {} {return [my bar3],4}
+    lappend result [foo4 bar4]
+    foo2 method bar2 {} {return [my bar1],x}
+    lappend result [foo4 bar4]
+} -cleanup {
+    SELF destroy
+} -result {1 1,2 1,2,3 1,2,3,4 1,x,3,4}
+
+test oo-24.1 {unknown method method - Bug 1965063} -setup {
+    oo::class create cls
+} -cleanup {
+    cls destroy
+} -returnCodes error -body {
+    oo::define cls {
+	method dummy {} {}
+	method unknown args {next {*}$args}
+    }
+    [cls new] foo bar
+} -result {unknown method "foo": must be destroy, dummy or unknown}
+test oo-24.2 {unknown method method - Bug 1965063} -setup {
+    oo::class create cls
+} -cleanup {
+    cls destroy
+} -returnCodes error -body {
+    oo::define cls {
+	method dummy {} {}
+	method unknown args {next {*}$args}
+    }
+    cls create obj
+    oo::objdefine obj {
+	method dummy2 {} {}
+	method unknown args {next {*}$args}
+    }
+    obj foo bar
+} -result {unknown method "foo": must be destroy, dummy, dummy2 or unknown}
+test oo-24.3 {unknown method method - absent method name} -setup {
+    set o [oo::object new]
+} -cleanup {
+    $o destroy
+} -body {
+    oo::objdefine $o method unknown args {
+	return "unknown: >>$args<<"
+    }
+    list [$o] [$o foobar] [$o foo bar]
+} -result {{unknown: >><<} {unknown: >>foobar<<} {unknown: >>foo bar<<}}
+
+# Probably need a better set of tests, but this is quite difficult to devise
+test oo-25.1 {call chain caching} -setup {
+    oo::class create cls {
+	method ab {} {return ok}
+    }
+    set result {}
+} -cleanup {
+    cls destroy
+} -body {
+    cls create foo
+    cls create bar
+    set m1 ab
+    set m2 a; append m2 b ;# different object!
+    lappend result [foo $m1] [foo $m1] [bar $m1] [foo $m1]
+    lappend result [foo $m2] [bar $m2]
+    oo::objdefine foo method ab {} {return good}
+    lappend result [foo $m1] [bar $m2]
+} -result {ok ok ok ok ok ok good ok}
+test oo-25.2 {call chain caching - Bug #2120903} -setup {
+    set c [oo::class create MyClass]
+    set o [$c new]
+} -body {
+    oo::define MyClass {
+	method name {} {return ok}
+	method isa o {MyClass name $o}
+	self method name o {$o name}
+    }
+    list [$o name] [$c name $o] [$o isa $o]
+} -cleanup {
+    $c destroy
+} -result {ok ok ok}
+
+test oo-26.1 {Bug 2037727} -setup {
+    proc succeed args {}
+    oo::object create example
+} -body {
+    oo::objdefine example method foo {} {succeed}
+    example foo
+    proc succeed {} {return succeed}
+    example foo
+} -cleanup {
+    example destroy
+    rename succeed {}
+} -result succeed
+test oo-26.2 {Bug 2037727} -setup {
+    oo::class create example {
+	method localProc {args body} {proc called $args $body}
+	method run {} { called }
+    }
+    example create i1
+    example create i2
+} -body {
+    i1 localProc args {}
+    i2 localProc args {return nonempty}
+    list [i1 run] [i2 run]
+} -cleanup {
+    example destroy
+} -result {{} nonempty}
+test oo-26.3 {Bug 2037727} -setup {
+    oo::class create example {
+	method subProc {args body} {
+	    namespace eval subns [list proc called $args $body]
+	}
+	method run {} { subns::called }
+    }
+    example create i1
+    example create i2
+} -body {
+    i1 subProc args {}
+    i2 subProc args {return nonempty}
+    list [i1 run] [i2 run]
+} -cleanup {
+    example destroy
+} -result {{} nonempty}
+
+test oo-27.1 {variables declaration - class introspection} -setup {
+    oo::class create foo
+} -cleanup {
+    foo destroy
+} -body {
+    oo::define foo variable a b c
+    info class variables foo
+} -result {a b c}
+test oo-27.2 {variables declaration - object introspection} -setup {
+    oo::object create foo
+} -cleanup {
+    foo destroy
+} -body {
+    oo::objdefine foo variable a b c
+    info object variables foo
+} -result {a b c}
+test oo-27.3 {variables declaration - basic behaviour} -setup {
+    oo::class create master
+} -cleanup {
+    master destroy
+} -body {
+    oo::class create foo {
+	superclass master
+	variable x!
+	constructor {} {set x! 1}
+	method y {} {incr x!}
+    }
+    foo create bar
+    bar y
+    bar y
+} -result 3
+test oo-27.4 {variables declaration - destructors too} -setup {
+    oo::class create master
+    set result bad!
+} -cleanup {
+    master destroy
+} -body {
+    oo::class create foo {
+	superclass master
+	variable x!
+	constructor {} {set x! 1}
+	method y {} {incr x!}
+	destructor {set ::result ${x!}}
+    }
+    foo create bar
+    bar y
+    bar y
+    bar destroy
+    return $result
+} -result 3
+test oo-27.5 {variables declaration - object-bound variables} -setup {
+    oo::object create foo
+} -cleanup {
+    foo destroy
+} -body {
+    oo::objdefine foo {
+	variable x!
+	method y {} {incr x!}
+    }
+    foo y
+    foo y
+} -result 2
+test oo-27.6 {variables declaration - non-interference of levels} -setup {
+    oo::class create master
+} -cleanup {
+    master destroy
+} -body {
+    oo::class create foo {
+	superclass master
+	variable x!
+	constructor {} {set x! 1}
+	method y {} {incr x!}
+    }
+    foo create bar
+    oo::objdefine bar {
+	variable y!
+	method y {} {list [next] [incr y!] [info var] [info local]}
+	export eval
+    }
+    bar y
+    list [bar y] [lsort [info object vars bar]] [bar eval {info vars *!}]
+} -result {{3 2 y! {}} {x! y!} {x! y!}}
+test oo-27.7 {variables declaration - one underlying variable space} -setup {
+    oo::class create master
+} -cleanup {
+    master destroy
+} -body {
+    oo::class create foo {
+	superclass master
+	variable x!
+	constructor {} {set x! 1}
+	method y {} {incr x!}
+    }
+    oo::class create foo2 {
+	superclass foo
+	variable y!
+	constructor {} {set y! 42; next}
+	method x {} {incr y! -1}
+    }
+    foo2 create bar
+    oo::objdefine bar {
+	variable x! y!
+	method z {} {list ${x!} ${y!}}
+    }
+    bar y
+    bar x
+    list [bar y] [bar x] [bar z]
+} -result {3 40 {3 40}}
+test oo-27.8 {variables declaration - error cases - ns separators} -body {
+    oo::define oo::object variable bad::var
+} -returnCodes error -result {invalid declared variable name "bad::var": must not contain namespace separators}
+test oo-27.9 {variables declaration - error cases - arrays} -body {
+    oo::define oo::object variable bad(var)
+} -returnCodes error -result {invalid declared variable name "bad(var)": must not refer to an array element}
+test oo-27.10 {variables declaration - no instance var leaks with class resolvers} -setup {
+    oo::class create master
+} -cleanup {
+    master destroy
+} -body {
+    oo::class create foo {
+	superclass master
+	variable clsvar
+	constructor {} {
+	    set clsvar 0
+	}
+	method step {} {
+	    incr clsvar
+	    return
+	}
+	method value {} {
+	    return $clsvar
+	}
+    }
+    foo create inst1
+    inst1 step
+    foo create inst2
+    inst2 step
+    inst1 step
+    inst2 step
+    inst1 step
+    list [inst1 value] [inst2 value]
+} -result {3 2}
+test oo-27.11 {variables declaration - no instance var leaks with class resolvers} -setup {
+    oo::class create master
+} -cleanup {
+    master destroy
+} -body {
+    oo::class create foo {
+	superclass master
+	variable clsvar
+	constructor {} {
+	    set clsvar 0
+	}
+	method step {} {
+	    incr clsvar
+	    return
+	}
+	method value {} {
+	    return $clsvar
+	}
+    }
+    foo create inst1
+    oo::objdefine inst1 {
+	variable clsvar
+	method reinit {} {
+	    set clsvar 0
+	}
+    }
+    foo create inst2
+    oo::objdefine inst2 {
+	variable clsvar
+	method reinit {} {
+	    set clsvar 0
+	}
+    }
+    inst1 step
+    inst2 step
+    inst1 reinit
+    inst2 reinit
+    inst1 step
+    inst2 step
+    inst1 step
+    inst2 step
+    inst1 step
+    list [inst1 value] [inst2 value]
+} -result {3 2}
+test oo-27.12 {variables declaration: leak per instance} -setup {
+    oo::class create foo
+} -constraints memory -body {
+    oo::define foo {
+	variable v
+	constructor {} {
+	    set v 0
+	}
+    }
+    leaktest {[foo new] destroy}
+} -cleanup {
+    foo destroy
+} -result 0
+# This test will actually (normally) crash if it fails!
+test oo-27.13 {variables declaration: Bug 3185009: require refcount management} -setup {
+    oo::object create foo
+} -body {
+    oo::objdefine foo {
+	variable x
+	method set v {set x $v}
+	method unset {} {unset x}
+	method exists {} {info exists x}
+	method get {} {return $x}
+    }
+    list [foo exists] [foo set 7] [foo exists] [foo get] [foo unset] \
+	[foo exists] [catch {foo get} msg] $msg
+} -cleanup {
+    foo destroy
+} -result {0 7 1 7 {} 0 1 {can't read "x": no such variable}}
+test oo-27.14 {variables declaration - multiple use} -setup {
+    oo::class create master
+} -cleanup {
+    master destroy
+} -body {
+    oo::class create foo {
+	superclass master
+	variable x
+	variable y
+	method boo {} {
+	    return [incr x],[incr y]
+	}
+    }
+    foo create bar
+    list [bar boo] [bar boo]
+} -result {1,1 2,2}
+test oo-27.15 {variables declaration - multiple use} -setup {
+    oo::class create master
+} -cleanup {
+    master destroy
+} -body {
+    oo::class create foo {
+	superclass master
+	variable
+	variable x y
+	method boo {} {
+	    return [incr x],[incr y]
+	}
+    }
+    foo create bar
+    list [bar boo] [bar boo]
+} -result {1,1 2,2}
+test oo-27.16 {variables declaration - multiple use} -setup {
+    oo::class create master
+} -cleanup {
+    master destroy
+} -body {
+    oo::class create foo {
+	superclass master
+	variable x
+	variable -clear
+	variable y
+	method boo {} {
+	    return [incr x],[incr y]
+	}
+    }
+    foo create bar
+    list [bar boo] [bar boo]
+} -result {1,1 1,2}
+test oo-27.17 {variables declaration - multiple use} -setup {
+    oo::class create master
+} -cleanup {
+    master destroy
+} -body {
+    oo::class create foo {
+	superclass master
+	variable x
+	variable -set y
+	method boo {} {
+	    return [incr x],[incr y]
+	}
+    }
+    foo create bar
+    list [bar boo] [bar boo]
+} -result {1,1 1,2}
+test oo-27.18 {variables declaration - multiple use} -setup {
+    oo::class create master
+} -cleanup {
+    master destroy
+} -body {
+    oo::class create foo {
+	superclass master
+	variable x
+	variable -? y
+	method boo {} {
+	    return [incr x],[incr y]
+	}
+    }
+    foo create bar
+    list [bar boo] [bar boo]
+} -returnCodes error -match glob -result {unknown method "-?": must be *}
+test oo-27.19 {variables declaration and [info vars]: Bug 2712377} -setup {
+    oo::class create Foo
+    set result {}
+} -body {
+    # This is really a test of problems to do with Tcl's introspection when a
+    # variable resolver is present...
+    oo::define Foo {
+	variable foo bar
+	method setvars {f b} {
+	    set foo $f
+	    set bar $b
+	}
+	method dump1 {} {
+	    lappend ::result <1>
+	    foreach v [lsort [info vars *]] {
+		lappend ::result $v=[set $v]
+	    }
+	    lappend ::result [info locals] [info locals *]
+	}
+	method dump2 {} {
+	    lappend ::result <2>
+	    foreach v [lsort [info vars *]] {
+		lappend ::result $v=[set $v]
+	    }
+	    lappend ::result | foo=$foo [info locals] [info locals *]
+	}
+    }
+    Foo create stuff
+    stuff setvars what ever
+    stuff dump1
+    stuff dump2
+    return $result
+} -cleanup {
+    Foo destroy
+} -result {<1> bar=ever foo=what v v <2> bar=ever foo=what | foo=what v v}
+test oo-27.20 {variables declaration and [info vars]: Bug 2712377} -setup {
+    oo::class create Foo
+    set result {}
+} -body {
+    # This is really a test of problems to do with Tcl's introspection when a
+    # variable resolver is present...
+    oo::define Foo {
+	variable foo bar
+	method setvars {f b} {
+	    set foo $f
+	    set bar $b
+	}
+	method dump1 {} {
+	    lappend ::result <1>
+	    foreach v [lsort [info vars *o]] {
+		lappend ::result $v=[set $v]
+	    }
+	    lappend ::result [info locals] [info locals *]
+	}
+	method dump2 {} {
+	    lappend ::result <2>
+	    foreach v [lsort [info vars *o]] {
+		lappend ::result $v=[set $v]
+	    }
+	    lappend ::result | foo=$foo [info locals] [info locals *]
+	}
+    }
+    Foo create stuff
+    stuff setvars what ever
+    stuff dump1
+    stuff dump2
+    return $result
+} -cleanup {
+    Foo destroy
+} -result {<1> foo=what v v <2> foo=what | foo=what v v}
+test oo-27.21 {variables declaration uniqueifies: Bug 3396896} -setup {
+    oo::class create Foo
+} -body {
+    oo::define Foo variable v v v t t v t
+    info class variable Foo
+} -cleanup {
+    Foo destroy
+} -result {v t}
+test oo-27.22 {variables declaration uniqueifies: Bug 3396896} -setup {
+    oo::object create foo
+} -body {
+    oo::objdefine foo variable v v v t t v t
+    info object variable foo
+} -cleanup {
+    foo destroy
+} -result {v t}
+test oo-27.23 {variable resolver leakage: Bug 1493a43044} -setup {
+    oo::class create Super
+    oo::class create Master {
+	superclass Super
+	variable member1 member2
+	constructor {} {
+	    set member1 master1
+	    set member2 master2
+	}
+	method getChild {} {
+	    Child new [self]
+	}
+    }
+    oo::class create Child {
+	superclass Super
+	variable member1 result
+	constructor {m} {
+	    set [namespace current]::member1 child1
+	    set ns [info object namespace $m]
+	    namespace upvar $ns member1 l1 member2 l2
+	    upvar 1 member1 l3 member2 l4
+	    [format namespace] upvar $ns member1 l5 member2 l6
+	    [format upvar] 1 member1 l7 member2 l8
+	    set result [list $l1 $l2 $l3 $l4 $l5 $l6 $l7 $l8]
+	}
+	method result {} {return $result}
+    }
+} -body {
+    [[Master new] getChild] result
+} -cleanup {
+    Super destroy
+} -result {master1 master2 master1 master2 master1 master2 master1 master2}
+
+# A feature that's not supported because the mechanism may change without
+# warning, but is supposed to work...
+test oo-28.1 {scripted extensions to oo::define} -setup {
+    interp create foo
+    foo eval {oo::class create cls {export eval}}
+} -cleanup {
+    interp delete foo
+} -body {
+    foo eval {
+	proc oo::define::privateMethod {name arguments body} {
+	    uplevel 1 [list method $name $arguments $body]
+	    uplevel 1 [list unexport $name]
+	}
+	oo::define cls privateMethod m {x y} {return $x,$y}
+	cls create obj
+	list [catch {obj m 1 2}] [obj eval my m 3 4]
+    }
+} -result {1 3,4}
+
+test oo-29.1 {self class with object-defined methods} -setup {
+    oo::object create obj
+} -body {
+    oo::objdefine obj method demo {} {
+	self class
+    }
+    obj demo
+} -returnCodes error -cleanup {
+    obj destroy
+} -result {method not defined by a class}
+
+test oo-30.1 {Bug 2903011: deleting an object in a constructor} -setup {
+    oo::class create cls
+} -body {
+    oo::define cls {constructor {} {[self] destroy}}
+    cls new
+} -returnCodes error -cleanup {
+    cls destroy
+} -result {object deleted in constructor}
+test oo-30.2 {Bug 2903011: deleting an object in a constructor} -setup {
+    oo::class create cls
+} -body {
+    oo::define cls {constructor {} {my destroy}}
+    cls new
+} -returnCodes error -cleanup {
+    cls destroy
+} -result {object deleted in constructor}
+
+test oo-31.1 {Bug 3111059: when objects and coroutines entangle} -setup {
+    oo::class create cls
+} -constraints memory -body {
+    oo::define cls {
+	method justyield {} {
+	    yield
+	}
+	constructor {} {
+	    coroutine coro my justyield
+	}
+    }
+    list [leaktest {[cls new] destroy}] [info class instances cls]
+} -cleanup {
+    cls destroy
+} -result {0 {}}
+test oo-31.2 {Bug 3111059: when objects and coroutines entangle} -setup {
+    oo::class create cls
+} -constraints memory -body {
+    oo::define cls {
+	method justyield {} {
+	    yield
+	}
+	constructor {} {
+	    coroutine coro my justyield
+	}
+	destructor {
+	    rename coro {}
+	}
+    }
+    list [leaktest {[cls new] destroy}] [info class instances cls]
+} -cleanup {
+    cls destroy
+} -result {0 {}}
+
+oo::class create SampleSlot {
+    superclass oo::Slot
+    constructor {} {
+	variable contents {a b c} ops {}
+    }
+    method contents {} {variable contents; return $contents}
+    method ops {} {variable ops; return $ops}
+    method Get {} {
+	variable contents
+	variable ops
+	lappend ops [info level] Get
+	return $contents
+    }
+    method Set {lst} {
+	variable contents $lst
+	variable ops
+	lappend ops [info level] Set $lst
+	return
+    }
+}
+
+test oo-32.1 {TIP 380: slots - class test} -setup {
+    SampleSlot create sampleSlot
+} -body {
+    list [info level] [sampleSlot contents] [sampleSlot ops]
+} -cleanup {
+    rename sampleSlot {}
+} -result {0 {a b c} {}}
+test oo-32.2 {TIP 380: slots - class test} -setup {
+    SampleSlot create sampleSlot
+} -body {
+    list [info level] [sampleSlot -clear] \
+	[sampleSlot contents] [sampleSlot ops]
+} -cleanup {
+    rename sampleSlot {}
+} -result {0 {} {} {1 Set {}}}
+test oo-32.3 {TIP 380: slots - class test} -setup {
+    SampleSlot create sampleSlot
+} -body {
+    list [info level] [sampleSlot -append g h i] \
+	[sampleSlot contents] [sampleSlot ops]
+} -cleanup {
+    rename sampleSlot {}
+} -result {0 {} {a b c g h i} {1 Get 1 Set {a b c g h i}}}
+test oo-32.4 {TIP 380: slots - class test} -setup {
+    SampleSlot create sampleSlot
+} -body {
+    list [info level] [sampleSlot -set d e f] \
+	[sampleSlot contents] [sampleSlot ops]
+} -cleanup {
+    rename sampleSlot {}
+} -result {0 {} {d e f} {1 Set {d e f}}}
+test oo-32.5 {TIP 380: slots - class test} -setup {
+    SampleSlot create sampleSlot
+} -body {
+    list [info level] [sampleSlot -set d e f] [sampleSlot -append g h i] \
+	[sampleSlot contents] [sampleSlot ops]
+} -cleanup {
+    rename sampleSlot {}
+} -result {0 {} {} {d e f g h i} {1 Set {d e f} 1 Get 1 Set {d e f g h i}}}
+
+test oo-33.1 {TIP 380: slots - defaulting} -setup {
+    set s [SampleSlot new]
+} -body {
+    list [$s x y] [$s contents]
+} -cleanup {
+    rename $s {}
+} -result {{} {a b c x y}}
+test oo-33.2 {TIP 380: slots - defaulting} -setup {
+    set s [SampleSlot new]
+} -body {
+    list [$s destroy; $s unknown] [$s contents]
+} -cleanup {
+    rename $s {}
+} -result {{} {a b c destroy unknown}}
+test oo-33.3 {TIP 380: slots - defaulting} -setup {
+    set s [SampleSlot new]
+} -body {
+    oo::objdefine $s forward --default-operation  my -set
+    list [$s destroy; $s unknown] [$s contents] [$s ops]
+} -cleanup {
+    rename $s {}
+} -result {{} unknown {1 Set destroy 1 Set unknown}}
+test oo-33.4 {TIP 380: slots - errors} -setup {
+    set s [SampleSlot new]
+} -body {
+    # Method names beginning with "-" are special to slots
+    $s -grill q
+} -returnCodes error -cleanup {
+    rename $s {}
+} -result {unknown method "-grill": must be -append, -clear, -set, contents or ops}
+
+SampleSlot destroy
+
+test oo-34.1 {TIP 380: slots - presence} -setup {
+    set obj [oo::object new]
+    set result {}
+} -body {
+    oo::define oo::object {
+	::lappend ::result [::info object class filter]
+	::lappend ::result [::info object class mixin]
+	::lappend ::result [::info object class superclass]
+	::lappend ::result [::info object class variable]
+    }
+    oo::objdefine $obj {
+	::lappend ::result [::info object class filter]
+	::lappend ::result [::info object class mixin]
+	::lappend ::result [::info object class variable]
+    }
+    return $result
+} -cleanup {
+    $obj destroy
+} -result {::oo::Slot ::oo::Slot ::oo::Slot ::oo::Slot ::oo::Slot ::oo::Slot ::oo::Slot}
+test oo-34.2 {TIP 380: slots - presence} {
+    lsort [info class instances oo::Slot]
+} {::oo::define::filter ::oo::define::mixin ::oo::define::superclass ::oo::define::variable ::oo::objdefine::filter ::oo::objdefine::mixin ::oo::objdefine::variable}
+proc getMethods obj {
+    list [lsort [info object methods $obj -all]] \
+	[lsort [info object methods $obj -private]]
+}
+test oo-34.3 {TIP 380: slots - presence} {
+    getMethods oo::define::filter
+} {{-append -clear -set} {Get Set}}
+test oo-34.4 {TIP 380: slots - presence} {
+    getMethods oo::define::mixin
+} {{-append -clear -set} {--default-operation Get Set}}
+test oo-34.5 {TIP 380: slots - presence} {
+    getMethods oo::define::superclass
+} {{-append -clear -set} {--default-operation Get Set}}
+test oo-34.6 {TIP 380: slots - presence} {
+    getMethods oo::define::variable
+} {{-append -clear -set} {Get Set}}
+test oo-34.7 {TIP 380: slots - presence} {
+    getMethods oo::objdefine::filter
+} {{-append -clear -set} {Get Set}}
+test oo-34.8 {TIP 380: slots - presence} {
+    getMethods oo::objdefine::mixin
+} {{-append -clear -set} {--default-operation Get Set}}
+test oo-34.9 {TIP 380: slots - presence} {
+    getMethods oo::objdefine::variable
+} {{-append -clear -set} {Get Set}}
+
+test oo-35.1 {Bug 9d61624b3d: Empty superclass must not cause crash} -setup {
+    oo::class create fruit {
+	method eat {} {}
+    }
+    set result {}
+} -body {
+    lappend result [fruit create ::apple] [info class superclasses fruit]
+    oo::define fruit superclass
+    lappend result [info class superclasses fruit] \
+	[info object class apple oo::object] \
+	[info class call fruit destroy] \
+	[catch { apple }]
+} -cleanup {
+    unset -nocomplain result
+    fruit destroy
+} -result {::apple ::oo::object ::oo::object 1 {{method destroy ::oo::object {core method: "destroy"}}} 1}
+test oo-35.2 {Bug 9d61624b3d: Empty superclass must not cause crash} -setup {
+    oo::class create fruitMetaclass {
+	superclass oo::class
+	method eat {} {}
+    }
+    set result {}
+} -body {
+    lappend result [fruitMetaclass create ::appleClass] \
+	[appleClass create orange] \
+	[info class superclasses fruitMetaclass]
+    oo::define fruitMetaclass superclass
+    lappend result [info class superclasses fruitMetaclass] \
+	[info object class appleClass oo::class] \
+	[catch { orange }] [info object class orange] \
+	[appleClass create pear]
+} -cleanup {
+    unset -nocomplain result
+    fruitMetaclass destroy
+} -result {::appleClass ::orange ::oo::class ::oo::class 1 1 ::appleClass ::pear}
+test oo-35.3 {Bug 593baa032c: superclass list teardown} {
+    # Bug makes this crash, especially with mem-debugging on
+    oo::class create B {}
+    oo::class create D {superclass B}
+    namespace eval [info object namespace D] [list [namespace which B] destroy]
+} {}
+test oo-35.4 {Bug 593baa032c: mixins list teardown} {
+    # Bug makes this crash, especially with mem-debugging on
+    oo::class create B {}
+    oo::class create D {mixin B}
+    namespace eval [info object namespace D] [list [namespace which B] destroy]
+} {}
+
+
+cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/tests/ooNext2.test b/tests/ooNext2.test
new file mode 100644
index 0000000..6a48d28
--- /dev/null
+++ b/tests/ooNext2.test
@@ -0,0 +1,1065 @@
+# This file contains a collection of tests for Tcl's built-in object system.
+# Sourcing this file into Tcl runs the tests and generates output for errors.
+# No output means no errors were found.
+#
+# Copyright (c) 2006-2011 Donal K. Fellows
+#
+# See the file "license.terms" for information on usage and redistribution of
+# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+package require TclOO 1.0.3
+package require tcltest 2
+if {"::tcltest" in [namespace children]} {
+    namespace import -force ::tcltest::*
+}
+
+testConstraint memory [llength [info commands memory]]
+if {[testConstraint memory]} {
+    proc getbytes {} {
+	set lines [split [memory info] \n]
+	return [lindex $lines 3 3]
+    }
+    proc leaktest {script {iterations 3}} {
+	set end [getbytes]
+	for {set i 0} {$i < $iterations} {incr i} {
+	    uplevel 1 $script
+	    set tmp $end
+	    set end [getbytes]
+	}
+	return [expr {$end - $tmp}]
+    }
+}
+
+test oo-nextto-1.1 {basic nextto functionality} -setup {
+    oo::class create root
+} -body {
+    oo::class create A {
+	superclass root
+	method x args {
+	    lappend ::result ==A== $args
+	}
+    }
+    oo::class create B {
+	superclass A
+	method x args {
+	    lappend ::result ==B== $args
+	    nextto A B -> A {*}$args
+	}
+    }
+    oo::class create C {
+	superclass A
+	method x args {
+	    lappend ::result ==C== $args
+	    nextto A C -> A {*}$args
+	}
+    }
+    oo::class create D {
+	superclass B C
+	method x args {
+	    lappend ::result ==D== $args
+	    next foo
+	    nextto C bar
+	}
+    }
+    set ::result {}
+    [D new] x
+    return $::result
+} -cleanup {
+    root destroy
+} -result {==D== {} ==B== foo ==A== {B -> A foo} ==C== bar ==A== {C -> A bar}}
+test oo-nextto-1.2 {basic nextto functionality} -setup {
+    oo::class create root
+} -body {
+    oo::class create A {
+	superclass root
+	method x args {
+	    lappend ::result ==A== $args
+	}
+    }
+    oo::class create B {
+	superclass A
+	method x args {
+	    lappend ::result ==B== $args
+	    nextto A B -> A {*}$args
+	}
+    }
+    oo::class create C {
+	superclass A
+	method x args {
+	    lappend ::result ==C== $args
+	    nextto A C -> A {*}$args
+	}
+    }
+    oo::class create D {
+	superclass B C
+	method x args {
+	    lappend ::result ==D== $args
+	    nextto B foo {*}$args
+	    nextto C bar {*}$args
+	}
+    }
+    set ::result {}
+    [D new] x 123
+    return $::result
+} -cleanup {
+    root destroy
+} -result {==D== 123 ==B== {foo 123} ==A== {B -> A foo 123} ==C== {bar 123} ==A== {C -> A bar 123}}
+test oo-nextto-1.3 {basic nextto functionality: constructors} -setup {
+    oo::class create root
+} -body {
+    oo::class create A {
+	superclass root
+	variable result
+	constructor {a c} {
+	    lappend result ==A== a=$a,c=$c
+	}
+    }
+    oo::class create B {
+	superclass root
+	variable result
+	constructor {b} {
+	    lappend result ==B== b=$b
+	}
+    }
+    oo::class create C {
+	superclass A B
+	variable result
+	constructor {p q r} {
+	    lappend result ==C== p=$p,q=$q,r=$r
+	    # Route arguments to superclasses, in non-trival pattern
+	    nextto B $q
+	    nextto A $p $r
+	}
+	method result {} {return $result}
+    }
+    [C new x y z] result
+} -cleanup {
+    root destroy
+} -result {==C== p=x,q=y,r=z ==B== b=y ==A== a=x,c=z}
+test oo-nextto-1.4 {basic nextto functionality: destructors} -setup {
+    oo::class create root {destructor return}
+} -body {
+    oo::class create A {
+	superclass root
+	destructor {
+	    lappend ::result ==A==
+	    next
+	}
+    }
+    oo::class create B {
+	superclass root
+	destructor {
+	    lappend ::result ==B==
+	    next
+	}
+    }
+    oo::class create C {
+	superclass A B
+	destructor {
+	    lappend ::result ==C==
+	    lappend ::result |
+	    nextto B
+	    lappend ::result |
+	    nextto A
+	    lappend ::result |
+	    next
+	}
+    }
+    set ::result ""
+    [C new] destroy
+    return $::result
+} -cleanup {
+    root destroy
+} -result {==C== | ==B== | ==A== ==B== | ==A== ==B==}
+
+test oo-nextto-2.1 {errors in nextto} -setup {
+    oo::class create root
+} -body {
+    oo::class create A {
+	superclass root
+	method x y {error $y}
+    }
+    oo::class create B {
+	superclass A
+	method x y {nextto A $y}
+    }
+    [B new] x boom
+} -cleanup {
+    root destroy
+} -result boom -returnCodes error
+test oo-nextto-2.2 {errors in nextto} -setup {
+    oo::class create root
+} -body {
+    oo::class create A {
+	superclass root
+	method x y {error $y}
+    }
+    oo::class create B {
+	superclass root
+	method x y {nextto A $y}
+    }
+    [B new] x boom
+} -returnCodes error -cleanup {
+    root destroy
+} -result {method has no non-filter implementation by "A"}
+test oo-nextto-2.3 {errors in nextto} -setup {
+    oo::class create root
+} -body {
+    oo::class create A {
+	superclass root
+	method x y {nextto $y}
+    }
+    oo::class create B {
+	superclass A
+	method x y {nextto A $y}
+    }
+    [B new] x B
+} -returnCodes error -cleanup {
+    root destroy
+} -result {method implementation by "B" not reachable from here}
+test oo-nextto-2.4 {errors in nextto} -setup {
+    oo::class create root
+} -body {
+    oo::class create A {
+	superclass root
+	method x y {nextto $y}
+    }
+    oo::class create B {
+	superclass A
+	method x y {nextto}
+    }
+    [B new] x B
+} -returnCodes error -cleanup {
+    root destroy
+} -result {wrong # args: should be "nextto class ?arg...?"}
+test oo-nextto-2.5 {errors in nextto} -setup {
+    oo::class create root
+} -body {
+    oo::class create A {
+	superclass root
+	method x y {nextto $y}
+    }
+    oo::class create B {
+	superclass A
+	method x y {nextto $y $y $y}
+    }
+    [B new] x A
+} -cleanup {
+    root destroy
+} -result {wrong # args: should be "nextto A y"} -returnCodes error
+test oo-nextto-2.6 {errors in nextto} -setup {
+    oo::class create root
+} -body {
+    oo::class create A {
+	superclass root
+	method x y {nextto $y}
+    }
+    oo::class create B {
+	superclass A
+	method x y {nextto $y $y $y}
+    }
+    [B new] x [root create notAClass]
+} -cleanup {
+    root destroy
+} -result {"::notAClass" is not a class} -returnCodes error
+test oo-nextto-2.7 {errors in nextto} -setup {
+    oo::class create root
+} -body {
+    oo::class create A {
+	superclass root
+	method x y {nextto $y}
+    }
+    oo::class create B {
+	superclass A
+	filter Y
+	method Y args {next {*}$args}
+    }
+    oo::class create C {
+	superclass B
+	method x y {nextto $y $y $y}
+    }
+    [C new] x B
+} -returnCodes error -cleanup {
+    root destroy
+} -result {method has no non-filter implementation by "B"}
+
+test oo-call-1.1 {object call introspection} -setup {
+    oo::class create root
+} -body {
+    oo::class create ::A {
+	superclass root
+	method x {} {}
+    }
+    A create y
+    info object call y x
+} -cleanup {
+    root destroy
+} -result {{method x ::A method}}
+test oo-call-1.2 {object call introspection} -setup {
+    oo::class create root
+} -body {
+    oo::class create ::A {
+	superclass root
+	method x {} {}
+    }
+    oo::class create ::B {
+	superclass A
+	method x {} {}
+    }
+    B create y
+    info object call y x
+} -cleanup {
+    root destroy
+} -result {{method x ::B method} {method x ::A method}}
+test oo-call-1.3 {object call introspection} -setup {
+    oo::class create root
+} -body {
+    oo::class create ::A {
+	superclass root
+	method x {} {}
+    }
+    A create y
+    oo::objdefine y method x {} {}
+    info object call y x
+} -cleanup {
+    root destroy
+} -result {{method x object method} {method x ::A method}}
+test oo-call-1.4 {object object call introspection - unknown} -setup {
+    oo::class create root
+} -body {
+    oo::class create ::A {
+	superclass root
+	method x {} {}
+    }
+    A create y
+    info object call y z
+} -cleanup {
+    root destroy
+} -result {{unknown unknown ::oo::object {core method: "unknown"}}}
+test oo-call-1.5 {object call introspection - filters} -setup {
+    oo::class create root
+} -body {
+    oo::class create ::A {
+	superclass root
+	method x {} {}
+	method y {} {}
+	filter y
+    }
+    A create y
+    info object call y x
+} -cleanup {
+    root destroy
+} -result {{filter y ::A method} {method x ::A method}}
+test oo-call-1.6 {object call introspection - filters} -setup {
+    oo::class create root
+} -body {
+    oo::class create ::A {
+	superclass root
+	method x {} {}
+	method y {} {}
+	filter y
+    }
+    oo::class create ::B {
+	superclass A
+	method x {} {}
+    }
+    B create y
+    info object call y x
+} -cleanup {
+    root destroy
+} -result {{filter y ::A method} {method x ::B method} {method x ::A method}}
+test oo-call-1.7 {object call introspection - filters} -setup {
+    oo::class create root
+} -body {
+    oo::class create ::A {
+	superclass root
+	method x {} {}
+	method y {} {}
+	filter y
+    }
+    oo::class create ::B {
+	superclass A
+	method x {} {}
+	method y {} {}
+    }
+    B create y
+    info object call y x
+} -cleanup {
+    root destroy
+} -result {{filter y ::B method} {filter y ::A method} {method x ::B method} {method x ::A method}}
+test oo-call-1.8 {object call introspection - filters} -setup {
+    oo::class create root
+} -body {
+    oo::class create ::A {
+	superclass root
+	method x {} {}
+	method y {} {}
+	filter y
+    }
+    oo::class create ::B {
+	superclass A
+	method x {} {}
+	method y {} {}
+	method z {} {}
+	filter z
+    }
+    B create y
+    info object call y x
+} -cleanup {
+    root destroy
+} -result {{filter z ::B method} {filter y ::B method} {filter y ::A method} {method x ::B method} {method x ::A method}}
+test oo-call-1.9 {object call introspection - filters} -setup {
+    oo::class create root
+} -body {
+    oo::class create ::A {
+	superclass root
+	method x {} {}
+	method y {} {}
+	filter y
+    }
+    oo::class create ::B {
+	superclass A
+	method x {} {}
+	method y {} {}
+	method z {} {}
+	filter z
+    }
+    B create y
+    info object call y y
+} -cleanup {
+    root destroy
+} -result {{filter z ::B method} {filter y ::B method} {filter y ::A method} {method y ::B method} {method y ::A method}}
+test oo-call-1.10 {object call introspection - filters + unknown} -setup {
+    oo::class create root
+} -body {
+    oo::class create ::A {
+	superclass root
+	method y {} {}
+	filter y
+    }
+    oo::class create ::B {
+	superclass A
+	method y {} {}
+	method unknown {} {}
+    }
+    B create y
+    info object call y x
+} -cleanup {
+    root destroy
+} -result {{filter y ::B method} {filter y ::A method} {unknown unknown ::B method} {unknown unknown ::oo::object {core method: "unknown"}}}
+test oo-call-1.11 {object call introspection - filters + unknown} -setup {
+    oo::class create root
+} -body {
+    oo::class create ::A {
+	superclass root
+	method y {} {}
+	filter y
+    }
+    A create y
+    oo::objdefine y method unknown {} {}
+    info object call y x
+} -cleanup {
+    root destroy
+} -result {{filter y ::A method} {unknown unknown object method} {unknown unknown ::oo::object {core method: "unknown"}}}
+test oo-call-1.12 {object call introspection - filters + unknown} -setup {
+    oo::class create root
+} -body {
+    oo::class create ::A {
+	superclass root
+	method y {} {}
+    }
+    A create y
+    oo::objdefine y {
+	method unknown {} {}
+	filter y
+    }
+    info object call y x
+} -cleanup {
+    root destroy
+} -result {{filter y ::A method} {unknown unknown object method} {unknown unknown ::oo::object {core method: "unknown"}}}
+test oo-call-1.13 {object call introspection - filters + unknown} -setup {
+    oo::class create root
+} -body {
+    oo::class create ::A {
+	superclass root
+	method y {} {}
+    }
+    A create y
+    oo::objdefine y {
+	method unknown {} {}
+	method x {} {}
+	filter y
+    }
+    info object call y x
+} -cleanup {
+    root destroy
+} -result {{filter y ::A method} {method x object method}}
+test oo-call-1.14 {object call introspection - errors} -body {
+    info object call
+} -returnCodes error -result {wrong # args: should be "info object call objName methodName"}
+test oo-call-1.15 {object call introspection - errors} -body {
+    info object call a
+} -returnCodes error -result {wrong # args: should be "info object call objName methodName"}
+test oo-call-1.16 {object call introspection - errors} -body {
+    info object call a b c
+} -returnCodes error -result {wrong # args: should be "info object call objName methodName"}
+test oo-call-1.17 {object call introspection - errors} -body {
+    info object call notanobject x
+} -returnCodes error -result {notanobject does not refer to an object}
+test oo-call-1.18 {object call introspection - memory leaks} -body {
+    leaktest {
+	info object call oo::object destroy
+    }
+} -constraints memory -result 0
+test oo-call-1.19 {object call introspection - memory leaks} -setup {
+    oo::class create leaktester { method foo {} {dummy} }
+} -body {
+    leaktest {
+	set lt [leaktester new]
+	oo::objdefine $lt method foobar {} {dummy}
+	list [info object call $lt destroy] \
+	    [info object call $lt foo] \
+	    [info object call $lt bar] \
+	    [info object call $lt foobar] \
+	    [$lt destroy]
+    }
+} -cleanup {
+    leaktester destroy
+} -constraints memory -result 0
+test oo-call-1.20 {object call introspection - complex case} -setup {
+    oo::class create root
+} -body {
+    oo::class create ::A {
+	superclass root
+	method x {} {}
+    }
+    oo::class create ::B {
+	superclass A
+	method x {} {}
+    }
+    oo::class create ::C {
+	superclass root
+	method x {} {}
+	mixin B
+    }
+    oo::class create ::D {
+	superclass C
+	method x {} {}
+    }
+    oo::class create ::E {
+	superclass root
+	method x {} {}
+    }
+    oo::class create ::F {
+	superclass E
+	method x {} {}
+    }
+    oo::class create ::G {
+	superclass root
+	method x {} {}
+    }
+    oo::class create ::H {
+	superclass G
+	method x {} {}
+    }
+    oo::define F mixin H
+    F create y
+    oo::objdefine y {
+	method x {} {}
+	mixin D
+    }
+    info object call y x
+} -cleanup {
+    root destroy
+} -result {{method x ::D method} {method x ::B method} {method x ::A method} {method x ::C method} {method x ::H method} {method x ::G method} {method x object method} {method x ::F method} {method x ::E method}}
+test oo-call-1.21 {object call introspection - complex case} -setup {
+    oo::class create root
+} -body {
+    oo::class create ::A {
+	superclass root
+	method y {} {}
+	filter y
+    }
+    oo::class create ::B {
+	superclass A
+	method y {} {}
+    }
+    oo::class create ::C {
+	superclass root
+	method x {} {}
+	mixin B
+    }
+    oo::class create ::D {
+	superclass C
+	filter x
+    }
+    oo::class create ::E {
+	superclass root
+	method y {} {}
+	method x {} {}
+    }
+    oo::class create ::F {
+	superclass E
+	method z {} {}
+	method q {} {}
+    }
+    F create y
+    oo::objdefine y {
+	method unknown {} {}
+	mixin D
+	filter q
+    }
+    info object call y z
+} -cleanup {
+    root destroy
+} -result {{filter x ::C method} {filter x ::E method} {filter y ::B method} {filter y ::A method} {filter y ::E method} {filter q ::F method} {method z ::F method}}
+
+test oo-call-2.1 {class call introspection} -setup {
+    oo::class create root
+} -body {
+    oo::class create ::A {
+	superclass root
+	method x {} {}
+    }
+    info class call A x
+} -cleanup {
+    root destroy
+} -result {{method x ::A method}}
+test oo-call-2.2 {class call introspection} -setup {
+    oo::class create root
+} -body {
+    oo::class create ::A {
+	superclass root
+	method x {} {}
+    }
+    oo::class create ::B {
+	superclass A
+	method x {} {}
+    }
+    list [info class call A x] [info class call B x]
+} -cleanup {
+    root destroy
+} -result {{{method x ::A method}} {{method x ::B method} {method x ::A method}}}
+test oo-call-2.3 {class call introspection} -setup {
+    oo::class create root
+} -body {
+    oo::class create ::A {
+	superclass root
+	method x {} {}
+    }
+    oo::class create ::B {
+	superclass A
+	method x {} {}
+    }
+    oo::class create ::C {
+	superclass A
+	method x {} {}
+    }
+    oo::class create ::D {
+	superclass C B
+	method x {} {}
+    }
+    info class call D x
+} -cleanup {
+    root destroy
+} -result {{method x ::D method} {method x ::C method} {method x ::B method} {method x ::A method}}
+test oo-call-2.4 {class call introspection - mixin} -setup {
+    oo::class create root
+} -body {
+    oo::class create ::A {
+	superclass root
+	method x {} {}
+    }
+    oo::class create ::B {
+	superclass A
+	method x {} {}
+    }
+    oo::class create ::C {
+	superclass A
+	method x {} {}
+    }
+    oo::class create ::D {
+	superclass C
+	mixin B
+	method x {} {}
+    }
+    info class call D x
+} -cleanup {
+    root destroy
+} -result {{method x ::B method} {method x ::D method} {method x ::C method} {method x ::A method}}
+test oo-call-2.5 {class call introspection - mixin + filter} -setup {
+    oo::class create root
+} -body {
+    oo::class create ::A {
+	superclass root
+	method x {} {}
+    }
+    oo::class create ::B {
+	superclass A
+	method x {} {}
+	method y {} {}
+	filter y
+    }
+    oo::class create ::C {
+	superclass A
+	method x {} {}
+	method y {} {}
+    }
+    oo::class create ::D {
+	superclass C
+	mixin B
+	method x {} {}
+    }
+    info class call D x
+} -cleanup {
+    root destroy
+} -result {{filter y ::B method} {filter y ::C method} {method x ::B method} {method x ::D method} {method x ::C method} {method x ::A method}}
+test oo-call-2.6 {class call introspection - mixin + filter + unknown} -setup {
+    oo::class create root
+} -body {
+    oo::class create ::A {
+	superclass root
+	method x {} {}
+	method unknown {} {}
+    }
+    oo::class create ::B {
+	superclass A
+	method x {} {}
+	method y {} {}
+	filter y
+    }
+    oo::class create ::C {
+	superclass A
+	method x {} {}
+	method y {} {}
+    }
+    oo::class create ::D {
+	superclass C
+	mixin B
+	method x {} {}
+	method unknown {} {}
+    }
+    info class call D z
+} -cleanup {
+    root destroy
+} -result {{filter y ::B method} {filter y ::C method} {unknown unknown ::D method} {unknown unknown ::A method} {unknown unknown ::oo::object {core method: "unknown"}}}
+test oo-call-2.7 {class call introspection - mixin + filter + unknown} -setup {
+    oo::class create root
+} -body {
+    oo::class create ::A {
+	superclass root
+	method x {} {}
+    }
+    oo::class create ::B {
+	superclass A
+	method x {} {}
+	filter x
+    }
+    info class call B x
+} -cleanup {
+    root destroy
+} -result {{filter x ::B method} {filter x ::A method} {method x ::B method} {method x ::A method}}
+test oo-call-2.8 {class call introspection - errors} -body {
+    info class call
+} -returnCodes error -result {wrong # args: should be "info class call className methodName"}
+test oo-call-2.9 {class call introspection - errors} -body {
+    info class call a
+} -returnCodes error -result {wrong # args: should be "info class call className methodName"}
+test oo-call-2.10 {class call introspection - errors} -body {
+    info class call a b c
+} -returnCodes error -result {wrong # args: should be "info class call className methodName"}
+test oo-call-2.11 {class call introspection - errors} -body {
+    info class call notaclass x
+} -returnCodes error -result {notaclass does not refer to an object}
+test oo-call-2.12 {class call introspection - errors} -setup {
+    oo::class create root
+} -body {
+    root create notaclass
+    info class call notaclass x
+} -returnCodes error -cleanup {
+    root destroy
+} -result {"notaclass" is not a class}
+test oo-call-2.13 {class call introspection - memory leaks} -body {
+    leaktest {
+	info class call oo::class destroy
+    }
+} -constraints memory -result 0
+test oo-call-2.14 {class call introspection - memory leaks} -body {
+    leaktest {
+	oo::class create leaktester { method foo {} {dummy} }
+	[leaktester new] destroy
+	list [info class call leaktester destroy] \
+	    [info class call leaktester foo] \
+	    [info class call leaktester bar] \
+	    [leaktester destroy]
+    }
+} -constraints memory -result 0
+
+test oo-call-3.1 {current call introspection} -setup {
+    oo::class create root
+} -body {
+    oo::class create A {
+	superclass root
+	method x {} {lappend ::result [self call]}
+    }
+    oo::class create B {
+	superclass A
+	method x {} {lappend ::result [self call];next}
+    }
+    B create y
+    oo::objdefine y method x {} {lappend ::result [self call];next}
+    set ::result {}
+    y x
+} -cleanup {
+    root destroy
+} -result {{{{method x object method} {method x ::B method} {method x ::A method}} 0} {{{method x object method} {method x ::B method} {method x ::A method}} 1} {{{method x object method} {method x ::B method} {method x ::A method}} 2}}
+test oo-call-3.2 {current call introspection} -setup {
+    oo::class create root
+} -constraints memory -body {
+    oo::class create A {
+	superclass root
+	method x {} {self call}
+    }
+    oo::class create B {
+	superclass A
+	method x {} {self call;next}
+    }
+    B create y
+    oo::objdefine y method x {} {self call;next}
+    leaktest {
+	y x
+    }
+} -cleanup {
+    root destroy
+} -result 0
+test oo-call-3.3 {current call introspection: in constructors} -setup {
+    oo::class create root
+} -body {
+    oo::class create A {
+	superclass root
+	constructor {} {lappend ::result [self call]}
+    }
+    oo::class create B {
+	superclass A
+	constructor {} {lappend ::result [self call]; next}
+    }
+    set ::result {}
+    [B new] destroy
+    return $::result
+} -cleanup {
+    root destroy
+} -result {{{{method <constructor> ::B method} {method <constructor> ::A method}} 0} {{{method <constructor> ::B method} {method <constructor> ::A method}} 1}}
+test oo-call-3.4 {current call introspection: in destructors} -setup {
+    oo::class create root
+} -body {
+    oo::class create A {
+	superclass root
+	destructor {lappend ::result [self call]}
+    }
+    oo::class create B {
+	superclass A
+	destructor {lappend ::result [self call]; next}
+    }
+    set ::result {}
+    [B new] destroy
+    return $::result
+} -cleanup {
+    root destroy
+} -result {{{{method <destructor> ::B method} {method <destructor> ::A method}} 0} {{{method <destructor> ::B method} {method <destructor> ::A method}} 1}}
+
+# Contributed tests from aspect, related to [0f42ff7871]
+#
+# dkf's "Principles Leading to a Fix"
+#
+#   A method ought to work "the same" whether or not it has been overridden by
+#   a subclass. A tailcalled command ought to have as parent stack the same
+#   thing you'd get with uplevel 1. A subclass will often expect the
+#   superclass's result to be the result that would be returned if the
+#   subclass was not there.
+
+# Common setup:
+#	any invocation of bar should emit "abc\nhi\n" then return to its
+#	caller
+set testopts {
+    -setup {
+	oo::class create Master
+	oo::class create Foo {
+	    superclass Master
+	    method bar {} {
+		puts abc
+		tailcall puts hi
+		puts xyz
+	    }
+	}
+	oo::class create Foo2 {
+	    superclass Master
+	}
+    }
+    -cleanup {
+	Master destroy
+    }
+}
+
+# these succeed, showing that without [next] the bug doesn't fire
+test next-tailcall-simple-1 "trivial case with one method" {*}$testopts -body {
+    [Foo create foo] bar
+} -output [join {abc hi} \n]\n
+test next-tailcall-simple-2 "my bar" {*}$testopts -body {
+    oo::define Foo method baz {} {
+	puts a
+	my bar
+	puts b
+    }
+    [Foo create foo] baz
+} -output [join {a abc hi b} \n]\n
+test next-tailcall-simple-3 "\[self\] bar" {*}$testopts -body {
+    oo::define Foo method baz {} {
+	puts a
+	[self] bar
+	puts b
+    }
+    [Foo create foo] baz
+} -output [join {a abc hi b} \n]\n
+test next-tailcall-simple-4 "foo bar" {*}$testopts -body {
+    oo::define Foo method baz {} {
+	puts a
+	foo bar
+	puts b
+    }
+    [Foo create foo] baz
+} -output [join {a abc hi b} \n]\n
+
+# everything from here on uses [next], and fails on 8.6.4 with compilation
+test next-tailcall-superclass-1 "next superclass" {*}$testopts -body {
+    oo::define Foo2 {
+	superclass Foo
+	method bar {} {
+	    puts a
+	    next
+	    puts b
+	}
+    }
+    [Foo2 create foo] bar
+} -output [join {a abc hi b} \n]\n
+test next-tailcall-superclass-2 "nextto superclass" {*}$testopts -body {
+    oo::define Foo2 {
+	superclass Foo
+	method bar {} {
+	    puts a
+	    nextto Foo
+	    puts b
+	}
+    }
+    [Foo2 create foo] bar
+} -output [join {a abc hi b} \n]\n
+
+test next-tailcall-mixin-1 "class mixin" {*}$testopts -body {
+    oo::define Foo2 {
+	method Bar {} {
+	    puts a
+	    next
+	    puts b
+	}
+	filter Bar
+    }
+    oo::define Foo mixin Foo2
+    Foo create foo
+    foo bar
+} -output [join {a abc hi b} \n]\n
+
+test next-tailcall-objmixin-1 "object mixin" {*}$testopts -body {
+    oo::define Foo2 {
+	method Bar {} {
+	    puts a
+	    next
+	    puts b
+	}
+	filter Bar
+    }
+    Foo create foo
+    oo::objdefine foo mixin Foo2
+    foo bar
+} -output [join {a abc hi b} \n]\n
+
+test next-tailcall-filter-1 "filter method" {*}$testopts -body {
+    oo::define Foo method Filter {} {
+	puts a
+	next
+	puts b
+    }
+    oo::define Foo filter Filter
+    [Foo new] bar
+} -output [join {a abc hi b} \n]\n
+
+test next-tailcall-forward-1 "forward method" {*}$testopts -body {
+    proc foobar {} {
+	puts "abc"
+	tailcall puts "hi"
+	puts "xyz"
+    }
+    oo::define Foo forward foobar foobar
+    oo::define Foo2 {
+	superclass Foo
+	method foobar {} {
+	    puts a
+	    next
+	    puts b
+	}
+    }
+    [Foo2 new] foobar
+} -output [join {a abc hi b} \n]\n
+
+test next-tailcall-constructor-1 "next in constructor" -body {
+    oo::class create Foo {
+	constructor {} {
+	    puts abc
+	    tailcall puts hi
+	    puts xyz
+	}
+    }
+    oo::class create Foo2 {
+	superclass Foo
+	constructor {} {
+	    puts a
+	    next
+	    puts b
+	}
+    }
+    list [Foo new] [Foo2 new]
+    return ""
+} -cleanup {
+    Foo destroy
+} -output [join {abc hi a abc hi b} \n]\n
+
+test next-tailcall-destructor-1 "next in destructor" -body {
+    oo::class create Foo {
+	destructor {
+	    puts abc
+	    tailcall puts hi
+	    puts xyz
+	}
+    }
+    oo::class create Foo2 {
+	superclass Foo
+	destructor {
+	    puts a
+	    next
+	    puts b
+	}
+    }
+    Foo create foo
+    Foo2 create foo2
+    foo destroy
+    foo2 destroy
+} -output [join {abc hi a abc hi b} \n]\n -cleanup {
+    Foo destroy
+}
+
+unset testopts
+
+cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/tests/opt.test b/tests/opt.test
new file mode 100644
index 0000000..2732d40
--- /dev/null
+++ b/tests/opt.test
@@ -0,0 +1,245 @@
+# Package covered:  opt1.0/optparse.tcl
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands.  Sourcing this file into Tcl runs the tests and
+# generates output for errors.  No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994-1997 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+    package require tcltest
+    namespace import -force ::tcltest::*
+}
+
+# the package we are going to test
+package require opt 0.4.6
+
+# we are using implementation specifics to test the package
+
+
+#### functions tests #####
+
+set n $::tcl::OptDescN
+
+test opt-1.1 {OptKeyRegister / check that auto allocation is skipping existing keys} {
+    list [::tcl::OptKeyRegister {} $n] [::tcl::OptKeyRegister {} [expr $n+1]] [::tcl::OptKeyRegister {}]
+} "$n [expr $n+1] [expr $n+2]"
+
+test opt-2.1 {OptKeyDelete} {
+    list [::tcl::OptKeyRegister {} testkey] \
+	    [info exists ::tcl::OptDesc(testkey)] \
+	    [::tcl::OptKeyDelete testkey] \
+	    [info exists ::tcl::OptDesc(testkey)]
+} {testkey 1 {} 0}
+
+test opt-3.1 {OptParse / temp key is removed} {
+    set n $::tcl::OptDescN
+    set prev [array names ::tcl::OptDesc]
+    ::tcl::OptKeyRegister {} $n
+    list [info exists ::tcl::OptDesc($n)]\
+	    [::tcl::OptKeyDelete $n]\
+	    [::tcl::OptParse {{-foo}} {}]\
+	    [info exists ::tcl::OptDesc($n)]\
+	    [expr {"[lsort $prev]"=="[lsort [array names ::tcl::OptDesc]]"}]
+} {1 {} {} 0 1}
+test opt-3.2 {OptParse / temp key is removed even on errors} {
+    set n $::tcl::OptDescN
+    catch {::tcl::OptKeyDelete $n}
+    list [catch {::tcl::OptParse {{-foo}} {-blah}}] \
+	    [info exists ::tcl::OptDesc($n)]
+} {1 0}
+
+test opt-4.1 {OptProc} {
+    ::tcl::OptProc optTest {} {}
+    optTest
+    ::tcl::OptKeyDelete optTest
+} {}
+
+test opt-5.1 {OptProcArgGiven} {
+    ::tcl::OptProc optTest {{-foo}} {
+	if {[::tcl::OptProcArgGiven "-foo"]} {
+	    return 1
+	} else {
+	    return 0
+	}
+    }
+    list [optTest] [optTest -f] [optTest -F] [optTest -fOO]
+} {0 1 1 1}
+
+test opt-6.1 {OptKeyParse} {
+    ::tcl::OptKeyRegister {} test
+    list [catch {::tcl::OptKeyParse test {-help}} msg] $msg
+} {1 {Usage information:
+    Var/FlagName Type Value Help
+    ------------ ---- ----- ----
+    (-help                  gives this help)}}
+
+test opt-7.1 {OptCheckType} {
+    list \
+	    [::tcl::OptCheckType 23 int] \
+	    [::tcl::OptCheckType 23 float] \
+	    [::tcl::OptCheckType true boolean] \
+	    [::tcl::OptCheckType "-blah" any] \
+	    [::tcl::OptCheckType {a b c} list] \
+	    [::tcl::OptCheckType maYbe choice {yes maYbe no}] \
+	    [catch {::tcl::OptCheckType "-blah" string}] \
+	    [catch {::tcl::OptCheckType 6 boolean}] \
+	    [catch {::tcl::OptCheckType x float}] \
+	    [catch {::tcl::OptCheckType "a \{ c" list}] \
+	    [catch {::tcl::OptCheckType 2.3 int}] \
+	    [catch {::tcl::OptCheckType foo choice {x y Foo z}}]
+} {23 23.0 1 -blah {a b c} maYbe 1 1 1 1 1 1}
+
+test opt-8.1 {List utilities} {
+    ::tcl::Lempty {}
+} 1
+test opt-8.2 {List utilities} {
+    ::tcl::Lempty {a b c}
+} 0
+test opt-8.3 {List utilities} {
+    ::tcl::Lget {a {b c d} e} {1 2}
+} d
+test opt-8.4 {List utilities} {
+    set l {a {b c d e} f}
+    ::tcl::Lvarset l {1 2} D
+    set l
+} {a {b c D e} f}
+test opt-8.5 {List utilities} {
+    set l {a b c}
+    ::tcl::Lvarset1 l 6 X
+    set l
+} {a b c {} {} {} X}
+test opt-8.6 {List utilities} {
+    set l {a {b c 7 e} f}
+    ::tcl::Lvarincr l {1 2}
+    set l
+} {a {b c 8 e} f}
+test opt-8.7 {List utilities} {
+    set l {a {b c 7 e} f}
+    ::tcl::Lvarincr l {1 2} -9
+    set l
+} {a {b c -2 e} f}
+# 8.8 and 8.9 missing?
+test opt-8.10 {List utilities} {
+    set l {a {b c 7 e} f}
+    ::tcl::Lvarpop l
+    set l
+} {{b c 7 e} f}
+test opt-8.11 {List utilities} {
+    catch {unset x}
+    set l {a {b c 7 e} f}
+    list [::tcl::Lassign $l u v w x] \
+	    $u $v $w [info exists x]
+} {3 a {b c 7 e} f 0}
+
+test opt-9.1 {Misc utilities} {
+    catch {unset v}
+    ::tcl::SetMax v 3
+    ::tcl::SetMax v 7
+    ::tcl::SetMax v 6
+    set v
+} 7
+test opt-9.2 {Misc utilities} {
+    catch {unset v}
+    ::tcl::SetMin v 3
+    ::tcl::SetMin v -7
+    ::tcl::SetMin v 1
+    set v
+} -7
+
+#### behaviour tests #####
+
+test opt-10.1 {ambigous flags} {
+    ::tcl::OptProc optTest {{-fla} {-other} {-flag2xyz} {-flag3xyz}} {}
+    catch {optTest -fL} msg
+    set msg
+} {ambigous option "-fL", choose from:
+    -fla      boolflag (false)
+    -flag2xyz boolflag (false)
+    -flag3xyz boolflag (false)}
+test opt-10.2 {non ambigous flags} {
+    ::tcl::OptProc optTest {{-flag1xyz} {-other} {-flag2xyz} {-flag3xyz}} {
+	return $flag2xyz
+    }
+    optTest -fLaG2
+} 1
+test opt-10.3 {non ambigous flags because of exact match} {
+    ::tcl::OptProc optTest {{-flag1x} {-other} {-flag1} {-flag1xy}} {
+	return $flag1
+    }
+    optTest -flAg1
+} 1
+test opt-10.4 {ambigous flags, not exact match} {
+    ::tcl::OptProc optTest {{-flag1xy} {-other} {-flag1} {-flag1xyz}} {
+	return $flag1
+    }
+    catch {optTest -fLag1X} msg
+    set msg
+} {ambigous option "-fLag1X", choose from:
+    -flag1xy  boolflag (false)
+    -flag1xyz boolflag (false)}
+
+# medium size overall test example: (defined once)
+::tcl::OptProc optTest {
+    {cmd -choice {print save delete} "sub command to choose"}
+    {-allowBoing -boolean true}
+    {arg2 -string "this is help"}
+    {?arg3? 7 "optional number"}
+    {-moreflags}
+} {
+    list $cmd $allowBoing $arg2 $arg3 $moreflags
+}
+
+test opt-10.5 {medium size overall test} {
+    list [catch {optTest} msg] $msg
+} {1 {no value given for parameter "cmd" (use -help for full usage) :
+    cmd choice (print save delete) sub command to choose}}
+test opt-10.6 {medium size overall test} {
+    list [catch {optTest -help} msg] $msg
+} {1 {Usage information:
+    Var/FlagName Type     Value   Help
+    ------------ ----     -----   ----
+    (-help                        gives this help)
+    cmd          choice   (print save delete) sub command to choose
+    -allowBoing  boolean  (true)
+    arg2         string   ()      this is help
+    ?arg3?       int      (7)     optional number
+    -moreflags   boolflag (false)}}
+test opt-10.7 {medium size overall test} {
+    optTest save tst
+} {save 1 tst 7 0}
+test opt-10.8 {medium size overall test} {
+    optTest save -allowBoing false -- 8
+} {save 0 8 7 0}
+test opt-10.9 {medium size overall test} {
+    optTest save tst -m --
+} {save 1 tst 7 1}
+test opt-10.10 {medium size overall test} {
+    list [catch {optTest save tst foo} msg] [lindex [split $msg "\n"] 0]
+} {1 {too many arguments (unexpected argument(s): foo), usage:}}
+
+test opt-11.1 {too many args test 2} {
+    set key [::tcl::OptKeyRegister {-foo}]
+    list [catch {::tcl::OptKeyParse $key {-foo blah}} msg] $msg\
+	    [::tcl::OptKeyDelete $key]
+} {1 {too many arguments (unexpected argument(s): blah), usage:
+    Var/FlagName Type     Value   Help
+    ------------ ----     -----   ----
+    (-help                        gives this help)
+    -foo         boolflag (false)} {}}
+test opt-11.2 {default value for args} {
+    set args {}
+    set key [::tcl::OptKeyRegister {{args -list {a b c} "args..."}}]
+    ::tcl::OptKeyParse $key {}
+    ::tcl::OptKeyDelete $key
+    set args
+} {a b c}
+
+# cleanup
+::tcltest::cleanupTests
+return
diff --git a/tests/package.test b/tests/package.test
new file mode 100644
index 0000000..da778f1
--- /dev/null
+++ b/tests/package.test
@@ -0,0 +1,1279 @@
+# This file contains tests for the package and ::pkg::* commands.
+# Note that the tests are limited to Tcl scripts only, there are no shared
+# libraries against which to test.
+#
+# Sourcing this file into Tcl runs the tests and generates output for errors.
+# No output means no errors were found.
+#
+# Copyright (c) 1995-1996 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+# Copyright (c) 2011 Donal K. Fellows
+#
+# See the file "license.terms" for information on usage and redistribution of
+# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {"::tcltest" ni [namespace children]} {
+    package require tcltest 2.3.3
+    namespace import -force ::tcltest::*
+}
+
+# Do all this in a slave interp to avoid garbaging the package list
+set i [interp create]
+tcltest::loadIntoSlaveInterpreter $i {*}$argv
+interp eval $i {
+namespace import -force ::tcltest::*
+package forget {*}[package names]
+set oldPkgUnknown [package unknown]
+package unknown {}
+set oldPath $auto_path
+set auto_path ""
+
+test package-1.1 {pkg::create gives error on insufficient args} -body {
+    ::pkg::create
+} -returnCodes error -match glob -result {wrong # args: should be "*"}
+test package-1.2 {pkg::create gives error on bad args} -body {
+    ::pkg::create -foo bar -bar baz -baz boo
+} -returnCodes error -match glob -result {unknown option "bar": *}
+test package-1.3 {pkg::create gives error on no value given} -body {
+    ::pkg::create -name foo -version 1.0 -source test.tcl -load
+} -returnCodes error -match glob -result {value for "-load" missing: *}
+test package-1.4 {pkg::create gives error on no name given} -body {
+    ::pkg::create -version 1.0 -source test.tcl -load foo.so
+} -returnCodes error -match glob -result {value for "-name" missing: *}
+test package-1.5 {pkg::create gives error on no version given} -body {
+    ::pkg::create -name foo -source test.tcl -load foo.so
+} -returnCodes error -match glob -result {value for "-version" missing: *}
+test package-1.6 {pkg::create gives error on no source or load options} -body {
+    ::pkg::create -name foo -version 1.0 -version 2.0
+} -returnCodes error -result {at least one of -load and -source must be given}
+test package-1.7 {pkg::create gives correct output for 1 direct source} {
+    ::pkg::create -name foo -version 1.0 -source test.tcl
+} {package ifneeded foo 1.0 [list source [file join $dir test.tcl]]}
+test package-1.8 {pkg::create gives correct output for 2 direct sources} {
+    ::pkg::create -name foo -version 1.0 -source test.tcl -source test2.tcl
+} {package ifneeded foo 1.0 [list source [file join $dir test.tcl]]\n[list source [file join $dir test2.tcl]]}
+test package-1.9 {pkg::create gives correct output for 1 direct load} {
+    ::pkg::create -name foo -version 1.0 -load test.so
+} {package ifneeded foo 1.0 [list load [file join $dir test.so]]}
+test package-1.10 {pkg::create gives correct output for 2 direct loads} {
+    ::pkg::create -name foo -version 1.0 -load test.so -load test2.so
+} {package ifneeded foo 1.0 [list load [file join $dir test.so]]\n[list load [file join $dir test2.so]]}
+test package-1.11 {pkg::create gives correct output for 1 lazy source} {
+    ::pkg::create -name foo -version 1.0 -source {test.tcl {foo bar}}
+} {package ifneeded foo 1.0 [list tclPkgSetup $dir foo 1.0 {{test.tcl source {foo bar}}}]}
+test package-1.12 {pkg::create gives correct output for 2 lazy sources} {
+    ::pkg::create -name foo -version 1.0 -source {test.tcl {foo bar}} \
+	    -source {test2.tcl {baz boo}}
+} {package ifneeded foo 1.0 [list tclPkgSetup $dir foo 1.0 {{test.tcl source {foo bar}} {test2.tcl source {baz boo}}}]}
+test package-1.13 {pkg::create gives correct output for 1 lazy load} {
+    ::pkg::create -name foo -version 1.0 -load {test.so {foo bar}}
+} {package ifneeded foo 1.0 [list tclPkgSetup $dir foo 1.0 {{test.so load {foo bar}}}]}
+test package-1.14 {pkg::create gives correct output for 2 lazy loads} {
+    ::pkg::create -name foo -version 1.0 -load {test.so {foo bar}} \
+	    -load {test2.so {baz boo}}
+} {package ifneeded foo 1.0 [list tclPkgSetup $dir foo 1.0 {{test.so load {foo bar}} {test2.so load {baz boo}}}]}
+test package-1.15 {pkg::create gives correct output for 1 each, direct} {
+    ::pkg::create -name foo -version 1.0 -source test.tcl -load test2.so
+} {package ifneeded foo 1.0 [list load [file join $dir test2.so]]\n[list source [file join $dir test.tcl]]}
+test package-1.16 {pkg::create gives correct output for 1 direct, 1 lazy} {
+    ::pkg::create -name foo -version 1.0 -source test.tcl \
+	    -source {test2.tcl {foo bar}}
+} {package ifneeded foo 1.0 [list source [file join $dir test.tcl]]\n[list tclPkgSetup $dir foo 1.0 {{test2.tcl source {foo bar}}}]}
+
+test package-2.1 {Tcl_PkgProvide procedure} {
+    package forget t
+    package provide t 2.3
+} {}
+test package-2.2 {Tcl_PkgProvide procedure} -returnCodes error -setup {
+    package forget t
+} -body {
+    package provide t 2.3
+    package provide t 2.2
+} -result {conflicting versions provided for package "t": 2.3, then 2.2}
+test package-2.3 {Tcl_PkgProvide procedure} -returnCodes error -setup {
+    package forget t
+} -body {
+    package provide t 2.3
+    package provide t 2.4
+} -result {conflicting versions provided for package "t": 2.3, then 2.4}
+test package-2.4 {Tcl_PkgProvide procedure} -returnCodes error -setup {
+    package forget t
+} -body {
+    package provide t 2.3
+    package provide t 3.3
+} -result {conflicting versions provided for package "t": 2.3, then 3.3}
+test package-2.5 {Tcl_PkgProvide procedure} -setup {
+    package forget t
+} -body {
+    package provide t 2.3
+    package provide t 2.3
+} -result {}
+test package-2.6 {Tcl_PkgProvide procedure} {
+    package forget t
+    package provide t 2.3a1
+} {}
+
+set n 0
+foreach v {
+    2.3k1 2a3a2 2ab3 2.a4 2.b4 2b.4 2a.4 2ba4 2a4b1
+    2b4a1 2b3b2
+} {
+    test package-2.7.$n {Tcl_PkgProvide procedure} -setup {
+	package forget t
+    } -returnCodes error -body "
+	package provide t $v
+    " -result "expected version number but got \"$v\""
+    incr n
+}
+
+test package-3.1 {Tcl_PkgRequire procedure, picking best version} -setup {
+    package forget t
+    set x xxx
+} -body {
+    foreach i {1.4 3.4 2.3 2.4 2.2} {
+	package ifneeded t $i "set x $i; package provide t $i"
+    }
+    package require t
+    return $x
+} -result {3.4}
+test package-3.2 {Tcl_PkgRequire procedure, picking best version} -setup {
+    package forget t
+    set x xxx
+} -body {
+    foreach i {1.4 3.4 2.3 2.4 2.2 3.5 3.2} {
+	package ifneeded t $i "set x $i; package provide t $i"
+    }
+    package require t
+    return $x
+} -result {3.5}
+test package-3.3 {Tcl_PkgRequire procedure, picking best version} -setup {
+    package forget t
+    set x xxx
+} -body {
+    foreach i {3.5 2.1 2.3} {
+	package ifneeded t $i "set x $i; package provide t $i"
+    }
+    package require t 2.2
+    return $x
+} -result {2.3}
+test package-3.4 {Tcl_PkgRequire procedure, picking best version} -setup {
+    package forget t
+    set x xxx
+} -body {
+    foreach i {1.4 3.4 2.3 2.4 2.2} {
+	package ifneeded t $i "set x $i; package provide t $i"
+    }
+    package require -exact t 2.3
+    return $x
+} -result {2.3}
+test package-3.5 {Tcl_PkgRequire procedure, picking best version} -setup {
+    package forget t
+    set x xxx
+} -body {
+    foreach i {1.4 3.4 2.3 2.4 2.2} {
+	package ifneeded t $i "set x $i; package provide t $i"
+    }
+    package require t 2.1
+    return $x
+} -result {2.4}
+test package-3.6 {Tcl_PkgRequire procedure, can't find suitable version} -setup {
+    package forget t
+} -returnCodes error -body {
+    package unknown {}
+    foreach i {1.4 3.4 2.3 2.4 2.2} {
+	package ifneeded t $i "set x $i"
+    }
+    package require t 2.5
+} -result {can't find package t 2.5}
+test package-3.7 {Tcl_PkgRequire procedure, can't find suitable version} -setup {
+    package forget t
+} -returnCodes error -body {
+    package unknown {}
+    foreach i {1.4 3.4 2.3 2.4 2.2} {
+	package ifneeded t $i "set x $i"
+    }
+    package require t 4.1
+} -result {can't find package t 4.1}
+test package-3.8 {Tcl_PkgRequire procedure, can't find suitable version} -setup {
+    package forget t
+} -returnCodes error -body {
+    package unknown {}
+    foreach i {1.4 3.4 2.3 2.4 2.2} {
+	package ifneeded t $i "set x $i"
+    }
+    package require -exact t 1.3
+} -result {can't find package t exactly 1.3}
+test package-3.9 {Tcl_PkgRequire procedure, can't find suitable version} -setup {
+    package forget t
+} -returnCodes error -body {
+    package unknown {}
+    package require t
+} -result {can't find package t}
+test package-3.10 {Tcl_PkgRequire procedure, error in ifneeded script} -setup {
+    package forget t
+} -body {
+    package ifneeded t 2.1 {package provide t 2.1; error "ifneeded test"}
+    list [catch {package require t 2.1} msg] $msg $::errorInfo
+} -match glob -result {1 {ifneeded test} {ifneeded test
+    while executing
+"error "ifneeded test""
+    ("package ifneeded*" script)
+    invoked from within
+"package require t 2.1"}}
+test package-3.11 {Tcl_PkgRequire procedure, ifneeded script doesn't provide package} -setup {
+    package forget t
+    set x xxx
+} -body {
+    package ifneeded t 2.1 "set x invoked"
+    list [catch {package require t 2.1} msg] $msg $x
+} -match glob -result {1 * invoked}
+test package-3.12 {Tcl_PkgRequire procedure, self-deleting script} -setup {
+    package forget t
+    set x xxx
+} -body {
+    package ifneeded t 1.2 "package forget t; set x 1.2; package provide t 1.2"
+    package require t 1.2
+    return $x
+} -result {1.2}
+test package-3.13 {Tcl_PkgRequire procedure, "package unknown" support} -setup {
+    package forget t
+    set x xxx
+} -body {
+    proc pkgUnknown args {
+	# args = name requirement
+	# requirement = v-v (for exact version)
+	global x
+	set x $args
+	package provide [lindex $args 0] [lindex [split [lindex $args 1] -] 0]
+    }
+    foreach i {1.4 3.4 2.3 2.4 2.2} {
+	package ifneeded t $i "set x $i"
+    }
+    package unknown pkgUnknown
+    package require -exact t 1.5
+    return $x
+} -cleanup {
+    package unknown {}
+} -result {t 1.5-1.5}
+test package-3.14 {Tcl_PkgRequire procedure, "package unknown" support} -setup {
+    package forget t
+    set x xxx
+} -body {
+    proc pkgUnknown args {
+	package ifneeded t 1.2 "set x loaded; package provide t 1.2"
+    }
+    package unknown pkgUnknown
+    list [package require t] $x
+} -cleanup {
+    package unknown {}
+} -result {1.2 loaded}
+test package-3.15 {Tcl_PkgRequire procedure, "package unknown" support} -setup {
+    package forget {a b}
+    package unknown pkgUnknown
+    set x xxx
+} -body {
+    proc pkgUnknown args {
+	global x
+	set x $args
+	package provide [lindex $args 0] 2.0
+    }
+    package require {a b}
+    return $x
+} -cleanup {
+    package unknown {}
+} -result {{a b} 0-}
+test package-3.16 {Tcl_PkgRequire procedure, "package unknown" error} -setup {
+    package forget t
+} -body {
+    proc pkgUnknown args {
+	error "testing package unknown"
+    }
+    package unknown pkgUnknown
+    list [catch {package require t} msg] $msg $::errorInfo
+} -cleanup {
+    package unknown {}
+} -result {1 {testing package unknown} {testing package unknown
+    while executing
+"error "testing package unknown""
+    (procedure "pkgUnknown" line 2)
+    invoked from within
+"pkgUnknown t 0-"
+    ("package unknown" script)
+    invoked from within
+"package require t"}}
+test package-3.17 {Tcl_PkgRequire procedure, "package unknown" doesn't load package} -setup {
+    package forget t
+    set x xxx
+} -body {
+    proc pkgUnknown args {
+	global x
+	set x $args
+    }
+    foreach i {1.4 3.4 2.3 2.4 2.2} {
+	package ifneeded t $i "set x $i"
+    }
+    package unknown pkgUnknown
+    list [catch {package require -exact t 1.5} msg] $msg $x
+} -cleanup {
+    package unknown {}
+} -result {1 {can't find package t exactly 1.5} {t 1.5-1.5}}
+test package-3.18 {Tcl_PkgRequire procedure, version checks} -setup {
+    package forget t
+} -body {
+    package provide t 2.3
+    package require t
+} -result {2.3}
+test package-3.19 {Tcl_PkgRequire procedure, version checks} -setup {
+    package forget t
+} -body {
+    package provide t 2.3
+    package require t 2.1
+} -result {2.3}
+test package-3.20 {Tcl_PkgRequire procedure, version checks} -setup {
+    package forget t
+} -body {
+    package provide t 2.3
+    package require t 2.3
+} -result {2.3}
+test package-3.21 {Tcl_PkgRequire procedure, version checks} -setup {
+    package forget t
+} -returnCodes error -body {
+    package provide t 2.3
+    package require t 2.4
+} -result {version conflict for package "t": have 2.3, need 2.4}
+test package-3.22 {Tcl_PkgRequire procedure, version checks} -setup {
+    package forget t
+} -returnCodes error -body {
+    package provide t 2.3
+    package require t 1.2
+} -result {version conflict for package "t": have 2.3, need 1.2}
+test package-3.23 {Tcl_PkgRequire procedure, version checks} -setup {
+    package forget t
+} -body {
+    package provide t 2.3
+    package require -exact t 2.3
+} -result {2.3}
+test package-3.24 {Tcl_PkgRequire procedure, version checks} -setup {
+    package forget t
+} -returnCodes error -body {
+    package provide t 2.3
+    package require -exact t 2.2
+} -result {version conflict for package "t": have 2.3, need exactly 2.2}
+test package-3.25 {Tcl_PkgRequire procedure, error in ifneeded script} -setup {
+    package forget t
+} -body {
+    package ifneeded t 2.1 {package provide t 2.1; error "ifneeded test" EI}
+    list [catch {package require t 2.1} msg] $msg $::errorInfo
+} -match glob -result {1 {ifneeded test} {EI
+    ("package ifneeded*" script)
+    invoked from within
+"package require t 2.1"}}
+test package-3.26 {Tcl_PkgRequire procedure, error in ifneeded script} -setup {
+    package forget t
+} -body {
+    package ifneeded t 2.1 {package provide t 2.1; foreach x 1 {error "ifneeded test" EI}}
+    list [catch {package require t 2.1} msg] $msg $::errorInfo
+} -match glob -result {1 {ifneeded test} {EI
+    ("foreach" body line 1)
+    invoked from within
+"foreach x 1 {error "ifneeded test" EI}"
+    ("package ifneeded*" script)
+    invoked from within
+"package require t 2.1"}}
+test package-3.27 {Tcl_PkgRequire: circular dependency} -setup {
+    package forget foo
+} -body {
+    package ifneeded foo 1 {package require foo 1}
+    package require foo 1
+} -cleanup {
+    package forget foo
+} -returnCodes error -match glob -result {circular package dependency:*}
+test package-3.28 {Tcl_PkgRequire: circular dependency} -setup {
+    package forget foo
+} -body {
+    package ifneeded foo 1 {package require foo 2}
+    package require foo 1
+} -cleanup {
+    package forget foo
+} -returnCodes error -match glob -result {circular package dependency:*}
+test package-3.29 {Tcl_PkgRequire: circular dependency} -setup {
+    package forget foo
+    package forget bar
+} -body {
+    package ifneeded foo 1 {package require bar 1; package provide foo 1}
+    package ifneeded bar 1 {package require foo 1; package provide bar 1}
+    package require foo 1
+} -cleanup {
+    package forget foo
+    package forget bar
+} -returnCodes error -match glob -result {circular package dependency:*}
+test package-3.30 {Tcl_PkgRequire: circular dependency} -setup {
+    package forget foo
+    package forget bar
+} -body {
+    package ifneeded foo 1 {package require bar 1; package provide foo 1}
+    package ifneeded foo 2 {package provide foo 2}
+    package ifneeded bar 1 {package require foo 2; package provide bar 1}
+    package require foo 1
+} -cleanup {
+    package forget foo
+    package forget bar
+} -returnCodes error -match glob -result {circular package dependency:*}
+test package-3.31 {Tcl_PkgRequire: consistent return values (1162286)} -setup {
+    package forget foo
+} -body {
+    package ifneeded foo 1 {package provide foo 1; error foo}
+    package require foo 1
+} -cleanup {
+    package forget foo
+} -returnCodes error -match glob -result foo
+test package-3.32 {Tcl_PkgRequire: consistent return values (1162286)} -setup {
+    package forget foo
+} -body {
+    package ifneeded foo 1 {package provide foo 1; error foo}
+    catch {package require foo 1}
+    package provide foo
+} -cleanup {
+    package forget foo
+} -result {}
+test package-3.33 {Tcl_PkgRequire: consistent return values (1162286)} -setup {
+    package forget foo
+} -body {
+    package ifneeded foo 1 {package provide foo 2}
+    package require foo 1
+} -cleanup {
+    package forget foo
+} -returnCodes error -match glob -result {attempt to provide package * failed:*}
+test package-3.34 {Tcl_PkgRequire: consistent return values (1162286)} -setup {
+    package forget foo
+} -body {
+    package ifneeded foo 1 {package provide foo 1.1}
+    package require foo 1
+} -cleanup {
+    package forget foo
+} -returnCodes error -match glob -result {attempt to provide package * failed:*}
+test package-3.34.1 {Tcl_PkgRequire: consistent return values (1162286)} -setup {
+    package forget foo
+} -body {
+    package ifneeded foo 1.1 {package provide foo 1}
+    package require foo 1
+} -cleanup {
+    package forget foo
+} -returnCodes error -match glob -result {attempt to provide package * failed:*}
+test package-3.34.2 {Tcl_PkgRequire: consistent return values (1162286)} -setup {
+    package forget foo
+} -body {
+    package ifneeded foo 1.1 {package provide foo 1}
+    package require foo 1.1
+} -cleanup {
+    package forget foo
+} -returnCodes error -match glob -result {attempt to provide package * failed:*}
+test package-3.35 {Tcl_PkgRequire: consistent return values (1162286)} -setup {
+    package forget foo
+} -body {
+    package ifneeded foo 1 {}
+    package require foo 1
+} -cleanup {
+    package forget foo
+} -returnCodes error -match glob -result {attempt to provide package * failed:*}
+test package-3.35.1 {Tcl_PkgRequire: consistent return values (1162286)} -setup {
+    package forget foo
+} -body {
+    package ifneeded foo 1 {break}
+    package require foo 1
+} -cleanup {
+    package forget foo
+} -returnCodes error -match glob \
+-result {attempt to provide package * failed: bad return code:*}
+test package-3.36 {Tcl_PkgRequire: consistent return values (1162286)} -setup {
+    package forget foo
+} -body {
+    package ifneeded foo 1 {continue}
+    package require foo 1
+} -cleanup {
+    package forget foo
+} -returnCodes error -match glob \
+-result {attempt to provide package * failed: bad return code:*}
+test package-3.37 {Tcl_PkgRequire: consistent return values (1162286)} -setup {
+    package forget foo
+} -body {
+    package ifneeded foo 1 {return}
+    package require foo 1
+} -cleanup {
+    package forget foo
+} -returnCodes error -match glob \
+-result {attempt to provide package * failed: bad return code:*}
+test package-3.38 {Tcl_PkgRequire: consistent return values (1162286)} -setup {
+    package forget foo
+} -body {
+    package ifneeded foo 1 {return -level 0 -code 10}
+    package require foo 1
+} -cleanup {
+    package forget foo
+} -returnCodes error -match glob \
+-result {attempt to provide package * failed: bad return code:*}
+test package-3.39 {Tcl_PkgRequire: consistent return values (1162286)} -setup {
+    package forget foo
+    set saveUnknown [package unknown]
+    package unknown {package provide foo 2 ;#}
+} -body {
+    package require foo 1
+} -cleanup {
+    package forget foo
+    package unknown $saveUnknown
+} -returnCodes error -match glob -result *
+test package-3.40 {Tcl_PkgRequire: consistent return values (1162286)} -setup {
+    package forget foo
+    set saveUnknown [package unknown]
+    package unknown {break ;#}
+} -body {
+    package require foo 1
+} -cleanup {
+    package forget foo
+    package unknown $saveUnknown
+} -returnCodes error -match glob -result {bad return code:*}
+test package-3.41 {Tcl_PkgRequire: consistent return values (1162286)} -setup {
+    package forget foo
+    set saveUnknown [package unknown]
+    package unknown {continue ;#}
+} -body {
+    package require foo 1
+} -cleanup {
+    package forget foo
+    package unknown $saveUnknown
+} -returnCodes error -match glob -result {bad return code:*}
+test package-3.42 {Tcl_PkgRequire: consistent return values (1162286)} -setup {
+    package forget foo
+    set saveUnknown [package unknown]
+    package unknown {return ;#}
+} -body {
+    package require foo 1
+} -cleanup {
+    package forget foo
+    package unknown $saveUnknown
+} -returnCodes error -match glob -result {bad return code:*}
+test package-3.43 {Tcl_PkgRequire: consistent return values (1162286)} -setup {
+    package forget foo
+    set saveUnknown [package unknown]
+    package unknown {return -level 0 -code 10 ;#}
+} -body {
+    package require foo 1
+} -cleanup {
+    package forget foo
+    package unknown $saveUnknown
+} -returnCodes error -match glob -result {bad return code:*}
+test package-3.44 {Tcl_PkgRequire: exact version matching (1578344)} -setup {
+    package provide demo 1.2.3
+} -body {
+    package require -exact demo 1.2
+} -returnCodes error -cleanup {
+    package forget demo
+} -result {version conflict for package "demo": have 1.2.3, need exactly 1.2}
+test package-3.50 {Tcl_PkgRequire procedure, picking best stable version} -setup {
+    package forget t
+    set x xxx
+} -body {
+    foreach i {1.4 3.4 4.0a1 2.3 2.4 2.2} {
+	package ifneeded t $i "set x $i; package provide t $i"
+    }
+    package require t
+    return $x
+} -result {3.4}
+test package-3.51 {Tcl_PkgRequire procedure, picking best stable version} -setup {
+    package forget t
+    set x xxx
+} -body {
+    foreach i {1.2b1 1.2 1.3a2 1.3} {
+	package ifneeded t $i "set x $i; package provide t $i"
+    }
+    package require t
+    return $x
+} -result {1.3}
+test package-3.52 {Tcl_PkgRequire procedure, picking best stable version} -setup {
+    package forget t
+    set x xxx
+} -body {
+    foreach i {1.2b1 1.2 1.3 1.3a2} {
+	package ifneeded t $i "set x $i; package provide t $i"
+    }
+    package require t
+    return $x
+} -result {1.3}
+
+test package-4.1 {Tcl_PackageCmd procedure} -returnCodes error -body {
+    package
+} -result {wrong # args: should be "package option ?arg ...?"}
+test package-4.2 {Tcl_PackageCmd procedure, "forget" option} {
+    package forget {*}[package names]
+    package names
+} {}
+test package-4.3 {Tcl_PackageCmd procedure, "forget" option} {
+    package forget {*}[package names]
+    package forget foo
+} {}
+test package-4.4 {Tcl_PackageCmd procedure, "forget" option} -setup {
+    package forget {*}[package names]
+    set result {}
+} -body {
+    package ifneeded t 1.1 {first script}
+    package ifneeded t 2.3 {second script}
+    package ifneeded x 1.4 {x's script}
+    lappend result [lsort [package names]] [package versions t]
+    package forget t
+    lappend result [lsort [package names]] [package versions t]
+} -result {{t x} {1.1 2.3} x {}}
+test package-4.5 {Tcl_PackageCmd procedure, "forget" option} -setup {
+    package forget {*}[package names]
+} -body {
+    package ifneeded a 1.1 {first script}
+    package ifneeded b 2.3 {second script}
+    package ifneeded c 1.4 {third script}
+    package forget
+    set result [list [lsort [package names]]]
+    package forget a c
+    lappend result [lsort [package names]]
+} -result {{a b c} b}
+test package-4.5.1 {Tcl_PackageCmd procedure, "forget" option} -body {
+    # Test for Bug 415273
+    package ifneeded a 1 "I should have been forgotten"
+    package forget no-such-package a
+    package ifneeded a 1
+} -cleanup {
+    package forget a
+} -result {}
+test package-4.6 {Tcl_PackageCmd procedure, "ifneeded" option} -body {
+    package ifneeded a
+} -returnCodes error -result {wrong # args: should be "package ifneeded package version ?script?"}
+test package-4.7 {Tcl_PackageCmd procedure, "ifneeded" option} -body {
+    package ifneeded a b c d
+} -returnCodes error -result {wrong # args: should be "package ifneeded package version ?script?"}
+test package-4.8 {Tcl_PackageCmd procedure, "ifneeded" option} -body {
+    package ifneeded t xyz
+} -returnCodes error -result {expected version number but got "xyz"}
+test package-4.9 {Tcl_PackageCmd procedure, "ifneeded" option} {
+    package forget {*}[package names]
+    list [package ifneeded foo 1.1] [package names]
+} {{} {}}
+test package-4.10 {Tcl_PackageCmd procedure, "ifneeded" option} -setup {
+    package forget t
+} -body {
+    package ifneeded t 1.4 "script for t 1.4"
+    list [package names] [package ifneeded t 1.4] [package versions t]
+} -result {t {script for t 1.4} 1.4}
+test package-4.11 {Tcl_PackageCmd procedure, "ifneeded" option} -setup {
+    package forget t
+} -body {
+    package ifneeded t 1.4 "script for t 1.4"
+    list [package ifneeded t 1.5] [package names] [package versions t]
+} -result {{} t 1.4}
+test package-4.12 {Tcl_PackageCmd procedure, "ifneeded" option} -setup {
+    package forget t
+} -body {
+    package ifneeded t 1.4 "script for t 1.4"
+    package ifneeded t 1.4 "second script for t 1.4"
+    list [package ifneeded t 1.4] [package names] [package versions t]
+} -result {{second script for t 1.4} t 1.4}
+test package-4.13 {Tcl_PackageCmd procedure, "ifneeded" option} -setup {
+    package forget t
+} -body {
+    package ifneeded t 1.4 "script for t 1.4"
+    package ifneeded t 1.2 "second script"
+    package ifneeded t 3.1 "last script"
+    list [package ifneeded t 1.2] [package versions t]
+} -result {{second script} {1.4 1.2 3.1}}
+test package-4.14 {Tcl_PackageCmd procedure, "names" option} -body {
+    package names a
+} -returnCodes error -result {wrong # args: should be "package names"}
+test package-4.15 {Tcl_PackageCmd procedure, "names" option} {
+    package forget {*}[package names]
+    package names
+} {}
+test package-4.16 {Tcl_PackageCmd procedure, "names" option} -setup {
+    package forget {*}[package names]
+} -body {
+    package ifneeded x 1.2 {dummy}
+    package provide x 1.3
+    package provide y 2.4
+    catch {package require z 47.16}
+    lsort [package names]
+} -result {x y}
+test package-4.17 {Tcl_PackageCmd procedure, "provide" option} -body {
+    package provide
+} -returnCodes error -result {wrong # args: should be "package provide package ?version?"}
+test package-4.18 {Tcl_PackageCmd procedure, "provide" option} -body {
+    package provide a b c
+} -returnCodes error -result {wrong # args: should be "package provide package ?version?"}
+test package-4.19 {Tcl_PackageCmd procedure, "provide" option} -setup {
+    package forget t
+} -body {
+    package provide t
+} -result {}
+test package-4.20 {Tcl_PackageCmd procedure, "provide" option} -setup {
+    package forget t
+} -body {
+    package provide t 2.3
+    package provide t
+} -result {2.3}
+test package-4.21 {Tcl_PackageCmd procedure, "provide" option} -setup {
+    package forget t
+} -returnCodes error -body {
+    package provide t a.b
+} -result {expected version number but got "a.b"}
+test package-4.22 {Tcl_PackageCmd procedure, "require" option} -returnCodes error -body {
+    package require
+} -result {wrong # args: should be "package require ?-exact? package ?requirement ...?"}
+test package-4.24 {Tcl_PackageCmd procedure, "require" option} -body {
+    package require -exact a b c
+    # Exact syntax: -exact name version
+    #              name ?requirement ...?
+} -returnCodes error -result {wrong # args: should be "package require ?-exact? package ?requirement ...?"}
+test package-4.26 {Tcl_PackageCmd procedure, "require" option} -body {
+    package require x a.b
+} -returnCodes error -result {expected version number but got "a.b"}
+test package-4.27 {Tcl_PackageCmd procedure, "require" option} -body {
+    package require -exact x a.b
+} -returnCodes error -result {expected version number but got "a.b"}
+test package-4.28 {Tcl_PackageCmd procedure, "require" option} -body {
+    package require -exact x
+} -returnCodes error -result {wrong # args: should be "package require ?-exact? package ?requirement ...?"}
+test package-4.29 {Tcl_PackageCmd procedure, "require" option} -body {
+    package require -exact
+} -returnCodes error -result {wrong # args: should be "package require ?-exact? package ?requirement ...?"}
+test package-4.30 {Tcl_PackageCmd procedure, "require" option} -setup {
+    package forget t
+} -body {
+    package provide t 2.3
+    package require t 2.1
+} -result {2.3}
+test package-4.31 {Tcl_PackageCmd procedure, "require" option} -setup {
+    package forget t
+} -body {
+    package require t
+} -returnCodes error -result {can't find package t}
+test package-4.32 {Tcl_PackageCmd procedure, "require" option} -setup {
+    package forget t
+} -body {
+    package ifneeded t 2.3 "error {synthetic error}"
+    package require t 2.3
+} -returnCodes error -result {synthetic error}
+test package-4.33 {Tcl_PackageCmd procedure, "unknown" option} -body {
+    package unknown a b
+} -returnCodes error -result {wrong # args: should be "package unknown ?command?"}
+test package-4.34 {Tcl_PackageCmd procedure, "unknown" option} {
+    package unknown "test script"
+    package unknown
+} {test script}
+test package-4.35 {Tcl_PackageCmd procedure, "unknown" option} {
+    package unknown "test script"
+    package unknown {}
+    package unknown
+} {}
+test package-4.36 {Tcl_PackageCmd procedure, "vcompare" option} -body {
+    package vcompare a
+} -returnCodes error -result {wrong # args: should be "package vcompare version1 version2"}
+test package-4.37 {Tcl_PackageCmd procedure, "vcompare" option} -body {
+    package vcompare a b c
+} -returnCodes error -result {wrong # args: should be "package vcompare version1 version2"}
+test package-4.38 {Tcl_PackageCmd procedure, "vcompare" option} -body {
+    package vcompare x.y 3.4
+} -returnCodes error -result {expected version number but got "x.y"}
+test package-4.39 {Tcl_PackageCmd procedure, "vcompare" option} -body {
+    package vcompare 2.1 a.b
+} -returnCodes error -result {expected version number but got "a.b"}
+test package-4.40 {Tcl_PackageCmd procedure, "vcompare" option} {
+    package vc 2.1 2.3
+} {-1}
+test package-4.41 {Tcl_PackageCmd procedure, "vcompare" option} {
+    package vc 2.2.4 2.2.4
+} {0}
+test package-4.42 {Tcl_PackageCmd procedure, "versions" option} -body {
+    package versions
+} -returnCodes error -result {wrong # args: should be "package versions package"}
+test package-4.43 {Tcl_PackageCmd procedure, "versions" option} -body {
+    package versions a b
+} -returnCodes error -result {wrong # args: should be "package versions package"}
+test package-4.44 {Tcl_PackageCmd procedure, "versions" option} -body {
+    package forget t
+    package versions t
+} -result {}
+test package-4.45 {Tcl_PackageCmd procedure, "versions" option} -setup {
+    package forget t
+} -body {
+    package provide t 2.3
+    package versions t
+} -result {}
+test package-4.46 {Tcl_PackageCmd procedure, "versions" option} -setup {
+    package forget t
+} -body {
+    package ifneeded t 2.3 x
+    package ifneeded t 2.4 y
+    package versions t
+} -result {2.3 2.4}
+test package-4.47 {Tcl_PackageCmd procedure, "vsatisfies" option} -body {
+    package vsatisfies a
+} -returnCodes error -result {wrong # args: should be "package vsatisfies version ?requirement ...?"}
+test package-4.49 {Tcl_PackageCmd procedure, "vsatisfies" option} -body {
+    package vsatisfies x.y 3.4
+} -returnCodes error -result {expected version number but got "x.y"}
+test package-4.50 {Tcl_PackageCmd procedure, "vsatisfies" option} -body {
+    package vcompare 2.1 a.b
+} -returnCodes error -result {expected version number but got "a.b"}
+test package-4.51 {Tcl_PackageCmd procedure, "vsatisfies" option} {
+    package vs 2.3 2.1
+} {1}
+test package-4.52 {Tcl_PackageCmd procedure, "vsatisfies" option} {
+    package vs 2.3 1.2
+} {0}
+test package-4.53 {Tcl_PackageCmd procedure, "versions" option} -body {
+    package foo
+} -returnCodes error -result {bad option "foo": must be forget, ifneeded, names, prefer, present, provide, require, unknown, vcompare, versions, or vsatisfies}
+test package-4.54 {Tcl_PackageCmd procedure, "vsatisfies" option} -body {
+    package vsatisfies 2.1 2.1-3.2-4.5
+} -returnCodes error -result {expected versionMin-versionMax but got "2.1-3.2-4.5"}
+test package-4.55 {Tcl_PackageCmd procedure, "vsatisfies" option} -body {
+    package vsatisfies 2.1 3.2-x.y
+} -returnCodes error -result {expected version number but got "x.y"}
+test package-4.56 {Tcl_PackageCmd procedure, "vsatisfies" option} -body {
+    package vsatisfies 2.1 x.y-3.2
+} -returnCodes error -result {expected version number but got "x.y"}
+
+# No tests for FindPackage; can't think up anything detectable errors.
+
+test package-5.1 {TclFreePackageInfo procedure} {
+    interp create slave
+    slave eval {
+	package ifneeded t 2.3 x
+	package ifneeded t 2.4 y
+	package ifneeded x 3.1 z
+	package provide q 4.3
+	package unknown "will this get freed?"
+    }
+    interp delete slave
+} {}
+test package-5.2 {TclFreePackageInfo procedure} -body {
+    interp create foo
+    foo eval {
+	package ifneeded t 2.3 x
+	package ifneeded t 2.4 y
+	package ifneeded x 3.1 z
+	package provide q 4.3
+    }
+    foo alias z kill
+    proc kill {} {
+	interp delete foo
+    }
+    foo eval package require x 3.1
+} -returnCodes error -match glob -result *
+
+test package-6.1 {CheckVersion procedure} {
+    package vcompare 1 2.1
+} -1
+test package-6.2 {CheckVersion procedure} -body {
+    package vcompare .1 2.1
+} -returnCodes error -result {expected version number but got ".1"}
+test package-6.3 {CheckVersion procedure} -body {
+    package vcompare 111.2a.3 2.1
+} -returnCodes error -result {expected version number but got "111.2a.3"}
+test package-6.4 {CheckVersion procedure} -body {
+    package vcompare 1.2.3. 2.1
+} -returnCodes error -result {expected version number but got "1.2.3."}
+test package-6.5 {CheckVersion procedure} -body {
+    package vcompare 1.2..3 2.1
+} -returnCodes error -result {expected version number but got "1.2..3"}
+
+test package-7.1 {ComparePkgVersions procedure} {
+    package vcompare 1.23 1.22
+} {1}
+test package-7.2 {ComparePkgVersions procedure} {
+    package vcompare 1.22.1.2.3 1.22.1.2.3
+} {0}
+test package-7.3 {ComparePkgVersions procedure} {
+    package vcompare 1.21 1.22
+} {-1}
+test package-7.4 {ComparePkgVersions procedure} {
+    package vcompare 1.21 1.21.2
+} {-1}
+test package-7.5 {ComparePkgVersions procedure} {
+    package vcompare 1.21.1 1.21
+} {1}
+test package-7.6 {ComparePkgVersions procedure} {
+    package vsatisfies 1.21.1 1.21
+} {1}
+test package-7.7 {ComparePkgVersions procedure} {
+    package vsatisfies 2.22.3 1.21
+} {0}
+test package-7.8 {ComparePkgVersions procedure} {
+    package vsatisfies 1 1
+} {1}
+test package-7.9 {ComparePkgVersions procedure} {
+    package vsatisfies 2 1
+} {0}
+
+test package-8.1 {Tcl_PkgPresent procedure, any version} -setup {
+    package forget t
+} -body {
+    package provide t 2.4
+    package present t
+} -result {2.4}
+test package-8.2 {Tcl_PkgPresent procedure, correct version} -setup {
+    package forget t
+} -body {
+    package provide t 2.4
+    package present t 2.4
+} -result {2.4}
+test package-8.3 {Tcl_PkgPresent procedure, satisfying version} -setup {
+    package forget t
+} -body {
+    package provide t 2.4
+    package present t 2.0
+} -result {2.4}
+test package-8.4 {Tcl_PkgPresent procedure, not satisfying version} -setup {
+    package forget t
+} -returnCodes error -body {
+    package provide t 2.4
+    package present t 2.6
+} -result {version conflict for package "t": have 2.4, need 2.6}
+test package-8.5 {Tcl_PkgPresent procedure, not satisfying version} -setup {
+    package forget t
+} -returnCodes error -body {
+    package provide t 2.4
+    package present t 1.0
+} -result {version conflict for package "t": have 2.4, need 1.0}
+test package-8.6 {Tcl_PkgPresent procedure, exact version} -setup {
+    package forget t
+} -body {
+    package provide t 2.4
+    package present -exact t 2.4
+} -result {2.4}
+test package-8.7 {Tcl_PkgPresent procedure, not exact version} -setup {
+    package forget t
+} -returnCodes error -body {
+    package provide t 2.4
+    package present -exact t 2.3
+} -result {version conflict for package "t": have 2.4, need exactly 2.3}
+test package-8.8 {Tcl_PkgPresent procedure, unknown package} -body {
+    package forget t
+    package present t
+} -returnCodes error -result {package t is not present}
+test package-8.9 {Tcl_PkgPresent procedure, unknown package} -body {
+    package forget t
+    package present t 2.4
+} -returnCodes error -result {package t 2.4 is not present}
+test package-8.10 {Tcl_PkgPresent procedure, unknown package} -body {
+    package forget t
+    package present -exact t 2.4
+} -returnCodes error -result {package t 2.4 is not present}
+test package-8.11 {Tcl_PackageCmd procedure, "present" option} -body {
+    package present
+} -returnCodes error -result {wrong # args: should be "package present ?-exact? package ?requirement ...?"}
+test package-8.12 {Tcl_PackageCmd procedure, "present" option} -body {
+    package present a b c
+} -returnCodes error -result {expected version number but got "b"}
+test package-8.13 {Tcl_PackageCmd procedure, "present" option} -body {
+    package present -exact a b c
+} -returnCodes error -result {wrong # args: should be "package present ?-exact? package ?requirement ...?"}
+test package-8.14 {Tcl_PackageCmd procedure, "present" option} -body {
+    package present -bs a b
+} -returnCodes error -result {expected version number but got "a"}
+test package-8.15 {Tcl_PackageCmd procedure, "present" option} -body {
+    package present x a.b
+} -returnCodes error -result {expected version number but got "a.b"}
+test package-8.16 {Tcl_PackageCmd procedure, "present" option} -body {
+    package present -exact x a.b
+} -returnCodes error -result {expected version number but got "a.b"}
+test package-8.17 {Tcl_PackageCmd procedure, "present" option} -body {
+    package present -exact x
+} -returnCodes error -result {wrong # args: should be "package present ?-exact? package ?requirement ...?"}
+test package-8.18 {Tcl_PackageCmd procedure, "present" option} -body {
+    package present -exact
+} -returnCodes error -result {wrong # args: should be "package present ?-exact? package ?requirement ...?"}
+
+set n 0
+foreach {r p vs vc} {
+    8.5a0    8.5a5    1          -1
+    8.5a0    8.5b1    1          -1
+    8.5a0    8.5.1    1          -1
+    8.5a0    8.6a0    1          -1
+    8.5a0    8.6b0    1          -1
+    8.5a0    8.6.0    1          -1
+    8.5a6    8.5a5    0          1
+    8.5a6    8.5b1    1          -1
+    8.5a6    8.5.1    1          -1
+    8.5a6    8.6a0    1          -1
+    8.5a6    8.6b0    1          -1
+    8.5a6    8.6.0    1          -1
+    8.5b0    8.5a5    0          1
+    8.5b0    8.5b1    1          -1
+    8.5b0    8.5.1    1          -1
+    8.5b0    8.6a0    1          -1
+    8.5b0    8.6b0    1          -1
+    8.5b0    8.6.0    1          -1
+    8.5b2    8.5a5    0          1
+    8.5b2    8.5b1    0          1
+    8.5b2    8.5.1    1          -1
+    8.5b2    8.6a0    1          -1
+    8.5b2    8.6b0    1          -1
+    8.5b2    8.6.0    1          -1
+    8.5      8.5a5    1          1
+    8.5      8.5b1    1          1
+    8.5      8.5.1    1          -1
+    8.5      8.6a0    1          -1
+    8.5      8.6b0    1          -1
+    8.5      8.6.0    1          -1
+    8.5.0    8.5a5    0          1
+    8.5.0    8.5b1    0          1
+    8.5.0    8.5.1    1          -1
+    8.5.0    8.6a0    1          -1
+    8.5.0    8.6b0    1          -1
+    8.5.0    8.6.0    1          -1
+    10       8        0          1
+    8        10       0          -1
+    0.0.1.2  0.1.2    1          -1
+} {
+    test package-9.$n {package vsatisfies} {
+	package vsatisfies $p $r
+    } $vs
+    test package-10.$n {package vcompare} {
+	package vcompare $r $p
+    } $vc
+    incr n
+}
+
+test package-11.0.0 {package vcompare at 32bit boundary} {
+    package vcompare [expr {1<<31}] [expr {(1<<31)-1}]
+} 1
+
+# Note: It is correct that the result of the very first test, i.e. "5.0 5.0a0"
+# is 1, i.e. that version 5.0a0 satisfies a 5.0 requirement.
+
+# The requirement "5.0" internally translates first to "5.0-6", and then to
+# its final form of "5.0a0-6a0". These translations are explicitly specified
+# by the TIP (Search for "padded/extended internally with 'a0'"). This was
+# done intentionally for exactly the tested case, that an alpha package can
+# satisfy a requirement for the regular package. An example would be a package
+# FOO requiring Tcl 8.X for its operation. It can be used with Tcl 8.Xa0.
+# Without our translation that would not be possible.
+
+set n 0
+foreach {required provided satisfied} {
+    5.0 5.0a0 1
+    5.0a0 5.0 1
+
+    8.5a0-   8.5a5    1
+    8.5a0-   8.5b1    1
+    8.5a0-   8.5.1    1
+    8.5a0-   8.6a0    1
+    8.5a0-   8.6b0    1
+    8.5a0-   8.6.0    1
+    8.5a6-   8.5a5    0
+    8.5a6-   8.5b1    1
+    8.5a6-   8.5.1    1
+    8.5a6-   8.6a0    1
+    8.5a6-   8.6b0    1
+    8.5a6-   8.6.0    1
+    8.5b0-   8.5a5    0
+    8.5b0-   8.5b1    1
+    8.5b0-   8.5.1    1
+    8.5b0-   8.6a0    1
+    8.5b0-   8.6b0    1
+    8.5b0-   8.6.0    1
+    8.5b2-   8.5a5    0
+    8.5b2-   8.5b1    0
+    8.5b2-   8.5.1    1
+    8.5b2-   8.6a0    1
+    8.5b2-   8.6b0    1
+    8.5b2-   8.6.0    1
+    8.5-     8.5a5    1
+    8.5-     8.5b1    1
+    8.5-     8.5.1    1
+    8.5-     8.6a0    1
+    8.5-     8.6b0    1
+    8.5-     8.6.0    1
+    8.5.0-   8.5a5    0
+    8.5.0-   8.5b1    0
+    8.5.0-   8.5.1    1
+    8.5.0-   8.6a0    1
+    8.5.0-   8.6b0    1
+    8.5.0-   8.6.0    1
+    8.5a0-7  8.5a5    0
+    8.5a0-7  8.5b1    0
+    8.5a0-7  8.5.1    0
+    8.5a0-7  8.6a0    0
+    8.5a0-7  8.6b0    0
+    8.5a0-7  8.6.0    0
+    8.5a6-7  8.5a5    0
+    8.5a6-7  8.5b1    0
+    8.5a6-7  8.5.1    0
+    8.5a6-7  8.6a0    0
+    8.5a6-7  8.6b0    0
+    8.5a6-7  8.6.0    0
+    8.5b0-7  8.5a5    0
+    8.5b0-7  8.5b1    0
+    8.5b0-7  8.5.1    0
+    8.5b0-7  8.6a0    0
+    8.5b0-7  8.6b0    0
+    8.5b0-7  8.6.0    0
+    8.5b2-7  8.5a5    0
+    8.5b2-7  8.5b1    0
+    8.5b2-7  8.5.1    0
+    8.5b2-7  8.6a0    0
+    8.5b2-7  8.6b0    0
+    8.5b2-7  8.6.0    0
+    8.5-7    8.5a5    0
+    8.5-7    8.5b1    0
+    8.5-7    8.5.1    0
+    8.5-7    8.6a0    0
+    8.5-7    8.6b0    0
+    8.5-7    8.6.0    0
+    8.5.0-7  8.5a5    0
+    8.5.0-7  8.5b1    0
+    8.5.0-7  8.5.1    0
+    8.5.0-7  8.6a0    0
+    8.5.0-7  8.6b0    0
+    8.5.0-7  8.6.0    0
+    8.5a0-8.6.1 8.5a5    1
+    8.5a0-8.6.1 8.5b1    1
+    8.5a0-8.6.1 8.5.1    1
+    8.5a0-8.6.1 8.6a0    1
+    8.5a0-8.6.1 8.6b0    1
+    8.5a0-8.6.1 8.6.0    1
+    8.5a6-8.6.1 8.5a5    0
+    8.5a6-8.6.1 8.5b1    1
+    8.5a6-8.6.1 8.5.1    1
+    8.5a6-8.6.1 8.6a0    1
+    8.5a6-8.6.1 8.6b0    1
+    8.5a6-8.6.1 8.6.0    1
+    8.5b0-8.6.1 8.5a5    0
+    8.5b0-8.6.1 8.5b1    1
+    8.5b0-8.6.1 8.5.1    1
+    8.5b0-8.6.1 8.6a0    1
+    8.5b0-8.6.1 8.6b0    1
+    8.5b0-8.6.1 8.6.0    1
+    8.5b2-8.6.1 8.5a5    0
+    8.5b2-8.6.1 8.5b1    0
+    8.5b2-8.6.1 8.5.1    1
+    8.5b2-8.6.1 8.6a0    1
+    8.5b2-8.6.1 8.6b0    1
+    8.5b2-8.6.1 8.6.0    1
+    8.5-8.6.1 8.5a5    1
+    8.5-8.6.1 8.5b1    1
+    8.5-8.6.1 8.5.1    1
+    8.5-8.6.1 8.6a0    1
+    8.5-8.6.1 8.6b0    1
+    8.5-8.6.1 8.6.0    1
+    8.5.0-8.6.1 8.5a5    0
+    8.5.0-8.6.1 8.5b1    0
+    8.5.0-8.6.1 8.5.1    1
+    8.5.0-8.6.1 8.6a0    1
+    8.5.0-8.6.1 8.6b0    1
+    8.5.0-8.6.1 8.6.0    1
+    8.5a0-8.5a0 8.5a0    1
+    8.5a0-8.5a0 8.5b1    0
+    8.5a0-8.5a0 8.4      0
+    8.5b0-8.5b0 8.5a5    0
+    8.5b0-8.5b0 8.5b0    1
+    8.5b0-8.5b0 8.5.1    0
+    8.5-8.5  8.5a5    0
+    8.5-8.5  8.5b1    0
+    8.5-8.5  8.5      1
+    8.5-8.5  8.5.1    0
+    8.5.0-8.5.0 8.5a5    0
+    8.5.0-8.5.0 8.5b1    0
+    8.5.0-8.5.0 8.5.0    1
+    8.5.0-8.5.0 8.5.1    0
+    8.5.0-8.5.0 8.6a0    0
+    8.5.0-8.5.0 8.6b0    0
+    8.5.0-8.5.0 8.6.0    0
+    8.2      9        0
+    8.2-     9        1
+    8.2-8.5  9        0
+    8.2-9.1  9        1
+
+    8.5-8.5     8.5b1 0
+    8.5a0-8.5   8.5b1 0
+    8.5a0-8.5.1 8.5b1 1
+
+    8.5-8.5     8.5 1
+    8.5.0-8.5.0 8.5 1
+    8.5a0-8.5.0 8.5 0
+} {
+    test package-11.$n "package vsatisfies $provided $required" {
+	package vsatisfies $provided $required
+    } $satisfied
+    incr n
+}
+
+test package-12.0 "package vsatisfies multiple" {
+    #                      yes no
+    package vsatisfies 8.4 8.4 7.3
+} 1
+test package-12.1 "package vsatisfies multiple" {
+    #                      no  yes
+    package vsatisfies 8.4 7.3 8.4
+} 1
+test package-12.2 "package vsatisfies multiple" {
+    #                        yes  yes
+    package vsatisfies 8.4.2 8.4  8.4.1
+} 1
+test package-12.3 "package vsatisfies multiple" {
+    #                      no  no
+    package vsatisfies 8.4 7.3 6.1
+} 0
+
+proc prefer {args} {
+    set ip [interp create]
+    try {
+	lappend res [$ip eval {package prefer}]
+	foreach mode $args {
+	    lappend res [$ip eval [list package prefer $mode]]
+	}
+	return $res
+    } finally {
+	interp delete $ip
+    }
+}
+
+test package-13.0 {package prefer defaults} {
+    prefer
+} stable
+test package-13.1 {package prefer defaults} -body {
+    set ::env(TCL_PKG_PREFER_LATEST) stable	;# value not relevant!
+    prefer
+} -cleanup {
+    unset -nocomplain ::env(TCL_PKG_PREFER_LATEST)
+} -result latest
+
+test package-14.0 {wrong\#args} -returnCodes error -body {
+    package prefer foo bar
+} -result {wrong # args: should be "package prefer ?latest|stable?"}
+test package-14.1 {bogus argument} -returnCodes error -body {
+    package prefer foo
+} -result {bad preference "foo": must be latest or stable}
+
+test package-15.0 {set, keep} {package prefer stable} stable
+test package-15.1 {set stable, keep} {prefer stable} {stable stable}
+test package-15.2 {set latest, change} {prefer latest} {stable latest}
+test package-15.3 {set latest, keep} {
+    prefer latest latest
+} {stable latest latest}
+test package-15.4 {set stable, rejected} {
+    prefer latest stable
+} {stable latest latest}
+
+rename prefer {}
+
+set auto_path $oldPath
+package unknown $oldPkgUnknown
+
+cleanupTests
+}
+
+# cleanup
+interp delete $i
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# fill-column: 78
+# End:
diff --git a/tests/parse.test b/tests/parse.test
new file mode 100644
index 0000000..d73c725
--- /dev/null
+++ b/tests/parse.test
@@ -0,0 +1,1138 @@
+# This file contains a collection of tests for the procedures in the
+# file tclParse.c.  Sourcing this file into Tcl runs the tests and
+# generates output for errors.  No output means no errors were found.
+#
+# Copyright (c) 1997 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[catch {package require tcltest 2.0.2}]} {
+    puts stderr "Skipping tests in [info script]. tcltest 2.0.2 required."
+    return
+}
+
+namespace eval ::tcl::test::parse {
+    namespace import ::tcltest::*
+
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
+
+testConstraint testparser [llength [info commands testparser]]
+testConstraint testbytestring [llength [info commands testbytestring]]
+testConstraint testevalobjv [llength [info commands testevalobjv]]
+testConstraint testevalex [llength [info commands testevalex]]
+testConstraint testparsevarname [llength [info commands testparsevarname]]
+testConstraint testparsevar [llength [info commands testparsevar]]
+testConstraint testasync [llength [info commands testasync]]
+testConstraint testcmdtrace [llength [info commands testcmdtrace]]
+testConstraint testevent [llength [info commands testevent]]
+testConstraint memory [llength [info commands memory]]
+
+test parse-1.1 {Tcl_ParseCommand procedure, computing string length} {testparser testbytestring} {
+    testparser [testbytestring "foo\0 bar"] -1
+} {- foo 1 simple foo 1 text foo 0 {}}
+test parse-1.2 {Tcl_ParseCommand procedure, computing string length} testparser {
+    testparser "foo bar" -1
+} {- {foo bar} 2 simple foo 1 text foo 0 simple bar 1 text bar 0 {}}
+test parse-1.3 {Tcl_ParseCommand procedure, leading space} testparser {
+    testparser "  \n\t   foo" 0
+} {- foo 1 simple foo 1 text foo 0 {}}
+test parse-1.4 {Tcl_ParseCommand procedure, leading space} testparser {
+    testparser "\f\r\vfoo" 0
+} {- foo 1 simple foo 1 text foo 0 {}}
+test parse-1.5 {Tcl_ParseCommand procedure, backslash-newline in leading space} testparser {
+    testparser "  \\\n foo" 0
+} {- foo 1 simple foo 1 text foo 0 {}}
+test parse-1.6 {Tcl_ParseCommand procedure, backslash-newline in leading space} testparser {
+    testparser {  \a foo} 0
+} {- {\a foo} 2 word {\a} 1 backslash {\a} 0 simple foo 1 text foo 0 {}}
+test parse-1.7 {Tcl_ParseCommand procedure, missing continuation line in leading space} testparser {
+    testparser "   \\\n" 0
+} {- {} 0 {}}
+test parse-1.8 {Tcl_ParseCommand procedure, eof in leading space} testparser {
+    testparser "      foo" 3
+} {- {} 0 {   foo}}
+test parse-1.9 {Tcl_ParseCommand procedure, backslash newline + newline} testparser {
+    testparser "cmd1\\\n\ncmd2" 0
+} {- cmd1\\\n\n 1 simple cmd1 1 text cmd1 0 cmd2}
+test parse-1.10 {Tcl_ParseCommand procedure, backslash newline + newline} testparser {
+    testparser "list \\\nA B\\\n\nlist C D" 0
+} {- list\ \\\nA\ B\\\n\n 3 simple list 1 text list 0 simple A 1 text A 0 simple B 1 text B 0 {list C D}}
+
+test parse-2.1 {Tcl_ParseCommand procedure, comments} testparser {
+    testparser "# foo bar\n foo" 0
+} {{# foo bar
+} foo 1 simple foo 1 text foo 0 {}}
+test parse-2.2 {Tcl_ParseCommand procedure, several comments} testparser {
+    testparser " # foo bar\n # another comment\n\n   foo" 0
+} {{# foo bar
+ # another comment
+} foo 1 simple foo 1 text foo 0 {}}
+test parse-2.3 {Tcl_ParseCommand procedure, backslash-newline in comments} testparser {
+    testparser " # foo bar\\\ncomment on continuation line\nfoo" 0
+} {\#\ foo\ bar\\\ncomment\ on\ continuation\ line\n foo 1 simple foo 1 text foo 0 {}}
+test parse-2.4 {Tcl_ParseCommand procedure, missing continuation line in comment} testparser {
+    testparser "#   \\\n" 0
+} {\#\ \ \ \\\n {} 0 {}}
+test parse-2.5 {Tcl_ParseCommand procedure, eof in comment} testparser {
+    testparser " # foo bar\nfoo" 8
+} {{# foo b} {} 0 {ar
+foo}}
+
+test parse-3.1 {Tcl_ParseCommand procedure, parsing words, skipping space} testparser {
+    testparser "foo  bar\t\tx" 0
+} {- {foo  bar		x} 3 simple foo 1 text foo 0 simple bar 1 text bar 0 simple x 1 text x 0 {}}
+test parse-3.2 {Tcl_ParseCommand procedure, missing continuation line in leading space} testparser {
+    testparser "abc  \\\n" 0
+} {- abc\ \ \\\n 1 simple abc 1 text abc 0 {}}
+test parse-3.3 {Tcl_ParseCommand procedure, parsing words, command ends in space} testparser {
+    testparser "foo  ;  bar x" 0
+} {- {foo  ;} 1 simple foo 1 text foo 0 {  bar x}}
+test parse-3.4 {Tcl_ParseCommand procedure, parsing words, command ends in space} testparser {
+    testparser "foo       " 5
+} {- {foo  } 1 simple foo 1 text foo 0 {     }}
+test parse-3.5 {Tcl_ParseCommand procedure, quoted words} testparser {
+    testparser {foo "a b c" d "efg";} 0
+} {- {foo "a b c" d "efg";} 4 simple foo 1 text foo 0 simple {"a b c"} 1 text {a b c} 0 simple d 1 text d 0 simple {"efg"} 1 text efg 0 {}}
+test parse-3.6 {Tcl_ParseCommand procedure, words in braces} testparser {
+    testparser {foo {a $b [concat foo]} {c d}} 0
+} {- {foo {a $b [concat foo]} {c d}} 3 simple foo 1 text foo 0 simple {{a $b [concat foo]}} 1 text {a $b [concat foo]} 0 simple {{c d}} 1 text {c d} 0 {}}
+test parse-3.7 {Tcl_ParseCommand procedure, error in unquoted word} testparser {
+    list [catch {testparser "foo \$\{abc" 0} msg] $msg $::errorInfo
+} {1 {missing close-brace for variable name} missing\ close-brace\ for\ variable\ name\n\ \ \ \ (remainder\ of\ script:\ \"\{abc\")\n\ \ \ \ invoked\ from\ within\n\"testparser\ \"foo\ \\\$\\\{abc\"\ 0\"}
+
+test parse-4.1 {Tcl_ParseCommand procedure, simple words} testparser {
+    testparser {foo} 0
+} {- foo 1 simple foo 1 text foo 0 {}}
+test parse-4.2 {Tcl_ParseCommand procedure, simple words} testparser {
+    testparser {{abc}} 0
+} {- {{abc}} 1 simple {{abc}} 1 text abc 0 {}}
+test parse-4.3 {Tcl_ParseCommand procedure, simple words} testparser {
+    testparser {"c d"} 0
+} {- {"c d"} 1 simple {"c d"} 1 text {c d} 0 {}}
+test parse-4.4 {Tcl_ParseCommand procedure, simple words} testparser {
+    testparser {x$d} 0
+} {- {x$d} 1 word {x$d} 3 text x 0 variable {$d} 1 text d 0 {}}
+test parse-4.5 {Tcl_ParseCommand procedure, simple words} testparser {
+    testparser {"a [foo] b"} 0
+} {- {"a [foo] b"} 1 word {"a [foo] b"} 3 text {a } 0 command {[foo]} 0 text { b} 0 {}}
+test parse-4.6 {Tcl_ParseCommand procedure, simple words} testparser {
+    testparser {$x} 0
+} {- {$x} 1 word {$x} 2 variable {$x} 1 text x 0 {}}
+
+test parse-5.1 {Tcl_ParseCommand procedure, backslash-newline terminates word} testparser {
+    testparser "{abc}\\\n" 0
+} {- \{abc\}\\\n 1 simple {{abc}} 1 text abc 0 {}}
+test parse-5.2 {Tcl_ParseCommand procedure, backslash-newline terminates word} testparser {
+    testparser "foo\\\nbar" 0
+} {- foo\\\nbar 2 simple foo 1 text foo 0 simple bar 1 text bar 0 {}}
+test parse-5.3 {Tcl_ParseCommand procedure, word terminator is command terminator} testparser {
+    testparser "foo\n bar" 0
+} {- {foo
+} 1 simple foo 1 text foo 0 { bar}}
+test parse-5.4 {Tcl_ParseCommand procedure, word terminator is command terminator} testparser {
+    testparser "foo; bar" 0
+} {- {foo;} 1 simple foo 1 text foo 0 { bar}}
+test parse-5.5 {Tcl_ParseCommand procedure, word terminator is end of string} testparser {
+    testparser "\"foo\" bar" 5
+} {- {"foo"} 1 simple {"foo"} 1 text foo 0 { bar}}
+test parse-5.6 {Tcl_ParseCommand procedure, junk after close quote} testparser {
+    list [catch {testparser {foo "bar"x} 0} msg] $msg $::errorInfo
+} {1 {extra characters after close-quote} {extra characters after close-quote
+    (remainder of script: "x")
+    invoked from within
+"testparser {foo "bar"x} 0"}}
+test parse-5.7 {Tcl_ParseCommand procedure, backslash-newline after close quote} testparser {
+    testparser "foo \"bar\"\\\nx" 0
+} {- foo\ \"bar\"\\\nx 3 simple foo 1 text foo 0 simple {"bar"} 1 text bar 0 simple x 1 text x 0 {}}
+test parse-5.8 {Tcl_ParseCommand procedure, junk after close brace} testparser {
+    list [catch {testparser {foo {bar}x} 0} msg] $msg $::errorInfo
+} {1 {extra characters after close-brace} {extra characters after close-brace
+    (remainder of script: "x")
+    invoked from within
+"testparser {foo {bar}x} 0"}}
+test parse-5.9 {Tcl_ParseCommand procedure, backslash-newline after close brace} testparser {
+    testparser "foo {bar}\\\nx" 0
+} {- foo\ \{bar\}\\\nx 3 simple foo 1 text foo 0 simple {{bar}} 1 text bar 0 simple x 1 text x 0 {}}
+test parse-5.10 {Tcl_ParseCommand procedure, multiple deletion of non-static buffer} testparser {
+    # This test is designed to catch bug 1681.
+    list [catch {testparser "a \"\\1\\2\\3\\4\\5\\6\\7\\8\\9\\1\\2\\3\\4\\5\\6\\7\\8" 0} msg] $msg $::errorInfo
+} "1 {missing \"} {missing \"
+    (remainder of script: \"\"\\1\\2\\3\\4\\5\\6\\7\\8\\9\\1\\2\\3\\4\\5\\6\\7\\8\")
+    invoked from within
+\"testparser \"a \\\"\\\\1\\\\2\\\\3\\\\4\\\\5\\\\6\\\\7\\\\8\\\\9\\\\1\\\\2\\\\3\\\\4\\\\5\\\\6\\\\7\\\\8\" 0\"}"
+
+test parse-5.11 {Tcl_ParseCommand: {*} parsing} testparser {
+    testparser {{expan}} 0
+} {- {{expan}} 1 simple {{expan}} 1 text expan 0 {}}
+test parse-5.12 {Tcl_ParseCommand: {*} parsing} -constraints {
+    testparser
+} -body {
+    testparser {{expan}x} 0
+} -returnCodes error  -result {extra characters after close-brace}
+test parse-5.13 {Tcl_ParseCommand: {*} parsing} testparser {
+    testparser {{**}} 0
+} {- {{**}} 1 simple {{**}} 1 text ** 0 {}}
+test parse-5.14 {Tcl_ParseCommand: {*} parsing} -constraints {
+    testparser
+} -body {
+    testparser {{**}x} 0
+} -returnCodes error  -result {extra characters after close-brace}
+test parse-5.15 {Tcl_ParseCommand: {*} parsing} -constraints {
+    testparser
+} -body {
+    testparser {{*}{123456}x} 0
+} -returnCodes error  -result {extra characters after close-brace}
+test parse-5.16 {Tcl_ParseCommand: {*} parsing} testparser {
+    testparser {{123456\
+			}} 0
+} {- {{123456 }} 1 simple {{123456 }} 1 text {123456 } 0 {}}
+test parse-5.17 {Tcl_ParseCommand: {*} parsing} -constraints {
+    testparser
+} -body {
+    testparser {{123456\
+			}x} 0
+} -returnCodes error  -result {extra characters after close-brace}
+test parse-5.18 {Tcl_ParseCommand: {*} parsing} testparser {
+    testparser {{*\
+			}} 0
+} {- {{* }} 1 simple {{* }} 1 text {* } 0 {}}
+test parse-5.19 {Tcl_ParseCommand: {*} parsing} -constraints {
+    testparser
+} -body {
+    testparser {{*\
+			}x} 0
+} -returnCodes error  -result {extra characters after close-brace}
+test parse-5.20 {Tcl_ParseCommand: {*} parsing} testparser {
+    testparser {{123456}} 0
+} {- {{123456}} 1 simple {{123456}} 1 text 123456 0 {}}
+test parse-5.21 {Tcl_ParseCommand: {*} parsing} -constraints {
+    testparser
+} -body {
+    testparser {{123456}x} 0
+} -returnCodes error  -result {extra characters after close-brace}
+test parse-5.22 {Tcl_ParseCommand: {*} parsing} testparser {
+    testparser {{*}} 0
+} {- {{*}} 1 simple {{*}} 1 text * 0 {}}
+test parse-5.23 {Tcl_ParseCommand: {*} parsing} testparser {
+    testparser {{*} } 0
+} {- {{*} } 1 simple {{*}} 1 text * 0 {}}
+test parse-5.24 {Tcl_ParseCommand: {*} parsing} testparser {
+    testparser {{*}x} 0
+} {- {{*}x} 1 simple x 1 text x 0 {}}
+test parse-5.25 {Tcl_ParseCommand: {*} parsing} testparser {
+    testparser {{*}
+} 0
+} {- {{*}
+} 1 simple {{*}} 1 text * 0 {}}
+test parse-5.26 {Tcl_ParseCommand: {*} parsing} testparser {
+    testparser {{*};} 0
+} {- {{*};} 1 simple {{*}} 1 text * 0 {}}
+test parse-5.27 {Tcl_ParseCommand: {*} parsing} testparser {
+    testparser "{*}\\\n foo bar" 0
+} {- \{*\}\\\n\ foo\ bar 3 simple {{*}} 1 text * 0 simple foo 1 text foo 0 simple bar 1 text bar 0 {}}
+test parse-5.28 {Tcl_ParseCommand: {*} parsing, expanded literals} testparser {
+    testparser {{*}{a b}} 0
+} {- {{*}{a b}} 2 simple a 1 text a 0 simple b 1 text b 0 {}}
+test parse-5.29 {Tcl_ParseCommand: {*} parsing, expanded literals, naked backslashes} testparser {
+    testparser {{*}{a \n b}} 0
+} {- {{*}{a \n b}} 1 expand {{*}{a \n b}} 1 text {a \n b} 0 {}}
+test parse-5.30 {Tcl_ParseCommand: {*} parsing, expanded literals} testparser {
+    testparser {{*}"a b"} 0
+} {- {{*}"a b"} 2 simple a 1 text a 0 simple b 1 text b 0 {}}
+test parse-5.31 {Tcl_ParseCommand: {*} parsing, expanded literals, naked backslashes} testparser {
+    testparser {{*}"a \n b"} 0
+} {- {{*}"a \n b"} 1 expand {{*}"a \n b"} 3 text {a } 0 backslash {\n} 0 text { b} 0 {}}
+
+test parse-6.1 {ParseTokens procedure, empty word} testparser {
+    testparser {""} 0
+} {- {""} 1 simple {""} 1 text {} 0 {}}
+test parse-6.2 {ParseTokens procedure, simple range} testparser {
+    testparser {"abc$x.e"} 0
+} {- {"abc$x.e"} 1 word {"abc$x.e"} 4 text abc 0 variable {$x} 1 text x 0 text .e 0 {}}
+test parse-6.3 {ParseTokens procedure, variable reference} testparser {
+    testparser {abc$x.e $y(z)} 0
+} {- {abc$x.e $y(z)} 2 word {abc$x.e} 4 text abc 0 variable {$x} 1 text x 0 text .e 0 word {$y(z)} 3 variable {$y(z)} 2 text y 0 text z 0 {}}
+test parse-6.4 {ParseTokens procedure, variable reference} testparser {
+    list [catch {testparser {$x([a )} 0} msg] $msg
+} {1 {missing close-bracket}}
+test parse-6.5 {ParseTokens procedure, command substitution} testparser {
+    testparser {[foo $x bar]z} 0
+} {- {[foo $x bar]z} 1 word {[foo $x bar]z} 2 command {[foo $x bar]} 0 text z 0 {}}
+test parse-6.6 {ParseTokens procedure, command substitution} testparser {
+    testparser {[foo \] [a b]]} 0
+} {- {[foo \] [a b]]} 1 word {[foo \] [a b]]} 1 command {[foo \] [a b]]} 0 {}}
+test parse-6.7 {ParseTokens procedure, error in command substitution} testparser {
+    list [catch {testparser {a [b {}c d] e} 0} msg] $msg $::errorInfo
+} {1 {extra characters after close-brace} {extra characters after close-brace
+    (remainder of script: "c d] e")
+    invoked from within
+"testparser {a [b {}c d] e} 0"}}
+test parse-6.8 {ParseTokens procedure, error in command substitution} {
+    info complete {a [b {}c d]}
+} {1}
+test parse-6.9 {ParseTokens procedure, error in command substitution} {
+    info complete {a [b "c d}
+} {0}
+test parse-6.10 {ParseTokens procedure, incomplete sub-command} {
+    info complete {puts [
+	expr 1+1
+	#this is a comment ]}
+} {0}
+test parse-6.11 {ParseTokens procedure, memory allocation for big nested command} testparser {
+    testparser {[$a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b)]} 0
+} {- {[$a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b)]} 1 word {[$a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b)]} 1 command {[$a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b)]} 0 {}}
+test parse-6.12 {ParseTokens procedure, missing close bracket} testparser {
+    list [catch {testparser {[foo $x bar} 0} msg] $msg $::errorInfo
+} {1 {missing close-bracket} {missing close-bracket
+    (remainder of script: "[foo $x bar")
+    invoked from within
+"testparser {[foo $x bar} 0"}}
+test parse-6.13 {ParseTokens procedure, backslash-newline without continuation line} testparser {
+    list [catch {testparser "\"a b\\\n" 0} msg] $msg $::errorInfo
+} {1 {missing "} missing\ \"\n\ \ \ \ (remainder\ of\ script:\ \"\"a\ b\\\n\")\n\ \ \ \ invoked\ from\ within\n\"testparser\ \"\\\"a\ b\\\\\\n\"\ 0\"}
+test parse-6.14 {ParseTokens procedure, backslash-newline} testparser {
+    testparser "b\\\nc" 0
+} {- b\\\nc 2 simple b 1 text b 0 simple c 1 text c 0 {}}
+test parse-6.15 {ParseTokens procedure, backslash-newline} testparser {
+    testparser "\"b\\\nc\"" 0
+} {- \"b\\\nc\" 1 word \"b\\\nc\" 3 text b 0 backslash \\\n 0 text c 0 {}}
+test parse-6.16 {ParseTokens procedure, backslash substitution} testparser {
+    testparser {\n\a\x7f} 0
+} {- {\n\a\x7f} 1 word {\n\a\x7f} 3 backslash {\n} 0 backslash {\a} 0 backslash {\x7f} 0 {}}
+test parse-6.17 {ParseTokens procedure, null characters} {testparser testbytestring} {
+    expr {[testparser [testbytestring "foo\0zz"] 0] eq
+"- [testbytestring foo\0zz] 1 word [testbytestring foo\0zz] 3 text foo 0 text [testbytestring \0] 0 text zz 0 {}"
+	}
+} 1
+test parse-6.18 {ParseTokens procedure, seek past numBytes for close-bracket} testparser {
+    # Test for Bug 681841
+    list [catch {testparser {[a]} 2} msg] $msg
+} {1 {missing close-bracket}}
+
+test parse-7.1 {Tcl_FreeParse and ExpandTokenArray procedures} testparser {
+    testparser {$a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) } 0
+} {- {$a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) $a(b) } 16 word {$a(b)} 3 variable {$a(b)} 2 text a 0 text b 0 word {$a(b)} 3 variable {$a(b)} 2 text a 0 text b 0 word {$a(b)} 3 variable {$a(b)} 2 text a 0 text b 0 word {$a(b)} 3 variable {$a(b)} 2 text a 0 text b 0 word {$a(b)} 3 variable {$a(b)} 2 text a 0 text b 0 word {$a(b)} 3 variable {$a(b)} 2 text a 0 text b 0 word {$a(b)} 3 variable {$a(b)} 2 text a 0 text b 0 word {$a(b)} 3 variable {$a(b)} 2 text a 0 text b 0 word {$a(b)} 3 variable {$a(b)} 2 text a 0 text b 0 word {$a(b)} 3 variable {$a(b)} 2 text a 0 text b 0 word {$a(b)} 3 variable {$a(b)} 2 text a 0 text b 0 word {$a(b)} 3 variable {$a(b)} 2 text a 0 text b 0 word {$a(b)} 3 variable {$a(b)} 2 text a 0 text b 0 word {$a(b)} 3 variable {$a(b)} 2 text a 0 text b 0 word {$a(b)} 3 variable {$a(b)} 2 text a 0 text b 0 word {$a(b)} 3 variable {$a(b)} 2 text a 0 text b 0 {}}
+
+test parse-8.1 {Tcl_EvalObjv procedure} testevalobjv {
+    testevalobjv 0 concat this is a test
+} {this is a test}
+test parse-8.2 {Tcl_EvalObjv procedure, unknown commands} testevalobjv {
+    rename ::unknown unknown.old
+    set x [catch {testevalobjv 10 asdf poiu} msg]
+    rename unknown.old ::unknown
+    list $x $msg
+} {1 {invalid command name "asdf"}}
+test parse-8.3 {Tcl_EvalObjv procedure, unknown commands} testevalobjv {
+    rename ::unknown unknown.old
+    proc ::unknown args {
+	return "unknown $args"
+    }
+    set x [catch {testevalobjv 0 asdf poiu} msg]
+    rename ::unknown {}
+    rename unknown.old ::unknown
+    list $x $msg
+} {0 {unknown asdf poiu}}
+test parse-8.4 {Tcl_EvalObjv procedure, unknown commands} testevalobjv {
+    rename ::unknown unknown.old
+    proc ::unknown args {
+	error "I don't like that command"
+    }
+    set x [catch {testevalobjv 0 asdf poiu} msg]
+    rename ::unknown {}
+    rename unknown.old ::unknown
+    list $x $msg
+} {1 {I don't like that command}}
+test parse-8.5 {Tcl_EvalObjv procedure, command traces} {testevalobjv testcmdtrace} {
+    testevalobjv 0 set x 123
+    testcmdtrace tracetest {testevalobjv 0 set x $x}
+} {{testevalobjv 0 set x $x} {testevalobjv 0 set x 123} {set x 123} {set x 123}}
+test parse-8.7 {Tcl_EvalObjv procedure, TCL_EVAL_GLOBAL flag} -constraints {
+    testevalobjv
+} -setup {
+    proc x {} {
+	set y 23
+	set z [testevalobjv 1 set y]
+	return [list $z $y]
+    }
+    set ::y 16
+} -cleanup {
+    unset ::y
+} -body {
+    x
+} -result {16 23}
+test parse-8.8 {Tcl_EvalObjv procedure, async handlers} -constraints {
+    testevalobjv testasync
+} -setup {
+    variable ::aresult
+    variable ::acode
+    proc async1 {result code} {
+	variable ::aresult 
+	variable ::acode
+	set aresult $result
+	set acode $code
+	return "new result"
+    }
+    set handler1 [testasync create async1]
+    set aresult xxx
+    set acode yyy
+} -cleanup {
+    testasync delete
+} -body {
+    list [testevalobjv 0 testasync mark $handler1 original 0] $acode $aresult
+} -result {{new result} 0 original}
+test parse-8.9 {Tcl_EvalObjv procedure, exceptional return} testevalobjv {
+    list [catch {testevalobjv 0 error message} msg] $msg
+} {1 message}
+test parse-8.10 {Tcl_EvalObjv procedure, TCL_EVAL_GLOBAL} testevalobjv {
+    rename ::unknown unknown.save
+    proc ::unknown args {lappend ::info [info level]}
+    catch {rename ::noSuchCommand {}}
+    set ::info {}
+    namespace eval test_ns_1 {
+       testevalobjv 1 noSuchCommand
+       uplevel #0 noSuchCommand
+    }
+    namespace delete test_ns_1
+    rename ::unknown {}
+    rename unknown.save ::unknown
+    set ::info
+} {1 1}
+test parse-8.11 {Tcl_EvalObjv procedure, TCL_EVAL_INVOKE} testevalobjv {
+    rename ::unknown unknown.save
+    proc ::unknown args {lappend ::info [info level]; uplevel 1 foo}
+    proc ::foo args {lappend ::info global}
+    catch {rename ::noSuchCommand {}}
+    set ::slave [interp create]
+    $::slave alias bar noSuchCommand
+    set ::info {}
+    namespace eval test_ns_1 {
+       proc foo args {lappend ::info namespace}
+       $::slave eval bar
+       testevalobjv 1 [list $::slave eval bar]
+       uplevel #0 [list $::slave eval bar]
+    }
+    namespace delete test_ns_1
+    rename ::foo {}
+    rename ::unknown {}
+    rename unknown.save ::unknown
+    set ::info
+} [subst {[set level 2; incr level [info level]] global 1 global 1 global}]
+test parse-8.12 {Tcl_EvalObjv procedure, TCL_EVAL_INVOKE} {
+    set ::auto_index(noSuchCommand) {
+        proc noSuchCommand {} {lappend ::info global}
+    }
+    set ::auto_index(::[string trimleft [namespace current]::test_ns_1::noSuchCommand :]) [list \
+        proc [namespace current]::test_ns_1::noSuchCommand {} {
+            lappend ::info ns
+        }]
+    catch {rename ::noSuchCommand {}}
+    set ::slave [interp create]
+    $::slave alias bar noSuchCommand
+    set ::info {}
+    namespace eval test_ns_1 {
+        $::slave eval bar
+    }
+    namespace delete test_ns_1
+    interp delete $::slave
+    catch {rename ::noSuchCommand {}}
+    set ::info
+} global
+
+
+test parse-9.1 {Tcl_LogCommandInfo, line numbers} testevalex {
+    unset -nocomplain x
+    list [catch {testevalex {for {} 1 {} {
+
+
+	# asdf
+	set x
+    }}}] $::errorInfo
+} {1 {can't read "x": no such variable
+    while executing
+"set x"
+    ("for" body line 5)
+    invoked from within
+"for {} 1 {} {
+
+
+	# asdf
+	set x
+    }"
+    invoked from within
+"testevalex {for {} 1 {} {
+
+
+	# asdf
+	set x
+    }}"}}
+test parse-9.2 {Tcl_LogCommandInfo, truncating long commands} {
+    list [catch {set a b 111111111 222222222 333333333 444444444 555555555 666666666 777777777 888888888 999999999 000000000 aaaaaaaaa bbbbbbbbb ccccccccc ddddddddd eeeeeeeee fffffffff ggggggggg}] $::errorInfo
+} {1 {wrong # args: should be "set varName ?newValue?"
+    while executing
+"set a b 111111111 222222222 333333333 444444444 555555555 666666666 777777777 888888888 999999999 000000000 aaaaaaaaa bbbbbbbbb ccccccccc ddddddddd ee..."}}
+
+test parse-10.1 {Tcl_EvalTokens, simple text} testevalex {
+    testevalex {concat test}
+} {test}
+test parse-10.2 {Tcl_EvalTokens, backslash sequences} testevalex {
+    testevalex {concat test\063\062test}
+} {test32test}
+test parse-10.3 {Tcl_EvalTokens, nested commands} testevalex {
+    testevalex {concat [expr 2 + 6]}
+} {8}
+test parse-10.4 {Tcl_EvalTokens, nested commands} testevalex {
+    unset -nocomplain a
+    list [catch {testevalex {concat xxx[expr $a]}} msg] $msg
+} {1 {can't read "a": no such variable}}
+test parse-10.5 {Tcl_EvalTokens, simple variables} testevalex {
+    set a hello
+    testevalex {concat $a}
+} {hello}
+test parse-10.6 {Tcl_EvalTokens, array variables} testevalex {
+    unset -nocomplain a
+    set a(12) 46
+    testevalex {concat $a(12)}
+} {46}
+test parse-10.7 {Tcl_EvalTokens, array variables} testevalex {
+    unset -nocomplain a
+    set a(12) 46
+    testevalex {concat $a(1[expr 3 - 1])}
+} {46}
+test parse-10.8 {Tcl_EvalTokens, array variables} testevalex {
+    unset -nocomplain a
+    list [catch {testevalex {concat $x($a)}} msg] $msg
+} {1 {can't read "a": no such variable}}
+test parse-10.9 {Tcl_EvalTokens, array variables} testevalex {
+    unset -nocomplain a
+    list [catch {testevalex {concat xyz$a(1)}} msg] $msg
+} {1 {can't read "a(1)": no such variable}}
+test parse-10.10 {Tcl_EvalTokens, object values} testevalex {
+    set a 123
+    testevalex {concat $a}
+} {123}
+test parse-10.11 {Tcl_EvalTokens, object values} testevalex {
+    set a 123
+    testevalex {concat $a$a$a}
+} {123123123}
+test parse-10.12 {Tcl_EvalTokens, object values} testevalex {
+    testevalex {concat [expr 2][expr 4][expr 6]}
+} {246}
+test parse-10.13 {Tcl_EvalTokens, string values} testevalex {
+    testevalex {concat {a" b"}}
+} {a" b"}
+test parse-10.14 {Tcl_EvalTokens, string values} testevalex {
+    set a 111
+    testevalex {concat x$a.$a.$a}
+} {x111.111.111}
+
+test parse-11.1 {Tcl_EvalEx, TCL_EVAL_GLOBAL flag} -constraints {
+    testevalex
+} -setup {
+    proc x {} {
+	set y 777
+	set z [testevalex "set y" global]
+	return [list $z $y]
+    }
+    set ::y 321
+} -cleanup {
+    unset ::y
+} -body {
+    x
+} -result {321 777}
+test parse-11.2 {Tcl_EvalEx, error while parsing} testevalex {
+    list [catch {testevalex {concat "abc}} msg] $msg
+} {1 {missing "}}
+test parse-11.3 {Tcl_EvalEx, error while collecting words} testevalex {
+    unset -nocomplain a
+    list [catch {testevalex {concat xyz $a}} msg] $msg
+} {1 {can't read "a": no such variable}}
+test parse-11.4 {Tcl_EvalEx, error in Tcl_EvalObjv call} testevalex {
+    unset -nocomplain a
+    list [catch {testevalex {_bogus_ a b c d}} msg] $msg
+} {1 {invalid command name "_bogus_"}}
+test parse-11.5 {Tcl_EvalEx, exceptional return} testevalex {
+    list [catch {testevalex {break}} msg] $msg
+} {3 {}}
+test parse-11.6 {Tcl_EvalEx, freeing memory} testevalex {
+    testevalex {concat a b c d e f g h i j k l m n o p q r s t u v w x y z}
+} {a b c d e f g h i j k l m n o p q r s t u v w x y z}
+test parse-11.7 {Tcl_EvalEx, multiple commands in script} testevalex {
+    list [testevalex {set a b; set c d}] $a $c
+} {d b d}
+test parse-11.8 {Tcl_EvalEx, multiple commands in script} testevalex {
+    list [testevalex {
+	set a b
+	set c d
+    }] $a $c
+} {d b d}
+test parse-11.9 {Tcl_EvalEx, freeing memory after error} testevalex {
+    unset -nocomplain a
+    list [catch {testevalex {concat a b c d e f g h i j k l m n o p q r s t u v w x y z $a}} msg] $msg
+} {1 {can't read "a": no such variable}}
+test parse-11.10 {Tcl_EvalTokens, empty commands} testevalex {
+    testevalex {concat xyz;   }
+} {xyz}
+test parse-11.11 {Tcl_EvalTokens, empty commands} testevalex {
+    testevalex "concat abc; ; # this is a comment\n"
+} {abc}
+test parse-11.12 {Tcl_EvalTokens, empty commands} testevalex {
+    testevalex {}
+} {}
+
+test parse-12.1 {Tcl_ParseVarName procedure, initialization} testparsevarname {
+    list [catch {testparsevarname {$a([first second])} 8 0} msg] $msg
+} {1 {missing close-bracket}}
+test parse-12.2 {Tcl_ParseVarName procedure, initialization} testparsevarname {
+    testparsevarname {$a([first second])} 0 0
+} {- {} 0 variable {$a([first second])} 2 text a 0 command {[first second]} 0 {}}
+test parse-12.3 {Tcl_ParseVarName procedure, initialization} testparsevarname {
+    list [catch {testparsevarname {$abcd} 3 0} msg] $msg
+} {0 {- {} 0 variable {$ab} 1 text ab 0 cd}}
+test parse-12.4 {Tcl_ParseVarName procedure, initialization} testparsevarname {
+    testparsevarname {$abcd} 0 0
+} {- {} 0 variable {$abcd} 1 text abcd 0 {}}
+test parse-12.5 {Tcl_ParseVarName procedure, just a dollar sign} testparsevarname {
+    testparsevarname {$abcd} 1 0
+} {- {} 0 text {$} 0 abcd}
+test parse-12.6 {Tcl_ParseVarName procedure, braced variable name} testparser {
+    testparser {${..[]b}cd} 0
+} {- {${..[]b}cd} 1 word {${..[]b}cd} 3 variable {${..[]b}} 1 text {..[]b} 0 text cd 0 {}}
+test parse-12.7 {Tcl_ParseVarName procedure, braced variable name} testparser {
+    testparser "\$\{\{\} " 0
+} {- \$\{\{\}\  1 word \$\{\{\} 2 variable \$\{\{\} 1 text \{ 0 {}}
+test parse-12.8 {Tcl_ParseVarName procedure, missing close brace} testparser {
+    list [catch {testparser "$\{abc" 0} msg] $msg $::errorInfo
+} {1 {missing close-brace for variable name} missing\ close-brace\ for\ variable\ name\n\ \ \ \ (remainder\ of\ script:\ \"\{abc\")\n\ \ \ \ invoked\ from\ within\n\"testparser\ \"\$\\\{abc\"\ 0\"}
+test parse-12.9 {Tcl_ParseVarName procedure, missing close brace} testparsevarname {
+    list [catch {testparsevarname {${bcd}} 4 0} msg] $msg
+} {1 {missing close-brace for variable name}}
+test parse-12.10 {Tcl_ParseVarName procedure, missing close brace} testparsevarname {
+    list [catch {testparsevarname {${bc}} 4 0} msg] $msg
+} {1 {missing close-brace for variable name}}
+test parse-12.11 {Tcl_ParseVarName procedure, simple variable name} testparser {
+    testparser {$az_AZ.} 0
+} {- {$az_AZ.} 1 word {$az_AZ.} 3 variable {$az_AZ} 1 text az_AZ 0 text . 0 {}}
+test parse-12.12 {Tcl_ParseVarName procedure, simple variable name} testparser {
+    testparser {$abcdefg} 4
+} {- {$abc} 1 word {$abc} 2 variable {$abc} 1 text abc 0 defg}
+test parse-12.13 {Tcl_ParseVarName procedure, simple variable name with ::} testparser {
+    testparser {$xyz::ab:c} 0
+} {- {$xyz::ab:c} 1 word {$xyz::ab:c} 3 variable {$xyz::ab} 1 text xyz::ab 0 text :c 0 {}}
+test parse-12.14 {Tcl_ParseVarName procedure, variable names with many colons} testparser {
+    testparser {$xyz:::::c} 0
+} {- {$xyz:::::c} 1 word {$xyz:::::c} 2 variable {$xyz:::::c} 1 text xyz:::::c 0 {}}
+test parse-12.15 {Tcl_ParseVarName procedure, : vs. ::} testparsevarname {
+    testparsevarname {$ab:cd} 0 0
+} {- {} 0 variable {$ab} 1 text ab 0 :cd}
+test parse-12.16 {Tcl_ParseVarName procedure, eof in ::} testparsevarname {
+    testparsevarname {$ab::cd} 4 0
+} {- {} 0 variable {$ab} 1 text ab 0 ::cd}
+test parse-12.17 {Tcl_ParseVarName procedure, eof in ::} testparsevarname {
+    testparsevarname {$ab:::cd} 5 0
+} {- {} 0 variable {$ab::} 1 text ab:: 0 :cd}
+test parse-12.18 {Tcl_ParseVarName procedure, no variable name} testparser {
+    testparser {$$ $.} 0
+} {- {$$ $.} 2 word {$$} 2 text {$} 0 text {$} 0 word {$.} 2 text {$} 0 text . 0 {}}
+test parse-12.19 {Tcl_ParseVarName procedure, EOF before (} testparsevarname {
+    testparsevarname {$ab(cd)} 3 0
+} {- {} 0 variable {$ab} 1 text ab 0 (cd)}
+test parse-12.20 {Tcl_ParseVarName procedure, array reference} testparser {
+    testparser {$x(abc)} 0
+} {- {$x(abc)} 1 word {$x(abc)} 3 variable {$x(abc)} 2 text x 0 text abc 0 {}}
+test parse-12.21 {Tcl_ParseVarName procedure, array reference} testparser {
+    testparser {$x(ab$cde[foo bar])} 0
+} {- {$x(ab$cde[foo bar])} 1 word {$x(ab$cde[foo bar])} 6 variable {$x(ab$cde[foo bar])} 5 text x 0 text ab 0 variable {$cde} 1 text cde 0 command {[foo bar]} 0 {}}
+test parse-12.22 {Tcl_ParseVarName procedure, array reference} testparser {
+    testparser {$x([cmd arg]zz)} 0
+} {- {$x([cmd arg]zz)} 1 word {$x([cmd arg]zz)} 4 variable {$x([cmd arg]zz)} 3 text x 0 command {[cmd arg]} 0 text zz 0 {}}
+test parse-12.23 {Tcl_ParseVarName procedure, missing close paren in array reference} testparser {
+    list [catch {testparser {$x(poiu} 0} msg] $msg $::errorInfo
+} {1 {missing )} {missing )
+    (remainder of script: "(poiu")
+    invoked from within
+"testparser {$x(poiu} 0"}}
+test parse-12.24 {Tcl_ParseVarName procedure, missing close paren in array reference} testparsevarname {
+    list [catch {testparsevarname {$ab(cd)} 6 0} msg] $msg $::errorInfo
+} {1 {missing )} {missing )
+    (remainder of script: "(cd)")
+    invoked from within
+"testparsevarname {$ab(cd)} 6 0"}}
+test parse-12.25 {Tcl_ParseVarName procedure, nested array reference} testparser {
+    testparser {$x(a$y(b$z))} 0
+} {- {$x(a$y(b$z))} 1 word {$x(a$y(b$z))} 8 variable {$x(a$y(b$z))} 7 text x 0 text a 0 variable {$y(b$z)} 4 text y 0 text b 0 variable {$z} 1 text z 0 {}}
+test parse-12.26 {Tcl_ParseVarName [d2ffcca163] non-ascii} testparser {
+    testparser "$\u0433" -1
+} "- {$\u0433} 1 word {$\u0433} 2 text {$} 0 text \u0433 0 {}"
+
+test parse-13.1 {Tcl_ParseVar procedure} testparsevar {
+    set abc 24
+    testparsevar {$abc.fg}
+} {24 .fg}
+test parse-13.2 {Tcl_ParseVar procedure, no variable name} testparsevar {
+    testparsevar {$}
+} {{$} {}}
+test parse-13.3 {Tcl_ParseVar procedure, no variable name} testparsevar {
+    testparsevar {$.123}
+} {{$} .123}
+test parse-13.4 {Tcl_ParseVar procedure, error looking up variable} testparsevar {
+    unset -nocomplain abc
+    list [catch {testparsevar {$abc}} msg] $msg
+} {1 {can't read "abc": no such variable}}
+test parse-13.5 {Tcl_ParseVar procedure, error looking up variable} testparsevar {
+    unset -nocomplain abc
+    list [catch {testparsevar {$abc([bogus x y z])}} msg] $msg
+} {1 {invalid command name "bogus"}}
+test parse-13.6 {Tcl_ParseVar memory leak} -constraints memory -setup {
+    proc getbytes {} {
+	return [lindex [split [memory info] \n] 3 3]
+    }
+} -body {
+    set a() foo
+    set end [getbytes]
+    for {set i 0} {$i < 5} {incr i} {
+	set vn {}
+	set res [testparsevar [append vn $ a([string repeat {[]} 19]) bar]]
+	if {$res ne {foo bar}} {error "Unexpected result: $res"}
+
+	set tmp $end
+	set end [getbytes]
+    }
+    expr {$end - $tmp}
+} -cleanup {
+    unset -nocomplain a end i vn res tmp
+    rename getbytes {}
+} -result 0
+
+test parse-14.1 {Tcl_ParseBraces procedure, computing string length} {testparser testbytestring} {
+    testparser [testbytestring "foo\0 bar"] -1
+} {- foo 1 simple foo 1 text foo 0 {}}
+test parse-14.2 {Tcl_ParseBraces procedure, computing string length} testparser {
+    testparser "foo bar" -1
+} {- {foo bar} 2 simple foo 1 text foo 0 simple bar 1 text bar 0 {}}
+test parse-14.3 {Tcl_ParseBraces procedure, words in braces} testparser {
+    testparser {foo {a $b [concat foo]} {c d}} 0
+} {- {foo {a $b [concat foo]} {c d}} 3 simple foo 1 text foo 0 simple {{a $b [concat foo]}} 1 text {a $b [concat foo]} 0 simple {{c d}} 1 text {c d} 0 {}}
+test parse-14.4 {Tcl_ParseBraces procedure, empty nested braces} testparser {
+    testparser {foo {{}}} 0
+} {- {foo {{}}} 2 simple foo 1 text foo 0 simple {{{}}} 1 text {{}} 0 {}}
+test parse-14.5 {Tcl_ParseBraces procedure, nested braces} testparser {
+    testparser {foo {{a {b} c} {} {d e}}} 0
+} {- {foo {{a {b} c} {} {d e}}} 2 simple foo 1 text foo 0 simple {{{a {b} c} {} {d e}}} 1 text {{a {b} c} {} {d e}} 0 {}}
+test parse-14.6 {Tcl_ParseBraces procedure, backslashes in words in braces} testparser {
+    testparser "foo {a \\n\\\{}" 0
+} {- {foo {a \n\{}} 2 simple foo 1 text foo 0 simple {{a \n\{}} 1 text {a \n\{} 0 {}}
+test parse-14.7 {Tcl_ParseBraces procedure, missing continuation line in braces} testparser {
+    list [catch {testparser "\{abc\\\n" 0} msg] $msg $::errorInfo
+} {1 {missing close-brace} missing\ close-brace\n\ \ \ \ (remainder\ of\ script:\ \"\{abc\\\n\")\n\ \ \ \ invoked\ from\ within\n\"testparser\ \"\\\{abc\\\\\\n\"\ 0\"}
+test parse-14.8 {Tcl_ParseBraces procedure, backslash-newline in braces} testparser {
+    testparser "foo {\\\nx}" 0
+} {- foo\ \{\\\nx\} 2 simple foo 1 text foo 0 word \{\\\nx\} 2 backslash \\\n 0 text x 0 {}}
+test parse-14.9 {Tcl_ParseBraces procedure, backslash-newline in braces} testparser {
+    testparser "foo {a \\\n   b}" 0
+} {- foo\ \{a\ \\\n\ \ \ b\} 2 simple foo 1 text foo 0 word \{a\ \\\n\ \ \ b\} 3 text {a } 0 backslash \\\n\ \ \  0 text b 0 {}}
+test parse-14.10 {Tcl_ParseBraces procedure, backslash-newline in braces} testparser {
+    testparser "foo {xyz\\\n }" 0
+} {- foo\ \{xyz\\\n\ \} 2 simple foo 1 text foo 0 word \{xyz\\\n\ \} 2 text xyz 0 backslash \\\n\  0 {}}
+test parse-14.11 {Tcl_ParseBraces procedure, empty braced string} testparser {
+    testparser {foo {}} 0
+} {- {foo {}} 2 simple foo 1 text foo 0 simple {{}} 1 text {} 0 {}}
+test parse-14.12 {Tcl_ParseBraces procedure, missing close brace} testparser {
+    list [catch {testparser "foo \{xy\\\nz" 0} msg] $msg $::errorInfo
+} {1 {missing close-brace} missing\ close-brace\n\ \ \ \ (remainder\ of\ script:\ \"\{xy\\\nz\")\n\ \ \ \ invoked\ from\ within\n\"testparser\ \"foo\ \\\{xy\\\\\\nz\"\ 0\"}
+
+test parse-15.1 {Tcl_ParseQuotedString procedure, computing string length} {testparser testbytestring} {
+    testparser [testbytestring "foo\0 bar"] -1
+} {- foo 1 simple foo 1 text foo 0 {}}
+test parse-15.2 {Tcl_ParseQuotedString procedure, computing string length} testparser {
+    testparser "foo bar" -1
+} {- {foo bar} 2 simple foo 1 text foo 0 simple bar 1 text bar 0 {}}
+test parse-15.3 {Tcl_ParseQuotedString procedure, word is quoted string} testparser {
+    testparser {foo "a b c" d "efg";} 0
+} {- {foo "a b c" d "efg";} 4 simple foo 1 text foo 0 simple {"a b c"} 1 text {a b c} 0 simple d 1 text d 0 simple {"efg"} 1 text efg 0 {}}
+test parse-15.4 {Tcl_ParseQuotedString procedure, garbage after quoted string} testparser {
+    list [catch {testparser {foo "a b c"d} 0} msg] $msg $::errorInfo
+} {1 {extra characters after close-quote} {extra characters after close-quote
+    (remainder of script: "d")
+    invoked from within
+"testparser {foo "a b c"d} 0"}}
+
+test parse-15.5 {CommandComplete procedure} {
+    info complete ""
+} 1
+test parse-15.6 {CommandComplete procedure} {
+    info complete "  \n"
+} 1
+test parse-15.7 {CommandComplete procedure} {
+    info complete "abc def"
+} 1
+test parse-15.8 {CommandComplete procedure} {
+    info complete "a b c d e f \t\n"
+} 1
+test parse-15.9 {CommandComplete procedure} {
+    info complete {a b c"d}
+} 1
+test parse-15.10 {CommandComplete procedure} {
+    info complete {a b "c d" e}
+} 1
+test parse-15.11 {CommandComplete procedure} {
+    info complete {a b "c d"}
+} 1
+test parse-15.12 {CommandComplete procedure} {
+    info complete {a b "c d"}
+} 1
+test parse-15.13 {CommandComplete procedure} {
+    info complete {a b "c d}
+} 0
+test parse-15.14 {CommandComplete procedure} {
+    info complete {a b "}
+} 0
+test parse-15.15 {CommandComplete procedure} {
+    info complete {a b "cd"xyz}
+} 1
+test parse-15.16 {CommandComplete procedure} {
+    info complete {a b "c $d() d"}
+} 1
+test parse-15.17 {CommandComplete procedure} {
+    info complete {a b "c $dd("}
+} 0
+test parse-15.18 {CommandComplete procedure} {
+    info complete {a b "c \"}
+} 0
+test parse-15.19 {CommandComplete procedure} {
+    info complete {a b "c [d e f]"}
+} 1
+test parse-15.20 {CommandComplete procedure} {
+    info complete {a b "c [d e f] g"}
+} 1
+test parse-15.21 {CommandComplete procedure} {
+    info complete {a b "c [d e f"}
+} 0
+test parse-15.22 {CommandComplete procedure} {
+    info complete {a {b c d} e}
+} 1
+test parse-15.23 {CommandComplete procedure} {
+    info complete {a {b c d}}
+} 1
+test parse-15.24 {CommandComplete procedure} {
+    info complete "a b\{c d"
+} 1
+test parse-15.25 {CommandComplete procedure} {
+    info complete "a b \{c"
+} 0
+test parse-15.26 {CommandComplete procedure} {
+    info complete "a b \{c{ }"
+} 0
+test parse-15.27 {CommandComplete procedure} {
+    info complete "a b {c d e}xxx"
+} 1
+test parse-15.28 {CommandComplete procedure} {
+    info complete "a b {c \\\{d e}xxx"
+} 1
+test parse-15.29 {CommandComplete procedure} {
+    info complete {a b [ab cd ef]}
+} 1
+test parse-15.30 {CommandComplete procedure} {
+    info complete {a b x[ab][cd][ef] gh}
+} 1
+test parse-15.31 {CommandComplete procedure} {
+    info complete {a b x[ab][cd[ef] gh}
+} 0
+test parse-15.32 {CommandComplete procedure} {
+    info complete {a b x[ gh}
+} 0
+test parse-15.33 {CommandComplete procedure} {
+    info complete {[]]]}
+} 1
+test parse-15.34 {CommandComplete procedure} {
+    info complete {abc x$yyy}
+} 1
+test parse-15.35 {CommandComplete procedure} {
+    info complete "abc x\${abc\[\\d} xyz"
+} 1
+test parse-15.36 {CommandComplete procedure} {
+    info complete "abc x\$\{ xyz"
+} 0
+test parse-15.37 {CommandComplete procedure} {
+    info complete {word $a(xyz)}
+} 1
+test parse-15.38 {CommandComplete procedure} {
+    info complete {word $a(}
+} 0
+test parse-15.39 {CommandComplete procedure} {
+    info complete "set a \\\n"
+} 0
+test parse-15.40 {CommandComplete procedure} {
+    info complete "set a \\\\\n"
+} 1
+test parse-15.41 {CommandComplete procedure} {
+    info complete "set a \\n "
+} 1
+test parse-15.42 {CommandComplete procedure} {
+    info complete "set a \\"
+} 1
+test parse-15.43 {CommandComplete procedure} {
+    info complete "foo \\\n\{"
+} 0
+test parse-15.44 {CommandComplete procedure} {
+    info complete "a\nb\n# \{\n# \{\nc\n"
+} 1
+test parse-15.45 {CommandComplete procedure} {
+    info complete "#Incomplete comment\\\n"
+} 0
+test parse-15.46 {CommandComplete procedure} {
+    info complete "#Incomplete comment\\\nBut now it's complete.\n"
+} 1
+test parse-15.47 {CommandComplete procedure} {
+    info complete "# Complete comment\\\\\n"
+} 1
+test parse-15.48 {CommandComplete procedure} {
+    info complete "abc\\\n def"
+} 1
+test parse-15.49 {CommandComplete procedure} {
+    info complete "abc\\\n "
+} 1
+test parse-15.50 {CommandComplete procedure} {
+    info complete "abc\\\n"
+} 0
+test parse-15.51 {CommandComplete procedure} "
+    info complete \"\\\{abc\\\}\\\{\"
+" 1
+test parse-15.52 {CommandComplete procedure} {
+    info complete "\"abc\"("
+} 1
+test parse-15.53 {CommandComplete procedure} "
+    info complete \" # \{\"
+" 1
+test parse-15.54 {CommandComplete procedure} "
+    info complete \"foo bar;# \{\"
+" 1
+test parse-15.55 {CommandComplete procedure} testbytestring {
+    info complete "set x [testbytestring \0]; puts hi"
+} 1
+test parse-15.56 {CommandComplete procedure} testbytestring {
+    info complete "set x [testbytestring \0]; \{"
+} 0
+test parse-15.57 {CommandComplete procedure} {
+    info complete "# Comment should be complete command"
+} 1
+test parse-15.58 {CommandComplete procedure, memory leaks} {
+    info complete "1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22"
+} 1
+test parse-15.59 {CommandComplete procedure} testbytestring {
+    # Test for Tcl Bug 684744
+    info complete [testbytestring "\x00;if 1 \{"]
+} 0
+test parse-15.60 {CommandComplete procedure} {
+    # Test for Tcl Bug 1968882
+    info complete \\\n
+} 0
+
+test parse-16.1 {Bug 218885 (Scriptics bug 2535)} {
+    subst {[eval {return foo}]bar}
+} foobar
+
+test parse-17.1 {Correct return codes from errors during substitution} {
+    catch {eval {w[continue]}}
+} 4
+
+test parse-18.1 {Tcl_SubstObj, ParseTokens flags} {
+    subst {foo\t$::tcl_library\t[set ::tcl_library]}
+} "foo	$::tcl_library	$::tcl_library"
+test parse-18.2 {Tcl_SubstObj, ParseTokens flags} {
+    subst -nocommands {foo\t$::tcl_library\t[set ::tcl_library]}
+} "foo	$::tcl_library	\[set ::tcl_library]"
+test parse-18.3 {Tcl_SubstObj, ParseTokens flags} {
+    subst -novariables {foo\t$::tcl_library\t[set ::tcl_library]}
+} "foo	\$::tcl_library	$::tcl_library"
+test parse-18.4 {Tcl_SubstObj, ParseTokens flags} {
+    subst -nobackslashes {foo\t$::tcl_library\t[set ::tcl_library]}
+} "foo\\t$::tcl_library\\t$::tcl_library"
+test parse-18.5 {Tcl_SubstObj, ParseTokens flags} {
+    subst -novariables -nobackslashes {foo\t$::tcl_library\t[set ::tcl_library]}
+} "foo\\t\$::tcl_library\\t$::tcl_library"
+test parse-18.6 {Tcl_SubstObj, ParseTokens flags} {
+    subst -nocommands -nobackslashes {foo\t$::tcl_library\t[set ::tcl_library]}
+} "foo\\t$::tcl_library\\t\[set ::tcl_library]"
+test parse-18.7 {Tcl_SubstObj, ParseTokens flags} {
+    subst -nocommands -novariables {foo\t$::tcl_library\t[set ::tcl_library]}
+} "foo	\$::tcl_library	\[set ::tcl_library]"
+test parse-18.8 {Tcl_SubstObj, ParseTokens flags} {
+    subst -nocommands -novariables -nobackslashes \
+	    {foo\t$::tcl_library\t[set ::tcl_library]}
+} "foo\\t\$::tcl_library\\t\[set ::tcl_library]"
+
+test parse-18.9 {Tcl_SubstObj, parse errors} {
+    list [catch "subst foo\$\{foo" msg] $msg
+} [list 1 "missing close-brace for variable name"]
+test parse-18.10 {Tcl_SubstObj, parse errors} {
+    list [catch "subst foo\[set \$\{foo]" msg] $msg
+} [list 1 "missing close-brace for variable name"]
+test parse-18.11 {Tcl_SubstObj, parse errors} {
+    list [catch "subst foo\$array(\$\{foo)" msg] $msg
+} [list 1 "missing close-brace for variable name"]
+test parse-18.12 {Tcl_SubstObj, parse errors} {
+    list [catch "subst foo\$(\$\{foo)" msg] $msg
+} [list 1 "missing close-brace for variable name"]
+test parse-18.13 {Tcl_SubstObj, parse errors} {
+    list [catch "subst \[" msg] $msg
+} [list 1 "missing close-bracket"]
+
+test parse-18.14 {Tcl_SubstObj, exception handling} {
+    subst {abc,[break],def}
+} {abc,}
+test parse-18.15 {Tcl_SubstObj, exception handling} {
+    subst {abc,[continue; expr 1+2],def}
+} {abc,,def}
+test parse-18.16 {Tcl_SubstObj, exception handling} {
+    subst {abc,[return foo; expr 1+2],def}
+} {abc,foo,def}
+test parse-18.17 {Tcl_SubstObj, exception handling} {
+    subst {abc,[return -code 10 foo; expr 1+2],def}
+} {abc,foo,def}
+test parse-18.18 {Tcl_SubstObj, exception handling} {
+    subst {abc,[break; set {} {}{}],def}
+} {abc,}
+test parse-18.19 {Tcl_SubstObj, exception handling} {
+    list [catch {subst {abc,[continue; expr 1+2; set {} {}{}],def}} msg] $msg
+} [list 1 "extra characters after close-brace"]
+test parse-18.20 {Tcl_SubstObj, exception handling} {
+    list [catch {subst {abc,[return foo; expr 1+2; set {} {}{}],def}} msg] $msg
+} [list 1 "extra characters after close-brace"]
+test parse-18.21 {Tcl_SubstObj, exception handling} {
+    list [catch {
+	subst {abc,[return -code 10 foo; expr 1+2; set {} {}{}],def}
+    } msg] $msg
+} [list 1 "extra characters after close-brace"]
+
+test parse-18.22 {Tcl_SubstObj, side effects} {
+    set a 0
+    list [subst {foo[incr a]bar}] $a
+} [list foo1bar 1]
+test parse-18.23 {Tcl_SubstObj, side effects} {
+    set a 0
+    list [subst {foo[incr a; incr a]bar}] $a
+} [list foo2bar 2]
+test parse-18.24 {Tcl_SubstObj, side effects} {
+    set a 0
+    list [subst {foo[incr a; break; incr a]bar}] $a
+} [list foo 1]
+test parse-18.25 {Tcl_SubstObj, side effects} {
+    set a 0
+    list [subst {foo[incr a; continue; incr a]bar}] $a
+} [list foobar 1]
+test parse-18.26 {Tcl_SubstObj, side effects} {
+    set a 0
+    list [subst {foo[incr a; return; incr a]bar}] $a
+} [list foobar 1]
+test parse-18.27 {Tcl_SubstObj, side effects} {
+    set a 0
+    list [subst {foo[incr a; return -code 10; incr a]bar}] $a
+} [list foobar 1]
+test parse-18.28 {Tcl_SubstObj, side effects} {
+    set a 0
+    catch {subst {foo[incr a; parse error {}{}; incr a]bar}}
+    set a
+} 1
+test parse-18.29 {Tcl_SubstObj, side effects} {
+    set a 0
+    catch {subst {foo[incr a; incr a; parse error {}{}]bar}}
+    set a
+} 2
+test parse-18.30 {Tcl_SubstObj, side effects} {
+    set a 0
+    catch {subst {foo[incr a; incr a parse error {}{}]bar}}
+    set a
+} 1
+
+test parse-19.1 {Bug 1115904: recursion limit in Tcl_EvalEx} -constraints {
+    testevalex
+} -setup {
+    interp create i
+    load {} Tcltest i
+    i eval {proc {} args {}}
+    interp recursionlimit i 3
+} -body {
+    i eval {testevalex {[]}}
+} -cleanup {
+    interp delete i
+}
+
+test parse-19.2 {Bug 1115904: recursion limit in Tcl_EvalEx} -constraints {
+    testevalex
+} -setup {
+    interp create i
+    load {} Tcltest i
+    i eval {proc {} args {}}
+    interp recursionlimit i 2
+} -body {
+    i eval {testevalex {[[]]}}
+} -cleanup {
+    interp delete i
+} -returnCodes error -match glob -result {too many nested*}
+
+test parse-19.3 {Bug 1115904: recursion limit in Tcl_EvalEx} emptyTest {
+    # Test no longer valid in Tcl 8.6
+} {}
+test parse-19.4 {Bug 1115904: recursion limit in Tcl_EvalEx} emptyTest {
+    # Test no longer valid in Tcl 8.6
+} {}
+
+test parse-20.1 {TclParseBackslash: truncated escape} testparser {
+    testparser {\u12345} 1
+} {- \\ 1 simple \\ 1 text \\ 0 u12345}
+test parse-20.2 {TclParseBackslash: truncated escape} testparser {
+    testparser {\u12345} 2
+} {- {\u} 1 word {\u} 1 backslash {\u} 0 12345}
+test parse-20.3 {TclParseBackslash: truncated escape} testparser {
+    testparser {\u12345} 3
+} {- {\u1} 1 word {\u1} 1 backslash {\u1} 0 2345}
+test parse-20.4 {TclParseBackslash: truncated escape} testparser {
+    testparser {\u12345} 4
+} {- {\u12} 1 word {\u12} 1 backslash {\u12} 0 345}
+test parse-20.5 {TclParseBackslash: truncated escape} testparser {
+    testparser {\u12345} 5
+} {- {\u123} 1 word {\u123} 1 backslash {\u123} 0 45}
+test parse-20.6 {TclParseBackslash: truncated escape} testparser {
+    testparser {\u12345} 6
+} {- {\u1234} 1 word {\u1234} 1 backslash {\u1234} 0 5}
+test parse-20.7 {TclParseBackslash: truncated escape} testparser {
+    testparser {\u12345} 7
+} {- {\u12345} 1 word {\u12345} 2 backslash {\u1234} 0 text 5 0 {}}
+
+test parse-20.8 {TclParseBackslash: truncated escape} testparser {
+    testparser {\x12X} 1
+} {- \\ 1 simple \\ 1 text \\ 0 x12X}
+test parse-20.9 {TclParseBackslash: truncated escape} testparser {
+    testparser {\x12X} 2
+} {- {\x} 1 word {\x} 1 backslash {\x} 0 12X}
+test parse-20.10 {TclParseBackslash: truncated escape} testparser {
+    testparser {\x12X} 3
+} {- {\x1} 1 word {\x1} 1 backslash {\x1} 0 2X}
+test parse-20.11 {TclParseBackslash: truncated escape} testparser {
+    testparser {\x12X} 4
+} {- {\x12} 1 word {\x12} 1 backslash {\x12} 0 X}
+test parse-20.12 {TclParseBackslash: truncated escape} testparser {
+    testparser {\x12X} 5
+} {- {\x12X} 1 word {\x12X} 2 backslash {\x12} 0 text X 0 {}}
+
+test parse-21.0 {Bug 1884496} testevent {
+    set ::script {testevent delete a; set a [p]; set ::done $a}
+    proc ::p {} {string first s $::script}
+    testevent queue a head $::script
+    vwait done
+} {}
+test parse-21.1 {TCL_EVAL_DIRECT coverage} testevent {
+    testevent queue a head {testevent delete a; \
+	set ::done [dict get [info frame 0] line]}
+    vwait done
+    set ::done
+} 2
+
+cleanupTests
+}
+
+namespace delete ::tcl::test::parse
+return
diff --git a/tests/parseExpr.test b/tests/parseExpr.test
new file mode 100644
index 0000000..ef05454
--- /dev/null
+++ b/tests/parseExpr.test
@@ -0,0 +1,1079 @@
+# This file contains a collection of tests for the procedures in the
+# file tclCompExpr.c.  Sourcing this file into Tcl runs the tests and
+# generates output for errors.  No output means no errors were found.
+#
+# Copyright (c) 1997 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+package require tcltest 2
+namespace import ::tcltest::*
+
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
+
+# Note that the Tcl expression parser (tclCompExpr.c) does not check
+# the semantic validity of the expressions it parses. It does not check,
+# for example, that a math function actually exists, or that the operands
+# of "<<" are integers.
+
+testConstraint testexprparser [llength [info commands testexprparser]]
+testConstraint testbytestring [llength [info commands testbytestring]]
+
+# Big test for correct ordering of data in [expr]
+
+proc testIEEE {} {
+    variable ieeeValues
+    binary scan [binary format dd -1.0 1.0] c* c
+    switch -exact -- $c {
+	{0 0 0 0 0 0 -16 -65 0 0 0 0 0 0 -16 63} {
+	    # little endian
+	    binary scan \x00\x00\x00\x00\x00\x00\xf0\xff d \
+		ieeeValues(-Infinity)
+	    binary scan \x00\x00\x00\x00\x00\x00\xf0\xbf d \
+		ieeeValues(-Normal)
+	    binary scan \x00\x00\x00\x00\x00\x00\x08\x80 d \
+		ieeeValues(-Subnormal)
+	    binary scan \x00\x00\x00\x00\x00\x00\x00\x80 d \
+		ieeeValues(-0)
+	    binary scan \x00\x00\x00\x00\x00\x00\x00\x00 d \
+		ieeeValues(+0)
+	    binary scan \x00\x00\x00\x00\x00\x00\x08\x00 d \
+		ieeeValues(+Subnormal)
+	    binary scan \x00\x00\x00\x00\x00\x00\xf0\x3f d \
+		ieeeValues(+Normal)
+	    binary scan \x00\x00\x00\x00\x00\x00\xf0\x7f d \
+		ieeeValues(+Infinity)
+	    binary scan \x00\x00\x00\x00\x00\x00\xf8\x7f d \
+		ieeeValues(NaN)
+	    set ieeeValues(littleEndian) 1
+	    return 1
+	}
+	{-65 -16 0 0 0 0 0 0 63 -16 0 0 0 0 0 0} {
+	    binary scan \xff\xf0\x00\x00\x00\x00\x00\x00 d \
+		ieeeValues(-Infinity)
+	    binary scan \xbf\xf0\x00\x00\x00\x00\x00\x00 d \
+		ieeeValues(-Normal)
+	    binary scan \x80\x08\x00\x00\x00\x00\x00\x00 d \
+		ieeeValues(-Subnormal)
+	    binary scan \x80\x00\x00\x00\x00\x00\x00\x00 d \
+		ieeeValues(-0)
+	    binary scan \x00\x00\x00\x00\x00\x00\x00\x00 d \
+		ieeeValues(+0)
+	    binary scan \x00\x08\x00\x00\x00\x00\x00\x00 d \
+		ieeeValues(+Subnormal)
+	    binary scan \x3f\xf0\x00\x00\x00\x00\x00\x00 d \
+		ieeeValues(+Normal)
+	    binary scan \x7f\xf0\x00\x00\x00\x00\x00\x00 d \
+		ieeeValues(+Infinity)
+	    binary scan \x7f\xf8\x00\x00\x00\x00\x00\x00 d \
+		ieeeValues(NaN)
+	    set ieeeValues(littleEndian) 0
+	    return 1
+	}
+	default {
+	    return 0
+	}
+    }
+}
+testConstraint ieeeFloatingPoint [testIEEE]
+
+######################################################################
+
+test parseExpr-1.1 {Tcl_ParseExpr procedure, computing string length} {testexprparser testbytestring} {
+    testexprparser [testbytestring "1+2\0 +3"] -1
+} {- {} 0 subexpr 1+2 5 operator + 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 {}}
+test parseExpr-1.2 {Tcl_ParseExpr procedure, computing string length} testexprparser {
+    testexprparser "1  + 2" -1
+} {- {} 0 subexpr {1  + 2} 5 operator + 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 {}}
+test parseExpr-1.3 {Tcl_ParseExpr procedure, error getting initial lexeme} testexprparser {
+    testexprparser 12345678901234567890 -1
+} {- {} 0 subexpr 12345678901234567890 1 text 12345678901234567890 0 {}}
+test parseExpr-1.4 {Tcl_ParseExpr procedure, error in conditional expression} \
+    -constraints testexprparser -body {
+        testexprparser {foo+} -1
+    } -match glob -returnCodes error -result *
+test parseExpr-1.5 {Tcl_ParseExpr procedure, lexemes after the expression} -constraints testexprparser -body {
+    testexprparser {1+2 345} -1
+} -returnCodes error -match glob -result *
+
+test parseExpr-2.1 {ParseCondExpr procedure, valid test subexpr} testexprparser {
+    testexprparser {2>3? 1 : 0} -1
+} {- {} 0 subexpr {2>3? 1 : 0} 11 operator ? 0 subexpr 2>3 5 operator > 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 subexpr 1 1 text 1 0 subexpr 0 1 text 0 0 {}}
+test parseExpr-2.2 {ParseCondExpr procedure, error in test subexpr} \
+	-constraints testexprparser -body {
+            testexprparser {0 || foo} -1
+    } -match glob -returnCodes error -result *
+test parseExpr-2.3 {ParseCondExpr procedure, next lexeme isn't "?"} testexprparser {
+    testexprparser {1+2} -1
+} {- {} 0 subexpr 1+2 5 operator + 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 {}}
+test parseExpr-2.4 {ParseCondExpr procedure, next lexeme is "?"} testexprparser {
+    testexprparser {1+2 ? 3 : 4} -1
+} {- {} 0 subexpr {1+2 ? 3 : 4} 11 operator ? 0 subexpr 1+2 5 operator + 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 subexpr 4 1 text 4 0 {}}
+test parseExpr-2.5 {ParseCondExpr procedure, bad lexeme after "?"} testexprparser {
+    testexprparser {1+2 ? 12345678901234567890 : 0} -1
+} {- {} 0 subexpr {1+2 ? 12345678901234567890 : 0} 11 operator ? 0 subexpr 1+2 5 operator + 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 12345678901234567890 1 text 12345678901234567890 0 subexpr 0 1 text 0 0 {}}
+test parseExpr-2.6 {ParseCondExpr procedure, valid "then" subexpression} testexprparser {
+    testexprparser {1? 3 : 4} -1
+} {- {} 0 subexpr {1? 3 : 4} 7 operator ? 0 subexpr 1 1 text 1 0 subexpr 3 1 text 3 0 subexpr 4 1 text 4 0 {}}
+test parseExpr-2.7 {ParseCondExpr procedure, error in "then" subexpression} \
+    -constraints testexprparser -body {
+        testexprparser {1? fred : martha} -1
+    } -match glob -returnCodes error -result *
+test parseExpr-2.8 {ParseCondExpr procedure, lexeme after "then" subexpr isn't ":"} -constraints testexprparser -body {
+    testexprparser {1? 2 martha 3} -1
+} -returnCodes error -match glob -result *
+test parseExpr-2.9 {ParseCondExpr procedure, valid "else" subexpression} testexprparser {
+    testexprparser {27||3? 3 : 4&&9} -1
+} {- {} 0 subexpr {27||3? 3 : 4&&9} 15 operator ? 0 subexpr 27||3 5 operator || 0 subexpr 27 1 text 27 0 subexpr 3 1 text 3 0 subexpr 3 1 text 3 0 subexpr 4&&9 5 operator && 0 subexpr 4 1 text 4 0 subexpr 9 1 text 9 0 {}}
+test parseExpr-2.10 {ParseCondExpr procedure, error in "else" subexpression} \
+    -constraints testexprparser -body {
+        testexprparser {1? 2 : martha} -1
+    } -match glob -returnCodes error -result *
+
+test parseExpr-3.1 {ParseLorExpr procedure, valid logical and subexpr} testexprparser {
+    testexprparser {1&&2 || 3} -1
+} {- {} 0 subexpr {1&&2 || 3} 9 operator || 0 subexpr 1&&2 5 operator && 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-3.2 {ParseLorExpr procedure, error in logical and subexpr} \
+    -constraints testexprparser -body {
+        testexprparser {1&&foo || 3} -1
+    } -match glob -returnCodes error -result *
+test parseExpr-3.3 {ParseLorExpr procedure, next lexeme isn't "||"} testexprparser {
+    testexprparser {1&&2? 1 : 0} -1
+} {- {} 0 subexpr {1&&2? 1 : 0} 11 operator ? 0 subexpr 1&&2 5 operator && 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 1 1 text 1 0 subexpr 0 1 text 0 0 {}}
+test parseExpr-3.4 {ParseLorExpr procedure, next lexeme is "||"} testexprparser {
+    testexprparser {1&&2 || 3} -1
+} {- {} 0 subexpr {1&&2 || 3} 9 operator || 0 subexpr 1&&2 5 operator && 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-3.5 {ParseLorExpr procedure, bad lexeme after "||"} testexprparser {
+    testexprparser {1&&2 || 12345678901234567890} -1
+} {- {} 0 subexpr {1&&2 || 12345678901234567890} 9 operator || 0 subexpr 1&&2 5 operator && 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 12345678901234567890 1 text 12345678901234567890 0 {}}
+test parseExpr-3.6 {ParseLorExpr procedure, valid RHS subexpression} testexprparser {
+    testexprparser {1&&2 || 3 || 4} -1
+} {- {} 0 subexpr {1&&2 || 3 || 4} 13 operator || 0 subexpr {1&&2 || 3} 9 operator || 0 subexpr 1&&2 5 operator && 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 subexpr 4 1 text 4 0 {}}
+test parseExpr-3.7 {ParseLorExpr procedure, error in RHS subexpression} \
+    -constraints testexprparser -body {
+        testexprparser {1&&2 || 3 || martha} -1
+    } -match glob -returnCodes error -result *
+
+test parseExpr-4.1 {ParseLandExpr procedure, valid LHS "|" subexpr} testexprparser {
+    testexprparser {1|2 && 3} -1
+} {- {} 0 subexpr {1|2 && 3} 9 operator && 0 subexpr 1|2 5 operator | 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-4.2 {ParseLandExpr procedure, error in LHS "|" subexpr} \
+    -constraints testexprparser -body {
+        testexprparser {1&&foo && 3} -1
+    } -match glob -returnCodes error -result *
+test parseExpr-4.3 {ParseLandExpr procedure, next lexeme isn't "&&"} testexprparser {
+    testexprparser {1|2? 1 : 0} -1
+} {- {} 0 subexpr {1|2? 1 : 0} 11 operator ? 0 subexpr 1|2 5 operator | 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 1 1 text 1 0 subexpr 0 1 text 0 0 {}}
+test parseExpr-4.4 {ParseLandExpr procedure, next lexeme is "&&"} testexprparser {
+    testexprparser {1|2 && 3} -1
+} {- {} 0 subexpr {1|2 && 3} 9 operator && 0 subexpr 1|2 5 operator | 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-4.5 {ParseLandExpr procedure, bad lexeme after "&&"} testexprparser {
+    testexprparser {1|2 && 12345678901234567890} -1
+} {- {} 0 subexpr {1|2 && 12345678901234567890} 9 operator && 0 subexpr 1|2 5 operator | 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 12345678901234567890 1 text 12345678901234567890 0 {}}
+test parseExpr-4.6 {ParseLandExpr procedure, valid RHS subexpression} testexprparser {
+    testexprparser {1|2 && 3 && 4} -1
+} {- {} 0 subexpr {1|2 && 3 && 4} 13 operator && 0 subexpr {1|2 && 3} 9 operator && 0 subexpr 1|2 5 operator | 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 subexpr 4 1 text 4 0 {}}
+test parseExpr-4.7 {ParseLandExpr procedure, error in RHS subexpression} \
+    -constraints testexprparser -body {
+        testexprparser {1|2 && 3 && martha} -1
+    } -match glob -returnCodes error -result *
+
+test parseExpr-5.1 {ParseBitOrExpr procedure, valid LHS "^" subexpr} testexprparser {
+    testexprparser {1^2 | 3} -1
+} {- {} 0 subexpr {1^2 | 3} 9 operator | 0 subexpr 1^2 5 operator ^ 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-5.2 {ParseBitOrExpr procedure, error in LHS "^" subexpr} \
+    -constraints testexprparser -body {
+        testexprparser {1|foo | 3} -1
+    } -match glob -returnCodes error -result *
+test parseExpr-5.3 {ParseBitOrExpr procedure, next lexeme isn't "|"} testexprparser {
+    testexprparser {1^2? 1 : 0} -1
+} {- {} 0 subexpr {1^2? 1 : 0} 11 operator ? 0 subexpr 1^2 5 operator ^ 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 1 1 text 1 0 subexpr 0 1 text 0 0 {}}
+test parseExpr-5.4 {ParseBitOrExpr procedure, next lexeme is "|"} testexprparser {
+    testexprparser {1^2 | 3} -1
+} {- {} 0 subexpr {1^2 | 3} 9 operator | 0 subexpr 1^2 5 operator ^ 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-5.5 {ParseBitOrExpr procedure, bad lexeme after "|"} testexprparser {
+    testexprparser {1^2 | 12345678901234567890} -1
+} {- {} 0 subexpr {1^2 | 12345678901234567890} 9 operator | 0 subexpr 1^2 5 operator ^ 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 12345678901234567890 1 text 12345678901234567890 0 {}}
+test parseExpr-5.6 {ParseBitOrExpr procedure, valid RHS subexpression} testexprparser {
+    testexprparser {1^2 | 3 | 4} -1
+} {- {} 0 subexpr {1^2 | 3 | 4} 13 operator | 0 subexpr {1^2 | 3} 9 operator | 0 subexpr 1^2 5 operator ^ 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 subexpr 4 1 text 4 0 {}}
+test parseExpr-5.7 {ParseBitOrExpr procedure, error in RHS subexpression} \
+    -constraints testexprparser -body {
+        testexprparser {1^2 | 3 | martha} -1
+    } -match glob -returnCodes error -result *
+
+test parseExpr-6.1 {ParseBitXorExpr procedure, valid LHS "&" subexpr} testexprparser {
+    testexprparser {1&2 ^ 3} -1
+} {- {} 0 subexpr {1&2 ^ 3} 9 operator ^ 0 subexpr 1&2 5 operator & 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-6.2 {ParseBitXorExpr procedure, error in LHS "&" subexpr} \
+    -constraints testexprparser -body {
+        testexprparser {1^foo ^ 3} -1
+    } -match glob -returnCodes error -result *
+test parseExpr-6.3 {ParseBitXorExpr procedure, next lexeme isn't "^"} testexprparser {
+    testexprparser {1&2? 1 : 0} -1
+} {- {} 0 subexpr {1&2? 1 : 0} 11 operator ? 0 subexpr 1&2 5 operator & 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 1 1 text 1 0 subexpr 0 1 text 0 0 {}}
+test parseExpr-6.4 {ParseBitXorExpr procedure, next lexeme is "^"} testexprparser {
+    testexprparser {1&2 ^ 3} -1
+} {- {} 0 subexpr {1&2 ^ 3} 9 operator ^ 0 subexpr 1&2 5 operator & 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-6.5 {ParseBitXorExpr procedure, bad lexeme after "^"} testexprparser {
+    testexprparser {1&2 ^ 12345678901234567890} -1
+} {- {} 0 subexpr {1&2 ^ 12345678901234567890} 9 operator ^ 0 subexpr 1&2 5 operator & 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 12345678901234567890 1 text 12345678901234567890 0 {}}
+test parseExpr-6.6 {ParseBitXorExpr procedure, valid RHS subexpression} testexprparser {
+    testexprparser {1&2 ^ 3 ^ 4} -1
+} {- {} 0 subexpr {1&2 ^ 3 ^ 4} 13 operator ^ 0 subexpr {1&2 ^ 3} 9 operator ^ 0 subexpr 1&2 5 operator & 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 subexpr 4 1 text 4 0 {}}
+test parseExpr-6.7 {ParseBitXorExpr procedure, error in RHS subexpression} \
+    -constraints testexprparser -body {
+        testexprparser {1&2 ^ 3 ^ martha} -1
+    } -match glob -returnCodes error -result *
+
+test parseExpr-7.1 {ParseBitAndExpr procedure, valid LHS equality subexpr} testexprparser {
+    testexprparser {1==2 & 3} -1
+} {- {} 0 subexpr {1==2 & 3} 9 operator & 0 subexpr 1==2 5 operator == 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-7.2 {ParseBitAndExpr procedure, error in LHS equality subexpr} \
+    -constraints testexprparser -body {
+        testexprparser {1!=foo & 3} -1
+    } -match glob -returnCodes error -result *
+test parseExpr-7.3 {ParseBitAndExpr procedure, next lexeme isn't "&"} testexprparser {
+    testexprparser {1==2? 1 : 0} -1
+} {- {} 0 subexpr {1==2? 1 : 0} 11 operator ? 0 subexpr 1==2 5 operator == 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 1 1 text 1 0 subexpr 0 1 text 0 0 {}}
+test parseExpr-7.4 {ParseBitAndExpr procedure, next lexeme is "&"} testexprparser {
+    testexprparser {1>2 & 3} -1
+} {- {} 0 subexpr {1>2 & 3} 9 operator & 0 subexpr 1>2 5 operator > 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-7.5 {ParseBitAndExpr procedure, bad lexeme after "&"} {testexprparser} {
+    testexprparser {1==2 & 12345678901234567890} -1
+} {- {} 0 subexpr {1==2 & 12345678901234567890} 9 operator & 0 subexpr 1==2 5 operator == 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 12345678901234567890 1 text 12345678901234567890 0 {}}
+test parseExpr-7.6 {ParseBitAndExpr procedure, valid RHS subexpression} testexprparser {
+    testexprparser {1<2 & 3 & 4} -1
+} {- {} 0 subexpr {1<2 & 3 & 4} 13 operator & 0 subexpr {1<2 & 3} 9 operator & 0 subexpr 1<2 5 operator < 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 subexpr 4 1 text 4 0 {}}
+test parseExpr-7.7 {ParseBitAndExpr procedure, error in RHS subexpression} \
+    -constraints testexprparser -body {
+        testexprparser {1==2 & 3>2 & martha} -1
+    } -match glob -returnCodes error -result *
+
+test parseExpr-8.1 {ParseEqualityExpr procedure, valid LHS relational subexpr} testexprparser {
+    testexprparser {1<2 == 3} -1
+} {- {} 0 subexpr {1<2 == 3} 9 operator == 0 subexpr 1<2 5 operator < 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-8.2 {ParseEqualityExpr procedure, error in LHS relational subexpr} \
+    -constraints testexprparser -body {
+        testexprparser {1>=foo == 3} -1
+    } -match glob -returnCodes error -result *
+test parseExpr-8.3 {ParseEqualityExpr procedure, next lexeme isn't "==" or "!="} testexprparser {
+    testexprparser {1<2? 1 : 0} -1
+} {- {} 0 subexpr {1<2? 1 : 0} 11 operator ? 0 subexpr 1<2 5 operator < 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 1 1 text 1 0 subexpr 0 1 text 0 0 {}}
+test parseExpr-8.4 {ParseEqualityExpr procedure, next lexeme is "==" or "!="} testexprparser {
+    testexprparser {1<2 == 3} -1
+} {- {} 0 subexpr {1<2 == 3} 9 operator == 0 subexpr 1<2 5 operator < 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-8.5 {ParseEqualityExpr procedure, next lexeme is "==" or "!="} testexprparser {
+    testexprparser {1<2 != 3} -1
+} {- {} 0 subexpr {1<2 != 3} 9 operator != 0 subexpr 1<2 5 operator < 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-8.6 {ParseEqualityExpr procedure, bad lexeme after "==" or "!="} testexprparser {
+    testexprparser {1<2 == 12345678901234567890} -1
+} {- {} 0 subexpr {1<2 == 12345678901234567890} 9 operator == 0 subexpr 1<2 5 operator < 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 12345678901234567890 1 text 12345678901234567890 0 {}}
+test parseExpr-8.7 {ParseEqualityExpr procedure, valid RHS subexpression} testexprparser {
+    testexprparser {1<2 == 3 == 4} -1
+} {- {} 0 subexpr {1<2 == 3 == 4} 13 operator == 0 subexpr {1<2 == 3} 9 operator == 0 subexpr 1<2 5 operator < 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 subexpr 4 1 text 4 0 {}}
+test parseExpr-8.8 {ParseEqualityExpr procedure, error in RHS subexpression} \
+    -constraints testexprparser -body {
+        testexprparser {1<2 == 3 != martha} -1
+    } -match glob -returnCodes error -result *
+
+test parseExpr-9.1 {ParseRelationalExpr procedure, valid LHS shift subexpr} testexprparser {
+    testexprparser {1<<2 < 3} -1
+} {- {} 0 subexpr {1<<2 < 3} 9 operator < 0 subexpr 1<<2 5 operator << 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-9.2 {ParseRelationalExpr procedure, error in LHS shift subexpr} \
+    -constraints testexprparser -body {
+        testexprparser {1>=foo < 3} -1
+    } -match glob -returnCodes error -result *
+test parseExpr-9.3 {ParseRelationalExpr procedure, next lexeme isn't relational op} testexprparser {
+    testexprparser {1<<2? 1 : 0} -1
+} {- {} 0 subexpr {1<<2? 1 : 0} 11 operator ? 0 subexpr 1<<2 5 operator << 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 1 1 text 1 0 subexpr 0 1 text 0 0 {}}
+test parseExpr-9.4 {ParseRelationalExpr procedure, next lexeme is relational op} testexprparser {
+    testexprparser {1<<2 < 3} -1
+} {- {} 0 subexpr {1<<2 < 3} 9 operator < 0 subexpr 1<<2 5 operator << 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-9.5 {ParseRelationalExpr procedure, next lexeme is relational op} testexprparser {
+    testexprparser {1>>2 > 3} -1
+} {- {} 0 subexpr {1>>2 > 3} 9 operator > 0 subexpr 1>>2 5 operator >> 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-9.6 {ParseRelationalExpr procedure, next lexeme is relational op} testexprparser {
+    testexprparser {1<<2 <= 3} -1
+} {- {} 0 subexpr {1<<2 <= 3} 9 operator <= 0 subexpr 1<<2 5 operator << 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-9.7 {ParseRelationalExpr procedure, next lexeme is relational op} testexprparser {
+    testexprparser {1<<2 >= 3} -1
+} {- {} 0 subexpr {1<<2 >= 3} 9 operator >= 0 subexpr 1<<2 5 operator << 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-9.8 {ParseRelationalExpr procedure, bad lexeme after relational op} testexprparser {
+    testexprparser {1<<2 < 12345678901234567890} -1
+} {- {} 0 subexpr {1<<2 < 12345678901234567890} 9 operator < 0 subexpr 1<<2 5 operator << 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 12345678901234567890 1 text 12345678901234567890 0 {}}
+test parseExpr-9.9 {ParseRelationalExpr procedure, valid RHS subexpression} testexprparser {
+    testexprparser {1<<2 < 3 < 4} -1
+} {- {} 0 subexpr {1<<2 < 3 < 4} 13 operator < 0 subexpr {1<<2 < 3} 9 operator < 0 subexpr 1<<2 5 operator << 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 subexpr 4 1 text 4 0 {}}
+test parseExpr-9.10 {ParseRelationalExpr procedure, error in RHS subexpression} \
+    -constraints testexprparser -body {
+        testexprparser {1<<2 < 3 > martha} -1
+    } -match glob -returnCodes error -result *
+
+test parseExpr-10.1 {ParseShiftExpr procedure, valid LHS add subexpr} testexprparser {
+    testexprparser {1+2 << 3} -1
+} {- {} 0 subexpr {1+2 << 3} 9 operator << 0 subexpr 1+2 5 operator + 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-10.2 {ParseShiftExpr procedure, error in LHS add subexpr} \
+    -constraints testexprparser -body {
+        testexprparser {1-foo << 3} -1
+    } -match glob -returnCodes error -result *
+test parseExpr-10.3 {ParseShiftExpr procedure, next lexeme isn't "<<" or ">>"} testexprparser {
+    testexprparser {1+2? 1 : 0} -1
+} {- {} 0 subexpr {1+2? 1 : 0} 11 operator ? 0 subexpr 1+2 5 operator + 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 1 1 text 1 0 subexpr 0 1 text 0 0 {}}
+test parseExpr-10.4 {ParseShiftExpr procedure, next lexeme is "<<" or ">>"} testexprparser {
+    testexprparser {1+2 << 3} -1
+} {- {} 0 subexpr {1+2 << 3} 9 operator << 0 subexpr 1+2 5 operator + 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-10.5 {ParseShiftExpr procedure, next lexeme is "<<" or ">>"} testexprparser {
+    testexprparser {1+2 >> 3} -1
+} {- {} 0 subexpr {1+2 >> 3} 9 operator >> 0 subexpr 1+2 5 operator + 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-10.6 {ParseShiftExpr procedure, bad lexeme after "<<" or ">>"} testexprparser {
+    testexprparser {1+2 << 12345678901234567890} -1
+} {- {} 0 subexpr {1+2 << 12345678901234567890} 9 operator << 0 subexpr 1+2 5 operator + 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 12345678901234567890 1 text 12345678901234567890 0 {}}
+test parseExpr-10.7 {ParseShiftExpr procedure, valid RHS subexpression} testexprparser {
+    testexprparser {1+2 << 3 << 4} -1
+} {- {} 0 subexpr {1+2 << 3 << 4} 13 operator << 0 subexpr {1+2 << 3} 9 operator << 0 subexpr 1+2 5 operator + 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 subexpr 4 1 text 4 0 {}}
+test parseExpr-10.8 {ParseShiftExpr procedure, error in RHS subexpression} \
+    -constraints testexprparser -body {
+        testexprparser {1+2 << 3 >> martha} -1
+    } -match glob -returnCodes error -result *
+
+test parseExpr-11.1 {ParseAddExpr procedure, valid LHS multiply subexpr} testexprparser {
+    testexprparser {1*2 + 3} -1
+} {- {} 0 subexpr {1*2 + 3} 9 operator + 0 subexpr 1*2 5 operator * 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-11.2 {ParseAddExpr procedure, error in LHS multiply subexpr} \
+    -constraints testexprparser -body {
+        testexprparser {1/foo + 3} -1
+    } -match glob -returnCodes error -result *
+test parseExpr-11.3 {ParseAddExpr procedure, next lexeme isn't "+" or "-"} testexprparser {
+    testexprparser {1*2? 1 : 0} -1
+} {- {} 0 subexpr {1*2? 1 : 0} 11 operator ? 0 subexpr 1*2 5 operator * 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 1 1 text 1 0 subexpr 0 1 text 0 0 {}}
+test parseExpr-11.4 {ParseAddExpr procedure, next lexeme is "+" or "-"} testexprparser {
+    testexprparser {1*2 + 3} -1
+} {- {} 0 subexpr {1*2 + 3} 9 operator + 0 subexpr 1*2 5 operator * 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-11.5 {ParseAddExpr procedure, next lexeme is "+" or "-"} testexprparser {
+    testexprparser {1*2 - 3} -1
+} {- {} 0 subexpr {1*2 - 3} 9 operator - 0 subexpr 1*2 5 operator * 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-11.6 {ParseAddExpr procedure, bad lexeme after "+" or "-"} testexprparser {
+    testexprparser {1*2 + 12345678901234567890} -1
+} {- {} 0 subexpr {1*2 + 12345678901234567890} 9 operator + 0 subexpr 1*2 5 operator * 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 12345678901234567890 1 text 12345678901234567890 0 {}}
+test parseExpr-11.7 {ParseAddExpr procedure, valid RHS subexpression} testexprparser {
+    testexprparser {1*2 + 3 + 4} -1
+} {- {} 0 subexpr {1*2 + 3 + 4} 13 operator + 0 subexpr {1*2 + 3} 9 operator + 0 subexpr 1*2 5 operator * 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 subexpr 4 1 text 4 0 {}}
+test parseExpr-11.8 {ParseAddExpr procedure, error in RHS subexpression} \
+    -constraints testexprparser -body {
+        testexprparser {1*2 + 3 - martha} -1
+    } -match glob -returnCodes error -result *
+
+test parseExpr-12.1 {ParseAddExpr procedure, valid LHS multiply subexpr} testexprparser {
+    testexprparser {1*2 + 3} -1
+} {- {} 0 subexpr {1*2 + 3} 9 operator + 0 subexpr 1*2 5 operator * 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-12.2 {ParseAddExpr procedure, error in LHS multiply subexpr} \
+    -constraints testexprparser -body {
+        testexprparser {1/foo + 3} -1
+    } -match glob -returnCodes error -result *
+test parseExpr-12.3 {ParseAddExpr procedure, next lexeme isn't "+" or "-"} testexprparser {
+    testexprparser {1*2? 1 : 0} -1
+} {- {} 0 subexpr {1*2? 1 : 0} 11 operator ? 0 subexpr 1*2 5 operator * 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 1 1 text 1 0 subexpr 0 1 text 0 0 {}}
+test parseExpr-12.4 {ParseAddExpr procedure, next lexeme is "+" or "-"} testexprparser {
+    testexprparser {1*2 + 3} -1
+} {- {} 0 subexpr {1*2 + 3} 9 operator + 0 subexpr 1*2 5 operator * 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-12.5 {ParseAddExpr procedure, next lexeme is "+" or "-"} testexprparser {
+    testexprparser {1*2 - 3} -1
+} {- {} 0 subexpr {1*2 - 3} 9 operator - 0 subexpr 1*2 5 operator * 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-12.6 {ParseAddExpr procedure, bad lexeme after "+" or "-"} testexprparser {
+    testexprparser {1*2 + 12345678901234567890} -1
+} {- {} 0 subexpr {1*2 + 12345678901234567890} 9 operator + 0 subexpr 1*2 5 operator * 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 12345678901234567890 1 text 12345678901234567890 0 {}}
+test parseExpr-12.7 {ParseAddExpr procedure, valid RHS subexpression} testexprparser {
+    testexprparser {1*2 + 3 + 4} -1
+} {- {} 0 subexpr {1*2 + 3 + 4} 13 operator + 0 subexpr {1*2 + 3} 9 operator + 0 subexpr 1*2 5 operator * 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 subexpr 4 1 text 4 0 {}}
+test parseExpr-12.8 {ParseAddExpr procedure, error in RHS subexpression} \
+    -constraints testexprparser -body {
+        testexprparser {1*2 + 3 - martha} -1
+    } -match glob -returnCodes error -result *
+
+test parseExpr-13.1 {ParseMultiplyExpr procedure, valid LHS unary subexpr} testexprparser {
+    testexprparser {+2 * 3} -1
+} {- {} 0 subexpr {+2 * 3} 7 operator * 0 subexpr +2 3 operator + 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-13.2 {ParseMultiplyExpr procedure, error in LHS unary subexpr} testexprparser {
+    testexprparser {-12345678901234567890 * 3} -1
+} {- {} 0 subexpr {-12345678901234567890 * 3} 7 operator * 0 subexpr -12345678901234567890 3 operator - 0 subexpr 12345678901234567890 1 text 12345678901234567890 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-13.3 {ParseMultiplyExpr procedure, next lexeme isn't "*", "/", or "%"} testexprparser {
+    testexprparser {+2? 1 : 0} -1
+} {- {} 0 subexpr {+2? 1 : 0} 9 operator ? 0 subexpr +2 3 operator + 0 subexpr 2 1 text 2 0 subexpr 1 1 text 1 0 subexpr 0 1 text 0 0 {}}
+test parseExpr-13.4 {ParseMultiplyExpr procedure, next lexeme is "*", "/", or "%"} testexprparser {
+    testexprparser {-123 * 3} -1
+} {- {} 0 subexpr {-123 * 3} 7 operator * 0 subexpr -123 3 operator - 0 subexpr 123 1 text 123 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-13.5 {ParseMultiplyExpr procedure, next lexeme is "*", "/", or "%"} testexprparser {
+    testexprparser {+-456 / 3} -1
+} {- {} 0 subexpr {+-456 / 3} 9 operator / 0 subexpr +-456 5 operator + 0 subexpr -456 3 operator - 0 subexpr 456 1 text 456 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-13.6 {ParseMultiplyExpr procedure, next lexeme is "*", "/", or "%"} testexprparser {
+    testexprparser {+-456 % 3} -1
+} {- {} 0 subexpr {+-456 % 3} 9 operator % 0 subexpr +-456 5 operator + 0 subexpr -456 3 operator - 0 subexpr 456 1 text 456 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-13.7 {ParseMultiplyExpr procedure, bad lexeme after "*", "/", or "%"} testexprparser {
+    testexprparser {--++5 / 12345678901234567890} -1
+} {- {} 0 subexpr {--++5 / 12345678901234567890} 13 operator / 0 subexpr --++5 9 operator - 0 subexpr -++5 7 operator - 0 subexpr ++5 5 operator + 0 subexpr +5 3 operator + 0 subexpr 5 1 text 5 0 subexpr 12345678901234567890 1 text 12345678901234567890 0 {}}
+test parseExpr-13.8 {ParseMultiplyExpr procedure, valid RHS subexpression} testexprparser {
+    testexprparser {-2 / 3 % 4} -1
+} {- {} 0 subexpr {-2 / 3 % 4} 11 operator % 0 subexpr {-2 / 3} 7 operator / 0 subexpr -2 3 operator - 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 subexpr 4 1 text 4 0 {}}
+test parseExpr-13.9 {ParseMultiplyExpr procedure, error in RHS subexpression} \
+    -constraints testexprparser -body {
+        testexprparser {++2 / 3 * martha} -1
+    } -match glob -returnCodes error -result *
+
+test parseExpr-14.1 {ParseUnaryExpr procedure, first token is unary operator} testexprparser {
+    testexprparser {+2} -1
+} {- {} 0 subexpr +2 3 operator + 0 subexpr 2 1 text 2 0 {}}
+test parseExpr-14.2 {ParseUnaryExpr procedure, first token is unary operator} testexprparser {
+    testexprparser {-2} -1
+} {- {} 0 subexpr -2 3 operator - 0 subexpr 2 1 text 2 0 {}}
+test parseExpr-14.3 {ParseUnaryExpr procedure, first token is unary operator} testexprparser {
+    testexprparser {~2} -1
+} {- {} 0 subexpr ~2 3 operator ~ 0 subexpr 2 1 text 2 0 {}}
+test parseExpr-14.4 {ParseUnaryExpr procedure, first token is unary operator} testexprparser {
+    testexprparser {!2} -1
+} {- {} 0 subexpr !2 3 operator ! 0 subexpr 2 1 text 2 0 {}}
+test parseExpr-14.5 {ParseUnaryExpr procedure, error in lexeme after unary op} testexprparser {
+    testexprparser {-12345678901234567890} -1
+} {- {} 0 subexpr -12345678901234567890 3 operator - 0 subexpr 12345678901234567890 1 text 12345678901234567890 0 {}}
+test parseExpr-14.6 {ParseUnaryExpr procedure, simple unary expr after unary op} testexprparser {
+    testexprparser {+"1234"} -1
+} {- {} 0 subexpr +\"1234\" 3 operator + 0 subexpr {"1234"} 1 text 1234 0 {}}
+test parseExpr-14.7 {ParseUnaryExpr procedure, another unary expr after unary op} testexprparser {
+    testexprparser {~!{fred}} -1
+} {- {} 0 subexpr ~!{fred} 5 operator ~ 0 subexpr !{fred} 3 operator ! 0 subexpr {{fred}} 1 text fred 0 {}}
+test parseExpr-14.8 {ParseUnaryExpr procedure, error in unary expr after unary op} -constraints testexprparser -body {
+    testexprparser {+-||27} -1
+} -returnCodes error -match glob -result *
+test parseExpr-14.9 {ParseUnaryExpr procedure, error in unary expr after unary op} -constraints testexprparser -body {
+    testexprparser {+-||27} -1
+} -returnCodes error -match glob -result *
+test parseExpr-14.10 {ParseUnaryExpr procedure, first token is not unary op} testexprparser {
+    testexprparser {123} -1
+} {- {} 0 subexpr 123 1 text 123 0 {}}
+test parseExpr-14.11 {ParseUnaryExpr procedure, not unary expr, complex primary expr} testexprparser {
+    testexprparser {(1+2)} -1
+} {- {} 0 subexpr 1+2 5 operator + 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 {}}
+test parseExpr-14.12 {ParseUnaryExpr procedure, not unary expr, error in primary expr} testexprparser {
+    testexprparser {(12345678901234567890)} -1
+} {- {} 0 subexpr 12345678901234567890 1 text 12345678901234567890 0 {}}
+
+test parseExpr-15.1 {ParsePrimaryExpr procedure, just parenthesized subexpr} testexprparser {
+    testexprparser {({abc}/{def})} -1
+} {- {} 0 subexpr {{abc}/{def}} 5 operator / 0 subexpr {{abc}} 1 text abc 0 subexpr {{def}} 1 text def 0 {}}
+test parseExpr-15.2 {ParsePrimaryExpr procedure, bad lexeme after "("} {testexprparser} {
+    testexprparser {(12345678901234567890)} -1
+} {- {} 0 subexpr 12345678901234567890 1 text 12345678901234567890 0 {}}
+test parseExpr-15.3 {ParsePrimaryExpr procedure, valid parenthesized subexpr} testexprparser {
+    testexprparser {({abc}? 2*4 : -6)} -1
+} {- {} 0 subexpr {{abc}? 2*4 : -6} 13 operator ? 0 subexpr {{abc}} 1 text abc 0 subexpr 2*4 5 operator * 0 subexpr 2 1 text 2 0 subexpr 4 1 text 4 0 subexpr -6 3 operator - 0 subexpr 6 1 text 6 0 {}}
+test parseExpr-15.4 {ParsePrimaryExpr procedure, error in parenthesized subexpr} -constraints testexprparser -body {
+    testexprparser {(? 123 : 456)} -1
+} -returnCodes error -match glob -result *
+test parseExpr-15.5 {ParsePrimaryExpr procedure, missing ")" after in parenthesized subexpr} -constraints testexprparser -body {
+    testexprparser {({abc}/{def}} -1
+} -returnCodes error -match glob -result *
+test parseExpr-15.6 {ParsePrimaryExpr procedure, primary is literal} testexprparser {
+    testexprparser {12345} -1
+} {- {} 0 subexpr 12345 1 text 12345 0 {}}
+test parseExpr-15.7 {ParsePrimaryExpr procedure, primary is literal} testexprparser {
+    testexprparser {12345.6789} -1
+} {- {} 0 subexpr 12345.6789 1 text 12345.6789 0 {}}
+test parseExpr-15.8 {ParsePrimaryExpr procedure, primary is var reference} testexprparser {
+    testexprparser {$a} -1
+} {- {} 0 subexpr {$a} 2 variable {$a} 1 text a 0 {}}
+test parseExpr-15.9 {ParsePrimaryExpr procedure, primary is var reference} testexprparser {
+    testexprparser {$a(hello$there)} -1
+} {- {} 0 subexpr {$a(hello$there)} 5 variable {$a(hello$there)} 4 text a 0 text hello 0 variable {$there} 1 text there 0 {}}
+test parseExpr-15.10 {ParsePrimaryExpr procedure, primary is var reference} testexprparser {
+    testexprparser {$a()} -1
+} {- {} 0 subexpr {$a()} 3 variable {$a()} 2 text a 0 text {} 0 {}}
+test parseExpr-15.11 {ParsePrimaryExpr procedure, error in var reference} -constraints testexprparser -body {
+    testexprparser {$a(} -1
+} -returnCodes error -match glob -result *
+test parseExpr-15.12 {ParsePrimaryExpr procedure, primary is quoted string} testexprparser {
+    testexprparser {"abc $xyz def"} -1
+} {- {} 0 subexpr {"abc $xyz def"} 5 word {"abc $xyz def"} 4 text {abc } 0 variable {$xyz} 1 text xyz 0 text { def} 0 {}}
+test parseExpr-15.13 {ParsePrimaryExpr procedure, error in quoted string} -constraints testexprparser -body {
+    testexprparser {"$a(12"} -1
+} -returnCodes error -match glob -result *
+test parseExpr-15.14 {ParsePrimaryExpr procedure, quoted string has multiple tokens} testexprparser {
+    testexprparser {"abc [xyz] $def"} -1
+} {- {} 0 subexpr {"abc [xyz] $def"} 6 word {"abc [xyz] $def"} 5 text {abc } 0 command {[xyz]} 0 text { } 0 variable {$def} 1 text def 0 {}}
+test parseExpr-15.15 {ParsePrimaryExpr procedure, primary is command} testexprparser {
+    testexprparser {[def]} -1
+} {- {} 0 subexpr {[def]} 1 command {[def]} 0 {}}
+test parseExpr-15.16 {ParsePrimaryExpr procedure, primary is multiple commands} testexprparser {
+    testexprparser {[one; two; three; four;]} -1
+} {- {} 0 subexpr {[one; two; three; four;]} 1 command {[one; two; three; four;]} 0 {}}
+test parseExpr-15.17 {ParsePrimaryExpr procedure, primary is multiple commands} testexprparser {
+    testexprparser {[one; two; three; four;]} -1
+} {- {} 0 subexpr {[one; two; three; four;]} 1 command {[one; two; three; four;]} 0 {}}
+test parseExpr-15.18 {ParsePrimaryExpr procedure, missing close bracket} -constraints testexprparser -body {
+    testexprparser {[one} -1
+} -returnCodes error -match glob -result *
+test parseExpr-15.19 {ParsePrimaryExpr procedure, primary is braced string} testexprparser {
+    testexprparser {{hello world}} -1
+} {- {} 0 subexpr {{hello world}} 1 text {hello world} 0 {}}
+test parseExpr-15.20 {ParsePrimaryExpr procedure, error in primary, which is braced string} -constraints testexprparser -body {
+    testexprparser "\{abc\\\n" -1
+} -returnCodes error -match glob -result *
+test parseExpr-15.21 {ParsePrimaryExpr procedure, primary is braced string with multiple tokens} testexprparser {
+    testexprparser "\{  \\
+ +123 \}" -1
+} {- {} 0 subexpr \{\ \ \\\n\ +123\ \} 4 word \{\ \ \\\n\ +123\ \} 3 text {  } 0 backslash \\\n\  0 text {+123 } 0 {}}
+test parseExpr-15.22 {ParsePrimaryExpr procedure, primary is function call} testexprparser {
+    testexprparser {foo(123)} -1
+} {- {} 0 subexpr foo(123) 3 operator foo 0 subexpr 123 1 text 123 0 {}}
+test parseExpr-15.23 {ParsePrimaryExpr procedure, bad lexeme after function name} -constraints testexprparser -body {
+    testexprparser {foo 12345678901234567890 123)} -1
+} -returnCodes error -match glob -result *
+test parseExpr-15.24 {ParsePrimaryExpr procedure, lexeme after function name isn't "("} \
+    -constraints testexprparser -body {
+        testexprparser {foo 27.4 123)} -1
+    } -match glob -returnCodes error -result *
+test parseExpr-15.25 {ParsePrimaryExpr procedure, bad lexeme after "("} testexprparser {
+    testexprparser {foo(12345678901234567890)} -1
+} {- {} 0 subexpr foo(12345678901234567890) 3 operator foo 0 subexpr 12345678901234567890 1 text 12345678901234567890 0 {}}
+test parseExpr-15.26 {ParsePrimaryExpr procedure, function call, one arg} testexprparser {
+    testexprparser {foo(27*4)} -1
+} {- {} 0 subexpr foo(27*4) 7 operator foo 0 subexpr 27*4 5 operator * 0 subexpr 27 1 text 27 0 subexpr 4 1 text 4 0 {}}
+test parseExpr-15.27 {ParsePrimaryExpr procedure, error in function arg} -constraints testexprparser -body {
+    testexprparser {foo(*1-2)} -1
+} -returnCodes error -match glob -result *
+test parseExpr-15.28 {ParsePrimaryExpr procedure, error in function arg} -constraints testexprparser -body {
+    testexprparser {foo(*1-2)} -1
+} -returnCodes error -match glob -result *
+test parseExpr-15.29 {ParsePrimaryExpr procedure, function call, comma after arg} testexprparser {
+    testexprparser {foo(27-2, (-2*[foo]))} -1
+} {- {} 0 subexpr {foo(27-2, (-2*[foo]))} 15 operator foo 0 subexpr 27-2 5 operator - 0 subexpr 27 1 text 27 0 subexpr 2 1 text 2 0 subexpr {-2*[foo]} 7 operator * 0 subexpr -2 3 operator - 0 subexpr 2 1 text 2 0 subexpr {[foo]} 1 command {[foo]} 0 {}}
+test parseExpr-15.30 {ParsePrimaryExpr procedure, bad lexeme after comma} testexprparser {
+    testexprparser {foo(123, 12345678901234567890)} -1
+} {- {} 0 subexpr {foo(123, 12345678901234567890)} 5 operator foo 0 subexpr 123 1 text 123 0 subexpr 12345678901234567890 1 text 12345678901234567890 0 {}}
+test parseExpr-15.31 {ParsePrimaryExpr procedure, lexeme not "," or ")" after arg} -constraints  testexprparser -body {
+    testexprparser {foo(123 [foo])} -1
+} -returnCodes error -match glob -result *
+test parseExpr-15.32 {ParsePrimaryExpr procedure, bad lexeme after primary} -constraints testexprparser -body {
+    testexprparser {123 12345678901234567890} -1
+} -returnCodes error -match glob -result *
+test parseExpr-15.33 {ParsePrimaryExpr procedure, comma-specific message} -constraints testexprparser -body {
+    testexprparser {123+,456} -1
+} -returnCodes error -match glob -result *
+test parseExpr-15.34 {ParsePrimaryExpr procedure, single equal-specific message} -constraints testexprparser -body {
+    testexprparser {123+=456} -1
+} -returnCodes error -match glob -result *
+test parseExpr-15.35 {ParsePrimaryExpr procedure, error in parenthesized subexpr} -constraints testexprparser -body {
+    testexprparser {(: 123 : 456)} -1
+} -returnCodes error -match glob -result *
+test parseExpr-15.36 {ParsePrimaryExpr procedure, missing close-bracket} -constraints testexprparser -body {
+    # Test for Bug 681841
+    testexprparser {[set a [format bc]} -1
+} -returnCodes error -match glob -result *
+
+test parseExpr-16.1 {GetLexeme procedure, whitespace before lexeme} testexprparser {
+    testexprparser {   123} -1
+} {- {} 0 subexpr 123 1 text 123 0 {}}
+test parseExpr-16.2 {GetLexeme procedure, whitespace before lexeme} testexprparser {
+    testexprparser {  \
+456} -1
+} {- {} 0 subexpr 456 1 text 456 0 {}}
+test parseExpr-16.3 {GetLexeme procedure, no lexeme after whitespace} testexprparser {
+    testexprparser { 123 \
+   } -1
+} {- {} 0 subexpr 123 1 text 123 0 {}}
+test parseExpr-16.4 {GetLexeme procedure, integer lexeme} testexprparser {
+    testexprparser {000} -1
+} {- {} 0 subexpr 000 1 text 000 0 {}}
+test parseExpr-16.5 {GetLexeme procedure, integer lexeme too big} testexprparser {
+    testexprparser {12345678901234567890} -1
+} {- {} 0 subexpr 12345678901234567890 1 text 12345678901234567890 0 {}}
+test parseExpr-16.6 {GetLexeme procedure, bad integer lexeme} -constraints testexprparser -body {
+    testexprparser {0o999} -1
+} -returnCodes error -match glob -result {*invalid octal number*}
+test parseExpr-16.7 {GetLexeme procedure, double lexeme} testexprparser {
+    testexprparser {0.999} -1
+} {- {} 0 subexpr 0.999 1 text 0.999 0 {}}
+test parseExpr-16.8 {GetLexeme procedure, double lexeme} testexprparser {
+    testexprparser {.123} -1
+} {- {} 0 subexpr .123 1 text .123 0 {}}
+test parseExpr-16.9 {GetLexeme procedure, double lexeme} {testexprparser unix} {
+    testexprparser {nan} -1
+} {- {} 0 subexpr nan 1 text nan 0 {}}
+test parseExpr-16.10 {GetLexeme procedure, double lexeme} {testexprparser unix} {
+    testexprparser {NaN} -1
+} {- {} 0 subexpr NaN 1 text NaN 0 {}}
+test parseExpr-16.11a {GetLexeme procedure, bad double lexeme too big} {testexprparser && !ieeeFloatingPoint} {
+    list [catch {testexprparser {123.e+99999999999999} -1} msg] $msg
+} {1 {floating-point value too large to represent}}
+test parseExpr-16.11b {GetLexeme procedure, bad double lexeme too big} {testexprparser && ieeeFloatingPoint} {
+    list [catch {testexprparser {123.e+99999999999999} -1} msg] $msg
+} {0 {- {} 0 subexpr 123.e+99999999999999 1 text 123.e+99999999999999 0 {}}}
+test parseExpr-16.12 {GetLexeme procedure, bad double lexeme} -constraints testexprparser -body {
+    testexprparser {123.4x56} -1
+} -returnCodes error -match glob -result *
+test parseExpr-16.13 {GetLexeme procedure, lexeme is "["} testexprparser {
+    testexprparser {[foo]} -1
+} {- {} 0 subexpr {[foo]} 1 command {[foo]} 0 {}}
+test parseExpr-16.14 {GetLexeme procedure, lexeme is open brace} testexprparser {
+    testexprparser {{bar}} -1
+} {- {} 0 subexpr {{bar}} 1 text bar 0 {}}
+test parseExpr-16.15 {GetLexeme procedure, lexeme is "("} testexprparser {
+    testexprparser {(123)} -1
+} {- {} 0 subexpr 123 1 text 123 0 {}}
+test parseExpr-16.16 {GetLexeme procedure, lexeme is ")"} testexprparser {
+    testexprparser {(2*3)} -1
+} {- {} 0 subexpr 2*3 5 operator * 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-16.17 {GetLexeme procedure, lexeme is "$"} testexprparser {
+    testexprparser {$wombat} -1
+} {- {} 0 subexpr {$wombat} 2 variable {$wombat} 1 text wombat 0 {}}
+test parseExpr-16.18 "GetLexeme procedure, lexeme is '\"'" testexprparser {
+    testexprparser {"fred"} -1
+} {- {} 0 subexpr {"fred"} 1 text fred 0 {}}
+test parseExpr-16.19 {GetLexeme procedure, lexeme is ","} testexprparser {
+    testexprparser {foo(1,2)} -1
+} {- {} 0 subexpr foo(1,2) 5 operator foo 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 {}}
+test parseExpr-16.20 {GetLexeme procedure, lexeme is "*"} testexprparser {
+    testexprparser {$a*$b} -1
+} {- {} 0 subexpr {$a*$b} 7 operator * 0 subexpr {$a} 2 variable {$a} 1 text a 0 subexpr {$b} 2 variable {$b} 1 text b 0 {}}
+test parseExpr-16.21 {GetLexeme procedure, lexeme is "/"} testexprparser {
+    testexprparser {5/6} -1
+} {- {} 0 subexpr 5/6 5 operator / 0 subexpr 5 1 text 5 0 subexpr 6 1 text 6 0 {}}
+test parseExpr-16.22 {GetLexeme procedure, lexeme is "%"} testexprparser {
+    testexprparser {5%[xxx]} -1
+} {- {} 0 subexpr {5%[xxx]} 5 operator % 0 subexpr 5 1 text 5 0 subexpr {[xxx]} 1 command {[xxx]} 0 {}}
+test parseExpr-16.23 {GetLexeme procedure, lexeme is "+"} testexprparser {
+    testexprparser {1+2} -1
+} {- {} 0 subexpr 1+2 5 operator + 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 {}}
+test parseExpr-16.24 {GetLexeme procedure, lexeme is "-"} testexprparser {
+    testexprparser {.12-0e27} -1
+} {- {} 0 subexpr .12-0e27 5 operator - 0 subexpr .12 1 text .12 0 subexpr 0e27 1 text 0e27 0 {}}
+test parseExpr-16.25 {GetLexeme procedure, lexeme is "?" or ":"} testexprparser {
+    testexprparser {$b? 1 : 0} -1
+} {- {} 0 subexpr {$b? 1 : 0} 8 operator ? 0 subexpr {$b} 2 variable {$b} 1 text b 0 subexpr 1 1 text 1 0 subexpr 0 1 text 0 0 {}}
+test parseExpr-16.26 {GetLexeme procedure, lexeme is "<"} testexprparser {
+    testexprparser {2<3} -1
+} {- {} 0 subexpr 2<3 5 operator < 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-16.27 {GetLexeme procedure, lexeme is "<<"} testexprparser {
+    testexprparser {2<<3} -1
+} {- {} 0 subexpr 2<<3 5 operator << 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-16.28 {GetLexeme procedure, lexeme is "<="} testexprparser {
+    testexprparser {2<=3} -1
+} {- {} 0 subexpr 2<=3 5 operator <= 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-16.29 {GetLexeme procedure, lexeme is ">"} testexprparser {
+    testexprparser {2>3} -1
+} {- {} 0 subexpr 2>3 5 operator > 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-16.30 {GetLexeme procedure, lexeme is ">>"} testexprparser {
+    testexprparser {2>>3} -1
+} {- {} 0 subexpr 2>>3 5 operator >> 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-16.31 {GetLexeme procedure, lexeme is ">="} testexprparser {
+    testexprparser {2>=3} -1
+} {- {} 0 subexpr 2>=3 5 operator >= 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-16.32 {GetLexeme procedure, lexeme is "=="} testexprparser {
+    testexprparser {2==3} -1
+} {- {} 0 subexpr 2==3 5 operator == 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-16.33 {GetLexeme procedure, bad lexeme starting with "="} -constraints testexprparser -body {
+    testexprparser {2=+3} -1
+} -returnCodes error -match glob -result *
+test parseExpr-16.34 {GetLexeme procedure, lexeme is "!="} testexprparser {
+    testexprparser {2!=3} -1
+} {- {} 0 subexpr 2!=3 5 operator != 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-16.35 {GetLexeme procedure, lexeme is "!"} testexprparser {
+    testexprparser {!2} -1
+} {- {} 0 subexpr !2 3 operator ! 0 subexpr 2 1 text 2 0 {}}
+test parseExpr-16.36 {GetLexeme procedure, lexeme is "&&"} testexprparser {
+    testexprparser {2&&3} -1
+} {- {} 0 subexpr 2&&3 5 operator && 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-16.37 {GetLexeme procedure, lexeme is "&"} testexprparser {
+    testexprparser {1&2} -1
+} {- {} 0 subexpr 1&2 5 operator & 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 {}}
+test parseExpr-16.38 {GetLexeme procedure, lexeme is "^"} testexprparser {
+    testexprparser {1^2} -1
+} {- {} 0 subexpr 1^2 5 operator ^ 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 {}}
+test parseExpr-16.39 {GetLexeme procedure, lexeme is "||"} testexprparser {
+    testexprparser {2||3} -1
+} {- {} 0 subexpr 2||3 5 operator || 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-16.40 {GetLexeme procedure, lexeme is "|"} testexprparser {
+    testexprparser {1|2} -1
+} {- {} 0 subexpr 1|2 5 operator | 0 subexpr 1 1 text 1 0 subexpr 2 1 text 2 0 {}}
+test parseExpr-16.41 {GetLexeme procedure, lexeme is "~"} testexprparser {
+    testexprparser {~2} -1
+} {- {} 0 subexpr ~2 3 operator ~ 0 subexpr 2 1 text 2 0 {}}
+test parseExpr-16.42 {GetLexeme procedure, lexeme is func name} testexprparser {
+    testexprparser {george()} -1
+} {- {} 0 subexpr george() 1 operator george 0 {}}
+test parseExpr-16.43 {GetLexeme procedure, lexeme is func name} testexprparser {
+    testexprparser {harmonic_ratio(2,3)} -1
+} {- {} 0 subexpr harmonic_ratio(2,3) 5 operator harmonic_ratio 0 subexpr 2 1 text 2 0 subexpr 3 1 text 3 0 {}}
+test parseExpr-16.44 {GetLexeme procedure, unknown lexeme} -constraints testexprparser -body {
+    testexprparser {@27} -1
+} -returnCodes error -match glob -result *
+
+test parseExpr-17.1 {PrependSubExprTokens procedure, expand token array} testexprparser {
+    testexprparser {[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]} -1
+} {- {} 0 subexpr {[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]} 13 operator && 0 subexpr {[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]} 9 operator && 0 subexpr {[string compare [format %c $i] [string index $a $i]]&&[string compare [format %c $i] [string index $a $i]]} 5 operator && 0 subexpr {[string compare [format %c $i] [string index $a $i]]} 1 command {[string compare [format %c $i] [string index $a $i]]} 0 subexpr {[string compare [format %c $i] [string index $a $i]]} 1 command {[string compare [format %c $i] [string index $a $i]]} 0 subexpr {[string compare [format %c $i] [string index $a $i]]} 1 command {[string compare [format %c $i] [string index $a $i]]} 0 subexpr {[string compare [format %c $i] [string index $a $i]]} 1 command {[string compare [format %c $i] [string index $a $i]]} 0 {}}
+
+test parseExpr-18.1 {LogSyntaxError procedure, error in expr longer than 60 chars} -constraints testexprparser -body {
+    testexprparser {(+0123456)*(+0123456)*(+0123456)*(+0123456)*(+0123456)*(+0123456)*(+0123456)/} -1
+} -returnCodes error -match glob -result *
+
+test parseExpr-19.1 {TclParseInteger: [Bug 648441]} -body {
+    # Should see this as integer "0" followed by incomplete function "x"
+    # Thus, syntax error.
+    # If Bug 648441 is not fixed, "0x" will be seen as floating point 0.0
+    expr 0x
+} -returnCodes error -match glob -result *
+
+test parseExpr-20.1 {Bug 1451233} {
+    expr 1000000000000000000042
+} 1000000000000000000042
+test parseExpr-20.2 {Bug 1451233} {
+    expr 10000000000000000000420000000042
+} 10000000000000000000420000000042
+test parseExpr-20.3 {Bug 1451233} {
+    expr 10000000000000000000020000000002
+} 10000000000000000000020000000002
+
+test parseExpr-21.1 {error messages} -body {
+    expr @
+} -returnCodes error -result {invalid character "@"
+in expression "@"}
+test parseExpr-21.2 {error messages} -body {
+    expr =
+} -returnCodes error -result {incomplete operator "="
+in expression "="}
+test parseExpr-21.3 {error messages} -body {
+    expr x
+} -returnCodes error -result {invalid bareword "x"
+in expression "x";
+should be "$x" or "{x}" or "x(...)" or ...}
+test parseExpr-21.4 {error messages} -body {
+    expr abcdefghijklmnopqrstuvwxyz
+} -returnCodes error -result {invalid bareword "abcdefghijklmnopqrstuv..."
+in expression "abcdefghijklmnopqrstuv...";
+should be "$abcdefghijklmnopqrstuv..." or "{abcdefghijklmnopqrstuv...}" or "abcdefghijklmnopqrstuv...(...)" or ...}
+test parseExpr-21.5 {error messages} -body {
+    expr {[][]}
+} -returnCodes error -result {missing operator at _@_
+in expression "[]_@_[]"}
+test parseExpr-21.6 {error messages} -body {
+    expr {0 0}
+} -returnCodes error -result {missing operator at _@_
+in expression "0 _@_0"}
+test parseExpr-21.7 {error messages} -body {
+    expr {0o8}
+} -returnCodes error -match glob -result {*invalid octal number*}
+test parseExpr-21.8 {error messages} -body {
+    expr {0o8x}
+} -returnCodes error -match glob -result {*invalid octal number*}
+test parseExpr-21.9 {error messages} -body {
+    expr {"} 
+} -returnCodes error -result {missing "
+in expression """}
+test parseExpr-21.10 {error messages} -body {
+    expr \{ 
+} -returnCodes error -result "missing close-brace
+in expression \"\{\""
+test parseExpr-21.11 {error messages} -body {
+    expr $
+} -returnCodes error -result {invalid character "$"
+in expression "$"}
+test parseExpr-21.12 {error messages} -body {
+    expr {$(}
+} -returnCodes error -result {missing )
+in expression "$("}
+test parseExpr-21.13 {error messages} -body {
+    expr {[""x]}
+} -returnCodes error -result {extra characters after close-quote
+in expression "[""x]"}
+test parseExpr-21.14 {error messages} -body {
+    expr {[}
+} -returnCodes error -result {missing close-bracket
+in expression "["}
+test parseExpr-21.15 {error messages} -body {
+    expr 0~0
+} -returnCodes error -result {missing operator at _@_
+in expression "0_@_~0"}
+test parseExpr-21.16 {error messages} -body {
+    expr ()
+} -returnCodes error -result {empty subexpression at _@_
+in expression "(_@_)"}
+test parseExpr-21.17 {error messages} -body {
+    expr (
+} -returnCodes error -result {unbalanced open paren
+in expression "("}
+test parseExpr-21.18 {error messages} -body {
+    expr a(0,)
+} -returnCodes error -result {missing function argument at _@_
+in expression "a(0,_@_)"}
+test parseExpr-21.19 {error messages} -body {
+    expr {}
+} -returnCodes error -result {empty expression
+in expression ""}
+test parseExpr-21.20 {error messages} -body {
+    expr )
+} -returnCodes error -result {unbalanced close paren
+in expression ")"}
+test parseExpr-21.21 {error messages} -body {
+    expr a(,0)
+} -returnCodes error -result {missing function argument at _@_
+in expression "a(_@_,0)"}
+test parseExpr-21.22 {error messages} -body {
+    expr 0&|0
+} -returnCodes error -result {missing operand at _@_
+in expression "0&_@_|0"}
+test parseExpr-21.23 {error messages} -body {
+    expr 0^^0
+} -returnCodes error -result {missing operand at _@_
+in expression "0^_@_^0"}
+test parseExpr-21.24 {error messages} -body {
+    expr 0|&0
+} -returnCodes error -result {missing operand at _@_
+in expression "0|_@_&0"}
+test parseExpr-21.25 {error messages} -body {
+    expr a(1+,0)
+} -returnCodes error -result {missing operand at _@_
+in expression "a(1+_@_,0)"}
+test parseExpr-21.26 {error messages} -body {
+    expr (0
+} -returnCodes error -result {unbalanced open paren
+in expression "(0"}
+test parseExpr-21.27 {error messages} -body {
+    expr 0?0
+} -returnCodes error -result {missing operator ":" at _@_
+in expression "0?0_@_"}
+test parseExpr-21.28 {error messages} -body {
+    expr 0:0
+} -returnCodes error -result {unexpected operator ":" without preceding "?"
+in expression "0:0"}
+test parseExpr-21.29 {error messages} -body {
+    expr 0)
+} -returnCodes error -result {unbalanced close paren
+in expression "0)"}
+test parseExpr-21.30 {error messages} -body {
+    expr 0,
+} -returnCodes error -result {unexpected "," outside function argument list
+in expression "0,"}
+test parseExpr-21.31 {error messages} -body {
+    expr 0,0
+} -returnCodes error -result {unexpected "," outside function argument list
+in expression "0,0"}
+test parseExpr-21.32 {error messages} -body {
+    expr (0,0)
+} -returnCodes error -result {unexpected "," outside function argument list
+in expression "(0,0)"}
+test parseExpr-21.33 {error messages} -body {
+    expr a(0:0,0)
+} -returnCodes error -result {unexpected operator ":" without preceding "?"
+in expression "a(0:0,0)"}
+test parseExpr-21.34 {error messages} -body {
+    expr {"abcdefghijklmnopqrstuvwxyz"@0}
+} -returnCodes error -result {invalid character "@"
+in expression "...fghijklmnopqrstuvwxyz"@0"}
+test parseExpr-21.35 {error messages} -body {
+    expr {0@"abcdefghijklmnopqrstuvwxyz"}
+} -returnCodes error -result {invalid character "@"
+in expression "0@"abcdefghijklmnopqrstu..."}
+test parseExpr-21.36 {error messages} -body {
+    expr {"abcdefghijklmnopqrstuvwxyz"@"abcdefghijklmnopqrstuvwxyz"}
+} -returnCodes error -result {invalid character "@"
+in expression "...fghijklmnopqrstuvwxyz"@"abcdefghijklmnopqrstu..."}
+test parseExpr-21.37 {error messages} -body {
+    expr [format {"%s" @ 0} [string repeat \u00a7 25]]
+} -returnCodes error -result [format {invalid character "@"
+in expression "...%s" @ 0"} [string repeat \u00a7 10]]
+test parseExpr-21.38 {error messages} -body {
+    expr [format {0 @ "%s"} [string repeat \u00a7 25]]
+} -returnCodes error -result [format {invalid character "@"
+in expression "0 @ "%s..."} [string repeat \u00a7 10]]
+test parseExpr-21.39 {error messages} -body {
+    expr [format {"%s" @ "%s"} [string repeat \u00a7 25] [string repeat \u00a7 25]]
+} -returnCodes error -result [format {invalid character "@"
+in expression "...%s" @ "%s..."} [string repeat \u00a7 10] [string repeat \u00a7 10]]
+test parseExpr-21.40 {error messages} -body {
+    catch {expr {"abcdefghijklmnopqrstuvwxyz"@0}} m o
+    dict get $o -errorinfo
+} -result {invalid character "@"
+in expression "...fghijklmnopqrstuvwxyz"@0"
+    (parsing expression ""abcdefghijklmnopqrstu...")
+    invoked from within
+"expr {"abcdefghijklmnopqrstuvwxyz"@0}"}
+test parseExpr-21.41 {error messages} -body {
+    catch {expr [format {"%s" @ 0} [string repeat \u00a7 25]]} m o
+    dict get $o -errorinfo
+} -result [format {invalid character "@"
+in expression "...%s" @ 0"
+    (parsing expression ""%s...")
+    invoked from within
+"expr [format {"%%s" @ 0} [string repeat \u00a7 25]]"} [string repeat \u00a7 10] [string repeat \u00a7 10]]
+test parseExpr-21.42 {error message} -body {
+    expr {123456789012345678901234567890*"abcdefghijklmnopqrstuvwxyz}
+} -returnCodes error -result {missing "
+in expression "...012345678901234567890*"abcdefghijklmnopqrstuv..."}
+test parseExpr-21.43 {error message} -body {
+    expr "123456789012345678901234567890*\"foobar\$\{abcdefghijklmnopqrstuvwxyz\""
+} -returnCodes error -result "missing close-brace for variable name
+in expression \"...8901234567890*\"foobar\$\{abcdefghijklmnopqrstuv...\""
+test parseExpr-21.44 {error message} -body {
+    expr {123456789012345678901234567890*"foo$bar(abcdefghijklmnopqrstuvwxyz"}
+} -returnCodes error -result {missing )
+in expression "...8901234567890*"foo$bar(abcdefghijklmnopqrstuv..."}
+test parseExpr-21.45 {error message} -body {
+    expr {123456789012345678901234567890*"foo$bar([{}abcdefghijklmnopqrstuvwxyz])"}
+} -returnCodes error -result {extra characters after close-brace
+in expression "...234567890*"foo$bar([{}abcdefghijklmnopqrstuv..."}
+test parseExpr-21.46 {error message} -body {
+    expr {123456789012345678901234567890*"foo$bar([""abcdefghijklmnopqrstuvwxyz])"}
+} -returnCodes error -result {extra characters after close-quote
+in expression "...234567890*"foo$bar([""abcdefghijklmnopqrstuv..."}
+test parseExpr-21.47 {error message} -body {
+    expr {123456789012345678901234567890*"foo$bar([abcdefghijklmnopqrstuvwxyz)"}
+} -returnCodes error -result {missing close-bracket
+in expression "...901234567890*"foo$bar([abcdefghijklmnopqrstuv..."}
+test parseExpr-21.48 {error message} -body {
+    expr "123456789012345678901234567890*\"foo\$bar(\[\{abcdefghijklmnopqrstuvwxyz])\""
+} -returnCodes error -result "missing close-brace
+in expression \"...01234567890*\"foo\$bar(\[\{abcdefghijklmnopqrstuv...\""
+
+test parseExpr-21.49 {error message} -body {
+    expr "123456789012345678901234567890*\{abcdefghijklmnopqrstuvwxyz"
+} -returnCodes error -result "missing close-brace
+in expression \"...012345678901234567890*\{abcdefghijklmnopqrstuv...\""
+
+test parseExpr-21.50 {error message} -body {
+    expr {123456789012345678901234567890*$foo(["abcdefghijklmnopqrstuvwxyz])}
+} -returnCodes error -result {missing "
+in expression "...678901234567890*$foo(["abcdefghijklmnopqrstuv..."}
+test parseExpr-21.51 {error message} -body {
+    expr "123456789012345678901234567890*\$\{abcdefghijklmnopqrstuvwxyz"
+} -returnCodes error -result "missing close-brace for variable name
+in expression \"...12345678901234567890*\$\{abcdefghijklmnopqrstuv...\""
+test parseExpr-21.52 {error message} -body {
+    expr {123456789012345678901234567890*$bar(abcdefghijklmnopqrstuvwxyz}
+} -returnCodes error -result {missing )
+in expression "...45678901234567890*$bar(abcdefghijklmnopqrstuv..."}
+test parseExpr-21.53 {error message} -body {
+    expr {123456789012345678901234567890*$bar([{}abcdefghijklmnopqrstuvwxyz])"}
+} -returnCodes error -result {extra characters after close-brace
+in expression "...8901234567890*$bar([{}abcdefghijklmnopqrstuv..."}
+test parseExpr-21.54 {error message} -body {
+    expr {123456789012345678901234567890*$bar([""abcdefghijklmnopqrstuvwxyz])"}
+} -returnCodes error -result {extra characters after close-quote
+in expression "...8901234567890*$bar([""abcdefghijklmnopqrstuv..."}
+test parseExpr-21.55 {error message} -body {
+    expr {123456789012345678901234567890*$bar([abcdefghijklmnopqrstuvwxyz)"}
+} -returnCodes error -result {missing close-bracket
+in expression "...5678901234567890*$bar([abcdefghijklmnopqrstuv..."}
+test parseExpr-21.56 {error message} -body {
+    expr "123456789012345678901234567890*\$bar(\[\{abcdefghijklmnopqrstuvwxyz])"
+} -returnCodes error -result "missing close-brace
+in expression \"...678901234567890*\$bar(\[\{abcdefghijklmnopqrstuv...\""
+
+test parseExpr-21.57 {error message} -body {
+    expr {123456789012345678901234567890*["abcdefghijklmnopqrstuvwxyz]}
+} -returnCodes error -result {missing "
+in expression "...12345678901234567890*["abcdefghijklmnopqrstuv..."}
+test parseExpr-21.58 {error message} -body {
+    expr "123456789012345678901234567890*\[\$\{abcdefghijklmnopqrstuvwxyz]"
+} -returnCodes error -result "missing close-brace for variable name
+in expression \"...2345678901234567890*\[\$\{abcdefghijklmnopqrstuv...\""
+test parseExpr-21.59 {error message} -body {
+    expr {123456789012345678901234567890*[$bar(abcdefghijklmnopqrstuvwxyz]}
+} -returnCodes error -result {missing )
+in expression "...5678901234567890*[$bar(abcdefghijklmnopqrstuv..."}
+test parseExpr-21.60 {error message} -body {
+    expr {123456789012345678901234567890*[{}abcdefghijklmnopqrstuvwxyz]"}
+} -returnCodes error -result {extra characters after close-brace
+in expression "...345678901234567890*[{}abcdefghijklmnopqrstuv..."}
+test parseExpr-21.61 {error message} -body {
+    expr {123456789012345678901234567890*[""abcdefghijklmnopqrstuvwxyz]"}
+} -returnCodes error -result {extra characters after close-quote
+in expression "...345678901234567890*[""abcdefghijklmnopqrstuv..."}
+test parseExpr-21.62 {error message} -body {
+    expr {123456789012345678901234567890*[abcdefghijklmnopqrstuvwxyz"}
+} -returnCodes error -result {missing close-bracket
+in expression "...012345678901234567890*[abcdefghijklmnopqrstuv..."}
+test parseExpr-21.63 {error message} -body {
+    expr "123456789012345678901234567890*\[\{abcdefghijklmnopqrstuvwxyz]"
+} -returnCodes error -result "missing close-brace
+in expression \"...12345678901234567890*\[\{abcdefghijklmnopqrstuv...\""
+
+test parseExpr-22.1 {Bug 3401704} -constraints testexprparser -body {
+    testexprparser 2a() 1
+} -result {- {} 0 subexpr 2 1 text 2 0 {}}
+test parseExpr-22.2 {Bug 3401704} -constraints testexprparser -body {
+    testexprparser nana() 3
+} -result {- {} 0 subexpr nan 1 text nan 0 {}}
+test parseExpr-22.3 {Bug 3401704} -constraints testexprparser -body {
+    testexprparser 2a() -1
+} -result {- {} 0 subexpr 2a() 1 operator 2a 0 {}}
+test parseExpr-22.4 {Bug 3401704} -constraints testexprparser -body {
+    testexprparser nana() -1
+} -result {- {} 0 subexpr nana() 1 operator nana 0 {}}
+test parseExpr-22.5 {Bug 3401704} -constraints testexprparser -body {
+    testexprparser nan9() -1
+} -result {- {} 0 subexpr nan9() 1 operator nan9 0 {}}
+test parseExpr-22.6 {Bug 3401704} -constraints testexprparser -body {
+    testexprparser 2_() -1
+} -result {- {} 0 subexpr 2_() 1 operator 2_ 0 {}}
+test parseExpr-22.7 {Bug 3401704} -constraints testexprparser -body {
+    testexprparser nan_() -1
+} -result {- {} 0 subexpr nan_() 1 operator nan_ 0 {}}
+test parseExpr-22.8 {Bug 3401704} -constraints testexprparser -body {
+    catch {testexprparser nan!() -1} m o
+    dict get $o -errorcode
+} -result {TCL PARSE EXPR MISSING}
+test parseExpr-22.9 {Bug 3401704} -constraints testexprparser -body {
+    testexprparser 1e3_() -1
+} -result {- {} 0 subexpr 1e3_() 1 operator 1e3_ 0 {}}
+test parseExpr-22.10 {Bug 3401704} -constraints testexprparser -body {
+    catch {testexprparser 1.3_() -1} m o
+    dict get $o -errorcode
+} -result {TCL PARSE EXPR BADCHAR}
+test parseExpr-22.11 {Bug 3401704} -constraints testexprparser -body {
+    catch {testexprparser 1e-3_() -1} m o
+    dict get $o -errorcode
+} -result {TCL PARSE EXPR BADCHAR}
+test parseExpr-22.12 {Bug 3401704} -constraints testexprparser -body {
+    catch {testexprparser naneq() -1} m o
+    dict get $o -errorcode
+} -result {TCL PARSE EXPR EMPTY}
+test parseExpr-22.13 {Bug 3401704} -constraints testexprparser -body {
+    testexprparser naner() -1
+} -result {- {} 0 subexpr naner() 1 operator naner 0 {}}
+
+test parseExpr-22.14 {Bug 3401704} -constraints testexprparser -body {
+    catch {testexprparser 08 -1} m o
+    dict get $o -errorcode
+} -result {TCL PARSE EXPR BADNUMBER OCTAL}
+test parseExpr-22.15 {Bug 3401704} -constraints testexprparser -body {
+    catch {testexprparser 0o8 -1} m o
+    dict get $o -errorcode
+} -result {TCL PARSE EXPR BADNUMBER OCTAL}
+test parseExpr-22.16 {Bug 3401704} -constraints testexprparser -body {
+    catch {testexprparser 0o08 -1} m o
+    dict get $o -errorcode
+} -result {TCL PARSE EXPR BADNUMBER OCTAL}
+test parseExpr-22.17 {Bug 3401704} -constraints testexprparser -body {
+    catch {testexprparser 0b2 -1} m o
+    dict get $o -errorcode
+} -result {TCL PARSE EXPR BADNUMBER BINARY}
+test parseExpr-22.18 {Bug 3401704} -constraints testexprparser -body {
+    catch {testexprparser 0b02 -1} m o
+    dict get $o -errorcode
+} -result {TCL PARSE EXPR BADNUMBER BINARY}
+
+test parseExpr-22.19 {Bug d2ffcca163} -constraints testexprparser -body {
+    testexprparser \u0433 -1
+} -returnCodes error -match glob -result {*invalid character*}
+test parseExpr-22.20 {Bug d2ffcca163} -constraints testexprparser -body {
+    testexprparser \u043f -1
+} -returnCodes error -match glob -result {*invalid character*}
+test parseExpr-22.21 {Bug d2ffcca163} -constraints testexprparser -body {
+    testexprparser in\u0433(0) -1
+} -returnCodes error -match glob -result {missing operand*}
+
+# cleanup
+cleanupTests
+return
diff --git a/tests/parseOld.test b/tests/parseOld.test
new file mode 100644
index 0000000..504d063
--- /dev/null
+++ b/tests/parseOld.test
@@ -0,0 +1,552 @@
+# Commands covered:  set (plus basic command syntax).  Also tests the
+# procedures in the file tclOldParse.c.  This set of tests is an old
+# one that predates the new parser in Tcl 8.1.
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands.  Sourcing this file into Tcl runs the tests and
+# generates output for errors.  No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994-1996 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+package require tcltest 2
+namespace import ::tcltest::*
+
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
+
+testConstraint testwordend [llength [info commands testwordend]]
+testConstraint testbytestring [llength [info commands testbytestring]]
+
+# Save the argv value for restoration later
+set savedArgv $argv
+
+proc fourArgs {a b c d} {
+    global arg1 arg2 arg3 arg4
+    set arg1 $a
+    set arg2 $b
+    set arg3 $c
+    set arg4 $d
+}
+
+proc getArgs args {
+    global argv
+    set argv $args
+}
+
+# Basic argument parsing.
+
+test parseOld-1.1 {basic argument parsing} {
+    set arg1 {}
+    fourArgs a b	c 		 d
+    list $arg1 $arg2 $arg3 $arg4
+} {a b c d}
+test parseOld-1.2 {basic argument parsing} {
+    set arg1 {}
+    eval "fourArgs 123\v4\f56\r7890"
+    list $arg1 $arg2 $arg3 $arg4
+} {123 4 56 7890}
+
+# Quotes.
+
+test parseOld-2.1 {quotes and variable-substitution} {
+    getArgs "a b c" d
+    set argv
+} {{a b c} d}
+test parseOld-2.2 {quotes and variable-substitution} {
+    set a 101
+    getArgs "a$a b c"
+    set argv
+} {{a101 b c}}
+test parseOld-2.3 {quotes and variable-substitution} {
+    set argv "xy[format xabc]"
+    set argv
+} {xyxabc}
+test parseOld-2.4 {quotes and variable-substitution} {
+    set argv "xy\t"
+    set argv
+} xy\t
+test parseOld-2.5 {quotes and variable-substitution} {
+    set argv "a b	c
+d e f"
+    set argv
+} a\ b\tc\nd\ e\ f
+test parseOld-2.6 {quotes and variable-substitution} {
+    set argv a"bcd"e
+    set argv
+} {a"bcd"e}
+
+# Braces.
+
+test parseOld-3.1 {braces} {
+    getArgs {a b c} d
+    set argv
+} "{a b c} d"
+test parseOld-3.2 {braces} {
+    set a 101
+    set argv {a$a b c}
+    set b [string index $argv 1]
+    set b
+} {$}
+test parseOld-3.3 {braces} {
+    set argv {a[format xyz] b}
+    string length $argv
+} 15
+test parseOld-3.4 {braces} {
+    set argv {a\nb\}}
+    string length $argv
+} 6
+test parseOld-3.5 {braces} {
+    set argv {{{{}}}}
+    set argv
+} "{{{}}}"
+test parseOld-3.6 {braces} {
+    set argv a{{}}b
+    set argv
+} "a{{}}b"
+test parseOld-3.7 {braces} {
+    set a [format "last]"]
+    set a
+} {last]}
+
+# Command substitution.
+
+test parseOld-4.1 {command substitution} {
+    set a [format xyz]
+    set a
+} xyz
+test parseOld-4.2 {command substitution} {
+    set a a[format xyz]b[format q]
+    set a
+} axyzbq
+test parseOld-4.3 {command substitution} {
+    set a a[
+set b 22;
+format %s $b
+
+]b
+    set a
+} a22b
+test parseOld-4.4 {command substitution} {
+    set a 7.7
+    if [catch {expr int($a)}] {set a foo}
+    set a
+} 7.7
+
+# Variable substitution.
+
+test parseOld-5.1 {variable substitution} {
+    set a 123
+    set b $a
+    set b
+} 123
+test parseOld-5.2 {variable substitution} {
+    set a 345
+    set b x$a.b
+    set b
+} x345.b
+test parseOld-5.3 {variable substitution} {
+    set _123z xx
+    set b $_123z^
+    set b
+} xx^
+test parseOld-5.4 {variable substitution} {
+    set a 78
+    set b a${a}b
+    set b
+} a78b
+test parseOld-5.5 {variable substitution} {catch {$_non_existent_} msg} 1
+test parseOld-5.6 {variable substitution} {
+    catch {$_non_existent_} msg
+    set msg
+} {can't read "_non_existent_": no such variable}
+test parseOld-5.7 {array variable substitution} {
+    unset -nocomplain a
+    set a(xyz) 123
+    set b $a(xyz)foo
+    set b
+} 123foo
+test parseOld-5.8 {array variable substitution} {
+    unset -nocomplain a
+    set "a(x y z)" 123
+    set b $a(x y z)foo
+    set b
+} 123foo
+test parseOld-5.9 {array variable substitution} {
+    unset -nocomplain a qqq
+    set "a(x y z)" qqq
+    set $a([format x]\ y [format z]) foo
+    set qqq
+} foo
+test parseOld-5.10 {array variable substitution} {
+    unset -nocomplain a
+    list [catch {set b $a(22)} msg] $msg
+} {1 {can't read "a(22)": no such variable}}
+test parseOld-5.11 {array variable substitution} {
+    set b a$!
+    set b
+} {a$!}
+test parseOld-5.12 {empty array name support} {
+    list [catch {set b a$()} msg] $msg
+} {1 {can't read "()": no such variable}}
+unset -nocomplain a
+test parseOld-5.13 {array variable substitution} {
+    unset -nocomplain a
+    set long {This is a very long variable, long enough to cause storage \
+	allocation to occur in Tcl_ParseVar.  If that storage isn't getting \
+	freed up correctly, then a core leak will occur when this test is \
+	run.  This text is probably beginning to sound like drivel, but I've \
+	run out of things to say and I need more characters still.}
+    set a($long) 777
+    set b $a($long)
+    list $b [array names a]
+} {777 {{This is a very long variable, long enough to cause storage \
+	allocation to occur in Tcl_ParseVar.  If that storage isn't getting \
+	freed up correctly, then a core leak will occur when this test is \
+	run.  This text is probably beginning to sound like drivel, but I've \
+	run out of things to say and I need more characters still.}}}
+test parseOld-5.14 {array variable substitution} {
+    unset -nocomplain a b a1
+    set a1(22) foo
+    set a(foo) bar
+    set b $a($a1(22))
+    set b
+} bar
+unset -nocomplain a a1
+
+test parseOld-7.1 {backslash substitution} {
+    set a "\a\c\n\]\}"
+    string length $a
+} 5
+test parseOld-7.2 {backslash substitution} {
+    set a {\a\c\n\]\}}
+    string length $a
+} 10
+test parseOld-7.3 {backslash substitution} {
+    set a "abc\
+def"
+    set a
+} {abc def}
+test parseOld-7.4 {backslash substitution} {
+    set a {abc\
+def}
+    set a
+} {abc def}
+test parseOld-7.5 {backslash substitution} {
+    set msg {}
+    set a xxx
+    set error [catch {if {24 < \
+	35} {set a 22} {set \
+	    a 33}} msg]
+    list $error $msg $a
+} {0 22 22}
+test parseOld-7.6 {backslash substitution} {
+    eval "concat abc\\"
+} "abc\\"
+test parseOld-7.7 {backslash substitution} {
+    eval "concat \\\na"
+} "a"
+test parseOld-7.8 {backslash substitution} {
+    eval "concat x\\\n   	a"
+} "x a"
+test parseOld-7.9 {backslash substitution} {
+    eval "concat \\x"
+} "x"
+test parseOld-7.10 {backslash substitution} {
+    eval "list a b\\\nc d"
+} {a b c d}
+test parseOld-7.11 {backslash substitution} {
+    eval "list a \"b c\"\\\nd e"
+} {a {b c} d e}
+test parseOld-7.12 {backslash substitution} testbytestring {
+    expr {[list \ua2] eq [testbytestring "\xc2\xa2"]}
+} 1
+test parseOld-7.13 {backslash substitution} testbytestring {
+    expr {[list \u4e21] eq [testbytestring "\xe4\xb8\xa1"]}
+} 1
+test parseOld-7.14 {backslash substitution} testbytestring {
+    expr {[list \u4e2k] eq [testbytestring "\xd3\xa2k"]}
+} 1
+
+# Semi-colon.
+
+test parseOld-8.1 {semi-colons} {
+    set b 0
+    getArgs a;set b 2
+    set argv
+} a
+test parseOld-8.2 {semi-colons} {
+    set b 0
+    getArgs a;set b 2
+    set b
+} 2
+test parseOld-8.3 {semi-colons} {
+    getArgs a b ; set b 1
+    set argv
+} {a b}
+test parseOld-8.4 {semi-colons} {
+    getArgs a b ; set b 1
+    set b
+} 1
+
+# The following checks are to ensure that the interpreter's result
+# gets re-initialized by Tcl_Eval in all the right places.
+
+set a 22
+test parseOld-9.1 {result initialization} {concat abc} abc
+test parseOld-9.2 {result initialization} {concat abc; proc foo {} {}} {}
+test parseOld-9.3 {result initialization} {concat abc; proc foo {} $a} {}
+test parseOld-9.4 {result initialization} {proc foo {} [concat abc]} {}
+test parseOld-9.5 {result initialization} {concat abc; } abc
+test parseOld-9.6 {result initialization} {
+    eval {
+    concat abc
+}} abc
+test parseOld-9.7 {result initialization} {} {}
+test parseOld-9.8 {result initialization} {concat abc; ; ;} abc
+
+# Syntax errors.
+
+test parseOld-10.1 {syntax errors} {catch "set a \{bcd" msg} 1
+test parseOld-10.2 {syntax errors} {
+	catch "set a \{bcd" msg
+	set msg
+} {missing close-brace}
+test parseOld-10.3 {syntax errors} {catch {set a "bcd} msg} 1
+test parseOld-10.4 {syntax errors} {
+	catch {set a "bcd} msg
+	set msg
+} {missing "}
+#" Emacs formatting >:^(
+test parseOld-10.5 {syntax errors} {catch {set a "bcd"xy} msg} 1
+test parseOld-10.6 {syntax errors} {
+	catch {set a "bcd"xy} msg
+	set msg
+} {extra characters after close-quote}
+test parseOld-10.7 {syntax errors} {catch "set a {bcd}xy" msg} 1
+test parseOld-10.8 {syntax errors} {
+	catch "set a {bcd}xy" msg
+	set msg
+} {extra characters after close-brace}
+test parseOld-10.9 {syntax errors} {catch {set a [format abc} msg} 1
+test parseOld-10.10 {syntax errors} {
+	catch {set a [format abc} msg
+	set msg
+} {missing close-bracket}
+test parseOld-10.11 {syntax errors} {catch gorp-a-lot msg} 1
+test parseOld-10.12 {syntax errors} {
+	catch gorp-a-lot msg
+	set msg
+} {invalid command name "gorp-a-lot"}
+test parseOld-10.13 {syntax errors} {
+    set a [concat {a}\
+ {b}]
+    set a
+} {a b}
+
+# The next test will fail on the Mac, 'cause the MSL uses a fixed sized
+# buffer for %d conversions (LAME!).  I won't leave the test out, however,
+# since MetroWerks may some day fix this.
+
+test parseOld-10.14 {syntax errors} {
+    list [catch {eval \$x[format "%01000d" 0](} msg] $msg $::errorInfo
+} {1 {missing )} {missing )
+    while executing
+"$x0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000..."
+    ("eval" body line 1)
+    invoked from within
+"eval \$x[format "%01000d" 0]("}}
+test parseOld-10.15 {syntax errors, missplaced braces} {
+    catch {
+        proc misplaced_end_brace {} {
+            set what foo
+            set when [expr ${what}size - [set off$what]}]
+    } msg
+    set msg
+} {extra characters after close-brace}
+test parseOld-10.16 {syntax errors, missplaced braces} {
+    catch {
+        set a {
+            set what foo
+            set when [expr ${what}size - [set off$what]}]
+    } msg
+    set msg
+} {extra characters after close-brace}
+test parseOld-10.17 {syntax errors, unusual spacing} {
+    list [catch {return [ [1]]} msg] $msg
+} {1 {invalid command name "1"}}
+# Long values (stressing storage management)
+
+set a {1111 2222 3333 4444 5555 6666 7777 8888 9999 aaaa bbbb cccc dddd eeee ffff gggg hhhh iiii jjjj kkkk llll mmmm nnnn oooo pppp qqqq rrrr ssss tttt uuuu vvvv wwww xxxx yyyy zzzz AAAA BBBB CCCC DDDD EEEE FFFF GGGG HHHH}
+
+test parseOld-11.1 {long values} {
+    string length $a
+} 214
+test parseOld-11.2 {long values} {
+    llength $a
+} 43
+test parseOld-11.3 {long values} {
+    set b "1111 2222 3333 4444 5555 6666 7777 8888 9999 aaaa bbbb cccc dddd eeee ffff gggg hhhh iiii jjjj kkkk llll mmmm nnnn oooo pppp qqqq rrrr ssss tttt uuuu vvvv wwww xxxx yyyy zzzz AAAA BBBB CCCC DDDD EEEE FFFF GGGG HHHH"
+    set b
+} $a
+test parseOld-11.4 {long values} {
+    set b "$a"
+    set b
+} $a
+test parseOld-11.5 {long values} {
+    set b [set a]
+    set b
+} $a
+test parseOld-11.6 {long values} {
+    set b [concat 1111 2222 3333 4444 5555 6666 7777 8888 9999 aaaa bbbb cccc dddd eeee ffff gggg hhhh iiii jjjj kkkk llll mmmm nnnn oooo pppp qqqq rrrr ssss tttt uuuu vvvv wwww xxxx yyyy zzzz AAAA BBBB CCCC DDDD EEEE FFFF GGGG HHHH]
+    string length $b
+} 214
+test parseOld-11.7 {long values} {
+    set b [concat 1111 2222 3333 4444 5555 6666 7777 8888 9999 aaaa bbbb cccc dddd eeee ffff gggg hhhh iiii jjjj kkkk llll mmmm nnnn oooo pppp qqqq rrrr ssss tttt uuuu vvvv wwww xxxx yyyy zzzz AAAA BBBB CCCC DDDD EEEE FFFF GGGG HHHH]
+    llength $b
+} 43
+# Duplicate action of previous test
+llength [set b [concat 1111 2222 3333 4444 5555 6666 7777 8888 9999 aaaa bbbb cccc dddd eeee ffff gggg hhhh iiii jjjj kkkk llll mmmm nnnn oooo pppp qqqq rrrr ssss tttt uuuu vvvv wwww xxxx yyyy zzzz AAAA BBBB CCCC DDDD EEEE FFFF GGGG HHHH]]
+test parseOld-11.8 {long values} {
+    set b
+} $a
+test parseOld-11.9 {long values} {
+    set a [concat 0000 1111 2222 3333 4444 5555 6666 7777 8888 9999 aaaa bbbb cccc dddd eeee ffff gggg hhhh iiii jjjj kkkk llll mmmm nnnn oooo pppp qqqq rrrr ssss tttt uuuu vvvv wwww xxxx yyyy zzzz AAAA BBBB CCCC DDDD EEEE FFFF GGGG HHHH IIII JJJJ KKKK LLLL MMMM NNNN OOOO PPPP QQQQ RRRR SSSS TTTT UUUU VVVV WWWW XXXX YYYY ZZZZ]
+    llength $a
+} 62
+set i 0
+foreach j [concat 0000 1111 2222 3333 4444 5555 6666 7777 8888 9999 aaaa bbbb cccc dddd eeee ffff gggg hhhh iiii jjjj kkkk llll mmmm nnnn oooo pppp qqqq rrrr ssss tttt uuuu vvvv wwww xxxx yyyy zzzz AAAA BBBB CCCC DDDD EEEE FFFF GGGG HHHH IIII JJJJ KKKK LLLL MMMM NNNN OOOO PPPP QQQQ RRRR SSSS TTTT UUUU VVVV WWWW XXXX YYYY ZZZZ] {
+    set test [string index 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ $i]
+    set test $test$test$test$test
+    test parseOld-11.10-[incr i] {long values} {
+	set j
+    } $test
+}
+test parseOld-11.11 {test buffer overflow in backslashes in braces} {
+    expr {"a" == {xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy\101\101\101\101\101\101\101\101\101\101\101\101\101\101\101\101\101\101\101\101\101\101\101\101\101\101}}
+} 0
+
+test parseOld-12.1 {comments} {
+    set a old
+    eval {  # set a new}
+    set a
+} {old}
+test parseOld-12.2 {comments} {
+    set a old
+    eval "  # set a new\nset a new"
+    set a
+} {new}
+test parseOld-12.3 {comments} {
+    set a old
+    eval "  # set a new\\\nset a new"
+    set a
+} {old}
+test parseOld-12.4 {comments} {
+    set a old
+    eval "  # set a new\\\\\nset a new"
+    set a
+} {new}
+
+test parseOld-13.1 {comments at the end of a bracketed script} {
+    set x "[
+expr 1+1
+# skip this!
+]"
+} {2}
+
+test parseOld-14.1 {TclWordEnd procedure} {testwordend} {
+    testwordend " 	\n abc"
+} {c}
+test parseOld-14.2 {TclWordEnd procedure} {testwordend} {
+    testwordend "   \\\n"
+} {}
+test parseOld-14.3 {TclWordEnd procedure} {testwordend} {
+    testwordend "   \\\n "
+} { }
+test parseOld-14.4 {TclWordEnd procedure} {testwordend} {
+    testwordend {"abc"}
+} {"}
+#" Emacs formatting :^(
+test parseOld-14.5 {TclWordEnd procedure} {testwordend} {
+    testwordend {{xyz}}
+} \}
+test parseOld-14.6 {TclWordEnd procedure} {testwordend} {
+    testwordend {{a{}b{}\}} xyz}
+} "\} xyz"
+test parseOld-14.7 {TclWordEnd procedure} {testwordend} {
+    testwordend {abc[this is a]def ghi}
+} {f ghi}
+test parseOld-14.8 {TclWordEnd procedure} {testwordend} {
+    testwordend "puts\\\n\n  "
+} "s\\\n\n  "
+test parseOld-14.9 {TclWordEnd procedure} {testwordend} {
+    testwordend "puts\\\n   	"
+} "s\\\n   	"
+test parseOld-14.10 {TclWordEnd procedure} {testwordend} {
+    testwordend "puts\\\n   	xyz"
+} "s\\\n   	xyz"
+test parseOld-14.11 {TclWordEnd procedure} {testwordend} {
+    testwordend {a$x.$y(a long index) foo}
+} ") foo"
+test parseOld-14.12 {TclWordEnd procedure} {testwordend} {
+    testwordend {abc; def}
+} {; def}
+test parseOld-14.13 {TclWordEnd procedure} {testwordend} {
+    testwordend {abc def}
+} {c def}
+test parseOld-14.14 {TclWordEnd procedure} {testwordend} {
+    testwordend {abc	def}
+} {c	def}
+test parseOld-14.15 {TclWordEnd procedure} {testwordend} {
+    testwordend "abc\ndef"
+} "c\ndef"
+test parseOld-14.16 {TclWordEnd procedure} {testwordend} {
+    testwordend "abc"
+} {c}
+test parseOld-14.17 {TclWordEnd procedure} {testwordend} {
+    testwordend "a\000bc"
+} {c}
+test parseOld-14.18 {TclWordEnd procedure} {testwordend} {
+    testwordend \[a\000\]
+} {]}
+test parseOld-14.19 {TclWordEnd procedure} {testwordend} {
+    testwordend \"a\000\"
+} {"}
+#" Emacs formatting :^(
+test parseOld-14.20 {TclWordEnd procedure} {testwordend} {
+    testwordend a{\000}b
+} {b}
+test parseOld-14.21 {TclWordEnd procedure} {testwordend} {
+    testwordend "   \000b"
+} {b}
+
+test parseOld-15.1 {TclScriptEnd procedure} {
+    info complete {puts [
+	expr 1+1
+	#this is a comment ]}
+} {0}
+test parseOld-15.2 {TclScriptEnd procedure} {
+    info complete "abc\\\n"
+} {0}
+test parseOld-15.3 {TclScriptEnd procedure} {
+    info complete "abc\\\\\n"
+} {1}
+test parseOld-15.4 {TclScriptEnd procedure} {
+    info complete "xyz \[abc \{abc\]"
+} {0}
+test parseOld-15.5 {TclScriptEnd procedure} {
+    info complete "xyz \[abc"
+} {0}
+
+# cleanup
+set argv $savedArgv
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/tests/pid.test b/tests/pid.test
new file mode 100644
index 0000000..d21dbaa
--- /dev/null
+++ b/tests/pid.test
@@ -0,0 +1,57 @@
+# Commands covered:  pid
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands.  Sourcing this file into Tcl runs the tests and
+# generates output for errors.  No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994-1995 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+    package require tcltest 2
+    namespace import -force ::tcltest::*
+}
+
+testConstraint pidDefined [llength [info commands pid]]
+
+test pid-1.1 {pid command} pidDefined {
+    regexp {(^[0-9]+$)|(^0x[0-9a-fA-F]+$)} [pid]
+} 1
+test pid-1.2 {pid command} -constraints {unixOrPc unixExecs pidDefined} -setup {
+    set path(test1) [makeFile {} test1]
+    file delete $path(test1)
+} -body {
+    set f [open |[list echo foo | cat >$path(test1)] w]
+    set pids [pid $f]
+    close $f
+    list [llength $pids] [regexp {^[0-9]+$} [lindex $pids 0]] \
+       [regexp {^[0-9]+$} [lindex $pids 1]] \
+       [expr {[lindex $pids 0] == [lindex $pids 1]}]
+} -cleanup {
+    removeFile test1
+} -result {2 1 1 0}
+test pid-1.3 {pid command} -constraints pidDefined -setup {
+    set path(test1) [makeFile {} test1]
+    file delete $path(test1)
+} -body {
+    set f [open $path(test1) w]
+    set pids [pid $f]
+    close $f
+    set pids
+} -cleanup {
+    removeFile test1
+} -result {}
+test pid-1.4 {pid command} pidDefined {
+    list [catch {pid a b} msg] $msg
+} {1 {wrong # args: should be "pid ?channelId?"}}
+test pid-1.5 {pid command} pidDefined {
+    list [catch {pid gorp} msg] $msg
+} {1 {can not find channel named "gorp"}}
+
+# cleanup
+::tcltest::cleanupTests
+return
diff --git a/tests/pkgMkIndex.test b/tests/pkgMkIndex.test
new file mode 100644
index 0000000..84c82ce
--- /dev/null
+++ b/tests/pkgMkIndex.test
@@ -0,0 +1,698 @@
+# This file contains tests for the pkg_mkIndex command.
+# Note that the tests are limited to Tcl scripts only, there are no shared
+# libraries against which to test.
+#
+# Sourcing this file into Tcl runs the tests and generates output for errors.
+# No output means no errors were found.
+#
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+# All rights reserved.
+
+package require tcltest 2
+namespace import ::tcltest::*
+
+set fullPkgPath [makeDirectory pkg]
+
+namespace eval pkgtest {
+    # Namespace for procs we can discard
+}
+
+# pkgtest::parseArgs --
+#
+#  Parse an argument list.
+#
+# Arguments:
+#  <flags>	(optional) arguments starting with a dash are collected as
+#		options to pkg_mkIndex and passed to pkg_mkIndex.
+#  dirPath	the directory to index
+#  pattern0	pattern to index
+#  ...		pattern to index
+#  patternN	pattern to index
+#
+# Results:
+#  Returns a three element list:
+#    0: the options
+#    1: the directory to index
+#    2: the patterns list
+
+proc pkgtest::parseArgs { args } {
+    set options ""
+
+    set argc [llength $args]
+    for {set iarg 0} {$iarg < $argc} {incr iarg} {
+	set a [lindex $args $iarg]
+	if {[regexp {^-} $a]} {
+	    lappend options $a
+	    if {$a eq "-load"} {
+		incr iarg
+		lappend options [lindex $args $iarg]
+	    }
+	} else {
+	    break
+	}
+    }
+
+    set dirPath [lindex $args $iarg]
+    incr iarg
+    set patternList [lrange $args $iarg end]
+
+    return [list $options $dirPath $patternList]
+}
+
+# pkgtest::parseIndex --
+#
+#  Loads a pkgIndex.tcl file, records all the calls to "package ifneeded".
+#
+# Arguments:
+#  filePath	path to the pkgIndex.tcl file.
+#
+# Results:
+#  Returns a list, in "array set/get" format, where the keys are the package
+#  name and version (in the form "$name:$version"), and the values the rest
+#  of the command line.
+
+proc pkgtest::parseIndex { filePath } {
+    # create a slave interpreter, where we override "package ifneeded"
+
+    set slave [interp create]
+    if {[catch {
+	$slave eval {
+	    rename package package_original
+	    proc package { args } {
+		if {[lindex $args 0] eq "ifneeded"} {
+		    set pkg [lindex $args 1]
+		    set ver [lindex $args 2]
+		    set ::PKGS($pkg:$ver) [lindex $args 3]
+		} else {
+		    return [package_original {*}$args]
+		}
+	    }
+	    array set ::PKGS {}
+	}
+
+	set dir [file dirname $filePath]
+	$slave eval {set curdir [pwd]}
+	$slave eval [list cd $dir]
+	$slave eval [list set dir $dir]
+	$slave eval [list source [file tail $filePath]]
+	$slave eval {cd $curdir}
+
+	# Create the list in sorted order, so that we don't get spurious
+	# errors because the order has changed.
+
+	array set P {}
+	foreach {k v} [$slave eval {array get ::PKGS}] {
+	    set P($k) $v
+	}
+
+	set PKGS ""
+	foreach k [lsort [array names P]] {
+	    lappend PKGS $k $P($k)
+	}
+    } err opts]} {
+	set ei [dict get $opts -errorinfo]
+	set ec [dict get $opts -errorcode]
+
+	catch {interp delete $slave}
+
+	error $ei $ec
+    }
+
+    interp delete $slave
+
+    return $PKGS
+}
+
+# pkgtest::createIndex --
+#
+#  Runs pkg_mkIndex for the given directory and set of patterns.  This
+#  procedure deletes any pkgIndex.tcl file in the target directory, then runs
+#  pkg_mkIndex.
+#
+# Arguments:
+#  <flags>	(optional) arguments starting with a dash are collected as
+#		options to pkg_mkIndex and passed to pkg_mkIndex.
+#  dirPath	the directory to index
+#  pattern0	pattern to index
+#  ...		pattern to index
+#  patternN	pattern to index
+#
+# Results:
+#  Returns a two element list:
+#    0: 1 if the procedure encountered an error, 0 otherwise.
+#    1: the error result if element 0 was 1
+
+proc pkgtest::createIndex { args } {
+    set parsed [parseArgs {*}$args]
+    set options [lindex $parsed 0]
+    set dirPath [lindex $parsed 1]
+    set patternList [lindex $parsed 2]
+
+    file mkdir $dirPath
+
+    if {[catch {
+	file delete [file join $dirPath pkgIndex.tcl]
+	pkg_mkIndex {*}$options $dirPath {*}$patternList
+    } err]} {
+	return [list 1 $err]
+    }
+
+    return [list 0 {}]
+}
+
+# makePkgList --
+#
+#  Takes the output of a pkgtest::parseIndex call, filters it and returns a
+#  cleaned up list of packages and their actions.
+#
+# Arguments:
+#  inList	output from a pkgtest::parseIndex.
+#
+# Results:
+#  Returns a list of two element lists:
+#    0: the name:version
+#    1: a list describing the package.
+#	For tclPkgSetup packages it consists of:
+#	 0: the keyword tclPkgSetup
+#	 1: the first file to source, with its exported procedures
+#	 2: the second file ...
+#	 N: the N-1st file ...
+
+proc makePkgList { inList } {
+    set pkgList ""
+
+    foreach {k v} $inList {
+	switch [lindex $v 0] {
+	    tclPkgSetup {
+		set l tclPkgSetup
+		foreach s [lindex $v 4] {
+		    lappend l $s
+		}
+	    }
+	    source {
+		set l $v
+	    }
+	    default {
+		error "can't handle $k $v"
+	    }
+	}
+
+	lappend pkgList [list $k $l]
+    }
+
+    return $pkgList
+}
+
+# pkgtest::runIndex --
+#
+#  Runs pkg_mkIndex, parses the generated index file.
+#
+# Arguments:
+#  <flags>	(optional) arguments starting with a dash are collected as
+#		options to pkg_mkIndex and passed to pkg_mkIndex.
+#  dirPath	the directory to index
+#  pattern0	pattern to index
+#  ...		pattern to index
+#  patternN	pattern to index
+#
+# Results:
+#  Returns a two element list:
+#    0: 1 if the procedure encountered an error, 0 otherwise.
+#    1: if no error, this is the parsed generated index file, in the format
+#	returned by pkgtest::parseIndex.  If error, this is the error result.
+
+proc pkgtest::runCreatedIndex {rv args} {
+    if {[lindex $rv 0] == 0} {
+	set parsed [parseArgs {*}$args]
+	set dirPath [lindex $parsed 1]
+	set idxFile [file join $dirPath pkgIndex.tcl]
+
+	if {[catch {
+	    set result [list 0 [makePkgList [parseIndex $idxFile]]]
+	} err]} {
+	    set result [list 1 $err]
+	} 
+	file delete $idxFile
+    } else {
+	set result $rv
+    }
+
+    return $result
+}
+proc pkgtest::runIndex { args } {
+    set rv [createIndex {*}$args]
+    return [runCreatedIndex $rv {*}$args]
+}
+
+# If there is no match to the patterns, make sure the directory hasn't changed
+# on us
+
+test pkgMkIndex-1.1 {nothing matches pattern - current dir is the same} {
+    list [pkgtest::runIndex -lazy $fullPkgPath nomatch.tcl] [pwd]
+} [list {1 {no files matched glob pattern "nomatch.tcl"}} [pwd]]
+
+makeFile {
+#  This is a simple package, just to check basic functionality.
+package provide simple 1.0
+namespace eval simple {
+    namespace export lower upper
+}
+proc simple::lower { stg } {
+    return [string tolower $stg]
+}
+proc simple::upper { stg } {
+    return [string toupper $stg]
+}
+} [file join pkg simple.tcl]
+
+test pkgMkIndex-2.1 {simple package} {
+    pkgtest::runIndex -lazy $fullPkgPath simple.tcl
+} {0 {{simple:1.0 {tclPkgSetup {simple.tcl source {::simple::lower ::simple::upper}}}}}}
+
+test pkgMkIndex-2.2 {simple package - use -direct} {
+    pkgtest::runIndex -direct $fullPkgPath simple.tcl
+} "0 {{simple:1.0 {[list source [file join $fullPkgPath simple.tcl]]}}}"
+
+test pkgMkIndex-2.3 {simple package - direct loading is default} {
+    pkgtest::runIndex $fullPkgPath simple.tcl
+} "0 {{simple:1.0 {[list source [file join $fullPkgPath simple.tcl]]}}}"
+
+test pkgMkIndex-2.4 {simple package - use -verbose} -body {
+    pkgtest::runIndex -verbose $fullPkgPath simple.tcl
+} -result "0 {{simple:1.0 {[list source [file join $fullPkgPath simple.tcl]]}}}" \
+    -errorOutput {successful sourcing of simple.tcl
+packages provided were {simple 1.0}
+processed simple.tcl
+}
+
+removeFile [file join pkg simple.tcl]
+
+makeFile {
+#  Contains global symbols, used to check that they don't have a leading ::
+package provide global 1.0
+proc global_lower { stg } {
+    return [string tolower $stg]
+}
+proc global_upper { stg } {
+    return [string toupper $stg]
+}
+} [file join pkg global.tcl]
+
+test pkgMkIndex-3.1 {simple package with global symbols} {
+    pkgtest::runIndex -lazy $fullPkgPath global.tcl
+} {0 {{global:1.0 {tclPkgSetup {global.tcl source {global_lower global_upper}}}}}}
+
+removeFile [file join pkg global.tcl]
+
+makeFile {
+#  This package is required by pkg1.
+#  This package is split into two files, to test packages that are split over
+#  multiple files.
+package provide pkg2 1.0
+namespace eval pkg2 {
+    namespace export p2-1
+}
+proc pkg2::p2-1 { num } {
+    return [expr $num * 2]
+}
+} [file join pkg pkg2_a.tcl]
+
+makeFile {
+#  This package is required by pkg1.
+#  This package is split into two files, to test packages that are split over
+#  multiple files.
+package provide pkg2 1.0
+namespace eval pkg2 {
+    namespace export p2-2
+}
+proc pkg2::p2-2 { num } {
+    return [expr $num * 3]
+}
+} [file join pkg pkg2_b.tcl]
+
+test pkgMkIndex-4.1 {split package} {
+    pkgtest::runIndex -lazy $fullPkgPath pkg2_a.tcl pkg2_b.tcl
+} {0 {{pkg2:1.0 {tclPkgSetup {pkg2_a.tcl source ::pkg2::p2-1} {pkg2_b.tcl source ::pkg2::p2-2}}}}}
+
+test pkgMkIndex-4.2 {split package - direct loading} {
+    pkgtest::runIndex -direct $fullPkgPath pkg2_a.tcl pkg2_b.tcl
+} "0 {{pkg2:1.0 {[list source [file join $fullPkgPath pkg2_a.tcl]]
+[list source [file join $fullPkgPath pkg2_b.tcl]]}}}"
+
+# Add the direct1 directory to auto_path, so that the direct1 package can be
+# found.
+set direct1 [makeDirectory direct1]
+lappend auto_path $direct1
+makeFile {
+#  This is referenced by pkgIndex.tcl as a -direct script.
+package provide direct1 1.0
+namespace eval direct1 {
+    namespace export pd1 pd2
+}
+proc direct1::pd1 { stg } {
+    return [string tolower $stg]
+}
+proc direct1::pd2 { stg } {
+    return [string toupper $stg]
+}
+} [file join direct1 direct1.tcl]
+pkg_mkIndex -direct $direct1 direct1.tcl
+
+makeFile {
+#  Does a package require of direct1, whose pkgIndex.tcl entry is created
+#  above with option -direct.  This tests that pkg_mkIndex can handle code
+#  that is sourced in pkgIndex.tcl files.
+package require direct1
+package provide std 1.0
+namespace eval std {
+    namespace export p1 p2
+}
+proc std::p1 { stg } {
+    return [string tolower $stg]
+}
+proc std::p2 { stg } {
+    return [string toupper $stg]
+}
+} [file join pkg std.tcl]
+
+test pkgMkIndex-5.1 {requires -direct package} {
+    pkgtest::runIndex -lazy $fullPkgPath std.tcl
+} {0 {{std:1.0 {tclPkgSetup {std.tcl source {::std::p1 ::std::p2}}}}}}
+
+removeFile [file join direct1 direct1.tcl]
+file delete [file join $direct1 pkgIndex.tcl]
+removeDirectory direct1
+removeFile [file join pkg std.tcl]
+
+makeFile {
+#  This package requires pkg3, but it does not use any of pkg3's procs in the
+#  code that is executed by the file (i.e. references to pkg3's procs are in
+#  the proc bodies only).
+package require pkg3 1.0
+package provide pkg1 1.0
+namespace eval pkg1 {
+    namespace export p1-1 p1-2
+}
+proc pkg1::p1-1 { num } {
+    return [pkg3::p3-1 $num]
+}
+proc pkg1::p1-2 { num } {
+    return [pkg3::p3-2 $num]
+}
+} [file join pkg pkg1.tcl]
+
+makeFile {
+package provide pkg3 1.0
+namespace eval pkg3 {
+    namespace export p3-1 p3-2
+}
+proc pkg3::p3-1 { num } {
+    return {[expr $num * 2]}
+}
+proc pkg3::p3-2 { num } {
+    return {[expr $num * 3]}
+}
+} [file join pkg pkg3.tcl]
+
+test pkgMkIndex-6.1 {pkg1 requires pkg3} {
+    pkgtest::runIndex -lazy $fullPkgPath pkg1.tcl pkg3.tcl
+} {0 {{pkg1:1.0 {tclPkgSetup {pkg1.tcl source {::pkg1::p1-1 ::pkg1::p1-2}}}} {pkg3:1.0 {tclPkgSetup {pkg3.tcl source {::pkg3::p3-1 ::pkg3::p3-2}}}}}}
+
+test pkgMkIndex-6.2 {pkg1 requires pkg3 - use -direct} {
+    pkgtest::runIndex -direct $fullPkgPath pkg1.tcl pkg3.tcl
+} "0 {{pkg1:1.0 {[list source [file join $fullPkgPath pkg1.tcl]]}} {pkg3:1.0 {[list source [file join $fullPkgPath pkg3.tcl]]}}}"
+
+removeFile [file join pkg pkg1.tcl]
+
+makeFile {
+#  This package requires pkg3, and it calls a pkg3 proc in the code that is
+#  executed by the file
+package require pkg3 1.0
+package provide pkg4 1.0
+namespace eval pkg4 {
+    namespace export p4-1 p4-2
+    variable m2 [pkg3::p3-1 10]
+}
+proc pkg4::p4-1 { num } {
+    variable m2
+    return [expr {$m2 * $num}]
+}
+proc pkg4::p4-2 { num } {
+    return [pkg3::p3-2 $num]
+}
+} [file join pkg pkg4.tcl]
+
+test pkgMkIndex-7.1 {pkg4 uses pkg3} {
+    pkgtest::runIndex -lazy $fullPkgPath pkg4.tcl pkg3.tcl
+} {0 {{pkg3:1.0 {tclPkgSetup {pkg3.tcl source {::pkg3::p3-1 ::pkg3::p3-2}}}} {pkg4:1.0 {tclPkgSetup {pkg4.tcl source {::pkg4::p4-1 ::pkg4::p4-2}}}}}}
+
+test pkgMkIndex-7.2 {pkg4 uses pkg3 - use -direct} {
+    pkgtest::runIndex -direct $fullPkgPath pkg4.tcl pkg3.tcl
+} "0 {{pkg3:1.0 {[list source [file join $fullPkgPath pkg3.tcl]]}} {pkg4:1.0 {[list source [file join $fullPkgPath pkg4.tcl]]}}}"
+
+removeFile [file join pkg pkg4.tcl]
+removeFile [file join pkg pkg3.tcl]
+
+makeFile {
+#  This package requires pkg2, and it calls a pkg2 proc in the code that is
+#  executed by the file.  Pkg2 is a split package.
+package require pkg2 1.0
+package provide pkg5 1.0
+namespace eval pkg5 {
+    namespace export p5-1 p5-2
+    variable m2 [pkg2::p2-1 10]
+    variable m3 [pkg2::p2-2 10]
+}
+proc pkg5::p5-1 { num } {
+    variable m2
+    return [expr {$m2 * $num}]
+}
+proc pkg5::p5-2 { num } {
+    variable m2
+    return [expr {$m2 * $num}]
+}
+} [file join pkg pkg5.tcl]
+
+test pkgMkIndex-8.1 {pkg5 uses pkg2} {
+    pkgtest::runIndex -lazy $fullPkgPath pkg5.tcl pkg2_a.tcl pkg2_b.tcl
+} {0 {{pkg2:1.0 {tclPkgSetup {pkg2_a.tcl source ::pkg2::p2-1} {pkg2_b.tcl source ::pkg2::p2-2}}} {pkg5:1.0 {tclPkgSetup {pkg5.tcl source {::pkg5::p5-1 ::pkg5::p5-2}}}}}}
+
+test pkgMkIndex-8.2 {pkg5 uses pkg2 - use -direct} {
+    pkgtest::runIndex -direct $fullPkgPath pkg5.tcl pkg2_a.tcl pkg2_b.tcl
+} "0 {{pkg2:1.0 {[list source [file join $fullPkgPath pkg2_a.tcl]]
+[list source [file join $fullPkgPath pkg2_b.tcl]]}} {pkg5:1.0 {[list source [file join $fullPkgPath pkg5.tcl]]}}}"
+
+removeFile [file join pkg pkg5.tcl]
+removeFile [file join pkg pkg2_a.tcl]
+removeFile [file join pkg pkg2_b.tcl]
+
+makeFile {
+#  This package requires circ2, and circ2 requires circ3, which in turn
+#  requires circ1.  In case of cirularities, pkg_mkIndex should give up when
+#  it gets stuck.
+package require circ2 1.0
+package provide circ1 1.0
+namespace eval circ1 {
+    namespace export c1-1 c1-2 c1-3 c1-4
+}
+proc circ1::c1-1 { num } {
+    return [circ2::c2-1 $num]
+}
+proc circ1::c1-2 { num } {
+    return [circ2::c2-2 $num]
+}
+proc circ1::c1-3 {} {
+    return 10
+}
+proc circ1::c1-4 {} {
+    return 20
+}
+} [file join pkg circ1.tcl]
+
+makeFile {
+#  This package is required by circ1, and requires circ3. Circ3, in turn,
+#  requires circ1 to give us a circularity.
+package require circ3 1.0
+package provide circ2 1.0
+namespace eval circ2 {
+    namespace export c2-1 c2-2
+}
+proc circ2::c2-1 { num } {
+    return [expr $num * [circ3::c3-1]]
+}
+proc circ2::c2-2 { num } {
+    return [expr $num * [circ3::c3-2]]
+}
+} [file join pkg circ2.tcl]
+
+makeFile {
+#  This package is required by circ2, and in turn requires circ1. This closes
+#  the circularity.
+package require circ1 1.0
+package provide circ3 1.0
+namespace eval circ3 {
+    namespace export c3-1 c3-4
+}
+proc circ3::c3-1 {} {
+    return [circ1::c1-3]
+}
+proc circ3::c3-2 {} {
+    return [circ1::c1-4]
+}
+} [file join pkg circ3.tcl]
+
+test pkgMkIndex-9.1 {circular packages} {
+    pkgtest::runIndex -lazy $fullPkgPath circ1.tcl circ2.tcl circ3.tcl
+} {0 {{circ1:1.0 {tclPkgSetup {circ1.tcl source {::circ1::c1-1 ::circ1::c1-2 ::circ1::c1-3 ::circ1::c1-4}}}} {circ2:1.0 {tclPkgSetup {circ2.tcl source {::circ2::c2-1 ::circ2::c2-2}}}} {circ3:1.0 {tclPkgSetup {circ3.tcl source ::circ3::c3-1}}}}}
+
+removeFile [file join pkg circ1.tcl]
+removeFile [file join pkg circ2.tcl]
+removeFile [file join pkg circ3.tcl]
+
+# Some tests require the existence of one of the DLLs in the dltest directory
+set x [file join [file dirname [info nameofexecutable]] dltest \
+	pkga[info sharedlibextension]]
+set dll "[file tail $x]Required"
+testConstraint $dll [file exists $x]
+
+if {[testConstraint $dll]} {
+    makeFile {
+#  This package provides Pkga, which is also provided by a DLL.
+package provide Pkga 1.0
+proc pkga_neq { x } {
+    return [expr {! [pkgq_eq $x]}]
+}
+} [file join pkg pkga.tcl]
+    file copy -force $x $fullPkgPath
+}
+testConstraint exec [llength [info commands ::exec]]
+
+test pkgMkIndex-10.1 {package in DLL and script} [list exec $dll] {
+    # Do all [load]ing of shared libraries in another process, so we can
+    # delete the file and not get stuck because we're holding a reference to
+    # it.
+    set cmd [list pkg_mkIndex -lazy $fullPkgPath [file tail $x] pkga.tcl]
+    exec [interpreter] << $cmd
+    pkgtest::runCreatedIndex {0 {}} -lazy $fullPkgPath pkga[info sharedlibextension] pkga.tcl
+} "0 {{Pkga:1.0 {tclPkgSetup {pkga[info sharedlibextension] load {pkga_eq pkga_quote}} {pkga.tcl source pkga_neq}}}}"
+test pkgMkIndex-10.2 {package in DLL hidden by -load} [list exec $dll] {
+    # Do all [load]ing of shared libraries in another process, so we can
+    # delete the file and not get stuck because we're holding a reference to
+    # it.
+    #
+    # This test depends on context from prior test, so repeat it.
+    set script \
+	"[list pkg_mkIndex -lazy $fullPkgPath [file tail $x] pkga.tcl]"
+    append script \n \
+	"[list pkg_mkIndex -lazy -load Pkg* $fullPkgPath [file tail $x]]"
+    exec [interpreter] << $script
+    pkgtest::runCreatedIndex {0 {}} -lazy -load Pkg* -- $fullPkgPath pkga[info sharedlibextension]
+} {0 {}}
+
+if {[testConstraint $dll]} {
+    file delete -force [file join $fullPkgPath [file tail $x]]
+    removeFile [file join pkg pkga.tcl]
+}
+
+# Tolerate "namespace import" at the global scope
+
+makeFile {
+package provide fubar 1.0
+namespace eval ::fubar:: {
+    #
+    # export only public functions.
+    #
+    namespace export {[a-z]*}
+}
+proc ::fubar::foo {bar} {
+    puts "$bar"
+    return true
+}
+namespace import ::fubar::foo
+} [file join pkg import.tcl]
+
+test pkgMkIndex-11.1 {conflicting namespace imports} {
+    pkgtest::runIndex -lazy $fullPkgPath import.tcl
+} {0 {{fubar:1.0 {tclPkgSetup {import.tcl source ::fubar::foo}}}}}
+
+removeFile [file join pkg import.tcl]
+
+# Verify that the auto load list generated is correct even when there is a
+# proc name conflict between two namespaces (ie, ::foo::baz and ::bar::baz)
+
+makeFile {
+package provide football 1.0
+namespace eval ::pro:: {
+    #
+    # export only public functions.
+    #
+    namespace export {[a-z]*}
+}
+namespace eval ::college:: {
+    #
+    # export only public functions.
+    #
+    namespace export {[a-z]*}
+}
+proc ::pro::team {} {
+    puts "go packers!"
+    return true
+}
+proc ::college::team {} {
+    puts "go badgers!"
+    return true
+}
+} [file join pkg samename.tcl]
+
+test pkgMkIndex-12.1 {same name procs in different namespace} {
+    pkgtest::runIndex -lazy $fullPkgPath samename.tcl
+} {0 {{football:1.0 {tclPkgSetup {samename.tcl source {::college::team ::pro::team}}}}}}
+
+removeFile [file join pkg samename.tcl]
+
+# Proc names with embedded spaces are properly listed (ie, correct number of
+# braces) in result
+makeFile {
+package provide spacename 1.0
+proc {a b} {} {}
+proc {c d} {} {}
+} [file join pkg spacename.tcl]
+
+test pkgMkIndex-13.1 {proc names with embedded spaces} {
+    pkgtest::runIndex -lazy $fullPkgPath spacename.tcl
+} {0 {{spacename:1.0 {tclPkgSetup {spacename.tcl source {{a b} {c d}}}}}}}
+
+removeFile [file join pkg spacename.tcl]
+
+# Test the tcl::Pkg::CompareExtension helper function
+test pkgMkIndex-14.1 {tcl::Pkg::CompareExtension} {unix} {
+    tcl::Pkg::CompareExtension foo.so .so
+} 1
+test pkgMkIndex-14.2 {tcl::Pkg::CompareExtension} {unix} {
+    tcl::Pkg::CompareExtension foo.so.bar .so
+} 0
+test pkgMkIndex-14.3 {tcl::Pkg::CompareExtension} {unix} {
+    tcl::Pkg::CompareExtension foo.so.1 .so
+} 1
+test pkgMkIndex-14.4 {tcl::Pkg::CompareExtension} {unix} {
+    tcl::Pkg::CompareExtension foo.so.1.2 .so
+} 1
+test pkgMkIndex-14.5 {tcl::Pkg::CompareExtension} {unix} {
+    tcl::Pkg::CompareExtension foo .so
+} 0
+test pkgMkIndex-14.6 {tcl::Pkg::CompareExtension} {unix} {
+    tcl::Pkg::CompareExtension foo.so.1.2.bar .so
+} 0
+
+# cleanup
+
+removeDirectory pkg
+
+namespace delete pkgtest
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# fill-column: 78
+# End:
diff --git a/tests/platform.test b/tests/platform.test
new file mode 100644
index 0000000..c826444
--- /dev/null
+++ b/tests/platform.test
@@ -0,0 +1,84 @@
+# The file tests the tcl_platform variable and platform package.
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands.  Sourcing this file into Tcl runs the tests and
+# generates output for errors.  No output means no errors were found.
+#
+# Copyright (c) 1999 by Scriptics Corporation
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+package require tcltest 2
+
+namespace eval ::tcl::test::platform {
+    namespace import ::tcltest::testConstraint
+    namespace import ::tcltest::test
+    namespace import ::tcltest::cleanupTests
+
+    variable ::tcl_platform
+
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
+
+testConstraint testCPUID [llength [info commands testcpuid]]
+
+test platform-1.0 {tcl_platform(engine)} {
+  set tcl_platform(engine)
+} {Tcl}
+
+test platform-1.1 {TclpSetVariables: tcl_platform} {
+    interp create i
+    i eval {catch {unset tcl_platform(debug)}}
+    i eval {catch {unset tcl_platform(threaded)}}
+    set result [i eval {lsort [array names tcl_platform]}]
+    interp delete i
+    set result
+} {byteOrder engine machine os osVersion pathSeparator platform pointerSize user wordSize}
+
+# Test assumes twos-complement arithmetic, which is true of virtually
+# everything these days.  Note that this does *not* use wide(), and
+# this is intentional since that could make Tcl's numbers wider than
+# the machine-integer on some platforms...
+test platform-2.1 {tcl_platform(wordSize) indicates size of native word} {
+    set result [expr {int(1 << (8 * $tcl_platform(wordSize) - 1))}]
+    # Result must be the largest bit in a machine word, which this checks
+    # without assuming how wide the word really is
+    list [expr {$result < 0}] [expr {$result ^ int($result - 1)}]
+} {1 -1}
+
+# On Windows/UNIX, test that the CPU ID works
+
+test platform-3.1 {CPU ID on Windows/UNIX} \
+    -constraints testCPUID \
+    -body {		
+	set cpudata [testcpuid 0]
+	binary format iii \
+	    [lindex $cpudata 1] \
+	    [lindex $cpudata 3] \
+	    [lindex $cpudata 2] 
+    } \
+    -match regexp \
+    -result {^(?:AuthenticAMD|CentaurHauls|CyrixInstead|GenuineIntel)$}
+
+# The platform package makes very few promises, but does promise that the
+# format of string it produces consists of two non-empty words separated by a
+# hyphen.
+package require platform
+test platform-4.1 {format of platform::identify result} -match regexp -body {
+    platform::identify
+} -result {^([^-]+-)+[^-]+$}
+test platform-4.2 {format of platform::generic result} -match regexp -body {
+    platform::generic
+} -result {^([^-]+-)+[^-]+$}
+
+# cleanup
+cleanupTests
+
+}
+namespace delete ::tcl::test::platform
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/tests/proc-old.test b/tests/proc-old.test
new file mode 100644
index 0000000..e45cf5c
--- /dev/null
+++ b/tests/proc-old.test
@@ -0,0 +1,517 @@
+# Commands covered:  proc, return, global
+#
+# This file, proc-old.test, includes the original set of tests for Tcl's
+# proc, return, and global commands. There is now a new file proc.test
+# that contains tests for the tclProc.c source file.
+#
+# Sourcing this file into Tcl runs the tests and generates output for
+# errors.  No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994-1997 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+    package require tcltest
+    namespace import -force ::tcltest::*
+}
+
+catch {rename t1 ""}
+catch {rename foo ""}
+
+proc tproc {} {return a; return b}
+test proc-old-1.1 {simple procedure call and return} {tproc} a
+proc tproc x {
+    set x [expr $x+1]
+    return $x
+}
+test proc-old-1.2 {simple procedure call and return} {tproc 2} 3
+test proc-old-1.3 {simple procedure call and return} {
+    proc tproc {} {return foo}
+} {}
+test proc-old-1.4 {simple procedure call and return} {
+    proc tproc {} {return}
+    tproc
+} {}
+proc tproc1 {a}   {incr a; return $a}
+proc tproc2 {a b} {incr a; return $a}
+test proc-old-1.5 {simple procedure call and return (2 procs with same body but different parameters)} {
+    list [tproc1 123] [tproc2 456 789]
+} {124 457}
+test proc-old-1.6 {simple procedure call and return (shared proc body string)} {
+    set x {}
+    proc tproc {} {}   ;# body is shared with x
+    list [tproc] [append x foo]
+} {{} foo}
+
+test proc-old-2.1 {local and global variables} {
+    proc tproc x {
+	set x [expr $x+1]
+	return $x
+    }
+    set x 42
+    list [tproc 6] $x
+} {7 42}
+test proc-old-2.2 {local and global variables} {
+    proc tproc x {
+	set y [expr $x+1]
+	return $y
+    }
+    set y 18
+    list [tproc 6] $y
+} {7 18}
+test proc-old-2.3 {local and global variables} {
+    proc tproc x {
+	global y
+	set y [expr $x+1]
+	return $y
+    }
+    set y 189
+    list [tproc 6] $y
+} {7 7}
+test proc-old-2.4 {local and global variables} {
+    proc tproc x {
+	global y
+	return [expr $x+$y]
+    }
+    set y 189
+    list [tproc 6] $y
+} {195 189}
+catch {unset _undefined_}
+test proc-old-2.5 {local and global variables} {
+    proc tproc x {
+	global _undefined_
+	return $_undefined_
+    }
+    list [catch {tproc xxx} msg] $msg
+} {1 {can't read "_undefined_": no such variable}}
+test proc-old-2.6 {local and global variables} {
+    set a 114
+    set b 115
+    global a b
+    list $a $b
+} {114 115}
+
+proc do {cmd} {eval $cmd}
+test proc-old-3.1 {local and global arrays} {
+    catch {unset a}
+    set a(0) 22
+    list [catch {do {global a; set a(0)}} msg] $msg
+} {0 22}
+test proc-old-3.2 {local and global arrays} {
+    catch {unset a}
+    set a(x) 22
+    list [catch {do {global a; set a(x) newValue}} msg] $msg $a(x)
+} {0 newValue newValue}
+test proc-old-3.3 {local and global arrays} {
+    catch {unset a}
+    set a(x) 22
+    set a(y) 33
+    list [catch {do {global a; unset a(y)}; array names a} msg] $msg
+} {0 x}
+test proc-old-3.4 {local and global arrays} {
+    catch {unset a}
+    set a(x) 22
+    set a(y) 33
+    list [catch {do {global a; unset a; info exists a}} msg] $msg \
+	    [info exists a]
+} {0 0 0}
+test proc-old-3.5 {local and global arrays} {
+    catch {unset a}
+    set a(x) 22
+    set a(y) 33
+    list [catch {do {global a; unset a(y); array names a}} msg] $msg
+} {0 x}
+catch {unset a}
+test proc-old-3.6 {local and global arrays} {
+    catch {unset a}
+    set a(x) 22
+    set a(y) 33
+    do {global a; do {global a; unset a}; set a(z) 22}
+    list [catch {array names a} msg] $msg
+} {0 z}
+test proc-old-3.7 {local and global arrays} {
+    proc t1 {args} {global info; set info 1}
+    catch {unset a}
+    set info {}
+    do {global a; trace var a(1) w t1}
+    set a(1) 44
+    set info
+} 1
+test proc-old-3.8 {local and global arrays} {
+    proc t1 {args} {global info; set info 1}
+    catch {unset a}
+    trace var a(1) w t1
+    set info {}
+    do {global a; trace vdelete a(1) w t1}
+    set a(1) 44
+    set info
+} {}
+test proc-old-3.9 {local and global arrays} {
+    proc t1 {args} {global info; set info 1}
+    catch {unset a}
+    trace var a(1) w t1
+    do {global a; trace vinfo a(1)}
+} {{w t1}}
+catch {unset a}
+
+test proc-old-30.1 {arguments and defaults} {
+    proc tproc {x y z} {
+	return [list $x $y $z]
+    }
+    tproc 11 12 13
+} {11 12 13}
+test proc-old-30.2 {arguments and defaults} {
+    proc tproc {x y z} {
+	return [list $x $y $z]
+    }
+    list [catch {tproc 11 12} msg] $msg
+} {1 {wrong # args: should be "tproc x y z"}}
+test proc-old-30.3 {arguments and defaults} {
+    proc tproc {x y z} {
+	return [list $x $y $z]
+    }
+    list [catch {tproc 11 12 13 14} msg] $msg
+} {1 {wrong # args: should be "tproc x y z"}}
+test proc-old-30.4 {arguments and defaults} {
+    proc tproc {x {y y-default} {z z-default}} {
+	return [list $x $y $z]
+    }
+    tproc 11 12 13
+} {11 12 13}
+test proc-old-30.5 {arguments and defaults} {
+    proc tproc {x {y y-default} {z z-default}} {
+	return [list $x $y $z]
+    }
+    tproc 11 12
+} {11 12 z-default}
+test proc-old-30.6 {arguments and defaults} {
+    proc tproc {x {y y-default} {z z-default}} {
+	return [list $x $y $z]
+    }
+    tproc 11
+} {11 y-default z-default}
+test proc-old-30.7 {arguments and defaults} {
+    proc tproc {x {y y-default} {z z-default}} {
+	return [list $x $y $z]
+    }
+    list [catch {tproc} msg] $msg
+} {1 {wrong # args: should be "tproc x ?y? ?z?"}}
+test proc-old-30.8 {arguments and defaults} {
+    list [catch {
+	proc tproc {x {y y-default} z} {
+	    return [list $x $y $z]
+	}
+	tproc 2 3
+    } msg] $msg
+} {1 {wrong # args: should be "tproc x ?y? z"}}
+test proc-old-30.9 {arguments and defaults} {
+    proc tproc {x {y y-default} args} {
+	return [list $x $y $args]
+    }
+    tproc 2 3 4 5
+} {2 3 {4 5}}
+test proc-old-30.10 {arguments and defaults} {
+    proc tproc {x {y y-default} args} {
+	return [list $x $y $args]
+    }
+    tproc 2 3
+} {2 3 {}}
+test proc-old-30.11 {arguments and defaults} {
+    proc tproc {x {y y-default} args} {
+	return [list $x $y $args]
+    }
+    tproc 2
+} {2 y-default {}}
+test proc-old-30.12 {arguments and defaults} {
+    proc tproc {x {y y-default} args} {
+	return [list $x $y $args]
+    }
+    list [catch {tproc} msg] $msg
+} {1 {wrong # args: should be "tproc x ?y? ?arg ...?"}}
+
+test proc-old-4.1 {variable numbers of arguments} {
+    proc tproc args {return $args}
+    tproc
+} {}
+test proc-old-4.2 {variable numbers of arguments} {
+    proc tproc args {return $args}
+    tproc 1 2 3 4 5 6 7 8
+} {1 2 3 4 5 6 7 8}
+test proc-old-4.3 {variable numbers of arguments} {
+    proc tproc args {return $args}
+    tproc 1 {2 3} {4 {5 6} {{{7}}}} 8
+} {1 {2 3} {4 {5 6} {{{7}}}} 8}
+test proc-old-4.4 {variable numbers of arguments} {
+    proc tproc {x y args} {return $args}
+    tproc 1 2 3 4 5 6 7
+} {3 4 5 6 7}
+test proc-old-4.5 {variable numbers of arguments} {
+    proc tproc {x y args} {return $args}
+    tproc 1 2
+} {}
+test proc-old-4.6 {variable numbers of arguments} {
+    proc tproc {x missing args} {return $args}
+    list [catch {tproc 1} msg] $msg
+} {1 {wrong # args: should be "tproc x missing ?arg ...?"}}
+
+test proc-old-5.1 {error conditions} {
+    list [catch {proc} msg] $msg
+} {1 {wrong # args: should be "proc name args body"}}
+test proc-old-5.2 {error conditions} {
+    list [catch {proc tproc b} msg] $msg
+} {1 {wrong # args: should be "proc name args body"}}
+test proc-old-5.3 {error conditions} {
+    list [catch {proc tproc b c d e} msg] $msg
+} {1 {wrong # args: should be "proc name args body"}}
+test proc-old-5.4 {error conditions} {
+    list [catch {proc tproc \{xyz {return foo}} msg] $msg
+} {1 {unmatched open brace in list}}
+test proc-old-5.5 {error conditions} {
+    list [catch {proc tproc {{} y} {return foo}} msg] $msg
+} {1 {argument with no name}}
+test proc-old-5.6 {error conditions} {
+    list [catch {proc tproc {{} y} {return foo}} msg] $msg
+} {1 {argument with no name}}
+test proc-old-5.7 {error conditions} {
+    list [catch {proc tproc {{x 1 2} y} {return foo}} msg] $msg
+} {1 {too many fields in argument specifier "x 1 2"}}
+test proc-old-5.8 {error conditions} {
+    catch {return}
+} 2
+proc tproc {} {
+    set a 22
+    global a
+}
+test proc-old-5.10 {error conditions} {
+    list [catch {tproc} msg] $msg
+} {1 {variable "a" already exists}}
+test proc-old-5.11 {error conditions} {
+    catch {rename tproc {}}
+    catch {
+	proc tproc {x {} z} {return foo}
+    }
+    list [catch {tproc 1} msg] $msg
+} {1 {invalid command name "tproc"}}
+test proc-old-5.12 {error conditions} {
+    proc tproc {} {
+	set a 22
+	error "error in procedure"
+	return
+    }
+    list [catch tproc msg] $msg
+} {1 {error in procedure}}
+test proc-old-5.13 {error conditions} {
+    proc tproc {} {
+	set a 22
+	error "error in procedure"
+	return
+    }
+    catch tproc msg
+    set ::errorInfo
+} {error in procedure
+    while executing
+"error "error in procedure""
+    (procedure "tproc" line 3)
+    invoked from within
+"tproc"}
+test proc-old-5.14 {error conditions} {
+    proc tproc {} {
+	set a 22
+	break
+	return
+    }
+    catch tproc msg
+    set ::errorInfo
+} {invoked "break" outside of a loop
+    (procedure "tproc" line 1)
+    invoked from within
+"tproc"}
+test proc-old-5.15 {error conditions} {
+    proc tproc {} {
+	set a 22
+	continue
+	return
+    }
+    catch tproc msg
+    set ::errorInfo
+} {invoked "continue" outside of a loop
+    (procedure "tproc" line 1)
+    invoked from within
+"tproc"}
+test proc-old-5.16 {error conditions} {
+    proc foo args {
+	global fooMsg
+	set fooMsg "foo was called: $args"
+    }
+    proc tproc {} {
+	set x 44
+	trace var x u foo
+	while {$x < 100} {
+	    error "Nested error"
+	}
+    }
+    set fooMsg "foo not called"
+    list [catch tproc msg] $msg $::errorInfo $fooMsg
+} {1 {Nested error} {Nested error
+    while executing
+"error "Nested error""
+    (procedure "tproc" line 5)
+    invoked from within
+"tproc"} {foo was called: x {} u}}
+
+# The tests below will really only be useful when run under Purify or
+# some other system that can detect accesses to freed memory...
+
+test proc-old-6.1 {procedure that redefines itself} {
+    proc tproc {} {
+	proc tproc {} {
+	    return 44
+	}
+	return 45
+    }
+    tproc
+} 45
+test proc-old-6.2 {procedure that deletes itself} {
+    proc tproc {} {
+	rename tproc {}
+	return 45
+    }
+    tproc
+} 45
+
+proc tproc code {
+    return -code $code abc
+}
+test proc-old-7.1 {return with special completion code} {
+    list [catch {tproc ok} msg] $msg
+} {0 abc}
+test proc-old-7.2 {return with special completion code} {
+    list [catch {tproc error} msg] $msg $::errorInfo $::errorCode
+} {1 abc {abc
+    while executing
+"tproc error"} NONE}
+test proc-old-7.3 {return with special completion code} {
+    list [catch {tproc return} msg] $msg
+} {2 abc}
+test proc-old-7.4 {return with special completion code} {
+    list [catch {tproc break} msg] $msg
+} {3 abc}
+test proc-old-7.5 {return with special completion code} {
+    list [catch {tproc continue} msg] $msg
+} {4 abc}
+test proc-old-7.6 {return with special completion code} {
+    list [catch {tproc -14} msg] $msg
+} {-14 abc}
+test proc-old-7.7 {return with special completion code} -body {
+    tproc err
+} -returnCodes error -match glob -result {bad completion code "err": must be ok, error, return, break, continue*, or an integer}
+test proc-old-7.8 {return with special completion code} -body {
+    tproc 10b
+} -returnCodes error -match glob -result {bad completion code "10b": must be ok, error, return, break, continue*, or an integer}
+test proc-old-7.9 {return with special completion code} {
+    proc tproc2 {} {
+	tproc return
+    }
+    list [catch tproc2 msg] $msg
+} {0 abc}
+test proc-old-7.10 {return with special completion code} {
+    proc tproc2 {} {
+	return -code error
+    }
+    list [catch tproc2 msg] $msg
+} {1 {}}
+test proc-old-7.11 {return with special completion code} {
+    proc tproc2 {} {
+	global errorCode errorInfo
+	catch {open _bad_file_name r} msg
+	return -code error -errorinfo $errorInfo -errorcode $errorCode $msg
+    }
+    set msg [list [catch tproc2 msg] $msg $::errorInfo $::errorCode]
+    regsub -all [file join {} _bad_file_name] $msg "_bad_file_name" msg
+    normalizeMsg $msg
+} {1 {couldn't open "_bad_file_name": no such file or directory} {couldn't open "_bad_file_name": no such file or directory
+    while executing
+"open _bad_file_name r"
+    invoked from within
+"tproc2"} {posix enoent {no such file or directory}}}
+test proc-old-7.12 {return with special completion code} {
+    proc tproc2 {} {
+	global errorCode errorInfo
+	catch {open _bad_file_name r} msg
+	return -code error -errorcode $errorCode $msg
+    }
+    set msg [list [catch tproc2 msg] $msg $::errorInfo $::errorCode]
+    regsub -all [file join {} _bad_file_name] $msg "_bad_file_name" msg
+    normalizeMsg $msg
+} {1 {couldn't open "_bad_file_name": no such file or directory} {couldn't open "_bad_file_name": no such file or directory
+    while executing
+"tproc2"} {posix enoent {no such file or directory}}}
+test proc-old-7.13 {return with special completion code} {
+    proc tproc2 {} {
+	global errorCode errorInfo
+	catch {open _bad_file_name r} msg
+	return -code error -errorinfo $errorInfo $msg
+    }
+    set msg [list [catch tproc2 msg] $msg $::errorInfo $::errorCode]
+    regsub -all [file join {} _bad_file_name] $msg "_bad_file_name" msg
+    normalizeMsg $msg
+} {1 {couldn't open "_bad_file_name": no such file or directory} {couldn't open "_bad_file_name": no such file or directory
+    while executing
+"open _bad_file_name r"
+    invoked from within
+"tproc2"} none}
+test proc-old-7.14 {return with special completion code} {
+    proc tproc2 {} {
+	global errorCode errorInfo
+	catch {open _bad_file_name r} msg
+	return -code error $msg
+    }
+    set msg [list [catch tproc2 msg] $msg $::errorInfo $::errorCode]
+    regsub -all [file join {} _bad_file_name] $msg "_bad_file_name" msg
+    normalizeMsg $msg
+} {1 {couldn't open "_bad_file_name": no such file or directory} {couldn't open "_bad_file_name": no such file or directory
+    while executing
+"tproc2"} none}
+test proc-old-7.15 {return with special completion code} {
+    list [catch {return -badOption foo message} msg] $msg
+} {2 message}
+
+test proc-old-8.1 {unset and undefined local arrays} {
+    proc t1 {} {
+        foreach v {xxx, yyy} {
+            catch {unset $v}
+        }
+        set yyy(foo) bar
+    }
+    t1
+} bar
+
+test proc-old-9.1 {empty command name} {
+    catch {rename {} ""}
+    proc t1 {args} {
+        return
+    }
+    set v [t1]
+    catch {$v}
+} 1
+
+test proc-old-10.1 {ByteCode epoch change during recursive proc execution} {
+    proc t1 x {
+        set y 20
+        rename expr expr.old
+        rename expr.old expr
+        if $x then {t1 0} ;# recursive call after foo's code is invalidated
+        return 20
+    }
+    t1 1
+} 20
+
+# cleanup
+catch {rename t1 ""}
+catch {rename foo ""}
+::tcltest::cleanupTests
+return
diff --git a/tests/proc.test b/tests/proc.test
new file mode 100644
index 0000000..e06720e
--- /dev/null
+++ b/tests/proc.test
@@ -0,0 +1,396 @@
+# This file contains tests for the tclProc.c source file. Tests appear in the
+# same order as the C code that they test. The set of tests is currently
+# incomplete since it includes only new tests, in particular tests for code
+# changed for the addition of Tcl namespaces. Other procedure-related tests
+# appear in other test files such as proc-old.test.
+#
+# Sourcing this file into Tcl runs the tests and generates output for errors.
+# No output means no errors were found.
+#
+# Copyright (c) 1997 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution of
+# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {"::tcltest" ni [namespace children]} {
+    package require tcltest 2
+    namespace import -force ::tcltest::*
+}
+
+testConstraint procbodytest [expr {![catch {package require procbodytest}]}]
+testConstraint memory	    [llength [info commands memory]]
+
+catch {namespace delete {*}[namespace children :: test_ns_*]}
+catch {rename p ""}
+catch {rename {} ""}
+catch {unset msg}
+
+test proc-1.1 {Tcl_ProcObjCmd, put proc in namespace specified in name, if any} -setup {
+    catch {namespace delete {*}[namespace children :: test_ns_*]}
+} -body {
+    namespace eval test_ns_1 {
+        namespace eval baz {}
+    }
+    proc test_ns_1::baz::p {} {
+        return "p in [namespace current]"
+    }
+    list [test_ns_1::baz::p] \
+         [namespace eval test_ns_1 {baz::p}] \
+         [info commands test_ns_1::baz::*]
+} -result {{p in ::test_ns_1::baz} {p in ::test_ns_1::baz} ::test_ns_1::baz::p}
+test proc-1.2 {Tcl_ProcObjCmd, namespace specified in proc name must exist} -setup {
+    catch {namespace delete {*}[namespace children :: test_ns_*]}
+} -returnCodes error -body {
+    proc test_ns_1::baz::p {} {}
+} -result {can't create procedure "test_ns_1::baz::p": unknown namespace}
+test proc-1.3 {Tcl_ProcObjCmd, empty proc name} -setup {
+    catch {namespace delete {*}[namespace children :: test_ns_*]}
+} -body {
+    proc :: {} {
+        return "empty called"
+    }
+    list [::] \
+         [info body {}]
+} -result {{empty called} {
+        return "empty called"
+    }}
+test proc-1.4 {Tcl_ProcObjCmd, simple proc name and proc defined in namespace} -setup {
+    catch {namespace delete {*}[namespace children :: test_ns_*]}
+} -body {
+    namespace eval test_ns_1 {
+        namespace eval baz {
+            proc p {} {
+                return "p in [namespace current]"
+            }
+        }
+    }
+    list [test_ns_1::baz::p] \
+         [info commands test_ns_1::baz::*]
+} -result {{p in ::test_ns_1::baz} ::test_ns_1::baz::p}
+test proc-1.5 {Tcl_ProcObjCmd, qualified proc name and proc defined in namespace} -setup {
+    catch {namespace delete {*}[namespace children :: test_ns_*]}
+} -body {
+    namespace eval test_ns_1::baz {}
+    namespace eval test_ns_1 {
+        proc baz::p {} {
+            return "p in [namespace current]"
+        }
+    }
+    list [test_ns_1::baz::p] \
+         [info commands test_ns_1::baz::*] \
+         [namespace eval test_ns_1::baz {namespace which p}]
+} -result {{p in ::test_ns_1::baz} ::test_ns_1::baz::p ::test_ns_1::baz::p}
+test proc-1.6 {Tcl_ProcObjCmd, namespace code ignores single ":"s in middle or end of command names} -setup {
+    catch {namespace delete {*}[namespace children :: test_ns_*]}
+} -body {
+    namespace eval test_ns_1 {
+        proc q: {} {return "q:"}
+        proc value:at: {} {return "value:at:"}
+    }
+    list [namespace eval test_ns_1 {q:}] \
+         [namespace eval test_ns_1 {value:at:}] \
+         [test_ns_1::q:] \
+         [test_ns_1::value:at:] \
+         [lsort [info commands test_ns_1::*]] \
+         [namespace eval test_ns_1 {namespace which q:}] \
+         [namespace eval test_ns_1 {namespace which value:at:}]
+} -result {q: value:at: q: value:at: {::test_ns_1::q: ::test_ns_1::value:at:} ::test_ns_1::q: ::test_ns_1::value:at:}
+test proc-1.7 {Tcl_ProcObjCmd, check that formal parameter names are not array elements} -setup {
+    catch {rename p ""}
+} -returnCodes error -body {
+    proc p {a(1) a(2)} { 
+	set z [expr $a(1)+$a(2)]
+	puts "$z=z, $a(1)=$a(1)"
+    }
+} -result {formal parameter "a(1)" is an array element}
+test proc-1.8 {Tcl_ProcObjCmd, check that formal parameter names are simple names} -setup {
+    catch {rename p ""}
+} -body {
+    proc p {b:a b::a} { 
+    }
+} -returnCodes error -result {formal parameter "b::a" is not a simple name}
+
+test proc-2.1 {TclFindProc, simple proc name and proc not in namespace} -setup {
+    catch {namespace delete {*}[namespace children :: test_ns_*]}
+    catch {rename p ""}
+} -body {
+    proc p {} {return "p in [namespace current]"}
+    info body p
+} -result {return "p in [namespace current]"}
+test proc-2.2 {TclFindProc, simple proc name and proc defined in namespace} -setup {
+    catch {namespace delete {*}[namespace children :: test_ns_*]}
+} -body {
+    namespace eval test_ns_1 {
+        namespace eval baz {
+            proc p {} {return "p in [namespace current]"}
+        }
+    }
+    namespace eval test_ns_1::baz {info body p}
+} -result {return "p in [namespace current]"}
+test proc-2.3 {TclFindProc, qualified proc name and proc defined in namespace} -setup {
+    catch {namespace delete {*}[namespace children :: test_ns_*]}
+} -body {
+    namespace eval test_ns_1::baz {}
+    namespace eval test_ns_1 {
+        proc baz::p {} {return "p in [namespace current]"}
+    }
+    namespace eval test_ns_1 {info body baz::p}
+} -result {return "p in [namespace current]"}
+test proc-2.4 {TclFindProc, global proc and executing in namespace} -setup {
+    catch {namespace delete {*}[namespace children :: test_ns_*]}
+    catch {rename p ""}
+} -body {
+    proc p {} {return "global p"}
+    namespace eval test_ns_1::baz {info body p}
+} -result {return "global p"}
+
+test proc-3.1 {TclObjInterpProc, proc defined and executing in same namespace} -setup {
+    catch {namespace delete {*}[namespace children :: test_ns_*]}
+} -body {
+    proc p {} {return "p in [namespace current]"}
+    p
+} -result {p in ::}
+test proc-3.2 {TclObjInterpProc, proc defined and executing in same namespace} -setup {
+    catch {namespace delete {*}[namespace children :: test_ns_*]}
+} -body {
+    namespace eval test_ns_1::baz {
+        proc p {} {return "p in [namespace current]"}
+        p
+    }
+} -result {p in ::test_ns_1::baz}
+test proc-3.3 {TclObjInterpProc, proc defined and executing in different namespaces} -setup {
+    catch {namespace delete {*}[namespace children :: test_ns_*]}
+    catch {rename p ""}
+} -body {
+    proc p {} {return "p in [namespace current]"}
+    namespace eval test_ns_1::baz {
+        p
+    }
+} -result {p in ::}
+test proc-3.4 {TclObjInterpProc, procs execute in the namespace in which they were defined unless renamed into new namespace} -setup {
+    catch {namespace delete {*}[namespace children :: test_ns_*]}
+    catch {rename p ""}
+} -body {
+    namespace eval test_ns_1::baz {
+        proc p {} {return "p in [namespace current]"}
+        rename ::test_ns_1::baz::p ::p
+        list [p] [namespace which p]
+    }
+} -result {{p in ::} ::p}
+test proc-3.5 {TclObjInterpProc, any old result is reset before appending error msg about missing arguments} -body {
+    proc p {x} {info commands 3m}
+    p
+} -returnCodes error -result {wrong # args: should be "p x"}
+test proc-3.6 {TclObjInterpProc, proper quoting of proc name, Bug 942757} -body {
+    proc {a b  c} {x} {info commands 3m}
+    {a b  c}
+} -returnCodes error -result {wrong # args: should be "{a b  c} x"}
+
+test proc-3.7 {TclObjInterpProc, wrong num args, Bug 3366265} {
+    proc {} {x} {}
+    list [catch {{}} msg] $msg
+} {1 {wrong # args: should be "{} x"}}
+
+catch {namespace delete {*}[namespace children :: test_ns_*]}
+catch {rename p ""}
+catch {rename {} ""}
+catch {rename {a b  c} {}}
+catch {unset msg}
+
+catch {rename p ""}
+catch {rename t ""}
+
+# Note that the test require that procedures whose body is used to create
+# procbody objects must be executed before the procbodytest::proc command is
+# executed, so that the Proc struct is populated correctly (CompiledLocals are
+# added at compile time).
+
+test proc-4.1 {TclCreateProc, procbody obj} -constraints procbodytest -body {
+    proc p x {return "$x:$x"}
+    set rv [p P]
+    procbodytest::proc t x p
+    lappend rv [t T]
+} -cleanup {
+    catch {rename p ""}
+    catch {rename t ""}
+} -result {P:P T:T}
+test proc-4.2 {TclCreateProc, procbody obj, use compiled locals} -body {
+    proc p x {
+	set y [string tolower $x]
+	return "$x:$y"
+    }
+    set rv [p P]
+    procbodytest::proc t x p
+    lappend rv [t T]
+} -constraints procbodytest -cleanup {
+    catch {rename p ""}
+    catch {rename t ""}
+} -result {P:p T:t}
+test proc-4.3 {TclCreateProc, procbody obj, too many args} -body {
+    proc p x {
+	set y [string tolower $x]
+	return "$x:$y"
+    }
+    set rv [p P]
+    procbodytest::proc t {x x1 x2} p
+    lappend rv [t T]
+} -constraints procbodytest -returnCodes error -cleanup {
+    catch {rename p ""}
+    catch {rename t ""}
+} -result {procedure "t": arg list contains 3 entries, precompiled header expects 1}
+test proc-4.4 {TclCreateProc, procbody obj, inconsistent arg name} -body {
+    proc p {x y z} {
+	set v [join [list $x $y $z]]
+	set w [string tolower $v]
+	return "$v:$w"
+    }
+    set rv [p P Q R]
+    procbodytest::proc t {x x1 z} p
+    lappend rv [t S T U]
+} -constraints procbodytest -returnCodes error -cleanup {
+    catch {rename p ""}
+    catch {rename t ""}
+} -result {procedure "t": formal parameter 1 is inconsistent with precompiled body}
+test proc-4.5 {TclCreateProc, procbody obj, inconsistent arg default type} -body {
+    proc p {x y {z Z}} {
+	set v [join [list $x $y $z]]
+	set w [string tolower $v]
+	return "$v:$w"
+    }
+    set rv [p P Q R]
+    procbodytest::proc t {x y z} p
+    lappend rv [t S T U]
+} -constraints procbodytest -returnCodes error -cleanup {
+    catch {rename p ""}
+    catch {rename t ""}
+} -result {procedure "t": formal parameter 2 is inconsistent with precompiled body}
+test proc-4.6 {TclCreateProc, procbody obj, inconsistent arg default type} -body {
+    proc p {x y z} {
+	set v [join [list $x $y $z]]
+	set w [string tolower $v]
+	return "$v:$w"
+    }
+    set rv [p P Q R]
+    procbodytest::proc t {x y {z Z}} p
+    lappend rv [t S T U]
+} -returnCodes error -constraints procbodytest -cleanup {
+    catch {rename p ""}
+    catch {rename t ""}
+} -result {procedure "t": formal parameter 2 is inconsistent with precompiled body}
+test proc-4.7 {TclCreateProc, procbody obj, inconsistent arg default value} -body {
+    proc p {x y {z Z}} {
+	set v [join [list $x $y $z]]
+	set w [string tolower $v]
+	return "$v:$w"
+    }
+    set rv [p P Q R]
+    procbodytest::proc t {x y {z ZZ}} p
+    lappend rv [t S T U]
+} -constraints procbodytest -returnCodes error -cleanup {
+    catch {rename p ""}
+    catch {rename t ""}
+} -result {procedure "t": formal parameter "z" has default value inconsistent with precompiled body}
+test proc-4.8 {TclCreateProc, procbody obj, no leak on multiple iterations} -setup {
+    proc getbytes {} {
+	set lines [split [memory info] "\n"]
+	lindex $lines 3 3
+    }
+    proc px x {
+	set y [string tolower $x]
+	return "$x:$y"
+    }
+    px x
+} -constraints {procbodytest memory} -body {
+    set end [getbytes]
+    for {set i 0} {$i < 5} {incr i} {
+	procbodytest::proc tx x px
+	set tmp $end
+	set end [getbytes]
+    }
+    set leakedBytes [expr {$end - $tmp}]
+} -cleanup {
+    rename getbytes {}
+    unset -nocomplain end i tmp leakedBytes
+} -result 0
+
+test proc-5.1 {Bytecompiling noop; test for correct argument substitution} -body {
+    proc p args {} ; # this will be bytecompiled into t
+    proc t {} {
+	set res {}
+	set a 0
+	set b 0
+	trace add variable a read {append res a ;#}
+	trace add variable b write {append res b ;#}
+	p $a ccccccw {bfe} {$a} [incr b] [incr a] {[incr b]} {$a} hello
+	set res
+    }
+    t
+} -cleanup {
+    catch {rename p ""}
+    catch {rename t ""}
+} -result {aba}    
+
+test proc-6.1 {ProcessProcResultCode: Bug 647307 (negative return code)} -body {
+    proc a {} {return -code -5}
+    proc b {} a
+    catch b
+} -cleanup {
+    rename a {}
+    rename b {}
+} -result -5
+
+test proc-7.1 {Redefining a compiled cmd: Bug 729692} {
+    proc bar args {}
+    proc foo {} {
+	proc bar args {return bar}
+	bar
+    }
+    foo
+} bar
+test proc-7.2 {Shadowing a compiled cmd: Bug 729692} -body {
+    namespace eval ugly {}
+    proc ugly::foo {} {
+	proc set args {return bar}
+	set x 1
+    }
+    ugly::foo
+} -cleanup {
+    namespace delete ugly
+} -result bar
+test proc-7.3 {Returning loop exception from redefined cmd: Bug 729692} -body {
+    namespace eval ugly {}
+    proc ugly::foo {} {
+	set i 0
+	while { 1 } {
+	    if { [incr i] > 3 } {
+		proc continue {} {return -code break}
+	    }
+	    continue
+	}
+	return $i
+    }
+    ugly::foo
+} -cleanup {
+    namespace delete ugly
+} -result 4
+
+test proc-7.4 {Proc struct outlives its interp: Bug 3532959} {
+    set lambda x
+    lappend lambda {set a 1}
+    interp create slave
+    slave eval [list apply $lambda foo]
+    interp delete slave
+    unset lambda
+} {}
+
+# cleanup
+catch {rename p ""}
+catch {rename t ""}
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# fill-column: 78
+# End:
diff --git a/tests/pwd.test b/tests/pwd.test
new file mode 100644
index 0000000..175c852
--- /dev/null
+++ b/tests/pwd.test
@@ -0,0 +1,31 @@
+# Commands covered:  pwd
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands.  Sourcing this file into Tcl runs the tests and
+# generates output for errors.  No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994-1997 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+    package require tcltest 2
+    namespace import -force ::tcltest::*
+}
+
+test pwd-1.1 {simple pwd} {
+    catch pwd
+} 0
+test pwd-1.2 {simple pwd} {
+    expr [string length pwd]>0
+} 1
+test pwd-1.3 {pwd takes no args} -body {
+    pwd foobar
+} -returnCodes error -result "wrong \# args: should be \"pwd\""
+
+# cleanup
+::tcltest::cleanupTests
+return
diff --git a/tests/reg.test b/tests/reg.test
new file mode 100644
index 0000000..d040632
--- /dev/null
+++ b/tests/reg.test
@@ -0,0 +1,1229 @@
+# reg.test --
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands.  Sourcing this file into Tcl runs the tests and
+# generates output for errors.  No output means no errors were found.
+# (Don't panic if you are seeing this as part of the reg distribution
+# and aren't using Tcl -- reg's own regression tester also knows how
+# to read this file, ignoring the Tcl-isms.)
+#
+# Copyright (c) 1998, 1999 Henry Spencer.  All rights reserved.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+    package require tcltest 2
+}
+
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
+
+# All tests require the testregexp command, return if this
+# command doesn't exist
+
+::tcltest::testConstraint testregexp [llength [info commands testregexp]]
+::tcltest::testConstraint localeRegexp 0
+
+# This file uses some custom procedures, defined below, for regexp regression
+# testing.  The name of the procedure indicates the general nature of the
+# test:
+#	expectError	compile error expected
+#	expectNomatch	match failure expected
+#	expectMatch	successful match
+#	expectIndices	successful match with -indices (used in checking things
+#			like nonparticipating subexpressions)
+#	expectPartial	unsuccessful match with -indices (!!) (used in checking
+#			partial-match reporting)
+# There is also "doing" which sets up title and major test number for each
+# block of tests.
+
+# The first 3 arguments are constant: a minor number (which often gets
+# a letter or two suffixed to it internally), some flags, and the RE
+# itself.  For expectError, the remaining argument is the name of the
+# compile error expected, less the leading "REG_".  For the rest, the
+# next argument is the string to try the match against.  Remaining
+# arguments are the substring expected to be matched, and any
+# substrings expected to be matched by subexpressions.  (For
+# expectNomatch, these arguments are optional, and if present are
+# ignored except that they indicate how many subexpressions should be
+# present in the RE.)  It is an error for the number of subexpression
+# arguments to be wrong.  Cases involving nonparticipating
+# subexpressions, checking where empty substrings are located,
+# etc. should be done using expectIndices and expectPartial.
+
+# The flag characters are complex and a bit eclectic.  Generally speaking, 
+# lowercase letters are compile options, uppercase are expected re_info
+# bits, and nonalphabetics are match options, controls for how the test is 
+# run, or testing options.  The one small surprise is that AREs are the
+# default, and you must explicitly request lesser flavors of RE.  The flags
+# are as follows.  It is admitted that some are not very mnemonic.
+# There are some others which are purely debugging tools and are not
+# useful in this file.
+#
+#	-	no-op (placeholder)
+#	+	provide fake xy equivalence class and ch collating element
+#	%	force small state-set cache in matcher (to test cache replace)
+#	^	beginning of string is not beginning of line
+#	$	end of string is not end of line
+#	*	test is Unicode-specific, needs big character set
+#
+#	&	test as both ARE and BRE
+#	b	BRE
+#	e	ERE
+#	a	turn advanced-features bit on (error unless ERE already)
+#	q	literal string, no metacharacters at all
+#
+#	i	case-independent matching
+#	o	("opaque") no subexpression capture
+#	p	newlines are half-magic, excluded from . and [^ only
+#	w	newlines are half-magic, significant to ^ and $ only
+#	n	newlines are fully magic, both effects
+#	x	expanded RE syntax
+#	t	incomplete-match reporting
+#
+#	A	backslash-_a_lphanumeric seen
+#	B	ERE/ARE literal-_b_race heuristic used
+#	E	backslash (_e_scape) seen within []
+#	H	looka_h_ead constraint seen
+#	I	_i_mpossible to match
+#	L	_l_ocale-specific construct seen
+#	M	unportable (_m_achine-specific) construct seen
+#	N	RE can match empty (_n_ull) string
+#	P	non-_P_OSIX construct seen
+#	Q	{} _q_uantifier seen
+#	R	back _r_eference seen
+#	S	POSIX-un_s_pecified syntax seen
+#	T	prefers shortest (_t_iny)
+#	U	saw original-POSIX botch:  unmatched right paren in ERE (_u_gh)
+
+# The one area we can't easily test is memory-allocation failures (which
+# are hard to provoke on command).  Embedded NULs also are not tested at
+# the moment, but this is a historical accident which should be fixed.
+
+
+# test procedures and related
+namespace eval RETest {
+    namespace export doing expect* knownBug
+
+    variable regBug 0
+
+    # re_info abbreviation mapping table
+    variable infonames
+    array set infonames {
+	A REG_UBSALNUM
+	B REG_UBRACES
+	E REG_UBBS
+	H REG_ULOOKAHEAD
+	I REG_UIMPOSSIBLE
+	L REG_ULOCALE
+	M REG_UUNPORT
+	N REG_UEMPTYMATCH
+	P REG_UNONPOSIX
+	Q REG_UBOUNDS
+	R REG_UBACKREF
+	S REG_UUNSPEC
+	T REG_USHORTEST
+	U REG_UPBOTCH
+    }
+    variable infonameorder "RHQBAUEPSMLNIT" ;# must match bit order, lsb first
+
+    # build test number (internal)
+    proc TestNum {args} {
+	return reg-[join [concat $args] .]
+    }
+
+    # build description, with possible modifiers (internal)
+    proc TestDesc {args} {
+	variable description
+
+	set testid [concat $args]
+	set d $description
+	if {[llength $testid] > 1} {
+	    set d "$d ([lrange $testid 1 end])"
+	}
+	return $d
+    }
+
+    # build trailing options and flags argument from a flags string (internal)
+    proc TestFlags {fl} {
+	set args [list]
+	set flags ""
+	foreach f [split $fl ""] {
+	    switch -exact -- $f {
+		"i" { lappend args "-nocase" }
+		"x" { lappend args "-expanded" }
+		"n" { lappend args "-line" }
+		"p" { lappend args "-linestop" }
+		"w" { lappend args "-lineanchor" }
+		"-" { }
+		default { append flags $f }
+	    }
+	}
+	if {$flags ne ""} {
+	    lappend args -xflags $flags
+	}
+	return $args
+    }
+
+    # build info-flags list from a flags string (internal)
+    proc TestInfoFlags {fl} {
+	variable infonames
+	variable infonameorder
+
+	set ret [list]
+	foreach f [split $infonameorder ""] {
+	    if {[string match *$f* $fl]} {
+		lappend ret $infonames($f)
+	    }
+	}
+	return $ret
+    }
+
+    # Share the generation of the list of test constraints so it is
+    # done the same on all routes.
+    proc TestConstraints {flags} {
+	set constraints [list testregexp]
+
+	variable regBug
+	if {$regBug} {
+	    # This will trigger registration as a skipped test
+	    lappend constraints knownBug
+	}
+
+	# Tcl locale stuff doesn't do the ch/xy test fakery yet
+	if {[string match *+* $flags]} {
+	    # This will trigger registration as a skipped test
+	    lappend constraints localeRegexp
+	}
+
+	return $constraints
+    }
+
+    # match expected, internal routine that does the work
+    # parameters like the "real" routines except they don't have "opts",
+    #  which is a possibly-empty list of switches for the regexp match attempt
+    # The ! flag is used to indicate expected match failure (for REG_EXPECT,
+    #  which wants argument testing even in the event of failure).
+    proc MatchExpected {opts testid flags re target args} {
+	# if &, test as both BRE and ARE
+	if {[string match *&* $flags]} {
+	    set f [string map {& {}} $flags]
+	    MatchExpected $opts "$testid ARE" ${f}  $re $target {*}$args
+	    MatchExpected $opts "$testid BRE" ${f}b $re $target {*}$args
+	    return
+	}
+
+	set constraints [TestConstraints $flags]
+
+	set f [TestFlags $flags]
+	set infoflags [TestInfoFlags $flags]
+	set ccmd [list testregexp -about        {*}$f $re]
+	set ecmd [list testregexp {*}$opts {*}$f $re $target]
+
+	set nsub [expr {[llength $args] - 1}]
+	set names [list]
+	set refs ""
+	for {set i 0} {$i < [llength $args]} {incr i} {
+	    if {$i == 0} {
+		set name match
+	    } else {
+		set name sub$i
+	    }
+	    lappend names $name
+	    append refs " \$$name"
+	    set $name ""
+	}
+	if {[string match *o* $flags]} {	;# REG_NOSUB kludge
+	    set nsub 0				;# unsigned value cannot be -1
+	}
+	if {[string match *t* $flags]} {	;# REG_EXPECT
+	    incr nsub -1			;# the extra does not count
+	}
+	set erun "list \[[concat $ecmd $names]\] $refs"
+	set result [list [expr {![string match *!* $flags]}] {*}$args]
+	set info [list $nsub $infoflags]
+
+	::tcltest::test [TestNum $testid compile] [TestDesc $testid compile] \
+		-constraints $constraints -body $ccmd -result $info
+	::tcltest::test [TestNum $testid execute] [TestDesc $testid execute] \
+		-constraints $constraints -body $erun -result $result
+    }
+
+    # set major test number and description
+    proc doing {major desc} {
+	variable description "RE engine $desc"
+    }
+
+    # compilation error expected
+    proc expectError {testid flags re err} {
+	# if &, test as both ARE and BRE
+	if {[string match *&* $flags]} {
+	    set f [string map {& {}} $flags]
+	    expectError "$testid ARE" ${f}  $re $err
+	    expectError "$testid BRE" ${f}b $re $err
+	    return
+	}
+
+	set constraints [TestConstraints $flags]
+
+	set cmd [list testregexp -about {*}[TestFlags $flags] $re]
+	::tcltest::test [TestNum $testid error] [TestDesc $testid error] \
+		-constraints $constraints -result [list 1 REG_$err] -body \
+		"list \[catch \{$cmd\}\] \[lindex \$::errorCode 1\]"
+    }
+
+    # match failure expected
+    proc expectNomatch {testid flags re target args} {
+	variable regBug
+	# if &, test as both ARE and BRE
+	if {[string match *&* $flags]} {
+	    set f [string map {& {}} $flags]
+	    expectNomatch "$testid ARE" ${f}  $re $target {*}$args
+	    expectNomatch "$testid BRE" ${f}b $re $target {*}$args
+	    return
+	}
+
+	set constraints [TestConstraints $flags]
+
+	set f [TestFlags $flags]
+	set infoflags [TestInfoFlags $flags]
+	set ccmd [list testregexp -about {*}$f $re]
+	set nsub [expr {[llength $args] - 1}]
+	if {$nsub == -1} {
+	    # didn't tell us number of subexps
+	    set ccmd "lreplace \[$ccmd\] 0 0"
+	    set info [list $infoflags]
+	} else {
+	    set info [list $nsub $infoflags]
+	}
+	set ecmd [list testregexp {*}$f $re $target]
+
+	::tcltest::test [TestNum $testid compile] [TestDesc $testid compile] \
+		-constraints $constraints -body $ccmd -result $info
+	::tcltest::test [TestNum $testid execute] [TestDesc $testid execute] \
+		-constraints $constraints -body $ecmd -result 0
+    }
+
+    # match expected (no missing, empty, or ambiguous submatches)
+    # expectMatch testno flags re target mat submat ...
+    proc expectMatch {args} {
+	MatchExpected {} {*}$args
+    }
+
+    # match expected (full fanciness)
+    # expectIndices testno flags re target mat submat ...
+    proc expectIndices {args} {
+	MatchExpected -indices {*}$args 
+    }
+
+    # partial match expected
+    # expectPartial testno flags re target mat "" ...
+    # Quirk:  number of ""s must be one more than number of subREs.
+    proc expectPartial {args} {
+	lset args 1 ![lindex $args 1]	;# add ! flag
+	MatchExpected -indices {*}$args
+    }
+
+    # test is a knownBug
+    proc knownBug {args} {
+	variable regBug 1
+	uplevel \#0 $args
+	set regBug 0
+    }
+}
+namespace import RETest::*
+
+######## the tests themselves ########
+
+# support functions and preliminary misc.
+# This is sensitive to changes in message wording, but we really have to
+# test the code->message expansion at least once.
+::tcltest::test reg-0.1 "regexp error reporting" {
+    list [catch {regexp (*) ign} msg] $msg
+} {1 {couldn't compile regular expression pattern: quantifier operand invalid}}
+
+
+doing 1 "basic sanity checks"
+expectMatch	1.1 &		abc	abc		abc
+expectNomatch	1.2 &		abc	def
+expectMatch	1.3 &		abc	xyabxabce	abc
+
+
+doing 2 "invalid option combinations"
+expectError	2.1 qe		a	INVARG
+expectError	2.2 qa		a	INVARG
+expectError	2.3 qx		a	INVARG
+expectError	2.4 qn		a	INVARG
+expectError	2.5 ba		a	INVARG
+
+
+doing 3 "basic syntax"
+expectIndices	3.1 &NS		""	a	{0 -1}
+expectMatch	3.2 NS		a|	a	a
+expectMatch	3.3 -		a|b	a	a
+expectMatch	3.4 -		a|b	b	b
+expectMatch	3.5 NS		a||b	b	b
+expectMatch	3.6 &		ab	ab	ab
+
+
+doing 4 "parentheses"
+expectMatch	4.1  -		(a)e		ae	ae	a
+expectMatch	4.2  o		(a)e		ae
+expectMatch	4.3  b		{\(a\)b}	ab	ab	a
+expectMatch	4.4  -		a((b)c)		abc	abc	bc	b
+expectMatch	4.5  -		a(b)(c)		abc	abc	b	c
+expectError	4.6  -		a(b		EPAREN
+expectError	4.7  b		{a\(b}		EPAREN
+# sigh, we blew it on the specs here... someday this will be fixed in POSIX,
+#  but meanwhile, it's fixed in AREs
+expectMatch	4.8  eU		a)b		a)b	a)b
+expectError	4.9  -		a)b		EPAREN
+expectError	4.10 b		{a\)b}		EPAREN
+expectMatch	4.11 P		a(?:b)c		abc	abc
+expectError	4.12 e		a(?:b)c		BADRPT
+expectIndices	4.13 S		a()b		ab	{0 1}	{1 0}
+expectMatch	4.14 SP		a(?:)b		ab	ab
+expectIndices	4.15 S		a(|b)c		ac	{0 1}	{1 0}
+expectMatch	4.16 S		a(b|)c		abc	abc	b
+
+
+doing 5 "simple one-char matching"
+# general case of brackets done later
+expectMatch	5.1 &		a.b		axb	axb
+expectNomatch	5.2 &n		"a.b"		"a\nb"
+expectMatch	5.3 &		{a[bc]d}	abd	abd
+expectMatch	5.4 &		{a[bc]d}	acd	acd
+expectNomatch	5.5 &		{a[bc]d}	aed
+expectNomatch	5.6 &		{a[^bc]d}	abd
+expectMatch	5.7 &		{a[^bc]d}	aed	aed
+expectNomatch	5.8 &p		"a\[^bc]d"	"a\nd"
+
+
+doing 6 "context-dependent syntax"
+# plus odds and ends
+expectError	6.1  -		*	BADRPT
+expectMatch	6.2  b		*	*	*
+expectMatch	6.3  b		{\(*\)}	*	*	*
+expectError	6.4  -		(*)	BADRPT
+expectMatch	6.5  b		^*	*	*
+expectError	6.6  -		^*	BADRPT
+expectNomatch	6.7  &		^b	^b
+expectMatch	6.8  b		x^	x^	x^
+expectNomatch	6.9  I		x^	x
+expectMatch	6.10 n		"\n^"	"x\nb"	"\n"
+expectNomatch	6.11 bS		{\(^b\)} ^b
+expectMatch	6.12 -		(^b)	b	b	b
+expectMatch	6.13 &		{x$}	x	x
+expectMatch	6.14 bS		{\(x$\)} x	x	x
+expectMatch	6.15 -		{(x$)}	x	x	x
+expectMatch	6.16 b		{x$y}	"x\$y"	"x\$y"
+expectNomatch	6.17 I		{x$y}	xy
+expectMatch	6.18 n		"x\$\n"	"x\n"	"x\n"
+expectError	6.19 -		+	BADRPT
+expectError	6.20 -		?	BADRPT
+
+
+doing 7 "simple quantifiers"
+expectMatch	7.1  &N		a*	aa	aa
+expectIndices	7.2  &N		a*	b	{0 -1}
+expectMatch	7.3  -		a+	aa	aa
+expectMatch	7.4  -		a?b	ab	ab
+expectMatch	7.5  -		a?b	b	b
+expectError	7.6  -		**	BADRPT
+expectMatch	7.7  bN		**	***	***
+expectError	7.8  &		a**	BADRPT
+expectError	7.9  &		a**b	BADRPT
+expectError	7.10 &		***	BADRPT
+expectError	7.11 -		a++	BADRPT
+expectError	7.12 -		a?+	BADRPT
+expectError	7.13 -		a?*	BADRPT
+expectError	7.14 -		a+*	BADRPT
+expectError	7.15 -		a*+	BADRPT
+
+
+doing 8 "braces"
+expectMatch	8.1  NQ		"a{0,1}"	""	""
+expectMatch	8.2  NQ		"a{0,1}"	ac	a
+expectError	8.3  -		"a{1,0}"	BADBR
+expectError	8.4  -		"a{1,2,3}"	BADBR
+expectError	8.5  -		"a{257}"	BADBR
+expectError	8.6  -		"a{1000}"	BADBR
+expectError	8.7  -		"a{1"		EBRACE
+expectError	8.8  -		"a{1n}"		BADBR
+expectMatch	8.9  BS		"a{b"		"a\{b"	"a\{b"
+expectMatch	8.10 BS		"a{"		"a\{"	"a\{"
+expectMatch	8.11 bQ		"a\\{0,1\\}b"	cb	b
+expectError	8.12 b		"a\\{0,1"	EBRACE
+expectError	8.13 -		"a{0,1\\"	BADBR
+expectMatch	8.14 Q		"a{0}b"		ab	b
+expectMatch	8.15 Q		"a{0,0}b"	ab	b
+expectMatch	8.16 Q		"a{0,1}b"	ab	ab
+expectMatch	8.17 Q		"a{0,2}b"	b	b
+expectMatch	8.18 Q		"a{0,2}b"	aab	aab
+expectMatch	8.19 Q		"a{0,}b"	aab	aab
+expectMatch	8.20 Q		"a{1,1}b"	aab	ab
+expectMatch	8.21 Q		"a{1,3}b"	aaaab	aaab
+expectNomatch	8.22 Q		"a{1,3}b"	b
+expectMatch	8.23 Q		"a{1,}b"	aab	aab
+expectNomatch	8.24 Q		"a{2,3}b"	ab
+expectMatch	8.25 Q		"a{2,3}b"	aaaab	aaab
+expectNomatch	8.26 Q		"a{2,}b"	ab
+expectMatch	8.27 Q		"a{2,}b"	aaaab	aaaab
+
+
+doing 9 "brackets"
+expectMatch	9.1  &		{a[bc]}		ac	ac
+expectMatch	9.2  &		{a[-]}		a-	a-
+expectMatch	9.3  &		{a[[.-.]]}	a-	a-
+expectMatch	9.4  &L		{a[[.zero.]]}	a0	a0
+expectMatch	9.5  &LM	{a[[.zero.]-9]}	a2	a2
+expectMatch	9.6  &M		{a[0-[.9.]]}	a2	a2
+expectMatch	9.7  &+L	{a[[=x=]]}	ax	ax
+expectMatch	9.8  &+L	{a[[=x=]]}	ay	ay
+expectNomatch	9.9  &+L	{a[[=x=]]}	az
+expectError	9.10 &		{a[0-[=x=]]}	ERANGE
+expectMatch	9.11 &L		{a[[:digit:]]}	a0	a0
+expectError	9.12 &		{a[[:woopsie:]]}	ECTYPE
+expectNomatch	9.13 &L		{a[[:digit:]]}	ab
+expectError	9.14 &		{a[0-[:digit:]]}	ERANGE
+expectMatch	9.15 &LP	{[[:<:]]a}	a	a
+expectMatch	9.16 &LP	{a[[:>:]]}	a	a
+expectError	9.17 &		{a[[..]]b}	ECOLLATE
+expectError	9.18 &		{a[[==]]b}	ECOLLATE
+expectError	9.19 &		{a[[::]]b}	ECTYPE
+expectError	9.20 &		{a[[.a}		EBRACK
+expectError	9.21 &		{a[[=a}		EBRACK
+expectError	9.22 &		{a[[:a}		EBRACK
+expectError	9.23 &		{a[}		EBRACK
+expectError	9.24 &		{a[b}		EBRACK
+expectError	9.25 &		{a[b-}		EBRACK
+expectError	9.26 &		{a[b-c}		EBRACK
+expectMatch	9.27 &M		{a[b-c]}	ab	ab
+expectMatch	9.28 &		{a[b-b]}	ab	ab
+expectMatch	9.29 &M		{a[1-2]}	a2	a2
+expectError	9.30 &		{a[c-b]}	ERANGE
+expectError	9.31 &		{a[a-b-c]}	ERANGE
+expectMatch	9.32 &M		{a[--?]b}	a?b	a?b
+expectMatch	9.33 &		{a[---]b}	a-b	a-b
+expectMatch	9.34 &		{a[]b]c}	a]c	a]c
+expectMatch	9.35 EP		{a[\]]b}	a]b	a]b
+expectNomatch	9.36 bE		{a[\]]b}	a]b
+expectMatch	9.37 bE		{a[\]]b}	"a\\]b"	"a\\]b"
+expectMatch	9.38 eE		{a[\]]b}	"a\\]b"	"a\\]b"
+expectMatch	9.39 EP		{a[\\]b}	"a\\b"	"a\\b"
+expectMatch	9.40 eE		{a[\\]b}	"a\\b"	"a\\b"
+expectMatch	9.41 bE		{a[\\]b}	"a\\b"	"a\\b"
+expectError	9.42 -		{a[\Z]b}	EESCAPE
+expectMatch	9.43 &		{a[[b]c}	"a\[c"	"a\[c"
+expectMatch	9.44 EMP*	{a[\u00fe-\u0507][\u00ff-\u0300]b} \
+	"a\u0102\u02ffb"	"a\u0102\u02ffb"
+
+
+doing 10 "anchors and newlines"
+expectMatch	10.1  &		^a	a	a
+expectNomatch	10.2  &^	^a	a
+expectIndices	10.3  &N	^	a	{0 -1}
+expectIndices	10.4  &		{a$}	aba	{2 2}
+expectNomatch	10.5  {&$}	{a$}	a
+expectIndices	10.6  &N	{$}	ab	{2 1}
+expectMatch	10.7  &n	^a	a	a
+expectMatch	10.8  &n	"^a"	"b\na"	"a"
+expectIndices	10.9  &w	"^a"	"a\na"	{0 0}
+expectIndices	10.10 &n^	"^a"	"a\na"	{2 2}
+expectMatch	10.11 &n	{a$}	a	a
+expectMatch	10.12 &n	"a\$"	"a\nb"	"a"
+expectIndices	10.13 &n	"a\$"	"a\na"	{0 0}
+expectIndices	10.14 N		^^	a	{0 -1}
+expectMatch	10.15 b		^^	^	^
+expectIndices	10.16 N		{$$}	a	{1 0}
+expectMatch	10.17 b		{$$}	"\$"	"\$"
+expectMatch	10.18 &N	{^$}	""	""
+expectNomatch	10.19 &N	{^$}	a
+expectIndices	10.20 &nN	"^\$"	a\n\nb	{2 1}
+expectMatch	10.21 N		{$^}	""	""
+expectMatch	10.22 b		{$^}	"\$^"	"\$^"
+expectMatch	10.23 P		{\Aa}	a	a
+expectMatch	10.24 ^P	{\Aa}	a	a
+expectNomatch	10.25 ^nP	{\Aa}	"b\na"
+expectMatch	10.26 P		{a\Z}	a	a
+expectMatch	10.27 \$P	{a\Z}	a	a
+expectNomatch	10.28 \$nP	{a\Z}	"a\nb"
+expectError	10.29 -		^*	BADRPT
+expectError	10.30 -		{$*}	BADRPT
+expectError	10.31 -		{\A*}	BADRPT
+expectError	10.32 -		{\Z*}	BADRPT
+
+
+doing 11 "boundary constraints"
+expectMatch	11.1  &LP	{[[:<:]]a}	a	a
+expectMatch	11.2  &LP	{[[:<:]]a}	-a	a
+expectNomatch	11.3  &LP	{[[:<:]]a}	ba
+expectMatch	11.4  &LP	{a[[:>:]]}	a	a
+expectMatch	11.5  &LP	{a[[:>:]]}	a-	a
+expectNomatch	11.6  &LP	{a[[:>:]]}	ab
+expectMatch	11.7  bLP	{\<a}		a	a
+expectNomatch	11.8  bLP	{\<a}		ba
+expectMatch	11.9  bLP	{a\>}		a	a
+expectNomatch	11.10 bLP	{a\>}		ab
+expectMatch	11.11 LP	{\ya}		a	a
+expectNomatch	11.12 LP	{\ya}		ba
+expectMatch	11.13 LP	{a\y}		a	a
+expectNomatch	11.14 LP	{a\y}		ab
+expectMatch	11.15 LP	{a\Y}		ab	a
+expectNomatch	11.16 LP	{a\Y}		a-
+expectNomatch	11.17 LP	{a\Y}		a
+expectNomatch	11.18 LP	{-\Y}		-a
+expectMatch	11.19 LP	{-\Y}		-%	-
+expectNomatch	11.20 LP	{\Y-}		a-
+expectError	11.21 -		{[[:<:]]*}	BADRPT
+expectError	11.22 -		{[[:>:]]*}	BADRPT
+expectError	11.23 b		{\<*}		BADRPT
+expectError	11.24 b		{\>*}		BADRPT
+expectError	11.25 -		{\y*}		BADRPT
+expectError	11.26 -		{\Y*}		BADRPT
+expectMatch	11.27 LP	{\ma}		a	a
+expectNomatch	11.28 LP	{\ma}		ba
+expectMatch	11.29 LP	{a\M}		a	a
+expectNomatch	11.30 LP	{a\M}		ab
+expectNomatch	11.31 ILP	{\Ma}		a
+expectNomatch	11.32 ILP	{a\m}		a
+
+
+doing 12 "character classes"
+expectMatch	12.1  LP	{a\db}		a0b	a0b
+expectNomatch	12.2  LP	{a\db}		axb
+expectNomatch	12.3  LP	{a\Db}		a0b
+expectMatch	12.4  LP	{a\Db}		axb	axb
+expectMatch	12.5  LP	"a\\sb"		"a b"	"a b"
+expectMatch	12.6  LP	"a\\sb"		"a\tb"	"a\tb"
+expectMatch	12.7  LP	"a\\sb"		"a\nb"	"a\nb"
+expectNomatch	12.8  LP	{a\sb}		axb
+expectMatch	12.9  LP	{a\Sb}		axb	axb
+expectNomatch	12.10 LP	"a\\Sb"		"a b"
+expectMatch	12.11 LP	{a\wb}		axb	axb
+expectNomatch	12.12 LP	{a\wb}		a-b
+expectNomatch	12.13 LP	{a\Wb}		axb
+expectMatch	12.14 LP	{a\Wb}		a-b	a-b
+expectMatch	12.15 LP	{\y\w+z\y}	adze-guz	guz
+expectMatch	12.16 LPE	{a[\d]b}	a1b	a1b
+expectMatch	12.17 LPE	"a\[\\s]b"	"a b"	"a b"
+expectMatch	12.18 LPE	{a[\w]b}	axb	axb
+
+
+doing 13 "escapes"
+expectError	13.1  &		"a\\"		EESCAPE
+expectMatch	13.2  -		{a\<b}		a<b	a<b
+expectMatch	13.3  e		{a\<b}		a<b	a<b
+expectMatch	13.4  bAS	{a\wb}		awb	awb
+expectMatch	13.5  eAS	{a\wb}		awb	awb
+expectMatch	13.6  PL	"a\\ab"		"a\007b"	"a\007b"
+expectMatch	13.7  P		"a\\bb"		"a\bb"	"a\bb"
+expectMatch	13.8  P		{a\Bb}		"a\\b"	"a\\b"
+expectMatch	13.9  MP	"a\\chb"	"a\bb"	"a\bb"
+expectMatch	13.10 MP	"a\\cHb"	"a\bb"	"a\bb"
+expectMatch	13.11 LMP	"a\\e"		"a\033"	"a\033"
+expectMatch	13.12 P		"a\\fb"		"a\fb"	"a\fb"
+expectMatch	13.13 P		"a\\nb"		"a\nb"	"a\nb"
+expectMatch	13.14 P		"a\\rb"		"a\rb"	"a\rb"
+expectMatch	13.15 P		"a\\tb"		"a\tb"	"a\tb"
+expectMatch	13.16 P		"a\\u0008x"	"a\bx"	"a\bx"
+expectMatch	13.17 P		{a\u008x}	"a\bx"	"a\bx"
+expectMatch	13.18 P		"a\\u00088x"	"a\b8x"	"a\b8x"
+expectMatch	13.19 P		"a\\U00000008x"	"a\bx"	"a\bx"
+expectMatch	13.20 P		{a\U0000008x}	"a\bx"	"a\bx"
+expectMatch	13.21 P		"a\\vb"		"a\vb"	"a\vb"
+expectMatch	13.22 MP	"a\\x08x"	"a\bx"	"a\bx"
+expectError	13.23 -		{a\xq}		EESCAPE
+expectMatch	13.24 MP	"a\\x08x"	"a\bx"	"a\bx"
+expectError	13.25 -		{a\z}		EESCAPE
+expectMatch	13.26 MP	"a\\010b"	"a\bb"	"a\bb"
+expectMatch	13.27 P		"a\\U00001234x"	"a\u1234x"	"a\u1234x"
+expectMatch	13.28 P		{a\U00001234x}	"a\u1234x"	"a\u1234x"
+expectMatch	13.29 P		"a\\U0001234x"	"a\u1234x"	"a\u1234x"
+expectMatch	13.30 P		{a\U0001234x}	"a\u1234x"	"a\u1234x"
+expectMatch	13.31 P		"a\\U000012345x"	"a\u12345x"	"a\u12345x"
+expectMatch	13.32 P		{a\U000012345x}	"a\u12345x"	"a\u12345x"
+expectMatch	13.33 P		"a\\U1000000x"	"a\ufffd0x"	"a\ufffd0x"
+expectMatch	13.34 P		{a\U1000000x}	"a\ufffd0x"	"a\ufffd0x"
+
+
+doing 14 "back references"
+# ugh
+expectMatch	14.1  RP	{a(b*)c\1}	abbcbb	abbcbb	bb
+expectMatch	14.2  RP	{a(b*)c\1}	ac	ac	""
+expectNomatch	14.3  RP	{a(b*)c\1}	abbcb
+expectMatch	14.4  RP	{a(b*)\1}	abbcbb	abb	b
+expectMatch	14.5  RP	{a(b|bb)\1}	abbcbb	abb	b
+expectMatch	14.6  RP	{a([bc])\1}	abb	abb	b
+expectNomatch	14.7  RP	{a([bc])\1}	abc
+expectMatch	14.8  RP	{a([bc])\1}	abcabb	abb	b
+expectNomatch	14.9  RP	{a([bc])*\1}	abc
+expectNomatch	14.10 RP	{a([bc])\1}	abB
+expectMatch	14.11 iRP	{a([bc])\1}	abB	abB	b
+expectMatch	14.12 RP	{a([bc])\1+}	abbb	abbb	b
+expectMatch	14.13 QRP	"a(\[bc])\\1{3,4}"	abbbb	abbbb	b
+expectNomatch	14.14 QRP	"a(\[bc])\\1{3,4}"	abbb
+expectMatch	14.15 RP	{a([bc])\1*}	abbb	abbb	b
+expectMatch	14.16 RP	{a([bc])\1*}	ab	ab	b
+expectMatch	14.17 RP	{a([bc])(\1*)}	ab	ab	b	""
+expectError	14.18 -		{a((b)\1)}	ESUBREG
+expectError	14.19 -		{a(b)c\2}	ESUBREG
+expectMatch	14.20 bR	{a\(b*\)c\1}	abbcbb	abbcbb	bb
+expectMatch	14.21 RP	{^([bc])\1*$}	bbb	bbb	b
+expectMatch	14.22 RP	{^([bc])\1*$}	ccc	ccc	c
+expectNomatch	14.23 RP	{^([bc])\1*$}	bcb
+expectMatch	14.24 LRP	{^(\w+)( \1)+$}	{abc abc abc} {abc abc abc} abc { abc}
+expectNomatch	14.25 LRP	{^(\w+)( \1)+$}	{abc abd abc}
+expectNomatch	14.26 LRP	{^(\w+)( \1)+$}	{abc abc abd}
+expectMatch	14.27 RP	{^(.+)( \1)+$}	{abc abc abc} {abc abc abc} abc { abc}
+expectNomatch	14.28 RP	{^(.+)( \1)+$}	{abc abd abc}
+expectNomatch	14.29 RP	{^(.+)( \1)+$}	{abc abc abd}
+
+
+doing 15 "octal escapes vs back references"
+# initial zero is always octal
+expectMatch	15.1  MP	"a\\010b"	"a\bb"	"a\bb"
+expectMatch	15.2  MP	"a\\0070b"	"a\0070b"	"a\0070b"
+expectMatch	15.3  MP	"a\\07b"	"a\007b"	"a\007b"
+expectMatch	15.4  MP	"a(b)(b)(b)(b)(b)(b)(b)(b)(b)(b)\\07c" \
+	"abbbbbbbbbb\007c" abbbbbbbbbb\007c b b b b b b b b b b
+# a single digit is always a backref
+expectError	15.5  -		{a\7b}	ESUBREG
+# otherwise it's a backref only if within range (barf!)
+expectMatch	15.6  MP	"a\\10b"	"a\bb"	"a\bb"
+expectMatch	15.7  MP	{a\101b}	aAb	aAb
+expectMatch	15.8  RP	{a(b)(b)(b)(b)(b)(b)(b)(b)(b)(b)\10c} \
+	"abbbbbbbbbbbc" abbbbbbbbbbbc b b b b b b b b b b
+# but we're fussy about border cases -- guys who want octal should use the zero
+expectError	15.9  -	{a((((((((((b\10))))))))))c}	ESUBREG
+# BREs don't have octal, EREs don't have backrefs
+expectMatch	15.10 MP	"a\\12b"	"a\nb"	"a\nb"
+expectError	15.11 b		{a\12b}		ESUBREG
+expectMatch	15.12 eAS	{a\12b}		a12b	a12b
+expectMatch	15.13 MP	{a\701b}	a\u00381b	a\u00381b
+
+
+doing 16 "expanded syntax"
+expectMatch	16.1 xP		"a b c"		"abc"	"abc"
+expectMatch	16.2 xP		"a b #oops\nc\td"	"abcd"	"abcd"
+expectMatch	16.3 x		"a\\ b\\\tc"	"a b\tc"	"a b\tc"
+expectMatch	16.4 xP		"a b\\#c"	"ab#c"	"ab#c"
+expectMatch	16.5 xP		"a b\[c d]e"	"ab e"	"ab e"
+expectMatch	16.6 xP		"a b\[c#d]e"	"ab#e"	"ab#e"
+expectMatch	16.7 xP		"a b\[c#d]e"	"abde"	"abde"
+expectMatch	16.8 xSPB	"ab{ d"		"ab\{d"	"ab\{d"
+expectMatch	16.9 xPQ	"ab{ 1 , 2 }c"	"abc"	"abc"
+
+
+doing 17 "misc syntax"
+expectMatch	17.1 P	a(?#comment)b	ab	ab
+
+
+doing 18 "unmatchable REs"
+expectNomatch	18.1 I	a^b		ab
+
+
+doing 19 "case independence"
+expectMatch	19.1 &i		ab		Ab	Ab
+expectMatch	19.2 &i		{a[bc]}		aC	aC
+expectNomatch	19.3 &i		{a[^bc]}	aB
+expectMatch	19.4 &iM	{a[b-d]}	aC	aC
+expectNomatch	19.5 &iM	{a[^b-d]}	aC
+
+
+doing 20 "directors and embedded options"
+expectError	20.1  &		***?		BADPAT
+expectMatch	20.2  q		***?		***?	***?
+expectMatch	20.3  &P	***=a*b		a*b	a*b
+expectMatch	20.4  q		***=a*b		***=a*b	***=a*b
+expectMatch	20.5  bLP	{***:\w+}	ab	ab
+expectMatch	20.6  eLP	{***:\w+}	ab	ab
+expectError	20.7  &		***:***=a*b	BADRPT
+expectMatch	20.8  &P	***:(?b)a+b	a+b	a+b
+expectMatch	20.9  P		(?b)a+b		a+b	a+b
+expectError	20.10 e		{(?b)\w+}	BADRPT
+expectMatch	20.11 bAS	{(?b)\w+}	(?b)w+	(?b)w+
+expectMatch	20.12 iP	(?c)a		a	a
+expectNomatch	20.13 iP	(?c)a		A
+expectMatch	20.14 APS	{(?e)\W+}	WW	WW
+expectMatch	20.15 P		(?i)a+		Aa	Aa
+expectNomatch	20.16 P		"(?m)a.b"	"a\nb"
+expectMatch	20.17 P		"(?m)^b"	"a\nb"	"b"
+expectNomatch	20.18 P		"(?n)a.b"	"a\nb"
+expectMatch	20.19 P		"(?n)^b"	"a\nb"	"b"
+expectNomatch	20.20 P		"(?p)a.b"	"a\nb"
+expectNomatch	20.21 P		"(?p)^b"	"a\nb"
+expectMatch	20.22 P		(?q)a+b		a+b	a+b
+expectMatch	20.23 nP	"(?s)a.b"	"a\nb"	"a\nb"
+expectMatch	20.24 xP	"(?t)a b"	"a b"	"a b"
+expectMatch	20.25 P		"(?w)a.b"	"a\nb"	"a\nb"
+expectMatch	20.26 P		"(?w)^b"	"a\nb"	"b"
+expectMatch	20.27 P		"(?x)a b"	"ab"	"ab"
+expectError	20.28 -		(?z)ab		BADOPT
+expectMatch	20.29 P		(?ici)a+	Aa	Aa
+expectError	20.30 P		(?i)(?q)a+	BADRPT
+expectMatch	20.31 P		(?q)(?i)a+	(?i)a+	(?i)a+
+expectMatch	20.32 P		(?qe)a+		a	a
+expectMatch	20.33 xP	"(?q)a b"	"a b"	"a b"
+expectMatch	20.34 P		"(?qx)a b"	"a b"	"a b"
+expectMatch	20.35 P		(?qi)ab		Ab	Ab
+
+
+doing 21 "capturing"
+expectMatch	21.1  -		a(b)c		abc	abc	b
+expectMatch	21.2  P		a(?:b)c		xabc	abc
+expectMatch	21.3  -		a((b))c		xabcy	abc	b	b
+expectMatch	21.4  P		a(?:(b))c	abcy	abc	b
+expectMatch	21.5  P		a((?:b))c	abc	abc	b
+expectMatch	21.6  P		a(?:(?:b))c	abc	abc
+expectIndices	21.7  Q		"a(b){0}c"	ac	{0 1}	{-1 -1}
+expectMatch	21.8  -		a(b)c(d)e	abcde	abcde	b	d
+expectMatch	21.9  -		(b)c(d)e	bcde	bcde	b	d
+expectMatch	21.10 -		a(b)(d)e	abde	abde	b	d
+expectMatch	21.11 -		a(b)c(d)	abcd	abcd	b	d
+expectMatch	21.12 -		(ab)(cd)	xabcdy	abcd	ab	cd
+expectMatch	21.13 -		a(b)?c		xabcy	abc	b
+expectIndices	21.14 -		a(b)?c		xacy	{1 2}	{-1 -1}
+expectMatch	21.15 -		a(b)?c(d)?e	xabcdey	abcde	b	d
+expectIndices	21.16 -		a(b)?c(d)?e	xacdey	{1 4}	{-1 -1}	{3 3}
+expectIndices	21.17 -		a(b)?c(d)?e	xabcey	{1 4}	{2 2}	{-1 -1}
+expectIndices	21.18 -		a(b)?c(d)?e	xacey	{1 3}	{-1 -1}	{-1 -1}
+expectMatch	21.19 -		a(b)*c		xabcy	abc	b
+expectIndices	21.20 -		a(b)*c		xabbbcy	{1 5}	{4 4}
+expectIndices	21.21 -		a(b)*c		xacy	{1 2}	{-1 -1}
+expectMatch	21.22 -		a(b*)c		xabbbcy	abbbc	bbb
+expectMatch	21.23 -		a(b*)c		xacy	ac	""
+expectNomatch	21.24 -		a(b)+c		xacy
+expectMatch	21.25 -		a(b)+c		xabcy	abc	b
+expectIndices	21.26 -		a(b)+c		xabbbcy	{1 5}	{4 4}
+expectMatch	21.27 -		a(b+)c		xabbbcy	abbbc	bbb
+expectIndices	21.28 Q		"a(b){2,3}c"	xabbbcy	{1 5}	{4 4}
+expectIndices	21.29 Q		"a(b){2,3}c"	xabbcy	{1 4}	{3 3}
+expectNomatch	21.30 Q		"a(b){2,3}c"	xabcy
+expectMatch	21.31 LP	"\\y(\\w+)\\y"	"-- abc-"	"abc"	"abc"
+expectMatch	21.32 -		a((b|c)d+)+	abacdbd	acdbd	bd	b
+expectMatch	21.33 N		(.*).*		abc	abc	abc
+expectMatch	21.34 N		(a*)*		bc	""	""
+expectMatch	21.35 M		{ TO (([a-z0-9._]+|"([^"]+|"")+")+)}	{asd TO foo}	{ TO foo} foo o {}
+
+
+doing 22 "multicharacter collating elements"
+# again ugh
+expectMatch	22.1  &+L	{a[c]e}		ace	ace
+expectNomatch	22.2  &+IL	{a[c]h}		ach
+expectMatch	22.3  &+L	{a[[.ch.]]}	ach	ach
+expectNomatch	22.4  &+L	{a[[.ch.]]}	ace
+expectMatch	22.5  &+L	{a[c[.ch.]]}	ac	ac
+expectMatch	22.6  &+L	{a[c[.ch.]]}	ace	ac
+expectMatch	22.7  &+L	{a[c[.ch.]]}	ache	ach
+expectNomatch	22.8  &+L	{a[^c]e}	ace
+expectMatch	22.9  &+L	{a[^c]e}	abe	abe
+expectMatch	22.10 &+L	{a[^c]e}	ache	ache
+expectNomatch	22.11 &+L	{a[^[.ch.]]}	ach
+expectMatch	22.12 &+L	{a[^[.ch.]]}	ace	ac
+expectMatch	22.13 &+L	{a[^[.ch.]]}	ac	ac
+expectMatch	22.14 &+L	{a[^[.ch.]]}	abe	ab
+expectNomatch	22.15 &+L	{a[^c[.ch.]]}	ach
+expectNomatch	22.16 &+L	{a[^c[.ch.]]}	ace
+expectNomatch	22.17 &+L	{a[^c[.ch.]]}	ac
+expectMatch	22.18 &+L	{a[^c[.ch.]]}	abe	ab
+expectMatch	22.19 &+L	{a[^b]}		ac	ac
+expectMatch	22.20 &+L	{a[^b]}		ace	ac
+expectMatch	22.21 &+L	{a[^b]}		ach	ach
+expectNomatch	22.22 &+L	{a[^b]}		abe
+
+
+doing 23 "lookahead constraints"
+expectMatch	23.1 HP		a(?=b)b*	ab	ab
+expectNomatch	23.2 HP		a(?=b)b*	a
+expectMatch	23.3 HP		a(?=b)b*(?=c)c*	abc	abc
+expectNomatch	23.4 HP		a(?=b)b*(?=c)c*	ab
+expectNomatch	23.5 HP		a(?!b)b*	ab
+expectMatch	23.6 HP		a(?!b)b*	a	a
+expectMatch	23.7 HP		(?=b)b		b	b
+expectNomatch	23.8 HP		(?=b)b		a
+
+
+doing 24 "non-greedy quantifiers"
+expectMatch	24.1  PT	ab+?		abb	ab
+expectMatch	24.2  PT	ab+?c		abbc	abbc
+expectMatch	24.3  PT	ab*?		abb	a
+expectMatch	24.4  PT	ab*?c		abbc	abbc
+expectMatch	24.5  PT	ab??		ab	a
+expectMatch	24.6  PT	ab??c		abc	abc
+expectMatch	24.7  PQT	"ab{2,4}?"	abbbb	abb
+expectMatch	24.8  PQT	"ab{2,4}?c"	abbbbc	abbbbc
+expectMatch	24.9  -		3z*		123zzzz456	3zzzz
+expectMatch	24.10 PT	3z*?		123zzzz456	3
+expectMatch	24.11 -		z*4		123zzzz456	zzzz4
+expectMatch	24.12 PT	z*?4		123zzzz456	zzzz4
+expectMatch	24.13 PT	{^([^/]+?)(?:/([^/]+?))(?:/([^/]+?))?$}	{foo/bar/baz}	{foo/bar/baz} {foo} {bar} {baz}
+
+
+doing 25 "mixed quantifiers"
+# this is very incomplete as yet
+# should include |
+expectMatch	25.1 PNT	{^(.*?)(a*)$}	"xyza"	xyza	xyz	a
+expectMatch	25.2 PNT	{^(.*?)(a*)$}	"xyzaa"	xyzaa	xyz	aa
+expectMatch	25.3 PNT	{^(.*?)(a*)$}	"xyz"	xyz	xyz	""
+
+
+doing 26 "tricky cases"
+# attempts to trick the matcher into accepting a short match
+expectMatch	26.1 -		(week|wee)(night|knights) \
+	"weeknights" weeknights wee knights
+expectMatch	26.2 RP		{a(bc*).*\1}	abccbccb abccbccb	b
+expectMatch	26.3 -		{a(b.[bc]*)+}	abcbd	abcbd	bd
+
+
+doing 27 "implementation misc."
+# duplicate arcs are suppressed
+expectMatch	27.1 P		a(?:b|b)c	abc	abc
+# make color/subcolor relationship go back and forth
+expectMatch	27.2 &		{[ab][ab][ab]}	aba	aba
+expectMatch	27.3 &		{[ab][ab][ab][ab][ab][ab][ab]} \
+	"abababa" abababa
+
+
+doing 28 "boundary busters etc."
+# color-descriptor allocation changes at 10
+expectMatch	28.1 &		abcdefghijkl	"abcdefghijkl"	abcdefghijkl
+# so does arc allocation
+expectMatch	28.2 P		a(?:b|c|d|e|f|g|h|i|j|k|l|m)n	"agn"	agn
+# subexpression tracking also at 10
+expectMatch	28.3 -		a(((((((((((((b)))))))))))))c \
+	"abc" abc b b b b b b b b b b b b b
+# state-set handling changes slightly at unsigned size (might be 64...)
+# (also stresses arc allocation)
+expectMatch	28.4  Q		"ab{1,100}c"	abbc	abbc
+expectMatch	28.5  Q		"ab{1,100}c" \
+	"abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbc" \
+	abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbc
+expectMatch	28.6  Q		"ab{1,100}c" \
+	"abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbc"\
+	abbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbc
+# force small cache and bust it, several ways
+expectMatch	28.7  LP	{\w+abcdefgh}	xyzabcdefgh	xyzabcdefgh
+expectMatch	28.8  %LP	{\w+abcdefgh}	xyzabcdefgh	xyzabcdefgh
+expectMatch	28.9  %LP	{\w+abcdefghijklmnopqrst} \
+	"xyzabcdefghijklmnopqrst" xyzabcdefghijklmnopqrst
+expectIndices	28.10 %LP	{\w+(abcdefgh)?} xyz	{0 2}	{-1 -1}
+expectIndices	28.11 %LP	{\w+(abcdefgh)?} xyzabcdefg	{0 9}	{-1 -1}
+expectIndices	28.12 %LP	{\w+(abcdefghijklmnopqrst)?} \
+	"xyzabcdefghijklmnopqrs" {0 21} {-1 -1}
+
+
+doing 29 "incomplete matches"
+expectPartial		29.1  t		def	abc	{3 2}	""
+expectPartial		29.2  t		bcd	abc	{1 2}	""
+expectPartial		29.3  t		abc	abab	{0 3}	""
+expectPartial		29.4  t		abc	abdab	{3 4}	""
+expectIndices		29.5  t		abc	abc	{0 2}	{0 2}
+expectIndices		29.6  t		abc	xyabc	{2 4}	{2 4}
+expectPartial		29.7  t		abc+	xyab	{2 3}	""
+expectIndices		29.8  t		abc+	xyabc	{2 4}	{2 4}
+knownBug expectIndices	29.9  t		abc+	xyabcd	{2 4}	{6 5}
+expectIndices		29.10 t		abc+	xyabcdd	{2 4}	{7 6}
+expectPartial		29.11 tPT	abc+?	xyab	{2 3}	""
+# the retain numbers in these two may look wrong, but they aren't
+expectIndices		29.12 tPT	abc+?	xyabc	{2 4}	{5 4}
+expectIndices		29.13 tPT	abc+?	xyabcc	{2 4}	{6 5}
+expectIndices		29.14 tPT	abc+?	xyabcd	{2 4}	{6 5}
+expectIndices		29.15 tPT	abc+?	xyabcdd	{2 4}	{7 6}
+expectIndices		29.16 t		abcd|bc	xyabc	{3 4}	{2 4}
+expectPartial		29.17 tn	.*k	"xx\nyyy"	{3 5}	""
+
+
+doing 30 "misc. oddities and old bugs"
+expectError	30.1 &		***	BADRPT
+expectMatch	30.2 N		a?b*	abb	abb
+expectMatch	30.3 N		a?b*	bb	bb
+expectMatch	30.4 &		a*b	aab	aab
+expectMatch	30.5 &		^a*b	aaaab	aaaab
+expectMatch	30.6 &M		{[0-6][1-2][0-3][0-6][1-6][0-6]} \
+	"010010" 010010
+# temporary REG_BOSONLY kludge
+expectMatch	30.7 s		abc	abcd	abc
+expectNomatch	30.8 s		abc	xabcd
+# back to normal stuff
+expectMatch	30.9 HLP	{(?n)^(?![t#])\S+} \
+	"tk\n\n#\n#\nit0"	it0
+
+
+# Now for tests *not* written by Henry Spencer
+
+namespace import -force ::tcltest::test
+
+# Tests resulting from bugs reported by users
+test reg-31.1 {[[:xdigit:]] behaves correctly when followed by [[:space:]]} {
+    set str {2:::DebugWin32}
+    set re {([[:xdigit:]])([[:space:]]*)}
+    list [regexp $re $str match xdigit spaces] $match $xdigit $spaces
+    # Code used to produce {1 2:::DebugWin32 2 :::DebugWin32} !!!
+} {1 2 2 {}}
+
+test reg-32.1 {canmatch functionality -- at end} testregexp {
+    set pat {blah}
+    set line "asd asd"
+    # can match at the final d, if '%' follows
+    set res [testregexp -xflags -- c $pat $line resvar]
+    lappend res $resvar
+} {0 7}
+test reg-32.2 {canmatch functionality -- at end} testregexp {
+    set pat {s%$}
+    set line "asd asd"
+    # can only match after the end of the string
+    set res [testregexp -xflags -- c $pat $line resvar]
+    lappend res $resvar
+} {0 7}
+test reg-32.3 {canmatch functionality -- not last char} testregexp {
+    set pat {[^d]%$}
+    set line "asd asd"
+    # can only match after the end of the string
+    set res [testregexp -xflags -- c $pat $line resvar]
+    lappend res $resvar
+} {0 7}
+test reg-32.3.1 {canmatch functionality -- no match} testregexp {
+    set pat {\Zx}
+    set line "asd asd"
+    # can match the last char, if followed by x
+    set res [testregexp -xflags -- c $pat $line resvar]
+    lappend res $resvar
+} {0 -1}
+test reg-32.4 {canmatch functionality -- last char} {knownBug testregexp} {
+    set pat {.x}
+    set line "asd asd"
+    # can match the last char, if followed by x
+    set res [testregexp -xflags -- c $pat $line resvar]
+    lappend res $resvar
+} {0 6}
+test reg-32.4.1 {canmatch functionality -- last char} {knownBug testregexp} {
+    set pat {.x$}
+    set line "asd asd"
+    # can match the last char, if followed by x
+    set res [testregexp -xflags -- c $pat $line resvar]
+    lappend res $resvar
+} {0 6}
+test reg-32.5 {canmatch functionality -- last char} {knownBug testregexp} {
+    set pat {.[^d]x$}
+    set line "asd asd"
+    # can match the last char, if followed by not-d and x.
+    set res [testregexp -xflags -- c $pat $line resvar]
+    lappend res $resvar
+} {0 6}
+test reg-32.6 {canmatch functionality -- last char} {knownBug testregexp} {
+    set pat {[^a]%[^\r\n]*$}
+    set line "asd asd"
+    # can match at the final d, if '%' follows
+    set res [testregexp -xflags -- c $pat $line resvar]
+    lappend res $resvar
+} {0 6}
+test reg-32.7 {canmatch functionality -- last char} {knownBug testregexp} {
+    set pat {[^a]%$}
+    set line "asd asd"
+    # can match at the final d, if '%' follows
+    set res [testregexp -xflags -- c $pat $line resvar]
+    lappend res $resvar
+} {0 6}
+test reg-32.8 {canmatch functionality -- last char} {knownBug testregexp} {
+    set pat {[^x]%$}
+    set line "asd asd"
+    # can match at the final d, if '%' follows
+    set res [testregexp -xflags -- c $pat $line resvar]
+    lappend res $resvar
+} {0 6}
+test reg-32.9 {canmatch functionality -- more complex case} {knownBug testregexp} {
+    set pat {((\B\B|\Bh+line)[ \t]*|[^\B]%[^\r\n]*)$}
+    set line "asd asd"
+    # can match at the final d, if '%' follows
+    set res [testregexp -xflags -- c $pat $line resvar]
+    lappend res $resvar
+} {0 6}
+
+# Tests reg-33.*: Checks for bug fixes
+
+test reg-33.1 {Bug 230589} {
+    regexp {[ ]*(^|[^%])%V} "*%V2" m s
+} 1
+test reg-33.2 {Bug 504785} {
+    regexp -inline {([^_.]*)([^.]*)\.(..)(.).*} bbcos_001_c01.q1la
+} {bbcos_001_c01.q1la bbcos _001_c01 q1 l}
+test reg-33.3 {Bug 505048} {
+    regexp {\A\s*[^<]*\s*<([^>]+)>} a<a>
+} 1
+test reg-33.4 {Bug 505048} {
+    regexp {\A\s*([^b]*)b} ab
+} 1
+test reg-33.5 {Bug 505048} {
+    regexp {\A\s*[^b]*(b)} ab
+} 1
+test reg-33.6 {Bug 505048} {
+    regexp {\A(\s*)[^b]*(b)} ab
+} 1
+test reg-33.7 {Bug 505048} {
+    regexp {\A\s*[^b]*b} ab
+} 1
+test reg-33.8 {Bug 505048} {
+    regexp -inline {\A\s*[^b]*b} ab
+} ab
+test reg-33.9 {Bug 505048} {
+    regexp -indices -inline {\A\s*[^b]*b} ab
+} {{0 1}}
+test reg-33.10 {Bug 840258} -body {
+    regsub {(^|\n)+\.*b} \n.b {} tmp
+} -cleanup {
+    unset tmp
+} -result 1
+test reg-33.11 {Bug 840258} -body {
+    regsub {(^|[\n\r]+)\.*\?<.*?(\n|\r)+} \
+	    "TQ\r\n.?<5000267>Test already stopped\r\n" {} tmp
+} -cleanup {
+    unset tmp
+} -result 1
+test reg-33.12 {Bug 1810264 - bad read} {
+    regexp {\3161573148} {\3161573148}
+} 0
+test reg-33.13 {Bug 1810264 - infinite loop} {
+    regexp {($|^)*} {x}
+} 1
+# Some environments have small default stack sizes. [Bug 1905562]
+test reg-33.14 {Bug 1810264 - super-expensive expression} nonPortable {
+    regexp {(x{200}){200}$y} {x}
+} 0
+
+test reg-33.15.1 {Bug 3603557 - an "in the wild" RE} {
+    lindex [regexp -expanded -about {
+	^TETRA_MODE_CMD				# Message Type
+	([[:blank:]]+)				# Pad
+	(ETS_1_1|ETS_1_2|ETS_2_2)		# SystemCode
+	([[:blank:]]+)				# Pad
+	(CONTINUOUS|CARRIER|MCCH|TRAFFIC)	# SharingMode
+	([[:blank:]]+)				# Pad
+	([[:digit:]]{1,2})			# ColourCode
+	([[:blank:]]+)				# Pad
+	(1|2|3|4|6|9|12|18)			# TSReservedFrames
+	([[:blank:]]+)				# Pad
+	(PASS|TRUE|FAIL|FALSE)			# UPlaneDTX
+	([[:blank:]]+)				# Pad
+	(PASS|TRUE|FAIL|FALSE)			# Frame18Extension
+	([[:blank:]]+)				# Pad
+	([[:digit:]]{1,4})			# MCC
+	([[:blank:]]+)				# Pad
+	([[:digit:]]{1,5})			# MNC
+	([[:blank:]]+)				# Pad
+	(BOTH|BCAST|ENQRY|NONE)			# NbrCellBcast
+	([[:blank:]]+)				# Pad
+	(UNKNOWN|LOW|MEDIUM|HIGH)		# CellServiceLevel
+	([[:blank:]]+)				# Pad
+	(PASS|TRUE|FAIL|FALSE)			# LateEntryInfo
+	([[:blank:]]+)				# Pad
+	(300|400)				# FrequencyBand
+	([[:blank:]]+)				# Pad
+	(NORMAL|REVERSE)			# ReverseOperation
+	([[:blank:]]+)				# Pad
+	(NONE|\+6\.25|\-6\.25|\+12\.5)		# Offset
+	([[:blank:]]+)				# Pad
+	(10)					# DuplexSpacing
+	([[:blank:]]+)				# Pad
+	([[:digit:]]{1,4})			# MainCarrierNr
+	([[:blank:]]+)				# Pad
+	(0|1|2|3)				# NrCSCCH
+	([[:blank:]]+)				# Pad
+	(15|20|25|30|35|40|45)			# MSTxPwrMax
+	([[:blank:]]+)				# Pad
+	(\-125|\-120|\-115|\-110|\-105|\-100|\-95|\-90|\-85|\-80|\-75|\-70|\-65|\-60|\-55|\-50)
+						# RxLevAccessMin
+	([[:blank:]]+)				# Pad
+	(\-53|\-51|\-49|\-47|\-45|\-43|\-41|\-39|\-37|\-35|\-33|\-31|\-29|\-27|\-25|\-23)
+						# AccessParameter
+	([[:blank:]]+)				# Pad
+	(DISABLE|[[:digit:]]{3,4})		# RadioDLTimeout
+	([[:blank:]]+)				# Pad
+	(\-[[:digit:]]{2,3})			# RSSIThreshold
+	([[:blank:]]+)				# Pad
+	([[:digit:]]{1,5})			# CCKIdSCKVerNr
+	([[:blank:]]+)				# Pad
+	([[:digit:]]{1,5})			# LocationArea
+	([[:blank:]]+)				# Pad
+	([(1|0)]{16})				# SubscriberClass
+	([[:blank:]]+)				# Pad
+	([(1|0)]{12})				# BSServiceDetails
+	([[:blank:]]+)				# Pad
+	(RANDOMIZE|IMMEDIATE|[[:digit:]]{1,2})	# IMM
+	([[:blank:]]+)				# Pad
+	([[:digit:]]{1,2})			# WT
+	([[:blank:]]+)				# Pad
+	([[:digit:]]{1,2})			# Nu
+	([[:blank:]]+)				# Pad
+	([0-1])					# FrameLngFctr
+	([[:blank:]]+)				# Pad
+	([[:digit:]]{1,2})			# TSPtr
+	([[:blank:]]+)				# Pad
+	([0-7])					# MinPriority
+	([[:blank:]]+)				# Pad
+	(PASS|TRUE|FAIL|FALSE)			# ExtdSrvcsEnabled
+	([[:blank:]]+)				# Pad
+	(.*)					# ConditionalFields
+    }] 0
+} 68
+test reg-33.16.1 {Bug [8d2c0da36d]- another "in the wild" RE} {
+    lindex [regexp -about "^MRK:client1: =1339 14HKelly Talisman 10011000 (\[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]*) \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* 8 0 8 0 0 0 77 77 1 1 2 0 11 { 1 3 8 \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* 00000000 1 13HC6 My Creator 2 3 8 \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* 00000000 1 31HC7 Slightly offensive name, huh 3 8 8 \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* 00000000 1 23HE-mail:kelly@hotbox.com 4 9 8 \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* 00000000 1 17Hcompface must die 5 10 8 \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* 00000000 0 3HAir 6 12 8 \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* 00000000 1 14HPGP public key 7 13 8 \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* 00000000 1 16Hkelly@hotbox.com 8 30 8 \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* 00000000 0 12H2 text/plain 9 30 8 \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* 00000000 0 13H2 x-kom/basic 10 33 8 \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* 00000000 1 1H0 11 14 8 \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* \[0-9\]* 00000000 1 1H3 }\r?"] 0
+} 1
+
+test reg-33.15 {constraint fixes} {
+    regexp {(^)+^} x
+} 1
+test reg-33.16 {constraint fixes} {
+    regexp {($^)+} x
+} 0
+test reg-33.17 {constraint fixes} {
+    regexp {(^$)*} x
+} 1
+test reg-33.18 {constraint fixes} {
+    regexp {(^(?!aa))+} {aa bb cc}
+} 0
+test reg-33.19 {constraint fixes} {
+    regexp {(^(?!aa)(?!bb)(?!cc))+} {aa x}
+} 0
+test reg-33.20 {constraint fixes} {
+    regexp {(^(?!aa)(?!bb)(?!cc))+} {bb x}
+} 0
+test reg-33.21 {constraint fixes} {
+    regexp {(^(?!aa)(?!bb)(?!cc))+} {cc x}
+} 0
+test reg-33.22 {constraint fixes} {
+    regexp {(^(?!aa)(?!bb)(?!cc))+} {dd x}
+} 1
+
+test reg-33.23 {} {
+    regexp {abcd(\m)+xyz} x
+} 0
+test reg-33.24 {} {
+    regexp {abcd(\m)+xyz} a
+} 0
+test reg-33.25 {} {
+    regexp {^abcd*(((((^(a c(e?d)a+|)+|)+|)+|)+|a)+|)} x
+} 0
+test reg-33.26 {} {
+    regexp {a^(^)bcd*xy(((((($a+|)+|)+|)+$|)+|)+|)^$} x
+} 0
+test reg-33.27 {} {
+    regexp {xyz(\Y\Y)+} x
+} 0
+test reg-33.28 {} {
+    regexp {x|(?:\M)+} x
+} 1
+test reg-33.29 {} {
+    # This is near the limits of the RE engine
+    regexp [string repeat x*y*z* 480] x
+} 1
+
+test reg-33.30 {Bug 1080042} {
+    regexp {(\Y)+} foo
+} 1
+
+# cleanup
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/tests/regexp.test b/tests/regexp.test
new file mode 100644
index 0000000..9fff262
--- /dev/null
+++ b/tests/regexp.test
@@ -0,0 +1,1133 @@
+# Commands covered:  regexp, regsub
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands.  Sourcing this file into Tcl runs the tests and
+# generates output for errors.  No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1998 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {"::tcltest" ni [namespace children]} {
+    package require tcltest 2
+    namespace import -force ::tcltest::*
+}
+
+unset -nocomplain foo
+
+testConstraint exec [llength [info commands exec]]
+
+test regexp-1.1 {basic regexp operation} {
+    regexp ab*c abbbc
+} 1
+test regexp-1.2 {basic regexp operation} {
+    regexp ab*c ac
+} 1
+test regexp-1.3 {basic regexp operation} {
+    regexp ab*c ab
+} 0
+test regexp-1.4 {basic regexp operation} {
+    regexp -- -gorp abc-gorpxxx
+} 1
+test regexp-1.5 {basic regexp operation} {
+    regexp {^([^ ]*)[ ]*([^ ]*)} "" a
+} 1
+test regexp-1.6 {basic regexp operation} {
+    list [catch {regexp {} abc} msg] $msg
+} {0 1}
+test regexp-1.7 {regexp utf compliance} {
+    # if not UTF-8 aware, result is "0 1"
+    set foo "\u4e4eb q"
+    regexp "\u4e4eb q" "a\u4e4eb qw\u5e4e\x4e wq" bar
+    list [string compare $foo $bar] [regexp 4 $bar]
+} {0 0}
+test regexp-1.8 {regexp ***= metasyntax} {
+    regexp -- "***=o" "aeiou"
+} 1
+test regexp-1.9 {regexp ***= metasyntax} {
+    set string "aeiou"
+    regexp -- "***=o" $string
+} 1
+test regexp-1.10 {regexp ***= metasyntax} {
+    set string "aeiou"
+    set re "***=o"
+    regexp -- $re $string
+} 1
+test regexp-1.11 {regexp ***= metasyntax} {
+    regexp -- "***=y" "aeiou"
+} 0
+test regexp-1.12 {regexp ***= metasyntax} {
+    set string "aeiou"
+    regexp -- "***=y" $string
+} 0
+test regexp-1.13 {regexp ***= metasyntax} {
+    set string "aeiou"
+    set re "***=y"
+    regexp -- $re $string
+} 0
+
+test regexp-2.1 {getting substrings back from regexp} {
+    set foo {}
+    list [regexp ab*c abbbbc foo] $foo
+} {1 abbbbc}
+test regexp-2.2 {getting substrings back from regexp} {
+    set foo {}
+    set f2 {}
+    list [regexp a(b*)c abbbbc foo f2] $foo $f2
+} {1 abbbbc bbbb}
+test regexp-2.3 {getting substrings back from regexp} {
+    set foo {}
+    set f2 {}
+    list [regexp a(b*)(c) abbbbc foo f2] $foo $f2
+} {1 abbbbc bbbb}
+test regexp-2.4 {getting substrings back from regexp} {
+    set foo {}
+    set f2 {}
+    set f3 {}
+    list [regexp a(b*)(c) abbbbc foo f2 f3] $foo $f2 $f3
+} {1 abbbbc bbbb c}
+test regexp-2.5 {getting substrings back from regexp} {
+    set foo {}; set f1 {}; set f2 {}; set f3 {}; set f4 {}; set f5 {};
+    set f6 {}; set f7 {}; set f8 {}; set f9 {}; set fa {}; set fb {};
+    list [regexp (1*)(2*)(3*)(4*)(5*)(6*)(7*)(8*)(9*)(a*)(b*) \
+	      12223345556789999aabbb \
+	    foo f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fb] $foo $f1 $f2 $f3 $f4 $f5 \
+	    $f6 $f7 $f8 $f9 $fa $fb
+} {1 12223345556789999aabbb 1 222 33 4 555 6 7 8 9999 aa bbb}
+test regexp-2.6 {getting substrings back from regexp} {
+    set foo 2; set f2 2; set f3 2; set f4 2
+    list [regexp (a)(b)? xay foo f2 f3 f4] $foo $f2 $f3 $f4
+} {1 a a {} {}}
+test regexp-2.7 {getting substrings back from regexp} {
+    set foo 1; set f2 1; set f3 1; set f4 1
+    list [regexp (a)(b)?(c) xacy foo f2 f3 f4] $foo $f2 $f3 $f4
+} {1 ac a {} c}
+test regexp-2.8 {getting substrings back from regexp} {
+    set match {}
+    list [regexp {^a*b} aaaab match] $match
+} {1 aaaab}
+test regexp-2.9 {getting substrings back from regexp} {
+    set foo {}
+    set f2 {}
+    list [regexp f\352te(b*)c f\352tebbbbc foo f2] $foo $f2
+} [list 1 f\352tebbbbc bbbb]
+test regexp-2.10 {getting substrings back from regexp} {
+    set foo {}
+    set f2 {}
+    list [regexp f\352te(b*)c eff\352tebbbbc foo f2] $foo $f2
+} [list 1 f\352tebbbbc bbbb]
+test regexp-2.11 {non-capturing subgroup} {
+    set foo {}
+    set f2 {}
+    list [regexp {str(?:a+)} straa foo f2] $foo $f2
+} [list 1 straa {}]
+test regexp-2.12 {non-capturing subgroup with -inline} {
+    regexp -inline {str(?:a+)} straa
+} {straa}
+test regexp-2.13 {non-capturing and capturing subgroups} {
+    set foo {}
+    set f2 {}
+    set f3 {}
+    list [regexp {str(?:a+)(c+)} straacc foo f2 f3] $foo $f2 $f3
+} [list 1 straacc cc {}]
+test regexp-2.14 {non-capturing and capturing subgroups} {
+    regexp -inline {str(?:a+)(c+)} straacc
+} {straacc cc}
+test regexp-2.15 {getting substrings back from regexp} {
+    set foo NA
+    set f2 NA
+    list [regexp {str(?:a+)} straa foo f2] $foo $f2
+} [list 1 straa {}]
+
+test regexp-3.1 {-indices option to regexp} {
+    set foo {}
+    list [regexp -indices ab*c abbbbc foo] $foo
+} {1 {0 5}}
+test regexp-3.2 {-indices option to regexp} {
+    set foo {}
+    set f2 {}
+    list [regexp -indices a(b*)c abbbbc foo f2] $foo $f2
+} {1 {0 5} {1 4}}
+test regexp-3.3 {-indices option to regexp} {
+    set foo {}
+    set f2 {}
+    list [regexp -indices a(b*)(c) abbbbc foo f2] $foo $f2
+} {1 {0 5} {1 4}}
+test regexp-3.4 {-indices option to regexp} {
+    set foo {}
+    set f2 {}
+    set f3 {}
+    list [regexp -indices a(b*)(c) abbbbc foo f2 f3] $foo $f2 $f3
+} {1 {0 5} {1 4} {5 5}}
+test regexp-3.5 {-indices option to regexp} {
+    set foo {}; set f1 {}; set f2 {}; set f3 {}; set f4 {}; set f5 {};
+    set f6 {}; set f7 {}; set f8 {}; set f9 {}
+    list [regexp -indices (1*)(2*)(3*)(4*)(5*)(6*)(7*)(8*)(9*) \
+	    12223345556789999 \
+	    foo f1 f2 f3 f4 f5 f6 f7 f8 f9] $foo $f1 $f2 $f3 $f4 $f5 \
+	    $f6 $f7 $f8 $f9
+} {1 {0 16} {0 0} {1 3} {4 5} {6 6} {7 9} {10 10} {11 11} {12 12} {13 16}}
+test regexp-3.6 {getting substrings back from regexp} {
+    set foo 2; set f2 2; set f3 2; set f4 2
+    list [regexp -indices (a)(b)? xay foo f2 f3 f4] $foo $f2 $f3 $f4
+} {1 {1 1} {1 1} {-1 -1} {-1 -1}}
+test regexp-3.7 {getting substrings back from regexp} {
+    set foo 1; set f2 1; set f3 1; set f4 1
+    list [regexp -indices (a)(b)?(c) xacy foo f2 f3 f4] $foo $f2 $f3 $f4
+} {1 {1 2} {1 1} {-1 -1} {2 2}}
+
+test regexp-4.1 {-nocase option to regexp} {
+    regexp -nocase foo abcFOo
+} 1
+test regexp-4.2 {-nocase option to regexp} {
+    set f1 22
+    set f2 33
+    set f3 44
+    list [regexp -nocase {a(b*)([xy]*)z} aBbbxYXxxZ22 f1 f2 f3] $f1 $f2 $f3
+} {1 aBbbxYXxxZ Bbb xYXxx}
+test regexp-4.3 {-nocase option to regexp} {
+    regexp -nocase FOo abcFOo
+} 1
+set x abcdefghijklmnopqrstuvwxyz1234567890
+set x $x$x$x$x$x$x$x$x$x$x$x$x
+test regexp-4.4 {case conversion in regexp} {
+    list [regexp -nocase $x $x foo] $foo
+} "1 $x"
+unset -nocomplain x
+
+test regexp-5.1 {exercise cache of compiled expressions} {
+    regexp .*a b
+    regexp .*b c
+    regexp .*c d
+    regexp .*d e
+    regexp .*e f
+    regexp .*a bbba
+} 1
+test regexp-5.2 {exercise cache of compiled expressions} {
+    regexp .*a b
+    regexp .*b c
+    regexp .*c d
+    regexp .*d e
+    regexp .*e f
+    regexp .*b xxxb
+} 1
+test regexp-5.3 {exercise cache of compiled expressions} {
+    regexp .*a b
+    regexp .*b c
+    regexp .*c d
+    regexp .*d e
+    regexp .*e f
+    regexp .*c yyyc
+} 1
+test regexp-5.4 {exercise cache of compiled expressions} {
+    regexp .*a b
+    regexp .*b c
+    regexp .*c d
+    regexp .*d e
+    regexp .*e f
+    regexp .*d 1d
+} 1
+test regexp-5.5 {exercise cache of compiled expressions} {
+    regexp .*a b
+    regexp .*b c
+    regexp .*c d
+    regexp .*d e
+    regexp .*e f
+    regexp .*e xe
+} 1
+
+test regexp-6.1 {regexp errors} {
+    list [catch {regexp a} msg] $msg
+} {1 {wrong # args: should be "regexp ?-option ...? exp string ?matchVar? ?subMatchVar ...?"}}
+test regexp-6.2 {regexp errors} {
+    list [catch {regexp -nocase a} msg] $msg
+} {1 {wrong # args: should be "regexp ?-option ...? exp string ?matchVar? ?subMatchVar ...?"}}
+test regexp-6.3 {regexp errors} {
+    list [catch {regexp -gorp a} msg] $msg
+} {1 {bad option "-gorp": must be -all, -about, -indices, -inline, -expanded, -line, -linestop, -lineanchor, -nocase, -start, or --}}
+test regexp-6.4 {regexp errors} {
+    list [catch {regexp a( b} msg] $msg
+} {1 {couldn't compile regular expression pattern: parentheses () not balanced}}
+test regexp-6.5 {regexp errors} {
+    list [catch {regexp a( b} msg] $msg
+} {1 {couldn't compile regular expression pattern: parentheses () not balanced}}
+test regexp-6.6 {regexp errors} {
+    list [catch {regexp a a f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1} msg] $msg
+} {0 1}
+test regexp-6.7 {regexp errors} {
+    list [catch {regexp (x)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.) xyzzy} msg] $msg
+} {0 0}
+test regexp-6.8 {regexp errors} -setup {
+    unset -nocomplain f1
+} -body {
+    set f1 44
+    regexp abc abc f1(f2)
+} -returnCodes error -result {can't set "f1(f2)": variable isn't array}
+test regexp-6.9 {regexp errors, -start bad int check} {
+    list [catch {regexp -start bogus {^$} {}} msg] $msg
+} {1 {bad index "bogus": must be integer?[+-]integer? or end?[+-]integer?}}
+test regexp-6.10 {regexp errors} {
+    list [catch {regexp {a[} b} msg] $msg
+} {1 {couldn't compile regular expression pattern: brackets [] not balanced}}
+
+test regexp-7.1 {basic regsub operation} {
+    list [regsub aa+ xaxaaaxaa 111&222 foo] $foo
+} {1 xax111aaa222xaa}
+test regexp-7.2 {basic regsub operation} {
+    list [regsub aa+ aaaxaa &111 foo] $foo
+} {1 aaa111xaa}
+test regexp-7.3 {basic regsub operation} {
+    list [regsub aa+ xaxaaa 111& foo] $foo
+} {1 xax111aaa}
+test regexp-7.4 {basic regsub operation} {
+    list [regsub aa+ aaa 11&2&333 foo] $foo
+} {1 11aaa2aaa333}
+test regexp-7.5 {basic regsub operation} {
+    list [regsub aa+ xaxaaaxaa &2&333 foo] $foo
+} {1 xaxaaa2aaa333xaa}
+test regexp-7.6 {basic regsub operation} {
+    list [regsub aa+ xaxaaaxaa 1&22& foo] $foo
+} {1 xax1aaa22aaaxaa}
+test regexp-7.7 {basic regsub operation} {
+    list [regsub a(a+) xaxaaaxaa {1\122\1} foo] $foo
+} {1 xax1aa22aaxaa}
+test regexp-7.8 {basic regsub operation} {
+    list [regsub a(a+) xaxaaaxaa {1\\\122\1} foo] $foo
+} "1 {xax1\\aa22aaxaa}"
+test regexp-7.9 {basic regsub operation} {
+    list [regsub a(a+) xaxaaaxaa {1\\122\1} foo] $foo
+} "1 {xax1\\122aaxaa}"
+test regexp-7.10 {basic regsub operation} {
+    list [regsub a(a+) xaxaaaxaa {1\\&\1} foo] $foo
+} "1 {xax1\\aaaaaxaa}"
+test regexp-7.11 {basic regsub operation} {
+    list [regsub a(a+) xaxaaaxaa {1\&\1} foo] $foo
+} {1 xax1&aaxaa}
+test regexp-7.12 {basic regsub operation} {
+    list [regsub a(a+) xaxaaaxaa {\1\1\1\1&&} foo] $foo
+} {1 xaxaaaaaaaaaaaaaaxaa}
+test regexp-7.13 {basic regsub operation} {
+    set foo xxx
+    list [regsub abc xyz 111 foo] $foo
+} {0 xyz}
+test regexp-7.14 {basic regsub operation} {
+    set foo xxx
+    list [regsub ^ xyz "111 " foo] $foo
+} {1 {111 xyz}}
+test regexp-7.15 {basic regsub operation} {
+    set foo xxx
+    list [regsub -- -foo abc-foodef "111 " foo] $foo
+} {1 {abc111 def}}
+test regexp-7.16 {basic regsub operation} {
+    set foo xxx
+    list [regsub x "" y foo] $foo
+} {0 {}}
+test regexp-7.17 {regsub utf compliance} {
+    # if not UTF-8 aware, result is "0 1"
+    set foo "xyz555ijka\u4e4ebpqr"
+    regsub a\u4e4eb xyza\u4e4ebijka\u4e4ebpqr 555 bar
+    list [string compare $foo $bar] [regexp 4 $bar]
+} {0 0}
+test regexp-7.18 {basic regsub replacement} {
+    list [regsub a+ aaa {&} foo] $foo
+} {1 aaa}
+test regexp-7.19 {basic regsub replacement} {
+    list [regsub a+ aaa {\&} foo] $foo
+} {1 &}
+test regexp-7.20 {basic regsub replacement} {
+    list [regsub a+ aaa {\\&} foo] $foo
+} {1 {\aaa}}
+test regexp-7.21 {basic regsub replacement} {
+    list [regsub a+ aaa {\\\&} foo] $foo
+} {1 {\&}}
+test regexp-7.22 {basic regsub replacement} {
+    list [regsub a+ aaa {\0} foo] $foo
+} {1 aaa}
+test regexp-7.23 {basic regsub replacement} {
+    list [regsub a+ aaa {\\0} foo] $foo
+} {1 {\0}}
+test regexp-7.24 {basic regsub replacement} {
+    list [regsub a+ aaa {\\\0} foo] $foo
+} {1 {\aaa}}
+test regexp-7.25 {basic regsub replacement} {
+    list [regsub a+ aaa {\\\\0} foo] $foo
+} {1 {\\0}}
+test regexp-7.26 {dollar zero is not a backslash replacement} {
+    list [regsub a+ aaa {$0} foo] $foo
+} {1 {$0}}
+test regexp-7.27 {dollar zero is not a backslash replacement} {
+    list [regsub a+ aaa {\0$0} foo] $foo
+} {1 {aaa$0}}
+test regexp-7.28 {dollar zero is not a backslash replacement} {
+    list [regsub a+ aaa {\$0} foo] $foo
+} {1 {\$0}}
+test regexp-7.29 {dollar zero is not a backslash replacement} {
+    list [regsub a+ aaa {\\} foo] $foo
+} {1 \\}
+
+test regexp-8.1 {case conversion in regsub} {
+    list [regsub -nocase a(a+) xaAAaAAay & foo] $foo
+} {1 xaAAaAAay}
+test regexp-8.2 {case conversion in regsub} {
+    list [regsub -nocase a(a+) xaAAaAAay & foo] $foo
+} {1 xaAAaAAay}
+test regexp-8.3 {case conversion in regsub} {
+    set foo 123
+    list [regsub a(a+) xaAAaAAay & foo] $foo
+} {0 xaAAaAAay}
+test regexp-8.4 {case conversion in regsub} {
+    set foo 123
+    list [regsub -nocase a CaDE b foo] $foo
+} {1 CbDE}
+test regexp-8.5 {case conversion in regsub} {
+    set foo 123
+    list [regsub -nocase XYZ CxYzD b foo] $foo
+} {1 CbD}
+test regexp-8.6 {case conversion in regsub} {
+    set x abcdefghijklmnopqrstuvwxyz1234567890
+    set x $x$x$x$x$x$x$x$x$x$x$x$x
+    set foo 123
+    list [regsub -nocase $x $x b foo] $foo
+} {1 b}
+
+test regexp-9.1 {-all option to regsub} {
+    set foo 86
+    list [regsub -all x+ axxxbxxcxdx |&| foo] $foo
+} {4 a|xxx|b|xx|c|x|d|x|}
+test regexp-9.2 {-all option to regsub} {
+    set foo 86
+    list [regsub -nocase -all x+ aXxXbxxcXdx |&| foo] $foo
+} {4 a|XxX|b|xx|c|X|d|x|}
+test regexp-9.3 {-all option to regsub} {
+    set foo 86
+    list [regsub x+ axxxbxxcxdx |&| foo] $foo
+} {1 a|xxx|bxxcxdx}
+test regexp-9.4 {-all option to regsub} {
+    set foo 86
+    list [regsub -all bc axxxbxxcxdx |&| foo] $foo
+} {0 axxxbxxcxdx}
+test regexp-9.5 {-all option to regsub} {
+    set foo xxx
+    list [regsub -all node "node node more" yy foo] $foo
+} {2 {yy yy more}}
+test regexp-9.6 {-all option to regsub} {
+    set foo xxx
+    list [regsub -all ^ xxx 123 foo] $foo
+} {1 123xxx}
+
+test regexp-10.1 {expanded syntax in regsub} {
+    set foo xxx
+    list [regsub -expanded ". \#comment\n  . \#comment2" abc def foo] $foo
+} {1 defc}
+test regexp-10.2 {newline sensitivity in regsub} {
+    set foo xxx
+    list [regsub -line {^a.*b$} "dabc\naxyb\n" 123 foo] $foo
+} "1 {dabc\n123\n}"
+test regexp-10.3 {newline sensitivity in regsub} {
+    set foo xxx
+    list [regsub -line {^a.*b$} "dabc\naxyb\nxb" 123 foo] $foo
+} "1 {dabc\n123\nxb}"
+test regexp-10.4 {partial newline sensitivity in regsub} {
+    set foo xxx
+    list [regsub -lineanchor {^a.*b$} "da\naxyb\nxb" 123 foo] $foo
+} "1 {da\n123}"
+test regexp-10.5 {inverse partial newline sensitivity in regsub} {
+    set foo xxx
+    list [regsub -linestop {a.*b} "da\nbaxyb\nxb" 123 foo] $foo
+} "1 {da\nb123\nxb}"
+
+test regexp-11.1 {regsub errors} {
+    list [catch {regsub a b} msg] $msg
+} {1 {wrong # args: should be "regsub ?-option ...? exp string subSpec ?varName?"}}
+test regexp-11.2 {regsub errors} {
+    list [catch {regsub -nocase a b} msg] $msg
+} {1 {wrong # args: should be "regsub ?-option ...? exp string subSpec ?varName?"}}
+test regexp-11.3 {regsub errors} {
+    list [catch {regsub -nocase -all a b} msg] $msg
+} {1 {wrong # args: should be "regsub ?-option ...? exp string subSpec ?varName?"}}
+test regexp-11.4 {regsub errors} {
+    list [catch {regsub a b c d e f} msg] $msg
+} {1 {wrong # args: should be "regsub ?-option ...? exp string subSpec ?varName?"}}
+test regexp-11.5 {regsub errors} {
+    list [catch {regsub -gorp a b c} msg] $msg
+} {1 {bad option "-gorp": must be -all, -nocase, -expanded, -line, -linestop, -lineanchor, -start, or --}}
+test regexp-11.6 {regsub errors} {
+    list [catch {regsub -nocase a( b c d} msg] $msg
+} {1 {couldn't compile regular expression pattern: parentheses () not balanced}}
+test regexp-11.7 {regsub errors} -setup {
+    unset -nocomplain f1
+} -body {
+    set f1 44
+    regsub -nocase aaa aaa xxx f1(f2)
+} -returnCodes error -result {can't set "f1(f2)": variable isn't array}
+test regexp-11.8 {regsub errors, -start bad int check} {
+    list [catch {regsub -start bogus pattern string rep var} msg] $msg
+} {1 {bad index "bogus": must be integer?[+-]integer? or end?[+-]integer?}}
+test regexp-11.9 {regsub without final variable name returns value} {
+    regsub b abaca X
+} {aXaca}
+test regexp-11.10 {regsub without final variable name returns value} {
+    regsub -all a abaca X
+} {XbXcX}
+test regexp-11.11 {regsub without final variable name returns value} {
+    regsub b(.*?)d abcdeabcfde {,&,\1,}
+} {a,bcd,c,eabcfde}
+test regexp-11.12 {regsub without final variable name returns value} {
+    regsub -all b(.*?)d abcdeabcfde {,&,\1,}
+} {a,bcd,c,ea,bcfd,cf,e}
+
+# This test crashes on the Mac unless you increase the Stack Space to about 1
+# Meg.  This is probably bigger than most users want... 
+# 8.2.3 regexp reduced stack space requirements, but this should be
+# tested again
+test regexp-12.1 {Tcl_RegExpExec: large number of subexpressions} {macCrash} {
+    list [regexp (.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.) abcdefghijklmnopqrstuvwxyz all a b c d e f g h i j k l m n o p q r s t u v w x y z] $all $a $b $c $d $e $f $g $h $i $j $k $l $m $n $o $p $q $r $s $t $u $v $w $x $y $z
+} {1 abcdefghijklmnopqrstuvwxyz a b c d e f g h i j k l m n o p q r s t u v w x y z}
+
+test regexp-13.1 {regsub of a very large string} {
+    # This test is designed to stress the memory subsystem in order to catch
+    # Bug #933.  It only fails if the Tcl memory allocator is in use.
+    set line {BEGIN_TABLE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; END_TABLE}
+    set filedata [string repeat $line 200]
+    for {set i 1} {$i<10} {incr i} {
+	regsub -all "BEGIN_TABLE " $filedata "" newfiledata
+    }
+    set x done
+} {done}
+
+test regexp-14.1 {CompileRegexp: regexp cache} {
+    regexp .*a b
+    regexp .*b c
+    regexp .*c d
+    regexp .*d e
+    regexp .*e f
+    set x .
+    append x *a
+    regexp $x bbba
+} 1
+test regexp-14.2 {CompileRegexp: regexp cache, different flags} {
+    regexp .*a b
+    regexp .*b c
+    regexp .*c d
+    regexp .*d e
+    regexp .*e f
+    set x .
+    append x *a
+    regexp -nocase $x bbba
+} 1
+test regexp-14.3 {CompileRegexp: regexp cache, empty regexp and empty cache} -constraints {
+    exec
+} -setup {
+    set junk [makeFile {puts [regexp {} foo]} junk.tcl]
+} -body {
+    exec [interpreter] $junk
+} -cleanup {
+    removeFile junk.tcl
+} -result 1
+
+test regexp-15.1 {regexp -start} {
+    unset -nocomplain x
+    list [regexp -start -10 {\d} 1abc2de3 x] $x
+} {1 1}
+test regexp-15.2 {regexp -start} {
+    unset -nocomplain x
+    list [regexp -start 2 {\d} 1abc2de3 x] $x
+} {1 2}
+test regexp-15.3 {regexp -start} {
+    unset -nocomplain x
+    list [regexp -start 4 {\d} 1abc2de3 x] $x
+} {1 2}
+test regexp-15.4 {regexp -start} {
+    unset -nocomplain x
+    list [regexp -start 5 {\d} 1abc2de3 x] $x
+} {1 3}
+test regexp-15.5 {regexp -start, over end of string} {
+    unset -nocomplain x
+    list [regexp -start [string length 1abc2de3] {\d} 1abc2de3 x] [info exists x]
+} {0 0}
+test regexp-15.6 {regexp -start, loss of ^$ behavior} {
+    list [regexp -start 2 {^$} {}]
+} {0}
+test regexp-15.7 {regexp -start, double option} {
+    regexp -start 2 -start 0 a abc
+} 1
+test regexp-15.8 {regexp -start, double option} {
+    regexp -start 0 -start 2 a abc
+} 0
+test regexp-15.9 {regexp -start, end relative index} {
+    unset -nocomplain x
+    list [regexp -start end {\d} 1abc2de3 x] [info exists x]
+} {0 0}
+test regexp-15.10 {regexp -start, end relative index} {
+    unset -nocomplain x
+    list [regexp -start end-1 {\d} 1abc2de3 x] [info exists x] $x
+} {1 1 3}
+test regexp-15.11 {regexp -start, over end of string} {
+    set x NA
+    list [regexp -start 2 {.*} ab x] $x
+} {1 {}}
+
+test regexp-16.1 {regsub -start} {
+    unset -nocomplain x
+    list [regsub -all -start 2 {\d} a1b2c3d4e5 {/&} x] $x
+} {4 a1b/2c/3d/4e/5}
+test regexp-16.2 {regsub -start} {
+    unset -nocomplain x
+    list [regsub -all -start -25 {z} hello {/&} x] $x
+} {0 hello}
+test regexp-16.3 {regsub -start} {
+    unset -nocomplain x
+    list [regsub -all -start 3 {z} hello {/&} x] $x
+} {0 hello}
+test regexp-16.4 {regsub -start, \A behavior} {
+    set out {}
+    lappend out [regsub -start 0 -all {\A(\w)} {abcde} {/\1} x] $x
+    lappend out [regsub -start 2 -all {\A(\w)} {abcde} {/\1} x] $x
+} {5 /a/b/c/d/e 3 ab/c/d/e}
+test regexp-16.5 {regsub -start, double option} {
+    list [regsub -start 2 -start 0 a abc c x] $x
+} {1 cbc}
+test regexp-16.6 {regsub -start, double option} {
+    list [regsub -start 0 -start 2 a abc c x] $x
+} {0 abc}
+test regexp-16.7 {regexp -start, end relative index} {
+    list [regsub -start end a aaa b x] $x
+} {0 aaa}
+test regexp-16.8 {regexp -start, end relative index} {
+    list [regsub -start end-1 a aaa b x] $x
+} {1 aab}
+test regexp-16.9 {regsub -start and -all} {
+    set foo {}
+    list [regsub -start 0 -all x+ axxxbxx |&| foo] $foo
+} {2 a|xxx|b|xx|}
+test regexp-16.10 {regsub -start and -all} {
+    set foo {}
+    list [regsub -start 1 -all x+ axxxbxx |&| foo] $foo
+} {2 a|xxx|b|xx|}
+test regexp-16.11 {regsub -start and -all} {
+    set foo {}
+    list [regsub -start 4 -all x+ axxxbxx |&| foo] $foo
+} {1 axxxb|xx|}
+test regexp-16.12 {regsub -start} {
+    set foo {}
+    list [regsub -start 4 x+ axxxbxx |&| foo] $foo
+} {1 axxxb|xx|}
+test regexp-16.13 {regsub -start and -all} {
+    set foo {}
+    list [regsub -start 1 -all a+ "" & foo] $foo
+} {0 {}}
+test regexp-16.14 {regsub -start} {
+    set foo {}
+    list [regsub -start 1 a+ "" & foo] $foo
+} {0 {}}
+test regexp-16.15 {regsub -start and -all} {
+    set foo {}
+    list [regsub -start 2 -all a+ "xy" & foo] $foo
+} {0 xy}
+test regexp-16.16 {regsub -start} {
+    set foo {}
+    list [regsub -start 2 a+ "xy" & foo] $foo
+} {0 xy}
+test regexp-16.17 {regsub -start and -all} {
+    set foo {}
+    list [regsub -start 1 -all y+ "xy" & foo] $foo
+} {1 xy}
+test regexp-16.18 {regsub -start} {
+    set foo {}
+    list [regsub -start 1 y+ "xy" & foo] $foo
+} {1 xy}
+test regexp-16.19 {regsub -start} {
+    set foo {}
+    list [regsub -start -1 a+ "" & foo] $foo
+} {0 {}}
+test regexp-16.20 {regsub -start, loss of ^$ behavior} {
+    set foo NA
+    list [regsub -start 1 {^$} {} & foo] $foo
+} {0 {}}
+test regexp-16.21 {regsub -start, loss of ^$ behavior} {
+    set foo NA
+    list [regsub -start 1 {^.*$} abc & foo] $foo
+} {0 abc}
+test regexp-16.22 {regsub -start, loss of ^$ behavior} {
+    set foo NA
+    list [regsub -all -start 1 {^.*$} abc & foo] $foo
+} {0 abc}
+
+test regexp-17.1 {regexp -inline} {
+    regexp -inline b ababa
+} {b}
+test regexp-17.2 {regexp -inline} {
+    regexp -inline (b) ababa
+} {b b}
+test regexp-17.3 {regexp -inline -indices} {
+    regexp -inline -indices (b) ababa
+} {{1 1} {1 1}}
+test regexp-17.4 {regexp -inline} {
+    regexp -inline {\w(\d+)\w} "   hello 23 there456def "
+} {e456d 456}
+test regexp-17.5 {regexp -inline no matches} {
+    regexp -inline {\w(\d+)\w} ""
+} {}
+test regexp-17.6 {regexp -inline no matches} {
+    regexp -inline hello goodbye
+} {}
+test regexp-17.7 {regexp -inline, no matchvars allowed} {
+    list [catch {regexp -inline b abc match} msg] $msg
+} {1 {regexp match variables not allowed when using -inline}}
+
+test regexp-18.1 {regexp -all} {
+    regexp -all b bbbbb
+} {5}
+test regexp-18.2 {regexp -all} {
+    regexp -all b abababbabaaaaaaaaaab
+} {6}
+test regexp-18.3 {regexp -all -inline} {
+    regexp -all -inline b abababbabaaaaaaaaaab
+} {b b b b b b}
+test regexp-18.4 {regexp -all -inline} {
+    regexp -all -inline {\w(\w)} abcdefg
+} {ab b cd d ef f}
+test regexp-18.5 {regexp -all -inline} {
+    regexp -all -inline {\w(\w)$} abcdefg
+} {fg g}
+test regexp-18.6 {regexp -all -inline} {
+    regexp -all -inline {\d+} 10:20:30:40
+} {10 20 30 40}
+test regexp-18.7 {regexp -all -inline} {
+    list [catch {regexp -all -inline b abc match} msg] $msg
+} {1 {regexp match variables not allowed when using -inline}}
+test regexp-18.8 {regexp -all} {
+    # This should not cause an infinite loop
+    regexp -all -inline {a*} a
+} {a}
+test regexp-18.9 {regexp -all} {
+    # Yes, the expected result is {a {}}.  Here's why:
+    # Start at index 0; a* matches the "a" there then stops.
+    # Go to index 1; a* matches the lambda (or {}) there then stops.  Recall
+    #   that a* matches zero or more "a"'s; thus it matches the string "b", as
+    #   there are zero or more "a"'s there.
+    # Go to index 2; this is past the end of the string, so stop.
+    regexp -all -inline {a*} ab
+} {a {}}
+test regexp-18.10 {regexp -all} {
+    # Yes, the expected result is {a {} a}.  Here's why:
+    # Start at index 0; a* matches the "a" there then stops.
+    # Go to index 1; a* matches the lambda (or {}) there then stops.   Recall
+    #   that a* matches zero or more "a"'s; thus it matches the string "b", as
+    #   there are zero or more "a"'s there.
+    # Go to index 2; a* matches the "a" there then stops.
+    # Go to index 3; this is past the end of the string, so stop.
+    regexp -all -inline {a*} aba
+} {a {} a}
+test regexp-18.11 {regexp -all} {
+    regexp -all -inline {^a} aaaa
+} {a}
+test regexp-18.12 {regexp -all -inline -indices} {
+    regexp -all -inline -indices a(b(c)d|e(f)g)h abcdhaefgh
+} {{0 4} {1 3} {2 2} {-1 -1} {5 9} {6 8} {-1 -1} {7 7}}
+
+test regexp-19.1 {regsub null replacement} {
+    regsub -all {@} {@hel@lo@} "\0a\0" result
+    list $result [string length $result]
+} "\0a\0hel\0a\0lo\0a\0 14"
+
+test regexp-19.2 {regsub null replacement} {
+    regsub -all {@} {@hel@lo@} "\0a\0" result
+    set expected "\0a\0hel\0a\0lo\0a\0"
+    string equal $result $expected
+} 1
+
+test regexp-20.1 {regsub shared object shimmering} {
+    # Bug #461322
+    set a abcdefghijklmnopqurstuvwxyz 
+    set b $a 
+    set c abcdefghijklmnopqurstuvwxyz0123456789 
+    regsub $a $c $b d 
+    list $d [string length $d] [string bytelength $d]
+} [list abcdefghijklmnopqurstuvwxyz0123456789 37 37]
+test regexp-20.2 {regsub shared object shimmering with -about} {
+    eval regexp -about abc
+} {0 {}}
+
+test regexp-21.1 {regsub works with empty string} {
+    regsub -- ^ {} foo
+} {foo}
+test regexp-21.2 {regsub works with empty string} {
+    regsub -- \$ {} foo
+} {foo}
+test regexp-21.3 {regsub works with empty string offset} {
+    regsub -start 0 -- ^ {} foo
+} {foo}
+test regexp-21.4 {regsub works with empty string offset} {
+    regsub -start 0 -- \$ {} foo
+} {foo}
+test regexp-21.5 {regsub works with empty string offset} {
+    regsub -start 3 -- \$ {123} foo
+} {123foo}
+test regexp-21.6 {regexp works with empty string} {
+    regexp -- ^ {}
+} {1}
+test regexp-21.7 {regexp works with empty string} {
+    regexp -start 0 -- ^ {}
+} {1}
+test regexp-21.8 {regexp works with empty string offset} {
+    regexp -start 3 -- ^ {123}
+} {0}
+test regexp-21.9 {regexp works with empty string offset} {
+    regexp -start 3 -- \$ {123}
+} {1}
+test regexp-21.10 {multiple matches handle newlines} {
+    regsub -all -lineanchor -- {^#[^\n]*\n} "#one\n#two\n#three\n" foo\n
+} "foo\nfoo\nfoo\n"
+test regexp-21.11 {multiple matches handle newlines} {
+    regsub -all -line -- ^ "a\nb\nc" \#
+} "\#a\n\#b\n\#c"
+test regexp-21.12 {multiple matches handle newlines} {
+    regsub -all -line -- ^ "\n\n" \#
+} "\#\n\#\n\#"
+test regexp-21.13 {multiple matches handle newlines} {
+    regexp -all -inline -indices -line -- ^ "a\nb\nc"
+} {{0 -1} {2 1} {4 3}}
+test regexp-21.14 {regsub works with empty string} {
+    regsub -- ^ {} &
+} {}
+test regexp-21.15 {regsub works with empty string} {
+    regsub -- ^ {} foo&
+} {foo}
+test regexp-21.16 {regsub works with empty string} {
+    regsub -all -- ^ {} foo&
+} {foo}
+test regexp-21.17 {regsub works with empty string} {
+    regsub -- ^ {} {foo\0}
+} {foo}
+test regexp-21.18 {regsub works with empty string} {
+    regsub -- ^.* {} {foo$0}
+} {foo$0}
+test regexp-21.19 {regsub works with empty string} {
+    regsub -- ^ {input} {}
+} {input}
+test regexp-21.20 {regsub works with empty string} {
+    regsub -- x {} {foo}
+} {}
+
+test regexp-22.1 {Bug 1810038} {
+    regexp ($|^X)* {}
+} 1
+test regexp-22.2 {regexp compile and backrefs, Bug 1857126} {
+    regexp -- {([bc])\1} bb
+} 1
+test regexp-22.3 {Bug 3604074} {
+    # This will hang in interps where the bug is not fixed
+    regexp ((((((((a)*)*)*)*)*)*)*)* a
+} 1
+test regexp-22.4 {Bug 3606139} -setup {
+    interp alias {} a {} string repeat a
+} -body {
+    # This crashes in interps where the bug is not fixed
+    regexp [join [list [a 160]([a 55])[a 668]([a 55])[a 669]([a 55]) \
+	[a 668]([a 55])[a 649]([a 55])[a 668]([a 55])[a 668]([a 55]) \
+	[a 672]([a 55])[a 669]([a 55])[a 671]([a 55])[a 671]([a 55]) \
+	[a 672]([a 55])[a 652]([a 55])[a 672]([a 55])[a 671]([a 55]) \
+	[a 671]([a 55])[a 671]([a 55])[a 653]([a 55])[a 672]([a 55]) \
+	[a 653]([a 55])[a 672]([a 55])[a 672]([a 55])[a 652]([a 55]) \
+	[a 671]([a 55])[a 652]([a 55])[a 652]([a 55])[a 672]([a 55]) \
+	[a 672]([a 55])[a 672]([a 55])[a 653]([a 55])[a 671]([a 55]) \
+	[a 669]([a 55])[a 649]([a 55])[a 668]([a 55])[a 668]([a 55]) \
+	[a 668]([a 55])[a 650]([a 55])[a 650]([a 55])[a 672]([a 55]) \
+	[a 669]([a 55])[a 669]([a 55])[a 668]([a 55])[a 668]([a 55]) \
+	[a 668]([a 55])[a 669]([a 55])[a 672]([a 55])[a 669]([a 55]) \
+	[a 669]([a 55])[a 669]([a 55])[a 669]([a 55])[a 672]([a 55]) \
+	[a 670]([a 55])[a 671]([a 55])[a 672]([a 55])[a 672]([a 55]) \
+	[a 671]([a 55])[a 671]([a 55])[a 672]([a 55])[a 669]([a 55]) \
+	[a 668]([a 55])[a 668]([a 55])[a 669]([a 55])[a 668]([a 55]) \
+	[a 669]([a 55])[a 668]([a 55])[a 669]([a 55])[a 669]([a 55]) \
+	[a 668]([a 55])[a 668]([a 55])[a 669]([a 55])[a 668]([a 55]) \
+	[a 669]([a 55])[a 669]([a 55])[a 669]([a 55])[a 669]([a 55]) \
+	[a 668]([a 55])[a 669]([a 55])[a 672]([a 55])[a 669]([a 55]) \
+	[a 669]([a 55])[a 669]([a 55])[a 669]([a 55])[a 668]([a 55]) \
+	[a 669]([a 55])[a 669]([a 55])[a 668]([a 55])[a 668]([a 55]) \
+	[a 668]([a 55])[a 669]([a 55])[a 668]([a 55])[a 669]([a 55]) \
+	[a 672]([a 55])[a 669]([a 55])[a 669]([a 55])[a 710]([a 55]) \
+	[a 668]([a 55])[a 669]([a 55])[a 668]([a 55])[a 669]([a 55]) \
+	[a 668]([a 55])[a 669]([a 55])[a 668]([a 55])[a 668]([a 55]) \
+	[a 668]([a 55])[a 668]([a 55])[a 668]([a 55])[a 669]([a 55]) \
+	[a 672]([a 55])[a 669]([a 55])[a 669]([a 55])[a 668]([a 55]) \
+	[a 669]([a 55])[a 669]([a 55])[a 668]([a 55])[a 668]([a 55]) \
+	[a 668]([a 55])[a 668]([a 55])[a 668]([a 55])[a 668]([a 55]) \
+	[a 667]([a 55])[a 668]([a 55])[a 669]([a 55])[a 668]([a 55]) \
+	[a 671]([a 55])[a 669]([a 55])[a 668]([a 55])[a 669]([a 55]) \
+	[a 669]([a 55])[a 669]([a 55])[a 668]([a 55])[a 669]([a 55]) \
+	[a 668]([a 55])[a 710]([a 55])[a 668]([a 55])[a 668]([a 55]) \
+	[a 668]([a 55])[a 668]([a 55])[a 668]([a 55])[a 511]] {}] a
+} -cleanup {
+    rename a {}
+} -returnCodes 1 -match glob -result {couldn't compile regular expression pattern: *}
+test regexp-22.5 {Bug 3610026} -setup {
+    set e {}
+    set cp 99
+    while {$cp < 32864} {
+	append e [format %c [incr cp]]
+    }
+} -body {
+    regexp -about $e
+} -cleanup {
+    unset -nocomplain e cp
+} -returnCodes error  -match glob -result {*too many colors*}
+test regexp-22.6 {Bug 6585b21ca8} {
+    expr {[regexp {(\w).*?\1} Programmer m] ? $m : "<NONE>"}
+} rogr
+
+
+test regexp-23.1 {regexp -all and -line} {
+    set string ""
+    list \
+	[regexp -all -inline -indices -line -- {^} $string] \
+	[regexp -all -inline -indices -line -- {^$} $string] \
+	[regexp -all -inline -indices -line -- {$} $string]
+} {{{0 -1}} {{0 -1}} {{0 -1}}}
+test regexp-23.2 {regexp -all and -line} {
+    set string "\n"
+    list \
+	[regexp -all -inline -indices -line -- {^} $string] \
+	[regexp -all -inline -indices -line -- {^$} $string] \
+	[regexp -all -inline -indices -line -- {$} $string]
+} {{{0 -1}} {{0 -1}} {{0 -1}}}
+test regexp-23.3 {regexp -all and -line} {
+    set string "\n\n"
+    list \
+	[regexp -all -inline -indices -line -- {^} $string] \
+	[regexp -all -inline -indices -line -- {^$} $string] \
+	[regexp -all -inline -indices -line -- {$} $string]
+} {{{0 -1} {1 0}} {{0 -1} {1 0}} {{0 -1} {1 0}}}
+test regexp-23.4 {regexp -all and -line} {
+    set string "a"
+    list \
+	[regexp -all -inline -indices -line -- {^} $string] \
+	[regexp -all -inline -indices -line -- {^.*$} $string] \
+	[regexp -all -inline -indices -line -- {$} $string]
+} {{{0 -1}} {{0 0}} {{1 0}}}
+test regexp-23.5 {regexp -all and -line} {knownBug} {
+    set string "a\n"
+    list \
+	[regexp -all -inline -indices -line -- {^} $string] \
+	[regexp -all -inline -indices -line -- {^.*$} $string] \
+	[regexp -all -inline -indices -line -- {$} $string]
+} {{{0 -1} {2 1}} {{0 0} {2 1}} {{1 0} {2 1}}}
+test regexp-23.6 {regexp -all and -line} {
+    set string "\na"
+    list \
+	[regexp -all -inline -indices -line -- {^} $string] \
+	[regexp -all -inline -indices -line -- {^.*$} $string] \
+	[regexp -all -inline -indices -line -- {$} $string]
+} {{{0 -1} {1 0}} {{0 -1} {1 1}} {{0 -1} {2 1}}}
+test regexp-23.7 {regexp -all and -line} {knownBug} {
+    set string "ab\n"
+    list \
+	[regexp -all -inline -indices -line -- {^} $string] \
+	[regexp -all -inline -indices -line -- {^.*$} $string] \
+	[regexp -all -inline -indices -line -- {$} $string]
+} {{{0 -1} {3 2}} {{0 1} {3 2}} {{2 1} {3 2}}}
+test regexp-23.8 {regexp -all and -line} {
+    set string "a\nb"
+    list \
+	[regexp -all -inline -indices -line -- {^} $string] \
+	[regexp -all -inline -indices -line -- {^.*$} $string] \
+	[regexp -all -inline -indices -line -- {$} $string]
+} {{{0 -1} {2 1}} {{0 0} {2 2}} {{1 0} {3 2}}}
+test regexp-23.9 {regexp -all and -line} {knownBug} {
+    set string "a\nb\n"
+    list \
+	[regexp -all -inline -indices -line -- {^} $string] \
+	[regexp -all -inline -indices -line -- {^.*$} $string] \
+	[regexp -all -inline -indices -line -- {$} $string]
+} {{{0 -1} {2 1} {4 3}} {{0 0} {2 2} {4 3}} {{1 0} {3 2} {4 3}}}
+test regexp-23.10 {regexp -all and -line} {
+    set string "a\nb\nc"
+    list \
+	[regexp -all -inline -indices -line -- {^} $string] \
+	[regexp -all -inline -indices -line -- {^.*$} $string] \
+	[regexp -all -inline -indices -line -- {$} $string]
+} {{{0 -1} {2 1} {4 3}} {{0 0} {2 2} {4 4}} {{1 0} {3 2} {5 4}}}
+test regexp-23.11 {regexp -all and -line} {
+    regexp -all -inline -indices -line -- {b} "abb\nb"
+} {{1 1} {2 2} {4 4}}
+
+test regexp-24.1 {regsub -all and -line} {
+    foreach {v1 v2 v3} {{} {} {}} {}
+    set string ""
+    list \
+	[regsub -line -all {^} $string {<&>} v1] $v1 \
+	[regsub -line -all {^$} $string {<&>} v2] $v2 \
+	[regsub -line -all {$} $string {<&>} v3] $v3
+} {1 <> 1 <> 1 <>}
+test regexp-24.2 {regsub -all and -line} {
+    foreach {v1 v2 v3} {{} {} {}} {}
+    set string "\n"
+    list \
+	[regsub -line -all {^} $string {<&>} v1] $v1 \
+	[regsub -line -all {^$} $string {<&>} v2] $v2 \
+	[regsub -line -all {$} $string {<&>} v3] $v3
+} [list 2 "<>\n<>" 2 "<>\n<>" 2 "<>\n<>"]
+test regexp-24.3 {regsub -all and -line} {
+    foreach {v1 v2 v3} {{} {} {}} {}
+    set string "\n\n"
+    list \
+	[regsub -line -all {^} $string {<&>} v1] $v1 \
+	[regsub -line -all {^$} $string {<&>} v2] $v2 \
+	[regsub -line -all {$} $string {<&>} v3] $v3
+} [list 3 "<>\n<>\n<>" 3 "<>\n<>\n<>" 3 "<>\n<>\n<>"]
+test regexp-24.4 {regsub -all and -line} {
+    foreach {v1 v2 v3} {{} {} {}} {}
+    set string "a"
+    list \
+	[regsub -line -all {^} $string {<&>} v1] $v1 \
+	[regsub -line -all {^.*$} $string {<&>} v2] $v2 \
+	[regsub -line -all {$} $string {<&>} v3] $v3
+} [list 1 "<>a" 1 "<a>" 1 "a<>"]
+test regexp-24.5 {regsub -all and -line} {
+    foreach {v1 v2 v3} {{} {} {}} {}
+    set string "a\n"
+    list \
+	[regsub -line -all {^} $string {<&>} v1] $v1 \
+	[regsub -line -all {^.*$} $string {<&>} v2] $v2 \
+	[regsub -line -all {$} $string {<&>} v3] $v3
+} [list 2 "<>a\n<>" 2 "<a>\n<>" 2 "a<>\n<>"]
+test regexp-24.6 {regsub -all and -line} {
+    foreach {v1 v2 v3} {{} {} {}} {}
+    set string "\na"
+    list \
+	[regsub -line -all {^} $string {<&>} v1] $v1 \
+	[regsub -line -all {^.*$} $string {<&>} v2] $v2 \
+	[regsub -line -all {$} $string {<&>} v3] $v3
+} [list 2 "<>\n<>a" 2 "<>\n<a>" 2 "<>\na<>"]
+test regexp-24.7 {regsub -all and -line} {
+    foreach {v1 v2 v3} {{} {} {}} {}
+    set string "ab\n"
+    list \
+	[regsub -line -all {^} $string {<&>} v1] $v1 \
+	[regsub -line -all {^.*$} $string {<&>} v2] $v2 \
+	[regsub -line -all {$} $string {<&>} v3] $v3
+} [list 2 "<>ab\n<>" 2 "<ab>\n<>" 2 "ab<>\n<>"]
+test regexp-24.8 {regsub -all and -line} {
+    foreach {v1 v2 v3} {{} {} {}} {}
+    set string "a\nb"
+    list \
+	[regsub -line -all {^} $string {<&>} v1] $v1 \
+	[regsub -line -all {^.*$} $string {<&>} v2] $v2 \
+	[regsub -line -all {$} $string {<&>} v3] $v3
+} [list 2 "<>a\n<>b" 2 "<a>\n<b>" 2 "a<>\nb<>"]
+test regexp-24.9 {regsub -all and -line} {
+    foreach {v1 v2 v3} {{} {} {}} {}
+    set string "a\nb\n"
+    list \
+	[regsub -line -all {^} $string {<&>} v1] $v1 \
+	[regsub -line -all {^.*$} $string {<&>} v2] $v2 \
+	[regsub -line -all {$} $string {<&>} v3] $v3
+} [list 3 "<>a\n<>b\n<>" 3 "<a>\n<b>\n<>" 3 "a<>\nb<>\n<>"]
+test regexp-24.10 {regsub -all and -line} {
+    foreach {v1 v2 v3} {{} {} {}} {}
+    set string "a\nb\nc"
+    list \
+	[regsub -line -all {^} $string {<&>} v1] $v1 \
+	[regsub -line -all {^.*$} $string {<&>} v2] $v2 \
+	[regsub -line -all {$} $string {<&>} v3] $v3
+} [list 3 "<>a\n<>b\n<>c" 3 "<a>\n<b>\n<c>" 3 "a<>\nb<>\nc<>"]
+test regexp-24.11 {regsub -all and -line} {
+    regsub -line -all {b} "abb\nb" {<&>}
+} "a<b><b>\n<b>"
+
+test regexp-25.1 {regexp without -line option} {
+    set foo ""
+    list [regexp {a.*b} "dabc\naxyb\n" foo] $foo
+} [list 1 abc\naxyb]
+test regexp-25.2 {regexp without -line option} {
+    set foo ""
+    list [regexp {^a.*b$} "dabc\naxyb\n" foo] $foo
+} {0 {}}
+test regexp-25.3 {regexp with -line option} {
+    set foo ""
+    list [regexp -line {^a.*b$} "dabc\naxyb\n" foo] $foo
+} {1 axyb}
+test regexp-25.4 {regexp with -line option} {
+    set foo ""
+    list [regexp -line {^a.*b$} "dabc\naxyb\nxb" foo] $foo
+} {1 axyb}
+test regexp-25.5 {regexp without -line option} {
+    set foo ""
+    list [regexp {^a.*b$} "dabc\naxyb\nxb" foo] $foo
+} {0 {}}
+test regexp-25.6 {regexp without -line option} {
+    set foo ""
+    list [regexp {a.*b$} "dabc\naxyb\nxb" foo] $foo
+} "1 {abc\naxyb\nxb}"
+test regexp-25.7 {regexp with -lineanchor option} {
+    set foo ""
+    list [regexp -lineanchor {^a.*b$} "dabc\naxyb\nxb" foo] $foo
+} "1 {axyb\nxb}"
+test regexp-25.8 {regexp with -lineanchor and -linestop option} {
+    set foo ""
+    list [regexp -lineanchor -linestop {^a.*b$} "dabc\naxyb\nxb" foo] $foo
+} {1 axyb}
+test regexp-25.9 {regexp with -linestop option} {
+    set foo ""
+    list [regexp -linestop {a.*b} "ab\naxyb\nxb" foo] $foo
+} {1 ab}
+
+test regexp-26.1 {matches start of line 1 time} {
+    regexp -all -inline -- {^a+} "aab\naaa"
+} {aa}
+test regexp-26.2 {matches start of line(s) 2 times} {
+    regexp -all -inline -line -- {^a+} "aab\naaa"
+} {aa aaa}
+test regexp-26.3 {effect of -line -all and -start} {
+    list \
+	[regexp -all -inline -line -start 0 -- {^a+} "aab\naaa"] \
+	[regexp -all -inline -line -start 1 -- {^a+} "aab\naaa"] \
+	[regexp -all -inline -line -start 3 -- {^a+} "aab\naaa"] \
+	[regexp -all -inline -line -start 4 -- {^a+} "aab\naaa"] \
+} {{aa aaa} aaa aaa aaa}
+# No regexp-26.4
+test regexp-26.5 {match length 0, match length 1} {
+    regexp -all -inline -line -- {^b*} "a\nb"
+} {{} b}
+test regexp-26.6 {non reporting capture group} {
+    regexp -all -inline -line -- {^(?:a+|b)} "aab\naaa"
+} {aa aaa}
+test regexp-26.7 {Tcl bug 2826551: -line sensitive regexp and -start} {
+    set match1 {}
+    set match2 {}
+    list \
+	[regexp -start 0 -indices -line {^a} "\nab" match1] $match1 \
+	[regexp -start 1 -indices -line {^a} "\nab" match2] $match2
+} {1 {1 1} 1 {1 1}}
+test regexp-26.8 {Tcl bug 2826551: diff regexp with -line option} {
+    set data "@1\n2\n+3\n@4\n-5\n+6\n7\n@8\n9\n"
+    regexp -all -inline -line {^@.*\n(?:[^@].*\n?)*} $data
+} [list "@1\n2\n+3\n" "@4\n-5\n+6\n7\n" "@8\n9\n"]
+test regexp-26.9 {Tcl bug 2826551: diff regexp with embedded -line option} {
+    set data "@1\n2\n+3\n@4\n-5\n+6\n7\n@8\n9\n"
+    regexp -all -inline {(?n)^@.*\n(?:[^@].*\n?)*} $data
+} [list "@1\n2\n+3\n" "@4\n-5\n+6\n7\n" "@8\n9\n"]
+test regexp-26.10 {regexp with -line option} {
+    regexp -all -inline -line -- {a*} "a\n"
+} {a {}}
+test regexp-26.11 {regexp without -line option} {
+    regexp -all -inline -- {a*} "a\n"
+} {a {}}
+test regexp-26.12 {regexp with -line option} {
+    regexp -all -inline -line -- {a*} "b\n"
+} {{} {}}
+test regexp-26.13 {regexp without -line option} {
+    regexp -all -inline -- {a*} "b\n"
+} {{} {}}
+
+# cleanup
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/tests/regexpComp.test b/tests/regexpComp.test
new file mode 100644
index 0000000..01ef06d
--- /dev/null
+++ b/tests/regexpComp.test
@@ -0,0 +1,997 @@
+# Commands covered:  regexp, regsub
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands.  Sourcing this file into Tcl runs the tests and
+# generates output for errors.  No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1998 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+    package require tcltest 2
+    namespace import -force ::tcltest::*
+}
+
+# Procedure to evaluate a script within a proc, to test compilation
+# functionality
+
+proc evalInProc { script } {
+    proc testProc {} $script
+    set status [catch {
+	testProc 
+    } result]
+    rename testProc {}
+    return $result
+    #return [list $status $result]
+}
+
+unset -nocomplain foo
+
+test regexpComp-1.1 {basic regexp operation} {
+    evalInProc {
+	regexp ab*c abbbc
+    }
+} 1
+test regexpComp-1.2 {basic regexp operation} {
+    evalInProc {
+	regexp ab*c ac
+    }
+} 1
+test regexpComp-1.3 {basic regexp operation} {
+    evalInProc {
+	regexp ab*c ab
+    }
+} 0
+test regexpComp-1.4 {basic regexp operation} {
+    evalInProc {
+	regexp -- -gorp abc-gorpxxx
+    }
+} 1
+test regexpComp-1.5 {basic regexp operation} {
+    evalInProc {
+	regexp {^([^ ]*)[ ]*([^ ]*)} "" a
+    }
+} 1
+test regexpComp-1.6 {basic regexp operation} {
+    list [catch {regexp {} abc} msg] $msg
+} {0 1}
+test regexpComp-1.7 {regexp utf compliance} {
+    # if not UTF-8 aware, result is "0 1"
+    evalInProc {
+	set foo "\u4e4eb q"
+	regexp "\u4e4eb q" "a\u4e4eb qw\u5e4e\x4e wq" bar
+	list [string compare $foo $bar] [regexp 4 $bar]
+    }
+} {0 0}
+
+test regexpComp-1.8 {regexp ***= metasyntax} {
+    evalInProc {
+	regexp -- "***=o" "aeiou"
+    }
+} 1
+test regexpComp-1.9 {regexp ***= metasyntax} {
+    evalInProc {
+	set string "aeiou"
+	regexp -- "***=o" $string
+    }
+} 1
+test regexpComp-1.10 {regexp ***= metasyntax} {
+    evalInProc {
+	set string "aeiou"
+	set re "***=o"
+	regexp -- $re $string
+    }
+} 1
+test regexpComp-1.11 {regexp ***= metasyntax} {
+    evalInProc {
+	regexp -- "***=y" "aeiou"
+    }
+} 0
+test regexpComp-1.12 {regexp ***= metasyntax} {
+    evalInProc {
+	set string "aeiou"
+	regexp -- "***=y" $string
+    }
+} 0
+test regexpComp-1.13 {regexp ***= metasyntax} {
+    evalInProc {
+	set string "aeiou"
+	set re "***=y"
+	regexp -- $re $string
+    }
+} 0
+test regexpComp-1.14 {regexp ***= metasyntax} {
+    evalInProc {
+	set string "aeiou"
+	set re "***=e*o"
+	regexp -- $re $string
+    }
+} 0
+test regexpComp-1.15 {regexp ***= metasyntax} {
+    evalInProc {
+	set string "ae*ou"
+	set re "***=e*o"
+	regexp -- $re $string
+    }
+} 1
+test regexpComp-1.16 {regexp ***= metasyntax} {
+    evalInProc {
+	set string {ae*[o]?ua}
+	set re {***=e*[o]?u}
+	regexp -- $re $string
+    }
+} 1
+
+test regexpComp-2.1 {getting substrings back from regexp} {
+    evalInProc {
+	set foo {}
+	list [regexp ab*c abbbbc foo] $foo
+    }
+} {1 abbbbc}
+test regexpComp-2.2 {getting substrings back from regexp} {
+    evalInProc {
+	set foo {}
+	set f2 {}
+	list [regexp a(b*)c abbbbc foo f2] $foo $f2
+    }
+} {1 abbbbc bbbb}
+test regexpComp-2.3 {getting substrings back from regexp} {
+    evalInProc {
+	set foo {}
+	set f2 {}
+	list [regexp a(b*)(c) abbbbc foo f2] $foo $f2
+    }
+} {1 abbbbc bbbb}
+test regexpComp-2.4 {getting substrings back from regexp} {
+    evalInProc {
+	set foo {}
+	set f2 {}
+	set f3 {}
+	list [regexp a(b*)(c) abbbbc foo f2 f3] $foo $f2 $f3
+    }
+} {1 abbbbc bbbb c}
+test regexpComp-2.5 {getting substrings back from regexp} {
+    evalInProc {
+	set foo {}; set f1 {}; set f2 {}; set f3 {}; set f4 {}; set f5 {};
+	set f6 {}; set f7 {}; set f8 {}; set f9 {}; set fa {}; set fb {};
+	list [regexp (1*)(2*)(3*)(4*)(5*)(6*)(7*)(8*)(9*)(a*)(b*) \
+		12223345556789999aabbb \
+		foo f1 f2 f3 f4 f5 f6 f7 f8 f9 fa fb] $foo $f1 $f2 $f3 $f4 $f5 \
+		$f6 $f7 $f8 $f9 $fa $fb
+    }
+} {1 12223345556789999aabbb 1 222 33 4 555 6 7 8 9999 aa bbb}
+test regexpComp-2.6 {getting substrings back from regexp} {
+    evalInProc {
+	set foo 2; set f2 2; set f3 2; set f4 2
+	list [regexp (a)(b)? xay foo f2 f3 f4] $foo $f2 $f3 $f4
+    }
+} {1 a a {} {}}
+test regexpComp-2.7 {getting substrings back from regexp} {
+    evalInProc {
+	set foo 1; set f2 1; set f3 1; set f4 1
+	list [regexp (a)(b)?(c) xacy foo f2 f3 f4] $foo $f2 $f3 $f4
+    }
+} {1 ac a {} c}
+test regexpComp-2.8 {getting substrings back from regexp} {
+    evalInProc {
+	set match {}
+	list [regexp {^a*b} aaaab match] $match
+    }
+} {1 aaaab}
+
+test regexpComp-3.1 {-indices option to regexp} {
+    evalInProc {
+	set foo {}
+	list [regexp -indices ab*c abbbbc foo] $foo
+    }
+} {1 {0 5}}
+test regexpComp-3.2 {-indices option to regexp} {
+    evalInProc {
+	set foo {}
+	set f2 {}
+	list [regexp -indices a(b*)c abbbbc foo f2] $foo $f2
+    }
+} {1 {0 5} {1 4}}
+test regexpComp-3.3 {-indices option to regexp} {
+    evalInProc {
+	set foo {}
+	set f2 {}
+	list [regexp -indices a(b*)(c) abbbbc foo f2] $foo $f2
+    }
+} {1 {0 5} {1 4}}
+test regexpComp-3.4 {-indices option to regexp} {
+    evalInProc {
+	set foo {}
+	set f2 {}
+	set f3 {}
+	list [regexp -indices a(b*)(c) abbbbc foo f2 f3] $foo $f2 $f3
+    }
+} {1 {0 5} {1 4} {5 5}}
+test regexpComp-3.5 {-indices option to regexp} {
+    evalInProc {
+	set foo {}; set f1 {}; set f2 {}; set f3 {}; set f4 {}; set f5 {};
+	set f6 {}; set f7 {}; set f8 {}; set f9 {}
+	list [regexp -indices (1*)(2*)(3*)(4*)(5*)(6*)(7*)(8*)(9*) \
+		12223345556789999 \
+		foo f1 f2 f3 f4 f5 f6 f7 f8 f9] $foo $f1 $f2 $f3 $f4 $f5 \
+		$f6 $f7 $f8 $f9
+    }
+} {1 {0 16} {0 0} {1 3} {4 5} {6 6} {7 9} {10 10} {11 11} {12 12} {13 16}}
+test regexpComp-3.6 {getting substrings back from regexp} {
+    evalInProc {
+	set foo 2; set f2 2; set f3 2; set f4 2
+	list [regexp -indices (a)(b)? xay foo f2 f3 f4] $foo $f2 $f3 $f4
+    }
+} {1 {1 1} {1 1} {-1 -1} {-1 -1}}
+test regexpComp-3.7 {getting substrings back from regexp} {
+    evalInProc {
+	set foo 1; set f2 1; set f3 1; set f4 1
+	list [regexp -indices (a)(b)?(c) xacy foo f2 f3 f4] $foo $f2 $f3 $f4
+    }
+} {1 {1 2} {1 1} {-1 -1} {2 2}}
+
+test regexpComp-4.1 {-nocase option to regexp} {
+    evalInProc {
+	regexp -nocase foo abcFOo
+    }
+} 1
+test regexpComp-4.2 {-nocase option to regexp} {
+    evalInProc {
+	set f1 22
+	set f2 33
+	set f3 44
+	list [regexp -nocase {a(b*)([xy]*)z} aBbbxYXxxZ22 f1 f2 f3] $f1 $f2 $f3
+    }
+} {1 aBbbxYXxxZ Bbb xYXxx}
+test regexpComp-4.3 {-nocase option to regexp} {
+    evalInProc {
+	regexp -nocase FOo abcFOo
+    }
+} 1
+set ::x abcdefghijklmnopqrstuvwxyz1234567890
+set ::x $x$x$x$x$x$x$x$x$x$x$x$x
+test regexpComp-4.4 {case conversion in regexp} {
+    evalInProc {
+	list [regexp -nocase $::x $::x foo] $foo
+    }
+} "1 $x"
+unset -nocomplain ::x
+
+test regexpComp-5.1 {exercise cache of compiled expressions} {
+    evalInProc {
+	regexp .*a b
+	regexp .*b c
+	regexp .*c d
+	regexp .*d e
+	regexp .*e f
+	regexp .*a bbba
+    }
+} 1
+test regexpComp-5.2 {exercise cache of compiled expressions} {
+    evalInProc {
+	regexp .*a b
+	regexp .*b c
+	regexp .*c d
+	regexp .*d e
+	regexp .*e f
+	regexp .*b xxxb
+    }
+} 1
+test regexpComp-5.3 {exercise cache of compiled expressions} {
+    evalInProc {
+	regexp .*a b
+	regexp .*b c
+	regexp .*c d
+	regexp .*d e
+	regexp .*e f
+	regexp .*c yyyc
+    }
+} 1
+test regexpComp-5.4 {exercise cache of compiled expressions} {
+    evalInProc {
+	regexp .*a b
+	regexp .*b c
+	regexp .*c d
+	regexp .*d e
+	regexp .*e f
+	regexp .*d 1d
+    }
+} 1
+test regexpComp-5.5 {exercise cache of compiled expressions} {
+    evalInProc {
+	regexp .*a b
+	regexp .*b c
+	regexp .*c d
+	regexp .*d e
+	regexp .*e f
+	regexp .*e xe
+    }
+} 1
+
+test regexpComp-6.1 {regexp errors} {
+    evalInProc {
+	list [catch {regexp a} msg] $msg
+    }
+} {1 {wrong # args: should be "regexp ?-option ...? exp string ?matchVar? ?subMatchVar ...?"}}
+test regexpComp-6.2 {regexp errors} {
+    evalInProc {
+	list [catch {regexp -nocase a} msg] $msg
+    }
+} {1 {wrong # args: should be "regexp ?-option ...? exp string ?matchVar? ?subMatchVar ...?"}}
+test regexpComp-6.3 {regexp errors} {
+    evalInProc {
+	list [catch {regexp -gorp a} msg] $msg
+    }
+} {1 {bad option "-gorp": must be -all, -about, -indices, -inline, -expanded, -line, -linestop, -lineanchor, -nocase, -start, or --}}
+test regexpComp-6.4 {regexp errors} {
+    evalInProc {
+	list [catch {regexp a( b} msg] $msg
+    }
+} {1 {couldn't compile regular expression pattern: parentheses () not balanced}}
+test regexpComp-6.5 {regexp errors} {
+    evalInProc {
+	list [catch {regexp a( b} msg] $msg
+    }
+} {1 {couldn't compile regular expression pattern: parentheses () not balanced}}
+test regexpComp-6.6 {regexp errors} {
+    evalInProc {
+	list [catch {regexp a a f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1} msg] $msg
+    }
+} {0 1}
+test regexpComp-6.7 {regexp errors} {
+    evalInProc {
+	list [catch {regexp (x)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.) xyzzy} msg] $msg
+    }
+} {0 0}
+test regexpComp-6.8 {regexp errors} {
+    evalInProc {
+	unset -nocomplain f1
+	set f1 44
+	list [catch {regexp abc abc f1(f2)} msg] $msg
+    }
+} {1 {can't set "f1(f2)": variable isn't array}}
+test regexpComp-6.9 {regexp errors, -start bad int check} {
+    evalInProc {
+	list [catch {regexp -start bogus {^$} {}} msg] $msg
+    }
+} {1 {bad index "bogus": must be integer?[+-]integer? or end?[+-]integer?}}
+
+test regexpComp-7.1 {basic regsub operation} {
+    evalInProc {
+	list [regsub aa+ xaxaaaxaa 111&222 foo] $foo
+    }
+} {1 xax111aaa222xaa}
+test regexpComp-7.2 {basic regsub operation} {
+    evalInProc {
+	list [regsub aa+ aaaxaa &111 foo] $foo
+    }
+} {1 aaa111xaa}
+test regexpComp-7.3 {basic regsub operation} {
+    evalInProc {
+	list [regsub aa+ xaxaaa 111& foo] $foo
+    }
+} {1 xax111aaa}
+test regexpComp-7.4 {basic regsub operation} {
+    evalInProc {
+	list [regsub aa+ aaa 11&2&333 foo] $foo
+    }
+} {1 11aaa2aaa333}
+test regexpComp-7.5 {basic regsub operation} {
+    evalInProc {
+	list [regsub aa+ xaxaaaxaa &2&333 foo] $foo
+    }
+} {1 xaxaaa2aaa333xaa}
+test regexpComp-7.6 {basic regsub operation} {
+    evalInProc {
+	list [regsub aa+ xaxaaaxaa 1&22& foo] $foo
+    }
+} {1 xax1aaa22aaaxaa}
+test regexpComp-7.7 {basic regsub operation} {
+    evalInProc {
+	list [regsub a(a+) xaxaaaxaa {1\122\1} foo] $foo
+    }
+} {1 xax1aa22aaxaa}
+test regexpComp-7.8 {basic regsub operation} {
+    evalInProc {
+	list [regsub a(a+) xaxaaaxaa {1\\\122\1} foo] $foo
+    }
+} "1 {xax1\\aa22aaxaa}"
+test regexpComp-7.9 {basic regsub operation} {
+    evalInProc {
+	list [regsub a(a+) xaxaaaxaa {1\\122\1} foo] $foo
+    }
+} "1 {xax1\\122aaxaa}"
+test regexpComp-7.10 {basic regsub operation} {
+    evalInProc {
+	list [regsub a(a+) xaxaaaxaa {1\\&\1} foo] $foo
+    }
+} "1 {xax1\\aaaaaxaa}"
+test regexpComp-7.11 {basic regsub operation} {
+    evalInProc {
+	list [regsub a(a+) xaxaaaxaa {1\&\1} foo] $foo
+    }
+} {1 xax1&aaxaa}
+test regexpComp-7.12 {basic regsub operation} {
+    evalInProc {
+	list [regsub a(a+) xaxaaaxaa {\1\1\1\1&&} foo] $foo
+    }
+} {1 xaxaaaaaaaaaaaaaaxaa}
+test regexpComp-7.13 {basic regsub operation} {
+    evalInProc {
+	set foo xxx
+	list [regsub abc xyz 111 foo] $foo
+    }
+} {0 xyz}
+test regexpComp-7.14 {basic regsub operation} {
+    evalInProc {
+	set foo xxx
+	list [regsub ^ xyz "111 " foo] $foo
+    }
+} {1 {111 xyz}}
+test regexpComp-7.15 {basic regsub operation} {
+    evalInProc {
+	set foo xxx
+	list [regsub -- -foo abc-foodef "111 " foo] $foo
+    }
+} {1 {abc111 def}}
+test regexpComp-7.16 {basic regsub operation} {
+    evalInProc {
+	set foo xxx
+	list [regsub x "" y foo] $foo
+    }
+} {0 {}}
+test regexpComp-7.17 {regsub utf compliance} {
+    evalInProc {
+	# if not UTF-8 aware, result is "0 1"
+	set foo "xyz555ijka\u4e4ebpqr"
+	regsub a\u4e4eb xyza\u4e4ebijka\u4e4ebpqr 555 bar
+	list [string compare $foo $bar] [regexp 4 $bar]
+    }
+} {0 0}
+
+test regexpComp-8.1 {case conversion in regsub} {
+    evalInProc {
+	list [regsub -nocase a(a+) xaAAaAAay & foo] $foo
+    }
+} {1 xaAAaAAay}
+test regexpComp-8.2 {case conversion in regsub} {
+    evalInProc {
+	list [regsub -nocase a(a+) xaAAaAAay & foo] $foo
+    }
+} {1 xaAAaAAay}
+test regexpComp-8.3 {case conversion in regsub} {
+    evalInProc {
+	set foo 123
+	list [regsub a(a+) xaAAaAAay & foo] $foo
+    }
+} {0 xaAAaAAay}
+test regexpComp-8.4 {case conversion in regsub} {
+    evalInProc {
+	set foo 123
+	list [regsub -nocase a CaDE b foo] $foo
+    }
+} {1 CbDE}
+test regexpComp-8.5 {case conversion in regsub} {
+    evalInProc {
+	set foo 123
+	list [regsub -nocase XYZ CxYzD b foo] $foo
+    }
+} {1 CbD}
+test regexpComp-8.6 {case conversion in regsub} {
+    evalInProc {
+	set x abcdefghijklmnopqrstuvwxyz1234567890
+	set x $x$x$x$x$x$x$x$x$x$x$x$x
+	set foo 123
+	list [regsub -nocase $x $x b foo] $foo
+    }
+} {1 b}
+
+test regexpComp-9.1 {-all option to regsub} {
+    evalInProc {
+	set foo 86
+	list [regsub -all x+ axxxbxxcxdx |&| foo] $foo
+    }
+} {4 a|xxx|b|xx|c|x|d|x|}
+test regexpComp-9.2 {-all option to regsub} {
+    evalInProc {
+	set foo 86
+	list [regsub -nocase -all x+ aXxXbxxcXdx |&| foo] $foo
+    }
+} {4 a|XxX|b|xx|c|X|d|x|}
+test regexpComp-9.3 {-all option to regsub} {
+    evalInProc {
+	set foo 86
+	list [regsub x+ axxxbxxcxdx |&| foo] $foo
+    }
+} {1 a|xxx|bxxcxdx}
+test regexpComp-9.4 {-all option to regsub} {
+    evalInProc {
+	set foo 86
+	list [regsub -all bc axxxbxxcxdx |&| foo] $foo
+    }
+} {0 axxxbxxcxdx}
+test regexpComp-9.5 {-all option to regsub} {
+    evalInProc {
+	set foo xxx
+	list [regsub -all node "node node more" yy foo] $foo
+    }
+} {2 {yy yy more}}
+test regexpComp-9.6 {-all option to regsub} {
+    evalInProc {
+	set foo xxx
+	list [regsub -all ^ xxx 123 foo] $foo
+    }
+} {1 123xxx}
+test regexpComp-9.7 {Bug 84af1192f5: -all option to regsub} {
+    evalInProc {
+	regsub -all {\(.*} 123(qwe) ""
+    }
+} 123
+
+test regexpComp-10.1 {expanded syntax in regsub} {
+    evalInProc {
+	set foo xxx
+	list [regsub -expanded ". \#comment\n  . \#comment2" abc def foo] $foo
+    }
+} {1 defc}
+test regexpComp-10.2 {newline sensitivity in regsub} {
+    evalInProc {
+	set foo xxx
+	list [regsub -line {^a.*b$} "dabc\naxyb\n" 123 foo] $foo
+    }
+} "1 {dabc\n123\n}"
+test regexpComp-10.3 {newline sensitivity in regsub} {
+    evalInProc {
+	set foo xxx
+	list [regsub -line {^a.*b$} "dabc\naxyb\nxb" 123 foo] $foo
+    }
+} "1 {dabc\n123\nxb}"
+test regexpComp-10.4 {partial newline sensitivity in regsub} {
+    evalInProc {
+	set foo xxx
+	list [regsub -lineanchor {^a.*b$} "da\naxyb\nxb" 123 foo] $foo
+    }
+} "1 {da\n123}"
+test regexpComp-10.5 {inverse partial newline sensitivity in regsub} {
+    evalInProc {
+	set foo xxx
+	list [regsub -linestop {a.*b} "da\nbaxyb\nxb" 123 foo] $foo
+    }
+} "1 {da\nb123\nxb}"
+
+test regexpComp-11.1 {regsub errors} {
+    evalInProc {
+	list [catch {regsub a b} msg] $msg
+    }
+} {1 {wrong # args: should be "regsub ?-option ...? exp string subSpec ?varName?"}}
+test regexpComp-11.2 {regsub errors} {
+    evalInProc {
+	list [catch {regsub -nocase a b} msg] $msg
+    }
+} {1 {wrong # args: should be "regsub ?-option ...? exp string subSpec ?varName?"}}
+test regexpComp-11.3 {regsub errors} {
+    evalInProc {
+	list [catch {regsub -nocase -all a b} msg] $msg
+    }
+} {1 {wrong # args: should be "regsub ?-option ...? exp string subSpec ?varName?"}}
+test regexpComp-11.4 {regsub errors} {
+    evalInProc {
+	list [catch {regsub a b c d e f} msg] $msg
+    }
+} {1 {wrong # args: should be "regsub ?-option ...? exp string subSpec ?varName?"}}
+test regexpComp-11.5 {regsub errors} {
+    evalInProc {
+	list [catch {regsub -gorp a b c} msg] $msg
+    }
+} {1 {bad option "-gorp": must be -all, -nocase, -expanded, -line, -linestop, -lineanchor, -start, or --}}
+test regexpComp-11.6 {regsub errors} {
+    evalInProc {
+	list [catch {regsub -nocase a( b c d} msg] $msg
+    }
+} {1 {couldn't compile regular expression pattern: parentheses () not balanced}}
+test regexpComp-11.7 {regsub errors} {
+    evalInProc {
+	unset -nocomplain f1
+	set f1 44
+	list [catch {regsub -nocase aaa aaa xxx f1(f2)} msg] $msg
+    }
+} {1 {can't set "f1(f2)": variable isn't array}}
+test regexpComp-11.8 {regsub errors, -start bad int check} {
+    evalInProc {
+	list [catch {regsub -start bogus pattern string rep var} msg] $msg
+    }
+} {1 {bad index "bogus": must be integer?[+-]integer? or end?[+-]integer?}}
+
+# This test crashes on the Mac unless you increase the Stack Space to about 1
+# Meg.  This is probably bigger than most users want... 
+# 8.2.3 regexp reduced stack space requirements, but this should be
+# tested again
+test regexpComp-12.1 {Tcl_RegExpExec: large number of subexpressions} {macCrash} {
+    evalInProc {
+	list [regexp (.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.)(.) abcdefghijklmnopqrstuvwxyz all a b c d e f g h i j k l m n o p q r s t u v w x y z] $all $a $b $c $d $e $f $g $h $i $j $k $l $m $n $o $p $q $r $s $t $u $v $w $x $y $z
+    }
+} {1 abcdefghijklmnopqrstuvwxyz a b c d e f g h i j k l m n o p q r s t u v w x y z}
+
+test regexpComp-13.1 {regsub of a very large string} {
+    # This test is designed to stress the memory subsystem in order
+    # to catch Bug #933.  It only fails if the Tcl memory allocator
+    # is in use.
+
+    set line {BEGIN_TABLE ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; END_TABLE}
+    set filedata [string repeat $line 200]
+    for {set i 1} {$i<10} {incr i} {
+	regsub -all "BEGIN_TABLE " $filedata "" newfiledata
+    }
+    set x done
+} {done}
+
+test regexpComp-14.1 {CompileRegexp: regexp cache} {
+    evalInProc {
+	regexp .*a b
+	regexp .*b c
+	regexp .*c d
+	regexp .*d e
+	regexp .*e f
+	set x .
+	append x *a
+	regexp $x bbba
+    }
+} 1
+test regexpComp-14.2 {CompileRegexp: regexp cache, different flags} {
+    evalInProc {
+	regexp .*a b
+	regexp .*b c
+	regexp .*c d
+	regexp .*d e
+	regexp .*e f
+	set x .
+	append x *a
+	regexp -nocase $x bbba
+    }
+} 1
+
+testConstraint exec [llength [info commands exec]]
+test regexpComp-14.3 {CompileRegexp: regexp cache, empty regexp and empty cache} -constraints {
+	exec
+} -setup {
+    set junk [makeFile {puts [regexp {} foo]} junk.tcl]
+} -body {
+    exec [interpreter] $junk
+} -cleanup {
+    removeFile junk.tcl
+} -result 1
+
+test regexpComp-15.1 {regexp -start} {
+    unset -nocomplain x
+    list [regexp -start -10 {\d} 1abc2de3 x] $x
+} {1 1}
+test regexpComp-15.2 {regexp -start} {
+    unset -nocomplain x
+    list [regexp -start 2 {\d} 1abc2de3 x] $x
+} {1 2}
+test regexpComp-15.3 {regexp -start} {
+    unset -nocomplain x
+    list [regexp -start 4 {\d} 1abc2de3 x] $x
+} {1 2}
+test regexpComp-15.4 {regexp -start} {
+    unset -nocomplain x
+    list [regexp -start 5 {\d} 1abc2de3 x] $x
+} {1 3}
+test regexpComp-15.5 {regexp -start, over end of string} {
+    unset -nocomplain x
+    list [regexp -start [string length 1abc2de3] {\d} 1abc2de3 x] [info exists x]
+} {0 0}
+test regexpComp-15.6 {regexp -start, loss of ^$ behavior} {
+    list [regexp -start 2 {^$} {}]
+} {0}
+
+test regexpComp-16.1 {regsub -start} {
+    unset -nocomplain x
+    list [regsub -all -start 2 {\d} a1b2c3d4e5 {/&} x] $x
+} {4 a1b/2c/3d/4e/5}
+test regexpComp-16.2 {regsub -start} {
+    unset -nocomplain x
+    list [regsub -all -start -25 {z} hello {/&} x] $x
+} {0 hello}
+test regexpComp-16.3 {regsub -start} {
+    unset -nocomplain x
+    list [regsub -all -start 3 {z} hello {/&} x] $x
+} {0 hello}
+test regexpComp-16.4 {regsub -start, \A behavior} {
+    set out {}
+    lappend out [regsub -start 0 -all {\A(\w)} {abcde} {/\1} x] $x
+    lappend out [regsub -start 2 -all {\A(\w)} {abcde} {/\1} x] $x
+} {5 /a/b/c/d/e 3 ab/c/d/e}
+
+test regexpComp-17.1 {regexp -inline} {
+    regexp -inline b ababa
+} {b}
+test regexpComp-17.2 {regexp -inline} {
+    regexp -inline (b) ababa
+} {b b}
+test regexpComp-17.3 {regexp -inline -indices} {
+    regexp -inline -indices (b) ababa
+} {{1 1} {1 1}}
+test regexpComp-17.4 {regexp -inline} {
+    regexp -inline {\w(\d+)\w} "   hello 23 there456def "
+} {e456d 456}
+test regexpComp-17.5 {regexp -inline no matches} {
+    regexp -inline {\w(\d+)\w} ""
+} {}
+test regexpComp-17.6 {regexp -inline no matches} {
+    regexp -inline hello goodbye
+} {}
+test regexpComp-17.7 {regexp -inline, no matchvars allowed} {
+    list [catch {regexp -inline b abc match} msg] $msg
+} {1 {regexp match variables not allowed when using -inline}}
+
+test regexpComp-18.1 {regexp -all} {
+    regexp -all b bbbbb
+} {5}
+test regexpComp-18.2 {regexp -all} {
+    regexp -all b abababbabaaaaaaaaaab
+} {6}
+test regexpComp-18.3 {regexp -all -inline} {
+    regexp -all -inline b abababbabaaaaaaaaaab
+} {b b b b b b}
+test regexpComp-18.4 {regexp -all -inline} {
+    regexp -all -inline {\w(\w)} abcdefg
+} {ab b cd d ef f}
+test regexpComp-18.5 {regexp -all -inline} {
+    regexp -all -inline {\w(\w)$} abcdefg
+} {fg g}
+test regexpComp-18.6 {regexp -all -inline} {
+    regexp -all -inline {\d+} 10:20:30:40
+} {10 20 30 40}
+test regexpComp-18.7 {regexp -all -inline} {
+    list [catch {regexp -all -inline b abc match} msg] $msg
+} {1 {regexp match variables not allowed when using -inline}}
+test regexpComp-18.8 {regexp -all} {
+    # This should not cause an infinite loop
+    regexp -all -inline {a*} a
+} {a}
+test regexpComp-18.9 {regexp -all} {
+    # Yes, the expected result is {a {}}.  Here's why:
+    # Start at index 0; a* matches the "a" there then stops.
+    # Go to index 1; a* matches the lambda (or {}) there then stops.  Recall
+    #   that a* matches zero or more "a"'s; thus it matches the string "b", as
+    #   there are zero or more "a"'s there.
+    # Go to index 2; this is past the end of the string, so stop.
+    regexp -all -inline {a*} ab
+} {a {}}
+test regexpComp-18.10 {regexp -all} {
+    # Yes, the expected result is {a {} a}.  Here's why:
+    # Start at index 0; a* matches the "a" there then stops.
+    # Go to index 1; a* matches the lambda (or {}) there then stops.   Recall
+    #   that a* matches zero or more "a"'s; thus it matches the string "b", as
+    #   there are zero or more "a"'s there.
+    # Go to index 2; a* matches the "a" there then stops.
+    # Go to index 3; this is past the end of the string, so stop.
+    regexp -all -inline {a*} aba
+} {a {} a}
+test regexpComp-18.11 {regexp -all} {
+    evalInProc {
+	regexp -all -inline {^a} aaaa
+    }
+} {a}
+test regexpComp-18.12 {regexp -all -inline -indices} {
+    evalInProc {
+	regexp -all -inline -indices a(b(c)d|e(f)g)h abcdhaefgh
+    }
+} {{0 4} {1 3} {2 2} {-1 -1} {5 9} {6 8} {-1 -1} {7 7}}
+
+test regexpComp-19.1 {regsub null replacement} {
+    evalInProc {
+	regsub -all {@} {@hel@lo@} "\0a\0" result
+	list $result [string length $result]
+    }
+} "\0a\0hel\0a\0lo\0a\0 14"
+
+test regexpComp-20.1 {regsub shared object shimmering} {
+    evalInProc {
+	# Bug #461322
+	set a abcdefghijklmnopqurstuvwxyz 
+	set b $a 
+	set c abcdefghijklmnopqurstuvwxyz0123456789 
+	regsub $a $c $b d 
+	list $d [string length $d] [string bytelength $d]
+    }
+} [list abcdefghijklmnopqurstuvwxyz0123456789 37 37]
+test regexpComp-20.2 {regsub shared object shimmering with -about} {
+    evalInProc {
+	eval regexp -about abc
+    }
+} {0 {}}
+
+test regexpComp-21.1 {regexp command compiling tests} {
+    evalInProc {
+	regexp foo bar
+    }
+} 0
+test regexpComp-21.2 {regexp command compiling tests} {
+    evalInProc {
+	regexp {^foo$} dogfood
+    }
+} 0
+test regexpComp-21.3 {regexp command compiling tests} {
+    evalInProc {
+	set a foo
+	regexp {^foo$} $a
+    }
+} 1
+test regexpComp-21.4 {regexp command compiling tests} {
+    evalInProc {
+	regexp foo dogfood
+    }
+} 1
+test regexpComp-21.5 {regexp command compiling tests} {
+    evalInProc {
+	regexp -nocase FOO dogfod
+    }
+} 0
+test regexpComp-21.6 {regexp command compiling tests} {
+    evalInProc {
+	regexp -n foo dogfoOd
+    }
+} 1
+test regexpComp-21.7 {regexp command compiling tests} {
+    evalInProc {
+	regexp -no -- FoO dogfood
+    }
+} 1
+test regexpComp-21.8 {regexp command compiling tests} {
+    evalInProc {
+	regexp -- foo dogfod
+    }
+} 0
+test regexpComp-21.9 {regexp command compiling tests} {
+    evalInProc {
+	list [catch {regexp -- -nocase foo dogfod} msg] $msg
+    }
+} {0 0}
+test regexpComp-21.10 {regexp command compiling tests} {
+    evalInProc {
+	list [regsub -all "" foo bar str] $str
+    }
+} {3 barfbarobaro}
+test regexpComp-21.11 {regexp command compiling tests} {
+    evalInProc {
+	list [regsub -all "" "" bar str] $str
+    }
+} {0 {}}
+
+test regexpComp-22.0.1 {Bug 1810038} {
+    evalInProc {
+	regexp ($|^X)* {}
+    }
+} 1
+
+test regexpComp-22.0.2 {regexp compile and backrefs, Bug 1857126} {
+    evalInProc {
+	regexp -- {([bc])\1} bb
+    }
+} 1
+
+set i 0
+foreach {str exp result} {
+    foo		^foo		1
+    foobar	^foobar$	1
+    foobar	bar$		1
+    foobar	^$		0
+    ""		^$		1
+    anything	$		1
+    anything	^.*$		1
+    anything	^.*a$		0
+    anything	^.*a.*$		1
+    anything	^.*.*$		1
+    anything	^.*..*$		1
+    anything	^.*b$		0
+    anything	^a.*$		1
+} {
+    test regexpComp-22.[incr i] {regexp command compiling tests} \
+	     [subst {evalInProc {set a "$str"; regexp {$exp} \$a}}] $result
+}
+
+set i 0
+foreach {str exp result} {
+    foo		^foo		1
+    foobar	^foobar$	1
+    foobar	bar$		1
+    foobar	^$		0
+    ""		^$		1
+    anything	$		1
+    anything	^.*$		1
+    anything	^.*a$		0
+    anything	^.*a.*$		1
+    anything	^.*.*$		1
+    anything	^.*..*$		1
+    anything	^.*b$		0
+    anything	^a.*$		1
+} {
+    test regexpComp-23.[incr i] {regexp command compiling tests INST_REGEXP} \
+	[subst {evalInProc {set a "$str"; set re "$exp"; regexp \$re \$a}}] $result
+}
+
+test regexpComp-24.1 {regexp command compiling tests} {
+    evalInProc {
+	set re foo
+	regexp -nocase $re bar
+    }
+} 0
+test regexpComp-24.2 {regexp command compiling tests} {
+    evalInProc {
+	set re {^foo$}
+	regexp $re dogfood
+    }
+} 0
+test regexpComp-24.3 {regexp command compiling tests} {
+    evalInProc {
+	set a foo
+	set re {^foo$}
+	regexp $re $a
+    }
+} 1
+test regexpComp-24.4 {regexp command compiling tests} {
+    evalInProc {
+	set re foo
+	regexp $re dogfood
+    }
+} 1
+test regexpComp-24.5 {regexp command compiling tests} {
+    evalInProc {
+	set re FOO
+	regexp -nocase $re dogfod
+    }
+} 0
+test regexpComp-24.6 {regexp command compiling tests} {
+    evalInProc {
+	set re foo
+	regexp -n $re dogfoOd
+    }
+} 1
+test regexpComp-24.7 {regexp command compiling tests} {
+    evalInProc {
+	set re FoO
+	regexp -no -- $re dogfood
+    }
+} 1
+test regexpComp-24.8 {regexp command compiling tests} {
+    evalInProc {
+	set re foo
+	regexp -- $re dogfod
+    }
+} 0
+test regexpComp-24.9 {regexp command compiling tests} {
+    evalInProc {
+	set re "("
+	list [catch {regexp -- $re dogfod} msg] $msg
+    }
+} {1 {couldn't compile regular expression pattern: parentheses () not balanced}}
+test regexpComp-24.10 {regexp command compiling tests} {
+    # Bug 1902436 - last * escaped
+    evalInProc {
+	set text {this is *bold* !}
+	set re {\*bold\*}
+	regexp -- $re $text
+    }
+} 1
+test regexpComp-24.11 {regexp command compiling tests} {
+    # Bug 1902436 - last * escaped
+    evalInProc {
+	set text {this is *bold* !}
+	set re {\*bold\*.*!}
+	regexp -- $re $text
+    }
+} 1
+
+# cleanup
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/tests/registry.test b/tests/registry.test
new file mode 100644
index 0000000..2072559
--- /dev/null
+++ b/tests/registry.test
@@ -0,0 +1,691 @@
+# registry.test --
+#
+# This file contains a collection of tests for the registry command.
+# Sourcing this file into Tcl runs the tests and generates output for
+# errors.  No output means no errors were found.
+#
+# In order for these tests to run, the registry package must be on the
+# auto_path or the registry package must have been loaded already.
+#
+# Copyright (c) 1997 by Sun Microsystems, Inc.  All rights reserved.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+    package require tcltest 2
+    namespace import -force ::tcltest::*
+}
+
+testConstraint reg 0
+if {[testConstraint win]} {
+    if {![catch {
+	    ::tcltest::loadTestedCommands
+	    set ::regver [package require registry 1.3.2]
+	}]} {
+	testConstraint reg 1
+    }
+}
+
+# determine the current locale
+testConstraint english [expr {
+    [llength [info commands testlocale]]
+    && [string match "English*" [testlocale all ""]]
+}]
+
+test registry-1.0 {check if we are testing the right dll} {win reg} {
+    set ::regver
+} {1.3.2}
+test registry-1.1 {argument parsing for registry command} {win reg} {
+    list [catch {registry} msg] $msg
+} {1 {wrong # args: should be "registry ?-32bit|-64bit? option ?arg ...?"}}
+test registry-1.1a {argument parsing for registry command} {win reg} {
+    list [catch {registry -32bit} msg] $msg
+} {1 {wrong # args: should be "registry ?-32bit|-64bit? option ?arg ...?"}}
+test registry-1.1b {argument parsing for registry command} {win reg} {
+    list [catch {registry -64bit} msg] $msg
+} {1 {wrong # args: should be "registry ?-32bit|-64bit? option ?arg ...?"}}
+test registry-1.2 {argument parsing for registry command} {win reg} {
+    list [catch {registry foo} msg] $msg
+} {1 {bad option "foo": must be broadcast, delete, get, keys, set, type, or values}}
+test registry-1.2a {argument parsing for registry command} {win reg} {
+    list [catch {registry -33bit foo} msg] $msg
+} {1 {bad mode "-33bit": must be -32bit or -64bit}}
+
+test registry-1.3 {argument parsing for registry command} {win reg} {
+    list [catch {registry d} msg] $msg
+} {1 {wrong # args: should be "registry delete keyName ?valueName?"}}
+test registry-1.3a {argument parsing for registry command} {win reg} {
+    list [catch {registry -32bit d} msg] $msg
+} {1 {wrong # args: should be "registry -32bit delete keyName ?valueName?"}}
+test registry-1.3b {argument parsing for registry command} {win reg} {
+    list [catch {registry -64bit d} msg] $msg
+} {1 {wrong # args: should be "registry -64bit delete keyName ?valueName?"}}
+test registry-1.4 {argument parsing for registry command} {win reg} {
+    list [catch {registry delete} msg] $msg
+} {1 {wrong # args: should be "registry delete keyName ?valueName?"}}
+test registry-1.5 {argument parsing for registry command} {win reg} {
+    list [catch {registry delete foo bar baz} msg] $msg
+} {1 {wrong # args: should be "registry delete keyName ?valueName?"}}
+
+test registry-1.6 {argument parsing for registry command} {win reg} {
+    list [catch {registry g} msg] $msg
+} {1 {wrong # args: should be "registry get keyName valueName"}}
+test registry-1.6a {argument parsing for registry command} {win reg} {
+    list [catch {registry -32bit g} msg] $msg
+} {1 {wrong # args: should be "registry -32bit get keyName valueName"}}
+test registry-1.6b {argument parsing for registry command} {win reg} {
+    list [catch {registry -64bit g} msg] $msg
+} {1 {wrong # args: should be "registry -64bit get keyName valueName"}}
+test registry-1.7 {argument parsing for registry command} {win reg} {
+    list [catch {registry get} msg] $msg
+} {1 {wrong # args: should be "registry get keyName valueName"}}
+test registry-1.8 {argument parsing for registry command} {win reg} {
+    list [catch {registry get foo} msg] $msg
+} {1 {wrong # args: should be "registry get keyName valueName"}}
+test registry-1.9 {argument parsing for registry command} {win reg} {
+    list [catch {registry get foo bar baz} msg] $msg
+} {1 {wrong # args: should be "registry get keyName valueName"}}
+
+test registry-1.10 {argument parsing for registry command} {win reg} {
+    list [catch {registry k} msg] $msg
+} {1 {wrong # args: should be "registry keys keyName ?pattern?"}}
+test registry-1.10a {argument parsing for registry command} {win reg} {
+    list [catch {registry -32bit k} msg] $msg
+} {1 {wrong # args: should be "registry -32bit keys keyName ?pattern?"}}
+test registry-1.10b {argument parsing for registry command} {win reg} {
+    list [catch {registry -64bit k} msg] $msg
+} {1 {wrong # args: should be "registry -64bit keys keyName ?pattern?"}}
+test registry-1.11 {argument parsing for registry command} {win reg} {
+    list [catch {registry keys} msg] $msg
+} {1 {wrong # args: should be "registry keys keyName ?pattern?"}}
+test registry-1.12 {argument parsing for registry command} {win reg} {
+    list [catch {registry keys foo bar baz} msg] $msg
+} {1 {wrong # args: should be "registry keys keyName ?pattern?"}}
+
+test registry-1.13 {argument parsing for registry command} {win reg} {
+    list [catch {registry s} msg] $msg
+} {1 {wrong # args: should be "registry set keyName ?valueName data ?type??"}}
+test registry-1.13a {argument parsing for registry command} {win reg} {
+    list [catch {registry -32bit s} msg] $msg
+} {1 {wrong # args: should be "registry -32bit set keyName ?valueName data ?type??"}}
+test registry-1.13b {argument parsing for registry command} {win reg} {
+    list [catch {registry -64bit s} msg] $msg
+} {1 {wrong # args: should be "registry -64bit set keyName ?valueName data ?type??"}}
+test registry-1.14 {argument parsing for registry command} {win reg} {
+    list [catch {registry set} msg] $msg
+} {1 {wrong # args: should be "registry set keyName ?valueName data ?type??"}}
+test registry-1.15 {argument parsing for registry command} {win reg} {
+    list [catch {registry set foo bar} msg] $msg
+} {1 {wrong # args: should be "registry set keyName ?valueName data ?type??"}}
+test registry-1.16 {argument parsing for registry command} {win reg} {
+    list [catch {registry set foo bar baz blat gorp} msg] $msg
+} {1 {wrong # args: should be "registry set keyName ?valueName data ?type??"}}
+
+test registry-1.17 {argument parsing for registry command} {win reg} {
+    list [catch {registry t} msg] $msg
+} {1 {wrong # args: should be "registry type keyName valueName"}}
+test registry-1.17a {argument parsing for registry command} {win reg} {
+    list [catch {registry -32bit t} msg] $msg
+} {1 {wrong # args: should be "registry -32bit type keyName valueName"}}
+test registry-1.17b {argument parsing for registry command} {win reg} {
+    list [catch {registry -64bit t} msg] $msg
+} {1 {wrong # args: should be "registry -64bit type keyName valueName"}}
+test registry-1.18 {argument parsing for registry command} {win reg} {
+    list [catch {registry type} msg] $msg
+} {1 {wrong # args: should be "registry type keyName valueName"}}
+test registry-1.19 {argument parsing for registry command} {win reg} {
+    list [catch {registry type foo} msg] $msg
+} {1 {wrong # args: should be "registry type keyName valueName"}}
+test registry-1.20 {argument parsing for registry command} {win reg} {
+    list [catch {registry type foo bar baz} msg] $msg
+} {1 {wrong # args: should be "registry type keyName valueName"}}
+
+test registry-1.21 {argument parsing for registry command} {win reg} {
+    list [catch {registry v} msg] $msg
+} {1 {wrong # args: should be "registry values keyName ?pattern?"}}
+test registry-1.21a {argument parsing for registry command} {win reg} {
+    list [catch {registry -32bit v} msg] $msg
+} {1 {wrong # args: should be "registry -32bit values keyName ?pattern?"}}
+test registry-1.21b {argument parsing for registry command} {win reg} {
+    list [catch {registry -64bit v} msg] $msg
+} {1 {wrong # args: should be "registry -64bit values keyName ?pattern?"}}
+test registry-1.22 {argument parsing for registry command} {win reg} {
+    list [catch {registry values} msg] $msg
+} {1 {wrong # args: should be "registry values keyName ?pattern?"}}
+test registry-1.23 {argument parsing for registry command} {win reg} {
+    list [catch {registry values foo bar baz} msg] $msg
+} {1 {wrong # args: should be "registry values keyName ?pattern?"}}
+
+test registry-2.1 {DeleteKey: bad key} {win reg} {
+    list [catch {registry delete foo} msg] $msg
+} {1 {bad root name "foo": must be HKEY_LOCAL_MACHINE, HKEY_USERS, HKEY_CLASSES_ROOT, HKEY_CURRENT_USER, HKEY_CURRENT_CONFIG, HKEY_PERFORMANCE_DATA, or HKEY_DYN_DATA}}
+test registry-2.2 {DeleteKey: bad key} {win reg} {
+    list [catch {registry delete HKEY_CLASSES_ROOT} msg] $msg
+} {1 {bad key: cannot delete root keys}}
+test registry-2.3 {DeleteKey: bad key} {win reg} {
+    list [catch {registry delete HKEY_CLASSES_ROOT\\} msg] $msg
+} {1 {bad key: cannot delete root keys}}
+test registry-2.4 {DeleteKey: subkey at root level} {win reg} {
+    registry set HKEY_CURRENT_USER\\TclFoobar
+    registry delete HKEY_CURRENT_USER\\TclFoobar
+    registry keys HKEY_CURRENT_USER TclFoobar
+} {}
+test registry-2.5 {DeleteKey: subkey below root level} {win reg} {
+    registry set HKEY_CURRENT_USER\\TclFoobar\\test
+    registry delete HKEY_CURRENT_USER\\TclFoobar\\test
+    set result [registry keys HKEY_CURRENT_USER TclFoobar\\test]
+    registry delete HKEY_CURRENT_USER\\TclFoobar
+    set result
+} {}
+test registry-2.6 {DeleteKey: recursive delete} {win reg} {
+    registry set HKEY_CURRENT_USER\\TclFoobar\\test1
+    registry set HKEY_CURRENT_USER\\TclFoobar\\test2\\test3
+    registry delete HKEY_CURRENT_USER\\TclFoobar
+    set result [registry keys HKEY_CURRENT_USER TclFoobar]
+    set result
+} {}
+test registry-2.7 {DeleteKey: trailing backslashes} {win reg english} {
+    registry set HKEY_CURRENT_USER\\TclFoobar\\baz
+    list [catch {registry delete HKEY_CURRENT_USER\\TclFoobar\\} msg] $msg
+} {1 {unable to delete key: The configuration registry key is invalid.}}
+test registry-2.8 {DeleteKey: failure} {win reg} {
+    registry delete HKEY_CURRENT_USER\\TclFoobar
+    registry delete HKEY_CURRENT_USER\\TclFoobar
+} {}
+test registry-2.9 {DeleteKey: unicode} {win reg} {
+    registry delete HKEY_CURRENT_USER\\TclFoobar
+    registry set HKEY_CURRENT_USER\\TclFoobar\\test\u00c7bar\\a
+    registry set HKEY_CURRENT_USER\\TclFoobar\\test\u00c7bar\\b
+    registry delete HKEY_CURRENT_USER\\TclFoobar\\test\u00c7bar
+    set result [registry keys HKEY_CURRENT_USER\\TclFoobar]
+    registry delete HKEY_CURRENT_USER\\TclFoobar
+    set result
+} {}
+
+test registry-3.1 {DeleteValue} {win reg} {
+    registry delete HKEY_CURRENT_USER\\TclFoobar
+    registry set HKEY_CURRENT_USER\\TclFoobar\\baz test1 blort
+    registry set HKEY_CURRENT_USER\\TclFoobar\\baz test2 blat
+    registry delete HKEY_CURRENT_USER\\TclFoobar\\baz test1
+    set result [registry values HKEY_CURRENT_USER\\TclFoobar\\baz]
+    registry delete HKEY_CURRENT_USER\\TclFoobar
+    set result
+} test2
+test registry-3.2 {DeleteValue: bad key} {win reg english} {
+    registry delete HKEY_CURRENT_USER\\TclFoobar
+    list [catch {registry delete HKEY_CURRENT_USER\\TclFoobar test} msg] $msg
+} {1 {unable to open key: The system cannot find the file specified.}}
+test registry-3.3 {DeleteValue: bad value} {win reg english} {
+    registry delete HKEY_CURRENT_USER\\TclFoobar
+    registry set HKEY_CURRENT_USER\\TclFoobar\\baz test2 blort
+    set result [list [catch {registry delete HKEY_CURRENT_USER\\TclFoobar test1} msg] $msg]
+    registry delete HKEY_CURRENT_USER\\TclFoobar
+    set result
+} {1 {unable to delete value "test1" from key "HKEY_CURRENT_USER\TclFoobar": The system cannot find the file specified.}}
+test registry-3.4 {DeleteValue: Unicode} {win reg} {
+    registry delete HKEY_CURRENT_USER\\TclFoobar
+    registry set HKEY_CURRENT_USER\\TclFoobar\\\u00c7baz \u00c7test1 blort
+    registry set HKEY_CURRENT_USER\\TclFoobar\\\u00c7baz test2 blat
+    registry delete HKEY_CURRENT_USER\\TclFoobar\\\u00c7baz \u00c7test1
+    set result [registry values HKEY_CURRENT_USER\\TclFoobar\\\u00c7baz]
+    registry delete HKEY_CURRENT_USER\\TclFoobar
+    set result
+} test2
+
+test registry-4.1 {GetKeyNames: bad key} {win reg english} {
+    registry delete HKEY_CURRENT_USER\\TclFoobar
+    list [catch {registry keys HKEY_CURRENT_USER\\TclFoobar} msg] $msg
+} {1 {unable to open key: The system cannot find the file specified.}}
+test registry-4.2 {GetKeyNames} {win reg} {
+    registry delete HKEY_CURRENT_USER\\TclFoobar
+    registry set HKEY_CURRENT_USER\\TclFoobar\\baz
+    set result [registry keys HKEY_CURRENT_USER\\TclFoobar]
+    registry delete HKEY_CURRENT_USER\\TclFoobar
+    set result
+} {baz}
+test registry-4.3 {GetKeyNames: remote key} {win reg nonPortable english} {
+    set hostname [info hostname]
+    registry set \\\\$hostname\\HKEY_CURRENT_USER\\TclFoobar\\baz
+    set result [registry keys \\\\gaspode\\HKEY_CURRENT_USER\\TclFoobar]
+    registry delete \\\\$hostname\\HKEY_CURRENT_USER\\TclFoobar
+    set result
+} {baz}
+test registry-4.4 {GetKeyNames: empty key} {win reg} {
+    registry delete HKEY_CURRENT_USER\\TclFoobar
+    registry set HKEY_CURRENT_USER\\TclFoobar
+    set result [registry keys HKEY_CURRENT_USER\\TclFoobar]
+    registry delete HKEY_CURRENT_USER\\TclFoobar
+    set result
+} {}
+test registry-4.5 {GetKeyNames: patterns} {win reg} {
+    registry delete HKEY_CURRENT_USER\\TclFoobar
+    registry set HKEY_CURRENT_USER\\TclFoobar\\baz
+    registry set HKEY_CURRENT_USER\\TclFoobar\\blat
+    registry set HKEY_CURRENT_USER\\TclFoobar\\foo
+    set result [lsort [registry keys HKEY_CURRENT_USER\\TclFoobar b*]]
+    registry delete HKEY_CURRENT_USER\\TclFoobar
+    set result
+} {baz blat}
+test registry-4.6 {GetKeyNames: names with spaces} {win reg} {
+    registry delete HKEY_CURRENT_USER\\TclFoobar
+    registry set HKEY_CURRENT_USER\\TclFoobar\\baz\ bar
+    registry set HKEY_CURRENT_USER\\TclFoobar\\blat
+    registry set HKEY_CURRENT_USER\\TclFoobar\\foo
+    set result [lsort [registry keys HKEY_CURRENT_USER\\TclFoobar b*]]
+    registry delete HKEY_CURRENT_USER\\TclFoobar
+    set result
+} {{baz bar} blat}
+test registry-4.7 {GetKeyNames: Unicode} {win reg english} {
+    registry delete HKEY_CURRENT_USER\\TclFoobar
+    registry set HKEY_CURRENT_USER\\TclFoobar\\baz\u00c7bar
+    registry set HKEY_CURRENT_USER\\TclFoobar\\blat
+    registry set HKEY_CURRENT_USER\\TclFoobar\\foo
+    set result [lsort [registry keys HKEY_CURRENT_USER\\TclFoobar b*]]
+    registry delete HKEY_CURRENT_USER\\TclFoobar
+    set result
+} "baz\u00c7bar blat"
+test registry-4.8 {GetKeyNames: Unicode} {win reg nt} {
+    registry delete HKEY_CURRENT_USER\\TclFoobar
+    registry set HKEY_CURRENT_USER\\TclFoobar\\baz\u30b7bar
+    registry set HKEY_CURRENT_USER\\TclFoobar\\blat
+    registry set HKEY_CURRENT_USER\\TclFoobar\\foo
+    set result [lsort [registry keys HKEY_CURRENT_USER\\TclFoobar b*]]
+    registry delete HKEY_CURRENT_USER\\TclFoobar
+    set result
+} "baz\u30b7bar blat"
+test registry-4.9 {GetKeyNames: very long key [Bug 1682211]} {*}{
+    -constraints {win reg}
+    -setup {
+	registry set HKEY_CURRENT_USER\\TclFoobar\\a
+	registry set HKEY_CURRENT_USER\\TclFoobar\\b[string repeat x 254]
+	registry set HKEY_CURRENT_USER\\TclFoobar\\c
+    }
+    -body {
+	lsort [registry keys HKEY_CURRENT_USER\\TclFoobar]
+    }
+    -cleanup {
+	registry delete HKEY_CURRENT_USER\\TclFoobar
+    }} \
+    -result [list a b[string repeat x 254] c]
+
+test registry-5.1 {GetType} {win reg english} {
+    registry delete HKEY_CURRENT_USER\\TclFoobar
+    list [catch {registry type HKEY_CURRENT_USER\\TclFoobar val1} msg] $msg
+} {1 {unable to open key: The system cannot find the file specified.}}
+test registry-5.2 {GetType} {win reg english} {
+    registry set HKEY_CURRENT_USER\\TclFoobar
+    list [catch {registry type HKEY_CURRENT_USER\\TclFoobar val1} msg] $msg
+} {1 {unable to get type of value "val1" from key "HKEY_CURRENT_USER\TclFoobar": The system cannot find the file specified.}}
+test registry-5.3 {GetType} {win reg} {
+    registry set HKEY_CURRENT_USER\\TclFoobar val1 foobar none
+    set result [registry type HKEY_CURRENT_USER\\TclFoobar val1]
+    registry delete HKEY_CURRENT_USER\\TclFoobar
+    set result
+} none
+test registry-5.4 {GetType} {win reg} {
+    registry set HKEY_CURRENT_USER\\TclFoobar val1 foobar
+    set result [registry type HKEY_CURRENT_USER\\TclFoobar val1]
+    registry delete HKEY_CURRENT_USER\\TclFoobar
+    set result
+} sz
+test registry-5.5 {GetType} {win reg} {
+    registry set HKEY_CURRENT_USER\\TclFoobar val1 foobar sz
+    set result [registry type HKEY_CURRENT_USER\\TclFoobar val1]
+    registry delete HKEY_CURRENT_USER\\TclFoobar
+    set result
+} sz
+test registry-5.6 {GetType} {win reg} {
+    registry set HKEY_CURRENT_USER\\TclFoobar val1 foobar expand_sz
+    set result [registry type HKEY_CURRENT_USER\\TclFoobar val1]
+    registry delete HKEY_CURRENT_USER\\TclFoobar
+    set result
+} expand_sz
+test registry-5.7 {GetType} {win reg} {
+    registry set HKEY_CURRENT_USER\\TclFoobar val1 1 binary
+    set result [registry type HKEY_CURRENT_USER\\TclFoobar val1]
+    registry delete HKEY_CURRENT_USER\\TclFoobar
+    set result
+} binary
+test registry-5.8 {GetType} {win reg} {
+    registry set HKEY_CURRENT_USER\\TclFoobar val1 1 dword
+    set result [registry type HKEY_CURRENT_USER\\TclFoobar val1]
+    registry delete HKEY_CURRENT_USER\\TclFoobar
+    set result
+} dword
+test registry-5.9 {GetType} {win reg} {
+    registry set HKEY_CURRENT_USER\\TclFoobar val1 1 dword_big_endian
+    set result [registry type HKEY_CURRENT_USER\\TclFoobar val1]
+    registry delete HKEY_CURRENT_USER\\TclFoobar
+    set result
+} dword_big_endian
+test registry-5.10 {GetType} {win reg} {
+    registry set HKEY_CURRENT_USER\\TclFoobar val1 1 link
+    set result [registry type HKEY_CURRENT_USER\\TclFoobar val1]
+    registry delete HKEY_CURRENT_USER\\TclFoobar
+    set result
+} link
+test registry-5.11 {GetType} {win reg} {
+    registry set HKEY_CURRENT_USER\\TclFoobar val1 foobar multi_sz
+    set result [registry type HKEY_CURRENT_USER\\TclFoobar val1]
+    registry delete HKEY_CURRENT_USER\\TclFoobar
+    set result
+} multi_sz
+test registry-5.12 {GetType} {win reg} {
+    registry set HKEY_CURRENT_USER\\TclFoobar val1 1 resource_list
+    set result [registry type HKEY_CURRENT_USER\\TclFoobar val1]
+    registry delete HKEY_CURRENT_USER\\TclFoobar
+    set result
+} resource_list
+test registry-5.13 {GetType: unknown types} {win reg} {
+    registry set HKEY_CURRENT_USER\\TclFoobar val1 1 24
+    set result [registry type HKEY_CURRENT_USER\\TclFoobar val1]
+    registry delete HKEY_CURRENT_USER\\TclFoobar
+    set result
+} 24
+test registry-5.14 {GetType: Unicode} {win reg} {
+    registry set HKEY_CURRENT_USER\\TclFoobar va\u00c7l1 1 24
+    set result [registry type HKEY_CURRENT_USER\\TclFoobar va\u00c7l1]
+    registry delete HKEY_CURRENT_USER\\TclFoobar
+    set result
+} 24
+
+test registry-6.1 {GetValue} {win reg english} {
+    registry delete HKEY_CURRENT_USER\\TclFoobar
+    list [catch {registry get HKEY_CURRENT_USER\\TclFoobar val1} msg] $msg
+} {1 {unable to open key: The system cannot find the file specified.}}
+test registry-6.2 {GetValue} {win reg english} {
+    registry set HKEY_CURRENT_USER\\TclFoobar
+    list [catch {registry get HKEY_CURRENT_USER\\TclFoobar val1} msg] $msg
+} {1 {unable to get value "val1" from key "HKEY_CURRENT_USER\TclFoobar": The system cannot find the file specified.}}
+test registry-6.3 {GetValue} {win reg} {
+    registry set HKEY_CURRENT_USER\\TclFoobar val1 foobar none
+    set result [registry get HKEY_CURRENT_USER\\TclFoobar val1]
+    registry delete HKEY_CURRENT_USER\\TclFoobar
+    set result
+} foobar
+test registry-6.4 {GetValue} {win reg} {
+    registry set HKEY_CURRENT_USER\\TclFoobar val1 foobar
+    set result [registry get HKEY_CURRENT_USER\\TclFoobar val1]
+    registry delete HKEY_CURRENT_USER\\TclFoobar
+    set result
+} foobar
+test registry-6.5 {GetValue} {win reg} {
+    registry set HKEY_CURRENT_USER\\TclFoobar val1 foobar sz
+    set result [registry get HKEY_CURRENT_USER\\TclFoobar val1]
+    registry delete HKEY_CURRENT_USER\\TclFoobar
+    set result
+} foobar
+test registry-6.6 {GetValue} {win reg} {
+    registry set HKEY_CURRENT_USER\\TclFoobar val1 foobar expand_sz
+    set result [registry get HKEY_CURRENT_USER\\TclFoobar val1]
+    registry delete HKEY_CURRENT_USER\\TclFoobar
+    set result
+} foobar
+test registry-6.7 {GetValue} {win reg} {
+    registry set HKEY_CURRENT_USER\\TclFoobar val1 1 binary
+    set result [registry get HKEY_CURRENT_USER\\TclFoobar val1]
+    registry delete HKEY_CURRENT_USER\\TclFoobar
+    set result
+} 1
+test registry-6.8 {GetValue} {win reg} {
+    registry set HKEY_CURRENT_USER\\TclFoobar val1 0x20 dword
+    set result [registry get HKEY_CURRENT_USER\\TclFoobar val1]
+    registry delete HKEY_CURRENT_USER\\TclFoobar
+    set result
+} 32
+test registry-6.9 {GetValue} {win reg} {
+    registry set HKEY_CURRENT_USER\\TclFoobar val1 0x20 dword_big_endian
+    set result [registry get HKEY_CURRENT_USER\\TclFoobar val1]
+    registry delete HKEY_CURRENT_USER\\TclFoobar
+    set result
+} 32
+test registry-6.10 {GetValue} {win reg} {
+    registry set HKEY_CURRENT_USER\\TclFoobar val1 1 link
+    set result [registry get HKEY_CURRENT_USER\\TclFoobar val1]
+    registry delete HKEY_CURRENT_USER\\TclFoobar
+    set result
+} 1
+test registry-6.11 {GetValue} {win reg} {
+    registry set HKEY_CURRENT_USER\\TclFoobar val1 foobar multi_sz
+    set result [registry get HKEY_CURRENT_USER\\TclFoobar val1]
+    registry delete HKEY_CURRENT_USER\\TclFoobar
+    set result
+} foobar
+test registry-6.12 {GetValue} {win reg} {
+    registry set HKEY_CURRENT_USER\\TclFoobar val1 {foo\ bar baz} multi_sz
+    set result [registry get HKEY_CURRENT_USER\\TclFoobar val1]
+    registry delete HKEY_CURRENT_USER\\TclFoobar
+    set result
+} {{foo bar} baz}
+test registry-6.13 {GetValue} {win reg} {
+    registry set HKEY_CURRENT_USER\\TclFoobar val1 {} multi_sz
+    set result [registry get HKEY_CURRENT_USER\\TclFoobar val1]
+    registry delete HKEY_CURRENT_USER\\TclFoobar
+    set result
+} {}
+test registry-6.14 {GetValue: truncation of multivalues with null elements} \
+	{win reg} {
+    registry set HKEY_CURRENT_USER\\TclFoobar val1 {a {} b} multi_sz
+    set result [registry get HKEY_CURRENT_USER\\TclFoobar val1]
+    registry delete HKEY_CURRENT_USER\\TclFoobar
+    set result
+} a
+test registry-6.15 {GetValue} {win reg} {
+    registry set HKEY_CURRENT_USER\\TclFoobar val1 1 resource_list
+    set result [registry get HKEY_CURRENT_USER\\TclFoobar val1]
+    registry delete HKEY_CURRENT_USER\\TclFoobar
+    set result
+} 1
+test registry-6.16 {GetValue: unknown types} {win reg} {
+    registry set HKEY_CURRENT_USER\\TclFoobar val1 1 24
+    set result [registry get HKEY_CURRENT_USER\\TclFoobar val1]
+    registry delete HKEY_CURRENT_USER\\TclFoobar
+    set result
+} 1
+test registry-6.17 {GetValue: Unicode value names} {win reg} {
+    registry set HKEY_CURRENT_USER\\TclFoobar val\u00c71 foobar multi_sz
+    set result [registry get HKEY_CURRENT_USER\\TclFoobar val\u00c71]
+    registry delete HKEY_CURRENT_USER\\TclFoobar
+    set result
+} foobar
+test registry-6.18 {GetValue: values with Unicode strings} {win reg nt} {
+    registry set HKEY_CURRENT_USER\\TclFoobar val1 {foo ba\u30b7r baz} multi_sz
+    set result [registry get HKEY_CURRENT_USER\\TclFoobar val1]
+    registry delete HKEY_CURRENT_USER\\TclFoobar
+    set result
+} "foo ba\u30b7r baz"
+test registry-6.19 {GetValue: values with Unicode strings} {win reg english} {
+    registry set HKEY_CURRENT_USER\\TclFoobar val1 {foo ba\u00c7r baz} multi_sz
+    set result [registry get HKEY_CURRENT_USER\\TclFoobar val1]
+    registry delete HKEY_CURRENT_USER\\TclFoobar
+    set result
+} "foo ba\u00c7r baz"
+test registry-6.20 {GetValue: values with Unicode strings with embedded nulls} {win reg} {
+    registry set HKEY_CURRENT_USER\\TclFoobar val1 {foo ba\u0000r baz} multi_sz
+    set result [registry get HKEY_CURRENT_USER\\TclFoobar val1]
+    registry delete HKEY_CURRENT_USER\\TclFoobar
+    set result
+} "foo ba r baz"
+test registry-6.21 {GetValue: very long value names and values} {pcOnly reg} {
+    registry set HKEY_CURRENT_USER\\TclFoobar [string repeat k 16383] [string repeat x 16383] multi_sz
+    set result [registry get HKEY_CURRENT_USER\\TclFoobar [string repeat k 16383]]
+    registry delete HKEY_CURRENT_USER\\TclFoobar
+    set result
+} [string repeat x 16383]
+
+test registry-7.1 {GetValueNames: bad key} -constraints {win reg english} -setup {
+    registry delete HKEY_CURRENT_USER\\TclFoobar
+} -body {
+    registry values HKEY_CURRENT_USER\\TclFoobar
+} -returnCodes error -result {unable to open key: The system cannot find the file specified.}
+test registry-7.2 {GetValueNames} -constraints {win reg} -setup {
+    registry delete HKEY_CURRENT_USER\\TclFoobar
+    registry set HKEY_CURRENT_USER\\TclFoobar baz foobar
+} -body {
+    registry values HKEY_CURRENT_USER\\TclFoobar
+} -cleanup {
+    registry delete HKEY_CURRENT_USER\\TclFoobar
+} -result baz
+test registry-7.3 {GetValueNames} -constraints {win reg} -setup {
+    registry delete HKEY_CURRENT_USER\\TclFoobar
+    registry set HKEY_CURRENT_USER\\TclFoobar baz foobar1
+    registry set HKEY_CURRENT_USER\\TclFoobar blat foobar2
+    registry set HKEY_CURRENT_USER\\TclFoobar {} foobar3
+} -body {
+    lsort [registry values HKEY_CURRENT_USER\\TclFoobar]
+} -cleanup {
+    registry delete HKEY_CURRENT_USER\\TclFoobar
+} -result {{} baz blat}
+test registry-7.4 {GetValueNames: remote key} -constraints {win reg nonPortable english} -body {
+    set hostname [info hostname]
+    registry set \\\\$hostname\\HKEY_CURRENT_USER\\TclFoobar baz blat
+    set result [registry values \\\\$hostname\\HKEY_CURRENT_USER\\TclFoobar]
+    registry delete \\\\$hostname\\HKEY_CURRENT_USER\\TclFoobar
+    set result
+} -result baz
+test registry-7.5 {GetValueNames: empty key} -constraints {win reg} -setup {
+    registry delete HKEY_CURRENT_USER\\TclFoobar
+    registry set HKEY_CURRENT_USER\\TclFoobar
+} -body {
+    registry values HKEY_CURRENT_USER\\TclFoobar
+} -cleanup {
+    registry delete HKEY_CURRENT_USER\\TclFoobar
+} -result {}
+test registry-7.6 {GetValueNames: patterns} -constraints {win reg} -setup {
+    registry delete HKEY_CURRENT_USER\\TclFoobar
+    registry set HKEY_CURRENT_USER\\TclFoobar baz foobar1
+    registry set HKEY_CURRENT_USER\\TclFoobar blat foobar2
+    registry set HKEY_CURRENT_USER\\TclFoobar foo foobar3
+} -body {
+    lsort [registry values HKEY_CURRENT_USER\\TclFoobar b*]
+} -cleanup {
+    registry delete HKEY_CURRENT_USER\\TclFoobar
+} -result {baz blat}
+test registry-7.7 {GetValueNames: names with spaces} -constraints {win reg} -setup {
+    registry delete HKEY_CURRENT_USER\\TclFoobar
+    registry set HKEY_CURRENT_USER\\TclFoobar baz\ bar foobar1
+    registry set HKEY_CURRENT_USER\\TclFoobar blat foobar2
+    registry set HKEY_CURRENT_USER\\TclFoobar foo foobar3
+} -body {
+    lsort [registry values HKEY_CURRENT_USER\\TclFoobar b*]
+} -cleanup {
+    registry delete HKEY_CURRENT_USER\\TclFoobar
+} -result {{baz bar} blat}
+
+test registry-8.1 {OpenSubKey} -constraints {win reg nonPortable english} \
+    -body {
+        # This test will only succeed if the current user does not have
+        # registry access on the specified machine.
+        registry keys {\\mom\HKEY_LOCAL_MACHINE}
+    } -returnCodes error -result "unable to open key: Access is denied."
+test registry-8.2 {OpenSubKey} -constraints {win reg} -setup {
+    registry delete HKEY_CURRENT_USER\\TclFoobar
+    registry set HKEY_CURRENT_USER\\TclFoobar
+} -body {
+    registry keys HKEY_CURRENT_USER TclFoobar
+} -cleanup {
+    registry delete HKEY_CURRENT_USER\\TclFoobar
+} -result {TclFoobar}
+test registry-8.3 {OpenSubKey} -constraints {win reg english} -setup {
+    registry delete HKEY_CURRENT_USER\\TclFoobar
+} -body {
+    registry keys HKEY_CURRENT_USER\\TclFoobar
+} -returnCodes error \
+    -result "unable to open key: The system cannot find the file specified."
+
+test registry-9.1 {ParseKeyName: bad keys} -constraints {win reg} -body {
+    registry values \\
+} -returnCodes error -result "bad key \"\\\": must start with a valid root"
+test registry-9.2 {ParseKeyName: bad keys} -constraints {win reg} -body {
+    registry values \\foobar
+} -returnCodes error -result {bad key "\foobar": must start with a valid root}
+test registry-9.3 {ParseKeyName: bad keys} -constraints {win reg} -body {
+    registry values \\\\
+} -returnCodes error -result {bad root name "": must be HKEY_LOCAL_MACHINE, HKEY_USERS, HKEY_CLASSES_ROOT, HKEY_CURRENT_USER, HKEY_CURRENT_CONFIG, HKEY_PERFORMANCE_DATA, or HKEY_DYN_DATA}
+test registry-9.4 {ParseKeyName: bad keys} -constraints {win reg} -body {
+    registry values \\\\\\
+} -returnCodes error -result {bad root name "": must be HKEY_LOCAL_MACHINE, HKEY_USERS, HKEY_CLASSES_ROOT, HKEY_CURRENT_USER, HKEY_CURRENT_CONFIG, HKEY_PERFORMANCE_DATA, or HKEY_DYN_DATA}
+test registry-9.5 {ParseKeyName: bad keys} -constraints {win reg english nt} -body {
+    registry values \\\\\\HKEY_CLASSES_ROOT
+} -returnCodes error -result {unable to open key: The network address is invalid.}
+test registry-9.6 {ParseKeyName: bad keys} -constraints {win reg} -body {
+    registry values \\\\gaspode
+} -returnCodes error -result {bad root name "": must be HKEY_LOCAL_MACHINE, HKEY_USERS, HKEY_CLASSES_ROOT, HKEY_CURRENT_USER, HKEY_CURRENT_CONFIG, HKEY_PERFORMANCE_DATA, or HKEY_DYN_DATA}
+test registry-9.7 {ParseKeyName: bad keys} -constraints {win reg} -body {
+    registry values foobar
+} -returnCodes error -result {bad root name "foobar": must be HKEY_LOCAL_MACHINE, HKEY_USERS, HKEY_CLASSES_ROOT, HKEY_CURRENT_USER, HKEY_CURRENT_CONFIG, HKEY_PERFORMANCE_DATA, or HKEY_DYN_DATA}
+test registry-9.8 {ParseKeyName: null keys} -constraints {win reg} -body {
+    registry delete HKEY_CLASSES_ROOT\\
+} -returnCodes error -result {bad key: cannot delete root keys}
+test registry-9.9 {ParseKeyName: null keys} \
+    -constraints {win reg english} \
+    -body {registry keys HKEY_CLASSES_ROOT\\TclFoobar\\baz} \
+    -returnCodes error \
+    -result {unable to open key: The system cannot find the file specified.}
+
+test registry-10.1 {RecursiveDeleteKey} -constraints {win reg} -setup {
+    registry delete HKEY_CURRENT_USER\\TclFoobar
+} -body {
+    registry set HKEY_CURRENT_USER\\TclFoobar\\test1
+    registry set HKEY_CURRENT_USER\\TclFoobar\\test2\\test3
+    registry delete HKEY_CURRENT_USER\\TclFoobar
+    set result [registry keys HKEY_CURRENT_USER TclFoobar]
+    set result
+} -result {}
+test registry-10.2 {RecursiveDeleteKey} -constraints {win reg} -setup {
+    registry delete HKEY_CURRENT_USER\\TclFoobar
+    registry set HKEY_CURRENT_USER\\TclFoobar\\test1
+    registry set HKEY_CURRENT_USER\\TclFoobar\\test2\\test3
+} -body {
+    registry delete HKEY_CURRENT_USER\\TclFoobar\\test2\\test4
+} -cleanup {
+    registry delete HKEY_CURRENT_USER\\TclFoobar
+} -result {}
+
+test registry-11.1 {SetValue: recursive creation} \
+    -constraints {win reg} -setup {
+        registry delete HKEY_CURRENT_USER\\TclFoobar
+    } -body {
+        registry set HKEY_CURRENT_USER\\TclFoobar\\baz blat foobar
+        set result [registry get HKEY_CURRENT_USER\\TclFoobar\\baz blat]
+    } -result {foobar}
+test registry-11.2 {SetValue: modification} -constraints {win reg} \
+    -setup {
+        registry delete HKEY_CURRENT_USER\\TclFoobar
+    } -body {
+        registry set HKEY_CURRENT_USER\\TclFoobar\\baz blat foobar
+        registry set HKEY_CURRENT_USER\\TclFoobar\\baz blat frob
+        set result [registry get HKEY_CURRENT_USER\\TclFoobar\\baz blat]
+    } -result {frob}
+test registry-11.3 {SetValue: failure} \
+    -constraints {win reg nonPortable english} \
+    -body {
+        # This test will only succeed if the current user does not have
+        # registry access on the specified machine.
+        registry set {\\mom\HKEY_CURRENT_USER\TclFoobar} bar foobar
+    } -returnCodes error -result {unable to open key: Access is denied.}
+
+test registry-12.1 {BroadcastValue} -constraints {win reg} -body {
+    registry broadcast
+} -returnCodes error -result "wrong # args: should be \"registry broadcast keyName ?-timeout milliseconds?\""
+test registry-12.2 {BroadcastValue} -constraints {win reg} -body {
+    registry broadcast "" -time
+} -returnCodes error -result "wrong # args: should be \"registry broadcast keyName ?-timeout milliseconds?\""
+test registry-12.3 {BroadcastValue} -constraints {win reg} -body {
+    registry broadcast "" - 500
+} -returnCodes error -result "wrong # args: should be \"registry broadcast keyName ?-timeout milliseconds?\""
+test registry-12.4 {BroadcastValue} -constraints {win reg} -body {
+    registry broadcast {Environment}
+} -result {1 0}
+test registry-12.5 {BroadcastValue} -constraints {win reg} -body {
+    registry b {}
+} -result {1 0}
+
+# cleanup
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# tcl-indent-level: 4
+# fill-column: 78
+# End:
diff --git a/tests/remote.tcl b/tests/remote.tcl
new file mode 100644
index 0000000..097e41f
--- /dev/null
+++ b/tests/remote.tcl
@@ -0,0 +1,159 @@
+# This file contains Tcl code to implement a remote server that can be
+# used during testing of Tcl socket code. This server is used by some
+# of the tests in socket.test.
+#
+# Source this file in the remote server you are using to test Tcl against.
+#
+# Copyright (c) 1995-1996 Sun Microsystems, Inc.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+# Initialize message delimitor
+
+# Initialize command array
+catch {unset command}
+set command(0) ""
+set callerSocket ""
+
+# Detect whether we should print out connection messages etc.
+if {![info exists VERBOSE]} {
+    set VERBOSE 0
+}
+
+proc __doCommands__ {l s} {
+    global callerSocket VERBOSE
+
+    if {$VERBOSE} {
+	puts "--- Server executing the following for socket $s:"
+	puts $l
+	puts "---"
+    }
+    set callerSocket $s
+    set ::errorInfo ""
+    set code [catch {uplevel "#0" $l} msg]
+    return [list $code $::errorInfo $msg]
+}
+
+proc __readAndExecute__ {s} {
+    global command VERBOSE
+
+    set l [gets $s]
+    if {[string compare $l "--Marker--Marker--Marker--"] == 0} {
+        puts $s [__doCommands__ $command($s) $s]
+	puts $s "--Marker--Marker--Marker--"
+        set command($s) ""
+	return
+    }
+    if {[string compare $l ""] == 0} {
+	if {[eof $s]} {
+	    if {$VERBOSE} {
+		puts "Server closing $s, eof from client"
+	    }
+	    close $s
+	}
+	return
+    }
+    if {[eof $s]} {
+	if {$VERBOSE} {
+	    puts "Server closing $s, eof from client"
+	}
+	close $s
+        unset command($s)
+        return
+    }
+    append command($s) $l "\n"
+}
+
+proc __accept__ {s a p} {
+    global command VERBOSE
+
+    if {$VERBOSE} {
+	puts "Server accepts new connection from $a:$p on $s"
+    }
+    set command($s) ""
+    fconfigure $s -buffering line -translation crlf
+    fileevent $s readable [list __readAndExecute__ $s]
+}
+
+set serverIsSilent 0
+for {set i 0} {$i < $argc} {incr i} {
+    if {[string compare -serverIsSilent [lindex $argv $i]] == 0} {
+	set serverIsSilent 1
+	break
+    }
+}
+if {![info exists serverPort]} {
+    if {[info exists env(serverPort)]} {
+	set serverPort $env(serverPort)
+    }
+}
+if {![info exists serverPort]} {
+    for {set i 0} {$i < $argc} {incr i} {
+	if {[string compare -port [lindex $argv $i]] == 0} {
+	    if {$i < [expr $argc - 1]} {
+		set serverPort [lindex $argv [expr $i + 1]]
+	    }
+	    break
+	}
+    }
+}
+if {![info exists serverPort]} {
+    set serverPort 2048
+}
+
+if {![info exists serverAddress]} {
+    if {[info exists env(serverAddress)]} {
+	set serverAddress $env(serverAddress)
+    }
+}
+if {![info exists serverAddress]} {
+    for {set i 0} {$i < $argc} {incr i} {
+	if {[string compare -address [lindex $argv $i]] == 0} {
+	    if {$i < [expr $argc - 1]} {
+		set serverAddress [lindex $argv [expr $i + 1]]
+	    }
+	    break
+	}
+    }
+}
+if {![info exists serverAddress]} {
+    set serverAddress 0.0.0.0
+}
+
+if {$serverIsSilent == 0} {
+    set l "Remote server listening on port $serverPort, IP $serverAddress."
+    puts ""
+    puts $l
+    for {set c [string length $l]} {$c > 0} {incr c -1} {puts -nonewline "-"}
+    puts ""
+    puts ""
+    puts "You have set the Tcl variables serverAddress to $serverAddress and"
+    puts "serverPort to $serverPort. You can set these with the -address and"
+    puts "-port command line options, or as environment variables in your"
+    puts "shell."
+    puts ""
+    puts "NOTE: The tests will not work properly if serverAddress is set to"
+    puts "\"localhost\" or 127.0.0.1."
+    puts ""
+    puts "When you invoke tcltest to run the tests, set the variables"
+    puts "remoteServerPort to $serverPort and remoteServerIP to"
+    puts "[info hostname]. You can set these as environment variables"
+    puts "from the shell. The tests will not work properly if you set"
+    puts "remoteServerIP to \"localhost\" or 127.0.0.1."
+    puts ""
+    puts -nonewline "Type Ctrl-C to terminate--> "
+    flush stdout
+}
+
+proc getPort sock {
+    lindex [fconfigure $sock -sockname] 2
+}
+
+if {[catch {set serverSocket \
+	[socket -myaddr $serverAddress -server __accept__ $serverPort]} msg]} {
+    puts "Server on $serverAddress:$serverPort cannot start: $msg"
+} else {
+    puts ready
+    vwait __server_wait_variable__
+}
diff --git a/tests/rename.test b/tests/rename.test
new file mode 100644
index 0000000..ebf5425
--- /dev/null
+++ b/tests/rename.test
@@ -0,0 +1,192 @@
+# Commands covered:  rename
+#
+# This file contains a collection of tests for one or more of the Tcl built-in
+# commands. Sourcing this file into Tcl runs the tests and generates output
+# for errors. No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution of
+# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+    package require tcltest 2
+    namespace import -force ::tcltest::*
+}
+
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
+
+testConstraint testdel [llength [info commands testdel]]
+
+# Must eliminate the "unknown" command while the test is running, especially
+# if the test is being run in a program with its own special-purpose unknown
+# command.
+catch {rename unknown unknown.old}
+
+catch {rename r2 {}}
+proc r1 {} {return "procedure r1"}
+rename r1 r2
+
+test rename-1.1 {simple renaming} {
+    r2
+} {procedure r1}
+test rename-1.2 {simple renaming} {
+    list [catch r1 msg] $msg
+} {1 {invalid command name "r1"}}
+rename r2 {}
+test rename-1.3 {simple renaming} {
+    list [catch r2 msg] $msg
+} {1 {invalid command name "r2"}}
+
+# The test below is tricky because it renames a built-in command. It's
+# possible that the test procedure uses this command, so must restore the
+# command before calling test again.
+rename list l.new
+set a [catch list msg1]
+set b [l.new a b c]
+rename l.new list
+set c [catch l.new msg2]
+set d [list 111 222]
+test rename-2.1 {renaming built-in command} {
+    list $a $msg1 $b $c $msg2 $d
+} {1 {invalid command name "list"} {a b c} 1 {invalid command name "l.new"} {111 222}}
+
+test rename-3.1 {error conditions} {
+    list [catch {rename r1} msg] $msg $errorCode
+} {1 {wrong # args: should be "rename oldName newName"} {TCL WRONGARGS}}
+test rename-3.2 {error conditions} {
+    list [catch {rename r1 r2 r3} msg] $msg $errorCode
+} {1 {wrong # args: should be "rename oldName newName"} {TCL WRONGARGS}}
+test rename-3.3 {error conditions} -setup {
+    proc r1 {} {}
+    proc r2 {} {}
+} -returnCodes error -body {
+    rename r1 r2
+} -result {can't rename to "r2": command already exists}
+test rename-3.4 {error conditions} -setup {
+    catch {rename r1 {}}
+    catch {rename r2 {}}
+} -returnCodes error -body {
+    rename r1 r2
+} -result {can't rename "r1": command doesn't exist}
+test rename-3.5 {error conditions} -setup {
+    catch {rename _non_existent_command {}}
+} -returnCodes error -body {
+    rename _non_existent_command {}
+} -result {can't delete "_non_existent_command": command doesn't exist}
+
+catch {rename unknown {}}
+catch {rename unknown.old unknown}
+catch {rename bar {}}
+
+test rename-4.1 {reentrancy issues with command deletion and renaming} testdel {
+    set x {}
+    testdel {} foo {lappend x deleted; rename bar {}; lappend x [info command bar]}
+    rename foo bar
+    lappend x |
+    rename bar {}
+    set x
+} {| deleted {}}
+test rename-4.2 {reentrancy issues with command deletion and renaming} testdel {
+    set x {}
+    testdel {} foo {lappend x deleted; rename foo bar}
+    rename foo {}
+    set x
+} {deleted}
+test rename-4.3 {reentrancy issues with command deletion and renaming} testdel {
+    set x {}
+    testdel {} foo {lappend x deleted; testdel {} foo {lappend x deleted2}}
+    rename foo {}
+    lappend x |
+    rename foo {}
+    set x
+} {deleted | deleted2}
+test rename-4.4 {reentrancy issues with command deletion and renaming} testdel {
+    set x {}
+    testdel {} foo {lappend x deleted; rename foo bar}
+    rename foo {}
+    lappend x | [info command bar]
+} {deleted | {}}
+test rename-4.5 {reentrancy issues with command deletion and renaming} testdel {
+    set env(value) before
+    interp create foo
+    testdel foo cmd {set env(value) deleted}
+    interp delete foo
+    set env(value)
+} {deleted}
+test rename-4.6 {reentrancy issues with command deletion and renaming} testdel {
+    proc kill args {
+	interp delete foo
+    }
+    set env(value) before
+    interp create foo
+    foo alias kill kill
+    testdel foo cmd {set env(value) deleted; kill}
+    list [catch {foo eval {rename cmd {}}} msg] $msg $env(value)
+} {0 {} deleted}
+test rename-4.7 {reentrancy issues with command deletion and renaming} testdel {
+    proc kill args {
+	interp delete foo
+    }
+    set env(value) before
+    interp create foo
+    foo alias kill kill
+    testdel foo cmd {set env(value) deleted; kill}
+    list [catch {interp delete foo} msg] $msg $env(value)
+} {0 {} deleted}
+if {[info exists env(value)]} {
+    unset env(value)
+}
+test rename-4.8 {Bug a16752c252} testdel {
+    set x broken
+    testdel {} foo {set x ok}
+    proc foo args {}
+    rename foo {}
+    return -level 0 $x[unset x]
+} ok
+
+# Save the unknown procedure which is modified by the following test.
+
+catch {rename unknown unknown.old}
+
+set SAVED_UNKNOWN "proc unknown "
+append SAVED_UNKNOWN [list [info args unknown.old] [info body unknown.old]]
+test rename-5.1 {repeated rename deletion and redefinition of same command} {
+    for {set i 0} {$i < 10} {incr i} {
+        eval $SAVED_UNKNOWN
+        tcl_wordBreakBefore "" 0
+        rename tcl_wordBreakBefore {}
+        rename unknown {}
+    }
+} {}
+
+catch {rename unknown {}}
+catch {rename unknown.old unknown}
+
+test rename-6.1 {old code invalidated (epoch incremented) when cmd with compile proc is renamed} -body {
+    proc x {} {
+        set a 123
+        set b [incr a]
+    }
+    x
+    rename incr incr.old
+    proc incr {} {puts "new incr called!"}
+    x
+} -cleanup {
+    rename incr {}
+    rename incr.old incr
+} -returnCodes error -result {wrong # args: should be "incr"}
+
+if {[info commands incr.old] != {}} {
+    catch {rename incr {}}
+    catch {rename incr.old incr}
+}
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/tests/resolver.test b/tests/resolver.test
new file mode 100644
index 0000000..f3d22e5
--- /dev/null
+++ b/tests/resolver.test
@@ -0,0 +1,206 @@
+# This test collection covers some unwanted interactions between command
+# literal sharing and the use of command resolvers (per-interp) which cause
+# command literals to be re-used with their command references being invalid
+# in the reusing context.  Sourcing this file into Tcl runs the tests and
+# generates output for errors.  No output means no errors were found.
+#
+# Copyright (c) 2011 Gustaf Neumann <gustaf.neumann@wu.ac.at>
+# Copyright (c) 2011 Stefan Sobernig <stefan.sobernig@wu.ac.at>
+#
+# See the file "license.terms" for information on usage and redistribution of
+# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+package require tcltest 2
+if {"::tcltest" in [namespace children]} {
+    namespace import -force ::tcltest::*
+}
+
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
+
+testConstraint testinterpresolver [llength [info commands testinterpresolver]]
+
+test resolver-1.1 {cmdNameObj sharing vs. cmd resolver: namespace import} -setup {
+    testinterpresolver up
+    namespace eval ::ns1 {
+	proc z {} { return Z }
+	namespace export z
+    }
+    proc ::y {} { return Y }
+    proc ::x {} {
+	z
+    }
+} -constraints testinterpresolver -body {
+    # 1) Have the proc body compiled: During compilation or, alternatively,
+    # the first evaluation of the compiled body, the InterpCmdResolver (see
+    # tclTest.c) maps the cmd token "z" to "::y"; this mapping is saved in the
+    # resulting CmdName Tcl_Obj with the print string "z". The CmdName Tcl_Obj
+    # is turned into a command literal shared for a given (here: the global)
+    # namespace.
+    set r0 [x];			# --> The result of [x] is "Y"
+    # 2) After having requested cmd resolution above, we can now use the
+    # globally shared CmdName Tcl_Obj "z", now bound to cmd ::y. This is
+    # certainly questionable, but defensible
+    set r1 [z];			# --> The result of [z] is "Y"
+    # 3) We import from the namespace ns1 another z. [namespace import] takes
+    # care "shadowed" cmd references, however, till now cmd literals have not
+    # been touched. This is, however, necessary since the BC compiler (used in
+    # the [namespace eval]) seems to be eager to reuse CmdName Tcl_Objs as cmd
+    # literals for a given NS scope. We expect, that r2 is "Z", the result of
+    # the namespace imported cmd.
+    namespace eval :: {
+	namespace import ::ns1::z
+	set r2 [z]
+    }
+    list $r0 $r1 $::r2
+} -cleanup {
+    testinterpresolver down
+    rename ::x ""
+    rename ::y ""
+    namespace delete ::ns1
+} -result {Y Y Z}
+test resolver-1.2 {cmdNameObj sharing vs. cmd resolver: proc creation} -setup {
+    testinterpresolver up
+    proc ::y {} { return Y }
+    proc ::x {} {
+	z
+    }
+} -constraints testinterpresolver -body {
+    set r0 [x]
+    set r1 [z]
+    proc ::foo {} {
+	proc ::z {} { return Z }
+	return [z]
+    }
+    list $r0 $r1 [::foo]
+} -cleanup {
+    testinterpresolver down
+    rename ::x ""
+    rename ::y ""
+    rename ::foo ""
+    rename ::z ""
+} -result {Y Y Z}
+test resolver-1.3 {cmdNameObj sharing vs. cmd resolver: rename} -setup {
+    testinterpresolver up
+    proc ::Z {} { return Z }
+    proc ::y {} { return Y }
+    proc ::x {} {
+	z
+    }
+} -constraints testinterpresolver -body {
+    set r0 [x]
+    set r1 [z]
+    namespace eval :: {
+	rename ::Z ::z
+	set r2 [z]
+    }
+    list $r0 $r1 $r2
+} -cleanup {
+    testinterpresolver down
+    rename ::x ""
+    rename ::y ""
+    rename ::z ""
+} -result {Y Y Z}
+test resolver-1.4 {cmdNameObj sharing vs. cmd resolver: interp expose} -setup {
+    testinterpresolver up
+    proc ::Z {} { return Z }
+    interp hide {} Z
+    proc ::y {} { return Y }
+    proc ::x {} {
+	z
+    }
+} -constraints testinterpresolver -body {
+    set r0 [x]
+    set r1 [z]
+    interp expose {} Z z
+    namespace eval :: {
+	set r2 [z]
+    }
+    list $r0 $r1 $r2
+} -cleanup {
+    testinterpresolver down
+    rename ::x ""
+    rename ::y ""
+    rename ::z ""
+} -result {Y Y Z}
+test resolver-1.5 {cmdNameObj sharing vs. cmd resolver: other than global NS} -setup {
+    testinterpresolver up
+    namespace eval ::ns1 {
+	proc z {} { return Z }
+	namespace export z
+    }
+    proc ::y {} { return Y }
+    namespace eval ::ns2 {
+	proc x {} {
+	    z
+	}
+    }
+    namespace eval :: {
+	variable r2 ""
+    }
+} -constraints testinterpresolver -body {
+    set r0 [namespace eval ::ns2 {x}]
+    set r1 [namespace eval ::ns2 {z}]
+    namespace eval ::ns2 {
+	namespace import ::ns1::z
+	set r2 [z]
+    }
+    list $r0 $r1 $r2
+} -cleanup {
+    testinterpresolver down
+    namespace delete ::ns2
+    namespace delete ::ns1
+} -result {Y Y Z}
+test resolver-1.6 {cmdNameObj sharing vs. cmd resolver: interp alias} -setup {
+    testinterpresolver up
+    proc ::Z {} { return Z }
+    proc ::y {} { return Y }
+    proc ::x {} {
+	z
+    }
+} -constraints testinterpresolver -body {
+    set r0 [x]
+    set r1 [z]
+    namespace eval :: {
+	interp alias {} ::z {} ::Z
+	set r2 [z]
+    }
+    list $r0 $r1 $r2
+} -cleanup {
+    testinterpresolver down
+    rename ::x ""
+    rename ::y ""
+    rename ::Z ""
+} -result {Y Y Z}
+
+test resolver-2.1 {compiled var resolver: Bug #3383616} -setup {
+    testinterpresolver up
+    # The compiled var resolver fetches just variables starting with a capital
+    # "T" and stores some test information in the resolver-specific resolver
+    # var info.
+    proc ::x {} {
+	set T1 100
+	return $T1
+    }
+} -constraints testinterpresolver -body {
+    # Call "x" the first time, causing a byte code compilation of the body.
+    # During the compilation the compiled var resolver, the resolve-specific
+    # var info is allocated, during the execution of the body, the variable is
+    # fetched and cached.
+    x;
+    # During later calls, the cached variable is reused.
+    x
+    # When the proc is freed, the resolver-specific resolver var info is
+    # freed. This did not happen before fix #3383616.
+    rename ::x ""
+} -cleanup {
+    testinterpresolver down
+} -result {}
+
+cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# fill-column: 78
+# End:
diff --git a/tests/result.test b/tests/result.test
new file mode 100644
index 0000000..9e8a66b
--- /dev/null
+++ b/tests/result.test
@@ -0,0 +1,147 @@
+# This file tests the routines in tclResult.c.
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands.  Sourcing this file into Tcl runs the tests and
+# generates output for errors.  No output means no errors were found.
+#
+# Copyright (c) 1997 by Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+package require tcltest 2
+namespace import ::tcltest::*
+
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
+
+# Some tests require the testsaveresult command
+
+testConstraint testsaveresult      [llength [info commands testsaveresult]]
+testConstraint testsetobjerrorcode [llength [info commands testsetobjerrorcode]]
+testConstraint testseterrorcode    [llength [info commands testseterrorcode]]
+testConstraint testreturn          [llength [info commands testreturn]]
+
+test result-1.1 {Tcl_SaveInterpResult} {testsaveresult} {
+    testsaveresult small {set x 42} 0
+} {small result}
+test result-1.2 {Tcl_SaveInterpResult} {testsaveresult} {
+    testsaveresult append {set x 42} 0
+} {append result}
+test result-1.3 {Tcl_SaveInterpResult} {testsaveresult} {
+    testsaveresult dynamic {set x 42} 0
+} {dynamic result notCalled present}
+test result-1.4 {Tcl_SaveInterpResult} {testsaveresult} {
+    testsaveresult object {set x 42} 0
+} {object result same}
+test result-1.5 {Tcl_SaveInterpResult} {testsaveresult} {
+    testsaveresult small {set x 42} 1
+} {42}
+test result-1.6 {Tcl_SaveInterpResult} {testsaveresult} {
+    testsaveresult append {set x 42} 1
+} {42}
+test result-1.7 {Tcl_SaveInterpResult} {testsaveresult} {
+    testsaveresult dynamic {set x 42} 1
+} {42 called missing}
+test result-1.8 {Tcl_SaveInterpResult} {testsaveresult} {
+    testsaveresult object {set x 42} 1
+} {42 different}
+
+# Tcl_RestoreInterpResult is mostly tested by the previous tests except
+# for the following case
+
+test result-2.1 {Tcl_RestoreInterpResult} {testsaveresult} {
+    testsaveresult append {cd _foobar} 0
+} {append result}
+
+# Tcl_DiscardInterpResult is mostly tested by the previous tests except
+# for the following cases
+
+test result-3.1 {Tcl_DiscardInterpResult} -constraints testsaveresult -body {
+    testsaveresult append {cd _foobar} 1
+} -returnCodes error -result {couldn't change working directory to "_foobar": no such file or directory}
+test result-3.2 {Tcl_DiscardInterpResult} {testsaveresult} {
+    testsaveresult free {set x 42} 1
+} {42}
+
+test result-4.1 {Tcl_SetObjErrorCode - one arg} {testsetobjerrorcode} {
+    catch {testsetobjerrorcode 1}
+    list [set errorCode]
+} {1}
+test result-4.2 {Tcl_SetObjErrorCode - two args} {testsetobjerrorcode} {
+    catch {testsetobjerrorcode 1 2}
+    list [set errorCode]
+} {{1 2}}
+test result-4.3 {Tcl_SetObjErrorCode - three args} {testsetobjerrorcode} {
+    catch {testsetobjerrorcode 1 2 3}
+    list [set errorCode]
+} {{1 2 3}}
+test result-4.4 {Tcl_SetObjErrorCode - four args} {testsetobjerrorcode} {
+    catch {testsetobjerrorcode 1 2 3 4}
+    list [set errorCode]
+} {{1 2 3 4}}
+test result-4.5 {Tcl_SetObjErrorCode - five args} {testsetobjerrorcode} {
+    catch {testsetobjerrorcode 1 2 3 4 5}
+    list [set errorCode]
+} {{1 2 3 4 5}}
+
+test result-5.1 {Tcl_SetErrorCode - one arg} testseterrorcode {
+    catch {testseterrorcode 1}
+    set errorCode
+} 1
+test result-5.2 {Tcl_SetErrorCode - one arg, list quoting} testseterrorcode {
+    catch {testseterrorcode {a b}}
+    set errorCode
+} {{a b}}
+test result-5.3 {Tcl_SetErrorCode - one arg, list quoting} testseterrorcode {
+    catch {testseterrorcode \{}
+    llength $errorCode
+} 1
+test result-5.4 {Tcl_SetErrorCode - two args, list quoting} testseterrorcode {
+    catch {testseterrorcode {a b} c}
+    set errorCode
+} {{a b} c}
+
+test result-6.0 {Bug 1209759} -constraints testreturn -body {
+    # Might panic if bug is not fixed.
+    proc foo {} {testreturn}
+    foo
+} -returnCodes ok  -result {}
+test result-6.1 {Bug 1209759} -constraints testreturn -body {
+    # Might panic if bug is not fixed.
+    proc foo {} {catch {return -level 2}; testreturn}
+    foo
+} -cleanup {
+    rename foo {}
+} -returnCodes ok -result {}
+test result-6.2 {Bug 1649062} -setup {
+    proc foo {} {
+        if {[catch {
+            return -code error -errorinfo custom -errorcode CUSTOM foo
+        } err]} {
+            return [list $err $::errorCode $::errorInfo]
+        }
+    }
+    set ::errorInfo {}
+    set ::errorCode {}
+} -body {
+    foo
+} -cleanup {
+    rename foo {}
+} -result {foo {} {}}
+test result-6.3 {Bug 2383005} {
+     catch {return -code error -errorcode {{}a} eek} m
+     set m
+} {bad -errorcode value: expected a list but got "{}a"}
+test result-6.4 {non-list -errorstack} -body {
+     catch {return -code error -errorstack {{}a} eek} m o
+     list $m [dict get $o -errorcode] [dict get $o -errorstack]
+} -match glob -result {{bad -errorstack value: expected a list but got "{}a"} {TCL RESULT NONLIST_ERRORSTACK} {INNER * UP 1}}
+test result-6.5 {odd-sized-list -errorstack} -body {
+     catch {return -code error -errorstack a eek} m o
+     list $m [dict get $o -errorcode] [dict get $o -errorstack]
+} -match glob -result {{forbidden odd-sized list for -errorstack: "a"} {TCL RESULT ODDSIZEDLIST_ERRORSTACK} {INNER * UP 1}}
+# cleanup
+cleanupTests
+return
diff --git a/tests/safe.test b/tests/safe.test
new file mode 100644
index 0000000..6c9c6c9
--- /dev/null
+++ b/tests/safe.test
@@ -0,0 +1,846 @@
+# safe.test --
+#
+# This file contains a collection of tests for safe Tcl, packages loading, and
+# using safe interpreters. Sourcing this file into tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 1995-1996 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution of
+# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+package require Tcl 8.5
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+    package require tcltest 2
+    namespace import -force ::tcltest::*
+}
+
+foreach i [interp slaves] {
+    interp delete $i
+}
+
+set saveAutoPath $::auto_path
+set ::auto_path [info library]
+
+# Force actual loading of the safe package because we use un exported (and
+# thus un-autoindexed) APIs in this test result arguments:
+catch {safe::interpConfigure}
+
+# testing that nested and statics do what is advertised (we use a static
+# package - Tcltest - but it might be absent if we're in standard tclsh)
+
+testConstraint TcltestPackage [expr {![catch {package require Tcltest}]}]
+
+test safe-1.1 {safe::interpConfigure syntax} -returnCodes error -body {
+    safe::interpConfigure
+} -result {no value given for parameter "slave" (use -help for full usage) :
+    slave name () name of the slave}
+test safe-1.2 {safe::interpCreate syntax} -returnCodes error -body {
+    safe::interpCreate -help
+} -result {Usage information:
+    Var/FlagName  Type     Value   Help
+    ------------  ----     -----   ----
+    (-help                         gives this help)
+    ?slave?       name     ()      name of the slave (optional)
+    -accessPath   list     ()      access path for the slave
+    -noStatics    boolflag (false) prevent loading of statically linked pkgs
+    -statics      boolean  (true)  loading of statically linked pkgs
+    -nestedLoadOk boolflag (false) allow nested loading
+    -nested       boolean  (false) nested loading
+    -deleteHook   script   ()      delete hook}
+test safe-1.3 {safe::interpInit syntax} -returnCodes error -body {
+    safe::interpInit -noStatics
+} -result {bad value "-noStatics" for parameter
+    slave name () name of the slave}
+
+test safe-2.1 {creating interpreters, should have no aliases} emptyTest {
+    # Disabled this test.  It tests nothing sensible.  [Bug 999612]
+    # interp aliases
+} ""
+test safe-2.2 {creating interpreters, should have no aliases} -setup {
+    catch {safe::interpDelete a}
+} -body {
+    interp create a
+    a aliases
+} -cleanup {
+    safe::interpDelete a
+} -result ""
+test safe-2.3 {creating safe interpreters, should have no unexpected aliases} -setup {
+    catch {safe::interpDelete a}
+} -body {
+    interp create a -safe
+    lsort [a aliases]
+} -cleanup {
+    interp delete a
+} -result {::tcl::mathfunc::max ::tcl::mathfunc::min clock}
+
+test safe-3.1 {calling safe::interpInit is safe} -setup {
+    catch {safe::interpDelete a}
+    interp create a -safe
+} -body {
+    safe::interpInit a
+    interp eval a exec ls
+} -returnCodes error -cleanup {
+    safe::interpDelete a
+} -result {invalid command name "exec"}
+test safe-3.2 {calling safe::interpCreate on trusted interp} -setup {
+    catch {safe::interpDelete a}
+} -body {
+    safe::interpCreate a
+    lsort [a aliases]
+} -cleanup {
+    safe::interpDelete a
+} -result {::tcl::file::atime ::tcl::file::attributes ::tcl::file::copy ::tcl::file::delete ::tcl::file::dirname ::tcl::file::executable ::tcl::file::exists ::tcl::file::extension ::tcl::file::isdirectory ::tcl::file::isfile ::tcl::file::link ::tcl::file::lstat ::tcl::file::mkdir ::tcl::file::mtime ::tcl::file::nativename ::tcl::file::normalize ::tcl::file::owned ::tcl::file::readable ::tcl::file::readlink ::tcl::file::rename ::tcl::file::rootname ::tcl::file::size ::tcl::file::stat ::tcl::file::tail ::tcl::file::tempfile ::tcl::file::type ::tcl::file::volumes ::tcl::file::writable ::tcl::info::nameofexecutable clock encoding exit glob load source}
+test safe-3.3 {calling safe::interpCreate on trusted interp} -setup {
+    catch {safe::interpDelete a}
+} -body {
+    safe::interpCreate a
+    interp eval a {source [file join $tcl_library init.tcl]}
+} -cleanup {
+    safe::interpDelete a
+} -result ""
+test safe-3.4 {calling safe::interpCreate on trusted interp} -setup {
+    catch {safe::interpDelete a}
+} -body {
+    safe::interpCreate a
+    interp eval a {source [file join $tcl_library init.tcl]}
+} -cleanup {
+    safe::interpDelete a
+} -result {}
+
+test safe-4.1 {safe::interpDelete} -setup {
+    catch {safe::interpDelete a}
+} -body {
+    interp create a
+    safe::interpDelete a
+} -result ""
+test safe-4.2 {safe::interpDelete, indirectly} -setup {
+    catch {safe::interpDelete a}
+} -body {
+    interp create a
+    a alias exit safe::interpDelete a
+    a eval exit
+} -result ""
+test safe-4.5 {safe::interpDelete} -setup {
+    catch {safe::interpDelete a}
+} -body {
+    safe::interpCreate a
+    safe::interpCreate a
+} -returnCodes error -cleanup {
+    safe::interpDelete a
+} -result {interpreter named "a" already exists, cannot create}
+test safe-4.6 {safe::interpDelete, indirectly} -setup {
+    catch {safe::interpDelete a}
+} -body {
+    safe::interpCreate a
+    a eval exit
+} -result ""
+
+# The following test checks whether the definition of tcl_endOfWord can be
+# obtained from auto_loading.
+
+test safe-5.1 {test auto-loading in safe interpreters} -setup {
+    catch {safe::interpDelete a}
+    safe::interpCreate a
+} -body {
+    interp eval a {tcl_endOfWord "" 0}
+} -cleanup {
+    safe::interpDelete a
+} -result -1
+
+# test safe interps 'information leak'
+proc SafeEval {script} {
+    # Helper procedure that ensures the safe interp is cleaned up even if
+    # there is a failure in the script.
+    set SafeInterp [interp create -safe]
+    catch {$SafeInterp eval $script} msg opts
+    interp delete $SafeInterp
+    return -options $opts $msg
+}
+
+test safe-6.1 {test safe interpreters knowledge of the world} {
+    lsort [SafeEval {info globals}]
+} {tcl_interactive tcl_patchLevel tcl_platform tcl_version}
+test safe-6.2 {test safe interpreters knowledge of the world} {
+    SafeEval {info script}
+} {}
+test safe-6.3 {test safe interpreters knowledge of the world} {
+    set r [SafeEval {array names tcl_platform}]
+    # If running a windows-debug shell, remove the "debug" element from r.
+    if {[testConstraint win]} {
+	set r [lsearch -all -inline -not -exact $r "debug"]
+    }
+    set r [lsearch -all -inline -not -exact $r "threaded"]
+    lsort $r
+} {byteOrder engine pathSeparator platform pointerSize wordSize}
+
+# More test should be added to check that hostname, nameofexecutable, aren't
+# leaking infos, but they still do...
+
+# high level general test
+test safe-7.1 {tests that everything works at high level} {
+    set i [safe::interpCreate]
+    # no error shall occur:
+    # (because the default access_path shall include 1st level sub dirs so
+    #  package require in a slave works like in the master)
+    set v [interp eval $i {package require http 1}]
+    # no error shall occur:
+    interp eval $i {http_config}
+    safe::interpDelete $i
+    set v
+} 1.0
+test safe-7.2 {tests specific path and interpFind/AddToAccessPath} -body {
+    set i [safe::interpCreate -nostat -nested 1 -accessPath [list [info library]]]
+    # should not add anything (p0)
+    set token1 [safe::interpAddToAccessPath $i [info library]]
+    # should add as p1
+    set token2 [safe::interpAddToAccessPath $i "/dummy/unixlike/test/path"]
+    # an error shall occur (http is not anymore in the secure 0-level
+    # provided deep path)
+    list $token1 $token2 \
+	    [catch {interp eval $i {package require http 1}} msg] $msg \
+	    [safe::interpConfigure $i]\
+	    [safe::interpDelete $i]
+} -match glob -result "{\$p(:0:)} {\$p(:*:)} 1 {can't find package http 1} {-accessPath {[list $tcl_library */dummy/unixlike/test/path]} -statics 0 -nested 1 -deleteHook {}} {}"
+test safe-7.3 {check that safe subinterpreters work} {
+    set i [safe::interpCreate]
+    set j [safe::interpCreate [list $i x]]
+    list [interp eval $j {join {o k} ""}] [safe::interpDelete $i] [interp exists $j]
+} {ok {} 0}
+
+# test source control on file name
+set i "a"
+test safe-8.1 {safe source control on file} -setup {
+    catch {safe::interpDelete $i}
+} -body {
+    safe::interpCreate $i
+    $i eval {source}
+} -returnCodes error -cleanup {
+    safe::interpDelete $i
+} -result {wrong # args: should be "source ?-encoding E? fileName"}
+test safe-8.2 {safe source control on file} -setup {
+    catch {safe::interpDelete $i}
+} -body {
+    safe::interpCreate $i
+    $i eval {source a b c d e}
+} -returnCodes error -cleanup {
+    safe::interpDelete $i
+} -result {wrong # args: should be "source ?-encoding E? fileName"}
+test safe-8.3 {safe source control on file} -setup {
+    catch {safe::interpDelete $i}
+    set log {}
+    proc safe-test-log {str} {lappend ::log $str}
+    set prevlog [safe::setLogCmd]
+} -body {
+    safe::interpCreate $i
+    safe::setLogCmd safe-test-log
+    list [catch {$i eval {source .}} msg] $msg $log
+} -cleanup {
+    safe::setLogCmd $prevlog
+    unset log
+    safe::interpDelete $i
+} -result {1 {permission denied} {{ERROR for slave a : ".": is a directory}}}
+test safe-8.4 {safe source control on file} -setup {
+    catch {safe::interpDelete $i}
+    set log {}
+    proc safe-test-log {str} {global log; lappend log $str}
+    set prevlog [safe::setLogCmd]
+} -body {
+    safe::interpCreate $i
+    safe::setLogCmd safe-test-log
+    list [catch {$i eval {source /abc/def}} msg] $msg $log
+} -cleanup {
+    safe::setLogCmd $prevlog
+    unset log
+    safe::interpDelete $i
+} -result {1 {permission denied} {{ERROR for slave a : "/abc/def": not in access_path}}}
+test safe-8.5 {safe source control on file} -setup {
+    catch {safe::interpDelete $i}
+    set log {}
+    proc safe-test-log {str} {global log; lappend log $str}
+    set prevlog [safe::setLogCmd]
+} -body {
+    # This tested filename == *.tcl or tclIndex, but that restriction was
+    # removed in 8.4a4 - hobbs
+    safe::interpCreate $i
+    safe::setLogCmd safe-test-log
+    list [catch {
+	$i eval {source [file join [info lib] blah]}
+    } msg] $msg $log
+} -cleanup {
+    safe::setLogCmd $prevlog
+    unset log
+    safe::interpDelete $i
+} -result [list 1 {no such file or directory} [list "ERROR for slave a : [file join [info library] blah]:no such file or directory"]]
+test safe-8.6 {safe source control on file} -setup {
+    catch {safe::interpDelete $i}
+    set log {}
+    proc safe-test-log {str} {global log; lappend log $str}
+    set prevlog [safe::setLogCmd]
+} -body {
+    safe::interpCreate $i
+    safe::setLogCmd safe-test-log
+    list [catch {
+	$i eval {source [file join [info lib] blah.tcl]}
+    } msg] $msg $log
+} -cleanup {
+    safe::setLogCmd $prevlog
+    unset log
+    safe::interpDelete $i
+} -result [list 1 {no such file or directory} [list "ERROR for slave a : [file join [info library] blah.tcl]:no such file or directory"]]
+test safe-8.7 {safe source control on file} -setup {
+    catch {safe::interpDelete $i}
+    set log {}
+    proc safe-test-log {str} {global log; lappend log $str}
+    set prevlog [safe::setLogCmd]
+} -body {
+    safe::interpCreate $i
+    # This tested length of filename, but that restriction was removed in
+    # 8.4a4 - hobbs
+    safe::setLogCmd safe-test-log
+    list [catch {
+	$i eval {source [file join [info lib] xxxxxxxxxxx.tcl]}
+    } msg] $msg $log
+} -cleanup {
+    safe::setLogCmd $prevlog
+    unset log
+    safe::interpDelete $i
+} -result [list 1 {no such file or directory} [list "ERROR for slave a : [file join [info library] xxxxxxxxxxx.tcl]:no such file or directory"]]
+test safe-8.8 {safe source forbids -rsrc} -setup {
+    catch {safe::interpDelete $i}
+    safe::interpCreate $i
+} -body {
+    $i eval {source -rsrc Init}
+} -returnCodes error -cleanup {
+    safe::interpDelete $i
+} -result {wrong # args: should be "source ?-encoding E? fileName"}
+test safe-8.9 {safe source and return} -setup {
+    set returnScript [makeFile {return "ok"} return.tcl]
+    catch {safe::interpDelete $i}
+} -body {
+    safe::interpCreate $i
+    set token [safe::interpAddToAccessPath $i [file dirname $returnScript]]
+    $i eval [list source $token/[file tail $returnScript]]
+} -cleanup {
+    catch {safe::interpDelete $i}
+    removeFile $returnScript
+} -result ok
+test safe-8.10 {safe source and return} -setup {
+    set returnScript [makeFile {return -level 2 "ok"} return.tcl]
+    catch {safe::interpDelete $i}
+} -body {
+    safe::interpCreate $i
+    set token [safe::interpAddToAccessPath $i [file dirname $returnScript]]
+    $i eval [list apply {filename {
+	source $filename
+	error boom
+    }} $token/[file tail $returnScript]]
+} -cleanup {
+    catch {safe::interpDelete $i}
+    removeFile $returnScript
+} -result ok
+
+set i "a"
+test safe-9.1 {safe interps' deleteHook} -setup {
+    catch {safe::interpDelete $i}
+    set res {}
+} -body {
+    proc testDelHook {args} {
+	global res
+	# the interp still exists at that point
+	interp eval a {set delete 1}
+	# mark that we've been here (successfully)
+	set res $args
+    }
+    safe::interpCreate $i -deleteHook "testDelHook arg1 arg2"
+    list [interp eval $i exit] $res
+} -result {{} {arg1 arg2 a}}
+test safe-9.2 {safe interps' error in deleteHook} -setup {
+    catch {safe::interpDelete $i}
+    set res {}
+    set log {}
+    proc safe-test-log {str} {lappend ::log $str}
+    set prevlog [safe::setLogCmd]
+} -body {
+    proc testDelHook {args} {
+	global res
+	# the interp still exists at that point
+	interp eval a {set delete 1}
+	# mark that we've been here (successfully)
+	set res $args
+	# create an exception
+	error "being catched"
+    }
+    safe::interpCreate $i -deleteHook "testDelHook arg1 arg2"
+    safe::setLogCmd safe-test-log
+    list [safe::interpDelete $i] $res $log
+} -cleanup {
+    safe::setLogCmd $prevlog
+    unset log
+} -result {{} {arg1 arg2 a} {{NOTICE for slave a : About to delete} {ERROR for slave a : Delete hook error (being catched)} {NOTICE for slave a : Deleted}}}
+test safe-9.3 {dual specification of statics} -returnCodes error -body {
+    safe::interpCreate -stat true -nostat
+} -result {conflicting values given for -statics and -noStatics}
+test safe-9.4 {dual specification of statics} {
+    # no error shall occur
+    safe::interpDelete [safe::interpCreate -stat false -nostat]
+} {}
+test safe-9.5 {dual specification of nested} -returnCodes error -body {
+    safe::interpCreate -nested 0 -nestedload
+} -result {conflicting values given for -nested and -nestedLoadOk}
+test safe-9.6 {interpConfigure widget like behaviour} -body {
+   # this test shall work, don't try to "fix it" unless you *really* know what
+   # you are doing (ie you are me :p) -- dl
+   list [set i [safe::interpCreate \
+		    -noStatics \
+		    -nestedLoadOk \
+		    -deleteHook {foo bar}]
+         safe::interpConfigure $i -accessPath /foo/bar
+         safe::interpConfigure $i]\
+	[safe::interpConfigure $i -aCCess]\
+	[safe::interpConfigure $i -nested]\
+	[safe::interpConfigure $i -statics]\
+	[safe::interpConfigure $i -DEL]\
+	[safe::interpConfigure $i -accessPath /blah -statics 1
+	 safe::interpConfigure $i]\
+	[safe::interpConfigure $i -deleteHook toto -nosta -nested 0
+	 safe::interpConfigure $i]
+} -match glob -result {{-accessPath * -statics 0 -nested 1 -deleteHook {foo bar}} {-accessPath *} {-nested 1} {-statics 0} {-deleteHook {foo bar}} {-accessPath * -statics 1 -nested 1 -deleteHook {foo bar}} {-accessPath * -statics 0 -nested 0 -deleteHook toto}}
+
+catch {teststaticpkg Safepkg1 0 0}
+test safe-10.1 {testing statics loading} -constraints TcltestPackage -setup {
+    set i [safe::interpCreate]
+} -body {
+    interp eval $i {load {} Safepkg1}
+} -returnCodes error -cleanup {
+    safe::interpDelete $i
+} -result {can't use package in a safe interpreter: no Safepkg1_SafeInit procedure}
+test safe-10.1.1 {testing statics loading} -constraints TcltestPackage -setup {
+    set i [safe::interpCreate]
+} -body {
+    catch {interp eval $i {load {} Safepkg1}} m o
+    dict get $o -errorinfo
+} -returnCodes ok -cleanup {
+    unset -nocomplain m o
+    safe::interpDelete $i
+} -result {can't use package in a safe interpreter: no Safepkg1_SafeInit procedure
+    invoked from within
+"load {} Safepkg1"
+    invoked from within
+"interp eval $i {load {} Safepkg1}"}
+test safe-10.2 {testing statics loading / -nostatics} -constraints TcltestPackage -body {
+    set i [safe::interpCreate -nostatics]
+    interp eval $i {load {} Safepkg1}
+} -returnCodes error -cleanup {
+    safe::interpDelete $i
+} -result {permission denied (static package)}
+test safe-10.3 {testing nested statics loading / no nested by default} -setup {
+    set i [safe::interpCreate]
+} -constraints TcltestPackage -body {
+    interp eval $i {interp create x; load {} Safepkg1 x}
+} -returnCodes error -cleanup {
+    safe::interpDelete $i
+} -result {permission denied (nested load)}
+test safe-10.4 {testing nested statics loading / -nestedloadok} -constraints TcltestPackage -body {
+    set i [safe::interpCreate -nestedloadok]
+    interp eval $i {interp create x; load {} Safepkg1 x}
+} -returnCodes error -cleanup {
+    safe::interpDelete $i
+} -result {can't use package in a safe interpreter: no Safepkg1_SafeInit procedure}
+test safe-10.4.1 {testing nested statics loading / -nestedloadok} -constraints TcltestPackage -body {
+    set i [safe::interpCreate -nestedloadok]
+    catch {interp eval $i {interp create x; load {} Safepkg1 x}} m o
+    dict get $o -errorinfo
+} -returnCodes ok -cleanup {
+    unset -nocomplain m o
+    safe::interpDelete $i
+} -result {can't use package in a safe interpreter: no Safepkg1_SafeInit procedure
+    invoked from within
+"load {} Safepkg1 x"
+    invoked from within
+"interp eval $i {interp create x; load {} Safepkg1 x}"}
+
+test safe-11.1 {testing safe encoding} -setup {
+    set i [safe::interpCreate]
+} -body {
+    interp eval $i encoding
+} -returnCodes error -cleanup {
+    safe::interpDelete $i
+} -result {wrong # args: should be "encoding option ?arg ...?"}
+test safe-11.1a {testing safe encoding} -setup {
+    set i [safe::interpCreate]
+} -body {
+    interp eval $i encoding foobar
+} -returnCodes error -cleanup {
+    safe::interpDelete $i
+} -match glob -result {bad option "foobar": must be *}
+test safe-11.2 {testing safe encoding} -setup {
+    set i [safe::interpCreate]
+} -body {
+    interp eval $i encoding system cp775
+} -returnCodes error -cleanup {
+    safe::interpDelete $i
+} -result {wrong # args: should be "encoding system"}
+test safe-11.3 {testing safe encoding} -setup {
+    set i [safe::interpCreate]
+} -body {
+    interp eval $i encoding system
+} -cleanup {
+    safe::interpDelete $i
+} -result [encoding system]
+test safe-11.4 {testing safe encoding} -setup {
+    set i [safe::interpCreate]
+} -body {
+    interp eval $i encoding names
+} -cleanup {
+    safe::interpDelete $i
+} -result [encoding names]
+test safe-11.5 {testing safe encoding} -setup {
+    set i [safe::interpCreate]
+} -body {
+    interp eval $i encoding convertfrom cp1258 foobar
+} -cleanup {
+    safe::interpDelete $i
+} -result foobar
+test safe-11.6 {testing safe encoding} -setup {
+    set i [safe::interpCreate]
+} -body {
+    interp eval $i encoding convertto cp1258 foobar
+} -cleanup {
+    safe::interpDelete $i
+} -result foobar
+test safe-11.7 {testing safe encoding} -setup {
+    set i [safe::interpCreate]
+} -body {
+    interp eval $i encoding convertfrom
+} -returnCodes error -cleanup {
+    safe::interpDelete $i
+} -result {wrong # args: should be "encoding convertfrom ?encoding? data"}
+test safe-11.7.1 {testing safe encoding} -setup {
+    set i [safe::interpCreate]
+} -body {
+    catch {interp eval $i encoding convertfrom} m o
+    dict get $o -errorinfo
+} -returnCodes ok -match glob -cleanup {
+    unset -nocomplain m o
+    safe::interpDelete $i
+} -result {wrong # args: should be "encoding convertfrom ?encoding? data"
+    while executing
+"encoding convertfrom"
+    invoked from within
+"::interp invokehidden interp* encoding convertfrom"
+    invoked from within
+"encoding convertfrom"
+    invoked from within
+"interp eval $i encoding convertfrom"}
+test safe-11.8 {testing safe encoding} -setup {
+    set i [safe::interpCreate]
+} -body {
+    interp eval $i encoding convertto
+} -returnCodes error -cleanup {
+    safe::interpDelete $i
+} -result {wrong # args: should be "encoding convertto ?encoding? data"}
+test safe-11.8.1 {testing safe encoding} -setup {
+    set i [safe::interpCreate]
+} -body {
+    catch {interp eval $i encoding convertto} m o
+    dict get $o -errorinfo
+} -returnCodes ok -match glob -cleanup {
+    unset -nocomplain m o
+    safe::interpDelete $i
+} -result {wrong # args: should be "encoding convertto ?encoding? data"
+    while executing
+"encoding convertto"
+    invoked from within
+"::interp invokehidden interp* encoding convertto"
+    invoked from within
+"encoding convertto"
+    invoked from within
+"interp eval $i encoding convertto"}
+
+test safe-12.1 {glob is restricted [Bug 2906841]} -setup {
+    set i [safe::interpCreate]
+} -body {
+    $i eval glob ../*
+} -returnCodes error -cleanup {
+    safe::interpDelete $i
+} -result "permission denied"
+test safe-12.2 {glob is restricted [Bug 2906841]} -setup {
+    set i [safe::interpCreate]
+} -body {
+    $i eval glob -directory .. *
+} -returnCodes error -cleanup {
+    safe::interpDelete $i
+} -result "permission denied"
+test safe-12.3 {glob is restricted [Bug 2906841]} -setup {
+    set i [safe::interpCreate]
+} -body {
+    $i eval glob -join .. *
+} -returnCodes error -cleanup {
+    safe::interpDelete $i
+} -result "permission denied"
+test safe-12.4 {glob is restricted [Bug 2906841]} -setup {
+    set i [safe::interpCreate]
+} -body {
+    $i eval glob -nocomplain ../*
+} -cleanup {
+    safe::interpDelete $i
+} -result {}
+test safe-12.5 {glob is restricted [Bug 2906841]} -setup {
+    set i [safe::interpCreate]
+} -body {
+    $i eval glob -directory .. -nocomplain *
+} -cleanup {
+    safe::interpDelete $i
+} -result {}
+test safe-12.6 {glob is restricted [Bug 2906841]} -setup {
+    set i [safe::interpCreate]
+} -body {
+    $i eval glob -nocomplain -join .. *
+} -cleanup {
+    safe::interpDelete $i
+} -result {}
+test safe-12.7 {glob is restricted} -setup {
+    set i [safe::interpCreate]
+} -body {
+    $i eval glob *
+} -returnCodes error -cleanup {
+    safe::interpDelete $i
+} -result {permission denied}
+
+proc buildEnvironment {filename} {
+    upvar 1 testdir testdir testdir2 testdir2 testfile testfile
+    set testdir [makeDirectory deletethisdir]
+    set testdir2 [makeDirectory deletemetoo $testdir]
+    set testfile [makeFile {} $filename $testdir2]
+}
+#### New tests for Safe base glob, with patches @ Bug 2964715
+test safe-13.1 {glob is restricted [Bug 2964715]} -setup {
+    set i [safe::interpCreate]
+} -body {
+    $i eval glob *
+} -returnCodes error -cleanup {
+    safe::interpDelete $i
+} -result {permission denied}
+test safe-13.2 {mimic the valid glob call by ::tcl::tm::UnknownHandler [Bug 2964715]} -setup {
+    set i [safe::interpCreate]
+    buildEnvironment deleteme.tm
+} -body {
+    ::safe::interpAddToAccessPath $i $testdir2
+    set result [$i eval glob -nocomplain -directory $testdir2 *.tm]
+    if {$result eq [list $testfile]} {
+        return "glob match"
+    } else {
+        return "no match: $result"
+    }
+} -cleanup {
+    safe::interpDelete $i
+    removeDirectory $testdir
+} -result {glob match}
+test safe-13.3 {cf 13.2 but test glob failure when -directory is outside access path [Bug 2964715]} -setup {
+    set i [safe::interpCreate]
+    buildEnvironment deleteme.tm
+} -body {
+    $i eval glob -directory $testdir2 *.tm
+} -returnCodes error -cleanup {
+    safe::interpDelete $i
+    removeDirectory $testdir
+} -result {permission denied}
+test safe-13.4 {another valid glob call [Bug 2964715]} -setup {
+    set i [safe::interpCreate]
+    buildEnvironment deleteme.tm
+} -body {
+    ::safe::interpAddToAccessPath $i $testdir
+    ::safe::interpAddToAccessPath $i $testdir2
+    set result [$i eval \
+	    glob -nocomplain -directory $testdir [file join deletemetoo *.tm]]
+    if {$result eq [list $testfile]} {
+        return "glob match"
+    } else {
+        return "no match: $result"
+    }
+} -cleanup {
+    safe::interpDelete $i
+    removeDirectory $testdir
+} -result {glob match}
+test safe-13.5 {as 13.4 but test glob failure when -directory is outside access path [Bug 2964715]} -setup {
+    set i [safe::interpCreate]
+    buildEnvironment deleteme.tm
+} -body {
+    ::safe::interpAddToAccessPath $i $testdir2
+    $i eval \
+	glob -directory $testdir [file join deletemetoo *.tm]
+} -returnCodes error -cleanup {
+    safe::interpDelete $i
+    removeDirectory $testdir
+} -result {permission denied}
+test safe-13.6 {as 13.4 but test silent failure when result is outside access_path [Bug 2964715]} -setup {
+    set i [safe::interpCreate]
+    buildEnvironment deleteme.tm
+} -body {
+    ::safe::interpAddToAccessPath $i $testdir
+    $i eval \
+	glob -nocomplain -directory $testdir [file join deletemetoo *.tm]
+} -cleanup {
+    safe::interpDelete $i
+    removeDirectory $testdir
+} -result {}
+test safe-13.7 {mimic the glob call by tclPkgUnknown which gives a deliberate error in a safe interpreter [Bug 2964715]} -setup {
+    set i [safe::interpCreate]
+    buildEnvironment pkgIndex.tcl
+} -body {
+    set safeTD [::safe::interpAddToAccessPath $i $testdir]
+    ::safe::interpAddToAccessPath $i $testdir2
+    string map [list $safeTD EXPECTED] [$i eval [list \
+	glob -directory $safeTD -join * pkgIndex.tcl]]
+} -cleanup {
+    safe::interpDelete $i
+    removeDirectory $testdir
+} -result {{EXPECTED/deletemetoo/pkgIndex.tcl}}
+# Note the extra {} around the result above; that's *expected* because of the
+# format of virtual path roots.
+test safe-13.8 {mimic the glob call by tclPkgUnknown without the deliberate error that is specific to pkgIndex.tcl [Bug 2964715]} -setup {
+    set i [safe::interpCreate]
+    buildEnvironment notIndex.tcl
+} -body {
+    set safeTD [::safe::interpAddToAccessPath $i $testdir]
+    ::safe::interpAddToAccessPath $i $testdir2
+    $i eval [list glob -directory $safeTD -join -nocomplain * notIndex.tcl]
+} -cleanup {
+    safe::interpDelete $i
+    removeDirectory $testdir
+} -result {}
+test safe-13.9 {as 13.8 but test glob failure when -directory is outside access path [Bug 2964715]} -setup {
+    set i [safe::interpCreate]
+    buildEnvironment notIndex.tcl
+} -body {
+    ::safe::interpAddToAccessPath $i $testdir2
+    set result [$i eval \
+	    glob -directory $testdir -join -nocomplain * notIndex.tcl]
+    if {$result eq [list $testfile]} {
+        return {glob match}
+    } else {
+        return "no match: $result"
+    }
+} -cleanup {
+    safe::interpDelete $i
+    removeDirectory $testdir
+} -result {no match: }
+test safe-13.10 {as 13.8 but test silent failure when result is outside access_path [Bug 2964715]} -setup {
+    set i [safe::interpCreate]
+    buildEnvironment notIndex.tcl
+} -body {
+    ::safe::interpAddToAccessPath $i $testdir
+    $i eval glob -directory $testdir -join -nocomplain * notIndex.tcl
+} -cleanup {
+    safe::interpDelete $i
+    removeDirectory $testdir
+} -result {}
+rename buildEnvironment {}
+
+#### Test for the module path
+test safe-14.1 {Check that module path is the same as in the master interpreter [Bug 2964715]} -setup {
+    set i [safe::interpCreate]
+} -body {
+    set tm {}
+    foreach token [$i eval ::tcl::tm::path list] {
+        lappend tm [dict get [set ::safe::S${i}(access_path,map)] $token]
+    }
+    return $tm
+} -cleanup {
+    safe::interpDelete $i
+} -result [::tcl::tm::path list]
+
+test safe-15.1 {safe file ensemble does not surprise code} -setup {
+    set i [interp create -safe]
+} -body {
+    set result [expr {"file" in [interp hidden $i]}]
+    lappend result [interp eval $i {tcl::file::split a/b/c}]
+    lappend result [catch {interp eval $i {tcl::file::isdirectory .}}]
+    lappend result [interp invokehidden $i file split a/b/c]
+    lappend result [catch {interp eval $i {file split a/b/c}} msg] $msg
+    lappend result [catch {interp invokehidden $i file isdirectory .}]
+    interp expose $i file
+    lappend result [catch {interp eval $i {file split a/b/c}} msg] $msg
+    lappend result [catch {interp eval $i {file isdirectory .}} msg] $msg
+} -cleanup {
+    unset -nocomplain msg
+    interp delete $i
+} -result {1 {a b c} 1 {a b c} 1 {invalid command name "file"} 1 0 {a b c} 1 {not allowed to invoke subcommand isdirectory of file}}
+test safe-15.1.1 {safe file ensemble does not surprise code} -setup {
+    set i [interp create -safe]
+} -body {
+    set result [expr {"file" in [interp hidden $i]}]
+    lappend result [interp eval $i {tcl::file::split a/b/c}]
+    lappend result [catch {interp eval $i {tcl::file::isdirectory .}}]
+    lappend result [interp invokehidden $i file split a/b/c]
+    lappend result [catch {interp eval $i {file split a/b/c}} msg] $msg
+    lappend result [catch {interp invokehidden $i file isdirectory .}]
+    interp expose $i file
+    lappend result [catch {interp eval $i {file split a/b/c}} msg] $msg
+    lappend result [catch {interp eval $i {file isdirectory .}} msg o] [dict get $o -errorinfo]
+} -cleanup {
+    unset -nocomplain msg o
+    interp delete $i
+} -result {1 {a b c} 1 {a b c} 1 {invalid command name "file"} 1 0 {a b c} 1 {not allowed to invoke subcommand isdirectory of file
+    while executing
+"file isdirectory ."
+    invoked from within
+"interp eval $i {file isdirectory .}"}}
+
+### ~ should have no special meaning in paths in safe interpreters
+test safe-16.1 {Bug 3529949: defang ~ in paths} -setup {
+    set savedHOME $env(HOME)
+    set env(HOME) /foo/bar
+    set i [safe::interpCreate]
+} -body {
+    $i eval {
+	set d [format %c 126]
+	list [file join [file dirname $d] [file tail $d]]
+    }
+} -cleanup {
+    safe::interpDelete $i
+    set env(HOME) $savedHOME
+} -result {./~}
+test safe-16.2 {Bug 3529949: defang ~user in paths} -setup {
+    set i [safe::interpCreate]
+    set user $tcl_platform(user)
+} -body {
+    string map [list $user USER] [$i eval \
+	    "file join \[file dirname ~$user\] \[file tail ~$user\]"]
+} -cleanup {
+    safe::interpDelete $i
+} -result {./~USER}
+test safe-16.3 {Bug 3529949: defang ~ in globs} -setup {
+    set syntheticHOME [makeDirectory foo]
+    makeFile {} bar $syntheticHOME
+    set savedHOME $env(HOME)
+    set env(HOME) $syntheticHOME
+    set i [safe::interpCreate]
+} -body {
+    ::safe::interpAddToAccessPath $i $syntheticHOME
+    $i eval {glob -nocomplain ~/*}
+} -cleanup {
+    safe::interpDelete $i
+    set env(HOME) $savedHOME
+    removeDirectory $syntheticHOME
+} -result {}
+test safe-16.4 {Bug 3529949: defang ~user in globs} -setup {
+    set i [safe::interpCreate]
+} -body {
+    ::safe::interpAddToAccessPath $i $~$tcl_platform(user)
+    $i eval [list glob -nocomplain ~$tcl_platform(user)/*]
+} -cleanup {
+    safe::interpDelete $i
+} -result {}
+
+set ::auto_path $saveAutoPath
+# cleanup
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/tests/scan.test b/tests/scan.test
new file mode 100644
index 0000000..b57b641
--- /dev/null
+++ b/tests/scan.test
@@ -0,0 +1,853 @@
+# Commands covered:  scan
+#
+# This file contains a collection of tests for one or more of the Tcl built-in
+# commands.  Sourcing this file into Tcl runs the tests and generates output
+# for errors.  No output means no errors were found.
+#
+# Copyright (c) 1991-1994 The Regents of the University of California.
+# Copyright (c) 1994-1997 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {"::tcltest" ni [namespace children]} {
+    package require tcltest 2
+    namespace import -force ::tcltest::*
+}
+
+# procedure that returns the range of integers
+
+proc int_range {} {
+    for { set MIN_INT 1 } { int($MIN_INT) > 0 } {} {
+	set MIN_INT [expr { $MIN_INT << 1 }]
+    }
+    set MIN_INT [expr {int($MIN_INT)}]
+    set MAX_INT [expr { ~ $MIN_INT }]
+    return [list $MIN_INT $MAX_INT]
+}
+
+# Big test for correct ordering of data in [expr]
+
+proc testIEEE {} {
+    variable ieeeValues
+    binary scan [binary format dd -1.0 1.0] c* c
+    switch -exact -- $c {
+	{0 0 0 0 0 0 -16 -65 0 0 0 0 0 0 -16 63} {
+	    # little endian
+	    binary scan \x00\x00\x00\x00\x00\x00\xf0\xff d \
+		ieeeValues(-Infinity)
+	    binary scan \x00\x00\x00\x00\x00\x00\xf0\xbf d \
+		ieeeValues(-Normal)
+	    binary scan \x00\x00\x00\x00\x00\x00\x08\x80 d \
+		ieeeValues(-Subnormal)
+	    binary scan \x00\x00\x00\x00\x00\x00\x00\x80 d \
+		ieeeValues(-0)
+	    binary scan \x00\x00\x00\x00\x00\x00\x00\x00 d \
+		ieeeValues(+0)
+	    binary scan \x00\x00\x00\x00\x00\x00\x08\x00 d \
+		ieeeValues(+Subnormal)
+	    binary scan \x00\x00\x00\x00\x00\x00\xf0\x3f d \
+		ieeeValues(+Normal)
+	    binary scan \x00\x00\x00\x00\x00\x00\xf0\x7f d \
+		ieeeValues(+Infinity)
+	    binary scan \x00\x00\x00\x00\x00\x00\xf8\x7f d \
+		ieeeValues(NaN)
+	    set ieeeValues(littleEndian) 1
+	    return 1
+	}
+	{-65 -16 0 0 0 0 0 0 63 -16 0 0 0 0 0 0} {
+	    binary scan \xff\xf0\x00\x00\x00\x00\x00\x00 d \
+		ieeeValues(-Infinity)
+	    binary scan \xbf\xf0\x00\x00\x00\x00\x00\x00 d \
+		ieeeValues(-Normal)
+	    binary scan \x80\x08\x00\x00\x00\x00\x00\x00 d \
+		ieeeValues(-Subnormal)
+	    binary scan \x80\x00\x00\x00\x00\x00\x00\x00 d \
+		ieeeValues(-0)
+	    binary scan \x00\x00\x00\x00\x00\x00\x00\x00 d \
+		ieeeValues(+0)
+	    binary scan \x00\x08\x00\x00\x00\x00\x00\x00 d \
+		ieeeValues(+Subnormal)
+	    binary scan \x3f\xf0\x00\x00\x00\x00\x00\x00 d \
+		ieeeValues(+Normal)
+	    binary scan \x7f\xf0\x00\x00\x00\x00\x00\x00 d \
+		ieeeValues(+Infinity)
+	    binary scan \x7f\xf8\x00\x00\x00\x00\x00\x00 d \
+		ieeeValues(NaN)
+	    set ieeeValues(littleEndian) 0
+	    return 1
+	}
+	default {
+	    return 0
+	}
+    }
+}
+
+testConstraint ieeeFloatingPoint [testIEEE]
+testConstraint wideIs64bit \
+	[expr {(wide(0x80000000) > 0) && (wide(0x8000000000000000) < 0)}]
+
+test scan-1.1 {BuildCharSet, CharInSet} {
+    list [scan foo {%[^o]} x] $x
+} {1 f}
+test scan-1.2 {BuildCharSet, CharInSet} {
+    list [scan \]foo {%[]f]} x] $x
+} {1 \]f}
+test scan-1.3 {BuildCharSet, CharInSet} {
+    list [scan abc-def {%[a-c]} x] $x
+} {1 abc}
+test scan-1.4 {BuildCharSet, CharInSet} {
+    list [scan abc-def {%[a-c]} x] $x
+} {1 abc}
+test scan-1.5 {BuildCharSet, CharInSet} {
+    list [scan -abc-def {%[-ac]} x] $x
+} {1 -a}
+test scan-1.6 {BuildCharSet, CharInSet} {
+    list [scan -abc-def {%[ac-]} x] $x
+} {1 -a}
+test scan-1.7 {BuildCharSet, CharInSet} {
+    list [scan abc-def {%[c-a]} x] $x
+} {1 abc}
+test scan-1.8 {BuildCharSet, CharInSet} {
+    list [scan def-abc {%[^c-a]} x] $x
+} {1 def-}
+test scan-1.9 {BuildCharSet, CharInSet no match} -setup {
+    unset -nocomplain x
+} -body {
+    list [scan {= f} {= %[TF]} x] [info exists x]
+} -result {0 0}
+
+test scan-2.1 {ReleaseCharSet} {
+    list [scan abcde {%[abc]} x] $x
+} {1 abc}
+test scan-2.2 {ReleaseCharSet} {
+    list [scan abcde {%[a-c]} x] $x
+} {1 abc}
+
+test scan-3.1 {ValidateFormat} -returnCodes error -body {
+    scan {} {%d%1$d} x
+} -result {cannot mix "%" and "%n$" conversion specifiers}
+test scan-3.2 {ValidateFormat} -returnCodes error -body {
+    scan {} {%d%1$d} x
+} -result {cannot mix "%" and "%n$" conversion specifiers}
+test scan-3.3 {ValidateFormat} -returnCodes error -body {
+    scan {} {%2$d%d} x
+} -result {"%n$" argument index out of range}
+test scan-3.4 {ValidateFormat} {
+    # degenerate case, before changed from 8.2 to 8.3
+    list [catch {scan {} %d} msg] $msg
+} {0 {}}
+test scan-3.5 {ValidateFormat} -returnCodes error -body {
+    scan {} {%10c} a
+} -result {field width may not be specified in %c conversion}
+test scan-3.6 {ValidateFormat} -returnCodes error -body {
+    scan {} {%*1$d} a
+} -result {bad scan conversion character "$"}
+test scan-3.7 {ValidateFormat} -returnCodes error -body {
+    scan {} {%1$d%1$d} a
+} -result {variable is assigned by multiple "%n$" conversion specifiers}
+test scan-3.8 {ValidateFormat} -returnCodes error -body {
+    scan {} a x
+} -result {variable is not assigned by any conversion specifiers}
+test scan-3.9 {ValidateFormat} -returnCodes error -body {
+    scan {} {%2$s} x y
+} -result {variable is not assigned by any conversion specifiers}
+test scan-3.10 {ValidateFormat} -returnCodes error -body {
+    scan {} {%[a} x
+} -result {unmatched [ in format string}
+test scan-3.11 {ValidateFormat} -returnCodes error -body {
+    scan {} {%[^a} x
+} -result {unmatched [ in format string}
+test scan-3.12 {ValidateFormat} -returnCodes error -body {
+    scan {} {%[]a} x
+} -result {unmatched [ in format string}
+test scan-3.13 {ValidateFormat} -returnCodes error -body {
+    scan {} {%[^]a} x
+} -result {unmatched [ in format string}
+
+test scan-4.1 {Tcl_ScanObjCmd, argument checks} -returnCodes error -body {
+    scan
+} -result {wrong # args: should be "scan string format ?varName ...?"}
+test scan-4.2 {Tcl_ScanObjCmd, argument checks} -returnCodes error -body {
+    scan string
+} -result {wrong # args: should be "scan string format ?varName ...?"}
+test scan-4.3 {Tcl_ScanObjCmd, argument checks} {
+    # degenerate case, before changed from 8.2 to 8.3
+    list [catch {scan string format} msg] $msg
+} {0 {}}
+test scan-4.4 {Tcl_ScanObjCmd, whitespace} {
+    list [scan {   abc   def   } {%s%s} x y] $x $y
+} {2 abc def}
+test scan-4.5 {Tcl_ScanObjCmd, whitespace} {
+    list [scan {   abc   def   } { %s %s } x y] $x $y
+} {2 abc def}
+test scan-4.6 {Tcl_ScanObjCmd, whitespace} {
+    list [scan {   abc   def   } { %s %s } x y] $x $y
+} {2 abc def}
+test scan-4.7 {Tcl_ScanObjCmd, literals} {
+    # degenerate case, before changed from 8.2 to 8.3
+    scan {   abc   def   } { abc def }
+} {}
+test scan-4.8 {Tcl_ScanObjCmd, literals} {
+    set x {}
+    list [scan {   abcg} { abc def %1s} x] $x
+} {0 {}}
+test scan-4.9 {Tcl_ScanObjCmd, literals} {
+    list [scan {   abc%defghi} { abc %% def%n } x] $x
+} {1 10}
+test scan-4.10 {Tcl_ScanObjCmd, assignment suppression} {
+    list [scan {   abc   def   } { %*c%s def } x] $x
+} {1 bc}
+test scan-4.11 {Tcl_ScanObjCmd, XPG3-style} {
+    list [scan {   abc   def   } {%2$s %1$s} x y] $x $y
+} {2 def abc}
+test scan-4.12 {Tcl_ScanObjCmd, width specifiers} {
+    list [scan {abc123456789012} {%3s%3d%3f%3[0-9]%s} a b c d e] $a $b $c $d $e
+} {5 abc 123 456.0 789 012}
+test scan-4.13 {Tcl_ScanObjCmd, width specifiers} {
+    list [scan {abc123456789012} {%3s%3d%3f%3[0-9]%s} a b c d e] $a $b $c $d $e
+} {5 abc 123 456.0 789 012}
+test scan-4.14 {Tcl_ScanObjCmd, underflow} {
+    set x {}
+    list [scan {a} {a%d} x] $x
+} {-1 {}}
+test scan-4.15 {Tcl_ScanObjCmd, underflow} {
+    set x {}
+    list [scan {} {a%d} x] $x
+} {-1 {}}
+test scan-4.16 {Tcl_ScanObjCmd, underflow} {
+    set x {}
+    list [scan {ab} {a%d} x] $x
+} {0 {}}
+test scan-4.17 {Tcl_ScanObjCmd, underflow} {
+    set x {}
+    list [scan {a   } {a%d} x] $x
+} {-1 {}}
+test scan-4.18 {Tcl_ScanObjCmd, skipping whitespace} {
+    list [scan {  b} {%c%s} x y] $x $y
+} {2 32 b}
+test scan-4.19 {Tcl_ScanObjCmd, skipping whitespace} {
+    list [scan {  b} {%[^b]%s} x y] $x $y
+} {2 {  } b}
+test scan-4.20 {Tcl_ScanObjCmd, string scanning} {
+    list [scan {abc def} {%s} x] $x
+} {1 abc}
+test scan-4.21 {Tcl_ScanObjCmd, string scanning} {
+    list [scan {abc def} {%0s} x] $x
+} {1 abc}
+test scan-4.22 {Tcl_ScanObjCmd, string scanning} {
+    list [scan {abc def} {%2s} x] $x
+} {1 ab}
+test scan-4.23 {Tcl_ScanObjCmd, string scanning} {
+    list [scan {abc def} {%*s%n} x] $x
+} {1 3}
+test scan-4.24 {Tcl_ScanObjCmd, charset scanning} {
+    list [scan {abcdef} {%[a-c]} x] $x
+} {1 abc}
+test scan-4.25 {Tcl_ScanObjCmd, charset scanning} {
+    list [scan {abcdef} {%0[a-c]} x] $x
+} {1 abc}
+test scan-4.26 {Tcl_ScanObjCmd, charset scanning} {
+    list [scan {abcdef} {%2[a-c]} x] $x
+} {1 ab}
+test scan-4.27 {Tcl_ScanObjCmd, charset scanning} {
+    list [scan {abcdef} {%*[a-c]%n} x] $x
+} {1 3}
+test scan-4.28 {Tcl_ScanObjCmd, character scanning} {
+    list [scan {abcdef} {%c} x] $x
+} {1 97}
+test scan-4.29 {Tcl_ScanObjCmd, character scanning} {
+    list [scan {abcdef} {%*c%n} x] $x
+} {1 1}
+
+test scan-4.30 {Tcl_ScanObjCmd, base-10 integer scanning} -setup {
+    set x {}
+} -body {
+    list [scan {1234567890a} {%3d} x] $x
+} -result {1 123}
+test scan-4.31 {Tcl_ScanObjCmd, base-10 integer scanning} -setup {
+    set x {}
+} -body {
+    list [scan {1234567890a} {%d} x] $x
+} -result {1 1234567890}
+test scan-4.32 {Tcl_ScanObjCmd, base-10 integer scanning} -setup {
+    set x {}
+} -body {
+    list [scan {01234567890a} {%d} x] $x
+} -result {1 1234567890}
+test scan-4.33 {Tcl_ScanObjCmd, base-10 integer scanning} -setup {
+    set x {}
+} -body {
+    list [scan {+01234} {%d} x] $x
+} -result {1 1234}
+test scan-4.34 {Tcl_ScanObjCmd, base-10 integer scanning} -setup {
+    set x {}
+} -body {
+    list [scan {-01234} {%d} x] $x
+} -result {1 -1234}
+test scan-4.35 {Tcl_ScanObjCmd, base-10 integer scanning} -setup {
+    set x {}
+} -body {
+    list [scan {a01234} {%d} x] $x
+} -result {0 {}}
+test scan-4.36 {Tcl_ScanObjCmd, base-10 integer scanning} -setup {
+    set x {}
+} -body {
+    list [scan {0x10} {%d} x] $x
+} -result {1 0}
+test scan-4.37 {Tcl_ScanObjCmd, base-8 integer scanning} -setup {
+    set x {}
+} -body {
+    list [scan {012345678} {%o} x] $x
+} -result {1 342391}
+test scan-4.38 {Tcl_ScanObjCmd, base-8 integer scanning} -setup {
+    set x {}
+} -body {
+    list [scan {+1238 -1239 123a} {%o%*s%o%*s%o} x y z] $x $y $z
+} -result {3 83 -83 83}
+test scan-4.39 {Tcl_ScanObjCmd, base-16 integer scanning} -setup {
+    set x {}
+} -body {
+    list [scan {+1238 -123a 0123} {%x%x%x} x y z] $x $y $z
+} -result {3 4664 -4666 291}
+test scan-4.40 {Tcl_ScanObjCmd, base-16 integer scanning} -setup {
+    set x {}
+} -body {
+    # The behavior changed in 8.4a4/8.3.4cvs (6 Feb) to correctly
+    # return '1' for 0x1 scanned via %x, to comply with 8.0 and C scanf.
+    # Bug #495213
+    list [scan {aBcDeF AbCdEf 0x1} {%x%x%x} x y z] $x $y $z
+} -result {3 11259375 11259375 1}
+test scan-4.40.1 {Tcl_ScanObjCmd, base-16 integer scanning} -setup {
+    set x {}
+} -body {
+    list [scan {0xF 0x00A0B 0X0XF} {%x %x %x} x y z] $x $y $z
+} -result {3 15 2571 0}
+test scan-4.40.2 {Tcl_ScanObjCmd, base-16 integer scanning} -setup {
+    unset -nocomplain x
+} -body {
+    list [scan {xF} {%x} x] [info exists x]
+} -result {0 0}
+test scan-4.40.3 {Tcl_ScanObjCmd, base-2 integer scanning} -setup {
+    set x {}
+} -body {
+    list [scan {1001 0b101 100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000} {%b %b %llb} x y z] $x $y $z
+} -result {3 9 5 340282366920938463463374607431768211456}
+test scan-4.41 {Tcl_ScanObjCmd, base-unknown integer scanning} -setup {
+    set x {}
+} -body {
+    list [scan {10 010 0x10 0b10} {%i%i%i%i} x y z t] $x $y $z $t
+} -result {4 10 8 16 0}
+test scan-4.42 {Tcl_ScanObjCmd, base-unknown integer scanning} -setup {
+    set x {}
+} -body {
+    list [scan {10 010 0X10} {%i%i%i} x y z] $x $y $z
+} -result {3 10 8 16}
+test scan-4.43 {Tcl_ScanObjCmd, integer scanning, odd cases} -setup {
+    set x {}
+} -body {
+    list [scan {+ } {%i} x] $x
+} -result {0 {}}
+test scan-4.44 {Tcl_ScanObjCmd, integer scanning, odd cases} -setup {
+    set x {}
+} -body {
+    list [scan {+} {%i} x] $x
+} -result {-1 {}}
+test scan-4.45 {Tcl_ScanObjCmd, integer scanning, odd cases} -setup {
+    set x {}
+} -body {
+    list [scan {0x} {%i%s} x y] $x $y
+} -result {2 0 x}
+test scan-4.46 {Tcl_ScanObjCmd, integer scanning, odd cases} -setup {
+    set x {}
+} -body {
+    list [scan {0X} {%i%s} x y] $x $y
+} -result {2 0 X}
+test scan-4.47 {Tcl_ScanObjCmd, integer scanning, suppressed} -setup {
+    set x {}
+} -body {
+    list [scan {123def} {%*i%s} x] $x
+} -result {1 def}
+test scan-4.48 {Tcl_ScanObjCmd, float scanning} {
+    list [scan {1 2 3} {%e %f %g} x y z] $x $y $z
+} {3 1.0 2.0 3.0}
+test scan-4.49 {Tcl_ScanObjCmd, float scanning} {
+    list [scan {.1 0.2 3.} {%e %f %g} x y z] $x $y $z
+} {3 0.1 0.2 3.0}
+test scan-4.49-uc-1 {Tcl_ScanObjCmd, float scanning} {
+    list [scan {0.5*0.75} {%E%c%G} x y z] $x $y $z
+} {3 0.5 42 0.75}
+test scan-4.49-uc-2 {Tcl_ScanObjCmd, float scanning} {
+    list [scan {5e-1*75E-2} {%E%c%G} x y z] $x $y $z
+} {3 0.5 42 0.75}
+test scan-4.50 {Tcl_ScanObjCmd, float scanning} {
+    list [scan {1234567890a} %f x] $x
+} {1 1234567890.0}
+test scan-4.51 {Tcl_ScanObjCmd, float scanning} {
+    list [scan {+123+45} %f x] $x
+} {1 123.0}
+test scan-4.52 {Tcl_ScanObjCmd, float scanning} {
+    list [scan {-123+45} %f x] $x
+} {1 -123.0}
+test scan-4.53 {Tcl_ScanObjCmd, float scanning} {
+    list [scan {1.0e1} %f x] $x
+} {1 10.0}
+test scan-4.54 {Tcl_ScanObjCmd, float scanning} {
+    list [scan {1.0e-1} %f x] $x
+} {1 0.1}
+test scan-4.55 {Tcl_ScanObjCmd, odd cases} -setup {
+    set x {}
+} -body {
+    list [scan {+} %f x] $x
+} -result {-1 {}}
+test scan-4.56 {Tcl_ScanObjCmd, odd cases} -setup {
+    set x {}
+} -body {
+    list [scan {1.0e} %f%s x y] $x $y
+} -result {2 1.0 e}
+test scan-4.57 {Tcl_ScanObjCmd, odd cases} -setup {
+    set x {}
+} -body {
+    list [scan {1.0e+} %f%s x y] $x $y
+} -result {2 1.0 e+}
+test scan-4.58 {Tcl_ScanObjCmd, odd cases} -setup {
+    set x {}
+    set y {}
+} -body {
+    list [scan {e1} %f%s x y] $x $y
+} -result {0 {} {}}
+test scan-4.59 {Tcl_ScanObjCmd, float scanning} {
+    list [scan {1.0e-1x} %*f%n x] $x
+} {1 6}
+
+test scan-4.60 {Tcl_ScanObjCmd, set errors} -setup {
+    set x {}
+    set y {}
+    unset -nocomplain z
+} -body {
+    array set z {}
+    list [catch {scan {abc def ghi} {%s%s%s} x z y} msg] $msg $x $y
+} -cleanup {
+    unset -nocomplain z
+} -result {1 {can't set "z": variable is array} abc ghi}
+test scan-4.61 {Tcl_ScanObjCmd, set errors} -setup {
+    set x {}
+    unset -nocomplain y
+    unset -nocomplain z
+} -body {
+    array set y {}
+    array set z {}
+    list [catch {scan {abc def ghi} {%s%s%s} x z y} msg] $msg $x
+} -cleanup {
+    unset -nocomplain y
+    unset -nocomplain z
+} -result {1 {can't set "z": variable is array} abc}
+
+test scan-4.62 {scanning of large and negative octal integers} {
+    lassign [int_range] MIN_INT MAX_INT
+    set scanstring [format {%o %o %o} -1 $MIN_INT $MAX_INT]
+    list [scan $scanstring {%o %o %o} a b c] \
+	[expr { $a == -1 }] [expr { $b == $MIN_INT }] [expr { $c == $MAX_INT }]
+} {3 1 1 1}
+test scan-4.63 {scanning of large and negative hex integers} {
+    lassign [int_range] MIN_INT MAX_INT
+    set scanstring [format {%x %x %x} -1 $MIN_INT $MAX_INT]
+    list [scan $scanstring {%x %x %x} a b c] \
+	[expr { $a == -1 }] [expr { $b == $MIN_INT }] [expr { $c == $MAX_INT }]
+} {3 1 1 1}
+test scan-4.64 {scanning of hex with %X} {
+    scan "123 abc f78" %X%X%X
+} {291 2748 3960}
+
+test scan-5.1 {integer scanning} -setup {
+    set a {}; set b {}; set c {}; set d {}
+} -body {
+    list [scan "-20 1476 \n33 0" "%d %d %d %d" a b c d] $a $b $c $d
+} -result {4 -20 1476 33 0}
+test scan-5.2 {integer scanning} -setup {
+    set a {}; set b {}; set c {}
+} -body {
+    list [scan "-45 16 7890 +10" "%2d %*d %10d %d" a b c] $a $b $c
+} -result {3 -4 16 7890}
+test scan-5.3 {integer scanning} -setup {
+    set a {}; set b {}; set c {}; set d {}
+} -body {
+    list [scan "-45 16 +10 987" "%ld %d %ld %d" a b c d] $a $b $c $d
+} -result {4 -45 16 10 987}
+test scan-5.4 {integer scanning} -setup {
+    set a {}; set b {}; set c {}; set d {}
+} -body {
+    list [scan "14 1ab 62 10" "%d %x %lo %x" a b c d] $a $b $c $d
+} -result {4 14 427 50 16}
+test scan-5.5 {integer scanning} -setup {
+    set a {}; set b {}; set c {}; set d {}
+} -body {
+    list [scan "12345670 1234567890ab cdefg" "%o	 %o %x %lx" a b c d] \
+	    $a $b $c $d
+} -result {4 2739128 342391 561323 52719}
+test scan-5.6 {integer scanning} -setup {
+    set a {}; set b {}; set c {}; set d {}
+} -body {
+    list [scan "ab123-24642" "%2x %3x %3o %2o" a b c d] $a $b $c $d
+} -result {4 171 291 -20 52}
+test scan-5.7 {integer scanning} -setup {
+    set a {}; set b {}
+} -body {
+    list [scan "1234567 234 567  " "%*3x %x %*o %4o" a b] $a $b
+} -result {2 17767 375}
+test scan-5.8 {integer scanning} -setup {
+    set a {}; set b {}
+} -body {
+    list [scan "a	1234" "%d %d" a b] $a $b
+} -result {0 {} {}}
+test scan-5.9 {integer scanning} -setup {
+    set a {}; set b {}; set c {}; set d {}
+} -body {
+    list [scan "12345678" "%2d %2d %2ld %2d" a b c d] $a $b $c $d
+} -result {4 12 34 56 78}
+test scan-5.10 {integer scanning} -setup {
+    set a {}; set b {}; set c {}; set d {}
+} -body {
+    list [scan "1 2 " "%hd %d %d %d" a b c d] $a $b $c $d
+} -result {2 1 2 {} {}}
+#
+# The behavior for scaning intergers larger than MAX_INT is not defined by the
+# ANSI spec.  Some implementations wrap the input (-16) some return MAX_INT.
+#
+test scan-5.11 {integer scanning} -constraints {nonPortable} -setup {
+    set a {}; set b {}
+} -body {
+    list [scan "4294967280 4294967280" "%u %d" a b] $a \
+	    [expr {$b == -16 || $b == 0x7fffffff}]
+} -result {2 4294967280 1}
+test scan-5.12 {integer scanning} -constraints {wideIs64bit} -setup {
+    set a {}; set b {}; set c {}
+} -body {
+    list [scan "7810179016327718216,6c63546f6c6c6548,661432506755433062510" \
+	    %ld,%lx,%lo a b c] $a $b $c
+} -result {3 7810179016327718216 7810179016327718216 7810179016327718216}
+test scan-5.13 {integer scanning and overflow} {
+    # This test used to fail on some 64-bit systems. [Bug 1011860]
+    scan {300000000 3000000000 30000000000} {%ld %ld %ld}
+} {300000000 3000000000 30000000000}
+
+test scan-5.14 {integer scanning} {
+    scan 0xff %u
+} 0
+
+test scan-6.1 {floating-point scanning} -setup {
+    set a {}; set b {}; set c {}; set d {}
+} -body {
+    list [scan "2.1 -3.0e8 .99962 a" "%f%g%e%f" a b c d] $a $b $c $d
+} -result {3 2.1 -300000000.0 0.99962 {}}
+test scan-6.2 {floating-point scanning} -setup {
+    set a {}; set b {}; set c {}; set d {}
+} -body {
+    list [scan "-1.2345 +8.2 9" "%3e %3lf %f %f" a b c d] $a $b $c $d
+} -result {4 -1.0 234.0 5.0 8.2}
+test scan-6.3 {floating-point scanning} -setup {
+    set a {}; set b {}; set c {}
+} -body {
+    list [scan "1e00004 332E-4 3e+4" "%Lf %*2e %f %f" a b c] $a $c
+} -result {3 10000.0 30000.0}
+#
+# Some libc implementations consider 3.e- bad input.  The ANSI spec states
+# that digits must follow the - sign.
+#
+test scan-6.4 {floating-point scanning} -setup {
+    set a {}; set b {}; set c {}
+} -body {
+    list [scan "1. 47.6 2.e2 3.e-" "%f %*f %f %f" a b c] $a $b $c
+} -result {3 1.0 200.0 3.0}
+test scan-6.5 {floating-point scanning} -setup {
+    set a {}; set b {}; set c {}; set d {}
+} -body {
+    list [scan "4.6 99999.7 876.43e-1 118" "%f %f %f %e" a b c d] $a $b $c $d
+} -result {4 4.6 99999.7 87.643 118.0}
+test scan-6.6 {floating-point scanning} -setup {
+    set a {}; set b {}; set c {}; set d {}
+} -body {
+    list [scan "1.2345 697.0e-3 124 .00005" "%f %e %f %e" a b c d] $a $b $c $d
+} -result {4 1.2345 0.697 124.0 5e-5}
+test scan-6.7 {floating-point scanning} -setup {
+    set a {}; set b {}; set c {}; set d {}
+} -body {
+    list [scan "4.6abc" "%f %f %f %f" a b c d] $a $b $c $d
+} -result {1 4.6 {} {} {}}
+test scan-6.8 {floating-point scanning} -setup {
+    set a {}; set b {}; set c {}; set d {}
+} -body {
+    list [scan "4.6 5.2" "%f %f %f %f" a b c d] $a $b $c $d
+} -result {2 4.6 5.2 {} {}}
+
+test scan-7.1 {string and character scanning} -setup {
+    set a {}; set b {}; set c {}; set d {}
+} -body {
+    list [scan "abc defghijk dum " "%s %3s %20s %s" a b c d] $a $b $c $d
+} -result {4 abc def ghijk dum}
+test scan-7.2 {string and character scanning} -setup {
+    set a {}; set b {}; set c {}; set d {}
+} -body {
+    list [scan "a       bcdef" "%c%c%1s %s" a b c d] $a $b $c $d
+} -result {4 97 32 b cdef}
+test scan-7.3 {string and character scanning} -setup {
+    set a {}; set b {}; set c {}
+} -body {
+    list [scan "123456 test " "%*c%*s %s %s %s" a b c] $a $b $c
+} -result {1 test {} {}}
+test scan-7.4 {string and character scanning} -setup {
+    set a {}; set b {}; set c {}; set d {}
+} -body {
+    list [scan "ababcd01234  f 123450" {%4[abcd] %4[abcd] %[^abcdef] %[^0]} a b c d] $a $b $c $d
+} -result {4 abab cd {01234  } {f 12345}}
+test scan-7.5 {string and character scanning} -setup {
+    set a {}; set b {}; set c {}
+} -body {
+    list [scan "aaaaaabc aaabcdefg  + +  XYZQR" {%*4[a] %s %*4[a]%s%*4[ +]%c} a b c] $a $b $c
+} -result {3 aabc bcdefg 43}
+test scan-7.6 {string and character scanning, unicode} -setup {
+    set a {}; set b {}; set c {}; set d {}
+} -body {
+    list [scan "abc d\u00c7fghijk dum " "%s %3s %20s %s" a b c d] $a $b $c $d
+} -result "4 abc d\u00c7f ghijk dum"
+test scan-7.7 {string and character scanning, unicode} -setup {
+    set a {}; set b {}
+} -body {
+    list [scan "ab\u00c7cdef" "ab%c%c" a b] $a $b
+} -result "2 199 99"
+test scan-7.8 {string and character scanning, unicode} -setup {
+    set a {}; set b {}
+} -body {
+    list [scan "ab\ufeffdef" "%\[ab\ufeff\]" a] $a
+} -result "1 ab\ufeff"
+
+test scan-8.1 {error conditions} -body {
+    scan a
+} -returnCodes error -match glob -result *
+test scan-8.2 {error conditions} -returnCodes error -body {
+    scan a
+} -result {wrong # args: should be "scan string format ?varName ...?"}
+test scan-8.3 {error conditions} -returnCodes error -body {
+    scan a %D x
+} -result {bad scan conversion character "D"}
+test scan-8.4 {error conditions} -returnCodes error -body {
+    scan a %O x
+} -result {bad scan conversion character "O"}
+test scan-8.5 {error conditions} -returnCodes error -body {
+    scan a %B x
+} -result {bad scan conversion character "B"}
+test scan-8.6 {error conditions} -returnCodes error -body {
+    scan a %F x
+} -result {bad scan conversion character "F"}
+test scan-8.7 {error conditions} -returnCodes error -body {
+    scan a %p x
+} -result {bad scan conversion character "p"}
+test scan-8.8 {error conditions} -returnCodes error -body {
+    scan a "%d %d" a
+} -result {different numbers of variable names and field specifiers}
+test scan-8.9 {error conditions} -returnCodes error -body {
+    scan a "%d %d" a b c
+} -result {variable is not assigned by any conversion specifiers}
+test scan-8.10 {error conditions} -setup {
+    set a {}; set b {}; set c {}; set d {}
+} -body {
+    list [expr {[scan "  a" " a %d %d %d %d" a b c d] <= 0}] $a $b $c $d
+} -result {1 {} {} {} {}}
+test scan-8.11 {error conditions} -setup {
+    set a {}; set b {}; set c {}; set d {}
+} -body {
+    list [scan "1 2" "%d %d %d %d" a b c d] $a $b $c $d
+} -result {2 1 2 {} {}}
+test scan-8.12 {error conditions} -setup {
+    unset -nocomplain a
+} -body {
+    set a(0) 44
+    scan 44 %d a
+} -returnCodes error -cleanup {
+    unset -nocomplain a
+} -result {can't set "a": variable is array}
+test scan-8.13 {error conditions} -setup {
+    unset -nocomplain a
+} -body {
+    set a(0) 44
+    scan 44 %c a
+} -returnCodes error -cleanup {
+    unset -nocomplain a
+} -result {can't set "a": variable is array}
+test scan-8.14 {error conditions} -setup {
+    unset -nocomplain a
+} -body {
+    set a(0) 44
+    scan 44 %s a
+} -returnCodes error -cleanup {
+    unset -nocomplain a
+} -result {can't set "a": variable is array}
+test scan-8.15 {error conditions} -setup {
+    unset -nocomplain a
+} -body {
+    set a(0) 44
+    scan 44 %f a
+} -returnCodes error -cleanup {
+    unset -nocomplain a
+} -result {can't set "a": variable is array}
+test scan-8.16 {error conditions} -setup {
+    unset -nocomplain a
+} -body {
+    set a(0) 44
+    scan 44 %f a
+} -returnCodes error -cleanup {
+    unset -nocomplain a
+} -result {can't set "a": variable is array}
+test scan-8.17 {error conditions} -returnCodes error -body {
+    scan 44 %2c a
+} -result {field width may not be specified in %c conversion}
+test scan-8.18 {error conditions} -returnCodes error -body {
+    scan abc {%[} x
+} -result {unmatched [ in format string}
+test scan-8.19 {error conditions} -returnCodes error -body {
+    scan abc {%[^a} x
+} -result {unmatched [ in format string}
+test scan-8.20 {error conditions} -returnCodes error -body {
+    scan abc {%[^]a} x
+} -result {unmatched [ in format string}
+test scan-8.21 {error conditions} -returnCodes error -body {
+    scan abc {%[]a} x
+} -result {unmatched [ in format string}
+
+test scan-9.1 {lots of arguments} {
+    scan "10 20 30 40 50 60 70 80 90 100 110 120 130 140 150 160 170 180 190 200" "%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d" a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15 a16 a17 a18 a19 a20
+} 20
+test scan-9.2 {lots of arguments} {
+    scan "10 20 30 40 50 60 70 80 90 100 110 120 130 140 150 160 170 180 190 200" "%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d" a1 a2 a3 a4 a5 a6 a7 a8 a9 a10 a11 a12 a13 a14 a15 a16 a17 a18 a19 a20
+    set a20
+} 200
+
+test scan-10.1 {miscellaneous tests} -setup {
+    set a {}
+} -body {
+    list [scan ab16c ab%dc a] $a
+} -result {1 16}
+test scan-10.2 {miscellaneous tests} -setup {
+    set a {}
+} -body {
+    list [scan ax16c ab%dc a] $a
+} -result {0 {}}
+test scan-10.3 {miscellaneous tests} -setup {
+    set a {}
+} -body {
+    list [catch {scan ab%c114 ab%%c%d a} msg] $msg $a
+} -result {0 1 114}
+test scan-10.4 {miscellaneous tests} -setup {
+    set a {}
+} -body {
+    list [catch {scan ab%c14 ab%%c%d a} msg] $msg $a
+} -result {0 1 14}
+test scan-10.5 {miscellaneous tests} -setup {
+    unset -nocomplain arr
+} -body {
+    set arr(2) {}
+    list [catch {scan ab%c14 ab%%c%d arr(2)} msg] $msg $arr(2)
+} -result {0 1 14}
+test scan-10.6 {miscellaneous tests} {
+    scan 5a {%i%[a]}
+} {5 a}
+test scan-10.7 {miscellaneous tests} {
+    scan {5 a} {%i%[a]}
+} {5 {}}
+
+test scan-11.1 {alignment in results array (TCL_ALIGN)} {
+    scan "123 13.6" "%s %f" a b
+    set b
+} 13.6
+test scan-11.2 {alignment in results array (TCL_ALIGN)} {
+    scan "1234567 13.6" "%s %f" a b
+    set b
+} 13.6
+test scan-11.3 {alignment in results array (TCL_ALIGN)} {
+    scan "12345678901 13.6" "%s %f" a b
+    set b
+} 13.6
+test scan-11.4 {alignment in results array (TCL_ALIGN)} {
+    scan "123456789012345 13.6" "%s %f" a b
+    set b
+} 13.6
+test scan-11.5 {alignment in results array (TCL_ALIGN)} {
+    scan "1234567890123456789 13.6" "%s %f" a b
+    set b
+} 13.6
+
+test scan-12.1 {Tcl_ScanObjCmd, inline case} {
+    scan a %c
+} 97
+test scan-12.2 {Tcl_ScanObjCmd, inline case} {
+    scan abc %c%c%c%c
+} {97 98 99 {}}
+test scan-12.3 {Tcl_ScanObjCmd, inline case} {
+    scan abc %s%c
+} {abc {}}
+test scan-12.4 {Tcl_ScanObjCmd, inline case, underflow} {
+    scan abc abc%c
+} {}
+test scan-12.5 {Tcl_ScanObjCmd, inline case} {
+    scan abc bogus%c%c%c
+} {{} {} {}}
+test scan-12.6 {Tcl_ScanObjCmd, inline case} {
+    # degenerate case, behavior changed from 8.2 to 8.3
+    list [catch {scan foo foobar} msg] $msg
+} {0 {}}
+test scan-12.7 {Tcl_ScanObjCmd, inline case lots of arguments} {
+    scan "10 20 30 40 50 60 70 80 90 100 110 120 130 140\
+	    150 160 170 180 190 200" \
+	    "%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d"
+} {10 20 30 40 50 60 70 80 90 100 110 120 130 140 150 160 170 180 190 200 {}}
+
+test scan-13.1 {Tcl_ScanObjCmd, inline XPG case} {
+    scan a {%1$c}
+} 97
+test scan-13.2 {Tcl_ScanObjCmd, inline XPG case} {
+    scan abc {%1$c%2$c%3$c%4$c}
+} {97 98 99 {}}
+test scan-13.3 {Tcl_ScanObjCmd, inline XPG case} -returnCodes error -body {
+    scan abc {%1$c%1$c}
+} -result {variable is assigned by multiple "%n$" conversion specifiers}
+test scan-13.4 {Tcl_ScanObjCmd, inline XPG case} {
+    scan abc {%2$s%1$c}
+} {{} abc}
+test scan-13.5 {Tcl_ScanObjCmd, inline XPG case, underflow} {
+    scan abc {abc%5$c}
+} {}
+test scan-13.6 {Tcl_ScanObjCmd, inline XPG case} {
+    catch {scan abc {bogus%1$c%5$c%10$c}} msg
+    list [llength $msg] $msg
+} {10 {{} {} {} {} {} {} {} {} {} {}}}
+test scan-13.7 {Tcl_ScanObjCmd, inline XPG case lots of arguments} {
+    scan "10 20 30 40 50 60 70 80 90 100 110 120 130 140 150 160 170 180 190 200" {%20$d %18$d %17$d %16$d %15$d %14$d %13$d %12$d %11$d %10$d %9$d %8$d %7$d %6$d %5$d %4$d %3$d %2$d %1$d}
+} {190 180 170 160 150 140 130 120 110 100 90 80 70 60 50 40 30 20 {} 10}
+test scan-13.8 {Tcl_ScanObjCmd, inline XPG case lots of arguments} {
+    set msg [scan "10 20 30" {%100$d %5$d %200$d}]
+    list [llength $msg] [lindex $msg 99] [lindex $msg 4] [lindex $msg 199]
+} {200 10 20 30}
+
+# scan infinities - not working
+
+test scan-14.1 {positive infinity} {
+    scan Inf %g d
+    return $d
+} Inf
+test scan-14.2 {negative infinity} {
+    scan -Inf %g d
+    return $d
+} -Inf
+
+# TODO - also need to scan NaN's
+
+catch {rename int_range {}}
+
+# cleanup
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/tests/security.test b/tests/security.test
new file mode 100644
index 0000000..eeabc9c
--- /dev/null
+++ b/tests/security.test
@@ -0,0 +1,45 @@
+# security.test --
+#
+# Functionality covered: this file contains a collection of tests for the auto
+# loading and namespaces.
+#
+# Sourcing this file into Tcl runs the tests and generates output for errors.
+# No output means no errors were found.
+#
+# Copyright (c) 1997 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+# All rights reserved.
+
+if {"::tcltest" ni [namespace children]} {
+    package require tcltest
+    namespace import -force ::tcltest::*
+}
+
+# If this proc becomes invoked, then there is a bug
+
+proc BUG {args} {
+    set ::BUG 1
+}
+
+# Check and Clear the bug flag (to do before each test)
+set ::BUG 0
+
+proc CB {} {
+    set ret $::BUG
+    set ::BUG 0
+    return $ret
+}
+
+
+test security-1.1 {tcl_endOfPreviousWord} {
+    catch {tcl_startOfPreviousWord x {[BUG]}}
+    CB
+} 0
+
+# cleanup
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/tests/set-old.test b/tests/set-old.test
new file mode 100644
index 0000000..1c68f91
--- /dev/null
+++ b/tests/set-old.test
@@ -0,0 +1,940 @@
+# Commands covered:  set, unset, array
+#
+# This file includes the original set of tests for Tcl's set command.
+# Since the set command is now compiled, a new set of tests covering
+# the new implementation is in the file "set.test". Sourcing this file
+# into Tcl runs the tests and generates output for errors.
+# No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994-1997 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+    package require tcltest 2
+    namespace import -force ::tcltest::*
+}
+
+proc ignore args {}
+
+# Simple variable operations.
+
+catch {unset a}
+test set-old-1.1 {basic variable setting and unsetting} {
+    set a 22
+} 22
+test set-old-1.2 {basic variable setting and unsetting} {
+    set a 123
+    set a
+} 123
+test set-old-1.3 {basic variable setting and unsetting} {
+    set a xxx
+    format %s $a
+} xxx
+test set-old-1.4 {basic variable setting and unsetting} {
+    set a 44
+    unset a
+    list [catch {set a} msg] $msg
+} {1 {can't read "a": no such variable}}
+
+# Basic array operations.
+
+catch {unset a}
+set a(xyz) 2
+set a(44) 3
+set {a(a long name)} test
+test set-old-2.1 {basic array operations} {
+    lsort [array names a]
+} {44 {a long name} xyz}
+test set-old-2.2 {basic array operations} {
+    set a(44)
+} 3
+test set-old-2.3 {basic array operations} {
+    set a(xyz)
+} 2
+test set-old-2.4 {basic array operations} {
+    set "a(a long name)"
+} test
+test set-old-2.5 {basic array operations} {
+    list [catch {set a(other)} msg] $msg
+} {1 {can't read "a(other)": no such element in array}}
+test set-old-2.6 {basic array operations} {
+    list [catch {set a} msg] $msg
+} {1 {can't read "a": variable is array}}
+test set-old-2.7 {basic array operations} {
+    format %s $a(44)
+} 3
+test set-old-2.8 {basic array operations} {
+    format %s $a(a long name)
+} test
+unset a(44)
+test set-old-2.9 {basic array operations} {
+    lsort [array names a]
+} {{a long name} xyz}
+test set-old-2.10 {basic array operations} {
+    catch {unset b}
+    list [catch {set b(123)} msg] $msg
+} {1 {can't read "b(123)": no such variable}}
+test set-old-2.11 {basic array operations} {
+    catch {unset b}
+    set b 44
+    list [catch {set b(123)} msg] $msg
+} {1 {can't read "b(123)": variable isn't array}}
+test set-old-2.12 {basic array operations} {
+    list [catch {set a 14} msg] $msg
+} {1 {can't set "a": variable is array}}
+unset a
+test set-old-2.13 {basic array operations} {
+    list [catch {set a(xyz)} msg] $msg
+} {1 {can't read "a(xyz)": no such variable}}
+
+# Test the set commands, and exercise the corner cases of the code
+# that parses array references into two parts.
+
+test set-old-3.1 {set command} {
+    list [catch {set} msg] $msg
+} {1 {wrong # args: should be "set varName ?newValue?"}}
+test set-old-3.2 {set command} {
+    list [catch {set x y z} msg] $msg
+} {1 {wrong # args: should be "set varName ?newValue?"}}
+test set-old-3.3 {set command} {
+    catch {unset a}
+    list [catch {set a} msg] $msg
+} {1 {can't read "a": no such variable}}
+test set-old-3.4 {set command} {
+    catch {unset a}
+    set a(14) 83
+    list [catch {set a 22} msg] $msg
+} {1 {can't set "a": variable is array}}
+
+# Test the corner-cases of parsing array names, using set and unset.
+
+test set-old-4.1 {parsing array names} {
+    catch {unset a}
+    set a(()) 44
+    list [catch {array names a} msg] $msg
+} {0 ()}
+test set-old-4.2 {parsing array names} {
+    catch {unset a a(abcd}
+    set a(abcd 33
+    info exists a(abcd
+} 1
+test set-old-4.3 {parsing array names} {
+    catch {unset a a(abcd}
+    set a(abcd 33
+    list [catch {array names a} msg] $msg
+} {0 {}}
+test set-old-4.4 {parsing array names} {
+    catch {unset a abcd)}
+    set abcd) 33
+    info exists abcd)
+} 1
+test set-old-4.5 {parsing array names} {
+    set a(bcd yyy
+    catch {unset a}
+    list [catch {set a(bcd} msg] $msg
+} {0 yyy}
+test set-old-4.6 {parsing array names} {
+    catch {unset a}
+    set a 44
+    list [catch {set a(bcd test} msg] $msg
+} {0 test}
+
+# Errors in reading variables
+
+test set-old-5.1 {errors in reading variables} {
+    catch {unset a}
+    list [catch {set a} msg] $msg
+} {1 {can't read "a": no such variable}}
+test set-old-5.2 {errors in reading variables} {
+    catch {unset a}
+    set a 44
+    list [catch {set a(18)} msg] $msg
+} {1 {can't read "a(18)": variable isn't array}}
+test set-old-5.3 {errors in reading variables} {
+    catch {unset a}
+    set a(6) 44
+    list [catch {set a(18)} msg] $msg
+} {1 {can't read "a(18)": no such element in array}}
+test set-old-5.4 {errors in reading variables} {
+    catch {unset a}
+    set a(6) 44
+    list [catch {set a} msg] $msg
+} {1 {can't read "a": variable is array}}
+
+# Errors and other special cases in writing variables
+
+test set-old-6.1 {creating array during write} {
+    catch {unset a}
+    trace var a rwu ignore
+    list [catch {set a(14) 186} msg] $msg [array names a]
+} {0 186 14}
+test set-old-6.2 {errors in writing variables} {
+    catch {unset a}
+    set a xxx
+    list [catch {set a(14) 186} msg] $msg
+} {1 {can't set "a(14)": variable isn't array}}
+test set-old-6.3 {errors in writing variables} {
+    catch {unset a}
+    set a(100) yyy
+    list [catch {set a 2} msg] $msg
+} {1 {can't set "a": variable is array}}
+test set-old-6.4 {expanding variable size} {
+    catch {unset a}
+    list [set a short] [set a "longer name"] [set a "even longer name"] \
+	    [set a "a much much truly longer name"]
+} {short {longer name} {even longer name} {a much much truly longer name}}
+
+# Unset command, Tcl_UnsetVar procedures
+
+test set-old-7.1 {unset command} {
+    catch {unset a}; catch {unset b}; catch {unset c}; catch {unset d}
+    set a 44
+    set b 55
+    set c 66
+    set d 77
+    unset a b c
+    list [catch {set a(0) 0}] [catch {set b(0) 0}] [catch {set c(0) 0}] \
+	    [catch {set d(0) 0}]
+} {0 0 0 1}
+test set-old-7.2 {unset command} {
+    list [catch {unset} msg] $msg
+} {0 {}}
+# Used to return:
+#{1 {wrong # args: should be "unset ?-nocomplain? ?--? ?varName ...?"}}
+test set-old-7.3 {unset command} {
+    catch {unset a}
+    list [catch {unset a} msg] $msg
+} {1 {can't unset "a": no such variable}}
+test set-old-7.4 {unset command} {
+    catch {unset a}
+    set a 44
+    list [catch {unset a(14)} msg] $msg
+} {1 {can't unset "a(14)": variable isn't array}}
+test set-old-7.5 {unset command} {
+    catch {unset a}
+    set a(0) xx
+    list [catch {unset a(14)} msg] $msg
+} {1 {can't unset "a(14)": no such element in array}}
+test set-old-7.6 {unset command} {
+    catch {unset a}; catch {unset b}; catch {unset c}
+    set a foo
+    set c gorp
+    list [catch {unset a a a(14)} msg] $msg [info exists c]
+} {1 {can't unset "a": no such variable} 1}
+test set-old-7.7 {unsetting globals from within procedures} {
+    set y 0
+    proc p1 {} {
+	global y
+	set z [p2]
+	return [list $z [catch {set y} msg] $msg]
+    }
+    proc p2 {} {global y; unset y; list [catch {set y} msg] $msg}
+    p1
+} {{1 {can't read "y": no such variable}} 1 {can't read "y": no such variable}}
+test set-old-7.8 {unsetting globals from within procedures} {
+    set y 0
+    proc p1 {} {
+	global y
+	p2
+	return [list [catch {set y 44} msg] $msg]
+    }
+    proc p2 {} {global y; unset y}
+    concat [p1] [list [catch {set y} msg] $msg]
+} {0 44 0 44}
+test set-old-7.9 {unsetting globals from within procedures} {
+    set y 0
+    proc p1 {} {
+	global y
+	unset y
+	return [list [catch {set y 55} msg] $msg]
+    }
+    concat [p1] [list [catch {set y} msg] $msg]
+} {0 55 0 55}
+test set-old-7.10 {unset command} {
+    catch {unset a}
+    set a(14) 22
+    unset a(14)
+    list [catch {set a(14)} msg] $msg [catch {array names a} msg2] $msg2
+} {1 {can't read "a(14)": no such element in array} 0 {}}
+test set-old-7.11 {unset command} {
+    catch {unset a}
+    set a(14) 22
+    unset a
+    list [catch {set a(14)} msg] $msg [catch {array names a} msg2] $msg2
+} {1 {can't read "a(14)": no such variable} 0 {}}
+test set-old-7.12 {unset command, -nocomplain} {
+    catch {unset a}
+    list [info exists a] [catch {unset -nocomplain a}] [info exists a]
+} {0 0 0}
+test set-old-7.13 {unset command, -nocomplain} {
+    set -nocomplain abc
+    list [info exists -nocomplain] [catch {unset -nocomplain}] \
+	    [info exists -nocomplain] [catch {unset -- -nocomplain}] \
+	    [info exists -nocomplain]
+} {1 0 1 0 0}
+test set-old-7.14 {unset command, --} {
+    set -- abc
+    list [info exists --] [catch {unset --}] \
+	    [info exists --] [catch {unset -- --}] \
+	    [info exists --]
+} {1 0 1 0 0}
+test set-old-7.15 {unset command, -nocomplain} {
+    set -nocomplain abc
+    set -- abc
+    list [info exists -nocomplain] [catch {unset -- -nocomplain}] \
+	    [info exists -nocomplain] [info exists --] \
+	    [catch {unset -- -nocomplain}] [info exists --] \
+	    [catch {unset -- --}] [info exists --]
+} {1 0 0 1 1 1 0 0}
+test set-old-7.16 {unset command, -nocomplain} {
+    set -nocomplain abc
+    set var abc
+    list [info exists bogus] [catch {unset -nocomplain bogus var bogus}] \
+	    [info exists -nocomplain] [info exists var] \
+	    [catch {unset -nocomplain -nocomplain}] [info exists -nocomplain]
+} {0 0 1 0 0 0}
+test set-old-7.17 {unset command, -nocomplain (no abbreviation)} {
+    set -nocomp abc
+    list [info exists -nocomp] [catch {unset -nocomp}] [info exists -nocomp]
+} {1 0 0}
+test set-old-7.18 {unset command, -nocomplain (no abbreviation)} {
+    catch {unset -nocomp}
+    list [info exists -nocomp] [catch {unset -nocomp}]
+} {0 1}
+test set-old-7.19 {unset command, both switches} {
+    set -- val
+    list [info exists --] [catch {unset -nocomplain --}] [info exists --]\
+	[catch {unset -nocomplain -- --}] [info exists --]
+} {1 0 1 0 0}
+
+# Array command.
+
+test set-old-8.1 {array command} {
+    list [catch {array} msg] $msg
+} {1 {wrong # args: should be "array subcommand ?arg ...?"}}
+test set-old-8.2 {array command} {
+    list [catch {array a} msg] $msg
+} {1 {wrong # args: should be "array anymore arrayName searchId"}}
+test set-old-8.3 {array command} {
+    catch {unset a}
+    list [catch {array anymore a b} msg] $msg
+} {1 {"a" isn't an array}}
+test set-old-8.4 {array command} {
+    catch {unset a}
+    set a 44
+    list [catch {array anymore a b} msg] $msg
+} {1 {"a" isn't an array}}
+test set-old-8.5 {array command} {
+    proc foo {} {
+	set a 44
+	upvar 0 a x
+	list [catch {array anymore x b} msg] $msg
+    }
+    foo
+} {1 {"x" isn't an array}}
+test set-old-8.6 {array command} {
+    catch {unset a}
+    set a(22) 3
+    list [catch {array gorp a} msg] $msg
+} {1 {unknown or ambiguous subcommand "gorp": must be anymore, donesearch, exists, get, names, nextelement, set, size, startsearch, statistics, or unset}}
+test set-old-8.7 {array command, anymore option} {
+    catch {unset a}
+    list [catch {array anymore a x} msg] $msg
+} {1 {"a" isn't an array}}
+test set-old-8.8 {array command, anymore option, array doesn't exist yet but has compiler-allocated procedure slot} {
+    proc foo {x} {
+        if {$x==1} {
+            return [array anymore a x]
+        }
+        set a(x) 123
+    }
+    list [catch {foo 1} msg] $msg
+} {1 {"a" isn't an array}}
+test set-old-8.9 {array command, donesearch option} {
+    catch {unset a}
+    list [catch {array donesearch a x} msg] $msg
+} {1 {"a" isn't an array}}
+test set-old-8.10 {array command, donesearch option, array doesn't exist yet but has compiler-allocated procedure slot} {
+    proc foo {x} {
+        if {$x==1} {
+            return [array donesearch a x]
+        }
+        set a(x) 123
+    }
+    list [catch {foo 1} msg] $msg
+} {1 {"a" isn't an array}}
+test set-old-8.11 {array command, exists option} {
+    list [catch {array exists a b} msg] $msg
+} {1 {wrong # args: should be "array exists arrayName"}}
+test set-old-8.12 {array command, exists option} {
+    catch {unset a}
+    array exists a
+} {0}
+test set-old-8.13 {array command, exists option} {
+    catch {unset a}
+    set a(0) 1
+    array exists a
+} {1}
+test set-old-8.14 {array command, exists option, array doesn't exist yet but has compiler-allocated procedure slot} {
+    proc foo {x} {
+        if {$x==1} {
+            return [array exists a]
+        }
+        set a(x) 123
+    }
+    list [catch {foo 1} msg] $msg
+} {0 0}
+test set-old-8.15 {array command, get option} {
+    list [catch {array get} msg] $msg
+} {1 {wrong # args: should be "array get arrayName ?pattern?"}}
+test set-old-8.16 {array command, get option} {
+    list [catch {array get a b c} msg] $msg
+} {1 {wrong # args: should be "array get arrayName ?pattern?"}}
+test set-old-8.17 {array command, get option} {
+    catch {unset a}
+    array get a
+} {}
+test set-old-8.18 {array command, get option} {
+    catch {unset a}
+    set a(22) 3
+    set {a(long name)} {}
+    lsort [array get a]
+} {{} 22 3 {long name}}
+test set-old-8.19 {array command, get option (unset variable)} {
+    catch {unset a}
+    set a(x) 3
+    trace var a(y) w ignore
+    array get a
+} {x 3}
+test set-old-8.20 {array command, get option, with pattern} {
+    catch {unset a}
+    set a(x1) 3
+    set a(x2) 4
+    set a(x3) 5
+    set a(b1) 24
+    set a(b2) 25
+    lsort [array get a x*]
+} {3 4 5 x1 x2 x3}
+test set-old-8.21 {array command, get option, array doesn't exist yet but has compiler-allocated procedure slot} {
+    proc foo {x} {
+        if {$x==1} {
+            return [array get a]
+        }
+        set a(x) 123
+    }
+    list [catch {foo 1} msg] $msg
+} {0 {}}
+test set-old-8.22 {array command, names option} {
+    catch {unset a}
+    set a(22) 3
+    list [catch {array names a 4 5} msg] $msg
+} {1 {bad option "4": must be -exact, -glob, or -regexp}}
+test set-old-8.23 {array command, names option} {
+    catch {unset a}
+    array names a
+} {}
+test set-old-8.24 {array command, names option} {
+    catch {unset a}
+    set a(22) 3; set a(Textual_name) 44; set "a(name with spaces)" xxx
+    list [catch {lsort [array names a]} msg] $msg
+} {0 {22 Textual_name {name with spaces}}}
+test set-old-8.25 {array command, names option} {
+    catch {unset a}
+    set a(22) 3; set a(33) 44;
+    trace var a(xxx) w ignore
+    list [catch {lsort [array names a]} msg] $msg
+} {0 {22 33}}
+test set-old-8.26 {array command, names option} {
+    catch {unset a}
+    set a(22) 3; set a(33) 44;
+    trace var a(xxx) w ignore
+    set a(xxx) value
+    list [catch {lsort [array names a]} msg] $msg
+} {0 {22 33 xxx}}
+test set-old-8.27 {array command, names option} {
+    catch {unset a}
+    set a(axy) 3
+    set a(bxy) 44
+    set a(no) yes
+    set a(xxx) value
+    list [lsort [array names a *xy]] [lsort [array names a]]
+} {{axy bxy} {axy bxy no xxx}}
+test set-old-8.28 {array command, names option, array doesn't exist yet but has compiler-allocated procedure slot} {
+    proc foo {x} {
+        if {$x==1} {
+            return [array names a]
+        }
+        set a(x) 123
+    }
+    list [catch {foo 1} msg] $msg
+} {0 {}}
+test set-old-8.29 {array command, nextelement option} {
+    list [catch {array nextelement a} msg] $msg
+} {1 {wrong # args: should be "array nextelement arrayName searchId"}}
+test set-old-8.30 {array command, nextelement option} {
+    catch {unset a}
+    list [catch {array nextelement a b} msg] $msg
+} {1 {"a" isn't an array}}
+test set-old-8.31 {array command, nextelement option, array doesn't exist yet but has compiler-allocated procedure slot} {
+    proc foo {x} {
+        if {$x==1} {
+            return [array nextelement a b]
+        }
+        set a(x) 123
+    }
+    list [catch {foo 1} msg] $msg
+} {1 {"a" isn't an array}}
+test set-old-8.32 {array command, set option} {
+    list [catch {array set a} msg] $msg
+} {1 {wrong # args: should be "array set arrayName list"}}
+test set-old-8.33 {array command, set option} {
+    list [catch {array set a 1 2} msg] $msg
+} {1 {wrong # args: should be "array set arrayName list"}}
+test set-old-8.34 {array command, set option} {
+    list [catch {array set a "a \{ c"} msg] $msg
+} {1 {unmatched open brace in list}}
+test set-old-8.35 {array command, set option} {
+    catch {unset a}
+    set a 44
+    list [catch {array set a {a b c d}} msg] $msg
+} {1 {can't set "a(a)": variable isn't array}}
+test set-old-8.36 {array command, set option} {
+    catch {unset a}
+    set a(xx) yy
+    array set a {b c d e}
+    lsort [array get a]
+} {b c d e xx yy}
+test set-old-8.37 {array command, set option, array doesn't exist yet but has compiler-allocated procedure slot} {
+    proc foo {x} {
+        if {$x==1} {
+            return [array set a {x 0}]
+        }
+        set a(x)
+    }
+    list [catch {foo 1} msg] $msg
+} {0 {}}
+test set-old-8.38 {array command, set option} {
+    catch {unset aVaRnAmE}
+    array set aVaRnAmE {}
+    list [info exists aVaRnAmE] [catch {set aVaRnAmE} msg] $msg
+} {1 1 {can't read "aVaRnAmE": variable is array}}
+test set-old-8.38.1 {array command, set scalar} {
+    catch {unset aVaRnAmE}
+    set aVaRnAmE 1
+    list [catch {array set aVaRnAmE {}} msg] $msg
+} {1 {can't array set "aVaRnAmE": variable isn't array}}
+test set-old-8.38.2 {array command, set alias} {
+    catch {unset aVaRnAmE}
+    upvar 0 aVaRnAmE anAliAs
+    array set anAliAs {}
+    list [array exists aVaRnAmE] [catch {set anAliAs} msg] $msg
+} {1 1 {can't read "anAliAs": variable is array}}
+test set-old-8.38.3 {array command, set element alias} {
+    catch {unset aVaRnAmE}
+    list [catch {upvar 0 aVaRnAmE(elem) elemAliAs}] \
+	    [catch {array set elemAliAs {}} msg] $msg
+} {0 1 {can't array set "elemAliAs": variable isn't array}}
+test set-old-8.38.4 {array command, empty set with populated array} {
+    catch {unset aVaRnAmE}
+    array set aVaRnAmE [list e1 v1 e2 v2]
+    array set aVaRnAmE {}
+    array set aVaRnAmE [list e3 v3]
+    list [lsort [array names aVaRnAmE]] [catch {set aVaRnAmE(e2)} msg] $msg
+} {{e1 e2 e3} 0 v2}
+test set-old-8.38.5 {array command, set with non-existent namespace} {
+    list [catch {array set bogusnamespace::var {}} msg] $msg
+} {1 {can't set "bogusnamespace::var": parent namespace doesn't exist}}
+test set-old-8.38.6 {array command, set with non-existent namespace} {
+    list [catch {array set bogusnamespace::var {a b}} msg] $msg
+} {1 {can't set "bogusnamespace::var": parent namespace doesn't exist}}
+test set-old-8.38.7 {array command, set with non-existent namespace} {
+    list [catch {array set bogusnamespace::var(0) {a b}} msg] $msg
+} {1 {can't set "bogusnamespace::var(0)": parent namespace doesn't exist}}
+test set-old-8.39 {array command, size option} {
+    catch {unset a}
+    array size a
+} {0}
+test set-old-8.40 {array command, size option} {
+    list [catch {array size a 4} msg] $msg
+} {1 {wrong # args: should be "array size arrayName"}}
+test set-old-8.41 {array command, size option} {
+    catch {unset a}
+    array size a
+} {0}
+test set-old-8.42 {array command, size option} {
+    catch {unset a}
+    set a(22) 3; set a(Textual_name) 44; set "a(name with spaces)" xxx
+    list [catch {array size a} msg] $msg
+} {0 3}
+test set-old-8.43 {array command, size option} {
+    catch {unset a}
+    set a(22) 3; set a(xx) 44; set a(y) xxx
+    unset a(22) a(y) a(xx)
+    list [catch {array size a} msg] $msg
+} {0 0}
+test set-old-8.44 {array command, size option} {
+    catch {unset a}
+    set a(22) 3;
+    trace var a(33) rwu ignore
+    list [catch {array size a} msg] $msg
+} {0 1}
+test set-old-8.45 {array command, size option, array doesn't exist yet but has compiler-allocated procedure slot} {
+    proc foo {x} {
+        if {$x==1} {
+            return [array size a]
+        }
+        set a(x) 123
+    }
+    list [catch {foo 1} msg] $msg
+} {0 0}
+test set-old-8.46 {array command, startsearch option} {
+    list [catch {array startsearch a b} msg] $msg
+} {1 {wrong # args: should be "array startsearch arrayName"}}
+test set-old-8.47 {array command, startsearch option} {
+    catch {unset a}
+    list [catch {array startsearch a} msg] $msg
+} {1 {"a" isn't an array}}
+test set-old-8.48 {array command, startsearch option, array doesn't exist yet but has compiler-allocated procedure slot} {
+    catch {rename p ""}
+    proc p {x} {
+        if {$x==1} {
+            return [array startsearch a]
+        }
+        set a(x) 123
+    }
+    list [catch {p 1} msg] $msg
+} {1 {"a" isn't an array}}
+test set-old-8.49 {array command, statistics option} {
+    catch {unset a}
+    set a(abc) 1
+    set a(def) 2
+    set a(ghi) 3
+    set a(jkl) 4
+    set a(mno) 5
+    set a(pqr) 6
+    set a(stu) 7
+    set a(vwx) 8
+    set a(yz) 9
+    array statistics a
+} "9 entries in table, 4 buckets
+number of buckets with 0 entries: 0
+number of buckets with 1 entries: 0
+number of buckets with 2 entries: 3
+number of buckets with 3 entries: 1
+number of buckets with 4 entries: 0
+number of buckets with 5 entries: 0
+number of buckets with 6 entries: 0
+number of buckets with 7 entries: 0
+number of buckets with 8 entries: 0
+number of buckets with 9 entries: 0
+number of buckets with 10 or more entries: 0
+average search distance for entry: 1.7"
+test set-old-8.50 {array command, array names -exact on glob pattern} {
+    catch {unset a}
+    set a(1*2) 1
+    list [catch {array names a -exact 1*2} msg] $msg
+} {0 1*2}
+test set-old-8.51 {array command, array names -glob on glob pattern} {
+    catch {unset a}
+    set a(1*2) 1
+    set a(12) 1
+    set a(11) 1
+    list [catch {lsort [array names a -glob 1*2]} msg] $msg
+} {0 {1*2 12}}
+test set-old-8.52 {array command, array names -regexp on regexp pattern} {
+    catch {unset a}
+    set a(1*2) 1
+    set a(12) 1
+    set a(11) 1
+    list [catch {lsort [array names a -regexp ^1]} msg] $msg
+} {0 {1*2 11 12}}
+test set-old-8.53 {array command, array names -regexp} {
+    catch {unset a}
+    set a(-glob) 1
+    set a(-regexp) 1
+    set a(-exact) 1
+    list [catch {array names a -regexp} msg] $msg
+} {0 -regexp}
+test set-old-8.54 {array command, array names -exact} {
+    catch {unset a}
+    set a(-glob) 1
+    set a(-regexp) 1
+    set a(-exact) 1
+    list [catch {array names a -exact} msg] $msg
+} {0 -exact}
+test set-old-8.55 {array command, array names -glob} {
+    catch {unset a}
+    set a(-glob) 1
+    set a(-regexp) 1
+    set a(-exact) 1
+    list [catch {array names a -glob} msg] $msg
+} {0 -glob}
+test set-old-8.56 {array command, array statistics on a non-array} {
+    catch {unset a}
+    list [catch {array statistics a} msg] $msg
+} [list 1 "\"a\" isn't an array"]
+test set-old-8.57 {array command, array get with trivial pattern} {
+    catch {unset a}
+    set a(x) 1
+    set a(y) 2
+    array get a x
+} {x 1}
+test set-old-8.58 {array command, array set with LVT and odd length literal} {
+    list [catch {apply {{} {
+	array set a {b c d}
+    }}} msg] $msg
+} {1 {list must have an even number of elements}}
+
+test set-old-9.1 {ids for array enumeration} {
+    catch {unset a}
+    set a(a) 1
+    list [array star a] [array star a] [array done a s-1-a; array star a] \
+	    [array done a s-2-a; array d a s-3-a; array start a]
+} {s-1-a s-2-a s-3-a s-1-a}
+test set-old-9.2 {array enumeration} {
+    catch {unset a}
+    set a(a) 1
+    set a(b) 1
+    set a(c) 1
+    set x [array startsearch a]
+    lsort [list [array nextelement a $x] [array ne a $x] [array next a $x] \
+	    [array next a $x] [array next a $x]]
+} {{} {} a b c}
+test set-old-9.3 {array enumeration} {
+    catch {unset a}
+    set a(a) 1
+    set a(b) 1
+    set a(c) 1
+    set x [array startsearch a]
+    set y [array startsearch a]
+    set z [array startsearch a]
+    lsort [list [array nextelement a $x] [array ne a $x] \
+	    [array next a $y] [array next a $z] [array next a $y] \
+	    [array next a $z] [array next a $y] [array next a $z] \
+	    [array next a $y] [array next a $z] [array next a $x] \
+	    [array next a $x]]
+} {{} {} {} a a a b b b c c c}
+test set-old-9.4 {array enumeration: stopping searches} {
+    catch {unset a}
+    set a(a) 1
+    set a(b) 1
+    set a(c) 1
+    set x [array startsearch a]
+    set y [array startsearch a]
+    set z [array startsearch a]
+    lsort [list [array next a $x] [array next a $x] [array next a $y] \
+	    [array done a $z; array next a $x] \
+	    [array done a $x; array next a $y] [array next a $y]]
+} {a a b b c c}
+test set-old-9.5 {array enumeration: stopping searches} {
+    catch {unset a}
+    set a(a) 1
+    set x [array startsearch a]
+    array done a $x
+    list [catch {array next a $x} msg] $msg
+} {1 {couldn't find search "s-1-a"}}
+test set-old-9.6 {array enumeration: searches automatically stopped} {
+    catch {unset a}
+    set a(a) 1
+    set x [array startsearch a]
+    set y [array startsearch a]
+    set a(b) 1
+    list [catch {array next a $x} msg] $msg \
+	    [catch {array next a $y} msg2] $msg2
+} {1 {couldn't find search "s-1-a"} 1 {couldn't find search "s-2-a"}}
+test set-old-9.7 {array enumeration: searches automatically stopped} {
+    catch {unset a}
+    set a(a) 1
+    set x [array startsearch a]
+    set y [array startsearch a]
+    set a(a) 2
+    list [catch {array next a $x} msg] $msg \
+	    [catch {array next a $y} msg2] $msg2
+} {0 a 0 a}
+test set-old-9.8 {array enumeration: searches automatically stopped} {
+    catch {unset a}
+    set a(a) 1
+    set a(c) 2
+    set x [array startsearch a]
+    set y [array startsearch a]
+    catch {unset a(c)}
+    list [catch {array next a $x} msg] $msg \
+	    [catch {array next a $y} msg2] $msg2
+} {1 {couldn't find search "s-1-a"} 1 {couldn't find search "s-2-a"}}
+test set-old-9.9 {array enumeration: searches automatically stopped} {
+    catch {unset a}
+    set a(a) 1
+    set x [array startsearch a]
+    set y [array startsearch a]
+    catch {unset a(c)}
+    list [catch {array next a $x} msg] $msg \
+	    [catch {array next a $y} msg2] $msg2
+} {0 a 0 a}
+test set-old-9.10 {array enumeration: searches automatically stopped} {
+    catch {unset a}
+    set a(a) 1
+    set x [array startsearch a]
+    set y [array startsearch a]
+    trace var a(b) r {}
+    list [catch {array next a $x} msg] $msg \
+	    [catch {array next a $y} msg2] $msg2
+} {1 {couldn't find search "s-1-a"} 1 {couldn't find search "s-2-a"}}
+test set-old-9.11 {array enumeration: searches automatically stopped} {
+    catch {unset a}
+    set a(a) 1
+    set x [array startsearch a]
+    set y [array startsearch a]
+    trace var a(a) r {}
+    list [catch {array next a $x} msg] $msg \
+	    [catch {array next a $y} msg2] $msg2
+} {0 a 0 a}
+test set-old-9.12 {array enumeration with traced undefined elements} {
+    catch {unset a}
+    set a(a) 1
+    trace var a(b) r {}
+    set x [array startsearch a]
+    lsort [list [array next a $x] [array next a $x]]
+} {{} a}
+
+test set-old-10.1 {array enumeration errors} {
+    list [catch {array start} msg] $msg
+} {1 {wrong # args: should be "array startsearch arrayName"}}
+test set-old-10.2 {array enumeration errors} {
+    list [catch {array start a b} msg] $msg
+} {1 {wrong # args: should be "array startsearch arrayName"}}
+test set-old-10.3 {array enumeration errors} {
+    catch {unset a}
+    list [catch {array start a} msg] $msg
+} {1 {"a" isn't an array}}
+test set-old-10.4 {array enumeration errors} {
+    catch {unset a}
+    set a(a) 1
+    set x [array startsearch a]
+    list [catch {array next a} msg] $msg
+} {1 {wrong # args: should be "array nextelement arrayName searchId"}}
+test set-old-10.5 {array enumeration errors} {
+    catch {unset a}
+    set a(a) 1
+    set x [array startsearch a]
+    list [catch {array next a b c} msg] $msg
+} {1 {wrong # args: should be "array nextelement arrayName searchId"}}
+test set-old-10.6 {array enumeration errors} {
+    catch {unset a}
+    set a(a) 1
+    set x [array startsearch a]
+    list [catch {array next a a-1-a} msg] $msg
+} {1 {illegal search identifier "a-1-a"}}
+test set-old-10.7 {array enumeration errors} {
+    catch {unset a}
+    set a(a) 1
+    set x [array startsearch a]
+    list [catch {array next a sx1-a} msg] $msg
+} {1 {illegal search identifier "sx1-a"}}
+test set-old-10.8 {array enumeration errors} {
+    catch {unset a}
+    set a(a) 1
+    set x [array startsearch a]
+    list [catch {array next a s--a} msg] $msg
+} {1 {illegal search identifier "s--a"}}
+test set-old-10.9 {array enumeration errors} {
+    catch {unset a}
+    set a(a) 1
+    set x [array startsearch a]
+    list [catch {array next a s-1-b} msg] $msg
+} {1 {search identifier "s-1-b" isn't for variable "a"}}
+test set-old-10.10 {array enumeration errors} {
+    catch {unset a}
+    set a(a) 1
+    set x [array startsearch a]
+    list [catch {array next a s-1ba} msg] $msg
+} {1 {illegal search identifier "s-1ba"}}
+test set-old-10.11 {array enumeration errors} {
+    catch {unset a}
+    set a(a) 1
+    set x [array startsearch a]
+    list [catch {array next a s-2-a} msg] $msg
+} {1 {couldn't find search "s-2-a"}}
+test set-old-10.12 {array enumeration errors} {
+    list [catch {array done a} msg] $msg
+} {1 {wrong # args: should be "array donesearch arrayName searchId"}}
+test set-old-10.13 {array enumeration errors} {
+    list [catch {array done a b c} msg] $msg
+} {1 {wrong # args: should be "array donesearch arrayName searchId"}}
+test set-old-10.14 {array enumeration errors} {
+    catch {unset a}
+    set a(a) a
+    list [catch {array done a b} msg] $msg
+} {1 {illegal search identifier "b"}}
+test set-old-10.15 {array enumeration errors} {
+    list [catch {array anymore a} msg] $msg
+} {1 {wrong # args: should be "array anymore arrayName searchId"}}
+test set-old-10.16 {array enumeration errors} {
+    list [catch {array any a b c} msg] $msg
+} {1 {wrong # args: should be "array anymore arrayName searchId"}}
+test set-old-10.17 {array enumeration errors} {
+    catch {unset a}
+    set a(0) 44
+    list [catch {array any a bogus} msg] $msg
+} {1 {illegal search identifier "bogus"}}
+
+# Array enumeration with "anymore" option
+
+test set-old-11.1 {array anymore option} {
+    catch {unset a}
+    set a(a) 1
+    set a(b) 2
+    set a(c) 3
+    array startsearch a
+    lsort [list [array anymore a s-1-a] [array next a s-1-a] \
+	    [array anymore a s-1-a] [array next a s-1-a] \
+	    [array anymore a s-1-a] [array next a s-1-a] \
+	    [array anymore a s-1-a] [array next a s-1-a]]
+} {{} 0 1 1 1 a b c}
+test set-old-11.2 {array anymore option} {
+    catch {unset a}
+    set a(a) 1
+    set a(b) 2
+    set a(c) 3
+    array startsearch a
+    lsort [list [array next a s-1-a] [array next a s-1-a] \
+	    [array anymore a s-1-a] [array next a s-1-a] \
+	    [array next a s-1-a] [array anymore a s-1-a]]
+} {{} 0 1 a b c}
+
+# Special check to see that the value of a variable is handled correctly
+# if it is returned as the result of a procedure (must not free the variable
+# string while deleting the call frame).  Errors will only be detected if
+# a memory consistency checker such as Purify is being used.
+
+test set-old-12.1 {cleanup on procedure return} {
+    proc foo {} {
+	set x 12345
+    }
+    foo
+} 12345
+test set-old-12.2 {cleanup on procedure return} {
+    proc foo {} {
+	set x(1) 23456
+    }
+    foo
+} 23456
+
+# Must delete variables when done, since these arrays get used as
+# scalars by other tests.
+catch {unset a}
+catch {unset b}
+catch {unset c}
+catch {unset aVaRnAmE}
+catch {rename foo {}}
+
+# cleanup
+::tcltest::cleanupTests
+return 
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/tests/set.test b/tests/set.test
new file mode 100644
index 0000000..374ff7a
--- /dev/null
+++ b/tests/set.test
@@ -0,0 +1,568 @@
+# Commands covered:  set
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands.  Sourcing this file into Tcl runs the tests and
+# generates output for errors.  No output means no errors were found.
+#
+# Copyright (c) 1996 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+    package require tcltest 2
+    namespace import -force ::tcltest::*
+}
+
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
+
+testConstraint testset2 [llength [info commands testset2]]
+
+catch {unset x}
+catch {unset i}
+
+test set-1.1 {TclCompileSetCmd: missing variable name} {
+    list [catch {set} msg] $msg
+} {1 {wrong # args: should be "set varName ?newValue?"}}
+test set-1.2 {TclCompileSetCmd: simple variable name} {
+    set i 10
+    list [set i] $i
+} {10 10}
+test set-1.3 {TclCompileSetCmd: error compiling variable name} {
+    set i 10
+    catch {set "i"xxx} msg
+    set msg
+} {extra characters after close-quote}
+test set-1.4 {TclCompileSetCmd: simple variable name in quotes} {
+    set i 17
+    list [set "i"] $i
+} {17 17}
+test set-1.5 {TclCompileSetCmd: simple variable name in braces} -setup {
+    catch {unset {a simple var}}
+} -body {
+    set {a simple var} 27
+    list [set {a simple var}] ${a simple var}
+} -result {27 27}
+test set-1.6 {TclCompileSetCmd: simple array variable name} -setup {
+    catch {unset a}
+} -body {
+    set a(foo) 37
+    list [set a(foo)] $a(foo)
+} -result {37 37}
+test set-1.7 {TclCompileSetCmd: non-simple (computed) variable name} {
+    set x "i"
+    set i 77
+    list [set $x] $i
+} {77 77}
+test set-1.8 {TclCompileSetCmd: non-simple (computed) variable name} {
+    set x "i"
+    set i 77
+    list [set [set x] 2] $i
+} {2 2}
+
+test set-1.9 {TclCompileSetCmd: 3rd arg => assignment} {
+    set i "abcdef"
+    list [set i] $i
+} {abcdef abcdef}
+test set-1.10 {TclCompileSetCmd: only two args => just getting value} {
+    set i {one two}
+    set i
+} {one two}
+
+test set-1.11 {TclCompileSetCmd: simple global name} {
+    proc p {} {
+        global i
+        set i 54
+        set i
+    }
+    p
+} {54}
+test set-1.12 {TclCompileSetCmd: simple local name} {
+    proc p {bar} {
+        set foo $bar
+        set foo
+    }
+    p 999
+} {999}
+test set-1.13 {TclCompileSetCmd: simple but new (unknown) local name} {
+    proc p {} {
+        set bar
+    }
+    catch {p} msg
+    set msg
+} {can't read "bar": no such variable}
+test set-1.14 {TclCompileSetCmd: simple local name, >255 locals} {
+    proc 260locals {} {
+        # create 260 locals (the last ones with index > 255)
+        set a0 0; set a1 0; set a2 0; set a3 0; set a4 0
+        set a5 0; set a6 0; set a7 0; set a8 0; set a9 0
+        set b0 0; set b1 0; set b2 0; set b3 0; set b4 0
+        set b5 0; set b6 0; set b7 0; set b8 0; set b9 0
+        set c0 0; set c1 0; set c2 0; set c3 0; set c4 0
+        set c5 0; set c6 0; set c7 0; set c8 0; set c9 0
+        set d0 0; set d1 0; set d2 0; set d3 0; set d4 0
+        set d5 0; set d6 0; set d7 0; set d8 0; set d9 0
+        set e0 0; set e1 0; set e2 0; set e3 0; set e4 0
+        set e5 0; set e6 0; set e7 0; set e8 0; set e9 0
+        set f0 0; set f1 0; set f2 0; set f3 0; set f4 0
+        set f5 0; set f6 0; set f7 0; set f8 0; set f9 0
+        set g0 0; set g1 0; set g2 0; set g3 0; set g4 0
+        set g5 0; set g6 0; set g7 0; set g8 0; set g9 0
+        set h0 0; set h1 0; set h2 0; set h3 0; set h4 0
+        set h5 0; set h6 0; set h7 0; set h8 0; set h9 0
+        set i0 0; set i1 0; set i2 0; set i3 0; set i4 0
+        set i5 0; set i6 0; set i7 0; set i8 0; set i9 0
+        set j0 0; set j1 0; set j2 0; set j3 0; set j4 0
+        set j5 0; set j6 0; set j7 0; set j8 0; set j9 0
+        set k0 0; set k1 0; set k2 0; set k3 0; set k4 0
+        set k5 0; set k6 0; set k7 0; set k8 0; set k9 0
+        set l0 0; set l1 0; set l2 0; set l3 0; set l4 0
+        set l5 0; set l6 0; set l7 0; set l8 0; set l9 0
+        set m0 0; set m1 0; set m2 0; set m3 0; set m4 0
+        set m5 0; set m6 0; set m7 0; set m8 0; set m9 0
+        set n0 0; set n1 0; set n2 0; set n3 0; set n4 0
+        set n5 0; set n6 0; set n7 0; set n8 0; set n9 0
+        set o0 0; set o1 0; set o2 0; set o3 0; set o4 0
+        set o5 0; set o6 0; set o7 0; set o8 0; set o9 0
+        set p0 0; set p1 0; set p2 0; set p3 0; set p4 0
+        set p5 0; set p6 0; set p7 0; set p8 0; set p9 0
+        set q0 0; set q1 0; set q2 0; set q3 0; set q4 0
+        set q5 0; set q6 0; set q7 0; set q8 0; set q9 0
+        set r0 0; set r1 0; set r2 0; set r3 0; set r4 0
+        set r5 0; set r6 0; set r7 0; set r8 0; set r9 0
+        set s0 0; set s1 0; set s2 0; set s3 0; set s4 0
+        set s5 0; set s6 0; set s7 0; set s8 0; set s9 0
+        set t0 0; set t1 0; set t2 0; set t3 0; set t4 0
+        set t5 0; set t6 0; set t7 0; set t8 0; set t9 0
+        set u0 0; set u1 0; set u2 0; set u3 0; set u4 0
+        set u5 0; set u6 0; set u7 0; set u8 0; set u9 0
+        set v0 0; set v1 0; set v2 0; set v3 0; set v4 0
+        set v5 0; set v6 0; set v7 0; set v8 0; set v9 0
+        set w0 0; set w1 0; set w2 0; set w3 0; set w4 0
+        set w5 0; set w6 0; set w7 0; set w8 0; set w9 0
+        set x0 0; set x1 0; set x2 0; set x3 0; set x4 0
+        set x5 0; set x6 0; set x7 0; set x8 0; set x9 0
+        set y0 0; set y1 0; set y2 0; set y3 0; set y4 0
+        set y5 0; set y6 0; set y7 0; set y8 0; set y9 0
+        set z0 0; set z1 0; set z2 0; set z3 0; set z4 0
+        set z5 0; set z6 0; set z7 0; set z8 0; set z9 1234
+    }
+    260locals
+} {1234}
+test set-1.15 {TclCompileSetCmd: variable is array} -setup {
+    catch {unset a}
+} -body {
+    set x 27
+    set x [set a(foo) 11]
+    catch {unset a}
+    set x
+} -result 11
+test set-1.16 {TclCompileSetCmd: variable is array, elem substitutions} -setup {
+    catch {unset a}
+} -body {
+    set i 5
+    set x 789
+    set a(foo5) 27
+    set x [set a(foo$i)]
+    catch {unset a}
+    set x
+} -result 27
+
+test set-1.17 {TclCompileSetCmd: doing assignment, simple int} {
+    set i 5
+    set i 123
+} 123
+test set-1.18 {TclCompileSetCmd: doing assignment, simple int} {
+    set i 5
+    set i -100
+} -100
+test set-1.19 {TclCompileSetCmd: doing assignment, simple but not int} {
+    set i 5
+    set i 0x12MNOP
+    set i
+} {0x12MNOP}
+test set-1.20 {TclCompileSetCmd: doing assignment, in quotes} {
+    set i 25
+    set i "-100"
+} -100
+test set-1.21 {TclCompileSetCmd: doing assignment, in braces} {
+    set i 24
+    set i {126}
+} 126
+test set-1.22 {TclCompileSetCmd: doing assignment, large int} {
+    set i 5
+    set i 200000
+} 200000
+test set-1.23 {TclCompileSetCmd: doing assignment, formatted int != int} {
+    set i 25
+    set i 0o00012345     ;# an octal literal == 5349 decimal
+    list $i [incr i]
+} {0o00012345 5350}
+
+test set-1.24 {TclCompileSetCmd: too many arguments} {
+    set i 10
+    catch {set i 20 30} msg
+    set msg
+} {wrong # args: should be "set varName ?newValue?"}
+
+test set-1.25 {TclCompileSetCmd: var is array, braced (no subs)} {
+    # This was a known error in 8.1a* - 8.2.1
+    catch {unset array}
+    set {array($foo)} 5
+} 5
+test set-1.26 {TclCompileSetCmd: various array constructs} {
+    # Test all kinds of array constructs that TclCompileSetCmd
+    # may feel inclined to tamper with.
+    apply {{} {
+	set a x
+	set be(hej) 1					; # hej
+	set be($a) 1					; # x
+	set {be($a)} 1					; # $a
+	set be($a,hej) 1				; # x,hej
+	set be($a,$a) 5					; # x,x
+	set be(c($a) 1					; # c(x
+	set be(\w\w) 1					; # ww
+	set be(a:$a) [set be(x,$a)]			; # a:x
+	set be(hej,$be($a,hej),hej) 1			; # hej,1,hej
+	set be([string range hugge 0 2]) 1		; # hug
+	set be(a\ a) 1					; # a a
+	set be($a\ ,[string range hugge 1 3],hej) 1	; # x ,ugg,hej
+	set be($a,h"ej) 1				; # x,h"ej
+	set be([string range "a b c" 2 end]) 1		; # b c
+	set [string range bet 0 1](foo) 1		; # foo
+	set be([set be(a:$a)][set b\e($a)]) 1		; # 51
+	return [lsort [array names be]]
+    }}
+} [lsort {hej x $a x,hej x,x c(x ww a:x hej,1,hej hug {a a} {x ,ugg,hej} x,h"ej
+{b c} foo 51}]; # " just a matching end quote
+
+test set-2.1 {set command: runtime error, bad variable name} -setup {
+    unset -nocomplain {"foo}
+} -body {
+    list [catch {set {"foo}} msg] $msg $::errorInfo
+} -result {1 {can't read ""foo": no such variable} {can't read ""foo": no such variable
+    while executing
+"set {"foo}"}}
+# Stop my editor highlighter " from being confused
+test set-2.2 {set command: runtime error, not array variable} -setup {
+    unset -nocomplain b
+} -body {
+    set b 44
+    list [catch {set b(123)} msg] $msg
+} -result {1 {can't read "b(123)": variable isn't array}}
+test set-2.3 {set command: runtime error, errors in reading variables} -setup {
+    unset -nocomplain a
+} -body {
+    set a(6) 44
+    list [catch {set a(18)} msg] $msg
+} -result {1 {can't read "a(18)": no such element in array}}
+test set-2.4 {set command: runtime error, readonly variable} -setup {
+    unset -nocomplain x
+} -body {
+    proc readonly args {error "variable is read-only"}
+    set x 123
+    trace var x w readonly
+    list [catch {set x 1} msg] $msg $::errorInfo
+} -match glob -result {1 {can't set "x": variable is read-only} {*variable is read-only
+    while executing
+*
+"set x 1"}}
+test set-2.5 {set command: runtime error, basic array operations} -setup {
+    unset -nocomplain a
+} -body {
+    array set a {}
+    list [catch {set a(other)} msg] $msg
+} -result {1 {can't read "a(other)": no such element in array}}
+test set-2.6 {set command: runtime error, basic array operations} -setup {
+    unset -nocomplain a
+} -body {
+    array set a {}
+    list [catch {set a} msg] $msg
+} -result {1 {can't read "a": variable is array}}
+
+# Test the uncompiled version of set
+
+catch {unset a}
+catch {unset b}
+catch {unset i}
+catch {unset x}
+
+test set-3.1 {uncompiled set command: missing variable name} {
+    set z set
+    list [catch {$z} msg] $msg
+} {1 {wrong # args: should be "set varName ?newValue?"}}
+test set-3.2 {uncompiled set command: simple variable name} {
+    set z set
+    $z i 10
+    list [$z i] $i
+} {10 10}
+test set-3.3 {uncompiled set command: error compiling variable name} {
+    set z set
+    $z i 10
+    catch {$z "i"xxx} msg
+    $z msg
+} {extra characters after close-quote}
+test set-3.4 {uncompiled set command: simple variable name in quotes} {
+    set z set
+    $z i 17
+    list [$z "i"] $i
+} {17 17}
+test set-3.5 {uncompiled set command: simple variable name in braces} {
+    set z set
+    catch {unset {a simple var}}
+    $z {a simple var} 27
+    list [$z {a simple var}] ${a simple var}
+} {27 27}
+test set-3.6 {uncompiled set command: simple array variable name} {
+    set z set
+    catch {unset a}
+    $z a(foo) 37
+    list [$z a(foo)] $a(foo)
+} {37 37}
+test set-3.7 {uncompiled set command: non-simple (computed) variable name} {
+    set z set
+    $z x "i"
+    $z i 77
+    list [$z $x] $i
+} {77 77}
+test set-3.8 {uncompiled set command: non-simple (computed) variable name} {
+    set z set
+    $z x "i"
+    $z i 77
+    list [$z [$z x] 2] $i
+} {2 2}
+
+test set-3.9 {uncompiled set command: 3rd arg => assignment} {
+    set z set
+    $z i "abcdef"
+    list [$z i] $i
+} {abcdef abcdef}
+test set-3.10 {uncompiled set command: only two args => just getting value} {
+    set z set
+    $z i {one two}
+    $z i
+} {one two}
+
+test set-3.11 {uncompiled set command: simple global name} {
+    proc p {} {
+	set z set
+        global i
+        $z i 54
+        $z i
+    }
+    p
+} {54}
+test set-3.12 {uncompiled set command: simple local name} {
+    proc p {bar} {
+	set z set
+        $z foo $bar
+        $z foo
+    }
+    p 999
+} {999}
+test set-3.13 {uncompiled set command: simple but new (unknown) local name} {
+    set z set
+    proc p {} {
+	set z set
+        $z bar
+    }
+    catch {p} msg
+    $z msg
+} {can't read "bar": no such variable}
+test set-3.14 {uncompiled set command: simple local name, >255 locals} {
+    proc 260locals {} {
+	set z set
+        # create 260 locals (the last ones with index > 255)
+        $z a0 0; $z a1 0; $z a2 0; $z a3 0; $z a4 0
+        $z a5 0; $z a6 0; $z a7 0; $z a8 0; $z a9 0
+        $z b0 0; $z b1 0; $z b2 0; $z b3 0; $z b4 0
+        $z b5 0; $z b6 0; $z b7 0; $z b8 0; $z b9 0
+        $z c0 0; $z c1 0; $z c2 0; $z c3 0; $z c4 0
+        $z c5 0; $z c6 0; $z c7 0; $z c8 0; $z c9 0
+        $z d0 0; $z d1 0; $z d2 0; $z d3 0; $z d4 0
+        $z d5 0; $z d6 0; $z d7 0; $z d8 0; $z d9 0
+        $z e0 0; $z e1 0; $z e2 0; $z e3 0; $z e4 0
+        $z e5 0; $z e6 0; $z e7 0; $z e8 0; $z e9 0
+        $z f0 0; $z f1 0; $z f2 0; $z f3 0; $z f4 0
+        $z f5 0; $z f6 0; $z f7 0; $z f8 0; $z f9 0
+        $z g0 0; $z g1 0; $z g2 0; $z g3 0; $z g4 0
+        $z g5 0; $z g6 0; $z g7 0; $z g8 0; $z g9 0
+        $z h0 0; $z h1 0; $z h2 0; $z h3 0; $z h4 0
+        $z h5 0; $z h6 0; $z h7 0; $z h8 0; $z h9 0
+        $z i0 0; $z i1 0; $z i2 0; $z i3 0; $z i4 0
+        $z i5 0; $z i6 0; $z i7 0; $z i8 0; $z i9 0
+        $z j0 0; $z j1 0; $z j2 0; $z j3 0; $z j4 0
+        $z j5 0; $z j6 0; $z j7 0; $z j8 0; $z j9 0
+        $z k0 0; $z k1 0; $z k2 0; $z k3 0; $z k4 0
+        $z k5 0; $z k6 0; $z k7 0; $z k8 0; $z k9 0
+        $z l0 0; $z l1 0; $z l2 0; $z l3 0; $z l4 0
+        $z l5 0; $z l6 0; $z l7 0; $z l8 0; $z l9 0
+        $z m0 0; $z m1 0; $z m2 0; $z m3 0; $z m4 0
+        $z m5 0; $z m6 0; $z m7 0; $z m8 0; $z m9 0
+        $z n0 0; $z n1 0; $z n2 0; $z n3 0; $z n4 0
+        $z n5 0; $z n6 0; $z n7 0; $z n8 0; $z n9 0
+        $z o0 0; $z o1 0; $z o2 0; $z o3 0; $z o4 0
+        $z o5 0; $z o6 0; $z o7 0; $z o8 0; $z o9 0
+        $z p0 0; $z p1 0; $z p2 0; $z p3 0; $z p4 0
+        $z p5 0; $z p6 0; $z p7 0; $z p8 0; $z p9 0
+        $z q0 0; $z q1 0; $z q2 0; $z q3 0; $z q4 0
+        $z q5 0; $z q6 0; $z q7 0; $z q8 0; $z q9 0
+        $z r0 0; $z r1 0; $z r2 0; $z r3 0; $z r4 0
+        $z r5 0; $z r6 0; $z r7 0; $z r8 0; $z r9 0
+        $z s0 0; $z s1 0; $z s2 0; $z s3 0; $z s4 0
+        $z s5 0; $z s6 0; $z s7 0; $z s8 0; $z s9 0
+        $z t0 0; $z t1 0; $z t2 0; $z t3 0; $z t4 0
+        $z t5 0; $z t6 0; $z t7 0; $z t8 0; $z t9 0
+        $z u0 0; $z u1 0; $z u2 0; $z u3 0; $z u4 0
+        $z u5 0; $z u6 0; $z u7 0; $z u8 0; $z u9 0
+        $z v0 0; $z v1 0; $z v2 0; $z v3 0; $z v4 0
+        $z v5 0; $z v6 0; $z v7 0; $z v8 0; $z v9 0
+        $z w0 0; $z w1 0; $z w2 0; $z w3 0; $z w4 0
+        $z w5 0; $z w6 0; $z w7 0; $z w8 0; $z w9 0
+        $z x0 0; $z x1 0; $z x2 0; $z x3 0; $z x4 0
+        $z x5 0; $z x6 0; $z x7 0; $z x8 0; $z x9 0
+        $z y0 0; $z y1 0; $z y2 0; $z y3 0; $z y4 0
+        $z y5 0; $z y6 0; $z y7 0; $z y8 0; $z y9 0
+        $z z0 0; $z z1 0; $z z2 0; $z z3 0; $z z4 0
+        $z z5 0; $z z6 0; $z z7 0; $z z8 0; $z z9 1234
+    }
+    260locals
+} {1234}
+test set-3.15 {uncompiled set command: variable is array} {
+    set z set
+    catch {unset a}
+    $z x 27
+    $z x [$z a(foo) 11]
+    catch {unset a}
+    $z x
+} 11
+test set-3.16 {uncompiled set command: variable is array, elem substitutions} {
+    set z set
+    catch {unset a}
+    $z i 5
+    $z x 789
+    $z a(foo5) 27
+    $z x [$z a(foo$i)]
+    catch {unset a}
+    $z x
+} 27
+
+test set-3.17 {uncompiled set command: doing assignment, simple int} {
+    set z set
+    $z i 5
+    $z i 123
+} 123
+test set-3.18 {uncompiled set command: doing assignment, simple int} {
+    set z set
+    $z i 5
+    $z i -100
+} -100
+test set-3.19 {uncompiled set command: doing assignment, simple but not int} {
+    set z set
+    $z i 5
+    $z i 0x12MNOP
+    $z i
+} {0x12MNOP}
+test set-3.20 {uncompiled set command: doing assignment, in quotes} {
+    set z set
+    $z i 25
+    $z i "-100"
+} -100
+test set-3.21 {uncompiled set command: doing assignment, in braces} {
+    set z set
+    $z i 24
+    $z i {126}
+} 126
+test set-3.22 {uncompiled set command: doing assignment, large int} {
+    set z set
+    $z i 5
+    $z i 200000
+} 200000
+test set-3.23 {uncompiled set command: doing assignment, formatted int != int} {
+    set z set
+    $z i 25
+    $z i 0o00012345     ;# an octal literal == 5349 decimal
+    list $i [incr i]
+} {0o00012345 5350}
+
+test set-3.24 {uncompiled set command: too many arguments} {
+    set z set
+    $z i 10
+    catch {$z i 20 30} msg
+    $z msg
+} {wrong # args: should be "set varName ?newValue?"}
+
+test set-4.1 {uncompiled set command: runtime error, bad variable name} -setup {
+    unset -nocomplain {"foo}
+} -body {
+    set z set
+    list [catch {$z {"foo}} msg] $msg $::errorInfo
+} -result {1 {can't read ""foo": no such variable} {can't read ""foo": no such variable
+    while executing
+"$z {"foo}"}}
+# Stop my editor highlighter " from being confused
+test set-4.2 {uncompiled set command: runtime error, not array variable} -setup {
+    catch {unset b}
+} -body {
+    set z set
+    $z b 44
+    list [catch {$z b(123)} msg] $msg
+} -result {1 {can't read "b(123)": variable isn't array}}
+test set-4.3 {uncompiled set command: runtime error, errors in reading variables} -setup {
+    catch {unset a}
+} -body {
+    set z set
+    $z a(6) 44
+    list [catch {$z a(18)} msg] $msg
+} -result {1 {can't read "a(18)": no such element in array}}
+test set-4.4 {uncompiled set command: runtime error, readonly variable} -body {
+    set z set
+    proc readonly args {error "variable is read-only"}
+    $z x 123
+    trace var x w readonly
+    list [catch {$z x 1} msg] $msg $::errorInfo
+} -match glob -result {1 {can't set "x": variable is read-only} {*variable is read-only
+    while executing
+*
+"$z x 1"}}
+test set-4.5 {uncompiled set command: runtime error, basic array operations} -setup {
+    unset -nocomplain a
+    array set a {}
+} -body {
+    set z set
+    list [catch {$z a(other)} msg] $msg
+} -result {1 {can't read "a(other)": no such element in array}}
+test set-4.6 {set command: runtime error, basic array operations} -setup {
+    unset -nocomplain a
+    array set a {}
+} -body {
+    set z set
+    list [catch {$z a} msg] $msg
+} -result {1 {can't read "a": variable is array}}
+
+test set-5.1 {error on malformed array name} -constraints testset2 -setup {
+    unset -nocomplain z
+} -body {
+    catch {testset2 z(a) b} msg
+    catch {testset2 z(b) a} msg1
+    list $msg $msg1
+} -result {{can't read "z(a)(b)": variable isn't array} {can't read "z(b)(a)": variable isn't array}}
+# In a mem-debug build, this test will crash unless Bug 3602706 is fixed.
+test set-5.2 {Bug 3602706} -body {
+    testset2 ::tcl_platform not-in-there
+} -returnCodes error -result * -match glob
+
+# cleanup
+catch {unset a}
+catch {unset b}
+catch {unset i}
+catch {unset x}
+catch {unset z}
+::tcltest::cleanupTests
+return 
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/tests/socket.test b/tests/socket.test
new file mode 100644
index 0000000..d43c41c
--- /dev/null
+++ b/tests/socket.test
@@ -0,0 +1,2413 @@
+# Commands tested in this file: socket.
+#
+# This file contains a collection of tests for one or more of the Tcl built-in
+# commands. Sourcing this file into Tcl runs the tests and generates output
+# for errors. No output means no errors were found.
+#
+# Copyright (c) 1994-1996 Sun Microsystems, Inc.
+# Copyright (c) 1998-2000 Ajuba Solutions.
+#
+# See the file "license.terms" for information on usage and redistribution of
+# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+# Running socket tests with a remote server:
+# ------------------------------------------
+#
+# Some tests in socket.test depend on the existence of a remote server to
+# which they connect. The remote server must be an instance of tcltest and it
+# must run the script found in the file "remote.tcl" in this directory. You
+# can start the remote server on any machine reachable from the machine on
+# which you want to run the socket tests, by issuing:
+#
+#     tcltest remote.tcl -port 2048	# Or choose another port number.
+#
+# If the machine you are running the remote server on has several IP
+# interfaces, you can choose which interface the server listens on for
+# connections by specifying the -address command line flag, so:
+#
+#     tcltest remote.tcl -address your.machine.com
+#
+# These options can also be set by environment variables. On Unix, you can
+# type these commands to the shell from which the remote server is started:
+#
+#     shell% setenv serverPort 2048
+#     shell% setenv serverAddress your.machine.com
+#
+# and subsequently you can start the remote server with:
+#
+#     tcltest remote.tcl
+#
+# to have it listen on port 2048 on the interface your.machine.com.
+#
+# When the server starts, it prints out a detailed message containing its
+# configuration information, and it will block until killed with a Ctrl-C.
+# Once the remote server exists, you can run the tests in socket.test with the
+# server by setting two Tcl variables:
+#
+#     % set remoteServerIP <name or address of machine on which server runs>
+#     % set remoteServerPort 2048
+#
+# These variables are also settable from the environment. On Unix, you can:
+#
+#     shell% setenv remoteServerIP machine.where.server.runs
+#     shell% senetv remoteServerPort 2048
+#
+# The preamble of the socket.test file checks to see if the variables are set
+# either in Tcl or in the environment; if they are, it attempts to connect to
+# the server. If the connection is successful, the tests using the remote
+# server will be performed; otherwise, it will attempt to start the remote
+# server (via exec) on platforms that support this, on the local host,
+# listening at port 2048. If all fails, a message is printed and the tests
+# using the remote server are not performed.
+
+package require tcltest 2
+namespace import -force ::tcltest::*
+
+# Some tests require the Thread package or exec command
+testConstraint thread [expr {0 == [catch {package require Thread 2.7-}]}]
+testConstraint exec [llength [info commands exec]]
+
+# Produce a random port number in the Dynamic/Private range
+# from 49152 through 65535.
+proc randport {} { expr {int(rand()*16383+49152)} }
+
+# Test the latency of tcp connections over the loopback interface. Some OSes
+# (e.g. NetBSD) seem to use the Nagle algorithm and delayed ACKs, so it takes
+# up to 200ms for a packet sent to localhost to arrive. We're measuring this
+# here, so that OSes that don't have this problem can run the tests at full
+# speed.
+set server [socket -server {apply {{s a p} {set ::s1 $s}}} 0]
+set s2 [socket localhost [lindex [fconfigure $server -sockname] 2]]
+vwait s1; close $server
+fconfigure $s1 -buffering line
+fconfigure $s2 -buffering line
+set t1 [clock milliseconds]
+puts $s2 test1; gets $s1
+puts $s2 test2; gets $s1
+close $s1; close $s2
+set t2 [clock milliseconds]
+set lat1 [expr {($t2-$t1)*2}]; # doubled as a safety margin
+
+# Test the latency of failed connection attempts over the loopback
+# interface. They can take more than a second under Windowos and requres
+# additional [after]s in some tests that are not needed on systems that fail
+# immediately.
+set t1 [clock milliseconds]
+catch {socket 127.0.0.1 [randport]}
+set t2 [clock milliseconds]
+set lat2 [expr {($t2-$t1)*3}]
+
+# Use the maximum of the two latency calculations, but at least 100ms
+set latency [expr {$lat1 > $lat2 ? $lat1 : $lat2}]
+set latency [expr {$latency > 100 ? $latency : 1000}]
+unset t1 t2 s1 s2 lat1 lat2 server
+
+# If remoteServerIP or remoteServerPort are not set, check in the environment
+# variables for externally set values.
+#
+
+if {![info exists remoteServerIP]} {
+    if {[info exists env(remoteServerIP)]} {
+	set remoteServerIP $env(remoteServerIP)
+    }
+}
+if {![info exists remoteServerPort]} {
+    if {[info exists env(remoteServerPort)]} {
+	set remoteServerPort $env(remoteServerPort)
+    } else {
+        if {[info exists remoteServerIP]} {
+	    set remoteServerPort 2048
+        }
+    }
+}
+
+if 0 {
+    # activate this to time the tests
+    proc test {args} {
+        set name [lindex $args 0]
+        puts "[lindex [time {uplevel [linsert $args 0 tcltest::test]}] 0] @@@ $name"
+    }
+}
+
+foreach {af localhost} {
+    inet 127.0.0.1
+    inet6 ::1
+} {
+    # Check if the family is supported and set the constraint accordingly
+    testConstraint supported_$af [expr {![catch {socket -server foo -myaddr $localhost 0} sock]}]
+    catch {close $sock}
+}
+
+set sock [socket -server foo -myaddr localhost 0]
+set sockname [fconfigure $sock -sockname]
+close $sock
+testConstraint localhost_v4 [expr {"127.0.0.1" in $sockname}]
+testConstraint localhost_v6 [expr {"::1" in $sockname}]
+
+
+foreach {af localhost} {
+    any 127.0.0.1
+    inet 127.0.0.1
+    inet6 ::1
+} {
+    if {![testConstraint supported_$af]} {
+        continue
+    }
+    set ::tcl::unsupported::socketAF $af
+#
+# Check if we're supposed to do tests against the remote server
+#
+
+set doTestsWithRemoteServer 1
+if {![info exists remoteServerIP]} {
+    set remoteServerIP $localhost
+}
+if {($doTestsWithRemoteServer == 1) && (![info exists remoteServerPort])} {
+    set remoteServerPort [randport]
+}
+
+# Attempt to connect to a remote server if one is already running. If it is
+# not running or for some other reason the connect fails, attempt to start the
+# remote server on the local host listening on port 2048. This is only done on
+# platforms that support exec (i.e. not on the Mac). On platforms that do not
+# support exec, the remote server must be started by the user before running
+# the tests.
+
+set remoteProcChan ""
+set commandSocket ""
+if {$doTestsWithRemoteServer} {
+    catch {close $commandSocket}
+    if {![catch {
+	set commandSocket [socket $remoteServerIP $remoteServerPort]
+    }]} then {
+	fconfigure $commandSocket -translation crlf -buffering line
+    } elseif {![testConstraint exec]} {
+	set noRemoteTestReason "can't exec"
+	set doTestsWithRemoteServer 0
+    } else {
+	set remoteServerIP $localhost
+	# Be *extra* careful in case this file is sourced from
+	# a directory other than the current one...
+	set remoteFile [file join [pwd] [file dirname [info script]] \
+		remote.tcl]
+	if {![catch {
+	    set remoteProcChan [open "|[list \
+		    [interpreter] $remoteFile -serverIsSilent \
+		    -port $remoteServerPort -address $remoteServerIP]" w+]
+	} msg]} then {
+	    gets $remoteProcChan
+	    if {[catch {
+		set commandSocket [socket $remoteServerIP $remoteServerPort]
+	    } msg] == 0} then {
+		fconfigure $commandSocket -translation crlf -buffering line
+	    } else {
+		set noRemoteTestReason $msg
+		set doTestsWithRemoteServer 0
+	    }
+	} else {
+	    set noRemoteTestReason "$msg [interpreter]"
+	    set doTestsWithRemoteServer 0
+	}
+    }
+}
+
+# Some tests are run only if we are doing testing against a remote server.
+testConstraint doTestsWithRemoteServer $doTestsWithRemoteServer
+if {!$doTestsWithRemoteServer} {
+    if {[string first s $::tcltest::verbose] != -1} {
+    	puts "Skipping tests with remote server. See tests/socket.test for"
+	puts "information on how to run remote server."
+	puts "Reason for not doing remote tests: $noRemoteTestReason"
+    }
+}
+
+#
+# If we do the tests, define a command to send a command to the remote server.
+#
+
+if {[testConstraint doTestsWithRemoteServer]} {
+    proc sendCommand {c} {
+	global commandSocket
+
+	if {[eof $commandSocket]} {
+	    error "remote server disappeared"
+	}
+	if {[catch {puts $commandSocket $c} msg]} {
+	    error "remote server disappaered: $msg"
+	}
+	if {[catch {puts $commandSocket "--Marker--Marker--Marker--"} msg]} {
+	    error "remote server disappeared: $msg"
+	}
+
+	while {1} {
+	    set line [gets $commandSocket]
+	    if {[eof $commandSocket]} {
+		error "remote server disappaered"
+	    }
+	    if {$line eq "--Marker--Marker--Marker--"} {
+		lassign $result code info value
+                return -code $code -errorinfo $info $value
+	    }
+            append result $line "\n"
+	}
+    }
+}
+
+proc getPort sock {
+    lindex [fconfigure $sock -sockname] 2
+}
+
+
+# ----------------------------------------------------------------------
+
+test socket_$af-1.1 {arg parsing for socket command} -constraints [list socket supported_$af] -body {
+    socket -server
+} -returnCodes error -result {no argument given for -server option}
+test socket_$af-1.2 {arg parsing for socket command} -constraints [list socket supported_$af] -body {
+    socket -server foo
+} -returnCodes error -result {wrong # args: should be "socket ?-myaddr addr? ?-myport myport? ?-async? host port" or "socket -server command ?-myaddr addr? port"}
+test socket_$af-1.3 {arg parsing for socket command} -constraints [list socket supported_$af] -body {
+    socket -myaddr
+} -returnCodes error -result {no argument given for -myaddr option}
+test socket_$af-1.4 {arg parsing for socket command} -constraints [list socket supported_$af] -body {
+    socket -myaddr $localhost
+} -returnCodes error -result {wrong # args: should be "socket ?-myaddr addr? ?-myport myport? ?-async? host port" or "socket -server command ?-myaddr addr? port"}
+test socket_$af-1.5 {arg parsing for socket command} -constraints [list socket supported_$af] -body {
+    socket -myport
+} -returnCodes error -result {no argument given for -myport option}
+test socket_$af-1.6 {arg parsing for socket command} -constraints [list socket supported_$af] -body {
+    socket -myport xxxx
+} -returnCodes error -result {expected integer but got "xxxx"}
+test socket_$af-1.7 {arg parsing for socket command} -constraints [list socket supported_$af] -body {
+    socket -myport 2522
+} -returnCodes error -result {wrong # args: should be "socket ?-myaddr addr? ?-myport myport? ?-async? host port" or "socket -server command ?-myaddr addr? port"}
+test socket_$af-1.8 {arg parsing for socket command} -constraints [list socket supported_$af] -body {
+    socket -froboz
+} -returnCodes error -result {bad option "-froboz": must be -async, -myaddr, -myport, or -server}
+test socket_$af-1.9 {arg parsing for socket command} -constraints [list socket supported_$af] -body {
+    socket -server foo -myport 2521 3333
+} -returnCodes error -result {option -myport is not valid for servers}
+test socket_$af-1.10 {arg parsing for socket command} -constraints [list socket supported_$af] -body {
+    socket host 2528 -junk
+} -returnCodes error -result {wrong # args: should be "socket ?-myaddr addr? ?-myport myport? ?-async? host port" or "socket -server command ?-myaddr addr? port"}
+test socket_$af-1.11 {arg parsing for socket command} -constraints [list socket supported_$af] -body {
+    socket -server callback 2520 --
+} -returnCodes error -result {wrong # args: should be "socket ?-myaddr addr? ?-myport myport? ?-async? host port" or "socket -server command ?-myaddr addr? port"}
+test socket_$af-1.12 {arg parsing for socket command} -constraints [list socket supported_$af] -body {
+    socket foo badport
+} -returnCodes error -result {expected integer but got "badport"}
+test socket_$af-1.13 {arg parsing for socket command} -constraints [list socket supported_$af] -body {
+    socket -async -server
+} -returnCodes error -result {cannot set -async option for server sockets}
+test socket_$af-1.14 {arg parsing for socket command} -constraints [list socket supported_$af] -body {
+    socket -server foo -async
+} -returnCodes error -result {cannot set -async option for server sockets}
+
+set path(script) [makeFile {} script]
+
+test socket_$af-2.1 {tcp connection} -constraints [list socket supported_$af stdio] -setup {
+    file delete $path(script)
+    set f [open $path(script) w]
+    puts $f {
+	set timer [after 10000 "set x timed_out"]
+	set f [socket -server accept 0]
+	proc accept {file addr port} {
+	    global x
+	    set x done
+            close $file
+	}
+	puts ready
+	puts [lindex [fconfigure $f -sockname] 2]
+	vwait x
+	after cancel $timer
+	close $f
+	puts $x
+    }
+    close $f
+    set f [open "|[list [interpreter] $path(script)]" r]
+    gets $f x
+    gets $f listen
+} -body {
+    # $x == "ready" at this point
+    set sock [socket $localhost $listen]
+    lappend x [gets $f]
+    close $sock
+    lappend x [gets $f]
+} -cleanup {
+    close $f
+} -result {ready done {}}
+test socket_$af-2.2 {tcp connection with client port specified} -setup {
+    set port [randport]
+    file delete $path(script)
+    set f [open $path(script) w]
+    puts $f {
+	set timer [after 10000 "set x timeout"]
+        set f [socket -server accept 0]
+	proc accept {file addr port} {
+            global x
+            puts "[gets $file] $port"
+            close $file
+            set x done
+	}
+	puts ready
+	puts [lindex [fconfigure $f -sockname] 2]
+	vwait x
+	after cancel $timer
+	close $f
+    }
+    close $f
+    set f [open "|[list [interpreter] $path(script)]" r]
+    gets $f x
+    gets $f listen
+} -constraints [list socket supported_$af stdio] -body {
+    # $x == "ready" at this point
+    set sock [socket -myport $port $localhost $listen]
+    puts $sock hello
+    flush $sock
+    lappend x [expr {[gets $f] eq "hello $port"}]
+    close $sock
+    return $x
+} -cleanup {
+    catch {close [socket $localhost $listen]}
+    close $f
+} -result {ready 1}
+test socket_$af-2.3 {tcp connection with client interface specified} -setup {
+    file delete $path(script)
+    set f [open $path(script) w]
+    puts $f {
+	set timer [after 2000 "set x done"]
+        set f [socket  -server accept 0]
+	proc accept {file addr port} {
+            global x
+            puts "[gets $file] $addr"
+            close $file
+            set x done
+	}
+	puts [lindex [fconfigure $f -sockname] 2]
+	puts ready
+	vwait x
+	after cancel $timer
+	close $f
+    }
+    close $f
+    set f [open "|[list [interpreter] $path(script)]" r]
+    gets $f listen
+    gets $f x
+} -constraints [list socket supported_$af stdio] -body {
+    # $x == "ready" at this point
+    set sock [socket -myaddr $localhost $localhost $listen]
+    puts $sock hello
+    flush $sock
+    lappend x [gets $f]
+    close $sock
+    return $x
+} -cleanup {
+    close $f
+} -result [list ready [list hello $localhost]]
+test socket_$af-2.4 {tcp connection with server interface specified} -setup {
+    file delete $path(script)
+    set f [open $path(script) w]
+    puts $f [list set localhost $localhost]
+    puts $f {
+	set timer [after 2000 "set x done"]
+        set f [socket -server accept -myaddr $localhost 0]
+	proc accept {file addr port} {
+            global x
+            puts "[gets $file]"
+            close $file
+            set x done
+	}
+	puts ready
+	puts [lindex [fconfigure $f -sockname] 2]
+	vwait x
+	after cancel $timer
+	close $f
+    }
+    close $f
+    set f [open "|[list [interpreter] $path(script)]" r]
+    gets $f x
+    gets $f listen
+} -constraints [list socket supported_$af stdio] -body {
+    # $x == "ready" at this point
+    set sock [socket $localhost $listen]
+    puts $sock hello
+    flush $sock
+    lappend x [gets $f]
+    close $sock
+    return $x
+} -cleanup {
+    close $f
+} -result {ready hello}
+test socket_$af-2.5 {tcp connection with redundant server port} -setup {
+    file delete $path(script)
+    set f [open $path(script) w]
+    puts $f {
+	set timer [after 10000 "set x timeout"]
+        set f [socket -server accept 0]
+	proc accept {file addr port} {
+            global x
+            puts "[gets $file]"
+            close $file
+            set x done
+	}
+	puts ready
+	puts [lindex [fconfigure $f -sockname] 2]
+	vwait x
+	after cancel $timer
+	close $f
+    }
+    close $f
+    set f [open "|[list [interpreter] $path(script)]" r]
+    gets $f x
+    gets $f listen
+} -constraints [list socket supported_$af stdio] -body {
+    # $x == "ready" at this point
+    set sock [socket $localhost $listen]
+    puts $sock hello
+    flush $sock
+    lappend x [gets $f]
+    close $sock
+    return $x
+} -cleanup {
+    close $f
+} -result {ready hello}
+test socket_$af-2.6 {tcp connection} -constraints [list socket supported_$af] -body {
+    set status ok
+    if {![catch {set sock [socket $localhost [randport]]}]} {
+	if {![catch {gets $sock}]} {
+	    set status broken
+	}
+	close $sock
+    }
+    set status
+} -result ok
+test socket_$af-2.7 {echo server, one line} -constraints [list socket supported_$af stdio] -setup {
+    file delete $path(script)
+    set f [open $path(script) w]
+    puts $f {
+	set timer [after 10000 "set x timeout"]
+	set f [socket -server accept 0]
+	proc accept {s a p} {
+            fileevent $s readable [list echo $s]
+	    fconfigure $s -translation lf -buffering line
+        }
+	proc echo {s} {
+	     set l [gets $s]
+             if {[eof $s]} {
+                 global x
+                 close $s
+                 set x done
+             } else {
+                 puts $s $l
+             }
+	}
+	puts ready
+	puts [lindex [fconfigure $f -sockname] 2]
+	vwait x
+	after cancel $timer
+	close $f
+	puts $x
+    }
+    close $f
+    set f [open "|[list [interpreter] $path(script)]" r]
+    gets $f
+    gets $f listen
+} -body {
+    set s [socket $localhost $listen]
+    fconfigure $s -buffering line -translation lf
+    puts $s "hello abcdefghijklmnop"
+    set x [gets $s]
+    close $s
+    list $x [gets $f]
+} -cleanup {
+    close $f
+} -result {{hello abcdefghijklmnop} done}
+removeFile script
+test socket_$af-2.8 {echo server, loop 50 times, single connection} -setup {
+    set path(script) [makeFile {
+	set f [socket -server accept 0]
+	proc accept {s a p} {
+            fileevent $s readable [list echo $s]
+            fconfigure $s -buffering line
+        }
+	proc echo {s} {
+	     global i
+             set l [gets $s]
+             if {[eof $s]} {
+                 global x
+                 close $s
+                 set x done
+             } else {
+	         incr i
+                 puts $s $l
+             }
+	}
+	set i 0
+	puts ready
+	puts [lindex [fconfigure $f -sockname] 2]
+	set timer [after 20000 "set x done"]
+	vwait x
+	after cancel $timer
+	close $f
+	puts "done $i"
+    } script]
+    set f [open "|[list [interpreter] $path(script)]" r]
+    gets $f
+    gets $f listen
+} -constraints [list socket supported_$af stdio] -body {
+    set s [socket $localhost $listen]
+    fconfigure $s -buffering line
+    catch {
+	for {set x 0} {$x < 50} {incr x} {
+	    puts $s "hello abcdefghijklmnop"
+	    gets $s
+	}
+    }
+    close $s
+    catch {set x [gets $f]}
+    return $x
+} -cleanup {
+    close $f
+    removeFile script
+} -result {done 50}
+set path(script) [makeFile {} script]
+test socket_$af-2.9 {socket conflict} -constraints [list socket supported_$af stdio] -body {
+    set s [socket -server accept 0]
+    file delete $path(script)
+    set f [open $path(script) w]
+    puts $f [list set ::tcl::unsupported::socketAF $::tcl::unsupported::socketAF]
+    puts $f "socket -server accept [lindex [fconfigure $s -sockname] 2]"
+    close $f
+    set f [open "|[list [interpreter] $path(script)]" r]
+    gets $f
+    after 100
+    close $f
+} -returnCodes error -cleanup {
+    close $s
+} -match glob -result {couldn't open socket: address already in use*}
+test socket_$af-2.10 {close on accept, accepted socket lives} -setup {
+    set done 0
+    set timer [after 20000 "set done timed_out"]
+} -constraints [list socket supported_$af] -body {
+    set ss [socket -server accept 0]
+    proc accept {s a p} {
+	global ss
+	close $ss
+	fileevent $s readable "readit $s"
+	fconfigure $s -trans lf
+    }
+    proc readit {s} {
+	global done
+	gets $s
+	close $s
+	set done 1
+    }
+    set cs [socket $localhost [lindex [fconfigure $ss -sockname] 2]]
+    puts $cs hello
+    close $cs
+    vwait done
+    return $done
+} -cleanup {
+    after cancel $timer
+} -result 1
+test socket_$af-2.11 {detecting new data} -constraints [list socket supported_$af] -setup {
+    proc accept {s a p} {
+	global sock
+	set sock $s
+    }
+    set s [socket -server accept 0]
+    set sock ""
+} -body {
+    set s2 [socket $localhost [lindex [fconfigure $s -sockname] 2]]
+    vwait sock
+    puts $s2 one
+    flush $s2
+    after idle {set x 1}
+    vwait x
+    fconfigure $sock -blocking 0
+    set result a:[gets $sock]
+    lappend result b:[gets $sock]
+    fconfigure $sock -blocking 1
+    puts $s2 two
+    flush $s2
+    after $latency {set x 1}; # NetBSD fails here if we do [after idle]
+    vwait x
+    fconfigure $sock -blocking 0
+    lappend result c:[gets $sock]
+} -cleanup {
+    fconfigure $sock -blocking 1
+    close $s2
+    close $s
+    close $sock
+} -result {a:one b: c:two}
+test socket_$af-2.12 {} [list socket stdio supported_$af] {
+    file delete $path(script)
+    set f [open $path(script) w]
+    puts $f {
+	set server [socket -server accept_client 0]
+	puts [lindex [chan configure $server -sockname] 2]
+	proc accept_client { client host port } {
+	    chan configure $client -blocking  0 -buffering line
+	    write_line $client
+	}
+	proc write_line client {
+	    if { [catch { chan puts $client [string repeat . 720000]}] } {
+		puts [catch {chan close $client}]
+	    } else {
+		puts signal1
+		after 0 write_line $client
+	    }
+	}
+	chan event stdin readable {set forever now}
+	vwait forever
+	exit
+    }
+    close $f
+    set f [open "|[list [interpreter] $path(script)]" r+]
+    gets $f port
+    set sock [socket $localhost $port]
+    chan event $sock readable [list read_lines $sock $f]
+    proc read_lines { sock pipe } {
+	gets $pipe
+	chan close $sock
+	chan event $pipe readable [list readpipe $pipe]
+    }
+    proc readpipe {pipe} {
+	while {![string is integer [set ::done [gets $pipe]]]} {}
+    }
+    vwait ::done
+    close $f
+    set ::done
+} 0
+test socket_$af-2.13 {Bug 1758a0b603} {socket stdio} {
+    file delete $path(script)
+    set f [open $path(script) w]
+    puts $f {
+	set server [socket -server accept 0]
+	puts [lindex [chan configure $server -sockname] 2]
+	proc accept { client host port } {
+	    chan configure $client -blocking  0 -buffering line -buffersize 1
+	    puts $client [string repeat . 720000]
+	    puts ready
+	    chan event $client writable [list setup $client]
+	}
+	proc setup client {
+	    chan event $client writable {set forever write}
+	    after 5 {set forever timeout}
+	}
+	vwait forever
+	puts $forever
+    }
+    close $f
+    set pipe [open |[list [interpreter] $path(script)] r]
+    gets $pipe port
+    set sock [socket $localhost $port]
+    chan configure $sock -blocking  0 -buffering line
+    chan event $sock readable [list read_lines $sock $pipe ]
+    proc read_lines { sock pipe } {
+	gets $pipe
+	gets $sock line
+	after idle [list stop $sock $pipe]
+	chan event $sock readable {}
+    }
+    proc stop {sock pipe} {
+	variable done
+	close $sock
+	set done [gets $pipe]
+    }
+    variable done
+    vwait [namespace which -variable done]
+    close $pipe
+    set done
+} write
+
+test socket_$af-3.1 {socket conflict} -constraints [list socket supported_$af stdio] -setup {
+    file delete $path(script)
+    set f [open $path(script) w]
+    puts $f [list set localhost $localhost]
+    puts $f {
+	set f [socket -server accept -myaddr $localhost 0]
+	puts ready
+	puts [lindex [fconfigure $f -sockname] 2]
+	gets stdin
+	close $f
+    }
+    close $f
+    set f [open "|[list [interpreter] $path(script)]" r+]
+    gets $f
+    gets $f listen
+} -body {
+    socket -server accept -myaddr $localhost $listen
+} -cleanup {
+    puts $f bye
+    close $f
+} -returnCodes error -result {couldn't open socket: address already in use}
+test socket_$af-3.2 {server with several clients} -setup {
+    file delete $path(script)
+    set f [open $path(script) w]
+    puts $f [list set localhost $localhost]
+    puts $f {
+	set t1 [after 30000 "set x timed_out"]
+	set t2 [after 31000 "set x timed_out"]
+	set t3 [after 32000 "set x timed_out"]
+	set counter 0
+	set s [socket -server accept -myaddr $localhost 0]
+	proc accept {s a p} {
+	    fileevent $s readable [list echo $s]
+	    fconfigure $s -buffering line
+	}
+	proc echo {s} {
+	     global x
+             set l [gets $s]
+             if {[eof $s]} {
+                 close $s
+                 set x done
+             } else {
+                 puts $s $l
+             }
+	}
+	puts ready
+	puts [lindex [fconfigure $s -sockname] 2]
+	vwait x
+	after cancel $t1
+	vwait x
+	after cancel $t2
+	vwait x
+	after cancel $t3
+	close $s
+	puts $x
+    }
+    close $f
+    set f [open "|[list [interpreter] $path(script)]" r+]
+    set x [gets $f]
+    gets $f listen
+} -constraints [list socket supported_$af stdio] -body {
+    # $x == "ready" here
+    set s1 [socket $localhost $listen]
+    fconfigure $s1 -buffering line
+    set s2 [socket $localhost $listen]
+    fconfigure $s2 -buffering line
+    set s3 [socket $localhost $listen]
+    fconfigure $s3 -buffering line
+    for {set i 0} {$i < 100} {incr i} {
+	puts $s1 hello,s1
+	gets $s1
+	puts $s2 hello,s2
+	gets $s2
+	puts $s3 hello,s3
+	gets $s3
+    }
+    close $s1
+    close $s2
+    close $s3
+    lappend x [gets $f]
+} -cleanup {
+    close $f
+} -result {ready done}
+
+test socket_$af-4.1 {server with several clients} -setup {
+    file delete $path(script)
+    set f [open $path(script) w]
+    puts $f [list set localhost $localhost]
+    puts $f {
+	set port [gets stdin]
+	set s [socket $localhost $port]
+	fconfigure $s -buffering line
+	for {set i 0} {$i < 100} {incr i} {
+	    puts $s hello
+	    gets $s
+	}
+	close $s
+	puts bye
+	gets stdin
+    }
+    close $f
+    set p1 [open "|[list [interpreter] $path(script)]" r+]
+    fconfigure $p1 -buffering line
+    set p2 [open "|[list [interpreter] $path(script)]" r+]
+    fconfigure $p2 -buffering line
+    set p3 [open "|[list [interpreter] $path(script)]" r+]
+    fconfigure $p3 -buffering line
+} -constraints [list socket supported_$af stdio] -body {
+    proc accept {s a p} {
+	fconfigure $s -buffering line
+	fileevent $s readable [list echo $s]
+    }
+    proc echo {s} {
+	global x
+        set l [gets $s]
+        if {[eof $s]} {
+            close $s
+            set x done
+        } else {
+            puts $s $l
+        }
+    }
+    set t1 [after 30000 "set x timed_out"]
+    set t2 [after 31000 "set x timed_out"]
+    set t3 [after 32000 "set x timed_out"]
+    set s [socket -server accept -myaddr $localhost 0]
+    set listen [lindex [fconfigure $s -sockname] 2]
+    puts $p1 $listen
+    puts $p2 $listen
+    puts $p3 $listen
+    vwait x
+    vwait x
+    vwait x
+    after cancel $t1
+    after cancel $t2
+    after cancel $t3
+    close $s
+    set l ""
+    lappend l [list p1 [gets $p1] $x]
+    lappend l [list p2 [gets $p2] $x]
+    lappend l [list p3 [gets $p3] $x]
+} -cleanup {
+    puts $p1 bye
+    puts $p2 bye
+    puts $p3 bye
+    close $p1
+    close $p2
+    close $p3
+} -result {{p1 bye done} {p2 bye done} {p3 bye done}}
+test socket_$af-4.2 {byte order problems, socket numbers, htons} -body {
+    close [socket -server dodo -myaddr $localhost 0x3000]
+    return ok
+} -constraints [list socket supported_$af] -result ok
+
+test socket_$af-5.1 {byte order problems, socket numbers, htons} -body {
+    if {![catch {socket -server dodo 0x1} msg]} {
+	close $msg
+        return {htons problem, should be disallowed, are you running as SU?}
+    }
+    return {couldn't open socket: not owner}
+} -constraints [list socket supported_$af unix notRoot] -result {couldn't open socket: not owner}
+test socket_$af-5.2 {byte order problems, socket numbers, htons} -body {
+    if {![catch {socket -server dodo 0x10000} msg]} {
+	close $msg
+	return {port resolution problem, should be disallowed}
+    }
+    return {couldn't open socket: port number too high}
+} -constraints [list socket supported_$af] -result {couldn't open socket: port number too high}
+test socket_$af-5.3 {byte order problems, socket numbers, htons} -body {
+    if {![catch {socket -server dodo 21} msg]} {
+	close $msg
+	return {htons problem, should be disallowed, are you running as SU?}
+    }
+    return {couldn't open socket: not owner}
+} -constraints [list socket supported_$af unix notRoot] -result {couldn't open socket: not owner}
+
+test socket_$af-6.1 {accept callback error} -constraints [list socket supported_$af stdio] -setup {
+    proc myHandler {msg options} {
+	variable x $msg
+    }
+    set handler [interp bgerror {}]
+    interp bgerror {} [namespace which myHandler]
+    file delete $path(script)
+} -body {
+    set f [open $path(script) w]
+    puts $f [list set localhost $localhost]
+    puts $f {
+	gets stdin port
+	socket $localhost $port
+    }
+    close $f
+    set f [open "|[list [interpreter] $path(script)]" r+]
+    proc accept {s a p} {expr 10 / 0}
+    set s [socket -server accept -myaddr $localhost 0]
+    puts $f [lindex [fconfigure $s -sockname] 2]
+    close $f
+    set timer [after 10000 "set x timed_out"]
+    vwait x
+    after cancel $timer
+    close $s
+    return $x
+} -cleanup {
+    interp bgerror {} $handler
+} -result {divide by zero}
+
+test socket_$af-6.2 {
+    readable fileevent on server socket
+} -setup {
+    set sock [socket -server dummy 0]
+} -constraints [list socket supported_$af] -body {
+    fileevent $sock readable dummy
+} -cleanup {
+    close $sock
+} -returnCodes 1 -result "channel is not readable"
+
+test socket_$af-6.3 {writable fileevent on server socket} -setup {
+    set sock [socket -server dummy 0]
+} -constraints [list socket supported_$af] -body {
+    fileevent $sock writable dummy
+} -cleanup {
+    close $sock
+} -returnCodes 1 -result "channel is not writable"
+
+test socket_$af-7.1 {testing socket specific options} -setup {
+    file delete $path(script)
+    set f [open $path(script) w]
+    puts $f {
+	set ss [socket -server accept 0]
+	proc accept args {
+	    global x
+	    set x done
+	}
+	puts ready
+	puts [lindex [fconfigure $ss -sockname] 2]
+	set timer [after 10000 "set x timed_out"]
+	vwait x
+	after cancel $timer
+    }
+    close $f
+    set f [open "|[list [interpreter] $path(script)]" r]
+    gets $f
+    gets $f listen
+    set l ""
+} -constraints [list socket supported_$af stdio] -body {
+    set s [socket $localhost $listen]
+    set p [fconfigure $s -peername]
+    close $s
+    lappend l [string compare [lindex $p 0] $localhost]
+    lappend l [string compare [lindex $p 2] $listen]
+    lappend l [llength $p]
+} -cleanup {
+    close $f
+} -result {0 0 3}
+test socket_$af-7.2 {testing socket specific options} -setup {
+    file delete $path(script)
+    set f [open $path(script) w]
+    puts $f [list set ::tcl::unsupported::socketAF $::tcl::unsupported::socketAF]
+    puts $f {
+	set ss [socket -server accept 0]
+	proc accept args {
+	    global x
+	    set x done
+	}
+	puts ready
+	puts [lindex [fconfigure $ss -sockname] 2]
+	set timer [after 10000 "set x timed_out"]
+	vwait x
+	after cancel $timer
+    }
+    close $f
+    set f [open "|[list [interpreter] $path(script)]" r]
+    gets $f
+    gets $f listen
+} -constraints [list socket supported_$af stdio] -body {
+    set s [socket $localhost $listen]
+    set p [fconfigure $s -sockname]
+    close $s
+    list [llength $p] \
+	    [regexp {^(127\.0\.0\.1|0\.0\.0\.0|::1)$} [lindex $p 0]] \
+	    [expr {[lindex $p 2] == $listen}]
+} -cleanup {
+    close $f
+} -result {3 1 0}
+test socket_$af-7.3 {testing socket specific options} -constraints [list socket supported_$af] -body {
+    set s [socket -server accept -myaddr $localhost 0]
+    set l [fconfigure $s]
+    close $s
+    update
+    llength $l
+} -result 14
+test socket_$af-7.4 {testing socket specific options} -constraints [list socket supported_$af] -setup {
+    set timer [after 10000 "set x timed_out"]
+    set l ""
+} -body {
+    set s [socket -server accept -myaddr $localhost 0]
+    proc accept {s a p} {
+	global x
+	set x [fconfigure $s -sockname]
+	close $s
+    }
+    set listen [lindex [fconfigure $s -sockname] 2]
+    set s1 [socket $localhost $listen]
+    vwait x
+    lappend l [expr {[lindex $x 2] == $listen}] [llength $x]
+} -cleanup {
+    after cancel $timer
+    close $s
+    close $s1
+} -result {1 3}
+test socket_$af-7.5 {testing socket specific options} -setup {
+    set timer [after 10000 "set x timed_out"]
+    set l ""
+} -constraints [list socket supported_$af unixOrPc] -body {
+    set s [socket -server accept 0]
+    proc accept {s a p} {
+	global x
+	set x [fconfigure $s -sockname]
+	close $s
+    }
+    set listen [lindex [fconfigure $s -sockname] 2]
+    set s1 [socket $localhost $listen]
+    vwait x
+    lappend l [lindex $x 0] [expr {[lindex $x 2] == $listen}] [llength $x]
+} -cleanup {
+    after cancel $timer
+    close $s
+    close $s1
+} -result [list $localhost 1 3]
+
+test socket_$af-8.1 {testing -async flag on sockets} -constraints [list socket supported_$af] -body {
+    # NOTE: This test may fail on some Solaris 2.4 systems. If it does, check
+    # that you have these patches installed (using showrev -p):
+    #
+    # 101907-05, 101925-02, 101945-14, 101959-03, 101969-05, 101973-03,
+    # 101977-03, 101981-02, 101985-01, 102001-03, 102003-01, 102007-01,
+    # 102011-02, 102024-01, 102039-01, 102044-01, 102048-01, 102062-03,
+    # 102066-04, 102070-01, 102105-01, 102153-03, 102216-01, 102232-01,
+    # 101878-03, 101879-01, 101880-03, 101933-01, 101950-01, 102030-01,
+    # 102057-08, 102140-01, 101920-02, 101921-09, 101922-07, 101923-03
+    #
+    # If after installing these patches you are still experiencing a problem,
+    # please email jyl@eng.sun.com. We have not observed this failure on
+    # Solaris 2.5, so another option (instead of installing these patches) is
+    # to upgrade to Solaris 2.5.
+    set s [socket -server accept -myaddr $localhost 0]
+    proc accept {s a p} {
+	global x
+	puts $s bye
+	close $s
+	set x done
+    }
+    set s1 [socket -async $localhost [lindex [fconfigure $s -sockname] 2]]
+    vwait x
+    gets $s1
+} -cleanup {
+    close $s
+    close $s1
+} -result bye
+
+test socket_$af-9.1 {testing spurious events} -constraints [list socket supported_$af] -setup {
+    set len 0
+    set spurious 0
+    set done 0
+    set timer [after 10000 "set done timed_out"]
+} -body {
+    proc readlittle {s} {
+	global spurious done len
+	set l [read $s 1]
+	if {[string length $l] == 0} {
+	    if {![eof $s]} {
+		incr spurious
+	    } else {
+		close $s
+		set done 1
+	    }
+	} else {
+	    incr len [string length $l]
+	}
+    }
+    proc accept {s a p} {
+	fconfigure $s -buffering none -blocking off
+	fileevent $s readable [list readlittle $s]
+    }
+    set s [socket -server accept -myaddr $localhost 0]
+    set c [socket $localhost [lindex [fconfigure $s -sockname] 2]]
+    puts -nonewline $c 01234567890123456789012345678901234567890123456789
+    close $c
+    vwait done
+    close $s
+    list $spurious $len
+} -cleanup {
+    after cancel $timer
+} -result {0 50}
+test socket_$af-9.2 {testing async write, fileevents, flush on close} -constraints [list socket supported_$af] -setup {
+    set firstblock ""
+    for {set i 0} {$i < 5} {incr i} {set firstblock "a$firstblock$firstblock"}
+    set secondblock ""
+    for {set i 0} {$i < 16} {incr i} {
+	set secondblock "b$secondblock$secondblock"
+    }
+    set timer [after 10000 "set done timed_out"]
+    set l [socket -server accept -myaddr $localhost 0]
+    proc accept {s a p} {
+	fconfigure $s -blocking 0 -translation lf -buffersize 16384 \
+		-buffering line
+	fileevent $s readable "readable $s"
+    }
+    proc readable {s} {
+	set l [gets $s]
+	fileevent $s readable {}
+	after idle respond $s
+    }
+    proc respond {s} {
+	global firstblock
+	puts -nonewline $s $firstblock
+	after idle writedata $s
+    }
+    proc writedata {s} {
+	global secondblock
+	puts -nonewline $s $secondblock
+	close $s
+    }
+} -body {
+    set s [socket $localhost [lindex [fconfigure $l -sockname] 2]]
+    fconfigure $s -blocking 0 -trans lf -buffering line
+    set count 0
+    puts $s hello
+    proc readit {s} {
+	global count done
+	set l [read $s]
+	incr count [string length $l]
+	if {[eof $s]} {
+	    close $s
+	    set done 1
+	}
+    }
+    fileevent $s readable "readit $s"
+    vwait done
+    return $count
+} -cleanup {
+    close $l
+    after cancel $timer
+} -result 65566
+test socket_$af-9.3 {testing EOF stickyness} -constraints [list socket supported_$af] -setup {
+    set count 0
+    set done false
+    proc write_then_close {s} {
+	puts $s bye
+	close $s
+    }
+    proc accept {s a p} {
+	fconfigure $s -buffering line -translation lf
+	fileevent $s writable "write_then_close $s"
+    }
+    set s [socket -server accept -myaddr $localhost 0]
+} -body {
+    proc count_to_eof {s} {
+	global count done
+	set l [gets $s]
+	if {[eof $s]} {
+	    incr count
+	    if {$count > 9} {
+		close $s
+		set done true
+		set count {eof is sticky}
+	    }
+	}
+    }
+    proc timerproc {s} {
+	global done count
+	set done true
+	set count {timer went off, eof is not sticky}
+	close $s
+    }
+    set c [socket $localhost [lindex [fconfigure $s -sockname] 2]]
+    fconfigure $c -blocking off -buffering line -translation lf
+    fileevent $c readable "count_to_eof $c"
+    set timer [after 1000 timerproc $c]
+    vwait done
+    return $count
+} -cleanup {
+    close $s
+    after cancel $timer
+} -result {eof is sticky}
+
+removeFile script
+
+test socket_$af-10.1 {testing socket accept callback error handling} \
+    -constraints [list socket supported_$af] -setup {
+    variable goterror 0
+    proc myHandler {msg options} {
+	variable goterror 1
+    }
+    set handler [interp bgerror {}]
+    interp bgerror {} [namespace which myHandler]
+} -body {
+    set s [socket -server accept -myaddr $localhost 0]
+    proc accept {s a p} {close $s; error}
+    set c [socket $localhost [lindex [fconfigure $s -sockname] 2]]
+    vwait goterror
+    close $s
+    close $c
+    return $goterror
+} -cleanup {
+    interp bgerror {} $handler
+} -result 1
+
+test socket_$af-11.1 {tcp connection} -setup {
+    set port [sendCommand {
+	set server [socket -server accept 0]
+	proc accept {s a p} {
+	    puts $s done
+	    close $s
+	}
+	getPort $server
+    }]
+} -constraints [list socket supported_$af doTestsWithRemoteServer] -body {
+    set s [socket $remoteServerIP $port]
+    gets $s
+} -cleanup {
+    close $s
+    sendCommand {close $server}
+} -result done
+test socket_$af-11.2 {client specifies its port} -setup {
+    set lport [randport]
+    set rport [sendCommand {
+	set server [socket -server accept 0]
+	proc accept {s a p} {
+	    puts $s $p
+	    close $s
+	}
+	getPort $server
+    }]
+} -constraints [list socket supported_$af doTestsWithRemoteServer] -body {
+    set s [socket -myport $lport $remoteServerIP $rport]
+    set r [gets $s]
+    expr {$r==$lport ? "ok" : "broken: $r != $port"}
+} -cleanup {
+    close $s
+    sendCommand {close $server}
+} -result ok
+test socket_$af-11.3 {trying to connect, no server} -body {
+    set status ok
+    if {![catch {set s [socket $remoteServerIp [randport]]}]} {
+	if {![catch {gets $s}]} {
+	    set status broken
+	}
+	close $s
+    }
+    return $status
+} -constraints [list socket supported_$af doTestsWithRemoteServer] -result ok
+test socket_$af-11.4 {remote echo, one line} -setup {
+    set port [sendCommand {
+	set server [socket -server accept 0]
+	proc accept {s a p} {
+	    fileevent $s readable [list echo $s]
+	    fconfigure $s -buffering line -translation crlf
+	}
+	proc echo {s} {
+	    set l [gets $s]
+	    if {[eof $s]} {
+		close $s
+	    } else {
+		puts $s $l
+	    }
+	}
+	getPort $server
+    }]
+} -constraints [list socket supported_$af doTestsWithRemoteServer] -body {
+    set f [socket $remoteServerIP $port]
+    fconfigure $f -translation crlf -buffering line
+    puts $f hello
+    gets $f
+} -cleanup {
+    catch {close $f}
+    sendCommand {close $server}
+} -result hello
+test socket_$af-11.5 {remote echo, 50 lines} -setup {
+    set port [sendCommand {
+	set server [socket -server accept 0]
+	proc accept {s a p} {
+	    fileevent $s readable [list echo $s]
+	    fconfigure $s -buffering line -translation crlf
+	}
+	proc echo {s} {
+	    set l [gets $s]
+	    if {[eof $s]} {
+		close $s
+	    } else {
+		puts $s $l
+	    }
+	}
+	getPort $server
+    }]
+} -constraints [list socket supported_$af doTestsWithRemoteServer] -body {
+    set f [socket $remoteServerIP $port]
+    fconfigure $f -translation crlf -buffering line
+    for {set cnt 0} {$cnt < 50} {incr cnt} {
+	puts $f "hello, $cnt"
+	if {[gets $f] != "hello, $cnt"} {
+	    break
+	}
+    }
+    return $cnt
+} -cleanup {
+    close $f
+    sendCommand {close $server}
+} -result 50
+test socket_$af-11.6 {socket conflict} -setup {
+    set s1 [socket -server accept -myaddr $localhost 0]
+} -constraints [list socket supported_$af doTestsWithRemoteServer] -body {
+    set s2 [socket -server accept -myaddr $localhost [getPort $s1]]
+    list [getPort $s2] [close $s2]
+} -cleanup {
+    close $s1
+} -returnCodes error -result {couldn't open socket: address already in use}
+test socket_$af-11.7 {server with several clients} -setup {
+    set port [sendCommand {
+	set server [socket -server accept 0]
+	proc accept {s a p} {
+	    fconfigure $s -buffering line
+	    fileevent $s readable [list echo $s]
+	}
+	proc echo {s} {
+	    set l [gets $s]
+	    if {[eof $s]} {
+		close $s
+	    } else {
+		puts $s $l
+	    }
+	}
+	getPort $server
+    }]
+} -constraints [list socket supported_$af doTestsWithRemoteServer] -body {
+    set s1 [socket $remoteServerIP $port]
+    fconfigure $s1 -buffering line
+    set s2 [socket $remoteServerIP $port]
+    fconfigure $s2 -buffering line
+    set s3 [socket $remoteServerIP $port]
+    fconfigure $s3 -buffering line
+    for {set i 0} {$i < 100} {incr i} {
+	puts $s1 hello,s1
+	gets $s1
+	puts $s2 hello,s2
+	gets $s2
+	puts $s3 hello,s3
+	gets $s3
+    }
+    return $i
+} -cleanup {
+    close $s1
+    close $s2
+    close $s3
+    sendCommand {close $server}
+} -result 100
+test socket_$af-11.8 {client with several servers} -setup {
+    lassign [sendCommand {
+	set s1 [socket -server "accept server1" 0]
+	set s2 [socket -server "accept server2" 0]
+	set s3 [socket -server "accept server3" 0]
+	proc accept {mp s a p} {
+	    puts $s $mp
+	    close $s
+	}
+	list [getPort $s1] [getPort $s2] [getPort $s3]
+    }] p1 p2 p3
+} -constraints [list socket supported_$af doTestsWithRemoteServer] -body {
+    set s1 [socket $remoteServerIP $p1]
+    set s2 [socket $remoteServerIP $p2]
+    set s3 [socket $remoteServerIP $p3]
+    list [gets $s1] [gets $s1] [eof $s1] [gets $s2] [gets $s2] [eof $s2] \
+	[gets $s3] [gets $s3] [eof $s3]
+} -cleanup {
+    close $s1
+    close $s2
+    close $s3
+    sendCommand {
+	close $s1
+	close $s2
+	close $s3
+    }
+} -result {server1 {} 1 server2 {} 1 server3 {} 1}
+test socket_$af-11.9 {accept callback error} -constraints [list socket supported_$af doTestsWithRemoteServer] -setup {
+    proc myHandler {msg options} {
+	variable x $msg
+    }
+    set handler [interp bgerror {}]
+    interp bgerror {} [namespace which myHandler]
+    set timer [after 10000 "set x timed_out"]
+} -body {
+    set s [socket -server accept 0]
+    proc accept {s a p} {expr {10 / 0}}
+    sendCommand "set port [getPort $s]"
+    if {[catch {
+	sendCommand {
+	    set peername [fconfigure $callerSocket -peername]
+	    set s [socket [lindex $peername 0] $port]
+	    close $s
+    	 }
+    } msg]} then {
+	close $s
+	error $msg
+    }
+    vwait x
+    return $x
+} -cleanup {
+    close $s
+    after cancel $timer
+    interp bgerror {} $handler
+} -result {divide by zero}
+test socket_$af-11.10 {testing socket specific options} -setup {
+    set port [sendCommand {
+	set server [socket -server accept 0]
+	proc accept {s a p} {close $s}
+	getPort $server
+    }]
+} -constraints [list socket supported_$af doTestsWithRemoteServer] -body {
+    set s [socket $remoteServerIP $port]
+    set p [fconfigure $s -peername]
+    set n [fconfigure $s -sockname]
+    list [expr {[lindex $p 2] == $port}] [llength $p] [llength $n]
+} -cleanup {
+    close $s
+    sendCommand {close $server}
+} -result {1 3 3}
+test socket_$af-11.11 {testing spurious events} -setup {
+    set port [sendCommand {
+	set server [socket -server accept 0]
+	proc accept {s a p} {
+	    fconfigure $s -translation "auto lf"
+	    after idle writesome $s
+	}
+	proc writesome {s} {
+	    for {set i 0} {$i < 100} {incr i} {
+		puts $s "line $i from remote server"
+	    }
+	    close $s
+	}
+	getPort $server
+    }]
+    set len 0
+    set spurious 0
+    set done 0
+    set timer [after 40000 "set done timed_out"]
+} -constraints [list socket supported_$af doTestsWithRemoteServer] -body {
+    proc readlittle {s} {
+	global spurious done len
+	set l [read $s 1]
+	if {[string length $l] == 0} {
+	    if {![eof $s]} {
+		incr spurious
+	    } else {
+		close $s
+		set done 1
+	    }
+	} else {
+	    incr len [string length $l]
+	}
+    }
+    set c [socket $remoteServerIP $port]
+    fileevent $c readable "readlittle $c"
+    vwait done
+    list $spurious $len $done
+} -cleanup {
+    after cancel $timer
+    sendCommand {close $server}
+} -result {0 2690 1}
+test socket_$af-11.12 {testing EOF stickyness} -constraints [list socket supported_$af doTestsWithRemoteServer] -setup {
+    set counter 0
+    set done 0
+    set port [sendCommand {
+	set server [socket -server accept 0]
+	proc accept {s a p} {
+	    after idle close $s
+	}
+	getPort $server
+    }]
+    proc timed_out {} {
+	global c done
+	set done {timed_out, EOF is not sticky}
+	close $c
+    }
+    set after_id [after 1000 timed_out]
+} -body {
+    proc count_up {s} {
+	global counter done
+	set l [gets $s]
+	if {[eof $s]} {
+	    incr counter
+	    if {$counter > 9} {
+		set done {EOF is sticky}
+		close $s
+	    }
+	}
+    }
+    set c [socket $remoteServerIP $port]
+    fileevent $c readable [list count_up $c]
+    vwait done
+    return $done
+} -cleanup {
+    after cancel $after_id
+    sendCommand {close $server}
+} -result {EOF is sticky}
+test socket_$af-11.13 {testing async write, async flush, async close} -setup {
+    set port [sendCommand {
+	set firstblock ""
+	for {set i 0} {$i < 5} {incr i} {
+		set firstblock "a$firstblock$firstblock"
+	}
+	set secondblock ""
+	for {set i 0} {$i < 16} {incr i} {
+	    set secondblock "b$secondblock$secondblock"
+	}
+	set l [socket -server accept 0]
+	proc accept {s a p} {
+	    fconfigure $s -blocking 0 -translation lf -buffersize 16384 \
+		-buffering line
+	    fileevent $s readable "readable $s"
+	}
+	proc readable {s} {
+	    set l [gets $s]
+	    fileevent $s readable {}
+	    after idle respond $s
+	}
+	proc respond {s} {
+	    global firstblock
+	    puts -nonewline $s $firstblock
+	    after idle writedata $s
+	}
+	proc writedata {s} {
+	    global secondblock
+	    puts -nonewline $s $secondblock
+	    close $s
+	}
+	getPort $l
+    }]
+    set timer [after 10000 "set done timed_out"]
+} -constraints [list socket supported_$af doTestsWithRemoteServer] -body {
+    proc readit {s} {
+	global count done
+	set l [read $s]
+	incr count [string length $l]
+	if {[eof $s]} {
+	    close $s
+	    set done 1
+	}
+    }
+    set s [socket $remoteServerIP $port]
+    fconfigure $s -blocking 0 -trans lf -buffering line
+    set count 0
+    puts $s hello
+    fileevent $s readable "readit $s"
+    vwait done
+    return $count
+} -cleanup {
+    after cancel $timer
+    sendCommand {close $l}
+} -result 65566
+
+set path(script1) [makeFile {} script1]
+set path(script2) [makeFile {} script2]
+
+test socket_$af-12.1 {testing inheritance of server sockets} -setup {
+    file delete $path(script1)
+    file delete $path(script2)
+    # Script1 is just a 10 second delay. If the server socket is inherited, it
+    # will be held open for 10 seconds
+    set f [open $path(script1) w]
+    puts $f {
+	fileevent stdin readable exit
+	after 10000 exit
+	vwait forever
+    }
+    close $f
+    # Script2 creates the server socket, launches script1, and exits.
+    # The server socket will now be closed unless script1 inherited it.
+    set f [open $path(script2) w]
+    puts $f [list set tcltest [interpreter]]
+    puts $f [list set delay $path(script1)]
+    puts $f [list set localhost $localhost]
+    puts $f {
+	set f [socket -server accept -myaddr $localhost 0]
+	proc accept { file addr port } {
+	    close $file
+	}
+	exec $tcltest $delay &
+	puts [lindex [fconfigure $f -sockname] 2]
+	close $f
+        exit
+    }
+    close $f
+} -constraints [list socket supported_$af stdio exec] -body {
+    # Launch script2 and wait 5 seconds
+    ### exec [interpreter] script2 &
+    set p [open "|[list [interpreter] $path(script2)]" r]
+    # If we can still connect to the server, the socket got inherited.
+    if {[catch {close [socket $localhost $listen]}]} {
+	return {server socket was not inherited}
+    } else {
+	return {server socket was inherited}
+    }
+} -cleanup {
+    catch {close $p}
+} -result {server socket was not inherited}
+test socket_$af-12.2 {testing inheritance of client sockets} -setup {
+    file delete $path(script1)
+    file delete $path(script2)
+    # Script1 is just a 20 second delay. If the server socket is inherited, it
+    # will be held open for 20 seconds
+    set f [open $path(script1) w]
+    puts $f {
+	fileevent stdin readable exit
+	after 20000 exit
+	vwait forever
+    }
+    close $f
+    # Script2 opens the client socket and writes to it. It then launches
+    # script1 and exits. If the child process inherited the client socket, the
+    # socket will still be open.
+    set f [open $path(script2) w]
+    puts $f [list set tcltest [interpreter]]
+    puts $f [list set delay $path(script1)]
+    puts $f [list set localhost $localhost]
+    puts $f {
+        gets stdin port
+	set f [socket $localhost $port]
+        exec $tcltest $delay &
+	puts $f testing
+	flush $f
+        exit
+    }
+    close $f
+    # If the socket doesn't hit end-of-file in 10 seconds, the script1 process
+    # must have inherited the client.
+    set timeout 0
+    set after [after 10000 {set x "client socket was inherited"}]
+} -constraints [list socket supported_$af stdio exec] -body {
+    # Create the server socket
+    set server [socket -server accept -myaddr $localhost 0]
+    proc accept { file host port } {
+	# When the client connects, establish the read handler
+	global server
+	close $server
+	fileevent $file readable [list getdata $file]
+	fconfigure $file -buffering line -blocking 0
+        set ::f $file
+    }
+    proc getdata { file } {
+	# Read handler on the accepted socket.
+	global x
+	set status [catch {read $file} data]
+	if {$status != 0} {
+	    set x "read failed, error was $data"
+	} elseif {$data ne ""} {
+	} elseif {[fblocked $file]} {
+	} elseif {[eof $file]} {
+            set x "client socket was not inherited"
+	} else {
+	    set x "impossible case"
+	}
+    }
+    # Launch the script2 process
+    ### exec [interpreter] script2 &
+    set p [open "|[list [interpreter] $path(script2)]" w]
+    puts $p [lindex [fconfigure $server -sockname] 2] ; flush $p
+    vwait x
+    return $x
+} -cleanup {
+    fconfigure $f -blocking 1
+    close $f
+    after cancel $after
+    close $p
+} -result {client socket was not inherited}
+test socket_$af-12.3 {testing inheritance of accepted sockets} -setup {
+    file delete $path(script1)
+    file delete $path(script2)
+    set f [open $path(script1) w]
+    puts $f {
+	fileevent stdin readable exit
+	after 10000 exit
+	vwait forever
+    }
+    close $f
+    set f [open $path(script2) w]
+    puts $f [list set tcltest [interpreter]]
+    puts $f [list set delay $path(script1)]
+    puts $f [list set localhost $localhost]
+    puts $f {
+	set server [socket -server accept -myaddr $localhost 0]
+	proc accept { file host port } {
+	    global tcltest delay
+	    puts $file {test data on socket}
+	    exec $tcltest $delay &
+            after idle exit
+	}
+	puts stdout [lindex [fconfigure $server -sockname] 2]
+	vwait forever
+    }
+    close $f
+} -constraints [list socket supported_$af stdio exec] -body {
+    # Launch the script2 process and connect to it. See how long the socket
+    # stays open
+    ## exec [interpreter] script2 &
+    set p [open "|[list [interpreter] $path(script2)]" r]
+    gets $p listen
+    set f [socket $localhost $listen]
+    fconfigure $f -buffering full -blocking 0
+    fileevent $f readable [list getdata $f]
+    # If the socket is still open after 5 seconds, the script1 process must
+    # have inherited the accepted socket.
+    set failed 0
+    set after [after 5000 [list set x "accepted socket was inherited"]]
+    proc getdata { file } {
+	# Read handler on the client socket.
+	global x
+	global failed
+	set status [catch {read $file} data]
+	if {$status != 0} {
+	    set x "read failed, error was $data"
+	} elseif {[string compare {} $data]} {
+	} elseif {[fblocked $file]} {
+	} elseif {[eof $file]} {
+            set x "accepted socket was not inherited"
+	} else {
+	    set x "impossible case"
+	}
+	return
+    }
+    vwait x
+    set x
+} -cleanup {
+    fconfigure $f -blocking 1
+    close $f
+    after cancel $after
+    close $p
+} -result {accepted socket was not inherited}
+
+test socket_$af-13.1 {Testing use of shared socket between two threads} -body {
+    # create a thread
+    set serverthread [thread::create -preserved [string map [list @localhost@ $localhost] {
+        set f [socket -server accept -myaddr @localhost@ 0]
+        set listen [lindex [fconfigure $f -sockname] 2]
+        proc accept {s a p} {
+            fileevent $s readable [list echo $s]
+            fconfigure $s -buffering line
+        }
+        proc echo {s} {
+             global i
+             set l [gets $s]
+             if {[eof $s]} {
+                 global x
+                 close $s
+                 set x done
+             } else {
+                 incr i
+                 puts $s $l
+             }
+        }
+        set i 0
+        vwait x
+        close $f
+    }]]
+    set port [thread::send $serverthread {set listen}]
+    set s [socket $localhost $port]
+    fconfigure $s -buffering line
+    catch {
+        puts $s "hello"
+        gets $s result
+    }
+    close $s
+    thread::release $serverthread
+    append result " " [llength [thread::names]]
+} -result {hello 1} -constraints [list socket supported_$af thread]
+
+# ----------------------------------------------------------------------
+
+removeFile script1
+removeFile script2
+
+# cleanup
+if {$remoteProcChan ne ""} {
+    catch {sendCommand exit}
+}
+catch {close $commandSocket}
+catch {close $remoteProcChan}
+}
+unset ::tcl::unsupported::socketAF
+test socket-14.0.0 {[socket -async] when server only listens on IPv4} \
+    -constraints {socket supported_inet localhost_v4} \
+    -setup {
+        proc accept {s a p} {
+            global x
+            puts $s bye
+            close $s
+            set x ok
+        }
+        set server [socket -server accept -myaddr 127.0.0.1 0]
+        set port [lindex [fconfigure $server -sockname] 2]
+    } -body {
+        set client [socket -async localhost $port]
+        set after [after $latency {set x [fconfigure $client -error]}]
+        vwait x
+        set x
+    } -cleanup {
+        after cancel $after
+        close $server
+        close $client
+        unset x
+    } -result ok
+test socket-14.0.1 {[socket -async] when server only listens on IPv6} \
+    -constraints {socket supported_inet6 localhost_v6} \
+    -setup {
+        proc accept {s a p} {
+            global x
+            puts $s bye
+            close $s
+            set x ok
+        }
+        set server [socket -server accept -myaddr ::1 0]
+        set port [lindex [fconfigure $server -sockname] 2]
+    } -body {
+        set client [socket -async localhost $port]
+        set after [after $latency {set x [fconfigure $client -error]}]
+        vwait x
+        set x
+    } -cleanup {
+        after cancel $after
+        close $server
+        close $client
+        unset x
+    } -result ok
+test socket-14.1 {[socket -async] fileevent while still connecting} \
+    -constraints {socket} \
+    -setup {
+        proc accept {s a p} {
+            global x
+            puts $s bye
+            close $s
+	    lappend x ok
+        }
+        set server [socket -server accept -myaddr localhost 0]
+        set port [lindex [fconfigure $server -sockname] 2]
+        set x ""
+    } -body {
+        set client [socket -async localhost $port]
+        fileevent $client writable {
+            lappend x [fconfigure $client -error]
+	    fileevent $client writable {}
+        }
+        set after [after $latency {lappend x timeout}]
+        while {[llength $x] < 2 && "timeout" ni $x} {
+            vwait x
+        }
+        lsort $x; # we only want to see both events, the order doesn't matter
+    } -cleanup {
+        after cancel $after
+        close $server
+        close $client
+        unset x
+    } -result {{} ok}
+test socket-14.2 {[socket -async] fileevent connection refused} \
+    -constraints {socket} \
+    -body {
+        set client [socket -async localhost [randport]]
+        fileevent $client writable {set x ok}
+        set after [after $latency {set x timeout}]
+        vwait x
+        after cancel $after
+        lappend x [fconfigure $client -error]
+    } -cleanup {
+        after cancel $after
+        close $client
+        unset x after client
+    } -result {ok {connection refused}}
+test socket-14.3 {[socket -async] when server only listens on IPv6} \
+    -constraints {socket supported_inet6 localhost_v6} \
+    -setup {
+        proc accept {s a p} {
+            global x
+            puts $s bye
+            close $s
+            set x ok
+        }
+        set server [socket -server accept -myaddr ::1 0]
+        set port [lindex [fconfigure $server -sockname] 2]
+    } -body {
+        set client [socket -async localhost $port]
+        set after [after $latency {set x [fconfigure $client -error]}]
+        vwait x
+        set x
+    } -cleanup {
+        after cancel $after
+        close $server
+        close $client
+        unset x
+    } -result ok
+test socket-14.4 {[socket -async] and both, readdable and writable fileevents} \
+    -constraints {socket} \
+    -setup {
+        proc accept {s a p} {
+            puts $s bye
+            close $s
+        }
+        set server [socket -server accept -myaddr localhost 0]
+        set port [lindex [fconfigure $server -sockname] 2]
+        set x ""
+    } -body {
+        set client [socket -async localhost $port]
+        fileevent $client writable {
+            lappend x [fconfigure $client -error]
+            fileevent $client writable {}
+        }
+        fileevent $client readable {lappend x [gets $client]}
+        set after [after $latency {lappend x timeout}]
+        while {[llength $x] < 2 && "timeout" ni $x} {
+            vwait x
+        }
+        lsort $x
+    } -cleanup {
+        after cancel $after
+        close $client
+        close $server
+        unset x
+    } -result {{} bye}
+# FIXME: we should also have an IPv6 counterpart of this
+test socket-14.5 {[socket -async] which fails before any connect() can be made} \
+    -constraints {socket supported_inet} \
+    -body {
+        # address from rfc5737
+        socket -async -myaddr 192.0.2.42 127.0.0.1 [randport]
+    } \
+    -returnCodes 1 \
+    -result {couldn't open socket: cannot assign requested address}
+test socket-14.6.0 {[socket -async] with no event loop and server listening on IPv4} \
+    -constraints {socket supported_inet localhost_v4} \
+    -setup {
+        proc accept {s a p} {
+            global x
+            puts $s bye
+            close $s
+            set x ok
+        }
+        set server [socket -server accept -myaddr 127.0.0.1 0]
+        set port [lindex [fconfigure $server -sockname] 2]
+        set x ""
+    } \
+    -body {
+        set client [socket -async localhost $port]
+        for {set i 0} {$i < 50} {incr i } {
+            update
+            if {$x ne ""} {
+                lappend x [gets $client]
+                break
+            }
+            after 100
+        }
+        set x
+    } \
+    -cleanup {
+        close $server
+        close $client
+        unset x
+    } \
+    -result {ok bye}
+test socket-14.6.1 {[socket -async] with no event loop and server listening on IPv6} \
+    -constraints {socket supported_inet6 localhost_v6} \
+    -setup {
+        proc accept {s a p} {
+            global x
+            puts $s bye
+            close $s
+            set x ok
+        }
+        set server [socket -server accept -myaddr ::1 0]
+        set port [lindex [fconfigure $server -sockname] 2]
+        set x ""
+    } \
+    -body {
+        set client [socket -async localhost $port]
+        for {set i 0} {$i < 50} {incr i } {
+            update
+            if {$x ne ""} {
+                lappend x [gets $client]
+                break
+            }
+            after 100
+        }
+        set x
+    } \
+    -cleanup {
+        close $server
+        close $client
+        unset x
+    } \
+    -result {ok bye}
+test socket-14.7.0 {pending [socket -async] and blocking [gets], server is IPv4} \
+    -constraints {socket supported_inet localhost_v4} \
+    -setup {
+        makeFile {
+            fileevent stdin readable exit
+            set server [socket -server accept -myaddr 127.0.0.1 0]
+            proc accept {s h p} {puts $s ok; close $s; set ::x 1}
+            puts [lindex [fconfigure $server -sockname] 2]
+            flush stdout
+            vwait x
+        } script
+        set fd [open |[list [interpreter] script] RDWR]
+        set port [gets $fd]
+    } -body {
+        set sock [socket -async localhost $port]
+        list [fconfigure $sock -error] [gets $sock] [fconfigure $sock -error]
+    } -cleanup {
+        close $fd
+        close $sock
+	removeFile script
+    } -result {{} ok {}}
+test socket-14.7.1 {pending [socket -async] and blocking [gets], server is IPv6} \
+    -constraints {socket supported_inet6 localhost_v6} \
+    -setup {
+        makeFile {
+            fileevent stdin readable exit
+            set server [socket -server accept -myaddr ::1 0]
+            proc accept {s h p} {puts $s ok; close $s; set ::x 1}
+            puts [lindex [fconfigure $server -sockname] 2]
+            flush stdout
+            vwait x
+        } script
+        set fd [open |[list [interpreter] script] RDWR]
+        set port [gets $fd]
+    } -body {
+        set sock [socket -async localhost $port]
+        list [fconfigure $sock -error] [gets $sock] [fconfigure $sock -error]
+    } -cleanup {
+        close $fd
+        close $sock
+	removeFile script
+    } -result {{} ok {}}
+test socket-14.7.2 {pending [socket -async] and blocking [gets], no listener} \
+    -constraints {socket} \
+    -body {
+        set sock [socket -async localhost [randport]]
+        catch {gets $sock} x
+        list $x [fconfigure $sock -error] [fconfigure $sock -error]
+    } -cleanup {
+        close $sock
+    } -match glob -result {{error reading "sock*": socket is not connected} {connection refused} {}}
+test socket-14.8.0 {pending [socket -async] and nonblocking [gets], server is IPv4} \
+    -constraints {socket supported_inet localhost_v4} \
+    -setup {
+        makeFile {
+            fileevent stdin readable exit
+            set server [socket -server accept -myaddr 127.0.0.1 0]
+            proc accept {s h p} {puts $s ok; close $s; set ::x 1}
+            puts [lindex [fconfigure $server -sockname] 2]
+            flush stdout
+            vwait x
+        } script
+        set fd [open |[list [interpreter] script] RDWR]
+        set port [gets $fd]
+    } -body {
+        set sock [socket -async localhost $port]
+        fconfigure $sock -blocking 0
+        for {set i 0} {$i < 50} {incr i } {
+            if {[catch {gets $sock} x] || $x ne "" || ![fblocked $sock]} break
+            after 200
+        }
+        set x
+    } -cleanup {
+        close $fd
+        close $sock
+	removeFile script
+    } -result {ok}
+test socket-14.8.1 {pending [socket -async] and nonblocking [gets], server is IPv6} \
+    -constraints {socket supported_inet6 localhost_v6} \
+    -setup {
+        makeFile {
+            fileevent stdin readable exit
+            set server [socket -server accept -myaddr ::1 0]
+            proc accept {s h p} {puts $s ok; close $s; set ::x 1}
+            puts [lindex [fconfigure $server -sockname] 2]
+            flush stdout
+            vwait x
+        } script
+        set fd [open |[list [interpreter] script] RDWR]
+        set port [gets $fd]
+    } -body {
+        set sock [socket -async localhost $port]
+        fconfigure $sock -blocking 0
+        for {set i 0} {$i < 50} {incr i } {
+            if {[catch {gets $sock} x] || $x ne "" || ![fblocked $sock]} break
+            after 200
+        }
+        set x
+    } -cleanup {
+        close $fd
+        close $sock
+	removeFile script
+    } -result {ok}
+test socket-14.8.2 {pending [socket -async] and nonblocking [gets], no listener} \
+    -constraints {socket} \
+    -body {
+        set sock [socket -async localhost [randport]]
+        fconfigure $sock -blocking 0
+        for {set i 0} {$i < 50} {incr i } {
+            if {[catch {gets $sock} x] || $x ne "" || ![fblocked $sock]} break
+            after 200
+        }
+        list $x [fconfigure $sock -error] [fconfigure $sock -error]
+    } -cleanup {
+        close $sock
+    } -match glob -result {{error reading "sock*": socket is not connected} {connection refused} {}}
+test socket-14.9.0 {pending [socket -async] and blocking [puts], server is IPv4} \
+    -constraints {socket supported_inet localhost_v4} \
+    -setup {
+        makeFile {
+            fileevent stdin readable exit
+            set server [socket -server accept -myaddr 127.0.0.1 0]
+            proc accept {s h p} {set ::x $s}
+            puts [lindex [fconfigure $server -sockname] 2]
+            flush stdout
+            vwait x
+            puts [gets $x]
+        } script
+        set fd [open |[list [interpreter] script] RDWR]
+        set port [gets $fd]
+    } -body {
+        set sock [socket -async localhost $port]
+        puts $sock ok
+        flush $sock
+        list [fconfigure $sock -error] [gets $fd]
+    } -cleanup {
+        close $fd
+        close $sock
+	removeFile script
+    } -result {{} ok}
+test socket-14.9.1 {pending [socket -async] and blocking [puts], server is IPv6} \
+    -constraints {socket supported_inet6 localhost_v6} \
+    -setup {
+        makeFile {
+            fileevent stdin readable exit
+            set server [socket -server accept -myaddr ::1 0]
+            proc accept {s h p} {set ::x $s}
+            puts [lindex [fconfigure $server -sockname] 2]
+            flush stdout
+            vwait x
+            puts [gets $x]
+        } script
+        set fd [open |[list [interpreter] script] RDWR]
+        set port [gets $fd]
+    } -body {
+        set sock [socket -async localhost $port]
+        puts $sock ok
+        flush $sock
+        list [fconfigure $sock -error] [gets $fd]
+    } -cleanup {
+        close $fd
+        close $sock
+	removeFile script
+    } -result {{} ok}
+test socket-14.10.0 {pending [socket -async] and nonblocking [puts], server is IPv4} \
+    -constraints {socket supported_inet localhost_v4} \
+    -setup {
+        makeFile {
+            fileevent stdin readable exit
+            set server [socket -server accept -myaddr 127.0.0.1 0]
+            proc accept {s h p} {set ::x $s}
+            puts [lindex [fconfigure $server -sockname] 2]
+            flush stdout
+            vwait x
+            puts [gets $x]
+        } script
+        set fd [open |[list [interpreter] script] RDWR]
+        set port [gets $fd]
+    } -body {
+        set sock [socket -async localhost $port]
+        fconfigure $sock -blocking 0
+        puts $sock ok
+        flush $sock
+        fileevent $fd readable {set x 1}
+        vwait x
+        list [fconfigure $sock -error] [gets $fd]
+    } -cleanup {
+        close $fd
+        close $sock
+	removeFile script
+    } -result {{} ok}
+test socket-14.10.1 {pending [socket -async] and nonblocking [puts], server is IPv6} \
+    -constraints {socket supported_inet6 localhost_v6} \
+    -setup {
+        makeFile {
+            fileevent stdin readable exit
+            set server [socket -server accept -myaddr ::1 0]
+            proc accept {s h p} {set ::x $s}
+            puts [lindex [fconfigure $server -sockname] 2]
+            flush stdout
+            vwait x
+            puts [gets $x]
+        } script
+        set fd [open |[list [interpreter] script] RDWR]
+        set port [gets $fd]
+    } -body {
+        set sock [socket -async localhost $port]
+        fconfigure $sock -blocking 0
+        puts $sock ok
+        flush $sock
+        fileevent $fd readable {set x 1}
+        vwait x
+        list [fconfigure $sock -error] [gets $fd]
+    } -cleanup {
+        close $fd
+        close $sock
+	removeFile script
+    } -result {{} ok}
+test socket-14.11.0 {pending [socket -async] and nonblocking [puts], no listener, no flush} \
+    -constraints {socket} \
+    -body {
+        set sock [socket -async localhost [randport]]
+        fconfigure $sock -blocking 0
+        puts $sock ok
+        fileevent $sock writable {set x 1}
+        vwait x
+        close $sock
+    } -cleanup {
+        catch {close $sock}
+        unset x
+    } -result {socket is not connected} -returnCodes 1
+test socket-14.11.1 {pending [socket -async] and nonblocking [puts], no listener, flush} \
+    -constraints {socket nonPortable} \
+    -body {
+        set sock [socket -async localhost [randport]]
+        fconfigure $sock -blocking 0
+        puts $sock ok
+        flush $sock
+        fileevent $sock writable {set x 1}
+        vwait x
+        close $sock
+    } -cleanup {
+        catch {close $sock}
+        catch {unset x}
+    } -result {socket is not connected} -returnCodes 1
+test socket-14.12 {[socket -async] background progress triggered by [fconfigure -error]} \
+    -constraints {socket} \
+    -body {
+        set s [socket -async localhost [randport]]
+        for {set i 0} {$i < 50} {incr i} {
+            set x [fconfigure $s -error]
+            if {$x != ""} break
+            after 200
+        }
+        set x
+    } -cleanup {
+        close $s
+        unset x s
+    } -result {connection refused}
+
+test socket-14.13 {testing writable event when quick failure} \
+    -constraints {socket win supported_inet} \
+    -body {
+    # Test for bug 336441ed59 where a quick background fail was ignored
+
+    # Test only for windows as socket -async 255.255.255.255 fails
+    # directly on unix
+
+    # The following connect should fail very quickly
+    set a1 [after 2000 {set x timeout}]
+    set s [socket -async 255.255.255.255 43434]
+    fileevent $s writable {set x writable}
+    vwait x
+    set x
+} -cleanup {
+    catch {close $s}
+    after cancel $a1
+} -result writable
+
+test socket-14.14 {testing fileevent readable on failed async socket connect} \
+    -constraints {socket} -body {
+    # Test for bug 581937ab1e
+
+    set a1 [after 5000 {set x timeout}]
+    # This connect should fail
+    set s [socket -async localhost [randport]]
+    fileevent $s readable {set x readable}
+    vwait x
+    set x
+} -cleanup {
+    catch {close $s}
+    after cancel $a1
+} -result readable
+
+test socket-14.15 {blocking read on async socket should not trigger event handlers} \
+    -constraints socket -body {
+        set s [socket -async localhost [randport]]
+        set x ok
+        fileevent $s writable {set x fail}
+        catch {read $s}
+	close $s
+        set x
+    } -result ok
+
+# v4 and v6 is required to prevent that the async connect does not terminate
+# before the fconfigure command. There is always an additional ip to try.
+test socket-14.16 {empty -peername while [socket -async] connecting} \
+    -constraints {socket localhost_v4 localhost_v6} \
+    -body {
+        set client [socket -async localhost [randport]]
+        fconfigure $client -peername
+    } -cleanup {
+        catch {close $client}
+    } -result {}
+
+# v4 and v6 is required to prevent that the async connect does not terminate
+# before the fconfigure command. There is always an additional ip to try.
+test socket-14.17 {empty -sockname while [socket -async] connecting} \
+    -constraints {socket localhost_v4 localhost_v6} \
+    -body {
+        set client [socket -async localhost [randport]]
+        fconfigure $client -sockname
+    } -cleanup {
+        catch {close $client}
+    } -result {}
+
+# test for bug c6ed4acfd8: running async socket connect with other connect
+# established will block tcl as it goes in an infinite loop in vwait
+test socket-14.18 {bug c6ed4acfd8: running async socket connect made other connect block} \
+    -constraints {socket} \
+    -body {
+        proc accept {channel address port} {}
+        set port [randport]
+        set ssock [socket -server accept $port]
+        set csock1 [socket -async localhost [randport]]
+        set csock2 [socket localhost $port]
+        after 1000 {set done ok}
+        vwait done
+} -cleanup {
+        catch {close $ssock}
+        catch {close $csock1}
+        catch {close $csock2}
+    } -result {}
+
+set num 0
+
+set x {localhost {socket} 127.0.0.1 {supported_inet} ::1 {supported_inet6}}
+set resultok {-result "sock*" -match glob}
+set resulterr {
+    -result {couldn't open socket: connection refused}
+    -returnCodes 1
+}
+foreach {servip sc} $x {
+    foreach {cliip cc} $x {
+        set constraints socket
+        lappend constraints $sc $cc
+        set result $resulterr
+        switch -- [lsort -unique [list $servip $cliip]] {
+            localhost - 127.0.0.1 - ::1 {
+                set result $resultok
+            }
+            {127.0.0.1 localhost} {
+                if {[testConstraint localhost_v4]} {
+                    set result $resultok
+                }
+            }
+            {::1 localhost} {
+                if {[testConstraint localhost_v6]} {
+                    set result $resultok
+                }
+            }
+        }
+        test socket-15.1.$num "Connect to $servip from $cliip" \
+            -constraints $constraints -setup {
+                set server [socket -server accept -myaddr $servip 0]
+                proc accept {s h p} { close $s }
+                set port [lindex [fconfigure $server -sockname] 2]
+            } -body {
+                set s [socket $cliip $port]
+            } -cleanup {
+                close $server
+                catch {close $s}
+            } {*}$result
+        incr num
+    }
+}
+
+::tcltest::cleanupTests
+flush stdout
+return
+
+# Local Variables:
+# mode: tcl
+# fill-column: 78
+# End:
diff --git a/tests/source.test b/tests/source.test
new file mode 100644
index 0000000..0235bd1
--- /dev/null
+++ b/tests/source.test
@@ -0,0 +1,312 @@
+# Commands covered:  source
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands.  Sourcing this file into Tcl runs the tests and
+# generates output for errors.  No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994-1996 Sun Microsystems, Inc.
+# Copyright (c) 1998-2000 by Scriptics Corporation.
+# Contributions from Don Porter, NIST, 2003.  (not subject to US copyright)
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[catch {package require tcltest 2.1}]} {
+    puts stderr "Skipping tests in [info script]. tcltest 2.1 required."
+    return
+}
+
+namespace eval ::tcl::test::source {
+    namespace import ::tcltest::*
+
+test source-1.1 {source command} -setup {
+    set x "old x value"
+    set y "old y value"
+    set z "old z value"
+    set sourcefile [makeFile {
+	set x 22
+	set y 33
+	set z 44
+    } source.file]
+} -body {
+    source $sourcefile
+    list $x $y $z
+} -cleanup {
+    removeFile source.file
+} -result {22 33 44}
+test source-1.2 {source command} -setup {
+    set sourcefile [makeFile {list result} source.file]
+} -body {
+    source $sourcefile
+} -cleanup {
+    removeFile source.file
+} -result result
+test source-1.3 {source command} -setup {
+    set sourcefile [makeFile {} source.file]
+    set fd [open $sourcefile w]
+    fconfigure $fd -translation lf
+    puts $fd "list a b c \\"
+    puts $fd "d e f"
+    close $fd
+} -body {
+    source $sourcefile
+} -cleanup {
+    removeFile source.file
+} -result {a b c d e f}
+
+proc ListGlobMatch {expected actual} {
+    if {[llength $expected] != [llength $actual]} {
+        return 0
+    }
+    foreach e $expected a $actual {
+        if {![string match $e $a]} {
+            return 0
+        }
+    }
+    return 1
+}
+customMatch listGlob [namespace which ListGlobMatch]
+
+test source-2.3 {source error conditions} -setup {
+    set sourcefile [makeFile {
+	set x 146
+	error "error in sourced file"
+	set y $x
+    } source.file]
+} -body {
+    list [catch {source $sourcefile} msg] $msg $::errorInfo
+} -cleanup {
+    removeFile source.file
+} -match listGlob -result [list 1 {error in sourced file} \
+	{error in sourced file
+    while executing
+"error "error in sourced file""
+    (file "*source.file" line 3)
+    invoked from within
+"source $sourcefile"}]
+test source-2.4 {source error conditions} -setup {
+    set sourcefile [makeFile {break} source.file]
+} -body {
+    source $sourcefile
+} -cleanup {
+    removeFile source.file
+} -returnCodes break
+test source-2.5 {source error conditions} -setup {
+    set sourcefile [makeFile {continue} source.file]
+} -body {
+    source $sourcefile
+} -cleanup {
+    removeFile source.file
+} -returnCodes continue
+test source-2.6 {source error conditions} -setup {
+    set sourcefile [makeFile {} _non_existent_]
+    removeFile _non_existent_
+} -body {
+    list [catch {source $sourcefile} msg] $msg $::errorCode
+} -match listGlob -result [list 1 \
+	{couldn't read file "*_non_existent_": no such file or directory} \
+	{POSIX ENOENT {no such file or directory}}]
+test source-2.7 {utf-8 with BOM} -setup {
+    set sourcefile [makeFile {} source.file]
+} -body {
+    set out [open $sourcefile w]
+    fconfigure $out -encoding utf-8
+    puts $out "\ufeffset y new-y"
+    close $out
+    set y old-y
+    source -encoding utf-8 $sourcefile
+    return $y
+} -cleanup {
+    removeFile $sourcefile
+} -result {new-y}
+
+test source-3.1 {return in middle of source file} -setup {
+    set sourcefile [makeFile {
+	set x new-x
+	return allDone
+	set y new-y
+    } source.file]
+} -body {
+    set x old-x
+    set y old-y
+    set z [source $sourcefile]
+    list $x $y $z
+} -cleanup {
+    removeFile source.file
+} -result {new-x old-y allDone}
+test source-3.2 {return with special code etc.} -setup {
+    set sourcefile [makeFile {
+	set x new-x
+	return -code break "Silly result"
+	set y new-y
+    } source.file]
+} -body {
+   source $sourcefile
+} -cleanup {
+    removeFile source.file
+} -returnCodes break -result {Silly result}
+test source-3.3 {return with special code etc.} -setup {
+    set sourcefile [makeFile {
+	set x new-x
+	return -code error "Simulated error"
+	set y new-y
+    } source.file]
+} -body {
+    list [catch {source $sourcefile} msg] $msg $::errorInfo $::errorCode
+} -cleanup {
+    removeFile source.file
+} -result {1 {Simulated error} {Simulated error
+    while executing
+"source $sourcefile"} NONE}
+test source-3.4 {return with special code etc.} -setup {
+    set sourcefile [makeFile {
+	set x new-x
+	return -code error -errorinfo "Simulated errorInfo stuff"
+	set y new-y
+    } source.file]
+} -body {
+    list [catch {source $sourcefile} msg] $msg $::errorInfo $::errorCode
+} -cleanup {
+    removeFile source.file
+} -result {1 {} {Simulated errorInfo stuff
+    invoked from within
+"source $sourcefile"} NONE}
+test source-3.5 {return with special code etc.} -setup {
+    set sourcefile [makeFile {
+	set x new-x
+	return -code error -errorinfo "Simulated errorInfo stuff" \
+		-errorcode {a b c}
+	set y new-y
+    } source.file]
+} -body {
+    list [catch {source $sourcefile} msg] $msg $::errorInfo $::errorCode
+} -cleanup {
+    removeFile source.file
+} -result {1 {} {Simulated errorInfo stuff
+    invoked from within
+"source $sourcefile"} {a b c}}
+
+test source-4.1 {continuation line parsing} -setup {
+    set sourcefile [makeFile [string map {CL \\\n} {
+	format %s "[dict get [info frame 0] type]:CL[dict get [info frame 0] line]CL[dict get [info frame 0] line]CL[dict get [info frame 0] line]"
+    }] source.file]
+} -body {
+    source $sourcefile
+} -cleanup {
+    removeFile source.file
+} -result {source: 3 4 5}
+
+test source-6.1 {source is binary ok} -setup {
+    # Note [makeFile] writes in the system encoding.
+    # [source] defaults to reading in the system encoding.
+    set sourcefile [makeFile [list set x "a b\0c"] source.file]
+} -body {
+    set x {}
+    source $sourcefile
+    string length $x
+} -cleanup {
+    removeFile source.file
+} -result 5
+test source-6.2 {source skips everything after Ctrl-Z: Bug 2040} -setup {
+    set sourcefile [makeFile "set x ab\32c" source.file]
+} -body {
+    set x {}
+    source $sourcefile
+    string length $x
+} -cleanup {
+    removeFile source.file
+} -result 2
+
+test source-7.1 {source -encoding test} -setup {
+    set sourcefile [makeFile {} source.file]
+    file delete $sourcefile
+    set f [open $sourcefile w]
+    fconfigure $f -encoding utf-8
+    puts $f "set symbol(square-root) \u221A; set x correct"
+    close $f
+} -body {
+    set x unset
+    source -encoding utf-8 $sourcefile
+    set x
+} -cleanup {
+    removeFile source.file
+} -result correct
+test source-7.2 {source -encoding test} -setup {
+    # This tests for bad interactions between [source -encoding]
+    # and use of the Control-Z character (\u001A) as a cross-platform
+    # EOF character by [source].  Here we write out and the [source] a
+    # file that contains the byte \x1A, although not the character \u001A in
+    # the indicated encoding.
+    set sourcefile [makeFile {} source.file]
+    file delete $sourcefile
+    set f [open $sourcefile w]
+    fconfigure $f -encoding unicode
+    puts $f "set symbol(square-root) \u221A; set x correct"
+    close $f
+} -body {
+    set x unset
+    source -encoding unicode $sourcefile
+    set x
+} -cleanup {
+    removeFile source.file
+} -result correct
+test source-7.3 {source -encoding: syntax} -body {
+    # Have to spell out the -encoding option
+    source -e utf-8 no_file
+} -returnCodes 1 -match glob -result {bad option*}
+test source-7.4 {source -encoding: syntax} -setup {
+    set sourcefile [makeFile {} source.file]
+} -body {
+    source -encoding no-such-encoding $sourcefile
+} -cleanup {
+    removeFile source.file
+} -returnCodes 1 -match glob -result {unknown encoding*}
+test source-7.5 {source -encoding: correct operation} -setup {
+    set sourcefile [makeFile {} source.file]
+    file delete $sourcefile
+    set f [open $sourcefile w]
+    fconfigure $f -encoding utf-8
+    puts $f "proc \u20ac {} {return foo}"
+    close $f
+} -body {
+    source -encoding utf-8 $sourcefile
+    \u20ac
+} -cleanup {
+    removeFile source.file
+    rename \u20ac {}
+} -result foo
+test source-7.6 {source -encoding: mismatch encoding error} -setup {
+    set sourcefile [makeFile {} source.file]
+    file delete $sourcefile
+    set f [open $sourcefile w]
+    fconfigure $f -encoding utf-8
+    puts $f "proc \u20ac {} {return foo}"
+    close $f
+} -body {
+    source -encoding ascii $sourcefile
+    \u20ac
+} -cleanup {
+    removeFile source.file
+} -returnCodes error -match glob -result {invalid command name*}
+
+test source-8.1 {source and coroutine/yield} -setup {
+    set sourcefile [makeFile {} source.file]
+    file delete $sourcefile
+} -body {
+    makeFile {yield 1; yield 2; return 3;} $sourcefile
+    coroutine coro apply {f {yield;source $f}} $sourcefile
+    list [coro] [coro] [coro] [info exist coro]
+} -cleanup {
+    catch {rename coro {}}
+    removeFile source.file
+} -result {1 2 3 0}
+
+cleanupTests
+}
+namespace delete ::tcl::test::source
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/tests/split.test b/tests/split.test
new file mode 100644
index 0000000..778131f
--- /dev/null
+++ b/tests/split.test
@@ -0,0 +1,88 @@
+# Commands covered:  split
+#
+# This file contains a collection of tests for one or more of the Tcl built-in
+# commands. Sourcing this file into Tcl runs the tests and generates output
+# for errors. No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994-1996 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution of
+# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+    package require tcltest
+    namespace import -force ::tcltest::*
+}
+
+test split-1.1 {basic split commands} {
+    split "a\n b\t\r c\n "
+} {a {} b {} {} c {} {}}
+test split-1.2 {basic split commands} {
+    split "word 1xyzword 2zword 3" xyz
+} {{word 1} {} {} {word 2} {word 3}}
+test split-1.3 {basic split commands} {
+    split "12345" {}
+} {1 2 3 4 5}
+test split-1.4 {basic split commands} {
+    split "a\}b\[c\{\]\$"
+} "a\\}b\\\[c\\{\\\]\\\$"
+test split-1.5 {basic split commands} {
+    split {} {}
+} {}
+test split-1.6 {basic split commands} {
+    split {}
+} {}
+test split-1.7 {basic split commands} {
+    split {   }
+} {{} {} {} {}}
+test split-1.8 {basic split commands} {
+    proc foo {} {
+        set x {}
+        foreach f [split {]\n} {}] {
+            append x $f
+        }
+        return $x	
+    }
+    foo
+} {]\n}
+test split-1.9 {basic split commands} {
+    proc foo {} {
+        set x ab\000c
+        set y [split $x {}]
+        return $y
+    }
+    foo
+} "a b \000 c"
+test split-1.10 {basic split commands} {
+    split "a0ab1b2bbb3\000c4" ab\000c
+} {{} 0 {} 1 2 {} {} 3 {} 4}
+test split-1.11 {basic split commands} {
+    split "12,3,45" {,}
+} {12 3 45}
+test split-1.12 {basic split commands} {
+    split "\u0001ab\u0001cd\u0001\u0001ef\u0001" \1
+} {{} ab cd {} ef {}}
+test split-1.13 {basic split commands} {
+    split "12,34,56," {,}
+} {12 34 56 {}}
+test split-1.14 {basic split commands} {
+    split ",12,,,34,56," {,}
+} {{} 12 {} {} 34 56 {}}
+
+test split-2.1 {split errors} {
+    list [catch split msg] $msg $errorCode
+} {1 {wrong # args: should be "split string ?splitChars?"} {TCL WRONGARGS}}
+test split-2.2 {split errors} {
+    list [catch {split a b c} msg] $msg $errorCode
+} {1 {wrong # args: should be "split string ?splitChars?"} {TCL WRONGARGS}}
+
+# cleanup
+catch {rename foo {}}
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/tests/stack.test b/tests/stack.test
new file mode 100644
index 0000000..13bc524
--- /dev/null
+++ b/tests/stack.test
@@ -0,0 +1,62 @@
+# Tests that the stack size is big enough for the application.
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands.  Sourcing this file into Tcl runs the tests and
+# generates output for errors.  No output means no errors were found.
+#
+# Copyright (c) 1998-2000 Ajuba Solutions.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+package require tcltest 2
+namespace import ::tcltest::*
+
+# Note that a failure in this test may result in a crash of the executable.
+
+test stack-1.1 {maxNestingDepth reached on infinite recursion} -body {
+    # do this in a sub process in case it segfaults
+    exec [interpreter] << {
+	proc recurse {} { recurse }
+	catch { recurse } rv
+	puts $rv
+    }
+} -result {too many nested evaluations (infinite loop?)}
+
+test stack-2.1 {maxNestingDepth reached on infinite recursion} -body {
+    # do this in a sub process in case it segfaults
+    exec [interpreter] << {
+	interp alias {} unknown {} notaknownproc
+	catch { unknown } msg
+	puts $msg
+    }
+} -result {too many nested evaluations (infinite loop?)}
+    
+# Make sure that there is enough stack to run regexp even if we're
+# close to the recursion limit. [Bug 947070] [Patch 746378]
+test stack-3.1 {enough room for regexp near recursion limit} -body {
+    # do this in a sub process in case it segfaults
+    exec [interpreter] << {
+	interp recursionlimit {} 10000
+	set depth 0
+	proc a { max } {
+	    if { [info level] < $max } {
+		set ::depth [info level]
+		a $max
+	    } else {
+		regexp {^ ?} x
+	    }
+	}
+	catch { a 10001 }
+	set depth2 $depth
+	puts [list [a $depth] [expr { $depth2 - $depth }]]
+    }
+} -result {1 1}
+
+# cleanup
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/tests/string.test b/tests/string.test
new file mode 100644
index 0000000..3611753
--- /dev/null
+++ b/tests/string.test
@@ -0,0 +1,2004 @@
+# Commands covered:  string
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands.  Sourcing this file into Tcl runs the tests and
+# generates output for errors.  No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+# Copyright (c) 2001 by Kevin B. Kenny.  All rights reserved.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+    package require tcltest
+    namespace import -force ::tcltest::*
+}
+
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
+
+# Some tests require the testobj command
+
+testConstraint testobj [expr {[info commands testobj] != {}}]
+testConstraint testindexobj [expr {[info commands testindexobj] != {}}]
+
+# Used for constraining memory leak tests
+testConstraint memory [llength [info commands memory]]
+
+test string-1.1 {error conditions} {
+    list [catch {string gorp a b} msg] $msg
+} {1 {unknown or ambiguous subcommand "gorp": must be bytelength, cat, compare, equal, first, index, is, last, length, map, match, range, repeat, replace, reverse, tolower, totitle, toupper, trim, trimleft, trimright, wordend, or wordstart}}
+test string-1.2 {error conditions} {
+    list [catch {string} msg] $msg
+} {1 {wrong # args: should be "string subcommand ?arg ...?"}}
+
+test string-2.1 {string compare, too few args} {
+    list [catch {string compare a} msg] $msg
+} {1 {wrong # args: should be "string compare ?-nocase? ?-length int? string1 string2"}}
+test string-2.2 {string compare, bad args} {
+    list [catch {string compare a b c} msg] $msg
+} {1 {bad option "a": must be -nocase or -length}}
+test string-2.3 {string compare, bad args} {
+    list [catch {string compare -length -nocase str1 str2} msg] $msg
+} {1 {expected integer but got "-nocase"}}
+test string-2.4 {string compare, too many args} {
+    list [catch {string compare -length 10 -nocase str1 str2 str3} msg] $msg
+} {1 {wrong # args: should be "string compare ?-nocase? ?-length int? string1 string2"}}
+test string-2.5 {string compare with length unspecified} {
+    list [catch {string compare -length 10 10} msg] $msg
+} {1 {wrong # args: should be "string compare ?-nocase? ?-length int? string1 string2"}}
+test string-2.6 {string compare} {
+    string compare abcde abdef
+} -1
+test string-2.7 {string compare, shortest method name} {
+    string co abcde ABCDE
+} 1
+test string-2.8 {string compare} {
+    string compare abcde abcde
+} 0
+test string-2.9 {string compare with length} {
+    string compare -length 2 abcde abxyz
+} 0
+test string-2.10 {string compare with special index} {
+    list [catch {string compare -length end-3 abcde abxyz} msg] $msg
+} {1 {expected integer but got "end-3"}}
+test string-2.11 {string compare, unicode} {
+    string compare ab\u7266 ab\u7267
+} -1
+test string-2.12 {string compare, high bit} {
+    # This test will fail if the underlying comparaison
+    # is using signed chars instead of unsigned chars.
+    # (like SunOS's default memcmp thus the compat/memcmp.c)
+    string compare "\x80" "@"
+    # Nb this tests works also in utf8 space because \x80 is
+    # translated into a 2 or more bytelength but whose first byte has
+    # the high bit set.
+} 1
+test string-2.13 {string compare -nocase} {
+    string compare -nocase abcde abdef
+} -1
+test string-2.14 {string compare -nocase} {
+    string compare -nocase abcde ABCDE
+} 0
+test string-2.15 {string compare -nocase} {
+    string compare -nocase abcde abcde
+} 0
+test string-2.16 {string compare -nocase with length} {
+    string compare -length 2 -nocase abcde Abxyz
+} 0
+test string-2.17 {string compare -nocase with length} {
+    string compare -nocase -length 3 abcde Abxyz
+} -1
+test string-2.18 {string compare -nocase with length <= 0} {
+    string compare -nocase -length -1 abcde AbCdEf
+} -1
+test string-2.19 {string compare -nocase with excessive length} {
+    string compare -nocase -length 50 AbCdEf abcde
+} 1
+test string-2.20 {string compare -len unicode} {
+    # These are strings that are 6 BYTELENGTH long, but the length
+    # shouldn't make a different because there are actually 3 CHARS long
+    string compare -len 5 \334\334\334 \334\334\374
+} -1
+test string-2.21 {string compare -nocase with special index} {
+    list [catch {string compare -nocase -length end-3 Abcde abxyz} msg] $msg
+} {1 {expected integer but got "end-3"}}
+test string-2.22 {string compare, null strings} {
+    string compare "" ""
+} 0
+test string-2.23 {string compare, null strings} {
+    string compare "" foo
+} -1
+test string-2.24 {string compare, null strings} {
+    string compare foo ""
+} 1
+test string-2.25 {string compare -nocase, null strings} {
+    string compare -nocase "" ""
+} 0
+test string-2.26 {string compare -nocase, null strings} {
+    string compare -nocase "" foo
+} -1
+test string-2.27 {string compare -nocase, null strings} {
+    string compare -nocase foo ""
+} 1
+test string-2.28 {string compare with length, unequal strings} {
+    string compare -length 2 abc abde
+} 0
+test string-2.29 {string compare with length, unequal strings} {
+    string compare -length 2 ab abde
+} 0
+test string-2.30 {string compare with NUL character vs. other ASCII} {
+    # Be careful here, since UTF-8 rep comparison with memcmp() of
+    # these puts chars in the wrong order
+    string compare \x00 \x01
+} -1
+test string-2.31 {string compare, high bit} {
+    proc foo {} {string compare "a\x80" "a@"}
+    foo
+} 1
+test string-2.32 {string compare, high bit} {
+    proc foo {} {string compare "a\x00" "a\x01"}
+    foo
+} -1
+test string-2.33 {string compare, high bit} {
+    proc foo {} {string compare "\x00\x00" "\x00\x01"}
+    foo
+} -1
+
+# only need a few tests on equal, since it uses the same code as
+# string compare, but just modifies the return output
+test string-3.1 {string equal} {
+    string equal abcde abdef
+} 0
+test string-3.2 {string equal} {
+    string eq abcde ABCDE
+} 0
+test string-3.3 {string equal} {
+    string equal abcde abcde
+} 1
+test string-3.4 {string equal -nocase} {
+    string equal -nocase \334\334\334\334\374\374\374\374 \334\334\334\334\334\334\334\334
+} 1
+test string-3.5 {string equal -nocase} {
+    string equal -nocase abcde abdef
+} 0
+test string-3.6 {string equal -nocase} {
+    string eq -nocase abcde ABCDE
+} 1
+test string-3.7 {string equal -nocase} {
+    string equal -nocase abcde abcde
+} 1
+test string-3.8 {string equal with length, unequal strings} {
+    string equal -length 2 abc abde
+} 1
+
+test string-4.1 {string first, too few args} {
+    list [catch {string first a} msg] $msg
+} {1 {wrong # args: should be "string first needleString haystackString ?startIndex?"}}
+test string-4.2 {string first, bad args} {
+    list [catch {string first a b c} msg] $msg
+} {1 {bad index "c": must be integer?[+-]integer? or end?[+-]integer?}}
+test string-4.3 {string first, too many args} {
+    list [catch {string first a b 5 d} msg] $msg
+} {1 {wrong # args: should be "string first needleString haystackString ?startIndex?"}}
+test string-4.4 {string first} {
+    string first bq abcdefgbcefgbqrs
+} 12
+test string-4.5 {string first} {
+    string fir bcd abcdefgbcefgbqrs
+} 1
+test string-4.6 {string first} {
+    string f b abcdefgbcefgbqrs
+} 1
+test string-4.7 {string first} {
+    string first xxx x123xx345xxx789xxx012
+} 9
+test string-4.8 {string first} {
+    string first "" x123xx345xxx789xxx012
+} -1
+test string-4.9 {string first, unicode} {
+    string first x abc\u7266x
+} 4
+test string-4.10 {string first, unicode} {
+    string first \u7266 abc\u7266x
+} 3
+test string-4.11 {string first, start index} {
+    string first \u7266 abc\u7266x 3
+} 3
+test string-4.12 {string first, start index} {
+    string first \u7266 abc\u7266x 4
+} -1
+test string-4.13 {string first, start index} {
+    string first \u7266 abc\u7266x end-2
+} 3
+test string-4.14 {string first, negative start index} {
+    string first b abc -1
+} 1
+test string-4.15 {string first, ability to two-byte encoded utf-8 chars} {
+    # Test for a bug in Tcl 8.3 where test for all-single-byte-encoded
+    # strings was incorrect, leading to an index returned by [string first] 
+    # which pointed past the end of the string.
+    set uchar \u057e    ;# character with two-byte encoding in utf-8
+    string first % %#$uchar$uchar#$uchar$uchar#% 3
+} 8
+
+test string-5.1 {string index} {
+    list [catch {string index} msg] $msg
+} {1 {wrong # args: should be "string index string charIndex"}}
+test string-5.2 {string index} {
+    list [catch {string index a b c} msg] $msg
+} {1 {wrong # args: should be "string index string charIndex"}}
+test string-5.3 {string index} {
+    string index abcde 0
+} a
+test string-5.4 {string index} {
+    string in abcde 4
+} e
+test string-5.5 {string index} {
+    string index abcde 5
+} {}
+test string-5.6 {string index} {
+    list [catch {string index abcde -10} msg] $msg
+} {0 {}}
+test string-5.7 {string index} {
+    list [catch {string index a xyz} msg] $msg
+} {1 {bad index "xyz": must be integer?[+-]integer? or end?[+-]integer?}}
+test string-5.8 {string index} {
+    string index abc end
+} c
+test string-5.9 {string index} {
+    string index abc end-1
+} b
+test string-5.10 {string index, unicode} {
+    string index abc\u7266d 4
+} d
+test string-5.11 {string index, unicode} {
+    string index abc\u7266d 3
+} \u7266
+test string-5.12 {string index, unicode over char length, under byte length} {
+    string index \334\374\334\374 6
+} {}
+test string-5.13 {string index, bytearray object} {
+    string index [binary format a5 fuz] 0
+} f
+test string-5.14 {string index, bytearray object} {
+    string index [binary format I* {0x50515253 0x52}] 3
+} S
+test string-5.15 {string index, bytearray object} {
+    set b [binary format I* {0x50515253 0x52}]
+    set i1 [string index $b end-6]
+    set i2 [string index $b 1]
+    string compare $i1 $i2
+} 0
+test string-5.16 {string index, bytearray object with string obj shimmering} {
+    set str "0123456789\x00 abcdedfghi"
+    binary scan $str H* dump
+    string compare [string index $str 10] \x00
+} 0
+test string-5.17 {string index, bad integer} -body {
+    list [catch {string index "abc" 0o8} msg] $msg
+} -match glob -result {1 {*invalid octal number*}}
+test string-5.18 {string index, bad integer} -body {
+    list [catch {string index "abc" end-0o0289} msg] $msg
+} -match glob -result {1 {*invalid octal number*}}
+test string-5.19 {string index, bytearray object out of bounds} {
+    string index [binary format I* {0x50515253 0x52}] -1
+} {}
+test string-5.20 {string index, bytearray object out of bounds} {
+    string index [binary format I* {0x50515253 0x52}] 20
+} {}
+
+
+proc largest_int {} {
+    # This will give us what the largest valid int on this machine is,
+    # so we can test for overflow properly below on >32 bit systems
+    set int 1
+    set exp 7; # assume we get at least 8 bits
+    while {wide($int) > 0} { set int [expr {wide(1) << [incr exp]}] }
+    return [expr {$int-1}]
+}
+
+test string-6.1 {string is, too few args} {
+    list [catch {string is} msg] $msg
+} {1 {wrong # args: should be "string is class ?-strict? ?-failindex var? str"}}
+test string-6.2 {string is, too few args} {
+    list [catch {string is alpha} msg] $msg
+} {1 {wrong # args: should be "string is class ?-strict? ?-failindex var? str"}}
+test string-6.3 {string is, bad args} {
+    list [catch {string is alpha -failin str} msg] $msg
+} {1 {wrong # args: should be "string is alpha ?-strict? ?-failindex var? str"}}
+test string-6.4 {string is, too many args} {
+    list [catch {string is alpha -failin var -strict str more} msg] $msg
+} {1 {wrong # args: should be "string is class ?-strict? ?-failindex var? str"}}
+test string-6.5 {string is, class check} {
+    list [catch {string is bogus str} msg] $msg
+} {1 {bad class "bogus": must be alnum, alpha, ascii, control, boolean, digit, double, entier, false, graph, integer, list, lower, print, punct, space, true, upper, wideinteger, wordchar, or xdigit}}
+test string-6.6 {string is, ambiguous class} {
+    list [catch {string is al str} msg] $msg
+} {1 {ambiguous class "al": must be alnum, alpha, ascii, control, boolean, digit, double, entier, false, graph, integer, list, lower, print, punct, space, true, upper, wideinteger, wordchar, or xdigit}}
+test string-6.7 {string is alpha, all ok} {
+    string is alpha -strict -failindex var abc
+} 1
+test string-6.8 {string is, error in var} {
+    list [string is alpha -failindex var abc5def] $var
+} {0 3}
+test string-6.9 {string is, var shouldn't get set} {
+    catch {unset var}
+    list [catch {string is alpha -failindex var abc; set var} msg] $msg
+} {1 {can't read "var": no such variable}}
+test string-6.10 {string is, ok on empty} {
+    string is alpha {}
+} 1
+test string-6.11 {string is, -strict check against empty} {
+    string is alpha -strict {}
+} 0
+test string-6.12 {string is alnum, true} {
+    string is alnum abc123
+} 1
+test string-6.13 {string is alnum, false} {
+    list [string is alnum -failindex var abc1.23] $var
+} {0 4}
+test string-6.14 {string is alnum, unicode} "string is alnum abc\xfc" 1
+test string-6.15 {string is alpha, true} {
+    string is alpha abc
+} 1
+test string-6.16 {string is alpha, false} {
+    list [string is alpha -fail var a1bcde] $var
+} {0 1}
+test string-6.17 {string is alpha, unicode} {
+    string is alpha abc\374
+} 1
+test string-6.18 {string is ascii, true} {
+    string is ascii abc\u007Fend\u0000
+} 1
+test string-6.19 {string is ascii, false} {
+    list [string is ascii -fail var abc\u0000def\u0080more] $var
+} {0 7}
+test string-6.20 {string is boolean, true} {
+    string is boolean true
+} 1
+test string-6.21 {string is boolean, true} {
+    string is boolean f
+} 1
+test string-6.22 {string is boolean, true based on type} {
+    string is bool [string compare a a]
+} 1
+test string-6.23 {string is boolean, false} {
+    list [string is bool -fail var yada] $var
+} {0 0}
+test string-6.24 {string is digit, true} {
+    string is digit 0123456789
+} 1
+test string-6.25 {string is digit, false} {
+    list [string is digit -fail var 0123\u00dc567] $var
+} {0 4}
+test string-6.26 {string is digit, false} {
+    list [string is digit -fail var +123567] $var
+} {0 0}
+test string-6.27 {string is double, true} {
+    string is double 1
+} 1
+test string-6.28 {string is double, true} {
+    string is double [expr double(1)]
+} 1
+test string-6.29 {string is double, true} {
+    string is double 1.0
+} 1
+test string-6.30 {string is double, true} {
+    string is double [string compare a a]
+} 1
+test string-6.31 {string is double, true} {
+    string is double "   +1.0e-1  "
+} 1
+test string-6.32 {string is double, true} {
+    string is double "\n1.0\v"
+} 1
+test string-6.33 {string is double, false} {
+    list [string is double -fail var 1abc] $var
+} {0 1}
+test string-6.34 {string is double, false} {
+    list [string is double -fail var abc] $var
+} {0 0}
+test string-6.35 {string is double, false} {
+    list [string is double -fail var "   1.0e4e4  "] $var
+} {0 8}
+test string-6.36 {string is double, false} {
+    list [string is double -fail var "\n"] $var
+} {0 0}
+test string-6.37 {string is double, false on int overflow} -setup {
+    set var priorValue
+} -body {
+    # Make it the largest int recognizable, with one more digit for overflow
+    # Since bignums arrived in Tcl 8.5, the sense of this test changed.
+    # Now integer values that exceed native limits become bignums, and
+    # bignums can convert to doubles without error.
+    list [string is double -fail var [largest_int]0] $var
+} -result {1 priorValue}
+# string-6.38 removed, underflow on input is no longer an error.
+test string-6.39 {string is double, false} {
+    # This test is non-portable because IRIX thinks 
+    # that .e1 is a valid double - this is really a bug
+    # on IRIX as .e1 should NOT be a valid double
+    #
+    # Portable now. Tcl 8.5 does its own double parsing.
+
+    list [string is double -fail var .e1] $var
+} {0 0}
+test string-6.40 {string is false, true} {
+    string is false false
+} 1
+test string-6.41 {string is false, true} {
+    string is false FaLsE
+} 1
+test string-6.42 {string is false, true} {
+    string is false N
+} 1
+test string-6.43 {string is false, true} {
+    string is false 0
+} 1
+test string-6.44 {string is false, true} {
+    string is false off
+} 1
+test string-6.45 {string is false, false} {
+    list [string is false -fail var abc] $var
+} {0 0}
+test string-6.46 {string is false, false} {
+    catch {unset var}
+    list [string is false -fail var Y] $var
+} {0 0}
+test string-6.47 {string is false, false} {
+    catch {unset var}
+    list [string is false -fail var offensive] $var
+} {0 0}
+test string-6.48 {string is integer, true} {
+    string is integer +1234567890
+} 1
+test string-6.49 {string is integer, true on type} {
+    string is integer [expr int(50.0)]
+} 1
+test string-6.50 {string is integer, true} {
+    string is integer [list -10]
+} 1
+test string-6.51 {string is integer, true as hex} {
+    string is integer 0xabcdef
+} 1
+test string-6.52 {string is integer, true as octal} {
+    string is integer 012345
+} 1
+test string-6.53 {string is integer, true with whitespace} {
+    string is integer "  \n1234\v"
+} 1
+test string-6.54 {string is integer, false} {
+    list [string is integer -fail var 123abc] $var
+} {0 3}
+test string-6.55 {string is integer, false on overflow} {
+    list [string is integer -fail var +[largest_int]0] $var
+} {0 -1}
+test string-6.56 {string is integer, false} {
+    list [string is integer -fail var [expr double(1)]] $var
+} {0 1}
+test string-6.57 {string is integer, false} {
+    list [string is integer -fail var "    "] $var
+} {0 0}
+test string-6.58 {string is integer, false on bad octal} {
+    list [string is integer -fail var 0o36963] $var
+} {0 4}
+test string-6.58.1 {string is integer, false on bad octal} {
+    list [string is integer -fail var 0o36963] $var
+} {0 4}
+test string-6.59 {string is integer, false on bad hex} {
+    list [string is integer -fail var 0X345XYZ] $var
+} {0 5}
+test string-6.60 {string is lower, true} {
+    string is lower abc
+} 1
+test string-6.61 {string is lower, unicode true} {
+    string is lower abc\u00fcue
+} 1
+test string-6.62 {string is lower, false} {
+    list [string is lower -fail var aBc] $var
+} {0 1}
+test string-6.63 {string is lower, false} {
+    list [string is lower -fail var abc1] $var
+} {0 3}
+test string-6.64 {string is lower, unicode false} {
+    list [string is lower -fail var ab\u00dcUE] $var
+} {0 2}
+test string-6.65 {string is space, true} {
+    string is space " \t\n\v\f"
+} 1
+test string-6.66 {string is space, false} {
+    list [string is space -fail var " \t\n\v1\f"] $var
+} {0 4}
+test string-6.67 {string is true, true} {
+    string is true true
+} 1
+test string-6.68 {string is true, true} {
+    string is true TrU
+} 1
+test string-6.69 {string is true, true} {
+    string is true ye
+} 1
+test string-6.70 {string is true, true} {
+    string is true 1
+} 1
+test string-6.71 {string is true, true} {
+    string is true on
+} 1
+test string-6.72 {string is true, false} {
+    list [string is true -fail var onto] $var
+} {0 0}
+test string-6.73 {string is true, false} {
+    catch {unset var}
+    list [string is true -fail var 25] $var
+} {0 0}
+test string-6.74 {string is true, false} {
+    catch {unset var}
+    list [string is true -fail var no] $var
+} {0 0}
+test string-6.75 {string is upper, true} {
+    string is upper ABC
+} 1
+test string-6.76 {string is upper, unicode true} {
+    string is upper ABC\u00dcUE
+} 1
+test string-6.77 {string is upper, false} {
+    list [string is upper -fail var AbC] $var
+} {0 1}
+test string-6.78 {string is upper, false} {
+    list [string is upper -fail var AB2C] $var
+} {0 2}
+test string-6.79 {string is upper, unicode false} {
+    list [string is upper -fail var ABC\u00fcue] $var
+} {0 3}
+test string-6.80 {string is wordchar, true} {
+    string is wordchar abc_123
+} 1
+test string-6.81 {string is wordchar, unicode true} {
+    string is wordchar abc\u00fcab\u00dcAB\u5001
+} 1
+test string-6.82 {string is wordchar, false} {
+    list [string is wordchar -fail var abcd.ef] $var
+} {0 4}
+test string-6.83 {string is wordchar, unicode false} {
+    list [string is wordchar -fail var abc\u0080def] $var
+} {0 3}
+test string-6.84 {string is control} {
+    ## Control chars are in the ranges
+    ## 00..1F && 7F..9F
+    list [string is control -fail var \x00\x01\x10\x1F\x7F\x80\x9F\x60] $var
+} {0 7}
+test string-6.85 {string is control} {
+    string is control \u0100
+} 0
+test string-6.86 {string is graph} {
+    ## graph is any print char, except space
+    list [string is gra -fail var "0123abc!@#\$\u0100 "] $var
+} {0 12}
+test string-6.87 {string is print} {
+    ## basically any printable char
+    list [string is print -fail var "0123abc!@#\$\u0100 \u0010"] $var
+} {0 13}
+test string-6.88 {string is punct} {
+    ## any graph char that isn't alnum
+    list [string is punct -fail var "_!@#\u00beq0"] $var
+} {0 4}
+test string-6.89 {string is xdigit} {
+    list [string is xdigit -fail var 0123456789\u0061bcdefABCDEFg] $var
+} {0 22}
+
+test string-6.90 {string is integer, bad integers} {
+    # SF bug #634856
+    set result ""
+    set numbers [list 1 +1 ++1 +-1 -+1 -1 --1 "- +1"]
+    foreach num $numbers {
+	lappend result [string is int -strict $num]
+    }
+    return $result
+} {1 1 0 0 0 1 0 0}
+test string-6.91 {string is double, bad doubles} {
+    set result ""
+    set numbers [list 1.0 +1.0 ++1.0 +-1.0 -+1.0 -1.0 --1.0 "- +1.0"]
+    foreach num $numbers {
+	lappend result [string is double -strict $num]
+    }
+    return $result
+} {1 1 0 0 0 1 0 0}
+test string-6.92 {string is integer, 32-bit overflow} {
+    # Bug 718878
+    set x 0x100000000
+    list [string is integer -failindex var $x] $var
+} {0 -1}
+test string-6.93 {string is integer, 32-bit overflow} {
+    # Bug 718878
+    set x 0x100000000
+    append x ""
+    list [string is integer -failindex var $x] $var
+} {0 -1}
+test string-6.94 {string is integer, 32-bit overflow} {
+    # Bug 718878
+    set x 0x100000000
+    list [string is integer -failindex var [expr {$x}]] $var
+} {0 -1}
+test string-6.95 {string is wideinteger, true} {
+    string is wideinteger +1234567890
+} 1
+test string-6.96 {string is wideinteger, true on type} {
+    string is wideinteger [expr wide(50.0)]
+} 1
+test string-6.97 {string is wideinteger, true} {
+    string is wideinteger [list -10]
+} 1
+test string-6.98 {string is wideinteger, true as hex} {
+    string is wideinteger 0xabcdef
+} 1
+test string-6.99 {string is wideinteger, true as octal} {
+    string is wideinteger 0123456
+} 1
+test string-6.100 {string is wideinteger, true with whitespace} {
+    string is wideinteger "  \n1234\v"
+} 1
+test string-6.101 {string is wideinteger, false} {
+    list [string is wideinteger -fail var 123abc] $var
+} {0 3}
+test string-6.102 {string is wideinteger, false on overflow} {
+    list [string is wideinteger -fail var +[largest_int]0] $var
+} {0 -1}
+test string-6.103 {string is wideinteger, false} {
+    list [string is wideinteger -fail var [expr double(1)]] $var
+} {0 1}
+test string-6.104 {string is wideinteger, false} {
+    list [string is wideinteger -fail var "    "] $var
+} {0 0}
+test string-6.105 {string is wideinteger, false on bad octal} {
+    list [string is wideinteger -fail var 0o36963] $var
+} {0 4}
+test string-6.105.1 {string is wideinteger, false on bad octal} {
+    list [string is wideinteger -fail var 0o36963] $var
+} {0 4}
+test string-6.106 {string is wideinteger, false on bad hex} {
+    list [string is wideinteger -fail var 0X345XYZ] $var
+} {0 5}
+test string-6.107 {string is integer, bad integers} {
+    # SF bug #634856
+    set result ""
+    set numbers [list 1 +1 ++1 +-1 -+1 -1 --1 "- +1"]
+    foreach num $numbers {
+	lappend result [string is wideinteger -strict $num]
+    }
+    return $result
+} {1 1 0 0 0 1 0 0}
+test string-6.108 {string is double, Bug 1382287} {
+    set x 2turtledoves
+    string is double $x
+    string is double $x
+} 0
+test string-6.109 {string is double, Bug 1360532} {
+    string is double 1\u00a0
+} 0
+test string-6.110 {string is entier, true} {
+    string is entier +1234567890
+} 1
+test string-6.111 {string is entier, true on type} {
+    string is entier [expr wide(50.0)]
+} 1
+test string-6.112 {string is entier, true} {
+    string is entier [list -10]
+} 1
+test string-6.113 {string is entier, true as hex} {
+    string is entier 0xabcdef
+} 1
+test string-6.114 {string is entier, true as octal} {
+    string is entier 0123456
+} 1
+test string-6.115 {string is entier, true with whitespace} {
+    string is entier "  \n1234\v"
+} 1
+test string-6.116 {string is entier, false} {
+    list [string is entier -fail var 123abc] $var
+} {0 3}
+test string-6.117 {string is entier, false} {
+    list [string is entier -fail var 123123123123123123123123123123123123123123123123123123123123123123123123123123123123abc] $var
+} {0 84}
+test string-6.118 {string is entier, false} {
+    list [string is entier -fail var [expr double(1)]] $var
+} {0 1}
+test string-6.119 {string is entier, false} {
+    list [string is entier -fail var "    "] $var
+} {0 0}
+test string-6.120 {string is entier, false on bad octal} {
+    list [string is entier -fail var 0o36963] $var
+} {0 4}
+test string-6.121.1 {string is entier, false on bad octal} {
+    list [string is entier -fail var 0o36963] $var
+} {0 4}
+test string-6.122 {string is entier, false on bad hex} {
+    list [string is entier -fail var 0X345XYZ] $var
+} {0 5}
+test string-6.123 {string is entier, bad integers} {
+    # SF bug #634856
+    set result ""
+    set numbers [list 1 +1 ++1 +-1 -+1 -1 --1 "- +1"]
+    foreach num $numbers {
+	lappend result [string is entier -strict $num]
+    }
+    return $result
+} {1 1 0 0 0 1 0 0}
+test string-6.124 {string is entier, true} {
+    string is entier +1234567890123456789012345678901234567890
+} 1
+test string-6.125 {string is entier, true} {
+    string is entier [list -10000000000000000000000000000000000000000000000000000000000000000000000000000000000000]
+} 1
+test string-6.126 {string is entier, true as hex} {
+    string is entier 0xabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef
+} 1
+test string-6.127 {string is entier, true as octal} {
+    string is entier 0123456112341234561234565623456123456123456123456123456123456123456123456123456123456
+} 1
+test string-6.128 {string is entier, true with whitespace} {
+    string is entier "  \n12340000000000000000000000000000000000000000000000000000000000000000000000000000000000000\v"
+} 1
+test string-6.129 {string is entier, false on bad octal} {
+    list [string is entier -fail var 0o1234561123412345612345656234561234561234561234561234561234561234561234561234561234536963] $var
+} {0 87}
+test string-6.130.1 {string is entier, false on bad octal} {
+    list [string is entier -fail var 0o1234561123412345612345656234561234561234561234561234561234561234561234561234561234536963] $var
+} {0 87}
+test string-6.131 {string is entier, false on bad hex} {
+    list [string is entier -fail var 0X12345611234123456123456562345612345612345612345612345612345612345612345612345612345345XYZ] $var
+} {0 88}
+
+catch {rename largest_int {}}
+
+test string-7.1 {string last, too few args} {
+    list [catch {string last a} msg] $msg
+} {1 {wrong # args: should be "string last needleString haystackString ?startIndex?"}}
+test string-7.2 {string last, bad args} {
+    list [catch {string last a b c} msg] $msg
+} {1 {bad index "c": must be integer?[+-]integer? or end?[+-]integer?}}
+test string-7.3 {string last, too many args} {
+    list [catch {string last a b c d} msg] $msg
+} {1 {wrong # args: should be "string last needleString haystackString ?startIndex?"}}
+test string-7.4 {string last} {
+    string la xxx xxxx123xx345x678
+} 1
+test string-7.5 {string last} {
+    string last xx xxxx123xx345x678
+} 7
+test string-7.6 {string last} {
+    string las x xxxx123xx345x678
+} 12
+test string-7.7 {string last, unicode} {
+    string las x xxxx12\u7266xx345x678
+} 12
+test string-7.8 {string last, unicode} {
+    string las \u7266 xxxx12\u7266xx345x678
+} 6
+test string-7.9 {string last, stop index} {
+    string las \u7266 xxxx12\u7266xx345x678
+} 6
+test string-7.10 {string last, unicode} {
+    string las \u7266 xxxx12\u7266xx345x678
+} 6
+test string-7.11 {string last, start index} {
+    string last \u7266 abc\u7266x 3
+} 3
+test string-7.12 {string last, start index} {
+    string last \u7266 abc\u7266x 2
+} -1
+test string-7.13 {string last, start index} {
+    ## Constrain to last 'a' should work
+    string last ba badbad end-1
+} 3
+test string-7.14 {string last, start index} {
+    ## Constrain to last 'b' should skip last 'ba'
+    string last ba badbad end-2
+} 0
+test string-7.15 {string last, start index} {
+    string last \334a \334ad\334ad 0
+} -1
+test string-7.16 {string last, start index} {
+    string last \334a \334ad\334ad end-1
+} 3
+
+test string-8.1 {string bytelength} {
+    list [catch {string bytelength} msg] $msg
+} {1 {wrong # args: should be "string bytelength string"}}
+test string-8.2 {string bytelength} {
+    list [catch {string bytelength a b} msg] $msg
+} {1 {wrong # args: should be "string bytelength string"}}
+test string-8.3 {string bytelength} {
+    string bytelength "\u00c7"
+} 2
+test string-8.4 {string bytelength} {
+    string b ""
+} 0
+
+test string-9.1 {string length} {
+    list [catch {string length} msg] $msg
+} {1 {wrong # args: should be "string length string"}}
+test string-9.2 {string length} {
+    list [catch {string length a b} msg] $msg
+} {1 {wrong # args: should be "string length string"}}
+test string-9.3 {string length} {
+    string length "a little string"
+} 15
+test string-9.4 {string length} {
+    string le ""
+} 0
+test string-9.5 {string length, unicode} {
+    string le "abcd\u7266"
+} 5
+test string-9.6 {string length, bytearray object} {
+    string length [binary format a5 foo]
+} 5
+test string-9.7 {string length, bytearray object} {
+    string length [binary format I* {0x50515253 0x52}]
+} 8
+
+test string-10.1 {string map, too few args} {
+    list [catch {string map} msg] $msg
+} {1 {wrong # args: should be "string map ?-nocase? charMap string"}}
+test string-10.2 {string map, bad args} {
+    list [catch {string map {a b} abba oops} msg] $msg
+} {1 {bad option "a b": must be -nocase}}
+test string-10.3 {string map, too many args} {
+    list [catch {string map -nocase {a b} str1 str2} msg] $msg
+} {1 {wrong # args: should be "string map ?-nocase? charMap string"}}
+test string-10.4 {string map} {
+    string map {a b} abba
+} {bbbb}
+test string-10.5 {string map} {
+    string map {a b} a
+} {b}
+test string-10.6 {string map -nocase} {
+    string map -nocase {a b} Abba
+} {bbbb}
+test string-10.7 {string map} {
+    string map {abc 321 ab * a A} aabcabaababcab
+} {A321*A*321*}
+test string-10.8 {string map -nocase} {
+    string map -nocase {aBc 321 Ab * a A} aabcabaababcab
+} {A321*A*321*}
+test string-10.9 {string map -nocase} {
+    string map -no {abc 321 Ab * a A} aAbCaBaAbAbcAb
+} {A321*A*321*}
+test string-10.10 {string map} {
+    list [catch {string map {a b c} abba} msg] $msg
+} {1 {char map list unbalanced}}
+test string-10.11 {string map, nulls} {
+    string map {\x00 NULL blah \x00nix} {qwerty}
+} {qwerty}
+test string-10.12 {string map, unicode} {
+    string map [list \374 ue UE \334] "a\374ueUE\000EU"
+} aueue\334\0EU
+test string-10.13 {string map, -nocase unicode} {
+    string map -nocase [list \374 ue UE \334] "a\374ueUE\000EU"
+} aue\334\334\0EU
+test string-10.14 {string map, -nocase null arguments} {
+    string map -nocase {{} abc} foo
+} foo
+test string-10.15 {string map, one pair case} {
+    string map -nocase {abc 32} aAbCaBaAbAbcAb
+} {a32aBaAb32Ab}
+test string-10.16 {string map, one pair case} {
+    string map -nocase {ab 4321} aAbCaBaAbAbcAb
+} {a4321C4321a43214321c4321}
+test string-10.17 {string map, one pair case} {
+    string map {Ab 4321} aAbCaBaAbAbcAb
+} {a4321CaBa43214321c4321}
+test string-10.18 {string map, empty argument} {
+    string map -nocase {{} abc} foo
+} foo
+test string-10.19 {string map, empty arguments} {
+    string map -nocase {{} abc f bar {} def} foo
+} baroo
+test string-10.20 {string map, dictionaries don't alter map ordering} {
+    set map {aa X a Y}
+    list [string map [dict create aa X a Y] aaa] [string map $map aaa] [dict size $map] [string map $map aaa]
+} {XY XY 2 XY}
+test string-10.21 {string map, ABR checks} {
+    string map {longstring foob} long
+} long
+test string-10.22 {string map, ABR checks} {
+    string map {long foob} long
+} foob
+test string-10.23 {string map, ABR checks} {
+    string map {lon foob} long
+} foobg
+test string-10.24 {string map, ABR checks} {
+    string map {lon foob} longlo
+} foobglo
+test string-10.25 {string map, ABR checks} {
+    string map {lon foob} longlon
+} foobgfoob
+test string-10.26 {string map, ABR checks} {
+    string map {longstring foob longstring bar} long
+} long
+test string-10.27 {string map, ABR checks} {
+    string map {long foob longstring bar} long
+} foob
+test string-10.28 {string map, ABR checks} {
+    string map {lon foob longstring bar} long
+} foobg
+test string-10.29 {string map, ABR checks} {
+    string map {lon foob longstring bar} longlo
+} foobglo
+test string-10.30 {string map, ABR checks} {
+    string map {lon foob longstring bar} longlon
+} foobgfoob
+test string-10.31 {string map, nasty sharing crash from [Bug 1018562]} {
+    set a {a b}
+    string map $a $a
+} {b b}
+
+test string-11.1 {string match, too few args} {
+    list [catch {string match a} msg] $msg
+} {1 {wrong # args: should be "string match ?-nocase? pattern string"}}
+test string-11.2 {string match, too many args} {
+    list [catch {string match a b c d} msg] $msg
+} {1 {wrong # args: should be "string match ?-nocase? pattern string"}}
+test string-11.3 {string match} {
+    string match abc abc
+} 1
+test string-11.4 {string match} {
+    string mat abc abd
+} 0
+test string-11.5 {string match} {
+    string match ab*c abc
+} 1
+test string-11.6 {string match} {
+    string match ab**c abc
+} 1
+test string-11.7 {string match} {
+    string match ab* abcdef
+} 1
+test string-11.8 {string match} {
+    string match *c abc
+} 1
+test string-11.9 {string match} {
+    string match *3*6*9 0123456789
+} 1
+test string-11.9.1 {string match} {
+    string match *3*6*89 0123456789
+} 1
+test string-11.9.2 {string match} {
+    string match *3*456*89 0123456789
+} 1
+test string-11.9.3 {string match} {
+    string match *3*6* 0123456789
+} 1
+test string-11.9.4 {string match} {
+    string match *3*56* 0123456789
+} 1
+test string-11.9.5 {string match} {
+    string match *3*456*** 0123456789
+} 1
+test string-11.9.6 {string match} {
+    string match **3*456** 0123456789
+} 1
+test string-11.9.7 {string match} {
+    string match *3***456* 0123456789
+} 1
+test string-11.9.8 {string match} {
+    string match *3***\[456]* 0123456789
+} 1
+test string-11.9.9 {string match} {
+    string match *3***\[4-6]* 0123456789
+} 1
+test string-11.9.10 {string match} {
+    string match *3***\[4-6] 0123456789
+} 0
+test string-11.9.11 {string match} {
+    string match *3***\[4-6] 0123456
+} 1
+test string-11.10 {string match} {
+    string match *3*6*9 01234567890
+} 0
+test string-11.10.1 {string match} {
+    string match *3*6*89 01234567890
+} 0
+test string-11.10.2 {string match} {
+    string match *3*456*89 01234567890
+} 0
+test string-11.10.3 {string match} {
+    string match **3*456*89 01234567890
+} 0
+test string-11.10.4 {string match} {
+    string match *3*456***89 01234567890
+} 0
+test string-11.11 {string match} {
+    string match a?c abc
+} 1
+test string-11.12 {string match} {
+    string match a??c abc
+} 0
+test string-11.13 {string match} {
+    string match ?1??4???8? 0123456789
+} 1
+test string-11.14 {string match} {
+    string match {[abc]bc} abc
+} 1
+test string-11.15 {string match} {
+    string match {a[abc]c} abc
+} 1
+test string-11.16 {string match} {
+    string match {a[xyz]c} abc
+} 0
+test string-11.17 {string match} {
+    string match {12[2-7]45} 12345
+} 1
+test string-11.18 {string match} {
+    string match {12[ab2-4cd]45} 12345
+} 1
+test string-11.19 {string match} {
+    string match {12[ab2-4cd]45} 12b45
+} 1
+test string-11.20 {string match} {
+    string match {12[ab2-4cd]45} 12d45
+} 1
+test string-11.21 {string match} {
+    string match {12[ab2-4cd]45} 12145
+} 0
+test string-11.22 {string match} {
+    string match {12[ab2-4cd]45} 12545
+} 0
+test string-11.23 {string match} {
+    string match {a\*b} a*b
+} 1
+test string-11.24 {string match} {
+    string match {a\*b} ab
+} 0
+test string-11.25 {string match} {
+    string match {a\*\?\[\]\\\x} "a*?\[\]\\x"
+} 1
+test string-11.26 {string match} {
+    string match ** ""
+} 1
+test string-11.27 {string match} {
+    string match *. ""
+} 0
+test string-11.28 {string match} {
+    string match "" ""
+} 1
+test string-11.29 {string match} {
+    string match \[a a
+} 1
+test string-11.30 {string match, bad args} {
+    list [catch {string match - b c} msg] $msg
+} {1 {bad option "-": must be -nocase}}
+test string-11.31 {string match case} {
+    string match a A
+} 0
+test string-11.32 {string match nocase} {
+    string match -n a A
+} 1
+test string-11.33 {string match nocase} {
+    string match -nocase a\334 A\374
+} 1
+test string-11.34 {string match nocase} {
+    string match -nocase a*f ABCDEf
+} 1
+test string-11.35 {string match case, false hope} {
+    # This is true because '_' lies between the A-Z and a-z ranges
+    string match {[A-z]} _
+} 1
+test string-11.36 {string match nocase range} {
+    # This is false because although '_' lies between the A-Z and a-z ranges,
+    # we lower case the end points before checking the ranges.
+    string match -nocase {[A-z]} _
+} 0
+test string-11.37 {string match nocase} {
+    string match -nocase {[A-fh-Z]} g
+} 0
+test string-11.38 {string match case, reverse range} {
+    string match {[A-fh-Z]} g
+} 1
+test string-11.39 {string match, *\ case} {
+    string match {*\abc} abc
+} 1
+test string-11.39.1 {string match, *\ case} {
+    string match {*ab\c} abc
+} 1
+test string-11.39.2 {string match, *\ case} {
+    string match {*ab\*} ab*
+} 1
+test string-11.39.3 {string match, *\ case} {
+    string match {*ab\*} abc
+} 0
+test string-11.39.4 {string match, *\ case} {
+    string match {*ab\\*} {ab\c}
+} 1
+test string-11.39.5 {string match, *\ case} {
+    string match {*ab\\*} {ab\*}
+} 1
+test string-11.40 {string match, *special case} {
+    string match {*[ab]} abc
+} 0
+test string-11.41 {string match, *special case} {
+    string match {*[ab]*} abc
+} 1
+test string-11.42 {string match, *special case} {
+    string match "*\\" "\\"
+} 0
+test string-11.43 {string match, *special case} {
+    string match "*\\\\" "\\"
+} 1
+test string-11.44 {string match, *special case} {
+    string match "*???" "12345"
+} 1
+test string-11.45 {string match, *special case} {
+    string match "*???" "12"
+} 0
+test string-11.46 {string match, *special case} {
+    string match "*\\*" "abc*"
+} 1
+test string-11.47 {string match, *special case} {
+    string match "*\\*" "*"
+} 1
+test string-11.48 {string match, *special case} {
+    string match "*\\*" "*abc"
+} 0
+test string-11.49 {string match, *special case} {
+    string match "?\\*" "a*"
+} 1
+test string-11.50 {string match, *special case} {
+    string match "\\" "\\"
+} 0
+test string-11.51 {string match; *, -nocase and UTF-8} {
+    string match -nocase [binary format I 717316707] \
+	    [binary format I 2028036707]
+} 1
+test string-11.52 {string match, null char in string} {
+    set out ""
+    set ptn "*abc*"
+    foreach elem [list "\u0000@abc" "@abc" "\u0000@abc\u0000" "blahabcblah"] {
+	lappend out [string match $ptn $elem]
+    }
+    set out
+} {1 1 1 1}
+test string-11.53 {string match, null char in pattern} {
+    set out ""
+    foreach {ptn elem} [list \
+	    "*\u0000abc\u0000"  "\u0000abc\u0000" \
+	    "*\u0000abc\u0000"  "\u0000abc\u0000ef" \
+	    "*\u0000abc\u0000*" "\u0000abc\u0000ef" \
+	    "*\u0000abc\u0000"  "@\u0000abc\u0000ef" \
+	    "*\u0000abc\u0000*"  "@\u0000abc\u0000ef" \
+	    ] {
+	lappend out [string match $ptn $elem]
+    }
+    set out
+} {1 0 1 0 1}
+test string-11.54 {string match, failure} {
+    set longString ""
+    for {set i 0} {$i < 10} {incr i} {
+	append longString "abcdefghijklmnopqrstuvwxy\u0000z01234567890123"
+    }
+    string first $longString 123
+    list [string match *cba* $longString] \
+	    [string match *a*l*\u0000* $longString] \
+	    [string match *a*l*\u0000*123 $longString] \
+	    [string match *a*l*\u0000*123* $longString] \
+	    [string match *a*l*\u0000*cba* $longString] \
+	    [string match *===* $longString]
+} {0 1 1 1 0 0}
+
+test string-12.1 {string range} {
+    list [catch {string range} msg] $msg
+} {1 {wrong # args: should be "string range string first last"}}
+test string-12.2 {string range} {
+    list [catch {string range a 1} msg] $msg
+} {1 {wrong # args: should be "string range string first last"}}
+test string-12.3 {string range} {
+    list [catch {string range a 1 2 3} msg] $msg
+} {1 {wrong # args: should be "string range string first last"}}
+test string-12.4 {string range} {
+    string range abcdefghijklmnop 2 14
+} {cdefghijklmno}
+test string-12.5 {string range, last > length} {
+    string range abcdefghijklmnop 7 1000
+} {hijklmnop}
+test string-12.6 {string range} {
+    string range abcdefghijklmnop 10 end
+} {klmnop}
+test string-12.7 {string range, last < first} {
+    string range abcdefghijklmnop 10 9
+} {}
+test string-12.8 {string range, first < 0} {
+    string range abcdefghijklmnop -3 2
+} {abc}
+test string-12.9 {string range} {
+    string range abcdefghijklmnop -3 -2
+} {}
+test string-12.10 {string range} {
+    string range abcdefghijklmnop 1000 1010
+} {}
+test string-12.11 {string range} {
+    string range abcdefghijklmnop -100 end
+} {abcdefghijklmnop}
+test string-12.12 {string range} {
+    list [catch {string range abc abc 1} msg] $msg
+} {1 {bad index "abc": must be integer?[+-]integer? or end?[+-]integer?}}
+test string-12.13 {string range} {
+    list [catch {string range abc 1 eof} msg] $msg
+} {1 {bad index "eof": must be integer?[+-]integer? or end?[+-]integer?}}
+test string-12.14 {string range} {
+    string range abcdefghijklmnop end-1 end
+} {op}
+test string-12.15 {string range} {
+    string range abcdefghijklmnop end 1000
+} {p}
+test string-12.16 {string range} {
+    string range abcdefghijklmnop end end-1
+} {}
+test string-12.17 {string range, unicode} {
+    string range ab\u7266cdefghijklmnop 5 5
+} e
+test string-12.18 {string range, unicode} {
+    string range ab\u7266cdefghijklmnop 2 3
+} \u7266c
+test string-12.19 {string range, bytearray object} {
+    set b [binary format I* {0x50515253 0x52}]
+    set r1 [string range $b 1 end-1]
+    set r2 [string range $b 1 6]
+    string equal $r1 $r2
+} 1
+test string-12.20 {string range, out of bounds indices} {
+    string range \u00ff 0 1
+} \u00ff
+# Bug 1410553
+test string-12.21 {string range, regenerates correct reps, bug 1410553} {
+    set bytes "\x00 \x03 \x41"
+    set rxBuffer {}
+    foreach ch $bytes {
+	append rxBuffer $ch
+	if {$ch eq "\x03"} {
+	    string length $rxBuffer
+	}
+    }
+    set rxCRC [string range $rxBuffer end-1 end]
+    binary scan [join $bytes {}] "H*" input_hex
+    binary scan $rxBuffer "H*" rxBuffer_hex
+    binary scan $rxCRC "H*" rxCRC_hex
+    list $input_hex $rxBuffer_hex $rxCRC_hex
+} {000341 000341 0341}
+test string-12.22 {string range, shimmering binary/index} {
+    set s 0000000001
+    binary scan $s a* x
+    string range $s $s end
+} 000000001
+
+test string-13.1 {string repeat} {
+    list [catch {string repeat} msg] $msg
+} {1 {wrong # args: should be "string repeat string count"}}
+test string-13.2 {string repeat} {
+    list [catch {string repeat abc 10 oops} msg] $msg
+} {1 {wrong # args: should be "string repeat string count"}}
+test string-13.3 {string repeat} {
+    string repeat {} 100
+} {}
+test string-13.4 {string repeat} {
+    string repeat { } 5
+} {     }
+test string-13.5 {string repeat} {
+    string repeat abc 3
+} {abcabcabc}
+test string-13.6 {string repeat} {
+    string repeat abc -1
+} {}
+test string-13.7 {string repeat} {
+    list [catch {string repeat abc end} msg] $msg
+} {1 {expected integer but got "end"}}
+test string-13.8 {string repeat} {
+    string repeat {} -1000
+} {}
+test string-13.9 {string repeat} {
+    string repeat {} 0
+} {}
+test string-13.10 {string repeat} {
+    string repeat def 0
+} {}
+test string-13.11 {string repeat} {
+    string repeat def 1
+} def
+test string-13.12 {string repeat} {
+    string repeat ab\u7266cd 3
+} ab\u7266cdab\u7266cdab\u7266cd
+test string-13.13 {string repeat} {
+    string repeat \x00 3
+} \x00\x00\x00
+test string-13.14 {string repeat} {
+    # The string range will ensure us that string repeat gets a unicode string
+    string repeat [string range ab\u7266cd 2 3] 3
+} \u7266c\u7266c\u7266c
+
+test string-14.1 {string replace} {
+    list [catch {string replace} msg] $msg
+} {1 {wrong # args: should be "string replace string first last ?string?"}}
+test string-14.2 {string replace} {
+    list [catch {string replace a 1} msg] $msg
+} {1 {wrong # args: should be "string replace string first last ?string?"}}
+test string-14.3 {string replace} {
+    list [catch {string replace a 1 2 3 4} msg] $msg
+} {1 {wrong # args: should be "string replace string first last ?string?"}}
+test string-14.4 {string replace} {
+} {}
+test string-14.5 {string replace} {
+    string replace abcdefghijklmnop 2 14
+} {abp}
+test string-14.6 {string replace} {
+    string replace abcdefghijklmnop 7 1000
+} {abcdefg}
+test string-14.7 {string replace} {
+    string replace abcdefghijklmnop 10 end
+} {abcdefghij}
+test string-14.8 {string replace} {
+    string replace abcdefghijklmnop 10 9
+} {abcdefghijklmnop}
+test string-14.9 {string replace} {
+    string replace abcdefghijklmnop -3 2
+} {defghijklmnop}
+test string-14.10 {string replace} {
+    string replace abcdefghijklmnop -3 -2
+} {abcdefghijklmnop}
+test string-14.11 {string replace} {
+    string replace abcdefghijklmnop 1000 1010
+} {abcdefghijklmnop}
+test string-14.12 {string replace} {
+    string replace abcdefghijklmnop -100 end
+} {}
+test string-14.13 {string replace} {
+    list [catch {string replace abc abc 1} msg] $msg
+} {1 {bad index "abc": must be integer?[+-]integer? or end?[+-]integer?}}
+test string-14.14 {string replace} {
+    list [catch {string replace abc 1 eof} msg] $msg
+} {1 {bad index "eof": must be integer?[+-]integer? or end?[+-]integer?}}
+test string-14.15 {string replace} {
+    string replace abcdefghijklmnop end-10 end-2 NEW
+} {abcdeNEWop}
+test string-14.16 {string replace} {
+    string replace abcdefghijklmnop 0 end foo
+} {foo}
+test string-14.17 {string replace} {
+    string replace abcdefghijklmnop end end-1
+} {abcdefghijklmnop}
+
+test string-15.1 {string tolower too few args} {
+    list [catch {string tolower} msg] $msg
+} {1 {wrong # args: should be "string tolower string ?first? ?last?"}}
+test string-15.2 {string tolower bad args} {
+    list [catch {string tolower a b} msg] $msg
+} {1 {bad index "b": must be integer?[+-]integer? or end?[+-]integer?}}
+test string-15.3 {string tolower too many args} {
+    list [catch {string tolower ABC 1 end oops} msg] $msg
+} {1 {wrong # args: should be "string tolower string ?first? ?last?"}}
+test string-15.4 {string tolower} {
+    string tolower ABCDeF
+} {abcdef}
+test string-15.5 {string tolower} {
+    string tolower "ABC  XyZ"
+} {abc  xyz}
+test string-15.6 {string tolower} {
+    string tolower {123#$&*()}
+} {123#$&*()}
+test string-15.7 {string tolower} {
+    string tolower ABC 1
+} AbC
+test string-15.8 {string tolower} {
+    string tolower ABC 1 end
+} Abc
+test string-15.9 {string tolower} {
+    string tolower ABC 0 end-1
+} abC
+test string-15.10 {string tolower, unicode} {
+     string tolower ABCabc\xc7\xe7
+} "abcabc\xe7\xe7"
+test string-15.11 {string tolower, compiled} {
+    lindex [string tolower [list A B [list C]]] 1
+} b
+
+test string-16.1 {string toupper} {
+    list [catch {string toupper} msg] $msg
+} {1 {wrong # args: should be "string toupper string ?first? ?last?"}}
+test string-16.2 {string toupper} {
+    list [catch {string toupper a b} msg] $msg
+} {1 {bad index "b": must be integer?[+-]integer? or end?[+-]integer?}}
+test string-16.3 {string toupper} {
+    list [catch {string toupper a 1 end oops} msg] $msg
+} {1 {wrong # args: should be "string toupper string ?first? ?last?"}}
+test string-16.4 {string toupper} {
+    string toupper abCDEf
+} {ABCDEF}
+test string-16.5 {string toupper} {
+    string toupper "abc xYz"
+} {ABC XYZ}
+test string-16.6 {string toupper} {
+    string toupper {123#$&*()}
+} {123#$&*()}
+test string-16.7 {string toupper} {
+    string toupper abc 1
+} aBc
+test string-16.8 {string toupper} {
+    string toupper abc 1 end
+} aBC
+test string-16.9 {string toupper} {
+    string toupper abc 0 end-1
+} ABc
+test string-16.10 {string toupper, unicode} {
+    string toupper ABCabc\xc7\xe7
+} "ABCABC\xc7\xc7"
+test string-16.11 {string toupper, compiled} {
+    lindex [string toupper [list a b [list c]]] 1
+} B
+
+test string-17.1 {string totitle} {
+    list [catch {string totitle} msg] $msg
+} {1 {wrong # args: should be "string totitle string ?first? ?last?"}}
+test string-17.2 {string totitle} {
+    list [catch {string totitle a b} msg] $msg
+} {1 {bad index "b": must be integer?[+-]integer? or end?[+-]integer?}}
+test string-17.3 {string totitle} {
+    string totitle abCDEf
+} {Abcdef}
+test string-17.4 {string totitle} {
+    string totitle "abc xYz"
+} {Abc xyz}
+test string-17.5 {string totitle} {
+    string totitle {123#$&*()}
+} {123#$&*()}
+test string-17.6 {string totitle, unicode} {
+    string totitle ABCabc\xc7\xe7
+} "Abcabc\xe7\xe7"
+test string-17.7 {string totitle, unicode} {
+    string totitle \u01f3BCabc\xc7\xe7
+} "\u01f2bcabc\xe7\xe7"
+test string-17.8 {string totitle, compiled} {
+    lindex [string totitle [list aa bb [list cc]]] 0
+} Aa
+
+test string-18.1 {string trim} {
+    list [catch {string trim} msg] $msg
+} {1 {wrong # args: should be "string trim string ?chars?"}}
+test string-18.2 {string trim} {
+    list [catch {string trim a b c} msg] $msg
+} {1 {wrong # args: should be "string trim string ?chars?"}}
+test string-18.3 {string trim} {
+    string trim "    XYZ      "
+} {XYZ}
+test string-18.4 {string trim} {
+    string trim "\t\nXYZ\t\n\r\n"
+} {XYZ}
+test string-18.5 {string trim} {
+    string trim "  A XYZ A    "
+} {A XYZ A}
+test string-18.6 {string trim} {
+    string trim "XXYYZZABC XXYYZZ" ZYX
+} {ABC }
+test string-18.7 {string trim} {
+    string trim "    \t\r      "
+} {}
+test string-18.8 {string trim} {
+    string trim {abcdefg} {}
+} {abcdefg}
+test string-18.9 {string trim} {
+    string trim {}
+} {}
+test string-18.10 {string trim} {
+    string trim ABC DEF
+} {ABC}
+test string-18.11 {string trim, unicode} {
+    string trim "\xe7\xe8 AB\xe7C \xe8\xe7" \xe7\xe8
+} " AB\xe7C "
+test string-18.12 {string trim, unicode default} {
+    string trim \ufeff\x00\u0085\u00a0\u1680\u180eABC\u1361\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u200b\u2028\u2029\u202f\u205f\u3000
+} ABC\u1361
+
+test string-19.1 {string trimleft} {
+    list [catch {string trimleft} msg] $msg
+} {1 {wrong # args: should be "string trimleft string ?chars?"}}
+test string-19.2 {string trimleft} {
+    string trimleft "    XYZ      "
+} {XYZ      }
+test string-19.3 {string trimleft, unicode default} {
+    string trimleft \ufeff\u0085\u00a0\x00\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u200b\u2028\u2029\u202f\u205f\u3000\u1361ABC
+} \u1361ABC
+
+test string-20.1 {string trimright errors} {
+    list [catch {string trimright} msg] $msg
+} {1 {wrong # args: should be "string trimright string ?chars?"}}
+test string-20.2 {string trimright errors} {
+    list [catch {string trimg a} msg] $msg
+} {1 {unknown or ambiguous subcommand "trimg": must be bytelength, cat, compare, equal, first, index, is, last, length, map, match, range, repeat, replace, reverse, tolower, totitle, toupper, trim, trimleft, trimright, wordend, or wordstart}}
+test string-20.3 {string trimright} {
+    string trimright "    XYZ      "
+} {    XYZ}
+test string-20.4 {string trimright} {
+    string trimright "   "
+} {}
+test string-20.5 {string trimright} {
+    string trimright ""
+} {}
+test string-20.6 {string trimright, unicode default} {
+    string trimright ABC\u1361\u0085\x00\u00a0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u200b\u2028\u2029\u202f\u205f\u3000
+} ABC\u1361
+
+test string-21.1 {string wordend} {
+    list [catch {string wordend a} msg] $msg
+} {1 {wrong # args: should be "string wordend string index"}}
+test string-21.2 {string wordend} {
+    list [catch {string wordend a b c} msg] $msg
+} {1 {wrong # args: should be "string wordend string index"}}
+test string-21.3 {string wordend} {
+    list [catch {string wordend a gorp} msg] $msg
+} {1 {bad index "gorp": must be integer?[+-]integer? or end?[+-]integer?}}
+test string-21.4 {string wordend} {
+    string wordend abc. -1
+} 3
+test string-21.5 {string wordend} {
+    string wordend abc. 100
+} 4
+test string-21.6 {string wordend} {
+    string wordend "word_one two three" 2
+} 8
+test string-21.7 {string wordend} {
+    string wordend "one .&# three" 5
+} 6
+test string-21.8 {string wordend} {
+    string worde "x.y" 0
+} 1
+test string-21.9 {string wordend} {
+    string worde "x.y" end-1
+} 2
+test string-21.10 {string wordend, unicode} {
+    string wordend "xyz\u00c7de fg" 0
+} 6
+test string-21.11 {string wordend, unicode} {
+    string wordend "xyz\uc700de fg" 0
+} 6
+test string-21.12 {string wordend, unicode} {
+    string wordend "xyz\u203fde fg" 0
+} 6
+test string-21.13 {string wordend, unicode} {
+    string wordend "xyz\u2045de fg" 0
+} 3
+test string-21.14 {string wordend, unicode} {
+    string wordend "\uc700\uc700 abc" 8
+} 6
+
+test string-22.1 {string wordstart} {
+    list [catch {string word a} msg] $msg
+} {1 {unknown or ambiguous subcommand "word": must be bytelength, cat, compare, equal, first, index, is, last, length, map, match, range, repeat, replace, reverse, tolower, totitle, toupper, trim, trimleft, trimright, wordend, or wordstart}}
+test string-22.2 {string wordstart} {
+    list [catch {string wordstart a} msg] $msg
+} {1 {wrong # args: should be "string wordstart string index"}}
+test string-22.3 {string wordstart} {
+    list [catch {string wordstart a b c} msg] $msg
+} {1 {wrong # args: should be "string wordstart string index"}}
+test string-22.4 {string wordstart} {
+    list [catch {string wordstart a gorp} msg] $msg
+} {1 {bad index "gorp": must be integer?[+-]integer? or end?[+-]integer?}}
+test string-22.5 {string wordstart} {
+    string wordstart "one two three_words" 400
+} 8
+test string-22.6 {string wordstart} {
+    string wordstart "one two three_words" 2
+} 0
+test string-22.7 {string wordstart} {
+    string wordstart "one two three_words" -2
+} 0
+test string-22.8 {string wordstart} {
+    string wordstart "one .*&^ three" 6
+} 6
+test string-22.9 {string wordstart} {
+    string wordstart "one two three" 4
+} 4
+test string-22.10 {string wordstart} {
+    string wordstart "one two three" end-5
+} 7
+test string-22.11 {string wordstart, unicode} {
+    string wordstart "one tw\u00c7o three" 7
+} 4
+test string-22.12 {string wordstart, unicode} {
+    string wordstart "ab\uc700\uc700 cdef ghi" 12
+} 10
+test string-22.13 {string wordstart, unicode} {
+    string wordstart "\uc700\uc700 abc" 8
+} 3
+
+test string-23.0 {string is boolean, Bug 1187123} testindexobj {
+    set x 5
+    catch {testindexobj $x foo bar soom}
+    string is boolean $x
+} 0
+test string-23.1 {string is command with empty string} {
+    set s ""
+    list \
+        [string is alnum $s] \
+        [string is alpha $s] \
+        [string is ascii $s] \
+        [string is control $s] \
+        [string is boolean $s] \
+        [string is digit $s] \
+        [string is double $s] \
+        [string is false $s] \
+        [string is graph $s] \
+        [string is integer $s] \
+        [string is lower $s] \
+        [string is print $s] \
+        [string is punct $s] \
+        [string is space $s] \
+        [string is true $s] \
+        [string is upper $s] \
+        [string is wordchar $s] \
+        [string is xdigit $s] \
+
+} {1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1}
+test string-23.2 {string is command with empty string} {
+    set s ""
+    list \
+        [string is alnum -strict $s] \
+        [string is alpha -strict $s] \
+        [string is ascii -strict $s] \
+        [string is control -strict $s] \
+        [string is boolean -strict $s] \
+        [string is digit -strict $s] \
+        [string is double -strict $s] \
+        [string is false -strict $s] \
+        [string is graph -strict $s] \
+        [string is integer -strict $s] \
+        [string is lower -strict $s] \
+        [string is print -strict $s] \
+        [string is punct -strict $s] \
+        [string is space -strict $s] \
+        [string is true -strict $s] \
+        [string is upper -strict $s] \
+        [string is wordchar -strict $s] \
+        [string is xdigit -strict $s] \
+
+} {0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0}
+
+test string-24.1 {string reverse command} -body {
+    string reverse
+} -returnCodes error -result "wrong # args: should be \"string reverse string\""
+test string-24.2 {string reverse command} -body {
+    string reverse a b
+} -returnCodes error -result "wrong # args: should be \"string reverse string\""
+test string-24.3 {string reverse command - shared string} {
+    set x abcde
+    string reverse $x
+} edcba
+test string-24.4 {string reverse command - unshared string} {
+    set x abc
+    set y de
+    string reverse $x$y
+} edcba
+test string-24.5 {string reverse command - shared unicode string} {
+    set x abcde\udead
+    string reverse $x
+} \udeadedcba
+test string-24.6 {string reverse command - unshared string} {
+    set x abc
+    set y de\udead
+    string reverse $x$y
+} \udeadedcba
+test string-24.7 {string reverse command - simple case} {
+    string reverse a
+} a
+test string-24.8 {string reverse command - simple case} {
+    string reverse \udead
+} \udead
+test string-24.9 {string reverse command - simple case} {
+    string reverse {}
+} {}
+test string-24.10 {string reverse command - corner case} {
+    set x \ubeef\udead
+    string reverse $x
+} \udead\ubeef
+test string-24.11 {string reverse command - corner case} {
+    set x \ubeef
+    set y \udead
+    string reverse $x$y
+} \udead\ubeef
+test string-24.12 {string reverse command - corner case} {
+    set x \ubeef
+    set y \udead
+    string is ascii [string reverse $x$y]
+} 0
+test string-24.13 {string reverse command - pure Unicode string} {
+    string reverse [string range \ubeef\udead\ubeef\udead\ubeef\udead 1 5]
+} \udead\ubeef\udead\ubeef\udead
+test string-24.14 {string reverse command - pure bytearray} {
+    binary scan [string reverse [binary format H* 010203]] H* x
+    set x
+} 030201
+test string-24.15 {string reverse command - pure bytearray} {
+    binary scan [tcl::string::reverse [binary format H* 010203]] H* x
+    set x
+} 030201
+
+test string-25.1 {string is list} {
+    string is list {a b c}
+} 1
+test string-25.2 {string is list} {
+    string is list "a \{b c"
+} 0
+test string-25.3 {string is list} {
+    string is list {a {b c}d e}
+} 0
+test string-25.4 {string is list} {
+    string is list {}
+} 1
+test string-25.5 {string is list} {
+    string is list -strict {a b c}
+} 1
+test string-25.6 {string is list} {
+    string is list -strict "a \{b c"
+} 0
+test string-25.7 {string is list} {
+    string is list -strict {a {b c}d e}
+} 0
+test string-25.8 {string is list} {
+    string is list -strict {}
+} 1
+test string-25.9 {string is list} {
+    set x {}
+    list [string is list -failindex x {a b c}] $x
+} {1 {}}
+test string-25.10 {string is list} {
+    set x {}
+    list [string is list -failindex x "a \{b c"] $x
+} {0 2}
+test string-25.11 {string is list} {
+    set x {}
+    list [string is list -failindex x {a b {b c}d e}] $x
+} {0 4}
+test string-25.12 {string is list} {
+    set x {}
+    list [string is list -failindex x {}] $x
+} {1 {}}
+test string-25.13 {string is list} {
+    set x {}
+    list [string is list -failindex x {  {b c}d e}] $x
+} {0 2}
+test string-25.14 {string is list} {
+    set x {}
+    list [string is list -failindex x "\uabcd {b c}d e"] $x
+} {0 2}
+
+test string-26.1 {tcl::prefix, too few args} -body {
+    tcl::prefix match a
+} -returnCodes 1 -result {wrong # args: should be "tcl::prefix match ?options? table string"}
+test string-26.2 {tcl::prefix, bad args} -body {
+    tcl::prefix match a b c
+} -returnCodes 1 -result {bad option "a": must be -error, -exact, or -message}
+test string-26.2.1 {tcl::prefix, empty table} -body {
+    tcl::prefix match {} foo
+} -returnCodes 1 -result {bad option "foo": no valid options}
+test string-26.3 {tcl::prefix, bad args} -body {
+    tcl::prefix match -error "{}x" -exact str1 str2
+} -returnCodes 1 -result {list element in braces followed by "x" instead of space}
+test string-26.3.1 {tcl::prefix, bad args} -body {
+    tcl::prefix match -error "x" -exact str1 str2
+} -returnCodes 1 -result {error options must have an even number of elements}
+test string-26.3.2 {tcl::prefix, bad args} -body {
+    tcl::prefix match -error str1 str2
+} -returnCodes 1 -result {missing value for -error}
+test string-26.4 {tcl::prefix, bad args} -body {
+    tcl::prefix match -message str1 str2
+} -returnCodes 1 -result {missing value for -message}
+test string-26.5 {tcl::prefix} {
+    tcl::prefix match {apa bepa cepa depa} cepa
+} cepa
+test string-26.6 {tcl::prefix} {
+    tcl::prefix match {apa bepa cepa depa} be
+} bepa
+test string-26.7 {tcl::prefix} -body {
+    tcl::prefix match -exact {apa bepa cepa depa} be
+} -returnCodes 1 -result {bad option "be": must be apa, bepa, cepa, or depa}
+test string-26.8 {tcl::prefix} -body {
+    tcl::prefix match -message wombat {apa bepa bear depa} be
+} -returnCodes 1 -result {ambiguous wombat "be": must be apa, bepa, bear, or depa}
+test string-26.9 {tcl::prefix} -body {
+    tcl::prefix match -error {} {apa bepa bear depa} be
+} -returnCodes 0 -result {}
+test string-26.10 {tcl::prefix} -body {
+    tcl::prefix match -error {-level 1} {apa bepa bear depa} be
+} -returnCodes 2 -result {ambiguous option "be": must be apa, bepa, bear, or depa}
+test string-26.10.1 {tcl::prefix} -setup {
+    proc _testprefix {args} {
+        array set opts {-a x -b y -c y}
+        foreach {opt val} $args {
+            set opt [tcl::prefix match -error {-level 1} {-a -b -c} $opt]
+            set opts($opt) $val
+        }
+        array get opts
+    }
+} -body {
+    set a [catch {_testprefix -x u} result options]
+    dict get $options -errorinfo
+} -cleanup {
+    rename _testprefix {}
+} -result {bad option "-x": must be -a, -b, or -c
+    while executing
+"_testprefix -x u"}
+
+# Helper for memory stress tests
+# Repeat each body in a local space checking that memory does not increase
+proc MemStress {args} {
+    set res {}
+    foreach body $args {
+        set end 0
+        for {set i 0} {$i < 5} {incr i} { 
+            proc MemStress_Body {} $body
+            uplevel 1 MemStress_Body
+            rename MemStress_Body {}
+            set tmp $end
+            set end [lindex [lindex [split [memory info] "\n"] 3] 3]
+        }
+        lappend res [expr {$end - $tmp}]
+    }
+    return $res
+}
+
+test string-26.11 {tcl::prefix: testing for leaks} -body {
+    # This test is made to stress object reference management
+    MemStress {
+        set table {hejj miff gurk}
+        set item [lindex $table 1]
+        # If not careful, this can cause a circular reference
+        # that will cause a leak.
+        tcl::prefix match $table $item
+    } {
+        # A similar case with nested lists
+        set table2 {hejj {miff maff} gurk}
+        set item [lindex [lindex $table2 1] 0]
+        tcl::prefix match $table2 $item
+    } {
+        # A similar case with dict
+        set table3 {hejj {miff maff} gurk2}
+        set item [lindex [dict keys [lindex $table3 1]] 0]
+        tcl::prefix match $table3 $item
+    }
+} -constraints memory -result {0 0 0}
+
+test string-26.12 {tcl::prefix: testing for leaks} -body {
+    # This is a memory leak test in a form that might actually happen
+    # in real code.  The shared literal "miff" causes a connection
+    # between the item and the table.
+    MemStress {
+        proc stress1 {item} {
+            set table [list hejj miff gurk]
+            tcl::prefix match $table $item
+        }
+        proc stress2 {} {
+            stress1 miff
+        }
+        stress2
+        rename stress1 {}
+        rename stress2 {}
+    }
+} -constraints memory -result 0
+
+test string-26.13 {tcl::prefix: testing for leaks} -body {
+    # This test is made to stress object reference management
+    MemStress {
+        set table [list hejj miff]
+        set item $table
+        set error $table
+        # Use the same objects in all places
+        catch {
+            tcl::prefix match -error $error $table $item
+        }
+    }
+} -constraints memory -result {0}
+
+test string-27.1 {tcl::prefix all, too few args} -body {
+    tcl::prefix all a
+} -returnCodes 1 -result {wrong # args: should be "tcl::prefix all table string"}
+test string-27.2 {tcl::prefix all, bad args} -body {
+    tcl::prefix all a b c
+} -returnCodes 1 -result {wrong # args: should be "tcl::prefix all table string"}
+test string-27.3 {tcl::prefix all, bad args} -body {
+    tcl::prefix all "{}x" str2
+} -returnCodes 1 -result {list element in braces followed by "x" instead of space}
+test string-27.4 {tcl::prefix all} {
+    tcl::prefix all {apa bepa cepa depa} c
+} cepa
+test string-27.5 {tcl::prefix all} {
+    tcl::prefix all {apa bepa cepa depa} cepa
+} cepa
+test string-27.6 {tcl::prefix all} {
+    tcl::prefix all {apa bepa cepa depa} cepax
+} {}
+test string-27.7 {tcl::prefix all} {
+    tcl::prefix all {apa aska appa} a
+} {apa aska appa}
+test string-27.8 {tcl::prefix all} {
+    tcl::prefix all {apa aska appa} ap
+} {apa appa}
+test string-27.9 {tcl::prefix all} {
+    tcl::prefix all {apa aska appa} p
+} {}
+test string-27.10 {tcl::prefix all} {
+    tcl::prefix all {apa aska appa} {}
+} {apa aska appa}
+
+test string-28.1 {tcl::prefix longest, too few args} -body {
+    tcl::prefix longest a
+} -returnCodes 1 -result {wrong # args: should be "tcl::prefix longest table string"}
+test string-28.2 {tcl::prefix longest, bad args} -body {
+    tcl::prefix longest a b c
+} -returnCodes 1 -result {wrong # args: should be "tcl::prefix longest table string"}
+test string-28.3 {tcl::prefix longest, bad args} -body {
+    tcl::prefix longest "{}x" str2
+} -returnCodes 1 -result {list element in braces followed by "x" instead of space}
+test string-28.4 {tcl::prefix longest} {
+    tcl::prefix longest {apa bepa cepa depa} c
+} cepa
+test string-28.5 {tcl::prefix longest} {
+    tcl::prefix longest {apa bepa cepa depa} cepa
+} cepa
+test string-28.6 {tcl::prefix longest} {
+    tcl::prefix longest {apa bepa cepa depa} cepax
+} {}
+test string-28.7 {tcl::prefix longest} {
+    tcl::prefix longest {apa aska appa} a
+} a
+test string-28.8 {tcl::prefix longest} {
+    tcl::prefix longest {apa aska appa} ap
+} ap
+test string-28.9 {tcl::prefix longest} {
+    tcl::prefix longest {apa bska appa} a
+} ap
+test string-28.10 {tcl::prefix longest} {
+    tcl::prefix longest {apa bska appa} {}
+} {}
+test string-28.11 {tcl::prefix longest} {
+    tcl::prefix longest {{} bska appa} {}
+} {}
+test string-28.12 {tcl::prefix longest} {
+    tcl::prefix longest {apa {} appa} {}
+} {}
+test string-28.13 {tcl::prefix longest} {
+    # Test UTF8 handling
+    tcl::prefix longest {ax\x90 bep ax\x91} a
+} ax
+
+test string-29.1 {string cat, no arg} {
+    string cat
+} ""
+test string-29.2 {string cat, single arg} {
+    set x FOO
+    string compare $x [string cat $x]
+} 0
+test string-29.3 {string cat, two args} {
+    set x FOO
+    string compare $x$x [string cat $x $x]
+} 0
+test string-29.4 {string cat, many args} {
+    set x FOO
+    set n 260
+    set xx [string repeat $x $n]
+    set vv [string repeat {$x} $n]
+    set vvs [string repeat {$x } $n]
+    set r1 [string compare $xx [subst $vv]]
+    set r2 [string compare $xx [eval "string cat $vvs"]]
+    list $r1 $r2
+} {0 0}
+
+
+
+# cleanup
+rename MemStress {}
+catch {rename foo {}}
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/tests/stringComp.test b/tests/stringComp.test
new file mode 100644
index 0000000..140a270
--- /dev/null
+++ b/tests/stringComp.test
@@ -0,0 +1,798 @@
+# Commands covered:  string
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands.  Sourcing this file into Tcl runs the tests and
+# generates output for errors.  No output means no errors were found.
+#
+# This differs from the original string tests in that the tests call
+# things in procs, which uses the compiled string code instead of
+# the runtime parse string code.  The tests of import should match
+# their equivalent number in string.test.
+#
+# Copyright (c) 2001 by ActiveState Corporation.
+# Copyright (c) 2001 by Kevin B. Kenny.  All rights reserved.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+    package require tcltest
+    namespace import -force ::tcltest::*
+}
+
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
+
+# Some tests require the testobj command
+
+testConstraint testobj [expr {[info commands testobj] != {}}]
+testConstraint memory [llength [info commands memory]]
+if {[testConstraint memory]} {
+    proc getbytes {} {
+	set lines [split [memory info] \n]
+	return [lindex $lines 3 3]
+    }
+    proc leaktest {script {iterations 3}} {
+	set end [getbytes]
+	for {set i 0} {$i < $iterations} {incr i} {
+	    uplevel 1 $script
+	    set tmp $end
+	    set end [getbytes]
+	}
+	return [expr {$end - $tmp}]
+    }
+}
+
+test stringComp-1.1 {error conditions} {
+    proc foo {} {string gorp a b}
+    list [catch {foo} msg] $msg
+} {1 {unknown or ambiguous subcommand "gorp": must be bytelength, cat, compare, equal, first, index, is, last, length, map, match, range, repeat, replace, reverse, tolower, totitle, toupper, trim, trimleft, trimright, wordend, or wordstart}}
+test stringComp-1.2 {error conditions} {
+    proc foo {} {string}
+    list [catch {foo} msg] $msg
+} {1 {wrong # args: should be "string subcommand ?arg ...?"}}
+test stringComp-1.3 {error condition - undefined method during compile} {
+    # We don't want this to complain about 'never' because it may never
+    # be called, or string may get redefined.  This must compile OK.
+    proc foo {str i} {
+        if {"yes" == "no"} { string never called but complains here }
+        string index $str $i
+    }
+    foo abc 0
+} a
+
+## Test string compare|equal over equal constraints
+## Use result for string compare, and negate it for string equal
+## The body will be tested both in and outside a proc
+set i 0
+foreach {tname tbody tresult tcode} {
+    {too few args} {
+	string compare a
+    } {wrong # args: should be "string compare ?-nocase? ?-length int? string1 string2"} {error}
+    {bad args} {
+	string compare a b c
+    } {bad option "a": must be -nocase or -length} {error}
+    {bad args} {
+	string compare -length -nocase str1 str2
+    } {expected integer but got "-nocase"} {error}
+    {too many args} {
+	string compare -length 10 -nocase str1 str2 str3
+    } {wrong # args: should be "string compare ?-nocase? ?-length int? string1 string2"} {error}
+    {compare with length unspecified} {
+	string compare -length 10 10
+    } {wrong # args: should be "string compare ?-nocase? ?-length int? string1 string2"} {error}
+    {basic operation fail} {
+	string compare abcde abdef
+    } {-1} {}
+    {basic operation success} {
+	string compare abcde abcde
+    } {0} {}
+    {with length} {
+	string compare -length 2 abcde abxyz
+    } {0} {}
+    {with special index} {
+	string compare -length end-3 abcde abxyz
+    } {expected integer but got "end-3"} {error}
+    {unicode} {
+	string compare ab\u7266 ab\u7267
+    } {-1} {}
+    {unicode} {string compare \334 \u00dc} 0 {}
+    {unicode} {string compare \334 \u00fc} -1 {}
+    {unicode} {string compare \334\334\334\374\374 \334\334\334\334\334} 1 {}
+    {high bit} {
+	# This test will fail if the underlying comparaison
+	# is using signed chars instead of unsigned chars.
+	# (like SunOS's default memcmp thus the compat/memcmp.c)
+	string compare "\x80" "@"
+	# Nb this tests works also in utf8 space because \x80 is
+	# translated into a 2 or more bytelength but whose first byte has
+	# the high bit set.
+    } {1} {}
+    {-nocase 1} {string compare -nocase abcde abdef} {-1} {}
+    {-nocase 2} {string compare -nocase abcde Abdef} {-1} {}
+    {-nocase 3} {string compare -nocase abcde ABCDE} {0} {}
+    {-nocase 4} {string compare -nocase abcde abcde} {0} {}
+    {-nocase unicode} {
+	string compare -nocase \334 \u00dc
+    } 0 {}
+    {-nocase unicode} {
+	string compare -nocase \334\334\334\374\u00fc \334\334\334\334\334
+    } 0 {}
+    {-nocase with length} {
+	string compare -length 2 -nocase abcde Abxyz
+    } {0} {}
+    {-nocase with length} {
+	string compare -nocase -length 3 abcde Abxyz
+    } {-1} {}
+    {-nocase with length <= 0} {
+	string compare -nocase -length -1 abcde AbCdEf
+    } {-1} {}
+    {-nocase with excessive length} {
+	string compare -nocase -length 50 AbCdEf abcde
+    } {1} {}
+    {-len unicode} {
+	# These are strings that are 6 BYTELENGTH long, but the length
+	# shouldn't make a different because there are actually 3 CHARS long
+	string compare -len 5 \334\334\334 \334\334\374
+    } -1 {}
+    {-nocase with special index} {
+	string compare -nocase -length end-3 Abcde abxyz
+    } {expected integer but got "end-3"} error
+    {null strings} {
+	string compare "" ""
+    } 0 {}
+    {null strings} {
+	string compare "" foo
+    } -1 {}
+    {null strings} {
+	string compare foo ""
+    } 1 {}
+    {-nocase null strings} {
+	string compare -nocase "" ""
+    } 0 {}
+    {-nocase null strings} {
+	string compare -nocase "" foo
+    } -1 {}
+    {-nocase null strings} {
+	string compare -nocase foo ""
+    } 1 {}
+    {with length, unequal strings} {
+	string compare -length 2 abc abde
+    } 0 {}
+    {with length, unequal strings} {
+	string compare -length 2 ab abde
+    } 0 {}
+    {with NUL character vs. other ASCII} {
+	# Be careful here, since UTF-8 rep comparison with memcmp() of
+	# these puts chars in the wrong order
+	string compare \x00 \x01
+    } -1 {}
+    {high bit} {
+	string compare "a\x80" "a@"
+    } 1 {}
+    {high bit} {
+	string compare "a\x00" "a\x01"
+    } -1 {}
+    {high bit} {
+	string compare "\x00\x00" "\x00\x01"
+    } -1 {}
+    {binary equal} {
+	string compare [binary format a100 0] [binary format a100 0]
+    } 0 {}
+    {binary neq} {
+	string compare [binary format a100a 0 1] [binary format a100a 0 0]
+    } 1 {}
+    {binary neq inequal length} {
+	string compare [binary format a20a 0 1] [binary format a100a 0 0]
+    } 1 {}
+} {
+    if {$tname eq ""} { continue }
+    if {$tcode eq ""} { set tcode ok }
+    test stringComp-2.[incr i] "string compare, $tname" \
+	-body [list eval $tbody] \
+	-returnCodes $tcode -result $tresult
+    test stringComp-2.[incr i] "string compare bc, $tname" \
+	-body "[list proc foo {} $tbody];foo" \
+	-returnCodes $tcode -result $tresult
+    if {"error" ni $tcode} {
+	set tresult [expr {!$tresult}]
+    } else {
+	set tresult [string map {compare equal} $tresult]
+    }
+    set tbody [string map {compare equal} $tbody]
+    test stringComp-2.[incr i] "string equal, $tname" \
+	-body [list eval $tbody] \
+	-returnCodes $tcode -result $tresult
+    test stringComp-2.[incr i] "string equal bc, $tname" \
+	-body "[list proc foo {} $tbody];foo" \
+	-returnCodes $tcode -result $tresult
+}
+
+# need a few extra tests short abbr cmd
+test stringComp-3.1 {string compare, shortest method name} {
+    proc foo {} {string co abcde ABCDE}
+    foo
+} 1
+test stringComp-3.2 {string equal, shortest method name} {
+    proc foo {} {string e abcde ABCDE}
+    foo
+} 0
+test stringComp-3.3 {string equal -nocase} {
+    proc foo {} {string eq -nocase abcde ABCDE}
+    foo
+} 1
+
+test stringComp-4.1 {string first, too few args} {
+    proc foo {} {string first a}
+    list [catch {foo} msg] $msg
+} {1 {wrong # args: should be "string first needleString haystackString ?startIndex?"}}
+test stringComp-4.2 {string first, bad args} {
+    proc foo {} {string first a b c}
+    list [catch {foo} msg] $msg
+} {1 {bad index "c": must be integer?[+-]integer? or end?[+-]integer?}}
+test stringComp-4.3 {string first, too many args} {
+    proc foo {} {string first a b 5 d}
+    list [catch {foo} msg] $msg
+} {1 {wrong # args: should be "string first needleString haystackString ?startIndex?"}}
+test stringComp-4.4 {string first} {
+    proc foo {} {string first bq abcdefgbcefgbqrs}
+    foo
+} 12
+test stringComp-4.5 {string first} {
+    proc foo {} {string fir bcd abcdefgbcefgbqrs}
+    foo
+} 1
+test stringComp-4.6 {string first} {
+    proc foo {} {string f b abcdefgbcefgbqrs}
+    foo
+} 1
+test stringComp-4.7 {string first} {
+    proc foo {} {string first xxx x123xx345xxx789xxx012}
+    foo
+} 9
+test stringComp-4.8 {string first} {
+    proc foo {} {string first "" x123xx345xxx789xxx012}
+    foo
+} -1
+test stringComp-4.9 {string first, unicode} {
+    proc foo {} {string first x abc\u7266x}
+    foo
+} 4
+test stringComp-4.10 {string first, unicode} {
+    proc foo {} {string first \u7266 abc\u7266x}
+    foo
+} 3
+test stringComp-4.11 {string first, start index} {
+    proc foo {} {string first \u7266 abc\u7266x 3}
+    foo
+} 3
+test stringComp-4.12 {string first, start index} {
+    proc foo {} {string first \u7266 abc\u7266x 4}
+    foo
+} -1
+test stringComp-4.13 {string first, start index} {
+    proc foo {} {string first \u7266 abc\u7266x end-2}
+    foo
+} 3
+test stringComp-4.14 {string first, negative start index} {
+    proc foo {} {string first b abc -1}
+    foo
+} 1
+
+test stringComp-5.1 {string index} {
+    proc foo {} {string index}
+    list [catch {foo} msg] $msg
+} {1 {wrong # args: should be "string index string charIndex"}}
+test stringComp-5.2 {string index} {
+    proc foo {} {string index a b c}
+    list [catch {foo} msg] $msg
+} {1 {wrong # args: should be "string index string charIndex"}}
+test stringComp-5.3 {string index} {
+    proc foo {} {string index abcde 0}
+    foo
+} a
+test stringComp-5.4 {string index} {
+    proc foo {} {string in abcde 4}
+    foo
+} e
+test stringComp-5.5 {string index} {
+    proc foo {} {string index abcde 5}
+    foo
+} {}
+test stringComp-5.6 {string index} {
+    proc foo {} {string index abcde -10}
+    list [catch {foo} msg] $msg
+} {0 {}}
+test stringComp-5.7 {string index} {
+    proc foo {} {string index a xyz}
+    list [catch {foo} msg] $msg
+} {1 {bad index "xyz": must be integer?[+-]integer? or end?[+-]integer?}}
+test stringComp-5.8 {string index} {
+    proc foo {} {string index abc end}
+    foo
+} c
+test stringComp-5.9 {string index} {
+    proc foo {} {string index abc end-1}
+    foo
+} b
+test stringComp-5.10 {string index, unicode} {
+    proc foo {} {string index abc\u7266d 4}
+    foo
+} d
+test stringComp-5.11 {string index, unicode} {
+    proc foo {} {string index abc\u7266d 3}
+    foo
+} \u7266
+test stringComp-5.12 {string index, unicode over char length, under byte length} {
+    proc foo {} {string index \334\374\334\374 6}
+    foo
+} {}
+test stringComp-5.13 {string index, bytearray object} {
+    proc foo {} {string index [binary format a5 fuz] 0}
+    foo
+} f
+test stringComp-5.14 {string index, bytearray object} {
+    proc foo {} {string index [binary format I* {0x50515253 0x52}] 3}
+    foo
+} S
+test stringComp-5.15 {string index, bytearray object} {
+    proc foo {} {
+	set b [binary format I* {0x50515253 0x52}]
+	set i1 [string index $b end-6]
+	set i2 [string index $b 1]
+	string compare $i1 $i2
+    }
+    foo
+} 0
+test stringComp-5.16 {string index, bytearray object with string obj shimmering} {
+    proc foo {} {
+	set str "0123456789\x00 abcdedfghi"
+	binary scan $str H* dump
+	string compare [string index $str 10] \x00
+    }
+    foo
+} 0
+test stringComp-5.17 {string index, bad integer} -body {
+    proc foo {} {string index "abc" 0o8}
+    list [catch {foo} msg] $msg
+} -match glob -result {1 {*invalid octal number*}}
+test stringComp-5.18 {string index, bad integer} -body {
+    proc foo {} {string index "abc" end-0o0289}
+    list [catch {foo} msg] $msg
+} -match glob -result {1 {*invalid octal number*}}
+test stringComp-5.19 {string index, bytearray object out of bounds} {
+    proc foo {} {string index [binary format I* {0x50515253 0x52}] -1}
+    foo
+} {}
+test stringComp-5.20 {string index, bytearray object out of bounds} {
+    proc foo {} {string index [binary format I* {0x50515253 0x52}] 20}
+    foo
+} {}
+
+
+proc largest_int {} {
+    # This will give us what the largest valid int on this machine is,
+    # so we can test for overflow properly below on >32 bit systems
+    set int 1
+    set exp 7; # assume we get at least 8 bits
+    while {$int > 0} { set int [expr {1 << [incr exp]}] }
+    return [expr {$int-1}]
+}
+
+## string is
+## not yet bc
+
+catch {rename largest_int {}}
+
+## string last
+## not yet bc
+
+## string length
+## not yet bc
+test stringComp-8.1 {string bytelength} {
+    proc foo {} {string bytelength}
+    list [catch {foo} msg] $msg
+} {1 {wrong # args: should be "string bytelength string"}}
+test stringComp-8.2 {string bytelength} {
+    proc foo {} {string bytelength a b}
+    list [catch {foo} msg] $msg
+} {1 {wrong # args: should be "string bytelength string"}}
+test stringComp-8.3 {string bytelength} {
+    proc foo {} {string bytelength "\u00c7"}
+    foo
+} 2
+test stringComp-8.4 {string bytelength} {
+    proc foo {} {string b ""}
+    foo
+} 0
+
+## string length
+##
+test stringComp-9.1 {string length} {
+    proc foo {} {string length}
+    list [catch {foo} msg] $msg
+} {1 {wrong # args: should be "string length string"}}
+test stringComp-9.2 {string length} {
+    proc foo {} {string length a b}
+    list [catch {foo} msg] $msg
+} {1 {wrong # args: should be "string length string"}}
+test stringComp-9.3 {string length} {
+    proc foo {} {string length "a little string"}
+    foo
+} 15
+test stringComp-9.4 {string length} {
+    proc foo {} {string le ""}
+    foo
+} 0
+test stringComp-9.5 {string length, unicode} {
+    proc foo {} {string le "abcd\u7266"}
+    foo
+} 5
+test stringComp-9.6 {string length, bytearray object} {
+    proc foo {} {string length [binary format a5 foo]}
+    foo
+} 5
+test stringComp-9.7 {string length, bytearray object} {
+    proc foo {} {string length [binary format I* {0x50515253 0x52}]}
+    foo
+} 8
+
+## string map
+## not yet bc
+
+## string match
+##
+test stringComp-11.1 {string match, too few args} {
+    proc foo {} {string match a}
+    list [catch {foo} msg] $msg
+} {1 {wrong # args: should be "string match ?-nocase? pattern string"}}
+test stringComp-11.2 {string match, too many args} {
+    proc foo {} {string match a b c d}
+    list [catch {foo} msg] $msg
+} {1 {wrong # args: should be "string match ?-nocase? pattern string"}}
+test stringComp-11.3 {string match} {
+    proc foo {} {string match abc abc}
+    foo
+} 1
+test stringComp-11.4 {string match} {
+    proc foo {} {string mat abc abd}
+    foo
+} 0
+test stringComp-11.5 {string match} {
+    proc foo {} {string match ab*c abc}
+    foo
+} 1
+test stringComp-11.6 {string match} {
+    proc foo {} {string match ab**c abc}
+    foo
+} 1
+test stringComp-11.7 {string match} {
+    proc foo {} {string match ab* abcdef}
+    foo
+} 1
+test stringComp-11.8 {string match} {
+    proc foo {} {string match *c abc}
+    foo
+} 1
+test stringComp-11.9 {string match} {
+    proc foo {} {string match *3*6*9 0123456789}
+    foo
+} 1
+test stringComp-11.10 {string match} {
+    proc foo {} {string match *3*6*9 01234567890}
+    foo
+} 0
+test stringComp-11.11 {string match} {
+    proc foo {} {string match a?c abc}
+    foo
+} 1
+test stringComp-11.12 {string match} {
+    proc foo {} {string match a??c abc}
+    foo
+} 0
+test stringComp-11.13 {string match} {
+    proc foo {} {string match ?1??4???8? 0123456789}
+    foo
+} 1
+test stringComp-11.14 {string match} {
+    proc foo {} {string match {[abc]bc} abc}
+    foo
+} 1
+test stringComp-11.15 {string match} {
+    proc foo {} {string match {a[abc]c} abc}
+    foo
+} 1
+test stringComp-11.16 {string match} {
+    proc foo {} {string match {a[xyz]c} abc}
+    foo
+} 0
+test stringComp-11.17 {string match} {
+    proc foo {} {string match {12[2-7]45} 12345}
+    foo
+} 1
+test stringComp-11.18 {string match} {
+    proc foo {} {string match {12[ab2-4cd]45} 12345}
+    foo
+} 1
+test stringComp-11.19 {string match} {
+    proc foo {} {string match {12[ab2-4cd]45} 12b45}
+    foo
+} 1
+test stringComp-11.20 {string match} {
+    proc foo {} {string match {12[ab2-4cd]45} 12d45}
+    foo
+} 1
+test stringComp-11.21 {string match} {
+    proc foo {} {string match {12[ab2-4cd]45} 12145}
+    foo
+} 0
+test stringComp-11.22 {string match} {
+    proc foo {} {string match {12[ab2-4cd]45} 12545}
+    foo
+} 0
+test stringComp-11.23 {string match} {
+    proc foo {} {string match {a\*b} a*b}
+    foo
+} 1
+test stringComp-11.24 {string match} {
+    proc foo {} {string match {a\*b} ab}
+    foo
+} 0
+test stringComp-11.25 {string match} {
+    proc foo {} {string match {a\*\?\[\]\\\x} "a*?\[\]\\x"}
+    foo
+} 1
+test stringComp-11.26 {string match} {
+    proc foo {} {string match ** ""}
+    foo
+} 1
+test stringComp-11.27 {string match} {
+    proc foo {} {string match *. ""}
+    foo
+} 0
+test stringComp-11.28 {string match} {
+    proc foo {} {string match "" ""}
+    foo
+} 1
+test stringComp-11.29 {string match} {
+    proc foo {} {string match \[a a}
+    foo
+} 1
+test stringComp-11.30 {string match, bad args} {
+    proc foo {} {string match - b c}
+    list [catch {foo} msg] $msg
+} {1 {bad option "-": must be -nocase}}
+test stringComp-11.31 {string match case} {
+    proc foo {} {string match a A}
+    foo
+} 0
+test stringComp-11.32 {string match nocase} {
+    proc foo {} {string match -n a A}
+    foo
+} 1
+test stringComp-11.33 {string match nocase} {
+    proc foo {} {string match -nocase a\334 A\374}
+    foo
+} 1
+test stringComp-11.34 {string match nocase} {
+    proc foo {} {string match -nocase a*f ABCDEf}
+    foo
+} 1
+test stringComp-11.35 {string match case, false hope} {
+    # This is true because '_' lies between the A-Z and a-z ranges
+    proc foo {} {string match {[A-z]} _}
+    foo
+} 1
+test stringComp-11.36 {string match nocase range} {
+    # This is false because although '_' lies between the A-Z and a-z ranges,
+    # we lower case the end points before checking the ranges.
+    proc foo {} {string match -nocase {[A-z]} _}
+    foo
+} 0
+test stringComp-11.37 {string match nocase} {
+    proc foo {} {string match -nocase {[A-fh-Z]} g}
+    foo
+} 0
+test stringComp-11.38 {string match case, reverse range} {
+    proc foo {} {string match {[A-fh-Z]} g}
+    foo
+} 1
+test stringComp-11.39 {string match, *\ case} {
+    proc foo {} {string match {*\abc} abc}
+    foo
+} 1
+test stringComp-11.40 {string match, *special case} {
+    proc foo {} {string match {*[ab]} abc}
+    foo
+} 0
+test stringComp-11.41 {string match, *special case} {
+    proc foo {} {string match {*[ab]*} abc}
+    foo
+} 1
+test stringComp-11.42 {string match, *special case} {
+    proc foo {} {string match "*\\" "\\"}
+    foo
+} 0
+test stringComp-11.43 {string match, *special case} {
+    proc foo {} {string match "*\\\\" "\\"}
+    foo
+} 1
+test stringComp-11.44 {string match, *special case} {
+    proc foo {} {string match "*???" "12345"}
+    foo
+} 1
+test stringComp-11.45 {string match, *special case} {
+    proc foo {} {string match "*???" "12"}
+    foo
+} 0
+test stringComp-11.46 {string match, *special case} {
+    proc foo {} {string match "*\\*" "abc*"}
+    foo
+} 1
+test stringComp-11.47 {string match, *special case} {
+    proc foo {} {string match "*\\*" "*"}
+    foo
+} 1
+test stringComp-11.48 {string match, *special case} {
+    proc foo {} {string match "*\\*" "*abc"}
+    foo
+} 0
+test stringComp-11.49 {string match, *special case} {
+    proc foo {} {string match "?\\*" "a*"}
+    foo
+} 1
+test stringComp-11.50 {string match, *special case} {
+    proc foo {} {string match "\\" "\\"}
+    foo
+} 0
+test stringComp-11.51 {string match; *, -nocase and UTF-8} {
+    proc foo {} {string match -nocase [binary format I 717316707] \
+	    [binary format I 2028036707]}
+    foo
+} 1
+test stringComp-11.52 {string match, null char in string} {
+    proc foo {} {
+	set ptn "*abc*"
+	foreach elem [list "\u0000@abc" "@abc" "\u0000@abc\u0000" "blahabcblah"] {
+	    lappend out [string match $ptn $elem]
+	}
+	set out
+    }
+    foo
+} {1 1 1 1}
+test stringComp-11.53 {string match, null char in pattern} {
+    proc foo {} {
+	set out ""
+	foreach {ptn elem} [list \
+		"*\u0000abc\u0000"  "\u0000abc\u0000" \
+		"*\u0000abc\u0000"  "\u0000abc\u0000ef" \
+		"*\u0000abc\u0000*" "\u0000abc\u0000ef" \
+		"*\u0000abc\u0000"  "@\u0000abc\u0000ef" \
+		"*\u0000abc\u0000*"  "@\u0000abc\u0000ef" \
+		] {
+	    lappend out [string match $ptn $elem]
+	}
+	set out
+    }
+    foo
+} {1 0 1 0 1}
+test stringComp-11.54 {string match, failure} {
+    proc foo {} {
+	set longString ""
+	for {set i 0} {$i < 10} {incr i} {
+	    append longString "abcdefghijklmnopqrstuvwxy\u0000z01234567890123"
+	}
+	list [string match *cba* $longString] \
+		[string match *a*l*\u0000* $longString] \
+		[string match *a*l*\u0000*123 $longString] \
+		[string match *a*l*\u0000*123* $longString] \
+		[string match *a*l*\u0000*cba* $longString] \
+		[string match *===* $longString]
+    }
+    foo
+} {0 1 1 1 0 0}
+
+## string range
+test stringComp-12.1 {Bug 3588366: end-offsets before start} {
+    apply {s {
+	string range $s 0 end-5
+    }} 12345
+} {}
+
+## string repeat
+## not yet bc
+
+## string replace
+test stringComp-14.1 {Bug 82e7f67325} {
+    apply {x {
+	set a [join $x {}]
+	lappend b [string length [string replace ___! 0 2 $a]]
+	lappend b [string length [string replace ___! 0 2 $a[unset a]]]
+    }} {a b}
+} {3 3}
+test stringComp-14.2 {Bug 82e7f67325} memory {
+    # As in stringComp-14.1, but make sure we don't retain too many refs
+    leaktest {
+	apply {x {
+	    set a [join $x {}]
+	    lappend b [string length [string replace ___! 0 2 $a]]
+	    lappend b [string length [string replace ___! 0 2 $a[unset a]]]
+	}} {a b}
+    }
+} {0}
+test stringComp-14.3 {Bug 0dca3bfa8f} {
+    apply {arg {
+	set argCopy $arg
+	set arg [string replace $arg 1 2 aa]
+	# Crashes in comparison before fix
+	expr {$arg ne $argCopy}
+    }} abcde
+} 1
+test stringComp-14.4 {Bug 1af8de570511} {
+    apply {{x y} {
+	# Generate an unshared string value
+	set val ""
+	for { set i 0 } { $i < $x } { incr i } {
+	    set val [format "0%s" $val]
+	}
+	string replace $val[unset val] 1 1 $y
+    }} 4 x
+} 0x00
+
+## string tolower
+## not yet bc
+
+## string toupper
+## not yet bc
+
+## string totitle
+## not yet bc
+
+## string trim*
+## not yet bc
+
+## string word*
+## not yet bc
+
+## string cat
+test stringComp-29.1 {string cat, no arg} {
+    proc foo {} {string cat}
+    foo
+} ""
+test stringComp-29.2 {string cat, single arg} {
+    proc foo {} {
+	set x FOO
+	string compare $x [string cat $x]
+    }
+    foo
+} 0
+test stringComp-29.3 {string cat, two args} {
+    proc foo {} {
+	set x FOO
+	string compare $x$x [string cat $x $x]
+    }
+    foo
+} 0
+test stringComp-29.4 {string cat, many args} {
+    proc foo {} {
+	set x FOO
+	set n 260
+	set xx [string repeat $x $n]
+	set vv [string repeat {$x} $n]
+	set vvs [string repeat {$x } $n]
+	set r1 [string compare $xx [subst $vv]]
+	set r2 [string compare $xx [eval "string cat $vvs"]]
+	list $r1 $r2
+    }
+    foo
+} {0 0}
+
+
+# cleanup
+catch {rename foo {}}
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/tests/stringObj.test b/tests/stringObj.test
new file mode 100644
index 0000000..8209142
--- /dev/null
+++ b/tests/stringObj.test
@@ -0,0 +1,491 @@
+# Commands covered: none
+#
+# This file contains tests for the procedures in tclStringObj.c that implement
+# the Tcl type manager for the string type.
+#
+# Sourcing this file into Tcl runs the tests and generates output for errors.
+# No output means no errors were found.
+#
+# Copyright (c) 1995-1997 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution of
+# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+    package require tcltest
+    namespace import -force ::tcltest::*
+}
+
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
+
+testConstraint testobj [llength [info commands testobj]]
+testConstraint testbytestring [llength [info commands testbytestring]]
+testConstraint testdstring [llength [info commands testdstring]]
+
+test stringObj-1.1 {string type registration} testobj {
+    set t [testobj types]
+    set first [string first "string" $t]
+    set result [expr {$first != -1}]
+} {1}
+
+test stringObj-2.1 {Tcl_NewStringObj} testobj {
+    set result ""
+    lappend result [testobj freeallvars]
+    lappend result [teststringobj set 1 abcd]
+    lappend result [testobj type 1]
+    lappend result [testobj refcount 1]
+} {{} abcd string 2}
+
+test stringObj-3.1 {Tcl_SetStringObj, existing "empty string" object} testobj {
+    set result ""
+    lappend result [testobj freeallvars]
+    lappend result [testobj newobj 1]
+    lappend result [teststringobj set 1 xyz]	;# makes existing obj a string
+    lappend result [testobj type 1]
+    lappend result [testobj refcount 1]
+} {{} {} xyz string 2}
+test stringObj-3.2 {Tcl_SetStringObj, existing non-"empty string" object} testobj {
+    set result ""
+    lappend result [testobj freeallvars]
+    lappend result [testintobj set 1 512]
+    lappend result [teststringobj set 1 foo]	;# makes existing obj a string
+    lappend result [testobj type 1]
+    lappend result [testobj refcount 1]
+} {{} 512 foo string 2}
+
+test stringObj-4.1 {Tcl_SetObjLength procedure, string gets shorter} testobj {
+    testobj freeallvars
+    teststringobj set 1 test
+    teststringobj setlength 1 3
+    list [teststringobj length 1] [teststringobj length2 1] \
+	    [teststringobj get 1]
+} {3 4 tes}
+test stringObj-4.2 {Tcl_SetObjLength procedure, string gets longer} testobj {
+    testobj freeallvars
+    teststringobj set 1 abcdef
+    teststringobj setlength 1 10
+    list [teststringobj length 1] [teststringobj length2 1]
+} {10 10}
+test stringObj-4.3 {Tcl_SetObjLength procedure, string gets longer} testobj {
+    testobj freeallvars
+    teststringobj set 1 abcdef
+    teststringobj append 1 xyzq -1
+    list [teststringobj length 1] [teststringobj length2 1] \
+	    [teststringobj get 1]
+} {10 20 abcdefxyzq}
+test stringObj-4.4 {Tcl_SetObjLength procedure, "expty string", length 0} testobj {
+    testobj freeallvars
+    testobj newobj 1
+    teststringobj setlength 1 0
+    list [teststringobj length2 1] [teststringobj get 1]
+} {0 {}}
+
+test stringObj-5.1 {Tcl_AppendToObj procedure, type conversion} testobj {
+    testobj freeallvars
+    testintobj set2 1 43
+    teststringobj append 1 xyz -1
+    teststringobj get 1
+} {43xyz}
+test stringObj-5.2 {Tcl_AppendToObj procedure, length calculation} testobj {
+    testobj freeallvars
+    teststringobj set 1 {x y }
+    teststringobj append 1 bbCCddEE 4
+    teststringobj append 1 123 -1
+    teststringobj get 1
+} {x y bbCC123}
+test stringObj-5.3 {Tcl_AppendToObj procedure, reallocating space} testobj {
+    testobj freeallvars
+    teststringobj set 1 xyz
+    teststringobj setlength 1 15
+    teststringobj setlength 1 2
+    set result {}
+    teststringobj append 1 1234567890123 -1
+    lappend result [teststringobj length 1] [teststringobj length2 1]
+    teststringobj setlength 1 10
+    teststringobj append 1 abcdef -1
+    lappend result [teststringobj length 1] [teststringobj length2 1] \
+	    [teststringobj get 1]
+} {15 15 16 32 xy12345678abcdef}
+
+test stringObj-6.1 {Tcl_AppendStringsToObj procedure, type conversion} testobj {
+    testobj freeallvars
+    teststringobj set2 1 [list a b]
+    teststringobj appendstrings 1 xyz { 1234 } foo
+    teststringobj get 1
+} {a bxyz 1234 foo}
+test stringObj-6.2 {Tcl_AppendStringsToObj procedure, counting space} testobj {
+    testobj freeallvars
+    teststringobj set 1 abc
+    teststringobj appendstrings 1
+    list [teststringobj length 1] [teststringobj get 1]
+} {3 abc}
+test stringObj-6.3 {Tcl_AppendStringsToObj procedure, counting space} testobj {
+    testobj freeallvars
+    teststringobj set 1 abc
+    teststringobj appendstrings 1 {} {} {} {}
+    list [teststringobj length 1] [teststringobj get 1]
+} {3 abc}
+test stringObj-6.4 {Tcl_AppendStringsToObj procedure, counting space} testobj {
+    testobj freeallvars
+    teststringobj set 1 abc
+    teststringobj appendstrings 1 { 123 } abcdefg
+    list [teststringobj length 1] [teststringobj get 1]
+} {15 {abc 123 abcdefg}}
+test stringObj-6.5 {Tcl_AppendStringsToObj procedure, don't double space if initial string empty} testobj {
+    testobj freeallvars
+    testobj newobj 1
+    teststringobj appendstrings 1 123 abcdefg
+    list [teststringobj length 1] [teststringobj length2 1] [teststringobj get 1]
+} {10 20 123abcdefg}
+test stringObj-6.6 {Tcl_AppendStringsToObj procedure, space reallocation} testobj {
+    testobj freeallvars
+    teststringobj set 1 abc
+    teststringobj setlength 1 10
+    teststringobj setlength 1 2
+    teststringobj appendstrings 1 34567890
+    list [teststringobj length 1] [teststringobj length2 1] \
+	    [teststringobj get 1]
+} {10 10 ab34567890}
+test stringObj-6.7 {Tcl_AppendStringsToObj procedure, space reallocation} testobj {
+    testobj freeallvars
+    teststringobj set 1 abc
+    teststringobj setlength 1 10
+    teststringobj setlength 1 2
+    teststringobj appendstrings 1 34567890x
+    list [teststringobj length 1] [teststringobj length2 1] \
+	    [teststringobj get 1]
+} {11 22 ab34567890x}
+test stringObj-6.8 {Tcl_AppendStringsToObj procedure, object totally empty} testobj {
+    testobj freeallvars
+    testobj newobj 1
+    teststringobj appendstrings 1 {}
+    list [teststringobj length2 1] [teststringobj get 1]
+} {0 {}}
+test stringObj-6.9 {Tcl_AppendStringToObj, pure unicode} testobj {
+    testobj freeallvars
+    teststringobj set2 1 [string replace abc 1 1 d]
+    teststringobj appendstrings 1 foo bar soom
+    teststringobj get 1
+} adcfoobarsoom
+
+test stringObj-7.1 {SetStringFromAny procedure} testobj {
+    testobj freeallvars
+    teststringobj set2 1 [list a b]
+    teststringobj append 1 x -1
+    list [teststringobj length 1] [teststringobj length2 1] \
+	    [teststringobj get 1]
+} {4 8 {a bx}}
+test stringObj-7.2 {SetStringFromAny procedure, null object} testobj {
+    testobj freeallvars
+    testobj newobj 1
+    teststringobj appendstrings 1 {}
+    list [teststringobj length 1] [teststringobj length2 1] \
+	    [teststringobj get 1]
+} {0 0 {}}
+test stringObj-7.3 {SetStringFromAny called with non-string obj} testobj {
+    set x 2345
+    list [incr x] [testobj objtype $x] [string index $x end] \
+	    [testobj objtype $x]
+} {2346 int 6 string}
+test stringObj-7.4 {SetStringFromAny called with string obj} testobj {
+    set x "abcdef"
+    list [string length $x] [testobj objtype $x] \
+	    [string length $x] [testobj objtype $x]
+} {6 string 6 string}
+
+test stringObj-8.1 {DupStringInternalRep procedure} testobj {
+    testobj freeallvars
+    teststringobj set 1 {}
+    teststringobj append 1 abcde -1
+    testobj duplicate 1 2
+    list [teststringobj length 1] [teststringobj length2 1] \
+	    [teststringobj maxchars 1] [teststringobj get 1] \
+	    [teststringobj length 2] [teststringobj length2 2] \
+	    [teststringobj maxchars 2] [teststringobj get 2]
+} {5 10 0 abcde 5 5 0 abcde}
+test stringObj-8.2 {DupUnicodeInternalRep, mixed width chars} testobj {
+    set x abc\u00ef\u00bf\u00aeghi
+    string length $x
+    set y $x
+    list [testobj objtype $x] [testobj objtype $y] [append x "\u00ae\u00bf\u00ef"] \
+	    [set y] [testobj objtype $x] [testobj objtype $y]
+} "string string abc\u00ef\u00bf\u00aeghi\u00ae\u00bf\u00ef abc\u00ef\u00bf\u00aeghi string string"
+test stringObj-8.3 {DupUnicodeInternalRep, mixed width chars} testobj {
+    set x abc\u00ef\u00bf\u00aeghi
+    set y $x
+    string length $x
+    list [testobj objtype $x] [testobj objtype $y] [append x "\u00ae\u00bf\u00ef"] \
+	    [set y] [testobj objtype $x] [testobj objtype $y]
+} "string string abc\u00ef\u00bf\u00aeghi\u00ae\u00bf\u00ef abc\u00ef\u00bf\u00aeghi string string"
+test stringObj-8.4 {DupUnicodeInternalRep, all byte-size chars} testobj {
+    set x abcdefghi
+    string length $x
+    set y $x
+    list [testobj objtype $x] [testobj objtype $y] [append x jkl] \
+	    [set y] [testobj objtype $x] [testobj objtype $y]
+} {string string abcdefghijkl abcdefghi string string}
+test stringObj-8.5 {DupUnicodeInternalRep, all byte-size chars} testobj {
+    set x abcdefghi
+    set y $x
+    string length $x
+    list [testobj objtype $x] [testobj objtype $y] [append x jkl] \
+	    [set y] [testobj objtype $x] [testobj objtype $y]
+} {string string abcdefghijkl abcdefghi string string}
+
+test stringObj-9.1 {TclAppendObjToObj, mixed src & dest} {testobj testdstring} {
+    set x abc\u00ef\u00bf\u00aeghi
+    testdstring free
+    testdstring append \u00ae\u00bf\u00ef -1
+    set y [testdstring get]
+    string length $x
+    list [testobj objtype $x] [testobj objtype $y] [append x $y] \
+	    [set y] [testobj objtype $x] [testobj objtype $y]
+} "string none abc\u00ef\u00bf\u00aeghi\u00ae\u00bf\u00ef \u00ae\u00bf\u00ef string none"
+test stringObj-9.2 {TclAppendObjToObj, mixed src & dest} testobj {
+    set x abc\u00ef\u00bf\u00aeghi
+    string length $x
+    list [testobj objtype $x] [append x $x] [testobj objtype $x] \
+	    [append x $x] [testobj objtype $x]
+} "string abc\u00ef\u00bf\u00aeghiabc\u00ef\u00bf\u00aeghi string\
+abc\u00ef\u00bf\u00aeghiabc\u00ef\u00bf\u00aeghiabc\u00ef\u00bf\u00aeghiabc\u00ef\u00bf\u00aeghi\
+string"
+test stringObj-9.3 {TclAppendObjToObj, mixed src & 1-byte dest} {testobj testdstring} {
+    set x abcdefghi
+    testdstring free
+    testdstring append \u00ae\u00bf\u00ef -1
+    set y [testdstring get]
+    string length $x
+    list [testobj objtype $x] [testobj objtype $y] [append x $y] \
+	    [set y] [testobj objtype $x] [testobj objtype $y]
+} "string none abcdefghi\u00ae\u00bf\u00ef \u00ae\u00bf\u00ef string none"
+test stringObj-9.4 {TclAppendObjToObj, 1-byte src & dest} {testobj testdstring} {
+    set x abcdefghi
+    testdstring free
+    testdstring append jkl -1
+    set y [testdstring get]
+    string length $x
+    list [testobj objtype $x] [testobj objtype $y] [append x $y] \
+	    [set y] [testobj objtype $x] [testobj objtype $y]
+} {string none abcdefghijkl jkl string none}
+test stringObj-9.5 {TclAppendObjToObj, 1-byte src & dest} testobj {
+    set x abcdefghi
+    string length $x
+    list [testobj objtype $x] [append x $x] [testobj objtype $x] \
+	    [append x $x] [testobj objtype $x]
+} {string abcdefghiabcdefghi string abcdefghiabcdefghiabcdefghiabcdefghi\
+string}
+test stringObj-9.6 {TclAppendObjToObj, 1-byte src & mixed dest} {testobj testdstring} {
+    set x abc\u00ef\u00bf\u00aeghi
+    testdstring free
+    testdstring append jkl -1
+    set y [testdstring get]
+    string length $x
+    list [testobj objtype $x] [testobj objtype $y] [append x $y] \
+	    [set y] [testobj objtype $x] [testobj objtype $y]
+} "string none abc\u00ef\u00bf\u00aeghijkl jkl string none"
+test stringObj-9.7 {TclAppendObjToObj, integer src & dest} testobj {
+    set x [expr {4 * 5}]
+    set y [expr {4 + 5}]
+    list [testobj objtype $x] [testobj objtype $y] [append x $y] \
+	    [testobj objtype $x] [append x $y] [testobj objtype $x] \
+	    [testobj objtype $y]
+} {int int 209 string 2099 string int}
+test stringObj-9.8 {TclAppendObjToObj, integer src & dest} testobj {
+    set x [expr {4 * 5}]
+    list [testobj objtype $x] [append x $x] [testobj objtype $x] \
+	    [append x $x] [testobj objtype $x]
+} {int 2020 string 20202020 string}
+test stringObj-9.9 {TclAppendObjToObj, integer src & 1-byte dest} testobj {
+    set x abcdefghi
+    set y [expr {4 + 5}]
+    string length $x
+    list [testobj objtype $x] [testobj objtype $y] [append x $y] \
+	    [set y] [testobj objtype $x] [testobj objtype $y]
+} {string int abcdefghi9 9 string int}
+test stringObj-9.10 {TclAppendObjToObj, integer src & mixed dest} testobj {
+    set x abc\u00ef\u00bf\u00aeghi
+    set y [expr {4 + 5}]
+    string length $x
+    list [testobj objtype $x] [testobj objtype $y] [append x $y] \
+	    [set y] [testobj objtype $x] [testobj objtype $y]
+} "string int abc\u00ef\u00bf\u00aeghi9 9 string int"
+test stringObj-9.11 {TclAppendObjToObj, mixed src & 1-byte dest index check} testobj {
+    # bug 2678, in <=8.2.0, the second obj (the one to append) in
+    # Tcl_AppendObjToObj was not correctly checked to see if it was all one
+    # byte chars, so a unicode string would be added as one byte chars.
+    set x abcdef
+    set len [string length $x]
+    set y a\u00fcb\u00e5c\u00ef
+    set len [string length $y]
+    append x $y
+    string length $x
+    set q {}
+    for {set i 0} {$i < 12} {incr i} {
+	lappend q [string index $x $i]
+    }
+    set q
+} "a b c d e f a \u00fc b \u00e5 c \u00ef"
+
+test stringObj-10.1 {Tcl_GetRange with all byte-size chars} {testobj testdstring} {
+    testdstring free
+    testdstring append abcdef -1
+    set x [testdstring get]
+    list [testobj objtype $x] [set y [string range $x 1 end-1]] \
+	    [testobj objtype $x] [testobj objtype $y]
+} [list none bcde string string]
+test stringObj-10.2 {Tcl_GetRange with some mixed width chars} {testobj testdstring} {
+    # Because this test does not use \uXXXX notation below instead of
+    # hardcoding the values, it may fail in multibyte locales. However, we
+    # need to test that the parser produces untyped objects even when there
+    # are high-ASCII characters in the input (like "ï"). I don't know what
+    # else to do but inline those characters here.
+    testdstring free
+    testdstring append "abc\u00ef\u00efdef" -1
+    set x [testdstring get]
+    list [testobj objtype $x] [set y [string range $x 1 end-1]] \
+	    [testobj objtype $x] [testobj objtype $y]
+} [list none "bc\u00EF\u00EFde" string string]
+test stringObj-10.3 {Tcl_GetRange with some mixed width chars} testobj {
+    # set x "abcïïdef"
+    # Use \uXXXX notation below instead of hardcoding the values, otherwise
+    # the test will fail in multibyte locales.
+    set x "abc\u00EF\u00EFdef"
+    string length $x
+    list [testobj objtype $x] [set y [string range $x 1 end-1]] \
+	    [testobj objtype $x] [testobj objtype $y]
+} [list string "bc\u00EF\u00EFde" string string]
+test stringObj-10.4 {Tcl_GetRange with some mixed width chars} testobj {
+    # set a "ïa¿b®cï¿d®"
+    # Use \uXXXX notation below instead of hardcoding the values, otherwise
+    # the test will fail in multibyte locales.
+    set a "\u00EFa\u00BFb\u00AEc\u00EF\u00BFd\u00AE"
+    set result [list]
+    while {[string length $a] > 0} {
+	set a [string range $a 1 end-1]
+	lappend result $a
+    }
+    set result
+} [list a\u00BFb\u00AEc\u00EF\u00BFd	\
+	\u00BFb\u00AEc\u00EF\u00BF	\
+	b\u00AEc\u00EF			\
+	\u00AEc				\
+	{}]
+
+test stringObj-11.1 {UpdateStringOfString} testobj {
+    set x 2345
+    list [string index $x end] [testobj objtype $x] [incr x] \
+	    [testobj objtype $x]
+} {5 string 2346 int}
+
+test stringObj-12.1 {Tcl_GetUniChar with byte-size chars} testobj {
+    set x "abcdefghi"
+    list [string index $x 0] [string index $x 1]
+} {a b}
+test stringObj-12.2 {Tcl_GetUniChar with byte-size chars} testobj {
+    set x "abcdefghi"
+    list [string index $x 3] [string index $x end]
+} {d i}
+test stringObj-12.3 {Tcl_GetUniChar with byte-size chars} testobj {
+    set x "abcdefghi"
+    list [string index $x end] [string index $x end-1]
+} {i h}
+test stringObj-12.4 {Tcl_GetUniChar with mixed width chars} testobj {
+    string index "\u00efa\u00bfb\u00aec\u00ae\u00bfd\u00ef" 0
+} "\u00ef"
+test stringObj-12.5 {Tcl_GetUniChar} testobj {
+    set x "\u00efa\u00bfb\u00aec\u00ae\u00bfd\u00ef"
+    list [string index $x 4] [string index $x 0]
+} "\u00ae \u00ef"
+test stringObj-12.6 {Tcl_GetUniChar} testobj {
+    string index "\u00efa\u00bfb\u00aec\u00ef\u00bfd\u00ae" end
+} "\u00ae"
+
+test stringObj-13.1 {Tcl_GetCharLength with byte-size chars} testobj {
+    set a ""
+    list [string length $a] [string length $a]
+} {0 0}
+test stringObj-13.2 {Tcl_GetCharLength with byte-size chars} testobj {
+    string length "a"
+} 1
+test stringObj-13.3 {Tcl_GetCharLength with byte-size chars} testobj {
+    set a "abcdef"
+    list [string length $a] [string length $a]
+} {6 6}
+test stringObj-13.4 {Tcl_GetCharLength with mixed width chars} testobj {
+    string length "\u00ae" 
+} 1
+test stringObj-13.5 {Tcl_GetCharLength with mixed width chars} testobj {
+    # string length "ï¿®ï¿®" 
+    # Use \uXXXX notation below instead of hardcoding the values, otherwise
+    # the test will fail in multibyte locales.
+    string length "\u00EF\u00BF\u00AE\u00EF\u00BF\u00AE"
+} 6
+test stringObj-13.6 {Tcl_GetCharLength with mixed width chars} testobj {
+    # set a "ïa¿b®cï¿d®"
+    # Use \uXXXX notation below instead of hardcoding the values, otherwise
+    # the test will fail in multibyte locales.
+    set a "\u00EFa\u00BFb\u00AEc\u00EF\u00BFd\u00AE"
+    list [string length $a] [string length $a]
+} {10 10}
+test stringObj-13.7 {Tcl_GetCharLength with identity nulls} {testobj testbytestring} {
+    # SF bug #684699
+    string length [testbytestring \x00]
+} 1
+test stringObj-13.8 {Tcl_GetCharLength with identity nulls} {testobj testbytestring} {
+    string length [testbytestring \x01\x00\x02]
+} 3
+
+test stringObj-14.1 {Tcl_SetObjLength on pure unicode object} testobj {
+    teststringobj set 1 foo
+    teststringobj getunicode 1
+    teststringobj append 1 bar -1
+    teststringobj getunicode 1
+    teststringobj append 1 bar -1
+    teststringobj setlength 1 0
+    teststringobj append 1 bar -1
+    teststringobj get 1
+} {bar}
+
+test stringObj-15.1 {Tcl_Append*ToObj: self appends} testobj {
+    teststringobj set 1 foo
+    teststringobj appendself 1 0
+} foofoo
+test stringObj-15.2 {Tcl_Append*ToObj: self appends} testobj {
+    teststringobj set 1 foo
+    teststringobj appendself 1 1
+} foooo
+test stringObj-15.3 {Tcl_Append*ToObj: self appends} testobj {
+    teststringobj set 1 foo
+    teststringobj appendself 1 2
+} fooo
+test stringObj-15.4 {Tcl_Append*ToObj: self appends} testobj {
+    teststringobj set 1 foo
+    teststringobj appendself 1 3
+} foo
+test stringObj-15.5 {Tcl_Append*ToObj: self appends} testobj {
+    teststringobj set 1 foo
+    teststringobj appendself2 1 0
+} foofoo
+test stringObj-15.6 {Tcl_Append*ToObj: self appends} testobj {
+    teststringobj set 1 foo
+    teststringobj appendself2 1 1
+} foooo
+test stringObj-15.7 {Tcl_Append*ToObj: self appends} testobj {
+    teststringobj set 1 foo
+    teststringobj appendself2 1 2
+} fooo
+test stringObj-15.8 {Tcl_Append*ToObj: self appends} testobj {
+    teststringobj set 1 foo
+    teststringobj appendself2 1 3
+} foo
+
+
+if {[testConstraint testobj]} {
+    testobj freeallvars
+}
+
+# cleanup
+::tcltest::cleanupTests
+return
diff --git a/tests/subst.test b/tests/subst.test
new file mode 100644
index 0000000..2115772
--- /dev/null
+++ b/tests/subst.test
@@ -0,0 +1,311 @@
+# Commands covered:  subst
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands.  Sourcing this file into Tcl runs the tests and
+# generates output for errors.  No output means no errors were found.
+#
+# Copyright (c) 1994 The Regents of the University of California.
+# Copyright (c) 1994 Sun Microsystems, Inc.
+# Copyright (c) 1998-2000 Ajuba Solutions.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+    package require tcltest 2.1
+    namespace import -force ::tcltest::*
+}
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
+
+testConstraint testbytestring [llength [info commands testbytestring]]
+
+test subst-1.1 {basics} -returnCodes error -body {
+    subst
+} -result {wrong # args: should be "subst ?-nobackslashes? ?-nocommands? ?-novariables? string"}
+test subst-1.2 {basics} -returnCodes error -body {
+    subst a b c
+} -result {bad option "a": must be -nobackslashes, -nocommands, or -novariables}
+
+test subst-2.1 {simple strings} {
+    subst {}
+} {}
+test subst-2.2 {simple strings} {
+    subst a
+} a
+test subst-2.3 {simple strings} {
+    subst abcdefg
+} abcdefg
+test subst-2.4 {simple strings} testbytestring {
+    # Tcl Bug 685106
+    expr {[subst [testbytestring bar\x00soom]] eq [testbytestring bar\x00soom]}
+} 1
+
+test subst-3.1 {backslash substitutions} {
+    subst {\x\$x\[foo bar]\\}
+} "x\$x\[foo bar]\\"
+test subst-3.2 {backslash substitutions with utf chars} {
+    # 'j' is just a char that doesn't mean anything, and \344 is 'ä'
+    # that also doesn't mean anything, but is multi-byte in UTF-8.
+    list [subst \j] [subst \\j] [subst \\344] [subst \\\344]
+} "j j \344 \344"
+
+test subst-4.1 {variable substitutions} {
+    set a 44
+    subst {$a}
+} {44}
+test subst-4.2 {variable substitutions} {
+    set a 44
+    subst {x$a.y{$a}.z}
+} {x44.y{44}.z}
+test subst-4.3 {variable substitutions} -setup {
+    catch {unset a}
+} -body {
+    set a(13) 82
+    set i 13
+    subst {x.$a($i)}
+} -result {x.82}
+catch {unset a}
+set long {This is a very long string, intentionally made so long that it
+	will overflow the static character size for dstrings, so that
+	additional memory will have to be allocated by subst.  That way,
+	if the subst procedure forgets to free up memory while returning
+	an error, there will be memory that isn't freed (this will be
+	detected when the tests are run under a checking memory allocator
+	such as Purify).}
+test subst-4.4 {variable substitutions} -returnCodes error -body {
+    subst {$long $a}
+} -result {can't read "a": no such variable}
+
+test subst-5.1 {command substitutions} {
+    subst {[concat {}]}
+} {}
+test subst-5.2 {command substitutions} {
+    subst {[concat A test string]}
+} {A test string}
+test subst-5.3 {command substitutions} {
+    subst {x.[concat foo].y.[concat bar].z}
+} {x.foo.y.bar.z}
+test subst-5.4 {command substitutions} {
+    list [catch {subst {$long [set long] [bogus_command]}} msg] $msg
+} {1 {invalid command name "bogus_command"}}
+test subst-5.5 {command substitutions} {
+    set a 0
+    list [catch {subst {[set a 1}} msg] $a $msg 
+} {1 0 {missing close-bracket}}
+test subst-5.6 {command substitutions} {
+    set a 0
+    list [catch {subst {0[set a 1}} msg] $a $msg 
+} {1 0 {missing close-bracket}}
+test subst-5.7 {command substitutions} {
+    set a 0
+    list [catch {subst {0[set a 1; set a 2}} msg] $a $msg 
+} {1 1 {missing close-bracket}}
+
+# repeat the tests above simulating cmd line input
+test subst-5.8 {command substitutions} {
+    set script {[subst {[set a 1}]}
+    list [catch {exec [info nameofexecutable] << $script} msg] $msg 
+} {1 {missing close-bracket}}
+test subst-5.9 {command substitutions} {
+    set script {[subst {0[set a 1}]}
+    list [catch {exec [info nameofexecutable] << $script} msg] $msg 
+} {1 {missing close-bracket}}
+test subst-5.10 {command substitutions} {
+    set script {[subst {0[set a 1; set a 2}]}
+    list [catch {exec [info nameofexecutable] << $script} msg] $msg 
+} {1 {missing close-bracket}}
+
+test subst-6.1 {clear the result after command substitution} -body {
+    catch {unset a}
+    subst {[concat foo] $a}
+} -returnCodes error -result {can't read "a": no such variable}
+
+test subst-7.1 {switches} -returnCodes error -body {
+    subst foo bar
+} -result {bad option "foo": must be -nobackslashes, -nocommands, or -novariables}
+test subst-7.2 {switches} -returnCodes error -body {
+    subst -no bar
+} -result {ambiguous option "-no": must be -nobackslashes, -nocommands, or -novariables}
+test subst-7.3 {switches} -returnCodes error -body {
+    subst -bogus bar
+} -result {bad option "-bogus": must be -nobackslashes, -nocommands, or -novariables}
+test subst-7.4 {switches} {
+    set x 123
+    subst -nobackslashes {abc $x [expr 1+2] \\\x41}
+} {abc 123 3 \\\x41}
+test subst-7.5 {switches} {
+    set x 123
+    subst -nocommands {abc $x [expr 1+2] \\\x41}
+} {abc 123 [expr 1+2] \A}
+test subst-7.6 {switches} {
+    set x 123
+    subst -novariables {abc $x [expr 1+2] \\\x41}
+} {abc $x 3 \A}
+test subst-7.7 {switches} {
+    set x 123
+    subst -nov -nob -noc {abc $x [expr 1+2] \\\x41}
+} {abc $x [expr 1+2] \\\x41}
+
+test subst-8.1 {return in a subst} {
+    subst {foo [return {x}; bogus code] bar}
+} {foo x bar}
+test subst-8.2 {return in a subst} {
+    subst {foo [return x ; bogus code] bar}
+} {foo x bar}
+test subst-8.3 {return in a subst} {
+    subst {foo [if 1 { return {x}; bogus code }] bar}
+} {foo x bar}
+test subst-8.4 {return in a subst} {
+    subst {[eval {return hi}] there}
+} {hi there}
+test subst-8.5 {return in a subst} {
+    subst {foo [return {]}; bogus code] bar}
+} {foo ] bar}
+test subst-8.6 {return in a subst} -returnCodes error -body {
+    subst "foo \[return {x}; bogus code bar"
+} -result {missing close-bracket}
+test subst-8.7 {return in a subst, parse error} -body {
+    subst {foo [return {x} ; set a {}"" ; stuff] bar} 
+} -returnCodes error -result {extra characters after close-brace}
+test subst-8.8 {return in a subst, parse error} -body {
+    subst {foo [return {x} ; set bar baz ; set a {}"" ; stuff] bar}
+} -returnCodes error -result {extra characters after close-brace}
+test subst-8.9 {return in a variable subst} {
+    subst {foo $var([return {x}]) bar}
+} {foo x bar}
+
+test subst-9.1 {error in a subst} -body {
+    subst {[error foo; bogus code]bar}
+} -returnCodes error -result foo
+test subst-9.2 {error in a subst} -body {
+    subst {[if 1 { error foo; bogus code}]bar}
+} -returnCodes error -result foo
+test subst-9.3 {error in a variable subst} -setup {
+    catch {unset var}
+} -body {
+    subst {foo $var([error foo]) bar}
+} -returnCodes error -result foo
+
+test subst-10.1 {break in a subst} {
+    subst {foo [break; bogus code] bar}
+} {foo }
+test subst-10.2 {break in a subst} {
+    subst {foo [break; return x; bogus code] bar}
+} {foo }
+test subst-10.3 {break in a subst} {
+    subst {foo [if 1 { break; bogus code}] bar}
+} {foo }
+test subst-10.4 {break in a subst, parse error} {
+    subst {foo [break ; set a {}{} ; stuff] bar}
+} {foo }
+test subst-10.5 {break in a subst, parse error} {
+    subst {foo [break ;set bar baz ;set a {}{} ; stuff] bar}
+} {foo }
+test subst-10.6 {break in a variable subst} {
+    subst {foo $var([break]) bar}
+} {foo }
+
+test subst-11.1 {continue in a subst} {
+    subst {foo [continue; bogus code] bar}
+} {foo  bar}
+test subst-11.2 {continue in a subst} {
+    subst {foo [continue; return x; bogus code] bar}
+} {foo  bar}
+test subst-11.3 {continue in a subst} {
+    subst {foo [if 1 { continue; bogus code}] bar}
+} {foo  bar}
+test subst-11.4 {continue in a subst, parse error} -body {
+    subst {foo [continue ; set a {}{} ; stuff] bar}
+} -returnCodes error -result {extra characters after close-brace}
+test subst-11.5 {continue in a subst, parse error} -body {
+    subst {foo [continue ;set bar baz ;set a {}{} ; stuff] bar}
+} -returnCodes error -result {extra characters after close-brace}
+test subst-11.6 {continue in a variable subst} {
+    subst {foo $var([continue]) bar}
+} {foo  bar}
+
+test subst-12.1 {nasty case, Bug 1036649} {
+    for {set i 0} {$i < 10} {incr i} {
+	set res [list [catch {subst "\[subst {};"} msg] $msg]
+	if {$msg ne "missing close-bracket"} break
+    }
+    return $res
+} {1 {missing close-bracket}}
+test subst-12.2 {nasty case, Bug 1036649} {
+    for {set i 0} {$i < 10} {incr i} {
+	set res [list [catch {subst "\[subst {}; "} msg] $msg]
+	if {$msg ne "missing close-bracket"} break
+    }
+    return $res
+} {1 {missing close-bracket}}
+test subst-12.3 {nasty case, Bug 1036649} {
+    set x 0
+    for {set i 0} {$i < 10} {incr i} {
+	set res [list [catch {subst "\[incr x;"} msg] $msg]
+	if {$msg ne "missing close-bracket"} break
+    }
+    lappend res $x
+} {1 {missing close-bracket} 10}
+test subst-12.4 {nasty case, Bug 1036649} {
+    set x 0
+    for {set i 0} {$i < 10} {incr i} {
+	set res [list [catch {subst "\[incr x; "} msg] $msg]
+	if {$msg ne "missing close-bracket"} break
+    }
+    lappend res $x
+} {1 {missing close-bracket} 10}
+test subst-12.5 {nasty case, Bug 1036649} {
+    set x 0
+    for {set i 0} {$i < 10} {incr i} {
+	set res [list [catch {subst "\[incr x"} msg] $msg]
+	if {$msg ne "missing close-bracket"} break
+    }
+    lappend res $x
+} {1 {missing close-bracket} 0}
+test subst-12.6 {nasty case with compilation} {
+    set x unset
+    set y unset
+    list [eval [list subst {[set x 1;break;incr x][set y $x]}]] $x $y
+} {{} 1 unset}
+test subst-12.7 {nasty case with compilation} {
+    set x unset
+    set y unset
+    list [eval [list subst {[set x 1;continue;incr x][set y $x]}]] $x $y
+} {1 1 1}
+
+test subst-13.1 {Bug 3081065} -setup {
+    set script [makeFile {
+	proc demo {string} {
+	    subst $string
+	}
+	demo name2
+    } subst13.tcl]
+} -body {
+    interp create slave
+    slave eval [list source $script]
+    interp delete slave
+    interp create slave
+    slave eval {
+	set count 400
+	while {[incr count -1]} {
+	    lappend bloat [expr {rand()}]
+	}
+    }
+    slave eval [list source $script]
+    interp delete slave
+} -cleanup {
+    removeFile subst13.tcl
+}
+test subst-13.2 {Test for segfault} -body {
+    subst {[}
+} -returnCodes error -result * -match glob
+
+
+# cleanup
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/tests/switch.test b/tests/switch.test
new file mode 100644
index 0000000..4d204bb
--- /dev/null
+++ b/tests/switch.test
@@ -0,0 +1,772 @@
+# Commands covered:  switch
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands.  Sourcing this file into Tcl runs the tests and
+# generates output for errors.  No output means no errors were found.
+#
+# Copyright (c) 1993 The Regents of the University of California.
+# Copyright (c) 1994 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {"::tcltest" ni [namespace children]} {
+    package require tcltest 2
+    namespace import -force ::tcltest::*
+}
+
+test switch-1.1 {simple patterns} {
+    switch a a {subst 1} b {subst 2} c {subst 3} default {subst 4}
+} 1
+test switch-1.2 {simple patterns} {
+    switch b a {subst 1} b {subst 2} c {subst 3} default {subst 4}
+} 2
+test switch-1.3 {simple patterns} {
+    switch x a {subst 1} b {subst 2} c {subst 3} default {subst 4}
+} 4
+test switch-1.4 {simple patterns} {
+    switch x a {subst 1} b {subst 2} c {subst 3}
+} {}
+test switch-1.5 {simple pattern matches many times} {
+    switch b a {subst 1} b {subst 2} b {subst 3} b {subst 4}
+} 2
+test switch-1.6 {simple patterns} {
+    switch default a {subst 1} default {subst 2} c {subst 3} default {subst 4}
+} 2
+test switch-1.7 {simple patterns} {
+    switch x a {subst 1} default {subst 2} c {subst 3} default {subst 4}
+} 4
+test switch-1.8 {simple patterns with -nocase} {
+    switch -nocase b a {subst 1} b {subst 2} c {subst 3} default {subst 4}
+} 2
+test switch-1.9 {simple patterns with -nocase} {
+    switch -nocase B a {subst 1} b {subst 2} c {subst 3} default {subst 4}
+} 2
+test switch-1.10 {simple patterns with -nocase} {
+    switch -nocase b a {subst 1} B {subst 2} c {subst 3} default {subst 4}
+} 2
+test switch-1.11 {simple patterns with -nocase} {
+    switch -nocase x a {subst 1} default {subst 2} c {subst 3} default {subst 4}
+} 4
+
+test switch-2.1 {single-argument form for pattern/command pairs} {
+    switch b {
+	a {subst 1}
+	b {subst 2}
+	default {subst 6}
+    }
+} {2}
+test switch-2.2 {single-argument form for pattern/command pairs} -body {
+    switch z {a 2 b}
+} -returnCodes error -result {extra switch pattern with no body}
+
+test switch-3.1 {-exact vs. -glob vs. -regexp} {
+    switch -exact aaaab {
+	^a*b$	{subst regexp}
+	*b	{subst glob}
+	aaaab	{subst exact}
+	default	{subst none}
+    }
+} exact
+test switch-3.2 {-exact vs. -glob vs. -regexp} {
+    switch -regexp aaaab {
+	^a*b$	{subst regexp}
+	*b	{subst glob}
+	aaaab	{subst exact}
+	default	{subst none}
+    }
+} regexp
+test switch-3.3 {-exact vs. -glob vs. -regexp} {
+    switch -glob aaaab {
+	^a*b$	{subst regexp}
+	*b	{subst glob}
+	aaaab	{subst exact}
+	default	{subst none}
+    }
+} glob
+test switch-3.4 {-exact vs. -glob vs. -regexp} {
+    switch aaaab {^a*b$} {subst regexp} *b {subst glob} \
+	    aaaab {subst exact} default {subst none}
+} exact
+test switch-3.5 {-exact vs. -glob vs. -regexp} {
+    switch -- -glob {
+	^g.*b$	{subst regexp}
+	-*	{subst glob}
+	-glob	{subst exact}
+	default {subst none}
+    }
+} exact
+test switch-3.6 {-exact vs. -glob vs. -regexp} -body {
+    switch -foo a b c
+} -returnCodes error -result {bad option "-foo": must be -exact, -glob, -indexvar, -matchvar, -nocase, -regexp, or --}
+test switch-3.7 {-exact vs. -glob vs. -regexp with -nocase} {
+    switch -exact -nocase aaaab {
+	^a*b$	{subst regexp}
+	*b	{subst glob}
+	aaaab	{subst exact}
+	default	{subst none}
+    }
+} exact
+test switch-3.8 {-exact vs. -glob vs. -regexp with -nocase} {
+    switch -regexp -nocase aaaab {
+	^a*b$	{subst regexp}
+	*b	{subst glob}
+	aaaab	{subst exact}
+	default	{subst none}
+    }
+} regexp
+test switch-3.9 {-exact vs. -glob vs. -regexp with -nocase} {
+    switch -glob -nocase aaaab {
+	^a*b$	{subst regexp}
+	*b	{subst glob}
+	aaaab	{subst exact}
+	default	{subst none}
+    }
+} glob
+test switch-3.10 {-exact vs. -glob vs. -regexp with -nocase} {
+    switch -nocase aaaab {^a*b$} {subst regexp} *b {subst glob} \
+	    aaaab {subst exact} default {subst none}
+} exact
+test switch-3.11 {-exact vs. -glob vs. -regexp with -nocase} {
+    switch -nocase -- -glob {
+	^g.*b$	{subst regexp}
+	-*	{subst glob}
+	-glob	{subst exact}
+	default {subst none}
+    }
+} exact
+test switch-3.12 {-exact vs. -glob vs. -regexp} {
+    switch -exa Foo Foo {set result OK}
+} OK
+test switch-3.13 {-exact vs. -glob vs. -regexp} {
+    switch -gl Foo Fo? {set result OK}
+} OK
+test switch-3.14 {-exact vs. -glob vs. -regexp} {
+    switch -re Foo Fo. {set result OK}
+} OK
+test switch-3.15 {-exact vs. -glob vs. -regexp} -body {
+    switch -exact -exact Foo Foo {set result OK}
+} -returnCodes error -result {bad option "-exact": -exact option already found}
+test switch-3.16 {-exact vs. -glob vs. -regexp} -body {
+    switch -exact -glob Foo Foo {set result OK}
+} -returnCodes error -result {bad option "-glob": -exact option already found}
+test switch-3.17 {-exact vs. -glob vs. -regexp} -body {
+    switch -glob -regexp Foo Foo {set result OK}
+} -returnCodes error -result {bad option "-regexp": -glob option already found}
+test switch-3.18 {-exact vs. -glob vs. -regexp} -body {
+    switch -regexp -glob Foo Foo {set result OK}
+} -returnCodes error -result {bad option "-glob": -regexp option already found}
+
+test switch-4.1 {error in executed command} {
+    list [catch {switch a a {error "Just a test"} default {subst 1}} msg] \
+	    $msg $::errorInfo
+} {1 {Just a test} {Just a test
+    while executing
+"error "Just a test""
+    ("a" arm line 1)
+    invoked from within
+"switch a a {error "Just a test"} default {subst 1}"}}
+test switch-4.2 {error: not enough args} -returnCodes error -body {
+    switch
+} -result {wrong # args: should be "switch ?-option ...? string ?pattern body ...? ?default body?"}
+test switch-4.3 {error: pattern with no body} -body {
+    switch a b
+} -returnCodes error -result {extra switch pattern with no body}
+test switch-4.4 {error: pattern with no body} -body {
+    switch a b {subst 1} c
+} -returnCodes error -result {extra switch pattern with no body}
+test switch-4.5 {error in default command} {
+    list [catch {switch foo a {error switch1} b {error switch 3} \
+	    default {error switch2}} msg] $msg $::errorInfo
+} {1 switch2 {switch2
+    while executing
+"error switch2"
+    ("default" arm line 1)
+    invoked from within
+"switch foo a {error switch1} b {error switch 3}  default {error switch2}"}}
+
+test switch-5.1 {errors in -regexp matching} -returnCodes error -body {
+    switch -regexp aaaab {
+	*b	{subst glob}
+	aaaab	{subst exact}
+	default	{subst none}
+    }
+} -result {couldn't compile regular expression pattern: quantifier operand invalid}
+
+test switch-6.1 {backslashes in patterns} {
+    switch -exact {\a\$\.\[} {
+	\a\$\.\[	{subst first}
+	\a\\$\.\\[	{subst second}
+	\\a\\$\\.\\[	{subst third}
+	{\a\\$\.\\[}	{subst fourth}
+	{\\a\\$\\.\\[}	{subst fifth}
+	default		{subst none}
+    }
+} third
+test switch-6.2 {backslashes in patterns} {
+    switch -exact {\a\$\.\[} {
+	\a\$\.\[	{subst first}
+	{\a\$\.\[}	{subst second}
+	{{\a\$\.\[}}	{subst third}
+	default		{subst none}
+    }
+} second
+
+test switch-7.1 {"-" bodies} {
+    switch a {
+	a -
+	b -
+	c {subst 1}
+	default {subst 2}
+    }
+} 1
+test switch-7.2 {"-" bodies} -body {
+    switch a {
+	a -
+	b -
+	c -
+    }
+} -returnCodes error -result {no body specified for pattern "c"}
+test switch-7.3 {"-" bodies} -body {
+    switch a {
+	a -
+	b -foo
+	c -
+    }
+} -returnCodes error -result {no body specified for pattern "c"}
+test switch-7.4 {"-" bodies} -body {
+    switch a {
+	a -
+	b -foo
+	c {}
+    }
+} -returnCodes error -result {invalid command name "-foo"}
+
+test switch-8.1 {empty body} {
+    set msg {}
+    switch {2} {
+    	1 {set msg 1}
+        2 {}
+        default {set msg 2}
+    }
+} {}
+proc test_switch_body {} {
+    return "INVOKED"
+}
+test switch-8.2 {weird body text, variable} {
+    set cmd {test_switch_body}
+    switch Foo {
+    	Foo $cmd
+    }
+} {INVOKED}
+test switch-8.3 {weird body text, variable} {
+    set cmd {test_switch_body}
+    switch Foo {
+    	Foo {$cmd}
+    }
+} {INVOKED}
+
+test switch-9.1 {empty pattern/body list} -returnCodes error -body {
+    switch x
+} -result {wrong # args: should be "switch ?-option ...? string ?pattern body ...? ?default body?"}
+test switch-9.2 {unpaired pattern} -returnCodes error -body {
+    switch -- x
+} -result {extra switch pattern with no body}
+test switch-9.3 {empty pattern/body list} -body {
+    switch x {}
+} -returnCodes error -result {wrong # args: should be "switch ?-option ...? string {?pattern body ...? ?default body?}"}
+test switch-9.4 {empty pattern/body list} -body {
+    switch -- x {}
+} -returnCodes error -result {wrong # args: should be "switch ?-option ...? string {?pattern body ...? ?default body?}"}
+test switch-9.5 {unpaired pattern} -body {
+    switch x a {} b
+} -returnCodes error -result {extra switch pattern with no body}
+test switch-9.6 {unpaired pattern} -body {
+    switch x {a {} b}
+} -returnCodes error -result {extra switch pattern with no body}
+test switch-9.7 {unpaired pattern} -body {
+    switch x a {} # comment b
+} -returnCodes error -result {extra switch pattern with no body}
+test switch-9.8 {unpaired pattern} -returnCodes error -body {
+    switch x {a {} # comment b}
+} -result {extra switch pattern with no body, this may be due to a comment incorrectly placed outside of a switch body - see the "switch" documentation}
+test switch-9.9 {unpaired pattern} -body {
+    switch x a {} x {} # comment b
+} -returnCodes error -result {extra switch pattern with no body}
+test switch-9.10 {unpaired pattern} -returnCodes error -body {
+    switch x {a {} x {} # comment b}
+} -result {extra switch pattern with no body, this may be due to a comment incorrectly placed outside of a switch body - see the "switch" documentation}
+
+test switch-10.1 {compiled -exact switch} {
+    if 1 {switch -exact -- a {a {subst 1} b {subst 2}}}
+} 1
+test switch-10.1a {compiled -exact switch} {
+    if 1 {switch -exact a {a {subst 1} b {subst 2}}}
+} 1
+test switch-10.2 {compiled -exact switch} {
+    if 1 {switch -exact -- b {a {subst 1} b {subst 2}}}
+} 2
+test switch-10.2a {compiled -exact switch} {
+    if 1 {switch -exact b {a {subst 1} b {subst 2}}}
+} 2
+test switch-10.3 {compiled -exact switch} {
+    if 1 {switch -exact -- c {a {subst 1} b {subst 2}}}
+} {}
+test switch-10.3a {compiled -exact switch} {
+    if 1 {switch -exact c {a {subst 1} b {subst 2}}}
+} {}
+test switch-10.4 {compiled -exact switch} {
+    if 1 {
+	set x 0
+	switch -exact -- c {a {subst 1} b {subst 2}}
+    }
+} {}
+test switch-10.5 {compiled -exact switch} {
+    if 1 {switch -exact -- a {a - aa {subst 1} b {subst 2}}}
+} 1
+test switch-10.6 {compiled -exact switch} {
+    if 1 {switch -exact -- b {a {
+	set x 1;set x 1;set x 1;set x 1;set x 1;set x 1;set x 1;set x 1
+	set x 1;set x 1;set x 1;set x 1;set x 1;set x 1;set x 1;set x 1
+	set x 1;set x 1;set x 1;set x 1;set x 1;set x 1;set x 1;set x 1
+	set x 1;set x 1;set x 1;set x 1;set x 1;set x 1;set x 1;set x 1
+	set x 1;set x 1;set x 1;set x 1;set x 1;set x 1;set x 1;set x 1
+	set x 1;set x 1;set x 1;set x 1;set x 1;set x 1;set x 1;set x 1
+	set x 1;set x 1;set x 1;set x 1;set x 1;set x 1;set x 1;set x 1
+	set x 1;set x 1;set x 1;set x 1;set x 1;set x 1;set x 1;set x 1
+    } b {subst 2}}}
+} 2
+
+# Command variants are:
+#    c* are compiled switches, i* are interpreted
+#    *-glob use glob matching, *-exact use exact matching
+#    *2* include a default clause (different results too.)
+proc cswtest-glob s {
+    set x 0; set y 0
+    foreach c [split $s {}] {
+	switch -glob $c {
+	    a {incr x}
+	    b {incr y}
+	}
+    }
+    set x [expr {$x*100}]; set y [expr {$y*100}]
+    foreach c [split $s {}] {
+	switch -glob -- $c a {incr x} b {incr y}
+    }
+    return $x,$y
+}
+proc iswtest-glob s {
+    set x 0; set y 0; set switch switch
+    foreach c [split $s {}] {
+	$switch -glob $c {
+	    a {incr x}
+	    b {incr y}
+	}
+    }
+    set x [expr {$x*100}]; set y [expr {$y*100}]
+    foreach c [split $s {}] {
+	$switch -glob -- $c a {incr x} b {incr y}
+    }
+    return $x,$y
+}
+proc cswtest-exact s {
+    set x 0; set y 0
+    foreach c [split $s {}] {
+	switch -exact $c {
+	    a {incr x}
+	    b {incr y}
+	}
+    }
+    set x [expr {$x*100}]; set y [expr {$y*100}]
+    foreach c [split $s {}] {
+	switch -exact -- $c a {incr x} b {incr y}
+    }
+    return $x,$y
+}
+proc iswtest-exact s {
+    set x 0; set y 0; set switch switch
+    foreach c [split $s {}] {
+	$switch -exact $c {
+	    a {incr x}
+	    b {incr y}
+	}
+    }
+    set x [expr {$x*100}]; set y [expr {$y*100}]
+    foreach c [split $s {}] {
+	$switch -exact -- $c a {incr x} b {incr y}
+    }
+    return $x,$y
+}
+proc cswtest2-glob s {
+    set x 0; set y 0; set z 0
+    foreach c [split $s {}] {
+	switch -glob $c {
+	    a {incr x}
+	    b {incr y}
+	    default {incr z}
+	}
+    }
+    set x [expr {$x*100}]; set y [expr {$y*100}]; set z [expr {$z*100}]
+    foreach c [split $s {}] {
+	switch -glob -- $c a {incr x} b {incr y} default {incr z}
+    }
+    return $x,$y,$z
+}
+proc iswtest2-glob s {
+    set x 0; set y 0; set z 0; set switch switch
+    foreach c [split $s {}] {
+	$switch -glob $c {
+	    a {incr x}
+	    b {incr y}
+	    default {incr z}
+	}
+    }
+    set x [expr {$x*100}]; set y [expr {$y*100}]; set z [expr {$z*100}]
+    foreach c [split $s {}] {
+	$switch -glob -- $c a {incr x} b {incr y} default {incr z}
+    }
+    return $x,$y,$z
+}
+proc cswtest2-exact s {
+    set x 0; set y 0; set z 0
+    foreach c [split $s {}] {
+	switch -exact $c {
+	    a {incr x}
+	    b {incr y}
+	    default {incr z}
+	}
+    }
+    set x [expr {$x*100}]; set y [expr {$y*100}]; set z [expr {$z*100}]
+    foreach c [split $s {}] {
+	switch -exact -- $c a {incr x} b {incr y} default {incr z}
+    }
+    return $x,$y,$z
+}
+proc iswtest2-exact s {
+    set x 0; set y 0; set z 0; set switch switch
+    foreach c [split $s {}] {
+	$switch -exact $c {
+	    a {incr x}
+	    b {incr y}
+	    default {incr z}
+	}
+    }
+    set x [expr {$x*100}]; set y [expr {$y*100}]; set z [expr {$z*100}]
+    foreach c [split $s {}] {
+	$switch -exact -- $c a {incr x} b {incr y} default {incr z}
+    }
+    return $x,$y,$z
+}
+
+test switch-10.7 {comparison of compiled and interpreted behaviour of switch, exact matching} {
+    cswtest-exact abcb
+} [iswtest-exact abcb]
+test switch-10.8 {comparison of compiled and interpreted behaviour of switch, glob matching} {
+    cswtest-glob abcb
+} [iswtest-glob abcb]
+test switch-10.9 {comparison of compiled and interpreted behaviour of switch, exact matching with default} {
+    cswtest2-exact abcb
+} [iswtest2-exact abcb]
+test switch-10.10 {comparison of compiled and interpreted behaviour of switch, glob matching with default} {
+    cswtest2-glob abcb
+} [iswtest2-glob abcb]
+proc cswtest-default-exact {x} {
+    switch -- $x {
+	a* {return b}
+	aa {return c}
+	default {return d}
+    }
+}
+test switch-10.11 {default to exact matching when compiled} {
+    cswtest-default-exact a
+} d
+test switch-10.12 {default to exact matching when compiled} {
+    cswtest-default-exact aa
+} c
+test switch-10.13 {default to exact matching when compiled} {
+    cswtest-default-exact a*
+} b
+test switch-10.14 {default to exact matching when compiled} {
+    cswtest-default-exact a**
+} d
+rename cswtest-default-exact {}
+rename cswtest-glob {}
+rename iswtest-glob {}
+rename cswtest2-glob {}
+rename iswtest2-glob {}
+rename cswtest-exact {}
+rename iswtest-exact {}
+rename cswtest2-exact {}
+rename iswtest2-exact {}
+# Bug 1891827
+test switch-10.15 {(not) compiled exact nocase regression} {
+    apply {{} {
+	switch -nocase -- A { a {return yes} default {return no} }
+    }}
+} yes
+
+# Added due to TIP#75
+test switch-11.1 {regexp matching with -matchvar} {
+    switch -regexp -matchvar x -- abc {.(.). {set x}}
+} {abc b}
+test switch-11.2 {regexp matching with -matchvar} {
+    set x GOOD
+    switch -regexp -matchvar x -- abc {.(.).. {list $x z}}
+    set x
+} GOOD
+test switch-11.3 {regexp matching with -matchvar} {
+    switch -regexp -matchvar x -- "a b c" {.(.). {set x}}
+} {{a b} { }}
+test switch-11.4 {regexp matching with -matchvar} {
+    set x BAD
+    switch -regexp -matchvar x -- "a b c" {
+	bc {list $x YES}
+	default {list $x NO}
+    }
+} {{} NO}
+test switch-11.5 {-matchvar without -regexp} {
+    set x {}
+    list [catch {switch -glob -matchvar x -- abc . {set x}} msg] $x $msg
+} {1 {} {-matchvar option requires -regexp option}}
+test switch-11.6 {-matchvar unwritable} {
+    set x {}
+    list [catch {switch -regexp -matchvar x(x) -- abc . {set x}} msg] $x $msg
+} {1 {} {can't set "x(x)": variable isn't array}}
+
+test switch-12.1 {regexp matching with -indexvar} {
+    switch -regexp -indexvar x -- abc {.(.). {set x}}
+} {{0 2} {1 1}}
+test switch-12.2 {regexp matching with -indexvar} {
+    set x GOOD
+    switch -regexp -indexvar x -- abc {.(.).. {list $x z}}
+    set x
+} GOOD
+test switch-12.3 {regexp matching with -indexvar} {
+    switch -regexp -indexvar x -- "a b c" {.(.). {set x}}
+} {{0 2} {1 1}}
+test switch-12.4 {regexp matching with -indexvar} {
+    set x BAD
+    switch -regexp -indexvar x -- "a b c" {
+	bc {list $x YES}
+	default {list $x NO}
+    }
+} {{} NO}
+test switch-12.5 {-indexvar without -regexp} {
+    set x {}
+    list [catch {switch -glob -indexvar x -- abc . {set x}} msg] $x $msg
+} {1 {} {-indexvar option requires -regexp option}}
+test switch-12.6 {-indexvar unwritable} {
+    set x {}
+    list [catch {switch -regexp -indexvar x(x) -- abc . {set x}} msg] $x $msg
+} {1 {} {can't set "x(x)": variable isn't array}}
+test switch-12.7 {[Bug 3106532] -indexvar should be directly usable with [string range]} {
+    set str abcdef
+    switch -regexp -indexvar x -- $str ^... {string range $str {*}[lindex $x 0]}
+} abc
+test switch-12.8 {-indexvar and matched empty strings} {
+    switch -regexp -indexvar x -- abcdef ^...(x?) {return $x}
+} {{0 2} {3 2}}
+test switch-12.9 {-indexvar and unmatched strings} {
+    switch -regexp -indexvar x -- abcdef ^...(x)? {return $x}
+} {{0 2} {-1 -1}}
+
+test switch-13.1 {-indexvar -matchvar combinations} {
+    switch -regexp -indexvar x -matchvar y abc {
+	. {list $x $y}
+    }
+} {{{0 0}} a}
+test switch-13.2 {-indexvar -matchvar combinations} {
+    switch -regexp -indexvar x -matchvar y abc {
+	.$ {list $x $y}
+    }
+} {{{2 2}} c}
+test switch-13.3 {-indexvar -matchvar combinations} {
+    switch -regexp -indexvar x -matchvar y abc {
+	(.)(.)(.) {list $x $y}
+    }
+} {{{0 2} {0 0} {1 1} {2 2}} {abc a b c}}
+test switch-13.4 {-indexvar -matchvar combinations} {
+    set x -
+    set y -
+    switch -regexp -indexvar x -matchvar y abc {
+	(.)(.)(.). -
+	default {list $x $y}
+    }
+} {{} {}}
+test switch-13.5 {-indexvar -matchvar combinations} {
+    set x -
+    set y -
+    list [catch {
+	switch -regexp -indexvar x(x) -matchvar y abc {. {list $x $y}}
+    } msg] $x $y $msg
+} {1 - - {can't set "x(x)": variable isn't array}}
+test switch-13.6 {-indexvar -matchvar combinations} {
+    set x -
+    set y -
+    list [catch {
+	switch -regexp -indexvar x -matchvar y(y) abc {. {list $x $y}}
+    } msg] $x $y $msg
+} {1 {{0 0}} - {can't set "y(y)": variable isn't array}}
+
+test switch-14.1 {-regexp -- compilation [Bug 1854399]} {
+    switch -regexp -- 0 {
+	{[0-9]+} {return yes}
+	default  {return no}
+    }
+    foo
+} yes
+test switch-14.2 {-regexp -- compilation [Bug 1854399]} {
+    proc foo {} {
+	switch -regexp -- 0 {
+	    {[0-9]+} {return yes}
+	    default  {return no}
+	}
+    }
+    foo
+} yes
+test switch-14.3 {-regexp -- compilation [Bug 1854399]} {
+    proc foo {} {
+	switch -regexp -- 0 {
+	    {\d+} {return yes}
+	    default  {return no}
+	}
+    }
+    foo
+} yes
+test switch-14.4 {-regexp -- compilation [Bug 1854399]} {
+    proc foo {} {
+	switch -regexp -- 0 {
+	    {0} {return yes}
+	    default  {return no}
+	}
+    }
+    foo
+} yes
+test switch-14.5 {switch -regexp compilation} {
+    apply {{} {
+	switch -regexp -- 0 {
+	    {0|1|2} {return yes}
+	    default {return no}
+	}
+    }}
+} yes
+test switch-14.6 {switch -regexp compilation} {
+    apply {{} {
+	switch -regexp -- 0 {
+	    {0|11|222} {return yes}
+	    default {return no}
+	}
+    }}
+} yes
+test switch-14.7 {switch -regexp compilation} {
+    apply {{} {
+	switch -regexp -- 0 {
+	    {[012]} {return yes}
+	    default {return no}
+	}
+    }}
+} yes
+test switch-14.8 {switch -regexp compilation} {
+    apply {{} {
+	switch -regexp -- x {
+	    {0|1|2} {return yes}
+	    default {return no}
+	}
+    }}
+} no
+test switch-14.9 {switch -regexp compilation} {
+    apply {{} {
+	switch -regexp -- x {
+	    {0|11|222} {return yes}
+	    default {return no}
+	}
+    }}
+} no
+test switch-14.10 {switch -regexp compilation} {
+    apply {{} {
+	switch -regexp -- x {
+	    {[012]} {return yes}
+	    default {return no}
+	}
+    }}
+} no
+test switch-14.11 {switch -regexp compilation} {
+    apply {{} {
+	switch -regexp -- x {
+	    {0|1|2} {return yes}
+	    .+ {return yes2}
+	    default {return no}
+	}
+    }}
+} yes2
+test switch-14.12 {switch -regexp compilation} {
+    apply {{} {
+	switch -regexp -- x {
+	    {0|11|222} {return yes}
+	    .+ {return yes2}
+	    default {return no}
+	}
+    }}
+} yes2
+test switch-14.13 {switch -regexp compilation} {
+    apply {{} {
+	switch -regexp -- x {
+	    {[012]} {return yes}
+	    .+ {return yes2}
+	    default {return no}
+	}
+    }}
+} yes2
+test switch-14.14 {switch -regexp compilation} {
+    apply {{} {
+	switch -regexp -- {} {
+	    {0|1|2} {return yes}
+	    .+ {return yes2}
+	    default {return no}
+	}
+    }}
+} no
+test switch-14.15 {switch -regexp compilation} {
+    apply {{} {
+	switch -regexp -- {} {
+	    {0|11|222} {return yes}
+	    .+ {return yes2}
+	    default {return no}
+	}
+    }}
+} no
+test switch-14.16 {switch -regexp compilation} {
+    apply {{} {
+	switch -regexp -- {} {
+	    {[012]} {return yes}
+	    .+ {return yes2}
+	    default {return no}
+	}
+    }}
+} no
+
+test switch-15.1 {coroutine safety of non-bytecoded switch} {*}{
+    -body {
+	proc coro {} {
+	    switch -glob a {
+		a {yield ok1}
+	    }
+	    return ok2
+	}
+	list [coroutine c coro] [c]
+    }
+    -result {ok1 ok2}
+    -cleanup {
+	rename coro {}
+    }
+}
+
+# cleanup
+catch {rename foo {}}
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/tests/tailcall.test b/tests/tailcall.test
new file mode 100644
index 0000000..26f3cbf
--- /dev/null
+++ b/tests/tailcall.test
@@ -0,0 +1,696 @@
+# Commands covered:  tailcall
+#
+# This file contains a collection of tests for experimental commands that are
+# found in ::tcl::unsupported. The tests will migrate to normal test files
+# if/when the commands find their way into the core.
+#
+# Copyright (c) 2008 by Miguel Sofer.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+    package require tcltest
+    namespace import -force ::tcltest::*
+}
+
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
+
+testConstraint testnrelevels [llength [info commands testnrelevels]]
+
+#
+# The tests that risked blowing the C stack on failure have been removed: we
+# can now actually measure using testnrelevels.
+#
+
+if {[testConstraint testnrelevels]} {
+    namespace eval testnre {
+	#
+	# [testnrelevels] returns a 6-list with: C-stack depth, iPtr->numlevels,
+	# cmdFrame level, callFrame level, tosPtr and callback depth 
+	#
+	variable last [testnrelevels] 
+	proc depthDiff {} {
+	    variable last
+	    set depth [testnrelevels]
+	    set res {}
+	    foreach t $depth l $last {
+		lappend res [expr {$t-$l}]
+	    }
+	    set last $depth
+	    return $res
+	}
+	namespace export *
+    }
+    namespace import testnre::*
+}
+
+proc errorcode options {
+    dict get [dict merge {-errorcode NONE} $options] -errorcode
+}
+
+test tailcall-0.1 {tailcall is constant space} -constraints testnrelevels -setup {
+    proc a i {
+	#
+	# NOTE: there may be a diff in callback depth with the first call
+	# ($i==0) due to the fact that the first is from an eval. Successive
+	# calls should add nothing to any stack depths.
+	#
+	if {$i == 1} {
+	    depthDiff
+	}
+	if {[incr i] > 10} {
+	    return [depthDiff]
+	}
+	tailcall a $i
+    }
+} -body {
+    a 0
+} -cleanup {
+    rename a {}
+} -result {0 0 0 0 0 0}
+
+test tailcall-0.2 {tailcall is constant space} -constraints testnrelevels -setup {
+    set a { i {
+	if {$i == 1} {
+	    depthDiff
+	}
+	if {[incr i] > 10} {
+	    return [depthDiff]
+	}
+	upvar 1 a a
+	tailcall apply $a $i
+    }}
+} -body {
+    apply $a 0
+} -cleanup {
+    unset a
+} -result {0 0 0 0 0 0}
+
+test tailcall-0.3 {tailcall is constant space} -constraints testnrelevels -setup {
+    proc a i {
+	if {$i == 1} {
+	    depthDiff
+	}
+	if {[incr i] > 10} {
+	    return [depthDiff]
+	}
+	tailcall b $i
+    }
+    interp alias {} b {} a
+} -body {
+    b 0
+} -cleanup {
+    rename a {}
+    rename b {}
+} -result {0 0 0 0 0 0}
+
+test tailcall-0.4 {tailcall is constant space} -constraints testnrelevels -setup {
+    namespace eval ::ns {
+	namespace export *
+    }
+    proc ::ns::a i {
+	if {$i == 1} {
+	    depthDiff
+	}
+	if {[incr i] > 10} {
+	    return [depthDiff]
+	}
+	set b [uplevel 1 [list namespace which b]]
+	tailcall $b $i
+    }
+    namespace import ::ns::a
+    rename a b
+} -body {
+    b 0
+} -cleanup {
+    rename b {}
+    namespace delete ::ns
+} -result {0 0 0 0 0 0}
+
+test tailcall-0.5 {tailcall is constant space} -constraints testnrelevels -setup {
+    proc b i {
+	if {$i == 1} {
+	    depthDiff
+	}
+	if {[incr i] > 10} {
+	    return [depthDiff]
+	}
+	tailcall a b $i
+    }
+    namespace ensemble create -command a -map {b b}
+} -body {
+    a b 0
+} -cleanup {
+    rename a {}
+    rename b {}
+} -result {0 0 0 0 0 0}
+
+test tailcall-0.5.1 {tailcall is constant space} -constraints testnrelevels -setup {
+    # 
+    # This test is related to [bug d87cb182053fd79b3]: the fix to that bug was
+    # to remove a call to TclSkipTailcall, which caused a violation of the
+    # constant-space property of tailcall in that particular
+    # configuration. This test was added to detect that, and insure that the
+    # problem is fixed.
+    #
+
+    proc b i {
+	if {$i == 1} {
+	    depthDiff
+	}
+	if {[incr i] > 10} {
+	    return [depthDiff]
+	}
+	tailcall dict b $i
+    }
+    set map0 [namespace ensemble configure dict -map]
+    set map $map0
+    dict set map b b
+    namespace ensemble configure dict -map $map
+} -body {
+    dict b 0
+} -cleanup {
+    rename b {}
+    namespace ensemble configure dict -map $map0
+    unset map map0
+} -result {0 0 0 0 0 0}
+
+test tailcall-0.6 {tailcall is constant space} -constraints {testnrelevels knownBug} -setup {
+    #
+    # This test fails because ns-unknown is not NR-enabled
+    #
+    proc c i {
+	if {$i == 1} {
+	    depthDiff
+	}
+	if {[incr i] > 10} {
+	    return [depthDiff]
+	}
+	tailcall a b $i
+    }
+    proc d {ens sub args} {
+	return [list $ens c]
+    }
+    namespace ensemble create -command a -unknown d
+} -body {
+    a b 0
+} -cleanup {
+    rename a {}
+    rename c {}
+    rename d {}
+} -result {0 0 0 0 0 0}
+
+test tailcall-0.7 {tailcall is constant space} -constraints testnrelevels -setup {
+    catch {rename foo {}}
+    oo::class create foo {
+	method b i {
+	    if {$i == 1} {
+		depthDiff
+	    }
+	    if {[incr i] > 10} {
+		return [depthDiff]
+	    }
+	    tailcall [self] b $i
+	}
+    }
+} -body {
+    foo create a
+    a b 0
+} -cleanup {
+    rename a {}
+    rename foo {}
+} -result {0 0 0 0 0 0}
+
+test tailcall-1 {tailcall} -body {
+    namespace eval a {
+	variable x *::a
+	proc xset {} {
+	    set tmp {}
+	    set ns {[namespace current]}
+	    set level [info level]
+	    for {set i 0} {$i <= [info level]} {incr i} {
+		uplevel #$i "set x $i$ns"
+		lappend tmp "$i [info level $i]"
+	    }
+	    lrange $tmp 1 end
+	}
+	proc foo {} {tailcall xset; set x noreach}
+    }
+    namespace eval b {
+	variable x *::b
+	proc xset args {error b::xset}
+	proc moo {} {set x 0; variable y [::a::foo]; set x}
+    }
+    variable x *::
+    proc xset args {error ::xset}
+    list [::b::moo] | $x $a::x $b::x | $::b::y 
+} -cleanup {
+    unset x
+    rename xset {}
+    namespace delete a b
+} -result {1::b | 0:: *::a *::b | {{1 ::b::moo} {2 xset}}}
+
+
+test tailcall-2 {tailcall in non-proc} -body {
+    namespace eval a [list tailcall set x 1]
+} -match glob -result *tailcall* -returnCodes error
+
+test tailcall-3 {tailcall falls off tebc} -body {
+    unset -nocomplain x
+    proc foo {} {tailcall set x 1}
+    list [catch foo msg] $msg [set x]
+} -cleanup {
+    rename foo {}
+    unset x
+} -result {0 1 1}
+
+test tailcall-4 {tailcall falls off tebc} -body {
+    set x 2
+    proc foo {} {tailcall set x 1}
+    foo
+    set x
+} -cleanup {
+    rename foo {}
+    unset x
+} -result 1
+
+test tailcall-5 {tailcall falls off tebc} -body {
+    set x 2
+    namespace eval bar {
+	variable x 3
+	proc foo {} {tailcall set x 1}
+    }
+    bar::foo
+    list $x $bar::x
+} -cleanup {
+    unset x
+    namespace delete bar
+} -result {1 3}
+
+test tailcall-6 {tailcall does remove callframes} -body {
+    proc foo {} {info level}
+    proc moo {} {tailcall foo}
+    proc boo {} {expr {[moo] - [info level]}}
+    boo
+} -cleanup {
+    rename foo {}
+    rename moo {}
+    rename boo {}
+} -result 1
+
+test tailcall-7 {tailcall does return} -setup {
+    namespace eval ::foo {
+	variable res {}
+	proc a {} {
+	    variable res
+	    append res a
+	    tailcall set x 1
+	    append res a
+	}
+	proc b {} {
+	    variable res
+	    append res b
+	    a
+	    append res b
+	}
+	proc c {} {
+	    variable res
+	    append res c
+	    b
+	    append res c
+	}
+    }
+} -body {
+    namespace eval ::foo c
+} -cleanup {
+    namespace delete ::foo
+} -result cbabc
+
+test tailcall-8 {tailcall tailcall} -setup {
+    namespace eval ::foo {
+	variable res {}
+	proc a {} {
+	    variable res
+	    append res a
+	    tailcall tailcall set x 1
+	    append res a
+	}
+	proc b {} {
+	    variable res
+	    append res b
+	    a
+	    append res b
+	}
+	proc c {} {
+	    variable res
+	    append res c
+	    b
+	    append res c
+	}
+    }
+} -body {
+    namespace eval ::foo c
+} -cleanup {
+    namespace delete ::foo
+} -result cbac
+
+test tailcall-9 {tailcall factorial} -setup {
+    proc fact {n {b 1}} {
+	if {$n == 1} {
+	    return $b
+	}
+	tailcall fact [expr {$n-1}] [expr {$n*$b}]
+    }
+} -body {
+    list [fact 1] [fact 5] [fact 10] [fact 15]
+} -cleanup {
+    rename fact {}
+} -result {1 120 3628800 1307674368000}
+
+test tailcall-10a {tailcall and eval} -setup {
+    set ::x 0
+    proc a {} {
+	eval [list tailcall lappend ::x 2]
+	set ::x 1
+    }
+} -body {
+    list [a] $::x
+} -cleanup {
+    unset -nocomplain ::x
+} -result {{0 2} {0 2}}
+
+test tailcall-10b {tailcall and eval} -setup {
+    set ::x 0
+    proc a {} {
+	eval {tailcall lappend ::x 2}
+	set ::x 1
+    }
+} -body {
+    list [a] $::x
+} -cleanup {
+    unset -nocomplain ::x
+} -result {{0 2} {0 2}}
+
+test tailcall-11a {tailcall and uplevel} -setup {
+    proc a {} {
+	uplevel 1 [list tailcall set ::x 2]
+	set ::x 1
+    }
+} -body {
+    list [a] $::x
+} -cleanup {
+    unset -nocomplain ::x
+} -match glob -result *tailcall* -returnCodes error
+
+test tailcall-11b {tailcall and uplevel} -setup {
+    proc a {} {
+	uplevel 1 {tailcall set ::x 2}
+	set ::x 1
+    }
+} -body {
+    list [a] $::x
+} -cleanup {
+    unset -nocomplain ::x
+} -match glob -result *tailcall* -returnCodes error
+
+test tailcall-11c {tailcall and uplevel} -setup {
+    proc a {} {
+	uplevel 1 {tailcall lappend ::x 2}
+	set ::x 1
+    }
+    proc b {} {set ::x 0; a; lappend ::x 3}
+} -body {
+    list [b] $::x
+} -cleanup {
+    rename a {}
+    rename b {}
+    unset -nocomplain ::x
+} -result {{0 3 2} {0 3 2}}
+
+test tailcall-12.1 {[Bug 2649975]} -setup {
+    proc dump {{text {}}} {
+	set text [uplevel 1 [list subst $text]]
+	set l [expr {[info level] -1}]
+	if {$text eq {}} {
+	    set text [info level $l]
+	}
+	puts "$l: $text"
+    }
+    # proc dump args {}
+    proc bravo {} {
+	upvar 1 v w
+	dump {inside bravo, v -> $w}
+	set v "procedure bravo"
+	#uplevel 1 [list delta ::betty]
+	uplevel 1 {delta ::betty}
+	return $::resolution
+    }
+    proc delta name {
+	upvar 1 v w
+	dump {inside delta, v -> $w}
+	set v "procedure delta"
+	tailcall foxtrot
+    }
+    proc foxtrot {} {
+	upvar 1 v w
+	dump {inside foxtrot, v -> $w}
+	global resolution
+	set ::resolution $w
+    }
+    set v "global level"
+} -body {
+    set result [bravo]
+    if {$result ne $v} {
+	puts "v should have been found at $v but was found in $result"
+    }
+} -cleanup {
+    unset v
+    rename dump {}
+    rename bravo {}
+    rename delta {}
+    rename foxtrot {}
+} -output {1: inside bravo, v -> global level
+1: inside delta, v -> global level
+1: inside foxtrot, v -> global level
+}
+
+test tailcall-12.2 {[Bug 2649975]} -setup {
+    proc dump {{text {}}} {
+	set text [uplevel 1 [list subst $text]]
+	set l [expr {[info level] -1}]
+	if {$text eq {}} {
+	    set text [info level $l]
+	}
+	puts "$l: $text"
+    }
+    # proc dump args {}
+    set v "global level"
+    oo::class create foo { # like connection
+	method alpha {} {  # like connections 'tables' method
+	    dump
+	    upvar 1 v w
+	    dump {inside foo's alpha, v resolves to $w}
+	    set v "foo's method alpha"
+	    dump {foo's alpha is calling [self] bravo - v should resolve at global level}
+	    set result [uplevel 1 [list [self] bravo]]
+	    dump {exiting from foo's alpha}
+	    return $result
+	}
+	method bravo {} {  # like connections 'foreach' method
+	    dump
+	    upvar 1 v w
+	    dump {inside foo's bravo, v resolves to $w}
+	    set v "foo's method bravo"
+	    dump {foo's bravo is calling charlie to create barney}
+	    set barney [my charlie ::barney]
+	    dump {foo's bravo is calling bravo on $barney}
+	    dump {v should resolve at global scope there}
+	    set result [uplevel 1 [list $barney bravo]]
+	    dump {exiting from foo's bravo}
+	    return $result
+	}
+	method charlie {name} {  # like tdbc prepare
+	    dump
+	    set v "foo's method charlie"
+	    dump {tailcalling bar's constructor}
+	    tailcall ::bar create $name
+	}
+    }
+    oo::class create bar { # like statement
+	method  bravo {} {   # like statement foreach method
+	    dump
+	    upvar 1 v w
+	    dump {inside bar's bravo, v is resolving to $w}
+	    set v "bar's method bravo"
+	    dump {calling delta to construct betty - v should resolve global there}
+	    uplevel 1 [list [self] delta ::betty]
+	    dump {exiting from bar's bravo}
+	    return [::betty whathappened]
+	}
+	method delta {name} {    # like statement execute method
+	    dump
+	    upvar 1 v w
+	    dump {inside bar's delta, v is resolving to $w}
+	    set v "bar's method delta"
+	    dump {tailcalling to construct $name as instance of grill}
+	    dump {v should resolve at global level in grill's constructor}
+	    dump {grill's constructor should run at level [info level]}
+	    tailcall grill create $name
+	}
+    }
+    oo::class create grill {
+	variable resolution
+	constructor {} {
+	    dump
+	    upvar 1 v w
+	    dump "in grill's constructor, v resolves to $w"
+	    set resolution $w
+	}
+	method whathappened {} {
+	    return $resolution
+	}
+    }
+    foo create fred
+} -body {
+    set result [fred alpha]
+    if {$result ne "global level"} {
+	puts "v should have been found at global level but was found in $result"
+    }
+} -cleanup {
+    unset result
+    rename fred {}
+    rename dump {}
+    rename foo {}
+    rename bar {}
+    rename grill {}
+} -output {1: fred alpha
+1: inside foo's alpha, v resolves to global level
+1: foo's alpha is calling ::fred bravo - v should resolve at global level
+1: ::fred bravo
+1: inside foo's bravo, v resolves to global level
+1: foo's bravo is calling charlie to create barney
+2: my charlie ::barney
+2: tailcalling bar's constructor
+1: foo's bravo is calling bravo on ::barney
+1: v should resolve at global scope there
+1: ::barney bravo
+1: inside bar's bravo, v is resolving to global level
+1: calling delta to construct betty - v should resolve global there
+1: ::barney delta ::betty
+1: inside bar's delta, v is resolving to global level
+1: tailcalling to construct ::betty as instance of grill
+1: v should resolve at global level in grill's constructor
+1: grill's constructor should run at level 1
+1: grill create ::betty
+1: in grill's constructor, v resolves to global level
+1: exiting from bar's bravo
+1: exiting from foo's bravo
+1: exiting from foo's alpha
+}
+
+test tailcall-12.3a0 {[Bug 2695587]} -body {
+    apply {{} {
+	catch [list tailcall foo]
+    }}
+} -returnCodes 1 -result {invalid command name "foo"}
+
+test tailcall-12.3a1 {[Bug 2695587]} -body {
+    apply {{} {
+	catch [list tailcall foo]
+	tailcall
+    }}
+} -result {}
+
+test tailcall-12.3a2 {[Bug 2695587]} -body {
+    apply {{} {
+	catch [list tailcall foo]
+	tailcall moo
+    }}
+} -returnCodes 1 -result {invalid command name "moo"}
+
+test tailcall-12.3a3 {[Bug 2695587]} -body {
+    set x 0
+    apply {{} {
+	catch [list tailcall foo]
+	tailcall lappend x 1
+    }}
+    set x
+} -cleanup {
+    unset x
+} -result {0 1} 
+
+test tailcall-12.3b0 {[Bug 2695587]} -body {
+    apply {{} {
+	set catch catch
+	$catch [list tailcall foo]
+    }}
+} -returnCodes 1 -result {invalid command name "foo"}
+
+test tailcall-12.3b1 {[Bug 2695587]} -body {
+    apply {{} {
+	set catch catch
+	$catch [list tailcall foo]
+	tailcall
+    }}
+} -result {}
+
+test tailcall-12.3b2 {[Bug 2695587]} -body {
+    apply {{} {
+	set catch catch
+	$catch [list tailcall foo]
+	tailcall moo
+    }}
+} -returnCodes 1 -result {invalid command name "moo"}
+
+test tailcall-12.3b3 {[Bug 2695587]} -body {
+    set x 0
+    apply {{} {
+	set catch catch
+	$catch [list tailcall foo]
+	tailcall lappend x 1
+    }}
+    set x
+} -cleanup {
+    unset x
+} -result {0 1} 
+
+# MORE VARIANTS MISSING: bc'ed caught script vs (bc'ed, not-bc'ed)
+# catch. Actually superfluous now, as tailcall just returns TCL_RETURN so that
+# standard catch behaviour is required.
+
+test tailcall-13.1 {directly tailcalling the tailcall command is ok} {
+    list [catch {
+	apply {{} {
+	    apply {{} {
+		tailcall tailcall subst ok
+		subst b
+	    }}
+	    subst c
+	}}
+    } msg opt] $msg [errorcode $opt]
+} {0 ok NONE}
+test tailcall-13.2 {indirectly tailcalling the tailcall command is ok} {
+    list [catch {
+	apply {{} {
+	    apply {{} {
+		tailcall eval tailcall subst ok
+		subst b
+	    }}
+	    subst c
+	}}
+    } msg opt] $msg [errorcode $opt]
+} {0 ok NONE}
+
+if {[testConstraint testnrelevels]} {
+    namespace forget testnre::*
+    namespace delete testnre
+}
+
+# cleanup
+::tcltest::cleanupTests
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/tests/tcltest.test b/tests/tcltest.test
new file mode 100644
index 0000000..728a018
--- /dev/null
+++ b/tests/tcltest.test
@@ -0,0 +1,1837 @@
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands.  Sourcing this file into Tcl runs the tests and
+# generates output for errors.  No output means no errors were found.
+#
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+# Copyright (c) 2000 by Ajuba Solutions
+# All rights reserved.
+
+# Note that there are several places where the value of
+# tcltest::currentFailure is stored/reset in the -setup/-cleanup
+# of a test that has a body that runs [test] that will fail.
+# This is a workaround of using the same tcltest code that we are
+# testing to run the test itself.  Ditto on things like [verbose].
+#
+# It would be better to have the -body of the tests run the tcltest
+# commands in a slave interp so the [test] being tested would not
+# interfere with the [test] doing the testing.
+#
+
+if {[catch {package require tcltest 2.1}]} {
+    puts stderr "Skipping tests in [info script].  tcltest 2.1 required."
+    return
+}
+
+namespace eval ::tcltest::test {
+
+namespace import ::tcltest::*
+
+makeFile {
+    package require tcltest
+    namespace import ::tcltest::test
+    test a-1.0 {test a} {
+	list 0
+    } {0}
+    test b-1.0 {test b} {
+	list 1
+    } {0}
+    test c-1.0 {test c} {knownBug} {
+    } {}
+    test d-1.0 {test d} {
+	error "foo" foo 9
+    } {}
+    tcltest::cleanupTests
+    exit
+} test.tcl
+
+cd [temporaryDirectory]
+testConstraint exec [llength [info commands exec]]
+
+# test -help
+# Child processes because -help [exit]s.
+test tcltest-1.1 {tcltest -help} {exec} {
+    set result [catch {exec [interpreter] test.tcl -help} msg]
+    list $result [regexp Usage $msg]
+} {1 1}
+test tcltest-1.2 {tcltest -help -something} {exec} {
+    set result [catch {exec [interpreter] test.tcl -help -something} msg]
+    list $result [regexp Usage $msg]
+} {1 1}
+test tcltest-1.3 {tcltest -h} {exec} {
+    set result [catch {exec [interpreter] test.tcl -h} msg]
+    list $result [regexp Usage $msg]
+} {1 0}
+
+# -verbose, implicit & explicit testing of [verbose]
+proc slave {msgVar args} {
+    upvar 1 $msgVar msg
+
+    interp create [namespace current]::i
+    # Fake the slave interp into dumping output to a file
+    i eval {namespace eval ::tcltest {}}
+    i eval "set tcltest::outputChannel\
+	    \[[list open [set of [makeFile {} output]] w]]"
+    i eval "set tcltest::errorChannel\
+	    \[[list open [set ef [makeFile {} error]] w]]"
+    i eval [list set argv0 [lindex $args 0]]
+    i eval [list set argv [lrange $args 1 end]]
+    i eval [list package ifneeded tcltest [package provide tcltest] \
+	    [package ifneeded tcltest [package provide tcltest]]]
+    i eval {proc exit args {}}
+
+    # Need to capture output in msg
+
+    set code [catch {i eval {source $argv0}}]
+    i eval {close $tcltest::outputChannel}
+    interp delete [namespace current]::i
+    set f [open $of]
+    set msg [read -nonewline $f]
+    close $f
+    set f [open $ef]
+    set err [read -nonewline $f]
+    close $f
+    removeFile output
+    removeFile error
+    if {[string length $err]} {
+	set code 1
+	append msg \n$err
+    }
+    return $code
+}
+test tcltest-2.0 {tcltest (verbose default - 'b')} {unixOrPc} {
+    set result [slave msg test.tcl]
+    list $result [regexp "Contents of test case" $msg] [regexp a-1.0 $msg] \
+	    [regexp c-1.0 $msg] \
+	    [regexp "Total.+4.+Passed.+1.+Skipped.+1.+Failed.+2" $msg]
+} {0 1 0 0 1}
+test tcltest-2.1 {tcltest -verbose 'b'} {unixOrPc} {
+    set result [slave msg test.tcl -verbose 'b']
+    list $result [regexp "Contents of test case" $msg] [regexp a-1.0 $msg] \
+	    [regexp c-1.0 $msg] \
+	    [regexp "Total.+4.+Passed.+1.+Skipped.+1.+Failed.+2" $msg]
+} {0 1 0 0 1}
+test tcltest-2.2 {tcltest -verbose 'p'} {unixOrPc} {
+    set result [slave msg test.tcl -verbose 'p']
+    list $result [regexp "Contents of test case" $msg] [regexp a-1.0 $msg] \
+	    [regexp c-1.0 $msg] \
+	    [regexp "Total.+4.+Passed.+1.+Skipped.+1.+Failed.+2" $msg]
+} {0 0 1 0 1}
+test tcltest-2.3 {tcltest -verbose 's'} {unixOrPc} {
+    set result [slave msg test.tcl -verbose 's']
+    list $result [regexp "Contents of test case" $msg] [regexp a-1.0 $msg] \
+	    [regexp c-1.0 $msg] \
+	    [regexp "Total.+4.+Passed.+1.+Skipped.+1.+Failed.+2" $msg]
+} {0 0 0 1 1}
+test tcltest-2.4 {tcltest -verbose 'ps'} {unixOrPc} {
+    set result [slave msg test.tcl -verbose 'ps']
+    list $result [regexp "Contents of test case" $msg] [regexp a-1.0 $msg] \
+	    [regexp c-1.0 $msg] \
+	    [regexp "Total.+4.+Passed.+1.+Skipped.+1.+Failed.+2" $msg]
+} {0 0 1 1 1}
+test tcltest-2.5 {tcltest -verbose 'psb'} {unixOrPc} {
+    set result [slave msg test.tcl -verbose 'psb']
+    list $result [regexp "Contents of test case" $msg] [regexp a-1.0 $msg] \
+	    [regexp c-1.0 $msg] \
+	    [regexp "Total.+4.+Passed.+1.+Skipped.+1.+Failed.+2" $msg]
+} {0 1 1 1 1}
+
+test tcltest-2.5a {tcltest -verbose 'pass skip body'} {unixOrPc} {
+    set result [slave msg test.tcl -verbose "pass skip body"]
+    list $result [regexp "Contents of test case" $msg] [regexp a-1.0 $msg] \
+	    [regexp c-1.0 $msg] \
+	    [regexp "Total.+4.+Passed.+1.+Skipped.+1.+Failed.+2" $msg]
+} {0 1 1 1 1}
+
+test tcltest-2.6 {tcltest -verbose 't'}  {
+    -constraints {unixOrPc}
+    -body {
+	set result [slave msg test.tcl -verbose 't']
+	list $result $msg
+    }
+    -result {^0 .*a-1.0 start.*b-1.0 start}
+    -match regexp
+}
+
+test tcltest-2.6a {tcltest -verbose 'start'}  {
+    -constraints {unixOrPc}
+    -body {
+	set result [slave msg test.tcl -verbose start]
+	list $result $msg
+    }
+    -result {^0 .*a-1.0 start.*b-1.0 start}
+    -match regexp
+}
+
+test tcltest-2.7 {tcltest::verbose}  {
+    -body {
+	set oldVerbosity [verbose]
+	verbose bar
+	set currentVerbosity [verbose]
+	verbose foo
+	set newVerbosity [verbose]
+	verbose $oldVerbosity
+	list $currentVerbosity $newVerbosity
+    }
+    -result {body {}}
+}
+
+test tcltest-2.8 {tcltest -verbose 'error'} {
+    -constraints {unixOrPc}
+    -body {
+	set result [slave msg test.tcl -verbose error]
+	list $result $msg
+    }
+    -result {errorInfo: foo.*errorCode: 9}
+    -match regexp
+}
+# -match, [match]
+test tcltest-3.1 {tcltest -match 'a*'} {unixOrPc} {
+    set result [slave msg test.tcl -match a* -verbose 'ps']
+    list $result [regexp a-1.0 $msg] [regexp b-1.0 $msg] [regexp c-1.0 $msg] \
+	    [regexp "Total.+4.+Passed.+1.+Skipped.+3.+Failed.+0" $msg]
+} {0 1 0 0 1}
+test tcltest-3.2 {tcltest -match 'b*'} {unixOrPc} {
+    set result [slave msg test.tcl -match b* -verbose 'ps']
+    list $result [regexp a-1.0 $msg] [regexp b-1.0 $msg] [regexp c-1.0 $msg] \
+	    [regexp "Total.+4.+Passed.+0.+Skipped.+3.+Failed.+1" $msg]
+} {0 0 1 0 1}
+test tcltest-3.3 {tcltest -match 'c*'} {unixOrPc} {
+    set result [slave msg test.tcl -match c* -verbose 'ps']
+    list $result [regexp a-1.0 $msg] [regexp b-1.0 $msg] [regexp c-1.0 $msg] \
+	    [regexp "Total.+4.+Passed.+0.+Skipped.+4.+Failed.+0" $msg]
+} {0 0 0 1 1}
+test tcltest-3.4 {tcltest -match 'a* b*'} {unixOrPc} {
+    set result [slave msg test.tcl -match {a* b*} -verbose 'ps']
+    list $result [regexp a-1.0 $msg] [regexp b-1.0 $msg] [regexp c-1.0 $msg] \
+	    [regexp "Total.+4.+Passed.+1.+Skipped.+2.+Failed.+1" $msg]
+} {0 1 1 0 1}
+
+test tcltest-3.5 {tcltest::match}  {
+    -body {
+	set oldMatch [match]
+	match foo
+	set currentMatch [match]
+	match bar
+	set newMatch [match]
+	match $oldMatch
+	list $currentMatch $newMatch
+    }
+    -result {foo bar}
+}
+
+# -skip, [skip]
+test tcltest-4.1 {tcltest -skip 'a*'} {unixOrPc} {
+    set result [slave msg test.tcl -skip a* -verbose 'ps']
+    list $result [regexp a-1.0 $msg] [regexp b-1.0 $msg] [regexp c-1.0 $msg] \
+	    [regexp "Total.+4.+Passed.+0.+Skipped.+2.+Failed.+1" $msg]
+} {0 0 1 1 1}
+test tcltest-4.2 {tcltest -skip 'b*'} {unixOrPc} {
+    set result [slave msg test.tcl -skip b* -verbose 'ps']
+    list $result [regexp a-1.0 $msg] [regexp b-1.0 $msg] [regexp c-1.0 $msg] \
+	    [regexp "Total.+4.+Passed.+1.+Skipped.+2.+Failed.+1" $msg]
+} {0 1 0 1 1}
+test tcltest-4.3 {tcltest -skip 'c*'} {unixOrPc} {
+    set result [slave msg test.tcl -skip c* -verbose 'ps']
+    list $result [regexp a-1.0 $msg] [regexp b-1.0 $msg] [regexp c-1.0 $msg] \
+	    [regexp "Total.+4.+Passed.+1.+Skipped.+1.+Failed.+2" $msg]
+} {0 1 1 0 1}
+test tcltest-4.4 {tcltest -skip 'a* b*'} {unixOrPc} {
+    set result [slave msg test.tcl -skip {a* b*} -verbose 'ps']
+    list $result [regexp a-1.0 $msg] [regexp b-1.0 $msg] [regexp c-1.0 $msg] \
+	    [regexp "Total.+4.+Passed.+0.+Skipped.+3.+Failed.+1" $msg]
+} {0 0 0 1 1}
+test tcltest-4.5 {tcltest -match 'a* b*' -skip 'b*'} {unixOrPc} {
+    set result [slave msg test.tcl -match {a* b*} -skip b* -verbose 'ps']
+    list $result [regexp a-1.0 $msg] [regexp b-1.0 $msg] [regexp c-1.0 $msg] \
+	    [regexp "Total.+4.+Passed.+1.+Skipped.+3.+Failed.+0" $msg]
+} {0 1 0 0 1}
+
+test tcltest-4.6 {tcltest::skip} {
+    -body {
+	set oldSkip [skip]
+	skip foo
+	set currentSkip [skip]
+	skip bar
+	set newSkip [skip]
+	skip $oldSkip
+	list $currentSkip $newSkip
+    }
+    -result {foo bar}
+}
+
+# -constraints, -limitconstraints, [testConstraint],
+# $constraintsSpecified, [limitConstraints]
+test tcltest-5.1 {tcltest -constraints 'knownBug'} {unixOrPc} {
+    set result [slave msg test.tcl -constraints knownBug -verbose 'ps']
+    list $result [regexp a-1.0 $msg] [regexp b-1.0 $msg] [regexp c-1.0 $msg] \
+	    [regexp "Total.+4.+Passed.+2.+Skipped.+0.+Failed.+2" $msg]
+} {0 1 1 1 1}
+test tcltest-5.2 {tcltest -constraints 'knownBug' -limitconstraints 1} {unixOrPc} {
+    set result [slave msg test.tcl -constraints knownBug -verbose 'p' -limitconstraints 1]
+    list $result [regexp a-1.0 $msg] [regexp b-1.0 $msg] [regexp c-1.0 $msg] \
+	    [regexp "Total.+4.+Passed.+1.+Skipped.+3.+Failed.+0" $msg]
+} {0 0 0 1 1}
+
+test tcltest-5.3 {testConstraint - constraint empty (tcltest::safeFetch)}  {
+    -body {
+	set r1 [testConstraint tcltestFakeConstraint]
+	set r2 [testConstraint tcltestFakeConstraint 4]
+	set r3 [testConstraint tcltestFakeConstraint]
+	list $r1 $r2 $r3
+    }
+    -result {0 4 4}
+    -cleanup {unset ::tcltest::testConstraints(tcltestFakeConstraint)}
+}
+
+# Removed this test of internals of tcltest.  Those internals have changed.
+#test tcltest-5.4 {tcltest::constraintsSpecified} {
+#    -setup {
+#	set constraintlist $::tcltest::constraintsSpecified
+#	set ::tcltest::constraintsSpecified {}
+#    }
+#    -body {
+#	set r1 $::tcltest::constraintsSpecified
+#	testConstraint tcltestFakeConstraint1 1
+#	set r2 $::tcltest::constraintsSpecified
+#	testConstraint tcltestFakeConstraint2 1
+#	set r3 $::tcltest::constraintsSpecified
+#	list $r1 $r2 $r3
+#    }
+#    -result {{} tcltestFakeConstraint1 {tcltestFakeConstraint1 tcltestFakeConstraint2}}
+#    -cleanup {
+#	set ::tcltest::constraintsSpecified $constraintlist
+#	unset ::tcltest::testConstraints(tcltestFakeConstraint1)
+#	unset ::tcltest::testConstraints(tcltestFakeConstraint2)
+#    }
+#}
+
+test tcltest-5.5 {InitConstraints: list of built-in constraints} \
+	-constraints {!singleTestInterp} \
+	-setup {tcltest::InitConstraints} \
+	-body { lsort [array names ::tcltest::testConstraints] } \
+	-result [lsort {
+    95 98 asyncPipeClose eformat emptyTest exec hasIsoLocale interactive
+    knownBug mac macCrash macOnly macOrPc macOrUnix macOrWin nonBlockFiles
+    nonPortable notRoot nt pc pcCrash pcOnly root singleTestInterp socket
+    stdio tempNotMac tempNotPc tempNotUnix tempNotWin unix unixCrash unixExecs
+    unixOnly unixOrPc unixOrWin userInteraction win winCrash winOnly
+}]
+
+# Removed this broken test.  Its usage of [limitConstraints] was not
+# in agreement with the documentation.  [limitConstraints] is supposed
+# to take an optional boolean argument, and "knownBug" ain't no boolean!
+#test tcltest-5.6 {tcltest::limitConstraints} {
+#    -setup {
+#        set keeplc $::tcltest::limitConstraints
+#        set keepkb [testConstraint knownBug]
+#    }
+#    -body {
+#        set r1 [limitConstraints]
+#        set r2 [limitConstraints knownBug]
+#        set r3 [limitConstraints]
+#        list $r1 $r2 $r3
+#    }
+#    -cleanup {
+#        limitConstraints $keeplc
+#        testConstraint knownBug $keepkb
+#    }
+#    -result {false knownBug knownBug}
+#}
+
+# -outfile, -errfile, [outputChannel], [outputFile], [errorChannel], [errorFile]
+set printerror [makeFile {
+    package require tcltest
+    namespace import ::tcltest::*
+    puts [outputChannel] "a test"
+    ::tcltest::PrintError "a really short string"
+    ::tcltest::PrintError "a really really really really really really long \
+	    string containing \"quotes\" and other bad bad stuff"
+    ::tcltest::PrintError "a really really long string containing a \
+	    \"Path/that/is/really/long/and/contains/no/spaces\""
+    ::tcltest::PrintError "a really really long string containing a \
+	    \"Really/Long/Path/that/contains/no/spaces/and/is/longer/than/eighty/characters/to/see/what/happens\""
+    ::tcltest::PrintError "Problem renaming file: error renaming \"Z:/ws/tcl8.2/win32-ix86/tests/core\" to \"Z:/ws/tcl8.2/win32-ix86/tests/movecore-core\""
+    exit
+} printerror.tcl]
+
+test tcltest-6.1 {tcltest -outfile, -errfile defaults} {
+    -constraints unixOrPc
+    -body {
+	slave msg $printerror
+	return $msg
+    }
+    -result {a test.*a really}
+    -match regexp
+}
+test tcltest-6.2 {tcltest -outfile a.tmp} {unixOrPc unixExecs} {
+    slave msg $printerror -outfile a.tmp
+    set result1 [catch {exec grep "a test" a.tmp}]
+    set result2 [catch {exec grep "a really" a.tmp}]
+    list [regexp "a test" $msg] [regexp "a really" $msg] \
+	    $result1 $result2 [file exists a.tmp] [file delete a.tmp]
+} {0 1 0 1 1 {}}
+test tcltest-6.3 {tcltest -errfile a.tmp} {unixOrPc unixExecs} {
+    slave msg $printerror -errfile a.tmp
+    set result1 [catch {exec grep "a test" a.tmp}]
+    set result2 [catch {exec grep "a really" a.tmp}]
+    list [regexp "a test" $msg] [regexp "a really" $msg] \
+	    $result1 $result2 [file exists a.tmp] [file delete a.tmp]
+} {1 0 1 0 1 {}}
+test tcltest-6.4 {tcltest -outfile a.tmp -errfile b.tmp} {unixOrPc unixExecs} {
+    slave msg $printerror -outfile a.tmp -errfile b.tmp
+    set result1 [catch {exec grep "a test" a.tmp}]
+    set result2 [catch {exec grep "a really" b.tmp}]
+    list [regexp "a test" $msg] [regexp "a really" $msg] \
+	    $result1 $result2 \
+	    [file exists a.tmp] [file delete a.tmp] \
+	    [file exists b.tmp] [file delete b.tmp]
+} {0 0 0 0 1 {} 1 {}}
+
+test tcltest-6.5 {tcltest::errorChannel - retrieval} {
+    -setup {
+	set of [errorChannel]
+	set ::tcltest::errorChannel stderr
+    }
+    -body {
+	errorChannel
+    }
+    -result {stderr}
+    -cleanup {
+	set ::tcltest::errorChannel $of
+    }
+}
+
+test tcltest-6.6 {tcltest::errorFile (implicit errorChannel)} {
+    -setup {
+	set ef [makeFile {} efile]
+	set of [errorFile]
+	set ::tcltest::errorChannel stderr
+	set ::tcltest::errorFile stderr
+    }
+    -body {
+	set f0 [errorChannel]
+	set f1 [errorFile]
+	set f2 [errorFile $ef]
+	set f3 [errorChannel]
+	set f4 [errorFile]
+	subst {$f0;$f1;$f2;$f3;$f4}
+    }
+    -result {stderr;stderr;.*efile;file[0-9a-f]+;.*efile}
+    -match regexp
+    -cleanup {
+	errorFile $of
+	removeFile efile
+    }
+}
+test tcltest-6.7 {tcltest::outputChannel - retrieval} {
+    -setup {
+	set of [outputChannel]
+	set ::tcltest::outputChannel stdout
+    }
+    -body {
+	outputChannel
+    }
+    -result {stdout}
+    -cleanup {
+	set ::tcltest::outputChannel $of
+    }
+}
+
+test tcltest-6.8 {tcltest::outputFile (implicit outputFile)} {
+    -setup {
+	set ef [makeFile {} efile]
+	set of [outputFile]
+	set ::tcltest::outputChannel stdout
+	set ::tcltest::outputFile stdout
+    }
+    -body {
+	set f0 [outputChannel]
+	set f1 [outputFile]
+	set f2 [outputFile $ef]
+	set f3 [outputChannel]
+	set f4 [outputFile]
+	subst {$f0;$f1;$f2;$f3;$f4}
+    }
+    -result {stdout;stdout;.*efile;file[0-9a-f]+;.*efile}
+    -match regexp
+    -cleanup {
+	outputFile $of
+	removeFile efile
+    }
+}
+
+# -debug, [debug]
+# Must use child processes to test -debug because it always writes
+# messages to stdout, and we have no way to capture stdout of a
+# slave interp
+test tcltest-7.1 {tcltest test.tcl -debug 0} {unixOrPc} {
+    catch {exec [interpreter] test.tcl -debug 0} msg
+    regexp "Flags passed into tcltest" $msg
+} {0}
+test tcltest-7.2 {tcltest test.tcl -debug 1} {unixOrPc} {
+    catch {exec [interpreter] test.tcl -debug 1 -skip b*} msg
+    list [regexp userSpecifiedSkip $msg] \
+	    [regexp "Flags passed into tcltest" $msg]
+} {1 0}
+test tcltest-7.3 {tcltest test.tcl -debug 1} {unixOrPc} {
+    catch {exec [interpreter] test.tcl -debug 1 -match b*} msg
+    list [regexp userSpecifiedNonMatch $msg] \
+	    [regexp "Flags passed into tcltest" $msg]
+} {1 0}
+test tcltest-7.4 {tcltest test.tcl -debug 2} {unixOrPc} {
+    catch {exec [interpreter] test.tcl -debug 2} msg
+    list [regexp "Flags passed into tcltest" $msg] [regexp "Running" $msg]
+} {1 0}
+test tcltest-7.5 {tcltest test.tcl -debug 3} {unixOrPc} {
+    catch {exec [interpreter] test.tcl -debug 3} msg
+    list [regexp "Flags passed into tcltest" $msg] [regexp "Running" $msg]
+} {1 1}
+
+test tcltest-7.6 {tcltest::debug} {
+    -setup {
+	set old $::tcltest::debug
+	set ::tcltest::debug 0
+    }
+    -body {
+	set f1 [debug]
+	set f2 [debug 1]
+	set f3 [debug]
+	set f4 [debug 2]
+	set f5 [debug]
+	list $f1 $f2 $f3 $f4 $f5
+    }
+    -result {0 1 1 2 2}
+    -cleanup {
+	set ::tcltest::debug $old
+    }
+}
+removeFile test.tcl
+
+# directory tests
+
+set a [makeFile {
+    package require tcltest
+    tcltest::makeFile {} a.tmp
+    puts [tcltest::outputChannel] "testdir: [tcltest::testsDirectory]"
+    exit
+} a.tcl]
+
+set tdiaf [makeFile {} thisdirectoryisafile]
+
+set normaldirectory [makeDirectory normaldirectory]
+normalizePath normaldirectory
+
+# -tmpdir, [temporaryDirectory]
+test tcltest-8.1 {tcltest a.tcl -tmpdir a} -constraints unixOrPc -setup {
+    file delete -force thisdirectorydoesnotexist
+} -body {
+    slave msg $a -tmpdir thisdirectorydoesnotexist
+    file exists [file join thisdirectorydoesnotexist a.tmp]
+} -cleanup {
+    file delete -force thisdirectorydoesnotexist
+} -result 1
+test tcltest-8.2 {tcltest a.tcl -tmpdir thisdirectoryisafile} {
+    -constraints unixOrPc
+    -body {
+	slave msg $a -tmpdir $tdiaf
+	return $msg
+    }
+    -result {*not a directory*}
+    -match glob
+}
+# Test non-writeable directories, non-readable directories with directory flags
+set notReadableDir [file join [temporaryDirectory] notreadable]
+set notWriteableDir [file join [temporaryDirectory] notwriteable]
+makeDirectory notreadable
+makeDirectory notwriteable
+switch -- $::tcl_platform(platform) {
+    unix {
+	file attributes $notReadableDir -permissions 00333
+	file attributes $notWriteableDir -permissions 00555
+    }
+    default {
+	catch {file attributes $notWriteableDir -readonly 1}
+	catch {testchmod 0 $notWriteableDir}
+    }
+}
+test tcltest-8.3 {tcltest a.tcl -tmpdir notReadableDir} {
+    -constraints {unix notRoot}
+    -body {
+	slave msg $a -tmpdir $notReadableDir
+	return $msg
+    }
+    -result {*not readable*}
+    -match glob
+}
+# This constraint doesn't go at the top of the file so that it doesn't
+# interfere with tcltest-5.5
+testConstraint notFAT [expr {
+    ![string match "FAT*" [lindex [file system $notWriteableDir] 1]]
+}]
+# FAT permissions are fairly hopeless; ignore this test if that FS is used
+test tcltest-8.4 {tcltest a.tcl -tmpdir notWriteableDir} {
+    -constraints {unixOrPc notRoot notFAT}
+    -body {
+	slave msg $a -tmpdir $notWriteableDir
+	return $msg
+    }
+    -result {*not writeable*}
+    -match glob
+}
+test tcltest-8.5 {tcltest a.tcl -tmpdir normaldirectory} {
+    -constraints unixOrPc
+    -body {
+	slave msg $a -tmpdir $normaldirectory
+	# The join is necessary because the message can be split on multiple
+	# lines
+	file exists [file join $normaldirectory a.tmp]
+    }
+    -cleanup {
+	catch {file delete [file join $normaldirectory a.tmp]}
+    }
+    -result 1
+}
+cd [workingDirectory]
+test tcltest-8.6 {temporaryDirectory}  {
+    -setup {
+	set old $::tcltest::temporaryDirectory
+	set ::tcltest::temporaryDirectory $normaldirectory
+    }
+    -body {
+	set f1 [temporaryDirectory]
+	set f2 [temporaryDirectory [workingDirectory]]
+	set f3 [temporaryDirectory]
+	list $f1 $f2 $f3
+    }
+    -result "[list $normaldirectory [workingDirectory] [workingDirectory]]"
+    -cleanup {
+	set ::tcltest::temporaryDirectory $old
+    }
+}
+test tcltest-8.6a {temporaryDirectory - test format 2} -setup {
+    set old $::tcltest::temporaryDirectory
+    set ::tcltest::temporaryDirectory $normaldirectory
+} -body {
+    set f1 [temporaryDirectory]
+    set f2 [temporaryDirectory [workingDirectory]]
+    set f3 [temporaryDirectory]
+    list $f1 $f2 $f3
+} -cleanup {
+    set ::tcltest::temporaryDirectory $old
+} -result [list $normaldirectory [workingDirectory] [workingDirectory]]
+cd [temporaryDirectory]
+# -testdir, [testsDirectory]
+test tcltest-8.10 {tcltest a.tcl -testdir thisdirectorydoesnotexist} {
+    -constraints unixOrPc
+    -setup {
+	file delete -force thisdirectorydoesnotexist
+    }
+    -body {
+	slave msg $a -testdir thisdirectorydoesnotexist
+	return $msg
+    }
+    -match glob
+    -result {*does not exist*}
+}
+test tcltest-8.11 {tcltest a.tcl -testdir thisdirectoryisafile} {
+    -constraints unixOrPc
+    -body {
+	slave msg $a -testdir $tdiaf
+	return $msg
+    }
+    -match glob
+    -result {*not a directory*}
+}
+test tcltest-8.12 {tcltest a.tcl -testdir notReadableDir} {
+    -constraints {unix notRoot}
+    -body {
+	slave msg $a -testdir $notReadableDir
+	return $msg
+    }
+    -match glob
+    -result {*not readable*}
+}
+test tcltest-8.13 {tcltest a.tcl -testdir normaldirectory} {
+    -constraints unixOrPc
+    -body {
+	slave msg $a -testdir $normaldirectory
+	# The join is necessary because the message can be split on multiple
+	# lines
+	list [string first "testdir: $normaldirectory" [join $msg]] \
+	    [file exists [file join [temporaryDirectory] a.tmp]]
+    }
+    -cleanup {
+	file delete [file join [temporaryDirectory] a.tmp]
+    }
+    -result {0 1}
+}
+cd [workingDirectory]
+set current [pwd]
+test tcltest-8.14 {testsDirectory} {
+    -setup {
+	set old $::tcltest::testsDirectory
+	set ::tcltest::testsDirectory $normaldirectory
+    }
+    -body {
+	set f1 [testsDirectory]
+	set f2 [testsDirectory $current]
+	set f3 [testsDirectory]
+	list $f1 $f2 $f3
+    }
+    -result "[list $normaldirectory $current $current]"
+    -cleanup {
+	set ::tcltest::testsDirectory $old
+    }
+}
+# [workingDirectory]
+test tcltest-8.60 {::workingDirectory}  {
+    -setup {
+	set old $::tcltest::workingDirectory
+	set current [pwd]
+	set ::tcltest::workingDirectory $normaldirectory
+	cd $normaldirectory
+    }
+    -body {
+	set f1 [workingDirectory]
+	set f2 [pwd]
+	set f3 [workingDirectory $current]
+	set f4 [pwd]
+	set f5 [workingDirectory]
+	list $f1 $f2 $f3 $f4 $f5
+    }
+    -result "[list $normaldirectory \
+                   $normaldirectory \
+                   $current \
+                   $current \
+                   $current]"
+    -cleanup {
+	set ::tcltest::workingDirectory $old
+	cd $current
+    }
+}
+
+# clean up from directory testing
+
+switch -- $::tcl_platform(platform) {
+    unix {
+	file attributes $notReadableDir -permissions 777
+	file attributes $notWriteableDir -permissions 777
+    }
+    default {
+	catch {testchmod 0o777 $notWriteableDir}
+	catch {file attributes $notWriteableDir -readonly 0}
+    }
+}
+
+file delete -force -- $notReadableDir $notWriteableDir
+removeFile a.tcl
+removeFile thisdirectoryisafile
+removeDirectory normaldirectory
+
+# -file, -notfile, [matchFiles], [skipFiles]
+test tcltest-9.1 {-file d*.tcl} -constraints {unixOrPc} -setup {
+    set old [testsDirectory]
+    testsDirectory [file dirname [info script]]
+} -body {
+    slave msg [file join [testsDirectory] all.tcl] -file d*.test
+    return $msg
+} -cleanup {
+    testsDirectory $old
+} -match regexp -result {dstring\.test}
+
+test tcltest-9.2 {-file d*.tcl} -constraints {unixOrPc} -setup {
+    set old [testsDirectory]
+    testsDirectory [file dirname [info script]]
+} -body {
+    slave msg [file join [testsDirectory] all.tcl] \
+	    -file d*.test -notfile dstring*
+    regexp {dstring\.test} $msg
+} -cleanup {
+    testsDirectory $old
+} -result 0
+
+test tcltest-9.3 {matchFiles}  {
+    -body {
+	set old [matchFiles]
+	matchFiles foo
+	set current [matchFiles]
+	matchFiles bar
+	set new [matchFiles]
+	matchFiles $old
+	list $current $new
+    }
+    -result {foo bar}
+}
+
+test tcltest-9.4 {skipFiles} {
+    -body {
+	set old [skipFiles]
+	skipFiles foo
+	set current [skipFiles]
+	skipFiles bar
+	set new [skipFiles]
+	skipFiles $old
+	list $current $new
+    }
+    -result {foo bar}
+}
+
+test tcltest-9.5 {GetMatchingFiles: Bug 1119798} -setup {
+    set d [makeDirectory tmp]
+    makeDirectory foo $d
+    makeFile {} fee $d
+    file copy [file join [file dirname [info script]] all.tcl] $d
+} -body {
+    slave msg [file join [temporaryDirectory] all.tcl] -file f*
+    regexp {exiting with errors:} $msg
+} -cleanup {
+    file delete [file join $d all.tcl]
+    removeFile fee $d
+    removeDirectory foo $d
+    removeDirectory tmp
+} -result 0
+
+# -preservecore, [preserveCore]
+set mc [makeFile {
+    package require tcltest
+    namespace import ::tcltest::test
+    test makecore {make a core file} {
+	set f [open core w]
+	close $f
+    } {}
+    ::tcltest::cleanupTests
+    return
+} makecore.tcl]
+
+cd [temporaryDirectory]
+test tcltest-10.1 {-preservecore 0} {unixOrPc} {
+    slave msg $mc -preservecore 0
+    file delete core
+    regexp "Core file produced" $msg
+} {0}
+test tcltest-10.2 {-preservecore 1} {unixOrPc} {
+    slave msg $mc -preservecore 1
+    file delete core
+    regexp "Core file produced" $msg
+} {1}
+test tcltest-10.3 {-preservecore 2} {unixOrPc} {
+    slave msg $mc -preservecore 2
+    file delete core
+    list [regexp "Core file produced" $msg] [regexp "Moving file to" $msg] \
+	    [regexp "core-" $msg] [file delete core-makecore]
+} {1 1 1 {}}
+test tcltest-10.4 {-preservecore 3} {unixOrPc} {
+    slave msg $mc -preservecore 3
+    file delete core
+    list [regexp "Core file produced" $msg] [regexp "Moving file to" $msg] \
+	    [regexp "core-" $msg] [file delete core-makecore]
+} {1 1 1 {}}
+
+# Removing this test.  It makes no sense to test the ability of
+# [preserveCore] to accept an invalid value that will cause errors
+# in other parts of tcltest's operation.
+#test tcltest-10.5 {preserveCore} {
+#    -body {
+#	set old [preserveCore]
+#	set result [preserveCore foo]
+#	set result2 [preserveCore]
+#	preserveCore $old
+#	list $result $result2
+#    }
+#    -result {foo foo}
+#}
+removeFile makecore.tcl
+
+# -load, -loadfile, [loadScript], [loadFile]
+set contents {
+    package require tcltest
+    namespace import tcltest::*
+    puts [outputChannel] $::tcltest::loadScript
+    exit
+}
+set loadfile [makeFile $contents load.tcl]
+
+test tcltest-12.1 {-load xxx} {unixOrPc} {
+    slave msg $loadfile -load xxx
+    return $msg
+} {xxx}
+
+# Using child process because of -debug usage.
+test tcltest-12.2 {-loadfile load.tcl} {unixOrPc} {
+    catch {exec [interpreter] $loadfile -debug 2 -loadfile $loadfile} msg
+    list \
+	    [regexp {tcltest} [join [list $msg] [split $msg \n]]] \
+	    [regexp {loadScript} [join [list $msg] [split $msg \n]]]
+} {1 1}
+
+test tcltest-12.3 {loadScript} {
+    -setup {
+	set old $::tcltest::loadScript
+	set ::tcltest::loadScript {}
+    }
+    -body {
+	set f1 [loadScript]
+	set f2 [loadScript xxx]
+	set f3 [loadScript]
+	list $f1 $f2 $f3
+    }
+    -result {{} xxx xxx}
+    -cleanup {
+	set ::tcltest::loadScript $old
+    }
+}
+
+test tcltest-12.4 {loadFile} {
+    -setup {
+	set olds $::tcltest::loadScript
+	set ::tcltest::loadScript {}
+	set oldf $::tcltest::loadFile
+	set ::tcltest::loadFile {}
+    }
+    -body {
+	set f1 [loadScript]
+	set f2 [loadFile]
+	set f3 [loadFile $loadfile]
+	set f4 [loadScript]
+	set f5 [loadFile]
+	list $f1 $f2 $f3 $f4 $f5
+    }
+    -result "[list {} {} $loadfile $contents $loadfile]\n"
+    -cleanup {
+	set ::tcltest::loadScript $olds
+	set ::tcltest::loadFile $oldf
+    }
+}
+removeFile load.tcl
+
+# [interpreter]
+test tcltest-13.1 {interpreter} {
+    -setup {
+	set old $::tcltest::tcltest
+	set ::tcltest::tcltest tcltest
+    }
+    -body {
+	set f1 [interpreter]
+	set f2 [interpreter tclsh]
+	set f3 [interpreter]
+	list $f1 $f2 $f3
+    }
+    -result {tcltest tclsh tclsh}
+    -cleanup {
+	set ::tcltest::tcltest $old
+    }
+}
+
+# -singleproc, [singleProcess]
+set spd [makeDirectory singleprocdir]
+makeFile {
+    set foo 1
+} single1.test $spd
+
+makeFile {
+    unset foo
+} single2.test $spd
+
+set allfile [makeFile {
+    package require tcltest
+    namespace import tcltest::*
+    testsDirectory [file join [temporaryDirectory] singleprocdir]
+    runAllTests
+} all-single.tcl $spd]
+cd [workingDirectory]
+
+test tcltest-14.1 {-singleproc - single process} {
+    -constraints {unixOrPc}
+    -body {
+	slave msg $allfile -singleproc 0 -tmpdir [temporaryDirectory]
+	return $msg
+    }
+    -result {Test file error: can't unset .foo.: no such variable}
+    -match regexp
+}
+
+test tcltest-14.2 {-singleproc - multiple process} {
+    -constraints {unixOrPc}
+    -body {
+	slave msg $allfile -singleproc 1 -tmpdir [temporaryDirectory]
+	return $msg
+    }
+    -result {single1.test.*single2.test.*all\-single.tcl:.*Total.*0.*Passed.*0.*Skipped.*0.*Failed.*0}
+    -match regexp
+}
+
+test tcltest-14.3 {singleProcess} {
+    -setup {
+	set old $::tcltest::singleProcess
+	set ::tcltest::singleProcess 0
+    }
+    -body {
+	set f1 [singleProcess]
+	set f2 [singleProcess 1]
+	set f3 [singleProcess]
+	list $f1 $f2 $f3
+    }
+    -result {0 1 1}
+    -cleanup {
+	set ::tcltest::singleProcess $old
+    }
+}
+removeFile single1.test $spd
+removeFile single2.test $spd
+removeDirectory singleprocdir
+
+# -asidefromdir, -relateddir, [matchDirectories], [skipDirectories]
+
+# Before running these tests, need to set up test subdirectories with their own
+# all.tcl files.
+
+set dtd [makeDirectory dirtestdir]
+set dtd1 [makeDirectory dirtestdir2.1 $dtd]
+set dtd2 [makeDirectory dirtestdir2.2 $dtd]
+set dtd3 [makeDirectory dirtestdir2.3 $dtd]
+makeFile {
+    package require tcltest
+    namespace import -force tcltest::*
+    testsDirectory [file join [temporaryDirectory] dirtestdir]
+    runAllTests
+} all.tcl $dtd
+makeFile {
+    package require tcltest
+    namespace import -force tcltest::*
+    testsDirectory [file join [temporaryDirectory] dirtestdir dirtestdir2.1]
+    runAllTests
+} all.tcl $dtd1
+makeFile {
+    package require tcltest
+    namespace import -force tcltest::*
+    testsDirectory [file join [temporaryDirectory]  dirtestdir dirtestdir2.2]
+    runAllTests
+} all.tcl $dtd2
+makeFile {
+    package require tcltest
+    namespace import -force tcltest::*
+    testsDirectory [file join [temporaryDirectory] dirtestdir dirtestdir2.3]
+    runAllTests
+} all.tcl $dtd3
+
+test tcltest-15.1 {basic directory walking} {
+    -constraints {unixOrPc}
+    -body {
+	if {[slave msg \
+		[file join $dtd all.tcl] \
+		-tmpdir [temporaryDirectory]] == 1} {
+	    error $msg
+	}
+    }
+    -match regexp
+    -returnCodes 1
+    -result {Tests located in:.*dirtestdir.*Tests located in:.*dirtestdir2.[123].*Tests located in:.*dirtestdir2.[123].*Tests located in:.*dirtestdir2.[123]}
+}
+
+test tcltest-15.2 {-asidefromdir} {
+    -constraints {unixOrPc}
+    -body {
+	if {[slave msg \
+		[file join $dtd all.tcl] \
+		-asidefromdir dirtestdir2.3 \
+		-tmpdir [temporaryDirectory]] == 1} {
+	    error $msg
+	}
+    }
+    -match regexp
+    -returnCodes 1
+    -result {Tests located in:.*dirtestdir.*Tests located in:.*dirtestdir2.[12].*Tests located in:.*dirtestdir2.[12].*dirtestdir2.[12] test ended at .*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Error:  No test files remain after applying your match and skip patterns!
+Error:  No test files remain after applying your match and skip patterns!
+Error:  No test files remain after applying your match and skip patterns!$}
+}
+
+test tcltest-15.3 {-relateddir, non-existent dir} {
+    -constraints {unixOrPc}
+    -body {
+	if {[slave msg \
+		[file join $dtd all.tcl] \
+		-relateddir [file join [temporaryDirectory] dirtestdir0] \
+		-tmpdir [temporaryDirectory]] == 1} {
+	    error $msg
+	}
+    }
+    -returnCodes 1
+    -match regexp
+    -result {[^~]|dirtestdir[^2]}
+}
+
+test tcltest-15.4 {-relateddir, subdir} {
+    -constraints {unixOrPc}
+    -body {
+	if {[slave msg \
+		[file join $dtd all.tcl] \
+		-relateddir dirtestdir2.1 -tmpdir [temporaryDirectory]] == 1} {
+	    error $msg
+	}
+    }
+    -returnCodes 1
+    -match regexp
+    -result {Tests located in:.*dirtestdir2.[^23]}
+}
+test tcltest-15.5 {-relateddir, -asidefromdir} {
+    -constraints {unixOrPc}
+    -body {
+	if {[slave msg \
+		[file join $dtd all.tcl] \
+		-relateddir "dirtestdir2.1 dirtestdir2.2" \
+		-asidefromdir dirtestdir2.2 \
+		-tmpdir [temporaryDirectory]] == 1} {
+	    error $msg
+	}
+    }
+    -match regexp
+    -returnCodes 1
+    -result {Tests located in:.*dirtestdir2.[^23]}
+}
+
+test tcltest-15.6 {matchDirectories} {
+    -setup {
+	set old [matchDirectories]
+	set ::tcltest::matchDirectories {}
+    }
+    -body {
+	set r1 [matchDirectories]
+	set r2 [matchDirectories foo]
+	set r3 [matchDirectories]
+	list $r1 $r2 $r3
+    }
+    -cleanup {
+	set ::tcltest::matchDirectories $old
+    }
+    -result {{} foo foo}
+}
+
+test tcltest-15.7 {skipDirectories} {
+    -setup {
+	set old [skipDirectories]
+	set ::tcltest::skipDirectories {}
+    }
+    -body {
+	set r1 [skipDirectories]
+	set r2 [skipDirectories foo]
+	set r3 [skipDirectories]
+	list $r1 $r2 $r3
+    }
+    -cleanup {
+	set ::tcltest::skipDirectories $old
+    }
+    -result {{} foo foo}
+}
+removeDirectory dirtestdir2.3 $dtd
+removeDirectory dirtestdir2.2 $dtd
+removeDirectory dirtestdir2.1 $dtd
+removeDirectory dirtestdir
+
+# TCLTEST_OPTIONS
+test tcltest-19.1 {TCLTEST_OPTIONS default} -setup {
+	if {[info exists ::env(TCLTEST_OPTIONS)]} {
+	    set oldoptions $::env(TCLTEST_OPTIONS)
+	} else {
+	    set oldoptions none
+	}
+	# set this to { } instead of just {} to get around quirk in
+	# Windows env handling that removes empty elements from env array.
+	set ::env(TCLTEST_OPTIONS) { }
+	interp create slave1
+	slave1 eval [list set argv {-debug 2}]
+	slave1 alias puts puts
+	interp create slave2
+	slave2 alias puts puts
+    } -cleanup {
+	interp delete slave2
+	interp delete slave1
+	if {$oldoptions eq "none"} {
+	    unset ::env(TCLTEST_OPTIONS)
+	} else {
+	    set ::env(TCLTEST_OPTIONS) $oldoptions
+	}
+    } -body {
+	slave1 eval [package ifneeded tcltest [package provide tcltest]]
+	slave1 eval tcltest::debug
+	set ::env(TCLTEST_OPTIONS) "-debug 3"
+	slave2 eval [package ifneeded tcltest [package provide tcltest]]
+	slave2 eval tcltest::debug
+    } -result {^3$} -match regexp -output\
+{tcltest::debug\s+= 2.*tcltest::debug\s+= 3}
+
+# Begin testing of tcltest procs ...
+
+cd [temporaryDirectory]
+# PrintError
+test tcltest-20.1 {PrintError} {unixOrPc} {
+    set result [slave msg $printerror]
+    list $result [regexp "Error:  a really short string" $msg] \
+	    [regexp "     \"quotes\"" $msg] [regexp "    \"Path" $msg] \
+	    [regexp "    \"Really" $msg] [regexp Problem $msg]
+} {1 1 1 1 1 1}
+cd [workingDirectory]
+removeFile printerror.tcl
+
+# test::test
+test tcltest-21.0 {name and desc but no args specified} -setup {
+    set v [verbose]
+} -cleanup {
+    verbose $v
+} -body {
+   verbose {}
+   test tcltest-21.0.0 bar
+} -result {}
+
+test tcltest-21.1 {expect with glob} {
+    -body {
+	list a b c d e
+    }
+    -match glob
+    -result {[ab] b c d e}
+}
+
+test tcltest-21.2 {force a test command failure} {
+    -body {
+	test tcltest-21.2.0 {
+	    return 2
+	} {1}
+    }
+    -returnCodes 1
+    -result {bad option "1": must be -body, -cleanup, -constraints, -errorOutput, -match, -output, -result, -returnCodes, or -setup}
+}
+
+test tcltest-21.3 {test command with setup} {
+    -setup {
+	set foo 1
+    }
+    -body {
+	set foo
+    }
+    -cleanup {unset foo}
+    -result {1}
+}
+
+test tcltest-21.4 {test command with cleanup failure} {
+    -setup {
+	if {[info exists foo]} {
+	    unset foo
+	}
+	set fail $::tcltest::currentFailure
+	set v [verbose]
+    }
+    -body {
+	verbose {}
+	test tcltest-21.4.0 {foo-1} {
+	    -cleanup {unset foo}
+	}
+    }
+    -result {^$}
+    -match regexp
+    -cleanup {verbose $v; set ::tcltest::currentFailure $fail}
+    -output "Test cleanup failed:.*can't unset \"foo\": no such variable"
+}
+
+test tcltest-21.5 {test command with setup failure} {
+    -setup {
+	if {[info exists foo]} {
+	    unset foo
+	}
+	set fail $::tcltest::currentFailure
+    }
+    -body {
+	test tcltest-21.5.0 {foo-2} {
+	    -setup {unset foo}
+	}
+    }
+    -result {^$}
+    -match regexp
+    -cleanup {set ::tcltest::currentFailure $fail}
+    -output "Test setup failed:.*can't unset \"foo\": no such variable"
+}
+
+test tcltest-21.6 {test command - setup occurs before cleanup & before script} {
+    -setup {set v [verbose]; set fail $::tcltest::currentFailure}
+    -body {
+	verbose {}
+	test tcltest-21.6.0 {foo-3} {
+	    -setup {
+		if {[info exists foo]} {
+		    unset foo
+		}
+		set foo 1
+		set expected 2
+	    }
+	    -body {
+		incr foo
+		set foo
+	    }
+	    -cleanup {
+		if {$foo != 2} {
+		    puts [outputChannel] "foo is wrong"
+		} else {
+		    puts [outputChannel] "foo is 2"
+		}
+	    }
+	    -result {$expected}
+	}
+    }
+    -cleanup {verbose $v; set ::tcltest::currentFailure $fail}
+    -result {^$}
+    -match regexp
+    -output "foo is 2"
+}
+
+test tcltest-21.7 {test command - bad flag} {
+    -setup {set fail $::tcltest::currentFailure}
+    -cleanup {set ::tcltest::currentFailure $fail}
+    -body {
+	test tcltest-21.7.0 {foo-4} {
+	    -foobar {}
+	}
+    }
+    -returnCodes 1
+    -result {bad option "-foobar": must be -body, -cleanup, -constraints, -errorOutput, -match, -output, -result, -returnCodes, or -setup}
+}
+
+# alternate test command format (these are the same as 21.1-21.6, with the
+# exception of being in the all-inline format)
+
+test tcltest-21.7a {expect with glob} \
+	-body {list a b c d e} \
+	-result {[ab] b c d e} \
+	-match glob
+
+test tcltest-21.8 {force a test command failure} \
+    -setup {set fail $::tcltest::currentFailure} \
+    -body {
+        test tcltest-21.8.0 {
+            return 2
+        } {1}
+    } \
+    -returnCodes 1 \
+    -cleanup {set ::tcltest::currentFailure $fail} \
+    -result {bad option "1": must be -body, -cleanup, -constraints, -errorOutput, -match, -output, -result, -returnCodes, or -setup}
+
+test tcltest-21.9 {test command with setup} \
+	-setup {set foo 1} \
+	-body {set foo} \
+	-cleanup {unset foo} \
+	-result {1}
+
+test tcltest-21.10 {test command with cleanup failure} -setup {
+    if {[info exists foo]} {
+	unset foo
+    }
+    set fail $::tcltest::currentFailure
+    set v [verbose]
+} -cleanup {
+    verbose $v
+    set ::tcltest::currentFailure $fail
+} -body {
+    verbose {}
+    test tcltest-21.10.0 {foo-1} -cleanup {unset foo}
+} -result {^$} -match regexp \
+	-output {Test cleanup failed:.*can't unset \"foo\": no such variable}
+
+test tcltest-21.11 {test command with setup failure} -setup {
+    if {[info exists foo]} {
+	unset foo
+    }
+    set fail $::tcltest::currentFailure
+} -cleanup {set ::tcltest::currentFailure $fail} -body {
+    test tcltest-21.11.0 {foo-2} -setup {unset foo}
+} -result {^$} -output {Test setup failed:.*can't unset \"foo\": no such variable} -match regexp
+
+test tcltest-21.12 {
+	test command - setup occurs before cleanup & before script
+} -setup {
+	set fail $::tcltest::currentFailure
+	set v [verbose]
+} -cleanup {
+	verbose $v
+	set ::tcltest::currentFailure $fail
+} -body {
+    verbose {}
+    test tcltest-21.12.0 {foo-3} -setup {
+	if {[info exists foo]} {
+	    unset foo
+	}
+	set foo 1
+	set expected 2
+    }  -body {
+	incr foo
+	set foo
+    }  -cleanup {
+	if {$foo != 2} {
+	    puts [outputChannel] "foo is wrong"
+	} else {
+	    puts [outputChannel] "foo is 2"
+	}
+    }  -result {$expected}
+} -result {^$} -output {foo is 2} -match regexp
+
+# test all.tcl usage (runAllTests); simulate .test file failure, as well as
+# crashes to determine whether or not these errors are logged.
+
+set atd [makeDirectory alltestdir]
+makeFile {
+    package require tcltest
+    namespace import -force tcltest::*
+    testsDirectory [file join [temporaryDirectory] alltestdir]
+    runAllTests
+} all.tcl $atd
+makeFile {
+    exit 1
+} exit.test $atd
+makeFile {
+    error "throw an error"
+} error.test $atd
+makeFile {
+    package require tcltest
+    namespace import -force tcltest::*
+    test foo-1.1 {foo} {
+	-body { return 1 }
+	-result {1}
+    }
+    cleanupTests
+} test.test $atd
+
+# Must use a child process because stdout/stderr parsing can't be
+# duplicated in slave interp.
+test tcltest-22.1 {runAllTests} {
+    -constraints {unixOrPc}
+    -body {
+	exec [interpreter] \
+		[file join $atd all.tcl] \
+		-verbose t -tmpdir [temporaryDirectory]
+    }
+    -match regexp
+    -result "Test files exiting with errors:.*error.test.*exit.test"
+}
+removeDirectory alltestdir
+
+# makeFile, removeFile, makeDirectory, removeDirectory, viewFile
+test tcltest-23.1 {makeFile} {
+    -setup {
+	set mfdir [file join [temporaryDirectory] mfdir]
+	file mkdir $mfdir
+    }
+    -body {
+	makeFile {} t1.tmp
+	makeFile {} et1.tmp $mfdir
+	list [file exists [file join [temporaryDirectory] t1.tmp]] \
+		[file exists [file join $mfdir et1.tmp]]
+    }
+    -cleanup {
+	file delete -force $mfdir \
+		[file join [temporaryDirectory] t1.tmp]
+    }
+    -result {1 1}
+}
+test tcltest-23.2 {removeFile} {
+    -setup {
+	set mfdir [file join [temporaryDirectory] mfdir]
+	file mkdir $mfdir
+	makeFile {} t1.tmp
+	makeFile {} et1.tmp $mfdir
+	if  {![file exists [file join [temporaryDirectory] t1.tmp]] || \
+		![file exists [file join $mfdir et1.tmp]]} {
+	    error "file creation didn't work"
+	}
+    }
+    -body {
+	removeFile t1.tmp
+	removeFile et1.tmp $mfdir
+	list [file exists [file join [temporaryDirectory] t1.tmp]] \
+		[file exists [file join $mfdir et1.tmp]]
+    }
+    -cleanup {
+	file delete -force $mfdir \
+		[file join [temporaryDirectory] t1.tmp]
+    }
+    -result {0 0}
+}
+test tcltest-23.3 {makeDirectory} {
+    -body {
+	set mfdir [file join [temporaryDirectory] mfdir]
+	file mkdir $mfdir
+	makeDirectory d1
+	makeDirectory d2 $mfdir
+	list [file exists [file join [temporaryDirectory] d1]] \
+		[file exists [file join $mfdir d2]]
+    }
+    -cleanup {
+	file delete -force [file join [temporaryDirectory] d1] $mfdir
+    }
+    -result {1 1}
+}
+test tcltest-23.4 {removeDirectory} {
+    -setup {
+	set mfdir [makeDirectory mfdir]
+	makeDirectory t1
+	makeDirectory t2 $mfdir
+	if {![file exists $mfdir] || \
+		![file exists [file join [temporaryDirectory] $mfdir t2]]} {
+	    error "setup failed - directory not created"
+	}
+    }
+    -body {
+	removeDirectory t1
+	removeDirectory t2 $mfdir
+	list [file exists [file join [temporaryDirectory] t1]] \
+		[file exists [file join $mfdir t2]]
+    }
+    -result {0 0}
+}
+test tcltest-23.5 {viewFile} {
+    -body {
+	set mfdir [file join [temporaryDirectory] mfdir]
+	file mkdir $mfdir
+	makeFile {foobar} t1.tmp
+	makeFile {foobarbaz} t2.tmp $mfdir
+	list [viewFile t1.tmp] [viewFile t2.tmp $mfdir]
+    }
+    -result {foobar foobarbaz}
+    -cleanup {
+	file delete -force $mfdir
+	removeFile t1.tmp
+    }
+}
+
+# customMatch
+proc matchNegative { expected actual } {
+   set match 0
+   foreach a $actual e $expected {
+      if { $a != $e } {
+         set match 1
+        break
+      }
+   }
+   return $match
+}
+
+test tcltest-24.0 {
+	customMatch: syntax
+} -body {
+	list [catch {customMatch} result] $result
+} -result [list 1 "wrong # args: should be \"customMatch mode script\""]
+
+test tcltest-24.1 {
+	customMatch: syntax
+} -body {
+	list [catch {customMatch foo} result] $result
+} -result [list 1 "wrong # args: should be \"customMatch mode script\""]
+
+test tcltest-24.2 {
+	customMatch: syntax
+} -body {
+	list [catch {customMatch foo bar baz} result] $result
+} -result [list 1 "wrong # args: should be \"customMatch mode script\""]
+
+test tcltest-24.3 {
+	customMatch: argument checking
+} -body {
+	list [catch {customMatch bad "a \{ b"} result] $result
+} -result [list 1 "invalid customMatch script; can't evaluate after completion"]
+
+test tcltest-24.4 {
+	test: valid -match values
+} -body {
+	list [catch {
+		test tcltest-24.4.0 {} \
+			-match [namespace current]::noSuchMode
+	} result] $result
+} -match glob -result {1 *bad -match value*}
+
+test tcltest-24.5 {
+	test: valid -match values
+} -setup {
+	customMatch [namespace current]::alwaysMatch "format 1 ;#"
+} -body {
+	list [catch {
+		test tcltest-24.5.0 {} \
+			-match [namespace current]::noSuchMode
+	} result] $result
+} -match glob -result {1 *bad -match value*: must be *alwaysMatch,*}
+
+test tcltest-24.6 {
+	customMatch: -match script that always matches
+} -setup {
+	customMatch [namespace current]::alwaysMatch "format 1 ;#"
+	set v [verbose]
+} -body {
+	verbose {}
+	test tcltest-24.6.0 {} -match [namespace current]::alwaysMatch \
+		-body {format 1} -result 0
+} -cleanup {
+	verbose $v
+} -result {} -output {} -errorOutput {}
+
+test tcltest-24.7 {
+	customMatch: replace default -exact matching
+} -setup {
+	set saveExactMatchScript $::tcltest::CustomMatch(exact)
+	customMatch exact "format 1 ;#"
+	set v [verbose]
+} -body {
+	verbose {}
+	test tcltest-24.7.0 {} -body {format 1} -result 0
+} -cleanup {
+	verbose $v
+	customMatch exact $saveExactMatchScript
+	unset saveExactMatchScript
+} -result {} -output {}
+
+test tcltest-24.9 {
+	customMatch: error during match
+} -setup {
+	proc errorDuringMatch args {return -code error "match returned error"}
+	customMatch [namespace current]::errorDuringMatch \
+		[namespace code errorDuringMatch]
+	set v [verbose]
+	set fail $::tcltest::currentFailure
+} -body {
+	verbose {}
+	test tcltest-24.9.0 {} -match [namespace current]::errorDuringMatch
+} -cleanup {
+	verbose $v
+	set ::tcltest::currentFailure $fail
+} -match glob -result {} -output {*FAILED*match returned error*}
+
+test tcltest-24.10 {
+	customMatch: bad return from match command
+} -setup {
+	proc nonBooleanReturn args {return foo}
+	customMatch nonBooleanReturn [namespace code nonBooleanReturn]
+	set v [verbose]
+	set fail $::tcltest::currentFailure
+} -body {
+	verbose {}
+	test tcltest-24.10.0 {} -match nonBooleanReturn
+} -cleanup {
+	verbose $v
+	set ::tcltest::currentFailure $fail
+} -match glob -result {} -output {*FAILED*expected boolean value*}
+
+test tcltest-24.11 {
+	test: -match exact
+} -body {
+	set result {A B C}
+} -match exact -result {A B C}
+
+test tcltest-24.12 {
+	test: -match exact	match command eval in ::, not caller namespace
+} -setup {
+	set saveExactMatchScript $::tcltest::CustomMatch(exact)
+	customMatch exact [list string equal]
+	set v [verbose]
+	proc string args {error {called [string] in caller namespace}}
+} -body {
+	verbose {}
+	test tcltest-24.12.0 {} -body {format 1} -result 1
+} -cleanup {
+	rename string {}
+	verbose $v
+	customMatch exact $saveExactMatchScript
+	unset saveExactMatchScript
+} -match exact -result {} -output {}
+
+test tcltest-24.13 {
+	test: -match exact	failure
+} -setup {
+	set saveExactMatchScript $::tcltest::CustomMatch(exact)
+	customMatch exact [list string equal]
+	set v [verbose]
+	set fail $::tcltest::currentFailure
+} -body {
+	verbose {}
+	test tcltest-24.13.0 {} -body {format 1} -result 0
+} -cleanup {
+	set ::tcltest::currentFailure $fail
+	verbose $v
+	customMatch exact $saveExactMatchScript
+	unset saveExactMatchScript
+} -match glob -result {} -output {*FAILED*Result was:
+1*(exact matching):
+0*}
+
+test tcltest-24.14 {
+	test: -match glob
+} -body {
+	set result {A B C}
+} -match glob -result {A B*}
+
+test tcltest-24.15 {
+	test: -match glob	failure
+} -setup {
+	set v [verbose]
+	set fail $::tcltest::currentFailure
+} -body {
+	verbose {}
+	test tcltest-24.15.0 {} -match glob -body {format {A B C}} \
+		-result {A B* }
+} -cleanup {
+	set ::tcltest::currentFailure $fail
+	verbose $v
+} -match glob -result {} -output {*FAILED*Result was:
+*(glob matching):
+*}
+
+test tcltest-24.16 {
+	test: -match regexp
+} -body {
+	set result {A B C}
+} -match regexp -result {A B.*}
+
+test tcltest-24.17 {
+	test: -match regexp	failure
+} -setup {
+	set fail $::tcltest::currentFailure
+	set v [verbose]
+} -body {
+	verbose {}
+	test tcltest-24.17.0 {} -match regexp -body {format {A B C}} \
+		-result {A B.* X}
+} -cleanup {
+	set ::tcltest::currentFailure $fail
+	verbose $v
+} -match glob -result {} -output {*FAILED*Result was:
+*(regexp matching):
+*}
+
+test tcltest-24.18 {
+	test: -match custom	forget namespace qualification
+} -setup {
+	set fail $::tcltest::currentFailure
+	set v [verbose]
+	customMatch negative matchNegative
+} -body {
+	verbose {}
+	test tcltest-24.18.0 {} -match negative -body {format {A B C}} \
+		-result {A B X}
+} -cleanup {
+	set ::tcltest::currentFailure $fail
+	verbose $v
+} -match glob -result {} -output {*FAILED*Error testing result:*}
+
+test tcltest-24.19 {
+	test: -match custom
+} -setup {
+	set v [verbose]
+	customMatch negative [namespace code matchNegative]
+} -body {
+	verbose {}
+	test tcltest-24.19.0 {} -match negative -body {format {A B C}} \
+		-result {A B X}
+} -cleanup {
+	verbose $v
+} -match exact -result {} -output {}
+
+test tcltest-24.20 {
+	test: -match custom	failure
+} -setup {
+	set fail $::tcltest::currentFailure
+	set v [verbose]
+	customMatch negative [namespace code matchNegative]
+} -body {
+	verbose {}
+	test tcltest-24.20.0 {} -match negative -body {format {A B C}} \
+		-result {A B C}
+} -cleanup {
+	set ::tcltest::currentFailure $fail
+	verbose $v
+} -match glob -result {} -output {*FAILED*Result was:
+*(negative matching):
+*}
+
+test tcltest-25.1 {
+	constraint of setup/cleanup (Bug 589859)
+} -setup {
+	set foo 0
+} -body {
+	# Buggy tcltest will generate result of 2
+	test tcltest-25.1.0 {} -constraints knownBug -setup {
+	    incr foo
+	} -body {
+	    incr foo
+	} -cleanup {
+	    incr foo
+	} -match glob -result *
+	set foo
+} -cleanup {
+	unset foo
+} -result 0
+
+test tcltest-25.2 {
+	puts -nonewline (Bug 612786)
+} -body {
+	puts -nonewline stdout bla
+	puts -nonewline stdout bla
+} -output {blabla}
+
+test tcltest-25.3 {
+	reported return code (Bug 611922)
+} -setup {
+	set fail $::tcltest::currentFailure
+	set v [verbose]
+} -body {
+	verbose {}
+	test tcltest-25.3.0 {} -body {
+	    error foo
+	}
+} -cleanup {
+	set ::tcltest::currentFailure $fail
+	verbose $v
+} -match glob -output {*generated error; Return code was: 1*}
+
+test tcltest-26.1 {Bug/RFE 1017151} -setup {
+    makeFile {
+	package require tcltest
+	set ::errorInfo "Should never see this"
+	tcltest::test tcltest-26.1.0 {
+	    no errorInfo when only return code mismatch
+	} -body {
+	    set x 1
+	} -returnCodes error -result 1
+	tcltest::cleanupTests
+    } test.tcl
+} -body {
+    slave msg [file join [temporaryDirectory] test.tcl]
+    return $msg
+} -cleanup {
+    removeFile test.tcl
+} -match glob -result {*
+---- Return code should have been one of: 1
+==== tcltest-26.1.0 FAILED*}
+
+test tcltest-26.2 {Bug/RFE 1017151} -setup {
+    makeFile {
+	package require tcltest
+	set ::errorInfo "Should never see this"
+	tcltest::test tcltest-26.2.0 {do not mask body errorInfo} -body {
+	    error "body error"
+	} -cleanup {
+	    error "cleanup error"
+	} -result 1
+	tcltest::cleanupTests
+    } test.tcl
+} -body {
+    slave msg [file join [temporaryDirectory] test.tcl]
+    return $msg
+} -cleanup {
+    removeFile test.tcl
+} -match glob -result {*
+---- errorInfo: body error
+*
+---- errorInfo(cleanup): cleanup error*}
+
+cleanupTests
+}
+
+namespace delete ::tcltest::test
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/tests/thread.test b/tests/thread.test
new file mode 100644
index 0000000..cc4c871
--- /dev/null
+++ b/tests/thread.test
@@ -0,0 +1,1443 @@
+# Commands covered:  (test)thread
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands.  Sourcing this file into Tcl runs the tests and
+# generates output for errors.  No output means no errors were found.
+#
+# Copyright (c) 1996 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+# Copyright (c) 2006-2008 by Joe Mistachkin.  All rights reserved.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+    package require tcltest 2.2
+    namespace import -force ::tcltest::*
+}
+
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
+
+# Some tests require the testthread command
+
+testConstraint testthread [expr {[info commands testthread] != {}}]
+
+# Some tests require the Thread package
+
+testConstraint thread [expr {0 == [catch {package require Thread 2.7-}]}]
+
+# Some tests may not work under valgrind
+
+testConstraint notValgrind [expr {![testConstraint valgrind]}]
+
+set threadSuperKillScript {
+    rename catch ""
+    rename while ""
+    rename unknown ""
+    rename update ""
+    thread::release
+}
+
+proc getThreadErrorFromInfo { info } {
+    set list [split $info \n]
+    set idx [lsearch -glob $list "*eval*unwound*"]
+    if {$idx != -1} then {
+        return [lindex $list $idx]
+    }
+    set idx [lsearch -glob $list "*eval*canceled*"]
+    if {$idx != -1} then {
+        return [lindex $list $idx]
+    }
+    return ""; # some other error we do not care about.
+}
+
+proc findThreadError { info } {
+    foreach error [lreverse $info] {
+        set error [getThreadErrorFromInfo $error]
+        if {[string length $error] > 0} then {
+            return $error
+        }
+    }
+    return ""; # some other error we do not care about.
+}
+
+proc ThreadError {id info} {
+    global threadSawError
+    if {[string length [getThreadErrorFromInfo $info]] > 0} then {
+        global threadId threadError
+        set threadId $id
+        lappend threadError($id) $info
+    }
+    set threadSawError($id) true; # signal main thread to exit [vwait].
+}
+
+if {[testConstraint thread]} {
+    thread::errorproc ThreadError
+}
+
+if {[testConstraint testthread]} {
+    proc drainEventQueue {} {
+	while {[set x [testthread event]]} {
+	    #puts "WARNING: drained $x event(s) on main thread"
+	}
+    }
+
+    testthread errorproc ThreadError
+}
+
+# Some tests require manual draining of the event queue
+
+testConstraint drainEventQueue [expr {[info commands drainEventQueue] != {}}]
+
+test thread-1.3 {Tcl_ThreadObjCmd: initial thread list} {thread} {
+    llength [thread::names]
+} 1
+test thread-1.4 {Tcl_ThreadObjCmd: thread create } {thread} {
+    set serverthread [thread::create -preserved]
+    set numthreads [llength [thread::names]]
+    thread::release $serverthread
+    set numthreads
+} {2}
+test thread-1.5 {Tcl_ThreadObjCmd: thread create one shot} {thread} {
+    thread::create {set x 5}
+    foreach try {0 1 2 4 5 6} {
+	# Try various ways to yield
+	update
+	after 10
+	set l [llength [thread::names]]
+	if {$l == 1} {
+	    break
+	}
+    }
+    set l
+} {1}
+test thread-1.6 {Tcl_ThreadObjCmd: thread exit} {thread} {
+    thread::create {{*}{}}
+    update
+    after 10
+    llength [thread::names]
+} {1}
+test thread-1.13 {Tcl_ThreadObjCmd: send args} {thread} {
+    set serverthread [thread::create -preserved]
+    set five [thread::send $serverthread {set x 5}]
+    thread::release $serverthread
+    set five
+} 5
+test thread-1.15 {Tcl_ThreadObjCmd: wait} {thread} {
+    set serverthread [thread::create -preserved {set z 5 ; thread::wait}]
+    set five [thread::send $serverthread {set z}]
+    thread::release $serverthread
+    set five
+} 5
+
+# The tests above also cover:
+# TclCreateThread, except when pthread_create fails
+# NewThread, safe and regular
+# ThreadErrorProc, except for printing to standard error
+
+test thread-2.1 {ListUpdateInner and ListRemove} {thread} {
+    catch {unset tid}
+    foreach t {0 1 2} {
+	upvar #0 t$t tid
+	set tid [thread::create -preserved]
+    }
+    foreach t {0 1 2} {
+	upvar #0 t$t tid
+	thread::release $tid
+    }
+    llength [thread::names]
+} 1
+
+test thread-3.1 {TclThreadList} {thread} {
+    catch {unset tid}
+    set len [llength [thread::names]]
+    set l1  {}
+    foreach t {0 1 2} {
+	lappend l1 [thread::create -preserved]
+    }
+    set l2 [thread::names]
+    set c [string compare [lsort [concat [thread::id] $l1]] [lsort $l2]]
+    foreach t $l1 {
+	thread::release $t
+    }
+    list $len $c
+} {1 0}
+
+test thread-4.1 {TclThreadSend to self} {thread} {
+    catch {unset x}
+    thread::send [thread::id] {
+	set x 4
+    }
+    set x
+} {4}
+test thread-4.2 {TclThreadSend -async} {thread} {
+    set len [llength [thread::names]]
+    set serverthread [thread::create -preserved]
+    thread::send -async $serverthread {
+	after 1 {thread::release}
+    }
+    set two [llength [thread::names]]
+    after 100 {set done 1}
+    vwait done
+    list $len [llength [thread::names]] $two
+} {1 1 2}
+test thread-4.3 {TclThreadSend preserve errorInfo} {thread} {
+    set len [llength [thread::names]]
+    set serverthread [thread::create -preserved]
+    set x [catch {thread::send $serverthread {set undef}} msg]
+    set savedErrorInfo $::errorInfo
+    thread::release $serverthread
+    list $len $x $msg $savedErrorInfo
+} {1 1 {can't read "undef": no such variable} {can't read "undef": no such variable
+    while executing
+"set undef"
+    invoked from within
+"thread::send $serverthread {set undef}"}}
+test thread-4.4 {TclThreadSend preserve code} {thread} {
+    set len [llength [thread::names]]
+    set serverthread [thread::create -preserved]
+    set ::errorInfo {}
+    set x [catch {thread::send $serverthread {set ::errorInfo {}; break}} msg]
+    set savedErrorInfo $::errorInfo
+    thread::release $serverthread
+    list $len $x $msg $savedErrorInfo
+} {1 3 {} {}}
+test thread-4.5 {TclThreadSend preserve errorCode} {thread} {
+    set serverthread [thread::create]
+    set x [catch {thread::send $serverthread {error ERR INFO CODE}} msg]
+    set savedErrorCode $::errorCode
+    thread::release $serverthread
+    list $x $msg $savedErrorCode
+} {1 ERR CODE}
+
+
+test thread-5.0 {Joining threads} {thread} {
+    set serverthread [thread::create -joinable -preserved]
+    thread::send -async $serverthread {after 1000 ; thread::release}
+    thread::join $serverthread
+} {0}
+test thread-5.1 {Joining threads after the fact} {thread} {
+    set serverthread [thread::create -joinable -preserved]
+    thread::send -async $serverthread {thread::release}
+    after 2000
+    thread::join $serverthread
+} {0}
+test thread-5.2 {Try to join a detached thread} {thread} {
+    set serverthread [thread::create -preserved]
+    thread::send -async $serverthread {after 1000 ; thread::release}
+    catch {set res [thread::join $serverthread]} msg
+    while {[llength [thread::names]] > 1} {
+	after 20
+    }
+    lrange $msg 0 2
+} {cannot join thread}
+
+test thread-6.1 {freeing very large object trees in a thread} thread {
+    # conceptual duplicate of obj-32.1
+    set serverthread [thread::create -preserved]
+    thread::send -async $serverthread {
+	set x {}
+	for {set i 0} {$i<100000} {incr i} {
+	    set x [list $x {}]
+	}
+	unset x
+    }
+    thread::release -wait $serverthread
+} 0
+
+# TIP #285: Script cancellation support
+test thread-7.4 {cancel: pure bytecode loop} -constraints {thread drainEventQueue} -setup {
+    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -body {
+    set serverthread [thread::create -joinable \
+	    [string map [list %ID% [thread::id]] {
+	proc foobar {} {
+	    if {![info exists foo]} then {
+		# signal the primary thread that we are ready
+		# to be canceled now (we are running).
+		thread::send %ID% [list set ::threadIdStarted [thread::id]]
+		set foo 1
+	    }
+	    while {1} {
+		# No bytecode at all here...
+	    }
+	}
+	foobar
+    }]]
+    # wait for other thread to signal "ready to cancel"
+    vwait ::threadIdStarted
+    set res [thread::cancel $serverthread]
+    vwait ::threadSawError($serverthread)
+    thread::join $serverthread; drainEventQueue
+    list $res [expr {$::threadIdStarted == $serverthread}] \
+              [expr {[info exists ::threadId] ? \
+                  $::threadId == $serverthread : 0}] \
+              [expr {[info exists ::threadError($serverthread)] ? \
+                  [findThreadError $::threadError($serverthread)] : ""}]
+} -cleanup {
+    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -result {{} 1 1 {eval canceled}}
+test thread-7.5 {cancel: pure inside-command loop} -constraints {thread drainEventQueue} -setup {
+    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -body {
+    set serverthread [thread::create -joinable \
+	    [string map [list %ID% [thread::id]] {
+	proc foobar {} {
+	    if {![info exists foo]} then {
+		# signal the primary thread that we are ready
+		# to be canceled now (we are running).
+		thread::send %ID% [list set ::threadIdStarted [thread::id]]
+		set foo 1
+	    }
+	    set while while
+	    $while {1} {
+		# No bytecode at all here...
+	    }
+	}
+	foobar
+    }]]
+    # wait for other thread to signal "ready to cancel"
+    vwait ::threadIdStarted
+    set res [thread::cancel $serverthread]
+    vwait ::threadSawError($serverthread)
+    thread::join $serverthread; drainEventQueue
+    list $res [expr {$::threadIdStarted == $serverthread}] \
+              [expr {[info exists ::threadId] ? \
+                  $::threadId == $serverthread : 0}] \
+              [expr {[info exists ::threadError($serverthread)] ? \
+                  [findThreadError $::threadError($serverthread)] : ""}]
+} -cleanup {
+    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -result {{} 1 1 {eval canceled}}
+test thread-7.6 {cancel: pure bytecode loop -unwind} -constraints {thread drainEventQueue} -setup {
+    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -body {
+    set serverthread [thread::create -joinable \
+	    [string map [list %ID% [thread::id]] {
+	proc foobar {} {
+	    if {![info exists foo]} then {
+		# signal the primary thread that we are ready
+		# to be canceled now (we are running).
+		thread::send %ID% [list set ::threadIdStarted [thread::id]]
+		set foo 1
+	    }
+	    while {1} {
+		# No bytecode at all here...
+	    }
+	}
+	foobar
+    }]]
+    # wait for other thread to signal "ready to cancel"
+    vwait ::threadIdStarted
+    set res [thread::cancel -unwind $serverthread]
+    vwait ::threadSawError($serverthread)
+    thread::join $serverthread; drainEventQueue
+    list $res [expr {$::threadIdStarted == $serverthread}] \
+              [expr {[info exists ::threadId] ? \
+                  $::threadId == $serverthread : 0}] \
+              [expr {[info exists ::threadError($serverthread)] ? \
+                  [findThreadError $::threadError($serverthread)] : ""}]
+} -cleanup {
+    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -result {{} 1 1 {eval unwound}}
+test thread-7.7 {cancel: pure inside-command loop -unwind} -constraints {thread drainEventQueue} -setup {
+    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -body {
+    set serverthread [thread::create -joinable \
+	    [string map [list %ID% [thread::id]] {
+	proc foobar {} {
+	    if {![info exists foo]} then {
+		# signal the primary thread that we are ready
+		# to be canceled now (we are running).
+		thread::send %ID% [list set ::threadIdStarted [thread::id]]
+		set foo 1
+	    }
+	    set while while
+	    $while {1} {
+		# No bytecode at all here...
+	    }
+	}
+	foobar
+    }]]
+    # wait for other thread to signal "ready to cancel"
+    vwait ::threadIdStarted
+    set res [thread::cancel -unwind $serverthread]
+    vwait ::threadSawError($serverthread)
+    thread::join $serverthread; drainEventQueue
+    list $res [expr {$::threadIdStarted == $serverthread}] \
+              [expr {[info exists ::threadId] ? \
+                  $::threadId == $serverthread : 0}] \
+              [expr {[info exists ::threadError($serverthread)] ? \
+                  [findThreadError $::threadError($serverthread)] : ""}]
+} -cleanup {
+    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -result {{} 1 1 {eval unwound}}
+test thread-7.8 {cancel: pure bytecode loop custom result} -constraints {thread drainEventQueue} -setup {
+    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -body {
+    set serverthread [thread::create -joinable \
+	    [string map [list %ID% [thread::id]] {
+	proc foobar {} {
+	    if {![info exists foo]} then {
+		# signal the primary thread that we are ready
+		# to be canceled now (we are running).
+		thread::send %ID% [list set ::threadIdStarted [thread::id]]
+		set foo 1
+	    }
+	    while {1} {
+		# No bytecode at all here...
+	    }
+	}
+	foobar
+    }]]
+    # wait for other thread to signal "ready to cancel"
+    vwait ::threadIdStarted
+    set res [thread::cancel $serverthread "the eval was canceled"]
+    vwait ::threadSawError($serverthread)
+    thread::join $serverthread; drainEventQueue
+    list $res [expr {$::threadIdStarted == $serverthread}] \
+              [expr {[info exists ::threadId] ? \
+                  $::threadId == $serverthread : 0}] \
+              [expr {[info exists ::threadError($serverthread)] ? \
+                  [findThreadError $::threadError($serverthread)] : ""}]
+} -cleanup {
+    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -result {{} 1 1 {the eval was canceled}}
+test thread-7.9 {cancel: pure inside-command loop custom result} -constraints {
+    thread
+    drainEventQueue
+} -setup {
+    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -body {
+    set serverthread [thread::create -joinable \
+	    [string map [list %ID% [thread::id]] {
+	proc foobar {} {
+	    if {![info exists foo]} then {
+		# signal the primary thread that we are ready
+		# to be canceled now (we are running).
+		thread::send %ID% [list set ::threadIdStarted [thread::id]]
+		set foo 1
+	    }
+	    set while while
+	    $while {1} {
+		# No bytecode at all here...
+	    }
+	}
+	foobar
+    }]]
+    # wait for other thread to signal "ready to cancel"
+    vwait ::threadIdStarted
+    set res [thread::cancel $serverthread "the eval was canceled"]
+    vwait ::threadSawError($serverthread)
+    thread::join $serverthread; drainEventQueue
+    list $res [expr {$::threadIdStarted == $serverthread}] \
+              [expr {[info exists ::threadId] ? \
+                  $::threadId == $serverthread : 0}] \
+              [expr {[info exists ::threadError($serverthread)] ? \
+                  [findThreadError $::threadError($serverthread)] : ""}]
+} -cleanup {
+    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -result {{} 1 1 {the eval was canceled}}
+test thread-7.10 {cancel: pure bytecode loop custom result -unwind} -constraints {
+    thread
+    drainEventQueue
+} -setup {
+    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -body {
+    set serverthread [thread::create -joinable \
+	    [string map [list %ID% [thread::id]] {
+	proc foobar {} {
+	    if {![info exists foo]} then {
+		# signal the primary thread that we are ready
+		# to be canceled now (we are running).
+		thread::send %ID% [list set ::threadIdStarted [thread::id]]
+		set foo 1
+	    }
+	    while {1} {
+		# No bytecode at all here...
+	    }
+	}
+	foobar
+    }]]
+    # wait for other thread to signal "ready to cancel"
+    vwait ::threadIdStarted
+    set res [thread::cancel -unwind $serverthread "the eval was unwound"]
+    vwait ::threadSawError($serverthread)
+    thread::join $serverthread; drainEventQueue
+    list $res [expr {$::threadIdStarted == $serverthread}] \
+              [expr {[info exists ::threadId] ? \
+                  $::threadId == $serverthread : 0}] \
+              [expr {[info exists ::threadError($serverthread)] ? \
+                  [findThreadError $::threadError($serverthread)] : ""}]
+} -cleanup {
+    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -result {{} 1 1 {the eval was unwound}}
+test thread-7.11 {cancel: pure inside-command loop custom result -unwind} -constraints {
+    thread
+    drainEventQueue
+} -setup {
+    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -body {
+    set serverthread [thread::create -joinable \
+	    [string map [list %ID% [thread::id]] {
+	proc foobar {} {
+	    if {![info exists foo]} then {
+		# signal the primary thread that we are ready
+		# to be canceled now (we are running).
+		thread::send %ID% [list set ::threadIdStarted [thread::id]]
+		set foo 1
+	    }
+	    set while while
+	    $while {1} {
+		# No bytecode at all here...
+	    }
+	}
+	foobar
+    }]]
+    # wait for other thread to signal "ready to cancel"
+    vwait ::threadIdStarted
+    set res [thread::cancel -unwind $serverthread "the eval was unwound"]
+    vwait ::threadSawError($serverthread)
+    thread::join $serverthread; drainEventQueue
+    list $res [expr {$::threadIdStarted == $serverthread}] \
+              [expr {[info exists ::threadId] ? \
+                  $::threadId == $serverthread : 0}] \
+              [expr {[info exists ::threadError($serverthread)] ? \
+                  [findThreadError $::threadError($serverthread)] : ""}]
+} -cleanup {
+    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -result {{} 1 1 {the eval was unwound}}
+test thread-7.12 {cancel: after} -constraints {thread drainEventQueue} -setup {
+    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -body {
+    set serverthread [thread::create -joinable \
+	    [string map [list %ID% [thread::id]] {
+	if {![info exists foo]} then {
+	    # signal the primary thread that we are ready
+	    # to be canceled now (we are running).
+	    thread::send %ID% [list set ::threadIdStarted [thread::id]]
+	    set foo 1
+	}
+	after 30000
+    }]]
+    # wait for other thread to signal "ready to cancel"
+    vwait ::threadIdStarted
+    set res [thread::cancel $serverthread]
+    vwait ::threadSawError($serverthread)
+    thread::join $serverthread; drainEventQueue
+    list $res [expr {$::threadIdStarted == $serverthread}] \
+              [expr {[info exists ::threadId] ? \
+                  $::threadId == $serverthread : 0}] \
+              [expr {[info exists ::threadError($serverthread)] ? \
+                  [findThreadError $::threadError($serverthread)] : ""}]
+} -cleanup {
+    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -result {{} 1 1 {eval canceled}}
+test thread-7.13 {cancel: after -unwind} -constraints {thread drainEventQueue} -setup {
+    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -body {
+    set serverthread [thread::create -joinable \
+	    [string map [list %ID% [thread::id]] {
+	if {![info exists foo]} then {
+	    # signal the primary thread that we are ready
+	    # to be canceled now (we are running).
+	    thread::send %ID% [list set ::threadIdStarted [thread::id]]
+	    set foo 1
+	}
+	after 30000
+    }]]
+    # wait for other thread to signal "ready to cancel"
+    vwait ::threadIdStarted
+    set res [thread::cancel -unwind $serverthread]
+    vwait ::threadSawError($serverthread)
+    thread::join $serverthread; drainEventQueue
+    list $res [expr {$::threadIdStarted == $serverthread}] \
+              [expr {[info exists ::threadId] ? \
+                  $::threadId == $serverthread : 0}] \
+              [expr {[info exists ::threadError($serverthread)] ? \
+                  [findThreadError $::threadError($serverthread)] : ""}]
+} -cleanup {
+    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -result {{} 1 1 {eval unwound}}
+test thread-7.14 {cancel: vwait} -constraints {thread drainEventQueue} -setup {
+    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -body {
+    set serverthread [thread::create -joinable \
+	    [string map [list %ID% [thread::id]] {
+	if {![info exists foo]} then {
+	    # signal the primary thread that we are ready
+	    # to be canceled now (we are running).
+	    thread::send %ID% [list set ::threadIdStarted [thread::id]]
+	    set foo 1
+	}
+	vwait forever
+    }]]
+    # wait for other thread to signal "ready to cancel"
+    vwait ::threadIdStarted
+    set res [thread::cancel $serverthread]
+    vwait ::threadSawError($serverthread)
+    thread::join $serverthread; drainEventQueue
+    list $res [expr {$::threadIdStarted == $serverthread}] \
+              [expr {[info exists ::threadId] ? \
+                  $::threadId == $serverthread : 0}] \
+              [expr {[info exists ::threadError($serverthread)] ? \
+                  [findThreadError $::threadError($serverthread)] : ""}]
+} -cleanup {
+    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -result {{} 1 1 {eval canceled}}
+test thread-7.15 {cancel: vwait -unwind} -constraints {thread drainEventQueue} -setup {
+    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -body {
+    set serverthread [thread::create -joinable \
+	    [string map [list %ID% [thread::id]] {
+	if {![info exists foo]} then {
+	    # signal the primary thread that we are ready
+	    # to be canceled now (we are running).
+	    thread::send %ID% [list set ::threadIdStarted [thread::id]]
+	    set foo 1
+	}
+	vwait forever
+    }]]
+    # wait for other thread to signal "ready to cancel"
+    vwait ::threadIdStarted
+    set res [thread::cancel -unwind $serverthread]
+    vwait ::threadSawError($serverthread)
+    thread::join $serverthread; drainEventQueue
+    list $res [expr {$::threadIdStarted == $serverthread}] \
+              [expr {[info exists ::threadId] ? \
+                  $::threadId == $serverthread : 0}] \
+              [expr {[info exists ::threadError($serverthread)] ? \
+                  [findThreadError $::threadError($serverthread)] : ""}]
+} -cleanup {
+    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -result {{} 1 1 {eval unwound}}
+test thread-7.16 {cancel: expr} -constraints {thread drainEventQueue} -setup {
+    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -body {
+    set serverthread [thread::create -joinable \
+	    [string map [list %ID% [thread::id]] {
+	set i [interp create]
+	$i eval "package require -exact Thread [package present Thread]"
+	$i eval {
+	    if {![info exists foo]} then {
+		# signal the primary thread that we are ready
+		# to be canceled now (we are running).
+
+		thread::send %ID% [list set ::threadIdStarted [thread::id]]
+		set foo 1
+	    }
+	    expr {[while {1} {incr x}]}
+	}
+    }]]
+    # wait for other thread to signal "ready to cancel"
+    vwait ::threadIdStarted
+    set res [thread::cancel $serverthread]
+    vwait ::threadSawError($serverthread)
+    thread::join $serverthread; drainEventQueue
+    list $res [expr {$::threadIdStarted == $serverthread}] \
+              [expr {[info exists ::threadId] ? \
+                  $::threadId == $serverthread : 0}] \
+              [expr {[info exists ::threadError($serverthread)] ? \
+                  [findThreadError $::threadError($serverthread)] : ""}]
+} -cleanup {
+    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -result {{} 1 1 {eval canceled}}
+test thread-7.17 {cancel: expr -unwind} -constraints {thread drainEventQueue} -setup {
+    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -body {
+    set serverthread [thread::create -joinable \
+	    [string map [list %ID% [thread::id]] {
+	set i [interp create]
+	$i eval "package require -exact Thread [package present Thread]"
+	$i eval {
+	    if {![info exists foo]} then {
+		# signal the primary thread that we are ready
+		# to be canceled now (we are running).
+		thread::send %ID% [list set ::threadIdStarted [thread::id]]
+		set foo 1
+	    }
+	    expr {[while {1} {incr x}]}
+	}
+    }]]
+    # wait for other thread to signal "ready to cancel"
+    vwait ::threadIdStarted
+    set res [thread::cancel -unwind $serverthread]
+    vwait ::threadSawError($serverthread)
+    thread::join $serverthread; drainEventQueue
+    list $res [expr {$::threadIdStarted == $serverthread}] \
+              [expr {[info exists ::threadId] ? \
+                  $::threadId == $serverthread : 0}] \
+              [expr {[info exists ::threadError($serverthread)] ? \
+                  [findThreadError $::threadError($serverthread)] : ""}]
+} -cleanup {
+    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -result {{} 1 1 {eval unwound}}
+test thread-7.18 {cancel: expr bignum} {thread drainEventQueue knownBug} {
+    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+    set serverthread [thread::create -joinable \
+	    [string map [list %ID% [thread::id]] {
+        set i [interp create]
+	$i eval "package require -exact Thread [package present Thread]"
+        $i eval {
+            if {![info exists foo]} then {
+                # signal the primary thread that we are ready
+                # to be canceled now (we are running).
+                thread::send %ID% [list set ::threadIdStarted [thread::id]]
+                set foo 1
+            }
+            #
+            # BUGBUG: This will not cancel because libtommath
+            #         does not check Tcl_Canceled.
+            #
+            expr {2**99999}
+        }
+    }]]
+    # wait for other thread to signal "ready to cancel"
+    vwait ::threadIdStarted; after 1000
+    set res [thread::cancel $serverthread]
+    vwait ::threadSawError($serverthread); # WARNING: Never returns (see above).
+    thread::join $serverthread; drainEventQueue; # WARNING: Never returns (see above).
+    list $res [expr {[info exists ::threadIdStarted] ? \
+                  $::threadIdStarted == $serverthread : 0}] \
+              [expr {[info exists ::threadId] ? \
+                  $::threadId == $serverthread : 0}] \
+              [expr {[info exists ::threadError($serverthread)] ? \
+                  [findThreadError $::threadError($serverthread)] : ""}]
+} {{} 1 0 {}}
+test thread-7.19 {cancel: expr bignum -unwind} {thread drainEventQueue knownBug} {
+    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+    set serverthread [thread::create -joinable \
+	    [string map [list %ID% [thread::id]] {
+        set i [interp create]
+	$i eval "package require -exact Thread [package present Thread]"
+        $i eval {
+            if {![info exists foo]} then {
+                # signal the primary thread that we are ready
+                # to be canceled now (we are running).
+                thread::send %ID% [list set ::threadIdStarted [thread::id]]
+                set foo 1
+            }
+            #
+            # BUGBUG: This will not cancel because libtommath
+            #         does not check Tcl_Canceled.
+            #
+            expr {2**99999}
+        }
+    }]]
+    # wait for other thread to signal "ready to cancel"
+    vwait ::threadIdStarted; after 1000
+    set res [thread::cancel -unwind $serverthread]
+    vwait ::threadSawError($serverthread); # WARNING: Never returns (see above).
+    thread::join $serverthread; drainEventQueue; # WARNING: Never returns (see above).
+    list $res [expr {[info exists ::threadIdStarted] ? \
+                  $::threadIdStarted == $serverthread : 0}] \
+              [expr {[info exists ::threadId] ? \
+                  $::threadId == $serverthread : 0}] \
+              [expr {[info exists ::threadError($serverthread)] ? \
+                  [findThreadError $::threadError($serverthread)] : ""}]
+} {{} 1 0 {}}
+test thread-7.20 {cancel: subst} -constraints {thread drainEventQueue} -setup {
+    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -body {
+    set serverthread [thread::create -joinable \
+	    [string map [list %ID% [thread::id]] {
+	set i [interp create]
+	$i eval "package require -exact Thread [package present Thread]"
+	$i eval {
+	    if {![info exists foo]} then {
+		# signal the primary thread that we are ready
+		# to be canceled now (we are running).
+		thread::send %ID% [list set ::threadIdStarted [thread::id]]
+		set foo 1
+	    }
+	    subst {[while {1} {incr x}]}
+	}
+    }]]
+    # wait for other thread to signal "ready to cancel"
+    vwait ::threadIdStarted
+    set res [thread::cancel $serverthread]
+    vwait ::threadSawError($serverthread)
+    thread::join $serverthread; drainEventQueue
+    list $res [expr {$::threadIdStarted == $serverthread}] \
+              [expr {[info exists ::threadId] ? \
+                  $::threadId == $serverthread : 0}] \
+              [expr {[info exists ::threadError($serverthread)] ? \
+                  [findThreadError $::threadError($serverthread)] : ""}]
+} -cleanup {
+    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -result {{} 1 1 {eval canceled}}
+test thread-7.21 {cancel: subst -unwind} -constraints {thread drainEventQueue} -setup {
+    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -body {
+    set serverthread [thread::create -joinable \
+	    [string map [list %ID% [thread::id]] {
+	set i [interp create]
+	$i eval "package require -exact Thread [package present Thread]"
+	$i eval {
+	    if {![info exists foo]} then {
+		# signal the primary thread that we are ready
+		# to be canceled now (we are running).
+		thread::send %ID% [list set ::threadIdStarted [thread::id]]
+		set foo 1
+	    }
+	    subst {[while {1} {incr x}]}
+	}
+    }]]
+    # wait for other thread to signal "ready to cancel"
+    vwait ::threadIdStarted
+    set res [thread::cancel -unwind $serverthread]
+    vwait ::threadSawError($serverthread)
+    thread::join $serverthread; drainEventQueue
+    list $res [expr {$::threadIdStarted == $serverthread}] \
+              [expr {[info exists ::threadId] ? \
+                  $::threadId == $serverthread : 0}] \
+              [expr {[info exists ::threadError($serverthread)] ? \
+                  [findThreadError $::threadError($serverthread)] : ""}]
+} -cleanup {
+    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -result {{} 1 1 {eval unwound}}
+test thread-7.22 {cancel: slave interp} -constraints {thread drainEventQueue} -setup {
+    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -body {
+    set serverthread [thread::create -joinable \
+	    [string map [list %ID% [thread::id]] {
+	set i [interp create]
+	$i eval "package require -exact Thread [package present Thread]"
+	$i eval {
+	    if {![info exists foo]} then {
+		# signal the primary thread that we are ready
+		# to be canceled now (we are running).
+		thread::send %ID% [list set ::threadIdStarted [thread::id]]
+		set foo 1
+	    }
+	    while {1} {}
+	}
+    }]]
+    # wait for other thread to signal "ready to cancel"
+    vwait ::threadIdStarted
+    set res [thread::cancel $serverthread]
+    vwait ::threadSawError($serverthread)
+    thread::join $serverthread; drainEventQueue
+    list $res [expr {$::threadIdStarted == $serverthread}] \
+              [expr {[info exists ::threadId] ? \
+                  $::threadId == $serverthread : 0}] \
+              [expr {[info exists ::threadError($serverthread)] ? \
+                  [findThreadError $::threadError($serverthread)] : ""}]
+} -cleanup {
+    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -result {{} 1 1 {eval canceled}}
+test thread-7.23 {cancel: slave interp -unwind} -constraints {thread drainEventQueue} -setup {
+    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -body {
+    set serverthread [thread::create -joinable \
+	    [string map [list %ID% [thread::id]] {
+	set i [interp create]
+	$i eval "package require -exact Thread [package present Thread]"
+	$i eval {
+	    if {![info exists foo]} then {
+		# signal the primary thread that we are ready
+		# to be canceled now (we are running).
+		thread::send %ID% [list set ::threadIdStarted [thread::id]]
+		set foo 1
+	    }
+	    set while while; $while {1} {}
+	}
+    }]]
+    # wait for other thread to signal "ready to cancel"
+    vwait ::threadIdStarted
+    set res [thread::cancel -unwind $serverthread]
+    vwait ::threadSawError($serverthread)
+    thread::join $serverthread; drainEventQueue
+    list $res [expr {$::threadIdStarted == $serverthread}] \
+              [expr {[info exists ::threadId] ? \
+                  $::threadId == $serverthread : 0}] \
+              [expr {[info exists ::threadError($serverthread)] ? \
+                  [findThreadError $::threadError($serverthread)] : ""}]
+} -cleanup {
+    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -result {{} 1 1 {eval unwound}}
+test thread-7.24 {cancel: nested catch inside pure bytecode loop} {thread drainEventQueue} {
+    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+    set serverthread [thread::create -joinable \
+	    [string map [list %ID% [thread::id]] {
+	proc foobar {} {
+	    while {1} {
+		if {![info exists foo]} then {
+		    # signal the primary thread that we are ready
+		    # to be canceled now (we are running).
+		    thread::send %ID% [list set ::threadIdStarted [thread::id]]
+		    set foo 1
+		}
+		catch {
+		    while {1} {
+			catch {
+			    while {1} {
+				# we must call update here because otherwise
+				# the thread cannot even be forced to exit.
+				update
+			    }
+			}
+		    }
+		}
+	    }
+	}
+	foobar
+    }]]
+    # wait for other thread to signal "ready to cancel"
+    vwait ::threadIdStarted; after 1000
+    set res [thread::cancel $serverthread]
+    thread::send $serverthread $::threadSuperKillScript
+    vwait ::threadSawError($serverthread)
+    thread::join $serverthread; drainEventQueue
+    list $res [expr {[info exists ::threadIdStarted] ? \
+		  $::threadIdStarted == $serverthread : 0}] \
+	      [expr {[info exists ::threadId] ? \
+		  $::threadId == $serverthread : 0}] \
+	      [expr {[info exists ::threadError($serverthread)] ? \
+		  [findThreadError $::threadError($serverthread)] : ""}]
+} {{} 1 0 {}}
+test thread-7.25 {cancel: nested catch inside pure inside-command loop} {thread drainEventQueue} {
+    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+    set serverthread [thread::create -joinable \
+	    [string map [list %ID% [thread::id]] {
+	proc foobar {} {
+	    set catch catch
+	    set while while
+	    $while {1} {
+		if {![info exists foo]} then {
+		    # signal the primary thread that we are ready
+		    # to be canceled now (we are running).
+		    thread::send %ID% [list set ::threadIdStarted [thread::id]]
+		    set foo 1
+		}
+		$catch {
+		    $while {1} {
+			$catch {
+			    $while {1} {
+				# we must call update here because otherwise
+				# the thread cannot even be forced to exit.
+				update
+			    }
+			}
+		    }
+		}
+	    }
+	}
+	foobar
+    }]]
+    # wait for other thread to signal "ready to cancel"
+    vwait ::threadIdStarted; after 1000
+    set res [thread::cancel $serverthread]
+    thread::send $serverthread $::threadSuperKillScript
+    vwait ::threadSawError($serverthread)
+    thread::join $serverthread; drainEventQueue
+    list $res [expr {[info exists ::threadIdStarted] ? \
+		  $::threadIdStarted == $serverthread : 0}] \
+	      [expr {[info exists ::threadId] ? \
+		  $::threadId == $serverthread : 0}] \
+	      [expr {[info exists ::threadError($serverthread)] ? \
+		  [findThreadError $::threadError($serverthread)] : ""}]
+} {{} 1 0 {}}
+test thread-7.26 {cancel: send async cancel bad interp path} {thread drainEventQueue} {
+    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+    set serverthread [thread::create -joinable \
+	[string map [list %ID% [thread::id]] {
+	proc foobar {} {
+	    while {1} {
+		if {![info exists foo]} then {
+		    # signal the primary thread that we are ready
+		    # to be canceled now (we are running).
+		    thread::send %ID% [list set ::threadIdStarted [thread::id]]
+		    set foo 1
+		}
+		update
+	    }
+	}
+	foobar
+    }]]
+    # wait for other thread to signal "ready to cancel"
+    vwait ::threadIdStarted
+    catch {thread::send $serverthread {interp cancel -- bad}} msg
+    thread::send -async $serverthread {interp cancel -unwind}
+    vwait ::threadSawError($serverthread)
+    thread::join $serverthread; drainEventQueue
+    list [expr {$::threadIdStarted == $serverthread}] $msg
+} {1 {could not find interpreter "bad"}}
+test thread-7.27 {cancel: send async cancel -- switch} -constraints {thread drainEventQueue} -setup {
+    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -body {
+    set serverthread [thread::create -joinable \
+	    [string map [list %ID% [thread::id]] {
+	set i [interp create -- -unwind]
+	$i eval "package require -exact Thread [package present Thread]"
+	$i eval {
+	    proc foobar {} {
+		while {1} {
+		    if {![info exists foo]} then {
+			# signal the primary thread that we are ready
+			# to be canceled now (we are running).
+			thread::send %ID% [list set ::threadIdStarted [thread::id]]
+			set foo 1
+		    }
+		    update
+		}
+	    }
+	    foobar
+	}
+    }]]
+    # wait for other thread to signal "ready to cancel"
+    vwait ::threadIdStarted
+    set res [thread::send -async $serverthread {interp cancel -- -unwind}]
+    vwait ::threadSawError($serverthread)
+    thread::join $serverthread; drainEventQueue
+    list $res [expr {$::threadIdStarted == $serverthread}] \
+              [expr {[info exists ::threadId] ? \
+                  $::threadId == $serverthread : 0}] \
+              [expr {[info exists ::threadError($serverthread)] ? \
+                  [findThreadError $::threadError($serverthread)] : ""}]
+} -cleanup {
+    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -result {{} 1 1 {eval canceled}}
+test thread-7.28 {cancel: send async cancel nested catch inside pure bytecode loop} {thread drainEventQueue} {
+    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+    set serverthread [thread::create -joinable \
+	    [string map [list %ID% [thread::id]] {
+	proc foobar {} {
+	    while {1} {
+		if {![info exists foo]} then {
+		    # signal the primary thread that we are ready
+		    # to be canceled now (we are running).
+		    thread::send %ID% [list set ::threadIdStarted [thread::id]]
+		    set foo 1
+		}
+		catch {
+		    while {1} {
+			catch {
+			    while {1} {
+				# we must call update here because otherwise
+				# the thread cannot even be forced to exit.
+				update
+			    }
+			}
+		    }
+		}
+	    }
+	}
+	foobar
+    }]]
+    # wait for other thread to signal "ready to cancel"
+    vwait ::threadIdStarted; after 1000
+    set res [thread::send -async $serverthread {interp cancel}]
+    thread::send $serverthread $::threadSuperKillScript
+    vwait ::threadSawError($serverthread)
+    thread::join $serverthread; drainEventQueue
+    list $res [expr {[info exists ::threadIdStarted] ? \
+		  $::threadIdStarted == $serverthread : 0}] \
+	      [expr {[info exists ::threadId] ? \
+		  $::threadId == $serverthread : 0}] \
+	      [expr {[info exists ::threadError($serverthread)] ? \
+		  [findThreadError $::threadError($serverthread)] : ""}]
+} {{} 1 1 {eval canceled}}
+test thread-7.29 {cancel: send async cancel nested catch pure inside-command loop} {thread drainEventQueue} {
+    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+    set serverthread [thread::create -joinable \
+	    [string map [list %ID% [thread::id]] {
+	proc foobar {} {
+	    set catch catch
+	    set while while
+	    $while {1} {
+		if {![info exists foo]} then {
+		    # signal the primary thread that we are ready
+		    # to be canceled now (we are running).
+		    thread::send %ID% [list set ::threadIdStarted [thread::id]]
+		    set foo 1
+		}
+		$catch {
+		    $while {1} {
+			$catch {
+			    $while {1} {
+				# we must call update here because otherwise
+				# the thread cannot even be forced to exit.
+				update
+			    }
+			}
+		    }
+		}
+	    }
+	}
+	foobar
+    }]]
+    # wait for other thread to signal "ready to cancel"
+    vwait ::threadIdStarted; after 1000
+    set res [thread::send -async $serverthread {interp cancel}]
+    thread::send $serverthread $::threadSuperKillScript
+    vwait ::threadSawError($serverthread)
+    thread::join $serverthread; drainEventQueue
+    list $res [expr {[info exists ::threadIdStarted] ? \
+		  $::threadIdStarted == $serverthread : 0}] \
+	      [expr {[info exists ::threadId] ? \
+		  $::threadId == $serverthread : 0}] \
+	      [expr {[info exists ::threadError($serverthread)] ? \
+		  [findThreadError $::threadError($serverthread)] : ""}]
+} {{} 1 1 {eval canceled}}
+test thread-7.30 {cancel: send async thread cancel nested catch inside pure bytecode loop} {thread drainEventQueue} {
+    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+    set serverthread [thread::create -joinable \
+	    [string map [list %ID% [thread::id]] {
+	proc foobar {} {
+	    while {1} {
+		if {![info exists foo]} then {
+		    # signal the primary thread that we are ready
+		    # to be canceled now (we are running).
+		    thread::send %ID% [list set ::threadIdStarted [thread::id]]
+		    set foo 1
+		}
+		catch {
+		    while {1} {
+			catch {
+			    while {1} {
+				# we must call update here because otherwise
+				# the thread cannot even be forced to exit.
+				update
+			    }
+			}
+		    }
+		}
+	    }
+	}
+	foobar
+    }]]
+    # wait for other thread to signal "ready to cancel"
+    vwait ::threadIdStarted; after 1000
+    set res [thread::send -async $serverthread {thread::cancel [thread::id]}]
+    thread::send $serverthread $::threadSuperKillScript
+    vwait ::threadSawError($serverthread)
+    thread::join $serverthread; drainEventQueue
+    list $res [expr {[info exists ::threadIdStarted] ? \
+		  $::threadIdStarted == $serverthread : 0}] \
+	      [expr {[info exists ::threadId] ? \
+		  $::threadId == $serverthread : 0}] \
+	      [expr {[info exists ::threadError($serverthread)] ? \
+		  [findThreadError $::threadError($serverthread)] : ""}]
+} {{} 1 1 {eval canceled}}
+test thread-7.31 {cancel: send async thread cancel nested catch pure inside-command loop} {thread drainEventQueue} {
+    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+    set serverthread [thread::create -joinable \
+	    [string map [list %ID% [thread::id]] {
+	proc foobar {} {
+	    set catch catch
+	    set while while
+	    $while {1} {
+		if {![info exists foo]} then {
+		    # signal the primary thread that we are ready
+		    # to be canceled now (we are running).
+		    thread::send %ID% [list set ::threadIdStarted [thread::id]]
+		    set foo 1
+		}
+		$catch {
+		    $while {1} {
+			$catch {
+			    $while {1} {
+				# we must call update here because otherwise
+				# the thread cannot even be forced to exit.
+				update
+			    }
+			}
+		    }
+		}
+	    }
+	}
+	foobar
+    }]]
+    # wait for other thread to signal "ready to cancel"
+    vwait ::threadIdStarted; after 1000
+    set res [thread::send -async $serverthread {thread::cancel [thread::id]}]
+    thread::send $serverthread $::threadSuperKillScript
+    vwait ::threadSawError($serverthread)
+    thread::join $serverthread; drainEventQueue
+    list $res [expr {[info exists ::threadIdStarted] ? \
+		  $::threadIdStarted == $serverthread : 0}] \
+	      [expr {[info exists ::threadId] ? \
+		  $::threadId == $serverthread : 0}] \
+	      [expr {[info exists ::threadError($serverthread)] ? \
+		  [findThreadError $::threadError($serverthread)] : ""}]
+} {{} 1 1 {eval canceled}}
+test thread-7.32 {cancel: nested catch inside pure bytecode loop -unwind} -constraints {thread drainEventQueue} -setup {
+    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -body {
+    set serverthread [thread::create -joinable \
+	    [string map [list %ID% [thread::id]] {
+	proc foobar {} {
+	    while {1} {
+		if {![info exists foo]} then {
+		    # signal the primary thread that we are ready
+		    # to be canceled now (we are running).
+		    thread::send %ID% [list set ::threadIdStarted [thread::id]]
+		    set foo 1
+		}
+		catch {
+		    while {1} {
+			catch {
+			    while {1} {
+				# No bytecode at all here...
+			    }
+			}
+		    }
+		}
+	    }
+	}
+	foobar
+    }]]
+    # wait for other thread to signal "ready to cancel"
+    vwait ::threadIdStarted
+    set res [thread::cancel -unwind $serverthread]
+    vwait ::threadSawError($serverthread)
+    thread::join $serverthread; drainEventQueue
+    list $res [expr {$::threadIdStarted == $serverthread}] \
+              [expr {[info exists ::threadId] ? \
+                  $::threadId == $serverthread : 0}] \
+              [expr {[info exists ::threadError($serverthread)] ? \
+                  [findThreadError $::threadError($serverthread)] : ""}]
+} -cleanup {
+    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -result {{} 1 1 {eval unwound}}
+test thread-7.33 {cancel: nested catch inside pure inside-command loop -unwind} -constraints {thread drainEventQueue} -setup {
+    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -body {
+    set serverthread [thread::create -joinable \
+	    [string map [list %ID% [thread::id]] {
+	proc foobar {} {
+	    set catch catch
+	    set while while
+	    $while {1} {
+		if {![info exists foo]} then {
+		    # signal the primary thread that we are ready
+		    # to be canceled now (we are running).
+		    thread::send %ID% [list set ::threadIdStarted [thread::id]]
+		    set foo 1
+		}
+		$catch {
+		    $while {1} {
+			$catch {
+			    $while {1} {
+				# No bytecode at all here...
+			    }
+			}
+		    }
+		}
+	    }
+	}
+	foobar
+    }]]
+    # wait for other thread to signal "ready to cancel"
+    vwait ::threadIdStarted
+    set res [thread::cancel -unwind $serverthread]
+    vwait ::threadSawError($serverthread)
+    thread::join $serverthread; drainEventQueue
+    list $res [expr {$::threadIdStarted == $serverthread}] \
+              [expr {[info exists ::threadId] ? \
+                  $::threadId == $serverthread : 0}] \
+              [expr {[info exists ::threadError($serverthread)] ? \
+                  [findThreadError $::threadError($serverthread)] : ""}]
+} -cleanup {
+    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -result {{} 1 1 {eval unwound}}
+test thread-7.34 {cancel: send async cancel nested catch inside pure bytecode loop -unwind} -constraints {thread drainEventQueue} -setup {
+    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -body {
+    set serverthread [thread::create -joinable \
+	    [string map [list %ID% [thread::id]] {
+	proc foobar {} {
+	    while {1} {
+		if {![info exists foo]} then {
+		    # signal the primary thread that we are ready
+		    # to be canceled now (we are running).
+		    thread::send %ID% [list set ::threadIdStarted [thread::id]]
+		    set foo 1
+		}
+		catch {
+		    while {1} {
+			catch {
+			    while {1} {
+				# we must call update here because otherwise
+				# the thread cannot even be forced to exit.
+				update
+			    }
+			}
+		    }
+		}
+	    }
+	}
+	foobar
+    }]]
+    # wait for other thread to signal "ready to cancel"
+    vwait ::threadIdStarted
+    set res [thread::send -async $serverthread {interp cancel -unwind}]
+    vwait ::threadSawError($serverthread)
+    thread::join $serverthread; drainEventQueue
+    list $res [expr {$::threadIdStarted == $serverthread}] \
+              [expr {[info exists ::threadId] ? \
+                  $::threadId == $serverthread : 0}] \
+              [expr {[info exists ::threadError($serverthread)] ? \
+                  [findThreadError $::threadError($serverthread)] : ""}]
+} -cleanup {
+    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -result {{} 1 1 {eval unwound}}
+test thread-7.35 {cancel: send async cancel nested catch inside pure inside-command loop -unwind} -constraints {thread drainEventQueue} -setup {
+    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -body {
+    set serverthread [thread::create -joinable \
+	    [string map [list %ID% [thread::id]] {
+	proc foobar {} {
+	    set catch catch
+	    set while while
+	    $while {1} {
+		if {![info exists foo]} then {
+		    # signal the primary thread that we are ready
+		    # to be canceled now (we are running).
+		    thread::send %ID% [list set ::threadIdStarted [thread::id]]
+		    set foo 1
+		}
+		$catch {
+		    $while {1} {
+			$catch {
+			    $while {1} {
+				# we must call update here because otherwise
+				# the thread cannot even be forced to exit.
+				update
+			    }
+			}
+		    }
+		}
+	    }
+	}
+	foobar
+    }]]
+    # wait for other thread to signal "ready to cancel"
+    vwait ::threadIdStarted
+    set res [thread::send -async $serverthread {interp cancel -unwind}]
+    vwait ::threadSawError($serverthread)
+    thread::join $serverthread; drainEventQueue
+    list $res [expr {$::threadIdStarted == $serverthread}] \
+              [expr {[info exists ::threadId] ? \
+                  $::threadId == $serverthread : 0}] \
+              [expr {[info exists ::threadError($serverthread)] ? \
+                  [findThreadError $::threadError($serverthread)] : ""}]
+} -cleanup {
+    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -result {{} 1 1 {eval unwound}}
+test thread-7.36 {cancel: send async thread cancel nested catch inside pure bytecode loop -unwind} -constraints {thread drainEventQueue} -setup {
+    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -body {
+    set serverthread [thread::create -joinable \
+	    [string map [list %ID% [thread::id]] {
+	proc foobar {} {
+	    while {1} {
+		if {![info exists foo]} then {
+		    # signal the primary thread that we are ready
+		    # to be canceled now (we are running).
+		    thread::send %ID% [list set ::threadIdStarted [thread::id]]
+		    set foo 1
+		}
+		catch {
+		    while {1} {
+			catch {
+			    while {1} {
+				# we must call update here because otherwise
+				# the thread cannot even be forced to exit.
+				update
+			    }
+			}
+		    }
+		}
+	    }
+	}
+	foobar
+    }]]
+    # wait for other thread to signal "ready to cancel"
+    vwait ::threadIdStarted
+    set res [thread::send -async $serverthread {thread::cancel -unwind [thread::id]}]
+    vwait ::threadSawError($serverthread)
+    thread::join $serverthread; drainEventQueue
+    list $res [expr {$::threadIdStarted == $serverthread}] \
+              [expr {[info exists ::threadId] ? \
+                  $::threadId == $serverthread : 0}] \
+              [expr {[info exists ::threadError($serverthread)] ? \
+                  [findThreadError $::threadError($serverthread)] : ""}]
+} -cleanup {
+    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -result {{} 1 1 {eval unwound}}
+test thread-7.37 {cancel: send async thread cancel nested catch inside pure inside-command loop -unwind} -constraints {thread drainEventQueue} -setup {
+    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -body {
+    set serverthread [thread::create -joinable \
+	    [string map [list %ID% [thread::id]] {
+	proc foobar {} {
+	    set catch catch
+	    set while while
+	    $while {1} {
+		if {![info exists foo]} then {
+		    # signal the primary thread that we are ready
+		    # to be canceled now (we are running).
+		    thread::send %ID% [list set ::threadIdStarted [thread::id]]
+		    set foo 1
+		}
+		$catch {
+		    $while {1} {
+			$catch {
+			    $while {1} {
+				# we must call update here because otherwise
+				# the thread cannot even be forced to exit.
+				update
+			    }
+			}
+		    }
+		}
+	    }
+	}
+	foobar
+    }]]
+    # wait for other thread to signal "ready to cancel"
+    vwait ::threadIdStarted
+    set res [thread::send -async $serverthread {thread::cancel -unwind [thread::id]}]
+    vwait ::threadSawError($serverthread)
+    thread::join $serverthread; drainEventQueue
+    list $res [expr {$::threadIdStarted == $serverthread}] \
+              [expr {[info exists ::threadId] ? \
+                  $::threadId == $serverthread : 0}] \
+              [expr {[info exists ::threadError($serverthread)] ? \
+                  [findThreadError $::threadError($serverthread)] : ""}]
+} -cleanup {
+    unset -nocomplain ::threadSawError ::threadError ::threadId ::threadIdStarted
+} -result {{} 1 1 {eval unwound}}
+
+test thread-8.1 {threaded fork stress} -constraints {thread} -setup {
+    unset -nocomplain ::threadCount ::execCount ::threads ::thread
+    set ::threadCount 10
+    set ::execCount 10
+} -body {
+    set ::threads [list]
+    for {set i 0} {$i < $::threadCount} {incr i} {
+	lappend ::threads [thread::create -joinable [string map \
+		[list %execCount% $::execCount] {
+	    proc execLs {} {
+		if {$::tcl_platform(platform) eq "windows"} then {
+		    return [exec $::env(COMSPEC) /c DIR]
+		} else {
+		    return [exec /bin/ls]
+		}
+	    }
+	    set j {%execCount%}; while {[incr j -1]} {execLs}
+	}]]
+    }
+    foreach ::thread $::threads {
+	thread::join $::thread
+    }
+} -cleanup {
+    unset -nocomplain ::threadCount ::execCount ::threads ::thread
+} -result {}
+
+# cleanup
+::tcltest::cleanupTests
+return
diff --git a/tests/timer.test b/tests/timer.test
new file mode 100644
index 0000000..ab6efc9
--- /dev/null
+++ b/tests/timer.test
@@ -0,0 +1,605 @@
+# This file contains a collection of tests for the procedures in the
+# file tclTimer.c, which includes the "after" Tcl command.  Sourcing
+# this file into Tcl runs the tests and generates output for errors.
+# No output means no errors were found.
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands.  Sourcing this file into Tcl runs the tests and
+# generates output for errors.  No output means no errors were found.
+#
+# Copyright (c) 1997 by Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+    package require tcltest 2
+    namespace import -force ::tcltest::*
+}
+
+test timer-1.1 {Tcl_CreateTimerHandler procedure} -setup {
+    foreach i [after info] {
+	after cancel $i
+    }
+} -body {
+    set x ""
+    foreach i {100 200 1000 50 150} {
+	after $i lappend x $i
+    }
+    after 200 set done 1
+    vwait done
+    return $x
+} -cleanup {
+    foreach i [after info] {
+	after cancel $i
+    }
+} -result {50 100 150 200}
+
+test timer-2.1 {Tcl_DeleteTimerHandler procedure} -setup {
+    foreach i [after info] {
+	after cancel $i
+    }
+} -body {
+    set x ""
+    foreach i {100 200 1000 50 150} {
+	after $i lappend x $i
+    }
+    after cancel lappend x 150
+    after cancel lappend x 50
+    after 200 set done 1
+    vwait done
+    return $x
+} -result {100 200}
+
+# No tests for Tcl_ServiceTimer or ResetTimer, since it is already tested
+# above.
+
+test timer-3.1 {TimerHandlerEventProc procedure: event masks} {
+    set x start
+    after 100 { set x fired }
+    update idletasks
+    set result $x
+    after 200
+    update
+    lappend result $x
+} {start fired}
+test timer-3.2 {TimerHandlerEventProc procedure: multiple timers} -setup {
+    foreach i [after info] {
+	after cancel $i
+    }
+} -body {
+    foreach i {200 600 1000} {
+	after $i lappend x $i
+    }
+    after 200
+    set result ""
+    set x ""
+    update
+    lappend result $x
+    after 400
+    update
+    lappend result $x
+    after 400
+    update
+    lappend result $x
+} -result {200 {200 600} {200 600 1000}}
+test timer-3.3 {TimerHandlerEventProc procedure: reentrant timer deletion} -setup {
+    foreach i [after info] {
+	after cancel $i
+    }
+} -body {
+    set x {}
+    after 100 lappend x 100
+    set i [after 300 lappend x 300]
+    after 200 after cancel $i
+    after 400
+    update
+    return $x
+} -result 100
+test timer-3.4 {TimerHandlerEventProc procedure: all expired timers fire} -setup {
+    foreach i [after info] {
+	after cancel $i
+    }
+} -body {
+    set x {}
+    after 100 lappend x a
+    after 200 lappend x b
+    after 300 lappend x c
+    after 300
+    vwait x
+    return $x
+} -result {a b c}
+test timer-3.5 {TimerHandlerEventProc procedure: reentrantly added timers don't fire} -setup {
+    foreach i [after info] {
+	after cancel $i
+    }
+} -body {
+    set x {}
+    after 100 {lappend x a; after 0 lappend x b}
+    after 100
+    vwait x
+    return $x
+} -result a
+test timer-3.6 {TimerHandlerEventProc procedure: reentrantly added timers don't fire} -setup {
+    foreach i [after info] {
+	after cancel $i
+    }
+} -body {
+    set x {}
+    after 100 {lappend x a; after 100 lappend x b; after 100}
+    after 100
+    vwait x
+    set result $x
+    vwait x
+    lappend result $x
+} -result {a {a b}}
+
+# No tests for Tcl_DoWhenIdle:  it's already tested by other tests
+# below.
+
+test timer-4.1 {Tcl_CancelIdleCall procedure} -setup {
+    foreach i [after info] {
+	after cancel $i
+    }
+} -body {
+    set x before
+    set y before
+    set z before
+    after idle set x after1
+    after idle set y after2
+    after idle set z after3
+    after cancel set y after2
+    update idletasks
+    list $x $y $z
+} -result {after1 before after3}
+test timer-4.2 {Tcl_CancelIdleCall procedure} -setup {
+    foreach i [after info] {
+	after cancel $i
+    }
+} -body {
+    set x before
+    set y before
+    set z before
+    after idle set x after1
+    after idle set y after2
+    after idle set z after3
+    after cancel set x after1
+    update idletasks
+    list $x $y $z
+} -result {before after2 after3}
+
+test timer-5.1 {Tcl_ServiceIdle, self-rescheduling handlers} -setup {
+    foreach i [after info] {
+	after cancel $i
+    }
+} -body {
+    set x 1
+    set y 23
+    after idle {incr x; after idle {incr x; after idle {incr x}}}
+    after idle {incr y}
+    vwait x
+    set result "$x $y"
+    update idletasks
+    lappend result $x
+} -result {2 24 4}
+
+test timer-6.1 {Tcl_AfterCmd procedure, basics} -returnCodes error -body {
+    after
+} -result {wrong # args: should be "after option ?arg ...?"}
+test timer-6.2 {Tcl_AfterCmd procedure, basics} -returnCodes error -body {
+    after 2x
+} -result {bad argument "2x": must be cancel, idle, info, or an integer}
+test timer-6.3 {Tcl_AfterCmd procedure, basics} -returnCodes error -body {
+    after gorp
+} -result {bad argument "gorp": must be cancel, idle, info, or an integer}
+test timer-6.4 {Tcl_AfterCmd procedure, ms argument} {
+    set x before
+    after 400 {set x after}
+    after 200
+    update
+    set y $x
+    after 400
+    update
+    list $y $x
+} {before after}
+test timer-6.5 {Tcl_AfterCmd procedure, ms argument} {
+    set x before
+    after 300 set x after
+    after 200
+    update
+    set y $x
+    after 200
+    update
+    list $y $x
+} {before after}
+test timer-6.6 {Tcl_AfterCmd procedure, cancel option} -body {
+    after cancel
+} -returnCodes error -result {wrong # args: should be "after cancel id|command"}
+test timer-6.7 {Tcl_AfterCmd procedure, cancel option} {
+    after cancel after#1
+} {}
+test timer-6.8 {Tcl_AfterCmd procedure, cancel option} {
+    after cancel {foo bar}
+} {}
+test timer-6.9 {Tcl_AfterCmd procedure, cancel option} -setup {
+    foreach i [after info] {
+	after cancel $i
+    }
+} -body {
+    set x before
+    set y [after 100 set x after]
+    after cancel $y
+    after 200
+    update
+    return $x
+} -result {before}
+test timer-6.10 {Tcl_AfterCmd procedure, cancel option} -setup {
+    foreach i [after info] {
+	after cancel $i
+    }
+} -body {
+    set x before
+    after 100 set x after
+    after cancel {set x after}
+    after 200
+    update
+    return $x
+} -result {before}
+test timer-6.11 {Tcl_AfterCmd procedure, cancel option} -setup {
+    foreach i [after info] {
+	after cancel $i
+    }
+} -body {
+    set x before
+    after 100 set x after
+    set id [after 300 set x after]
+    after cancel $id
+    after 200
+    update
+    set y $x
+    set x cleared
+    after 200
+    update
+    list $y $x
+} -result {after cleared}
+test timer-6.12 {Tcl_AfterCmd procedure, cancel option} -setup {
+    foreach i [after info] {
+	after cancel $i
+    }
+} -body {
+    set x first
+    after idle lappend x second
+    after idle lappend x third
+    set i [after idle lappend x fourth]
+    after cancel {lappend x second}
+    after cancel $i
+    update idletasks
+    return $x
+} -result {first third}
+test timer-6.13 {Tcl_AfterCmd procedure, cancel option, multiple arguments for command} -setup {
+    foreach i [after info] {
+	after cancel $i
+    }
+} -body {
+    set x first
+    after idle lappend x second
+    after idle lappend x third
+    set i [after idle lappend x fourth]
+    after cancel lappend x second
+    after cancel $i
+    update idletasks
+    return $x
+} -result {first third}
+test timer-6.14 {Tcl_AfterCmd procedure, cancel option, cancel during handler, used to dump core} -setup {
+    foreach i [after info] {
+	after cancel $i
+    }
+} -body {
+    set id [
+	after 100 {
+	    set x done
+	    after cancel $id
+	}
+    ]
+    vwait x
+} -result {}
+test timer-6.15 {Tcl_AfterCmd procedure, cancel option, multiple interps} -setup {
+    foreach i [after info] {
+	after cancel $i
+    }
+} -body {
+    interp create x
+    x eval {set a before; set b before; after idle {set a a-after};
+	    after idle {set b b-after}}
+    set result [llength [x eval after info]]
+    lappend result [llength [after info]]
+    after cancel {set b b-after}
+    set a aaa
+    set b bbb
+    x eval {after cancel set a a-after}
+    update idletasks
+    lappend result $a $b [x eval {list $a $b}]
+} -cleanup {
+    interp delete x
+} -result {2 0 aaa bbb {before b-after}}
+test timer-6.16 {Tcl_AfterCmd procedure, idle option} -body {
+    after idle
+} -returnCodes error -result {wrong # args: should be "after idle script ?script ...?"}
+test timer-6.17 {Tcl_AfterCmd procedure, idle option} {
+    set x before
+    after idle {set x after}
+    set y $x
+    update idletasks
+    list $y $x
+} {before after}
+test timer-6.18 {Tcl_AfterCmd procedure, idle option} {
+    set x before
+    after idle set x after
+    set y $x
+    update idletasks
+    list $y $x
+} {before after}
+
+set event1 [after idle event 1]
+set event2 [after 1000 event 2]
+interp create x
+set childEvent [x eval {after idle event in child}]
+test timer-6.19 {Tcl_AfterCmd, info option} {
+    lsort [after info]
+} [lsort "$event1 $event2"]
+test timer-6.20 {Tcl_AfterCmd, info option} -returnCodes error -body {
+    after info a b
+} -result {wrong # args: should be "after info ?id?"}
+test timer-6.21 {Tcl_AfterCmd, info option} -returnCodes error -body {
+    after info $childEvent
+} -result "event \"$childEvent\" doesn't exist"
+test timer-6.22 {Tcl_AfterCmd, info option} {
+    list [after info $event1] [after info $event2]
+} {{{event 1} idle} {{event 2} timer}}
+after cancel $event1
+after cancel $event2
+interp delete x
+
+test timer-6.23 {Tcl_AfterCmd procedure, no option, script with NUL} -setup {
+    foreach i [after info] {
+	after cancel $i
+    }
+} -body {
+    set x "hello world"
+    after 1 "set x ab\0cd"
+    after 10
+    update
+    string length $x
+} -result {5}
+test timer-6.24 {Tcl_AfterCmd procedure, no option, script with NUL} -setup {
+    foreach i [after info] {
+	after cancel $i
+    }
+} -body {
+    set x "hello world"
+    after 1 set x ab\0cd
+    after 10
+    update
+    string length $x
+} -result {5}
+test timer-6.25 {Tcl_AfterCmd procedure, cancel option, script with NUL} -setup {
+    foreach i [after info] {
+	after cancel $i
+    }
+} -body {
+    set x "hello world"
+    after 1 set x ab\0cd
+    after cancel "set x ab\0ef"
+    llength [after info]
+} -cleanup {
+    foreach i [after info] {
+	after cancel $i
+    }
+} -result {1}
+test timer-6.26 {Tcl_AfterCmd procedure, cancel option, script with NUL} -setup {
+    foreach i [after info] {
+	after cancel $i
+    }
+} -body {
+    set x "hello world"
+    after 1 set x ab\0cd
+    after cancel set x ab\0ef
+    llength [after info]
+} -cleanup {
+    foreach i [after info] {
+	after cancel $i
+    }
+} -result {1}
+test timer-6.27 {Tcl_AfterCmd procedure, idle option, script with NUL} -setup {
+    foreach i [after info] {
+	after cancel $i
+    }
+} -body {
+    set x "hello world"
+    after idle "set x ab\0cd"
+    update
+    string length $x
+} -result {5}
+test timer-6.28 {Tcl_AfterCmd procedure, idle option, script with NUL} -setup {
+    foreach i [after info] {
+	after cancel $i
+    }
+} -body {
+    set x "hello world"
+    after idle set x ab\0cd
+    update
+    string length $x
+} -result {5}
+test timer-6.29 {Tcl_AfterCmd procedure, info option, script with NUL} -setup {
+    foreach i [after info] {
+	after cancel $i
+    }
+} -body {
+    set x "hello world"
+    set id junk
+    set id [after 10 set x ab\0cd]
+    update
+    string length [lindex [lindex [after info $id] 0] 2]
+} -cleanup {
+    foreach i [after info] {
+	after cancel $i
+    }
+} -result 5
+
+set event [after idle foo bar]
+scan $event after#%d lastId
+test timer-7.1 {GetAfterEvent procedure} -returnCodes error -body {
+    after info xfter#$lastId
+} -result "event \"xfter#$lastId\" doesn't exist"
+test timer-7.2 {GetAfterEvent procedure} -returnCodes error -body {
+    after info afterx$lastId
+} -result "event \"afterx$lastId\" doesn't exist"
+test timer-7.3 {GetAfterEvent procedure} -returnCodes error -body {
+    after info after#ab
+} -result {event "after#ab" doesn't exist}
+test timer-7.4 {GetAfterEvent procedure} -returnCodes error -body {
+    after info after#
+} -result {event "after#" doesn't exist}
+test timer-7.5 {GetAfterEvent procedure} -returnCodes error -body {
+    after info after#${lastId}x
+} -result "event \"after#${lastId}x\" doesn't exist"
+test timer-7.6 {GetAfterEvent procedure} -returnCodes error -body {
+    after info afterx[expr {$lastId+1}]
+} -result "event \"afterx[expr {$lastId+1}]\" doesn't exist"
+after cancel $event
+
+test timer-8.1 {AfterProc procedure} {
+    set x before
+    proc foo {} {
+	set x untouched
+	after 100 {set x after}
+	after 200
+	update
+	return $x
+    }
+    list [foo] $x
+} {untouched after}
+test timer-8.2 {AfterProc procedure} -setup {
+    variable x empty
+    proc myHandler {msg options} {
+	variable x [list $msg [dict get $options -errorinfo]]
+    }
+    set handler [interp bgerror {}]
+    interp bgerror {} [namespace which myHandler]
+} -body {
+    after 100 {error "After error"}
+    after 200
+    set y $x
+    update
+    list $y $x
+} -cleanup {
+    interp bgerror {} $handler
+} -result {empty {{After error} {After error
+    while executing
+"error "After error""
+    ("after" script)}}}
+test timer-8.3 {AfterProc procedure, deleting handler from itself} -setup {
+    foreach i [after info] {
+	after cancel $i
+    }
+} -body {
+    proc foo {} {
+	global x
+	set x {}
+	foreach i [after info] {
+	    lappend x [after info $i]
+	}
+	after cancel foo
+    }
+    after idle foo
+    after 1000 {error "I shouldn't ever have executed"}
+    update idletasks
+    return $x
+} -result {{{error "I shouldn't ever have executed"} timer}}
+test timer-8.4 {AfterProc procedure, deleting handler from itself} -setup {
+    foreach i [after info] {
+	after cancel $i
+    }
+} -body {
+    proc foo {} {
+	global x
+	set x {}
+	foreach i [after info] {
+	    lappend x [after info $i]
+	}
+	after cancel foo
+    }
+    after 1000 {error "I shouldn't ever have executed"}
+    after idle foo
+    update idletasks
+    return $x
+} -result {{{error "I shouldn't ever have executed"} timer}}
+
+foreach i [after info] {
+    after cancel $i
+}
+
+# No test for FreeAfterPtr, since it is already tested above.
+
+test timer-9.1 {AfterCleanupProc procedure} -setup {
+    catch {interp delete x}
+} -body {
+    interp create x
+    x eval {after 200 {
+	lappend x after
+	puts "part 1: this message should not appear"
+    }}
+    after 200 {lappend x after2}
+    x eval {after 200 {
+	lappend x after3
+	puts "part 2: this message should not appear"
+    }}
+    after 200 {lappend x after4}
+    x eval {after 200 {
+	lappend x after5
+	puts "part 3: this message should not appear"
+    }}
+    interp delete x
+    set x before
+    after 300
+    update
+    return $x
+} -result {before after2 after4}
+
+test timer-10.1 {Bug 1016167: [after] overwrites imports} -setup {
+    interp create slave
+    slave eval namespace export after
+    slave eval namespace eval foo namespace import ::after
+} -body {
+    slave eval foo::after 1
+    slave eval namespace origin foo::after
+} -cleanup {
+    # Bug will cause crash here; would cause failure otherwise
+    interp delete slave
+} -result ::after
+
+test timer-11.1 {Bug 1350291: [after] overflowing 32-bit field} -body {
+    set b ok
+    set a [after 0x100000001 {set b "after fired early"}]
+    after 100 set done 1
+    vwait done
+    return $b
+} -cleanup {
+    catch {after cancel $a}
+} -result ok
+test timer-11.2 {Bug 1350293: [after] negative argument} -body {
+    set l {}
+    after 100 {lappend l 100; set done 1}
+    after -1 {lappend l -1}
+    vwait done
+    return $l
+} -result {-1 100}
+
+# cleanup
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/tests/tm.test b/tests/tm.test
new file mode 100644
index 0000000..1b22f8c
--- /dev/null
+++ b/tests/tm.test
@@ -0,0 +1,245 @@
+# This file contains tests for the ::tcl::tm::* commands.
+#
+# Sourcing this file into Tcl runs the tests and generates output for
+# errors.  No output means no errors were found.
+#
+# Copyright (c) 2004 by Donal K. Fellows.
+# All rights reserved.
+
+package require Tcl 8.5
+if {"::tcltest" ni [namespace children]} {
+    package require tcltest 2
+    namespace import -force ::tcltest::*
+}
+
+test tm-1.1 {tm: path command exists} {
+    catch { ::tcl::tm::path }
+    info commands ::tcl::tm::path
+} ::tcl::tm::path
+test tm-1.2 {tm: path command syntax} -returnCodes error -body {
+    ::tcl::tm::path foo
+} -result {unknown or ambiguous subcommand "foo": must be add, list, or remove}
+test tm-1.3 {tm: path command syntax} {
+    ::tcl::tm::path add
+} {}
+test tm-1.4 {tm: path command syntax} {
+    ::tcl::tm::path remove
+} {}
+test tm-1.5 {tm: path command syntax} -returnCodes error -body {
+    ::tcl::tm::path list foobar
+} -result "wrong # args: should be \"::tcl::tm::path list\""
+
+test tm-2.1 {tm: roots command exists} {
+    catch { ::tcl::tm::roots }
+    info commands ::tcl::tm::roots
+} ::tcl::tm::roots
+test tm-2.2 {tm: roots command syntax} -returnCodes error -body {
+    ::tcl::tm::roots
+} -result "wrong # args: should be \"::tcl::tm::roots paths\""
+test tm-2.3 {tm: roots command syntax} -returnCodes error -body {
+    ::tcl::tm::roots foo bar
+} -result "wrong # args: should be \"::tcl::tm::roots paths\""
+
+
+test tm-3.1 {tm: module path management, input validation} -setup {
+    # Save and clear the list
+    set defaults [::tcl::tm::path list]
+    foreach p $defaults {::tcl::tm::path remove $p}
+} -cleanup {
+    # Restore old contents of path list.
+    foreach p [::tcl::tm::path list] {::tcl::tm::path remove $p}
+    foreach p $defaults {::tcl::tm::path add $p}
+} -returnCodes error -body {
+    ::tcl::tm::path add foo/bar
+    ::tcl::tm::path add foo
+} -result {foo is ancestor of existing module path foo/bar.}
+
+test tm-3.2 {tm: module path management, input validation} -setup {
+    # Save and clear the list
+    set defaults [::tcl::tm::path list]
+    foreach p $defaults {::tcl::tm::path remove $p}
+} -cleanup {
+    # Restore old contents of path list.
+    foreach p [::tcl::tm::path list] {::tcl::tm::path remove $p}
+    foreach p $defaults {::tcl::tm::path add $p}
+} -returnCodes error -body {
+    ::tcl::tm::path add foo
+    ::tcl::tm::path add foo/bar
+} -result {foo/bar is subdirectory of existing module path foo.}
+
+test tm-3.3 {tm: module path management, add/list interaction} -setup {
+    # Save and clear the list
+    set defaults [::tcl::tm::path list]
+    foreach p $defaults {::tcl::tm::path remove $p}
+} -cleanup {
+    # Restore old contents of path list.
+    foreach p [::tcl::tm::path list] {::tcl::tm::path remove $p}
+    foreach p $defaults {::tcl::tm::path add $p}
+} -body {
+    ::tcl::tm::path add foo
+    ::tcl::tm::path add bar
+    ::tcl::tm::path list
+} -result {bar foo}
+
+test tm-3.4 {tm: module path management, add/list interaction} -setup {
+    # Save and clear the list
+    set defaults [::tcl::tm::path list]
+    foreach p $defaults {::tcl::tm::path remove $p}
+} -cleanup {
+    # Restore old contents of path list.
+    foreach p [::tcl::tm::path list] {::tcl::tm::path remove $p}
+    foreach p $defaults {::tcl::tm::path add $p}
+} -body {
+    ::tcl::tm::path add foo bar baz
+    ::tcl::tm::path list
+} -result {baz bar foo}
+
+test tm-3.5 {tm: module path management, input validation/list interaction} -setup {
+    # Save and clear the list
+    set defaults [::tcl::tm::path list]
+    foreach p $defaults {::tcl::tm::path remove $p}
+} -cleanup {
+    # Restore old contents of path list.
+    foreach p [::tcl::tm::path list] {::tcl::tm::path remove $p}
+    foreach p $defaults {::tcl::tm::path add $p}
+} -body {
+    catch {::tcl::tm::path add snarf foo geode foo/bar}
+    # Nothing is added if a problem was found.
+    ::tcl::tm::path list
+} -result {}
+
+test tm-3.6 {tm: module path management, input validation/list interaction} -setup {
+    # Save and clear the list
+    set defaults [::tcl::tm::path list]
+    foreach p $defaults {::tcl::tm::path remove $p}
+} -cleanup {
+    # Restore old contents of path list.
+    foreach p [::tcl::tm::path list] {::tcl::tm::path remove $p}
+    foreach p $defaults {::tcl::tm::path add $p}
+} -body {
+    catch {::tcl::tm::path add snarf foo/bar geode foo}
+    # Nothing is added if a problem was found.
+    ::tcl::tm::path list
+} -result {}
+
+test tm-3.7 {tm: module path management, input validation/list interaction} -setup {
+    # Save and clear the list
+    set defaults [::tcl::tm::path list]
+    foreach p $defaults {::tcl::tm::path remove $p}
+} -cleanup {
+    # Restore old contents of path list.
+    foreach p [::tcl::tm::path list] {::tcl::tm::path remove $p}
+    foreach p $defaults {::tcl::tm::path add $p}
+} -body {
+    catch {
+	::tcl::tm::path add foo/bar
+	::tcl::tm::path add snarf geode foo
+    }
+    # Nothing is added if a problem was found.
+    ::tcl::tm::path list
+} -result {foo/bar}
+
+test tm-3.8 {tm: module path management, input validation, ignore duplicates} -setup {
+    # Save and clear the list
+    set defaults [::tcl::tm::path list]
+    foreach p $defaults {::tcl::tm::path remove $p}
+} -cleanup {
+    # Restore old contents of path list.
+    foreach p [::tcl::tm::path list] {::tcl::tm::path remove $p}
+    foreach p $defaults {::tcl::tm::path add $p}
+} -body {
+    # Ignore path if present
+    ::tcl::tm::path add foo
+    ::tcl::tm::path add snarf geode foo
+    ::tcl::tm::path list
+} -result {geode snarf foo}
+
+test tm-3.9 {tm: module path management, input validation, ignore duplicates} -setup {
+    # Save and clear the list
+    set defaults [::tcl::tm::path list]
+    foreach p $defaults {::tcl::tm::path remove $p}
+} -cleanup {
+    # Restore old contents of path list.
+    foreach p [::tcl::tm::path list] {::tcl::tm::path remove $p}
+    foreach p $defaults {::tcl::tm::path add $p}
+} -body {
+    # Ignore path if present
+    ::tcl::tm::path add foo snarf geode foo
+    ::tcl::tm::path list
+} -result {geode snarf foo}
+
+test tm-3.10 {tm: module path management, remove} -setup {
+    # Save and clear the list
+    set defaults [::tcl::tm::path list]
+    foreach p $defaults {::tcl::tm::path remove $p}
+} -cleanup {
+    # Restore old contents of path list.
+    foreach p [::tcl::tm::path list] {::tcl::tm::path remove $p}
+    foreach p $defaults {::tcl::tm::path add $p}
+} -body {
+    ::tcl::tm::path add snarf geode foo
+    ::tcl::tm::path remove foo
+    ::tcl::tm::path list
+} -result {geode snarf}
+
+test tm-3.11 {tm: module path management, remove ignores unknown path} -setup {
+    # Save and clear the list
+    set defaults [::tcl::tm::path list]
+    foreach p $defaults {::tcl::tm::path remove $p}
+} -cleanup {
+    # Restore old contents of path list.
+    foreach p [::tcl::tm::path list] {::tcl::tm::path remove $p}
+    foreach p $defaults {::tcl::tm::path add $p}
+} -body {
+    ::tcl::tm::path add foo snarf geode
+    ::tcl::tm::path remove fox
+    ::tcl::tm::path list
+} -result {geode snarf foo}
+
+
+proc genpaths {base} {
+    # Normalizing picks up drive letters on windows [Bug 1053568]
+    set base [file normalize $base]
+    lassign [split [package present Tcl] .] major minor 
+    set results {}
+    set base [file join $base tcl$major]
+    lappend results [file join $base site-tcl]
+    for {set i 0} {$i <= $minor} {incr i} {
+	lappend results [file join $base ${major}.$i]
+    }
+    return $results
+}
+
+test tm-3.12 {tm: module path management, roots} -setup {
+    # Save and clear the list
+    set defaults [::tcl::tm::path list]
+    foreach p $defaults {::tcl::tm::path remove $p}
+} -cleanup {
+    # Restore old contents of path list.
+    foreach p [::tcl::tm::path list] {::tcl::tm::path remove $p}
+    foreach p $defaults {::tcl::tm::path add $p}
+} -body {
+    ::tcl::tm::roots /FOO
+    ::tcl::tm::path list
+} -result [genpaths /FOO]
+
+test tm-3.13 {tm: module path management, roots} -setup {
+    # Save and clear the list
+    set defaults [::tcl::tm::path list]
+    foreach p $defaults {::tcl::tm::path remove $p}
+} -cleanup {
+    # Restore old contents of path list.
+    foreach p [::tcl::tm::path list] {::tcl::tm::path remove $p}
+    foreach p $defaults {::tcl::tm::path add $p}
+} -body {
+    ::tcl::tm::roots [list /FOO /BAR]
+    ::tcl::tm::path list
+} -result [concat [genpaths /BAR] [genpaths /FOO]]
+
+rename genpaths {}
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/tests/trace.test b/tests/trace.test
new file mode 100644
index 0000000..d830f3c
--- /dev/null
+++ b/tests/trace.test
@@ -0,0 +1,2686 @@
+# Commands covered:  trace
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands.  Sourcing this file into Tcl runs the tests and
+# generates output for errors.  No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+package require tcltest
+namespace import ::tcltest::*
+
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
+
+testConstraint testcmdtrace [llength [info commands testcmdtrace]]
+testConstraint testevalobjv [llength [info commands testevalobjv]]
+
+# Used for constraining memory leak tests
+testConstraint memory [llength [info commands memory]]
+
+proc getbytes {} {
+    set lines [split [memory info] "\n"]
+    lindex [lindex $lines 3] 3
+}
+
+proc traceScalar {name1 name2 op} {
+    global info
+    set info [list $name1 $name2 $op [catch {uplevel 1 set $name1} msg] $msg]
+}
+proc traceScalarAppend {name1 name2 op} {
+    global info
+    lappend info $name1 $name2 $op [catch {uplevel 1 set $name1} msg] $msg
+}
+proc traceArray {name1 name2 op} {
+    global info
+    set info [list $name1 $name2 $op [catch {uplevel 1 set [set name1]($name2)} msg] $msg]
+}
+proc traceArray2 {name1 name2 op} {
+    global info
+    set info [list $name1 $name2 $op]
+}
+proc traceProc {name1 name2 op} {
+    global info
+    set info [concat $info [list $name1 $name2 $op]]
+}
+proc traceTag {tag args} {
+    global info
+    set info [concat $info $tag]
+}
+proc traceError {args} {
+    error "trace returned error"
+}
+proc traceCheck {cmd args} {
+    global info
+    set info [list [catch $cmd msg] $msg]
+}
+proc traceCrtElement {value name1 name2 op} {
+    uplevel 1 set ${name1}($name2) $value
+}
+proc traceCommand {oldName newName op} {
+    global info
+    set info [list $oldName $newName $op]
+}
+
+test trace-0.0 {memory corruption in trace (Tcl Bug 484339)} {
+    # You may need Purify or Electric Fence to reliably
+    # see this one fail.
+    unset -nocomplain z
+    trace add variable z array {set z(foo) 1 ;#}
+    set res "names: [array names z]"
+    unset -nocomplain ::z
+    trace variable ::z w {unset ::z; error "memory corruption";#}
+    list [catch {set ::z 1} msg] $msg
+} {1 {can't set "::z": memory corruption}}
+
+# Read-tracing on variables
+
+test trace-1.1 {trace variable reads} {
+    unset -nocomplain x
+    set info {}
+    trace add variable x read traceScalar
+    list [catch {set x} msg] $msg $info
+} {1 {can't read "x": no such variable} {x {} read 1 {can't read "x": no such variable}}}
+test trace-1.2 {trace variable reads} {
+    unset -nocomplain x
+    set x 123
+    set info {}
+    trace add variable x read traceScalar
+    list [catch {set x} msg] $msg $info
+} {0 123 {x {} read 0 123}}
+test trace-1.3 {trace variable reads} {
+    unset -nocomplain x
+    set info {}
+    trace add variable x read traceScalar
+    set x 123
+    set info
+} {}
+test trace-1.4 {trace array element reads} {
+    unset -nocomplain x
+    set info {}
+    trace add variable x(2) read traceArray
+    list [catch {set x(2)} msg] $msg $info
+} {1 {can't read "x(2)": no such element in array} {x 2 read 1 {can't read "x(2)": no such element in array}}}
+test trace-1.5 {trace array element reads} {
+    unset -nocomplain x
+    set x(2) zzz
+    set info {}
+    trace add variable x(2) read traceArray
+    list [catch {set x(2)} msg] $msg $info
+} {0 zzz {x 2 read 0 zzz}}
+test trace-1.6 {trace array element reads} {
+    unset -nocomplain x
+    set info {}
+    trace add variable x read traceArray2
+    proc p {} {
+        global x
+        set x(2) willi
+        return $x(2)
+    }
+    list [catch {p} msg] $msg $info
+} {0 willi {x 2 read}}
+test trace-1.7 {trace array element reads, create element undefined if nonexistant} {
+    unset -nocomplain x
+    set info {}
+    trace add variable x read q
+    proc q {name1 name2 op} {
+        global info
+        set info [list $name1 $name2 $op]
+        global $name1
+        set ${name1}($name2) wolf
+    }
+    proc p {} {
+        global x
+        set x(X) willi
+        return $x(Y)
+    }
+    list [catch {p} msg] $msg $info
+} {0 wolf {x Y read}}
+test trace-1.8 {trace reads on whole arrays} {
+    unset -nocomplain x
+    set info {}
+    trace add variable x read traceArray
+    list [catch {set x(2)} msg] $msg $info
+} {1 {can't read "x(2)": no such variable} {}}
+test trace-1.9 {trace reads on whole arrays} {
+    unset -nocomplain x
+    set x(2) zzz
+    set info {}
+    trace add variable x read traceArray
+    list [catch {set x(2)} msg] $msg $info
+} {0 zzz {x 2 read 0 zzz}}
+test trace-1.10 {trace variable reads} {
+    unset -nocomplain x
+    set x 444
+    set info {}
+    trace add variable x read traceScalar
+    unset x
+    set info
+} {}
+test trace-1.11 {read traces that modify the array structure} {
+    unset -nocomplain x
+    set x(bar) 0 
+    trace variable x r {set x(foo) 1 ;#} 
+    trace variable x r {unset -nocomplain x(bar) ;#} 
+    array get x
+} {}
+test trace-1.12 {read traces that modify the array structure} {
+    unset -nocomplain x
+    set x(bar) 0 
+    trace variable x r {unset -nocomplain x(bar) ;#} 
+    trace variable x r {set x(foo) 1 ;#} 
+    array get x
+} {}
+test trace-1.13 {read traces that modify the array structure} {
+    unset -nocomplain x
+    set x(bar) 0 
+    trace variable x r {set x(foo) 1 ;#} 
+    trace variable x r {unset -nocomplain x;#} 
+    list [catch {array get x} res] $res
+} {1 {can't read "x(bar)": no such variable}}
+test trace-1.14 {read traces that modify the array structure} {
+    unset -nocomplain x
+    set x(bar) 0 
+    trace variable x r {unset -nocomplain x;#} 
+    trace variable x r {set x(foo) 1 ;#} 
+    list [catch {array get x} res] $res
+} {1 {can't read "x(bar)": no such variable}}
+
+# Basic write-tracing on variables
+
+test trace-2.1 {trace variable writes} {
+    unset -nocomplain x
+    set info {}
+    trace add variable x write traceScalar
+    set x 123
+    set info
+} {x {} write 0 123}
+test trace-2.2 {trace writes to array elements} {
+    unset -nocomplain x
+    set info {}
+    trace add variable x(33) write traceArray
+    set x(33) 444
+    set info
+} {x 33 write 0 444}
+test trace-2.3 {trace writes on whole arrays} {
+    unset -nocomplain x
+    set info {}
+    trace add variable x write traceArray
+    set x(abc) qq
+    set info
+} {x abc write 0 qq}
+test trace-2.4 {trace variable writes} {
+    unset -nocomplain x
+    set x 1234
+    set info {}
+    trace add variable x write traceScalar
+    set x
+    set info
+} {}
+test trace-2.5 {trace variable writes} {
+    unset -nocomplain x
+    set x 1234
+    set info {}
+    trace add variable x write traceScalar
+    unset x
+    set info
+} {}
+test trace-2.6 {trace variable writes on compiled local} {
+    #
+    # Check correct function of whole array traces on compiled local
+    # arrays [Bug 1770591]. The corresponding function for read traces is
+    # already indirectly tested in trace-1.7
+    #
+    unset -nocomplain x
+    set info {}
+    proc p {} {
+	trace add variable x write traceArray
+	set x(X) willy
+    }
+    p
+    set info
+} {x X write 0 willy}
+test trace-2.7 {trace variable writes on errorInfo} -body {
+   #
+   # Check correct behaviour of write traces on errorInfo.
+   # [Bug 1773040]
+   trace add variable ::errorInfo write traceScalar
+   catch {set dne}
+   lrange [set info] 0 2
+} -cleanup {
+   # always remove trace on errorInfo otherwise further tests will fail
+   unset ::errorInfo
+} -result {::errorInfo {} write}
+
+
+
+# append no longer triggers read traces when fetching the old values of
+# variables before doing the append operation. However, lappend _does_
+# still trigger these read traces. Also lappend triggers only one write
+# trace: after appending all arguments to the list.
+
+test trace-3.1 {trace variable read-modify-writes} {
+    unset -nocomplain x
+    set info {}
+    trace add variable x read traceScalarAppend
+    append x 123
+    append x 456
+    lappend x 789
+    set info
+} {x {} read 0 123456}
+test trace-3.2 {trace variable read-modify-writes} {
+    unset -nocomplain x
+    set info {}
+    trace add variable x {read write} traceScalarAppend
+    append x 123
+    lappend x 456
+    set info
+} {x {} write 0 123 x {} read 0 123 x {} write 0 {123 456}}
+
+# Basic unset-tracing on variables
+
+test trace-4.1 {trace variable unsets} {
+    unset -nocomplain x
+    set info {}
+    trace add variable x unset traceScalar
+    unset -nocomplain x
+    set info
+} {x {} unset 1 {can't read "x": no such variable}}
+test trace-4.2 {variable mustn't exist during unset trace} {
+    unset -nocomplain x
+    set x 1234
+    set info {}
+    trace add variable x unset traceScalar
+    unset x
+    set info
+} {x {} unset 1 {can't read "x": no such variable}}
+test trace-4.3 {unset traces mustn't be called during reads and writes} {
+    unset -nocomplain x
+    set info {}
+    trace add variable x unset traceScalar
+    set x 44
+    set x
+    set info
+} {}
+test trace-4.4 {trace unsets on array elements} {
+    unset -nocomplain x
+    set x(0) 18
+    set info {}
+    trace add variable x(1) unset traceArray
+    unset -nocomplain x(1)
+    set info
+} {x 1 unset 1 {can't read "x(1)": no such element in array}}
+test trace-4.5 {trace unsets on array elements} {
+    unset -nocomplain x
+    set x(1) 18
+    set info {}
+    trace add variable x(1) unset traceArray
+    unset x(1)
+    set info
+} {x 1 unset 1 {can't read "x(1)": no such element in array}}
+test trace-4.6 {trace unsets on array elements} {
+    unset -nocomplain x
+    set x(1) 18
+    set info {}
+    trace add variable x(1) unset traceArray
+    unset x
+    set info
+} {x 1 unset 1 {can't read "x(1)": no such variable}}
+test trace-4.7 {trace unsets on whole arrays} {
+    unset -nocomplain x
+    set x(1) 18
+    set info {}
+    trace add variable x unset traceProc
+    unset -nocomplain x(0)
+    set info
+} {}
+test trace-4.8 {trace unsets on whole arrays} {
+    unset -nocomplain x
+    set x(1) 18
+    set x(2) 144
+    set x(3) 14
+    set info {}
+    trace add variable x unset traceProc
+    unset x(1)
+    set info
+} {x 1 unset}
+test trace-4.9 {trace unsets on whole arrays} {
+    unset -nocomplain x
+    set x(1) 18
+    set x(2) 144
+    set x(3) 14
+    set info {}
+    trace add variable x unset traceProc
+    unset x
+    set info
+} {x {} unset}
+
+# Array tracing on variables
+test trace-5.1 {array traces fire on accesses via [array]} {
+    unset -nocomplain x
+    set x(b) 2
+    trace add variable x array traceArray2
+    set ::info {}
+    array set x {a 1}
+    set ::info
+} {x {} array}
+test trace-5.2 {array traces do not fire on normal accesses} {
+    unset -nocomplain x
+    set x(b) 2
+    trace add variable x array traceArray2
+    set ::info {}
+    set x(a) 1
+    set x(b) $x(a)
+    set ::info
+} {}
+test trace-5.3 {array traces do not outlive variable} {
+    unset -nocomplain x
+    trace add variable x array traceArray2
+    set ::info {}
+    set x(a) 1
+    unset x
+    array set x {a 1}
+    set ::info
+} {}
+test trace-5.4 {array traces properly listed in trace information} {
+    unset -nocomplain x
+    trace add variable x array traceArray2
+    set result [trace info variable x]
+    set result
+} [list [list array traceArray2]]
+test trace-5.5 {array traces properly listed in trace information} {
+    unset -nocomplain x
+    trace variable x a traceArray2
+    set result [trace vinfo x]
+    set result
+} [list [list a traceArray2]]
+test trace-5.6 {array traces don't fire on scalar variables} {
+    unset -nocomplain x
+    set x foo
+    trace add variable x array traceArray2
+    set ::info {}
+    catch {array set x {a 1}}
+    set ::info
+} {}
+test trace-5.7 {array traces fire for undefined variables} {
+    unset -nocomplain x
+    trace add variable x array traceArray2
+    set ::info {}
+    array set x {a 1}
+    set ::info
+} {x {} array}
+test trace-5.8 {array traces fire for undefined variables} {
+    unset -nocomplain x
+    trace add variable x array {set x(foo) 1 ;#}
+    set res "names: [array names x]"
+} {names: foo}
+    
+# Trace multiple trace types at once.
+
+test trace-6.1 {multiple ops traced at once} {
+    unset -nocomplain x
+    set info {}
+    trace add variable x {read write unset} traceProc
+    catch {set x}
+    set x 22
+    set x
+    set x 33
+    unset x
+    set info
+} {x {} read x {} write x {} read x {} write x {} unset}
+test trace-6.2 {multiple ops traced on array element} {
+    unset -nocomplain x
+    set info {}
+    trace add variable x(0) {read write unset} traceProc
+    catch {set x(0)}
+    set x(0) 22
+    set x(0)
+    set x(0) 33
+    unset x(0)
+    unset x
+    set info
+} {x 0 read x 0 write x 0 read x 0 write x 0 unset}
+test trace-6.3 {multiple ops traced on whole array} {
+    unset -nocomplain x
+    set info {}
+    trace add variable x {read write unset} traceProc
+    catch {set x(0)}
+    set x(0) 22
+    set x(0)
+    set x(0) 33
+    unset x(0)
+    unset x
+    set info
+} {x 0 write x 0 read x 0 write x 0 unset x {} unset}
+
+# Check order of invocation of traces
+
+test trace-7.1 {order of invocation of traces} {
+    unset -nocomplain x
+    set info {}
+    trace add variable x read "traceTag 1"
+    trace add variable x read "traceTag 2"
+    trace add variable x read "traceTag 3"
+    catch {set x}
+    set x 22
+    set x
+    set info
+} {3 2 1 3 2 1}
+test trace-7.2 {order of invocation of traces} {
+    unset -nocomplain x
+    set x(0) 44
+    set info {}
+    trace add variable x(0) read "traceTag 1"
+    trace add variable x(0) read "traceTag 2"
+    trace add variable x(0) read "traceTag 3"
+    set x(0)
+    set info
+} {3 2 1}
+test trace-7.3 {order of invocation of traces} {
+    unset -nocomplain x
+    set x(0) 44
+    set info {}
+    trace add variable x(0) read "traceTag 1"
+    trace add variable x read "traceTag A1"
+    trace add variable x(0) read "traceTag 2"
+    trace add variable x read "traceTag A2"
+    trace add variable x(0) read "traceTag 3"
+    trace add variable x read "traceTag A3"
+    set x(0)
+    set info
+} {A3 A2 A1 3 2 1}
+
+# Check effects of errors in trace procedures
+
+test trace-8.1 {error returns from traces} {
+    unset -nocomplain x
+    set x 123
+    set info {}
+    trace add variable x read "traceTag 1"
+    trace add variable x read traceError
+    list [catch {set x} msg] $msg $info
+} {1 {can't read "x": trace returned error} {}}
+test trace-8.2 {error returns from traces} {
+    unset -nocomplain x
+    set x 123
+    set info {}
+    trace add variable x write "traceTag 1"
+    trace add variable x write traceError
+    list [catch {set x 44} msg] $msg $info
+} {1 {can't set "x": trace returned error} {}}
+test trace-8.3 {error returns from traces} {
+    unset -nocomplain x
+    set x 123
+    set info {}
+    trace add variable x write traceError
+    list [catch {append x 44} msg] $msg $info
+} {1 {can't set "x": trace returned error} {}}
+test trace-8.4 {error returns from traces} {
+    unset -nocomplain x
+    set x 123
+    set info {}
+    trace add variable x unset "traceTag 1"
+    trace add variable x unset traceError
+    list [catch {unset x} msg] $msg $info
+} {0 {} 1}
+test trace-8.5 {error returns from traces} {
+    unset -nocomplain x
+    set x(0) 123
+    set info {}
+    trace add variable x(0) read "traceTag 1"
+    trace add variable x read "traceTag 2"
+    trace add variable x read traceError
+    trace add variable x read "traceTag 3"
+    list [catch {set x(0)} msg] $msg $info
+} {1 {can't read "x(0)": trace returned error} 3}
+test trace-8.6 {error returns from traces} {
+    unset -nocomplain x
+    set x 123
+    trace add variable x unset traceError
+    list [catch {unset x} msg] $msg
+} {0 {}}
+test trace-8.7 {error returns from traces} {
+    # This test just makes sure that the memory for the error message
+    # gets deallocated correctly when the trace is invoked again or
+    # when the trace is deleted.
+    unset -nocomplain x
+    set x 123
+    trace add variable x read traceError
+    catch {set x}
+    catch {set x}
+    trace remove variable x read traceError
+} {}
+test trace-8.8 {error returns from traces} {
+    # Yet more elaborate memory corruption testing that checks nothing
+    # bad happens when the trace deletes itself and installs something
+    # new.  Alas, there is no neat way to guarantee that this test will
+    # fail if there is a problem, but that's life and with the new code
+    # it should *never* fail.
+    #
+    # Adapted from Bug #219393 reported by Don Porter.
+    catch {rename ::foo {}}
+    proc foo {old args} {
+	trace remove variable ::x write [list foo $old]
+	trace add    variable ::x write [list foo $::x]
+	error "foo"
+    }
+    unset -nocomplain ::x ::y
+    set x junk
+    trace add variable ::x write [list foo $x]
+    for {set y 0} {$y<100} {incr y} {
+	catch {set x junk}
+    }
+    unset x
+} {}
+
+# Check to see that variables are expunged before trace
+# procedures are invoked, so trace procedure can even manipulate
+# a new copy of the variables.
+
+test trace-9.1 {be sure variable is unset before trace is called} {
+    unset -nocomplain x
+    set x 33
+    set info {}
+    trace add variable x unset {traceCheck {uplevel 1 set x}}
+    unset x
+    set info
+} {1 {can't read "x": no such variable}}
+test trace-9.2 {be sure variable is unset before trace is called} {
+    unset -nocomplain x
+    set x 33
+    set info {}
+    trace add variable x unset {traceCheck {uplevel 1 set x 22}}
+    unset x
+    concat $info [list [catch {set x} msg] $msg]
+} {0 22 0 22}
+test trace-9.3 {be sure traces are cleared before unset trace called} {
+    unset -nocomplain x
+    set x 33
+    set info {}
+    trace add variable x unset {traceCheck {uplevel 1 trace info variable x}}
+    unset x
+    set info
+} {0 {}}
+test trace-9.4 {set new trace during unset trace} {
+    unset -nocomplain x
+    set x 33
+    set info {}
+    trace add variable x unset {traceCheck {global x; trace add variable x unset traceProc}}
+    unset x
+    concat $info [trace info variable x]
+} {0 {} {unset traceProc}}
+
+test trace-10.1 {make sure array elements are unset before traces are called} {
+    unset -nocomplain x
+    set x(0) 33
+    set info {}
+    trace add variable x(0) unset {traceCheck {uplevel 1 set x(0)}}
+    unset x(0)
+    set info
+} {1 {can't read "x(0)": no such element in array}}
+test trace-10.2 {make sure array elements are unset before traces are called} {
+    unset -nocomplain x
+    set x(0) 33
+    set info {}
+    trace add variable x(0) unset {traceCheck {uplevel 1 set x(0) zzz}}
+    unset x(0)
+    concat $info [list [catch {set x(0)} msg] $msg]
+} {0 zzz 0 zzz}
+test trace-10.3 {array elements are unset before traces are called} {
+    unset -nocomplain x
+    set x(0) 33
+    set info {}
+    trace add variable x(0) unset {traceCheck {global x; trace info variable x(0)}}
+    unset x(0)
+    set info
+} {0 {}}
+test trace-10.4 {set new array element trace during unset trace} {
+    unset -nocomplain x
+    set x(0) 33
+    set info {}
+    trace add variable x(0) unset {traceCheck {uplevel 1 {trace add variable x(0) read {}}}}
+    unset -nocomplain x(0)
+    concat $info [trace info variable x(0)]
+} {0 {} {read {}}}
+
+test trace-11.1 {make sure arrays are unset before traces are called} {
+    unset -nocomplain x
+    set x(0) 33
+    set info {}
+    trace add variable x unset {traceCheck {uplevel 1 set x(0)}}
+    unset x
+    set info
+} {1 {can't read "x(0)": no such variable}}
+test trace-11.2 {make sure arrays are unset before traces are called} {
+    unset -nocomplain x
+    set x(y) 33
+    set info {}
+    trace add variable x unset {traceCheck {uplevel 1 set x(y) 22}}
+    unset x
+    concat $info [list [catch {set x(y)} msg] $msg]
+} {0 22 0 22}
+test trace-11.3 {make sure arrays are unset before traces are called} {
+    unset -nocomplain x
+    set x(y) 33
+    set info {}
+    trace add variable x unset {traceCheck {uplevel 1 array exists x}}
+    unset x
+    set info
+} {0 0}
+test trace-11.4 {make sure arrays are unset before traces are called} {
+    unset -nocomplain x
+    set x(y) 33
+    set info {}
+    set cmd {traceCheck {uplevel 1 {trace info variable x}}}
+    trace add variable x unset $cmd
+    unset x
+    set info
+} {0 {}}
+test trace-11.5 {set new array trace during unset trace} {
+    unset -nocomplain x
+    set x(y) 33
+    set info {}
+    trace add variable x unset {traceCheck {global x; trace add variable x read {}}}
+    unset x
+    concat $info [trace info variable x]
+} {0 {} {read {}}}
+test trace-11.6 {create scalar during array unset trace} {
+    unset -nocomplain x
+    set x(y) 33
+    set info {}
+    trace add variable x unset {traceCheck {global x; set x 44}}
+    unset x
+    concat $info [list [catch {set x} msg] $msg]
+} {0 44 0 44}
+
+# Check special conditions (e.g. errors) in Tcl_TraceVar2.
+
+test trace-12.1 {creating array when setting variable traces} {
+    unset -nocomplain x
+    set info {}
+    trace add variable x(0) write traceProc
+    list [catch {set x 22} msg] $msg
+} {1 {can't set "x": variable is array}}
+test trace-12.2 {creating array when setting variable traces} {
+    unset -nocomplain x
+    set info {}
+    trace add variable x(0) write traceProc
+    list [catch {set x(0)} msg] $msg
+} {1 {can't read "x(0)": no such element in array}}
+test trace-12.3 {creating array when setting variable traces} {
+    unset -nocomplain x
+    set info {}
+    trace add variable x(0) write traceProc
+    set x(0) 22
+    set info
+} {x 0 write}
+test trace-12.4 {creating variable when setting variable traces} {
+    unset -nocomplain x
+    set info {}
+    trace add variable x write traceProc
+    list [catch {set x} msg] $msg
+} {1 {can't read "x": no such variable}}
+test trace-12.5 {creating variable when setting variable traces} {
+    unset -nocomplain x
+    set info {}
+    trace add variable x write traceProc
+    set x 22
+    set info
+} {x {} write}
+test trace-12.6 {creating variable when setting variable traces} {
+    unset -nocomplain x
+    set info {}
+    trace add variable x write traceProc
+    set x(0) 22
+    set info
+} {x 0 write}
+test trace-12.7 {create array element during read trace} {
+    unset -nocomplain x
+    set x(2) zzz
+    trace add variable x read {traceCrtElement xyzzy}
+    list [catch {set x(3)} msg] $msg
+} {0 xyzzy}
+test trace-12.8 {errors when setting variable traces} {
+    unset -nocomplain x
+    set x 44
+    list [catch {trace add variable x(0) write traceProc} msg] $msg
+} {1 {can't trace "x(0)": variable isn't array}}
+
+# Check trace deletion
+
+test trace-13.1 {delete one trace from another} {
+    proc delTraces {args} {
+	global x
+	trace remove variable x read {traceTag 2}
+	trace remove variable x read {traceTag 3}
+	trace remove variable x read {traceTag 4}
+    }
+    unset -nocomplain x
+    set x 44
+    set info {}
+    trace add variable x read {traceTag 1}
+    trace add variable x read {traceTag 2}
+    trace add variable x read {traceTag 3}
+    trace add variable x read {traceTag 4}
+    trace add variable x read delTraces 
+    trace add variable x read {traceTag 5}
+    set x
+    set info
+} {5 1}
+
+test trace-13.2 {leak when unsetting traced variable} \
+    -constraints memory -body {
+	set end [getbytes]
+	proc f args {}
+	for {set i 0} {$i < 5} {incr i} {
+	    trace add variable bepa write f
+	    set bepa a
+	    unset bepa
+	    set tmp $end
+	    set end [getbytes]
+	}
+	expr {$end - $tmp}
+    } -cleanup {
+	unset -nocomplain end i tmp
+    } -result 0
+test trace-13.3 {leak when removing traces} \
+    -constraints memory -body {
+	set end [getbytes]
+	proc f args {}
+	for {set i 0} {$i < 5} {incr i} {
+	    trace add variable bepa write f
+	    set bepa a
+	    trace remove variable bepa write f
+	    set tmp $end
+	    set end [getbytes]
+	}
+	expr {$end - $tmp}
+    } -cleanup {
+	unset -nocomplain end i tmp
+    } -result 0
+test trace-13.4 {leaks in error returns from traces} \
+    -constraints memory -body {
+	set end [getbytes]
+	for {set i 0} {$i < 5} {incr i} {
+	    set apa {a 1 b 2}
+	    set bepa [lrange $apa 0 end]
+	    trace add variable bepa write {error hej}
+	    catch {set bepa a}
+	    unset bepa
+	    set tmp $end
+	    set end [getbytes]
+	}
+	expr {$end - $tmp}
+    } -cleanup {
+	unset -nocomplain end i tmp
+    } -result 0
+
+# Check operation and syntax of "trace" command.
+
+# Syntax for adding/removing variable and command traces is basically the
+# same:
+#	trace add variable name opList command
+#	trace remove variable name opList command
+#
+# The following loops just get all the common "wrong # args" tests done.
+
+set i 0
+set start "wrong # args:"
+foreach type {variable command} {
+    foreach op {add remove} {
+	test trace-14.0.[incr i] "trace command, wrong # args errors" {
+	    list [catch {trace $op $type} msg] $msg
+	} [list 1 "$start should be \"trace $op $type name opList command\""]
+	test trace-14.0.[incr i] "trace command wrong # args errors" {
+	    list [catch {trace $op $type foo} msg] $msg
+	} [list 1 "$start should be \"trace $op $type name opList command\""]
+	test trace-14.0.[incr i] "trace command, wrong # args errors" {
+	    list [catch {trace $op $type foo bar} msg] $msg
+	} [list 1 "$start should be \"trace $op $type name opList command\""]
+	test trace-14.0.[incr i] "trace command, wrong # args errors" {
+	    list [catch {trace $op $type foo bar baz boo} msg] $msg
+	} [list 1 "$start should be \"trace $op $type name opList command\""]
+    }
+    test trace-14.0.[incr i] "trace command, wrong # args errors" {
+	list [catch {trace info $type foo bar} msg] $msg
+    } [list 1 "$start should be \"trace info $type name\""]
+    test trace-14.0.[incr i] "trace command, wrong # args errors" {
+	list [catch {trace info $type} msg] $msg
+    } [list 1 "$start should be \"trace info $type name\""]
+}
+
+test trace-14.1 "trace command, wrong # args errors" {
+    list [catch {trace} msg] $msg
+} [list 1 "wrong # args: should be \"trace option ?arg ...?\""]
+test trace-14.2 "trace command, wrong # args errors" {
+    list [catch {trace add} msg] $msg
+} [list 1 "wrong # args: should be \"trace add type ?arg ...?\""]
+test trace-14.3 "trace command, wrong # args errors" {
+    list [catch {trace remove} msg] $msg
+} [list 1 "wrong # args: should be \"trace remove type ?arg ...?\""]
+test trace-14.4 "trace command, wrong # args errors" {
+    list [catch {trace info} msg] $msg
+} [list 1 "wrong # args: should be \"trace info type name\""]
+
+test trace-14.5 {trace command, invalid option} {
+    list [catch {trace gorp} msg] $msg
+} [list 1 "bad option \"gorp\": must be add, info, remove, variable, vdelete, or vinfo"]
+
+# Again, [trace ... command] and [trace ... variable] share syntax and
+# error message styles for their opList options; these loops test those 
+# error messages.
+
+set i 0
+set errs [list "array, read, unset, or write" "delete or rename" "enter, leave, enterstep, or leavestep"]
+set abbvs [list {a r u w} {d r} {}]
+proc x {} {}
+foreach type {variable command execution} err $errs abbvlist $abbvs {
+    foreach op {add remove} {
+	test trace-14.6.[incr i] "trace $op $type errors" {
+	    list [catch {trace $op $type x {y z w} a} msg] $msg
+	} [list 1 "bad operation \"y\": must be $err"]
+	foreach abbv $abbvlist {
+	    test trace-14.6.[incr i] "trace $op $type rejects abbreviations" {
+		list [catch {trace $op $type x $abbv a} msg] $msg
+	    } [list 1 "bad operation \"$abbv\": must be $err"]
+	}
+	test trace-14.6.[incr i] "trace $op $type rejects null opList" {
+	    list [catch {trace $op $type x {} a} msg] $msg
+	} [list 1 "bad operation list \"\": must be one or more of $err"]
+    }
+}
+rename x {}
+
+test trace-14.7 {trace command, "trace variable" errors} {
+    list [catch {trace variable} msg] $msg
+} [list 1 "wrong # args: should be \"trace variable name ops command\""]
+test trace-14.8 {trace command, "trace variable" errors} {
+    list [catch {trace variable x} msg] $msg
+} [list 1 "wrong # args: should be \"trace variable name ops command\""]
+test trace-14.9 {trace command, "trace variable" errors} {
+    list [catch {trace variable x y} msg] $msg
+} [list 1 "wrong # args: should be \"trace variable name ops command\""]
+test trace-14.10 {trace command, "trace variable" errors} {
+    list [catch {trace variable x y z w} msg] $msg
+} [list 1 "wrong # args: should be \"trace variable name ops command\""]
+test trace-14.11 {trace command, "trace variable" errors} {
+    list [catch {trace variable x y z} msg] $msg
+} [list 1 "bad operations \"y\": should be one or more of rwua"]
+
+
+test trace-14.12 {trace command ("remove variable" option)} {
+    unset -nocomplain x
+    set info {}
+    trace add variable x write traceProc
+    trace remove variable x write traceProc
+} {}
+test trace-14.13 {trace command ("remove variable" option)} {
+    unset -nocomplain x
+    set info {}
+    trace add variable x write traceProc
+    trace remove variable x write traceProc
+    set x 12345
+    set info
+} {}
+test trace-14.14 {trace command ("remove variable" option)} {
+    unset -nocomplain x
+    set info {}
+    trace add variable x write {traceTag 1}
+    trace add variable x write traceProc
+    trace add variable x write {traceTag 2}
+    set x yy
+    trace remove variable x write traceProc
+    set x 12345
+    trace remove variable x write {traceTag 1}
+    set x foo
+    trace remove variable x write {traceTag 2}
+    set x gorp
+    set info
+} {2 x {} write 1 2 1 2}
+test trace-14.15 {trace command ("remove variable" option)} {
+    unset -nocomplain x
+    set info {}
+    trace add variable x write {traceTag 1}
+    trace remove variable x write non_existent
+    set x 12345
+    set info
+} {1}
+test trace-14.16 {trace command ("info variable" option)} {
+    unset -nocomplain x
+    trace add variable x write {traceTag 1}
+    trace add variable x write traceProc
+    trace add variable x write {traceTag 2}
+    trace info variable x
+} {{write {traceTag 2}} {write traceProc} {write {traceTag 1}}}
+test trace-14.17 {trace command ("info variable" option)} {
+    unset -nocomplain x
+    trace info variable x
+} {}
+test trace-14.18 {trace command ("info variable" option)} {
+    unset -nocomplain x
+    trace info variable x(0)
+} {}
+test trace-14.19 {trace command ("info variable" option)} {
+    unset -nocomplain x
+    set x 44
+    trace info variable x(0)
+} {}
+test trace-14.20 {trace command ("info variable" option)} {
+    unset -nocomplain x
+    set x 44
+    trace add variable x write {traceTag 1}
+    proc check {} {global x; trace info variable x}
+    check
+} {{write {traceTag 1}}}
+
+# Check fancy trace commands (long ones, weird arguments, etc.)
+
+test trace-15.1 {long trace command} {
+    unset -nocomplain x
+    set info {}
+    trace add variable x write {traceTag {This is a very very long argument.  It's \
+	designed to test out the facilities of TraceVarProc for dealing \
+	with such long arguments by malloc-ing space.  One possibility \
+	is that space doesn't get freed properly.  If this happens, then \
+	invoking this test over and over again will eventually leak memory.}}
+    set x 44
+    set info
+} {This is a very very long argument.  It's \
+	designed to test out the facilities of TraceVarProc for dealing \
+	with such long arguments by malloc-ing space.  One possibility \
+	is that space doesn't get freed properly.  If this happens, then \
+	invoking this test over and over again will eventually leak memory.}
+test trace-15.2 {long trace command result to ignore} {
+    proc longResult {args} {return "quite a bit of text, designed to
+	generate a core leak if this command file is invoked over and over again
+	and memory isn't being recycled correctly"}
+    unset -nocomplain x
+    trace add variable x write longResult
+    set x 44
+    set x 5
+    set x abcde
+} abcde
+test trace-15.3 {special list-handling in trace commands} {
+    unset -nocomplain "x y z"
+    set "x y z(a\n\{)" 44
+    set info {}
+    trace add variable "x y z(a\n\{)" write traceProc
+    set "x y z(a\n\{)" 33
+    set info
+} "{x y z} a\\n\\\{ write"
+
+# Check for proper handling of unsets during traces.
+
+proc traceUnset {unsetName args} {
+    global info
+    upvar 1 $unsetName x
+    lappend info [catch {unset x} msg] $msg [catch {set x} msg] $msg
+}
+proc traceReset {unsetName resetName args} {
+    global info
+    upvar 1 $unsetName x $resetName y
+    lappend info [catch {unset x} msg] $msg [catch {set y xyzzy} msg] $msg
+}
+proc traceReset2 {unsetName resetName args} {
+    global info
+    lappend info [catch {uplevel 1 unset $unsetName} msg] $msg \
+	    [catch {uplevel 1 set $resetName xyzzy} msg] $msg
+}
+proc traceAppend {string name1 name2 op} {
+    global info
+    lappend info $string
+}
+
+test trace-16.1 {unsets during read traces} {
+    unset -nocomplain y
+    set y 1234
+    set info {}
+    trace add variable y read {traceUnset y}
+    trace add variable y unset {traceAppend unset}
+    lappend info [catch {set y} msg] $msg
+} {unset 0 {} 1 {can't read "x": no such variable} 1 {can't read "y": no such variable}}
+test trace-16.2 {unsets during read traces} {
+    unset -nocomplain y
+    set y(0) 1234
+    set info {}
+    trace add variable y(0) read {traceUnset y(0)}
+    lappend info [catch {set y(0)} msg] $msg
+} {0 {} 1 {can't read "x": no such variable} 1 {can't read "y(0)": no such element in array}}
+test trace-16.3 {unsets during read traces} {
+    unset -nocomplain y
+    set y(0) 1234
+    set info {}
+    trace add variable y(0) read {traceUnset y}
+    lappend info [catch {set y(0)} msg] $msg
+} {0 {} 1 {can't read "x": no such variable} 1 {can't read "y(0)": no such variable}}
+test trace-16.4 {unsets during read traces} {
+    unset -nocomplain y
+    set y 1234
+    set info {}
+    trace add variable y read {traceReset y y}
+    lappend info [catch {set y} msg] $msg
+} {0 {} 0 xyzzy 0 xyzzy}
+test trace-16.5 {unsets during read traces} {
+    unset -nocomplain y
+    set y(0) 1234
+    set info {}
+    trace add variable y(0) read {traceReset y(0) y(0)}
+    lappend info [catch {set y(0)} msg] $msg
+} {0 {} 0 xyzzy 0 xyzzy}
+test trace-16.6 {unsets during read traces} {
+    unset -nocomplain y
+    set y(0) 1234
+    set info {}
+    trace add variable y(0) read {traceReset y y(0)}
+    lappend info [catch {set y(0)} msg] $msg [catch {set y(0)} msg] $msg
+} {0 {} 1 {can't set "y": upvar refers to element in deleted array} 1 {can't read "y(0)": no such variable} 1 {can't read "y(0)": no such variable}}
+test trace-16.7 {unsets during read traces} {
+    unset -nocomplain y
+    set y(0) 1234
+    set info {}
+    trace add variable y(0) read {traceReset2 y y(0)}
+    lappend info [catch {set y(0)} msg] $msg [catch {set y(0)} msg] $msg
+} {0 {} 0 xyzzy 1 {can't read "y(0)": no such element in array} 0 xyzzy}
+test trace-16.8 {unsets during write traces} {
+    unset -nocomplain y
+    set y 1234
+    set info {}
+    trace add variable y write {traceUnset y}
+    trace add variable y unset {traceAppend unset}
+    lappend info [catch {set y xxx} msg] $msg
+} {unset 0 {} 1 {can't read "x": no such variable} 0 {}}
+test trace-16.9 {unsets during write traces} {
+    unset -nocomplain y
+    set y(0) 1234
+    set info {}
+    trace add variable y(0) write {traceUnset y(0)}
+    lappend info [catch {set y(0) xxx} msg] $msg
+} {0 {} 1 {can't read "x": no such variable} 0 {}}
+test trace-16.10 {unsets during write traces} {
+    unset -nocomplain y
+    set y(0) 1234
+    set info {}
+    trace add variable y(0) write {traceUnset y}
+    lappend info [catch {set y(0) xxx} msg] $msg
+} {0 {} 1 {can't read "x": no such variable} 0 {}}
+test trace-16.11 {unsets during write traces} {
+    unset -nocomplain y
+    set y 1234
+    set info {}
+    trace add variable y write {traceReset y y}
+    lappend info [catch {set y xxx} msg] $msg
+} {0 {} 0 xyzzy 0 xyzzy}
+test trace-16.12 {unsets during write traces} {
+    unset -nocomplain y
+    set y(0) 1234
+    set info {}
+    trace add variable y(0) write {traceReset y(0) y(0)}
+    lappend info [catch {set y(0) xxx} msg] $msg
+} {0 {} 0 xyzzy 0 xyzzy}
+test trace-16.13 {unsets during write traces} {
+    unset -nocomplain y
+    set y(0) 1234
+    set info {}
+    trace add variable y(0) write {traceReset y y(0)}
+    lappend info [catch {set y(0) xxx} msg] $msg [catch {set y(0)} msg] $msg
+} {0 {} 1 {can't set "y": upvar refers to element in deleted array} 0 {} 1 {can't read "y(0)": no such variable}}
+test trace-16.14 {unsets during write traces} {
+    unset -nocomplain y
+    set y(0) 1234
+    set info {}
+    trace add variable y(0) write {traceReset2 y y(0)}
+    lappend info [catch {set y(0) xxx} msg] $msg [catch {set y(0)} msg] $msg
+} {0 {} 0 xyzzy 0 {} 0 xyzzy}
+test trace-16.15 {unsets during unset traces} {
+    unset -nocomplain y
+    set y 1234
+    set info {}
+    trace add variable y unset {traceUnset y}
+    lappend info [catch {unset y} msg] $msg [catch {set y} msg] $msg
+} {1 {can't unset "x": no such variable} 1 {can't read "x": no such variable} 0 {} 1 {can't read "y": no such variable}}
+test trace-16.16 {unsets during unset traces} {
+    unset -nocomplain y
+    set y(0) 1234
+    set info {}
+    trace add variable y(0) unset {traceUnset y(0)}
+    lappend info [catch {unset y(0)} msg] $msg [catch {set y(0)} msg] $msg
+} {1 {can't unset "x": no such variable} 1 {can't read "x": no such variable} 0 {} 1 {can't read "y(0)": no such element in array}}
+test trace-16.17 {unsets during unset traces} {
+    unset -nocomplain y
+    set y(0) 1234
+    set info {}
+    trace add variable y(0) unset {traceUnset y}
+    lappend info [catch {unset y(0)} msg] $msg [catch {set y(0)} msg] $msg
+} {0 {} 1 {can't read "x": no such variable} 0 {} 1 {can't read "y(0)": no such variable}}
+test trace-16.18 {unsets during unset traces} {
+    unset -nocomplain y
+    set y 1234
+    set info {}
+    trace add variable y unset {traceReset2 y y}
+    lappend info [catch {unset y} msg] $msg [catch {set y} msg] $msg
+} {1 {can't unset "y": no such variable} 0 xyzzy 0 {} 0 xyzzy}
+test trace-16.19 {unsets during unset traces} {
+    unset -nocomplain y
+    set y(0) 1234
+    set info {}
+    trace add variable y(0) unset {traceReset2 y(0) y(0)}
+    lappend info [catch {unset y(0)} msg] $msg [catch {set y(0)} msg] $msg
+} {1 {can't unset "y(0)": no such element in array} 0 xyzzy 0 {} 0 xyzzy}
+test trace-16.20 {unsets during unset traces} {
+    unset -nocomplain y
+    set y(0) 1234
+    set info {}
+    trace add variable y(0) unset {traceReset2 y y(0)}
+    lappend info [catch {unset y(0)} msg] $msg [catch {set y(0)} msg] $msg
+} {0 {} 0 xyzzy 0 {} 0 xyzzy}
+test trace-16.21 {unsets cancelling traces} {
+    unset -nocomplain y
+    set y 1234
+    set info {}
+    trace add variable y read {traceAppend first}
+    trace add variable y read {traceUnset y}
+    trace add variable y read {traceAppend third}
+    trace add variable y unset {traceAppend unset}
+    lappend info [catch {set y} msg] $msg
+} {third unset 0 {} 1 {can't read "x": no such variable} 1 {can't read "y": no such variable}}
+test trace-16.22 {unsets cancelling traces} {
+    unset -nocomplain y
+    set y(0) 1234
+    set info {}
+    trace add variable y(0) read {traceAppend first}
+    trace add variable y(0) read {traceUnset y}
+    trace add variable y(0) read {traceAppend third}
+    trace add variable y(0) unset {traceAppend unset}
+    lappend info [catch {set y(0)} msg] $msg
+} {third unset 0 {} 1 {can't read "x": no such variable} 1 {can't read "y(0)": no such variable}}
+
+# Check various non-interference between traces and other things.
+
+test trace-17.1 {trace doesn't prevent unset errors} {
+    unset -nocomplain x
+    set info {}
+    trace add variable x unset {traceProc}
+    list [catch {unset x} msg] $msg $info
+} {1 {can't unset "x": no such variable} {x {} unset}}
+test trace-17.2 {traced variables must survive procedure exits} {
+    unset -nocomplain x
+    proc p1 {} {global x; trace add variable x write traceProc}
+    p1
+    trace info variable x
+} {{write traceProc}}
+test trace-17.3 {traced variables must survive procedure exits} {
+    unset -nocomplain x
+    set info {}
+    proc p1 {} {global x; trace add variable x write traceProc}
+    p1
+    set x 44
+    set info
+} {x {} write}
+
+# Be sure that procedure frames are released before unset traces
+# are invoked.
+
+test trace-18.1 {unset traces on procedure returns} {
+    proc p1 {x y} {set a 44; p2 14}
+    proc p2 {z} {trace add variable z unset {traceCheck {lsort [uplevel 1 {info vars}]}}}
+    set info {}
+    p1 foo bar
+    set info
+} {0 {a x y}}
+test trace-18.2 {namespace delete / trace vdelete combo} {
+    namespace eval ::foo {
+	variable x 123
+    }
+    proc p1 args {
+	trace vdelete ::foo::x u p1
+    }
+    trace variable ::foo::x u p1
+    namespace delete ::foo
+    info exists ::foo::x
+} 0
+test trace-18.3 {namespace delete / trace vdelete combo, Bug \#1337229} {
+    namespace eval ::ns {}
+    trace add variable ::ns::var unset {unset ::ns::var ;#}
+    namespace delete ::ns
+} {}
+test trace-18.4 {namespace delete / trace vdelete combo, Bug \#1338280} {
+    namespace eval ::ref {}
+    set ::ref::var1 AAA
+    trace add variable ::ref::var1 unset doTrace
+    set ::ref::var2 BBB
+    trace add variable ::ref::var2 {unset} doTrace
+    proc doTrace {vtraced vidx op} {
+	global info
+	append info [catch {set ::$vtraced}][llength [info vars ::ref::*]]
+    }
+    set info {}
+    namespace delete ::ref
+    rename doTrace {}
+    set info
+} 1110
+
+# Delete arrays when done, so they can be re-used as scalars
+# elsewhere.
+
+unset -nocomplain x y
+
+test trace-19.0.1 {trace add command (command existence)} {
+    # Just in case!
+    catch {rename nosuchname ""}
+    list [catch {trace add command nosuchname rename traceCommand} msg] $msg
+} {1 {unknown command "nosuchname"}}
+test trace-19.0.2 {trace add command (command existence in ns)} {
+    list [catch {trace add command nosuchns::nosuchname rename traceCommand} msg] $msg
+} {1 {unknown command "nosuchns::nosuchname"}}
+
+
+test trace-19.1 {trace add command (rename option)} {
+    proc foo {} {}
+    catch {rename bar {}}
+    trace add command foo rename traceCommand
+    rename foo bar
+    set info
+} {::foo ::bar rename}
+test trace-19.2 {traces stick with renamed commands} {
+    proc foo {} {}
+    catch {rename bar {}}
+    trace add command foo rename traceCommand
+    rename foo bar
+    rename bar foo
+    set info
+} {::bar ::foo rename}
+test trace-19.2.1 {trace add command rename trace exists} {
+    proc foo {} {}
+    trace add command foo rename traceCommand
+    trace info command foo
+} {{rename traceCommand}}
+test trace-19.3 {command rename traces don't fire on command deletion} {
+    proc foo {} {}
+    set info {}
+    trace add command foo rename traceCommand
+    rename foo {}
+    set info
+} {}
+test trace-19.4 {trace add command rename doesn't trace recreated commands} {
+    proc foo {} {}
+    catch {rename bar {}}
+    set info {}
+    trace add command foo rename traceCommand
+    proc foo {} {}
+    rename foo bar
+    set info
+} {}
+test trace-19.5 {trace add command deleted removes traces} {
+    proc foo {} {}
+    trace add command foo rename traceCommand
+    proc foo {} {}
+    trace info command foo
+} {}
+
+test trace-19.6 {trace add command rename in namespace} -setup {
+    namespace eval tc {}
+    proc tc::tcfoo {} {}
+} -body {
+    trace add command tc::tcfoo rename traceCommand
+    rename tc::tcfoo tc::tcbar
+    set info
+} -cleanup {
+    namespace delete tc
+} -result {::tc::tcfoo ::tc::tcbar rename}
+test trace-19.7 {trace add command rename in namespace back again} -setup {
+    namespace eval tc {}
+    proc tc::tcfoo {} {}
+} -body {
+    trace add command tc::tcfoo rename traceCommand
+    rename tc::tcfoo tc::tcbar
+    rename tc::tcbar tc::tcfoo
+    set info
+} -cleanup {
+    namespace delete tc
+} -result {::tc::tcbar ::tc::tcfoo rename}
+test trace-19.8 {trace add command rename in namespace to out of namespace} -setup {
+    namespace eval tc {}
+    proc tc::tcfoo {} {}
+} -body {
+    trace add command tc::tcfoo rename traceCommand
+    rename tc::tcfoo tcbar
+    set info
+} -cleanup {
+    catch {rename tcbar {}}
+    namespace delete tc
+} -result {::tc::tcfoo ::tcbar rename}
+test trace-19.9 {trace add command rename back into namespace} -setup {
+    namespace eval tc {}
+    proc tc::tcfoo {} {}
+} -body {
+    trace add command tc::tcfoo rename traceCommand
+    rename tc::tcfoo tcbar
+    rename tcbar tc::tcfoo
+    set info
+} -cleanup {
+    namespace delete tc
+} -result {::tcbar ::tc::tcfoo rename}
+test trace-19.10 {trace add command failed rename doesn't trigger trace} {
+    set info {}
+    proc foo {} {}
+    proc bar {} {}
+    trace add command foo {rename delete} traceCommand
+    catch {rename foo bar}
+    set info
+} {}
+catch {rename foo {}}
+catch {rename bar {}}
+
+test trace-19.11 {trace add command qualifies when renamed in namespace} -setup {
+    namespace eval tc {}
+    proc tc::tcfoo {} {}
+} -body {
+    set info {}
+    trace add command tc::tcfoo {rename delete} traceCommand
+    namespace eval tc {rename tcfoo tcbar}
+    set info
+} -cleanup {
+    namespace delete tc
+} -result {::tc::tcfoo ::tc::tcbar rename}
+
+# Make sure it exists again
+proc foo {} {}
+
+test trace-20.1 {trace add command (delete option)} {
+    trace add command foo delete traceCommand
+    rename foo ""
+    set info
+} {::foo {} delete}
+test trace-20.2 {trace add command delete doesn't trace recreated commands} {
+    set info {}
+    proc foo {} {}
+    rename foo ""
+    set info
+} {}
+test trace-20.2.1 {trace add command delete trace info} {
+    proc foo {} {}
+    trace add command foo delete traceCommand
+    trace info command foo
+} {{delete traceCommand}}
+test trace-20.3 {trace add command implicit delete} {
+    proc foo {} {}
+    trace add command foo delete traceCommand
+    proc foo {} {}
+    set info
+} {::foo {} delete}
+test trace-20.3.1 {trace add command delete trace info} {
+    proc foo {} {}
+    trace info command foo
+} {}
+test trace-20.4 {trace add command rename followed by delete} {
+    set infotemp {}
+    proc foo {} {}
+    trace add command foo {rename delete} traceCommand
+    rename foo bar
+    lappend infotemp $info
+    rename bar {}
+    lappend infotemp $info
+    set info $infotemp
+    unset infotemp
+    set info
+} {{::foo ::bar rename} {::bar {} delete}}
+catch {rename foo {}}
+catch {rename bar {}}
+
+test trace-20.5 {trace add command rename and delete} {
+    set infotemp {}
+    set info {}
+    proc foo {} {}
+    trace add command foo {rename delete} traceCommand
+    rename foo bar
+    lappend infotemp $info
+    rename bar {}
+    lappend infotemp $info
+    set info $infotemp
+    unset infotemp
+    set info
+} {{::foo ::bar rename} {::bar {} delete}}
+
+test trace-20.6 {trace add command rename and delete in subinterp} {
+    set tc [interp create]
+    foreach p {traceCommand} {
+	$tc eval [list proc $p [info args $p] [info body $p]]
+    }
+    $tc eval [list set infotemp {}]
+    $tc eval [list set info {}]
+    $tc eval [list proc foo {} {}]
+    $tc eval [list trace add command foo {rename delete} traceCommand]
+    $tc eval [list rename foo bar]
+    $tc eval {lappend infotemp $info}
+    $tc eval [list rename bar {}]
+    $tc eval {lappend infotemp $info}
+    $tc eval {set info $infotemp}
+    $tc eval [list unset infotemp]
+    set info [$tc eval [list set info]]
+    interp delete $tc
+    set info
+} {{::foo ::bar rename} {::bar {} delete}}
+
+# I'd like it if this test could give 'foo {} d' as a result,
+# but interp deletion means there is no interp to evaluate
+# the trace in.
+test trace-20.7 {trace add command delete in subinterp while being deleted} {
+    set info {}
+    set tc [interp create]
+    interp alias $tc traceCommand {} traceCommand
+    $tc eval [list proc foo {} {}]
+    $tc eval [list trace add command foo {rename delete} traceCommand]
+    interp delete $tc
+    set info
+} {}
+
+proc traceDelete {cmd old new op} {
+    trace remove command $cmd {*}[lindex [trace info command $cmd] 0]
+    global info
+    set info [list $old $new $op]
+}
+proc traceCmdrename {cmd old new op} {
+    rename $old someothername
+}
+proc traceCmddelete {cmd old new op} {
+    rename $old ""
+}
+test trace-20.8 {trace delete while trace is active} {
+    set info {}
+    proc foo {} {}
+    catch {rename bar {}}
+    trace add command foo {rename delete} [list traceDelete foo]
+    rename foo bar
+    list [set info] [trace info command bar]
+} {{::foo ::bar rename} {}}
+
+test trace-20.9 {rename trace deletes command} {
+    set info {}
+    proc foo {} {}
+    catch {rename bar {}}
+    catch {rename someothername {}}
+    trace add command foo rename [list traceCmddelete foo]
+    rename foo bar
+    list [info commands foo] [info commands bar] [info commands someothername]
+} {{} {} {}}
+
+test trace-20.10 {rename trace renames command} {
+    set info {}
+    proc foo {} {}
+    catch {rename bar {}}
+    catch {rename someothername {}}
+    trace add command foo rename [list traceCmdrename foo]
+    rename foo bar
+    set info [list [info commands foo] [info commands bar] [info commands someothername]]
+    rename someothername {}
+    set info
+} {{} {} someothername}
+
+test trace-20.11 {delete trace deletes command} {
+    set info {}
+    proc foo {} {}
+    catch {rename bar {}}
+    catch {rename someothername {}}
+    trace add command foo delete [list traceCmddelete foo]
+    rename foo {}
+    list [info commands foo] [info commands bar] [info commands someothername]
+} {{} {} {}}
+
+test trace-20.12 {delete trace renames command} {
+    set info {}
+    proc foo {} {}
+    catch {rename bar {}}
+    catch {rename someothername {}}
+    trace add command foo delete [list traceCmdrename foo]
+    rename foo bar
+    rename bar {}
+    # None of these should exist.
+    list [info commands foo] [info commands bar] [info commands someothername]
+} {{} {} {}}
+
+test trace-20.13 {rename trace discards result [Bug 1355342]} {
+    proc foo {} {}
+    trace add command foo rename {set w Aha!;#}
+    list [rename foo bar] [rename bar {}]
+} {{} {}}
+test trace-20.14 {rename trace discards error result [Bug 1355342]} {
+    proc foo {} {}
+    trace add command foo rename {error}
+    list [rename foo bar] [rename bar {}]
+} {{} {}}
+test trace-20.15 {delete trace discards result [Bug 1355342]} {
+    proc foo {} {}
+    trace add command foo delete {set w Aha!;#}
+    rename foo {}
+} {}
+test trace-20.16 {delete trace discards error result [Bug 1355342]} {
+    proc foo {} {}
+    trace add command foo delete {error}
+    rename foo {}
+} {}
+
+
+proc foo {b} { set a $b }
+
+
+# Delete arrays when done, so they can be re-used as scalars
+# elsewhere.
+
+unset -nocomplain x y
+
+# Delete procedures when done, so we don't clash with other tests
+# (e.g. foobar will clash with 'unknown' tests).
+catch {rename foobar {}}
+catch {rename foo {}}
+catch {rename bar {}}
+
+proc foo {a} {
+    set b $a
+}
+
+proc traceExecute {args} {
+    global info
+    lappend info $args
+}
+
+test trace-21.1 {trace execution: enter} {
+    set info {}
+    trace add execution foo enter [list traceExecute foo]
+    foo 1
+    trace remove execution foo enter [list traceExecute foo]
+    set info
+} {{foo {foo 1} enter}}
+
+test trace-21.2 {trace exeuction: leave} {
+    set info {}
+    trace add execution foo leave [list traceExecute foo]
+    foo 2
+    trace remove execution foo leave [list traceExecute foo]
+    set info
+} {{foo {foo 2} 0 2 leave}}
+
+test trace-21.3 {trace exeuction: enter, leave} {
+    set info {}
+    trace add execution foo {enter leave} [list traceExecute foo]
+    foo 3
+    trace remove execution foo {enter leave} [list traceExecute foo]
+    set info
+} {{foo {foo 3} enter} {foo {foo 3} 0 3 leave}}
+
+test trace-21.4 {trace execution: enter, leave, enterstep} {
+    set info {}
+    trace add execution foo {enter leave enterstep} [list traceExecute foo]
+    foo 3
+    trace remove execution foo {enter leave enterstep} [list traceExecute foo]
+    set info
+} {{foo {foo 3} enter} {foo {set b 3} enterstep} {foo {foo 3} 0 3 leave}}
+
+test trace-21.5 {trace execution: enter, leave, enterstep, leavestep} {
+    set info {}
+    trace add execution foo {enter leave enterstep leavestep} [list traceExecute foo]
+    foo 3
+    trace remove execution foo {enter leave enterstep leavestep} [list traceExecute foo]
+    set info
+} {{foo {foo 3} enter} {foo {set b 3} enterstep} {foo {set b 3} 0 3 leavestep} {foo {foo 3} 0 3 leave}}
+
+test trace-21.6 {trace execution: enterstep, leavestep} {
+    set info {}
+    trace add execution foo {enterstep leavestep} [list traceExecute foo]
+    foo 3
+    trace remove execution foo {enterstep leavestep} [list traceExecute foo]
+    set info
+} {{foo {set b 3} enterstep} {foo {set b 3} 0 3 leavestep}}
+
+test trace-21.7 {trace execution: enterstep} {
+    set info {}
+    trace add execution foo {enterstep} [list traceExecute foo]
+    foo 3
+    trace remove execution foo {enterstep} [list traceExecute foo]
+    set info
+} {{foo {set b 3} enterstep}}
+
+test trace-21.8 {trace execution: leavestep} {
+    set info {}
+    trace add execution foo {leavestep} [list traceExecute foo]
+    foo 3
+    trace remove execution foo {leavestep} [list traceExecute foo]
+    set info
+} {{foo {set b 3} 0 3 leavestep}}
+
+test trace-21.9 {trace execution: TCL_EVAL_GLOBAL} testevalobjv {
+    trace add execution foo enter soom
+    proc ::soom args {lappend ::info SUCCESS [info level]}
+    set ::info {}
+    namespace eval test_ns_1 {
+        proc soom args {lappend ::info FAIL [info level]}
+        # [testevalobjv 1 ...] ought to produce the same
+       # results as [uplevel #0 ...].
+        testevalobjv 1 foo x
+       uplevel #0 foo x
+    }
+    namespace delete test_ns_1
+    trace remove execution foo enter soom
+    set ::info
+} {SUCCESS 1 SUCCESS 1}
+
+test trace-21.10 {trace execution: TCL_EVAL_GLOBAL} testevalobjv {
+    trace add execution foo leave soom
+    proc ::soom args {lappend ::info SUCCESS [info level]}
+    set ::info {}
+    namespace eval test_ns_1 {
+        proc soom args {lappend ::info FAIL [info level]}
+        # [testevalobjv 1 ...] ought to produce the same
+       # results as [uplevel #0 ...].
+        testevalobjv 1 foo x
+       uplevel #0 foo x
+    }
+    namespace delete test_ns_1
+    trace remove execution foo leave soom
+    set ::info
+} {SUCCESS 1 SUCCESS 1}
+
+test trace-21.11 {trace execution and alias} -setup {
+    set res {}
+    proc ::x {} {return ::}
+    namespace eval a {}
+    proc ::a::x {} {return ::a}
+    interp alias {} y {} x
+} -body {
+    lappend res [namespace eval ::a y]
+    trace add execution ::x enter {
+      rename ::x {}
+	proc ::x {} {return ::}
+    #}
+    lappend res [namespace eval ::a y]
+} -cleanup {
+    namespace delete a
+    rename ::x {}
+} -result {:: ::}
+
+proc set2 args {
+    set {*}$args
+}
+
+test trace-21.12 {bug 2438181} -setup {
+    trace add execution set2 leave {puts one two three #;}
+} -body {
+    set2 a hello
+} -returnCodes 1 -result {wrong # args: should be "puts ?-nonewline? ?channelId? string"}
+
+proc factorial {n} {
+    if {$n != 1} { return [expr {$n * [factorial [expr {$n -1 }]]}] }
+    return 1
+}
+
+test trace-22.1 {recursive(1) trace execution: enter} {
+    set info {}
+    trace add execution factorial {enter} [list traceExecute factorial]
+    factorial 1
+    trace remove execution factorial {enter} [list traceExecute factorial]
+    set info
+} {{factorial {factorial 1} enter}}
+
+test trace-22.2 {recursive(2) trace execution: enter} {
+    set info {}
+    trace add execution factorial {enter} [list traceExecute factorial]
+    factorial 2
+    trace remove execution factorial {enter} [list traceExecute factorial]
+    set info
+} {{factorial {factorial 2} enter} {factorial {factorial 1} enter}}
+
+test trace-22.3 {recursive(3) trace execution: enter} {
+    set info {}
+    trace add execution factorial {enter} [list traceExecute factorial]
+    factorial 3
+    trace remove execution factorial {enter} [list traceExecute factorial]
+    set info
+} {{factorial {factorial 3} enter} {factorial {factorial 2} enter} {factorial {factorial 1} enter}}
+
+test trace-23.1 {recursive(1) trace execution: enter, leave, enterstep, leavestep} {
+    set info {}
+    trace add execution factorial {enter leave enterstep leavestep} [list traceExecute]
+    factorial 1
+    trace remove execution factorial {enter leave enterstep leavestep} [list traceExecute]
+    join $info "\n"
+} {{factorial 1} enter
+{if {$n != 1} { return [expr {$n * [factorial [expr {$n -1 }]]}] }} enterstep
+{if {$n != 1} { return [expr {$n * [factorial [expr {$n -1 }]]}] }} 0 {} leavestep
+{return 1} enterstep
+{return 1} 2 1 leavestep
+{factorial 1} 0 1 leave}
+
+test trace-23.2 {recursive(2) trace execution: enter, leave, enterstep, leavestep} {
+    set info {}
+    trace add execution factorial {enter leave enterstep leavestep} [list traceExecute]
+    factorial 2
+    trace remove execution factorial {enter leave enterstep leavestep} [list traceExecute]
+    join $info "\n"
+} {{factorial 2} enter
+{if {$n != 1} { return [expr {$n * [factorial [expr {$n -1 }]]}] }} enterstep
+{expr {$n * [factorial [expr {$n -1 }]]}} enterstep
+{expr {$n -1 }} enterstep
+{expr {$n -1 }} 0 1 leavestep
+{factorial 1} enterstep
+{factorial 1} enter
+{if {$n != 1} { return [expr {$n * [factorial [expr {$n -1 }]]}] }} enterstep
+{if {$n != 1} { return [expr {$n * [factorial [expr {$n -1 }]]}] }} 0 {} leavestep
+{return 1} enterstep
+{return 1} 2 1 leavestep
+{factorial 1} 0 1 leave
+{factorial 1} 0 1 leavestep
+{expr {$n * [factorial [expr {$n -1 }]]}} 0 2 leavestep
+{return 2} enterstep
+{return 2} 2 2 leavestep
+{if {$n != 1} { return [expr {$n * [factorial [expr {$n -1 }]]}] }} 2 2 leavestep
+{factorial 2} 0 2 leave}
+
+test trace-23.3 {recursive(3) trace execution: enter, leave, enterstep, leavestep} {
+    set info {}
+    trace add execution factorial {enter leave enterstep leavestep} [list traceExecute]
+    factorial 3
+    trace remove execution factorial {enter leave enterstep leavestep} [list traceExecute]
+    join $info "\n"
+} {{factorial 3} enter
+{if {$n != 1} { return [expr {$n * [factorial [expr {$n -1 }]]}] }} enterstep
+{expr {$n * [factorial [expr {$n -1 }]]}} enterstep
+{expr {$n -1 }} enterstep
+{expr {$n -1 }} 0 2 leavestep
+{factorial 2} enterstep
+{factorial 2} enter
+{if {$n != 1} { return [expr {$n * [factorial [expr {$n -1 }]]}] }} enterstep
+{expr {$n * [factorial [expr {$n -1 }]]}} enterstep
+{expr {$n -1 }} enterstep
+{expr {$n -1 }} 0 1 leavestep
+{factorial 1} enterstep
+{factorial 1} enter
+{if {$n != 1} { return [expr {$n * [factorial [expr {$n -1 }]]}] }} enterstep
+{if {$n != 1} { return [expr {$n * [factorial [expr {$n -1 }]]}] }} 0 {} leavestep
+{return 1} enterstep
+{return 1} 2 1 leavestep
+{factorial 1} 0 1 leave
+{factorial 1} 0 1 leavestep
+{expr {$n * [factorial [expr {$n -1 }]]}} 0 2 leavestep
+{return 2} enterstep
+{return 2} 2 2 leavestep
+{if {$n != 1} { return [expr {$n * [factorial [expr {$n -1 }]]}] }} 2 2 leavestep
+{factorial 2} 0 2 leave
+{factorial 2} 0 2 leavestep
+{expr {$n * [factorial [expr {$n -1 }]]}} 0 6 leavestep
+{return 6} enterstep
+{return 6} 2 6 leavestep
+{if {$n != 1} { return [expr {$n * [factorial [expr {$n -1 }]]}] }} 2 6 leavestep
+{factorial 3} 0 6 leave}
+
+proc traceDelete {cmd args} {
+    trace remove execution $cmd {*}[lindex [trace info execution $cmd] 0]
+    global info
+    set info $args
+}
+
+test trace-24.1 {delete trace during enter trace} {
+    set info {}
+    trace add execution foo enter [list traceDelete foo]
+    foo 1
+    list $info [catch {trace info execution foo} res] $res
+} {{{foo 1} enter} 0 {}}
+
+test trace-24.2 {delete trace during leave trace} {
+    set info {}
+    trace add execution foo leave [list traceDelete foo]
+    foo 1
+    list $info [catch {trace info execution foo} res] $res
+} {{{foo 1} 0 1 leave} 0 {}}
+
+test trace-24.3 {delete trace during enter-leave trace} {
+    set info {}
+    trace add execution foo {enter leave} [list traceDelete foo]
+    foo 1
+    list $info [catch {trace info execution foo} res] $res
+} {{{foo 1} enter} 0 {}}
+
+test trace-24.4 {delete trace during all exec traces} {
+    set info {}
+    trace add execution foo {enter leave enterstep leavestep} [list traceDelete foo]
+    foo 1
+    list $info [catch {trace info execution foo} res] $res
+} {{{foo 1} enter} 0 {}}
+
+test trace-24.5 {delete trace during all exec traces except enter} {
+    set info {}
+    trace add execution foo {leave enterstep leavestep} [list traceDelete foo]
+    foo 1
+    list $info [catch {trace info execution foo} res] $res
+} {{{set b 1} enterstep} 0 {}}
+
+proc traceDelete {cmd args} {
+    rename $cmd {}
+    global info
+    set info $args
+}
+
+proc foo {a} {
+    set b $a
+}
+
+test trace-25.1 {delete command during enter trace} {
+    set info {}
+    trace add execution foo enter [list traceDelete foo]
+    catch {foo 1} err
+    list $err $info [catch {trace info execution foo} res] $res
+} {{invalid command name "foo"} {{foo 1} enter} 1 {unknown command "foo"}}
+
+proc foo {a} {
+    set b $a
+}
+
+test trace-25.2 {delete command during leave trace} {
+    set info {}
+    trace add execution foo leave [list traceDelete foo]
+    foo 1
+    list $info [catch {trace info execution foo} res] $res
+} {{{foo 1} 0 1 leave} 1 {unknown command "foo"}}
+
+proc foo {a} {
+    set b $a
+}
+
+test trace-25.3 {delete command during enter then leave trace} {
+    set info {}
+    trace add execution foo enter [list traceDelete foo]
+    trace add execution foo leave [list traceDelete foo]
+    catch {foo 1} err
+    list $err $info [catch {trace info execution foo} res] $res
+} {{invalid command name "foo"} {{foo 1} enter} 1 {unknown command "foo"}}
+
+proc foo {a} {
+    set b $a
+}
+proc traceExecute2 {args} {
+    global info
+    lappend info $args
+}
+
+# This shows the peculiar consequences of having two traces
+# at the same time: as well as tracing the procedure you want
+test trace-25.4 {order dependencies of two enter traces} {
+    set info {}
+    trace add execution foo enter [list traceExecute traceExecute]
+    trace add execution foo enter [list traceExecute2 traceExecute2]
+    catch {foo 1} err
+    trace remove execution foo enter [list traceExecute traceExecute]
+    trace remove execution foo enter [list traceExecute2 traceExecute2]
+    join [list $err [join $info \n] [trace info execution foo]] "\n"
+} {1
+traceExecute2 {foo 1} enter
+traceExecute {foo 1} enter
+}
+
+test trace-25.5 {order dependencies of two step traces} {
+    set info {}
+    trace add execution foo enterstep [list traceExecute traceExecute]
+    trace add execution foo enterstep [list traceExecute2 traceExecute2]
+    catch {foo 1} err
+    trace remove execution foo enterstep [list traceExecute traceExecute]
+    trace remove execution foo enterstep [list traceExecute2 traceExecute2]
+    join [list $err [join $info \n] [trace info execution foo]] "\n"
+} {1
+traceExecute2 {set b 1} enterstep
+traceExecute {set b 1} enterstep
+}
+
+# We don't want the result string (5th argument), or the results
+# will get unmanageable.
+proc tracePostExecute {args} {
+    global info
+    lappend info [concat [lrange $args 0 2] [lindex $args 4]]
+}
+proc tracePostExecute2 {args} {
+    global info
+    lappend info [concat [lrange $args 0 2] [lindex $args 4]]
+}
+
+test trace-25.6 {order dependencies of two leave traces} {
+    set info {}
+    trace add execution foo leave [list tracePostExecute tracePostExecute]
+    trace add execution foo leave [list tracePostExecute2 tracePostExecute2]
+    catch {foo 1} err
+    trace remove execution foo leave [list tracePostExecute tracePostExecute]
+    trace remove execution foo leave [list tracePostExecute2 tracePostExecute2]
+    join [list $err [join $info \n] [trace info execution foo]] "\n"
+} {1
+tracePostExecute {foo 1} 0 leave
+tracePostExecute2 {foo 1} 0 leave
+}
+
+test trace-25.7 {order dependencies of two leavestep traces} {
+    set info {}
+    trace add execution foo leavestep [list tracePostExecute tracePostExecute]
+    trace add execution foo leavestep [list tracePostExecute2 tracePostExecute2]
+    catch {foo 1} err
+    trace remove execution foo leavestep [list tracePostExecute tracePostExecute]
+    trace remove execution foo leavestep [list tracePostExecute2 tracePostExecute2]
+    join [list $err [join $info \n] [trace info execution foo]] "\n"
+} {1
+tracePostExecute {set b 1} 0 leavestep
+tracePostExecute2 {set b 1} 0 leavestep
+}
+
+proc foo {a} {
+    set b $a
+}
+
+proc traceDelete {cmd args} {
+    rename $cmd {}
+    global info
+    set info $args
+}
+
+test trace-25.8 {delete command during enter leave and enter/leave-step traces} {
+    set info {}
+    trace add execution foo enter [list traceDelete foo]
+    trace add execution foo leave [list traceDelete foo]
+    trace add execution foo enterstep [list traceDelete foo]
+    trace add execution foo leavestep [list traceDelete foo]
+    catch {foo 1} err
+    list $err $info [catch {trace info execution foo} res] $res
+} {{invalid command name "foo"} {{foo 1} enter} 1 {unknown command "foo"}}
+
+proc foo {a} {
+    set b $a
+}
+
+test trace-25.9 {delete command during enter leave and leavestep traces} {
+    set info {}
+    trace add execution foo enter [list traceDelete foo]
+    trace add execution foo leave [list traceDelete foo]
+    trace add execution foo leavestep [list traceDelete foo]
+    catch {foo 1} err
+    list $err $info [catch {trace info execution foo} res] $res
+} {{invalid command name "foo"} {{foo 1} enter} 1 {unknown command "foo"}}
+
+proc foo {a} {
+    set b $a
+}
+
+test trace-25.10 {delete command during leave and leavestep traces} {
+    set info {}
+    trace add execution foo leave [list traceDelete foo]
+    trace add execution foo leavestep [list traceDelete foo]
+    catch {foo 1} err
+    list $err $info [catch {trace info execution foo} res] $res
+} {1 {{set b 1} 0 1 leavestep} 1 {unknown command "foo"}}
+
+proc foo {a} {
+    set b $a
+}
+
+test trace-25.11 {delete command during enter and enterstep traces} {
+    set info {}
+    trace add execution foo enter [list traceDelete foo]
+    trace add execution foo enterstep [list traceDelete foo]
+    catch {foo 1} err
+    list $err $info [catch {trace info execution foo} res] $res
+} {{invalid command name "foo"} {{foo 1} enter} 1 {unknown command "foo"}}
+
+test trace-26.1 {trace targetCmd when invoked through an alias} {
+    proc foo {args} {
+	set b $args
+    }
+    set info {}
+    trace add execution foo enter [list traceExecute foo]
+    interp alias {} bar {} foo 1
+    bar 2
+    trace remove execution foo enter [list traceExecute foo]
+    set info
+} {{foo {foo 1 2} enter}}
+test trace-26.2 {trace targetCmd when invoked through an alias} {
+    proc foo {args} {
+	set b $args
+    }
+    set info {}
+    trace add execution foo enter [list traceExecute foo]
+    interp create child
+    interp alias child bar {} foo 1
+    child eval bar 2
+    interp delete child
+    trace remove execution foo enter [list traceExecute foo]
+    set info
+} {{foo {foo 1 2} enter}}
+
+test trace-27.1 {memory leak in rename trace (604609)} {
+    catch {rename bar {}}
+    proc foo {} {error foo}
+    trace add command foo rename {rename foo "" ;#}
+    rename foo bar
+    info commands foo
+} {}
+
+test trace-27.2 {command trace remove nonsense} {
+    list [catch {trace remove command thisdoesntexist \
+      {delete rename} bar} res] $res
+} {1 {unknown command "thisdoesntexist"}}
+
+test trace-27.3 {command trace info nonsense} {
+    list [catch {trace info command thisdoesntexist} res] $res
+} {1 {unknown command "thisdoesntexist"}}
+
+
+test trace-28.1 {enterstep and leavestep traces with update idletasks (615043)} {
+    catch {rename foo {}}
+    proc foo {} {
+        set a 1
+        update idletasks
+        set b 1
+    }
+
+    set info {}
+    trace add execution foo {enter enterstep leavestep leave} \
+        [list traceExecute foo]
+    update
+    after idle {set a "idle"}
+    foo
+
+    trace remove execution foo {enter enterstep leavestep leave} \
+        [list traceExecute foo]
+    rename foo {}
+    unset -nocomplain a
+    join $info "\n"
+} {foo foo enter
+foo {set a 1} enterstep
+foo {set a 1} 0 1 leavestep
+foo {update idletasks} enterstep
+foo {set a idle} enterstep
+foo {set a idle} 0 idle leavestep
+foo {update idletasks} 0 {} leavestep
+foo {set b 1} enterstep
+foo {set b 1} 0 1 leavestep
+foo foo 0 1 leave}
+
+test trace-28.2 {exec traces with 'error'} {
+    set info {}
+    set res {}
+    
+    proc foo {} {
+	if {[catch {bar}]} {
+	    return "error"
+	} else {
+	    return "ok"
+	}
+    }
+
+    proc bar {} { error "msg" }
+
+    lappend res [foo]
+
+    trace add execution foo {enter enterstep leave leavestep} \
+      [list traceExecute foo]
+
+    # With the trace active
+
+    lappend res [foo]
+
+    trace remove execution foo {enter enterstep leave leavestep} \
+      [list traceExecute foo]
+    
+    list $res [join $info \n]
+} {{error error} {foo foo enter
+foo {if {[catch {bar}]} {
+	    return "error"
+	} else {
+	    return "ok"
+	}} enterstep
+foo {catch bar} enterstep
+foo bar enterstep
+foo {error msg} enterstep
+foo {error msg} 1 msg leavestep
+foo bar 1 msg leavestep
+foo {catch bar} 0 1 leavestep
+foo {return error} enterstep
+foo {return error} 2 error leavestep
+foo {if {[catch {bar}]} {
+	    return "error"
+	} else {
+	    return "ok"
+	}} 2 error leavestep
+foo foo 0 error leave}}
+
+test trace-28.3 {exec traces with 'return -code error'} {
+    set info {}
+    set res {}
+    
+    proc foo {} {
+	if {[catch {bar}]} {
+	    return "error"
+	} else {
+	    return "ok"
+	}
+    }
+
+    proc bar {} { return -code error "msg" }
+
+    lappend res [foo]
+
+    trace add execution foo {enter enterstep leave leavestep} \
+      [list traceExecute foo]
+
+    # With the trace active
+
+    lappend res [foo]
+
+    trace remove execution foo {enter enterstep leave leavestep} \
+      [list traceExecute foo]
+    
+    list $res [join $info \n]
+} {{error error} {foo foo enter
+foo {if {[catch {bar}]} {
+	    return "error"
+	} else {
+	    return "ok"
+	}} enterstep
+foo {catch bar} enterstep
+foo bar enterstep
+foo {return -code error msg} enterstep
+foo {return -code error msg} 2 msg leavestep
+foo bar 1 msg leavestep
+foo {catch bar} 0 1 leavestep
+foo {return error} enterstep
+foo {return error} 2 error leavestep
+foo {if {[catch {bar}]} {
+	    return "error"
+	} else {
+	    return "ok"
+	}} 2 error leavestep
+foo foo 0 error leave}}
+
+test trace-28.4 {exec traces in slave with 'return -code error'} {
+    interp create slave
+    interp alias slave traceExecute {} traceExecute
+    set info {}
+    set res [interp eval slave {
+	set info {}
+	set res {}
+	
+	proc foo {} {
+	    if {[catch {bar}]} {
+		return "error"
+	    } else {
+		return "ok"
+	    }
+	}
+	
+	proc bar {} { return -code error "msg" }
+	
+	lappend res [foo]
+	
+	trace add execution foo {enter enterstep leave leavestep} \
+	  [list traceExecute foo]
+	
+	# With the trace active
+	
+	lappend res [foo]
+	
+	trace remove execution foo {enter enterstep leave leavestep} \
+	  [list traceExecute foo]
+	
+	list $res
+    }]
+    interp delete slave
+    lappend res [join $info \n]
+} {{error error} {foo foo enter
+foo {if {[catch {bar}]} {
+		return "error"
+	    } else {
+		return "ok"
+	    }} enterstep
+foo {catch bar} enterstep
+foo bar enterstep
+foo {return -code error msg} enterstep
+foo {return -code error msg} 2 msg leavestep
+foo bar 1 msg leavestep
+foo {catch bar} 0 1 leavestep
+foo {return error} enterstep
+foo {return error} 2 error leavestep
+foo {if {[catch {bar}]} {
+		return "error"
+	    } else {
+		return "ok"
+	    }} 2 error leavestep
+foo foo 0 error leave}}
+
+test trace-28.5 {exec traces} {
+    set info {}
+    proc foo {args} { set a 1 }
+    trace add execution foo {enter enterstep leave leavestep} \
+      [list traceExecute foo]
+    after idle [list foo test-28.4]
+    update
+    # Complicated way of removing traces
+    set ti [lindex [eval [list trace info execution ::foo]] 0]
+    if {[llength $ti]} {
+	eval [concat [list trace remove execution foo] $ti]
+    }
+    join $info \n
+} {foo {foo test-28.4} enter
+foo {set a 1} enterstep
+foo {set a 1} 0 1 leavestep
+foo {foo test-28.4} 0 1 leave}
+
+test trace-28.6 {exec traces firing order} {
+    set info {}
+    proc enterStep {cmd op} {lappend ::info "enter $cmd/$op"}
+    proc leaveStep {cmd code result op} {lappend ::info "leave $cmd/$code/$result/$op"}
+
+    proc foo x {
+	set b x=$x
+	incr x
+    }
+    trace add execution foo enterstep enterStep
+    trace add execution foo leavestep leaveStep
+    foo 42
+    rename foo {}
+    join $info \n
+} {enter set b x=42/enterstep
+leave set b x=42/0/x=42/leavestep
+enter incr x/enterstep
+leave incr x/0/43/leavestep}
+
+test trace-28.7 {exec trace information} {
+    set info {}
+    proc foo x { incr x }
+    proc bar {args} {}
+    trace add execution foo {enter leave enterstep leavestep} bar
+    set info [trace info execution foo]
+    trace remove execution foo {enter leave enterstep leavestep} bar
+} {}
+
+test trace-28.8 {exec trace remove nonsense} {
+    list [catch {trace remove execution thisdoesntexist \
+      {enter leave enterstep leavestep} bar} res] $res
+} {1 {unknown command "thisdoesntexist"}}
+
+test trace-28.9 {exec trace info nonsense} {
+    list [catch {trace info execution thisdoesntexist} res] $res
+} {1 {unknown command "thisdoesntexist"}}
+
+test trace-28.10 {exec trace info nonsense} {
+    list [catch {trace remove execution} res] $res
+} {1 {wrong # args: should be "trace remove execution name opList command"}}
+
+test trace-29.1 {Tcl_CreateTrace, correct command and argc/argv arguments of trace proc} {testcmdtrace} {
+    testcmdtrace tracetest {set stuff [expr 14 + 16]}
+} {{expr 14 + 16} {expr 14 + 16} {set stuff [expr 14 + 16]} {set stuff 30}}
+test trace-29.2 {Tcl_CreateTrace, correct command and argc/argv arguments of trace proc} {testcmdtrace} {
+    testcmdtrace tracetest {set stuff [info tclversion]}
+} [concat {{info tclversion} {info tclversion} ::tcl::info::tclversion {::tcl::info::tclversion} {set stuff [info tclversion]}} [list "set stuff [info tclversion]"]]
+test trace-29.3 {Tcl_CreateTrace, correct command and argc/argv arguments of trace proc} {testcmdtrace} {
+    testcmdtrace deletetest {set stuff [info tclversion]}
+} [info tclversion]
+test trace-29.4 {Tcl_CreateTrace, check that tracing doesn't cause memory faults} {testcmdtrace} {
+    # Note that the proc call is the same as the variable name, and that
+    # the call can be direct or indirect by way of another procedure
+    proc tracer {args} {}
+    proc tracedLoop {level} {
+	incr level
+	tracer
+	foreach tracer [expr {$level==1 ? {1 2} : {}}] {tracedLoop $level}
+    }
+    testcmdtrace tracetest {tracedLoop 0}
+} {{tracedLoop 0} {tracedLoop 0} {incr level} {incr level} tracer {tracer} {expr {$level==1 ? {1 2} : {}}} {expr {$level==1 ? {1 2} : {}}} {foreach tracer [expr {$level==1 ? {1 2} : {}}] {tracedLoop $level}} {foreach tracer {1 2} {tracedLoop $level}} {tracedLoop $level} {tracedLoop 1} {incr level} {incr level} tracer {tracer} {expr {$level==1 ? {1 2} : {}}} {expr {$level==1 ? {1 2} : {}}} {foreach tracer [expr {$level==1 ? {1 2} : {}}] {tracedLoop $level}} {foreach tracer {} {tracedLoop $level}} {tracedLoop $level} {tracedLoop 1} {incr level} {incr level} tracer {tracer} {expr {$level==1 ? {1 2} : {}}} {expr {$level==1 ? {1 2} : {}}} {foreach tracer [expr {$level==1 ? {1 2} : {}}] {tracedLoop $level}} {foreach tracer {} {tracedLoop $level}}}
+catch {rename tracer {}}
+catch {rename tracedLoop {}}
+
+test trace-29.5 {Tcl_CreateObjTrace, status return TCL_ERROR} {testcmdtrace} {
+    proc Error { args } { error "Shouldn't get here" }
+    set x 1;
+    list [catch {testcmdtrace resulttest {Error $x}} result] [set result]
+} {1 {Error $x}}
+
+test trace-29.6 {Tcl_CreateObjTrace, status return TCL_RETURN} {testcmdtrace} {
+    proc Return { args } { error "Shouldn't get here" }
+    set x 1;
+    list [catch {testcmdtrace resulttest {Return $x}} result] [set result]
+} {2 {}}
+
+test trace-29.7 {Tcl_CreateObjTrace, status return TCL_BREAK} {testcmdtrace} {
+    proc Break { args } { error "Shouldn't get here" }
+    set x 1;
+    list [catch {testcmdtrace resulttest {Break $x}} result] [set result]
+} {3 {}}
+
+test trace-29.8 {Tcl_CreateObjTrace, status return TCL_CONTINUE} {testcmdtrace} {
+    proc Continue { args } { error "Shouldn't get here" }
+    set x 1;
+    list [catch {testcmdtrace resulttest {Continue $x}} result] [set result]
+} {4 {}}
+
+test trace-29.9 {Tcl_CreateObjTrace, status return unknown} {testcmdtrace} {
+    proc OtherStatus { args } { error "Shouldn't get here" }
+    set x 1;
+    list [catch {testcmdtrace resulttest {OtherStatus $x}} result] [set result]
+} {6 {}}
+
+test trace-29.10 {Tcl_CreateTrace, correct level interpretation} {testcmdtrace} {
+    proc foo {} {uplevel 1 bar}
+    proc bar {} {uplevel 1 grok}
+    proc grok {} {uplevel 1 spock}
+    proc spock {} {uplevel 1 fascinating}
+    proc fascinating {} {}
+    testcmdtrace leveltest {foo}
+} {foo {foo} {uplevel 1 bar} {uplevel 1 bar} bar {bar} {uplevel 1 grok} {uplevel 1 grok}}
+
+test trace-29.11 {Tcl_CreateTrace, multiple traces} {testcmdtrace} {
+    testcmdtrace doubletest {format xx}
+} {{format xx} {format xx}}
+
+test trace-30.1 {Tcl_DeleteTrace} {emptyTest} {
+    # the above tests have tested Tcl_DeleteTrace
+} {}
+
+test trace-31.1 {command and execution traces shared struct} {
+    # Tcl Bug 807243
+    proc foo {} {}
+    trace add command foo delete foo
+    trace add execution foo enter foo
+    set result [trace info command foo]
+    trace remove command foo delete foo
+    trace remove execution foo enter foo
+    rename foo {}
+    set result
+} [list [list delete foo]]
+test trace-31.2 {command and execution traces shared struct} {
+    # Tcl Bug 807243
+    proc foo {} {}
+    trace add command foo delete foo
+    trace add execution foo enter foo
+    set result [trace info execution foo]
+    trace remove command foo delete foo
+    trace remove execution foo enter foo
+    rename foo {}
+    set result
+} [list [list enter foo]]
+
+test trace-32.1 {
+    TraceCommandInfo refcount decr in TraceCommandProc w/o loss of reference
+} {
+    # Tcl Bug 811483
+    proc foo {} {}
+    trace add command foo delete foo
+    trace add execution foo enter foo
+    set result [trace info command foo]
+    rename foo {}
+    set result
+} [list [list delete foo]]
+
+test trace-33.1 {variable match with remove variable} {
+    unset -nocomplain x
+    trace variable x w foo
+    trace remove variable x write foo
+    llength [trace info variable x]
+} 0
+
+test trace-34.1 {Bug 1201035} {
+    set ::x [list]
+    proc foo {} {lappend ::x foo}
+    proc bar args {
+        lappend ::x $args
+        trace remove execution foo leavestep bar
+        trace remove execution foo enterstep bar
+        trace add execution foo leavestep bar
+        trace add execution foo enterstep bar
+        lappend ::x done
+    }
+    trace add execution foo leavestep bar
+    trace add execution foo enterstep bar
+    foo
+    set ::x
+} {{{lappend ::x foo} enterstep} done foo}
+
+test trace-34.2 {Bug 1224585} {
+    proc foo {} {}
+    proc bar args {trace remove execution foo leave soom}
+    trace add execution foo leave bar
+    trace add execution foo leave soom
+    foo
+} {}
+
+test trace-34.3 {Bug 1224585} {
+    proc foo {} {set x {}}
+    proc bar args {trace remove execution foo enterstep soom}
+    trace add execution foo enterstep soom
+    trace add execution foo enterstep bar
+    foo
+} {}
+
+# We test here for the half-documented and currently valid interplay between
+# delete traces and namespace deletion.
+test trace-34.4 {Bug 1047286} {
+    variable x notrace
+    proc callback {old - -} {
+        variable x "$old exists: [namespace which -command $old]"
+    }
+    namespace eval ::foo {proc bar {} {}}
+    trace add command ::foo::bar delete [namespace code callback]
+    namespace delete ::foo
+    set x
+} {::foo::bar exists: ::foo::bar}
+
+test trace-34.5 {Bug 1047286} {
+    variable x notrace
+    proc callback {old - -} {
+        variable x "$old exists: [namespace which -command $old]"
+    }
+    namespace eval ::foo {proc bar {} {}}
+    trace add command ::foo::bar delete [namespace code callback]
+    namespace eval ::foo namespace delete ::foo
+    set x
+} {::foo::bar exists: }
+
+test trace-34.6 {Bug 1458266} -setup {
+    proc dummy {} {}
+    proc stepTraceHandler {cmdString args} {
+        variable log
+        append log "[expr {[info level] - 1}]: [lindex [split $cmdString] 0]\n"
+        dummy
+        isTracedInside_2
+    }
+    proc cmdTraceHandler {cmdString args} {
+        # silent
+    }
+    proc isTracedInside_1 {} {
+        isTracedInside_2
+    }
+    proc isTracedInside_2 {} {
+        set x 2
+    }
+} -body {
+    variable log {}
+    trace add execution isTracedInside_1 enterstep stepTraceHandler
+    trace add execution isTracedInside_2 enterstep stepTraceHandler
+    isTracedInside_1
+    variable first $log
+    set log {}
+    trace add execution dummy enter cmdTraceHandler
+    isTracedInside_1
+    variable second $log
+    expr {($first eq $second) ? "ok" : "\n$first\nand\n\n$second\ndiffer"}
+} -cleanup {
+    unset -nocomplain log first second
+    rename dummy {}
+    rename stepTraceHandler {}
+    rename cmdTraceHandler {}
+    rename isTracedInside_1 {}
+    rename isTracedInside_2 {}
+} -result ok
+
+test trace-35.1 {527164: Keep -errorinfo of traces} -setup {
+    unset -nocomplain x y
+} -body {
+    trace add variable x write {error foo;#}
+    trace add variable y write {set x 2;#}
+    list [catch {set y 1} msg opts] $msg [dict get $opts -errorinfo]
+} -cleanup {
+    unset -nocomplain x y
+} -result {1 {can't set "y": can't set "x": foo} {foo
+    while executing
+"error foo"
+    (write trace on "x")
+    invoked from within
+"set x 2"
+    (write trace on "y")
+    invoked from within
+"set y 1"}}
+
+
+#
+# Test for the correct(?) dynamics of execution traces. This test insures that
+# the dynamics of the original implementation remain valid; note that
+# these aspects are neither documented nor do they appear in TIP 62
+
+proc traceproc {tracevar args} {
+    append ::$tracevar *
+}
+proc untraced {type} {
+    trace add execution untraced $type {traceproc tracevar}
+    append ::tracevar -
+}
+proc runbase {results base} {
+    set tt {enter leave enterstep leavestep}
+    foreach n {1 2 3 4} t $tt r $results {
+	eval [subst $base]
+    }
+}
+set base {
+    test trace-36.$n {dynamic trace creation: $t} -setup {
+	set ::tracevar {}
+    } -cleanup {
+	unset ::tracevar
+	trace remove execution untraced $t {traceproc tracevar}
+    } -body {
+	untraced $t
+	set ::tracevar
+    } -result {$r}
+}
+runbase {- - - -} $base
+
+set base {
+    test trace-37.$n {dynamic trace addition: $t} -setup {
+	set ::tracevar {}
+	set ::tracevar2 {}
+	trace add execution untraced enter {traceproc tracevar2}
+    } -cleanup {
+	trace remove execution untraced $t {traceproc tracevar}
+	trace remove execution untraced enter {traceproc tracevar2}
+	unset ::tracevar ::tracevar2
+    } -body {
+	untraced $t
+	list \$::tracevar \$::tracevar2
+    } -result {$r}
+}
+runbase {{- *} {-* *} {- *} {- *}} $base
+
+set base {
+    test trace-38.$n {dynamic trace addition: $t} -setup {
+	set ::tracevar {}
+	set ::tracevar2 {}
+	trace add execution untraced leave {traceproc tracevar2}
+    } -cleanup {
+	trace remove execution untraced $t {traceproc tracevar}
+	trace remove execution untraced leave {traceproc tracevar2}
+	unset ::tracevar ::tracevar2
+    } -body {
+	untraced $t
+	list \$::tracevar \$::tracevar2
+    } -result {$r}
+}
+runbase {{- *} {-* *} {- *} {- *}} $base
+
+test trace-39 {bug #3484621: tracing Bc'ed commands} -setup {
+    set ::traceLog 0
+    set ::traceCalls 0
+    set ::bar [list 0 1 2 3]
+    set res {}
+    proc dotrace args {
+	incr ::traceLog
+    }
+    proc foo {} {
+	incr ::traceCalls
+	# choose a BC'ed command that is 'unlikely' to interfere with tcltest's
+	# internals 
+	lset ::bar 1 2
+    }
+} -body {
+    foo
+    lappend res $::traceLog
+
+    trace add execution lset enter dotrace
+    foo
+    lappend res $::traceLog
+
+    trace remove execution lset enter dotrace
+    foo
+    lappend res $::traceLog
+
+    list $::traceCalls | {*}$res
+} -cleanup {
+    unset ::traceLog ::traceCalls ::bar res
+    rename dotrace {}
+    rename foo {}
+} -result {3 | 0 1 1}
+    
+test trace-39.1 {bug #3485022: tracing Bc'ed commands} -setup {
+    set ::traceLog 0
+    set ::traceCalls 0
+    set res {}
+    proc dotrace args {
+	incr ::traceLog
+    }
+    proc foo {} {
+	incr ::traceCalls
+	string equal zip zap
+    }
+} -body {
+    foo
+    lappend res $::traceLog
+
+    trace add execution ::tcl::string::equal enter dotrace
+    foo
+    lappend res $::traceLog
+
+    trace remove execution tcl::string::equal enter dotrace
+    foo
+    lappend res $::traceLog
+
+    list $::traceCalls | {*}$res
+} -cleanup {
+    unset ::traceLog ::traceCalls res
+    rename dotrace {}
+    rename foo {}
+} -result {3 | 0 1 1}
+
+test trace-40.1 {execution trace errors become command errors} {
+    proc foo args {}
+    trace add execution foo enter {rename foo {}; error bar;#}
+    catch foo m
+    return -level 0 $m[unset m]
+} bar
+    
+# Delete procedures when done, so we don't clash with other tests
+# (e.g. foobar will clash with 'unknown' tests).
+catch {rename foobar {}}
+catch {rename foo {}}
+catch {rename bar {}}
+catch {rename untraced {}}
+catch {rename traceproc {}}
+catch {rename runbase {}}
+
+# Unset the variable when done
+unset -nocomplain info base
+
+# cleanup
+cleanupTests
+return
diff --git a/tests/unixFCmd.test b/tests/unixFCmd.test
new file mode 100644
index 0000000..183c145
--- /dev/null
+++ b/tests/unixFCmd.test
@@ -0,0 +1,441 @@
+# This file tests the tclUnixFCmd.c file.
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands.  Sourcing this file into Tcl runs the tests and
+# generates output for errors.  No output means no errors were found.
+#
+# Copyright (c) 1996 Sun Microsystems, Inc.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+    package require tcltest 2
+    namespace import -force ::tcltest::*
+}
+
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
+
+testConstraint testchmod [llength [info commands testchmod]]
+
+# These tests really need to be run from a writable directory, which
+# it is assumed [temporaryDirectory] is.
+set oldcwd [pwd]
+cd [temporaryDirectory]
+
+# Several tests require need to match results against the unix username
+set user {}
+if {[testConstraint unix]} {
+    catch {set user [exec whoami]}
+    if {$user == ""} {
+	catch {regexp {^[^(]*\(([^)]*)\)} [exec id] dummy user}
+    }
+    if {$user == ""} {
+	set user "root"
+    }
+}
+
+# Find a group that exists on this system, or else skip tests that require
+# groups
+testConstraint foundGroup 0
+if {[testConstraint unix]} {
+    catch {
+	set groupList [exec groups]
+	set group [lindex $groupList 0]
+	testConstraint foundGroup 1
+    }
+}
+
+# check whether -readonly attribute is supported
+testConstraint readonlyAttr 0
+if {[testConstraint unix]} {
+    set f [makeFile "whatever" probe]
+    catch {
+	file attributes $f -readonly
+	testConstraint readonlyAttr 1
+    }
+    removeFile probe
+}
+
+proc openup {path} {
+    testchmod 0o777 $path
+    if {[file isdirectory $path]} {
+	catch {
+	    foreach p [glob -directory $path *] {
+		openup $p
+	    }
+	}
+    }
+}
+
+proc cleanup {args} {
+    foreach p ". $args" {
+	set x ""
+	catch {
+	    set x [glob -directory $p tf* td*]
+	}
+	foreach file $x {
+	    if {
+		[catch {file delete -force -- $file}]
+		&& [testConstraint testchmod]
+	    } then {
+		openup $file
+		file delete -force -- $file
+	    }
+	}
+    }
+}
+
+if {[testConstraint unix] && [testConstraint notRoot]} {
+    testConstraint execMknod [expr {![catch {exec mknod tf1 p}]}]
+    cleanup
+}
+
+test unixFCmd-1.1 {TclpRenameFile: EACCES} -setup {
+    cleanup
+} -constraints {unix notRoot} -body {
+    file mkdir td1/td2/td3
+    file attributes td1/td2 -permissions 0000
+    file rename td1/td2/td3 td2
+} -returnCodes error -cleanup {
+    file attributes td1/td2 -permissions 0755
+    cleanup
+} -result {error renaming "td1/td2/td3": permission denied}
+test unixFCmd-1.2 {TclpRenameFile: EEXIST} -setup {
+    cleanup
+} -constraints {unix notRoot} -body {
+    file mkdir td1/td2
+    file mkdir td2
+    file rename td2 td1
+} -returnCodes error -cleanup {
+    cleanup
+} -result {error renaming "td2" to "td1/td2": file already exists}
+test unixFCmd-1.3 {TclpRenameFile: EINVAL} -setup {
+    cleanup
+} -constraints {unix notRoot} -body {
+    file mkdir td1
+    file rename td1 td1
+} -returnCodes error -cleanup {
+    cleanup
+} -result {error renaming "td1" to "td1/td1": trying to rename a volume or move a directory into itself}
+test unixFCmd-1.4 {TclpRenameFile: EISDIR} {emptyTest unix notRoot} {
+    # can't make it happen
+} {}
+test unixFCmd-1.5 {TclpRenameFile: ENOENT} -setup {
+    cleanup
+} -constraints {unix notRoot} -body {
+    file mkdir td1
+    file rename td2 td1
+} -returnCodes error -cleanup {
+    cleanup
+} -result {error renaming "td2": no such file or directory}
+test unixFCmd-1.6 {TclpRenameFile: ENOTDIR} {emptyTest unix notRoot} {
+    # can't make it happen
+} {}
+test unixFCmd-1.7 {TclpRenameFile: EXDEV} -setup {
+    cleanup
+} -constraints {unix notRoot} -body {
+    file mkdir foo/bar
+    file attr foo -perm 040555
+    file rename foo/bar /tmp
+} -returnCodes error -cleanup {
+    catch {file delete /tmp/bar}
+    catch {file attr foo -perm 040777}
+    catch {file delete -force foo}
+} -match glob -result {*: permission denied}
+test unixFCmd-1.8 {Checking EINTR Bug} {unix notRoot nonPortable} {
+    testalarm
+    after 2000
+    list [testgotsig] [testgotsig]
+} {1 0}
+test unixFCmd-1.9 {Checking EINTR Bug} -constraints {unix notRoot nonPortable} -setup {
+    cleanup
+    set f [open tfalarm w]
+    puts $f {
+	after 2000
+	puts "hello world"
+	exit 0
+    }
+    close $f
+} -body {
+    testalarm
+    set pipe [open "|[info nameofexecutable] tfalarm" r+]
+    set line [read $pipe 1]
+    catch {close $pipe}
+    list $line [testgotsig]
+} -cleanup {
+    cleanup
+} -result {h 1}
+
+test unixFCmd-2.1 {TclpCopyFile: target exists: lstat(dst) == 0} -setup {
+    cleanup
+} -constraints {unix notRoot} -body {
+    close [open tf1 a]
+    close [open tf2 a]
+    file copy -force tf1 tf2
+} -cleanup {
+    cleanup
+} -result {}
+test unixFCmd-2.2.1 {TclpCopyFile: src is symlink} -setup {
+    cleanup
+} -constraints {unix notRoot dontCopyLinks} -body {
+    # copying links should end up with real files
+    close [open tf1 a]
+    file link -symbolic tf2 tf1
+    file copy tf2 tf3
+    file type tf3
+} -cleanup {
+    cleanup
+} -result file
+test unixFCmd-2.2.2 {TclpCopyFile: src is symlink} -setup {
+    cleanup
+} -constraints {unix notRoot} -body {
+    # copying links should end up with the links copied
+    close [open tf1 a]
+    file link -symbolic tf2 tf1
+    file copy tf2 tf3
+    file type tf3
+} -cleanup {
+    cleanup
+} -result link
+test unixFCmd-2.3 {TclpCopyFile: src is block} -setup {
+    cleanup
+} -constraints {unix notRoot} -body {
+    set null "/dev/null"
+    while {[file type $null] != "characterSpecial"} {
+	set null [file join [file dirname $null] [file readlink $null]]
+    }
+    # file copy $null tf1
+} -result {}
+test unixFCmd-2.4 {TclpCopyFile: src is fifo} -setup {
+    cleanup
+} -constraints {unix notRoot execMknod} -body {
+    exec mknod tf1 p
+    file copy tf1 tf2
+    list [file type tf1] [file type tf2]
+} -cleanup {
+    cleanup
+} -result {fifo fifo}
+test unixFCmd-2.5 {TclpCopyFile: copy attributes} -setup {
+    cleanup
+} -constraints {unix notRoot} -body {
+    close [open tf1 a]
+    file attributes tf1 -permissions 0472
+    file copy tf1 tf2
+    file attributes tf2 -permissions
+} -cleanup {
+    cleanup
+} -result 00472 ;# i.e. perms field of [exec ls -l tf2] is -r--rwx-w-
+
+test unixFCmd-3.1 {CopyFile not done} {emptyTest unix notRoot} {
+} {}
+
+test unixFCmd-4.1 {TclpDeleteFile not done} {emptyTest unix notRoot} {
+} {}
+
+test unixFCmd-5.1 {TclpCreateDirectory not done} {emptyTest unix notRoot} {
+} {}
+
+test unixFCmd-6.1 {TclpCopyDirectory not done} {emptyTest unix notRoot} {
+} {}
+
+test unixFCmd-7.1 {TclpRemoveDirectory not done} {emptyTest unix notRoot} {
+} {}
+
+test unixFCmd-8.1 {TraverseUnixTree not done} {emptyTest unix notRoot} {
+} {}
+
+test unixFCmd-9.1 {TraversalCopy not done} {emptyTest unix notRoot} {
+} {}
+
+test unixFCmd-10.1 {TraversalDelete not done} {emptyTest unix notRoot} {
+} {}
+
+test unixFCmd-11.1 {CopyFileAttrs not done} {emptyTest unix notRoot} {
+} {}
+
+test unixFCmd-12.1 {GetGroupAttribute - file not found} -setup {
+    catch {file delete -force -- foo.test}
+} -constraints {unix notRoot} -returnCodes error -body {
+    file attributes foo.test -group
+} -result {could not read "foo.test": no such file or directory}
+test unixFCmd-12.2 {GetGroupAttribute - file found} -setup {
+    catch {file delete -force -- foo.test}
+} -constraints {unix notRoot} -body {
+    close [open foo.test w]
+    file attributes foo.test -group
+} -cleanup {
+    file delete -force -- foo.test
+} -match glob -result *
+
+test unixFCmd-13.1 {GetOwnerAttribute - file not found} -setup {
+    catch {file delete -force -- foo.test}
+} -constraints {unix notRoot} -returnCodes error -body {
+    file attributes foo.test -group
+} -result {could not read "foo.test": no such file or directory}
+test unixFCmd-13.2 {GetOwnerAttribute} -setup {
+    catch {file delete -force -- foo.test}
+} -constraints {unix notRoot} -body {
+    close [open foo.test w]
+    file attributes foo.test -owner
+} -cleanup {
+    file delete -force -- foo.test
+} -result $user
+
+test unixFCmd-14.1 {GetPermissionsAttribute - file not found} -setup {
+    catch {file delete -force -- foo.test}
+} -constraints {unix notRoot} -returnCodes error -body {
+    file attributes foo.test -permissions
+} -result {could not read "foo.test": no such file or directory}
+test unixFCmd-14.2 {GetPermissionsAttribute} -setup {
+    catch {file delete -force -- foo.test}
+} -constraints {unix notRoot} -body {
+    close [open foo.test w]
+    file attribute foo.test -permissions
+} -cleanup {
+    file delete -force -- foo.test
+} -match glob -result *
+
+#groups hard to test
+test unixFCmd-15.1 {SetGroupAttribute - invalid group} -setup {
+    catch {file delete -force -- foo.test}
+} -constraints {unix notRoot} -body {
+    file attributes foo.test -group foozzz
+} -returnCodes error -cleanup {
+    file delete -force -- foo.test
+} -result {could not set group for file "foo.test": group "foozzz" does not exist}
+test unixFCmd-15.2 {SetGroupAttribute - invalid file} -setup {
+    catch {file delete -force -- foo.test}
+} -constraints {unix notRoot foundGroup} -returnCodes error -body {
+    file attributes foo.test -group $group
+} -result {could not set group for file "foo.test": no such file or directory}
+
+#changing owners hard to do
+test unixFCmd-16.1 {SetOwnerAttribute - current owner} -setup {
+    catch {file delete -force -- foo.test}
+} -constraints {unix notRoot} -body {
+    close [open foo.test w]
+    list [file attributes foo.test -owner $user] \
+	[file attributes foo.test -owner]
+} -cleanup {
+    file delete -force -- foo.test
+} -result [list {} $user]
+test unixFCmd-16.2 {SetOwnerAttribute - invalid file} -setup {
+    catch {file delete -force -- foo.test}
+} -constraints {unix notRoot} -returnCodes error -body {
+    file attributes foo.test -owner $user
+} -result {could not set owner for file "foo.test": no such file or directory}
+test unixFCmd-16.3 {SetOwnerAttribute - invalid owner} -setup {
+    catch {file delete -force -- foo.test}
+} -constraints {unix notRoot} -returnCodes error -body {
+    file attributes foo.test -owner foozzz
+} -result {could not set owner for file "foo.test": user "foozzz" does not exist}
+
+test unixFCmd-17.1 {SetPermissionsAttribute} -setup {
+    catch {file delete -force -- foo.test}
+} -constraints {unix notRoot} -body {
+    close [open foo.test w]
+    list [file attributes foo.test -permissions 0000] \
+	[file attributes foo.test -permissions]
+} -cleanup {
+    file delete -force -- foo.test
+} -result {{} 00000}
+test unixFCmd-17.2 {SetPermissionsAttribute} -setup {
+    catch {file delete -force -- foo.test}
+} -constraints {unix notRoot} -returnCodes error -body {
+    file attributes foo.test -permissions 0000
+} -result {could not set permissions for file "foo.test": no such file or directory}
+test unixFCmd-17.3 {SetPermissionsAttribute} -setup {
+    catch {file delete -force -- foo.test}
+} -constraints {unix notRoot} -body {
+    close [open foo.test w]
+    file attributes foo.test -permissions foo
+} -cleanup {
+    file delete -force -- foo.test
+} -returnCodes error -result {unknown permission string format "foo"}
+test unixFCmd-17.4 {SetPermissionsAttribute} -setup {
+    catch {file delete -force -- foo.test}
+} -constraints {unix notRoot} -body {
+    close [open foo.test w]
+    file attributes foo.test -permissions ---rwx
+} -cleanup {
+    file delete -force -- foo.test
+} -returnCodes error -result {unknown permission string format "---rwx"}
+
+close [open foo.test w]
+set ::i 4
+proc permcheck {testnum permList expected} {
+    test $testnum {SetPermissionsAttribute} {unix notRoot} {
+      set result {}
+      foreach permstr $permList {
+	file attributes foo.test -permissions $permstr
+	lappend result [file attributes foo.test -permissions]
+      }
+      set result
+    } $expected
+}
+permcheck unixFCmd-17.5   rwxrwxrwx	00777
+permcheck unixFCmd-17.6   r--r---w-	00442
+permcheck unixFCmd-17.7   {0 u+rwx,g+r u-w o+rwx} {00000 00740 00540 00547}
+permcheck unixFCmd-17.11  --x--x--x	00111
+permcheck unixFCmd-17.12  {0 a+rwx} {00000 00777}
+file delete -force -- foo.test
+
+test unixFCmd-18.1 {Unix pwd} -constraints {unix notRoot nonPortable} -setup {
+    set cd [pwd]
+} -body {
+    # This test is nonPortable because SunOS generates a weird error
+    # message when the current directory isn't readable.
+    set nd $cd/tstdir
+    file mkdir $nd
+    cd $nd
+    file attributes $nd -permissions 0000
+    pwd
+} -returnCodes error -cleanup {
+    cd $cd
+    file attributes $nd -permissions 0755
+    file delete $nd
+} -match glob -result {error getting working directory name:*}
+
+test unixFCmd-19.1 {GetReadOnlyAttribute - file not found} -setup {
+    catch {file delete -force -- foo.test}
+} -constraints {unix notRoot readonlyAttr} -returnCodes error -body {
+    file attributes foo.test -readonly
+} -result {could not read "foo.test": no such file or directory}
+test unixFCmd-19.2 {GetReadOnlyAttribute} -setup {
+    catch {file delete -force -- foo.test}
+} -constraints {unix notRoot readonlyAttr} -body {
+    close [open foo.test w]
+    file attribute foo.test -readonly
+} -cleanup {
+    file delete -force -- foo.test
+} -result 0
+
+test unixFCmd-20.1 {SetReadOnlyAttribute} -setup {
+    catch {file delete -force -- foo.test}
+} -constraints {unix notRoot readonlyAttr} -body {
+    close [open foo.test w]
+    list [catch {file attributes foo.test -readonly 1} msg] $msg \
+	    [catch {file attribute foo.test -readonly} msg] $msg \
+	    [catch {file delete -force -- foo.test}] \
+	    [catch {file attributes foo.test -readonly 0} msg] $msg \
+	    [catch {file attribute foo.test -readonly} msg] $msg
+} -cleanup {
+    file delete -force -- foo.test
+} -result {0 {} 0 1 1 0 {} 0 0}
+test unixFCmd-20.2 {SetReadOnlyAttribute} -setup {
+    catch {file delete -force -- foo.test}
+} -constraints {unix notRoot readonlyAttr} -returnCodes error -body {
+    file attributes foo.test -readonly 1
+} -result {could not read "foo.test": no such file or directory}
+
+# cleanup
+cleanup
+cd $oldcwd
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/tests/unixFile.test b/tests/unixFile.test
new file mode 100644
index 0000000..8147f48
--- /dev/null
+++ b/tests/unixFile.test
@@ -0,0 +1,65 @@
+# This file contains tests for the routines in the file tclUnixFile.c
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands.  Sourcing this file into Tcl runs the tests and
+# generates output for errors.  No output means no errors were found.
+#
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+    package require tcltest
+    namespace import -force ::tcltest::*
+}
+
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
+
+testConstraint testfindexecutable [llength [info commands testfindexecutable]]
+
+set oldpwd [pwd]
+cd [temporaryDirectory]
+
+catch {
+    set oldPath $env(PATH)
+    file attributes [makeFile "" junk] -perm 0777
+}
+set absPath [file join [temporaryDirectory] junk]
+
+test unixFile-1.1 {Tcl_FindExecutable} {testfindexecutable unix} {
+    set env(PATH) ""
+    testfindexecutable junk
+} $absPath
+test unixFile-1.2 {Tcl_FindExecutable} {testfindexecutable unix} {
+    set env(PATH) "/dummy"
+    testfindexecutable junk
+} {}
+test unixFile-1.3 {Tcl_FindExecutable} {testfindexecutable unix} {
+    set env(PATH) "/dummy:[pwd]"
+    testfindexecutable junk
+} $absPath
+test unixFile-1.4 {Tcl_FindExecutable} {testfindexecutable unix} {
+    set env(PATH) "/dummy:"
+    testfindexecutable junk
+} $absPath
+test unixFile-1.5 {Tcl_FindExecutable} {testfindexecutable unix} {
+    set env(PATH) "/dummy:/dummy"
+    testfindexecutable junk
+} {}
+test unixFile-1.6 {Tcl_FindExecutable} {testfindexecutable unix} {
+    set env(PATH) "/dummy::/dummy"
+    testfindexecutable junk
+} $absPath
+test unixFile-1.7 {Tcl_FindExecutable} {testfindexecutable unix} {
+    set env(PATH) ":/dummy"
+    testfindexecutable junk
+} $absPath
+
+# cleanup
+catch {set env(PATH) $oldPath}
+removeFile junk
+cd $oldpwd
+::tcltest::cleanupTests
+return
diff --git a/tests/unixForkEvent.test b/tests/unixForkEvent.test
new file mode 100644
index 0000000..120f362
--- /dev/null
+++ b/tests/unixForkEvent.test
@@ -0,0 +1,45 @@
+# This file contains a collection of tests for the procedures in the file
+# tclUnixNotify.c.  Sourcing this file into Tcl runs the tests and
+# generates output for errors.  No output means no errors were found.
+#
+# Copyright (c) 1995-1997 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+package require tcltest 2
+namespace import -force ::tcltest::*
+
+testConstraint testfork [llength [info commands testfork]]
+
+# Test if the notifier thread is well initialized in a forked interpreter
+# by Tcl_InitNotifier
+test unixforkevent-1.1 {fork and test writeable event} \
+    -constraints {testfork nonPortable} \
+    -body {
+	set myFolder [makeDirectory unixtestfork]
+	set pid [testfork]
+	if {$pid == 0} {
+	    # we are the forked process
+	    set result initialized
+	    set h [open [file join $myFolder test.txt] w]
+	    fileevent $h writable\
+		    "set result writable;\
+		    after cancel [after 1000 {set result timeout}]"
+	    vwait result
+	    close $h
+	    makeFile $result result.txt $myFolder
+	    exit
+	}
+	# we are the original process
+	while {![file readable [file join $myFolder result.txt]]} {}
+	viewFile result.txt $myFolder
+    } \
+    -result {writable} \
+    -cleanup { 
+	catch { removeFolder $myFolder }
+    }
+
+::tcltest::cleanupTests
+return
diff --git a/tests/unixInit.test b/tests/unixInit.test
new file mode 100644
index 0000000..05338ed
--- /dev/null
+++ b/tests/unixInit.test
@@ -0,0 +1,402 @@
+# The file tests the functions in the tclUnixInit.c file.
+#
+# This file contains a collection of tests for one or more of the Tcl built-in
+# commands.  Sourcing this file into Tcl runs the tests and generates output
+# for errors.  No output means no errors were found.
+#
+# Copyright (c) 1997 by Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution of
+# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+package require tcltest 2.2
+namespace import ::tcltest::*
+unset -nocomplain path
+catch {set oldlang $env(LANG)}
+set env(LANG) C
+
+test unixInit-1.1 {TclpInitPlatform: ignore SIGPIPE} {unix stdio} {
+    set x {}
+    # Watch out for a race condition here.  If tcltest is too slow to start
+    # then we'll kill it before it has a chance to set up its signal handler.
+    set f [open "|[list [interpreter]]" w+]
+    puts $f "puts hi"
+    flush $f
+    gets $f
+    exec kill -PIPE [pid $f]
+    lappend x [catch {close $f}]
+    set f [open "|[list [interpreter]]" w+]
+    puts $f "puts hi"
+    flush $f
+    gets $f
+    exec kill [pid $f]
+    lappend x [catch {close $f}]
+    set x
+} {0 1}
+# This test is really a test of code in tclUnixChan.c, but the channels are
+# set up as part of initialisation of the interpreter so the test seems to me
+# to fit here as well as anywhere else.
+test unixInit-1.2 {initialisation: standard channel type deduction} {unix stdio} {
+    # pipe1 is a connection to a server that reports what port it starts on,
+    # and delivers a constant string to the first client to connect to that
+    # port before exiting.
+    set pipe1 [open "|[list [interpreter]]" r+]
+    puts $pipe1 {
+	proc accept {channel host port} {
+	    puts $channel {puts [chan configure stdin -peername]; exit}
+	    close $channel
+	    exit
+	}
+	puts [chan configure [socket -server accept -myaddr 127.0.0.1 0] -sockname]
+	vwait forever \
+	    }
+    # Note the backslash above; this is important to make sure that the whole
+    # string is read before an [exit] can happen...
+    flush $pipe1
+    set port [lindex [gets $pipe1] 2]
+    set sock [socket localhost $port]
+    # pipe2 is a connection to a Tcl interpreter that takes its orders from
+    # the socket we hand it (i.e. the server we create above.)  These orders
+    # will tell it to print out the details about the socket it is taking
+    # instructions from, hopefully identifying it as a socket.  Which is what
+    # this test is all about.
+    set pipe2 [open "|[list [interpreter] <@$sock]" r]
+    set result [gets $pipe2]
+    # Clear any pending data; stops certain kinds of (non-important) errors
+    chan configure $pipe1 -blocking 0; gets $pipe1
+    chan configure $pipe2 -blocking 0; gets $pipe2
+    # Close the pipes and the socket.
+    close $pipe2
+    close $pipe1
+    catch {close $sock}
+    # Can't use normal comparison, as hostname varies due to some
+    # installations having a messed up /etc/hosts file.
+    if {
+	"127.0.0.1" eq [lindex $result 0] && $port == [lindex $result 2]
+    } then {
+	subst "OK"
+    } else {
+	subst "Expected: `[list 127.0.0.1 localhost $port]', Got `$result'"
+    }
+} {OK}
+
+# The unixInit-2.* tests were written to test the internal routine,
+# TclpInitLibraryPath.  That routine no longer does the things it used to do
+# so those tests are obsolete.  Skip them.
+
+skip [concat [skip] unixInit-2.*]
+
+test unixInit-2.0 {TclpInitLibraryPath: setting tclDefaultEncodingDir} {
+    set origDir [testgetdefenc]
+    testsetdefenc slappy
+    set path [testgetdefenc]
+    testsetdefenc $origDir
+    set path
+} {slappy}
+test unixInit-2.1 {TclpInitLibraryPath: value of installLib, developLib} -setup {
+    unset -nocomplain oldlibrary
+    if {[info exists env(TCL_LIBRARY)]} {
+	set oldlibrary $env(TCL_LIBRARY)
+	unset env(TCL_LIBRARY)
+    }
+} -body {
+    set path [getlibpath]
+    set installLib lib/tcl[info tclversion]
+    set developLib tcl[info patchlevel]/library
+    set prefix [file dirname [file dirname [interpreter]]]
+    list [string equal [lindex $path 0] $prefix/$installLib] \
+	[string equal [lindex $path 4] [file dirname $prefix]/$developLib]
+} -cleanup {
+    if {[info exists oldlibrary]} {
+	set env(TCL_LIBRARY) $oldlibrary
+	unset oldlibrary
+    }
+} -result {1 1}
+test unixInit-2.2 {TclpInitLibraryPath: TCL_LIBRARY} -setup {
+    unset -nocomplain oldlibrary
+    if {[info exists env(TCL_LIBRARY)]} {
+	set oldlibrary $env(TCL_LIBRARY)
+    }
+} -body {
+    # ((str != NULL) && (str[0] != '\0'))
+    set env(TCL_LIBRARY) sparkly
+    lindex [getlibpath] 0
+} -cleanup {
+    unset -nocomplain env(TCL_LIBRARY)
+    if {[info exists oldlibrary]} {
+	set env(TCL_LIBRARY) $oldlibrary
+	unset oldlibrary
+    }
+} -result "sparkly"
+test unixInit-2.3 {TclpInitLibraryPath: TCL_LIBRARY wrong version} -setup {
+    unset -nocomplain oldlibrary
+    if {[info exists env(TCL_LIBRARY)]} {
+	set oldlibrary $env(TCL_LIBRARY)
+    }
+} -body {
+    # ((pathc > 0) && (strcasecmp(installLib + 4, pathv[pathc - 1]) != 0))
+    set env(TCL_LIBRARY) /a/b/tcl1.7
+    lrange [getlibpath] 0 1
+} -cleanup {
+    unset -nocomplain env(TCL_LIBRARY)
+    if {[info exists oldlibrary]} {
+	set env(TCL_LIBRARY) $oldlibrary
+	unset oldlibrary
+    }
+} -result [list /a/b/tcl1.7 /a/b/tcl[info tclversion]]
+test unixInit-2.4 {TclpInitLibraryPath: TCL_LIBRARY: INTL} -setup {
+    if {[info exists env(TCL_LIBRARY)]} {
+	set oldlibrary $env(TCL_LIBRARY)
+    }
+} -body {
+    # Child process translates env variable from native encoding.
+    set env(TCL_LIBRARY) "\xa7"
+    lindex [getlibpath] 0
+} -cleanup {
+    unset -nocomplain env(TCL_LIBRARY) env(LANG)
+    if {[info exists oldlibrary]} {
+	set env(TCL_LIBRARY) $oldlibrary
+	unset oldlibrary
+    }
+} -result "\xa7"
+test unixInit-2.5 {TclpInitLibraryPath: compiled-in library path} {
+    # cannot test
+} {}
+test unixInit-2.6 {TclpInitLibraryPath: executable relative} -setup {
+    unset -nocomplain oldlibrary
+    if {[info exists env(TCL_LIBRARY)]} {
+	set oldlibrary $env(TCL_LIBRARY)
+    }
+    set env(TCL_LIBRARY) [info library]
+    makeDirectory tmp
+    makeDirectory [file join tmp sparkly]
+    makeDirectory [file join tmp sparkly bin]
+    file copy [interpreter] [file join [temporaryDirectory] tmp sparkly \
+	    bin tcltest]
+    makeDirectory [file join tmp sparkly lib]
+    makeDirectory [file join tmp sparkly lib tcl[info tclversion]]
+    makeFile {} [file join tmp sparkly lib tcl[info tclversion] init.tcl]
+} -body {
+    lrange [getlibpath [file join [temporaryDirectory] tmp sparkly \
+	    bin tcltest]] 1 2
+} -cleanup {
+    removeFile [file join tmp sparkly lib tcl[info tclversion] init.tcl]
+    removeDirectory [file join tmp sparkly lib tcl[info tclversion]]
+    removeDirectory [file join tmp sparkly lib]
+    removeDirectory [file join tmp sparkly bin]
+    removeDirectory [file join tmp sparkly]
+    removeDirectory tmp
+    unset env(TCL_LIBRARY)
+    if {[info exists oldlibrary]} {
+	set env(TCL_LIBRARY) $oldlibrary
+	unset oldlibrary
+    }
+} -result [list [temporaryDirectory]/tmp/sparkly/lib/tcl[info tclversion] [temporaryDirectory]/tmp/lib/tcl[info tclversion]]
+test unixInit-2.7 {TclpInitLibraryPath: compiled-in library path} {
+    # would need test command to get defaultLibDir and compare it to
+    # [lindex $auto_path end]
+} {}
+#
+# The following two tests write to the directory /tmp/sparkly instead of to
+# [temporaryDirectory].  This is because the failures tested by these tests
+# need paths near the "root" of the file system to present themselves.
+#
+test unixInit-2.8 {TclpInitLibraryPath: all absolute pathtype} -setup {
+    unset -nocomplain oldlibrary
+    if {[info exists env(TCL_LIBRARY)]} {
+	set oldlibrary $env(TCL_LIBRARY)
+    }
+    set env(TCL_LIBRARY) [info library]
+    # Checking for Bug 219416
+    # When a program that embeds the Tcl library, like tcltest, is installed
+    # near the "root" of the file system, there was a problem constructing
+    # directories relative to the executable.  When a relative ".." went past
+    # the root, relative path names were created rather than absolute
+    # pathnames.  In some cases, accessing past the root caused memory access
+    # violations too.
+    #
+    # The bug is now fixed, but here we check for it by making sure that the
+    # directories constructed relative to the executable are all absolute
+    # pathnames, even when the executable is installed near the root of the
+    # filesystem.
+    #
+    # The only directory near the root we are likely to have write access to
+    # is /tmp.
+    file delete -force /tmp/sparkly
+    file delete -force /tmp/lib/tcl[info tclversion]
+    file mkdir /tmp/sparkly
+    file copy [interpreter] /tmp/sparkly/tcltest
+    # Keep any existing /tmp/lib directory
+    set deletelib 1
+    if {[file exists /tmp/lib]} {
+	if {[file isdirectory /tmp/lib]} {
+	    set deletelib 0
+	} else {
+	    file delete -force /tmp/lib
+	}
+    }
+    # For a successful Tcl_Init, we need a [source]-able init.tcl in
+    # ../lib/tcl$version relative to the executable.
+    file mkdir /tmp/lib/tcl[info tclversion]
+    close [open /tmp/lib/tcl[info tclversion]/init.tcl w]
+} -body {
+    # Check that all directories in the library path are absolute pathnames
+    set allAbsolute 1
+    foreach dir [getlibpath /tmp/sparkly/tcltest] {
+	set allAbsolute [expr {$allAbsolute \
+		&& [string equal absolute [file pathtype $dir]]}]
+    }
+    set allAbsolute
+} -cleanup {
+    # Clean up temporary installation
+    file delete -force /tmp/sparkly
+    file delete -force /tmp/lib/tcl[info tclversion]
+    if {$deletelib} {file delete -force /tmp/lib}
+    unset env(TCL_LIBRARY)
+    if {[info exists oldlibrary]} {
+	set env(TCL_LIBRARY) $oldlibrary
+	unset oldlibrary
+    }
+} -result 1
+test unixInit-2.9 {TclpInitLibraryPath: paths relative to executable} -setup {
+    # Checking for Bug 438014
+    unset -nocomplain oldlibrary
+    if {[info exists env(TCL_LIBRARY)]} {
+	set oldlibrary $env(TCL_LIBRARY)
+    }
+    set env(TCL_LIBRARY) [info library]
+    file delete -force /tmp/sparkly
+    file delete -force /tmp/library
+    file mkdir /tmp/sparkly
+    file copy [interpreter] /tmp/sparkly/tcltest
+    file mkdir /tmp/library/
+    close [open /tmp/library/init.tcl w]
+} -body {
+    lrange [getlibpath /tmp/sparkly/tcltest] 1 5
+} -cleanup {
+    file delete -force /tmp/sparkly
+    file delete -force /tmp/library
+    unset env(TCL_LIBRARY)
+    if {[info exists oldlibrary]} {
+	set env(TCL_LIBRARY) $oldlibrary
+	unset oldlibrary
+    }
+} -result [list /tmp/lib/tcl[info tclversion] /lib/tcl[info tclversion] \
+        /tmp/library /library /tcl[info patchlevel]/library]
+test unixInit-2.10 {TclpInitLibraryPath: executable relative} -setup {
+    unset -nocomplain oldlibrary
+    if {[info exists env(TCL_LIBRARY)]} {
+	set oldlibrary $env(TCL_LIBRARY)
+    }
+    set env(TCL_LIBRARY) [info library]
+    set tmpDir [makeDirectory tmp]
+    set sparklyDir [makeDirectory sparkly $tmpDir]
+    set execPath [file join [makeDirectory bin $sparklyDir] tcltest]
+    file copy [interpreter] $execPath
+    set libDir [makeDirectory lib $sparklyDir]
+    set scriptDir [makeDirectory tcl[info tclversion] $libDir]
+    makeFile {} init.tcl $scriptDir
+    set saveDir [pwd]
+    cd $libDir
+} -body {
+    # Checking for Bug 832657
+    set x [lrange [getlibpath [file join .. bin tcltest]] 3 4]
+    foreach p $x {
+	lappend y [file normalize $p]
+    }
+    set y
+} -cleanup {
+    cd $saveDir
+    removeFile init.tcl $scriptDir
+    removeDirectory tcl[info tclversion] $libDir
+    file delete $execPath
+    removeDirectory bin $sparklyDir
+    removeDirectory lib $sparklyDir
+    removeDirectory sparkly $tmpDir
+    removeDirectory tmp
+    unset -nocomplain saveDir scriptDir libDir execPath sparklyDir tmpDir
+    unset -nocomplain x p y env(TCL_LIBRARY)
+    if {[info exists oldlibrary]} {
+	set env(TCL_LIBRARY) $oldlibrary
+	unset oldlibrary
+    }
+} -result [list [file join [temporaryDirectory] tmp sparkly library] \
+	[file join [temporaryDirectory] tmp library] ]
+
+test unixInit-3.1 {TclpSetInitialEncodings} -constraints {
+	unix stdio
+} -body {
+    set env(LANG) C
+    set f [open "|[list [interpreter]]" w+]
+    chan configure $f -buffering none
+    puts $f {puts [encoding system]; exit}
+    set enc [gets $f]
+    close $f
+    return $enc
+} -cleanup {
+    unset -nocomplain env(LANG)
+} -match regexp -result [expr {
+	($tcl_platform(os) eq "Darwin") ? "^utf-8$" : "^iso8859-15?$"}]
+test unixInit-3.2 {TclpSetInitialEncodings} -setup {
+    catch {set oldlc_all $env(LC_ALL)}
+} -constraints {unix stdio} -body {
+    set env(LANG) japanese
+    set env(LC_ALL) japanese
+    set f [open "|[list [interpreter]]" w+]
+    chan configure $f -buffering none
+    puts $f {puts [encoding system]; exit}
+    set enc [gets $f]
+    close $f
+    set validEncodings [list euc-jp]
+    if {[string match HP-UX $tcl_platform(os)]} {
+	# Some older HP-UX systems need us to accept this as valid Bug 453883
+	# reports that newer HP-UX systems report euc-jp like everybody else.
+	lappend validEncodings shiftjis
+    }
+    expr {$enc ni $validEncodings}
+} -cleanup {
+    unset -nocomplain env(LANG) env(LC_ALL)
+    catch {set env(LC_ALL) $oldlc_all}
+} -result 0
+
+test unixInit-4.1 {TclpSetVariables} {unix} {
+    # just make sure they exist
+    set a [list $tcl_library $tcl_pkgPath $tcl_platform(os)]
+    set a [list $tcl_platform(osVersion) $tcl_platform(machine)]
+    set tcl_platform(platform)
+} "unix"
+
+test unixInit-5.1 {Tcl_Init} {emptyTest unix} {
+    # test initScript
+} {}
+
+test unixInit-6.1 {Tcl_SourceRCFile} {emptyTest unix} {
+} {}
+
+test unixInit-7.1 {closed standard channel: Bug 772288} -constraints {
+    unix stdio
+} -body {
+    set tclsh [interpreter]
+    set crash [makeFile {puts [open /dev/null]} crash.tcl]
+    set crashtest [makeFile "
+	close stdin
+	[list exec $tclsh $crash]
+    " crashtest.tcl]
+    exec $tclsh $crashtest
+} -cleanup {
+    removeFile crash.tcl
+    removeFile crashtest.tcl
+} -returnCodes 0
+
+# cleanup
+unset -nocomplain env(LANG)
+catch {set env(LANG) $oldlang}
+unset -nocomplain path
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# fill-column: 78
+# End:
diff --git a/tests/unixNotfy.test b/tests/unixNotfy.test
new file mode 100644
index 0000000..2f03529
--- /dev/null
+++ b/tests/unixNotfy.test
@@ -0,0 +1,102 @@
+# This file contains tests for tclUnixNotfy.c.
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands.  Sourcing this file into Tcl runs the tests and
+# generates output for errors.  No output means no errors were found.
+#
+# Copyright (c) 1997 by Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+    package require tcltest 2
+    namespace import -force ::tcltest::*
+}
+
+# When run in a Tk shell, these tests hang.
+testConstraint noTk [expr {0 != [catch {package present Tk}]}]
+testConstraint thread [expr {0 == [catch {package require Thread 2.7-}]}]
+# Darwin always uses a threaded notifier
+testConstraint unthreaded [expr {
+    ![::tcl::pkgconfig get threaded]
+    && $tcl_platform(os) ne "Darwin"
+}]
+
+# The next two tests will hang if threads are enabled because the notifier
+# will not necessarily wait for ever in this case, so it does not generate
+# an error.
+test unixNotfy-1.1 {Tcl_DeleteFileHandler} -constraints {noTk unix unthreaded} -body {
+    catch {vwait x}
+    set f [open [makeFile "" foo] w]
+    fileevent $f writable {set x 1}
+    vwait x
+    close $f
+    list [catch {vwait x} msg] $msg
+} -result {1 {can't wait for variable "x": would wait forever}} -cleanup { 
+    catch { close $f }
+    catch { removeFile foo }
+}
+test unixNotfy-1.2 {Tcl_DeleteFileHandler} -constraints {noTk unix unthreaded} -body {
+    catch {vwait x}
+    set f1 [open [makeFile "" foo] w]
+    set f2 [open [makeFile "" foo2] w]
+    fileevent $f1 writable {set x 1}
+    fileevent $f2 writable {set y 1}
+    vwait x
+    close $f1
+    vwait y
+    close $f2
+    list [catch {vwait x} msg] $msg
+} -result {1 {can't wait for variable "x": would wait forever}} -cleanup {
+    catch { close $f1 }
+    catch { close $f2 }
+    catch { removeFile foo }
+    catch { removeFile foo2 }
+}
+
+test unixNotfy-2.1 {Tcl_DeleteFileHandler} \
+    -constraints {noTk unix thread} \
+    -body {
+	update
+	set f [open [makeFile "" foo] w]
+	fileevent $f writable {set x 1}
+	vwait x
+	close $f
+   	thread::create "thread::send [thread::id] {set x ok}"
+	vwait x
+	set x
+    } \
+    -result {ok} \
+    -cleanup {
+	catch { close $f }
+	catch { removeFile foo }
+    }
+test unixNotfy-2.2 {Tcl_DeleteFileHandler} \
+    -constraints {noTk unix thread} \
+    -body {
+	update
+	set f1 [open [makeFile "" foo] w]
+	set f2 [open [makeFile "" foo2] w]
+	fileevent $f1 writable {set x 1}
+	fileevent $f2 writable {set y 1}
+	vwait x
+	close $f1
+	vwait y
+	close $f2
+   	thread::create "thread::send [thread::id] {set x ok}"
+	vwait x
+	set x
+    } \
+    -result {ok} \
+    -cleanup { 
+	catch { close $f1 }
+	catch { close $f2 }
+	catch { removeFile foo }
+	catch { removeFile foo2 }
+    }
+
+# cleanup
+::tcltest::cleanupTests
+return
diff --git a/tests/unknown.test b/tests/unknown.test
new file mode 100644
index 0000000..e80d3a6
--- /dev/null
+++ b/tests/unknown.test
@@ -0,0 +1,65 @@
+# Commands covered:  unknown
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands.  Sourcing this file into Tcl runs the tests and
+# generates output for errors.  No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+package require tcltest 2
+namespace import ::tcltest::*
+
+unset -nocomplain x
+catch {rename unknown unknown.old}
+
+test unknown-1.1 {non-existent "unknown" command} {
+    list [catch {_non-existent_ foo bar} msg] $msg
+} {1 {invalid command name "_non-existent_"}}
+
+proc unknown {args} {
+    global x
+    set x $args
+}
+test unknown-2.1 {calling "unknown" command} {
+    foobar x y z
+    set x
+} {foobar x y z}
+test unknown-2.2 {calling "unknown" command with lots of args} {
+    foobar 1 2 3 4 5 6 7
+    set x
+} {foobar 1 2 3 4 5 6 7}
+test unknown-2.3 {calling "unknown" command with lots of args} {
+    foobar 1 2 3 4 5 6 7 8
+    set x
+} {foobar 1 2 3 4 5 6 7 8}
+test unknown-2.4 {calling "unknown" command with lots of args} {
+    foobar 1 2 3 4 5 6 7 8 9
+    set x
+} {foobar 1 2 3 4 5 6 7 8 9}
+
+test unknown-3.1 {argument quoting in calls to "unknown"} {
+    foobar \{ \} a\{b \; "\\" \$a a\[b \]
+    set x
+} "foobar \\{ \\} a\\{b {;} \\\\ {\$a} {a\[b} \\]"
+
+proc unknown args {
+    error "unknown failed"
+}
+test unknown-4.1 {errors in "unknown" procedure} {
+    list [catch {non-existent a b} msg] $msg $errorCode
+} {1 {unknown failed} NONE}
+
+# cleanup
+catch {rename unknown {}}
+catch {rename unknown.old unknown}
+cleanupTests
+return 
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/tests/unload.test b/tests/unload.test
new file mode 100644
index 0000000..73f1091
--- /dev/null
+++ b/tests/unload.test
@@ -0,0 +1,313 @@
+# Commands covered:  unload
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands.  Sourcing this file into Tcl runs the tests and
+# generates output for errors.  No output means no errors were found.
+#
+# Copyright (c) 1995 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+# Copyright (c) 2003-2004 by Georgios Petasis
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+    package require tcltest 2
+    namespace import -force ::tcltest::*
+}
+
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
+
+# Figure out what extension is used for shared libraries on this
+# platform.
+if {![info exists ext]} {
+    set ext [info sharedlibextension]
+}
+
+# Tests require the existence of one of the DLLs in the dltest directory.
+set testDir [file join [file dirname [info nameofexecutable]] dltest]
+set x [file join $testDir pkgua$ext]
+set dll "[file tail $x]Required"
+testConstraint $dll [file readable $x]
+
+# Tests also require that this DLL has not already been loaded.
+set loaded "[file tail $x]Loaded"
+set alreadyLoaded [info loaded]
+testConstraint $loaded [expr {![string match *pkgua* $alreadyLoaded]}]
+
+set alreadyTotalLoaded [info loaded]
+
+# Certain tests require the 'teststaticpkg' command from tcltest
+testConstraint teststaticpkg [llength [info commands teststaticpkg]]
+
+# Certain tests need the 'testsimplefilsystem' in tcltest
+testConstraint testsimplefilesystem \
+	[llength [info commands testsimplefilesystem]]
+
+proc loadIfNotPresent {pkg args} {
+    global testDir ext
+    set loaded [lmap x [info loaded {*}$args] {lindex $x 1}]
+    if {[string totitle $pkg] ni $loaded} {
+	load [file join $testDir $pkg$ext]
+    }
+}
+
+# Basic tests: parameter testing...
+test unload-1.1 {basic errors} -returnCodes error -body {
+    unload
+} -result {wrong # args: should be "unload ?-switch ...? fileName ?packageName? ?interp?"}
+test unload-1.2 {basic errors} -returnCodes error -body {
+    unload a b c d
+} -result {wrong # args: should be "unload ?-switch ...? fileName ?packageName? ?interp?"}
+test unload-1.3 {basic errors} -returnCodes error -body {
+    unload a b foobar
+} -result {could not find interpreter "foobar"}
+test unload-1.4 {basic errors} -returnCodes error -body {
+    unload {}
+} -result {must specify either file name or package name}
+test unload-1.5 {basic errors} -returnCodes error -body {
+    unload {} {}
+} -result {must specify either file name or package name}
+test unload-1.6 {basic errors} -returnCodes error -body {
+    unload {} Unknown
+} -result {package "Unknown" is loaded statically and cannot be unloaded}
+test unload-1.7 {-nocomplain switch} {
+    unload -nocomplain {} Unknown
+} {}
+
+set pkgua_loaded {}
+set pkgua_detached {}
+set pkgua_unloaded {}
+# Tests for loading/unloading in trusted (non-safe) interpreters...
+test unload-2.1 {basic loading of non-unloadable package, with guess for package name} [list $dll $loaded] {
+    loadIfNotPresent pkga
+    list [pkga_eq abc def] [lsort [info commands pkga_*]]
+} {0 {pkga_eq pkga_quote}}
+test unload-2.2 {basic loading of unloadable package, with guess for package name} [list $dll $loaded] {
+    list $pkgua_loaded $pkgua_detached $pkgua_unloaded \
+	    [load [file join $testDir pkgua$ext]] \
+	    [pkgua_eq abc def] [lsort [info commands pkgua_*]] \
+	    $pkgua_loaded $pkgua_detached $pkgua_unloaded
+} {{} {} {} {} 0 {pkgua_eq pkgua_quote} . {} {}}
+test unload-2.3 {basic unloading of non-unloadable package, with guess for package name} -setup {
+    loadIfNotPresent pkga
+} -constraints [list $dll $loaded] -returnCodes error -match glob -body {
+    unload [file join $testDir pkga$ext]
+} -result {file "*" cannot be unloaded under a trusted interpreter}
+test unload-2.4 {basic unloading of unloadable package, with guess for package name} -setup {
+    loadIfNotPresent pkgua
+} -constraints [list $dll $loaded] -body {
+    list $pkgua_loaded $pkgua_detached $pkgua_unloaded \
+	    [unload [file join $testDir pkgua$ext]] \
+	    [info commands pkgua_*] \
+	    $pkgua_loaded $pkgua_detached $pkgua_unloaded
+} -result {. {} {} {} {} . . .}
+test unload-2.5 {reloading of unloaded package, with guess for package name} -setup {
+    if {$pkgua_loaded eq ""} {
+	loadIfNotPresent pkgua
+	unload [file join $testDir pkgua$ext]
+    }
+} -constraints [list $dll $loaded] -body {
+    list $pkgua_loaded $pkgua_detached $pkgua_unloaded \
+	    [load [file join $testDir pkgua$ext]] \
+	    [pkgua_eq abc def] [lsort [info commands pkgua_*]] \
+	    $pkgua_loaded $pkgua_detached $pkgua_unloaded
+} -result {. . . {} 0 {pkgua_eq pkgua_quote} .. . .}
+test unload-2.6 {basic unloading of re-loaded package, with guess for package name} -setup {
+    # Establish expected state
+    if {$pkgua_loaded eq ""} {
+	loadIfNotPresent pkgua
+	unload [file join $testDir pkgua$ext]
+	load [file join $testDir pkgua$ext]
+    }
+} -constraints [list $dll $loaded] -body {
+    list $pkgua_loaded $pkgua_detached $pkgua_unloaded \
+	    [unload [file join $testDir pkgua$ext]] \
+	    [info commands pkgua_*] \
+	    $pkgua_loaded $pkgua_detached $pkgua_unloaded
+} -result {.. . . {} {} .. .. ..}
+
+# Tests for loading/unloading in safe interpreters...
+interp create -safe child
+child eval {
+    set pkgua_loaded {}
+    set pkgua_detached {}
+    set pkgua_unloaded {}
+}
+test unload-3.1 {basic loading of non-unloadable package in a safe interpreter, with package name conversion} \
+	[list $dll $loaded] {
+    catch {rename pkgb_sub {}}
+    load [file join $testDir pkgb$ext] pKgB child
+    list [child eval pkgb_sub 44 13] [catch {child eval pkgb_unsafe} msg] $msg \
+         [catch {pkgb_sub 12 10} msg2] $msg2
+} {31 1 {invalid command name "pkgb_unsafe"} 1 {invalid command name "pkgb_sub"}}
+test unload-3.2 {basic loading of unloadable package in a safe interpreter, with package name conversion} \
+	[list $dll $loaded] {
+    list [child eval {list $pkgua_loaded $pkgua_detached $pkgua_unloaded}] \
+	    [load [file join $testDir pkgua$ext] pKgUA child] \
+	    [child eval pkgua_eq abc def] \
+	    [lsort [child eval info commands pkgua_*]] \
+	    [child eval {list $pkgua_loaded $pkgua_detached $pkgua_unloaded}]
+} {{{} {} {}} {} 0 {pkgua_eq pkgua_quote} {. {} {}}}
+test unload-3.3 {unloading of a package that has never been loaded from a safe interpreter} -setup {
+    loadIfNotPresent pkga
+} -constraints [list $dll $loaded] -returnCodes error -match glob -body {
+    unload [file join $testDir pkga$ext] {} child
+} -result {file "*" has never been loaded in this interpreter}
+test unload-3.4 {basic unloading of a non-unloadable package from a safe interpreter, with guess for package name} -setup {
+    if {[lsearch -index 1 [info loaded child] Pkgb] == -1} {
+	load [file join $testDir pkgb$ext] pKgB child
+    }
+} -constraints [list $dll $loaded] -returnCodes error -match glob -body {
+    unload [file join $testDir pkgb$ext] {} child
+} -result {file "*" cannot be unloaded under a safe interpreter}
+test unload-3.5 {basic unloading of an unloadable package from a safe interpreter, with guess for package name} -setup {
+    if {[lsearch -index 1 [info loaded child] Pkgua] == -1} {
+	load [file join $testDir pkgua$ext] pkgua child
+    }
+} -constraints [list $dll $loaded] -body {
+    list [child eval {list $pkgua_loaded $pkgua_detached $pkgua_unloaded}] \
+	    [unload [file join $testDir pkgua$ext] {} child] \
+	    [child eval info commands pkgua_*] \
+	    [child eval {list $pkgua_loaded $pkgua_detached $pkgua_unloaded}]
+} -result {{. {} {}} {} {} {. . .}}
+test unload-3.6 {reloading of unloaded package in a safe interpreter, with guess for package name} -setup {
+    if {[child eval set pkgua_loaded] eq ""} {
+	load [file join $testDir pkgua$ext] {} child
+	unload [file join $testDir pkgua$ext] {} child
+    }
+} -constraints [list $dll $loaded] -body {
+    list [child eval {list $pkgua_loaded $pkgua_detached $pkgua_unloaded}] \
+	    [load [file join $testDir pkgua$ext] {} child] \
+	    [child eval pkgua_eq abc def] \
+	    [lsort [child eval info commands pkgua_*]] \
+	    [child eval {list $pkgua_loaded $pkgua_detached $pkgua_unloaded}]
+} -result {{. . .} {} 0 {pkgua_eq pkgua_quote} {.. . .}}
+test unload-3.7 {basic unloading of re-loaded package from a safe interpreter, with package name conversion} -setup {
+    if {[child eval set pkgua_loaded] eq ""} {
+	load [file join $testDir pkgua$ext] {} child
+	unload [file join $testDir pkgua$ext] {} child
+	load [file join $testDir pkgua$ext] {} child
+    }
+} -constraints [list $dll $loaded] -body {
+    list [child eval {list $pkgua_loaded $pkgua_detached $pkgua_unloaded}] \
+	    [unload [file join $testDir pkgua$ext] pKgUa child] \
+	    [child eval info commands pkgua_*] \
+	    [child eval {list $pkgua_loaded $pkgua_detached $pkgua_unloaded}]
+} -result {{.. . .} {} {} {.. .. ..}}
+
+# Tests for loading/unloading of a package among multiple interpreters...
+interp create child-trusted
+child-trusted eval {
+    set pkgua_loaded {}
+    set pkgua_detached {}
+    set pkgua_unloaded {}
+}
+array set load {M 0 C 0 T 0}
+## Load package in main trusted interpreter...
+test unload-4.1 {loading of unloadable package in trusted interpreter, with guess for package name} -setup {
+    set pkgua_loaded ""
+    set pkgua_detached ""
+    set pkgua_unloaded ""
+    incr load(M)
+} -constraints [list $dll $loaded] -body {
+    list [list $pkgua_loaded $pkgua_detached $pkgua_unloaded] \
+	    [load [file join $testDir pkgua$ext]] \
+	    [pkgua_eq abc def] [lsort [info commands pkgua_*]] \
+	    [list $pkgua_loaded $pkgua_detached $pkgua_unloaded]
+} -result {{{} {} {}} {} 0 {pkgua_eq pkgua_quote} {. {} {}}}
+## Load package in child-safe interpreter...
+test unload-4.2 {basic loading of unloadable package in a safe interpreter, with package name conversion} -setup {
+    child eval {
+	set pkgua_loaded ""
+	set pkgua_detached ""
+	set pkgua_unloaded ""
+    }
+    incr load(C)
+} -constraints [list $dll $loaded] -body {
+    list [child eval {list $pkgua_loaded $pkgua_detached $pkgua_unloaded}] \
+	    [load [file join $testDir pkgua$ext] pKgUA child] \
+	    [child eval pkgua_eq abc def] \
+	    [lsort [child eval info commands pkgua_*]] \
+	    [child eval {list $pkgua_loaded $pkgua_detached $pkgua_unloaded}]
+} -result {{{} {} {}} {} 0 {pkgua_eq pkgua_quote} {. {} {}}}
+## Load package in child-trusted interpreter...
+test unload-4.3 {basic loading of unloadable package in a second trusted interpreter, with package name conversion} -setup {
+    incr load(T)
+} -constraints [list $dll $loaded] -body {
+    list [child-trusted eval {list $pkgua_loaded $pkgua_detached $pkgua_unloaded}] \
+	    [load [file join $testDir pkgua$ext] pkguA child-trusted] \
+	    [child-trusted eval pkgua_eq abc def] \
+	    [lsort [child-trusted eval info commands pkgua_*]] \
+	    [child-trusted eval {list $pkgua_loaded $pkgua_detached $pkgua_unloaded}]
+} -result {{{} {} {}} {} 0 {pkgua_eq pkgua_quote} {. {} {}}}
+## Unload the package from the main trusted interpreter...
+test unload-4.4 {basic unloading of unloadable package from trusted interpreter, with guess for package name} -setup {
+    if {!$load(M)} {
+	load [file join $testDir pkgua$ext]
+    }
+    if {!$load(C)} {
+	load [file join $testDir pkgua$ext] {} child
+	incr load(C)
+    }
+    if {!$load(T)} {
+	load [file join $testDir pkgua$ext] {} child-trusted
+	incr load(T)
+    }
+} -constraints [list $dll $loaded] -body {
+    list [list $pkgua_loaded $pkgua_detached $pkgua_unloaded] \
+	    [unload [file join $testDir pkgua$ext]] \
+	    [info commands pkgua_*] \
+	    [list $pkgua_loaded $pkgua_detached $pkgua_unloaded]
+} -result {{. {} {}} {} {} {. . {}}}
+## Unload the package from the child safe interpreter...
+test unload-4.5 {basic unloading of unloadable package from a safe interpreter, with guess for package name} -setup {
+    if {!$load(C)} {
+	load [file join $testDir pkgua$ext] {} child
+    }
+    if {!$load(T)} {
+	load [file join $testDir pkgua$ext] {} child-trusted
+	incr load(T)
+    }
+} -constraints [list $dll $loaded] -body {
+    list [child eval {list $pkgua_loaded $pkgua_detached $pkgua_unloaded}] \
+	    [unload [file join $testDir pkgua$ext] {} child] \
+	    [child eval info commands pkgua_*] \
+	    [child eval {list $pkgua_loaded $pkgua_detached $pkgua_unloaded}]
+} -result {{. {} {}} {} {} {. . {}}}
+## Unload the package from the child trusted interpreter...
+test unload-4.6 {basic unloading of unloadable package from a safe interpreter, with guess for package name} -setup {
+    if {!$load(T)} {
+	load [file join $testDir pkgua$ext] {} child-trusted
+    }
+} -constraints [list $dll $loaded] -body {
+    list [child-trusted eval {list $pkgua_loaded $pkgua_detached $pkgua_unloaded}] \
+	    [unload [file join $testDir pkgua$ext] {} child-trusted] \
+	    [child-trusted eval info commands pkgua_*] \
+	    [child-trusted eval {list $pkgua_loaded $pkgua_detached $pkgua_unloaded}]
+} -result {{. {} {}} {} {} {. . .}}
+
+test unload-5.1 {unload a module loaded from vfs} \
+     -constraints [list $dll $loaded testsimplefilesystem] \
+     -setup {
+	 set dir [pwd]
+	 cd $testDir
+	 testsimplefilesystem 1
+	 load simplefs:/pkgua$ext pkgua
+     } \
+    -body {
+	list [catch {unload simplefs:/pkgua$ext} msg] $msg
+    } \
+    -result {0 {}}
+
+# cleanup
+interp delete child
+interp delete child-trusted
+unset ext
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/tests/uplevel.test b/tests/uplevel.test
new file mode 100644
index 0000000..9ecc0d5
--- /dev/null
+++ b/tests/uplevel.test
@@ -0,0 +1,305 @@
+# Commands covered:  uplevel
+#
+# This file contains a collection of tests for one or more of the Tcl built-in
+# commands.  Sourcing this file into Tcl runs the tests and generates output
+# for errors.  No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution of
+# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+    package require tcltest
+    namespace import -force ::tcltest::*
+}
+
+proc a {x y} {
+    newset z [expr $x+$y]
+    return $z
+}
+proc newset {name value} {
+    uplevel set $name $value
+    uplevel 1 {uplevel 1 {set xyz 22}}
+}
+
+test uplevel-1.1 {simple operation} {
+    set xyz 0
+    a 22 33
+} 55
+test uplevel-1.2 {command is another uplevel command} {
+    set xyz 0
+    a 22 33
+    set xyz
+} 22
+
+proc a1 {} {
+    b1
+    global a a1
+    set a $x
+    set a1 $y
+}
+proc b1 {} {
+    c1
+    global b b1
+    set b $x
+    set b1 $y
+}
+proc c1 {} {
+    uplevel 1 set x 111
+    uplevel #2 set y 222
+    uplevel 2 set x 333
+    uplevel #1 set y 444
+    uplevel 3 set x 555
+    uplevel #0 set y 666
+}
+a1
+test uplevel-2.1 {relative and absolute uplevel} {set a} 333
+test uplevel-2.2 {relative and absolute uplevel} {set a1} 444
+test uplevel-2.3 {relative and absolute uplevel} {set b} 111
+test uplevel-2.4 {relative and absolute uplevel} {set b1} 222
+test uplevel-2.5 {relative and absolute uplevel} {set x} 555
+test uplevel-2.6 {relative and absolute uplevel} {set y} 666
+
+test uplevel-3.1 {uplevel to same level} {
+    set x 33
+    uplevel #0 set x 44
+    set x
+} 44
+test uplevel-3.2 {uplevel to same level} {
+    set x 33
+    uplevel 0 set x
+} 33
+test uplevel-3.3 {uplevel to same level} {
+    set y xxx
+    proc a1 {} {set y 55; uplevel 0 set y 66; return $y}
+    a1
+} 66
+test uplevel-3.4 {uplevel to same level} {
+    set y zzz
+    proc a1 {} {set y 55; uplevel #1 set y}
+    a1
+} 55
+
+test uplevel-4.1 {error: non-existent level} -returnCodes error -body {
+    apply {{} {
+	uplevel #2 {set y 222}
+    }}
+} -result {bad level "#2"}
+test uplevel-4.2 {error: non-existent level} -returnCodes error -body {
+    apply {{} {
+	uplevel 3 {set a b}
+    }}
+} -result {bad level "3"}
+test uplevel-4.3 {error: not enough args} -returnCodes error -body {
+    uplevel
+} -result {wrong # args: should be "uplevel ?level? command ?arg ...?"}
+test uplevel-4.4 {error: not enough args} -returnCodes error -body {
+    apply {{} {
+	uplevel 1
+    }}
+} -result {wrong # args: should be "uplevel ?level? command ?arg ...?"}
+test uplevel-4.5 {level parsing} {
+    apply {{} {uplevel 0 {}}}
+} {}
+test uplevel-4.6 {level parsing} {
+    apply {{} {uplevel #0 {}}}
+} {}
+test uplevel-4.7 {level parsing} {
+    apply {{} {uplevel [expr 0] {}}}
+} {}
+test uplevel-4.8 {level parsing} {
+    apply {{} {uplevel #[expr 0] {}}}
+} {}
+test uplevel-4.9 {level parsing} {
+    apply {{} {uplevel -0 {}}}
+} {}
+test uplevel-4.10 {level parsing} {
+    apply {{} {uplevel #-0 {}}}
+} {}
+test uplevel-4.11 {level parsing} {
+    apply {{} {uplevel [expr -0] {}}}
+} {}
+test uplevel-4.12 {level parsing} {
+    apply {{} {uplevel #[expr -0] {}}}
+} {}
+test uplevel-4.13 {level parsing} {
+    apply {{} {uplevel 1 {}}}
+} {}
+test uplevel-4.14 {level parsing} {
+    apply {{} {uplevel #1 {}}}
+} {}
+test uplevel-4.15 {level parsing} {
+    apply {{} {uplevel [expr 1] {}}}
+} {}
+test uplevel-4.16 {level parsing} {
+    apply {{} {uplevel #[expr 1] {}}}
+} {}
+test uplevel-4.17 {level parsing} {
+    apply {{} {uplevel -0xffffffff {}}}
+} {}
+test uplevel-4.18 {level parsing} {
+    apply {{} {uplevel #-0xffffffff {}}}
+} {}
+test uplevel-4.19 {level parsing} {
+    apply {{} {uplevel [expr -0xffffffff] {}}}
+} {}
+test uplevel-4.20 {level parsing} {
+    apply {{} {uplevel #[expr -0xffffffff] {}}}
+} {}
+test uplevel-4.21 {level parsing} -body {
+    apply {{} {uplevel -1 {}}}
+} -returnCodes error -result {invalid command name "-1"}
+test uplevel-4.22 {level parsing} -body {
+    apply {{} {uplevel #-1 {}}}
+} -returnCodes error -result {bad level "#-1"}
+test uplevel-4.23 {level parsing} -body {
+    apply {{} {uplevel [expr -1] {}}}
+} -returnCodes error -result {invalid command name "-1"}
+test uplevel-4.24 {level parsing} -body {
+    apply {{} {uplevel #[expr -1] {}}}
+} -returnCodes error -result {bad level "#-1"}
+test uplevel-4.25 {level parsing} -body {
+    apply {{} {uplevel 0xffffffff {}}}
+} -returnCodes error -result {bad level "0xffffffff"}
+test uplevel-4.26 {level parsing} -body {
+    apply {{} {uplevel #0xffffffff {}}}
+} -returnCodes error -result {bad level "#0xffffffff"}
+test uplevel-4.27 {level parsing} -body {
+    apply {{} {uplevel [expr 0xffffffff] {}}}
+} -returnCodes error -result {bad level "4294967295"}
+test uplevel-4.28 {level parsing} -body {
+    apply {{} {uplevel #[expr 0xffffffff] {}}}
+} -returnCodes error -result {bad level "#4294967295"}
+test uplevel-4.29 {level parsing} -body {
+    apply {{} {uplevel 0.2 {}}}
+} -returnCodes error -result {bad level "0.2"}
+test uplevel-4.30 {level parsing} -body {
+    apply {{} {uplevel #0.2 {}}}
+} -returnCodes error -result {bad level "#0.2"}
+test uplevel-4.31 {level parsing} -body {
+    apply {{} {uplevel [expr 0.2] {}}}
+} -returnCodes error -result {bad level "0.2"}
+test uplevel-4.32 {level parsing} -body {
+    apply {{} {uplevel #[expr 0.2] {}}}
+} -returnCodes error -result {bad level "#0.2"}
+test uplevel-4.33 {level parsing} -body {
+    apply {{} {uplevel .2 {}}}
+} -returnCodes error -result {invalid command name ".2"}
+test uplevel-4.34 {level parsing} -body {
+    apply {{} {uplevel #.2 {}}}
+} -returnCodes error -result {bad level "#.2"}
+test uplevel-4.35 {level parsing} -body {
+    apply {{} {uplevel [expr .2] {}}}
+} -returnCodes error -result {bad level "0.2"}
+test uplevel-4.36 {level parsing} -body {
+    apply {{} {uplevel #[expr .2] {}}}
+} -returnCodes error -result {bad level "#0.2"}
+
+
+
+
+proc a2 {} {
+    uplevel a3
+}
+proc a3 {} {
+    global x y
+    set x [info level]
+    set y [info level 1]
+}
+a2
+test uplevel-5.1 {info level} {set x} 1
+test uplevel-5.2 {info level} {set y} a3
+
+namespace eval ns1 {
+    proc set args {return ::ns1}
+}
+proc a2 {} {
+    uplevel {set x ::}
+}
+test uplevel-6.1 {uplevel and shadowed cmds} {
+    set res [namespace eval ns1 a2]
+    lappend res [namespace eval ns2 a2]
+    lappend res [namespace eval ns1 a2]
+    namespace eval ns1 {rename set {}}
+    lappend res [namespace eval ns1 a2]
+} {::ns1 :: ::ns1 ::}
+
+#
+# These tests verify that upleveled scripts run in the correct level and access
+# the proper variables.
+#
+
+test uplevel-7.1 {var access, no LVT in either level} -setup {
+    set x 1
+    unset -nocomplain y z
+} -body {
+    namespace eval foo {
+	set x 2 
+	set y 2
+	uplevel 1 {
+	    set x 3
+	    set y 3
+	    set z 3
+	}
+    }
+    list $x $y $z
+} -cleanup {
+    namespace delete foo
+    unset -nocomplain x y z
+} -result {3 3 3}
+
+test uplevel-7.2 {var access, no LVT in upper level} -setup {
+    set x 1
+    unset -nocomplain y z
+} -body {
+    proc foo {} {
+	set x 2 
+	set y 2
+	uplevel 1 {
+	    set x 3
+	    set y 3
+	    set z 3
+	}
+    }
+    foo
+    list $x $y $z
+} -cleanup {
+    rename foo {}
+    unset -nocomplain x y z
+} -result {3 3 3}
+
+test uplevel-7.3 {var access, LVT in upper level} -setup {
+    proc moo {} {
+	set x 1; #var in LVT
+	unset -nocomplain y z
+	foo
+	list $x $y $z
+    }
+} -body {
+    proc foo {} {
+	set x 2 
+	set y 2
+	uplevel 1 {
+	    set x 3
+	    set y 3
+	    set z 3
+	}
+    }
+    foo
+    moo
+} -cleanup {
+    rename foo {}
+    rename moo {}
+} -result {3 3 3}
+
+# cleanup
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# fill-column: 78
+# End:
diff --git a/tests/upvar.test b/tests/upvar.test
new file mode 100644
index 0000000..5ea870d
--- /dev/null
+++ b/tests/upvar.test
@@ -0,0 +1,588 @@
+# Commands covered:  'upvar', 'namespace upvar'
+#
+# This file contains a collection of tests for one or more of the Tcl built-in
+# commands. Sourcing this file into Tcl runs the tests and generates output
+# for errors. No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution of
+# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+    package require tcltest 2
+    namespace import -force ::tcltest::*
+}
+
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
+
+testConstraint testupvar [llength [info commands testupvar]]
+
+test upvar-1.1 {reading variables with upvar} {
+    proc p1 {a b} {set c 22; set d 33; p2}
+    proc p2 {} {upvar a x1 b x2 c x3 d x4; set a abc; list $x1 $x2 $x3 $x4 $a}
+    p1 foo bar
+} {foo bar 22 33 abc}
+test upvar-1.2 {reading variables with upvar} {
+    proc p1 {a b} {set c 22; set d 33; p2}
+    proc p2 {} {p3}
+    proc p3 {} {upvar 2 a x1 b x2 c x3 d x4; set a abc; list $x1 $x2 $x3 $x4 $a}
+    p1 foo bar
+} {foo bar 22 33 abc}
+test upvar-1.3 {reading variables with upvar} {
+    proc p1 {a b} {set c 22; set d 33; p2}
+    proc p2 {} {p3}
+    proc p3 {} {
+	upvar #1 a x1 b x2 c x3 d x4
+	set a abc
+	list $x1 $x2 $x3 $x4 $a
+    }
+    p1 foo bar
+} {foo bar 22 33 abc}
+test upvar-1.4 {reading variables with upvar} {
+    set x1 44
+    set x2 55
+    proc p1 {} {p2}
+    proc p2 {} {
+	upvar 2 x1 x1 x2 a
+	upvar #0 x1 b
+	set c $b
+	incr b 3
+	list $x1 $a $b
+    }
+    p1
+} {47 55 47}
+test upvar-1.5 {reading array elements with upvar} {
+    proc p1 {} {set a(0) zeroth; set a(1) first; p2}
+    proc p2 {} {upvar a(0) x; set x}
+    p1
+} {zeroth}
+
+test upvar-2.1 {writing variables with upvar} {
+    proc p1 {a b} {set c 22; set d 33; p2; list $a $b $c $d}
+    proc p2 {} {
+	upvar a x1 b x2 c x3 d x4
+	set x1 14
+	set x4 88
+    }
+    p1 foo bar
+} {14 bar 22 88}
+test upvar-2.2 {writing variables with upvar} {
+    set x1 44
+    set x2 55
+    proc p1 {x1 x2} {
+	upvar #0 x1 a
+	upvar x2 b
+	set a $x1
+	set b $x2
+    }
+    p1 newbits morebits
+    list $x1 $x2
+} {newbits morebits}
+test upvar-2.3 {writing variables with upvar} {
+    catch {unset x1}
+    catch {unset x2}
+    proc p1 {x1 x2} {
+	upvar #0 x1 a
+	upvar x2 b
+	set a $x1
+	set b $x2
+    }
+    p1 newbits morebits
+    list [catch {set x1} msg] $msg [catch {set x2} msg] $msg
+} {0 newbits 0 morebits}
+test upvar-2.4 {writing array elements with upvar} {
+    proc p1 {} {set a(0) zeroth; set a(1) first; list [p2] $a(0)}
+    proc p2 {} {upvar a(0) x; set x xyzzy}
+    p1
+} {xyzzy xyzzy}
+
+test upvar-3.1 {unsetting variables with upvar} {
+    proc p1 {a b} {set c 22; set d 33; p2; lsort [info vars]}
+    proc p2 {} {
+	upvar 1 a x1 d x2
+	unset x1 x2
+    }
+    p1 foo bar
+} {b c}
+test upvar-3.2 {unsetting variables with upvar} {
+    proc p1 {a b} {set c 22; set d 33; p2; lsort [info vars]}
+    proc p2 {} {
+	upvar 1 a x1 d x2
+	unset x1 x2
+	set x2 28
+    }
+    p1 foo bar
+} {b c d}
+test upvar-3.3 {unsetting variables with upvar} {
+    set x1 44
+    set x2 55
+    proc p1 {} {p2}
+    proc p2 {} {
+	upvar 2 x1 a
+	upvar #0 x2 b
+	unset a b
+    }
+    p1
+    list [info exists x1] [info exists x2]
+} {0 0}
+test upvar-3.4 {unsetting variables with upvar} {
+    set x1 44
+    set x2 55
+    proc p1 {} {
+	upvar x1 a x2 b
+	unset a b
+	set b 118
+    }
+    p1
+    list [info exists x1] [catch {set x2} msg] $msg
+} {0 0 118}
+test upvar-3.5 {unsetting array elements with upvar} {
+    proc p1 {} {
+	set a(0) zeroth
+	set a(1) first
+	set a(2) second
+	p2
+	array names a
+    }
+    proc p2 {} {upvar a(0) x; unset x}
+    lsort [p1]
+} {1 2}
+test upvar-3.6 {unsetting then resetting array elements with upvar} {
+    proc p1 {} {
+	set a(0) zeroth
+	set a(1) first
+	set a(2) second
+	p2
+	list [lsort [array names a]] [catch {set a(0)} msg] $msg
+    }
+    proc p2 {} {upvar a(0) x; unset x; set x 12345}
+    p1
+} {{0 1 2} 0 12345}
+
+test upvar-4.1 {nested upvars} {
+    set x1 88
+    proc p1 {a b} {set c 22; set d 33; p2}
+    proc p2 {} {global x1; upvar c x2; p3}
+    proc p3 {} {
+	upvar x1 a x2 b
+	list $a $b
+    }
+    p1 14 15
+} {88 22}
+test upvar-4.2 {nested upvars} {
+    set x1 88
+    proc p1 {a b} {set c 22; set d 33; p2; list $a $b $c $d}
+    proc p2 {} {global x1; upvar c x2; p3}
+    proc p3 {} {
+	upvar x1 a x2 b
+	set a foo
+	set b bar
+    }
+    list [p1 14 15] $x1
+} {{14 15 bar 33} foo}
+
+proc tproc {args} {global x; set x [list $args [uplevel info vars]]}
+test upvar-5.1 {traces involving upvars} {
+    proc p1 {a b} {set c 22; set d 33; trace var c rw tproc; p2}
+    proc p2 {} {upvar c x1; set x1 22}
+    set x ---
+    p1 foo bar
+    set x
+} {{x1 {} w} x1}
+test upvar-5.2 {traces involving upvars} {
+    proc p1 {a b} {set c 22; set d 33; trace var c rw tproc; p2}
+    proc p2 {} {upvar c x1; set x1}
+    set x ---
+    p1 foo bar
+    set x
+} {{x1 {} r} x1}
+test upvar-5.3 {traces involving upvars} {
+    proc p1 {a b} {set c 22; set d 33; trace var c rwu tproc; p2}
+    proc p2 {} {upvar c x1; unset x1}
+    set x ---
+    p1 foo bar
+    set x
+} {{x1 {} u} x1}
+
+test upvar-6.1 {retargeting an upvar} {
+    proc p1 {} {
+	set a(0) zeroth
+	set a(1) first
+	set a(2) second
+	p2
+    }
+    proc p2 {} {
+	upvar a x
+	set result {}
+	foreach i [array names x] {
+	    upvar a($i) x
+	    lappend result $x
+	}
+	lsort $result
+    }
+    p1
+} {first second zeroth}
+test upvar-6.2 {retargeting an upvar} {
+    set x 44
+    set y abcde
+    proc p1 {} {
+	global x
+	set result $x
+	upvar y x
+	lappend result $x
+    }
+    p1
+} {44 abcde}
+test upvar-6.3 {retargeting an upvar} {
+    set x 44
+    set y abcde
+    proc p1 {} {
+	upvar y x
+	lappend result $x
+	global x
+	lappend result $x
+    }
+    p1
+} {abcde 44}
+
+test upvar-7.1 {upvar to same level} {
+    set x 44
+    set y 55
+    catch {unset uv}
+    upvar #0 x uv
+    set uv abc
+    upvar 0 y uv
+    set uv xyzzy
+    list $x $y
+} {abc xyzzy}
+test upvar-7.2 {upvar to same level} {
+    set x 1234
+    set y 4567
+    proc p1 {x y} {
+	upvar 0 x uv
+	set uv $y
+	return "$x $y"
+    }
+    p1 44 89
+} {89 89}
+test upvar-7.3 {upvar to same level} {
+    set x 1234
+    set y 4567
+    proc p1 {x y} {
+	upvar #1 x uv
+	set uv $y
+	return "$x $y"
+    }
+    p1 xyz abc
+} {abc abc}
+test upvar-7.4 {upvar to same level: tricky problems when deleting variable table} {
+    proc tt {} {upvar #1 toto loc;  return $loc}
+    list [catch tt msg] $msg
+} {1 {can't read "loc": no such variable}}
+test upvar-7.5 {potential memory leak when deleting variable table} {
+    proc leak {} {
+	array set foo {1 2 3 4}
+	upvar 0 foo(1) bar
+    }
+    leak
+} {}
+
+test upvar-8.1 {errors in upvar command} -returnCodes error -body {
+    upvar
+} -result {wrong # args: should be "upvar ?level? otherVar localVar ?otherVar localVar ...?"}
+test upvar-8.2 {errors in upvar command} -returnCodes error -body {
+    upvar 1
+} -result {wrong # args: should be "upvar ?level? otherVar localVar ?otherVar localVar ...?"}
+test upvar-8.2.1 {upvar with numeric first argument} {
+    apply {{} {set 0 ok; apply {{} {upvar 0 x; return $x}}}}
+} ok
+test upvar-8.3 {errors in upvar command} -returnCodes error -body {
+    proc p1 {} {upvar a b c}
+    p1
+} -result {bad level "a"}
+test upvar-8.4 {errors in upvar command} -returnCodes error -body {
+    proc p1 {} {upvar 0 b b}
+    p1
+} -result {can't upvar from variable to itself}
+test upvar-8.5 {errors in upvar command} -returnCodes error -body {
+    proc p1 {} {upvar 0 a b; upvar 0 b a}
+    p1
+} -result {can't upvar from variable to itself}
+test upvar-8.6 {errors in upvar command} -returnCodes error -body {
+    proc p1 {} {set a 33; upvar b a}
+    p1
+} -result {variable "a" already exists}
+test upvar-8.7 {errors in upvar command} -returnCodes error -body {
+    proc p1 {} {trace variable a w foo; upvar b a}
+    p1
+} -result {variable "a" has traces: can't use for upvar}
+test upvar-8.8 {create nested array with upvar} -body {
+    proc p1 {} {upvar x(a) b; set b(2) 44}
+    catch {unset x}
+    p1
+} -returnCodes error -cleanup {
+    unset x
+} -result {can't set "b(2)": variable isn't array}
+test upvar-8.9 {upvar won't create namespace variable that refers to procedure variable} -setup {
+    catch {namespace delete {*}[namespace children :: test_ns_*]}
+    catch {rename MakeLink ""}
+    namespace eval ::test_ns_1 {}
+} -returnCodes error -body {
+    proc MakeLink {a} {
+	namespace eval ::test_ns_1 {
+	    upvar a a
+	}
+	unset ::test_ns_1::a
+    }
+    MakeLink 1
+} -result {bad variable name "a": can't create namespace variable that refers to procedure variable}
+test upvar-8.10 {upvar will create element alias for new array element} -setup {
+    catch {unset upvarArray}
+} -body {
+    array set upvarArray {}
+    catch {upvar 0 upvarArray(elem) upvarArrayElemAlias}
+} -result {0}
+test upvar-8.11 {upvar will not create a variable that looks like an array} -setup {
+    catch {unset upvarArray}
+} -body {
+    array set upvarArray {}
+    upvar 0 upvarArray(elem) upvarArrayElemAlias(elem)
+} -returnCodes 1 -match glob -result *
+
+test upvar-9.1 {Tcl_UpVar2 procedure} testupvar {
+    list [catch {testupvar xyz a {} x global} msg] $msg
+} {1 {bad level "xyz"}}
+test upvar-9.2 {Tcl_UpVar2 procedure} testupvar {
+    catch {unset a}
+    catch {unset x}
+    set a 44
+    list [catch "testupvar #0 a 1 x global" msg] $msg
+} {1 {can't access "a(1)": variable isn't array}}
+test upvar-9.3 {Tcl_UpVar2 procedure} testupvar {
+    proc foo {} {
+	testupvar 1 a {} x local
+	set x
+    }
+    catch {unset a}
+    catch {unset x}
+    set a 44
+    foo
+} {44}
+test upvar-9.4 {Tcl_UpVar2 procedure} testupvar {
+    proc foo {} {
+	testupvar 1 a {} _up_ global
+	list [catch {set x} msg] $msg
+    }
+    catch {unset a}
+    catch {unset _up_}
+    set a 44
+    concat [foo] $_up_
+} {1 {can't read "x": no such variable} 44}
+test upvar-9.5 {Tcl_UpVar2 procedure} testupvar {
+    proc foo {} {
+	testupvar 1 a b x local
+	set x
+    }
+    catch {unset a}
+    catch {unset x}
+    set a(b) 1234
+    foo
+} {1234}
+test upvar-9.6 {Tcl_UpVar procedure} testupvar {
+    proc foo {} {
+	testupvar 1 a x local
+	set x
+    }
+    catch {unset a}
+    catch {unset x}
+    set a xyzzy
+    foo
+} {xyzzy}
+test upvar-9.7 {Tcl_UpVar procedure} testupvar {
+    proc foo {} {
+	testupvar #0 a(b) x local
+	set x
+    }
+    catch {unset a}
+    catch {unset x}
+    set a(b) 1234
+    foo
+} {1234}
+catch {unset a}
+
+test upvar-10.1 {CompileWord OBOE} -setup {
+    proc linenumber {} {dict get [info frame -1] line}
+} -body {
+    apply {n {
+        upvar 1 {*}{
+        } [return [incr n -[linenumber]]] x
+    }} [linenumber]
+} -cleanup {
+    rename linenumber {}
+} -result 1
+
+#
+# Tests for 'namespace upvar'. As the implementation is essentially the same as
+# for 'upvar', we only test that the variables are linked correctly, i.e., we
+# assume that the behaviour of variables once the link is established has
+# already been tested above.
+#
+
+# Clear out any namespaces called test_ns_*
+catch {namespace delete {*}[namespace children :: test_ns_*]}
+namespace eval test_ns_0 {
+    variable x test_ns_0
+}
+set ::x test_global
+
+test upvar-NS-1.1 {nsupvar links to correct variable} -body {
+    namespace eval test_ns_1 {
+	namespace upvar ::test_ns_0 x w
+	set w
+    }
+} -result {test_ns_0} -cleanup {
+    namespace delete test_ns_1
+}
+test upvar-NS-1.2 {nsupvar links to correct variable} -body {
+    namespace eval test_ns_1 {
+	proc a {} {
+	    namespace upvar ::test_ns_0 x w
+	    set w
+	}
+	return [a]
+    }
+} -result {test_ns_0} -cleanup {
+    namespace delete test_ns_1
+}
+test upvar-NS-1.3 {nsupvar links to correct variable} -body {
+    namespace eval test_ns_1 {
+	namespace upvar test_ns_0 x w
+	set w
+    }
+} -returnCodes error -cleanup {
+    namespace delete test_ns_1
+} -result {namespace "test_ns_0" not found in "::test_ns_1"}
+test upvar-NS-1.4 {nsupvar links to correct variable} -body {
+    namespace eval test_ns_1 {
+	proc a {} {
+	    namespace upvar test_ns_0 x w
+	    set w
+	}
+	return [a]
+    }
+} -returnCodes error -cleanup {
+    namespace delete test_ns_1
+} -result {namespace "test_ns_0" not found in "::test_ns_1"}
+    
+test upvar-NS-1.5 {nsupvar links to correct variable} -body {
+    namespace eval test_ns_1 {
+	namespace eval test_ns_0 {}
+	namespace upvar test_ns_0 x w
+	set w
+    }
+} -cleanup {
+    namespace delete test_ns_1
+} -result {can't read "w": no such variable} -returnCodes error
+test upvar-NS-1.6 {nsupvar links to correct variable} -body {
+    namespace eval test_ns_1 {
+	namespace eval test_ns_0 {}
+	proc a {} {
+	    namespace upvar test_ns_0 x w
+	    set w
+	}
+	return [a]
+    }
+} -cleanup {
+    namespace delete test_ns_1
+} -result {can't read "w": no such variable} -returnCodes error
+test upvar-NS-1.7 {nsupvar links to correct variable} -body {
+    namespace eval test_ns_1 {
+	namespace eval test_ns_0 {
+	    variable x test_ns_1::test_ns_0
+	}
+	namespace upvar test_ns_0 x w
+	set w
+    }
+} -cleanup {
+    namespace delete test_ns_1
+} -result {test_ns_1::test_ns_0}
+test upvar-NS-1.8 {nsupvar links to correct variable} -body {
+    namespace eval test_ns_1 {
+	namespace eval test_ns_0 {
+	    variable x test_ns_1::test_ns_0
+	}
+	proc a {} {
+	    namespace upvar test_ns_0 x w
+	    set w
+	}
+	return [a]
+    }
+} -cleanup {
+    namespace delete test_ns_1
+} -result {test_ns_1::test_ns_0}
+test upvar-NS-1.9 {nsupvar links to correct variable} -body {
+    namespace eval test_ns_1 {
+	variable x test_ns_1
+	proc a {} {
+	    namespace upvar test_ns_0 x w
+	    set w
+	}
+	return [a]
+    }
+} -returnCodes error -cleanup {
+    namespace delete test_ns_1
+} -result {namespace "test_ns_0" not found in "::test_ns_1"}
+
+test upvar-NS-2.1 {TIP 323} -returnCodes error -body {
+    namespace upvar
+} -result {wrong # args: should be "namespace upvar ns ?otherVar myVar ...?"}
+test upvar-NS-2.2 {TIP 323} -setup {
+    namespace eval test_ns_1 {}
+} -body {
+    namespace upvar test_ns_1
+} -cleanup {
+    namespace delete test_ns_1
+} -result {}
+
+test upvar-NS-3.1 {CompileWord OBOE} -setup {
+    proc linenumber {} {dict get [info frame -1] line}
+} -body {
+    apply {n {
+        namespace upvar {*}{
+        } [return [incr n -[linenumber]]] x y
+    }} [linenumber]
+} -cleanup {
+    rename linenumber {}
+} -result 1
+test upvar-NS-3.2 {CompileWord OBOE} -setup {
+    proc linenumber {} {dict get [info frame -1] line}
+} -body {
+    apply {n {
+        namespace upvar :: {*}{
+        } [return [incr n -[linenumber]]] x
+    }} [linenumber]
+} -cleanup {
+    rename linenumber {}
+} -result 1
+test upvar-NS-3.3 {CompileWord OBOE} -setup {
+    proc linenumber {} {dict get [info frame -1] line}
+} -body {
+    apply {n {
+        variable x {*}{
+        } [return [incr n -[linenumber]]]
+    }} [linenumber]
+} -cleanup {
+    rename linenumber {}
+} -result 1
+
+# cleanup
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/tests/utf.test b/tests/utf.test
new file mode 100644
index 0000000..a03dd6c
--- /dev/null
+++ b/tests/utf.test
@@ -0,0 +1,452 @@
+# This file contains a collection of tests for tclUtf.c
+# Sourcing this file into Tcl runs the tests and generates output for
+# errors.  No output means no errors were found.
+#
+# Copyright (c) 1997 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+    package require tcltest 2
+    namespace import -force ::tcltest::*
+}
+
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
+
+testConstraint testbytestring [llength [info commands testbytestring]]
+
+catch {unset x}
+
+test utf-1.1 {Tcl_UniCharToUtf: 1 byte sequences} testbytestring {
+    expr {"\x01" eq [testbytestring "\x01"]}
+} 1
+test utf-1.2 {Tcl_UniCharToUtf: 2 byte sequences} testbytestring {
+    expr {"\x00" eq [testbytestring "\xc0\x80"]}
+} 1
+test utf-1.3 {Tcl_UniCharToUtf: 2 byte sequences} testbytestring {
+    expr {"\xe0" eq [testbytestring "\xc3\xa0"]}
+} 1
+test utf-1.4 {Tcl_UniCharToUtf: 3 byte sequences} testbytestring {
+    expr {"\u4e4e" eq [testbytestring "\xe4\xb9\x8e"]}
+} 1
+test utf-1.5 {Tcl_UniCharToUtf: overflowed Tcl_UniChar} testbytestring {
+    expr {[format %c 0x110000] eq [testbytestring "\xef\xbf\xbd"]}
+} 1
+test utf-1.6 {Tcl_UniCharToUtf: negative Tcl_UniChar} testbytestring {
+    expr {[format %c -1] eq [testbytestring "\xef\xbf\xbd"]}
+} 1
+
+test utf-2.1 {Tcl_UtfToUniChar: low ascii} {
+    string length "abc"
+} {3}
+test utf-2.2 {Tcl_UtfToUniChar: naked trail bytes} testbytestring {
+    string length [testbytestring "\x82\x83\x84"]
+} {3}
+test utf-2.3 {Tcl_UtfToUniChar: lead (2-byte) followed by non-trail} testbytestring {
+    string length [testbytestring "\xC2"]
+} {1}
+test utf-2.4 {Tcl_UtfToUniChar: lead (2-byte) followed by trail} testbytestring {
+    string length [testbytestring "\xC2\xa2"]
+} {1}
+test utf-2.5 {Tcl_UtfToUniChar: lead (3-byte) followed by non-trail} testbytestring {
+    string length [testbytestring "\xE2"]
+} {1}
+test utf-2.6 {Tcl_UtfToUniChar: lead (3-byte) followed by 1 trail} testbytestring {
+    string length [testbytestring "\xE2\xA2"]
+} {2}
+test utf-2.7 {Tcl_UtfToUniChar: lead (3-byte) followed by 2 trail} testbytestring {
+    string length [testbytestring "\xE4\xb9\x8e"]
+} {1}
+test utf-2.8 {Tcl_UtfToUniChar: longer UTF sequences not supported} testbytestring {
+    string length [testbytestring "\xF4\xA2\xA2\xA2"]
+} {4}
+
+test utf-3.1 {Tcl_UtfCharComplete} {
+} {}
+
+testConstraint testnumutfchars [llength [info commands testnumutfchars]]
+test utf-4.1 {Tcl_NumUtfChars: zero length} testnumutfchars {
+    testnumutfchars ""
+} {0}
+test utf-4.2 {Tcl_NumUtfChars: length 1} {testnumutfchars testbytestring} {
+    testnumutfchars [testbytestring "\xC2\xA2"]
+} {1}
+test utf-4.3 {Tcl_NumUtfChars: long string} {testnumutfchars testbytestring} {
+    testnumutfchars [testbytestring "abc\xC2\xA2\xe4\xb9\x8e\uA2\u4e4e"]
+} {7}
+test utf-4.4 {Tcl_NumUtfChars: #u0000} {testnumutfchars testbytestring} {
+    testnumutfchars [testbytestring "\xC0\x80"]
+} {1}
+test utf-4.5 {Tcl_NumUtfChars: zero length, calc len} testnumutfchars {
+    testnumutfchars "" 1
+} {0}
+test utf-4.6 {Tcl_NumUtfChars: length 1, calc len} {testnumutfchars testbytestring} {
+    testnumutfchars [testbytestring "\xC2\xA2"] 1
+} {1}
+test utf-4.7 {Tcl_NumUtfChars: long string, calc len} {testnumutfchars testbytestring} {
+    testnumutfchars [testbytestring "abc\xC2\xA2\xe4\xb9\x8e\uA2\u4e4e"] 1
+} {7}
+test utf-4.8 {Tcl_NumUtfChars: #u0000, calc len} {testnumutfchars testbytestring} {
+    testnumutfchars [testbytestring "\xC0\x80"] 1
+} {1}
+
+test utf-5.1 {Tcl_UtfFindFirsts} {
+} {}
+
+test utf-6.1 {Tcl_UtfNext} {
+} {}
+
+test utf-7.1 {Tcl_UtfPrev} {
+} {}
+
+test utf-8.1 {Tcl_UniCharAtIndex: index = 0} {
+    string index abcd 0
+} {a}
+test utf-8.2 {Tcl_UniCharAtIndex: index = 0} {
+    string index \u4e4e\u25a 0
+} "\u4e4e"
+test utf-8.3 {Tcl_UniCharAtIndex: index > 0} {
+    string index abcd 2
+} {c}
+test utf-8.4 {Tcl_UniCharAtIndex: index > 0} {
+    string index \u4e4e\u25a\xff\u543 2
+} "\uff"
+
+test utf-9.1 {Tcl_UtfAtIndex: index = 0} {
+    string range abcd 0 2
+} {abc}
+test utf-9.2 {Tcl_UtfAtIndex: index > 0} {
+    string range \u4e4e\u25a\xff\u543klmnop 1 5
+} "\u25a\xff\u543kl"
+
+
+test utf-10.1 {Tcl_UtfBackslash: dst == NULL} {
+    set x \n
+} {
+}
+test utf-10.2 {Tcl_UtfBackslash: \u subst} testbytestring {
+    expr {"\ua2" eq [testbytestring "\xc2\xa2"]}
+} 1
+test utf-10.3 {Tcl_UtfBackslash: longer \u subst} testbytestring {
+    expr {"\u4e21" eq [testbytestring "\xe4\xb8\xa1"]}
+} 1
+test utf-10.4 {Tcl_UtfBackslash: stops at first non-hex} testbytestring {
+    expr {"\u4e2k" eq "[testbytestring \xd3\xa2]k"}
+} 1
+test utf-10.5 {Tcl_UtfBackslash: stops after 4 hex chars} testbytestring {
+    expr {"\u4e216" eq "[testbytestring \xe4\xb8\xa1]6"}
+} 1
+proc bsCheck {char num} {
+    global errNum
+    test utf-10.$errNum {backslash substitution} {
+	scan $char %c value
+	set value
+    } $num
+    incr errNum
+}
+set errNum 6
+bsCheck \b	8
+bsCheck \e	101
+bsCheck \f	12
+bsCheck \n	10
+bsCheck \r	13
+bsCheck \t	9
+bsCheck \v	11
+bsCheck \{	123
+bsCheck \}	125
+bsCheck \[	91
+bsCheck \]	93
+bsCheck \$	36
+bsCheck \ 	32
+bsCheck \;	59
+bsCheck \\	92
+bsCheck \Ca	67
+bsCheck \Ma	77
+bsCheck \CMa	67
+# prior to 8.3, this returned 8, as \8 as accepted as an
+# octal value - but it isn't! [Bug: 3975]
+bsCheck \8a	56
+bsCheck \14	12
+bsCheck \141	97
+bsCheck b\0	98
+bsCheck \x	120
+bsCheck \xa	10
+bsCheck \xA	10
+bsCheck \x41	65
+bsCheck \x541	84
+bsCheck \u	117
+bsCheck \uk	117
+bsCheck \u41	65
+bsCheck \ua	10
+bsCheck \uA	10
+bsCheck \340	224
+bsCheck \ua1	161
+bsCheck \u4e21	20001
+bsCheck \741	60
+bsCheck \U	85
+bsCheck \Uk	85
+bsCheck \U41	65
+bsCheck \Ua	10
+bsCheck \UA	10
+bsCheck \Ua1	161
+bsCheck \U4e21	20001
+bsCheck \U004e21	20001
+bsCheck \U00004e21	20001
+bsCheck \U00110000	65533
+bsCheck \Uffffffff	65533
+
+test utf-11.1 {Tcl_UtfToUpper} {
+    string toupper {}
+} {}
+test utf-11.2 {Tcl_UtfToUpper} {
+    string toupper abc
+} ABC
+test utf-11.3 {Tcl_UtfToUpper} {
+    string toupper \u00e3ab
+} \u00c3AB
+test utf-11.4 {Tcl_UtfToUpper} {
+    string toupper \u01e3ab
+} \u01e2AB
+
+test utf-12.1 {Tcl_UtfToLower} {
+    string tolower {}
+} {}
+test utf-12.2 {Tcl_UtfToLower} {
+    string tolower ABC
+} abc
+test utf-12.3 {Tcl_UtfToLower} {
+    string tolower \u00c3AB
+} \u00e3ab
+test utf-12.4 {Tcl_UtfToLower} {
+    string tolower \u01e2AB
+} \u01e3ab
+
+test utf-13.1 {Tcl_UtfToTitle} {
+    string totitle {}
+} {}
+test utf-13.2 {Tcl_UtfToTitle} {
+    string totitle abc
+} Abc
+test utf-13.3 {Tcl_UtfToTitle} {
+    string totitle \u00e3ab
+} \u00c3ab
+test utf-13.4 {Tcl_UtfToTitle} {
+    string totitle \u01f3ab
+} \u01f2ab
+
+test utf-14.1 {Tcl_UtfNcasecmp} {
+    string compare -nocase a b
+} -1
+test utf-14.2 {Tcl_UtfNcasecmp} {
+    string compare -nocase b a
+} 1
+test utf-14.3 {Tcl_UtfNcasecmp} {
+    string compare -nocase B a
+} 1
+test utf-14.4 {Tcl_UtfNcasecmp} {
+    string compare -nocase aBcB abca
+} 1
+
+test utf-15.1 {Tcl_UniCharToUpper, negative delta} {
+    string toupper aA
+} AA
+test utf-15.2 {Tcl_UniCharToUpper, positive delta} {
+    string toupper \u0178\u00ff
+} \u0178\u0178
+test utf-15.3 {Tcl_UniCharToUpper, no delta} {
+    string toupper !
+} !
+
+test utf-16.1 {Tcl_UniCharToLower, negative delta} {
+    string tolower aA
+} aa
+test utf-16.2 {Tcl_UniCharToLower, positive delta} {
+    string tolower \u0178\u00ff\uA78D\u01c5
+} \u00ff\u00ff\u0265\u01c6
+
+test utf-17.1 {Tcl_UniCharToLower, no delta} {
+    string tolower !
+} !
+
+test utf-18.1 {Tcl_UniCharToTitle, add one for title} {
+    string totitle \u01c4
+} \u01c5
+test utf-18.2 {Tcl_UniCharToTitle, subtract one for title} {
+    string totitle \u01c6
+} \u01c5
+test utf-18.3 {Tcl_UniCharToTitle, subtract delta for title (positive)} {
+    string totitle \u017f
+} \u0053
+test utf-18.4 {Tcl_UniCharToTitle, subtract delta for title (negative)} {
+    string totitle \u00ff
+} \u0178
+test utf-18.5 {Tcl_UniCharToTitle, no delta} {
+    string totitle !
+} !
+
+test utf-19.1 {TclUniCharLen} -body {
+    list [regexp \\d abc456def foo] $foo
+} -cleanup {
+    unset -nocomplain foo
+} -result {1 4}
+
+test utf-20.1 {TclUniCharNcmp} {
+} {}
+
+test utf-21.1 {TclUniCharIsAlnum} {
+    # this returns 1 with Unicode 7 compliance
+    string is alnum \u1040\u021f\u0220
+} {1}
+test utf-21.2 {unicode alnum char in regc_locale.c} {
+    # this returns 1 with Unicode 7 compliance
+    list [regexp {^[[:alnum:]]+$} \u1040\u021f\u0220] [regexp {^\w+$} \u1040\u021f\u0220_\u203f\u2040\u2054\ufe33\ufe34\ufe4d\ufe4e\ufe4f\uff3f]
+} {1 1}
+test utf-21.3 {unicode print char in regc_locale.c} {
+    # this returns 1 with Unicode 7 compliance
+    regexp {^[[:print:]]+$} \ufbc1
+} 1
+test utf-21.4 {TclUniCharIsGraph} {
+    # [Bug 3464428]
+    string is graph \u0120
+} {1}
+test utf-21.5 {unicode graph char in regc_locale.c} {
+    # [Bug 3464428]
+    regexp {^[[:graph:]]+$} \u0120
+} {1}
+test utf-21.6 {TclUniCharIsGraph} {
+    # [Bug 3464428]
+    string is graph \u00a0
+} {0}
+test utf-21.7 {unicode graph char in regc_locale.c} {
+    # [Bug 3464428]
+    regexp {[[:graph:]]} \u0020\u00a0\u2028\u2029
+} {0}
+test utf-21.8 {TclUniCharIsPrint} {
+    # [Bug 3464428]
+    string is print \u0009
+} {0}
+test utf-21.9 {unicode print char in regc_locale.c} {
+    # [Bug 3464428]
+    regexp {[[:print:]]} \u0009
+} {0}
+test utf-21.10 {unicode print char in regc_locale.c} {
+    # [Bug 3464428]
+    regexp {[[:print:]]} \u0009
+} {0}
+test utf-21.11 {TclUniCharIsControl} {
+    # [Bug 3464428]
+    string is control \u0000\u001f\u00ad\u0605\u061c\u180e\u2066\ufeff
+} {1}
+test utf-21.12 {unicode control char in regc_locale.c} {
+    # [Bug 3464428], [Bug a876646efe]
+    regexp {^[[:cntrl:]]*$} \u0000\u001f\u00ad\u0605\u061c\u180e\u2066\ufeff
+} {1}
+
+test utf-22.1 {TclUniCharIsWordChar} {
+    string wordend "xyz123_bar fg" 0
+} 10
+test utf-22.2 {TclUniCharIsWordChar} {
+    string wordend "x\u5080z123_bar\u203c fg" 0
+} 10
+
+test utf-23.1 {TclUniCharIsAlpha} {
+    # this returns 1 with Unicode 7 compliance
+    string is alpha \u021f\u0220\u037f\u052f
+} {1}
+test utf-23.2 {unicode alpha char in regc_locale.c} {
+    # this returns 1 with Unicode 7 compliance
+    regexp {^[[:alpha:]]+$} \u021f\u0220\u037f\u052f
+} {1}
+
+test utf-24.1 {TclUniCharIsDigit} {
+    # this returns 1 with Unicode 7 compliance
+    string is digit \u1040\uabf0
+} {1}
+test utf-24.2 {unicode digit char in regc_locale.c} {
+    # this returns 1 with Unicode 7 compliance
+    list [regexp {^[[:digit:]]+$} \u1040\uabf0] [regexp {^\d+$} \u1040\uabf0]
+} {1 1}
+
+test utf-24.3 {TclUniCharIsSpace} {
+    # this returns 1 with Unicode 7/TIP 413 compliance
+    string is space \u0085\u1680\u180e\u200b\u202f\u2060
+} {1}
+test utf-24.4 {unicode space char in regc_locale.c} {
+    # this returns 1 with Unicode 7/TIP 413 compliance
+    list [regexp {^[[:space:]]+$} \u0085\u1680\u180e\u200b\u202f\u2060] [regexp {^\s+$} \u0085\u1680\u180e\u200b\u202f\u2060]
+} {1 1}
+
+testConstraint teststringobj [llength [info commands teststringobj]]
+
+test utf-25.1 {Tcl_UniCharNcasecmp} -constraints teststringobj \
+    -setup {
+	testobj freeallvars
+    } \
+    -body {
+	teststringobj set 1 a
+	teststringobj set 2 b
+	teststringobj getunicode 1
+	teststringobj getunicode 2
+	string compare -nocase [teststringobj get 1] [teststringobj get 2]
+    } \
+    -cleanup {
+	testobj freeallvars
+    } \
+    -result -1
+test utf-25.2 {Tcl_UniCharNcasecmp} -constraints teststringobj \
+    -setup {
+	testobj freeallvars
+    } \
+    -body {
+	teststringobj set 1 b
+	teststringobj set 2 a
+	teststringobj getunicode 1
+	teststringobj getunicode 2
+	string compare -nocase [teststringobj get 1] [teststringobj get 2]
+    } \
+    -cleanup {
+	testobj freeallvars
+    } \
+    -result 1
+test utf-25.3 {Tcl_UniCharNcasecmp} -constraints teststringobj \
+    -setup {
+	testobj freeallvars
+    } \
+    -body {
+	teststringobj set 1 B
+	teststringobj set 2 a
+	teststringobj getunicode 1
+	teststringobj getunicode 2
+	string compare -nocase [teststringobj get 1] [teststringobj get 2]
+    } \
+    -cleanup {
+	testobj freeallvars
+    } \
+    -result 1
+
+test utf-25.4 {Tcl_UniCharNcasecmp} -constraints teststringobj \
+    -setup {
+	testobj freeallvars
+    } \
+    -body {
+	teststringobj set 1 aBcB
+	teststringobj set 2 abca
+	teststringobj getunicode 1
+	teststringobj getunicode 2
+	string compare -nocase [teststringobj get 1] [teststringobj get 2]
+    } \
+    -cleanup {
+	testobj freeallvars
+    } \
+    -result 1
+
+# cleanup
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/tests/util.test b/tests/util.test
new file mode 100644
index 0000000..7782f35
--- /dev/null
+++ b/tests/util.test
@@ -0,0 +1,4028 @@
+# This file is a Tcl script to test the code in the file tclUtil.c.
+# This file is organized in the standard fashion for Tcl tests.
+#
+# Copyright (c) 1995-1998 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+    package require tcltest
+    namespace import -force ::tcltest::*
+}
+
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
+
+testConstraint controversialNaN 1
+testConstraint testbytestring [llength [info commands testbytestring]]
+testConstraint testdstring [llength [info commands testdstring]]
+testConstraint testconcatobj [llength [info commands testconcatobj]]
+testConstraint testdoubledigits [llength [info commands testdoubledigits]]
+
+# Big test for correct ordering of data in [expr]
+
+proc testIEEE {} {
+    variable ieeeValues
+    binary scan [binary format dd -1.0 1.0] c* c
+    switch -exact -- $c {
+	{0 0 0 0 0 0 -16 -65 0 0 0 0 0 0 -16 63} {
+	    # little endian
+	    binary scan \x00\x00\x00\x00\x00\x00\xf0\xff d \
+		ieeeValues(-Infinity)
+	    binary scan \x00\x00\x00\x00\x00\x00\xf0\xbf d \
+		ieeeValues(-Normal)
+	    binary scan \x00\x00\x00\x00\x00\x00\x08\x80 d \
+		ieeeValues(-Subnormal)
+	    binary scan \x00\x00\x00\x00\x00\x00\x00\x80 d \
+		ieeeValues(-0)
+	    binary scan \x00\x00\x00\x00\x00\x00\x00\x00 d \
+		ieeeValues(+0)
+	    binary scan \x00\x00\x00\x00\x00\x00\x08\x00 d \
+		ieeeValues(+Subnormal)
+	    binary scan \x00\x00\x00\x00\x00\x00\xf0\x3f d \
+		ieeeValues(+Normal)
+	    binary scan \x00\x00\x00\x00\x00\x00\xf0\x7f d \
+		ieeeValues(+Infinity)
+	    binary scan \x00\x00\x00\x00\x00\x00\xf8\x7f d \
+		ieeeValues(NaN)
+	    binary scan \x00\x00\x00\x00\x00\x00\xf8\xff d \
+		ieeeValues(-NaN)
+	    binary scan \xef\xcd\xab\x89\x67\x45\xfb\xff d \
+		ieeeValues(-NaN(3456789abcdef))
+	    set ieeeValues(littleEndian) 1
+	    return 1
+	}
+	{-65 -16 0 0 0 0 0 0 63 -16 0 0 0 0 0 0} {
+	    binary scan \xff\xf0\x00\x00\x00\x00\x00\x00 d \
+		ieeeValues(-Infinity)
+	    binary scan \xbf\xf0\x00\x00\x00\x00\x00\x00 d \
+		ieeeValues(-Normal)
+	    binary scan \x80\x08\x00\x00\x00\x00\x00\x00 d \
+		ieeeValues(-Subnormal)
+	    binary scan \x80\x00\x00\x00\x00\x00\x00\x00 d \
+		ieeeValues(-0)
+	    binary scan \x00\x00\x00\x00\x00\x00\x00\x00 d \
+		ieeeValues(+0)
+	    binary scan \x00\x08\x00\x00\x00\x00\x00\x00 d \
+		ieeeValues(+Subnormal)
+	    binary scan \x3f\xf0\x00\x00\x00\x00\x00\x00 d \
+		ieeeValues(+Normal)
+	    binary scan \x7f\xf0\x00\x00\x00\x00\x00\x00 d \
+		ieeeValues(+Infinity)
+	    binary scan \x7f\xf8\x00\x00\x00\x00\x00\x00 d \
+		ieeeValues(NaN)
+	    binary scan \xff\xf8\x00\x00\x00\x00\x00\x00 d \
+		ieeeValues(-NaN)
+	    binary scan \xff\xfb\x45\x67\x89\xab\xcd\xef d \
+		ieeeValues(-NaN(3456789abcdef))
+	    set ieeeValues(littleEndian) 0
+	    return 1
+	}
+	default {
+	    return 0
+	}
+    }
+}
+testConstraint ieeeFloatingPoint [testIEEE]
+
+proc convertDouble { x } {
+    variable ieeeValues
+    if { $ieeeValues(littleEndian) } {
+	binary scan [binary format w $x] d result
+    } else {
+	binary scan [binary format W $x] d result
+    }
+    return $result
+}
+
+proc verdonk_test {sig binexp shouldbe exp} {
+    regexp {([-+]?)([0-9a-f]+)} $sig -> signum sig
+    scan $sig %llx sig
+    if {$signum eq {-}} {
+	set signum [expr 1<<63]
+    } else {
+	set signum 0
+    }
+    regexp {E([-+]?[0-9]+)} $binexp -> binexp
+    set word [expr {$signum | (($binexp + 0x3ff)<<52)|($sig & ~(1<<52))}]
+    binary scan [binary format w $word] q double
+    regexp {([-+])(\d+)_(\d+)\&} $shouldbe -> signum digits1 digits2
+    regexp {E([-+]\d+)} $exp -> decexp
+    incr decexp [expr {[string length $digits1] - 1}]
+    lassign [testdoubledigits $double [string length $digits1] e] \
+	outdigits decpt outsign
+    if {[string index $digits2 0] >= 5} {
+	incr digits1
+    }
+    if {$outsign != $signum || $outdigits != $digits1 || $decpt != $decexp} {
+	return -code error "result is ${outsign}0.${outdigits}E$decpt\
+                            should be ${signum}0.${digits1}E$decexp"
+    }
+}
+
+test util-1.1 {TclFindElement procedure - binary element in middle of list} {
+    lindex {0 foo\x00help 1} 1
+} "foo\x00help"
+test util-1.2 {TclFindElement procedure - binary element at end of list} {
+    lindex {0 foo\x00help} 1
+} "foo\x00help"
+
+test util-2.1 {TclCopyAndCollapse procedure - normal string} {
+    lindex {0 foo} 1
+} {foo}
+test util-2.2 {TclCopyAndCollapse procedure - string with backslashes} {
+    lindex {0 foo\n\x00help 1} 1
+} "foo\n\x00help"
+
+test util-3.1 {Tcl_ScanCountedElement procedure - don't leave unmatched braces} {
+    # This test checks for a very tricky feature.  Any list element
+    # generated with Tcl_ScanCountedElement and Tcl_ConvertElement must
+    # have the property that it can be enclosing in curly braces to make
+    # an embedded sub-list.  If this property doesn't hold, then
+    # Tcl_DStringStartSublist doesn't work.
+    set x {}
+    lappend x "# \\\{ \\"
+    concat $x [llength "{$x}"]
+} {\#\ \\\{\ \\ 1}
+test util-3.2 {Tcl_ConverCountedElement procedure - quote leading '#'} {
+    list # # a
+} {{#} # a}
+test util-3.3 {Tcl_ConverCountedElement procedure - quote leading '#'} {
+    list #\{ # a
+} {\#\{ # a}
+test util-3.4 {Tcl_ConverCountedElement procedure - quote leading '#'} {
+    proc # {} {return #}
+    set result [eval [list #]]
+    rename # {}
+    set result
+} {#}
+test util-3.4.1 {Tcl_ConverCountedElement procedure - quote leading '#'} {
+    proc # {} {return #}
+    set cmd [list #]
+    append cmd ""	;# force string rep generation
+    set result [eval $cmd]
+    rename # {}
+    set result
+} {#}
+test util-3.5 {Tcl_ConverCountedElement procedure - quote leading '#'} {
+    proc #\{ {} {return #}
+    set result [eval [list #\{]]
+    rename #\{ {}
+    set result
+} {#}
+test util-3.5.1 {Tcl_ConverCountedElement procedure - quote leading '#'} {
+    proc #\{ {} {return #}
+    set cmd [list #\{]
+    append cmd ""	;# force string rep generation
+    set result [eval $cmd]
+    rename #\{ {}
+    set result
+} {#}
+test util-3.6 {Tcl_ConvertElement, Bug 3371644} {
+    interp create #\\
+    interp alias {} x #\\ concat
+    interp target {} x ;# Crash if bug not fixed
+    interp delete #\\
+} {}
+
+test util-4.1 {Tcl_ConcatObj - backslash-space at end of argument} {
+    concat a {b\ } c
+} {a b\  c}
+test util-4.2 {Tcl_ConcatObj - backslash-space at end of argument} {
+    concat a {b\   } c
+} {a b\  c}
+test util-4.3 {Tcl_ConcatObj - backslash-space at end of argument} {
+    concat a {b\\   } c
+} {a b\\  c}
+test util-4.4 {Tcl_ConcatObj - backslash-space at end of argument} {
+    concat a {b } c
+} {a b c}
+test util-4.5 {Tcl_ConcatObj - backslash-space at end of argument} {
+    concat a { } c
+} {a c}
+test util-4.6 {Tcl_ConcatObj - utf-8 sequence with "whitespace" char} {
+    # Check for Bug #227512.  If this violates C isspace, then it returns \xc3.
+    concat \xe0
+} \xe0
+test util-4.7 {Tcl_ConcatObj - refCount safety} testconcatobj {
+    # Check for Bug #1447328 (actually, bugs in its original "fix"). One of the
+    # symptoms was Bug #2055782. 
+    testconcatobj
+} {}
+
+proc Wrapper_Tcl_StringMatch {pattern string} {
+    # Forces use of Tcl_StringMatch, not Tcl_UniCharCaseMatch
+    switch -glob -- $string $pattern {return 1} default {return 0}
+}
+test util-5.1 {Tcl_StringMatch} {
+    Wrapper_Tcl_StringMatch ab*c abc
+} 1
+test util-5.2 {Tcl_StringMatch} {
+    Wrapper_Tcl_StringMatch ab**c abc
+} 1
+test util-5.3 {Tcl_StringMatch} {
+    Wrapper_Tcl_StringMatch ab* abcdef
+} 1
+test util-5.4 {Tcl_StringMatch} {
+    Wrapper_Tcl_StringMatch *c abc
+} 1
+test util-5.5 {Tcl_StringMatch} {
+    Wrapper_Tcl_StringMatch *3*6*9 0123456789
+} 1
+test util-5.6 {Tcl_StringMatch} {
+    Wrapper_Tcl_StringMatch *3*6*9 01234567890
+} 0
+test util-5.7 {Tcl_StringMatch: UTF-8} {
+    Wrapper_Tcl_StringMatch *u \u4e4fu
+} 1
+test util-5.8 {Tcl_StringMatch} {
+    Wrapper_Tcl_StringMatch a?c abc
+} 1
+test util-5.9 {Tcl_StringMatch: UTF-8} {
+    # skip one character in string
+    Wrapper_Tcl_StringMatch a?c a\u4e4fc
+} 1
+test util-5.10 {Tcl_StringMatch} {
+    Wrapper_Tcl_StringMatch a??c abc
+} 0
+test util-5.11 {Tcl_StringMatch} {
+    Wrapper_Tcl_StringMatch ?1??4???8? 0123456789
+} 1
+test util-5.12 {Tcl_StringMatch} {
+    Wrapper_Tcl_StringMatch {[abc]bc} abc
+} 1
+test util-5.13 {Tcl_StringMatch: UTF-8} {
+    # string += Tcl_UtfToUniChar(string, &ch);
+    Wrapper_Tcl_StringMatch "\[\u4e4fxy\]bc" "\u4e4fbc"
+} 1
+test util-5.14 {Tcl_StringMatch} {
+    # if ((*pattern == ']') || (*pattern == '\0'))
+    # badly formed pattern
+    Wrapper_Tcl_StringMatch {[]} {[]}
+} 0
+test util-5.15 {Tcl_StringMatch} {
+    # if ((*pattern == ']') || (*pattern == '\0'))
+    # badly formed pattern
+    Wrapper_Tcl_StringMatch {[} {[}
+} 0
+test util-5.16 {Tcl_StringMatch} {
+    Wrapper_Tcl_StringMatch {a[abc]c} abc
+} 1
+test util-5.17 {Tcl_StringMatch: UTF-8} {
+    # pattern += Tcl_UtfToUniChar(pattern, &endChar);
+    # get 1 UTF-8 character
+    Wrapper_Tcl_StringMatch "a\[a\u4e4fc]c" "a\u4e4fc"
+} 1
+test util-5.18 {Tcl_StringMatch: UTF-8} testbytestring {
+    # pattern += Tcl_UtfToUniChar(pattern, &endChar);
+    # proper advance: wrong answer would match on UTF trail byte of \u4e4f
+    Wrapper_Tcl_StringMatch {a[a\u4e4fc]c} [testbytestring a\u008fc]
+} 0
+test util-5.19 {Tcl_StringMatch: UTF-8} {
+    # pattern += Tcl_UtfToUniChar(pattern, &endChar);
+    # proper advance.
+    Wrapper_Tcl_StringMatch {a[a\u4e4fc]c} "acc"
+} 1
+test util-5.20 {Tcl_StringMatch} {
+    Wrapper_Tcl_StringMatch {a[xyz]c} abc
+} 0
+test util-5.21 {Tcl_StringMatch} {
+    Wrapper_Tcl_StringMatch {12[2-7]45} 12345
+} 1
+test util-5.22 {Tcl_StringMatch: UTF-8 range} {
+    Wrapper_Tcl_StringMatch "\[\u4e00-\u4e4f]" "0"
+} 0
+test util-5.23 {Tcl_StringMatch: UTF-8 range} {
+    Wrapper_Tcl_StringMatch "\[\u4e00-\u4e4f]" "\u4e33"
+} 1
+test util-5.24 {Tcl_StringMatch: UTF-8 range} {
+    Wrapper_Tcl_StringMatch "\[\u4e00-\u4e4f]" "\uff08"
+} 0
+test util-5.25 {Tcl_StringMatch} {
+    Wrapper_Tcl_StringMatch {12[ab2-4cd]45} 12345
+} 1
+test util-5.26 {Tcl_StringMatch} {
+    Wrapper_Tcl_StringMatch {12[ab2-4cd]45} 12b45
+} 1
+test util-5.27 {Tcl_StringMatch} {
+    Wrapper_Tcl_StringMatch {12[ab2-4cd]45} 12d45
+} 1
+test util-5.28 {Tcl_StringMatch} {
+    Wrapper_Tcl_StringMatch {12[ab2-4cd]45} 12145
+} 0
+test util-5.29 {Tcl_StringMatch} {
+    Wrapper_Tcl_StringMatch {12[ab2-4cd]45} 12545
+} 0
+test util-5.30 {Tcl_StringMatch: forwards range} {
+    Wrapper_Tcl_StringMatch {[k-w]} "z"
+} 0
+test util-5.31 {Tcl_StringMatch: forwards range} {
+    Wrapper_Tcl_StringMatch {[k-w]} "w"
+} 1
+test util-5.32 {Tcl_StringMatch: forwards range} {
+    Wrapper_Tcl_StringMatch {[k-w]} "r"
+} 1
+test util-5.33 {Tcl_StringMatch: forwards range} {
+    Wrapper_Tcl_StringMatch {[k-w]} "k"
+} 1
+test util-5.34 {Tcl_StringMatch: forwards range} {
+    Wrapper_Tcl_StringMatch {[k-w]} "a"
+} 0
+test util-5.35 {Tcl_StringMatch: reverse range} {
+    Wrapper_Tcl_StringMatch {[w-k]} "z"
+} 0
+test util-5.36 {Tcl_StringMatch: reverse range} {
+    Wrapper_Tcl_StringMatch {[w-k]} "w"
+} 1
+test util-5.37 {Tcl_StringMatch: reverse range} {
+    Wrapper_Tcl_StringMatch {[w-k]} "r"
+} 1
+test util-5.38 {Tcl_StringMatch: reverse range} {
+    Wrapper_Tcl_StringMatch {[w-k]} "k"
+} 1
+test util-5.39 {Tcl_StringMatch: reverse range} {
+    Wrapper_Tcl_StringMatch {[w-k]} "a"
+} 0
+test util-5.40 {Tcl_StringMatch: skip correct number of ']'} {
+    Wrapper_Tcl_StringMatch {[A-]x} Ax
+} 0
+test util-5.41 {Tcl_StringMatch: skip correct number of ']'} {
+    Wrapper_Tcl_StringMatch {[A-]]x} Ax
+} 1
+test util-5.42 {Tcl_StringMatch: skip correct number of ']'} {
+    Wrapper_Tcl_StringMatch {[A-]]x} \ue1x
+} 0
+test util-5.43 {Tcl_StringMatch: skip correct number of ']'} {
+    Wrapper_Tcl_StringMatch \[A-]\ue1]x \ue1x
+} 1
+test util-5.44 {Tcl_StringMatch: skip correct number of ']'} {
+    Wrapper_Tcl_StringMatch {[A-]h]x} hx
+} 1
+test util-5.45 {Tcl_StringMatch} {
+    # if (*pattern == '\0')
+    # badly formed pattern, still treats as a set
+    Wrapper_Tcl_StringMatch {[a} a
+} 1
+test util-5.46 {Tcl_StringMatch} {
+    Wrapper_Tcl_StringMatch {a\*b} a*b
+} 1
+test util-5.47 {Tcl_StringMatch} {
+    Wrapper_Tcl_StringMatch {a\*b} ab
+} 0
+test util-5.48 {Tcl_StringMatch} {
+    Wrapper_Tcl_StringMatch {a\*\?\[\]\\\x} "a*?\[\]\\x"
+} 1
+test util-5.49 {Tcl_StringMatch} {
+    Wrapper_Tcl_StringMatch ** ""
+} 1
+test util-5.50 {Tcl_StringMatch} {
+    Wrapper_Tcl_StringMatch *. ""
+} 0
+test util-5.51 {Tcl_StringMatch} {
+    Wrapper_Tcl_StringMatch "" ""
+} 1
+
+test util-6.1 {Tcl_PrintDouble - using tcl_precision} -setup {
+    set old_precision $::tcl_precision
+    set ::tcl_precision 12
+} -body {
+    concat x[expr 1.4]
+} -cleanup {
+    set ::tcl_precision $old_precision
+} -result {x1.4}
+test util-6.2 {Tcl_PrintDouble - using tcl_precision} -setup {
+    set old_precision $::tcl_precision
+    set ::tcl_precision 12
+} -body {
+    concat x[expr 1.39999999999]
+} -cleanup {
+    set ::tcl_precision $old_precision
+} -result {x1.39999999999}
+test util-6.3 {Tcl_PrintDouble - using tcl_precision} -setup {
+    set old_precision $::tcl_precision
+    set ::tcl_precision 12
+} -body {
+    concat x[expr 1.399999999999]
+} -cleanup {
+    set ::tcl_precision $old_precision
+} -result {x1.4}
+test util-6.4 {Tcl_PrintDouble - using tcl_precision} -setup {
+    set old_precision $::tcl_precision
+    set ::tcl_precision 5
+} -body {
+    concat x[expr 1.123412341234]
+} -cleanup {
+    set tcl_precision $old_precision
+} -result {x1.1234}
+test util-6.5 {Tcl_PrintDouble - make sure there's a decimal point} {
+    concat x[expr 2.0]
+} {x2.0}
+test util-6.6 {Tcl_PrintDouble - make sure there's a decimal point} {
+    concat x[expr 3.0e98]
+} {x3e+98}
+
+test util-7.1 {TclPrecTraceProc - unset callbacks} -setup {
+    set old_precision $::tcl_precision
+} -body {
+    set tcl_precision 7
+    set x $tcl_precision
+    unset tcl_precision
+    list $x $tcl_precision
+} -cleanup {
+    set ::tcl_precision $old_precision
+} -result {7 7}
+test util-7.2 {TclPrecTraceProc - read traces, sharing among interpreters}  -setup {
+    set old_precision $::tcl_precision
+} -body {
+    set tcl_precision 12
+    interp create child
+    set x [child eval set tcl_precision]
+    child eval {set tcl_precision 6}
+    interp delete child
+    list $x $tcl_precision
+} -cleanup {
+    set ::tcl_precision $old_precision
+} -result {12 6}
+test util-7.3 {TclPrecTraceProc - write traces, safe interpreters} -setup {
+    set old_precision $::tcl_precision
+} -body {
+    set tcl_precision 12
+    interp create -safe child
+    set x [child eval {
+	list [catch {set tcl_precision 8} msg] $msg
+    }]
+    interp delete child
+    list $x $tcl_precision
+} -cleanup {
+    set ::tcl_precision $old_precision
+} -result {{1 {can't set "tcl_precision": can't modify precision from a safe interpreter}} 12}
+test util-7.4 {TclPrecTraceProc - write traces, bogus values} -setup {
+    set old_precision $::tcl_precision
+} -body {
+    set tcl_precision 12
+    list [catch {set tcl_precision abc} msg] $msg $tcl_precision
+} -cleanup {
+    set ::tcl_precision $old_precision
+} -result {1 {can't set "tcl_precision": improper value for precision} 12}
+
+# This test always succeeded in the C locale anyway...
+test util-8.1 {TclNeedSpace - correct UTF8 handling} {
+    # Bug 411825
+    # Note that this test relies on the fact that
+    # [interp target] calls on Tcl_AppendElement()
+    # which calls on TclNeedSpace().  If [interp target]
+    # is ever updated, this test will no longer test
+    # TclNeedSpace.
+    interp create \u5420
+    interp create [list \u5420 foo]
+    interp alias {} fooset [list \u5420 foo] set
+    set result [interp target {} fooset]
+    interp delete \u5420
+    set result
+} "\u5420 foo"
+test util-8.2 {TclNeedSpace - correct UTF8 handling} testdstring {
+    # Bug 411825
+    # This tests the same bug as the previous test, but
+    # should be more future-proof, as the DString
+    # operations will likely continue to call TclNeedSpace
+    testdstring free
+    testdstring append \u5420 -1
+    testdstring element foo
+    llength [testdstring get]
+} 2
+test util-8.3 {TclNeedSpace - correct UTF8 handling} testdstring {
+    # Bug 411825 - new variant reported by Dossy Shiobara
+    testdstring free
+    testdstring append \u00A0 -1
+    testdstring element foo
+    llength [testdstring get]
+} 2
+test util-8.4 {TclNeedSpace - correct UTF8 handling} testdstring {
+    # Another bug uncovered while fixing 411825
+    testdstring free
+    testdstring append {\ } -1
+    testdstring append \{ -1
+    testdstring element foo
+    llength [testdstring get]
+} 2
+test util-8.5 {TclNeedSpace - correct UTF8 handling} testdstring {
+    # Note that in this test TclNeedSpace actually gets it wrong,
+    # claiming we need a space when we really do not.  Extra space
+    # between list elements is harmless though, and better to have
+    # extra space in really weird string reps of lists, than to
+    # invest the effort required to make TclNeedSpace foolproof.
+    testdstring free
+    testdstring append {\\ } -1
+    testdstring element foo
+    list [llength [testdstring get]] [string length [testdstring get]]
+} {2 7}
+test util-8.6 {TclNeedSpace - correct UTF8 handling} testdstring {
+    # Another example of TclNeedSpace harmlessly getting it wrong.
+    testdstring free
+    testdstring append {\\ } -1
+    testdstring append \{ -1
+    testdstring element foo
+    testdstring append \} -1
+    list [llength [testdstring get]] [string length [testdstring get]]
+} {2 9}
+
+test util-9.0.0 {TclGetIntForIndex} {
+    string index abcd 0
+} a
+test util-9.0.1 {TclGetIntForIndex} {
+    string index abcd 0x0
+} a
+test util-9.0.2 {TclGetIntForIndex} {
+    string index abcd -0x0
+} a
+test util-9.0.3 {TclGetIntForIndex} {
+    string index abcd { 0 }
+} a
+test util-9.0.4 {TclGetIntForIndex} {
+    string index abcd { 0x0 }
+} a
+test util-9.0.5 {TclGetIntForIndex} {
+    string index abcd { -0x0 }
+} a
+test util-9.0.6 {TclGetIntForIndex} {
+    string index abcd 01
+} b
+test util-9.0.7 {TclGetIntForIndex} {
+    string index abcd { 01 }
+} b
+test util-9.1.0 {TclGetIntForIndex} {
+    string index abcd 3
+} d
+test util-9.1.1 {TclGetIntForIndex} {
+    string index abcd { 3 }
+} d
+test util-9.1.2 {TclGetIntForIndex} {
+    string index abcdefghijk 0xa
+} k
+test util-9.1.3 {TclGetIntForIndex} {
+    string index abcdefghijk { 0xa }
+} k
+test util-9.2.0 {TclGetIntForIndex} {
+    string index abcd end
+} d 
+test util-9.2.1 {TclGetIntForIndex} -body {
+    string index abcd { end}
+} -returnCodes error -match glob -result *
+test util-9.2.2 {TclGetIntForIndex} -body {
+    string index abcd {end }
+} -returnCodes error -match glob -result *
+test util-9.3 {TclGetIntForIndex} {
+    # Deprecated
+    string index abcd en
+} d
+test util-9.4 {TclGetIntForIndex} {
+    # Deprecated
+    string index abcd e
+} d
+test util-9.5.0 {TclGetIntForIndex} {
+    string index abcd end-1
+} c
+test util-9.5.1 {TclGetIntForIndex} {
+    string index abcd {end-1 }
+} c
+test util-9.5.2 {TclGetIntForIndex} -body {
+    string index abcd { end-1}
+} -returnCodes error -match glob -result *
+test util-9.6 {TclGetIntForIndex} {
+    string index abcd end+-1
+} c
+test util-9.7 {TclGetIntForIndex} {
+    string index abcd end+1
+} {}
+test util-9.8 {TclGetIntForIndex} {
+    string index abcd end--1
+} {}
+test util-9.9.0 {TclGetIntForIndex} {
+    string index abcd 0+0
+} a
+test util-9.9.1 {TclGetIntForIndex} {
+    string index abcd { 0+0 }
+} a
+test util-9.10 {TclGetIntForIndex} {
+    string index abcd 0-0
+} a
+test util-9.11 {TclGetIntForIndex} {
+    string index abcd 1+0
+} b
+test util-9.12 {TclGetIntForIndex} {
+    string index abcd 1-0
+} b
+test util-9.13 {TclGetIntForIndex} {
+    string index abcd 1+1
+} c
+test util-9.14 {TclGetIntForIndex} {
+    string index abcd 1-1
+} a
+test util-9.15 {TclGetIntForIndex} {
+    string index abcd -1+2
+} b
+test util-9.16 {TclGetIntForIndex} {
+    string index abcd -1--2
+} b
+test util-9.17 {TclGetIntForIndex} {
+    string index abcd { -1+2 }
+} b
+test util-9.18 {TclGetIntForIndex} {
+    string index abcd { -1--2 }
+} b
+test util-9.19 {TclGetIntForIndex} -body {
+    string index a {}
+} -returnCodes error -match glob -result *
+test util-9.20 {TclGetIntForIndex} -body {
+    string index a { }
+} -returnCodes error -match glob -result *
+test util-9.21 {TclGetIntForIndex} -body {
+    string index a " \r\t\n"
+} -returnCodes error -match glob -result *
+test util-9.22 {TclGetIntForIndex} -body {
+    string index a +
+} -returnCodes error -match glob -result *
+test util-9.23 {TclGetIntForIndex} -body {
+    string index a -
+} -returnCodes error -match glob -result *
+test util-9.24 {TclGetIntForIndex} -body {
+    string index a x
+} -returnCodes error -match glob -result *
+test util-9.25 {TclGetIntForIndex} -body {
+    string index a +x
+} -returnCodes error -match glob -result *
+test util-9.26 {TclGetIntForIndex} -body {
+    string index a -x
+} -returnCodes error -match glob -result *
+test util-9.27 {TclGetIntForIndex} -body {
+    string index a 0y
+} -returnCodes error -match glob -result *
+test util-9.28 {TclGetIntForIndex} -body {
+    string index a 1*
+} -returnCodes error -match glob -result *
+test util-9.29 {TclGetIntForIndex} -body {
+    string index a 0+
+} -returnCodes error -match glob -result *
+test util-9.30 {TclGetIntForIndex} -body {
+    string index a {0+ }
+} -returnCodes error -match glob -result *
+test util-9.31 {TclGetIntForIndex} -body {
+    string index a 0x
+} -returnCodes error -match glob -result *
+test util-9.32 {TclGetIntForIndex} -body {
+    string index a 0x1FFFFFFFF+0
+} -returnCodes error -match glob -result *
+test util-9.33 {TclGetIntForIndex} -body {
+    string index a 100000000000+0
+} -returnCodes error -match glob -result *
+test util-9.34 {TclGetIntForIndex} -body {
+    string index a 1.0
+} -returnCodes error -match glob -result *
+test util-9.35 {TclGetIntForIndex} -body {
+    string index a 1e23
+} -returnCodes error -match glob -result *
+test util-9.36 {TclGetIntForIndex} -body {
+    string index a 1.5e2
+} -returnCodes error -match glob -result *
+test util-9.37 {TclGetIntForIndex} -body {
+    string index a 0+x
+} -returnCodes error -match glob -result *
+test util-9.38 {TclGetIntForIndex} -body {
+    string index a 0+0x
+} -returnCodes error -match glob -result *
+test util-9.39 {TclGetIntForIndex} -body {
+    string index a 0+0xg
+} -returnCodes error -match glob -result *
+test util-9.40 {TclGetIntForIndex} -body {
+    string index a 0+0xg
+} -returnCodes error -match glob -result *
+test util-9.41 {TclGetIntForIndex} -body {
+    string index a 0+1.0
+} -returnCodes error -match glob -result *
+test util-9.42 {TclGetIntForIndex} -body {
+    string index a 0+1e2
+} -returnCodes error -match glob -result *
+test util-9.43 {TclGetIntForIndex} -body {
+    string index a 0+1.5e1
+} -returnCodes error -match glob -result *
+test util-9.44 {TclGetIntForIndex} -body {
+    string index a 0+1000000000000
+} -returnCodes error -match glob -result *
+
+test util-10.1 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0x0000000000000000
+} {0.0}
+test util-10.2 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0x8000000000000000
+} {-0.0}
+test util-10.3 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0x7ef754e31cd072da
+} {4e+303}
+test util-10.4 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0xd08afcef51f0fb5f
+} {-1e+80}
+test util-10.5 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0x7ed754e31cd072da
+} {1e+303}
+test util-10.6 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0xfee754e31cd072da
+} {-2e+303}
+test util-10.7 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0x0afe07b27dd78b14
+} {1e-255}
+test util-10.8 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0x93ae29e9c56687fe
+} {-7e-214}
+test util-10.9 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0x376be03d0bf225c7
+} {1e-41}
+test util-10.10 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0xa0ca2fe76a3f9475
+} {-1e-150}
+test util-10.11 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0x7fa9a2028368022e
+} {9e+306}
+test util-10.12 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0xdfc317e5ef3ab327
+} {-2e+153}
+test util-10.13 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0x5fd317e5ef3ab327
+} {4e+153}
+test util-10.14 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0xdfe317e5ef3ab327
+} {-8e+153}
+test util-10.15 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0x00feb8e84fa0b278
+} {7e-304}
+test util-10.16 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0x8133339131c46f8b
+} {-7e-303}
+test util-10.17 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0x35dc0f92a6276c9d
+} {3e-49}
+test util-10.18 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0xa445ce1f143d7ad2
+} {-6e-134}
+test util-10.19 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0x2d2c0794d9d40e96
+} {4.3e-91}
+test util-10.20 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0xad3c0794d9d40e96
+} {-8.6e-91}
+test util-10.21 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0x30ecd5bee57763e6
+} {5.1e-73}
+test util-10.22 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0x68ad1c26db7d0dae
+} {1.7e+196}
+test util-10.23 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0xbfa3f7ced916872b
+} {-0.039}
+test util-10.24 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0x64b7d93193f78fc6
+} {1.51e+177}
+test util-10.25 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0x98ea82a1631eeb30
+} {-1.19e-188}
+test util-10.26 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0xd216c309024bab4b
+} {-2.83e+87}
+test util-10.27 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0x0dfdbbac6f83a821
+} {2.7869147e-241}
+test util-10.28 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0xdadc569e968e0944
+} {-4.91080654e+129}
+test util-10.29 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0x5acc569e968e0944
+} {2.45540327e+129}
+test util-10.30 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0xab5fc575867314ee
+} {-9.078555839e-100}
+test util-10.31 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0xdabc569e968e0944
+} {-1.227701635e+129}
+test util-10.32 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0x2b6fc575867314ee
+} {1.8157111678e-99}
+test util-10.33 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0xb3b8bf7e7fa6f02a
+} {-1.5400733123779e-59}
+test util-10.34 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0xcd83de005bd620df
+} {-2.6153245263757307e+65}
+test util-10.35 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0x6cdf92bacb3cb40c
+} {2.7210404151224248e+216}
+test util-10.36 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0xecef92bacb3cb40c
+} {-5.4420808302448496e+216}
+test util-10.37 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0x49342dbf25096cf5
+} {4.5e+44}
+test util-10.38 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0xd06afcef51f0fb5f
+} {-2.5e+79}
+test util-10.39 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0x49002498ea6df0c4
+} {4.5e+43}
+test util-10.40 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0xfeb754e31cd072da
+} {-2.5e+302}
+test util-10.41 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0x1d22deac01e2b4f7
+} {2.5e-168}
+test util-10.42 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0xaccb1df536c13eee
+} {-6.5e-93}
+test util-10.43 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0x3650711fed5b19a4
+} {4.5e-47}
+test util-10.44 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0xb6848d67e8b1e00d
+} {-4.5e-46}
+test util-10.45 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0x4bac8c574c0c6be7
+} {3.5e+56}
+test util-10.46 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0xccd756183c147514
+} {-1.5e+62}
+test util-10.47 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0x4ca2ab469676c410
+} {1.5e+61}
+test util-10.48 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0xcf5539684e774b48
+} {-1.5e+74}
+test util-10.49 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0x2e12e5f5dfa4fe9d
+} {9.5e-87}
+test util-10.50 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0x8b9bdc2417bf7787
+} {-9.5e-253}
+test util-10.51 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0x00eeb8e84fa0b278
+} {3.5e-304}
+test util-10.52 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0xadde3cbc9907fdc8
+} {-9.5e-88}
+test util-10.53 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0x2bb0ad836f269a17
+} {3.05e-98}
+test util-10.54 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0x950b39ae1909c31b
+} {-2.65e-207}
+test util-10.55 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0x1bfb2ab18615fcc6
+} {6.865e-174}
+test util-10.56 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0x98f3e1f90a573064
+} {-1.785e-188}
+test util-10.57 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0x5206c309024bab4b
+} {1.415e+87}
+test util-10.58 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0xcc059bd3ad46e346
+} {-1.6955e+58}
+test util-10.59 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0x47bdf4170f0fdecc
+} {3.9815e+37}
+test util-10.60 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0x59e7e1e0f1c7a4ac
+} {1.263005e+125}
+test util-10.61 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0xda1dda592e398dd7
+} {-1.263005e+126}
+test util-10.62 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0xdc4e597c0b94b7ae
+} {-4.4118455e+136}
+test util-10.63 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0x5aac569e968e0944
+} {6.138508175e+128}
+test util-10.64 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0xdabc569e968e0944
+} {-1.227701635e+129}
+test util-10.65 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0x6ce7ae0c186d8709
+} {4.081560622683637e+216}
+test util-10.66 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0x44b52d02c7e14af7
+} {1.0000000000000001e+23}
+test util-10.67 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0xc589d971e4fe8402
+} {-1e+27}
+test util-10.68 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0x4599d971e4fe8402
+} {2e+27}
+test util-10.69 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0xc5a9d971e4fe8402
+} {-4e+27}
+test util-10.70 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0x3e45798ee2308c3a
+} {1e-8}
+test util-10.71 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0xbe55798ee2308c3a
+} {-2e-8}
+test util-10.72 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0x3e65798ee2308c3a
+} {4e-8}
+test util-10.73 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0xbabef2d0f5da7dd9
+} {-1e-25}
+test util-10.74 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0x44da784379d99db4
+} {5e+23}
+test util-10.75 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0xc4fa784379d99db4
+} {-2e+24}
+test util-10.76 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0x4503da329b633647
+} {3e+24}
+test util-10.77 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0xc54cf389cd46047d
+} {-7e+25}
+test util-10.78 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0x3fc999999999999a
+} {0.2}
+test util-10.79 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0xbfd3333333333333
+} {-0.3}
+test util-10.80 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0x3cf6849b86a12b9b
+} {5e-15}
+test util-10.81 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0xbd16849b86a12b9b
+} {-2e-14}
+test util-10.82 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0x3b87ccfc73126788
+} {6.3e-22}
+test util-10.83 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0xbbbdc03b8fd7016a
+} {-6.3e-21}
+test util-10.84 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0x3fa3f7ced916872b
+} {0.039}
+test util-10.85 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0x460b297cad9f70b6
+} {2.69e+29}
+test util-10.86 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0xc61b297cad9f70b6
+} {-5.38e+29}
+test util-10.87 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0x3adcdc06b20ef183
+} {3.73e-25}
+test util-10.88 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0x45fb297cad9f70b6
+} {1.345e+29}
+test util-10.89 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0xc60b297cad9f70b6
+} {-2.69e+29}
+test util-10.90 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0xbc050a246ecd44f3
+} {-1.4257e-19}
+test util-10.91 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0xbec19b96f36ec68b
+} {-2.09901e-6}
+test util-10.92 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0x3dcc06d366394441
+} {5.0980203373e-11}
+test util-10.93 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0xc79f58ac4db68c90
+} {-1.04166211811e+37}
+test util-10.94 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0x4569d971e4fe8402
+} {2.5e+26}
+test util-10.95 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0xc50dc74be914d16b
+} {-4.5e+24}
+test util-10.96 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0x4534adf4b7320335
+} {2.5e+25}
+test util-10.97 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0xc54ae22487c1042b
+} {-6.5e+25}
+test util-10.98 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0x3c987fe49aab41e0
+} {8.5e-17}
+test util-10.99 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0xbc2f5c05e4b23fd7
+} {-8.5e-19}
+test util-10.100 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0x3d5faa7ab552a552
+} {4.5e-13}
+test util-10.101 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0xbdbb7cdfd9d7bdbb
+} {-2.5e-11}
+test util-10.102 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0x44f3da329b633647
+} {1.5e+24}
+test util-10.103 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0xc53cf389cd46047d
+} {-3.5e+25}
+test util-10.104 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0x454f04ef12cb04cf
+} {7.5e+25}
+test util-10.105 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0xc55f04ef12cb04cf
+} {-1.5e+26}
+test util-10.106 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0x3fc3333333333333
+} {0.15}
+test util-10.107 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0xbdb07e1fe91b0b70
+} {-1.5e-11}
+test util-10.108 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0x3de49da7e361ce4c
+} {1.5e-10}
+test util-10.109 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0xbe19c511dc3a41df
+} {-1.5e-9}
+test util-10.110 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0xc5caa83d74267822
+} {-1.65e+28}
+test util-10.111 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0x4588f1d5969453de
+} {9.65e+26}
+test util-10.112 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0x3b91d9bd564dcda6
+} {9.45e-22}
+test util-10.113 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0xbcfa58973ecbede6
+} {-5.85e-15}
+test util-10.114 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0x45eb297cad9f70b6
+} {6.725e+28}
+test util-10.115 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0xc5fb297cad9f70b6
+} {-1.345e+29}
+test util-10.116 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0x3accdc06b20ef183
+} {1.865e-25}
+test util-10.117 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0xbd036071dcae4565
+} {-8.605e-15}
+test util-10.118 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0x462cb968d297dde8
+} {1.137885e+30}
+test util-10.119 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0xc661f3e1839eeab1
+} {-1.137885e+31}
+test util-10.120 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0x474e9cec176c96f8
+} {3.179033335e+35}
+test util-10.121 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0x3dbc06d366394441
+} {2.54901016865e-11}
+test util-10.122 {Tcl_PrintDouble - rounding} {ieeeFloatingPoint} {
+    convertDouble 0x478f58ac4db68c90
+} {5.20831059055e+36}
+
+test util-11.1 {Tcl_PrintDouble - scaling} {
+    expr 1.1e-5
+} {1.1e-5}
+test util-11.2 {Tcl_PrintDouble - scaling} {
+    expr 1.1e-4
+} {0.00011}
+test util-11.3 {Tcl_PrintDouble - scaling} {
+    expr 1.1e-3
+} {0.0011}
+test util-11.4 {Tcl_PrintDouble - scaling} {
+    expr 1.1e-2
+} {0.011}
+test util-11.5 {Tcl_PrintDouble - scaling} {
+    expr 1.1e-1
+} {0.11}
+test util-11.6 {Tcl_PrintDouble - scaling} {
+    expr 1.1e0
+} {1.1}
+test util-11.7 {Tcl_PrintDouble - scaling} {
+    expr 1.1e1
+} {11.0}
+test util-11.8 {Tcl_PrintDouble - scaling} {
+    expr 1.1e2
+} {110.0}
+test util-11.9 {Tcl_PrintDouble - scaling} {
+    expr 1.1e3
+} {1100.0}
+test util-11.10 {Tcl_PrintDouble - scaling} {
+    expr 1.1e4
+} {11000.0}
+test util-11.11 {Tcl_PrintDouble - scaling} {
+    expr 1.1e5
+} {110000.0}
+test util-11.12 {Tcl_PrintDouble - scaling} {
+    expr 1.1e6
+} {1100000.0}
+test util-11.13 {Tcl_PrintDouble - scaling} {
+    expr 1.1e7
+} {11000000.0}
+test util-11.14 {Tcl_PrintDouble - scaling} {
+    expr 1.1e8
+} {110000000.0}
+test util-11.15 {Tcl_PrintDouble - scaling} {
+    expr 1.1e9
+} {1100000000.0}
+test util-11.16 {Tcl_PrintDouble - scaling} {
+    expr 1.1e10
+} {11000000000.0}
+test util-11.17 {Tcl_PrintDouble - scaling} {
+    expr 1.1e11
+} {110000000000.0}
+test util-11.18 {Tcl_PrintDouble - scaling} {
+    expr 1.1e12
+} {1100000000000.0}
+test util-11.19 {Tcl_PrintDouble - scaling} {
+    expr 1.1e13
+} {11000000000000.0}
+test util-11.20 {Tcl_PrintDouble - scaling} {
+    expr 1.1e14
+} {110000000000000.0}
+test util-11.21 {Tcl_PrintDouble - scaling} {
+    expr 1.1e15
+} {1100000000000000.0}
+test util-11.22 {Tcl_PrintDouble - scaling} {
+    expr 1.1e16
+} {11000000000000000.0}
+test util-11.23 {Tcl_PrintDouble - scaling} {
+    expr 1.1e17
+} {1.1e+17}
+
+test util-12.1 {TclDoubleDigits - Inf} {testdoubledigits ieeeFloatingPoint} {
+     testdoubledigits Inf -1 shortest
+} {Infinity 9999 +}
+test util-12.2 {TclDoubleDigits - -Inf} {testdoubledigits ieeeFloatingPoint} {
+     testdoubledigits -Inf -1 shortest
+} {Infinity 9999 -}
+test util-12.3 {TclDoubleDigits - NaN} {testdoubledigits ieeeFloatingPoint} {
+     testdoubledigits $ieeeValues(NaN) -1 shortest
+} {NaN 9999 +}
+test util-12.4 {TclDoubleDigits - NaN} {*}{
+     -constraints {testdoubledigits ieeeFloatingPoint controversialNaN}
+     -body {
+	 testdoubledigits -NaN -1 shortest
+     }
+    -result {NaN 9999 -}
+}
+test util-12.5 {TclDoubleDigits - 0} testdoubledigits {
+     testdoubledigits 0.0 -1 shortest
+} {0 0 +}
+test util-12.6 {TclDoubleDigits - -0} testdoubledigits {
+     testdoubledigits -0.0 -1 shortest
+} {0 0 -}
+
+# Verdonk test vectors
+
+test util-13.1 {just over exact - 1 digits} {*}{
+    -constraints testdoubledigits
+    -body {
+        verdonk_test 1754e31cd072da E+1008 +4_000000000000000000& E+303
+    }
+    -result {}
+}
+test util-13.2 {just over exact - 1 digits} {*}{
+    -constraints testdoubledigits
+    -body {
+        verdonk_test -1afcef51f0fb5f E+265 -1_000000000000000000& E+80
+    }
+    -result {}
+}
+test util-13.3 {just over exact - 1 digits} {*}{
+    -constraints testdoubledigits
+    -body {
+        verdonk_test 1754e31cd072da E+1006 +1_000000000000000000& E+303
+    }
+    -result {}
+}
+test util-13.4 {just over exact - 1 digits} {*}{
+    -constraints testdoubledigits
+    -body {
+        verdonk_test -1754e31cd072da E+1007 -2_000000000000000000& E+303
+    }
+    -result {}
+}
+test util-13.5 {just over exact - 1 digits} {*}{
+    -constraints testdoubledigits
+    -body {
+        verdonk_test 1e07b27dd78b14 E-848 +1_00000000000000000& E-255
+    }
+    -result {}
+}
+test util-13.6 {just over exact - 1 digits} {*}{
+    -constraints testdoubledigits
+    -body {
+        verdonk_test -1e29e9c56687fe E-709 -7_00000000000000000& E-214
+    }
+    -result {}
+}
+test util-13.7 {just over exact - 1 digits} {*}{
+    -constraints testdoubledigits
+    -body {
+        verdonk_test 1be03d0bf225c7 E-137 +1_00000000000000000& E-41
+    }
+    -result {}
+}
+test util-13.8 {just over exact - 1 digits} {*}{
+    -constraints testdoubledigits
+    -body {
+        verdonk_test -1a2fe76a3f9475 E-499 -1_00000000000000000& E-150
+    }
+    -result {}
+}
+test util-13.9 {just under exact - 1 digits} {*}{
+    -constraints testdoubledigits
+    -body {
+        verdonk_test 19a2028368022e E+1019 +8_999999999999999999& E+306
+    }
+    -result {}
+}
+test util-13.10 {just under exact - 1 digits} {*}{
+    -constraints testdoubledigits
+    -body {
+        verdonk_test -1317e5ef3ab327 E+509 -1_999999999999999999& E+153
+    }
+    -result {}
+}
+test util-13.11 {just under exact - 1 digits} {*}{
+    -constraints testdoubledigits
+    -body {
+        verdonk_test 1317e5ef3ab327 E+510 +3_99999999999999999& E+153
+    }
+    -result {}
+}
+test util-13.12 {just under exact - 1 digits} {*}{
+    -constraints testdoubledigits
+    -body {
+        verdonk_test -1317e5ef3ab327 E+511 -7_99999999999999999& E+153
+    }
+    -result {}
+}
+test util-13.13 {just under exact - 1 digits} {*}{
+    -constraints testdoubledigits
+    -body {
+        verdonk_test 1eb8e84fa0b278 E-1008 +6_999999999999999999& E-304
+    }
+    -result {}
+}
+test util-13.14 {just under exact - 1 digits} {*}{
+    -constraints testdoubledigits
+    -body {
+        verdonk_test -13339131c46f8b E-1004 -6_999999999999999999& E-303
+    }
+    -result {}
+}
+test util-13.15 {just under exact - 1 digits} {*}{
+    -constraints testdoubledigits
+    -body {
+        verdonk_test 1c0f92a6276c9d E-162 +2_999999999999999999& E-49
+    }
+    -result {}
+}
+test util-13.16 {just under exact - 1 digits} {*}{
+    -constraints testdoubledigits
+    -body {
+        verdonk_test -15ce1f143d7ad2 E-443 -5_99999999999999999& E-134
+    }
+    -result {}
+}
+test util-13.17 {just over exact - 2 digits} {*}{
+    -constraints testdoubledigits
+    -body {
+        verdonk_test 1c0794d9d40e96 E-301 +43_000000000000000000& E-92
+    }
+    -result {}
+}
+test util-13.18 {just over exact - 2 digits} {*}{
+    -constraints testdoubledigits
+    -body {
+        verdonk_test -1c0794d9d40e96 E-300 -86_000000000000000000& E-92
+    }
+    -result {}
+}
+test util-13.19 {just over exact - 2 digits} {*}{
+    -constraints testdoubledigits
+    -body {
+        verdonk_test 1cd5bee57763e6 E-241 +51_000000000000000000& E-74
+    }
+    -result {}
+}
+test util-13.20 {just under exact - 2 digits} {*}{
+    -constraints testdoubledigits
+    -body {
+        verdonk_test 1d1c26db7d0dae E+651 +16_999999999999999999& E+195
+    }
+    -result {}
+}
+test util-13.21 {just under exact - 2 digits} {*}{
+    -constraints testdoubledigits
+    -body {
+        verdonk_test -13f7ced916872b E-5 -38_999999999999999999& E-3
+    }
+    -result {}
+}
+test util-13.22 {just over exact - 3 digits} {*}{
+    -constraints testdoubledigits
+    -body {
+        verdonk_test 17d93193f78fc6 E+588 +151_0000000000000000000& E+175
+    }
+    -result {}
+}
+test util-13.23 {just over exact - 3 digits} {*}{
+    -constraints testdoubledigits
+    -body {
+        verdonk_test -1a82a1631eeb30 E-625 -119_000000000000000000& E-190
+    }
+    -result {}
+}
+test util-13.24 {just under exact - 3 digits} {*}{
+    -constraints testdoubledigits
+    -body {
+        verdonk_test -16c309024bab4b E+290 -282_999999999999999999& E+85
+    }
+    -result {}
+}
+test util-13.25 {just over exact - 8 digits} {*}{
+    -constraints testdoubledigits
+    -body {
+        verdonk_test 1dbbac6f83a821 E-800 +27869147_0000000000000000000& E-248
+    }
+    -result {}
+}
+test util-13.26 {just under exact - 9 digits} {*}{
+    -constraints testdoubledigits
+    -body {
+        verdonk_test -1c569e968e0944 E+430 -491080653_9999999999999999999& E+121
+    }
+    -result {}
+}
+test util-13.27 {just under exact - 9 digits} {*}{
+    -constraints testdoubledigits
+    -body {
+        verdonk_test 1c569e968e0944 E+429 +245540326_9999999999999999999& E+121
+    }
+    -result {}
+}
+test util-13.28 {just over exact - 10 digits} {*}{
+    -constraints testdoubledigits
+    -body {
+        verdonk_test -1fc575867314ee E-330 -9078555839_0000000000000000000& E-109
+    }
+    -result {}
+}
+test util-13.29 {just under exact - 10 digits} {*}{
+    -constraints testdoubledigits
+    -body {
+        verdonk_test -1c569e968e0944 E+428 -1227701634_9999999999999999999& E+120
+    }
+    -result {}
+}
+test util-13.30 {just over exact - 11 digits} {*}{
+    -constraints testdoubledigits
+    -body {
+        verdonk_test 1fc575867314ee E-329 +18157111678_0000000000000000000& E-109
+    }
+    -result {}
+}
+test util-13.31 {just over exact - 14 digits} {*}{
+    -constraints testdoubledigits
+    -body {
+        verdonk_test -18bf7e7fa6f02a E-196 -15400733123779_0000000000000000000& E-72
+    }
+    -result {}
+}
+test util-13.32 {just over exact - 17 digits} {*}{
+    -constraints testdoubledigits
+    -body {
+        verdonk_test -13de005bd620df E+217 -26153245263757307_0000000000000000000& E+49
+    }
+    -result {}
+}
+test util-13.33 {just over exact - 18 digits} {*}{
+    -constraints testdoubledigits
+    -body {
+        verdonk_test 1f92bacb3cb40c E+718 +272104041512242479_0000000000000000000& E+199
+    }
+    -result {}
+}
+test util-13.34 {just over exact - 18 digits} {*}{
+    -constraints testdoubledigits
+    -body {
+        verdonk_test -1f92bacb3cb40c E+719 -544208083024484958_0000000000000000000& E+199
+    }
+    -result {}
+}
+test util-13.35 {just over half ulp - 1 digits} {*}{
+    -constraints testdoubledigits
+    -body {
+        verdonk_test 142dbf25096cf5 E+148 +4_500000000000000000& E+44
+    }
+    -result {}
+}
+test util-13.36 {just over half ulp - 1 digits} {*}{
+    -constraints testdoubledigits
+    -body {
+        verdonk_test -1afcef51f0fb5f E+263 -2_500000000000000000& E+79
+    }
+    -result {}
+}
+test util-13.37 {just over half ulp - 1 digits} {*}{
+    -constraints testdoubledigits
+    -body {
+        verdonk_test 102498ea6df0c4 E+145 +4_500000000000000000& E+43
+    }
+    -result {}
+}
+test util-13.38 {just over half ulp - 1 digits} {*}{
+    -constraints testdoubledigits
+    -body {
+        verdonk_test -1754e31cd072da E+1004 -2_500000000000000000& E+302
+    }
+    -result {}
+}
+test util-13.39 {just over half ulp - 1 digits} {*}{
+    -constraints testdoubledigits
+    -body {
+        verdonk_test 12deac01e2b4f7 E-557 +2_50000000000000000& E-168
+    }
+    -result {}
+}
+test util-13.40 {just over half ulp - 1 digits} {*}{
+    -constraints testdoubledigits
+    -body {
+        verdonk_test -1b1df536c13eee E-307 -6_50000000000000000& E-93
+    }
+    -result {}
+}
+test util-13.41 {just over half ulp - 1 digits} {*}{
+    -constraints testdoubledigits
+    -body {
+        verdonk_test 10711fed5b19a4 E-154 +4_50000000000000000& E-47
+    }
+    -result {}
+}
+test util-13.42 {just over half ulp - 1 digits} {*}{
+    -constraints testdoubledigits
+    -body {
+        verdonk_test -148d67e8b1e00d E-151 -4_50000000000000000& E-46
+    }
+    -result {}
+}
+test util-13.43 {just under half ulp - 1 digits} {*}{
+    -constraints testdoubledigits
+    -body {
+        verdonk_test 1c8c574c0c6be7 E+187 +3_49999999999999999& E+56
+    }
+    -result {}
+}
+test util-13.44 {just under half ulp - 1 digits} {*}{
+    -constraints testdoubledigits
+    -body {
+        verdonk_test -1756183c147514 E+206 -1_49999999999999999& E+62
+    }
+    -result {}
+}
+test util-13.45 {just under half ulp - 1 digits} {*}{
+    -constraints testdoubledigits
+    -body {
+        verdonk_test 12ab469676c410 E+203 +1_49999999999999999& E+61
+    }
+    -result {}
+}
+test util-13.46 {just under half ulp - 1 digits} {*}{
+    -constraints testdoubledigits
+    -body {
+        verdonk_test -1539684e774b48 E+246 -1_49999999999999999& E+74
+    }
+    -result {}
+}
+test util-13.47 {just under half ulp - 1 digits} {*}{
+    -constraints testdoubledigits
+    -body {
+        verdonk_test 12e5f5dfa4fe9d E-286 +9_499999999999999999& E-87
+    }
+    -result {}
+}
+test util-13.48 {just under half ulp - 1 digits} {*}{
+    -constraints testdoubledigits
+    -body {
+        verdonk_test -1bdc2417bf7787 E-838 -9_499999999999999999& E-253
+    }
+    -result {}
+}
+test util-13.49 {just under half ulp - 1 digits} {*}{
+    -constraints testdoubledigits
+    -body {
+        verdonk_test 1eb8e84fa0b278 E-1009 +3_499999999999999999& E-304
+    }
+    -result {}
+}
+test util-13.50 {just under half ulp - 1 digits} {*}{
+    -constraints testdoubledigits
+    -body {
+        verdonk_test -1e3cbc9907fdc8 E-290 -9_499999999999999999& E-88
+    }
+    -result {}
+}
+test util-13.51 {just over half ulp - 2 digits} {*}{
+    -constraints testdoubledigits
+    -body {
+        verdonk_test 10ad836f269a17 E-324 +30_500000000000000000& E-99
+    }
+    -result {}
+}
+test util-13.52 {just over half ulp - 2 digits} {*}{
+    -constraints testdoubledigits
+    -body {
+        verdonk_test -1b39ae1909c31b E-687 -26_500000000000000000& E-208
+    }
+    -result {}
+}
+test util-13.53 {just over half ulp - 3 digits} {*}{
+    -constraints testdoubledigits
+    -body {
+        verdonk_test 1b2ab18615fcc6 E-576 +686_500000000000000000& E-176
+    }
+    -result {}
+}
+test util-13.54 {just over half ulp - 3 digits} {*}{
+    -constraints testdoubledigits
+    -body {
+        verdonk_test -13e1f90a573064 E-624 -178_500000000000000000& E-190
+    }
+    -result {}
+}
+test util-13.55 {just under half ulp - 3 digits} {*}{
+    -constraints testdoubledigits
+    -body {
+        verdonk_test 16c309024bab4b E+289 +141_499999999999999999& E+85
+    }
+    -result {}
+}
+test util-13.56 {just under half ulp - 4 digits} {*}{
+    -constraints testdoubledigits
+    -body {
+        verdonk_test -159bd3ad46e346 E+193 -1695_499999999999999999& E+55
+    }
+    -result {}
+}
+test util-13.57 {just under half ulp - 4 digits} {*}{
+    -constraints testdoubledigits
+    -body {
+        verdonk_test 1df4170f0fdecc E+124 +3981_499999999999999999& E+34
+    }
+    -result {}
+}
+test util-13.58 {just over half ulp - 6 digits} {*}{
+    -constraints testdoubledigits
+    -body {
+        verdonk_test 17e1e0f1c7a4ac E+415 +126300_5000000000000000000& E+120
+    }
+    -result {}
+}
+test util-13.59 {just over half ulp - 6 digits} {*}{
+    -constraints testdoubledigits
+    -body {
+        verdonk_test -1dda592e398dd7 E+418 -126300_5000000000000000000& E+121
+    }
+    -result {}
+}
+test util-13.60 {just under half ulp - 7 digits} {*}{
+    -constraints testdoubledigits
+    -body {
+        verdonk_test -1e597c0b94b7ae E+453 -4411845_499999999999999999& E+130
+    }
+    -result {}
+}
+test util-13.61 {just under half ulp - 9 digits} {*}{
+    -constraints testdoubledigits
+    -body {
+        verdonk_test 1c569e968e0944 E+427 +613850817_4999999999999999999& E+120
+    }
+    -result {}
+}
+test util-13.62 {just under half ulp - 9 digits} {*}{
+    -constraints testdoubledigits
+    -body {
+        verdonk_test -1c569e968e0944 E+428 -122770163_49999999999999999999& E+121
+    }
+    -result {}
+}
+test util-13.63 {just over half ulp - 18 digits} {*}{
+    -constraints testdoubledigits
+    -body {
+        verdonk_test 17ae0c186d8709 E+719 +408156062268363718_5000000000000000000& E+199
+    }
+    -result {}
+}
+test util-13.64 {just over exact - 1 digits} {*}{
+    -constraints testdoubledigits
+    -body {
+        verdonk_test 152d02c7e14af7 E+76 +1_0000000000000000& E+23
+    }
+    -result {}
+}
+test util-13.65 {just over exact - 1 digits} {*}{
+    -constraints testdoubledigits
+    -body {
+        verdonk_test -19d971e4fe8402 E+89 -1_0000000000000000& E+27
+    }
+    -result {}
+}
+test util-13.66 {just over exact - 1 digits} {*}{
+    -constraints testdoubledigits
+    -body {
+        verdonk_test 19d971e4fe8402 E+90 +2_0000000000000000& E+27
+    }
+    -result {}
+}
+test util-13.67 {just over exact - 1 digits} {*}{
+    -constraints testdoubledigits
+    -body {
+        verdonk_test -19d971e4fe8402 E+91 -4_0000000000000000& E+27
+    }
+    -result {}
+}
+test util-13.68 {just over exact - 1 digits} {*}{
+    -constraints testdoubledigits
+    -body {
+        verdonk_test 15798ee2308c3a E-27 +1_0000000000000000& E-8
+    }
+    -result {}
+}
+test util-13.69 {just over exact - 1 digits} {*}{
+    -constraints testdoubledigits
+    -body {
+        verdonk_test -15798ee2308c3a E-26 -2_0000000000000000& E-8
+    }
+    -result {}
+}
+test util-13.70 {just over exact - 1 digits} {*}{
+    -constraints testdoubledigits
+    -body {
+        verdonk_test 15798ee2308c3a E-25 +4_0000000000000000& E-8
+    }
+    -result {}
+}
+test util-13.71 {just over exact - 1 digits} {*}{
+    -constraints testdoubledigits
+    -body {
+        verdonk_test -1ef2d0f5da7dd9 E-84 -1_0000000000000000& E-25
+    }
+    -result {}
+}
+test util-13.72 {just under exact - 1 digits} {*}{
+    -constraints testdoubledigits
+    -body {
+        verdonk_test 1a784379d99db4 E+78 +4_9999999999999999& E+23
+    }
+    -result {}
+}
+test util-13.73 {just under exact - 1 digits} {*}{
+    -constraints testdoubledigits
+    -body {
+        verdonk_test -1a784379d99db4 E+80 -1_9999999999999999& E+24
+    }
+    -result {}
+}
+test util-13.74 {just under exact - 1 digits} {*}{
+    -constraints testdoubledigits
+    -body {
+        verdonk_test 13da329b633647 E+81 +2_9999999999999999& E+24
+    }
+    -result {}
+}
+test util-13.75 {just under exact - 1 digits} {*}{
+    -constraints testdoubledigits
+    -body {
+        verdonk_test -1cf389cd46047d E+85 -6_9999999999999999& E+25
+    }
+    -result {}
+}
+test util-13.76 {just under exact - 1 digits} {*}{
+    -constraints testdoubledigits
+    -body {
+        verdonk_test 19999999999999 E-3 +1_99999999999999999& E-1
+    }
+    -result {}
+}
+test util-13.77 {just under exact - 1 digits} {*}{
+    -constraints testdoubledigits
+    -body {
+        verdonk_test -13333333333333 E-2 -2_99999999999999999& E-1
+    }
+    -result {}
+}
+test util-13.78 {just under exact - 1 digits} {*}{
+    -constraints testdoubledigits
+    -body {
+        verdonk_test 16849b86a12b9b E-48 +4_99999999999999999& E-15
+    }
+    -result {}
+}
+test util-13.79 {just under exact - 1 digits} {*}{
+    -constraints testdoubledigits
+    -body {
+        verdonk_test -16849b86a12b9b E-46 -1_99999999999999999& E-14
+    }
+    -result {}
+}
+test util-13.80 {just over exact - 2 digits} {*}{
+    -constraints testdoubledigits
+    -body {
+        verdonk_test 17ccfc73126788 E-71 +63_00000000000000000& E-23
+    }
+    -result {}
+}
+test util-13.81 {just over exact - 2 digits} {*}{
+    -constraints testdoubledigits
+    -body {
+        verdonk_test -1dc03b8fd7016a E-68 -63_00000000000000000& E-22
+    }
+    -result {}
+}
+test util-13.82 {just under exact - 2 digits} {*}{
+    -constraints testdoubledigits
+    -body {
+        verdonk_test 13f7ced916872b E-5 +38_999999999999999999& E-3
+    }
+    -result {}
+}
+test util-13.83 {just over exact - 3 digits} {*}{
+    -constraints testdoubledigits
+    -body {
+        verdonk_test 1b297cad9f70b6 E+97 +269_000000000000000000& E+27
+    }
+    -result {}
+}
+test util-13.84 {just over exact - 3 digits} {*}{
+    -constraints testdoubledigits
+    -body {
+        verdonk_test -1b297cad9f70b6 E+98 -538_00000000000000000& E+27
+    }
+    -result {}
+}
+test util-13.85 {just over exact - 3 digits} {*}{
+    -constraints testdoubledigits
+    -body {
+        verdonk_test 1cdc06b20ef183 E-82 +373_00000000000000000& E-27
+    }
+    -result {}
+}
+test util-13.86 {just over exact - 4 digits} {*}{
+    -constraints testdoubledigits
+    -body {
+        verdonk_test 1b297cad9f70b6 E+96 +1345_00000000000000000& E+26
+    }
+    -result {}
+}
+# this one is not 4 digits, it is 3, and it is covered above.
+test util-13.87 {just over exact - 4 digits} {*}{
+    -constraints {testdoubledigits knownBadTest}
+    -body {
+        verdonk_test -1b297cad9f70b6 E+97 -2690_00000000000000000& E+26
+    }
+    -result {}
+}
+test util-13.88 {just over exact - 5 digits} {*}{
+    -constraints testdoubledigits
+    -body {
+        verdonk_test -150a246ecd44f3 E-63 -14257_00000000000000000& E-23
+    }
+    -result {}
+}
+test util-13.89 {just under exact - 6 digits} {*}{
+    -constraints testdoubledigits
+    -body {
+        verdonk_test -119b96f36ec68b E-19 -209900_999999999999999999& E-11
+    }
+    -result {}
+}
+test util-13.90 {just over exact - 11 digits} {*}{
+    -constraints testdoubledigits
+    -body {
+        verdonk_test 1c06d366394441 E-35 +50980203373_000000000000000000& E-21
+    }
+    -result {}
+}
+test util-13.91 {just under exact - 12 digits} {*}{
+    -constraints testdoubledigits
+    -body {
+        verdonk_test -1f58ac4db68c90 E+122 -104166211810_99999999999999999& E+26
+    }
+    -result {}
+}
+test util-13.92 {just over half ulp - 1 digits} {*}{
+    -constraints testdoubledigits
+    -body {
+        verdonk_test 19d971e4fe8402 E+87 +2_5000000000000000& E+26
+    }
+    -result {}
+}
+test util-13.93 {just over half ulp - 1 digits} {*}{
+    -constraints testdoubledigits
+    -body {
+        verdonk_test -1dc74be914d16b E+81 -4_500000000000000& E+24
+    }
+    -result {}
+}
+test util-13.94 {just over half ulp - 1 digits} {*}{
+    -constraints testdoubledigits
+    -body {
+        verdonk_test 14adf4b7320335 E+84 +2_500000000000000& E+25
+    }
+    -result {}
+}
+test util-13.95 {just over half ulp - 1 digits} {*}{
+    -constraints testdoubledigits
+    -body {
+        verdonk_test -1ae22487c1042b E+85 -6_5000000000000000& E+25
+    }
+    -result {}
+}
+test util-13.96 {just over half ulp - 1 digits} {*}{
+    -constraints testdoubledigits
+    -body {
+        verdonk_test 187fe49aab41e0 E-54 +8_5000000000000000& E-17
+    }
+    -result {}
+}
+test util-13.97 {just over half ulp - 1 digits} {*}{
+    -constraints testdoubledigits
+    -body {
+        verdonk_test -1f5c05e4b23fd7 E-61 -8_5000000000000000& E-19
+    }
+    -result {}
+}
+test util-13.98 {just over half ulp - 1 digits} {*}{
+    -constraints testdoubledigits
+    -body {
+        verdonk_test 1faa7ab552a552 E-42 +4_5000000000000000& E-13
+    }
+    -result {}
+}
+test util-13.99 {just over half ulp - 1 digits} {*}{
+    -constraints testdoubledigits
+    -body {
+        verdonk_test -1b7cdfd9d7bdbb E-36 -2_5000000000000000& E-11
+    }
+    -result {}
+}
+test util-13.100 {just under half ulp - 1 digits} {*}{
+    -constraints testdoubledigits
+    -body {
+        verdonk_test 13da329b633647 E+80 +1_4999999999999999& E+24
+    }
+    -result {}
+}
+test util-13.101 {just under half ulp - 1 digits} {*}{
+    -constraints testdoubledigits
+    -body {
+        verdonk_test -1cf389cd46047d E+84 -3_49999999999999999& E+25
+    }
+    -result {}
+}
+test util-13.102 {just under half ulp - 1 digits} {*}{
+    -constraints testdoubledigits
+    -body {
+        verdonk_test 1f04ef12cb04cf E+85 +7_4999999999999999& E+25
+    }
+    -result {}
+}
+test util-13.103 {just under half ulp - 1 digits} {*}{
+    -constraints testdoubledigits
+    -body {
+        verdonk_test -1f04ef12cb04cf E+86 -1_4999999999999999& E+26
+    }
+    -result {}
+}
+test util-13.104 {just under half ulp - 1 digits} {*}{
+    -constraints testdoubledigits
+    -body {
+        verdonk_test 13333333333333 E-3 +1_49999999999999999& E-1
+    }
+    -result {}
+}
+test util-13.105 {just under half ulp - 1 digits} {*}{
+    -constraints testdoubledigits
+    -body {
+        verdonk_test -107e1fe91b0b70 E-36 -1_49999999999999999& E-11
+    }
+    -result {}
+}
+test util-13.106 {just under half ulp - 1 digits} {*}{
+    -constraints testdoubledigits
+    -body {
+        verdonk_test 149da7e361ce4c E-33 +1_49999999999999999& E-10
+    }
+    -result {}
+}
+test util-13.107 {just under half ulp - 1 digits} {*}{
+    -constraints testdoubledigits
+    -body {
+        verdonk_test -19c511dc3a41df E-30 -1_49999999999999999& E-9
+    }
+    -result {}
+}
+test util-13.108 {just over half ulp - 2 digits} {*}{
+    -constraints testdoubledigits
+    -body {
+        verdonk_test -1aa83d74267822 E+93 -16_5000000000000000& E+27
+    }
+    -result {}
+}
+test util-13.109 {just over half ulp - 2 digits} {*}{
+    -constraints testdoubledigits
+    -body {
+        verdonk_test 18f1d5969453de E+89 +96_5000000000000000& E+25
+    }
+    -result {}
+}
+test util-13.110 {just over half ulp - 2 digits} {*}{
+    -constraints testdoubledigits
+    -body {
+        verdonk_test 11d9bd564dcda6 E-70 +94_50000000000000000& E-23
+    }
+    -result {}
+}
+test util-13.111 {just over half ulp - 2 digits} {*}{
+    -constraints testdoubledigits
+    -body {
+        verdonk_test -1a58973ecbede6 E-48 -58_50000000000000000& E-16
+    }
+    -result {}
+}
+test util-13.112 {just over half ulp - 3 digits} {*}{
+    -constraints testdoubledigits
+    -body {
+        verdonk_test 1b297cad9f70b6 E+95 +672_50000000000000000& E+26
+    }
+    -result {}
+}
+test util-13.113 {just over half ulp - 3 digits} {*}{
+    -constraints testdoubledigits
+    -body {
+        verdonk_test -1b297cad9f70b6 E+96 -134_500000000000000000& E+27
+    }
+    -result {}
+}
+test util-13.114 {just over half ulp - 3 digits} {*}{
+    -constraints testdoubledigits
+    -body {
+        verdonk_test 1cdc06b20ef183 E-83 +186_50000000000000000& E-27
+    }
+    -result {}
+}
+test util-13.115 {just over half ulp - 3 digits} {*}{
+    -constraints testdoubledigits
+    -body {
+        verdonk_test -136071dcae4565 E-47 -860_50000000000000000& E-17
+    }
+    -result {}
+}
+test util-13.116 {just over half ulp - 6 digits} {*}{
+    -constraints testdoubledigits
+    -body {
+        verdonk_test 1cb968d297dde8 E+99 +113788_50000000000000000& E+25
+    }
+    -result {}
+}
+test util-13.117 {just over half ulp - 6 digits} {*}{
+    -constraints testdoubledigits
+    -body {
+        verdonk_test -11f3e1839eeab1 E+103 -113788_50000000000000000& E+26
+    }
+    -result {}
+}
+test util-13.118 {just under half ulp - 9 digits} {*}{
+    -constraints testdoubledigits
+    -body {
+        verdonk_test 1e9cec176c96f8 E+117 +317903333_49999999999999999& E+27
+    }
+    -result {}
+}
+test util-13.119 {just over half ulp - 11 digits} {*}{
+    -constraints testdoubledigits
+    -body {
+        verdonk_test 1c06d366394441 E-36 +25490101686_500000000000000000& E-21
+    }
+    -result {}
+}
+test util-13.120 {just under half ulp - 11 digits} {*}{
+    -constraints testdoubledigits
+    -body {
+        verdonk_test 1f58ac4db68c90 E+121 +52083105905_49999999999999999& E+26
+    }
+    -result {}
+}
+
+test util-14.1 {funky NaN} {*}{
+    -constraints {ieeeFloatingPoint controversialNaN}
+    -body {
+	set ieeeValues(-NaN)
+    }
+    -result -NaN
+}
+
+test util-14.2 {funky NaN} {*}{
+    -constraints {ieeeFloatingPoint controversialNaN}
+    -body {
+	set ieeeValues(-NaN(3456789abcdef))
+    }
+    -result -NaN(3456789abcdef)
+}
+
+test util-15.1 {largest subnormal} {*}{
+    -body {
+	binary scan [binary format w 0x000fffffffffffff] q x
+	set x
+    }
+    -result 2.225073858507201e-308
+    -cleanup {
+	unset x
+    }
+}
+
+test util-15.2 {largest subnormal} {*}{
+    -body {
+	binary scan [binary format w 0x800fffffffffffff] q x
+	set x
+    }
+    -result -2.225073858507201e-308
+    -cleanup {
+	unset x
+    }
+}
+
+test util-15.3 {largest subnormal} {*}{
+    -body {
+	binary scan [binary format q 2.225073858507201e-308] w x
+	format %#lx $x
+    }
+    -result 0xfffffffffffff
+    -cleanup {
+	unset x
+    }
+}
+
+test util-15.4 {largest subnormal} {*}{
+    -body {
+	binary scan [binary format q -2.225073858507201e-308] w x
+	format %#lx $x
+    }
+    -result 0x800fffffffffffff
+    -cleanup {
+	unset x
+    }
+}
+
+test util-15.5 {smallest normal} {*}{
+    -body {
+	binary scan [binary format w 0x0010000000000000] q x
+	set x
+    }
+    -result 2.2250738585072014e-308
+    -cleanup {
+	unset x
+    }
+}
+
+test util-15.6 {smallest normal} {*}{
+    -body {
+	binary scan [binary format w 0x8010000000000000] q x
+	set x
+    }
+    -result -2.2250738585072014e-308
+    -cleanup {
+	unset x
+    }
+}
+
+test util-15.7 {smallest normal} {*}{
+    -body {
+	binary scan [binary format q 2.2250738585072014e-308] w x
+	format %#lx $x
+    }
+    -result 0x10000000000000
+    -cleanup {
+	unset x
+    }
+}
+
+test util-15.8 {smallest normal} {*}{
+    -body {
+	binary scan [binary format q -2.2250738585072014e-308] w x
+	format %#lx $x
+    }
+    -result 0x8010000000000000
+    -cleanup {
+	unset x
+    }
+}
+
+set saved_precision $::tcl_precision
+foreach ::tcl_precision {0 12} {
+    for {set e -312} {$e < -9} {incr e} {
+	test util-16.1.$::tcl_precision.$e {shortening of numbers} \
+	    "expr 1.1e$e" 1.1e$e
+    }
+}
+set tcl_precision 0
+for {set e -9} {$e < -4} {incr e} {
+    test util-16.1.$::tcl_precision.$e {shortening of numbers} \
+	"expr 1.1e$e" 1.1e$e
+}
+set tcl_precision 12
+for {set e -9} {$e < -4} {incr e} {
+    test util-16.1.$::tcl_precision.$e {8.4 compatible formatting of doubles} \
+	"expr 1.1e$e" 1.1e[format %+03d $e]
+}
+foreach ::tcl_precision {0 12} {
+    test util-16.1.$::tcl_precision.-4 {shortening of numbers} \
+	{expr 1.1e-4} \
+	0.00011
+    test util-16.1.$::tcl_precision.-3 {shortening of numbers} \
+	{expr 1.1e-3} \
+	0.0011
+    test util-16.1.$::tcl_precision.-2 {shortening of numbers} \
+	{expr 1.1e-2} \
+	0.011
+    test util-16.1.$::tcl_precision.-1 {shortening of numbers} \
+	{expr 1.1e-1} \
+	0.11
+    test util-16.1.$::tcl_precision.0 {shortening of numbers} \
+	{expr 1.1} \
+	1.1
+    for {set e 1} {$e < 17} {incr e} {
+	test util-16.1.$::tcl_precision.$e {shortening of numbers} \
+	    "expr 11[string repeat 0 [expr {$e-1}]].0" \
+	    11[string repeat 0 [expr {$e-1}]].0
+    }
+    for {set e 17} {$e < 309} {incr e} {
+	test util-16.1.$::tcl_precision.$e {shortening of numbers} \
+	    "expr 1.1e$e" 1.1e+$e
+    }
+}
+set tcl_precision 17
+test util-16.1.17.-300 {8.4 compatible formatting of doubles} \
+    {expr 1e-300} \
+    1e-300
+test util-16.1.17.-299 {8.4 compatible formatting of doubles} \
+    {expr 1e-299} \
+    9.9999999999999999e-300
+test util-16.1.17.-298 {8.4 compatible formatting of doubles} \
+    {expr 1e-298} \
+    9.9999999999999991e-299
+test util-16.1.17.-297 {8.4 compatible formatting of doubles} \
+    {expr 1e-297} \
+    1e-297
+test util-16.1.17.-296 {8.4 compatible formatting of doubles} \
+    {expr 1e-296} \
+    1e-296
+test util-16.1.17.-295 {8.4 compatible formatting of doubles} \
+    {expr 1e-295} \
+    1.0000000000000001e-295
+test util-16.1.17.-294 {8.4 compatible formatting of doubles} \
+    {expr 1e-294} \
+    1e-294
+test util-16.1.17.-293 {8.4 compatible formatting of doubles} \
+    {expr 1e-293} \
+    1.0000000000000001e-293
+test util-16.1.17.-292 {8.4 compatible formatting of doubles} \
+    {expr 1e-292} \
+    1.0000000000000001e-292
+test util-16.1.17.-291 {8.4 compatible formatting of doubles} \
+    {expr 1e-291} \
+    9.9999999999999996e-292
+test util-16.1.17.-290 {8.4 compatible formatting of doubles} \
+    {expr 1e-290} \
+    1.0000000000000001e-290
+test util-16.1.17.-289 {8.4 compatible formatting of doubles} \
+    {expr 1e-289} \
+    1e-289
+test util-16.1.17.-288 {8.4 compatible formatting of doubles} \
+    {expr 1e-288} \
+    1.0000000000000001e-288
+test util-16.1.17.-287 {8.4 compatible formatting of doubles} \
+    {expr 1e-287} \
+    1e-287
+test util-16.1.17.-286 {8.4 compatible formatting of doubles} \
+    {expr 1e-286} \
+    1.0000000000000001e-286
+test util-16.1.17.-285 {8.4 compatible formatting of doubles} \
+    {expr 1e-285} \
+    1.0000000000000001e-285
+test util-16.1.17.-284 {8.4 compatible formatting of doubles} \
+    {expr 1e-284} \
+    1e-284
+test util-16.1.17.-283 {8.4 compatible formatting of doubles} \
+    {expr 1e-283} \
+    9.9999999999999995e-284
+test util-16.1.17.-282 {8.4 compatible formatting of doubles} \
+    {expr 1e-282} \
+    1e-282
+test util-16.1.17.-281 {8.4 compatible formatting of doubles} \
+    {expr 1e-281} \
+    1e-281
+test util-16.1.17.-280 {8.4 compatible formatting of doubles} \
+    {expr 1e-280} \
+    9.9999999999999996e-281
+test util-16.1.17.-279 {8.4 compatible formatting of doubles} \
+    {expr 1e-279} \
+    1.0000000000000001e-279
+test util-16.1.17.-278 {8.4 compatible formatting of doubles} \
+    {expr 1e-278} \
+    9.9999999999999994e-279
+test util-16.1.17.-277 {8.4 compatible formatting of doubles} \
+    {expr 1e-277} \
+    9.9999999999999997e-278
+test util-16.1.17.-276 {8.4 compatible formatting of doubles} \
+    {expr 1e-276} \
+    1.0000000000000001e-276
+test util-16.1.17.-275 {8.4 compatible formatting of doubles} \
+    {expr 1e-275} \
+    9.9999999999999993e-276
+test util-16.1.17.-274 {8.4 compatible formatting of doubles} \
+    {expr 1e-274} \
+    9.9999999999999997e-275
+test util-16.1.17.-273 {8.4 compatible formatting of doubles} \
+    {expr 1e-273} \
+    1.0000000000000001e-273
+test util-16.1.17.-272 {8.4 compatible formatting of doubles} \
+    {expr 1e-272} \
+    9.9999999999999993e-273
+test util-16.1.17.-271 {8.4 compatible formatting of doubles} \
+    {expr 1e-271} \
+    9.9999999999999996e-272
+test util-16.1.17.-270 {8.4 compatible formatting of doubles} \
+    {expr 1e-270} \
+    1e-270
+test util-16.1.17.-269 {8.4 compatible formatting of doubles} \
+    {expr 1e-269} \
+    9.9999999999999996e-270
+test util-16.1.17.-268 {8.4 compatible formatting of doubles} \
+    {expr 1e-268} \
+    9.9999999999999996e-269
+test util-16.1.17.-267 {8.4 compatible formatting of doubles} \
+    {expr 1e-267} \
+    9.9999999999999998e-268
+test util-16.1.17.-266 {8.4 compatible formatting of doubles} \
+    {expr 1e-266} \
+    9.9999999999999998e-267
+test util-16.1.17.-265 {8.4 compatible formatting of doubles} \
+    {expr 1e-265} \
+    9.9999999999999998e-266
+test util-16.1.17.-264 {8.4 compatible formatting of doubles} \
+    {expr 1e-264} \
+    1e-264
+test util-16.1.17.-263 {8.4 compatible formatting of doubles} \
+    {expr 1e-263} \
+    1e-263
+test util-16.1.17.-262 {8.4 compatible formatting of doubles} \
+    {expr 1e-262} \
+    1e-262
+test util-16.1.17.-261 {8.4 compatible formatting of doubles} \
+    {expr 1e-261} \
+    9.9999999999999998e-262
+test util-16.1.17.-260 {8.4 compatible formatting of doubles} \
+    {expr 1e-260} \
+    9.9999999999999996e-261
+test util-16.1.17.-259 {8.4 compatible formatting of doubles} \
+    {expr 1e-259} \
+    1.0000000000000001e-259
+test util-16.1.17.-258 {8.4 compatible formatting of doubles} \
+    {expr 1e-258} \
+    9.9999999999999995e-259
+test util-16.1.17.-257 {8.4 compatible formatting of doubles} \
+    {expr 1e-257} \
+    9.9999999999999998e-258
+test util-16.1.17.-256 {8.4 compatible formatting of doubles} \
+    {expr 1e-256} \
+    9.9999999999999998e-257
+test util-16.1.17.-255 {8.4 compatible formatting of doubles} \
+    {expr 1e-255} \
+    1e-255
+test util-16.1.17.-254 {8.4 compatible formatting of doubles} \
+    {expr 1e-254} \
+    9.9999999999999991e-255
+test util-16.1.17.-253 {8.4 compatible formatting of doubles} \
+    {expr 1e-253} \
+    1.0000000000000001e-253
+test util-16.1.17.-252 {8.4 compatible formatting of doubles} \
+    {expr 1e-252} \
+    9.9999999999999994e-253
+test util-16.1.17.-251 {8.4 compatible formatting of doubles} \
+    {expr 1e-251} \
+    1e-251
+test util-16.1.17.-250 {8.4 compatible formatting of doubles} \
+    {expr 1e-250} \
+    1.0000000000000001e-250
+test util-16.1.17.-249 {8.4 compatible formatting of doubles} \
+    {expr 1e-249} \
+    1.0000000000000001e-249
+test util-16.1.17.-248 {8.4 compatible formatting of doubles} \
+    {expr 1e-248} \
+    9.9999999999999998e-249
+test util-16.1.17.-247 {8.4 compatible formatting of doubles} \
+    {expr 1e-247} \
+    1e-247
+test util-16.1.17.-246 {8.4 compatible formatting of doubles} \
+    {expr 1e-246} \
+    9.9999999999999996e-247
+test util-16.1.17.-245 {8.4 compatible formatting of doubles} \
+    {expr 1e-245} \
+    9.9999999999999993e-246
+test util-16.1.17.-244 {8.4 compatible formatting of doubles} \
+    {expr 1e-244} \
+    9.9999999999999993e-245
+test util-16.1.17.-243 {8.4 compatible formatting of doubles} \
+    {expr 1e-243} \
+    1e-243
+test util-16.1.17.-242 {8.4 compatible formatting of doubles} \
+    {expr 1e-242} \
+    9.9999999999999997e-243
+test util-16.1.17.-241 {8.4 compatible formatting of doubles} \
+    {expr 1e-241} \
+    9.9999999999999997e-242
+test util-16.1.17.-240 {8.4 compatible formatting of doubles} \
+    {expr 1e-240} \
+    9.9999999999999997e-241
+test util-16.1.17.-239 {8.4 compatible formatting of doubles} \
+    {expr 1e-239} \
+    1.0000000000000001e-239
+test util-16.1.17.-238 {8.4 compatible formatting of doubles} \
+    {expr 1e-238} \
+    9.9999999999999999e-239
+test util-16.1.17.-237 {8.4 compatible formatting of doubles} \
+    {expr 1e-237} \
+    9.9999999999999999e-238
+test util-16.1.17.-236 {8.4 compatible formatting of doubles} \
+    {expr 1e-236} \
+    1e-236
+test util-16.1.17.-235 {8.4 compatible formatting of doubles} \
+    {expr 1e-235} \
+    9.9999999999999996e-236
+test util-16.1.17.-234 {8.4 compatible formatting of doubles} \
+    {expr 1e-234} \
+    9.9999999999999996e-235
+test util-16.1.17.-233 {8.4 compatible formatting of doubles} \
+    {expr 1e-233} \
+    9.9999999999999996e-234
+test util-16.1.17.-232 {8.4 compatible formatting of doubles} \
+    {expr 1e-232} \
+    1e-232
+test util-16.1.17.-231 {8.4 compatible formatting of doubles} \
+    {expr 1e-231} \
+    9.9999999999999999e-232
+test util-16.1.17.-230 {8.4 compatible formatting of doubles} \
+    {expr 1e-230} \
+    1e-230
+test util-16.1.17.-229 {8.4 compatible formatting of doubles} \
+    {expr 1e-229} \
+    1.0000000000000001e-229
+test util-16.1.17.-228 {8.4 compatible formatting of doubles} \
+    {expr 1e-228} \
+    1e-228
+test util-16.1.17.-227 {8.4 compatible formatting of doubles} \
+    {expr 1e-227} \
+    9.9999999999999994e-228
+test util-16.1.17.-226 {8.4 compatible formatting of doubles} \
+    {expr 1e-226} \
+    9.9999999999999992e-227
+test util-16.1.17.-225 {8.4 compatible formatting of doubles} \
+    {expr 1e-225} \
+    9.9999999999999996e-226
+test util-16.1.17.-224 {8.4 compatible formatting of doubles} \
+    {expr 1e-224} \
+    1e-224
+test util-16.1.17.-223 {8.4 compatible formatting of doubles} \
+    {expr 1e-223} \
+    9.9999999999999997e-224
+test util-16.1.17.-222 {8.4 compatible formatting of doubles} \
+    {expr 1e-222} \
+    1e-222
+test util-16.1.17.-221 {8.4 compatible formatting of doubles} \
+    {expr 1e-221} \
+    1e-221
+test util-16.1.17.-220 {8.4 compatible formatting of doubles} \
+    {expr 1e-220} \
+    9.9999999999999999e-221
+test util-16.1.17.-219 {8.4 compatible formatting of doubles} \
+    {expr 1e-219} \
+    1e-219
+test util-16.1.17.-218 {8.4 compatible formatting of doubles} \
+    {expr 1e-218} \
+    1e-218
+test util-16.1.17.-217 {8.4 compatible formatting of doubles} \
+    {expr 1e-217} \
+    1.0000000000000001e-217
+test util-16.1.17.-216 {8.4 compatible formatting of doubles} \
+    {expr 1e-216} \
+    1e-216
+test util-16.1.17.-215 {8.4 compatible formatting of doubles} \
+    {expr 1e-215} \
+    1e-215
+test util-16.1.17.-214 {8.4 compatible formatting of doubles} \
+    {expr 1e-214} \
+    9.9999999999999991e-215
+test util-16.1.17.-213 {8.4 compatible formatting of doubles} \
+    {expr 1e-213} \
+    9.9999999999999995e-214
+test util-16.1.17.-212 {8.4 compatible formatting of doubles} \
+    {expr 1e-212} \
+    9.9999999999999995e-213
+test util-16.1.17.-211 {8.4 compatible formatting of doubles} \
+    {expr 1e-211} \
+    1.0000000000000001e-211
+test util-16.1.17.-210 {8.4 compatible formatting of doubles} \
+    {expr 1e-210} \
+    1e-210
+test util-16.1.17.-209 {8.4 compatible formatting of doubles} \
+    {expr 1e-209} \
+    1e-209
+test util-16.1.17.-208 {8.4 compatible formatting of doubles} \
+    {expr 1e-208} \
+    1.0000000000000001e-208
+test util-16.1.17.-207 {8.4 compatible formatting of doubles} \
+    {expr 1e-207} \
+    9.9999999999999993e-208
+test util-16.1.17.-206 {8.4 compatible formatting of doubles} \
+    {expr 1e-206} \
+    1e-206
+test util-16.1.17.-205 {8.4 compatible formatting of doubles} \
+    {expr 1e-205} \
+    1e-205
+test util-16.1.17.-204 {8.4 compatible formatting of doubles} \
+    {expr 1e-204} \
+    1e-204
+test util-16.1.17.-203 {8.4 compatible formatting of doubles} \
+    {expr 1e-203} \
+    1e-203
+test util-16.1.17.-202 {8.4 compatible formatting of doubles} \
+    {expr 1e-202} \
+    1e-202
+test util-16.1.17.-201 {8.4 compatible formatting of doubles} \
+    {expr 1e-201} \
+    9.9999999999999995e-202
+test util-16.1.17.-200 {8.4 compatible formatting of doubles} \
+    {expr 1e-200} \
+    9.9999999999999998e-201
+test util-16.1.17.-199 {8.4 compatible formatting of doubles} \
+    {expr 1e-199} \
+    9.9999999999999998e-200
+test util-16.1.17.-198 {8.4 compatible formatting of doubles} \
+    {expr 1e-198} \
+    9.9999999999999991e-199
+test util-16.1.17.-197 {8.4 compatible formatting of doubles} \
+    {expr 1e-197} \
+    9.9999999999999999e-198
+test util-16.1.17.-196 {8.4 compatible formatting of doubles} \
+    {expr 1e-196} \
+    1e-196
+test util-16.1.17.-195 {8.4 compatible formatting of doubles} \
+    {expr 1e-195} \
+    1.0000000000000001e-195
+test util-16.1.17.-194 {8.4 compatible formatting of doubles} \
+    {expr 1e-194} \
+    1e-194
+test util-16.1.17.-193 {8.4 compatible formatting of doubles} \
+    {expr 1e-193} \
+    1e-193
+test util-16.1.17.-192 {8.4 compatible formatting of doubles} \
+    {expr 1e-192} \
+    1.0000000000000001e-192
+test util-16.1.17.-191 {8.4 compatible formatting of doubles} \
+    {expr 1e-191} \
+    1e-191
+test util-16.1.17.-190 {8.4 compatible formatting of doubles} \
+    {expr 1e-190} \
+    1e-190
+test util-16.1.17.-189 {8.4 compatible formatting of doubles} \
+    {expr 1e-189} \
+    1.0000000000000001e-189
+test util-16.1.17.-188 {8.4 compatible formatting of doubles} \
+    {expr 1e-188} \
+    9.9999999999999995e-189
+test util-16.1.17.-187 {8.4 compatible formatting of doubles} \
+    {expr 1e-187} \
+    1e-187
+test util-16.1.17.-186 {8.4 compatible formatting of doubles} \
+    {expr 1e-186} \
+    9.9999999999999991e-187
+test util-16.1.17.-185 {8.4 compatible formatting of doubles} \
+    {expr 1e-185} \
+    9.9999999999999999e-186
+test util-16.1.17.-184 {8.4 compatible formatting of doubles} \
+    {expr 1e-184} \
+    1.0000000000000001e-184
+test util-16.1.17.-183 {8.4 compatible formatting of doubles} \
+    {expr 1e-183} \
+    1e-183
+test util-16.1.17.-182 {8.4 compatible formatting of doubles} \
+    {expr 1e-182} \
+    1e-182
+test util-16.1.17.-181 {8.4 compatible formatting of doubles} \
+    {expr 1e-181} \
+    1e-181
+test util-16.1.17.-180 {8.4 compatible formatting of doubles} \
+    {expr 1e-180} \
+    1e-180
+test util-16.1.17.-179 {8.4 compatible formatting of doubles} \
+    {expr 1e-179} \
+    1e-179
+test util-16.1.17.-178 {8.4 compatible formatting of doubles} \
+    {expr 1e-178} \
+    9.9999999999999995e-179
+test util-16.1.17.-177 {8.4 compatible formatting of doubles} \
+    {expr 1e-177} \
+    9.9999999999999995e-178
+test util-16.1.17.-176 {8.4 compatible formatting of doubles} \
+    {expr 1e-176} \
+    1e-176
+test util-16.1.17.-175 {8.4 compatible formatting of doubles} \
+    {expr 1e-175} \
+    1e-175
+test util-16.1.17.-174 {8.4 compatible formatting of doubles} \
+    {expr 1e-174} \
+    1e-174
+test util-16.1.17.-173 {8.4 compatible formatting of doubles} \
+    {expr 1e-173} \
+    1e-173
+test util-16.1.17.-172 {8.4 compatible formatting of doubles} \
+    {expr 1e-172} \
+    1e-172
+test util-16.1.17.-171 {8.4 compatible formatting of doubles} \
+    {expr 1e-171} \
+    9.9999999999999998e-172
+test util-16.1.17.-170 {8.4 compatible formatting of doubles} \
+    {expr 1e-170} \
+    9.9999999999999998e-171
+test util-16.1.17.-169 {8.4 compatible formatting of doubles} \
+    {expr 1e-169} \
+    1e-169
+test util-16.1.17.-168 {8.4 compatible formatting of doubles} \
+    {expr 1e-168} \
+    1e-168
+test util-16.1.17.-167 {8.4 compatible formatting of doubles} \
+    {expr 1e-167} \
+    1e-167
+test util-16.1.17.-166 {8.4 compatible formatting of doubles} \
+    {expr 1e-166} \
+    1e-166
+test util-16.1.17.-165 {8.4 compatible formatting of doubles} \
+    {expr 1e-165} \
+    1e-165
+test util-16.1.17.-164 {8.4 compatible formatting of doubles} \
+    {expr 1e-164} \
+    9.9999999999999996e-165
+test util-16.1.17.-163 {8.4 compatible formatting of doubles} \
+    {expr 1e-163} \
+    9.9999999999999992e-164
+test util-16.1.17.-162 {8.4 compatible formatting of doubles} \
+    {expr 1e-162} \
+    9.9999999999999995e-163
+test util-16.1.17.-161 {8.4 compatible formatting of doubles} \
+    {expr 1e-161} \
+    1e-161
+test util-16.1.17.-160 {8.4 compatible formatting of doubles} \
+    {expr 1e-160} \
+    9.9999999999999999e-161
+test util-16.1.17.-159 {8.4 compatible formatting of doubles} \
+    {expr 1e-159} \
+    9.9999999999999999e-160
+test util-16.1.17.-158 {8.4 compatible formatting of doubles} \
+    {expr 1e-158} \
+    1.0000000000000001e-158
+test util-16.1.17.-157 {8.4 compatible formatting of doubles} \
+    {expr 1e-157} \
+    9.9999999999999994e-158
+test util-16.1.17.-156 {8.4 compatible formatting of doubles} \
+    {expr 1e-156} \
+    1e-156
+test util-16.1.17.-155 {8.4 compatible formatting of doubles} \
+    {expr 1e-155} \
+    1e-155
+test util-16.1.17.-154 {8.4 compatible formatting of doubles} \
+    {expr 1e-154} \
+    9.9999999999999997e-155
+test util-16.1.17.-153 {8.4 compatible formatting of doubles} \
+    {expr 1e-153} \
+    1e-153
+test util-16.1.17.-152 {8.4 compatible formatting of doubles} \
+    {expr 1e-152} \
+    1.0000000000000001e-152
+test util-16.1.17.-151 {8.4 compatible formatting of doubles} \
+    {expr 1e-151} \
+    9.9999999999999994e-152
+test util-16.1.17.-150 {8.4 compatible formatting of doubles} \
+    {expr 1e-150} \
+    1e-150
+test util-16.1.17.-149 {8.4 compatible formatting of doubles} \
+    {expr 1e-149} \
+    9.9999999999999998e-150
+test util-16.1.17.-148 {8.4 compatible formatting of doubles} \
+    {expr 1e-148} \
+    9.9999999999999994e-149
+test util-16.1.17.-147 {8.4 compatible formatting of doubles} \
+    {expr 1e-147} \
+    9.9999999999999997e-148
+test util-16.1.17.-146 {8.4 compatible formatting of doubles} \
+    {expr 1e-146} \
+    1e-146
+test util-16.1.17.-145 {8.4 compatible formatting of doubles} \
+    {expr 1e-145} \
+    9.9999999999999991e-146
+test util-16.1.17.-144 {8.4 compatible formatting of doubles} \
+    {expr 1e-144} \
+    9.9999999999999995e-145
+test util-16.1.17.-143 {8.4 compatible formatting of doubles} \
+    {expr 1e-143} \
+    9.9999999999999995e-144
+test util-16.1.17.-142 {8.4 compatible formatting of doubles} \
+    {expr 1e-142} \
+    1e-142
+test util-16.1.17.-141 {8.4 compatible formatting of doubles} \
+    {expr 1e-141} \
+    1e-141
+test util-16.1.17.-140 {8.4 compatible formatting of doubles} \
+    {expr 1e-140} \
+    9.9999999999999998e-141
+test util-16.1.17.-139 {8.4 compatible formatting of doubles} \
+    {expr 1e-139} \
+    1e-139
+test util-16.1.17.-138 {8.4 compatible formatting of doubles} \
+    {expr 1e-138} \
+    1.0000000000000001e-138
+test util-16.1.17.-137 {8.4 compatible formatting of doubles} \
+    {expr 1e-137} \
+    9.9999999999999998e-138
+test util-16.1.17.-136 {8.4 compatible formatting of doubles} \
+    {expr 1e-136} \
+    1e-136
+test util-16.1.17.-135 {8.4 compatible formatting of doubles} \
+    {expr 1e-135} \
+    1e-135
+test util-16.1.17.-134 {8.4 compatible formatting of doubles} \
+    {expr 1e-134} \
+    1e-134
+test util-16.1.17.-133 {8.4 compatible formatting of doubles} \
+    {expr 1e-133} \
+    1.0000000000000001e-133
+test util-16.1.17.-132 {8.4 compatible formatting of doubles} \
+    {expr 1e-132} \
+    9.9999999999999999e-133
+test util-16.1.17.-131 {8.4 compatible formatting of doubles} \
+    {expr 1e-131} \
+    9.9999999999999999e-132
+test util-16.1.17.-130 {8.4 compatible formatting of doubles} \
+    {expr 1e-130} \
+    1.0000000000000001e-130
+test util-16.1.17.-129 {8.4 compatible formatting of doubles} \
+    {expr 1e-129} \
+    9.9999999999999993e-130
+test util-16.1.17.-128 {8.4 compatible formatting of doubles} \
+    {expr 1e-128} \
+    1.0000000000000001e-128
+test util-16.1.17.-127 {8.4 compatible formatting of doubles} \
+    {expr 1e-127} \
+    1e-127
+test util-16.1.17.-126 {8.4 compatible formatting of doubles} \
+    {expr 1e-126} \
+    9.9999999999999995e-127
+test util-16.1.17.-125 {8.4 compatible formatting of doubles} \
+    {expr 1e-125} \
+    1e-125
+test util-16.1.17.-124 {8.4 compatible formatting of doubles} \
+    {expr 1e-124} \
+    9.9999999999999993e-125
+test util-16.1.17.-123 {8.4 compatible formatting of doubles} \
+    {expr 1e-123} \
+    1.0000000000000001e-123
+test util-16.1.17.-122 {8.4 compatible formatting of doubles} \
+    {expr 1e-122} \
+    1.0000000000000001e-122
+test util-16.1.17.-121 {8.4 compatible formatting of doubles} \
+    {expr 1e-121} \
+    9.9999999999999998e-122
+test util-16.1.17.-120 {8.4 compatible formatting of doubles} \
+    {expr 1e-120} \
+    9.9999999999999998e-121
+test util-16.1.17.-119 {8.4 compatible formatting of doubles} \
+    {expr 1e-119} \
+    1e-119
+test util-16.1.17.-118 {8.4 compatible formatting of doubles} \
+    {expr 1e-118} \
+    9.9999999999999999e-119
+test util-16.1.17.-117 {8.4 compatible formatting of doubles} \
+    {expr 1e-117} \
+    1e-117
+test util-16.1.17.-116 {8.4 compatible formatting of doubles} \
+    {expr 1e-116} \
+    9.9999999999999999e-117
+test util-16.1.17.-115 {8.4 compatible formatting of doubles} \
+    {expr 1e-115} \
+    1.0000000000000001e-115
+test util-16.1.17.-114 {8.4 compatible formatting of doubles} \
+    {expr 1e-114} \
+    1.0000000000000001e-114
+test util-16.1.17.-113 {8.4 compatible formatting of doubles} \
+    {expr 1e-113} \
+    9.9999999999999998e-114
+test util-16.1.17.-112 {8.4 compatible formatting of doubles} \
+    {expr 1e-112} \
+    9.9999999999999995e-113
+test util-16.1.17.-111 {8.4 compatible formatting of doubles} \
+    {expr 1e-111} \
+    1.0000000000000001e-111
+test util-16.1.17.-110 {8.4 compatible formatting of doubles} \
+    {expr 1e-110} \
+    1.0000000000000001e-110
+test util-16.1.17.-109 {8.4 compatible formatting of doubles} \
+    {expr 1e-109} \
+    9.9999999999999999e-110
+test util-16.1.17.-108 {8.4 compatible formatting of doubles} \
+    {expr 1e-108} \
+    1e-108
+test util-16.1.17.-107 {8.4 compatible formatting of doubles} \
+    {expr 1e-107} \
+    1e-107
+test util-16.1.17.-106 {8.4 compatible formatting of doubles} \
+    {expr 1e-106} \
+    9.9999999999999994e-107
+test util-16.1.17.-105 {8.4 compatible formatting of doubles} \
+    {expr 1e-105} \
+    9.9999999999999997e-106
+test util-16.1.17.-104 {8.4 compatible formatting of doubles} \
+    {expr 1e-104} \
+    9.9999999999999993e-105
+test util-16.1.17.-103 {8.4 compatible formatting of doubles} \
+    {expr 1e-103} \
+    9.9999999999999996e-104
+test util-16.1.17.-102 {8.4 compatible formatting of doubles} \
+    {expr 1e-102} \
+    9.9999999999999993e-103
+test util-16.1.17.-101 {8.4 compatible formatting of doubles} \
+    {expr 1e-101} \
+    1.0000000000000001e-101
+test util-16.1.17.-100 {8.4 compatible formatting of doubles} \
+    {expr 1e-100} \
+    1e-100
+test util-16.1.17.-99 {8.4 compatible formatting of doubles} \
+    {expr 1e-99} \
+    1e-99
+test util-16.1.17.-98 {8.4 compatible formatting of doubles} \
+    {expr 1e-98} \
+    9.9999999999999994e-99
+test util-16.1.17.-97 {8.4 compatible formatting of doubles} \
+    {expr 1e-97} \
+    1e-97
+test util-16.1.17.-96 {8.4 compatible formatting of doubles} \
+    {expr 1e-96} \
+    9.9999999999999991e-97
+test util-16.1.17.-95 {8.4 compatible formatting of doubles} \
+    {expr 1e-95} \
+    9.9999999999999999e-96
+test util-16.1.17.-94 {8.4 compatible formatting of doubles} \
+    {expr 1e-94} \
+    9.9999999999999996e-95
+test util-16.1.17.-93 {8.4 compatible formatting of doubles} \
+    {expr 1e-93} \
+    9.999999999999999e-94
+test util-16.1.17.-92 {8.4 compatible formatting of doubles} \
+    {expr 1e-92} \
+    9.9999999999999999e-93
+test util-16.1.17.-91 {8.4 compatible formatting of doubles} \
+    {expr 1e-91} \
+    1e-91
+test util-16.1.17.-90 {8.4 compatible formatting of doubles} \
+    {expr 1e-90} \
+    9.9999999999999999e-91
+test util-16.1.17.-89 {8.4 compatible formatting of doubles} \
+    {expr 1e-89} \
+    1e-89
+test util-16.1.17.-88 {8.4 compatible formatting of doubles} \
+    {expr 1e-88} \
+    9.9999999999999993e-89
+test util-16.1.17.-87 {8.4 compatible formatting of doubles} \
+    {expr 1e-87} \
+    1e-87
+test util-16.1.17.-86 {8.4 compatible formatting of doubles} \
+    {expr 1e-86} \
+    1.0000000000000001e-86
+test util-16.1.17.-85 {8.4 compatible formatting of doubles} \
+    {expr 1e-85} \
+    9.9999999999999998e-86
+test util-16.1.17.-84 {8.4 compatible formatting of doubles} \
+    {expr 1e-84} \
+    1e-84
+test util-16.1.17.-83 {8.4 compatible formatting of doubles} \
+    {expr 1e-83} \
+    1e-83
+test util-16.1.17.-82 {8.4 compatible formatting of doubles} \
+    {expr 1e-82} \
+    9.9999999999999996e-83
+test util-16.1.17.-81 {8.4 compatible formatting of doubles} \
+    {expr 1e-81} \
+    9.9999999999999996e-82
+test util-16.1.17.-80 {8.4 compatible formatting of doubles} \
+    {expr 1e-80} \
+    9.9999999999999996e-81
+test util-16.1.17.-79 {8.4 compatible formatting of doubles} \
+    {expr 1e-79} \
+    1e-79
+test util-16.1.17.-78 {8.4 compatible formatting of doubles} \
+    {expr 1e-78} \
+    1e-78
+test util-16.1.17.-77 {8.4 compatible formatting of doubles} \
+    {expr 1e-77} \
+    9.9999999999999993e-78
+test util-16.1.17.-76 {8.4 compatible formatting of doubles} \
+    {expr 1e-76} \
+    9.9999999999999993e-77
+test util-16.1.17.-75 {8.4 compatible formatting of doubles} \
+    {expr 1e-75} \
+    9.9999999999999996e-76
+test util-16.1.17.-74 {8.4 compatible formatting of doubles} \
+    {expr 1e-74} \
+    9.9999999999999996e-75
+test util-16.1.17.-73 {8.4 compatible formatting of doubles} \
+    {expr 1e-73} \
+    1e-73
+test util-16.1.17.-72 {8.4 compatible formatting of doubles} \
+    {expr 1e-72} \
+    9.9999999999999997e-73
+test util-16.1.17.-71 {8.4 compatible formatting of doubles} \
+    {expr 1e-71} \
+    9.9999999999999992e-72
+test util-16.1.17.-70 {8.4 compatible formatting of doubles} \
+    {expr 1e-70} \
+    1e-70
+test util-16.1.17.-69 {8.4 compatible formatting of doubles} \
+    {expr 1e-69} \
+    9.9999999999999996e-70
+test util-16.1.17.-68 {8.4 compatible formatting of doubles} \
+    {expr 1e-68} \
+    1.0000000000000001e-68
+test util-16.1.17.-67 {8.4 compatible formatting of doubles} \
+    {expr 1e-67} \
+    9.9999999999999994e-68
+test util-16.1.17.-66 {8.4 compatible formatting of doubles} \
+    {expr 1e-66} \
+    9.9999999999999998e-67
+test util-16.1.17.-65 {8.4 compatible formatting of doubles} \
+    {expr 1e-65} \
+    9.9999999999999992e-66
+test util-16.1.17.-64 {8.4 compatible formatting of doubles} \
+    {expr 1e-64} \
+    9.9999999999999997e-65
+test util-16.1.17.-63 {8.4 compatible formatting of doubles} \
+    {expr 1e-63} \
+    1.0000000000000001e-63
+test util-16.1.17.-62 {8.4 compatible formatting of doubles} \
+    {expr 1e-62} \
+    1e-62
+test util-16.1.17.-61 {8.4 compatible formatting of doubles} \
+    {expr 1e-61} \
+    1e-61
+test util-16.1.17.-60 {8.4 compatible formatting of doubles} \
+    {expr 1e-60} \
+    9.9999999999999997e-61
+test util-16.1.17.-59 {8.4 compatible formatting of doubles} \
+    {expr 1e-59} \
+    1e-59
+test util-16.1.17.-58 {8.4 compatible formatting of doubles} \
+    {expr 1e-58} \
+    1e-58
+test util-16.1.17.-57 {8.4 compatible formatting of doubles} \
+    {expr 1e-57} \
+    9.9999999999999995e-58
+test util-16.1.17.-56 {8.4 compatible formatting of doubles} \
+    {expr 1e-56} \
+    1e-56
+test util-16.1.17.-55 {8.4 compatible formatting of doubles} \
+    {expr 1e-55} \
+    9.9999999999999999e-56
+test util-16.1.17.-54 {8.4 compatible formatting of doubles} \
+    {expr 1e-54} \
+    1e-54
+test util-16.1.17.-53 {8.4 compatible formatting of doubles} \
+    {expr 1e-53} \
+    1e-53
+test util-16.1.17.-52 {8.4 compatible formatting of doubles} \
+    {expr 1e-52} \
+    1e-52
+test util-16.1.17.-51 {8.4 compatible formatting of doubles} \
+    {expr 1e-51} \
+    1e-51
+test util-16.1.17.-50 {8.4 compatible formatting of doubles} \
+    {expr 1e-50} \
+    1e-50
+test util-16.1.17.-49 {8.4 compatible formatting of doubles} \
+    {expr 1e-49} \
+    9.9999999999999994e-50
+test util-16.1.17.-48 {8.4 compatible formatting of doubles} \
+    {expr 1e-48} \
+    9.9999999999999997e-49
+test util-16.1.17.-47 {8.4 compatible formatting of doubles} \
+    {expr 1e-47} \
+    9.9999999999999997e-48
+test util-16.1.17.-46 {8.4 compatible formatting of doubles} \
+    {expr 1e-46} \
+    1e-46
+test util-16.1.17.-45 {8.4 compatible formatting of doubles} \
+    {expr 1e-45} \
+    9.9999999999999998e-46
+test util-16.1.17.-44 {8.4 compatible formatting of doubles} \
+    {expr 1e-44} \
+    9.9999999999999995e-45
+test util-16.1.17.-43 {8.4 compatible formatting of doubles} \
+    {expr 1e-43} \
+    1.0000000000000001e-43
+test util-16.1.17.-42 {8.4 compatible formatting of doubles} \
+    {expr 1e-42} \
+    1e-42
+test util-16.1.17.-41 {8.4 compatible formatting of doubles} \
+    {expr 1e-41} \
+    1e-41
+test util-16.1.17.-40 {8.4 compatible formatting of doubles} \
+    {expr 1e-40} \
+    9.9999999999999993e-41
+test util-16.1.17.-39 {8.4 compatible formatting of doubles} \
+    {expr 1e-39} \
+    9.9999999999999993e-40
+test util-16.1.17.-38 {8.4 compatible formatting of doubles} \
+    {expr 1e-38} \
+    9.9999999999999996e-39
+test util-16.1.17.-37 {8.4 compatible formatting of doubles} \
+    {expr 1e-37} \
+    1.0000000000000001e-37
+test util-16.1.17.-36 {8.4 compatible formatting of doubles} \
+    {expr 1e-36} \
+    9.9999999999999994e-37
+test util-16.1.17.-35 {8.4 compatible formatting of doubles} \
+    {expr 1e-35} \
+    1e-35
+test util-16.1.17.-34 {8.4 compatible formatting of doubles} \
+    {expr 1e-34} \
+    9.9999999999999993e-35
+test util-16.1.17.-33 {8.4 compatible formatting of doubles} \
+    {expr 1e-33} \
+    1.0000000000000001e-33
+test util-16.1.17.-32 {8.4 compatible formatting of doubles} \
+    {expr 1e-32} \
+    1.0000000000000001e-32
+test util-16.1.17.-31 {8.4 compatible formatting of doubles} \
+    {expr 1e-31} \
+    1.0000000000000001e-31
+test util-16.1.17.-30 {8.4 compatible formatting of doubles} \
+    {expr 1e-30} \
+    1.0000000000000001e-30
+test util-16.1.17.-29 {8.4 compatible formatting of doubles} \
+    {expr 1e-29} \
+    9.9999999999999994e-30
+test util-16.1.17.-28 {8.4 compatible formatting of doubles} \
+    {expr 1e-28} \
+    9.9999999999999997e-29
+test util-16.1.17.-27 {8.4 compatible formatting of doubles} \
+    {expr 1e-27} \
+    1e-27
+test util-16.1.17.-26 {8.4 compatible formatting of doubles} \
+    {expr 1e-26} \
+    1e-26
+test util-16.1.17.-25 {8.4 compatible formatting of doubles} \
+    {expr 1e-25} \
+    1e-25
+test util-16.1.17.-24 {8.4 compatible formatting of doubles} \
+    {expr 1e-24} \
+    9.9999999999999992e-25
+test util-16.1.17.-23 {8.4 compatible formatting of doubles} \
+    {expr 1e-23} \
+    9.9999999999999996e-24
+test util-16.1.17.-22 {8.4 compatible formatting of doubles} \
+    {expr 1e-22} \
+    1e-22
+test util-16.1.17.-21 {8.4 compatible formatting of doubles} \
+    {expr 1e-21} \
+    9.9999999999999991e-22
+test util-16.1.17.-20 {8.4 compatible formatting of doubles} \
+    {expr 1e-20} \
+    9.9999999999999995e-21
+test util-16.1.17.-19 {8.4 compatible formatting of doubles} \
+    {expr 1e-19} \
+    9.9999999999999998e-20
+test util-16.1.17.-18 {8.4 compatible formatting of doubles} \
+    {expr 1e-18} \
+    1.0000000000000001e-18
+test util-16.1.17.-17 {8.4 compatible formatting of doubles} \
+    {expr 1e-17} \
+    1.0000000000000001e-17
+test util-16.1.17.-16 {8.4 compatible formatting of doubles} \
+    {expr 1e-16} \
+    9.9999999999999998e-17
+test util-16.1.17.-15 {8.4 compatible formatting of doubles} \
+    {expr 1e-15} \
+    1.0000000000000001e-15
+test util-16.1.17.-14 {8.4 compatible formatting of doubles} \
+    {expr 1e-14} \
+    1e-14
+test util-16.1.17.-13 {8.4 compatible formatting of doubles} \
+    {expr 1e-13} \
+    1e-13
+test util-16.1.17.-12 {8.4 compatible formatting of doubles} \
+    {expr 1e-12} \
+    9.9999999999999998e-13
+test util-16.1.17.-11 {8.4 compatible formatting of doubles} \
+    {expr 1e-11} \
+    9.9999999999999994e-12
+test util-16.1.17.-10 {8.4 compatible formatting of doubles} \
+    {expr 1e-10} \
+    1e-10
+test util-16.1.17.-9 {8.4 compatible formatting of doubles} \
+    {expr 1e-9} \
+    1.0000000000000001e-09
+test util-16.1.17.-8 {8.4 compatible formatting of doubles} \
+    {expr 1e-8} \
+    1e-08
+test util-16.1.17.-7 {8.4 compatible formatting of doubles} \
+    {expr 1e-7} \
+    9.9999999999999995e-08
+test util-16.1.17.-6 {8.4 compatible formatting of doubles} \
+    {expr 1e-6} \
+    9.9999999999999995e-07
+test util-16.1.17.-5 {8.4 compatible formatting of doubles} \
+    {expr 1e-5} \
+    1.0000000000000001e-05
+test util-16.1.17.-4 {8.4 compatible formatting of doubles} \
+    {expr 1e-4} \
+    0.0001
+test util-16.1.17.-3 {8.4 compatible formatting of doubles} \
+    {expr 1e-3} \
+    0.001
+test util-16.1.17.-2 {8.4 compatible formatting of doubles} \
+    {expr 1e-2} \
+    0.01
+test util-16.1.17.-1 {8.4 compatible formatting of doubles} \
+    {expr 1e-1} \
+    0.10000000000000001
+test util-16.1.17.0 {8.4 compatible formatting of doubles} \
+    {expr 1e0} \
+    1.0
+test util-16.1.17.1 {8.4 compatible formatting of doubles} \
+    {expr 1e1} \
+    10.0
+test util-16.1.17.2 {8.4 compatible formatting of doubles} \
+    {expr 1e2} \
+    100.0
+test util-16.1.17.3 {8.4 compatible formatting of doubles} \
+    {expr 1e3} \
+    1000.0
+test util-16.1.17.4 {8.4 compatible formatting of doubles} \
+    {expr 1e4} \
+    10000.0
+test util-16.1.17.5 {8.4 compatible formatting of doubles} \
+    {expr 1e5} \
+    100000.0
+test util-16.1.17.6 {8.4 compatible formatting of doubles} \
+    {expr 1e6} \
+    1000000.0
+test util-16.1.17.7 {8.4 compatible formatting of doubles} \
+    {expr 1e7} \
+    10000000.0
+test util-16.1.17.8 {8.4 compatible formatting of doubles} \
+    {expr 1e8} \
+    100000000.0
+test util-16.1.17.9 {8.4 compatible formatting of doubles} \
+    {expr 1e9} \
+    1000000000.0
+test util-16.1.17.10 {8.4 compatible formatting of doubles} \
+    {expr 1e10} \
+    10000000000.0
+test util-16.1.17.11 {8.4 compatible formatting of doubles} \
+    {expr 1e11} \
+    100000000000.0
+test util-16.1.17.12 {8.4 compatible formatting of doubles} \
+    {expr 1e12} \
+    1000000000000.0
+test util-16.1.17.13 {8.4 compatible formatting of doubles} \
+    {expr 1e13} \
+    10000000000000.0
+test util-16.1.17.14 {8.4 compatible formatting of doubles} \
+    {expr 1e14} \
+    100000000000000.0
+test util-16.1.17.15 {8.4 compatible formatting of doubles} \
+    {expr 1e15} \
+    1000000000000000.0
+test util-16.1.17.16 {8.4 compatible formatting of doubles} \
+    {expr 1e16} \
+    10000000000000000.0
+test util-16.1.17.17 {8.4 compatible formatting of doubles} \
+    {expr 1e17} \
+    1e+17
+test util-16.1.17.18 {8.4 compatible formatting of doubles} \
+    {expr 1e18} \
+    1e+18
+test util-16.1.17.19 {8.4 compatible formatting of doubles} \
+    {expr 1e19} \
+    1e+19
+test util-16.1.17.20 {8.4 compatible formatting of doubles} \
+    {expr 1e20} \
+    1e+20
+test util-16.1.17.21 {8.4 compatible formatting of doubles} \
+    {expr 1e21} \
+    1e+21
+test util-16.1.17.22 {8.4 compatible formatting of doubles} \
+    {expr 1e22} \
+    1e+22
+test util-16.1.17.23 {8.4 compatible formatting of doubles} \
+    {expr 1e23} \
+    9.9999999999999992e+22
+test util-16.1.17.24 {8.4 compatible formatting of doubles} \
+    {expr 1e24} \
+    9.9999999999999998e+23
+test util-16.1.17.25 {8.4 compatible formatting of doubles} \
+    {expr 1e25} \
+    1.0000000000000001e+25
+test util-16.1.17.26 {8.4 compatible formatting of doubles} \
+    {expr 1e26} \
+    1e+26
+test util-16.1.17.27 {8.4 compatible formatting of doubles} \
+    {expr 1e27} \
+    1e+27
+test util-16.1.17.28 {8.4 compatible formatting of doubles} \
+    {expr 1e28} \
+    9.9999999999999996e+27
+test util-16.1.17.29 {8.4 compatible formatting of doubles} \
+    {expr 1e29} \
+    9.9999999999999991e+28
+test util-16.1.17.30 {8.4 compatible formatting of doubles} \
+    {expr 1e30} \
+    1e+30
+test util-16.1.17.31 {8.4 compatible formatting of doubles} \
+    {expr 1e31} \
+    9.9999999999999996e+30
+test util-16.1.17.32 {8.4 compatible formatting of doubles} \
+    {expr 1e32} \
+    1.0000000000000001e+32
+test util-16.1.17.33 {8.4 compatible formatting of doubles} \
+    {expr 1e33} \
+    9.9999999999999995e+32
+test util-16.1.17.34 {8.4 compatible formatting of doubles} \
+    {expr 1e34} \
+    9.9999999999999995e+33
+test util-16.1.17.35 {8.4 compatible formatting of doubles} \
+    {expr 1e35} \
+    9.9999999999999997e+34
+test util-16.1.17.36 {8.4 compatible formatting of doubles} \
+    {expr 1e36} \
+    1e+36
+test util-16.1.17.37 {8.4 compatible formatting of doubles} \
+    {expr 1e37} \
+    9.9999999999999995e+36
+test util-16.1.17.38 {8.4 compatible formatting of doubles} \
+    {expr 1e38} \
+    9.9999999999999998e+37
+test util-16.1.17.39 {8.4 compatible formatting of doubles} \
+    {expr 1e39} \
+    9.9999999999999994e+38
+test util-16.1.17.40 {8.4 compatible formatting of doubles} \
+    {expr 1e40} \
+    1e+40
+test util-16.1.17.41 {8.4 compatible formatting of doubles} \
+    {expr 1e41} \
+    1e+41
+test util-16.1.17.42 {8.4 compatible formatting of doubles} \
+    {expr 1e42} \
+    1e+42
+test util-16.1.17.43 {8.4 compatible formatting of doubles} \
+    {expr 1e43} \
+    1e+43
+test util-16.1.17.44 {8.4 compatible formatting of doubles} \
+    {expr 1e44} \
+    1.0000000000000001e+44
+test util-16.1.17.45 {8.4 compatible formatting of doubles} \
+    {expr 1e45} \
+    9.9999999999999993e+44
+test util-16.1.17.46 {8.4 compatible formatting of doubles} \
+    {expr 1e46} \
+    9.9999999999999999e+45
+test util-16.1.17.47 {8.4 compatible formatting of doubles} \
+    {expr 1e47} \
+    1e+47
+test util-16.1.17.48 {8.4 compatible formatting of doubles} \
+    {expr 1e48} \
+    1e+48
+test util-16.1.17.49 {8.4 compatible formatting of doubles} \
+    {expr 1e49} \
+    9.9999999999999995e+48
+test util-16.1.17.50 {8.4 compatible formatting of doubles} \
+    {expr 1e50} \
+    1.0000000000000001e+50
+test util-16.1.17.51 {8.4 compatible formatting of doubles} \
+    {expr 1e51} \
+    9.9999999999999999e+50
+test util-16.1.17.52 {8.4 compatible formatting of doubles} \
+    {expr 1e52} \
+    9.9999999999999999e+51
+test util-16.1.17.53 {8.4 compatible formatting of doubles} \
+    {expr 1e53} \
+    9.9999999999999999e+52
+test util-16.1.17.54 {8.4 compatible formatting of doubles} \
+    {expr 1e54} \
+    1.0000000000000001e+54
+test util-16.1.17.55 {8.4 compatible formatting of doubles} \
+    {expr 1e55} \
+    1e+55
+test util-16.1.17.56 {8.4 compatible formatting of doubles} \
+    {expr 1e56} \
+    1.0000000000000001e+56
+test util-16.1.17.57 {8.4 compatible formatting of doubles} \
+    {expr 1e57} \
+    1e+57
+test util-16.1.17.58 {8.4 compatible formatting of doubles} \
+    {expr 1e58} \
+    9.9999999999999994e+57
+test util-16.1.17.59 {8.4 compatible formatting of doubles} \
+    {expr 1e59} \
+    9.9999999999999997e+58
+test util-16.1.17.60 {8.4 compatible formatting of doubles} \
+    {expr 1e60} \
+    9.9999999999999995e+59
+test util-16.1.17.61 {8.4 compatible formatting of doubles} \
+    {expr 1e61} \
+    9.9999999999999995e+60
+test util-16.1.17.62 {8.4 compatible formatting of doubles} \
+    {expr 1e62} \
+    1e+62
+test util-16.1.17.63 {8.4 compatible formatting of doubles} \
+    {expr 1e63} \
+    1.0000000000000001e+63
+test util-16.1.17.64 {8.4 compatible formatting of doubles} \
+    {expr 1e64} \
+    1e+64
+test util-16.1.17.65 {8.4 compatible formatting of doubles} \
+    {expr 1e65} \
+    9.9999999999999999e+64
+test util-16.1.17.66 {8.4 compatible formatting of doubles} \
+    {expr 1e66} \
+    9.9999999999999995e+65
+test util-16.1.17.67 {8.4 compatible formatting of doubles} \
+    {expr 1e67} \
+    9.9999999999999998e+66
+test util-16.1.17.68 {8.4 compatible formatting of doubles} \
+    {expr 1e68} \
+    9.9999999999999995e+67
+test util-16.1.17.69 {8.4 compatible formatting of doubles} \
+    {expr 1e69} \
+    1.0000000000000001e+69
+test util-16.1.17.70 {8.4 compatible formatting of doubles} \
+    {expr 1e70} \
+    1.0000000000000001e+70
+test util-16.1.17.71 {8.4 compatible formatting of doubles} \
+    {expr 1e71} \
+    1e+71
+test util-16.1.17.72 {8.4 compatible formatting of doubles} \
+    {expr 1e72} \
+    9.9999999999999994e+71
+test util-16.1.17.73 {8.4 compatible formatting of doubles} \
+    {expr 1e73} \
+    9.9999999999999998e+72
+test util-16.1.17.74 {8.4 compatible formatting of doubles} \
+    {expr 1e74} \
+    9.9999999999999995e+73
+test util-16.1.17.75 {8.4 compatible formatting of doubles} \
+    {expr 1e75} \
+    9.9999999999999993e+74
+test util-16.1.17.76 {8.4 compatible formatting of doubles} \
+    {expr 1e76} \
+    1e+76
+test util-16.1.17.77 {8.4 compatible formatting of doubles} \
+    {expr 1e77} \
+    9.9999999999999998e+76
+test util-16.1.17.78 {8.4 compatible formatting of doubles} \
+    {expr 1e78} \
+    1e+78
+test util-16.1.17.79 {8.4 compatible formatting of doubles} \
+    {expr 1e79} \
+    9.9999999999999997e+78
+test util-16.1.17.80 {8.4 compatible formatting of doubles} \
+    {expr 1e80} \
+    1e+80
+test util-16.1.17.81 {8.4 compatible formatting of doubles} \
+    {expr 1e81} \
+    9.9999999999999992e+80
+test util-16.1.17.82 {8.4 compatible formatting of doubles} \
+    {expr 1e82} \
+    9.9999999999999996e+81
+test util-16.1.17.83 {8.4 compatible formatting of doubles} \
+    {expr 1e83} \
+    1e+83
+test util-16.1.17.84 {8.4 compatible formatting of doubles} \
+    {expr 1e84} \
+    1.0000000000000001e+84
+test util-16.1.17.85 {8.4 compatible formatting of doubles} \
+    {expr 1e85} \
+    1e+85
+test util-16.1.17.86 {8.4 compatible formatting of doubles} \
+    {expr 1e86} \
+    1e+86
+test util-16.1.17.87 {8.4 compatible formatting of doubles} \
+    {expr 1e87} \
+    9.9999999999999996e+86
+test util-16.1.17.88 {8.4 compatible formatting of doubles} \
+    {expr 1e88} \
+    9.9999999999999996e+87
+test util-16.1.17.89 {8.4 compatible formatting of doubles} \
+    {expr 1e89} \
+    9.9999999999999999e+88
+test util-16.1.17.90 {8.4 compatible formatting of doubles} \
+    {expr 1e90} \
+    9.9999999999999997e+89
+test util-16.1.17.91 {8.4 compatible formatting of doubles} \
+    {expr 1e91} \
+    1.0000000000000001e+91
+test util-16.1.17.92 {8.4 compatible formatting of doubles} \
+    {expr 1e92} \
+    1e+92
+test util-16.1.17.93 {8.4 compatible formatting of doubles} \
+    {expr 1e93} \
+    1e+93
+test util-16.1.17.94 {8.4 compatible formatting of doubles} \
+    {expr 1e94} \
+    1e+94
+test util-16.1.17.95 {8.4 compatible formatting of doubles} \
+    {expr 1e95} \
+    1e+95
+test util-16.1.17.96 {8.4 compatible formatting of doubles} \
+    {expr 1e96} \
+    1e+96
+test util-16.1.17.97 {8.4 compatible formatting of doubles} \
+    {expr 1e97} \
+    1.0000000000000001e+97
+test util-16.1.17.98 {8.4 compatible formatting of doubles} \
+    {expr 1e98} \
+    1e+98
+test util-16.1.17.99 {8.4 compatible formatting of doubles} \
+    {expr 1e99} \
+    9.9999999999999997e+98
+test util-16.1.17.100 {8.4 compatible formatting of doubles} \
+    {expr 1e100} \
+    1e+100
+test util-16.1.17.101 {8.4 compatible formatting of doubles} \
+    {expr 1e101} \
+    9.9999999999999998e+100
+test util-16.1.17.102 {8.4 compatible formatting of doubles} \
+    {expr 1e102} \
+    9.9999999999999998e+101
+test util-16.1.17.103 {8.4 compatible formatting of doubles} \
+    {expr 1e103} \
+    1e+103
+test util-16.1.17.104 {8.4 compatible formatting of doubles} \
+    {expr 1e104} \
+    1e+104
+test util-16.1.17.105 {8.4 compatible formatting of doubles} \
+    {expr 1e105} \
+    9.9999999999999994e+104
+test util-16.1.17.106 {8.4 compatible formatting of doubles} \
+    {expr 1e106} \
+    1.0000000000000001e+106
+test util-16.1.17.107 {8.4 compatible formatting of doubles} \
+    {expr 1e107} \
+    9.9999999999999997e+106
+test util-16.1.17.108 {8.4 compatible formatting of doubles} \
+    {expr 1e108} \
+    1e+108
+test util-16.1.17.109 {8.4 compatible formatting of doubles} \
+    {expr 1e109} \
+    9.9999999999999998e+108
+test util-16.1.17.110 {8.4 compatible formatting of doubles} \
+    {expr 1e110} \
+    1e+110
+test util-16.1.17.111 {8.4 compatible formatting of doubles} \
+    {expr 1e111} \
+    9.9999999999999996e+110
+test util-16.1.17.112 {8.4 compatible formatting of doubles} \
+    {expr 1e112} \
+    9.9999999999999993e+111
+test util-16.1.17.113 {8.4 compatible formatting of doubles} \
+    {expr 1e113} \
+    1e+113
+test util-16.1.17.114 {8.4 compatible formatting of doubles} \
+    {expr 1e114} \
+    1e+114
+test util-16.1.17.115 {8.4 compatible formatting of doubles} \
+    {expr 1e115} \
+    1e+115
+test util-16.1.17.116 {8.4 compatible formatting of doubles} \
+    {expr 1e116} \
+    1e+116
+test util-16.1.17.117 {8.4 compatible formatting of doubles} \
+    {expr 1e117} \
+    1.0000000000000001e+117
+test util-16.1.17.118 {8.4 compatible formatting of doubles} \
+    {expr 1e118} \
+    9.9999999999999997e+117
+test util-16.1.17.119 {8.4 compatible formatting of doubles} \
+    {expr 1e119} \
+    9.9999999999999994e+118
+test util-16.1.17.120 {8.4 compatible formatting of doubles} \
+    {expr 1e120} \
+    9.9999999999999998e+119
+test util-16.1.17.121 {8.4 compatible formatting of doubles} \
+    {expr 1e121} \
+    1e+121
+test util-16.1.17.122 {8.4 compatible formatting of doubles} \
+    {expr 1e122} \
+    1e+122
+test util-16.1.17.123 {8.4 compatible formatting of doubles} \
+    {expr 1e123} \
+    9.9999999999999998e+122
+test util-16.1.17.124 {8.4 compatible formatting of doubles} \
+    {expr 1e124} \
+    9.9999999999999995e+123
+test util-16.1.17.125 {8.4 compatible formatting of doubles} \
+    {expr 1e125} \
+    9.9999999999999992e+124
+test util-16.1.17.126 {8.4 compatible formatting of doubles} \
+    {expr 1e126} \
+    9.9999999999999992e+125
+test util-16.1.17.127 {8.4 compatible formatting of doubles} \
+    {expr 1e127} \
+    9.9999999999999995e+126
+test util-16.1.17.128 {8.4 compatible formatting of doubles} \
+    {expr 1e128} \
+    1.0000000000000001e+128
+test util-16.1.17.129 {8.4 compatible formatting of doubles} \
+    {expr 1e129} \
+    1e+129
+test util-16.1.17.130 {8.4 compatible formatting of doubles} \
+    {expr 1e130} \
+    1.0000000000000001e+130
+test util-16.1.17.131 {8.4 compatible formatting of doubles} \
+    {expr 1e131} \
+    9.9999999999999991e+130
+test util-16.1.17.132 {8.4 compatible formatting of doubles} \
+    {expr 1e132} \
+    9.9999999999999999e+131
+test util-16.1.17.133 {8.4 compatible formatting of doubles} \
+    {expr 1e133} \
+    1e+133
+test util-16.1.17.134 {8.4 compatible formatting of doubles} \
+    {expr 1e134} \
+    9.9999999999999992e+133
+test util-16.1.17.135 {8.4 compatible formatting of doubles} \
+    {expr 1e135} \
+    9.9999999999999996e+134
+test util-16.1.17.136 {8.4 compatible formatting of doubles} \
+    {expr 1e136} \
+    1.0000000000000001e+136
+test util-16.1.17.137 {8.4 compatible formatting of doubles} \
+    {expr 1e137} \
+    1e+137
+test util-16.1.17.138 {8.4 compatible formatting of doubles} \
+    {expr 1e138} \
+    1e+138
+test util-16.1.17.139 {8.4 compatible formatting of doubles} \
+    {expr 1e139} \
+    1e+139
+test util-16.1.17.140 {8.4 compatible formatting of doubles} \
+    {expr 1e140} \
+    1.0000000000000001e+140
+test util-16.1.17.141 {8.4 compatible formatting of doubles} \
+    {expr 1e141} \
+    1e+141
+test util-16.1.17.142 {8.4 compatible formatting of doubles} \
+    {expr 1e142} \
+    1.0000000000000001e+142
+test util-16.1.17.143 {8.4 compatible formatting of doubles} \
+    {expr 1e143} \
+    1e+143
+test util-16.1.17.144 {8.4 compatible formatting of doubles} \
+    {expr 1e144} \
+    1e+144
+test util-16.1.17.145 {8.4 compatible formatting of doubles} \
+    {expr 1e145} \
+    9.9999999999999999e+144
+test util-16.1.17.146 {8.4 compatible formatting of doubles} \
+    {expr 1e146} \
+    9.9999999999999993e+145
+test util-16.1.17.147 {8.4 compatible formatting of doubles} \
+    {expr 1e147} \
+    9.9999999999999998e+146
+test util-16.1.17.148 {8.4 compatible formatting of doubles} \
+    {expr 1e148} \
+    1e+148
+test util-16.1.17.149 {8.4 compatible formatting of doubles} \
+    {expr 1e149} \
+    1e+149
+test util-16.1.17.150 {8.4 compatible formatting of doubles} \
+    {expr 1e150} \
+    9.9999999999999998e+149
+test util-16.1.17.151 {8.4 compatible formatting of doubles} \
+    {expr 1e151} \
+    1e+151
+test util-16.1.17.152 {8.4 compatible formatting of doubles} \
+    {expr 1e152} \
+    1e+152
+test util-16.1.17.153 {8.4 compatible formatting of doubles} \
+    {expr 1e153} \
+    1e+153
+test util-16.1.17.154 {8.4 compatible formatting of doubles} \
+    {expr 1e154} \
+    1e+154
+test util-16.1.17.155 {8.4 compatible formatting of doubles} \
+    {expr 1e155} \
+    1e+155
+test util-16.1.17.156 {8.4 compatible formatting of doubles} \
+    {expr 1e156} \
+    9.9999999999999998e+155
+test util-16.1.17.157 {8.4 compatible formatting of doubles} \
+    {expr 1e157} \
+    9.9999999999999998e+156
+test util-16.1.17.158 {8.4 compatible formatting of doubles} \
+    {expr 1e158} \
+    9.9999999999999995e+157
+test util-16.1.17.159 {8.4 compatible formatting of doubles} \
+    {expr 1e159} \
+    9.9999999999999993e+158
+test util-16.1.17.160 {8.4 compatible formatting of doubles} \
+    {expr 1e160} \
+    1e+160
+test util-16.1.17.161 {8.4 compatible formatting of doubles} \
+    {expr 1e161} \
+    1e+161
+test util-16.1.17.162 {8.4 compatible formatting of doubles} \
+    {expr 1e162} \
+    9.9999999999999994e+161
+test util-16.1.17.163 {8.4 compatible formatting of doubles} \
+    {expr 1e163} \
+    9.9999999999999994e+162
+test util-16.1.17.164 {8.4 compatible formatting of doubles} \
+    {expr 1e164} \
+    1e+164
+test util-16.1.17.165 {8.4 compatible formatting of doubles} \
+    {expr 1e165} \
+    9.999999999999999e+164
+test util-16.1.17.166 {8.4 compatible formatting of doubles} \
+    {expr 1e166} \
+    9.9999999999999994e+165
+test util-16.1.17.167 {8.4 compatible formatting of doubles} \
+    {expr 1e167} \
+    1e+167
+test util-16.1.17.168 {8.4 compatible formatting of doubles} \
+    {expr 1e168} \
+    9.9999999999999993e+167
+test util-16.1.17.169 {8.4 compatible formatting of doubles} \
+    {expr 1e169} \
+    9.9999999999999993e+168
+test util-16.1.17.170 {8.4 compatible formatting of doubles} \
+    {expr 1e170} \
+    1e+170
+test util-16.1.17.171 {8.4 compatible formatting of doubles} \
+    {expr 1e171} \
+    9.9999999999999995e+170
+test util-16.1.17.172 {8.4 compatible formatting of doubles} \
+    {expr 1e172} \
+    1.0000000000000001e+172
+test util-16.1.17.173 {8.4 compatible formatting of doubles} \
+    {expr 1e173} \
+    1e+173
+test util-16.1.17.174 {8.4 compatible formatting of doubles} \
+    {expr 1e174} \
+    1.0000000000000001e+174
+test util-16.1.17.175 {8.4 compatible formatting of doubles} \
+    {expr 1e175} \
+    9.9999999999999994e+174
+test util-16.1.17.176 {8.4 compatible formatting of doubles} \
+    {expr 1e176} \
+    1e+176
+test util-16.1.17.177 {8.4 compatible formatting of doubles} \
+    {expr 1e177} \
+    1e+177
+test util-16.1.17.178 {8.4 compatible formatting of doubles} \
+    {expr 1e178} \
+    1.0000000000000001e+178
+test util-16.1.17.179 {8.4 compatible formatting of doubles} \
+    {expr 1e179} \
+    9.9999999999999998e+178
+test util-16.1.17.180 {8.4 compatible formatting of doubles} \
+    {expr 1e180} \
+    1e+180
+test util-16.1.17.181 {8.4 compatible formatting of doubles} \
+    {expr 1e181} \
+    9.9999999999999992e+180
+test util-16.1.17.182 {8.4 compatible formatting of doubles} \
+    {expr 1e182} \
+    1.0000000000000001e+182
+test util-16.1.17.183 {8.4 compatible formatting of doubles} \
+    {expr 1e183} \
+    9.9999999999999995e+182
+test util-16.1.17.184 {8.4 compatible formatting of doubles} \
+    {expr 1e184} \
+    1e+184
+test util-16.1.17.185 {8.4 compatible formatting of doubles} \
+    {expr 1e185} \
+    9.9999999999999998e+184
+test util-16.1.17.186 {8.4 compatible formatting of doubles} \
+    {expr 1e186} \
+    9.9999999999999998e+185
+test util-16.1.17.187 {8.4 compatible formatting of doubles} \
+    {expr 1e187} \
+    9.9999999999999991e+186
+test util-16.1.17.188 {8.4 compatible formatting of doubles} \
+    {expr 1e188} \
+    1e+188
+test util-16.1.17.189 {8.4 compatible formatting of doubles} \
+    {expr 1e189} \
+    1e+189
+test util-16.1.17.190 {8.4 compatible formatting of doubles} \
+    {expr 1e190} \
+    1.0000000000000001e+190
+test util-16.1.17.191 {8.4 compatible formatting of doubles} \
+    {expr 1e191} \
+    1.0000000000000001e+191
+test util-16.1.17.192 {8.4 compatible formatting of doubles} \
+    {expr 1e192} \
+    1e+192
+test util-16.1.17.193 {8.4 compatible formatting of doubles} \
+    {expr 1e193} \
+    1.0000000000000001e+193
+test util-16.1.17.194 {8.4 compatible formatting of doubles} \
+    {expr 1e194} \
+    9.9999999999999994e+193
+test util-16.1.17.195 {8.4 compatible formatting of doubles} \
+    {expr 1e195} \
+    9.9999999999999998e+194
+test util-16.1.17.196 {8.4 compatible formatting of doubles} \
+    {expr 1e196} \
+    9.9999999999999995e+195
+test util-16.1.17.197 {8.4 compatible formatting of doubles} \
+    {expr 1e197} \
+    9.9999999999999995e+196
+test util-16.1.17.198 {8.4 compatible formatting of doubles} \
+    {expr 1e198} \
+    1e+198
+test util-16.1.17.199 {8.4 compatible formatting of doubles} \
+    {expr 1e199} \
+    1.0000000000000001e+199
+test util-16.1.17.200 {8.4 compatible formatting of doubles} \
+    {expr 1e200} \
+    9.9999999999999997e+199
+test util-16.1.17.201 {8.4 compatible formatting of doubles} \
+    {expr 1e201} \
+    1e+201
+test util-16.1.17.202 {8.4 compatible formatting of doubles} \
+    {expr 1e202} \
+    9.999999999999999e+201
+test util-16.1.17.203 {8.4 compatible formatting of doubles} \
+    {expr 1e203} \
+    9.9999999999999999e+202
+test util-16.1.17.204 {8.4 compatible formatting of doubles} \
+    {expr 1e204} \
+    9.9999999999999999e+203
+test util-16.1.17.205 {8.4 compatible formatting of doubles} \
+    {expr 1e205} \
+    1e+205
+test util-16.1.17.206 {8.4 compatible formatting of doubles} \
+    {expr 1e206} \
+    1e+206
+test util-16.1.17.207 {8.4 compatible formatting of doubles} \
+    {expr 1e207} \
+    1e+207
+test util-16.1.17.208 {8.4 compatible formatting of doubles} \
+    {expr 1e208} \
+    9.9999999999999998e+207
+test util-16.1.17.209 {8.4 compatible formatting of doubles} \
+    {expr 1e209} \
+    1.0000000000000001e+209
+test util-16.1.17.210 {8.4 compatible formatting of doubles} \
+    {expr 1e210} \
+    9.9999999999999993e+209
+test util-16.1.17.211 {8.4 compatible formatting of doubles} \
+    {expr 1e211} \
+    9.9999999999999996e+210
+test util-16.1.17.212 {8.4 compatible formatting of doubles} \
+    {expr 1e212} \
+    9.9999999999999991e+211
+test util-16.1.17.213 {8.4 compatible formatting of doubles} \
+    {expr 1e213} \
+    9.9999999999999998e+212
+test util-16.1.17.214 {8.4 compatible formatting of doubles} \
+    {expr 1e214} \
+    9.9999999999999995e+213
+test util-16.1.17.215 {8.4 compatible formatting of doubles} \
+    {expr 1e215} \
+    9.9999999999999991e+214
+test util-16.1.17.216 {8.4 compatible formatting of doubles} \
+    {expr 1e216} \
+    1e+216
+test util-16.1.17.217 {8.4 compatible formatting of doubles} \
+    {expr 1e217} \
+    9.9999999999999996e+216
+test util-16.1.17.218 {8.4 compatible formatting of doubles} \
+    {expr 1e218} \
+    1.0000000000000001e+218
+test util-16.1.17.219 {8.4 compatible formatting of doubles} \
+    {expr 1e219} \
+    9.9999999999999997e+218
+test util-16.1.17.220 {8.4 compatible formatting of doubles} \
+    {expr 1e220} \
+    1e+220
+test util-16.1.17.221 {8.4 compatible formatting of doubles} \
+    {expr 1e221} \
+    1e+221
+test util-16.1.17.222 {8.4 compatible formatting of doubles} \
+    {expr 1e222} \
+    1e+222
+test util-16.1.17.223 {8.4 compatible formatting of doubles} \
+    {expr 1e223} \
+    1e+223
+test util-16.1.17.224 {8.4 compatible formatting of doubles} \
+    {expr 1e224} \
+    9.9999999999999997e+223
+test util-16.1.17.225 {8.4 compatible formatting of doubles} \
+    {expr 1e225} \
+    9.9999999999999993e+224
+test util-16.1.17.226 {8.4 compatible formatting of doubles} \
+    {expr 1e226} \
+    9.9999999999999996e+225
+test util-16.1.17.227 {8.4 compatible formatting of doubles} \
+    {expr 1e227} \
+    1.0000000000000001e+227
+test util-16.1.17.228 {8.4 compatible formatting of doubles} \
+    {expr 1e228} \
+    9.9999999999999992e+227
+test util-16.1.17.229 {8.4 compatible formatting of doubles} \
+    {expr 1e229} \
+    9.9999999999999999e+228
+test util-16.1.17.230 {8.4 compatible formatting of doubles} \
+    {expr 1e230} \
+    1.0000000000000001e+230
+test util-16.1.17.231 {8.4 compatible formatting of doubles} \
+    {expr 1e231} \
+    1.0000000000000001e+231
+test util-16.1.17.232 {8.4 compatible formatting of doubles} \
+    {expr 1e232} \
+    1.0000000000000001e+232
+test util-16.1.17.233 {8.4 compatible formatting of doubles} \
+    {expr 1e233} \
+    9.9999999999999997e+232
+test util-16.1.17.234 {8.4 compatible formatting of doubles} \
+    {expr 1e234} \
+    1e+234
+test util-16.1.17.235 {8.4 compatible formatting of doubles} \
+    {expr 1e235} \
+    1.0000000000000001e+235
+test util-16.1.17.236 {8.4 compatible formatting of doubles} \
+    {expr 1e236} \
+    1.0000000000000001e+236
+test util-16.1.17.237 {8.4 compatible formatting of doubles} \
+    {expr 1e237} \
+    9.9999999999999994e+236
+test util-16.1.17.238 {8.4 compatible formatting of doubles} \
+    {expr 1e238} \
+    1e+238
+test util-16.1.17.239 {8.4 compatible formatting of doubles} \
+    {expr 1e239} \
+    9.9999999999999999e+238
+test util-16.1.17.240 {8.4 compatible formatting of doubles} \
+    {expr 1e240} \
+    1e+240
+test util-16.1.17.241 {8.4 compatible formatting of doubles} \
+    {expr 1e241} \
+    1.0000000000000001e+241
+test util-16.1.17.242 {8.4 compatible formatting of doubles} \
+    {expr 1e242} \
+    1.0000000000000001e+242
+test util-16.1.17.243 {8.4 compatible formatting of doubles} \
+    {expr 1e243} \
+    1.0000000000000001e+243
+test util-16.1.17.244 {8.4 compatible formatting of doubles} \
+    {expr 1e244} \
+    1.0000000000000001e+244
+test util-16.1.17.245 {8.4 compatible formatting of doubles} \
+    {expr 1e245} \
+    1e+245
+test util-16.1.17.246 {8.4 compatible formatting of doubles} \
+    {expr 1e246} \
+    1.0000000000000001e+246
+test util-16.1.17.247 {8.4 compatible formatting of doubles} \
+    {expr 1e247} \
+    9.9999999999999995e+246
+test util-16.1.17.248 {8.4 compatible formatting of doubles} \
+    {expr 1e248} \
+    1e+248
+test util-16.1.17.249 {8.4 compatible formatting of doubles} \
+    {expr 1e249} \
+    9.9999999999999992e+248
+test util-16.1.17.250 {8.4 compatible formatting of doubles} \
+    {expr 1e250} \
+    9.9999999999999992e+249
+test util-16.1.17.251 {8.4 compatible formatting of doubles} \
+    {expr 1e251} \
+    1e+251
+test util-16.1.17.252 {8.4 compatible formatting of doubles} \
+    {expr 1e252} \
+    1.0000000000000001e+252
+test util-16.1.17.253 {8.4 compatible formatting of doubles} \
+    {expr 1e253} \
+    9.9999999999999994e+252
+test util-16.1.17.254 {8.4 compatible formatting of doubles} \
+    {expr 1e254} \
+    9.9999999999999994e+253
+test util-16.1.17.255 {8.4 compatible formatting of doubles} \
+    {expr 1e255} \
+    9.9999999999999999e+254
+test util-16.1.17.256 {8.4 compatible formatting of doubles} \
+    {expr 1e256} \
+    1e+256
+test util-16.1.17.257 {8.4 compatible formatting of doubles} \
+    {expr 1e257} \
+    1e+257
+test util-16.1.17.258 {8.4 compatible formatting of doubles} \
+    {expr 1e258} \
+    1.0000000000000001e+258
+test util-16.1.17.259 {8.4 compatible formatting of doubles} \
+    {expr 1e259} \
+    9.9999999999999993e+258
+test util-16.1.17.260 {8.4 compatible formatting of doubles} \
+    {expr 1e260} \
+    1.0000000000000001e+260
+test util-16.1.17.261 {8.4 compatible formatting of doubles} \
+    {expr 1e261} \
+    9.9999999999999993e+260
+test util-16.1.17.262 {8.4 compatible formatting of doubles} \
+    {expr 1e262} \
+    1e+262
+test util-16.1.17.263 {8.4 compatible formatting of doubles} \
+    {expr 1e263} \
+    1e+263
+test util-16.1.17.264 {8.4 compatible formatting of doubles} \
+    {expr 1e264} \
+    1e+264
+test util-16.1.17.265 {8.4 compatible formatting of doubles} \
+    {expr 1e265} \
+    1.0000000000000001e+265
+test util-16.1.17.266 {8.4 compatible formatting of doubles} \
+    {expr 1e266} \
+    1e+266
+test util-16.1.17.267 {8.4 compatible formatting of doubles} \
+    {expr 1e267} \
+    9.9999999999999997e+266
+test util-16.1.17.268 {8.4 compatible formatting of doubles} \
+    {expr 1e268} \
+    9.9999999999999997e+267
+test util-16.1.17.269 {8.4 compatible formatting of doubles} \
+    {expr 1e269} \
+    1e+269
+test util-16.1.17.270 {8.4 compatible formatting of doubles} \
+    {expr 1e270} \
+    1e+270
+test util-16.1.17.271 {8.4 compatible formatting of doubles} \
+    {expr 1e271} \
+    9.9999999999999995e+270
+test util-16.1.17.272 {8.4 compatible formatting of doubles} \
+    {expr 1e272} \
+    1.0000000000000001e+272
+test util-16.1.17.273 {8.4 compatible formatting of doubles} \
+    {expr 1e273} \
+    9.9999999999999995e+272
+test util-16.1.17.274 {8.4 compatible formatting of doubles} \
+    {expr 1e274} \
+    9.9999999999999992e+273
+test util-16.1.17.275 {8.4 compatible formatting of doubles} \
+    {expr 1e275} \
+    9.9999999999999996e+274
+test util-16.1.17.276 {8.4 compatible formatting of doubles} \
+    {expr 1e276} \
+    1.0000000000000001e+276
+test util-16.1.17.277 {8.4 compatible formatting of doubles} \
+    {expr 1e277} \
+    1e+277
+test util-16.1.17.278 {8.4 compatible formatting of doubles} \
+    {expr 1e278} \
+    9.9999999999999996e+277
+test util-16.1.17.279 {8.4 compatible formatting of doubles} \
+    {expr 1e279} \
+    1.0000000000000001e+279
+test util-16.1.17.280 {8.4 compatible formatting of doubles} \
+    {expr 1e280} \
+    1e+280
+test util-16.1.17.281 {8.4 compatible formatting of doubles} \
+    {expr 1e281} \
+    1e+281
+test util-16.1.17.282 {8.4 compatible formatting of doubles} \
+    {expr 1e282} \
+    1e+282
+test util-16.1.17.283 {8.4 compatible formatting of doubles} \
+    {expr 1e283} \
+    9.9999999999999996e+282
+test util-16.1.17.284 {8.4 compatible formatting of doubles} \
+    {expr 1e284} \
+    1.0000000000000001e+284
+test util-16.1.17.285 {8.4 compatible formatting of doubles} \
+    {expr 1e285} \
+    9.9999999999999998e+284
+test util-16.1.17.286 {8.4 compatible formatting of doubles} \
+    {expr 1e286} \
+    1e+286
+test util-16.1.17.287 {8.4 compatible formatting of doubles} \
+    {expr 1e287} \
+    1.0000000000000001e+287
+test util-16.1.17.288 {8.4 compatible formatting of doubles} \
+    {expr 1e288} \
+    1e+288
+test util-16.1.17.289 {8.4 compatible formatting of doubles} \
+    {expr 1e289} \
+    1.0000000000000001e+289
+test util-16.1.17.290 {8.4 compatible formatting of doubles} \
+    {expr 1e290} \
+    1.0000000000000001e+290
+test util-16.1.17.291 {8.4 compatible formatting of doubles} \
+    {expr 1e291} \
+    9.9999999999999996e+290
+test util-16.1.17.292 {8.4 compatible formatting of doubles} \
+    {expr 1e292} \
+    1e+292
+test util-16.1.17.293 {8.4 compatible formatting of doubles} \
+    {expr 1e293} \
+    9.9999999999999992e+292
+test util-16.1.17.294 {8.4 compatible formatting of doubles} \
+    {expr 1e294} \
+    1.0000000000000001e+294
+test util-16.1.17.295 {8.4 compatible formatting of doubles} \
+    {expr 1e295} \
+    9.9999999999999998e+294
+test util-16.1.17.296 {8.4 compatible formatting of doubles} \
+    {expr 1e296} \
+    9.9999999999999998e+295
+test util-16.1.17.297 {8.4 compatible formatting of doubles} \
+    {expr 1e297} \
+    1e+297
+test util-16.1.17.298 {8.4 compatible formatting of doubles} \
+    {expr 1e298} \
+    9.9999999999999996e+297
+test util-16.1.17.299 {8.4 compatible formatting of doubles} \
+    {expr 1e299} \
+    1.0000000000000001e+299
+test util-16.1.17.300 {8.4 compatible formatting of doubles} \
+    {expr 1e300} \
+    1.0000000000000001e+300
+test util-16.1.17.301 {8.4 compatible formatting of doubles} \
+    {expr 1e301} \
+    1.0000000000000001e+301
+test util-16.1.17.302 {8.4 compatible formatting of doubles} \
+    {expr 1e302} \
+    1.0000000000000001e+302
+test util-16.1.17.303 {8.4 compatible formatting of doubles} \
+    {expr 1e303} \
+    1e+303
+test util-16.1.17.304 {8.4 compatible formatting of doubles} \
+    {expr 1e304} \
+    9.9999999999999994e+303
+test util-16.1.17.305 {8.4 compatible formatting of doubles} \
+    {expr 1e305} \
+    9.9999999999999994e+304
+test util-16.1.17.306 {8.4 compatible formatting of doubles} \
+    {expr 1e306} \
+    1e+306
+test util-16.1.17.307 {8.4 compatible formatting of doubles} \
+    {expr 1e307} \
+    9.9999999999999999e+306
+
+test util-17.1 {bankers' rounding [Bug 3349507]} {ieeeFloatingPoint} {
+    set r {}
+    foreach {input} {
+	0x1ffffffffffffc000
+	0x1ffffffffffffc800
+	0x1ffffffffffffd000
+	0x1ffffffffffffd800
+	0x1ffffffffffffe000
+	0x1ffffffffffffe800
+	0x1fffffffffffff000
+	0x1fffffffffffff800
+    } {
+	binary scan [binary format q [expr double($input)]] wu x
+	lappend r [format %#llx $x]
+	binary scan [binary format q [expr double(-$input)]] wu x
+	lappend r [format %#llx $x]
+    }
+    set r
+} [list {*}{
+    0x43fffffffffffffc 0xc3fffffffffffffc 
+    0x43fffffffffffffc 0xc3fffffffffffffc
+    0x43fffffffffffffd 0xc3fffffffffffffd
+    0x43fffffffffffffe 0xc3fffffffffffffe
+    0x43fffffffffffffe 0xc3fffffffffffffe
+    0x43fffffffffffffe 0xc3fffffffffffffe
+    0x43ffffffffffffff 0xc3ffffffffffffff
+    0x4400000000000000 0xc400000000000000
+}]
+
+set ::tcl_precision $saved_precision
+
+# cleanup
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/tests/var.test b/tests/var.test
new file mode 100644
index 0000000..297034a
--- /dev/null
+++ b/tests/var.test
@@ -0,0 +1,993 @@
+# This file contains tests for the tclVar.c source file. Tests appear in the
+# same order as the C code that they test. The set of tests is currently
+# incomplete since it currently includes only new tests for code changed for
+# the addition of Tcl namespaces. Other variable-related tests appear in
+# several other test files including namespace.test, set.test, trace.test, and
+# upvar.test.
+#
+# Sourcing this file into Tcl runs the tests and generates output for errors.
+# No output means no errors were found.
+#
+# Copyright (c) 1997 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution of
+# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {"::tcltest" ni [namespace children]} {
+    package require tcltest 2.2
+    namespace import -force ::tcltest::*
+}
+
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
+
+testConstraint testupvar [llength [info commands testupvar]]
+testConstraint testgetvarfullname [llength [info commands testgetvarfullname]]
+testConstraint testsetnoerr [llength [info commands testsetnoerr]]
+testConstraint memory [llength [info commands memory]]
+
+catch {rename p ""}
+catch {namespace delete test_ns_var}
+catch {unset xx}
+catch {unset x}
+catch {unset y}
+catch {unset i}
+catch {unset a}
+catch {unset arr}
+
+test var-1.1 {TclLookupVar, Array handling} -setup {
+    catch {unset a}
+} -body {
+    set x "incr"  ;# force no compilation and runtime call to Tcl_IncrCmd 
+    set i 10
+    set arr(foo) 37
+    list [$x i] $i [$x arr(foo)] $arr(foo)
+} -result {11 11 38 38}
+set ::x "global value"
+namespace eval test_ns_var {
+    variable x "namespace value"
+}
+test var-1.2 {TclLookupVar, TCL_GLOBAL_ONLY implies global namespace var} {
+    namespace eval test_ns_var {
+        proc p {} {
+            global x  ;# specifies TCL_GLOBAL_ONLY to get global x
+            return $x
+        }
+    }
+    test_ns_var::p
+} {global value}
+test var-1.3 {TclLookupVar, TCL_NAMESPACE_ONLY implies namespace var} {
+    namespace eval test_ns_var {
+        proc q {} {
+            variable x  ;# specifies TCL_NAMESPACE_ONLY to get namespace x
+            return $x
+        }
+    }
+    test_ns_var::q
+} {namespace value}
+test var-1.4 {TclLookupVar, no active call frame implies global namespace var} {
+    set x
+} {global value}
+test var-1.5 {TclLookupVar, active call frame pushed for namespace eval implies namespace var} {
+    namespace eval test_ns_var {set x}
+} {namespace value}
+test var-1.6 {TclLookupVar, name starts with :: implies some namespace var} {
+    namespace eval test_ns_var {set ::x}
+} {global value}
+test var-1.7 {TclLookupVar, error finding namespace var} -body {
+    set a:::b
+} -returnCodes error -result {can't read "a:::b": no such variable}
+test var-1.8 {TclLookupVar, error finding namespace var} -body {
+    set ::foobarfoo
+} -returnCodes error -result {can't read "::foobarfoo": no such variable}
+test var-1.9 {TclLookupVar, create new namespace var} {
+    namespace eval test_ns_var {
+        set v hello
+    }
+} {hello}
+test var-1.10 {TclLookupVar, create new namespace var} -setup {
+    catch {unset y}
+} -body {
+    namespace eval test_ns_var {
+        set ::y 789
+    }
+    set y
+} -result {789}
+test var-1.11 {TclLookupVar, error creating new namespace var} -body {
+    namespace eval test_ns_var {
+        set ::test_ns_var::foo::bar 314159
+    }
+} -returnCodes error -result {can't set "::test_ns_var::foo::bar": parent namespace doesn't exist}
+test var-1.12 {TclLookupVar, error creating new namespace var} -body {
+    namespace eval test_ns_var {
+        set ::test_ns_var::foo:: 1997
+    }
+} -returnCodes error -result {can't set "::test_ns_var::foo::": parent namespace doesn't exist}
+test var-1.13 {TclLookupVar, new namespace var is created in a particular namespace} {
+    catch {unset aNeWnAmEiNnS}
+    namespace eval test_ns_var {
+        namespace eval test_ns_var2::test_ns_var3 {
+            set aNeWnAmEiNnS 77777
+        }
+        # namespace which builds a name by traversing nsPtr chain to ::
+        namespace which -variable test_ns_var2::test_ns_var3::aNeWnAmEiNnS
+    }
+} {::test_ns_var::test_ns_var2::test_ns_var3::aNeWnAmEiNnS}
+test var-1.14 {TclLookupVar, namespace code ignores ":"s in middle and end of var names} {
+    namespace eval test_ns_var {
+        set : 123
+        set v: 456
+        set x:y: 789
+        list [set :] [set v:] [set x:y:] \
+             ${:} ${v:} ${x:y:} \
+             [expr {":" in [info vars]}] \
+             [expr {"v:" in [info vars]}] \
+             [expr {"x:y:" in [info vars]}]
+    }
+} {123 456 789 123 456 789 1 1 1}
+test var-1.15 {TclLookupVar, resurrect variable via upvar to deleted namespace: compiled code path} {
+    namespace eval test_ns_var {
+	variable foo 2
+    }
+    proc p {} {
+	variable ::test_ns_var::foo
+	lappend result [catch {set foo} msg] $msg
+        namespace delete ::test_ns_var
+	lappend result [catch {set foo 3} msg] $msg
+	lappend result [catch {set foo(3) 3} msg] $msg
+    }
+    p
+} {0 2 1 {can't set "foo": upvar refers to variable in deleted namespace} 1 {can't set "foo(3)": upvar refers to variable in deleted namespace}}
+test var-1.16 {TclLookupVar, resurrect variable via upvar to deleted namespace: uncompiled code path} {
+    namespace eval test_ns_var {
+	variable result
+        namespace eval subns {
+	    variable foo 2
+	}
+	upvar 0 subns::foo foo
+	lappend result [catch {set foo} msg] $msg
+        namespace delete subns
+	lappend result [catch {set foo 3} msg] $msg
+	lappend result [catch {set foo(3) 3} msg] $msg
+        namespace delete [namespace current]
+	set result
+    }
+} {0 2 1 {can't set "foo": upvar refers to variable in deleted namespace} 1 {can't set "foo(3)": upvar refers to variable in deleted namespace}}
+test var-1.17 {TclLookupVar, resurrect array element via upvar to deleted array: compiled code path} {
+    namespace eval test_ns_var {
+	variable result
+	proc p {} {
+	    array set x {1 2 3 4}
+	    upvar 0 x(1) foo
+	    lappend result [catch {set foo} msg] $msg
+	    unset x
+	    lappend result [catch {set foo 3} msg] $msg
+	}
+	set result [p]
+        namespace delete [namespace current]
+	set result
+    }
+} {0 2 1 {can't set "foo": upvar refers to element in deleted array}}
+test var-1.18 {TclLookupVar, resurrect array element via upvar to deleted array: uncompiled code path} -setup {
+    unset -nocomplain test_ns_var::x
+} -body {
+    namespace eval test_ns_var {
+	variable result {}
+	variable x
+	array set x {1 2 3 4}
+	upvar 0 x(1) foo
+	lappend result [catch {set foo} msg] $msg
+	unset x
+	lappend result [catch {set foo 3} msg] $msg
+        namespace delete [namespace current]
+	set result
+    }
+} -result {0 2 1 {can't set "foo": upvar refers to element in deleted array}}
+test var-1.19 {TclLookupVar, right error message when parsing variable name} -body {
+    [format set] thisvar(doesntexist)
+} -returnCodes error -result {can't read "thisvar(doesntexist)": no such variable}
+
+test var-2.1 {Tcl_LappendObjCmd, create var if new} {
+    catch {unset x}
+    lappend x 1 2
+} {1 2}
+
+test var-3.1 {MakeUpvar, TCL_NAMESPACE_ONLY not specified for other var} -setup {
+    catch {unset x}
+} -body {
+    set x 1997
+    proc p {} {
+        global x  ;# calls MakeUpvar with TCL_NAMESPACE_ONLY for other var x
+        return $x
+    }
+    p
+} -result {1997}
+test var-3.2 {MakeUpvar, other var has TCL_NAMESPACE_ONLY specified} {
+    namespace eval test_ns_var {
+        catch {unset v}
+        variable v 1998
+        proc p {} {
+            variable v  ;# TCL_NAMESPACE_ONLY specified for other var x
+            return $v
+        }
+        p
+    }
+} {1998}
+test var-3.3 {MakeUpvar, my var has TCL_GLOBAL_ONLY specified} -setup {
+    catch {unset a}
+} -constraints testupvar -body {
+    set a 123321
+    proc p {} {
+	# create global xx linked to global a
+	testupvar 1 a {} xx global 
+    }
+    list [p] $xx [set xx 789] $a
+} -result {{} 123321 789 789}
+test var-3.4 {MakeUpvar, my var has TCL_NAMESPACE_ONLY specified} -setup {
+    catch {unset a}
+} -constraints testupvar -body {
+    set a 456
+    namespace eval test_ns_var {
+	catch {unset ::test_ns_var::vv}
+	proc p {} {
+	    # create namespace var vv linked to global a
+	    testupvar 1 a {} vv namespace 
+	}
+	p
+    }
+    list $test_ns_var::vv [set test_ns_var::vv 123] $a
+} -result {456 123 123}
+test var-3.5 {MakeUpvar, no call frame so my var will be in global :: ns} -setup {
+    catch {unset aaaaa}
+    catch {unset xxxxx}
+} -body {
+    set aaaaa 77777
+    upvar #0 aaaaa xxxxx
+    list [set xxxxx] [set aaaaa]
+} -result {77777 77777}
+test var-3.6 {MakeUpvar, active call frame pushed for namespace eval} -setup {
+    catch {unset a}
+} -body {
+    set a 121212
+    namespace eval test_ns_var {
+        upvar ::a vvv
+        set vvv
+    }
+} -result {121212}
+test var-3.7 {MakeUpvar, my var has ::s} -setup {
+    catch {unset a}
+} -body {
+    set a 789789
+    upvar #0 a test_ns_var::lnk
+    namespace eval test_ns_var {
+        set lnk
+    }
+} -result {789789}
+test var-3.8 {MakeUpvar, my var already exists in global ns} -setup {
+    upvar #0 aaaaa xxxxx
+    catch {unset aaaaa}
+    catch {unset xxxxx}
+} -body {
+    set aaaaa 456654
+    set xxxxx hello
+    upvar #0 aaaaa xxxxx
+    set xxxxx
+} -result {hello}
+test var-3.9 {MakeUpvar, my var has invalid ns name} -setup {
+    catch {unset aaaaa}
+} -returnCodes error -body {
+    set aaaaa 789789
+    upvar #0 aaaaa test_ns_fred::lnk
+} -cleanup {
+    unset ::aaaaa
+} -result {can't create "test_ns_fred::lnk": parent namespace doesn't exist}
+test var-3.10 {MakeUpvar, between namespaces} -body {
+    namespace eval {} {
+	variable bar 0
+	namespace eval foo upvar bar bar
+	set foo::bar 1
+	list $bar $foo::bar
+    }
+} -result {1 1}
+test var-3.11 {MakeUpvar, my var looks like array elem} -setup {
+    catch {unset aaaaa}
+} -returnCodes error -body {
+    set aaaaa 789789
+    upvar #0 aaaaa foo(bar)
+} -result {bad variable name "foo(bar)": can't create a scalar variable that looks like an array element}
+
+test var-4.1 {Tcl_GetVariableName, global variable} testgetvarfullname {
+    catch {unset a}
+    set a 123
+    testgetvarfullname a global
+} ::a
+test var-4.2 {Tcl_GetVariableName, namespace variable} testgetvarfullname {
+    namespace eval test_ns_var {
+	variable george
+	testgetvarfullname george namespace
+    }
+} ::test_ns_var::george
+test var-4.3 {Tcl_GetVariableName, variable can't be array element} -setup {
+    catch {unset a}
+} -constraints testgetvarfullname -body {
+    set a(1) foo
+    testgetvarfullname a(1) global
+} -returnCodes error -result {unknown variable "a(1)"}
+
+test var-5.1 {Tcl_GetVariableFullName, global variable} -setup {
+    catch {unset a}
+} -body {
+    set a bar
+    namespace which -variable a
+} -result {::a}
+test var-5.2 {Tcl_GetVariableFullName, namespace variable} {
+    namespace eval test_ns_var {
+        variable martha
+        namespace which -variable martha
+    }
+} {::test_ns_var::martha}
+test var-5.3 {Tcl_GetVariableFullName, namespace variable} -setup {
+    namespace eval test_ns_var {variable martha}
+} -body {
+    namespace which -variable test_ns_var::martha
+} -result {::test_ns_var::martha}
+
+test var-6.1 {Tcl_GlobalObjCmd, variable is qualified by a namespace name} {
+    namespace eval test_ns_var {
+        variable boeing 777
+    }
+    apply {{} {
+        global ::test_ns_var::boeing
+        set boeing
+    }}
+} {777}
+test var-6.2 {Tcl_GlobalObjCmd, variable is qualified by a namespace name} {
+    namespace eval test_ns_var {
+        namespace eval test_ns_nested {
+            variable java java
+        }
+        proc p {} {
+            global ::test_ns_var::test_ns_nested::java
+            set java
+        }
+    }
+    test_ns_var::p
+} {java}
+test var-6.3 {Tcl_GlobalObjCmd, variable named {} qualified by a namespace name} {
+    namespace eval ::test_ns_var::test_ns_nested {}
+    set ::test_ns_var::test_ns_nested:: 24
+    apply {{} {
+        global ::test_ns_var::test_ns_nested::
+        set {}
+    }}
+} {24}
+test var-6.4 {Tcl_GlobalObjCmd, variable name matching :*} {
+    # Test for Tcl Bug 480176
+    set :v broken
+    proc p {} {
+	global :v
+	set :v fixed
+    }
+    p
+    set :v
+} {fixed}
+test var-6.5 {Tcl_GlobalObjCmd, no-op case (TIP 323)} {
+    global
+} {}
+test var-6.6 {Tcl_GlobalObjCmd, no-op case (TIP 323)} {
+    proc p {} {
+	global
+    }
+    p
+} {}
+
+test var-7.1 {Tcl_VariableObjCmd, create and initialize one new ns variable} -setup {
+    catch {namespace delete test_ns_var}
+} -body {
+    namespace eval test_ns_var {
+        variable one 1
+    }
+    list [info vars test_ns_var::*] [set test_ns_var::one]
+} -result {::test_ns_var::one 1}
+test var-7.2 {Tcl_VariableObjCmd, if new and no value, leave undefined} {
+    set two 2222222
+    namespace eval test_ns_var {
+        variable two
+    }
+    list [info exists test_ns_var::two] [catch {set test_ns_var::two} msg] $msg
+} {0 1 {can't read "test_ns_var::two": no such variable}}
+test var-7.3 {Tcl_VariableObjCmd, "define" var already created above} -setup {
+    catch {namespace delete test_ns_var}
+    namespace eval test_ns_var {variable one 1}
+} -body {
+    namespace eval test_ns_var {
+        variable two 2
+    }
+    list [lsort [info vars test_ns_var::*]] \
+         [namespace eval test_ns_var {set two}]
+} -result [list [lsort {::test_ns_var::two ::test_ns_var::one}] 2]
+test var-7.4 {Tcl_VariableObjCmd, list of vars} -setup {
+    catch {namespace delete test_ns_var}
+    namespace eval test_ns_var {variable one 1; variable two 2}
+} -body {
+    namespace eval test_ns_var {
+        variable three 3 four 4
+    }
+    list [lsort [info vars test_ns_var::*]] \
+         [namespace eval test_ns_var {expr $three+$four}]
+} -result [list [lsort {::test_ns_var::four ::test_ns_var::three ::test_ns_var::two ::test_ns_var::one}] 7]
+test var-7.5 {Tcl_VariableObjCmd, value for last var is optional} -setup {
+    catch {unset a}
+    catch {unset five}
+    catch {unset six}
+} -body {
+    set a ""
+    set five 555
+    set six  666
+    namespace eval test_ns_var {
+        variable five 5 six
+        lappend a $five
+    }
+    lappend a $test_ns_var::five \
+        [set test_ns_var::six 6] [set test_ns_var::six] $six
+} -cleanup {
+    catch {unset five}
+    catch {unset six}
+} -result {5 5 6 6 666}
+test var-7.6 {Tcl_VariableObjCmd, variable name can be qualified} -setup {
+    catch {unset newvar}
+} -body {
+    namespace eval test_ns_var {
+        variable ::newvar cheers!
+    }
+    return $newvar
+} -cleanup {
+    catch {unset newvar}
+} -result {cheers!}
+test var-7.7 {Tcl_VariableObjCmd, bad var name} -returnCodes error -body {
+    namespace eval test_ns_var {
+        variable sev:::en 7
+    }
+} -result {can't define "sev:::en": parent namespace doesn't exist}
+test var-7.8 {Tcl_VariableObjCmd, if var already exists and no value is given, leave value unchanged} {
+    set a ""
+    namespace eval test_ns_var {
+        variable eight 8
+        lappend a $eight
+        variable eight
+        lappend a $eight
+    }
+    set a
+} {8 8}
+test var-7.9 {Tcl_VariableObjCmd, mark as namespace var so var persists until namespace is destroyed or var is unset} -setup {
+    catch {namespace delete test_ns_var2}
+} -body {
+    set a ""
+    namespace eval test_ns_var2 {
+        variable x 123
+        variable y
+        variable z
+    }
+    lappend a [lsort [info vars test_ns_var2::*]]
+    lappend a [info exists test_ns_var2::x] [info exists test_ns_var2::y] \
+        [info exists test_ns_var2::z]
+    lappend a [list [catch {set test_ns_var2::y} msg] $msg]
+    lappend a [lsort [info vars test_ns_var2::*]]
+    lappend a [info exists test_ns_var2::y] [info exists test_ns_var2::z]
+    lappend a [set test_ns_var2::y hello]
+    lappend a [info exists test_ns_var2::y] [info exists test_ns_var2::z]
+    lappend a [list [catch {unset test_ns_var2::y} msg] $msg]
+    lappend a [lsort [info vars test_ns_var2::*]]
+    lappend a [info exists test_ns_var2::y] [info exists test_ns_var2::z]
+    lappend a [list [catch {unset test_ns_var2::z} msg] $msg]
+    lappend a [namespace delete test_ns_var2]
+} -result [list [lsort {::test_ns_var2::x ::test_ns_var2::y ::test_ns_var2::z}] 1 0 0\
+	{1 {can't read "test_ns_var2::y": no such variable}}\
+	[lsort {::test_ns_var2::x ::test_ns_var2::y ::test_ns_var2::z}] 0 0\
+	hello 1 0\
+	{0 {}}\
+	[lsort {::test_ns_var2::x ::test_ns_var2::z}] 0 0\
+	{1 {can't unset "test_ns_var2::z": no such variable}}\
+	{}]
+test var-7.10 {Tcl_VariableObjCmd, variable cmd inside proc creates local link var} -setup {
+    namespace eval test_ns_var { variable eight 8 }
+} -body {
+    namespace eval test_ns_var {
+        proc p {} {
+            variable eight
+            list [set eight] [info vars]
+        }
+        p
+    }
+} -result {8 eight}
+test var-7.11 {Tcl_VariableObjCmd, variable cmd inside proc creates local link var} -setup {
+    namespace eval test_ns_var { variable eight 8 }
+} -body {
+    proc p {} {   ;# note this proc is at global :: scope
+        variable test_ns_var::eight
+        list [set eight] [info vars]
+    }
+    p
+} -result {8 eight}
+test var-7.12 {Tcl_VariableObjCmd, variable cmd inside proc creates local link var} {
+    namespace eval test_ns_var {
+        variable {} {My name is empty}
+    }
+    proc p {} {   ;# note this proc is at global :: scope
+        variable test_ns_var::
+        list [set {}] [info vars]
+    }
+    p
+} {{My name is empty} {{}}}
+test var-7.13 {Tcl_VariableObjCmd, variable named ":"} {
+    namespace eval test_ns_var {
+        variable : {My name is ":"}
+	proc p {} {
+	    variable :
+	    list [set :] [info vars]
+	}
+	p
+    }
+} {{My name is ":"} :}
+test var-7.14 {Tcl_VariableObjCmd, array element parameter} -body {
+    namespace eval test_ns_var { variable arrayvar(1) }
+} -returnCodes error -result "can't define \"arrayvar(1)\": name refers to an element in an array"
+test var-7.15 {Tcl_VariableObjCmd, array element parameter} -body {
+    namespace eval test_ns_var { 
+	variable arrayvar
+	set arrayvar(1) x
+	variable arrayvar(1) y
+    }   
+} -returnCodes error -result "can't define \"arrayvar(1)\": name refers to an element in an array"
+test var-7.16 {Tcl_VariableObjCmd, no args (TIP 323)} {
+    variable
+} {}
+test var-7.17 {Tcl_VariableObjCmd, no args (TIP 323)} {
+    namespace eval test_ns_var {
+	variable
+    }
+} {}
+
+test var-8.1 {TclDeleteVars, "unset" traces are called with fully-qualified var names} -setup {
+    catch {namespace delete test_ns_var}
+    catch {unset a}
+} -body {
+    namespace eval test_ns_var {
+        variable v 123
+        variable info ""
+        proc traceUnset {name1 name2 op} {
+            variable info
+            set info [concat $info [list $name1 $name2 $op]]
+        }
+        trace var v u [namespace code traceUnset]
+    }
+    list [unset test_ns_var::v] $test_ns_var::info
+} -result {{} {test_ns_var::v {} u}}
+test var-8.2 {TclDeleteNamespaceVars, "unset" traces on ns delete are called with fully-qualified var names} -setup {
+    catch {namespace delete test_ns_var}
+    catch {unset a}
+} -body {
+    set info ""
+    namespace eval test_ns_var {
+        variable v 123 1
+        trace var v u ::traceUnset
+    }
+    proc traceUnset {name1 name2 op} {
+	set ::info [concat $::info [list $name1 $name2 $op]]
+    }
+    list [namespace delete test_ns_var] $::info
+} -result {{} {::test_ns_var::v {} u}}
+
+test var-9.1 {behaviour of TclGet/SetVar simple get/set} -setup {
+    catch {unset u}
+    catch {unset v}
+} -constraints testsetnoerr -body {
+    list \
+	[set u a; testsetnoerr u] \
+	[testsetnoerr v b] \
+	[testseterr u] \
+	[unset v; testseterr v b]
+} -result [list {before get a} {before set b} {before get a} {before set b}]
+test var-9.2 {behaviour of TclGet/SetVar namespace get/set} -setup {
+    catch {namespace delete ns}
+} -constraints testsetnoerr -body {
+    namespace eval ns {variable u a; variable v}
+    list \
+	[testsetnoerr ns::u] \
+	[testsetnoerr ns::v b] \
+	[testseterr ns::u] \
+	[unset ns::v; testseterr ns::v b]
+} -result [list {before get a} {before set b} {before get a} {before set b}]
+test var-9.3 {behaviour of TclGetVar no variable} -setup {
+    catch {unset u}
+} -constraints testsetnoerr -body {
+    list \
+	[catch {testsetnoerr u} res] $res \
+	[catch {testseterr u} res] $res
+} -result {1 {before get} 1 {can't read "u": no such variable}}
+test var-9.4 {behaviour of TclGetVar no namespace variable} -setup {
+    catch {namespace delete ns}
+} -constraints testsetnoerr -body {
+    namespace eval ns {}
+    list \
+	[catch {testsetnoerr ns::w} res] $res \
+	[catch {testseterr ns::w} res] $res
+} -result {1 {before get} 1 {can't read "ns::w": no such variable}}
+test var-9.5 {behaviour of TclGetVar no namespace} -setup {
+    catch {namespace delete ns}
+} -constraints testsetnoerr -body {
+    list \
+	[catch {testsetnoerr ns::u} res] $res \
+	[catch {testseterr ns::v} res] $res
+} -result {1 {before get} 1 {can't read "ns::v": no such variable}}
+test var-9.6 {behaviour of TclSetVar no namespace} -setup {
+    catch {namespace delete ns}
+} -constraints testsetnoerr -body {
+    list \
+	[catch {testsetnoerr ns::v 1} res] $res \
+	[catch {testseterr ns::v 1} res] $res
+} -result {1 {before set} 1 {can't set "ns::v": parent namespace doesn't exist}}
+test var-9.7 {behaviour of TclGetVar array variable} -setup {
+    catch {unset arr}
+} -constraints testsetnoerr -body {
+    set arr(1) 1
+    list \
+	[catch {testsetnoerr arr} res] $res \
+	[catch {testseterr arr} res] $res
+} -result {1 {before get} 1 {can't read "arr": variable is array}}
+test var-9.8 {behaviour of TclSetVar array variable} -setup {
+    catch {unset arr}
+} -constraints testsetnoerr -body {
+    set arr(1) 1
+    list \
+	[catch {testsetnoerr arr 2} res] $res \
+	[catch {testseterr arr 2} res] $res
+} -result {1 {before set} 1 {can't set "arr": variable is array}}
+test var-9.9 {behaviour of TclGetVar read trace success} -setup {
+    catch {unset u}
+    catch {unset v}
+} -constraints testsetnoerr -body {
+    proc resetvar {val name elem op} {upvar 1 $name v; set v $val}
+    set u 10
+    trace var u r [list resetvar 1]
+    trace var v r [list resetvar 2]
+    list \
+	[testsetnoerr u] \
+	[testseterr v]
+} -result {{before get 1} {before get 2}}
+test var-9.10 {behaviour of TclGetVar read trace error} testsetnoerr {
+    proc writeonly args {error "write-only"}
+    set v 456
+    trace var v r writeonly
+    list \
+	[catch {testsetnoerr v} msg] $msg \
+	[catch {testseterr v} msg] $msg
+} {1 {before get} 1 {can't read "v": write-only}}
+test var-9.11 {behaviour of TclSetVar write trace success} -setup {
+    catch {unset u}
+    catch {unset v}
+} -constraints testsetnoerr -body {
+    proc doubleval {name elem op} {upvar 1 $name v; set v [expr {2 * $v}]}
+    set v 1
+    trace var v w doubleval
+    trace var u w doubleval
+    list \
+	[testsetnoerr u 2] \
+	[testseterr v 3]
+} -result {{before set 4} {before set 6}}
+test var-9.12 {behaviour of TclSetVar write trace error} testsetnoerr {
+    proc readonly args {error "read-only"}
+    set v 456
+    trace var v w readonly
+    list \
+	[catch {testsetnoerr v 2} msg] $msg $v \
+	[catch {testseterr v 3} msg] $msg $v
+} {1 {before set} 2 1 {can't set "v": read-only} 3}
+
+test var-10.1 {can't nest arrays with array set} -setup {
+   catch {unset arr}
+} -returnCodes error -body {
+   array set arr(x) {a 1 b 2}
+} -result {can't set "arr(x)": variable isn't array}
+test var-10.2 {can't nest arrays with array set} -setup {
+   catch {unset arr}
+} -returnCodes error -body {
+   array set arr(x) {}
+} -result {can't set "arr(x)": variable isn't array}
+
+test var-11.1 {array unset} -setup {
+    catch {unset a}
+} -body {
+    array set a { 1,1 a 1,2 b 2,1 c 2,3 d }
+    array unset a 1,*
+    lsort -dict [array names a]
+} -result {2,1 2,3}
+test var-11.2 {array unset} -setup {
+    catch {unset a}
+} -body {
+    array set a { 1,1 a 1,2 b }
+    array unset a
+    array exists a
+} -result 0
+test var-11.3 {array unset errors} -setup {
+    catch {unset a}
+} -returnCodes error -body {
+    array set a { 1,1 a 1,2 b }
+    array unset a pattern too
+} -result {wrong # args: should be "array unset arrayName ?pattern?"}
+
+test var-12.1 {TclFindCompiledLocals, {} array name} {
+    namespace eval n {
+	proc p {} {
+	    variable {}
+	    set (0) 0
+	    set (1) 1
+	    set n 2
+	    set ($n) 2
+	    set ($n,foo) 2
+	}
+	p
+	lsort -dictionary [array names {}]
+    }
+} {0 1 2 2,foo}
+
+test var-13.1 {Tcl_UnsetVar2, unset array with trace set on element} -setup {
+    catch {unset t}
+} -body {
+    proc foo {var ind op} {
+	global t
+	set foo bar
+    }
+    namespace eval :: {
+	set t(1) 1
+	trace variable t(1) u foo
+	unset t
+    }
+    set x "If you see this, it worked"
+} -result "If you see this, it worked"
+
+test var-14.1 {array names syntax} -body {
+    array names foo bar baz snafu
+} -returnCodes 1 -match glob -result *
+test var-14.2 {array names -glob} -body {
+    array names tcl_platform -glob os
+} -result os
+
+test var-15.1 {segfault in [unset], [Bug 735335]} {
+    proc A { name } {
+	upvar $name var
+	set var $name
+    }
+    #
+    # Note that the variable name has to be 
+    # unused previously for the segfault to
+    # be triggered.
+    #
+    namespace eval test A useSomeUnlikelyNameHere
+    namespace eval test unset useSomeUnlikelyNameHere
+} {}
+test var-15.2 {compiled unset evaluation order, Bug 3970f54c4e} {
+    apply {{} {unset foo [return ok]}}
+} ok
+
+test var-16.1 {CallVarTraces: save/restore interp error state} {
+    trace add variable ::errorCode write " ;#"
+    catch {error foo bar baz}
+    trace remove variable ::errorCode write " ;#"
+    set ::errorInfo
+} bar
+
+test var-17.1 {TclArraySet [Bug 1669489]} -setup {
+    unset -nocomplain ::a
+} -body {
+    namespace eval :: {
+	set elements {1 2 3 4}
+	trace add variable a write "string length \$elements ;#"
+	array set a $elements
+    }
+} -cleanup {
+    unset -nocomplain ::a ::elements
+} -result {}
+
+test var-18.1 {array unset and unset traces: Bug 2939073} -setup {
+    set already 0
+    unset -nocomplain x
+} -body {
+    array set x {e 1 i 1}
+    trace add variable x unset {apply {args {
+	global already x
+	if {!$already} {
+	    set already 1
+	    unset x(i)
+	}
+    }}}
+    # The next command would crash reliably with memory debugging prior to the
+    # bug fix.
+    array unset x *
+    array size x
+} -cleanup {
+    unset x already
+} -result 0
+
+test var-19.1 {crash when freeing locals hashtable: Bug 3037525} {
+    proc foo {} { catch {upvar 0 dummy \$index} }
+    foo ; # This crashes without the fix for the bug
+    rename foo {}
+} {}
+
+test var-20.1 {array set compilation correctness: Bug 3603163} -setup {
+    unset -nocomplain x
+} -body {
+    apply {{} {
+	global x
+	array set x {a 1}
+    }}
+    array size x
+} -result 1
+test var-20.2 {array set compilation correctness: Bug 3603163} -setup {
+    unset -nocomplain x
+} -body {
+    apply {{} {
+	global x
+	array set x {}
+    }}
+    array size x
+} -result 0
+test var-20.3 {array set compilation correctness: Bug 3603163} -setup {
+    unset -nocomplain x
+} -body {
+    apply {{} {
+	array set ::x {a 1}
+    }}
+    array size x
+} -result 1
+test var-20.4 {array set compilation correctness: Bug 3603163} -setup {
+    unset -nocomplain x
+} -body {
+    apply {{} {
+	array set ::x {}
+    }}
+    array size x
+} -result 0
+test var-20.5 {array set compilation correctness: Bug 3603163} -setup {
+    unset -nocomplain x
+} -body {
+    apply {{} {
+	global x
+	eval {array set x {a 1}}
+    }}
+    array size x
+} -result 1
+test var-20.6 {array set compilation correctness: Bug 3603163} -setup {
+    unset -nocomplain x
+} -body {
+    apply {{} {
+	global x
+	eval {array set x {}}
+    }}
+    array size x
+} -result 0
+test var-20.7 {array set compilation correctness: Bug 3603163} -setup {
+    unset -nocomplain x
+} -body {
+    apply {{} {
+	eval {array set ::x {a 1}}
+    }}
+    array size x
+} -result 1
+test var-20.8 {array set compilation correctness: Bug 3603163} -setup {
+    unset -nocomplain x
+} -body {
+    apply {{} {
+	eval {array set ::x {}}
+    }}
+    array size x
+} -result 0
+test var-20.9 {[bc1a96407a] array set compiled w/ trace} -setup {
+    variable foo
+    variable lambda
+    unset -nocomplain lambda foo
+    array set foo {}
+    lappend lambda {}
+    lappend lambda [list array set [namespace which -variable foo] {a 1}]
+} -body {
+    after 0 [list apply $lambda]
+    vwait [namespace which -variable foo]
+} -cleanup {
+    unset -nocomplain lambda foo
+} -result {}
+test var-20.10 {[bc1a96407a] array set don't compile bad varname} -body {
+    apply {{} {set name foo(bar); array set $name {a 1}}}
+} -returnCodes error -match glob -result *
+
+test var-21.0 {PushVarNameWord OBOE in compiled unset} -setup {
+    proc linenumber {} {dict get [info frame -1] line}
+} -body {
+    apply {n {
+	set foo bar
+        unset foo {*}{
+        } [return [incr n -[linenumber]]]
+    }} [linenumber]
+} -cleanup {
+    rename linenumber {}
+} -result 1
+
+test var-22.0 {leak in array element unset: Bug a3309d01db} -setup {
+    proc getbytes {} {
+	lindex [split [memory info] \n] 3 3
+    }
+    proc doit k {
+	variable A
+	set A($k) {}
+	foreach n [array names A] {
+	    if {$n <= $k-1} {
+		unset A($n)
+	    }
+	}
+    }
+} -constraints memory -body {
+    set end [getbytes]
+    for {set i 0} {$i < 5} {incr i} {
+	doit $i
+        set tmp $end
+        set end [getbytes]
+    }
+    set leakedBytes [expr {$end - $tmp}]
+} -cleanup {
+    array unset A
+    rename getbytes {}
+    rename doit {}
+} -result 0
+test var-22.1 {leak in localVarName intrep: Bug 80304238ac} -setup {
+    proc getbytes {} {
+	lindex [split [memory info] \n] 3 3
+    }
+    proc doit {} {
+	interp create slave
+	slave eval {
+	    proc doit script {
+		eval $script
+		set foo bar
+	    }
+	    doit {foreach foo baz {}}
+	}
+	interp delete slave
+    }
+} -constraints memory -body {
+    set end [getbytes]
+    for {set i 0} {$i < 5} {incr i} {
+	doit
+        set tmp $end
+        set end [getbytes]
+    }
+    set leakedBytes [expr {$end - $tmp}]
+} -cleanup {
+    array unset A
+    rename getbytes {}
+    rename doit {}
+} -result 0
+
+
+catch {namespace delete ns}
+catch {unset arr}
+catch {unset v}
+
+catch {rename p ""}
+catch {namespace delete test_ns_var}
+catch {namespace delete test_ns_var2}
+catch {unset xx}
+catch {unset x}
+catch {unset y}
+catch {unset i}
+catch {unset a}
+catch {unset xxxxx}
+catch {unset aaaaa}
+
+# cleanup
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/tests/while-old.test b/tests/while-old.test
new file mode 100644
index 0000000..ee17d0b
--- /dev/null
+++ b/tests/while-old.test
@@ -0,0 +1,119 @@
+# Commands covered:  while
+#
+# This file contains the original set of tests for Tcl's while command.
+# Since the while command is now compiled, a new set of tests covering
+# the new implementation is in the file "while.test". Sourcing this file
+# into Tcl runs the tests and generates output for errors.
+# No output means no errors were found.
+#
+# Copyright (c) 1991-1993 The Regents of the University of California.
+# Copyright (c) 1994-1996 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+    package require tcltest
+    namespace import -force ::tcltest::*
+}
+
+test while-old-1.1 {basic while loops} {
+    set count 0
+    while {$count < 10} {set count [expr $count+1]}
+    set count
+} 10
+test while-old-1.2 {basic while loops} {
+    set value xxx
+    while {2 > 3} {set value yyy}
+    set value
+} xxx
+test while-old-1.3 {basic while loops} {
+    set value 1
+    while {"true"} {
+	incr value;
+	if {$value > 5} {
+	    break;
+	}
+    }
+    set value
+} 6
+test while-old-1.4 {basic while loops, multiline test expr} {
+    set value 1
+    while {($tcl_platform(platform) != "foobar1") && \
+	    ($tcl_platform(platform) != "foobar2")} {
+        incr value
+        break
+    }
+    set value
+} {2}
+test while-old-1.5 {basic while loops, test expr in quotes} {
+    set value 1
+    while "0 < 3" {set value 2; break}
+    set value
+} {2}
+
+test while-old-2.1 {continue in while loop} {
+    set list {1 2 3 4 5}
+    set index 0
+    set result {}
+    while {$index < 5} {
+	if {$index == 2} {set index [expr $index+1]; continue}
+	set result [concat $result [lindex $list $index]]
+	set index [expr $index+1]
+    }
+    set result
+} {1 2 4 5}
+
+test while-old-3.1 {break in while loop} {
+    set list {1 2 3 4 5}
+    set index 0
+    set result {}
+    while {$index < 5} {
+	if {$index == 3} break
+	set result [concat $result [lindex $list $index]]
+	set index [expr $index+1]
+    }
+    set result
+} {1 2 3}
+
+test while-old-4.1 {errors in while loops} {
+    set err [catch {while} msg]
+    list $err $msg
+} {1 {wrong # args: should be "while test command"}}
+test while-old-4.2 {errors in while loops} {
+    set err [catch {while 1} msg]
+    list $err $msg
+} {1 {wrong # args: should be "while test command"}}
+test while-old-4.3 {errors in while loops} {
+    set err [catch {while 1 2 3} msg]
+    list $err $msg
+} {1 {wrong # args: should be "while test command"}}
+test while-old-4.4 {errors in while loops} {
+    set err [catch {while {"a"+"b"} {error "loop aborted"}} msg]
+    list $err $msg
+} {1 {can't use non-numeric string as operand of "+"}}
+test while-old-4.5 {errors in while loops} {
+    catch {unset x}
+    set x 1
+    set err [catch {while {$x} {set x foo}} msg]
+    list $err $msg
+} {1 {expected boolean value but got "foo"}}
+test while-old-4.6 {errors in while loops} {
+    set err [catch {while {1} {error "loop aborted"}} msg]
+    list $err $msg $::errorInfo
+} {1 {loop aborted} {loop aborted
+    while executing
+"error "loop aborted""}}
+
+test while-old-5.1 {while return result} {
+    while {0} {set a 400}
+} {}
+test while-old-5.2 {while return result} {
+    set x 1
+    while {$x} {set x 0}
+} {}
+
+# cleanup
+::tcltest::cleanupTests
+return
diff --git a/tests/while.test b/tests/while.test
new file mode 100644
index 0000000..642ec93
--- /dev/null
+++ b/tests/while.test
@@ -0,0 +1,702 @@
+# Commands covered:  while
+#
+# This file contains a collection of tests for one or more of the Tcl built-in
+# commands.  Sourcing this file into Tcl runs the tests and generates output
+# for errors.  No output means no errors were found.
+#
+# Copyright (c) 1996 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution of
+# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {"::tcltest" ni [namespace children]} {
+    package require tcltest 2
+    namespace import -force ::tcltest::*
+}
+
+# Basic "while" operation.
+
+catch {unset i}
+catch {unset a}
+
+test while-1.1 {TclCompileWhileCmd: missing test expression} -body {
+    while
+} -returnCodes error -result {wrong # args: should be "while test command"}
+test while-1.2 {TclCompileWhileCmd: error in test expression} -body {
+    set i 0
+    catch {while {$i<} break}
+    return $::errorInfo
+} -cleanup {
+    unset i
+} -match glob -result {*"while {$i<} break"}
+test while-1.3 {TclCompileWhileCmd: error in test expression} -body {
+    while {"a"+"b"} {error "loop aborted"}
+} -returnCodes error -result {can't use non-numeric string as operand of "+"}
+test while-1.4 {TclCompileWhileCmd: multiline test expr} -body {
+    set value 1
+    while {($tcl_platform(platform) != "foobar1") && \
+	    ($tcl_platform(platform) != "foobar2")} {
+        incr value
+        break
+    }
+    return $value
+} -cleanup {
+    unset value
+} -result {2}
+test while-1.5 {TclCompileWhileCmd: non-numeric boolean test expr} -body {
+    set value 1
+    while {"true"} {
+	incr value;
+	if {$value > 5} {
+	    break;
+	}
+    }
+    return $value
+} -cleanup {
+    unset value
+} -result 6
+test while-1.6 {TclCompileWhileCmd: test expr is enclosed in quotes} {
+    set i 0
+    while "$i > 5" {}
+} {}
+test while-1.7 {TclCompileWhileCmd: missing command body} -body {
+    set i 0
+    while {$i < 5}
+} -returnCodes error -result {wrong # args: should be "while test command"}
+test while-1.8 {TclCompileWhileCmd: error compiling command body} -body {
+    set i 0
+    catch {while {$i < 5} {set}}
+    return $::errorInfo
+} -match glob -cleanup {
+    unset i
+} -result {wrong # args: should be "set varName ?newValue?"
+    while *ing
+"set"*}
+test while-1.9 {TclCompileWhileCmd: simple command body} -body {
+    set a {}
+    set i 1
+    while {$i<6} {
+	if $i==4 break
+	set a [concat $a $i]
+        incr i
+    }
+    return $a
+} -cleanup {
+    unset a i
+} -result {1 2 3}
+test while-1.10 {TclCompileWhileCmd: command body in quotes} -body {
+    set a {}
+    set i 1
+    while {$i<6} "append a x; incr i"
+    return $a
+} -cleanup {
+    unset a i
+} -result {xxxxx}
+test while-1.11 {TclCompileWhileCmd: computed command body} -setup {
+    catch {unset x1}
+    catch {unset bb}
+    catch {unset x2}
+} -body {
+    set x1 {append a x1; }
+    set bb {break}
+    set x2 {; append a x2; incr i}
+    set a {}
+    set i 1
+    while {$i<6} $x1$bb$x2
+    return $a
+} -cleanup {
+    unset x1 bb x2 a i
+} -result {x1}
+test while-1.12 {TclCompileWhileCmd: long command body} -body {
+    set a {}
+    set i 1
+    while {$i<6} {
+	if $i==4 break
+	if $i>5 continue
+	if {$i>6 && $tcl_platform(machine)=="xxx"} {
+	    catch {set a $a} msg
+	    catch {incr i 5} msg
+	    catch {incr i -5} msg
+	}
+	if {$i>6 && $tcl_platform(machine)=="xxx"} {
+	    catch {set a $a} msg
+	    catch {incr i 5} msg
+	    catch {incr i -5} msg
+	}
+	if {$i>6 && $tcl_platform(machine)=="xxx"} {
+	    catch {set a $a} msg
+	    catch {incr i 5} msg
+	    catch {incr i -5} msg
+	}
+	if {$i>6 && $tcl_platform(machine)=="xxx"} {
+	    catch {set a $a} msg
+	    catch {incr i 5} msg
+	    catch {incr i -5} msg
+	}
+	if {$i>6 && $tcl_platform(machine)=="xxx"} {
+	    catch {set a $a} msg
+	    catch {incr i 5} msg
+	    catch {incr i -5} msg
+	}
+	set a [concat $a $i]
+        incr i
+    }
+    return $a
+} -cleanup {
+    unset a i
+} -result {1 2 3}
+test while-1.13 {TclCompileWhileCmd: while command result} -body {
+    set i 0
+    set a [while {$i < 5} {incr i}]
+    return $a
+} -cleanup {
+    unset a i
+} -result {}
+test while-1.14 {TclCompileWhileCmd: while command result} -body {
+    set i 0
+    set a [while {$i < 5} {if $i==3 break; incr i}]
+    return $a
+} -cleanup {
+    unset a i
+} -result {}
+
+# Check "while" and "continue".
+
+test while-2.1 {continue tests} -body {
+    set a {}
+    set i 1
+    while {$i <= 4} {
+        incr i
+	if {$i == 3} continue
+	set a [concat $a $i]
+    }
+    return $a
+} -cleanup {
+    unset a i
+} -result {2 4 5}
+test while-2.2 {continue tests} -body {
+    set a {}
+    set i 1
+    while {$i <= 4} {
+        incr i
+	if {$i != 2} continue
+	set a [concat $a $i]
+    }
+    return $a
+} -cleanup {
+    unset a i
+} -result {2}
+test while-2.3 {continue tests, nested loops} -body {
+    set msg {}
+    set i 1
+    while {$i <= 4} {
+        incr i
+        set a 1
+	while {$a <= 2} {
+            incr a
+            if {$i>=3 && $a>=3} continue
+            set msg [concat $msg "$i.$a"]
+        }
+    }
+    return $msg
+} -cleanup {
+    unset a i msg
+} -result {2.2 2.3 3.2 4.2 5.2}
+test while-2.4 {continue tests, long command body} -body {
+    set a {}
+    set i 1
+    while {$i<6} {
+	if $i==2 {incr i; continue}
+	if $i==4 break
+	if $i>5 continue
+	if {$i>6 && $tcl_platform(machine)=="xxx"} {
+	    catch {set a $a} msg
+	    catch {incr i 5} msg
+	    catch {incr i -5} msg
+	}
+	if {$i>6 && $tcl_platform(machine)=="xxx"} {
+	    catch {set a $a} msg
+	    catch {incr i 5} msg
+	    catch {incr i -5} msg
+	}
+	if {$i>6 && $tcl_platform(machine)=="xxx"} {
+	    catch {set a $a} msg
+	    catch {incr i 5} msg
+	    catch {incr i -5} msg
+	}
+	if {$i>6 && $tcl_platform(machine)=="xxx"} {
+	    catch {set a $a} msg
+	    catch {incr i 5} msg
+	    catch {incr i -5} msg
+	}
+	if {$i>6 && $tcl_platform(machine)=="xxx"} {
+	    catch {set a $a} msg
+	    catch {incr i 5} msg
+	    catch {incr i -5} msg
+	}
+	set a [concat $a $i]
+        incr i
+    }
+    return $a
+} -cleanup {
+    unset a i
+} -result {1 3}
+
+# Check "while" and "break".
+
+test while-3.1 {break tests} -body {
+    set a {}
+    set i 1
+    while {$i <= 4} {
+	if {$i == 3} break
+	set a [concat $a $i]
+        incr i
+    }
+    return $a
+} -cleanup {
+    unset a i
+} -result {1 2}
+test while-3.2 {break tests, nested loops} -body {
+    set msg {}
+    set i 1
+    while {$i <= 4} {
+        set a 1
+	while {$a <= 2} {
+            if {$i>=2 && $a>=2} break
+            set msg [concat $msg "$i.$a"]
+            incr a
+        }
+        incr i
+    }
+    return $msg
+} -cleanup {
+    unset a i msg
+} -result {1.1 1.2 2.1 3.1 4.1}
+test while-3.3 {break tests, long command body} -body {
+    set a {}
+    set i 1
+    while {$i<6} {
+	if $i==2 {incr i; continue}
+	if $i==5 break
+	if $i>5 continue
+	if {$i>6 && $tcl_platform(machine)=="xxx"} {
+	    catch {set a $a} msg
+	    catch {incr i 5} msg
+	    catch {incr i -5} msg
+	}
+	if {$i>6 && $tcl_platform(machine)=="xxx"} {
+	    catch {set a $a} msg
+	    catch {incr i 5} msg
+	    catch {incr i -5} msg
+	}
+	if {$i>6 && $tcl_platform(machine)=="xxx"} {
+	    catch {set a $a} msg
+	    catch {incr i 5} msg
+	    catch {incr i -5} msg
+	}
+	if $i==4 break
+	if {$i>6 && $tcl_platform(machine)=="xxx"} {
+	    catch {set a $a} msg
+	    catch {incr i 5} msg
+	    catch {incr i -5} msg
+	}
+	if {$i>6 && $tcl_platform(machine)=="xxx"} {
+	    catch {set a $a} msg
+	    catch {incr i 5} msg
+	    catch {incr i -5} msg
+	}
+	set a [concat $a $i]
+        incr i
+    }
+    return $a
+} -cleanup {
+    unset a i
+} -result {1 3}
+
+# Check "while" with computed command names.
+
+test while-4.1 {while and computed command names} -body {
+    set i 0
+    set z while
+    $z {$i < 10} {
+        incr i
+    }
+    return $i
+} -cleanup {
+    unset i z
+} -result 10
+test while-4.2 {while (not compiled): missing test expression} -body {
+    set z while
+    $z
+} -returnCodes error -cleanup {
+    unset z
+} -result {wrong # args: should be "while test command"}
+test while-4.3 {while (not compiled): error in test expression} -body {
+    set i 0
+    set z while
+    catch {$z {$i<} {set x 1}}
+    return $::errorInfo
+} -match glob -cleanup {
+    unset i z
+} -result {*"$z {$i<} {set x 1}"}
+test while-4.4 {while (not compiled): error in test expression} -body {
+    set z while
+    $z {"a"+"b"} {error "loop aborted"}
+} -returnCodes error -result {can't use non-numeric string as operand of "+"}
+test while-4.5 {while (not compiled): multiline test expr} -body {
+    set value 1
+    set z while
+    $z {($tcl_platform(platform) != "foobar1") && \
+	    ($tcl_platform(platform) != "foobar2")} {
+        incr value
+        break
+    }
+    return $value
+} -cleanup {
+    unset value z
+} -result {2}
+test while-4.6 {while (not compiled): non-numeric boolean test expr} -body {
+    set value 1
+    set z while
+    $z {"true"} {
+	incr value;
+	if {$value > 5} {
+	    break;
+	}
+    }
+    return $value
+} -cleanup {
+    unset value z
+} -result 6
+test while-4.7 {while (not compiled): test expr is enclosed in quotes} -body {
+    set i 0
+    set z while
+    $z "$i > 5" {}
+} -cleanup {
+    unset i z
+} -result {}
+test while-4.8 {while (not compiled): missing command body} -body {
+    set i 0
+    set z while
+    $z {$i < 5}
+} -returnCodes error -cleanup {
+    unset i z
+} -result {wrong # args: should be "while test command"}
+test while-4.9 {while (not compiled): error compiling command body} -body {
+    set i 0
+    set z while
+    catch {$z {$i < 5} {set}}
+    set ::errorInfo
+} -match glob -cleanup {
+    unset i z
+} -result {wrong # args: should be "set varName ?newValue?"
+    while *ing
+"set"
+    ("while" body line 1)
+    invoked from within
+"$z {$i < 5} {set}"}
+test while-4.10 {while (not compiled): simple command body} -body {
+    set a {}
+    set i 1
+    set z while
+    $z {$i<6} {
+	if $i==4 break
+	set a [concat $a $i]
+        incr i
+    }
+    return $a
+} -cleanup {
+    unset a i z
+} -result {1 2 3}
+test while-4.11 {while (not compiled): command body in quotes} -body {
+    set a {}
+    set i 1
+    set z while
+    $z {$i<6} "append a x; incr i"
+    return $a
+} -cleanup {
+    unset a i z
+} -result {xxxxx}
+test while-4.12 {while (not compiled): computed command body} -setup {
+    catch {unset x1}
+    catch {unset bb}
+    catch {unset x2}
+} -body {
+    set z while
+    set x1 {append a x1; }
+    set bb {break}
+    set x2 {; append a x2; incr i}
+    set a {}
+    set i 1
+    $z {$i<6} $x1$bb$x2
+    return $a
+} -cleanup {
+    unset z x1 bb x2 a i
+} -result {x1}
+test while-4.13 {while (not compiled): long command body} -body {
+    set a {}
+    set z while
+    set i 1
+    $z {$i<6} {
+	if $i==4 break
+	if $i>5 continue
+	if {$i>6 && $tcl_platform(machine)=="xxx"} {
+	    catch {set a $a} msg
+	    catch {incr i 5} msg
+	    catch {incr i -5} msg
+	}
+	if {$i>6 && $tcl_platform(machine)=="xxx"} {
+	    catch {set a $a} msg
+	    catch {incr i 5} msg
+	    catch {incr i -5} msg
+	}
+	if {$i>6 && $tcl_platform(machine)=="xxx"} {
+	    catch {set a $a} msg
+	    catch {incr i 5} msg
+	    catch {incr i -5} msg
+	}
+	if {$i>6 && $tcl_platform(machine)=="xxx"} {
+	    catch {set a $a} msg
+	    catch {incr i 5} msg
+	    catch {incr i -5} msg
+	}
+	if {$i>6 && $tcl_platform(machine)=="xxx"} {
+	    catch {set a $a} msg
+	    catch {incr i 5} msg
+	    catch {incr i -5} msg
+	}
+	set a [concat $a $i]
+        incr i
+    }
+    return $a
+} -cleanup {
+    unset a i z
+} -result {1 2 3}
+test while-4.14 {while (not compiled): while command result} -body {
+    set i 0
+    set z while
+    set a [$z {$i < 5} {incr i}]
+    return $a
+} -cleanup {
+    unset a i z
+} -result {}
+test while-4.15 {while (not compiled): while command result} -body {
+    set i 0
+    set z while
+    set a [$z {$i < 5} {if $i==3 break; incr i}]
+    return $a
+} -cleanup {
+    unset a i z
+} -result {}
+
+# Check "break" with computed command names.
+
+test while-5.1 {break and computed command names} -body {
+    set i 0
+    set z break
+    while 1 {
+        if {$i > 10} $z
+        incr i
+    }
+    return $i
+} -cleanup {
+    unset i z
+} -result 11
+test while-5.2 {break tests with computed command names} -body {
+    set a {}
+    set i 1
+    set z break
+    while {$i <= 4} {
+	if {$i == 3} $z
+	set a [concat $a $i]
+        incr i
+    }
+    return $a
+} -cleanup {
+    unset a i z
+} -result {1 2}
+test while-5.3 {break tests, nested loops with computed command names} -body {
+    set msg {}
+    set i 1
+    set z break
+    while {$i <= 4} {
+        set a 1
+	while {$a <= 2} {
+            if {$i>=2 && $a>=2} $z
+            set msg [concat $msg "$i.$a"]
+            incr a
+        }
+        incr i
+    }
+    return $msg
+} -cleanup {
+    unset a i z msg
+} -result {1.1 1.2 2.1 3.1 4.1}
+test while-5.4 {break tests, long command body with computed command names} -body {
+    set a {}
+    set i 1
+    set z break
+    while {$i<6} {
+	if $i==2 {incr i; continue}
+	if $i==5 $z
+	if $i>5 continue
+	if {$i>6 && $tcl_platform(machine)=="xxx"} {
+	    catch {set a $a} msg
+	    catch {incr i 5} msg
+	    catch {incr i -5} msg
+	}
+	if {$i>6 && $tcl_platform(machine)=="xxx"} {
+	    catch {set a $a} msg
+	    catch {incr i 5} msg
+	    catch {incr i -5} msg
+	}
+	if {$i>6 && $tcl_platform(machine)=="xxx"} {
+	    catch {set a $a} msg
+	    catch {incr i 5} msg
+	    catch {incr i -5} msg
+	}
+	if $i==4 $z
+	if {$i>6 && $tcl_platform(machine)=="xxx"} {
+	    catch {set a $a} msg
+	    catch {incr i 5} msg
+	    catch {incr i -5} msg
+	}
+	if {$i>6 && $tcl_platform(machine)=="xxx"} {
+	    catch {set a $a} msg
+	    catch {incr i 5} msg
+	    catch {incr i -5} msg
+	}
+	set a [concat $a $i]
+        incr i
+    }
+    return $a
+} -cleanup {
+    unset a i z
+} -result {1 3}
+
+# Check "continue" with computed command names.
+
+test while-6.1 {continue and computed command names} -body {
+    set i 0
+    set z continue
+    while 1 {
+        incr i
+        if {$i < 10} $z
+        break
+    }
+    return $i
+} -cleanup {
+    unset i z
+} -result 10
+test while-6.2 {continue tests} -body {
+    set a {}
+    set i 1
+    set z continue
+    while {$i <= 4} {
+        incr i
+	if {$i == 3} $z
+	set a [concat $a $i]
+    }
+    return $a
+} -cleanup {
+    unset a i z
+} -result {2 4 5}
+test while-6.3 {continue tests with computed command names} -body {
+    set a {}
+    set i 1
+    set z continue
+    while {$i <= 4} {
+        incr i
+	if {$i != 2} $z
+	set a [concat $a $i]
+    }
+    return $a
+} -cleanup {
+    unset a i z
+} -result {2}
+test while-6.4 {continue tests, nested loops with computed command names} -body {
+    set msg {}
+    set i 1
+    set z continue
+    while {$i <= 4} {
+        incr i
+        set a 1
+	while {$a <= 2} {
+            incr a
+            if {$i>=3 && $a>=3} $z
+            set msg [concat $msg "$i.$a"]
+        }
+    }
+    return $msg
+} -cleanup {
+    unset a i z msg
+} -result {2.2 2.3 3.2 4.2 5.2}
+test while-6.5 {continue tests, long command body with computed command names} -body {
+    set a {}
+    set i 1
+    set z continue
+    while {$i<6} {
+	if $i==2 {incr i; continue}
+	if $i==4 break
+	if $i>5 $z
+	if {$i>6 && $tcl_platform(machine)=="xxx"} {
+	    catch {set a $a} msg
+	    catch {incr i 5} msg
+	    catch {incr i -5} msg
+	}
+	if {$i>6 && $tcl_platform(machine)=="xxx"} {
+	    catch {set a $a} msg
+	    catch {incr i 5} msg
+	    catch {incr i -5} msg
+	}
+	if {$i>6 && $tcl_platform(machine)=="xxx"} {
+	    catch {set a $a} msg
+	    catch {incr i 5} msg
+	    catch {incr i -5} msg
+	}
+	if {$i>6 && $tcl_platform(machine)=="xxx"} {
+	    catch {set a $a} msg
+	    catch {incr i 5} msg
+	    catch {incr i -5} msg
+	}
+	if {$i>6 && $tcl_platform(machine)=="xxx"} {
+	    catch {set a $a} msg
+	    catch {incr i 5} msg
+	    catch {incr i -5} msg
+	}
+	set a [concat $a $i]
+        incr i
+    }
+    return $a
+} -cleanup {
+    unset a i z
+} -result {1 3}
+
+# Test for incorrect "double evaluation" semantics
+
+test while-7.1 {delayed substitution of body} -body {
+    set i 0
+    while {[incr i] < 10} "
+       set result $i
+    "
+    proc p {} {
+	set i 0
+	while {[incr i] < 10} "
+	    set result $i
+	"
+	return $result
+    }
+    append result [p]
+} -cleanup {
+    unset result i
+} -result {00}
+
+# cleanup
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# fill-column: 78
+# End:
diff --git a/tests/winConsole.test b/tests/winConsole.test
new file mode 100644
index 0000000..fdde41c
--- /dev/null
+++ b/tests/winConsole.test
@@ -0,0 +1,48 @@
+# This file tests the tclWinConsole.c file.
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands.  Sourcing this file into Tcl runs the tests and
+# generates output for errors.  No output means no errors were found.
+#
+# Copyright (c) 1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+    package require tcltest
+    namespace import -force ::tcltest::*
+}
+
+
+test winConsole-1.1 {Console file channel: non-blocking gets} {win interactive} {
+    set oldmode [fconfigure stdin]
+
+    puts stdout "Enter abcdef<return> now: " nonewline
+    flush stdout
+    fileevent stdin readable {
+	if {[gets stdin line] >= 0} {
+	    set result $line
+	} else {
+	    set result "gets failed"
+	}
+    }
+
+    fconfigure stdin -blocking 0 -buffering line
+
+    set result {}
+    vwait result
+
+    #cleanup the fileevent
+    fileevent stdin readable {}
+    fconfigure stdin {*}$oldmode
+
+    set result
+
+}  "abcdef"
+
+#cleanup
+
+::tcltest::cleanupTests
+return
+
diff --git a/tests/winDde.test b/tests/winDde.test
new file mode 100644
index 0000000..f04fb45
--- /dev/null
+++ b/tests/winDde.test
@@ -0,0 +1,491 @@
+# This file tests the tclWinDde.c file.
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands.  Sourcing this file into Tcl runs the tests and
+# generates output for errors. No output means no errors were found.
+#
+# Copyright (c) 1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {"::tcltest" ni [namespace children]} {
+    package require tcltest 2
+    #tcltest::configure -verbose {pass start}
+    namespace import -force ::tcltest::*
+}
+
+testConstraint debug [::tcl::pkgconfig get debug]
+testConstraint dde 0
+if {[testConstraint win]} {
+    if {![catch {
+	    ::tcltest::loadTestedCommands
+	    set ::ddever [package require dde 1.4.0]
+	    set ::ddelib [lindex [package ifneeded dde $::ddever] 1]}]} {
+	testConstraint dde 1
+    }
+}
+
+
+# -------------------------------------------------------------------------
+# Setup a script for a test server
+#
+
+set scriptName [makeFile {} script1.tcl]
+
+proc createChildProcess {ddeServerName args} {
+    file delete -force $::scriptName
+
+    set f [open $::scriptName w+]
+    puts $f [list set ddeServerName $ddeServerName]
+    puts $f [list load $::ddelib dde]
+    puts $f {
+        # DDE child server -
+        #
+	if {"::tcltest" ni [namespace children]} {
+	    package require tcltest
+	    namespace import -force ::tcltest::*
+	}
+
+        # If an error occurs during the tests, this process may end up not
+        # being closed down. To deal with this we create a 30s timeout.
+        proc ::DoTimeout {} {
+            global done ddeServerName
+            set done 1
+            puts "winDde.test child process $ddeServerName timed out."
+            flush stdout
+        }
+        set timeout [after 30000 ::DoTimeout]
+
+        # Define a restricted handler.
+        proc Handler1 {cmd} {
+            if {$cmd eq "stop"} {set ::done 1}
+            if {$cmd == ""} {
+                set cmd "null data"
+            }
+            puts $cmd ; flush stdout
+            return
+        }
+        proc Handler2 {cmd} {
+            if {$cmd eq "stop"} {set ::done 1}
+            puts [uplevel \#0 $cmd] ; flush stdout
+            return
+        }
+        proc Handler3 {prefix cmd} {
+            if {$cmd eq "stop"} {set ::done 1}
+            puts [list $prefix $cmd] ; flush stdout
+            return
+        }
+    }
+    # set the dde server name to the supplied argument.
+    puts $f [list dde servername {*}$args -- $ddeServerName]
+    puts $f {
+        # run the server and handle final cleanup.
+        after 200;# give dde a chance to get going.
+	puts ready
+        flush stdout
+	vwait done
+	# allow enough time for the calling process to
+	# claim all results, to avoid spurious "server did
+	# not respond"
+	after 200 {set reallyDone 1}
+	vwait reallyDone
+	exit
+    }
+    close $f
+
+    # run the child server script.
+    set f [open |[list [interpreter] $::scriptName] r]
+    fconfigure $f -buffering line
+    gets $f line
+    return $f
+}
+
+# -------------------------------------------------------------------------
+test winDde-1.0 {check if we are testing the right dll} {win dde} {
+    set ::ddever
+} {1.4.0}
+
+test winDde-1.1 {Settings the server's topic name} -constraints dde -body {
+    list [dde servername foobar] [dde servername] [dde servername self]
+} -result {foobar foobar self}
+
+test winDde-2.1 {Checking for other services} -constraints dde -body {
+    expr [llength [dde services {} {}]] >= 0
+} -result 1
+test winDde-2.2 {Checking for existence, with service and topic specified} \
+	-constraints dde -body {
+    llength [dde services TclEval self]
+} -result 1
+test winDde-2.3 {Checking for existence, with only the service specified} \
+	-constraints dde -body {
+    expr [llength [dde services TclEval {}]] >= 1
+} -result 1
+test winDde-2.4 {Checking for existence, with only the topic specified} \
+	-constraints dde -body {
+    expr [llength [dde services {} self]] >= 1
+} -result 1
+
+# -------------------------------------------------------------------------
+
+test winDde-3.1 {DDE execute locally} -constraints dde -body {
+    set \xe1 ""
+    dde execute TclEval self [list set \xe1 foo]
+    set \xe1
+} -result foo
+test winDde-3.2 {DDE execute -async locally} -constraints dde -body {
+    set \xe1 ""
+    dde execute -async TclEval self [list set \xe1 foo]
+    update
+    set \xe1
+} -result foo
+test winDde-3.3 {DDE request locally} -constraints dde -body {
+    set \xe1 ""
+    dde execute TclEval self [list set \xe1 foo]
+    dde request TclEval self \xe1
+} -result foo
+test winDde-3.4 {DDE eval locally} -constraints dde -body {
+    set \xe1 ""
+    dde eval self set \xe1 foo
+} -result foo
+test winDde-3.5 {DDE request locally} -constraints dde -body {
+    set \xe1 ""
+    dde execute TclEval self [list set \xe1 foo]
+    dde request -binary TclEval self \xe1
+} -result "foo\x00"
+# Set variable a to A with diaeresis (unicode C4) by relying on the fact
+# that utf8 is sent (e.g. "c3 84" on the wire)
+test winDde-3.6 {DDE request utf8} -constraints dde -body {
+    set \xe1 "not set"
+    dde execute TclEval self "set \xe1 \xc4"
+    scan [set \xe1] %c
+} -result 196
+# Set variable a to A with diaeresis (unicode C4) using binary execute
+# and compose utf-8 (e.g. "c3 84" ) manualy
+test winDde-3.7 {DDE request binary} -constraints dde -body {
+    set \xe1 "not set"
+    dde execute -binary TclEval self [list set \xc3\xa1 \xc3\x84\x00]
+    scan [set \xe1] %c
+} -result 196
+test winDde-3.8 {DDE poke locally} -constraints {dde debug} -body {
+    set \xe1 ""
+    dde poke TclEval self \xe1 \xc4
+    dde request TclEval self \xe1
+} -result \xc4
+test winDde-3.9 {DDE poke -binary locally} -constraints {dde debug} -body {
+    set \xe1 ""
+    dde poke -binary TclEval self \xe1 \xc3\x84\x00
+    dde request TclEval self \xe1
+} -result \xc4
+
+# -------------------------------------------------------------------------
+
+test winDde-4.1 {DDE execute remotely} -constraints {dde stdio} -body {
+    set \xe1 ""
+    set name ch\xEDld-4.1
+    set child [createChildProcess $name]
+    dde execute TclEval $name [list set \xe1 foo]
+    dde execute TclEval $name {set done 1}
+    update
+    set \xe1
+} -result ""
+test winDde-4.2 {DDE execute async remotely} -constraints {dde stdio} -body {
+    set \xe1 ""
+    set name ch\xEDld-4.2
+    set child [createChildProcess $name]
+    dde execute -async TclEval $name [list set \xe1 foo]
+    update
+    dde execute TclEval $name {set done 1}
+    update
+    set \xe1
+} -result ""
+test winDde-4.3 {DDE request remotely} -constraints {dde stdio} -body {
+    set \xe1 ""
+    set name ch\xEDld-4.3
+    set child [createChildProcess $name]
+    dde execute TclEval $name [list set \xe1 foo]
+    set \xe1 [dde request TclEval $name \xe1]
+    dde execute TclEval $name {set done 1}
+    update
+    set \xe1
+} -result foo
+test winDde-4.4 {DDE eval remotely} -constraints {dde stdio} -body {
+    set \xe1 ""
+    set name ch\xEDld-4.4
+    set child [createChildProcess $name]
+    set \xe1 [dde eval $name set \xe1 foo]
+    dde execute TclEval $name {set done 1}
+    update
+    set \xe1
+}  -result foo
+test winDde-4.5 {DDE poke remotely} -constraints {dde debug stdio} -body {
+    set \xe1 ""
+    set name ch\xEDld-4.5
+    set child [createChildProcess $name]
+    dde poke TclEval $name \xe1 foo
+    set \xe1 [dde request TclEval $name \xe1]
+    dde execute TclEval $name {set done 1}
+    update
+    set \xe1
+} -result foo
+
+# -------------------------------------------------------------------------
+
+test winDde-5.1 {check for bad arguments} -constraints dde -body {
+    dde execute "" "" "" ""
+} -returnCodes error -result {wrong # args: should be "dde execute ?-async? ?-binary? serviceName topicName value"}
+test winDde-5.2 {check for bad arguments} -constraints dde -body {
+    dde execute -binary "" "" ""
+} -returnCodes error -result {cannot execute null data}
+test winDde-5.3 {check for bad arguments} -constraints dde -body {
+    dde execute -foo "" "" ""
+} -returnCodes error -result {wrong # args: should be "dde execute ?-async? ?-binary? serviceName topicName value"}
+test winDde-5.4 {DDE eval bad arguments} -constraints dde -body {
+    dde eval "" "foo"
+} -returnCodes error -result {invalid service name ""}
+
+# -------------------------------------------------------------------------
+
+test winDde-6.1 {DDE servername bad arguments} -constraints dde -body {
+    dde servername -z -z -z
+} -returnCodes error -result {bad option "-z": must be -force, -handler, or --}
+test winDde-6.2 {DDE servername set name} -constraints dde -body {
+    dde servername -- winDde-6.2
+} -result {winDde-6.2}
+test winDde-6.3 {DDE servername set exact name} -constraints dde -body {
+    dde servername -force winDde-6.3
+} -result {winDde-6.3}
+test winDde-6.4 {DDE servername set exact name} -constraints dde -body {
+    dde servername -force -- winDde-6.4
+} -result {winDde-6.4}
+test winDde-6.5 {DDE remote servername collision} -constraints {dde stdio} -setup {
+    set name ch\xEDld-6.5
+    set child [createChildProcess $name]
+} -body {
+    dde servername -- $name
+} -cleanup {
+    dde execute TclEval $name {set done 1}
+    update
+} -result "ch\xEDld-6.5 #2"
+test winDde-6.6 {DDE remote servername collision force} -constraints {dde stdio} -setup {
+    set name ch\xEDld-6.6
+    set child [createChildProcess $name]
+} -body {
+    dde servername -force -- $name
+} -cleanup {
+    dde execute TclEval $name {set done 1}
+    update
+} -result "ch\xEDld-6.6"
+
+# -------------------------------------------------------------------------
+
+test winDde-7.1 {Load DDE in slave interpreter} -constraints dde -setup {
+    interp create slave
+} -body {
+    slave eval [list load $::ddelib Dde]
+    slave eval [list dde servername -- dde-interp-7.1]
+} -cleanup {
+    interp delete slave
+} -result {dde-interp-7.1}
+test winDde-7.2 {DDE slave cleanup} -constraints dde -setup {
+    interp create slave
+    slave eval [list load $::ddelib Dde]
+    slave eval [list dde servername -- dde-interp-7.5]
+    interp delete slave
+} -body {
+    dde services TclEval {}
+    set s [dde services TclEval {}]
+    set m [list [list TclEval dde-interp-7.5]]
+    if {$m in $s} {
+	set s
+    }
+} -result {}
+test winDde-7.3 {DDE present in slave interp} -constraints dde -setup {
+    interp create slave
+    slave eval [list load $::ddelib Dde]
+    slave eval [list dde servername -- dde-interp-7.3]
+} -body {
+    dde services TclEval dde-interp-7.3
+} -cleanup {
+    interp delete slave
+} -result {{TclEval dde-interp-7.3}}
+test winDde-7.4 {interp name collision with -force} -constraints dde -setup {
+    interp create slave
+    slave eval [list load $::ddelib Dde]
+    slave eval [list dde servername -- dde-interp-7.4]
+} -body {
+    dde servername -force -- dde-interp-7.4
+} -cleanup {
+    interp delete slave
+} -result {dde-interp-7.4}
+test winDde-7.5 {interp name collision without -force} -constraints dde -setup {
+    interp create slave
+    slave eval [list load $::ddelib Dde]
+    slave eval [list dde servername -- dde-interp-7.5]
+} -body {
+    dde servername -- dde-interp-7.5
+} -cleanup {
+    interp delete slave
+} -result "dde-interp-7.5 #2"
+
+# -------------------------------------------------------------------------
+
+test winDde-8.1 {Safe DDE load} -constraints dde -setup {
+    interp create -safe slave
+    slave invokehidden load $::ddelib Dde
+} -body {
+    slave eval dde servername slave
+} -cleanup {
+    interp delete slave
+} -returnCodes error -result {invalid command name "dde"}
+test winDde-8.2 {Safe DDE set servername} -constraints dde -setup {
+    interp create -safe slave
+    slave invokehidden load $::ddelib Dde
+} -body {
+    slave invokehidden dde servername slave
+} -cleanup {interp delete slave} -result {slave}
+test winDde-8.3 {Safe DDE check handler required for eval} -constraints dde -setup {
+    interp create -safe slave
+    slave invokehidden load $::ddelib Dde
+    slave invokehidden dde servername slave
+} -body {
+    catch {dde eval slave set a 1} msg
+} -cleanup {interp delete slave} -result {1}
+test winDde-8.4 {Safe DDE check that execute is denied} -constraints dde -setup {
+    interp create -safe slave
+    slave invokehidden load $::ddelib Dde
+    slave invokehidden dde servername slave
+} -body {
+    slave eval set a 1
+    dde execute TclEval slave {set a 2}
+    slave eval set a
+} -cleanup {interp delete slave} -result 1
+test winDde-8.5 {Safe DDE check that request is denied} -constraints dde -setup {
+    interp create -safe slave
+    slave invokehidden load $::ddelib Dde
+    slave invokehidden dde servername slave
+} -body {
+    slave eval set a 1
+    dde request TclEval slave a
+} -cleanup {
+    interp delete slave
+} -returnCodes error -result {remote server cannot handle this command}
+test winDde-8.6 {Safe DDE assign handler procedure} -constraints dde -setup {
+    interp create -safe slave
+    slave invokehidden load $::ddelib Dde
+    slave eval {proc DDEACCEPT {cmd} {set ::DDECMD $cmd}}
+} -body {
+    slave invokehidden dde servername -handler DDEACCEPT slave
+} -cleanup {interp delete slave} -result slave
+test winDde-8.7 {Safe DDE check simple command} -constraints dde -setup {
+    interp create -safe slave
+    slave invokehidden load $::ddelib Dde
+    slave eval {proc DDEACCEPT {cmd} {set ::DDECMD $cmd}}
+    slave invokehidden dde servername -handler DDEACCEPT slave
+} -body {
+    dde eval slave set x 1
+} -cleanup {interp delete slave} -result {set x 1}
+test winDde-8.8 {Safe DDE check non-list command} -constraints dde -setup {
+    interp create -safe slave
+    slave invokehidden load $::ddelib Dde
+    slave eval {proc DDEACCEPT {cmd} {set ::DDECMD $cmd}}
+    slave invokehidden dde servername -handler DDEACCEPT slave
+} -body {
+    set s "c:\\Program Files\\Microsoft Visual Studio\\"
+    dde eval slave $s
+    string equal [slave eval set DDECMD] $s
+} -cleanup {interp delete slave} -result 1
+test winDde-8.9 {Safe DDE check command evaluation} -constraints dde -setup {
+    interp create -safe slave
+    slave invokehidden load $::ddelib Dde
+    slave eval {proc DDEACCEPT {cmd} {set ::DDECMD [uplevel \#0 $cmd]}}
+    slave invokehidden dde servername -handler DDEACCEPT slave
+} -body {
+    dde eval slave set \xe1 1
+    slave eval set \xe1
+} -cleanup {interp delete slave} -result 1
+test winDde-8.10 {Safe DDE check command evaluation (2)} -constraints dde -setup {
+    interp create -safe slave
+    slave invokehidden load $::ddelib Dde
+    slave eval {proc DDEACCEPT {cmd} {set ::DDECMD [uplevel \#0 $cmd]}}
+    slave invokehidden dde servername -handler DDEACCEPT slave
+} -body {
+    dde eval slave [list set x 1]
+    slave eval set x
+} -cleanup {interp delete slave} -result 1
+test winDde-8.11 {Safe DDE check command evaluation (3)} -constraints dde -setup {
+    interp create -safe slave
+    slave invokehidden load $::ddelib Dde
+    slave eval {proc DDEACCEPT {cmd} {set ::DDECMD [uplevel \#0 $cmd]}}
+    slave invokehidden dde servername -handler DDEACCEPT slave
+} -body {
+    dde eval slave [list [list set x 1]]
+    slave eval set x
+} -cleanup {interp delete slave} -returnCodes error -result {invalid command name "set x 1"}
+
+# -------------------------------------------------------------------------
+
+test winDde-9.1 {External safe DDE check string passing} -constraints {dde stdio} -setup {
+    set name ch\xEDld-9.1
+    set child [createChildProcess $name -handler Handler1]
+    file copy -force script1.tcl dde-script.tcl
+} -body {
+    dde eval $name set x 1
+    gets $child line
+    set line
+} -cleanup {
+    dde execute TclEval $name stop
+    update
+    file delete -force -- dde-script.tcl
+} -result {set x 1}
+test winDde-9.2 {External safe DDE check command evaluation} -constraints {dde stdio} -setup {
+    set name ch\xEDld-9.2
+    set child [createChildProcess $name -handler Handler2]
+    file copy -force script1.tcl dde-script.tcl
+} -body {
+    dde eval $name set x 1
+    gets $child line
+    set line
+} -cleanup {
+    dde execute TclEval $name stop
+    update
+    file delete -force -- dde-script.tcl
+} -result 1
+test winDde-9.3 {External safe DDE check prefixed arguments} -constraints {dde stdio} -setup {
+    set name ch\xEDld-9.3
+    set child [createChildProcess $name -handler [list Handler3 ARG]]
+    file copy -force script1.tcl dde-script.tcl
+} -body {
+    dde eval $name set x 1
+    gets $child line
+    set line
+} -cleanup {
+    dde execute TclEval $name stop
+    update
+    file delete -force -- dde-script.tcl
+} -result {ARG {set x 1}}
+test winDde-9.4 {External safe DDE check null data passing} -constraints {dde stdio} -setup {
+    set name ch\xEDld-9.4
+    set child [createChildProcess $name -handler Handler1]
+    file copy -force script1.tcl dde-script.tcl
+} -body {
+    dde execute TclEval $name ""
+    gets $child line
+    set line
+} -cleanup {
+    dde execute TclEval $name stop
+    update
+    file delete -force -- dde-script.tcl
+} -result {null data}
+
+# -------------------------------------------------------------------------
+
+#cleanup
+#catch {interp delete $slave};           # ensure we clean up the slave.
+file delete -force $::scriptName
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/tests/winFCmd.test b/tests/winFCmd.test
new file mode 100644
index 0000000..a808c82
--- /dev/null
+++ b/tests/winFCmd.test
@@ -0,0 +1,1465 @@
+# This file tests the tclWinFCmd.c file.
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands.  Sourcing this file into Tcl runs the tests and
+# generates output for errors.  No output means no errors were found.
+#
+# Copyright (c) 1996-1997 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+    package require tcltest
+    namespace import -force ::tcltest::*
+}
+
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
+
+# Initialise the test constraints
+
+testConstraint winVista 0
+testConstraint win2000orXP 0
+testConstraint winOlderThan2000 0
+testConstraint testvolumetype [llength [info commands testvolumetype]]
+testConstraint testfile       [llength [info commands testfile]]
+testConstraint testchmod      [llength [info commands testchmod]]
+testConstraint cdrom 0
+testConstraint exdev 0
+testConstraint longFileNames 0
+
+proc createfile {file {string a}} {
+    set f [open $file w]
+    puts -nonewline $f $string
+    close $f
+    return $string
+}
+
+proc contents {file} {
+    set f [open $file r]
+    set r [read $f]
+    close $f
+    set r
+}
+
+proc cleanup {args} {
+    foreach p ". $args" {
+	set x ""
+	catch {
+	    set x [glob -directory $p tf* td*]
+	}
+	if {$x != ""} {
+	    catch {file delete -force -- {*}$x}
+	}
+    }
+}
+
+if {[testConstraint winOnly]} {
+    set major [string index $tcl_platform(osVersion) 0]
+    if {[testConstraint nt] && $major > 4} {
+        if {$major > 5} {
+            testConstraint winVista 1
+        } elseif {$major == 5} {
+            testConstraint win2000orXP 1
+        }
+    } else {
+	testConstraint winOlderThan2000 1
+    }
+}
+
+# find a CD-ROM so we can test read-only filesystems.
+
+proc findfile {dir} {
+    foreach p [glob -nocomplain -type f -directory $dir *] {
+	return $p
+    }
+    foreach p [glob -nocomplain -type d -directory $dir *] {
+	set f [findfile $p]
+	if {$f ne ""} {
+	    return $f
+	}
+    }
+    return ""
+}
+
+if {[testConstraint testvolumetype]} {
+    foreach p {d e f g h i j k l m n o p q r s t u v w x y z} {
+        if {![catch {testvolumetype ${p}:} result] && $result in {CDFS UDF}} {
+            set cdrom ${p}:
+	    set cdfile [findfile $cdrom]
+	    testConstraint cdrom 1
+	    break
+        }
+    }
+}
+
+# NB: filename is chosen to be short but unlikely to clash with other apps
+if {[file exists c:/] && [file exists d:/]} {
+    catch {file delete d:/TclTmpF.1}
+    if {[catch {createfile d:/TclTmpF.1 {}}] == 0} {
+	file delete d:/TclTmpF.1
+	testConstraint exdev 1
+    }
+}
+
+file delete -force -- td1
+if {![catch {open td1 w} testfile]} {
+    close $testfile
+    testConstraint longFileNames 1
+    file delete -force -- td1
+}
+
+# A really long file name
+# length of longname is 1216 chars, which should be greater than any static
+# buffer or allowable filename.
+
+set longname "abcdefghihjllmnopqrstuvwxyz01234567890"
+append longname $longname
+append longname $longname
+append longname $longname
+append longname $longname
+append longname $longname
+
+# Uses the "testfile" command instead of the "file" command.  The "file"
+# command provides several layers of sanity checks on the arguments and
+# it can be difficult to actually forward "insane" arguments to the
+# low-level posix emulation layer.
+
+test winFCmd-1.1 {TclpRenameFile: errno: EACCES} -body {
+    testfile mv $cdfile $cdrom/dummy~~.fil
+} -constraints {win cdrom testfile} -returnCodes error -result EACCES
+test winFCmd-1.2 {TclpRenameFile: errno: EEXIST} -setup {
+    cleanup
+} -constraints {win testfile} -body {
+    file mkdir td1/td2/td3
+    file mkdir td2
+    testfile mv td2 td1/td2
+} -returnCodes error -result EEXIST
+test winFCmd-1.3 {TclpRenameFile: errno: EINVAL} -setup {
+    cleanup
+} -constraints {win testfile} -body {
+    testfile mv / td1
+} -returnCodes error -result EINVAL
+test winFCmd-1.4 {TclpRenameFile: errno: EINVAL} -setup {
+    cleanup
+} -constraints {win testfile} -body {
+    file mkdir td1
+    testfile mv td1 td1/td2
+} -returnCodes error -result EINVAL
+test winFCmd-1.5 {TclpRenameFile: errno: EISDIR} -setup {
+    cleanup
+} -constraints {win testfile} -body {
+    file mkdir td1
+    createfile tf1
+    testfile mv tf1 td1
+} -returnCodes error -result EISDIR
+test winFCmd-1.6 {TclpRenameFile: errno: ENOENT} -setup {
+    cleanup
+} -constraints {win testfile} -body {
+    testfile mv tf1 tf2
+} -returnCodes error -result ENOENT
+test winFCmd-1.7 {TclpRenameFile: errno: ENOENT} -setup {
+    cleanup
+} -constraints {win testfile} -body {
+    testfile mv "" tf2
+} -returnCodes error -result ENOENT
+test winFCmd-1.8 {TclpRenameFile: errno: ENOENT} -setup {
+    cleanup
+} -constraints {win testfile} -body {
+    createfile tf1
+    testfile mv tf1 ""
+} -returnCodes error -result ENOENT
+test winFCmd-1.9 {TclpRenameFile: errno: ENOTDIR} -setup {
+    cleanup
+} -constraints {win testfile} -body {
+    file mkdir td1
+    createfile tf1
+    testfile mv td1 tf1
+} -returnCodes error -result ENOTDIR
+test winFCmd-1.10 {TclpRenameFile: errno: EXDEV} -setup {
+    file delete -force d:/tf1
+} -constraints {win exdev testfile} -body {
+    file mkdir c:/tf1
+    testfile mv c:/tf1 d:/tf1
+} -cleanup {
+    file delete -force c:/tf1
+} -returnCodes error -result EXDEV
+test winFCmd-1.11 {TclpRenameFile: errno: EACCES} -setup {
+    cleanup
+} -constraints {win testfile} -body {
+    set fd [open tf1 w]
+    testfile mv tf1 tf2
+} -cleanup {
+    catch {close $fd}
+} -returnCodes error -result EACCES
+test winFCmd-1.12 {TclpRenameFile: errno: EACCES} -setup {
+    cleanup
+} -constraints {win testfile} -body {
+    createfile tf1
+    set fd [open tf2 w]
+    testfile mv tf1 tf2
+} -cleanup {
+    catch {close $fd}
+} -returnCodes error -result EACCES
+test winFCmd-1.13 {TclpRenameFile: errno: EACCES} -setup {
+    cleanup
+} -constraints {win win2000orXP testfile} -body {
+    testfile mv nul tf1
+} -returnCodes error -result EINVAL
+test winFCmd-1.14 {TclpRenameFile: errno: EACCES} -setup {
+    cleanup
+} -constraints {win nt winOlderThan2000 testfile} -body {
+    testfile mv nul tf1
+} -returnCodes error -result EACCES
+test winFCmd-1.15 {TclpRenameFile: errno: EEXIST} -setup {
+    cleanup
+} -constraints {win nt testfile} -body {
+    createfile tf1
+    testfile mv tf1 nul
+} -returnCodes error -result EEXIST
+test winFCmd-1.16 {TclpRenameFile: MoveFile() != FALSE} -setup {
+    cleanup
+} -constraints {win testfile} -body {
+    createfile tf1 tf1
+    testfile mv tf1 tf2
+    list [file exists tf1] [contents tf2]
+} -result {0 tf1}
+test winFCmd-1.17 {TclpRenameFile: MoveFile() == FALSE} -setup {
+    cleanup
+} -constraints {win testfile} -body {
+    testfile mv tf1 tf2
+} -returnCodes error -result ENOENT
+test winFCmd-1.18 {TclpRenameFile: srcAttr == -1} -setup {
+    cleanup
+} -constraints {win testfile} -body {
+    testfile mv tf1 tf2
+} -returnCodes error -result ENOENT
+test winFCmd-1.19 {TclpRenameFile: errno == EACCES} -setup {
+    cleanup
+} -constraints {win win2000orXP testfile} -body {
+    testfile mv nul tf1
+} -returnCodes error -result EINVAL
+test winFCmd-1.19.1 {TclpRenameFile: errno == EACCES} -setup {
+    cleanup
+} -constraints {win nt winOlderThan2000 testfile} -body {
+    testfile mv nul tf1
+} -returnCodes error -result EACCES
+test winFCmd-1.20 {TclpRenameFile: src is dir} -setup {
+    cleanup
+} -constraints {win nt testfile} -body {
+    # under 95, this would actually succeed and move the current dir out from
+    # under the current process!
+    file delete /tf1
+    testfile mv [pwd] /tf1
+} -returnCodes error -result EACCES
+test winFCmd-1.21 {TclpRenameFile: long src} -setup {
+    cleanup
+} -constraints {win testfile} -body {
+    testfile mv $longname tf1
+} -returnCodes error -result ENAMETOOLONG
+test winFCmd-1.22 {TclpRenameFile: long dst} -setup {
+    cleanup
+} -constraints {win testfile} -body {
+    createfile tf1
+    testfile mv tf1 $longname
+} -returnCodes error -result ENAMETOOLONG
+test winFCmd-1.23 {TclpRenameFile: move dir into self} -setup {
+    cleanup
+} -constraints {win testfile} -body {
+    file mkdir td1
+    testfile mv [pwd]/td1 td1/td2
+} -returnCodes error -result EINVAL
+test winFCmd-1.24 {TclpRenameFile: move a root dir} -setup {
+    cleanup
+} -constraints {win testfile} -body {
+    testfile mv / c:/
+} -returnCodes error -result EINVAL
+test winFCmd-1.25 {TclpRenameFile: cross file systems} -setup {
+    cleanup
+} -constraints {win cdrom testfile} -body {
+    file mkdir td1
+    testfile mv td1 $cdrom/td1
+} -returnCodes error -result EXDEV
+test winFCmd-1.26 {TclpRenameFile: readonly fs} -setup {
+    cleanup
+} -constraints {win cdrom testfile} -body {
+    testfile mv $cdfile $cdrom/dummy~~.fil
+} -returnCodes error -result EACCES
+test winFCmd-1.27 {TclpRenameFile: open file} -setup {
+    cleanup
+} -constraints {win testfile} -body {
+    set fd [open tf1 w]
+    testfile mv tf1 tf2
+} -cleanup {
+    catch {close $fd}
+} -returnCodes error -result EACCES
+test winFCmd-1.28 {TclpRenameFile: errno == EEXIST} -setup {
+    cleanup
+} -constraints {win testfile} -body {
+    createfile tf1
+    createfile tf2
+    testfile mv tf1 tf2
+    list [file exists tf1] [file exists tf2]
+} -result {0 1}
+test winFCmd-1.29 {TclpRenameFile: src is dir} -setup {
+    cleanup
+} -constraints {win testfile} -body {
+    file mkdir td1
+    createfile tf1
+    testfile mv td1 tf1
+} -returnCodes error -result ENOTDIR
+test winFCmd-1.30 {TclpRenameFile: dst is dir} -setup {
+    cleanup
+} -constraints {win testfile} -body {
+    file mkdir td1
+    file mkdir td2/td2
+    testfile mv td1 td2
+} -returnCodes error -result EEXIST
+test winFCmd-1.31 {TclpRenameFile: TclpRemoveDirectory fails} -setup {
+    cleanup
+} -constraints {win testfile} -body {
+    file mkdir td1
+    file mkdir td2/td2
+    testfile mv td1 td2
+} -returnCodes error -result EEXIST
+test winFCmd-1.32 {TclpRenameFile: TclpRemoveDirectory succeeds} -setup {
+    cleanup
+} -constraints {win testfile} -body {
+    file mkdir td1/td2
+    file mkdir td2
+    testfile mv td1 td2
+    list [file exists td1] [file exists td2] [file exists td2/td2]
+} -result {0 1 1}
+test winFCmd-1.33 {TclpRenameFile: After removing dst dir, MoveFile fails} \
+	-constraints {win exdev testfile testchmod} -body {
+    file mkdir d:/td1
+    testchmod 0 d:/td1
+    file mkdir c:/tf1
+    catch {testfile mv c:/tf1 d:/td1} msg
+    list $msg [file writable d:/td1]
+} -cleanup {
+    catch {testchmod 0o666 d:/td1}
+    file delete d:/td1
+    file delete -force c:/tf1
+} -result {EXDEV 0}
+test winFCmd-1.34 {TclpRenameFile: src is dir, dst is not} -setup {
+    cleanup
+} -constraints {win testfile} -body {
+    file mkdir td1
+    createfile tf1
+    testfile mv td1 tf1
+} -cleanup {
+    cleanup
+} -returnCodes error -result ENOTDIR
+test winFCmd-1.35 {TclpRenameFile: src is not dir, dst is} -setup {
+    cleanup
+} -constraints {win testfile} -body {
+    file mkdir td1
+    createfile tf1
+    testfile mv tf1 td1
+} -cleanup {
+    cleanup
+} -returnCodes error -result EISDIR
+test winFCmd-1.36 {TclpRenameFile: src and dst not dir} -setup {
+    cleanup
+} -constraints {win testfile} -body {
+    createfile tf1 tf1
+    createfile tf2 tf2
+    testfile mv tf1 tf2
+    contents tf2
+} -cleanup {
+    cleanup
+} -result {tf1}
+test winFCmd-1.37 {TclpRenameFile: need to restore temp file} {win emptyTest} {
+    # Can't figure out how to cause this.
+    # Need a file that can't be copied.
+} {}
+
+# If the native filesystem produces 0 for inodes numbers there is no point
+# doing the following test.
+testConstraint winNonZeroInodes [eval {
+    file stat [info nameofexecutable] statExe
+    expr {$statExe(ino) != 0}
+}]
+
+proc MakeFiles {dirname} {
+    set inodes {}
+    set ndx -1
+    while {1} {
+        # upped to 50K for 64bit Server 2008
+        if {$ndx > 50000} {
+            return -code error "limit reached without finding a collistion."
+        }
+        set filename [file join $dirname Test[incr ndx]]
+        set f [open $filename w]
+        close $f
+        file stat $filename stat
+        if {[set n [lsearch -exact -integer $inodes $stat(ino)]] != -1} {
+            return [list [file join $dirname Test$n] $filename]
+        }
+        lappend inodes $stat(ino)
+        unset stat
+    }
+}
+
+test winFCmd-1.38 {TclpRenameFile: check rename of conflicting inodes} -setup {
+    cleanup
+} -constraints {win winNonZeroInodes} -body {
+    file mkdir td1
+    foreach {a b} [MakeFiles td1] break
+    file rename -force $a $b
+    file exists $a
+} -cleanup {
+    cleanup
+} -result {0}
+
+
+test winFCmd-2.1 {TclpCopyFile: errno: EACCES} -setup {
+    cleanup
+} -constraints {win cdrom testfile} -body {
+    testfile cp $cdfile $cdrom/dummy~~.fil
+} -returnCodes error -result EACCES
+test winFCmd-2.2 {TclpCopyFile: errno: EISDIR} -setup {
+    cleanup
+} -constraints {win testfile} -body {
+    file mkdir td1
+    testfile cp td1 tf1
+} -cleanup {
+    cleanup
+} -returnCodes error -result EISDIR
+test winFCmd-2.3 {TclpCopyFile: errno: EISDIR} -setup {
+    cleanup
+} -constraints {win testfile} -body {
+    createfile tf1
+    file mkdir td1
+    testfile cp tf1 td1
+} -cleanup {
+    cleanup
+} -returnCodes error -result EISDIR
+test winFCmd-2.4 {TclpCopyFile: errno: ENOENT} -setup {
+    cleanup
+} -constraints {win testfile} -body {
+    testfile cp tf1 tf2
+} -returnCodes error -result ENOENT
+test winFCmd-2.5 {TclpCopyFile: errno: ENOENT} -setup {
+    cleanup
+} -constraints {win testfile} -body {
+    testfile cp "" tf2
+} -returnCodes error -result ENOENT
+test winFCmd-2.6 {TclpCopyFile: errno: ENOENT} -setup {
+    cleanup
+} -constraints {win testfile} -body {
+    createfile tf1
+    testfile cp tf1 ""
+} -cleanup {
+    cleanup
+} -returnCodes error -result ENOENT
+test winFCmd-2.7 {TclpCopyFile: errno: EACCES} -setup {
+    cleanup
+} -constraints {win win2000orXP testfile} -body {
+    testfile cp nul tf1
+} -returnCodes error -result EINVAL
+test winFCmd-2.8 {TclpCopyFile: errno: EACCES} -setup {
+    cleanup
+} -constraints {win nt winOlderThan2000 testfile} -body {
+    testfile cp nul tf1
+} -returnCodes error -result EACCES
+test winFCmd-2.10 {TclpCopyFile: CopyFile succeeds} -setup {
+    cleanup
+} -constraints {win testfile} -body {
+    createfile tf1 tf1
+    testfile cp tf1 tf2
+    list [contents tf1] [contents tf2]
+} -cleanup {
+    cleanup
+} -result {tf1 tf1}
+test winFCmd-2.11 {TclpCopyFile: CopyFile succeeds} -setup {
+    cleanup
+} -constraints {win testfile} -body {
+    createfile tf1 tf1
+    createfile tf2 tf2
+    testfile cp tf1 tf2
+    list [contents tf1] [contents tf2]
+} -cleanup {
+    cleanup
+} -result {tf1 tf1}
+test winFCmd-2.12 {TclpCopyFile: CopyFile succeeds} -setup {
+    cleanup
+} -constraints {win testfile} -body {
+    createfile tf1 tf1
+    testchmod 0 tf1
+    testfile cp tf1 tf2
+    list [contents tf2] [file writable tf2]
+} -cleanup {
+    catch {testchmod 0o666 tf1}
+    cleanup
+} -result {tf1 0}
+test winFCmd-2.13 {TclpCopyFile: CopyFile fails} -setup {
+    cleanup
+} -constraints {win testfile} -body {
+    createfile tf1
+    file mkdir td1
+    testfile cp tf1 td1
+} -cleanup {
+    cleanup
+} -returnCodes error -result EISDIR
+test winFCmd-2.14 {TclpCopyFile: errno == EACCES} -setup {
+    cleanup
+} -constraints {win testfile} -body {
+    file mkdir td1
+    testfile cp td1 tf1
+} -cleanup {
+    cleanup
+} -returnCodes error -result EISDIR
+test winFCmd-2.15 {TclpCopyFile: src is directory} -setup {
+    cleanup
+} -constraints {win testfile} -body {
+    file mkdir td1
+    testfile cp td1 tf1
+} -cleanup {
+    cleanup
+} -returnCodes error -result EISDIR
+test winFCmd-2.16 {TclpCopyFile: dst is directory} -setup {
+    cleanup
+} -constraints {win testfile} -body {
+    createfile tf1
+    file mkdir td1
+    testfile cp tf1 td1
+} -cleanup {
+    cleanup
+} -returnCodes error -result EISDIR
+test winFCmd-2.17 {TclpCopyFile: dst is readonly} -setup {
+    cleanup
+} -constraints {win testfile testchmod} -body {
+    createfile tf1 tf1
+    createfile tf2 tf2
+    testchmod 0 tf2
+    testfile cp tf1 tf2
+    list [file writable tf2] [contents tf2]
+} -cleanup {
+    catch {testchmod 0o666 tf2}
+    cleanup
+} -result {1 tf1}
+
+test winFCmd-3.1 {TclpDeleteFile: errno: EACCES} -body {
+    testfile rm $cdfile $cdrom/dummy~~.fil
+} -constraints {win cdrom testfile} -returnCodes error -result EACCES
+test winFCmd-3.2 {TclpDeleteFile: errno: EISDIR} -setup {
+    cleanup
+} -constraints {win testfile} -body {
+    file mkdir td1
+    testfile rm td1
+} -cleanup {
+    cleanup
+} -returnCodes error -result EISDIR
+test winFCmd-3.3 {TclpDeleteFile: errno: ENOENT} -setup {
+    cleanup
+} -constraints {win testfile} -body {
+    testfile rm tf1
+} -returnCodes error -result ENOENT
+test winFCmd-3.4 {TclpDeleteFile: errno: ENOENT} -setup {
+    cleanup
+} -constraints {win testfile} -body {
+    testfile rm ""
+} -returnCodes error -result ENOENT
+test winFCmd-3.5 {TclpDeleteFile: errno: EACCES} -setup {
+    cleanup
+} -constraints {win testfile} -body {
+    set fd [open tf1 w]
+    testfile rm tf1
+} -cleanup {
+    close $fd
+    cleanup
+} -returnCodes error -result EACCES
+test winFCmd-3.6 {TclpDeleteFile: errno: EACCES} -setup {
+    cleanup
+} -constraints {win testfile} -body {
+    testfile rm nul
+} -returnCodes error -result EACCES
+test winFCmd-3.7 {TclpDeleteFile: DeleteFile succeeds} -setup {
+    cleanup
+} -constraints {win testfile} -body {
+    createfile tf1
+    testfile rm tf1
+    file exists tf1
+} -result {0}
+test winFCmd-3.8 {TclpDeleteFile: DeleteFile fails} -setup {
+    cleanup
+} -constraints {win testfile} -body {
+    file mkdir td1
+    testfile rm td1
+} -cleanup {
+    cleanup
+} -returnCodes error -result EISDIR
+test winFCmd-3.9 {TclpDeleteFile: errno == EACCES} -setup {
+    cleanup
+} -constraints {win testfile} -body {
+    set fd [open tf1 w]
+    testfile rm tf1
+} -cleanup {
+    close $fd
+} -returnCodes error -result EACCES
+test winFCmd-3.10 {TclpDeleteFile: path is readonly} -setup {
+    cleanup
+} -constraints {win testfile testchmod} -body {
+    createfile tf1
+    testchmod 0 tf1
+    testfile rm tf1
+    file exists tf1
+} -result {0}
+test winFCmd-3.11 {TclpDeleteFile: still can't remove path} -setup {
+    cleanup
+} -constraints {win testfile testchmod} -body {
+    set fd [open tf1 w]
+    testchmod 0 tf1
+    testfile rm tf1
+} -cleanup {
+    close $fd
+    catch {testchmod 0o666 tf1}
+    cleanup
+} -returnCodes error -result EACCES
+
+test winFCmd-4.1 {TclpCreateDirectory: errno: EACCES} -body {
+    testfile mkdir $cdrom/dummy~~.dir
+} -constraints {win nt cdrom testfile} -returnCodes error -result EACCES
+test winFCmd-4.3 {TclpCreateDirectory: errno: EEXIST} -setup {
+    cleanup
+} -constraints {win testfile} -body {
+    file mkdir td1
+    testfile mkdir td1
+} -cleanup {
+    cleanup
+} -returnCodes error -result EEXIST
+test winFCmd-4.4 {TclpCreateDirectory: errno: ENOENT} -setup {
+    cleanup
+} -constraints {win testfile} -body {
+    testfile mkdir td1/td2
+} -returnCodes error -result ENOENT
+test winFCmd-4.5 {TclpCreateDirectory: CreateDirectory succeeds} -setup {
+    cleanup
+} -constraints {win testfile} -body {
+    testfile mkdir td1
+    file type td1
+} -cleanup cleanup -result directory
+
+test winFCmd-5.1 {TclpCopyDirectory: calls TraverseWinTree} -setup {
+    cleanup
+} -constraints {win testfile} -body {
+    file mkdir td1
+    testfile cpdir td1 td2
+    list [file type td1] [file type td2]
+} -cleanup {
+    cleanup
+} -result {directory directory}
+
+test winFCmd-6.1 {TclpRemoveDirectory: errno: EACCES} -setup {
+    cleanup
+} -constraints {winVista testfile testchmod} -body {
+    file mkdir td1
+    testchmod 0 td1
+    testfile rmdir td1
+    file exists td1
+} -returnCodes error -cleanup {
+    catch {testchmod 0o666 td1}
+    cleanup
+} -result {td1 EACCES}
+# This next test has a very hokey way of matching...
+test winFCmd-6.2 {TclpRemoveDirectory: errno: EEXIST} -setup {
+    cleanup
+} -constraints {win testfile} -body {
+    file mkdir td1/td2
+    list [catch {testfile rmdir td1} msg] [file tail $msg]
+} -result {1 {td1 EEXIST}}
+test winFCmd-6.3 {TclpRemoveDirectory: errno: EACCES} {win emptyTest} {
+    # can't test this w/o removing everything on your hard disk first!
+    # testfile rmdir /
+} {}
+# This next test has a very hokey way of matching...
+test winFCmd-6.4 {TclpRemoveDirectory: errno: ENOENT} -setup {
+    cleanup
+} -constraints {win testfile} -body {
+    list [catch {testfile rmdir td1} msg] [file tail $msg]
+} -result {1 {td1 ENOENT}}
+test winFCmd-6.5 {TclpRemoveDirectory: errno: ENOENT} -setup {
+    cleanup
+} -constraints {win testfile} -body {
+    testfile rmdir ""
+} -returnCodes error -result ENOENT
+# This next test has a very hokey way of matching...
+test winFCmd-6.6 {TclpRemoveDirectory: errno: ENOTDIR} -setup {
+    cleanup
+} -constraints {win testfile} -body {
+    createfile tf1
+    list [catch {testfile rmdir tf1} msg] [file tail $msg]
+} -result {1 {tf1 ENOTDIR}}
+test winFCmd-6.7 {TclpRemoveDirectory: RemoveDirectory succeeds} -setup {
+    cleanup
+} -constraints {win testfile} -body {
+    file mkdir td1
+    testfile rmdir td1
+    file exists td1
+} -result {0}
+# This next test has a very hokey way of matching...
+test winFCmd-6.8 {TclpRemoveDirectory: RemoveDirectory fails} -setup {
+    cleanup
+} -constraints {win testfile} -body {
+    createfile tf1
+    list [catch {testfile rmdir tf1} msg] [file tail $msg]
+} -result {1 {tf1 ENOTDIR}}
+test winFCmd-6.9 {TclpRemoveDirectory: errno == EACCES} -setup {
+    cleanup
+} -constraints {winVista testfile testchmod} -body {
+    file mkdir td1
+    testchmod 0 td1
+    testfile rmdir td1
+    file exists td1
+} -returnCodes error -cleanup {
+    catch {testchmod 0o666 td1}
+    cleanup
+} -result {td1 EACCES}
+test winFCmd-6.11 {TclpRemoveDirectory: attr == -1} -setup {
+    cleanup
+} -constraints {win nt testfile} -body {
+    testfile rmdir /
+    # WinXP returns EEXIST, WinNT seems to return EACCES.  No policy
+    # decision has been made as to which is correct.
+} -returnCodes error -match regexp -result {^/ E(ACCES|EXIST)$}
+test winFCmd-6.13 {TclpRemoveDirectory: write-protected} -setup {
+    cleanup
+} -constraints {winVista testfile testchmod} -body {
+    file mkdir td1
+    testchmod 0 td1
+    testfile rmdir td1
+    file exists td1
+} -cleanup {
+    catch {testchmod 0o666 td1}
+    cleanup
+} -returnCodes error -result {td1 EACCES}
+# This next test has a very hokey way of matching...
+test winFCmd-6.15 {TclpRemoveDirectory: !recursive} -setup {
+    cleanup
+} -constraints {win testfile} -body {
+    file mkdir td1/td2
+    list [catch {testfile rmdir td1} msg] [file tail $msg]
+} -result {1 {td1 EEXIST}}
+test winFCmd-6.16 {TclpRemoveDirectory: recursive, but errno != EEXIST} -setup {
+    cleanup
+} -constraints {win testfile} -body {
+    createfile tf1
+    testfile rmdir -force tf1
+} -returnCodes error -result {tf1 ENOTDIR}
+test winFCmd-6.17 {TclpRemoveDirectory: calls TraverseWinTree} -setup {
+    cleanup
+} -constraints {win testfile} -body {
+    file mkdir td1/td2
+    testfile rmdir -force td1
+    file exists td1
+} -result {0}
+
+test winFCmd-7.1 {TraverseWinTree: targetPtr == NULL} -setup {
+    cleanup
+} -constraints {win testfile} -body {
+    file mkdir td1/td2/td3
+    testfile rmdir -force td1
+    file exists td1
+} -result {0}
+test winFCmd-7.2 {TraverseWinTree: targetPtr != NULL} -setup {
+    cleanup
+} -constraints {win testfile} -body {
+    file mkdir td1/td2/td3
+    testfile cpdir td1 td2
+    list [file exists td1] [file exists td2]
+} -cleanup {
+    cleanup
+} -result {1 1}
+test winFCmd-7.3 {TraverseWinTree: sourceAttr == -1} -setup {
+    cleanup
+} -constraints {win testfile} -body {
+    testfile cpdir td1 td2
+} -returnCodes error -result {td1 ENOENT}
+test winFCmd-7.4 {TraverseWinTree: source isn't directory} -setup {
+    cleanup
+} -constraints {win testfile} -body {
+    file mkdir td1
+    createfile td1/tf1 tf1
+    testfile cpdir td1 td2
+    contents td2/tf1
+} -cleanup {
+    cleanup
+} -result {tf1}
+test winFCmd-7.5 {TraverseWinTree: call TraversalCopy: DOTREE_F} -setup {
+    cleanup
+} -constraints {win testfile} -body {
+    file mkdir td1
+    createfile td1/tf1 tf1
+    testfile cpdir td1 td2
+    contents td2/tf1
+} -cleanup {
+    cleanup
+} -result {tf1}
+test winFCmd-7.6 {TraverseWinTree: call TraversalDelete: DOTREE_F} -setup {
+    cleanup
+} -constraints {win testfile} -body {
+    file mkdir td1
+    createfile td1/tf1 tf1
+    testfile rmdir -force td1
+    file exists td1
+} -result {0}
+test winFCmd-7.7 {TraverseWinTree: append \ to source if necessary} -setup {
+    cleanup
+} -constraints {win testfile} -body {
+    file mkdir td1
+    createfile td1/tf1 tf1
+    testfile cpdir td1 td2
+    contents td2/tf1
+} -cleanup {
+    cleanup
+} -result {tf1}
+test winFCmd-7.9 {TraverseWinTree: append \ to source if necessary} -body {
+    testfile rmdir $cdrom/
+} -constraints {win nt cdrom testfile} -returnCodes error -match glob \
+    -result {* EACCES}
+test winFCmd-7.10 {TraverseWinTree: can't read directory: handle == INVALID} \
+	{win emptyTest} {
+    # can't make it happen
+} {}
+test winFCmd-7.11 {TraverseWinTree: call TraversalCopy: DOTREE_PRED} -setup {
+    cleanup
+} -constraints {win testfile testchmod} -body {
+    file mkdir td1
+    createfile td1/tf1 tf1
+    testchmod 0 td1
+    testfile cpdir td1 td2
+    list [file exists td2] [file writable td2]
+} -cleanup {
+    catch {testchmod 0o666 td1}
+    cleanup
+} -result {1 1}
+test winFCmd-7.12 {TraverseWinTree: call TraversalDelete: DOTREE_PRED} -setup {
+    cleanup
+} -constraints {win testfile} -body {
+    file mkdir td1
+    createfile td1/tf1 tf1
+    testfile rmdir -force td1
+    file exists td1
+} -result {0}
+test winFCmd-7.13 {TraverseWinTree: append \ to target if necessary} -setup {
+    cleanup
+} -constraints {win testfile} -body {
+    file mkdir td1
+    createfile td1/tf1 tf1
+    testfile cpdir td1 td2
+    contents td2/tf1
+} -cleanup {
+    cleanup
+} -result {tf1}
+test winFCmd-7.15 {TraverseWinTree: append \ to target if necessary} -setup {
+    cleanup
+} -constraints {win nt testfile} -body {
+    file mkdir td1
+    testfile cpdir td1 /
+} -cleanup {
+    cleanup
+    # Windows7 returns EEXIST, XP returns EACCES
+} -returnCodes error -match regexp -result {^/ E(ACCES|EXIST)$}
+test winFCmd-7.16 {TraverseWinTree: recurse on files: no files} -setup {
+    cleanup
+} -constraints {win testfile} -body {
+    file mkdir td1
+    testfile cpdir td1 td2
+} -cleanup {
+    cleanup
+} -result {}
+test winFCmd-7.17 {TraverseWinTree: recurse on files: one file} -setup {
+    cleanup
+} -constraints {win testfile} -body {
+    file mkdir td1
+    createfile td1/td2
+    testfile cpdir td1 td2
+    glob td2/*
+} -cleanup {
+    cleanup
+} -result {td2/td2}
+test winFCmd-7.18 {TraverseWinTree: recurse on files: several files and dir} -setup {
+    cleanup
+} -constraints {win testfile} -body {
+    file mkdir td1
+    createfile td1/tf1
+    createfile td1/tf2
+    file mkdir td1/td2/td3
+    createfile td1/tf3
+    createfile td1/tf4
+    testfile cpdir td1 td2
+    lsort [glob td2/*]
+} -cleanup {
+    cleanup
+} -result {td2/td2 td2/tf1 td2/tf2 td2/tf3 td2/tf4}
+test winFCmd-7.19 {TraverseWinTree: call TraversalCopy: DOTREE_POSTD} -setup {
+    cleanup
+} -constraints {win testfile testchmod} -body {
+    file mkdir td1
+    createfile td1/tf1 tf1
+    testchmod 0 td1
+    testfile cpdir td1 td2
+    list [file exists td2] [file writable td2]
+} -cleanup {
+    catch {testchmod 0o666 td1}
+    cleanup
+} -result {1 1}
+test winFCmd-7.20 {TraverseWinTree: call TraversalDelete: DOTREE_POSTD} -setup {
+    cleanup
+} -constraints {win testfile} -body {
+    file mkdir td1
+    createfile td1/tf1 tf1
+    testfile rmdir -force td1
+    file exists td1
+} -result {0}
+test winFCmd-7.21 {TraverseWinTree: fill errorPtr} -setup {
+    cleanup
+} -constraints {win testfile} -body {
+    testfile cpdir td1 td2
+} -returnCodes error -result {td1 ENOENT}
+
+test winFCmd-8.1 {TraversalCopy: DOTREE_F} -setup {
+    cleanup
+} -constraints {win testfile} -body {
+    file mkdir td1
+    testfile cpdir td1 td1
+} -returnCodes error -result {td1 EEXIST}
+test winFCmd-8.2 {TraversalCopy: DOTREE_PRED} -setup {
+    cleanup
+} -constraints {win testfile testchmod} -body {
+    file mkdir td1/td2
+    testchmod 0 td1
+    testfile cpdir td1 td2
+    list [file writable td1] [file writable td1/td2]
+} -cleanup {
+    catch {testchmod 0o666 td1}
+    cleanup
+} -result {0 1}
+test winFCmd-8.3 {TraversalCopy: DOTREE_POSTD} -setup {
+    cleanup
+} -constraints {win testfile} -body {
+    file mkdir td1
+    testfile cpdir td1 td2
+} -cleanup {
+    cleanup
+} -result {}
+
+test winFCmd-9.1 {TraversalDelete: DOTREE_F} -setup {
+    cleanup
+} -constraints {win testfile} -body {
+    file mkdir td1
+    createfile td1/tf1
+    testfile rmdir -force td1
+} -result {}
+test winFCmd-9.3 {TraversalDelete: DOTREE_PRED} -setup {
+    cleanup
+} -constraints {winVista testfile testchmod} -body {
+    file mkdir td1/td2
+    testchmod 0 td1
+    testfile rmdir -force td1
+    file exists td1
+} -cleanup {
+    catch {testchmod 0o666 td1}
+    cleanup
+} -returnCodes error -result {td1 EACCES}
+test winFCmd-9.4 {TraversalDelete: DOTREE_POSTD} -setup {
+    cleanup
+} -constraints {win testfile} -body {
+    file mkdir td1/td1/td3/td4/td5
+    testfile rmdir -force td1
+} -result {}
+
+test winFCmd-10.1 {AttributesPosixError - get} -constraints {win} -setup {
+    cleanup
+} -body {
+    file attributes td1 -archive
+} -returnCodes error -result {could not read "td1": no such file or directory}
+test winFCmd-10.2 {AttributesPosixError - set} -constraints {win} -setup {
+    cleanup
+} -body {
+    file attributes td1 -archive 0
+} -returnCodes error -result {could not read "td1": no such file or directory}
+
+test winFCmd-11.1 {GetWinFileAttributes} -constraints {win} -setup {
+    cleanup
+} -body {
+    createfile td1 {}
+    file attributes td1 -archive
+} -cleanup {
+    cleanup
+} -result 1
+test winFCmd-11.2 {GetWinFileAttributes} -constraints {win} -setup {
+    cleanup
+} -body {
+    createfile td1 {}
+    file attributes td1 -readonly
+} -cleanup {
+    cleanup
+} -result 0
+test winFCmd-11.3 {GetWinFileAttributes} -constraints {win} -setup {
+    cleanup
+} -body {
+    createfile td1 {}
+    file attributes td1 -hidden
+} -cleanup {
+    cleanup
+} -result 0
+test winFCmd-11.4 {GetWinFileAttributes} -constraints {win} -setup {
+    cleanup
+} -body {
+    createfile td1 {}
+    file attributes td1 -system
+} -cleanup {
+    cleanup
+} -result 0
+test winFCmd-11.5 {GetWinFileAttributes} -constraints {win} -setup {
+    set old [pwd]
+} -body {
+    # Attr of relative paths that resolve to root was failing don't care about
+    # answer, just that test runs.
+    cd c:/
+    file attr c:
+    file attr c:.
+    file attr .
+} -cleanup {
+    cd $old
+} -match glob -result *
+test winFCmd-11.6 {GetWinFileAttributes} -constraints {win} -body {
+    file attr c:/ -hidden
+} -result {0}
+
+test winFCmd-12.1 {ConvertFileNameFormat} -constraints {win} -setup {
+    cleanup
+} -body {
+    createfile td1 {}
+    string tolower [file attributes td1 -longname]
+} -cleanup {
+    cleanup
+} -result {td1}
+test winFCmd-12.2 {ConvertFileNameFormat} -constraints {win} -setup {
+    cleanup
+} -body {
+    file mkdir td1
+    createfile td1/td1 {}
+    string tolower [file attributes td1/td1 -longname]
+} -cleanup {
+    cleanup
+} -result {td1/td1}
+test winFCmd-12.3 {ConvertFileNameFormat} -constraints {win} -setup {
+    cleanup
+} -body {
+    file mkdir td1
+    file mkdir td1/td2
+    createfile td1/td3 {}
+    string tolower [file attributes td1/td2/../td3 -longname]
+} -cleanup {
+    cleanup
+} -result {td1/td2/../td3}
+test winFCmd-12.4 {ConvertFileNameFormat} -constraints {win} -setup {
+    cleanup
+} -body {
+    createfile td1 {}
+    string tolower [file attributes ./td1 -longname]
+} -cleanup {
+    cleanup
+} -result {./td1}
+test winFCmd-12.5 {ConvertFileNameFormat: absolute path} -body {
+    list [file attributes / -longname] [file attributes \\ -longname]
+} -constraints {win} -result {/ /}
+test winFCmd-12.6 {ConvertFileNameFormat: absolute path with drive} -setup {
+    catch {file delete -force -- c:/td1}
+} -constraints {win win2000orXP} -body {
+    createfile c:/td1 {}
+    string tolower [file attributes c:/td1 -longname]
+} -cleanup {
+    file delete -force -- c:/td1
+} -result {c:/td1}
+test winFCmd-12.7 {ConvertFileNameFormat} -body {
+    string tolower [file attributes //bisque/tcl/ws -longname]
+} -constraints {nonPortable win} -result {//bisque/tcl/ws}
+test winFCmd-12.8 {ConvertFileNameFormat} -setup {
+    cleanup
+} -constraints {win longFileNames} -body {
+    createfile td1 {}
+    string tolower [file attributes td1 -longname]
+} -cleanup {
+    cleanup
+} -result {td1}
+test winFCmd-12.10 {ConvertFileNameFormat} -setup {
+    cleanup
+} -constraints {longFileNames win} -body {
+    createfile td1td1td1 {}
+    file attributes td1td1td1 -shortname
+} -cleanup {
+    cleanup
+} -match glob -result *
+test winFCmd-12.11 {ConvertFileNameFormat} -setup {
+    cleanup
+} -constraints {longFileNames win} -body {
+    createfile td1 {}
+    string tolower [file attributes td1 -shortname]
+} -cleanup {
+    cleanup
+} -result {td1}
+
+test winFCmd-13.1 {GetWinFileLongName} -constraints {win} -setup {
+    cleanup
+} -body {
+    createfile td1 {}
+    string tolower [file attributes td1 -longname]
+} -cleanup {
+    cleanup
+} -result td1
+
+test winFCmd-14.1 {GetWinFileShortName} -constraints {win} -setup {
+    cleanup
+} -body {
+    createfile td1 {}
+    string tolower [file attributes td1 -shortname]
+} -cleanup {
+    cleanup
+} -result td1
+
+test winFCmd-15.1 {SetWinFileAttributes} -constraints {win} -setup {
+    cleanup
+} -body {
+    file attributes td1 -archive 0
+} -returnCodes error -result {could not read "td1": no such file or directory}
+test winFCmd-15.2 {SetWinFileAttributes - archive} -constraints {win} -setup {
+    cleanup
+} -body {
+    createfile td1 {}
+    list [file attributes td1 -archive 1] [file attributes td1 -archive]
+} -cleanup {
+    cleanup
+} -result {{} 1}
+test winFCmd-15.3 {SetWinFileAttributes - archive} -constraints {win} -setup {
+    cleanup
+} -body {
+    createfile td1 {}
+    list [file attributes td1 -archive 0] [file attributes td1 -archive]
+} -cleanup {
+    cleanup
+} -result {{} 0}
+test winFCmd-15.4 {SetWinFileAttributes - hidden} -constraints {win} -setup {
+    cleanup
+} -body {
+    createfile td1 {}
+    list [file attributes td1 -hidden 1] [file attributes td1 -hidden] \
+	[file attributes td1 -hidden 0]
+} -cleanup {
+    cleanup
+} -result {{} 1 {}}
+test winFCmd-15.5 {SetWinFileAttributes - hidden} -constraints {win} -setup {
+    cleanup
+} -body {
+    createfile td1 {}
+    list [file attributes td1 -hidden 0] [file attributes td1 -hidden]
+} -cleanup {
+    cleanup
+} -result {{} 0}
+test winFCmd-15.6 {SetWinFileAttributes - readonly} -setup {
+    cleanup
+} -constraints {win} -body {
+    createfile td1 {}
+    list [file attributes td1 -readonly 1] [file attributes td1 -readonly]
+} -cleanup {
+    cleanup
+} -result {{} 1}
+test winFCmd-15.7 {SetWinFileAttributes - readonly} -setup {
+    cleanup
+} -constraints {win} -body {
+    createfile td1 {}
+    list [file attributes td1 -readonly 0] [file attributes td1 -readonly]
+} -cleanup {
+    cleanup
+} -result {{} 0}
+test winFCmd-15.8 {SetWinFileAttributes - system} -constraints {win} -setup {
+    cleanup
+} -body {
+    createfile td1 {}
+    list [file attributes td1 -system 1] [file attributes td1 -system]
+} -cleanup {
+    cleanup
+} -result {{} 1}
+test winFCmd-15.9 {SetWinFileAttributes - system} -constraints {win} -setup {
+    cleanup
+} -body {
+    createfile td1 {}
+    list [file attributes td1 -system 0] [file attributes td1 -system]
+} -cleanup {
+    cleanup
+} -result {{} 0}
+test winFCmd-15.10 {SetWinFileAttributes - failing} -setup {
+    cleanup
+} -constraints {win cdrom} -body {
+    file attributes $cdfile -archive 1
+} -returnCodes error -match glob -result *
+
+test winFCmd-16.1 {Windows file normalization} -constraints {win} -body {
+    list [file normalize c:/] [file normalize C:/]
+} -result {C:/ C:/}
+test winFCmd-16.2 {Windows file normalization} -constraints {win} -body {
+    createfile td1... {}
+    file tail [file normalize td1]
+} -cleanup {
+    file delete td1...
+} -result {td1}
+set pwd [pwd]
+set d [string index $pwd 0]
+test winFCmd-16.3 {Windows file normalization} -constraints {win} -body {
+    file norm ${d}:foo
+} -result [file join $pwd foo]
+test winFCmd-16.4 {Windows file normalization} -constraints {win} -body {
+    file norm [string tolower ${d}]:foo
+} -result [file join $pwd foo]
+test winFCmd-16.5 {Windows file normalization} -constraints {win} -body {
+    file norm ${d}:foo/bar
+} -result [file join $pwd foo/bar]
+test winFCmd-16.6 {Windows file normalization} -constraints {win} -body {
+    file norm ${d}:foo\\bar
+} -result [file join $pwd foo/bar]
+test winFCmd-16.7 {Windows file normalization} -constraints {win} -body {
+    file norm /bar
+} -result "${d}:/bar"
+test winFCmd-16.8 {Windows file normalization} -constraints {win} -body {
+    file norm ///bar
+} -result "${d}:/bar"
+test winFCmd-16.9 {Windows file normalization} -constraints {win} -body {
+    file norm /bar/foo
+} -result "${d}:/bar/foo"
+if {$d eq "C"} { set dd "D" } else { set dd "C" }
+test winFCmd-16.10 {Windows file normalization} -constraints {win} -body {
+    file norm ${dd}:foo
+} -result "${dd}:/foo"
+test winFCmd-16.11 {Windows file normalization} -body {
+    cd ${d}:
+    cd $cdrom
+    cd ${d}:
+    cd $cdrom
+    # Must not crash
+    set result "no crash"
+} -constraints {win cdrom} -cleanup {
+    cd $pwd
+} -result {no crash}
+test winFCmd-16.12 {Windows file normalization - no crash} \
+  -constraints win -setup {
+    set oldhome ""
+    catch {set oldhome $::env(HOME)}
+} -body {
+    set expectedResult [file normalize ${d}:]
+    set ::env(HOME) ${d}:
+    cd
+    # At one point this led to an infinite recursion in Tcl
+    set result [pwd]; # <- Must not crash
+    set result "no crash"
+} -cleanup {
+    set ::env(HOME) $oldhome
+    cd $pwd
+} -result {no crash}
+test winFCmd-16.13 {Windows file normalization - absolute HOME} -setup {
+    set oldhome ""
+    catch {set oldhome $::env(HOME)}
+} -constraints win -body {
+    # Test 'cd' normalization when HOME is absolute
+    set ::env(HOME) ${d}:/
+    cd
+    pwd
+} -cleanup {
+    set ::env(HOME) $oldhome
+    cd $pwd
+} -result [file normalize ${d}:/]
+test winFCmd-16.14 {Windows file normalization - relative HOME} -setup {
+    set oldhome ""
+    catch {set oldhome $::env(HOME)}
+} -constraints win -body {
+    # Test 'cd' normalization when HOME is relative
+    set ::env(HOME) ${d}:
+    cd
+    pwd
+} -cleanup {
+    set ::env(HOME) $oldhome
+    cd $pwd
+} -result $pwd
+
+test winFCmd-17.1 {Windows bad permissions cd} -constraints win -body {
+    set d {}
+    foreach dd {c:/ d:/ e:/} {
+	eval lappend d [glob -nocomplain \
+	  -types hidden -dir $dd "System Volume Information"]
+    }
+    # Old versions of Tcl gave a misleading error that the
+    # directory in question didn't exist.
+    if {[llength $d] && [catch {cd [lindex $d 0]} err]} {
+	regsub ".*: " $err "" err
+	set err
+    } else {
+        set err "permission denied"
+    }
+} -cleanup {
+    cd $pwd
+} -result "permission denied"
+
+cd $pwd
+unset d dd pwd
+
+test winFCmd-18.1 {Windows reserved path names} -constraints win -body {
+    file pathtype com1
+} -result "absolute"
+test winFCmd-18.1.2 {Windows reserved path names} -constraints win -body {
+    file pathtype com4
+} -result "absolute"
+test winFCmd-18.1.3 {Windows reserved path names} -constraints win -body {
+    file pathtype com9
+} -result "absolute"
+test winFCmd-18.1.4 {Windows reserved path names} -constraints win -body {
+    file pathtype lpt3
+} -result "absolute"
+test winFCmd-18.1.5 {Windows reserved path names} -constraints win -body {
+    file pathtype lpt9
+} -result "absolute"
+test winFCmd-18.1.6 {Windows reserved path names} -constraints win -body {
+    file pathtype nul
+} -result "absolute"
+test winFCmd-18.1.7 {Windows reserved path names} -constraints win -body {
+    file pathtype null
+} -result "relative"
+test winFCmd-18.2 {Windows reserved path names} -constraints win -body {
+    file pathtype com1:
+} -result "absolute"
+test winFCmd-18.3 {Windows reserved path names} -constraints win -body {
+    file pathtype COM1
+} -result "absolute"
+test winFCmd-18.4 {Windows reserved path names} -constraints win -body {
+    file pathtype CoM1:
+} -result "absolute"
+test winFCmd-18.5 {Windows reserved path names} -constraints win -body {
+    file normalize com1:
+} -result COM1
+test winFCmd-18.6 {Windows reserved path names} -constraints win -body {
+    file normalize COM1:
+} -result COM1
+test winFCmd-18.7 {Windows reserved path names} -constraints win -body {
+    file normalize cOm1
+} -result COM1
+test winFCmd-18.8 {Windows reserved path names} -constraints win -body {
+    file normalize cOm1:
+} -result COM1
+
+test winFCmd-19.1 {Windows extended path names} -constraints nt -body {
+    file normalize //?/c:/windows/win.ini
+} -result //?/c:/windows/win.ini
+test winFCmd-19.2 {Windows extended path names} -constraints nt -body {
+    file normalize //?/c:/windows/../windows/win.ini
+} -result //?/c:/windows/win.ini
+test winFCmd-19.3 {Windows extended path names} -constraints nt -setup {
+    set tmpfile [file join $::env(TEMP) tcl[string repeat x 20].tmp]
+    set tmpfile [file normalize $tmpfile]
+} -body {
+    list [catch {
+        set f [open $tmpfile [list WRONLY CREAT]]
+        close $f
+    } res] $res
+} -cleanup {
+    catch {file delete $tmpfile}
+} -result [list 0 {}]
+test winFCmd-19.4 {Windows extended path names} -constraints nt -setup {
+    set tmpfile [file join $::env(TEMP) tcl[string repeat x 20].tmp]
+    set tmpfile //?/[file normalize $tmpfile]
+} -body {
+    list [catch {
+        set f [open $tmpfile [list WRONLY CREAT]]
+        close $f
+    } res] $res
+} -cleanup {
+    catch {file delete $tmpfile}
+} -result [list 0 {}]
+test winFCmd-19.5 {Windows extended path names} -constraints nt -setup {
+    set tmpfile [file join $::env(TEMP) tcl[string repeat x 248].tmp]
+    set tmpfile [file normalize $tmpfile]
+} -body {
+    list [catch {
+        set f [open $tmpfile [list WRONLY CREAT]]
+        close $f
+    } res] $res
+} -cleanup {
+    catch {file delete $tmpfile}
+} -result [list 0 {}]
+test winFCmd-19.6 {Windows extended path names} -constraints nt -setup {
+    set tmpfile [file join $::env(TEMP) tcl[string repeat x 248].tmp]
+    set tmpfile //?/[file normalize $tmpfile]
+} -body {
+    list [catch {
+        set f [open $tmpfile [list WRONLY CREAT]]
+        close $f
+    } res] $res
+} -cleanup {
+    catch {file delete $tmpfile}
+} -result [list 0 {}]
+test winFCmd-19.7 {Windows extended path names} -constraints nt -setup {
+    set tmpfile [file join $::env(TEMP) "tcl[pid].tmp "]
+    set tmpfile [file normalize $tmpfile]
+} -body {
+    list [catch {
+        set f [open $tmpfile [list WRONLY CREAT]]
+        close $f
+    } res] $res [glob -directory $::env(TEMP) -tails tcl[pid].*]
+} -cleanup {
+    catch {file delete $tmpfile}
+} -result [list 0 {} [list tcl[pid].tmp]]
+test winFCmd-19.8 {Windows extended path names} -constraints nt -setup {
+    set tmpfile [file join $::env(TEMP) "tcl[pid].tmp "]
+    set tmpfile //?/[file normalize $tmpfile]
+} -body {
+    list [catch {
+        set f [open $tmpfile [list WRONLY CREAT]]
+        close $f
+    } res] $res [glob -directory $::env(TEMP) -tails tcl[pid].*]
+} -cleanup {
+    catch {file delete $tmpfile}
+} -result [list 0 {} [list "tcl[pid].tmp "]]
+
+test winFCmd-19.9 {Windows devices path names} -constraints nt -body {
+    file normalize //./com1
+} -result //./com1
+
+
+# This block of code used to occur after the "return" call, so I'm
+# commenting it out and assuming that this code is still under construction.
+#foreach source {tef ted tnf tnd "" nul com1} {
+#    foreach chmodsrc {000 755} {
+#        foreach dest "tfn tfe tdn tdempty tdfull td1/td2 $p $p/td1 {} nul" {
+#	    foreach chmoddst {000 755} {
+#		puts hi
+#		cleanup
+#		file delete -force ted tef
+#		file mkdir ted
+#		createfile tef
+#		createfile tfe
+#		file mkdir tdempty
+#		file mkdir tdfull/td1/td2
+#
+#		catch {testchmod $chmodsrc $source}
+#		catch {testchmod $chmoddst $dest}
+#
+#		if [catch {file rename $source $dest} msg] {
+#		    puts "file rename $source ($chmodsrc) $dest ($chmoddst)"
+#		    puts $msg
+#		}
+#	    }
+#	}
+#    }
+#}
+
+# cleanup
+cleanup
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/tests/winFile.test b/tests/winFile.test
new file mode 100644
index 0000000..2c47f5f
--- /dev/null
+++ b/tests/winFile.test
@@ -0,0 +1,224 @@
+# This file tests the tclWinFile.c file.
+#
+# This file contains a collection of tests for one or more of the Tcl built-in
+# commands. Sourcing this file into Tcl runs the tests and generates output
+# for errors. No output means no errors were found.
+#
+# Copyright (c) 1997 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution of
+# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[catch {package require tcltest 2.0.2}]} {
+    puts stderr "Skipping tests in [info script]. tcltest 2.0.2 required."
+    return
+}
+namespace import -force ::tcltest::*
+
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
+
+testConstraint testvolumetype [llength [info commands testvolumetype]]
+testConstraint notNTFS 0
+testConstraint win2000 0
+
+if {[testConstraint testvolumetype]} {
+    testConstraint notNTFS [expr {[testvolumetype] eq "NTFS"}]
+}
+if {[testConstraint nt] && $::tcl_platform(osVersion) >= 5.0} {
+    testConstraint win2000 1
+}
+
+test winFile-1.1 {TclpGetUserHome} -constraints {win} -body {
+    glob ~nosuchuser
+} -returnCodes error -result {user "nosuchuser" doesn't exist}
+test winFile-1.2 {TclpGetUserHome} -constraints {win nt nonPortable} -body {
+    # The administrator account should always exist.
+    glob ~administrator
+} -match glob -result *
+test winFile-1.4 {TclpGetUserHome} {win nt nonPortable} {
+    catch {glob ~stanton@workgroup}
+} {0}
+
+test winFile-2.1 {TclpMatchFiles: case sensitivity} -constraints {win} -body {
+    makeFile {} GlobCapS
+    list [glob -nocomplain GlobC*] [glob -nocomplain globc*]
+} -cleanup {
+    removeFile GlobCapS
+} -result {GlobCapS GlobCapS}
+test winFile-2.2 {TclpMatchFiles: case sensitivity} -constraints {win} -body {
+    makeFile {} globlower
+    list [glob -nocomplain globl*] [glob -nocomplain gLOBl*]
+} -cleanup {
+    removeFile globlower
+} -result {globlower globlower}
+
+test winFile-3.1 {file system} -constraints {win testvolumetype} -setup {
+    set res ""
+} -body {
+    foreach vol [file volumes] {
+	# Have to catch in case there is a removable drive (CDROM, floppy)
+	# with nothing in it.
+	catch {
+	    if {[lindex [file system $vol] 1] ne [testvolumetype $vol]} {
+		append res "For $vol, we found [file system $vol]\
+			and [testvolumetype $vol] are different\n"
+	    }
+	}
+    }
+    set res
+} -result {}
+
+proc cacls {fname args} {
+    string trim [eval [list exec cacls [file nativename $fname]] $args <<y]
+}
+
+# dir/q output:
+# 2003-11-03  20:36                  598 OCTAVIAN\benny         filename.txt
+# Note this output from a german win2k machine:
+# 14.12.2007  14:26                   30 VORDEFINIERT\Administratest.dat
+#
+# Modified to cope with Msys environment and use ls -l.
+proc getuser {fname} {
+    global env
+    set tryname $fname
+    if {[file isdirectory $fname]} {
+	set tryname [file dirname $fname]
+    }
+    set owner ""
+    set tail [file tail $tryname]
+    if {[info exists env(OSTYPE)] && $env(OSTYPE) eq "msys"} {
+        set dirtext [exec ls -l $fname]
+        foreach line [split $dirtext "\n"] {
+            set owner [lindex $line 2]
+        }
+    } else {
+        set dirtext [exec cmd /c dir /q [file nativename $fname]]
+        foreach line [split $dirtext "\n"] {
+            if {[string match -nocase "*$tail" $line]} {
+                set attrs [string range $line 0 end-[string length $tail]]
+                regexp { [^ \\]+\\.*$} $attrs owner
+                set owner [string trim $owner]
+            }
+        }
+    }
+    if {$owner eq ""} {
+	error "getuser: Owner not found in output of dir/q"
+    }
+    return $owner
+}
+
+proc test_read {fname} {
+    if {[catch {open $fname r} ifs]} {
+	return 0
+    }
+    set readfailed [catch {read $ifs}]
+    return [expr {![catch {close $ifs}] && !$readfailed}]
+}
+
+proc test_writ {fname} {
+    if {[catch {open $fname w} ofs]} {
+	return 0
+    }
+    set writefailed [catch {puts $ofs "Hello"}]
+    return [expr {![catch {close $ofs}] && !$writefailed}]
+}
+
+proc test_access {fname read writ} {
+    set problem {}
+    foreach type {read writ} {
+	if {[set $type] != [file ${type}able $fname]} {
+	    lappend problem "[set $type] != \[file ${type}able $fname\]"
+	}
+	if {[set $type] != [test_${type} $fname]} {
+	    lappend problem "[set $type] != \[test_${type} $fname\]"
+	}
+    }
+    if {![llength $problem]} {
+	return
+    }
+    return "Problem [join $problem \n]\nActual rights are: [cacls $fname]"
+}
+
+if {[testConstraint win]} {
+    # Create the test file
+    # NOTE: [tcltest::makeFile] not used.  Presumably to force file
+    # creation in a particular filesystem?  If not, try [makeFile]
+    # in a -setup script.
+    set fname test.dat
+    file delete $fname
+    close [open $fname w]
+}
+
+test winFile-4.0 {
+    Enhanced NTFS user/group permissions: test no acccess
+} -constraints {
+    win nt notNTFS win2000
+} -setup {
+    set owner [getuser $fname]
+    set user $::env(USERDOMAIN)\\$::env(USERNAME)
+} -body {
+    # Clean out all well-known ACLs
+    catch {cacls $fname /E /R "Everyone"} result
+    catch {cacls $fname /E /R $user} result
+    catch {cacls $fname /E /R $owner} result
+    cacls $fname /E /P $user:N
+    test_access $fname 0 0
+} -result {}
+test winFile-4.1 {
+    Enhanced NTFS user/group permissions: test readable only
+} -constraints {
+    win nt notNTFS
+} -setup {
+    set user $::env(USERDOMAIN)\\$::env(USERNAME)
+} -body {
+    cacls $fname /E /P $user:N
+    cacls $fname /E /G $user:R
+    test_access $fname 1 0
+} -result {}
+test winFile-4.2 {
+    Enhanced NTFS user/group permissions: test writable only
+} -constraints {
+    win nt notNTFS
+} -setup {
+    set user $::env(USERDOMAIN)\\$::env(USERNAME)
+} -body {
+    catch {cacls $fname /E /R $user} result
+    cacls $fname /E /P $user:N
+    cacls $fname /E /G $user:W
+    test_access $fname 0 1
+} -result {}
+test winFile-4.3 {
+    Enhanced NTFS user/group permissions: test read+write
+} -constraints {
+    win nt notNTFS
+} -setup {
+    set user $::env(USERDOMAIN)\\$::env(USERNAME)
+} -body {
+    catch {cacls $fname /E /R $user} result
+    cacls $fname /E /P $user:N
+    cacls $fname /E /G $user:R
+    cacls $fname /E /G $user:W
+    test_access $fname 1 1
+} -result {}
+test winFile-4.4 {
+    Enhanced NTFS user/group permissions: test full access
+} -constraints {
+    win nt notNTFS
+} -setup {
+    set user $::env(USERDOMAIN)\\$::env(USERNAME)
+} -body {
+    catch {cacls $fname /E /R $user} result
+    cacls $fname /E /P $user:N
+    cacls $fname /E /G $user:F
+    test_access $fname 1 1
+} -result {}
+
+if {[testConstraint win]} {
+    file delete $fname
+}
+
+# cleanup
+cleanupTests
+return
diff --git a/tests/winNotify.test b/tests/winNotify.test
new file mode 100644
index 0000000..3e9aa29
--- /dev/null
+++ b/tests/winNotify.test
@@ -0,0 +1,162 @@
+# This file tests the tclWinNotify.c file.
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands.  Sourcing this file into Tcl runs the tests and
+# generates output for errors.  No output means no errors were found.
+#
+# Copyright (c) 1997 by Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+    package require tcltest
+    namespace import -force ::tcltest::*
+}
+
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
+
+testConstraint testeventloop [expr {[info commands testeventloop] != {}}]
+
+# There is no explicit test for InitNotifier or NotifierExitHandler
+
+test winNotify-1.1 {Tcl_SetTimer: positive timeout} {win} {
+    set done 0
+    after 1000 { set done 1 }
+    vwait done
+    set done
+} 1
+test winNotify-1.2 {Tcl_SetTimer: positive timeout, message pending} {win} {
+    set x 0
+    set y 1
+    set a1 [after 0 { incr y }]
+    after cancel $a1
+    after 500 { incr x }
+    vwait x
+    list $x $y
+} {1 1}
+test winNotify-1.3 {Tcl_SetTimer: cancelling positive timeout} {win} {
+    set x 0
+    set y 1
+    set id [after 10000 { incr y }]
+    after 0 { incr x }
+    vwait x
+    after cancel $id
+    list $x $y
+} {1 1}
+test winNotify-1.4 {Tcl_SetTimer: null timeout, message pending} {win} {
+    set x 0
+    set y 1
+    after 0 { incr x }
+    after 0 { incr y }
+    vwait x
+    list $x $y
+} {1 2}
+
+test winNotify-2.1 {Tcl_ResetIdleTimer} {win} {
+    set x 0
+    update
+    after idle { incr x }
+    vwait x
+    set x
+} 1
+test winNotify-2.2 {Tcl_ResetIdleTimer: message pending} {win} {
+    set x 0
+    set y 1
+    update
+    after idle { incr x }
+    after idle { incr y }
+    update
+    list $x $y
+} {1 2}
+
+test winNotify-3.1 {NotifierProc: non-modal normal timer} {win testeventloop} {
+    update
+    set x 0
+    foreach i [after info] {
+	after cancel $i
+    }
+    after 500 { incr x; testeventloop done }
+    testeventloop wait
+    set x
+} 1
+test winNotify-3.2 {NotifierProc: non-modal normal timer, rescheduled} {win testeventloop} {
+    update
+    set x 0
+    foreach i [after info] {
+	after cancel $i
+    }
+    after 500 { incr x; after 100 {incr x; testeventloop done }}
+    testeventloop wait
+    set x
+} 2
+test winNotify-3.3 {NotifierProc: modal normal timer} {win} {
+    update
+    set x 0
+    foreach i [after info] {
+	after cancel $i
+    }
+    after 500 { incr x }
+    vwait x
+    set x
+} 1
+test winNotify-3.4 {NotifierProc: modal normal timer, rescheduled} {win} {
+    update
+    set x 0
+    foreach i [after info] {
+	after cancel $i
+    }
+    set y 0
+    after 500 { incr y; after 100 {incr x}}
+    vwait x
+    list $x $y
+} {1 1}
+test winNotify-3.5 {NotifierProc: non-modal idle timer} {win testeventloop} {
+    update
+    set x 0
+    foreach i [after info] {
+	after cancel $i
+    }
+    after idle { incr x; testeventloop done }
+    testeventloop wait
+    set x
+} 1
+test winNotify-3.6 {NotifierProc: non-modal idle timer, rescheduled} {win testeventloop} {
+    update
+    set x 0
+    foreach i [after info] {
+	after cancel $i
+    }
+    after idle { incr x; after idle {incr x; testeventloop done }}
+    testeventloop wait
+    set x
+} 2
+test winNotify-3.7 {NotifierProc: modal idle timer} {win} {
+    update
+    set x 0
+    foreach i [after info] {
+	after cancel $i
+    }
+    after idle { incr x }
+    vwait x
+    set x
+} 1
+test winNotify-3.8 {NotifierProc: modal idle timer, rescheduled} {win} {
+    update
+    set x 0
+    foreach i [after info] {
+	after cancel $i
+    }
+    set y 0
+    after idle { incr y; after idle {incr x}}
+    vwait x
+    list $x $y
+} {1 1}
+
+# Tcl_DoOneEvent is tested by the timer.test, io.test, and event.test files
+
+# cleanup
+::tcltest::cleanupTests
+return
diff --git a/tests/winPipe.test b/tests/winPipe.test
new file mode 100644
index 0000000..9c6f94d
--- /dev/null
+++ b/tests/winPipe.test
@@ -0,0 +1,454 @@
+#
+# winPipe.test --
+#
+# This file contains a collection of tests for tclWinPipe.c
+#
+# Sourcing this file into Tcl runs the tests and generates output for errors.
+# No output (except for one message) means no errors were found.
+#
+# Copyright (c) 1996 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution of
+# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+package require tcltest
+namespace import -force ::tcltest::*
+unset -nocomplain path
+
+catch {
+    ::tcltest::loadTestedCommands
+    package require -exact Tcltest [info patchlevel]
+    set ::tcltestlib [lindex [package ifneeded Tcltest [info patchlevel]] 1]
+}
+
+set bindir [file join [pwd] [file dirname [info nameofexecutable]]]
+set cat32 [file join $bindir cat32.exe]
+
+testConstraint exec         [llength [info commands exec]]
+testConstraint cat32        [file exists $cat32]
+testConstraint AllocConsole [catch {puts console1 ""}]
+testConstraint RealConsole  [expr {![testConstraint AllocConsole]}]
+testConstraint testexcept   [llength [info commands testexcept]]
+
+
+set big bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\n
+append big $big
+append big $big	
+append big $big
+append big $big
+append big $big
+append big $big
+
+set path(little) [makeFile {} little]
+set f [open $path(little) w] 
+puts -nonewline $f "little"
+close $f
+
+set path(big) [makeFile {} big]
+set f [open $path(big) w]
+puts -nonewline $f $big
+close $f
+
+proc contents {file} {
+    set f [open $file r]
+    set r [read $f]
+    close $f
+    set r
+}
+
+set path(more) [makeFile {
+    while {[eof stdin] == 0} {
+	puts -nonewline [read stdin]
+    }
+} more]
+
+set path(stdout) [makeFile {} stdout]
+set path(stderr) [makeFile {} stderr]
+
+test winpipe-1.1 {32 bit comprehensive tests: from little file} {win exec cat32} {
+    exec $cat32 < $path(little) > $path(stdout) 2> $path(stderr)
+    list [contents $path(stdout)] [contents $path(stderr)]
+} {little stderr32}
+test winpipe-1.2 {32 bit comprehensive tests: from big file} {win exec cat32} {
+    exec $cat32 < $path(big) > $path(stdout) 2> $path(stderr)
+    list [contents $path(stdout)] [contents $path(stderr)]
+} "{$big} stderr32"
+test winpipe-1.3 {32 bit comprehensive tests: a little from pipe} {win nt exec cat32} {
+    exec [interpreter] $path(more) < $path(little) | $cat32 > $path(stdout) 2> $path(stderr)
+    list [contents $path(stdout)] [contents $path(stderr)]
+} {little stderr32}
+test winpipe-1.4 {32 bit comprehensive tests: a lot from pipe} {win nt exec cat32} {
+    exec [interpreter] $path(more) < $path(big) | $cat32 > $path(stdout) 2> $path(stderr)
+    list [contents $path(stdout)] [contents $path(stderr)]
+} "{$big} stderr32"
+test winpipe-1.6 {32 bit comprehensive tests: from console} \
+	{win cat32 AllocConsole} {
+    # would block waiting for human input
+} {}
+test winpipe-1.7 {32 bit comprehensive tests: from NUL} {win exec cat32} {
+    exec $cat32 < nul > $path(stdout) 2> $path(stderr)
+    list [contents $path(stdout)] [contents $path(stderr)]
+} {{} stderr32}
+test winpipe-1.8 {32 bit comprehensive tests: from socket} {win cat32} {
+    # doesn't work
+} {}
+test winpipe-1.9 {32 bit comprehensive tests: from nowhere} \
+	{win exec cat32 RealConsole} {
+    exec $cat32 > $path(stdout) 2> $path(stderr)
+    list [contents $path(stdout)] [contents $path(stderr)]
+} {{} stderr32}
+test winpipe-1.10 {32 bit comprehensive tests: from file handle} \
+	{win exec cat32} {
+    set f [open $path(little) r]
+    exec $cat32 <@$f > $path(stdout) 2> $path(stderr)
+    close $f
+    list [contents $path(stdout)] [contents $path(stderr)]
+} {little stderr32}
+test winpipe-1.11 {32 bit comprehensive tests: read from application} \
+	{win exec cat32} {
+    set f [open "|[list $cat32] < [list $path(little)]" r]
+    gets $f line
+    catch {close $f} msg
+    list $line $msg
+} {little stderr32}
+test winpipe-1.12 {32 bit comprehensive tests: a little to file} \
+	{win exec cat32} {
+    exec $cat32 < $path(little) > $path(stdout) 2> $path(stderr)
+    list [contents $path(stdout)] [contents $path(stderr)]
+} {little stderr32}
+test winpipe-1.13 {32 bit comprehensive tests: a lot to file} \
+	{win exec cat32} {
+    exec $cat32 < $path(big) > $path(stdout) 2> $path(stderr)
+    list [contents $path(stdout)] [contents $path(stderr)]
+} "{$big} stderr32"
+test winpipe-1.14 {32 bit comprehensive tests: a little to pipe} \
+	{win exec stdio cat32} {
+    exec $cat32 < $path(little) | [interpreter] $path(more) > $path(stdout) 2> $path(stderr)
+    list [contents $path(stdout)] [contents $path(stderr)]
+} {little stderr32}
+test winpipe-1.15 {32 bit comprehensive tests: a lot to pipe} \
+	{win exec stdio cat32} {
+    exec $cat32 < $path(big) | [interpreter] $path(more) > $path(stdout) 2> $path(stderr)
+    list [contents $path(stdout)] [contents $path(stderr)]
+} "{$big} stderr32"
+test winpipe-1.16 {32 bit comprehensive tests: to console} {win exec cat32} {
+    catch {exec $cat32 << "You should see this\n" >@stdout} msg
+    set msg
+} stderr32
+test winpipe-1.17 {32 bit comprehensive tests: to NUL} {win exec cat32} {
+    # some apps hang when sending a large amount to NUL.  $cat32 isn't one.
+    catch {exec $cat32 < $path(big) > nul} msg
+    set msg
+} stderr32
+test winpipe-1.18 {32 bit comprehensive tests: to nowhere} \
+	{win exec cat32 RealConsole} {
+    exec $cat32 < $path(big) >&@stdout
+} {}
+test winpipe-1.19 {32 bit comprehensive tests: to file handle} {win exec cat32} {
+    set f1 [open $path(stdout) w]
+    set f2 [open $path(stderr) w]
+    exec $cat32 < $path(little) >@$f1 2>@$f2
+    close $f1
+    close $f2
+    list [contents $path(stdout)] [contents $path(stderr)]
+} {little stderr32}
+test winpipe-1.20 {32 bit comprehensive tests: write to application} \
+	{win exec cat32} {
+    set f [open |[list $cat32 >$path(stdout)] w]
+    puts -nonewline $f "foo"
+    catch {close $f} msg
+    list [contents $path(stdout)] $msg
+} {foo stderr32}
+test winpipe-1.21 {32 bit comprehensive tests: read/write application} \
+	{win exec cat32} {
+    set f [open "|[list $cat32]" r+]
+    puts $f $big
+    puts $f \032
+    flush $f
+    set r [read $f 64]
+    catch {close $f}
+    set r
+} "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
+
+test winpipe-4.1 {Tcl_WaitPid} {win nt exec cat32} {
+    proc readResults {f} {
+	global x result
+	if { [eof $f] } {
+	    close $f
+	    set x 1
+	} else {
+	    set line [read $f ]
+	    set result "$result$line"
+	}
+    }
+    set f [open "|[list $cat32] < $path(big) 2> $path(stderr)" r]
+    fconfigure $f  -buffering none -blocking 0
+    fileevent $f readable "readResults $f"
+    set x 0
+    set result ""
+    vwait x
+    list $result $x [contents $path(stderr)]
+} "{$big} 1 stderr32"
+test winpipe-4.2 {Tcl_WaitPid: return of exception codes, SIGFPE} {win exec testexcept} {
+    set f [open "|[list [interpreter]]" w+]
+    set pid [pid $f]
+    puts $f "load $::tcltestlib Tcltest"
+    puts $f "testexcept float_underflow"
+    set status [catch {close $f}]
+    list $status [expr {$pid == [lindex $::errorCode 1]}] [lindex $::errorCode 2]
+} {1 1 SIGFPE}
+test winpipe-4.3 {Tcl_WaitPid: return of exception codes, SIGSEGV} {win exec testexcept} {
+    set f [open "|[list [interpreter]]" w+]
+    set pid [pid $f]
+    puts $f "load $::tcltestlib Tcltest"
+    puts $f "testexcept access_violation"
+    set status [catch {close $f}]
+    list $status [expr {$pid == [lindex $::errorCode 1]}] [lindex $::errorCode 2]
+} {1 1 SIGSEGV}
+test winpipe-4.4 {Tcl_WaitPid: return of exception codes, SIGILL} {win exec testexcept} {
+    set f [open "|[list [interpreter]]" w+]
+    set pid [pid $f]
+    puts $f "load $::tcltestlib Tcltest"
+    puts $f "testexcept illegal_instruction"
+    set status [catch {close $f}]
+    list $status [expr {$pid == [lindex $::errorCode 1]}] [lindex $::errorCode 2]
+} {1 1 SIGILL}
+test winpipe-4.5 {Tcl_WaitPid: return of exception codes, SIGINT} {win exec testexcept} {
+    set f [open "|[list [interpreter]]" w+]
+    set pid [pid $f]
+    puts $f "load $::tcltestlib Tcltest"
+    puts $f "testexcept ctrl+c"
+    set status [catch {close $f}]
+    list $status [expr {$pid == [lindex $::errorCode 1]}] [lindex $::errorCode 2]
+} {1 1 SIGINT}
+
+set path(nothing) [makeFile {} nothing]
+close [open $path(nothing) w]
+
+catch {set env_tmp $env(TMP)}
+catch {set env_temp $env(TEMP)}
+
+set env(TMP) c:/
+set env(TEMP) c:/
+
+test winpipe-5.1 {TclpCreateTempFile: cleanup temp files} {win exec} {
+    set x {}
+    set existing [glob -nocomplain c:/tcl*.tmp]
+    exec [interpreter] < $path(nothing)
+    foreach p [glob -nocomplain c:/tcl*.tmp] {
+	if {$p ni $existing} {
+	    lappend x $p
+	}
+    }
+    set x
+} {}
+test winpipe-5.2 {TclpCreateTempFile: TMP and TEMP not defined} {win exec} {
+    set tmp $env(TMP)
+    set temp $env(TEMP)
+    unset env(TMP)
+    unset env(TEMP)
+    exec [interpreter] < $path(nothing)
+    set env(TMP) $tmp
+    set env(TEMP) $temp
+    set x {}
+} {}
+test winpipe-5.3 {TclpCreateTempFile: TMP specifies non-existent directory} \
+	{win exec } {
+    set tmp $env(TMP)
+    set env(TMP) snarky
+    exec [interpreter] < $path(nothing)
+    set env(TMP) $tmp
+    set x {}
+} {}
+test winpipe-5.4 {TclpCreateTempFile: TEMP specifies non-existent directory} \
+	{win exec} {
+    set tmp $env(TMP)
+    set temp $env(TEMP)
+    unset env(TMP)
+    set env(TEMP) snarky
+    exec [interpreter] < $path(nothing)
+    set env(TMP) $tmp
+    set env(TEMP) $temp
+    set x {}
+} {}
+
+test winpipe-6.1 {PipeSetupProc & PipeCheckProc: read threads} \
+	{win exec cat32} {
+    set f [open "|[list $cat32]" r+]
+    fconfigure $f -blocking 0
+    fileevent $f writable { set x writable }
+    set x {}
+    vwait x
+    fileevent $f writable {}
+    fileevent $f readable { lappend x readable }
+    after 100 { lappend x timeout }
+    vwait x
+    puts $f foobar
+    flush $f
+    vwait x
+    lappend x [read $f]
+    after 100 { lappend x timeout }
+    vwait x
+    fconfigure $f -blocking 1
+    lappend x [catch {close $f} msg] $msg
+} {writable timeout readable {foobar
+} timeout 1 stderr32}
+test winpipe-6.2 {PipeSetupProc & PipeCheckProc: write threads} \
+	{win exec cat32} {
+    set f [open "|[list $cat32]" r+]
+    fconfigure $f -blocking 0
+    fileevent $f writable { set x writable }
+    set x {}
+    vwait x
+    puts -nonewline $f $big$big$big$big
+    flush $f
+    after 100 { lappend x timeout }
+    vwait x
+    lappend x [catch {close $f} msg] $msg
+} {writable timeout 0 {}}
+
+set path(echoArgs.tcl) [makeFile {
+    puts "[list $argv0 $argv]"
+} echoArgs.tcl]
+
+### validate the raw output of BuildCommandLine().
+###
+test winpipe-7.1 {BuildCommandLine: null arguments} {win exec} {
+    exec $env(COMSPEC) /c echo foo "" bar
+} {foo "" bar}
+test winpipe-7.2 {BuildCommandLine: null arguments} {win exec} {
+    exec $env(COMSPEC) /c echo foo {} bar
+} {foo "" bar}
+test winpipe-7.3 {BuildCommandLine: dbl quote quoting #1} {win exec} {
+    exec $env(COMSPEC) /c echo foo "\"" bar
+} {foo \" bar}
+test winpipe-7.4 {BuildCommandLine: dbl quote quoting #2} {win exec} {
+    exec $env(COMSPEC) /c echo foo {""} bar
+} {foo \"\" bar}
+test winpipe-7.5 {BuildCommandLine: dbl quote quoting #3} {win exec} {
+    exec $env(COMSPEC) /c echo foo "\" " bar
+} {foo "\" " bar}
+test winpipe-7.6 {BuildCommandLine: dbl quote quoting #4} {win exec} {
+    exec $env(COMSPEC) /c echo foo {a="b"} bar
+} {foo a=\"b\" bar}
+test winpipe-7.7 {BuildCommandLine: dbl quote quoting #5} {win exec} {
+    exec $env(COMSPEC) /c echo foo {a = "b"} bar
+} {foo "a = \"b\"" bar}
+test winpipe-7.8 {BuildCommandLine: dbl quote quoting #6} {win exec} {
+    exec $env(COMSPEC) /c echo {"hello"} {""hello""} {"""hello"""} {"\"hello\""} {he llo} "he \" llo"
+} {\"hello\" \"\"hello\"\" \"\"\"hello\"\"\" \"\\\"hello\\\"\" "he llo" "he \" llo"}
+test winpipe-7.9 {BuildCommandLine: N backslashes followed a quote rule #1} {win exec} {
+    exec $env(COMSPEC) /c echo foo \\ bar
+} {foo \ bar}
+test winpipe-7.10 {BuildCommandLine: N backslashes followed a quote rule #2} {win exec} {
+    exec $env(COMSPEC) /c echo foo \\\\ bar
+} {foo \\ bar}
+test winpipe-7.11 {BuildCommandLine: N backslashes followed a quote rule #3} {win exec} {
+    exec $env(COMSPEC) /c echo foo \\\ \\ bar
+} {foo "\ \\" bar}
+test winpipe-7.12 {BuildCommandLine: N backslashes followed a quote rule #4} {win exec} {
+    exec $env(COMSPEC) /c echo foo \\\ \\\\ bar
+} {foo "\ \\\\" bar}
+test winpipe-7.13 {BuildCommandLine: N backslashes followed a quote rule #5} {win exec} {
+    exec $env(COMSPEC) /c echo foo \\\ \\\\\\ bar
+} {foo "\ \\\\\\" bar}
+test winpipe-7.14 {BuildCommandLine: N backslashes followed a quote rule #6} {win exec} {
+    exec $env(COMSPEC) /c echo foo \\\ \\\" bar
+} {foo "\ \\\"" bar}
+test winpipe-7.15 {BuildCommandLine: N backslashes followed a quote rule #7} {win exec} {
+    exec $env(COMSPEC) /c echo foo \\\ \\\\\" bar
+} {foo "\ \\\\\"" bar}
+test winpipe-7.16 {BuildCommandLine: N backslashes followed a quote rule #8} {win exec} {
+    exec $env(COMSPEC) /c echo foo \\\ \\\\\\\" bar
+} {foo "\ \\\\\\\"" bar}
+test winpipe-7.17 {BuildCommandLine: special chars #4} {win exec} {
+    exec $env(COMSPEC) /c echo foo \{ bar
+} "foo \{ bar"
+test winpipe-7.18 {BuildCommandLine: special chars #5} {win exec} {
+    exec $env(COMSPEC) /c echo foo \} bar
+} "foo \} bar"
+
+### validate the pass-thru from BuildCommandLine() to the crt's parse_cmdline().
+###
+test winpipe-8.1 {BuildCommandLine/parse_cmdline pass-thru: null arguments} {win exec} {
+    exec [interpreter] $path(echoArgs.tcl) foo "" bar
+} [list $path(echoArgs.tcl) [list foo {} bar]]
+test winpipe-8.2 {BuildCommandLine/parse_cmdline pass-thru: null arguments} {win exec} {
+    exec [interpreter] $path(echoArgs.tcl) foo {} bar
+} [list $path(echoArgs.tcl) [list foo {} bar]]
+test winpipe-8.3 {BuildCommandLine/parse_cmdline pass-thru: dbl quote quoting #1} {win exec} {
+    exec [interpreter] $path(echoArgs.tcl) foo "\"" bar
+} [list $path(echoArgs.tcl) [list foo "\"" bar]]
+test winpipe-8.4 {BuildCommandLine/parse_cmdline pass-thru: dbl quote quoting #2} {win exec} {
+    exec [interpreter] $path(echoArgs.tcl) foo {""} bar
+} [list $path(echoArgs.tcl) [list foo {""} bar]]
+test winpipe-8.5 {BuildCommandLine/parse_cmdline pass-thru: dbl quote quoting #3} {win exec} {
+    exec [interpreter] $path(echoArgs.tcl) foo "\" " bar
+} [list $path(echoArgs.tcl) [list foo "\" " bar]]
+test winpipe-8.6 {BuildCommandLine/parse_cmdline pass-thru: dbl quote quoting #4} {win exec} {
+    exec [interpreter] $path(echoArgs.tcl) foo {a="b"} bar
+} [list $path(echoArgs.tcl) [list foo {a="b"} bar]]
+test winpipe-8.7 {BuildCommandLine/parse_cmdline pass-thru: dbl quote quoting #5} {win exec} {
+    exec [interpreter] $path(echoArgs.tcl) foo {a = "b"} bar
+} [list $path(echoArgs.tcl) [list foo {a = "b"} bar]]
+test winpipe-8.8 {BuildCommandLine/parse_cmdline pass-thru: dbl quote quoting #6} {win exec} {
+    exec [interpreter] $path(echoArgs.tcl) {"hello"} {""hello""} {"""hello"""} {"\"hello\""} {he llo} {he " llo}
+} [list $path(echoArgs.tcl) [list {"hello"} {""hello""} {"""hello"""} {"\"hello\""} {he llo} {he " llo}]]
+test winpipe-8.9 {BuildCommandLine/parse_cmdline pass-thru: N backslashes followed a quote rule #1} {win exec} {
+    exec [interpreter] $path(echoArgs.tcl) foo \\ bar
+} [list $path(echoArgs.tcl) [list foo \\ bar]]
+test winpipe-8.10 {BuildCommandLine/parse_cmdline pass-thru: N backslashes followed a quote rule #2} {win exec} {
+    exec [interpreter] $path(echoArgs.tcl) foo \\\\ bar
+} [list $path(echoArgs.tcl) [list foo \\\\ bar]]
+test winpipe-8.11 {BuildCommandLine/parse_cmdline pass-thru: N backslashes followed a quote rule #3} {win exec} {
+    exec [interpreter] $path(echoArgs.tcl) foo \\\ \\ bar
+} [list $path(echoArgs.tcl) [list foo \\\ \\ bar]]
+test winpipe-8.12 {BuildCommandLine/parse_cmdline pass-thru: N backslashes followed a quote rule #4} {win exec} {
+    exec [interpreter] $path(echoArgs.tcl) foo \\\ \\\\ bar
+} [list $path(echoArgs.tcl) [list foo \\\ \\\\ bar]]
+test winpipe-8.13 {BuildCommandLine/parse_cmdline pass-thru: N backslashes followed a quote rule #5} {win exec} {
+    exec [interpreter] $path(echoArgs.tcl) foo \\\ \\\\\\ bar
+} [list $path(echoArgs.tcl) [list foo \\\ \\\\\\ bar]]
+test winpipe-8.14 {BuildCommandLine/parse_cmdline pass-thru: N backslashes followed a quote rule #6} {win exec} {
+    exec [interpreter] $path(echoArgs.tcl) foo \\\ \\\" bar
+} [list $path(echoArgs.tcl) [list foo \\\ \\\" bar]]
+test winpipe-8.15 {BuildCommandLine/parse_cmdline pass-thru: N backslashes followed a quote rule #7} {win exec} {
+    exec [interpreter] $path(echoArgs.tcl) foo \\\ \\\\\" bar
+} [list $path(echoArgs.tcl) [list foo \\\ \\\\\" bar]]
+test winpipe-8.16 {BuildCommandLine/parse_cmdline pass-thru: N backslashes followed a quote rule #8} {win exec} {
+    exec [interpreter] $path(echoArgs.tcl) foo \\\ \\\\\\\" bar
+} [list $path(echoArgs.tcl) [list foo \\\ \\\\\\\" bar]]
+test winpipe-8.17 {BuildCommandLine/parse_cmdline pass-thru: special chars #1} {win exec} {
+    exec [interpreter] $path(echoArgs.tcl) foo \{ bar
+} [list $path(echoArgs.tcl) [list foo \{ bar]]
+test winpipe-8.18 {BuildCommandLine/parse_cmdline pass-thru: special chars #2} {win exec} {
+    exec [interpreter] $path(echoArgs.tcl) foo \} bar
+} [list $path(echoArgs.tcl) [list foo \} bar]]
+test winpipe-8.19 {ensure parse_cmdline isn't doing wildcard replacement} {win exec} {
+    exec [interpreter] $path(echoArgs.tcl) foo * makefile.?c bar
+} [list $path(echoArgs.tcl) [list foo * makefile.?c bar]]
+
+# restore old values for env(TMP) and env(TEMP)
+
+if {[catch {set env(TMP) $env_tmp}]} {
+    unset env(TMP)
+}
+if {[catch {set env(TEMP) $env_temp}]} {
+    unset env(TEMP)
+}
+
+# cleanup
+removeFile little
+removeFile big
+removeFile more
+removeFile stdout
+removeFile stderr
+removeFile nothing
+removeFile echoArgs.tcl
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/tests/winTime.test b/tests/winTime.test
new file mode 100644
index 0000000..add8f98
--- /dev/null
+++ b/tests/winTime.test
@@ -0,0 +1,66 @@
+# This file tests the tclWinTime.c file.
+#
+# This file contains a collection of tests for one or more of the Tcl
+# built-in commands.  Sourcing this file into Tcl runs the tests and
+# generates output for errors.  No output means no errors were found.
+#
+# Copyright (c) 1997 Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+    package require tcltest
+    namespace import -force ::tcltest::*
+}
+
+::tcltest::loadTestedCommands
+catch [list package require -exact Tcltest [info patchlevel]]
+
+testConstraint testwinclock [llength [info commands testwinclock]]
+
+# The next two tests will crash on Windows if the check for negative
+# clock values is not done properly.
+
+test winTime-1.1 {TclpGetDate} {win} {
+    set ::env(TZ) JST-9
+    set result [clock format -1 -format %Y]
+    unset ::env(TZ)
+    set result
+} {1970}
+test winTime-1.2 {TclpGetDate} {win} {
+    set ::env(TZ) PST8
+    set result [clock format 1 -format %Y]
+    unset ::env(TZ)
+    set result
+} {1969}
+
+# Next test tries to make sure that the Tcl clock stays in step
+# with the Windows clock.  30 sec really isn't enough,
+# but how much time does a tester have patience for?
+
+test winTime-2.1 {Synchronization of Tcl and Windows clocks} {testwinclock} {
+    # May fail due to OS/hardware discrepancies.  See:
+    # http://support.microsoft.com/default.aspx?scid=kb;en-us;274323
+    set failed {}
+    set ok 1
+    foreach start_sec [testwinclock] break
+    while { 1 } {
+	foreach { sys_sec sys_usec tcl_sec tcl_usec } [testwinclock] break
+	set diff [expr { $tcl_sec - $sys_sec
+			 + 1.0e-6 * ( $tcl_usec - $sys_usec ) }]
+        if { abs($diff) > 0.06 } {
+	    set failed "Tcl clock differs from system clock by $diff sec"
+	    break
+	} else {
+	    testwinsleep 1
+	}
+	if { $sys_sec - $start_sec >= 30 } break
+    }
+    set failed
+} {}
+
+# cleanup
+::tcltest::cleanupTests
+return
diff --git a/tests/zlib.test b/tests/zlib.test
new file mode 100644
index 0000000..8a040d8
--- /dev/null
+++ b/tests/zlib.test
@@ -0,0 +1,926 @@
+# The file tests the tclZlib.c file.
+#
+# This file contains a collection of tests for one or more of the Tcl built-in
+# commands. Sourcing this file into Tcl runs the tests and generates output
+# for errors. No output means no errors were found.
+#
+# Copyright (c) 1996-1998 by Sun Microsystems, Inc.
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution of
+# this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+if {"::tcltest" ni [namespace children]} {
+    package require tcltest 2.1
+    namespace import -force ::tcltest::*
+}
+
+testConstraint zlib [llength [info commands zlib]]
+testConstraint recentZlib 0
+catch {
+    # Work around a bug in some versions of zlib; known to manifest on at
+    # least Mac OS X Mountain Lion...
+    testConstraint recentZlib \
+	    [package vsatisfies [zlib::pkgconfig get zlibVersion] 1.2.6]
+}
+
+test zlib-1.1 {zlib basics} -constraints zlib -returnCodes error -body {
+    zlib
+} -result {wrong # args: should be "zlib command arg ?...?"}
+test zlib-1.2 {zlib basics} -constraints zlib -returnCodes error -body {
+    zlib ? {}
+} -result {bad command "?": must be adler32, compress, crc32, decompress, deflate, gunzip, gzip, inflate, push, or stream}
+test zlib-1.3 {zlib basics} -constraints zlib -body {
+    zlib::pkgconfig list
+} -result zlibVersion
+test zlib-1.4 {zlib basics} -constraints zlib -body {
+    package present zlib
+} -result 2.0.1
+
+test zlib-2.1 {zlib compress/decompress} zlib {
+    zlib decompress [zlib compress abcdefghijklm]
+} abcdefghijklm
+
+test zlib-3.1 {zlib deflate/inflate} zlib {
+    zlib inflate [zlib deflate abcdefghijklm]
+} abcdefghijklm
+
+test zlib-4.1 {zlib gzip/gunzip} zlib {
+    zlib gunzip [zlib gzip abcdefghijklm]
+} abcdefghijklm
+test zlib-4.2 {zlib gzip/gunzip} zlib {
+    set s [string repeat abcdef 5]
+    list [zlib gunzip [zlib gzip $s -header {comment gorp}] -header head] \
+	[dict get $head comment] [dict get $head size]
+} {abcdefabcdefabcdefabcdefabcdef gorp 30}
+
+test zlib-5.1 {zlib adler32} zlib {
+    format %x [expr {[zlib adler32 abcdeabcdeabcdeabcdeabcdeabcde] & 0xffffffff}]
+} b3b50b9b
+test zlib-5.2 {zlib adler32} zlib {
+    format %x [expr {[zlib adler32 abcdeabcdeabcdeabcdeabcdeabcde 42] & 0xffffffff}]
+} b8830bc4
+test zlib-5.3 {zlib adler32} -constraints zlib -returnCodes error -body {
+    zlib adler32 abcdeabcdeabcdeabcdeabcdeabcde 42 x
+} -result {wrong # args: should be "zlib adler32 data ?startValue?"}
+
+test zlib-6.1 {zlib crc32} zlib {
+    format %x [expr {[zlib crc32 abcdeabcdeabcdeabcdeabcdeabcde] & 0xffffffff}]
+} 6f73e901
+test zlib-6.2 {zlib crc32} zlib {
+    format %x [expr {[zlib crc32 abcdeabcdeabcdeabcdeabcdeabcde 42] & 0xffffffff}]
+} ce1c4914
+test zlib-6.3 {zlib crc32} -constraints zlib -returnCodes error -body {
+    zlib crc32 abcdeabcdeabcdeabcdeabcdeabcde 42 x
+} -result {wrong # args: should be "zlib crc32 data ?startValue?"}
+test zlib-6.4 {zlib crc32: bug 2662434} -constraints zlib -body {
+    zlib crc32 "dabale arroz a la zorra el abad"
+} -result 3842832571
+
+test zlib-7.0 {zlib stream} -constraints zlib -returnCodes error -setup {
+    set s [zlib stream compress]
+} -body {
+    $s ?
+} -cleanup {
+    $s close
+} -result {bad option "?": must be add, checksum, close, eof, finalize, flush, fullflush, get, header, put, or reset}
+test zlib-7.1 {zlib stream} zlib {
+    set s [zlib stream compress]
+    $s put -finalize abcdeEDCBA
+    set data [$s get]
+    set result [list [$s get] [format %x [$s checksum]]]
+    $s close
+    lappend result [zlib decompress $data]
+} {{} 136f033f abcdeEDCBA}
+test zlib-7.2 {zlib stream} zlib {
+    set s [zlib stream decompress]
+    $s put -finalize [zlib compress abcdeEDCBA]
+    set data [$s get]
+    set result [list [$s get] [format %x [$s checksum]]]
+    $s close
+    lappend result $data
+} {{} 136f033f abcdeEDCBA}
+test zlib-7.3 {zlib stream} zlib {
+    set s [zlib stream deflate]
+    $s put -finalize abcdeEDCBA
+    set data [$s get]
+    set result [list [$s get] [format %x [$s checksum]]]
+    $s close
+    lappend result [zlib inflate $data]
+} {{} 1 abcdeEDCBA}
+test zlib-7.4 {zlib stream} zlib {
+    set s [zlib stream inflate]
+    $s put -finalize [zlib deflate abcdeEDCBA]
+    set data [$s get]
+    set result [list [$s get] [format %x [$s checksum]]]
+    $s close
+    lappend result $data
+} {{} 1 abcdeEDCBA}
+test zlib-7.5 {zlib stream} zlib {
+    set s [zlib stream gzip]
+    $s put -finalize abcdeEDCBA..
+    set data [$s get]
+    set result [list [$s get] [format %x [$s checksum]]]
+    $s close
+    lappend result [zlib gunzip $data]
+} {{} 69f34b6a abcdeEDCBA..}
+test zlib-7.6 {zlib stream} zlib {
+    set s [zlib stream gunzip]
+    $s put -finalize [zlib gzip abcdeEDCBA..]
+    set data [$s get]
+    set result [list [$s get] [format %x [$s checksum]]]
+    $s close
+    lappend result $data
+} {{} 69f34b6a abcdeEDCBA..}
+test zlib-7.7 {zlib stream: Bug 25842c161} -constraints zlib -body {
+    set s [zlib stream deflate]
+    $s put {}
+} -cleanup {
+    catch {$s close}
+} -result ""
+
+test zlib-8.1 {zlib transformation} -constraints zlib -setup {
+    set file [makeFile {} test.gz]
+} -body {
+    set f [zlib push gzip [open $file w] -header {comment gorp}]
+    puts $f "ok"
+    close $f
+    set f [zlib push gunzip [open $file]]
+    list [gets $f] [dict get [chan configure $f -header] comment]
+} -cleanup {
+    close $f
+    removeFile $file
+} -result {ok gorp}
+test zlib-8.2 {zlib transformation} -constraints zlib -setup {
+    set file [makeFile {} test.z]
+} -body {
+    set f [zlib push compress [open $file w]]
+    puts $f "ok"
+    close $f
+    set f [zlib push decompress [open $file]]
+    gets $f
+} -cleanup {
+    close $f
+    removeFile $file
+} -result ok
+test zlib-8.3 {zlib transformation and fileevent} -constraints zlib -setup {
+    set srv [socket -myaddr localhost -server {apply {{c a p} {
+        fconfigure $c -translation binary -buffering none -blocking 0
+        puts -nonewline $c [zlib gzip [string repeat a 81920]]
+        close $c
+    }}} 0]
+    set port [lindex [fconfigure $srv -sockname] 2]
+    set file [makeFile {} test.gz]
+    set fout [open $file wb]
+} -body {
+    set sin [socket localhost $port]
+    try {
+	fconfigure $sin -translation binary
+	zlib push gunzip $sin
+	after 1000 {set total timeout}
+	fcopy $sin $fout -command {apply {{c {e {}}} {
+	    set ::total [expr {$e eq {} ? $c : $e}]
+	}}}
+	vwait total
+	after cancel {set total timeout}
+    } finally {
+	close $sin
+    }
+    append total --> [file size $file]
+} -cleanup {
+    close $fout
+    close $srv
+    removeFile $file
+} -result 81920-->81920
+test zlib-8.4 {transformation and flushing: Bug 3517696} -setup {
+    set file [makeFile {} test.z]
+    set fd [open $file w]
+} -constraints zlib -body {
+    zlib push compress $fd
+    puts $fd "qwertyuiop"
+    fconfigure $fd -flush sync
+    puts $fd "qwertyuiop"
+} -cleanup {
+    catch {close $fd}
+    removeFile $file
+} -result {}
+test zlib-8.5 {transformation and flushing and fileevents: Bug 3525907} -setup {
+    foreach {r w} [chan pipe] break
+} -constraints zlib -body {
+    set ::res {}
+    fconfigure $w -buffering none
+    zlib push compress $w
+    puts -nonewline $w qwertyuiop
+    chan configure $w -flush sync
+    after 500 {puts -nonewline $w asdfghjkl;close $w}
+    fconfigure $r -blocking 0 -buffering none
+    zlib push decompress $r
+    fileevent $r readable {set msg [read $r];lappend ::res $msg;if {[eof $r]} {set ::done 1}}
+    after 250 {lappend ::res MIDDLE}
+    vwait ::done
+    set ::res
+} -cleanup {
+    catch {close $r}
+} -result {qwertyuiop MIDDLE asdfghjkl {}}
+test zlib-8.6 {transformation and fconfigure} -setup {
+    set file [makeFile {} test.z]
+    set fd [open $file wb]
+} -constraints zlib -body {
+    list [fconfigure $fd] [zlib push compress $fd; fconfigure $fd] \
+	[chan pop $fd; fconfigure $fd]
+} -cleanup {
+    catch {close $fd}
+    removeFile $file
+} -result {{-blocking 1 -buffering full -buffersize 4096 -encoding binary -eofchar {} -translation lf} {-blocking 1 -buffering full -buffersize 4096 -encoding binary -eofchar {} -translation lf -checksum 1 -dictionary {}} {-blocking 1 -buffering full -buffersize 4096 -encoding binary -eofchar {} -translation lf}}
+test zlib-8.7 {transformation and fconfigure} -setup {
+    set file [makeFile {} test.gz]
+    set fd [open $file wb]
+} -constraints zlib -body {
+    list [fconfigure $fd] [zlib push gzip $fd; fconfigure $fd] \
+	[chan pop $fd; fconfigure $fd]
+} -cleanup {
+    catch {close $fd}
+    removeFile $file
+} -result {{-blocking 1 -buffering full -buffersize 4096 -encoding binary -eofchar {} -translation lf} {-blocking 1 -buffering full -buffersize 4096 -encoding binary -eofchar {} -translation lf -checksum 0} {-blocking 1 -buffering full -buffersize 4096 -encoding binary -eofchar {} -translation lf}}
+# Input is headers from fetching SPDY draft
+# Dictionary is that which is proposed _in_ SPDY draft
+set spdyHeaders "HTTP/1.0 200 OK\r\nContent-Type: text/html; charset=utf-8\r\nX-Robots-Tag: noarchive\r\nLast-Modified: Tue, 05 Jun 2012 02:43:25 GMT\r\nETag: \"1338864205129|#public|0|en|||0\"\r\nExpires: Tue, 05 Jun 2012 16:17:11 GMT\r\nDate: Tue, 05 Jun 2012 16:17:06 GMT\r\nCache-Control: public, max-age=5\r\nX-Content-Type-Options: nosniff\r\nX-XSS-Protection: 1; mode=block\r\nServer: GSE\r\n"
+set spdyDict "optionsgetheadpostputdeletetraceacceptaccept-charsetaccept-encodingaccept-languageauthorizationexpectfromhostif-modified-sinceif-matchif-none-matchif-rangeif-unmodifiedsincemax-forwardsproxy-authorizationrangerefererteuser-agent100101200201202203204205206300301302303304305306307400401402403404405406407408409410411412413414415416417500501502503504505accept-rangesageetaglocationproxy-authenticatepublicretry-afterservervarywarningwww-authenticateallowcontent-basecontent-encodingcache-controlconnectiondatetrailertransfer-encodingupgradeviawarningcontent-languagecontent-lengthcontent-locationcontent-md5content-rangecontent-typeetagexpireslast-modifiedset-cookieMondayTuesdayWednesdayThursdayFridaySaturdaySundayJanFebMarAprMayJunJulAugSepOctNovDecchunkedtext/htmlimage/pngimage/jpgimage/gifapplication/xmlapplication/xhtmltext/plainpublicmax-agecharset=iso-8859-1utf-8gzipdeflateHTTP/1.1statusversionurl"
+test zlib-8.8 {transformation and fconfigure} -setup {
+    lassign [chan pipe] inSide outSide
+} -constraints zlib -body {
+    zlib push compress $outSide -dictionary $spdyDict
+    fconfigure $outSide -blocking 0 -translation binary -buffering none
+    fconfigure $inSide -blocking 1 -translation binary
+    puts -nonewline $outSide $spdyHeaders
+    chan pop $outSide
+    chan close $outSide
+    set compressed [read $inSide]
+    catch {zlib decompress $compressed} err opt
+    list [string length [zlib compress $spdyHeaders]] \
+	[string length $compressed] \
+	$err [dict get $opt -errorcode] [zlib adler32 $spdyDict]
+} -cleanup {
+    catch {close $outSide}
+    catch {close $inSide}
+} -result {260 222 {need dictionary} {TCL ZLIB NEED_DICT 2381337010} 2381337010}
+test zlib-8.9 {transformation and fconfigure} -setup {
+    lassign [chan pipe] inSide outSide
+    set strm [zlib stream decompress]
+} -constraints zlib -body {
+    zlib push compress $outSide -dictionary $spdyDict
+    fconfigure $outSide -blocking 0 -translation binary -buffering none
+    fconfigure $inSide -blocking 1 -translation binary
+    puts -nonewline $outSide $spdyHeaders
+    set result [fconfigure $outSide -checksum]
+    chan pop $outSide
+    chan close $outSide
+    $strm put -dictionary $spdyDict [read $inSide]
+    lappend result [string length $spdyHeaders] [string length [$strm get]]
+} -cleanup {
+    catch {close $outSide}
+    catch {close $inSide}
+    catch {$strm close}
+} -result {3064818174 358 358}
+test zlib-8.10 {transformation and fconfigure} -setup {
+    lassign [chan pipe] inSide outSide
+} -constraints {zlib recentZlib} -body {
+    zlib push deflate $outSide -dictionary $spdyDict
+    fconfigure $outSide -blocking 0 -translation binary -buffering none
+    fconfigure $inSide -blocking 1 -translation binary
+    puts -nonewline $outSide $spdyHeaders
+    chan pop $outSide
+    chan close $outSide
+    set compressed [read $inSide]
+    catch {
+	zlib inflate $compressed
+	throw UNREACHABLE "should be unreachable"
+    } err opt
+    list [string length [zlib deflate $spdyHeaders]] \
+	[string length $compressed] \
+	$err [dict get $opt -errorcode]
+} -cleanup {
+    catch {close $outSide}
+    catch {close $inSide}
+} -result {254 212 {data error} {TCL ZLIB DATA}}
+test zlib-8.11 {transformation and fconfigure} -setup {
+    lassign [chan pipe] inSide outSide
+    set strm [zlib stream inflate]
+} -constraints zlib -body {
+    zlib push deflate $outSide -dictionary $spdyDict
+    fconfigure $outSide -blocking 0 -translation binary -buffering none
+    fconfigure $inSide -blocking 1 -translation binary
+    puts -nonewline $outSide $spdyHeaders
+    chan pop $outSide
+    chan close $outSide
+    $strm put -dictionary $spdyDict [read $inSide]
+    list [string length $spdyHeaders] [string length [$strm get]]
+} -cleanup {
+    catch {close $outSide}
+    catch {close $inSide}
+    catch {$strm close}
+} -result {358 358}
+test zlib-8.12 {transformation and fconfigure} -setup {
+    lassign [chan pipe] inSide outSide
+    set strm [zlib stream compress]
+} -constraints zlib -body {
+    $strm put -dictionary $spdyDict -finalize $spdyHeaders
+    zlib push decompress $inSide
+    fconfigure $outSide -blocking 0 -translation binary
+    fconfigure $inSide -translation binary -dictionary $spdyDict
+    puts -nonewline $outSide [$strm get]
+    close $outSide
+    list [string length $spdyHeaders] [string length [read $inSide]] \
+	[fconfigure $inSide -checksum]
+} -cleanup {
+    catch {close $outSide}
+    catch {close $inSide}
+    catch {$strm close}
+} -result {358 358 3064818174}
+test zlib-8.13 {transformation and fconfigure} -setup {
+    lassign [chan pipe] inSide outSide
+    set strm [zlib stream compress]
+} -constraints zlib -body {
+    $strm put -dictionary $spdyDict -finalize $spdyHeaders
+    zlib push decompress $inSide -dictionary $spdyDict
+    fconfigure $outSide -blocking 0 -translation binary
+    fconfigure $inSide -translation binary
+    puts -nonewline $outSide [$strm get]
+    close $outSide
+    list [string length $spdyHeaders] [string length [read $inSide]] \
+	[fconfigure $inSide -checksum]
+} -cleanup {
+    catch {close $outSide}
+    catch {close $inSide}
+    catch {$strm close}
+} -result {358 358 3064818174}
+test zlib-8.14 {transformation and fconfigure} -setup {
+    lassign [chan pipe] inSide outSide
+    set strm [zlib stream deflate]
+} -constraints zlib -body {
+    $strm put -finalize -dictionary $spdyDict $spdyHeaders
+    zlib push inflate $inSide
+    fconfigure $outSide -blocking 0 -buffering none -translation binary
+    fconfigure $inSide -translation binary -dictionary $spdyDict
+    puts -nonewline $outSide [$strm get]
+    close $outSide
+    list [string length $spdyHeaders] [string length [read $inSide]]
+} -cleanup {
+    catch {close $outSide}
+    catch {close $inSide}
+    catch {$strm close}
+} -result {358 358}
+test zlib-8.15 {transformation and fconfigure} -setup {
+    lassign [chan pipe] inSide outSide
+    set strm [zlib stream deflate]
+} -constraints zlib -body {
+    $strm put -finalize -dictionary $spdyDict $spdyHeaders
+    zlib push inflate $inSide -dictionary $spdyDict
+    fconfigure $outSide -blocking 0 -buffering none -translation binary
+    fconfigure $inSide -translation binary
+    puts -nonewline $outSide [$strm get]
+    close $outSide
+    list [string length $spdyHeaders] [string length [read $inSide]]
+} -cleanup {
+    catch {close $outSide}
+    catch {close $inSide}
+    catch {$strm close}
+} -result {358 358}
+test zlib-8.16 {Bug 3603553: buffer transfer with large writes} -setup {
+    # Actual data isn't very important; needs to be substantially larger than
+    # the internal buffer (32kB) and incompressible.
+    set largeData {}
+    for {set i 0;expr srand(1)} {$i < 100000} {incr i} {
+	append largeData [lindex "a b c d e f g h i j k l m n o p" \
+		[expr {int(16*rand())}]]
+    }
+    set file [makeFile {} test.gz]
+} -constraints zlib -body {
+    set f [open $file wb]
+    fconfigure $f -buffering none
+    zlib push gzip $f
+    puts -nonewline $f $largeData
+    close $f
+    file size $file
+} -cleanup {
+    removeFile $file
+} -result 57647
+test zlib-8.17 {Bug dd260aaf: fconfigure} -setup {
+    lassign [chan pipe] inSide outSide
+} -constraints zlib -body {
+    zlib push inflate $inSide
+    zlib push deflate $outSide
+    list [chan configure $inSide -dictionary] [chan configure $outSide -dictionary]
+} -cleanup {
+    catch {close $inSide}
+    catch {close $outSide}
+} -result {{} {}}
+test zlib-8.18 {Bug dd260aaf: fconfigure} -setup {
+    lassign [chan pipe] inSide outSide
+} -constraints zlib -body {
+    zlib push inflate $inSide -dictionary "one two"
+    zlib push deflate $outSide -dictionary "one two"
+    list [chan configure $inSide -dictionary] [chan configure $outSide -dictionary]
+} -cleanup {
+    catch {close $inSide}
+    catch {close $outSide}
+} -result {{one two} {one two}}
+
+test zlib-9.1 "check fcopy with push" -constraints zlib -setup {
+    set sfile [makeFile {} testsrc.gz]
+    set file [makeFile {} test.gz]
+    set f [open $sfile wb]
+    puts -nonewline $f [zlib gzip [string repeat a 81920]]
+    close $f
+} -body {
+    set fin [zlib push gunzip [open $sfile rb]]
+    set fout [open $file wb]
+    set total [fcopy $fin $fout]
+    close $fin ; close $fout
+    list copied $total size [file size $file]
+} -cleanup {
+    removeFile $file
+    removeFile $sfile
+} -result {copied 81920 size 81920}
+test zlib-9.2 "socket fcopy with push" -constraints zlib -setup {
+    set srv [socket -myaddr localhost -server {apply {{c a p} {
+        chan configure $c -translation binary -buffering none -blocking 0
+        puts -nonewline $c [zlib gzip [string repeat a 81920]]
+        close $c
+    }}} 0]
+    set file [makeFile {} test.gz]
+} -body {
+    lassign [chan configure $srv -sockname] addr name port
+    set sin [socket $addr $port]
+    chan configure $sin -translation binary
+    zlib push gunzip $sin
+    update
+    set total [fcopy $sin [set fout [open $file wb]]]
+    close $sin
+    close $fout
+    list read $total size [file size $file]
+} -cleanup {
+    close $srv
+    removeFile $file
+} -result {read 81920 size 81920}
+test zlib-9.3 "socket fcopy bg (identity)" -constraints {tempNotWin zlib} -setup {
+    set srv [socket -myaddr localhost -server {apply {{c a p} {
+        #puts "connection from $a:$p on $c"
+        chan configure $c -translation binary -buffering none -blocking 0
+        puts -nonewline $c [string repeat a 81920]
+        close $c
+    }}} 0]
+    set file [makeFile {} test.gz]
+} -body {
+    lassign [chan configure $srv -sockname] addr name port
+    #puts "listening for connections on $addr $port"
+    set sin [socket localhost $port]
+    chan configure $sin -translation binary
+    update
+    set fout [open $file wb]
+    after 1000 {set ::total timeout}
+    fcopy $sin $fout -command {apply {{c {e {}}} {
+        set ::total [expr {$e eq {} ? $c : $e}]
+    }}}
+    vwait ::total
+    after cancel {set ::total timeout}
+    close $sin; close $fout
+    list read $::total size [file size $file]
+} -cleanup {
+    close $srv
+    removeFile $file
+} -returnCodes {ok error} -result {read 81920 size 81920}
+test zlib-9.4 "socket fcopy bg (gzip)" -constraints zlib -setup {
+    set srv [socket -myaddr localhost -server {apply {{c a p} {
+        chan configure $c -translation binary -buffering none -blocking 0
+        puts -nonewline $c [zlib gzip [string repeat a 81920]]
+        close $c
+    }}} 0]
+    set file [makeFile {} test.gz]
+} -body {
+    lassign [chan configure $srv -sockname] addr name port
+    set sin [socket $addr $port]
+    chan configure $sin -translation binary
+    zlib push gunzip $sin
+    update
+    set fout [open $file wb]
+    after 1000 {set ::total timeout}
+    fcopy $sin $fout -command {apply {{c {e {}}} {
+        set ::total [expr {$e eq {} ? $c : $e}]
+    }}}
+    vwait ::total
+    after cancel {set ::total timeout}
+    close $sin; close $fout
+    list read $::total size [file size $file]
+} -cleanup {
+    close $srv
+    removeFile $file
+} -result {read 81920 size 81920}
+test zlib-9.5 "socket fcopy incremental (gzip)" -constraints zlib -setup {
+    set srv [socket -myaddr localhost -server {apply {{c a p} {
+        chan configure $c -translation binary -buffering none -blocking 0
+        puts -nonewline $c [zlib gzip [string repeat a 81920]]
+        close $c
+    }}} 0]
+    proc zlib95copy {i o t c {e {}}} {
+        incr t $c
+        if {$e ne {}} {
+            set ::total [list error $e]
+        } elseif {[eof $i]} {
+            set ::total [list eof $t]
+        } else {
+            fcopy $i $o -size 8192 -command [list zlib95copy $i $o $t]
+        }
+    }
+    set file [makeFile {} test.gz]
+} -body {
+    lassign [chan configure $srv -sockname] addr name port
+    set sin [socket $addr $port]
+    chan configure $sin -translation binary
+    zlib push gunzip $sin
+    update
+    set fout [open $file wb]
+    after 1000 {set ::total timeout}
+    fcopy $sin $fout -size 8192 -command [list zlib95copy $sin $fout 0]
+    vwait ::total
+    after cancel {set ::total timeout}
+    close $sin; close $fout
+    list $::total size [file size $file]
+} -cleanup {
+    close $srv
+    rename zlib95copy {}
+    removeFile $file
+} -result {{eof 81920} size 81920}
+test zlib-9.6 "bug #2818131 (gzip)" -constraints zlib -setup {
+    set srv [socket -myaddr localhost -server {apply {{c a p} {
+        chan configure $c -translation binary -buffering none -blocking 0
+        zlib push gzip $c
+        puts -nonewline $c [string repeat hello 100]
+        close $c
+    }}} 0]
+} -body {
+    lassign [chan configure $srv -sockname] addr name port
+    after 1000 {set ::total timeout}
+    set s [socket $addr $port]
+    chan configure $s -translation binary
+    zlib push gunzip $s
+    chan event $s readable [list apply {{s} {
+        set d [read $s]
+        if {[eof $s]} {
+            chan event $s readable {}
+            set ::total [list eof [string length $d]]
+        }
+    }} $s]
+    vwait ::total
+    after cancel {set ::total timeout}
+    close $s
+    set ::total
+} -cleanup {
+    close $srv
+    unset -nocomplain total
+} -result {eof 500}
+test zlib-9.7 "bug #2818131 (compress)" -constraints zlib -setup {
+    set srv [socket -myaddr localhost -server {apply {{c a p} {
+        chan configure $c -translation binary -buffering none -blocking 0
+        zlib push compress $c
+        puts -nonewline $c [string repeat hello 100]
+        close $c
+    }}} 0]
+} -body {
+    lassign [chan configure $srv -sockname] addr name port
+    after 1000 {set ::total timeout}
+    set s [socket $addr $port]
+    chan configure $s -translation binary
+    zlib push decompress $s
+    chan event $s readable [list apply {{s} {
+        set d [read $s]
+        if {[eof $s]} {
+            chan event $s readable {}
+            set ::total [list eof [string length $d]]
+        }
+    }} $s]
+    vwait ::total
+    after cancel {set ::total timeout}
+    close $s
+    set ::total
+} -cleanup {
+    close $srv
+    unset -nocomplain total
+} -result {eof 500}
+test zlib-9.8 "bug #2818131 (deflate)" -constraints zlib -setup {
+    set srv [socket -myaddr localhost -server {apply {{c a p} {
+        chan configure $c -translation binary -buffering none -blocking 0
+        zlib push deflate $c
+        puts -nonewline $c [string repeat hello 100]
+        close $c
+    }}} 0]
+} -body {
+    lassign [chan configure $srv -sockname] addr name port
+    after 1000 {set ::total timeout}
+    set s [socket $addr $port]
+    chan configure $s -translation binary
+    zlib push inflate $s
+    chan event $s readable [list apply {{s} {
+        set d [read $s]
+        if {[eof $s]} {
+            chan event $s readable {}
+            set ::total [list eof [string length $d]]
+        }
+    }} $s]
+    vwait ::total
+    after cancel {set ::total timeout}
+    close $s
+    set ::total
+} -cleanup {
+    unset -nocomplain total
+    close $srv
+} -result {eof 500}
+test zlib-9.9 "bug #2818131 (gzip mismatch)" -constraints zlib -setup {
+    proc bgerror {s} {set ::total [list error $s]}
+    set srv [socket -myaddr localhost -server {apply {{c a p} {
+        chan configure $c -translation binary -buffering none -blocking 0
+        zlib push gzip $c
+        puts -nonewline $c [string repeat hello 100]
+        close $c
+    }}} 0]
+} -body {
+    lassign [chan configure $srv -sockname] addr name port
+    after 1000 {set ::total timeout}
+    set s [socket $addr $port]
+    try {
+        chan configure $s -translation binary
+        zlib push inflate $s
+        chan event $s readable [list apply {{s} {
+            set d [read $s]
+            if {[eof $s]} {
+                chan event $s readable {}
+                set ::total [list eof [string length $d]]
+            }
+        }} $s]
+        vwait ::total
+    } finally {
+	after cancel {set ::total timeout}
+        close $s
+    }
+    set ::total
+} -cleanup {
+    unset -nocomplain total
+    close $srv
+    rename bgerror {}
+} -result {error {invalid block type}}
+test zlib-9.10 "bug #2818131 (compress mismatch)" -constraints zlib -setup {
+    proc bgerror {s} {set ::total [list error $s]}
+    set srv [socket -myaddr localhost -server {apply {{c a p} {
+        chan configure $c -translation binary -buffering none -blocking 0
+        zlib push compress $c
+        puts -nonewline $c [string repeat hello 100]
+        close $c
+    }}} 0]
+} -body {
+    lassign [chan configure $srv -sockname] addr name port
+    after 1000 {set ::total timeout}
+    set s [socket $addr $port]
+    try {
+        chan configure $s -translation binary
+        zlib push inflate $s
+        chan event $s readable [list apply {{s} {
+            set d [read $s]
+            if {[eof $s]} {
+                chan event $s readable {}
+                set ::total [list eof [string length $d]]
+            }
+        }} $s]
+        vwait ::total
+    } finally {
+	after cancel {set ::total timeout}
+        close $s
+    }
+    set ::total
+} -cleanup {
+    unset -nocomplain total
+    close $srv
+    rename bgerror {}
+} -result {error {invalid stored block lengths}}
+test zlib-9.11 "bug #2818131 (deflate mismatch)" -constraints zlib -setup {
+    proc bgerror {s} {set ::total [list error $s]}
+    set srv [socket -myaddr localhost -server {apply {{c a p} {
+        chan configure $c -translation binary -buffering none -blocking 0
+        zlib push deflate $c
+        puts -nonewline $c [string repeat hello 100]
+        close $c
+    }}} 0]
+} -body {
+    lassign [chan configure $srv -sockname] addr name port
+    after 1000 {set ::total timeout}
+    set s [socket $addr $port]
+    try {
+        chan configure $s -translation binary
+        zlib push gunzip $s
+        chan event $s readable [list apply {{s} {
+            set d [read $s]
+            if {[eof $s]} {
+                chan event $s readable {}
+                set ::total [list eof [string length $d]]
+            }
+        }} $s]
+        vwait ::total
+    } finally {
+	after cancel {set ::total timeout}
+        close $s
+    }
+    set ::total
+} -cleanup {
+    unset -nocomplain total
+    close $srv
+    rename bgerror {}
+} -result {error {incorrect header check}}
+
+test zlib-10.0 "bug #2818131 (close with null interp)" -constraints {
+    zlib
+} -setup {
+    proc bgerror {s} {set ::total [list error $s]}
+    set srv [socket -myaddr localhost -server {apply {{c a p} {
+        chan configure $c -translation binary
+        zlib push inflate $c
+        chan event $c readable [list apply {{c} {
+            set d [read $c]
+            if {[eof $c]} {
+                chan event $c readable {}
+                close $c
+                set ::total [list eof [string length $d]]
+            }
+        }} $c]
+    }}} 0]
+} -body {
+    lassign [chan configure $srv -sockname] addr name port
+    after 1000 {set ::total timeout}
+    set s [socket $addr $port]
+    chan configure $s -translation binary -buffering none -blocking 0
+    zlib push gzip $s
+    chan event $s xyzzy [list apply {{s} {
+        if {[gets $s line] < 0} {
+            chan close $s
+        }
+    }} $s]
+    after idle [list apply {{s} {
+        puts $s test
+        chan close $s
+        after 100 {set ::total done}
+    }} $s]
+    vwait ::total
+    after cancel {set ::total timeout}
+    after cancel {set ::total done}
+    set ::total
+} -cleanup {
+    close $srv
+    rename bgerror {}
+} -returnCodes error \
+  -result {bad event name "xyzzy": must be readable or writable}
+test zlib-10.1 "bug #2818131 (mismatch read)" -constraints {
+    zlib
+} -setup {
+    proc bgerror {s} {set ::total [list error $s]}
+    proc zlibRead {c} {
+        set d [read $c]
+        if {[eof $c]} {
+            chan event $c readable {}
+            close $c
+            set ::total [list eof [string length $d]]
+        }
+    }
+    set srv [socket -myaddr localhost -server {apply {{c a p} {
+        chan configure $c -translation binary
+        zlib push inflate $c
+        chan event $c readable [list zlibRead $c]
+    }}} 0]
+} -body {
+    lassign [chan configure $srv -sockname] addr name port
+    after 1000 {set ::total timeout}
+    set s [socket $addr $port]
+    chan configure $s -translation binary -buffering none -blocking 0
+    zlib push gzip $s
+    chan event $s readable [list zlibRead $s]
+    after idle [list apply {{s} {
+        puts $s test
+        chan close $s
+        after 100 {set ::total done}
+    }} $s]
+    vwait ::total
+    after cancel {set ::total timeout}
+    after cancel {set ::total done}
+    set ::total
+} -cleanup {
+    close $srv
+    rename bgerror {}
+    rename zlibRead {}
+} -result {error {invalid block type}}
+test zlib-10.2 "bug #2818131 (mismatch gets)" -constraints {
+    zlib
+} -setup {
+    proc bgerror {s} {set ::total [list error $s]}
+    proc zlibRead {c} {
+        if {[gets $c line] < 0} {
+            close $c
+            set ::total [list error -1]
+        } elseif {[eof $c]} {
+            chan event $c readable {}
+            close $c
+            set ::total [list eof 0]
+        }
+    }
+    set srv [socket -myaddr localhost -server {apply {{c a p} {
+        chan configure $c -translation binary
+        zlib push inflate $c
+        chan event $c readable [list zlibRead $c]
+    }}} 0]
+} -body {
+    lassign [chan configure $srv -sockname] addr name port
+    after 1000 {set ::total timeout}
+    set s [socket $addr $port]
+    chan configure $s -translation binary -buffering none -blocking 0
+    zlib push gzip $s
+    chan event $s readable [list zlibRead $s]
+    after idle [list apply {{s} {
+        puts $s test
+        chan close $s
+        after 100 {set ::total done}
+    }} $s]
+    vwait ::total
+    after cancel {set ::total timeout}
+    after cancel {set ::total done}
+    set ::total
+} -cleanup {
+    close $srv
+    rename bgerror {}
+    rename zlibRead {}
+} -result {error {invalid block type}}
+
+test zlib-11.1 "Bug #3390073: mis-appled gzip filtering" -setup {
+    set file [makeFile {} test.input]
+} -constraints zlib -body {
+    set f [open $file wb]
+    puts -nonewline [zlib push gzip $f] [string repeat "hello" 1000]
+    close $f
+    set f [open $file rb]
+    set d [read $f]
+    close $f
+    set d [zlib gunzip $d]
+    list [regexp -all "hello" $d] [string length [regsub -all "hello" $d {}]]
+} -cleanup {
+    removeFile $file
+} -result {1000 0}
+test zlib-11.2 "Bug #3390073: mis-appled gzip filtering" -setup {
+    set file [makeFile {} test.input]
+} -constraints zlib -body {
+    set f [open $file wb]
+    puts -nonewline [zlib push gzip $f -header {filename /foo/bar}] \
+	[string repeat "hello" 1000]
+    close $f
+    set f [open $file rb]
+    set d [read $f]
+    close $f
+    set d [zlib gunzip $d -header h]
+    list [regexp -all "hello" $d] [dict get $h filename] \
+	[string length [regsub -all "hello" $d {}]]
+} -cleanup {
+    removeFile $file
+} -result {1000 /foo/bar 0}
+test zlib-11.3 {Bug 3595576 variant} -setup {
+    set file [makeFile {} test.input]
+} -constraints zlib -body {
+    set f [open $file wb]
+    puts -nonewline [zlib push gzip $f -header {filename /foo/bar}] \
+	[string repeat "hello" 1000]
+    close $f
+    set f [open $file rb]
+    set d [read $f]
+    close $f
+    zlib gunzip $d -header noSuchNs::foo
+} -cleanup {
+    removeFile $file
+} -returnCodes error -result {can't set "noSuchNs::foo": parent namespace doesn't exist}
+
+test zlib-12.1 {Tk Bug 9eb55debc5} -constraints zlib -setup {
+    set stream [zlib stream compress]
+} -body {
+    for {set opts {};set y 0} {$y < 60} {incr y} {
+	for {set line {};set x 0} {$x < 100} {incr x} {
+	    append line [binary format ccc $x $y 128]
+	}
+	if {$y == 59} {
+	    set opts -finalize
+	}
+	$stream put {*}$opts $line
+    }
+    set data [$stream get]
+    list [string length $data] [string length [zlib decompress $data]]
+} -cleanup {
+    $stream close
+} -result {12026 18000}
+
+::tcltest::cleanupTests
+return
+
+# Local Variables:
+# mode: tcl
+# End:
diff --git a/tools/Makefile.in b/tools/Makefile.in
new file mode 100644
index 0000000..5e9f88e
--- /dev/null
+++ b/tools/Makefile.in
@@ -0,0 +1,67 @@
+# This makefile is used to convert Tcl manual pages into various
+# alternate formats:
+#
+#    Windows help file:  1. Build the winhelp target on Unix
+#			 2. Build the helpfile target on Windows
+#
+#    HTML:		 1. Build the html target on Unix
+
+TCL		= tcl@TCL_VERSION@
+TK		= tk@TCL_VERSION@
+VER		= @TCL_WIN_VERSION@
+
+TCL_BIN_DIR	= @TCL_BIN_DIR@
+TCL_SOURCE	= @TCL_SRC_DIR@
+TK_SOURCE	= $(TCL_SOURCE)/../$(TK)
+PRO_SOURCE	= $(TCL_SOURCE)/../pro
+ITCL_SOURCE	= $(TCL_SOURCE)/../itcl3.1.0
+
+TCL_DOCS	= $(TCL_SOURCE)/doc/*.[13n]
+
+TK_DOCS		= $(TK_SOURCE)/doc/*.[13n]
+
+PRO_DOCS	= \
+	$(PRO_SOURCE)/doc/man/procheck.1 \
+	$(PRO_SOURCE)/doc/man/prodebug.1 \
+	$(PRO_SOURCE)/doc/man/prodebug.n \
+	$(PRO_SOURCE)/doc/man/prolicense.1
+
+ITCL_DOCS	= \
+	$(ITCL_SOURCE)/itcl/doc/*.[13n] \
+	$(ITCL_SOURCE)/itk/doc/*.[13n]
+
+#	$(ITCL_SOURCE)/iwidgets3.0.0/doc/*.[13n]
+
+COREDOCS	= $(TCL_DOCS) $(TK_DOCS)
+#PRODOCS	= $(COREDOCS) $(PRO_DOCS) $(ITCL_DOCS)
+PRODOCS		= $(COREDOCS) $(PRO_DOCS)
+TCLSH		= $(TCL_BIN_DIR)/tclsh
+CC		= @CC@
+
+#
+# Targets
+#
+
+all: core
+
+pro:
+	$(MAKE) DOCS="$(PRODOCS)" VER="" rtf
+
+core:
+	$(MAKE) DOCS="$(COREDOCS)" rtf
+
+rtf: $(TCL_SOURCE)/tools/man2help.tcl man2tcl $(DOCS)
+	LD_LIBRARY_PATH=$(TCL_BIN_DIR) \
+	TCL_LIBRARY=$(TCL_SOURCE)/library \
+	$(TCLSH) $(TCL_SOURCE)/tools/man2help.tcl tcl "$(VER)" $(DOCS)
+
+winhelp: tcl.rtf
+
+man2tcl: $(TCL_SOURCE)/tools/man2tcl.c
+	$(CC) $(CFLAGS) -o man2tcl $(TCL_SOURCE)/tools/man2tcl.c
+
+clean:
+	-rm -f man2tcl *.o *.cnt *.rtf
+
+helpfile:
+	hcw /c /e tcl.hpj
diff --git a/tools/README b/tools/README
new file mode 100644
index 0000000..f4bf627
--- /dev/null
+++ b/tools/README
@@ -0,0 +1,25 @@
+This directory contains unsupported tools used to build parts of Tcl
+for distribution.
+
+
+uniParse.tcl -- Script for converting the Unicode character database
+	into a compact table stored in generic/tclUniData.c.
+
+uniClass.tcl -- Script for generating regexp class tables from the Tcl
+	"string is" classes
+
+Generating HTML files.
+The tcl-tk-man-html.tcl script from Robert Critchlow
+generates a nice set of HTML with good cross references.
+Use it like
+    tclsh tcl-tk-man-html.tcl --htmldir=/tmp/tcl8.2
+This script is very picky about the organization of man pages,
+effectively acting as a style enforcer.
+
+Generating Windows Help Files:
+1) Build tcl in the ../unix directory
+2) On UNIX, (after autoconf and configure), do
+	make
+    this converts the Nroff to RTF files.
+2) On Windows, convert the RTF to a Help doc, do
+	nmake helpfile
diff --git a/tools/checkLibraryDoc.tcl b/tools/checkLibraryDoc.tcl
new file mode 100755
index 0000000..6d147ac
--- /dev/null
+++ b/tools/checkLibraryDoc.tcl
@@ -0,0 +1,293 @@
+# checkLibraryDoc.tcl --
+#
+# This script attempts to determine what APIs exist in the source base that
+# have not been documented.  By grepping through all of the doc/*.3 man
+# pages, looking for "Pkg_*" (e.g., Tcl_ or Tk_), and comparing this list
+# against the list of Pkg_ APIs found in the source (e.g., tcl8.2/*/*.[ch])
+# we create six lists:
+#      1) APIs in Source not in Docs.
+#      2) APIs in Docs not in Source.
+#      3) Internal APIs and structs.
+#      4) Misc APIs and structs that we are not documenting.
+#      5) Command APIs (e.g., Tcl_ArrayObjCmd.)
+#      6) Proc pointers (e.g., Tcl_CloseProc.)
+#
+# Note: Each list is "a best guess" approximation.  If developers write
+# non-standard code, this script will produce erroneous results.  Each
+# list should be carefully checked for accuracy.
+#
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+# All rights reserved.
+
+
+lappend auto_path "c:/program\ files/tclpro1.2/win32-ix86/bin"
+#lappend auto_path "/home/surles/cvs/tclx8.0/tcl/unix"
+if {[catch {package require Tclx}]} {
+    puts "error: could not load TclX.  Please set TCL_LIBRARY."
+    exit 1
+}
+
+# A list of structs that are known to be undocumented.
+
+set StructList {
+    Tcl_AsyncHandler \
+    Tcl_CallFrame \
+    Tcl_Condition \
+    Tcl_Encoding \
+    Tcl_EncodingState \
+    Tcl_EncodingType \
+    Tcl_HashEntry \
+    Tcl_HashSearch \
+    Tcl_HashTable \
+    Tcl_Mutex \
+    Tcl_Pid \
+    Tcl_QueuePosition \
+    Tcl_ResolvedVarInfo \
+    Tcl_SavedResult \
+    Tcl_ThreadDataKey \
+    Tcl_ThreadId \
+    Tcl_Time \
+    Tcl_TimerToken \
+    Tcl_Token \
+    Tcl_Trace \
+    Tcl_Value \
+    Tcl_ValueType \
+    Tcl_Var \
+    Tk_3DBorder \
+    Tk_ArgvInfo \
+    Tk_BindingTable \
+    Tk_Canvas \
+    Tk_CanvasTextInfo \
+    Tk_ConfigSpec \
+    Tk_ConfigTypes \
+    Tk_Cursor \
+    Tk_CustomOption \
+    Tk_ErrorHandler \
+    Tk_FakeWin \
+    Tk_Font \
+    Tk_FontMetrics \
+    Tk_GeomMgr \
+    Tk_Image \
+    Tk_ImageMaster \
+    Tk_ImageType \
+    Tk_Item \
+    Tk_ItemType \
+    Tk_OptionSpec\
+    Tk_OptionTable \
+    Tk_OptionType \
+    Tk_PhotoHandle \
+    Tk_PhotoImageBlock \
+    Tk_PhotoImageFormat \
+    Tk_PostscriptInfo \
+    Tk_SavedOption \
+    Tk_SavedOptions \
+    Tk_SegType \
+    Tk_TextLayout \
+    Tk_Window \
+}
+
+# Misc junk that appears in the comments of the source.  This just
+# allows us to filter comments that "fool" the script.
+
+set CommentList {
+    Tcl_Create\[Obj\]Command \
+    Tcl_DecrRefCount\\n \
+    Tcl_NewObj\\n \
+    Tk_GetXXX \
+}
+
+# Main entry point to this script.
+
+proc main {} {
+    global argv0
+    global argv
+
+    set len [llength $argv]
+    if {($len != 2) && ($len != 3)} {
+	puts "usage: $argv0 pkgName pkgDir \[outFile\]"
+	puts "   pkgName == Tcl,Tk"
+	puts "   pkgDir  == /home/surles/cvs/tcl8.2"
+	exit 1
+    }
+
+    set pkg [lindex $argv 0]
+    set dir [lindex $argv 1]
+    if {[llength $argv] == 3} {
+	set file [open [lindex $argv 2] w]
+    } else {
+	set file stdout
+    }
+
+    foreach {c d} [compare [grepCode $dir $pkg] [grepDocs $dir $pkg]] {}
+    filter $c $d $dir $pkg $file
+
+    if {$file ne "stdout"} {
+	close $file
+    }
+    return
+}
+
+# Intersect the two list and write out the sets of APIs in one
+# list that is not in the other.
+
+proc compare {list1 list2} {
+    set inter [intersect3 $list1 $list2]
+    return [list [lindex $inter 0] [lindex $inter 2]]
+}
+
+# Filter the lists into the six lists we report on.  Then write
+# the results to the file.
+
+proc filter {code docs dir pkg {outFile stdout}} {
+    set apis  {}
+
+    # A list of Tcl command APIs.  These are not documented.
+    # This list should just be verified for accuracy.
+
+    set cmds  {}
+
+    # A list of proc pointer structs.  These are not documented.
+    # This list should just be verified for accuracy.
+
+    set procs {}
+
+    # A list of internal declarations.  These are not documented.
+    # This list should just be verified for accuracy.
+
+    set decls [grepDecl $dir $pkg]
+
+    # A list of misc. procedure declarations that are not documented.
+    # This list should just be verified for accuracy.
+
+    set misc [grepMisc $dir $pkg]
+
+    set pat1 ".*(${pkg}_\[A-z0-9]+).*$"
+
+    # A list of APIs in the source, not in the docs.
+    # This list should just be verified for accuracy.
+
+    foreach x $code {
+	if {[string match *Cmd $x]} {
+	    if {[string match ${pkg}* $x]} {
+		lappend cmds $x
+	    }
+	} elseif {[string match *Proc $x]} {
+	    if {[string match ${pkg}* $x]} {
+		lappend procs $x
+	    }
+	} elseif {[lsearch -exact $decls $x] >= 0} {
+	    # No Op.
+	} elseif {[lsearch -exact $misc $x] >= 0} {
+	    # No Op.
+	} else {
+	    lappend apis $x
+	}
+    }
+
+    dump $apis  "APIs in Source not in Docs." $outFile
+    dump $docs  "APIs in Docs not in Source." $outFile
+    dump $decls "Internal APIs and structs."  $outFile
+    dump $misc  "Misc APIs and structs that we are not documenting." $outFile
+    dump $cmds  "Command APIs."  $outFile
+    dump $procs "Proc pointers." $outFile
+    return
+}
+
+# Print the list of APIs if the list is not null.
+
+proc dump {list title file} {
+    if {$list ne ""} {
+	puts $file ""
+	puts $file $title
+	puts $file "---------------------------------------------------------"
+	foreach x $list {
+	    puts $file $x
+	}
+    }
+}
+
+# Grep into "dir/*/*.[ch]" looking for APIs that match $pkg_*.
+# (e.g., Tcl_Exit).  Return a list of APIs.
+
+proc grepCode {dir pkg} {
+    set apis [myGrep "${pkg}_\.\*" "${dir}/\*/\*\.\[ch\]"]
+    set pat1 ".*(${pkg}_\[A-z0-9]+).*$"
+
+    foreach a $apis {
+	if {[regexp --  $pat1 $a main n1]} {
+	    set result([string trim $n1]) 1
+	}
+    }
+    return [lsort [array names result]]
+}
+
+# Grep into "dir/doc/*.3" looking for APIs that match $pkg_*.
+# (e.g., Tcl_Exit).  Return a list of APIs.
+
+proc grepDocs {dir pkg} {
+    set apis [myGrep "\\fB${pkg}_\.\*\\fR" "${dir}/doc/\*\.3"]
+    set pat1 ".*(${pkg}_\[A-z0-9]+)\\\\fR.*$"
+
+    foreach a $apis {
+	if {[regexp -- $pat1 $a main n1]} {
+	    set result([string trim $n1]) 1
+	}
+    }
+    return [lsort [array names result]]
+}
+
+# Grep into "generic/pkgIntDecls.h" looking for APIs that match $pkg_*.
+# (e.g., Tcl_Export).  Return a list of APIs.
+
+proc grepDecl {dir pkg} {
+    set file [file join $dir generic "[string tolower $pkg]IntDecls.h"]
+    set apis [myGrep "^EXTERN.*\[ \t\]${pkg}_.*" $file]
+    set pat1 ".*(${pkg}_\[A-z0-9]+).*$"
+
+    foreach a $apis {
+	if {[regexp -- $pat1 $a main n1]} {
+	    set result([string trim $n1]) 1
+	}
+    }
+    return [lsort [array names result]]
+}
+
+# Grep into "*/*.[ch]" looking for APIs that match $pkg_Db*.
+# (e.g., Tcl_DbCkalloc).  Return a list of APIs.
+
+proc grepMisc {dir pkg} {
+    global CommentList
+    global StructList
+
+    set apis [myGrep "^EXTERN.*\[ \t\]${pkg}_Db.*" "${dir}/\*/\*\.\[ch\]"]
+    set pat1 ".*(${pkg}_\[A-z0-9]+).*$"
+
+    foreach a $apis {
+	if {[regexp -- $pat1 $a main n1]} {
+	    set dbg([string trim $n1]) 1
+	}
+    }
+
+    set result {}
+    eval {lappend result} $StructList
+    eval {lappend result} [lsort [array names dbg]]
+    eval {lappend result} $CommentList
+    return $result
+}
+
+proc myGrep {searchPat globPat} {
+    set result {}
+    foreach file [glob -nocomplain $globPat] {
+	set file [open $file r]
+	set data [read $file]
+	close $file
+	foreach line [split $data "\n"] {
+	    if {[regexp "^.*${searchPat}.*\$" $line]} {
+		lappend result $line
+	    }
+	}
+    }
+    return $result
+}
+main
+
diff --git a/tools/configure b/tools/configure
new file mode 100755
index 0000000..3d30039
--- /dev/null
+++ b/tools/configure
@@ -0,0 +1,2170 @@
+#! /bin/sh
+# Guess values for system-dependent variables and create Makefiles.
+# Generated by GNU Autoconf 2.59.
+#
+# Copyright (C) 2003 Free Software Foundation, Inc.
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+## --------------------- ##
+## M4sh Initialization.  ##
+## --------------------- ##
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+  emulate sh
+  NULLCMD=:
+  # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
+  set -o posix
+fi
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# Support unset when possible.
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+  as_unset=unset
+else
+  as_unset=false
+fi
+
+
+# Work around bugs in pre-3.0 UWIN ksh.
+$as_unset ENV MAIL MAILPATH
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+for as_var in \
+  LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
+  LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
+  LC_TELEPHONE LC_TIME
+do
+  if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
+    eval $as_var=C; export $as_var
+  else
+    $as_unset $as_var
+  fi
+done
+
+# Required to use basename.
+if expr a : '\(a\)' >/dev/null 2>&1; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
+  as_basename=basename
+else
+  as_basename=false
+fi
+
+
+# Name of the executable.
+as_me=`$as_basename "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+	 X"$0" : 'X\(//\)$' \| \
+	 X"$0" : 'X\(/\)$' \| \
+	 .     : '\(.\)' 2>/dev/null ||
+echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
+  	  /^X\/\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\/\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`
+
+
+# PATH needs CR, and LINENO needs CR and PATH.
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  echo "#! /bin/sh" >conf$$.sh
+  echo  "exit 0"   >>conf$$.sh
+  chmod +x conf$$.sh
+  if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+    PATH_SEPARATOR=';'
+  else
+    PATH_SEPARATOR=:
+  fi
+  rm -f conf$$.sh
+fi
+
+
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2"  || {
+  # Find who we are.  Look in the path if we contain no path at all
+  # relative or not.
+  case $0 in
+    *[\\/]* ) as_myself=$0 ;;
+    *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+
+       ;;
+  esac
+  # We did not find ourselves, most probably we were run as `sh COMMAND'
+  # in which case we are not to be found in the path.
+  if test "x$as_myself" = x; then
+    as_myself=$0
+  fi
+  if test ! -f "$as_myself"; then
+    { echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2
+   { (exit 1); exit 1; }; }
+  fi
+  case $CONFIG_SHELL in
+  '')
+    as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for as_base in sh bash ksh sh5; do
+	 case $as_dir in
+	 /*)
+	   if ("$as_dir/$as_base" -c '
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2" ') 2>/dev/null; then
+	     $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; }
+	     $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; }
+	     CONFIG_SHELL=$as_dir/$as_base
+	     export CONFIG_SHELL
+	     exec "$CONFIG_SHELL" "$0" ${1+"$@"}
+	   fi;;
+	 esac
+       done
+done
+;;
+  esac
+
+  # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+  # uniformly replaced by the line number.  The first 'sed' inserts a
+  # line-number line before each line; the second 'sed' does the real
+  # work.  The second script uses 'N' to pair each line-number line
+  # with the numbered line, and appends trailing '-' during
+  # substitution so that $LINENO is not a special case at line end.
+  # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+  # second 'sed' script.  Blame Lee E. McMahon for sed's syntax.  :-)
+  sed '=' <$as_myself |
+    sed '
+      N
+      s,$,-,
+      : loop
+      s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
+      t loop
+      s,-$,,
+      s,^['$as_cr_digits']*\n,,
+    ' >$as_me.lineno &&
+  chmod +x $as_me.lineno ||
+    { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2
+   { (exit 1); exit 1; }; }
+
+  # Don't try to exec as it changes $[0], causing all sort of problems
+  # (the dirname of $[0] is not the place where we might find the
+  # original and so on.  Autoconf is especially sensible to this).
+  . ./$as_me.lineno
+  # Exit status is that of the last command.
+  exit
+}
+
+
+case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
+  *c*,-n*) ECHO_N= ECHO_C='
+' ECHO_T='	' ;;
+  *c*,*  ) ECHO_N=-n ECHO_C= ECHO_T= ;;
+  *)       ECHO_N= ECHO_C='\c' ECHO_T= ;;
+esac
+
+if expr a : '\(a\)' >/dev/null 2>&1; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+rm -f conf$$ conf$$.exe conf$$.file
+echo >conf$$.file
+if ln -s conf$$.file conf$$ 2>/dev/null; then
+  # We could just check for DJGPP; but this test a) works b) is more generic
+  # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).
+  if test -f conf$$.exe; then
+    # Don't use ln at all; we don't have any links
+    as_ln_s='cp -p'
+  else
+    as_ln_s='ln -s'
+  fi
+elif ln conf$$.file conf$$ 2>/dev/null; then
+  as_ln_s=ln
+else
+  as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.file
+
+if mkdir -p . 2>/dev/null; then
+  as_mkdir_p=:
+else
+  test -d ./-p && rmdir ./-p
+  as_mkdir_p=false
+fi
+
+as_executable_p="test -f"
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.
+as_nl='
+'
+IFS=" 	$as_nl"
+
+# CDPATH.
+$as_unset CDPATH
+
+
+# Name of the host.
+# hostname on some systems (SVR3.2, Linux) returns a bogus exit status,
+# so uname gets run too.
+ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
+
+exec 6>&1
+
+#
+# Initializations.
+#
+ac_default_prefix=/usr/local
+ac_config_libobj_dir=.
+cross_compiling=no
+subdirs=
+MFLAGS=
+MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+
+# Maximum number of lines to put in a shell here document.
+# This variable seems obsolete.  It should probably be removed, and
+# only ac_max_sed_lines should be used.
+: ${ac_max_here_lines=38}
+
+# Identity of this package.
+PACKAGE_NAME=
+PACKAGE_TARNAME=
+PACKAGE_VERSION=
+PACKAGE_STRING=
+PACKAGE_BUGREPORT=
+
+ac_unique_file="man2tcl.c"
+ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS TCL_WIN_VERSION CC TCL_VERSION TCL_PATCH_LEVEL TCL_SRC_DIR TCL_BIN_DIR LIBOBJS LTLIBOBJS'
+ac_subst_files=''
+
+# Initialize some variables set by options.
+ac_init_help=
+ac_init_version=false
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+cache_file=/dev/null
+exec_prefix=NONE
+no_create=
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+verbose=
+x_includes=NONE
+x_libraries=NONE
+
+# Installation directory options.
+# These are left unexpanded so users can "make install exec_prefix=/foo"
+# and all the variables that are supposed to be based on exec_prefix
+# by default will actually change.
+# Use braces instead of parens because sh, perl, etc. also accept them.
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datadir='${prefix}/share'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+libdir='${exec_prefix}/lib'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+infodir='${prefix}/info'
+mandir='${prefix}/man'
+
+ac_prev=
+for ac_option
+do
+  # If the previous option needs an argument, assign it.
+  if test -n "$ac_prev"; then
+    eval "$ac_prev=\$ac_option"
+    ac_prev=
+    continue
+  fi
+
+  ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'`
+
+  # Accept the important Cygnus configure options, so we can diagnose typos.
+
+  case $ac_option in
+
+  -bindir | --bindir | --bindi | --bind | --bin | --bi)
+    ac_prev=bindir ;;
+  -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+    bindir=$ac_optarg ;;
+
+  -build | --build | --buil | --bui | --bu)
+    ac_prev=build_alias ;;
+  -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+    build_alias=$ac_optarg ;;
+
+  -cache-file | --cache-file | --cache-fil | --cache-fi \
+  | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+    ac_prev=cache_file ;;
+  -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+  | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+    cache_file=$ac_optarg ;;
+
+  --config-cache | -C)
+    cache_file=config.cache ;;
+
+  -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
+    ac_prev=datadir ;;
+  -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
+  | --da=*)
+    datadir=$ac_optarg ;;
+
+  -disable-* | --disable-*)
+    ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid feature name: $ac_feature" >&2
+   { (exit 1); exit 1; }; }
+    ac_feature=`echo $ac_feature | sed 's/-/_/g'`
+    eval "enable_$ac_feature=no" ;;
+
+  -enable-* | --enable-*)
+    ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid feature name: $ac_feature" >&2
+   { (exit 1); exit 1; }; }
+    ac_feature=`echo $ac_feature | sed 's/-/_/g'`
+    case $ac_option in
+      *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
+      *) ac_optarg=yes ;;
+    esac
+    eval "enable_$ac_feature='$ac_optarg'" ;;
+
+  -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+  | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+  | --exec | --exe | --ex)
+    ac_prev=exec_prefix ;;
+  -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+  | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+  | --exec=* | --exe=* | --ex=*)
+    exec_prefix=$ac_optarg ;;
+
+  -gas | --gas | --ga | --g)
+    # Obsolete; use --with-gas.
+    with_gas=yes ;;
+
+  -help | --help | --hel | --he | -h)
+    ac_init_help=long ;;
+  -help=r* | --help=r* | --hel=r* | --he=r* | -hr*)
+    ac_init_help=recursive ;;
+  -help=s* | --help=s* | --hel=s* | --he=s* | -hs*)
+    ac_init_help=short ;;
+
+  -host | --host | --hos | --ho)
+    ac_prev=host_alias ;;
+  -host=* | --host=* | --hos=* | --ho=*)
+    host_alias=$ac_optarg ;;
+
+  -includedir | --includedir | --includedi | --included | --include \
+  | --includ | --inclu | --incl | --inc)
+    ac_prev=includedir ;;
+  -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+  | --includ=* | --inclu=* | --incl=* | --inc=*)
+    includedir=$ac_optarg ;;
+
+  -infodir | --infodir | --infodi | --infod | --info | --inf)
+    ac_prev=infodir ;;
+  -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+    infodir=$ac_optarg ;;
+
+  -libdir | --libdir | --libdi | --libd)
+    ac_prev=libdir ;;
+  -libdir=* | --libdir=* | --libdi=* | --libd=*)
+    libdir=$ac_optarg ;;
+
+  -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+  | --libexe | --libex | --libe)
+    ac_prev=libexecdir ;;
+  -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+  | --libexe=* | --libex=* | --libe=*)
+    libexecdir=$ac_optarg ;;
+
+  -localstatedir | --localstatedir | --localstatedi | --localstated \
+  | --localstate | --localstat | --localsta | --localst \
+  | --locals | --local | --loca | --loc | --lo)
+    ac_prev=localstatedir ;;
+  -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+  | --localstate=* | --localstat=* | --localsta=* | --localst=* \
+  | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
+    localstatedir=$ac_optarg ;;
+
+  -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+    ac_prev=mandir ;;
+  -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+    mandir=$ac_optarg ;;
+
+  -nfp | --nfp | --nf)
+    # Obsolete; use --without-fp.
+    with_fp=no ;;
+
+  -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+  | --no-cr | --no-c | -n)
+    no_create=yes ;;
+
+  -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+  | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+    no_recursion=yes ;;
+
+  -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+  | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+  | --oldin | --oldi | --old | --ol | --o)
+    ac_prev=oldincludedir ;;
+  -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+  | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+  | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+    oldincludedir=$ac_optarg ;;
+
+  -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+    ac_prev=prefix ;;
+  -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+    prefix=$ac_optarg ;;
+
+  -program-prefix | --program-prefix | --program-prefi | --program-pref \
+  | --program-pre | --program-pr | --program-p)
+    ac_prev=program_prefix ;;
+  -program-prefix=* | --program-prefix=* | --program-prefi=* \
+  | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+    program_prefix=$ac_optarg ;;
+
+  -program-suffix | --program-suffix | --program-suffi | --program-suff \
+  | --program-suf | --program-su | --program-s)
+    ac_prev=program_suffix ;;
+  -program-suffix=* | --program-suffix=* | --program-suffi=* \
+  | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+    program_suffix=$ac_optarg ;;
+
+  -program-transform-name | --program-transform-name \
+  | --program-transform-nam | --program-transform-na \
+  | --program-transform-n | --program-transform- \
+  | --program-transform | --program-transfor \
+  | --program-transfo | --program-transf \
+  | --program-trans | --program-tran \
+  | --progr-tra | --program-tr | --program-t)
+    ac_prev=program_transform_name ;;
+  -program-transform-name=* | --program-transform-name=* \
+  | --program-transform-nam=* | --program-transform-na=* \
+  | --program-transform-n=* | --program-transform-=* \
+  | --program-transform=* | --program-transfor=* \
+  | --program-transfo=* | --program-transf=* \
+  | --program-trans=* | --program-tran=* \
+  | --progr-tra=* | --program-tr=* | --program-t=*)
+    program_transform_name=$ac_optarg ;;
+
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil)
+    silent=yes ;;
+
+  -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+    ac_prev=sbindir ;;
+  -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+  | --sbi=* | --sb=*)
+    sbindir=$ac_optarg ;;
+
+  -sharedstatedir | --sharedstatedir | --sharedstatedi \
+  | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+  | --sharedst | --shareds | --shared | --share | --shar \
+  | --sha | --sh)
+    ac_prev=sharedstatedir ;;
+  -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+  | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+  | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+  | --sha=* | --sh=*)
+    sharedstatedir=$ac_optarg ;;
+
+  -site | --site | --sit)
+    ac_prev=site ;;
+  -site=* | --site=* | --sit=*)
+    site=$ac_optarg ;;
+
+  -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+    ac_prev=srcdir ;;
+  -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+    srcdir=$ac_optarg ;;
+
+  -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+  | --syscon | --sysco | --sysc | --sys | --sy)
+    ac_prev=sysconfdir ;;
+  -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+  | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+    sysconfdir=$ac_optarg ;;
+
+  -target | --target | --targe | --targ | --tar | --ta | --t)
+    ac_prev=target_alias ;;
+  -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+    target_alias=$ac_optarg ;;
+
+  -v | -verbose | --verbose | --verbos | --verbo | --verb)
+    verbose=yes ;;
+
+  -version | --version | --versio | --versi | --vers | -V)
+    ac_init_version=: ;;
+
+  -with-* | --with-*)
+    ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid package name: $ac_package" >&2
+   { (exit 1); exit 1; }; }
+    ac_package=`echo $ac_package| sed 's/-/_/g'`
+    case $ac_option in
+      *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
+      *) ac_optarg=yes ;;
+    esac
+    eval "with_$ac_package='$ac_optarg'" ;;
+
+  -without-* | --without-*)
+    ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid package name: $ac_package" >&2
+   { (exit 1); exit 1; }; }
+    ac_package=`echo $ac_package | sed 's/-/_/g'`
+    eval "with_$ac_package=no" ;;
+
+  --x)
+    # Obsolete; use --with-x.
+    with_x=yes ;;
+
+  -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+  | --x-incl | --x-inc | --x-in | --x-i)
+    ac_prev=x_includes ;;
+  -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+  | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+    x_includes=$ac_optarg ;;
+
+  -x-libraries | --x-libraries | --x-librarie | --x-librari \
+  | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+    ac_prev=x_libraries ;;
+  -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+  | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+    x_libraries=$ac_optarg ;;
+
+  -*) { echo "$as_me: error: unrecognized option: $ac_option
+Try \`$0 --help' for more information." >&2
+   { (exit 1); exit 1; }; }
+    ;;
+
+  *=*)
+    ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
+    # Reject names that are not valid shell variable names.
+    expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null &&
+      { echo "$as_me: error: invalid variable name: $ac_envvar" >&2
+   { (exit 1); exit 1; }; }
+    ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`
+    eval "$ac_envvar='$ac_optarg'"
+    export $ac_envvar ;;
+
+  *)
+    # FIXME: should be removed in autoconf 3.0.
+    echo "$as_me: WARNING: you should use --build, --host, --target" >&2
+    expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
+      echo "$as_me: WARNING: invalid host type: $ac_option" >&2
+    : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}
+    ;;
+
+  esac
+done
+
+if test -n "$ac_prev"; then
+  ac_option=--`echo $ac_prev | sed 's/_/-/g'`
+  { echo "$as_me: error: missing argument to $ac_option" >&2
+   { (exit 1); exit 1; }; }
+fi
+
+# Be sure to have absolute paths.
+for ac_var in exec_prefix prefix
+do
+  eval ac_val=$`echo $ac_var`
+  case $ac_val in
+    [\\/$]* | ?:[\\/]* | NONE | '' ) ;;
+    *)  { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
+   { (exit 1); exit 1; }; };;
+  esac
+done
+
+# Be sure to have absolute paths.
+for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \
+	      localstatedir libdir includedir oldincludedir infodir mandir
+do
+  eval ac_val=$`echo $ac_var`
+  case $ac_val in
+    [\\/$]* | ?:[\\/]* ) ;;
+    *)  { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
+   { (exit 1); exit 1; }; };;
+  esac
+done
+
+# There might be people who depend on the old broken behavior: `$host'
+# used to hold the argument of --host etc.
+# FIXME: To remove some day.
+build=$build_alias
+host=$host_alias
+target=$target_alias
+
+# FIXME: To remove some day.
+if test "x$host_alias" != x; then
+  if test "x$build_alias" = x; then
+    cross_compiling=maybe
+    echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host.
+    If a cross compiler is detected then cross compile mode will be used." >&2
+  elif test "x$build_alias" != "x$host_alias"; then
+    cross_compiling=yes
+  fi
+fi
+
+ac_tool_prefix=
+test -n "$host_alias" && ac_tool_prefix=$host_alias-
+
+test "$silent" = yes && exec 6>/dev/null
+
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+  ac_srcdir_defaulted=yes
+  # Try the directory containing this script, then its parent.
+  ac_confdir=`(dirname "$0") 2>/dev/null ||
+$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$0" : 'X\(//\)[^/]' \| \
+	 X"$0" : 'X\(//\)$' \| \
+	 X"$0" : 'X\(/\)' \| \
+	 .     : '\(.\)' 2>/dev/null ||
+echo X"$0" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+  	  /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+  	  /^X\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`
+  srcdir=$ac_confdir
+  if test ! -r $srcdir/$ac_unique_file; then
+    srcdir=..
+  fi
+else
+  ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+  if test "$ac_srcdir_defaulted" = yes; then
+    { echo "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2
+   { (exit 1); exit 1; }; }
+  else
+    { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2
+   { (exit 1); exit 1; }; }
+  fi
+fi
+(cd $srcdir && test -r ./$ac_unique_file) 2>/dev/null ||
+  { echo "$as_me: error: sources are in $srcdir, but \`cd $srcdir' does not work" >&2
+   { (exit 1); exit 1; }; }
+srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'`
+ac_env_build_alias_set=${build_alias+set}
+ac_env_build_alias_value=$build_alias
+ac_cv_env_build_alias_set=${build_alias+set}
+ac_cv_env_build_alias_value=$build_alias
+ac_env_host_alias_set=${host_alias+set}
+ac_env_host_alias_value=$host_alias
+ac_cv_env_host_alias_set=${host_alias+set}
+ac_cv_env_host_alias_value=$host_alias
+ac_env_target_alias_set=${target_alias+set}
+ac_env_target_alias_value=$target_alias
+ac_cv_env_target_alias_set=${target_alias+set}
+ac_cv_env_target_alias_value=$target_alias
+
+#
+# Report the --help message.
+#
+if test "$ac_init_help" = "long"; then
+  # Omit some internal or obsolete options to make the list less imposing.
+  # This message is too long to be a string in the A/UX 3.1 sh.
+  cat <<_ACEOF
+\`configure' configures this package to adapt to many kinds of systems.
+
+Usage: $0 [OPTION]... [VAR=VALUE]...
+
+To assign environment variables (e.g., CC, CFLAGS...), specify them as
+VAR=VALUE.  See below for descriptions of some of the useful variables.
+
+Defaults for the options are specified in brackets.
+
+Configuration:
+  -h, --help              display this help and exit
+      --help=short        display options specific to this package
+      --help=recursive    display the short help of all the included packages
+  -V, --version           display version information and exit
+  -q, --quiet, --silent   do not print \`checking...' messages
+      --cache-file=FILE   cache test results in FILE [disabled]
+  -C, --config-cache      alias for \`--cache-file=config.cache'
+  -n, --no-create         do not create output files
+      --srcdir=DIR        find the sources in DIR [configure dir or \`..']
+
+_ACEOF
+
+  cat <<_ACEOF
+Installation directories:
+  --prefix=PREFIX         install architecture-independent files in PREFIX
+			  [$ac_default_prefix]
+  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX
+			  [PREFIX]
+
+By default, \`make install' will install all the files in
+\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc.  You can specify
+an installation prefix other than \`$ac_default_prefix' using \`--prefix',
+for instance \`--prefix=\$HOME'.
+
+For better control, use the options below.
+
+Fine tuning of the installation directories:
+  --bindir=DIR           user executables [EPREFIX/bin]
+  --sbindir=DIR          system admin executables [EPREFIX/sbin]
+  --libexecdir=DIR       program executables [EPREFIX/libexec]
+  --datadir=DIR          read-only architecture-independent data [PREFIX/share]
+  --sysconfdir=DIR       read-only single-machine data [PREFIX/etc]
+  --sharedstatedir=DIR   modifiable architecture-independent data [PREFIX/com]
+  --localstatedir=DIR    modifiable single-machine data [PREFIX/var]
+  --libdir=DIR           object code libraries [EPREFIX/lib]
+  --includedir=DIR       C header files [PREFIX/include]
+  --oldincludedir=DIR    C header files for non-gcc [/usr/include]
+  --infodir=DIR          info documentation [PREFIX/info]
+  --mandir=DIR           man documentation [PREFIX/man]
+_ACEOF
+
+  cat <<\_ACEOF
+_ACEOF
+fi
+
+if test -n "$ac_init_help"; then
+
+  cat <<\_ACEOF
+
+Optional Packages:
+  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
+  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
+  --with-tcl=DIR          use Tcl $DEF_VER binaries from DIR
+
+_ACEOF
+fi
+
+if test "$ac_init_help" = "recursive"; then
+  # If there are subdirs, report their specific --help.
+  ac_popdir=`pwd`
+  for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
+    test -d $ac_dir || continue
+    ac_builddir=.
+
+if test "$ac_dir" != .; then
+  ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+  # A "../" for each directory in $ac_dir_suffix.
+  ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
+else
+  ac_dir_suffix= ac_top_builddir=
+fi
+
+case $srcdir in
+  .)  # No --srcdir option.  We are building in place.
+    ac_srcdir=.
+    if test -z "$ac_top_builddir"; then
+       ac_top_srcdir=.
+    else
+       ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
+    fi ;;
+  [\\/]* | ?:[\\/]* )  # Absolute path.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir ;;
+  *) # Relative path.
+    ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_builddir$srcdir ;;
+esac
+
+# Do not use `cd foo && pwd` to compute absolute paths, because
+# the directories may not exist.
+case `pwd` in
+.) ac_abs_builddir="$ac_dir";;
+*)
+  case "$ac_dir" in
+  .) ac_abs_builddir=`pwd`;;
+  [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";;
+  *) ac_abs_builddir=`pwd`/"$ac_dir";;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_builddir=${ac_top_builddir}.;;
+*)
+  case ${ac_top_builddir}. in
+  .) ac_abs_top_builddir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;;
+  *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_srcdir=$ac_srcdir;;
+*)
+  case $ac_srcdir in
+  .) ac_abs_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;;
+  *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_srcdir=$ac_top_srcdir;;
+*)
+  case $ac_top_srcdir in
+  .) ac_abs_top_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;;
+  *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;;
+  esac;;
+esac
+
+    cd $ac_dir
+    # Check for guested configure; otherwise get Cygnus style configure.
+    if test -f $ac_srcdir/configure.gnu; then
+      echo
+      $SHELL $ac_srcdir/configure.gnu  --help=recursive
+    elif test -f $ac_srcdir/configure; then
+      echo
+      $SHELL $ac_srcdir/configure  --help=recursive
+    elif test -f $ac_srcdir/configure.ac ||
+	   test -f $ac_srcdir/configure.in; then
+      echo
+      $ac_configure --help
+    else
+      echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
+    fi
+    cd $ac_popdir
+  done
+fi
+
+test -n "$ac_init_help" && exit 0
+if $ac_init_version; then
+  cat <<\_ACEOF
+
+Copyright (C) 2003 Free Software Foundation, Inc.
+This configure script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it.
+_ACEOF
+  exit 0
+fi
+exec 5>config.log
+cat >&5 <<_ACEOF
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+
+It was created by $as_me, which was
+generated by GNU Autoconf 2.59.  Invocation command line was
+
+  $ $0 $@
+
+_ACEOF
+{
+cat <<_ASUNAME
+## --------- ##
+## Platform. ##
+## --------- ##
+
+hostname = `(hostname || uname -n) 2>/dev/null | sed 1q`
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown`
+/bin/uname -X     = `(/bin/uname -X) 2>/dev/null     || echo unknown`
+
+/bin/arch              = `(/bin/arch) 2>/dev/null              || echo unknown`
+/usr/bin/arch -k       = `(/usr/bin/arch -k) 2>/dev/null       || echo unknown`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
+hostinfo               = `(hostinfo) 2>/dev/null               || echo unknown`
+/bin/machine           = `(/bin/machine) 2>/dev/null           || echo unknown`
+/usr/bin/oslevel       = `(/usr/bin/oslevel) 2>/dev/null       || echo unknown`
+/bin/universe          = `(/bin/universe) 2>/dev/null          || echo unknown`
+
+_ASUNAME
+
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  echo "PATH: $as_dir"
+done
+
+} >&5
+
+cat >&5 <<_ACEOF
+
+
+## ----------- ##
+## Core tests. ##
+## ----------- ##
+
+_ACEOF
+
+
+# Keep a trace of the command line.
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Strip out --silent because we don't want to record it for future runs.
+# Also quote any args containing shell meta-characters.
+# Make two passes to allow for proper duplicate-argument suppression.
+ac_configure_args=
+ac_configure_args0=
+ac_configure_args1=
+ac_sep=
+ac_must_keep_next=false
+for ac_pass in 1 2
+do
+  for ac_arg
+  do
+    case $ac_arg in
+    -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;;
+    -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+    | -silent | --silent | --silen | --sile | --sil)
+      continue ;;
+    *" "*|*"	"*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
+      ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+    esac
+    case $ac_pass in
+    1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;;
+    2)
+      ac_configure_args1="$ac_configure_args1 '$ac_arg'"
+      if test $ac_must_keep_next = true; then
+	ac_must_keep_next=false # Got value, back to normal.
+      else
+	case $ac_arg in
+	  *=* | --config-cache | -C | -disable-* | --disable-* \
+	  | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \
+	  | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \
+	  | -with-* | --with-* | -without-* | --without-* | --x)
+	    case "$ac_configure_args0 " in
+	      "$ac_configure_args1"*" '$ac_arg' "* ) continue ;;
+	    esac
+	    ;;
+	  -* ) ac_must_keep_next=true ;;
+	esac
+      fi
+      ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'"
+      # Get rid of the leading space.
+      ac_sep=" "
+      ;;
+    esac
+  done
+done
+$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; }
+$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; }
+
+# When interrupted or exit'd, cleanup temporary files, and complete
+# config.log.  We remove comments because anyway the quotes in there
+# would cause problems or look ugly.
+# WARNING: Be sure not to use single quotes in there, as some shells,
+# such as our DU 5.0 friend, will then `close' the trap.
+trap 'exit_status=$?
+  # Save into config.log some information that might help in debugging.
+  {
+    echo
+
+    cat <<\_ASBOX
+## ---------------- ##
+## Cache variables. ##
+## ---------------- ##
+_ASBOX
+    echo
+    # The following way of writing the cache mishandles newlines in values,
+{
+  (set) 2>&1 |
+    case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in
+    *ac_space=\ *)
+      sed -n \
+	"s/'"'"'/'"'"'\\\\'"'"''"'"'/g;
+	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p"
+      ;;
+    *)
+      sed -n \
+	"s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
+      ;;
+    esac;
+}
+    echo
+
+    cat <<\_ASBOX
+## ----------------- ##
+## Output variables. ##
+## ----------------- ##
+_ASBOX
+    echo
+    for ac_var in $ac_subst_vars
+    do
+      eval ac_val=$`echo $ac_var`
+      echo "$ac_var='"'"'$ac_val'"'"'"
+    done | sort
+    echo
+
+    if test -n "$ac_subst_files"; then
+      cat <<\_ASBOX
+## ------------- ##
+## Output files. ##
+## ------------- ##
+_ASBOX
+      echo
+      for ac_var in $ac_subst_files
+      do
+	eval ac_val=$`echo $ac_var`
+	echo "$ac_var='"'"'$ac_val'"'"'"
+      done | sort
+      echo
+    fi
+
+    if test -s confdefs.h; then
+      cat <<\_ASBOX
+## ----------- ##
+## confdefs.h. ##
+## ----------- ##
+_ASBOX
+      echo
+      sed "/^$/d" confdefs.h | sort
+      echo
+    fi
+    test "$ac_signal" != 0 &&
+      echo "$as_me: caught signal $ac_signal"
+    echo "$as_me: exit $exit_status"
+  } >&5
+  rm -f core *.core &&
+  rm -rf conftest* confdefs* conf$$* $ac_clean_files &&
+    exit $exit_status
+     ' 0
+for ac_signal in 1 2 13 15; do
+  trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal
+done
+ac_signal=0
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo >confdefs.h
+
+# Predefined preprocessor variables.
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_NAME "$PACKAGE_NAME"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_VERSION "$PACKAGE_VERSION"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_STRING "$PACKAGE_STRING"
+_ACEOF
+
+
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
+_ACEOF
+
+
+# Let the site file select an alternate cache file if it wants to.
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+  if test "x$prefix" != xNONE; then
+    CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+  else
+    CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+  fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+  if test -r "$ac_site_file"; then
+    { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5
+echo "$as_me: loading site script $ac_site_file" >&6;}
+    sed 's/^/| /' "$ac_site_file" >&5
+    . "$ac_site_file"
+  fi
+done
+
+if test -r "$cache_file"; then
+  # Some versions of bash will fail to source /dev/null (special
+  # files actually), so we avoid doing that.
+  if test -f "$cache_file"; then
+    { echo "$as_me:$LINENO: loading cache $cache_file" >&5
+echo "$as_me: loading cache $cache_file" >&6;}
+    case $cache_file in
+      [\\/]* | ?:[\\/]* ) . $cache_file;;
+      *)                      . ./$cache_file;;
+    esac
+  fi
+else
+  { echo "$as_me:$LINENO: creating cache $cache_file" >&5
+echo "$as_me: creating cache $cache_file" >&6;}
+  >$cache_file
+fi
+
+# Check that the precious variables saved in the cache have kept the same
+# value.
+ac_cache_corrupted=false
+for ac_var in `(set) 2>&1 |
+	       sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do
+  eval ac_old_set=\$ac_cv_env_${ac_var}_set
+  eval ac_new_set=\$ac_env_${ac_var}_set
+  eval ac_old_val="\$ac_cv_env_${ac_var}_value"
+  eval ac_new_val="\$ac_env_${ac_var}_value"
+  case $ac_old_set,$ac_new_set in
+    set,)
+      { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,set)
+      { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5
+echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
+      ac_cache_corrupted=: ;;
+    ,);;
+    *)
+      if test "x$ac_old_val" != "x$ac_new_val"; then
+	{ echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5
+echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+	{ echo "$as_me:$LINENO:   former value:  $ac_old_val" >&5
+echo "$as_me:   former value:  $ac_old_val" >&2;}
+	{ echo "$as_me:$LINENO:   current value: $ac_new_val" >&5
+echo "$as_me:   current value: $ac_new_val" >&2;}
+	ac_cache_corrupted=:
+      fi;;
+  esac
+  # Pass precious variables to config.status.
+  if test "$ac_new_set" = set; then
+    case $ac_new_val in
+    *" "*|*"	"*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
+      ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+    *) ac_arg=$ac_var=$ac_new_val ;;
+    esac
+    case " $ac_configure_args " in
+      *" '$ac_arg' "*) ;; # Avoid dups.  Use of quotes ensures accuracy.
+      *) ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+    esac
+  fi
+done
+if $ac_cache_corrupted; then
+  { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5
+echo "$as_me: error: changes in the environment can compromise the build" >&2;}
+  { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5
+echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+# Recover information that Tcl computed with its configure script.
+
+#--------------------------------------------------------------------
+#       See if there was a command-line option for where Tcl is;  if
+#       not, assume that its top-level directory is a sibling of ours.
+#--------------------------------------------------------------------
+
+DEF_VER=8.6
+
+
+# Check whether --with-tcl or --without-tcl was given.
+if test "${with_tcl+set}" = set; then
+  withval="$with_tcl"
+  TCL_BIN_DIR=$withval
+else
+  TCL_BIN_DIR=`cd ../../tcl$DEF_VER$TCL_PATCH_LEVEL/unix; pwd`
+fi;
+if test ! -d $TCL_BIN_DIR; then
+    { { echo "$as_me:$LINENO: error: Tcl directory $TCL_BIN_DIR doesn't exist" >&5
+echo "$as_me: error: Tcl directory $TCL_BIN_DIR doesn't exist" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+if test ! -f $TCL_BIN_DIR/tclConfig.sh; then
+    { { echo "$as_me:$LINENO: error: There's no tclConfig.sh in $TCL_BIN_DIR;  perhaps you didn't specify the Tcl *build* directory (not the toplevel Tcl directory) or you forgot to configure Tcl?" >&5
+echo "$as_me: error: There's no tclConfig.sh in $TCL_BIN_DIR;  perhaps you didn't specify the Tcl *build* directory (not the toplevel Tcl directory) or you forgot to configure Tcl?" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+. $TCL_BIN_DIR/tclConfig.sh
+
+TCL_WIN_VERSION=$TCL_MAJOR_VERSION$TCL_MINOR_VERSION
+
+CC=$TCL_CC
+
+
+
+
+
+
+                    ac_config_files="$ac_config_files Makefile tcl.hpj"
+cat >confcache <<\_ACEOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs, see configure's option --config-cache.
+# It is not useful on other systems.  If it contains results you don't
+# want to keep, you may remove or edit it.
+#
+# config.status only pays attention to the cache file if you give it
+# the --recheck option to rerun configure.
+#
+# `ac_cv_env_foo' variables (set or unset) will be overridden when
+# loading this file, other *unset* `ac_cv_foo' will be assigned the
+# following values.
+
+_ACEOF
+
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+{
+  (set) 2>&1 |
+    case `(ac_space=' '; set | grep ac_space) 2>&1` in
+    *ac_space=\ *)
+      # `set' does not quote correctly, so add quotes (double-quote
+      # substitution turns \\\\ into \\, and sed turns \\ into \).
+      sed -n \
+	"s/'/'\\\\''/g;
+	  s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
+      ;;
+    *)
+      # `set' quotes correctly as required by POSIX, so do not add quotes.
+      sed -n \
+	"s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
+      ;;
+    esac;
+} |
+  sed '
+     t clear
+     : clear
+     s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
+     t end
+     /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
+     : end' >>confcache
+if diff $cache_file confcache >/dev/null 2>&1; then :; else
+  if test -w $cache_file; then
+    test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file"
+    cat confcache >$cache_file
+  else
+    echo "not updating unwritable cache $cache_file"
+  fi
+fi
+rm -f confcache
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# VPATH may cause trouble with some makes, so we remove $(srcdir),
+# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and
+# trailing colons and then remove the whole line if VPATH becomes empty
+# (actually we leave an empty line to preserve line numbers).
+if test "x$srcdir" = x.; then
+  ac_vpsub='/^[	 ]*VPATH[	 ]*=/{
+s/:*\$(srcdir):*/:/;
+s/:*\${srcdir}:*/:/;
+s/:*@srcdir@:*/:/;
+s/^\([^=]*=[	 ]*\):*/\1/;
+s/:*$//;
+s/^[^=]*=[	 ]*$//;
+}'
+fi
+
+# Transform confdefs.h into DEFS.
+# Protect against shell expansion while executing Makefile rules.
+# Protect against Makefile macro expansion.
+#
+# If the first sed substitution is executed (which looks for macros that
+# take arguments), then we branch to the quote section.  Otherwise,
+# look for a macro that doesn't take arguments.
+cat >confdef2opt.sed <<\_ACEOF
+t clear
+: clear
+s,^[	 ]*#[	 ]*define[	 ][	 ]*\([^	 (][^	 (]*([^)]*)\)[	 ]*\(.*\),-D\1=\2,g
+t quote
+s,^[	 ]*#[	 ]*define[	 ][	 ]*\([^	 ][^	 ]*\)[	 ]*\(.*\),-D\1=\2,g
+t quote
+d
+: quote
+s,[	 `~#$^&*(){}\\|;'"<>?],\\&,g
+s,\[,\\&,g
+s,\],\\&,g
+s,\$,$$,g
+p
+_ACEOF
+# We use echo to avoid assuming a particular line-breaking character.
+# The extra dot is to prevent the shell from consuming trailing
+# line-breaks from the sub-command output.  A line-break within
+# single-quotes doesn't work because, if this script is created in a
+# platform that uses two characters for line-breaks (e.g., DOS), tr
+# would break.
+ac_LF_and_DOT=`echo; echo .`
+DEFS=`sed -n -f confdef2opt.sed confdefs.h | tr "$ac_LF_and_DOT" ' .'`
+rm -f confdef2opt.sed
+
+
+ac_libobjs=
+ac_ltlibobjs=
+for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
+  # 1. Remove the extension, and $U if already installed.
+  ac_i=`echo "$ac_i" |
+	 sed 's/\$U\././;s/\.o$//;s/\.obj$//'`
+  # 2. Add them.
+  ac_libobjs="$ac_libobjs $ac_i\$U.$ac_objext"
+  ac_ltlibobjs="$ac_ltlibobjs $ac_i"'$U.lo'
+done
+LIBOBJS=$ac_libobjs
+
+LTLIBOBJS=$ac_ltlibobjs
+
+
+
+: ${CONFIG_STATUS=./config.status}
+ac_clean_files_save=$ac_clean_files
+ac_clean_files="$ac_clean_files $CONFIG_STATUS"
+{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5
+echo "$as_me: creating $CONFIG_STATUS" >&6;}
+cat >$CONFIG_STATUS <<_ACEOF
+#! $SHELL
+# Generated by $as_me.
+# Run this file to recreate the current configuration.
+# Compiler output produced by configure, useful for debugging
+# configure, is in config.log if it exists.
+
+debug=false
+ac_cs_recheck=false
+ac_cs_silent=false
+SHELL=\${CONFIG_SHELL-$SHELL}
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+## --------------------- ##
+## M4sh Initialization.  ##
+## --------------------- ##
+
+# Be Bourne compatible
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+  emulate sh
+  NULLCMD=:
+  # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+  # is contrary to our usage.  Disable this feature.
+  alias -g '${1+"$@"}'='"$@"'
+elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
+  set -o posix
+fi
+DUALCASE=1; export DUALCASE # for MKS sh
+
+# Support unset when possible.
+if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
+  as_unset=unset
+else
+  as_unset=false
+fi
+
+
+# Work around bugs in pre-3.0 UWIN ksh.
+$as_unset ENV MAIL MAILPATH
+PS1='$ '
+PS2='> '
+PS4='+ '
+
+# NLS nuisances.
+for as_var in \
+  LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
+  LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
+  LC_TELEPHONE LC_TIME
+do
+  if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
+    eval $as_var=C; export $as_var
+  else
+    $as_unset $as_var
+  fi
+done
+
+# Required to use basename.
+if expr a : '\(a\)' >/dev/null 2>&1; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
+  as_basename=basename
+else
+  as_basename=false
+fi
+
+
+# Name of the executable.
+as_me=`$as_basename "$0" ||
+$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
+	 X"$0" : 'X\(//\)$' \| \
+	 X"$0" : 'X\(/\)$' \| \
+	 .     : '\(.\)' 2>/dev/null ||
+echo X/"$0" |
+    sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
+  	  /^X\/\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\/\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`
+
+
+# PATH needs CR, and LINENO needs CR and PATH.
+# Avoid depending upon Character Ranges.
+as_cr_letters='abcdefghijklmnopqrstuvwxyz'
+as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
+as_cr_Letters=$as_cr_letters$as_cr_LETTERS
+as_cr_digits='0123456789'
+as_cr_alnum=$as_cr_Letters$as_cr_digits
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+  echo "#! /bin/sh" >conf$$.sh
+  echo  "exit 0"   >>conf$$.sh
+  chmod +x conf$$.sh
+  if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
+    PATH_SEPARATOR=';'
+  else
+    PATH_SEPARATOR=:
+  fi
+  rm -f conf$$.sh
+fi
+
+
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2"  || {
+  # Find who we are.  Look in the path if we contain no path at all
+  # relative or not.
+  case $0 in
+    *[\\/]* ) as_myself=$0 ;;
+    *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+done
+
+       ;;
+  esac
+  # We did not find ourselves, most probably we were run as `sh COMMAND'
+  # in which case we are not to be found in the path.
+  if test "x$as_myself" = x; then
+    as_myself=$0
+  fi
+  if test ! -f "$as_myself"; then
+    { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5
+echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;}
+   { (exit 1); exit 1; }; }
+  fi
+  case $CONFIG_SHELL in
+  '')
+    as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for as_base in sh bash ksh sh5; do
+	 case $as_dir in
+	 /*)
+	   if ("$as_dir/$as_base" -c '
+  as_lineno_1=$LINENO
+  as_lineno_2=$LINENO
+  as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
+  test "x$as_lineno_1" != "x$as_lineno_2" &&
+  test "x$as_lineno_3"  = "x$as_lineno_2" ') 2>/dev/null; then
+	     $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; }
+	     $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; }
+	     CONFIG_SHELL=$as_dir/$as_base
+	     export CONFIG_SHELL
+	     exec "$CONFIG_SHELL" "$0" ${1+"$@"}
+	   fi;;
+	 esac
+       done
+done
+;;
+  esac
+
+  # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
+  # uniformly replaced by the line number.  The first 'sed' inserts a
+  # line-number line before each line; the second 'sed' does the real
+  # work.  The second script uses 'N' to pair each line-number line
+  # with the numbered line, and appends trailing '-' during
+  # substitution so that $LINENO is not a special case at line end.
+  # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
+  # second 'sed' script.  Blame Lee E. McMahon for sed's syntax.  :-)
+  sed '=' <$as_myself |
+    sed '
+      N
+      s,$,-,
+      : loop
+      s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
+      t loop
+      s,-$,,
+      s,^['$as_cr_digits']*\n,,
+    ' >$as_me.lineno &&
+  chmod +x $as_me.lineno ||
+    { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5
+echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;}
+   { (exit 1); exit 1; }; }
+
+  # Don't try to exec as it changes $[0], causing all sort of problems
+  # (the dirname of $[0] is not the place where we might find the
+  # original and so on.  Autoconf is especially sensible to this).
+  . ./$as_me.lineno
+  # Exit status is that of the last command.
+  exit
+}
+
+
+case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
+  *c*,-n*) ECHO_N= ECHO_C='
+' ECHO_T='	' ;;
+  *c*,*  ) ECHO_N=-n ECHO_C= ECHO_T= ;;
+  *)       ECHO_N= ECHO_C='\c' ECHO_T= ;;
+esac
+
+if expr a : '\(a\)' >/dev/null 2>&1; then
+  as_expr=expr
+else
+  as_expr=false
+fi
+
+rm -f conf$$ conf$$.exe conf$$.file
+echo >conf$$.file
+if ln -s conf$$.file conf$$ 2>/dev/null; then
+  # We could just check for DJGPP; but this test a) works b) is more generic
+  # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).
+  if test -f conf$$.exe; then
+    # Don't use ln at all; we don't have any links
+    as_ln_s='cp -p'
+  else
+    as_ln_s='ln -s'
+  fi
+elif ln conf$$.file conf$$ 2>/dev/null; then
+  as_ln_s=ln
+else
+  as_ln_s='cp -p'
+fi
+rm -f conf$$ conf$$.exe conf$$.file
+
+if mkdir -p . 2>/dev/null; then
+  as_mkdir_p=:
+else
+  test -d ./-p && rmdir ./-p
+  as_mkdir_p=false
+fi
+
+as_executable_p="test -f"
+
+# Sed expression to map a string onto a valid CPP name.
+as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
+
+# Sed expression to map a string onto a valid variable name.
+as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
+
+
+# IFS
+# We need space, tab and new line, in precisely that order.
+as_nl='
+'
+IFS=" 	$as_nl"
+
+# CDPATH.
+$as_unset CDPATH
+
+exec 6>&1
+
+# Open the log real soon, to keep \$[0] and so on meaningful, and to
+# report actual input values of CONFIG_FILES etc. instead of their
+# values after options handling.  Logging --version etc. is OK.
+exec 5>>config.log
+{
+  echo
+  sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+} >&5
+cat >&5 <<_CSEOF
+
+This file was extended by $as_me, which was
+generated by GNU Autoconf 2.59.  Invocation command line was
+
+  CONFIG_FILES    = $CONFIG_FILES
+  CONFIG_HEADERS  = $CONFIG_HEADERS
+  CONFIG_LINKS    = $CONFIG_LINKS
+  CONFIG_COMMANDS = $CONFIG_COMMANDS
+  $ $0 $@
+
+_CSEOF
+echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5
+echo >&5
+_ACEOF
+
+# Files that config.status was made for.
+if test -n "$ac_config_files"; then
+  echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_headers"; then
+  echo "config_headers=\"$ac_config_headers\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_links"; then
+  echo "config_links=\"$ac_config_links\"" >>$CONFIG_STATUS
+fi
+
+if test -n "$ac_config_commands"; then
+  echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS
+fi
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+ac_cs_usage="\
+\`$as_me' instantiates files from templates according to the
+current configuration.
+
+Usage: $0 [OPTIONS] [FILE]...
+
+  -h, --help       print this help, then exit
+  -V, --version    print version number, then exit
+  -q, --quiet      do not print progress messages
+  -d, --debug      don't remove temporary files
+      --recheck    update $as_me by reconfiguring in the same conditions
+  --file=FILE[:TEMPLATE]
+		   instantiate the configuration file FILE
+
+Configuration files:
+$config_files
+
+Report bugs to <bug-autoconf@gnu.org>."
+_ACEOF
+
+cat >>$CONFIG_STATUS <<_ACEOF
+ac_cs_version="\\
+config.status
+configured by $0, generated by GNU Autoconf 2.59,
+  with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\"
+
+Copyright (C) 2003 Free Software Foundation, Inc.
+This config.status script is free software; the Free Software Foundation
+gives unlimited permission to copy, distribute and modify it."
+srcdir=$srcdir
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+# If no file are specified by the user, then we need to provide default
+# value.  By we need to know if files were specified by the user.
+ac_need_defaults=:
+while test $# != 0
+do
+  case $1 in
+  --*=*)
+    ac_option=`expr "x$1" : 'x\([^=]*\)='`
+    ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'`
+    ac_shift=:
+    ;;
+  -*)
+    ac_option=$1
+    ac_optarg=$2
+    ac_shift=shift
+    ;;
+  *) # This is not an option, so the user has probably given explicit
+     # arguments.
+     ac_option=$1
+     ac_need_defaults=false;;
+  esac
+
+  case $ac_option in
+  # Handling of the options.
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+  -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+    ac_cs_recheck=: ;;
+  --version | --vers* | -V )
+    echo "$ac_cs_version"; exit 0 ;;
+  --he | --h)
+    # Conflict between --help and --header
+    { { echo "$as_me:$LINENO: error: ambiguous option: $1
+Try \`$0 --help' for more information." >&5
+echo "$as_me: error: ambiguous option: $1
+Try \`$0 --help' for more information." >&2;}
+   { (exit 1); exit 1; }; };;
+  --help | --hel | -h )
+    echo "$ac_cs_usage"; exit 0 ;;
+  --debug | --d* | -d )
+    debug=: ;;
+  --file | --fil | --fi | --f )
+    $ac_shift
+    CONFIG_FILES="$CONFIG_FILES $ac_optarg"
+    ac_need_defaults=false;;
+  --header | --heade | --head | --hea )
+    $ac_shift
+    CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg"
+    ac_need_defaults=false;;
+  -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+  | -silent | --silent | --silen | --sile | --sil | --si | --s)
+    ac_cs_silent=: ;;
+
+  # This is an error.
+  -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1
+Try \`$0 --help' for more information." >&5
+echo "$as_me: error: unrecognized option: $1
+Try \`$0 --help' for more information." >&2;}
+   { (exit 1); exit 1; }; } ;;
+
+  *) ac_config_targets="$ac_config_targets $1" ;;
+
+  esac
+  shift
+done
+
+ac_configure_extra_args=
+
+if $ac_cs_silent; then
+  exec 6>/dev/null
+  ac_configure_extra_args="$ac_configure_extra_args --silent"
+fi
+
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+if \$ac_cs_recheck; then
+  echo "running $SHELL $0 " $ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6
+  exec $SHELL $0 $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+fi
+
+_ACEOF
+
+
+
+
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+for ac_config_target in $ac_config_targets
+do
+  case "$ac_config_target" in
+  # Handling of arguments.
+  "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile" ;;
+  "tcl.hpj" ) CONFIG_FILES="$CONFIG_FILES tcl.hpj" ;;
+  *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5
+echo "$as_me: error: invalid argument: $ac_config_target" >&2;}
+   { (exit 1); exit 1; }; };;
+  esac
+done
+
+# If the user did not use the arguments to specify the items to instantiate,
+# then the envvar interface is used.  Set only those that are not.
+# We use the long form for the default assignment because of an extremely
+# bizarre bug on SunOS 4.1.3.
+if $ac_need_defaults; then
+  test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files
+fi
+
+# Have a temporary directory for convenience.  Make it in the build tree
+# simply because there is no reason to put it here, and in addition,
+# creating and moving files from /tmp can sometimes cause problems.
+# Create a temporary directory, and hook for its removal unless debugging.
+$debug ||
+{
+  trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0
+  trap '{ (exit 1); exit 1; }' 1 2 13 15
+}
+
+# Create a (secure) tmp directory for tmp files.
+
+{
+  tmp=`(umask 077 && mktemp -d -q "./confstatXXXXXX") 2>/dev/null` &&
+  test -n "$tmp" && test -d "$tmp"
+}  ||
+{
+  tmp=./confstat$$-$RANDOM
+  (umask 077 && mkdir $tmp)
+} ||
+{
+   echo "$me: cannot create a temporary directory in ." >&2
+   { (exit 1); exit 1; }
+}
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<_ACEOF
+
+#
+# CONFIG_FILES section.
+#
+
+# No need to generate the scripts if there are no CONFIG_FILES.
+# This happens for instance when ./config.status config.h
+if test -n "\$CONFIG_FILES"; then
+  # Protect against being on the right side of a sed subst in config.status.
+  sed 's/,@/@@/; s/@,/@@/; s/,;t t\$/@;t t/; /@;t t\$/s/[\\\\&,]/\\\\&/g;
+   s/@@/,@/; s/@@/@,/; s/@;t t\$/,;t t/' >\$tmp/subs.sed <<\\CEOF
+s,@SHELL@,$SHELL,;t t
+s,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t
+s,@PACKAGE_NAME@,$PACKAGE_NAME,;t t
+s,@PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t
+s,@PACKAGE_VERSION@,$PACKAGE_VERSION,;t t
+s,@PACKAGE_STRING@,$PACKAGE_STRING,;t t
+s,@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t
+s,@exec_prefix@,$exec_prefix,;t t
+s,@prefix@,$prefix,;t t
+s,@program_transform_name@,$program_transform_name,;t t
+s,@bindir@,$bindir,;t t
+s,@sbindir@,$sbindir,;t t
+s,@libexecdir@,$libexecdir,;t t
+s,@datadir@,$datadir,;t t
+s,@sysconfdir@,$sysconfdir,;t t
+s,@sharedstatedir@,$sharedstatedir,;t t
+s,@localstatedir@,$localstatedir,;t t
+s,@libdir@,$libdir,;t t
+s,@includedir@,$includedir,;t t
+s,@oldincludedir@,$oldincludedir,;t t
+s,@infodir@,$infodir,;t t
+s,@mandir@,$mandir,;t t
+s,@build_alias@,$build_alias,;t t
+s,@host_alias@,$host_alias,;t t
+s,@target_alias@,$target_alias,;t t
+s,@DEFS@,$DEFS,;t t
+s,@ECHO_C@,$ECHO_C,;t t
+s,@ECHO_N@,$ECHO_N,;t t
+s,@ECHO_T@,$ECHO_T,;t t
+s,@LIBS@,$LIBS,;t t
+s,@TCL_WIN_VERSION@,$TCL_WIN_VERSION,;t t
+s,@CC@,$CC,;t t
+s,@TCL_VERSION@,$TCL_VERSION,;t t
+s,@TCL_PATCH_LEVEL@,$TCL_PATCH_LEVEL,;t t
+s,@TCL_SRC_DIR@,$TCL_SRC_DIR,;t t
+s,@TCL_BIN_DIR@,$TCL_BIN_DIR,;t t
+s,@LIBOBJS@,$LIBOBJS,;t t
+s,@LTLIBOBJS@,$LTLIBOBJS,;t t
+CEOF
+
+_ACEOF
+
+  cat >>$CONFIG_STATUS <<\_ACEOF
+  # Split the substitutions into bite-sized pieces for seds with
+  # small command number limits, like on Digital OSF/1 and HP-UX.
+  ac_max_sed_lines=48
+  ac_sed_frag=1 # Number of current file.
+  ac_beg=1 # First line for current file.
+  ac_end=$ac_max_sed_lines # Line after last line for current file.
+  ac_more_lines=:
+  ac_sed_cmds=
+  while $ac_more_lines; do
+    if test $ac_beg -gt 1; then
+      sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
+    else
+      sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
+    fi
+    if test ! -s $tmp/subs.frag; then
+      ac_more_lines=false
+    else
+      # The purpose of the label and of the branching condition is to
+      # speed up the sed processing (if there are no `@' at all, there
+      # is no need to browse any of the substitutions).
+      # These are the two extra sed commands mentioned above.
+      (echo ':t
+  /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed
+      if test -z "$ac_sed_cmds"; then
+	ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed"
+      else
+	ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed"
+      fi
+      ac_sed_frag=`expr $ac_sed_frag + 1`
+      ac_beg=$ac_end
+      ac_end=`expr $ac_end + $ac_max_sed_lines`
+    fi
+  done
+  if test -z "$ac_sed_cmds"; then
+    ac_sed_cmds=cat
+  fi
+fi # test -n "$CONFIG_FILES"
+
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue
+  # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+  case $ac_file in
+  - | *:- | *:-:* ) # input from stdin
+	cat >$tmp/stdin
+	ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+	ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+  *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
+	ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
+  * )   ac_file_in=$ac_file.in ;;
+  esac
+
+  # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories.
+  ac_dir=`(dirname "$ac_file") 2>/dev/null ||
+$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$ac_file" : 'X\(//\)[^/]' \| \
+	 X"$ac_file" : 'X\(//\)$' \| \
+	 X"$ac_file" : 'X\(/\)' \| \
+	 .     : '\(.\)' 2>/dev/null ||
+echo X"$ac_file" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+  	  /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+  	  /^X\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`
+  { if $as_mkdir_p; then
+    mkdir -p "$ac_dir"
+  else
+    as_dir="$ac_dir"
+    as_dirs=
+    while test ! -d "$as_dir"; do
+      as_dirs="$as_dir $as_dirs"
+      as_dir=`(dirname "$as_dir") 2>/dev/null ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+	 X"$as_dir" : 'X\(//\)[^/]' \| \
+	 X"$as_dir" : 'X\(//\)$' \| \
+	 X"$as_dir" : 'X\(/\)' \| \
+	 .     : '\(.\)' 2>/dev/null ||
+echo X"$as_dir" |
+    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
+  	  /^X\(\/\/\)[^/].*/{ s//\1/; q; }
+  	  /^X\(\/\/\)$/{ s//\1/; q; }
+  	  /^X\(\/\).*/{ s//\1/; q; }
+  	  s/.*/./; q'`
+    done
+    test ! -n "$as_dirs" || mkdir $as_dirs
+  fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5
+echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;}
+   { (exit 1); exit 1; }; }; }
+
+  ac_builddir=.
+
+if test "$ac_dir" != .; then
+  ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
+  # A "../" for each directory in $ac_dir_suffix.
+  ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
+else
+  ac_dir_suffix= ac_top_builddir=
+fi
+
+case $srcdir in
+  .)  # No --srcdir option.  We are building in place.
+    ac_srcdir=.
+    if test -z "$ac_top_builddir"; then
+       ac_top_srcdir=.
+    else
+       ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
+    fi ;;
+  [\\/]* | ?:[\\/]* )  # Absolute path.
+    ac_srcdir=$srcdir$ac_dir_suffix;
+    ac_top_srcdir=$srcdir ;;
+  *) # Relative path.
+    ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
+    ac_top_srcdir=$ac_top_builddir$srcdir ;;
+esac
+
+# Do not use `cd foo && pwd` to compute absolute paths, because
+# the directories may not exist.
+case `pwd` in
+.) ac_abs_builddir="$ac_dir";;
+*)
+  case "$ac_dir" in
+  .) ac_abs_builddir=`pwd`;;
+  [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";;
+  *) ac_abs_builddir=`pwd`/"$ac_dir";;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_builddir=${ac_top_builddir}.;;
+*)
+  case ${ac_top_builddir}. in
+  .) ac_abs_top_builddir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;;
+  *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_srcdir=$ac_srcdir;;
+*)
+  case $ac_srcdir in
+  .) ac_abs_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;;
+  *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;;
+  esac;;
+esac
+case $ac_abs_builddir in
+.) ac_abs_top_srcdir=$ac_top_srcdir;;
+*)
+  case $ac_top_srcdir in
+  .) ac_abs_top_srcdir=$ac_abs_builddir;;
+  [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;;
+  *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;;
+  esac;;
+esac
+
+
+
+  if test x"$ac_file" != x-; then
+    { echo "$as_me:$LINENO: creating $ac_file" >&5
+echo "$as_me: creating $ac_file" >&6;}
+    rm -f "$ac_file"
+  fi
+  # Let's still pretend it is `configure' which instantiates (i.e., don't
+  # use $as_me), people would be surprised to read:
+  #    /* config.h.  Generated by config.status.  */
+  if test x"$ac_file" = x-; then
+    configure_input=
+  else
+    configure_input="$ac_file.  "
+  fi
+  configure_input=$configure_input"Generated from `echo $ac_file_in |
+				     sed 's,.*/,,'` by configure."
+
+  # First look for the input files in the build tree, otherwise in the
+  # src tree.
+  ac_file_inputs=`IFS=:
+    for f in $ac_file_in; do
+      case $f in
+      -) echo $tmp/stdin ;;
+      [\\/$]*)
+	 # Absolute (can't be DOS-style, as IFS=:)
+	 test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+   { (exit 1); exit 1; }; }
+	 echo "$f";;
+      *) # Relative
+	 if test -f "$f"; then
+	   # Build tree
+	   echo "$f"
+	 elif test -f "$srcdir/$f"; then
+	   # Source tree
+	   echo "$srcdir/$f"
+	 else
+	   # /dev/null tree
+	   { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
+echo "$as_me: error: cannot find input file: $f" >&2;}
+   { (exit 1); exit 1; }; }
+	 fi;;
+      esac
+    done` || { (exit 1); exit 1; }
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF
+  sed "$ac_vpsub
+$extrasub
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF
+:t
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
+s,@configure_input@,$configure_input,;t t
+s,@srcdir@,$ac_srcdir,;t t
+s,@abs_srcdir@,$ac_abs_srcdir,;t t
+s,@top_srcdir@,$ac_top_srcdir,;t t
+s,@abs_top_srcdir@,$ac_abs_top_srcdir,;t t
+s,@builddir@,$ac_builddir,;t t
+s,@abs_builddir@,$ac_abs_builddir,;t t
+s,@top_builddir@,$ac_top_builddir,;t t
+s,@abs_top_builddir@,$ac_abs_top_builddir,;t t
+" $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out
+  rm -f $tmp/stdin
+  if test x"$ac_file" != x-; then
+    mv $tmp/out $ac_file
+  else
+    cat $tmp/out
+    rm -f $tmp/out
+  fi
+
+done
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF
+
+{ (exit 0); exit 0; }
+_ACEOF
+chmod +x $CONFIG_STATUS
+ac_clean_files=$ac_clean_files_save
+
+
+# configure is writing to config.log, and then calls config.status.
+# config.status does its own redirection, appending to config.log.
+# Unfortunately, on DOS this fails, as config.log is still kept open
+# by configure, so config.status won't be able to write to it; its
+# output is simply discarded.  So we exec the FD to /dev/null,
+# effectively closing config.log, so it can be properly (re)opened and
+# appended to by config.status.  When coming back to configure, we
+# need to make the FD available again.
+if test "$no_create" != yes; then
+  ac_cs_success=:
+  ac_config_status_args=
+  test "$silent" = yes &&
+    ac_config_status_args="$ac_config_status_args --quiet"
+  exec 5>/dev/null
+  $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false
+  exec 5>>config.log
+  # Use ||, not &&, to avoid exiting from the if with $? = 1, which
+  # would make configure fail if this is the last instruction.
+  $ac_cs_success || { (exit 1); exit 1; }
+fi
+
diff --git a/tools/configure.in b/tools/configure.in
new file mode 100644
index 0000000..6aebcaa
--- /dev/null
+++ b/tools/configure.in
@@ -0,0 +1,35 @@
+dnl	This file is an input file used by the GNU "autoconf" program to
+dnl	generate the file "configure", which is run to configure the
+dnl	Makefile in this directory.
+AC_INIT(man2tcl.c)
+AC_PREREQ(2.59)
+
+# Recover information that Tcl computed with its configure script.
+
+#--------------------------------------------------------------------
+#       See if there was a command-line option for where Tcl is;  if
+#       not, assume that its top-level directory is a sibling of ours.
+#--------------------------------------------------------------------
+
+DEF_VER=8.6
+
+AC_ARG_WITH(tcl, [  --with-tcl=DIR          use Tcl $DEF_VER binaries from DIR], TCL_BIN_DIR=$withval, TCL_BIN_DIR=`cd ../../tcl$DEF_VER$TCL_PATCH_LEVEL/unix; pwd`)
+if test ! -d $TCL_BIN_DIR; then
+    AC_MSG_ERROR(Tcl directory $TCL_BIN_DIR doesn't exist)
+fi
+if test ! -f $TCL_BIN_DIR/tclConfig.sh; then
+    AC_MSG_ERROR(There's no tclConfig.sh in $TCL_BIN_DIR;  perhaps you didn't specify the Tcl *build* directory (not the toplevel Tcl directory) or you forgot to configure Tcl?)
+fi
+
+. $TCL_BIN_DIR/tclConfig.sh
+
+TCL_WIN_VERSION=$TCL_MAJOR_VERSION$TCL_MINOR_VERSION
+AC_SUBST(TCL_WIN_VERSION)
+CC=$TCL_CC
+AC_SUBST(CC)
+AC_SUBST(TCL_VERSION)
+AC_SUBST(TCL_PATCH_LEVEL)
+AC_SUBST(TCL_SRC_DIR)
+AC_SUBST(TCL_BIN_DIR)
+
+AC_OUTPUT(Makefile tcl.hpj)
diff --git a/tools/encoding/Makefile b/tools/encoding/Makefile
new file mode 100644
index 0000000..4c10673
--- /dev/null
+++ b/tools/encoding/Makefile
@@ -0,0 +1,110 @@
+#
+# This file is a Makefile to compile all the encoding files.  
+#
+# Run "make" to compile all the encoding files (*.txt,*.esc) into the
+# format that Tcl can use (*.enc).  It is your responsibility to move the
+# encoding files to the appropriate place ($TCL_ROOT/library/encoding
+#
+# The .txt files in this directory come from the Unicode CD and are covered
+# by the following copyright notice:
+#
+#---------------------------------------------------------------------------
+#
+# Copyright (c) 1996 Unicode, Inc.  All Rights reserved.
+#
+# This file is provided as-is by Unicode, Inc. (The Unicode Consortium).
+# No claims are made as to fitness for any particular purpose.  No
+# warranties of any kind are expressed or implied.  The recipient
+# agrees to determine applicability of information provided.  If this
+# file has been provided on magnetic media by Unicode, Inc., the sole
+# remedy for any claim will be exchange of defective media within 90
+# days of receipt.
+#
+# Recipient is granted the right to make copies in any form for
+# internal distribution and to freely use the information supplied
+# in the creation of products supporting Unicode.  Unicode, Inc.
+# specifically excludes the right to re-distribute this file directly
+# to third parties or other organizations whether for profit or not.
+#
+# In other words:  Don't put this file on the Internet.  People who want to 
+# get it over the Internet should do so directly from ftp://unicode.org.  They
+# can therefore be assured of getting the most recent and accurate version.
+#
+#----------------------------------------------------------------------------
+#
+# The txt2enc program built by this makefile is used to compile individual
+# .txt files into .enc files, the format that Tcl understands for encoding 
+# files.  This compilation to a different format is allowed by the above
+# restriction. 
+#
+# The files shiftjis.txt and jis0208.txt were modified from the original
+# ones provided on the Unicode CD.  The double-width backslash character
+# 0x815F in these two Japanese encodings was being mapped to Unicode 005C
+# (REVERSE SOLIDUS), the normal backslash character.  They have been
+# changed to map 0x815F to Unicode FF3C (FULLWIDTH REVERSE SOLIDUS) and let
+# the regular backslash character map to itself.  This follows how cp932
+# behaves.
+#
+# Copyright (c) 1998 Sun Microsystems, Inc.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+# SCCS: @(#) Makefile 1.1 98/01/28 11:41:36
+#
+
+EUC_ENCODINGS = euc-cn.txt euc-kr.txt euc-jp.txt 
+
+encodings: clean txt2enc $(EUC_ENCODINGS)
+	@echo Compiling encoding files.
+	@for p in *.esc; do \
+	    base=`echo $$p | sed 's/\..*$$//'`; \
+	    echo $$base.enc; \
+	    echo "# Encoding file: $$base, escape-driven" > $$base.enc; \
+	    echo "E" >> $$base.enc; \
+	    cat $$p >> $$base.enc; \
+	done
+	@for p in *.txt; do \
+	    enc=`echo $$p | sed 's/\..*$$/\.enc/'`; \
+	    echo $$enc; \
+	    ./txt2enc -e 0 -u 1 $$p > $$enc; \
+	done
+	@echo 
+	@echo Compiling special versions of encoding files.
+	@for p in ascii.txt; do \
+	    enc=`echo $$p | sed 's/\..*$$/\.enc/'`; \
+	    echo $$enc; \
+	    ./txt2enc -m $$p > $$enc; \
+	done
+	@for p in jis0208.txt; do \
+	    enc=`echo $$p | sed 's/\..*$$/\.enc/'`; \
+	    echo $$enc; \
+	    ./txt2enc -e 1 -u 2 $$p > $$enc; \
+	done
+	@for p in symbol.txt dingbats.txt macDingbats.txt; do \
+	    enc=`echo $$p | sed 's/\..*$$/\.enc/'`; \
+	    echo $$enc; \
+	    ./txt2enc -e 0 -u 1 -s $$p > $$enc; \
+	done
+
+clean:
+	@rm -f txt2enc *.enc $(EUC_ENCODINGS)
+
+txt2enc: txt2enc.c
+	@gcc -o txt2enc txt2enc.c
+
+euc-jp.txt: ascii.txt jis0208.txt Makefile
+	@echo Building euc-jp.txt from components.
+	@cat ascii.txt > euc-jp.txt
+	@grep '^0x[A-F]' jis0201.txt | sed 's/0x/0x8E/' >> euc-jp.txt
+	@cat jis0208.txt | awk 'BEGIN {print "ibase=16"} index($$1,"#") != 1 {print substr($$2,3) "+" 8080; print substr($$3,3)}' | bc | awk '{ str = $$1; getline; printf "0x%04x 0x%04x\n", str, $$0}' >> euc-jp.txt
+
+euc-kr.txt: ascii.txt ksc5601.txt Makefile
+	@echo Building euc-kr.txt from components.
+	@cat ascii.txt > euc-kr.txt
+	@cat ksc5601.txt | awk 'BEGIN {print "ibase=16"} index($$1,"#") != 1 {print substr($$1,3) "+" 8080; print substr($$2,3)}' | bc | awk '{ str = $$1; getline; printf "0x%04x 0x%04x\n", str, $$0}' >> euc-kr.txt
+
+euc-cn.txt: ascii.txt gb2312.txt Makefile
+	@echo Building euc-cn.txt from components.
+	@cat ascii.txt > euc-cn.txt
+	@cat gb2312.txt | awk 'BEGIN {print "ibase=16"} index($$1,"#") != 1 {print substr($$1,3) "+" 8080; print substr($$2,3)}' | bc | awk '{ str = $$1; getline; printf "0x%04x 0x%04x\n", str, $$0}' >> euc-cn.txt
diff --git a/tools/encoding/README b/tools/encoding/README
new file mode 100644
index 0000000..0713f4e
--- /dev/null
+++ b/tools/encoding/README
@@ -0,0 +1,5 @@
+On Unix, use "make" to compile all the encoding files (*.txt,*.esc)
+into the format that Tcl can use (*.enc).  It is the caller's
+responsibility to move the generated .enc files to the appropriate
+place (the $TCL_LIBRARY/encoding directory).
+
diff --git a/tools/encoding/ascii.txt b/tools/encoding/ascii.txt
new file mode 100644
index 0000000..66ba6f3
--- /dev/null
+++ b/tools/encoding/ascii.txt
@@ -0,0 +1,95 @@
+0x20	0x0020	#	SPACE
+0x21	0x0021	#	EXCLAMATION MARK
+0x22	0x0022	#	QUOTATION MARK
+0x23	0x0023	#	NUMBER SIGN
+0x24	0x0024	#	DOLLAR SIGN
+0x25	0x0025	#	PERCENT SIGN
+0x26	0x0026	#	AMPERSAND
+0x27	0x0027	#	APOSTROPHE
+0x28	0x0028	#	LEFT PARENTHESIS
+0x29	0x0029	#	RIGHT PARENTHESIS
+0x2A	0x002A	#	ASTERISK
+0x2B	0x002B	#	PLUS SIGN
+0x2C	0x002C	#	COMMA
+0x2D	0x002D	#	HYPHEN-MINUS
+0x2E	0x002E	#	FULL STOP
+0x2F	0x002F	#	SOLIDUS
+0x30	0x0030	#	DIGIT ZERO
+0x31	0x0031	#	DIGIT ONE
+0x32	0x0032	#	DIGIT TWO
+0x33	0x0033	#	DIGIT THREE
+0x34	0x0034	#	DIGIT FOUR
+0x35	0x0035	#	DIGIT FIVE
+0x36	0x0036	#	DIGIT SIX
+0x37	0x0037	#	DIGIT SEVEN
+0x38	0x0038	#	DIGIT EIGHT
+0x39	0x0039	#	DIGIT NINE
+0x3A	0x003A	#	COLON
+0x3B	0x003B	#	SEMICOLON
+0x3C	0x003C	#	LESS-THAN SIGN
+0x3D	0x003D	#	EQUALS SIGN
+0x3E	0x003E	#	GREATER-THAN SIGN
+0x3F	0x003F	#	QUESTION MARK
+0x40	0x0040	#	COMMERCIAL AT
+0x41	0x0041	#	LATIN CAPITAL LETTER A
+0x42	0x0042	#	LATIN CAPITAL LETTER B
+0x43	0x0043	#	LATIN CAPITAL LETTER C
+0x44	0x0044	#	LATIN CAPITAL LETTER D
+0x45	0x0045	#	LATIN CAPITAL LETTER E
+0x46	0x0046	#	LATIN CAPITAL LETTER F
+0x47	0x0047	#	LATIN CAPITAL LETTER G
+0x48	0x0048	#	LATIN CAPITAL LETTER H
+0x49	0x0049	#	LATIN CAPITAL LETTER I
+0x4A	0x004A	#	LATIN CAPITAL LETTER J
+0x4B	0x004B	#	LATIN CAPITAL LETTER K
+0x4C	0x004C	#	LATIN CAPITAL LETTER L
+0x4D	0x004D	#	LATIN CAPITAL LETTER M
+0x4E	0x004E	#	LATIN CAPITAL LETTER N
+0x4F	0x004F	#	LATIN CAPITAL LETTER O
+0x50	0x0050	#	LATIN CAPITAL LETTER P
+0x51	0x0051	#	LATIN CAPITAL LETTER Q
+0x52	0x0052	#	LATIN CAPITAL LETTER R
+0x53	0x0053	#	LATIN CAPITAL LETTER S
+0x54	0x0054	#	LATIN CAPITAL LETTER T
+0x55	0x0055	#	LATIN CAPITAL LETTER U
+0x56	0x0056	#	LATIN CAPITAL LETTER V
+0x57	0x0057	#	LATIN CAPITAL LETTER W
+0x58	0x0058	#	LATIN CAPITAL LETTER X
+0x59	0x0059	#	LATIN CAPITAL LETTER Y
+0x5A	0x005A	#	LATIN CAPITAL LETTER Z
+0x5B	0x005B	#	LEFT SQUARE BRACKET
+0x5C	0x005C	#	REVERSE SOLIDUS
+0x5D	0x005D	#	RIGHT SQUARE BRACKET
+0x5E	0x005E	#	CIRCUMFLEX ACCENT
+0x5F	0x005F	#	LOW LINE
+0x60	0x0060	#	GRAVE ACCENT
+0x61	0x0061	#	LATIN SMALL LETTER A
+0x62	0x0062	#	LATIN SMALL LETTER B
+0x63	0x0063	#	LATIN SMALL LETTER C
+0x64	0x0064	#	LATIN SMALL LETTER D
+0x65	0x0065	#	LATIN SMALL LETTER E
+0x66	0x0066	#	LATIN SMALL LETTER F
+0x67	0x0067	#	LATIN SMALL LETTER G
+0x68	0x0068	#	LATIN SMALL LETTER H
+0x69	0x0069	#	LATIN SMALL LETTER I
+0x6A	0x006A	#	LATIN SMALL LETTER J
+0x6B	0x006B	#	LATIN SMALL LETTER K
+0x6C	0x006C	#	LATIN SMALL LETTER L
+0x6D	0x006D	#	LATIN SMALL LETTER M
+0x6E	0x006E	#	LATIN SMALL LETTER N
+0x6F	0x006F	#	LATIN SMALL LETTER O
+0x70	0x0070	#	LATIN SMALL LETTER P
+0x71	0x0071	#	LATIN SMALL LETTER Q
+0x72	0x0072	#	LATIN SMALL LETTER R
+0x73	0x0073	#	LATIN SMALL LETTER S
+0x74	0x0074	#	LATIN SMALL LETTER T
+0x75	0x0075	#	LATIN SMALL LETTER U
+0x76	0x0076	#	LATIN SMALL LETTER V
+0x77	0x0077	#	LATIN SMALL LETTER W
+0x78	0x0078	#	LATIN SMALL LETTER X
+0x79	0x0079	#	LATIN SMALL LETTER Y
+0x7A	0x007A	#	LATIN SMALL LETTER Z
+0x7B	0x007B	#	LEFT CURLY BRACKET
+0x7C	0x007C	#	VERTICAL LINE
+0x7D	0x007D	#	RIGHT CURLY BRACKET
+0x7E	0x007E	#	TILDE
diff --git a/tools/encoding/big5.txt b/tools/encoding/big5.txt
new file mode 100644
index 0000000..5cc9e81
--- /dev/null
+++ b/tools/encoding/big5.txt
@@ -0,0 +1,13904 @@
+# big5.txt --
+#
+#	BIG5 to Unicode table (modified)
+#
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+# NOTE: this table has been modified to include the 7-bit ASCII
+# characters that are allowed in BIG5 files.
+#
+#
+#	Name:             BIG5 to Unicode table (complete)
+#	Unicode version:  1.1
+#	Table version:    0.0d3
+#	Table format:     Format A
+#	Date:             11 February 1994
+#	Authors:          Glenn Adams <glenn@metis.com>
+#                     John H. Jenkins <John_Jenkins@taligent.com>
+#
+#	Copyright (c) 1991-1994 Unicode, Inc.  All Rights reserved.
+#
+#	This file is provided as-is by Unicode, Inc. (The Unicode Consortium).
+#	No claims are made as to fitness for any particular purpose.  No
+#	warranties of any kind are expressed or implied.  The recipient
+#	agrees to determine applicability of information provided.  If this
+#	file has been provided on magnetic media by Unicode, Inc., the sole
+#	remedy for any claim will be exchange of defective media within 90
+#	days of receipt.
+#
+#	Recipient is granted the right to make copies in any form for
+#	internal distribution and to freely use the information supplied
+#	in the creation of products supporting Unicode.  Unicode, Inc.
+#	specifically excludes the right to re-distribute this file directly
+#	to third parties or other organizations whether for profit or not.
+#
+#	General notes:
+#
+#	This table contains the data Metis and Taligent currently have on how
+#       BIG5 characters map into Unicode.
+#
+#	WARNING!  It is currently impossible to provide round-trip compatibility
+#		between BIG5 and Unicode.  
+#
+#	A number of characters are not currently mapped because
+#		of conflicts with other mappings.  They are as follows:
+#
+#       BIG5        Description                    Comments
+#
+#       0xA15A      SPACING UNDERSCORE             duplicates A1C4
+#       0xA1C3      SPACING HEAVY OVERSCORE        not in Unicode
+#       0xA1C5      SPACING HEAVY UNDERSCORE       not in Unicode
+#       0xA1FE      LT DIAG UP RIGHT TO LOW LEFT   duplicates A2AC
+#       0xA240      LT DIAG UP LEFT TO LOW RIGHT   duplicates A2AD
+#       0xA2CC      HANGZHOU NUMERAL TEN           conflicts with A451 mapping
+#       0xA2CE      HANGZHOU NUMERAL THIRTY        conflicts with A4CA mapping
+#
+#	We currently map all of these characters to U+FFFD REPLACEMENT CHARACTER.
+#		It is also possible to map these characters to their duplicates, or to
+#		the user zone.  
+#	
+#	Notes:
+#
+#	1. In addition to the above, there is some uncertainty about the
+#       mappings in the range C6A1 - C8FE, and F9DD - F9FE.  The ETEN
+#		version of BIG5 organizes the former range differently, and adds
+#		additional characters in the latter range.  The correct mappings
+#		these ranges need to be determined.
+#
+#	2.  There is an uncertainty in the mapping of the Big Five character
+#		0xA3BC.  This character occurs within the Big Five block of tone marks
+#		for bopomofo and is intended to be the tone mark for the first tone in
+#		Mandarin Chinese.  We have selected the mapping U+02C9 MODIFIER LETTER
+#		MACRON (Mandarin Chinese first tone) to reflect this semantic.  
+#		However, because bopomofo uses the absense of a tone mark to indicate
+#		the first Mandarin tone, most implementations of Big Five represent
+#		this character with a blank space, and so a mapping such as U+2003 EM SPACE
+#		might be preferred.  
+#		
+#			
+#
+#	Format:  Three tab-separated columns
+#		 Column #1 is the BIG5 code (in hex as 0xXXXX)
+#		 Column #2 is the Unicode (in hex as 0xXXXX)
+#		 Column #3  is the Unicode name (follows a comment sign, '#')
+#					The official names for Unicode characters U+4E00
+#					to U+9FA5, inclusive, is "CJK UNIFIED IDEOGRAPH-XXXX",
+#					where XXXX is the code point.  Including all these
+#					names in this file increases its size substantially
+#					and needlessly.  The token "<CJK>" is used for the
+#					name of these characters.  If necessary, it can be
+#					expanded algorithmically by a parser or editor.
+#
+#	The entries are in BIG5 order
+#
+#	Any comments or problems, contact <John_Jenkins@taligent.com>
+#
+#
+0x20	0x0020	# SPACE
+0x21	0x0021	# EXCLAMATION MARK
+0x22	0x0022	# QUOTATION MARK
+0x23	0x0023	# NUMBER SIGN
+0x24	0x0024	# DOLLAR SIGN
+0x25	0x0025	# PERCENT SIGN
+0x26	0x0026	# AMPERSAND
+0x27	0x0027	# APOSTROPHE
+0x28	0x0028	# LEFT PARENTHESIS
+0x29	0x0029	# RIGHT PARENTHESIS
+0x2A	0x002A	# ASTERISK
+0x2B	0x002B	# PLUS SIGN
+0x2C	0x002C	# COMMA
+0x2D	0x002D	# HYPHEN-MINUS
+0x2E	0x002E	# FULL STOP
+0x2F	0x002F	# SOLIDUS
+0x30	0x0030	# DIGIT ZERO
+0x31	0x0031	# DIGIT ONE
+0x32	0x0032	# DIGIT TWO
+0x33	0x0033	# DIGIT THREE
+0x34	0x0034	# DIGIT FOUR
+0x35	0x0035	# DIGIT FIVE
+0x36	0x0036	# DIGIT SIX
+0x37	0x0037	# DIGIT SEVEN
+0x38	0x0038	# DIGIT EIGHT
+0x39	0x0039	# DIGIT NINE
+0x3A	0x003A	# COLON
+0x3B	0x003B	# SEMICOLON
+0x3C	0x003C	# LESS-THAN SIGN
+0x3D	0x003D	# EQUALS SIGN
+0x3E	0x003E	# GREATER-THAN SIGN
+0x3F	0x003F	# QUESTION MARK
+0x40	0x0040	# COMMERCIAL AT
+0x41	0x0041	# LATIN CAPITAL LETTER A
+0x42	0x0042	# LATIN CAPITAL LETTER B
+0x43	0x0043	# LATIN CAPITAL LETTER C
+0x44	0x0044	# LATIN CAPITAL LETTER D
+0x45	0x0045	# LATIN CAPITAL LETTER E
+0x46	0x0046	# LATIN CAPITAL LETTER F
+0x47	0x0047	# LATIN CAPITAL LETTER G
+0x48	0x0048	# LATIN CAPITAL LETTER H
+0x49	0x0049	# LATIN CAPITAL LETTER I
+0x4A	0x004A	# LATIN CAPITAL LETTER J
+0x4B	0x004B	# LATIN CAPITAL LETTER K
+0x4C	0x004C	# LATIN CAPITAL LETTER L
+0x4D	0x004D	# LATIN CAPITAL LETTER M
+0x4E	0x004E	# LATIN CAPITAL LETTER N
+0x4F	0x004F	# LATIN CAPITAL LETTER O
+0x50	0x0050	# LATIN CAPITAL LETTER P
+0x51	0x0051	# LATIN CAPITAL LETTER Q
+0x52	0x0052	# LATIN CAPITAL LETTER R
+0x53	0x0053	# LATIN CAPITAL LETTER S
+0x54	0x0054	# LATIN CAPITAL LETTER T
+0x55	0x0055	# LATIN CAPITAL LETTER U
+0x56	0x0056	# LATIN CAPITAL LETTER V
+0x57	0x0057	# LATIN CAPITAL LETTER W
+0x58	0x0058	# LATIN CAPITAL LETTER X
+0x59	0x0059	# LATIN CAPITAL LETTER Y
+0x5A	0x005A	# LATIN CAPITAL LETTER Z
+0x5B	0x005B	# LEFT SQUARE BRACKET
+0x5C	0x005C	#REVERSE SOLIDUS (rendered as Halfwidth Yen Sign)
+0x5D	0x005D	# RIGHT SQUARE BRACKET
+0x5E	0x005E	# CIRCUMFLEX ACCENT
+0x5F	0x005F	# LOW LINE
+0x60	0x0060	# GRAVE ACCENT
+0x61	0x0061	# LATIN SMALL LETTER A
+0x62	0x0062	# LATIN SMALL LETTER B
+0x63	0x0063	# LATIN SMALL LETTER C
+0x64	0x0064	# LATIN SMALL LETTER D
+0x65	0x0065	# LATIN SMALL LETTER E
+0x66	0x0066	# LATIN SMALL LETTER F
+0x67	0x0067	# LATIN SMALL LETTER G
+0x68	0x0068	# LATIN SMALL LETTER H
+0x69	0x0069	# LATIN SMALL LETTER I
+0x6A	0x006A	# LATIN SMALL LETTER J
+0x6B	0x006B	# LATIN SMALL LETTER K
+0x6C	0x006C	# LATIN SMALL LETTER L
+0x6D	0x006D	# LATIN SMALL LETTER M
+0x6E	0x006E	# LATIN SMALL LETTER N
+0x6F	0x006F	# LATIN SMALL LETTER O
+0x70	0x0070	# LATIN SMALL LETTER P
+0x71	0x0071	# LATIN SMALL LETTER Q
+0x72	0x0072	# LATIN SMALL LETTER R
+0x73	0x0073	# LATIN SMALL LETTER S
+0x74	0x0074	# LATIN SMALL LETTER T
+0x75	0x0075	# LATIN SMALL LETTER U
+0x76	0x0076	# LATIN SMALL LETTER V
+0x77	0x0077	# LATIN SMALL LETTER W
+0x78	0x0078	# LATIN SMALL LETTER X
+0x79	0x0079	# LATIN SMALL LETTER Y
+0x7A	0x007A	# LATIN SMALL LETTER Z
+0x7B	0x007B	# LEFT CURLY BRACKET
+0x7C	0x007C	# VERTICAL LINE
+0x7D	0x007D	# RIGHT CURLY BRACKET
+0x7E	0x007E	# TILDE
+0xA140	0x3000	# IDEOGRAPHIC SPACE
+0xA141	0xFF0C	# FULLWIDTH COMMA
+0xA142	0x3001	# IDEOGRAPHIC COMMA
+0xA143	0x3002	# IDEOGRAPHIC FULL STOP
+0xA144	0xFF0E	# FULLWIDTH FULL STOP
+0xA145	0x2022	# BULLET
+0xA146	0xFF1B	# FULLWIDTH SEMICOLON
+0xA147	0xFF1A	# FULLWIDTH COLON
+0xA148	0xFF1F	# FULLWIDTH QUESTION MARK
+0xA149	0xFF01	# FULLWIDTH EXCLAMATION MARK
+0xA14A	0xFE30	# PRESENTATION FORM FOR VERTICAL TWO DOT LEADER
+0xA14B	0x2026	# HORIZONTAL ELLIPSIS
+0xA14C	0x2025	# TWO DOT LEADER
+0xA14D	0xFE50	# SMALL COMMA
+0xA14E	0xFF64	# HALFWIDTH IDEOGRAPHIC COMMA
+0xA14F	0xFE52	# SMALL FULL STOP
+0xA150	0x00B7	# MIDDLE DOT
+0xA151	0xFE54	# SMALL SEMICOLON
+0xA152	0xFE55	# SMALL COLON
+0xA153	0xFE56	# SMALL QUESTION MARK
+0xA154	0xFE57	# SMALL EXCLAMATION MARK
+0xA155	0xFF5C	# FULLWIDTH VERTICAL BAR
+0xA156	0x2013	# EN DASH
+0xA157	0xFE31	# PRESENTATION FORM FOR VERTICAL EM DASH
+0xA158	0x2014	# EM DASH
+0xA159	0xFE33	# PRESENTATION FORM FOR VERTICAL LOW LINE
+0xA15A	0xFFFD	# *** NO MAPPING ***
+0xA15B	0xFE34	# PRESENTATION FORM FOR VERTICAL WAVY LOW LINE
+0xA15C	0xFE4F	# WAVY LOW LINE
+0xA15D	0xFF08	# FULLWIDTH LEFT PARENTHESIS
+0xA15E	0xFF09	# FULLWIDTH RIGHT PARENTHESIS
+0xA15F	0xFE35	# PRESENTATION FORM FOR VERTICAL LEFT PARENTHESIS
+0xA160	0xFE36	# PRESENTATION FORM FOR VERTICAL RIGHT PARENTHESIS
+0xA161	0xFF5B	# FULLWIDTH LEFT CURLY BRACKET
+0xA162	0xFF5D	# FULLWIDTH RIGHT CURLY BRACKET
+0xA163	0xFE37	# PRESENTATION FORM FOR VERTICAL LEFT CURLY BRACKET
+0xA164	0xFE38	# PRESENTATION FORM FOR VERTICAL RIGHT CURLY BRACKET
+0xA165	0x3014	# LEFT TORTOISE SHELL BRACKET
+0xA166	0x3015	# RIGHT TORTOISE SHELL BRACKET
+0xA167	0xFE39	# PRESENTATION FORM FOR VERTICAL LEFT TORTOISE SHELL BRACKET
+0xA168	0xFE3A	# PRESENTATION FORM FOR VERTICAL RIGHT TORTOISE SHELL BRACKET
+0xA169	0x3010	# LEFT BLACK LENTICULAR BRACKET
+0xA16A	0x3011	# RIGHT BLACK LENTICULAR BRACKET
+0xA16B	0xFE3B	# PRESENTATION FORM FOR VERTICAL LEFT BLACK LENTICULAR BRACKET
+0xA16C	0xFE3C	# PRESENTATION FORM FOR VERTICAL RIGHT BLACK LENTICULAR BRACKET
+0xA16D	0x300A	# LEFT DOUBLE ANGLE BRACKET
+0xA16E	0x300B	# RIGHT DOUBLE ANGLE BRACKET
+0xA16F	0xFE3D	# PRESENTATION FORM FOR VERTICAL LEFT DOUBLE ANGLE BRACKET
+0xA170	0xFE3E	# PRESENTATION FORM FOR VERTICAL RIGHT DOUBLE ANGLE BRACKET
+0xA171	0x3008	# LEFT ANGLE BRACKET
+0xA172	0x3009	# RIGHT ANGLE BRACKET
+0xA173	0xFE3F	# PRESENTATION FORM FOR VERTICAL LEFT ANGLE BRACKET
+0xA174	0xFE40	# PRESENTATION FORM FOR VERTICAL RIGHT ANGLE BRACKET
+0xA175	0x300C	# LEFT CORNER BRACKET
+0xA176	0x300D	# RIGHT CORNER BRACKET
+0xA177	0xFE41	# PRESENTATION FORM FOR VERTICAL LEFT CORNER BRACKET
+0xA178	0xFE42	# PRESENTATION FORM FOR VERTICAL RIGHT CORNER BRACKET
+0xA179	0x300E	# LEFT WHITE CORNER BRACKET
+0xA17A	0x300F	# RIGHT WHITE CORNER BRACKET
+0xA17B	0xFE43	# PRESENTATION FORM FOR VERTICAL LEFT WHITE CORNER BRACKET
+0xA17C	0xFE44	# PRESENTATION FORM FOR VERTICAL RIGHT WHITE CORNER BRACKET
+0xA17D	0xFE59	# SMALL LEFT PARENTHESIS
+0xA17E	0xFE5A	# SMALL RIGHT PARENTHESIS
+0xA1A1	0xFE5B	# SMALL LEFT CURLY BRACKET
+0xA1A2	0xFE5C	# SMALL RIGHT CURLY BRACKET
+0xA1A3	0xFE5D	# SMALL LEFT TORTOISE SHELL BRACKET
+0xA1A4	0xFE5E	# SMALL RIGHT TORTOISE SHELL BRACKET
+0xA1A5	0x2018	# LEFT SINGLE QUOTATION MARK
+0xA1A6	0x2019	# RIGHT SINGLE QUOTATION MARK
+0xA1A7	0x201C	# LEFT DOUBLE QUOTATION MARK
+0xA1A8	0x201D	# RIGHT DOUBLE QUOTATION MARK
+0xA1A9	0x301D	# REVERSED DOUBLE PRIME QUOTATION MARK
+0xA1AA	0x301E	# DOUBLE PRIME QUOTATION MARK
+0xA1AB	0x2035	# REVERSED PRIME
+0xA1AC	0x2032	# PRIME
+0xA1AD	0xFF03	# FULLWIDTH NUMBER SIGN
+0xA1AE	0xFF06	# FULLWIDTH AMPERSAND
+0xA1AF	0xFF0A	# FULLWIDTH ASTERISK
+0xA1B0	0x203B	# REFERENCE MARK
+0xA1B1	0x00A7	# SECTION SIGN
+0xA1B2	0x3003	# DITTO MARK
+0xA1B3	0x25CB	# WHITE CIRCLE
+0xA1B4	0x25CF	# BLACK CIRCLE
+0xA1B5	0x25B3	# WHITE UP-POINTING TRIANGLE
+0xA1B6	0x25B2	# BLACK UP-POINTING TRIANGLE
+0xA1B7	0x25CE	# BULLSEYE
+0xA1B8	0x2606	# WHITE STAR
+0xA1B9	0x2605	# BLACK STAR
+0xA1BA	0x25C7	# WHITE DIAMOND
+0xA1BB	0x25C6	# BLACK DIAMOND
+0xA1BC	0x25A1	# WHITE SQUARE
+0xA1BD	0x25A0	# BLACK SQUARE
+0xA1BE	0x25BD	# WHITE DOWN-POINTING TRIANGLE
+0xA1BF	0x25BC	# BLACK DOWN-POINTING TRIANGLE
+0xA1C0	0x32A3	# CIRCLED IDEOGRAPH CORRECT
+0xA1C1	0x2105	# CARE OF
+0xA1C2	0x203E	# OVERLINE
+0xA1C3	0xFFFD	# *** NO MAPPING ***
+0xA1C4	0xFF3F	# FULLWIDTH LOW LINE
+0xA1C5	0xFFFD	# *** NO MAPPING ***
+0xA1C6	0xFE49	# DASHED OVERLINE
+0xA1C7	0xFE4A	# CENTRELINE OVERLINE
+0xA1C8	0xFE4D	# DASHED LOW LINE
+0xA1C9	0xFE4E	# CENTRELINE LOW LINE
+0xA1CA	0xFE4B	# WAVY OVERLINE
+0xA1CB	0xFE4C	# DOUBLE WAVY OVERLINE
+0xA1CC	0xFE5F	# SMALL NUMBER SIGN
+0xA1CD	0xFE60	# SMALL AMPERSAND
+0xA1CE	0xFE61	# SMALL ASTERISK
+0xA1CF	0xFF0B	# FULLWIDTH PLUS SIGN
+0xA1D0	0xFF0D	# FULLWIDTH HYPHEN-MINUS
+0xA1D1	0x00D7	# MULTIPLICATION SIGN
+0xA1D2	0x00F7	# DIVISION SIGN
+0xA1D3	0x00B1	# PLUS-MINUS SIGN
+0xA1D4	0x221A	# SQUARE ROOT
+0xA1D5	0xFF1C	# FULLWIDTH LESS-THAN SIGN
+0xA1D6	0xFF1E	# FULLWIDTH GREATER-THAN SIGN
+0xA1D7	0xFF1D	# FULLWIDTH EQUALS SIGN
+0xA1D8	0x2266	# LESS THAN OVER EQUAL TO
+0xA1D9	0x2267	# GREATER THAN OVER EQUAL TO
+0xA1DA	0x2260	# NOT EQUAL TO
+0xA1DB	0x221E	# INFINITY
+0xA1DC	0x2252	# APPROXIMATELY EQUAL TO OR THE IMAGE OF
+0xA1DD	0x2261	# IDENTICAL TO
+0xA1DE	0xFE62	# SMALL PLUS SIGN
+0xA1DF	0xFE63	# SMALL HYPHEN-MINUS
+0xA1E0	0xFE64	# SMALL LESS-THAN SIGN
+0xA1E1	0xFE65	# SMALL GREATER-THAN SIGN
+0xA1E2	0xFE66	# SMALL EQUALS SIGN
+0xA1E3	0x223C	# TILDE OPERATOR
+0xA1E4	0x2229	# INTERSECTION
+0xA1E5	0x222A	# UNION
+0xA1E6	0x22A5	# UP TACK
+0xA1E7	0x2220	# ANGLE
+0xA1E8	0x221F	# RIGHT ANGLE
+0xA1E9	0x22BF	# RIGHT TRIANGLE
+0xA1EA	0x33D2	# SQUARE LOG
+0xA1EB	0x33D1	# SQUARE LN
+0xA1EC	0x222B	# INTEGRAL
+0xA1ED	0x222E	# CONTOUR INTEGRAL
+0xA1EE	0x2235	# BECAUSE
+0xA1EF	0x2234	# THEREFORE
+0xA1F0	0x2640	# FEMALE SIGN
+0xA1F1	0x2642	# MALE SIGN
+0xA1F2	0x2641	# EARTH
+0xA1F3	0x2609	# SUN
+0xA1F4	0x2191	# UPWARDS ARROW
+0xA1F5	0x2193	# DOWNWARDS ARROW
+0xA1F6	0x2190	# LEFTWARDS ARROW
+0xA1F7	0x2192	# RIGHTWARDS ARROW
+0xA1F8	0x2196	# NORTH WEST ARROW
+0xA1F9	0x2197	# NORTH EAST ARROW
+0xA1FA	0x2199	# SOUTH WEST ARROW
+0xA1FB	0x2198	# SOUTH EAST ARROW
+0xA1FC	0x2225	# PARALLEL TO
+0xA1FD	0x2223	# DIVIDES
+0xA1FE	0xFFFD	# *** NO MAPPING ***
+0xA240	0xFFFD	# *** NO MAPPING ***
+0xA241	0xFF0F	# FULLWIDTH SOLIDUS
+0xA242	0xFF3C	# FULLWIDTH REVERSE SOLIDUS
+0xA243	0xFF04	# FULLWIDTH DOLLAR SIGN
+0xA244	0x00A5	# YEN SIGN
+0xA245	0x3012	# POSTAL MARK
+0xA246	0x00A2	# CENT SIGN
+0xA247	0x00A3	# POUND SIGN
+0xA248	0xFF05	# FULLWIDTH PERCENT SIGN
+0xA249	0xFF20	# FULLWIDTH COMMERCIAL AT
+0xA24A	0x2103	# DEGREE CELSIUS
+0xA24B	0x2109	# DEGREE FAHRENHEIT
+0xA24C	0xFE69	# SMALL DOLLAR SIGN
+0xA24D	0xFE6A	# SMALL PERCENT SIGN
+0xA24E	0xFE6B	# SMALL COMMERCIAL AT
+0xA24F	0x33D5	# SQUARE MIL
+0xA250	0x339C	# SQUARE MM
+0xA251	0x339D	# SQUARE CM
+0xA252	0x339E	# SQUARE KM
+0xA253	0x33CE	# SQUARE KM CAPITAL
+0xA254	0x33A1	# SQUARE M SQUARED
+0xA255	0x338E	# SQUARE MG
+0xA256	0x338F	# SQUARE KG
+0xA257	0x33C4	# SQUARE CC
+0xA258	0x00B0	# DEGREE SIGN
+0xA259	0x5159	# <CJK>
+0xA25A	0x515B	# <CJK>
+0xA25B	0x515E	# <CJK>
+0xA25C	0x515D	# <CJK>
+0xA25D	0x5161	# <CJK>
+0xA25E	0x5163	# <CJK>
+0xA25F	0x55E7	# <CJK>
+0xA260	0x74E9	# <CJK>
+0xA261	0x7CCE	# <CJK>
+0xA262	0x2581	# LOWER ONE EIGHTH BLOCK
+0xA263	0x2582	# LOWER ONE QUARTER BLOCK
+0xA264	0x2583	# LOWER THREE EIGHTHS BLOCK
+0xA265	0x2584	# LOWER HALF BLOCK
+0xA266	0x2585	# LOWER FIVE EIGHTHS BLOCK
+0xA267	0x2586	# LOWER THREE QUARTERS BLOCK
+0xA268	0x2587	# LOWER SEVEN EIGHTHS BLOCK
+0xA269	0x2588	# FULL BLOCK
+0xA26A	0x258F	# LEFT ONE EIGHTH BLOCK
+0xA26B	0x258E	# LEFT ONE QUARTER BLOCK
+0xA26C	0x258D	# LEFT THREE EIGHTHS BLOCK
+0xA26D	0x258C	# LEFT HALF BLOCK
+0xA26E	0x258B	# LEFT FIVE EIGHTHS BLOCK
+0xA26F	0x258A	# LEFT THREE QUARTERS BLOCK
+0xA270	0x2589	# LEFT SEVEN EIGHTHS BLOCK
+0xA271	0x253C	# BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
+0xA272	0x2534	# BOX DRAWINGS LIGHT UP AND HORIZONTAL
+0xA273	0x252C	# BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
+0xA274	0x2524	# BOX DRAWINGS LIGHT VERTICAL AND LEFT
+0xA275	0x251C	# BOX DRAWINGS LIGHT VERTICAL AND RIGHT
+0xA276	0x2594	# UPPER ONE EIGHTH BLOCK
+0xA277	0x2500	# BOX DRAWINGS LIGHT HORIZONTAL
+0xA278	0x2502	# BOX DRAWINGS LIGHT VERTICAL
+0xA279	0x2595	# RIGHT ONE EIGHTH BLOCK
+0xA27A	0x250C	# BOX DRAWINGS LIGHT DOWN AND RIGHT
+0xA27B	0x2510	# BOX DRAWINGS LIGHT DOWN AND LEFT
+0xA27C	0x2514	# BOX DRAWINGS LIGHT UP AND RIGHT
+0xA27D	0x2518	# BOX DRAWINGS LIGHT UP AND LEFT
+0xA27E	0x256D	# BOX DRAWINGS LIGHT ARC DOWN AND RIGHT
+0xA2A1	0x256E	# BOX DRAWINGS LIGHT ARC DOWN AND LEFT
+0xA2A2	0x2570	# BOX DRAWINGS LIGHT ARC UP AND RIGHT
+0xA2A3	0x256F	# BOX DRAWINGS LIGHT ARC UP AND LEFT
+0xA2A4	0x2550	# BOX DRAWINGS DOUBLE HORIZONTAL
+0xA2A5	0x255E	# BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE
+0xA2A6	0x256A	# BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE
+0xA2A7	0x2561	# BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE
+0xA2A8	0x25E2	# BLACK LOWER RIGHT TRIANGLE
+0xA2A9	0x25E3	# BLACK LOWER LEFT TRIANGLE
+0xA2AA	0x25E5	# BLACK UPPER RIGHT TRIANGLE
+0xA2AB	0x25E4	# BLACK UPPER LEFT TRIANGLE
+0xA2AC	0x2571	# BOX DRAWINGS LIGHT DIAGONAL UPPER RIGHT TO LOWER LEFT
+0xA2AD	0x2572	# BOX DRAWINGS LIGHT DIAGONAL UPPER LEFT TO LOWER RIGHT
+0xA2AE	0x2573	# BOX DRAWINGS LIGHT DIAGONAL CROSS
+0xA2AF	0xFF10	# FULLWIDTH DIGIT ZERO
+0xA2B0	0xFF11	# FULLWIDTH DIGIT ONE
+0xA2B1	0xFF12	# FULLWIDTH DIGIT TWO
+0xA2B2	0xFF13	# FULLWIDTH DIGIT THREE
+0xA2B3	0xFF14	# FULLWIDTH DIGIT FOUR
+0xA2B4	0xFF15	# FULLWIDTH DIGIT FIVE
+0xA2B5	0xFF16	# FULLWIDTH DIGIT SIX
+0xA2B6	0xFF17	# FULLWIDTH DIGIT SEVEN
+0xA2B7	0xFF18	# FULLWIDTH DIGIT EIGHT
+0xA2B8	0xFF19	# FULLWIDTH DIGIT NINE
+0xA2B9	0x2160	# ROMAN NUMERAL ONE
+0xA2BA	0x2161	# ROMAN NUMERAL TWO
+0xA2BB	0x2162	# ROMAN NUMERAL THREE
+0xA2BC	0x2163	# ROMAN NUMERAL FOUR
+0xA2BD	0x2164	# ROMAN NUMERAL FIVE
+0xA2BE	0x2165	# ROMAN NUMERAL SIX
+0xA2BF	0x2166	# ROMAN NUMERAL SEVEN
+0xA2C0	0x2167	# ROMAN NUMERAL EIGHT
+0xA2C1	0x2168	# ROMAN NUMERAL NINE
+0xA2C2	0x2169	# ROMAN NUMERAL TEN
+0xA2C3	0x3021	# HANGZHOU NUMERAL ONE
+0xA2C4	0x3022	# HANGZHOU NUMERAL TWO
+0xA2C5	0x3023	# HANGZHOU NUMERAL THREE
+0xA2C6	0x3024	# HANGZHOU NUMERAL FOUR
+0xA2C7	0x3025	# HANGZHOU NUMERAL FIVE
+0xA2C8	0x3026	# HANGZHOU NUMERAL SIX
+0xA2C9	0x3027	# HANGZHOU NUMERAL SEVEN
+0xA2CA	0x3028	# HANGZHOU NUMERAL EIGHT
+0xA2CB	0x3029	# HANGZHOU NUMERAL NINE
+0xA2CC	0xFFFD	# *** NO MAPPING ***
+0xA2CD	0x5344	# <CJK>
+0xA2CE	0xFFFD	# *** NO MAPPING ***
+0xA2CF	0xFF21	# FULLWIDTH LATIN CAPITAL LETTER A
+0xA2D0	0xFF22	# FULLWIDTH LATIN CAPITAL LETTER B
+0xA2D1	0xFF23	# FULLWIDTH LATIN CAPITAL LETTER C
+0xA2D2	0xFF24	# FULLWIDTH LATIN CAPITAL LETTER D
+0xA2D3	0xFF25	# FULLWIDTH LATIN CAPITAL LETTER E
+0xA2D4	0xFF26	# FULLWIDTH LATIN CAPITAL LETTER F
+0xA2D5	0xFF27	# FULLWIDTH LATIN CAPITAL LETTER G
+0xA2D6	0xFF28	# FULLWIDTH LATIN CAPITAL LETTER H
+0xA2D7	0xFF29	# FULLWIDTH LATIN CAPITAL LETTER I
+0xA2D8	0xFF2A	# FULLWIDTH LATIN CAPITAL LETTER J
+0xA2D9	0xFF2B	# FULLWIDTH LATIN CAPITAL LETTER K
+0xA2DA	0xFF2C	# FULLWIDTH LATIN CAPITAL LETTER L
+0xA2DB	0xFF2D	# FULLWIDTH LATIN CAPITAL LETTER M
+0xA2DC	0xFF2E	# FULLWIDTH LATIN CAPITAL LETTER N
+0xA2DD	0xFF2F	# FULLWIDTH LATIN CAPITAL LETTER O
+0xA2DE	0xFF30	# FULLWIDTH LATIN CAPITAL LETTER P
+0xA2DF	0xFF31	# FULLWIDTH LATIN CAPITAL LETTER Q
+0xA2E0	0xFF32	# FULLWIDTH LATIN CAPITAL LETTER R
+0xA2E1	0xFF33	# FULLWIDTH LATIN CAPITAL LETTER S
+0xA2E2	0xFF34	# FULLWIDTH LATIN CAPITAL LETTER T
+0xA2E3	0xFF35	# FULLWIDTH LATIN CAPITAL LETTER U
+0xA2E4	0xFF36	# FULLWIDTH LATIN CAPITAL LETTER V
+0xA2E5	0xFF37	# FULLWIDTH LATIN CAPITAL LETTER W
+0xA2E6	0xFF38	# FULLWIDTH LATIN CAPITAL LETTER X
+0xA2E7	0xFF39	# FULLWIDTH LATIN CAPITAL LETTER Y
+0xA2E8	0xFF3A	# FULLWIDTH LATIN CAPITAL LETTER Z
+0xA2E9	0xFF41	# FULLWIDTH LATIN SMALL LETTER A
+0xA2EA	0xFF42	# FULLWIDTH LATIN SMALL LETTER B
+0xA2EB	0xFF43	# FULLWIDTH LATIN SMALL LETTER C
+0xA2EC	0xFF44	# FULLWIDTH LATIN SMALL LETTER D
+0xA2ED	0xFF45	# FULLWIDTH LATIN SMALL LETTER E
+0xA2EE	0xFF46	# FULLWIDTH LATIN SMALL LETTER F
+0xA2EF	0xFF47	# FULLWIDTH LATIN SMALL LETTER G
+0xA2F0	0xFF48	# FULLWIDTH LATIN SMALL LETTER H
+0xA2F1	0xFF49	# FULLWIDTH LATIN SMALL LETTER I
+0xA2F2	0xFF4A	# FULLWIDTH LATIN SMALL LETTER J
+0xA2F3	0xFF4B	# FULLWIDTH LATIN SMALL LETTER K
+0xA2F4	0xFF4C	# FULLWIDTH LATIN SMALL LETTER L
+0xA2F5	0xFF4D	# FULLWIDTH LATIN SMALL LETTER M
+0xA2F6	0xFF4E	# FULLWIDTH LATIN SMALL LETTER N
+0xA2F7	0xFF4F	# FULLWIDTH LATIN SMALL LETTER O
+0xA2F8	0xFF50	# FULLWIDTH LATIN SMALL LETTER P
+0xA2F9	0xFF51	# FULLWIDTH LATIN SMALL LETTER Q
+0xA2FA	0xFF52	# FULLWIDTH LATIN SMALL LETTER R
+0xA2FB	0xFF53	# FULLWIDTH LATIN SMALL LETTER S
+0xA2FC	0xFF54	# FULLWIDTH LATIN SMALL LETTER T
+0xA2FD	0xFF55	# FULLWIDTH LATIN SMALL LETTER U
+0xA2FE	0xFF56	# FULLWIDTH LATIN SMALL LETTER V
+0xA340	0xFF57	# FULLWIDTH LATIN SMALL LETTER W
+0xA341	0xFF58	# FULLWIDTH LATIN SMALL LETTER X
+0xA342	0xFF59	# FULLWIDTH LATIN SMALL LETTER Y
+0xA343	0xFF5A	# FULLWIDTH LATIN SMALL LETTER Z
+0xA344	0x0391	# GREEK CAPITAL LETTER ALPHA
+0xA345	0x0392	# GREEK CAPITAL LETTER BETA
+0xA346	0x0393	# GREEK CAPITAL LETTER GAMMA
+0xA347	0x0394	# GREEK CAPITAL LETTER DELTA
+0xA348	0x0395	# GREEK CAPITAL LETTER EPSILON
+0xA349	0x0396	# GREEK CAPITAL LETTER ZETA
+0xA34A	0x0397	# GREEK CAPITAL LETTER ETA
+0xA34B	0x0398	# GREEK CAPITAL LETTER THETA
+0xA34C	0x0399	# GREEK CAPITAL LETTER IOTA
+0xA34D	0x039A	# GREEK CAPITAL LETTER KAPPA
+0xA34E	0x039B	# GREEK CAPITAL LETTER LAMDA
+0xA34F	0x039C	# GREEK CAPITAL LETTER MU
+0xA350	0x039D	# GREEK CAPITAL LETTER NU
+0xA351	0x039E	# GREEK CAPITAL LETTER XI
+0xA352	0x039F	# GREEK CAPITAL LETTER OMICRON
+0xA353	0x03A0	# GREEK CAPITAL LETTER PI
+0xA354	0x03A1	# GREEK CAPITAL LETTER RHO
+0xA355	0x03A3	# GREEK CAPITAL LETTER SIGMA
+0xA356	0x03A4	# GREEK CAPITAL LETTER TAU
+0xA357	0x03A5	# GREEK CAPITAL LETTER UPSILON
+0xA358	0x03A6	# GREEK CAPITAL LETTER PHI
+0xA359	0x03A7	# GREEK CAPITAL LETTER CHI
+0xA35A	0x03A8	# GREEK CAPITAL LETTER PSI
+0xA35B	0x03A9	# GREEK CAPITAL LETTER OMEGA
+0xA35C	0x03B1	# GREEK SMALL LETTER ALPHA
+0xA35D	0x03B2	# GREEK SMALL LETTER BETA
+0xA35E	0x03B3	# GREEK SMALL LETTER GAMMA
+0xA35F	0x03B4	# GREEK SMALL LETTER DELTA
+0xA360	0x03B5	# GREEK SMALL LETTER EPSILON
+0xA361	0x03B6	# GREEK SMALL LETTER ZETA
+0xA362	0x03B7	# GREEK SMALL LETTER ETA
+0xA363	0x03B8	# GREEK SMALL LETTER THETA
+0xA364	0x03B9	# GREEK SMALL LETTER IOTA
+0xA365	0x03BA	# GREEK SMALL LETTER KAPPA
+0xA366	0x03BB	# GREEK SMALL LETTER LAMDA
+0xA367	0x03BC	# GREEK SMALL LETTER MU
+0xA368	0x03BD	# GREEK SMALL LETTER NU
+0xA369	0x03BE	# GREEK SMALL LETTER XI
+0xA36A	0x03BF	# GREEK SMALL LETTER OMICRON
+0xA36B	0x03C0	# GREEK SMALL LETTER PI
+0xA36C	0x03C1	# GREEK SMALL LETTER RHO
+0xA36D	0x03C3	# GREEK SMALL LETTER SIGMA
+0xA36E	0x03C4	# GREEK SMALL LETTER TAU
+0xA36F	0x03C5	# GREEK SMALL LETTER UPSILON
+0xA370	0x03C6	# GREEK SMALL LETTER PHI
+0xA371	0x03C7	# GREEK SMALL LETTER CHI
+0xA372	0x03C8	# GREEK SMALL LETTER PSI
+0xA373	0x03C9	# GREEK SMALL LETTER OMEGA
+0xA374	0x3105	# BOPOMOFO LETTER B
+0xA375	0x3106	# BOPOMOFO LETTER P
+0xA376	0x3107	# BOPOMOFO LETTER M
+0xA377	0x3108	# BOPOMOFO LETTER F
+0xA378	0x3109	# BOPOMOFO LETTER D
+0xA379	0x310A	# BOPOMOFO LETTER T
+0xA37A	0x310B	# BOPOMOFO LETTER N
+0xA37B	0x310C	# BOPOMOFO LETTER L
+0xA37C	0x310D	# BOPOMOFO LETTER G
+0xA37D	0x310E	# BOPOMOFO LETTER K
+0xA37E	0x310F	# BOPOMOFO LETTER H
+0xA3A1	0x3110	# BOPOMOFO LETTER J
+0xA3A2	0x3111	# BOPOMOFO LETTER Q
+0xA3A3	0x3112	# BOPOMOFO LETTER X
+0xA3A4	0x3113	# BOPOMOFO LETTER ZH
+0xA3A5	0x3114	# BOPOMOFO LETTER CH
+0xA3A6	0x3115	# BOPOMOFO LETTER SH
+0xA3A7	0x3116	# BOPOMOFO LETTER R
+0xA3A8	0x3117	# BOPOMOFO LETTER Z
+0xA3A9	0x3118	# BOPOMOFO LETTER C
+0xA3AA	0x3119	# BOPOMOFO LETTER S
+0xA3AB	0x311A	# BOPOMOFO LETTER A
+0xA3AC	0x311B	# BOPOMOFO LETTER O
+0xA3AD	0x311C	# BOPOMOFO LETTER E
+0xA3AE	0x311D	# BOPOMOFO LETTER EH
+0xA3AF	0x311E	# BOPOMOFO LETTER AI
+0xA3B0	0x311F	# BOPOMOFO LETTER EI
+0xA3B1	0x3120	# BOPOMOFO LETTER AU
+0xA3B2	0x3121	# BOPOMOFO LETTER OU
+0xA3B3	0x3122	# BOPOMOFO LETTER AN
+0xA3B4	0x3123	# BOPOMOFO LETTER EN
+0xA3B5	0x3124	# BOPOMOFO LETTER ANG
+0xA3B6	0x3125	# BOPOMOFO LETTER ENG
+0xA3B7	0x3126	# BOPOMOFO LETTER ER
+0xA3B8	0x3127	# BOPOMOFO LETTER I
+0xA3B9	0x3128	# BOPOMOFO LETTER U
+0xA3BA	0x3129	# BOPOMOFO LETTER IU
+0xA3BB	0x02D9	# DOT ABOVE (Mandarin Chinese light tone)
+0xA3BC	0x02C9	# MODIFIER LETTER MACRON (Mandarin Chinese first tone)
+0xA3BD	0x02CA	# MODIFIER LETTER ACUTE ACCENT (Mandarin Chinese second tone)
+0xA3BE	0x02C7	# CARON (Mandarin Chinese third tone)
+0xA3BF	0x02CB	# MODIFIER LETTER GRAVE ACCENT (Mandarin Chinese fourth tone)
+0xA440	0x4E00	# <CJK>
+0xA441	0x4E59	# <CJK>
+0xA442	0x4E01	# <CJK>
+0xA443	0x4E03	# <CJK>
+0xA444	0x4E43	# <CJK>
+0xA445	0x4E5D	# <CJK>
+0xA446	0x4E86	# <CJK>
+0xA447	0x4E8C	# <CJK>
+0xA448	0x4EBA	# <CJK>
+0xA449	0x513F	# <CJK>
+0xA44A	0x5165	# <CJK>
+0xA44B	0x516B	# <CJK>
+0xA44C	0x51E0	# <CJK>
+0xA44D	0x5200	# <CJK>
+0xA44E	0x5201	# <CJK>
+0xA44F	0x529B	# <CJK>
+0xA450	0x5315	# <CJK>
+0xA451	0x5341	# <CJK>
+0xA452	0x535C	# <CJK>
+0xA453	0x53C8	# <CJK>
+0xA454	0x4E09	# <CJK>
+0xA455	0x4E0B	# <CJK>
+0xA456	0x4E08	# <CJK>
+0xA457	0x4E0A	# <CJK>
+0xA458	0x4E2B	# <CJK>
+0xA459	0x4E38	# <CJK>
+0xA45A	0x51E1	# <CJK>
+0xA45B	0x4E45	# <CJK>
+0xA45C	0x4E48	# <CJK>
+0xA45D	0x4E5F	# <CJK>
+0xA45E	0x4E5E	# <CJK>
+0xA45F	0x4E8E	# <CJK>
+0xA460	0x4EA1	# <CJK>
+0xA461	0x5140	# <CJK>
+0xA462	0x5203	# <CJK>
+0xA463	0x52FA	# <CJK>
+0xA464	0x5343	# <CJK>
+0xA465	0x53C9	# <CJK>
+0xA466	0x53E3	# <CJK>
+0xA467	0x571F	# <CJK>
+0xA468	0x58EB	# <CJK>
+0xA469	0x5915	# <CJK>
+0xA46A	0x5927	# <CJK>
+0xA46B	0x5973	# <CJK>
+0xA46C	0x5B50	# <CJK>
+0xA46D	0x5B51	# <CJK>
+0xA46E	0x5B53	# <CJK>
+0xA46F	0x5BF8	# <CJK>
+0xA470	0x5C0F	# <CJK>
+0xA471	0x5C22	# <CJK>
+0xA472	0x5C38	# <CJK>
+0xA473	0x5C71	# <CJK>
+0xA474	0x5DDD	# <CJK>
+0xA475	0x5DE5	# <CJK>
+0xA476	0x5DF1	# <CJK>
+0xA477	0x5DF2	# <CJK>
+0xA478	0x5DF3	# <CJK>
+0xA479	0x5DFE	# <CJK>
+0xA47A	0x5E72	# <CJK>
+0xA47B	0x5EFE	# <CJK>
+0xA47C	0x5F0B	# <CJK>
+0xA47D	0x5F13	# <CJK>
+0xA47E	0x624D	# <CJK>
+0xA4A1	0x4E11	# <CJK>
+0xA4A2	0x4E10	# <CJK>
+0xA4A3	0x4E0D	# <CJK>
+0xA4A4	0x4E2D	# <CJK>
+0xA4A5	0x4E30	# <CJK>
+0xA4A6	0x4E39	# <CJK>
+0xA4A7	0x4E4B	# <CJK>
+0xA4A8	0x5C39	# <CJK>
+0xA4A9	0x4E88	# <CJK>
+0xA4AA	0x4E91	# <CJK>
+0xA4AB	0x4E95	# <CJK>
+0xA4AC	0x4E92	# <CJK>
+0xA4AD	0x4E94	# <CJK>
+0xA4AE	0x4EA2	# <CJK>
+0xA4AF	0x4EC1	# <CJK>
+0xA4B0	0x4EC0	# <CJK>
+0xA4B1	0x4EC3	# <CJK>
+0xA4B2	0x4EC6	# <CJK>
+0xA4B3	0x4EC7	# <CJK>
+0xA4B4	0x4ECD	# <CJK>
+0xA4B5	0x4ECA	# <CJK>
+0xA4B6	0x4ECB	# <CJK>
+0xA4B7	0x4EC4	# <CJK>
+0xA4B8	0x5143	# <CJK>
+0xA4B9	0x5141	# <CJK>
+0xA4BA	0x5167	# <CJK>
+0xA4BB	0x516D	# <CJK>
+0xA4BC	0x516E	# <CJK>
+0xA4BD	0x516C	# <CJK>
+0xA4BE	0x5197	# <CJK>
+0xA4BF	0x51F6	# <CJK>
+0xA4C0	0x5206	# <CJK>
+0xA4C1	0x5207	# <CJK>
+0xA4C2	0x5208	# <CJK>
+0xA4C3	0x52FB	# <CJK>
+0xA4C4	0x52FE	# <CJK>
+0xA4C5	0x52FF	# <CJK>
+0xA4C6	0x5316	# <CJK>
+0xA4C7	0x5339	# <CJK>
+0xA4C8	0x5348	# <CJK>
+0xA4C9	0x5347	# <CJK>
+0xA4CA	0x5345	# <CJK>
+0xA4CB	0x535E	# <CJK>
+0xA4CC	0x5384	# <CJK>
+0xA4CD	0x53CB	# <CJK>
+0xA4CE	0x53CA	# <CJK>
+0xA4CF	0x53CD	# <CJK>
+0xA4D0	0x58EC	# <CJK>
+0xA4D1	0x5929	# <CJK>
+0xA4D2	0x592B	# <CJK>
+0xA4D3	0x592A	# <CJK>
+0xA4D4	0x592D	# <CJK>
+0xA4D5	0x5B54	# <CJK>
+0xA4D6	0x5C11	# <CJK>
+0xA4D7	0x5C24	# <CJK>
+0xA4D8	0x5C3A	# <CJK>
+0xA4D9	0x5C6F	# <CJK>
+0xA4DA	0x5DF4	# <CJK>
+0xA4DB	0x5E7B	# <CJK>
+0xA4DC	0x5EFF	# <CJK>
+0xA4DD	0x5F14	# <CJK>
+0xA4DE	0x5F15	# <CJK>
+0xA4DF	0x5FC3	# <CJK>
+0xA4E0	0x6208	# <CJK>
+0xA4E1	0x6236	# <CJK>
+0xA4E2	0x624B	# <CJK>
+0xA4E3	0x624E	# <CJK>
+0xA4E4	0x652F	# <CJK>
+0xA4E5	0x6587	# <CJK>
+0xA4E6	0x6597	# <CJK>
+0xA4E7	0x65A4	# <CJK>
+0xA4E8	0x65B9	# <CJK>
+0xA4E9	0x65E5	# <CJK>
+0xA4EA	0x66F0	# <CJK>
+0xA4EB	0x6708	# <CJK>
+0xA4EC	0x6728	# <CJK>
+0xA4ED	0x6B20	# <CJK>
+0xA4EE	0x6B62	# <CJK>
+0xA4EF	0x6B79	# <CJK>
+0xA4F0	0x6BCB	# <CJK>
+0xA4F1	0x6BD4	# <CJK>
+0xA4F2	0x6BDB	# <CJK>
+0xA4F3	0x6C0F	# <CJK>
+0xA4F4	0x6C34	# <CJK>
+0xA4F5	0x706B	# <CJK>
+0xA4F6	0x722A	# <CJK>
+0xA4F7	0x7236	# <CJK>
+0xA4F8	0x723B	# <CJK>
+0xA4F9	0x7247	# <CJK>
+0xA4FA	0x7259	# <CJK>
+0xA4FB	0x725B	# <CJK>
+0xA4FC	0x72AC	# <CJK>
+0xA4FD	0x738B	# <CJK>
+0xA4FE	0x4E19	# <CJK>
+0xA540	0x4E16	# <CJK>
+0xA541	0x4E15	# <CJK>
+0xA542	0x4E14	# <CJK>
+0xA543	0x4E18	# <CJK>
+0xA544	0x4E3B	# <CJK>
+0xA545	0x4E4D	# <CJK>
+0xA546	0x4E4F	# <CJK>
+0xA547	0x4E4E	# <CJK>
+0xA548	0x4EE5	# <CJK>
+0xA549	0x4ED8	# <CJK>
+0xA54A	0x4ED4	# <CJK>
+0xA54B	0x4ED5	# <CJK>
+0xA54C	0x4ED6	# <CJK>
+0xA54D	0x4ED7	# <CJK>
+0xA54E	0x4EE3	# <CJK>
+0xA54F	0x4EE4	# <CJK>
+0xA550	0x4ED9	# <CJK>
+0xA551	0x4EDE	# <CJK>
+0xA552	0x5145	# <CJK>
+0xA553	0x5144	# <CJK>
+0xA554	0x5189	# <CJK>
+0xA555	0x518A	# <CJK>
+0xA556	0x51AC	# <CJK>
+0xA557	0x51F9	# <CJK>
+0xA558	0x51FA	# <CJK>
+0xA559	0x51F8	# <CJK>
+0xA55A	0x520A	# <CJK>
+0xA55B	0x52A0	# <CJK>
+0xA55C	0x529F	# <CJK>
+0xA55D	0x5305	# <CJK>
+0xA55E	0x5306	# <CJK>
+0xA55F	0x5317	# <CJK>
+0xA560	0x531D	# <CJK>
+0xA561	0x4EDF	# <CJK>
+0xA562	0x534A	# <CJK>
+0xA563	0x5349	# <CJK>
+0xA564	0x5361	# <CJK>
+0xA565	0x5360	# <CJK>
+0xA566	0x536F	# <CJK>
+0xA567	0x536E	# <CJK>
+0xA568	0x53BB	# <CJK>
+0xA569	0x53EF	# <CJK>
+0xA56A	0x53E4	# <CJK>
+0xA56B	0x53F3	# <CJK>
+0xA56C	0x53EC	# <CJK>
+0xA56D	0x53EE	# <CJK>
+0xA56E	0x53E9	# <CJK>
+0xA56F	0x53E8	# <CJK>
+0xA570	0x53FC	# <CJK>
+0xA571	0x53F8	# <CJK>
+0xA572	0x53F5	# <CJK>
+0xA573	0x53EB	# <CJK>
+0xA574	0x53E6	# <CJK>
+0xA575	0x53EA	# <CJK>
+0xA576	0x53F2	# <CJK>
+0xA577	0x53F1	# <CJK>
+0xA578	0x53F0	# <CJK>
+0xA579	0x53E5	# <CJK>
+0xA57A	0x53ED	# <CJK>
+0xA57B	0x53FB	# <CJK>
+0xA57C	0x56DB	# <CJK>
+0xA57D	0x56DA	# <CJK>
+0xA57E	0x5916	# <CJK>
+0xA5A1	0x592E	# <CJK>
+0xA5A2	0x5931	# <CJK>
+0xA5A3	0x5974	# <CJK>
+0xA5A4	0x5976	# <CJK>
+0xA5A5	0x5B55	# <CJK>
+0xA5A6	0x5B83	# <CJK>
+0xA5A7	0x5C3C	# <CJK>
+0xA5A8	0x5DE8	# <CJK>
+0xA5A9	0x5DE7	# <CJK>
+0xA5AA	0x5DE6	# <CJK>
+0xA5AB	0x5E02	# <CJK>
+0xA5AC	0x5E03	# <CJK>
+0xA5AD	0x5E73	# <CJK>
+0xA5AE	0x5E7C	# <CJK>
+0xA5AF	0x5F01	# <CJK>
+0xA5B0	0x5F18	# <CJK>
+0xA5B1	0x5F17	# <CJK>
+0xA5B2	0x5FC5	# <CJK>
+0xA5B3	0x620A	# <CJK>
+0xA5B4	0x6253	# <CJK>
+0xA5B5	0x6254	# <CJK>
+0xA5B6	0x6252	# <CJK>
+0xA5B7	0x6251	# <CJK>
+0xA5B8	0x65A5	# <CJK>
+0xA5B9	0x65E6	# <CJK>
+0xA5BA	0x672E	# <CJK>
+0xA5BB	0x672C	# <CJK>
+0xA5BC	0x672A	# <CJK>
+0xA5BD	0x672B	# <CJK>
+0xA5BE	0x672D	# <CJK>
+0xA5BF	0x6B63	# <CJK>
+0xA5C0	0x6BCD	# <CJK>
+0xA5C1	0x6C11	# <CJK>
+0xA5C2	0x6C10	# <CJK>
+0xA5C3	0x6C38	# <CJK>
+0xA5C4	0x6C41	# <CJK>
+0xA5C5	0x6C40	# <CJK>
+0xA5C6	0x6C3E	# <CJK>
+0xA5C7	0x72AF	# <CJK>
+0xA5C8	0x7384	# <CJK>
+0xA5C9	0x7389	# <CJK>
+0xA5CA	0x74DC	# <CJK>
+0xA5CB	0x74E6	# <CJK>
+0xA5CC	0x7518	# <CJK>
+0xA5CD	0x751F	# <CJK>
+0xA5CE	0x7528	# <CJK>
+0xA5CF	0x7529	# <CJK>
+0xA5D0	0x7530	# <CJK>
+0xA5D1	0x7531	# <CJK>
+0xA5D2	0x7532	# <CJK>
+0xA5D3	0x7533	# <CJK>
+0xA5D4	0x758B	# <CJK>
+0xA5D5	0x767D	# <CJK>
+0xA5D6	0x76AE	# <CJK>
+0xA5D7	0x76BF	# <CJK>
+0xA5D8	0x76EE	# <CJK>
+0xA5D9	0x77DB	# <CJK>
+0xA5DA	0x77E2	# <CJK>
+0xA5DB	0x77F3	# <CJK>
+0xA5DC	0x793A	# <CJK>
+0xA5DD	0x79BE	# <CJK>
+0xA5DE	0x7A74	# <CJK>
+0xA5DF	0x7ACB	# <CJK>
+0xA5E0	0x4E1E	# <CJK>
+0xA5E1	0x4E1F	# <CJK>
+0xA5E2	0x4E52	# <CJK>
+0xA5E3	0x4E53	# <CJK>
+0xA5E4	0x4E69	# <CJK>
+0xA5E5	0x4E99	# <CJK>
+0xA5E6	0x4EA4	# <CJK>
+0xA5E7	0x4EA6	# <CJK>
+0xA5E8	0x4EA5	# <CJK>
+0xA5E9	0x4EFF	# <CJK>
+0xA5EA	0x4F09	# <CJK>
+0xA5EB	0x4F19	# <CJK>
+0xA5EC	0x4F0A	# <CJK>
+0xA5ED	0x4F15	# <CJK>
+0xA5EE	0x4F0D	# <CJK>
+0xA5EF	0x4F10	# <CJK>
+0xA5F0	0x4F11	# <CJK>
+0xA5F1	0x4F0F	# <CJK>
+0xA5F2	0x4EF2	# <CJK>
+0xA5F3	0x4EF6	# <CJK>
+0xA5F4	0x4EFB	# <CJK>
+0xA5F5	0x4EF0	# <CJK>
+0xA5F6	0x4EF3	# <CJK>
+0xA5F7	0x4EFD	# <CJK>
+0xA5F8	0x4F01	# <CJK>
+0xA5F9	0x4F0B	# <CJK>
+0xA5FA	0x5149	# <CJK>
+0xA5FB	0x5147	# <CJK>
+0xA5FC	0x5146	# <CJK>
+0xA5FD	0x5148	# <CJK>
+0xA5FE	0x5168	# <CJK>
+0xA640	0x5171	# <CJK>
+0xA641	0x518D	# <CJK>
+0xA642	0x51B0	# <CJK>
+0xA643	0x5217	# <CJK>
+0xA644	0x5211	# <CJK>
+0xA645	0x5212	# <CJK>
+0xA646	0x520E	# <CJK>
+0xA647	0x5216	# <CJK>
+0xA648	0x52A3	# <CJK>
+0xA649	0x5308	# <CJK>
+0xA64A	0x5321	# <CJK>
+0xA64B	0x5320	# <CJK>
+0xA64C	0x5370	# <CJK>
+0xA64D	0x5371	# <CJK>
+0xA64E	0x5409	# <CJK>
+0xA64F	0x540F	# <CJK>
+0xA650	0x540C	# <CJK>
+0xA651	0x540A	# <CJK>
+0xA652	0x5410	# <CJK>
+0xA653	0x5401	# <CJK>
+0xA654	0x540B	# <CJK>
+0xA655	0x5404	# <CJK>
+0xA656	0x5411	# <CJK>
+0xA657	0x540D	# <CJK>
+0xA658	0x5408	# <CJK>
+0xA659	0x5403	# <CJK>
+0xA65A	0x540E	# <CJK>
+0xA65B	0x5406	# <CJK>
+0xA65C	0x5412	# <CJK>
+0xA65D	0x56E0	# <CJK>
+0xA65E	0x56DE	# <CJK>
+0xA65F	0x56DD	# <CJK>
+0xA660	0x5733	# <CJK>
+0xA661	0x5730	# <CJK>
+0xA662	0x5728	# <CJK>
+0xA663	0x572D	# <CJK>
+0xA664	0x572C	# <CJK>
+0xA665	0x572F	# <CJK>
+0xA666	0x5729	# <CJK>
+0xA667	0x5919	# <CJK>
+0xA668	0x591A	# <CJK>
+0xA669	0x5937	# <CJK>
+0xA66A	0x5938	# <CJK>
+0xA66B	0x5984	# <CJK>
+0xA66C	0x5978	# <CJK>
+0xA66D	0x5983	# <CJK>
+0xA66E	0x597D	# <CJK>
+0xA66F	0x5979	# <CJK>
+0xA670	0x5982	# <CJK>
+0xA671	0x5981	# <CJK>
+0xA672	0x5B57	# <CJK>
+0xA673	0x5B58	# <CJK>
+0xA674	0x5B87	# <CJK>
+0xA675	0x5B88	# <CJK>
+0xA676	0x5B85	# <CJK>
+0xA677	0x5B89	# <CJK>
+0xA678	0x5BFA	# <CJK>
+0xA679	0x5C16	# <CJK>
+0xA67A	0x5C79	# <CJK>
+0xA67B	0x5DDE	# <CJK>
+0xA67C	0x5E06	# <CJK>
+0xA67D	0x5E76	# <CJK>
+0xA67E	0x5E74	# <CJK>
+0xA6A1	0x5F0F	# <CJK>
+0xA6A2	0x5F1B	# <CJK>
+0xA6A3	0x5FD9	# <CJK>
+0xA6A4	0x5FD6	# <CJK>
+0xA6A5	0x620E	# <CJK>
+0xA6A6	0x620C	# <CJK>
+0xA6A7	0x620D	# <CJK>
+0xA6A8	0x6210	# <CJK>
+0xA6A9	0x6263	# <CJK>
+0xA6AA	0x625B	# <CJK>
+0xA6AB	0x6258	# <CJK>
+0xA6AC	0x6536	# <CJK>
+0xA6AD	0x65E9	# <CJK>
+0xA6AE	0x65E8	# <CJK>
+0xA6AF	0x65EC	# <CJK>
+0xA6B0	0x65ED	# <CJK>
+0xA6B1	0x66F2	# <CJK>
+0xA6B2	0x66F3	# <CJK>
+0xA6B3	0x6709	# <CJK>
+0xA6B4	0x673D	# <CJK>
+0xA6B5	0x6734	# <CJK>
+0xA6B6	0x6731	# <CJK>
+0xA6B7	0x6735	# <CJK>
+0xA6B8	0x6B21	# <CJK>
+0xA6B9	0x6B64	# <CJK>
+0xA6BA	0x6B7B	# <CJK>
+0xA6BB	0x6C16	# <CJK>
+0xA6BC	0x6C5D	# <CJK>
+0xA6BD	0x6C57	# <CJK>
+0xA6BE	0x6C59	# <CJK>
+0xA6BF	0x6C5F	# <CJK>
+0xA6C0	0x6C60	# <CJK>
+0xA6C1	0x6C50	# <CJK>
+0xA6C2	0x6C55	# <CJK>
+0xA6C3	0x6C61	# <CJK>
+0xA6C4	0x6C5B	# <CJK>
+0xA6C5	0x6C4D	# <CJK>
+0xA6C6	0x6C4E	# <CJK>
+0xA6C7	0x7070	# <CJK>
+0xA6C8	0x725F	# <CJK>
+0xA6C9	0x725D	# <CJK>
+0xA6CA	0x767E	# <CJK>
+0xA6CB	0x7AF9	# <CJK>
+0xA6CC	0x7C73	# <CJK>
+0xA6CD	0x7CF8	# <CJK>
+0xA6CE	0x7F36	# <CJK>
+0xA6CF	0x7F8A	# <CJK>
+0xA6D0	0x7FBD	# <CJK>
+0xA6D1	0x8001	# <CJK>
+0xA6D2	0x8003	# <CJK>
+0xA6D3	0x800C	# <CJK>
+0xA6D4	0x8012	# <CJK>
+0xA6D5	0x8033	# <CJK>
+0xA6D6	0x807F	# <CJK>
+0xA6D7	0x8089	# <CJK>
+0xA6D8	0x808B	# <CJK>
+0xA6D9	0x808C	# <CJK>
+0xA6DA	0x81E3	# <CJK>
+0xA6DB	0x81EA	# <CJK>
+0xA6DC	0x81F3	# <CJK>
+0xA6DD	0x81FC	# <CJK>
+0xA6DE	0x820C	# <CJK>
+0xA6DF	0x821B	# <CJK>
+0xA6E0	0x821F	# <CJK>
+0xA6E1	0x826E	# <CJK>
+0xA6E2	0x8272	# <CJK>
+0xA6E3	0x827E	# <CJK>
+0xA6E4	0x866B	# <CJK>
+0xA6E5	0x8840	# <CJK>
+0xA6E6	0x884C	# <CJK>
+0xA6E7	0x8863	# <CJK>
+0xA6E8	0x897F	# <CJK>
+0xA6E9	0x9621	# <CJK>
+0xA6EA	0x4E32	# <CJK>
+0xA6EB	0x4EA8	# <CJK>
+0xA6EC	0x4F4D	# <CJK>
+0xA6ED	0x4F4F	# <CJK>
+0xA6EE	0x4F47	# <CJK>
+0xA6EF	0x4F57	# <CJK>
+0xA6F0	0x4F5E	# <CJK>
+0xA6F1	0x4F34	# <CJK>
+0xA6F2	0x4F5B	# <CJK>
+0xA6F3	0x4F55	# <CJK>
+0xA6F4	0x4F30	# <CJK>
+0xA6F5	0x4F50	# <CJK>
+0xA6F6	0x4F51	# <CJK>
+0xA6F7	0x4F3D	# <CJK>
+0xA6F8	0x4F3A	# <CJK>
+0xA6F9	0x4F38	# <CJK>
+0xA6FA	0x4F43	# <CJK>
+0xA6FB	0x4F54	# <CJK>
+0xA6FC	0x4F3C	# <CJK>
+0xA6FD	0x4F46	# <CJK>
+0xA6FE	0x4F63	# <CJK>
+0xA740	0x4F5C	# <CJK>
+0xA741	0x4F60	# <CJK>
+0xA742	0x4F2F	# <CJK>
+0xA743	0x4F4E	# <CJK>
+0xA744	0x4F36	# <CJK>
+0xA745	0x4F59	# <CJK>
+0xA746	0x4F5D	# <CJK>
+0xA747	0x4F48	# <CJK>
+0xA748	0x4F5A	# <CJK>
+0xA749	0x514C	# <CJK>
+0xA74A	0x514B	# <CJK>
+0xA74B	0x514D	# <CJK>
+0xA74C	0x5175	# <CJK>
+0xA74D	0x51B6	# <CJK>
+0xA74E	0x51B7	# <CJK>
+0xA74F	0x5225	# <CJK>
+0xA750	0x5224	# <CJK>
+0xA751	0x5229	# <CJK>
+0xA752	0x522A	# <CJK>
+0xA753	0x5228	# <CJK>
+0xA754	0x52AB	# <CJK>
+0xA755	0x52A9	# <CJK>
+0xA756	0x52AA	# <CJK>
+0xA757	0x52AC	# <CJK>
+0xA758	0x5323	# <CJK>
+0xA759	0x5373	# <CJK>
+0xA75A	0x5375	# <CJK>
+0xA75B	0x541D	# <CJK>
+0xA75C	0x542D	# <CJK>
+0xA75D	0x541E	# <CJK>
+0xA75E	0x543E	# <CJK>
+0xA75F	0x5426	# <CJK>
+0xA760	0x544E	# <CJK>
+0xA761	0x5427	# <CJK>
+0xA762	0x5446	# <CJK>
+0xA763	0x5443	# <CJK>
+0xA764	0x5433	# <CJK>
+0xA765	0x5448	# <CJK>
+0xA766	0x5442	# <CJK>
+0xA767	0x541B	# <CJK>
+0xA768	0x5429	# <CJK>
+0xA769	0x544A	# <CJK>
+0xA76A	0x5439	# <CJK>
+0xA76B	0x543B	# <CJK>
+0xA76C	0x5438	# <CJK>
+0xA76D	0x542E	# <CJK>
+0xA76E	0x5435	# <CJK>
+0xA76F	0x5436	# <CJK>
+0xA770	0x5420	# <CJK>
+0xA771	0x543C	# <CJK>
+0xA772	0x5440	# <CJK>
+0xA773	0x5431	# <CJK>
+0xA774	0x542B	# <CJK>
+0xA775	0x541F	# <CJK>
+0xA776	0x542C	# <CJK>
+0xA777	0x56EA	# <CJK>
+0xA778	0x56F0	# <CJK>
+0xA779	0x56E4	# <CJK>
+0xA77A	0x56EB	# <CJK>
+0xA77B	0x574A	# <CJK>
+0xA77C	0x5751	# <CJK>
+0xA77D	0x5740	# <CJK>
+0xA77E	0x574D	# <CJK>
+0xA7A1	0x5747	# <CJK>
+0xA7A2	0x574E	# <CJK>
+0xA7A3	0x573E	# <CJK>
+0xA7A4	0x5750	# <CJK>
+0xA7A5	0x574F	# <CJK>
+0xA7A6	0x573B	# <CJK>
+0xA7A7	0x58EF	# <CJK>
+0xA7A8	0x593E	# <CJK>
+0xA7A9	0x599D	# <CJK>
+0xA7AA	0x5992	# <CJK>
+0xA7AB	0x59A8	# <CJK>
+0xA7AC	0x599E	# <CJK>
+0xA7AD	0x59A3	# <CJK>
+0xA7AE	0x5999	# <CJK>
+0xA7AF	0x5996	# <CJK>
+0xA7B0	0x598D	# <CJK>
+0xA7B1	0x59A4	# <CJK>
+0xA7B2	0x5993	# <CJK>
+0xA7B3	0x598A	# <CJK>
+0xA7B4	0x59A5	# <CJK>
+0xA7B5	0x5B5D	# <CJK>
+0xA7B6	0x5B5C	# <CJK>
+0xA7B7	0x5B5A	# <CJK>
+0xA7B8	0x5B5B	# <CJK>
+0xA7B9	0x5B8C	# <CJK>
+0xA7BA	0x5B8B	# <CJK>
+0xA7BB	0x5B8F	# <CJK>
+0xA7BC	0x5C2C	# <CJK>
+0xA7BD	0x5C40	# <CJK>
+0xA7BE	0x5C41	# <CJK>
+0xA7BF	0x5C3F	# <CJK>
+0xA7C0	0x5C3E	# <CJK>
+0xA7C1	0x5C90	# <CJK>
+0xA7C2	0x5C91	# <CJK>
+0xA7C3	0x5C94	# <CJK>
+0xA7C4	0x5C8C	# <CJK>
+0xA7C5	0x5DEB	# <CJK>
+0xA7C6	0x5E0C	# <CJK>
+0xA7C7	0x5E8F	# <CJK>
+0xA7C8	0x5E87	# <CJK>
+0xA7C9	0x5E8A	# <CJK>
+0xA7CA	0x5EF7	# <CJK>
+0xA7CB	0x5F04	# <CJK>
+0xA7CC	0x5F1F	# <CJK>
+0xA7CD	0x5F64	# <CJK>
+0xA7CE	0x5F62	# <CJK>
+0xA7CF	0x5F77	# <CJK>
+0xA7D0	0x5F79	# <CJK>
+0xA7D1	0x5FD8	# <CJK>
+0xA7D2	0x5FCC	# <CJK>
+0xA7D3	0x5FD7	# <CJK>
+0xA7D4	0x5FCD	# <CJK>
+0xA7D5	0x5FF1	# <CJK>
+0xA7D6	0x5FEB	# <CJK>
+0xA7D7	0x5FF8	# <CJK>
+0xA7D8	0x5FEA	# <CJK>
+0xA7D9	0x6212	# <CJK>
+0xA7DA	0x6211	# <CJK>
+0xA7DB	0x6284	# <CJK>
+0xA7DC	0x6297	# <CJK>
+0xA7DD	0x6296	# <CJK>
+0xA7DE	0x6280	# <CJK>
+0xA7DF	0x6276	# <CJK>
+0xA7E0	0x6289	# <CJK>
+0xA7E1	0x626D	# <CJK>
+0xA7E2	0x628A	# <CJK>
+0xA7E3	0x627C	# <CJK>
+0xA7E4	0x627E	# <CJK>
+0xA7E5	0x6279	# <CJK>
+0xA7E6	0x6273	# <CJK>
+0xA7E7	0x6292	# <CJK>
+0xA7E8	0x626F	# <CJK>
+0xA7E9	0x6298	# <CJK>
+0xA7EA	0x626E	# <CJK>
+0xA7EB	0x6295	# <CJK>
+0xA7EC	0x6293	# <CJK>
+0xA7ED	0x6291	# <CJK>
+0xA7EE	0x6286	# <CJK>
+0xA7EF	0x6539	# <CJK>
+0xA7F0	0x653B	# <CJK>
+0xA7F1	0x6538	# <CJK>
+0xA7F2	0x65F1	# <CJK>
+0xA7F3	0x66F4	# <CJK>
+0xA7F4	0x675F	# <CJK>
+0xA7F5	0x674E	# <CJK>
+0xA7F6	0x674F	# <CJK>
+0xA7F7	0x6750	# <CJK>
+0xA7F8	0x6751	# <CJK>
+0xA7F9	0x675C	# <CJK>
+0xA7FA	0x6756	# <CJK>
+0xA7FB	0x675E	# <CJK>
+0xA7FC	0x6749	# <CJK>
+0xA7FD	0x6746	# <CJK>
+0xA7FE	0x6760	# <CJK>
+0xA840	0x6753	# <CJK>
+0xA841	0x6757	# <CJK>
+0xA842	0x6B65	# <CJK>
+0xA843	0x6BCF	# <CJK>
+0xA844	0x6C42	# <CJK>
+0xA845	0x6C5E	# <CJK>
+0xA846	0x6C99	# <CJK>
+0xA847	0x6C81	# <CJK>
+0xA848	0x6C88	# <CJK>
+0xA849	0x6C89	# <CJK>
+0xA84A	0x6C85	# <CJK>
+0xA84B	0x6C9B	# <CJK>
+0xA84C	0x6C6A	# <CJK>
+0xA84D	0x6C7A	# <CJK>
+0xA84E	0x6C90	# <CJK>
+0xA84F	0x6C70	# <CJK>
+0xA850	0x6C8C	# <CJK>
+0xA851	0x6C68	# <CJK>
+0xA852	0x6C96	# <CJK>
+0xA853	0x6C92	# <CJK>
+0xA854	0x6C7D	# <CJK>
+0xA855	0x6C83	# <CJK>
+0xA856	0x6C72	# <CJK>
+0xA857	0x6C7E	# <CJK>
+0xA858	0x6C74	# <CJK>
+0xA859	0x6C86	# <CJK>
+0xA85A	0x6C76	# <CJK>
+0xA85B	0x6C8D	# <CJK>
+0xA85C	0x6C94	# <CJK>
+0xA85D	0x6C98	# <CJK>
+0xA85E	0x6C82	# <CJK>
+0xA85F	0x7076	# <CJK>
+0xA860	0x707C	# <CJK>
+0xA861	0x707D	# <CJK>
+0xA862	0x7078	# <CJK>
+0xA863	0x7262	# <CJK>
+0xA864	0x7261	# <CJK>
+0xA865	0x7260	# <CJK>
+0xA866	0x72C4	# <CJK>
+0xA867	0x72C2	# <CJK>
+0xA868	0x7396	# <CJK>
+0xA869	0x752C	# <CJK>
+0xA86A	0x752B	# <CJK>
+0xA86B	0x7537	# <CJK>
+0xA86C	0x7538	# <CJK>
+0xA86D	0x7682	# <CJK>
+0xA86E	0x76EF	# <CJK>
+0xA86F	0x77E3	# <CJK>
+0xA870	0x79C1	# <CJK>
+0xA871	0x79C0	# <CJK>
+0xA872	0x79BF	# <CJK>
+0xA873	0x7A76	# <CJK>
+0xA874	0x7CFB	# <CJK>
+0xA875	0x7F55	# <CJK>
+0xA876	0x8096	# <CJK>
+0xA877	0x8093	# <CJK>
+0xA878	0x809D	# <CJK>
+0xA879	0x8098	# <CJK>
+0xA87A	0x809B	# <CJK>
+0xA87B	0x809A	# <CJK>
+0xA87C	0x80B2	# <CJK>
+0xA87D	0x826F	# <CJK>
+0xA87E	0x8292	# <CJK>
+0xA8A1	0x828B	# <CJK>
+0xA8A2	0x828D	# <CJK>
+0xA8A3	0x898B	# <CJK>
+0xA8A4	0x89D2	# <CJK>
+0xA8A5	0x8A00	# <CJK>
+0xA8A6	0x8C37	# <CJK>
+0xA8A7	0x8C46	# <CJK>
+0xA8A8	0x8C55	# <CJK>
+0xA8A9	0x8C9D	# <CJK>
+0xA8AA	0x8D64	# <CJK>
+0xA8AB	0x8D70	# <CJK>
+0xA8AC	0x8DB3	# <CJK>
+0xA8AD	0x8EAB	# <CJK>
+0xA8AE	0x8ECA	# <CJK>
+0xA8AF	0x8F9B	# <CJK>
+0xA8B0	0x8FB0	# <CJK>
+0xA8B1	0x8FC2	# <CJK>
+0xA8B2	0x8FC6	# <CJK>
+0xA8B3	0x8FC5	# <CJK>
+0xA8B4	0x8FC4	# <CJK>
+0xA8B5	0x5DE1	# <CJK>
+0xA8B6	0x9091	# <CJK>
+0xA8B7	0x90A2	# <CJK>
+0xA8B8	0x90AA	# <CJK>
+0xA8B9	0x90A6	# <CJK>
+0xA8BA	0x90A3	# <CJK>
+0xA8BB	0x9149	# <CJK>
+0xA8BC	0x91C6	# <CJK>
+0xA8BD	0x91CC	# <CJK>
+0xA8BE	0x9632	# <CJK>
+0xA8BF	0x962E	# <CJK>
+0xA8C0	0x9631	# <CJK>
+0xA8C1	0x962A	# <CJK>
+0xA8C2	0x962C	# <CJK>
+0xA8C3	0x4E26	# <CJK>
+0xA8C4	0x4E56	# <CJK>
+0xA8C5	0x4E73	# <CJK>
+0xA8C6	0x4E8B	# <CJK>
+0xA8C7	0x4E9B	# <CJK>
+0xA8C8	0x4E9E	# <CJK>
+0xA8C9	0x4EAB	# <CJK>
+0xA8CA	0x4EAC	# <CJK>
+0xA8CB	0x4F6F	# <CJK>
+0xA8CC	0x4F9D	# <CJK>
+0xA8CD	0x4F8D	# <CJK>
+0xA8CE	0x4F73	# <CJK>
+0xA8CF	0x4F7F	# <CJK>
+0xA8D0	0x4F6C	# <CJK>
+0xA8D1	0x4F9B	# <CJK>
+0xA8D2	0x4F8B	# <CJK>
+0xA8D3	0x4F86	# <CJK>
+0xA8D4	0x4F83	# <CJK>
+0xA8D5	0x4F70	# <CJK>
+0xA8D6	0x4F75	# <CJK>
+0xA8D7	0x4F88	# <CJK>
+0xA8D8	0x4F69	# <CJK>
+0xA8D9	0x4F7B	# <CJK>
+0xA8DA	0x4F96	# <CJK>
+0xA8DB	0x4F7E	# <CJK>
+0xA8DC	0x4F8F	# <CJK>
+0xA8DD	0x4F91	# <CJK>
+0xA8DE	0x4F7A	# <CJK>
+0xA8DF	0x5154	# <CJK>
+0xA8E0	0x5152	# <CJK>
+0xA8E1	0x5155	# <CJK>
+0xA8E2	0x5169	# <CJK>
+0xA8E3	0x5177	# <CJK>
+0xA8E4	0x5176	# <CJK>
+0xA8E5	0x5178	# <CJK>
+0xA8E6	0x51BD	# <CJK>
+0xA8E7	0x51FD	# <CJK>
+0xA8E8	0x523B	# <CJK>
+0xA8E9	0x5238	# <CJK>
+0xA8EA	0x5237	# <CJK>
+0xA8EB	0x523A	# <CJK>
+0xA8EC	0x5230	# <CJK>
+0xA8ED	0x522E	# <CJK>
+0xA8EE	0x5236	# <CJK>
+0xA8EF	0x5241	# <CJK>
+0xA8F0	0x52BE	# <CJK>
+0xA8F1	0x52BB	# <CJK>
+0xA8F2	0x5352	# <CJK>
+0xA8F3	0x5354	# <CJK>
+0xA8F4	0x5353	# <CJK>
+0xA8F5	0x5351	# <CJK>
+0xA8F6	0x5366	# <CJK>
+0xA8F7	0x5377	# <CJK>
+0xA8F8	0x5378	# <CJK>
+0xA8F9	0x5379	# <CJK>
+0xA8FA	0x53D6	# <CJK>
+0xA8FB	0x53D4	# <CJK>
+0xA8FC	0x53D7	# <CJK>
+0xA8FD	0x5473	# <CJK>
+0xA8FE	0x5475	# <CJK>
+0xA940	0x5496	# <CJK>
+0xA941	0x5478	# <CJK>
+0xA942	0x5495	# <CJK>
+0xA943	0x5480	# <CJK>
+0xA944	0x547B	# <CJK>
+0xA945	0x5477	# <CJK>
+0xA946	0x5484	# <CJK>
+0xA947	0x5492	# <CJK>
+0xA948	0x5486	# <CJK>
+0xA949	0x547C	# <CJK>
+0xA94A	0x5490	# <CJK>
+0xA94B	0x5471	# <CJK>
+0xA94C	0x5476	# <CJK>
+0xA94D	0x548C	# <CJK>
+0xA94E	0x549A	# <CJK>
+0xA94F	0x5462	# <CJK>
+0xA950	0x5468	# <CJK>
+0xA951	0x548B	# <CJK>
+0xA952	0x547D	# <CJK>
+0xA953	0x548E	# <CJK>
+0xA954	0x56FA	# <CJK>
+0xA955	0x5783	# <CJK>
+0xA956	0x5777	# <CJK>
+0xA957	0x576A	# <CJK>
+0xA958	0x5769	# <CJK>
+0xA959	0x5761	# <CJK>
+0xA95A	0x5766	# <CJK>
+0xA95B	0x5764	# <CJK>
+0xA95C	0x577C	# <CJK>
+0xA95D	0x591C	# <CJK>
+0xA95E	0x5949	# <CJK>
+0xA95F	0x5947	# <CJK>
+0xA960	0x5948	# <CJK>
+0xA961	0x5944	# <CJK>
+0xA962	0x5954	# <CJK>
+0xA963	0x59BE	# <CJK>
+0xA964	0x59BB	# <CJK>
+0xA965	0x59D4	# <CJK>
+0xA966	0x59B9	# <CJK>
+0xA967	0x59AE	# <CJK>
+0xA968	0x59D1	# <CJK>
+0xA969	0x59C6	# <CJK>
+0xA96A	0x59D0	# <CJK>
+0xA96B	0x59CD	# <CJK>
+0xA96C	0x59CB	# <CJK>
+0xA96D	0x59D3	# <CJK>
+0xA96E	0x59CA	# <CJK>
+0xA96F	0x59AF	# <CJK>
+0xA970	0x59B3	# <CJK>
+0xA971	0x59D2	# <CJK>
+0xA972	0x59C5	# <CJK>
+0xA973	0x5B5F	# <CJK>
+0xA974	0x5B64	# <CJK>
+0xA975	0x5B63	# <CJK>
+0xA976	0x5B97	# <CJK>
+0xA977	0x5B9A	# <CJK>
+0xA978	0x5B98	# <CJK>
+0xA979	0x5B9C	# <CJK>
+0xA97A	0x5B99	# <CJK>
+0xA97B	0x5B9B	# <CJK>
+0xA97C	0x5C1A	# <CJK>
+0xA97D	0x5C48	# <CJK>
+0xA97E	0x5C45	# <CJK>
+0xA9A1	0x5C46	# <CJK>
+0xA9A2	0x5CB7	# <CJK>
+0xA9A3	0x5CA1	# <CJK>
+0xA9A4	0x5CB8	# <CJK>
+0xA9A5	0x5CA9	# <CJK>
+0xA9A6	0x5CAB	# <CJK>
+0xA9A7	0x5CB1	# <CJK>
+0xA9A8	0x5CB3	# <CJK>
+0xA9A9	0x5E18	# <CJK>
+0xA9AA	0x5E1A	# <CJK>
+0xA9AB	0x5E16	# <CJK>
+0xA9AC	0x5E15	# <CJK>
+0xA9AD	0x5E1B	# <CJK>
+0xA9AE	0x5E11	# <CJK>
+0xA9AF	0x5E78	# <CJK>
+0xA9B0	0x5E9A	# <CJK>
+0xA9B1	0x5E97	# <CJK>
+0xA9B2	0x5E9C	# <CJK>
+0xA9B3	0x5E95	# <CJK>
+0xA9B4	0x5E96	# <CJK>
+0xA9B5	0x5EF6	# <CJK>
+0xA9B6	0x5F26	# <CJK>
+0xA9B7	0x5F27	# <CJK>
+0xA9B8	0x5F29	# <CJK>
+0xA9B9	0x5F80	# <CJK>
+0xA9BA	0x5F81	# <CJK>
+0xA9BB	0x5F7F	# <CJK>
+0xA9BC	0x5F7C	# <CJK>
+0xA9BD	0x5FDD	# <CJK>
+0xA9BE	0x5FE0	# <CJK>
+0xA9BF	0x5FFD	# <CJK>
+0xA9C0	0x5FF5	# <CJK>
+0xA9C1	0x5FFF	# <CJK>
+0xA9C2	0x600F	# <CJK>
+0xA9C3	0x6014	# <CJK>
+0xA9C4	0x602F	# <CJK>
+0xA9C5	0x6035	# <CJK>
+0xA9C6	0x6016	# <CJK>
+0xA9C7	0x602A	# <CJK>
+0xA9C8	0x6015	# <CJK>
+0xA9C9	0x6021	# <CJK>
+0xA9CA	0x6027	# <CJK>
+0xA9CB	0x6029	# <CJK>
+0xA9CC	0x602B	# <CJK>
+0xA9CD	0x601B	# <CJK>
+0xA9CE	0x6216	# <CJK>
+0xA9CF	0x6215	# <CJK>
+0xA9D0	0x623F	# <CJK>
+0xA9D1	0x623E	# <CJK>
+0xA9D2	0x6240	# <CJK>
+0xA9D3	0x627F	# <CJK>
+0xA9D4	0x62C9	# <CJK>
+0xA9D5	0x62CC	# <CJK>
+0xA9D6	0x62C4	# <CJK>
+0xA9D7	0x62BF	# <CJK>
+0xA9D8	0x62C2	# <CJK>
+0xA9D9	0x62B9	# <CJK>
+0xA9DA	0x62D2	# <CJK>
+0xA9DB	0x62DB	# <CJK>
+0xA9DC	0x62AB	# <CJK>
+0xA9DD	0x62D3	# <CJK>
+0xA9DE	0x62D4	# <CJK>
+0xA9DF	0x62CB	# <CJK>
+0xA9E0	0x62C8	# <CJK>
+0xA9E1	0x62A8	# <CJK>
+0xA9E2	0x62BD	# <CJK>
+0xA9E3	0x62BC	# <CJK>
+0xA9E4	0x62D0	# <CJK>
+0xA9E5	0x62D9	# <CJK>
+0xA9E6	0x62C7	# <CJK>
+0xA9E7	0x62CD	# <CJK>
+0xA9E8	0x62B5	# <CJK>
+0xA9E9	0x62DA	# <CJK>
+0xA9EA	0x62B1	# <CJK>
+0xA9EB	0x62D8	# <CJK>
+0xA9EC	0x62D6	# <CJK>
+0xA9ED	0x62D7	# <CJK>
+0xA9EE	0x62C6	# <CJK>
+0xA9EF	0x62AC	# <CJK>
+0xA9F0	0x62CE	# <CJK>
+0xA9F1	0x653E	# <CJK>
+0xA9F2	0x65A7	# <CJK>
+0xA9F3	0x65BC	# <CJK>
+0xA9F4	0x65FA	# <CJK>
+0xA9F5	0x6614	# <CJK>
+0xA9F6	0x6613	# <CJK>
+0xA9F7	0x660C	# <CJK>
+0xA9F8	0x6606	# <CJK>
+0xA9F9	0x6602	# <CJK>
+0xA9FA	0x660E	# <CJK>
+0xA9FB	0x6600	# <CJK>
+0xA9FC	0x660F	# <CJK>
+0xA9FD	0x6615	# <CJK>
+0xA9FE	0x660A	# <CJK>
+0xAA40	0x6607	# <CJK>
+0xAA41	0x670D	# <CJK>
+0xAA42	0x670B	# <CJK>
+0xAA43	0x676D	# <CJK>
+0xAA44	0x678B	# <CJK>
+0xAA45	0x6795	# <CJK>
+0xAA46	0x6771	# <CJK>
+0xAA47	0x679C	# <CJK>
+0xAA48	0x6773	# <CJK>
+0xAA49	0x6777	# <CJK>
+0xAA4A	0x6787	# <CJK>
+0xAA4B	0x679D	# <CJK>
+0xAA4C	0x6797	# <CJK>
+0xAA4D	0x676F	# <CJK>
+0xAA4E	0x6770	# <CJK>
+0xAA4F	0x677F	# <CJK>
+0xAA50	0x6789	# <CJK>
+0xAA51	0x677E	# <CJK>
+0xAA52	0x6790	# <CJK>
+0xAA53	0x6775	# <CJK>
+0xAA54	0x679A	# <CJK>
+0xAA55	0x6793	# <CJK>
+0xAA56	0x677C	# <CJK>
+0xAA57	0x676A	# <CJK>
+0xAA58	0x6772	# <CJK>
+0xAA59	0x6B23	# <CJK>
+0xAA5A	0x6B66	# <CJK>
+0xAA5B	0x6B67	# <CJK>
+0xAA5C	0x6B7F	# <CJK>
+0xAA5D	0x6C13	# <CJK>
+0xAA5E	0x6C1B	# <CJK>
+0xAA5F	0x6CE3	# <CJK>
+0xAA60	0x6CE8	# <CJK>
+0xAA61	0x6CF3	# <CJK>
+0xAA62	0x6CB1	# <CJK>
+0xAA63	0x6CCC	# <CJK>
+0xAA64	0x6CE5	# <CJK>
+0xAA65	0x6CB3	# <CJK>
+0xAA66	0x6CBD	# <CJK>
+0xAA67	0x6CBE	# <CJK>
+0xAA68	0x6CBC	# <CJK>
+0xAA69	0x6CE2	# <CJK>
+0xAA6A	0x6CAB	# <CJK>
+0xAA6B	0x6CD5	# <CJK>
+0xAA6C	0x6CD3	# <CJK>
+0xAA6D	0x6CB8	# <CJK>
+0xAA6E	0x6CC4	# <CJK>
+0xAA6F	0x6CB9	# <CJK>
+0xAA70	0x6CC1	# <CJK>
+0xAA71	0x6CAE	# <CJK>
+0xAA72	0x6CD7	# <CJK>
+0xAA73	0x6CC5	# <CJK>
+0xAA74	0x6CF1	# <CJK>
+0xAA75	0x6CBF	# <CJK>
+0xAA76	0x6CBB	# <CJK>
+0xAA77	0x6CE1	# <CJK>
+0xAA78	0x6CDB	# <CJK>
+0xAA79	0x6CCA	# <CJK>
+0xAA7A	0x6CAC	# <CJK>
+0xAA7B	0x6CEF	# <CJK>
+0xAA7C	0x6CDC	# <CJK>
+0xAA7D	0x6CD6	# <CJK>
+0xAA7E	0x6CE0	# <CJK>
+0xAAA1	0x7095	# <CJK>
+0xAAA2	0x708E	# <CJK>
+0xAAA3	0x7092	# <CJK>
+0xAAA4	0x708A	# <CJK>
+0xAAA5	0x7099	# <CJK>
+0xAAA6	0x722C	# <CJK>
+0xAAA7	0x722D	# <CJK>
+0xAAA8	0x7238	# <CJK>
+0xAAA9	0x7248	# <CJK>
+0xAAAA	0x7267	# <CJK>
+0xAAAB	0x7269	# <CJK>
+0xAAAC	0x72C0	# <CJK>
+0xAAAD	0x72CE	# <CJK>
+0xAAAE	0x72D9	# <CJK>
+0xAAAF	0x72D7	# <CJK>
+0xAAB0	0x72D0	# <CJK>
+0xAAB1	0x73A9	# <CJK>
+0xAAB2	0x73A8	# <CJK>
+0xAAB3	0x739F	# <CJK>
+0xAAB4	0x73AB	# <CJK>
+0xAAB5	0x73A5	# <CJK>
+0xAAB6	0x753D	# <CJK>
+0xAAB7	0x759D	# <CJK>
+0xAAB8	0x7599	# <CJK>
+0xAAB9	0x759A	# <CJK>
+0xAABA	0x7684	# <CJK>
+0xAABB	0x76C2	# <CJK>
+0xAABC	0x76F2	# <CJK>
+0xAABD	0x76F4	# <CJK>
+0xAABE	0x77E5	# <CJK>
+0xAABF	0x77FD	# <CJK>
+0xAAC0	0x793E	# <CJK>
+0xAAC1	0x7940	# <CJK>
+0xAAC2	0x7941	# <CJK>
+0xAAC3	0x79C9	# <CJK>
+0xAAC4	0x79C8	# <CJK>
+0xAAC5	0x7A7A	# <CJK>
+0xAAC6	0x7A79	# <CJK>
+0xAAC7	0x7AFA	# <CJK>
+0xAAC8	0x7CFE	# <CJK>
+0xAAC9	0x7F54	# <CJK>
+0xAACA	0x7F8C	# <CJK>
+0xAACB	0x7F8B	# <CJK>
+0xAACC	0x8005	# <CJK>
+0xAACD	0x80BA	# <CJK>
+0xAACE	0x80A5	# <CJK>
+0xAACF	0x80A2	# <CJK>
+0xAAD0	0x80B1	# <CJK>
+0xAAD1	0x80A1	# <CJK>
+0xAAD2	0x80AB	# <CJK>
+0xAAD3	0x80A9	# <CJK>
+0xAAD4	0x80B4	# <CJK>
+0xAAD5	0x80AA	# <CJK>
+0xAAD6	0x80AF	# <CJK>
+0xAAD7	0x81E5	# <CJK>
+0xAAD8	0x81FE	# <CJK>
+0xAAD9	0x820D	# <CJK>
+0xAADA	0x82B3	# <CJK>
+0xAADB	0x829D	# <CJK>
+0xAADC	0x8299	# <CJK>
+0xAADD	0x82AD	# <CJK>
+0xAADE	0x82BD	# <CJK>
+0xAADF	0x829F	# <CJK>
+0xAAE0	0x82B9	# <CJK>
+0xAAE1	0x82B1	# <CJK>
+0xAAE2	0x82AC	# <CJK>
+0xAAE3	0x82A5	# <CJK>
+0xAAE4	0x82AF	# <CJK>
+0xAAE5	0x82B8	# <CJK>
+0xAAE6	0x82A3	# <CJK>
+0xAAE7	0x82B0	# <CJK>
+0xAAE8	0x82BE	# <CJK>
+0xAAE9	0x82B7	# <CJK>
+0xAAEA	0x864E	# <CJK>
+0xAAEB	0x8671	# <CJK>
+0xAAEC	0x521D	# <CJK>
+0xAAED	0x8868	# <CJK>
+0xAAEE	0x8ECB	# <CJK>
+0xAAEF	0x8FCE	# <CJK>
+0xAAF0	0x8FD4	# <CJK>
+0xAAF1	0x8FD1	# <CJK>
+0xAAF2	0x90B5	# <CJK>
+0xAAF3	0x90B8	# <CJK>
+0xAAF4	0x90B1	# <CJK>
+0xAAF5	0x90B6	# <CJK>
+0xAAF6	0x91C7	# <CJK>
+0xAAF7	0x91D1	# <CJK>
+0xAAF8	0x9577	# <CJK>
+0xAAF9	0x9580	# <CJK>
+0xAAFA	0x961C	# <CJK>
+0xAAFB	0x9640	# <CJK>
+0xAAFC	0x963F	# <CJK>
+0xAAFD	0x963B	# <CJK>
+0xAAFE	0x9644	# <CJK>
+0xAB40	0x9642	# <CJK>
+0xAB41	0x96B9	# <CJK>
+0xAB42	0x96E8	# <CJK>
+0xAB43	0x9752	# <CJK>
+0xAB44	0x975E	# <CJK>
+0xAB45	0x4E9F	# <CJK>
+0xAB46	0x4EAD	# <CJK>
+0xAB47	0x4EAE	# <CJK>
+0xAB48	0x4FE1	# <CJK>
+0xAB49	0x4FB5	# <CJK>
+0xAB4A	0x4FAF	# <CJK>
+0xAB4B	0x4FBF	# <CJK>
+0xAB4C	0x4FE0	# <CJK>
+0xAB4D	0x4FD1	# <CJK>
+0xAB4E	0x4FCF	# <CJK>
+0xAB4F	0x4FDD	# <CJK>
+0xAB50	0x4FC3	# <CJK>
+0xAB51	0x4FB6	# <CJK>
+0xAB52	0x4FD8	# <CJK>
+0xAB53	0x4FDF	# <CJK>
+0xAB54	0x4FCA	# <CJK>
+0xAB55	0x4FD7	# <CJK>
+0xAB56	0x4FAE	# <CJK>
+0xAB57	0x4FD0	# <CJK>
+0xAB58	0x4FC4	# <CJK>
+0xAB59	0x4FC2	# <CJK>
+0xAB5A	0x4FDA	# <CJK>
+0xAB5B	0x4FCE	# <CJK>
+0xAB5C	0x4FDE	# <CJK>
+0xAB5D	0x4FB7	# <CJK>
+0xAB5E	0x5157	# <CJK>
+0xAB5F	0x5192	# <CJK>
+0xAB60	0x5191	# <CJK>
+0xAB61	0x51A0	# <CJK>
+0xAB62	0x524E	# <CJK>
+0xAB63	0x5243	# <CJK>
+0xAB64	0x524A	# <CJK>
+0xAB65	0x524D	# <CJK>
+0xAB66	0x524C	# <CJK>
+0xAB67	0x524B	# <CJK>
+0xAB68	0x5247	# <CJK>
+0xAB69	0x52C7	# <CJK>
+0xAB6A	0x52C9	# <CJK>
+0xAB6B	0x52C3	# <CJK>
+0xAB6C	0x52C1	# <CJK>
+0xAB6D	0x530D	# <CJK>
+0xAB6E	0x5357	# <CJK>
+0xAB6F	0x537B	# <CJK>
+0xAB70	0x539A	# <CJK>
+0xAB71	0x53DB	# <CJK>
+0xAB72	0x54AC	# <CJK>
+0xAB73	0x54C0	# <CJK>
+0xAB74	0x54A8	# <CJK>
+0xAB75	0x54CE	# <CJK>
+0xAB76	0x54C9	# <CJK>
+0xAB77	0x54B8	# <CJK>
+0xAB78	0x54A6	# <CJK>
+0xAB79	0x54B3	# <CJK>
+0xAB7A	0x54C7	# <CJK>
+0xAB7B	0x54C2	# <CJK>
+0xAB7C	0x54BD	# <CJK>
+0xAB7D	0x54AA	# <CJK>
+0xAB7E	0x54C1	# <CJK>
+0xABA1	0x54C4	# <CJK>
+0xABA2	0x54C8	# <CJK>
+0xABA3	0x54AF	# <CJK>
+0xABA4	0x54AB	# <CJK>
+0xABA5	0x54B1	# <CJK>
+0xABA6	0x54BB	# <CJK>
+0xABA7	0x54A9	# <CJK>
+0xABA8	0x54A7	# <CJK>
+0xABA9	0x54BF	# <CJK>
+0xABAA	0x56FF	# <CJK>
+0xABAB	0x5782	# <CJK>
+0xABAC	0x578B	# <CJK>
+0xABAD	0x57A0	# <CJK>
+0xABAE	0x57A3	# <CJK>
+0xABAF	0x57A2	# <CJK>
+0xABB0	0x57CE	# <CJK>
+0xABB1	0x57AE	# <CJK>
+0xABB2	0x5793	# <CJK>
+0xABB3	0x5955	# <CJK>
+0xABB4	0x5951	# <CJK>
+0xABB5	0x594F	# <CJK>
+0xABB6	0x594E	# <CJK>
+0xABB7	0x5950	# <CJK>
+0xABB8	0x59DC	# <CJK>
+0xABB9	0x59D8	# <CJK>
+0xABBA	0x59FF	# <CJK>
+0xABBB	0x59E3	# <CJK>
+0xABBC	0x59E8	# <CJK>
+0xABBD	0x5A03	# <CJK>
+0xABBE	0x59E5	# <CJK>
+0xABBF	0x59EA	# <CJK>
+0xABC0	0x59DA	# <CJK>
+0xABC1	0x59E6	# <CJK>
+0xABC2	0x5A01	# <CJK>
+0xABC3	0x59FB	# <CJK>
+0xABC4	0x5B69	# <CJK>
+0xABC5	0x5BA3	# <CJK>
+0xABC6	0x5BA6	# <CJK>
+0xABC7	0x5BA4	# <CJK>
+0xABC8	0x5BA2	# <CJK>
+0xABC9	0x5BA5	# <CJK>
+0xABCA	0x5C01	# <CJK>
+0xABCB	0x5C4E	# <CJK>
+0xABCC	0x5C4F	# <CJK>
+0xABCD	0x5C4D	# <CJK>
+0xABCE	0x5C4B	# <CJK>
+0xABCF	0x5CD9	# <CJK>
+0xABD0	0x5CD2	# <CJK>
+0xABD1	0x5DF7	# <CJK>
+0xABD2	0x5E1D	# <CJK>
+0xABD3	0x5E25	# <CJK>
+0xABD4	0x5E1F	# <CJK>
+0xABD5	0x5E7D	# <CJK>
+0xABD6	0x5EA0	# <CJK>
+0xABD7	0x5EA6	# <CJK>
+0xABD8	0x5EFA	# <CJK>
+0xABD9	0x5F08	# <CJK>
+0xABDA	0x5F2D	# <CJK>
+0xABDB	0x5F65	# <CJK>
+0xABDC	0x5F88	# <CJK>
+0xABDD	0x5F85	# <CJK>
+0xABDE	0x5F8A	# <CJK>
+0xABDF	0x5F8B	# <CJK>
+0xABE0	0x5F87	# <CJK>
+0xABE1	0x5F8C	# <CJK>
+0xABE2	0x5F89	# <CJK>
+0xABE3	0x6012	# <CJK>
+0xABE4	0x601D	# <CJK>
+0xABE5	0x6020	# <CJK>
+0xABE6	0x6025	# <CJK>
+0xABE7	0x600E	# <CJK>
+0xABE8	0x6028	# <CJK>
+0xABE9	0x604D	# <CJK>
+0xABEA	0x6070	# <CJK>
+0xABEB	0x6068	# <CJK>
+0xABEC	0x6062	# <CJK>
+0xABED	0x6046	# <CJK>
+0xABEE	0x6043	# <CJK>
+0xABEF	0x606C	# <CJK>
+0xABF0	0x606B	# <CJK>
+0xABF1	0x606A	# <CJK>
+0xABF2	0x6064	# <CJK>
+0xABF3	0x6241	# <CJK>
+0xABF4	0x62DC	# <CJK>
+0xABF5	0x6316	# <CJK>
+0xABF6	0x6309	# <CJK>
+0xABF7	0x62FC	# <CJK>
+0xABF8	0x62ED	# <CJK>
+0xABF9	0x6301	# <CJK>
+0xABFA	0x62EE	# <CJK>
+0xABFB	0x62FD	# <CJK>
+0xABFC	0x6307	# <CJK>
+0xABFD	0x62F1	# <CJK>
+0xABFE	0x62F7	# <CJK>
+0xAC40	0x62EF	# <CJK>
+0xAC41	0x62EC	# <CJK>
+0xAC42	0x62FE	# <CJK>
+0xAC43	0x62F4	# <CJK>
+0xAC44	0x6311	# <CJK>
+0xAC45	0x6302	# <CJK>
+0xAC46	0x653F	# <CJK>
+0xAC47	0x6545	# <CJK>
+0xAC48	0x65AB	# <CJK>
+0xAC49	0x65BD	# <CJK>
+0xAC4A	0x65E2	# <CJK>
+0xAC4B	0x6625	# <CJK>
+0xAC4C	0x662D	# <CJK>
+0xAC4D	0x6620	# <CJK>
+0xAC4E	0x6627	# <CJK>
+0xAC4F	0x662F	# <CJK>
+0xAC50	0x661F	# <CJK>
+0xAC51	0x6628	# <CJK>
+0xAC52	0x6631	# <CJK>
+0xAC53	0x6624	# <CJK>
+0xAC54	0x66F7	# <CJK>
+0xAC55	0x67FF	# <CJK>
+0xAC56	0x67D3	# <CJK>
+0xAC57	0x67F1	# <CJK>
+0xAC58	0x67D4	# <CJK>
+0xAC59	0x67D0	# <CJK>
+0xAC5A	0x67EC	# <CJK>
+0xAC5B	0x67B6	# <CJK>
+0xAC5C	0x67AF	# <CJK>
+0xAC5D	0x67F5	# <CJK>
+0xAC5E	0x67E9	# <CJK>
+0xAC5F	0x67EF	# <CJK>
+0xAC60	0x67C4	# <CJK>
+0xAC61	0x67D1	# <CJK>
+0xAC62	0x67B4	# <CJK>
+0xAC63	0x67DA	# <CJK>
+0xAC64	0x67E5	# <CJK>
+0xAC65	0x67B8	# <CJK>
+0xAC66	0x67CF	# <CJK>
+0xAC67	0x67DE	# <CJK>
+0xAC68	0x67F3	# <CJK>
+0xAC69	0x67B0	# <CJK>
+0xAC6A	0x67D9	# <CJK>
+0xAC6B	0x67E2	# <CJK>
+0xAC6C	0x67DD	# <CJK>
+0xAC6D	0x67D2	# <CJK>
+0xAC6E	0x6B6A	# <CJK>
+0xAC6F	0x6B83	# <CJK>
+0xAC70	0x6B86	# <CJK>
+0xAC71	0x6BB5	# <CJK>
+0xAC72	0x6BD2	# <CJK>
+0xAC73	0x6BD7	# <CJK>
+0xAC74	0x6C1F	# <CJK>
+0xAC75	0x6CC9	# <CJK>
+0xAC76	0x6D0B	# <CJK>
+0xAC77	0x6D32	# <CJK>
+0xAC78	0x6D2A	# <CJK>
+0xAC79	0x6D41	# <CJK>
+0xAC7A	0x6D25	# <CJK>
+0xAC7B	0x6D0C	# <CJK>
+0xAC7C	0x6D31	# <CJK>
+0xAC7D	0x6D1E	# <CJK>
+0xAC7E	0x6D17	# <CJK>
+0xACA1	0x6D3B	# <CJK>
+0xACA2	0x6D3D	# <CJK>
+0xACA3	0x6D3E	# <CJK>
+0xACA4	0x6D36	# <CJK>
+0xACA5	0x6D1B	# <CJK>
+0xACA6	0x6CF5	# <CJK>
+0xACA7	0x6D39	# <CJK>
+0xACA8	0x6D27	# <CJK>
+0xACA9	0x6D38	# <CJK>
+0xACAA	0x6D29	# <CJK>
+0xACAB	0x6D2E	# <CJK>
+0xACAC	0x6D35	# <CJK>
+0xACAD	0x6D0E	# <CJK>
+0xACAE	0x6D2B	# <CJK>
+0xACAF	0x70AB	# <CJK>
+0xACB0	0x70BA	# <CJK>
+0xACB1	0x70B3	# <CJK>
+0xACB2	0x70AC	# <CJK>
+0xACB3	0x70AF	# <CJK>
+0xACB4	0x70AD	# <CJK>
+0xACB5	0x70B8	# <CJK>
+0xACB6	0x70AE	# <CJK>
+0xACB7	0x70A4	# <CJK>
+0xACB8	0x7230	# <CJK>
+0xACB9	0x7272	# <CJK>
+0xACBA	0x726F	# <CJK>
+0xACBB	0x7274	# <CJK>
+0xACBC	0x72E9	# <CJK>
+0xACBD	0x72E0	# <CJK>
+0xACBE	0x72E1	# <CJK>
+0xACBF	0x73B7	# <CJK>
+0xACC0	0x73CA	# <CJK>
+0xACC1	0x73BB	# <CJK>
+0xACC2	0x73B2	# <CJK>
+0xACC3	0x73CD	# <CJK>
+0xACC4	0x73C0	# <CJK>
+0xACC5	0x73B3	# <CJK>
+0xACC6	0x751A	# <CJK>
+0xACC7	0x752D	# <CJK>
+0xACC8	0x754F	# <CJK>
+0xACC9	0x754C	# <CJK>
+0xACCA	0x754E	# <CJK>
+0xACCB	0x754B	# <CJK>
+0xACCC	0x75AB	# <CJK>
+0xACCD	0x75A4	# <CJK>
+0xACCE	0x75A5	# <CJK>
+0xACCF	0x75A2	# <CJK>
+0xACD0	0x75A3	# <CJK>
+0xACD1	0x7678	# <CJK>
+0xACD2	0x7686	# <CJK>
+0xACD3	0x7687	# <CJK>
+0xACD4	0x7688	# <CJK>
+0xACD5	0x76C8	# <CJK>
+0xACD6	0x76C6	# <CJK>
+0xACD7	0x76C3	# <CJK>
+0xACD8	0x76C5	# <CJK>
+0xACD9	0x7701	# <CJK>
+0xACDA	0x76F9	# <CJK>
+0xACDB	0x76F8	# <CJK>
+0xACDC	0x7709	# <CJK>
+0xACDD	0x770B	# <CJK>
+0xACDE	0x76FE	# <CJK>
+0xACDF	0x76FC	# <CJK>
+0xACE0	0x7707	# <CJK>
+0xACE1	0x77DC	# <CJK>
+0xACE2	0x7802	# <CJK>
+0xACE3	0x7814	# <CJK>
+0xACE4	0x780C	# <CJK>
+0xACE5	0x780D	# <CJK>
+0xACE6	0x7946	# <CJK>
+0xACE7	0x7949	# <CJK>
+0xACE8	0x7948	# <CJK>
+0xACE9	0x7947	# <CJK>
+0xACEA	0x79B9	# <CJK>
+0xACEB	0x79BA	# <CJK>
+0xACEC	0x79D1	# <CJK>
+0xACED	0x79D2	# <CJK>
+0xACEE	0x79CB	# <CJK>
+0xACEF	0x7A7F	# <CJK>
+0xACF0	0x7A81	# <CJK>
+0xACF1	0x7AFF	# <CJK>
+0xACF2	0x7AFD	# <CJK>
+0xACF3	0x7C7D	# <CJK>
+0xACF4	0x7D02	# <CJK>
+0xACF5	0x7D05	# <CJK>
+0xACF6	0x7D00	# <CJK>
+0xACF7	0x7D09	# <CJK>
+0xACF8	0x7D07	# <CJK>
+0xACF9	0x7D04	# <CJK>
+0xACFA	0x7D06	# <CJK>
+0xACFB	0x7F38	# <CJK>
+0xACFC	0x7F8E	# <CJK>
+0xACFD	0x7FBF	# <CJK>
+0xACFE	0x8004	# <CJK>
+0xAD40	0x8010	# <CJK>
+0xAD41	0x800D	# <CJK>
+0xAD42	0x8011	# <CJK>
+0xAD43	0x8036	# <CJK>
+0xAD44	0x80D6	# <CJK>
+0xAD45	0x80E5	# <CJK>
+0xAD46	0x80DA	# <CJK>
+0xAD47	0x80C3	# <CJK>
+0xAD48	0x80C4	# <CJK>
+0xAD49	0x80CC	# <CJK>
+0xAD4A	0x80E1	# <CJK>
+0xAD4B	0x80DB	# <CJK>
+0xAD4C	0x80CE	# <CJK>
+0xAD4D	0x80DE	# <CJK>
+0xAD4E	0x80E4	# <CJK>
+0xAD4F	0x80DD	# <CJK>
+0xAD50	0x81F4	# <CJK>
+0xAD51	0x8222	# <CJK>
+0xAD52	0x82E7	# <CJK>
+0xAD53	0x8303	# <CJK>
+0xAD54	0x8305	# <CJK>
+0xAD55	0x82E3	# <CJK>
+0xAD56	0x82DB	# <CJK>
+0xAD57	0x82E6	# <CJK>
+0xAD58	0x8304	# <CJK>
+0xAD59	0x82E5	# <CJK>
+0xAD5A	0x8302	# <CJK>
+0xAD5B	0x8309	# <CJK>
+0xAD5C	0x82D2	# <CJK>
+0xAD5D	0x82D7	# <CJK>
+0xAD5E	0x82F1	# <CJK>
+0xAD5F	0x8301	# <CJK>
+0xAD60	0x82DC	# <CJK>
+0xAD61	0x82D4	# <CJK>
+0xAD62	0x82D1	# <CJK>
+0xAD63	0x82DE	# <CJK>
+0xAD64	0x82D3	# <CJK>
+0xAD65	0x82DF	# <CJK>
+0xAD66	0x82EF	# <CJK>
+0xAD67	0x8306	# <CJK>
+0xAD68	0x8650	# <CJK>
+0xAD69	0x8679	# <CJK>
+0xAD6A	0x867B	# <CJK>
+0xAD6B	0x867A	# <CJK>
+0xAD6C	0x884D	# <CJK>
+0xAD6D	0x886B	# <CJK>
+0xAD6E	0x8981	# <CJK>
+0xAD6F	0x89D4	# <CJK>
+0xAD70	0x8A08	# <CJK>
+0xAD71	0x8A02	# <CJK>
+0xAD72	0x8A03	# <CJK>
+0xAD73	0x8C9E	# <CJK>
+0xAD74	0x8CA0	# <CJK>
+0xAD75	0x8D74	# <CJK>
+0xAD76	0x8D73	# <CJK>
+0xAD77	0x8DB4	# <CJK>
+0xAD78	0x8ECD	# <CJK>
+0xAD79	0x8ECC	# <CJK>
+0xAD7A	0x8FF0	# <CJK>
+0xAD7B	0x8FE6	# <CJK>
+0xAD7C	0x8FE2	# <CJK>
+0xAD7D	0x8FEA	# <CJK>
+0xAD7E	0x8FE5	# <CJK>
+0xADA1	0x8FED	# <CJK>
+0xADA2	0x8FEB	# <CJK>
+0xADA3	0x8FE4	# <CJK>
+0xADA4	0x8FE8	# <CJK>
+0xADA5	0x90CA	# <CJK>
+0xADA6	0x90CE	# <CJK>
+0xADA7	0x90C1	# <CJK>
+0xADA8	0x90C3	# <CJK>
+0xADA9	0x914B	# <CJK>
+0xADAA	0x914A	# <CJK>
+0xADAB	0x91CD	# <CJK>
+0xADAC	0x9582	# <CJK>
+0xADAD	0x9650	# <CJK>
+0xADAE	0x964B	# <CJK>
+0xADAF	0x964C	# <CJK>
+0xADB0	0x964D	# <CJK>
+0xADB1	0x9762	# <CJK>
+0xADB2	0x9769	# <CJK>
+0xADB3	0x97CB	# <CJK>
+0xADB4	0x97ED	# <CJK>
+0xADB5	0x97F3	# <CJK>
+0xADB6	0x9801	# <CJK>
+0xADB7	0x98A8	# <CJK>
+0xADB8	0x98DB	# <CJK>
+0xADB9	0x98DF	# <CJK>
+0xADBA	0x9996	# <CJK>
+0xADBB	0x9999	# <CJK>
+0xADBC	0x4E58	# <CJK>
+0xADBD	0x4EB3	# <CJK>
+0xADBE	0x500C	# <CJK>
+0xADBF	0x500D	# <CJK>
+0xADC0	0x5023	# <CJK>
+0xADC1	0x4FEF	# <CJK>
+0xADC2	0x5026	# <CJK>
+0xADC3	0x5025	# <CJK>
+0xADC4	0x4FF8	# <CJK>
+0xADC5	0x5029	# <CJK>
+0xADC6	0x5016	# <CJK>
+0xADC7	0x5006	# <CJK>
+0xADC8	0x503C	# <CJK>
+0xADC9	0x501F	# <CJK>
+0xADCA	0x501A	# <CJK>
+0xADCB	0x5012	# <CJK>
+0xADCC	0x5011	# <CJK>
+0xADCD	0x4FFA	# <CJK>
+0xADCE	0x5000	# <CJK>
+0xADCF	0x5014	# <CJK>
+0xADD0	0x5028	# <CJK>
+0xADD1	0x4FF1	# <CJK>
+0xADD2	0x5021	# <CJK>
+0xADD3	0x500B	# <CJK>
+0xADD4	0x5019	# <CJK>
+0xADD5	0x5018	# <CJK>
+0xADD6	0x4FF3	# <CJK>
+0xADD7	0x4FEE	# <CJK>
+0xADD8	0x502D	# <CJK>
+0xADD9	0x502A	# <CJK>
+0xADDA	0x4FFE	# <CJK>
+0xADDB	0x502B	# <CJK>
+0xADDC	0x5009	# <CJK>
+0xADDD	0x517C	# <CJK>
+0xADDE	0x51A4	# <CJK>
+0xADDF	0x51A5	# <CJK>
+0xADE0	0x51A2	# <CJK>
+0xADE1	0x51CD	# <CJK>
+0xADE2	0x51CC	# <CJK>
+0xADE3	0x51C6	# <CJK>
+0xADE4	0x51CB	# <CJK>
+0xADE5	0x5256	# <CJK>
+0xADE6	0x525C	# <CJK>
+0xADE7	0x5254	# <CJK>
+0xADE8	0x525B	# <CJK>
+0xADE9	0x525D	# <CJK>
+0xADEA	0x532A	# <CJK>
+0xADEB	0x537F	# <CJK>
+0xADEC	0x539F	# <CJK>
+0xADED	0x539D	# <CJK>
+0xADEE	0x53DF	# <CJK>
+0xADEF	0x54E8	# <CJK>
+0xADF0	0x5510	# <CJK>
+0xADF1	0x5501	# <CJK>
+0xADF2	0x5537	# <CJK>
+0xADF3	0x54FC	# <CJK>
+0xADF4	0x54E5	# <CJK>
+0xADF5	0x54F2	# <CJK>
+0xADF6	0x5506	# <CJK>
+0xADF7	0x54FA	# <CJK>
+0xADF8	0x5514	# <CJK>
+0xADF9	0x54E9	# <CJK>
+0xADFA	0x54ED	# <CJK>
+0xADFB	0x54E1	# <CJK>
+0xADFC	0x5509	# <CJK>
+0xADFD	0x54EE	# <CJK>
+0xADFE	0x54EA	# <CJK>
+0xAE40	0x54E6	# <CJK>
+0xAE41	0x5527	# <CJK>
+0xAE42	0x5507	# <CJK>
+0xAE43	0x54FD	# <CJK>
+0xAE44	0x550F	# <CJK>
+0xAE45	0x5703	# <CJK>
+0xAE46	0x5704	# <CJK>
+0xAE47	0x57C2	# <CJK>
+0xAE48	0x57D4	# <CJK>
+0xAE49	0x57CB	# <CJK>
+0xAE4A	0x57C3	# <CJK>
+0xAE4B	0x5809	# <CJK>
+0xAE4C	0x590F	# <CJK>
+0xAE4D	0x5957	# <CJK>
+0xAE4E	0x5958	# <CJK>
+0xAE4F	0x595A	# <CJK>
+0xAE50	0x5A11	# <CJK>
+0xAE51	0x5A18	# <CJK>
+0xAE52	0x5A1C	# <CJK>
+0xAE53	0x5A1F	# <CJK>
+0xAE54	0x5A1B	# <CJK>
+0xAE55	0x5A13	# <CJK>
+0xAE56	0x59EC	# <CJK>
+0xAE57	0x5A20	# <CJK>
+0xAE58	0x5A23	# <CJK>
+0xAE59	0x5A29	# <CJK>
+0xAE5A	0x5A25	# <CJK>
+0xAE5B	0x5A0C	# <CJK>
+0xAE5C	0x5A09	# <CJK>
+0xAE5D	0x5B6B	# <CJK>
+0xAE5E	0x5C58	# <CJK>
+0xAE5F	0x5BB0	# <CJK>
+0xAE60	0x5BB3	# <CJK>
+0xAE61	0x5BB6	# <CJK>
+0xAE62	0x5BB4	# <CJK>
+0xAE63	0x5BAE	# <CJK>
+0xAE64	0x5BB5	# <CJK>
+0xAE65	0x5BB9	# <CJK>
+0xAE66	0x5BB8	# <CJK>
+0xAE67	0x5C04	# <CJK>
+0xAE68	0x5C51	# <CJK>
+0xAE69	0x5C55	# <CJK>
+0xAE6A	0x5C50	# <CJK>
+0xAE6B	0x5CED	# <CJK>
+0xAE6C	0x5CFD	# <CJK>
+0xAE6D	0x5CFB	# <CJK>
+0xAE6E	0x5CEA	# <CJK>
+0xAE6F	0x5CE8	# <CJK>
+0xAE70	0x5CF0	# <CJK>
+0xAE71	0x5CF6	# <CJK>
+0xAE72	0x5D01	# <CJK>
+0xAE73	0x5CF4	# <CJK>
+0xAE74	0x5DEE	# <CJK>
+0xAE75	0x5E2D	# <CJK>
+0xAE76	0x5E2B	# <CJK>
+0xAE77	0x5EAB	# <CJK>
+0xAE78	0x5EAD	# <CJK>
+0xAE79	0x5EA7	# <CJK>
+0xAE7A	0x5F31	# <CJK>
+0xAE7B	0x5F92	# <CJK>
+0xAE7C	0x5F91	# <CJK>
+0xAE7D	0x5F90	# <CJK>
+0xAE7E	0x6059	# <CJK>
+0xAEA1	0x6063	# <CJK>
+0xAEA2	0x6065	# <CJK>
+0xAEA3	0x6050	# <CJK>
+0xAEA4	0x6055	# <CJK>
+0xAEA5	0x606D	# <CJK>
+0xAEA6	0x6069	# <CJK>
+0xAEA7	0x606F	# <CJK>
+0xAEA8	0x6084	# <CJK>
+0xAEA9	0x609F	# <CJK>
+0xAEAA	0x609A	# <CJK>
+0xAEAB	0x608D	# <CJK>
+0xAEAC	0x6094	# <CJK>
+0xAEAD	0x608C	# <CJK>
+0xAEAE	0x6085	# <CJK>
+0xAEAF	0x6096	# <CJK>
+0xAEB0	0x6247	# <CJK>
+0xAEB1	0x62F3	# <CJK>
+0xAEB2	0x6308	# <CJK>
+0xAEB3	0x62FF	# <CJK>
+0xAEB4	0x634E	# <CJK>
+0xAEB5	0x633E	# <CJK>
+0xAEB6	0x632F	# <CJK>
+0xAEB7	0x6355	# <CJK>
+0xAEB8	0x6342	# <CJK>
+0xAEB9	0x6346	# <CJK>
+0xAEBA	0x634F	# <CJK>
+0xAEBB	0x6349	# <CJK>
+0xAEBC	0x633A	# <CJK>
+0xAEBD	0x6350	# <CJK>
+0xAEBE	0x633D	# <CJK>
+0xAEBF	0x632A	# <CJK>
+0xAEC0	0x632B	# <CJK>
+0xAEC1	0x6328	# <CJK>
+0xAEC2	0x634D	# <CJK>
+0xAEC3	0x634C	# <CJK>
+0xAEC4	0x6548	# <CJK>
+0xAEC5	0x6549	# <CJK>
+0xAEC6	0x6599	# <CJK>
+0xAEC7	0x65C1	# <CJK>
+0xAEC8	0x65C5	# <CJK>
+0xAEC9	0x6642	# <CJK>
+0xAECA	0x6649	# <CJK>
+0xAECB	0x664F	# <CJK>
+0xAECC	0x6643	# <CJK>
+0xAECD	0x6652	# <CJK>
+0xAECE	0x664C	# <CJK>
+0xAECF	0x6645	# <CJK>
+0xAED0	0x6641	# <CJK>
+0xAED1	0x66F8	# <CJK>
+0xAED2	0x6714	# <CJK>
+0xAED3	0x6715	# <CJK>
+0xAED4	0x6717	# <CJK>
+0xAED5	0x6821	# <CJK>
+0xAED6	0x6838	# <CJK>
+0xAED7	0x6848	# <CJK>
+0xAED8	0x6846	# <CJK>
+0xAED9	0x6853	# <CJK>
+0xAEDA	0x6839	# <CJK>
+0xAEDB	0x6842	# <CJK>
+0xAEDC	0x6854	# <CJK>
+0xAEDD	0x6829	# <CJK>
+0xAEDE	0x68B3	# <CJK>
+0xAEDF	0x6817	# <CJK>
+0xAEE0	0x684C	# <CJK>
+0xAEE1	0x6851	# <CJK>
+0xAEE2	0x683D	# <CJK>
+0xAEE3	0x67F4	# <CJK>
+0xAEE4	0x6850	# <CJK>
+0xAEE5	0x6840	# <CJK>
+0xAEE6	0x683C	# <CJK>
+0xAEE7	0x6843	# <CJK>
+0xAEE8	0x682A	# <CJK>
+0xAEE9	0x6845	# <CJK>
+0xAEEA	0x6813	# <CJK>
+0xAEEB	0x6818	# <CJK>
+0xAEEC	0x6841	# <CJK>
+0xAEED	0x6B8A	# <CJK>
+0xAEEE	0x6B89	# <CJK>
+0xAEEF	0x6BB7	# <CJK>
+0xAEF0	0x6C23	# <CJK>
+0xAEF1	0x6C27	# <CJK>
+0xAEF2	0x6C28	# <CJK>
+0xAEF3	0x6C26	# <CJK>
+0xAEF4	0x6C24	# <CJK>
+0xAEF5	0x6CF0	# <CJK>
+0xAEF6	0x6D6A	# <CJK>
+0xAEF7	0x6D95	# <CJK>
+0xAEF8	0x6D88	# <CJK>
+0xAEF9	0x6D87	# <CJK>
+0xAEFA	0x6D66	# <CJK>
+0xAEFB	0x6D78	# <CJK>
+0xAEFC	0x6D77	# <CJK>
+0xAEFD	0x6D59	# <CJK>
+0xAEFE	0x6D93	# <CJK>
+0xAF40	0x6D6C	# <CJK>
+0xAF41	0x6D89	# <CJK>
+0xAF42	0x6D6E	# <CJK>
+0xAF43	0x6D5A	# <CJK>
+0xAF44	0x6D74	# <CJK>
+0xAF45	0x6D69	# <CJK>
+0xAF46	0x6D8C	# <CJK>
+0xAF47	0x6D8A	# <CJK>
+0xAF48	0x6D79	# <CJK>
+0xAF49	0x6D85	# <CJK>
+0xAF4A	0x6D65	# <CJK>
+0xAF4B	0x6D94	# <CJK>
+0xAF4C	0x70CA	# <CJK>
+0xAF4D	0x70D8	# <CJK>
+0xAF4E	0x70E4	# <CJK>
+0xAF4F	0x70D9	# <CJK>
+0xAF50	0x70C8	# <CJK>
+0xAF51	0x70CF	# <CJK>
+0xAF52	0x7239	# <CJK>
+0xAF53	0x7279	# <CJK>
+0xAF54	0x72FC	# <CJK>
+0xAF55	0x72F9	# <CJK>
+0xAF56	0x72FD	# <CJK>
+0xAF57	0x72F8	# <CJK>
+0xAF58	0x72F7	# <CJK>
+0xAF59	0x7386	# <CJK>
+0xAF5A	0x73ED	# <CJK>
+0xAF5B	0x7409	# <CJK>
+0xAF5C	0x73EE	# <CJK>
+0xAF5D	0x73E0	# <CJK>
+0xAF5E	0x73EA	# <CJK>
+0xAF5F	0x73DE	# <CJK>
+0xAF60	0x7554	# <CJK>
+0xAF61	0x755D	# <CJK>
+0xAF62	0x755C	# <CJK>
+0xAF63	0x755A	# <CJK>
+0xAF64	0x7559	# <CJK>
+0xAF65	0x75BE	# <CJK>
+0xAF66	0x75C5	# <CJK>
+0xAF67	0x75C7	# <CJK>
+0xAF68	0x75B2	# <CJK>
+0xAF69	0x75B3	# <CJK>
+0xAF6A	0x75BD	# <CJK>
+0xAF6B	0x75BC	# <CJK>
+0xAF6C	0x75B9	# <CJK>
+0xAF6D	0x75C2	# <CJK>
+0xAF6E	0x75B8	# <CJK>
+0xAF6F	0x768B	# <CJK>
+0xAF70	0x76B0	# <CJK>
+0xAF71	0x76CA	# <CJK>
+0xAF72	0x76CD	# <CJK>
+0xAF73	0x76CE	# <CJK>
+0xAF74	0x7729	# <CJK>
+0xAF75	0x771F	# <CJK>
+0xAF76	0x7720	# <CJK>
+0xAF77	0x7728	# <CJK>
+0xAF78	0x77E9	# <CJK>
+0xAF79	0x7830	# <CJK>
+0xAF7A	0x7827	# <CJK>
+0xAF7B	0x7838	# <CJK>
+0xAF7C	0x781D	# <CJK>
+0xAF7D	0x7834	# <CJK>
+0xAF7E	0x7837	# <CJK>
+0xAFA1	0x7825	# <CJK>
+0xAFA2	0x782D	# <CJK>
+0xAFA3	0x7820	# <CJK>
+0xAFA4	0x781F	# <CJK>
+0xAFA5	0x7832	# <CJK>
+0xAFA6	0x7955	# <CJK>
+0xAFA7	0x7950	# <CJK>
+0xAFA8	0x7960	# <CJK>
+0xAFA9	0x795F	# <CJK>
+0xAFAA	0x7956	# <CJK>
+0xAFAB	0x795E	# <CJK>
+0xAFAC	0x795D	# <CJK>
+0xAFAD	0x7957	# <CJK>
+0xAFAE	0x795A	# <CJK>
+0xAFAF	0x79E4	# <CJK>
+0xAFB0	0x79E3	# <CJK>
+0xAFB1	0x79E7	# <CJK>
+0xAFB2	0x79DF	# <CJK>
+0xAFB3	0x79E6	# <CJK>
+0xAFB4	0x79E9	# <CJK>
+0xAFB5	0x79D8	# <CJK>
+0xAFB6	0x7A84	# <CJK>
+0xAFB7	0x7A88	# <CJK>
+0xAFB8	0x7AD9	# <CJK>
+0xAFB9	0x7B06	# <CJK>
+0xAFBA	0x7B11	# <CJK>
+0xAFBB	0x7C89	# <CJK>
+0xAFBC	0x7D21	# <CJK>
+0xAFBD	0x7D17	# <CJK>
+0xAFBE	0x7D0B	# <CJK>
+0xAFBF	0x7D0A	# <CJK>
+0xAFC0	0x7D20	# <CJK>
+0xAFC1	0x7D22	# <CJK>
+0xAFC2	0x7D14	# <CJK>
+0xAFC3	0x7D10	# <CJK>
+0xAFC4	0x7D15	# <CJK>
+0xAFC5	0x7D1A	# <CJK>
+0xAFC6	0x7D1C	# <CJK>
+0xAFC7	0x7D0D	# <CJK>
+0xAFC8	0x7D19	# <CJK>
+0xAFC9	0x7D1B	# <CJK>
+0xAFCA	0x7F3A	# <CJK>
+0xAFCB	0x7F5F	# <CJK>
+0xAFCC	0x7F94	# <CJK>
+0xAFCD	0x7FC5	# <CJK>
+0xAFCE	0x7FC1	# <CJK>
+0xAFCF	0x8006	# <CJK>
+0xAFD0	0x8018	# <CJK>
+0xAFD1	0x8015	# <CJK>
+0xAFD2	0x8019	# <CJK>
+0xAFD3	0x8017	# <CJK>
+0xAFD4	0x803D	# <CJK>
+0xAFD5	0x803F	# <CJK>
+0xAFD6	0x80F1	# <CJK>
+0xAFD7	0x8102	# <CJK>
+0xAFD8	0x80F0	# <CJK>
+0xAFD9	0x8105	# <CJK>
+0xAFDA	0x80ED	# <CJK>
+0xAFDB	0x80F4	# <CJK>
+0xAFDC	0x8106	# <CJK>
+0xAFDD	0x80F8	# <CJK>
+0xAFDE	0x80F3	# <CJK>
+0xAFDF	0x8108	# <CJK>
+0xAFE0	0x80FD	# <CJK>
+0xAFE1	0x810A	# <CJK>
+0xAFE2	0x80FC	# <CJK>
+0xAFE3	0x80EF	# <CJK>
+0xAFE4	0x81ED	# <CJK>
+0xAFE5	0x81EC	# <CJK>
+0xAFE6	0x8200	# <CJK>
+0xAFE7	0x8210	# <CJK>
+0xAFE8	0x822A	# <CJK>
+0xAFE9	0x822B	# <CJK>
+0xAFEA	0x8228	# <CJK>
+0xAFEB	0x822C	# <CJK>
+0xAFEC	0x82BB	# <CJK>
+0xAFED	0x832B	# <CJK>
+0xAFEE	0x8352	# <CJK>
+0xAFEF	0x8354	# <CJK>
+0xAFF0	0x834A	# <CJK>
+0xAFF1	0x8338	# <CJK>
+0xAFF2	0x8350	# <CJK>
+0xAFF3	0x8349	# <CJK>
+0xAFF4	0x8335	# <CJK>
+0xAFF5	0x8334	# <CJK>
+0xAFF6	0x834F	# <CJK>
+0xAFF7	0x8332	# <CJK>
+0xAFF8	0x8339	# <CJK>
+0xAFF9	0x8336	# <CJK>
+0xAFFA	0x8317	# <CJK>
+0xAFFB	0x8340	# <CJK>
+0xAFFC	0x8331	# <CJK>
+0xAFFD	0x8328	# <CJK>
+0xAFFE	0x8343	# <CJK>
+0xB040	0x8654	# <CJK>
+0xB041	0x868A	# <CJK>
+0xB042	0x86AA	# <CJK>
+0xB043	0x8693	# <CJK>
+0xB044	0x86A4	# <CJK>
+0xB045	0x86A9	# <CJK>
+0xB046	0x868C	# <CJK>
+0xB047	0x86A3	# <CJK>
+0xB048	0x869C	# <CJK>
+0xB049	0x8870	# <CJK>
+0xB04A	0x8877	# <CJK>
+0xB04B	0x8881	# <CJK>
+0xB04C	0x8882	# <CJK>
+0xB04D	0x887D	# <CJK>
+0xB04E	0x8879	# <CJK>
+0xB04F	0x8A18	# <CJK>
+0xB050	0x8A10	# <CJK>
+0xB051	0x8A0E	# <CJK>
+0xB052	0x8A0C	# <CJK>
+0xB053	0x8A15	# <CJK>
+0xB054	0x8A0A	# <CJK>
+0xB055	0x8A17	# <CJK>
+0xB056	0x8A13	# <CJK>
+0xB057	0x8A16	# <CJK>
+0xB058	0x8A0F	# <CJK>
+0xB059	0x8A11	# <CJK>
+0xB05A	0x8C48	# <CJK>
+0xB05B	0x8C7A	# <CJK>
+0xB05C	0x8C79	# <CJK>
+0xB05D	0x8CA1	# <CJK>
+0xB05E	0x8CA2	# <CJK>
+0xB05F	0x8D77	# <CJK>
+0xB060	0x8EAC	# <CJK>
+0xB061	0x8ED2	# <CJK>
+0xB062	0x8ED4	# <CJK>
+0xB063	0x8ECF	# <CJK>
+0xB064	0x8FB1	# <CJK>
+0xB065	0x9001	# <CJK>
+0xB066	0x9006	# <CJK>
+0xB067	0x8FF7	# <CJK>
+0xB068	0x9000	# <CJK>
+0xB069	0x8FFA	# <CJK>
+0xB06A	0x8FF4	# <CJK>
+0xB06B	0x9003	# <CJK>
+0xB06C	0x8FFD	# <CJK>
+0xB06D	0x9005	# <CJK>
+0xB06E	0x8FF8	# <CJK>
+0xB06F	0x9095	# <CJK>
+0xB070	0x90E1	# <CJK>
+0xB071	0x90DD	# <CJK>
+0xB072	0x90E2	# <CJK>
+0xB073	0x9152	# <CJK>
+0xB074	0x914D	# <CJK>
+0xB075	0x914C	# <CJK>
+0xB076	0x91D8	# <CJK>
+0xB077	0x91DD	# <CJK>
+0xB078	0x91D7	# <CJK>
+0xB079	0x91DC	# <CJK>
+0xB07A	0x91D9	# <CJK>
+0xB07B	0x9583	# <CJK>
+0xB07C	0x9662	# <CJK>
+0xB07D	0x9663	# <CJK>
+0xB07E	0x9661	# <CJK>
+0xB0A1	0x965B	# <CJK>
+0xB0A2	0x965D	# <CJK>
+0xB0A3	0x9664	# <CJK>
+0xB0A4	0x9658	# <CJK>
+0xB0A5	0x965E	# <CJK>
+0xB0A6	0x96BB	# <CJK>
+0xB0A7	0x98E2	# <CJK>
+0xB0A8	0x99AC	# <CJK>
+0xB0A9	0x9AA8	# <CJK>
+0xB0AA	0x9AD8	# <CJK>
+0xB0AB	0x9B25	# <CJK>
+0xB0AC	0x9B32	# <CJK>
+0xB0AD	0x9B3C	# <CJK>
+0xB0AE	0x4E7E	# <CJK>
+0xB0AF	0x507A	# <CJK>
+0xB0B0	0x507D	# <CJK>
+0xB0B1	0x505C	# <CJK>
+0xB0B2	0x5047	# <CJK>
+0xB0B3	0x5043	# <CJK>
+0xB0B4	0x504C	# <CJK>
+0xB0B5	0x505A	# <CJK>
+0xB0B6	0x5049	# <CJK>
+0xB0B7	0x5065	# <CJK>
+0xB0B8	0x5076	# <CJK>
+0xB0B9	0x504E	# <CJK>
+0xB0BA	0x5055	# <CJK>
+0xB0BB	0x5075	# <CJK>
+0xB0BC	0x5074	# <CJK>
+0xB0BD	0x5077	# <CJK>
+0xB0BE	0x504F	# <CJK>
+0xB0BF	0x500F	# <CJK>
+0xB0C0	0x506F	# <CJK>
+0xB0C1	0x506D	# <CJK>
+0xB0C2	0x515C	# <CJK>
+0xB0C3	0x5195	# <CJK>
+0xB0C4	0x51F0	# <CJK>
+0xB0C5	0x526A	# <CJK>
+0xB0C6	0x526F	# <CJK>
+0xB0C7	0x52D2	# <CJK>
+0xB0C8	0x52D9	# <CJK>
+0xB0C9	0x52D8	# <CJK>
+0xB0CA	0x52D5	# <CJK>
+0xB0CB	0x5310	# <CJK>
+0xB0CC	0x530F	# <CJK>
+0xB0CD	0x5319	# <CJK>
+0xB0CE	0x533F	# <CJK>
+0xB0CF	0x5340	# <CJK>
+0xB0D0	0x533E	# <CJK>
+0xB0D1	0x53C3	# <CJK>
+0xB0D2	0x66FC	# <CJK>
+0xB0D3	0x5546	# <CJK>
+0xB0D4	0x556A	# <CJK>
+0xB0D5	0x5566	# <CJK>
+0xB0D6	0x5544	# <CJK>
+0xB0D7	0x555E	# <CJK>
+0xB0D8	0x5561	# <CJK>
+0xB0D9	0x5543	# <CJK>
+0xB0DA	0x554A	# <CJK>
+0xB0DB	0x5531	# <CJK>
+0xB0DC	0x5556	# <CJK>
+0xB0DD	0x554F	# <CJK>
+0xB0DE	0x5555	# <CJK>
+0xB0DF	0x552F	# <CJK>
+0xB0E0	0x5564	# <CJK>
+0xB0E1	0x5538	# <CJK>
+0xB0E2	0x552E	# <CJK>
+0xB0E3	0x555C	# <CJK>
+0xB0E4	0x552C	# <CJK>
+0xB0E5	0x5563	# <CJK>
+0xB0E6	0x5533	# <CJK>
+0xB0E7	0x5541	# <CJK>
+0xB0E8	0x5557	# <CJK>
+0xB0E9	0x5708	# <CJK>
+0xB0EA	0x570B	# <CJK>
+0xB0EB	0x5709	# <CJK>
+0xB0EC	0x57DF	# <CJK>
+0xB0ED	0x5805	# <CJK>
+0xB0EE	0x580A	# <CJK>
+0xB0EF	0x5806	# <CJK>
+0xB0F0	0x57E0	# <CJK>
+0xB0F1	0x57E4	# <CJK>
+0xB0F2	0x57FA	# <CJK>
+0xB0F3	0x5802	# <CJK>
+0xB0F4	0x5835	# <CJK>
+0xB0F5	0x57F7	# <CJK>
+0xB0F6	0x57F9	# <CJK>
+0xB0F7	0x5920	# <CJK>
+0xB0F8	0x5962	# <CJK>
+0xB0F9	0x5A36	# <CJK>
+0xB0FA	0x5A41	# <CJK>
+0xB0FB	0x5A49	# <CJK>
+0xB0FC	0x5A66	# <CJK>
+0xB0FD	0x5A6A	# <CJK>
+0xB0FE	0x5A40	# <CJK>
+0xB140	0x5A3C	# <CJK>
+0xB141	0x5A62	# <CJK>
+0xB142	0x5A5A	# <CJK>
+0xB143	0x5A46	# <CJK>
+0xB144	0x5A4A	# <CJK>
+0xB145	0x5B70	# <CJK>
+0xB146	0x5BC7	# <CJK>
+0xB147	0x5BC5	# <CJK>
+0xB148	0x5BC4	# <CJK>
+0xB149	0x5BC2	# <CJK>
+0xB14A	0x5BBF	# <CJK>
+0xB14B	0x5BC6	# <CJK>
+0xB14C	0x5C09	# <CJK>
+0xB14D	0x5C08	# <CJK>
+0xB14E	0x5C07	# <CJK>
+0xB14F	0x5C60	# <CJK>
+0xB150	0x5C5C	# <CJK>
+0xB151	0x5C5D	# <CJK>
+0xB152	0x5D07	# <CJK>
+0xB153	0x5D06	# <CJK>
+0xB154	0x5D0E	# <CJK>
+0xB155	0x5D1B	# <CJK>
+0xB156	0x5D16	# <CJK>
+0xB157	0x5D22	# <CJK>
+0xB158	0x5D11	# <CJK>
+0xB159	0x5D29	# <CJK>
+0xB15A	0x5D14	# <CJK>
+0xB15B	0x5D19	# <CJK>
+0xB15C	0x5D24	# <CJK>
+0xB15D	0x5D27	# <CJK>
+0xB15E	0x5D17	# <CJK>
+0xB15F	0x5DE2	# <CJK>
+0xB160	0x5E38	# <CJK>
+0xB161	0x5E36	# <CJK>
+0xB162	0x5E33	# <CJK>
+0xB163	0x5E37	# <CJK>
+0xB164	0x5EB7	# <CJK>
+0xB165	0x5EB8	# <CJK>
+0xB166	0x5EB6	# <CJK>
+0xB167	0x5EB5	# <CJK>
+0xB168	0x5EBE	# <CJK>
+0xB169	0x5F35	# <CJK>
+0xB16A	0x5F37	# <CJK>
+0xB16B	0x5F57	# <CJK>
+0xB16C	0x5F6C	# <CJK>
+0xB16D	0x5F69	# <CJK>
+0xB16E	0x5F6B	# <CJK>
+0xB16F	0x5F97	# <CJK>
+0xB170	0x5F99	# <CJK>
+0xB171	0x5F9E	# <CJK>
+0xB172	0x5F98	# <CJK>
+0xB173	0x5FA1	# <CJK>
+0xB174	0x5FA0	# <CJK>
+0xB175	0x5F9C	# <CJK>
+0xB176	0x607F	# <CJK>
+0xB177	0x60A3	# <CJK>
+0xB178	0x6089	# <CJK>
+0xB179	0x60A0	# <CJK>
+0xB17A	0x60A8	# <CJK>
+0xB17B	0x60CB	# <CJK>
+0xB17C	0x60B4	# <CJK>
+0xB17D	0x60E6	# <CJK>
+0xB17E	0x60BD	# <CJK>
+0xB1A1	0x60C5	# <CJK>
+0xB1A2	0x60BB	# <CJK>
+0xB1A3	0x60B5	# <CJK>
+0xB1A4	0x60DC	# <CJK>
+0xB1A5	0x60BC	# <CJK>
+0xB1A6	0x60D8	# <CJK>
+0xB1A7	0x60D5	# <CJK>
+0xB1A8	0x60C6	# <CJK>
+0xB1A9	0x60DF	# <CJK>
+0xB1AA	0x60B8	# <CJK>
+0xB1AB	0x60DA	# <CJK>
+0xB1AC	0x60C7	# <CJK>
+0xB1AD	0x621A	# <CJK>
+0xB1AE	0x621B	# <CJK>
+0xB1AF	0x6248	# <CJK>
+0xB1B0	0x63A0	# <CJK>
+0xB1B1	0x63A7	# <CJK>
+0xB1B2	0x6372	# <CJK>
+0xB1B3	0x6396	# <CJK>
+0xB1B4	0x63A2	# <CJK>
+0xB1B5	0x63A5	# <CJK>
+0xB1B6	0x6377	# <CJK>
+0xB1B7	0x6367	# <CJK>
+0xB1B8	0x6398	# <CJK>
+0xB1B9	0x63AA	# <CJK>
+0xB1BA	0x6371	# <CJK>
+0xB1BB	0x63A9	# <CJK>
+0xB1BC	0x6389	# <CJK>
+0xB1BD	0x6383	# <CJK>
+0xB1BE	0x639B	# <CJK>
+0xB1BF	0x636B	# <CJK>
+0xB1C0	0x63A8	# <CJK>
+0xB1C1	0x6384	# <CJK>
+0xB1C2	0x6388	# <CJK>
+0xB1C3	0x6399	# <CJK>
+0xB1C4	0x63A1	# <CJK>
+0xB1C5	0x63AC	# <CJK>
+0xB1C6	0x6392	# <CJK>
+0xB1C7	0x638F	# <CJK>
+0xB1C8	0x6380	# <CJK>
+0xB1C9	0x637B	# <CJK>
+0xB1CA	0x6369	# <CJK>
+0xB1CB	0x6368	# <CJK>
+0xB1CC	0x637A	# <CJK>
+0xB1CD	0x655D	# <CJK>
+0xB1CE	0x6556	# <CJK>
+0xB1CF	0x6551	# <CJK>
+0xB1D0	0x6559	# <CJK>
+0xB1D1	0x6557	# <CJK>
+0xB1D2	0x555F	# <CJK>
+0xB1D3	0x654F	# <CJK>
+0xB1D4	0x6558	# <CJK>
+0xB1D5	0x6555	# <CJK>
+0xB1D6	0x6554	# <CJK>
+0xB1D7	0x659C	# <CJK>
+0xB1D8	0x659B	# <CJK>
+0xB1D9	0x65AC	# <CJK>
+0xB1DA	0x65CF	# <CJK>
+0xB1DB	0x65CB	# <CJK>
+0xB1DC	0x65CC	# <CJK>
+0xB1DD	0x65CE	# <CJK>
+0xB1DE	0x665D	# <CJK>
+0xB1DF	0x665A	# <CJK>
+0xB1E0	0x6664	# <CJK>
+0xB1E1	0x6668	# <CJK>
+0xB1E2	0x6666	# <CJK>
+0xB1E3	0x665E	# <CJK>
+0xB1E4	0x66F9	# <CJK>
+0xB1E5	0x52D7	# <CJK>
+0xB1E6	0x671B	# <CJK>
+0xB1E7	0x6881	# <CJK>
+0xB1E8	0x68AF	# <CJK>
+0xB1E9	0x68A2	# <CJK>
+0xB1EA	0x6893	# <CJK>
+0xB1EB	0x68B5	# <CJK>
+0xB1EC	0x687F	# <CJK>
+0xB1ED	0x6876	# <CJK>
+0xB1EE	0x68B1	# <CJK>
+0xB1EF	0x68A7	# <CJK>
+0xB1F0	0x6897	# <CJK>
+0xB1F1	0x68B0	# <CJK>
+0xB1F2	0x6883	# <CJK>
+0xB1F3	0x68C4	# <CJK>
+0xB1F4	0x68AD	# <CJK>
+0xB1F5	0x6886	# <CJK>
+0xB1F6	0x6885	# <CJK>
+0xB1F7	0x6894	# <CJK>
+0xB1F8	0x689D	# <CJK>
+0xB1F9	0x68A8	# <CJK>
+0xB1FA	0x689F	# <CJK>
+0xB1FB	0x68A1	# <CJK>
+0xB1FC	0x6882	# <CJK>
+0xB1FD	0x6B32	# <CJK>
+0xB1FE	0x6BBA	# <CJK>
+0xB240	0x6BEB	# <CJK>
+0xB241	0x6BEC	# <CJK>
+0xB242	0x6C2B	# <CJK>
+0xB243	0x6D8E	# <CJK>
+0xB244	0x6DBC	# <CJK>
+0xB245	0x6DF3	# <CJK>
+0xB246	0x6DD9	# <CJK>
+0xB247	0x6DB2	# <CJK>
+0xB248	0x6DE1	# <CJK>
+0xB249	0x6DCC	# <CJK>
+0xB24A	0x6DE4	# <CJK>
+0xB24B	0x6DFB	# <CJK>
+0xB24C	0x6DFA	# <CJK>
+0xB24D	0x6E05	# <CJK>
+0xB24E	0x6DC7	# <CJK>
+0xB24F	0x6DCB	# <CJK>
+0xB250	0x6DAF	# <CJK>
+0xB251	0x6DD1	# <CJK>
+0xB252	0x6DAE	# <CJK>
+0xB253	0x6DDE	# <CJK>
+0xB254	0x6DF9	# <CJK>
+0xB255	0x6DB8	# <CJK>
+0xB256	0x6DF7	# <CJK>
+0xB257	0x6DF5	# <CJK>
+0xB258	0x6DC5	# <CJK>
+0xB259	0x6DD2	# <CJK>
+0xB25A	0x6E1A	# <CJK>
+0xB25B	0x6DB5	# <CJK>
+0xB25C	0x6DDA	# <CJK>
+0xB25D	0x6DEB	# <CJK>
+0xB25E	0x6DD8	# <CJK>
+0xB25F	0x6DEA	# <CJK>
+0xB260	0x6DF1	# <CJK>
+0xB261	0x6DEE	# <CJK>
+0xB262	0x6DE8	# <CJK>
+0xB263	0x6DC6	# <CJK>
+0xB264	0x6DC4	# <CJK>
+0xB265	0x6DAA	# <CJK>
+0xB266	0x6DEC	# <CJK>
+0xB267	0x6DBF	# <CJK>
+0xB268	0x6DE6	# <CJK>
+0xB269	0x70F9	# <CJK>
+0xB26A	0x7109	# <CJK>
+0xB26B	0x710A	# <CJK>
+0xB26C	0x70FD	# <CJK>
+0xB26D	0x70EF	# <CJK>
+0xB26E	0x723D	# <CJK>
+0xB26F	0x727D	# <CJK>
+0xB270	0x7281	# <CJK>
+0xB271	0x731C	# <CJK>
+0xB272	0x731B	# <CJK>
+0xB273	0x7316	# <CJK>
+0xB274	0x7313	# <CJK>
+0xB275	0x7319	# <CJK>
+0xB276	0x7387	# <CJK>
+0xB277	0x7405	# <CJK>
+0xB278	0x740A	# <CJK>
+0xB279	0x7403	# <CJK>
+0xB27A	0x7406	# <CJK>
+0xB27B	0x73FE	# <CJK>
+0xB27C	0x740D	# <CJK>
+0xB27D	0x74E0	# <CJK>
+0xB27E	0x74F6	# <CJK>
+0xB2A1	0x74F7	# <CJK>
+0xB2A2	0x751C	# <CJK>
+0xB2A3	0x7522	# <CJK>
+0xB2A4	0x7565	# <CJK>
+0xB2A5	0x7566	# <CJK>
+0xB2A6	0x7562	# <CJK>
+0xB2A7	0x7570	# <CJK>
+0xB2A8	0x758F	# <CJK>
+0xB2A9	0x75D4	# <CJK>
+0xB2AA	0x75D5	# <CJK>
+0xB2AB	0x75B5	# <CJK>
+0xB2AC	0x75CA	# <CJK>
+0xB2AD	0x75CD	# <CJK>
+0xB2AE	0x768E	# <CJK>
+0xB2AF	0x76D4	# <CJK>
+0xB2B0	0x76D2	# <CJK>
+0xB2B1	0x76DB	# <CJK>
+0xB2B2	0x7737	# <CJK>
+0xB2B3	0x773E	# <CJK>
+0xB2B4	0x773C	# <CJK>
+0xB2B5	0x7736	# <CJK>
+0xB2B6	0x7738	# <CJK>
+0xB2B7	0x773A	# <CJK>
+0xB2B8	0x786B	# <CJK>
+0xB2B9	0x7843	# <CJK>
+0xB2BA	0x784E	# <CJK>
+0xB2BB	0x7965	# <CJK>
+0xB2BC	0x7968	# <CJK>
+0xB2BD	0x796D	# <CJK>
+0xB2BE	0x79FB	# <CJK>
+0xB2BF	0x7A92	# <CJK>
+0xB2C0	0x7A95	# <CJK>
+0xB2C1	0x7B20	# <CJK>
+0xB2C2	0x7B28	# <CJK>
+0xB2C3	0x7B1B	# <CJK>
+0xB2C4	0x7B2C	# <CJK>
+0xB2C5	0x7B26	# <CJK>
+0xB2C6	0x7B19	# <CJK>
+0xB2C7	0x7B1E	# <CJK>
+0xB2C8	0x7B2E	# <CJK>
+0xB2C9	0x7C92	# <CJK>
+0xB2CA	0x7C97	# <CJK>
+0xB2CB	0x7C95	# <CJK>
+0xB2CC	0x7D46	# <CJK>
+0xB2CD	0x7D43	# <CJK>
+0xB2CE	0x7D71	# <CJK>
+0xB2CF	0x7D2E	# <CJK>
+0xB2D0	0x7D39	# <CJK>
+0xB2D1	0x7D3C	# <CJK>
+0xB2D2	0x7D40	# <CJK>
+0xB2D3	0x7D30	# <CJK>
+0xB2D4	0x7D33	# <CJK>
+0xB2D5	0x7D44	# <CJK>
+0xB2D6	0x7D2F	# <CJK>
+0xB2D7	0x7D42	# <CJK>
+0xB2D8	0x7D32	# <CJK>
+0xB2D9	0x7D31	# <CJK>
+0xB2DA	0x7F3D	# <CJK>
+0xB2DB	0x7F9E	# <CJK>
+0xB2DC	0x7F9A	# <CJK>
+0xB2DD	0x7FCC	# <CJK>
+0xB2DE	0x7FCE	# <CJK>
+0xB2DF	0x7FD2	# <CJK>
+0xB2E0	0x801C	# <CJK>
+0xB2E1	0x804A	# <CJK>
+0xB2E2	0x8046	# <CJK>
+0xB2E3	0x812F	# <CJK>
+0xB2E4	0x8116	# <CJK>
+0xB2E5	0x8123	# <CJK>
+0xB2E6	0x812B	# <CJK>
+0xB2E7	0x8129	# <CJK>
+0xB2E8	0x8130	# <CJK>
+0xB2E9	0x8124	# <CJK>
+0xB2EA	0x8202	# <CJK>
+0xB2EB	0x8235	# <CJK>
+0xB2EC	0x8237	# <CJK>
+0xB2ED	0x8236	# <CJK>
+0xB2EE	0x8239	# <CJK>
+0xB2EF	0x838E	# <CJK>
+0xB2F0	0x839E	# <CJK>
+0xB2F1	0x8398	# <CJK>
+0xB2F2	0x8378	# <CJK>
+0xB2F3	0x83A2	# <CJK>
+0xB2F4	0x8396	# <CJK>
+0xB2F5	0x83BD	# <CJK>
+0xB2F6	0x83AB	# <CJK>
+0xB2F7	0x8392	# <CJK>
+0xB2F8	0x838A	# <CJK>
+0xB2F9	0x8393	# <CJK>
+0xB2FA	0x8389	# <CJK>
+0xB2FB	0x83A0	# <CJK>
+0xB2FC	0x8377	# <CJK>
+0xB2FD	0x837B	# <CJK>
+0xB2FE	0x837C	# <CJK>
+0xB340	0x8386	# <CJK>
+0xB341	0x83A7	# <CJK>
+0xB342	0x8655	# <CJK>
+0xB343	0x5F6A	# <CJK>
+0xB344	0x86C7	# <CJK>
+0xB345	0x86C0	# <CJK>
+0xB346	0x86B6	# <CJK>
+0xB347	0x86C4	# <CJK>
+0xB348	0x86B5	# <CJK>
+0xB349	0x86C6	# <CJK>
+0xB34A	0x86CB	# <CJK>
+0xB34B	0x86B1	# <CJK>
+0xB34C	0x86AF	# <CJK>
+0xB34D	0x86C9	# <CJK>
+0xB34E	0x8853	# <CJK>
+0xB34F	0x889E	# <CJK>
+0xB350	0x8888	# <CJK>
+0xB351	0x88AB	# <CJK>
+0xB352	0x8892	# <CJK>
+0xB353	0x8896	# <CJK>
+0xB354	0x888D	# <CJK>
+0xB355	0x888B	# <CJK>
+0xB356	0x8993	# <CJK>
+0xB357	0x898F	# <CJK>
+0xB358	0x8A2A	# <CJK>
+0xB359	0x8A1D	# <CJK>
+0xB35A	0x8A23	# <CJK>
+0xB35B	0x8A25	# <CJK>
+0xB35C	0x8A31	# <CJK>
+0xB35D	0x8A2D	# <CJK>
+0xB35E	0x8A1F	# <CJK>
+0xB35F	0x8A1B	# <CJK>
+0xB360	0x8A22	# <CJK>
+0xB361	0x8C49	# <CJK>
+0xB362	0x8C5A	# <CJK>
+0xB363	0x8CA9	# <CJK>
+0xB364	0x8CAC	# <CJK>
+0xB365	0x8CAB	# <CJK>
+0xB366	0x8CA8	# <CJK>
+0xB367	0x8CAA	# <CJK>
+0xB368	0x8CA7	# <CJK>
+0xB369	0x8D67	# <CJK>
+0xB36A	0x8D66	# <CJK>
+0xB36B	0x8DBE	# <CJK>
+0xB36C	0x8DBA	# <CJK>
+0xB36D	0x8EDB	# <CJK>
+0xB36E	0x8EDF	# <CJK>
+0xB36F	0x9019	# <CJK>
+0xB370	0x900D	# <CJK>
+0xB371	0x901A	# <CJK>
+0xB372	0x9017	# <CJK>
+0xB373	0x9023	# <CJK>
+0xB374	0x901F	# <CJK>
+0xB375	0x901D	# <CJK>
+0xB376	0x9010	# <CJK>
+0xB377	0x9015	# <CJK>
+0xB378	0x901E	# <CJK>
+0xB379	0x9020	# <CJK>
+0xB37A	0x900F	# <CJK>
+0xB37B	0x9022	# <CJK>
+0xB37C	0x9016	# <CJK>
+0xB37D	0x901B	# <CJK>
+0xB37E	0x9014	# <CJK>
+0xB3A1	0x90E8	# <CJK>
+0xB3A2	0x90ED	# <CJK>
+0xB3A3	0x90FD	# <CJK>
+0xB3A4	0x9157	# <CJK>
+0xB3A5	0x91CE	# <CJK>
+0xB3A6	0x91F5	# <CJK>
+0xB3A7	0x91E6	# <CJK>
+0xB3A8	0x91E3	# <CJK>
+0xB3A9	0x91E7	# <CJK>
+0xB3AA	0x91ED	# <CJK>
+0xB3AB	0x91E9	# <CJK>
+0xB3AC	0x9589	# <CJK>
+0xB3AD	0x966A	# <CJK>
+0xB3AE	0x9675	# <CJK>
+0xB3AF	0x9673	# <CJK>
+0xB3B0	0x9678	# <CJK>
+0xB3B1	0x9670	# <CJK>
+0xB3B2	0x9674	# <CJK>
+0xB3B3	0x9676	# <CJK>
+0xB3B4	0x9677	# <CJK>
+0xB3B5	0x966C	# <CJK>
+0xB3B6	0x96C0	# <CJK>
+0xB3B7	0x96EA	# <CJK>
+0xB3B8	0x96E9	# <CJK>
+0xB3B9	0x7AE0	# <CJK>
+0xB3BA	0x7ADF	# <CJK>
+0xB3BB	0x9802	# <CJK>
+0xB3BC	0x9803	# <CJK>
+0xB3BD	0x9B5A	# <CJK>
+0xB3BE	0x9CE5	# <CJK>
+0xB3BF	0x9E75	# <CJK>
+0xB3C0	0x9E7F	# <CJK>
+0xB3C1	0x9EA5	# <CJK>
+0xB3C2	0x9EBB	# <CJK>
+0xB3C3	0x50A2	# <CJK>
+0xB3C4	0x508D	# <CJK>
+0xB3C5	0x5085	# <CJK>
+0xB3C6	0x5099	# <CJK>
+0xB3C7	0x5091	# <CJK>
+0xB3C8	0x5080	# <CJK>
+0xB3C9	0x5096	# <CJK>
+0xB3CA	0x5098	# <CJK>
+0xB3CB	0x509A	# <CJK>
+0xB3CC	0x6700	# <CJK>
+0xB3CD	0x51F1	# <CJK>
+0xB3CE	0x5272	# <CJK>
+0xB3CF	0x5274	# <CJK>
+0xB3D0	0x5275	# <CJK>
+0xB3D1	0x5269	# <CJK>
+0xB3D2	0x52DE	# <CJK>
+0xB3D3	0x52DD	# <CJK>
+0xB3D4	0x52DB	# <CJK>
+0xB3D5	0x535A	# <CJK>
+0xB3D6	0x53A5	# <CJK>
+0xB3D7	0x557B	# <CJK>
+0xB3D8	0x5580	# <CJK>
+0xB3D9	0x55A7	# <CJK>
+0xB3DA	0x557C	# <CJK>
+0xB3DB	0x558A	# <CJK>
+0xB3DC	0x559D	# <CJK>
+0xB3DD	0x5598	# <CJK>
+0xB3DE	0x5582	# <CJK>
+0xB3DF	0x559C	# <CJK>
+0xB3E0	0x55AA	# <CJK>
+0xB3E1	0x5594	# <CJK>
+0xB3E2	0x5587	# <CJK>
+0xB3E3	0x558B	# <CJK>
+0xB3E4	0x5583	# <CJK>
+0xB3E5	0x55B3	# <CJK>
+0xB3E6	0x55AE	# <CJK>
+0xB3E7	0x559F	# <CJK>
+0xB3E8	0x553E	# <CJK>
+0xB3E9	0x55B2	# <CJK>
+0xB3EA	0x559A	# <CJK>
+0xB3EB	0x55BB	# <CJK>
+0xB3EC	0x55AC	# <CJK>
+0xB3ED	0x55B1	# <CJK>
+0xB3EE	0x557E	# <CJK>
+0xB3EF	0x5589	# <CJK>
+0xB3F0	0x55AB	# <CJK>
+0xB3F1	0x5599	# <CJK>
+0xB3F2	0x570D	# <CJK>
+0xB3F3	0x582F	# <CJK>
+0xB3F4	0x582A	# <CJK>
+0xB3F5	0x5834	# <CJK>
+0xB3F6	0x5824	# <CJK>
+0xB3F7	0x5830	# <CJK>
+0xB3F8	0x5831	# <CJK>
+0xB3F9	0x5821	# <CJK>
+0xB3FA	0x581D	# <CJK>
+0xB3FB	0x5820	# <CJK>
+0xB3FC	0x58F9	# <CJK>
+0xB3FD	0x58FA	# <CJK>
+0xB3FE	0x5960	# <CJK>
+0xB440	0x5A77	# <CJK>
+0xB441	0x5A9A	# <CJK>
+0xB442	0x5A7F	# <CJK>
+0xB443	0x5A92	# <CJK>
+0xB444	0x5A9B	# <CJK>
+0xB445	0x5AA7	# <CJK>
+0xB446	0x5B73	# <CJK>
+0xB447	0x5B71	# <CJK>
+0xB448	0x5BD2	# <CJK>
+0xB449	0x5BCC	# <CJK>
+0xB44A	0x5BD3	# <CJK>
+0xB44B	0x5BD0	# <CJK>
+0xB44C	0x5C0A	# <CJK>
+0xB44D	0x5C0B	# <CJK>
+0xB44E	0x5C31	# <CJK>
+0xB44F	0x5D4C	# <CJK>
+0xB450	0x5D50	# <CJK>
+0xB451	0x5D34	# <CJK>
+0xB452	0x5D47	# <CJK>
+0xB453	0x5DFD	# <CJK>
+0xB454	0x5E45	# <CJK>
+0xB455	0x5E3D	# <CJK>
+0xB456	0x5E40	# <CJK>
+0xB457	0x5E43	# <CJK>
+0xB458	0x5E7E	# <CJK>
+0xB459	0x5ECA	# <CJK>
+0xB45A	0x5EC1	# <CJK>
+0xB45B	0x5EC2	# <CJK>
+0xB45C	0x5EC4	# <CJK>
+0xB45D	0x5F3C	# <CJK>
+0xB45E	0x5F6D	# <CJK>
+0xB45F	0x5FA9	# <CJK>
+0xB460	0x5FAA	# <CJK>
+0xB461	0x5FA8	# <CJK>
+0xB462	0x60D1	# <CJK>
+0xB463	0x60E1	# <CJK>
+0xB464	0x60B2	# <CJK>
+0xB465	0x60B6	# <CJK>
+0xB466	0x60E0	# <CJK>
+0xB467	0x611C	# <CJK>
+0xB468	0x6123	# <CJK>
+0xB469	0x60FA	# <CJK>
+0xB46A	0x6115	# <CJK>
+0xB46B	0x60F0	# <CJK>
+0xB46C	0x60FB	# <CJK>
+0xB46D	0x60F4	# <CJK>
+0xB46E	0x6168	# <CJK>
+0xB46F	0x60F1	# <CJK>
+0xB470	0x610E	# <CJK>
+0xB471	0x60F6	# <CJK>
+0xB472	0x6109	# <CJK>
+0xB473	0x6100	# <CJK>
+0xB474	0x6112	# <CJK>
+0xB475	0x621F	# <CJK>
+0xB476	0x6249	# <CJK>
+0xB477	0x63A3	# <CJK>
+0xB478	0x638C	# <CJK>
+0xB479	0x63CF	# <CJK>
+0xB47A	0x63C0	# <CJK>
+0xB47B	0x63E9	# <CJK>
+0xB47C	0x63C9	# <CJK>
+0xB47D	0x63C6	# <CJK>
+0xB47E	0x63CD	# <CJK>
+0xB4A1	0x63D2	# <CJK>
+0xB4A2	0x63E3	# <CJK>
+0xB4A3	0x63D0	# <CJK>
+0xB4A4	0x63E1	# <CJK>
+0xB4A5	0x63D6	# <CJK>
+0xB4A6	0x63ED	# <CJK>
+0xB4A7	0x63EE	# <CJK>
+0xB4A8	0x6376	# <CJK>
+0xB4A9	0x63F4	# <CJK>
+0xB4AA	0x63EA	# <CJK>
+0xB4AB	0x63DB	# <CJK>
+0xB4AC	0x6452	# <CJK>
+0xB4AD	0x63DA	# <CJK>
+0xB4AE	0x63F9	# <CJK>
+0xB4AF	0x655E	# <CJK>
+0xB4B0	0x6566	# <CJK>
+0xB4B1	0x6562	# <CJK>
+0xB4B2	0x6563	# <CJK>
+0xB4B3	0x6591	# <CJK>
+0xB4B4	0x6590	# <CJK>
+0xB4B5	0x65AF	# <CJK>
+0xB4B6	0x666E	# <CJK>
+0xB4B7	0x6670	# <CJK>
+0xB4B8	0x6674	# <CJK>
+0xB4B9	0x6676	# <CJK>
+0xB4BA	0x666F	# <CJK>
+0xB4BB	0x6691	# <CJK>
+0xB4BC	0x667A	# <CJK>
+0xB4BD	0x667E	# <CJK>
+0xB4BE	0x6677	# <CJK>
+0xB4BF	0x66FE	# <CJK>
+0xB4C0	0x66FF	# <CJK>
+0xB4C1	0x671F	# <CJK>
+0xB4C2	0x671D	# <CJK>
+0xB4C3	0x68FA	# <CJK>
+0xB4C4	0x68D5	# <CJK>
+0xB4C5	0x68E0	# <CJK>
+0xB4C6	0x68D8	# <CJK>
+0xB4C7	0x68D7	# <CJK>
+0xB4C8	0x6905	# <CJK>
+0xB4C9	0x68DF	# <CJK>
+0xB4CA	0x68F5	# <CJK>
+0xB4CB	0x68EE	# <CJK>
+0xB4CC	0x68E7	# <CJK>
+0xB4CD	0x68F9	# <CJK>
+0xB4CE	0x68D2	# <CJK>
+0xB4CF	0x68F2	# <CJK>
+0xB4D0	0x68E3	# <CJK>
+0xB4D1	0x68CB	# <CJK>
+0xB4D2	0x68CD	# <CJK>
+0xB4D3	0x690D	# <CJK>
+0xB4D4	0x6912	# <CJK>
+0xB4D5	0x690E	# <CJK>
+0xB4D6	0x68C9	# <CJK>
+0xB4D7	0x68DA	# <CJK>
+0xB4D8	0x696E	# <CJK>
+0xB4D9	0x68FB	# <CJK>
+0xB4DA	0x6B3E	# <CJK>
+0xB4DB	0x6B3A	# <CJK>
+0xB4DC	0x6B3D	# <CJK>
+0xB4DD	0x6B98	# <CJK>
+0xB4DE	0x6B96	# <CJK>
+0xB4DF	0x6BBC	# <CJK>
+0xB4E0	0x6BEF	# <CJK>
+0xB4E1	0x6C2E	# <CJK>
+0xB4E2	0x6C2F	# <CJK>
+0xB4E3	0x6C2C	# <CJK>
+0xB4E4	0x6E2F	# <CJK>
+0xB4E5	0x6E38	# <CJK>
+0xB4E6	0x6E54	# <CJK>
+0xB4E7	0x6E21	# <CJK>
+0xB4E8	0x6E32	# <CJK>
+0xB4E9	0x6E67	# <CJK>
+0xB4EA	0x6E4A	# <CJK>
+0xB4EB	0x6E20	# <CJK>
+0xB4EC	0x6E25	# <CJK>
+0xB4ED	0x6E23	# <CJK>
+0xB4EE	0x6E1B	# <CJK>
+0xB4EF	0x6E5B	# <CJK>
+0xB4F0	0x6E58	# <CJK>
+0xB4F1	0x6E24	# <CJK>
+0xB4F2	0x6E56	# <CJK>
+0xB4F3	0x6E6E	# <CJK>
+0xB4F4	0x6E2D	# <CJK>
+0xB4F5	0x6E26	# <CJK>
+0xB4F6	0x6E6F	# <CJK>
+0xB4F7	0x6E34	# <CJK>
+0xB4F8	0x6E4D	# <CJK>
+0xB4F9	0x6E3A	# <CJK>
+0xB4FA	0x6E2C	# <CJK>
+0xB4FB	0x6E43	# <CJK>
+0xB4FC	0x6E1D	# <CJK>
+0xB4FD	0x6E3E	# <CJK>
+0xB4FE	0x6ECB	# <CJK>
+0xB540	0x6E89	# <CJK>
+0xB541	0x6E19	# <CJK>
+0xB542	0x6E4E	# <CJK>
+0xB543	0x6E63	# <CJK>
+0xB544	0x6E44	# <CJK>
+0xB545	0x6E72	# <CJK>
+0xB546	0x6E69	# <CJK>
+0xB547	0x6E5F	# <CJK>
+0xB548	0x7119	# <CJK>
+0xB549	0x711A	# <CJK>
+0xB54A	0x7126	# <CJK>
+0xB54B	0x7130	# <CJK>
+0xB54C	0x7121	# <CJK>
+0xB54D	0x7136	# <CJK>
+0xB54E	0x716E	# <CJK>
+0xB54F	0x711C	# <CJK>
+0xB550	0x724C	# <CJK>
+0xB551	0x7284	# <CJK>
+0xB552	0x7280	# <CJK>
+0xB553	0x7336	# <CJK>
+0xB554	0x7325	# <CJK>
+0xB555	0x7334	# <CJK>
+0xB556	0x7329	# <CJK>
+0xB557	0x743A	# <CJK>
+0xB558	0x742A	# <CJK>
+0xB559	0x7433	# <CJK>
+0xB55A	0x7422	# <CJK>
+0xB55B	0x7425	# <CJK>
+0xB55C	0x7435	# <CJK>
+0xB55D	0x7436	# <CJK>
+0xB55E	0x7434	# <CJK>
+0xB55F	0x742F	# <CJK>
+0xB560	0x741B	# <CJK>
+0xB561	0x7426	# <CJK>
+0xB562	0x7428	# <CJK>
+0xB563	0x7525	# <CJK>
+0xB564	0x7526	# <CJK>
+0xB565	0x756B	# <CJK>
+0xB566	0x756A	# <CJK>
+0xB567	0x75E2	# <CJK>
+0xB568	0x75DB	# <CJK>
+0xB569	0x75E3	# <CJK>
+0xB56A	0x75D9	# <CJK>
+0xB56B	0x75D8	# <CJK>
+0xB56C	0x75DE	# <CJK>
+0xB56D	0x75E0	# <CJK>
+0xB56E	0x767B	# <CJK>
+0xB56F	0x767C	# <CJK>
+0xB570	0x7696	# <CJK>
+0xB571	0x7693	# <CJK>
+0xB572	0x76B4	# <CJK>
+0xB573	0x76DC	# <CJK>
+0xB574	0x774F	# <CJK>
+0xB575	0x77ED	# <CJK>
+0xB576	0x785D	# <CJK>
+0xB577	0x786C	# <CJK>
+0xB578	0x786F	# <CJK>
+0xB579	0x7A0D	# <CJK>
+0xB57A	0x7A08	# <CJK>
+0xB57B	0x7A0B	# <CJK>
+0xB57C	0x7A05	# <CJK>
+0xB57D	0x7A00	# <CJK>
+0xB57E	0x7A98	# <CJK>
+0xB5A1	0x7A97	# <CJK>
+0xB5A2	0x7A96	# <CJK>
+0xB5A3	0x7AE5	# <CJK>
+0xB5A4	0x7AE3	# <CJK>
+0xB5A5	0x7B49	# <CJK>
+0xB5A6	0x7B56	# <CJK>
+0xB5A7	0x7B46	# <CJK>
+0xB5A8	0x7B50	# <CJK>
+0xB5A9	0x7B52	# <CJK>
+0xB5AA	0x7B54	# <CJK>
+0xB5AB	0x7B4D	# <CJK>
+0xB5AC	0x7B4B	# <CJK>
+0xB5AD	0x7B4F	# <CJK>
+0xB5AE	0x7B51	# <CJK>
+0xB5AF	0x7C9F	# <CJK>
+0xB5B0	0x7CA5	# <CJK>
+0xB5B1	0x7D5E	# <CJK>
+0xB5B2	0x7D50	# <CJK>
+0xB5B3	0x7D68	# <CJK>
+0xB5B4	0x7D55	# <CJK>
+0xB5B5	0x7D2B	# <CJK>
+0xB5B6	0x7D6E	# <CJK>
+0xB5B7	0x7D72	# <CJK>
+0xB5B8	0x7D61	# <CJK>
+0xB5B9	0x7D66	# <CJK>
+0xB5BA	0x7D62	# <CJK>
+0xB5BB	0x7D70	# <CJK>
+0xB5BC	0x7D73	# <CJK>
+0xB5BD	0x5584	# <CJK>
+0xB5BE	0x7FD4	# <CJK>
+0xB5BF	0x7FD5	# <CJK>
+0xB5C0	0x800B	# <CJK>
+0xB5C1	0x8052	# <CJK>
+0xB5C2	0x8085	# <CJK>
+0xB5C3	0x8155	# <CJK>
+0xB5C4	0x8154	# <CJK>
+0xB5C5	0x814B	# <CJK>
+0xB5C6	0x8151	# <CJK>
+0xB5C7	0x814E	# <CJK>
+0xB5C8	0x8139	# <CJK>
+0xB5C9	0x8146	# <CJK>
+0xB5CA	0x813E	# <CJK>
+0xB5CB	0x814C	# <CJK>
+0xB5CC	0x8153	# <CJK>
+0xB5CD	0x8174	# <CJK>
+0xB5CE	0x8212	# <CJK>
+0xB5CF	0x821C	# <CJK>
+0xB5D0	0x83E9	# <CJK>
+0xB5D1	0x8403	# <CJK>
+0xB5D2	0x83F8	# <CJK>
+0xB5D3	0x840D	# <CJK>
+0xB5D4	0x83E0	# <CJK>
+0xB5D5	0x83C5	# <CJK>
+0xB5D6	0x840B	# <CJK>
+0xB5D7	0x83C1	# <CJK>
+0xB5D8	0x83EF	# <CJK>
+0xB5D9	0x83F1	# <CJK>
+0xB5DA	0x83F4	# <CJK>
+0xB5DB	0x8457	# <CJK>
+0xB5DC	0x840A	# <CJK>
+0xB5DD	0x83F0	# <CJK>
+0xB5DE	0x840C	# <CJK>
+0xB5DF	0x83CC	# <CJK>
+0xB5E0	0x83FD	# <CJK>
+0xB5E1	0x83F2	# <CJK>
+0xB5E2	0x83CA	# <CJK>
+0xB5E3	0x8438	# <CJK>
+0xB5E4	0x840E	# <CJK>
+0xB5E5	0x8404	# <CJK>
+0xB5E6	0x83DC	# <CJK>
+0xB5E7	0x8407	# <CJK>
+0xB5E8	0x83D4	# <CJK>
+0xB5E9	0x83DF	# <CJK>
+0xB5EA	0x865B	# <CJK>
+0xB5EB	0x86DF	# <CJK>
+0xB5EC	0x86D9	# <CJK>
+0xB5ED	0x86ED	# <CJK>
+0xB5EE	0x86D4	# <CJK>
+0xB5EF	0x86DB	# <CJK>
+0xB5F0	0x86E4	# <CJK>
+0xB5F1	0x86D0	# <CJK>
+0xB5F2	0x86DE	# <CJK>
+0xB5F3	0x8857	# <CJK>
+0xB5F4	0x88C1	# <CJK>
+0xB5F5	0x88C2	# <CJK>
+0xB5F6	0x88B1	# <CJK>
+0xB5F7	0x8983	# <CJK>
+0xB5F8	0x8996	# <CJK>
+0xB5F9	0x8A3B	# <CJK>
+0xB5FA	0x8A60	# <CJK>
+0xB5FB	0x8A55	# <CJK>
+0xB5FC	0x8A5E	# <CJK>
+0xB5FD	0x8A3C	# <CJK>
+0xB5FE	0x8A41	# <CJK>
+0xB640	0x8A54	# <CJK>
+0xB641	0x8A5B	# <CJK>
+0xB642	0x8A50	# <CJK>
+0xB643	0x8A46	# <CJK>
+0xB644	0x8A34	# <CJK>
+0xB645	0x8A3A	# <CJK>
+0xB646	0x8A36	# <CJK>
+0xB647	0x8A56	# <CJK>
+0xB648	0x8C61	# <CJK>
+0xB649	0x8C82	# <CJK>
+0xB64A	0x8CAF	# <CJK>
+0xB64B	0x8CBC	# <CJK>
+0xB64C	0x8CB3	# <CJK>
+0xB64D	0x8CBD	# <CJK>
+0xB64E	0x8CC1	# <CJK>
+0xB64F	0x8CBB	# <CJK>
+0xB650	0x8CC0	# <CJK>
+0xB651	0x8CB4	# <CJK>
+0xB652	0x8CB7	# <CJK>
+0xB653	0x8CB6	# <CJK>
+0xB654	0x8CBF	# <CJK>
+0xB655	0x8CB8	# <CJK>
+0xB656	0x8D8A	# <CJK>
+0xB657	0x8D85	# <CJK>
+0xB658	0x8D81	# <CJK>
+0xB659	0x8DCE	# <CJK>
+0xB65A	0x8DDD	# <CJK>
+0xB65B	0x8DCB	# <CJK>
+0xB65C	0x8DDA	# <CJK>
+0xB65D	0x8DD1	# <CJK>
+0xB65E	0x8DCC	# <CJK>
+0xB65F	0x8DDB	# <CJK>
+0xB660	0x8DC6	# <CJK>
+0xB661	0x8EFB	# <CJK>
+0xB662	0x8EF8	# <CJK>
+0xB663	0x8EFC	# <CJK>
+0xB664	0x8F9C	# <CJK>
+0xB665	0x902E	# <CJK>
+0xB666	0x9035	# <CJK>
+0xB667	0x9031	# <CJK>
+0xB668	0x9038	# <CJK>
+0xB669	0x9032	# <CJK>
+0xB66A	0x9036	# <CJK>
+0xB66B	0x9102	# <CJK>
+0xB66C	0x90F5	# <CJK>
+0xB66D	0x9109	# <CJK>
+0xB66E	0x90FE	# <CJK>
+0xB66F	0x9163	# <CJK>
+0xB670	0x9165	# <CJK>
+0xB671	0x91CF	# <CJK>
+0xB672	0x9214	# <CJK>
+0xB673	0x9215	# <CJK>
+0xB674	0x9223	# <CJK>
+0xB675	0x9209	# <CJK>
+0xB676	0x921E	# <CJK>
+0xB677	0x920D	# <CJK>
+0xB678	0x9210	# <CJK>
+0xB679	0x9207	# <CJK>
+0xB67A	0x9211	# <CJK>
+0xB67B	0x9594	# <CJK>
+0xB67C	0x958F	# <CJK>
+0xB67D	0x958B	# <CJK>
+0xB67E	0x9591	# <CJK>
+0xB6A1	0x9593	# <CJK>
+0xB6A2	0x9592	# <CJK>
+0xB6A3	0x958E	# <CJK>
+0xB6A4	0x968A	# <CJK>
+0xB6A5	0x968E	# <CJK>
+0xB6A6	0x968B	# <CJK>
+0xB6A7	0x967D	# <CJK>
+0xB6A8	0x9685	# <CJK>
+0xB6A9	0x9686	# <CJK>
+0xB6AA	0x968D	# <CJK>
+0xB6AB	0x9672	# <CJK>
+0xB6AC	0x9684	# <CJK>
+0xB6AD	0x96C1	# <CJK>
+0xB6AE	0x96C5	# <CJK>
+0xB6AF	0x96C4	# <CJK>
+0xB6B0	0x96C6	# <CJK>
+0xB6B1	0x96C7	# <CJK>
+0xB6B2	0x96EF	# <CJK>
+0xB6B3	0x96F2	# <CJK>
+0xB6B4	0x97CC	# <CJK>
+0xB6B5	0x9805	# <CJK>
+0xB6B6	0x9806	# <CJK>
+0xB6B7	0x9808	# <CJK>
+0xB6B8	0x98E7	# <CJK>
+0xB6B9	0x98EA	# <CJK>
+0xB6BA	0x98EF	# <CJK>
+0xB6BB	0x98E9	# <CJK>
+0xB6BC	0x98F2	# <CJK>
+0xB6BD	0x98ED	# <CJK>
+0xB6BE	0x99AE	# <CJK>
+0xB6BF	0x99AD	# <CJK>
+0xB6C0	0x9EC3	# <CJK>
+0xB6C1	0x9ECD	# <CJK>
+0xB6C2	0x9ED1	# <CJK>
+0xB6C3	0x4E82	# <CJK>
+0xB6C4	0x50AD	# <CJK>
+0xB6C5	0x50B5	# <CJK>
+0xB6C6	0x50B2	# <CJK>
+0xB6C7	0x50B3	# <CJK>
+0xB6C8	0x50C5	# <CJK>
+0xB6C9	0x50BE	# <CJK>
+0xB6CA	0x50AC	# <CJK>
+0xB6CB	0x50B7	# <CJK>
+0xB6CC	0x50BB	# <CJK>
+0xB6CD	0x50AF	# <CJK>
+0xB6CE	0x50C7	# <CJK>
+0xB6CF	0x527F	# <CJK>
+0xB6D0	0x5277	# <CJK>
+0xB6D1	0x527D	# <CJK>
+0xB6D2	0x52DF	# <CJK>
+0xB6D3	0x52E6	# <CJK>
+0xB6D4	0x52E4	# <CJK>
+0xB6D5	0x52E2	# <CJK>
+0xB6D6	0x52E3	# <CJK>
+0xB6D7	0x532F	# <CJK>
+0xB6D8	0x55DF	# <CJK>
+0xB6D9	0x55E8	# <CJK>
+0xB6DA	0x55D3	# <CJK>
+0xB6DB	0x55E6	# <CJK>
+0xB6DC	0x55CE	# <CJK>
+0xB6DD	0x55DC	# <CJK>
+0xB6DE	0x55C7	# <CJK>
+0xB6DF	0x55D1	# <CJK>
+0xB6E0	0x55E3	# <CJK>
+0xB6E1	0x55E4	# <CJK>
+0xB6E2	0x55EF	# <CJK>
+0xB6E3	0x55DA	# <CJK>
+0xB6E4	0x55E1	# <CJK>
+0xB6E5	0x55C5	# <CJK>
+0xB6E6	0x55C6	# <CJK>
+0xB6E7	0x55E5	# <CJK>
+0xB6E8	0x55C9	# <CJK>
+0xB6E9	0x5712	# <CJK>
+0xB6EA	0x5713	# <CJK>
+0xB6EB	0x585E	# <CJK>
+0xB6EC	0x5851	# <CJK>
+0xB6ED	0x5858	# <CJK>
+0xB6EE	0x5857	# <CJK>
+0xB6EF	0x585A	# <CJK>
+0xB6F0	0x5854	# <CJK>
+0xB6F1	0x586B	# <CJK>
+0xB6F2	0x584C	# <CJK>
+0xB6F3	0x586D	# <CJK>
+0xB6F4	0x584A	# <CJK>
+0xB6F5	0x5862	# <CJK>
+0xB6F6	0x5852	# <CJK>
+0xB6F7	0x584B	# <CJK>
+0xB6F8	0x5967	# <CJK>
+0xB6F9	0x5AC1	# <CJK>
+0xB6FA	0x5AC9	# <CJK>
+0xB6FB	0x5ACC	# <CJK>
+0xB6FC	0x5ABE	# <CJK>
+0xB6FD	0x5ABD	# <CJK>
+0xB6FE	0x5ABC	# <CJK>
+0xB740	0x5AB3	# <CJK>
+0xB741	0x5AC2	# <CJK>
+0xB742	0x5AB2	# <CJK>
+0xB743	0x5D69	# <CJK>
+0xB744	0x5D6F	# <CJK>
+0xB745	0x5E4C	# <CJK>
+0xB746	0x5E79	# <CJK>
+0xB747	0x5EC9	# <CJK>
+0xB748	0x5EC8	# <CJK>
+0xB749	0x5F12	# <CJK>
+0xB74A	0x5F59	# <CJK>
+0xB74B	0x5FAC	# <CJK>
+0xB74C	0x5FAE	# <CJK>
+0xB74D	0x611A	# <CJK>
+0xB74E	0x610F	# <CJK>
+0xB74F	0x6148	# <CJK>
+0xB750	0x611F	# <CJK>
+0xB751	0x60F3	# <CJK>
+0xB752	0x611B	# <CJK>
+0xB753	0x60F9	# <CJK>
+0xB754	0x6101	# <CJK>
+0xB755	0x6108	# <CJK>
+0xB756	0x614E	# <CJK>
+0xB757	0x614C	# <CJK>
+0xB758	0x6144	# <CJK>
+0xB759	0x614D	# <CJK>
+0xB75A	0x613E	# <CJK>
+0xB75B	0x6134	# <CJK>
+0xB75C	0x6127	# <CJK>
+0xB75D	0x610D	# <CJK>
+0xB75E	0x6106	# <CJK>
+0xB75F	0x6137	# <CJK>
+0xB760	0x6221	# <CJK>
+0xB761	0x6222	# <CJK>
+0xB762	0x6413	# <CJK>
+0xB763	0x643E	# <CJK>
+0xB764	0x641E	# <CJK>
+0xB765	0x642A	# <CJK>
+0xB766	0x642D	# <CJK>
+0xB767	0x643D	# <CJK>
+0xB768	0x642C	# <CJK>
+0xB769	0x640F	# <CJK>
+0xB76A	0x641C	# <CJK>
+0xB76B	0x6414	# <CJK>
+0xB76C	0x640D	# <CJK>
+0xB76D	0x6436	# <CJK>
+0xB76E	0x6416	# <CJK>
+0xB76F	0x6417	# <CJK>
+0xB770	0x6406	# <CJK>
+0xB771	0x656C	# <CJK>
+0xB772	0x659F	# <CJK>
+0xB773	0x65B0	# <CJK>
+0xB774	0x6697	# <CJK>
+0xB775	0x6689	# <CJK>
+0xB776	0x6687	# <CJK>
+0xB777	0x6688	# <CJK>
+0xB778	0x6696	# <CJK>
+0xB779	0x6684	# <CJK>
+0xB77A	0x6698	# <CJK>
+0xB77B	0x668D	# <CJK>
+0xB77C	0x6703	# <CJK>
+0xB77D	0x6994	# <CJK>
+0xB77E	0x696D	# <CJK>
+0xB7A1	0x695A	# <CJK>
+0xB7A2	0x6977	# <CJK>
+0xB7A3	0x6960	# <CJK>
+0xB7A4	0x6954	# <CJK>
+0xB7A5	0x6975	# <CJK>
+0xB7A6	0x6930	# <CJK>
+0xB7A7	0x6982	# <CJK>
+0xB7A8	0x694A	# <CJK>
+0xB7A9	0x6968	# <CJK>
+0xB7AA	0x696B	# <CJK>
+0xB7AB	0x695E	# <CJK>
+0xB7AC	0x6953	# <CJK>
+0xB7AD	0x6979	# <CJK>
+0xB7AE	0x6986	# <CJK>
+0xB7AF	0x695D	# <CJK>
+0xB7B0	0x6963	# <CJK>
+0xB7B1	0x695B	# <CJK>
+0xB7B2	0x6B47	# <CJK>
+0xB7B3	0x6B72	# <CJK>
+0xB7B4	0x6BC0	# <CJK>
+0xB7B5	0x6BBF	# <CJK>
+0xB7B6	0x6BD3	# <CJK>
+0xB7B7	0x6BFD	# <CJK>
+0xB7B8	0x6EA2	# <CJK>
+0xB7B9	0x6EAF	# <CJK>
+0xB7BA	0x6ED3	# <CJK>
+0xB7BB	0x6EB6	# <CJK>
+0xB7BC	0x6EC2	# <CJK>
+0xB7BD	0x6E90	# <CJK>
+0xB7BE	0x6E9D	# <CJK>
+0xB7BF	0x6EC7	# <CJK>
+0xB7C0	0x6EC5	# <CJK>
+0xB7C1	0x6EA5	# <CJK>
+0xB7C2	0x6E98	# <CJK>
+0xB7C3	0x6EBC	# <CJK>
+0xB7C4	0x6EBA	# <CJK>
+0xB7C5	0x6EAB	# <CJK>
+0xB7C6	0x6ED1	# <CJK>
+0xB7C7	0x6E96	# <CJK>
+0xB7C8	0x6E9C	# <CJK>
+0xB7C9	0x6EC4	# <CJK>
+0xB7CA	0x6ED4	# <CJK>
+0xB7CB	0x6EAA	# <CJK>
+0xB7CC	0x6EA7	# <CJK>
+0xB7CD	0x6EB4	# <CJK>
+0xB7CE	0x714E	# <CJK>
+0xB7CF	0x7159	# <CJK>
+0xB7D0	0x7169	# <CJK>
+0xB7D1	0x7164	# <CJK>
+0xB7D2	0x7149	# <CJK>
+0xB7D3	0x7167	# <CJK>
+0xB7D4	0x715C	# <CJK>
+0xB7D5	0x716C	# <CJK>
+0xB7D6	0x7166	# <CJK>
+0xB7D7	0x714C	# <CJK>
+0xB7D8	0x7165	# <CJK>
+0xB7D9	0x715E	# <CJK>
+0xB7DA	0x7146	# <CJK>
+0xB7DB	0x7168	# <CJK>
+0xB7DC	0x7156	# <CJK>
+0xB7DD	0x723A	# <CJK>
+0xB7DE	0x7252	# <CJK>
+0xB7DF	0x7337	# <CJK>
+0xB7E0	0x7345	# <CJK>
+0xB7E1	0x733F	# <CJK>
+0xB7E2	0x733E	# <CJK>
+0xB7E3	0x746F	# <CJK>
+0xB7E4	0x745A	# <CJK>
+0xB7E5	0x7455	# <CJK>
+0xB7E6	0x745F	# <CJK>
+0xB7E7	0x745E	# <CJK>
+0xB7E8	0x7441	# <CJK>
+0xB7E9	0x743F	# <CJK>
+0xB7EA	0x7459	# <CJK>
+0xB7EB	0x745B	# <CJK>
+0xB7EC	0x745C	# <CJK>
+0xB7ED	0x7576	# <CJK>
+0xB7EE	0x7578	# <CJK>
+0xB7EF	0x7600	# <CJK>
+0xB7F0	0x75F0	# <CJK>
+0xB7F1	0x7601	# <CJK>
+0xB7F2	0x75F2	# <CJK>
+0xB7F3	0x75F1	# <CJK>
+0xB7F4	0x75FA	# <CJK>
+0xB7F5	0x75FF	# <CJK>
+0xB7F6	0x75F4	# <CJK>
+0xB7F7	0x75F3	# <CJK>
+0xB7F8	0x76DE	# <CJK>
+0xB7F9	0x76DF	# <CJK>
+0xB7FA	0x775B	# <CJK>
+0xB7FB	0x776B	# <CJK>
+0xB7FC	0x7766	# <CJK>
+0xB7FD	0x775E	# <CJK>
+0xB7FE	0x7763	# <CJK>
+0xB840	0x7779	# <CJK>
+0xB841	0x776A	# <CJK>
+0xB842	0x776C	# <CJK>
+0xB843	0x775C	# <CJK>
+0xB844	0x7765	# <CJK>
+0xB845	0x7768	# <CJK>
+0xB846	0x7762	# <CJK>
+0xB847	0x77EE	# <CJK>
+0xB848	0x788E	# <CJK>
+0xB849	0x78B0	# <CJK>
+0xB84A	0x7897	# <CJK>
+0xB84B	0x7898	# <CJK>
+0xB84C	0x788C	# <CJK>
+0xB84D	0x7889	# <CJK>
+0xB84E	0x787C	# <CJK>
+0xB84F	0x7891	# <CJK>
+0xB850	0x7893	# <CJK>
+0xB851	0x787F	# <CJK>
+0xB852	0x797A	# <CJK>
+0xB853	0x797F	# <CJK>
+0xB854	0x7981	# <CJK>
+0xB855	0x842C	# <CJK>
+0xB856	0x79BD	# <CJK>
+0xB857	0x7A1C	# <CJK>
+0xB858	0x7A1A	# <CJK>
+0xB859	0x7A20	# <CJK>
+0xB85A	0x7A14	# <CJK>
+0xB85B	0x7A1F	# <CJK>
+0xB85C	0x7A1E	# <CJK>
+0xB85D	0x7A9F	# <CJK>
+0xB85E	0x7AA0	# <CJK>
+0xB85F	0x7B77	# <CJK>
+0xB860	0x7BC0	# <CJK>
+0xB861	0x7B60	# <CJK>
+0xB862	0x7B6E	# <CJK>
+0xB863	0x7B67	# <CJK>
+0xB864	0x7CB1	# <CJK>
+0xB865	0x7CB3	# <CJK>
+0xB866	0x7CB5	# <CJK>
+0xB867	0x7D93	# <CJK>
+0xB868	0x7D79	# <CJK>
+0xB869	0x7D91	# <CJK>
+0xB86A	0x7D81	# <CJK>
+0xB86B	0x7D8F	# <CJK>
+0xB86C	0x7D5B	# <CJK>
+0xB86D	0x7F6E	# <CJK>
+0xB86E	0x7F69	# <CJK>
+0xB86F	0x7F6A	# <CJK>
+0xB870	0x7F72	# <CJK>
+0xB871	0x7FA9	# <CJK>
+0xB872	0x7FA8	# <CJK>
+0xB873	0x7FA4	# <CJK>
+0xB874	0x8056	# <CJK>
+0xB875	0x8058	# <CJK>
+0xB876	0x8086	# <CJK>
+0xB877	0x8084	# <CJK>
+0xB878	0x8171	# <CJK>
+0xB879	0x8170	# <CJK>
+0xB87A	0x8178	# <CJK>
+0xB87B	0x8165	# <CJK>
+0xB87C	0x816E	# <CJK>
+0xB87D	0x8173	# <CJK>
+0xB87E	0x816B	# <CJK>
+0xB8A1	0x8179	# <CJK>
+0xB8A2	0x817A	# <CJK>
+0xB8A3	0x8166	# <CJK>
+0xB8A4	0x8205	# <CJK>
+0xB8A5	0x8247	# <CJK>
+0xB8A6	0x8482	# <CJK>
+0xB8A7	0x8477	# <CJK>
+0xB8A8	0x843D	# <CJK>
+0xB8A9	0x8431	# <CJK>
+0xB8AA	0x8475	# <CJK>
+0xB8AB	0x8466	# <CJK>
+0xB8AC	0x846B	# <CJK>
+0xB8AD	0x8449	# <CJK>
+0xB8AE	0x846C	# <CJK>
+0xB8AF	0x845B	# <CJK>
+0xB8B0	0x843C	# <CJK>
+0xB8B1	0x8435	# <CJK>
+0xB8B2	0x8461	# <CJK>
+0xB8B3	0x8463	# <CJK>
+0xB8B4	0x8469	# <CJK>
+0xB8B5	0x846D	# <CJK>
+0xB8B6	0x8446	# <CJK>
+0xB8B7	0x865E	# <CJK>
+0xB8B8	0x865C	# <CJK>
+0xB8B9	0x865F	# <CJK>
+0xB8BA	0x86F9	# <CJK>
+0xB8BB	0x8713	# <CJK>
+0xB8BC	0x8708	# <CJK>
+0xB8BD	0x8707	# <CJK>
+0xB8BE	0x8700	# <CJK>
+0xB8BF	0x86FE	# <CJK>
+0xB8C0	0x86FB	# <CJK>
+0xB8C1	0x8702	# <CJK>
+0xB8C2	0x8703	# <CJK>
+0xB8C3	0x8706	# <CJK>
+0xB8C4	0x870A	# <CJK>
+0xB8C5	0x8859	# <CJK>
+0xB8C6	0x88DF	# <CJK>
+0xB8C7	0x88D4	# <CJK>
+0xB8C8	0x88D9	# <CJK>
+0xB8C9	0x88DC	# <CJK>
+0xB8CA	0x88D8	# <CJK>
+0xB8CB	0x88DD	# <CJK>
+0xB8CC	0x88E1	# <CJK>
+0xB8CD	0x88CA	# <CJK>
+0xB8CE	0x88D5	# <CJK>
+0xB8CF	0x88D2	# <CJK>
+0xB8D0	0x899C	# <CJK>
+0xB8D1	0x89E3	# <CJK>
+0xB8D2	0x8A6B	# <CJK>
+0xB8D3	0x8A72	# <CJK>
+0xB8D4	0x8A73	# <CJK>
+0xB8D5	0x8A66	# <CJK>
+0xB8D6	0x8A69	# <CJK>
+0xB8D7	0x8A70	# <CJK>
+0xB8D8	0x8A87	# <CJK>
+0xB8D9	0x8A7C	# <CJK>
+0xB8DA	0x8A63	# <CJK>
+0xB8DB	0x8AA0	# <CJK>
+0xB8DC	0x8A71	# <CJK>
+0xB8DD	0x8A85	# <CJK>
+0xB8DE	0x8A6D	# <CJK>
+0xB8DF	0x8A62	# <CJK>
+0xB8E0	0x8A6E	# <CJK>
+0xB8E1	0x8A6C	# <CJK>
+0xB8E2	0x8A79	# <CJK>
+0xB8E3	0x8A7B	# <CJK>
+0xB8E4	0x8A3E	# <CJK>
+0xB8E5	0x8A68	# <CJK>
+0xB8E6	0x8C62	# <CJK>
+0xB8E7	0x8C8A	# <CJK>
+0xB8E8	0x8C89	# <CJK>
+0xB8E9	0x8CCA	# <CJK>
+0xB8EA	0x8CC7	# <CJK>
+0xB8EB	0x8CC8	# <CJK>
+0xB8EC	0x8CC4	# <CJK>
+0xB8ED	0x8CB2	# <CJK>
+0xB8EE	0x8CC3	# <CJK>
+0xB8EF	0x8CC2	# <CJK>
+0xB8F0	0x8CC5	# <CJK>
+0xB8F1	0x8DE1	# <CJK>
+0xB8F2	0x8DDF	# <CJK>
+0xB8F3	0x8DE8	# <CJK>
+0xB8F4	0x8DEF	# <CJK>
+0xB8F5	0x8DF3	# <CJK>
+0xB8F6	0x8DFA	# <CJK>
+0xB8F7	0x8DEA	# <CJK>
+0xB8F8	0x8DE4	# <CJK>
+0xB8F9	0x8DE6	# <CJK>
+0xB8FA	0x8EB2	# <CJK>
+0xB8FB	0x8F03	# <CJK>
+0xB8FC	0x8F09	# <CJK>
+0xB8FD	0x8EFE	# <CJK>
+0xB8FE	0x8F0A	# <CJK>
+0xB940	0x8F9F	# <CJK>
+0xB941	0x8FB2	# <CJK>
+0xB942	0x904B	# <CJK>
+0xB943	0x904A	# <CJK>
+0xB944	0x9053	# <CJK>
+0xB945	0x9042	# <CJK>
+0xB946	0x9054	# <CJK>
+0xB947	0x903C	# <CJK>
+0xB948	0x9055	# <CJK>
+0xB949	0x9050	# <CJK>
+0xB94A	0x9047	# <CJK>
+0xB94B	0x904F	# <CJK>
+0xB94C	0x904E	# <CJK>
+0xB94D	0x904D	# <CJK>
+0xB94E	0x9051	# <CJK>
+0xB94F	0x903E	# <CJK>
+0xB950	0x9041	# <CJK>
+0xB951	0x9112	# <CJK>
+0xB952	0x9117	# <CJK>
+0xB953	0x916C	# <CJK>
+0xB954	0x916A	# <CJK>
+0xB955	0x9169	# <CJK>
+0xB956	0x91C9	# <CJK>
+0xB957	0x9237	# <CJK>
+0xB958	0x9257	# <CJK>
+0xB959	0x9238	# <CJK>
+0xB95A	0x923D	# <CJK>
+0xB95B	0x9240	# <CJK>
+0xB95C	0x923E	# <CJK>
+0xB95D	0x925B	# <CJK>
+0xB95E	0x924B	# <CJK>
+0xB95F	0x9264	# <CJK>
+0xB960	0x9251	# <CJK>
+0xB961	0x9234	# <CJK>
+0xB962	0x9249	# <CJK>
+0xB963	0x924D	# <CJK>
+0xB964	0x9245	# <CJK>
+0xB965	0x9239	# <CJK>
+0xB966	0x923F	# <CJK>
+0xB967	0x925A	# <CJK>
+0xB968	0x9598	# <CJK>
+0xB969	0x9698	# <CJK>
+0xB96A	0x9694	# <CJK>
+0xB96B	0x9695	# <CJK>
+0xB96C	0x96CD	# <CJK>
+0xB96D	0x96CB	# <CJK>
+0xB96E	0x96C9	# <CJK>
+0xB96F	0x96CA	# <CJK>
+0xB970	0x96F7	# <CJK>
+0xB971	0x96FB	# <CJK>
+0xB972	0x96F9	# <CJK>
+0xB973	0x96F6	# <CJK>
+0xB974	0x9756	# <CJK>
+0xB975	0x9774	# <CJK>
+0xB976	0x9776	# <CJK>
+0xB977	0x9810	# <CJK>
+0xB978	0x9811	# <CJK>
+0xB979	0x9813	# <CJK>
+0xB97A	0x980A	# <CJK>
+0xB97B	0x9812	# <CJK>
+0xB97C	0x980C	# <CJK>
+0xB97D	0x98FC	# <CJK>
+0xB97E	0x98F4	# <CJK>
+0xB9A1	0x98FD	# <CJK>
+0xB9A2	0x98FE	# <CJK>
+0xB9A3	0x99B3	# <CJK>
+0xB9A4	0x99B1	# <CJK>
+0xB9A5	0x99B4	# <CJK>
+0xB9A6	0x9AE1	# <CJK>
+0xB9A7	0x9CE9	# <CJK>
+0xB9A8	0x9E82	# <CJK>
+0xB9A9	0x9F0E	# <CJK>
+0xB9AA	0x9F13	# <CJK>
+0xB9AB	0x9F20	# <CJK>
+0xB9AC	0x50E7	# <CJK>
+0xB9AD	0x50EE	# <CJK>
+0xB9AE	0x50E5	# <CJK>
+0xB9AF	0x50D6	# <CJK>
+0xB9B0	0x50ED	# <CJK>
+0xB9B1	0x50DA	# <CJK>
+0xB9B2	0x50D5	# <CJK>
+0xB9B3	0x50CF	# <CJK>
+0xB9B4	0x50D1	# <CJK>
+0xB9B5	0x50F1	# <CJK>
+0xB9B6	0x50CE	# <CJK>
+0xB9B7	0x50E9	# <CJK>
+0xB9B8	0x5162	# <CJK>
+0xB9B9	0x51F3	# <CJK>
+0xB9BA	0x5283	# <CJK>
+0xB9BB	0x5282	# <CJK>
+0xB9BC	0x5331	# <CJK>
+0xB9BD	0x53AD	# <CJK>
+0xB9BE	0x55FE	# <CJK>
+0xB9BF	0x5600	# <CJK>
+0xB9C0	0x561B	# <CJK>
+0xB9C1	0x5617	# <CJK>
+0xB9C2	0x55FD	# <CJK>
+0xB9C3	0x5614	# <CJK>
+0xB9C4	0x5606	# <CJK>
+0xB9C5	0x5609	# <CJK>
+0xB9C6	0x560D	# <CJK>
+0xB9C7	0x560E	# <CJK>
+0xB9C8	0x55F7	# <CJK>
+0xB9C9	0x5616	# <CJK>
+0xB9CA	0x561F	# <CJK>
+0xB9CB	0x5608	# <CJK>
+0xB9CC	0x5610	# <CJK>
+0xB9CD	0x55F6	# <CJK>
+0xB9CE	0x5718	# <CJK>
+0xB9CF	0x5716	# <CJK>
+0xB9D0	0x5875	# <CJK>
+0xB9D1	0x587E	# <CJK>
+0xB9D2	0x5883	# <CJK>
+0xB9D3	0x5893	# <CJK>
+0xB9D4	0x588A	# <CJK>
+0xB9D5	0x5879	# <CJK>
+0xB9D6	0x5885	# <CJK>
+0xB9D7	0x587D	# <CJK>
+0xB9D8	0x58FD	# <CJK>
+0xB9D9	0x5925	# <CJK>
+0xB9DA	0x5922	# <CJK>
+0xB9DB	0x5924	# <CJK>
+0xB9DC	0x596A	# <CJK>
+0xB9DD	0x5969	# <CJK>
+0xB9DE	0x5AE1	# <CJK>
+0xB9DF	0x5AE6	# <CJK>
+0xB9E0	0x5AE9	# <CJK>
+0xB9E1	0x5AD7	# <CJK>
+0xB9E2	0x5AD6	# <CJK>
+0xB9E3	0x5AD8	# <CJK>
+0xB9E4	0x5AE3	# <CJK>
+0xB9E5	0x5B75	# <CJK>
+0xB9E6	0x5BDE	# <CJK>
+0xB9E7	0x5BE7	# <CJK>
+0xB9E8	0x5BE1	# <CJK>
+0xB9E9	0x5BE5	# <CJK>
+0xB9EA	0x5BE6	# <CJK>
+0xB9EB	0x5BE8	# <CJK>
+0xB9EC	0x5BE2	# <CJK>
+0xB9ED	0x5BE4	# <CJK>
+0xB9EE	0x5BDF	# <CJK>
+0xB9EF	0x5C0D	# <CJK>
+0xB9F0	0x5C62	# <CJK>
+0xB9F1	0x5D84	# <CJK>
+0xB9F2	0x5D87	# <CJK>
+0xB9F3	0x5E5B	# <CJK>
+0xB9F4	0x5E63	# <CJK>
+0xB9F5	0x5E55	# <CJK>
+0xB9F6	0x5E57	# <CJK>
+0xB9F7	0x5E54	# <CJK>
+0xB9F8	0x5ED3	# <CJK>
+0xB9F9	0x5ED6	# <CJK>
+0xB9FA	0x5F0A	# <CJK>
+0xB9FB	0x5F46	# <CJK>
+0xB9FC	0x5F70	# <CJK>
+0xB9FD	0x5FB9	# <CJK>
+0xB9FE	0x6147	# <CJK>
+0xBA40	0x613F	# <CJK>
+0xBA41	0x614B	# <CJK>
+0xBA42	0x6177	# <CJK>
+0xBA43	0x6162	# <CJK>
+0xBA44	0x6163	# <CJK>
+0xBA45	0x615F	# <CJK>
+0xBA46	0x615A	# <CJK>
+0xBA47	0x6158	# <CJK>
+0xBA48	0x6175	# <CJK>
+0xBA49	0x622A	# <CJK>
+0xBA4A	0x6487	# <CJK>
+0xBA4B	0x6458	# <CJK>
+0xBA4C	0x6454	# <CJK>
+0xBA4D	0x64A4	# <CJK>
+0xBA4E	0x6478	# <CJK>
+0xBA4F	0x645F	# <CJK>
+0xBA50	0x647A	# <CJK>
+0xBA51	0x6451	# <CJK>
+0xBA52	0x6467	# <CJK>
+0xBA53	0x6434	# <CJK>
+0xBA54	0x646D	# <CJK>
+0xBA55	0x647B	# <CJK>
+0xBA56	0x6572	# <CJK>
+0xBA57	0x65A1	# <CJK>
+0xBA58	0x65D7	# <CJK>
+0xBA59	0x65D6	# <CJK>
+0xBA5A	0x66A2	# <CJK>
+0xBA5B	0x66A8	# <CJK>
+0xBA5C	0x669D	# <CJK>
+0xBA5D	0x699C	# <CJK>
+0xBA5E	0x69A8	# <CJK>
+0xBA5F	0x6995	# <CJK>
+0xBA60	0x69C1	# <CJK>
+0xBA61	0x69AE	# <CJK>
+0xBA62	0x69D3	# <CJK>
+0xBA63	0x69CB	# <CJK>
+0xBA64	0x699B	# <CJK>
+0xBA65	0x69B7	# <CJK>
+0xBA66	0x69BB	# <CJK>
+0xBA67	0x69AB	# <CJK>
+0xBA68	0x69B4	# <CJK>
+0xBA69	0x69D0	# <CJK>
+0xBA6A	0x69CD	# <CJK>
+0xBA6B	0x69AD	# <CJK>
+0xBA6C	0x69CC	# <CJK>
+0xBA6D	0x69A6	# <CJK>
+0xBA6E	0x69C3	# <CJK>
+0xBA6F	0x69A3	# <CJK>
+0xBA70	0x6B49	# <CJK>
+0xBA71	0x6B4C	# <CJK>
+0xBA72	0x6C33	# <CJK>
+0xBA73	0x6F33	# <CJK>
+0xBA74	0x6F14	# <CJK>
+0xBA75	0x6EFE	# <CJK>
+0xBA76	0x6F13	# <CJK>
+0xBA77	0x6EF4	# <CJK>
+0xBA78	0x6F29	# <CJK>
+0xBA79	0x6F3E	# <CJK>
+0xBA7A	0x6F20	# <CJK>
+0xBA7B	0x6F2C	# <CJK>
+0xBA7C	0x6F0F	# <CJK>
+0xBA7D	0x6F02	# <CJK>
+0xBA7E	0x6F22	# <CJK>
+0xBAA1	0x6EFF	# <CJK>
+0xBAA2	0x6EEF	# <CJK>
+0xBAA3	0x6F06	# <CJK>
+0xBAA4	0x6F31	# <CJK>
+0xBAA5	0x6F38	# <CJK>
+0xBAA6	0x6F32	# <CJK>
+0xBAA7	0x6F23	# <CJK>
+0xBAA8	0x6F15	# <CJK>
+0xBAA9	0x6F2B	# <CJK>
+0xBAAA	0x6F2F	# <CJK>
+0xBAAB	0x6F88	# <CJK>
+0xBAAC	0x6F2A	# <CJK>
+0xBAAD	0x6EEC	# <CJK>
+0xBAAE	0x6F01	# <CJK>
+0xBAAF	0x6EF2	# <CJK>
+0xBAB0	0x6ECC	# <CJK>
+0xBAB1	0x6EF7	# <CJK>
+0xBAB2	0x7194	# <CJK>
+0xBAB3	0x7199	# <CJK>
+0xBAB4	0x717D	# <CJK>
+0xBAB5	0x718A	# <CJK>
+0xBAB6	0x7184	# <CJK>
+0xBAB7	0x7192	# <CJK>
+0xBAB8	0x723E	# <CJK>
+0xBAB9	0x7292	# <CJK>
+0xBABA	0x7296	# <CJK>
+0xBABB	0x7344	# <CJK>
+0xBABC	0x7350	# <CJK>
+0xBABD	0x7464	# <CJK>
+0xBABE	0x7463	# <CJK>
+0xBABF	0x746A	# <CJK>
+0xBAC0	0x7470	# <CJK>
+0xBAC1	0x746D	# <CJK>
+0xBAC2	0x7504	# <CJK>
+0xBAC3	0x7591	# <CJK>
+0xBAC4	0x7627	# <CJK>
+0xBAC5	0x760D	# <CJK>
+0xBAC6	0x760B	# <CJK>
+0xBAC7	0x7609	# <CJK>
+0xBAC8	0x7613	# <CJK>
+0xBAC9	0x76E1	# <CJK>
+0xBACA	0x76E3	# <CJK>
+0xBACB	0x7784	# <CJK>
+0xBACC	0x777D	# <CJK>
+0xBACD	0x777F	# <CJK>
+0xBACE	0x7761	# <CJK>
+0xBACF	0x78C1	# <CJK>
+0xBAD0	0x789F	# <CJK>
+0xBAD1	0x78A7	# <CJK>
+0xBAD2	0x78B3	# <CJK>
+0xBAD3	0x78A9	# <CJK>
+0xBAD4	0x78A3	# <CJK>
+0xBAD5	0x798E	# <CJK>
+0xBAD6	0x798F	# <CJK>
+0xBAD7	0x798D	# <CJK>
+0xBAD8	0x7A2E	# <CJK>
+0xBAD9	0x7A31	# <CJK>
+0xBADA	0x7AAA	# <CJK>
+0xBADB	0x7AA9	# <CJK>
+0xBADC	0x7AED	# <CJK>
+0xBADD	0x7AEF	# <CJK>
+0xBADE	0x7BA1	# <CJK>
+0xBADF	0x7B95	# <CJK>
+0xBAE0	0x7B8B	# <CJK>
+0xBAE1	0x7B75	# <CJK>
+0xBAE2	0x7B97	# <CJK>
+0xBAE3	0x7B9D	# <CJK>
+0xBAE4	0x7B94	# <CJK>
+0xBAE5	0x7B8F	# <CJK>
+0xBAE6	0x7BB8	# <CJK>
+0xBAE7	0x7B87	# <CJK>
+0xBAE8	0x7B84	# <CJK>
+0xBAE9	0x7CB9	# <CJK>
+0xBAEA	0x7CBD	# <CJK>
+0xBAEB	0x7CBE	# <CJK>
+0xBAEC	0x7DBB	# <CJK>
+0xBAED	0x7DB0	# <CJK>
+0xBAEE	0x7D9C	# <CJK>
+0xBAEF	0x7DBD	# <CJK>
+0xBAF0	0x7DBE	# <CJK>
+0xBAF1	0x7DA0	# <CJK>
+0xBAF2	0x7DCA	# <CJK>
+0xBAF3	0x7DB4	# <CJK>
+0xBAF4	0x7DB2	# <CJK>
+0xBAF5	0x7DB1	# <CJK>
+0xBAF6	0x7DBA	# <CJK>
+0xBAF7	0x7DA2	# <CJK>
+0xBAF8	0x7DBF	# <CJK>
+0xBAF9	0x7DB5	# <CJK>
+0xBAFA	0x7DB8	# <CJK>
+0xBAFB	0x7DAD	# <CJK>
+0xBAFC	0x7DD2	# <CJK>
+0xBAFD	0x7DC7	# <CJK>
+0xBAFE	0x7DAC	# <CJK>
+0xBB40	0x7F70	# <CJK>
+0xBB41	0x7FE0	# <CJK>
+0xBB42	0x7FE1	# <CJK>
+0xBB43	0x7FDF	# <CJK>
+0xBB44	0x805E	# <CJK>
+0xBB45	0x805A	# <CJK>
+0xBB46	0x8087	# <CJK>
+0xBB47	0x8150	# <CJK>
+0xBB48	0x8180	# <CJK>
+0xBB49	0x818F	# <CJK>
+0xBB4A	0x8188	# <CJK>
+0xBB4B	0x818A	# <CJK>
+0xBB4C	0x817F	# <CJK>
+0xBB4D	0x8182	# <CJK>
+0xBB4E	0x81E7	# <CJK>
+0xBB4F	0x81FA	# <CJK>
+0xBB50	0x8207	# <CJK>
+0xBB51	0x8214	# <CJK>
+0xBB52	0x821E	# <CJK>
+0xBB53	0x824B	# <CJK>
+0xBB54	0x84C9	# <CJK>
+0xBB55	0x84BF	# <CJK>
+0xBB56	0x84C6	# <CJK>
+0xBB57	0x84C4	# <CJK>
+0xBB58	0x8499	# <CJK>
+0xBB59	0x849E	# <CJK>
+0xBB5A	0x84B2	# <CJK>
+0xBB5B	0x849C	# <CJK>
+0xBB5C	0x84CB	# <CJK>
+0xBB5D	0x84B8	# <CJK>
+0xBB5E	0x84C0	# <CJK>
+0xBB5F	0x84D3	# <CJK>
+0xBB60	0x8490	# <CJK>
+0xBB61	0x84BC	# <CJK>
+0xBB62	0x84D1	# <CJK>
+0xBB63	0x84CA	# <CJK>
+0xBB64	0x873F	# <CJK>
+0xBB65	0x871C	# <CJK>
+0xBB66	0x873B	# <CJK>
+0xBB67	0x8722	# <CJK>
+0xBB68	0x8725	# <CJK>
+0xBB69	0x8734	# <CJK>
+0xBB6A	0x8718	# <CJK>
+0xBB6B	0x8755	# <CJK>
+0xBB6C	0x8737	# <CJK>
+0xBB6D	0x8729	# <CJK>
+0xBB6E	0x88F3	# <CJK>
+0xBB6F	0x8902	# <CJK>
+0xBB70	0x88F4	# <CJK>
+0xBB71	0x88F9	# <CJK>
+0xBB72	0x88F8	# <CJK>
+0xBB73	0x88FD	# <CJK>
+0xBB74	0x88E8	# <CJK>
+0xBB75	0x891A	# <CJK>
+0xBB76	0x88EF	# <CJK>
+0xBB77	0x8AA6	# <CJK>
+0xBB78	0x8A8C	# <CJK>
+0xBB79	0x8A9E	# <CJK>
+0xBB7A	0x8AA3	# <CJK>
+0xBB7B	0x8A8D	# <CJK>
+0xBB7C	0x8AA1	# <CJK>
+0xBB7D	0x8A93	# <CJK>
+0xBB7E	0x8AA4	# <CJK>
+0xBBA1	0x8AAA	# <CJK>
+0xBBA2	0x8AA5	# <CJK>
+0xBBA3	0x8AA8	# <CJK>
+0xBBA4	0x8A98	# <CJK>
+0xBBA5	0x8A91	# <CJK>
+0xBBA6	0x8A9A	# <CJK>
+0xBBA7	0x8AA7	# <CJK>
+0xBBA8	0x8C6A	# <CJK>
+0xBBA9	0x8C8D	# <CJK>
+0xBBAA	0x8C8C	# <CJK>
+0xBBAB	0x8CD3	# <CJK>
+0xBBAC	0x8CD1	# <CJK>
+0xBBAD	0x8CD2	# <CJK>
+0xBBAE	0x8D6B	# <CJK>
+0xBBAF	0x8D99	# <CJK>
+0xBBB0	0x8D95	# <CJK>
+0xBBB1	0x8DFC	# <CJK>
+0xBBB2	0x8F14	# <CJK>
+0xBBB3	0x8F12	# <CJK>
+0xBBB4	0x8F15	# <CJK>
+0xBBB5	0x8F13	# <CJK>
+0xBBB6	0x8FA3	# <CJK>
+0xBBB7	0x9060	# <CJK>
+0xBBB8	0x9058	# <CJK>
+0xBBB9	0x905C	# <CJK>
+0xBBBA	0x9063	# <CJK>
+0xBBBB	0x9059	# <CJK>
+0xBBBC	0x905E	# <CJK>
+0xBBBD	0x9062	# <CJK>
+0xBBBE	0x905D	# <CJK>
+0xBBBF	0x905B	# <CJK>
+0xBBC0	0x9119	# <CJK>
+0xBBC1	0x9118	# <CJK>
+0xBBC2	0x911E	# <CJK>
+0xBBC3	0x9175	# <CJK>
+0xBBC4	0x9178	# <CJK>
+0xBBC5	0x9177	# <CJK>
+0xBBC6	0x9174	# <CJK>
+0xBBC7	0x9278	# <CJK>
+0xBBC8	0x9280	# <CJK>
+0xBBC9	0x9285	# <CJK>
+0xBBCA	0x9298	# <CJK>
+0xBBCB	0x9296	# <CJK>
+0xBBCC	0x927B	# <CJK>
+0xBBCD	0x9293	# <CJK>
+0xBBCE	0x929C	# <CJK>
+0xBBCF	0x92A8	# <CJK>
+0xBBD0	0x927C	# <CJK>
+0xBBD1	0x9291	# <CJK>
+0xBBD2	0x95A1	# <CJK>
+0xBBD3	0x95A8	# <CJK>
+0xBBD4	0x95A9	# <CJK>
+0xBBD5	0x95A3	# <CJK>
+0xBBD6	0x95A5	# <CJK>
+0xBBD7	0x95A4	# <CJK>
+0xBBD8	0x9699	# <CJK>
+0xBBD9	0x969C	# <CJK>
+0xBBDA	0x969B	# <CJK>
+0xBBDB	0x96CC	# <CJK>
+0xBBDC	0x96D2	# <CJK>
+0xBBDD	0x9700	# <CJK>
+0xBBDE	0x977C	# <CJK>
+0xBBDF	0x9785	# <CJK>
+0xBBE0	0x97F6	# <CJK>
+0xBBE1	0x9817	# <CJK>
+0xBBE2	0x9818	# <CJK>
+0xBBE3	0x98AF	# <CJK>
+0xBBE4	0x98B1	# <CJK>
+0xBBE5	0x9903	# <CJK>
+0xBBE6	0x9905	# <CJK>
+0xBBE7	0x990C	# <CJK>
+0xBBE8	0x9909	# <CJK>
+0xBBE9	0x99C1	# <CJK>
+0xBBEA	0x9AAF	# <CJK>
+0xBBEB	0x9AB0	# <CJK>
+0xBBEC	0x9AE6	# <CJK>
+0xBBED	0x9B41	# <CJK>
+0xBBEE	0x9B42	# <CJK>
+0xBBEF	0x9CF4	# <CJK>
+0xBBF0	0x9CF6	# <CJK>
+0xBBF1	0x9CF3	# <CJK>
+0xBBF2	0x9EBC	# <CJK>
+0xBBF3	0x9F3B	# <CJK>
+0xBBF4	0x9F4A	# <CJK>
+0xBBF5	0x5104	# <CJK>
+0xBBF6	0x5100	# <CJK>
+0xBBF7	0x50FB	# <CJK>
+0xBBF8	0x50F5	# <CJK>
+0xBBF9	0x50F9	# <CJK>
+0xBBFA	0x5102	# <CJK>
+0xBBFB	0x5108	# <CJK>
+0xBBFC	0x5109	# <CJK>
+0xBBFD	0x5105	# <CJK>
+0xBBFE	0x51DC	# <CJK>
+0xBC40	0x5287	# <CJK>
+0xBC41	0x5288	# <CJK>
+0xBC42	0x5289	# <CJK>
+0xBC43	0x528D	# <CJK>
+0xBC44	0x528A	# <CJK>
+0xBC45	0x52F0	# <CJK>
+0xBC46	0x53B2	# <CJK>
+0xBC47	0x562E	# <CJK>
+0xBC48	0x563B	# <CJK>
+0xBC49	0x5639	# <CJK>
+0xBC4A	0x5632	# <CJK>
+0xBC4B	0x563F	# <CJK>
+0xBC4C	0x5634	# <CJK>
+0xBC4D	0x5629	# <CJK>
+0xBC4E	0x5653	# <CJK>
+0xBC4F	0x564E	# <CJK>
+0xBC50	0x5657	# <CJK>
+0xBC51	0x5674	# <CJK>
+0xBC52	0x5636	# <CJK>
+0xBC53	0x562F	# <CJK>
+0xBC54	0x5630	# <CJK>
+0xBC55	0x5880	# <CJK>
+0xBC56	0x589F	# <CJK>
+0xBC57	0x589E	# <CJK>
+0xBC58	0x58B3	# <CJK>
+0xBC59	0x589C	# <CJK>
+0xBC5A	0x58AE	# <CJK>
+0xBC5B	0x58A9	# <CJK>
+0xBC5C	0x58A6	# <CJK>
+0xBC5D	0x596D	# <CJK>
+0xBC5E	0x5B09	# <CJK>
+0xBC5F	0x5AFB	# <CJK>
+0xBC60	0x5B0B	# <CJK>
+0xBC61	0x5AF5	# <CJK>
+0xBC62	0x5B0C	# <CJK>
+0xBC63	0x5B08	# <CJK>
+0xBC64	0x5BEE	# <CJK>
+0xBC65	0x5BEC	# <CJK>
+0xBC66	0x5BE9	# <CJK>
+0xBC67	0x5BEB	# <CJK>
+0xBC68	0x5C64	# <CJK>
+0xBC69	0x5C65	# <CJK>
+0xBC6A	0x5D9D	# <CJK>
+0xBC6B	0x5D94	# <CJK>
+0xBC6C	0x5E62	# <CJK>
+0xBC6D	0x5E5F	# <CJK>
+0xBC6E	0x5E61	# <CJK>
+0xBC6F	0x5EE2	# <CJK>
+0xBC70	0x5EDA	# <CJK>
+0xBC71	0x5EDF	# <CJK>
+0xBC72	0x5EDD	# <CJK>
+0xBC73	0x5EE3	# <CJK>
+0xBC74	0x5EE0	# <CJK>
+0xBC75	0x5F48	# <CJK>
+0xBC76	0x5F71	# <CJK>
+0xBC77	0x5FB7	# <CJK>
+0xBC78	0x5FB5	# <CJK>
+0xBC79	0x6176	# <CJK>
+0xBC7A	0x6167	# <CJK>
+0xBC7B	0x616E	# <CJK>
+0xBC7C	0x615D	# <CJK>
+0xBC7D	0x6155	# <CJK>
+0xBC7E	0x6182	# <CJK>
+0xBCA1	0x617C	# <CJK>
+0xBCA2	0x6170	# <CJK>
+0xBCA3	0x616B	# <CJK>
+0xBCA4	0x617E	# <CJK>
+0xBCA5	0x61A7	# <CJK>
+0xBCA6	0x6190	# <CJK>
+0xBCA7	0x61AB	# <CJK>
+0xBCA8	0x618E	# <CJK>
+0xBCA9	0x61AC	# <CJK>
+0xBCAA	0x619A	# <CJK>
+0xBCAB	0x61A4	# <CJK>
+0xBCAC	0x6194	# <CJK>
+0xBCAD	0x61AE	# <CJK>
+0xBCAE	0x622E	# <CJK>
+0xBCAF	0x6469	# <CJK>
+0xBCB0	0x646F	# <CJK>
+0xBCB1	0x6479	# <CJK>
+0xBCB2	0x649E	# <CJK>
+0xBCB3	0x64B2	# <CJK>
+0xBCB4	0x6488	# <CJK>
+0xBCB5	0x6490	# <CJK>
+0xBCB6	0x64B0	# <CJK>
+0xBCB7	0x64A5	# <CJK>
+0xBCB8	0x6493	# <CJK>
+0xBCB9	0x6495	# <CJK>
+0xBCBA	0x64A9	# <CJK>
+0xBCBB	0x6492	# <CJK>
+0xBCBC	0x64AE	# <CJK>
+0xBCBD	0x64AD	# <CJK>
+0xBCBE	0x64AB	# <CJK>
+0xBCBF	0x649A	# <CJK>
+0xBCC0	0x64AC	# <CJK>
+0xBCC1	0x6499	# <CJK>
+0xBCC2	0x64A2	# <CJK>
+0xBCC3	0x64B3	# <CJK>
+0xBCC4	0x6575	# <CJK>
+0xBCC5	0x6577	# <CJK>
+0xBCC6	0x6578	# <CJK>
+0xBCC7	0x66AE	# <CJK>
+0xBCC8	0x66AB	# <CJK>
+0xBCC9	0x66B4	# <CJK>
+0xBCCA	0x66B1	# <CJK>
+0xBCCB	0x6A23	# <CJK>
+0xBCCC	0x6A1F	# <CJK>
+0xBCCD	0x69E8	# <CJK>
+0xBCCE	0x6A01	# <CJK>
+0xBCCF	0x6A1E	# <CJK>
+0xBCD0	0x6A19	# <CJK>
+0xBCD1	0x69FD	# <CJK>
+0xBCD2	0x6A21	# <CJK>
+0xBCD3	0x6A13	# <CJK>
+0xBCD4	0x6A0A	# <CJK>
+0xBCD5	0x69F3	# <CJK>
+0xBCD6	0x6A02	# <CJK>
+0xBCD7	0x6A05	# <CJK>
+0xBCD8	0x69ED	# <CJK>
+0xBCD9	0x6A11	# <CJK>
+0xBCDA	0x6B50	# <CJK>
+0xBCDB	0x6B4E	# <CJK>
+0xBCDC	0x6BA4	# <CJK>
+0xBCDD	0x6BC5	# <CJK>
+0xBCDE	0x6BC6	# <CJK>
+0xBCDF	0x6F3F	# <CJK>
+0xBCE0	0x6F7C	# <CJK>
+0xBCE1	0x6F84	# <CJK>
+0xBCE2	0x6F51	# <CJK>
+0xBCE3	0x6F66	# <CJK>
+0xBCE4	0x6F54	# <CJK>
+0xBCE5	0x6F86	# <CJK>
+0xBCE6	0x6F6D	# <CJK>
+0xBCE7	0x6F5B	# <CJK>
+0xBCE8	0x6F78	# <CJK>
+0xBCE9	0x6F6E	# <CJK>
+0xBCEA	0x6F8E	# <CJK>
+0xBCEB	0x6F7A	# <CJK>
+0xBCEC	0x6F70	# <CJK>
+0xBCED	0x6F64	# <CJK>
+0xBCEE	0x6F97	# <CJK>
+0xBCEF	0x6F58	# <CJK>
+0xBCF0	0x6ED5	# <CJK>
+0xBCF1	0x6F6F	# <CJK>
+0xBCF2	0x6F60	# <CJK>
+0xBCF3	0x6F5F	# <CJK>
+0xBCF4	0x719F	# <CJK>
+0xBCF5	0x71AC	# <CJK>
+0xBCF6	0x71B1	# <CJK>
+0xBCF7	0x71A8	# <CJK>
+0xBCF8	0x7256	# <CJK>
+0xBCF9	0x729B	# <CJK>
+0xBCFA	0x734E	# <CJK>
+0xBCFB	0x7357	# <CJK>
+0xBCFC	0x7469	# <CJK>
+0xBCFD	0x748B	# <CJK>
+0xBCFE	0x7483	# <CJK>
+0xBD40	0x747E	# <CJK>
+0xBD41	0x7480	# <CJK>
+0xBD42	0x757F	# <CJK>
+0xBD43	0x7620	# <CJK>
+0xBD44	0x7629	# <CJK>
+0xBD45	0x761F	# <CJK>
+0xBD46	0x7624	# <CJK>
+0xBD47	0x7626	# <CJK>
+0xBD48	0x7621	# <CJK>
+0xBD49	0x7622	# <CJK>
+0xBD4A	0x769A	# <CJK>
+0xBD4B	0x76BA	# <CJK>
+0xBD4C	0x76E4	# <CJK>
+0xBD4D	0x778E	# <CJK>
+0xBD4E	0x7787	# <CJK>
+0xBD4F	0x778C	# <CJK>
+0xBD50	0x7791	# <CJK>
+0xBD51	0x778B	# <CJK>
+0xBD52	0x78CB	# <CJK>
+0xBD53	0x78C5	# <CJK>
+0xBD54	0x78BA	# <CJK>
+0xBD55	0x78CA	# <CJK>
+0xBD56	0x78BE	# <CJK>
+0xBD57	0x78D5	# <CJK>
+0xBD58	0x78BC	# <CJK>
+0xBD59	0x78D0	# <CJK>
+0xBD5A	0x7A3F	# <CJK>
+0xBD5B	0x7A3C	# <CJK>
+0xBD5C	0x7A40	# <CJK>
+0xBD5D	0x7A3D	# <CJK>
+0xBD5E	0x7A37	# <CJK>
+0xBD5F	0x7A3B	# <CJK>
+0xBD60	0x7AAF	# <CJK>
+0xBD61	0x7AAE	# <CJK>
+0xBD62	0x7BAD	# <CJK>
+0xBD63	0x7BB1	# <CJK>
+0xBD64	0x7BC4	# <CJK>
+0xBD65	0x7BB4	# <CJK>
+0xBD66	0x7BC6	# <CJK>
+0xBD67	0x7BC7	# <CJK>
+0xBD68	0x7BC1	# <CJK>
+0xBD69	0x7BA0	# <CJK>
+0xBD6A	0x7BCC	# <CJK>
+0xBD6B	0x7CCA	# <CJK>
+0xBD6C	0x7DE0	# <CJK>
+0xBD6D	0x7DF4	# <CJK>
+0xBD6E	0x7DEF	# <CJK>
+0xBD6F	0x7DFB	# <CJK>
+0xBD70	0x7DD8	# <CJK>
+0xBD71	0x7DEC	# <CJK>
+0xBD72	0x7DDD	# <CJK>
+0xBD73	0x7DE8	# <CJK>
+0xBD74	0x7DE3	# <CJK>
+0xBD75	0x7DDA	# <CJK>
+0xBD76	0x7DDE	# <CJK>
+0xBD77	0x7DE9	# <CJK>
+0xBD78	0x7D9E	# <CJK>
+0xBD79	0x7DD9	# <CJK>
+0xBD7A	0x7DF2	# <CJK>
+0xBD7B	0x7DF9	# <CJK>
+0xBD7C	0x7F75	# <CJK>
+0xBD7D	0x7F77	# <CJK>
+0xBD7E	0x7FAF	# <CJK>
+0xBDA1	0x7FE9	# <CJK>
+0xBDA2	0x8026	# <CJK>
+0xBDA3	0x819B	# <CJK>
+0xBDA4	0x819C	# <CJK>
+0xBDA5	0x819D	# <CJK>
+0xBDA6	0x81A0	# <CJK>
+0xBDA7	0x819A	# <CJK>
+0xBDA8	0x8198	# <CJK>
+0xBDA9	0x8517	# <CJK>
+0xBDAA	0x853D	# <CJK>
+0xBDAB	0x851A	# <CJK>
+0xBDAC	0x84EE	# <CJK>
+0xBDAD	0x852C	# <CJK>
+0xBDAE	0x852D	# <CJK>
+0xBDAF	0x8513	# <CJK>
+0xBDB0	0x8511	# <CJK>
+0xBDB1	0x8523	# <CJK>
+0xBDB2	0x8521	# <CJK>
+0xBDB3	0x8514	# <CJK>
+0xBDB4	0x84EC	# <CJK>
+0xBDB5	0x8525	# <CJK>
+0xBDB6	0x84FF	# <CJK>
+0xBDB7	0x8506	# <CJK>
+0xBDB8	0x8782	# <CJK>
+0xBDB9	0x8774	# <CJK>
+0xBDBA	0x8776	# <CJK>
+0xBDBB	0x8760	# <CJK>
+0xBDBC	0x8766	# <CJK>
+0xBDBD	0x8778	# <CJK>
+0xBDBE	0x8768	# <CJK>
+0xBDBF	0x8759	# <CJK>
+0xBDC0	0x8757	# <CJK>
+0xBDC1	0x874C	# <CJK>
+0xBDC2	0x8753	# <CJK>
+0xBDC3	0x885B	# <CJK>
+0xBDC4	0x885D	# <CJK>
+0xBDC5	0x8910	# <CJK>
+0xBDC6	0x8907	# <CJK>
+0xBDC7	0x8912	# <CJK>
+0xBDC8	0x8913	# <CJK>
+0xBDC9	0x8915	# <CJK>
+0xBDCA	0x890A	# <CJK>
+0xBDCB	0x8ABC	# <CJK>
+0xBDCC	0x8AD2	# <CJK>
+0xBDCD	0x8AC7	# <CJK>
+0xBDCE	0x8AC4	# <CJK>
+0xBDCF	0x8A95	# <CJK>
+0xBDD0	0x8ACB	# <CJK>
+0xBDD1	0x8AF8	# <CJK>
+0xBDD2	0x8AB2	# <CJK>
+0xBDD3	0x8AC9	# <CJK>
+0xBDD4	0x8AC2	# <CJK>
+0xBDD5	0x8ABF	# <CJK>
+0xBDD6	0x8AB0	# <CJK>
+0xBDD7	0x8AD6	# <CJK>
+0xBDD8	0x8ACD	# <CJK>
+0xBDD9	0x8AB6	# <CJK>
+0xBDDA	0x8AB9	# <CJK>
+0xBDDB	0x8ADB	# <CJK>
+0xBDDC	0x8C4C	# <CJK>
+0xBDDD	0x8C4E	# <CJK>
+0xBDDE	0x8C6C	# <CJK>
+0xBDDF	0x8CE0	# <CJK>
+0xBDE0	0x8CDE	# <CJK>
+0xBDE1	0x8CE6	# <CJK>
+0xBDE2	0x8CE4	# <CJK>
+0xBDE3	0x8CEC	# <CJK>
+0xBDE4	0x8CED	# <CJK>
+0xBDE5	0x8CE2	# <CJK>
+0xBDE6	0x8CE3	# <CJK>
+0xBDE7	0x8CDC	# <CJK>
+0xBDE8	0x8CEA	# <CJK>
+0xBDE9	0x8CE1	# <CJK>
+0xBDEA	0x8D6D	# <CJK>
+0xBDEB	0x8D9F	# <CJK>
+0xBDEC	0x8DA3	# <CJK>
+0xBDED	0x8E2B	# <CJK>
+0xBDEE	0x8E10	# <CJK>
+0xBDEF	0x8E1D	# <CJK>
+0xBDF0	0x8E22	# <CJK>
+0xBDF1	0x8E0F	# <CJK>
+0xBDF2	0x8E29	# <CJK>
+0xBDF3	0x8E1F	# <CJK>
+0xBDF4	0x8E21	# <CJK>
+0xBDF5	0x8E1E	# <CJK>
+0xBDF6	0x8EBA	# <CJK>
+0xBDF7	0x8F1D	# <CJK>
+0xBDF8	0x8F1B	# <CJK>
+0xBDF9	0x8F1F	# <CJK>
+0xBDFA	0x8F29	# <CJK>
+0xBDFB	0x8F26	# <CJK>
+0xBDFC	0x8F2A	# <CJK>
+0xBDFD	0x8F1C	# <CJK>
+0xBDFE	0x8F1E	# <CJK>
+0xBE40	0x8F25	# <CJK>
+0xBE41	0x9069	# <CJK>
+0xBE42	0x906E	# <CJK>
+0xBE43	0x9068	# <CJK>
+0xBE44	0x906D	# <CJK>
+0xBE45	0x9077	# <CJK>
+0xBE46	0x9130	# <CJK>
+0xBE47	0x912D	# <CJK>
+0xBE48	0x9127	# <CJK>
+0xBE49	0x9131	# <CJK>
+0xBE4A	0x9187	# <CJK>
+0xBE4B	0x9189	# <CJK>
+0xBE4C	0x918B	# <CJK>
+0xBE4D	0x9183	# <CJK>
+0xBE4E	0x92C5	# <CJK>
+0xBE4F	0x92BB	# <CJK>
+0xBE50	0x92B7	# <CJK>
+0xBE51	0x92EA	# <CJK>
+0xBE52	0x92AC	# <CJK>
+0xBE53	0x92E4	# <CJK>
+0xBE54	0x92C1	# <CJK>
+0xBE55	0x92B3	# <CJK>
+0xBE56	0x92BC	# <CJK>
+0xBE57	0x92D2	# <CJK>
+0xBE58	0x92C7	# <CJK>
+0xBE59	0x92F0	# <CJK>
+0xBE5A	0x92B2	# <CJK>
+0xBE5B	0x95AD	# <CJK>
+0xBE5C	0x95B1	# <CJK>
+0xBE5D	0x9704	# <CJK>
+0xBE5E	0x9706	# <CJK>
+0xBE5F	0x9707	# <CJK>
+0xBE60	0x9709	# <CJK>
+0xBE61	0x9760	# <CJK>
+0xBE62	0x978D	# <CJK>
+0xBE63	0x978B	# <CJK>
+0xBE64	0x978F	# <CJK>
+0xBE65	0x9821	# <CJK>
+0xBE66	0x982B	# <CJK>
+0xBE67	0x981C	# <CJK>
+0xBE68	0x98B3	# <CJK>
+0xBE69	0x990A	# <CJK>
+0xBE6A	0x9913	# <CJK>
+0xBE6B	0x9912	# <CJK>
+0xBE6C	0x9918	# <CJK>
+0xBE6D	0x99DD	# <CJK>
+0xBE6E	0x99D0	# <CJK>
+0xBE6F	0x99DF	# <CJK>
+0xBE70	0x99DB	# <CJK>
+0xBE71	0x99D1	# <CJK>
+0xBE72	0x99D5	# <CJK>
+0xBE73	0x99D2	# <CJK>
+0xBE74	0x99D9	# <CJK>
+0xBE75	0x9AB7	# <CJK>
+0xBE76	0x9AEE	# <CJK>
+0xBE77	0x9AEF	# <CJK>
+0xBE78	0x9B27	# <CJK>
+0xBE79	0x9B45	# <CJK>
+0xBE7A	0x9B44	# <CJK>
+0xBE7B	0x9B77	# <CJK>
+0xBE7C	0x9B6F	# <CJK>
+0xBE7D	0x9D06	# <CJK>
+0xBE7E	0x9D09	# <CJK>
+0xBEA1	0x9D03	# <CJK>
+0xBEA2	0x9EA9	# <CJK>
+0xBEA3	0x9EBE	# <CJK>
+0xBEA4	0x9ECE	# <CJK>
+0xBEA5	0x58A8	# <CJK>
+0xBEA6	0x9F52	# <CJK>
+0xBEA7	0x5112	# <CJK>
+0xBEA8	0x5118	# <CJK>
+0xBEA9	0x5114	# <CJK>
+0xBEAA	0x5110	# <CJK>
+0xBEAB	0x5115	# <CJK>
+0xBEAC	0x5180	# <CJK>
+0xBEAD	0x51AA	# <CJK>
+0xBEAE	0x51DD	# <CJK>
+0xBEAF	0x5291	# <CJK>
+0xBEB0	0x5293	# <CJK>
+0xBEB1	0x52F3	# <CJK>
+0xBEB2	0x5659	# <CJK>
+0xBEB3	0x566B	# <CJK>
+0xBEB4	0x5679	# <CJK>
+0xBEB5	0x5669	# <CJK>
+0xBEB6	0x5664	# <CJK>
+0xBEB7	0x5678	# <CJK>
+0xBEB8	0x566A	# <CJK>
+0xBEB9	0x5668	# <CJK>
+0xBEBA	0x5665	# <CJK>
+0xBEBB	0x5671	# <CJK>
+0xBEBC	0x566F	# <CJK>
+0xBEBD	0x566C	# <CJK>
+0xBEBE	0x5662	# <CJK>
+0xBEBF	0x5676	# <CJK>
+0xBEC0	0x58C1	# <CJK>
+0xBEC1	0x58BE	# <CJK>
+0xBEC2	0x58C7	# <CJK>
+0xBEC3	0x58C5	# <CJK>
+0xBEC4	0x596E	# <CJK>
+0xBEC5	0x5B1D	# <CJK>
+0xBEC6	0x5B34	# <CJK>
+0xBEC7	0x5B78	# <CJK>
+0xBEC8	0x5BF0	# <CJK>
+0xBEC9	0x5C0E	# <CJK>
+0xBECA	0x5F4A	# <CJK>
+0xBECB	0x61B2	# <CJK>
+0xBECC	0x6191	# <CJK>
+0xBECD	0x61A9	# <CJK>
+0xBECE	0x618A	# <CJK>
+0xBECF	0x61CD	# <CJK>
+0xBED0	0x61B6	# <CJK>
+0xBED1	0x61BE	# <CJK>
+0xBED2	0x61CA	# <CJK>
+0xBED3	0x61C8	# <CJK>
+0xBED4	0x6230	# <CJK>
+0xBED5	0x64C5	# <CJK>
+0xBED6	0x64C1	# <CJK>
+0xBED7	0x64CB	# <CJK>
+0xBED8	0x64BB	# <CJK>
+0xBED9	0x64BC	# <CJK>
+0xBEDA	0x64DA	# <CJK>
+0xBEDB	0x64C4	# <CJK>
+0xBEDC	0x64C7	# <CJK>
+0xBEDD	0x64C2	# <CJK>
+0xBEDE	0x64CD	# <CJK>
+0xBEDF	0x64BF	# <CJK>
+0xBEE0	0x64D2	# <CJK>
+0xBEE1	0x64D4	# <CJK>
+0xBEE2	0x64BE	# <CJK>
+0xBEE3	0x6574	# <CJK>
+0xBEE4	0x66C6	# <CJK>
+0xBEE5	0x66C9	# <CJK>
+0xBEE6	0x66B9	# <CJK>
+0xBEE7	0x66C4	# <CJK>
+0xBEE8	0x66C7	# <CJK>
+0xBEE9	0x66B8	# <CJK>
+0xBEEA	0x6A3D	# <CJK>
+0xBEEB	0x6A38	# <CJK>
+0xBEEC	0x6A3A	# <CJK>
+0xBEED	0x6A59	# <CJK>
+0xBEEE	0x6A6B	# <CJK>
+0xBEEF	0x6A58	# <CJK>
+0xBEF0	0x6A39	# <CJK>
+0xBEF1	0x6A44	# <CJK>
+0xBEF2	0x6A62	# <CJK>
+0xBEF3	0x6A61	# <CJK>
+0xBEF4	0x6A4B	# <CJK>
+0xBEF5	0x6A47	# <CJK>
+0xBEF6	0x6A35	# <CJK>
+0xBEF7	0x6A5F	# <CJK>
+0xBEF8	0x6A48	# <CJK>
+0xBEF9	0x6B59	# <CJK>
+0xBEFA	0x6B77	# <CJK>
+0xBEFB	0x6C05	# <CJK>
+0xBEFC	0x6FC2	# <CJK>
+0xBEFD	0x6FB1	# <CJK>
+0xBEFE	0x6FA1	# <CJK>
+0xBF40	0x6FC3	# <CJK>
+0xBF41	0x6FA4	# <CJK>
+0xBF42	0x6FC1	# <CJK>
+0xBF43	0x6FA7	# <CJK>
+0xBF44	0x6FB3	# <CJK>
+0xBF45	0x6FC0	# <CJK>
+0xBF46	0x6FB9	# <CJK>
+0xBF47	0x6FB6	# <CJK>
+0xBF48	0x6FA6	# <CJK>
+0xBF49	0x6FA0	# <CJK>
+0xBF4A	0x6FB4	# <CJK>
+0xBF4B	0x71BE	# <CJK>
+0xBF4C	0x71C9	# <CJK>
+0xBF4D	0x71D0	# <CJK>
+0xBF4E	0x71D2	# <CJK>
+0xBF4F	0x71C8	# <CJK>
+0xBF50	0x71D5	# <CJK>
+0xBF51	0x71B9	# <CJK>
+0xBF52	0x71CE	# <CJK>
+0xBF53	0x71D9	# <CJK>
+0xBF54	0x71DC	# <CJK>
+0xBF55	0x71C3	# <CJK>
+0xBF56	0x71C4	# <CJK>
+0xBF57	0x7368	# <CJK>
+0xBF58	0x749C	# <CJK>
+0xBF59	0x74A3	# <CJK>
+0xBF5A	0x7498	# <CJK>
+0xBF5B	0x749F	# <CJK>
+0xBF5C	0x749E	# <CJK>
+0xBF5D	0x74E2	# <CJK>
+0xBF5E	0x750C	# <CJK>
+0xBF5F	0x750D	# <CJK>
+0xBF60	0x7634	# <CJK>
+0xBF61	0x7638	# <CJK>
+0xBF62	0x763A	# <CJK>
+0xBF63	0x76E7	# <CJK>
+0xBF64	0x76E5	# <CJK>
+0xBF65	0x77A0	# <CJK>
+0xBF66	0x779E	# <CJK>
+0xBF67	0x779F	# <CJK>
+0xBF68	0x77A5	# <CJK>
+0xBF69	0x78E8	# <CJK>
+0xBF6A	0x78DA	# <CJK>
+0xBF6B	0x78EC	# <CJK>
+0xBF6C	0x78E7	# <CJK>
+0xBF6D	0x79A6	# <CJK>
+0xBF6E	0x7A4D	# <CJK>
+0xBF6F	0x7A4E	# <CJK>
+0xBF70	0x7A46	# <CJK>
+0xBF71	0x7A4C	# <CJK>
+0xBF72	0x7A4B	# <CJK>
+0xBF73	0x7ABA	# <CJK>
+0xBF74	0x7BD9	# <CJK>
+0xBF75	0x7C11	# <CJK>
+0xBF76	0x7BC9	# <CJK>
+0xBF77	0x7BE4	# <CJK>
+0xBF78	0x7BDB	# <CJK>
+0xBF79	0x7BE1	# <CJK>
+0xBF7A	0x7BE9	# <CJK>
+0xBF7B	0x7BE6	# <CJK>
+0xBF7C	0x7CD5	# <CJK>
+0xBF7D	0x7CD6	# <CJK>
+0xBF7E	0x7E0A	# <CJK>
+0xBFA1	0x7E11	# <CJK>
+0xBFA2	0x7E08	# <CJK>
+0xBFA3	0x7E1B	# <CJK>
+0xBFA4	0x7E23	# <CJK>
+0xBFA5	0x7E1E	# <CJK>
+0xBFA6	0x7E1D	# <CJK>
+0xBFA7	0x7E09	# <CJK>
+0xBFA8	0x7E10	# <CJK>
+0xBFA9	0x7F79	# <CJK>
+0xBFAA	0x7FB2	# <CJK>
+0xBFAB	0x7FF0	# <CJK>
+0xBFAC	0x7FF1	# <CJK>
+0xBFAD	0x7FEE	# <CJK>
+0xBFAE	0x8028	# <CJK>
+0xBFAF	0x81B3	# <CJK>
+0xBFB0	0x81A9	# <CJK>
+0xBFB1	0x81A8	# <CJK>
+0xBFB2	0x81FB	# <CJK>
+0xBFB3	0x8208	# <CJK>
+0xBFB4	0x8258	# <CJK>
+0xBFB5	0x8259	# <CJK>
+0xBFB6	0x854A	# <CJK>
+0xBFB7	0x8559	# <CJK>
+0xBFB8	0x8548	# <CJK>
+0xBFB9	0x8568	# <CJK>
+0xBFBA	0x8569	# <CJK>
+0xBFBB	0x8543	# <CJK>
+0xBFBC	0x8549	# <CJK>
+0xBFBD	0x856D	# <CJK>
+0xBFBE	0x856A	# <CJK>
+0xBFBF	0x855E	# <CJK>
+0xBFC0	0x8783	# <CJK>
+0xBFC1	0x879F	# <CJK>
+0xBFC2	0x879E	# <CJK>
+0xBFC3	0x87A2	# <CJK>
+0xBFC4	0x878D	# <CJK>
+0xBFC5	0x8861	# <CJK>
+0xBFC6	0x892A	# <CJK>
+0xBFC7	0x8932	# <CJK>
+0xBFC8	0x8925	# <CJK>
+0xBFC9	0x892B	# <CJK>
+0xBFCA	0x8921	# <CJK>
+0xBFCB	0x89AA	# <CJK>
+0xBFCC	0x89A6	# <CJK>
+0xBFCD	0x8AE6	# <CJK>
+0xBFCE	0x8AFA	# <CJK>
+0xBFCF	0x8AEB	# <CJK>
+0xBFD0	0x8AF1	# <CJK>
+0xBFD1	0x8B00	# <CJK>
+0xBFD2	0x8ADC	# <CJK>
+0xBFD3	0x8AE7	# <CJK>
+0xBFD4	0x8AEE	# <CJK>
+0xBFD5	0x8AFE	# <CJK>
+0xBFD6	0x8B01	# <CJK>
+0xBFD7	0x8B02	# <CJK>
+0xBFD8	0x8AF7	# <CJK>
+0xBFD9	0x8AED	# <CJK>
+0xBFDA	0x8AF3	# <CJK>
+0xBFDB	0x8AF6	# <CJK>
+0xBFDC	0x8AFC	# <CJK>
+0xBFDD	0x8C6B	# <CJK>
+0xBFDE	0x8C6D	# <CJK>
+0xBFDF	0x8C93	# <CJK>
+0xBFE0	0x8CF4	# <CJK>
+0xBFE1	0x8E44	# <CJK>
+0xBFE2	0x8E31	# <CJK>
+0xBFE3	0x8E34	# <CJK>
+0xBFE4	0x8E42	# <CJK>
+0xBFE5	0x8E39	# <CJK>
+0xBFE6	0x8E35	# <CJK>
+0xBFE7	0x8F3B	# <CJK>
+0xBFE8	0x8F2F	# <CJK>
+0xBFE9	0x8F38	# <CJK>
+0xBFEA	0x8F33	# <CJK>
+0xBFEB	0x8FA8	# <CJK>
+0xBFEC	0x8FA6	# <CJK>
+0xBFED	0x9075	# <CJK>
+0xBFEE	0x9074	# <CJK>
+0xBFEF	0x9078	# <CJK>
+0xBFF0	0x9072	# <CJK>
+0xBFF1	0x907C	# <CJK>
+0xBFF2	0x907A	# <CJK>
+0xBFF3	0x9134	# <CJK>
+0xBFF4	0x9192	# <CJK>
+0xBFF5	0x9320	# <CJK>
+0xBFF6	0x9336	# <CJK>
+0xBFF7	0x92F8	# <CJK>
+0xBFF8	0x9333	# <CJK>
+0xBFF9	0x932F	# <CJK>
+0xBFFA	0x9322	# <CJK>
+0xBFFB	0x92FC	# <CJK>
+0xBFFC	0x932B	# <CJK>
+0xBFFD	0x9304	# <CJK>
+0xBFFE	0x931A	# <CJK>
+0xC040	0x9310	# <CJK>
+0xC041	0x9326	# <CJK>
+0xC042	0x9321	# <CJK>
+0xC043	0x9315	# <CJK>
+0xC044	0x932E	# <CJK>
+0xC045	0x9319	# <CJK>
+0xC046	0x95BB	# <CJK>
+0xC047	0x96A7	# <CJK>
+0xC048	0x96A8	# <CJK>
+0xC049	0x96AA	# <CJK>
+0xC04A	0x96D5	# <CJK>
+0xC04B	0x970E	# <CJK>
+0xC04C	0x9711	# <CJK>
+0xC04D	0x9716	# <CJK>
+0xC04E	0x970D	# <CJK>
+0xC04F	0x9713	# <CJK>
+0xC050	0x970F	# <CJK>
+0xC051	0x975B	# <CJK>
+0xC052	0x975C	# <CJK>
+0xC053	0x9766	# <CJK>
+0xC054	0x9798	# <CJK>
+0xC055	0x9830	# <CJK>
+0xC056	0x9838	# <CJK>
+0xC057	0x983B	# <CJK>
+0xC058	0x9837	# <CJK>
+0xC059	0x982D	# <CJK>
+0xC05A	0x9839	# <CJK>
+0xC05B	0x9824	# <CJK>
+0xC05C	0x9910	# <CJK>
+0xC05D	0x9928	# <CJK>
+0xC05E	0x991E	# <CJK>
+0xC05F	0x991B	# <CJK>
+0xC060	0x9921	# <CJK>
+0xC061	0x991A	# <CJK>
+0xC062	0x99ED	# <CJK>
+0xC063	0x99E2	# <CJK>
+0xC064	0x99F1	# <CJK>
+0xC065	0x9AB8	# <CJK>
+0xC066	0x9ABC	# <CJK>
+0xC067	0x9AFB	# <CJK>
+0xC068	0x9AED	# <CJK>
+0xC069	0x9B28	# <CJK>
+0xC06A	0x9B91	# <CJK>
+0xC06B	0x9D15	# <CJK>
+0xC06C	0x9D23	# <CJK>
+0xC06D	0x9D26	# <CJK>
+0xC06E	0x9D28	# <CJK>
+0xC06F	0x9D12	# <CJK>
+0xC070	0x9D1B	# <CJK>
+0xC071	0x9ED8	# <CJK>
+0xC072	0x9ED4	# <CJK>
+0xC073	0x9F8D	# <CJK>
+0xC074	0x9F9C	# <CJK>
+0xC075	0x512A	# <CJK>
+0xC076	0x511F	# <CJK>
+0xC077	0x5121	# <CJK>
+0xC078	0x5132	# <CJK>
+0xC079	0x52F5	# <CJK>
+0xC07A	0x568E	# <CJK>
+0xC07B	0x5680	# <CJK>
+0xC07C	0x5690	# <CJK>
+0xC07D	0x5685	# <CJK>
+0xC07E	0x5687	# <CJK>
+0xC0A1	0x568F	# <CJK>
+0xC0A2	0x58D5	# <CJK>
+0xC0A3	0x58D3	# <CJK>
+0xC0A4	0x58D1	# <CJK>
+0xC0A5	0x58CE	# <CJK>
+0xC0A6	0x5B30	# <CJK>
+0xC0A7	0x5B2A	# <CJK>
+0xC0A8	0x5B24	# <CJK>
+0xC0A9	0x5B7A	# <CJK>
+0xC0AA	0x5C37	# <CJK>
+0xC0AB	0x5C68	# <CJK>
+0xC0AC	0x5DBC	# <CJK>
+0xC0AD	0x5DBA	# <CJK>
+0xC0AE	0x5DBD	# <CJK>
+0xC0AF	0x5DB8	# <CJK>
+0xC0B0	0x5E6B	# <CJK>
+0xC0B1	0x5F4C	# <CJK>
+0xC0B2	0x5FBD	# <CJK>
+0xC0B3	0x61C9	# <CJK>
+0xC0B4	0x61C2	# <CJK>
+0xC0B5	0x61C7	# <CJK>
+0xC0B6	0x61E6	# <CJK>
+0xC0B7	0x61CB	# <CJK>
+0xC0B8	0x6232	# <CJK>
+0xC0B9	0x6234	# <CJK>
+0xC0BA	0x64CE	# <CJK>
+0xC0BB	0x64CA	# <CJK>
+0xC0BC	0x64D8	# <CJK>
+0xC0BD	0x64E0	# <CJK>
+0xC0BE	0x64F0	# <CJK>
+0xC0BF	0x64E6	# <CJK>
+0xC0C0	0x64EC	# <CJK>
+0xC0C1	0x64F1	# <CJK>
+0xC0C2	0x64E2	# <CJK>
+0xC0C3	0x64ED	# <CJK>
+0xC0C4	0x6582	# <CJK>
+0xC0C5	0x6583	# <CJK>
+0xC0C6	0x66D9	# <CJK>
+0xC0C7	0x66D6	# <CJK>
+0xC0C8	0x6A80	# <CJK>
+0xC0C9	0x6A94	# <CJK>
+0xC0CA	0x6A84	# <CJK>
+0xC0CB	0x6AA2	# <CJK>
+0xC0CC	0x6A9C	# <CJK>
+0xC0CD	0x6ADB	# <CJK>
+0xC0CE	0x6AA3	# <CJK>
+0xC0CF	0x6A7E	# <CJK>
+0xC0D0	0x6A97	# <CJK>
+0xC0D1	0x6A90	# <CJK>
+0xC0D2	0x6AA0	# <CJK>
+0xC0D3	0x6B5C	# <CJK>
+0xC0D4	0x6BAE	# <CJK>
+0xC0D5	0x6BDA	# <CJK>
+0xC0D6	0x6C08	# <CJK>
+0xC0D7	0x6FD8	# <CJK>
+0xC0D8	0x6FF1	# <CJK>
+0xC0D9	0x6FDF	# <CJK>
+0xC0DA	0x6FE0	# <CJK>
+0xC0DB	0x6FDB	# <CJK>
+0xC0DC	0x6FE4	# <CJK>
+0xC0DD	0x6FEB	# <CJK>
+0xC0DE	0x6FEF	# <CJK>
+0xC0DF	0x6F80	# <CJK>
+0xC0E0	0x6FEC	# <CJK>
+0xC0E1	0x6FE1	# <CJK>
+0xC0E2	0x6FE9	# <CJK>
+0xC0E3	0x6FD5	# <CJK>
+0xC0E4	0x6FEE	# <CJK>
+0xC0E5	0x6FF0	# <CJK>
+0xC0E6	0x71E7	# <CJK>
+0xC0E7	0x71DF	# <CJK>
+0xC0E8	0x71EE	# <CJK>
+0xC0E9	0x71E6	# <CJK>
+0xC0EA	0x71E5	# <CJK>
+0xC0EB	0x71ED	# <CJK>
+0xC0EC	0x71EC	# <CJK>
+0xC0ED	0x71F4	# <CJK>
+0xC0EE	0x71E0	# <CJK>
+0xC0EF	0x7235	# <CJK>
+0xC0F0	0x7246	# <CJK>
+0xC0F1	0x7370	# <CJK>
+0xC0F2	0x7372	# <CJK>
+0xC0F3	0x74A9	# <CJK>
+0xC0F4	0x74B0	# <CJK>
+0xC0F5	0x74A6	# <CJK>
+0xC0F6	0x74A8	# <CJK>
+0xC0F7	0x7646	# <CJK>
+0xC0F8	0x7642	# <CJK>
+0xC0F9	0x764C	# <CJK>
+0xC0FA	0x76EA	# <CJK>
+0xC0FB	0x77B3	# <CJK>
+0xC0FC	0x77AA	# <CJK>
+0xC0FD	0x77B0	# <CJK>
+0xC0FE	0x77AC	# <CJK>
+0xC140	0x77A7	# <CJK>
+0xC141	0x77AD	# <CJK>
+0xC142	0x77EF	# <CJK>
+0xC143	0x78F7	# <CJK>
+0xC144	0x78FA	# <CJK>
+0xC145	0x78F4	# <CJK>
+0xC146	0x78EF	# <CJK>
+0xC147	0x7901	# <CJK>
+0xC148	0x79A7	# <CJK>
+0xC149	0x79AA	# <CJK>
+0xC14A	0x7A57	# <CJK>
+0xC14B	0x7ABF	# <CJK>
+0xC14C	0x7C07	# <CJK>
+0xC14D	0x7C0D	# <CJK>
+0xC14E	0x7BFE	# <CJK>
+0xC14F	0x7BF7	# <CJK>
+0xC150	0x7C0C	# <CJK>
+0xC151	0x7BE0	# <CJK>
+0xC152	0x7CE0	# <CJK>
+0xC153	0x7CDC	# <CJK>
+0xC154	0x7CDE	# <CJK>
+0xC155	0x7CE2	# <CJK>
+0xC156	0x7CDF	# <CJK>
+0xC157	0x7CD9	# <CJK>
+0xC158	0x7CDD	# <CJK>
+0xC159	0x7E2E	# <CJK>
+0xC15A	0x7E3E	# <CJK>
+0xC15B	0x7E46	# <CJK>
+0xC15C	0x7E37	# <CJK>
+0xC15D	0x7E32	# <CJK>
+0xC15E	0x7E43	# <CJK>
+0xC15F	0x7E2B	# <CJK>
+0xC160	0x7E3D	# <CJK>
+0xC161	0x7E31	# <CJK>
+0xC162	0x7E45	# <CJK>
+0xC163	0x7E41	# <CJK>
+0xC164	0x7E34	# <CJK>
+0xC165	0x7E39	# <CJK>
+0xC166	0x7E48	# <CJK>
+0xC167	0x7E35	# <CJK>
+0xC168	0x7E3F	# <CJK>
+0xC169	0x7E2F	# <CJK>
+0xC16A	0x7F44	# <CJK>
+0xC16B	0x7FF3	# <CJK>
+0xC16C	0x7FFC	# <CJK>
+0xC16D	0x8071	# <CJK>
+0xC16E	0x8072	# <CJK>
+0xC16F	0x8070	# <CJK>
+0xC170	0x806F	# <CJK>
+0xC171	0x8073	# <CJK>
+0xC172	0x81C6	# <CJK>
+0xC173	0x81C3	# <CJK>
+0xC174	0x81BA	# <CJK>
+0xC175	0x81C2	# <CJK>
+0xC176	0x81C0	# <CJK>
+0xC177	0x81BF	# <CJK>
+0xC178	0x81BD	# <CJK>
+0xC179	0x81C9	# <CJK>
+0xC17A	0x81BE	# <CJK>
+0xC17B	0x81E8	# <CJK>
+0xC17C	0x8209	# <CJK>
+0xC17D	0x8271	# <CJK>
+0xC17E	0x85AA	# <CJK>
+0xC1A1	0x8584	# <CJK>
+0xC1A2	0x857E	# <CJK>
+0xC1A3	0x859C	# <CJK>
+0xC1A4	0x8591	# <CJK>
+0xC1A5	0x8594	# <CJK>
+0xC1A6	0x85AF	# <CJK>
+0xC1A7	0x859B	# <CJK>
+0xC1A8	0x8587	# <CJK>
+0xC1A9	0x85A8	# <CJK>
+0xC1AA	0x858A	# <CJK>
+0xC1AB	0x8667	# <CJK>
+0xC1AC	0x87C0	# <CJK>
+0xC1AD	0x87D1	# <CJK>
+0xC1AE	0x87B3	# <CJK>
+0xC1AF	0x87D2	# <CJK>
+0xC1B0	0x87C6	# <CJK>
+0xC1B1	0x87AB	# <CJK>
+0xC1B2	0x87BB	# <CJK>
+0xC1B3	0x87BA	# <CJK>
+0xC1B4	0x87C8	# <CJK>
+0xC1B5	0x87CB	# <CJK>
+0xC1B6	0x893B	# <CJK>
+0xC1B7	0x8936	# <CJK>
+0xC1B8	0x8944	# <CJK>
+0xC1B9	0x8938	# <CJK>
+0xC1BA	0x893D	# <CJK>
+0xC1BB	0x89AC	# <CJK>
+0xC1BC	0x8B0E	# <CJK>
+0xC1BD	0x8B17	# <CJK>
+0xC1BE	0x8B19	# <CJK>
+0xC1BF	0x8B1B	# <CJK>
+0xC1C0	0x8B0A	# <CJK>
+0xC1C1	0x8B20	# <CJK>
+0xC1C2	0x8B1D	# <CJK>
+0xC1C3	0x8B04	# <CJK>
+0xC1C4	0x8B10	# <CJK>
+0xC1C5	0x8C41	# <CJK>
+0xC1C6	0x8C3F	# <CJK>
+0xC1C7	0x8C73	# <CJK>
+0xC1C8	0x8CFA	# <CJK>
+0xC1C9	0x8CFD	# <CJK>
+0xC1CA	0x8CFC	# <CJK>
+0xC1CB	0x8CF8	# <CJK>
+0xC1CC	0x8CFB	# <CJK>
+0xC1CD	0x8DA8	# <CJK>
+0xC1CE	0x8E49	# <CJK>
+0xC1CF	0x8E4B	# <CJK>
+0xC1D0	0x8E48	# <CJK>
+0xC1D1	0x8E4A	# <CJK>
+0xC1D2	0x8F44	# <CJK>
+0xC1D3	0x8F3E	# <CJK>
+0xC1D4	0x8F42	# <CJK>
+0xC1D5	0x8F45	# <CJK>
+0xC1D6	0x8F3F	# <CJK>
+0xC1D7	0x907F	# <CJK>
+0xC1D8	0x907D	# <CJK>
+0xC1D9	0x9084	# <CJK>
+0xC1DA	0x9081	# <CJK>
+0xC1DB	0x9082	# <CJK>
+0xC1DC	0x9080	# <CJK>
+0xC1DD	0x9139	# <CJK>
+0xC1DE	0x91A3	# <CJK>
+0xC1DF	0x919E	# <CJK>
+0xC1E0	0x919C	# <CJK>
+0xC1E1	0x934D	# <CJK>
+0xC1E2	0x9382	# <CJK>
+0xC1E3	0x9328	# <CJK>
+0xC1E4	0x9375	# <CJK>
+0xC1E5	0x934A	# <CJK>
+0xC1E6	0x9365	# <CJK>
+0xC1E7	0x934B	# <CJK>
+0xC1E8	0x9318	# <CJK>
+0xC1E9	0x937E	# <CJK>
+0xC1EA	0x936C	# <CJK>
+0xC1EB	0x935B	# <CJK>
+0xC1EC	0x9370	# <CJK>
+0xC1ED	0x935A	# <CJK>
+0xC1EE	0x9354	# <CJK>
+0xC1EF	0x95CA	# <CJK>
+0xC1F0	0x95CB	# <CJK>
+0xC1F1	0x95CC	# <CJK>
+0xC1F2	0x95C8	# <CJK>
+0xC1F3	0x95C6	# <CJK>
+0xC1F4	0x96B1	# <CJK>
+0xC1F5	0x96B8	# <CJK>
+0xC1F6	0x96D6	# <CJK>
+0xC1F7	0x971C	# <CJK>
+0xC1F8	0x971E	# <CJK>
+0xC1F9	0x97A0	# <CJK>
+0xC1FA	0x97D3	# <CJK>
+0xC1FB	0x9846	# <CJK>
+0xC1FC	0x98B6	# <CJK>
+0xC1FD	0x9935	# <CJK>
+0xC1FE	0x9A01	# <CJK>
+0xC240	0x99FF	# <CJK>
+0xC241	0x9BAE	# <CJK>
+0xC242	0x9BAB	# <CJK>
+0xC243	0x9BAA	# <CJK>
+0xC244	0x9BAD	# <CJK>
+0xC245	0x9D3B	# <CJK>
+0xC246	0x9D3F	# <CJK>
+0xC247	0x9E8B	# <CJK>
+0xC248	0x9ECF	# <CJK>
+0xC249	0x9EDE	# <CJK>
+0xC24A	0x9EDC	# <CJK>
+0xC24B	0x9EDD	# <CJK>
+0xC24C	0x9EDB	# <CJK>
+0xC24D	0x9F3E	# <CJK>
+0xC24E	0x9F4B	# <CJK>
+0xC24F	0x53E2	# <CJK>
+0xC250	0x5695	# <CJK>
+0xC251	0x56AE	# <CJK>
+0xC252	0x58D9	# <CJK>
+0xC253	0x58D8	# <CJK>
+0xC254	0x5B38	# <CJK>
+0xC255	0x5F5D	# <CJK>
+0xC256	0x61E3	# <CJK>
+0xC257	0x6233	# <CJK>
+0xC258	0x64F4	# <CJK>
+0xC259	0x64F2	# <CJK>
+0xC25A	0x64FE	# <CJK>
+0xC25B	0x6506	# <CJK>
+0xC25C	0x64FA	# <CJK>
+0xC25D	0x64FB	# <CJK>
+0xC25E	0x64F7	# <CJK>
+0xC25F	0x65B7	# <CJK>
+0xC260	0x66DC	# <CJK>
+0xC261	0x6726	# <CJK>
+0xC262	0x6AB3	# <CJK>
+0xC263	0x6AAC	# <CJK>
+0xC264	0x6AC3	# <CJK>
+0xC265	0x6ABB	# <CJK>
+0xC266	0x6AB8	# <CJK>
+0xC267	0x6AC2	# <CJK>
+0xC268	0x6AAE	# <CJK>
+0xC269	0x6AAF	# <CJK>
+0xC26A	0x6B5F	# <CJK>
+0xC26B	0x6B78	# <CJK>
+0xC26C	0x6BAF	# <CJK>
+0xC26D	0x7009	# <CJK>
+0xC26E	0x700B	# <CJK>
+0xC26F	0x6FFE	# <CJK>
+0xC270	0x7006	# <CJK>
+0xC271	0x6FFA	# <CJK>
+0xC272	0x7011	# <CJK>
+0xC273	0x700F	# <CJK>
+0xC274	0x71FB	# <CJK>
+0xC275	0x71FC	# <CJK>
+0xC276	0x71FE	# <CJK>
+0xC277	0x71F8	# <CJK>
+0xC278	0x7377	# <CJK>
+0xC279	0x7375	# <CJK>
+0xC27A	0x74A7	# <CJK>
+0xC27B	0x74BF	# <CJK>
+0xC27C	0x7515	# <CJK>
+0xC27D	0x7656	# <CJK>
+0xC27E	0x7658	# <CJK>
+0xC2A1	0x7652	# <CJK>
+0xC2A2	0x77BD	# <CJK>
+0xC2A3	0x77BF	# <CJK>
+0xC2A4	0x77BB	# <CJK>
+0xC2A5	0x77BC	# <CJK>
+0xC2A6	0x790E	# <CJK>
+0xC2A7	0x79AE	# <CJK>
+0xC2A8	0x7A61	# <CJK>
+0xC2A9	0x7A62	# <CJK>
+0xC2AA	0x7A60	# <CJK>
+0xC2AB	0x7AC4	# <CJK>
+0xC2AC	0x7AC5	# <CJK>
+0xC2AD	0x7C2B	# <CJK>
+0xC2AE	0x7C27	# <CJK>
+0xC2AF	0x7C2A	# <CJK>
+0xC2B0	0x7C1E	# <CJK>
+0xC2B1	0x7C23	# <CJK>
+0xC2B2	0x7C21	# <CJK>
+0xC2B3	0x7CE7	# <CJK>
+0xC2B4	0x7E54	# <CJK>
+0xC2B5	0x7E55	# <CJK>
+0xC2B6	0x7E5E	# <CJK>
+0xC2B7	0x7E5A	# <CJK>
+0xC2B8	0x7E61	# <CJK>
+0xC2B9	0x7E52	# <CJK>
+0xC2BA	0x7E59	# <CJK>
+0xC2BB	0x7F48	# <CJK>
+0xC2BC	0x7FF9	# <CJK>
+0xC2BD	0x7FFB	# <CJK>
+0xC2BE	0x8077	# <CJK>
+0xC2BF	0x8076	# <CJK>
+0xC2C0	0x81CD	# <CJK>
+0xC2C1	0x81CF	# <CJK>
+0xC2C2	0x820A	# <CJK>
+0xC2C3	0x85CF	# <CJK>
+0xC2C4	0x85A9	# <CJK>
+0xC2C5	0x85CD	# <CJK>
+0xC2C6	0x85D0	# <CJK>
+0xC2C7	0x85C9	# <CJK>
+0xC2C8	0x85B0	# <CJK>
+0xC2C9	0x85BA	# <CJK>
+0xC2CA	0x85B9	# <CJK>
+0xC2CB	0x85A6	# <CJK>
+0xC2CC	0x87EF	# <CJK>
+0xC2CD	0x87EC	# <CJK>
+0xC2CE	0x87F2	# <CJK>
+0xC2CF	0x87E0	# <CJK>
+0xC2D0	0x8986	# <CJK>
+0xC2D1	0x89B2	# <CJK>
+0xC2D2	0x89F4	# <CJK>
+0xC2D3	0x8B28	# <CJK>
+0xC2D4	0x8B39	# <CJK>
+0xC2D5	0x8B2C	# <CJK>
+0xC2D6	0x8B2B	# <CJK>
+0xC2D7	0x8C50	# <CJK>
+0xC2D8	0x8D05	# <CJK>
+0xC2D9	0x8E59	# <CJK>
+0xC2DA	0x8E63	# <CJK>
+0xC2DB	0x8E66	# <CJK>
+0xC2DC	0x8E64	# <CJK>
+0xC2DD	0x8E5F	# <CJK>
+0xC2DE	0x8E55	# <CJK>
+0xC2DF	0x8EC0	# <CJK>
+0xC2E0	0x8F49	# <CJK>
+0xC2E1	0x8F4D	# <CJK>
+0xC2E2	0x9087	# <CJK>
+0xC2E3	0x9083	# <CJK>
+0xC2E4	0x9088	# <CJK>
+0xC2E5	0x91AB	# <CJK>
+0xC2E6	0x91AC	# <CJK>
+0xC2E7	0x91D0	# <CJK>
+0xC2E8	0x9394	# <CJK>
+0xC2E9	0x938A	# <CJK>
+0xC2EA	0x9396	# <CJK>
+0xC2EB	0x93A2	# <CJK>
+0xC2EC	0x93B3	# <CJK>
+0xC2ED	0x93AE	# <CJK>
+0xC2EE	0x93AC	# <CJK>
+0xC2EF	0x93B0	# <CJK>
+0xC2F0	0x9398	# <CJK>
+0xC2F1	0x939A	# <CJK>
+0xC2F2	0x9397	# <CJK>
+0xC2F3	0x95D4	# <CJK>
+0xC2F4	0x95D6	# <CJK>
+0xC2F5	0x95D0	# <CJK>
+0xC2F6	0x95D5	# <CJK>
+0xC2F7	0x96E2	# <CJK>
+0xC2F8	0x96DC	# <CJK>
+0xC2F9	0x96D9	# <CJK>
+0xC2FA	0x96DB	# <CJK>
+0xC2FB	0x96DE	# <CJK>
+0xC2FC	0x9724	# <CJK>
+0xC2FD	0x97A3	# <CJK>
+0xC2FE	0x97A6	# <CJK>
+0xC340	0x97AD	# <CJK>
+0xC341	0x97F9	# <CJK>
+0xC342	0x984D	# <CJK>
+0xC343	0x984F	# <CJK>
+0xC344	0x984C	# <CJK>
+0xC345	0x984E	# <CJK>
+0xC346	0x9853	# <CJK>
+0xC347	0x98BA	# <CJK>
+0xC348	0x993E	# <CJK>
+0xC349	0x993F	# <CJK>
+0xC34A	0x993D	# <CJK>
+0xC34B	0x992E	# <CJK>
+0xC34C	0x99A5	# <CJK>
+0xC34D	0x9A0E	# <CJK>
+0xC34E	0x9AC1	# <CJK>
+0xC34F	0x9B03	# <CJK>
+0xC350	0x9B06	# <CJK>
+0xC351	0x9B4F	# <CJK>
+0xC352	0x9B4E	# <CJK>
+0xC353	0x9B4D	# <CJK>
+0xC354	0x9BCA	# <CJK>
+0xC355	0x9BC9	# <CJK>
+0xC356	0x9BFD	# <CJK>
+0xC357	0x9BC8	# <CJK>
+0xC358	0x9BC0	# <CJK>
+0xC359	0x9D51	# <CJK>
+0xC35A	0x9D5D	# <CJK>
+0xC35B	0x9D60	# <CJK>
+0xC35C	0x9EE0	# <CJK>
+0xC35D	0x9F15	# <CJK>
+0xC35E	0x9F2C	# <CJK>
+0xC35F	0x5133	# <CJK>
+0xC360	0x56A5	# <CJK>
+0xC361	0x58DE	# <CJK>
+0xC362	0x58DF	# <CJK>
+0xC363	0x58E2	# <CJK>
+0xC364	0x5BF5	# <CJK>
+0xC365	0x9F90	# <CJK>
+0xC366	0x5EEC	# <CJK>
+0xC367	0x61F2	# <CJK>
+0xC368	0x61F7	# <CJK>
+0xC369	0x61F6	# <CJK>
+0xC36A	0x61F5	# <CJK>
+0xC36B	0x6500	# <CJK>
+0xC36C	0x650F	# <CJK>
+0xC36D	0x66E0	# <CJK>
+0xC36E	0x66DD	# <CJK>
+0xC36F	0x6AE5	# <CJK>
+0xC370	0x6ADD	# <CJK>
+0xC371	0x6ADA	# <CJK>
+0xC372	0x6AD3	# <CJK>
+0xC373	0x701B	# <CJK>
+0xC374	0x701F	# <CJK>
+0xC375	0x7028	# <CJK>
+0xC376	0x701A	# <CJK>
+0xC377	0x701D	# <CJK>
+0xC378	0x7015	# <CJK>
+0xC379	0x7018	# <CJK>
+0xC37A	0x7206	# <CJK>
+0xC37B	0x720D	# <CJK>
+0xC37C	0x7258	# <CJK>
+0xC37D	0x72A2	# <CJK>
+0xC37E	0x7378	# <CJK>
+0xC3A1	0x737A	# <CJK>
+0xC3A2	0x74BD	# <CJK>
+0xC3A3	0x74CA	# <CJK>
+0xC3A4	0x74E3	# <CJK>
+0xC3A5	0x7587	# <CJK>
+0xC3A6	0x7586	# <CJK>
+0xC3A7	0x765F	# <CJK>
+0xC3A8	0x7661	# <CJK>
+0xC3A9	0x77C7	# <CJK>
+0xC3AA	0x7919	# <CJK>
+0xC3AB	0x79B1	# <CJK>
+0xC3AC	0x7A6B	# <CJK>
+0xC3AD	0x7A69	# <CJK>
+0xC3AE	0x7C3E	# <CJK>
+0xC3AF	0x7C3F	# <CJK>
+0xC3B0	0x7C38	# <CJK>
+0xC3B1	0x7C3D	# <CJK>
+0xC3B2	0x7C37	# <CJK>
+0xC3B3	0x7C40	# <CJK>
+0xC3B4	0x7E6B	# <CJK>
+0xC3B5	0x7E6D	# <CJK>
+0xC3B6	0x7E79	# <CJK>
+0xC3B7	0x7E69	# <CJK>
+0xC3B8	0x7E6A	# <CJK>
+0xC3B9	0x7F85	# <CJK>
+0xC3BA	0x7E73	# <CJK>
+0xC3BB	0x7FB6	# <CJK>
+0xC3BC	0x7FB9	# <CJK>
+0xC3BD	0x7FB8	# <CJK>
+0xC3BE	0x81D8	# <CJK>
+0xC3BF	0x85E9	# <CJK>
+0xC3C0	0x85DD	# <CJK>
+0xC3C1	0x85EA	# <CJK>
+0xC3C2	0x85D5	# <CJK>
+0xC3C3	0x85E4	# <CJK>
+0xC3C4	0x85E5	# <CJK>
+0xC3C5	0x85F7	# <CJK>
+0xC3C6	0x87FB	# <CJK>
+0xC3C7	0x8805	# <CJK>
+0xC3C8	0x880D	# <CJK>
+0xC3C9	0x87F9	# <CJK>
+0xC3CA	0x87FE	# <CJK>
+0xC3CB	0x8960	# <CJK>
+0xC3CC	0x895F	# <CJK>
+0xC3CD	0x8956	# <CJK>
+0xC3CE	0x895E	# <CJK>
+0xC3CF	0x8B41	# <CJK>
+0xC3D0	0x8B5C	# <CJK>
+0xC3D1	0x8B58	# <CJK>
+0xC3D2	0x8B49	# <CJK>
+0xC3D3	0x8B5A	# <CJK>
+0xC3D4	0x8B4E	# <CJK>
+0xC3D5	0x8B4F	# <CJK>
+0xC3D6	0x8B46	# <CJK>
+0xC3D7	0x8B59	# <CJK>
+0xC3D8	0x8D08	# <CJK>
+0xC3D9	0x8D0A	# <CJK>
+0xC3DA	0x8E7C	# <CJK>
+0xC3DB	0x8E72	# <CJK>
+0xC3DC	0x8E87	# <CJK>
+0xC3DD	0x8E76	# <CJK>
+0xC3DE	0x8E6C	# <CJK>
+0xC3DF	0x8E7A	# <CJK>
+0xC3E0	0x8E74	# <CJK>
+0xC3E1	0x8F54	# <CJK>
+0xC3E2	0x8F4E	# <CJK>
+0xC3E3	0x8FAD	# <CJK>
+0xC3E4	0x908A	# <CJK>
+0xC3E5	0x908B	# <CJK>
+0xC3E6	0x91B1	# <CJK>
+0xC3E7	0x91AE	# <CJK>
+0xC3E8	0x93E1	# <CJK>
+0xC3E9	0x93D1	# <CJK>
+0xC3EA	0x93DF	# <CJK>
+0xC3EB	0x93C3	# <CJK>
+0xC3EC	0x93C8	# <CJK>
+0xC3ED	0x93DC	# <CJK>
+0xC3EE	0x93DD	# <CJK>
+0xC3EF	0x93D6	# <CJK>
+0xC3F0	0x93E2	# <CJK>
+0xC3F1	0x93CD	# <CJK>
+0xC3F2	0x93D8	# <CJK>
+0xC3F3	0x93E4	# <CJK>
+0xC3F4	0x93D7	# <CJK>
+0xC3F5	0x93E8	# <CJK>
+0xC3F6	0x95DC	# <CJK>
+0xC3F7	0x96B4	# <CJK>
+0xC3F8	0x96E3	# <CJK>
+0xC3F9	0x972A	# <CJK>
+0xC3FA	0x9727	# <CJK>
+0xC3FB	0x9761	# <CJK>
+0xC3FC	0x97DC	# <CJK>
+0xC3FD	0x97FB	# <CJK>
+0xC3FE	0x985E	# <CJK>
+0xC440	0x9858	# <CJK>
+0xC441	0x985B	# <CJK>
+0xC442	0x98BC	# <CJK>
+0xC443	0x9945	# <CJK>
+0xC444	0x9949	# <CJK>
+0xC445	0x9A16	# <CJK>
+0xC446	0x9A19	# <CJK>
+0xC447	0x9B0D	# <CJK>
+0xC448	0x9BE8	# <CJK>
+0xC449	0x9BE7	# <CJK>
+0xC44A	0x9BD6	# <CJK>
+0xC44B	0x9BDB	# <CJK>
+0xC44C	0x9D89	# <CJK>
+0xC44D	0x9D61	# <CJK>
+0xC44E	0x9D72	# <CJK>
+0xC44F	0x9D6A	# <CJK>
+0xC450	0x9D6C	# <CJK>
+0xC451	0x9E92	# <CJK>
+0xC452	0x9E97	# <CJK>
+0xC453	0x9E93	# <CJK>
+0xC454	0x9EB4	# <CJK>
+0xC455	0x52F8	# <CJK>
+0xC456	0x56A8	# <CJK>
+0xC457	0x56B7	# <CJK>
+0xC458	0x56B6	# <CJK>
+0xC459	0x56B4	# <CJK>
+0xC45A	0x56BC	# <CJK>
+0xC45B	0x58E4	# <CJK>
+0xC45C	0x5B40	# <CJK>
+0xC45D	0x5B43	# <CJK>
+0xC45E	0x5B7D	# <CJK>
+0xC45F	0x5BF6	# <CJK>
+0xC460	0x5DC9	# <CJK>
+0xC461	0x61F8	# <CJK>
+0xC462	0x61FA	# <CJK>
+0xC463	0x6518	# <CJK>
+0xC464	0x6514	# <CJK>
+0xC465	0x6519	# <CJK>
+0xC466	0x66E6	# <CJK>
+0xC467	0x6727	# <CJK>
+0xC468	0x6AEC	# <CJK>
+0xC469	0x703E	# <CJK>
+0xC46A	0x7030	# <CJK>
+0xC46B	0x7032	# <CJK>
+0xC46C	0x7210	# <CJK>
+0xC46D	0x737B	# <CJK>
+0xC46E	0x74CF	# <CJK>
+0xC46F	0x7662	# <CJK>
+0xC470	0x7665	# <CJK>
+0xC471	0x7926	# <CJK>
+0xC472	0x792A	# <CJK>
+0xC473	0x792C	# <CJK>
+0xC474	0x792B	# <CJK>
+0xC475	0x7AC7	# <CJK>
+0xC476	0x7AF6	# <CJK>
+0xC477	0x7C4C	# <CJK>
+0xC478	0x7C43	# <CJK>
+0xC479	0x7C4D	# <CJK>
+0xC47A	0x7CEF	# <CJK>
+0xC47B	0x7CF0	# <CJK>
+0xC47C	0x8FAE	# <CJK>
+0xC47D	0x7E7D	# <CJK>
+0xC47E	0x7E7C	# <CJK>
+0xC4A1	0x7E82	# <CJK>
+0xC4A2	0x7F4C	# <CJK>
+0xC4A3	0x8000	# <CJK>
+0xC4A4	0x81DA	# <CJK>
+0xC4A5	0x8266	# <CJK>
+0xC4A6	0x85FB	# <CJK>
+0xC4A7	0x85F9	# <CJK>
+0xC4A8	0x8611	# <CJK>
+0xC4A9	0x85FA	# <CJK>
+0xC4AA	0x8606	# <CJK>
+0xC4AB	0x860B	# <CJK>
+0xC4AC	0x8607	# <CJK>
+0xC4AD	0x860A	# <CJK>
+0xC4AE	0x8814	# <CJK>
+0xC4AF	0x8815	# <CJK>
+0xC4B0	0x8964	# <CJK>
+0xC4B1	0x89BA	# <CJK>
+0xC4B2	0x89F8	# <CJK>
+0xC4B3	0x8B70	# <CJK>
+0xC4B4	0x8B6C	# <CJK>
+0xC4B5	0x8B66	# <CJK>
+0xC4B6	0x8B6F	# <CJK>
+0xC4B7	0x8B5F	# <CJK>
+0xC4B8	0x8B6B	# <CJK>
+0xC4B9	0x8D0F	# <CJK>
+0xC4BA	0x8D0D	# <CJK>
+0xC4BB	0x8E89	# <CJK>
+0xC4BC	0x8E81	# <CJK>
+0xC4BD	0x8E85	# <CJK>
+0xC4BE	0x8E82	# <CJK>
+0xC4BF	0x91B4	# <CJK>
+0xC4C0	0x91CB	# <CJK>
+0xC4C1	0x9418	# <CJK>
+0xC4C2	0x9403	# <CJK>
+0xC4C3	0x93FD	# <CJK>
+0xC4C4	0x95E1	# <CJK>
+0xC4C5	0x9730	# <CJK>
+0xC4C6	0x98C4	# <CJK>
+0xC4C7	0x9952	# <CJK>
+0xC4C8	0x9951	# <CJK>
+0xC4C9	0x99A8	# <CJK>
+0xC4CA	0x9A2B	# <CJK>
+0xC4CB	0x9A30	# <CJK>
+0xC4CC	0x9A37	# <CJK>
+0xC4CD	0x9A35	# <CJK>
+0xC4CE	0x9C13	# <CJK>
+0xC4CF	0x9C0D	# <CJK>
+0xC4D0	0x9E79	# <CJK>
+0xC4D1	0x9EB5	# <CJK>
+0xC4D2	0x9EE8	# <CJK>
+0xC4D3	0x9F2F	# <CJK>
+0xC4D4	0x9F5F	# <CJK>
+0xC4D5	0x9F63	# <CJK>
+0xC4D6	0x9F61	# <CJK>
+0xC4D7	0x5137	# <CJK>
+0xC4D8	0x5138	# <CJK>
+0xC4D9	0x56C1	# <CJK>
+0xC4DA	0x56C0	# <CJK>
+0xC4DB	0x56C2	# <CJK>
+0xC4DC	0x5914	# <CJK>
+0xC4DD	0x5C6C	# <CJK>
+0xC4DE	0x5DCD	# <CJK>
+0xC4DF	0x61FC	# <CJK>
+0xC4E0	0x61FE	# <CJK>
+0xC4E1	0x651D	# <CJK>
+0xC4E2	0x651C	# <CJK>
+0xC4E3	0x6595	# <CJK>
+0xC4E4	0x66E9	# <CJK>
+0xC4E5	0x6AFB	# <CJK>
+0xC4E6	0x6B04	# <CJK>
+0xC4E7	0x6AFA	# <CJK>
+0xC4E8	0x6BB2	# <CJK>
+0xC4E9	0x704C	# <CJK>
+0xC4EA	0x721B	# <CJK>
+0xC4EB	0x72A7	# <CJK>
+0xC4EC	0x74D6	# <CJK>
+0xC4ED	0x74D4	# <CJK>
+0xC4EE	0x7669	# <CJK>
+0xC4EF	0x77D3	# <CJK>
+0xC4F0	0x7C50	# <CJK>
+0xC4F1	0x7E8F	# <CJK>
+0xC4F2	0x7E8C	# <CJK>
+0xC4F3	0x7FBC	# <CJK>
+0xC4F4	0x8617	# <CJK>
+0xC4F5	0x862D	# <CJK>
+0xC4F6	0x861A	# <CJK>
+0xC4F7	0x8823	# <CJK>
+0xC4F8	0x8822	# <CJK>
+0xC4F9	0x8821	# <CJK>
+0xC4FA	0x881F	# <CJK>
+0xC4FB	0x896A	# <CJK>
+0xC4FC	0x896C	# <CJK>
+0xC4FD	0x89BD	# <CJK>
+0xC4FE	0x8B74	# <CJK>
+0xC540	0x8B77	# <CJK>
+0xC541	0x8B7D	# <CJK>
+0xC542	0x8D13	# <CJK>
+0xC543	0x8E8A	# <CJK>
+0xC544	0x8E8D	# <CJK>
+0xC545	0x8E8B	# <CJK>
+0xC546	0x8F5F	# <CJK>
+0xC547	0x8FAF	# <CJK>
+0xC548	0x91BA	# <CJK>
+0xC549	0x942E	# <CJK>
+0xC54A	0x9433	# <CJK>
+0xC54B	0x9435	# <CJK>
+0xC54C	0x943A	# <CJK>
+0xC54D	0x9438	# <CJK>
+0xC54E	0x9432	# <CJK>
+0xC54F	0x942B	# <CJK>
+0xC550	0x95E2	# <CJK>
+0xC551	0x9738	# <CJK>
+0xC552	0x9739	# <CJK>
+0xC553	0x9732	# <CJK>
+0xC554	0x97FF	# <CJK>
+0xC555	0x9867	# <CJK>
+0xC556	0x9865	# <CJK>
+0xC557	0x9957	# <CJK>
+0xC558	0x9A45	# <CJK>
+0xC559	0x9A43	# <CJK>
+0xC55A	0x9A40	# <CJK>
+0xC55B	0x9A3E	# <CJK>
+0xC55C	0x9ACF	# <CJK>
+0xC55D	0x9B54	# <CJK>
+0xC55E	0x9B51	# <CJK>
+0xC55F	0x9C2D	# <CJK>
+0xC560	0x9C25	# <CJK>
+0xC561	0x9DAF	# <CJK>
+0xC562	0x9DB4	# <CJK>
+0xC563	0x9DC2	# <CJK>
+0xC564	0x9DB8	# <CJK>
+0xC565	0x9E9D	# <CJK>
+0xC566	0x9EEF	# <CJK>
+0xC567	0x9F19	# <CJK>
+0xC568	0x9F5C	# <CJK>
+0xC569	0x9F66	# <CJK>
+0xC56A	0x9F67	# <CJK>
+0xC56B	0x513C	# <CJK>
+0xC56C	0x513B	# <CJK>
+0xC56D	0x56C8	# <CJK>
+0xC56E	0x56CA	# <CJK>
+0xC56F	0x56C9	# <CJK>
+0xC570	0x5B7F	# <CJK>
+0xC571	0x5DD4	# <CJK>
+0xC572	0x5DD2	# <CJK>
+0xC573	0x5F4E	# <CJK>
+0xC574	0x61FF	# <CJK>
+0xC575	0x6524	# <CJK>
+0xC576	0x6B0A	# <CJK>
+0xC577	0x6B61	# <CJK>
+0xC578	0x7051	# <CJK>
+0xC579	0x7058	# <CJK>
+0xC57A	0x7380	# <CJK>
+0xC57B	0x74E4	# <CJK>
+0xC57C	0x758A	# <CJK>
+0xC57D	0x766E	# <CJK>
+0xC57E	0x766C	# <CJK>
+0xC5A1	0x79B3	# <CJK>
+0xC5A2	0x7C60	# <CJK>
+0xC5A3	0x7C5F	# <CJK>
+0xC5A4	0x807E	# <CJK>
+0xC5A5	0x807D	# <CJK>
+0xC5A6	0x81DF	# <CJK>
+0xC5A7	0x8972	# <CJK>
+0xC5A8	0x896F	# <CJK>
+0xC5A9	0x89FC	# <CJK>
+0xC5AA	0x8B80	# <CJK>
+0xC5AB	0x8D16	# <CJK>
+0xC5AC	0x8D17	# <CJK>
+0xC5AD	0x8E91	# <CJK>
+0xC5AE	0x8E93	# <CJK>
+0xC5AF	0x8F61	# <CJK>
+0xC5B0	0x9148	# <CJK>
+0xC5B1	0x9444	# <CJK>
+0xC5B2	0x9451	# <CJK>
+0xC5B3	0x9452	# <CJK>
+0xC5B4	0x973D	# <CJK>
+0xC5B5	0x973E	# <CJK>
+0xC5B6	0x97C3	# <CJK>
+0xC5B7	0x97C1	# <CJK>
+0xC5B8	0x986B	# <CJK>
+0xC5B9	0x9955	# <CJK>
+0xC5BA	0x9A55	# <CJK>
+0xC5BB	0x9A4D	# <CJK>
+0xC5BC	0x9AD2	# <CJK>
+0xC5BD	0x9B1A	# <CJK>
+0xC5BE	0x9C49	# <CJK>
+0xC5BF	0x9C31	# <CJK>
+0xC5C0	0x9C3E	# <CJK>
+0xC5C1	0x9C3B	# <CJK>
+0xC5C2	0x9DD3	# <CJK>
+0xC5C3	0x9DD7	# <CJK>
+0xC5C4	0x9F34	# <CJK>
+0xC5C5	0x9F6C	# <CJK>
+0xC5C6	0x9F6A	# <CJK>
+0xC5C7	0x9F94	# <CJK>
+0xC5C8	0x56CC	# <CJK>
+0xC5C9	0x5DD6	# <CJK>
+0xC5CA	0x6200	# <CJK>
+0xC5CB	0x6523	# <CJK>
+0xC5CC	0x652B	# <CJK>
+0xC5CD	0x652A	# <CJK>
+0xC5CE	0x66EC	# <CJK>
+0xC5CF	0x6B10	# <CJK>
+0xC5D0	0x74DA	# <CJK>
+0xC5D1	0x7ACA	# <CJK>
+0xC5D2	0x7C64	# <CJK>
+0xC5D3	0x7C63	# <CJK>
+0xC5D4	0x7C65	# <CJK>
+0xC5D5	0x7E93	# <CJK>
+0xC5D6	0x7E96	# <CJK>
+0xC5D7	0x7E94	# <CJK>
+0xC5D8	0x81E2	# <CJK>
+0xC5D9	0x8638	# <CJK>
+0xC5DA	0x863F	# <CJK>
+0xC5DB	0x8831	# <CJK>
+0xC5DC	0x8B8A	# <CJK>
+0xC5DD	0x9090	# <CJK>
+0xC5DE	0x908F	# <CJK>
+0xC5DF	0x9463	# <CJK>
+0xC5E0	0x9460	# <CJK>
+0xC5E1	0x9464	# <CJK>
+0xC5E2	0x9768	# <CJK>
+0xC5E3	0x986F	# <CJK>
+0xC5E4	0x995C	# <CJK>
+0xC5E5	0x9A5A	# <CJK>
+0xC5E6	0x9A5B	# <CJK>
+0xC5E7	0x9A57	# <CJK>
+0xC5E8	0x9AD3	# <CJK>
+0xC5E9	0x9AD4	# <CJK>
+0xC5EA	0x9AD1	# <CJK>
+0xC5EB	0x9C54	# <CJK>
+0xC5EC	0x9C57	# <CJK>
+0xC5ED	0x9C56	# <CJK>
+0xC5EE	0x9DE5	# <CJK>
+0xC5EF	0x9E9F	# <CJK>
+0xC5F0	0x9EF4	# <CJK>
+0xC5F1	0x56D1	# <CJK>
+0xC5F2	0x58E9	# <CJK>
+0xC5F3	0x652C	# <CJK>
+0xC5F4	0x705E	# <CJK>
+0xC5F5	0x7671	# <CJK>
+0xC5F6	0x7672	# <CJK>
+0xC5F7	0x77D7	# <CJK>
+0xC5F8	0x7F50	# <CJK>
+0xC5F9	0x7F88	# <CJK>
+0xC5FA	0x8836	# <CJK>
+0xC5FB	0x8839	# <CJK>
+0xC5FC	0x8862	# <CJK>
+0xC5FD	0x8B93	# <CJK>
+0xC5FE	0x8B92	# <CJK>
+0xC640	0x8B96	# <CJK>
+0xC641	0x8277	# <CJK>
+0xC642	0x8D1B	# <CJK>
+0xC643	0x91C0	# <CJK>
+0xC644	0x946A	# <CJK>
+0xC645	0x9742	# <CJK>
+0xC646	0x9748	# <CJK>
+0xC647	0x9744	# <CJK>
+0xC648	0x97C6	# <CJK>
+0xC649	0x9870	# <CJK>
+0xC64A	0x9A5F	# <CJK>
+0xC64B	0x9B22	# <CJK>
+0xC64C	0x9B58	# <CJK>
+0xC64D	0x9C5F	# <CJK>
+0xC64E	0x9DF9	# <CJK>
+0xC64F	0x9DFA	# <CJK>
+0xC650	0x9E7C	# <CJK>
+0xC651	0x9E7D	# <CJK>
+0xC652	0x9F07	# <CJK>
+0xC653	0x9F77	# <CJK>
+0xC654	0x9F72	# <CJK>
+0xC655	0x5EF3	# <CJK>
+0xC656	0x6B16	# <CJK>
+0xC657	0x7063	# <CJK>
+0xC658	0x7C6C	# <CJK>
+0xC659	0x7C6E	# <CJK>
+0xC65A	0x883B	# <CJK>
+0xC65B	0x89C0	# <CJK>
+0xC65C	0x8EA1	# <CJK>
+0xC65D	0x91C1	# <CJK>
+0xC65E	0x9472	# <CJK>
+0xC65F	0x9470	# <CJK>
+0xC660	0x9871	# <CJK>
+0xC661	0x995E	# <CJK>
+0xC662	0x9AD6	# <CJK>
+0xC663	0x9B23	# <CJK>
+0xC664	0x9ECC	# <CJK>
+0xC665	0x7064	# <CJK>
+0xC666	0x77DA	# <CJK>
+0xC667	0x8B9A	# <CJK>
+0xC668	0x9477	# <CJK>
+0xC669	0x97C9	# <CJK>
+0xC66A	0x9A62	# <CJK>
+0xC66B	0x9A65	# <CJK>
+0xC66C	0x7E9C	# <CJK>
+0xC66D	0x8B9C	# <CJK>
+0xC66E	0x8EAA	# <CJK>
+0xC66F	0x91C5	# <CJK>
+0xC670	0x947D	# <CJK>
+0xC671	0x947E	# <CJK>
+0xC672	0x947C	# <CJK>
+0xC673	0x9C77	# <CJK>
+0xC674	0x9C78	# <CJK>
+0xC675	0x9EF7	# <CJK>
+0xC676	0x8C54	# <CJK>
+0xC677	0x947F	# <CJK>
+0xC678	0x9E1A	# <CJK>
+0xC679	0x7228	# <CJK>
+0xC67A	0x9A6A	# <CJK>
+0xC67B	0x9B31	# <CJK>
+0xC67C	0x9E1B	# <CJK>
+0xC67D	0x9E1E	# <CJK>
+0xC67E	0x7C72	# <CJK>
+0xC6A1	0x30FE	# KATAKANA VOICED ITERATION MARK
+0xC6A2	0x309D	# HIRAGANA ITERATION MARK
+0xC6A3	0x309E	# HIRAGANA VOICED ITERATION MARK
+0xC6A4	0x3005	# IDEOGRAPHIC ITERATION MARK
+0xC6A5	0x3041	# HIRAGANA LETTER SMALL A
+0xC6A6	0x3042	# HIRAGANA LETTER A
+0xC6A7	0x3043	# HIRAGANA LETTER SMALL I
+0xC6A8	0x3044	# HIRAGANA LETTER I
+0xC6A9	0x3045	# HIRAGANA LETTER SMALL U
+0xC6AA	0x3046	# HIRAGANA LETTER U
+0xC6AB	0x3047	# HIRAGANA LETTER SMALL E
+0xC6AC	0x3048	# HIRAGANA LETTER E
+0xC6AD	0x3049	# HIRAGANA LETTER SMALL O
+0xC6AE	0x304A	# HIRAGANA LETTER O
+0xC6AF	0x304B	# HIRAGANA LETTER KA
+0xC6B0	0x304C	# HIRAGANA LETTER GA
+0xC6B1	0x304D	# HIRAGANA LETTER KI
+0xC6B2	0x304E	# HIRAGANA LETTER GI
+0xC6B3	0x304F	# HIRAGANA LETTER KU
+0xC6B4	0x3050	# HIRAGANA LETTER GU
+0xC6B5	0x3051	# HIRAGANA LETTER KE
+0xC6B6	0x3052	# HIRAGANA LETTER GE
+0xC6B7	0x3053	# HIRAGANA LETTER KO
+0xC6B8	0x3054	# HIRAGANA LETTER GO
+0xC6B9	0x3055	# HIRAGANA LETTER SA
+0xC6BA	0x3056	# HIRAGANA LETTER ZA
+0xC6BB	0x3057	# HIRAGANA LETTER SI
+0xC6BC	0x3058	# HIRAGANA LETTER ZI
+0xC6BD	0x3059	# HIRAGANA LETTER SU
+0xC6BE	0x305A	# HIRAGANA LETTER ZU
+0xC6BF	0x305B	# HIRAGANA LETTER SE
+0xC6C0	0x305C	# HIRAGANA LETTER ZE
+0xC6C1	0x305D	# HIRAGANA LETTER SO
+0xC6C2	0x305E	# HIRAGANA LETTER ZO
+0xC6C3	0x305F	# HIRAGANA LETTER TA
+0xC6C4	0x3060	# HIRAGANA LETTER DA
+0xC6C5	0x3061	# HIRAGANA LETTER TI
+0xC6C6	0x3062	# HIRAGANA LETTER DI
+0xC6C7	0x3063	# HIRAGANA LETTER SMALL TU
+0xC6C8	0x3064	# HIRAGANA LETTER TU
+0xC6C9	0x3065	# HIRAGANA LETTER DU
+0xC6CA	0x3066	# HIRAGANA LETTER TE
+0xC6CB	0x3067	# HIRAGANA LETTER DE
+0xC6CC	0x3068	# HIRAGANA LETTER TO
+0xC6CD	0x3069	# HIRAGANA LETTER DO
+0xC6CE	0x306A	# HIRAGANA LETTER NA
+0xC6CF	0x306B	# HIRAGANA LETTER NI
+0xC6D0	0x306C	# HIRAGANA LETTER NU
+0xC6D1	0x306D	# HIRAGANA LETTER NE
+0xC6D2	0x306E	# HIRAGANA LETTER NO
+0xC6D3	0x306F	# HIRAGANA LETTER HA
+0xC6D4	0x3070	# HIRAGANA LETTER BA
+0xC6D5	0x3071	# HIRAGANA LETTER PA
+0xC6D6	0x3072	# HIRAGANA LETTER HI
+0xC6D7	0x3073	# HIRAGANA LETTER BI
+0xC6D8	0x3074	# HIRAGANA LETTER PI
+0xC6D9	0x3075	# HIRAGANA LETTER HU
+0xC6DA	0x3076	# HIRAGANA LETTER BU
+0xC6DB	0x3077	# HIRAGANA LETTER PU
+0xC6DC	0x3078	# HIRAGANA LETTER HE
+0xC6DD	0x3079	# HIRAGANA LETTER BE
+0xC6DE	0x307A	# HIRAGANA LETTER PE
+0xC6DF	0x307B	# HIRAGANA LETTER HO
+0xC6E0	0x307C	# HIRAGANA LETTER BO
+0xC6E1	0x307D	# HIRAGANA LETTER PO
+0xC6E2	0x307E	# HIRAGANA LETTER MA
+0xC6E3	0x307F	# HIRAGANA LETTER MI
+0xC6E4	0x3080	# HIRAGANA LETTER MU
+0xC6E5	0x3081	# HIRAGANA LETTER ME
+0xC6E6	0x3082	# HIRAGANA LETTER MO
+0xC6E7	0x3083	# HIRAGANA LETTER SMALL YA
+0xC6E8	0x3084	# HIRAGANA LETTER YA
+0xC6E9	0x3085	# HIRAGANA LETTER SMALL YU
+0xC6EA	0x3086	# HIRAGANA LETTER YU
+0xC6EB	0x3087	# HIRAGANA LETTER SMALL YO
+0xC6EC	0x3088	# HIRAGANA LETTER YO
+0xC6ED	0x3089	# HIRAGANA LETTER RA
+0xC6EE	0x308A	# HIRAGANA LETTER RI
+0xC6EF	0x308B	# HIRAGANA LETTER RU
+0xC6F0	0x308C	# HIRAGANA LETTER RE
+0xC6F1	0x308D	# HIRAGANA LETTER RO
+0xC6F2	0x308E	# HIRAGANA LETTER SMALL WA
+0xC6F3	0x308F	# HIRAGANA LETTER WA
+0xC6F4	0x3090	# HIRAGANA LETTER WI
+0xC6F5	0x3091	# HIRAGANA LETTER WE
+0xC6F6	0x3092	# HIRAGANA LETTER WO
+0xC6F7	0x3093	# HIRAGANA LETTER N
+0xC6F8	0x30A1	# KATAKANA LETTER SMALL A
+0xC6F9	0x30A2	# KATAKANA LETTER A
+0xC6FA	0x30A3	# KATAKANA LETTER SMALL I
+0xC6FB	0x30A4	# KATAKANA LETTER I
+0xC6FC	0x30A5	# KATAKANA LETTER SMALL U
+0xC6FD	0x30A6	# KATAKANA LETTER U
+0xC6FE	0x30A7	# KATAKANA LETTER SMALL E
+0xC740	0x30A8	# KATAKANA LETTER E
+0xC741	0x30A9	# KATAKANA LETTER SMALL O
+0xC742	0x30AA	# KATAKANA LETTER O
+0xC743	0x30AB	# KATAKANA LETTER KA
+0xC744	0x30AC	# KATAKANA LETTER GA
+0xC745	0x30AD	# KATAKANA LETTER KI
+0xC746	0x30AE	# KATAKANA LETTER GI
+0xC747	0x30AF	# KATAKANA LETTER KU
+0xC748	0x30B0	# KATAKANA LETTER GU
+0xC749	0x30B1	# KATAKANA LETTER KE
+0xC74A	0x30B2	# KATAKANA LETTER GE
+0xC74B	0x30B3	# KATAKANA LETTER KO
+0xC74C	0x30B4	# KATAKANA LETTER GO
+0xC74D	0x30B5	# KATAKANA LETTER SA
+0xC74E	0x30B6	# KATAKANA LETTER ZA
+0xC74F	0x30B7	# KATAKANA LETTER SI
+0xC750	0x30B8	# KATAKANA LETTER ZI
+0xC751	0x30B9	# KATAKANA LETTER SU
+0xC752	0x30BA	# KATAKANA LETTER ZU
+0xC753	0x30BB	# KATAKANA LETTER SE
+0xC754	0x30BC	# KATAKANA LETTER ZE
+0xC755	0x30BD	# KATAKANA LETTER SO
+0xC756	0x30BE	# KATAKANA LETTER ZO
+0xC757	0x30BF	# KATAKANA LETTER TA
+0xC758	0x30C0	# KATAKANA LETTER DA
+0xC759	0x30C1	# KATAKANA LETTER TI
+0xC75A	0x30C2	# KATAKANA LETTER DI
+0xC75B	0x30C3	# KATAKANA LETTER SMALL TU
+0xC75C	0x30C4	# KATAKANA LETTER TU
+0xC75D	0x30C5	# KATAKANA LETTER DU
+0xC75E	0x30C6	# KATAKANA LETTER TE
+0xC75F	0x30C7	# KATAKANA LETTER DE
+0xC760	0x30C8	# KATAKANA LETTER TO
+0xC761	0x30C9	# KATAKANA LETTER DO
+0xC762	0x30CA	# KATAKANA LETTER NA
+0xC763	0x30CB	# KATAKANA LETTER NI
+0xC764	0x30CC	# KATAKANA LETTER NU
+0xC765	0x30CD	# KATAKANA LETTER NE
+0xC766	0x30CE	# KATAKANA LETTER NO
+0xC767	0x30CF	# KATAKANA LETTER HA
+0xC768	0x30D0	# KATAKANA LETTER BA
+0xC769	0x30D1	# KATAKANA LETTER PA
+0xC76A	0x30D2	# KATAKANA LETTER HI
+0xC76B	0x30D3	# KATAKANA LETTER BI
+0xC76C	0x30D4	# KATAKANA LETTER PI
+0xC76D	0x30D5	# KATAKANA LETTER HU
+0xC76E	0x30D6	# KATAKANA LETTER BU
+0xC76F	0x30D7	# KATAKANA LETTER PU
+0xC770	0x30D8	# KATAKANA LETTER HE
+0xC771	0x30D9	# KATAKANA LETTER BE
+0xC772	0x30DA	# KATAKANA LETTER PE
+0xC773	0x30DB	# KATAKANA LETTER HO
+0xC774	0x30DC	# KATAKANA LETTER BO
+0xC775	0x30DD	# KATAKANA LETTER PO
+0xC776	0x30DE	# KATAKANA LETTER MA
+0xC777	0x30DF	# KATAKANA LETTER MI
+0xC778	0x30E0	# KATAKANA LETTER MU
+0xC779	0x30E1	# KATAKANA LETTER ME
+0xC77A	0x30E2	# KATAKANA LETTER MO
+0xC77B	0x30E3	# KATAKANA LETTER SMALL YA
+0xC77C	0x30E4	# KATAKANA LETTER YA
+0xC77D	0x30E5	# KATAKANA LETTER SMALL YU
+0xC77E	0x30E6	# KATAKANA LETTER YU
+0xC7A1	0x30E7	# KATAKANA LETTER SMALL YO
+0xC7A2	0x30E8	# KATAKANA LETTER YO
+0xC7A3	0x30E9	# KATAKANA LETTER RA
+0xC7A4	0x30EA	# KATAKANA LETTER RI
+0xC7A5	0x30EB	# KATAKANA LETTER RU
+0xC7A6	0x30EC	# KATAKANA LETTER RE
+0xC7A7	0x30ED	# KATAKANA LETTER RO
+0xC7A8	0x30EE	# KATAKANA LETTER SMALL WA
+0xC7A9	0x30EF	# KATAKANA LETTER WA
+0xC7AA	0x30F0	# KATAKANA LETTER WI
+0xC7AB	0x30F1	# KATAKANA LETTER WE
+0xC7AC	0x30F2	# KATAKANA LETTER WO
+0xC7AD	0x30F3	# KATAKANA LETTER N
+0xC7AE	0x30F4	# KATAKANA LETTER VU
+0xC7AF	0x30F5	# KATAKANA LETTER SMALL KA
+0xC7B0	0x30F6	# KATAKANA LETTER SMALL KE
+0xC7B1	0x0414	# CYRILLIC CAPITAL LETTER DE
+0xC7B2	0x0415	# CYRILLIC CAPITAL LETTER IE
+0xC7B3	0x0401	# CYRILLIC CAPITAL LETTER IO
+0xC7B4	0x0416	# CYRILLIC CAPITAL LETTER ZHE
+0xC7B5	0x0417	# CYRILLIC CAPITAL LETTER ZE
+0xC7B6	0x0418	# CYRILLIC CAPITAL LETTER I
+0xC7B7	0x0419	# CYRILLIC CAPITAL LETTER SHORT I
+0xC7B8	0x041A	# CYRILLIC CAPITAL LETTER KA
+0xC7B9	0x041B	# CYRILLIC CAPITAL LETTER EL
+0xC7BA	0x041C	# CYRILLIC CAPITAL LETTER EM
+0xC7BB	0x0423	# CYRILLIC CAPITAL LETTER U
+0xC7BC	0x0424	# CYRILLIC CAPITAL LETTER EF
+0xC7BD	0x0425	# CYRILLIC CAPITAL LETTER HA
+0xC7BE	0x0426	# CYRILLIC CAPITAL LETTER TSE
+0xC7BF	0x0427	# CYRILLIC CAPITAL LETTER CHE
+0xC7C0	0x0428	# CYRILLIC CAPITAL LETTER SHA
+0xC7C1	0x0429	# CYRILLIC CAPITAL LETTER SHCHA
+0xC7C2	0x042A	# CYRILLIC CAPITAL LETTER HARD SIGN
+0xC7C3	0x042B	# CYRILLIC CAPITAL LETTER YERU
+0xC7C4	0x042C	# CYRILLIC CAPITAL LETTER SOFT SIGN
+0xC7C5	0x042D	# CYRILLIC CAPITAL LETTER E
+0xC7C6	0x042E	# CYRILLIC CAPITAL LETTER YU
+0xC7C7	0x042F	# CYRILLIC CAPITAL LETTER YA
+0xC7C8	0x0430	# CYRILLIC SMALL LETTER A
+0xC7C9	0x0431	# CYRILLIC SMALL LETTER BE
+0xC7CA	0x0432	# CYRILLIC SMALL LETTER VE
+0xC7CB	0x0433	# CYRILLIC SMALL LETTER GHE
+0xC7CC	0x0434	# CYRILLIC SMALL LETTER DE
+0xC7CD	0x0435	# CYRILLIC SMALL LETTER IE
+0xC7CE	0x0451	# CYRILLIC SMALL LETTER IO
+0xC7CF	0x0436	# CYRILLIC SMALL LETTER ZHE
+0xC7D0	0x0437	# CYRILLIC SMALL LETTER ZE
+0xC7D1	0x0438	# CYRILLIC SMALL LETTER I
+0xC7D2	0x0439	# CYRILLIC SMALL LETTER SHORT I
+0xC7D3	0x043A	# CYRILLIC SMALL LETTER KA
+0xC7D4	0x043B	# CYRILLIC SMALL LETTER EL
+0xC7D5	0x043C	# CYRILLIC SMALL LETTER EM
+0xC7D6	0x043D	# CYRILLIC SMALL LETTER EN
+0xC7D7	0x043E	# CYRILLIC SMALL LETTER O
+0xC7D8	0x043F	# CYRILLIC SMALL LETTER PE
+0xC7D9	0x0440	# CYRILLIC SMALL LETTER ER
+0xC7DA	0x0441	# CYRILLIC SMALL LETTER ES
+0xC7DB	0x0442	# CYRILLIC SMALL LETTER TE
+0xC7DC	0x0443	# CYRILLIC SMALL LETTER U
+0xC7DD	0x0444	# CYRILLIC SMALL LETTER EF
+0xC7DE	0x0445	# CYRILLIC SMALL LETTER HA
+0xC7DF	0x0446	# CYRILLIC SMALL LETTER TSE
+0xC7E0	0x0447	# CYRILLIC SMALL LETTER CHE
+0xC7E1	0x0448	# CYRILLIC SMALL LETTER SHA
+0xC7E2	0x0449	# CYRILLIC SMALL LETTER SHCHA
+0xC7E3	0x044A	# CYRILLIC SMALL LETTER HARD SIGN
+0xC7E4	0x044B	# CYRILLIC SMALL LETTER YERU
+0xC7E5	0x044C	# CYRILLIC SMALL LETTER SOFT SIGN
+0xC7E6	0x044D	# CYRILLIC SMALL LETTER E
+0xC7E7	0x044E	# CYRILLIC SMALL LETTER YU
+0xC7E8	0x044F	# CYRILLIC SMALL LETTER YA
+0xC7E9	0x2460	# CIRCLED DIGIT ONE
+0xC7EA	0x2461	# CIRCLED DIGIT TWO
+0xC7EB	0x2462	# CIRCLED DIGIT THREE
+0xC7EC	0x2463	# CIRCLED DIGIT FOUR
+0xC7ED	0x2464	# CIRCLED DIGIT FIVE
+0xC7EE	0x2465	# CIRCLED DIGIT SIX
+0xC7EF	0x2466	# CIRCLED DIGIT SEVEN
+0xC7F0	0x2467	# CIRCLED DIGIT EIGHT
+0xC7F1	0x2468	# CIRCLED DIGIT NINE
+0xC7F2	0x2469	# CIRCLED NUMBER TEN
+0xC7F3	0x2474	# PARENTHESIZED DIGIT ONE
+0xC7F4	0x2475	# PARENTHESIZED DIGIT TWO
+0xC7F5	0x2476	# PARENTHESIZED DIGIT THREE
+0xC7F6	0x2477	# PARENTHESIZED DIGIT FOUR
+0xC7F7	0x2478	# PARENTHESIZED DIGIT FIVE
+0xC7F8	0x2479	# PARENTHESIZED DIGIT SIX
+0xC7F9	0x247A	# PARENTHESIZED DIGIT SEVEN
+0xC7FA	0x247B	# PARENTHESIZED DIGIT EIGHT
+0xC7FB	0x247C	# PARENTHESIZED DIGIT NINE
+0xC7FC	0x247D	# PARENTHESIZED NUMBER TEN
+0xC940	0x4E42	# <CJK>
+0xC941	0x4E5C	# <CJK>
+0xC942	0x51F5	# <CJK>
+0xC943	0x531A	# <CJK>
+0xC944	0x5382	# <CJK>
+0xC945	0x4E07	# <CJK>
+0xC946	0x4E0C	# <CJK>
+0xC947	0x4E47	# <CJK>
+0xC948	0x4E8D	# <CJK>
+0xC949	0x56D7	# <CJK>
+0xC94A	0xFA0C	# CJK COMPATIBILITY IDEOGRAPH-FA0C
+0xC94B	0x5C6E	# <CJK>
+0xC94C	0x5F73	# <CJK>
+0xC94D	0x4E0F	# <CJK>
+0xC94E	0x5187	# <CJK>
+0xC94F	0x4E0E	# <CJK>
+0xC950	0x4E2E	# <CJK>
+0xC951	0x4E93	# <CJK>
+0xC952	0x4EC2	# <CJK>
+0xC953	0x4EC9	# <CJK>
+0xC954	0x4EC8	# <CJK>
+0xC955	0x5198	# <CJK>
+0xC956	0x52FC	# <CJK>
+0xC957	0x536C	# <CJK>
+0xC958	0x53B9	# <CJK>
+0xC959	0x5720	# <CJK>
+0xC95A	0x5903	# <CJK>
+0xC95B	0x592C	# <CJK>
+0xC95C	0x5C10	# <CJK>
+0xC95D	0x5DFF	# <CJK>
+0xC95E	0x65E1	# <CJK>
+0xC95F	0x6BB3	# <CJK>
+0xC960	0x6BCC	# <CJK>
+0xC961	0x6C14	# <CJK>
+0xC962	0x723F	# <CJK>
+0xC963	0x4E31	# <CJK>
+0xC964	0x4E3C	# <CJK>
+0xC965	0x4EE8	# <CJK>
+0xC966	0x4EDC	# <CJK>
+0xC967	0x4EE9	# <CJK>
+0xC968	0x4EE1	# <CJK>
+0xC969	0x4EDD	# <CJK>
+0xC96A	0x4EDA	# <CJK>
+0xC96B	0x520C	# <CJK>
+0xC96C	0x531C	# <CJK>
+0xC96D	0x534C	# <CJK>
+0xC96E	0x5722	# <CJK>
+0xC96F	0x5723	# <CJK>
+0xC970	0x5917	# <CJK>
+0xC971	0x592F	# <CJK>
+0xC972	0x5B81	# <CJK>
+0xC973	0x5B84	# <CJK>
+0xC974	0x5C12	# <CJK>
+0xC975	0x5C3B	# <CJK>
+0xC976	0x5C74	# <CJK>
+0xC977	0x5C73	# <CJK>
+0xC978	0x5E04	# <CJK>
+0xC979	0x5E80	# <CJK>
+0xC97A	0x5E82	# <CJK>
+0xC97B	0x5FC9	# <CJK>
+0xC97C	0x6209	# <CJK>
+0xC97D	0x6250	# <CJK>
+0xC97E	0x6C15	# <CJK>
+0xC9A1	0x6C36	# <CJK>
+0xC9A2	0x6C43	# <CJK>
+0xC9A3	0x6C3F	# <CJK>
+0xC9A4	0x6C3B	# <CJK>
+0xC9A5	0x72AE	# <CJK>
+0xC9A6	0x72B0	# <CJK>
+0xC9A7	0x738A	# <CJK>
+0xC9A8	0x79B8	# <CJK>
+0xC9A9	0x808A	# <CJK>
+0xC9AA	0x961E	# <CJK>
+0xC9AB	0x4F0E	# <CJK>
+0xC9AC	0x4F18	# <CJK>
+0xC9AD	0x4F2C	# <CJK>
+0xC9AE	0x4EF5	# <CJK>
+0xC9AF	0x4F14	# <CJK>
+0xC9B0	0x4EF1	# <CJK>
+0xC9B1	0x4F00	# <CJK>
+0xC9B2	0x4EF7	# <CJK>
+0xC9B3	0x4F08	# <CJK>
+0xC9B4	0x4F1D	# <CJK>
+0xC9B5	0x4F02	# <CJK>
+0xC9B6	0x4F05	# <CJK>
+0xC9B7	0x4F22	# <CJK>
+0xC9B8	0x4F13	# <CJK>
+0xC9B9	0x4F04	# <CJK>
+0xC9BA	0x4EF4	# <CJK>
+0xC9BB	0x4F12	# <CJK>
+0xC9BC	0x51B1	# <CJK>
+0xC9BD	0x5213	# <CJK>
+0xC9BE	0x5209	# <CJK>
+0xC9BF	0x5210	# <CJK>
+0xC9C0	0x52A6	# <CJK>
+0xC9C1	0x5322	# <CJK>
+0xC9C2	0x531F	# <CJK>
+0xC9C3	0x534D	# <CJK>
+0xC9C4	0x538A	# <CJK>
+0xC9C5	0x5407	# <CJK>
+0xC9C6	0x56E1	# <CJK>
+0xC9C7	0x56DF	# <CJK>
+0xC9C8	0x572E	# <CJK>
+0xC9C9	0x572A	# <CJK>
+0xC9CA	0x5734	# <CJK>
+0xC9CB	0x593C	# <CJK>
+0xC9CC	0x5980	# <CJK>
+0xC9CD	0x597C	# <CJK>
+0xC9CE	0x5985	# <CJK>
+0xC9CF	0x597B	# <CJK>
+0xC9D0	0x597E	# <CJK>
+0xC9D1	0x5977	# <CJK>
+0xC9D2	0x597F	# <CJK>
+0xC9D3	0x5B56	# <CJK>
+0xC9D4	0x5C15	# <CJK>
+0xC9D5	0x5C25	# <CJK>
+0xC9D6	0x5C7C	# <CJK>
+0xC9D7	0x5C7A	# <CJK>
+0xC9D8	0x5C7B	# <CJK>
+0xC9D9	0x5C7E	# <CJK>
+0xC9DA	0x5DDF	# <CJK>
+0xC9DB	0x5E75	# <CJK>
+0xC9DC	0x5E84	# <CJK>
+0xC9DD	0x5F02	# <CJK>
+0xC9DE	0x5F1A	# <CJK>
+0xC9DF	0x5F74	# <CJK>
+0xC9E0	0x5FD5	# <CJK>
+0xC9E1	0x5FD4	# <CJK>
+0xC9E2	0x5FCF	# <CJK>
+0xC9E3	0x625C	# <CJK>
+0xC9E4	0x625E	# <CJK>
+0xC9E5	0x6264	# <CJK>
+0xC9E6	0x6261	# <CJK>
+0xC9E7	0x6266	# <CJK>
+0xC9E8	0x6262	# <CJK>
+0xC9E9	0x6259	# <CJK>
+0xC9EA	0x6260	# <CJK>
+0xC9EB	0x625A	# <CJK>
+0xC9EC	0x6265	# <CJK>
+0xC9ED	0x65EF	# <CJK>
+0xC9EE	0x65EE	# <CJK>
+0xC9EF	0x673E	# <CJK>
+0xC9F0	0x6739	# <CJK>
+0xC9F1	0x6738	# <CJK>
+0xC9F2	0x673B	# <CJK>
+0xC9F3	0x673A	# <CJK>
+0xC9F4	0x673F	# <CJK>
+0xC9F5	0x673C	# <CJK>
+0xC9F6	0x6733	# <CJK>
+0xC9F7	0x6C18	# <CJK>
+0xC9F8	0x6C46	# <CJK>
+0xC9F9	0x6C52	# <CJK>
+0xC9FA	0x6C5C	# <CJK>
+0xC9FB	0x6C4F	# <CJK>
+0xC9FC	0x6C4A	# <CJK>
+0xC9FD	0x6C54	# <CJK>
+0xC9FE	0x6C4B	# <CJK>
+0xCA40	0x6C4C	# <CJK>
+0xCA41	0x7071	# <CJK>
+0xCA42	0x725E	# <CJK>
+0xCA43	0x72B4	# <CJK>
+0xCA44	0x72B5	# <CJK>
+0xCA45	0x738E	# <CJK>
+0xCA46	0x752A	# <CJK>
+0xCA47	0x767F	# <CJK>
+0xCA48	0x7A75	# <CJK>
+0xCA49	0x7F51	# <CJK>
+0xCA4A	0x8278	# <CJK>
+0xCA4B	0x827C	# <CJK>
+0xCA4C	0x8280	# <CJK>
+0xCA4D	0x827D	# <CJK>
+0xCA4E	0x827F	# <CJK>
+0xCA4F	0x864D	# <CJK>
+0xCA50	0x897E	# <CJK>
+0xCA51	0x9099	# <CJK>
+0xCA52	0x9097	# <CJK>
+0xCA53	0x9098	# <CJK>
+0xCA54	0x909B	# <CJK>
+0xCA55	0x9094	# <CJK>
+0xCA56	0x9622	# <CJK>
+0xCA57	0x9624	# <CJK>
+0xCA58	0x9620	# <CJK>
+0xCA59	0x9623	# <CJK>
+0xCA5A	0x4F56	# <CJK>
+0xCA5B	0x4F3B	# <CJK>
+0xCA5C	0x4F62	# <CJK>
+0xCA5D	0x4F49	# <CJK>
+0xCA5E	0x4F53	# <CJK>
+0xCA5F	0x4F64	# <CJK>
+0xCA60	0x4F3E	# <CJK>
+0xCA61	0x4F67	# <CJK>
+0xCA62	0x4F52	# <CJK>
+0xCA63	0x4F5F	# <CJK>
+0xCA64	0x4F41	# <CJK>
+0xCA65	0x4F58	# <CJK>
+0xCA66	0x4F2D	# <CJK>
+0xCA67	0x4F33	# <CJK>
+0xCA68	0x4F3F	# <CJK>
+0xCA69	0x4F61	# <CJK>
+0xCA6A	0x518F	# <CJK>
+0xCA6B	0x51B9	# <CJK>
+0xCA6C	0x521C	# <CJK>
+0xCA6D	0x521E	# <CJK>
+0xCA6E	0x5221	# <CJK>
+0xCA6F	0x52AD	# <CJK>
+0xCA70	0x52AE	# <CJK>
+0xCA71	0x5309	# <CJK>
+0xCA72	0x5363	# <CJK>
+0xCA73	0x5372	# <CJK>
+0xCA74	0x538E	# <CJK>
+0xCA75	0x538F	# <CJK>
+0xCA76	0x5430	# <CJK>
+0xCA77	0x5437	# <CJK>
+0xCA78	0x542A	# <CJK>
+0xCA79	0x5454	# <CJK>
+0xCA7A	0x5445	# <CJK>
+0xCA7B	0x5419	# <CJK>
+0xCA7C	0x541C	# <CJK>
+0xCA7D	0x5425	# <CJK>
+0xCA7E	0x5418	# <CJK>
+0xCAA1	0x543D	# <CJK>
+0xCAA2	0x544F	# <CJK>
+0xCAA3	0x5441	# <CJK>
+0xCAA4	0x5428	# <CJK>
+0xCAA5	0x5424	# <CJK>
+0xCAA6	0x5447	# <CJK>
+0xCAA7	0x56EE	# <CJK>
+0xCAA8	0x56E7	# <CJK>
+0xCAA9	0x56E5	# <CJK>
+0xCAAA	0x5741	# <CJK>
+0xCAAB	0x5745	# <CJK>
+0xCAAC	0x574C	# <CJK>
+0xCAAD	0x5749	# <CJK>
+0xCAAE	0x574B	# <CJK>
+0xCAAF	0x5752	# <CJK>
+0xCAB0	0x5906	# <CJK>
+0xCAB1	0x5940	# <CJK>
+0xCAB2	0x59A6	# <CJK>
+0xCAB3	0x5998	# <CJK>
+0xCAB4	0x59A0	# <CJK>
+0xCAB5	0x5997	# <CJK>
+0xCAB6	0x598E	# <CJK>
+0xCAB7	0x59A2	# <CJK>
+0xCAB8	0x5990	# <CJK>
+0xCAB9	0x598F	# <CJK>
+0xCABA	0x59A7	# <CJK>
+0xCABB	0x59A1	# <CJK>
+0xCABC	0x5B8E	# <CJK>
+0xCABD	0x5B92	# <CJK>
+0xCABE	0x5C28	# <CJK>
+0xCABF	0x5C2A	# <CJK>
+0xCAC0	0x5C8D	# <CJK>
+0xCAC1	0x5C8F	# <CJK>
+0xCAC2	0x5C88	# <CJK>
+0xCAC3	0x5C8B	# <CJK>
+0xCAC4	0x5C89	# <CJK>
+0xCAC5	0x5C92	# <CJK>
+0xCAC6	0x5C8A	# <CJK>
+0xCAC7	0x5C86	# <CJK>
+0xCAC8	0x5C93	# <CJK>
+0xCAC9	0x5C95	# <CJK>
+0xCACA	0x5DE0	# <CJK>
+0xCACB	0x5E0A	# <CJK>
+0xCACC	0x5E0E	# <CJK>
+0xCACD	0x5E8B	# <CJK>
+0xCACE	0x5E89	# <CJK>
+0xCACF	0x5E8C	# <CJK>
+0xCAD0	0x5E88	# <CJK>
+0xCAD1	0x5E8D	# <CJK>
+0xCAD2	0x5F05	# <CJK>
+0xCAD3	0x5F1D	# <CJK>
+0xCAD4	0x5F78	# <CJK>
+0xCAD5	0x5F76	# <CJK>
+0xCAD6	0x5FD2	# <CJK>
+0xCAD7	0x5FD1	# <CJK>
+0xCAD8	0x5FD0	# <CJK>
+0xCAD9	0x5FED	# <CJK>
+0xCADA	0x5FE8	# <CJK>
+0xCADB	0x5FEE	# <CJK>
+0xCADC	0x5FF3	# <CJK>
+0xCADD	0x5FE1	# <CJK>
+0xCADE	0x5FE4	# <CJK>
+0xCADF	0x5FE3	# <CJK>
+0xCAE0	0x5FFA	# <CJK>
+0xCAE1	0x5FEF	# <CJK>
+0xCAE2	0x5FF7	# <CJK>
+0xCAE3	0x5FFB	# <CJK>
+0xCAE4	0x6000	# <CJK>
+0xCAE5	0x5FF4	# <CJK>
+0xCAE6	0x623A	# <CJK>
+0xCAE7	0x6283	# <CJK>
+0xCAE8	0x628C	# <CJK>
+0xCAE9	0x628E	# <CJK>
+0xCAEA	0x628F	# <CJK>
+0xCAEB	0x6294	# <CJK>
+0xCAEC	0x6287	# <CJK>
+0xCAED	0x6271	# <CJK>
+0xCAEE	0x627B	# <CJK>
+0xCAEF	0x627A	# <CJK>
+0xCAF0	0x6270	# <CJK>
+0xCAF1	0x6281	# <CJK>
+0xCAF2	0x6288	# <CJK>
+0xCAF3	0x6277	# <CJK>
+0xCAF4	0x627D	# <CJK>
+0xCAF5	0x6272	# <CJK>
+0xCAF6	0x6274	# <CJK>
+0xCAF7	0x6537	# <CJK>
+0xCAF8	0x65F0	# <CJK>
+0xCAF9	0x65F4	# <CJK>
+0xCAFA	0x65F3	# <CJK>
+0xCAFB	0x65F2	# <CJK>
+0xCAFC	0x65F5	# <CJK>
+0xCAFD	0x6745	# <CJK>
+0xCAFE	0x6747	# <CJK>
+0xCB40	0x6759	# <CJK>
+0xCB41	0x6755	# <CJK>
+0xCB42	0x674C	# <CJK>
+0xCB43	0x6748	# <CJK>
+0xCB44	0x675D	# <CJK>
+0xCB45	0x674D	# <CJK>
+0xCB46	0x675A	# <CJK>
+0xCB47	0x674B	# <CJK>
+0xCB48	0x6BD0	# <CJK>
+0xCB49	0x6C19	# <CJK>
+0xCB4A	0x6C1A	# <CJK>
+0xCB4B	0x6C78	# <CJK>
+0xCB4C	0x6C67	# <CJK>
+0xCB4D	0x6C6B	# <CJK>
+0xCB4E	0x6C84	# <CJK>
+0xCB4F	0x6C8B	# <CJK>
+0xCB50	0x6C8F	# <CJK>
+0xCB51	0x6C71	# <CJK>
+0xCB52	0x6C6F	# <CJK>
+0xCB53	0x6C69	# <CJK>
+0xCB54	0x6C9A	# <CJK>
+0xCB55	0x6C6D	# <CJK>
+0xCB56	0x6C87	# <CJK>
+0xCB57	0x6C95	# <CJK>
+0xCB58	0x6C9C	# <CJK>
+0xCB59	0x6C66	# <CJK>
+0xCB5A	0x6C73	# <CJK>
+0xCB5B	0x6C65	# <CJK>
+0xCB5C	0x6C7B	# <CJK>
+0xCB5D	0x6C8E	# <CJK>
+0xCB5E	0x7074	# <CJK>
+0xCB5F	0x707A	# <CJK>
+0xCB60	0x7263	# <CJK>
+0xCB61	0x72BF	# <CJK>
+0xCB62	0x72BD	# <CJK>
+0xCB63	0x72C3	# <CJK>
+0xCB64	0x72C6	# <CJK>
+0xCB65	0x72C1	# <CJK>
+0xCB66	0x72BA	# <CJK>
+0xCB67	0x72C5	# <CJK>
+0xCB68	0x7395	# <CJK>
+0xCB69	0x7397	# <CJK>
+0xCB6A	0x7393	# <CJK>
+0xCB6B	0x7394	# <CJK>
+0xCB6C	0x7392	# <CJK>
+0xCB6D	0x753A	# <CJK>
+0xCB6E	0x7539	# <CJK>
+0xCB6F	0x7594	# <CJK>
+0xCB70	0x7595	# <CJK>
+0xCB71	0x7681	# <CJK>
+0xCB72	0x793D	# <CJK>
+0xCB73	0x8034	# <CJK>
+0xCB74	0x8095	# <CJK>
+0xCB75	0x8099	# <CJK>
+0xCB76	0x8090	# <CJK>
+0xCB77	0x8092	# <CJK>
+0xCB78	0x809C	# <CJK>
+0xCB79	0x8290	# <CJK>
+0xCB7A	0x828F	# <CJK>
+0xCB7B	0x8285	# <CJK>
+0xCB7C	0x828E	# <CJK>
+0xCB7D	0x8291	# <CJK>
+0xCB7E	0x8293	# <CJK>
+0xCBA1	0x828A	# <CJK>
+0xCBA2	0x8283	# <CJK>
+0xCBA3	0x8284	# <CJK>
+0xCBA4	0x8C78	# <CJK>
+0xCBA5	0x8FC9	# <CJK>
+0xCBA6	0x8FBF	# <CJK>
+0xCBA7	0x909F	# <CJK>
+0xCBA8	0x90A1	# <CJK>
+0xCBA9	0x90A5	# <CJK>
+0xCBAA	0x909E	# <CJK>
+0xCBAB	0x90A7	# <CJK>
+0xCBAC	0x90A0	# <CJK>
+0xCBAD	0x9630	# <CJK>
+0xCBAE	0x9628	# <CJK>
+0xCBAF	0x962F	# <CJK>
+0xCBB0	0x962D	# <CJK>
+0xCBB1	0x4E33	# <CJK>
+0xCBB2	0x4F98	# <CJK>
+0xCBB3	0x4F7C	# <CJK>
+0xCBB4	0x4F85	# <CJK>
+0xCBB5	0x4F7D	# <CJK>
+0xCBB6	0x4F80	# <CJK>
+0xCBB7	0x4F87	# <CJK>
+0xCBB8	0x4F76	# <CJK>
+0xCBB9	0x4F74	# <CJK>
+0xCBBA	0x4F89	# <CJK>
+0xCBBB	0x4F84	# <CJK>
+0xCBBC	0x4F77	# <CJK>
+0xCBBD	0x4F4C	# <CJK>
+0xCBBE	0x4F97	# <CJK>
+0xCBBF	0x4F6A	# <CJK>
+0xCBC0	0x4F9A	# <CJK>
+0xCBC1	0x4F79	# <CJK>
+0xCBC2	0x4F81	# <CJK>
+0xCBC3	0x4F78	# <CJK>
+0xCBC4	0x4F90	# <CJK>
+0xCBC5	0x4F9C	# <CJK>
+0xCBC6	0x4F94	# <CJK>
+0xCBC7	0x4F9E	# <CJK>
+0xCBC8	0x4F92	# <CJK>
+0xCBC9	0x4F82	# <CJK>
+0xCBCA	0x4F95	# <CJK>
+0xCBCB	0x4F6B	# <CJK>
+0xCBCC	0x4F6E	# <CJK>
+0xCBCD	0x519E	# <CJK>
+0xCBCE	0x51BC	# <CJK>
+0xCBCF	0x51BE	# <CJK>
+0xCBD0	0x5235	# <CJK>
+0xCBD1	0x5232	# <CJK>
+0xCBD2	0x5233	# <CJK>
+0xCBD3	0x5246	# <CJK>
+0xCBD4	0x5231	# <CJK>
+0xCBD5	0x52BC	# <CJK>
+0xCBD6	0x530A	# <CJK>
+0xCBD7	0x530B	# <CJK>
+0xCBD8	0x533C	# <CJK>
+0xCBD9	0x5392	# <CJK>
+0xCBDA	0x5394	# <CJK>
+0xCBDB	0x5487	# <CJK>
+0xCBDC	0x547F	# <CJK>
+0xCBDD	0x5481	# <CJK>
+0xCBDE	0x5491	# <CJK>
+0xCBDF	0x5482	# <CJK>
+0xCBE0	0x5488	# <CJK>
+0xCBE1	0x546B	# <CJK>
+0xCBE2	0x547A	# <CJK>
+0xCBE3	0x547E	# <CJK>
+0xCBE4	0x5465	# <CJK>
+0xCBE5	0x546C	# <CJK>
+0xCBE6	0x5474	# <CJK>
+0xCBE7	0x5466	# <CJK>
+0xCBE8	0x548D	# <CJK>
+0xCBE9	0x546F	# <CJK>
+0xCBEA	0x5461	# <CJK>
+0xCBEB	0x5460	# <CJK>
+0xCBEC	0x5498	# <CJK>
+0xCBED	0x5463	# <CJK>
+0xCBEE	0x5467	# <CJK>
+0xCBEF	0x5464	# <CJK>
+0xCBF0	0x56F7	# <CJK>
+0xCBF1	0x56F9	# <CJK>
+0xCBF2	0x576F	# <CJK>
+0xCBF3	0x5772	# <CJK>
+0xCBF4	0x576D	# <CJK>
+0xCBF5	0x576B	# <CJK>
+0xCBF6	0x5771	# <CJK>
+0xCBF7	0x5770	# <CJK>
+0xCBF8	0x5776	# <CJK>
+0xCBF9	0x5780	# <CJK>
+0xCBFA	0x5775	# <CJK>
+0xCBFB	0x577B	# <CJK>
+0xCBFC	0x5773	# <CJK>
+0xCBFD	0x5774	# <CJK>
+0xCBFE	0x5762	# <CJK>
+0xCC40	0x5768	# <CJK>
+0xCC41	0x577D	# <CJK>
+0xCC42	0x590C	# <CJK>
+0xCC43	0x5945	# <CJK>
+0xCC44	0x59B5	# <CJK>
+0xCC45	0x59BA	# <CJK>
+0xCC46	0x59CF	# <CJK>
+0xCC47	0x59CE	# <CJK>
+0xCC48	0x59B2	# <CJK>
+0xCC49	0x59CC	# <CJK>
+0xCC4A	0x59C1	# <CJK>
+0xCC4B	0x59B6	# <CJK>
+0xCC4C	0x59BC	# <CJK>
+0xCC4D	0x59C3	# <CJK>
+0xCC4E	0x59D6	# <CJK>
+0xCC4F	0x59B1	# <CJK>
+0xCC50	0x59BD	# <CJK>
+0xCC51	0x59C0	# <CJK>
+0xCC52	0x59C8	# <CJK>
+0xCC53	0x59B4	# <CJK>
+0xCC54	0x59C7	# <CJK>
+0xCC55	0x5B62	# <CJK>
+0xCC56	0x5B65	# <CJK>
+0xCC57	0x5B93	# <CJK>
+0xCC58	0x5B95	# <CJK>
+0xCC59	0x5C44	# <CJK>
+0xCC5A	0x5C47	# <CJK>
+0xCC5B	0x5CAE	# <CJK>
+0xCC5C	0x5CA4	# <CJK>
+0xCC5D	0x5CA0	# <CJK>
+0xCC5E	0x5CB5	# <CJK>
+0xCC5F	0x5CAF	# <CJK>
+0xCC60	0x5CA8	# <CJK>
+0xCC61	0x5CAC	# <CJK>
+0xCC62	0x5C9F	# <CJK>
+0xCC63	0x5CA3	# <CJK>
+0xCC64	0x5CAD	# <CJK>
+0xCC65	0x5CA2	# <CJK>
+0xCC66	0x5CAA	# <CJK>
+0xCC67	0x5CA7	# <CJK>
+0xCC68	0x5C9D	# <CJK>
+0xCC69	0x5CA5	# <CJK>
+0xCC6A	0x5CB6	# <CJK>
+0xCC6B	0x5CB0	# <CJK>
+0xCC6C	0x5CA6	# <CJK>
+0xCC6D	0x5E17	# <CJK>
+0xCC6E	0x5E14	# <CJK>
+0xCC6F	0x5E19	# <CJK>
+0xCC70	0x5F28	# <CJK>
+0xCC71	0x5F22	# <CJK>
+0xCC72	0x5F23	# <CJK>
+0xCC73	0x5F24	# <CJK>
+0xCC74	0x5F54	# <CJK>
+0xCC75	0x5F82	# <CJK>
+0xCC76	0x5F7E	# <CJK>
+0xCC77	0x5F7D	# <CJK>
+0xCC78	0x5FDE	# <CJK>
+0xCC79	0x5FE5	# <CJK>
+0xCC7A	0x602D	# <CJK>
+0xCC7B	0x6026	# <CJK>
+0xCC7C	0x6019	# <CJK>
+0xCC7D	0x6032	# <CJK>
+0xCC7E	0x600B	# <CJK>
+0xCCA1	0x6034	# <CJK>
+0xCCA2	0x600A	# <CJK>
+0xCCA3	0x6017	# <CJK>
+0xCCA4	0x6033	# <CJK>
+0xCCA5	0x601A	# <CJK>
+0xCCA6	0x601E	# <CJK>
+0xCCA7	0x602C	# <CJK>
+0xCCA8	0x6022	# <CJK>
+0xCCA9	0x600D	# <CJK>
+0xCCAA	0x6010	# <CJK>
+0xCCAB	0x602E	# <CJK>
+0xCCAC	0x6013	# <CJK>
+0xCCAD	0x6011	# <CJK>
+0xCCAE	0x600C	# <CJK>
+0xCCAF	0x6009	# <CJK>
+0xCCB0	0x601C	# <CJK>
+0xCCB1	0x6214	# <CJK>
+0xCCB2	0x623D	# <CJK>
+0xCCB3	0x62AD	# <CJK>
+0xCCB4	0x62B4	# <CJK>
+0xCCB5	0x62D1	# <CJK>
+0xCCB6	0x62BE	# <CJK>
+0xCCB7	0x62AA	# <CJK>
+0xCCB8	0x62B6	# <CJK>
+0xCCB9	0x62CA	# <CJK>
+0xCCBA	0x62AE	# <CJK>
+0xCCBB	0x62B3	# <CJK>
+0xCCBC	0x62AF	# <CJK>
+0xCCBD	0x62BB	# <CJK>
+0xCCBE	0x62A9	# <CJK>
+0xCCBF	0x62B0	# <CJK>
+0xCCC0	0x62B8	# <CJK>
+0xCCC1	0x653D	# <CJK>
+0xCCC2	0x65A8	# <CJK>
+0xCCC3	0x65BB	# <CJK>
+0xCCC4	0x6609	# <CJK>
+0xCCC5	0x65FC	# <CJK>
+0xCCC6	0x6604	# <CJK>
+0xCCC7	0x6612	# <CJK>
+0xCCC8	0x6608	# <CJK>
+0xCCC9	0x65FB	# <CJK>
+0xCCCA	0x6603	# <CJK>
+0xCCCB	0x660B	# <CJK>
+0xCCCC	0x660D	# <CJK>
+0xCCCD	0x6605	# <CJK>
+0xCCCE	0x65FD	# <CJK>
+0xCCCF	0x6611	# <CJK>
+0xCCD0	0x6610	# <CJK>
+0xCCD1	0x66F6	# <CJK>
+0xCCD2	0x670A	# <CJK>
+0xCCD3	0x6785	# <CJK>
+0xCCD4	0x676C	# <CJK>
+0xCCD5	0x678E	# <CJK>
+0xCCD6	0x6792	# <CJK>
+0xCCD7	0x6776	# <CJK>
+0xCCD8	0x677B	# <CJK>
+0xCCD9	0x6798	# <CJK>
+0xCCDA	0x6786	# <CJK>
+0xCCDB	0x6784	# <CJK>
+0xCCDC	0x6774	# <CJK>
+0xCCDD	0x678D	# <CJK>
+0xCCDE	0x678C	# <CJK>
+0xCCDF	0x677A	# <CJK>
+0xCCE0	0x679F	# <CJK>
+0xCCE1	0x6791	# <CJK>
+0xCCE2	0x6799	# <CJK>
+0xCCE3	0x6783	# <CJK>
+0xCCE4	0x677D	# <CJK>
+0xCCE5	0x6781	# <CJK>
+0xCCE6	0x6778	# <CJK>
+0xCCE7	0x6779	# <CJK>
+0xCCE8	0x6794	# <CJK>
+0xCCE9	0x6B25	# <CJK>
+0xCCEA	0x6B80	# <CJK>
+0xCCEB	0x6B7E	# <CJK>
+0xCCEC	0x6BDE	# <CJK>
+0xCCED	0x6C1D	# <CJK>
+0xCCEE	0x6C93	# <CJK>
+0xCCEF	0x6CEC	# <CJK>
+0xCCF0	0x6CEB	# <CJK>
+0xCCF1	0x6CEE	# <CJK>
+0xCCF2	0x6CD9	# <CJK>
+0xCCF3	0x6CB6	# <CJK>
+0xCCF4	0x6CD4	# <CJK>
+0xCCF5	0x6CAD	# <CJK>
+0xCCF6	0x6CE7	# <CJK>
+0xCCF7	0x6CB7	# <CJK>
+0xCCF8	0x6CD0	# <CJK>
+0xCCF9	0x6CC2	# <CJK>
+0xCCFA	0x6CBA	# <CJK>
+0xCCFB	0x6CC3	# <CJK>
+0xCCFC	0x6CC6	# <CJK>
+0xCCFD	0x6CED	# <CJK>
+0xCCFE	0x6CF2	# <CJK>
+0xCD40	0x6CD2	# <CJK>
+0xCD41	0x6CDD	# <CJK>
+0xCD42	0x6CB4	# <CJK>
+0xCD43	0x6C8A	# <CJK>
+0xCD44	0x6C9D	# <CJK>
+0xCD45	0x6C80	# <CJK>
+0xCD46	0x6CDE	# <CJK>
+0xCD47	0x6CC0	# <CJK>
+0xCD48	0x6D30	# <CJK>
+0xCD49	0x6CCD	# <CJK>
+0xCD4A	0x6CC7	# <CJK>
+0xCD4B	0x6CB0	# <CJK>
+0xCD4C	0x6CF9	# <CJK>
+0xCD4D	0x6CCF	# <CJK>
+0xCD4E	0x6CE9	# <CJK>
+0xCD4F	0x6CD1	# <CJK>
+0xCD50	0x7094	# <CJK>
+0xCD51	0x7098	# <CJK>
+0xCD52	0x7085	# <CJK>
+0xCD53	0x7093	# <CJK>
+0xCD54	0x7086	# <CJK>
+0xCD55	0x7084	# <CJK>
+0xCD56	0x7091	# <CJK>
+0xCD57	0x7096	# <CJK>
+0xCD58	0x7082	# <CJK>
+0xCD59	0x709A	# <CJK>
+0xCD5A	0x7083	# <CJK>
+0xCD5B	0x726A	# <CJK>
+0xCD5C	0x72D6	# <CJK>
+0xCD5D	0x72CB	# <CJK>
+0xCD5E	0x72D8	# <CJK>
+0xCD5F	0x72C9	# <CJK>
+0xCD60	0x72DC	# <CJK>
+0xCD61	0x72D2	# <CJK>
+0xCD62	0x72D4	# <CJK>
+0xCD63	0x72DA	# <CJK>
+0xCD64	0x72CC	# <CJK>
+0xCD65	0x72D1	# <CJK>
+0xCD66	0x73A4	# <CJK>
+0xCD67	0x73A1	# <CJK>
+0xCD68	0x73AD	# <CJK>
+0xCD69	0x73A6	# <CJK>
+0xCD6A	0x73A2	# <CJK>
+0xCD6B	0x73A0	# <CJK>
+0xCD6C	0x73AC	# <CJK>
+0xCD6D	0x739D	# <CJK>
+0xCD6E	0x74DD	# <CJK>
+0xCD6F	0x74E8	# <CJK>
+0xCD70	0x753F	# <CJK>
+0xCD71	0x7540	# <CJK>
+0xCD72	0x753E	# <CJK>
+0xCD73	0x758C	# <CJK>
+0xCD74	0x7598	# <CJK>
+0xCD75	0x76AF	# <CJK>
+0xCD76	0x76F3	# <CJK>
+0xCD77	0x76F1	# <CJK>
+0xCD78	0x76F0	# <CJK>
+0xCD79	0x76F5	# <CJK>
+0xCD7A	0x77F8	# <CJK>
+0xCD7B	0x77FC	# <CJK>
+0xCD7C	0x77F9	# <CJK>
+0xCD7D	0x77FB	# <CJK>
+0xCD7E	0x77FA	# <CJK>
+0xCDA1	0x77F7	# <CJK>
+0xCDA2	0x7942	# <CJK>
+0xCDA3	0x793F	# <CJK>
+0xCDA4	0x79C5	# <CJK>
+0xCDA5	0x7A78	# <CJK>
+0xCDA6	0x7A7B	# <CJK>
+0xCDA7	0x7AFB	# <CJK>
+0xCDA8	0x7C75	# <CJK>
+0xCDA9	0x7CFD	# <CJK>
+0xCDAA	0x8035	# <CJK>
+0xCDAB	0x808F	# <CJK>
+0xCDAC	0x80AE	# <CJK>
+0xCDAD	0x80A3	# <CJK>
+0xCDAE	0x80B8	# <CJK>
+0xCDAF	0x80B5	# <CJK>
+0xCDB0	0x80AD	# <CJK>
+0xCDB1	0x8220	# <CJK>
+0xCDB2	0x82A0	# <CJK>
+0xCDB3	0x82C0	# <CJK>
+0xCDB4	0x82AB	# <CJK>
+0xCDB5	0x829A	# <CJK>
+0xCDB6	0x8298	# <CJK>
+0xCDB7	0x829B	# <CJK>
+0xCDB8	0x82B5	# <CJK>
+0xCDB9	0x82A7	# <CJK>
+0xCDBA	0x82AE	# <CJK>
+0xCDBB	0x82BC	# <CJK>
+0xCDBC	0x829E	# <CJK>
+0xCDBD	0x82BA	# <CJK>
+0xCDBE	0x82B4	# <CJK>
+0xCDBF	0x82A8	# <CJK>
+0xCDC0	0x82A1	# <CJK>
+0xCDC1	0x82A9	# <CJK>
+0xCDC2	0x82C2	# <CJK>
+0xCDC3	0x82A4	# <CJK>
+0xCDC4	0x82C3	# <CJK>
+0xCDC5	0x82B6	# <CJK>
+0xCDC6	0x82A2	# <CJK>
+0xCDC7	0x8670	# <CJK>
+0xCDC8	0x866F	# <CJK>
+0xCDC9	0x866D	# <CJK>
+0xCDCA	0x866E	# <CJK>
+0xCDCB	0x8C56	# <CJK>
+0xCDCC	0x8FD2	# <CJK>
+0xCDCD	0x8FCB	# <CJK>
+0xCDCE	0x8FD3	# <CJK>
+0xCDCF	0x8FCD	# <CJK>
+0xCDD0	0x8FD6	# <CJK>
+0xCDD1	0x8FD5	# <CJK>
+0xCDD2	0x8FD7	# <CJK>
+0xCDD3	0x90B2	# <CJK>
+0xCDD4	0x90B4	# <CJK>
+0xCDD5	0x90AF	# <CJK>
+0xCDD6	0x90B3	# <CJK>
+0xCDD7	0x90B0	# <CJK>
+0xCDD8	0x9639	# <CJK>
+0xCDD9	0x963D	# <CJK>
+0xCDDA	0x963C	# <CJK>
+0xCDDB	0x963A	# <CJK>
+0xCDDC	0x9643	# <CJK>
+0xCDDD	0x4FCD	# <CJK>
+0xCDDE	0x4FC5	# <CJK>
+0xCDDF	0x4FD3	# <CJK>
+0xCDE0	0x4FB2	# <CJK>
+0xCDE1	0x4FC9	# <CJK>
+0xCDE2	0x4FCB	# <CJK>
+0xCDE3	0x4FC1	# <CJK>
+0xCDE4	0x4FD4	# <CJK>
+0xCDE5	0x4FDC	# <CJK>
+0xCDE6	0x4FD9	# <CJK>
+0xCDE7	0x4FBB	# <CJK>
+0xCDE8	0x4FB3	# <CJK>
+0xCDE9	0x4FDB	# <CJK>
+0xCDEA	0x4FC7	# <CJK>
+0xCDEB	0x4FD6	# <CJK>
+0xCDEC	0x4FBA	# <CJK>
+0xCDED	0x4FC0	# <CJK>
+0xCDEE	0x4FB9	# <CJK>
+0xCDEF	0x4FEC	# <CJK>
+0xCDF0	0x5244	# <CJK>
+0xCDF1	0x5249	# <CJK>
+0xCDF2	0x52C0	# <CJK>
+0xCDF3	0x52C2	# <CJK>
+0xCDF4	0x533D	# <CJK>
+0xCDF5	0x537C	# <CJK>
+0xCDF6	0x5397	# <CJK>
+0xCDF7	0x5396	# <CJK>
+0xCDF8	0x5399	# <CJK>
+0xCDF9	0x5398	# <CJK>
+0xCDFA	0x54BA	# <CJK>
+0xCDFB	0x54A1	# <CJK>
+0xCDFC	0x54AD	# <CJK>
+0xCDFD	0x54A5	# <CJK>
+0xCDFE	0x54CF	# <CJK>
+0xCE40	0x54C3	# <CJK>
+0xCE41	0x830D	# <CJK>
+0xCE42	0x54B7	# <CJK>
+0xCE43	0x54AE	# <CJK>
+0xCE44	0x54D6	# <CJK>
+0xCE45	0x54B6	# <CJK>
+0xCE46	0x54C5	# <CJK>
+0xCE47	0x54C6	# <CJK>
+0xCE48	0x54A0	# <CJK>
+0xCE49	0x5470	# <CJK>
+0xCE4A	0x54BC	# <CJK>
+0xCE4B	0x54A2	# <CJK>
+0xCE4C	0x54BE	# <CJK>
+0xCE4D	0x5472	# <CJK>
+0xCE4E	0x54DE	# <CJK>
+0xCE4F	0x54B0	# <CJK>
+0xCE50	0x57B5	# <CJK>
+0xCE51	0x579E	# <CJK>
+0xCE52	0x579F	# <CJK>
+0xCE53	0x57A4	# <CJK>
+0xCE54	0x578C	# <CJK>
+0xCE55	0x5797	# <CJK>
+0xCE56	0x579D	# <CJK>
+0xCE57	0x579B	# <CJK>
+0xCE58	0x5794	# <CJK>
+0xCE59	0x5798	# <CJK>
+0xCE5A	0x578F	# <CJK>
+0xCE5B	0x5799	# <CJK>
+0xCE5C	0x57A5	# <CJK>
+0xCE5D	0x579A	# <CJK>
+0xCE5E	0x5795	# <CJK>
+0xCE5F	0x58F4	# <CJK>
+0xCE60	0x590D	# <CJK>
+0xCE61	0x5953	# <CJK>
+0xCE62	0x59E1	# <CJK>
+0xCE63	0x59DE	# <CJK>
+0xCE64	0x59EE	# <CJK>
+0xCE65	0x5A00	# <CJK>
+0xCE66	0x59F1	# <CJK>
+0xCE67	0x59DD	# <CJK>
+0xCE68	0x59FA	# <CJK>
+0xCE69	0x59FD	# <CJK>
+0xCE6A	0x59FC	# <CJK>
+0xCE6B	0x59F6	# <CJK>
+0xCE6C	0x59E4	# <CJK>
+0xCE6D	0x59F2	# <CJK>
+0xCE6E	0x59F7	# <CJK>
+0xCE6F	0x59DB	# <CJK>
+0xCE70	0x59E9	# <CJK>
+0xCE71	0x59F3	# <CJK>
+0xCE72	0x59F5	# <CJK>
+0xCE73	0x59E0	# <CJK>
+0xCE74	0x59FE	# <CJK>
+0xCE75	0x59F4	# <CJK>
+0xCE76	0x59ED	# <CJK>
+0xCE77	0x5BA8	# <CJK>
+0xCE78	0x5C4C	# <CJK>
+0xCE79	0x5CD0	# <CJK>
+0xCE7A	0x5CD8	# <CJK>
+0xCE7B	0x5CCC	# <CJK>
+0xCE7C	0x5CD7	# <CJK>
+0xCE7D	0x5CCB	# <CJK>
+0xCE7E	0x5CDB	# <CJK>
+0xCEA1	0x5CDE	# <CJK>
+0xCEA2	0x5CDA	# <CJK>
+0xCEA3	0x5CC9	# <CJK>
+0xCEA4	0x5CC7	# <CJK>
+0xCEA5	0x5CCA	# <CJK>
+0xCEA6	0x5CD6	# <CJK>
+0xCEA7	0x5CD3	# <CJK>
+0xCEA8	0x5CD4	# <CJK>
+0xCEA9	0x5CCF	# <CJK>
+0xCEAA	0x5CC8	# <CJK>
+0xCEAB	0x5CC6	# <CJK>
+0xCEAC	0x5CCE	# <CJK>
+0xCEAD	0x5CDF	# <CJK>
+0xCEAE	0x5CF8	# <CJK>
+0xCEAF	0x5DF9	# <CJK>
+0xCEB0	0x5E21	# <CJK>
+0xCEB1	0x5E22	# <CJK>
+0xCEB2	0x5E23	# <CJK>
+0xCEB3	0x5E20	# <CJK>
+0xCEB4	0x5E24	# <CJK>
+0xCEB5	0x5EB0	# <CJK>
+0xCEB6	0x5EA4	# <CJK>
+0xCEB7	0x5EA2	# <CJK>
+0xCEB8	0x5E9B	# <CJK>
+0xCEB9	0x5EA3	# <CJK>
+0xCEBA	0x5EA5	# <CJK>
+0xCEBB	0x5F07	# <CJK>
+0xCEBC	0x5F2E	# <CJK>
+0xCEBD	0x5F56	# <CJK>
+0xCEBE	0x5F86	# <CJK>
+0xCEBF	0x6037	# <CJK>
+0xCEC0	0x6039	# <CJK>
+0xCEC1	0x6054	# <CJK>
+0xCEC2	0x6072	# <CJK>
+0xCEC3	0x605E	# <CJK>
+0xCEC4	0x6045	# <CJK>
+0xCEC5	0x6053	# <CJK>
+0xCEC6	0x6047	# <CJK>
+0xCEC7	0x6049	# <CJK>
+0xCEC8	0x605B	# <CJK>
+0xCEC9	0x604C	# <CJK>
+0xCECA	0x6040	# <CJK>
+0xCECB	0x6042	# <CJK>
+0xCECC	0x605F	# <CJK>
+0xCECD	0x6024	# <CJK>
+0xCECE	0x6044	# <CJK>
+0xCECF	0x6058	# <CJK>
+0xCED0	0x6066	# <CJK>
+0xCED1	0x606E	# <CJK>
+0xCED2	0x6242	# <CJK>
+0xCED3	0x6243	# <CJK>
+0xCED4	0x62CF	# <CJK>
+0xCED5	0x630D	# <CJK>
+0xCED6	0x630B	# <CJK>
+0xCED7	0x62F5	# <CJK>
+0xCED8	0x630E	# <CJK>
+0xCED9	0x6303	# <CJK>
+0xCEDA	0x62EB	# <CJK>
+0xCEDB	0x62F9	# <CJK>
+0xCEDC	0x630F	# <CJK>
+0xCEDD	0x630C	# <CJK>
+0xCEDE	0x62F8	# <CJK>
+0xCEDF	0x62F6	# <CJK>
+0xCEE0	0x6300	# <CJK>
+0xCEE1	0x6313	# <CJK>
+0xCEE2	0x6314	# <CJK>
+0xCEE3	0x62FA	# <CJK>
+0xCEE4	0x6315	# <CJK>
+0xCEE5	0x62FB	# <CJK>
+0xCEE6	0x62F0	# <CJK>
+0xCEE7	0x6541	# <CJK>
+0xCEE8	0x6543	# <CJK>
+0xCEE9	0x65AA	# <CJK>
+0xCEEA	0x65BF	# <CJK>
+0xCEEB	0x6636	# <CJK>
+0xCEEC	0x6621	# <CJK>
+0xCEED	0x6632	# <CJK>
+0xCEEE	0x6635	# <CJK>
+0xCEEF	0x661C	# <CJK>
+0xCEF0	0x6626	# <CJK>
+0xCEF1	0x6622	# <CJK>
+0xCEF2	0x6633	# <CJK>
+0xCEF3	0x662B	# <CJK>
+0xCEF4	0x663A	# <CJK>
+0xCEF5	0x661D	# <CJK>
+0xCEF6	0x6634	# <CJK>
+0xCEF7	0x6639	# <CJK>
+0xCEF8	0x662E	# <CJK>
+0xCEF9	0x670F	# <CJK>
+0xCEFA	0x6710	# <CJK>
+0xCEFB	0x67C1	# <CJK>
+0xCEFC	0x67F2	# <CJK>
+0xCEFD	0x67C8	# <CJK>
+0xCEFE	0x67BA	# <CJK>
+0xCF40	0x67DC	# <CJK>
+0xCF41	0x67BB	# <CJK>
+0xCF42	0x67F8	# <CJK>
+0xCF43	0x67D8	# <CJK>
+0xCF44	0x67C0	# <CJK>
+0xCF45	0x67B7	# <CJK>
+0xCF46	0x67C5	# <CJK>
+0xCF47	0x67EB	# <CJK>
+0xCF48	0x67E4	# <CJK>
+0xCF49	0x67DF	# <CJK>
+0xCF4A	0x67B5	# <CJK>
+0xCF4B	0x67CD	# <CJK>
+0xCF4C	0x67B3	# <CJK>
+0xCF4D	0x67F7	# <CJK>
+0xCF4E	0x67F6	# <CJK>
+0xCF4F	0x67EE	# <CJK>
+0xCF50	0x67E3	# <CJK>
+0xCF51	0x67C2	# <CJK>
+0xCF52	0x67B9	# <CJK>
+0xCF53	0x67CE	# <CJK>
+0xCF54	0x67E7	# <CJK>
+0xCF55	0x67F0	# <CJK>
+0xCF56	0x67B2	# <CJK>
+0xCF57	0x67FC	# <CJK>
+0xCF58	0x67C6	# <CJK>
+0xCF59	0x67ED	# <CJK>
+0xCF5A	0x67CC	# <CJK>
+0xCF5B	0x67AE	# <CJK>
+0xCF5C	0x67E6	# <CJK>
+0xCF5D	0x67DB	# <CJK>
+0xCF5E	0x67FA	# <CJK>
+0xCF5F	0x67C9	# <CJK>
+0xCF60	0x67CA	# <CJK>
+0xCF61	0x67C3	# <CJK>
+0xCF62	0x67EA	# <CJK>
+0xCF63	0x67CB	# <CJK>
+0xCF64	0x6B28	# <CJK>
+0xCF65	0x6B82	# <CJK>
+0xCF66	0x6B84	# <CJK>
+0xCF67	0x6BB6	# <CJK>
+0xCF68	0x6BD6	# <CJK>
+0xCF69	0x6BD8	# <CJK>
+0xCF6A	0x6BE0	# <CJK>
+0xCF6B	0x6C20	# <CJK>
+0xCF6C	0x6C21	# <CJK>
+0xCF6D	0x6D28	# <CJK>
+0xCF6E	0x6D34	# <CJK>
+0xCF6F	0x6D2D	# <CJK>
+0xCF70	0x6D1F	# <CJK>
+0xCF71	0x6D3C	# <CJK>
+0xCF72	0x6D3F	# <CJK>
+0xCF73	0x6D12	# <CJK>
+0xCF74	0x6D0A	# <CJK>
+0xCF75	0x6CDA	# <CJK>
+0xCF76	0x6D33	# <CJK>
+0xCF77	0x6D04	# <CJK>
+0xCF78	0x6D19	# <CJK>
+0xCF79	0x6D3A	# <CJK>
+0xCF7A	0x6D1A	# <CJK>
+0xCF7B	0x6D11	# <CJK>
+0xCF7C	0x6D00	# <CJK>
+0xCF7D	0x6D1D	# <CJK>
+0xCF7E	0x6D42	# <CJK>
+0xCFA1	0x6D01	# <CJK>
+0xCFA2	0x6D18	# <CJK>
+0xCFA3	0x6D37	# <CJK>
+0xCFA4	0x6D03	# <CJK>
+0xCFA5	0x6D0F	# <CJK>
+0xCFA6	0x6D40	# <CJK>
+0xCFA7	0x6D07	# <CJK>
+0xCFA8	0x6D20	# <CJK>
+0xCFA9	0x6D2C	# <CJK>
+0xCFAA	0x6D08	# <CJK>
+0xCFAB	0x6D22	# <CJK>
+0xCFAC	0x6D09	# <CJK>
+0xCFAD	0x6D10	# <CJK>
+0xCFAE	0x70B7	# <CJK>
+0xCFAF	0x709F	# <CJK>
+0xCFB0	0x70BE	# <CJK>
+0xCFB1	0x70B1	# <CJK>
+0xCFB2	0x70B0	# <CJK>
+0xCFB3	0x70A1	# <CJK>
+0xCFB4	0x70B4	# <CJK>
+0xCFB5	0x70B5	# <CJK>
+0xCFB6	0x70A9	# <CJK>
+0xCFB7	0x7241	# <CJK>
+0xCFB8	0x7249	# <CJK>
+0xCFB9	0x724A	# <CJK>
+0xCFBA	0x726C	# <CJK>
+0xCFBB	0x7270	# <CJK>
+0xCFBC	0x7273	# <CJK>
+0xCFBD	0x726E	# <CJK>
+0xCFBE	0x72CA	# <CJK>
+0xCFBF	0x72E4	# <CJK>
+0xCFC0	0x72E8	# <CJK>
+0xCFC1	0x72EB	# <CJK>
+0xCFC2	0x72DF	# <CJK>
+0xCFC3	0x72EA	# <CJK>
+0xCFC4	0x72E6	# <CJK>
+0xCFC5	0x72E3	# <CJK>
+0xCFC6	0x7385	# <CJK>
+0xCFC7	0x73CC	# <CJK>
+0xCFC8	0x73C2	# <CJK>
+0xCFC9	0x73C8	# <CJK>
+0xCFCA	0x73C5	# <CJK>
+0xCFCB	0x73B9	# <CJK>
+0xCFCC	0x73B6	# <CJK>
+0xCFCD	0x73B5	# <CJK>
+0xCFCE	0x73B4	# <CJK>
+0xCFCF	0x73EB	# <CJK>
+0xCFD0	0x73BF	# <CJK>
+0xCFD1	0x73C7	# <CJK>
+0xCFD2	0x73BE	# <CJK>
+0xCFD3	0x73C3	# <CJK>
+0xCFD4	0x73C6	# <CJK>
+0xCFD5	0x73B8	# <CJK>
+0xCFD6	0x73CB	# <CJK>
+0xCFD7	0x74EC	# <CJK>
+0xCFD8	0x74EE	# <CJK>
+0xCFD9	0x752E	# <CJK>
+0xCFDA	0x7547	# <CJK>
+0xCFDB	0x7548	# <CJK>
+0xCFDC	0x75A7	# <CJK>
+0xCFDD	0x75AA	# <CJK>
+0xCFDE	0x7679	# <CJK>
+0xCFDF	0x76C4	# <CJK>
+0xCFE0	0x7708	# <CJK>
+0xCFE1	0x7703	# <CJK>
+0xCFE2	0x7704	# <CJK>
+0xCFE3	0x7705	# <CJK>
+0xCFE4	0x770A	# <CJK>
+0xCFE5	0x76F7	# <CJK>
+0xCFE6	0x76FB	# <CJK>
+0xCFE7	0x76FA	# <CJK>
+0xCFE8	0x77E7	# <CJK>
+0xCFE9	0x77E8	# <CJK>
+0xCFEA	0x7806	# <CJK>
+0xCFEB	0x7811	# <CJK>
+0xCFEC	0x7812	# <CJK>
+0xCFED	0x7805	# <CJK>
+0xCFEE	0x7810	# <CJK>
+0xCFEF	0x780F	# <CJK>
+0xCFF0	0x780E	# <CJK>
+0xCFF1	0x7809	# <CJK>
+0xCFF2	0x7803	# <CJK>
+0xCFF3	0x7813	# <CJK>
+0xCFF4	0x794A	# <CJK>
+0xCFF5	0x794C	# <CJK>
+0xCFF6	0x794B	# <CJK>
+0xCFF7	0x7945	# <CJK>
+0xCFF8	0x7944	# <CJK>
+0xCFF9	0x79D5	# <CJK>
+0xCFFA	0x79CD	# <CJK>
+0xCFFB	0x79CF	# <CJK>
+0xCFFC	0x79D6	# <CJK>
+0xCFFD	0x79CE	# <CJK>
+0xCFFE	0x7A80	# <CJK>
+0xD040	0x7A7E	# <CJK>
+0xD041	0x7AD1	# <CJK>
+0xD042	0x7B00	# <CJK>
+0xD043	0x7B01	# <CJK>
+0xD044	0x7C7A	# <CJK>
+0xD045	0x7C78	# <CJK>
+0xD046	0x7C79	# <CJK>
+0xD047	0x7C7F	# <CJK>
+0xD048	0x7C80	# <CJK>
+0xD049	0x7C81	# <CJK>
+0xD04A	0x7D03	# <CJK>
+0xD04B	0x7D08	# <CJK>
+0xD04C	0x7D01	# <CJK>
+0xD04D	0x7F58	# <CJK>
+0xD04E	0x7F91	# <CJK>
+0xD04F	0x7F8D	# <CJK>
+0xD050	0x7FBE	# <CJK>
+0xD051	0x8007	# <CJK>
+0xD052	0x800E	# <CJK>
+0xD053	0x800F	# <CJK>
+0xD054	0x8014	# <CJK>
+0xD055	0x8037	# <CJK>
+0xD056	0x80D8	# <CJK>
+0xD057	0x80C7	# <CJK>
+0xD058	0x80E0	# <CJK>
+0xD059	0x80D1	# <CJK>
+0xD05A	0x80C8	# <CJK>
+0xD05B	0x80C2	# <CJK>
+0xD05C	0x80D0	# <CJK>
+0xD05D	0x80C5	# <CJK>
+0xD05E	0x80E3	# <CJK>
+0xD05F	0x80D9	# <CJK>
+0xD060	0x80DC	# <CJK>
+0xD061	0x80CA	# <CJK>
+0xD062	0x80D5	# <CJK>
+0xD063	0x80C9	# <CJK>
+0xD064	0x80CF	# <CJK>
+0xD065	0x80D7	# <CJK>
+0xD066	0x80E6	# <CJK>
+0xD067	0x80CD	# <CJK>
+0xD068	0x81FF	# <CJK>
+0xD069	0x8221	# <CJK>
+0xD06A	0x8294	# <CJK>
+0xD06B	0x82D9	# <CJK>
+0xD06C	0x82FE	# <CJK>
+0xD06D	0x82F9	# <CJK>
+0xD06E	0x8307	# <CJK>
+0xD06F	0x82E8	# <CJK>
+0xD070	0x8300	# <CJK>
+0xD071	0x82D5	# <CJK>
+0xD072	0x833A	# <CJK>
+0xD073	0x82EB	# <CJK>
+0xD074	0x82D6	# <CJK>
+0xD075	0x82F4	# <CJK>
+0xD076	0x82EC	# <CJK>
+0xD077	0x82E1	# <CJK>
+0xD078	0x82F2	# <CJK>
+0xD079	0x82F5	# <CJK>
+0xD07A	0x830C	# <CJK>
+0xD07B	0x82FB	# <CJK>
+0xD07C	0x82F6	# <CJK>
+0xD07D	0x82F0	# <CJK>
+0xD07E	0x82EA	# <CJK>
+0xD0A1	0x82E4	# <CJK>
+0xD0A2	0x82E0	# <CJK>
+0xD0A3	0x82FA	# <CJK>
+0xD0A4	0x82F3	# <CJK>
+0xD0A5	0x82ED	# <CJK>
+0xD0A6	0x8677	# <CJK>
+0xD0A7	0x8674	# <CJK>
+0xD0A8	0x867C	# <CJK>
+0xD0A9	0x8673	# <CJK>
+0xD0AA	0x8841	# <CJK>
+0xD0AB	0x884E	# <CJK>
+0xD0AC	0x8867	# <CJK>
+0xD0AD	0x886A	# <CJK>
+0xD0AE	0x8869	# <CJK>
+0xD0AF	0x89D3	# <CJK>
+0xD0B0	0x8A04	# <CJK>
+0xD0B1	0x8A07	# <CJK>
+0xD0B2	0x8D72	# <CJK>
+0xD0B3	0x8FE3	# <CJK>
+0xD0B4	0x8FE1	# <CJK>
+0xD0B5	0x8FEE	# <CJK>
+0xD0B6	0x8FE0	# <CJK>
+0xD0B7	0x90F1	# <CJK>
+0xD0B8	0x90BD	# <CJK>
+0xD0B9	0x90BF	# <CJK>
+0xD0BA	0x90D5	# <CJK>
+0xD0BB	0x90C5	# <CJK>
+0xD0BC	0x90BE	# <CJK>
+0xD0BD	0x90C7	# <CJK>
+0xD0BE	0x90CB	# <CJK>
+0xD0BF	0x90C8	# <CJK>
+0xD0C0	0x91D4	# <CJK>
+0xD0C1	0x91D3	# <CJK>
+0xD0C2	0x9654	# <CJK>
+0xD0C3	0x964F	# <CJK>
+0xD0C4	0x9651	# <CJK>
+0xD0C5	0x9653	# <CJK>
+0xD0C6	0x964A	# <CJK>
+0xD0C7	0x964E	# <CJK>
+0xD0C8	0x501E	# <CJK>
+0xD0C9	0x5005	# <CJK>
+0xD0CA	0x5007	# <CJK>
+0xD0CB	0x5013	# <CJK>
+0xD0CC	0x5022	# <CJK>
+0xD0CD	0x5030	# <CJK>
+0xD0CE	0x501B	# <CJK>
+0xD0CF	0x4FF5	# <CJK>
+0xD0D0	0x4FF4	# <CJK>
+0xD0D1	0x5033	# <CJK>
+0xD0D2	0x5037	# <CJK>
+0xD0D3	0x502C	# <CJK>
+0xD0D4	0x4FF6	# <CJK>
+0xD0D5	0x4FF7	# <CJK>
+0xD0D6	0x5017	# <CJK>
+0xD0D7	0x501C	# <CJK>
+0xD0D8	0x5020	# <CJK>
+0xD0D9	0x5027	# <CJK>
+0xD0DA	0x5035	# <CJK>
+0xD0DB	0x502F	# <CJK>
+0xD0DC	0x5031	# <CJK>
+0xD0DD	0x500E	# <CJK>
+0xD0DE	0x515A	# <CJK>
+0xD0DF	0x5194	# <CJK>
+0xD0E0	0x5193	# <CJK>
+0xD0E1	0x51CA	# <CJK>
+0xD0E2	0x51C4	# <CJK>
+0xD0E3	0x51C5	# <CJK>
+0xD0E4	0x51C8	# <CJK>
+0xD0E5	0x51CE	# <CJK>
+0xD0E6	0x5261	# <CJK>
+0xD0E7	0x525A	# <CJK>
+0xD0E8	0x5252	# <CJK>
+0xD0E9	0x525E	# <CJK>
+0xD0EA	0x525F	# <CJK>
+0xD0EB	0x5255	# <CJK>
+0xD0EC	0x5262	# <CJK>
+0xD0ED	0x52CD	# <CJK>
+0xD0EE	0x530E	# <CJK>
+0xD0EF	0x539E	# <CJK>
+0xD0F0	0x5526	# <CJK>
+0xD0F1	0x54E2	# <CJK>
+0xD0F2	0x5517	# <CJK>
+0xD0F3	0x5512	# <CJK>
+0xD0F4	0x54E7	# <CJK>
+0xD0F5	0x54F3	# <CJK>
+0xD0F6	0x54E4	# <CJK>
+0xD0F7	0x551A	# <CJK>
+0xD0F8	0x54FF	# <CJK>
+0xD0F9	0x5504	# <CJK>
+0xD0FA	0x5508	# <CJK>
+0xD0FB	0x54EB	# <CJK>
+0xD0FC	0x5511	# <CJK>
+0xD0FD	0x5505	# <CJK>
+0xD0FE	0x54F1	# <CJK>
+0xD140	0x550A	# <CJK>
+0xD141	0x54FB	# <CJK>
+0xD142	0x54F7	# <CJK>
+0xD143	0x54F8	# <CJK>
+0xD144	0x54E0	# <CJK>
+0xD145	0x550E	# <CJK>
+0xD146	0x5503	# <CJK>
+0xD147	0x550B	# <CJK>
+0xD148	0x5701	# <CJK>
+0xD149	0x5702	# <CJK>
+0xD14A	0x57CC	# <CJK>
+0xD14B	0x5832	# <CJK>
+0xD14C	0x57D5	# <CJK>
+0xD14D	0x57D2	# <CJK>
+0xD14E	0x57BA	# <CJK>
+0xD14F	0x57C6	# <CJK>
+0xD150	0x57BD	# <CJK>
+0xD151	0x57BC	# <CJK>
+0xD152	0x57B8	# <CJK>
+0xD153	0x57B6	# <CJK>
+0xD154	0x57BF	# <CJK>
+0xD155	0x57C7	# <CJK>
+0xD156	0x57D0	# <CJK>
+0xD157	0x57B9	# <CJK>
+0xD158	0x57C1	# <CJK>
+0xD159	0x590E	# <CJK>
+0xD15A	0x594A	# <CJK>
+0xD15B	0x5A19	# <CJK>
+0xD15C	0x5A16	# <CJK>
+0xD15D	0x5A2D	# <CJK>
+0xD15E	0x5A2E	# <CJK>
+0xD15F	0x5A15	# <CJK>
+0xD160	0x5A0F	# <CJK>
+0xD161	0x5A17	# <CJK>
+0xD162	0x5A0A	# <CJK>
+0xD163	0x5A1E	# <CJK>
+0xD164	0x5A33	# <CJK>
+0xD165	0x5B6C	# <CJK>
+0xD166	0x5BA7	# <CJK>
+0xD167	0x5BAD	# <CJK>
+0xD168	0x5BAC	# <CJK>
+0xD169	0x5C03	# <CJK>
+0xD16A	0x5C56	# <CJK>
+0xD16B	0x5C54	# <CJK>
+0xD16C	0x5CEC	# <CJK>
+0xD16D	0x5CFF	# <CJK>
+0xD16E	0x5CEE	# <CJK>
+0xD16F	0x5CF1	# <CJK>
+0xD170	0x5CF7	# <CJK>
+0xD171	0x5D00	# <CJK>
+0xD172	0x5CF9	# <CJK>
+0xD173	0x5E29	# <CJK>
+0xD174	0x5E28	# <CJK>
+0xD175	0x5EA8	# <CJK>
+0xD176	0x5EAE	# <CJK>
+0xD177	0x5EAA	# <CJK>
+0xD178	0x5EAC	# <CJK>
+0xD179	0x5F33	# <CJK>
+0xD17A	0x5F30	# <CJK>
+0xD17B	0x5F67	# <CJK>
+0xD17C	0x605D	# <CJK>
+0xD17D	0x605A	# <CJK>
+0xD17E	0x6067	# <CJK>
+0xD1A1	0x6041	# <CJK>
+0xD1A2	0x60A2	# <CJK>
+0xD1A3	0x6088	# <CJK>
+0xD1A4	0x6080	# <CJK>
+0xD1A5	0x6092	# <CJK>
+0xD1A6	0x6081	# <CJK>
+0xD1A7	0x609D	# <CJK>
+0xD1A8	0x6083	# <CJK>
+0xD1A9	0x6095	# <CJK>
+0xD1AA	0x609B	# <CJK>
+0xD1AB	0x6097	# <CJK>
+0xD1AC	0x6087	# <CJK>
+0xD1AD	0x609C	# <CJK>
+0xD1AE	0x608E	# <CJK>
+0xD1AF	0x6219	# <CJK>
+0xD1B0	0x6246	# <CJK>
+0xD1B1	0x62F2	# <CJK>
+0xD1B2	0x6310	# <CJK>
+0xD1B3	0x6356	# <CJK>
+0xD1B4	0x632C	# <CJK>
+0xD1B5	0x6344	# <CJK>
+0xD1B6	0x6345	# <CJK>
+0xD1B7	0x6336	# <CJK>
+0xD1B8	0x6343	# <CJK>
+0xD1B9	0x63E4	# <CJK>
+0xD1BA	0x6339	# <CJK>
+0xD1BB	0x634B	# <CJK>
+0xD1BC	0x634A	# <CJK>
+0xD1BD	0x633C	# <CJK>
+0xD1BE	0x6329	# <CJK>
+0xD1BF	0x6341	# <CJK>
+0xD1C0	0x6334	# <CJK>
+0xD1C1	0x6358	# <CJK>
+0xD1C2	0x6354	# <CJK>
+0xD1C3	0x6359	# <CJK>
+0xD1C4	0x632D	# <CJK>
+0xD1C5	0x6347	# <CJK>
+0xD1C6	0x6333	# <CJK>
+0xD1C7	0x635A	# <CJK>
+0xD1C8	0x6351	# <CJK>
+0xD1C9	0x6338	# <CJK>
+0xD1CA	0x6357	# <CJK>
+0xD1CB	0x6340	# <CJK>
+0xD1CC	0x6348	# <CJK>
+0xD1CD	0x654A	# <CJK>
+0xD1CE	0x6546	# <CJK>
+0xD1CF	0x65C6	# <CJK>
+0xD1D0	0x65C3	# <CJK>
+0xD1D1	0x65C4	# <CJK>
+0xD1D2	0x65C2	# <CJK>
+0xD1D3	0x664A	# <CJK>
+0xD1D4	0x665F	# <CJK>
+0xD1D5	0x6647	# <CJK>
+0xD1D6	0x6651	# <CJK>
+0xD1D7	0x6712	# <CJK>
+0xD1D8	0x6713	# <CJK>
+0xD1D9	0x681F	# <CJK>
+0xD1DA	0x681A	# <CJK>
+0xD1DB	0x6849	# <CJK>
+0xD1DC	0x6832	# <CJK>
+0xD1DD	0x6833	# <CJK>
+0xD1DE	0x683B	# <CJK>
+0xD1DF	0x684B	# <CJK>
+0xD1E0	0x684F	# <CJK>
+0xD1E1	0x6816	# <CJK>
+0xD1E2	0x6831	# <CJK>
+0xD1E3	0x681C	# <CJK>
+0xD1E4	0x6835	# <CJK>
+0xD1E5	0x682B	# <CJK>
+0xD1E6	0x682D	# <CJK>
+0xD1E7	0x682F	# <CJK>
+0xD1E8	0x684E	# <CJK>
+0xD1E9	0x6844	# <CJK>
+0xD1EA	0x6834	# <CJK>
+0xD1EB	0x681D	# <CJK>
+0xD1EC	0x6812	# <CJK>
+0xD1ED	0x6814	# <CJK>
+0xD1EE	0x6826	# <CJK>
+0xD1EF	0x6828	# <CJK>
+0xD1F0	0x682E	# <CJK>
+0xD1F1	0x684D	# <CJK>
+0xD1F2	0x683A	# <CJK>
+0xD1F3	0x6825	# <CJK>
+0xD1F4	0x6820	# <CJK>
+0xD1F5	0x6B2C	# <CJK>
+0xD1F6	0x6B2F	# <CJK>
+0xD1F7	0x6B2D	# <CJK>
+0xD1F8	0x6B31	# <CJK>
+0xD1F9	0x6B34	# <CJK>
+0xD1FA	0x6B6D	# <CJK>
+0xD1FB	0x8082	# <CJK>
+0xD1FC	0x6B88	# <CJK>
+0xD1FD	0x6BE6	# <CJK>
+0xD1FE	0x6BE4	# <CJK>
+0xD240	0x6BE8	# <CJK>
+0xD241	0x6BE3	# <CJK>
+0xD242	0x6BE2	# <CJK>
+0xD243	0x6BE7	# <CJK>
+0xD244	0x6C25	# <CJK>
+0xD245	0x6D7A	# <CJK>
+0xD246	0x6D63	# <CJK>
+0xD247	0x6D64	# <CJK>
+0xD248	0x6D76	# <CJK>
+0xD249	0x6D0D	# <CJK>
+0xD24A	0x6D61	# <CJK>
+0xD24B	0x6D92	# <CJK>
+0xD24C	0x6D58	# <CJK>
+0xD24D	0x6D62	# <CJK>
+0xD24E	0x6D6D	# <CJK>
+0xD24F	0x6D6F	# <CJK>
+0xD250	0x6D91	# <CJK>
+0xD251	0x6D8D	# <CJK>
+0xD252	0x6DEF	# <CJK>
+0xD253	0x6D7F	# <CJK>
+0xD254	0x6D86	# <CJK>
+0xD255	0x6D5E	# <CJK>
+0xD256	0x6D67	# <CJK>
+0xD257	0x6D60	# <CJK>
+0xD258	0x6D97	# <CJK>
+0xD259	0x6D70	# <CJK>
+0xD25A	0x6D7C	# <CJK>
+0xD25B	0x6D5F	# <CJK>
+0xD25C	0x6D82	# <CJK>
+0xD25D	0x6D98	# <CJK>
+0xD25E	0x6D2F	# <CJK>
+0xD25F	0x6D68	# <CJK>
+0xD260	0x6D8B	# <CJK>
+0xD261	0x6D7E	# <CJK>
+0xD262	0x6D80	# <CJK>
+0xD263	0x6D84	# <CJK>
+0xD264	0x6D16	# <CJK>
+0xD265	0x6D83	# <CJK>
+0xD266	0x6D7B	# <CJK>
+0xD267	0x6D7D	# <CJK>
+0xD268	0x6D75	# <CJK>
+0xD269	0x6D90	# <CJK>
+0xD26A	0x70DC	# <CJK>
+0xD26B	0x70D3	# <CJK>
+0xD26C	0x70D1	# <CJK>
+0xD26D	0x70DD	# <CJK>
+0xD26E	0x70CB	# <CJK>
+0xD26F	0x7F39	# <CJK>
+0xD270	0x70E2	# <CJK>
+0xD271	0x70D7	# <CJK>
+0xD272	0x70D2	# <CJK>
+0xD273	0x70DE	# <CJK>
+0xD274	0x70E0	# <CJK>
+0xD275	0x70D4	# <CJK>
+0xD276	0x70CD	# <CJK>
+0xD277	0x70C5	# <CJK>
+0xD278	0x70C6	# <CJK>
+0xD279	0x70C7	# <CJK>
+0xD27A	0x70DA	# <CJK>
+0xD27B	0x70CE	# <CJK>
+0xD27C	0x70E1	# <CJK>
+0xD27D	0x7242	# <CJK>
+0xD27E	0x7278	# <CJK>
+0xD2A1	0x7277	# <CJK>
+0xD2A2	0x7276	# <CJK>
+0xD2A3	0x7300	# <CJK>
+0xD2A4	0x72FA	# <CJK>
+0xD2A5	0x72F4	# <CJK>
+0xD2A6	0x72FE	# <CJK>
+0xD2A7	0x72F6	# <CJK>
+0xD2A8	0x72F3	# <CJK>
+0xD2A9	0x72FB	# <CJK>
+0xD2AA	0x7301	# <CJK>
+0xD2AB	0x73D3	# <CJK>
+0xD2AC	0x73D9	# <CJK>
+0xD2AD	0x73E5	# <CJK>
+0xD2AE	0x73D6	# <CJK>
+0xD2AF	0x73BC	# <CJK>
+0xD2B0	0x73E7	# <CJK>
+0xD2B1	0x73E3	# <CJK>
+0xD2B2	0x73E9	# <CJK>
+0xD2B3	0x73DC	# <CJK>
+0xD2B4	0x73D2	# <CJK>
+0xD2B5	0x73DB	# <CJK>
+0xD2B6	0x73D4	# <CJK>
+0xD2B7	0x73DD	# <CJK>
+0xD2B8	0x73DA	# <CJK>
+0xD2B9	0x73D7	# <CJK>
+0xD2BA	0x73D8	# <CJK>
+0xD2BB	0x73E8	# <CJK>
+0xD2BC	0x74DE	# <CJK>
+0xD2BD	0x74DF	# <CJK>
+0xD2BE	0x74F4	# <CJK>
+0xD2BF	0x74F5	# <CJK>
+0xD2C0	0x7521	# <CJK>
+0xD2C1	0x755B	# <CJK>
+0xD2C2	0x755F	# <CJK>
+0xD2C3	0x75B0	# <CJK>
+0xD2C4	0x75C1	# <CJK>
+0xD2C5	0x75BB	# <CJK>
+0xD2C6	0x75C4	# <CJK>
+0xD2C7	0x75C0	# <CJK>
+0xD2C8	0x75BF	# <CJK>
+0xD2C9	0x75B6	# <CJK>
+0xD2CA	0x75BA	# <CJK>
+0xD2CB	0x768A	# <CJK>
+0xD2CC	0x76C9	# <CJK>
+0xD2CD	0x771D	# <CJK>
+0xD2CE	0x771B	# <CJK>
+0xD2CF	0x7710	# <CJK>
+0xD2D0	0x7713	# <CJK>
+0xD2D1	0x7712	# <CJK>
+0xD2D2	0x7723	# <CJK>
+0xD2D3	0x7711	# <CJK>
+0xD2D4	0x7715	# <CJK>
+0xD2D5	0x7719	# <CJK>
+0xD2D6	0x771A	# <CJK>
+0xD2D7	0x7722	# <CJK>
+0xD2D8	0x7727	# <CJK>
+0xD2D9	0x7823	# <CJK>
+0xD2DA	0x782C	# <CJK>
+0xD2DB	0x7822	# <CJK>
+0xD2DC	0x7835	# <CJK>
+0xD2DD	0x782F	# <CJK>
+0xD2DE	0x7828	# <CJK>
+0xD2DF	0x782E	# <CJK>
+0xD2E0	0x782B	# <CJK>
+0xD2E1	0x7821	# <CJK>
+0xD2E2	0x7829	# <CJK>
+0xD2E3	0x7833	# <CJK>
+0xD2E4	0x782A	# <CJK>
+0xD2E5	0x7831	# <CJK>
+0xD2E6	0x7954	# <CJK>
+0xD2E7	0x795B	# <CJK>
+0xD2E8	0x794F	# <CJK>
+0xD2E9	0x795C	# <CJK>
+0xD2EA	0x7953	# <CJK>
+0xD2EB	0x7952	# <CJK>
+0xD2EC	0x7951	# <CJK>
+0xD2ED	0x79EB	# <CJK>
+0xD2EE	0x79EC	# <CJK>
+0xD2EF	0x79E0	# <CJK>
+0xD2F0	0x79EE	# <CJK>
+0xD2F1	0x79ED	# <CJK>
+0xD2F2	0x79EA	# <CJK>
+0xD2F3	0x79DC	# <CJK>
+0xD2F4	0x79DE	# <CJK>
+0xD2F5	0x79DD	# <CJK>
+0xD2F6	0x7A86	# <CJK>
+0xD2F7	0x7A89	# <CJK>
+0xD2F8	0x7A85	# <CJK>
+0xD2F9	0x7A8B	# <CJK>
+0xD2FA	0x7A8C	# <CJK>
+0xD2FB	0x7A8A	# <CJK>
+0xD2FC	0x7A87	# <CJK>
+0xD2FD	0x7AD8	# <CJK>
+0xD2FE	0x7B10	# <CJK>
+0xD340	0x7B04	# <CJK>
+0xD341	0x7B13	# <CJK>
+0xD342	0x7B05	# <CJK>
+0xD343	0x7B0F	# <CJK>
+0xD344	0x7B08	# <CJK>
+0xD345	0x7B0A	# <CJK>
+0xD346	0x7B0E	# <CJK>
+0xD347	0x7B09	# <CJK>
+0xD348	0x7B12	# <CJK>
+0xD349	0x7C84	# <CJK>
+0xD34A	0x7C91	# <CJK>
+0xD34B	0x7C8A	# <CJK>
+0xD34C	0x7C8C	# <CJK>
+0xD34D	0x7C88	# <CJK>
+0xD34E	0x7C8D	# <CJK>
+0xD34F	0x7C85	# <CJK>
+0xD350	0x7D1E	# <CJK>
+0xD351	0x7D1D	# <CJK>
+0xD352	0x7D11	# <CJK>
+0xD353	0x7D0E	# <CJK>
+0xD354	0x7D18	# <CJK>
+0xD355	0x7D16	# <CJK>
+0xD356	0x7D13	# <CJK>
+0xD357	0x7D1F	# <CJK>
+0xD358	0x7D12	# <CJK>
+0xD359	0x7D0F	# <CJK>
+0xD35A	0x7D0C	# <CJK>
+0xD35B	0x7F5C	# <CJK>
+0xD35C	0x7F61	# <CJK>
+0xD35D	0x7F5E	# <CJK>
+0xD35E	0x7F60	# <CJK>
+0xD35F	0x7F5D	# <CJK>
+0xD360	0x7F5B	# <CJK>
+0xD361	0x7F96	# <CJK>
+0xD362	0x7F92	# <CJK>
+0xD363	0x7FC3	# <CJK>
+0xD364	0x7FC2	# <CJK>
+0xD365	0x7FC0	# <CJK>
+0xD366	0x8016	# <CJK>
+0xD367	0x803E	# <CJK>
+0xD368	0x8039	# <CJK>
+0xD369	0x80FA	# <CJK>
+0xD36A	0x80F2	# <CJK>
+0xD36B	0x80F9	# <CJK>
+0xD36C	0x80F5	# <CJK>
+0xD36D	0x8101	# <CJK>
+0xD36E	0x80FB	# <CJK>
+0xD36F	0x8100	# <CJK>
+0xD370	0x8201	# <CJK>
+0xD371	0x822F	# <CJK>
+0xD372	0x8225	# <CJK>
+0xD373	0x8333	# <CJK>
+0xD374	0x832D	# <CJK>
+0xD375	0x8344	# <CJK>
+0xD376	0x8319	# <CJK>
+0xD377	0x8351	# <CJK>
+0xD378	0x8325	# <CJK>
+0xD379	0x8356	# <CJK>
+0xD37A	0x833F	# <CJK>
+0xD37B	0x8341	# <CJK>
+0xD37C	0x8326	# <CJK>
+0xD37D	0x831C	# <CJK>
+0xD37E	0x8322	# <CJK>
+0xD3A1	0x8342	# <CJK>
+0xD3A2	0x834E	# <CJK>
+0xD3A3	0x831B	# <CJK>
+0xD3A4	0x832A	# <CJK>
+0xD3A5	0x8308	# <CJK>
+0xD3A6	0x833C	# <CJK>
+0xD3A7	0x834D	# <CJK>
+0xD3A8	0x8316	# <CJK>
+0xD3A9	0x8324	# <CJK>
+0xD3AA	0x8320	# <CJK>
+0xD3AB	0x8337	# <CJK>
+0xD3AC	0x832F	# <CJK>
+0xD3AD	0x8329	# <CJK>
+0xD3AE	0x8347	# <CJK>
+0xD3AF	0x8345	# <CJK>
+0xD3B0	0x834C	# <CJK>
+0xD3B1	0x8353	# <CJK>
+0xD3B2	0x831E	# <CJK>
+0xD3B3	0x832C	# <CJK>
+0xD3B4	0x834B	# <CJK>
+0xD3B5	0x8327	# <CJK>
+0xD3B6	0x8348	# <CJK>
+0xD3B7	0x8653	# <CJK>
+0xD3B8	0x8652	# <CJK>
+0xD3B9	0x86A2	# <CJK>
+0xD3BA	0x86A8	# <CJK>
+0xD3BB	0x8696	# <CJK>
+0xD3BC	0x868D	# <CJK>
+0xD3BD	0x8691	# <CJK>
+0xD3BE	0x869E	# <CJK>
+0xD3BF	0x8687	# <CJK>
+0xD3C0	0x8697	# <CJK>
+0xD3C1	0x8686	# <CJK>
+0xD3C2	0x868B	# <CJK>
+0xD3C3	0x869A	# <CJK>
+0xD3C4	0x8685	# <CJK>
+0xD3C5	0x86A5	# <CJK>
+0xD3C6	0x8699	# <CJK>
+0xD3C7	0x86A1	# <CJK>
+0xD3C8	0x86A7	# <CJK>
+0xD3C9	0x8695	# <CJK>
+0xD3CA	0x8698	# <CJK>
+0xD3CB	0x868E	# <CJK>
+0xD3CC	0x869D	# <CJK>
+0xD3CD	0x8690	# <CJK>
+0xD3CE	0x8694	# <CJK>
+0xD3CF	0x8843	# <CJK>
+0xD3D0	0x8844	# <CJK>
+0xD3D1	0x886D	# <CJK>
+0xD3D2	0x8875	# <CJK>
+0xD3D3	0x8876	# <CJK>
+0xD3D4	0x8872	# <CJK>
+0xD3D5	0x8880	# <CJK>
+0xD3D6	0x8871	# <CJK>
+0xD3D7	0x887F	# <CJK>
+0xD3D8	0x886F	# <CJK>
+0xD3D9	0x8883	# <CJK>
+0xD3DA	0x887E	# <CJK>
+0xD3DB	0x8874	# <CJK>
+0xD3DC	0x887C	# <CJK>
+0xD3DD	0x8A12	# <CJK>
+0xD3DE	0x8C47	# <CJK>
+0xD3DF	0x8C57	# <CJK>
+0xD3E0	0x8C7B	# <CJK>
+0xD3E1	0x8CA4	# <CJK>
+0xD3E2	0x8CA3	# <CJK>
+0xD3E3	0x8D76	# <CJK>
+0xD3E4	0x8D78	# <CJK>
+0xD3E5	0x8DB5	# <CJK>
+0xD3E6	0x8DB7	# <CJK>
+0xD3E7	0x8DB6	# <CJK>
+0xD3E8	0x8ED1	# <CJK>
+0xD3E9	0x8ED3	# <CJK>
+0xD3EA	0x8FFE	# <CJK>
+0xD3EB	0x8FF5	# <CJK>
+0xD3EC	0x9002	# <CJK>
+0xD3ED	0x8FFF	# <CJK>
+0xD3EE	0x8FFB	# <CJK>
+0xD3EF	0x9004	# <CJK>
+0xD3F0	0x8FFC	# <CJK>
+0xD3F1	0x8FF6	# <CJK>
+0xD3F2	0x90D6	# <CJK>
+0xD3F3	0x90E0	# <CJK>
+0xD3F4	0x90D9	# <CJK>
+0xD3F5	0x90DA	# <CJK>
+0xD3F6	0x90E3	# <CJK>
+0xD3F7	0x90DF	# <CJK>
+0xD3F8	0x90E5	# <CJK>
+0xD3F9	0x90D8	# <CJK>
+0xD3FA	0x90DB	# <CJK>
+0xD3FB	0x90D7	# <CJK>
+0xD3FC	0x90DC	# <CJK>
+0xD3FD	0x90E4	# <CJK>
+0xD3FE	0x9150	# <CJK>
+0xD440	0x914E	# <CJK>
+0xD441	0x914F	# <CJK>
+0xD442	0x91D5	# <CJK>
+0xD443	0x91E2	# <CJK>
+0xD444	0x91DA	# <CJK>
+0xD445	0x965C	# <CJK>
+0xD446	0x965F	# <CJK>
+0xD447	0x96BC	# <CJK>
+0xD448	0x98E3	# <CJK>
+0xD449	0x9ADF	# <CJK>
+0xD44A	0x9B2F	# <CJK>
+0xD44B	0x4E7F	# <CJK>
+0xD44C	0x5070	# <CJK>
+0xD44D	0x506A	# <CJK>
+0xD44E	0x5061	# <CJK>
+0xD44F	0x505E	# <CJK>
+0xD450	0x5060	# <CJK>
+0xD451	0x5053	# <CJK>
+0xD452	0x504B	# <CJK>
+0xD453	0x505D	# <CJK>
+0xD454	0x5072	# <CJK>
+0xD455	0x5048	# <CJK>
+0xD456	0x504D	# <CJK>
+0xD457	0x5041	# <CJK>
+0xD458	0x505B	# <CJK>
+0xD459	0x504A	# <CJK>
+0xD45A	0x5062	# <CJK>
+0xD45B	0x5015	# <CJK>
+0xD45C	0x5045	# <CJK>
+0xD45D	0x505F	# <CJK>
+0xD45E	0x5069	# <CJK>
+0xD45F	0x506B	# <CJK>
+0xD460	0x5063	# <CJK>
+0xD461	0x5064	# <CJK>
+0xD462	0x5046	# <CJK>
+0xD463	0x5040	# <CJK>
+0xD464	0x506E	# <CJK>
+0xD465	0x5073	# <CJK>
+0xD466	0x5057	# <CJK>
+0xD467	0x5051	# <CJK>
+0xD468	0x51D0	# <CJK>
+0xD469	0x526B	# <CJK>
+0xD46A	0x526D	# <CJK>
+0xD46B	0x526C	# <CJK>
+0xD46C	0x526E	# <CJK>
+0xD46D	0x52D6	# <CJK>
+0xD46E	0x52D3	# <CJK>
+0xD46F	0x532D	# <CJK>
+0xD470	0x539C	# <CJK>
+0xD471	0x5575	# <CJK>
+0xD472	0x5576	# <CJK>
+0xD473	0x553C	# <CJK>
+0xD474	0x554D	# <CJK>
+0xD475	0x5550	# <CJK>
+0xD476	0x5534	# <CJK>
+0xD477	0x552A	# <CJK>
+0xD478	0x5551	# <CJK>
+0xD479	0x5562	# <CJK>
+0xD47A	0x5536	# <CJK>
+0xD47B	0x5535	# <CJK>
+0xD47C	0x5530	# <CJK>
+0xD47D	0x5552	# <CJK>
+0xD47E	0x5545	# <CJK>
+0xD4A1	0x550C	# <CJK>
+0xD4A2	0x5532	# <CJK>
+0xD4A3	0x5565	# <CJK>
+0xD4A4	0x554E	# <CJK>
+0xD4A5	0x5539	# <CJK>
+0xD4A6	0x5548	# <CJK>
+0xD4A7	0x552D	# <CJK>
+0xD4A8	0x553B	# <CJK>
+0xD4A9	0x5540	# <CJK>
+0xD4AA	0x554B	# <CJK>
+0xD4AB	0x570A	# <CJK>
+0xD4AC	0x5707	# <CJK>
+0xD4AD	0x57FB	# <CJK>
+0xD4AE	0x5814	# <CJK>
+0xD4AF	0x57E2	# <CJK>
+0xD4B0	0x57F6	# <CJK>
+0xD4B1	0x57DC	# <CJK>
+0xD4B2	0x57F4	# <CJK>
+0xD4B3	0x5800	# <CJK>
+0xD4B4	0x57ED	# <CJK>
+0xD4B5	0x57FD	# <CJK>
+0xD4B6	0x5808	# <CJK>
+0xD4B7	0x57F8	# <CJK>
+0xD4B8	0x580B	# <CJK>
+0xD4B9	0x57F3	# <CJK>
+0xD4BA	0x57CF	# <CJK>
+0xD4BB	0x5807	# <CJK>
+0xD4BC	0x57EE	# <CJK>
+0xD4BD	0x57E3	# <CJK>
+0xD4BE	0x57F2	# <CJK>
+0xD4BF	0x57E5	# <CJK>
+0xD4C0	0x57EC	# <CJK>
+0xD4C1	0x57E1	# <CJK>
+0xD4C2	0x580E	# <CJK>
+0xD4C3	0x57FC	# <CJK>
+0xD4C4	0x5810	# <CJK>
+0xD4C5	0x57E7	# <CJK>
+0xD4C6	0x5801	# <CJK>
+0xD4C7	0x580C	# <CJK>
+0xD4C8	0x57F1	# <CJK>
+0xD4C9	0x57E9	# <CJK>
+0xD4CA	0x57F0	# <CJK>
+0xD4CB	0x580D	# <CJK>
+0xD4CC	0x5804	# <CJK>
+0xD4CD	0x595C	# <CJK>
+0xD4CE	0x5A60	# <CJK>
+0xD4CF	0x5A58	# <CJK>
+0xD4D0	0x5A55	# <CJK>
+0xD4D1	0x5A67	# <CJK>
+0xD4D2	0x5A5E	# <CJK>
+0xD4D3	0x5A38	# <CJK>
+0xD4D4	0x5A35	# <CJK>
+0xD4D5	0x5A6D	# <CJK>
+0xD4D6	0x5A50	# <CJK>
+0xD4D7	0x5A5F	# <CJK>
+0xD4D8	0x5A65	# <CJK>
+0xD4D9	0x5A6C	# <CJK>
+0xD4DA	0x5A53	# <CJK>
+0xD4DB	0x5A64	# <CJK>
+0xD4DC	0x5A57	# <CJK>
+0xD4DD	0x5A43	# <CJK>
+0xD4DE	0x5A5D	# <CJK>
+0xD4DF	0x5A52	# <CJK>
+0xD4E0	0x5A44	# <CJK>
+0xD4E1	0x5A5B	# <CJK>
+0xD4E2	0x5A48	# <CJK>
+0xD4E3	0x5A8E	# <CJK>
+0xD4E4	0x5A3E	# <CJK>
+0xD4E5	0x5A4D	# <CJK>
+0xD4E6	0x5A39	# <CJK>
+0xD4E7	0x5A4C	# <CJK>
+0xD4E8	0x5A70	# <CJK>
+0xD4E9	0x5A69	# <CJK>
+0xD4EA	0x5A47	# <CJK>
+0xD4EB	0x5A51	# <CJK>
+0xD4EC	0x5A56	# <CJK>
+0xD4ED	0x5A42	# <CJK>
+0xD4EE	0x5A5C	# <CJK>
+0xD4EF	0x5B72	# <CJK>
+0xD4F0	0x5B6E	# <CJK>
+0xD4F1	0x5BC1	# <CJK>
+0xD4F2	0x5BC0	# <CJK>
+0xD4F3	0x5C59	# <CJK>
+0xD4F4	0x5D1E	# <CJK>
+0xD4F5	0x5D0B	# <CJK>
+0xD4F6	0x5D1D	# <CJK>
+0xD4F7	0x5D1A	# <CJK>
+0xD4F8	0x5D20	# <CJK>
+0xD4F9	0x5D0C	# <CJK>
+0xD4FA	0x5D28	# <CJK>
+0xD4FB	0x5D0D	# <CJK>
+0xD4FC	0x5D26	# <CJK>
+0xD4FD	0x5D25	# <CJK>
+0xD4FE	0x5D0F	# <CJK>
+0xD540	0x5D30	# <CJK>
+0xD541	0x5D12	# <CJK>
+0xD542	0x5D23	# <CJK>
+0xD543	0x5D1F	# <CJK>
+0xD544	0x5D2E	# <CJK>
+0xD545	0x5E3E	# <CJK>
+0xD546	0x5E34	# <CJK>
+0xD547	0x5EB1	# <CJK>
+0xD548	0x5EB4	# <CJK>
+0xD549	0x5EB9	# <CJK>
+0xD54A	0x5EB2	# <CJK>
+0xD54B	0x5EB3	# <CJK>
+0xD54C	0x5F36	# <CJK>
+0xD54D	0x5F38	# <CJK>
+0xD54E	0x5F9B	# <CJK>
+0xD54F	0x5F96	# <CJK>
+0xD550	0x5F9F	# <CJK>
+0xD551	0x608A	# <CJK>
+0xD552	0x6090	# <CJK>
+0xD553	0x6086	# <CJK>
+0xD554	0x60BE	# <CJK>
+0xD555	0x60B0	# <CJK>
+0xD556	0x60BA	# <CJK>
+0xD557	0x60D3	# <CJK>
+0xD558	0x60D4	# <CJK>
+0xD559	0x60CF	# <CJK>
+0xD55A	0x60E4	# <CJK>
+0xD55B	0x60D9	# <CJK>
+0xD55C	0x60DD	# <CJK>
+0xD55D	0x60C8	# <CJK>
+0xD55E	0x60B1	# <CJK>
+0xD55F	0x60DB	# <CJK>
+0xD560	0x60B7	# <CJK>
+0xD561	0x60CA	# <CJK>
+0xD562	0x60BF	# <CJK>
+0xD563	0x60C3	# <CJK>
+0xD564	0x60CD	# <CJK>
+0xD565	0x60C0	# <CJK>
+0xD566	0x6332	# <CJK>
+0xD567	0x6365	# <CJK>
+0xD568	0x638A	# <CJK>
+0xD569	0x6382	# <CJK>
+0xD56A	0x637D	# <CJK>
+0xD56B	0x63BD	# <CJK>
+0xD56C	0x639E	# <CJK>
+0xD56D	0x63AD	# <CJK>
+0xD56E	0x639D	# <CJK>
+0xD56F	0x6397	# <CJK>
+0xD570	0x63AB	# <CJK>
+0xD571	0x638E	# <CJK>
+0xD572	0x636F	# <CJK>
+0xD573	0x6387	# <CJK>
+0xD574	0x6390	# <CJK>
+0xD575	0x636E	# <CJK>
+0xD576	0x63AF	# <CJK>
+0xD577	0x6375	# <CJK>
+0xD578	0x639C	# <CJK>
+0xD579	0x636D	# <CJK>
+0xD57A	0x63AE	# <CJK>
+0xD57B	0x637C	# <CJK>
+0xD57C	0x63A4	# <CJK>
+0xD57D	0x633B	# <CJK>
+0xD57E	0x639F	# <CJK>
+0xD5A1	0x6378	# <CJK>
+0xD5A2	0x6385	# <CJK>
+0xD5A3	0x6381	# <CJK>
+0xD5A4	0x6391	# <CJK>
+0xD5A5	0x638D	# <CJK>
+0xD5A6	0x6370	# <CJK>
+0xD5A7	0x6553	# <CJK>
+0xD5A8	0x65CD	# <CJK>
+0xD5A9	0x6665	# <CJK>
+0xD5AA	0x6661	# <CJK>
+0xD5AB	0x665B	# <CJK>
+0xD5AC	0x6659	# <CJK>
+0xD5AD	0x665C	# <CJK>
+0xD5AE	0x6662	# <CJK>
+0xD5AF	0x6718	# <CJK>
+0xD5B0	0x6879	# <CJK>
+0xD5B1	0x6887	# <CJK>
+0xD5B2	0x6890	# <CJK>
+0xD5B3	0x689C	# <CJK>
+0xD5B4	0x686D	# <CJK>
+0xD5B5	0x686E	# <CJK>
+0xD5B6	0x68AE	# <CJK>
+0xD5B7	0x68AB	# <CJK>
+0xD5B8	0x6956	# <CJK>
+0xD5B9	0x686F	# <CJK>
+0xD5BA	0x68A3	# <CJK>
+0xD5BB	0x68AC	# <CJK>
+0xD5BC	0x68A9	# <CJK>
+0xD5BD	0x6875	# <CJK>
+0xD5BE	0x6874	# <CJK>
+0xD5BF	0x68B2	# <CJK>
+0xD5C0	0x688F	# <CJK>
+0xD5C1	0x6877	# <CJK>
+0xD5C2	0x6892	# <CJK>
+0xD5C3	0x687C	# <CJK>
+0xD5C4	0x686B	# <CJK>
+0xD5C5	0x6872	# <CJK>
+0xD5C6	0x68AA	# <CJK>
+0xD5C7	0x6880	# <CJK>
+0xD5C8	0x6871	# <CJK>
+0xD5C9	0x687E	# <CJK>
+0xD5CA	0x689B	# <CJK>
+0xD5CB	0x6896	# <CJK>
+0xD5CC	0x688B	# <CJK>
+0xD5CD	0x68A0	# <CJK>
+0xD5CE	0x6889	# <CJK>
+0xD5CF	0x68A4	# <CJK>
+0xD5D0	0x6878	# <CJK>
+0xD5D1	0x687B	# <CJK>
+0xD5D2	0x6891	# <CJK>
+0xD5D3	0x688C	# <CJK>
+0xD5D4	0x688A	# <CJK>
+0xD5D5	0x687D	# <CJK>
+0xD5D6	0x6B36	# <CJK>
+0xD5D7	0x6B33	# <CJK>
+0xD5D8	0x6B37	# <CJK>
+0xD5D9	0x6B38	# <CJK>
+0xD5DA	0x6B91	# <CJK>
+0xD5DB	0x6B8F	# <CJK>
+0xD5DC	0x6B8D	# <CJK>
+0xD5DD	0x6B8E	# <CJK>
+0xD5DE	0x6B8C	# <CJK>
+0xD5DF	0x6C2A	# <CJK>
+0xD5E0	0x6DC0	# <CJK>
+0xD5E1	0x6DAB	# <CJK>
+0xD5E2	0x6DB4	# <CJK>
+0xD5E3	0x6DB3	# <CJK>
+0xD5E4	0x6E74	# <CJK>
+0xD5E5	0x6DAC	# <CJK>
+0xD5E6	0x6DE9	# <CJK>
+0xD5E7	0x6DE2	# <CJK>
+0xD5E8	0x6DB7	# <CJK>
+0xD5E9	0x6DF6	# <CJK>
+0xD5EA	0x6DD4	# <CJK>
+0xD5EB	0x6E00	# <CJK>
+0xD5EC	0x6DC8	# <CJK>
+0xD5ED	0x6DE0	# <CJK>
+0xD5EE	0x6DDF	# <CJK>
+0xD5EF	0x6DD6	# <CJK>
+0xD5F0	0x6DBE	# <CJK>
+0xD5F1	0x6DE5	# <CJK>
+0xD5F2	0x6DDC	# <CJK>
+0xD5F3	0x6DDD	# <CJK>
+0xD5F4	0x6DDB	# <CJK>
+0xD5F5	0x6DF4	# <CJK>
+0xD5F6	0x6DCA	# <CJK>
+0xD5F7	0x6DBD	# <CJK>
+0xD5F8	0x6DED	# <CJK>
+0xD5F9	0x6DF0	# <CJK>
+0xD5FA	0x6DBA	# <CJK>
+0xD5FB	0x6DD5	# <CJK>
+0xD5FC	0x6DC2	# <CJK>
+0xD5FD	0x6DCF	# <CJK>
+0xD5FE	0x6DC9	# <CJK>
+0xD640	0x6DD0	# <CJK>
+0xD641	0x6DF2	# <CJK>
+0xD642	0x6DD3	# <CJK>
+0xD643	0x6DFD	# <CJK>
+0xD644	0x6DD7	# <CJK>
+0xD645	0x6DCD	# <CJK>
+0xD646	0x6DE3	# <CJK>
+0xD647	0x6DBB	# <CJK>
+0xD648	0x70FA	# <CJK>
+0xD649	0x710D	# <CJK>
+0xD64A	0x70F7	# <CJK>
+0xD64B	0x7117	# <CJK>
+0xD64C	0x70F4	# <CJK>
+0xD64D	0x710C	# <CJK>
+0xD64E	0x70F0	# <CJK>
+0xD64F	0x7104	# <CJK>
+0xD650	0x70F3	# <CJK>
+0xD651	0x7110	# <CJK>
+0xD652	0x70FC	# <CJK>
+0xD653	0x70FF	# <CJK>
+0xD654	0x7106	# <CJK>
+0xD655	0x7113	# <CJK>
+0xD656	0x7100	# <CJK>
+0xD657	0x70F8	# <CJK>
+0xD658	0x70F6	# <CJK>
+0xD659	0x710B	# <CJK>
+0xD65A	0x7102	# <CJK>
+0xD65B	0x710E	# <CJK>
+0xD65C	0x727E	# <CJK>
+0xD65D	0x727B	# <CJK>
+0xD65E	0x727C	# <CJK>
+0xD65F	0x727F	# <CJK>
+0xD660	0x731D	# <CJK>
+0xD661	0x7317	# <CJK>
+0xD662	0x7307	# <CJK>
+0xD663	0x7311	# <CJK>
+0xD664	0x7318	# <CJK>
+0xD665	0x730A	# <CJK>
+0xD666	0x7308	# <CJK>
+0xD667	0x72FF	# <CJK>
+0xD668	0x730F	# <CJK>
+0xD669	0x731E	# <CJK>
+0xD66A	0x7388	# <CJK>
+0xD66B	0x73F6	# <CJK>
+0xD66C	0x73F8	# <CJK>
+0xD66D	0x73F5	# <CJK>
+0xD66E	0x7404	# <CJK>
+0xD66F	0x7401	# <CJK>
+0xD670	0x73FD	# <CJK>
+0xD671	0x7407	# <CJK>
+0xD672	0x7400	# <CJK>
+0xD673	0x73FA	# <CJK>
+0xD674	0x73FC	# <CJK>
+0xD675	0x73FF	# <CJK>
+0xD676	0x740C	# <CJK>
+0xD677	0x740B	# <CJK>
+0xD678	0x73F4	# <CJK>
+0xD679	0x7408	# <CJK>
+0xD67A	0x7564	# <CJK>
+0xD67B	0x7563	# <CJK>
+0xD67C	0x75CE	# <CJK>
+0xD67D	0x75D2	# <CJK>
+0xD67E	0x75CF	# <CJK>
+0xD6A1	0x75CB	# <CJK>
+0xD6A2	0x75CC	# <CJK>
+0xD6A3	0x75D1	# <CJK>
+0xD6A4	0x75D0	# <CJK>
+0xD6A5	0x768F	# <CJK>
+0xD6A6	0x7689	# <CJK>
+0xD6A7	0x76D3	# <CJK>
+0xD6A8	0x7739	# <CJK>
+0xD6A9	0x772F	# <CJK>
+0xD6AA	0x772D	# <CJK>
+0xD6AB	0x7731	# <CJK>
+0xD6AC	0x7732	# <CJK>
+0xD6AD	0x7734	# <CJK>
+0xD6AE	0x7733	# <CJK>
+0xD6AF	0x773D	# <CJK>
+0xD6B0	0x7725	# <CJK>
+0xD6B1	0x773B	# <CJK>
+0xD6B2	0x7735	# <CJK>
+0xD6B3	0x7848	# <CJK>
+0xD6B4	0x7852	# <CJK>
+0xD6B5	0x7849	# <CJK>
+0xD6B6	0x784D	# <CJK>
+0xD6B7	0x784A	# <CJK>
+0xD6B8	0x784C	# <CJK>
+0xD6B9	0x7826	# <CJK>
+0xD6BA	0x7845	# <CJK>
+0xD6BB	0x7850	# <CJK>
+0xD6BC	0x7964	# <CJK>
+0xD6BD	0x7967	# <CJK>
+0xD6BE	0x7969	# <CJK>
+0xD6BF	0x796A	# <CJK>
+0xD6C0	0x7963	# <CJK>
+0xD6C1	0x796B	# <CJK>
+0xD6C2	0x7961	# <CJK>
+0xD6C3	0x79BB	# <CJK>
+0xD6C4	0x79FA	# <CJK>
+0xD6C5	0x79F8	# <CJK>
+0xD6C6	0x79F6	# <CJK>
+0xD6C7	0x79F7	# <CJK>
+0xD6C8	0x7A8F	# <CJK>
+0xD6C9	0x7A94	# <CJK>
+0xD6CA	0x7A90	# <CJK>
+0xD6CB	0x7B35	# <CJK>
+0xD6CC	0x7B47	# <CJK>
+0xD6CD	0x7B34	# <CJK>
+0xD6CE	0x7B25	# <CJK>
+0xD6CF	0x7B30	# <CJK>
+0xD6D0	0x7B22	# <CJK>
+0xD6D1	0x7B24	# <CJK>
+0xD6D2	0x7B33	# <CJK>
+0xD6D3	0x7B18	# <CJK>
+0xD6D4	0x7B2A	# <CJK>
+0xD6D5	0x7B1D	# <CJK>
+0xD6D6	0x7B31	# <CJK>
+0xD6D7	0x7B2B	# <CJK>
+0xD6D8	0x7B2D	# <CJK>
+0xD6D9	0x7B2F	# <CJK>
+0xD6DA	0x7B32	# <CJK>
+0xD6DB	0x7B38	# <CJK>
+0xD6DC	0x7B1A	# <CJK>
+0xD6DD	0x7B23	# <CJK>
+0xD6DE	0x7C94	# <CJK>
+0xD6DF	0x7C98	# <CJK>
+0xD6E0	0x7C96	# <CJK>
+0xD6E1	0x7CA3	# <CJK>
+0xD6E2	0x7D35	# <CJK>
+0xD6E3	0x7D3D	# <CJK>
+0xD6E4	0x7D38	# <CJK>
+0xD6E5	0x7D36	# <CJK>
+0xD6E6	0x7D3A	# <CJK>
+0xD6E7	0x7D45	# <CJK>
+0xD6E8	0x7D2C	# <CJK>
+0xD6E9	0x7D29	# <CJK>
+0xD6EA	0x7D41	# <CJK>
+0xD6EB	0x7D47	# <CJK>
+0xD6EC	0x7D3E	# <CJK>
+0xD6ED	0x7D3F	# <CJK>
+0xD6EE	0x7D4A	# <CJK>
+0xD6EF	0x7D3B	# <CJK>
+0xD6F0	0x7D28	# <CJK>
+0xD6F1	0x7F63	# <CJK>
+0xD6F2	0x7F95	# <CJK>
+0xD6F3	0x7F9C	# <CJK>
+0xD6F4	0x7F9D	# <CJK>
+0xD6F5	0x7F9B	# <CJK>
+0xD6F6	0x7FCA	# <CJK>
+0xD6F7	0x7FCB	# <CJK>
+0xD6F8	0x7FCD	# <CJK>
+0xD6F9	0x7FD0	# <CJK>
+0xD6FA	0x7FD1	# <CJK>
+0xD6FB	0x7FC7	# <CJK>
+0xD6FC	0x7FCF	# <CJK>
+0xD6FD	0x7FC9	# <CJK>
+0xD6FE	0x801F	# <CJK>
+0xD740	0x801E	# <CJK>
+0xD741	0x801B	# <CJK>
+0xD742	0x8047	# <CJK>
+0xD743	0x8043	# <CJK>
+0xD744	0x8048	# <CJK>
+0xD745	0x8118	# <CJK>
+0xD746	0x8125	# <CJK>
+0xD747	0x8119	# <CJK>
+0xD748	0x811B	# <CJK>
+0xD749	0x812D	# <CJK>
+0xD74A	0x811F	# <CJK>
+0xD74B	0x812C	# <CJK>
+0xD74C	0x811E	# <CJK>
+0xD74D	0x8121	# <CJK>
+0xD74E	0x8115	# <CJK>
+0xD74F	0x8127	# <CJK>
+0xD750	0x811D	# <CJK>
+0xD751	0x8122	# <CJK>
+0xD752	0x8211	# <CJK>
+0xD753	0x8238	# <CJK>
+0xD754	0x8233	# <CJK>
+0xD755	0x823A	# <CJK>
+0xD756	0x8234	# <CJK>
+0xD757	0x8232	# <CJK>
+0xD758	0x8274	# <CJK>
+0xD759	0x8390	# <CJK>
+0xD75A	0x83A3	# <CJK>
+0xD75B	0x83A8	# <CJK>
+0xD75C	0x838D	# <CJK>
+0xD75D	0x837A	# <CJK>
+0xD75E	0x8373	# <CJK>
+0xD75F	0x83A4	# <CJK>
+0xD760	0x8374	# <CJK>
+0xD761	0x838F	# <CJK>
+0xD762	0x8381	# <CJK>
+0xD763	0x8395	# <CJK>
+0xD764	0x8399	# <CJK>
+0xD765	0x8375	# <CJK>
+0xD766	0x8394	# <CJK>
+0xD767	0x83A9	# <CJK>
+0xD768	0x837D	# <CJK>
+0xD769	0x8383	# <CJK>
+0xD76A	0x838C	# <CJK>
+0xD76B	0x839D	# <CJK>
+0xD76C	0x839B	# <CJK>
+0xD76D	0x83AA	# <CJK>
+0xD76E	0x838B	# <CJK>
+0xD76F	0x837E	# <CJK>
+0xD770	0x83A5	# <CJK>
+0xD771	0x83AF	# <CJK>
+0xD772	0x8388	# <CJK>
+0xD773	0x8397	# <CJK>
+0xD774	0x83B0	# <CJK>
+0xD775	0x837F	# <CJK>
+0xD776	0x83A6	# <CJK>
+0xD777	0x8387	# <CJK>
+0xD778	0x83AE	# <CJK>
+0xD779	0x8376	# <CJK>
+0xD77A	0x839A	# <CJK>
+0xD77B	0x8659	# <CJK>
+0xD77C	0x8656	# <CJK>
+0xD77D	0x86BF	# <CJK>
+0xD77E	0x86B7	# <CJK>
+0xD7A1	0x86C2	# <CJK>
+0xD7A2	0x86C1	# <CJK>
+0xD7A3	0x86C5	# <CJK>
+0xD7A4	0x86BA	# <CJK>
+0xD7A5	0x86B0	# <CJK>
+0xD7A6	0x86C8	# <CJK>
+0xD7A7	0x86B9	# <CJK>
+0xD7A8	0x86B3	# <CJK>
+0xD7A9	0x86B8	# <CJK>
+0xD7AA	0x86CC	# <CJK>
+0xD7AB	0x86B4	# <CJK>
+0xD7AC	0x86BB	# <CJK>
+0xD7AD	0x86BC	# <CJK>
+0xD7AE	0x86C3	# <CJK>
+0xD7AF	0x86BD	# <CJK>
+0xD7B0	0x86BE	# <CJK>
+0xD7B1	0x8852	# <CJK>
+0xD7B2	0x8889	# <CJK>
+0xD7B3	0x8895	# <CJK>
+0xD7B4	0x88A8	# <CJK>
+0xD7B5	0x88A2	# <CJK>
+0xD7B6	0x88AA	# <CJK>
+0xD7B7	0x889A	# <CJK>
+0xD7B8	0x8891	# <CJK>
+0xD7B9	0x88A1	# <CJK>
+0xD7BA	0x889F	# <CJK>
+0xD7BB	0x8898	# <CJK>
+0xD7BC	0x88A7	# <CJK>
+0xD7BD	0x8899	# <CJK>
+0xD7BE	0x889B	# <CJK>
+0xD7BF	0x8897	# <CJK>
+0xD7C0	0x88A4	# <CJK>
+0xD7C1	0x88AC	# <CJK>
+0xD7C2	0x888C	# <CJK>
+0xD7C3	0x8893	# <CJK>
+0xD7C4	0x888E	# <CJK>
+0xD7C5	0x8982	# <CJK>
+0xD7C6	0x89D6	# <CJK>
+0xD7C7	0x89D9	# <CJK>
+0xD7C8	0x89D5	# <CJK>
+0xD7C9	0x8A30	# <CJK>
+0xD7CA	0x8A27	# <CJK>
+0xD7CB	0x8A2C	# <CJK>
+0xD7CC	0x8A1E	# <CJK>
+0xD7CD	0x8C39	# <CJK>
+0xD7CE	0x8C3B	# <CJK>
+0xD7CF	0x8C5C	# <CJK>
+0xD7D0	0x8C5D	# <CJK>
+0xD7D1	0x8C7D	# <CJK>
+0xD7D2	0x8CA5	# <CJK>
+0xD7D3	0x8D7D	# <CJK>
+0xD7D4	0x8D7B	# <CJK>
+0xD7D5	0x8D79	# <CJK>
+0xD7D6	0x8DBC	# <CJK>
+0xD7D7	0x8DC2	# <CJK>
+0xD7D8	0x8DB9	# <CJK>
+0xD7D9	0x8DBF	# <CJK>
+0xD7DA	0x8DC1	# <CJK>
+0xD7DB	0x8ED8	# <CJK>
+0xD7DC	0x8EDE	# <CJK>
+0xD7DD	0x8EDD	# <CJK>
+0xD7DE	0x8EDC	# <CJK>
+0xD7DF	0x8ED7	# <CJK>
+0xD7E0	0x8EE0	# <CJK>
+0xD7E1	0x8EE1	# <CJK>
+0xD7E2	0x9024	# <CJK>
+0xD7E3	0x900B	# <CJK>
+0xD7E4	0x9011	# <CJK>
+0xD7E5	0x901C	# <CJK>
+0xD7E6	0x900C	# <CJK>
+0xD7E7	0x9021	# <CJK>
+0xD7E8	0x90EF	# <CJK>
+0xD7E9	0x90EA	# <CJK>
+0xD7EA	0x90F0	# <CJK>
+0xD7EB	0x90F4	# <CJK>
+0xD7EC	0x90F2	# <CJK>
+0xD7ED	0x90F3	# <CJK>
+0xD7EE	0x90D4	# <CJK>
+0xD7EF	0x90EB	# <CJK>
+0xD7F0	0x90EC	# <CJK>
+0xD7F1	0x90E9	# <CJK>
+0xD7F2	0x9156	# <CJK>
+0xD7F3	0x9158	# <CJK>
+0xD7F4	0x915A	# <CJK>
+0xD7F5	0x9153	# <CJK>
+0xD7F6	0x9155	# <CJK>
+0xD7F7	0x91EC	# <CJK>
+0xD7F8	0x91F4	# <CJK>
+0xD7F9	0x91F1	# <CJK>
+0xD7FA	0x91F3	# <CJK>
+0xD7FB	0x91F8	# <CJK>
+0xD7FC	0x91E4	# <CJK>
+0xD7FD	0x91F9	# <CJK>
+0xD7FE	0x91EA	# <CJK>
+0xD840	0x91EB	# <CJK>
+0xD841	0x91F7	# <CJK>
+0xD842	0x91E8	# <CJK>
+0xD843	0x91EE	# <CJK>
+0xD844	0x957A	# <CJK>
+0xD845	0x9586	# <CJK>
+0xD846	0x9588	# <CJK>
+0xD847	0x967C	# <CJK>
+0xD848	0x966D	# <CJK>
+0xD849	0x966B	# <CJK>
+0xD84A	0x9671	# <CJK>
+0xD84B	0x966F	# <CJK>
+0xD84C	0x96BF	# <CJK>
+0xD84D	0x976A	# <CJK>
+0xD84E	0x9804	# <CJK>
+0xD84F	0x98E5	# <CJK>
+0xD850	0x9997	# <CJK>
+0xD851	0x509B	# <CJK>
+0xD852	0x5095	# <CJK>
+0xD853	0x5094	# <CJK>
+0xD854	0x509E	# <CJK>
+0xD855	0x508B	# <CJK>
+0xD856	0x50A3	# <CJK>
+0xD857	0x5083	# <CJK>
+0xD858	0x508C	# <CJK>
+0xD859	0x508E	# <CJK>
+0xD85A	0x509D	# <CJK>
+0xD85B	0x5068	# <CJK>
+0xD85C	0x509C	# <CJK>
+0xD85D	0x5092	# <CJK>
+0xD85E	0x5082	# <CJK>
+0xD85F	0x5087	# <CJK>
+0xD860	0x515F	# <CJK>
+0xD861	0x51D4	# <CJK>
+0xD862	0x5312	# <CJK>
+0xD863	0x5311	# <CJK>
+0xD864	0x53A4	# <CJK>
+0xD865	0x53A7	# <CJK>
+0xD866	0x5591	# <CJK>
+0xD867	0x55A8	# <CJK>
+0xD868	0x55A5	# <CJK>
+0xD869	0x55AD	# <CJK>
+0xD86A	0x5577	# <CJK>
+0xD86B	0x5645	# <CJK>
+0xD86C	0x55A2	# <CJK>
+0xD86D	0x5593	# <CJK>
+0xD86E	0x5588	# <CJK>
+0xD86F	0x558F	# <CJK>
+0xD870	0x55B5	# <CJK>
+0xD871	0x5581	# <CJK>
+0xD872	0x55A3	# <CJK>
+0xD873	0x5592	# <CJK>
+0xD874	0x55A4	# <CJK>
+0xD875	0x557D	# <CJK>
+0xD876	0x558C	# <CJK>
+0xD877	0x55A6	# <CJK>
+0xD878	0x557F	# <CJK>
+0xD879	0x5595	# <CJK>
+0xD87A	0x55A1	# <CJK>
+0xD87B	0x558E	# <CJK>
+0xD87C	0x570C	# <CJK>
+0xD87D	0x5829	# <CJK>
+0xD87E	0x5837	# <CJK>
+0xD8A1	0x5819	# <CJK>
+0xD8A2	0x581E	# <CJK>
+0xD8A3	0x5827	# <CJK>
+0xD8A4	0x5823	# <CJK>
+0xD8A5	0x5828	# <CJK>
+0xD8A6	0x57F5	# <CJK>
+0xD8A7	0x5848	# <CJK>
+0xD8A8	0x5825	# <CJK>
+0xD8A9	0x581C	# <CJK>
+0xD8AA	0x581B	# <CJK>
+0xD8AB	0x5833	# <CJK>
+0xD8AC	0x583F	# <CJK>
+0xD8AD	0x5836	# <CJK>
+0xD8AE	0x582E	# <CJK>
+0xD8AF	0x5839	# <CJK>
+0xD8B0	0x5838	# <CJK>
+0xD8B1	0x582D	# <CJK>
+0xD8B2	0x582C	# <CJK>
+0xD8B3	0x583B	# <CJK>
+0xD8B4	0x5961	# <CJK>
+0xD8B5	0x5AAF	# <CJK>
+0xD8B6	0x5A94	# <CJK>
+0xD8B7	0x5A9F	# <CJK>
+0xD8B8	0x5A7A	# <CJK>
+0xD8B9	0x5AA2	# <CJK>
+0xD8BA	0x5A9E	# <CJK>
+0xD8BB	0x5A78	# <CJK>
+0xD8BC	0x5AA6	# <CJK>
+0xD8BD	0x5A7C	# <CJK>
+0xD8BE	0x5AA5	# <CJK>
+0xD8BF	0x5AAC	# <CJK>
+0xD8C0	0x5A95	# <CJK>
+0xD8C1	0x5AAE	# <CJK>
+0xD8C2	0x5A37	# <CJK>
+0xD8C3	0x5A84	# <CJK>
+0xD8C4	0x5A8A	# <CJK>
+0xD8C5	0x5A97	# <CJK>
+0xD8C6	0x5A83	# <CJK>
+0xD8C7	0x5A8B	# <CJK>
+0xD8C8	0x5AA9	# <CJK>
+0xD8C9	0x5A7B	# <CJK>
+0xD8CA	0x5A7D	# <CJK>
+0xD8CB	0x5A8C	# <CJK>
+0xD8CC	0x5A9C	# <CJK>
+0xD8CD	0x5A8F	# <CJK>
+0xD8CE	0x5A93	# <CJK>
+0xD8CF	0x5A9D	# <CJK>
+0xD8D0	0x5BEA	# <CJK>
+0xD8D1	0x5BCD	# <CJK>
+0xD8D2	0x5BCB	# <CJK>
+0xD8D3	0x5BD4	# <CJK>
+0xD8D4	0x5BD1	# <CJK>
+0xD8D5	0x5BCA	# <CJK>
+0xD8D6	0x5BCE	# <CJK>
+0xD8D7	0x5C0C	# <CJK>
+0xD8D8	0x5C30	# <CJK>
+0xD8D9	0x5D37	# <CJK>
+0xD8DA	0x5D43	# <CJK>
+0xD8DB	0x5D6B	# <CJK>
+0xD8DC	0x5D41	# <CJK>
+0xD8DD	0x5D4B	# <CJK>
+0xD8DE	0x5D3F	# <CJK>
+0xD8DF	0x5D35	# <CJK>
+0xD8E0	0x5D51	# <CJK>
+0xD8E1	0x5D4E	# <CJK>
+0xD8E2	0x5D55	# <CJK>
+0xD8E3	0x5D33	# <CJK>
+0xD8E4	0x5D3A	# <CJK>
+0xD8E5	0x5D52	# <CJK>
+0xD8E6	0x5D3D	# <CJK>
+0xD8E7	0x5D31	# <CJK>
+0xD8E8	0x5D59	# <CJK>
+0xD8E9	0x5D42	# <CJK>
+0xD8EA	0x5D39	# <CJK>
+0xD8EB	0x5D49	# <CJK>
+0xD8EC	0x5D38	# <CJK>
+0xD8ED	0x5D3C	# <CJK>
+0xD8EE	0x5D32	# <CJK>
+0xD8EF	0x5D36	# <CJK>
+0xD8F0	0x5D40	# <CJK>
+0xD8F1	0x5D45	# <CJK>
+0xD8F2	0x5E44	# <CJK>
+0xD8F3	0x5E41	# <CJK>
+0xD8F4	0x5F58	# <CJK>
+0xD8F5	0x5FA6	# <CJK>
+0xD8F6	0x5FA5	# <CJK>
+0xD8F7	0x5FAB	# <CJK>
+0xD8F8	0x60C9	# <CJK>
+0xD8F9	0x60B9	# <CJK>
+0xD8FA	0x60CC	# <CJK>
+0xD8FB	0x60E2	# <CJK>
+0xD8FC	0x60CE	# <CJK>
+0xD8FD	0x60C4	# <CJK>
+0xD8FE	0x6114	# <CJK>
+0xD940	0x60F2	# <CJK>
+0xD941	0x610A	# <CJK>
+0xD942	0x6116	# <CJK>
+0xD943	0x6105	# <CJK>
+0xD944	0x60F5	# <CJK>
+0xD945	0x6113	# <CJK>
+0xD946	0x60F8	# <CJK>
+0xD947	0x60FC	# <CJK>
+0xD948	0x60FE	# <CJK>
+0xD949	0x60C1	# <CJK>
+0xD94A	0x6103	# <CJK>
+0xD94B	0x6118	# <CJK>
+0xD94C	0x611D	# <CJK>
+0xD94D	0x6110	# <CJK>
+0xD94E	0x60FF	# <CJK>
+0xD94F	0x6104	# <CJK>
+0xD950	0x610B	# <CJK>
+0xD951	0x624A	# <CJK>
+0xD952	0x6394	# <CJK>
+0xD953	0x63B1	# <CJK>
+0xD954	0x63B0	# <CJK>
+0xD955	0x63CE	# <CJK>
+0xD956	0x63E5	# <CJK>
+0xD957	0x63E8	# <CJK>
+0xD958	0x63EF	# <CJK>
+0xD959	0x63C3	# <CJK>
+0xD95A	0x649D	# <CJK>
+0xD95B	0x63F3	# <CJK>
+0xD95C	0x63CA	# <CJK>
+0xD95D	0x63E0	# <CJK>
+0xD95E	0x63F6	# <CJK>
+0xD95F	0x63D5	# <CJK>
+0xD960	0x63F2	# <CJK>
+0xD961	0x63F5	# <CJK>
+0xD962	0x6461	# <CJK>
+0xD963	0x63DF	# <CJK>
+0xD964	0x63BE	# <CJK>
+0xD965	0x63DD	# <CJK>
+0xD966	0x63DC	# <CJK>
+0xD967	0x63C4	# <CJK>
+0xD968	0x63D8	# <CJK>
+0xD969	0x63D3	# <CJK>
+0xD96A	0x63C2	# <CJK>
+0xD96B	0x63C7	# <CJK>
+0xD96C	0x63CC	# <CJK>
+0xD96D	0x63CB	# <CJK>
+0xD96E	0x63C8	# <CJK>
+0xD96F	0x63F0	# <CJK>
+0xD970	0x63D7	# <CJK>
+0xD971	0x63D9	# <CJK>
+0xD972	0x6532	# <CJK>
+0xD973	0x6567	# <CJK>
+0xD974	0x656A	# <CJK>
+0xD975	0x6564	# <CJK>
+0xD976	0x655C	# <CJK>
+0xD977	0x6568	# <CJK>
+0xD978	0x6565	# <CJK>
+0xD979	0x658C	# <CJK>
+0xD97A	0x659D	# <CJK>
+0xD97B	0x659E	# <CJK>
+0xD97C	0x65AE	# <CJK>
+0xD97D	0x65D0	# <CJK>
+0xD97E	0x65D2	# <CJK>
+0xD9A1	0x667C	# <CJK>
+0xD9A2	0x666C	# <CJK>
+0xD9A3	0x667B	# <CJK>
+0xD9A4	0x6680	# <CJK>
+0xD9A5	0x6671	# <CJK>
+0xD9A6	0x6679	# <CJK>
+0xD9A7	0x666A	# <CJK>
+0xD9A8	0x6672	# <CJK>
+0xD9A9	0x6701	# <CJK>
+0xD9AA	0x690C	# <CJK>
+0xD9AB	0x68D3	# <CJK>
+0xD9AC	0x6904	# <CJK>
+0xD9AD	0x68DC	# <CJK>
+0xD9AE	0x692A	# <CJK>
+0xD9AF	0x68EC	# <CJK>
+0xD9B0	0x68EA	# <CJK>
+0xD9B1	0x68F1	# <CJK>
+0xD9B2	0x690F	# <CJK>
+0xD9B3	0x68D6	# <CJK>
+0xD9B4	0x68F7	# <CJK>
+0xD9B5	0x68EB	# <CJK>
+0xD9B6	0x68E4	# <CJK>
+0xD9B7	0x68F6	# <CJK>
+0xD9B8	0x6913	# <CJK>
+0xD9B9	0x6910	# <CJK>
+0xD9BA	0x68F3	# <CJK>
+0xD9BB	0x68E1	# <CJK>
+0xD9BC	0x6907	# <CJK>
+0xD9BD	0x68CC	# <CJK>
+0xD9BE	0x6908	# <CJK>
+0xD9BF	0x6970	# <CJK>
+0xD9C0	0x68B4	# <CJK>
+0xD9C1	0x6911	# <CJK>
+0xD9C2	0x68EF	# <CJK>
+0xD9C3	0x68C6	# <CJK>
+0xD9C4	0x6914	# <CJK>
+0xD9C5	0x68F8	# <CJK>
+0xD9C6	0x68D0	# <CJK>
+0xD9C7	0x68FD	# <CJK>
+0xD9C8	0x68FC	# <CJK>
+0xD9C9	0x68E8	# <CJK>
+0xD9CA	0x690B	# <CJK>
+0xD9CB	0x690A	# <CJK>
+0xD9CC	0x6917	# <CJK>
+0xD9CD	0x68CE	# <CJK>
+0xD9CE	0x68C8	# <CJK>
+0xD9CF	0x68DD	# <CJK>
+0xD9D0	0x68DE	# <CJK>
+0xD9D1	0x68E6	# <CJK>
+0xD9D2	0x68F4	# <CJK>
+0xD9D3	0x68D1	# <CJK>
+0xD9D4	0x6906	# <CJK>
+0xD9D5	0x68D4	# <CJK>
+0xD9D6	0x68E9	# <CJK>
+0xD9D7	0x6915	# <CJK>
+0xD9D8	0x6925	# <CJK>
+0xD9D9	0x68C7	# <CJK>
+0xD9DA	0x6B39	# <CJK>
+0xD9DB	0x6B3B	# <CJK>
+0xD9DC	0x6B3F	# <CJK>
+0xD9DD	0x6B3C	# <CJK>
+0xD9DE	0x6B94	# <CJK>
+0xD9DF	0x6B97	# <CJK>
+0xD9E0	0x6B99	# <CJK>
+0xD9E1	0x6B95	# <CJK>
+0xD9E2	0x6BBD	# <CJK>
+0xD9E3	0x6BF0	# <CJK>
+0xD9E4	0x6BF2	# <CJK>
+0xD9E5	0x6BF3	# <CJK>
+0xD9E6	0x6C30	# <CJK>
+0xD9E7	0x6DFC	# <CJK>
+0xD9E8	0x6E46	# <CJK>
+0xD9E9	0x6E47	# <CJK>
+0xD9EA	0x6E1F	# <CJK>
+0xD9EB	0x6E49	# <CJK>
+0xD9EC	0x6E88	# <CJK>
+0xD9ED	0x6E3C	# <CJK>
+0xD9EE	0x6E3D	# <CJK>
+0xD9EF	0x6E45	# <CJK>
+0xD9F0	0x6E62	# <CJK>
+0xD9F1	0x6E2B	# <CJK>
+0xD9F2	0x6E3F	# <CJK>
+0xD9F3	0x6E41	# <CJK>
+0xD9F4	0x6E5D	# <CJK>
+0xD9F5	0x6E73	# <CJK>
+0xD9F6	0x6E1C	# <CJK>
+0xD9F7	0x6E33	# <CJK>
+0xD9F8	0x6E4B	# <CJK>
+0xD9F9	0x6E40	# <CJK>
+0xD9FA	0x6E51	# <CJK>
+0xD9FB	0x6E3B	# <CJK>
+0xD9FC	0x6E03	# <CJK>
+0xD9FD	0x6E2E	# <CJK>
+0xD9FE	0x6E5E	# <CJK>
+0xDA40	0x6E68	# <CJK>
+0xDA41	0x6E5C	# <CJK>
+0xDA42	0x6E61	# <CJK>
+0xDA43	0x6E31	# <CJK>
+0xDA44	0x6E28	# <CJK>
+0xDA45	0x6E60	# <CJK>
+0xDA46	0x6E71	# <CJK>
+0xDA47	0x6E6B	# <CJK>
+0xDA48	0x6E39	# <CJK>
+0xDA49	0x6E22	# <CJK>
+0xDA4A	0x6E30	# <CJK>
+0xDA4B	0x6E53	# <CJK>
+0xDA4C	0x6E65	# <CJK>
+0xDA4D	0x6E27	# <CJK>
+0xDA4E	0x6E78	# <CJK>
+0xDA4F	0x6E64	# <CJK>
+0xDA50	0x6E77	# <CJK>
+0xDA51	0x6E55	# <CJK>
+0xDA52	0x6E79	# <CJK>
+0xDA53	0x6E52	# <CJK>
+0xDA54	0x6E66	# <CJK>
+0xDA55	0x6E35	# <CJK>
+0xDA56	0x6E36	# <CJK>
+0xDA57	0x6E5A	# <CJK>
+0xDA58	0x7120	# <CJK>
+0xDA59	0x711E	# <CJK>
+0xDA5A	0x712F	# <CJK>
+0xDA5B	0x70FB	# <CJK>
+0xDA5C	0x712E	# <CJK>
+0xDA5D	0x7131	# <CJK>
+0xDA5E	0x7123	# <CJK>
+0xDA5F	0x7125	# <CJK>
+0xDA60	0x7122	# <CJK>
+0xDA61	0x7132	# <CJK>
+0xDA62	0x711F	# <CJK>
+0xDA63	0x7128	# <CJK>
+0xDA64	0x713A	# <CJK>
+0xDA65	0x711B	# <CJK>
+0xDA66	0x724B	# <CJK>
+0xDA67	0x725A	# <CJK>
+0xDA68	0x7288	# <CJK>
+0xDA69	0x7289	# <CJK>
+0xDA6A	0x7286	# <CJK>
+0xDA6B	0x7285	# <CJK>
+0xDA6C	0x728B	# <CJK>
+0xDA6D	0x7312	# <CJK>
+0xDA6E	0x730B	# <CJK>
+0xDA6F	0x7330	# <CJK>
+0xDA70	0x7322	# <CJK>
+0xDA71	0x7331	# <CJK>
+0xDA72	0x7333	# <CJK>
+0xDA73	0x7327	# <CJK>
+0xDA74	0x7332	# <CJK>
+0xDA75	0x732D	# <CJK>
+0xDA76	0x7326	# <CJK>
+0xDA77	0x7323	# <CJK>
+0xDA78	0x7335	# <CJK>
+0xDA79	0x730C	# <CJK>
+0xDA7A	0x742E	# <CJK>
+0xDA7B	0x742C	# <CJK>
+0xDA7C	0x7430	# <CJK>
+0xDA7D	0x742B	# <CJK>
+0xDA7E	0x7416	# <CJK>
+0xDAA1	0x741A	# <CJK>
+0xDAA2	0x7421	# <CJK>
+0xDAA3	0x742D	# <CJK>
+0xDAA4	0x7431	# <CJK>
+0xDAA5	0x7424	# <CJK>
+0xDAA6	0x7423	# <CJK>
+0xDAA7	0x741D	# <CJK>
+0xDAA8	0x7429	# <CJK>
+0xDAA9	0x7420	# <CJK>
+0xDAAA	0x7432	# <CJK>
+0xDAAB	0x74FB	# <CJK>
+0xDAAC	0x752F	# <CJK>
+0xDAAD	0x756F	# <CJK>
+0xDAAE	0x756C	# <CJK>
+0xDAAF	0x75E7	# <CJK>
+0xDAB0	0x75DA	# <CJK>
+0xDAB1	0x75E1	# <CJK>
+0xDAB2	0x75E6	# <CJK>
+0xDAB3	0x75DD	# <CJK>
+0xDAB4	0x75DF	# <CJK>
+0xDAB5	0x75E4	# <CJK>
+0xDAB6	0x75D7	# <CJK>
+0xDAB7	0x7695	# <CJK>
+0xDAB8	0x7692	# <CJK>
+0xDAB9	0x76DA	# <CJK>
+0xDABA	0x7746	# <CJK>
+0xDABB	0x7747	# <CJK>
+0xDABC	0x7744	# <CJK>
+0xDABD	0x774D	# <CJK>
+0xDABE	0x7745	# <CJK>
+0xDABF	0x774A	# <CJK>
+0xDAC0	0x774E	# <CJK>
+0xDAC1	0x774B	# <CJK>
+0xDAC2	0x774C	# <CJK>
+0xDAC3	0x77DE	# <CJK>
+0xDAC4	0x77EC	# <CJK>
+0xDAC5	0x7860	# <CJK>
+0xDAC6	0x7864	# <CJK>
+0xDAC7	0x7865	# <CJK>
+0xDAC8	0x785C	# <CJK>
+0xDAC9	0x786D	# <CJK>
+0xDACA	0x7871	# <CJK>
+0xDACB	0x786A	# <CJK>
+0xDACC	0x786E	# <CJK>
+0xDACD	0x7870	# <CJK>
+0xDACE	0x7869	# <CJK>
+0xDACF	0x7868	# <CJK>
+0xDAD0	0x785E	# <CJK>
+0xDAD1	0x7862	# <CJK>
+0xDAD2	0x7974	# <CJK>
+0xDAD3	0x7973	# <CJK>
+0xDAD4	0x7972	# <CJK>
+0xDAD5	0x7970	# <CJK>
+0xDAD6	0x7A02	# <CJK>
+0xDAD7	0x7A0A	# <CJK>
+0xDAD8	0x7A03	# <CJK>
+0xDAD9	0x7A0C	# <CJK>
+0xDADA	0x7A04	# <CJK>
+0xDADB	0x7A99	# <CJK>
+0xDADC	0x7AE6	# <CJK>
+0xDADD	0x7AE4	# <CJK>
+0xDADE	0x7B4A	# <CJK>
+0xDADF	0x7B3B	# <CJK>
+0xDAE0	0x7B44	# <CJK>
+0xDAE1	0x7B48	# <CJK>
+0xDAE2	0x7B4C	# <CJK>
+0xDAE3	0x7B4E	# <CJK>
+0xDAE4	0x7B40	# <CJK>
+0xDAE5	0x7B58	# <CJK>
+0xDAE6	0x7B45	# <CJK>
+0xDAE7	0x7CA2	# <CJK>
+0xDAE8	0x7C9E	# <CJK>
+0xDAE9	0x7CA8	# <CJK>
+0xDAEA	0x7CA1	# <CJK>
+0xDAEB	0x7D58	# <CJK>
+0xDAEC	0x7D6F	# <CJK>
+0xDAED	0x7D63	# <CJK>
+0xDAEE	0x7D53	# <CJK>
+0xDAEF	0x7D56	# <CJK>
+0xDAF0	0x7D67	# <CJK>
+0xDAF1	0x7D6A	# <CJK>
+0xDAF2	0x7D4F	# <CJK>
+0xDAF3	0x7D6D	# <CJK>
+0xDAF4	0x7D5C	# <CJK>
+0xDAF5	0x7D6B	# <CJK>
+0xDAF6	0x7D52	# <CJK>
+0xDAF7	0x7D54	# <CJK>
+0xDAF8	0x7D69	# <CJK>
+0xDAF9	0x7D51	# <CJK>
+0xDAFA	0x7D5F	# <CJK>
+0xDAFB	0x7D4E	# <CJK>
+0xDAFC	0x7F3E	# <CJK>
+0xDAFD	0x7F3F	# <CJK>
+0xDAFE	0x7F65	# <CJK>
+0xDB40	0x7F66	# <CJK>
+0xDB41	0x7FA2	# <CJK>
+0xDB42	0x7FA0	# <CJK>
+0xDB43	0x7FA1	# <CJK>
+0xDB44	0x7FD7	# <CJK>
+0xDB45	0x8051	# <CJK>
+0xDB46	0x804F	# <CJK>
+0xDB47	0x8050	# <CJK>
+0xDB48	0x80FE	# <CJK>
+0xDB49	0x80D4	# <CJK>
+0xDB4A	0x8143	# <CJK>
+0xDB4B	0x814A	# <CJK>
+0xDB4C	0x8152	# <CJK>
+0xDB4D	0x814F	# <CJK>
+0xDB4E	0x8147	# <CJK>
+0xDB4F	0x813D	# <CJK>
+0xDB50	0x814D	# <CJK>
+0xDB51	0x813A	# <CJK>
+0xDB52	0x81E6	# <CJK>
+0xDB53	0x81EE	# <CJK>
+0xDB54	0x81F7	# <CJK>
+0xDB55	0x81F8	# <CJK>
+0xDB56	0x81F9	# <CJK>
+0xDB57	0x8204	# <CJK>
+0xDB58	0x823C	# <CJK>
+0xDB59	0x823D	# <CJK>
+0xDB5A	0x823F	# <CJK>
+0xDB5B	0x8275	# <CJK>
+0xDB5C	0x833B	# <CJK>
+0xDB5D	0x83CF	# <CJK>
+0xDB5E	0x83F9	# <CJK>
+0xDB5F	0x8423	# <CJK>
+0xDB60	0x83C0	# <CJK>
+0xDB61	0x83E8	# <CJK>
+0xDB62	0x8412	# <CJK>
+0xDB63	0x83E7	# <CJK>
+0xDB64	0x83E4	# <CJK>
+0xDB65	0x83FC	# <CJK>
+0xDB66	0x83F6	# <CJK>
+0xDB67	0x8410	# <CJK>
+0xDB68	0x83C6	# <CJK>
+0xDB69	0x83C8	# <CJK>
+0xDB6A	0x83EB	# <CJK>
+0xDB6B	0x83E3	# <CJK>
+0xDB6C	0x83BF	# <CJK>
+0xDB6D	0x8401	# <CJK>
+0xDB6E	0x83DD	# <CJK>
+0xDB6F	0x83E5	# <CJK>
+0xDB70	0x83D8	# <CJK>
+0xDB71	0x83FF	# <CJK>
+0xDB72	0x83E1	# <CJK>
+0xDB73	0x83CB	# <CJK>
+0xDB74	0x83CE	# <CJK>
+0xDB75	0x83D6	# <CJK>
+0xDB76	0x83F5	# <CJK>
+0xDB77	0x83C9	# <CJK>
+0xDB78	0x8409	# <CJK>
+0xDB79	0x840F	# <CJK>
+0xDB7A	0x83DE	# <CJK>
+0xDB7B	0x8411	# <CJK>
+0xDB7C	0x8406	# <CJK>
+0xDB7D	0x83C2	# <CJK>
+0xDB7E	0x83F3	# <CJK>
+0xDBA1	0x83D5	# <CJK>
+0xDBA2	0x83FA	# <CJK>
+0xDBA3	0x83C7	# <CJK>
+0xDBA4	0x83D1	# <CJK>
+0xDBA5	0x83EA	# <CJK>
+0xDBA6	0x8413	# <CJK>
+0xDBA7	0x83C3	# <CJK>
+0xDBA8	0x83EC	# <CJK>
+0xDBA9	0x83EE	# <CJK>
+0xDBAA	0x83C4	# <CJK>
+0xDBAB	0x83FB	# <CJK>
+0xDBAC	0x83D7	# <CJK>
+0xDBAD	0x83E2	# <CJK>
+0xDBAE	0x841B	# <CJK>
+0xDBAF	0x83DB	# <CJK>
+0xDBB0	0x83FE	# <CJK>
+0xDBB1	0x86D8	# <CJK>
+0xDBB2	0x86E2	# <CJK>
+0xDBB3	0x86E6	# <CJK>
+0xDBB4	0x86D3	# <CJK>
+0xDBB5	0x86E3	# <CJK>
+0xDBB6	0x86DA	# <CJK>
+0xDBB7	0x86EA	# <CJK>
+0xDBB8	0x86DD	# <CJK>
+0xDBB9	0x86EB	# <CJK>
+0xDBBA	0x86DC	# <CJK>
+0xDBBB	0x86EC	# <CJK>
+0xDBBC	0x86E9	# <CJK>
+0xDBBD	0x86D7	# <CJK>
+0xDBBE	0x86E8	# <CJK>
+0xDBBF	0x86D1	# <CJK>
+0xDBC0	0x8848	# <CJK>
+0xDBC1	0x8856	# <CJK>
+0xDBC2	0x8855	# <CJK>
+0xDBC3	0x88BA	# <CJK>
+0xDBC4	0x88D7	# <CJK>
+0xDBC5	0x88B9	# <CJK>
+0xDBC6	0x88B8	# <CJK>
+0xDBC7	0x88C0	# <CJK>
+0xDBC8	0x88BE	# <CJK>
+0xDBC9	0x88B6	# <CJK>
+0xDBCA	0x88BC	# <CJK>
+0xDBCB	0x88B7	# <CJK>
+0xDBCC	0x88BD	# <CJK>
+0xDBCD	0x88B2	# <CJK>
+0xDBCE	0x8901	# <CJK>
+0xDBCF	0x88C9	# <CJK>
+0xDBD0	0x8995	# <CJK>
+0xDBD1	0x8998	# <CJK>
+0xDBD2	0x8997	# <CJK>
+0xDBD3	0x89DD	# <CJK>
+0xDBD4	0x89DA	# <CJK>
+0xDBD5	0x89DB	# <CJK>
+0xDBD6	0x8A4E	# <CJK>
+0xDBD7	0x8A4D	# <CJK>
+0xDBD8	0x8A39	# <CJK>
+0xDBD9	0x8A59	# <CJK>
+0xDBDA	0x8A40	# <CJK>
+0xDBDB	0x8A57	# <CJK>
+0xDBDC	0x8A58	# <CJK>
+0xDBDD	0x8A44	# <CJK>
+0xDBDE	0x8A45	# <CJK>
+0xDBDF	0x8A52	# <CJK>
+0xDBE0	0x8A48	# <CJK>
+0xDBE1	0x8A51	# <CJK>
+0xDBE2	0x8A4A	# <CJK>
+0xDBE3	0x8A4C	# <CJK>
+0xDBE4	0x8A4F	# <CJK>
+0xDBE5	0x8C5F	# <CJK>
+0xDBE6	0x8C81	# <CJK>
+0xDBE7	0x8C80	# <CJK>
+0xDBE8	0x8CBA	# <CJK>
+0xDBE9	0x8CBE	# <CJK>
+0xDBEA	0x8CB0	# <CJK>
+0xDBEB	0x8CB9	# <CJK>
+0xDBEC	0x8CB5	# <CJK>
+0xDBED	0x8D84	# <CJK>
+0xDBEE	0x8D80	# <CJK>
+0xDBEF	0x8D89	# <CJK>
+0xDBF0	0x8DD8	# <CJK>
+0xDBF1	0x8DD3	# <CJK>
+0xDBF2	0x8DCD	# <CJK>
+0xDBF3	0x8DC7	# <CJK>
+0xDBF4	0x8DD6	# <CJK>
+0xDBF5	0x8DDC	# <CJK>
+0xDBF6	0x8DCF	# <CJK>
+0xDBF7	0x8DD5	# <CJK>
+0xDBF8	0x8DD9	# <CJK>
+0xDBF9	0x8DC8	# <CJK>
+0xDBFA	0x8DD7	# <CJK>
+0xDBFB	0x8DC5	# <CJK>
+0xDBFC	0x8EEF	# <CJK>
+0xDBFD	0x8EF7	# <CJK>
+0xDBFE	0x8EFA	# <CJK>
+0xDC40	0x8EF9	# <CJK>
+0xDC41	0x8EE6	# <CJK>
+0xDC42	0x8EEE	# <CJK>
+0xDC43	0x8EE5	# <CJK>
+0xDC44	0x8EF5	# <CJK>
+0xDC45	0x8EE7	# <CJK>
+0xDC46	0x8EE8	# <CJK>
+0xDC47	0x8EF6	# <CJK>
+0xDC48	0x8EEB	# <CJK>
+0xDC49	0x8EF1	# <CJK>
+0xDC4A	0x8EEC	# <CJK>
+0xDC4B	0x8EF4	# <CJK>
+0xDC4C	0x8EE9	# <CJK>
+0xDC4D	0x902D	# <CJK>
+0xDC4E	0x9034	# <CJK>
+0xDC4F	0x902F	# <CJK>
+0xDC50	0x9106	# <CJK>
+0xDC51	0x912C	# <CJK>
+0xDC52	0x9104	# <CJK>
+0xDC53	0x90FF	# <CJK>
+0xDC54	0x90FC	# <CJK>
+0xDC55	0x9108	# <CJK>
+0xDC56	0x90F9	# <CJK>
+0xDC57	0x90FB	# <CJK>
+0xDC58	0x9101	# <CJK>
+0xDC59	0x9100	# <CJK>
+0xDC5A	0x9107	# <CJK>
+0xDC5B	0x9105	# <CJK>
+0xDC5C	0x9103	# <CJK>
+0xDC5D	0x9161	# <CJK>
+0xDC5E	0x9164	# <CJK>
+0xDC5F	0x915F	# <CJK>
+0xDC60	0x9162	# <CJK>
+0xDC61	0x9160	# <CJK>
+0xDC62	0x9201	# <CJK>
+0xDC63	0x920A	# <CJK>
+0xDC64	0x9225	# <CJK>
+0xDC65	0x9203	# <CJK>
+0xDC66	0x921A	# <CJK>
+0xDC67	0x9226	# <CJK>
+0xDC68	0x920F	# <CJK>
+0xDC69	0x920C	# <CJK>
+0xDC6A	0x9200	# <CJK>
+0xDC6B	0x9212	# <CJK>
+0xDC6C	0x91FF	# <CJK>
+0xDC6D	0x91FD	# <CJK>
+0xDC6E	0x9206	# <CJK>
+0xDC6F	0x9204	# <CJK>
+0xDC70	0x9227	# <CJK>
+0xDC71	0x9202	# <CJK>
+0xDC72	0x921C	# <CJK>
+0xDC73	0x9224	# <CJK>
+0xDC74	0x9219	# <CJK>
+0xDC75	0x9217	# <CJK>
+0xDC76	0x9205	# <CJK>
+0xDC77	0x9216	# <CJK>
+0xDC78	0x957B	# <CJK>
+0xDC79	0x958D	# <CJK>
+0xDC7A	0x958C	# <CJK>
+0xDC7B	0x9590	# <CJK>
+0xDC7C	0x9687	# <CJK>
+0xDC7D	0x967E	# <CJK>
+0xDC7E	0x9688	# <CJK>
+0xDCA1	0x9689	# <CJK>
+0xDCA2	0x9683	# <CJK>
+0xDCA3	0x9680	# <CJK>
+0xDCA4	0x96C2	# <CJK>
+0xDCA5	0x96C8	# <CJK>
+0xDCA6	0x96C3	# <CJK>
+0xDCA7	0x96F1	# <CJK>
+0xDCA8	0x96F0	# <CJK>
+0xDCA9	0x976C	# <CJK>
+0xDCAA	0x9770	# <CJK>
+0xDCAB	0x976E	# <CJK>
+0xDCAC	0x9807	# <CJK>
+0xDCAD	0x98A9	# <CJK>
+0xDCAE	0x98EB	# <CJK>
+0xDCAF	0x9CE6	# <CJK>
+0xDCB0	0x9EF9	# <CJK>
+0xDCB1	0x4E83	# <CJK>
+0xDCB2	0x4E84	# <CJK>
+0xDCB3	0x4EB6	# <CJK>
+0xDCB4	0x50BD	# <CJK>
+0xDCB5	0x50BF	# <CJK>
+0xDCB6	0x50C6	# <CJK>
+0xDCB7	0x50AE	# <CJK>
+0xDCB8	0x50C4	# <CJK>
+0xDCB9	0x50CA	# <CJK>
+0xDCBA	0x50B4	# <CJK>
+0xDCBB	0x50C8	# <CJK>
+0xDCBC	0x50C2	# <CJK>
+0xDCBD	0x50B0	# <CJK>
+0xDCBE	0x50C1	# <CJK>
+0xDCBF	0x50BA	# <CJK>
+0xDCC0	0x50B1	# <CJK>
+0xDCC1	0x50CB	# <CJK>
+0xDCC2	0x50C9	# <CJK>
+0xDCC3	0x50B6	# <CJK>
+0xDCC4	0x50B8	# <CJK>
+0xDCC5	0x51D7	# <CJK>
+0xDCC6	0x527A	# <CJK>
+0xDCC7	0x5278	# <CJK>
+0xDCC8	0x527B	# <CJK>
+0xDCC9	0x527C	# <CJK>
+0xDCCA	0x55C3	# <CJK>
+0xDCCB	0x55DB	# <CJK>
+0xDCCC	0x55CC	# <CJK>
+0xDCCD	0x55D0	# <CJK>
+0xDCCE	0x55CB	# <CJK>
+0xDCCF	0x55CA	# <CJK>
+0xDCD0	0x55DD	# <CJK>
+0xDCD1	0x55C0	# <CJK>
+0xDCD2	0x55D4	# <CJK>
+0xDCD3	0x55C4	# <CJK>
+0xDCD4	0x55E9	# <CJK>
+0xDCD5	0x55BF	# <CJK>
+0xDCD6	0x55D2	# <CJK>
+0xDCD7	0x558D	# <CJK>
+0xDCD8	0x55CF	# <CJK>
+0xDCD9	0x55D5	# <CJK>
+0xDCDA	0x55E2	# <CJK>
+0xDCDB	0x55D6	# <CJK>
+0xDCDC	0x55C8	# <CJK>
+0xDCDD	0x55F2	# <CJK>
+0xDCDE	0x55CD	# <CJK>
+0xDCDF	0x55D9	# <CJK>
+0xDCE0	0x55C2	# <CJK>
+0xDCE1	0x5714	# <CJK>
+0xDCE2	0x5853	# <CJK>
+0xDCE3	0x5868	# <CJK>
+0xDCE4	0x5864	# <CJK>
+0xDCE5	0x584F	# <CJK>
+0xDCE6	0x584D	# <CJK>
+0xDCE7	0x5849	# <CJK>
+0xDCE8	0x586F	# <CJK>
+0xDCE9	0x5855	# <CJK>
+0xDCEA	0x584E	# <CJK>
+0xDCEB	0x585D	# <CJK>
+0xDCEC	0x5859	# <CJK>
+0xDCED	0x5865	# <CJK>
+0xDCEE	0x585B	# <CJK>
+0xDCEF	0x583D	# <CJK>
+0xDCF0	0x5863	# <CJK>
+0xDCF1	0x5871	# <CJK>
+0xDCF2	0x58FC	# <CJK>
+0xDCF3	0x5AC7	# <CJK>
+0xDCF4	0x5AC4	# <CJK>
+0xDCF5	0x5ACB	# <CJK>
+0xDCF6	0x5ABA	# <CJK>
+0xDCF7	0x5AB8	# <CJK>
+0xDCF8	0x5AB1	# <CJK>
+0xDCF9	0x5AB5	# <CJK>
+0xDCFA	0x5AB0	# <CJK>
+0xDCFB	0x5ABF	# <CJK>
+0xDCFC	0x5AC8	# <CJK>
+0xDCFD	0x5ABB	# <CJK>
+0xDCFE	0x5AC6	# <CJK>
+0xDD40	0x5AB7	# <CJK>
+0xDD41	0x5AC0	# <CJK>
+0xDD42	0x5ACA	# <CJK>
+0xDD43	0x5AB4	# <CJK>
+0xDD44	0x5AB6	# <CJK>
+0xDD45	0x5ACD	# <CJK>
+0xDD46	0x5AB9	# <CJK>
+0xDD47	0x5A90	# <CJK>
+0xDD48	0x5BD6	# <CJK>
+0xDD49	0x5BD8	# <CJK>
+0xDD4A	0x5BD9	# <CJK>
+0xDD4B	0x5C1F	# <CJK>
+0xDD4C	0x5C33	# <CJK>
+0xDD4D	0x5D71	# <CJK>
+0xDD4E	0x5D63	# <CJK>
+0xDD4F	0x5D4A	# <CJK>
+0xDD50	0x5D65	# <CJK>
+0xDD51	0x5D72	# <CJK>
+0xDD52	0x5D6C	# <CJK>
+0xDD53	0x5D5E	# <CJK>
+0xDD54	0x5D68	# <CJK>
+0xDD55	0x5D67	# <CJK>
+0xDD56	0x5D62	# <CJK>
+0xDD57	0x5DF0	# <CJK>
+0xDD58	0x5E4F	# <CJK>
+0xDD59	0x5E4E	# <CJK>
+0xDD5A	0x5E4A	# <CJK>
+0xDD5B	0x5E4D	# <CJK>
+0xDD5C	0x5E4B	# <CJK>
+0xDD5D	0x5EC5	# <CJK>
+0xDD5E	0x5ECC	# <CJK>
+0xDD5F	0x5EC6	# <CJK>
+0xDD60	0x5ECB	# <CJK>
+0xDD61	0x5EC7	# <CJK>
+0xDD62	0x5F40	# <CJK>
+0xDD63	0x5FAF	# <CJK>
+0xDD64	0x5FAD	# <CJK>
+0xDD65	0x60F7	# <CJK>
+0xDD66	0x6149	# <CJK>
+0xDD67	0x614A	# <CJK>
+0xDD68	0x612B	# <CJK>
+0xDD69	0x6145	# <CJK>
+0xDD6A	0x6136	# <CJK>
+0xDD6B	0x6132	# <CJK>
+0xDD6C	0x612E	# <CJK>
+0xDD6D	0x6146	# <CJK>
+0xDD6E	0x612F	# <CJK>
+0xDD6F	0x614F	# <CJK>
+0xDD70	0x6129	# <CJK>
+0xDD71	0x6140	# <CJK>
+0xDD72	0x6220	# <CJK>
+0xDD73	0x9168	# <CJK>
+0xDD74	0x6223	# <CJK>
+0xDD75	0x6225	# <CJK>
+0xDD76	0x6224	# <CJK>
+0xDD77	0x63C5	# <CJK>
+0xDD78	0x63F1	# <CJK>
+0xDD79	0x63EB	# <CJK>
+0xDD7A	0x6410	# <CJK>
+0xDD7B	0x6412	# <CJK>
+0xDD7C	0x6409	# <CJK>
+0xDD7D	0x6420	# <CJK>
+0xDD7E	0x6424	# <CJK>
+0xDDA1	0x6433	# <CJK>
+0xDDA2	0x6443	# <CJK>
+0xDDA3	0x641F	# <CJK>
+0xDDA4	0x6415	# <CJK>
+0xDDA5	0x6418	# <CJK>
+0xDDA6	0x6439	# <CJK>
+0xDDA7	0x6437	# <CJK>
+0xDDA8	0x6422	# <CJK>
+0xDDA9	0x6423	# <CJK>
+0xDDAA	0x640C	# <CJK>
+0xDDAB	0x6426	# <CJK>
+0xDDAC	0x6430	# <CJK>
+0xDDAD	0x6428	# <CJK>
+0xDDAE	0x6441	# <CJK>
+0xDDAF	0x6435	# <CJK>
+0xDDB0	0x642F	# <CJK>
+0xDDB1	0x640A	# <CJK>
+0xDDB2	0x641A	# <CJK>
+0xDDB3	0x6440	# <CJK>
+0xDDB4	0x6425	# <CJK>
+0xDDB5	0x6427	# <CJK>
+0xDDB6	0x640B	# <CJK>
+0xDDB7	0x63E7	# <CJK>
+0xDDB8	0x641B	# <CJK>
+0xDDB9	0x642E	# <CJK>
+0xDDBA	0x6421	# <CJK>
+0xDDBB	0x640E	# <CJK>
+0xDDBC	0x656F	# <CJK>
+0xDDBD	0x6592	# <CJK>
+0xDDBE	0x65D3	# <CJK>
+0xDDBF	0x6686	# <CJK>
+0xDDC0	0x668C	# <CJK>
+0xDDC1	0x6695	# <CJK>
+0xDDC2	0x6690	# <CJK>
+0xDDC3	0x668B	# <CJK>
+0xDDC4	0x668A	# <CJK>
+0xDDC5	0x6699	# <CJK>
+0xDDC6	0x6694	# <CJK>
+0xDDC7	0x6678	# <CJK>
+0xDDC8	0x6720	# <CJK>
+0xDDC9	0x6966	# <CJK>
+0xDDCA	0x695F	# <CJK>
+0xDDCB	0x6938	# <CJK>
+0xDDCC	0x694E	# <CJK>
+0xDDCD	0x6962	# <CJK>
+0xDDCE	0x6971	# <CJK>
+0xDDCF	0x693F	# <CJK>
+0xDDD0	0x6945	# <CJK>
+0xDDD1	0x696A	# <CJK>
+0xDDD2	0x6939	# <CJK>
+0xDDD3	0x6942	# <CJK>
+0xDDD4	0x6957	# <CJK>
+0xDDD5	0x6959	# <CJK>
+0xDDD6	0x697A	# <CJK>
+0xDDD7	0x6948	# <CJK>
+0xDDD8	0x6949	# <CJK>
+0xDDD9	0x6935	# <CJK>
+0xDDDA	0x696C	# <CJK>
+0xDDDB	0x6933	# <CJK>
+0xDDDC	0x693D	# <CJK>
+0xDDDD	0x6965	# <CJK>
+0xDDDE	0x68F0	# <CJK>
+0xDDDF	0x6978	# <CJK>
+0xDDE0	0x6934	# <CJK>
+0xDDE1	0x6969	# <CJK>
+0xDDE2	0x6940	# <CJK>
+0xDDE3	0x696F	# <CJK>
+0xDDE4	0x6944	# <CJK>
+0xDDE5	0x6976	# <CJK>
+0xDDE6	0x6958	# <CJK>
+0xDDE7	0x6941	# <CJK>
+0xDDE8	0x6974	# <CJK>
+0xDDE9	0x694C	# <CJK>
+0xDDEA	0x693B	# <CJK>
+0xDDEB	0x694B	# <CJK>
+0xDDEC	0x6937	# <CJK>
+0xDDED	0x695C	# <CJK>
+0xDDEE	0x694F	# <CJK>
+0xDDEF	0x6951	# <CJK>
+0xDDF0	0x6932	# <CJK>
+0xDDF1	0x6952	# <CJK>
+0xDDF2	0x692F	# <CJK>
+0xDDF3	0x697B	# <CJK>
+0xDDF4	0x693C	# <CJK>
+0xDDF5	0x6B46	# <CJK>
+0xDDF6	0x6B45	# <CJK>
+0xDDF7	0x6B43	# <CJK>
+0xDDF8	0x6B42	# <CJK>
+0xDDF9	0x6B48	# <CJK>
+0xDDFA	0x6B41	# <CJK>
+0xDDFB	0x6B9B	# <CJK>
+0xDDFC	0xFA0D	# CJK COMPATIBILITY IDEOGRAPH-FA0D
+0xDDFD	0x6BFB	# <CJK>
+0xDDFE	0x6BFC	# <CJK>
+0xDE40	0x6BF9	# <CJK>
+0xDE41	0x6BF7	# <CJK>
+0xDE42	0x6BF8	# <CJK>
+0xDE43	0x6E9B	# <CJK>
+0xDE44	0x6ED6	# <CJK>
+0xDE45	0x6EC8	# <CJK>
+0xDE46	0x6E8F	# <CJK>
+0xDE47	0x6EC0	# <CJK>
+0xDE48	0x6E9F	# <CJK>
+0xDE49	0x6E93	# <CJK>
+0xDE4A	0x6E94	# <CJK>
+0xDE4B	0x6EA0	# <CJK>
+0xDE4C	0x6EB1	# <CJK>
+0xDE4D	0x6EB9	# <CJK>
+0xDE4E	0x6EC6	# <CJK>
+0xDE4F	0x6ED2	# <CJK>
+0xDE50	0x6EBD	# <CJK>
+0xDE51	0x6EC1	# <CJK>
+0xDE52	0x6E9E	# <CJK>
+0xDE53	0x6EC9	# <CJK>
+0xDE54	0x6EB7	# <CJK>
+0xDE55	0x6EB0	# <CJK>
+0xDE56	0x6ECD	# <CJK>
+0xDE57	0x6EA6	# <CJK>
+0xDE58	0x6ECF	# <CJK>
+0xDE59	0x6EB2	# <CJK>
+0xDE5A	0x6EBE	# <CJK>
+0xDE5B	0x6EC3	# <CJK>
+0xDE5C	0x6EDC	# <CJK>
+0xDE5D	0x6ED8	# <CJK>
+0xDE5E	0x6E99	# <CJK>
+0xDE5F	0x6E92	# <CJK>
+0xDE60	0x6E8E	# <CJK>
+0xDE61	0x6E8D	# <CJK>
+0xDE62	0x6EA4	# <CJK>
+0xDE63	0x6EA1	# <CJK>
+0xDE64	0x6EBF	# <CJK>
+0xDE65	0x6EB3	# <CJK>
+0xDE66	0x6ED0	# <CJK>
+0xDE67	0x6ECA	# <CJK>
+0xDE68	0x6E97	# <CJK>
+0xDE69	0x6EAE	# <CJK>
+0xDE6A	0x6EA3	# <CJK>
+0xDE6B	0x7147	# <CJK>
+0xDE6C	0x7154	# <CJK>
+0xDE6D	0x7152	# <CJK>
+0xDE6E	0x7163	# <CJK>
+0xDE6F	0x7160	# <CJK>
+0xDE70	0x7141	# <CJK>
+0xDE71	0x715D	# <CJK>
+0xDE72	0x7162	# <CJK>
+0xDE73	0x7172	# <CJK>
+0xDE74	0x7178	# <CJK>
+0xDE75	0x716A	# <CJK>
+0xDE76	0x7161	# <CJK>
+0xDE77	0x7142	# <CJK>
+0xDE78	0x7158	# <CJK>
+0xDE79	0x7143	# <CJK>
+0xDE7A	0x714B	# <CJK>
+0xDE7B	0x7170	# <CJK>
+0xDE7C	0x715F	# <CJK>
+0xDE7D	0x7150	# <CJK>
+0xDE7E	0x7153	# <CJK>
+0xDEA1	0x7144	# <CJK>
+0xDEA2	0x714D	# <CJK>
+0xDEA3	0x715A	# <CJK>
+0xDEA4	0x724F	# <CJK>
+0xDEA5	0x728D	# <CJK>
+0xDEA6	0x728C	# <CJK>
+0xDEA7	0x7291	# <CJK>
+0xDEA8	0x7290	# <CJK>
+0xDEA9	0x728E	# <CJK>
+0xDEAA	0x733C	# <CJK>
+0xDEAB	0x7342	# <CJK>
+0xDEAC	0x733B	# <CJK>
+0xDEAD	0x733A	# <CJK>
+0xDEAE	0x7340	# <CJK>
+0xDEAF	0x734A	# <CJK>
+0xDEB0	0x7349	# <CJK>
+0xDEB1	0x7444	# <CJK>
+0xDEB2	0x744A	# <CJK>
+0xDEB3	0x744B	# <CJK>
+0xDEB4	0x7452	# <CJK>
+0xDEB5	0x7451	# <CJK>
+0xDEB6	0x7457	# <CJK>
+0xDEB7	0x7440	# <CJK>
+0xDEB8	0x744F	# <CJK>
+0xDEB9	0x7450	# <CJK>
+0xDEBA	0x744E	# <CJK>
+0xDEBB	0x7442	# <CJK>
+0xDEBC	0x7446	# <CJK>
+0xDEBD	0x744D	# <CJK>
+0xDEBE	0x7454	# <CJK>
+0xDEBF	0x74E1	# <CJK>
+0xDEC0	0x74FF	# <CJK>
+0xDEC1	0x74FE	# <CJK>
+0xDEC2	0x74FD	# <CJK>
+0xDEC3	0x751D	# <CJK>
+0xDEC4	0x7579	# <CJK>
+0xDEC5	0x7577	# <CJK>
+0xDEC6	0x6983	# <CJK>
+0xDEC7	0x75EF	# <CJK>
+0xDEC8	0x760F	# <CJK>
+0xDEC9	0x7603	# <CJK>
+0xDECA	0x75F7	# <CJK>
+0xDECB	0x75FE	# <CJK>
+0xDECC	0x75FC	# <CJK>
+0xDECD	0x75F9	# <CJK>
+0xDECE	0x75F8	# <CJK>
+0xDECF	0x7610	# <CJK>
+0xDED0	0x75FB	# <CJK>
+0xDED1	0x75F6	# <CJK>
+0xDED2	0x75ED	# <CJK>
+0xDED3	0x75F5	# <CJK>
+0xDED4	0x75FD	# <CJK>
+0xDED5	0x7699	# <CJK>
+0xDED6	0x76B5	# <CJK>
+0xDED7	0x76DD	# <CJK>
+0xDED8	0x7755	# <CJK>
+0xDED9	0x775F	# <CJK>
+0xDEDA	0x7760	# <CJK>
+0xDEDB	0x7752	# <CJK>
+0xDEDC	0x7756	# <CJK>
+0xDEDD	0x775A	# <CJK>
+0xDEDE	0x7769	# <CJK>
+0xDEDF	0x7767	# <CJK>
+0xDEE0	0x7754	# <CJK>
+0xDEE1	0x7759	# <CJK>
+0xDEE2	0x776D	# <CJK>
+0xDEE3	0x77E0	# <CJK>
+0xDEE4	0x7887	# <CJK>
+0xDEE5	0x789A	# <CJK>
+0xDEE6	0x7894	# <CJK>
+0xDEE7	0x788F	# <CJK>
+0xDEE8	0x7884	# <CJK>
+0xDEE9	0x7895	# <CJK>
+0xDEEA	0x7885	# <CJK>
+0xDEEB	0x7886	# <CJK>
+0xDEEC	0x78A1	# <CJK>
+0xDEED	0x7883	# <CJK>
+0xDEEE	0x7879	# <CJK>
+0xDEEF	0x7899	# <CJK>
+0xDEF0	0x7880	# <CJK>
+0xDEF1	0x7896	# <CJK>
+0xDEF2	0x787B	# <CJK>
+0xDEF3	0x797C	# <CJK>
+0xDEF4	0x7982	# <CJK>
+0xDEF5	0x797D	# <CJK>
+0xDEF6	0x7979	# <CJK>
+0xDEF7	0x7A11	# <CJK>
+0xDEF8	0x7A18	# <CJK>
+0xDEF9	0x7A19	# <CJK>
+0xDEFA	0x7A12	# <CJK>
+0xDEFB	0x7A17	# <CJK>
+0xDEFC	0x7A15	# <CJK>
+0xDEFD	0x7A22	# <CJK>
+0xDEFE	0x7A13	# <CJK>
+0xDF40	0x7A1B	# <CJK>
+0xDF41	0x7A10	# <CJK>
+0xDF42	0x7AA3	# <CJK>
+0xDF43	0x7AA2	# <CJK>
+0xDF44	0x7A9E	# <CJK>
+0xDF45	0x7AEB	# <CJK>
+0xDF46	0x7B66	# <CJK>
+0xDF47	0x7B64	# <CJK>
+0xDF48	0x7B6D	# <CJK>
+0xDF49	0x7B74	# <CJK>
+0xDF4A	0x7B69	# <CJK>
+0xDF4B	0x7B72	# <CJK>
+0xDF4C	0x7B65	# <CJK>
+0xDF4D	0x7B73	# <CJK>
+0xDF4E	0x7B71	# <CJK>
+0xDF4F	0x7B70	# <CJK>
+0xDF50	0x7B61	# <CJK>
+0xDF51	0x7B78	# <CJK>
+0xDF52	0x7B76	# <CJK>
+0xDF53	0x7B63	# <CJK>
+0xDF54	0x7CB2	# <CJK>
+0xDF55	0x7CB4	# <CJK>
+0xDF56	0x7CAF	# <CJK>
+0xDF57	0x7D88	# <CJK>
+0xDF58	0x7D86	# <CJK>
+0xDF59	0x7D80	# <CJK>
+0xDF5A	0x7D8D	# <CJK>
+0xDF5B	0x7D7F	# <CJK>
+0xDF5C	0x7D85	# <CJK>
+0xDF5D	0x7D7A	# <CJK>
+0xDF5E	0x7D8E	# <CJK>
+0xDF5F	0x7D7B	# <CJK>
+0xDF60	0x7D83	# <CJK>
+0xDF61	0x7D7C	# <CJK>
+0xDF62	0x7D8C	# <CJK>
+0xDF63	0x7D94	# <CJK>
+0xDF64	0x7D84	# <CJK>
+0xDF65	0x7D7D	# <CJK>
+0xDF66	0x7D92	# <CJK>
+0xDF67	0x7F6D	# <CJK>
+0xDF68	0x7F6B	# <CJK>
+0xDF69	0x7F67	# <CJK>
+0xDF6A	0x7F68	# <CJK>
+0xDF6B	0x7F6C	# <CJK>
+0xDF6C	0x7FA6	# <CJK>
+0xDF6D	0x7FA5	# <CJK>
+0xDF6E	0x7FA7	# <CJK>
+0xDF6F	0x7FDB	# <CJK>
+0xDF70	0x7FDC	# <CJK>
+0xDF71	0x8021	# <CJK>
+0xDF72	0x8164	# <CJK>
+0xDF73	0x8160	# <CJK>
+0xDF74	0x8177	# <CJK>
+0xDF75	0x815C	# <CJK>
+0xDF76	0x8169	# <CJK>
+0xDF77	0x815B	# <CJK>
+0xDF78	0x8162	# <CJK>
+0xDF79	0x8172	# <CJK>
+0xDF7A	0x6721	# <CJK>
+0xDF7B	0x815E	# <CJK>
+0xDF7C	0x8176	# <CJK>
+0xDF7D	0x8167	# <CJK>
+0xDF7E	0x816F	# <CJK>
+0xDFA1	0x8144	# <CJK>
+0xDFA2	0x8161	# <CJK>
+0xDFA3	0x821D	# <CJK>
+0xDFA4	0x8249	# <CJK>
+0xDFA5	0x8244	# <CJK>
+0xDFA6	0x8240	# <CJK>
+0xDFA7	0x8242	# <CJK>
+0xDFA8	0x8245	# <CJK>
+0xDFA9	0x84F1	# <CJK>
+0xDFAA	0x843F	# <CJK>
+0xDFAB	0x8456	# <CJK>
+0xDFAC	0x8476	# <CJK>
+0xDFAD	0x8479	# <CJK>
+0xDFAE	0x848F	# <CJK>
+0xDFAF	0x848D	# <CJK>
+0xDFB0	0x8465	# <CJK>
+0xDFB1	0x8451	# <CJK>
+0xDFB2	0x8440	# <CJK>
+0xDFB3	0x8486	# <CJK>
+0xDFB4	0x8467	# <CJK>
+0xDFB5	0x8430	# <CJK>
+0xDFB6	0x844D	# <CJK>
+0xDFB7	0x847D	# <CJK>
+0xDFB8	0x845A	# <CJK>
+0xDFB9	0x8459	# <CJK>
+0xDFBA	0x8474	# <CJK>
+0xDFBB	0x8473	# <CJK>
+0xDFBC	0x845D	# <CJK>
+0xDFBD	0x8507	# <CJK>
+0xDFBE	0x845E	# <CJK>
+0xDFBF	0x8437	# <CJK>
+0xDFC0	0x843A	# <CJK>
+0xDFC1	0x8434	# <CJK>
+0xDFC2	0x847A	# <CJK>
+0xDFC3	0x8443	# <CJK>
+0xDFC4	0x8478	# <CJK>
+0xDFC5	0x8432	# <CJK>
+0xDFC6	0x8445	# <CJK>
+0xDFC7	0x8429	# <CJK>
+0xDFC8	0x83D9	# <CJK>
+0xDFC9	0x844B	# <CJK>
+0xDFCA	0x842F	# <CJK>
+0xDFCB	0x8442	# <CJK>
+0xDFCC	0x842D	# <CJK>
+0xDFCD	0x845F	# <CJK>
+0xDFCE	0x8470	# <CJK>
+0xDFCF	0x8439	# <CJK>
+0xDFD0	0x844E	# <CJK>
+0xDFD1	0x844C	# <CJK>
+0xDFD2	0x8452	# <CJK>
+0xDFD3	0x846F	# <CJK>
+0xDFD4	0x84C5	# <CJK>
+0xDFD5	0x848E	# <CJK>
+0xDFD6	0x843B	# <CJK>
+0xDFD7	0x8447	# <CJK>
+0xDFD8	0x8436	# <CJK>
+0xDFD9	0x8433	# <CJK>
+0xDFDA	0x8468	# <CJK>
+0xDFDB	0x847E	# <CJK>
+0xDFDC	0x8444	# <CJK>
+0xDFDD	0x842B	# <CJK>
+0xDFDE	0x8460	# <CJK>
+0xDFDF	0x8454	# <CJK>
+0xDFE0	0x846E	# <CJK>
+0xDFE1	0x8450	# <CJK>
+0xDFE2	0x870B	# <CJK>
+0xDFE3	0x8704	# <CJK>
+0xDFE4	0x86F7	# <CJK>
+0xDFE5	0x870C	# <CJK>
+0xDFE6	0x86FA	# <CJK>
+0xDFE7	0x86D6	# <CJK>
+0xDFE8	0x86F5	# <CJK>
+0xDFE9	0x874D	# <CJK>
+0xDFEA	0x86F8	# <CJK>
+0xDFEB	0x870E	# <CJK>
+0xDFEC	0x8709	# <CJK>
+0xDFED	0x8701	# <CJK>
+0xDFEE	0x86F6	# <CJK>
+0xDFEF	0x870D	# <CJK>
+0xDFF0	0x8705	# <CJK>
+0xDFF1	0x88D6	# <CJK>
+0xDFF2	0x88CB	# <CJK>
+0xDFF3	0x88CD	# <CJK>
+0xDFF4	0x88CE	# <CJK>
+0xDFF5	0x88DE	# <CJK>
+0xDFF6	0x88DB	# <CJK>
+0xDFF7	0x88DA	# <CJK>
+0xDFF8	0x88CC	# <CJK>
+0xDFF9	0x88D0	# <CJK>
+0xDFFA	0x8985	# <CJK>
+0xDFFB	0x899B	# <CJK>
+0xDFFC	0x89DF	# <CJK>
+0xDFFD	0x89E5	# <CJK>
+0xDFFE	0x89E4	# <CJK>
+0xE040	0x89E1	# <CJK>
+0xE041	0x89E0	# <CJK>
+0xE042	0x89E2	# <CJK>
+0xE043	0x89DC	# <CJK>
+0xE044	0x89E6	# <CJK>
+0xE045	0x8A76	# <CJK>
+0xE046	0x8A86	# <CJK>
+0xE047	0x8A7F	# <CJK>
+0xE048	0x8A61	# <CJK>
+0xE049	0x8A3F	# <CJK>
+0xE04A	0x8A77	# <CJK>
+0xE04B	0x8A82	# <CJK>
+0xE04C	0x8A84	# <CJK>
+0xE04D	0x8A75	# <CJK>
+0xE04E	0x8A83	# <CJK>
+0xE04F	0x8A81	# <CJK>
+0xE050	0x8A74	# <CJK>
+0xE051	0x8A7A	# <CJK>
+0xE052	0x8C3C	# <CJK>
+0xE053	0x8C4B	# <CJK>
+0xE054	0x8C4A	# <CJK>
+0xE055	0x8C65	# <CJK>
+0xE056	0x8C64	# <CJK>
+0xE057	0x8C66	# <CJK>
+0xE058	0x8C86	# <CJK>
+0xE059	0x8C84	# <CJK>
+0xE05A	0x8C85	# <CJK>
+0xE05B	0x8CCC	# <CJK>
+0xE05C	0x8D68	# <CJK>
+0xE05D	0x8D69	# <CJK>
+0xE05E	0x8D91	# <CJK>
+0xE05F	0x8D8C	# <CJK>
+0xE060	0x8D8E	# <CJK>
+0xE061	0x8D8F	# <CJK>
+0xE062	0x8D8D	# <CJK>
+0xE063	0x8D93	# <CJK>
+0xE064	0x8D94	# <CJK>
+0xE065	0x8D90	# <CJK>
+0xE066	0x8D92	# <CJK>
+0xE067	0x8DF0	# <CJK>
+0xE068	0x8DE0	# <CJK>
+0xE069	0x8DEC	# <CJK>
+0xE06A	0x8DF1	# <CJK>
+0xE06B	0x8DEE	# <CJK>
+0xE06C	0x8DD0	# <CJK>
+0xE06D	0x8DE9	# <CJK>
+0xE06E	0x8DE3	# <CJK>
+0xE06F	0x8DE2	# <CJK>
+0xE070	0x8DE7	# <CJK>
+0xE071	0x8DF2	# <CJK>
+0xE072	0x8DEB	# <CJK>
+0xE073	0x8DF4	# <CJK>
+0xE074	0x8F06	# <CJK>
+0xE075	0x8EFF	# <CJK>
+0xE076	0x8F01	# <CJK>
+0xE077	0x8F00	# <CJK>
+0xE078	0x8F05	# <CJK>
+0xE079	0x8F07	# <CJK>
+0xE07A	0x8F08	# <CJK>
+0xE07B	0x8F02	# <CJK>
+0xE07C	0x8F0B	# <CJK>
+0xE07D	0x9052	# <CJK>
+0xE07E	0x903F	# <CJK>
+0xE0A1	0x9044	# <CJK>
+0xE0A2	0x9049	# <CJK>
+0xE0A3	0x903D	# <CJK>
+0xE0A4	0x9110	# <CJK>
+0xE0A5	0x910D	# <CJK>
+0xE0A6	0x910F	# <CJK>
+0xE0A7	0x9111	# <CJK>
+0xE0A8	0x9116	# <CJK>
+0xE0A9	0x9114	# <CJK>
+0xE0AA	0x910B	# <CJK>
+0xE0AB	0x910E	# <CJK>
+0xE0AC	0x916E	# <CJK>
+0xE0AD	0x916F	# <CJK>
+0xE0AE	0x9248	# <CJK>
+0xE0AF	0x9252	# <CJK>
+0xE0B0	0x9230	# <CJK>
+0xE0B1	0x923A	# <CJK>
+0xE0B2	0x9266	# <CJK>
+0xE0B3	0x9233	# <CJK>
+0xE0B4	0x9265	# <CJK>
+0xE0B5	0x925E	# <CJK>
+0xE0B6	0x9283	# <CJK>
+0xE0B7	0x922E	# <CJK>
+0xE0B8	0x924A	# <CJK>
+0xE0B9	0x9246	# <CJK>
+0xE0BA	0x926D	# <CJK>
+0xE0BB	0x926C	# <CJK>
+0xE0BC	0x924F	# <CJK>
+0xE0BD	0x9260	# <CJK>
+0xE0BE	0x9267	# <CJK>
+0xE0BF	0x926F	# <CJK>
+0xE0C0	0x9236	# <CJK>
+0xE0C1	0x9261	# <CJK>
+0xE0C2	0x9270	# <CJK>
+0xE0C3	0x9231	# <CJK>
+0xE0C4	0x9254	# <CJK>
+0xE0C5	0x9263	# <CJK>
+0xE0C6	0x9250	# <CJK>
+0xE0C7	0x9272	# <CJK>
+0xE0C8	0x924E	# <CJK>
+0xE0C9	0x9253	# <CJK>
+0xE0CA	0x924C	# <CJK>
+0xE0CB	0x9256	# <CJK>
+0xE0CC	0x9232	# <CJK>
+0xE0CD	0x959F	# <CJK>
+0xE0CE	0x959C	# <CJK>
+0xE0CF	0x959E	# <CJK>
+0xE0D0	0x959B	# <CJK>
+0xE0D1	0x9692	# <CJK>
+0xE0D2	0x9693	# <CJK>
+0xE0D3	0x9691	# <CJK>
+0xE0D4	0x9697	# <CJK>
+0xE0D5	0x96CE	# <CJK>
+0xE0D6	0x96FA	# <CJK>
+0xE0D7	0x96FD	# <CJK>
+0xE0D8	0x96F8	# <CJK>
+0xE0D9	0x96F5	# <CJK>
+0xE0DA	0x9773	# <CJK>
+0xE0DB	0x9777	# <CJK>
+0xE0DC	0x9778	# <CJK>
+0xE0DD	0x9772	# <CJK>
+0xE0DE	0x980F	# <CJK>
+0xE0DF	0x980D	# <CJK>
+0xE0E0	0x980E	# <CJK>
+0xE0E1	0x98AC	# <CJK>
+0xE0E2	0x98F6	# <CJK>
+0xE0E3	0x98F9	# <CJK>
+0xE0E4	0x99AF	# <CJK>
+0xE0E5	0x99B2	# <CJK>
+0xE0E6	0x99B0	# <CJK>
+0xE0E7	0x99B5	# <CJK>
+0xE0E8	0x9AAD	# <CJK>
+0xE0E9	0x9AAB	# <CJK>
+0xE0EA	0x9B5B	# <CJK>
+0xE0EB	0x9CEA	# <CJK>
+0xE0EC	0x9CED	# <CJK>
+0xE0ED	0x9CE7	# <CJK>
+0xE0EE	0x9E80	# <CJK>
+0xE0EF	0x9EFD	# <CJK>
+0xE0F0	0x50E6	# <CJK>
+0xE0F1	0x50D4	# <CJK>
+0xE0F2	0x50D7	# <CJK>
+0xE0F3	0x50E8	# <CJK>
+0xE0F4	0x50F3	# <CJK>
+0xE0F5	0x50DB	# <CJK>
+0xE0F6	0x50EA	# <CJK>
+0xE0F7	0x50DD	# <CJK>
+0xE0F8	0x50E4	# <CJK>
+0xE0F9	0x50D3	# <CJK>
+0xE0FA	0x50EC	# <CJK>
+0xE0FB	0x50F0	# <CJK>
+0xE0FC	0x50EF	# <CJK>
+0xE0FD	0x50E3	# <CJK>
+0xE0FE	0x50E0	# <CJK>
+0xE140	0x51D8	# <CJK>
+0xE141	0x5280	# <CJK>
+0xE142	0x5281	# <CJK>
+0xE143	0x52E9	# <CJK>
+0xE144	0x52EB	# <CJK>
+0xE145	0x5330	# <CJK>
+0xE146	0x53AC	# <CJK>
+0xE147	0x5627	# <CJK>
+0xE148	0x5615	# <CJK>
+0xE149	0x560C	# <CJK>
+0xE14A	0x5612	# <CJK>
+0xE14B	0x55FC	# <CJK>
+0xE14C	0x560F	# <CJK>
+0xE14D	0x561C	# <CJK>
+0xE14E	0x5601	# <CJK>
+0xE14F	0x5613	# <CJK>
+0xE150	0x5602	# <CJK>
+0xE151	0x55FA	# <CJK>
+0xE152	0x561D	# <CJK>
+0xE153	0x5604	# <CJK>
+0xE154	0x55FF	# <CJK>
+0xE155	0x55F9	# <CJK>
+0xE156	0x5889	# <CJK>
+0xE157	0x587C	# <CJK>
+0xE158	0x5890	# <CJK>
+0xE159	0x5898	# <CJK>
+0xE15A	0x5886	# <CJK>
+0xE15B	0x5881	# <CJK>
+0xE15C	0x587F	# <CJK>
+0xE15D	0x5874	# <CJK>
+0xE15E	0x588B	# <CJK>
+0xE15F	0x587A	# <CJK>
+0xE160	0x5887	# <CJK>
+0xE161	0x5891	# <CJK>
+0xE162	0x588E	# <CJK>
+0xE163	0x5876	# <CJK>
+0xE164	0x5882	# <CJK>
+0xE165	0x5888	# <CJK>
+0xE166	0x587B	# <CJK>
+0xE167	0x5894	# <CJK>
+0xE168	0x588F	# <CJK>
+0xE169	0x58FE	# <CJK>
+0xE16A	0x596B	# <CJK>
+0xE16B	0x5ADC	# <CJK>
+0xE16C	0x5AEE	# <CJK>
+0xE16D	0x5AE5	# <CJK>
+0xE16E	0x5AD5	# <CJK>
+0xE16F	0x5AEA	# <CJK>
+0xE170	0x5ADA	# <CJK>
+0xE171	0x5AED	# <CJK>
+0xE172	0x5AEB	# <CJK>
+0xE173	0x5AF3	# <CJK>
+0xE174	0x5AE2	# <CJK>
+0xE175	0x5AE0	# <CJK>
+0xE176	0x5ADB	# <CJK>
+0xE177	0x5AEC	# <CJK>
+0xE178	0x5ADE	# <CJK>
+0xE179	0x5ADD	# <CJK>
+0xE17A	0x5AD9	# <CJK>
+0xE17B	0x5AE8	# <CJK>
+0xE17C	0x5ADF	# <CJK>
+0xE17D	0x5B77	# <CJK>
+0xE17E	0x5BE0	# <CJK>
+0xE1A1	0x5BE3	# <CJK>
+0xE1A2	0x5C63	# <CJK>
+0xE1A3	0x5D82	# <CJK>
+0xE1A4	0x5D80	# <CJK>
+0xE1A5	0x5D7D	# <CJK>
+0xE1A6	0x5D86	# <CJK>
+0xE1A7	0x5D7A	# <CJK>
+0xE1A8	0x5D81	# <CJK>
+0xE1A9	0x5D77	# <CJK>
+0xE1AA	0x5D8A	# <CJK>
+0xE1AB	0x5D89	# <CJK>
+0xE1AC	0x5D88	# <CJK>
+0xE1AD	0x5D7E	# <CJK>
+0xE1AE	0x5D7C	# <CJK>
+0xE1AF	0x5D8D	# <CJK>
+0xE1B0	0x5D79	# <CJK>
+0xE1B1	0x5D7F	# <CJK>
+0xE1B2	0x5E58	# <CJK>
+0xE1B3	0x5E59	# <CJK>
+0xE1B4	0x5E53	# <CJK>
+0xE1B5	0x5ED8	# <CJK>
+0xE1B6	0x5ED1	# <CJK>
+0xE1B7	0x5ED7	# <CJK>
+0xE1B8	0x5ECE	# <CJK>
+0xE1B9	0x5EDC	# <CJK>
+0xE1BA	0x5ED5	# <CJK>
+0xE1BB	0x5ED9	# <CJK>
+0xE1BC	0x5ED2	# <CJK>
+0xE1BD	0x5ED4	# <CJK>
+0xE1BE	0x5F44	# <CJK>
+0xE1BF	0x5F43	# <CJK>
+0xE1C0	0x5F6F	# <CJK>
+0xE1C1	0x5FB6	# <CJK>
+0xE1C2	0x612C	# <CJK>
+0xE1C3	0x6128	# <CJK>
+0xE1C4	0x6141	# <CJK>
+0xE1C5	0x615E	# <CJK>
+0xE1C6	0x6171	# <CJK>
+0xE1C7	0x6173	# <CJK>
+0xE1C8	0x6152	# <CJK>
+0xE1C9	0x6153	# <CJK>
+0xE1CA	0x6172	# <CJK>
+0xE1CB	0x616C	# <CJK>
+0xE1CC	0x6180	# <CJK>
+0xE1CD	0x6174	# <CJK>
+0xE1CE	0x6154	# <CJK>
+0xE1CF	0x617A	# <CJK>
+0xE1D0	0x615B	# <CJK>
+0xE1D1	0x6165	# <CJK>
+0xE1D2	0x613B	# <CJK>
+0xE1D3	0x616A	# <CJK>
+0xE1D4	0x6161	# <CJK>
+0xE1D5	0x6156	# <CJK>
+0xE1D6	0x6229	# <CJK>
+0xE1D7	0x6227	# <CJK>
+0xE1D8	0x622B	# <CJK>
+0xE1D9	0x642B	# <CJK>
+0xE1DA	0x644D	# <CJK>
+0xE1DB	0x645B	# <CJK>
+0xE1DC	0x645D	# <CJK>
+0xE1DD	0x6474	# <CJK>
+0xE1DE	0x6476	# <CJK>
+0xE1DF	0x6472	# <CJK>
+0xE1E0	0x6473	# <CJK>
+0xE1E1	0x647D	# <CJK>
+0xE1E2	0x6475	# <CJK>
+0xE1E3	0x6466	# <CJK>
+0xE1E4	0x64A6	# <CJK>
+0xE1E5	0x644E	# <CJK>
+0xE1E6	0x6482	# <CJK>
+0xE1E7	0x645E	# <CJK>
+0xE1E8	0x645C	# <CJK>
+0xE1E9	0x644B	# <CJK>
+0xE1EA	0x6453	# <CJK>
+0xE1EB	0x6460	# <CJK>
+0xE1EC	0x6450	# <CJK>
+0xE1ED	0x647F	# <CJK>
+0xE1EE	0x643F	# <CJK>
+0xE1EF	0x646C	# <CJK>
+0xE1F0	0x646B	# <CJK>
+0xE1F1	0x6459	# <CJK>
+0xE1F2	0x6465	# <CJK>
+0xE1F3	0x6477	# <CJK>
+0xE1F4	0x6573	# <CJK>
+0xE1F5	0x65A0	# <CJK>
+0xE1F6	0x66A1	# <CJK>
+0xE1F7	0x66A0	# <CJK>
+0xE1F8	0x669F	# <CJK>
+0xE1F9	0x6705	# <CJK>
+0xE1FA	0x6704	# <CJK>
+0xE1FB	0x6722	# <CJK>
+0xE1FC	0x69B1	# <CJK>
+0xE1FD	0x69B6	# <CJK>
+0xE1FE	0x69C9	# <CJK>
+0xE240	0x69A0	# <CJK>
+0xE241	0x69CE	# <CJK>
+0xE242	0x6996	# <CJK>
+0xE243	0x69B0	# <CJK>
+0xE244	0x69AC	# <CJK>
+0xE245	0x69BC	# <CJK>
+0xE246	0x6991	# <CJK>
+0xE247	0x6999	# <CJK>
+0xE248	0x698E	# <CJK>
+0xE249	0x69A7	# <CJK>
+0xE24A	0x698D	# <CJK>
+0xE24B	0x69A9	# <CJK>
+0xE24C	0x69BE	# <CJK>
+0xE24D	0x69AF	# <CJK>
+0xE24E	0x69BF	# <CJK>
+0xE24F	0x69C4	# <CJK>
+0xE250	0x69BD	# <CJK>
+0xE251	0x69A4	# <CJK>
+0xE252	0x69D4	# <CJK>
+0xE253	0x69B9	# <CJK>
+0xE254	0x69CA	# <CJK>
+0xE255	0x699A	# <CJK>
+0xE256	0x69CF	# <CJK>
+0xE257	0x69B3	# <CJK>
+0xE258	0x6993	# <CJK>
+0xE259	0x69AA	# <CJK>
+0xE25A	0x69A1	# <CJK>
+0xE25B	0x699E	# <CJK>
+0xE25C	0x69D9	# <CJK>
+0xE25D	0x6997	# <CJK>
+0xE25E	0x6990	# <CJK>
+0xE25F	0x69C2	# <CJK>
+0xE260	0x69B5	# <CJK>
+0xE261	0x69A5	# <CJK>
+0xE262	0x69C6	# <CJK>
+0xE263	0x6B4A	# <CJK>
+0xE264	0x6B4D	# <CJK>
+0xE265	0x6B4B	# <CJK>
+0xE266	0x6B9E	# <CJK>
+0xE267	0x6B9F	# <CJK>
+0xE268	0x6BA0	# <CJK>
+0xE269	0x6BC3	# <CJK>
+0xE26A	0x6BC4	# <CJK>
+0xE26B	0x6BFE	# <CJK>
+0xE26C	0x6ECE	# <CJK>
+0xE26D	0x6EF5	# <CJK>
+0xE26E	0x6EF1	# <CJK>
+0xE26F	0x6F03	# <CJK>
+0xE270	0x6F25	# <CJK>
+0xE271	0x6EF8	# <CJK>
+0xE272	0x6F37	# <CJK>
+0xE273	0x6EFB	# <CJK>
+0xE274	0x6F2E	# <CJK>
+0xE275	0x6F09	# <CJK>
+0xE276	0x6F4E	# <CJK>
+0xE277	0x6F19	# <CJK>
+0xE278	0x6F1A	# <CJK>
+0xE279	0x6F27	# <CJK>
+0xE27A	0x6F18	# <CJK>
+0xE27B	0x6F3B	# <CJK>
+0xE27C	0x6F12	# <CJK>
+0xE27D	0x6EED	# <CJK>
+0xE27E	0x6F0A	# <CJK>
+0xE2A1	0x6F36	# <CJK>
+0xE2A2	0x6F73	# <CJK>
+0xE2A3	0x6EF9	# <CJK>
+0xE2A4	0x6EEE	# <CJK>
+0xE2A5	0x6F2D	# <CJK>
+0xE2A6	0x6F40	# <CJK>
+0xE2A7	0x6F30	# <CJK>
+0xE2A8	0x6F3C	# <CJK>
+0xE2A9	0x6F35	# <CJK>
+0xE2AA	0x6EEB	# <CJK>
+0xE2AB	0x6F07	# <CJK>
+0xE2AC	0x6F0E	# <CJK>
+0xE2AD	0x6F43	# <CJK>
+0xE2AE	0x6F05	# <CJK>
+0xE2AF	0x6EFD	# <CJK>
+0xE2B0	0x6EF6	# <CJK>
+0xE2B1	0x6F39	# <CJK>
+0xE2B2	0x6F1C	# <CJK>
+0xE2B3	0x6EFC	# <CJK>
+0xE2B4	0x6F3A	# <CJK>
+0xE2B5	0x6F1F	# <CJK>
+0xE2B6	0x6F0D	# <CJK>
+0xE2B7	0x6F1E	# <CJK>
+0xE2B8	0x6F08	# <CJK>
+0xE2B9	0x6F21	# <CJK>
+0xE2BA	0x7187	# <CJK>
+0xE2BB	0x7190	# <CJK>
+0xE2BC	0x7189	# <CJK>
+0xE2BD	0x7180	# <CJK>
+0xE2BE	0x7185	# <CJK>
+0xE2BF	0x7182	# <CJK>
+0xE2C0	0x718F	# <CJK>
+0xE2C1	0x717B	# <CJK>
+0xE2C2	0x7186	# <CJK>
+0xE2C3	0x7181	# <CJK>
+0xE2C4	0x7197	# <CJK>
+0xE2C5	0x7244	# <CJK>
+0xE2C6	0x7253	# <CJK>
+0xE2C7	0x7297	# <CJK>
+0xE2C8	0x7295	# <CJK>
+0xE2C9	0x7293	# <CJK>
+0xE2CA	0x7343	# <CJK>
+0xE2CB	0x734D	# <CJK>
+0xE2CC	0x7351	# <CJK>
+0xE2CD	0x734C	# <CJK>
+0xE2CE	0x7462	# <CJK>
+0xE2CF	0x7473	# <CJK>
+0xE2D0	0x7471	# <CJK>
+0xE2D1	0x7475	# <CJK>
+0xE2D2	0x7472	# <CJK>
+0xE2D3	0x7467	# <CJK>
+0xE2D4	0x746E	# <CJK>
+0xE2D5	0x7500	# <CJK>
+0xE2D6	0x7502	# <CJK>
+0xE2D7	0x7503	# <CJK>
+0xE2D8	0x757D	# <CJK>
+0xE2D9	0x7590	# <CJK>
+0xE2DA	0x7616	# <CJK>
+0xE2DB	0x7608	# <CJK>
+0xE2DC	0x760C	# <CJK>
+0xE2DD	0x7615	# <CJK>
+0xE2DE	0x7611	# <CJK>
+0xE2DF	0x760A	# <CJK>
+0xE2E0	0x7614	# <CJK>
+0xE2E1	0x76B8	# <CJK>
+0xE2E2	0x7781	# <CJK>
+0xE2E3	0x777C	# <CJK>
+0xE2E4	0x7785	# <CJK>
+0xE2E5	0x7782	# <CJK>
+0xE2E6	0x776E	# <CJK>
+0xE2E7	0x7780	# <CJK>
+0xE2E8	0x776F	# <CJK>
+0xE2E9	0x777E	# <CJK>
+0xE2EA	0x7783	# <CJK>
+0xE2EB	0x78B2	# <CJK>
+0xE2EC	0x78AA	# <CJK>
+0xE2ED	0x78B4	# <CJK>
+0xE2EE	0x78AD	# <CJK>
+0xE2EF	0x78A8	# <CJK>
+0xE2F0	0x787E	# <CJK>
+0xE2F1	0x78AB	# <CJK>
+0xE2F2	0x789E	# <CJK>
+0xE2F3	0x78A5	# <CJK>
+0xE2F4	0x78A0	# <CJK>
+0xE2F5	0x78AC	# <CJK>
+0xE2F6	0x78A2	# <CJK>
+0xE2F7	0x78A4	# <CJK>
+0xE2F8	0x7998	# <CJK>
+0xE2F9	0x798A	# <CJK>
+0xE2FA	0x798B	# <CJK>
+0xE2FB	0x7996	# <CJK>
+0xE2FC	0x7995	# <CJK>
+0xE2FD	0x7994	# <CJK>
+0xE2FE	0x7993	# <CJK>
+0xE340	0x7997	# <CJK>
+0xE341	0x7988	# <CJK>
+0xE342	0x7992	# <CJK>
+0xE343	0x7990	# <CJK>
+0xE344	0x7A2B	# <CJK>
+0xE345	0x7A4A	# <CJK>
+0xE346	0x7A30	# <CJK>
+0xE347	0x7A2F	# <CJK>
+0xE348	0x7A28	# <CJK>
+0xE349	0x7A26	# <CJK>
+0xE34A	0x7AA8	# <CJK>
+0xE34B	0x7AAB	# <CJK>
+0xE34C	0x7AAC	# <CJK>
+0xE34D	0x7AEE	# <CJK>
+0xE34E	0x7B88	# <CJK>
+0xE34F	0x7B9C	# <CJK>
+0xE350	0x7B8A	# <CJK>
+0xE351	0x7B91	# <CJK>
+0xE352	0x7B90	# <CJK>
+0xE353	0x7B96	# <CJK>
+0xE354	0x7B8D	# <CJK>
+0xE355	0x7B8C	# <CJK>
+0xE356	0x7B9B	# <CJK>
+0xE357	0x7B8E	# <CJK>
+0xE358	0x7B85	# <CJK>
+0xE359	0x7B98	# <CJK>
+0xE35A	0x5284	# <CJK>
+0xE35B	0x7B99	# <CJK>
+0xE35C	0x7BA4	# <CJK>
+0xE35D	0x7B82	# <CJK>
+0xE35E	0x7CBB	# <CJK>
+0xE35F	0x7CBF	# <CJK>
+0xE360	0x7CBC	# <CJK>
+0xE361	0x7CBA	# <CJK>
+0xE362	0x7DA7	# <CJK>
+0xE363	0x7DB7	# <CJK>
+0xE364	0x7DC2	# <CJK>
+0xE365	0x7DA3	# <CJK>
+0xE366	0x7DAA	# <CJK>
+0xE367	0x7DC1	# <CJK>
+0xE368	0x7DC0	# <CJK>
+0xE369	0x7DC5	# <CJK>
+0xE36A	0x7D9D	# <CJK>
+0xE36B	0x7DCE	# <CJK>
+0xE36C	0x7DC4	# <CJK>
+0xE36D	0x7DC6	# <CJK>
+0xE36E	0x7DCB	# <CJK>
+0xE36F	0x7DCC	# <CJK>
+0xE370	0x7DAF	# <CJK>
+0xE371	0x7DB9	# <CJK>
+0xE372	0x7D96	# <CJK>
+0xE373	0x7DBC	# <CJK>
+0xE374	0x7D9F	# <CJK>
+0xE375	0x7DA6	# <CJK>
+0xE376	0x7DAE	# <CJK>
+0xE377	0x7DA9	# <CJK>
+0xE378	0x7DA1	# <CJK>
+0xE379	0x7DC9	# <CJK>
+0xE37A	0x7F73	# <CJK>
+0xE37B	0x7FE2	# <CJK>
+0xE37C	0x7FE3	# <CJK>
+0xE37D	0x7FE5	# <CJK>
+0xE37E	0x7FDE	# <CJK>
+0xE3A1	0x8024	# <CJK>
+0xE3A2	0x805D	# <CJK>
+0xE3A3	0x805C	# <CJK>
+0xE3A4	0x8189	# <CJK>
+0xE3A5	0x8186	# <CJK>
+0xE3A6	0x8183	# <CJK>
+0xE3A7	0x8187	# <CJK>
+0xE3A8	0x818D	# <CJK>
+0xE3A9	0x818C	# <CJK>
+0xE3AA	0x818B	# <CJK>
+0xE3AB	0x8215	# <CJK>
+0xE3AC	0x8497	# <CJK>
+0xE3AD	0x84A4	# <CJK>
+0xE3AE	0x84A1	# <CJK>
+0xE3AF	0x849F	# <CJK>
+0xE3B0	0x84BA	# <CJK>
+0xE3B1	0x84CE	# <CJK>
+0xE3B2	0x84C2	# <CJK>
+0xE3B3	0x84AC	# <CJK>
+0xE3B4	0x84AE	# <CJK>
+0xE3B5	0x84AB	# <CJK>
+0xE3B6	0x84B9	# <CJK>
+0xE3B7	0x84B4	# <CJK>
+0xE3B8	0x84C1	# <CJK>
+0xE3B9	0x84CD	# <CJK>
+0xE3BA	0x84AA	# <CJK>
+0xE3BB	0x849A	# <CJK>
+0xE3BC	0x84B1	# <CJK>
+0xE3BD	0x84D0	# <CJK>
+0xE3BE	0x849D	# <CJK>
+0xE3BF	0x84A7	# <CJK>
+0xE3C0	0x84BB	# <CJK>
+0xE3C1	0x84A2	# <CJK>
+0xE3C2	0x8494	# <CJK>
+0xE3C3	0x84C7	# <CJK>
+0xE3C4	0x84CC	# <CJK>
+0xE3C5	0x849B	# <CJK>
+0xE3C6	0x84A9	# <CJK>
+0xE3C7	0x84AF	# <CJK>
+0xE3C8	0x84A8	# <CJK>
+0xE3C9	0x84D6	# <CJK>
+0xE3CA	0x8498	# <CJK>
+0xE3CB	0x84B6	# <CJK>
+0xE3CC	0x84CF	# <CJK>
+0xE3CD	0x84A0	# <CJK>
+0xE3CE	0x84D7	# <CJK>
+0xE3CF	0x84D4	# <CJK>
+0xE3D0	0x84D2	# <CJK>
+0xE3D1	0x84DB	# <CJK>
+0xE3D2	0x84B0	# <CJK>
+0xE3D3	0x8491	# <CJK>
+0xE3D4	0x8661	# <CJK>
+0xE3D5	0x8733	# <CJK>
+0xE3D6	0x8723	# <CJK>
+0xE3D7	0x8728	# <CJK>
+0xE3D8	0x876B	# <CJK>
+0xE3D9	0x8740	# <CJK>
+0xE3DA	0x872E	# <CJK>
+0xE3DB	0x871E	# <CJK>
+0xE3DC	0x8721	# <CJK>
+0xE3DD	0x8719	# <CJK>
+0xE3DE	0x871B	# <CJK>
+0xE3DF	0x8743	# <CJK>
+0xE3E0	0x872C	# <CJK>
+0xE3E1	0x8741	# <CJK>
+0xE3E2	0x873E	# <CJK>
+0xE3E3	0x8746	# <CJK>
+0xE3E4	0x8720	# <CJK>
+0xE3E5	0x8732	# <CJK>
+0xE3E6	0x872A	# <CJK>
+0xE3E7	0x872D	# <CJK>
+0xE3E8	0x873C	# <CJK>
+0xE3E9	0x8712	# <CJK>
+0xE3EA	0x873A	# <CJK>
+0xE3EB	0x8731	# <CJK>
+0xE3EC	0x8735	# <CJK>
+0xE3ED	0x8742	# <CJK>
+0xE3EE	0x8726	# <CJK>
+0xE3EF	0x8727	# <CJK>
+0xE3F0	0x8738	# <CJK>
+0xE3F1	0x8724	# <CJK>
+0xE3F2	0x871A	# <CJK>
+0xE3F3	0x8730	# <CJK>
+0xE3F4	0x8711	# <CJK>
+0xE3F5	0x88F7	# <CJK>
+0xE3F6	0x88E7	# <CJK>
+0xE3F7	0x88F1	# <CJK>
+0xE3F8	0x88F2	# <CJK>
+0xE3F9	0x88FA	# <CJK>
+0xE3FA	0x88FE	# <CJK>
+0xE3FB	0x88EE	# <CJK>
+0xE3FC	0x88FC	# <CJK>
+0xE3FD	0x88F6	# <CJK>
+0xE3FE	0x88FB	# <CJK>
+0xE440	0x88F0	# <CJK>
+0xE441	0x88EC	# <CJK>
+0xE442	0x88EB	# <CJK>
+0xE443	0x899D	# <CJK>
+0xE444	0x89A1	# <CJK>
+0xE445	0x899F	# <CJK>
+0xE446	0x899E	# <CJK>
+0xE447	0x89E9	# <CJK>
+0xE448	0x89EB	# <CJK>
+0xE449	0x89E8	# <CJK>
+0xE44A	0x8AAB	# <CJK>
+0xE44B	0x8A99	# <CJK>
+0xE44C	0x8A8B	# <CJK>
+0xE44D	0x8A92	# <CJK>
+0xE44E	0x8A8F	# <CJK>
+0xE44F	0x8A96	# <CJK>
+0xE450	0x8C3D	# <CJK>
+0xE451	0x8C68	# <CJK>
+0xE452	0x8C69	# <CJK>
+0xE453	0x8CD5	# <CJK>
+0xE454	0x8CCF	# <CJK>
+0xE455	0x8CD7	# <CJK>
+0xE456	0x8D96	# <CJK>
+0xE457	0x8E09	# <CJK>
+0xE458	0x8E02	# <CJK>
+0xE459	0x8DFF	# <CJK>
+0xE45A	0x8E0D	# <CJK>
+0xE45B	0x8DFD	# <CJK>
+0xE45C	0x8E0A	# <CJK>
+0xE45D	0x8E03	# <CJK>
+0xE45E	0x8E07	# <CJK>
+0xE45F	0x8E06	# <CJK>
+0xE460	0x8E05	# <CJK>
+0xE461	0x8DFE	# <CJK>
+0xE462	0x8E00	# <CJK>
+0xE463	0x8E04	# <CJK>
+0xE464	0x8F10	# <CJK>
+0xE465	0x8F11	# <CJK>
+0xE466	0x8F0E	# <CJK>
+0xE467	0x8F0D	# <CJK>
+0xE468	0x9123	# <CJK>
+0xE469	0x911C	# <CJK>
+0xE46A	0x9120	# <CJK>
+0xE46B	0x9122	# <CJK>
+0xE46C	0x911F	# <CJK>
+0xE46D	0x911D	# <CJK>
+0xE46E	0x911A	# <CJK>
+0xE46F	0x9124	# <CJK>
+0xE470	0x9121	# <CJK>
+0xE471	0x911B	# <CJK>
+0xE472	0x917A	# <CJK>
+0xE473	0x9172	# <CJK>
+0xE474	0x9179	# <CJK>
+0xE475	0x9173	# <CJK>
+0xE476	0x92A5	# <CJK>
+0xE477	0x92A4	# <CJK>
+0xE478	0x9276	# <CJK>
+0xE479	0x929B	# <CJK>
+0xE47A	0x927A	# <CJK>
+0xE47B	0x92A0	# <CJK>
+0xE47C	0x9294	# <CJK>
+0xE47D	0x92AA	# <CJK>
+0xE47E	0x928D	# <CJK>
+0xE4A1	0x92A6	# <CJK>
+0xE4A2	0x929A	# <CJK>
+0xE4A3	0x92AB	# <CJK>
+0xE4A4	0x9279	# <CJK>
+0xE4A5	0x9297	# <CJK>
+0xE4A6	0x927F	# <CJK>
+0xE4A7	0x92A3	# <CJK>
+0xE4A8	0x92EE	# <CJK>
+0xE4A9	0x928E	# <CJK>
+0xE4AA	0x9282	# <CJK>
+0xE4AB	0x9295	# <CJK>
+0xE4AC	0x92A2	# <CJK>
+0xE4AD	0x927D	# <CJK>
+0xE4AE	0x9288	# <CJK>
+0xE4AF	0x92A1	# <CJK>
+0xE4B0	0x928A	# <CJK>
+0xE4B1	0x9286	# <CJK>
+0xE4B2	0x928C	# <CJK>
+0xE4B3	0x9299	# <CJK>
+0xE4B4	0x92A7	# <CJK>
+0xE4B5	0x927E	# <CJK>
+0xE4B6	0x9287	# <CJK>
+0xE4B7	0x92A9	# <CJK>
+0xE4B8	0x929D	# <CJK>
+0xE4B9	0x928B	# <CJK>
+0xE4BA	0x922D	# <CJK>
+0xE4BB	0x969E	# <CJK>
+0xE4BC	0x96A1	# <CJK>
+0xE4BD	0x96FF	# <CJK>
+0xE4BE	0x9758	# <CJK>
+0xE4BF	0x977D	# <CJK>
+0xE4C0	0x977A	# <CJK>
+0xE4C1	0x977E	# <CJK>
+0xE4C2	0x9783	# <CJK>
+0xE4C3	0x9780	# <CJK>
+0xE4C4	0x9782	# <CJK>
+0xE4C5	0x977B	# <CJK>
+0xE4C6	0x9784	# <CJK>
+0xE4C7	0x9781	# <CJK>
+0xE4C8	0x977F	# <CJK>
+0xE4C9	0x97CE	# <CJK>
+0xE4CA	0x97CD	# <CJK>
+0xE4CB	0x9816	# <CJK>
+0xE4CC	0x98AD	# <CJK>
+0xE4CD	0x98AE	# <CJK>
+0xE4CE	0x9902	# <CJK>
+0xE4CF	0x9900	# <CJK>
+0xE4D0	0x9907	# <CJK>
+0xE4D1	0x999D	# <CJK>
+0xE4D2	0x999C	# <CJK>
+0xE4D3	0x99C3	# <CJK>
+0xE4D4	0x99B9	# <CJK>
+0xE4D5	0x99BB	# <CJK>
+0xE4D6	0x99BA	# <CJK>
+0xE4D7	0x99C2	# <CJK>
+0xE4D8	0x99BD	# <CJK>
+0xE4D9	0x99C7	# <CJK>
+0xE4DA	0x9AB1	# <CJK>
+0xE4DB	0x9AE3	# <CJK>
+0xE4DC	0x9AE7	# <CJK>
+0xE4DD	0x9B3E	# <CJK>
+0xE4DE	0x9B3F	# <CJK>
+0xE4DF	0x9B60	# <CJK>
+0xE4E0	0x9B61	# <CJK>
+0xE4E1	0x9B5F	# <CJK>
+0xE4E2	0x9CF1	# <CJK>
+0xE4E3	0x9CF2	# <CJK>
+0xE4E4	0x9CF5	# <CJK>
+0xE4E5	0x9EA7	# <CJK>
+0xE4E6	0x50FF	# <CJK>
+0xE4E7	0x5103	# <CJK>
+0xE4E8	0x5130	# <CJK>
+0xE4E9	0x50F8	# <CJK>
+0xE4EA	0x5106	# <CJK>
+0xE4EB	0x5107	# <CJK>
+0xE4EC	0x50F6	# <CJK>
+0xE4ED	0x50FE	# <CJK>
+0xE4EE	0x510B	# <CJK>
+0xE4EF	0x510C	# <CJK>
+0xE4F0	0x50FD	# <CJK>
+0xE4F1	0x510A	# <CJK>
+0xE4F2	0x528B	# <CJK>
+0xE4F3	0x528C	# <CJK>
+0xE4F4	0x52F1	# <CJK>
+0xE4F5	0x52EF	# <CJK>
+0xE4F6	0x5648	# <CJK>
+0xE4F7	0x5642	# <CJK>
+0xE4F8	0x564C	# <CJK>
+0xE4F9	0x5635	# <CJK>
+0xE4FA	0x5641	# <CJK>
+0xE4FB	0x564A	# <CJK>
+0xE4FC	0x5649	# <CJK>
+0xE4FD	0x5646	# <CJK>
+0xE4FE	0x5658	# <CJK>
+0xE540	0x565A	# <CJK>
+0xE541	0x5640	# <CJK>
+0xE542	0x5633	# <CJK>
+0xE543	0x563D	# <CJK>
+0xE544	0x562C	# <CJK>
+0xE545	0x563E	# <CJK>
+0xE546	0x5638	# <CJK>
+0xE547	0x562A	# <CJK>
+0xE548	0x563A	# <CJK>
+0xE549	0x571A	# <CJK>
+0xE54A	0x58AB	# <CJK>
+0xE54B	0x589D	# <CJK>
+0xE54C	0x58B1	# <CJK>
+0xE54D	0x58A0	# <CJK>
+0xE54E	0x58A3	# <CJK>
+0xE54F	0x58AF	# <CJK>
+0xE550	0x58AC	# <CJK>
+0xE551	0x58A5	# <CJK>
+0xE552	0x58A1	# <CJK>
+0xE553	0x58FF	# <CJK>
+0xE554	0x5AFF	# <CJK>
+0xE555	0x5AF4	# <CJK>
+0xE556	0x5AFD	# <CJK>
+0xE557	0x5AF7	# <CJK>
+0xE558	0x5AF6	# <CJK>
+0xE559	0x5B03	# <CJK>
+0xE55A	0x5AF8	# <CJK>
+0xE55B	0x5B02	# <CJK>
+0xE55C	0x5AF9	# <CJK>
+0xE55D	0x5B01	# <CJK>
+0xE55E	0x5B07	# <CJK>
+0xE55F	0x5B05	# <CJK>
+0xE560	0x5B0F	# <CJK>
+0xE561	0x5C67	# <CJK>
+0xE562	0x5D99	# <CJK>
+0xE563	0x5D97	# <CJK>
+0xE564	0x5D9F	# <CJK>
+0xE565	0x5D92	# <CJK>
+0xE566	0x5DA2	# <CJK>
+0xE567	0x5D93	# <CJK>
+0xE568	0x5D95	# <CJK>
+0xE569	0x5DA0	# <CJK>
+0xE56A	0x5D9C	# <CJK>
+0xE56B	0x5DA1	# <CJK>
+0xE56C	0x5D9A	# <CJK>
+0xE56D	0x5D9E	# <CJK>
+0xE56E	0x5E69	# <CJK>
+0xE56F	0x5E5D	# <CJK>
+0xE570	0x5E60	# <CJK>
+0xE571	0x5E5C	# <CJK>
+0xE572	0x7DF3	# <CJK>
+0xE573	0x5EDB	# <CJK>
+0xE574	0x5EDE	# <CJK>
+0xE575	0x5EE1	# <CJK>
+0xE576	0x5F49	# <CJK>
+0xE577	0x5FB2	# <CJK>
+0xE578	0x618B	# <CJK>
+0xE579	0x6183	# <CJK>
+0xE57A	0x6179	# <CJK>
+0xE57B	0x61B1	# <CJK>
+0xE57C	0x61B0	# <CJK>
+0xE57D	0x61A2	# <CJK>
+0xE57E	0x6189	# <CJK>
+0xE5A1	0x619B	# <CJK>
+0xE5A2	0x6193	# <CJK>
+0xE5A3	0x61AF	# <CJK>
+0xE5A4	0x61AD	# <CJK>
+0xE5A5	0x619F	# <CJK>
+0xE5A6	0x6192	# <CJK>
+0xE5A7	0x61AA	# <CJK>
+0xE5A8	0x61A1	# <CJK>
+0xE5A9	0x618D	# <CJK>
+0xE5AA	0x6166	# <CJK>
+0xE5AB	0x61B3	# <CJK>
+0xE5AC	0x622D	# <CJK>
+0xE5AD	0x646E	# <CJK>
+0xE5AE	0x6470	# <CJK>
+0xE5AF	0x6496	# <CJK>
+0xE5B0	0x64A0	# <CJK>
+0xE5B1	0x6485	# <CJK>
+0xE5B2	0x6497	# <CJK>
+0xE5B3	0x649C	# <CJK>
+0xE5B4	0x648F	# <CJK>
+0xE5B5	0x648B	# <CJK>
+0xE5B6	0x648A	# <CJK>
+0xE5B7	0x648C	# <CJK>
+0xE5B8	0x64A3	# <CJK>
+0xE5B9	0x649F	# <CJK>
+0xE5BA	0x6468	# <CJK>
+0xE5BB	0x64B1	# <CJK>
+0xE5BC	0x6498	# <CJK>
+0xE5BD	0x6576	# <CJK>
+0xE5BE	0x657A	# <CJK>
+0xE5BF	0x6579	# <CJK>
+0xE5C0	0x657B	# <CJK>
+0xE5C1	0x65B2	# <CJK>
+0xE5C2	0x65B3	# <CJK>
+0xE5C3	0x66B5	# <CJK>
+0xE5C4	0x66B0	# <CJK>
+0xE5C5	0x66A9	# <CJK>
+0xE5C6	0x66B2	# <CJK>
+0xE5C7	0x66B7	# <CJK>
+0xE5C8	0x66AA	# <CJK>
+0xE5C9	0x66AF	# <CJK>
+0xE5CA	0x6A00	# <CJK>
+0xE5CB	0x6A06	# <CJK>
+0xE5CC	0x6A17	# <CJK>
+0xE5CD	0x69E5	# <CJK>
+0xE5CE	0x69F8	# <CJK>
+0xE5CF	0x6A15	# <CJK>
+0xE5D0	0x69F1	# <CJK>
+0xE5D1	0x69E4	# <CJK>
+0xE5D2	0x6A20	# <CJK>
+0xE5D3	0x69FF	# <CJK>
+0xE5D4	0x69EC	# <CJK>
+0xE5D5	0x69E2	# <CJK>
+0xE5D6	0x6A1B	# <CJK>
+0xE5D7	0x6A1D	# <CJK>
+0xE5D8	0x69FE	# <CJK>
+0xE5D9	0x6A27	# <CJK>
+0xE5DA	0x69F2	# <CJK>
+0xE5DB	0x69EE	# <CJK>
+0xE5DC	0x6A14	# <CJK>
+0xE5DD	0x69F7	# <CJK>
+0xE5DE	0x69E7	# <CJK>
+0xE5DF	0x6A40	# <CJK>
+0xE5E0	0x6A08	# <CJK>
+0xE5E1	0x69E6	# <CJK>
+0xE5E2	0x69FB	# <CJK>
+0xE5E3	0x6A0D	# <CJK>
+0xE5E4	0x69FC	# <CJK>
+0xE5E5	0x69EB	# <CJK>
+0xE5E6	0x6A09	# <CJK>
+0xE5E7	0x6A04	# <CJK>
+0xE5E8	0x6A18	# <CJK>
+0xE5E9	0x6A25	# <CJK>
+0xE5EA	0x6A0F	# <CJK>
+0xE5EB	0x69F6	# <CJK>
+0xE5EC	0x6A26	# <CJK>
+0xE5ED	0x6A07	# <CJK>
+0xE5EE	0x69F4	# <CJK>
+0xE5EF	0x6A16	# <CJK>
+0xE5F0	0x6B51	# <CJK>
+0xE5F1	0x6BA5	# <CJK>
+0xE5F2	0x6BA3	# <CJK>
+0xE5F3	0x6BA2	# <CJK>
+0xE5F4	0x6BA6	# <CJK>
+0xE5F5	0x6C01	# <CJK>
+0xE5F6	0x6C00	# <CJK>
+0xE5F7	0x6BFF	# <CJK>
+0xE5F8	0x6C02	# <CJK>
+0xE5F9	0x6F41	# <CJK>
+0xE5FA	0x6F26	# <CJK>
+0xE5FB	0x6F7E	# <CJK>
+0xE5FC	0x6F87	# <CJK>
+0xE5FD	0x6FC6	# <CJK>
+0xE5FE	0x6F92	# <CJK>
+0xE640	0x6F8D	# <CJK>
+0xE641	0x6F89	# <CJK>
+0xE642	0x6F8C	# <CJK>
+0xE643	0x6F62	# <CJK>
+0xE644	0x6F4F	# <CJK>
+0xE645	0x6F85	# <CJK>
+0xE646	0x6F5A	# <CJK>
+0xE647	0x6F96	# <CJK>
+0xE648	0x6F76	# <CJK>
+0xE649	0x6F6C	# <CJK>
+0xE64A	0x6F82	# <CJK>
+0xE64B	0x6F55	# <CJK>
+0xE64C	0x6F72	# <CJK>
+0xE64D	0x6F52	# <CJK>
+0xE64E	0x6F50	# <CJK>
+0xE64F	0x6F57	# <CJK>
+0xE650	0x6F94	# <CJK>
+0xE651	0x6F93	# <CJK>
+0xE652	0x6F5D	# <CJK>
+0xE653	0x6F00	# <CJK>
+0xE654	0x6F61	# <CJK>
+0xE655	0x6F6B	# <CJK>
+0xE656	0x6F7D	# <CJK>
+0xE657	0x6F67	# <CJK>
+0xE658	0x6F90	# <CJK>
+0xE659	0x6F53	# <CJK>
+0xE65A	0x6F8B	# <CJK>
+0xE65B	0x6F69	# <CJK>
+0xE65C	0x6F7F	# <CJK>
+0xE65D	0x6F95	# <CJK>
+0xE65E	0x6F63	# <CJK>
+0xE65F	0x6F77	# <CJK>
+0xE660	0x6F6A	# <CJK>
+0xE661	0x6F7B	# <CJK>
+0xE662	0x71B2	# <CJK>
+0xE663	0x71AF	# <CJK>
+0xE664	0x719B	# <CJK>
+0xE665	0x71B0	# <CJK>
+0xE666	0x71A0	# <CJK>
+0xE667	0x719A	# <CJK>
+0xE668	0x71A9	# <CJK>
+0xE669	0x71B5	# <CJK>
+0xE66A	0x719D	# <CJK>
+0xE66B	0x71A5	# <CJK>
+0xE66C	0x719E	# <CJK>
+0xE66D	0x71A4	# <CJK>
+0xE66E	0x71A1	# <CJK>
+0xE66F	0x71AA	# <CJK>
+0xE670	0x719C	# <CJK>
+0xE671	0x71A7	# <CJK>
+0xE672	0x71B3	# <CJK>
+0xE673	0x7298	# <CJK>
+0xE674	0x729A	# <CJK>
+0xE675	0x7358	# <CJK>
+0xE676	0x7352	# <CJK>
+0xE677	0x735E	# <CJK>
+0xE678	0x735F	# <CJK>
+0xE679	0x7360	# <CJK>
+0xE67A	0x735D	# <CJK>
+0xE67B	0x735B	# <CJK>
+0xE67C	0x7361	# <CJK>
+0xE67D	0x735A	# <CJK>
+0xE67E	0x7359	# <CJK>
+0xE6A1	0x7362	# <CJK>
+0xE6A2	0x7487	# <CJK>
+0xE6A3	0x7489	# <CJK>
+0xE6A4	0x748A	# <CJK>
+0xE6A5	0x7486	# <CJK>
+0xE6A6	0x7481	# <CJK>
+0xE6A7	0x747D	# <CJK>
+0xE6A8	0x7485	# <CJK>
+0xE6A9	0x7488	# <CJK>
+0xE6AA	0x747C	# <CJK>
+0xE6AB	0x7479	# <CJK>
+0xE6AC	0x7508	# <CJK>
+0xE6AD	0x7507	# <CJK>
+0xE6AE	0x757E	# <CJK>
+0xE6AF	0x7625	# <CJK>
+0xE6B0	0x761E	# <CJK>
+0xE6B1	0x7619	# <CJK>
+0xE6B2	0x761D	# <CJK>
+0xE6B3	0x761C	# <CJK>
+0xE6B4	0x7623	# <CJK>
+0xE6B5	0x761A	# <CJK>
+0xE6B6	0x7628	# <CJK>
+0xE6B7	0x761B	# <CJK>
+0xE6B8	0x769C	# <CJK>
+0xE6B9	0x769D	# <CJK>
+0xE6BA	0x769E	# <CJK>
+0xE6BB	0x769B	# <CJK>
+0xE6BC	0x778D	# <CJK>
+0xE6BD	0x778F	# <CJK>
+0xE6BE	0x7789	# <CJK>
+0xE6BF	0x7788	# <CJK>
+0xE6C0	0x78CD	# <CJK>
+0xE6C1	0x78BB	# <CJK>
+0xE6C2	0x78CF	# <CJK>
+0xE6C3	0x78CC	# <CJK>
+0xE6C4	0x78D1	# <CJK>
+0xE6C5	0x78CE	# <CJK>
+0xE6C6	0x78D4	# <CJK>
+0xE6C7	0x78C8	# <CJK>
+0xE6C8	0x78C3	# <CJK>
+0xE6C9	0x78C4	# <CJK>
+0xE6CA	0x78C9	# <CJK>
+0xE6CB	0x799A	# <CJK>
+0xE6CC	0x79A1	# <CJK>
+0xE6CD	0x79A0	# <CJK>
+0xE6CE	0x799C	# <CJK>
+0xE6CF	0x79A2	# <CJK>
+0xE6D0	0x799B	# <CJK>
+0xE6D1	0x6B76	# <CJK>
+0xE6D2	0x7A39	# <CJK>
+0xE6D3	0x7AB2	# <CJK>
+0xE6D4	0x7AB4	# <CJK>
+0xE6D5	0x7AB3	# <CJK>
+0xE6D6	0x7BB7	# <CJK>
+0xE6D7	0x7BCB	# <CJK>
+0xE6D8	0x7BBE	# <CJK>
+0xE6D9	0x7BAC	# <CJK>
+0xE6DA	0x7BCE	# <CJK>
+0xE6DB	0x7BAF	# <CJK>
+0xE6DC	0x7BB9	# <CJK>
+0xE6DD	0x7BCA	# <CJK>
+0xE6DE	0x7BB5	# <CJK>
+0xE6DF	0x7CC5	# <CJK>
+0xE6E0	0x7CC8	# <CJK>
+0xE6E1	0x7CCC	# <CJK>
+0xE6E2	0x7CCB	# <CJK>
+0xE6E3	0x7DF7	# <CJK>
+0xE6E4	0x7DDB	# <CJK>
+0xE6E5	0x7DEA	# <CJK>
+0xE6E6	0x7DE7	# <CJK>
+0xE6E7	0x7DD7	# <CJK>
+0xE6E8	0x7DE1	# <CJK>
+0xE6E9	0x7E03	# <CJK>
+0xE6EA	0x7DFA	# <CJK>
+0xE6EB	0x7DE6	# <CJK>
+0xE6EC	0x7DF6	# <CJK>
+0xE6ED	0x7DF1	# <CJK>
+0xE6EE	0x7DF0	# <CJK>
+0xE6EF	0x7DEE	# <CJK>
+0xE6F0	0x7DDF	# <CJK>
+0xE6F1	0x7F76	# <CJK>
+0xE6F2	0x7FAC	# <CJK>
+0xE6F3	0x7FB0	# <CJK>
+0xE6F4	0x7FAD	# <CJK>
+0xE6F5	0x7FED	# <CJK>
+0xE6F6	0x7FEB	# <CJK>
+0xE6F7	0x7FEA	# <CJK>
+0xE6F8	0x7FEC	# <CJK>
+0xE6F9	0x7FE6	# <CJK>
+0xE6FA	0x7FE8	# <CJK>
+0xE6FB	0x8064	# <CJK>
+0xE6FC	0x8067	# <CJK>
+0xE6FD	0x81A3	# <CJK>
+0xE6FE	0x819F	# <CJK>
+0xE740	0x819E	# <CJK>
+0xE741	0x8195	# <CJK>
+0xE742	0x81A2	# <CJK>
+0xE743	0x8199	# <CJK>
+0xE744	0x8197	# <CJK>
+0xE745	0x8216	# <CJK>
+0xE746	0x824F	# <CJK>
+0xE747	0x8253	# <CJK>
+0xE748	0x8252	# <CJK>
+0xE749	0x8250	# <CJK>
+0xE74A	0x824E	# <CJK>
+0xE74B	0x8251	# <CJK>
+0xE74C	0x8524	# <CJK>
+0xE74D	0x853B	# <CJK>
+0xE74E	0x850F	# <CJK>
+0xE74F	0x8500	# <CJK>
+0xE750	0x8529	# <CJK>
+0xE751	0x850E	# <CJK>
+0xE752	0x8509	# <CJK>
+0xE753	0x850D	# <CJK>
+0xE754	0x851F	# <CJK>
+0xE755	0x850A	# <CJK>
+0xE756	0x8527	# <CJK>
+0xE757	0x851C	# <CJK>
+0xE758	0x84FB	# <CJK>
+0xE759	0x852B	# <CJK>
+0xE75A	0x84FA	# <CJK>
+0xE75B	0x8508	# <CJK>
+0xE75C	0x850C	# <CJK>
+0xE75D	0x84F4	# <CJK>
+0xE75E	0x852A	# <CJK>
+0xE75F	0x84F2	# <CJK>
+0xE760	0x8515	# <CJK>
+0xE761	0x84F7	# <CJK>
+0xE762	0x84EB	# <CJK>
+0xE763	0x84F3	# <CJK>
+0xE764	0x84FC	# <CJK>
+0xE765	0x8512	# <CJK>
+0xE766	0x84EA	# <CJK>
+0xE767	0x84E9	# <CJK>
+0xE768	0x8516	# <CJK>
+0xE769	0x84FE	# <CJK>
+0xE76A	0x8528	# <CJK>
+0xE76B	0x851D	# <CJK>
+0xE76C	0x852E	# <CJK>
+0xE76D	0x8502	# <CJK>
+0xE76E	0x84FD	# <CJK>
+0xE76F	0x851E	# <CJK>
+0xE770	0x84F6	# <CJK>
+0xE771	0x8531	# <CJK>
+0xE772	0x8526	# <CJK>
+0xE773	0x84E7	# <CJK>
+0xE774	0x84E8	# <CJK>
+0xE775	0x84F0	# <CJK>
+0xE776	0x84EF	# <CJK>
+0xE777	0x84F9	# <CJK>
+0xE778	0x8518	# <CJK>
+0xE779	0x8520	# <CJK>
+0xE77A	0x8530	# <CJK>
+0xE77B	0x850B	# <CJK>
+0xE77C	0x8519	# <CJK>
+0xE77D	0x852F	# <CJK>
+0xE77E	0x8662	# <CJK>
+0xE7A1	0x8756	# <CJK>
+0xE7A2	0x8763	# <CJK>
+0xE7A3	0x8764	# <CJK>
+0xE7A4	0x8777	# <CJK>
+0xE7A5	0x87E1	# <CJK>
+0xE7A6	0x8773	# <CJK>
+0xE7A7	0x8758	# <CJK>
+0xE7A8	0x8754	# <CJK>
+0xE7A9	0x875B	# <CJK>
+0xE7AA	0x8752	# <CJK>
+0xE7AB	0x8761	# <CJK>
+0xE7AC	0x875A	# <CJK>
+0xE7AD	0x8751	# <CJK>
+0xE7AE	0x875E	# <CJK>
+0xE7AF	0x876D	# <CJK>
+0xE7B0	0x876A	# <CJK>
+0xE7B1	0x8750	# <CJK>
+0xE7B2	0x874E	# <CJK>
+0xE7B3	0x875F	# <CJK>
+0xE7B4	0x875D	# <CJK>
+0xE7B5	0x876F	# <CJK>
+0xE7B6	0x876C	# <CJK>
+0xE7B7	0x877A	# <CJK>
+0xE7B8	0x876E	# <CJK>
+0xE7B9	0x875C	# <CJK>
+0xE7BA	0x8765	# <CJK>
+0xE7BB	0x874F	# <CJK>
+0xE7BC	0x877B	# <CJK>
+0xE7BD	0x8775	# <CJK>
+0xE7BE	0x8762	# <CJK>
+0xE7BF	0x8767	# <CJK>
+0xE7C0	0x8769	# <CJK>
+0xE7C1	0x885A	# <CJK>
+0xE7C2	0x8905	# <CJK>
+0xE7C3	0x890C	# <CJK>
+0xE7C4	0x8914	# <CJK>
+0xE7C5	0x890B	# <CJK>
+0xE7C6	0x8917	# <CJK>
+0xE7C7	0x8918	# <CJK>
+0xE7C8	0x8919	# <CJK>
+0xE7C9	0x8906	# <CJK>
+0xE7CA	0x8916	# <CJK>
+0xE7CB	0x8911	# <CJK>
+0xE7CC	0x890E	# <CJK>
+0xE7CD	0x8909	# <CJK>
+0xE7CE	0x89A2	# <CJK>
+0xE7CF	0x89A4	# <CJK>
+0xE7D0	0x89A3	# <CJK>
+0xE7D1	0x89ED	# <CJK>
+0xE7D2	0x89F0	# <CJK>
+0xE7D3	0x89EC	# <CJK>
+0xE7D4	0x8ACF	# <CJK>
+0xE7D5	0x8AC6	# <CJK>
+0xE7D6	0x8AB8	# <CJK>
+0xE7D7	0x8AD3	# <CJK>
+0xE7D8	0x8AD1	# <CJK>
+0xE7D9	0x8AD4	# <CJK>
+0xE7DA	0x8AD5	# <CJK>
+0xE7DB	0x8ABB	# <CJK>
+0xE7DC	0x8AD7	# <CJK>
+0xE7DD	0x8ABE	# <CJK>
+0xE7DE	0x8AC0	# <CJK>
+0xE7DF	0x8AC5	# <CJK>
+0xE7E0	0x8AD8	# <CJK>
+0xE7E1	0x8AC3	# <CJK>
+0xE7E2	0x8ABA	# <CJK>
+0xE7E3	0x8ABD	# <CJK>
+0xE7E4	0x8AD9	# <CJK>
+0xE7E5	0x8C3E	# <CJK>
+0xE7E6	0x8C4D	# <CJK>
+0xE7E7	0x8C8F	# <CJK>
+0xE7E8	0x8CE5	# <CJK>
+0xE7E9	0x8CDF	# <CJK>
+0xE7EA	0x8CD9	# <CJK>
+0xE7EB	0x8CE8	# <CJK>
+0xE7EC	0x8CDA	# <CJK>
+0xE7ED	0x8CDD	# <CJK>
+0xE7EE	0x8CE7	# <CJK>
+0xE7EF	0x8DA0	# <CJK>
+0xE7F0	0x8D9C	# <CJK>
+0xE7F1	0x8DA1	# <CJK>
+0xE7F2	0x8D9B	# <CJK>
+0xE7F3	0x8E20	# <CJK>
+0xE7F4	0x8E23	# <CJK>
+0xE7F5	0x8E25	# <CJK>
+0xE7F6	0x8E24	# <CJK>
+0xE7F7	0x8E2E	# <CJK>
+0xE7F8	0x8E15	# <CJK>
+0xE7F9	0x8E1B	# <CJK>
+0xE7FA	0x8E16	# <CJK>
+0xE7FB	0x8E11	# <CJK>
+0xE7FC	0x8E19	# <CJK>
+0xE7FD	0x8E26	# <CJK>
+0xE7FE	0x8E27	# <CJK>
+0xE840	0x8E14	# <CJK>
+0xE841	0x8E12	# <CJK>
+0xE842	0x8E18	# <CJK>
+0xE843	0x8E13	# <CJK>
+0xE844	0x8E1C	# <CJK>
+0xE845	0x8E17	# <CJK>
+0xE846	0x8E1A	# <CJK>
+0xE847	0x8F2C	# <CJK>
+0xE848	0x8F24	# <CJK>
+0xE849	0x8F18	# <CJK>
+0xE84A	0x8F1A	# <CJK>
+0xE84B	0x8F20	# <CJK>
+0xE84C	0x8F23	# <CJK>
+0xE84D	0x8F16	# <CJK>
+0xE84E	0x8F17	# <CJK>
+0xE84F	0x9073	# <CJK>
+0xE850	0x9070	# <CJK>
+0xE851	0x906F	# <CJK>
+0xE852	0x9067	# <CJK>
+0xE853	0x906B	# <CJK>
+0xE854	0x912F	# <CJK>
+0xE855	0x912B	# <CJK>
+0xE856	0x9129	# <CJK>
+0xE857	0x912A	# <CJK>
+0xE858	0x9132	# <CJK>
+0xE859	0x9126	# <CJK>
+0xE85A	0x912E	# <CJK>
+0xE85B	0x9185	# <CJK>
+0xE85C	0x9186	# <CJK>
+0xE85D	0x918A	# <CJK>
+0xE85E	0x9181	# <CJK>
+0xE85F	0x9182	# <CJK>
+0xE860	0x9184	# <CJK>
+0xE861	0x9180	# <CJK>
+0xE862	0x92D0	# <CJK>
+0xE863	0x92C3	# <CJK>
+0xE864	0x92C4	# <CJK>
+0xE865	0x92C0	# <CJK>
+0xE866	0x92D9	# <CJK>
+0xE867	0x92B6	# <CJK>
+0xE868	0x92CF	# <CJK>
+0xE869	0x92F1	# <CJK>
+0xE86A	0x92DF	# <CJK>
+0xE86B	0x92D8	# <CJK>
+0xE86C	0x92E9	# <CJK>
+0xE86D	0x92D7	# <CJK>
+0xE86E	0x92DD	# <CJK>
+0xE86F	0x92CC	# <CJK>
+0xE870	0x92EF	# <CJK>
+0xE871	0x92C2	# <CJK>
+0xE872	0x92E8	# <CJK>
+0xE873	0x92CA	# <CJK>
+0xE874	0x92C8	# <CJK>
+0xE875	0x92CE	# <CJK>
+0xE876	0x92E6	# <CJK>
+0xE877	0x92CD	# <CJK>
+0xE878	0x92D5	# <CJK>
+0xE879	0x92C9	# <CJK>
+0xE87A	0x92E0	# <CJK>
+0xE87B	0x92DE	# <CJK>
+0xE87C	0x92E7	# <CJK>
+0xE87D	0x92D1	# <CJK>
+0xE87E	0x92D3	# <CJK>
+0xE8A1	0x92B5	# <CJK>
+0xE8A2	0x92E1	# <CJK>
+0xE8A3	0x92C6	# <CJK>
+0xE8A4	0x92B4	# <CJK>
+0xE8A5	0x957C	# <CJK>
+0xE8A6	0x95AC	# <CJK>
+0xE8A7	0x95AB	# <CJK>
+0xE8A8	0x95AE	# <CJK>
+0xE8A9	0x95B0	# <CJK>
+0xE8AA	0x96A4	# <CJK>
+0xE8AB	0x96A2	# <CJK>
+0xE8AC	0x96D3	# <CJK>
+0xE8AD	0x9705	# <CJK>
+0xE8AE	0x9708	# <CJK>
+0xE8AF	0x9702	# <CJK>
+0xE8B0	0x975A	# <CJK>
+0xE8B1	0x978A	# <CJK>
+0xE8B2	0x978E	# <CJK>
+0xE8B3	0x9788	# <CJK>
+0xE8B4	0x97D0	# <CJK>
+0xE8B5	0x97CF	# <CJK>
+0xE8B6	0x981E	# <CJK>
+0xE8B7	0x981D	# <CJK>
+0xE8B8	0x9826	# <CJK>
+0xE8B9	0x9829	# <CJK>
+0xE8BA	0x9828	# <CJK>
+0xE8BB	0x9820	# <CJK>
+0xE8BC	0x981B	# <CJK>
+0xE8BD	0x9827	# <CJK>
+0xE8BE	0x98B2	# <CJK>
+0xE8BF	0x9908	# <CJK>
+0xE8C0	0x98FA	# <CJK>
+0xE8C1	0x9911	# <CJK>
+0xE8C2	0x9914	# <CJK>
+0xE8C3	0x9916	# <CJK>
+0xE8C4	0x9917	# <CJK>
+0xE8C5	0x9915	# <CJK>
+0xE8C6	0x99DC	# <CJK>
+0xE8C7	0x99CD	# <CJK>
+0xE8C8	0x99CF	# <CJK>
+0xE8C9	0x99D3	# <CJK>
+0xE8CA	0x99D4	# <CJK>
+0xE8CB	0x99CE	# <CJK>
+0xE8CC	0x99C9	# <CJK>
+0xE8CD	0x99D6	# <CJK>
+0xE8CE	0x99D8	# <CJK>
+0xE8CF	0x99CB	# <CJK>
+0xE8D0	0x99D7	# <CJK>
+0xE8D1	0x99CC	# <CJK>
+0xE8D2	0x9AB3	# <CJK>
+0xE8D3	0x9AEC	# <CJK>
+0xE8D4	0x9AEB	# <CJK>
+0xE8D5	0x9AF3	# <CJK>
+0xE8D6	0x9AF2	# <CJK>
+0xE8D7	0x9AF1	# <CJK>
+0xE8D8	0x9B46	# <CJK>
+0xE8D9	0x9B43	# <CJK>
+0xE8DA	0x9B67	# <CJK>
+0xE8DB	0x9B74	# <CJK>
+0xE8DC	0x9B71	# <CJK>
+0xE8DD	0x9B66	# <CJK>
+0xE8DE	0x9B76	# <CJK>
+0xE8DF	0x9B75	# <CJK>
+0xE8E0	0x9B70	# <CJK>
+0xE8E1	0x9B68	# <CJK>
+0xE8E2	0x9B64	# <CJK>
+0xE8E3	0x9B6C	# <CJK>
+0xE8E4	0x9CFC	# <CJK>
+0xE8E5	0x9CFA	# <CJK>
+0xE8E6	0x9CFD	# <CJK>
+0xE8E7	0x9CFF	# <CJK>
+0xE8E8	0x9CF7	# <CJK>
+0xE8E9	0x9D07	# <CJK>
+0xE8EA	0x9D00	# <CJK>
+0xE8EB	0x9CF9	# <CJK>
+0xE8EC	0x9CFB	# <CJK>
+0xE8ED	0x9D08	# <CJK>
+0xE8EE	0x9D05	# <CJK>
+0xE8EF	0x9D04	# <CJK>
+0xE8F0	0x9E83	# <CJK>
+0xE8F1	0x9ED3	# <CJK>
+0xE8F2	0x9F0F	# <CJK>
+0xE8F3	0x9F10	# <CJK>
+0xE8F4	0x511C	# <CJK>
+0xE8F5	0x5113	# <CJK>
+0xE8F6	0x5117	# <CJK>
+0xE8F7	0x511A	# <CJK>
+0xE8F8	0x5111	# <CJK>
+0xE8F9	0x51DE	# <CJK>
+0xE8FA	0x5334	# <CJK>
+0xE8FB	0x53E1	# <CJK>
+0xE8FC	0x5670	# <CJK>
+0xE8FD	0x5660	# <CJK>
+0xE8FE	0x566E	# <CJK>
+0xE940	0x5673	# <CJK>
+0xE941	0x5666	# <CJK>
+0xE942	0x5663	# <CJK>
+0xE943	0x566D	# <CJK>
+0xE944	0x5672	# <CJK>
+0xE945	0x565E	# <CJK>
+0xE946	0x5677	# <CJK>
+0xE947	0x571C	# <CJK>
+0xE948	0x571B	# <CJK>
+0xE949	0x58C8	# <CJK>
+0xE94A	0x58BD	# <CJK>
+0xE94B	0x58C9	# <CJK>
+0xE94C	0x58BF	# <CJK>
+0xE94D	0x58BA	# <CJK>
+0xE94E	0x58C2	# <CJK>
+0xE94F	0x58BC	# <CJK>
+0xE950	0x58C6	# <CJK>
+0xE951	0x5B17	# <CJK>
+0xE952	0x5B19	# <CJK>
+0xE953	0x5B1B	# <CJK>
+0xE954	0x5B21	# <CJK>
+0xE955	0x5B14	# <CJK>
+0xE956	0x5B13	# <CJK>
+0xE957	0x5B10	# <CJK>
+0xE958	0x5B16	# <CJK>
+0xE959	0x5B28	# <CJK>
+0xE95A	0x5B1A	# <CJK>
+0xE95B	0x5B20	# <CJK>
+0xE95C	0x5B1E	# <CJK>
+0xE95D	0x5BEF	# <CJK>
+0xE95E	0x5DAC	# <CJK>
+0xE95F	0x5DB1	# <CJK>
+0xE960	0x5DA9	# <CJK>
+0xE961	0x5DA7	# <CJK>
+0xE962	0x5DB5	# <CJK>
+0xE963	0x5DB0	# <CJK>
+0xE964	0x5DAE	# <CJK>
+0xE965	0x5DAA	# <CJK>
+0xE966	0x5DA8	# <CJK>
+0xE967	0x5DB2	# <CJK>
+0xE968	0x5DAD	# <CJK>
+0xE969	0x5DAF	# <CJK>
+0xE96A	0x5DB4	# <CJK>
+0xE96B	0x5E67	# <CJK>
+0xE96C	0x5E68	# <CJK>
+0xE96D	0x5E66	# <CJK>
+0xE96E	0x5E6F	# <CJK>
+0xE96F	0x5EE9	# <CJK>
+0xE970	0x5EE7	# <CJK>
+0xE971	0x5EE6	# <CJK>
+0xE972	0x5EE8	# <CJK>
+0xE973	0x5EE5	# <CJK>
+0xE974	0x5F4B	# <CJK>
+0xE975	0x5FBC	# <CJK>
+0xE976	0x619D	# <CJK>
+0xE977	0x61A8	# <CJK>
+0xE978	0x6196	# <CJK>
+0xE979	0x61C5	# <CJK>
+0xE97A	0x61B4	# <CJK>
+0xE97B	0x61C6	# <CJK>
+0xE97C	0x61C1	# <CJK>
+0xE97D	0x61CC	# <CJK>
+0xE97E	0x61BA	# <CJK>
+0xE9A1	0x61BF	# <CJK>
+0xE9A2	0x61B8	# <CJK>
+0xE9A3	0x618C	# <CJK>
+0xE9A4	0x64D7	# <CJK>
+0xE9A5	0x64D6	# <CJK>
+0xE9A6	0x64D0	# <CJK>
+0xE9A7	0x64CF	# <CJK>
+0xE9A8	0x64C9	# <CJK>
+0xE9A9	0x64BD	# <CJK>
+0xE9AA	0x6489	# <CJK>
+0xE9AB	0x64C3	# <CJK>
+0xE9AC	0x64DB	# <CJK>
+0xE9AD	0x64F3	# <CJK>
+0xE9AE	0x64D9	# <CJK>
+0xE9AF	0x6533	# <CJK>
+0xE9B0	0x657F	# <CJK>
+0xE9B1	0x657C	# <CJK>
+0xE9B2	0x65A2	# <CJK>
+0xE9B3	0x66C8	# <CJK>
+0xE9B4	0x66BE	# <CJK>
+0xE9B5	0x66C0	# <CJK>
+0xE9B6	0x66CA	# <CJK>
+0xE9B7	0x66CB	# <CJK>
+0xE9B8	0x66CF	# <CJK>
+0xE9B9	0x66BD	# <CJK>
+0xE9BA	0x66BB	# <CJK>
+0xE9BB	0x66BA	# <CJK>
+0xE9BC	0x66CC	# <CJK>
+0xE9BD	0x6723	# <CJK>
+0xE9BE	0x6A34	# <CJK>
+0xE9BF	0x6A66	# <CJK>
+0xE9C0	0x6A49	# <CJK>
+0xE9C1	0x6A67	# <CJK>
+0xE9C2	0x6A32	# <CJK>
+0xE9C3	0x6A68	# <CJK>
+0xE9C4	0x6A3E	# <CJK>
+0xE9C5	0x6A5D	# <CJK>
+0xE9C6	0x6A6D	# <CJK>
+0xE9C7	0x6A76	# <CJK>
+0xE9C8	0x6A5B	# <CJK>
+0xE9C9	0x6A51	# <CJK>
+0xE9CA	0x6A28	# <CJK>
+0xE9CB	0x6A5A	# <CJK>
+0xE9CC	0x6A3B	# <CJK>
+0xE9CD	0x6A3F	# <CJK>
+0xE9CE	0x6A41	# <CJK>
+0xE9CF	0x6A6A	# <CJK>
+0xE9D0	0x6A64	# <CJK>
+0xE9D1	0x6A50	# <CJK>
+0xE9D2	0x6A4F	# <CJK>
+0xE9D3	0x6A54	# <CJK>
+0xE9D4	0x6A6F	# <CJK>
+0xE9D5	0x6A69	# <CJK>
+0xE9D6	0x6A60	# <CJK>
+0xE9D7	0x6A3C	# <CJK>
+0xE9D8	0x6A5E	# <CJK>
+0xE9D9	0x6A56	# <CJK>
+0xE9DA	0x6A55	# <CJK>
+0xE9DB	0x6A4D	# <CJK>
+0xE9DC	0x6A4E	# <CJK>
+0xE9DD	0x6A46	# <CJK>
+0xE9DE	0x6B55	# <CJK>
+0xE9DF	0x6B54	# <CJK>
+0xE9E0	0x6B56	# <CJK>
+0xE9E1	0x6BA7	# <CJK>
+0xE9E2	0x6BAA	# <CJK>
+0xE9E3	0x6BAB	# <CJK>
+0xE9E4	0x6BC8	# <CJK>
+0xE9E5	0x6BC7	# <CJK>
+0xE9E6	0x6C04	# <CJK>
+0xE9E7	0x6C03	# <CJK>
+0xE9E8	0x6C06	# <CJK>
+0xE9E9	0x6FAD	# <CJK>
+0xE9EA	0x6FCB	# <CJK>
+0xE9EB	0x6FA3	# <CJK>
+0xE9EC	0x6FC7	# <CJK>
+0xE9ED	0x6FBC	# <CJK>
+0xE9EE	0x6FCE	# <CJK>
+0xE9EF	0x6FC8	# <CJK>
+0xE9F0	0x6F5E	# <CJK>
+0xE9F1	0x6FC4	# <CJK>
+0xE9F2	0x6FBD	# <CJK>
+0xE9F3	0x6F9E	# <CJK>
+0xE9F4	0x6FCA	# <CJK>
+0xE9F5	0x6FA8	# <CJK>
+0xE9F6	0x7004	# <CJK>
+0xE9F7	0x6FA5	# <CJK>
+0xE9F8	0x6FAE	# <CJK>
+0xE9F9	0x6FBA	# <CJK>
+0xE9FA	0x6FAC	# <CJK>
+0xE9FB	0x6FAA	# <CJK>
+0xE9FC	0x6FCF	# <CJK>
+0xE9FD	0x6FBF	# <CJK>
+0xE9FE	0x6FB8	# <CJK>
+0xEA40	0x6FA2	# <CJK>
+0xEA41	0x6FC9	# <CJK>
+0xEA42	0x6FAB	# <CJK>
+0xEA43	0x6FCD	# <CJK>
+0xEA44	0x6FAF	# <CJK>
+0xEA45	0x6FB2	# <CJK>
+0xEA46	0x6FB0	# <CJK>
+0xEA47	0x71C5	# <CJK>
+0xEA48	0x71C2	# <CJK>
+0xEA49	0x71BF	# <CJK>
+0xEA4A	0x71B8	# <CJK>
+0xEA4B	0x71D6	# <CJK>
+0xEA4C	0x71C0	# <CJK>
+0xEA4D	0x71C1	# <CJK>
+0xEA4E	0x71CB	# <CJK>
+0xEA4F	0x71D4	# <CJK>
+0xEA50	0x71CA	# <CJK>
+0xEA51	0x71C7	# <CJK>
+0xEA52	0x71CF	# <CJK>
+0xEA53	0x71BD	# <CJK>
+0xEA54	0x71D8	# <CJK>
+0xEA55	0x71BC	# <CJK>
+0xEA56	0x71C6	# <CJK>
+0xEA57	0x71DA	# <CJK>
+0xEA58	0x71DB	# <CJK>
+0xEA59	0x729D	# <CJK>
+0xEA5A	0x729E	# <CJK>
+0xEA5B	0x7369	# <CJK>
+0xEA5C	0x7366	# <CJK>
+0xEA5D	0x7367	# <CJK>
+0xEA5E	0x736C	# <CJK>
+0xEA5F	0x7365	# <CJK>
+0xEA60	0x736B	# <CJK>
+0xEA61	0x736A	# <CJK>
+0xEA62	0x747F	# <CJK>
+0xEA63	0x749A	# <CJK>
+0xEA64	0x74A0	# <CJK>
+0xEA65	0x7494	# <CJK>
+0xEA66	0x7492	# <CJK>
+0xEA67	0x7495	# <CJK>
+0xEA68	0x74A1	# <CJK>
+0xEA69	0x750B	# <CJK>
+0xEA6A	0x7580	# <CJK>
+0xEA6B	0x762F	# <CJK>
+0xEA6C	0x762D	# <CJK>
+0xEA6D	0x7631	# <CJK>
+0xEA6E	0x763D	# <CJK>
+0xEA6F	0x7633	# <CJK>
+0xEA70	0x763C	# <CJK>
+0xEA71	0x7635	# <CJK>
+0xEA72	0x7632	# <CJK>
+0xEA73	0x7630	# <CJK>
+0xEA74	0x76BB	# <CJK>
+0xEA75	0x76E6	# <CJK>
+0xEA76	0x779A	# <CJK>
+0xEA77	0x779D	# <CJK>
+0xEA78	0x77A1	# <CJK>
+0xEA79	0x779C	# <CJK>
+0xEA7A	0x779B	# <CJK>
+0xEA7B	0x77A2	# <CJK>
+0xEA7C	0x77A3	# <CJK>
+0xEA7D	0x7795	# <CJK>
+0xEA7E	0x7799	# <CJK>
+0xEAA1	0x7797	# <CJK>
+0xEAA2	0x78DD	# <CJK>
+0xEAA3	0x78E9	# <CJK>
+0xEAA4	0x78E5	# <CJK>
+0xEAA5	0x78EA	# <CJK>
+0xEAA6	0x78DE	# <CJK>
+0xEAA7	0x78E3	# <CJK>
+0xEAA8	0x78DB	# <CJK>
+0xEAA9	0x78E1	# <CJK>
+0xEAAA	0x78E2	# <CJK>
+0xEAAB	0x78ED	# <CJK>
+0xEAAC	0x78DF	# <CJK>
+0xEAAD	0x78E0	# <CJK>
+0xEAAE	0x79A4	# <CJK>
+0xEAAF	0x7A44	# <CJK>
+0xEAB0	0x7A48	# <CJK>
+0xEAB1	0x7A47	# <CJK>
+0xEAB2	0x7AB6	# <CJK>
+0xEAB3	0x7AB8	# <CJK>
+0xEAB4	0x7AB5	# <CJK>
+0xEAB5	0x7AB1	# <CJK>
+0xEAB6	0x7AB7	# <CJK>
+0xEAB7	0x7BDE	# <CJK>
+0xEAB8	0x7BE3	# <CJK>
+0xEAB9	0x7BE7	# <CJK>
+0xEABA	0x7BDD	# <CJK>
+0xEABB	0x7BD5	# <CJK>
+0xEABC	0x7BE5	# <CJK>
+0xEABD	0x7BDA	# <CJK>
+0xEABE	0x7BE8	# <CJK>
+0xEABF	0x7BF9	# <CJK>
+0xEAC0	0x7BD4	# <CJK>
+0xEAC1	0x7BEA	# <CJK>
+0xEAC2	0x7BE2	# <CJK>
+0xEAC3	0x7BDC	# <CJK>
+0xEAC4	0x7BEB	# <CJK>
+0xEAC5	0x7BD8	# <CJK>
+0xEAC6	0x7BDF	# <CJK>
+0xEAC7	0x7CD2	# <CJK>
+0xEAC8	0x7CD4	# <CJK>
+0xEAC9	0x7CD7	# <CJK>
+0xEACA	0x7CD0	# <CJK>
+0xEACB	0x7CD1	# <CJK>
+0xEACC	0x7E12	# <CJK>
+0xEACD	0x7E21	# <CJK>
+0xEACE	0x7E17	# <CJK>
+0xEACF	0x7E0C	# <CJK>
+0xEAD0	0x7E1F	# <CJK>
+0xEAD1	0x7E20	# <CJK>
+0xEAD2	0x7E13	# <CJK>
+0xEAD3	0x7E0E	# <CJK>
+0xEAD4	0x7E1C	# <CJK>
+0xEAD5	0x7E15	# <CJK>
+0xEAD6	0x7E1A	# <CJK>
+0xEAD7	0x7E22	# <CJK>
+0xEAD8	0x7E0B	# <CJK>
+0xEAD9	0x7E0F	# <CJK>
+0xEADA	0x7E16	# <CJK>
+0xEADB	0x7E0D	# <CJK>
+0xEADC	0x7E14	# <CJK>
+0xEADD	0x7E25	# <CJK>
+0xEADE	0x7E24	# <CJK>
+0xEADF	0x7F43	# <CJK>
+0xEAE0	0x7F7B	# <CJK>
+0xEAE1	0x7F7C	# <CJK>
+0xEAE2	0x7F7A	# <CJK>
+0xEAE3	0x7FB1	# <CJK>
+0xEAE4	0x7FEF	# <CJK>
+0xEAE5	0x802A	# <CJK>
+0xEAE6	0x8029	# <CJK>
+0xEAE7	0x806C	# <CJK>
+0xEAE8	0x81B1	# <CJK>
+0xEAE9	0x81A6	# <CJK>
+0xEAEA	0x81AE	# <CJK>
+0xEAEB	0x81B9	# <CJK>
+0xEAEC	0x81B5	# <CJK>
+0xEAED	0x81AB	# <CJK>
+0xEAEE	0x81B0	# <CJK>
+0xEAEF	0x81AC	# <CJK>
+0xEAF0	0x81B4	# <CJK>
+0xEAF1	0x81B2	# <CJK>
+0xEAF2	0x81B7	# <CJK>
+0xEAF3	0x81A7	# <CJK>
+0xEAF4	0x81F2	# <CJK>
+0xEAF5	0x8255	# <CJK>
+0xEAF6	0x8256	# <CJK>
+0xEAF7	0x8257	# <CJK>
+0xEAF8	0x8556	# <CJK>
+0xEAF9	0x8545	# <CJK>
+0xEAFA	0x856B	# <CJK>
+0xEAFB	0x854D	# <CJK>
+0xEAFC	0x8553	# <CJK>
+0xEAFD	0x8561	# <CJK>
+0xEAFE	0x8558	# <CJK>
+0xEB40	0x8540	# <CJK>
+0xEB41	0x8546	# <CJK>
+0xEB42	0x8564	# <CJK>
+0xEB43	0x8541	# <CJK>
+0xEB44	0x8562	# <CJK>
+0xEB45	0x8544	# <CJK>
+0xEB46	0x8551	# <CJK>
+0xEB47	0x8547	# <CJK>
+0xEB48	0x8563	# <CJK>
+0xEB49	0x853E	# <CJK>
+0xEB4A	0x855B	# <CJK>
+0xEB4B	0x8571	# <CJK>
+0xEB4C	0x854E	# <CJK>
+0xEB4D	0x856E	# <CJK>
+0xEB4E	0x8575	# <CJK>
+0xEB4F	0x8555	# <CJK>
+0xEB50	0x8567	# <CJK>
+0xEB51	0x8560	# <CJK>
+0xEB52	0x858C	# <CJK>
+0xEB53	0x8566	# <CJK>
+0xEB54	0x855D	# <CJK>
+0xEB55	0x8554	# <CJK>
+0xEB56	0x8565	# <CJK>
+0xEB57	0x856C	# <CJK>
+0xEB58	0x8663	# <CJK>
+0xEB59	0x8665	# <CJK>
+0xEB5A	0x8664	# <CJK>
+0xEB5B	0x879B	# <CJK>
+0xEB5C	0x878F	# <CJK>
+0xEB5D	0x8797	# <CJK>
+0xEB5E	0x8793	# <CJK>
+0xEB5F	0x8792	# <CJK>
+0xEB60	0x8788	# <CJK>
+0xEB61	0x8781	# <CJK>
+0xEB62	0x8796	# <CJK>
+0xEB63	0x8798	# <CJK>
+0xEB64	0x8779	# <CJK>
+0xEB65	0x8787	# <CJK>
+0xEB66	0x87A3	# <CJK>
+0xEB67	0x8785	# <CJK>
+0xEB68	0x8790	# <CJK>
+0xEB69	0x8791	# <CJK>
+0xEB6A	0x879D	# <CJK>
+0xEB6B	0x8784	# <CJK>
+0xEB6C	0x8794	# <CJK>
+0xEB6D	0x879C	# <CJK>
+0xEB6E	0x879A	# <CJK>
+0xEB6F	0x8789	# <CJK>
+0xEB70	0x891E	# <CJK>
+0xEB71	0x8926	# <CJK>
+0xEB72	0x8930	# <CJK>
+0xEB73	0x892D	# <CJK>
+0xEB74	0x892E	# <CJK>
+0xEB75	0x8927	# <CJK>
+0xEB76	0x8931	# <CJK>
+0xEB77	0x8922	# <CJK>
+0xEB78	0x8929	# <CJK>
+0xEB79	0x8923	# <CJK>
+0xEB7A	0x892F	# <CJK>
+0xEB7B	0x892C	# <CJK>
+0xEB7C	0x891F	# <CJK>
+0xEB7D	0x89F1	# <CJK>
+0xEB7E	0x8AE0	# <CJK>
+0xEBA1	0x8AE2	# <CJK>
+0xEBA2	0x8AF2	# <CJK>
+0xEBA3	0x8AF4	# <CJK>
+0xEBA4	0x8AF5	# <CJK>
+0xEBA5	0x8ADD	# <CJK>
+0xEBA6	0x8B14	# <CJK>
+0xEBA7	0x8AE4	# <CJK>
+0xEBA8	0x8ADF	# <CJK>
+0xEBA9	0x8AF0	# <CJK>
+0xEBAA	0x8AC8	# <CJK>
+0xEBAB	0x8ADE	# <CJK>
+0xEBAC	0x8AE1	# <CJK>
+0xEBAD	0x8AE8	# <CJK>
+0xEBAE	0x8AFF	# <CJK>
+0xEBAF	0x8AEF	# <CJK>
+0xEBB0	0x8AFB	# <CJK>
+0xEBB1	0x8C91	# <CJK>
+0xEBB2	0x8C92	# <CJK>
+0xEBB3	0x8C90	# <CJK>
+0xEBB4	0x8CF5	# <CJK>
+0xEBB5	0x8CEE	# <CJK>
+0xEBB6	0x8CF1	# <CJK>
+0xEBB7	0x8CF0	# <CJK>
+0xEBB8	0x8CF3	# <CJK>
+0xEBB9	0x8D6C	# <CJK>
+0xEBBA	0x8D6E	# <CJK>
+0xEBBB	0x8DA5	# <CJK>
+0xEBBC	0x8DA7	# <CJK>
+0xEBBD	0x8E33	# <CJK>
+0xEBBE	0x8E3E	# <CJK>
+0xEBBF	0x8E38	# <CJK>
+0xEBC0	0x8E40	# <CJK>
+0xEBC1	0x8E45	# <CJK>
+0xEBC2	0x8E36	# <CJK>
+0xEBC3	0x8E3C	# <CJK>
+0xEBC4	0x8E3D	# <CJK>
+0xEBC5	0x8E41	# <CJK>
+0xEBC6	0x8E30	# <CJK>
+0xEBC7	0x8E3F	# <CJK>
+0xEBC8	0x8EBD	# <CJK>
+0xEBC9	0x8F36	# <CJK>
+0xEBCA	0x8F2E	# <CJK>
+0xEBCB	0x8F35	# <CJK>
+0xEBCC	0x8F32	# <CJK>
+0xEBCD	0x8F39	# <CJK>
+0xEBCE	0x8F37	# <CJK>
+0xEBCF	0x8F34	# <CJK>
+0xEBD0	0x9076	# <CJK>
+0xEBD1	0x9079	# <CJK>
+0xEBD2	0x907B	# <CJK>
+0xEBD3	0x9086	# <CJK>
+0xEBD4	0x90FA	# <CJK>
+0xEBD5	0x9133	# <CJK>
+0xEBD6	0x9135	# <CJK>
+0xEBD7	0x9136	# <CJK>
+0xEBD8	0x9193	# <CJK>
+0xEBD9	0x9190	# <CJK>
+0xEBDA	0x9191	# <CJK>
+0xEBDB	0x918D	# <CJK>
+0xEBDC	0x918F	# <CJK>
+0xEBDD	0x9327	# <CJK>
+0xEBDE	0x931E	# <CJK>
+0xEBDF	0x9308	# <CJK>
+0xEBE0	0x931F	# <CJK>
+0xEBE1	0x9306	# <CJK>
+0xEBE2	0x930F	# <CJK>
+0xEBE3	0x937A	# <CJK>
+0xEBE4	0x9338	# <CJK>
+0xEBE5	0x933C	# <CJK>
+0xEBE6	0x931B	# <CJK>
+0xEBE7	0x9323	# <CJK>
+0xEBE8	0x9312	# <CJK>
+0xEBE9	0x9301	# <CJK>
+0xEBEA	0x9346	# <CJK>
+0xEBEB	0x932D	# <CJK>
+0xEBEC	0x930E	# <CJK>
+0xEBED	0x930D	# <CJK>
+0xEBEE	0x92CB	# <CJK>
+0xEBEF	0x931D	# <CJK>
+0xEBF0	0x92FA	# <CJK>
+0xEBF1	0x9325	# <CJK>
+0xEBF2	0x9313	# <CJK>
+0xEBF3	0x92F9	# <CJK>
+0xEBF4	0x92F7	# <CJK>
+0xEBF5	0x9334	# <CJK>
+0xEBF6	0x9302	# <CJK>
+0xEBF7	0x9324	# <CJK>
+0xEBF8	0x92FF	# <CJK>
+0xEBF9	0x9329	# <CJK>
+0xEBFA	0x9339	# <CJK>
+0xEBFB	0x9335	# <CJK>
+0xEBFC	0x932A	# <CJK>
+0xEBFD	0x9314	# <CJK>
+0xEBFE	0x930C	# <CJK>
+0xEC40	0x930B	# <CJK>
+0xEC41	0x92FE	# <CJK>
+0xEC42	0x9309	# <CJK>
+0xEC43	0x9300	# <CJK>
+0xEC44	0x92FB	# <CJK>
+0xEC45	0x9316	# <CJK>
+0xEC46	0x95BC	# <CJK>
+0xEC47	0x95CD	# <CJK>
+0xEC48	0x95BE	# <CJK>
+0xEC49	0x95B9	# <CJK>
+0xEC4A	0x95BA	# <CJK>
+0xEC4B	0x95B6	# <CJK>
+0xEC4C	0x95BF	# <CJK>
+0xEC4D	0x95B5	# <CJK>
+0xEC4E	0x95BD	# <CJK>
+0xEC4F	0x96A9	# <CJK>
+0xEC50	0x96D4	# <CJK>
+0xEC51	0x970B	# <CJK>
+0xEC52	0x9712	# <CJK>
+0xEC53	0x9710	# <CJK>
+0xEC54	0x9799	# <CJK>
+0xEC55	0x9797	# <CJK>
+0xEC56	0x9794	# <CJK>
+0xEC57	0x97F0	# <CJK>
+0xEC58	0x97F8	# <CJK>
+0xEC59	0x9835	# <CJK>
+0xEC5A	0x982F	# <CJK>
+0xEC5B	0x9832	# <CJK>
+0xEC5C	0x9924	# <CJK>
+0xEC5D	0x991F	# <CJK>
+0xEC5E	0x9927	# <CJK>
+0xEC5F	0x9929	# <CJK>
+0xEC60	0x999E	# <CJK>
+0xEC61	0x99EE	# <CJK>
+0xEC62	0x99EC	# <CJK>
+0xEC63	0x99E5	# <CJK>
+0xEC64	0x99E4	# <CJK>
+0xEC65	0x99F0	# <CJK>
+0xEC66	0x99E3	# <CJK>
+0xEC67	0x99EA	# <CJK>
+0xEC68	0x99E9	# <CJK>
+0xEC69	0x99E7	# <CJK>
+0xEC6A	0x9AB9	# <CJK>
+0xEC6B	0x9ABF	# <CJK>
+0xEC6C	0x9AB4	# <CJK>
+0xEC6D	0x9ABB	# <CJK>
+0xEC6E	0x9AF6	# <CJK>
+0xEC6F	0x9AFA	# <CJK>
+0xEC70	0x9AF9	# <CJK>
+0xEC71	0x9AF7	# <CJK>
+0xEC72	0x9B33	# <CJK>
+0xEC73	0x9B80	# <CJK>
+0xEC74	0x9B85	# <CJK>
+0xEC75	0x9B87	# <CJK>
+0xEC76	0x9B7C	# <CJK>
+0xEC77	0x9B7E	# <CJK>
+0xEC78	0x9B7B	# <CJK>
+0xEC79	0x9B82	# <CJK>
+0xEC7A	0x9B93	# <CJK>
+0xEC7B	0x9B92	# <CJK>
+0xEC7C	0x9B90	# <CJK>
+0xEC7D	0x9B7A	# <CJK>
+0xEC7E	0x9B95	# <CJK>
+0xECA1	0x9B7D	# <CJK>
+0xECA2	0x9B88	# <CJK>
+0xECA3	0x9D25	# <CJK>
+0xECA4	0x9D17	# <CJK>
+0xECA5	0x9D20	# <CJK>
+0xECA6	0x9D1E	# <CJK>
+0xECA7	0x9D14	# <CJK>
+0xECA8	0x9D29	# <CJK>
+0xECA9	0x9D1D	# <CJK>
+0xECAA	0x9D18	# <CJK>
+0xECAB	0x9D22	# <CJK>
+0xECAC	0x9D10	# <CJK>
+0xECAD	0x9D19	# <CJK>
+0xECAE	0x9D1F	# <CJK>
+0xECAF	0x9E88	# <CJK>
+0xECB0	0x9E86	# <CJK>
+0xECB1	0x9E87	# <CJK>
+0xECB2	0x9EAE	# <CJK>
+0xECB3	0x9EAD	# <CJK>
+0xECB4	0x9ED5	# <CJK>
+0xECB5	0x9ED6	# <CJK>
+0xECB6	0x9EFA	# <CJK>
+0xECB7	0x9F12	# <CJK>
+0xECB8	0x9F3D	# <CJK>
+0xECB9	0x5126	# <CJK>
+0xECBA	0x5125	# <CJK>
+0xECBB	0x5122	# <CJK>
+0xECBC	0x5124	# <CJK>
+0xECBD	0x5120	# <CJK>
+0xECBE	0x5129	# <CJK>
+0xECBF	0x52F4	# <CJK>
+0xECC0	0x5693	# <CJK>
+0xECC1	0x568C	# <CJK>
+0xECC2	0x568D	# <CJK>
+0xECC3	0x5686	# <CJK>
+0xECC4	0x5684	# <CJK>
+0xECC5	0x5683	# <CJK>
+0xECC6	0x567E	# <CJK>
+0xECC7	0x5682	# <CJK>
+0xECC8	0x567F	# <CJK>
+0xECC9	0x5681	# <CJK>
+0xECCA	0x58D6	# <CJK>
+0xECCB	0x58D4	# <CJK>
+0xECCC	0x58CF	# <CJK>
+0xECCD	0x58D2	# <CJK>
+0xECCE	0x5B2D	# <CJK>
+0xECCF	0x5B25	# <CJK>
+0xECD0	0x5B32	# <CJK>
+0xECD1	0x5B23	# <CJK>
+0xECD2	0x5B2C	# <CJK>
+0xECD3	0x5B27	# <CJK>
+0xECD4	0x5B26	# <CJK>
+0xECD5	0x5B2F	# <CJK>
+0xECD6	0x5B2E	# <CJK>
+0xECD7	0x5B7B	# <CJK>
+0xECD8	0x5BF1	# <CJK>
+0xECD9	0x5BF2	# <CJK>
+0xECDA	0x5DB7	# <CJK>
+0xECDB	0x5E6C	# <CJK>
+0xECDC	0x5E6A	# <CJK>
+0xECDD	0x5FBE	# <CJK>
+0xECDE	0x5FBB	# <CJK>
+0xECDF	0x61C3	# <CJK>
+0xECE0	0x61B5	# <CJK>
+0xECE1	0x61BC	# <CJK>
+0xECE2	0x61E7	# <CJK>
+0xECE3	0x61E0	# <CJK>
+0xECE4	0x61E5	# <CJK>
+0xECE5	0x61E4	# <CJK>
+0xECE6	0x61E8	# <CJK>
+0xECE7	0x61DE	# <CJK>
+0xECE8	0x64EF	# <CJK>
+0xECE9	0x64E9	# <CJK>
+0xECEA	0x64E3	# <CJK>
+0xECEB	0x64EB	# <CJK>
+0xECEC	0x64E4	# <CJK>
+0xECED	0x64E8	# <CJK>
+0xECEE	0x6581	# <CJK>
+0xECEF	0x6580	# <CJK>
+0xECF0	0x65B6	# <CJK>
+0xECF1	0x65DA	# <CJK>
+0xECF2	0x66D2	# <CJK>
+0xECF3	0x6A8D	# <CJK>
+0xECF4	0x6A96	# <CJK>
+0xECF5	0x6A81	# <CJK>
+0xECF6	0x6AA5	# <CJK>
+0xECF7	0x6A89	# <CJK>
+0xECF8	0x6A9F	# <CJK>
+0xECF9	0x6A9B	# <CJK>
+0xECFA	0x6AA1	# <CJK>
+0xECFB	0x6A9E	# <CJK>
+0xECFC	0x6A87	# <CJK>
+0xECFD	0x6A93	# <CJK>
+0xECFE	0x6A8E	# <CJK>
+0xED40	0x6A95	# <CJK>
+0xED41	0x6A83	# <CJK>
+0xED42	0x6AA8	# <CJK>
+0xED43	0x6AA4	# <CJK>
+0xED44	0x6A91	# <CJK>
+0xED45	0x6A7F	# <CJK>
+0xED46	0x6AA6	# <CJK>
+0xED47	0x6A9A	# <CJK>
+0xED48	0x6A85	# <CJK>
+0xED49	0x6A8C	# <CJK>
+0xED4A	0x6A92	# <CJK>
+0xED4B	0x6B5B	# <CJK>
+0xED4C	0x6BAD	# <CJK>
+0xED4D	0x6C09	# <CJK>
+0xED4E	0x6FCC	# <CJK>
+0xED4F	0x6FA9	# <CJK>
+0xED50	0x6FF4	# <CJK>
+0xED51	0x6FD4	# <CJK>
+0xED52	0x6FE3	# <CJK>
+0xED53	0x6FDC	# <CJK>
+0xED54	0x6FED	# <CJK>
+0xED55	0x6FE7	# <CJK>
+0xED56	0x6FE6	# <CJK>
+0xED57	0x6FDE	# <CJK>
+0xED58	0x6FF2	# <CJK>
+0xED59	0x6FDD	# <CJK>
+0xED5A	0x6FE2	# <CJK>
+0xED5B	0x6FE8	# <CJK>
+0xED5C	0x71E1	# <CJK>
+0xED5D	0x71F1	# <CJK>
+0xED5E	0x71E8	# <CJK>
+0xED5F	0x71F2	# <CJK>
+0xED60	0x71E4	# <CJK>
+0xED61	0x71F0	# <CJK>
+0xED62	0x71E2	# <CJK>
+0xED63	0x7373	# <CJK>
+0xED64	0x736E	# <CJK>
+0xED65	0x736F	# <CJK>
+0xED66	0x7497	# <CJK>
+0xED67	0x74B2	# <CJK>
+0xED68	0x74AB	# <CJK>
+0xED69	0x7490	# <CJK>
+0xED6A	0x74AA	# <CJK>
+0xED6B	0x74AD	# <CJK>
+0xED6C	0x74B1	# <CJK>
+0xED6D	0x74A5	# <CJK>
+0xED6E	0x74AF	# <CJK>
+0xED6F	0x7510	# <CJK>
+0xED70	0x7511	# <CJK>
+0xED71	0x7512	# <CJK>
+0xED72	0x750F	# <CJK>
+0xED73	0x7584	# <CJK>
+0xED74	0x7643	# <CJK>
+0xED75	0x7648	# <CJK>
+0xED76	0x7649	# <CJK>
+0xED77	0x7647	# <CJK>
+0xED78	0x76A4	# <CJK>
+0xED79	0x76E9	# <CJK>
+0xED7A	0x77B5	# <CJK>
+0xED7B	0x77AB	# <CJK>
+0xED7C	0x77B2	# <CJK>
+0xED7D	0x77B7	# <CJK>
+0xED7E	0x77B6	# <CJK>
+0xEDA1	0x77B4	# <CJK>
+0xEDA2	0x77B1	# <CJK>
+0xEDA3	0x77A8	# <CJK>
+0xEDA4	0x77F0	# <CJK>
+0xEDA5	0x78F3	# <CJK>
+0xEDA6	0x78FD	# <CJK>
+0xEDA7	0x7902	# <CJK>
+0xEDA8	0x78FB	# <CJK>
+0xEDA9	0x78FC	# <CJK>
+0xEDAA	0x78F2	# <CJK>
+0xEDAB	0x7905	# <CJK>
+0xEDAC	0x78F9	# <CJK>
+0xEDAD	0x78FE	# <CJK>
+0xEDAE	0x7904	# <CJK>
+0xEDAF	0x79AB	# <CJK>
+0xEDB0	0x79A8	# <CJK>
+0xEDB1	0x7A5C	# <CJK>
+0xEDB2	0x7A5B	# <CJK>
+0xEDB3	0x7A56	# <CJK>
+0xEDB4	0x7A58	# <CJK>
+0xEDB5	0x7A54	# <CJK>
+0xEDB6	0x7A5A	# <CJK>
+0xEDB7	0x7ABE	# <CJK>
+0xEDB8	0x7AC0	# <CJK>
+0xEDB9	0x7AC1	# <CJK>
+0xEDBA	0x7C05	# <CJK>
+0xEDBB	0x7C0F	# <CJK>
+0xEDBC	0x7BF2	# <CJK>
+0xEDBD	0x7C00	# <CJK>
+0xEDBE	0x7BFF	# <CJK>
+0xEDBF	0x7BFB	# <CJK>
+0xEDC0	0x7C0E	# <CJK>
+0xEDC1	0x7BF4	# <CJK>
+0xEDC2	0x7C0B	# <CJK>
+0xEDC3	0x7BF3	# <CJK>
+0xEDC4	0x7C02	# <CJK>
+0xEDC5	0x7C09	# <CJK>
+0xEDC6	0x7C03	# <CJK>
+0xEDC7	0x7C01	# <CJK>
+0xEDC8	0x7BF8	# <CJK>
+0xEDC9	0x7BFD	# <CJK>
+0xEDCA	0x7C06	# <CJK>
+0xEDCB	0x7BF0	# <CJK>
+0xEDCC	0x7BF1	# <CJK>
+0xEDCD	0x7C10	# <CJK>
+0xEDCE	0x7C0A	# <CJK>
+0xEDCF	0x7CE8	# <CJK>
+0xEDD0	0x7E2D	# <CJK>
+0xEDD1	0x7E3C	# <CJK>
+0xEDD2	0x7E42	# <CJK>
+0xEDD3	0x7E33	# <CJK>
+0xEDD4	0x9848	# <CJK>
+0xEDD5	0x7E38	# <CJK>
+0xEDD6	0x7E2A	# <CJK>
+0xEDD7	0x7E49	# <CJK>
+0xEDD8	0x7E40	# <CJK>
+0xEDD9	0x7E47	# <CJK>
+0xEDDA	0x7E29	# <CJK>
+0xEDDB	0x7E4C	# <CJK>
+0xEDDC	0x7E30	# <CJK>
+0xEDDD	0x7E3B	# <CJK>
+0xEDDE	0x7E36	# <CJK>
+0xEDDF	0x7E44	# <CJK>
+0xEDE0	0x7E3A	# <CJK>
+0xEDE1	0x7F45	# <CJK>
+0xEDE2	0x7F7F	# <CJK>
+0xEDE3	0x7F7E	# <CJK>
+0xEDE4	0x7F7D	# <CJK>
+0xEDE5	0x7FF4	# <CJK>
+0xEDE6	0x7FF2	# <CJK>
+0xEDE7	0x802C	# <CJK>
+0xEDE8	0x81BB	# <CJK>
+0xEDE9	0x81C4	# <CJK>
+0xEDEA	0x81CC	# <CJK>
+0xEDEB	0x81CA	# <CJK>
+0xEDEC	0x81C5	# <CJK>
+0xEDED	0x81C7	# <CJK>
+0xEDEE	0x81BC	# <CJK>
+0xEDEF	0x81E9	# <CJK>
+0xEDF0	0x825B	# <CJK>
+0xEDF1	0x825A	# <CJK>
+0xEDF2	0x825C	# <CJK>
+0xEDF3	0x8583	# <CJK>
+0xEDF4	0x8580	# <CJK>
+0xEDF5	0x858F	# <CJK>
+0xEDF6	0x85A7	# <CJK>
+0xEDF7	0x8595	# <CJK>
+0xEDF8	0x85A0	# <CJK>
+0xEDF9	0x858B	# <CJK>
+0xEDFA	0x85A3	# <CJK>
+0xEDFB	0x857B	# <CJK>
+0xEDFC	0x85A4	# <CJK>
+0xEDFD	0x859A	# <CJK>
+0xEDFE	0x859E	# <CJK>
+0xEE40	0x8577	# <CJK>
+0xEE41	0x857C	# <CJK>
+0xEE42	0x8589	# <CJK>
+0xEE43	0x85A1	# <CJK>
+0xEE44	0x857A	# <CJK>
+0xEE45	0x8578	# <CJK>
+0xEE46	0x8557	# <CJK>
+0xEE47	0x858E	# <CJK>
+0xEE48	0x8596	# <CJK>
+0xEE49	0x8586	# <CJK>
+0xEE4A	0x858D	# <CJK>
+0xEE4B	0x8599	# <CJK>
+0xEE4C	0x859D	# <CJK>
+0xEE4D	0x8581	# <CJK>
+0xEE4E	0x85A2	# <CJK>
+0xEE4F	0x8582	# <CJK>
+0xEE50	0x8588	# <CJK>
+0xEE51	0x8585	# <CJK>
+0xEE52	0x8579	# <CJK>
+0xEE53	0x8576	# <CJK>
+0xEE54	0x8598	# <CJK>
+0xEE55	0x8590	# <CJK>
+0xEE56	0x859F	# <CJK>
+0xEE57	0x8668	# <CJK>
+0xEE58	0x87BE	# <CJK>
+0xEE59	0x87AA	# <CJK>
+0xEE5A	0x87AD	# <CJK>
+0xEE5B	0x87C5	# <CJK>
+0xEE5C	0x87B0	# <CJK>
+0xEE5D	0x87AC	# <CJK>
+0xEE5E	0x87B9	# <CJK>
+0xEE5F	0x87B5	# <CJK>
+0xEE60	0x87BC	# <CJK>
+0xEE61	0x87AE	# <CJK>
+0xEE62	0x87C9	# <CJK>
+0xEE63	0x87C3	# <CJK>
+0xEE64	0x87C2	# <CJK>
+0xEE65	0x87CC	# <CJK>
+0xEE66	0x87B7	# <CJK>
+0xEE67	0x87AF	# <CJK>
+0xEE68	0x87C4	# <CJK>
+0xEE69	0x87CA	# <CJK>
+0xEE6A	0x87B4	# <CJK>
+0xEE6B	0x87B6	# <CJK>
+0xEE6C	0x87BF	# <CJK>
+0xEE6D	0x87B8	# <CJK>
+0xEE6E	0x87BD	# <CJK>
+0xEE6F	0x87DE	# <CJK>
+0xEE70	0x87B2	# <CJK>
+0xEE71	0x8935	# <CJK>
+0xEE72	0x8933	# <CJK>
+0xEE73	0x893C	# <CJK>
+0xEE74	0x893E	# <CJK>
+0xEE75	0x8941	# <CJK>
+0xEE76	0x8952	# <CJK>
+0xEE77	0x8937	# <CJK>
+0xEE78	0x8942	# <CJK>
+0xEE79	0x89AD	# <CJK>
+0xEE7A	0x89AF	# <CJK>
+0xEE7B	0x89AE	# <CJK>
+0xEE7C	0x89F2	# <CJK>
+0xEE7D	0x89F3	# <CJK>
+0xEE7E	0x8B1E	# <CJK>
+0xEEA1	0x8B18	# <CJK>
+0xEEA2	0x8B16	# <CJK>
+0xEEA3	0x8B11	# <CJK>
+0xEEA4	0x8B05	# <CJK>
+0xEEA5	0x8B0B	# <CJK>
+0xEEA6	0x8B22	# <CJK>
+0xEEA7	0x8B0F	# <CJK>
+0xEEA8	0x8B12	# <CJK>
+0xEEA9	0x8B15	# <CJK>
+0xEEAA	0x8B07	# <CJK>
+0xEEAB	0x8B0D	# <CJK>
+0xEEAC	0x8B08	# <CJK>
+0xEEAD	0x8B06	# <CJK>
+0xEEAE	0x8B1C	# <CJK>
+0xEEAF	0x8B13	# <CJK>
+0xEEB0	0x8B1A	# <CJK>
+0xEEB1	0x8C4F	# <CJK>
+0xEEB2	0x8C70	# <CJK>
+0xEEB3	0x8C72	# <CJK>
+0xEEB4	0x8C71	# <CJK>
+0xEEB5	0x8C6F	# <CJK>
+0xEEB6	0x8C95	# <CJK>
+0xEEB7	0x8C94	# <CJK>
+0xEEB8	0x8CF9	# <CJK>
+0xEEB9	0x8D6F	# <CJK>
+0xEEBA	0x8E4E	# <CJK>
+0xEEBB	0x8E4D	# <CJK>
+0xEEBC	0x8E53	# <CJK>
+0xEEBD	0x8E50	# <CJK>
+0xEEBE	0x8E4C	# <CJK>
+0xEEBF	0x8E47	# <CJK>
+0xEEC0	0x8F43	# <CJK>
+0xEEC1	0x8F40	# <CJK>
+0xEEC2	0x9085	# <CJK>
+0xEEC3	0x907E	# <CJK>
+0xEEC4	0x9138	# <CJK>
+0xEEC5	0x919A	# <CJK>
+0xEEC6	0x91A2	# <CJK>
+0xEEC7	0x919B	# <CJK>
+0xEEC8	0x9199	# <CJK>
+0xEEC9	0x919F	# <CJK>
+0xEECA	0x91A1	# <CJK>
+0xEECB	0x919D	# <CJK>
+0xEECC	0x91A0	# <CJK>
+0xEECD	0x93A1	# <CJK>
+0xEECE	0x9383	# <CJK>
+0xEECF	0x93AF	# <CJK>
+0xEED0	0x9364	# <CJK>
+0xEED1	0x9356	# <CJK>
+0xEED2	0x9347	# <CJK>
+0xEED3	0x937C	# <CJK>
+0xEED4	0x9358	# <CJK>
+0xEED5	0x935C	# <CJK>
+0xEED6	0x9376	# <CJK>
+0xEED7	0x9349	# <CJK>
+0xEED8	0x9350	# <CJK>
+0xEED9	0x9351	# <CJK>
+0xEEDA	0x9360	# <CJK>
+0xEEDB	0x936D	# <CJK>
+0xEEDC	0x938F	# <CJK>
+0xEEDD	0x934C	# <CJK>
+0xEEDE	0x936A	# <CJK>
+0xEEDF	0x9379	# <CJK>
+0xEEE0	0x9357	# <CJK>
+0xEEE1	0x9355	# <CJK>
+0xEEE2	0x9352	# <CJK>
+0xEEE3	0x934F	# <CJK>
+0xEEE4	0x9371	# <CJK>
+0xEEE5	0x9377	# <CJK>
+0xEEE6	0x937B	# <CJK>
+0xEEE7	0x9361	# <CJK>
+0xEEE8	0x935E	# <CJK>
+0xEEE9	0x9363	# <CJK>
+0xEEEA	0x9367	# <CJK>
+0xEEEB	0x9380	# <CJK>
+0xEEEC	0x934E	# <CJK>
+0xEEED	0x9359	# <CJK>
+0xEEEE	0x95C7	# <CJK>
+0xEEEF	0x95C0	# <CJK>
+0xEEF0	0x95C9	# <CJK>
+0xEEF1	0x95C3	# <CJK>
+0xEEF2	0x95C5	# <CJK>
+0xEEF3	0x95B7	# <CJK>
+0xEEF4	0x96AE	# <CJK>
+0xEEF5	0x96B0	# <CJK>
+0xEEF6	0x96AC	# <CJK>
+0xEEF7	0x9720	# <CJK>
+0xEEF8	0x971F	# <CJK>
+0xEEF9	0x9718	# <CJK>
+0xEEFA	0x971D	# <CJK>
+0xEEFB	0x9719	# <CJK>
+0xEEFC	0x979A	# <CJK>
+0xEEFD	0x97A1	# <CJK>
+0xEEFE	0x979C	# <CJK>
+0xEF40	0x979E	# <CJK>
+0xEF41	0x979D	# <CJK>
+0xEF42	0x97D5	# <CJK>
+0xEF43	0x97D4	# <CJK>
+0xEF44	0x97F1	# <CJK>
+0xEF45	0x9841	# <CJK>
+0xEF46	0x9844	# <CJK>
+0xEF47	0x984A	# <CJK>
+0xEF48	0x9849	# <CJK>
+0xEF49	0x9845	# <CJK>
+0xEF4A	0x9843	# <CJK>
+0xEF4B	0x9925	# <CJK>
+0xEF4C	0x992B	# <CJK>
+0xEF4D	0x992C	# <CJK>
+0xEF4E	0x992A	# <CJK>
+0xEF4F	0x9933	# <CJK>
+0xEF50	0x9932	# <CJK>
+0xEF51	0x992F	# <CJK>
+0xEF52	0x992D	# <CJK>
+0xEF53	0x9931	# <CJK>
+0xEF54	0x9930	# <CJK>
+0xEF55	0x9998	# <CJK>
+0xEF56	0x99A3	# <CJK>
+0xEF57	0x99A1	# <CJK>
+0xEF58	0x9A02	# <CJK>
+0xEF59	0x99FA	# <CJK>
+0xEF5A	0x99F4	# <CJK>
+0xEF5B	0x99F7	# <CJK>
+0xEF5C	0x99F9	# <CJK>
+0xEF5D	0x99F8	# <CJK>
+0xEF5E	0x99F6	# <CJK>
+0xEF5F	0x99FB	# <CJK>
+0xEF60	0x99FD	# <CJK>
+0xEF61	0x99FE	# <CJK>
+0xEF62	0x99FC	# <CJK>
+0xEF63	0x9A03	# <CJK>
+0xEF64	0x9ABE	# <CJK>
+0xEF65	0x9AFE	# <CJK>
+0xEF66	0x9AFD	# <CJK>
+0xEF67	0x9B01	# <CJK>
+0xEF68	0x9AFC	# <CJK>
+0xEF69	0x9B48	# <CJK>
+0xEF6A	0x9B9A	# <CJK>
+0xEF6B	0x9BA8	# <CJK>
+0xEF6C	0x9B9E	# <CJK>
+0xEF6D	0x9B9B	# <CJK>
+0xEF6E	0x9BA6	# <CJK>
+0xEF6F	0x9BA1	# <CJK>
+0xEF70	0x9BA5	# <CJK>
+0xEF71	0x9BA4	# <CJK>
+0xEF72	0x9B86	# <CJK>
+0xEF73	0x9BA2	# <CJK>
+0xEF74	0x9BA0	# <CJK>
+0xEF75	0x9BAF	# <CJK>
+0xEF76	0x9D33	# <CJK>
+0xEF77	0x9D41	# <CJK>
+0xEF78	0x9D67	# <CJK>
+0xEF79	0x9D36	# <CJK>
+0xEF7A	0x9D2E	# <CJK>
+0xEF7B	0x9D2F	# <CJK>
+0xEF7C	0x9D31	# <CJK>
+0xEF7D	0x9D38	# <CJK>
+0xEF7E	0x9D30	# <CJK>
+0xEFA1	0x9D45	# <CJK>
+0xEFA2	0x9D42	# <CJK>
+0xEFA3	0x9D43	# <CJK>
+0xEFA4	0x9D3E	# <CJK>
+0xEFA5	0x9D37	# <CJK>
+0xEFA6	0x9D40	# <CJK>
+0xEFA7	0x9D3D	# <CJK>
+0xEFA8	0x7FF5	# <CJK>
+0xEFA9	0x9D2D	# <CJK>
+0xEFAA	0x9E8A	# <CJK>
+0xEFAB	0x9E89	# <CJK>
+0xEFAC	0x9E8D	# <CJK>
+0xEFAD	0x9EB0	# <CJK>
+0xEFAE	0x9EC8	# <CJK>
+0xEFAF	0x9EDA	# <CJK>
+0xEFB0	0x9EFB	# <CJK>
+0xEFB1	0x9EFF	# <CJK>
+0xEFB2	0x9F24	# <CJK>
+0xEFB3	0x9F23	# <CJK>
+0xEFB4	0x9F22	# <CJK>
+0xEFB5	0x9F54	# <CJK>
+0xEFB6	0x9FA0	# <CJK>
+0xEFB7	0x5131	# <CJK>
+0xEFB8	0x512D	# <CJK>
+0xEFB9	0x512E	# <CJK>
+0xEFBA	0x5698	# <CJK>
+0xEFBB	0x569C	# <CJK>
+0xEFBC	0x5697	# <CJK>
+0xEFBD	0x569A	# <CJK>
+0xEFBE	0x569D	# <CJK>
+0xEFBF	0x5699	# <CJK>
+0xEFC0	0x5970	# <CJK>
+0xEFC1	0x5B3C	# <CJK>
+0xEFC2	0x5C69	# <CJK>
+0xEFC3	0x5C6A	# <CJK>
+0xEFC4	0x5DC0	# <CJK>
+0xEFC5	0x5E6D	# <CJK>
+0xEFC6	0x5E6E	# <CJK>
+0xEFC7	0x61D8	# <CJK>
+0xEFC8	0x61DF	# <CJK>
+0xEFC9	0x61ED	# <CJK>
+0xEFCA	0x61EE	# <CJK>
+0xEFCB	0x61F1	# <CJK>
+0xEFCC	0x61EA	# <CJK>
+0xEFCD	0x61F0	# <CJK>
+0xEFCE	0x61EB	# <CJK>
+0xEFCF	0x61D6	# <CJK>
+0xEFD0	0x61E9	# <CJK>
+0xEFD1	0x64FF	# <CJK>
+0xEFD2	0x6504	# <CJK>
+0xEFD3	0x64FD	# <CJK>
+0xEFD4	0x64F8	# <CJK>
+0xEFD5	0x6501	# <CJK>
+0xEFD6	0x6503	# <CJK>
+0xEFD7	0x64FC	# <CJK>
+0xEFD8	0x6594	# <CJK>
+0xEFD9	0x65DB	# <CJK>
+0xEFDA	0x66DA	# <CJK>
+0xEFDB	0x66DB	# <CJK>
+0xEFDC	0x66D8	# <CJK>
+0xEFDD	0x6AC5	# <CJK>
+0xEFDE	0x6AB9	# <CJK>
+0xEFDF	0x6ABD	# <CJK>
+0xEFE0	0x6AE1	# <CJK>
+0xEFE1	0x6AC6	# <CJK>
+0xEFE2	0x6ABA	# <CJK>
+0xEFE3	0x6AB6	# <CJK>
+0xEFE4	0x6AB7	# <CJK>
+0xEFE5	0x6AC7	# <CJK>
+0xEFE6	0x6AB4	# <CJK>
+0xEFE7	0x6AAD	# <CJK>
+0xEFE8	0x6B5E	# <CJK>
+0xEFE9	0x6BC9	# <CJK>
+0xEFEA	0x6C0B	# <CJK>
+0xEFEB	0x7007	# <CJK>
+0xEFEC	0x700C	# <CJK>
+0xEFED	0x700D	# <CJK>
+0xEFEE	0x7001	# <CJK>
+0xEFEF	0x7005	# <CJK>
+0xEFF0	0x7014	# <CJK>
+0xEFF1	0x700E	# <CJK>
+0xEFF2	0x6FFF	# <CJK>
+0xEFF3	0x7000	# <CJK>
+0xEFF4	0x6FFB	# <CJK>
+0xEFF5	0x7026	# <CJK>
+0xEFF6	0x6FFC	# <CJK>
+0xEFF7	0x6FF7	# <CJK>
+0xEFF8	0x700A	# <CJK>
+0xEFF9	0x7201	# <CJK>
+0xEFFA	0x71FF	# <CJK>
+0xEFFB	0x71F9	# <CJK>
+0xEFFC	0x7203	# <CJK>
+0xEFFD	0x71FD	# <CJK>
+0xEFFE	0x7376	# <CJK>
+0xF040	0x74B8	# <CJK>
+0xF041	0x74C0	# <CJK>
+0xF042	0x74B5	# <CJK>
+0xF043	0x74C1	# <CJK>
+0xF044	0x74BE	# <CJK>
+0xF045	0x74B6	# <CJK>
+0xF046	0x74BB	# <CJK>
+0xF047	0x74C2	# <CJK>
+0xF048	0x7514	# <CJK>
+0xF049	0x7513	# <CJK>
+0xF04A	0x765C	# <CJK>
+0xF04B	0x7664	# <CJK>
+0xF04C	0x7659	# <CJK>
+0xF04D	0x7650	# <CJK>
+0xF04E	0x7653	# <CJK>
+0xF04F	0x7657	# <CJK>
+0xF050	0x765A	# <CJK>
+0xF051	0x76A6	# <CJK>
+0xF052	0x76BD	# <CJK>
+0xF053	0x76EC	# <CJK>
+0xF054	0x77C2	# <CJK>
+0xF055	0x77BA	# <CJK>
+0xF056	0x78FF	# <CJK>
+0xF057	0x790C	# <CJK>
+0xF058	0x7913	# <CJK>
+0xF059	0x7914	# <CJK>
+0xF05A	0x7909	# <CJK>
+0xF05B	0x7910	# <CJK>
+0xF05C	0x7912	# <CJK>
+0xF05D	0x7911	# <CJK>
+0xF05E	0x79AD	# <CJK>
+0xF05F	0x79AC	# <CJK>
+0xF060	0x7A5F	# <CJK>
+0xF061	0x7C1C	# <CJK>
+0xF062	0x7C29	# <CJK>
+0xF063	0x7C19	# <CJK>
+0xF064	0x7C20	# <CJK>
+0xF065	0x7C1F	# <CJK>
+0xF066	0x7C2D	# <CJK>
+0xF067	0x7C1D	# <CJK>
+0xF068	0x7C26	# <CJK>
+0xF069	0x7C28	# <CJK>
+0xF06A	0x7C22	# <CJK>
+0xF06B	0x7C25	# <CJK>
+0xF06C	0x7C30	# <CJK>
+0xF06D	0x7E5C	# <CJK>
+0xF06E	0x7E50	# <CJK>
+0xF06F	0x7E56	# <CJK>
+0xF070	0x7E63	# <CJK>
+0xF071	0x7E58	# <CJK>
+0xF072	0x7E62	# <CJK>
+0xF073	0x7E5F	# <CJK>
+0xF074	0x7E51	# <CJK>
+0xF075	0x7E60	# <CJK>
+0xF076	0x7E57	# <CJK>
+0xF077	0x7E53	# <CJK>
+0xF078	0x7FB5	# <CJK>
+0xF079	0x7FB3	# <CJK>
+0xF07A	0x7FF7	# <CJK>
+0xF07B	0x7FF8	# <CJK>
+0xF07C	0x8075	# <CJK>
+0xF07D	0x81D1	# <CJK>
+0xF07E	0x81D2	# <CJK>
+0xF0A1	0x81D0	# <CJK>
+0xF0A2	0x825F	# <CJK>
+0xF0A3	0x825E	# <CJK>
+0xF0A4	0x85B4	# <CJK>
+0xF0A5	0x85C6	# <CJK>
+0xF0A6	0x85C0	# <CJK>
+0xF0A7	0x85C3	# <CJK>
+0xF0A8	0x85C2	# <CJK>
+0xF0A9	0x85B3	# <CJK>
+0xF0AA	0x85B5	# <CJK>
+0xF0AB	0x85BD	# <CJK>
+0xF0AC	0x85C7	# <CJK>
+0xF0AD	0x85C4	# <CJK>
+0xF0AE	0x85BF	# <CJK>
+0xF0AF	0x85CB	# <CJK>
+0xF0B0	0x85CE	# <CJK>
+0xF0B1	0x85C8	# <CJK>
+0xF0B2	0x85C5	# <CJK>
+0xF0B3	0x85B1	# <CJK>
+0xF0B4	0x85B6	# <CJK>
+0xF0B5	0x85D2	# <CJK>
+0xF0B6	0x8624	# <CJK>
+0xF0B7	0x85B8	# <CJK>
+0xF0B8	0x85B7	# <CJK>
+0xF0B9	0x85BE	# <CJK>
+0xF0BA	0x8669	# <CJK>
+0xF0BB	0x87E7	# <CJK>
+0xF0BC	0x87E6	# <CJK>
+0xF0BD	0x87E2	# <CJK>
+0xF0BE	0x87DB	# <CJK>
+0xF0BF	0x87EB	# <CJK>
+0xF0C0	0x87EA	# <CJK>
+0xF0C1	0x87E5	# <CJK>
+0xF0C2	0x87DF	# <CJK>
+0xF0C3	0x87F3	# <CJK>
+0xF0C4	0x87E4	# <CJK>
+0xF0C5	0x87D4	# <CJK>
+0xF0C6	0x87DC	# <CJK>
+0xF0C7	0x87D3	# <CJK>
+0xF0C8	0x87ED	# <CJK>
+0xF0C9	0x87D8	# <CJK>
+0xF0CA	0x87E3	# <CJK>
+0xF0CB	0x87A4	# <CJK>
+0xF0CC	0x87D7	# <CJK>
+0xF0CD	0x87D9	# <CJK>
+0xF0CE	0x8801	# <CJK>
+0xF0CF	0x87F4	# <CJK>
+0xF0D0	0x87E8	# <CJK>
+0xF0D1	0x87DD	# <CJK>
+0xF0D2	0x8953	# <CJK>
+0xF0D3	0x894B	# <CJK>
+0xF0D4	0x894F	# <CJK>
+0xF0D5	0x894C	# <CJK>
+0xF0D6	0x8946	# <CJK>
+0xF0D7	0x8950	# <CJK>
+0xF0D8	0x8951	# <CJK>
+0xF0D9	0x8949	# <CJK>
+0xF0DA	0x8B2A	# <CJK>
+0xF0DB	0x8B27	# <CJK>
+0xF0DC	0x8B23	# <CJK>
+0xF0DD	0x8B33	# <CJK>
+0xF0DE	0x8B30	# <CJK>
+0xF0DF	0x8B35	# <CJK>
+0xF0E0	0x8B47	# <CJK>
+0xF0E1	0x8B2F	# <CJK>
+0xF0E2	0x8B3C	# <CJK>
+0xF0E3	0x8B3E	# <CJK>
+0xF0E4	0x8B31	# <CJK>
+0xF0E5	0x8B25	# <CJK>
+0xF0E6	0x8B37	# <CJK>
+0xF0E7	0x8B26	# <CJK>
+0xF0E8	0x8B36	# <CJK>
+0xF0E9	0x8B2E	# <CJK>
+0xF0EA	0x8B24	# <CJK>
+0xF0EB	0x8B3B	# <CJK>
+0xF0EC	0x8B3D	# <CJK>
+0xF0ED	0x8B3A	# <CJK>
+0xF0EE	0x8C42	# <CJK>
+0xF0EF	0x8C75	# <CJK>
+0xF0F0	0x8C99	# <CJK>
+0xF0F1	0x8C98	# <CJK>
+0xF0F2	0x8C97	# <CJK>
+0xF0F3	0x8CFE	# <CJK>
+0xF0F4	0x8D04	# <CJK>
+0xF0F5	0x8D02	# <CJK>
+0xF0F6	0x8D00	# <CJK>
+0xF0F7	0x8E5C	# <CJK>
+0xF0F8	0x8E62	# <CJK>
+0xF0F9	0x8E60	# <CJK>
+0xF0FA	0x8E57	# <CJK>
+0xF0FB	0x8E56	# <CJK>
+0xF0FC	0x8E5E	# <CJK>
+0xF0FD	0x8E65	# <CJK>
+0xF0FE	0x8E67	# <CJK>
+0xF140	0x8E5B	# <CJK>
+0xF141	0x8E5A	# <CJK>
+0xF142	0x8E61	# <CJK>
+0xF143	0x8E5D	# <CJK>
+0xF144	0x8E69	# <CJK>
+0xF145	0x8E54	# <CJK>
+0xF146	0x8F46	# <CJK>
+0xF147	0x8F47	# <CJK>
+0xF148	0x8F48	# <CJK>
+0xF149	0x8F4B	# <CJK>
+0xF14A	0x9128	# <CJK>
+0xF14B	0x913A	# <CJK>
+0xF14C	0x913B	# <CJK>
+0xF14D	0x913E	# <CJK>
+0xF14E	0x91A8	# <CJK>
+0xF14F	0x91A5	# <CJK>
+0xF150	0x91A7	# <CJK>
+0xF151	0x91AF	# <CJK>
+0xF152	0x91AA	# <CJK>
+0xF153	0x93B5	# <CJK>
+0xF154	0x938C	# <CJK>
+0xF155	0x9392	# <CJK>
+0xF156	0x93B7	# <CJK>
+0xF157	0x939B	# <CJK>
+0xF158	0x939D	# <CJK>
+0xF159	0x9389	# <CJK>
+0xF15A	0x93A7	# <CJK>
+0xF15B	0x938E	# <CJK>
+0xF15C	0x93AA	# <CJK>
+0xF15D	0x939E	# <CJK>
+0xF15E	0x93A6	# <CJK>
+0xF15F	0x9395	# <CJK>
+0xF160	0x9388	# <CJK>
+0xF161	0x9399	# <CJK>
+0xF162	0x939F	# <CJK>
+0xF163	0x938D	# <CJK>
+0xF164	0x93B1	# <CJK>
+0xF165	0x9391	# <CJK>
+0xF166	0x93B2	# <CJK>
+0xF167	0x93A4	# <CJK>
+0xF168	0x93A8	# <CJK>
+0xF169	0x93B4	# <CJK>
+0xF16A	0x93A3	# <CJK>
+0xF16B	0x93A5	# <CJK>
+0xF16C	0x95D2	# <CJK>
+0xF16D	0x95D3	# <CJK>
+0xF16E	0x95D1	# <CJK>
+0xF16F	0x96B3	# <CJK>
+0xF170	0x96D7	# <CJK>
+0xF171	0x96DA	# <CJK>
+0xF172	0x5DC2	# <CJK>
+0xF173	0x96DF	# <CJK>
+0xF174	0x96D8	# <CJK>
+0xF175	0x96DD	# <CJK>
+0xF176	0x9723	# <CJK>
+0xF177	0x9722	# <CJK>
+0xF178	0x9725	# <CJK>
+0xF179	0x97AC	# <CJK>
+0xF17A	0x97AE	# <CJK>
+0xF17B	0x97A8	# <CJK>
+0xF17C	0x97AB	# <CJK>
+0xF17D	0x97A4	# <CJK>
+0xF17E	0x97AA	# <CJK>
+0xF1A1	0x97A2	# <CJK>
+0xF1A2	0x97A5	# <CJK>
+0xF1A3	0x97D7	# <CJK>
+0xF1A4	0x97D9	# <CJK>
+0xF1A5	0x97D6	# <CJK>
+0xF1A6	0x97D8	# <CJK>
+0xF1A7	0x97FA	# <CJK>
+0xF1A8	0x9850	# <CJK>
+0xF1A9	0x9851	# <CJK>
+0xF1AA	0x9852	# <CJK>
+0xF1AB	0x98B8	# <CJK>
+0xF1AC	0x9941	# <CJK>
+0xF1AD	0x993C	# <CJK>
+0xF1AE	0x993A	# <CJK>
+0xF1AF	0x9A0F	# <CJK>
+0xF1B0	0x9A0B	# <CJK>
+0xF1B1	0x9A09	# <CJK>
+0xF1B2	0x9A0D	# <CJK>
+0xF1B3	0x9A04	# <CJK>
+0xF1B4	0x9A11	# <CJK>
+0xF1B5	0x9A0A	# <CJK>
+0xF1B6	0x9A05	# <CJK>
+0xF1B7	0x9A07	# <CJK>
+0xF1B8	0x9A06	# <CJK>
+0xF1B9	0x9AC0	# <CJK>
+0xF1BA	0x9ADC	# <CJK>
+0xF1BB	0x9B08	# <CJK>
+0xF1BC	0x9B04	# <CJK>
+0xF1BD	0x9B05	# <CJK>
+0xF1BE	0x9B29	# <CJK>
+0xF1BF	0x9B35	# <CJK>
+0xF1C0	0x9B4A	# <CJK>
+0xF1C1	0x9B4C	# <CJK>
+0xF1C2	0x9B4B	# <CJK>
+0xF1C3	0x9BC7	# <CJK>
+0xF1C4	0x9BC6	# <CJK>
+0xF1C5	0x9BC3	# <CJK>
+0xF1C6	0x9BBF	# <CJK>
+0xF1C7	0x9BC1	# <CJK>
+0xF1C8	0x9BB5	# <CJK>
+0xF1C9	0x9BB8	# <CJK>
+0xF1CA	0x9BD3	# <CJK>
+0xF1CB	0x9BB6	# <CJK>
+0xF1CC	0x9BC4	# <CJK>
+0xF1CD	0x9BB9	# <CJK>
+0xF1CE	0x9BBD	# <CJK>
+0xF1CF	0x9D5C	# <CJK>
+0xF1D0	0x9D53	# <CJK>
+0xF1D1	0x9D4F	# <CJK>
+0xF1D2	0x9D4A	# <CJK>
+0xF1D3	0x9D5B	# <CJK>
+0xF1D4	0x9D4B	# <CJK>
+0xF1D5	0x9D59	# <CJK>
+0xF1D6	0x9D56	# <CJK>
+0xF1D7	0x9D4C	# <CJK>
+0xF1D8	0x9D57	# <CJK>
+0xF1D9	0x9D52	# <CJK>
+0xF1DA	0x9D54	# <CJK>
+0xF1DB	0x9D5F	# <CJK>
+0xF1DC	0x9D58	# <CJK>
+0xF1DD	0x9D5A	# <CJK>
+0xF1DE	0x9E8E	# <CJK>
+0xF1DF	0x9E8C	# <CJK>
+0xF1E0	0x9EDF	# <CJK>
+0xF1E1	0x9F01	# <CJK>
+0xF1E2	0x9F00	# <CJK>
+0xF1E3	0x9F16	# <CJK>
+0xF1E4	0x9F25	# <CJK>
+0xF1E5	0x9F2B	# <CJK>
+0xF1E6	0x9F2A	# <CJK>
+0xF1E7	0x9F29	# <CJK>
+0xF1E8	0x9F28	# <CJK>
+0xF1E9	0x9F4C	# <CJK>
+0xF1EA	0x9F55	# <CJK>
+0xF1EB	0x5134	# <CJK>
+0xF1EC	0x5135	# <CJK>
+0xF1ED	0x5296	# <CJK>
+0xF1EE	0x52F7	# <CJK>
+0xF1EF	0x53B4	# <CJK>
+0xF1F0	0x56AB	# <CJK>
+0xF1F1	0x56AD	# <CJK>
+0xF1F2	0x56A6	# <CJK>
+0xF1F3	0x56A7	# <CJK>
+0xF1F4	0x56AA	# <CJK>
+0xF1F5	0x56AC	# <CJK>
+0xF1F6	0x58DA	# <CJK>
+0xF1F7	0x58DD	# <CJK>
+0xF1F8	0x58DB	# <CJK>
+0xF1F9	0x5912	# <CJK>
+0xF1FA	0x5B3D	# <CJK>
+0xF1FB	0x5B3E	# <CJK>
+0xF1FC	0x5B3F	# <CJK>
+0xF1FD	0x5DC3	# <CJK>
+0xF1FE	0x5E70	# <CJK>
+0xF240	0x5FBF	# <CJK>
+0xF241	0x61FB	# <CJK>
+0xF242	0x6507	# <CJK>
+0xF243	0x6510	# <CJK>
+0xF244	0x650D	# <CJK>
+0xF245	0x6509	# <CJK>
+0xF246	0x650C	# <CJK>
+0xF247	0x650E	# <CJK>
+0xF248	0x6584	# <CJK>
+0xF249	0x65DE	# <CJK>
+0xF24A	0x65DD	# <CJK>
+0xF24B	0x66DE	# <CJK>
+0xF24C	0x6AE7	# <CJK>
+0xF24D	0x6AE0	# <CJK>
+0xF24E	0x6ACC	# <CJK>
+0xF24F	0x6AD1	# <CJK>
+0xF250	0x6AD9	# <CJK>
+0xF251	0x6ACB	# <CJK>
+0xF252	0x6ADF	# <CJK>
+0xF253	0x6ADC	# <CJK>
+0xF254	0x6AD0	# <CJK>
+0xF255	0x6AEB	# <CJK>
+0xF256	0x6ACF	# <CJK>
+0xF257	0x6ACD	# <CJK>
+0xF258	0x6ADE	# <CJK>
+0xF259	0x6B60	# <CJK>
+0xF25A	0x6BB0	# <CJK>
+0xF25B	0x6C0C	# <CJK>
+0xF25C	0x7019	# <CJK>
+0xF25D	0x7027	# <CJK>
+0xF25E	0x7020	# <CJK>
+0xF25F	0x7016	# <CJK>
+0xF260	0x702B	# <CJK>
+0xF261	0x7021	# <CJK>
+0xF262	0x7022	# <CJK>
+0xF263	0x7023	# <CJK>
+0xF264	0x7029	# <CJK>
+0xF265	0x7017	# <CJK>
+0xF266	0x7024	# <CJK>
+0xF267	0x701C	# <CJK>
+0xF268	0x702A	# <CJK>
+0xF269	0x720C	# <CJK>
+0xF26A	0x720A	# <CJK>
+0xF26B	0x7207	# <CJK>
+0xF26C	0x7202	# <CJK>
+0xF26D	0x7205	# <CJK>
+0xF26E	0x72A5	# <CJK>
+0xF26F	0x72A6	# <CJK>
+0xF270	0x72A4	# <CJK>
+0xF271	0x72A3	# <CJK>
+0xF272	0x72A1	# <CJK>
+0xF273	0x74CB	# <CJK>
+0xF274	0x74C5	# <CJK>
+0xF275	0x74B7	# <CJK>
+0xF276	0x74C3	# <CJK>
+0xF277	0x7516	# <CJK>
+0xF278	0x7660	# <CJK>
+0xF279	0x77C9	# <CJK>
+0xF27A	0x77CA	# <CJK>
+0xF27B	0x77C4	# <CJK>
+0xF27C	0x77F1	# <CJK>
+0xF27D	0x791D	# <CJK>
+0xF27E	0x791B	# <CJK>
+0xF2A1	0x7921	# <CJK>
+0xF2A2	0x791C	# <CJK>
+0xF2A3	0x7917	# <CJK>
+0xF2A4	0x791E	# <CJK>
+0xF2A5	0x79B0	# <CJK>
+0xF2A6	0x7A67	# <CJK>
+0xF2A7	0x7A68	# <CJK>
+0xF2A8	0x7C33	# <CJK>
+0xF2A9	0x7C3C	# <CJK>
+0xF2AA	0x7C39	# <CJK>
+0xF2AB	0x7C2C	# <CJK>
+0xF2AC	0x7C3B	# <CJK>
+0xF2AD	0x7CEC	# <CJK>
+0xF2AE	0x7CEA	# <CJK>
+0xF2AF	0x7E76	# <CJK>
+0xF2B0	0x7E75	# <CJK>
+0xF2B1	0x7E78	# <CJK>
+0xF2B2	0x7E70	# <CJK>
+0xF2B3	0x7E77	# <CJK>
+0xF2B4	0x7E6F	# <CJK>
+0xF2B5	0x7E7A	# <CJK>
+0xF2B6	0x7E72	# <CJK>
+0xF2B7	0x7E74	# <CJK>
+0xF2B8	0x7E68	# <CJK>
+0xF2B9	0x7F4B	# <CJK>
+0xF2BA	0x7F4A	# <CJK>
+0xF2BB	0x7F83	# <CJK>
+0xF2BC	0x7F86	# <CJK>
+0xF2BD	0x7FB7	# <CJK>
+0xF2BE	0x7FFD	# <CJK>
+0xF2BF	0x7FFE	# <CJK>
+0xF2C0	0x8078	# <CJK>
+0xF2C1	0x81D7	# <CJK>
+0xF2C2	0x81D5	# <CJK>
+0xF2C3	0x8264	# <CJK>
+0xF2C4	0x8261	# <CJK>
+0xF2C5	0x8263	# <CJK>
+0xF2C6	0x85EB	# <CJK>
+0xF2C7	0x85F1	# <CJK>
+0xF2C8	0x85ED	# <CJK>
+0xF2C9	0x85D9	# <CJK>
+0xF2CA	0x85E1	# <CJK>
+0xF2CB	0x85E8	# <CJK>
+0xF2CC	0x85DA	# <CJK>
+0xF2CD	0x85D7	# <CJK>
+0xF2CE	0x85EC	# <CJK>
+0xF2CF	0x85F2	# <CJK>
+0xF2D0	0x85F8	# <CJK>
+0xF2D1	0x85D8	# <CJK>
+0xF2D2	0x85DF	# <CJK>
+0xF2D3	0x85E3	# <CJK>
+0xF2D4	0x85DC	# <CJK>
+0xF2D5	0x85D1	# <CJK>
+0xF2D6	0x85F0	# <CJK>
+0xF2D7	0x85E6	# <CJK>
+0xF2D8	0x85EF	# <CJK>
+0xF2D9	0x85DE	# <CJK>
+0xF2DA	0x85E2	# <CJK>
+0xF2DB	0x8800	# <CJK>
+0xF2DC	0x87FA	# <CJK>
+0xF2DD	0x8803	# <CJK>
+0xF2DE	0x87F6	# <CJK>
+0xF2DF	0x87F7	# <CJK>
+0xF2E0	0x8809	# <CJK>
+0xF2E1	0x880C	# <CJK>
+0xF2E2	0x880B	# <CJK>
+0xF2E3	0x8806	# <CJK>
+0xF2E4	0x87FC	# <CJK>
+0xF2E5	0x8808	# <CJK>
+0xF2E6	0x87FF	# <CJK>
+0xF2E7	0x880A	# <CJK>
+0xF2E8	0x8802	# <CJK>
+0xF2E9	0x8962	# <CJK>
+0xF2EA	0x895A	# <CJK>
+0xF2EB	0x895B	# <CJK>
+0xF2EC	0x8957	# <CJK>
+0xF2ED	0x8961	# <CJK>
+0xF2EE	0x895C	# <CJK>
+0xF2EF	0x8958	# <CJK>
+0xF2F0	0x895D	# <CJK>
+0xF2F1	0x8959	# <CJK>
+0xF2F2	0x8988	# <CJK>
+0xF2F3	0x89B7	# <CJK>
+0xF2F4	0x89B6	# <CJK>
+0xF2F5	0x89F6	# <CJK>
+0xF2F6	0x8B50	# <CJK>
+0xF2F7	0x8B48	# <CJK>
+0xF2F8	0x8B4A	# <CJK>
+0xF2F9	0x8B40	# <CJK>
+0xF2FA	0x8B53	# <CJK>
+0xF2FB	0x8B56	# <CJK>
+0xF2FC	0x8B54	# <CJK>
+0xF2FD	0x8B4B	# <CJK>
+0xF2FE	0x8B55	# <CJK>
+0xF340	0x8B51	# <CJK>
+0xF341	0x8B42	# <CJK>
+0xF342	0x8B52	# <CJK>
+0xF343	0x8B57	# <CJK>
+0xF344	0x8C43	# <CJK>
+0xF345	0x8C77	# <CJK>
+0xF346	0x8C76	# <CJK>
+0xF347	0x8C9A	# <CJK>
+0xF348	0x8D06	# <CJK>
+0xF349	0x8D07	# <CJK>
+0xF34A	0x8D09	# <CJK>
+0xF34B	0x8DAC	# <CJK>
+0xF34C	0x8DAA	# <CJK>
+0xF34D	0x8DAD	# <CJK>
+0xF34E	0x8DAB	# <CJK>
+0xF34F	0x8E6D	# <CJK>
+0xF350	0x8E78	# <CJK>
+0xF351	0x8E73	# <CJK>
+0xF352	0x8E6A	# <CJK>
+0xF353	0x8E6F	# <CJK>
+0xF354	0x8E7B	# <CJK>
+0xF355	0x8EC2	# <CJK>
+0xF356	0x8F52	# <CJK>
+0xF357	0x8F51	# <CJK>
+0xF358	0x8F4F	# <CJK>
+0xF359	0x8F50	# <CJK>
+0xF35A	0x8F53	# <CJK>
+0xF35B	0x8FB4	# <CJK>
+0xF35C	0x9140	# <CJK>
+0xF35D	0x913F	# <CJK>
+0xF35E	0x91B0	# <CJK>
+0xF35F	0x91AD	# <CJK>
+0xF360	0x93DE	# <CJK>
+0xF361	0x93C7	# <CJK>
+0xF362	0x93CF	# <CJK>
+0xF363	0x93C2	# <CJK>
+0xF364	0x93DA	# <CJK>
+0xF365	0x93D0	# <CJK>
+0xF366	0x93F9	# <CJK>
+0xF367	0x93EC	# <CJK>
+0xF368	0x93CC	# <CJK>
+0xF369	0x93D9	# <CJK>
+0xF36A	0x93A9	# <CJK>
+0xF36B	0x93E6	# <CJK>
+0xF36C	0x93CA	# <CJK>
+0xF36D	0x93D4	# <CJK>
+0xF36E	0x93EE	# <CJK>
+0xF36F	0x93E3	# <CJK>
+0xF370	0x93D5	# <CJK>
+0xF371	0x93C4	# <CJK>
+0xF372	0x93CE	# <CJK>
+0xF373	0x93C0	# <CJK>
+0xF374	0x93D2	# <CJK>
+0xF375	0x93E7	# <CJK>
+0xF376	0x957D	# <CJK>
+0xF377	0x95DA	# <CJK>
+0xF378	0x95DB	# <CJK>
+0xF379	0x96E1	# <CJK>
+0xF37A	0x9729	# <CJK>
+0xF37B	0x972B	# <CJK>
+0xF37C	0x972C	# <CJK>
+0xF37D	0x9728	# <CJK>
+0xF37E	0x9726	# <CJK>
+0xF3A1	0x97B3	# <CJK>
+0xF3A2	0x97B7	# <CJK>
+0xF3A3	0x97B6	# <CJK>
+0xF3A4	0x97DD	# <CJK>
+0xF3A5	0x97DE	# <CJK>
+0xF3A6	0x97DF	# <CJK>
+0xF3A7	0x985C	# <CJK>
+0xF3A8	0x9859	# <CJK>
+0xF3A9	0x985D	# <CJK>
+0xF3AA	0x9857	# <CJK>
+0xF3AB	0x98BF	# <CJK>
+0xF3AC	0x98BD	# <CJK>
+0xF3AD	0x98BB	# <CJK>
+0xF3AE	0x98BE	# <CJK>
+0xF3AF	0x9948	# <CJK>
+0xF3B0	0x9947	# <CJK>
+0xF3B1	0x9943	# <CJK>
+0xF3B2	0x99A6	# <CJK>
+0xF3B3	0x99A7	# <CJK>
+0xF3B4	0x9A1A	# <CJK>
+0xF3B5	0x9A15	# <CJK>
+0xF3B6	0x9A25	# <CJK>
+0xF3B7	0x9A1D	# <CJK>
+0xF3B8	0x9A24	# <CJK>
+0xF3B9	0x9A1B	# <CJK>
+0xF3BA	0x9A22	# <CJK>
+0xF3BB	0x9A20	# <CJK>
+0xF3BC	0x9A27	# <CJK>
+0xF3BD	0x9A23	# <CJK>
+0xF3BE	0x9A1E	# <CJK>
+0xF3BF	0x9A1C	# <CJK>
+0xF3C0	0x9A14	# <CJK>
+0xF3C1	0x9AC2	# <CJK>
+0xF3C2	0x9B0B	# <CJK>
+0xF3C3	0x9B0A	# <CJK>
+0xF3C4	0x9B0E	# <CJK>
+0xF3C5	0x9B0C	# <CJK>
+0xF3C6	0x9B37	# <CJK>
+0xF3C7	0x9BEA	# <CJK>
+0xF3C8	0x9BEB	# <CJK>
+0xF3C9	0x9BE0	# <CJK>
+0xF3CA	0x9BDE	# <CJK>
+0xF3CB	0x9BE4	# <CJK>
+0xF3CC	0x9BE6	# <CJK>
+0xF3CD	0x9BE2	# <CJK>
+0xF3CE	0x9BF0	# <CJK>
+0xF3CF	0x9BD4	# <CJK>
+0xF3D0	0x9BD7	# <CJK>
+0xF3D1	0x9BEC	# <CJK>
+0xF3D2	0x9BDC	# <CJK>
+0xF3D3	0x9BD9	# <CJK>
+0xF3D4	0x9BE5	# <CJK>
+0xF3D5	0x9BD5	# <CJK>
+0xF3D6	0x9BE1	# <CJK>
+0xF3D7	0x9BDA	# <CJK>
+0xF3D8	0x9D77	# <CJK>
+0xF3D9	0x9D81	# <CJK>
+0xF3DA	0x9D8A	# <CJK>
+0xF3DB	0x9D84	# <CJK>
+0xF3DC	0x9D88	# <CJK>
+0xF3DD	0x9D71	# <CJK>
+0xF3DE	0x9D80	# <CJK>
+0xF3DF	0x9D78	# <CJK>
+0xF3E0	0x9D86	# <CJK>
+0xF3E1	0x9D8B	# <CJK>
+0xF3E2	0x9D8C	# <CJK>
+0xF3E3	0x9D7D	# <CJK>
+0xF3E4	0x9D6B	# <CJK>
+0xF3E5	0x9D74	# <CJK>
+0xF3E6	0x9D75	# <CJK>
+0xF3E7	0x9D70	# <CJK>
+0xF3E8	0x9D69	# <CJK>
+0xF3E9	0x9D85	# <CJK>
+0xF3EA	0x9D73	# <CJK>
+0xF3EB	0x9D7B	# <CJK>
+0xF3EC	0x9D82	# <CJK>
+0xF3ED	0x9D6F	# <CJK>
+0xF3EE	0x9D79	# <CJK>
+0xF3EF	0x9D7F	# <CJK>
+0xF3F0	0x9D87	# <CJK>
+0xF3F1	0x9D68	# <CJK>
+0xF3F2	0x9E94	# <CJK>
+0xF3F3	0x9E91	# <CJK>
+0xF3F4	0x9EC0	# <CJK>
+0xF3F5	0x9EFC	# <CJK>
+0xF3F6	0x9F2D	# <CJK>
+0xF3F7	0x9F40	# <CJK>
+0xF3F8	0x9F41	# <CJK>
+0xF3F9	0x9F4D	# <CJK>
+0xF3FA	0x9F56	# <CJK>
+0xF3FB	0x9F57	# <CJK>
+0xF3FC	0x9F58	# <CJK>
+0xF3FD	0x5337	# <CJK>
+0xF3FE	0x56B2	# <CJK>
+0xF440	0x56B5	# <CJK>
+0xF441	0x56B3	# <CJK>
+0xF442	0x58E3	# <CJK>
+0xF443	0x5B45	# <CJK>
+0xF444	0x5DC6	# <CJK>
+0xF445	0x5DC7	# <CJK>
+0xF446	0x5EEE	# <CJK>
+0xF447	0x5EEF	# <CJK>
+0xF448	0x5FC0	# <CJK>
+0xF449	0x5FC1	# <CJK>
+0xF44A	0x61F9	# <CJK>
+0xF44B	0x6517	# <CJK>
+0xF44C	0x6516	# <CJK>
+0xF44D	0x6515	# <CJK>
+0xF44E	0x6513	# <CJK>
+0xF44F	0x65DF	# <CJK>
+0xF450	0x66E8	# <CJK>
+0xF451	0x66E3	# <CJK>
+0xF452	0x66E4	# <CJK>
+0xF453	0x6AF3	# <CJK>
+0xF454	0x6AF0	# <CJK>
+0xF455	0x6AEA	# <CJK>
+0xF456	0x6AE8	# <CJK>
+0xF457	0x6AF9	# <CJK>
+0xF458	0x6AF1	# <CJK>
+0xF459	0x6AEE	# <CJK>
+0xF45A	0x6AEF	# <CJK>
+0xF45B	0x703C	# <CJK>
+0xF45C	0x7035	# <CJK>
+0xF45D	0x702F	# <CJK>
+0xF45E	0x7037	# <CJK>
+0xF45F	0x7034	# <CJK>
+0xF460	0x7031	# <CJK>
+0xF461	0x7042	# <CJK>
+0xF462	0x7038	# <CJK>
+0xF463	0x703F	# <CJK>
+0xF464	0x703A	# <CJK>
+0xF465	0x7039	# <CJK>
+0xF466	0x7040	# <CJK>
+0xF467	0x703B	# <CJK>
+0xF468	0x7033	# <CJK>
+0xF469	0x7041	# <CJK>
+0xF46A	0x7213	# <CJK>
+0xF46B	0x7214	# <CJK>
+0xF46C	0x72A8	# <CJK>
+0xF46D	0x737D	# <CJK>
+0xF46E	0x737C	# <CJK>
+0xF46F	0x74BA	# <CJK>
+0xF470	0x76AB	# <CJK>
+0xF471	0x76AA	# <CJK>
+0xF472	0x76BE	# <CJK>
+0xF473	0x76ED	# <CJK>
+0xF474	0x77CC	# <CJK>
+0xF475	0x77CE	# <CJK>
+0xF476	0x77CF	# <CJK>
+0xF477	0x77CD	# <CJK>
+0xF478	0x77F2	# <CJK>
+0xF479	0x7925	# <CJK>
+0xF47A	0x7923	# <CJK>
+0xF47B	0x7927	# <CJK>
+0xF47C	0x7928	# <CJK>
+0xF47D	0x7924	# <CJK>
+0xF47E	0x7929	# <CJK>
+0xF4A1	0x79B2	# <CJK>
+0xF4A2	0x7A6E	# <CJK>
+0xF4A3	0x7A6C	# <CJK>
+0xF4A4	0x7A6D	# <CJK>
+0xF4A5	0x7AF7	# <CJK>
+0xF4A6	0x7C49	# <CJK>
+0xF4A7	0x7C48	# <CJK>
+0xF4A8	0x7C4A	# <CJK>
+0xF4A9	0x7C47	# <CJK>
+0xF4AA	0x7C45	# <CJK>
+0xF4AB	0x7CEE	# <CJK>
+0xF4AC	0x7E7B	# <CJK>
+0xF4AD	0x7E7E	# <CJK>
+0xF4AE	0x7E81	# <CJK>
+0xF4AF	0x7E80	# <CJK>
+0xF4B0	0x7FBA	# <CJK>
+0xF4B1	0x7FFF	# <CJK>
+0xF4B2	0x8079	# <CJK>
+0xF4B3	0x81DB	# <CJK>
+0xF4B4	0x81D9	# <CJK>
+0xF4B5	0x820B	# <CJK>
+0xF4B6	0x8268	# <CJK>
+0xF4B7	0x8269	# <CJK>
+0xF4B8	0x8622	# <CJK>
+0xF4B9	0x85FF	# <CJK>
+0xF4BA	0x8601	# <CJK>
+0xF4BB	0x85FE	# <CJK>
+0xF4BC	0x861B	# <CJK>
+0xF4BD	0x8600	# <CJK>
+0xF4BE	0x85F6	# <CJK>
+0xF4BF	0x8604	# <CJK>
+0xF4C0	0x8609	# <CJK>
+0xF4C1	0x8605	# <CJK>
+0xF4C2	0x860C	# <CJK>
+0xF4C3	0x85FD	# <CJK>
+0xF4C4	0x8819	# <CJK>
+0xF4C5	0x8810	# <CJK>
+0xF4C6	0x8811	# <CJK>
+0xF4C7	0x8817	# <CJK>
+0xF4C8	0x8813	# <CJK>
+0xF4C9	0x8816	# <CJK>
+0xF4CA	0x8963	# <CJK>
+0xF4CB	0x8966	# <CJK>
+0xF4CC	0x89B9	# <CJK>
+0xF4CD	0x89F7	# <CJK>
+0xF4CE	0x8B60	# <CJK>
+0xF4CF	0x8B6A	# <CJK>
+0xF4D0	0x8B5D	# <CJK>
+0xF4D1	0x8B68	# <CJK>
+0xF4D2	0x8B63	# <CJK>
+0xF4D3	0x8B65	# <CJK>
+0xF4D4	0x8B67	# <CJK>
+0xF4D5	0x8B6D	# <CJK>
+0xF4D6	0x8DAE	# <CJK>
+0xF4D7	0x8E86	# <CJK>
+0xF4D8	0x8E88	# <CJK>
+0xF4D9	0x8E84	# <CJK>
+0xF4DA	0x8F59	# <CJK>
+0xF4DB	0x8F56	# <CJK>
+0xF4DC	0x8F57	# <CJK>
+0xF4DD	0x8F55	# <CJK>
+0xF4DE	0x8F58	# <CJK>
+0xF4DF	0x8F5A	# <CJK>
+0xF4E0	0x908D	# <CJK>
+0xF4E1	0x9143	# <CJK>
+0xF4E2	0x9141	# <CJK>
+0xF4E3	0x91B7	# <CJK>
+0xF4E4	0x91B5	# <CJK>
+0xF4E5	0x91B2	# <CJK>
+0xF4E6	0x91B3	# <CJK>
+0xF4E7	0x940B	# <CJK>
+0xF4E8	0x9413	# <CJK>
+0xF4E9	0x93FB	# <CJK>
+0xF4EA	0x9420	# <CJK>
+0xF4EB	0x940F	# <CJK>
+0xF4EC	0x9414	# <CJK>
+0xF4ED	0x93FE	# <CJK>
+0xF4EE	0x9415	# <CJK>
+0xF4EF	0x9410	# <CJK>
+0xF4F0	0x9428	# <CJK>
+0xF4F1	0x9419	# <CJK>
+0xF4F2	0x940D	# <CJK>
+0xF4F3	0x93F5	# <CJK>
+0xF4F4	0x9400	# <CJK>
+0xF4F5	0x93F7	# <CJK>
+0xF4F6	0x9407	# <CJK>
+0xF4F7	0x940E	# <CJK>
+0xF4F8	0x9416	# <CJK>
+0xF4F9	0x9412	# <CJK>
+0xF4FA	0x93FA	# <CJK>
+0xF4FB	0x9409	# <CJK>
+0xF4FC	0x93F8	# <CJK>
+0xF4FD	0x940A	# <CJK>
+0xF4FE	0x93FF	# <CJK>
+0xF540	0x93FC	# <CJK>
+0xF541	0x940C	# <CJK>
+0xF542	0x93F6	# <CJK>
+0xF543	0x9411	# <CJK>
+0xF544	0x9406	# <CJK>
+0xF545	0x95DE	# <CJK>
+0xF546	0x95E0	# <CJK>
+0xF547	0x95DF	# <CJK>
+0xF548	0x972E	# <CJK>
+0xF549	0x972F	# <CJK>
+0xF54A	0x97B9	# <CJK>
+0xF54B	0x97BB	# <CJK>
+0xF54C	0x97FD	# <CJK>
+0xF54D	0x97FE	# <CJK>
+0xF54E	0x9860	# <CJK>
+0xF54F	0x9862	# <CJK>
+0xF550	0x9863	# <CJK>
+0xF551	0x985F	# <CJK>
+0xF552	0x98C1	# <CJK>
+0xF553	0x98C2	# <CJK>
+0xF554	0x9950	# <CJK>
+0xF555	0x994E	# <CJK>
+0xF556	0x9959	# <CJK>
+0xF557	0x994C	# <CJK>
+0xF558	0x994B	# <CJK>
+0xF559	0x9953	# <CJK>
+0xF55A	0x9A32	# <CJK>
+0xF55B	0x9A34	# <CJK>
+0xF55C	0x9A31	# <CJK>
+0xF55D	0x9A2C	# <CJK>
+0xF55E	0x9A2A	# <CJK>
+0xF55F	0x9A36	# <CJK>
+0xF560	0x9A29	# <CJK>
+0xF561	0x9A2E	# <CJK>
+0xF562	0x9A38	# <CJK>
+0xF563	0x9A2D	# <CJK>
+0xF564	0x9AC7	# <CJK>
+0xF565	0x9ACA	# <CJK>
+0xF566	0x9AC6	# <CJK>
+0xF567	0x9B10	# <CJK>
+0xF568	0x9B12	# <CJK>
+0xF569	0x9B11	# <CJK>
+0xF56A	0x9C0B	# <CJK>
+0xF56B	0x9C08	# <CJK>
+0xF56C	0x9BF7	# <CJK>
+0xF56D	0x9C05	# <CJK>
+0xF56E	0x9C12	# <CJK>
+0xF56F	0x9BF8	# <CJK>
+0xF570	0x9C40	# <CJK>
+0xF571	0x9C07	# <CJK>
+0xF572	0x9C0E	# <CJK>
+0xF573	0x9C06	# <CJK>
+0xF574	0x9C17	# <CJK>
+0xF575	0x9C14	# <CJK>
+0xF576	0x9C09	# <CJK>
+0xF577	0x9D9F	# <CJK>
+0xF578	0x9D99	# <CJK>
+0xF579	0x9DA4	# <CJK>
+0xF57A	0x9D9D	# <CJK>
+0xF57B	0x9D92	# <CJK>
+0xF57C	0x9D98	# <CJK>
+0xF57D	0x9D90	# <CJK>
+0xF57E	0x9D9B	# <CJK>
+0xF5A1	0x9DA0	# <CJK>
+0xF5A2	0x9D94	# <CJK>
+0xF5A3	0x9D9C	# <CJK>
+0xF5A4	0x9DAA	# <CJK>
+0xF5A5	0x9D97	# <CJK>
+0xF5A6	0x9DA1	# <CJK>
+0xF5A7	0x9D9A	# <CJK>
+0xF5A8	0x9DA2	# <CJK>
+0xF5A9	0x9DA8	# <CJK>
+0xF5AA	0x9D9E	# <CJK>
+0xF5AB	0x9DA3	# <CJK>
+0xF5AC	0x9DBF	# <CJK>
+0xF5AD	0x9DA9	# <CJK>
+0xF5AE	0x9D96	# <CJK>
+0xF5AF	0x9DA6	# <CJK>
+0xF5B0	0x9DA7	# <CJK>
+0xF5B1	0x9E99	# <CJK>
+0xF5B2	0x9E9B	# <CJK>
+0xF5B3	0x9E9A	# <CJK>
+0xF5B4	0x9EE5	# <CJK>
+0xF5B5	0x9EE4	# <CJK>
+0xF5B6	0x9EE7	# <CJK>
+0xF5B7	0x9EE6	# <CJK>
+0xF5B8	0x9F30	# <CJK>
+0xF5B9	0x9F2E	# <CJK>
+0xF5BA	0x9F5B	# <CJK>
+0xF5BB	0x9F60	# <CJK>
+0xF5BC	0x9F5E	# <CJK>
+0xF5BD	0x9F5D	# <CJK>
+0xF5BE	0x9F59	# <CJK>
+0xF5BF	0x9F91	# <CJK>
+0xF5C0	0x513A	# <CJK>
+0xF5C1	0x5139	# <CJK>
+0xF5C2	0x5298	# <CJK>
+0xF5C3	0x5297	# <CJK>
+0xF5C4	0x56C3	# <CJK>
+0xF5C5	0x56BD	# <CJK>
+0xF5C6	0x56BE	# <CJK>
+0xF5C7	0x5B48	# <CJK>
+0xF5C8	0x5B47	# <CJK>
+0xF5C9	0x5DCB	# <CJK>
+0xF5CA	0x5DCF	# <CJK>
+0xF5CB	0x5EF1	# <CJK>
+0xF5CC	0x61FD	# <CJK>
+0xF5CD	0x651B	# <CJK>
+0xF5CE	0x6B02	# <CJK>
+0xF5CF	0x6AFC	# <CJK>
+0xF5D0	0x6B03	# <CJK>
+0xF5D1	0x6AF8	# <CJK>
+0xF5D2	0x6B00	# <CJK>
+0xF5D3	0x7043	# <CJK>
+0xF5D4	0x7044	# <CJK>
+0xF5D5	0x704A	# <CJK>
+0xF5D6	0x7048	# <CJK>
+0xF5D7	0x7049	# <CJK>
+0xF5D8	0x7045	# <CJK>
+0xF5D9	0x7046	# <CJK>
+0xF5DA	0x721D	# <CJK>
+0xF5DB	0x721A	# <CJK>
+0xF5DC	0x7219	# <CJK>
+0xF5DD	0x737E	# <CJK>
+0xF5DE	0x7517	# <CJK>
+0xF5DF	0x766A	# <CJK>
+0xF5E0	0x77D0	# <CJK>
+0xF5E1	0x792D	# <CJK>
+0xF5E2	0x7931	# <CJK>
+0xF5E3	0x792F	# <CJK>
+0xF5E4	0x7C54	# <CJK>
+0xF5E5	0x7C53	# <CJK>
+0xF5E6	0x7CF2	# <CJK>
+0xF5E7	0x7E8A	# <CJK>
+0xF5E8	0x7E87	# <CJK>
+0xF5E9	0x7E88	# <CJK>
+0xF5EA	0x7E8B	# <CJK>
+0xF5EB	0x7E86	# <CJK>
+0xF5EC	0x7E8D	# <CJK>
+0xF5ED	0x7F4D	# <CJK>
+0xF5EE	0x7FBB	# <CJK>
+0xF5EF	0x8030	# <CJK>
+0xF5F0	0x81DD	# <CJK>
+0xF5F1	0x8618	# <CJK>
+0xF5F2	0x862A	# <CJK>
+0xF5F3	0x8626	# <CJK>
+0xF5F4	0x861F	# <CJK>
+0xF5F5	0x8623	# <CJK>
+0xF5F6	0x861C	# <CJK>
+0xF5F7	0x8619	# <CJK>
+0xF5F8	0x8627	# <CJK>
+0xF5F9	0x862E	# <CJK>
+0xF5FA	0x8621	# <CJK>
+0xF5FB	0x8620	# <CJK>
+0xF5FC	0x8629	# <CJK>
+0xF5FD	0x861E	# <CJK>
+0xF5FE	0x8625	# <CJK>
+0xF640	0x8829	# <CJK>
+0xF641	0x881D	# <CJK>
+0xF642	0x881B	# <CJK>
+0xF643	0x8820	# <CJK>
+0xF644	0x8824	# <CJK>
+0xF645	0x881C	# <CJK>
+0xF646	0x882B	# <CJK>
+0xF647	0x884A	# <CJK>
+0xF648	0x896D	# <CJK>
+0xF649	0x8969	# <CJK>
+0xF64A	0x896E	# <CJK>
+0xF64B	0x896B	# <CJK>
+0xF64C	0x89FA	# <CJK>
+0xF64D	0x8B79	# <CJK>
+0xF64E	0x8B78	# <CJK>
+0xF64F	0x8B45	# <CJK>
+0xF650	0x8B7A	# <CJK>
+0xF651	0x8B7B	# <CJK>
+0xF652	0x8D10	# <CJK>
+0xF653	0x8D14	# <CJK>
+0xF654	0x8DAF	# <CJK>
+0xF655	0x8E8E	# <CJK>
+0xF656	0x8E8C	# <CJK>
+0xF657	0x8F5E	# <CJK>
+0xF658	0x8F5B	# <CJK>
+0xF659	0x8F5D	# <CJK>
+0xF65A	0x9146	# <CJK>
+0xF65B	0x9144	# <CJK>
+0xF65C	0x9145	# <CJK>
+0xF65D	0x91B9	# <CJK>
+0xF65E	0x943F	# <CJK>
+0xF65F	0x943B	# <CJK>
+0xF660	0x9436	# <CJK>
+0xF661	0x9429	# <CJK>
+0xF662	0x943D	# <CJK>
+0xF663	0x943C	# <CJK>
+0xF664	0x9430	# <CJK>
+0xF665	0x9439	# <CJK>
+0xF666	0x942A	# <CJK>
+0xF667	0x9437	# <CJK>
+0xF668	0x942C	# <CJK>
+0xF669	0x9440	# <CJK>
+0xF66A	0x9431	# <CJK>
+0xF66B	0x95E5	# <CJK>
+0xF66C	0x95E4	# <CJK>
+0xF66D	0x95E3	# <CJK>
+0xF66E	0x9735	# <CJK>
+0xF66F	0x973A	# <CJK>
+0xF670	0x97BF	# <CJK>
+0xF671	0x97E1	# <CJK>
+0xF672	0x9864	# <CJK>
+0xF673	0x98C9	# <CJK>
+0xF674	0x98C6	# <CJK>
+0xF675	0x98C0	# <CJK>
+0xF676	0x9958	# <CJK>
+0xF677	0x9956	# <CJK>
+0xF678	0x9A39	# <CJK>
+0xF679	0x9A3D	# <CJK>
+0xF67A	0x9A46	# <CJK>
+0xF67B	0x9A44	# <CJK>
+0xF67C	0x9A42	# <CJK>
+0xF67D	0x9A41	# <CJK>
+0xF67E	0x9A3A	# <CJK>
+0xF6A1	0x9A3F	# <CJK>
+0xF6A2	0x9ACD	# <CJK>
+0xF6A3	0x9B15	# <CJK>
+0xF6A4	0x9B17	# <CJK>
+0xF6A5	0x9B18	# <CJK>
+0xF6A6	0x9B16	# <CJK>
+0xF6A7	0x9B3A	# <CJK>
+0xF6A8	0x9B52	# <CJK>
+0xF6A9	0x9C2B	# <CJK>
+0xF6AA	0x9C1D	# <CJK>
+0xF6AB	0x9C1C	# <CJK>
+0xF6AC	0x9C2C	# <CJK>
+0xF6AD	0x9C23	# <CJK>
+0xF6AE	0x9C28	# <CJK>
+0xF6AF	0x9C29	# <CJK>
+0xF6B0	0x9C24	# <CJK>
+0xF6B1	0x9C21	# <CJK>
+0xF6B2	0x9DB7	# <CJK>
+0xF6B3	0x9DB6	# <CJK>
+0xF6B4	0x9DBC	# <CJK>
+0xF6B5	0x9DC1	# <CJK>
+0xF6B6	0x9DC7	# <CJK>
+0xF6B7	0x9DCA	# <CJK>
+0xF6B8	0x9DCF	# <CJK>
+0xF6B9	0x9DBE	# <CJK>
+0xF6BA	0x9DC5	# <CJK>
+0xF6BB	0x9DC3	# <CJK>
+0xF6BC	0x9DBB	# <CJK>
+0xF6BD	0x9DB5	# <CJK>
+0xF6BE	0x9DCE	# <CJK>
+0xF6BF	0x9DB9	# <CJK>
+0xF6C0	0x9DBA	# <CJK>
+0xF6C1	0x9DAC	# <CJK>
+0xF6C2	0x9DC8	# <CJK>
+0xF6C3	0x9DB1	# <CJK>
+0xF6C4	0x9DAD	# <CJK>
+0xF6C5	0x9DCC	# <CJK>
+0xF6C6	0x9DB3	# <CJK>
+0xF6C7	0x9DCD	# <CJK>
+0xF6C8	0x9DB2	# <CJK>
+0xF6C9	0x9E7A	# <CJK>
+0xF6CA	0x9E9C	# <CJK>
+0xF6CB	0x9EEB	# <CJK>
+0xF6CC	0x9EEE	# <CJK>
+0xF6CD	0x9EED	# <CJK>
+0xF6CE	0x9F1B	# <CJK>
+0xF6CF	0x9F18	# <CJK>
+0xF6D0	0x9F1A	# <CJK>
+0xF6D1	0x9F31	# <CJK>
+0xF6D2	0x9F4E	# <CJK>
+0xF6D3	0x9F65	# <CJK>
+0xF6D4	0x9F64	# <CJK>
+0xF6D5	0x9F92	# <CJK>
+0xF6D6	0x4EB9	# <CJK>
+0xF6D7	0x56C6	# <CJK>
+0xF6D8	0x56C5	# <CJK>
+0xF6D9	0x56CB	# <CJK>
+0xF6DA	0x5971	# <CJK>
+0xF6DB	0x5B4B	# <CJK>
+0xF6DC	0x5B4C	# <CJK>
+0xF6DD	0x5DD5	# <CJK>
+0xF6DE	0x5DD1	# <CJK>
+0xF6DF	0x5EF2	# <CJK>
+0xF6E0	0x6521	# <CJK>
+0xF6E1	0x6520	# <CJK>
+0xF6E2	0x6526	# <CJK>
+0xF6E3	0x6522	# <CJK>
+0xF6E4	0x6B0B	# <CJK>
+0xF6E5	0x6B08	# <CJK>
+0xF6E6	0x6B09	# <CJK>
+0xF6E7	0x6C0D	# <CJK>
+0xF6E8	0x7055	# <CJK>
+0xF6E9	0x7056	# <CJK>
+0xF6EA	0x7057	# <CJK>
+0xF6EB	0x7052	# <CJK>
+0xF6EC	0x721E	# <CJK>
+0xF6ED	0x721F	# <CJK>
+0xF6EE	0x72A9	# <CJK>
+0xF6EF	0x737F	# <CJK>
+0xF6F0	0x74D8	# <CJK>
+0xF6F1	0x74D5	# <CJK>
+0xF6F2	0x74D9	# <CJK>
+0xF6F3	0x74D7	# <CJK>
+0xF6F4	0x766D	# <CJK>
+0xF6F5	0x76AD	# <CJK>
+0xF6F6	0x7935	# <CJK>
+0xF6F7	0x79B4	# <CJK>
+0xF6F8	0x7A70	# <CJK>
+0xF6F9	0x7A71	# <CJK>
+0xF6FA	0x7C57	# <CJK>
+0xF6FB	0x7C5C	# <CJK>
+0xF6FC	0x7C59	# <CJK>
+0xF6FD	0x7C5B	# <CJK>
+0xF6FE	0x7C5A	# <CJK>
+0xF740	0x7CF4	# <CJK>
+0xF741	0x7CF1	# <CJK>
+0xF742	0x7E91	# <CJK>
+0xF743	0x7F4F	# <CJK>
+0xF744	0x7F87	# <CJK>
+0xF745	0x81DE	# <CJK>
+0xF746	0x826B	# <CJK>
+0xF747	0x8634	# <CJK>
+0xF748	0x8635	# <CJK>
+0xF749	0x8633	# <CJK>
+0xF74A	0x862C	# <CJK>
+0xF74B	0x8632	# <CJK>
+0xF74C	0x8636	# <CJK>
+0xF74D	0x882C	# <CJK>
+0xF74E	0x8828	# <CJK>
+0xF74F	0x8826	# <CJK>
+0xF750	0x882A	# <CJK>
+0xF751	0x8825	# <CJK>
+0xF752	0x8971	# <CJK>
+0xF753	0x89BF	# <CJK>
+0xF754	0x89BE	# <CJK>
+0xF755	0x89FB	# <CJK>
+0xF756	0x8B7E	# <CJK>
+0xF757	0x8B84	# <CJK>
+0xF758	0x8B82	# <CJK>
+0xF759	0x8B86	# <CJK>
+0xF75A	0x8B85	# <CJK>
+0xF75B	0x8B7F	# <CJK>
+0xF75C	0x8D15	# <CJK>
+0xF75D	0x8E95	# <CJK>
+0xF75E	0x8E94	# <CJK>
+0xF75F	0x8E9A	# <CJK>
+0xF760	0x8E92	# <CJK>
+0xF761	0x8E90	# <CJK>
+0xF762	0x8E96	# <CJK>
+0xF763	0x8E97	# <CJK>
+0xF764	0x8F60	# <CJK>
+0xF765	0x8F62	# <CJK>
+0xF766	0x9147	# <CJK>
+0xF767	0x944C	# <CJK>
+0xF768	0x9450	# <CJK>
+0xF769	0x944A	# <CJK>
+0xF76A	0x944B	# <CJK>
+0xF76B	0x944F	# <CJK>
+0xF76C	0x9447	# <CJK>
+0xF76D	0x9445	# <CJK>
+0xF76E	0x9448	# <CJK>
+0xF76F	0x9449	# <CJK>
+0xF770	0x9446	# <CJK>
+0xF771	0x973F	# <CJK>
+0xF772	0x97E3	# <CJK>
+0xF773	0x986A	# <CJK>
+0xF774	0x9869	# <CJK>
+0xF775	0x98CB	# <CJK>
+0xF776	0x9954	# <CJK>
+0xF777	0x995B	# <CJK>
+0xF778	0x9A4E	# <CJK>
+0xF779	0x9A53	# <CJK>
+0xF77A	0x9A54	# <CJK>
+0xF77B	0x9A4C	# <CJK>
+0xF77C	0x9A4F	# <CJK>
+0xF77D	0x9A48	# <CJK>
+0xF77E	0x9A4A	# <CJK>
+0xF7A1	0x9A49	# <CJK>
+0xF7A2	0x9A52	# <CJK>
+0xF7A3	0x9A50	# <CJK>
+0xF7A4	0x9AD0	# <CJK>
+0xF7A5	0x9B19	# <CJK>
+0xF7A6	0x9B2B	# <CJK>
+0xF7A7	0x9B3B	# <CJK>
+0xF7A8	0x9B56	# <CJK>
+0xF7A9	0x9B55	# <CJK>
+0xF7AA	0x9C46	# <CJK>
+0xF7AB	0x9C48	# <CJK>
+0xF7AC	0x9C3F	# <CJK>
+0xF7AD	0x9C44	# <CJK>
+0xF7AE	0x9C39	# <CJK>
+0xF7AF	0x9C33	# <CJK>
+0xF7B0	0x9C41	# <CJK>
+0xF7B1	0x9C3C	# <CJK>
+0xF7B2	0x9C37	# <CJK>
+0xF7B3	0x9C34	# <CJK>
+0xF7B4	0x9C32	# <CJK>
+0xF7B5	0x9C3D	# <CJK>
+0xF7B6	0x9C36	# <CJK>
+0xF7B7	0x9DDB	# <CJK>
+0xF7B8	0x9DD2	# <CJK>
+0xF7B9	0x9DDE	# <CJK>
+0xF7BA	0x9DDA	# <CJK>
+0xF7BB	0x9DCB	# <CJK>
+0xF7BC	0x9DD0	# <CJK>
+0xF7BD	0x9DDC	# <CJK>
+0xF7BE	0x9DD1	# <CJK>
+0xF7BF	0x9DDF	# <CJK>
+0xF7C0	0x9DE9	# <CJK>
+0xF7C1	0x9DD9	# <CJK>
+0xF7C2	0x9DD8	# <CJK>
+0xF7C3	0x9DD6	# <CJK>
+0xF7C4	0x9DF5	# <CJK>
+0xF7C5	0x9DD5	# <CJK>
+0xF7C6	0x9DDD	# <CJK>
+0xF7C7	0x9EB6	# <CJK>
+0xF7C8	0x9EF0	# <CJK>
+0xF7C9	0x9F35	# <CJK>
+0xF7CA	0x9F33	# <CJK>
+0xF7CB	0x9F32	# <CJK>
+0xF7CC	0x9F42	# <CJK>
+0xF7CD	0x9F6B	# <CJK>
+0xF7CE	0x9F95	# <CJK>
+0xF7CF	0x9FA2	# <CJK>
+0xF7D0	0x513D	# <CJK>
+0xF7D1	0x5299	# <CJK>
+0xF7D2	0x58E8	# <CJK>
+0xF7D3	0x58E7	# <CJK>
+0xF7D4	0x5972	# <CJK>
+0xF7D5	0x5B4D	# <CJK>
+0xF7D6	0x5DD8	# <CJK>
+0xF7D7	0x882F	# <CJK>
+0xF7D8	0x5F4F	# <CJK>
+0xF7D9	0x6201	# <CJK>
+0xF7DA	0x6203	# <CJK>
+0xF7DB	0x6204	# <CJK>
+0xF7DC	0x6529	# <CJK>
+0xF7DD	0x6525	# <CJK>
+0xF7DE	0x6596	# <CJK>
+0xF7DF	0x66EB	# <CJK>
+0xF7E0	0x6B11	# <CJK>
+0xF7E1	0x6B12	# <CJK>
+0xF7E2	0x6B0F	# <CJK>
+0xF7E3	0x6BCA	# <CJK>
+0xF7E4	0x705B	# <CJK>
+0xF7E5	0x705A	# <CJK>
+0xF7E6	0x7222	# <CJK>
+0xF7E7	0x7382	# <CJK>
+0xF7E8	0x7381	# <CJK>
+0xF7E9	0x7383	# <CJK>
+0xF7EA	0x7670	# <CJK>
+0xF7EB	0x77D4	# <CJK>
+0xF7EC	0x7C67	# <CJK>
+0xF7ED	0x7C66	# <CJK>
+0xF7EE	0x7E95	# <CJK>
+0xF7EF	0x826C	# <CJK>
+0xF7F0	0x863A	# <CJK>
+0xF7F1	0x8640	# <CJK>
+0xF7F2	0x8639	# <CJK>
+0xF7F3	0x863C	# <CJK>
+0xF7F4	0x8631	# <CJK>
+0xF7F5	0x863B	# <CJK>
+0xF7F6	0x863E	# <CJK>
+0xF7F7	0x8830	# <CJK>
+0xF7F8	0x8832	# <CJK>
+0xF7F9	0x882E	# <CJK>
+0xF7FA	0x8833	# <CJK>
+0xF7FB	0x8976	# <CJK>
+0xF7FC	0x8974	# <CJK>
+0xF7FD	0x8973	# <CJK>
+0xF7FE	0x89FE	# <CJK>
+0xF840	0x8B8C	# <CJK>
+0xF841	0x8B8E	# <CJK>
+0xF842	0x8B8B	# <CJK>
+0xF843	0x8B88	# <CJK>
+0xF844	0x8C45	# <CJK>
+0xF845	0x8D19	# <CJK>
+0xF846	0x8E98	# <CJK>
+0xF847	0x8F64	# <CJK>
+0xF848	0x8F63	# <CJK>
+0xF849	0x91BC	# <CJK>
+0xF84A	0x9462	# <CJK>
+0xF84B	0x9455	# <CJK>
+0xF84C	0x945D	# <CJK>
+0xF84D	0x9457	# <CJK>
+0xF84E	0x945E	# <CJK>
+0xF84F	0x97C4	# <CJK>
+0xF850	0x97C5	# <CJK>
+0xF851	0x9800	# <CJK>
+0xF852	0x9A56	# <CJK>
+0xF853	0x9A59	# <CJK>
+0xF854	0x9B1E	# <CJK>
+0xF855	0x9B1F	# <CJK>
+0xF856	0x9B20	# <CJK>
+0xF857	0x9C52	# <CJK>
+0xF858	0x9C58	# <CJK>
+0xF859	0x9C50	# <CJK>
+0xF85A	0x9C4A	# <CJK>
+0xF85B	0x9C4D	# <CJK>
+0xF85C	0x9C4B	# <CJK>
+0xF85D	0x9C55	# <CJK>
+0xF85E	0x9C59	# <CJK>
+0xF85F	0x9C4C	# <CJK>
+0xF860	0x9C4E	# <CJK>
+0xF861	0x9DFB	# <CJK>
+0xF862	0x9DF7	# <CJK>
+0xF863	0x9DEF	# <CJK>
+0xF864	0x9DE3	# <CJK>
+0xF865	0x9DEB	# <CJK>
+0xF866	0x9DF8	# <CJK>
+0xF867	0x9DE4	# <CJK>
+0xF868	0x9DF6	# <CJK>
+0xF869	0x9DE1	# <CJK>
+0xF86A	0x9DEE	# <CJK>
+0xF86B	0x9DE6	# <CJK>
+0xF86C	0x9DF2	# <CJK>
+0xF86D	0x9DF0	# <CJK>
+0xF86E	0x9DE2	# <CJK>
+0xF86F	0x9DEC	# <CJK>
+0xF870	0x9DF4	# <CJK>
+0xF871	0x9DF3	# <CJK>
+0xF872	0x9DE8	# <CJK>
+0xF873	0x9DED	# <CJK>
+0xF874	0x9EC2	# <CJK>
+0xF875	0x9ED0	# <CJK>
+0xF876	0x9EF2	# <CJK>
+0xF877	0x9EF3	# <CJK>
+0xF878	0x9F06	# <CJK>
+0xF879	0x9F1C	# <CJK>
+0xF87A	0x9F38	# <CJK>
+0xF87B	0x9F37	# <CJK>
+0xF87C	0x9F36	# <CJK>
+0xF87D	0x9F43	# <CJK>
+0xF87E	0x9F4F	# <CJK>
+0xF8A1	0x9F71	# <CJK>
+0xF8A2	0x9F70	# <CJK>
+0xF8A3	0x9F6E	# <CJK>
+0xF8A4	0x9F6F	# <CJK>
+0xF8A5	0x56D3	# <CJK>
+0xF8A6	0x56CD	# <CJK>
+0xF8A7	0x5B4E	# <CJK>
+0xF8A8	0x5C6D	# <CJK>
+0xF8A9	0x652D	# <CJK>
+0xF8AA	0x66ED	# <CJK>
+0xF8AB	0x66EE	# <CJK>
+0xF8AC	0x6B13	# <CJK>
+0xF8AD	0x705F	# <CJK>
+0xF8AE	0x7061	# <CJK>
+0xF8AF	0x705D	# <CJK>
+0xF8B0	0x7060	# <CJK>
+0xF8B1	0x7223	# <CJK>
+0xF8B2	0x74DB	# <CJK>
+0xF8B3	0x74E5	# <CJK>
+0xF8B4	0x77D5	# <CJK>
+0xF8B5	0x7938	# <CJK>
+0xF8B6	0x79B7	# <CJK>
+0xF8B7	0x79B6	# <CJK>
+0xF8B8	0x7C6A	# <CJK>
+0xF8B9	0x7E97	# <CJK>
+0xF8BA	0x7F89	# <CJK>
+0xF8BB	0x826D	# <CJK>
+0xF8BC	0x8643	# <CJK>
+0xF8BD	0x8838	# <CJK>
+0xF8BE	0x8837	# <CJK>
+0xF8BF	0x8835	# <CJK>
+0xF8C0	0x884B	# <CJK>
+0xF8C1	0x8B94	# <CJK>
+0xF8C2	0x8B95	# <CJK>
+0xF8C3	0x8E9E	# <CJK>
+0xF8C4	0x8E9F	# <CJK>
+0xF8C5	0x8EA0	# <CJK>
+0xF8C6	0x8E9D	# <CJK>
+0xF8C7	0x91BE	# <CJK>
+0xF8C8	0x91BD	# <CJK>
+0xF8C9	0x91C2	# <CJK>
+0xF8CA	0x946B	# <CJK>
+0xF8CB	0x9468	# <CJK>
+0xF8CC	0x9469	# <CJK>
+0xF8CD	0x96E5	# <CJK>
+0xF8CE	0x9746	# <CJK>
+0xF8CF	0x9743	# <CJK>
+0xF8D0	0x9747	# <CJK>
+0xF8D1	0x97C7	# <CJK>
+0xF8D2	0x97E5	# <CJK>
+0xF8D3	0x9A5E	# <CJK>
+0xF8D4	0x9AD5	# <CJK>
+0xF8D5	0x9B59	# <CJK>
+0xF8D6	0x9C63	# <CJK>
+0xF8D7	0x9C67	# <CJK>
+0xF8D8	0x9C66	# <CJK>
+0xF8D9	0x9C62	# <CJK>
+0xF8DA	0x9C5E	# <CJK>
+0xF8DB	0x9C60	# <CJK>
+0xF8DC	0x9E02	# <CJK>
+0xF8DD	0x9DFE	# <CJK>
+0xF8DE	0x9E07	# <CJK>
+0xF8DF	0x9E03	# <CJK>
+0xF8E0	0x9E06	# <CJK>
+0xF8E1	0x9E05	# <CJK>
+0xF8E2	0x9E00	# <CJK>
+0xF8E3	0x9E01	# <CJK>
+0xF8E4	0x9E09	# <CJK>
+0xF8E5	0x9DFF	# <CJK>
+0xF8E6	0x9DFD	# <CJK>
+0xF8E7	0x9E04	# <CJK>
+0xF8E8	0x9EA0	# <CJK>
+0xF8E9	0x9F1E	# <CJK>
+0xF8EA	0x9F46	# <CJK>
+0xF8EB	0x9F74	# <CJK>
+0xF8EC	0x9F75	# <CJK>
+0xF8ED	0x9F76	# <CJK>
+0xF8EE	0x56D4	# <CJK>
+0xF8EF	0x652E	# <CJK>
+0xF8F0	0x65B8	# <CJK>
+0xF8F1	0x6B18	# <CJK>
+0xF8F2	0x6B19	# <CJK>
+0xF8F3	0x6B17	# <CJK>
+0xF8F4	0x6B1A	# <CJK>
+0xF8F5	0x7062	# <CJK>
+0xF8F6	0x7226	# <CJK>
+0xF8F7	0x72AA	# <CJK>
+0xF8F8	0x77D8	# <CJK>
+0xF8F9	0x77D9	# <CJK>
+0xF8FA	0x7939	# <CJK>
+0xF8FB	0x7C69	# <CJK>
+0xF8FC	0x7C6B	# <CJK>
+0xF8FD	0x7CF6	# <CJK>
+0xF8FE	0x7E9A	# <CJK>
+0xF940	0x7E98	# <CJK>
+0xF941	0x7E9B	# <CJK>
+0xF942	0x7E99	# <CJK>
+0xF943	0x81E0	# <CJK>
+0xF944	0x81E1	# <CJK>
+0xF945	0x8646	# <CJK>
+0xF946	0x8647	# <CJK>
+0xF947	0x8648	# <CJK>
+0xF948	0x8979	# <CJK>
+0xF949	0x897A	# <CJK>
+0xF94A	0x897C	# <CJK>
+0xF94B	0x897B	# <CJK>
+0xF94C	0x89FF	# <CJK>
+0xF94D	0x8B98	# <CJK>
+0xF94E	0x8B99	# <CJK>
+0xF94F	0x8EA5	# <CJK>
+0xF950	0x8EA4	# <CJK>
+0xF951	0x8EA3	# <CJK>
+0xF952	0x946E	# <CJK>
+0xF953	0x946D	# <CJK>
+0xF954	0x946F	# <CJK>
+0xF955	0x9471	# <CJK>
+0xF956	0x9473	# <CJK>
+0xF957	0x9749	# <CJK>
+0xF958	0x9872	# <CJK>
+0xF959	0x995F	# <CJK>
+0xF95A	0x9C68	# <CJK>
+0xF95B	0x9C6E	# <CJK>
+0xF95C	0x9C6D	# <CJK>
+0xF95D	0x9E0B	# <CJK>
+0xF95E	0x9E0D	# <CJK>
+0xF95F	0x9E10	# <CJK>
+0xF960	0x9E0F	# <CJK>
+0xF961	0x9E12	# <CJK>
+0xF962	0x9E11	# <CJK>
+0xF963	0x9EA1	# <CJK>
+0xF964	0x9EF5	# <CJK>
+0xF965	0x9F09	# <CJK>
+0xF966	0x9F47	# <CJK>
+0xF967	0x9F78	# <CJK>
+0xF968	0x9F7B	# <CJK>
+0xF969	0x9F7A	# <CJK>
+0xF96A	0x9F79	# <CJK>
+0xF96B	0x571E	# <CJK>
+0xF96C	0x7066	# <CJK>
+0xF96D	0x7C6F	# <CJK>
+0xF96E	0x883C	# <CJK>
+0xF96F	0x8DB2	# <CJK>
+0xF970	0x8EA6	# <CJK>
+0xF971	0x91C3	# <CJK>
+0xF972	0x9474	# <CJK>
+0xF973	0x9478	# <CJK>
+0xF974	0x9476	# <CJK>
+0xF975	0x9475	# <CJK>
+0xF976	0x9A60	# <CJK>
+0xF977	0x9C74	# <CJK>
+0xF978	0x9C73	# <CJK>
+0xF979	0x9C71	# <CJK>
+0xF97A	0x9C75	# <CJK>
+0xF97B	0x9E14	# <CJK>
+0xF97C	0x9E13	# <CJK>
+0xF97D	0x9EF6	# <CJK>
+0xF97E	0x9F0A	# <CJK>
+0xF9A1	0x9FA4	# <CJK>
+0xF9A2	0x7068	# <CJK>
+0xF9A3	0x7065	# <CJK>
+0xF9A4	0x7CF7	# <CJK>
+0xF9A5	0x866A	# <CJK>
+0xF9A6	0x883E	# <CJK>
+0xF9A7	0x883D	# <CJK>
+0xF9A8	0x883F	# <CJK>
+0xF9A9	0x8B9E	# <CJK>
+0xF9AA	0x8C9C	# <CJK>
+0xF9AB	0x8EA9	# <CJK>
+0xF9AC	0x8EC9	# <CJK>
+0xF9AD	0x974B	# <CJK>
+0xF9AE	0x9873	# <CJK>
+0xF9AF	0x9874	# <CJK>
+0xF9B0	0x98CC	# <CJK>
+0xF9B1	0x9961	# <CJK>
+0xF9B2	0x99AB	# <CJK>
+0xF9B3	0x9A64	# <CJK>
+0xF9B4	0x9A66	# <CJK>
+0xF9B5	0x9A67	# <CJK>
+0xF9B6	0x9B24	# <CJK>
+0xF9B7	0x9E15	# <CJK>
+0xF9B8	0x9E17	# <CJK>
+0xF9B9	0x9F48	# <CJK>
+0xF9BA	0x6207	# <CJK>
+0xF9BB	0x6B1E	# <CJK>
+0xF9BC	0x7227	# <CJK>
+0xF9BD	0x864C	# <CJK>
+0xF9BE	0x8EA8	# <CJK>
+0xF9BF	0x9482	# <CJK>
+0xF9C0	0x9480	# <CJK>
+0xF9C1	0x9481	# <CJK>
+0xF9C2	0x9A69	# <CJK>
+0xF9C3	0x9A68	# <CJK>
+0xF9C4	0x9B2E	# <CJK>
+0xF9C5	0x9E19	# <CJK>
+0xF9C6	0x7229	# <CJK>
+0xF9C7	0x864B	# <CJK>
+0xF9C8	0x8B9F	# <CJK>
+0xF9C9	0x9483	# <CJK>
+0xF9CA	0x9C79	# <CJK>
+0xF9CB	0x9EB7	# <CJK>
+0xF9CC	0x7675	# <CJK>
+0xF9CD	0x9A6B	# <CJK>
+0xF9CE	0x9C7A	# <CJK>
+0xF9CF	0x9E1D	# <CJK>
+0xF9D0	0x7069	# <CJK>
+0xF9D1	0x706A	# <CJK>
+0xF9D2	0x9EA4	# <CJK>
+0xF9D3	0x9F7E	# <CJK>
+0xF9D4	0x9F49	# <CJK>
+0xF9D5	0x9F98	# <CJK>
diff --git a/tools/encoding/cjk.inf b/tools/encoding/cjk.inf
new file mode 100644
index 0000000..9fbe527
--- /dev/null
+++ b/tools/encoding/cjk.inf
@@ -0,0 +1,4467 @@
+--- BEGIN (CJK.INF VERSION 2.1 07/12/96) 185553 BYTES ---
+CJK.INF Version 2.1 (July 12, 1996)
+
+Copyright (C) 1995-1996 Ken Lunde. All Rights Reserved.
+
+CJK is a registered trademark and service mark of The Research
+  Libraries Group, Inc.
+
+Online Companion to "Understanding Japanese Information Processing"
+- ENGLISH: 1993, O'Reilly & Associates, Inc., ISBN 1-56592-043-0
+- JAPANESE: 1995, SOFTBANK Corporation, ISBN 4-89052-708-7
+
+
+	This online document provides information on CJK (that is,
+Chinese, Japanese, and Korean) character set standards and encoding
+systems. In short, it provides detailed information on how CJK text is
+handled electronically. I am happy to share this information with
+others, and I would appreciate any comments/feedback on its content.
+The current version (master copy) of this document is maintained at:
+
+  ftp://ftp.ora.com/pub/examples/nutshell/ujip/doc/cjk.inf
+
+This file may also be obtained by contacting me directly using one of
+the e-mail addresses listed in the CONTACT INFORMATION section.
+
+
+TABLE OF CONTENTS
+
+  VERSION HISTORY
+  RESTRICTIONS
+  CONTACT INFORMATION
+  WHAT HAPPENED TO JAPAN.INF?
+  DISCLAIMER
+  CONVENTIONS
+  INTRODUCTION
+  PART 1: WHAT'S UP WITH UJIP?
+  PART 2: CJK CHARACTER SET STANDARDS
+    2.1: JAPANESE
+      2.1.1: JIS X 0201-1976
+      2.1.2: JIS X 0208-1990
+      2.1.3: JIS X 0212-1990
+      2.1.4: JIS X 0221-1995
+      2.1.5: JIS X 0213-199X
+      2.1.6: OBSOLETE STANDARDS
+    2.2: CHINESE (PRC)
+      2.2.1: GB 1988-89
+      2.2.2: GB 2312-80
+      2.2.3: GB 6345.1-86
+      2.2.4: GB 7589-87
+      2.2.5: GB 7590-87
+      2.2.6: GB 8565.2-88
+      2.2.7: GB/T 12345-90
+      2.2.8: GB/T 13131-9X
+      2.2.9: GB/T 13132-9X
+      2.2.10: GB 13000.1-93
+      2.2.11: ISO-IR-165:1992
+      2.2.12: OBSOLETE STANDARDS
+    2.3: CHINESE (TAIWAN)
+      2.3.1: BIG FIVE
+      2.3.2: CNS 11643-1992
+      2.3.3: CNS 5205
+      2.3.4: OBSOLETE STANDARDS
+    2.4: KOREAN
+      2.4.1: KS C 5636-1993
+      2.4.2: KS C 5601-1992
+      2.4.3: KS C 5657-1991
+      2.4.4: GB 12052-89
+      2.4.5: KS C 5700-1995
+      2.4.6: OBSOLETE STANDARDS
+    2.5: CJK
+      2.5.1: ISO 10646-1:1993
+      2.5.2: CCCII
+      2.5.3: ANSI Z39.64-1989
+    2.6: OTHER
+      2.6.1: GB 8045-87
+      2.6.2: TCVN-5773:1993
+  PART 3: CJK ENCODING SYSTEMS
+    3.1: 7-BIT ISO 2022 ENCODING
+      3.1.1: CODE SPACE
+      3.1.2: ISO-REGISTERED ESCAPE SEQUENCES
+      3.1.3: ISO-2022-JP AND ISO-2022-JP-2
+      3.1.4: ISO-2022-KR
+      3.1.5: ISO-2022-CN AND ISO-2022-CN-EXT
+    3.2: EUC ENCODING
+      3.2.1: JAPANESE REPRESENTATION
+      3.2.2: CHINESE (PRC) REPRESENTATION
+      3.2.3: CHINESE (TAIWAN) REPRESENTATION
+      3.2.4: KOREAN REPRESENTATION
+    3.3: LOCALE-SPECIFIC ENCODINGS
+      3.3.1: SHIFT-JIS
+      3.3.2: HZ (HZ-GB-2312)
+      3.3.3: zW
+      3.3.4: BIG FIVE
+      3.3.5: JOHAB
+      3.3.6: N-BYTE HANGUL
+      3.3.7: UCS-2
+      3.3.8: UCS-4
+      3.3.9: UTF-7
+      3.3.10: UTF-8
+      3.3.11: UTF-16
+      3.3.12: ANSI Z39.64-1989
+      3.3.13: BASE64
+      3.3.14: IBM DBCS-HOST
+      3.3.15: IBM DBCS-PC
+      3.3.16: IBM DBCS-/TBCS-EUC
+      3.3.17: UNIFIED HANGUL CODE
+      3.3.18: TRON CODE
+      3.3.19: GBK
+    3.4: CJK CODE PAGES
+  PART 4: CJK CHARACTER SET COMPATIBILITY ISSUES
+    4.1: JAPANESE
+    4.2: CHINESE (PRC)
+    4.3: CHINESE (TAIWAN)
+    4.4: KOREAN
+    4.5: ISO 10646-1:1993
+    4.6: UNICODE
+    4.7: CODE CONVERSION TIPS
+  PART 5: CJK-CAPABLE OPERATING SYSTEMS
+    5.1: MS-DOS
+    5.2: WINDOWS
+    5.3: MACINTOSH
+    5.4: UNIX AND X WINDOWS
+    5.5: OTHERS
+  PART 6: CJK TEXT AND INTERNET SERVICES
+    6.1: ELECTRONIC MAIL
+    6.2: USENET NEWS
+    6.3: GOPHER
+    6.4: WORLD-WIDE WEB
+    6.5: FILE TRANSFER TIPS
+  PART 7: CJK TEXT HANDLING SOFTWARE
+    7.1: MULE
+    7.2: CNPRINT
+    7.3: MASS
+    7.4: ADOBE TYPE MANAGER (ATM)
+    7.5: MACINTOSH SOFTWARE
+    7.6: MACBLUE TELNET
+    7.7: CXTERM
+    7.8: UW-DBM
+    7.9: POSTSCRIPT
+    7.10: NJWIN
+  PART 8: CJK PROGRAMMING ISSUES
+    8.1: C AND C++
+    8.2: PERL
+    8.3: JAVA
+  A FINAL NOTE
+  ACKNOWLEDGMENTS
+  APPENDIX A: INFORMATION SOURCES
+    A.1: USENET NEWSGROUPS AND MAILING LISTS
+      A.1.1: USENET NEWSGROUPS
+      A.1.2: MAILING LISTS
+    A.2: INTERNET RESOURCES
+      A.2.1: USEFUL FTP SITES
+      A.2.2: USEFUL TELNET SITES
+      A.2.3: USEFUL GOPHER SITES
+      A.2.4: USEFUL WWW SITES
+      A.2.5: USEFUL MAIL SERVERS
+    A.3: OTHER RESOURCES
+      A.3.1: BOOKS
+      A.3.2: MAGAZINES
+      A.3.3: JOURNALS
+      A.3.4: RFCs
+      A.3.5: FAQs
+
+
+VERSION HISTORY
+
+	The following is a complete listing of the earlier versions of
+this document along with their release dates and sizes (in bytes):
+
+  Document   Version  Release Date  Size
+  ^^^^^^^^   ^^^^^^^  ^^^^^^^^^^^^  ^^^^
+  JAPAN.INF  1.0      Unknown       Unknown
+  JAPAN.INF  1.1      08/19/91      101,784
+  JAPAN.INF  1.2      03/20/92      166,929 (JIS) or 165,639 (Shift-JIS/EUC)
+  CJK.INF    1.0      06/09/95      103,985
+  CJK.INF    1.1      06/12/95      112,771
+  CJK.INF    1.2      06/14/95      125,275
+  CJK.INF    1.3      06/16/95      130,069
+  CJK.INF    1.4      06/19/95      142,543
+  CJK.INF    1.5      06/22/95      146,064
+  CJK.INF    1.6      06/29/95      150,882
+  CJK.INF    1.7      08/15/95      153,772
+  CJK.INF    1.8      09/11/95      157,295
+  CJK.INF    1.9      12/18/95      170,698
+  CJK.INF    2.0      03/12/96      175,973
+
+With the release of this version, all of the above are now considered
+obsolete. Also, note the three-year gap between the last installment
+of JAPAN.INF and the first installment of CJK.INF -- I was writing
+UJIP and my PhD dissertation during those three years. Ah, so much for
+excuses...
+
+
+RESTRICTIONS
+
+	This document is provided free-of-charge to *anyone*, but no
+person or company is permitted to modify, sell, or otherwise
+distribute it for profit or other purposes. This document may be
+bundled with commercial products only with the prior consent from the
+author, and provided that it is not modified in any way whatsoever.
+The point here is that I worked long and hard on this document so that
+lots of fine folks and companies can benefit from its contents -- not
+profit from it.
+
+
+CONTACT INFORMATION
+
+	I would enjoy hearing from readers of this document, even if
+it is just to say "hello" or whatever. I can be contacted as follows:
+
+  Ken Lunde
+  Adobe Systems Incorporated
+  1585 Charleston Road
+  P.O. Box 7900
+  Mountain View, CA 94039-7900 USA
+  415-962-3866 (office phone)
+  415-960-0886 (facsimile)
+  lunde@adobe.com (preferred)
+  lunde@ora.com or ujip@ora.com
+  WWW Home Page: http://jasper.ora.com/lunde/
+
+If you wonder what I do for my day job, read on.
+	I have been working for Adobe Systems for over four years now
+(before that I was a graduate student at UW-Madison), and my current
+position is Project Manager, CJK Type Development.
+
+
+WHAT HAPPENED TO JAPAN.INF?
+
+	Put bluntly, JAPAN.INF died. It first evolved into my first
+book entitled "Understanding Japanese Information Processing" (this
+book is now into its second printing, and the Japanese translation was
+just published). After my book came out, I did attempt to update
+JAPAN.INF, but the effort felt a bit futile. I decided that something
+fresh was necessary.
+	JAPAN.INF also evolved into this document, which breaks the
+Japanese barrier by providing similar information on Chinese and
+Korean character sets and encodings. It fills the Chinese and Korean
+gap, so to speak. My specialty (and hobby, believe it or not) is the
+field of CJK character sets and encoding systems, so I felt that
+shifting this document more towards those lines was appropriate use of
+my (copious) free time (I wish there were more than 24 hours in a
+day!). Besides, this document now becomes useful to a much broader
+audience.
+
+
+DISCLAIMER
+
+	Ah yes, the ever popular disclaimer! Here's mine. Although I
+list my address here at Adobe Systems Incorporated for contact
+purposes, Adobe Systems does not endorse this document which I have
+created, and have continued (and will continue) to update on a regular
+basis (uh, yeah, I promise this time!). This document is a personal
+endeavor to inform people of how CJK text can be handled on a variety
+of platforms.
+
+
+CONVENTIONS
+
+	The notation that is used for detailing Internet resource
+information, such as the Internet protocol type, site name, path, and
+file follows the URL (Uniform Resource Locator) notation, namely:
+
+  protocol://site-name/path/file
+
+An example URL is as follows:
+
+  ftp://ftp.ora.com/pub/examples/nutshell/ujip/00README
+
+The protocol is FTP, the site-name is ftp.ora.com, the path is pub/
+examples/nutshell/ujip/, and the file is 00README. Also note that this
+same notation is used for invoking FTP on WWW (World Wide Web)
+browsing software, such as Mosaic, Netscape, or Lynx.
+	Note that most references to HTTP documents use the four-
+letter file extension ".html". However, some HTTP documents are on
+file systems that support only three-letter file extensions (can you
+say "MS-DOS"?), so you may encounter just ".htm". This is just to let
+you know that what you see is not a typo.
+	References to my book "Understanding Japanese Information
+Processing" are (affectionately) abbreviated as UJIP. These references
+also apply to the Japanese translation (UJIP-J).
+	Hexadecimal values are prefixed with 0x, and every two
+hexadecimal digits represent a one-byte value. Other values can be
+assumed to be in decimal notation.
+	Chinese characters are referred to as kanji (Japanese), hanzi
+(Chinese), or hanja (Korean), depending on context.
+	References to ISO 10646-1:1993 also refer to Unicode
+(usually). I have done this so that I do not have to repeat "Unicode"
+in the same context as ISO 10646-1:1993. There are times, however,
+when I need to distinguish ISO 10646-1:1993 from Unicode.
+
+
+INTRODUCTION
+
+	Electronic mail (e-mail), just one of the many Internet
+resources, has become a very efficient means of communicating both
+locally and world-wide. While it is very simple to send text which
+uses only the 94 printable ASCII characters, character sets that
+contain more than these ASCII characters pose special problems.
+	This document is primarily concerned with CJK character set
+and encoding issues. Much of this sort of information is not easily
+obtained. This represents one person's attempt at making such
+information more widely available.
+
+
+PART 1: WHAT'S UP WITH UJIP?
+
+	UJIP (First Edition) was published in September 1993 by
+O'Reilly & Associates, Incorporated. The second printing (*not* the
+Second Edition) was subsequently published in March 1994. The page
+count for both printings is unchanged at 470.
+	The following files contain the latest information about
+changes (additions and corrections) made to UJIP and UJIP-J for
+various printings, both for those that have taken place (such as for
+the second printing of the English edition) and for those that are
+planned (the first digit is the edition, and the second is the
+printing):
+
+  ftp://ftp.ora.com/pub/examples/nutshell/ujip/errata/ujip-errata-1-2.txt
+  ftp://ftp.ora.com/pub/examples/nutshell/ujip/errata/ujip-errata-1-3.txt
+  ftp://ftp.ora.com/pub/examples/nutshell/ujip/errata/ujip-j-errata-1-2.txt
+
+I *highly* recommend that all readers of UJIP obtain these errata
+files. Those without FTP access can request copies directly from me.
+	The Japanese translation of UJIP (UJIP-J), co-published by
+O'Reilly & Associates, Incorporated and SOFTBANK Corporation, was just
+released. The translation was done by my good friend Jack Halpern,
+along with one of his colleagues, Takeo Suzuki. The Japanese edition
+incorporates corrections and updates not yet found in the English
+edition. The page count is 535.
+	Late-breaking news! I am currently working on UJIP Second
+Edition (to be retitled as "Understanding CJK Information Processing"
+and abbreviated UCJKIP). If all goes well, it should be available by
+January 1997, and will be well over 700 pages. If there was something
+you wanted to see in UJIP, now's your chance to send me a request...
+
+
+PART 2: CJK CHARACTER SET STANDARDS
+
+	These sections describe the character sets used in Japan,
+China (PRC and Taiwan), and Korea. Exact numbers of characters are
+provided for each character set standard (when known), as well as
+tidbits of information not otherwise available. This provides the
+basic foundations for understanding how CJK scripts are handled on
+computer systems.
+	The two basic types of characters enumerated by CJK character
+set standards are Chinese characters (kanji, hanzi, or hanja), which
+number in the thousands (and, in some cases, tens of thousands), and
+characters other than Chinese characters (symbols, numerals, kana
+hangul, alphabets, and so on), which usually number in the hundreds
+(there are thousands of pre-combined hangul, though).
+	If you happen to be running X Windows, it is very easy to
+display these CJK character sets (if a bitmapped font for the
+character set exists, that is). Here is what I usually do:
+
+o Obtain a BDF (Bitmap Distribution Format) font for the target
+  character set. Try the following URLs for starters:
+
+  ftp://cair-archive.kaist.ac.kr/pub/hangul/fonts/
+  ftp://etlport.etl.go.jp/pub/mule/fonts/
+  ftp://ftp.ifcss.org/pub/software/fonts/{big5,cns,gb,misc,unicode}/bdf/
+  ftp://ftp.kuis.kyoto-u.ac.jp/misc/fonts/jisksp-fonts/
+  ftp://ftp.net.tsinghua.edu.cn/pub/Chinese/fonts/
+  ftp://ftp.ora.com/pub/examples/nutshell/ujip/unix/
+  ftp://ftp.technet.sg:/pub/chinese/fonts/
+  http://ccic.ifcss.org/www/pub/software/fonts/
+
+  BDF files usually have the string "bdf" somewhere in their file
+  name, usually at the end. If the file is compressed (noticing that
+  it ends in .gz or .Z is a good indication), decompress it. BDF files
+  are text files.
+
+o Convert the BDF file to SNF (Server Natural Format) or PCF (Portable
+  Compiled Format) using the programs "bdftosnf" or "bdftopcf,"
+  respectively. Example command lines are as follows:
+
+  % bdftopcf jiskan16-1990.bdf > k16-90.pcf
+  % bdftosnf jiskan16-1990.bdf > k16-90.snf
+
+  SNF files (and the "bdftosnf" program) are used on X11R4 and
+  earlier, and PCF files (and the "bdftopcf" program) are used on
+  X11R5 and later.
+
+o Copy the SNF or PCF file to a directory in the font search path (or
+  make a new path). Supposing I made a new directory called "fonts" in
+  my home directory, I then run "mkfontdir" on the directory
+  containing the SNF or PCF files as follows:
+
+  % mkfontdir ~/fonts
+
+  This creates a fonts.dir file in ~/fonts. I can now add this
+  directory to my font search path with the following command:
+
+  % xset +fp ~/fonts
+
+o The command "xfd" (X Font Displayer) with the "-fn" switch followed
+  by a font name then invokes a window that displays all the
+  characters of the font. In the case of two-byte (CJK) fonts, one row
+  is displayed at a time. The following is an example command line:
+
+  % xfd -fn -misc-fixed-medium-r-normal--16-150-75-75-c-160-jisx0208.1990-0
+
+  You can create a "fonts.alias" file in the same directory as the
+  "fonts.dir" file in order to shorten the name when accessing the
+  font. The alias "k16-90" could be used instead if the content of the
+  fonts.alias file is as follows:
+
+  k16-90  -misc-fixed-medium-r-normal--16-150-75-75-c-160-jisx0208.1990-0
+
+  Don't forget to execute the following command in order to make the
+  X Font Server aware of the new alias:
+
+  % xset fp rehash
+
+  Now you can use a simpler command line for "xfd" as follows:
+
+  % xfd -fn k16-90
+
+	The "X Window System User's Guide" (Volume 3 of the X Window
+System series by O'Reilly & Associates, Inc.) provides detailed
+information on managing fonts under X Windows (pp 123-160). The
+article entitled "The X Administrator: Font Formats and Utilities" (pp
+14-34 in "The X Resource," Issue 2), describes the BDF, SNF, and PCF
+formats in great detail.
+	There is another bitmap format called HBF (Hanzi Bitmap
+Format), which is similar to BDF, but optimized for fixed-width
+(monospaced) fonts. It is described in the article entitled "The HBF
+Font Format: Optimizing Fixed-pitch Font Support" (pp 113-123 in "The
+X Resource," Issue 10), and also at the following URL:
+
+  ftp://ftp.ifcss.org/pub/software/fonts/hbf-discussion/
+
+HBF fonts can be found at the following URL:
+
+  ftp://ftp.ifcss.org/pub/software/fonts/{big5,cns,gb,misc,unicode}/hbf/
+
+	Lastly, you may wish to check out my newly-developed CJK
+Character Set Server, which generates various CJK character sets with
+proper encoding applied. It is written in Perl, and accessed through
+an HTML form. This server can be considered an upgrade to my JChar
+tool (written in C). The URL is:
+
+  http://jasper.ora.com/lunde/cjk-char.html
+
+
+2.1: JAPANESE
+
+	All (national) character set standards that originate in Japan
+have names that begin with the three letters JIS. JIS is short for
+"Japanese Industrial Standard." But it is JSA (Japanese Standards
+Association) who publishes the corresponding manuals. Chapter 3 and
+Appendixes H and J of UJIP provide more detailed information on
+Japanese character set standards.
+
+
+2.1.1: JIS X 0201-1976
+
+	JIS X 0201-1976 (formerly JIS C 6220-1969; reaffirmed in 1989;
+and its revision [with no character set changes] is currently under
+public review) enumerates two sets of characters: JIS-Roman and
+half-width katakana.
+	JIS-Roman is the Japanese equivalent of the ASCII character
+set, namely 128 characters consisting of the following:
+
+o 10 numerals
+o 52 uppercase and lowercase characters of the Latin alphabet
+o 32 symbols (punctuation and so on)
+o 34 non-printing characters (white space and control characters)
+
+The term "white space" refers to characters that occupy space, but
+have no appearance, such as tabs, spaces, and termination characters
+(line feed, carriage return, and form feed).
+	So, how are JIS-Roman and ASCII different? The following
+three codes are (usually) different:
+
+  Code   ASCII        JIS-Roman
+  ^^^^   ^^^^^        ^^^^^^^^^
+  0x5C   backslash    yen symbol
+  0x7C   broken bar   bar
+  0x7E   tilde        overbar
+
+	Half-width katakana consists of 63 characters that provide a
+minimal set of characters necessary for expressing Japanese. The
+shapes are compressed, and visually occupy a space half that of
+*normal* Japanese characters.
+
+
+2.1.2: JIS X 0208-1990
+
+	This basic Japanese character set standard enumerates 6,879
+characters, 6,355 of which are kanji separated into two levels. Kanji
+in the first level are arranged by (most frequent) reading, and those
+in the second level are arranged by radical then total number of
+(remaining) strokes.
+
+o Row 1: 94 symbols
+o Row 2: 53 symbols
+o Row 3: 10 numerals and 52 uppercase and lowercase Latin alphabet
+o Row 4: 83 hiragana
+o Row 5: 86 katakana
+o Row 6: 48 uppercase and lowercase Greek alphabet
+o Row 7: 66 uppercase and lowercase Cyrillic (Russian) alphabet
+o Row 8: 32 line-drawing elements
+o Rows 16 through 47: 2,965 kanji (JIS Level 1 Kanji; last is 47-51)
+o Rows 48 through 84: 3,390 kanji (JIS Level 2 Kanji; last is 84-06)
+
+Appendix B of UJIP provides a complete illustration of the JIS X
+0208-1990 character set standard by KUTEN (row-cell) code. Appendix G
+(pp 294-317) of "Developing International Software for Windows 95 and
+Windows NT" by Nadine Kano illustrates the JIS X 0208-1990 character
+set standard plus the Microsoft extensions by Shift-JIS code
+(Microsoft calls this Code Page 932).
+	Earlier versions of this standard were dated 1978 (JIS C
+6226-1978) and 1983 (JIS X 0208-1983, formerly JIS C 6226-1983).
+	JIS X 0208 went through a revision (from November 1995 until
+February 1996), and is slated for publication sometime in 1996 (to
+become JIS X 0208-1996). More information on this revision is
+available at the following URL:
+
+  ftp://ftp.tiu.ac.jp/jis/jisx0208/
+
+
+2.1.3: JIS X 0212-1990
+
+	This supplemental Japanese character set standard enumerates
+6,067 characters, 5,801 of which are kanji ordered by radical then
+total number of (remaining) strokes. All 5,801 kanji are unique when
+compared to those in JIS X 0208-1990 (see Section 2.1.2). The
+remaining 266 characters are categorized as non-kanji.
+
+o Row 2: 21 diacritics and symbols
+o Row 6: 21 Greek characters with diacritics
+o Row 7: 26 Eastern European characters
+o Rows 9 through 11: 198 alphabetic characters
+o Rows 16 through 77: 5,801 kanji (last is 77-67)
+
+Appendix C of UJIP provides a complete illustration of the JIS X
+0212-1990 character set standard by KUTEN (row-cell) code.
+	The only commercial operating system that provides JIS X
+0212-1990 support is BTRON by Personal Media Corporation:
+
+  http://www.personal-media.co.jp/
+
+Section 3.3.18 provides information about TRON Code (used by BTRON),
+and details how it encodes the JIS X 0212-1990 character set.
+
+
+2.1.4: JIS X 0221-1995
+
+	This document is, for all practical purposes, the Japanese
+translation of ISO 10646-1:1993 (see Section 2.5.1). Like ISO
+10646-1:1993, it is based on Unicode Version 1.1.
+	It is noteworthy that JIS X 0221-1995 enumerates subsets that
+are applicable for Japanese use (a brief description of their contents
+in parentheses):
+
+o BASIC JAPANESE (JIS X 0208-1990 and JIS X 0201-1976 -- characters
+  that can be created by means of combining are not included -- 6,884
+  characters)
+o JAPANESE NON IDEOGRAPHICS SUPPLEMENT (1,913 characters: all non-
+  kanji of JIS X 0212-1990 plus hundreds of non-JIS characters)
+o JAPANESE IDEOGRAPHICS SUPPLEMENT 1 (918 frequently-used kanji from
+  JIS X 0212-1990, including 28 that are identical to kanji forms in
+  JIS C 6226-1978)
+o JAPANESE IDEOGRAPHICS SUPPLEMENT 2 (the remainder of JIS X 0212-
+  1990, namely 4,883 kanji)
+o JAPANESE IDEOGRAPHICS SUPPLEMENT 3 (the remaining kanji of ISO
+  10646-1:1993, namely 8,746 characters)
+o FULLWIDTH ALPHANUMERICS (94 characters; for compatibility)
+o HALFWIDTH KATAKANA (63 characters; for compatibility)
+
+	Pages 893 through 993 provide Kangxi Zidian (a classic
+300-year-old Chinese character dictionary containing approximately
+50,000 characters) and Dai Kanwa Jiten (also known as Morohashi)
+indexes for the entire Chinese character block, namely from 0x4E00
+through 0x9FA5.
+	At 25,750 Yen, it is actually cheaper than ISO 10646-1:1993!
+
+
+2.1.5: JIS X 0213-199X
+
+	I recently became aware that JSA plans to publish an extension
+to JIS X 0208, containing approximately 2,000 characters (kanji and
+non-kanji). A public review of this new standard is planned for Summer
+1996. I would expect that its information will eventually be available
+at the following URL:
+
+    ftp://ftp.tiu.ac.jp/jis/
+
+
+2.1.6: OBSOLETE STANDARDS
+
+	JIS C 6226-1978 and JIS X 0208-1983 (formerly JIS C 6226-1983)
+have been superseded by JIS X 0208-1990. Section 4.1 provides details
+on the changes made between these earlier versions of JIS X 0208.
+	JIS X 0221-1995 does not mean the end of JIS X 0201-1976, JIS
+X 0208-1990, and JIS X 0212-1990. Instead, it will co-exist with those
+standards.
+
+
+2.2: CHINESE (PRC)
+
+	All character set standards that originate in PRC have
+designations that begin with "GB." "GB" is short for "Guo Biao" (which
+is, in turn, short for "Guojia Biaojun") and means "National
+Standard." A select few also have "/T" attached. The "T" presumably is
+short for "Traditional." Section 2.2.11 describes ISO-IR-165:1992,
+which is a variant of GB 2312-80. It is included here because of this
+relationship.
+	Most people correlate GB character set standards with
+simplified Chinese, but as you will see below, that is not always the
+case.
+	There are three basic character sets, each one having a
+simplified and traditional version.
+
+  Character Set  Set Number  Character Forms
+  ^^^^^^^^^^^^^  ^^^^^^^^^^  ^^^^^^^^^^^^^^^
+  GB 2312-80     0           Simplified
+  GB/T 12345-90  1           Traditional of GB 2312-80
+  GB 7589-87     2           Simplified
+  GB/T 13131-9X  3           Traditional of GB 7589-87
+  GB 7590-87     4           Simplified
+  GB/T 13132-9X  5           Traditional of GB 7590-87
+
+
+2.2.1: GB 1988-89
+
+	This character set, formerly GB 1988-80 and sometimes referred
+to as GB-Roman, is the Chinese analog to ASCII and ISO 646. The main
+difference is that the currency symbol (0x24), which is represented as
+a dollar sign ($) in ASCII, is represented as a Chinese Yuan
+(currency) symbol instead. GB 1988-89 is sometimes referred to as
+GB-Roman.
+
+
+2.2.2: GB 2312-80
+
+	This basic (simplified) Chinese character set standard
+enumerates 7,445 characters, 6,763 of which are hanzi separated into
+two levels. Hanzi in the first level are arranged by reading, and
+those in the second level are arranges by radical then total number of
+(remaining) strokes. GB 2312-80 is also known as the "Primary Set,"
+GB0 (zero), or just GB.
+
+o Row 1: 94 symbols
+o Row 2: 72 numerals
+o Row 3: 94 full-width GB 1988-89 characters (see Section 2.2.1)
+o Row 4: 83 hiragana
+o Row 5: 86 katakana
+o Row 6: 48 uppercase and lowercase Greek alphabet
+o Row 7: 66 uppercase and lowercase Cyrillic (Russian) alphabet
+o Row 8: 26 Pinyin and 37 Bopomofo characters
+o Row 9: 76 line-drawing elements (09-04 through 09-79)
+o Rows 16 through 55: 3,755 hanzi (Level 1 Hanzi; last is 55-89)
+o Rows 56 through 87: 3,008 hanzi (Level 2 Hanzi; last is 87-94)
+
+Compare some of the structure with JIS X 0208-1990, and you will find
+many similarities, such as:
+
+o Hiragana, katakana, Greek, and Cyrillic characters are in Rows 4, 5,
+  6, and 7, respectively
+o Chinese characters begin at Row 16
+o Chinese characters are separated into two levels
+o Level 1 arranged by reading
+o Level 2 arranged by radical then total number of strokes
+
+The Japanese standard, JIS C 6226-1978, came out in 1978, which means
+that it pre-dates GB 2312-80. The above similarities could not be by
+coincidence, but rather by design.
+	Appendix G (pp 318-344) of "Developing International Software
+for Windows 95 and Windows NT" by Nadine Kano illustrates the GB 2312-
+80 character set standard by EUC code (Microsoft calls this Code Page
+936). Code Page 936 incorporates the correction of the hanzi at 79-81,
+and the correction of the order of 07-22 and 07-23 (see Section 2.2.3
+for more details).
+
+
+2.2.3: GB 6345.1-86
+
+	This document specifies corrections and additions to GB
+2312-80 (see Section 2.2.2). The following is a detailed enumeration
+of the changes:
+
+o The form of "g" in Row 3 (position 71) was altered
+o Row 8 has six additional Pinyin characters (08-27 through 08-32)
+o Row 10 contains half-width versions of Row 3 (94 characters)
+o Row 11 contains half-width versions of the Pinyin characters from
+  Row 8 (32 characters; 11-01 through 11-32)
+o The hanzi at 79-81 was corrected to have a simplified left-side
+  radical (this was an error in GB 2312-80)
+
+Note that these changes affect the total number of characters in GB
+2312-80 -- an increase of 132 characters. This now makes 7,577 as
+the total number of characters in GB 2312-80 (7,445 plus 132).
+	There was, however, an undocumented correction made in GB
+6345.1-86. The order of characters 07-22 and 07-23 (uppercase
+Cyrillic) were reversed. This error is apparently in the first and
+perhaps second printing of the GB 2312-80 manual, because the copy I
+have is from the third printing, and this has been corrected. Page 145
+(Figure 113) of John Clews' "Language Automation Worldwide: The
+Development of Character Set Standards" illustrates this error.
+Developers should take special note of this -- I have seen GB 2312-80
+based font products that propagate this ordering error.
+
+
+2.2.4: GB 7589-87
+
+	This character set enumerates 7,237 hanzi in Rows 16 through
+92 (last is 92-93), and they are ordered by radical then total number
+of (remaining) strokes. GB 7589-87 is also known as the "Second
+Supplementary Set" or GB2.
+
+
+2.2.5: GB 7590-87
+
+	This character set enumerates 7,039 hanzi in Rows 16 through
+90 (last is 90-83), and they are ordered by radical then total number
+of (remaining) strokes. GB 7590-87 is also known as the "Fourth
+Supplementary Set" or GB4.
+
+
+2.2.6: GB 8565.2-88
+
+	This standard makes additions to GB 2312-80 (these additions
+are separate from those made in GB 6345.1-86 described in Section
+2.2.3). GB 8565.2-88 is also known as GB8. In this case there are 705
+additions, indicated as follows:
+
+o Row 13 contains 50 hanzi from GB 7589-87 (last is 13-50)
+o Row 14 contains 92 hanzi from GB 7590-87 (last is 14-92)
+o Row 15 contains 69 non-hanzi indicating dates and times, plus 24
+  miscellaneous hanzi (for personal/place names and radicals; last is
+  15-93).
+o Rows 90 through 94 contain 470 hanzi from GB 7589-87 (94 each)
+
+GB 8565.2-88 therefore provides a total of 8,150 characters (7,445
+plus 705).
+
+
+2.2.7: GB/T 12345-90
+
+	This character set is nearly identical to GB 2312-80 (see
+Section 2.2.2) in terms of the number and arrangement of characters,
+but simplified hanzi are replaced by their traditional versions. GB/T
+12345-90 is also known as the "Supplementary Set" or GB1.
+	The following are some interesting facts about this character
+set (some instances of simplified/traditional pairs that appear below
+are actually character form differences):
+
+o 29 vertical-use characters (punctuation and parentheses) included in
+  Row 6 (06-57 through 06-85).
+
+o 2,118 traditional hanzi replace simplified hanzi in Rows 16 through
+  87. The "G1-Unique" appendix of the unofficial version (supplied to
+  the CJK-JRG for Han Unification purposes) is missing the following
+  four (specifies only 2,114):
+
+  0x5B3B    0x6D2F
+  0x5E7C    0x6F71
+
+  But, ISO 10646-1:1993 ended up getting these hanzi included anyway,
+  with correct mappings.
+
+o Four simplified/traditional hanzi pairs (eight affected code points)
+  in rows 16 through 87 are swapped:
+
+  0x3A73 <-> 0x6161
+  0x5577 <-> 0x6167
+  0x5360 <-> 0x6245 (see the next bullet)
+  0x4334 <-> 0x7761
+
+o One hanzi (0x6245), after being swapped, had its left-side radical
+  unsimplified (this character, now at 0x5360, is considered part of
+  the 2,118 traditional hanzi from the second bullet):
+
+  0x6245 -> 0x5360
+
+o 103 hanzi included in Rows 88 (94 characters) and 89 (9 characters;
+  89-01 through 89-09). These are all related to characters between
+  Rows 16 and 87.
+
+  - 41 simplified hanzi from Rows 16 through 87 moved to Rows 88 and
+    89 (traditional hanzi are now at the original code points):
+
+    0x3327 -> 0x7827  0x3E5D -> 0x7846  0x4B49 -> 0x7869
+    0x3365 -> 0x7828  0x3F64 -> 0x7849  0x4C28 -> 0x786B
+    0x3373 -> 0x7829  0x402F -> 0x784B  0x4D3F -> 0x786F
+    0x3533 -> 0x782C  0x4030 -> 0x784C  0x4D72 -> 0x7871
+    0x356D -> 0x782D  0x406F -> 0x784E  0x5236 -> 0x7878
+    0x3637 -> 0x782F  0x4131 -> 0x7850  0x5374 -> 0x7879
+    0x3736 -> 0x7832  0x463B -> 0x785C  0x5438 -> 0x787C
+    0x3761 -> 0x7833  0x463E -> 0x785D  0x5446 -> 0x787D
+    0x3849 -> 0x7835  0x464B -> 0x785E  0x5622 -> 0x7921
+    0x3963 -> 0x7838  0x464D -> 0x785F  0x563B -> 0x7923
+    0x3B2E -> 0x783B  0x4653 -> 0x7860  0x5656 -> 0x7926
+    0x3C38 -> 0x7840  0x4837 -> 0x7866  0x567E -> 0x7928
+    0x3C5B -> 0x7842  0x4961 -> 0x7867  0x573C -> 0x7929
+    0x3C76 -> 0x7843  0x4A75 -> 0x7868
+
+  - 62 hanzi added to Rows 88 and 89 (the gaps from the above are
+    filled in). These were mostly to account for multiple traditional
+    hanzi collapsing into a single simplified form.
+
+  - The following code point mappings illustrate how all of these 103
+    hanzi are related to hanzi between Rows 16 and 87 (note how many
+    of these 103 hanzi map to a single code point):
+
+    0x7821 -> 0x305A  0x7844 -> 0x3D2A  0x7867 -> 0x4961
+    0x7822 -> 0x3065  0x7845 -> 0x3E21  0x7868 -> 0x4A75
+    0x7823 -> 0x316D  0x7846 -> 0x3E5D  0x7869 -> 0x4B49
+    0x7824 -> 0x3170  0x7847 -> 0x3E6D  0x786A -> 0x4B55
+    0x7825 -> 0x3237  0x7848 -> 0x3F4B  0x786B -> 0x4C28
+    0x7826 -> 0x3245  0x7849 -> 0x3F64  0x786C -> 0x4C28
+    0x7827 -> 0x3327  0x784A -> 0x4027  0x786D -> 0x4C28
+    0x7828 -> 0x3365  0x784B -> 0x402F  0x786E -> 0x4C33
+    0x7829 -> 0x3373  0x784C -> 0x4030  0x786F -> 0x4D3F
+    0x782A -> 0x3376  0x784D -> 0x405B  0x7870 -> 0x4D45
+    0x782B -> 0x3531  0x784E -> 0x406F  0x7871 -> 0x4D72
+    0x782C -> 0x3533  0x784F -> 0x407A  0x7872 -> 0x4F35
+    0x782D -> 0x356D  0x7850 -> 0x4131  0x7873 -> 0x4F35
+    0x782E -> 0x362C  0x7851 -> 0x414B  0x7874 -> 0x4F4C
+    0x782F -> 0x3637  0x7852 -> 0x4231  0x7875 -> 0x4F72
+    0x7830 -> 0x3671  0x7853 -> 0x425E  0x7876 -> 0x506B
+    0x7831 -> 0x3722  0x7854 -> 0x4339  0x7877 -> 0x5229
+    0x7832 -> 0x3736  0x7855 -> 0x4349  0x7878 -> 0x5236
+    0x7833 -> 0x3761  0x7856 -> 0x4349  0x7879 -> 0x5374
+    0x7834 -> 0x3834  0x7857 -> 0x4349  0x787A -> 0x5379
+    0x7835 -> 0x3849  0x7858 -> 0x4356  0x787B -> 0x5375
+    0x7836 -> 0x3948  0x7859 -> 0x4366  0x787C -> 0x5438
+    0x7837 -> 0x394E  0x785A -> 0x436F  0x787D -> 0x5446
+    0x7838 -> 0x3963  0x785B -> 0x3159  0x787E -> 0x5460
+    0x7839 -> 0x6358  0x785C -> 0x463B  0x7921 -> 0x5622
+    0x783A -> 0x3A7A  0x785D -> 0x463E  0x7922 -> 0x563B
+    0x783B -> 0x3B2E  0x785E -> 0x464B  0x7923 -> 0x563B
+    0x783C -> 0x3B58  0x785F -> 0x464D  0x7924 -> 0x5642
+    0x783D -> 0x3B63  0x7860 -> 0x4653  0x7925 -> 0x5646
+    0x783E -> 0x3B71  0x7861 -> 0x4727  0x7926 -> 0x5656
+    0x783F -> 0x3C22  0x7862 -> 0x4729  0x7927 -> 0x566C
+    0x7840 -> 0x3C38  0x7863 -> 0x4F4B  0x7928 -> 0x567E
+    0x7841 -> 0x3C52  0x7864 -> 0x476F  0x7929 -> 0x573C
+    0x7842 -> 0x3C5B  0x7865 -> 0x477A
+    0x7843 -> 0x3C76  0x7866 -> 0x4837
+
+So, if we total everything up, we see that GB/T 12345-90 has 2,180
+hanzi (2,118 are replacements for GB 2312-80 code points, and 62 are
+additional) and 29 non-hanzi not found in GB 2312-80.
+	Note that the printing of the GB/T 12345-90 has some
+character-form errors. The errors I am aware of are as follows:
+
+  Code Point  Description of Error
+  ^^^^^^^^^^  ^^^^^^^^^^^^^^^^^^^^
+  0x4125      The upper-left element should be "tree" instead of
+              "warrior"
+  0x596C      The "bird" radical should not include the "fire" element
+
+
+2.2.8: GB/T 13131-9X
+
+	This character set is identical to GB 7589-87 (see Section
+2.2.4) in terms of number of characters, but simplified hanzi are
+replaced by their traditional versions. The exact number of such
+substitutions is currently unknown to this author. GB/T 13131-9X is
+also known as the "Third Supplementary Set" or GB3.
+
+
+2.2.9: GB/T 13132-9X
+
+	This character set is identical to GB 7590-87 (see Section
+2.2.5) in terms of number of characters, but simplified hanzi are
+replaced by their traditional versions. The exact number of such
+substitutions is currently unknown to this author. GB/T 13132-9X is
+also known as the "Fifth Supplementary Set" or GB5.
+
+
+2.2.10: GB 13000.1-93
+
+	This document is, for all practical purposes, the Chinese
+translation of ISO 10646-1:1993 (see Section 2.5.1).
+
+
+2.2.11: ISO-IR-165:1992
+
+	This standard, also known as the CCITT Chinese Set, is a
+variant of GB 2312-80 with the following characteristics:
+
+o GB 6345.1-86 modifications (including the undocumented one) and
+  additions, namely 132 characters (see Section 2.2.3)
+o GB 8565.2-88 additions, namely 705 characters (see Section 2.2.6)
+o Row 6 contains 22 background (shading) characters (06-60 through
+  06-81)
+o Row 12 contains 94 hanzi
+o Row 13 contains 44 additional hanzi (13-51 through 13-94; fills the
+  row)
+o Row 15 contains 1 additional hanzi (15-94)
+
+ISO-IR-165:1992 can therefore be considered a superset of GB 2312-80,
+GB 6345.1-86, and GB 8565.2-88. This means 8,443 total characters
+compared to the 7,445 in GB 2312-80, 7,577 in GB 6345.1-86, and the
+8,150 in GB 8565.2-88.
+
+
+2.2.12: OBSOLETE STANDARDS
+
+	Most GB standards seem to be revised through other documents,
+so it is hard to point to a standard and claim that it is obsolete.
+The only revision I am aware of is the GB 1988-89 (the original was
+named GB 1988-80).
+
+
+2.3: CHINESE (TAIWAN)
+
+	The sections below describe two major Taiwanese character
+sets, namely Big Five and CNS 11643-1992. As you will learn they are
+somewhat compatible. CCCII, also developed in Taiwan, is described in
+Section 2.5.2.
+
+
+2.3.1: BIG FIVE
+
+	The Big Five character set is composed of 94 rows of 157
+characters each (the 157 characters of each row are encoded in an
+initial group of 63 codes followed by the remaining 94 codes). The
+following is a break-down of its contents:
+
+o Row 1: 157 symbols
+o Row 2: 157 symbols
+o Row 3: 94 symbols
+o Rows 4 through 38: 5,401 hanzi (Level 1 Hanzi; last is 38-63)
+o Rows 41 through 89: 7,652 hanzi (Level 2 Hanzi; last is 89-116)
+
+This forms what I consider to be the basic Big Five set. Actually, two
+of the hanzi in Level 2 are duplicates, so there are actually only
+7,650 unique hanzi in Level 2.
+	There are two major extensions to Big Five. The first really
+has no name, and can be considered part of the basic Big Five set as
+specified above. It adds the following characters:
+
+o Rows 38-39: 4 Japanese iteration marks, 83 hiragana, 86 katakana, 66
+  uppercase and lowercase Cyrillic (Russian) alphabet, 10 circled
+  digits, and 10 parenthesized digits
+
+	The other extension was developed by a company called ETen
+Information System in Taiwan, and is actually considered to be the
+most widely used version of Big Five. It provides the following
+extensions to Big Five (different from the above extension):
+
+o Rows 38-40: 10 circled digits, 10 parenthesized digits, 10 lowercase
+  Roman numerals, 25 classical radicals, 15 Japanese-specific symbols,
+  83 hiragana, 86 katakana, 66 uppercase and lowercase Cyrillic
+  (Russian) alphabet, 3 arrows, 10 radical-like hanzi elements, 40
+  fraction-like digits, and 7 symbols
+o Row 89: 7 hanzi, 33 double-lined line-drawing elements, and a black
+  box
+
+	It is *very* important to note that while these two extensions
+have many common portions (in particular, hiragana, katakana, the
+Cyrillic alphabet, and so on), they do not share the same code points
+for such characters.
+	Appendix G (pp 407-450) of "Developing International Software
+for Windows 95 and Windows NT" by Nadine Kano illustrates the Big Five
+character set standard by Big Five code (Microsoft calls this Code
+Page 950). Code Page 950 incorporates some of the ETen extensions,
+namely those in Row 89.
+
+
+2.3.2: CNS 11643-1992
+
+	CNS 11643-1992 (also known as CNS 11643 X 5012), by
+definition, consists of 16 planes of characters, seven of which have
+character assignments. Each plane is a 94-row-by-94-cell matrix
+capable of holding a total of 8,836 characters. CNS stands for
+"Chinese National Standard."
+	CNS 11643-1992 specifies characters only in the first seven
+planes. A break-down of characters, by plane, is as follows:
+
+o Plane 1:
+  - 438 symbols in Rows 1 through 6
+  - 213 classical radicals in Rows 7 through 9
+  - 33 graphic representations of control characters in Row 34
+  - 5,401 hanzi in Rows 36 through 93 (last is 93-43)
+o Plane 2: 7,650 hanzi in Rows 1 through 82 (last is 82-36)
+o Plane 3: 6,148 hanzi in Rows 1 through 66 (last is 66-38)
+o Plane 4: 7,298 hanzi in Rows 1 through 78 (last is 78-60)
+o Plane 5: 8,603 hanzi in Rows 1 through 92 (last is 92-49)
+o Plane 6: 6,388 hanzi in Rows 1 through 68 (last is 68-90)
+o Plane 7: 6,539 hanzi in Rows 1 through 70 (last is 70-53)
+
+The total number of characters in CNS 11643-1992 is a staggering
+48,711 characters, 48,027 of which are hanzi. Also note that number of
+hanzi in Plane 1 is identical to Level 1 hanzi of Big Five (see
+Section 2.3.1). The 2 extra hanzi in Level 2 hanzi of Big Five are
+actually redundant, and are therefore not in CNS 11643-1992 Plane 2.
+	It is rumored that Plane 8 is currently being defined, and
+will add yet more hanzi to this standard.
+
+
+2.3.3: CNS 5205
+
+	This character set is Taiwan's analog to ASCII and ISO 646,
+and is reportedly rarely used. How it differs from ASCII, if at all,
+is unknown to this author.
+
+
+2.3.4: OBSOLETE STANDARDS
+
+	CNS 11643-1986 specified characters only in the first three
+planes, as described in Section 2.3.2. Also, Plane 3 of CNS 11643-1992
+was called Plane 14 of CNS 11643-1986.
+
+
+2.4: KOREAN
+
+	The sections below describe the most current Korean character
+sets, namely KS C 5636-1993, KS C 5601-1992, KS C 5657-1991, and KS C
+5700-1995. "KS" stands for "Korean Standard."
+
+
+2.4.1: KS C 5636-1993
+
+	This character set (published on January 6, 1993), formerly KS
+C 5636-1989 (published on April 22, 1989) and sometimes referred to as
+KS-Roman, is the Korean analog to ASCII and ISO 646-1991. The primary
+difference is that the ASCII backslash (0x5C) is represented as a Won
+symbol.
+
+
+2.4.2: KS C 5601-1992
+
+	This basic Korean character set standard enumerates 8,224
+characters, 4,888 of which are hanja, and 2,350 of which are pre-
+combined hangul. The hanja and hangul blocks are arranged by reading.
+The following is a break-down of its contents:
+
+o Row 1: 94 symbols
+o Row 2: 69 abbreviations and symbols
+o Row 3: 94 full-width KS C 5636-1993 characters (see Section 2.4.1)
+o Row 4: 94 hangul elements
+o Row 5: 68 lowercase and uppercase Roman numerals and lowercase and
+  uppercase Greek alphabet
+o Row 6: 68 line-drawing elements
+o Row 7: 79 abbreviations
+o Row 8: 91 phonetic symbols, circled characters, and fractions
+o Row 9: 94 phonetic symbols, parenthesized characters, subscripts,
+  and superscripts
+o Row 10: 83 hiragana
+o Row 11: 86 katakana
+o Row 12: 66 lowercase and uppercase Cyrillic (Russian) alphabet
+o Rows 16 through 40: 2,350 pre-combined hangul (last is 40-94)
+o Rows 42 through 93: 4,888 hanja (last is 93-94)
+
+Rows 41 and 94 are designated for user-defined characters.
+	There are many similarities with JIS X 0208-1990 and GB
+2312-80, such as hiragana, katakana, Greek, and Cyrillic characters,
+but they are assigned to different rows.
+	There is an interesting note about the hanja block (Rows 42
+through 93). Although there are 4,888 hanja, not all are unique. The
+hanja block is arranged by reading, and in those cases when a hanja
+has more than one reading, that hanja is duplicated (sometimes more
+than once) in the same character set. There are 268 such cases of
+duplicate hanja in KS C 5601-1992, meaning that it contains 4,620
+unique hanja. If you have a copy of the KS C 5601-1992 manual handy,
+you can compare the following four code points:
+
+  0x6445
+  0x5162
+  0x5525
+  0x6879
+
+While most of these cases involve two hanja instances, there are four
+hanja that have three instances, and one (listed above) that has four!
+This is the only CJK character set that has this property of
+intentionally duplicating Chinese characters. See Section 4.4 for more
+details.
+	Annex 3 of this standard defines the complete set of 11,172
+pre-combined hangul characters, also known as Johab. Johab refers to
+the encoding method, and is almost like encoding all possible three-
+letter words (meaning that most are nonsense). See Section 3.3.5 for
+more details on Johab encoding.
+
+
+2.4.3: KS C 5657-1991
+
+	This character set standard provides supplemental characters
+for Korean writing, to include symbols, pre-combined hangul, and
+hanja. The following is a break-down of its contents:
+
+o Rows 1 through 7: 613 lowercase and uppercase Latin characters with
+  diacritics (see note below)
+o Rows 8 through 10: 273 lowercase and uppercase Greek characters with
+  diacritics
+o Rows 11 through 13: 275 symbols
+o Row 14: 27 compound hangul elements
+o Rows 16 through 36: 1,930 pre-combined hangul (last is 36-50)
+o Rows 37 through 54: 1,675 pre-combined hangul (last is 54-77; see
+  note below)
+o Rows 55 through 85: 2,856 hanja (last is 85-36)
+
+The KS C 5657-1991 manual has a possible error (or at least an
+inconsistency) for Rows 1 through 7. The manual says that there are
+615 characters in that range, but I only counted 613. The difference
+can be found on page 19 as the following two characters:
+
+  Character Code  Character
+  ^^^^^^^^^^^^^^  ^^^^^^^^^
+  0x2137          X
+  0x217A          TM
+
+An "X" doesn't belong there (it is already in KS C 5601-1992 at code
+point 0x2358), and the trademark symbol is also part of KS C 5601-1992
+at code point 0x2262. This is why I feel that my count of 613 is more
+accurate than what is explicitly stated in the manual on page 2.
+	Also, page 2 of the manual says that Rows 37 through 54
+contains 1,677 pre-combined hangul, but I only counted 1,675 (17 rows
+of 94 characters plus a final row with 77 characters -- do the math
+for yourself).
+	Here's another interesting note. My official copy of this
+standard has all of its 2,856 hanja hand-written.
+
+
+2.4.4: GB 12052-89
+
+	You may be asking yourself why a GB standard is listed under
+the Korean section of this document. Well, there is a rather large
+Korean population in China (Korea was considered part of China before
+the 1890s), and they need a character set standard for communicating
+using hangul. GB 12052-89 is a Korean character set standard
+established by China (PRC), and enumerates a total of 5,979
+characters.
+	The following is the arrangement of this character set:
+
+o Row 1: 94 symbols
+o Row 2: 72 numerals
+o Row 3: 94 full-width ASCII characters
+o Row 4: 83 hiragana
+o Row 5: 86 katakana
+o Row 6: 48 uppercase and lowercase Greek alphabet
+o Row 7: 66 uppercase and lowercase Cyrillic (Russian) alphabet
+o Row 8: 26 Pinyin and 37 Bopomofo characters
+o Row 9: 76 line-drawing elements (09-04 through 09-79)
+o Rows 16 through 37: 2,068 pre-combined hangul (Level 1 Hangul, Part
+  1; last is 37-94)
+o Rows 38 through 52: 1,356 pre-combined hangul (Level 1 Hangul, Part
+  2; last is 52-40)
+o Rows 53 through 71: 1,779 pre-combined hangul (Level 2 Hangul; last
+  is 71-87)
+o Rows 71 through 72: 94 "Idu" hanja (71-89 through 72-88)
+
+	There are a few interesting notes I can make about this
+character set:
+
+o Rows 1 through 9 are identical to the same rows in GB 2312-80,
+  except that 03-04 is a dollar sign, not a Chinese Yuan (currency)
+  symbol.
+
+o The GB 12052-89 manual states on pp 1 and 3 that Rows 53 through 72
+  contain 1,876 characters, but I only counted 1,873 (1,779 hangul
+  plus 94 hanja).
+
+o The total number of characters, 5,979, is correctly stated in the
+  manual although the hangul count is incorrect.
+
+o The arrangement and ordering of these hangul bear no relationship to
+  that of KS C 5601-1992. Both standards order by reading, which is
+  the only way in which they are similar.
+
+	I am not aware to what extent this character set is being
+used (and who might be using it).
+
+
+2.4.5: KS C 5700-1995
+
+	Korea has developed a new character set standard called KS C
+5700-1995. It is equivalent to ISO 10646-1:1993, but have pre-combined
+hangul as provided (and ordered) in Unicode Version 2.0 (meaning that
+all 11,172 hangul are in a contiguous block).
+
+
+2.4.6: OBSOLETE STANDARDS
+
+	KS C 5601-1986, KS C 5601-1987, and KS C 5601-1989 are the
+same, character-set wise, to KS C 5601-1992. The 1992 edition provides
+more material in the form of annexes. KS C 5601-1982, the original
+version, enumerated only the 51 basic hangul elements in a one-byte 7-
+and 8-bit encoding. This information is still part of KS C 5601-1992,
+but in Annex 4.
+	There were two earlier multiple-byte standards called KS C
+5619-1982 and KIPS. KS C 5619-1982 enumerated 51 hangul elements,
+1,316 pre-combined hangul, and 1,672 hanja. KIPS (Korean Information
+Processing System) enumerated 2,058 pre-combined hangul and 2,392
+hanja. Both have been rendered obsolete by KS C 5601-1987.
+
+
+2.5: CJK
+
+	The only true CJK character sets available today are CCCII,
+ANSI Z39.64-1989 (also known as EACC or REACC), and ISO 10646-1:1993.
+ISO 10646-1:1993 is unique in that it goes beyond CJK (Chinese
+characters) to provide virtually all commonly-used alphabetic scripts.
+	Of these three, only ISO 10646-1:1993 is expected to gain
+wide-spread acceptance. CCCII and ANSI Z39.64-1989 are still used
+today, but primarily for bibliographic purposes.
+
+
+2.5.1: ISO 10646-1:1993
+
+	Published by ISO (International Organization for
+Standardization) in Switzerland, this character set enumerates over
+34,000 characters. Its I-zone ("I" stands for "Ideograph") enumerates
+approximately 21,000 Chinese characters, which is the result of a
+massive effort by the CJK-JRG (CJK Joint Research Group) called "Han
+Unification." The CJK-JRG is now called the IRG (Ideographic
+Rapporteur Group), and is off doing additional research for future
+Chinese character allocations to ISO 10646-1:1993.
+	The Basic Multilingual Plane (BMP) of ISO 10646-1:1993 is
+equivalent to Unicode. While Unicode is comprised of a single plane of
+characters (which doesn't allow much room for future expansion), ISO
+10646-1:1993 contains hundreds of such planes.
+	One very nice feature of this standard's manual are the CJK
+code correspondence tables in Section 26 (pp 262-698). Four columns
+are provided for each ISO 10646-1:1993 I-zone code point -- simplified
+Chinese, traditional Chinese, Japanese, and Korean. If the ISO
+10646-1:1993 Chinese character maps to one of these locales, the
+hexadecimal character code, (decimal) row-cell value, and glyph for
+that locale is provided. The corresponding tables in Volume 2 of "The
+Unicode Standard" provide character codes (sometimes the hexadecimal
+character code, and sometimes the row-cell value) and a single
+glyph. Quite unfortunate. I hear that a new edition of "The Unicode
+Standard" is about to be released. I hope that this problem has been
+addressed.
+	ISO 10646-1:1993 does not replace existing national character
+set standards. It simply provides a single character set that is a
+superset of *most* national character sets. For example, only a
+fraction of the 48,027 hanzi in CNS 11643-1992 are included in ISO
+10646-1:1993. I feel that it is best to think of ISO 10646-1:1993 as
+"just another character set." My philosophy is to support the maximum
+number of character sets and encodings as possible.
+	A note about ordering this standard. If you order through ANSI
+in the United States, try to get an original manual. It is not easy,
+though. You see, ANSI has duplication rights for ISO documents.
+Photocopying Section 26 (pp 262-698) doesn't do the Chinese characters
+much justice, and some characters become hard-to-read. Unfortunately,
+there is no way to indicate that you want an original ISO document
+through ANSI's ordering process, so some post-ordering haggling may
+become necessary.
+	More information on ISO 10646-1:1993 can be found at the
+following URL:
+
+  http://www.unicode.org/
+
+	Japan, China (PRC), and Korea have developed their own
+national standards that are based on ISO 10646-1:1993. They are
+designated as JIS X 0221-1995 (see Section 2.1.4), GB 13000.1-93 (see
+Section 2.2.10), and KS C 5700-1995 (see Section 2.4.5), respectively.
+	Note that these national-standard versions of Unicode are
+aligned differently with its three versions:
+
+  Unicode Version 1.0
+  Unicode Version 1.1 <-> ISO 10646-1:1993, JIS X 0221-1995, GB 13000.1-93
+  Unicode Version 2.0 <-> KS C 5700-1995
+
+One of the major changes made for Unicode Version 2.0 is the inclusion
+of all 11,172 hangul. Versions 1.1 has 6,656 hangul.
+
+
+2.5.2: CCCII
+
+	The Chinese Character Analysis Group in Taiwan developed CCCII
+(Chinese Character Code for Information Interchange) in the 1980s.
+This character set is composed of 94 planes that have 94 rows and 94
+cells (94 x 94 x 94 = 830,584 characters). Furthermore, every six
+planes constitute a "layer" (6 x 94 x 94 = 53,016 characters). The
+following is the contents of each of the 16 layers (the 16th layer
+contains only four planes):
+
+o Layer 1: Symbols and Traditional Chinese characters
+o Layer 2: Simplified Chinese characters from PRC
+o Layers 3 through 12: Variant Chinese character forms
+o Layer 13: Japanese kana and kokuji (Japanese-made kanji)
+o Layer 14: Korean hangul
+o Layer 15: Reserved
+o Layer 16: Miscellaneous characters (Japanese and Korean)
+
+	Layers 1 through 12 have a special meaning and relationship.
+The same code point in these layers is designed to hold the same
+character, but with different forms. Layer 1 code points contain the
+traditional character forms, Layer 2 code points contain the
+simplified character forms (if any), and Layers 3 through 12 contain
+variant character forms (if any). For example, given a Chinese
+character with three forms, its encoding and arrangement may be as
+follows:
+
+  Character Form  Code Point  Layer
+  ^^^^^^^^^^^^^^  ^^^^^^^^^^  ^^^^^
+  Traditional     0x224E41    1
+  Simplified      0x284E41    2
+  Variant         0x2E4E41    3
+
+Note how the second and third bytes (0x4E41) are identical in all
+three instances -- only the first byte's value, which indicates the
+layer, differs. Needless to say, this method of arrangement provides
+easy access to related Chinese character forms. No wonder it is used
+for bibliographic purposes.
+	The first layer is composed as follows:
+
+o Plane 1/Row 2: 56 mathematical symbols
+o Plane 1/Row 3: The ASCII character set
+o Plane 1/Row 11: 35 Chinese punctuation marks
+o Plane 1/Rows 12 through 14: 214 classical radicals
+o Plane 1/Row 15: 41 Chinese numerical symbols, 37 phonetic symbols,
+  and 4 tone marks
+o Plane 1/Rows 16 through 67: 4,808 common Chinese characters
+o Plane 1/Row 68 through Plane 3/Row 64: 17,032 less common Chinese
+  characters
+o Plane 3/Row 65 through Plane 6/Row 5: 20,583 rare Chinese characters
+
+Note that Row 1 of all planes is reserved, and never assigned
+characters. Take this into account when studying the above table
+ranges that span planes (that is, skip Row 1).
+	In addition to the above, there are 11,517 simplified Chinese
+characters in Layer 2 (3,625 are considered PRC simplified forms, and
+the remaining 7,892 are regular simplified forms). This provides a
+total of 53,940 Chinese characters.
+	Further information on CCCII (to include very interesting
+historical notes) can be found on pp 146-149 of John Clews' "Language
+Automation Worldwide: The Development of Character Set Standards" and
+Chapter 6 of Huang & Huang's "An Introduction to Chinese, Japanese,
+and Korean Computing."
+
+
+2.5.3: ANSI Z39.64-1989
+
+	This national standard is designated as ANSI Z39.64-1989 and
+named "East Asian Character Code" (EACC), but was originally known as
+REACC (RLIN East Asian Character Code), that is, before it became a
+national standard. RLIN stands for "Research Libraries Information
+Network," which was developed by the Research Libraries Group (RLG)
+located in Mountain View, California.
+	RLG's Home Page is at the following URL:
+
+  http://www.rlg.org/
+
+	The structure of ANSI Z39.64-1989 is based on CCCII, but with
+a few differences. Many consider it to be superior to and a
+replacement for CCCII (see Section 2.5.2).
+	The ANSI Z39.64-1989 standard is available through ANSI, but
+you should be aware that it is distributed in the form of several
+microfiche. Not a terribly useful storage medium these days. I had my
+set tranformed into tangible printed pages. You can also obtain this
+standard through NISO (National Information Standards Organization)
+Press Fulfillment. Their URL is:
+
+  http://www.niso.org/
+
+	EACC has been designated by the Library of Congress as a
+character set for use in USMARC (United States MAchine-Readable
+Cataloging) records, and is used extensively by East Asian libraries
+across North America.
+	EACC is also being used in Australia for the National CJK
+Project. Check out the following URL for more details:
+
+  http://www.nla.gov.au/1/asian/ncjk/cjkhome.html
+
+	Further information on ANSI Z39.64-1989 (to include very
+interesting historical notes) can be found on pp 150-156 of John
+Clews' "Language Automation Worldwide: The Development of Character
+Set Standards" (although a source at RLG tells me that some of Clews'
+facts are wrong) and Chapter 6 of Huang & Huang's "An Introduction to
+Chinese, Japanese, and Korean Computing."
+	The authoritative paper on EACC is "RLIN East Asian Character
+Code and the RLIN CJK Thesaurus" by Karen Smith Yoshimura and Alan
+Tucker, published in "Proceedings of the Second Asian-Pacific
+Conference on Library Science," May 20-24,1985, Seoul, Korea.
+
+
+2.6: OTHER
+
+	This section includes character set standards that don't
+properly fall under the above sections.
+
+
+2.6.1: GB 8045-87
+
+	GB 8045-87 is a Mongolian character set standard established
+by China (PRC). This standard enumerates 94 Mongolian characters. Of
+these 94 characters, 12 are punctuation (vertically-oriented), and the
+remaining 82 are characters specific to the Mongolian script.
+Mongolian is written vertically like Chinese.
+	I do not discuss the encoding for GB 8045-87 in Part 3, so
+will do it here. The GB 8045-87 manual describes a 7- and 8-bit
+encoding. The 7-bit encoding puts these 94 characters in the standard
+ASCII printable range, namely 0x21 through 0x7E. Code point 0x20 is
+marked as "MSP" which stands for "Mongolian space." The 8-bit encoding
+puts these 94 characters in the range 0xA1 through 0xFE, with the
+"MSP" character at code point 0xA0. The GB 1988-89 set is then encoded
+in the range 0x21 through 0x7E.
+
+
+2.6.2: TCVN-5773:1993
+
+	TCVN-5773:1993 (also called NSCII, which is short for Nom
+Standard Code for Information Interchange) is the Vietnamese analog to
+ISO 10646-1:1993, but adds 1,775 Vietnamese-specific Chinese
+characters. These 1,775 characters are encoded in the range 0xA000
+through 0xA6EE.
+	More information on TCVN-5773:1993 can be found at the
+following URL:
+
+  ftp://unicode.org/pub/MappingTables/EastAsiaMaps/
+
+There are two files at the above URL that pertain to this standard.
+The first is a README, and the second is a Macintosh HyperCard stack
+(requires HyperCard):
+
+  TCVN-NSCII.README
+  TCVN-NSCIIstack_1.0.sea.hqx
+
+
+PART 3: CJK ENCODING SYSTEMS
+
+	These sections describe the various systems for encoding the
+character set standards listed in Part 2. The first two described,
+7-bit ISO 2022 and EUC, are not specific to a locale, and in some
+cases not specific to CJK.
+	The CJK Character Set Server at the following URL can generate
+character sets based on encodings described in this section:
+
+  http://jasper.ora.com/lunde/cjk-char.html
+
+I suggest that you use this as a way to obtain files that illustrate
+these encodings in action.
+	But first, please take a peek at the following table, which is
+an attempt to illustrate how two Chinese characters (that stand for
+"kanji/hanzi/hanja") are encoded using the various methods presented
+in the following sections (character codes as hexadecimal digits, and
+escape sequences or shift sequences as printable characters):
+
+o Japanese (JIS X 0208-1990 & JIS X 0201-1976):
+  - 7-bit ISO 2022        <ESC> & @ <ESC> $ B 0x3441 0x3B7A <ESC> ( J
+  - ISO-2022-JP           <ESC> $ B 0x3441 0x3B7A <ESC> ( J
+  - EUC                   0xB4C1 0xBBFA
+  - Shift-JIS             0x8ABF 0x8E9A
+
+o Simplified Chinese (GB 2312-80 & GB 1988-89 or ASCII):
+  - 7-bit ISO 2022        <ESC> $ A 0x3A3A 0x5756 <ESC> ( T
+  - ISO-2022-CN           <ESC> $ ) A <SO> 0x3A3A 0x5756 <SI>
+  - EUC                   0xBABA 0xD7D6
+  - HZ (HZ-GB-2312)       ~{ 0x3A3A 0x5756 ~}
+  - zW                    zW 0x3A3A 0x5756
+
+o Traditional Chinese (CNS 11643-1992):
+  - 7-bit ISO 2022        <ESC> $ ( G 0x6947 0x4773 <ESC> ( B
+  - ISO-2022-CN           <ESC> $ ) G <SO> 0x6947 0x4773 <SI>
+  - EUC                   0xE9C7 0xC7F3 or 0x8EA1E9C7 0x8EA1C7F3
+
+o Traditional Chinese (Big Five):
+  - Big Five              0xBA7E 0xA672
+
+o Korean (KS C 5601-1992 & ASCII):
+  - 7-bit ISO 2022        <ESC> $ ( C 0x7953 0x6D2E <ESC> ( B
+  - ISO-2022-KR           <ESC> $ ) C <SO> 0x7953 0x6D2E <SI>
+  - EUC                   0xF9D3 0xEDAE
+  - Johab                 0xF7D3 0xF1AE
+
+o CJK (ISO 10646-1:1993, JIS X 0221-1995, GB 13000.1-93, or KS C
+  5700-1995):
+  - UCS-2                 0x6F22 0x5B57
+  - UCS-4                 0x00006F22 0x00005B57
+
+The above should have given you a taste of what information the
+following sections provide.
+
+
+3.1: 7-BIT ISO 2022 ENCODING
+
+	7-bit ISO 2022 is the name commonly given to the encoding
+system that uses escape sequences to shift between character sets.
+(ISO 2022 encoded Japanese text is also known as "JIS" encoding, but
+is different from ISO-2022-JP and ISO-2022-JP-2, and will be explained
+in Section 3.1.3.) This encoding comes from the ISO 2022-1993
+standard.
+	An escape sequence, as the name implies, consists of an escape
+character followed by a sequence of one or more characters. These
+escape sequences are used to change character set of the text
+stream. This may also mean a shift from one- to two-byte-per-character
+mode (or vice versa).
+	7-bit ISO 2022 Character sets fall into two types: one-byte
+and two-byte. CJK character sets, for obvious reasons, fall into the
+latter group.
+	One advantage that 7-bit ISO 2022 encoding has over other
+encoding systems is that its escape sequences specify the character
+set, thus specify the locale. 7-bit ISO 2022 encoding also encodes
+text using only seven-bit bytes, which has the benefit of being able
+to survive Internet travel (e-mail).
+
+
+3.1.1: CODE SPACE
+
+	Each byte in the representation of graphic (printable)
+characters fall into the range 0x21 (decimal 33) through 0x7E (decimal
+126). For one-byte character sets, this means a maximum of 94
+characters. For two-byte character sets, this means a maximum of 8,836
+characters (94 x 94 = 8,836).
+
+  One-byte Characters                           Encoding Range
+  ^^^^^^^^^^^^^^^^^^^                           ^^^^^^^^^^^^^^
+  first byte range                              0x21-0x7E
+
+  Two-byte Characters                           Encoding Range
+  ^^^^^^^^^^^^^^^^^^^                           ^^^^^^^^^^^^^^
+  first byte range                              0x21-0x7E
+  second byte range                             0x21-0x7E
+
+White space and control characters (of which the "escape" character is
+one) are still found in 0x00-0x20 and 0x7F.
+
+
+3.1.2: ISO-REGISTERED ESCAPE SEQUENCES
+
+	The following is a table that provides the ISO-registered
+escape sequences for various one- and two-byte character sets
+mentioned in Part 2 of this document (ISO registration numbers
+provided in the fourth column):
+
+  One-byte Character Set  Escape Sequence      Hexadecimal     ISO Reg
+  ^^^^^^^^^^^^^^^^^^^^^^  ^^^^^^^^^^^^^^^      ^^^^^^^^^^^     ^^^^^^^
+  ASCII (ANSI X3.4-1986)  <ESC> ( B            0x1B2842        6
+  Half-width katakana     <ESC> ( I            0x1B2849        13
+  JIS X 0201-1976 Roman   <ESC> ( J            0x1B284A        14
+  GB 1988-89 Roman        <ESC> ( T            0x1B2854        57
+
+  Two-byte Character Set  Escape Sequence      Hexadecimal     ISO Reg
+  ^^^^^^^^^^^^^^^^^^^^^^  ^^^^^^^^^^^^^^^      ^^^^^^^^^^^     ^^^^^^^
+  JIS C 6226-1978         <ESC> $ @            0x1B2440        42
+  GB 2312-80              <ESC> $ A            0x1B2441        58
+  JIS X 0208-1983         <ESC> $ B            0x1B2442        87
+  KS C 5601-1992          <ESC> $ ( C          0x1B242843      149
+  JIS X 0212-1990         <ESC> $ ( D          0x1B242844      159
+  ISO-IR-165:1992         <ESC> $ ( E          0x1B242845      165
+  JIS X 0208-1990         <ESC> & @ <ESC> $ B  0x1B26401B2442  168
+  CNS 11643-1992 Plane 1  <ESC> $ ( G          0x1B242847      171
+  CNS 11643-1992 Plane 2  <ESC> $ ( H          0x1B242848      172
+  CNS 11643-1992 Plane 3  <ESC> $ ( I          0x1B242849      183
+  CNS 11643-1992 Plane 4  <ESC> $ ( J          0x1B24284A      184
+  CNS 11643-1992 Plane 5  <ESC> $ ( K          0x1B24284B      185
+  CNS 11643-1992 Plane 6  <ESC> $ ( L          0x1B24284C      186
+  CNS 11643-1992 Plane 7  <ESC> $ ( M          0x1B24284D      187
+
+Note that the first four two-byte character sets do not use an opening
+parenthesis (0x28 or "(") in their escape sequences, which means that
+they don't follow the 7-bit ISO 2022 rules precisely. They are shorter
+for historical reasons, and are retained for backwards compatibility.
+Also note that not all of the CJK character set standards described in
+Part 2 have ISO-registered escape sequences.
+	There are other encoding methods that are similar to 7-bit ISO
+2022 in that they are suitable for Internet use, but are locale-
+specific. These include HZ and zW encoding, both of which are specific
+to the GB 2312-80 character set (see Sections 3.3.2 and 3.3.3).
+ISO-2022-JP, ISO-2022-KR, ISO-2022-CN, and ISO-2022-CN-EXT are
+described below.
+
+
+3.1.3: ISO-2022-JP AND ISO-2022-JP-2
+
+	ISO-2022-JP is best described as a subset of 7-bit ISO 2022
+encoding for Japanese, and reflects how Japanese text is encoded for
+e-mail messages. ISO-2022-JP-2 is an extension that supports
+additional character sets.
+	There are only four escape sequences permitted in ISO-2022-JP,
+indicated as follows:
+
+  One-byte Character Set  Escape Sequence      Hexadecimal
+  ^^^^^^^^^^^^^^^^^^^^^^  ^^^^^^^^^^^^^^^      ^^^^^^^^^^^
+  ASCII (ANSI X3.4-1986)  <ESC> ( B            0x1B2842
+  JIS X 0201-1976 Roman   <ESC> ( J            0x1B284A
+
+  Two-byte Character Set  Escape Sequence      Hexadecimal
+  ^^^^^^^^^^^^^^^^^^^^^^  ^^^^^^^^^^^^^^^      ^^^^^^^^^^^
+  JIS C 6226-1978         <ESC> $ @            0x1B2440
+  JIS X 0208-1983         <ESC> $ B            0x1B2442
+
+Note the lack of JIS X 0208-1990, JIS X 0212-1990, and half-width
+katakana escape sequences. The JIS X 0208-1983 escape sequence is used
+to indicate both JIS X 0208-1983 and JIS X 0208-1990 (for practical
+reasons).
+	ISO-2022-JP-2 permits additional escape sequences, indicated
+as follows:
+
+  One-byte Character Set  Escape Sequence      Hexadecimal
+  ^^^^^^^^^^^^^^^^^^^^^^  ^^^^^^^^^^^^^^^      ^^^^^^^^^^^
+  ASCII (ANSI X3.4-1986)  <ESC> ( B            0x1B2842
+  JIS X 0201-1976 Roman   <ESC> ( J            0x1B284A
+
+  Two-byte Character Set  Escape Sequence      Hexadecimal
+  ^^^^^^^^^^^^^^^^^^^^^^  ^^^^^^^^^^^^^^^      ^^^^^^^^^^^
+  JIS C 6226-1978         <ESC> $ @            0x1B2440
+  JIS X 0208-1983         <ESC> $ B            0x1B2442
+  JIS X 0212-1990         <ESC> $ ( D          0x1B242844
+  GB 2312-80              <ESC> $ A            0x1B2441
+  KS C 5601-1992          <ESC> $ ( C          0x1B242843
+
+With the introduction of ISO-2022-KR (see Section 3.1.4), ISO-2022-CN
+(see Section 3.1.5), and ISO-2022-CN-EXT (see Section 3.1.5), the
+usefulness of supporting GB 2312-80 and KS C 5601-1992 can be
+questioned. However, ISO-2022-JP-2 provides support for JIS X
+0212-1990.
+	More detailed information on ISO-2022-JP encoding can be found
+in RFC 1468. And, more detailed information on ISO-2022-JP-2 encoding
+can be found in RFC 1554.
+
+
+3.1.4: ISO-2022-KR
+
+	ISO-2022-KR is similar to ISO-2022-JP (see Section 3.1.3) in
+that it reflects how Korean text is encoded for e-mail messages.
+However, its actual implementation is a bit different. Below is a
+summary.
+	There are only two shift sequences used in ISO-2022-KR,
+indicated as follows:
+
+  One-byte Character Set  Shift Sequence       Hexadecimal
+  ^^^^^^^^^^^^^^^^^^^^^^  ^^^^^^^^^^^^^^       ^^^^^^^^^^^
+  ASCII (ANSI X3.4-1986)  <SI>                 0x0F
+
+  Two-byte Character Set  Shift Sequence       Hexadecimal
+  ^^^^^^^^^^^^^^^^^^^^^^  ^^^^^^^^^^^^^^       ^^^^^^^^^^^
+  KS C 5601-1992          <SO>                 0x0E
+
+Furthermore, the following designator sequence must appear only once,
+at the beginning of a line, before any KS C 5601-1992 characters (this
+usually means that it appears by itself on the first line of the
+file):
+
+  <ESC> $ ) C             0x1B242943
+
+It almost looks the same as the KS C 5601-1992 escape sequence in
+7-bit ISO 2022, but look again. The opening parenthesis (0x28 or "(")
+is replaced by a closing parenthesis (0x29 or ")"). This designator
+sequence serves a different purpose than an escape sequence. It is
+like a flag indicating that "this document contains KS C 5601-1992
+characters." The <SO> and <SI> control characters actually perform the
+switching between one- (ASCII) and two-byte (KS C 5601-1992) codes.
+	More detailed information on ISO-2022-KR encoding can be found
+in RFC 1557.
+
+
+3.1.5: ISO-2022-CN AND ISO-2022-CN-EXT
+
+	ISO-2022-CN and ISO-2022-CN-EXT are similar to ISO-2022-JP
+(see Section 3.1.3) and ISO-2022-KR (see Section 3.1.4) in that they
+reflect how Chinese text is encoded for e-mail messages.
+	Like with ISO-2022-KR, there are only two shift sequences,
+indicated as follows:
+
+  One-byte Character Set  Shift Sequence       Hexadecimal
+  ^^^^^^^^^^^^^^^^^^^^^^  ^^^^^^^^^^^^^^       ^^^^^^^^^^^
+  ASCII (ANSI X3.4-1986)  <SI>                 0x0F
+
+  Two-byte Character Set  Shift Sequence       Hexadecimal
+  ^^^^^^^^^^^^^^^^^^^^^^  ^^^^^^^^^^^^^^       ^^^^^^^^^^^
+  <Too Many to List>      <SO>                 0x0E
+
+But, unlike ISO-2022-KR, there are single shift sequences. Single
+shift means that they are used before every (single) character, not
+before sequences of characters.
+
+  Single Shift Type       Shift Sequence       Hexadecimal
+  ^^^^^^^^^^^^^^^^^       ^^^^^^^^^^^^^^       ^^^^^^^^^^^
+  SS2                     <ESC> N              0x1B4E
+  SS3                     <ESC> O (not zero!)  0x1B4F
+
+	ISO-2022-CN supports the following character sets using SO and
+SS2 designations:
+
+  Character Set           Type   Designation Sequence  Hexadecimal
+  ^^^^^^^^^^^^^           ^^^^   ^^^^^^^^^^^^^^^^^^^^  ^^^^^^^^^^^
+  GB 2312-80              SO     <ESC> $ ) A           0x1B242941
+  CNS 11643-1992 Plane 1  SO     <ESC> $ ) G           0x1B242947
+  CNS 11643-1992 Plane 2  SS2    <ESC> $ * H           0x1B242A48
+
+The designator sequences must appear once on a line before any
+instance of the character set it designates. If two lines contain
+characters from the same character set, both lines must include the
+designator sequence (this is so the text can be displayed correctly
+when scroll back in a window). This is different behavior from
+ISO-2022-KR where the designator sequence appears once in the entire
+file (this is because ISO-2022-KR supports a single two-byte character
+set).
+	ISO-2022-CN-EXT supports the following character sets using
+SO, SS2, and SS3 designations (notice how ISO-2022-CN is still
+supported in the same manner):
+
+  Character Set           Type   Designation Sequence  Hexadecimal
+  ^^^^^^^^^^^^^           ^^^^   ^^^^^^^^^^^^^^^^^^^^  ^^^^^^^^^^^
+  GB 2312-80              SO     <ESC> $ ) A           0x1B242941
+  GB/T 12345-90           SO     NOT REGISTERED
+  ISO-IR-165              SO     <ESC> $ ) E           0x1B242945
+  CNS 11643-1992 Plane 1  SO     <ESC> $ ) G           0x1B242947
+  CNS 11643-1992 Plane 2  SS2    <ESC> $ * H           0x1B242A48
+  GB 7589-87              SS2    NOT REGISTERED
+  GB/T 13131-9X           SS2    NOT REGISTERED
+  CNS 11643-1992 Plane 3  SS3    <ESC> $ + I           0x1B242B49
+  CNS 11643-1992 Plane 4  SS3    <ESC> $ + J           0x1B242B4A
+  CNS 11643-1992 Plane 5  SS3    <ESC> $ + K           0x1B242B4B
+  CNS 11643-1992 Plane 6  SS3    <ESC> $ + L           0x1B242B4C
+  CNS 11643-1992 Plane 7  SS3    <ESC> $ + M           0x1B242B4D
+  GB 7590-87              SS3    NOT REGISTERED
+  GB/T 13132-9X           SS3    NOT REGISTERED
+
+Support for character sets indicated as NOT REGISTERED will be added
+once they are ISO-registered.
+	More detailed information on ISO-2022-CN and ISO-2022-CN-EXT
+encodings can be found in RFC 1922.
+
+
+3.2: EUC ENCODING
+
+	EUC stands for "Extended UNIX Code," and is a rich encoding
+system from ISO 2022-1993 that is designed to handle large or multiple
+character sets. It is primarily used on UNIX systems, such as Sun's
+Solaris.
+	EUC consists of four codes sets, numbered 0 through 3. The
+only code set that is more or less fixed by definition is code set 0,
+which is specified to contain ASCII or a locale's equivalent (such as
+JIS X 0201-1976 for Japanese or GB 1988-89 for PRC Chinese).
+	It is quite common to append the locale name to "EUC" when
+designating a specific instance of EUC encoding. Common designations
+include EUC-JP, EUC-CN, EUC-KR, and EUC-TW.
+
+
+3.2.1: JAPANESE REPRESENTATION
+
+	The following table illustrates the Japanese representation of
+EUC packed format:
+
+  EUC Code Sets                                 Encoding Range
+  ^^^^^^^^^^^^^                                 ^^^^^^^^^^^^^^
+  Code set 0 (ASCII or JIS X 0201-1976 Roman):  0x21-0x7E
+  Code set 1 (JIS X 0208):                      0xA1A1-0xFEFE
+  Code set 2 (half-width katakana):             0x8EA1-0x8EDF
+  Code set 3 (JIS X 0212-1990):                 0x8FA1A1-0x8FFEFE
+
+An earlier version of EUC for Japanese used code set 3 as the user-
+defined range.
+
+
+3.2.2: CHINESE (PRC) REPRESENTATION
+
+	The following table illustrates the Chinese (PRC)
+representation of EUC packed format:
+
+  EUC Code Sets                                 Encoding Range
+  ^^^^^^^^^^^^^                                 ^^^^^^^^^^^^^^
+  Code set 0 (ASCII or GB 1988-89):             0x21-0x7E
+  Code set 1 (GB 2312-80):                      0xA1A1-0xFEFE
+  Code set 2:                                   unused
+  Code set 3:                                   unused
+
+Note how code sets 2 and 3 are unused.
+	The encoding used on Macintosh is quite similar, but has a
+shortened two-byte range (0xA1A1 through 0xFCFE) plus additional
+one-byte code points, namely 0x80 ("u" with dieresis), 0xFD
+("copyright" symbol: "c" in a circle), 0xFE ("trademark" symbol: "TM"
+as a superscript), and 0xFF ("ellipsis" symbol: three dots).
+
+
+3.2.3: CHINESE (TAIWAN) REPRESENTATION
+
+	The following table illustrates the Chinese (Taiwan)
+representation of EUC packed format:
+
+  EUC Code Sets                                 Encoding Range
+  ^^^^^^^^^^^^^                                 ^^^^^^^^^^^^^^
+  Code set 0 (ASCII):                           0x21-0x7E
+  Code set 1 (CNS 11643-1992 Plane 1):          0xA1A1-0xFEFE
+  Code set 2 (CNS 11643-1992 Planes 1-16):      0x8EA1A1A1-0x8EB0FEFE
+  Code set 3:                                   unused
+
+Note how CNS 11643-1992 Plane 1 is redundantly encoded in code set 1
+(two-byte) and code set 2 (four-byte). The second byte of code set 2
+indicates the plane number. For example, 0xA1 is Plane 1 and so on up
+until 0xB0, which is Plane 16.
+
+
+3.2.4: KOREAN REPRESENTATION
+
+	The following table illustrates the Korean representation of
+EUC packed format (this is also known as "Wansung" encoding -- the
+Korean word "wansung" means "pre-compose"):
+
+  EUC Code Sets                                 Encoding Range
+  ^^^^^^^^^^^^^                                 ^^^^^^^^^^^^^^
+  Code set 0 (ASCII or KS C 5636-1993):         0x21-0x7E
+  Code set 1 (KS C 5601-1992):                  0xA1A1-0xFEFE
+  Code set 2:                                   unused
+  Code set 3:                                   unused
+
+Note how code sets 2 and 3 are unused.
+	The encoding used on Macintosh is quite similar, but has a
+shortened two-byte range (0xA1A1 through 0xFDFE) plus additional
+one-byte code points, namely 0x81 ("won" symbol), 0x82 (hyphen), 0x83
+("copyright" symbol: "c" in a circle), 0xFE ("trademark" symbol: "TM"
+as a superscript), and 0xFF ("ellipsis" symbol: three dots).
+	See Section 3.3.17 for a description of Microsoft's extension
+to this encoding, called Unified Hangul Code.
+
+
+3.3: LOCALE-SPECIFIC ENCODINGS
+
+	The encoding systems described in the following sections are
+considered to be locale-specific, namely that are used to encode a
+specific character set standard. This is not to say that they are not
+widely used (actually, some of these are among the most widely used
+encoding systems!), but rather that they are tied to a specific
+character set.
+
+
+3.3.1: SHIFT-JIS
+
+	Shift-JIS (also known as MS Kanji, SJIS, or DBCS-PC) is the
+encoding system used on machines that support MS-DOS or Windows, and
+also for Macintosh (KanjiTalk or Japanese Language Kit). It was
+originally developed by Microsoft Corporation as a way to support the
+Japanese character set on MS-DOS. The following tables provide the
+Shift-JIS encoding ranges:
+
+  Two-byte Standard Characters                  Encoding Ranges
+  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^                  ^^^^^^^^^^^^^^^
+  first byte ranges                             0x81-0x9F, 0xE0-0xEF
+  second byte ranges                            0x40-0x7E, 0x80-0xFC
+
+  Two-byte User-defined Characters              Encoding Ranges
+  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^              ^^^^^^^^^^^^^^^
+  first byte range                              0xF0-0xFC
+  second byte ranges                            0x40-0x7E, 0x80-0xFC
+
+  One-byte Characters                           Encoding Range
+  ^^^^^^^^^^^^^^^^^^^                           ^^^^^^^^^^^^^^
+  Half-width katakana                           0xA1-0xDF
+  ASCII/JIS-Roman                               0x21-0x7E
+
+It is important to note that the user-defined range does not
+correspond to code points in other encodings that support Japanese,
+such as 7-bit ISO 2022 or EUC. This is a portability problem. It is
+also unique in that it does not support the JIS X 0212-1990 character
+set standard.
+	The encoding used on Macintosh is quite similar to the above
+table, but has additional one-byte code points, namely 0x80
+(backslash), 0xFD ("copyright" symbol: "c" in a circle), 0xFE
+("trademark" symbol: "TM" as a superscript), and 0xFF ("ellipsis"
+symbol: three dots).
+
+
+3.3.2: HZ (HZ-GB-2312)
+
+	HZ is a simple yet very powerful and reliable system for
+encoding GB 2312-80 text which was developed by Fung Fung Lee
+(lee@umunhum.stanford.edu). HZ encoding is commonly used when
+exchanging e-mail or posting messages to Usenet News (specifically, to
+alt.chinese.text).
+	The actual encoding ranges used for one- and two-byte
+characters is almost identical to 7-bit ISO 2022 encoding (see Section
+3.1.1). The first-byte range is limited to 0x21 through 0x77. But,
+instead of using an escape sequence to shift between one- and two-byte
+character modes, a simple string of two printable characters is used.
+
+  One-byte Character Set  Shift Sequence       Hexadecimal
+  ^^^^^^^^^^^^^^^^^^^^^^  ^^^^^^^^^^^^^^       ^^^^^^^^^^^
+  ASCII                   ~}                   0x7E7D
+
+  Two-byte Character Set  Shift Sequence       Hexadecimal
+  ^^^^^^^^^^^^^^^^^^^^^^  ^^^^^^^^^^^^^^       ^^^^^^^^^^^
+  GB 2312-80              ~{                   0x7E7B
+
+The tilde character (0x7E) is interpreted as an escape character in HZ
+encoding, so it has special meaning. If a tilde character is to appear
+in one-byte-per-character mode, it must be doubled (so ~~ would appear
+as just ~). This means that there are three escape sequences used in
+HZ encoding:
+
+  Escape Sequence  Meaning
+  ^^^^^^^^^^^^^^^  ^^^^^^^
+  ~~               ~ in one-byte-per-character mode
+  ~}               Shift into one-byte-per-character mode
+  ~{               Shift into two-byte-per-character mode
+
+There is also a fourth escape sequence, namely ~ plus a newline
+character (~\n). This escape sequence is a line-continuation marker to
+be consumed with no output produced.
+	This method works without problems because the shift sequences
+represent empty positions in the very last row of the GB 2312-80 table
+(actually, the second- and third-from-last code points). HZ encoding
+makes 77 of the 94 rows accessible, and because there are no defined
+characters beyond row 77, this causes no problems.
+	The complete HZ specification is part of the HZ package,
+described in RFC 1843, and available in HTML format. These are
+available at the following URLs:
+
+  ftp://ftp.ifcss.org/pub/software/unix/convert/HZ-2.0.tar.gz
+  ftp://ftp.ora.com/pub/examples/nutshell/ujip/Ch9/rfc-1843.txt
+  http://umunhum.stanford.edu/~lee/chicomp/HZ_spec.html
+
+In addition, RFC 1842 establishes "HZ-GB-2312" as the "charset"
+parameter in MIME-encoded e-mail headers. Its properties are identical
+to HZ encoding as described in RFC 1843.
+
+
+3.3.3: zW
+
+	zW encoding, developed by Ya-Gui Wei and Edmund Lai, is older
+than and somewhat similar to HZ encoding (HZ is considered to be a
+better encoding system, and users are encouraged to switch over to HZ
+encoding).
+	zW encoding is named by how it encodes each line of GB 2312-80
+text, namely lines that contain Chinese text must begin with the two
+characters "z" and "W" ("zW"). This encoding method does not permit
+the mixture of one- (ASCII) and two-byte (GB 2312-80) characters on a
+per-character basis, but rather on a per-line basis. That is, each
+line can contain only Chinese or ASCII text, but not both.
+	More information on zW encoding can be found as part of the
+ZWDOS package available at the following URL:
+
+  ftp://ftp.ifcss.org/pub/software/dos/ZWDOS/
+
+
+3.3.4: BIG FIVE
+
+	Big Five is the encoding system used on machines that support
+MS-DOS or Windows, and also for Macintosh (such as the Chinese
+Language Kit or the fully-localized operating system).
+
+  Two-byte Standard Characters                  Encoding Ranges
+  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^                  ^^^^^^^^^^^^^^^
+  first byte range                              0xA1-0xFE
+  second byte ranges                            0x40-0x7E, 0xA1-0xFE
+
+  One-byte Characters                           Encoding Range
+  ^^^^^^^^^^^^^^^^^^^                           ^^^^^^^^^^^^^^
+  ASCII                                         0x21-0x7E
+
+	The encoding used on Macintosh is quite similar to the above,
+but has a slightly shortened two-byte range (second byte range up to
+0xFC only) plus additional one-byte code points, namely 0x80
+(backslash), 0xFD ("copyright" symbol: "c" in a circle), 0xFE
+("trademark" symbol: "TM" as a superscript), and 0xFF ("ellipsis"
+symbol: three dots).
+
+
+3.3.5: JOHAB
+
+	Korean hangul characters are typically encoded in what is
+known as pre-combined form, namely 2 or 3 hangul elements bound into a
+single character. KS C 5601-1992 enumerates 2,350 such pre-combined
+forms. While this number is felt to be sufficient for most purposes,
+it does not account for the total number of possible permutations. The
+encoding system that encodes all possible pre-combined hangul is known
+as Johab encoding (also known as "two-byte combination code" -- the
+Korean word "johab" means "combine"), and is described in Annex 3 of
+the KS C 5601-1992 standard. This encoding is almost like encoding all
+possible three-letter words in English -- while all combinations are
+possible, only a fraction represent *real* words.
+	Pre-combined hangul can be composed of 19 different initial,
+21 different medial, and 27 different final hangul elements (28,
+actually, if you count the placeholder). This provides a maximum of
+11,172 pre-combined hangul. Of these 67 hangul elements, 51 are unique
+(some can occur in different positions). Each of these positions are
+encoded using five bits each (five bits can encode up to 32 unique
+objects). The encoding array looks as follows:
+
+o Bit 1: always on
+o Bits 2-6: initial hangul element
+o Bits 7-11: medial hangul element
+o Bits 12-16: final hangul element
+
+Initial and final elements are consonants, and the medial elements are
+vowels. This encoding must be treated as a 16-bite entity because the
+bit array of the medial hangul element spans the first and second byte.
+	Johab encoding also provides the complete set of KS C 5601-
+1992 symbols and hanja, but in different code points. Annex 3 of the
+KS C 5601-1992 manual (pp 33-34) contains a complete symbol and hanja
+mapping table between EUC and Johab code points. (The KS C 5601-1989
+manual did not have this.) The code space ranges for Johab encoding
+are as follows:
+
+  One-byte Characters                           Encoding Range
+  ^^^^^^^^^^^^^^^^^^^                           ^^^^^^^^^^^^^^
+  ASCII or KS C 5636-1993                       0x21-0x7E
+
+  Two-byte Pre-combined Hangul                  Encoding Ranges
+  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^                  ^^^^^^^^^^^^^^^
+  first byte range                              0x84-0xD3
+  second byte ranges                            0x41-0x7E, 0x81-0xFE
+
+  Two-byte Symbols and Hanja                    Encoding Ranges
+  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^                  ^^^^^^^^^^^^^^^
+  first byte ranges                             0xD8-0xDE, 0xE0-0xF9
+  second byte ranges                            0x31-0x7E, 0x91-0xFE
+
+Note that the second byte ranges encode a total of 188 characters, and
+that the second byte ranges for hangul and symbols/hanja are slightly
+different (yet the same size, namely 188 characters).
+	Here is a summary of the above table, which better describes
+what is encoded where. Rows 0x84 through 0xD3 provide 80 rows of 188
+characters each (15,040 code points, which is more than enough for the
+11,172 pre-combined hangul). Row 0xD8 provides 188 user-defined
+positions, the same as Rows 41 and 94 in the standard KS C 5601-1992
+table. Rows 0xD9 through 0xDE encode Rows 1 through 12 of the standard
+KS C 5601-1992 table (symbols). Rows 0xE0 through 0xF9 encode Rows 42
+through 94 of the KS C 5601-1992 table (hanja). The following URL
+provides a complete mapping table for the KS C 5601-1992 symbols and
+hanja:
+
+  ftp://ftp.ora.com/pub/examples/nutshell/ujip/map/non-hangul-codes.txt
+
+The following URLs provides similar information (they are the same
+file), but only for the 11,172 pre-combined hangul:
+
+  ftp://ftp.ora.com/pub/examples/nutshell/ujip/map/hangul-codes.txt
+  ftp://unicode.org/pub/MappingTables/EastAsiaMaps/hangul-codes.txt
+
+	Of further interest may be that Microsoft designates Johab
+encoding as its Code Page 1361. Microsoft if planning to support Johab
+encoding for Korean Windows NT.
+
+
+3.3.6: N-BYTE HANGUL
+
+	In the days before full two-byte capable operating systems,
+each of the 51 basic hangul elements were encoding using a single
+(7-bit) byte. The encoding range spans 0x40 through 0x7C, but there
+are several unassigned gaps. This is known as the "N-byte Hangul"
+code, and is described in Annex 4 (page 35) of the KS C 5601-1992
+manual.
+	The following table illustrates these 51 one-byte code points
+(the pronunciation or meaning of the hangul element is provided in
+parentheses) and how they map to the three 5-bit arrays in Johab
+encoding (expressed as binary patterns):
+
+  Element        Initial  Medial   Final
+  ^^^^^^^        ^^^^^^^  ^^^^^^   ^^^^^
+  0x40 ("fill")  00001    00010    00001
+  0x41 (g)       00010    *****    00010
+  0x42 (gg)      00011    *****    00011
+  0x43 (gs)      *****    *****    00100
+  0x44 (n)       00100    *****    00101
+  0x45 (nj)      *****    *****    00110
+  0x46 (nh)      *****    *****    00111
+  0x47 (d)       00101    *****    01000
+  0x48 (dd)      00110    *****    *****
+  0x49 (r)       00111    *****    01001
+  0x4A (rg)      *****    *****    01010
+  0x4B (rm)      *****    *****    01011
+  0x4C (rb)      *****    *****    01100
+  0x4D (rs)      *****    *****    01101
+  0x4E (rt)      *****    *****    01110
+  0x4F (rp)      *****    *****    01111
+  0x50 (rh)      *****    *****    10000
+  0x51 (m)       01000    *****    10001
+  0x52 (b)       01001    *****    10011
+  0x53 (bb)      01010    *****    *****
+  0x54 (bs)      *****    *****    10100
+  0x55 (s)       01011    *****    10101
+  0x56 (ss)      01100    *****    10110
+  0x57 (ng)      01101    *****    10111
+  0x58 (j)       01110    *****    11000
+  0x59 (jj)      01111    *****    *****
+  0x5A (c)       10000    *****    11001
+  0x5B (k)       10001    *****    11010
+  0x5C (t)       10010    *****    11011
+  0x5D (p)       10011    *****    11100
+  0x5E (h)       10100    *****    11101
+  0x5F UNASSIGNED
+  0x60 UNASSIGNED
+  0x61 UNASSIGNED
+  0x62 (a)       *****    00011    *****
+  0x63 (ae)      *****    00100    *****
+  0x64 (ya)      *****    00101    *****
+  0x65 (yae)     *****    00110    *****
+  0x66 (eo)      *****    00111    *****
+  0x67 (e)       *****    01010    *****
+  0x68 UNASSIGNED
+  0x69 UNASSIGNED
+  0x6A (yeo)     *****    01011    *****
+  0x6B (ye)      *****    01100    *****
+  0x6C (o)       *****    01101    *****
+  0x6D (wa)      *****    01110    *****
+  0x6E (wae)     *****    01111    *****
+  0x6F (oe)      *****    10010    *****
+  0x70 UNASSIGNED
+  0x71 UNASSIGNED
+  0x72 (yo)      *****    10011    *****
+  0x73 (u)       *****    10100    *****
+  0x74 (weo)     *****    10101    *****
+  0x75 (we)      *****    10110    *****
+  0x76 (wi)      *****    10111    *****
+  0x77 (yu)      *****    11010    *****
+  0x78 UNASSIGNED
+  0x79 UNASSIGNED
+  0x7A (eu)      *****    11011    *****
+  0x7B (yi)      *****    11100    *****
+  0x7C (i)       *****    11101    *****
+
+	There are utilities to convert N-byte Hangul code to other,
+more widely-used, encoding methods. Pointers to these and other code
+conversion utilities can be found in Section 4.7.
+
+
+3.3.7: UCS-2
+
+	UCS-2 (Universal Character Set containing 2 bytes) encoding is
+one way to encode ISO 10646-1:1993 text, and is considered identical
+to Unicode encoding. Its encoding range, which is quite simple, is as
+follows:
+
+  ISO 10646-1:1993 Characters                   Encoding Range
+  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^                  ^^^^^^^^^^^^^^
+  first byte range                              0x00-0xFF
+  second byte range                             0x00-0xFF
+
+Yes, folks, the whole range of 65,536 possible code points are
+available for encoding characters. The "signature" that indicates a
+file using UCS-2 is as follows:
+
+  0xFEFF
+
+	Escape sequences for UCS-2 have already been registered with
+ISO, and are as follows:
+
+  ISO 10646-1:1993        Escape Sequence      Hexadecimal     ISO Reg
+  ^^^^^^^^^^^^^^^^        ^^^^^^^^^^^^^^^      ^^^^^^^^^^^     ^^^^^^^
+  UCS-2 Level 1           <ESC> % / @          0x1B252F40      162
+  UCS-2 Level 2           <ESC> % / C          0x1B252F43      174
+  UCS-2 Level 3           <ESC> % / E          0x1B252F45      176
+
+So what do these three levels mean? Level 3 means all characters in
+ISO 10646-1:1993 with no restrictions (0x0000 through 0xFFFF).
+	Level 2 begins to restrict the character set by not including
+the following characters or character ranges:
+
+  0x0300-0x0345  0x09D7         0x0BD7         0x11A8-0x11F9
+  0x0360-0x0361  0x0A3C         0x0C55-0x0C56  0x20D0-0x20E1
+  0x0483-0x0486  0x0A70-0x0A71  0x0CD5-0x0CD6  0x302A-0x302F
+  0x093C         0x0ABC         0x0D57         0x3099-0x309A
+  0x0953-0x0954  0x0B3C         0x1100-0x1159  0xFE20-0xFE23
+  0x09BC         0x0B56-0x0B57  0x115F-0x11A2
+
+These are all combining characters, and represent 364 code points.
+	Level 1 further restricts the character set by not including
+the following characters or character ranges:
+
+  0x05B0-0x05B9  0x09BE-0x09C4  0x0B47-0x0B48  0x0D02-0x0D03
+  0x05BB-0x05BD  0x09C7-0x09C8  0x0B4B-0x0B4D  0x0D3E-0x0D43
+  0x05BF         0x09CB-0x09CD  0x0B82-0x0B83  0x0D46-0x0D48
+  0x05C1-0x05C2  0x09E2-0x09E3  0x0BBE-0x0BC2  0x0D4A-0x0D4D
+  0x064B-0x0652  0x0A02         0x0BC6-0x0BC8  0x0E31
+  0x0670         0x0A3E-0x0A42  0x0BCA-0x0BCD  0x0E34-0x0E3A
+  0x06D6-0x06E4  0x0A47-0x0A48  0x0C01-0x0C03  0x0E47-0x0E4E
+  0x06E7-0x06E8  0x0A4B-0x0A4D  0x0C3E-0x0C44  0x0EB1
+  0x06EA-0x06ED  0x0A81-0x0A83  0x0C46-0x0C48  0x0EB4-0x0EB9
+  0x0901-0x0903  0x0ABE-0x0AC5  0x0C4A-0x0C4D  0x0EBB-0x0EBC
+  0x093E-0x094D  0x0AC7-0x0AC9  0x0C82-0x0C83  0x0EC8-0x0ECD
+  0x0951-0x0952  0x0ACB-0x0ACD  0x0CBE-0x0CC4  0xFB1E
+  0x0962-0x0963  0x0B01-0x0B03  0x0CC6-0x0CC8
+  0x0981-0x0983  0x0B3E-0x0B43  0x0CCA-0x0CCD
+
+These, too, are all combining characters, and represent 586 code
+points (222 above plus the 364 characters from the Level 2
+restriction).
+
+
+3.3.8: UCS-4
+
+	UCS-4 (Universal Character Set containing 4 bytes) encoding is
+another way to encode ISO 10646-1:1993 text, and is used for future
+expansion of the character set. Its encoding range is as follows:
+
+  ISO 10646-1:1993 Characters                   Encoding Range
+  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^                  ^^^^^^^^^^^^^^
+  first byte range                              0x00-0x7F
+  second byte range                             0x00-0xFF
+  third byte range                              0x00-0xFF
+  fourth byte range                             0x00-0xFF
+
+Note that the first byte range only goes up to 0x7F. This means that
+UCS-4 is a 31-bit encoding. And, in case you're wondering, 31 bits
+provide 2,147,483,648 code points. The "signature" that indicates a
+file using UCS-4 is as follows:
+
+  0x0000 0xFEFF
+
+	Escape sequences for UCS-4 have already been registered with
+ISO, and are as follows:
+
+  ISO 10646-1:1993        Escape Sequence      Hexadecimal     ISO Reg
+  ^^^^^^^^^^^^^^^^        ^^^^^^^^^^^^^^^      ^^^^^^^^^^^     ^^^^^^^
+  UCS-4 Level 1           <ESC> % / A          0x1B252F41      163
+  UCS-4 Level 2           <ESC> % / D          0x1B252F44      175
+  UCS-4 Level 3           <ESC> % / F          0x1B252F46      177
+
+See the end of Section 3.3.7 for a description of these three levels.
+But, in the case of UCS-4, simply prepend "0000" to all the values.
+
+
+3.3.9: UTF-7
+
+	It turns out that *raw* ISO 10646-1:1993 encoding (that is,
+UCS-2 or UCS-4) can cause problems because null bytes (0x00) are
+possible (and frequent). Several UTFs (UCS Transformation Formats)
+have been developed to deal with this and other problems. I must admit
+that I don't know too much about UTFs, and what I provide below is
+minimal, but does include pointers to more complete descriptions.
+	UTF-7 is a mail-safe 7-bit transformation format for UCS-2
+(including UTF-16). It uses straight ASCII for many ASCII characters,
+and switches into a Base64 encoding of UCS-2 or UTF-16 for everything
+else. It was designed to be usable in MIME-compliant e-mail headers as
+well as message bodies, and to pass through gateways to non-ASCII mail
+systems (like Bitnet). More detailed information on UTF-7 can be found
+in RFC 1642, and a UTF-7 converter is available. The following URLs
+provide this information:
+
+  http://www.stonehand.com/unicode/standard/utf7.html
+  ftp://unicode.org/pub/Programs/ConvertUTF/
+
+
+3.3.10: UTF-8
+
+	UTF-8 (also known as UTF-2 or FSS-UTF -- FSS stands for "file
+system safe") can represent any character in UCS-2 and UCS-4, and is
+officially an annex to ISO 10646-1:1993. It is different from UTF-7 in
+that it encodes character sets into 8-bit bytes. UCS-2 and UCS-4 have
+problems with some file systems and utilities, so this UTF was
+developed.
+	More detailed information on UTF-8 and its relationship with
+ISO 10646-1:1993 can be found at the following URLs:
+
+  http://www.stonehand.com/unicode/standard/utf8.html
+  ftp://unicode.org/pub/Programs/ConvertUTF/
+
+	X/Open Company Limited also published a document that
+describes UTF-8 in detail (they call it FSS-UTF), and you can find
+information about it at the following URL:
+
+  http://www.xopen.co.uk/public/pubs/catalog/c501.htm
+
+The new programming language called Java supports Unicode through
+UTF-8. More information on Java is at the following URL:
+
+  http://www.javasoft.com/
+
+
+3.3.11: UTF-16
+
+	UTF-16 (formerly UCS-2E), like UTF-8, is now officially an
+annex to ISO 10646-1:1993. From what I've read, UTF-16 transforms
+UCS-4 into a 16-bit form. UTF-16 can then be further encoded in UTF-7
+or UTF-8 (but doing this is not according to the standard -- there is
+little to gain by doing so).
+	More detailed information on UTF-16 and its relationship with
+ISO 10646-1:1993 can be found at the following URLs:
+
+  http://www.stonehand.com/unicode/standard/utf16.html
+  ftp://unicode.org/pub/Programs/ConvertUTF/
+
+
+3.3.12: ANSI Z39.64-1989
+
+	The encoding used for ANSI Z39.64-1989 (and CCCII) is three-
+byte 7-bit ISO 2022, namely the following code space:
+
+  Three-byte ANSI Z39.64-1989                   Encoding Range
+  ^^^^^^^^^^^^^^^^^^^^^^^^^^^                   ^^^^^^^^^^^^^^
+  first byte range                              0x21-0x7E
+  second byte range                             0x21-0x7E
+  third byte range                              0x21-0x7E
+
+
+3.3.13: BASE64
+
+	Base64 encoding is mentioned here only because of its common
+usage in e-mail headers, and relationship with MIME (Multi-purpose
+Internet Mail Extensions). It is also a source of confusion. Base64 is
+a method of encoding arbitrary bytes into the safest 64-character
+ASCII subset, and is defined in RFC 1341 (which adapted it from RFC
+1113). RFC 1341 was made obsolete by RFC 1521. RFC 1522 also provides
+useful information, particularly for handling non-ASCII text, and
+obsoletes RFC 1342.
+	Here is how it works. Every three bytes are encoded as a
+four-byte sequence. That is, the 24 bits that make up the three bytes
+are split into four 6-bit segments (6 bits can encode up to 64
+characters). Each 6-bit segment is then converted into a character in
+the Base64 Alphabet (see below). There is a 65th character, "=", which
+has a special purpose (it functions as a "pad" if a full three-byte
+sequence is not found). This all may sound a bit like uuencoding, but
+it is different. The Base64 Alphabet is as follows:
+
+  ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/
+
+	My name, written in Japanese kanji, is as follows when it is
+EUC-encoded (six bytes, expressed as three groups of hexadecimal
+values, one group for each character):
+
+  0xBEAE 0xCED3 0xB7F5
+
+When these three EUC-encoded characters are converted to Base64
+encoding, they appear as follows (eight bytes):
+
+  vq7O07f1
+
+	Base64 encoding is most commonly used for encoding non-ASCII
+text that appears in e-mail headers. Of all the portions of an e-mail
+message, its header gets manipulated the most during transmission, and
+Base64 encoding offers a safe way to further encode non-ASCII text so
+that it is not altered by mail-routing software. This is where Base64
+encoding can cause confusion. For example, what goes through your mind
+when you see the following chunk o' text?
+
+  From: lunde@adobe.com (=?ISO-2022-JP?B?vq7O07f1?=)
+
+Many folks think that they are seeing ISO-2022-JP encoding. Not
+true. The "ISO-2022-JP" portion is just a flag that indicates the
+original encoding before Base64 encoding was applied. The actual
+Base64-encoded portion is enclosed between question marks (?) as
+follows:
+
+  From: lunde@adobe.com (=?ISO-2022-JP?B?vq7O07f1?=)
+                                        >^^^^^^^^<
+
+The whole string enclosed in parentheses has several components, and
+the following explains their purpose and relationships (using the
+above string as an example):
+
+  Component      Explanation
+  ^^^^^^^^^      ^^^^^^^^^^^
+  =?             Signals start of encoded string
+  ISO-2022-JP    Charset name ("ISO-2022-JP" is for Japanese)
+  ?              Delimiter
+  B              Encoding ("B" is for Base64)
+  ?              Delimiter
+  vq7O07f1       Example string of type "charset" encoded by "encoding"
+  ?=             Signals end of encoded string
+
+	One typically does not need to worry about encoding text as
+Base64 (MIME-compliant mailing software usually performs this task for
+you). The problem is usually trying to decode Base64-encoded text. A
+Base64 decoder is available in Perl at the following URL:
+
+  ftp://ftp.ora.com/pub/examples/nutshell/ujip/perl/b64decode.pl
+
+Note that this program takes "raw" Base64 data as input. Any non-
+Base64 stuff must be stripped. I usually run this from within Mule
+("C-u M-| b64decode.pl") after defining a region around the Base64-
+encoded material. I hope to replace this program soon with one that
+automatically recognizes the Base64-encoded portions.
+	Most MIME-compliant e-mail software can decode Base64-encoded
+text.
+
+
+3.3.14: IBM DBCS-HOST
+
+	The oldest two-byte encoding system is IBM's DBCS-Host. DBCS
+stands for Double-Byte Character Set. DBCS-Host is still in use on
+IBM's mainframe computer systems (hence the use of "Host").
+	DBCS-Host encoding is EBCDIC-based, and uses Shift characters,
+0x0E and 0x0F, to switch between one- and two-byte mode. Its encoding
+specifications are as follows:
+
+  Two-byte Characters                           Encoding Range
+  ^^^^^^^^^^^^^^^^^^^                           ^^^^^^^^^^^^^^
+  first byte range                              0x41-0xFE
+  second byte range                             0x41-0xFE
+
+  Two-byte "Space" Character                    Code Point
+  ^^^^^^^^^^^^^^^^^^^^^^^^^^                    ^^^^^^^^^^
+  first- and second byte                        0x4040
+
+  One-byte Characters                           Encoding Range
+  ^^^^^^^^^^^^^^^^^^^                           ^^^^^^^^^^^^^^
+  EBCDIC                                        0x41-0xF9
+
+  Shifting Characters                           Code Point
+  ^^^^^^^^^^^^^^^^^^^                           ^^^^^^^^^^^^^^
+  Two-byte                                      0x0E
+  One-byte                                      0x0F
+
+This same encoding specification is shared by all of IBM's CJK
+character sets, namely for Japanese, Simplified Chinese, Traditional
+Chinese, and Korean.
+
+
+3.3.15: IBM DBCS-PC
+
+	IBM's DBCS-PC encoding is used on IBM personal computers (that
+is where the "PC" comes from). DBCS-PC encoding is ASCII-based, and
+uses the values of characters' bytes themselves to switch between one-
+and two-byte mode. Its encoding specifications are as follows:
+
+  Two-byte Characters                           Encoding Ranges
+  ^^^^^^^^^^^^^^^^^^^                           ^^^^^^^^^^^^^^^
+  first byte range                              0x81-0xFE
+  second byte range                             0x40-0x7E, 0x80-0xFE
+
+  One-byte Characters                           Encoding Range
+  ^^^^^^^^^^^^^^^^^^^                           ^^^^^^^^^^^^^^
+  ASCII                                         0x21-0x7E
+
+This same encoding specification is shared by all of IBM's CJK
+character sets, namely for Japanese, Simplified Chinese, Traditional
+Chinese, and Korean.
+	DBCS-PC encoding for Japanese, although conforming to the
+above encoding specifications, actually uses the same encoding
+specifications for Shift-JIS, to include the full user-defined range
+(see Section 3.3.1 for more details on Shift-JIS encoding). One big
+accommodation is the half-width katakana range, namely 0xA1 through
+0xDF. Further, the DBCS-PC code space that is outside the Shift-JIS
+specification is unused.
+	DBCS-PC encoding for Korean uses the equivalent of EUC code
+set 1 code points (0xA1A1 through 0xFEFE) for those characters that
+are common with KS C 5601-1992. Those characters that are not common
+with KS C 5601-1992, namely IBM's extensions, are within the DBCS-PC
+encoding space, but outside EUC encoding space (0x9A through 0xA0).
+Many hanja and pre-combined hangul are part of IBM's Korean extension.
+	Note that DBCS-PC is sort of useless without a corresponding
+SBCS (Single-Byte Character Set) for the one-byte range. Mixing DBCS
+and SBCS results in a MBCS (Multiple-Byte Character Set). How these
+are mixed to form MBCSs is detailed in Section 3.4.
+
+
+3.3.16: IBM DBCS-/TBCS-EUC
+
+	IBM has also developed DBCS-EUC and TBCS-EUC encodings. TBCS
+stands for Triple-Byte Character Set. These essentially follow the EUC
+encoding specifications, and were developed for use with IBM's AIX
+(Advanced Interactive Executive) operating system, which is
+UNIX-based.
+	Refer to Section 3.2 for all the details on EUC encoding.
+
+
+3.3.17: UNIFIED HANGUL CODE
+
+	Microsoft has developed what is called "Unified Hangul Code"
+(UHC) for its Windows 95 operating system (this was also known as
+"Extended Wansung"). It is the optional, not standard, character set
+of Win95K.
+	UHC provides full compatibility with KS C 5601-1992 EUC
+encoding (see Section 3.2.4), but adds additional encoding ranges for
+holding additional pre-combined hangul (more precisely, the 8,822 that
+are needed to fully support the Johab character set). The following is
+a table that provides the encoding ranges for UHC encoding:
+
+  Two-byte Standard Characters                  Encoding Ranges
+  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^                  ^^^^^^^^^^^^^^^
+  first byte range                              0x81-0xFE
+  second byte ranges                            0x41-0x5A, 0x61-0x7A,
+                                                and 0x81-0xFE
+
+  One-byte Characters                           Encoding Range
+  ^^^^^^^^^^^^^^^^^^^                           ^^^^^^^^^^^^^^
+  ASCII                                         0x21-0x7E
+
+Note that 0xA1A1 through 0xFEFE in the above encoding is still
+identical, in terms of character-to-code allocation, with KS C 5601-
+1992 in EUC encoding.
+	Appendix G (pp 345-406) of "Developing International Software
+for Windows 95 and Windows NT" by Nadine Kano illustrates the KS C
+5601-1992 character set standard plus these Microsoft extensions
+(8,822 pre-combined hangul) by UHC code (Microsoft calls this Code
+Page 949).
+
+
+3.3.18: TRON CODE
+
+	TRON (The Real-time Operating system Nucleus) is an OS
+developed in Japan some time ago. Personal Media Corporation has done
+work to develop BTRON (Business TRON), which is unique in that it is
+the only commercially-available OS that supports JIS X 0212-1990.
+	TRON Code provides a one- and two-byte encoding space and a
+method for switching between them.
+	The following is how the two-byte space in TRON Code is
+allocated:
+
+  A-Zone (8,836 characters; JIS X 0208-1990)    Encoding Range
+  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^    ^^^^^^^^^^^^^^
+  first byte range                              0x21-0x7E
+  second byte range                             0x21-0x7E
+
+  B-Zone (11,844 characters; JIS X 0212-1990)   Encoding Range
+  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   ^^^^^^^^^^^^^^
+  first byte range                              0x80-0xFD
+  second byte range                             0x21-0x7E
+
+  C-Zone (11,844 characters; unassigned)        Encoding Range
+  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^        ^^^^^^^^^^^^^^
+  first byte range                              0x21-0x7E
+  second byte range                             0x80-0xFD
+
+  D-Zone (15,876 characters; unassigned)        Encoding Range
+  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^        ^^^^^^^^^^^^^^
+  first byte range                              0x80-0xFD
+  second byte range                             0x80-0xFD
+
+Note how the B-Zone is larger that the conventional 94-by-94
+matrix. In fact, the JIS X 0212-1990 portion of the B-Zone is
+restricted to 0xA121-0xFD7E (93-by-94 matrix -- 0xFE as a first-byte
+value is unavailable, and you will see why in a minute).
+	TRON Code implements "language specifying codes" consisting of
+two bytes as follows:
+
+  Two-byte Japanese                             0xFE21
+  One-byte English                              0xFE80
+
+0xFE21 in a one-byte stream invokes two-byte Japanese mode, and 0xFE80
+in a two-byte stream invokes one-byte English mode.
+	The following is the one-byte encoding range for TRON Code:
+
+  One-byte Characters                           0x21-0x7E and 0x80-0xFD
+
+Control codes are in 0x00-0x20 and 0x7F (the usual ASCII control code
+range). Also, 0xA0 is reserved as a fixed-width space character.
+
+
+3.3.19: GBK
+
+	GBK is an extension to GB 2312-80 that adds all ISO 10646-
+1:1993 (GB 13000.1-93) hanzi not already in GB 2312-80. GBK is defined
+as a normative annex of GB 13000.1-93 (see Section 2.2.10). The "K" in
+"GBK" is the first sound in the Chinese word meaning "extension" (read
+"Kuo Zhan").
+	GBK is divided into five levels as follows:
+
+  Level  Encoded Range  Total Code Points  Total Encoded Characters
+  ^^^^^  ^^^^^^^^^^^^^  ^^^^^^^^^^^^^^^^^  ^^^^^^^^^^^^^^^^^^^^^^^^
+  GBK/1  0xA1A1-0xA9FE    846                717
+  GBK/2  0xB0A1-0xF7FE  6,768              6,763
+  GBK/3  0x8140-0xA0FE  6,080              6,080
+  GBK/4  0xAA40-0xFEA0  8,160              8,160
+  GBK/5  0xA840-0xA9A0    192                166
+
+	There are also 1,894 user-defined code points as follows:
+
+  Encoded Range  Total Code Points
+  ^^^^^^^^^^^^^  ^^^^^^^^^^^^^^^^^
+  0xAAA1-0xAFFE  564
+  0xF8A1-0xFEFE  658
+  0xA140-0xA7A0  672
+
+	GBK thus provides a total of 23,940 code points, 21,886 of
+which are assigned.
+	Each "row" in the GBK code table consists of 190 characters.
+The following describes the encoding ranges of GBK in detail:
+
+  Two-byte Standard Characters                  Encoding Ranges
+  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^                  ^^^^^^^^^^^^^^^
+  first byte range                              0x81-0xFE
+  second byte ranges                            0x40-0x7E and 0x80-0xFE
+
+  One-byte Characters                           Encoding Range
+  ^^^^^^^^^^^^^^^^^^^                           ^^^^^^^^^^^^^^
+  ASCII                                         0x21-0x7E
+
+Note that the sub-range 0xA1A1-0xFEFE in the above encoding is still
+identical, in terms of character-to-code allocation, with GB 2312-80
+in EUC encoding. GBK is therefore backward-compatible with GB 2312-80
+and forward-compatible with ISO 10646-1:1993.
+	GBK is the standard character set and encoding for the
+Simplified Chinese version of Windows 95.
+
+
+3.4: CJK CODE PAGES
+
+	Many times one reads about references to "Code Pages" in
+material about CJK (and other) character sets and encodings. These are
+not literal pages, but rather references to a character set and
+encoding combination. In the case of CJK Code Pages, they definitely
+comprise more than one page!
+	Microsoft refers to its supported CJK character sets and
+encodings through such Code Page designations. The following is a
+listing of several Microsoft CJK Code Pages along with their
+characteristics:
+
+  Code Page  Characteristics
+  ^^^^^^^^^  ^^^^^^^^^^^^^^^
+  932        JIS X 0208-1990 base, Shift-JIS encoding, Microsoft
+             extensions (NEC Row 13 and IBM select characters in
+             redundantly encoded in Rows 89 through 92 and Rows 115
+             through 119)
+  936        GB 2312-80 base, EUC encoding
+  949        KS C 5601-1992 base, Unified Hangul Code encoding,
+             remaining 8,822 pre-combined hangul as extension (all of
+             this is referred to as Unified Hangul Code)
+  950        Big Five base, Big Five encoding, Microsoft extensions
+             (actually, the ETen extensions of Row 89)
+  1361       Johab base, Johab encoding
+
+	IBM also uses Code Page designations, and, in fact, some
+designations (and associated characteristics) are nearly identical to
+those in the above table, most notably, Code Pages 932 and 936. IBM's
+Code Page 932 does not include NEC Row 13 or IBM select characters in
+Rows 89 through 92.
+	The best way to describe IBM Code Page designations is by
+first listing the SBCS (Single-Byte Character Set) and DBCS (Double-
+Byte Character Set) Code Page designations (those designated by "Host"
+use EBCDIC-based encodings):
+
+  IBM SBCS Code Page          Characteristics
+  ^^^^^^^^^^^^^^^^^^          ^^^^^^^^^^^^^^^
+  37 (US)                     SBCS-Host
+  290 (Japanese)              SBCS-Host
+  833 (Korean)                SBCS-Host
+  836 (Simplified Chinese)    SBCS-Host
+  891 (Korean)                SBCS-PC
+  897 (Japanese)              SBCS-PC
+  903 (Simplified Chinese)    SBCS-PC
+  904 (Traditional Chinese)   SBCS-PC
+
+  IBM DBCS Code Page          Characteristics
+  ^^^^^^^^^^^^^^^^^^          ^^^^^^^^^^^^^^^
+  300 (Japanese)              DBCS-Host
+  301 (Japanese)              DBCS-PC
+  834 (Korean)                DBCS-Host
+  835 (Traditional Chinese)   DBCS-Host
+  837 (Simplified Chinese)    DBCS-Host
+  926 (Korean)                DBCS-PC
+  927 (Traditional Chinese)   DBCS-PC
+  928 (Simplified Chinese)    DBCS-PC
+
+So far there appears to be no relationship with Microsoft's CJK Code
+Pages, but when we combine the above SBCS and DBCS Code Pages into
+MBCS (Multiple-Byte Character Set) Code Pages, things become a bit
+more revealing:
+
+  IBM MBCS Code Page          Characteristics
+  ^^^^^^^^^^^^^^^^^^          ^^^^^^^^^^^^^^^
+  930 (Japanese)              MBCS-Host (Code Pages 300 and 290)
+  932 (Japanese)              MBCS-PC (Code Pages 301 and 897)
+  933 (Korean)                MBCS-Host (Code Pages 834 and 833)
+  934 (Korean)                MBCS-PC (Code Pages 926 and 891)
+  938 (Traditional Chinese)   MBCS-PC (Code Pages 927 and 904)
+  936 (Simplified Chinese)    MBCS-PC (Code Pages 928 and 903)
+  5031 (Simplified Chinese)   MBCS-Host (Code Pages 837 and 836)
+  5033 (Traditional Chinese)  MBCS-Host (Code Pages 835 and 37)
+
+So, you can now see that many of Microsoft's CJK Code Pages are
+derived from those established by IBM.
+	More detailed information on the encoding specifications for
+DBCS-Host and DBCS-PC can be found in Sections 3.3.14 and 3.3.15,
+respectively.
+
+
+PART 4: CJK CHARACTER SET COMPATIBILITY ISSUES
+
+	The sections below provide detailed information about
+compatibility issues between CJK character sets, to include tidbits of
+useful information.
+	One thing to mention first is that conversion to and from
+IBM's DBCS-Host (Section 3.3.14) and DBCS-PC (Section 3.3.15)
+encodings is table-driven, and fully documented in the following IBM
+publication:
+
+o IBM Corporation. "Character Data Representation Architecture - Level
+  2, Registry." 1993. IBM order number SC09-1391-01.
+
+Unfortunately, the CJK-related tables are not supplied in machine-
+readable format, and must be obtained from IBM directly. The only real
+compatibility issue is trying to obtain the conversion tables from
+IBM.
+
+
+4.1: JAPANESE
+
+	In general, when a Japanese character set was revised,
+characters were simply added (usually appended at the end). However,
+when JIS C 6226-1978 was revised in 1983 (to become JIS X 0208-1983),
+a bit more happened (this is still a controversy).
+	A detailed treatment of the two main transitions, JIS C 6226-
+1978 to JIS X 0208-1983 and JIS X 0208-1983 to JIS X 0208-1990, is
+covered in Appendix J of UJIP. I provide machine-readable files that
+detail these transitions at the following URL:
+
+  ftp://ftp.ora.com/pub/examples/nutshell/ujip/AppJ/
+
+	An interesting side note here is that there is a reason why
+there are many lists that illustrate JIS C 6226-1978 and JIS X 0208-
+1983 kanji form differences. While most share the same basic set of
+changes, there are some inconsistencies. Well, it turns out that JIS C
+6226-1978 had ten printings, and not all of them shared the same kanji
+forms. If comparisons between JIS C 6226-1978 and JIS X 0208-1983 were
+made using different printings of the JIS C 6226-1978 manual, the
+results can differ slightly.
+	There are also interesting correspondences between JIS X
+0208-1990 and JIS X 0212-1990. 28 kanji that vanished during the JIS C
+6226-1978 to JIS X 0208-1983 transition (they were replaced by
+simplified versions) were restored in JIS X 0212-1990 (at totally
+different code points). Appendix J of UJIP discusses this, and a file
+at the following URL details the 28 mappings:
+
+  ftp://ftp.ora.com/pub/examples/nutshell/ujip/AppJ/TJ2.jis
+
+
+4.2: CHINESE (PRC)
+
+	The basic PRC standard, GB 2312-80, has been revised, but not
+through a later version of the standard. Instead, the revisions were
+carried out in the form of three other documents. Specifically, they
+are (in order of publication):
+
+o GB 6345.1-86 (see Section 2.2.3)
+o GB 8565.2-88 (see Section 2.2.6)
+o GB/T 12345-90 (see Section 2.2.7)
+
+Unless you are aware of these documents, figuring out what has been
+corrected or added to GB 2312-80 is nearly impossible.
+
+
+4.3: CHINESE (TAIWAN)
+
+	The first question people think of with regard to Big Five and
+CNS 11643-1992 is compatibility. It turns out that Planes 1 and 2 of
+CNS 11643-1992 are more or less equivalent to Big Five, but a handful
+of hanzi are in a different order. The following tables detail the
+mapping from Big Five (with the ETen extension) to CNS 11643-1992
+(when using this conversion table, keep in mind the encoding space
+ranges for both Big Five and CNS 11643-1992):
+
+Big Five Level 1 Correspondence to CNS 11643-1992 Plane 1:
+
+  0xA140-0xA1F5 <-> 0x2121-0x2256
+         0xA1F6 <-> 0x2258
+         0xA1F7 <-> 0x2257
+  0xA1F8-0xA2AE <-> 0x2259-0x234E
+  0xA2AF-0xA3BF <-> 0x2421-0x2570
+  0xA3C0-0xA3E0 <-> 0x4221-0x4241  # Symbols for control characters
+  0xA440-0xACFD <-> 0x4421-0x5322  # Level 1 Hanzi BEGIN
+         0xACFE <-> 0x5753
+  0xAD40-0xAFCF <-> 0x5323-0x5752
+  0xAFD0-0xBBC7 <-> 0x5754-0x6B4F
+  0xBBC8-0xBE51 <-> 0x6B51-0x6F5B
+         0xBE52 <-> 0x6B50
+  0xBE53-0xC1AA <-> 0x6F5C-0x7534
+  0xC1AB-0xC2CA <-> 0x7536-0x7736
+         0xC2CB <-> 0x7535
+  0xC2CC-0xC360 <-> 0x7737-0x782C
+  0xC361-0xC3B8 <-> 0x782E-0x7863
+         0xC3B9 <-> 0x7865
+         0xC3BA <-> 0x7864
+  0xC3BB-0xC455 <-> 0x7866-0x7961
+         0xC456 <-> 0x782D
+  0xC457-0xC67E <-> 0x7962-0x7D4B  # Level 1 Hanzi END
+  0xC6A1-0xC6AA <-> 0x2621-0x262A  # Circled numerals
+  0xC6AB-0xC6B4 <-> 0x262B-0x2634  # Parenthesized numerals
+  0xC6B5-0xC6BE <-> 0x2635-0x263E  # Lowercase Roman numerals
+  0xC6BF-0xC6C0 <-> 0x2723-0x2724  # 213 radicals BEGIN
+  0xC6C1-0xC6C2 <-> 0x2726, 0x2728
+  0xC6C3-0xC6C5 <-> 0x272D-0x272F
+  0xC6C6-0xC6C7 <-> 0x2734, 0x2737
+  0xC6C8-0xC6C9 <-> 0x273A, 0x273C
+  0xC6CA-0xC6CB <-> 0x2742, 0x2747
+  0xC6CC-0xC6CD <-> 0x274E, 0x2753
+  0xC6CE-0xC6CF <-> 0x2754-0x2755
+  0xC6D0-0xC6D1 <-> 0x2759-0x275A
+  0xC6D2-0xC6D3 <-> 0x2761, 0x2766
+  0xC6D4-0xC6D5 <-> 0x2829-0x282A
+  0xC6D6-0xC6D7 <-> 0x2863, 0x286C # 213 radicals END
+  0xC6D8-0xC6E6  -> ******         # Japanese symbols
+  0xC6E7-0xC77A  -> ******         # Hiragana
+  0xC77B-0xC7F2  -> ******         # Katakana
+  0xC7F3-0xC875  -> ******         # Cyrillic alphabet
+  0xC876-0xC878  -> ******         # Symbols
+         0xC87A  -> ******         # Hanzi element
+         0xC87C  -> ******         # Hanzi element
+  0xC87E-0xC8A1  -> ******         # Hanzi elements
+  0xC8A3-0xC8A4  -> ******         # Hanzi elements
+  0xC8A5-0xC8CC  -> ******         # Combined numerals
+  0xC8CD-0xC8D3  -> ******         # Japanese symbols
+
+Big Five Level 1 Correspondences to CNS 11643-1992 Plane 4:
+
+         0xC879 <-> 0x2123         # Hanzi element
+         0xC87B <-> 0x2124         # Hanzi element
+         0xC87D <-> 0x212A         # Hanzi element
+         0xC8A2 <-> 0x2152         # Hanzi element
+
+Big Five Level 2 Correspondence to CNS 11643-1992 Plane 1:
+
+         0xC94A  -> 0x4442         # duplicate of 0xA461
+
+Big Five Level 2 Correspondences to CNS 11643-1992 Plane 2:
+
+  0xC940-0xC949 <-> 0x2121-0x212A  # Level 2 Hanzi BEGIN
+  0xC94B-0xC96B <-> 0x212B-0x214B
+  0xC96C-0xC9BD <-> 0x214D-0x217C
+         0xC9BE <-> 0x214C
+  0xC9BF-0xC9EC <-> 0x217D-0x224C
+  0xC9ED-0xCAF6 <-> 0x224E-0x2438
+         0xCAF7 <-> 0x224D
+  0xCAF8-0xD6CB <-> 0x2439-0x376E
+         0xD6CC <-> 0x3E63
+  0xD6CD-0xD779 <-> 0x3770-0x387D
+         0xD77A <-> 0x3F6A
+  0xD77B-0xDADE <-> 0x387E-0x3E62
+         0xDADF <-> 0x376F
+  0xDAE0-0xDBA6 <-> 0x3E64-0x3F69
+  0xDBA7-0xDDFB <-> 0x3F6B-0x4423
+         0xDDFC  -> 0x4176         # duplicate of 0xDCD1
+  0xDDFD-0xE8A2 <-> 0x4424-0x554A
+  0xE8A3-0xE975 <-> 0x554C-0x5721
+  0xE976-0xEB5A <-> 0x5723-0x5A27
+  0xEB5B-0xEBF0 <-> 0x5A29-0x5B3E
+         0xEBF1 <-> 0x554B
+  0xEBF2-0xECDD <-> 0x5B3F-0x5C69
+         0xECDE <-> 0x5722
+  0xECDF-0xEDA9 <-> 0x5C6A-0x5D73
+  0xEDAA-0xEEEA <-> 0x5D75-0x6038
+         0xEEEB <-> 0x642F
+  0xEEEC-0xF055 <-> 0x6039-0x6242
+         0xF056 <-> 0x5D74
+  0xF057-0xF0CA <-> 0x6243-0x6336
+         0xF0CB <-> 0x5A28
+  0xF0CC-0xF162 <-> 0x6337-0x642E
+  0xF163-0xF16A <-> 0x6430-0x6437
+         0xF16B <-> 0x6761
+  0xF16C-0xF267 <-> 0x6438-0x6572
+         0xF268 <-> 0x6934
+  0xF269-0xF2C2 <-> 0x6573-0x664C
+  0xF2C3-0xF374 <-> 0x664E-0x6760
+  0xF375-0xF465 <-> 0x6762-0x6933
+  0xF466-0xF4B4 <-> 0x6935-0x6961
+         0xF4B5 <-> 0x664D
+  0xF4B6-0xF4FC <-> 0x6962-0x6A4A
+  0xF4FD-0xF662 <-> 0x6A4C-0x6C51
+         0xF663 <-> 0x6A4B
+  0xF664-0xF976 <-> 0x6C52-0x7165
+  0xF977-0xF9C3 <-> 0x7167-0x7233
+         0xF9C4 <-> 0x7166
+         0xF9C5 <-> 0x7234
+         0xF9C6 <-> 0x7240
+  0xF9C7-0xF9D1 <-> 0x7235-0x723F
+  0xF9D2-0xF9D5 <-> 0x7241-0x7244  # Level 2 Hanzi END
+  0xF9DD-0xF9FE  -> ******         # Symbols
+
+Big Five Level 2 Correspondence to CNS 11643-1992 Plane 3:
+
+         0xF9D6 <-> 0x4337         # ETen-specific hanzi
+         0xF9D7 <-> 0x4F50         # ETen-specific hanzi
+         0xF9D8 <-> 0x444E         # ETen-specific hanzi
+         0xF9D9 <-> 0x504A         # ETen-specific hanzi
+         0xF9DA <-> 0x2C5D         # ETen-specific hanzi
+         0xF9DB <-> 0x3D7E         # ETen-specific hanzi
+         0xF9DC <-> 0x4B5C         # ETen-specific hanzi
+
+I adapted the above from material Ross Paterson (rap@doc.ic.ac.uk)
+kindly made available at the following URL:
+
+  http://www.ifcss.org:8001/www/pub/software/info/cjk-codes/
+
+Check it out. Basically, I just changed the CNS 11643-1992 codes from
+decimal row-cell values to hexadecimal codes, and corrected the
+mappings to correspond to ETen's Big Five (which is considered to be
+the most standard).
+	It turns out that corrections were made to Big Five (at least
+in the ETen and Microsoft implementations thereof) which made it a bit
+closer to CNS 11643-1992 as far as character ordering is concerned.
+The following six lines of code correspondences:
+
+  0xCAF8-0xD6CB <-> 0x2439-0x376E
+         0xD6CC <-> 0x3E63
+  0xD6CD-0xD779 <-> 0x3770-0x387D
+         0xD77A <-> 0x3F6A
+  0xD77B-0xDADE <-> 0x387E-0x3E62
+         0xDADF <-> 0x376F
+
+can now be expressed as the following three lines:
+
+  0xCAF8-0xD779 <-> 0x2439-0x387D
+         0xD77A <-> 0x3F6A
+  0xD77B-0xDBA6 <-> 0x387E-0x3F69
+
+In essence, the ordering of Big Five characters 0xD6CC and 0xDADF were
+reversed. This resulted in the same order as found in CNS 11643-1992
+Plane 2.
+	As for the two duplicate hanzi in Big Five (as indicated in
+the above tables), they have been placed into a compatibility zone in
+ISO 10646-1:1993 (this allows for round-trip conversion). The mapping
+is as follows:
+
+  Big Five  ISO 10646-1:1993
+  ^^^^^^^^  ^^^^^^^^^^^^^^^^
+  0xC94A -> 0xFA0C
+  0xDDFC -> 0xFA0D
+
+	Speaking of duplicate hanzi, Plane 1 of CNS 11643-1992
+contains 213 classical radicals in rows 27 through 29. However, 187 of
+them map directly to hanzi code points in Planes 1, 2, and 3 (and
+naturally to Big Five). Below is a detailed mapping of these 213
+radicals:
+
+  Radical   CNS 11643   Big Five    Radical   CNS 11643   Big Five
+  ^^^^^^^   ^^^^^^^^^   ^^^^^^^^    ^^^^^^^   ^^^^^^^^^   ^^^^^^^^
+  0x2721 -> 0x4421      0xA440      0x282E -> 0x4678      0xA5D8
+  0x2722 -> 0x2121 (3)  ******      0x282F -> 0x4679      0xA5D9
+  0x2723 -> 0x2122 (3)  0xC6BF      0x2830 -> 0x467A      0xA5DA
+  0x2724 -> 0x2123 (3)	0xC6C0      0x2831 -> 0x467B      0xA5DB
+  0x2725 -> 0x4422      0xA441      0x2832 -> 0x467C      0xA5DC
+  0x2726 -> 0x2124 (3)	0xC6C1      0x2833 -> 0x2167 (2)  0xC9A8
+  0x2727 -> 0x4428      0xA447      0x2834 -> 0x467D      0xA5DD
+  0x2728 -> ******	0xC6C2      0x2835 -> 0x467E      0xA5DE
+  0x2729 -> 0x4429      0xA448      0x2836 -> 0x4721      0xA5DF
+  0x272A -> 0x442A      0xA449      0x2837 -> 0x484C      0xA6CB
+  0x272B -> 0x442B      0xA44A      0x2838 -> 0x484D      0xA6CC
+  0x272C -> 0x442C      0xA44B      0x2839 -> 0x484E      0xA6CD
+  0x272D -> 0x2127 (3)	0xC6C3      0x283A -> 0x484F      0xA6CE
+  0x272E -> 0x2128 (3)	0xC6C4      0x283B -> 0x2269 (2)  0xCA49
+  0x272F -> ******	0xC6C5      0x283C -> 0x4850      0xA6CF
+  0x2730 -> 0x442D      0xA44C      0x283D -> 0x4851      0xA6D0
+  0x2731 -> 0x2123 (2)  0xC942      0x283E -> 0x4852      0xA6D1
+  0x2732 -> 0x442E      0xA44D      0x283F -> 0x4854      0xA6D3
+  0x2733 -> 0x4430      0xA44F      0x2840 -> 0x4855      0xA6D4
+  0x2734 -> ******      0xC6C6      0x2841 -> 0x4856      0xA6D5
+  0x2735 -> 0x4431      0xA450      0x2842 -> 0x4857      0xA6D6
+  0x2736 -> 0x2124 (2)  0xC943      0x2843 -> 0x4858      0xA6D7
+  0x2737 -> 0x2129 (3)  0xC6C7      0x2844 -> 0x485B      0xA6DA
+  0x2738 -> 0x4432      0xA451      0x2845 -> 0x485C      0xA6DB
+  0x2739 -> 0x4433      0xA452      0x2846 -> 0x485D      0xA6DC
+  0x273A -> 0x212A (3)  0xC6C8      0x2847 -> 0x485E      0xA6DD
+  0x273B -> 0x2125 (2)  0xC944      0x2848 -> 0x485F      0xA6DE
+  0x273C -> 0x212B (3)  0xC6C9      0x2849 -> 0x4860      0xA6DF
+  0x273D -> 0x4434      0xA453      0x284A -> 0x4861      0xA6E0
+  0x273E -> 0x4447      0xA466      0x284B -> 0x4862      0xA6E1
+  0x273F -> 0x212A (2)  0xC949      0x284C -> 0x4863      0xA6E2
+  0x2740 -> 0x4448      0xA467      0x284D -> 0x226A (2)  0xCA4A
+  0x2741 -> 0x4449      0xA468      0x284E -> 0x226F (2)  0xCA4F
+  0x2742 -> 0x213A (3)  0xC6CA      0x284F -> 0x4865      0xA6E4
+  0x2743 -> 0x444A      0xA469      0x2850 -> 0x4866      0xA6E5
+  0x2744 -> 0x444B      0xA46A      0x2851 -> 0x4867      0xA6E6
+  0x2745 -> 0x444C      0xA46B      0x2852 -> 0x4868      0xA6E7
+  0x2746 -> 0x444D      0xA46C      0x2853 -> 0x2270 (2)  0xCA50
+  0x2747 -> 0x213B (3)  0xC6CB      0x2854 -> 0x4B44      0xA8A3
+  0x2748 -> 0x4450      0xA46F      0x2855 -> 0x4B45      0xA8A4
+  0x2749 -> 0x4451      0xA470      0x2856 -> 0x4B46      0xA8A5
+  0x274A -> 0x4452      0xA471      0x2857 -> 0x4B47      0xA8A6
+  0x274B -> 0x4453      0xA472      0x2858 -> 0x4B48      0xA8A7
+  0x274C -> 0x212B (2)  0xC94B      0x2859 -> 0x4B49      0xA8A8
+  0x274D -> 0x4454      0xA473      0x285A -> 0x2524 (2)  0xCBA4
+  0x274E -> 0x213C (3)  0xC6CC      0x285B -> 0x4B4A      0xA8A9
+  0x274F -> 0x4456      0xA475      0x285C -> 0x4B4B      0xA8AA
+  0x2750 -> 0x4457      0xA476      0x285D -> 0x4B4C      0xA8AB
+  0x2751 -> 0x445A      0xA479      0x285E -> 0x4B4D      0xA8AC
+  0x2752 -> 0x445B      0xA47A      0x285F -> 0x4B4E      0xA8AD
+  0x2753 -> 0x213D (3)  0xC6CD      0x2860 -> 0x4B4F      0xA8AE
+  0x2754 -> 0x213E (3)  0xC6CE      0x2861 -> 0x4B50      0xA8AF
+  0x2755 -> 0x213F (3)  0xC6CF      0x2862 -> 0x4B51      0xA8B0
+  0x2756 -> 0x445C      0xA47B      0x2863 -> 0x272F (3)  0xC6D6
+  0x2757 -> 0x445D      0xA47C      0x2864 -> 0x4B57      0xA8B6
+  0x2758 -> 0x445E      0xA47D      0x2865 -> 0x4B5C      0xA8BB
+  0x2759 -> 0x2140 (3)  0xC6D0      0x2866 -> 0x4B5D      0xA8BC
+  0x275A -> 0x2142 (3)  0xC6D1      0x2867 -> 0x4B5E      0xA8BD
+  0x275B -> 0x212C (2)  0xC94C      0x2868 -> 0x4F5A      0xAAF7
+  0x275C -> 0x4540      0xA4DF      0x2869 -> 0x4F5B      0xAAF8
+  0x275D -> 0x4541      0xA4E0      0x286A -> 0x4F5C      0xAAF9
+  0x275E -> 0x4542      0xA4E1      0x286B -> 0x4F5D      0xAAFA
+  0x275F -> 0x4543      0xA4E2      0x286C -> 0x2A7D (3)  0xC6D7
+  0x2760 -> 0x4545      0xA4E4      0x286D -> 0x4F63      0xAB41
+  0x2761 -> 0x2167 (3)  0xC6D2      0x286E -> 0x4F64      0xAB42
+  0x2762 -> 0x4546      0xA4E5      0x286F -> 0x4F65      0xAB43
+  0x2763 -> 0x4547      0xA4E6      0x2870 -> 0x4F66      0xAB44
+  0x2764 -> 0x4548      0xA4E7      0x2871 -> 0x5372      0xADB1
+  0x2765 -> 0x4549      0xA4E8      0x2872 -> 0x5373      0xADB2
+  0x2766 -> 0x2169 (3)  0xC6D3      0x2873 -> 0x5374      0xADB3
+  0x2767 -> 0x454A      0xA4E9      0x2874 -> 0x5375      0xADB4
+  0x2768 -> 0x454B      0xA4EA      0x2875 -> 0x5376      0xADB5
+  0x2769 -> 0x454C      0xA4EB      0x2876 -> 0x5377      0xADB6
+  0x276A -> 0x454D      0xA4EC      0x2877 -> 0x5378      0xADB7
+  0x276B -> 0x454E      0xA4ED      0x2878 -> 0x5379      0xADB8
+  0x276C -> 0x454F      0xA4EE      0x2879 -> 0x537A      0xADB9
+  0x276D -> 0x4550      0xA4EF      0x287A -> 0x537B      0xADBA
+  0x276E -> 0x213F (2)  0xC95F      0x287B -> 0x537C      0xADBB
+  0x276F -> 0x4551      0xA4F0      0x287C -> 0x586B      0xB0A8
+  0x2770 -> 0x4552      0xA4F1      0x287D -> 0x586C      0xB0A9
+  0x2771 -> 0x4553      0xA4F2      0x287E -> 0x586D      0xB0AA
+  0x2772 -> 0x4554      0xA4F3      0x2921 -> 0x334C (2)  0xD449
+  0x2773 -> 0x2141 (2)  0xC961      0x2922 -> 0x586E      0xB0AB
+  0x2774 -> 0x4555      0xA4F4      0x2923 -> 0x334D (2)  0xD44A
+  0x2775 -> 0x4556      0xA4F5      0x2924 -> 0x586F      0xB0AC
+  0x2776 -> 0x4557      0xA4F6      0x2925 -> 0x5870      0xB0AD
+  0x2777 -> 0x4558      0xA4F7      0x2926 -> 0x5E23      0xB3BD
+  0x2778 -> 0x4559      0xA4F8      0x2927 -> 0x5E24      0xB3BE
+  0x2779 -> 0x2142 (2)  0xC962      0x2928 -> 0x5E25      0xB3BF
+  0x277A -> 0x455A      0xA4F9      0x2929 -> 0x5E26      0xB3C0
+  0x277B -> 0x455B      0xA4FA      0x292A -> 0x5E27      0xB3C1
+  0x277C -> 0x455C      0xA4FB      0x292B -> 0x5E28      0xB3C2
+  0x277D -> 0x455D      0xA4FC      0x292C -> 0x6327      0xB6C0
+  0x277E -> 0x4668      0xA5C8      0x292D -> 0x6328      0xB6C1
+  0x2821 -> 0x4669      0xA5C9      0x292E -> 0x6329      0xB6C2
+  0x2822 -> 0x466A      0xA5CA      0x292F -> 0x4155 (2)  0xDCB0
+  0x2823 -> 0x466B      0xA5CB      0x2930 -> 0x4875 (2)  0xE0EF
+  0x2824 -> 0x466C      0xA5CC      0x2931 -> 0x676F      0xB9A9
+  0x2825 -> 0x466D      0xA5CD      0x2932 -> 0x6770      0xB9AA
+  0x2826 -> 0x466E      0xA5CE      0x2933 -> 0x6771      0xB9AB
+  0x2827 -> 0x4670      0xA5D0      0x2934 -> 0x6B7C      0xBBF3
+  0x2828 -> 0x4674      0xA5D4      0x2935 -> 0x6B7D      0xBBF4
+  0x2829 -> 0x225B (3)  0xC6D4      0x2936 -> 0x702F      0xBEA6
+  0x282A -> 0x225C (3)  0xC6D5      0x2937 -> 0x733E      0xC073
+  0x282B -> 0x4675      0xA5D5      0x2938 -> 0x733F      0xC074
+  0x282C -> 0x4676      0xA5D6      0x2939 -> 0x6142 (2)  0xEFB6
+  0x282D -> 0x4677      0xA5D7
+
+
+4.4: KOREAN
+
+	The 268 duplicate hanja in KS C 5601-1992 can cause problems
+when converting to and from other CJK character sets. When converting
+from KS C 5601-1992, two or more hanja can collapse into a single code
+point. When converting these 268 hanja to KS C 5601-1992, a decision
+about which KS C 5601-1992 code point to map to must be made. The only
+exception to this is mapping to and from ISO 10646-1:1993. That
+standard encodes these 268 duplicate hanja in a compatibility zone,
+namely from 0xF900 through 0xFA0B.
+	The following is a listing of 262 hanja that map to two or
+more code points (four map to three code points, and one maps to four:
+a total of 268 redundantly-encoded hanja) in KS C 5601-1992:
+
+  Standard  Extra     Standard  Extra     Standard  Extra
+  ^^^^^^^^  ^^^^^     ^^^^^^^^  ^^^^^     ^^^^^^^^  ^^^^^
+  0x4A39 -> 0x4D4F    0x5573 -> 0x6631    0x573C -> 0x6B29
+  0x4B3D -> 0x7A22    0x5574 -> 0x6633    0x573E -> 0x6B3A
+  0x4C38 -> 0x7A66    0x5575 -> 0x6637    0x573F -> 0x6B3B
+  0x4C5A -> 0x4B56    0x5576 -> 0x6638    0x5740 -> 0x6B3D
+  0x4C78 -> 0x5050    0x5579 -> 0x663C    0x5741 -> 0x6B41
+  0x4D7A -> 0x4E2D    0x557B -> 0x6646    0x5743 -> 0x6B42
+  0x4E29 -> 0x7C29    0x557C -> 0x6647    0x5744 -> 0x6B46
+  0x4F23 -> 0x4F7B    0x557E -> 0x6652    0x5745 -> 0x6B47
+  0x4F4F -> 0x5022    0x5621 -> 0x6656    0x5747 -> 0x6B4C
+            0x5038    0x5622 -> 0x6659    0x5748 -> 0x6B4F
+  0x5142 -> 0x4B50    0x5623 -> 0x665F    0x5749 -> 0x6B50
+  0x5151 -> 0x505D    0x5624 -> 0x6661    0x574A -> 0x6B51
+  0x5159 -> 0x547C    0x5625 -> 0x6665    0x574C -> 0x6B58
+  0x5167 -> 0x552B    0x5626 -> 0x6664    0x574D -> 0x5270
+  0x522F -> 0x5155    0x5627 -> 0x6666    0x574E -> 0x5271
+  0x5233 -> 0x657C    0x5628 -> 0x6668    0x574F -> 0x5272
+  0x5234 -> 0x6644    0x562A -> 0x666A    0x5750 -> 0x5273
+  0x5235 -> 0x664A    0x562B -> 0x666B    0x5752 -> 0x5274
+  0x5236 -> 0x665C    0x562D -> 0x666F    0x5753 -> 0x5275
+  0x5237 -> 0x6676    0x562E -> 0x6671    0x5754 -> 0x5277
+  0x523A -> 0x6677    0x562F -> 0x6675    0x5755 -> 0x5278
+  0x523B -> 0x5638    0x5631 -> 0x6679    0x5757 -> 0x6C26
+            0x672C    0x5633 -> 0x6721    0x5759 -> 0x6C27
+  0x5241 -> 0x564D    0x5634 -> 0x6726    0x575B -> 0x6C2A
+  0x5263 -> 0x6871    0x5635 -> 0x6729    0x575D -> 0x6C30
+  0x526E -> 0x6A74    0x5637 -> 0x672A    0x575E -> 0x6C31
+  0x526F -> 0x6B2A    0x563A -> 0x672D    0x5762 -> 0x6C35
+  0x527A -> 0x6C32    0x563B -> 0x6730    0x5765 -> 0x6C38
+  0x527B -> 0x6C49    0x563C -> 0x673F    0x5767 -> 0x6C3A
+  0x527C -> 0x6C4A    0x563E -> 0x6746    0x576A -> 0x6C40
+  0x527E -> 0x7331    0x5640 -> 0x6747    0x576B -> 0x6C41
+  0x5321 -> 0x552E    0x5642 -> 0x674B    0x576C -> 0x6C45
+  0x5358 -> 0x7738    0x5643 -> 0x674D    0x576E -> 0x6C46
+  0x536B -> 0x7748    0x5644 -> 0x674F    0x5770 -> 0x6C55
+  0x5378 -> 0x7674    0x5645 -> 0x6750    0x5772 -> 0x6C5D
+  0x5441 -> 0x5466    0x5647 -> 0x6753    0x5773 -> 0x6C5E
+  0x5457 -> 0x7753    0x5649 -> 0x675F    0x5774 -> 0x6C61
+  0x547A -> 0x5154    0x564A -> 0x6764    0x5776 -> 0x6C64
+  0x547B -> 0x5158    0x564B -> 0x6766    0x5777 -> 0x6C67
+  0x547D -> 0x515B    0x564C -> 0x523E    0x5778 -> 0x6C68
+  0x547E -> 0x515C    0x564F -> 0x5242    0x5779 -> 0x6C77
+  0x5521 -> 0x515D    0x5650 -> 0x5243    0x577A -> 0x6C78
+  0x5522 -> 0x515E    0x5653 -> 0x5244    0x577C -> 0x6C7A
+  0x5523 -> 0x515F    0x5654 -> 0x5246    0x5821 -> 0x6D21
+  0x5524 -> 0x5160    0x5655 -> 0x5247    0x5822 -> 0x6D22
+  0x5526 -> 0x5163    0x5656 -> 0x5248    0x5823 -> 0x6D23
+  0x5527 -> 0x5164    0x5657 -> 0x5249    0x5A72 -> 0x5B64
+  0x5528 -> 0x5165    0x5658 -> 0x524A    0x5C56 -> 0x5D25
+  0x552A -> 0x5166    0x565A -> 0x524B    0x5C5F -> 0x7870
+  0x552C -> 0x5168    0x565B -> 0x524D    0x5C74 -> 0x5D55
+  0x552D -> 0x5169    0x565C -> 0x524E    0x5D41 -> 0x5B45
+  0x552F -> 0x516A    0x565E -> 0x524F    0x5F2F -> 0x616D
+  0x5530 -> 0x516B    0x565F -> 0x5250    0x5F52 -> 0x6D6E
+  0x5531 -> 0x516D    0x5660 -> 0x5251    0x5F5D -> 0x5F61
+  0x5534 -> 0x516F    0x5661 -> 0x5252    0x5F63 -> 0x5E7E
+  0x5535 -> 0x5170    0x5662 -> 0x5253    0x6063 -> 0x612D
+  0x5536 -> 0x5172    0x5663 -> 0x5254              0x6672
+  0x5539 -> 0x5176    0x5665 -> 0x5255    0x607D -> 0x5F68
+  0x553D -> 0x517A    0x5666 -> 0x5256    0x6163 -> 0x574B
+  0x5540 -> 0x517C    0x5667 -> 0x5257              0x6B52
+  0x5541 -> 0x517D    0x566B -> 0x5259    0x6226 -> 0x5E7C
+  0x5543 -> 0x517E    0x566C -> 0x525A    0x6326 -> 0x6429
+  0x5544 -> 0x5222    0x566F -> 0x525E    0x635B -> 0x723D
+  0x5545 -> 0x5223    0x5670 -> 0x525F    0x6427 -> 0x727A
+  0x5546 -> 0x5227    0x5671 -> 0x5261    0x6442 -> 0x6777
+  0x5547 -> 0x5228    0x5674 -> 0x5262    0x6445 -> 0x5162
+  0x5548 -> 0x5229    0x5675 -> 0x6867              0x5525
+  0x5549 -> 0x522A    0x5676 -> 0x6868              0x6879
+  0x554D -> 0x522B    0x5677 -> 0x6870    0x6534 -> 0x652E
+  0x554E -> 0x522D    0x5679 -> 0x6877    0x6636 -> 0x6C2F
+  0x5552 -> 0x5232    0x567A -> 0x687B    0x6728 -> 0x6071
+  0x5553 -> 0x6531    0x567B -> 0x687E    0x6856 -> 0x6A41
+  0x5554 -> 0x6532    0x567E -> 0x6927    0x6C36 -> 0x5764
+  0x5555 -> 0x6539    0x5721 -> 0x692C    0x6C56 -> 0x666C
+  0x5557 -> 0x653B    0x5723 -> 0x694C    0x6D29 -> 0x7427
+  0x5558 -> 0x653C    0x5724 -> 0x5264    0x6D33 -> 0x6E5B
+  0x5559 -> 0x6544    0x5726 -> 0x5265    0x6F37 -> 0x746E
+  0x555D -> 0x654E    0x5727 -> 0x5266    0x7263 -> 0x6375
+  0x555E -> 0x6550    0x5728 -> 0x5267    0x7333 -> 0x4B67
+  0x555F -> 0x6552    0x5729 -> 0x5268    0x7351 -> 0x5F33
+  0x5561 -> 0x6556    0x572B -> 0x5269    0x742C -> 0x7676
+  0x5564 -> 0x657A    0x572C -> 0x526A    0x7658 -> 0x6421
+  0x5565 -> 0x657B    0x5730 -> 0x526B    0x7835 -> 0x5C25
+  0x5566 -> 0x657E    0x5731 -> 0x6A65    0x786C -> 0x785B
+  0x5569 -> 0x6621    0x5733 -> 0x6A77    0x7932 -> 0x5D74
+  0x556B -> 0x6624    0x5735 -> 0x6A7C    0x7A3C -> 0x7A21
+  0x556C -> 0x6627    0x5736 -> 0x6A7E    0x7B29 -> 0x6741
+  0x556F -> 0x662D    0x5738 -> 0x6B24    0x7C41 -> 0x4D68
+  0x5571 -> 0x662F    0x573A -> 0x6B27    0x7D3B -> 0x6977
+  0x5572 -> 0x6630
+
+The above table represents a weekend of my time (but time well spent,
+in my opinion).
+
+
+4.5: ISO 10646-1:1993
+
+	The Chinese character subset of ISO 10646-1:1993
+has excellent round-trip conversion capability with the various
+national character sets. Those national character sets with duplicate
+characters, such as KS C 5601-1992 (268 hanja) and Big Five (2 hanzi),
+have corresponding code points in ISO 10646-1:1993 within
+a compatibility zone. See Sections 4.3 and 4.4 for more details.
+	Other issues regarding ISO 10646-1:1993 have to do with proper
+character rendering (that is, how characters are displayed, printed,
+or otherwise imaged). Many (sometimes) subtle character form
+differences have been collapsed under ISO 10646-1:1993. Language or
+locale was not one of the factors used in performing Han Unification.
+This means that it is nearly impossible to create a single ISO 10646-1:
+1993 font that meets the character form criteria of each of the four
+CJK locales. An ISO 10646-1:1993 code point is not enough information
+to render a Chinese character. If the font was specifically designed
+for a single locale, it is a non-problem, but if there is any CJK
+intent, text must be flagged for language or locale.
+
+
+4.6: UNICODE
+
+	One of the most interesting (and major) differences between
+the current three flavors of Unicode are the number and arrangement of
+pre-combined hangul. The following table provides a summary of the
+differences:
+
+  Unicode       Number of Pre-combined Hangul   UCS-2 Ranges
+  ^^^^^^^       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^   ^^^^^^^^^^^^
+  Version 1.0   2,350 Basic Hangul              0x3400-0x3D3D
+
+  Version 1.1   2,350 Basic Hangul              0x3400-0x3D3D
+                1,930 Supplemental Hangul A     0x3D2E-0x44B7
+                2,376 Supplemental Hangul B     0x44BE-0x4DFF
+
+  Version 2.0  11,172 Hangul                    0xAC00-0xD7A3
+
+Of the above three versions, the most controversial is Version 2.0.
+Why? Because it is located in the user-defined range of Unicode
+(O-Zone: 16,384 code points in 0xA000-0xDFFF), and occupies
+approximately two-thirds of its space.
+	The information in the above table is courtesy of the
+following useful document:
+
+  ftp://unicode.org/pub/MappingTables/EastAsiaMaps/Hangul-Codes.txt
+
+The same file is also mirrored at the following URL:
+
+  ftp://ftp.ora.com/pub/examples/nutshell/ujip/map/hangul-codes.txt
+
+
+4.7: CODE CONVERSION TIPS
+
+	There are two types of conversions that can be performed. The
+first type is converting between different encodings for the same
+character set. This is usually without problems (but not always). The
+second type is converting from one character set to another (it is not
+usually relevant whether the underlying encoding has changed or not).
+This usually involves the handling of characters that are in one
+character set, but not the other. So, what to do?
+	I suggest JConv for handling Japanese code conversion (this
+means converting between JIS, Shift-JIS, and EUC encodings). This is
+in the category of different encodings for the same character set. The
+following URLs provide executables or source code:
+
+  ftp://ftp.ora.com/pub/examples/nutshell/ujip/mac/jconv-30.hqx
+  ftp://ftp.ora.com/pub/examples/nutshell/ujip/mac/jconv-dd-181.hqx
+  ftp://ftp.ora.com/pub/examples/nutshell/ujip/dos/jconv.exe
+  ftp://ftp.ora.com/pub/examples/nutshell/ujip/src/jconv.c
+
+There are other programs available that do the same basic thing as
+JConv, such as kc and nkf. They are available at the following URL:
+
+  ftp://ftp.ora.com/pub/examples/nutshell/ujip/unix/
+
+	For software and tables that handles Chinese code conversion
+(this includes conversion to and from Japanese), I suggest browsing at
+the following URLs:
+
+  ftp://etlport.etl.go.jp/pub/iso-2022-cn/convert/
+  ftp://ftp.ifcss.org/pub/software/dos/convert/
+  ftp://ftp.ifcss.org/pub/software/mac/convert/
+  ftp://ftp.ifcss.org/pub/software/ms-win/convert/
+  ftp://ftp.ifcss.org/pub/software/unix/convert/
+  ftp://ftp.ifcss.org/pub/software/vms/convert/
+  ftp://ftp.net.tsinghua.edu.cn/pub/Chinese/convert/
+  ftp://ftp.ora.com/pub/examples/nutshell/ujip/map/
+  ftp://ftp.seed.net.tw/Pub/Chinese/DOS/code-convert/
+  http://www.yajima.kuis.kyoto-u.ac.jp/staffs/yasuoka/CJK.html
+
+The latter URL has FTP links to tables created by Koichi Yasuoka
+(yasuoka@kudpc.kyoto-u.ac.jp).
+	The following URLs provide utilities or tables for converting
+between various Korean encodings (the last represent the same file):
+
+  ftp://cair-archive.kaist.ac.kr/pub/hangul/code/
+  ftp://ftp.ora.com/pub/examples/nutshell/ujip/map/non-hangul-codes.txt
+  ftp://ftp.ora.com/pub/examples/nutshell/ujip/map/hangul-codes.txt
+  ftp://unicode.org/pub/MappingTables/EastAsiaMaps/Hangul-Codes.txt
+
+A popular Korean code conversion utility seems to be "hcode" by
+June-Yub Lee (jylee@cims.nyu.edu).
+	Finally, the following URLs provide many Unicode- and CJK-
+related mapping tables:
+
+  ftp://ftp.ora.com/pub/examples/nutshell/ujip/map/
+  ftp://ftp.ora.com/pub/examples/nutshell/ujip/unicode/
+  ftp://unicode.org/pub/MappingTables/
+  http://www.yajima.kuis.kyoto-u.ac.jp/staffs/yasuoka/CJK.html
+
+Note that the official and authoritative Unicode mapping tables (from
+Unicode values to various international, national and vendor
+standards) are maintained by the Unicode Consortium at the following
+URL:
+
+  ftp://unicode.org/pub/MappingTables/
+
+Version 2.0 of "The Unicode Standard" (to be published by Addison-
+Wesley shortly) will include these mapping tables on CD-ROM.
+
+
+PART 5: CJK-CAPABLE OPERATING SYSTEMS
+
+	The first step in being able to display CJK text is to obtain
+an operating system that handles such text (or an application that
+sets up its own CJK-capable environment). Below I describe how
+different types of machines can handle CJK text.
+	Actually, for the first few releases of CJK.INF, these
+subsections will be far from complete (some may even be empty!). The
+purpose of CJK.INF is to provide detailed information on character set
+standards and encoding systems, so I therefore consider this sort of
+information secondary.
+
+
+5.1: MS-DOS
+
+	I am not aware of any CJK-capable MS-DOS operating system, but
+localized versions do exist. CJK support has been introduced with
+Microsoft's Windows operating system (see Section 5.2).
+
+
+5.2: WINDOWS
+
+	Microsoft has CJK versions of its Windows operating system
+available. The latest versions of their Windows operating system are
+called Windows 95 and Windows NT. Windows 95 supports the same
+character sets and encodings as in Windows Version 3.1 -- Windows NT
+supports Unicode (ISO 10646-1:1993). Contact Microsoft Corporation for
+more details. The URL of their WWW Home Page is:
+
+  http://www.microsoft.com/
+
+Nadine Kano's "Developing International Software for Windows 95 and
+Windows NT" provides abundant reference material for how CJK is
+supported in Windows 95 and Windows NT. Check it out.
+	TwinBridge is a package that adds CJK functionality to non-CJK
+Windows. Demo versions of TwinBridge for Japanese and Chinese are at
+the following URLs:
+
+  ftp://ftp.netcom.com/pub/tw/twinbrg/Japanese/demo/tbjdemo.zip
+  ftp://ftp.netcom.com/pub/tw/twinbrg/Chinese/demo/tbcdemo.zip
+
+	Another useful CJK add-on for Windows 95 is NJWIN (see Section
+7.10) by Hongbo Data Systems.
+
+
+5.3: MACINTOSH
+
+	Macintosh is well-known as a computer that was designed to
+handle multilingual texts. There are currently fully-localized
+operating systems available for Japanese (KanjiTalk), Chinese
+(simplified and traditional available), and Korean (HangulTalk). In
+addition, Apple has developed "Language Kits" (*LK) for Chinese (CLK)
+and Japanese (JLK). A Korean Language Kit (KLK) will be released
+shortly.
+	These localized operating systems can usually be installed
+together in order to make your system CJK-capable.
+	The common portion of these CJK-capable operating systems is a
+technology Apple calls "WorldScript II" ("WorldScript I" is for one-
+byte scripts). It provides the basic one- and two-byte functionality.
+
+
+5.4: UNIX AND X WINDOWS
+
+	The typical encoding system used on UNIX and X Windows is EUC
+(see Section 3.2). Many systems, such as IBM's AIX, can be configured
+to handle both EUC and Shift-JIS (for Japanese). In addition, X11R6 (X
+Window System, Version 11, Release 6) has many CJK-capable features.
+	If you have a fast PC and a good amount of RAM (more than
+4MB), you should consider replacing MS-DOS (and Microsoft Windows,
+too, if you have it) with Linux, which is a full-blown UNIX operating
+system that runs on Intel processors. You can even run X Windows
+(X11R6). "Running Linux" by Matt Welsh and Lar Kaufman is an excellent
+guide to installing and using Linux. The companion volume, "Linux
+Network Administrator's Guide" by Olaf Kirch is also useful. Because
+there is a fine line -- or no line at all -- between a user and System
+Administrator when using Linux, "Essential System Administration"
+Second Edition by AEleen Frisch is a must-have.
+	Linux and Linux information are available at the following
+URLs:
+
+  ftp://sunsite.unc.edu/pub/Linux/
+  http://sunsite.unc.edu/mdw/linux.html
+
+I personally use Linux, and find it quite useful and powerful. My bias
+comes from being a UNIX user. But, you can't beat the price (free),
+and all of my favorite text-manipulation tools (such as Perl) are
+readily available.
+
+
+5.5: OTHERS
+
+	No information yet.
+
+
+PART 6: CJK TEXT AND INTERNET SERVICES
+
+	Part 5 described how CJK text is handled on a machine
+internally, but this part goes into the implications of handling such
+text externally, namely for information interchange purposes. This
+boils down to handling CJK text on Internet services.
+	For more detailed information on how these and other Internet
+services are used, I suggest "The Whole Internet User's Guide &
+Catalog" by Ed Krol. For more information on setting up and
+maintaining these and other Internet services, I suggest "Managing
+Internet Information Services" by Cricket Liu et al.
+
+
+6.1: ELECTRONIC MAIL
+
+	The most basic Internet service is electronic mail (henceforth
+to be called "e-mail"), which is virtually guaranteed to be available
+to all users regardless of their system.
+	Several Internet standards (called RFCs, short for Request For
+Comments) have been developed to describe how CJK text is to be handled
+over e-mail systems (see Section A.3.4).
+	The bottom-line is that most e-mail systems do not support
+8-bit characters (that is, bytes that have their 8th bit set). Some do
+offer 8-bit support, but you can never know what path your e-mail
+might take while on route to its recipient. This means that 7-bit ISO
+2022 (or equivalent) is the ideal encoding to use when sending CJK
+text through e-mail. If your operating system processes another
+encoding system, you must convert from that encoding to one that is
+compatible with 7-bit ISO 2022.
+	However, even 7-bit ISO 2022 encoding can get mangled by
+mail-routing software -- the escape character, sometimes even part of
+the escape sequence (meaning more than just the escape character), is
+stripped. The JConv tool described in Section 4.7 restores stripped
+escape sequences for Japanese 7-bit ISO 2022.
+	If your mailing software is MIME-compliant, there is a means
+to identify the character set and encoding of the message using the
+"charset" parameter. Some valid "charset" values include the
+following:
+
+o iso-2022-jp     (see Section 3.1.3)
+o iso-2022-jp-2   (see Section 3.1.3)
+o iso-2022-kr     (see Section 3.1.4)
+o iso-2022-cn     (see Section 3.1.5)
+o iso-2022-cn-ext (see Section 3.1.5)
+o iso-8859-1
+
+Insertion of these values should happen automatically.
+	A last-ditch effort to send CJK text through e-mail is to use
+uuencode or Base64 encoding (see Section 3.3.13). Base64 is something
+that is usually done automatically by mailing software -- explicit
+Base64 encoding is not common. The recipient must then run uudecode or
+a Base64 decoder to get the original file (if such utilities are
+available).
+
+
+6.2: USENET NEWS
+
+	Usenet News follows many of the same requirements as e-mail,
+namely that 7-bit ISO 2022 encoding is ideal. However, some newsgroups
+use specific encoding methods, such as:
+
+  alt.chinese.text             (HZ encoding used for Chinese text)
+  alt.chinese.text.big5        (Big Five encoding used for Chinese text)
+  chinese.flame                (UTF-7)
+  chinese.text.unicode         (UTF-8)
+
+Also, the newsgroups in Korean (all begin with "han.*") use EUC (EUC-
+KR) because the news-handling software in Korea has been designed to
+handle eight-bit characters correctly. Mailing list versions of Korean
+newsgroups are likely to use ISO-2022-KR encoding.
+	One common problem with Usenet News is that the escape
+characters used in 7-bit ISO 2022 encoding are sometimes stripped,
+usually by the software used to post the article. This can be quite
+annoying. There are programs available, such as JConv, that repair
+such files by restoring the escape characters.
+	Another common problem are news readers that do not allow
+escape characters to function. One simple solution is to "pipe" the
+article through a display command, such as "more," "page," "less," or
+"cat." This is done by typing a "pipe" character (|) followed by the
+command name anywhere within the article being displayed.
+
+
+6.3: GOPHER
+
+	The World-Wide Web (WWW) has almost eliminated the need for
+using Gopher, so I won't discuss it here. Not that I don't appreciate
+Gopher servers, but what I mean is that WWW browsing software permits
+access to Gopher sites.
+
+
+6.4: WORLD-WIDE WEB
+
+	First, there are two types of WWW browsers available. The most
+common type is the graphics-based browser (examples include Mosaic and
+Netscape). Graphics-based browsers have the unfortunate requirement of
+a TCP/IP (SLIP and PPP support these protocols) connection. Lynx and
+the W3 client for Emacs, which are text-based browsers, can be run
+from the host computer through a standard terminal connection. They
+don't display all the pretty pictures that folks put into their WWW
+documents, but you get all the text (this is, in many ways, a blessing
+in disguise -- transferring graphics is what slows down graphics-based
+browsers the most). When the W3 client is run using Mule, it becomes a
+fully CJK-capable WWW browser. Both Lynx and the W3 client for Emacs
+are freely available. A Japanese-capable Lynx is available at the
+following URL:
+
+  ftp://ftp.ipc.chiba-u.ac.jp/pub.asada/www/lynx/
+
+There is also a WWW page that provides information on Japanese-capable
+Lynx. Its URL is as follows:
+
+  http://www.icsd6.tj.chiba-u.ac.jp/lynx/
+
+	When WWW documents first came online, there was no method for
+handling CJK character sets. This has, fortunately, changed. As of
+this writing, two commercial WWW browsers support Japanese. They are
+Infomosaic by Fujitsu Limited, and Netscape Navigator by Netscape
+Communications Corporation (Version 1.1 added Japanese support). Both
+are graphics-based browsers. The former can be ordered at the
+following URL:
+
+  http://www.fujitsu.co.jp/
+
+The latter can be found at the following URLs:
+
+  http://www.netscape.com/
+  ftp://ftp.netscape.com/
+
+	One can also use a delegate server to *filter* Japanese codes
+to the one supported by your browser. It is also possible to
+"Japanize" existing WWW browsers using assorted tools and patches.
+Katsuhiko Momoi (momoi@tigger.stcloud.msus.edu) has authored an
+excellent guide to Japanizing WWW browsers. Its URL is:
+
+  http://condor.stcloud.msus.edu:20020/netscape.html
+
+I *highly* suggest reading it.
+	Japanese-capable WWW browsers support automatic detection of
+the three Japanese encoding methods (JIS, Shift-JIS, and EUC). Hey,
+but, what about support for the "C" and "K" of CJK? Attempting to
+answer this question provides us an answer to another question: "What
+is the best encoding method to use for CJK WWW documents?"
+	Encoding methods such as EUC and Shift-JIS provide for mixing
+only two character sets. This is because they provide no way to *flag*
+or *tag* text for locale (character set) information. Without flagging
+information, it is impossible to distinguish Japanese EUC from Chinese
+or Korean EUC. However, the escape sequences used in 7-bit ISO 2022
+encoding explicitly provide locale information. 7-bit ISO 2022 is
+ideal for static documents, which is exactly what one finds on WWW.
+	My personal recommendation (for the short-term) is to compose
+WWW documents (also called HTML documents; HTML stands for Hyper Text
+Markup Language) using 7-bit ISO 2022 encoding. The escape sequences
+themselves act as explicit flags that indicate locale. However, some
+WWW clients are confused by 7-bit ISO 2022 encoding, but the products
+by Netscape Communications and Fujitsu Limited prove that this can
+work. See the following URL for a description of this problem:
+
+  http://www.ntt.jp/japan/note-on-JP/LibWWW-patch.html
+
+	Check out the following URLs for information on and proposals
+for international support for WWW:
+
+  http://www.ebt.com:8080/docs/multilingual-www.html
+  http://www.w3.org/hypertext/WWW/International/Overview/
+
+	There is currently an RFC in the works (called an Internet
+Draft) to address the problem of internationalizing HTML by using
+Unicode. It is very promising. The latest draft is available at the
+following URLs:
+
+  ftp://ds.internic.net/internet-drafts/draft-ietf-html-i18n-04.txt.Z
+  ftp://ftp.isi.edu/internet-drafts/draft-ietf-html-i18n-04.txt
+  ftp://munnari.oz.au/internet-drafts/draft-ietf-html-i18n-04.txt.Z
+  ftp://nic.nordu.net/internet-drafts/draft-ietf-html-i18n-04.txt
+
+Note that some have been compressed.
+
+
+6.5: FILE TRANSFER TIPS
+
+	Although CJK encoding systems such as Shift-JIS and EUC make
+extensive use of 8-bit bytes, that does not mean that you need to
+treat the data as binary. Such files are simply to be treated as text,
+and should be transferred in text mode (for example, FTP's ASCII mode,
+which is also called "Type A Transfer").
+	When text files are transferred in binary mode (such as FTP's
+BINARY mode, which is also called Type I Transfer"), line termination
+characters are left unaltered. For example, when transferring a text
+file from UNIX to Macintosh, a text transfer will translate the UNIX
+newline (0x0A) characters to Macintosh carriage return (0x0D)
+characters, but a binary transfer will make no such modifications.
+Text-style conversion is typically desired.
+	The most common types of files that need to be handled as
+binary include tar archives (*.tar), compressed files (*.Z, *.gz,
+*.zip, *.zoo, *.lzh, and so on), and executables (*.exe, *.bin, and so
+on).
+
+
+PART 7: CJK TEXT HANDLING SOFTWARE
+
+	This section describes various CJK-capable software packages.
+I expect this section to grow with future versions of this document. I
+define "CJK-capable" as being able to support Chinese, Japanese, and
+Korean text.
+	The descriptions I provide below are intentionally short. You
+are encouraged to use the information pointers to obtain further
+information or the software itself.
+
+
+7.1: MULE
+
+	Mule (multilingual enhancement to GNU Emacs), written by
+Kenichi Handa (handa@etl.go.jp), is the first (and only?) CJK-capable
+editor for UNIX systems, and is freely available under the terms of
+the GNU General Public License. Mule was developed from Nemacs
+(Nihongo Emacs).
+	Mule is available at the following URL:
+
+  ftp://etlport.etl.go.jp/pub/mule/
+
+	Mule, beginning with Version 2.2, includes handy utilities
+(any2ps and m2ps) for printing files in any of the encodings supported
+by Mule (which is a lot of encodings, by the way). These programs use
+BDF fonts. See the beginning of Part 2 for a list of URLs that have
+CJK BDF fonts.
+	GNU Emacs is a fine editor, and Mule takes it several steps
+further by providing multilingual support. I personally use Mule
+together with SKK (for Japanese input) -- it is a superb combination.
+
+
+7.2: CNPRINT
+
+	CNPRINT, developed by Yidao Cai (cai@neurophys.wisc.edu), is a
+utility to print CJK text (or convert it to a PostScript file), and is
+available for MS-DOS, VMS, and UNIX systems. A wide range of encoding
+methods are supported by CNPRINT.
+	CNPRINT is available at the following URLs:
+
+  ftp://ftp.ifcss.org/pub/software/{dos,unix,vms}/print/
+  ftp://neurophys.wisc.edu/[public.cn]/
+
+
+7.3: MASS
+
+	MASS (Multilingual Application Support Service), developed at
+the National University of Singapore, is a suite of software tools
+that speed and ease the development of UNIX-based CJK (actually, more
+than just CJK) applications. It supports a wide variety of character
+sets and encodings, including ISO 10646-1:1993 (UCS-2, UTF-7, and
+UTF-8), EACC, and CCCII.
+	More information on MASS, to include contact information for
+its developers, can be found at the following URL:
+
+  http://www.iss.nus.sg/RND/MLP/Projects/MASS/MASS.html
+
+
+7.4: ADOBE TYPE MANAGER (ATM)
+
+	Adobe Type Manager for Macintosh, beginning with Version 3.8,
+is CJK-capable (as long as the underlying operating system is CJK-
+capable). Actually, ATM generically supports CID-keyed fonts, which
+are based on a newly-developed file specification for fonts with large
+numbers of characters (like CJK fonts). See Section 7.9 for more
+details.
+	ATM is very easy to obtain. It is bundled with fonts and
+applications from Adobe Systems (chances are you have ATM if you
+recently purchased an Adobe product). But what about Windows? The
+Windows version of ATM should soon follow with identical
+functionality.
+
+
+7.5: MACINTOSH SOFTWARE
+
+	WorldScript II, a System Extension introduced with System 7,
+provides multi-byte script handling, namely CJK support. If a
+Macintosh product claims to support WorldScript II, chances are it is
+CJK-capable (provided that your operating system has the necessary
+extensions loaded).
+	The CJK encodings that are supported by WorldScript II capable
+applications are the same as made available by the underlying
+Macintosh operating system. No import/export of other encodings is
+supported at the operating system level. You must run separate
+conversion utilities for both import and export. Anyway, below are
+some products that are known to be CJK capable.
+	Nisus Writer, written by Nisus Software, is fully CJK-capable
+as long as you have the appropriate scripts installed (such as CLK for
+Chinese or JLK for Japanese). A "Language Key" (read "dongle") is also
+required for Chinese and Korean (and some one-byte scripts such as
+Arabic and Hebrew). A demo version of Nisus Writer is available at the
+following URL:
+
+  ftp://ftp.nisus-soft.com/pub/nisus/demos/
+
+Give it a try! Updates are also available at the same FTP site. Nisus
+Software can be contacted using the following e-mail address or
+through their WWW page:
+
+  info@nisus-soft.com
+  http://www.nisus-soft.com/
+
+I also suggest reading "The Nisus Way" by Joe Kissell. Chapter 13
+provides detailed information about using Nisus Writer with
+WorldScript, and includes a CD-ROM containing among other things a
+trial (expires after 90 days) version of Nisus Writer and a
+non-expiring version of Nisus Compact.
+	ClarisWorks by Claris Corporation, beginning with Version 4.0,
+is compatible with WorldScript II and all Apple language kits. This
+translates into full CJK support. The following URL provides a trial
+version of ClarisWorks:
+
+  ftp://ftp.claris.com/pub/USA-Macintosh/Trial_Software/
+
+The following URL has detailed information on this and other Claris
+products:
+
+  http://www.claris.com/
+
+	The latest version of WordPerfect by Novell Incorporated is
+also compatible with WorldScript II. The following URL has detailed
+information:
+
+  http://wp.novell.com/tree.htm
+
+
+7.6: MACBLUE TELNET
+
+	Although MacBlue Telnet (a modified version of NCSA Telnet) is
+Macintosh software, I describe it separately because it does not
+require the various Apple Language Kits or localized operating
+systems. There are also input methods, adapted from cxterm (see
+Section 7.7), available that cover the CJK spectrum (Japanese,
+Simplified Chinese, Traditional Chinese, and Korean).
+	MacBlue Telnet is available at the following URL:
+
+  ftp://ftp.ifcss.org/pub/software/mac/networking/MacBlueTelnet/
+
+Its associated CJK input methods are at the following URL:
+
+  ftp://ftp.ifcss.org/pub/software/mac/input/
+
+
+7.7: CXTERM
+
+	This program, cxterm, is a CJK-capable xterm for X Windows
+(works with X11R4, X11R5, and X11R6). It is based on the X11R6 xterm.
+It is available at the following URL:
+
+  ftp://ftp.ifcss.org/pub/software/x-win/cxterm/
+
+	The following URL is for a program that adds Unicode
+capability to cxterm:
+
+  ftp://ftp.ifcss.org/pub/software/unix/convert/hztty-2.0.tar.gz
+
+The following URL adds support for other encodings to cxterm:
+
+  ftp://ftp.ifcss.org/pub/software/unix/convert/BeTTY-1.534.tar.gz
+
+
+7.8: UW-DBM
+
+	UW-DBM, for Windows 3.1, Windows 95, and Windows NT, is a
+program that allows users to handle Chinese (Big Five, GB-2312-80, or
+HZ code), Japanese (Shift-JIS), and Korean (KS C 5601-1992)
+simultaneously. More information on UW-DBM is available at the
+following URL:
+
+  http://www.gy.com/ccd/win95/cjkw95.htm
+
+	A demo version of UW-DBM is available at the following URL:
+
+  ftp://ftp.aimnet.com/pub/users/chinabus/uwdbm40.zip
+
+
+7.9: POSTSCRIPT
+
+	With the introduction of CID-keyed Font Technology, PostScript
+has become fully CJK capable.
+	Adobe Systems has developed the following CJK character
+collection for CID-keyed fonts (font developers are encouraged to
+conform to these specifications):
+
+  Character Collection  CIDs   Supported Character Sets & Encodings
+  ^^^^^^^^^^^^^^^^^^^^  ^^^^   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+  Adobe-GB1-1           9,897  GB 2312-80 and GB/T 12345-90; 7-bit ISO
+                               2022 and EUC
+  Adobe-CNS1-0         14,099  Big Five (ETen extensions) and CNS
+                               11643-1992 Planes 1 and 2; Big Five,
+                               7-bit ISO 2022, and EUC
+  Adobe-Japan1-2        8,720  JIS X 0208-1990; Shift-JIS, 7-bit ISO
+                               2022, and EUC
+  Adobe-Japan2-0        6,068  JIS X 0212-1990; 7-bit ISO 2022 and EUC
+  Adobe-Korea1-1       18,155  KS C 5601-1992 (Macintosh extensions
+                               plus Johab); 7-bit ISO 2022, EUC, UHC,
+                               and Johab
+
+Note that Macintosh and Windows do not support any of the encodings
+for Adobe-Japan2-0, thus fonts based on that specification are
+unusable for those platforms.
+	Adobe Systems also have a few things in the works (that is,
+they are either proposed or in draft form), all of which are
+supplements to above character collections (that is, they add CIDs):
+
+  Character Collection  CIDs   Supported Character Sets & Encodings
+  ^^^^^^^^^^^^^^^^^^^^  ^^^^   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+  Adobe-CNS1-1         +6,018  Add CNS 11643-1992 Plane 3 support (30
+                               of the 6,148 hanzi are in Adobe-CNS1-0)
+
+	To find out more about these CJK character collections or
+CID-keyed font technology, contact the Adobe Developers Association.
+Several CID-related documents have been published. ADA's contact
+information is as follows:
+
+  Adobe Developers Association
+  Adobe Systems Incorporated
+  1585 Charleston Road
+  P.O. Box 7900
+  Mountain View, CA 94039-7900
+  USA
+  +1-415-961-4111 (phone)
+  +1-415-967-9231 (facsimile)
+  devsupp-person@adobe.com
+  http://www.adobe.com/Support/
+
+Adobe Systems has recently developed the CID SDK (CID Software
+Developers Kit), which is on a single CD-ROM. Contact the Adobe
+Developers Association for information on obtaining a copy.
+	The complete CID-keyed font file specification and an overview
+document are available at the following URLs (as a PostScript or PDF
+[Adobe Acrobat] file, respectively):
+
+  ftp://ftp.adobe.com/pub/adobe/DeveloperSupport/TechNotes/PSfiles/
+  ftp://ftp.adobe.com/pub/adobe/DeveloperSupport/TechNotes/PDFfiles/
+
+The file names (not provided above due to URL length) are:
+
+  5014.CMap_CIDFont_Spec.ps    (complete CID engineering specification)
+  5014.CMap_CIDFont_Spec.pdf
+  5092.CID_Overview.ps         (CID technology overview)
+  5092.CID_Overview.pdf
+
+Other related files, most character collection specifications, are
+available only in PDF format at the latter URL indicated above:
+
+  5004.AFM_Spec.pdf            (Includes CID-keyed AFM specification)
+  5078b.pdf                    (Adobe-Japan1-2 character collection)
+  5079b.pdf                    (Adobe-GB1-0 character collection)
+  5080b.pdf                    (Adobe-CNS1-0 character collection)
+  5093b.pdf                    (Adobe-Korea1-0 character collection)
+  5094.pdf                     (Adobe CJK CMap file descriptions)
+  5097b.pdf                    (Adobe-Japan2-0 character collection)
+
+If you do not have Adobe Acrobat, there is a freely-available Acrobat
+Reader (for Macintosh, Windows, MS-DOS, and UNIX) at the following
+URL:
+
+  ftp://ftp.adobe.com/pub/adobe/Applications/Acrobat/
+
+	I have also placed some CJK character collection materials,
+including prototype Unicode (UCS-2 and UTF-8) CMap files, at the
+following URL:
+
+  ftp://ftp.ora.com/pub/examples/nutshell/ujip/adobe/
+
+A sample (Adobe-Korea1-0) CIDFont is also available at the above URL.
+	There is also a somewhat brief description of CID-keyed fonts
+at the end of Chapter 6 in UJIP.
+
+
+7.10: NJWIN
+
+	Hongbo Data Systems has recently release a ShareWare ($49 USD)
+product called NJWIN whose purpose is to force the display of CJK text
+in non-CJK applications running under US Windows 95. Actually, there
+are two versions: full CJK and Japanese only.
+	NJWIN and its full description are available at the following
+URL:
+
+  http://www.njstar.com.au/njstar/njwin.htm
+
+Other (popular) URLs that carry NJWIN are as follows:
+
+  ftp://ftp.ora.com/pub/examples/nutshell/ujip/windows/
+  ftp://ftp.cc.monash.edu.au/pub/nihongo/
+
+	Hongbo Data Systems' e-mail address is:
+
+  hongbo@njstar.com.au
+
+Their WWW Home Page is at the following URL:
+
+  http://www.njstar.com.au/
+
+
+PART 8: CJK PROGRAMMING ISSUES
+
+	This new section describes issues related to using specific
+programming languages to process CJK text.
+
+
+8.1: C AND C++
+
+	At one time I used C on a regular basis for my CJK programming
+needs, and released three tools for others to use: JConv, JChar, and
+JCode. While these tools are specific to Japanese, they can be easily
+adapted for CJK use. Their source code is available at the following
+URL:
+
+  ftp://ftp.ora.com/pub/examples/nutshell/ujip/src/
+
+	I also provided several C code snippets in Chapter 7 of
+UJIP. These are available in machine-readable form at the following
+URL:
+
+  ftp://ftp.ora.com/pub/examples/nutshell/ujip/Ch7/
+
+
+8.2: PERL
+
+	Although Perl does not have any special CJK facilities (note
+that most implementations of C and C++ do not either), it provides a
+powerful programming environment that is useful for many CJK-related
+tasks.
+	The noteworthy features of Perl are associative arrays and
+regular expressions. These are features not found in C or C++, and
+allow one to write meaningful code in little time.
+	JPerl is an implementation of Perl that provides two-byte
+support for Japanese (EUC or Shift-JIS encoding). It is not ideal
+because JPerl scripts often cannot run under (non-Japanese) Perl.
+	If you often write programs for internal use, I suggest that
+you check out Perl to see if it can offer you something. Chances are
+that it can. A good place to start looking at Perl are through books
+on the subject (see Section A.3.1) and at the following URL:
+
+  http://www.perl.com/
+
+	For those who like additional reading, "The Perl Journal" is
+starting up, and information is at the following URL:
+
+  http://work.media.mit.edu/the_perl_journal/
+
+
+8.3: JAVA
+
+	I am just starting to learn about the Java programming
+language (and rightly so since my wife is Javanese!). It seems to have
+a lot to offer.
+	The most interesting aspects of Java are:
+
+o Built-in support for Unicode and UTF-8.
+o The programmer must write code in the object-oriented paradigm.
+o Provides a portable way to supply compiled code.
+o Security features for Internet use.
+
+More information on Java are at the following URLs:
+
+  http://www.gamelan.com/
+  http://www.javasoft.com/
+
+Oh, Gamelan is the name of Javanese music.
+	Of the books about Java published thus far, the one I consider
+to be the best is "Java in a Nutshell" by David Flanagan.
+	One programming feature of Perl that I dearly miss in Java are
+regexes (regular expressions). Luckily, some kind person wrote a regex
+package for Java based on Perl regexes. Information on this Java regex
+package is available at the following URL:
+
+  http://www.win.net/~stevesoft/pat/
+
+
+A FINAL NOTE
+
+	I hope that the information presented here will prove
+useful. I would like to keep the electronic version of this document
+as up-to-date as possible, and through readers' input, I am able to
+do so.
+	Many readers will notice that I am very heavy into UNIX and
+Macintosh (well, I recently got my first PC). If anyone has any
+information on CJK-capable interfaces for other platforms, please feel
+free to send it to me, and I will be sure to include it in the next
+version of CJK.INF. Please include sources for the software or
+documentation by providing addresses, phone numbers, FTP sites, and so
+on.
+	Please do not hesitate to ask me further question concerning
+any subject presented in this document.
+
+
+ACKNOWLEDGMENTS
+
+	I would like to express my deepest thanks to Kazumasa Utashiro
+of Internet Initiative Japan (IIJ). He taught to me how to send and
+receive Japanese text using the 7-bit ISO 2022 codes back in 1989.
+With his help I was able to write JAPAN.INF, my book, and this
+document in order to inform others about what he has taught me plus
+more.
+	Next, I thank all the folks at O'Reilly & Associates for
+publishing UJIP. Special thanks to Tim O'Reilly for accepting the book
+proposal, and to Peter Mui for guiding me through the process. I have
+had nothing but good experiences with "them there fine folks."
+	I got to know Jack Halpern through UJIP, and he subsequently
+translated it into Japanese. Many thanks to him.
+	I am also grateful to my employer, Adobe Systems, for letting
+me work on interesting CJK-related projects. I really like what I do
+here. In particular, I want to thank Dan Mills, my manager, for
+putting up with me for these past four years.
+	Lastly, I would also like to thank the countless people who
+provided comments on JAPAN.INF, UJIP, and CJK.INF. I hope that this
+new document lives up to the spirit of my previous efforts.
+
+
+APPENDIX A: OTHER INFORMATION SOURCES
+
+	One of the most useful types of information are pointers to
+other information sources. This appendix provides just that.
+
+
+A.1: USENET NEWSGROUPS AND MAILING LISTS
+
+	Appendix L of UJIP provided information on a number of mailing
+lists. This section supplements that appendix with information on
+other useful mailing lists, and points out which ones in UJIP are
+relevant to readers of CJK.INF.
+
+
+A.1.1: USENET NEWSGROUPS
+
+	The following Usenet Newsgroups typically have postings with
+information relevant to issues discussed in CJK.INF (in alphabetical
+order):
+
+  alt.chinese.computing
+  alt.chinese.text                (HZ encoding used for Chinese text)
+  alt.chinese.text.big5           (Big Five encoding used for Chinese text)
+  alt.japanese.text               (JIS encoding used for Japanese text)
+  chinese.flame                   (UTF-7)
+  chinese.text.unicode            (UTF-8)
+  comp.lang.c
+  comp.lang.c++
+  comp.lang.java
+  comp.lang.perl.misc
+  comp.software.international
+  comp.std.internat
+  fj.editor.mule                  (JIS encoding used for Japanese text)
+  fj.kanji                        (JIS encoding used for Japanese text)
+  fj.net.infosystems.www.browsers (JIS encoding used for Japanese text)
+  fj.news.reader                  (JIS encoding used for Japanese text)
+  han.comp.hangul
+  han.sys.mac
+  sci.lang.japan                  (JIS encoding used for Japanese text)
+
+	If your local news host does not provide a feed of the fj.*
+newsgroups (shame on them!), or if you do not have access to Usenet
+News, you can alternatively fetch them from the following URL:
+
+  ftp://kuso.shef.ac.uk/pub/News/
+
+The subdirectories correspond to the newsgroup name, but with the
+"dots" being replaced by "slashes." For example, the "fj.binaries.mac"
+newsgroup is archived in the "fj/binaries/mac" subdirectory. Many
+thanks to Earl Kinmonth (jp1ek@sunc.shef.uc.uk) for this service.
+	There are some sites that carry full feeds of the fj.*
+newsgroups, and permit public access (meaning that you can configure
+your news reader to point to it). The only one I know of thus far is
+as follows:
+
+  ume.cc.tsukuba.ac.jp
+
+
+A.1.2: MAILING LISTS
+
+	The following are mailing lists that should interest readers
+of this document (some are more active than others). The first line
+after each entry indicates the address (or addresses) that can be used
+for subscribing. The second line is the address for posting.
+
+o CCNET-L MAILING LIST
+  listserv@uga.uga.edu (or listserv@uga)
+  ccnet-l@uga.uga.edu
+
+o China Net Mailing List
+  majordomo@lists.mindspring.com
+  (See http://www.asia-net.com/ or jobs@asia-net.com)
+
+o EASUG (East Asian Software Users Group) Mailing List
+  easug-request@guvax.acc.georgetown.edu
+  easug@guvax.acc.georgetown.edu
+
+o EBTI-L (Electronic Buddhist Text Initiative) Mailing List
+  ebti-l-request@uxmail.ust.hk
+  ebti-l@uxmail.ust.hk
+
+o EFJ (Electronic Frontiers Japan) Mailing List
+  majordomo@lists.twics.com
+  efj@lists.twics.com
+
+o Hangul Mailing List (han.comp.hangul newsgroup)
+  majordomo@cair.kaist.ac.kr
+  hangul@cair.kaist.ac.kr
+
+o INSOFT-L Mailing List
+  majordomo@trans2.b30.ingr.com
+  insoft-l@trans2.b30
+
+o ISO 10646 Mailing List
+  listproc@listproc.hcf.jhu.edu
+  iso10646@listproc.hcf.jhu.edu
+
+o Japan Net Mailing List
+  majordomo@lists.mindspring.com
+  (See http://www.asia-net.com/ or jobs@asia-net.com)
+
+o KanjiTalk Mailing List
+  kanjitalk-request@cs15.atr-sw.atr.co.jp (or kanjitalk-request@crl.go.jp)
+  kanjitalk@cs15.atr-sw.atr.co.jp (or kanjitalk@crl.go.jp)
+
+o Mac Mailing List (han.sys.mac newsgroup)
+  majordomo@krnic.net
+  mac@krnic.net
+
+o Mule Mailing List
+  mule-request@etl.go.jp
+  mule@etl.go.jp or mule-jp@etl.go.jp
+
+o NIHONGO Mailing List (sci.lang.japan newsgroup)
+  listserv@mitvma.mit.edu (or listserv@mitvma)
+  nihongo@mitvma.mit.edu
+
+o Nihongo-Hiroba Mailing List
+  listproc@mcfeeley.cc.utexas.edu
+  nihongo-hiroba@mcfeeley.cc.utexas.edu
+
+o Nisus Mailing List
+  listserv@dartmouth.edu
+  nisus@dartmouth.edu
+
+o TLUG (Tokyo Linux User's Group) Mailing List
+  majordomo@lists.twics.com
+  tlug@lists.twics.com
+
+o Unicode Mailing List
+  unicode-request@unicode.org
+  unicode@unicode.org
+
+o WNN User Mailing List
+  wnn-user-request@wnn.astem.or.jp
+  wnn-user-jp@wnn.astem.or.jp
+
+o WWW Multilingual Mailing List
+  www-mling-request@square.ntt.jp
+  www-mling@square.ntt.jp
+
+If the name of the mailing list is part of the subscription address
+(such as "easug-request"), the message body should look like this:
+
+  subscribe
+
+Including your name is optional. If username in the subscription
+address is "listserv" or "majordomo" (these are names of mailing list
+managing software), the mailing list name must appear after
+"subscribe" in the message body as follows:
+
+  subscribe ccnet-l
+
+Again, including your name is optional.
+	The following URL has information about Japanese-related
+mailing lists:
+
+  gopher://gan1.ncc.go.jp/11/INFO/mail-lists/
+
+
+A.2: INTERNET RESOURCES
+
+	The Internet provides what I would consider to be the greatest
+information resources of all. These can be subcategorized into FTP,
+Telnet, Gopher, WWW, and e-mail.
+
+
+A.2.1: USEFUL FTP SITES
+
+	Below are the URLs for useful FTP sites. The directory
+specified is the recommended place from which to start poking around
+for useful files.
+
+  ftp://cair-archive.kaist.ac.kr/pub/hangul/
+  ftp://etlport.etl.go.jp/pub/mule/
+  ftp://ftp.adobe.com/pub/adobe/
+  ftp://ftp.cc.monash.edu.au/pub/nihongo/
+  ftp://ftp.ifcss.org/pub/software/
+  ftp://ftp.ora.com/pub/examples/nutshell/ujip/
+  ftp://ftp.sra.co.jp/pub/
+  ftp://ftp.uwtc.washington.edu/pub/Japanese/
+  ftp://kuso.shef.ac.uk/pub/Japanese/
+  ftp://unicode.org/pub/
+
+This list is expected to grow.
+
+
+A.2.2: USEFUL TELNET SITES
+
+	For those who have a NIFTY-Serve account, there is now a very
+convenient way to access NIFTY-Serve using telnet. The URL is as
+follows:
+
+  telnet://r2.niftyserve.or.jp/
+
+Information about what NIFTY-Serve has to offer (and how to subscribe)
+can be found at the following URL:
+
+  http://www.nifty.co.jp/
+
+	Another information service with a similar access mechanism is
+CompuServe, whose URL is as follows:
+
+  telnet://compuserve.com/
+
+You will need to press the return key to get the "Host Name:" prompt,
+at which time you type "cis" (just follow the menus from this point
+on).
+	You can also do a search on fj.* newsgroup articles at the
+following URL:
+
+  telnet://asahi-net.or.jp/
+
+You login as "fj-db" once you are connected.
+
+
+A.2.3: USEFUL GOPHER SITES
+
+	I am not too much of a Gopher user. There, of course, is the
+following:
+
+  gopher://gopher.ora.com/
+
+Another Gopher site provides information on Japanese-related mailing
+lists:
+
+  gopher://gan1.ncc.go.jp/11/INFO/mail-lists/
+
+If you happen to know of others, please let me know.
+
+
+A.2.4: USEFUL WWW SITES
+
+	Because the World-Wide Web is a constantly changing place (and
+more importantly, because I don't want to re-issue a new version of
+this document every month!), I will maintain links to useful documents
+at my WWW Home Page. Its URL is as follows:
+
+  http://jasper.ora.com/lunde/
+
+If you cannot get to my WWW Home Page, you couldn't get to any that I
+would list here anyway.
+
+
+A.2.5: USEFUL MAIL SERVERS
+
+	In the past (that is, in JAPAN.INF) I included a full list of
+the domains in the "jp" hierarchy. That took up a lot of space, and
+changes very rapidly. You can now send a request to a mail server in
+order to return the most current listing. The mail server is:
+
+  mail-server@nic.ad.jp
+
+The most common command is "send," and the following arguments can be
+supplied to retrieve specific documents (and should be in the message
+body, not on the "Subject:" line):
+
+  send help
+  send index
+  send jpnic/domain-list.txt
+  send jpnic/domain-list-e.txt
+
+The first sends back a help file, the second sends back a complete
+index of files that can be retrieved (use this one to see what other
+useful stuff is available), and the last two send back a complete
+listing of domains in the "fj" hierarchy (the last one send it back in
+English/romanized).
+
+
+A.3: OTHER RESOURCES
+
+	This section provides pointers to specific documentation
+available electronically or in print.
+
+
+A.3.1: BOOKS
+
+	There are other useful reference materials available in print
+or online, in addition to the various national and international
+standards mentioned throughout this document. The following are books
+that I recommend for further reading or mental stimulus. (Sorry for
+plugging my own books in this list, but they are relevant.)
+
+o Clews, John. "Language Automation Worldwide: The Development of
+  Character Set Standards." SESAME Computer Projects. 1988. ISBN
+  1-870095-01-4.
+
+o Flanagan, David. "Java in a Nutshell." O'Reilly & Associates,
+  Inc. 1996. ISBN 1-56592-183-6.
+
+o Frisch, AEleen. "Essential System Administration." Second Edition.
+  O'Reilly & Associates, Inc. 1995. ISBN 1-56592-127-5.
+
+o Huang, Jack & Timothy Huang. "An Introduction to Chinese, Japanese
+  and Korean Computing." World Scientific Computing. 1989. ISBN
+  9971-50-664-5.
+
+o IBM Corporation. "Character Data Representation Architecture - Level
+  2, Registry." 1993. IBM order number SC09-1391-01.
+
+o Kano, Nadine. "Developing International Software for Windows 95 and
+  Windows NT." Microsoft Press. 1995. ISBN 1-55615-840-8.
+
+o Kirch, Olaf. "Linux Network Administrator's Guide." O'Reilly &
+  Associates, Inc. 1995. ISBN 1-56592-087-2.
+
+o Kissell, Joe. "The Nisus Way." MIS:Press. 1996. ISBN 1-55828-455-9.
+
+o Krol, Ed. "The Whole Internet User's Guide & Catalog." Second
+  Edition. O'Reilly & Associates, Inc. 1994. ISBN 1-56592-063-5.
+
+o Liu, Cricket et al. "Managing Internet Information Services."
+  O'Reilly & Associates, Inc. 1994. ISBN 1-56592-062-7.
+
+o Lunde, Ken. "Understanding Japanese Information Processing."
+  O'Reilly & Associates, Incorporated. 1993. ISBN 1-56592-043-0. LCCN
+  PL524.5.L86 1993.
+
+o Lunde, Ken. "Nihongo Joho Shori." SOFTBANK Corporation. 1995. ISBN
+  4-89052-708-7.
+
+o Luong, Tuoc V. et al. "Internationalization: Developing Software for
+  Global Markets." John Wiley & Sons, Incorporated. 1995. ISBN
+  0-471-07661-9.
+
+o Schwartz, Randal L. "Learning Perl." O'Reilly & Associates,
+  Incorporated. 1993. ISBN 1-56592-042-2.
+
+o Stallman, Richard M. "GNU Emacs Manual." Tenth edition. Free
+  Software Foundation. 1994. ISBN 1-882114-04-3.
+
+o Tuthill, Bill. "Solaris International Developer's Guide." SunSoft
+  Press and PTR Prentice Hall. 1993. ISBN 0-13-031063-8.
+
+o Unicode Consortium, The. "The Unicode Standard: Worldwide Character
+  Encoding." Version 1.0. Volume 2. Addison-Wesley. 1992. ISBN
+  0-201-60845-6.
+
+o Vromans, Johan. "Perl 5 Desktop Reference." O'Reilly & Associates,
+  Inc. 1996. ISBN 1-56592-187-9.
+
+o Wall, Larry & Randal L. Schwartz. "Programming Perl." O'Reilly &
+  Associates, Incorporated. 1991. ISBN 0-937175-64-1.
+
+o Welsh, Matt & Lar Kaufman. "Running Linux." O'Reilly & Associates,
+  Inc. 1995. ISBN 1-56592-100-3.
+
+	If you want to get your hands on any of the national or
+international standards mentioned in this document, I suggest the
+following:
+
+o The American National Standards Institute can provide ISO, KS, and
+  JIS standards. Bear in mind that ISO standards will most likely
+  arrive as a photocopy of the original.
+
+  ANSI
+  11 West 42nd Street
+  New York, NY 10036
+  USA
+  +1-212-642-4900 (phone)
+  +1-212-302-1286 (facsimile)
+
+o The International Organization for Standardization can provide
+  ISO standards.
+
+  ISO
+  1, rue de Varemb
+  Case postale 56
+  CH-1211, Geneva 20
+  SWITZERLAND
+  +41-22-749-01-11 (phone)
+  +41-22-733-34-30 (facsimile)
+  central@isocs.iso.ch (e-mail)
+  http://www.iso.ch/ (WWW)
+
+o Chinese (GB and CNS) standards are the hardest to obtain. It is
+  quite unfortunate.
+
+
+A.3.2: MAGAZINES
+
+o "Computing Japan," published monthly, ISSN 1340-7228,
+  editors@cj.gol.com.
+
+o "MANGAJIN," published 10 times per year, ISSN 1051-8177.
+
+o "Multilingual Communications & Computing," published bi-monthly,
+  ISSN 1065-7657, info@multilingual.com.
+
+o "The Perl Journal," published quarterly, ISSN 1087-903X,
+  perl-journal-subscriptions@perl.com.
+
+
+A.3.3: JOURNALS
+
+o "Chinese Information Processing" (CIP), published bi-monthly, ISSN
+  1003-9082. (In Chinese.)
+
+o "Computer Processing of Chinese & Oriental Languages" (CPCOL),
+  co-published twice a year by World Scientific Publishing and Chinese
+  Language Computer Society (CLCS), ISSN 0715-9048.
+
+o "The Electronic Bodhidharma," published by the International
+  Research Institute for Zen (IRIZ) Buddhism, Hanazono University,
+  Japan. More information on the organization that publishes this
+  journal is available at the following URL:
+
+  http://www.iijnet.or.jp/iriz/irizhtml/irizhome.htm
+
+
+A.3.4: RFCs
+
+	Many RFCs (Request For Comments) are relevant to this
+document. They are:
+
+o RFC 1341: "MIME (Multipurpose Internet Mail Extensions): Mechanisms
+  for Specifying and Describing the Format of Internet Message
+  Bodies," by Nathaniel Borenstein and Ned Freed, June 1992.
+
+o RFC 1342: "Representation of Non-ASCII Text in Internet Message
+  Headers," by Keith Moore, June 1992.
+
+o RFC 1468: "Japanese Character Encoding for Internet Messages," by
+  Jun Murai et al., June 1993.
+
+o RFC 1521: "MIME (Multipurpose Internet Mail Extensions) Part One:
+  Mechanisms for Specifying and Describing the Format of Internet
+  Message Bodies," by Nathaniel Borenstein and Ned Freed, September
+  1993. Obsoletes RFC 1341.
+
+o RFC 1522: "MIME (Multipurpose Internet Mail Extensions) Part Two:
+  Message Header Extensions for Non-ASCII Text," by Keith Moore,
+  September 1993. Obsoletes RFC 1342.
+
+o RFC 1554: "ISO-2022-JP-2: Multilingual Extension of ISO-2022-JP," by
+  Masataka Ohta and Kenichi Handa, December 1993.
+
+o RFC 1557: "Korean Character Encoding for Internet Messages," by
+  Uhhyung Choi et al., December 1993.
+
+o RFC 1642: "UTF-7: A Mail-Safe Transformation Format of Unicode," by
+  David Goldsmith and Mark Davis, July 1994.
+
+o RFC 1815: "Character Sets ISO-10646 and ISO-10646-J-1," by Masataka
+  Ohta, July 1995.
+
+o RFC 1842: "ASCII Printable Characters-Based Chinese Character
+  Encoding for Internet Messages," by Ya-Gui Wei et al., August 1995.
+
+o RFC 1843: "HZ - A Data Format for Exchanging Files of Arbitrarily
+  Mixed Chinese and ASCII Characters," by Fung Fung Lee, August 1995.
+
+o RFC 1922: "Chinese Character Encoding for Internet Messages," by
+  Haifeng Zhu et al., March 1996.
+
+These RFCs can be obtained from FTP archives that contain all RFC
+documents, such as at the following URLs
+
+  ftp://nic.ddn.mil/rfc/
+  ftp://ftp.uu.net/inet/rfc/
+
+But these specific ones are mirrored at the following URL for
+convenience:
+
+  ftp://ftp.ora.com/pub/examples/nutshell/ujip/Ch9/
+
+
+A.3.5: FAQs
+
+	There are several FAQ (Frequently Asked Questions) files that
+provide useful information. The following is a listing of some along
+with their URLs:
+
+o "Japanese Language Information" FAQ (formerly the "sci.lang.japan"
+  FAQ) by Rafael Santos (santos@mickey.ai.kyutech.ac.jp) at:
+
+  http://www.mickey.ai.kyutech.ac.jp/cgi-bin/japanese/
+
+  Update announcements are usually posted to the sci.lang.japan
+  newsgroup.
+
+o "Programming for Internationalization" FAQ by Michael Gschwind
+  (mike@vlsivie.tuwien.ac.at) at:
+
+  ftp://ftp.vlsivie.tuwien.ac.at/pub/8bit/ISO-programming
+
+  Also posted to the comp.software.international newsgroup. This and
+  other internationalization documents are also accessible through the
+  following URL:
+
+  http://www.vlsivie.tuwien.ac.at/mike/i18n.html
+
+o Three FAQs about Internet Service Providers in Japan by Taki Naruto
+  (tn@panix.com), Jesse Casman (jcasman@unm.edu), and Kenji Yoshida
+  (kenny@mb.tokyo.infoweb.or.jp), respectively, at:
+
+  http://www.panix.com/~tn/ispj.html
+  http://nobunaga.unm.edu/internet.html
+  http://cswww2.essex.ac.uk/users/whean/japan/net.html
+
+o "Internationalization Reference List" by Eugene Dorr
+  (gdorr@pgh.legent.com) at:
+
+  ftp://ftp.ora.com/pub/examples/nutshell/ujip/doc/i18n-books.txt
+
+  Note really a FAQ, but quite useful because it is a very complete
+  listing of I18N-related books.
+
+o "INSOFT-L Service" by Brian Tatro (btatro@tatro.com) at:
+
+  http://iquest.com/~btatro/in2.html
+
+  This includes a link to the FAQ for the INSOFT-L Mailing List (see
+  Section A.1.2).
+
+o "How to Use Japanese on the Internet with a PC: From Login to WWW"
+  by Hideki Hirayama (sgw01623@niftyserve.or.jp) at:
+
+  ftp://ftp.ora.com/pub/examples/nutshell/ujip/faq/jpn-inet.FAQ
+
+o "Hangul and Internet in Korea" FAQ by Jungshik Shin
+  (jshin@minerva.cis.yale.edu) at:
+
+  http://pantheon.cis.yale.edu/~jshin/faq/
+---  END (CJK.INF VERSION 2.1 07/12/96) 185553 BYTES  ---
diff --git a/tools/encoding/cp1250.txt b/tools/encoding/cp1250.txt
new file mode 100644
index 0000000..081d776
--- /dev/null
+++ b/tools/encoding/cp1250.txt
@@ -0,0 +1,274 @@
+#
+#    Name:     cp1250 to Unicode table
+#    Unicode version: 2.0
+#    Table version: 2.01
+#    Table format:  Format A
+#    Date:          04/15/98
+#
+#    Contact:       cpxlate@microsoft.com
+#
+#    General notes: none
+#
+#    Format: Three tab-separated columns
+#        Column #1 is the cp1250 code (in hex)
+#        Column #2 is the Unicode (in hex as 0xXXXX)
+#        Column #3 is the Unicode name (follows a comment sign, '#')
+#
+#    The entries are in cp1250 order
+#
+0x00	0x0000	#NULL
+0x01	0x0001	#START OF HEADING
+0x02	0x0002	#START OF TEXT
+0x03	0x0003	#END OF TEXT
+0x04	0x0004	#END OF TRANSMISSION
+0x05	0x0005	#ENQUIRY
+0x06	0x0006	#ACKNOWLEDGE
+0x07	0x0007	#BELL
+0x08	0x0008	#BACKSPACE
+0x09	0x0009	#HORIZONTAL TABULATION
+0x0A	0x000A	#LINE FEED
+0x0B	0x000B	#VERTICAL TABULATION
+0x0C	0x000C	#FORM FEED
+0x0D	0x000D	#CARRIAGE RETURN
+0x0E	0x000E	#SHIFT OUT
+0x0F	0x000F	#SHIFT IN
+0x10	0x0010	#DATA LINK ESCAPE
+0x11	0x0011	#DEVICE CONTROL ONE
+0x12	0x0012	#DEVICE CONTROL TWO
+0x13	0x0013	#DEVICE CONTROL THREE
+0x14	0x0014	#DEVICE CONTROL FOUR
+0x15	0x0015	#NEGATIVE ACKNOWLEDGE
+0x16	0x0016	#SYNCHRONOUS IDLE
+0x17	0x0017	#END OF TRANSMISSION BLOCK
+0x18	0x0018	#CANCEL
+0x19	0x0019	#END OF MEDIUM
+0x1A	0x001A	#SUBSTITUTE
+0x1B	0x001B	#ESCAPE
+0x1C	0x001C	#FILE SEPARATOR
+0x1D	0x001D	#GROUP SEPARATOR
+0x1E	0x001E	#RECORD SEPARATOR
+0x1F	0x001F	#UNIT SEPARATOR
+0x20	0x0020	#SPACE
+0x21	0x0021	#EXCLAMATION MARK
+0x22	0x0022	#QUOTATION MARK
+0x23	0x0023	#NUMBER SIGN
+0x24	0x0024	#DOLLAR SIGN
+0x25	0x0025	#PERCENT SIGN
+0x26	0x0026	#AMPERSAND
+0x27	0x0027	#APOSTROPHE
+0x28	0x0028	#LEFT PARENTHESIS
+0x29	0x0029	#RIGHT PARENTHESIS
+0x2A	0x002A	#ASTERISK
+0x2B	0x002B	#PLUS SIGN
+0x2C	0x002C	#COMMA
+0x2D	0x002D	#HYPHEN-MINUS
+0x2E	0x002E	#FULL STOP
+0x2F	0x002F	#SOLIDUS
+0x30	0x0030	#DIGIT ZERO
+0x31	0x0031	#DIGIT ONE
+0x32	0x0032	#DIGIT TWO
+0x33	0x0033	#DIGIT THREE
+0x34	0x0034	#DIGIT FOUR
+0x35	0x0035	#DIGIT FIVE
+0x36	0x0036	#DIGIT SIX
+0x37	0x0037	#DIGIT SEVEN
+0x38	0x0038	#DIGIT EIGHT
+0x39	0x0039	#DIGIT NINE
+0x3A	0x003A	#COLON
+0x3B	0x003B	#SEMICOLON
+0x3C	0x003C	#LESS-THAN SIGN
+0x3D	0x003D	#EQUALS SIGN
+0x3E	0x003E	#GREATER-THAN SIGN
+0x3F	0x003F	#QUESTION MARK
+0x40	0x0040	#COMMERCIAL AT
+0x41	0x0041	#LATIN CAPITAL LETTER A
+0x42	0x0042	#LATIN CAPITAL LETTER B
+0x43	0x0043	#LATIN CAPITAL LETTER C
+0x44	0x0044	#LATIN CAPITAL LETTER D
+0x45	0x0045	#LATIN CAPITAL LETTER E
+0x46	0x0046	#LATIN CAPITAL LETTER F
+0x47	0x0047	#LATIN CAPITAL LETTER G
+0x48	0x0048	#LATIN CAPITAL LETTER H
+0x49	0x0049	#LATIN CAPITAL LETTER I
+0x4A	0x004A	#LATIN CAPITAL LETTER J
+0x4B	0x004B	#LATIN CAPITAL LETTER K
+0x4C	0x004C	#LATIN CAPITAL LETTER L
+0x4D	0x004D	#LATIN CAPITAL LETTER M
+0x4E	0x004E	#LATIN CAPITAL LETTER N
+0x4F	0x004F	#LATIN CAPITAL LETTER O
+0x50	0x0050	#LATIN CAPITAL LETTER P
+0x51	0x0051	#LATIN CAPITAL LETTER Q
+0x52	0x0052	#LATIN CAPITAL LETTER R
+0x53	0x0053	#LATIN CAPITAL LETTER S
+0x54	0x0054	#LATIN CAPITAL LETTER T
+0x55	0x0055	#LATIN CAPITAL LETTER U
+0x56	0x0056	#LATIN CAPITAL LETTER V
+0x57	0x0057	#LATIN CAPITAL LETTER W
+0x58	0x0058	#LATIN CAPITAL LETTER X
+0x59	0x0059	#LATIN CAPITAL LETTER Y
+0x5A	0x005A	#LATIN CAPITAL LETTER Z
+0x5B	0x005B	#LEFT SQUARE BRACKET
+0x5C	0x005C	#REVERSE SOLIDUS
+0x5D	0x005D	#RIGHT SQUARE BRACKET
+0x5E	0x005E	#CIRCUMFLEX ACCENT
+0x5F	0x005F	#LOW LINE
+0x60	0x0060	#GRAVE ACCENT
+0x61	0x0061	#LATIN SMALL LETTER A
+0x62	0x0062	#LATIN SMALL LETTER B
+0x63	0x0063	#LATIN SMALL LETTER C
+0x64	0x0064	#LATIN SMALL LETTER D
+0x65	0x0065	#LATIN SMALL LETTER E
+0x66	0x0066	#LATIN SMALL LETTER F
+0x67	0x0067	#LATIN SMALL LETTER G
+0x68	0x0068	#LATIN SMALL LETTER H
+0x69	0x0069	#LATIN SMALL LETTER I
+0x6A	0x006A	#LATIN SMALL LETTER J
+0x6B	0x006B	#LATIN SMALL LETTER K
+0x6C	0x006C	#LATIN SMALL LETTER L
+0x6D	0x006D	#LATIN SMALL LETTER M
+0x6E	0x006E	#LATIN SMALL LETTER N
+0x6F	0x006F	#LATIN SMALL LETTER O
+0x70	0x0070	#LATIN SMALL LETTER P
+0x71	0x0071	#LATIN SMALL LETTER Q
+0x72	0x0072	#LATIN SMALL LETTER R
+0x73	0x0073	#LATIN SMALL LETTER S
+0x74	0x0074	#LATIN SMALL LETTER T
+0x75	0x0075	#LATIN SMALL LETTER U
+0x76	0x0076	#LATIN SMALL LETTER V
+0x77	0x0077	#LATIN SMALL LETTER W
+0x78	0x0078	#LATIN SMALL LETTER X
+0x79	0x0079	#LATIN SMALL LETTER Y
+0x7A	0x007A	#LATIN SMALL LETTER Z
+0x7B	0x007B	#LEFT CURLY BRACKET
+0x7C	0x007C	#VERTICAL LINE
+0x7D	0x007D	#RIGHT CURLY BRACKET
+0x7E	0x007E	#TILDE
+0x7F	0x007F	#DELETE
+0x80	0x20AC	#EURO SIGN
+0x81	      	#UNDEFINED
+0x82	0x201A	#SINGLE LOW-9 QUOTATION MARK
+0x83	      	#UNDEFINED
+0x84	0x201E	#DOUBLE LOW-9 QUOTATION MARK
+0x85	0x2026	#HORIZONTAL ELLIPSIS
+0x86	0x2020	#DAGGER
+0x87	0x2021	#DOUBLE DAGGER
+0x88	      	#UNDEFINED
+0x89	0x2030	#PER MILLE SIGN
+0x8A	0x0160	#LATIN CAPITAL LETTER S WITH CARON
+0x8B	0x2039	#SINGLE LEFT-POINTING ANGLE QUOTATION MARK
+0x8C	0x015A	#LATIN CAPITAL LETTER S WITH ACUTE
+0x8D	0x0164	#LATIN CAPITAL LETTER T WITH CARON
+0x8E	0x017D	#LATIN CAPITAL LETTER Z WITH CARON
+0x8F	0x0179	#LATIN CAPITAL LETTER Z WITH ACUTE
+0x90	      	#UNDEFINED
+0x91	0x2018	#LEFT SINGLE QUOTATION MARK
+0x92	0x2019	#RIGHT SINGLE QUOTATION MARK
+0x93	0x201C	#LEFT DOUBLE QUOTATION MARK
+0x94	0x201D	#RIGHT DOUBLE QUOTATION MARK
+0x95	0x2022	#BULLET
+0x96	0x2013	#EN DASH
+0x97	0x2014	#EM DASH
+0x98	      	#UNDEFINED
+0x99	0x2122	#TRADE MARK SIGN
+0x9A	0x0161	#LATIN SMALL LETTER S WITH CARON
+0x9B	0x203A	#SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
+0x9C	0x015B	#LATIN SMALL LETTER S WITH ACUTE
+0x9D	0x0165	#LATIN SMALL LETTER T WITH CARON
+0x9E	0x017E	#LATIN SMALL LETTER Z WITH CARON
+0x9F	0x017A	#LATIN SMALL LETTER Z WITH ACUTE
+0xA0	0x00A0	#NO-BREAK SPACE
+0xA1	0x02C7	#CARON
+0xA2	0x02D8	#BREVE
+0xA3	0x0141	#LATIN CAPITAL LETTER L WITH STROKE
+0xA4	0x00A4	#CURRENCY SIGN
+0xA5	0x0104	#LATIN CAPITAL LETTER A WITH OGONEK
+0xA6	0x00A6	#BROKEN BAR
+0xA7	0x00A7	#SECTION SIGN
+0xA8	0x00A8	#DIAERESIS
+0xA9	0x00A9	#COPYRIGHT SIGN
+0xAA	0x015E	#LATIN CAPITAL LETTER S WITH CEDILLA
+0xAB	0x00AB	#LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+0xAC	0x00AC	#NOT SIGN
+0xAD	0x00AD	#SOFT HYPHEN
+0xAE	0x00AE	#REGISTERED SIGN
+0xAF	0x017B	#LATIN CAPITAL LETTER Z WITH DOT ABOVE
+0xB0	0x00B0	#DEGREE SIGN
+0xB1	0x00B1	#PLUS-MINUS SIGN
+0xB2	0x02DB	#OGONEK
+0xB3	0x0142	#LATIN SMALL LETTER L WITH STROKE
+0xB4	0x00B4	#ACUTE ACCENT
+0xB5	0x00B5	#MICRO SIGN
+0xB6	0x00B6	#PILCROW SIGN
+0xB7	0x00B7	#MIDDLE DOT
+0xB8	0x00B8	#CEDILLA
+0xB9	0x0105	#LATIN SMALL LETTER A WITH OGONEK
+0xBA	0x015F	#LATIN SMALL LETTER S WITH CEDILLA
+0xBB	0x00BB	#RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+0xBC	0x013D	#LATIN CAPITAL LETTER L WITH CARON
+0xBD	0x02DD	#DOUBLE ACUTE ACCENT
+0xBE	0x013E	#LATIN SMALL LETTER L WITH CARON
+0xBF	0x017C	#LATIN SMALL LETTER Z WITH DOT ABOVE
+0xC0	0x0154	#LATIN CAPITAL LETTER R WITH ACUTE
+0xC1	0x00C1	#LATIN CAPITAL LETTER A WITH ACUTE
+0xC2	0x00C2	#LATIN CAPITAL LETTER A WITH CIRCUMFLEX
+0xC3	0x0102	#LATIN CAPITAL LETTER A WITH BREVE
+0xC4	0x00C4	#LATIN CAPITAL LETTER A WITH DIAERESIS
+0xC5	0x0139	#LATIN CAPITAL LETTER L WITH ACUTE
+0xC6	0x0106	#LATIN CAPITAL LETTER C WITH ACUTE
+0xC7	0x00C7	#LATIN CAPITAL LETTER C WITH CEDILLA
+0xC8	0x010C	#LATIN CAPITAL LETTER C WITH CARON
+0xC9	0x00C9	#LATIN CAPITAL LETTER E WITH ACUTE
+0xCA	0x0118	#LATIN CAPITAL LETTER E WITH OGONEK
+0xCB	0x00CB	#LATIN CAPITAL LETTER E WITH DIAERESIS
+0xCC	0x011A	#LATIN CAPITAL LETTER E WITH CARON
+0xCD	0x00CD	#LATIN CAPITAL LETTER I WITH ACUTE
+0xCE	0x00CE	#LATIN CAPITAL LETTER I WITH CIRCUMFLEX
+0xCF	0x010E	#LATIN CAPITAL LETTER D WITH CARON
+0xD0	0x0110	#LATIN CAPITAL LETTER D WITH STROKE
+0xD1	0x0143	#LATIN CAPITAL LETTER N WITH ACUTE
+0xD2	0x0147	#LATIN CAPITAL LETTER N WITH CARON
+0xD3	0x00D3	#LATIN CAPITAL LETTER O WITH ACUTE
+0xD4	0x00D4	#LATIN CAPITAL LETTER O WITH CIRCUMFLEX
+0xD5	0x0150	#LATIN CAPITAL LETTER O WITH DOUBLE ACUTE
+0xD6	0x00D6	#LATIN CAPITAL LETTER O WITH DIAERESIS
+0xD7	0x00D7	#MULTIPLICATION SIGN
+0xD8	0x0158	#LATIN CAPITAL LETTER R WITH CARON
+0xD9	0x016E	#LATIN CAPITAL LETTER U WITH RING ABOVE
+0xDA	0x00DA	#LATIN CAPITAL LETTER U WITH ACUTE
+0xDB	0x0170	#LATIN CAPITAL LETTER U WITH DOUBLE ACUTE
+0xDC	0x00DC	#LATIN CAPITAL LETTER U WITH DIAERESIS
+0xDD	0x00DD	#LATIN CAPITAL LETTER Y WITH ACUTE
+0xDE	0x0162	#LATIN CAPITAL LETTER T WITH CEDILLA
+0xDF	0x00DF	#LATIN SMALL LETTER SHARP S
+0xE0	0x0155	#LATIN SMALL LETTER R WITH ACUTE
+0xE1	0x00E1	#LATIN SMALL LETTER A WITH ACUTE
+0xE2	0x00E2	#LATIN SMALL LETTER A WITH CIRCUMFLEX
+0xE3	0x0103	#LATIN SMALL LETTER A WITH BREVE
+0xE4	0x00E4	#LATIN SMALL LETTER A WITH DIAERESIS
+0xE5	0x013A	#LATIN SMALL LETTER L WITH ACUTE
+0xE6	0x0107	#LATIN SMALL LETTER C WITH ACUTE
+0xE7	0x00E7	#LATIN SMALL LETTER C WITH CEDILLA
+0xE8	0x010D	#LATIN SMALL LETTER C WITH CARON
+0xE9	0x00E9	#LATIN SMALL LETTER E WITH ACUTE
+0xEA	0x0119	#LATIN SMALL LETTER E WITH OGONEK
+0xEB	0x00EB	#LATIN SMALL LETTER E WITH DIAERESIS
+0xEC	0x011B	#LATIN SMALL LETTER E WITH CARON
+0xED	0x00ED	#LATIN SMALL LETTER I WITH ACUTE
+0xEE	0x00EE	#LATIN SMALL LETTER I WITH CIRCUMFLEX
+0xEF	0x010F	#LATIN SMALL LETTER D WITH CARON
+0xF0	0x0111	#LATIN SMALL LETTER D WITH STROKE
+0xF1	0x0144	#LATIN SMALL LETTER N WITH ACUTE
+0xF2	0x0148	#LATIN SMALL LETTER N WITH CARON
+0xF3	0x00F3	#LATIN SMALL LETTER O WITH ACUTE
+0xF4	0x00F4	#LATIN SMALL LETTER O WITH CIRCUMFLEX
+0xF5	0x0151	#LATIN SMALL LETTER O WITH DOUBLE ACUTE
+0xF6	0x00F6	#LATIN SMALL LETTER O WITH DIAERESIS
+0xF7	0x00F7	#DIVISION SIGN
+0xF8	0x0159	#LATIN SMALL LETTER R WITH CARON
+0xF9	0x016F	#LATIN SMALL LETTER U WITH RING ABOVE
+0xFA	0x00FA	#LATIN SMALL LETTER U WITH ACUTE
+0xFB	0x0171	#LATIN SMALL LETTER U WITH DOUBLE ACUTE
+0xFC	0x00FC	#LATIN SMALL LETTER U WITH DIAERESIS
+0xFD	0x00FD	#LATIN SMALL LETTER Y WITH ACUTE
+0xFE	0x0163	#LATIN SMALL LETTER T WITH CEDILLA
+0xFF	0x02D9	#DOT ABOVE
diff --git a/tools/encoding/cp1251.txt b/tools/encoding/cp1251.txt
new file mode 100644
index 0000000..37eadbd
--- /dev/null
+++ b/tools/encoding/cp1251.txt
@@ -0,0 +1,274 @@
+#
+#    Name:     cp1251 to Unicode table
+#    Unicode version: 2.0
+#    Table version: 2.01
+#    Table format:  Format A
+#    Date:          04/15/98
+#
+#    Contact:       cpxlate@microsoft.com
+#
+#    General notes: none
+#
+#    Format: Three tab-separated columns
+#        Column #1 is the cp1251 code (in hex)
+#        Column #2 is the Unicode (in hex as 0xXXXX)
+#        Column #3 is the Unicode name (follows a comment sign, '#')
+#
+#    The entries are in cp1251 order
+#
+0x00	0x0000	#NULL
+0x01	0x0001	#START OF HEADING
+0x02	0x0002	#START OF TEXT
+0x03	0x0003	#END OF TEXT
+0x04	0x0004	#END OF TRANSMISSION
+0x05	0x0005	#ENQUIRY
+0x06	0x0006	#ACKNOWLEDGE
+0x07	0x0007	#BELL
+0x08	0x0008	#BACKSPACE
+0x09	0x0009	#HORIZONTAL TABULATION
+0x0A	0x000A	#LINE FEED
+0x0B	0x000B	#VERTICAL TABULATION
+0x0C	0x000C	#FORM FEED
+0x0D	0x000D	#CARRIAGE RETURN
+0x0E	0x000E	#SHIFT OUT
+0x0F	0x000F	#SHIFT IN
+0x10	0x0010	#DATA LINK ESCAPE
+0x11	0x0011	#DEVICE CONTROL ONE
+0x12	0x0012	#DEVICE CONTROL TWO
+0x13	0x0013	#DEVICE CONTROL THREE
+0x14	0x0014	#DEVICE CONTROL FOUR
+0x15	0x0015	#NEGATIVE ACKNOWLEDGE
+0x16	0x0016	#SYNCHRONOUS IDLE
+0x17	0x0017	#END OF TRANSMISSION BLOCK
+0x18	0x0018	#CANCEL
+0x19	0x0019	#END OF MEDIUM
+0x1A	0x001A	#SUBSTITUTE
+0x1B	0x001B	#ESCAPE
+0x1C	0x001C	#FILE SEPARATOR
+0x1D	0x001D	#GROUP SEPARATOR
+0x1E	0x001E	#RECORD SEPARATOR
+0x1F	0x001F	#UNIT SEPARATOR
+0x20	0x0020	#SPACE
+0x21	0x0021	#EXCLAMATION MARK
+0x22	0x0022	#QUOTATION MARK
+0x23	0x0023	#NUMBER SIGN
+0x24	0x0024	#DOLLAR SIGN
+0x25	0x0025	#PERCENT SIGN
+0x26	0x0026	#AMPERSAND
+0x27	0x0027	#APOSTROPHE
+0x28	0x0028	#LEFT PARENTHESIS
+0x29	0x0029	#RIGHT PARENTHESIS
+0x2A	0x002A	#ASTERISK
+0x2B	0x002B	#PLUS SIGN
+0x2C	0x002C	#COMMA
+0x2D	0x002D	#HYPHEN-MINUS
+0x2E	0x002E	#FULL STOP
+0x2F	0x002F	#SOLIDUS
+0x30	0x0030	#DIGIT ZERO
+0x31	0x0031	#DIGIT ONE
+0x32	0x0032	#DIGIT TWO
+0x33	0x0033	#DIGIT THREE
+0x34	0x0034	#DIGIT FOUR
+0x35	0x0035	#DIGIT FIVE
+0x36	0x0036	#DIGIT SIX
+0x37	0x0037	#DIGIT SEVEN
+0x38	0x0038	#DIGIT EIGHT
+0x39	0x0039	#DIGIT NINE
+0x3A	0x003A	#COLON
+0x3B	0x003B	#SEMICOLON
+0x3C	0x003C	#LESS-THAN SIGN
+0x3D	0x003D	#EQUALS SIGN
+0x3E	0x003E	#GREATER-THAN SIGN
+0x3F	0x003F	#QUESTION MARK
+0x40	0x0040	#COMMERCIAL AT
+0x41	0x0041	#LATIN CAPITAL LETTER A
+0x42	0x0042	#LATIN CAPITAL LETTER B
+0x43	0x0043	#LATIN CAPITAL LETTER C
+0x44	0x0044	#LATIN CAPITAL LETTER D
+0x45	0x0045	#LATIN CAPITAL LETTER E
+0x46	0x0046	#LATIN CAPITAL LETTER F
+0x47	0x0047	#LATIN CAPITAL LETTER G
+0x48	0x0048	#LATIN CAPITAL LETTER H
+0x49	0x0049	#LATIN CAPITAL LETTER I
+0x4A	0x004A	#LATIN CAPITAL LETTER J
+0x4B	0x004B	#LATIN CAPITAL LETTER K
+0x4C	0x004C	#LATIN CAPITAL LETTER L
+0x4D	0x004D	#LATIN CAPITAL LETTER M
+0x4E	0x004E	#LATIN CAPITAL LETTER N
+0x4F	0x004F	#LATIN CAPITAL LETTER O
+0x50	0x0050	#LATIN CAPITAL LETTER P
+0x51	0x0051	#LATIN CAPITAL LETTER Q
+0x52	0x0052	#LATIN CAPITAL LETTER R
+0x53	0x0053	#LATIN CAPITAL LETTER S
+0x54	0x0054	#LATIN CAPITAL LETTER T
+0x55	0x0055	#LATIN CAPITAL LETTER U
+0x56	0x0056	#LATIN CAPITAL LETTER V
+0x57	0x0057	#LATIN CAPITAL LETTER W
+0x58	0x0058	#LATIN CAPITAL LETTER X
+0x59	0x0059	#LATIN CAPITAL LETTER Y
+0x5A	0x005A	#LATIN CAPITAL LETTER Z
+0x5B	0x005B	#LEFT SQUARE BRACKET
+0x5C	0x005C	#REVERSE SOLIDUS
+0x5D	0x005D	#RIGHT SQUARE BRACKET
+0x5E	0x005E	#CIRCUMFLEX ACCENT
+0x5F	0x005F	#LOW LINE
+0x60	0x0060	#GRAVE ACCENT
+0x61	0x0061	#LATIN SMALL LETTER A
+0x62	0x0062	#LATIN SMALL LETTER B
+0x63	0x0063	#LATIN SMALL LETTER C
+0x64	0x0064	#LATIN SMALL LETTER D
+0x65	0x0065	#LATIN SMALL LETTER E
+0x66	0x0066	#LATIN SMALL LETTER F
+0x67	0x0067	#LATIN SMALL LETTER G
+0x68	0x0068	#LATIN SMALL LETTER H
+0x69	0x0069	#LATIN SMALL LETTER I
+0x6A	0x006A	#LATIN SMALL LETTER J
+0x6B	0x006B	#LATIN SMALL LETTER K
+0x6C	0x006C	#LATIN SMALL LETTER L
+0x6D	0x006D	#LATIN SMALL LETTER M
+0x6E	0x006E	#LATIN SMALL LETTER N
+0x6F	0x006F	#LATIN SMALL LETTER O
+0x70	0x0070	#LATIN SMALL LETTER P
+0x71	0x0071	#LATIN SMALL LETTER Q
+0x72	0x0072	#LATIN SMALL LETTER R
+0x73	0x0073	#LATIN SMALL LETTER S
+0x74	0x0074	#LATIN SMALL LETTER T
+0x75	0x0075	#LATIN SMALL LETTER U
+0x76	0x0076	#LATIN SMALL LETTER V
+0x77	0x0077	#LATIN SMALL LETTER W
+0x78	0x0078	#LATIN SMALL LETTER X
+0x79	0x0079	#LATIN SMALL LETTER Y
+0x7A	0x007A	#LATIN SMALL LETTER Z
+0x7B	0x007B	#LEFT CURLY BRACKET
+0x7C	0x007C	#VERTICAL LINE
+0x7D	0x007D	#RIGHT CURLY BRACKET
+0x7E	0x007E	#TILDE
+0x7F	0x007F	#DELETE
+0x80	0x0402	#CYRILLIC CAPITAL LETTER DJE
+0x81	0x0403	#CYRILLIC CAPITAL LETTER GJE
+0x82	0x201A	#SINGLE LOW-9 QUOTATION MARK
+0x83	0x0453	#CYRILLIC SMALL LETTER GJE
+0x84	0x201E	#DOUBLE LOW-9 QUOTATION MARK
+0x85	0x2026	#HORIZONTAL ELLIPSIS
+0x86	0x2020	#DAGGER
+0x87	0x2021	#DOUBLE DAGGER
+0x88	0x20AC	#EURO SIGN
+0x89	0x2030	#PER MILLE SIGN
+0x8A	0x0409	#CYRILLIC CAPITAL LETTER LJE
+0x8B	0x2039	#SINGLE LEFT-POINTING ANGLE QUOTATION MARK
+0x8C	0x040A	#CYRILLIC CAPITAL LETTER NJE
+0x8D	0x040C	#CYRILLIC CAPITAL LETTER KJE
+0x8E	0x040B	#CYRILLIC CAPITAL LETTER TSHE
+0x8F	0x040F	#CYRILLIC CAPITAL LETTER DZHE
+0x90	0x0452	#CYRILLIC SMALL LETTER DJE
+0x91	0x2018	#LEFT SINGLE QUOTATION MARK
+0x92	0x2019	#RIGHT SINGLE QUOTATION MARK
+0x93	0x201C	#LEFT DOUBLE QUOTATION MARK
+0x94	0x201D	#RIGHT DOUBLE QUOTATION MARK
+0x95	0x2022	#BULLET
+0x96	0x2013	#EN DASH
+0x97	0x2014	#EM DASH
+0x98	      	#UNDEFINED
+0x99	0x2122	#TRADE MARK SIGN
+0x9A	0x0459	#CYRILLIC SMALL LETTER LJE
+0x9B	0x203A	#SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
+0x9C	0x045A	#CYRILLIC SMALL LETTER NJE
+0x9D	0x045C	#CYRILLIC SMALL LETTER KJE
+0x9E	0x045B	#CYRILLIC SMALL LETTER TSHE
+0x9F	0x045F	#CYRILLIC SMALL LETTER DZHE
+0xA0	0x00A0	#NO-BREAK SPACE
+0xA1	0x040E	#CYRILLIC CAPITAL LETTER SHORT U
+0xA2	0x045E	#CYRILLIC SMALL LETTER SHORT U
+0xA3	0x0408	#CYRILLIC CAPITAL LETTER JE
+0xA4	0x00A4	#CURRENCY SIGN
+0xA5	0x0490	#CYRILLIC CAPITAL LETTER GHE WITH UPTURN
+0xA6	0x00A6	#BROKEN BAR
+0xA7	0x00A7	#SECTION SIGN
+0xA8	0x0401	#CYRILLIC CAPITAL LETTER IO
+0xA9	0x00A9	#COPYRIGHT SIGN
+0xAA	0x0404	#CYRILLIC CAPITAL LETTER UKRAINIAN IE
+0xAB	0x00AB	#LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+0xAC	0x00AC	#NOT SIGN
+0xAD	0x00AD	#SOFT HYPHEN
+0xAE	0x00AE	#REGISTERED SIGN
+0xAF	0x0407	#CYRILLIC CAPITAL LETTER YI
+0xB0	0x00B0	#DEGREE SIGN
+0xB1	0x00B1	#PLUS-MINUS SIGN
+0xB2	0x0406	#CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I
+0xB3	0x0456	#CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I
+0xB4	0x0491	#CYRILLIC SMALL LETTER GHE WITH UPTURN
+0xB5	0x00B5	#MICRO SIGN
+0xB6	0x00B6	#PILCROW SIGN
+0xB7	0x00B7	#MIDDLE DOT
+0xB8	0x0451	#CYRILLIC SMALL LETTER IO
+0xB9	0x2116	#NUMERO SIGN
+0xBA	0x0454	#CYRILLIC SMALL LETTER UKRAINIAN IE
+0xBB	0x00BB	#RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+0xBC	0x0458	#CYRILLIC SMALL LETTER JE
+0xBD	0x0405	#CYRILLIC CAPITAL LETTER DZE
+0xBE	0x0455	#CYRILLIC SMALL LETTER DZE
+0xBF	0x0457	#CYRILLIC SMALL LETTER YI
+0xC0	0x0410	#CYRILLIC CAPITAL LETTER A
+0xC1	0x0411	#CYRILLIC CAPITAL LETTER BE
+0xC2	0x0412	#CYRILLIC CAPITAL LETTER VE
+0xC3	0x0413	#CYRILLIC CAPITAL LETTER GHE
+0xC4	0x0414	#CYRILLIC CAPITAL LETTER DE
+0xC5	0x0415	#CYRILLIC CAPITAL LETTER IE
+0xC6	0x0416	#CYRILLIC CAPITAL LETTER ZHE
+0xC7	0x0417	#CYRILLIC CAPITAL LETTER ZE
+0xC8	0x0418	#CYRILLIC CAPITAL LETTER I
+0xC9	0x0419	#CYRILLIC CAPITAL LETTER SHORT I
+0xCA	0x041A	#CYRILLIC CAPITAL LETTER KA
+0xCB	0x041B	#CYRILLIC CAPITAL LETTER EL
+0xCC	0x041C	#CYRILLIC CAPITAL LETTER EM
+0xCD	0x041D	#CYRILLIC CAPITAL LETTER EN
+0xCE	0x041E	#CYRILLIC CAPITAL LETTER O
+0xCF	0x041F	#CYRILLIC CAPITAL LETTER PE
+0xD0	0x0420	#CYRILLIC CAPITAL LETTER ER
+0xD1	0x0421	#CYRILLIC CAPITAL LETTER ES
+0xD2	0x0422	#CYRILLIC CAPITAL LETTER TE
+0xD3	0x0423	#CYRILLIC CAPITAL LETTER U
+0xD4	0x0424	#CYRILLIC CAPITAL LETTER EF
+0xD5	0x0425	#CYRILLIC CAPITAL LETTER HA
+0xD6	0x0426	#CYRILLIC CAPITAL LETTER TSE
+0xD7	0x0427	#CYRILLIC CAPITAL LETTER CHE
+0xD8	0x0428	#CYRILLIC CAPITAL LETTER SHA
+0xD9	0x0429	#CYRILLIC CAPITAL LETTER SHCHA
+0xDA	0x042A	#CYRILLIC CAPITAL LETTER HARD SIGN
+0xDB	0x042B	#CYRILLIC CAPITAL LETTER YERU
+0xDC	0x042C	#CYRILLIC CAPITAL LETTER SOFT SIGN
+0xDD	0x042D	#CYRILLIC CAPITAL LETTER E
+0xDE	0x042E	#CYRILLIC CAPITAL LETTER YU
+0xDF	0x042F	#CYRILLIC CAPITAL LETTER YA
+0xE0	0x0430	#CYRILLIC SMALL LETTER A
+0xE1	0x0431	#CYRILLIC SMALL LETTER BE
+0xE2	0x0432	#CYRILLIC SMALL LETTER VE
+0xE3	0x0433	#CYRILLIC SMALL LETTER GHE
+0xE4	0x0434	#CYRILLIC SMALL LETTER DE
+0xE5	0x0435	#CYRILLIC SMALL LETTER IE
+0xE6	0x0436	#CYRILLIC SMALL LETTER ZHE
+0xE7	0x0437	#CYRILLIC SMALL LETTER ZE
+0xE8	0x0438	#CYRILLIC SMALL LETTER I
+0xE9	0x0439	#CYRILLIC SMALL LETTER SHORT I
+0xEA	0x043A	#CYRILLIC SMALL LETTER KA
+0xEB	0x043B	#CYRILLIC SMALL LETTER EL
+0xEC	0x043C	#CYRILLIC SMALL LETTER EM
+0xED	0x043D	#CYRILLIC SMALL LETTER EN
+0xEE	0x043E	#CYRILLIC SMALL LETTER O
+0xEF	0x043F	#CYRILLIC SMALL LETTER PE
+0xF0	0x0440	#CYRILLIC SMALL LETTER ER
+0xF1	0x0441	#CYRILLIC SMALL LETTER ES
+0xF2	0x0442	#CYRILLIC SMALL LETTER TE
+0xF3	0x0443	#CYRILLIC SMALL LETTER U
+0xF4	0x0444	#CYRILLIC SMALL LETTER EF
+0xF5	0x0445	#CYRILLIC SMALL LETTER HA
+0xF6	0x0446	#CYRILLIC SMALL LETTER TSE
+0xF7	0x0447	#CYRILLIC SMALL LETTER CHE
+0xF8	0x0448	#CYRILLIC SMALL LETTER SHA
+0xF9	0x0449	#CYRILLIC SMALL LETTER SHCHA
+0xFA	0x044A	#CYRILLIC SMALL LETTER HARD SIGN
+0xFB	0x044B	#CYRILLIC SMALL LETTER YERU
+0xFC	0x044C	#CYRILLIC SMALL LETTER SOFT SIGN
+0xFD	0x044D	#CYRILLIC SMALL LETTER E
+0xFE	0x044E	#CYRILLIC SMALL LETTER YU
+0xFF	0x044F	#CYRILLIC SMALL LETTER YA
diff --git a/tools/encoding/cp1252.txt b/tools/encoding/cp1252.txt
new file mode 100644
index 0000000..2ca4486
--- /dev/null
+++ b/tools/encoding/cp1252.txt
@@ -0,0 +1,274 @@
+#
+#    Name:     cp1252 to Unicode table
+#    Unicode version: 2.0
+#    Table version: 2.01
+#    Table format:  Format A
+#    Date:          04/15/98
+#
+#    Contact:       cpxlate@microsoft.com
+#
+#    General notes: none
+#
+#    Format: Three tab-separated columns
+#        Column #1 is the cp1252 code (in hex)
+#        Column #2 is the Unicode (in hex as 0xXXXX)
+#        Column #3 is the Unicode name (follows a comment sign, '#')
+#
+#    The entries are in cp1252 order
+#
+0x00	0x0000	#NULL
+0x01	0x0001	#START OF HEADING
+0x02	0x0002	#START OF TEXT
+0x03	0x0003	#END OF TEXT
+0x04	0x0004	#END OF TRANSMISSION
+0x05	0x0005	#ENQUIRY
+0x06	0x0006	#ACKNOWLEDGE
+0x07	0x0007	#BELL
+0x08	0x0008	#BACKSPACE
+0x09	0x0009	#HORIZONTAL TABULATION
+0x0A	0x000A	#LINE FEED
+0x0B	0x000B	#VERTICAL TABULATION
+0x0C	0x000C	#FORM FEED
+0x0D	0x000D	#CARRIAGE RETURN
+0x0E	0x000E	#SHIFT OUT
+0x0F	0x000F	#SHIFT IN
+0x10	0x0010	#DATA LINK ESCAPE
+0x11	0x0011	#DEVICE CONTROL ONE
+0x12	0x0012	#DEVICE CONTROL TWO
+0x13	0x0013	#DEVICE CONTROL THREE
+0x14	0x0014	#DEVICE CONTROL FOUR
+0x15	0x0015	#NEGATIVE ACKNOWLEDGE
+0x16	0x0016	#SYNCHRONOUS IDLE
+0x17	0x0017	#END OF TRANSMISSION BLOCK
+0x18	0x0018	#CANCEL
+0x19	0x0019	#END OF MEDIUM
+0x1A	0x001A	#SUBSTITUTE
+0x1B	0x001B	#ESCAPE
+0x1C	0x001C	#FILE SEPARATOR
+0x1D	0x001D	#GROUP SEPARATOR
+0x1E	0x001E	#RECORD SEPARATOR
+0x1F	0x001F	#UNIT SEPARATOR
+0x20	0x0020	#SPACE
+0x21	0x0021	#EXCLAMATION MARK
+0x22	0x0022	#QUOTATION MARK
+0x23	0x0023	#NUMBER SIGN
+0x24	0x0024	#DOLLAR SIGN
+0x25	0x0025	#PERCENT SIGN
+0x26	0x0026	#AMPERSAND
+0x27	0x0027	#APOSTROPHE
+0x28	0x0028	#LEFT PARENTHESIS
+0x29	0x0029	#RIGHT PARENTHESIS
+0x2A	0x002A	#ASTERISK
+0x2B	0x002B	#PLUS SIGN
+0x2C	0x002C	#COMMA
+0x2D	0x002D	#HYPHEN-MINUS
+0x2E	0x002E	#FULL STOP
+0x2F	0x002F	#SOLIDUS
+0x30	0x0030	#DIGIT ZERO
+0x31	0x0031	#DIGIT ONE
+0x32	0x0032	#DIGIT TWO
+0x33	0x0033	#DIGIT THREE
+0x34	0x0034	#DIGIT FOUR
+0x35	0x0035	#DIGIT FIVE
+0x36	0x0036	#DIGIT SIX
+0x37	0x0037	#DIGIT SEVEN
+0x38	0x0038	#DIGIT EIGHT
+0x39	0x0039	#DIGIT NINE
+0x3A	0x003A	#COLON
+0x3B	0x003B	#SEMICOLON
+0x3C	0x003C	#LESS-THAN SIGN
+0x3D	0x003D	#EQUALS SIGN
+0x3E	0x003E	#GREATER-THAN SIGN
+0x3F	0x003F	#QUESTION MARK
+0x40	0x0040	#COMMERCIAL AT
+0x41	0x0041	#LATIN CAPITAL LETTER A
+0x42	0x0042	#LATIN CAPITAL LETTER B
+0x43	0x0043	#LATIN CAPITAL LETTER C
+0x44	0x0044	#LATIN CAPITAL LETTER D
+0x45	0x0045	#LATIN CAPITAL LETTER E
+0x46	0x0046	#LATIN CAPITAL LETTER F
+0x47	0x0047	#LATIN CAPITAL LETTER G
+0x48	0x0048	#LATIN CAPITAL LETTER H
+0x49	0x0049	#LATIN CAPITAL LETTER I
+0x4A	0x004A	#LATIN CAPITAL LETTER J
+0x4B	0x004B	#LATIN CAPITAL LETTER K
+0x4C	0x004C	#LATIN CAPITAL LETTER L
+0x4D	0x004D	#LATIN CAPITAL LETTER M
+0x4E	0x004E	#LATIN CAPITAL LETTER N
+0x4F	0x004F	#LATIN CAPITAL LETTER O
+0x50	0x0050	#LATIN CAPITAL LETTER P
+0x51	0x0051	#LATIN CAPITAL LETTER Q
+0x52	0x0052	#LATIN CAPITAL LETTER R
+0x53	0x0053	#LATIN CAPITAL LETTER S
+0x54	0x0054	#LATIN CAPITAL LETTER T
+0x55	0x0055	#LATIN CAPITAL LETTER U
+0x56	0x0056	#LATIN CAPITAL LETTER V
+0x57	0x0057	#LATIN CAPITAL LETTER W
+0x58	0x0058	#LATIN CAPITAL LETTER X
+0x59	0x0059	#LATIN CAPITAL LETTER Y
+0x5A	0x005A	#LATIN CAPITAL LETTER Z
+0x5B	0x005B	#LEFT SQUARE BRACKET
+0x5C	0x005C	#REVERSE SOLIDUS
+0x5D	0x005D	#RIGHT SQUARE BRACKET
+0x5E	0x005E	#CIRCUMFLEX ACCENT
+0x5F	0x005F	#LOW LINE
+0x60	0x0060	#GRAVE ACCENT
+0x61	0x0061	#LATIN SMALL LETTER A
+0x62	0x0062	#LATIN SMALL LETTER B
+0x63	0x0063	#LATIN SMALL LETTER C
+0x64	0x0064	#LATIN SMALL LETTER D
+0x65	0x0065	#LATIN SMALL LETTER E
+0x66	0x0066	#LATIN SMALL LETTER F
+0x67	0x0067	#LATIN SMALL LETTER G
+0x68	0x0068	#LATIN SMALL LETTER H
+0x69	0x0069	#LATIN SMALL LETTER I
+0x6A	0x006A	#LATIN SMALL LETTER J
+0x6B	0x006B	#LATIN SMALL LETTER K
+0x6C	0x006C	#LATIN SMALL LETTER L
+0x6D	0x006D	#LATIN SMALL LETTER M
+0x6E	0x006E	#LATIN SMALL LETTER N
+0x6F	0x006F	#LATIN SMALL LETTER O
+0x70	0x0070	#LATIN SMALL LETTER P
+0x71	0x0071	#LATIN SMALL LETTER Q
+0x72	0x0072	#LATIN SMALL LETTER R
+0x73	0x0073	#LATIN SMALL LETTER S
+0x74	0x0074	#LATIN SMALL LETTER T
+0x75	0x0075	#LATIN SMALL LETTER U
+0x76	0x0076	#LATIN SMALL LETTER V
+0x77	0x0077	#LATIN SMALL LETTER W
+0x78	0x0078	#LATIN SMALL LETTER X
+0x79	0x0079	#LATIN SMALL LETTER Y
+0x7A	0x007A	#LATIN SMALL LETTER Z
+0x7B	0x007B	#LEFT CURLY BRACKET
+0x7C	0x007C	#VERTICAL LINE
+0x7D	0x007D	#RIGHT CURLY BRACKET
+0x7E	0x007E	#TILDE
+0x7F	0x007F	#DELETE
+0x80	0x20AC	#EURO SIGN
+0x81	      	#UNDEFINED
+0x82	0x201A	#SINGLE LOW-9 QUOTATION MARK
+0x83	0x0192	#LATIN SMALL LETTER F WITH HOOK
+0x84	0x201E	#DOUBLE LOW-9 QUOTATION MARK
+0x85	0x2026	#HORIZONTAL ELLIPSIS
+0x86	0x2020	#DAGGER
+0x87	0x2021	#DOUBLE DAGGER
+0x88	0x02C6	#MODIFIER LETTER CIRCUMFLEX ACCENT
+0x89	0x2030	#PER MILLE SIGN
+0x8A	0x0160	#LATIN CAPITAL LETTER S WITH CARON
+0x8B	0x2039	#SINGLE LEFT-POINTING ANGLE QUOTATION MARK
+0x8C	0x0152	#LATIN CAPITAL LIGATURE OE
+0x8D	      	#UNDEFINED
+0x8E	0x017D	#LATIN CAPITAL LETTER Z WITH CARON
+0x8F	      	#UNDEFINED
+0x90	      	#UNDEFINED
+0x91	0x2018	#LEFT SINGLE QUOTATION MARK
+0x92	0x2019	#RIGHT SINGLE QUOTATION MARK
+0x93	0x201C	#LEFT DOUBLE QUOTATION MARK
+0x94	0x201D	#RIGHT DOUBLE QUOTATION MARK
+0x95	0x2022	#BULLET
+0x96	0x2013	#EN DASH
+0x97	0x2014	#EM DASH
+0x98	0x02DC	#SMALL TILDE
+0x99	0x2122	#TRADE MARK SIGN
+0x9A	0x0161	#LATIN SMALL LETTER S WITH CARON
+0x9B	0x203A	#SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
+0x9C	0x0153	#LATIN SMALL LIGATURE OE
+0x9D	      	#UNDEFINED
+0x9E	0x017E	#LATIN SMALL LETTER Z WITH CARON
+0x9F	0x0178	#LATIN CAPITAL LETTER Y WITH DIAERESIS
+0xA0	0x00A0	#NO-BREAK SPACE
+0xA1	0x00A1	#INVERTED EXCLAMATION MARK
+0xA2	0x00A2	#CENT SIGN
+0xA3	0x00A3	#POUND SIGN
+0xA4	0x00A4	#CURRENCY SIGN
+0xA5	0x00A5	#YEN SIGN
+0xA6	0x00A6	#BROKEN BAR
+0xA7	0x00A7	#SECTION SIGN
+0xA8	0x00A8	#DIAERESIS
+0xA9	0x00A9	#COPYRIGHT SIGN
+0xAA	0x00AA	#FEMININE ORDINAL INDICATOR
+0xAB	0x00AB	#LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+0xAC	0x00AC	#NOT SIGN
+0xAD	0x00AD	#SOFT HYPHEN
+0xAE	0x00AE	#REGISTERED SIGN
+0xAF	0x00AF	#MACRON
+0xB0	0x00B0	#DEGREE SIGN
+0xB1	0x00B1	#PLUS-MINUS SIGN
+0xB2	0x00B2	#SUPERSCRIPT TWO
+0xB3	0x00B3	#SUPERSCRIPT THREE
+0xB4	0x00B4	#ACUTE ACCENT
+0xB5	0x00B5	#MICRO SIGN
+0xB6	0x00B6	#PILCROW SIGN
+0xB7	0x00B7	#MIDDLE DOT
+0xB8	0x00B8	#CEDILLA
+0xB9	0x00B9	#SUPERSCRIPT ONE
+0xBA	0x00BA	#MASCULINE ORDINAL INDICATOR
+0xBB	0x00BB	#RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+0xBC	0x00BC	#VULGAR FRACTION ONE QUARTER
+0xBD	0x00BD	#VULGAR FRACTION ONE HALF
+0xBE	0x00BE	#VULGAR FRACTION THREE QUARTERS
+0xBF	0x00BF	#INVERTED QUESTION MARK
+0xC0	0x00C0	#LATIN CAPITAL LETTER A WITH GRAVE
+0xC1	0x00C1	#LATIN CAPITAL LETTER A WITH ACUTE
+0xC2	0x00C2	#LATIN CAPITAL LETTER A WITH CIRCUMFLEX
+0xC3	0x00C3	#LATIN CAPITAL LETTER A WITH TILDE
+0xC4	0x00C4	#LATIN CAPITAL LETTER A WITH DIAERESIS
+0xC5	0x00C5	#LATIN CAPITAL LETTER A WITH RING ABOVE
+0xC6	0x00C6	#LATIN CAPITAL LETTER AE
+0xC7	0x00C7	#LATIN CAPITAL LETTER C WITH CEDILLA
+0xC8	0x00C8	#LATIN CAPITAL LETTER E WITH GRAVE
+0xC9	0x00C9	#LATIN CAPITAL LETTER E WITH ACUTE
+0xCA	0x00CA	#LATIN CAPITAL LETTER E WITH CIRCUMFLEX
+0xCB	0x00CB	#LATIN CAPITAL LETTER E WITH DIAERESIS
+0xCC	0x00CC	#LATIN CAPITAL LETTER I WITH GRAVE
+0xCD	0x00CD	#LATIN CAPITAL LETTER I WITH ACUTE
+0xCE	0x00CE	#LATIN CAPITAL LETTER I WITH CIRCUMFLEX
+0xCF	0x00CF	#LATIN CAPITAL LETTER I WITH DIAERESIS
+0xD0	0x00D0	#LATIN CAPITAL LETTER ETH
+0xD1	0x00D1	#LATIN CAPITAL LETTER N WITH TILDE
+0xD2	0x00D2	#LATIN CAPITAL LETTER O WITH GRAVE
+0xD3	0x00D3	#LATIN CAPITAL LETTER O WITH ACUTE
+0xD4	0x00D4	#LATIN CAPITAL LETTER O WITH CIRCUMFLEX
+0xD5	0x00D5	#LATIN CAPITAL LETTER O WITH TILDE
+0xD6	0x00D6	#LATIN CAPITAL LETTER O WITH DIAERESIS
+0xD7	0x00D7	#MULTIPLICATION SIGN
+0xD8	0x00D8	#LATIN CAPITAL LETTER O WITH STROKE
+0xD9	0x00D9	#LATIN CAPITAL LETTER U WITH GRAVE
+0xDA	0x00DA	#LATIN CAPITAL LETTER U WITH ACUTE
+0xDB	0x00DB	#LATIN CAPITAL LETTER U WITH CIRCUMFLEX
+0xDC	0x00DC	#LATIN CAPITAL LETTER U WITH DIAERESIS
+0xDD	0x00DD	#LATIN CAPITAL LETTER Y WITH ACUTE
+0xDE	0x00DE	#LATIN CAPITAL LETTER THORN
+0xDF	0x00DF	#LATIN SMALL LETTER SHARP S
+0xE0	0x00E0	#LATIN SMALL LETTER A WITH GRAVE
+0xE1	0x00E1	#LATIN SMALL LETTER A WITH ACUTE
+0xE2	0x00E2	#LATIN SMALL LETTER A WITH CIRCUMFLEX
+0xE3	0x00E3	#LATIN SMALL LETTER A WITH TILDE
+0xE4	0x00E4	#LATIN SMALL LETTER A WITH DIAERESIS
+0xE5	0x00E5	#LATIN SMALL LETTER A WITH RING ABOVE
+0xE6	0x00E6	#LATIN SMALL LETTER AE
+0xE7	0x00E7	#LATIN SMALL LETTER C WITH CEDILLA
+0xE8	0x00E8	#LATIN SMALL LETTER E WITH GRAVE
+0xE9	0x00E9	#LATIN SMALL LETTER E WITH ACUTE
+0xEA	0x00EA	#LATIN SMALL LETTER E WITH CIRCUMFLEX
+0xEB	0x00EB	#LATIN SMALL LETTER E WITH DIAERESIS
+0xEC	0x00EC	#LATIN SMALL LETTER I WITH GRAVE
+0xED	0x00ED	#LATIN SMALL LETTER I WITH ACUTE
+0xEE	0x00EE	#LATIN SMALL LETTER I WITH CIRCUMFLEX
+0xEF	0x00EF	#LATIN SMALL LETTER I WITH DIAERESIS
+0xF0	0x00F0	#LATIN SMALL LETTER ETH
+0xF1	0x00F1	#LATIN SMALL LETTER N WITH TILDE
+0xF2	0x00F2	#LATIN SMALL LETTER O WITH GRAVE
+0xF3	0x00F3	#LATIN SMALL LETTER O WITH ACUTE
+0xF4	0x00F4	#LATIN SMALL LETTER O WITH CIRCUMFLEX
+0xF5	0x00F5	#LATIN SMALL LETTER O WITH TILDE
+0xF6	0x00F6	#LATIN SMALL LETTER O WITH DIAERESIS
+0xF7	0x00F7	#DIVISION SIGN
+0xF8	0x00F8	#LATIN SMALL LETTER O WITH STROKE
+0xF9	0x00F9	#LATIN SMALL LETTER U WITH GRAVE
+0xFA	0x00FA	#LATIN SMALL LETTER U WITH ACUTE
+0xFB	0x00FB	#LATIN SMALL LETTER U WITH CIRCUMFLEX
+0xFC	0x00FC	#LATIN SMALL LETTER U WITH DIAERESIS
+0xFD	0x00FD	#LATIN SMALL LETTER Y WITH ACUTE
+0xFE	0x00FE	#LATIN SMALL LETTER THORN
+0xFF	0x00FF	#LATIN SMALL LETTER Y WITH DIAERESIS
diff --git a/tools/encoding/cp1253.txt b/tools/encoding/cp1253.txt
new file mode 100644
index 0000000..2ba51a0
--- /dev/null
+++ b/tools/encoding/cp1253.txt
@@ -0,0 +1,274 @@
+#
+#    Name:     cp1253 to Unicode table
+#    Unicode version: 2.0
+#    Table version: 2.01
+#    Table format:  Format A
+#    Date:          04/15/98
+#
+#    Contact:       cpxlate@microsoft.com
+#
+#    General notes: none
+#
+#    Format: Three tab-separated columns
+#        Column #1 is the cp1253 code (in hex)
+#        Column #2 is the Unicode (in hex as 0xXXXX)
+#        Column #3 is the Unicode name (follows a comment sign, '#')
+#
+#    The entries are in cp1253 order
+#
+0x00	0x0000	#NULL
+0x01	0x0001	#START OF HEADING
+0x02	0x0002	#START OF TEXT
+0x03	0x0003	#END OF TEXT
+0x04	0x0004	#END OF TRANSMISSION
+0x05	0x0005	#ENQUIRY
+0x06	0x0006	#ACKNOWLEDGE
+0x07	0x0007	#BELL
+0x08	0x0008	#BACKSPACE
+0x09	0x0009	#HORIZONTAL TABULATION
+0x0A	0x000A	#LINE FEED
+0x0B	0x000B	#VERTICAL TABULATION
+0x0C	0x000C	#FORM FEED
+0x0D	0x000D	#CARRIAGE RETURN
+0x0E	0x000E	#SHIFT OUT
+0x0F	0x000F	#SHIFT IN
+0x10	0x0010	#DATA LINK ESCAPE
+0x11	0x0011	#DEVICE CONTROL ONE
+0x12	0x0012	#DEVICE CONTROL TWO
+0x13	0x0013	#DEVICE CONTROL THREE
+0x14	0x0014	#DEVICE CONTROL FOUR
+0x15	0x0015	#NEGATIVE ACKNOWLEDGE
+0x16	0x0016	#SYNCHRONOUS IDLE
+0x17	0x0017	#END OF TRANSMISSION BLOCK
+0x18	0x0018	#CANCEL
+0x19	0x0019	#END OF MEDIUM
+0x1A	0x001A	#SUBSTITUTE
+0x1B	0x001B	#ESCAPE
+0x1C	0x001C	#FILE SEPARATOR
+0x1D	0x001D	#GROUP SEPARATOR
+0x1E	0x001E	#RECORD SEPARATOR
+0x1F	0x001F	#UNIT SEPARATOR
+0x20	0x0020	#SPACE
+0x21	0x0021	#EXCLAMATION MARK
+0x22	0x0022	#QUOTATION MARK
+0x23	0x0023	#NUMBER SIGN
+0x24	0x0024	#DOLLAR SIGN
+0x25	0x0025	#PERCENT SIGN
+0x26	0x0026	#AMPERSAND
+0x27	0x0027	#APOSTROPHE
+0x28	0x0028	#LEFT PARENTHESIS
+0x29	0x0029	#RIGHT PARENTHESIS
+0x2A	0x002A	#ASTERISK
+0x2B	0x002B	#PLUS SIGN
+0x2C	0x002C	#COMMA
+0x2D	0x002D	#HYPHEN-MINUS
+0x2E	0x002E	#FULL STOP
+0x2F	0x002F	#SOLIDUS
+0x30	0x0030	#DIGIT ZERO
+0x31	0x0031	#DIGIT ONE
+0x32	0x0032	#DIGIT TWO
+0x33	0x0033	#DIGIT THREE
+0x34	0x0034	#DIGIT FOUR
+0x35	0x0035	#DIGIT FIVE
+0x36	0x0036	#DIGIT SIX
+0x37	0x0037	#DIGIT SEVEN
+0x38	0x0038	#DIGIT EIGHT
+0x39	0x0039	#DIGIT NINE
+0x3A	0x003A	#COLON
+0x3B	0x003B	#SEMICOLON
+0x3C	0x003C	#LESS-THAN SIGN
+0x3D	0x003D	#EQUALS SIGN
+0x3E	0x003E	#GREATER-THAN SIGN
+0x3F	0x003F	#QUESTION MARK
+0x40	0x0040	#COMMERCIAL AT
+0x41	0x0041	#LATIN CAPITAL LETTER A
+0x42	0x0042	#LATIN CAPITAL LETTER B
+0x43	0x0043	#LATIN CAPITAL LETTER C
+0x44	0x0044	#LATIN CAPITAL LETTER D
+0x45	0x0045	#LATIN CAPITAL LETTER E
+0x46	0x0046	#LATIN CAPITAL LETTER F
+0x47	0x0047	#LATIN CAPITAL LETTER G
+0x48	0x0048	#LATIN CAPITAL LETTER H
+0x49	0x0049	#LATIN CAPITAL LETTER I
+0x4A	0x004A	#LATIN CAPITAL LETTER J
+0x4B	0x004B	#LATIN CAPITAL LETTER K
+0x4C	0x004C	#LATIN CAPITAL LETTER L
+0x4D	0x004D	#LATIN CAPITAL LETTER M
+0x4E	0x004E	#LATIN CAPITAL LETTER N
+0x4F	0x004F	#LATIN CAPITAL LETTER O
+0x50	0x0050	#LATIN CAPITAL LETTER P
+0x51	0x0051	#LATIN CAPITAL LETTER Q
+0x52	0x0052	#LATIN CAPITAL LETTER R
+0x53	0x0053	#LATIN CAPITAL LETTER S
+0x54	0x0054	#LATIN CAPITAL LETTER T
+0x55	0x0055	#LATIN CAPITAL LETTER U
+0x56	0x0056	#LATIN CAPITAL LETTER V
+0x57	0x0057	#LATIN CAPITAL LETTER W
+0x58	0x0058	#LATIN CAPITAL LETTER X
+0x59	0x0059	#LATIN CAPITAL LETTER Y
+0x5A	0x005A	#LATIN CAPITAL LETTER Z
+0x5B	0x005B	#LEFT SQUARE BRACKET
+0x5C	0x005C	#REVERSE SOLIDUS
+0x5D	0x005D	#RIGHT SQUARE BRACKET
+0x5E	0x005E	#CIRCUMFLEX ACCENT
+0x5F	0x005F	#LOW LINE
+0x60	0x0060	#GRAVE ACCENT
+0x61	0x0061	#LATIN SMALL LETTER A
+0x62	0x0062	#LATIN SMALL LETTER B
+0x63	0x0063	#LATIN SMALL LETTER C
+0x64	0x0064	#LATIN SMALL LETTER D
+0x65	0x0065	#LATIN SMALL LETTER E
+0x66	0x0066	#LATIN SMALL LETTER F
+0x67	0x0067	#LATIN SMALL LETTER G
+0x68	0x0068	#LATIN SMALL LETTER H
+0x69	0x0069	#LATIN SMALL LETTER I
+0x6A	0x006A	#LATIN SMALL LETTER J
+0x6B	0x006B	#LATIN SMALL LETTER K
+0x6C	0x006C	#LATIN SMALL LETTER L
+0x6D	0x006D	#LATIN SMALL LETTER M
+0x6E	0x006E	#LATIN SMALL LETTER N
+0x6F	0x006F	#LATIN SMALL LETTER O
+0x70	0x0070	#LATIN SMALL LETTER P
+0x71	0x0071	#LATIN SMALL LETTER Q
+0x72	0x0072	#LATIN SMALL LETTER R
+0x73	0x0073	#LATIN SMALL LETTER S
+0x74	0x0074	#LATIN SMALL LETTER T
+0x75	0x0075	#LATIN SMALL LETTER U
+0x76	0x0076	#LATIN SMALL LETTER V
+0x77	0x0077	#LATIN SMALL LETTER W
+0x78	0x0078	#LATIN SMALL LETTER X
+0x79	0x0079	#LATIN SMALL LETTER Y
+0x7A	0x007A	#LATIN SMALL LETTER Z
+0x7B	0x007B	#LEFT CURLY BRACKET
+0x7C	0x007C	#VERTICAL LINE
+0x7D	0x007D	#RIGHT CURLY BRACKET
+0x7E	0x007E	#TILDE
+0x7F	0x007F	#DELETE
+0x80	0x20AC	#EURO SIGN
+0x81	      	#UNDEFINED
+0x82	0x201A	#SINGLE LOW-9 QUOTATION MARK
+0x83	0x0192	#LATIN SMALL LETTER F WITH HOOK
+0x84	0x201E	#DOUBLE LOW-9 QUOTATION MARK
+0x85	0x2026	#HORIZONTAL ELLIPSIS
+0x86	0x2020	#DAGGER
+0x87	0x2021	#DOUBLE DAGGER
+0x88	      	#UNDEFINED
+0x89	0x2030	#PER MILLE SIGN
+0x8A	      	#UNDEFINED
+0x8B	0x2039	#SINGLE LEFT-POINTING ANGLE QUOTATION MARK
+0x8C	      	#UNDEFINED
+0x8D	      	#UNDEFINED
+0x8E	      	#UNDEFINED
+0x8F	      	#UNDEFINED
+0x90	      	#UNDEFINED
+0x91	0x2018	#LEFT SINGLE QUOTATION MARK
+0x92	0x2019	#RIGHT SINGLE QUOTATION MARK
+0x93	0x201C	#LEFT DOUBLE QUOTATION MARK
+0x94	0x201D	#RIGHT DOUBLE QUOTATION MARK
+0x95	0x2022	#BULLET
+0x96	0x2013	#EN DASH
+0x97	0x2014	#EM DASH
+0x98	      	#UNDEFINED
+0x99	0x2122	#TRADE MARK SIGN
+0x9A	      	#UNDEFINED
+0x9B	0x203A	#SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
+0x9C	      	#UNDEFINED
+0x9D	      	#UNDEFINED
+0x9E	      	#UNDEFINED
+0x9F	      	#UNDEFINED
+0xA0	0x00A0	#NO-BREAK SPACE
+0xA1	0x0385	#GREEK DIALYTIKA TONOS
+0xA2	0x0386	#GREEK CAPITAL LETTER ALPHA WITH TONOS
+0xA3	0x00A3	#POUND SIGN
+0xA4	0x00A4	#CURRENCY SIGN
+0xA5	0x00A5	#YEN SIGN
+0xA6	0x00A6	#BROKEN BAR
+0xA7	0x00A7	#SECTION SIGN
+0xA8	0x00A8	#DIAERESIS
+0xA9	0x00A9	#COPYRIGHT SIGN
+0xAA	      	#UNDEFINED
+0xAB	0x00AB	#LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+0xAC	0x00AC	#NOT SIGN
+0xAD	0x00AD	#SOFT HYPHEN
+0xAE	0x00AE	#REGISTERED SIGN
+0xAF	0x2015	#HORIZONTAL BAR
+0xB0	0x00B0	#DEGREE SIGN
+0xB1	0x00B1	#PLUS-MINUS SIGN
+0xB2	0x00B2	#SUPERSCRIPT TWO
+0xB3	0x00B3	#SUPERSCRIPT THREE
+0xB4	0x0384	#GREEK TONOS
+0xB5	0x00B5	#MICRO SIGN
+0xB6	0x00B6	#PILCROW SIGN
+0xB7	0x00B7	#MIDDLE DOT
+0xB8	0x0388	#GREEK CAPITAL LETTER EPSILON WITH TONOS
+0xB9	0x0389	#GREEK CAPITAL LETTER ETA WITH TONOS
+0xBA	0x038A	#GREEK CAPITAL LETTER IOTA WITH TONOS
+0xBB	0x00BB	#RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+0xBC	0x038C	#GREEK CAPITAL LETTER OMICRON WITH TONOS
+0xBD	0x00BD	#VULGAR FRACTION ONE HALF
+0xBE	0x038E	#GREEK CAPITAL LETTER UPSILON WITH TONOS
+0xBF	0x038F	#GREEK CAPITAL LETTER OMEGA WITH TONOS
+0xC0	0x0390	#GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS
+0xC1	0x0391	#GREEK CAPITAL LETTER ALPHA
+0xC2	0x0392	#GREEK CAPITAL LETTER BETA
+0xC3	0x0393	#GREEK CAPITAL LETTER GAMMA
+0xC4	0x0394	#GREEK CAPITAL LETTER DELTA
+0xC5	0x0395	#GREEK CAPITAL LETTER EPSILON
+0xC6	0x0396	#GREEK CAPITAL LETTER ZETA
+0xC7	0x0397	#GREEK CAPITAL LETTER ETA
+0xC8	0x0398	#GREEK CAPITAL LETTER THETA
+0xC9	0x0399	#GREEK CAPITAL LETTER IOTA
+0xCA	0x039A	#GREEK CAPITAL LETTER KAPPA
+0xCB	0x039B	#GREEK CAPITAL LETTER LAMDA
+0xCC	0x039C	#GREEK CAPITAL LETTER MU
+0xCD	0x039D	#GREEK CAPITAL LETTER NU
+0xCE	0x039E	#GREEK CAPITAL LETTER XI
+0xCF	0x039F	#GREEK CAPITAL LETTER OMICRON
+0xD0	0x03A0	#GREEK CAPITAL LETTER PI
+0xD1	0x03A1	#GREEK CAPITAL LETTER RHO
+0xD2	      	#UNDEFINED
+0xD3	0x03A3	#GREEK CAPITAL LETTER SIGMA
+0xD4	0x03A4	#GREEK CAPITAL LETTER TAU
+0xD5	0x03A5	#GREEK CAPITAL LETTER UPSILON
+0xD6	0x03A6	#GREEK CAPITAL LETTER PHI
+0xD7	0x03A7	#GREEK CAPITAL LETTER CHI
+0xD8	0x03A8	#GREEK CAPITAL LETTER PSI
+0xD9	0x03A9	#GREEK CAPITAL LETTER OMEGA
+0xDA	0x03AA	#GREEK CAPITAL LETTER IOTA WITH DIALYTIKA
+0xDB	0x03AB	#GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA
+0xDC	0x03AC	#GREEK SMALL LETTER ALPHA WITH TONOS
+0xDD	0x03AD	#GREEK SMALL LETTER EPSILON WITH TONOS
+0xDE	0x03AE	#GREEK SMALL LETTER ETA WITH TONOS
+0xDF	0x03AF	#GREEK SMALL LETTER IOTA WITH TONOS
+0xE0	0x03B0	#GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS
+0xE1	0x03B1	#GREEK SMALL LETTER ALPHA
+0xE2	0x03B2	#GREEK SMALL LETTER BETA
+0xE3	0x03B3	#GREEK SMALL LETTER GAMMA
+0xE4	0x03B4	#GREEK SMALL LETTER DELTA
+0xE5	0x03B5	#GREEK SMALL LETTER EPSILON
+0xE6	0x03B6	#GREEK SMALL LETTER ZETA
+0xE7	0x03B7	#GREEK SMALL LETTER ETA
+0xE8	0x03B8	#GREEK SMALL LETTER THETA
+0xE9	0x03B9	#GREEK SMALL LETTER IOTA
+0xEA	0x03BA	#GREEK SMALL LETTER KAPPA
+0xEB	0x03BB	#GREEK SMALL LETTER LAMDA
+0xEC	0x03BC	#GREEK SMALL LETTER MU
+0xED	0x03BD	#GREEK SMALL LETTER NU
+0xEE	0x03BE	#GREEK SMALL LETTER XI
+0xEF	0x03BF	#GREEK SMALL LETTER OMICRON
+0xF0	0x03C0	#GREEK SMALL LETTER PI
+0xF1	0x03C1	#GREEK SMALL LETTER RHO
+0xF2	0x03C2	#GREEK SMALL LETTER FINAL SIGMA
+0xF3	0x03C3	#GREEK SMALL LETTER SIGMA
+0xF4	0x03C4	#GREEK SMALL LETTER TAU
+0xF5	0x03C5	#GREEK SMALL LETTER UPSILON
+0xF6	0x03C6	#GREEK SMALL LETTER PHI
+0xF7	0x03C7	#GREEK SMALL LETTER CHI
+0xF8	0x03C8	#GREEK SMALL LETTER PSI
+0xF9	0x03C9	#GREEK SMALL LETTER OMEGA
+0xFA	0x03CA	#GREEK SMALL LETTER IOTA WITH DIALYTIKA
+0xFB	0x03CB	#GREEK SMALL LETTER UPSILON WITH DIALYTIKA
+0xFC	0x03CC	#GREEK SMALL LETTER OMICRON WITH TONOS
+0xFD	0x03CD	#GREEK SMALL LETTER UPSILON WITH TONOS
+0xFE	0x03CE	#GREEK SMALL LETTER OMEGA WITH TONOS
+0xFF	      	#UNDEFINED
diff --git a/tools/encoding/cp1254.txt b/tools/encoding/cp1254.txt
new file mode 100644
index 0000000..ca1a1eb
--- /dev/null
+++ b/tools/encoding/cp1254.txt
@@ -0,0 +1,274 @@
+#
+#    Name:     cp1254 to Unicode table
+#    Unicode version: 2.0
+#    Table version: 2.01
+#    Table format:  Format A
+#    Date:          04/15/98
+#
+#    Contact:       cpxlate@microsoft.com
+#
+#    General notes: none
+#
+#    Format: Three tab-separated columns
+#        Column #1 is the cp1254 code (in hex)
+#        Column #2 is the Unicode (in hex as 0xXXXX)
+#        Column #3 is the Unicode name (follows a comment sign, '#')
+#
+#    The entries are in cp1254 order
+#
+0x00	0x0000	#NULL
+0x01	0x0001	#START OF HEADING
+0x02	0x0002	#START OF TEXT
+0x03	0x0003	#END OF TEXT
+0x04	0x0004	#END OF TRANSMISSION
+0x05	0x0005	#ENQUIRY
+0x06	0x0006	#ACKNOWLEDGE
+0x07	0x0007	#BELL
+0x08	0x0008	#BACKSPACE
+0x09	0x0009	#HORIZONTAL TABULATION
+0x0A	0x000A	#LINE FEED
+0x0B	0x000B	#VERTICAL TABULATION
+0x0C	0x000C	#FORM FEED
+0x0D	0x000D	#CARRIAGE RETURN
+0x0E	0x000E	#SHIFT OUT
+0x0F	0x000F	#SHIFT IN
+0x10	0x0010	#DATA LINK ESCAPE
+0x11	0x0011	#DEVICE CONTROL ONE
+0x12	0x0012	#DEVICE CONTROL TWO
+0x13	0x0013	#DEVICE CONTROL THREE
+0x14	0x0014	#DEVICE CONTROL FOUR
+0x15	0x0015	#NEGATIVE ACKNOWLEDGE
+0x16	0x0016	#SYNCHRONOUS IDLE
+0x17	0x0017	#END OF TRANSMISSION BLOCK
+0x18	0x0018	#CANCEL
+0x19	0x0019	#END OF MEDIUM
+0x1A	0x001A	#SUBSTITUTE
+0x1B	0x001B	#ESCAPE
+0x1C	0x001C	#FILE SEPARATOR
+0x1D	0x001D	#GROUP SEPARATOR
+0x1E	0x001E	#RECORD SEPARATOR
+0x1F	0x001F	#UNIT SEPARATOR
+0x20	0x0020	#SPACE
+0x21	0x0021	#EXCLAMATION MARK
+0x22	0x0022	#QUOTATION MARK
+0x23	0x0023	#NUMBER SIGN
+0x24	0x0024	#DOLLAR SIGN
+0x25	0x0025	#PERCENT SIGN
+0x26	0x0026	#AMPERSAND
+0x27	0x0027	#APOSTROPHE
+0x28	0x0028	#LEFT PARENTHESIS
+0x29	0x0029	#RIGHT PARENTHESIS
+0x2A	0x002A	#ASTERISK
+0x2B	0x002B	#PLUS SIGN
+0x2C	0x002C	#COMMA
+0x2D	0x002D	#HYPHEN-MINUS
+0x2E	0x002E	#FULL STOP
+0x2F	0x002F	#SOLIDUS
+0x30	0x0030	#DIGIT ZERO
+0x31	0x0031	#DIGIT ONE
+0x32	0x0032	#DIGIT TWO
+0x33	0x0033	#DIGIT THREE
+0x34	0x0034	#DIGIT FOUR
+0x35	0x0035	#DIGIT FIVE
+0x36	0x0036	#DIGIT SIX
+0x37	0x0037	#DIGIT SEVEN
+0x38	0x0038	#DIGIT EIGHT
+0x39	0x0039	#DIGIT NINE
+0x3A	0x003A	#COLON
+0x3B	0x003B	#SEMICOLON
+0x3C	0x003C	#LESS-THAN SIGN
+0x3D	0x003D	#EQUALS SIGN
+0x3E	0x003E	#GREATER-THAN SIGN
+0x3F	0x003F	#QUESTION MARK
+0x40	0x0040	#COMMERCIAL AT
+0x41	0x0041	#LATIN CAPITAL LETTER A
+0x42	0x0042	#LATIN CAPITAL LETTER B
+0x43	0x0043	#LATIN CAPITAL LETTER C
+0x44	0x0044	#LATIN CAPITAL LETTER D
+0x45	0x0045	#LATIN CAPITAL LETTER E
+0x46	0x0046	#LATIN CAPITAL LETTER F
+0x47	0x0047	#LATIN CAPITAL LETTER G
+0x48	0x0048	#LATIN CAPITAL LETTER H
+0x49	0x0049	#LATIN CAPITAL LETTER I
+0x4A	0x004A	#LATIN CAPITAL LETTER J
+0x4B	0x004B	#LATIN CAPITAL LETTER K
+0x4C	0x004C	#LATIN CAPITAL LETTER L
+0x4D	0x004D	#LATIN CAPITAL LETTER M
+0x4E	0x004E	#LATIN CAPITAL LETTER N
+0x4F	0x004F	#LATIN CAPITAL LETTER O
+0x50	0x0050	#LATIN CAPITAL LETTER P
+0x51	0x0051	#LATIN CAPITAL LETTER Q
+0x52	0x0052	#LATIN CAPITAL LETTER R
+0x53	0x0053	#LATIN CAPITAL LETTER S
+0x54	0x0054	#LATIN CAPITAL LETTER T
+0x55	0x0055	#LATIN CAPITAL LETTER U
+0x56	0x0056	#LATIN CAPITAL LETTER V
+0x57	0x0057	#LATIN CAPITAL LETTER W
+0x58	0x0058	#LATIN CAPITAL LETTER X
+0x59	0x0059	#LATIN CAPITAL LETTER Y
+0x5A	0x005A	#LATIN CAPITAL LETTER Z
+0x5B	0x005B	#LEFT SQUARE BRACKET
+0x5C	0x005C	#REVERSE SOLIDUS
+0x5D	0x005D	#RIGHT SQUARE BRACKET
+0x5E	0x005E	#CIRCUMFLEX ACCENT
+0x5F	0x005F	#LOW LINE
+0x60	0x0060	#GRAVE ACCENT
+0x61	0x0061	#LATIN SMALL LETTER A
+0x62	0x0062	#LATIN SMALL LETTER B
+0x63	0x0063	#LATIN SMALL LETTER C
+0x64	0x0064	#LATIN SMALL LETTER D
+0x65	0x0065	#LATIN SMALL LETTER E
+0x66	0x0066	#LATIN SMALL LETTER F
+0x67	0x0067	#LATIN SMALL LETTER G
+0x68	0x0068	#LATIN SMALL LETTER H
+0x69	0x0069	#LATIN SMALL LETTER I
+0x6A	0x006A	#LATIN SMALL LETTER J
+0x6B	0x006B	#LATIN SMALL LETTER K
+0x6C	0x006C	#LATIN SMALL LETTER L
+0x6D	0x006D	#LATIN SMALL LETTER M
+0x6E	0x006E	#LATIN SMALL LETTER N
+0x6F	0x006F	#LATIN SMALL LETTER O
+0x70	0x0070	#LATIN SMALL LETTER P
+0x71	0x0071	#LATIN SMALL LETTER Q
+0x72	0x0072	#LATIN SMALL LETTER R
+0x73	0x0073	#LATIN SMALL LETTER S
+0x74	0x0074	#LATIN SMALL LETTER T
+0x75	0x0075	#LATIN SMALL LETTER U
+0x76	0x0076	#LATIN SMALL LETTER V
+0x77	0x0077	#LATIN SMALL LETTER W
+0x78	0x0078	#LATIN SMALL LETTER X
+0x79	0x0079	#LATIN SMALL LETTER Y
+0x7A	0x007A	#LATIN SMALL LETTER Z
+0x7B	0x007B	#LEFT CURLY BRACKET
+0x7C	0x007C	#VERTICAL LINE
+0x7D	0x007D	#RIGHT CURLY BRACKET
+0x7E	0x007E	#TILDE
+0x7F	0x007F	#DELETE
+0x80	0x20AC	#EURO SIGN
+0x81	      	#UNDEFINED
+0x82	0x201A	#SINGLE LOW-9 QUOTATION MARK
+0x83	0x0192	#LATIN SMALL LETTER F WITH HOOK
+0x84	0x201E	#DOUBLE LOW-9 QUOTATION MARK
+0x85	0x2026	#HORIZONTAL ELLIPSIS
+0x86	0x2020	#DAGGER
+0x87	0x2021	#DOUBLE DAGGER
+0x88	0x02C6	#MODIFIER LETTER CIRCUMFLEX ACCENT
+0x89	0x2030	#PER MILLE SIGN
+0x8A	0x0160	#LATIN CAPITAL LETTER S WITH CARON
+0x8B	0x2039	#SINGLE LEFT-POINTING ANGLE QUOTATION MARK
+0x8C	0x0152	#LATIN CAPITAL LIGATURE OE
+0x8D	      	#UNDEFINED
+0x8E	      	#UNDEFINED
+0x8F	      	#UNDEFINED
+0x90	      	#UNDEFINED
+0x91	0x2018	#LEFT SINGLE QUOTATION MARK
+0x92	0x2019	#RIGHT SINGLE QUOTATION MARK
+0x93	0x201C	#LEFT DOUBLE QUOTATION MARK
+0x94	0x201D	#RIGHT DOUBLE QUOTATION MARK
+0x95	0x2022	#BULLET
+0x96	0x2013	#EN DASH
+0x97	0x2014	#EM DASH
+0x98	0x02DC	#SMALL TILDE
+0x99	0x2122	#TRADE MARK SIGN
+0x9A	0x0161	#LATIN SMALL LETTER S WITH CARON
+0x9B	0x203A	#SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
+0x9C	0x0153	#LATIN SMALL LIGATURE OE
+0x9D	      	#UNDEFINED
+0x9E	      	#UNDEFINED
+0x9F	0x0178	#LATIN CAPITAL LETTER Y WITH DIAERESIS
+0xA0	0x00A0	#NO-BREAK SPACE
+0xA1	0x00A1	#INVERTED EXCLAMATION MARK
+0xA2	0x00A2	#CENT SIGN
+0xA3	0x00A3	#POUND SIGN
+0xA4	0x00A4	#CURRENCY SIGN
+0xA5	0x00A5	#YEN SIGN
+0xA6	0x00A6	#BROKEN BAR
+0xA7	0x00A7	#SECTION SIGN
+0xA8	0x00A8	#DIAERESIS
+0xA9	0x00A9	#COPYRIGHT SIGN
+0xAA	0x00AA	#FEMININE ORDINAL INDICATOR
+0xAB	0x00AB	#LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+0xAC	0x00AC	#NOT SIGN
+0xAD	0x00AD	#SOFT HYPHEN
+0xAE	0x00AE	#REGISTERED SIGN
+0xAF	0x00AF	#MACRON
+0xB0	0x00B0	#DEGREE SIGN
+0xB1	0x00B1	#PLUS-MINUS SIGN
+0xB2	0x00B2	#SUPERSCRIPT TWO
+0xB3	0x00B3	#SUPERSCRIPT THREE
+0xB4	0x00B4	#ACUTE ACCENT
+0xB5	0x00B5	#MICRO SIGN
+0xB6	0x00B6	#PILCROW SIGN
+0xB7	0x00B7	#MIDDLE DOT
+0xB8	0x00B8	#CEDILLA
+0xB9	0x00B9	#SUPERSCRIPT ONE
+0xBA	0x00BA	#MASCULINE ORDINAL INDICATOR
+0xBB	0x00BB	#RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+0xBC	0x00BC	#VULGAR FRACTION ONE QUARTER
+0xBD	0x00BD	#VULGAR FRACTION ONE HALF
+0xBE	0x00BE	#VULGAR FRACTION THREE QUARTERS
+0xBF	0x00BF	#INVERTED QUESTION MARK
+0xC0	0x00C0	#LATIN CAPITAL LETTER A WITH GRAVE
+0xC1	0x00C1	#LATIN CAPITAL LETTER A WITH ACUTE
+0xC2	0x00C2	#LATIN CAPITAL LETTER A WITH CIRCUMFLEX
+0xC3	0x00C3	#LATIN CAPITAL LETTER A WITH TILDE
+0xC4	0x00C4	#LATIN CAPITAL LETTER A WITH DIAERESIS
+0xC5	0x00C5	#LATIN CAPITAL LETTER A WITH RING ABOVE
+0xC6	0x00C6	#LATIN CAPITAL LETTER AE
+0xC7	0x00C7	#LATIN CAPITAL LETTER C WITH CEDILLA
+0xC8	0x00C8	#LATIN CAPITAL LETTER E WITH GRAVE
+0xC9	0x00C9	#LATIN CAPITAL LETTER E WITH ACUTE
+0xCA	0x00CA	#LATIN CAPITAL LETTER E WITH CIRCUMFLEX
+0xCB	0x00CB	#LATIN CAPITAL LETTER E WITH DIAERESIS
+0xCC	0x00CC	#LATIN CAPITAL LETTER I WITH GRAVE
+0xCD	0x00CD	#LATIN CAPITAL LETTER I WITH ACUTE
+0xCE	0x00CE	#LATIN CAPITAL LETTER I WITH CIRCUMFLEX
+0xCF	0x00CF	#LATIN CAPITAL LETTER I WITH DIAERESIS
+0xD0	0x011E	#LATIN CAPITAL LETTER G WITH BREVE
+0xD1	0x00D1	#LATIN CAPITAL LETTER N WITH TILDE
+0xD2	0x00D2	#LATIN CAPITAL LETTER O WITH GRAVE
+0xD3	0x00D3	#LATIN CAPITAL LETTER O WITH ACUTE
+0xD4	0x00D4	#LATIN CAPITAL LETTER O WITH CIRCUMFLEX
+0xD5	0x00D5	#LATIN CAPITAL LETTER O WITH TILDE
+0xD6	0x00D6	#LATIN CAPITAL LETTER O WITH DIAERESIS
+0xD7	0x00D7	#MULTIPLICATION SIGN
+0xD8	0x00D8	#LATIN CAPITAL LETTER O WITH STROKE
+0xD9	0x00D9	#LATIN CAPITAL LETTER U WITH GRAVE
+0xDA	0x00DA	#LATIN CAPITAL LETTER U WITH ACUTE
+0xDB	0x00DB	#LATIN CAPITAL LETTER U WITH CIRCUMFLEX
+0xDC	0x00DC	#LATIN CAPITAL LETTER U WITH DIAERESIS
+0xDD	0x0130	#LATIN CAPITAL LETTER I WITH DOT ABOVE
+0xDE	0x015E	#LATIN CAPITAL LETTER S WITH CEDILLA
+0xDF	0x00DF	#LATIN SMALL LETTER SHARP S
+0xE0	0x00E0	#LATIN SMALL LETTER A WITH GRAVE
+0xE1	0x00E1	#LATIN SMALL LETTER A WITH ACUTE
+0xE2	0x00E2	#LATIN SMALL LETTER A WITH CIRCUMFLEX
+0xE3	0x00E3	#LATIN SMALL LETTER A WITH TILDE
+0xE4	0x00E4	#LATIN SMALL LETTER A WITH DIAERESIS
+0xE5	0x00E5	#LATIN SMALL LETTER A WITH RING ABOVE
+0xE6	0x00E6	#LATIN SMALL LETTER AE
+0xE7	0x00E7	#LATIN SMALL LETTER C WITH CEDILLA
+0xE8	0x00E8	#LATIN SMALL LETTER E WITH GRAVE
+0xE9	0x00E9	#LATIN SMALL LETTER E WITH ACUTE
+0xEA	0x00EA	#LATIN SMALL LETTER E WITH CIRCUMFLEX
+0xEB	0x00EB	#LATIN SMALL LETTER E WITH DIAERESIS
+0xEC	0x00EC	#LATIN SMALL LETTER I WITH GRAVE
+0xED	0x00ED	#LATIN SMALL LETTER I WITH ACUTE
+0xEE	0x00EE	#LATIN SMALL LETTER I WITH CIRCUMFLEX
+0xEF	0x00EF	#LATIN SMALL LETTER I WITH DIAERESIS
+0xF0	0x011F	#LATIN SMALL LETTER G WITH BREVE
+0xF1	0x00F1	#LATIN SMALL LETTER N WITH TILDE
+0xF2	0x00F2	#LATIN SMALL LETTER O WITH GRAVE
+0xF3	0x00F3	#LATIN SMALL LETTER O WITH ACUTE
+0xF4	0x00F4	#LATIN SMALL LETTER O WITH CIRCUMFLEX
+0xF5	0x00F5	#LATIN SMALL LETTER O WITH TILDE
+0xF6	0x00F6	#LATIN SMALL LETTER O WITH DIAERESIS
+0xF7	0x00F7	#DIVISION SIGN
+0xF8	0x00F8	#LATIN SMALL LETTER O WITH STROKE
+0xF9	0x00F9	#LATIN SMALL LETTER U WITH GRAVE
+0xFA	0x00FA	#LATIN SMALL LETTER U WITH ACUTE
+0xFB	0x00FB	#LATIN SMALL LETTER U WITH CIRCUMFLEX
+0xFC	0x00FC	#LATIN SMALL LETTER U WITH DIAERESIS
+0xFD	0x0131	#LATIN SMALL LETTER DOTLESS I
+0xFE	0x015F	#LATIN SMALL LETTER S WITH CEDILLA
+0xFF	0x00FF	#LATIN SMALL LETTER Y WITH DIAERESIS
diff --git a/tools/encoding/cp1255.txt b/tools/encoding/cp1255.txt
new file mode 100644
index 0000000..341517f
--- /dev/null
+++ b/tools/encoding/cp1255.txt
@@ -0,0 +1,274 @@
+#
+#    Name:     cp1255 to Unicode table
+#    Unicode version: 2.0
+#    Table version: 2.01
+#    Table format:  Format A
+#    Date:          1/7/2000
+#
+#    Contact:       cpxlate@microsoft.com
+#
+#    General notes: none
+#
+#    Format: Three tab-separated columns
+#        Column #1 is the cp1255 code (in hex)
+#        Column #2 is the Unicode (in hex as 0xXXXX)
+#        Column #3 is the Unicode name (follows a comment sign, '#')
+#
+#    The entries are in cp1255 order
+#
+0x00	0x0000	#NULL
+0x01	0x0001	#START OF HEADING
+0x02	0x0002	#START OF TEXT
+0x03	0x0003	#END OF TEXT
+0x04	0x0004	#END OF TRANSMISSION
+0x05	0x0005	#ENQUIRY
+0x06	0x0006	#ACKNOWLEDGE
+0x07	0x0007	#BELL
+0x08	0x0008	#BACKSPACE
+0x09	0x0009	#HORIZONTAL TABULATION
+0x0A	0x000A	#LINE FEED
+0x0B	0x000B	#VERTICAL TABULATION
+0x0C	0x000C	#FORM FEED
+0x0D	0x000D	#CARRIAGE RETURN
+0x0E	0x000E	#SHIFT OUT
+0x0F	0x000F	#SHIFT IN
+0x10	0x0010	#DATA LINK ESCAPE
+0x11	0x0011	#DEVICE CONTROL ONE
+0x12	0x0012	#DEVICE CONTROL TWO
+0x13	0x0013	#DEVICE CONTROL THREE
+0x14	0x0014	#DEVICE CONTROL FOUR
+0x15	0x0015	#NEGATIVE ACKNOWLEDGE
+0x16	0x0016	#SYNCHRONOUS IDLE
+0x17	0x0017	#END OF TRANSMISSION BLOCK
+0x18	0x0018	#CANCEL
+0x19	0x0019	#END OF MEDIUM
+0x1A	0x001A	#SUBSTITUTE
+0x1B	0x001B	#ESCAPE
+0x1C	0x001C	#FILE SEPARATOR
+0x1D	0x001D	#GROUP SEPARATOR
+0x1E	0x001E	#RECORD SEPARATOR
+0x1F	0x001F	#UNIT SEPARATOR
+0x20	0x0020	#SPACE
+0x21	0x0021	#EXCLAMATION MARK
+0x22	0x0022	#QUOTATION MARK
+0x23	0x0023	#NUMBER SIGN
+0x24	0x0024	#DOLLAR SIGN
+0x25	0x0025	#PERCENT SIGN
+0x26	0x0026	#AMPERSAND
+0x27	0x0027	#APOSTROPHE
+0x28	0x0028	#LEFT PARENTHESIS
+0x29	0x0029	#RIGHT PARENTHESIS
+0x2A	0x002A	#ASTERISK
+0x2B	0x002B	#PLUS SIGN
+0x2C	0x002C	#COMMA
+0x2D	0x002D	#HYPHEN-MINUS
+0x2E	0x002E	#FULL STOP
+0x2F	0x002F	#SOLIDUS
+0x30	0x0030	#DIGIT ZERO
+0x31	0x0031	#DIGIT ONE
+0x32	0x0032	#DIGIT TWO
+0x33	0x0033	#DIGIT THREE
+0x34	0x0034	#DIGIT FOUR
+0x35	0x0035	#DIGIT FIVE
+0x36	0x0036	#DIGIT SIX
+0x37	0x0037	#DIGIT SEVEN
+0x38	0x0038	#DIGIT EIGHT
+0x39	0x0039	#DIGIT NINE
+0x3A	0x003A	#COLON
+0x3B	0x003B	#SEMICOLON
+0x3C	0x003C	#LESS-THAN SIGN
+0x3D	0x003D	#EQUALS SIGN
+0x3E	0x003E	#GREATER-THAN SIGN
+0x3F	0x003F	#QUESTION MARK
+0x40	0x0040	#COMMERCIAL AT
+0x41	0x0041	#LATIN CAPITAL LETTER A
+0x42	0x0042	#LATIN CAPITAL LETTER B
+0x43	0x0043	#LATIN CAPITAL LETTER C
+0x44	0x0044	#LATIN CAPITAL LETTER D
+0x45	0x0045	#LATIN CAPITAL LETTER E
+0x46	0x0046	#LATIN CAPITAL LETTER F
+0x47	0x0047	#LATIN CAPITAL LETTER G
+0x48	0x0048	#LATIN CAPITAL LETTER H
+0x49	0x0049	#LATIN CAPITAL LETTER I
+0x4A	0x004A	#LATIN CAPITAL LETTER J
+0x4B	0x004B	#LATIN CAPITAL LETTER K
+0x4C	0x004C	#LATIN CAPITAL LETTER L
+0x4D	0x004D	#LATIN CAPITAL LETTER M
+0x4E	0x004E	#LATIN CAPITAL LETTER N
+0x4F	0x004F	#LATIN CAPITAL LETTER O
+0x50	0x0050	#LATIN CAPITAL LETTER P
+0x51	0x0051	#LATIN CAPITAL LETTER Q
+0x52	0x0052	#LATIN CAPITAL LETTER R
+0x53	0x0053	#LATIN CAPITAL LETTER S
+0x54	0x0054	#LATIN CAPITAL LETTER T
+0x55	0x0055	#LATIN CAPITAL LETTER U
+0x56	0x0056	#LATIN CAPITAL LETTER V
+0x57	0x0057	#LATIN CAPITAL LETTER W
+0x58	0x0058	#LATIN CAPITAL LETTER X
+0x59	0x0059	#LATIN CAPITAL LETTER Y
+0x5A	0x005A	#LATIN CAPITAL LETTER Z
+0x5B	0x005B	#LEFT SQUARE BRACKET
+0x5C	0x005C	#REVERSE SOLIDUS
+0x5D	0x005D	#RIGHT SQUARE BRACKET
+0x5E	0x005E	#CIRCUMFLEX ACCENT
+0x5F	0x005F	#LOW LINE
+0x60	0x0060	#GRAVE ACCENT
+0x61	0x0061	#LATIN SMALL LETTER A
+0x62	0x0062	#LATIN SMALL LETTER B
+0x63	0x0063	#LATIN SMALL LETTER C
+0x64	0x0064	#LATIN SMALL LETTER D
+0x65	0x0065	#LATIN SMALL LETTER E
+0x66	0x0066	#LATIN SMALL LETTER F
+0x67	0x0067	#LATIN SMALL LETTER G
+0x68	0x0068	#LATIN SMALL LETTER H
+0x69	0x0069	#LATIN SMALL LETTER I
+0x6A	0x006A	#LATIN SMALL LETTER J
+0x6B	0x006B	#LATIN SMALL LETTER K
+0x6C	0x006C	#LATIN SMALL LETTER L
+0x6D	0x006D	#LATIN SMALL LETTER M
+0x6E	0x006E	#LATIN SMALL LETTER N
+0x6F	0x006F	#LATIN SMALL LETTER O
+0x70	0x0070	#LATIN SMALL LETTER P
+0x71	0x0071	#LATIN SMALL LETTER Q
+0x72	0x0072	#LATIN SMALL LETTER R
+0x73	0x0073	#LATIN SMALL LETTER S
+0x74	0x0074	#LATIN SMALL LETTER T
+0x75	0x0075	#LATIN SMALL LETTER U
+0x76	0x0076	#LATIN SMALL LETTER V
+0x77	0x0077	#LATIN SMALL LETTER W
+0x78	0x0078	#LATIN SMALL LETTER X
+0x79	0x0079	#LATIN SMALL LETTER Y
+0x7A	0x007A	#LATIN SMALL LETTER Z
+0x7B	0x007B	#LEFT CURLY BRACKET
+0x7C	0x007C	#VERTICAL LINE
+0x7D	0x007D	#RIGHT CURLY BRACKET
+0x7E	0x007E	#TILDE
+0x7F	0x007F	#DELETE
+0x80	0x20AC	#EURO SIGN
+0x81	      	#UNDEFINED
+0x82	0x201A	#SINGLE LOW-9 QUOTATION MARK
+0x83	0x0192	#LATIN SMALL LETTER F WITH HOOK
+0x84	0x201E	#DOUBLE LOW-9 QUOTATION MARK
+0x85	0x2026	#HORIZONTAL ELLIPSIS
+0x86	0x2020	#DAGGER
+0x87	0x2021	#DOUBLE DAGGER
+0x88	0x02C6	#MODIFIER LETTER CIRCUMFLEX ACCENT
+0x89	0x2030	#PER MILLE SIGN
+0x8A	      	#UNDEFINED
+0x8B	0x2039	#SINGLE LEFT-POINTING ANGLE QUOTATION MARK
+0x8C	      	#UNDEFINED
+0x8D	      	#UNDEFINED
+0x8E	      	#UNDEFINED
+0x8F	      	#UNDEFINED
+0x90	      	#UNDEFINED
+0x91	0x2018	#LEFT SINGLE QUOTATION MARK
+0x92	0x2019	#RIGHT SINGLE QUOTATION MARK
+0x93	0x201C	#LEFT DOUBLE QUOTATION MARK
+0x94	0x201D	#RIGHT DOUBLE QUOTATION MARK
+0x95	0x2022	#BULLET
+0x96	0x2013	#EN DASH
+0x97	0x2014	#EM DASH
+0x98	0x02DC	#SMALL TILDE
+0x99	0x2122	#TRADE MARK SIGN
+0x9A	      	#UNDEFINED
+0x9B	0x203A	#SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
+0x9C	      	#UNDEFINED
+0x9D	      	#UNDEFINED
+0x9E	      	#UNDEFINED
+0x9F	      	#UNDEFINED
+0xA0	0x00A0	#NO-BREAK SPACE
+0xA1	0x00A1	#INVERTED EXCLAMATION MARK
+0xA2	0x00A2	#CENT SIGN
+0xA3	0x00A3	#POUND SIGN
+0xA4	0x20AA	#NEW SHEQEL SIGN
+0xA5	0x00A5	#YEN SIGN
+0xA6	0x00A6	#BROKEN BAR
+0xA7	0x00A7	#SECTION SIGN
+0xA8	0x00A8	#DIAERESIS
+0xA9	0x00A9	#COPYRIGHT SIGN
+0xAA	0x00D7	#MULTIPLICATION SIGN
+0xAB	0x00AB	#LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+0xAC	0x00AC	#NOT SIGN
+0xAD	0x00AD	#SOFT HYPHEN
+0xAE	0x00AE	#REGISTERED SIGN
+0xAF	0x00AF	#MACRON
+0xB0	0x00B0	#DEGREE SIGN
+0xB1	0x00B1	#PLUS-MINUS SIGN
+0xB2	0x00B2	#SUPERSCRIPT TWO
+0xB3	0x00B3	#SUPERSCRIPT THREE
+0xB4	0x00B4	#ACUTE ACCENT
+0xB5	0x00B5	#MICRO SIGN
+0xB6	0x00B6	#PILCROW SIGN
+0xB7	0x00B7	#MIDDLE DOT
+0xB8	0x00B8	#CEDILLA
+0xB9	0x00B9	#SUPERSCRIPT ONE
+0xBA	0x00F7	#DIVISION SIGN
+0xBB	0x00BB	#RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+0xBC	0x00BC	#VULGAR FRACTION ONE QUARTER
+0xBD	0x00BD	#VULGAR FRACTION ONE HALF
+0xBE	0x00BE	#VULGAR FRACTION THREE QUARTERS
+0xBF	0x00BF	#INVERTED QUESTION MARK
+0xC0	0x05B0	#HEBREW POINT SHEVA
+0xC1	0x05B1	#HEBREW POINT HATAF SEGOL
+0xC2	0x05B2	#HEBREW POINT HATAF PATAH
+0xC3	0x05B3	#HEBREW POINT HATAF QAMATS
+0xC4	0x05B4	#HEBREW POINT HIRIQ
+0xC5	0x05B5	#HEBREW POINT TSERE
+0xC6	0x05B6	#HEBREW POINT SEGOL
+0xC7	0x05B7	#HEBREW POINT PATAH
+0xC8	0x05B8	#HEBREW POINT QAMATS
+0xC9	0x05B9	#HEBREW POINT HOLAM
+0xCA		#UNDEFINED
+0xCB	0x05BB	#HEBREW POINT QUBUTS
+0xCC	0x05BC	#HEBREW POINT DAGESH OR MAPIQ
+0xCD	0x05BD	#HEBREW POINT METEG
+0xCE	0x05BE	#HEBREW PUNCTUATION MAQAF
+0xCF	0x05BF	#HEBREW POINT RAFE
+0xD0	0x05C0	#HEBREW PUNCTUATION PASEQ
+0xD1	0x05C1	#HEBREW POINT SHIN DOT
+0xD2	0x05C2	#HEBREW POINT SIN DOT
+0xD3	0x05C3	#HEBREW PUNCTUATION SOF PASUQ
+0xD4	0x05F0	#HEBREW LIGATURE YIDDISH DOUBLE VAV
+0xD5	0x05F1	#HEBREW LIGATURE YIDDISH VAV YOD
+0xD6	0x05F2	#HEBREW LIGATURE YIDDISH DOUBLE YOD
+0xD7	0x05F3	#HEBREW PUNCTUATION GERESH
+0xD8	0x05F4	#HEBREW PUNCTUATION GERSHAYIM
+0xD9	      	#UNDEFINED
+0xDA	      	#UNDEFINED
+0xDB	      	#UNDEFINED
+0xDC	      	#UNDEFINED
+0xDD	      	#UNDEFINED
+0xDE	      	#UNDEFINED
+0xDF	      	#UNDEFINED
+0xE0	0x05D0	#HEBREW LETTER ALEF
+0xE1	0x05D1	#HEBREW LETTER BET
+0xE2	0x05D2	#HEBREW LETTER GIMEL
+0xE3	0x05D3	#HEBREW LETTER DALET
+0xE4	0x05D4	#HEBREW LETTER HE
+0xE5	0x05D5	#HEBREW LETTER VAV
+0xE6	0x05D6	#HEBREW LETTER ZAYIN
+0xE7	0x05D7	#HEBREW LETTER HET
+0xE8	0x05D8	#HEBREW LETTER TET
+0xE9	0x05D9	#HEBREW LETTER YOD
+0xEA	0x05DA	#HEBREW LETTER FINAL KAF
+0xEB	0x05DB	#HEBREW LETTER KAF
+0xEC	0x05DC	#HEBREW LETTER LAMED
+0xED	0x05DD	#HEBREW LETTER FINAL MEM
+0xEE	0x05DE	#HEBREW LETTER MEM
+0xEF	0x05DF	#HEBREW LETTER FINAL NUN
+0xF0	0x05E0	#HEBREW LETTER NUN
+0xF1	0x05E1	#HEBREW LETTER SAMEKH
+0xF2	0x05E2	#HEBREW LETTER AYIN
+0xF3	0x05E3	#HEBREW LETTER FINAL PE
+0xF4	0x05E4	#HEBREW LETTER PE
+0xF5	0x05E5	#HEBREW LETTER FINAL TSADI
+0xF6	0x05E6	#HEBREW LETTER TSADI
+0xF7	0x05E7	#HEBREW LETTER QOF
+0xF8	0x05E8	#HEBREW LETTER RESH
+0xF9	0x05E9	#HEBREW LETTER SHIN
+0xFA	0x05EA	#HEBREW LETTER TAV
+0xFB	      	#UNDEFINED
+0xFC	      	#UNDEFINED
+0xFD	0x200E	#LEFT-TO-RIGHT MARK
+0xFE	0x200F	#RIGHT-TO-LEFT MARK
+0xFF	      	#UNDEFINED
diff --git a/tools/encoding/cp1256.txt b/tools/encoding/cp1256.txt
new file mode 100644
index 0000000..0edd081
--- /dev/null
+++ b/tools/encoding/cp1256.txt
@@ -0,0 +1,274 @@
+#
+#    Name:     cp1256 to Unicode table
+#    Unicode version: 2.1
+#    Table version: 2.01
+#    Table format:  Format A
+#    Date:          01/5/99
+#
+#    Contact:       cpxlate@microsoft.com
+#
+#    General notes: none
+#
+#    Format: Three tab-separated columns
+#        Column #1 is the cp1256 code (in hex)
+#        Column #2 is the Unicode (in hex as 0xXXXX)
+#        Column #3 is the Unicode name (follows a comment sign, '#')
+#
+#    The entries are in cp1256 order
+#
+0x00	0x0000	#NULL
+0x01	0x0001	#START OF HEADING
+0x02	0x0002	#START OF TEXT
+0x03	0x0003	#END OF TEXT
+0x04	0x0004	#END OF TRANSMISSION
+0x05	0x0005	#ENQUIRY
+0x06	0x0006	#ACKNOWLEDGE
+0x07	0x0007	#BELL
+0x08	0x0008	#BACKSPACE
+0x09	0x0009	#HORIZONTAL TABULATION
+0x0A	0x000A	#LINE FEED
+0x0B	0x000B	#VERTICAL TABULATION
+0x0C	0x000C	#FORM FEED
+0x0D	0x000D	#CARRIAGE RETURN
+0x0E	0x000E	#SHIFT OUT
+0x0F	0x000F	#SHIFT IN
+0x10	0x0010	#DATA LINK ESCAPE
+0x11	0x0011	#DEVICE CONTROL ONE
+0x12	0x0012	#DEVICE CONTROL TWO
+0x13	0x0013	#DEVICE CONTROL THREE
+0x14	0x0014	#DEVICE CONTROL FOUR
+0x15	0x0015	#NEGATIVE ACKNOWLEDGE
+0x16	0x0016	#SYNCHRONOUS IDLE
+0x17	0x0017	#END OF TRANSMISSION BLOCK
+0x18	0x0018	#CANCEL
+0x19	0x0019	#END OF MEDIUM
+0x1A	0x001A	#SUBSTITUTE
+0x1B	0x001B	#ESCAPE
+0x1C	0x001C	#FILE SEPARATOR
+0x1D	0x001D	#GROUP SEPARATOR
+0x1E	0x001E	#RECORD SEPARATOR
+0x1F	0x001F	#UNIT SEPARATOR
+0x20	0x0020	#SPACE
+0x21	0x0021	#EXCLAMATION MARK
+0x22	0x0022	#QUOTATION MARK
+0x23	0x0023	#NUMBER SIGN
+0x24	0x0024	#DOLLAR SIGN
+0x25	0x0025	#PERCENT SIGN
+0x26	0x0026	#AMPERSAND
+0x27	0x0027	#APOSTROPHE
+0x28	0x0028	#LEFT PARENTHESIS
+0x29	0x0029	#RIGHT PARENTHESIS
+0x2A	0x002A	#ASTERISK
+0x2B	0x002B	#PLUS SIGN
+0x2C	0x002C	#COMMA
+0x2D	0x002D	#HYPHEN-MINUS
+0x2E	0x002E	#FULL STOP
+0x2F	0x002F	#SOLIDUS
+0x30	0x0030	#DIGIT ZERO
+0x31	0x0031	#DIGIT ONE
+0x32	0x0032	#DIGIT TWO
+0x33	0x0033	#DIGIT THREE
+0x34	0x0034	#DIGIT FOUR
+0x35	0x0035	#DIGIT FIVE
+0x36	0x0036	#DIGIT SIX
+0x37	0x0037	#DIGIT SEVEN
+0x38	0x0038	#DIGIT EIGHT
+0x39	0x0039	#DIGIT NINE
+0x3A	0x003A	#COLON
+0x3B	0x003B	#SEMICOLON
+0x3C	0x003C	#LESS-THAN SIGN
+0x3D	0x003D	#EQUALS SIGN
+0x3E	0x003E	#GREATER-THAN SIGN
+0x3F	0x003F	#QUESTION MARK
+0x40	0x0040	#COMMERCIAL AT
+0x41	0x0041	#LATIN CAPITAL LETTER A
+0x42	0x0042	#LATIN CAPITAL LETTER B
+0x43	0x0043	#LATIN CAPITAL LETTER C
+0x44	0x0044	#LATIN CAPITAL LETTER D
+0x45	0x0045	#LATIN CAPITAL LETTER E
+0x46	0x0046	#LATIN CAPITAL LETTER F
+0x47	0x0047	#LATIN CAPITAL LETTER G
+0x48	0x0048	#LATIN CAPITAL LETTER H
+0x49	0x0049	#LATIN CAPITAL LETTER I
+0x4A	0x004A	#LATIN CAPITAL LETTER J
+0x4B	0x004B	#LATIN CAPITAL LETTER K
+0x4C	0x004C	#LATIN CAPITAL LETTER L
+0x4D	0x004D	#LATIN CAPITAL LETTER M
+0x4E	0x004E	#LATIN CAPITAL LETTER N
+0x4F	0x004F	#LATIN CAPITAL LETTER O
+0x50	0x0050	#LATIN CAPITAL LETTER P
+0x51	0x0051	#LATIN CAPITAL LETTER Q
+0x52	0x0052	#LATIN CAPITAL LETTER R
+0x53	0x0053	#LATIN CAPITAL LETTER S
+0x54	0x0054	#LATIN CAPITAL LETTER T
+0x55	0x0055	#LATIN CAPITAL LETTER U
+0x56	0x0056	#LATIN CAPITAL LETTER V
+0x57	0x0057	#LATIN CAPITAL LETTER W
+0x58	0x0058	#LATIN CAPITAL LETTER X
+0x59	0x0059	#LATIN CAPITAL LETTER Y
+0x5A	0x005A	#LATIN CAPITAL LETTER Z
+0x5B	0x005B	#LEFT SQUARE BRACKET
+0x5C	0x005C	#REVERSE SOLIDUS
+0x5D	0x005D	#RIGHT SQUARE BRACKET
+0x5E	0x005E	#CIRCUMFLEX ACCENT
+0x5F	0x005F	#LOW LINE
+0x60	0x0060	#GRAVE ACCENT
+0x61	0x0061	#LATIN SMALL LETTER A
+0x62	0x0062	#LATIN SMALL LETTER B
+0x63	0x0063	#LATIN SMALL LETTER C
+0x64	0x0064	#LATIN SMALL LETTER D
+0x65	0x0065	#LATIN SMALL LETTER E
+0x66	0x0066	#LATIN SMALL LETTER F
+0x67	0x0067	#LATIN SMALL LETTER G
+0x68	0x0068	#LATIN SMALL LETTER H
+0x69	0x0069	#LATIN SMALL LETTER I
+0x6A	0x006A	#LATIN SMALL LETTER J
+0x6B	0x006B	#LATIN SMALL LETTER K
+0x6C	0x006C	#LATIN SMALL LETTER L
+0x6D	0x006D	#LATIN SMALL LETTER M
+0x6E	0x006E	#LATIN SMALL LETTER N
+0x6F	0x006F	#LATIN SMALL LETTER O
+0x70	0x0070	#LATIN SMALL LETTER P
+0x71	0x0071	#LATIN SMALL LETTER Q
+0x72	0x0072	#LATIN SMALL LETTER R
+0x73	0x0073	#LATIN SMALL LETTER S
+0x74	0x0074	#LATIN SMALL LETTER T
+0x75	0x0075	#LATIN SMALL LETTER U
+0x76	0x0076	#LATIN SMALL LETTER V
+0x77	0x0077	#LATIN SMALL LETTER W
+0x78	0x0078	#LATIN SMALL LETTER X
+0x79	0x0079	#LATIN SMALL LETTER Y
+0x7A	0x007A	#LATIN SMALL LETTER Z
+0x7B	0x007B	#LEFT CURLY BRACKET
+0x7C	0x007C	#VERTICAL LINE
+0x7D	0x007D	#RIGHT CURLY BRACKET
+0x7E	0x007E	#TILDE
+0x7F	0x007F	#DELETE
+0x80	0x20AC	#EURO SIGN
+0x81	0x067E	#ARABIC LETTER PEH
+0x82	0x201A	#SINGLE LOW-9 QUOTATION MARK
+0x83	0x0192	#LATIN SMALL LETTER F WITH HOOK
+0x84	0x201E	#DOUBLE LOW-9 QUOTATION MARK
+0x85	0x2026	#HORIZONTAL ELLIPSIS
+0x86	0x2020	#DAGGER
+0x87	0x2021	#DOUBLE DAGGER
+0x88	0x02C6	#MODIFIER LETTER CIRCUMFLEX ACCENT
+0x89	0x2030	#PER MILLE SIGN
+0x8A	0x0679	#ARABIC LETTER TTEH
+0x8B	0x2039	#SINGLE LEFT-POINTING ANGLE QUOTATION MARK
+0x8C	0x0152	#LATIN CAPITAL LIGATURE OE
+0x8D	0x0686	#ARABIC LETTER TCHEH
+0x8E	0x0698	#ARABIC LETTER JEH
+0x8F	0x0688	#ARABIC LETTER DDAL
+0x90	0x06AF	#ARABIC LETTER GAF
+0x91	0x2018	#LEFT SINGLE QUOTATION MARK
+0x92	0x2019	#RIGHT SINGLE QUOTATION MARK
+0x93	0x201C	#LEFT DOUBLE QUOTATION MARK
+0x94	0x201D	#RIGHT DOUBLE QUOTATION MARK
+0x95	0x2022	#BULLET
+0x96	0x2013	#EN DASH
+0x97	0x2014	#EM DASH
+0x98	0x06A9	#ARABIC LETTER KEHEH
+0x99	0x2122	#TRADE MARK SIGN
+0x9A	0x0691	#ARABIC LETTER RREH
+0x9B	0x203A	#SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
+0x9C	0x0153	#LATIN SMALL LIGATURE OE
+0x9D	0x200C	#ZERO WIDTH NON-JOINER
+0x9E	0x200D	#ZERO WIDTH JOINER
+0x9F	0x06BA	#ARABIC LETTER NOON GHUNNA
+0xA0	0x00A0	#NO-BREAK SPACE
+0xA1	0x060C	#ARABIC COMMA
+0xA2	0x00A2	#CENT SIGN
+0xA3	0x00A3	#POUND SIGN
+0xA4	0x00A4	#CURRENCY SIGN
+0xA5	0x00A5	#YEN SIGN
+0xA6	0x00A6	#BROKEN BAR
+0xA7	0x00A7	#SECTION SIGN
+0xA8	0x00A8	#DIAERESIS
+0xA9	0x00A9	#COPYRIGHT SIGN
+0xAA	0x06BE	#ARABIC LETTER HEH DOACHASHMEE
+0xAB	0x00AB	#LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+0xAC	0x00AC	#NOT SIGN
+0xAD	0x00AD	#SOFT HYPHEN
+0xAE	0x00AE	#REGISTERED SIGN
+0xAF	0x00AF	#MACRON
+0xB0	0x00B0	#DEGREE SIGN
+0xB1	0x00B1	#PLUS-MINUS SIGN
+0xB2	0x00B2	#SUPERSCRIPT TWO
+0xB3	0x00B3	#SUPERSCRIPT THREE
+0xB4	0x00B4	#ACUTE ACCENT
+0xB5	0x00B5	#MICRO SIGN
+0xB6	0x00B6	#PILCROW SIGN
+0xB7	0x00B7	#MIDDLE DOT
+0xB8	0x00B8	#CEDILLA
+0xB9	0x00B9	#SUPERSCRIPT ONE
+0xBA	0x061B	#ARABIC SEMICOLON
+0xBB	0x00BB	#RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+0xBC	0x00BC	#VULGAR FRACTION ONE QUARTER
+0xBD	0x00BD	#VULGAR FRACTION ONE HALF
+0xBE	0x00BE	#VULGAR FRACTION THREE QUARTERS
+0xBF	0x061F	#ARABIC QUESTION MARK
+0xC0	0x06C1	#ARABIC LETTER HEH GOAL
+0xC1	0x0621	#ARABIC LETTER HAMZA
+0xC2	0x0622	#ARABIC LETTER ALEF WITH MADDA ABOVE
+0xC3	0x0623	#ARABIC LETTER ALEF WITH HAMZA ABOVE
+0xC4	0x0624	#ARABIC LETTER WAW WITH HAMZA ABOVE
+0xC5	0x0625	#ARABIC LETTER ALEF WITH HAMZA BELOW
+0xC6	0x0626	#ARABIC LETTER YEH WITH HAMZA ABOVE
+0xC7	0x0627	#ARABIC LETTER ALEF
+0xC8	0x0628	#ARABIC LETTER BEH
+0xC9	0x0629	#ARABIC LETTER TEH MARBUTA
+0xCA	0x062A	#ARABIC LETTER TEH
+0xCB	0x062B	#ARABIC LETTER THEH
+0xCC	0x062C	#ARABIC LETTER JEEM
+0xCD	0x062D	#ARABIC LETTER HAH
+0xCE	0x062E	#ARABIC LETTER KHAH
+0xCF	0x062F	#ARABIC LETTER DAL
+0xD0	0x0630	#ARABIC LETTER THAL
+0xD1	0x0631	#ARABIC LETTER REH
+0xD2	0x0632	#ARABIC LETTER ZAIN
+0xD3	0x0633	#ARABIC LETTER SEEN
+0xD4	0x0634	#ARABIC LETTER SHEEN
+0xD5	0x0635	#ARABIC LETTER SAD
+0xD6	0x0636	#ARABIC LETTER DAD
+0xD7	0x00D7	#MULTIPLICATION SIGN
+0xD8	0x0637	#ARABIC LETTER TAH
+0xD9	0x0638	#ARABIC LETTER ZAH
+0xDA	0x0639	#ARABIC LETTER AIN
+0xDB	0x063A	#ARABIC LETTER GHAIN
+0xDC	0x0640	#ARABIC TATWEEL
+0xDD	0x0641	#ARABIC LETTER FEH
+0xDE	0x0642	#ARABIC LETTER QAF
+0xDF	0x0643	#ARABIC LETTER KAF
+0xE0	0x00E0	#LATIN SMALL LETTER A WITH GRAVE
+0xE1	0x0644	#ARABIC LETTER LAM
+0xE2	0x00E2	#LATIN SMALL LETTER A WITH CIRCUMFLEX
+0xE3	0x0645	#ARABIC LETTER MEEM
+0xE4	0x0646	#ARABIC LETTER NOON
+0xE5	0x0647	#ARABIC LETTER HEH
+0xE6	0x0648	#ARABIC LETTER WAW
+0xE7	0x00E7	#LATIN SMALL LETTER C WITH CEDILLA
+0xE8	0x00E8	#LATIN SMALL LETTER E WITH GRAVE
+0xE9	0x00E9	#LATIN SMALL LETTER E WITH ACUTE
+0xEA	0x00EA	#LATIN SMALL LETTER E WITH CIRCUMFLEX
+0xEB	0x00EB	#LATIN SMALL LETTER E WITH DIAERESIS
+0xEC	0x0649	#ARABIC LETTER ALEF MAKSURA
+0xED	0x064A	#ARABIC LETTER YEH
+0xEE	0x00EE	#LATIN SMALL LETTER I WITH CIRCUMFLEX
+0xEF	0x00EF	#LATIN SMALL LETTER I WITH DIAERESIS
+0xF0	0x064B	#ARABIC FATHATAN
+0xF1	0x064C	#ARABIC DAMMATAN
+0xF2	0x064D	#ARABIC KASRATAN
+0xF3	0x064E	#ARABIC FATHA
+0xF4	0x00F4	#LATIN SMALL LETTER O WITH CIRCUMFLEX
+0xF5	0x064F	#ARABIC DAMMA
+0xF6	0x0650	#ARABIC KASRA
+0xF7	0x00F7	#DIVISION SIGN
+0xF8	0x0651	#ARABIC SHADDA
+0xF9	0x00F9	#LATIN SMALL LETTER U WITH GRAVE
+0xFA	0x0652	#ARABIC SUKUN
+0xFB	0x00FB	#LATIN SMALL LETTER U WITH CIRCUMFLEX
+0xFC	0x00FC	#LATIN SMALL LETTER U WITH DIAERESIS
+0xFD	0x200E	#LEFT-TO-RIGHT MARK
+0xFE	0x200F	#RIGHT-TO-LEFT MARK
+0xFF	0x06D2	#ARABIC LETTER YEH BARREE
diff --git a/tools/encoding/cp1257.txt b/tools/encoding/cp1257.txt
new file mode 100644
index 0000000..97979d9
--- /dev/null
+++ b/tools/encoding/cp1257.txt
@@ -0,0 +1,274 @@
+#
+#    Name:     cp1257 to Unicode table
+#    Unicode version: 2.0
+#    Table version: 2.01
+#    Table format:  Format A
+#    Date:          04/15/98
+#
+#    Contact:       cpxlate@microsoft.com
+#
+#    General notes: none
+#
+#    Format: Three tab-separated columns
+#        Column #1 is the cp1257 code (in hex)
+#        Column #2 is the Unicode (in hex as 0xXXXX)
+#        Column #3 is the Unicode name (follows a comment sign, '#')
+#
+#    The entries are in cp1257 order
+#
+0x00	0x0000	#NULL
+0x01	0x0001	#START OF HEADING
+0x02	0x0002	#START OF TEXT
+0x03	0x0003	#END OF TEXT
+0x04	0x0004	#END OF TRANSMISSION
+0x05	0x0005	#ENQUIRY
+0x06	0x0006	#ACKNOWLEDGE
+0x07	0x0007	#BELL
+0x08	0x0008	#BACKSPACE
+0x09	0x0009	#HORIZONTAL TABULATION
+0x0A	0x000A	#LINE FEED
+0x0B	0x000B	#VERTICAL TABULATION
+0x0C	0x000C	#FORM FEED
+0x0D	0x000D	#CARRIAGE RETURN
+0x0E	0x000E	#SHIFT OUT
+0x0F	0x000F	#SHIFT IN
+0x10	0x0010	#DATA LINK ESCAPE
+0x11	0x0011	#DEVICE CONTROL ONE
+0x12	0x0012	#DEVICE CONTROL TWO
+0x13	0x0013	#DEVICE CONTROL THREE
+0x14	0x0014	#DEVICE CONTROL FOUR
+0x15	0x0015	#NEGATIVE ACKNOWLEDGE
+0x16	0x0016	#SYNCHRONOUS IDLE
+0x17	0x0017	#END OF TRANSMISSION BLOCK
+0x18	0x0018	#CANCEL
+0x19	0x0019	#END OF MEDIUM
+0x1A	0x001A	#SUBSTITUTE
+0x1B	0x001B	#ESCAPE
+0x1C	0x001C	#FILE SEPARATOR
+0x1D	0x001D	#GROUP SEPARATOR
+0x1E	0x001E	#RECORD SEPARATOR
+0x1F	0x001F	#UNIT SEPARATOR
+0x20	0x0020	#SPACE
+0x21	0x0021	#EXCLAMATION MARK
+0x22	0x0022	#QUOTATION MARK
+0x23	0x0023	#NUMBER SIGN
+0x24	0x0024	#DOLLAR SIGN
+0x25	0x0025	#PERCENT SIGN
+0x26	0x0026	#AMPERSAND
+0x27	0x0027	#APOSTROPHE
+0x28	0x0028	#LEFT PARENTHESIS
+0x29	0x0029	#RIGHT PARENTHESIS
+0x2A	0x002A	#ASTERISK
+0x2B	0x002B	#PLUS SIGN
+0x2C	0x002C	#COMMA
+0x2D	0x002D	#HYPHEN-MINUS
+0x2E	0x002E	#FULL STOP
+0x2F	0x002F	#SOLIDUS
+0x30	0x0030	#DIGIT ZERO
+0x31	0x0031	#DIGIT ONE
+0x32	0x0032	#DIGIT TWO
+0x33	0x0033	#DIGIT THREE
+0x34	0x0034	#DIGIT FOUR
+0x35	0x0035	#DIGIT FIVE
+0x36	0x0036	#DIGIT SIX
+0x37	0x0037	#DIGIT SEVEN
+0x38	0x0038	#DIGIT EIGHT
+0x39	0x0039	#DIGIT NINE
+0x3A	0x003A	#COLON
+0x3B	0x003B	#SEMICOLON
+0x3C	0x003C	#LESS-THAN SIGN
+0x3D	0x003D	#EQUALS SIGN
+0x3E	0x003E	#GREATER-THAN SIGN
+0x3F	0x003F	#QUESTION MARK
+0x40	0x0040	#COMMERCIAL AT
+0x41	0x0041	#LATIN CAPITAL LETTER A
+0x42	0x0042	#LATIN CAPITAL LETTER B
+0x43	0x0043	#LATIN CAPITAL LETTER C
+0x44	0x0044	#LATIN CAPITAL LETTER D
+0x45	0x0045	#LATIN CAPITAL LETTER E
+0x46	0x0046	#LATIN CAPITAL LETTER F
+0x47	0x0047	#LATIN CAPITAL LETTER G
+0x48	0x0048	#LATIN CAPITAL LETTER H
+0x49	0x0049	#LATIN CAPITAL LETTER I
+0x4A	0x004A	#LATIN CAPITAL LETTER J
+0x4B	0x004B	#LATIN CAPITAL LETTER K
+0x4C	0x004C	#LATIN CAPITAL LETTER L
+0x4D	0x004D	#LATIN CAPITAL LETTER M
+0x4E	0x004E	#LATIN CAPITAL LETTER N
+0x4F	0x004F	#LATIN CAPITAL LETTER O
+0x50	0x0050	#LATIN CAPITAL LETTER P
+0x51	0x0051	#LATIN CAPITAL LETTER Q
+0x52	0x0052	#LATIN CAPITAL LETTER R
+0x53	0x0053	#LATIN CAPITAL LETTER S
+0x54	0x0054	#LATIN CAPITAL LETTER T
+0x55	0x0055	#LATIN CAPITAL LETTER U
+0x56	0x0056	#LATIN CAPITAL LETTER V
+0x57	0x0057	#LATIN CAPITAL LETTER W
+0x58	0x0058	#LATIN CAPITAL LETTER X
+0x59	0x0059	#LATIN CAPITAL LETTER Y
+0x5A	0x005A	#LATIN CAPITAL LETTER Z
+0x5B	0x005B	#LEFT SQUARE BRACKET
+0x5C	0x005C	#REVERSE SOLIDUS
+0x5D	0x005D	#RIGHT SQUARE BRACKET
+0x5E	0x005E	#CIRCUMFLEX ACCENT
+0x5F	0x005F	#LOW LINE
+0x60	0x0060	#GRAVE ACCENT
+0x61	0x0061	#LATIN SMALL LETTER A
+0x62	0x0062	#LATIN SMALL LETTER B
+0x63	0x0063	#LATIN SMALL LETTER C
+0x64	0x0064	#LATIN SMALL LETTER D
+0x65	0x0065	#LATIN SMALL LETTER E
+0x66	0x0066	#LATIN SMALL LETTER F
+0x67	0x0067	#LATIN SMALL LETTER G
+0x68	0x0068	#LATIN SMALL LETTER H
+0x69	0x0069	#LATIN SMALL LETTER I
+0x6A	0x006A	#LATIN SMALL LETTER J
+0x6B	0x006B	#LATIN SMALL LETTER K
+0x6C	0x006C	#LATIN SMALL LETTER L
+0x6D	0x006D	#LATIN SMALL LETTER M
+0x6E	0x006E	#LATIN SMALL LETTER N
+0x6F	0x006F	#LATIN SMALL LETTER O
+0x70	0x0070	#LATIN SMALL LETTER P
+0x71	0x0071	#LATIN SMALL LETTER Q
+0x72	0x0072	#LATIN SMALL LETTER R
+0x73	0x0073	#LATIN SMALL LETTER S
+0x74	0x0074	#LATIN SMALL LETTER T
+0x75	0x0075	#LATIN SMALL LETTER U
+0x76	0x0076	#LATIN SMALL LETTER V
+0x77	0x0077	#LATIN SMALL LETTER W
+0x78	0x0078	#LATIN SMALL LETTER X
+0x79	0x0079	#LATIN SMALL LETTER Y
+0x7A	0x007A	#LATIN SMALL LETTER Z
+0x7B	0x007B	#LEFT CURLY BRACKET
+0x7C	0x007C	#VERTICAL LINE
+0x7D	0x007D	#RIGHT CURLY BRACKET
+0x7E	0x007E	#TILDE
+0x7F	0x007F	#DELETE
+0x80	0x20AC	#EURO SIGN
+0x81	      	#UNDEFINED
+0x82	0x201A	#SINGLE LOW-9 QUOTATION MARK
+0x83	      	#UNDEFINED
+0x84	0x201E	#DOUBLE LOW-9 QUOTATION MARK
+0x85	0x2026	#HORIZONTAL ELLIPSIS
+0x86	0x2020	#DAGGER
+0x87	0x2021	#DOUBLE DAGGER
+0x88	      	#UNDEFINED
+0x89	0x2030	#PER MILLE SIGN
+0x8A	      	#UNDEFINED
+0x8B	0x2039	#SINGLE LEFT-POINTING ANGLE QUOTATION MARK
+0x8C	      	#UNDEFINED
+0x8D	0x00A8	#DIAERESIS
+0x8E	0x02C7	#CARON
+0x8F	0x00B8	#CEDILLA
+0x90	      	#UNDEFINED
+0x91	0x2018	#LEFT SINGLE QUOTATION MARK
+0x92	0x2019	#RIGHT SINGLE QUOTATION MARK
+0x93	0x201C	#LEFT DOUBLE QUOTATION MARK
+0x94	0x201D	#RIGHT DOUBLE QUOTATION MARK
+0x95	0x2022	#BULLET
+0x96	0x2013	#EN DASH
+0x97	0x2014	#EM DASH
+0x98	      	#UNDEFINED
+0x99	0x2122	#TRADE MARK SIGN
+0x9A	      	#UNDEFINED
+0x9B	0x203A	#SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
+0x9C	      	#UNDEFINED
+0x9D	0x00AF	#MACRON
+0x9E	0x02DB	#OGONEK
+0x9F	      	#UNDEFINED
+0xA0	0x00A0	#NO-BREAK SPACE
+0xA1	      	#UNDEFINED
+0xA2	0x00A2	#CENT SIGN
+0xA3	0x00A3	#POUND SIGN
+0xA4	0x00A4	#CURRENCY SIGN
+0xA5	      	#UNDEFINED
+0xA6	0x00A6	#BROKEN BAR
+0xA7	0x00A7	#SECTION SIGN
+0xA8	0x00D8	#LATIN CAPITAL LETTER O WITH STROKE
+0xA9	0x00A9	#COPYRIGHT SIGN
+0xAA	0x0156	#LATIN CAPITAL LETTER R WITH CEDILLA
+0xAB	0x00AB	#LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+0xAC	0x00AC	#NOT SIGN
+0xAD	0x00AD	#SOFT HYPHEN
+0xAE	0x00AE	#REGISTERED SIGN
+0xAF	0x00C6	#LATIN CAPITAL LETTER AE
+0xB0	0x00B0	#DEGREE SIGN
+0xB1	0x00B1	#PLUS-MINUS SIGN
+0xB2	0x00B2	#SUPERSCRIPT TWO
+0xB3	0x00B3	#SUPERSCRIPT THREE
+0xB4	0x00B4	#ACUTE ACCENT
+0xB5	0x00B5	#MICRO SIGN
+0xB6	0x00B6	#PILCROW SIGN
+0xB7	0x00B7	#MIDDLE DOT
+0xB8	0x00F8	#LATIN SMALL LETTER O WITH STROKE
+0xB9	0x00B9	#SUPERSCRIPT ONE
+0xBA	0x0157	#LATIN SMALL LETTER R WITH CEDILLA
+0xBB	0x00BB	#RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+0xBC	0x00BC	#VULGAR FRACTION ONE QUARTER
+0xBD	0x00BD	#VULGAR FRACTION ONE HALF
+0xBE	0x00BE	#VULGAR FRACTION THREE QUARTERS
+0xBF	0x00E6	#LATIN SMALL LETTER AE
+0xC0	0x0104	#LATIN CAPITAL LETTER A WITH OGONEK
+0xC1	0x012E	#LATIN CAPITAL LETTER I WITH OGONEK
+0xC2	0x0100	#LATIN CAPITAL LETTER A WITH MACRON
+0xC3	0x0106	#LATIN CAPITAL LETTER C WITH ACUTE
+0xC4	0x00C4	#LATIN CAPITAL LETTER A WITH DIAERESIS
+0xC5	0x00C5	#LATIN CAPITAL LETTER A WITH RING ABOVE
+0xC6	0x0118	#LATIN CAPITAL LETTER E WITH OGONEK
+0xC7	0x0112	#LATIN CAPITAL LETTER E WITH MACRON
+0xC8	0x010C	#LATIN CAPITAL LETTER C WITH CARON
+0xC9	0x00C9	#LATIN CAPITAL LETTER E WITH ACUTE
+0xCA	0x0179	#LATIN CAPITAL LETTER Z WITH ACUTE
+0xCB	0x0116	#LATIN CAPITAL LETTER E WITH DOT ABOVE
+0xCC	0x0122	#LATIN CAPITAL LETTER G WITH CEDILLA
+0xCD	0x0136	#LATIN CAPITAL LETTER K WITH CEDILLA
+0xCE	0x012A	#LATIN CAPITAL LETTER I WITH MACRON
+0xCF	0x013B	#LATIN CAPITAL LETTER L WITH CEDILLA
+0xD0	0x0160	#LATIN CAPITAL LETTER S WITH CARON
+0xD1	0x0143	#LATIN CAPITAL LETTER N WITH ACUTE
+0xD2	0x0145	#LATIN CAPITAL LETTER N WITH CEDILLA
+0xD3	0x00D3	#LATIN CAPITAL LETTER O WITH ACUTE
+0xD4	0x014C	#LATIN CAPITAL LETTER O WITH MACRON
+0xD5	0x00D5	#LATIN CAPITAL LETTER O WITH TILDE
+0xD6	0x00D6	#LATIN CAPITAL LETTER O WITH DIAERESIS
+0xD7	0x00D7	#MULTIPLICATION SIGN
+0xD8	0x0172	#LATIN CAPITAL LETTER U WITH OGONEK
+0xD9	0x0141	#LATIN CAPITAL LETTER L WITH STROKE
+0xDA	0x015A	#LATIN CAPITAL LETTER S WITH ACUTE
+0xDB	0x016A	#LATIN CAPITAL LETTER U WITH MACRON
+0xDC	0x00DC	#LATIN CAPITAL LETTER U WITH DIAERESIS
+0xDD	0x017B	#LATIN CAPITAL LETTER Z WITH DOT ABOVE
+0xDE	0x017D	#LATIN CAPITAL LETTER Z WITH CARON
+0xDF	0x00DF	#LATIN SMALL LETTER SHARP S
+0xE0	0x0105	#LATIN SMALL LETTER A WITH OGONEK
+0xE1	0x012F	#LATIN SMALL LETTER I WITH OGONEK
+0xE2	0x0101	#LATIN SMALL LETTER A WITH MACRON
+0xE3	0x0107	#LATIN SMALL LETTER C WITH ACUTE
+0xE4	0x00E4	#LATIN SMALL LETTER A WITH DIAERESIS
+0xE5	0x00E5	#LATIN SMALL LETTER A WITH RING ABOVE
+0xE6	0x0119	#LATIN SMALL LETTER E WITH OGONEK
+0xE7	0x0113	#LATIN SMALL LETTER E WITH MACRON
+0xE8	0x010D	#LATIN SMALL LETTER C WITH CARON
+0xE9	0x00E9	#LATIN SMALL LETTER E WITH ACUTE
+0xEA	0x017A	#LATIN SMALL LETTER Z WITH ACUTE
+0xEB	0x0117	#LATIN SMALL LETTER E WITH DOT ABOVE
+0xEC	0x0123	#LATIN SMALL LETTER G WITH CEDILLA
+0xED	0x0137	#LATIN SMALL LETTER K WITH CEDILLA
+0xEE	0x012B	#LATIN SMALL LETTER I WITH MACRON
+0xEF	0x013C	#LATIN SMALL LETTER L WITH CEDILLA
+0xF0	0x0161	#LATIN SMALL LETTER S WITH CARON
+0xF1	0x0144	#LATIN SMALL LETTER N WITH ACUTE
+0xF2	0x0146	#LATIN SMALL LETTER N WITH CEDILLA
+0xF3	0x00F3	#LATIN SMALL LETTER O WITH ACUTE
+0xF4	0x014D	#LATIN SMALL LETTER O WITH MACRON
+0xF5	0x00F5	#LATIN SMALL LETTER O WITH TILDE
+0xF6	0x00F6	#LATIN SMALL LETTER O WITH DIAERESIS
+0xF7	0x00F7	#DIVISION SIGN
+0xF8	0x0173	#LATIN SMALL LETTER U WITH OGONEK
+0xF9	0x0142	#LATIN SMALL LETTER L WITH STROKE
+0xFA	0x015B	#LATIN SMALL LETTER S WITH ACUTE
+0xFB	0x016B	#LATIN SMALL LETTER U WITH MACRON
+0xFC	0x00FC	#LATIN SMALL LETTER U WITH DIAERESIS
+0xFD	0x017C	#LATIN SMALL LETTER Z WITH DOT ABOVE
+0xFE	0x017E	#LATIN SMALL LETTER Z WITH CARON
+0xFF	0x02D9	#DOT ABOVE
diff --git a/tools/encoding/cp1258.txt b/tools/encoding/cp1258.txt
new file mode 100644
index 0000000..392310a
--- /dev/null
+++ b/tools/encoding/cp1258.txt
@@ -0,0 +1,274 @@
+#
+#    Name:     cp1258 to Unicode table
+#    Unicode version: 2.0
+#    Table version: 2.01
+#    Table format:  Format A
+#    Date:          04/15/98
+#
+#    Contact:       cpxlate@microsoft.com
+#
+#    General notes: none
+#
+#    Format: Three tab-separated columns
+#        Column #1 is the cp1258 code (in hex)
+#        Column #2 is the Unicode (in hex as 0xXXXX)
+#        Column #3 is the Unicode name (follows a comment sign, '#')
+#
+#    The entries are in cp1258 order
+#
+0x00	0x0000	#NULL
+0x01	0x0001	#START OF HEADING
+0x02	0x0002	#START OF TEXT
+0x03	0x0003	#END OF TEXT
+0x04	0x0004	#END OF TRANSMISSION
+0x05	0x0005	#ENQUIRY
+0x06	0x0006	#ACKNOWLEDGE
+0x07	0x0007	#BELL
+0x08	0x0008	#BACKSPACE
+0x09	0x0009	#HORIZONTAL TABULATION
+0x0A	0x000A	#LINE FEED
+0x0B	0x000B	#VERTICAL TABULATION
+0x0C	0x000C	#FORM FEED
+0x0D	0x000D	#CARRIAGE RETURN
+0x0E	0x000E	#SHIFT OUT
+0x0F	0x000F	#SHIFT IN
+0x10	0x0010	#DATA LINK ESCAPE
+0x11	0x0011	#DEVICE CONTROL ONE
+0x12	0x0012	#DEVICE CONTROL TWO
+0x13	0x0013	#DEVICE CONTROL THREE
+0x14	0x0014	#DEVICE CONTROL FOUR
+0x15	0x0015	#NEGATIVE ACKNOWLEDGE
+0x16	0x0016	#SYNCHRONOUS IDLE
+0x17	0x0017	#END OF TRANSMISSION BLOCK
+0x18	0x0018	#CANCEL
+0x19	0x0019	#END OF MEDIUM
+0x1A	0x001A	#SUBSTITUTE
+0x1B	0x001B	#ESCAPE
+0x1C	0x001C	#FILE SEPARATOR
+0x1D	0x001D	#GROUP SEPARATOR
+0x1E	0x001E	#RECORD SEPARATOR
+0x1F	0x001F	#UNIT SEPARATOR
+0x20	0x0020	#SPACE
+0x21	0x0021	#EXCLAMATION MARK
+0x22	0x0022	#QUOTATION MARK
+0x23	0x0023	#NUMBER SIGN
+0x24	0x0024	#DOLLAR SIGN
+0x25	0x0025	#PERCENT SIGN
+0x26	0x0026	#AMPERSAND
+0x27	0x0027	#APOSTROPHE
+0x28	0x0028	#LEFT PARENTHESIS
+0x29	0x0029	#RIGHT PARENTHESIS
+0x2A	0x002A	#ASTERISK
+0x2B	0x002B	#PLUS SIGN
+0x2C	0x002C	#COMMA
+0x2D	0x002D	#HYPHEN-MINUS
+0x2E	0x002E	#FULL STOP
+0x2F	0x002F	#SOLIDUS
+0x30	0x0030	#DIGIT ZERO
+0x31	0x0031	#DIGIT ONE
+0x32	0x0032	#DIGIT TWO
+0x33	0x0033	#DIGIT THREE
+0x34	0x0034	#DIGIT FOUR
+0x35	0x0035	#DIGIT FIVE
+0x36	0x0036	#DIGIT SIX
+0x37	0x0037	#DIGIT SEVEN
+0x38	0x0038	#DIGIT EIGHT
+0x39	0x0039	#DIGIT NINE
+0x3A	0x003A	#COLON
+0x3B	0x003B	#SEMICOLON
+0x3C	0x003C	#LESS-THAN SIGN
+0x3D	0x003D	#EQUALS SIGN
+0x3E	0x003E	#GREATER-THAN SIGN
+0x3F	0x003F	#QUESTION MARK
+0x40	0x0040	#COMMERCIAL AT
+0x41	0x0041	#LATIN CAPITAL LETTER A
+0x42	0x0042	#LATIN CAPITAL LETTER B
+0x43	0x0043	#LATIN CAPITAL LETTER C
+0x44	0x0044	#LATIN CAPITAL LETTER D
+0x45	0x0045	#LATIN CAPITAL LETTER E
+0x46	0x0046	#LATIN CAPITAL LETTER F
+0x47	0x0047	#LATIN CAPITAL LETTER G
+0x48	0x0048	#LATIN CAPITAL LETTER H
+0x49	0x0049	#LATIN CAPITAL LETTER I
+0x4A	0x004A	#LATIN CAPITAL LETTER J
+0x4B	0x004B	#LATIN CAPITAL LETTER K
+0x4C	0x004C	#LATIN CAPITAL LETTER L
+0x4D	0x004D	#LATIN CAPITAL LETTER M
+0x4E	0x004E	#LATIN CAPITAL LETTER N
+0x4F	0x004F	#LATIN CAPITAL LETTER O
+0x50	0x0050	#LATIN CAPITAL LETTER P
+0x51	0x0051	#LATIN CAPITAL LETTER Q
+0x52	0x0052	#LATIN CAPITAL LETTER R
+0x53	0x0053	#LATIN CAPITAL LETTER S
+0x54	0x0054	#LATIN CAPITAL LETTER T
+0x55	0x0055	#LATIN CAPITAL LETTER U
+0x56	0x0056	#LATIN CAPITAL LETTER V
+0x57	0x0057	#LATIN CAPITAL LETTER W
+0x58	0x0058	#LATIN CAPITAL LETTER X
+0x59	0x0059	#LATIN CAPITAL LETTER Y
+0x5A	0x005A	#LATIN CAPITAL LETTER Z
+0x5B	0x005B	#LEFT SQUARE BRACKET
+0x5C	0x005C	#REVERSE SOLIDUS
+0x5D	0x005D	#RIGHT SQUARE BRACKET
+0x5E	0x005E	#CIRCUMFLEX ACCENT
+0x5F	0x005F	#LOW LINE
+0x60	0x0060	#GRAVE ACCENT
+0x61	0x0061	#LATIN SMALL LETTER A
+0x62	0x0062	#LATIN SMALL LETTER B
+0x63	0x0063	#LATIN SMALL LETTER C
+0x64	0x0064	#LATIN SMALL LETTER D
+0x65	0x0065	#LATIN SMALL LETTER E
+0x66	0x0066	#LATIN SMALL LETTER F
+0x67	0x0067	#LATIN SMALL LETTER G
+0x68	0x0068	#LATIN SMALL LETTER H
+0x69	0x0069	#LATIN SMALL LETTER I
+0x6A	0x006A	#LATIN SMALL LETTER J
+0x6B	0x006B	#LATIN SMALL LETTER K
+0x6C	0x006C	#LATIN SMALL LETTER L
+0x6D	0x006D	#LATIN SMALL LETTER M
+0x6E	0x006E	#LATIN SMALL LETTER N
+0x6F	0x006F	#LATIN SMALL LETTER O
+0x70	0x0070	#LATIN SMALL LETTER P
+0x71	0x0071	#LATIN SMALL LETTER Q
+0x72	0x0072	#LATIN SMALL LETTER R
+0x73	0x0073	#LATIN SMALL LETTER S
+0x74	0x0074	#LATIN SMALL LETTER T
+0x75	0x0075	#LATIN SMALL LETTER U
+0x76	0x0076	#LATIN SMALL LETTER V
+0x77	0x0077	#LATIN SMALL LETTER W
+0x78	0x0078	#LATIN SMALL LETTER X
+0x79	0x0079	#LATIN SMALL LETTER Y
+0x7A	0x007A	#LATIN SMALL LETTER Z
+0x7B	0x007B	#LEFT CURLY BRACKET
+0x7C	0x007C	#VERTICAL LINE
+0x7D	0x007D	#RIGHT CURLY BRACKET
+0x7E	0x007E	#TILDE
+0x7F	0x007F	#DELETE
+0x80	0x20AC	#EURO SIGN
+0x81	      	#UNDEFINED
+0x82	0x201A	#SINGLE LOW-9 QUOTATION MARK
+0x83	0x0192	#LATIN SMALL LETTER F WITH HOOK
+0x84	0x201E	#DOUBLE LOW-9 QUOTATION MARK
+0x85	0x2026	#HORIZONTAL ELLIPSIS
+0x86	0x2020	#DAGGER
+0x87	0x2021	#DOUBLE DAGGER
+0x88	0x02C6	#MODIFIER LETTER CIRCUMFLEX ACCENT
+0x89	0x2030	#PER MILLE SIGN
+0x8A	      	#UNDEFINED
+0x8B	0x2039	#SINGLE LEFT-POINTING ANGLE QUOTATION MARK
+0x8C	0x0152	#LATIN CAPITAL LIGATURE OE
+0x8D	      	#UNDEFINED
+0x8E	      	#UNDEFINED
+0x8F	      	#UNDEFINED
+0x90	      	#UNDEFINED
+0x91	0x2018	#LEFT SINGLE QUOTATION MARK
+0x92	0x2019	#RIGHT SINGLE QUOTATION MARK
+0x93	0x201C	#LEFT DOUBLE QUOTATION MARK
+0x94	0x201D	#RIGHT DOUBLE QUOTATION MARK
+0x95	0x2022	#BULLET
+0x96	0x2013	#EN DASH
+0x97	0x2014	#EM DASH
+0x98	0x02DC	#SMALL TILDE
+0x99	0x2122	#TRADE MARK SIGN
+0x9A	      	#UNDEFINED
+0x9B	0x203A	#SINGLE RIGHT-POINTING ANGLE QUOTATION MARK
+0x9C	0x0153	#LATIN SMALL LIGATURE OE
+0x9D	      	#UNDEFINED
+0x9E	      	#UNDEFINED
+0x9F	0x0178	#LATIN CAPITAL LETTER Y WITH DIAERESIS
+0xA0	0x00A0	#NO-BREAK SPACE
+0xA1	0x00A1	#INVERTED EXCLAMATION MARK
+0xA2	0x00A2	#CENT SIGN
+0xA3	0x00A3	#POUND SIGN
+0xA4	0x00A4	#CURRENCY SIGN
+0xA5	0x00A5	#YEN SIGN
+0xA6	0x00A6	#BROKEN BAR
+0xA7	0x00A7	#SECTION SIGN
+0xA8	0x00A8	#DIAERESIS
+0xA9	0x00A9	#COPYRIGHT SIGN
+0xAA	0x00AA	#FEMININE ORDINAL INDICATOR
+0xAB	0x00AB	#LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+0xAC	0x00AC	#NOT SIGN
+0xAD	0x00AD	#SOFT HYPHEN
+0xAE	0x00AE	#REGISTERED SIGN
+0xAF	0x00AF	#MACRON
+0xB0	0x00B0	#DEGREE SIGN
+0xB1	0x00B1	#PLUS-MINUS SIGN
+0xB2	0x00B2	#SUPERSCRIPT TWO
+0xB3	0x00B3	#SUPERSCRIPT THREE
+0xB4	0x00B4	#ACUTE ACCENT
+0xB5	0x00B5	#MICRO SIGN
+0xB6	0x00B6	#PILCROW SIGN
+0xB7	0x00B7	#MIDDLE DOT
+0xB8	0x00B8	#CEDILLA
+0xB9	0x00B9	#SUPERSCRIPT ONE
+0xBA	0x00BA	#MASCULINE ORDINAL INDICATOR
+0xBB	0x00BB	#RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+0xBC	0x00BC	#VULGAR FRACTION ONE QUARTER
+0xBD	0x00BD	#VULGAR FRACTION ONE HALF
+0xBE	0x00BE	#VULGAR FRACTION THREE QUARTERS
+0xBF	0x00BF	#INVERTED QUESTION MARK
+0xC0	0x00C0	#LATIN CAPITAL LETTER A WITH GRAVE
+0xC1	0x00C1	#LATIN CAPITAL LETTER A WITH ACUTE
+0xC2	0x00C2	#LATIN CAPITAL LETTER A WITH CIRCUMFLEX
+0xC3	0x0102	#LATIN CAPITAL LETTER A WITH BREVE
+0xC4	0x00C4	#LATIN CAPITAL LETTER A WITH DIAERESIS
+0xC5	0x00C5	#LATIN CAPITAL LETTER A WITH RING ABOVE
+0xC6	0x00C6	#LATIN CAPITAL LETTER AE
+0xC7	0x00C7	#LATIN CAPITAL LETTER C WITH CEDILLA
+0xC8	0x00C8	#LATIN CAPITAL LETTER E WITH GRAVE
+0xC9	0x00C9	#LATIN CAPITAL LETTER E WITH ACUTE
+0xCA	0x00CA	#LATIN CAPITAL LETTER E WITH CIRCUMFLEX
+0xCB	0x00CB	#LATIN CAPITAL LETTER E WITH DIAERESIS
+0xCC	0x0300	#COMBINING GRAVE ACCENT
+0xCD	0x00CD	#LATIN CAPITAL LETTER I WITH ACUTE
+0xCE	0x00CE	#LATIN CAPITAL LETTER I WITH CIRCUMFLEX
+0xCF	0x00CF	#LATIN CAPITAL LETTER I WITH DIAERESIS
+0xD0	0x0110	#LATIN CAPITAL LETTER D WITH STROKE
+0xD1	0x00D1	#LATIN CAPITAL LETTER N WITH TILDE
+0xD2	0x0309	#COMBINING HOOK ABOVE
+0xD3	0x00D3	#LATIN CAPITAL LETTER O WITH ACUTE
+0xD4	0x00D4	#LATIN CAPITAL LETTER O WITH CIRCUMFLEX
+0xD5	0x01A0	#LATIN CAPITAL LETTER O WITH HORN
+0xD6	0x00D6	#LATIN CAPITAL LETTER O WITH DIAERESIS
+0xD7	0x00D7	#MULTIPLICATION SIGN
+0xD8	0x00D8	#LATIN CAPITAL LETTER O WITH STROKE
+0xD9	0x00D9	#LATIN CAPITAL LETTER U WITH GRAVE
+0xDA	0x00DA	#LATIN CAPITAL LETTER U WITH ACUTE
+0xDB	0x00DB	#LATIN CAPITAL LETTER U WITH CIRCUMFLEX
+0xDC	0x00DC	#LATIN CAPITAL LETTER U WITH DIAERESIS
+0xDD	0x01AF	#LATIN CAPITAL LETTER U WITH HORN
+0xDE	0x0303	#COMBINING TILDE
+0xDF	0x00DF	#LATIN SMALL LETTER SHARP S
+0xE0	0x00E0	#LATIN SMALL LETTER A WITH GRAVE
+0xE1	0x00E1	#LATIN SMALL LETTER A WITH ACUTE
+0xE2	0x00E2	#LATIN SMALL LETTER A WITH CIRCUMFLEX
+0xE3	0x0103	#LATIN SMALL LETTER A WITH BREVE
+0xE4	0x00E4	#LATIN SMALL LETTER A WITH DIAERESIS
+0xE5	0x00E5	#LATIN SMALL LETTER A WITH RING ABOVE
+0xE6	0x00E6	#LATIN SMALL LETTER AE
+0xE7	0x00E7	#LATIN SMALL LETTER C WITH CEDILLA
+0xE8	0x00E8	#LATIN SMALL LETTER E WITH GRAVE
+0xE9	0x00E9	#LATIN SMALL LETTER E WITH ACUTE
+0xEA	0x00EA	#LATIN SMALL LETTER E WITH CIRCUMFLEX
+0xEB	0x00EB	#LATIN SMALL LETTER E WITH DIAERESIS
+0xEC	0x0301	#COMBINING ACUTE ACCENT
+0xED	0x00ED	#LATIN SMALL LETTER I WITH ACUTE
+0xEE	0x00EE	#LATIN SMALL LETTER I WITH CIRCUMFLEX
+0xEF	0x00EF	#LATIN SMALL LETTER I WITH DIAERESIS
+0xF0	0x0111	#LATIN SMALL LETTER D WITH STROKE
+0xF1	0x00F1	#LATIN SMALL LETTER N WITH TILDE
+0xF2	0x0323	#COMBINING DOT BELOW
+0xF3	0x00F3	#LATIN SMALL LETTER O WITH ACUTE
+0xF4	0x00F4	#LATIN SMALL LETTER O WITH CIRCUMFLEX
+0xF5	0x01A1	#LATIN SMALL LETTER O WITH HORN
+0xF6	0x00F6	#LATIN SMALL LETTER O WITH DIAERESIS
+0xF7	0x00F7	#DIVISION SIGN
+0xF8	0x00F8	#LATIN SMALL LETTER O WITH STROKE
+0xF9	0x00F9	#LATIN SMALL LETTER U WITH GRAVE
+0xFA	0x00FA	#LATIN SMALL LETTER U WITH ACUTE
+0xFB	0x00FB	#LATIN SMALL LETTER U WITH CIRCUMFLEX
+0xFC	0x00FC	#LATIN SMALL LETTER U WITH DIAERESIS
+0xFD	0x01B0	#LATIN SMALL LETTER U WITH HORN
+0xFE	0x20AB	#DONG SIGN
+0xFF	0x00FF	#LATIN SMALL LETTER Y WITH DIAERESIS
diff --git a/tools/encoding/cp437.txt b/tools/encoding/cp437.txt
new file mode 100644
index 0000000..ae38e17
--- /dev/null
+++ b/tools/encoding/cp437.txt
@@ -0,0 +1,273 @@
+#
+#    Name:     cp437_DOSLatinUS to Unicode table
+#    Unicode version: 2.0
+#    Table version: 2.00
+#    Table format:  Format A
+#    Date:          04/24/96
+#    Authors:       Lori Brownell <loribr@microsoft.com>
+#                   K.D. Chang    <a-kchang@microsoft.com>
+#    General notes: none
+#
+#    Format: Three tab-separated columns
+#        Column #1 is the cp437_DOSLatinUS code (in hex)
+#        Column #2 is the Unicode (in hex as 0xXXXX)
+#        Column #3 is the Unicode name (follows a comment sign, '#')
+#
+#    The entries are in cp437_DOSLatinUS order
+#
+0x00	0x0000	#NULL
+0x01	0x0001	#START OF HEADING
+0x02	0x0002	#START OF TEXT
+0x03	0x0003	#END OF TEXT
+0x04	0x0004	#END OF TRANSMISSION
+0x05	0x0005	#ENQUIRY
+0x06	0x0006	#ACKNOWLEDGE
+0x07	0x0007	#BELL
+0x08	0x0008	#BACKSPACE
+0x09	0x0009	#HORIZONTAL TABULATION
+0x0a	0x000a	#LINE FEED
+0x0b	0x000b	#VERTICAL TABULATION
+0x0c	0x000c	#FORM FEED
+0x0d	0x000d	#CARRIAGE RETURN
+0x0e	0x000e	#SHIFT OUT
+0x0f	0x000f	#SHIFT IN
+0x10	0x0010	#DATA LINK ESCAPE
+0x11	0x0011	#DEVICE CONTROL ONE
+0x12	0x0012	#DEVICE CONTROL TWO
+0x13	0x0013	#DEVICE CONTROL THREE
+0x14	0x0014	#DEVICE CONTROL FOUR
+0x15	0x0015	#NEGATIVE ACKNOWLEDGE
+0x16	0x0016	#SYNCHRONOUS IDLE
+0x17	0x0017	#END OF TRANSMISSION BLOCK
+0x18	0x0018	#CANCEL
+0x19	0x0019	#END OF MEDIUM
+0x1a	0x001a	#SUBSTITUTE
+0x1b	0x001b	#ESCAPE
+0x1c	0x001c	#FILE SEPARATOR
+0x1d	0x001d	#GROUP SEPARATOR
+0x1e	0x001e	#RECORD SEPARATOR
+0x1f	0x001f	#UNIT SEPARATOR
+0x20	0x0020	#SPACE
+0x21	0x0021	#EXCLAMATION MARK
+0x22	0x0022	#QUOTATION MARK
+0x23	0x0023	#NUMBER SIGN
+0x24	0x0024	#DOLLAR SIGN
+0x25	0x0025	#PERCENT SIGN
+0x26	0x0026	#AMPERSAND
+0x27	0x0027	#APOSTROPHE
+0x28	0x0028	#LEFT PARENTHESIS
+0x29	0x0029	#RIGHT PARENTHESIS
+0x2a	0x002a	#ASTERISK
+0x2b	0x002b	#PLUS SIGN
+0x2c	0x002c	#COMMA
+0x2d	0x002d	#HYPHEN-MINUS
+0x2e	0x002e	#FULL STOP
+0x2f	0x002f	#SOLIDUS
+0x30	0x0030	#DIGIT ZERO
+0x31	0x0031	#DIGIT ONE
+0x32	0x0032	#DIGIT TWO
+0x33	0x0033	#DIGIT THREE
+0x34	0x0034	#DIGIT FOUR
+0x35	0x0035	#DIGIT FIVE
+0x36	0x0036	#DIGIT SIX
+0x37	0x0037	#DIGIT SEVEN
+0x38	0x0038	#DIGIT EIGHT
+0x39	0x0039	#DIGIT NINE
+0x3a	0x003a	#COLON
+0x3b	0x003b	#SEMICOLON
+0x3c	0x003c	#LESS-THAN SIGN
+0x3d	0x003d	#EQUALS SIGN
+0x3e	0x003e	#GREATER-THAN SIGN
+0x3f	0x003f	#QUESTION MARK
+0x40	0x0040	#COMMERCIAL AT
+0x41	0x0041	#LATIN CAPITAL LETTER A
+0x42	0x0042	#LATIN CAPITAL LETTER B
+0x43	0x0043	#LATIN CAPITAL LETTER C
+0x44	0x0044	#LATIN CAPITAL LETTER D
+0x45	0x0045	#LATIN CAPITAL LETTER E
+0x46	0x0046	#LATIN CAPITAL LETTER F
+0x47	0x0047	#LATIN CAPITAL LETTER G
+0x48	0x0048	#LATIN CAPITAL LETTER H
+0x49	0x0049	#LATIN CAPITAL LETTER I
+0x4a	0x004a	#LATIN CAPITAL LETTER J
+0x4b	0x004b	#LATIN CAPITAL LETTER K
+0x4c	0x004c	#LATIN CAPITAL LETTER L
+0x4d	0x004d	#LATIN CAPITAL LETTER M
+0x4e	0x004e	#LATIN CAPITAL LETTER N
+0x4f	0x004f	#LATIN CAPITAL LETTER O
+0x50	0x0050	#LATIN CAPITAL LETTER P
+0x51	0x0051	#LATIN CAPITAL LETTER Q
+0x52	0x0052	#LATIN CAPITAL LETTER R
+0x53	0x0053	#LATIN CAPITAL LETTER S
+0x54	0x0054	#LATIN CAPITAL LETTER T
+0x55	0x0055	#LATIN CAPITAL LETTER U
+0x56	0x0056	#LATIN CAPITAL LETTER V
+0x57	0x0057	#LATIN CAPITAL LETTER W
+0x58	0x0058	#LATIN CAPITAL LETTER X
+0x59	0x0059	#LATIN CAPITAL LETTER Y
+0x5a	0x005a	#LATIN CAPITAL LETTER Z
+0x5b	0x005b	#LEFT SQUARE BRACKET
+0x5c	0x005c	#REVERSE SOLIDUS
+0x5d	0x005d	#RIGHT SQUARE BRACKET
+0x5e	0x005e	#CIRCUMFLEX ACCENT
+0x5f	0x005f	#LOW LINE
+0x60	0x0060	#GRAVE ACCENT
+0x61	0x0061	#LATIN SMALL LETTER A
+0x62	0x0062	#LATIN SMALL LETTER B
+0x63	0x0063	#LATIN SMALL LETTER C
+0x64	0x0064	#LATIN SMALL LETTER D
+0x65	0x0065	#LATIN SMALL LETTER E
+0x66	0x0066	#LATIN SMALL LETTER F
+0x67	0x0067	#LATIN SMALL LETTER G
+0x68	0x0068	#LATIN SMALL LETTER H
+0x69	0x0069	#LATIN SMALL LETTER I
+0x6a	0x006a	#LATIN SMALL LETTER J
+0x6b	0x006b	#LATIN SMALL LETTER K
+0x6c	0x006c	#LATIN SMALL LETTER L
+0x6d	0x006d	#LATIN SMALL LETTER M
+0x6e	0x006e	#LATIN SMALL LETTER N
+0x6f	0x006f	#LATIN SMALL LETTER O
+0x70	0x0070	#LATIN SMALL LETTER P
+0x71	0x0071	#LATIN SMALL LETTER Q
+0x72	0x0072	#LATIN SMALL LETTER R
+0x73	0x0073	#LATIN SMALL LETTER S
+0x74	0x0074	#LATIN SMALL LETTER T
+0x75	0x0075	#LATIN SMALL LETTER U
+0x76	0x0076	#LATIN SMALL LETTER V
+0x77	0x0077	#LATIN SMALL LETTER W
+0x78	0x0078	#LATIN SMALL LETTER X
+0x79	0x0079	#LATIN SMALL LETTER Y
+0x7a	0x007a	#LATIN SMALL LETTER Z
+0x7b	0x007b	#LEFT CURLY BRACKET
+0x7c	0x007c	#VERTICAL LINE
+0x7d	0x007d	#RIGHT CURLY BRACKET
+0x7e	0x007e	#TILDE
+0x7f	0x007f	#DELETE
+0x80	0x00c7	#LATIN CAPITAL LETTER C WITH CEDILLA
+0x81	0x00fc	#LATIN SMALL LETTER U WITH DIAERESIS
+0x82	0x00e9	#LATIN SMALL LETTER E WITH ACUTE
+0x83	0x00e2	#LATIN SMALL LETTER A WITH CIRCUMFLEX
+0x84	0x00e4	#LATIN SMALL LETTER A WITH DIAERESIS
+0x85	0x00e0	#LATIN SMALL LETTER A WITH GRAVE
+0x86	0x00e5	#LATIN SMALL LETTER A WITH RING ABOVE
+0x87	0x00e7	#LATIN SMALL LETTER C WITH CEDILLA
+0x88	0x00ea	#LATIN SMALL LETTER E WITH CIRCUMFLEX
+0x89	0x00eb	#LATIN SMALL LETTER E WITH DIAERESIS
+0x8a	0x00e8	#LATIN SMALL LETTER E WITH GRAVE
+0x8b	0x00ef	#LATIN SMALL LETTER I WITH DIAERESIS
+0x8c	0x00ee	#LATIN SMALL LETTER I WITH CIRCUMFLEX
+0x8d	0x00ec	#LATIN SMALL LETTER I WITH GRAVE
+0x8e	0x00c4	#LATIN CAPITAL LETTER A WITH DIAERESIS
+0x8f	0x00c5	#LATIN CAPITAL LETTER A WITH RING ABOVE
+0x90	0x00c9	#LATIN CAPITAL LETTER E WITH ACUTE
+0x91	0x00e6	#LATIN SMALL LIGATURE AE
+0x92	0x00c6	#LATIN CAPITAL LIGATURE AE
+0x93	0x00f4	#LATIN SMALL LETTER O WITH CIRCUMFLEX
+0x94	0x00f6	#LATIN SMALL LETTER O WITH DIAERESIS
+0x95	0x00f2	#LATIN SMALL LETTER O WITH GRAVE
+0x96	0x00fb	#LATIN SMALL LETTER U WITH CIRCUMFLEX
+0x97	0x00f9	#LATIN SMALL LETTER U WITH GRAVE
+0x98	0x00ff	#LATIN SMALL LETTER Y WITH DIAERESIS
+0x99	0x00d6	#LATIN CAPITAL LETTER O WITH DIAERESIS
+0x9a	0x00dc	#LATIN CAPITAL LETTER U WITH DIAERESIS
+0x9b	0x00a2	#CENT SIGN
+0x9c	0x00a3	#POUND SIGN
+0x9d	0x00a5	#YEN SIGN
+0x9e	0x20a7	#PESETA SIGN
+0x9f	0x0192	#LATIN SMALL LETTER F WITH HOOK
+0xa0	0x00e1	#LATIN SMALL LETTER A WITH ACUTE
+0xa1	0x00ed	#LATIN SMALL LETTER I WITH ACUTE
+0xa2	0x00f3	#LATIN SMALL LETTER O WITH ACUTE
+0xa3	0x00fa	#LATIN SMALL LETTER U WITH ACUTE
+0xa4	0x00f1	#LATIN SMALL LETTER N WITH TILDE
+0xa5	0x00d1	#LATIN CAPITAL LETTER N WITH TILDE
+0xa6	0x00aa	#FEMININE ORDINAL INDICATOR
+0xa7	0x00ba	#MASCULINE ORDINAL INDICATOR
+0xa8	0x00bf	#INVERTED QUESTION MARK
+0xa9	0x2310	#REVERSED NOT SIGN
+0xaa	0x00ac	#NOT SIGN
+0xab	0x00bd	#VULGAR FRACTION ONE HALF
+0xac	0x00bc	#VULGAR FRACTION ONE QUARTER
+0xad	0x00a1	#INVERTED EXCLAMATION MARK
+0xae	0x00ab	#LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+0xaf	0x00bb	#RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+0xb0	0x2591	#LIGHT SHADE
+0xb1	0x2592	#MEDIUM SHADE
+0xb2	0x2593	#DARK SHADE
+0xb3	0x2502	#BOX DRAWINGS LIGHT VERTICAL
+0xb4	0x2524	#BOX DRAWINGS LIGHT VERTICAL AND LEFT
+0xb5	0x2561	#BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE
+0xb6	0x2562	#BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE
+0xb7	0x2556	#BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE
+0xb8	0x2555	#BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE
+0xb9	0x2563	#BOX DRAWINGS DOUBLE VERTICAL AND LEFT
+0xba	0x2551	#BOX DRAWINGS DOUBLE VERTICAL
+0xbb	0x2557	#BOX DRAWINGS DOUBLE DOWN AND LEFT
+0xbc	0x255d	#BOX DRAWINGS DOUBLE UP AND LEFT
+0xbd	0x255c	#BOX DRAWINGS UP DOUBLE AND LEFT SINGLE
+0xbe	0x255b	#BOX DRAWINGS UP SINGLE AND LEFT DOUBLE
+0xbf	0x2510	#BOX DRAWINGS LIGHT DOWN AND LEFT
+0xc0	0x2514	#BOX DRAWINGS LIGHT UP AND RIGHT
+0xc1	0x2534	#BOX DRAWINGS LIGHT UP AND HORIZONTAL
+0xc2	0x252c	#BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
+0xc3	0x251c	#BOX DRAWINGS LIGHT VERTICAL AND RIGHT
+0xc4	0x2500	#BOX DRAWINGS LIGHT HORIZONTAL
+0xc5	0x253c	#BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
+0xc6	0x255e	#BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE
+0xc7	0x255f	#BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE
+0xc8	0x255a	#BOX DRAWINGS DOUBLE UP AND RIGHT
+0xc9	0x2554	#BOX DRAWINGS DOUBLE DOWN AND RIGHT
+0xca	0x2569	#BOX DRAWINGS DOUBLE UP AND HORIZONTAL
+0xcb	0x2566	#BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL
+0xcc	0x2560	#BOX DRAWINGS DOUBLE VERTICAL AND RIGHT
+0xcd	0x2550	#BOX DRAWINGS DOUBLE HORIZONTAL
+0xce	0x256c	#BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL
+0xcf	0x2567	#BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE
+0xd0	0x2568	#BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE
+0xd1	0x2564	#BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE
+0xd2	0x2565	#BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE
+0xd3	0x2559	#BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE
+0xd4	0x2558	#BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE
+0xd5	0x2552	#BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE
+0xd6	0x2553	#BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE
+0xd7	0x256b	#BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE
+0xd8	0x256a	#BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE
+0xd9	0x2518	#BOX DRAWINGS LIGHT UP AND LEFT
+0xda	0x250c	#BOX DRAWINGS LIGHT DOWN AND RIGHT
+0xdb	0x2588	#FULL BLOCK
+0xdc	0x2584	#LOWER HALF BLOCK
+0xdd	0x258c	#LEFT HALF BLOCK
+0xde	0x2590	#RIGHT HALF BLOCK
+0xdf	0x2580	#UPPER HALF BLOCK
+0xe0	0x03b1	#GREEK SMALL LETTER ALPHA
+0xe1	0x00df	#LATIN SMALL LETTER SHARP S
+0xe2	0x0393	#GREEK CAPITAL LETTER GAMMA
+0xe3	0x03c0	#GREEK SMALL LETTER PI
+0xe4	0x03a3	#GREEK CAPITAL LETTER SIGMA
+0xe5	0x03c3	#GREEK SMALL LETTER SIGMA
+0xe6	0x00b5	#MICRO SIGN
+0xe7	0x03c4	#GREEK SMALL LETTER TAU
+0xe8	0x03a6	#GREEK CAPITAL LETTER PHI
+0xe9	0x0398	#GREEK CAPITAL LETTER THETA
+0xea	0x03a9	#GREEK CAPITAL LETTER OMEGA
+0xeb	0x03b4	#GREEK SMALL LETTER DELTA
+0xec	0x221e	#INFINITY
+0xed	0x03c6	#GREEK SMALL LETTER PHI
+0xee	0x03b5	#GREEK SMALL LETTER EPSILON
+0xef	0x2229	#INTERSECTION
+0xf0	0x2261	#IDENTICAL TO
+0xf1	0x00b1	#PLUS-MINUS SIGN
+0xf2	0x2265	#GREATER-THAN OR EQUAL TO
+0xf3	0x2264	#LESS-THAN OR EQUAL TO
+0xf4	0x2320	#TOP HALF INTEGRAL
+0xf5	0x2321	#BOTTOM HALF INTEGRAL
+0xf6	0x00f7	#DIVISION SIGN
+0xf7	0x2248	#ALMOST EQUAL TO
+0xf8	0x00b0	#DEGREE SIGN
+0xf9	0x2219	#BULLET OPERATOR
+0xfa	0x00b7	#MIDDLE DOT
+0xfb	0x221a	#SQUARE ROOT
+0xfc	0x207f	#SUPERSCRIPT LATIN SMALL LETTER N
+0xfd	0x00b2	#SUPERSCRIPT TWO
+0xfe	0x25a0	#BLACK SQUARE
+0xff	0x00a0	#NO-BREAK SPACE
diff --git a/tools/encoding/cp737.txt b/tools/encoding/cp737.txt
new file mode 100644
index 0000000..0fc572f
--- /dev/null
+++ b/tools/encoding/cp737.txt
@@ -0,0 +1,273 @@
+#
+#    Name:     cp737_DOSGreek to Unicode table
+#    Unicode version: 2.0
+#    Table version: 2.00
+#    Table format:  Format A
+#    Date:          04/24/96
+#    Authors:       Lori Brownell <loribr@microsoft.com>
+#                   K.D. Chang    <a-kchang@microsoft.com>
+#    General notes: none
+#
+#    Format: Three tab-separated columns
+#        Column #1 is the cp737_DOSGreek code (in hex)
+#        Column #2 is the Unicode (in hex as 0xXXXX)
+#        Column #3 is the Unicode name (follows a comment sign, '#')
+#
+#    The entries are in cp737_DOSGreek order
+#
+0x00	0x0000	#NULL
+0x01	0x0001	#START OF HEADING
+0x02	0x0002	#START OF TEXT
+0x03	0x0003	#END OF TEXT
+0x04	0x0004	#END OF TRANSMISSION
+0x05	0x0005	#ENQUIRY
+0x06	0x0006	#ACKNOWLEDGE
+0x07	0x0007	#BELL
+0x08	0x0008	#BACKSPACE
+0x09	0x0009	#HORIZONTAL TABULATION
+0x0a	0x000a	#LINE FEED
+0x0b	0x000b	#VERTICAL TABULATION
+0x0c	0x000c	#FORM FEED
+0x0d	0x000d	#CARRIAGE RETURN
+0x0e	0x000e	#SHIFT OUT
+0x0f	0x000f	#SHIFT IN
+0x10	0x0010	#DATA LINK ESCAPE
+0x11	0x0011	#DEVICE CONTROL ONE
+0x12	0x0012	#DEVICE CONTROL TWO
+0x13	0x0013	#DEVICE CONTROL THREE
+0x14	0x0014	#DEVICE CONTROL FOUR
+0x15	0x0015	#NEGATIVE ACKNOWLEDGE
+0x16	0x0016	#SYNCHRONOUS IDLE
+0x17	0x0017	#END OF TRANSMISSION BLOCK
+0x18	0x0018	#CANCEL
+0x19	0x0019	#END OF MEDIUM
+0x1a	0x001a	#SUBSTITUTE
+0x1b	0x001b	#ESCAPE
+0x1c	0x001c	#FILE SEPARATOR
+0x1d	0x001d	#GROUP SEPARATOR
+0x1e	0x001e	#RECORD SEPARATOR
+0x1f	0x001f	#UNIT SEPARATOR
+0x20	0x0020	#SPACE
+0x21	0x0021	#EXCLAMATION MARK
+0x22	0x0022	#QUOTATION MARK
+0x23	0x0023	#NUMBER SIGN
+0x24	0x0024	#DOLLAR SIGN
+0x25	0x0025	#PERCENT SIGN
+0x26	0x0026	#AMPERSAND
+0x27	0x0027	#APOSTROPHE
+0x28	0x0028	#LEFT PARENTHESIS
+0x29	0x0029	#RIGHT PARENTHESIS
+0x2a	0x002a	#ASTERISK
+0x2b	0x002b	#PLUS SIGN
+0x2c	0x002c	#COMMA
+0x2d	0x002d	#HYPHEN-MINUS
+0x2e	0x002e	#FULL STOP
+0x2f	0x002f	#SOLIDUS
+0x30	0x0030	#DIGIT ZERO
+0x31	0x0031	#DIGIT ONE
+0x32	0x0032	#DIGIT TWO
+0x33	0x0033	#DIGIT THREE
+0x34	0x0034	#DIGIT FOUR
+0x35	0x0035	#DIGIT FIVE
+0x36	0x0036	#DIGIT SIX
+0x37	0x0037	#DIGIT SEVEN
+0x38	0x0038	#DIGIT EIGHT
+0x39	0x0039	#DIGIT NINE
+0x3a	0x003a	#COLON
+0x3b	0x003b	#SEMICOLON
+0x3c	0x003c	#LESS-THAN SIGN
+0x3d	0x003d	#EQUALS SIGN
+0x3e	0x003e	#GREATER-THAN SIGN
+0x3f	0x003f	#QUESTION MARK
+0x40	0x0040	#COMMERCIAL AT
+0x41	0x0041	#LATIN CAPITAL LETTER A
+0x42	0x0042	#LATIN CAPITAL LETTER B
+0x43	0x0043	#LATIN CAPITAL LETTER C
+0x44	0x0044	#LATIN CAPITAL LETTER D
+0x45	0x0045	#LATIN CAPITAL LETTER E
+0x46	0x0046	#LATIN CAPITAL LETTER F
+0x47	0x0047	#LATIN CAPITAL LETTER G
+0x48	0x0048	#LATIN CAPITAL LETTER H
+0x49	0x0049	#LATIN CAPITAL LETTER I
+0x4a	0x004a	#LATIN CAPITAL LETTER J
+0x4b	0x004b	#LATIN CAPITAL LETTER K
+0x4c	0x004c	#LATIN CAPITAL LETTER L
+0x4d	0x004d	#LATIN CAPITAL LETTER M
+0x4e	0x004e	#LATIN CAPITAL LETTER N
+0x4f	0x004f	#LATIN CAPITAL LETTER O
+0x50	0x0050	#LATIN CAPITAL LETTER P
+0x51	0x0051	#LATIN CAPITAL LETTER Q
+0x52	0x0052	#LATIN CAPITAL LETTER R
+0x53	0x0053	#LATIN CAPITAL LETTER S
+0x54	0x0054	#LATIN CAPITAL LETTER T
+0x55	0x0055	#LATIN CAPITAL LETTER U
+0x56	0x0056	#LATIN CAPITAL LETTER V
+0x57	0x0057	#LATIN CAPITAL LETTER W
+0x58	0x0058	#LATIN CAPITAL LETTER X
+0x59	0x0059	#LATIN CAPITAL LETTER Y
+0x5a	0x005a	#LATIN CAPITAL LETTER Z
+0x5b	0x005b	#LEFT SQUARE BRACKET
+0x5c	0x005c	#REVERSE SOLIDUS
+0x5d	0x005d	#RIGHT SQUARE BRACKET
+0x5e	0x005e	#CIRCUMFLEX ACCENT
+0x5f	0x005f	#LOW LINE
+0x60	0x0060	#GRAVE ACCENT
+0x61	0x0061	#LATIN SMALL LETTER A
+0x62	0x0062	#LATIN SMALL LETTER B
+0x63	0x0063	#LATIN SMALL LETTER C
+0x64	0x0064	#LATIN SMALL LETTER D
+0x65	0x0065	#LATIN SMALL LETTER E
+0x66	0x0066	#LATIN SMALL LETTER F
+0x67	0x0067	#LATIN SMALL LETTER G
+0x68	0x0068	#LATIN SMALL LETTER H
+0x69	0x0069	#LATIN SMALL LETTER I
+0x6a	0x006a	#LATIN SMALL LETTER J
+0x6b	0x006b	#LATIN SMALL LETTER K
+0x6c	0x006c	#LATIN SMALL LETTER L
+0x6d	0x006d	#LATIN SMALL LETTER M
+0x6e	0x006e	#LATIN SMALL LETTER N
+0x6f	0x006f	#LATIN SMALL LETTER O
+0x70	0x0070	#LATIN SMALL LETTER P
+0x71	0x0071	#LATIN SMALL LETTER Q
+0x72	0x0072	#LATIN SMALL LETTER R
+0x73	0x0073	#LATIN SMALL LETTER S
+0x74	0x0074	#LATIN SMALL LETTER T
+0x75	0x0075	#LATIN SMALL LETTER U
+0x76	0x0076	#LATIN SMALL LETTER V
+0x77	0x0077	#LATIN SMALL LETTER W
+0x78	0x0078	#LATIN SMALL LETTER X
+0x79	0x0079	#LATIN SMALL LETTER Y
+0x7a	0x007a	#LATIN SMALL LETTER Z
+0x7b	0x007b	#LEFT CURLY BRACKET
+0x7c	0x007c	#VERTICAL LINE
+0x7d	0x007d	#RIGHT CURLY BRACKET
+0x7e	0x007e	#TILDE
+0x7f	0x007f	#DELETE
+0x80	0x0391	#GREEK CAPITAL LETTER ALPHA
+0x81	0x0392	#GREEK CAPITAL LETTER BETA
+0x82	0x0393	#GREEK CAPITAL LETTER GAMMA
+0x83	0x0394	#GREEK CAPITAL LETTER DELTA
+0x84	0x0395	#GREEK CAPITAL LETTER EPSILON
+0x85	0x0396	#GREEK CAPITAL LETTER ZETA
+0x86	0x0397	#GREEK CAPITAL LETTER ETA
+0x87	0x0398	#GREEK CAPITAL LETTER THETA
+0x88	0x0399	#GREEK CAPITAL LETTER IOTA
+0x89	0x039a	#GREEK CAPITAL LETTER KAPPA
+0x8a	0x039b	#GREEK CAPITAL LETTER LAMDA
+0x8b	0x039c	#GREEK CAPITAL LETTER MU
+0x8c	0x039d	#GREEK CAPITAL LETTER NU
+0x8d	0x039e	#GREEK CAPITAL LETTER XI
+0x8e	0x039f	#GREEK CAPITAL LETTER OMICRON
+0x8f	0x03a0	#GREEK CAPITAL LETTER PI
+0x90	0x03a1	#GREEK CAPITAL LETTER RHO
+0x91	0x03a3	#GREEK CAPITAL LETTER SIGMA
+0x92	0x03a4	#GREEK CAPITAL LETTER TAU
+0x93	0x03a5	#GREEK CAPITAL LETTER UPSILON
+0x94	0x03a6	#GREEK CAPITAL LETTER PHI
+0x95	0x03a7	#GREEK CAPITAL LETTER CHI
+0x96	0x03a8	#GREEK CAPITAL LETTER PSI
+0x97	0x03a9	#GREEK CAPITAL LETTER OMEGA
+0x98	0x03b1	#GREEK SMALL LETTER ALPHA
+0x99	0x03b2	#GREEK SMALL LETTER BETA
+0x9a	0x03b3	#GREEK SMALL LETTER GAMMA
+0x9b	0x03b4	#GREEK SMALL LETTER DELTA
+0x9c	0x03b5	#GREEK SMALL LETTER EPSILON
+0x9d	0x03b6	#GREEK SMALL LETTER ZETA
+0x9e	0x03b7	#GREEK SMALL LETTER ETA
+0x9f	0x03b8	#GREEK SMALL LETTER THETA
+0xa0	0x03b9	#GREEK SMALL LETTER IOTA
+0xa1	0x03ba	#GREEK SMALL LETTER KAPPA
+0xa2	0x03bb	#GREEK SMALL LETTER LAMDA
+0xa3	0x03bc	#GREEK SMALL LETTER MU
+0xa4	0x03bd	#GREEK SMALL LETTER NU
+0xa5	0x03be	#GREEK SMALL LETTER XI
+0xa6	0x03bf	#GREEK SMALL LETTER OMICRON
+0xa7	0x03c0	#GREEK SMALL LETTER PI
+0xa8	0x03c1	#GREEK SMALL LETTER RHO
+0xa9	0x03c3	#GREEK SMALL LETTER SIGMA
+0xaa	0x03c2	#GREEK SMALL LETTER FINAL SIGMA
+0xab	0x03c4	#GREEK SMALL LETTER TAU
+0xac	0x03c5	#GREEK SMALL LETTER UPSILON
+0xad	0x03c6	#GREEK SMALL LETTER PHI
+0xae	0x03c7	#GREEK SMALL LETTER CHI
+0xaf	0x03c8	#GREEK SMALL LETTER PSI
+0xb0	0x2591	#LIGHT SHADE
+0xb1	0x2592	#MEDIUM SHADE
+0xb2	0x2593	#DARK SHADE
+0xb3	0x2502	#BOX DRAWINGS LIGHT VERTICAL
+0xb4	0x2524	#BOX DRAWINGS LIGHT VERTICAL AND LEFT
+0xb5	0x2561	#BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE
+0xb6	0x2562	#BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE
+0xb7	0x2556	#BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE
+0xb8	0x2555	#BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE
+0xb9	0x2563	#BOX DRAWINGS DOUBLE VERTICAL AND LEFT
+0xba	0x2551	#BOX DRAWINGS DOUBLE VERTICAL
+0xbb	0x2557	#BOX DRAWINGS DOUBLE DOWN AND LEFT
+0xbc	0x255d	#BOX DRAWINGS DOUBLE UP AND LEFT
+0xbd	0x255c	#BOX DRAWINGS UP DOUBLE AND LEFT SINGLE
+0xbe	0x255b	#BOX DRAWINGS UP SINGLE AND LEFT DOUBLE
+0xbf	0x2510	#BOX DRAWINGS LIGHT DOWN AND LEFT
+0xc0	0x2514	#BOX DRAWINGS LIGHT UP AND RIGHT
+0xc1	0x2534	#BOX DRAWINGS LIGHT UP AND HORIZONTAL
+0xc2	0x252c	#BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
+0xc3	0x251c	#BOX DRAWINGS LIGHT VERTICAL AND RIGHT
+0xc4	0x2500	#BOX DRAWINGS LIGHT HORIZONTAL
+0xc5	0x253c	#BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
+0xc6	0x255e	#BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE
+0xc7	0x255f	#BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE
+0xc8	0x255a	#BOX DRAWINGS DOUBLE UP AND RIGHT
+0xc9	0x2554	#BOX DRAWINGS DOUBLE DOWN AND RIGHT
+0xca	0x2569	#BOX DRAWINGS DOUBLE UP AND HORIZONTAL
+0xcb	0x2566	#BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL
+0xcc	0x2560	#BOX DRAWINGS DOUBLE VERTICAL AND RIGHT
+0xcd	0x2550	#BOX DRAWINGS DOUBLE HORIZONTAL
+0xce	0x256c	#BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL
+0xcf	0x2567	#BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE
+0xd0	0x2568	#BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE
+0xd1	0x2564	#BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE
+0xd2	0x2565	#BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE
+0xd3	0x2559	#BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE
+0xd4	0x2558	#BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE
+0xd5	0x2552	#BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE
+0xd6	0x2553	#BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE
+0xd7	0x256b	#BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE
+0xd8	0x256a	#BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE
+0xd9	0x2518	#BOX DRAWINGS LIGHT UP AND LEFT
+0xda	0x250c	#BOX DRAWINGS LIGHT DOWN AND RIGHT
+0xdb	0x2588	#FULL BLOCK
+0xdc	0x2584	#LOWER HALF BLOCK
+0xdd	0x258c	#LEFT HALF BLOCK
+0xde	0x2590	#RIGHT HALF BLOCK
+0xdf	0x2580	#UPPER HALF BLOCK
+0xe0	0x03c9	#GREEK SMALL LETTER OMEGA
+0xe1	0x03ac	#GREEK SMALL LETTER ALPHA WITH TONOS
+0xe2	0x03ad	#GREEK SMALL LETTER EPSILON WITH TONOS
+0xe3	0x03ae	#GREEK SMALL LETTER ETA WITH TONOS
+0xe4	0x03ca	#GREEK SMALL LETTER IOTA WITH DIALYTIKA
+0xe5	0x03af	#GREEK SMALL LETTER IOTA WITH TONOS
+0xe6	0x03cc	#GREEK SMALL LETTER OMICRON WITH TONOS
+0xe7	0x03cd	#GREEK SMALL LETTER UPSILON WITH TONOS
+0xe8	0x03cb	#GREEK SMALL LETTER UPSILON WITH DIALYTIKA
+0xe9	0x03ce	#GREEK SMALL LETTER OMEGA WITH TONOS
+0xea	0x0386	#GREEK CAPITAL LETTER ALPHA WITH TONOS
+0xeb	0x0388	#GREEK CAPITAL LETTER EPSILON WITH TONOS
+0xec	0x0389	#GREEK CAPITAL LETTER ETA WITH TONOS
+0xed	0x038a	#GREEK CAPITAL LETTER IOTA WITH TONOS
+0xee	0x038c	#GREEK CAPITAL LETTER OMICRON WITH TONOS
+0xef	0x038e	#GREEK CAPITAL LETTER UPSILON WITH TONOS
+0xf0	0x038f	#GREEK CAPITAL LETTER OMEGA WITH TONOS
+0xf1	0x00b1	#PLUS-MINUS SIGN
+0xf2	0x2265	#GREATER-THAN OR EQUAL TO
+0xf3	0x2264	#LESS-THAN OR EQUAL TO
+0xf4	0x03aa	#GREEK CAPITAL LETTER IOTA WITH DIALYTIKA
+0xf5	0x03ab	#GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA
+0xf6	0x00f7	#DIVISION SIGN
+0xf7	0x2248	#ALMOST EQUAL TO
+0xf8	0x00b0	#DEGREE SIGN
+0xf9	0x2219	#BULLET OPERATOR
+0xfa	0x00b7	#MIDDLE DOT
+0xfb	0x221a	#SQUARE ROOT
+0xfc	0x207f	#SUPERSCRIPT LATIN SMALL LETTER N
+0xfd	0x00b2	#SUPERSCRIPT TWO
+0xfe	0x25a0	#BLACK SQUARE
+0xff	0x00a0	#NO-BREAK SPACE
diff --git a/tools/encoding/cp775.txt b/tools/encoding/cp775.txt
new file mode 100644
index 0000000..1ad4e4e
--- /dev/null
+++ b/tools/encoding/cp775.txt
@@ -0,0 +1,274 @@
+#
+#    Name:     cp775_DOSBaltRim to Unicode table
+#    Unicode version: 2.0
+#    Table version: 2.00
+#    Table format:  Format A
+#    Date:          04/24/96
+#    Authors:       Lori Brownell <loribr@microsoft.com>
+#                   K.D. Chang    <a-kchang@microsoft.com>
+#    General notes: none
+#
+#    Format: Three tab-separated columns
+#        Column #1 is the cp775_DOSBaltRim code (in hex)
+#        Column #2 is the Unicode (in hex as 0xXXXX)
+#        Column #3 is the Unicode name (follows a comment sign, '#')
+#
+#    The entries are in cp775_DOSBaltRim order
+#
+0x00	0x0000	#NULL
+0x01	0x0001	#START OF HEADING
+0x02	0x0002	#START OF TEXT
+0x03	0x0003	#END OF TEXT
+0x04	0x0004	#END OF TRANSMISSION
+0x05	0x0005	#ENQUIRY
+0x06	0x0006	#ACKNOWLEDGE
+0x07	0x0007	#BELL
+0x08	0x0008	#BACKSPACE
+0x09	0x0009	#HORIZONTAL TABULATION
+0x0a	0x000a	#LINE FEED
+0x0b	0x000b	#VERTICAL TABULATION
+0x0c	0x000c	#FORM FEED
+0x0d	0x000d	#CARRIAGE RETURN
+0x0e	0x000e	#SHIFT OUT
+0x0f	0x000f	#SHIFT IN
+0x10	0x0010	#DATA LINK ESCAPE
+0x11	0x0011	#DEVICE CONTROL ONE
+0x12	0x0012	#DEVICE CONTROL TWO
+0x13	0x0013	#DEVICE CONTROL THREE
+0x14	0x0014	#DEVICE CONTROL FOUR
+0x15	0x0015	#NEGATIVE ACKNOWLEDGE
+0x16	0x0016	#SYNCHRONOUS IDLE
+0x17	0x0017	#END OF TRANSMISSION BLOCK
+0x18	0x0018	#CANCEL
+0x19	0x0019	#END OF MEDIUM
+0x1a	0x001a	#SUBSTITUTE
+0x1b	0x001b	#ESCAPE
+0x1c	0x001c	#FILE SEPARATOR
+0x1d	0x001d	#GROUP SEPARATOR
+0x1e	0x001e	#RECORD SEPARATOR
+0x1f	0x001f	#UNIT SEPARATOR
+0x20	0x0020	#SPACE
+0x21	0x0021	#EXCLAMATION MARK
+0x22	0x0022	#QUOTATION MARK
+0x23	0x0023	#NUMBER SIGN
+0x24	0x0024	#DOLLAR SIGN
+0x25	0x0025	#PERCENT SIGN
+0x26	0x0026	#AMPERSAND
+0x27	0x0027	#APOSTROPHE
+0x28	0x0028	#LEFT PARENTHESIS
+0x29	0x0029	#RIGHT PARENTHESIS
+0x2a	0x002a	#ASTERISK
+0x2b	0x002b	#PLUS SIGN
+0x2c	0x002c	#COMMA
+0x2d	0x002d	#HYPHEN-MINUS
+0x2e	0x002e	#FULL STOP
+0x2f	0x002f	#SOLIDUS
+0x30	0x0030	#DIGIT ZERO
+0x31	0x0031	#DIGIT ONE
+0x32	0x0032	#DIGIT TWO
+0x33	0x0033	#DIGIT THREE
+0x34	0x0034	#DIGIT FOUR
+0x35	0x0035	#DIGIT FIVE
+0x36	0x0036	#DIGIT SIX
+0x37	0x0037	#DIGIT SEVEN
+0x38	0x0038	#DIGIT EIGHT
+0x39	0x0039	#DIGIT NINE
+0x3a	0x003a	#COLON
+0x3b	0x003b	#SEMICOLON
+0x3c	0x003c	#LESS-THAN SIGN
+0x3d	0x003d	#EQUALS SIGN
+0x3e	0x003e	#GREATER-THAN SIGN
+0x3f	0x003f	#QUESTION MARK
+0x40	0x0040	#COMMERCIAL AT
+0x41	0x0041	#LATIN CAPITAL LETTER A
+0x42	0x0042	#LATIN CAPITAL LETTER B
+0x43	0x0043	#LATIN CAPITAL LETTER C
+0x44	0x0044	#LATIN CAPITAL LETTER D
+0x45	0x0045	#LATIN CAPITAL LETTER E
+0x46	0x0046	#LATIN CAPITAL LETTER F
+0x47	0x0047	#LATIN CAPITAL LETTER G
+0x48	0x0048	#LATIN CAPITAL LETTER H
+0x49	0x0049	#LATIN CAPITAL LETTER I
+0x4a	0x004a	#LATIN CAPITAL LETTER J
+0x4b	0x004b	#LATIN CAPITAL LETTER K
+0x4c	0x004c	#LATIN CAPITAL LETTER L
+0x4d	0x004d	#LATIN CAPITAL LETTER M
+0x4e	0x004e	#LATIN CAPITAL LETTER N
+0x4f	0x004f	#LATIN CAPITAL LETTER O
+0x50	0x0050	#LATIN CAPITAL LETTER P
+0x51	0x0051	#LATIN CAPITAL LETTER Q
+0x52	0x0052	#LATIN CAPITAL LETTER R
+0x53	0x0053	#LATIN CAPITAL LETTER S
+0x54	0x0054	#LATIN CAPITAL LETTER T
+0x55	0x0055	#LATIN CAPITAL LETTER U
+0x56	0x0056	#LATIN CAPITAL LETTER V
+0x57	0x0057	#LATIN CAPITAL LETTER W
+0x58	0x0058	#LATIN CAPITAL LETTER X
+0x59	0x0059	#LATIN CAPITAL LETTER Y
+0x5a	0x005a	#LATIN CAPITAL LETTER Z
+0x5b	0x005b	#LEFT SQUARE BRACKET
+0x5c	0x005c	#REVERSE SOLIDUS
+0x5d	0x005d	#RIGHT SQUARE BRACKET
+0x5e	0x005e	#CIRCUMFLEX ACCENT
+0x5f	0x005f	#LOW LINE
+0x60	0x0060	#GRAVE ACCENT
+0x61	0x0061	#LATIN SMALL LETTER A
+0x62	0x0062	#LATIN SMALL LETTER B
+0x63	0x0063	#LATIN SMALL LETTER C
+0x64	0x0064	#LATIN SMALL LETTER D
+0x65	0x0065	#LATIN SMALL LETTER E
+0x66	0x0066	#LATIN SMALL LETTER F
+0x67	0x0067	#LATIN SMALL LETTER G
+0x68	0x0068	#LATIN SMALL LETTER H
+0x69	0x0069	#LATIN SMALL LETTER I
+0x6a	0x006a	#LATIN SMALL LETTER J
+0x6b	0x006b	#LATIN SMALL LETTER K
+0x6c	0x006c	#LATIN SMALL LETTER L
+0x6d	0x006d	#LATIN SMALL LETTER M
+0x6e	0x006e	#LATIN SMALL LETTER N
+0x6f	0x006f	#LATIN SMALL LETTER O
+0x70	0x0070	#LATIN SMALL LETTER P
+0x71	0x0071	#LATIN SMALL LETTER Q
+0x72	0x0072	#LATIN SMALL LETTER R
+0x73	0x0073	#LATIN SMALL LETTER S
+0x74	0x0074	#LATIN SMALL LETTER T
+0x75	0x0075	#LATIN SMALL LETTER U
+0x76	0x0076	#LATIN SMALL LETTER V
+0x77	0x0077	#LATIN SMALL LETTER W
+0x78	0x0078	#LATIN SMALL LETTER X
+0x79	0x0079	#LATIN SMALL LETTER Y
+0x7a	0x007a	#LATIN SMALL LETTER Z
+0x7b	0x007b	#LEFT CURLY BRACKET
+0x7c	0x007c	#VERTICAL LINE
+0x7d	0x007d	#RIGHT CURLY BRACKET
+0x7e	0x007e	#TILDE
+0x7f	0x007f	#DELETE
+0x80	0x0106	#LATIN CAPITAL LETTER C WITH ACUTE
+0x81	0x00fc	#LATIN SMALL LETTER U WITH DIAERESIS
+0x82	0x00e9	#LATIN SMALL LETTER E WITH ACUTE
+0x83	0x0101	#LATIN SMALL LETTER A WITH MACRON
+0x84	0x00e4	#LATIN SMALL LETTER A WITH DIAERESIS
+0x85	0x0123	#LATIN SMALL LETTER G WITH CEDILLA
+0x86	0x00e5	#LATIN SMALL LETTER A WITH RING ABOVE
+0x87	0x0107	#LATIN SMALL LETTER C WITH ACUTE
+0x88	0x0142	#LATIN SMALL LETTER L WITH STROKE
+0x89	0x0113	#LATIN SMALL LETTER E WITH MACRON
+0x8a	0x0156	#LATIN CAPITAL LETTER R WITH CEDILLA
+0x8b	0x0157	#LATIN SMALL LETTER R WITH CEDILLA
+0x8c	0x012b	#LATIN SMALL LETTER I WITH MACRON
+0x8d	0x0179	#LATIN CAPITAL LETTER Z WITH ACUTE
+0x8e	0x00c4	#LATIN CAPITAL LETTER A WITH DIAERESIS
+0x8f	0x00c5	#LATIN CAPITAL LETTER A WITH RING ABOVE
+0x90	0x00c9	#LATIN CAPITAL LETTER E WITH ACUTE
+0x91	0x00e6	#LATIN SMALL LIGATURE AE
+0x92	0x00c6	#LATIN CAPITAL LIGATURE AE
+0x93	0x014d	#LATIN SMALL LETTER O WITH MACRON
+0x94	0x00f6	#LATIN SMALL LETTER O WITH DIAERESIS
+0x95	0x0122	#LATIN CAPITAL LETTER G WITH CEDILLA
+0x96	0x00a2	#CENT SIGN
+0x97	0x015a	#LATIN CAPITAL LETTER S WITH ACUTE
+0x98	0x015b	#LATIN SMALL LETTER S WITH ACUTE
+0x99	0x00d6	#LATIN CAPITAL LETTER O WITH DIAERESIS
+0x9a	0x00dc	#LATIN CAPITAL LETTER U WITH DIAERESIS
+0x9b	0x00f8	#LATIN SMALL LETTER O WITH STROKE
+0x9c	0x00a3	#POUND SIGN
+0x9d	0x00d8	#LATIN CAPITAL LETTER O WITH STROKE
+0x9e	0x00d7	#MULTIPLICATION SIGN
+0x9f	0x00a4	#CURRENCY SIGN
+0xa0	0x0100	#LATIN CAPITAL LETTER A WITH MACRON
+0xa1	0x012a	#LATIN CAPITAL LETTER I WITH MACRON
+0xa2	0x00f3	#LATIN SMALL LETTER O WITH ACUTE
+0xa3	0x017b	#LATIN CAPITAL LETTER Z WITH DOT ABOVE
+0xa4	0x017c	#LATIN SMALL LETTER Z WITH DOT ABOVE
+0xa5	0x017a	#LATIN SMALL LETTER Z WITH ACUTE
+0xa6	0x201d	#RIGHT DOUBLE QUOTATION MARK
+0xa7	0x00a6	#BROKEN BAR
+0xa8	0x00a9	#COPYRIGHT SIGN
+0xa9	0x00ae	#REGISTERED SIGN
+0xaa	0x00ac	#NOT SIGN
+0xab	0x00bd	#VULGAR FRACTION ONE HALF
+0xac	0x00bc	#VULGAR FRACTION ONE QUARTER
+0xad	0x0141	#LATIN CAPITAL LETTER L WITH STROKE
+0xae	0x00ab	#LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+0xaf	0x00bb	#RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+0xb0	0x2591	#LIGHT SHADE
+0xb1	0x2592	#MEDIUM SHADE
+0xb2	0x2593	#DARK SHADE
+0xb3	0x2502	#BOX DRAWINGS LIGHT VERTICAL
+0xb4	0x2524	#BOX DRAWINGS LIGHT VERTICAL AND LEFT
+0xb5	0x0104	#LATIN CAPITAL LETTER A WITH OGONEK
+0xb6	0x010c	#LATIN CAPITAL LETTER C WITH CARON
+0xb7	0x0118	#LATIN CAPITAL LETTER E WITH OGONEK
+0xb8	0x0116	#LATIN CAPITAL LETTER E WITH DOT ABOVE
+0xb9	0x2563	#BOX DRAWINGS DOUBLE VERTICAL AND LEFT
+0xba	0x2551	#BOX DRAWINGS DOUBLE VERTICAL
+0xbb	0x2557	#BOX DRAWINGS DOUBLE DOWN AND LEFT
+0xbc	0x255d	#BOX DRAWINGS DOUBLE UP AND LEFT
+0xbd	0x012e	#LATIN CAPITAL LETTER I WITH OGONEK
+0xbe	0x0160	#LATIN CAPITAL LETTER S WITH CARON
+0xbf	0x2510	#BOX DRAWINGS LIGHT DOWN AND LEFT
+0xc0	0x2514	#BOX DRAWINGS LIGHT UP AND RIGHT
+0xc1	0x2534	#BOX DRAWINGS LIGHT UP AND HORIZONTAL
+0xc2	0x252c	#BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
+0xc3	0x251c	#BOX DRAWINGS LIGHT VERTICAL AND RIGHT
+0xc4	0x2500	#BOX DRAWINGS LIGHT HORIZONTAL
+0xc5	0x253c	#BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
+0xc6	0x0172	#LATIN CAPITAL LETTER U WITH OGONEK
+0xc7	0x016a	#LATIN CAPITAL LETTER U WITH MACRON
+0xc8	0x255a	#BOX DRAWINGS DOUBLE UP AND RIGHT
+0xc9	0x2554	#BOX DRAWINGS DOUBLE DOWN AND RIGHT
+0xca	0x2569	#BOX DRAWINGS DOUBLE UP AND HORIZONTAL
+0xcb	0x2566	#BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL
+0xcc	0x2560	#BOX DRAWINGS DOUBLE VERTICAL AND RIGHT
+0xcd	0x2550	#BOX DRAWINGS DOUBLE HORIZONTAL
+0xce	0x256c	#BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL
+0xcf	0x017d	#LATIN CAPITAL LETTER Z WITH CARON
+0xd0	0x0105	#LATIN SMALL LETTER A WITH OGONEK
+0xd1	0x010d	#LATIN SMALL LETTER C WITH CARON
+0xd2	0x0119	#LATIN SMALL LETTER E WITH OGONEK
+0xd3	0x0117	#LATIN SMALL LETTER E WITH DOT ABOVE
+0xd4	0x012f	#LATIN SMALL LETTER I WITH OGONEK
+0xd5	0x0161	#LATIN SMALL LETTER S WITH CARON
+0xd6	0x0173	#LATIN SMALL LETTER U WITH OGONEK
+0xd7	0x016b	#LATIN SMALL LETTER U WITH MACRON
+0xd8	0x017e	#LATIN SMALL LETTER Z WITH CARON
+0xd9	0x2518	#BOX DRAWINGS LIGHT UP AND LEFT
+0xda	0x250c	#BOX DRAWINGS LIGHT DOWN AND RIGHT
+0xdb	0x2588	#FULL BLOCK
+0xdc	0x2584	#LOWER HALF BLOCK
+0xdd	0x258c	#LEFT HALF BLOCK
+0xde	0x2590	#RIGHT HALF BLOCK
+0xdf	0x2580	#UPPER HALF BLOCK
+0xe0	0x00d3	#LATIN CAPITAL LETTER O WITH ACUTE
+0xe1	0x00df	#LATIN SMALL LETTER SHARP S (GERMAN)
+0xe2	0x014c	#LATIN CAPITAL LETTER O WITH MACRON
+0xe3	0x0143	#LATIN CAPITAL LETTER N WITH ACUTE
+0xe4	0x00f5	#LATIN SMALL LETTER O WITH TILDE
+0xe5	0x00d5	#LATIN CAPITAL LETTER O WITH TILDE
+0xe6	0x00b5	#MICRO SIGN
+0xe7	0x0144	#LATIN SMALL LETTER N WITH ACUTE
+0xe8	0x0136	#LATIN CAPITAL LETTER K WITH CEDILLA
+0xe9	0x0137	#LATIN SMALL LETTER K WITH CEDILLA
+0xea	0x013b	#LATIN CAPITAL LETTER L WITH CEDILLA
+0xeb	0x013c	#LATIN SMALL LETTER L WITH CEDILLA
+0xec	0x0146	#LATIN SMALL LETTER N WITH CEDILLA
+0xed	0x0112	#LATIN CAPITAL LETTER E WITH MACRON
+0xee	0x0145	#LATIN CAPITAL LETTER N WITH CEDILLA
+0xef	0x2019	#RIGHT SINGLE QUOTATION MARK
+0xf0	0x00ad	#SOFT HYPHEN
+0xf1	0x00b1	#PLUS-MINUS SIGN
+0xf2	0x201c	#LEFT DOUBLE QUOTATION MARK
+0xf3	0x00be	#VULGAR FRACTION THREE QUARTERS
+0xf4	0x00b6	#PILCROW SIGN
+0xf5	0x00a7	#SECTION SIGN
+0xf6	0x00f7	#DIVISION SIGN
+0xf7	0x201e	#DOUBLE LOW-9 QUOTATION MARK
+0xf8	0x00b0	#DEGREE SIGN
+0xf9	0x2219	#BULLET OPERATOR
+0xfa	0x00b7	#MIDDLE DOT
+0xfb	0x00b9	#SUPERSCRIPT ONE
+0xfc	0x00b3	#SUPERSCRIPT THREE
+0xfd	0x00b2	#SUPERSCRIPT TWO
+0xfe	0x25a0	#BLACK SQUARE
+0xff	0x00a0	#NO-BREAK SPACE
+
diff --git a/tools/encoding/cp850.txt b/tools/encoding/cp850.txt
new file mode 100644
index 0000000..590b1af
--- /dev/null
+++ b/tools/encoding/cp850.txt
@@ -0,0 +1,273 @@
+#
+#    Name:     cp850_DOSLatin1 to Unicode table
+#    Unicode version: 2.0
+#    Table version: 2.00
+#    Table format:  Format A
+#    Date:          04/24/96
+#    Authors:       Lori Brownell <loribr@microsoft.com>
+#                   K.D. Chang    <a-kchang@microsoft.com>
+#    General notes: none
+#
+#    Format: Three tab-separated columns
+#        Column #1 is the cp850_DOSLatin1 code (in hex)
+#        Column #2 is the Unicode (in hex as 0xXXXX)
+#        Column #3 is the Unicode name (follows a comment sign, '#')
+#
+#    The entries are in cp850_DOSLatin1 order
+#
+0x00	0x0000	#NULL
+0x01	0x0001	#START OF HEADING
+0x02	0x0002	#START OF TEXT
+0x03	0x0003	#END OF TEXT
+0x04	0x0004	#END OF TRANSMISSION
+0x05	0x0005	#ENQUIRY
+0x06	0x0006	#ACKNOWLEDGE
+0x07	0x0007	#BELL
+0x08	0x0008	#BACKSPACE
+0x09	0x0009	#HORIZONTAL TABULATION
+0x0a	0x000a	#LINE FEED
+0x0b	0x000b	#VERTICAL TABULATION
+0x0c	0x000c	#FORM FEED
+0x0d	0x000d	#CARRIAGE RETURN
+0x0e	0x000e	#SHIFT OUT
+0x0f	0x000f	#SHIFT IN
+0x10	0x0010	#DATA LINK ESCAPE
+0x11	0x0011	#DEVICE CONTROL ONE
+0x12	0x0012	#DEVICE CONTROL TWO
+0x13	0x0013	#DEVICE CONTROL THREE
+0x14	0x0014	#DEVICE CONTROL FOUR
+0x15	0x0015	#NEGATIVE ACKNOWLEDGE
+0x16	0x0016	#SYNCHRONOUS IDLE
+0x17	0x0017	#END OF TRANSMISSION BLOCK
+0x18	0x0018	#CANCEL
+0x19	0x0019	#END OF MEDIUM
+0x1a	0x001a	#SUBSTITUTE
+0x1b	0x001b	#ESCAPE
+0x1c	0x001c	#FILE SEPARATOR
+0x1d	0x001d	#GROUP SEPARATOR
+0x1e	0x001e	#RECORD SEPARATOR
+0x1f	0x001f	#UNIT SEPARATOR
+0x20	0x0020	#SPACE
+0x21	0x0021	#EXCLAMATION MARK
+0x22	0x0022	#QUOTATION MARK
+0x23	0x0023	#NUMBER SIGN
+0x24	0x0024	#DOLLAR SIGN
+0x25	0x0025	#PERCENT SIGN
+0x26	0x0026	#AMPERSAND
+0x27	0x0027	#APOSTROPHE
+0x28	0x0028	#LEFT PARENTHESIS
+0x29	0x0029	#RIGHT PARENTHESIS
+0x2a	0x002a	#ASTERISK
+0x2b	0x002b	#PLUS SIGN
+0x2c	0x002c	#COMMA
+0x2d	0x002d	#HYPHEN-MINUS
+0x2e	0x002e	#FULL STOP
+0x2f	0x002f	#SOLIDUS
+0x30	0x0030	#DIGIT ZERO
+0x31	0x0031	#DIGIT ONE
+0x32	0x0032	#DIGIT TWO
+0x33	0x0033	#DIGIT THREE
+0x34	0x0034	#DIGIT FOUR
+0x35	0x0035	#DIGIT FIVE
+0x36	0x0036	#DIGIT SIX
+0x37	0x0037	#DIGIT SEVEN
+0x38	0x0038	#DIGIT EIGHT
+0x39	0x0039	#DIGIT NINE
+0x3a	0x003a	#COLON
+0x3b	0x003b	#SEMICOLON
+0x3c	0x003c	#LESS-THAN SIGN
+0x3d	0x003d	#EQUALS SIGN
+0x3e	0x003e	#GREATER-THAN SIGN
+0x3f	0x003f	#QUESTION MARK
+0x40	0x0040	#COMMERCIAL AT
+0x41	0x0041	#LATIN CAPITAL LETTER A
+0x42	0x0042	#LATIN CAPITAL LETTER B
+0x43	0x0043	#LATIN CAPITAL LETTER C
+0x44	0x0044	#LATIN CAPITAL LETTER D
+0x45	0x0045	#LATIN CAPITAL LETTER E
+0x46	0x0046	#LATIN CAPITAL LETTER F
+0x47	0x0047	#LATIN CAPITAL LETTER G
+0x48	0x0048	#LATIN CAPITAL LETTER H
+0x49	0x0049	#LATIN CAPITAL LETTER I
+0x4a	0x004a	#LATIN CAPITAL LETTER J
+0x4b	0x004b	#LATIN CAPITAL LETTER K
+0x4c	0x004c	#LATIN CAPITAL LETTER L
+0x4d	0x004d	#LATIN CAPITAL LETTER M
+0x4e	0x004e	#LATIN CAPITAL LETTER N
+0x4f	0x004f	#LATIN CAPITAL LETTER O
+0x50	0x0050	#LATIN CAPITAL LETTER P
+0x51	0x0051	#LATIN CAPITAL LETTER Q
+0x52	0x0052	#LATIN CAPITAL LETTER R
+0x53	0x0053	#LATIN CAPITAL LETTER S
+0x54	0x0054	#LATIN CAPITAL LETTER T
+0x55	0x0055	#LATIN CAPITAL LETTER U
+0x56	0x0056	#LATIN CAPITAL LETTER V
+0x57	0x0057	#LATIN CAPITAL LETTER W
+0x58	0x0058	#LATIN CAPITAL LETTER X
+0x59	0x0059	#LATIN CAPITAL LETTER Y
+0x5a	0x005a	#LATIN CAPITAL LETTER Z
+0x5b	0x005b	#LEFT SQUARE BRACKET
+0x5c	0x005c	#REVERSE SOLIDUS
+0x5d	0x005d	#RIGHT SQUARE BRACKET
+0x5e	0x005e	#CIRCUMFLEX ACCENT
+0x5f	0x005f	#LOW LINE
+0x60	0x0060	#GRAVE ACCENT
+0x61	0x0061	#LATIN SMALL LETTER A
+0x62	0x0062	#LATIN SMALL LETTER B
+0x63	0x0063	#LATIN SMALL LETTER C
+0x64	0x0064	#LATIN SMALL LETTER D
+0x65	0x0065	#LATIN SMALL LETTER E
+0x66	0x0066	#LATIN SMALL LETTER F
+0x67	0x0067	#LATIN SMALL LETTER G
+0x68	0x0068	#LATIN SMALL LETTER H
+0x69	0x0069	#LATIN SMALL LETTER I
+0x6a	0x006a	#LATIN SMALL LETTER J
+0x6b	0x006b	#LATIN SMALL LETTER K
+0x6c	0x006c	#LATIN SMALL LETTER L
+0x6d	0x006d	#LATIN SMALL LETTER M
+0x6e	0x006e	#LATIN SMALL LETTER N
+0x6f	0x006f	#LATIN SMALL LETTER O
+0x70	0x0070	#LATIN SMALL LETTER P
+0x71	0x0071	#LATIN SMALL LETTER Q
+0x72	0x0072	#LATIN SMALL LETTER R
+0x73	0x0073	#LATIN SMALL LETTER S
+0x74	0x0074	#LATIN SMALL LETTER T
+0x75	0x0075	#LATIN SMALL LETTER U
+0x76	0x0076	#LATIN SMALL LETTER V
+0x77	0x0077	#LATIN SMALL LETTER W
+0x78	0x0078	#LATIN SMALL LETTER X
+0x79	0x0079	#LATIN SMALL LETTER Y
+0x7a	0x007a	#LATIN SMALL LETTER Z
+0x7b	0x007b	#LEFT CURLY BRACKET
+0x7c	0x007c	#VERTICAL LINE
+0x7d	0x007d	#RIGHT CURLY BRACKET
+0x7e	0x007e	#TILDE
+0x7f	0x007f	#DELETE
+0x80	0x00c7	#LATIN CAPITAL LETTER C WITH CEDILLA
+0x81	0x00fc	#LATIN SMALL LETTER U WITH DIAERESIS
+0x82	0x00e9	#LATIN SMALL LETTER E WITH ACUTE
+0x83	0x00e2	#LATIN SMALL LETTER A WITH CIRCUMFLEX
+0x84	0x00e4	#LATIN SMALL LETTER A WITH DIAERESIS
+0x85	0x00e0	#LATIN SMALL LETTER A WITH GRAVE
+0x86	0x00e5	#LATIN SMALL LETTER A WITH RING ABOVE
+0x87	0x00e7	#LATIN SMALL LETTER C WITH CEDILLA
+0x88	0x00ea	#LATIN SMALL LETTER E WITH CIRCUMFLEX
+0x89	0x00eb	#LATIN SMALL LETTER E WITH DIAERESIS
+0x8a	0x00e8	#LATIN SMALL LETTER E WITH GRAVE
+0x8b	0x00ef	#LATIN SMALL LETTER I WITH DIAERESIS
+0x8c	0x00ee	#LATIN SMALL LETTER I WITH CIRCUMFLEX
+0x8d	0x00ec	#LATIN SMALL LETTER I WITH GRAVE
+0x8e	0x00c4	#LATIN CAPITAL LETTER A WITH DIAERESIS
+0x8f	0x00c5	#LATIN CAPITAL LETTER A WITH RING ABOVE
+0x90	0x00c9	#LATIN CAPITAL LETTER E WITH ACUTE
+0x91	0x00e6	#LATIN SMALL LIGATURE AE
+0x92	0x00c6	#LATIN CAPITAL LIGATURE AE
+0x93	0x00f4	#LATIN SMALL LETTER O WITH CIRCUMFLEX
+0x94	0x00f6	#LATIN SMALL LETTER O WITH DIAERESIS
+0x95	0x00f2	#LATIN SMALL LETTER O WITH GRAVE
+0x96	0x00fb	#LATIN SMALL LETTER U WITH CIRCUMFLEX
+0x97	0x00f9	#LATIN SMALL LETTER U WITH GRAVE
+0x98	0x00ff	#LATIN SMALL LETTER Y WITH DIAERESIS
+0x99	0x00d6	#LATIN CAPITAL LETTER O WITH DIAERESIS
+0x9a	0x00dc	#LATIN CAPITAL LETTER U WITH DIAERESIS
+0x9b	0x00f8	#LATIN SMALL LETTER O WITH STROKE
+0x9c	0x00a3	#POUND SIGN
+0x9d	0x00d8	#LATIN CAPITAL LETTER O WITH STROKE
+0x9e	0x00d7	#MULTIPLICATION SIGN
+0x9f	0x0192	#LATIN SMALL LETTER F WITH HOOK
+0xa0	0x00e1	#LATIN SMALL LETTER A WITH ACUTE
+0xa1	0x00ed	#LATIN SMALL LETTER I WITH ACUTE
+0xa2	0x00f3	#LATIN SMALL LETTER O WITH ACUTE
+0xa3	0x00fa	#LATIN SMALL LETTER U WITH ACUTE
+0xa4	0x00f1	#LATIN SMALL LETTER N WITH TILDE
+0xa5	0x00d1	#LATIN CAPITAL LETTER N WITH TILDE
+0xa6	0x00aa	#FEMININE ORDINAL INDICATOR
+0xa7	0x00ba	#MASCULINE ORDINAL INDICATOR
+0xa8	0x00bf	#INVERTED QUESTION MARK
+0xa9	0x00ae	#REGISTERED SIGN
+0xaa	0x00ac	#NOT SIGN
+0xab	0x00bd	#VULGAR FRACTION ONE HALF
+0xac	0x00bc	#VULGAR FRACTION ONE QUARTER
+0xad	0x00a1	#INVERTED EXCLAMATION MARK
+0xae	0x00ab	#LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+0xaf	0x00bb	#RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+0xb0	0x2591	#LIGHT SHADE
+0xb1	0x2592	#MEDIUM SHADE
+0xb2	0x2593	#DARK SHADE
+0xb3	0x2502	#BOX DRAWINGS LIGHT VERTICAL
+0xb4	0x2524	#BOX DRAWINGS LIGHT VERTICAL AND LEFT
+0xb5	0x00c1	#LATIN CAPITAL LETTER A WITH ACUTE
+0xb6	0x00c2	#LATIN CAPITAL LETTER A WITH CIRCUMFLEX
+0xb7	0x00c0	#LATIN CAPITAL LETTER A WITH GRAVE
+0xb8	0x00a9	#COPYRIGHT SIGN
+0xb9	0x2563	#BOX DRAWINGS DOUBLE VERTICAL AND LEFT
+0xba	0x2551	#BOX DRAWINGS DOUBLE VERTICAL
+0xbb	0x2557	#BOX DRAWINGS DOUBLE DOWN AND LEFT
+0xbc	0x255d	#BOX DRAWINGS DOUBLE UP AND LEFT
+0xbd	0x00a2	#CENT SIGN
+0xbe	0x00a5	#YEN SIGN
+0xbf	0x2510	#BOX DRAWINGS LIGHT DOWN AND LEFT
+0xc0	0x2514	#BOX DRAWINGS LIGHT UP AND RIGHT
+0xc1	0x2534	#BOX DRAWINGS LIGHT UP AND HORIZONTAL
+0xc2	0x252c	#BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
+0xc3	0x251c	#BOX DRAWINGS LIGHT VERTICAL AND RIGHT
+0xc4	0x2500	#BOX DRAWINGS LIGHT HORIZONTAL
+0xc5	0x253c	#BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
+0xc6	0x00e3	#LATIN SMALL LETTER A WITH TILDE
+0xc7	0x00c3	#LATIN CAPITAL LETTER A WITH TILDE
+0xc8	0x255a	#BOX DRAWINGS DOUBLE UP AND RIGHT
+0xc9	0x2554	#BOX DRAWINGS DOUBLE DOWN AND RIGHT
+0xca	0x2569	#BOX DRAWINGS DOUBLE UP AND HORIZONTAL
+0xcb	0x2566	#BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL
+0xcc	0x2560	#BOX DRAWINGS DOUBLE VERTICAL AND RIGHT
+0xcd	0x2550	#BOX DRAWINGS DOUBLE HORIZONTAL
+0xce	0x256c	#BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL
+0xcf	0x00a4	#CURRENCY SIGN
+0xd0	0x00f0	#LATIN SMALL LETTER ETH
+0xd1	0x00d0	#LATIN CAPITAL LETTER ETH
+0xd2	0x00ca	#LATIN CAPITAL LETTER E WITH CIRCUMFLEX
+0xd3	0x00cb	#LATIN CAPITAL LETTER E WITH DIAERESIS
+0xd4	0x00c8	#LATIN CAPITAL LETTER E WITH GRAVE
+0xd5	0x0131	#LATIN SMALL LETTER DOTLESS I
+0xd6	0x00cd	#LATIN CAPITAL LETTER I WITH ACUTE
+0xd7	0x00ce	#LATIN CAPITAL LETTER I WITH CIRCUMFLEX
+0xd8	0x00cf	#LATIN CAPITAL LETTER I WITH DIAERESIS
+0xd9	0x2518	#BOX DRAWINGS LIGHT UP AND LEFT
+0xda	0x250c	#BOX DRAWINGS LIGHT DOWN AND RIGHT
+0xdb	0x2588	#FULL BLOCK
+0xdc	0x2584	#LOWER HALF BLOCK
+0xdd	0x00a6	#BROKEN BAR
+0xde	0x00cc	#LATIN CAPITAL LETTER I WITH GRAVE
+0xdf	0x2580	#UPPER HALF BLOCK
+0xe0	0x00d3	#LATIN CAPITAL LETTER O WITH ACUTE
+0xe1	0x00df	#LATIN SMALL LETTER SHARP S
+0xe2	0x00d4	#LATIN CAPITAL LETTER O WITH CIRCUMFLEX
+0xe3	0x00d2	#LATIN CAPITAL LETTER O WITH GRAVE
+0xe4	0x00f5	#LATIN SMALL LETTER O WITH TILDE
+0xe5	0x00d5	#LATIN CAPITAL LETTER O WITH TILDE
+0xe6	0x00b5	#MICRO SIGN
+0xe7	0x00fe	#LATIN SMALL LETTER THORN
+0xe8	0x00de	#LATIN CAPITAL LETTER THORN
+0xe9	0x00da	#LATIN CAPITAL LETTER U WITH ACUTE
+0xea	0x00db	#LATIN CAPITAL LETTER U WITH CIRCUMFLEX
+0xeb	0x00d9	#LATIN CAPITAL LETTER U WITH GRAVE
+0xec	0x00fd	#LATIN SMALL LETTER Y WITH ACUTE
+0xed	0x00dd	#LATIN CAPITAL LETTER Y WITH ACUTE
+0xee	0x00af	#MACRON
+0xef	0x00b4	#ACUTE ACCENT
+0xf0	0x00ad	#SOFT HYPHEN
+0xf1	0x00b1	#PLUS-MINUS SIGN
+0xf2	0x2017	#DOUBLE LOW LINE
+0xf3	0x00be	#VULGAR FRACTION THREE QUARTERS
+0xf4	0x00b6	#PILCROW SIGN
+0xf5	0x00a7	#SECTION SIGN
+0xf6	0x00f7	#DIVISION SIGN
+0xf7	0x00b8	#CEDILLA
+0xf8	0x00b0	#DEGREE SIGN
+0xf9	0x00a8	#DIAERESIS
+0xfa	0x00b7	#MIDDLE DOT
+0xfb	0x00b9	#SUPERSCRIPT ONE
+0xfc	0x00b3	#SUPERSCRIPT THREE
+0xfd	0x00b2	#SUPERSCRIPT TWO
+0xfe	0x25a0	#BLACK SQUARE
+0xff	0x00a0	#NO-BREAK SPACE
diff --git a/tools/encoding/cp852.txt b/tools/encoding/cp852.txt
new file mode 100644
index 0000000..2f2daba
--- /dev/null
+++ b/tools/encoding/cp852.txt
@@ -0,0 +1,273 @@
+#
+#    Name:     cp852_DOSLatin2 to Unicode table
+#    Unicode version: 2.0
+#    Table version: 2.00
+#    Table format:  Format A
+#    Date:          04/24/96
+#    Authors:       Lori Brownell <loribr@microsoft.com>
+#                   K.D. Chang    <a-kchang@microsoft.com>
+#    General notes: none
+#
+#    Format: Three tab-separated columns
+#        Column #1 is the cp852_DOSLatin2 code (in hex)
+#        Column #2 is the Unicode (in hex as 0xXXXX)
+#        Column #3 is the Unicode name (follows a comment sign, '#')
+#
+#    The entries are in cp852_DOSLatin2 order
+#
+0x00	0x0000	#NULL
+0x01	0x0001	#START OF HEADING
+0x02	0x0002	#START OF TEXT
+0x03	0x0003	#END OF TEXT
+0x04	0x0004	#END OF TRANSMISSION
+0x05	0x0005	#ENQUIRY
+0x06	0x0006	#ACKNOWLEDGE
+0x07	0x0007	#BELL
+0x08	0x0008	#BACKSPACE
+0x09	0x0009	#HORIZONTAL TABULATION
+0x0a	0x000a	#LINE FEED
+0x0b	0x000b	#VERTICAL TABULATION
+0x0c	0x000c	#FORM FEED
+0x0d	0x000d	#CARRIAGE RETURN
+0x0e	0x000e	#SHIFT OUT
+0x0f	0x000f	#SHIFT IN
+0x10	0x0010	#DATA LINK ESCAPE
+0x11	0x0011	#DEVICE CONTROL ONE
+0x12	0x0012	#DEVICE CONTROL TWO
+0x13	0x0013	#DEVICE CONTROL THREE
+0x14	0x0014	#DEVICE CONTROL FOUR
+0x15	0x0015	#NEGATIVE ACKNOWLEDGE
+0x16	0x0016	#SYNCHRONOUS IDLE
+0x17	0x0017	#END OF TRANSMISSION BLOCK
+0x18	0x0018	#CANCEL
+0x19	0x0019	#END OF MEDIUM
+0x1a	0x001a	#SUBSTITUTE
+0x1b	0x001b	#ESCAPE
+0x1c	0x001c	#FILE SEPARATOR
+0x1d	0x001d	#GROUP SEPARATOR
+0x1e	0x001e	#RECORD SEPARATOR
+0x1f	0x001f	#UNIT SEPARATOR
+0x20	0x0020	#SPACE
+0x21	0x0021	#EXCLAMATION MARK
+0x22	0x0022	#QUOTATION MARK
+0x23	0x0023	#NUMBER SIGN
+0x24	0x0024	#DOLLAR SIGN
+0x25	0x0025	#PERCENT SIGN
+0x26	0x0026	#AMPERSAND
+0x27	0x0027	#APOSTROPHE
+0x28	0x0028	#LEFT PARENTHESIS
+0x29	0x0029	#RIGHT PARENTHESIS
+0x2a	0x002a	#ASTERISK
+0x2b	0x002b	#PLUS SIGN
+0x2c	0x002c	#COMMA
+0x2d	0x002d	#HYPHEN-MINUS
+0x2e	0x002e	#FULL STOP
+0x2f	0x002f	#SOLIDUS
+0x30	0x0030	#DIGIT ZERO
+0x31	0x0031	#DIGIT ONE
+0x32	0x0032	#DIGIT TWO
+0x33	0x0033	#DIGIT THREE
+0x34	0x0034	#DIGIT FOUR
+0x35	0x0035	#DIGIT FIVE
+0x36	0x0036	#DIGIT SIX
+0x37	0x0037	#DIGIT SEVEN
+0x38	0x0038	#DIGIT EIGHT
+0x39	0x0039	#DIGIT NINE
+0x3a	0x003a	#COLON
+0x3b	0x003b	#SEMICOLON
+0x3c	0x003c	#LESS-THAN SIGN
+0x3d	0x003d	#EQUALS SIGN
+0x3e	0x003e	#GREATER-THAN SIGN
+0x3f	0x003f	#QUESTION MARK
+0x40	0x0040	#COMMERCIAL AT
+0x41	0x0041	#LATIN CAPITAL LETTER A
+0x42	0x0042	#LATIN CAPITAL LETTER B
+0x43	0x0043	#LATIN CAPITAL LETTER C
+0x44	0x0044	#LATIN CAPITAL LETTER D
+0x45	0x0045	#LATIN CAPITAL LETTER E
+0x46	0x0046	#LATIN CAPITAL LETTER F
+0x47	0x0047	#LATIN CAPITAL LETTER G
+0x48	0x0048	#LATIN CAPITAL LETTER H
+0x49	0x0049	#LATIN CAPITAL LETTER I
+0x4a	0x004a	#LATIN CAPITAL LETTER J
+0x4b	0x004b	#LATIN CAPITAL LETTER K
+0x4c	0x004c	#LATIN CAPITAL LETTER L
+0x4d	0x004d	#LATIN CAPITAL LETTER M
+0x4e	0x004e	#LATIN CAPITAL LETTER N
+0x4f	0x004f	#LATIN CAPITAL LETTER O
+0x50	0x0050	#LATIN CAPITAL LETTER P
+0x51	0x0051	#LATIN CAPITAL LETTER Q
+0x52	0x0052	#LATIN CAPITAL LETTER R
+0x53	0x0053	#LATIN CAPITAL LETTER S
+0x54	0x0054	#LATIN CAPITAL LETTER T
+0x55	0x0055	#LATIN CAPITAL LETTER U
+0x56	0x0056	#LATIN CAPITAL LETTER V
+0x57	0x0057	#LATIN CAPITAL LETTER W
+0x58	0x0058	#LATIN CAPITAL LETTER X
+0x59	0x0059	#LATIN CAPITAL LETTER Y
+0x5a	0x005a	#LATIN CAPITAL LETTER Z
+0x5b	0x005b	#LEFT SQUARE BRACKET
+0x5c	0x005c	#REVERSE SOLIDUS
+0x5d	0x005d	#RIGHT SQUARE BRACKET
+0x5e	0x005e	#CIRCUMFLEX ACCENT
+0x5f	0x005f	#LOW LINE
+0x60	0x0060	#GRAVE ACCENT
+0x61	0x0061	#LATIN SMALL LETTER A
+0x62	0x0062	#LATIN SMALL LETTER B
+0x63	0x0063	#LATIN SMALL LETTER C
+0x64	0x0064	#LATIN SMALL LETTER D
+0x65	0x0065	#LATIN SMALL LETTER E
+0x66	0x0066	#LATIN SMALL LETTER F
+0x67	0x0067	#LATIN SMALL LETTER G
+0x68	0x0068	#LATIN SMALL LETTER H
+0x69	0x0069	#LATIN SMALL LETTER I
+0x6a	0x006a	#LATIN SMALL LETTER J
+0x6b	0x006b	#LATIN SMALL LETTER K
+0x6c	0x006c	#LATIN SMALL LETTER L
+0x6d	0x006d	#LATIN SMALL LETTER M
+0x6e	0x006e	#LATIN SMALL LETTER N
+0x6f	0x006f	#LATIN SMALL LETTER O
+0x70	0x0070	#LATIN SMALL LETTER P
+0x71	0x0071	#LATIN SMALL LETTER Q
+0x72	0x0072	#LATIN SMALL LETTER R
+0x73	0x0073	#LATIN SMALL LETTER S
+0x74	0x0074	#LATIN SMALL LETTER T
+0x75	0x0075	#LATIN SMALL LETTER U
+0x76	0x0076	#LATIN SMALL LETTER V
+0x77	0x0077	#LATIN SMALL LETTER W
+0x78	0x0078	#LATIN SMALL LETTER X
+0x79	0x0079	#LATIN SMALL LETTER Y
+0x7a	0x007a	#LATIN SMALL LETTER Z
+0x7b	0x007b	#LEFT CURLY BRACKET
+0x7c	0x007c	#VERTICAL LINE
+0x7d	0x007d	#RIGHT CURLY BRACKET
+0x7e	0x007e	#TILDE
+0x7f	0x007f	#DELETE
+0x80	0x00c7	#LATIN CAPITAL LETTER C WITH CEDILLA
+0x81	0x00fc	#LATIN SMALL LETTER U WITH DIAERESIS
+0x82	0x00e9	#LATIN SMALL LETTER E WITH ACUTE
+0x83	0x00e2	#LATIN SMALL LETTER A WITH CIRCUMFLEX
+0x84	0x00e4	#LATIN SMALL LETTER A WITH DIAERESIS
+0x85	0x016f	#LATIN SMALL LETTER U WITH RING ABOVE
+0x86	0x0107	#LATIN SMALL LETTER C WITH ACUTE
+0x87	0x00e7	#LATIN SMALL LETTER C WITH CEDILLA
+0x88	0x0142	#LATIN SMALL LETTER L WITH STROKE
+0x89	0x00eb	#LATIN SMALL LETTER E WITH DIAERESIS
+0x8a	0x0150	#LATIN CAPITAL LETTER O WITH DOUBLE ACUTE
+0x8b	0x0151	#LATIN SMALL LETTER O WITH DOUBLE ACUTE
+0x8c	0x00ee	#LATIN SMALL LETTER I WITH CIRCUMFLEX
+0x8d	0x0179	#LATIN CAPITAL LETTER Z WITH ACUTE
+0x8e	0x00c4	#LATIN CAPITAL LETTER A WITH DIAERESIS
+0x8f	0x0106	#LATIN CAPITAL LETTER C WITH ACUTE
+0x90	0x00c9	#LATIN CAPITAL LETTER E WITH ACUTE
+0x91	0x0139	#LATIN CAPITAL LETTER L WITH ACUTE
+0x92	0x013a	#LATIN SMALL LETTER L WITH ACUTE
+0x93	0x00f4	#LATIN SMALL LETTER O WITH CIRCUMFLEX
+0x94	0x00f6	#LATIN SMALL LETTER O WITH DIAERESIS
+0x95	0x013d	#LATIN CAPITAL LETTER L WITH CARON
+0x96	0x013e	#LATIN SMALL LETTER L WITH CARON
+0x97	0x015a	#LATIN CAPITAL LETTER S WITH ACUTE
+0x98	0x015b	#LATIN SMALL LETTER S WITH ACUTE
+0x99	0x00d6	#LATIN CAPITAL LETTER O WITH DIAERESIS
+0x9a	0x00dc	#LATIN CAPITAL LETTER U WITH DIAERESIS
+0x9b	0x0164	#LATIN CAPITAL LETTER T WITH CARON
+0x9c	0x0165	#LATIN SMALL LETTER T WITH CARON
+0x9d	0x0141	#LATIN CAPITAL LETTER L WITH STROKE
+0x9e	0x00d7	#MULTIPLICATION SIGN
+0x9f	0x010d	#LATIN SMALL LETTER C WITH CARON
+0xa0	0x00e1	#LATIN SMALL LETTER A WITH ACUTE
+0xa1	0x00ed	#LATIN SMALL LETTER I WITH ACUTE
+0xa2	0x00f3	#LATIN SMALL LETTER O WITH ACUTE
+0xa3	0x00fa	#LATIN SMALL LETTER U WITH ACUTE
+0xa4	0x0104	#LATIN CAPITAL LETTER A WITH OGONEK
+0xa5	0x0105	#LATIN SMALL LETTER A WITH OGONEK
+0xa6	0x017d	#LATIN CAPITAL LETTER Z WITH CARON
+0xa7	0x017e	#LATIN SMALL LETTER Z WITH CARON
+0xa8	0x0118	#LATIN CAPITAL LETTER E WITH OGONEK
+0xa9	0x0119	#LATIN SMALL LETTER E WITH OGONEK
+0xaa	0x00ac	#NOT SIGN
+0xab	0x017a	#LATIN SMALL LETTER Z WITH ACUTE
+0xac	0x010c	#LATIN CAPITAL LETTER C WITH CARON
+0xad	0x015f	#LATIN SMALL LETTER S WITH CEDILLA
+0xae	0x00ab	#LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+0xaf	0x00bb	#RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+0xb0	0x2591	#LIGHT SHADE
+0xb1	0x2592	#MEDIUM SHADE
+0xb2	0x2593	#DARK SHADE
+0xb3	0x2502	#BOX DRAWINGS LIGHT VERTICAL
+0xb4	0x2524	#BOX DRAWINGS LIGHT VERTICAL AND LEFT
+0xb5	0x00c1	#LATIN CAPITAL LETTER A WITH ACUTE
+0xb6	0x00c2	#LATIN CAPITAL LETTER A WITH CIRCUMFLEX
+0xb7	0x011a	#LATIN CAPITAL LETTER E WITH CARON
+0xb8	0x015e	#LATIN CAPITAL LETTER S WITH CEDILLA
+0xb9	0x2563	#BOX DRAWINGS DOUBLE VERTICAL AND LEFT
+0xba	0x2551	#BOX DRAWINGS DOUBLE VERTICAL
+0xbb	0x2557	#BOX DRAWINGS DOUBLE DOWN AND LEFT
+0xbc	0x255d	#BOX DRAWINGS DOUBLE UP AND LEFT
+0xbd	0x017b	#LATIN CAPITAL LETTER Z WITH DOT ABOVE
+0xbe	0x017c	#LATIN SMALL LETTER Z WITH DOT ABOVE
+0xbf	0x2510	#BOX DRAWINGS LIGHT DOWN AND LEFT
+0xc0	0x2514	#BOX DRAWINGS LIGHT UP AND RIGHT
+0xc1	0x2534	#BOX DRAWINGS LIGHT UP AND HORIZONTAL
+0xc2	0x252c	#BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
+0xc3	0x251c	#BOX DRAWINGS LIGHT VERTICAL AND RIGHT
+0xc4	0x2500	#BOX DRAWINGS LIGHT HORIZONTAL
+0xc5	0x253c	#BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
+0xc6	0x0102	#LATIN CAPITAL LETTER A WITH BREVE
+0xc7	0x0103	#LATIN SMALL LETTER A WITH BREVE
+0xc8	0x255a	#BOX DRAWINGS DOUBLE UP AND RIGHT
+0xc9	0x2554	#BOX DRAWINGS DOUBLE DOWN AND RIGHT
+0xca	0x2569	#BOX DRAWINGS DOUBLE UP AND HORIZONTAL
+0xcb	0x2566	#BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL
+0xcc	0x2560	#BOX DRAWINGS DOUBLE VERTICAL AND RIGHT
+0xcd	0x2550	#BOX DRAWINGS DOUBLE HORIZONTAL
+0xce	0x256c	#BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL
+0xcf	0x00a4	#CURRENCY SIGN
+0xd0	0x0111	#LATIN SMALL LETTER D WITH STROKE
+0xd1	0x0110	#LATIN CAPITAL LETTER D WITH STROKE
+0xd2	0x010e	#LATIN CAPITAL LETTER D WITH CARON
+0xd3	0x00cb	#LATIN CAPITAL LETTER E WITH DIAERESIS
+0xd4	0x010f	#LATIN SMALL LETTER D WITH CARON
+0xd5	0x0147	#LATIN CAPITAL LETTER N WITH CARON
+0xd6	0x00cd	#LATIN CAPITAL LETTER I WITH ACUTE
+0xd7	0x00ce	#LATIN CAPITAL LETTER I WITH CIRCUMFLEX
+0xd8	0x011b	#LATIN SMALL LETTER E WITH CARON
+0xd9	0x2518	#BOX DRAWINGS LIGHT UP AND LEFT
+0xda	0x250c	#BOX DRAWINGS LIGHT DOWN AND RIGHT
+0xdb	0x2588	#FULL BLOCK
+0xdc	0x2584	#LOWER HALF BLOCK
+0xdd	0x0162	#LATIN CAPITAL LETTER T WITH CEDILLA
+0xde	0x016e	#LATIN CAPITAL LETTER U WITH RING ABOVE
+0xdf	0x2580	#UPPER HALF BLOCK
+0xe0	0x00d3	#LATIN CAPITAL LETTER O WITH ACUTE
+0xe1	0x00df	#LATIN SMALL LETTER SHARP S
+0xe2	0x00d4	#LATIN CAPITAL LETTER O WITH CIRCUMFLEX
+0xe3	0x0143	#LATIN CAPITAL LETTER N WITH ACUTE
+0xe4	0x0144	#LATIN SMALL LETTER N WITH ACUTE
+0xe5	0x0148	#LATIN SMALL LETTER N WITH CARON
+0xe6	0x0160	#LATIN CAPITAL LETTER S WITH CARON
+0xe7	0x0161	#LATIN SMALL LETTER S WITH CARON
+0xe8	0x0154	#LATIN CAPITAL LETTER R WITH ACUTE
+0xe9	0x00da	#LATIN CAPITAL LETTER U WITH ACUTE
+0xea	0x0155	#LATIN SMALL LETTER R WITH ACUTE
+0xeb	0x0170	#LATIN CAPITAL LETTER U WITH DOUBLE ACUTE
+0xec	0x00fd	#LATIN SMALL LETTER Y WITH ACUTE
+0xed	0x00dd	#LATIN CAPITAL LETTER Y WITH ACUTE
+0xee	0x0163	#LATIN SMALL LETTER T WITH CEDILLA
+0xef	0x00b4	#ACUTE ACCENT
+0xf0	0x00ad	#SOFT HYPHEN
+0xf1	0x02dd	#DOUBLE ACUTE ACCENT
+0xf2	0x02db	#OGONEK
+0xf3	0x02c7	#CARON
+0xf4	0x02d8	#BREVE
+0xf5	0x00a7	#SECTION SIGN
+0xf6	0x00f7	#DIVISION SIGN
+0xf7	0x00b8	#CEDILLA
+0xf8	0x00b0	#DEGREE SIGN
+0xf9	0x00a8	#DIAERESIS
+0xfa	0x02d9	#DOT ABOVE
+0xfb	0x0171	#LATIN SMALL LETTER U WITH DOUBLE ACUTE
+0xfc	0x0158	#LATIN CAPITAL LETTER R WITH CARON
+0xfd	0x0159	#LATIN SMALL LETTER R WITH CARON
+0xfe	0x25a0	#BLACK SQUARE
+0xff	0x00a0	#NO-BREAK SPACE
diff --git a/tools/encoding/cp855.txt b/tools/encoding/cp855.txt
new file mode 100644
index 0000000..d43daf0
--- /dev/null
+++ b/tools/encoding/cp855.txt
@@ -0,0 +1,274 @@
+#
+#    Name:     cp855_DOSCyrillic to Unicode table
+#    Unicode version: 2.0
+#    Table version: 2.00
+#    Table format:  Format A
+#    Date:          04/24/96
+#    Authors:       Lori Brownell <loribr@microsoft.com>
+#                   K.D. Chang    <a-kchang@microsoft.com>
+#    General notes: none
+#
+#    Format: Three tab-separated columns
+#        Column #1 is the cp855_DOSCyrillic code (in hex)
+#        Column #2 is the Unicode (in hex as 0xXXXX)
+#        Column #3 is the Unicode name (follows a comment sign, '#')
+#
+#    The entries are in cp855_DOSCyrillic order
+#
+0x00	0x0000	#NULL
+0x01	0x0001	#START OF HEADING
+0x02	0x0002	#START OF TEXT
+0x03	0x0003	#END OF TEXT
+0x04	0x0004	#END OF TRANSMISSION
+0x05	0x0005	#ENQUIRY
+0x06	0x0006	#ACKNOWLEDGE
+0x07	0x0007	#BELL
+0x08	0x0008	#BACKSPACE
+0x09	0x0009	#HORIZONTAL TABULATION
+0x0a	0x000a	#LINE FEED
+0x0b	0x000b	#VERTICAL TABULATION
+0x0c	0x000c	#FORM FEED
+0x0d	0x000d	#CARRIAGE RETURN
+0x0e	0x000e	#SHIFT OUT
+0x0f	0x000f	#SHIFT IN
+0x10	0x0010	#DATA LINK ESCAPE
+0x11	0x0011	#DEVICE CONTROL ONE
+0x12	0x0012	#DEVICE CONTROL TWO
+0x13	0x0013	#DEVICE CONTROL THREE
+0x14	0x0014	#DEVICE CONTROL FOUR
+0x15	0x0015	#NEGATIVE ACKNOWLEDGE
+0x16	0x0016	#SYNCHRONOUS IDLE
+0x17	0x0017	#END OF TRANSMISSION BLOCK
+0x18	0x0018	#CANCEL
+0x19	0x0019	#END OF MEDIUM
+0x1a	0x001a	#SUBSTITUTE
+0x1b	0x001b	#ESCAPE
+0x1c	0x001c	#FILE SEPARATOR
+0x1d	0x001d	#GROUP SEPARATOR
+0x1e	0x001e	#RECORD SEPARATOR
+0x1f	0x001f	#UNIT SEPARATOR
+0x20	0x0020	#SPACE
+0x21	0x0021	#EXCLAMATION MARK
+0x22	0x0022	#QUOTATION MARK
+0x23	0x0023	#NUMBER SIGN
+0x24	0x0024	#DOLLAR SIGN
+0x25	0x0025	#PERCENT SIGN
+0x26	0x0026	#AMPERSAND
+0x27	0x0027	#APOSTROPHE
+0x28	0x0028	#LEFT PARENTHESIS
+0x29	0x0029	#RIGHT PARENTHESIS
+0x2a	0x002a	#ASTERISK
+0x2b	0x002b	#PLUS SIGN
+0x2c	0x002c	#COMMA
+0x2d	0x002d	#HYPHEN-MINUS
+0x2e	0x002e	#FULL STOP
+0x2f	0x002f	#SOLIDUS
+0x30	0x0030	#DIGIT ZERO
+0x31	0x0031	#DIGIT ONE
+0x32	0x0032	#DIGIT TWO
+0x33	0x0033	#DIGIT THREE
+0x34	0x0034	#DIGIT FOUR
+0x35	0x0035	#DIGIT FIVE
+0x36	0x0036	#DIGIT SIX
+0x37	0x0037	#DIGIT SEVEN
+0x38	0x0038	#DIGIT EIGHT
+0x39	0x0039	#DIGIT NINE
+0x3a	0x003a	#COLON
+0x3b	0x003b	#SEMICOLON
+0x3c	0x003c	#LESS-THAN SIGN
+0x3d	0x003d	#EQUALS SIGN
+0x3e	0x003e	#GREATER-THAN SIGN
+0x3f	0x003f	#QUESTION MARK
+0x40	0x0040	#COMMERCIAL AT
+0x41	0x0041	#LATIN CAPITAL LETTER A
+0x42	0x0042	#LATIN CAPITAL LETTER B
+0x43	0x0043	#LATIN CAPITAL LETTER C
+0x44	0x0044	#LATIN CAPITAL LETTER D
+0x45	0x0045	#LATIN CAPITAL LETTER E
+0x46	0x0046	#LATIN CAPITAL LETTER F
+0x47	0x0047	#LATIN CAPITAL LETTER G
+0x48	0x0048	#LATIN CAPITAL LETTER H
+0x49	0x0049	#LATIN CAPITAL LETTER I
+0x4a	0x004a	#LATIN CAPITAL LETTER J
+0x4b	0x004b	#LATIN CAPITAL LETTER K
+0x4c	0x004c	#LATIN CAPITAL LETTER L
+0x4d	0x004d	#LATIN CAPITAL LETTER M
+0x4e	0x004e	#LATIN CAPITAL LETTER N
+0x4f	0x004f	#LATIN CAPITAL LETTER O
+0x50	0x0050	#LATIN CAPITAL LETTER P
+0x51	0x0051	#LATIN CAPITAL LETTER Q
+0x52	0x0052	#LATIN CAPITAL LETTER R
+0x53	0x0053	#LATIN CAPITAL LETTER S
+0x54	0x0054	#LATIN CAPITAL LETTER T
+0x55	0x0055	#LATIN CAPITAL LETTER U
+0x56	0x0056	#LATIN CAPITAL LETTER V
+0x57	0x0057	#LATIN CAPITAL LETTER W
+0x58	0x0058	#LATIN CAPITAL LETTER X
+0x59	0x0059	#LATIN CAPITAL LETTER Y
+0x5a	0x005a	#LATIN CAPITAL LETTER Z
+0x5b	0x005b	#LEFT SQUARE BRACKET
+0x5c	0x005c	#REVERSE SOLIDUS
+0x5d	0x005d	#RIGHT SQUARE BRACKET
+0x5e	0x005e	#CIRCUMFLEX ACCENT
+0x5f	0x005f	#LOW LINE
+0x60	0x0060	#GRAVE ACCENT
+0x61	0x0061	#LATIN SMALL LETTER A
+0x62	0x0062	#LATIN SMALL LETTER B
+0x63	0x0063	#LATIN SMALL LETTER C
+0x64	0x0064	#LATIN SMALL LETTER D
+0x65	0x0065	#LATIN SMALL LETTER E
+0x66	0x0066	#LATIN SMALL LETTER F
+0x67	0x0067	#LATIN SMALL LETTER G
+0x68	0x0068	#LATIN SMALL LETTER H
+0x69	0x0069	#LATIN SMALL LETTER I
+0x6a	0x006a	#LATIN SMALL LETTER J
+0x6b	0x006b	#LATIN SMALL LETTER K
+0x6c	0x006c	#LATIN SMALL LETTER L
+0x6d	0x006d	#LATIN SMALL LETTER M
+0x6e	0x006e	#LATIN SMALL LETTER N
+0x6f	0x006f	#LATIN SMALL LETTER O
+0x70	0x0070	#LATIN SMALL LETTER P
+0x71	0x0071	#LATIN SMALL LETTER Q
+0x72	0x0072	#LATIN SMALL LETTER R
+0x73	0x0073	#LATIN SMALL LETTER S
+0x74	0x0074	#LATIN SMALL LETTER T
+0x75	0x0075	#LATIN SMALL LETTER U
+0x76	0x0076	#LATIN SMALL LETTER V
+0x77	0x0077	#LATIN SMALL LETTER W
+0x78	0x0078	#LATIN SMALL LETTER X
+0x79	0x0079	#LATIN SMALL LETTER Y
+0x7a	0x007a	#LATIN SMALL LETTER Z
+0x7b	0x007b	#LEFT CURLY BRACKET
+0x7c	0x007c	#VERTICAL LINE
+0x7d	0x007d	#RIGHT CURLY BRACKET
+0x7e	0x007e	#TILDE
+0x7f	0x007f	#DELETE
+0x80	0x0452	#CYRILLIC SMALL LETTER DJE
+0x81	0x0402	#CYRILLIC CAPITAL LETTER DJE
+0x82	0x0453	#CYRILLIC SMALL LETTER GJE
+0x83	0x0403	#CYRILLIC CAPITAL LETTER GJE
+0x84	0x0451	#CYRILLIC SMALL LETTER IO
+0x85	0x0401	#CYRILLIC CAPITAL LETTER IO
+0x86	0x0454	#CYRILLIC SMALL LETTER UKRAINIAN IE
+0x87	0x0404	#CYRILLIC CAPITAL LETTER UKRAINIAN IE
+0x88	0x0455	#CYRILLIC SMALL LETTER DZE
+0x89	0x0405	#CYRILLIC CAPITAL LETTER DZE
+0x8a	0x0456	#CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I
+0x8b	0x0406	#CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I
+0x8c	0x0457	#CYRILLIC SMALL LETTER YI
+0x8d	0x0407	#CYRILLIC CAPITAL LETTER YI
+0x8e	0x0458	#CYRILLIC SMALL LETTER JE
+0x8f	0x0408	#CYRILLIC CAPITAL LETTER JE
+0x90	0x0459	#CYRILLIC SMALL LETTER LJE
+0x91	0x0409	#CYRILLIC CAPITAL LETTER LJE
+0x92	0x045a	#CYRILLIC SMALL LETTER NJE
+0x93	0x040a	#CYRILLIC CAPITAL LETTER NJE
+0x94	0x045b	#CYRILLIC SMALL LETTER TSHE
+0x95	0x040b	#CYRILLIC CAPITAL LETTER TSHE
+0x96	0x045c	#CYRILLIC SMALL LETTER KJE
+0x97	0x040c	#CYRILLIC CAPITAL LETTER KJE
+0x98	0x045e	#CYRILLIC SMALL LETTER SHORT U
+0x99	0x040e	#CYRILLIC CAPITAL LETTER SHORT U
+0x9a	0x045f	#CYRILLIC SMALL LETTER DZHE
+0x9b	0x040f	#CYRILLIC CAPITAL LETTER DZHE
+0x9c	0x044e	#CYRILLIC SMALL LETTER YU
+0x9d	0x042e	#CYRILLIC CAPITAL LETTER YU
+0x9e	0x044a	#CYRILLIC SMALL LETTER HARD SIGN
+0x9f	0x042a	#CYRILLIC CAPITAL LETTER HARD SIGN
+0xa0	0x0430	#CYRILLIC SMALL LETTER A
+0xa1	0x0410	#CYRILLIC CAPITAL LETTER A
+0xa2	0x0431	#CYRILLIC SMALL LETTER BE
+0xa3	0x0411	#CYRILLIC CAPITAL LETTER BE
+0xa4	0x0446	#CYRILLIC SMALL LETTER TSE
+0xa5	0x0426	#CYRILLIC CAPITAL LETTER TSE
+0xa6	0x0434	#CYRILLIC SMALL LETTER DE
+0xa7	0x0414	#CYRILLIC CAPITAL LETTER DE
+0xa8	0x0435	#CYRILLIC SMALL LETTER IE
+0xa9	0x0415	#CYRILLIC CAPITAL LETTER IE
+0xaa	0x0444	#CYRILLIC SMALL LETTER EF
+0xab	0x0424	#CYRILLIC CAPITAL LETTER EF
+0xac	0x0433	#CYRILLIC SMALL LETTER GHE
+0xad	0x0413	#CYRILLIC CAPITAL LETTER GHE
+0xae	0x00ab	#LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+0xaf	0x00bb	#RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+0xb0	0x2591	#LIGHT SHADE
+0xb1	0x2592	#MEDIUM SHADE
+0xb2	0x2593	#DARK SHADE
+0xb3	0x2502	#BOX DRAWINGS LIGHT VERTICAL
+0xb4	0x2524	#BOX DRAWINGS LIGHT VERTICAL AND LEFT
+0xb5	0x0445	#CYRILLIC SMALL LETTER HA
+0xb6	0x0425	#CYRILLIC CAPITAL LETTER HA
+0xb7	0x0438	#CYRILLIC SMALL LETTER I
+0xb8	0x0418	#CYRILLIC CAPITAL LETTER I
+0xb9	0x2563	#BOX DRAWINGS DOUBLE VERTICAL AND LEFT
+0xba	0x2551	#BOX DRAWINGS DOUBLE VERTICAL
+0xbb	0x2557	#BOX DRAWINGS DOUBLE DOWN AND LEFT
+0xbc	0x255d	#BOX DRAWINGS DOUBLE UP AND LEFT
+0xbd	0x0439	#CYRILLIC SMALL LETTER SHORT I
+0xbe	0x0419	#CYRILLIC CAPITAL LETTER SHORT I
+0xbf	0x2510	#BOX DRAWINGS LIGHT DOWN AND LEFT
+0xc0	0x2514	#BOX DRAWINGS LIGHT UP AND RIGHT
+0xc1	0x2534	#BOX DRAWINGS LIGHT UP AND HORIZONTAL
+0xc2	0x252c	#BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
+0xc3	0x251c	#BOX DRAWINGS LIGHT VERTICAL AND RIGHT
+0xc4	0x2500	#BOX DRAWINGS LIGHT HORIZONTAL
+0xc5	0x253c	#BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
+0xc6	0x043a	#CYRILLIC SMALL LETTER KA
+0xc7	0x041a	#CYRILLIC CAPITAL LETTER KA
+0xc8	0x255a	#BOX DRAWINGS DOUBLE UP AND RIGHT
+0xc9	0x2554	#BOX DRAWINGS DOUBLE DOWN AND RIGHT
+0xca	0x2569	#BOX DRAWINGS DOUBLE UP AND HORIZONTAL
+0xcb	0x2566	#BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL
+0xcc	0x2560	#BOX DRAWINGS DOUBLE VERTICAL AND RIGHT
+0xcd	0x2550	#BOX DRAWINGS DOUBLE HORIZONTAL
+0xce	0x256c	#BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL
+0xcf	0x00a4	#CURRENCY SIGN
+0xd0	0x043b	#CYRILLIC SMALL LETTER EL
+0xd1	0x041b	#CYRILLIC CAPITAL LETTER EL
+0xd2	0x043c	#CYRILLIC SMALL LETTER EM
+0xd3	0x041c	#CYRILLIC CAPITAL LETTER EM
+0xd4	0x043d	#CYRILLIC SMALL LETTER EN
+0xd5	0x041d	#CYRILLIC CAPITAL LETTER EN
+0xd6	0x043e	#CYRILLIC SMALL LETTER O
+0xd7	0x041e	#CYRILLIC CAPITAL LETTER O
+0xd8	0x043f	#CYRILLIC SMALL LETTER PE
+0xd9	0x2518	#BOX DRAWINGS LIGHT UP AND LEFT
+0xda	0x250c	#BOX DRAWINGS LIGHT DOWN AND RIGHT
+0xdb	0x2588	#FULL BLOCK
+0xdc	0x2584	#LOWER HALF BLOCK
+0xdd	0x041f	#CYRILLIC CAPITAL LETTER PE
+0xde	0x044f	#CYRILLIC SMALL LETTER YA
+0xdf	0x2580	#UPPER HALF BLOCK
+0xe0	0x042f	#CYRILLIC CAPITAL LETTER YA
+0xe1	0x0440	#CYRILLIC SMALL LETTER ER
+0xe2	0x0420	#CYRILLIC CAPITAL LETTER ER
+0xe3	0x0441	#CYRILLIC SMALL LETTER ES
+0xe4	0x0421	#CYRILLIC CAPITAL LETTER ES
+0xe5	0x0442	#CYRILLIC SMALL LETTER TE
+0xe6	0x0422	#CYRILLIC CAPITAL LETTER TE
+0xe7	0x0443	#CYRILLIC SMALL LETTER U
+0xe8	0x0423	#CYRILLIC CAPITAL LETTER U
+0xe9	0x0436	#CYRILLIC SMALL LETTER ZHE
+0xea	0x0416	#CYRILLIC CAPITAL LETTER ZHE
+0xeb	0x0432	#CYRILLIC SMALL LETTER VE
+0xec	0x0412	#CYRILLIC CAPITAL LETTER VE
+0xed	0x044c	#CYRILLIC SMALL LETTER SOFT SIGN
+0xee	0x042c	#CYRILLIC CAPITAL LETTER SOFT SIGN
+0xef	0x2116	#NUMERO SIGN
+0xf0	0x00ad	#SOFT HYPHEN
+0xf1	0x044b	#CYRILLIC SMALL LETTER YERU
+0xf2	0x042b	#CYRILLIC CAPITAL LETTER YERU
+0xf3	0x0437	#CYRILLIC SMALL LETTER ZE
+0xf4	0x0417	#CYRILLIC CAPITAL LETTER ZE
+0xf5	0x0448	#CYRILLIC SMALL LETTER SHA
+0xf6	0x0428	#CYRILLIC CAPITAL LETTER SHA
+0xf7	0x044d	#CYRILLIC SMALL LETTER E
+0xf8	0x042d	#CYRILLIC CAPITAL LETTER E
+0xf9	0x0449	#CYRILLIC SMALL LETTER SHCHA
+0xfa	0x0429	#CYRILLIC CAPITAL LETTER SHCHA
+0xfb	0x0447	#CYRILLIC SMALL LETTER CHE
+0xfc	0x0427	#CYRILLIC CAPITAL LETTER CHE
+0xfd	0x00a7	#SECTION SIGN
+0xfe	0x25a0	#BLACK SQUARE
+0xff	0x00a0	#NO-BREAK SPACE
+
diff --git a/tools/encoding/cp857.txt b/tools/encoding/cp857.txt
new file mode 100644
index 0000000..3059383
--- /dev/null
+++ b/tools/encoding/cp857.txt
@@ -0,0 +1,274 @@
+#
+#    Name:     cp857_DOSTurkish to Unicode table
+#    Unicode version: 2.0
+#    Table version: 2.00
+#    Table format:  Format A
+#    Date:          04/24/96
+#    Authors:       Lori Brownell <loribr@microsoft.com>
+#                   K.D. Chang    <a-kchang@microsoft.com>
+#    General notes: none
+#
+#    Format: Three tab-separated columns
+#        Column #1 is the cp857_DOSTurkish code (in hex)
+#        Column #2 is the Unicode (in hex as 0xXXXX)
+#        Column #3 is the Unicode name (follows a comment sign, '#')
+#
+#    The entries are in cp857_DOSTurkish order
+#
+0x00	0x0000	#NULL
+0x01	0x0001	#START OF HEADING
+0x02	0x0002	#START OF TEXT
+0x03	0x0003	#END OF TEXT
+0x04	0x0004	#END OF TRANSMISSION
+0x05	0x0005	#ENQUIRY
+0x06	0x0006	#ACKNOWLEDGE
+0x07	0x0007	#BELL
+0x08	0x0008	#BACKSPACE
+0x09	0x0009	#HORIZONTAL TABULATION
+0x0a	0x000a	#LINE FEED
+0x0b	0x000b	#VERTICAL TABULATION
+0x0c	0x000c	#FORM FEED
+0x0d	0x000d	#CARRIAGE RETURN
+0x0e	0x000e	#SHIFT OUT
+0x0f	0x000f	#SHIFT IN
+0x10	0x0010	#DATA LINK ESCAPE
+0x11	0x0011	#DEVICE CONTROL ONE
+0x12	0x0012	#DEVICE CONTROL TWO
+0x13	0x0013	#DEVICE CONTROL THREE
+0x14	0x0014	#DEVICE CONTROL FOUR
+0x15	0x0015	#NEGATIVE ACKNOWLEDGE
+0x16	0x0016	#SYNCHRONOUS IDLE
+0x17	0x0017	#END OF TRANSMISSION BLOCK
+0x18	0x0018	#CANCEL
+0x19	0x0019	#END OF MEDIUM
+0x1a	0x001a	#SUBSTITUTE
+0x1b	0x001b	#ESCAPE
+0x1c	0x001c	#FILE SEPARATOR
+0x1d	0x001d	#GROUP SEPARATOR
+0x1e	0x001e	#RECORD SEPARATOR
+0x1f	0x001f	#UNIT SEPARATOR
+0x20	0x0020	#SPACE
+0x21	0x0021	#EXCLAMATION MARK
+0x22	0x0022	#QUOTATION MARK
+0x23	0x0023	#NUMBER SIGN
+0x24	0x0024	#DOLLAR SIGN
+0x25	0x0025	#PERCENT SIGN
+0x26	0x0026	#AMPERSAND
+0x27	0x0027	#APOSTROPHE
+0x28	0x0028	#LEFT PARENTHESIS
+0x29	0x0029	#RIGHT PARENTHESIS
+0x2a	0x002a	#ASTERISK
+0x2b	0x002b	#PLUS SIGN
+0x2c	0x002c	#COMMA
+0x2d	0x002d	#HYPHEN-MINUS
+0x2e	0x002e	#FULL STOP
+0x2f	0x002f	#SOLIDUS
+0x30	0x0030	#DIGIT ZERO
+0x31	0x0031	#DIGIT ONE
+0x32	0x0032	#DIGIT TWO
+0x33	0x0033	#DIGIT THREE
+0x34	0x0034	#DIGIT FOUR
+0x35	0x0035	#DIGIT FIVE
+0x36	0x0036	#DIGIT SIX
+0x37	0x0037	#DIGIT SEVEN
+0x38	0x0038	#DIGIT EIGHT
+0x39	0x0039	#DIGIT NINE
+0x3a	0x003a	#COLON
+0x3b	0x003b	#SEMICOLON
+0x3c	0x003c	#LESS-THAN SIGN
+0x3d	0x003d	#EQUALS SIGN
+0x3e	0x003e	#GREATER-THAN SIGN
+0x3f	0x003f	#QUESTION MARK
+0x40	0x0040	#COMMERCIAL AT
+0x41	0x0041	#LATIN CAPITAL LETTER A
+0x42	0x0042	#LATIN CAPITAL LETTER B
+0x43	0x0043	#LATIN CAPITAL LETTER C
+0x44	0x0044	#LATIN CAPITAL LETTER D
+0x45	0x0045	#LATIN CAPITAL LETTER E
+0x46	0x0046	#LATIN CAPITAL LETTER F
+0x47	0x0047	#LATIN CAPITAL LETTER G
+0x48	0x0048	#LATIN CAPITAL LETTER H
+0x49	0x0049	#LATIN CAPITAL LETTER I
+0x4a	0x004a	#LATIN CAPITAL LETTER J
+0x4b	0x004b	#LATIN CAPITAL LETTER K
+0x4c	0x004c	#LATIN CAPITAL LETTER L
+0x4d	0x004d	#LATIN CAPITAL LETTER M
+0x4e	0x004e	#LATIN CAPITAL LETTER N
+0x4f	0x004f	#LATIN CAPITAL LETTER O
+0x50	0x0050	#LATIN CAPITAL LETTER P
+0x51	0x0051	#LATIN CAPITAL LETTER Q
+0x52	0x0052	#LATIN CAPITAL LETTER R
+0x53	0x0053	#LATIN CAPITAL LETTER S
+0x54	0x0054	#LATIN CAPITAL LETTER T
+0x55	0x0055	#LATIN CAPITAL LETTER U
+0x56	0x0056	#LATIN CAPITAL LETTER V
+0x57	0x0057	#LATIN CAPITAL LETTER W
+0x58	0x0058	#LATIN CAPITAL LETTER X
+0x59	0x0059	#LATIN CAPITAL LETTER Y
+0x5a	0x005a	#LATIN CAPITAL LETTER Z
+0x5b	0x005b	#LEFT SQUARE BRACKET
+0x5c	0x005c	#REVERSE SOLIDUS
+0x5d	0x005d	#RIGHT SQUARE BRACKET
+0x5e	0x005e	#CIRCUMFLEX ACCENT
+0x5f	0x005f	#LOW LINE
+0x60	0x0060	#GRAVE ACCENT
+0x61	0x0061	#LATIN SMALL LETTER A
+0x62	0x0062	#LATIN SMALL LETTER B
+0x63	0x0063	#LATIN SMALL LETTER C
+0x64	0x0064	#LATIN SMALL LETTER D
+0x65	0x0065	#LATIN SMALL LETTER E
+0x66	0x0066	#LATIN SMALL LETTER F
+0x67	0x0067	#LATIN SMALL LETTER G
+0x68	0x0068	#LATIN SMALL LETTER H
+0x69	0x0069	#LATIN SMALL LETTER I
+0x6a	0x006a	#LATIN SMALL LETTER J
+0x6b	0x006b	#LATIN SMALL LETTER K
+0x6c	0x006c	#LATIN SMALL LETTER L
+0x6d	0x006d	#LATIN SMALL LETTER M
+0x6e	0x006e	#LATIN SMALL LETTER N
+0x6f	0x006f	#LATIN SMALL LETTER O
+0x70	0x0070	#LATIN SMALL LETTER P
+0x71	0x0071	#LATIN SMALL LETTER Q
+0x72	0x0072	#LATIN SMALL LETTER R
+0x73	0x0073	#LATIN SMALL LETTER S
+0x74	0x0074	#LATIN SMALL LETTER T
+0x75	0x0075	#LATIN SMALL LETTER U
+0x76	0x0076	#LATIN SMALL LETTER V
+0x77	0x0077	#LATIN SMALL LETTER W
+0x78	0x0078	#LATIN SMALL LETTER X
+0x79	0x0079	#LATIN SMALL LETTER Y
+0x7a	0x007a	#LATIN SMALL LETTER Z
+0x7b	0x007b	#LEFT CURLY BRACKET
+0x7c	0x007c	#VERTICAL LINE
+0x7d	0x007d	#RIGHT CURLY BRACKET
+0x7e	0x007e	#TILDE
+0x7f	0x007f	#DELETE
+0x80	0x00c7	#LATIN CAPITAL LETTER C WITH CEDILLA
+0x81	0x00fc	#LATIN SMALL LETTER U WITH DIAERESIS
+0x82	0x00e9	#LATIN SMALL LETTER E WITH ACUTE
+0x83	0x00e2	#LATIN SMALL LETTER A WITH CIRCUMFLEX
+0x84	0x00e4	#LATIN SMALL LETTER A WITH DIAERESIS
+0x85	0x00e0	#LATIN SMALL LETTER A WITH GRAVE
+0x86	0x00e5	#LATIN SMALL LETTER A WITH RING ABOVE
+0x87	0x00e7	#LATIN SMALL LETTER C WITH CEDILLA
+0x88	0x00ea	#LATIN SMALL LETTER E WITH CIRCUMFLEX
+0x89	0x00eb	#LATIN SMALL LETTER E WITH DIAERESIS
+0x8a	0x00e8	#LATIN SMALL LETTER E WITH GRAVE
+0x8b	0x00ef	#LATIN SMALL LETTER I WITH DIAERESIS
+0x8c	0x00ee	#LATIN SMALL LETTER I WITH CIRCUMFLEX
+0x8d	0x0131	#LATIN SMALL LETTER DOTLESS I
+0x8e	0x00c4	#LATIN CAPITAL LETTER A WITH DIAERESIS
+0x8f	0x00c5	#LATIN CAPITAL LETTER A WITH RING ABOVE
+0x90	0x00c9	#LATIN CAPITAL LETTER E WITH ACUTE
+0x91	0x00e6	#LATIN SMALL LIGATURE AE
+0x92	0x00c6	#LATIN CAPITAL LIGATURE AE
+0x93	0x00f4	#LATIN SMALL LETTER O WITH CIRCUMFLEX
+0x94	0x00f6	#LATIN SMALL LETTER O WITH DIAERESIS
+0x95	0x00f2	#LATIN SMALL LETTER O WITH GRAVE
+0x96	0x00fb	#LATIN SMALL LETTER U WITH CIRCUMFLEX
+0x97	0x00f9	#LATIN SMALL LETTER U WITH GRAVE
+0x98	0x0130	#LATIN CAPITAL LETTER I WITH DOT ABOVE
+0x99	0x00d6	#LATIN CAPITAL LETTER O WITH DIAERESIS
+0x9a	0x00dc	#LATIN CAPITAL LETTER U WITH DIAERESIS
+0x9b	0x00f8	#LATIN SMALL LETTER O WITH STROKE
+0x9c	0x00a3	#POUND SIGN
+0x9d	0x00d8	#LATIN CAPITAL LETTER O WITH STROKE
+0x9e	0x015e	#LATIN CAPITAL LETTER S WITH CEDILLA
+0x9f	0x015f	#LATIN SMALL LETTER S WITH CEDILLA
+0xa0	0x00e1	#LATIN SMALL LETTER A WITH ACUTE
+0xa1	0x00ed	#LATIN SMALL LETTER I WITH ACUTE
+0xa2	0x00f3	#LATIN SMALL LETTER O WITH ACUTE
+0xa3	0x00fa	#LATIN SMALL LETTER U WITH ACUTE
+0xa4	0x00f1	#LATIN SMALL LETTER N WITH TILDE
+0xa5	0x00d1	#LATIN CAPITAL LETTER N WITH TILDE
+0xa6	0x011e	#LATIN CAPITAL LETTER G WITH BREVE
+0xa7	0x011f	#LATIN SMALL LETTER G WITH BREVE
+0xa8	0x00bf	#INVERTED QUESTION MARK
+0xa9	0x00ae	#REGISTERED SIGN
+0xaa	0x00ac	#NOT SIGN
+0xab	0x00bd	#VULGAR FRACTION ONE HALF
+0xac	0x00bc	#VULGAR FRACTION ONE QUARTER
+0xad	0x00a1	#INVERTED EXCLAMATION MARK
+0xae	0x00ab	#LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+0xaf	0x00bb	#RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+0xb0	0x2591	#LIGHT SHADE
+0xb1	0x2592	#MEDIUM SHADE
+0xb2	0x2593	#DARK SHADE
+0xb3	0x2502	#BOX DRAWINGS LIGHT VERTICAL
+0xb4	0x2524	#BOX DRAWINGS LIGHT VERTICAL AND LEFT
+0xb5	0x00c1	#LATIN CAPITAL LETTER A WITH ACUTE
+0xb6	0x00c2	#LATIN CAPITAL LETTER A WITH CIRCUMFLEX
+0xb7	0x00c0	#LATIN CAPITAL LETTER A WITH GRAVE
+0xb8	0x00a9	#COPYRIGHT SIGN
+0xb9	0x2563	#BOX DRAWINGS DOUBLE VERTICAL AND LEFT
+0xba	0x2551	#BOX DRAWINGS DOUBLE VERTICAL
+0xbb	0x2557	#BOX DRAWINGS DOUBLE DOWN AND LEFT
+0xbc	0x255d	#BOX DRAWINGS DOUBLE UP AND LEFT
+0xbd	0x00a2	#CENT SIGN
+0xbe	0x00a5	#YEN SIGN
+0xbf	0x2510	#BOX DRAWINGS LIGHT DOWN AND LEFT
+0xc0	0x2514	#BOX DRAWINGS LIGHT UP AND RIGHT
+0xc1	0x2534	#BOX DRAWINGS LIGHT UP AND HORIZONTAL
+0xc2	0x252c	#BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
+0xc3	0x251c	#BOX DRAWINGS LIGHT VERTICAL AND RIGHT
+0xc4	0x2500	#BOX DRAWINGS LIGHT HORIZONTAL
+0xc5	0x253c	#BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
+0xc6	0x00e3	#LATIN SMALL LETTER A WITH TILDE
+0xc7	0x00c3	#LATIN CAPITAL LETTER A WITH TILDE
+0xc8	0x255a	#BOX DRAWINGS DOUBLE UP AND RIGHT
+0xc9	0x2554	#BOX DRAWINGS DOUBLE DOWN AND RIGHT
+0xca	0x2569	#BOX DRAWINGS DOUBLE UP AND HORIZONTAL
+0xcb	0x2566	#BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL
+0xcc	0x2560	#BOX DRAWINGS DOUBLE VERTICAL AND RIGHT
+0xcd	0x2550	#BOX DRAWINGS DOUBLE HORIZONTAL
+0xce	0x256c	#BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL
+0xcf	0x00a4	#CURRENCY SIGN
+0xd0	0x00ba	#MASCULINE ORDINAL INDICATOR
+0xd1	0x00aa	#FEMININE ORDINAL INDICATOR
+0xd2	0x00ca	#LATIN CAPITAL LETTER E WITH CIRCUMFLEX
+0xd3	0x00cb	#LATIN CAPITAL LETTER E WITH DIAERESIS
+0xd4	0x00c8	#LATIN CAPITAL LETTER E WITH GRAVE
+0xd5		#UNDEFINED
+0xd6	0x00cd	#LATIN CAPITAL LETTER I WITH ACUTE
+0xd7	0x00ce	#LATIN CAPITAL LETTER I WITH CIRCUMFLEX
+0xd8	0x00cf	#LATIN CAPITAL LETTER I WITH DIAERESIS
+0xd9	0x2518	#BOX DRAWINGS LIGHT UP AND LEFT
+0xda	0x250c	#BOX DRAWINGS LIGHT DOWN AND RIGHT
+0xdb	0x2588	#FULL BLOCK
+0xdc	0x2584	#LOWER HALF BLOCK
+0xdd	0x00a6	#BROKEN BAR
+0xde	0x00cc	#LATIN CAPITAL LETTER I WITH GRAVE
+0xdf	0x2580	#UPPER HALF BLOCK
+0xe0	0x00d3	#LATIN CAPITAL LETTER O WITH ACUTE
+0xe1	0x00df	#LATIN SMALL LETTER SHARP S
+0xe2	0x00d4	#LATIN CAPITAL LETTER O WITH CIRCUMFLEX
+0xe3	0x00d2	#LATIN CAPITAL LETTER O WITH GRAVE
+0xe4	0x00f5	#LATIN SMALL LETTER O WITH TILDE
+0xe5	0x00d5	#LATIN CAPITAL LETTER O WITH TILDE
+0xe6	0x00b5	#MICRO SIGN
+0xe7		#UNDEFINED
+0xe8	0x00d7	#MULTIPLICATION SIGN
+0xe9	0x00da	#LATIN CAPITAL LETTER U WITH ACUTE
+0xea	0x00db	#LATIN CAPITAL LETTER U WITH CIRCUMFLEX
+0xeb	0x00d9	#LATIN CAPITAL LETTER U WITH GRAVE
+0xec	0x00ec	#LATIN SMALL LETTER I WITH GRAVE
+0xed	0x00ff	#LATIN SMALL LETTER Y WITH DIAERESIS
+0xee	0x00af	#MACRON
+0xef	0x00b4	#ACUTE ACCENT
+0xf0	0x00ad	#SOFT HYPHEN
+0xf1	0x00b1	#PLUS-MINUS SIGN
+0xf2		#UNDEFINED
+0xf3	0x00be	#VULGAR FRACTION THREE QUARTERS
+0xf4	0x00b6	#PILCROW SIGN
+0xf5	0x00a7	#SECTION SIGN
+0xf6	0x00f7	#DIVISION SIGN
+0xf7	0x00b8	#CEDILLA
+0xf8	0x00b0	#DEGREE SIGN
+0xf9	0x00a8	#DIAERESIS
+0xfa	0x00b7	#MIDDLE DOT
+0xfb	0x00b9	#SUPERSCRIPT ONE
+0xfc	0x00b3	#SUPERSCRIPT THREE
+0xfd	0x00b2	#SUPERSCRIPT TWO
+0xfe	0x25a0	#BLACK SQUARE
+0xff	0x00a0	#NO-BREAK SPACE
+
diff --git a/tools/encoding/cp860.txt b/tools/encoding/cp860.txt
new file mode 100644
index 0000000..d7f2cb7
--- /dev/null
+++ b/tools/encoding/cp860.txt
@@ -0,0 +1,274 @@
+#
+#    Name:     cp860_DOSPortuguese to Unicode table
+#    Unicode version: 2.0
+#    Table version: 2.00
+#    Table format:  Format A
+#    Date:          04/24/96
+#    Authors:       Lori Brownell <loribr@microsoft.com>
+#                   K.D. Chang    <a-kchang@microsoft.com>
+#    General notes: none
+#
+#    Format: Three tab-separated columns
+#        Column #1 is the cp860_DOSPortuguese code (in hex)
+#        Column #2 is the Unicode (in hex as 0xXXXX)
+#        Column #3 is the Unicode name (follows a comment sign, '#')
+#
+#    The entries are in cp860_DOSPortuguese order
+#
+0x00	0x0000	#NULL
+0x01	0x0001	#START OF HEADING
+0x02	0x0002	#START OF TEXT
+0x03	0x0003	#END OF TEXT
+0x04	0x0004	#END OF TRANSMISSION
+0x05	0x0005	#ENQUIRY
+0x06	0x0006	#ACKNOWLEDGE
+0x07	0x0007	#BELL
+0x08	0x0008	#BACKSPACE
+0x09	0x0009	#HORIZONTAL TABULATION
+0x0a	0x000a	#LINE FEED
+0x0b	0x000b	#VERTICAL TABULATION
+0x0c	0x000c	#FORM FEED
+0x0d	0x000d	#CARRIAGE RETURN
+0x0e	0x000e	#SHIFT OUT
+0x0f	0x000f	#SHIFT IN
+0x10	0x0010	#DATA LINK ESCAPE
+0x11	0x0011	#DEVICE CONTROL ONE
+0x12	0x0012	#DEVICE CONTROL TWO
+0x13	0x0013	#DEVICE CONTROL THREE
+0x14	0x0014	#DEVICE CONTROL FOUR
+0x15	0x0015	#NEGATIVE ACKNOWLEDGE
+0x16	0x0016	#SYNCHRONOUS IDLE
+0x17	0x0017	#END OF TRANSMISSION BLOCK
+0x18	0x0018	#CANCEL
+0x19	0x0019	#END OF MEDIUM
+0x1a	0x001a	#SUBSTITUTE
+0x1b	0x001b	#ESCAPE
+0x1c	0x001c	#FILE SEPARATOR
+0x1d	0x001d	#GROUP SEPARATOR
+0x1e	0x001e	#RECORD SEPARATOR
+0x1f	0x001f	#UNIT SEPARATOR
+0x20	0x0020	#SPACE
+0x21	0x0021	#EXCLAMATION MARK
+0x22	0x0022	#QUOTATION MARK
+0x23	0x0023	#NUMBER SIGN
+0x24	0x0024	#DOLLAR SIGN
+0x25	0x0025	#PERCENT SIGN
+0x26	0x0026	#AMPERSAND
+0x27	0x0027	#APOSTROPHE
+0x28	0x0028	#LEFT PARENTHESIS
+0x29	0x0029	#RIGHT PARENTHESIS
+0x2a	0x002a	#ASTERISK
+0x2b	0x002b	#PLUS SIGN
+0x2c	0x002c	#COMMA
+0x2d	0x002d	#HYPHEN-MINUS
+0x2e	0x002e	#FULL STOP
+0x2f	0x002f	#SOLIDUS
+0x30	0x0030	#DIGIT ZERO
+0x31	0x0031	#DIGIT ONE
+0x32	0x0032	#DIGIT TWO
+0x33	0x0033	#DIGIT THREE
+0x34	0x0034	#DIGIT FOUR
+0x35	0x0035	#DIGIT FIVE
+0x36	0x0036	#DIGIT SIX
+0x37	0x0037	#DIGIT SEVEN
+0x38	0x0038	#DIGIT EIGHT
+0x39	0x0039	#DIGIT NINE
+0x3a	0x003a	#COLON
+0x3b	0x003b	#SEMICOLON
+0x3c	0x003c	#LESS-THAN SIGN
+0x3d	0x003d	#EQUALS SIGN
+0x3e	0x003e	#GREATER-THAN SIGN
+0x3f	0x003f	#QUESTION MARK
+0x40	0x0040	#COMMERCIAL AT
+0x41	0x0041	#LATIN CAPITAL LETTER A
+0x42	0x0042	#LATIN CAPITAL LETTER B
+0x43	0x0043	#LATIN CAPITAL LETTER C
+0x44	0x0044	#LATIN CAPITAL LETTER D
+0x45	0x0045	#LATIN CAPITAL LETTER E
+0x46	0x0046	#LATIN CAPITAL LETTER F
+0x47	0x0047	#LATIN CAPITAL LETTER G
+0x48	0x0048	#LATIN CAPITAL LETTER H
+0x49	0x0049	#LATIN CAPITAL LETTER I
+0x4a	0x004a	#LATIN CAPITAL LETTER J
+0x4b	0x004b	#LATIN CAPITAL LETTER K
+0x4c	0x004c	#LATIN CAPITAL LETTER L
+0x4d	0x004d	#LATIN CAPITAL LETTER M
+0x4e	0x004e	#LATIN CAPITAL LETTER N
+0x4f	0x004f	#LATIN CAPITAL LETTER O
+0x50	0x0050	#LATIN CAPITAL LETTER P
+0x51	0x0051	#LATIN CAPITAL LETTER Q
+0x52	0x0052	#LATIN CAPITAL LETTER R
+0x53	0x0053	#LATIN CAPITAL LETTER S
+0x54	0x0054	#LATIN CAPITAL LETTER T
+0x55	0x0055	#LATIN CAPITAL LETTER U
+0x56	0x0056	#LATIN CAPITAL LETTER V
+0x57	0x0057	#LATIN CAPITAL LETTER W
+0x58	0x0058	#LATIN CAPITAL LETTER X
+0x59	0x0059	#LATIN CAPITAL LETTER Y
+0x5a	0x005a	#LATIN CAPITAL LETTER Z
+0x5b	0x005b	#LEFT SQUARE BRACKET
+0x5c	0x005c	#REVERSE SOLIDUS
+0x5d	0x005d	#RIGHT SQUARE BRACKET
+0x5e	0x005e	#CIRCUMFLEX ACCENT
+0x5f	0x005f	#LOW LINE
+0x60	0x0060	#GRAVE ACCENT
+0x61	0x0061	#LATIN SMALL LETTER A
+0x62	0x0062	#LATIN SMALL LETTER B
+0x63	0x0063	#LATIN SMALL LETTER C
+0x64	0x0064	#LATIN SMALL LETTER D
+0x65	0x0065	#LATIN SMALL LETTER E
+0x66	0x0066	#LATIN SMALL LETTER F
+0x67	0x0067	#LATIN SMALL LETTER G
+0x68	0x0068	#LATIN SMALL LETTER H
+0x69	0x0069	#LATIN SMALL LETTER I
+0x6a	0x006a	#LATIN SMALL LETTER J
+0x6b	0x006b	#LATIN SMALL LETTER K
+0x6c	0x006c	#LATIN SMALL LETTER L
+0x6d	0x006d	#LATIN SMALL LETTER M
+0x6e	0x006e	#LATIN SMALL LETTER N
+0x6f	0x006f	#LATIN SMALL LETTER O
+0x70	0x0070	#LATIN SMALL LETTER P
+0x71	0x0071	#LATIN SMALL LETTER Q
+0x72	0x0072	#LATIN SMALL LETTER R
+0x73	0x0073	#LATIN SMALL LETTER S
+0x74	0x0074	#LATIN SMALL LETTER T
+0x75	0x0075	#LATIN SMALL LETTER U
+0x76	0x0076	#LATIN SMALL LETTER V
+0x77	0x0077	#LATIN SMALL LETTER W
+0x78	0x0078	#LATIN SMALL LETTER X
+0x79	0x0079	#LATIN SMALL LETTER Y
+0x7a	0x007a	#LATIN SMALL LETTER Z
+0x7b	0x007b	#LEFT CURLY BRACKET
+0x7c	0x007c	#VERTICAL LINE
+0x7d	0x007d	#RIGHT CURLY BRACKET
+0x7e	0x007e	#TILDE
+0x7f	0x007f	#DELETE
+0x80	0x00c7	#LATIN CAPITAL LETTER C WITH CEDILLA
+0x81	0x00fc	#LATIN SMALL LETTER U WITH DIAERESIS
+0x82	0x00e9	#LATIN SMALL LETTER E WITH ACUTE
+0x83	0x00e2	#LATIN SMALL LETTER A WITH CIRCUMFLEX
+0x84	0x00e3	#LATIN SMALL LETTER A WITH TILDE
+0x85	0x00e0	#LATIN SMALL LETTER A WITH GRAVE
+0x86	0x00c1	#LATIN CAPITAL LETTER A WITH ACUTE
+0x87	0x00e7	#LATIN SMALL LETTER C WITH CEDILLA
+0x88	0x00ea	#LATIN SMALL LETTER E WITH CIRCUMFLEX
+0x89	0x00ca	#LATIN CAPITAL LETTER E WITH CIRCUMFLEX
+0x8a	0x00e8	#LATIN SMALL LETTER E WITH GRAVE
+0x8b	0x00cd	#LATIN CAPITAL LETTER I WITH ACUTE
+0x8c	0x00d4	#LATIN CAPITAL LETTER O WITH CIRCUMFLEX
+0x8d	0x00ec	#LATIN SMALL LETTER I WITH GRAVE
+0x8e	0x00c3	#LATIN CAPITAL LETTER A WITH TILDE
+0x8f	0x00c2	#LATIN CAPITAL LETTER A WITH CIRCUMFLEX
+0x90	0x00c9	#LATIN CAPITAL LETTER E WITH ACUTE
+0x91	0x00c0	#LATIN CAPITAL LETTER A WITH GRAVE
+0x92	0x00c8	#LATIN CAPITAL LETTER E WITH GRAVE
+0x93	0x00f4	#LATIN SMALL LETTER O WITH CIRCUMFLEX
+0x94	0x00f5	#LATIN SMALL LETTER O WITH TILDE
+0x95	0x00f2	#LATIN SMALL LETTER O WITH GRAVE
+0x96	0x00da	#LATIN CAPITAL LETTER U WITH ACUTE
+0x97	0x00f9	#LATIN SMALL LETTER U WITH GRAVE
+0x98	0x00cc	#LATIN CAPITAL LETTER I WITH GRAVE
+0x99	0x00d5	#LATIN CAPITAL LETTER O WITH TILDE
+0x9a	0x00dc	#LATIN CAPITAL LETTER U WITH DIAERESIS
+0x9b	0x00a2	#CENT SIGN
+0x9c	0x00a3	#POUND SIGN
+0x9d	0x00d9	#LATIN CAPITAL LETTER U WITH GRAVE
+0x9e	0x20a7	#PESETA SIGN
+0x9f	0x00d3	#LATIN CAPITAL LETTER O WITH ACUTE
+0xa0	0x00e1	#LATIN SMALL LETTER A WITH ACUTE
+0xa1	0x00ed	#LATIN SMALL LETTER I WITH ACUTE
+0xa2	0x00f3	#LATIN SMALL LETTER O WITH ACUTE
+0xa3	0x00fa	#LATIN SMALL LETTER U WITH ACUTE
+0xa4	0x00f1	#LATIN SMALL LETTER N WITH TILDE
+0xa5	0x00d1	#LATIN CAPITAL LETTER N WITH TILDE
+0xa6	0x00aa	#FEMININE ORDINAL INDICATOR
+0xa7	0x00ba	#MASCULINE ORDINAL INDICATOR
+0xa8	0x00bf	#INVERTED QUESTION MARK
+0xa9	0x00d2	#LATIN CAPITAL LETTER O WITH GRAVE
+0xaa	0x00ac	#NOT SIGN
+0xab	0x00bd	#VULGAR FRACTION ONE HALF
+0xac	0x00bc	#VULGAR FRACTION ONE QUARTER
+0xad	0x00a1	#INVERTED EXCLAMATION MARK
+0xae	0x00ab	#LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+0xaf	0x00bb	#RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+0xb0	0x2591	#LIGHT SHADE
+0xb1	0x2592	#MEDIUM SHADE
+0xb2	0x2593	#DARK SHADE
+0xb3	0x2502	#BOX DRAWINGS LIGHT VERTICAL
+0xb4	0x2524	#BOX DRAWINGS LIGHT VERTICAL AND LEFT
+0xb5	0x2561	#BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE
+0xb6	0x2562	#BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE
+0xb7	0x2556	#BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE
+0xb8	0x2555	#BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE
+0xb9	0x2563	#BOX DRAWINGS DOUBLE VERTICAL AND LEFT
+0xba	0x2551	#BOX DRAWINGS DOUBLE VERTICAL
+0xbb	0x2557	#BOX DRAWINGS DOUBLE DOWN AND LEFT
+0xbc	0x255d	#BOX DRAWINGS DOUBLE UP AND LEFT
+0xbd	0x255c	#BOX DRAWINGS UP DOUBLE AND LEFT SINGLE
+0xbe	0x255b	#BOX DRAWINGS UP SINGLE AND LEFT DOUBLE
+0xbf	0x2510	#BOX DRAWINGS LIGHT DOWN AND LEFT
+0xc0	0x2514	#BOX DRAWINGS LIGHT UP AND RIGHT
+0xc1	0x2534	#BOX DRAWINGS LIGHT UP AND HORIZONTAL
+0xc2	0x252c	#BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
+0xc3	0x251c	#BOX DRAWINGS LIGHT VERTICAL AND RIGHT
+0xc4	0x2500	#BOX DRAWINGS LIGHT HORIZONTAL
+0xc5	0x253c	#BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
+0xc6	0x255e	#BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE
+0xc7	0x255f	#BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE
+0xc8	0x255a	#BOX DRAWINGS DOUBLE UP AND RIGHT
+0xc9	0x2554	#BOX DRAWINGS DOUBLE DOWN AND RIGHT
+0xca	0x2569	#BOX DRAWINGS DOUBLE UP AND HORIZONTAL
+0xcb	0x2566	#BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL
+0xcc	0x2560	#BOX DRAWINGS DOUBLE VERTICAL AND RIGHT
+0xcd	0x2550	#BOX DRAWINGS DOUBLE HORIZONTAL
+0xce	0x256c	#BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL
+0xcf	0x2567	#BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE
+0xd0	0x2568	#BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE
+0xd1	0x2564	#BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE
+0xd2	0x2565	#BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE
+0xd3	0x2559	#BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE
+0xd4	0x2558	#BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE
+0xd5	0x2552	#BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE
+0xd6	0x2553	#BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE
+0xd7	0x256b	#BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE
+0xd8	0x256a	#BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE
+0xd9	0x2518	#BOX DRAWINGS LIGHT UP AND LEFT
+0xda	0x250c	#BOX DRAWINGS LIGHT DOWN AND RIGHT
+0xdb	0x2588	#FULL BLOCK
+0xdc	0x2584	#LOWER HALF BLOCK
+0xdd	0x258c	#LEFT HALF BLOCK
+0xde	0x2590	#RIGHT HALF BLOCK
+0xdf	0x2580	#UPPER HALF BLOCK
+0xe0	0x03b1	#GREEK SMALL LETTER ALPHA
+0xe1	0x00df	#LATIN SMALL LETTER SHARP S
+0xe2	0x0393	#GREEK CAPITAL LETTER GAMMA
+0xe3	0x03c0	#GREEK SMALL LETTER PI
+0xe4	0x03a3	#GREEK CAPITAL LETTER SIGMA
+0xe5	0x03c3	#GREEK SMALL LETTER SIGMA
+0xe6	0x00b5	#MICRO SIGN
+0xe7	0x03c4	#GREEK SMALL LETTER TAU
+0xe8	0x03a6	#GREEK CAPITAL LETTER PHI
+0xe9	0x0398	#GREEK CAPITAL LETTER THETA
+0xea	0x03a9	#GREEK CAPITAL LETTER OMEGA
+0xeb	0x03b4	#GREEK SMALL LETTER DELTA
+0xec	0x221e	#INFINITY
+0xed	0x03c6	#GREEK SMALL LETTER PHI
+0xee	0x03b5	#GREEK SMALL LETTER EPSILON
+0xef	0x2229	#INTERSECTION
+0xf0	0x2261	#IDENTICAL TO
+0xf1	0x00b1	#PLUS-MINUS SIGN
+0xf2	0x2265	#GREATER-THAN OR EQUAL TO
+0xf3	0x2264	#LESS-THAN OR EQUAL TO
+0xf4	0x2320	#TOP HALF INTEGRAL
+0xf5	0x2321	#BOTTOM HALF INTEGRAL
+0xf6	0x00f7	#DIVISION SIGN
+0xf7	0x2248	#ALMOST EQUAL TO
+0xf8	0x00b0	#DEGREE SIGN
+0xf9	0x2219	#BULLET OPERATOR
+0xfa	0x00b7	#MIDDLE DOT
+0xfb	0x221a	#SQUARE ROOT
+0xfc	0x207f	#SUPERSCRIPT LATIN SMALL LETTER N
+0xfd	0x00b2	#SUPERSCRIPT TWO
+0xfe	0x25a0	#BLACK SQUARE
+0xff	0x00a0	#NO-BREAK SPACE
+
diff --git a/tools/encoding/cp861.txt b/tools/encoding/cp861.txt
new file mode 100644
index 0000000..fe0f02b
--- /dev/null
+++ b/tools/encoding/cp861.txt
@@ -0,0 +1,274 @@
+#
+#    Name:     cp861_DOSIcelandic to Unicode table
+#    Unicode version: 2.0
+#    Table version: 2.00
+#    Table format:  Format A
+#    Date:          04/24/96
+#    Authors:       Lori Brownell <loribr@microsoft.com>
+#                   K.D. Chang    <a-kchang@microsoft.com>
+#    General notes: none
+#
+#    Format: Three tab-separated columns
+#        Column #1 is the cp861_DOSIcelandic code (in hex)
+#        Column #2 is the Unicode (in hex as 0xXXXX)
+#        Column #3 is the Unicode name (follows a comment sign, '#')
+#
+#    The entries are in cp861_DOSIcelandic order
+#
+0x00	0x0000	#NULL
+0x01	0x0001	#START OF HEADING
+0x02	0x0002	#START OF TEXT
+0x03	0x0003	#END OF TEXT
+0x04	0x0004	#END OF TRANSMISSION
+0x05	0x0005	#ENQUIRY
+0x06	0x0006	#ACKNOWLEDGE
+0x07	0x0007	#BELL
+0x08	0x0008	#BACKSPACE
+0x09	0x0009	#HORIZONTAL TABULATION
+0x0a	0x000a	#LINE FEED
+0x0b	0x000b	#VERTICAL TABULATION
+0x0c	0x000c	#FORM FEED
+0x0d	0x000d	#CARRIAGE RETURN
+0x0e	0x000e	#SHIFT OUT
+0x0f	0x000f	#SHIFT IN
+0x10	0x0010	#DATA LINK ESCAPE
+0x11	0x0011	#DEVICE CONTROL ONE
+0x12	0x0012	#DEVICE CONTROL TWO
+0x13	0x0013	#DEVICE CONTROL THREE
+0x14	0x0014	#DEVICE CONTROL FOUR
+0x15	0x0015	#NEGATIVE ACKNOWLEDGE
+0x16	0x0016	#SYNCHRONOUS IDLE
+0x17	0x0017	#END OF TRANSMISSION BLOCK
+0x18	0x0018	#CANCEL
+0x19	0x0019	#END OF MEDIUM
+0x1a	0x001a	#SUBSTITUTE
+0x1b	0x001b	#ESCAPE
+0x1c	0x001c	#FILE SEPARATOR
+0x1d	0x001d	#GROUP SEPARATOR
+0x1e	0x001e	#RECORD SEPARATOR
+0x1f	0x001f	#UNIT SEPARATOR
+0x20	0x0020	#SPACE
+0x21	0x0021	#EXCLAMATION MARK
+0x22	0x0022	#QUOTATION MARK
+0x23	0x0023	#NUMBER SIGN
+0x24	0x0024	#DOLLAR SIGN
+0x25	0x0025	#PERCENT SIGN
+0x26	0x0026	#AMPERSAND
+0x27	0x0027	#APOSTROPHE
+0x28	0x0028	#LEFT PARENTHESIS
+0x29	0x0029	#RIGHT PARENTHESIS
+0x2a	0x002a	#ASTERISK
+0x2b	0x002b	#PLUS SIGN
+0x2c	0x002c	#COMMA
+0x2d	0x002d	#HYPHEN-MINUS
+0x2e	0x002e	#FULL STOP
+0x2f	0x002f	#SOLIDUS
+0x30	0x0030	#DIGIT ZERO
+0x31	0x0031	#DIGIT ONE
+0x32	0x0032	#DIGIT TWO
+0x33	0x0033	#DIGIT THREE
+0x34	0x0034	#DIGIT FOUR
+0x35	0x0035	#DIGIT FIVE
+0x36	0x0036	#DIGIT SIX
+0x37	0x0037	#DIGIT SEVEN
+0x38	0x0038	#DIGIT EIGHT
+0x39	0x0039	#DIGIT NINE
+0x3a	0x003a	#COLON
+0x3b	0x003b	#SEMICOLON
+0x3c	0x003c	#LESS-THAN SIGN
+0x3d	0x003d	#EQUALS SIGN
+0x3e	0x003e	#GREATER-THAN SIGN
+0x3f	0x003f	#QUESTION MARK
+0x40	0x0040	#COMMERCIAL AT
+0x41	0x0041	#LATIN CAPITAL LETTER A
+0x42	0x0042	#LATIN CAPITAL LETTER B
+0x43	0x0043	#LATIN CAPITAL LETTER C
+0x44	0x0044	#LATIN CAPITAL LETTER D
+0x45	0x0045	#LATIN CAPITAL LETTER E
+0x46	0x0046	#LATIN CAPITAL LETTER F
+0x47	0x0047	#LATIN CAPITAL LETTER G
+0x48	0x0048	#LATIN CAPITAL LETTER H
+0x49	0x0049	#LATIN CAPITAL LETTER I
+0x4a	0x004a	#LATIN CAPITAL LETTER J
+0x4b	0x004b	#LATIN CAPITAL LETTER K
+0x4c	0x004c	#LATIN CAPITAL LETTER L
+0x4d	0x004d	#LATIN CAPITAL LETTER M
+0x4e	0x004e	#LATIN CAPITAL LETTER N
+0x4f	0x004f	#LATIN CAPITAL LETTER O
+0x50	0x0050	#LATIN CAPITAL LETTER P
+0x51	0x0051	#LATIN CAPITAL LETTER Q
+0x52	0x0052	#LATIN CAPITAL LETTER R
+0x53	0x0053	#LATIN CAPITAL LETTER S
+0x54	0x0054	#LATIN CAPITAL LETTER T
+0x55	0x0055	#LATIN CAPITAL LETTER U
+0x56	0x0056	#LATIN CAPITAL LETTER V
+0x57	0x0057	#LATIN CAPITAL LETTER W
+0x58	0x0058	#LATIN CAPITAL LETTER X
+0x59	0x0059	#LATIN CAPITAL LETTER Y
+0x5a	0x005a	#LATIN CAPITAL LETTER Z
+0x5b	0x005b	#LEFT SQUARE BRACKET
+0x5c	0x005c	#REVERSE SOLIDUS
+0x5d	0x005d	#RIGHT SQUARE BRACKET
+0x5e	0x005e	#CIRCUMFLEX ACCENT
+0x5f	0x005f	#LOW LINE
+0x60	0x0060	#GRAVE ACCENT
+0x61	0x0061	#LATIN SMALL LETTER A
+0x62	0x0062	#LATIN SMALL LETTER B
+0x63	0x0063	#LATIN SMALL LETTER C
+0x64	0x0064	#LATIN SMALL LETTER D
+0x65	0x0065	#LATIN SMALL LETTER E
+0x66	0x0066	#LATIN SMALL LETTER F
+0x67	0x0067	#LATIN SMALL LETTER G
+0x68	0x0068	#LATIN SMALL LETTER H
+0x69	0x0069	#LATIN SMALL LETTER I
+0x6a	0x006a	#LATIN SMALL LETTER J
+0x6b	0x006b	#LATIN SMALL LETTER K
+0x6c	0x006c	#LATIN SMALL LETTER L
+0x6d	0x006d	#LATIN SMALL LETTER M
+0x6e	0x006e	#LATIN SMALL LETTER N
+0x6f	0x006f	#LATIN SMALL LETTER O
+0x70	0x0070	#LATIN SMALL LETTER P
+0x71	0x0071	#LATIN SMALL LETTER Q
+0x72	0x0072	#LATIN SMALL LETTER R
+0x73	0x0073	#LATIN SMALL LETTER S
+0x74	0x0074	#LATIN SMALL LETTER T
+0x75	0x0075	#LATIN SMALL LETTER U
+0x76	0x0076	#LATIN SMALL LETTER V
+0x77	0x0077	#LATIN SMALL LETTER W
+0x78	0x0078	#LATIN SMALL LETTER X
+0x79	0x0079	#LATIN SMALL LETTER Y
+0x7a	0x007a	#LATIN SMALL LETTER Z
+0x7b	0x007b	#LEFT CURLY BRACKET
+0x7c	0x007c	#VERTICAL LINE
+0x7d	0x007d	#RIGHT CURLY BRACKET
+0x7e	0x007e	#TILDE
+0x7f	0x007f	#DELETE
+0x80	0x00c7	#LATIN CAPITAL LETTER C WITH CEDILLA
+0x81	0x00fc	#LATIN SMALL LETTER U WITH DIAERESIS
+0x82	0x00e9	#LATIN SMALL LETTER E WITH ACUTE
+0x83	0x00e2	#LATIN SMALL LETTER A WITH CIRCUMFLEX
+0x84	0x00e4	#LATIN SMALL LETTER A WITH DIAERESIS
+0x85	0x00e0	#LATIN SMALL LETTER A WITH GRAVE
+0x86	0x00e5	#LATIN SMALL LETTER A WITH RING ABOVE
+0x87	0x00e7	#LATIN SMALL LETTER C WITH CEDILLA
+0x88	0x00ea	#LATIN SMALL LETTER E WITH CIRCUMFLEX
+0x89	0x00eb	#LATIN SMALL LETTER E WITH DIAERESIS
+0x8a	0x00e8	#LATIN SMALL LETTER E WITH GRAVE
+0x8b	0x00d0	#LATIN CAPITAL LETTER ETH
+0x8c	0x00f0	#LATIN SMALL LETTER ETH
+0x8d	0x00de	#LATIN CAPITAL LETTER THORN
+0x8e	0x00c4	#LATIN CAPITAL LETTER A WITH DIAERESIS
+0x8f	0x00c5	#LATIN CAPITAL LETTER A WITH RING ABOVE
+0x90	0x00c9	#LATIN CAPITAL LETTER E WITH ACUTE
+0x91	0x00e6	#LATIN SMALL LIGATURE AE
+0x92	0x00c6	#LATIN CAPITAL LIGATURE AE
+0x93	0x00f4	#LATIN SMALL LETTER O WITH CIRCUMFLEX
+0x94	0x00f6	#LATIN SMALL LETTER O WITH DIAERESIS
+0x95	0x00fe	#LATIN SMALL LETTER THORN
+0x96	0x00fb	#LATIN SMALL LETTER U WITH CIRCUMFLEX
+0x97	0x00dd	#LATIN CAPITAL LETTER Y WITH ACUTE
+0x98	0x00fd	#LATIN SMALL LETTER Y WITH ACUTE
+0x99	0x00d6	#LATIN CAPITAL LETTER O WITH DIAERESIS
+0x9a	0x00dc	#LATIN CAPITAL LETTER U WITH DIAERESIS
+0x9b	0x00f8	#LATIN SMALL LETTER O WITH STROKE
+0x9c	0x00a3	#POUND SIGN
+0x9d	0x00d8	#LATIN CAPITAL LETTER O WITH STROKE
+0x9e	0x20a7	#PESETA SIGN
+0x9f	0x0192	#LATIN SMALL LETTER F WITH HOOK
+0xa0	0x00e1	#LATIN SMALL LETTER A WITH ACUTE
+0xa1	0x00ed	#LATIN SMALL LETTER I WITH ACUTE
+0xa2	0x00f3	#LATIN SMALL LETTER O WITH ACUTE
+0xa3	0x00fa	#LATIN SMALL LETTER U WITH ACUTE
+0xa4	0x00c1	#LATIN CAPITAL LETTER A WITH ACUTE
+0xa5	0x00cd	#LATIN CAPITAL LETTER I WITH ACUTE
+0xa6	0x00d3	#LATIN CAPITAL LETTER O WITH ACUTE
+0xa7	0x00da	#LATIN CAPITAL LETTER U WITH ACUTE
+0xa8	0x00bf	#INVERTED QUESTION MARK
+0xa9	0x2310	#REVERSED NOT SIGN
+0xaa	0x00ac	#NOT SIGN
+0xab	0x00bd	#VULGAR FRACTION ONE HALF
+0xac	0x00bc	#VULGAR FRACTION ONE QUARTER
+0xad	0x00a1	#INVERTED EXCLAMATION MARK
+0xae	0x00ab	#LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+0xaf	0x00bb	#RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+0xb0	0x2591	#LIGHT SHADE
+0xb1	0x2592	#MEDIUM SHADE
+0xb2	0x2593	#DARK SHADE
+0xb3	0x2502	#BOX DRAWINGS LIGHT VERTICAL
+0xb4	0x2524	#BOX DRAWINGS LIGHT VERTICAL AND LEFT
+0xb5	0x2561	#BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE
+0xb6	0x2562	#BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE
+0xb7	0x2556	#BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE
+0xb8	0x2555	#BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE
+0xb9	0x2563	#BOX DRAWINGS DOUBLE VERTICAL AND LEFT
+0xba	0x2551	#BOX DRAWINGS DOUBLE VERTICAL
+0xbb	0x2557	#BOX DRAWINGS DOUBLE DOWN AND LEFT
+0xbc	0x255d	#BOX DRAWINGS DOUBLE UP AND LEFT
+0xbd	0x255c	#BOX DRAWINGS UP DOUBLE AND LEFT SINGLE
+0xbe	0x255b	#BOX DRAWINGS UP SINGLE AND LEFT DOUBLE
+0xbf	0x2510	#BOX DRAWINGS LIGHT DOWN AND LEFT
+0xc0	0x2514	#BOX DRAWINGS LIGHT UP AND RIGHT
+0xc1	0x2534	#BOX DRAWINGS LIGHT UP AND HORIZONTAL
+0xc2	0x252c	#BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
+0xc3	0x251c	#BOX DRAWINGS LIGHT VERTICAL AND RIGHT
+0xc4	0x2500	#BOX DRAWINGS LIGHT HORIZONTAL
+0xc5	0x253c	#BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
+0xc6	0x255e	#BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE
+0xc7	0x255f	#BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE
+0xc8	0x255a	#BOX DRAWINGS DOUBLE UP AND RIGHT
+0xc9	0x2554	#BOX DRAWINGS DOUBLE DOWN AND RIGHT
+0xca	0x2569	#BOX DRAWINGS DOUBLE UP AND HORIZONTAL
+0xcb	0x2566	#BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL
+0xcc	0x2560	#BOX DRAWINGS DOUBLE VERTICAL AND RIGHT
+0xcd	0x2550	#BOX DRAWINGS DOUBLE HORIZONTAL
+0xce	0x256c	#BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL
+0xcf	0x2567	#BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE
+0xd0	0x2568	#BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE
+0xd1	0x2564	#BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE
+0xd2	0x2565	#BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE
+0xd3	0x2559	#BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE
+0xd4	0x2558	#BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE
+0xd5	0x2552	#BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE
+0xd6	0x2553	#BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE
+0xd7	0x256b	#BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE
+0xd8	0x256a	#BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE
+0xd9	0x2518	#BOX DRAWINGS LIGHT UP AND LEFT
+0xda	0x250c	#BOX DRAWINGS LIGHT DOWN AND RIGHT
+0xdb	0x2588	#FULL BLOCK
+0xdc	0x2584	#LOWER HALF BLOCK
+0xdd	0x258c	#LEFT HALF BLOCK
+0xde	0x2590	#RIGHT HALF BLOCK
+0xdf	0x2580	#UPPER HALF BLOCK
+0xe0	0x03b1	#GREEK SMALL LETTER ALPHA
+0xe1	0x00df	#LATIN SMALL LETTER SHARP S
+0xe2	0x0393	#GREEK CAPITAL LETTER GAMMA
+0xe3	0x03c0	#GREEK SMALL LETTER PI
+0xe4	0x03a3	#GREEK CAPITAL LETTER SIGMA
+0xe5	0x03c3	#GREEK SMALL LETTER SIGMA
+0xe6	0x00b5	#MICRO SIGN
+0xe7	0x03c4	#GREEK SMALL LETTER TAU
+0xe8	0x03a6	#GREEK CAPITAL LETTER PHI
+0xe9	0x0398	#GREEK CAPITAL LETTER THETA
+0xea	0x03a9	#GREEK CAPITAL LETTER OMEGA
+0xeb	0x03b4	#GREEK SMALL LETTER DELTA
+0xec	0x221e	#INFINITY
+0xed	0x03c6	#GREEK SMALL LETTER PHI
+0xee	0x03b5	#GREEK SMALL LETTER EPSILON
+0xef	0x2229	#INTERSECTION
+0xf0	0x2261	#IDENTICAL TO
+0xf1	0x00b1	#PLUS-MINUS SIGN
+0xf2	0x2265	#GREATER-THAN OR EQUAL TO
+0xf3	0x2264	#LESS-THAN OR EQUAL TO
+0xf4	0x2320	#TOP HALF INTEGRAL
+0xf5	0x2321	#BOTTOM HALF INTEGRAL
+0xf6	0x00f7	#DIVISION SIGN
+0xf7	0x2248	#ALMOST EQUAL TO
+0xf8	0x00b0	#DEGREE SIGN
+0xf9	0x2219	#BULLET OPERATOR
+0xfa	0x00b7	#MIDDLE DOT
+0xfb	0x221a	#SQUARE ROOT
+0xfc	0x207f	#SUPERSCRIPT LATIN SMALL LETTER N
+0xfd	0x00b2	#SUPERSCRIPT TWO
+0xfe	0x25a0	#BLACK SQUARE
+0xff	0x00a0	#NO-BREAK SPACE
+
diff --git a/tools/encoding/cp862.txt b/tools/encoding/cp862.txt
new file mode 100644
index 0000000..9631105
--- /dev/null
+++ b/tools/encoding/cp862.txt
@@ -0,0 +1,274 @@
+#
+#    Name:     cp862_DOSHebrew to Unicode table
+#    Unicode version: 2.0
+#    Table version: 2.00
+#    Table format:  Format A
+#    Date:          04/24/96
+#    Authors:       Lori Brownell <loribr@microsoft.com>
+#                   K.D. Chang    <a-kchang@microsoft.com>
+#    General notes: none
+#
+#    Format: Three tab-separated columns
+#        Column #1 is the cp862_DOSHebrew code (in hex)
+#        Column #2 is the Unicode (in hex as 0xXXXX)
+#        Column #3 is the Unicode name (follows a comment sign, '#')
+#
+#    The entries are in cp862_DOSHebrew order
+#
+0x00	0x0000	#NULL
+0x01	0x0001	#START OF HEADING
+0x02	0x0002	#START OF TEXT
+0x03	0x0003	#END OF TEXT
+0x04	0x0004	#END OF TRANSMISSION
+0x05	0x0005	#ENQUIRY
+0x06	0x0006	#ACKNOWLEDGE
+0x07	0x0007	#BELL
+0x08	0x0008	#BACKSPACE
+0x09	0x0009	#HORIZONTAL TABULATION
+0x0a	0x000a	#LINE FEED
+0x0b	0x000b	#VERTICAL TABULATION
+0x0c	0x000c	#FORM FEED
+0x0d	0x000d	#CARRIAGE RETURN
+0x0e	0x000e	#SHIFT OUT
+0x0f	0x000f	#SHIFT IN
+0x10	0x0010	#DATA LINK ESCAPE
+0x11	0x0011	#DEVICE CONTROL ONE
+0x12	0x0012	#DEVICE CONTROL TWO
+0x13	0x0013	#DEVICE CONTROL THREE
+0x14	0x0014	#DEVICE CONTROL FOUR
+0x15	0x0015	#NEGATIVE ACKNOWLEDGE
+0x16	0x0016	#SYNCHRONOUS IDLE
+0x17	0x0017	#END OF TRANSMISSION BLOCK
+0x18	0x0018	#CANCEL
+0x19	0x0019	#END OF MEDIUM
+0x1a	0x001a	#SUBSTITUTE
+0x1b	0x001b	#ESCAPE
+0x1c	0x001c	#FILE SEPARATOR
+0x1d	0x001d	#GROUP SEPARATOR
+0x1e	0x001e	#RECORD SEPARATOR
+0x1f	0x001f	#UNIT SEPARATOR
+0x20	0x0020	#SPACE
+0x21	0x0021	#EXCLAMATION MARK
+0x22	0x0022	#QUOTATION MARK
+0x23	0x0023	#NUMBER SIGN
+0x24	0x0024	#DOLLAR SIGN
+0x25	0x0025	#PERCENT SIGN
+0x26	0x0026	#AMPERSAND
+0x27	0x0027	#APOSTROPHE
+0x28	0x0028	#LEFT PARENTHESIS
+0x29	0x0029	#RIGHT PARENTHESIS
+0x2a	0x002a	#ASTERISK
+0x2b	0x002b	#PLUS SIGN
+0x2c	0x002c	#COMMA
+0x2d	0x002d	#HYPHEN-MINUS
+0x2e	0x002e	#FULL STOP
+0x2f	0x002f	#SOLIDUS
+0x30	0x0030	#DIGIT ZERO
+0x31	0x0031	#DIGIT ONE
+0x32	0x0032	#DIGIT TWO
+0x33	0x0033	#DIGIT THREE
+0x34	0x0034	#DIGIT FOUR
+0x35	0x0035	#DIGIT FIVE
+0x36	0x0036	#DIGIT SIX
+0x37	0x0037	#DIGIT SEVEN
+0x38	0x0038	#DIGIT EIGHT
+0x39	0x0039	#DIGIT NINE
+0x3a	0x003a	#COLON
+0x3b	0x003b	#SEMICOLON
+0x3c	0x003c	#LESS-THAN SIGN
+0x3d	0x003d	#EQUALS SIGN
+0x3e	0x003e	#GREATER-THAN SIGN
+0x3f	0x003f	#QUESTION MARK
+0x40	0x0040	#COMMERCIAL AT
+0x41	0x0041	#LATIN CAPITAL LETTER A
+0x42	0x0042	#LATIN CAPITAL LETTER B
+0x43	0x0043	#LATIN CAPITAL LETTER C
+0x44	0x0044	#LATIN CAPITAL LETTER D
+0x45	0x0045	#LATIN CAPITAL LETTER E
+0x46	0x0046	#LATIN CAPITAL LETTER F
+0x47	0x0047	#LATIN CAPITAL LETTER G
+0x48	0x0048	#LATIN CAPITAL LETTER H
+0x49	0x0049	#LATIN CAPITAL LETTER I
+0x4a	0x004a	#LATIN CAPITAL LETTER J
+0x4b	0x004b	#LATIN CAPITAL LETTER K
+0x4c	0x004c	#LATIN CAPITAL LETTER L
+0x4d	0x004d	#LATIN CAPITAL LETTER M
+0x4e	0x004e	#LATIN CAPITAL LETTER N
+0x4f	0x004f	#LATIN CAPITAL LETTER O
+0x50	0x0050	#LATIN CAPITAL LETTER P
+0x51	0x0051	#LATIN CAPITAL LETTER Q
+0x52	0x0052	#LATIN CAPITAL LETTER R
+0x53	0x0053	#LATIN CAPITAL LETTER S
+0x54	0x0054	#LATIN CAPITAL LETTER T
+0x55	0x0055	#LATIN CAPITAL LETTER U
+0x56	0x0056	#LATIN CAPITAL LETTER V
+0x57	0x0057	#LATIN CAPITAL LETTER W
+0x58	0x0058	#LATIN CAPITAL LETTER X
+0x59	0x0059	#LATIN CAPITAL LETTER Y
+0x5a	0x005a	#LATIN CAPITAL LETTER Z
+0x5b	0x005b	#LEFT SQUARE BRACKET
+0x5c	0x005c	#REVERSE SOLIDUS
+0x5d	0x005d	#RIGHT SQUARE BRACKET
+0x5e	0x005e	#CIRCUMFLEX ACCENT
+0x5f	0x005f	#LOW LINE
+0x60	0x0060	#GRAVE ACCENT
+0x61	0x0061	#LATIN SMALL LETTER A
+0x62	0x0062	#LATIN SMALL LETTER B
+0x63	0x0063	#LATIN SMALL LETTER C
+0x64	0x0064	#LATIN SMALL LETTER D
+0x65	0x0065	#LATIN SMALL LETTER E
+0x66	0x0066	#LATIN SMALL LETTER F
+0x67	0x0067	#LATIN SMALL LETTER G
+0x68	0x0068	#LATIN SMALL LETTER H
+0x69	0x0069	#LATIN SMALL LETTER I
+0x6a	0x006a	#LATIN SMALL LETTER J
+0x6b	0x006b	#LATIN SMALL LETTER K
+0x6c	0x006c	#LATIN SMALL LETTER L
+0x6d	0x006d	#LATIN SMALL LETTER M
+0x6e	0x006e	#LATIN SMALL LETTER N
+0x6f	0x006f	#LATIN SMALL LETTER O
+0x70	0x0070	#LATIN SMALL LETTER P
+0x71	0x0071	#LATIN SMALL LETTER Q
+0x72	0x0072	#LATIN SMALL LETTER R
+0x73	0x0073	#LATIN SMALL LETTER S
+0x74	0x0074	#LATIN SMALL LETTER T
+0x75	0x0075	#LATIN SMALL LETTER U
+0x76	0x0076	#LATIN SMALL LETTER V
+0x77	0x0077	#LATIN SMALL LETTER W
+0x78	0x0078	#LATIN SMALL LETTER X
+0x79	0x0079	#LATIN SMALL LETTER Y
+0x7a	0x007a	#LATIN SMALL LETTER Z
+0x7b	0x007b	#LEFT CURLY BRACKET
+0x7c	0x007c	#VERTICAL LINE
+0x7d	0x007d	#RIGHT CURLY BRACKET
+0x7e	0x007e	#TILDE
+0x7f	0x007f	#DELETE
+0x80	0x05d0	#HEBREW LETTER ALEF
+0x81	0x05d1	#HEBREW LETTER BET
+0x82	0x05d2	#HEBREW LETTER GIMEL
+0x83	0x05d3	#HEBREW LETTER DALET
+0x84	0x05d4	#HEBREW LETTER HE
+0x85	0x05d5	#HEBREW LETTER VAV
+0x86	0x05d6	#HEBREW LETTER ZAYIN
+0x87	0x05d7	#HEBREW LETTER HET
+0x88	0x05d8	#HEBREW LETTER TET
+0x89	0x05d9	#HEBREW LETTER YOD
+0x8a	0x05da	#HEBREW LETTER FINAL KAF
+0x8b	0x05db	#HEBREW LETTER KAF
+0x8c	0x05dc	#HEBREW LETTER LAMED
+0x8d	0x05dd	#HEBREW LETTER FINAL MEM
+0x8e	0x05de	#HEBREW LETTER MEM
+0x8f	0x05df	#HEBREW LETTER FINAL NUN
+0x90	0x05e0	#HEBREW LETTER NUN
+0x91	0x05e1	#HEBREW LETTER SAMEKH
+0x92	0x05e2	#HEBREW LETTER AYIN
+0x93	0x05e3	#HEBREW LETTER FINAL PE
+0x94	0x05e4	#HEBREW LETTER PE
+0x95	0x05e5	#HEBREW LETTER FINAL TSADI
+0x96	0x05e6	#HEBREW LETTER TSADI
+0x97	0x05e7	#HEBREW LETTER QOF
+0x98	0x05e8	#HEBREW LETTER RESH
+0x99	0x05e9	#HEBREW LETTER SHIN
+0x9a	0x05ea	#HEBREW LETTER TAV
+0x9b	0x00a2	#CENT SIGN
+0x9c	0x00a3	#POUND SIGN
+0x9d	0x00a5	#YEN SIGN
+0x9e	0x20a7	#PESETA SIGN
+0x9f	0x0192	#LATIN SMALL LETTER F WITH HOOK
+0xa0	0x00e1	#LATIN SMALL LETTER A WITH ACUTE
+0xa1	0x00ed	#LATIN SMALL LETTER I WITH ACUTE
+0xa2	0x00f3	#LATIN SMALL LETTER O WITH ACUTE
+0xa3	0x00fa	#LATIN SMALL LETTER U WITH ACUTE
+0xa4	0x00f1	#LATIN SMALL LETTER N WITH TILDE
+0xa5	0x00d1	#LATIN CAPITAL LETTER N WITH TILDE
+0xa6	0x00aa	#FEMININE ORDINAL INDICATOR
+0xa7	0x00ba	#MASCULINE ORDINAL INDICATOR
+0xa8	0x00bf	#INVERTED QUESTION MARK
+0xa9	0x2310	#REVERSED NOT SIGN
+0xaa	0x00ac	#NOT SIGN
+0xab	0x00bd	#VULGAR FRACTION ONE HALF
+0xac	0x00bc	#VULGAR FRACTION ONE QUARTER
+0xad	0x00a1	#INVERTED EXCLAMATION MARK
+0xae	0x00ab	#LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+0xaf	0x00bb	#RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+0xb0	0x2591	#LIGHT SHADE
+0xb1	0x2592	#MEDIUM SHADE
+0xb2	0x2593	#DARK SHADE
+0xb3	0x2502	#BOX DRAWINGS LIGHT VERTICAL
+0xb4	0x2524	#BOX DRAWINGS LIGHT VERTICAL AND LEFT
+0xb5	0x2561	#BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE
+0xb6	0x2562	#BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE
+0xb7	0x2556	#BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE
+0xb8	0x2555	#BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE
+0xb9	0x2563	#BOX DRAWINGS DOUBLE VERTICAL AND LEFT
+0xba	0x2551	#BOX DRAWINGS DOUBLE VERTICAL
+0xbb	0x2557	#BOX DRAWINGS DOUBLE DOWN AND LEFT
+0xbc	0x255d	#BOX DRAWINGS DOUBLE UP AND LEFT
+0xbd	0x255c	#BOX DRAWINGS UP DOUBLE AND LEFT SINGLE
+0xbe	0x255b	#BOX DRAWINGS UP SINGLE AND LEFT DOUBLE
+0xbf	0x2510	#BOX DRAWINGS LIGHT DOWN AND LEFT
+0xc0	0x2514	#BOX DRAWINGS LIGHT UP AND RIGHT
+0xc1	0x2534	#BOX DRAWINGS LIGHT UP AND HORIZONTAL
+0xc2	0x252c	#BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
+0xc3	0x251c	#BOX DRAWINGS LIGHT VERTICAL AND RIGHT
+0xc4	0x2500	#BOX DRAWINGS LIGHT HORIZONTAL
+0xc5	0x253c	#BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
+0xc6	0x255e	#BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE
+0xc7	0x255f	#BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE
+0xc8	0x255a	#BOX DRAWINGS DOUBLE UP AND RIGHT
+0xc9	0x2554	#BOX DRAWINGS DOUBLE DOWN AND RIGHT
+0xca	0x2569	#BOX DRAWINGS DOUBLE UP AND HORIZONTAL
+0xcb	0x2566	#BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL
+0xcc	0x2560	#BOX DRAWINGS DOUBLE VERTICAL AND RIGHT
+0xcd	0x2550	#BOX DRAWINGS DOUBLE HORIZONTAL
+0xce	0x256c	#BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL
+0xcf	0x2567	#BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE
+0xd0	0x2568	#BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE
+0xd1	0x2564	#BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE
+0xd2	0x2565	#BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE
+0xd3	0x2559	#BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE
+0xd4	0x2558	#BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE
+0xd5	0x2552	#BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE
+0xd6	0x2553	#BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE
+0xd7	0x256b	#BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE
+0xd8	0x256a	#BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE
+0xd9	0x2518	#BOX DRAWINGS LIGHT UP AND LEFT
+0xda	0x250c	#BOX DRAWINGS LIGHT DOWN AND RIGHT
+0xdb	0x2588	#FULL BLOCK
+0xdc	0x2584	#LOWER HALF BLOCK
+0xdd	0x258c	#LEFT HALF BLOCK
+0xde	0x2590	#RIGHT HALF BLOCK
+0xdf	0x2580	#UPPER HALF BLOCK
+0xe0	0x03b1	#GREEK SMALL LETTER ALPHA
+0xe1	0x00df	#LATIN SMALL LETTER SHARP S (GERMAN)
+0xe2	0x0393	#GREEK CAPITAL LETTER GAMMA
+0xe3	0x03c0	#GREEK SMALL LETTER PI
+0xe4	0x03a3	#GREEK CAPITAL LETTER SIGMA
+0xe5	0x03c3	#GREEK SMALL LETTER SIGMA
+0xe6	0x00b5	#MICRO SIGN
+0xe7	0x03c4	#GREEK SMALL LETTER TAU
+0xe8	0x03a6	#GREEK CAPITAL LETTER PHI
+0xe9	0x0398	#GREEK CAPITAL LETTER THETA
+0xea	0x03a9	#GREEK CAPITAL LETTER OMEGA
+0xeb	0x03b4	#GREEK SMALL LETTER DELTA
+0xec	0x221e	#INFINITY
+0xed	0x03c6	#GREEK SMALL LETTER PHI
+0xee	0x03b5	#GREEK SMALL LETTER EPSILON
+0xef	0x2229	#INTERSECTION
+0xf0	0x2261	#IDENTICAL TO
+0xf1	0x00b1	#PLUS-MINUS SIGN
+0xf2	0x2265	#GREATER-THAN OR EQUAL TO
+0xf3	0x2264	#LESS-THAN OR EQUAL TO
+0xf4	0x2320	#TOP HALF INTEGRAL
+0xf5	0x2321	#BOTTOM HALF INTEGRAL
+0xf6	0x00f7	#DIVISION SIGN
+0xf7	0x2248	#ALMOST EQUAL TO
+0xf8	0x00b0	#DEGREE SIGN
+0xf9	0x2219	#BULLET OPERATOR
+0xfa	0x00b7	#MIDDLE DOT
+0xfb	0x221a	#SQUARE ROOT
+0xfc	0x207f	#SUPERSCRIPT LATIN SMALL LETTER N
+0xfd	0x00b2	#SUPERSCRIPT TWO
+0xfe	0x25a0	#BLACK SQUARE
+0xff	0x00a0	#NO-BREAK SPACE
+
diff --git a/tools/encoding/cp863.txt b/tools/encoding/cp863.txt
new file mode 100644
index 0000000..cc4eae1
--- /dev/null
+++ b/tools/encoding/cp863.txt
@@ -0,0 +1,274 @@
+#
+#    Name:     cp863_DOSCanadaF to Unicode table
+#    Unicode version: 2.0
+#    Table version: 2.00
+#    Table format:  Format A
+#    Date:          04/24/96
+#    Authors:       Lori Brownell <loribr@microsoft.com>
+#                   K.D. Chang    <a-kchang@microsoft.com>
+#    General notes: none
+#
+#    Format: Three tab-separated columns
+#        Column #1 is the cp863_DOSCanadaF code (in hex)
+#        Column #2 is the Unicode (in hex as 0xXXXX)
+#        Column #3 is the Unicode name (follows a comment sign, '#')
+#
+#    The entries are in cp863_DOSCanadaF order
+#
+0x00	0x0000	#NULL
+0x01	0x0001	#START OF HEADING
+0x02	0x0002	#START OF TEXT
+0x03	0x0003	#END OF TEXT
+0x04	0x0004	#END OF TRANSMISSION
+0x05	0x0005	#ENQUIRY
+0x06	0x0006	#ACKNOWLEDGE
+0x07	0x0007	#BELL
+0x08	0x0008	#BACKSPACE
+0x09	0x0009	#HORIZONTAL TABULATION
+0x0a	0x000a	#LINE FEED
+0x0b	0x000b	#VERTICAL TABULATION
+0x0c	0x000c	#FORM FEED
+0x0d	0x000d	#CARRIAGE RETURN
+0x0e	0x000e	#SHIFT OUT
+0x0f	0x000f	#SHIFT IN
+0x10	0x0010	#DATA LINK ESCAPE
+0x11	0x0011	#DEVICE CONTROL ONE
+0x12	0x0012	#DEVICE CONTROL TWO
+0x13	0x0013	#DEVICE CONTROL THREE
+0x14	0x0014	#DEVICE CONTROL FOUR
+0x15	0x0015	#NEGATIVE ACKNOWLEDGE
+0x16	0x0016	#SYNCHRONOUS IDLE
+0x17	0x0017	#END OF TRANSMISSION BLOCK
+0x18	0x0018	#CANCEL
+0x19	0x0019	#END OF MEDIUM
+0x1a	0x001a	#SUBSTITUTE
+0x1b	0x001b	#ESCAPE
+0x1c	0x001c	#FILE SEPARATOR
+0x1d	0x001d	#GROUP SEPARATOR
+0x1e	0x001e	#RECORD SEPARATOR
+0x1f	0x001f	#UNIT SEPARATOR
+0x20	0x0020	#SPACE
+0x21	0x0021	#EXCLAMATION MARK
+0x22	0x0022	#QUOTATION MARK
+0x23	0x0023	#NUMBER SIGN
+0x24	0x0024	#DOLLAR SIGN
+0x25	0x0025	#PERCENT SIGN
+0x26	0x0026	#AMPERSAND
+0x27	0x0027	#APOSTROPHE
+0x28	0x0028	#LEFT PARENTHESIS
+0x29	0x0029	#RIGHT PARENTHESIS
+0x2a	0x002a	#ASTERISK
+0x2b	0x002b	#PLUS SIGN
+0x2c	0x002c	#COMMA
+0x2d	0x002d	#HYPHEN-MINUS
+0x2e	0x002e	#FULL STOP
+0x2f	0x002f	#SOLIDUS
+0x30	0x0030	#DIGIT ZERO
+0x31	0x0031	#DIGIT ONE
+0x32	0x0032	#DIGIT TWO
+0x33	0x0033	#DIGIT THREE
+0x34	0x0034	#DIGIT FOUR
+0x35	0x0035	#DIGIT FIVE
+0x36	0x0036	#DIGIT SIX
+0x37	0x0037	#DIGIT SEVEN
+0x38	0x0038	#DIGIT EIGHT
+0x39	0x0039	#DIGIT NINE
+0x3a	0x003a	#COLON
+0x3b	0x003b	#SEMICOLON
+0x3c	0x003c	#LESS-THAN SIGN
+0x3d	0x003d	#EQUALS SIGN
+0x3e	0x003e	#GREATER-THAN SIGN
+0x3f	0x003f	#QUESTION MARK
+0x40	0x0040	#COMMERCIAL AT
+0x41	0x0041	#LATIN CAPITAL LETTER A
+0x42	0x0042	#LATIN CAPITAL LETTER B
+0x43	0x0043	#LATIN CAPITAL LETTER C
+0x44	0x0044	#LATIN CAPITAL LETTER D
+0x45	0x0045	#LATIN CAPITAL LETTER E
+0x46	0x0046	#LATIN CAPITAL LETTER F
+0x47	0x0047	#LATIN CAPITAL LETTER G
+0x48	0x0048	#LATIN CAPITAL LETTER H
+0x49	0x0049	#LATIN CAPITAL LETTER I
+0x4a	0x004a	#LATIN CAPITAL LETTER J
+0x4b	0x004b	#LATIN CAPITAL LETTER K
+0x4c	0x004c	#LATIN CAPITAL LETTER L
+0x4d	0x004d	#LATIN CAPITAL LETTER M
+0x4e	0x004e	#LATIN CAPITAL LETTER N
+0x4f	0x004f	#LATIN CAPITAL LETTER O
+0x50	0x0050	#LATIN CAPITAL LETTER P
+0x51	0x0051	#LATIN CAPITAL LETTER Q
+0x52	0x0052	#LATIN CAPITAL LETTER R
+0x53	0x0053	#LATIN CAPITAL LETTER S
+0x54	0x0054	#LATIN CAPITAL LETTER T
+0x55	0x0055	#LATIN CAPITAL LETTER U
+0x56	0x0056	#LATIN CAPITAL LETTER V
+0x57	0x0057	#LATIN CAPITAL LETTER W
+0x58	0x0058	#LATIN CAPITAL LETTER X
+0x59	0x0059	#LATIN CAPITAL LETTER Y
+0x5a	0x005a	#LATIN CAPITAL LETTER Z
+0x5b	0x005b	#LEFT SQUARE BRACKET
+0x5c	0x005c	#REVERSE SOLIDUS
+0x5d	0x005d	#RIGHT SQUARE BRACKET
+0x5e	0x005e	#CIRCUMFLEX ACCENT
+0x5f	0x005f	#LOW LINE
+0x60	0x0060	#GRAVE ACCENT
+0x61	0x0061	#LATIN SMALL LETTER A
+0x62	0x0062	#LATIN SMALL LETTER B
+0x63	0x0063	#LATIN SMALL LETTER C
+0x64	0x0064	#LATIN SMALL LETTER D
+0x65	0x0065	#LATIN SMALL LETTER E
+0x66	0x0066	#LATIN SMALL LETTER F
+0x67	0x0067	#LATIN SMALL LETTER G
+0x68	0x0068	#LATIN SMALL LETTER H
+0x69	0x0069	#LATIN SMALL LETTER I
+0x6a	0x006a	#LATIN SMALL LETTER J
+0x6b	0x006b	#LATIN SMALL LETTER K
+0x6c	0x006c	#LATIN SMALL LETTER L
+0x6d	0x006d	#LATIN SMALL LETTER M
+0x6e	0x006e	#LATIN SMALL LETTER N
+0x6f	0x006f	#LATIN SMALL LETTER O
+0x70	0x0070	#LATIN SMALL LETTER P
+0x71	0x0071	#LATIN SMALL LETTER Q
+0x72	0x0072	#LATIN SMALL LETTER R
+0x73	0x0073	#LATIN SMALL LETTER S
+0x74	0x0074	#LATIN SMALL LETTER T
+0x75	0x0075	#LATIN SMALL LETTER U
+0x76	0x0076	#LATIN SMALL LETTER V
+0x77	0x0077	#LATIN SMALL LETTER W
+0x78	0x0078	#LATIN SMALL LETTER X
+0x79	0x0079	#LATIN SMALL LETTER Y
+0x7a	0x007a	#LATIN SMALL LETTER Z
+0x7b	0x007b	#LEFT CURLY BRACKET
+0x7c	0x007c	#VERTICAL LINE
+0x7d	0x007d	#RIGHT CURLY BRACKET
+0x7e	0x007e	#TILDE
+0x7f	0x007f	#DELETE
+0x80	0x00c7	#LATIN CAPITAL LETTER C WITH CEDILLA
+0x81	0x00fc	#LATIN SMALL LETTER U WITH DIAERESIS
+0x82	0x00e9	#LATIN SMALL LETTER E WITH ACUTE
+0x83	0x00e2	#LATIN SMALL LETTER A WITH CIRCUMFLEX
+0x84	0x00c2	#LATIN CAPITAL LETTER A WITH CIRCUMFLEX
+0x85	0x00e0	#LATIN SMALL LETTER A WITH GRAVE
+0x86	0x00b6	#PILCROW SIGN
+0x87	0x00e7	#LATIN SMALL LETTER C WITH CEDILLA
+0x88	0x00ea	#LATIN SMALL LETTER E WITH CIRCUMFLEX
+0x89	0x00eb	#LATIN SMALL LETTER E WITH DIAERESIS
+0x8a	0x00e8	#LATIN SMALL LETTER E WITH GRAVE
+0x8b	0x00ef	#LATIN SMALL LETTER I WITH DIAERESIS
+0x8c	0x00ee	#LATIN SMALL LETTER I WITH CIRCUMFLEX
+0x8d	0x2017	#DOUBLE LOW LINE
+0x8e	0x00c0	#LATIN CAPITAL LETTER A WITH GRAVE
+0x8f	0x00a7	#SECTION SIGN
+0x90	0x00c9	#LATIN CAPITAL LETTER E WITH ACUTE
+0x91	0x00c8	#LATIN CAPITAL LETTER E WITH GRAVE
+0x92	0x00ca	#LATIN CAPITAL LETTER E WITH CIRCUMFLEX
+0x93	0x00f4	#LATIN SMALL LETTER O WITH CIRCUMFLEX
+0x94	0x00cb	#LATIN CAPITAL LETTER E WITH DIAERESIS
+0x95	0x00cf	#LATIN CAPITAL LETTER I WITH DIAERESIS
+0x96	0x00fb	#LATIN SMALL LETTER U WITH CIRCUMFLEX
+0x97	0x00f9	#LATIN SMALL LETTER U WITH GRAVE
+0x98	0x00a4	#CURRENCY SIGN
+0x99	0x00d4	#LATIN CAPITAL LETTER O WITH CIRCUMFLEX
+0x9a	0x00dc	#LATIN CAPITAL LETTER U WITH DIAERESIS
+0x9b	0x00a2	#CENT SIGN
+0x9c	0x00a3	#POUND SIGN
+0x9d	0x00d9	#LATIN CAPITAL LETTER U WITH GRAVE
+0x9e	0x00db	#LATIN CAPITAL LETTER U WITH CIRCUMFLEX
+0x9f	0x0192	#LATIN SMALL LETTER F WITH HOOK
+0xa0	0x00a6	#BROKEN BAR
+0xa1	0x00b4	#ACUTE ACCENT
+0xa2	0x00f3	#LATIN SMALL LETTER O WITH ACUTE
+0xa3	0x00fa	#LATIN SMALL LETTER U WITH ACUTE
+0xa4	0x00a8	#DIAERESIS
+0xa5	0x00b8	#CEDILLA
+0xa6	0x00b3	#SUPERSCRIPT THREE
+0xa7	0x00af	#MACRON
+0xa8	0x00ce	#LATIN CAPITAL LETTER I WITH CIRCUMFLEX
+0xa9	0x2310	#REVERSED NOT SIGN
+0xaa	0x00ac	#NOT SIGN
+0xab	0x00bd	#VULGAR FRACTION ONE HALF
+0xac	0x00bc	#VULGAR FRACTION ONE QUARTER
+0xad	0x00be	#VULGAR FRACTION THREE QUARTERS
+0xae	0x00ab	#LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+0xaf	0x00bb	#RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+0xb0	0x2591	#LIGHT SHADE
+0xb1	0x2592	#MEDIUM SHADE
+0xb2	0x2593	#DARK SHADE
+0xb3	0x2502	#BOX DRAWINGS LIGHT VERTICAL
+0xb4	0x2524	#BOX DRAWINGS LIGHT VERTICAL AND LEFT
+0xb5	0x2561	#BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE
+0xb6	0x2562	#BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE
+0xb7	0x2556	#BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE
+0xb8	0x2555	#BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE
+0xb9	0x2563	#BOX DRAWINGS DOUBLE VERTICAL AND LEFT
+0xba	0x2551	#BOX DRAWINGS DOUBLE VERTICAL
+0xbb	0x2557	#BOX DRAWINGS DOUBLE DOWN AND LEFT
+0xbc	0x255d	#BOX DRAWINGS DOUBLE UP AND LEFT
+0xbd	0x255c	#BOX DRAWINGS UP DOUBLE AND LEFT SINGLE
+0xbe	0x255b	#BOX DRAWINGS UP SINGLE AND LEFT DOUBLE
+0xbf	0x2510	#BOX DRAWINGS LIGHT DOWN AND LEFT
+0xc0	0x2514	#BOX DRAWINGS LIGHT UP AND RIGHT
+0xc1	0x2534	#BOX DRAWINGS LIGHT UP AND HORIZONTAL
+0xc2	0x252c	#BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
+0xc3	0x251c	#BOX DRAWINGS LIGHT VERTICAL AND RIGHT
+0xc4	0x2500	#BOX DRAWINGS LIGHT HORIZONTAL
+0xc5	0x253c	#BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
+0xc6	0x255e	#BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE
+0xc7	0x255f	#BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE
+0xc8	0x255a	#BOX DRAWINGS DOUBLE UP AND RIGHT
+0xc9	0x2554	#BOX DRAWINGS DOUBLE DOWN AND RIGHT
+0xca	0x2569	#BOX DRAWINGS DOUBLE UP AND HORIZONTAL
+0xcb	0x2566	#BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL
+0xcc	0x2560	#BOX DRAWINGS DOUBLE VERTICAL AND RIGHT
+0xcd	0x2550	#BOX DRAWINGS DOUBLE HORIZONTAL
+0xce	0x256c	#BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL
+0xcf	0x2567	#BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE
+0xd0	0x2568	#BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE
+0xd1	0x2564	#BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE
+0xd2	0x2565	#BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE
+0xd3	0x2559	#BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE
+0xd4	0x2558	#BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE
+0xd5	0x2552	#BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE
+0xd6	0x2553	#BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE
+0xd7	0x256b	#BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE
+0xd8	0x256a	#BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE
+0xd9	0x2518	#BOX DRAWINGS LIGHT UP AND LEFT
+0xda	0x250c	#BOX DRAWINGS LIGHT DOWN AND RIGHT
+0xdb	0x2588	#FULL BLOCK
+0xdc	0x2584	#LOWER HALF BLOCK
+0xdd	0x258c	#LEFT HALF BLOCK
+0xde	0x2590	#RIGHT HALF BLOCK
+0xdf	0x2580	#UPPER HALF BLOCK
+0xe0	0x03b1	#GREEK SMALL LETTER ALPHA
+0xe1	0x00df	#LATIN SMALL LETTER SHARP S
+0xe2	0x0393	#GREEK CAPITAL LETTER GAMMA
+0xe3	0x03c0	#GREEK SMALL LETTER PI
+0xe4	0x03a3	#GREEK CAPITAL LETTER SIGMA
+0xe5	0x03c3	#GREEK SMALL LETTER SIGMA
+0xe6	0x00b5	#MICRO SIGN
+0xe7	0x03c4	#GREEK SMALL LETTER TAU
+0xe8	0x03a6	#GREEK CAPITAL LETTER PHI
+0xe9	0x0398	#GREEK CAPITAL LETTER THETA
+0xea	0x03a9	#GREEK CAPITAL LETTER OMEGA
+0xeb	0x03b4	#GREEK SMALL LETTER DELTA
+0xec	0x221e	#INFINITY
+0xed	0x03c6	#GREEK SMALL LETTER PHI
+0xee	0x03b5	#GREEK SMALL LETTER EPSILON
+0xef	0x2229	#INTERSECTION
+0xf0	0x2261	#IDENTICAL TO
+0xf1	0x00b1	#PLUS-MINUS SIGN
+0xf2	0x2265	#GREATER-THAN OR EQUAL TO
+0xf3	0x2264	#LESS-THAN OR EQUAL TO
+0xf4	0x2320	#TOP HALF INTEGRAL
+0xf5	0x2321	#BOTTOM HALF INTEGRAL
+0xf6	0x00f7	#DIVISION SIGN
+0xf7	0x2248	#ALMOST EQUAL TO
+0xf8	0x00b0	#DEGREE SIGN
+0xf9	0x2219	#BULLET OPERATOR
+0xfa	0x00b7	#MIDDLE DOT
+0xfb	0x221a	#SQUARE ROOT
+0xfc	0x207f	#SUPERSCRIPT LATIN SMALL LETTER N
+0xfd	0x00b2	#SUPERSCRIPT TWO
+0xfe	0x25a0	#BLACK SQUARE
+0xff	0x00a0	#NO-BREAK SPACE
+
diff --git a/tools/encoding/cp864.txt b/tools/encoding/cp864.txt
new file mode 100644
index 0000000..7aa055f
--- /dev/null
+++ b/tools/encoding/cp864.txt
@@ -0,0 +1,274 @@
+#
+#    Name:     cp864_DOSArabic to Unicode table
+#    Unicode version: 2.0
+#    Table version: 2.00
+#    Table format:  Format A
+#    Date:          04/24/96
+#    Authors:       Lori Brownell <loribr@microsoft.com>
+#                   K.D. Chang    <a-kchang@microsoft.com>
+#    General notes: none
+#
+#    Format: Three tab-separated columns
+#        Column #1 is the cp864_DOSArabic code (in hex)
+#        Column #2 is the Unicode (in hex as 0xXXXX)
+#        Column #3 is the Unicode name (follows a comment sign, '#')
+#
+#    The entries are in cp864_DOSArabic order
+#
+0x00	0x0000	#NULL
+0x01	0x0001	#START OF HEADING
+0x02	0x0002	#START OF TEXT
+0x03	0x0003	#END OF TEXT
+0x04	0x0004	#END OF TRANSMISSION
+0x05	0x0005	#ENQUIRY
+0x06	0x0006	#ACKNOWLEDGE
+0x07	0x0007	#BELL
+0x08	0x0008	#BACKSPACE
+0x09	0x0009	#HORIZONTAL TABULATION
+0x0a	0x000a	#LINE FEED
+0x0b	0x000b	#VERTICAL TABULATION
+0x0c	0x000c	#FORM FEED
+0x0d	0x000d	#CARRIAGE RETURN
+0x0e	0x000e	#SHIFT OUT
+0x0f	0x000f	#SHIFT IN
+0x10	0x0010	#DATA LINK ESCAPE
+0x11	0x0011	#DEVICE CONTROL ONE
+0x12	0x0012	#DEVICE CONTROL TWO
+0x13	0x0013	#DEVICE CONTROL THREE
+0x14	0x0014	#DEVICE CONTROL FOUR
+0x15	0x0015	#NEGATIVE ACKNOWLEDGE
+0x16	0x0016	#SYNCHRONOUS IDLE
+0x17	0x0017	#END OF TRANSMISSION BLOCK
+0x18	0x0018	#CANCEL
+0x19	0x0019	#END OF MEDIUM
+0x1a	0x001a	#SUBSTITUTE
+0x1b	0x001b	#ESCAPE
+0x1c	0x001c	#FILE SEPARATOR
+0x1d	0x001d	#GROUP SEPARATOR
+0x1e	0x001e	#RECORD SEPARATOR
+0x1f	0x001f	#UNIT SEPARATOR
+0x20	0x0020	#SPACE
+0x21	0x0021	#EXCLAMATION MARK
+0x22	0x0022	#QUOTATION MARK
+0x23	0x0023	#NUMBER SIGN
+0x24	0x0024	#DOLLAR SIGN
+0x25	0x066a	#ARABIC PERCENT SIGN
+0x26	0x0026	#AMPERSAND
+0x27	0x0027	#APOSTROPHE
+0x28	0x0028	#LEFT PARENTHESIS
+0x29	0x0029	#RIGHT PARENTHESIS
+0x2a	0x002a	#ASTERISK
+0x2b	0x002b	#PLUS SIGN
+0x2c	0x002c	#COMMA
+0x2d	0x002d	#HYPHEN-MINUS
+0x2e	0x002e	#FULL STOP
+0x2f	0x002f	#SOLIDUS
+0x30	0x0030	#DIGIT ZERO
+0x31	0x0031	#DIGIT ONE
+0x32	0x0032	#DIGIT TWO
+0x33	0x0033	#DIGIT THREE
+0x34	0x0034	#DIGIT FOUR
+0x35	0x0035	#DIGIT FIVE
+0x36	0x0036	#DIGIT SIX
+0x37	0x0037	#DIGIT SEVEN
+0x38	0x0038	#DIGIT EIGHT
+0x39	0x0039	#DIGIT NINE
+0x3a	0x003a	#COLON
+0x3b	0x003b	#SEMICOLON
+0x3c	0x003c	#LESS-THAN SIGN
+0x3d	0x003d	#EQUALS SIGN
+0x3e	0x003e	#GREATER-THAN SIGN
+0x3f	0x003f	#QUESTION MARK
+0x40	0x0040	#COMMERCIAL AT
+0x41	0x0041	#LATIN CAPITAL LETTER A
+0x42	0x0042	#LATIN CAPITAL LETTER B
+0x43	0x0043	#LATIN CAPITAL LETTER C
+0x44	0x0044	#LATIN CAPITAL LETTER D
+0x45	0x0045	#LATIN CAPITAL LETTER E
+0x46	0x0046	#LATIN CAPITAL LETTER F
+0x47	0x0047	#LATIN CAPITAL LETTER G
+0x48	0x0048	#LATIN CAPITAL LETTER H
+0x49	0x0049	#LATIN CAPITAL LETTER I
+0x4a	0x004a	#LATIN CAPITAL LETTER J
+0x4b	0x004b	#LATIN CAPITAL LETTER K
+0x4c	0x004c	#LATIN CAPITAL LETTER L
+0x4d	0x004d	#LATIN CAPITAL LETTER M
+0x4e	0x004e	#LATIN CAPITAL LETTER N
+0x4f	0x004f	#LATIN CAPITAL LETTER O
+0x50	0x0050	#LATIN CAPITAL LETTER P
+0x51	0x0051	#LATIN CAPITAL LETTER Q
+0x52	0x0052	#LATIN CAPITAL LETTER R
+0x53	0x0053	#LATIN CAPITAL LETTER S
+0x54	0x0054	#LATIN CAPITAL LETTER T
+0x55	0x0055	#LATIN CAPITAL LETTER U
+0x56	0x0056	#LATIN CAPITAL LETTER V
+0x57	0x0057	#LATIN CAPITAL LETTER W
+0x58	0x0058	#LATIN CAPITAL LETTER X
+0x59	0x0059	#LATIN CAPITAL LETTER Y
+0x5a	0x005a	#LATIN CAPITAL LETTER Z
+0x5b	0x005b	#LEFT SQUARE BRACKET
+0x5c	0x005c	#REVERSE SOLIDUS
+0x5d	0x005d	#RIGHT SQUARE BRACKET
+0x5e	0x005e	#CIRCUMFLEX ACCENT
+0x5f	0x005f	#LOW LINE
+0x60	0x0060	#GRAVE ACCENT
+0x61	0x0061	#LATIN SMALL LETTER A
+0x62	0x0062	#LATIN SMALL LETTER B
+0x63	0x0063	#LATIN SMALL LETTER C
+0x64	0x0064	#LATIN SMALL LETTER D
+0x65	0x0065	#LATIN SMALL LETTER E
+0x66	0x0066	#LATIN SMALL LETTER F
+0x67	0x0067	#LATIN SMALL LETTER G
+0x68	0x0068	#LATIN SMALL LETTER H
+0x69	0x0069	#LATIN SMALL LETTER I
+0x6a	0x006a	#LATIN SMALL LETTER J
+0x6b	0x006b	#LATIN SMALL LETTER K
+0x6c	0x006c	#LATIN SMALL LETTER L
+0x6d	0x006d	#LATIN SMALL LETTER M
+0x6e	0x006e	#LATIN SMALL LETTER N
+0x6f	0x006f	#LATIN SMALL LETTER O
+0x70	0x0070	#LATIN SMALL LETTER P
+0x71	0x0071	#LATIN SMALL LETTER Q
+0x72	0x0072	#LATIN SMALL LETTER R
+0x73	0x0073	#LATIN SMALL LETTER S
+0x74	0x0074	#LATIN SMALL LETTER T
+0x75	0x0075	#LATIN SMALL LETTER U
+0x76	0x0076	#LATIN SMALL LETTER V
+0x77	0x0077	#LATIN SMALL LETTER W
+0x78	0x0078	#LATIN SMALL LETTER X
+0x79	0x0079	#LATIN SMALL LETTER Y
+0x7a	0x007a	#LATIN SMALL LETTER Z
+0x7b	0x007b	#LEFT CURLY BRACKET
+0x7c	0x007c	#VERTICAL LINE
+0x7d	0x007d	#RIGHT CURLY BRACKET
+0x7e	0x007e	#TILDE
+0x7f	0x007f	#DELETE
+0x80	0x00b0	#DEGREE SIGN
+0x81	0x00b7	#MIDDLE DOT
+0x82	0x2219	#BULLET OPERATOR
+0x83	0x221a	#SQUARE ROOT
+0x84	0x2592	#MEDIUM SHADE
+0x85	0x2500	#FORMS LIGHT HORIZONTAL
+0x86	0x2502	#FORMS LIGHT VERTICAL
+0x87	0x253c	#FORMS LIGHT VERTICAL AND HORIZONTAL
+0x88	0x2524	#FORMS LIGHT VERTICAL AND LEFT
+0x89	0x252c	#FORMS LIGHT DOWN AND HORIZONTAL
+0x8a	0x251c	#FORMS LIGHT VERTICAL AND RIGHT
+0x8b	0x2534	#FORMS LIGHT UP AND HORIZONTAL
+0x8c	0x2510	#FORMS LIGHT DOWN AND LEFT
+0x8d	0x250c	#FORMS LIGHT DOWN AND RIGHT
+0x8e	0x2514	#FORMS LIGHT UP AND RIGHT
+0x8f	0x2518	#FORMS LIGHT UP AND LEFT
+0x90	0x03b2	#GREEK SMALL BETA
+0x91	0x221e	#INFINITY
+0x92	0x03c6	#GREEK SMALL PHI
+0x93	0x00b1	#PLUS-OR-MINUS SIGN
+0x94	0x00bd	#FRACTION 1/2
+0x95	0x00bc	#FRACTION 1/4
+0x96	0x2248	#ALMOST EQUAL TO
+0x97	0x00ab	#LEFT POINTING GUILLEMET
+0x98	0x00bb	#RIGHT POINTING GUILLEMET
+0x99	0xfef7	#ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE ISOLATED FORM
+0x9a	0xfef8	#ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE FINAL FORM
+0x9b		#UNDEFINED
+0x9c		#UNDEFINED
+0x9d	0xfefb	#ARABIC LIGATURE LAM WITH ALEF ISOLATED FORM
+0x9e	0xfefc	#ARABIC LIGATURE LAM WITH ALEF FINAL FORM
+0x9f		#UNDEFINED
+0xa0	0x00a0	#NON-BREAKING SPACE
+0xa1	0x00ad	#SOFT HYPHEN
+0xa2	0xfe82	#ARABIC LETTER ALEF WITH MADDA ABOVE FINAL FORM
+0xa3	0x00a3	#POUND SIGN
+0xa4	0x00a4	#CURRENCY SIGN
+0xa5	0xfe84	#ARABIC LETTER ALEF WITH HAMZA ABOVE FINAL FORM
+0xa6		#UNDEFINED
+0xa7		#UNDEFINED
+0xa8	0xfe8e	#ARABIC LETTER ALEF FINAL FORM
+0xa9	0xfe8f	#ARABIC LETTER BEH ISOLATED FORM
+0xaa	0xfe95	#ARABIC LETTER TEH ISOLATED FORM
+0xab	0xfe99	#ARABIC LETTER THEH ISOLATED FORM
+0xac	0x060c	#ARABIC COMMA
+0xad	0xfe9d	#ARABIC LETTER JEEM ISOLATED FORM
+0xae	0xfea1	#ARABIC LETTER HAH ISOLATED FORM
+0xaf	0xfea5	#ARABIC LETTER KHAH ISOLATED FORM
+0xb0	0x0660	#ARABIC-INDIC DIGIT ZERO
+0xb1	0x0661	#ARABIC-INDIC DIGIT ONE
+0xb2	0x0662	#ARABIC-INDIC DIGIT TWO
+0xb3	0x0663	#ARABIC-INDIC DIGIT THREE
+0xb4	0x0664	#ARABIC-INDIC DIGIT FOUR
+0xb5	0x0665	#ARABIC-INDIC DIGIT FIVE
+0xb6	0x0666	#ARABIC-INDIC DIGIT SIX
+0xb7	0x0667	#ARABIC-INDIC DIGIT SEVEN
+0xb8	0x0668	#ARABIC-INDIC DIGIT EIGHT
+0xb9	0x0669	#ARABIC-INDIC DIGIT NINE
+0xba	0xfed1	#ARABIC LETTER FEH ISOLATED FORM
+0xbb	0x061b	#ARABIC SEMICOLON
+0xbc	0xfeb1	#ARABIC LETTER SEEN ISOLATED FORM
+0xbd	0xfeb5	#ARABIC LETTER SHEEN ISOLATED FORM
+0xbe	0xfeb9	#ARABIC LETTER SAD ISOLATED FORM
+0xbf	0x061f	#ARABIC QUESTION MARK
+0xc0	0x00a2	#CENT SIGN
+0xc1	0xfe80	#ARABIC LETTER HAMZA ISOLATED FORM
+0xc2	0xfe81	#ARABIC LETTER ALEF WITH MADDA ABOVE ISOLATED FORM
+0xc3	0xfe83	#ARABIC LETTER ALEF WITH HAMZA ABOVE ISOLATED FORM
+0xc4	0xfe85	#ARABIC LETTER WAW WITH HAMZA ABOVE ISOLATED FORM
+0xc5	0xfeca	#ARABIC LETTER AIN FINAL FORM
+0xc6	0xfe8b	#ARABIC LETTER YEH WITH HAMZA ABOVE INITIAL FORM
+0xc7	0xfe8d	#ARABIC LETTER ALEF ISOLATED FORM
+0xc8	0xfe91	#ARABIC LETTER BEH INITIAL FORM
+0xc9	0xfe93	#ARABIC LETTER TEH MARBUTA ISOLATED FORM
+0xca	0xfe97	#ARABIC LETTER TEH INITIAL FORM
+0xcb	0xfe9b	#ARABIC LETTER THEH INITIAL FORM
+0xcc	0xfe9f	#ARABIC LETTER JEEM INITIAL FORM
+0xcd	0xfea3	#ARABIC LETTER HAH INITIAL FORM
+0xce	0xfea7	#ARABIC LETTER KHAH INITIAL FORM
+0xcf	0xfea9	#ARABIC LETTER DAL ISOLATED FORM
+0xd0	0xfeab	#ARABIC LETTER THAL ISOLATED FORM
+0xd1	0xfead	#ARABIC LETTER REH ISOLATED FORM
+0xd2	0xfeaf	#ARABIC LETTER ZAIN ISOLATED FORM
+0xd3	0xfeb3	#ARABIC LETTER SEEN INITIAL FORM
+0xd4	0xfeb7	#ARABIC LETTER SHEEN INITIAL FORM
+0xd5	0xfebb	#ARABIC LETTER SAD INITIAL FORM
+0xd6	0xfebf	#ARABIC LETTER DAD INITIAL FORM
+0xd7	0xfec1	#ARABIC LETTER TAH ISOLATED FORM
+0xd8	0xfec5	#ARABIC LETTER ZAH ISOLATED FORM
+0xd9	0xfecb	#ARABIC LETTER AIN INITIAL FORM
+0xda	0xfecf	#ARABIC LETTER GHAIN INITIAL FORM
+0xdb	0x00a6	#BROKEN VERTICAL BAR
+0xdc	0x00ac	#NOT SIGN
+0xdd	0x00f7	#DIVISION SIGN
+0xde	0x00d7	#MULTIPLICATION SIGN
+0xdf	0xfec9	#ARABIC LETTER AIN ISOLATED FORM
+0xe0	0x0640	#ARABIC TATWEEL
+0xe1	0xfed3	#ARABIC LETTER FEH INITIAL FORM
+0xe2	0xfed7	#ARABIC LETTER QAF INITIAL FORM
+0xe3	0xfedb	#ARABIC LETTER KAF INITIAL FORM
+0xe4	0xfedf	#ARABIC LETTER LAM INITIAL FORM
+0xe5	0xfee3	#ARABIC LETTER MEEM INITIAL FORM
+0xe6	0xfee7	#ARABIC LETTER NOON INITIAL FORM
+0xe7	0xfeeb	#ARABIC LETTER HEH INITIAL FORM
+0xe8	0xfeed	#ARABIC LETTER WAW ISOLATED FORM
+0xe9	0xfeef	#ARABIC LETTER ALEF MAKSURA ISOLATED FORM
+0xea	0xfef3	#ARABIC LETTER YEH INITIAL FORM
+0xeb	0xfebd	#ARABIC LETTER DAD ISOLATED FORM
+0xec	0xfecc	#ARABIC LETTER AIN MEDIAL FORM
+0xed	0xfece	#ARABIC LETTER GHAIN FINAL FORM
+0xee	0xfecd	#ARABIC LETTER GHAIN ISOLATED FORM
+0xef	0xfee1	#ARABIC LETTER MEEM ISOLATED FORM
+0xf0	0xfe7d	#ARABIC SHADDA MEDIAL FORM
+0xf1	0x0651	#ARABIC SHADDAH
+0xf2	0xfee5	#ARABIC LETTER NOON ISOLATED FORM
+0xf3	0xfee9	#ARABIC LETTER HEH ISOLATED FORM
+0xf4	0xfeec	#ARABIC LETTER HEH MEDIAL FORM
+0xf5	0xfef0	#ARABIC LETTER ALEF MAKSURA FINAL FORM
+0xf6	0xfef2	#ARABIC LETTER YEH FINAL FORM
+0xf7	0xfed0	#ARABIC LETTER GHAIN MEDIAL FORM
+0xf8	0xfed5	#ARABIC LETTER QAF ISOLATED FORM
+0xf9	0xfef5	#ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE ISOLATED FORM
+0xfa	0xfef6	#ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE FINAL FORM
+0xfb	0xfedd	#ARABIC LETTER LAM ISOLATED FORM
+0xfc	0xfed9	#ARABIC LETTER KAF ISOLATED FORM
+0xfd	0xfef1	#ARABIC LETTER YEH ISOLATED FORM
+0xfe	0x25a0	#BLACK SQUARE
+0xff		#UNDEFINED
+
diff --git a/tools/encoding/cp865.txt b/tools/encoding/cp865.txt
new file mode 100644
index 0000000..67705f4
--- /dev/null
+++ b/tools/encoding/cp865.txt
@@ -0,0 +1,274 @@
+#
+#    Name:     cp865_DOSNordic to Unicode table
+#    Unicode version: 2.0
+#    Table version: 2.00
+#    Table format:  Format A
+#    Date:          04/24/96
+#    Authors:       Lori Brownell <loribr@microsoft.com>
+#                   K.D. Chang    <a-kchang@microsoft.com>
+#    General notes: none
+#
+#    Format: Three tab-separated columns
+#        Column #1 is the cp865_DOSNordic code (in hex)
+#        Column #2 is the Unicode (in hex as 0xXXXX)
+#        Column #3 is the Unicode name (follows a comment sign, '#')
+#
+#    The entries are in cp865_DOSNordic order
+#
+0x00	0x0000	#NULL
+0x01	0x0001	#START OF HEADING
+0x02	0x0002	#START OF TEXT
+0x03	0x0003	#END OF TEXT
+0x04	0x0004	#END OF TRANSMISSION
+0x05	0x0005	#ENQUIRY
+0x06	0x0006	#ACKNOWLEDGE
+0x07	0x0007	#BELL
+0x08	0x0008	#BACKSPACE
+0x09	0x0009	#HORIZONTAL TABULATION
+0x0a	0x000a	#LINE FEED
+0x0b	0x000b	#VERTICAL TABULATION
+0x0c	0x000c	#FORM FEED
+0x0d	0x000d	#CARRIAGE RETURN
+0x0e	0x000e	#SHIFT OUT
+0x0f	0x000f	#SHIFT IN
+0x10	0x0010	#DATA LINK ESCAPE
+0x11	0x0011	#DEVICE CONTROL ONE
+0x12	0x0012	#DEVICE CONTROL TWO
+0x13	0x0013	#DEVICE CONTROL THREE
+0x14	0x0014	#DEVICE CONTROL FOUR
+0x15	0x0015	#NEGATIVE ACKNOWLEDGE
+0x16	0x0016	#SYNCHRONOUS IDLE
+0x17	0x0017	#END OF TRANSMISSION BLOCK
+0x18	0x0018	#CANCEL
+0x19	0x0019	#END OF MEDIUM
+0x1a	0x001a	#SUBSTITUTE
+0x1b	0x001b	#ESCAPE
+0x1c	0x001c	#FILE SEPARATOR
+0x1d	0x001d	#GROUP SEPARATOR
+0x1e	0x001e	#RECORD SEPARATOR
+0x1f	0x001f	#UNIT SEPARATOR
+0x20	0x0020	#SPACE
+0x21	0x0021	#EXCLAMATION MARK
+0x22	0x0022	#QUOTATION MARK
+0x23	0x0023	#NUMBER SIGN
+0x24	0x0024	#DOLLAR SIGN
+0x25	0x0025	#PERCENT SIGN
+0x26	0x0026	#AMPERSAND
+0x27	0x0027	#APOSTROPHE
+0x28	0x0028	#LEFT PARENTHESIS
+0x29	0x0029	#RIGHT PARENTHESIS
+0x2a	0x002a	#ASTERISK
+0x2b	0x002b	#PLUS SIGN
+0x2c	0x002c	#COMMA
+0x2d	0x002d	#HYPHEN-MINUS
+0x2e	0x002e	#FULL STOP
+0x2f	0x002f	#SOLIDUS
+0x30	0x0030	#DIGIT ZERO
+0x31	0x0031	#DIGIT ONE
+0x32	0x0032	#DIGIT TWO
+0x33	0x0033	#DIGIT THREE
+0x34	0x0034	#DIGIT FOUR
+0x35	0x0035	#DIGIT FIVE
+0x36	0x0036	#DIGIT SIX
+0x37	0x0037	#DIGIT SEVEN
+0x38	0x0038	#DIGIT EIGHT
+0x39	0x0039	#DIGIT NINE
+0x3a	0x003a	#COLON
+0x3b	0x003b	#SEMICOLON
+0x3c	0x003c	#LESS-THAN SIGN
+0x3d	0x003d	#EQUALS SIGN
+0x3e	0x003e	#GREATER-THAN SIGN
+0x3f	0x003f	#QUESTION MARK
+0x40	0x0040	#COMMERCIAL AT
+0x41	0x0041	#LATIN CAPITAL LETTER A
+0x42	0x0042	#LATIN CAPITAL LETTER B
+0x43	0x0043	#LATIN CAPITAL LETTER C
+0x44	0x0044	#LATIN CAPITAL LETTER D
+0x45	0x0045	#LATIN CAPITAL LETTER E
+0x46	0x0046	#LATIN CAPITAL LETTER F
+0x47	0x0047	#LATIN CAPITAL LETTER G
+0x48	0x0048	#LATIN CAPITAL LETTER H
+0x49	0x0049	#LATIN CAPITAL LETTER I
+0x4a	0x004a	#LATIN CAPITAL LETTER J
+0x4b	0x004b	#LATIN CAPITAL LETTER K
+0x4c	0x004c	#LATIN CAPITAL LETTER L
+0x4d	0x004d	#LATIN CAPITAL LETTER M
+0x4e	0x004e	#LATIN CAPITAL LETTER N
+0x4f	0x004f	#LATIN CAPITAL LETTER O
+0x50	0x0050	#LATIN CAPITAL LETTER P
+0x51	0x0051	#LATIN CAPITAL LETTER Q
+0x52	0x0052	#LATIN CAPITAL LETTER R
+0x53	0x0053	#LATIN CAPITAL LETTER S
+0x54	0x0054	#LATIN CAPITAL LETTER T
+0x55	0x0055	#LATIN CAPITAL LETTER U
+0x56	0x0056	#LATIN CAPITAL LETTER V
+0x57	0x0057	#LATIN CAPITAL LETTER W
+0x58	0x0058	#LATIN CAPITAL LETTER X
+0x59	0x0059	#LATIN CAPITAL LETTER Y
+0x5a	0x005a	#LATIN CAPITAL LETTER Z
+0x5b	0x005b	#LEFT SQUARE BRACKET
+0x5c	0x005c	#REVERSE SOLIDUS
+0x5d	0x005d	#RIGHT SQUARE BRACKET
+0x5e	0x005e	#CIRCUMFLEX ACCENT
+0x5f	0x005f	#LOW LINE
+0x60	0x0060	#GRAVE ACCENT
+0x61	0x0061	#LATIN SMALL LETTER A
+0x62	0x0062	#LATIN SMALL LETTER B
+0x63	0x0063	#LATIN SMALL LETTER C
+0x64	0x0064	#LATIN SMALL LETTER D
+0x65	0x0065	#LATIN SMALL LETTER E
+0x66	0x0066	#LATIN SMALL LETTER F
+0x67	0x0067	#LATIN SMALL LETTER G
+0x68	0x0068	#LATIN SMALL LETTER H
+0x69	0x0069	#LATIN SMALL LETTER I
+0x6a	0x006a	#LATIN SMALL LETTER J
+0x6b	0x006b	#LATIN SMALL LETTER K
+0x6c	0x006c	#LATIN SMALL LETTER L
+0x6d	0x006d	#LATIN SMALL LETTER M
+0x6e	0x006e	#LATIN SMALL LETTER N
+0x6f	0x006f	#LATIN SMALL LETTER O
+0x70	0x0070	#LATIN SMALL LETTER P
+0x71	0x0071	#LATIN SMALL LETTER Q
+0x72	0x0072	#LATIN SMALL LETTER R
+0x73	0x0073	#LATIN SMALL LETTER S
+0x74	0x0074	#LATIN SMALL LETTER T
+0x75	0x0075	#LATIN SMALL LETTER U
+0x76	0x0076	#LATIN SMALL LETTER V
+0x77	0x0077	#LATIN SMALL LETTER W
+0x78	0x0078	#LATIN SMALL LETTER X
+0x79	0x0079	#LATIN SMALL LETTER Y
+0x7a	0x007a	#LATIN SMALL LETTER Z
+0x7b	0x007b	#LEFT CURLY BRACKET
+0x7c	0x007c	#VERTICAL LINE
+0x7d	0x007d	#RIGHT CURLY BRACKET
+0x7e	0x007e	#TILDE
+0x7f	0x007f	#DELETE
+0x80	0x00c7	#LATIN CAPITAL LETTER C WITH CEDILLA
+0x81	0x00fc	#LATIN SMALL LETTER U WITH DIAERESIS
+0x82	0x00e9	#LATIN SMALL LETTER E WITH ACUTE
+0x83	0x00e2	#LATIN SMALL LETTER A WITH CIRCUMFLEX
+0x84	0x00e4	#LATIN SMALL LETTER A WITH DIAERESIS
+0x85	0x00e0	#LATIN SMALL LETTER A WITH GRAVE
+0x86	0x00e5	#LATIN SMALL LETTER A WITH RING ABOVE
+0x87	0x00e7	#LATIN SMALL LETTER C WITH CEDILLA
+0x88	0x00ea	#LATIN SMALL LETTER E WITH CIRCUMFLEX
+0x89	0x00eb	#LATIN SMALL LETTER E WITH DIAERESIS
+0x8a	0x00e8	#LATIN SMALL LETTER E WITH GRAVE
+0x8b	0x00ef	#LATIN SMALL LETTER I WITH DIAERESIS
+0x8c	0x00ee	#LATIN SMALL LETTER I WITH CIRCUMFLEX
+0x8d	0x00ec	#LATIN SMALL LETTER I WITH GRAVE
+0x8e	0x00c4	#LATIN CAPITAL LETTER A WITH DIAERESIS
+0x8f	0x00c5	#LATIN CAPITAL LETTER A WITH RING ABOVE
+0x90	0x00c9	#LATIN CAPITAL LETTER E WITH ACUTE
+0x91	0x00e6	#LATIN SMALL LIGATURE AE
+0x92	0x00c6	#LATIN CAPITAL LIGATURE AE
+0x93	0x00f4	#LATIN SMALL LETTER O WITH CIRCUMFLEX
+0x94	0x00f6	#LATIN SMALL LETTER O WITH DIAERESIS
+0x95	0x00f2	#LATIN SMALL LETTER O WITH GRAVE
+0x96	0x00fb	#LATIN SMALL LETTER U WITH CIRCUMFLEX
+0x97	0x00f9	#LATIN SMALL LETTER U WITH GRAVE
+0x98	0x00ff	#LATIN SMALL LETTER Y WITH DIAERESIS
+0x99	0x00d6	#LATIN CAPITAL LETTER O WITH DIAERESIS
+0x9a	0x00dc	#LATIN CAPITAL LETTER U WITH DIAERESIS
+0x9b	0x00f8	#LATIN SMALL LETTER O WITH STROKE
+0x9c	0x00a3	#POUND SIGN
+0x9d	0x00d8	#LATIN CAPITAL LETTER O WITH STROKE
+0x9e	0x20a7	#PESETA SIGN
+0x9f	0x0192	#LATIN SMALL LETTER F WITH HOOK
+0xa0	0x00e1	#LATIN SMALL LETTER A WITH ACUTE
+0xa1	0x00ed	#LATIN SMALL LETTER I WITH ACUTE
+0xa2	0x00f3	#LATIN SMALL LETTER O WITH ACUTE
+0xa3	0x00fa	#LATIN SMALL LETTER U WITH ACUTE
+0xa4	0x00f1	#LATIN SMALL LETTER N WITH TILDE
+0xa5	0x00d1	#LATIN CAPITAL LETTER N WITH TILDE
+0xa6	0x00aa	#FEMININE ORDINAL INDICATOR
+0xa7	0x00ba	#MASCULINE ORDINAL INDICATOR
+0xa8	0x00bf	#INVERTED QUESTION MARK
+0xa9	0x2310	#REVERSED NOT SIGN
+0xaa	0x00ac	#NOT SIGN
+0xab	0x00bd	#VULGAR FRACTION ONE HALF
+0xac	0x00bc	#VULGAR FRACTION ONE QUARTER
+0xad	0x00a1	#INVERTED EXCLAMATION MARK
+0xae	0x00ab	#LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+0xaf	0x00a4	#CURRENCY SIGN
+0xb0	0x2591	#LIGHT SHADE
+0xb1	0x2592	#MEDIUM SHADE
+0xb2	0x2593	#DARK SHADE
+0xb3	0x2502	#BOX DRAWINGS LIGHT VERTICAL
+0xb4	0x2524	#BOX DRAWINGS LIGHT VERTICAL AND LEFT
+0xb5	0x2561	#BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE
+0xb6	0x2562	#BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE
+0xb7	0x2556	#BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE
+0xb8	0x2555	#BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE
+0xb9	0x2563	#BOX DRAWINGS DOUBLE VERTICAL AND LEFT
+0xba	0x2551	#BOX DRAWINGS DOUBLE VERTICAL
+0xbb	0x2557	#BOX DRAWINGS DOUBLE DOWN AND LEFT
+0xbc	0x255d	#BOX DRAWINGS DOUBLE UP AND LEFT
+0xbd	0x255c	#BOX DRAWINGS UP DOUBLE AND LEFT SINGLE
+0xbe	0x255b	#BOX DRAWINGS UP SINGLE AND LEFT DOUBLE
+0xbf	0x2510	#BOX DRAWINGS LIGHT DOWN AND LEFT
+0xc0	0x2514	#BOX DRAWINGS LIGHT UP AND RIGHT
+0xc1	0x2534	#BOX DRAWINGS LIGHT UP AND HORIZONTAL
+0xc2	0x252c	#BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
+0xc3	0x251c	#BOX DRAWINGS LIGHT VERTICAL AND RIGHT
+0xc4	0x2500	#BOX DRAWINGS LIGHT HORIZONTAL
+0xc5	0x253c	#BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
+0xc6	0x255e	#BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE
+0xc7	0x255f	#BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE
+0xc8	0x255a	#BOX DRAWINGS DOUBLE UP AND RIGHT
+0xc9	0x2554	#BOX DRAWINGS DOUBLE DOWN AND RIGHT
+0xca	0x2569	#BOX DRAWINGS DOUBLE UP AND HORIZONTAL
+0xcb	0x2566	#BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL
+0xcc	0x2560	#BOX DRAWINGS DOUBLE VERTICAL AND RIGHT
+0xcd	0x2550	#BOX DRAWINGS DOUBLE HORIZONTAL
+0xce	0x256c	#BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL
+0xcf	0x2567	#BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE
+0xd0	0x2568	#BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE
+0xd1	0x2564	#BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE
+0xd2	0x2565	#BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE
+0xd3	0x2559	#BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE
+0xd4	0x2558	#BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE
+0xd5	0x2552	#BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE
+0xd6	0x2553	#BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE
+0xd7	0x256b	#BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE
+0xd8	0x256a	#BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE
+0xd9	0x2518	#BOX DRAWINGS LIGHT UP AND LEFT
+0xda	0x250c	#BOX DRAWINGS LIGHT DOWN AND RIGHT
+0xdb	0x2588	#FULL BLOCK
+0xdc	0x2584	#LOWER HALF BLOCK
+0xdd	0x258c	#LEFT HALF BLOCK
+0xde	0x2590	#RIGHT HALF BLOCK
+0xdf	0x2580	#UPPER HALF BLOCK
+0xe0	0x03b1	#GREEK SMALL LETTER ALPHA
+0xe1	0x00df	#LATIN SMALL LETTER SHARP S
+0xe2	0x0393	#GREEK CAPITAL LETTER GAMMA
+0xe3	0x03c0	#GREEK SMALL LETTER PI
+0xe4	0x03a3	#GREEK CAPITAL LETTER SIGMA
+0xe5	0x03c3	#GREEK SMALL LETTER SIGMA
+0xe6	0x00b5	#MICRO SIGN
+0xe7	0x03c4	#GREEK SMALL LETTER TAU
+0xe8	0x03a6	#GREEK CAPITAL LETTER PHI
+0xe9	0x0398	#GREEK CAPITAL LETTER THETA
+0xea	0x03a9	#GREEK CAPITAL LETTER OMEGA
+0xeb	0x03b4	#GREEK SMALL LETTER DELTA
+0xec	0x221e	#INFINITY
+0xed	0x03c6	#GREEK SMALL LETTER PHI
+0xee	0x03b5	#GREEK SMALL LETTER EPSILON
+0xef	0x2229	#INTERSECTION
+0xf0	0x2261	#IDENTICAL TO
+0xf1	0x00b1	#PLUS-MINUS SIGN
+0xf2	0x2265	#GREATER-THAN OR EQUAL TO
+0xf3	0x2264	#LESS-THAN OR EQUAL TO
+0xf4	0x2320	#TOP HALF INTEGRAL
+0xf5	0x2321	#BOTTOM HALF INTEGRAL
+0xf6	0x00f7	#DIVISION SIGN
+0xf7	0x2248	#ALMOST EQUAL TO
+0xf8	0x00b0	#DEGREE SIGN
+0xf9	0x2219	#BULLET OPERATOR
+0xfa	0x00b7	#MIDDLE DOT
+0xfb	0x221a	#SQUARE ROOT
+0xfc	0x207f	#SUPERSCRIPT LATIN SMALL LETTER N
+0xfd	0x00b2	#SUPERSCRIPT TWO
+0xfe	0x25a0	#BLACK SQUARE
+0xff	0x00a0	#NO-BREAK SPACE
+
diff --git a/tools/encoding/cp866.txt b/tools/encoding/cp866.txt
new file mode 100644
index 0000000..880fb70
--- /dev/null
+++ b/tools/encoding/cp866.txt
@@ -0,0 +1,274 @@
+#
+#    Name:     cp866_DOSCyrillicRussian to Unicode table
+#    Unicode version: 2.0
+#    Table version: 2.00
+#    Table format:  Format A
+#    Date:          04/24/96
+#    Authors:       Lori Brownell <loribr@microsoft.com>
+#                   K.D. Chang    <a-kchang@microsoft.com>
+#    General notes: none
+#
+#    Format: Three tab-separated columns
+#        Column #1 is the cp866_DOSCyrillicRussian code (in hex)
+#        Column #2 is the Unicode (in hex as 0xXXXX)
+#        Column #3 is the Unicode name (follows a comment sign, '#')
+#
+#    The entries are in cp866_DOSCyrillicRussian order
+#
+0x00	0x0000	#NULL
+0x01	0x0001	#START OF HEADING
+0x02	0x0002	#START OF TEXT
+0x03	0x0003	#END OF TEXT
+0x04	0x0004	#END OF TRANSMISSION
+0x05	0x0005	#ENQUIRY
+0x06	0x0006	#ACKNOWLEDGE
+0x07	0x0007	#BELL
+0x08	0x0008	#BACKSPACE
+0x09	0x0009	#HORIZONTAL TABULATION
+0x0a	0x000a	#LINE FEED
+0x0b	0x000b	#VERTICAL TABULATION
+0x0c	0x000c	#FORM FEED
+0x0d	0x000d	#CARRIAGE RETURN
+0x0e	0x000e	#SHIFT OUT
+0x0f	0x000f	#SHIFT IN
+0x10	0x0010	#DATA LINK ESCAPE
+0x11	0x0011	#DEVICE CONTROL ONE
+0x12	0x0012	#DEVICE CONTROL TWO
+0x13	0x0013	#DEVICE CONTROL THREE
+0x14	0x0014	#DEVICE CONTROL FOUR
+0x15	0x0015	#NEGATIVE ACKNOWLEDGE
+0x16	0x0016	#SYNCHRONOUS IDLE
+0x17	0x0017	#END OF TRANSMISSION BLOCK
+0x18	0x0018	#CANCEL
+0x19	0x0019	#END OF MEDIUM
+0x1a	0x001a	#SUBSTITUTE
+0x1b	0x001b	#ESCAPE
+0x1c	0x001c	#FILE SEPARATOR
+0x1d	0x001d	#GROUP SEPARATOR
+0x1e	0x001e	#RECORD SEPARATOR
+0x1f	0x001f	#UNIT SEPARATOR
+0x20	0x0020	#SPACE
+0x21	0x0021	#EXCLAMATION MARK
+0x22	0x0022	#QUOTATION MARK
+0x23	0x0023	#NUMBER SIGN
+0x24	0x0024	#DOLLAR SIGN
+0x25	0x0025	#PERCENT SIGN
+0x26	0x0026	#AMPERSAND
+0x27	0x0027	#APOSTROPHE
+0x28	0x0028	#LEFT PARENTHESIS
+0x29	0x0029	#RIGHT PARENTHESIS
+0x2a	0x002a	#ASTERISK
+0x2b	0x002b	#PLUS SIGN
+0x2c	0x002c	#COMMA
+0x2d	0x002d	#HYPHEN-MINUS
+0x2e	0x002e	#FULL STOP
+0x2f	0x002f	#SOLIDUS
+0x30	0x0030	#DIGIT ZERO
+0x31	0x0031	#DIGIT ONE
+0x32	0x0032	#DIGIT TWO
+0x33	0x0033	#DIGIT THREE
+0x34	0x0034	#DIGIT FOUR
+0x35	0x0035	#DIGIT FIVE
+0x36	0x0036	#DIGIT SIX
+0x37	0x0037	#DIGIT SEVEN
+0x38	0x0038	#DIGIT EIGHT
+0x39	0x0039	#DIGIT NINE
+0x3a	0x003a	#COLON
+0x3b	0x003b	#SEMICOLON
+0x3c	0x003c	#LESS-THAN SIGN
+0x3d	0x003d	#EQUALS SIGN
+0x3e	0x003e	#GREATER-THAN SIGN
+0x3f	0x003f	#QUESTION MARK
+0x40	0x0040	#COMMERCIAL AT
+0x41	0x0041	#LATIN CAPITAL LETTER A
+0x42	0x0042	#LATIN CAPITAL LETTER B
+0x43	0x0043	#LATIN CAPITAL LETTER C
+0x44	0x0044	#LATIN CAPITAL LETTER D
+0x45	0x0045	#LATIN CAPITAL LETTER E
+0x46	0x0046	#LATIN CAPITAL LETTER F
+0x47	0x0047	#LATIN CAPITAL LETTER G
+0x48	0x0048	#LATIN CAPITAL LETTER H
+0x49	0x0049	#LATIN CAPITAL LETTER I
+0x4a	0x004a	#LATIN CAPITAL LETTER J
+0x4b	0x004b	#LATIN CAPITAL LETTER K
+0x4c	0x004c	#LATIN CAPITAL LETTER L
+0x4d	0x004d	#LATIN CAPITAL LETTER M
+0x4e	0x004e	#LATIN CAPITAL LETTER N
+0x4f	0x004f	#LATIN CAPITAL LETTER O
+0x50	0x0050	#LATIN CAPITAL LETTER P
+0x51	0x0051	#LATIN CAPITAL LETTER Q
+0x52	0x0052	#LATIN CAPITAL LETTER R
+0x53	0x0053	#LATIN CAPITAL LETTER S
+0x54	0x0054	#LATIN CAPITAL LETTER T
+0x55	0x0055	#LATIN CAPITAL LETTER U
+0x56	0x0056	#LATIN CAPITAL LETTER V
+0x57	0x0057	#LATIN CAPITAL LETTER W
+0x58	0x0058	#LATIN CAPITAL LETTER X
+0x59	0x0059	#LATIN CAPITAL LETTER Y
+0x5a	0x005a	#LATIN CAPITAL LETTER Z
+0x5b	0x005b	#LEFT SQUARE BRACKET
+0x5c	0x005c	#REVERSE SOLIDUS
+0x5d	0x005d	#RIGHT SQUARE BRACKET
+0x5e	0x005e	#CIRCUMFLEX ACCENT
+0x5f	0x005f	#LOW LINE
+0x60	0x0060	#GRAVE ACCENT
+0x61	0x0061	#LATIN SMALL LETTER A
+0x62	0x0062	#LATIN SMALL LETTER B
+0x63	0x0063	#LATIN SMALL LETTER C
+0x64	0x0064	#LATIN SMALL LETTER D
+0x65	0x0065	#LATIN SMALL LETTER E
+0x66	0x0066	#LATIN SMALL LETTER F
+0x67	0x0067	#LATIN SMALL LETTER G
+0x68	0x0068	#LATIN SMALL LETTER H
+0x69	0x0069	#LATIN SMALL LETTER I
+0x6a	0x006a	#LATIN SMALL LETTER J
+0x6b	0x006b	#LATIN SMALL LETTER K
+0x6c	0x006c	#LATIN SMALL LETTER L
+0x6d	0x006d	#LATIN SMALL LETTER M
+0x6e	0x006e	#LATIN SMALL LETTER N
+0x6f	0x006f	#LATIN SMALL LETTER O
+0x70	0x0070	#LATIN SMALL LETTER P
+0x71	0x0071	#LATIN SMALL LETTER Q
+0x72	0x0072	#LATIN SMALL LETTER R
+0x73	0x0073	#LATIN SMALL LETTER S
+0x74	0x0074	#LATIN SMALL LETTER T
+0x75	0x0075	#LATIN SMALL LETTER U
+0x76	0x0076	#LATIN SMALL LETTER V
+0x77	0x0077	#LATIN SMALL LETTER W
+0x78	0x0078	#LATIN SMALL LETTER X
+0x79	0x0079	#LATIN SMALL LETTER Y
+0x7a	0x007a	#LATIN SMALL LETTER Z
+0x7b	0x007b	#LEFT CURLY BRACKET
+0x7c	0x007c	#VERTICAL LINE
+0x7d	0x007d	#RIGHT CURLY BRACKET
+0x7e	0x007e	#TILDE
+0x7f	0x007f	#DELETE
+0x80	0x0410	#CYRILLIC CAPITAL LETTER A
+0x81	0x0411	#CYRILLIC CAPITAL LETTER BE
+0x82	0x0412	#CYRILLIC CAPITAL LETTER VE
+0x83	0x0413	#CYRILLIC CAPITAL LETTER GHE
+0x84	0x0414	#CYRILLIC CAPITAL LETTER DE
+0x85	0x0415	#CYRILLIC CAPITAL LETTER IE
+0x86	0x0416	#CYRILLIC CAPITAL LETTER ZHE
+0x87	0x0417	#CYRILLIC CAPITAL LETTER ZE
+0x88	0x0418	#CYRILLIC CAPITAL LETTER I
+0x89	0x0419	#CYRILLIC CAPITAL LETTER SHORT I
+0x8a	0x041a	#CYRILLIC CAPITAL LETTER KA
+0x8b	0x041b	#CYRILLIC CAPITAL LETTER EL
+0x8c	0x041c	#CYRILLIC CAPITAL LETTER EM
+0x8d	0x041d	#CYRILLIC CAPITAL LETTER EN
+0x8e	0x041e	#CYRILLIC CAPITAL LETTER O
+0x8f	0x041f	#CYRILLIC CAPITAL LETTER PE
+0x90	0x0420	#CYRILLIC CAPITAL LETTER ER
+0x91	0x0421	#CYRILLIC CAPITAL LETTER ES
+0x92	0x0422	#CYRILLIC CAPITAL LETTER TE
+0x93	0x0423	#CYRILLIC CAPITAL LETTER U
+0x94	0x0424	#CYRILLIC CAPITAL LETTER EF
+0x95	0x0425	#CYRILLIC CAPITAL LETTER HA
+0x96	0x0426	#CYRILLIC CAPITAL LETTER TSE
+0x97	0x0427	#CYRILLIC CAPITAL LETTER CHE
+0x98	0x0428	#CYRILLIC CAPITAL LETTER SHA
+0x99	0x0429	#CYRILLIC CAPITAL LETTER SHCHA
+0x9a	0x042a	#CYRILLIC CAPITAL LETTER HARD SIGN
+0x9b	0x042b	#CYRILLIC CAPITAL LETTER YERU
+0x9c	0x042c	#CYRILLIC CAPITAL LETTER SOFT SIGN
+0x9d	0x042d	#CYRILLIC CAPITAL LETTER E
+0x9e	0x042e	#CYRILLIC CAPITAL LETTER YU
+0x9f	0x042f	#CYRILLIC CAPITAL LETTER YA
+0xa0	0x0430	#CYRILLIC SMALL LETTER A
+0xa1	0x0431	#CYRILLIC SMALL LETTER BE
+0xa2	0x0432	#CYRILLIC SMALL LETTER VE
+0xa3	0x0433	#CYRILLIC SMALL LETTER GHE
+0xa4	0x0434	#CYRILLIC SMALL LETTER DE
+0xa5	0x0435	#CYRILLIC SMALL LETTER IE
+0xa6	0x0436	#CYRILLIC SMALL LETTER ZHE
+0xa7	0x0437	#CYRILLIC SMALL LETTER ZE
+0xa8	0x0438	#CYRILLIC SMALL LETTER I
+0xa9	0x0439	#CYRILLIC SMALL LETTER SHORT I
+0xaa	0x043a	#CYRILLIC SMALL LETTER KA
+0xab	0x043b	#CYRILLIC SMALL LETTER EL
+0xac	0x043c	#CYRILLIC SMALL LETTER EM
+0xad	0x043d	#CYRILLIC SMALL LETTER EN
+0xae	0x043e	#CYRILLIC SMALL LETTER O
+0xaf	0x043f	#CYRILLIC SMALL LETTER PE
+0xb0	0x2591	#LIGHT SHADE
+0xb1	0x2592	#MEDIUM SHADE
+0xb2	0x2593	#DARK SHADE
+0xb3	0x2502	#BOX DRAWINGS LIGHT VERTICAL
+0xb4	0x2524	#BOX DRAWINGS LIGHT VERTICAL AND LEFT
+0xb5	0x2561	#BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE
+0xb6	0x2562	#BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE
+0xb7	0x2556	#BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE
+0xb8	0x2555	#BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE
+0xb9	0x2563	#BOX DRAWINGS DOUBLE VERTICAL AND LEFT
+0xba	0x2551	#BOX DRAWINGS DOUBLE VERTICAL
+0xbb	0x2557	#BOX DRAWINGS DOUBLE DOWN AND LEFT
+0xbc	0x255d	#BOX DRAWINGS DOUBLE UP AND LEFT
+0xbd	0x255c	#BOX DRAWINGS UP DOUBLE AND LEFT SINGLE
+0xbe	0x255b	#BOX DRAWINGS UP SINGLE AND LEFT DOUBLE
+0xbf	0x2510	#BOX DRAWINGS LIGHT DOWN AND LEFT
+0xc0	0x2514	#BOX DRAWINGS LIGHT UP AND RIGHT
+0xc1	0x2534	#BOX DRAWINGS LIGHT UP AND HORIZONTAL
+0xc2	0x252c	#BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
+0xc3	0x251c	#BOX DRAWINGS LIGHT VERTICAL AND RIGHT
+0xc4	0x2500	#BOX DRAWINGS LIGHT HORIZONTAL
+0xc5	0x253c	#BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
+0xc6	0x255e	#BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE
+0xc7	0x255f	#BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE
+0xc8	0x255a	#BOX DRAWINGS DOUBLE UP AND RIGHT
+0xc9	0x2554	#BOX DRAWINGS DOUBLE DOWN AND RIGHT
+0xca	0x2569	#BOX DRAWINGS DOUBLE UP AND HORIZONTAL
+0xcb	0x2566	#BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL
+0xcc	0x2560	#BOX DRAWINGS DOUBLE VERTICAL AND RIGHT
+0xcd	0x2550	#BOX DRAWINGS DOUBLE HORIZONTAL
+0xce	0x256c	#BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL
+0xcf	0x2567	#BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE
+0xd0	0x2568	#BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE
+0xd1	0x2564	#BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE
+0xd2	0x2565	#BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE
+0xd3	0x2559	#BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE
+0xd4	0x2558	#BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE
+0xd5	0x2552	#BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE
+0xd6	0x2553	#BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE
+0xd7	0x256b	#BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE
+0xd8	0x256a	#BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE
+0xd9	0x2518	#BOX DRAWINGS LIGHT UP AND LEFT
+0xda	0x250c	#BOX DRAWINGS LIGHT DOWN AND RIGHT
+0xdb	0x2588	#FULL BLOCK
+0xdc	0x2584	#LOWER HALF BLOCK
+0xdd	0x258c	#LEFT HALF BLOCK
+0xde	0x2590	#RIGHT HALF BLOCK
+0xdf	0x2580	#UPPER HALF BLOCK
+0xe0	0x0440	#CYRILLIC SMALL LETTER ER
+0xe1	0x0441	#CYRILLIC SMALL LETTER ES
+0xe2	0x0442	#CYRILLIC SMALL LETTER TE
+0xe3	0x0443	#CYRILLIC SMALL LETTER U
+0xe4	0x0444	#CYRILLIC SMALL LETTER EF
+0xe5	0x0445	#CYRILLIC SMALL LETTER HA
+0xe6	0x0446	#CYRILLIC SMALL LETTER TSE
+0xe7	0x0447	#CYRILLIC SMALL LETTER CHE
+0xe8	0x0448	#CYRILLIC SMALL LETTER SHA
+0xe9	0x0449	#CYRILLIC SMALL LETTER SHCHA
+0xea	0x044a	#CYRILLIC SMALL LETTER HARD SIGN
+0xeb	0x044b	#CYRILLIC SMALL LETTER YERU
+0xec	0x044c	#CYRILLIC SMALL LETTER SOFT SIGN
+0xed	0x044d	#CYRILLIC SMALL LETTER E
+0xee	0x044e	#CYRILLIC SMALL LETTER YU
+0xef	0x044f	#CYRILLIC SMALL LETTER YA
+0xf0	0x0401	#CYRILLIC CAPITAL LETTER IO
+0xf1	0x0451	#CYRILLIC SMALL LETTER IO
+0xf2	0x0404	#CYRILLIC CAPITAL LETTER UKRAINIAN IE
+0xf3	0x0454	#CYRILLIC SMALL LETTER UKRAINIAN IE
+0xf4	0x0407	#CYRILLIC CAPITAL LETTER YI
+0xf5	0x0457	#CYRILLIC SMALL LETTER YI
+0xf6	0x040e	#CYRILLIC CAPITAL LETTER SHORT U
+0xf7	0x045e	#CYRILLIC SMALL LETTER SHORT U
+0xf8	0x00b0	#DEGREE SIGN
+0xf9	0x2219	#BULLET OPERATOR
+0xfa	0x00b7	#MIDDLE DOT
+0xfb	0x221a	#SQUARE ROOT
+0xfc	0x2116	#NUMERO SIGN
+0xfd	0x00a4	#CURRENCY SIGN
+0xfe	0x25a0	#BLACK SQUARE
+0xff	0x00a0	#NO-BREAK SPACE
+
diff --git a/tools/encoding/cp869.txt b/tools/encoding/cp869.txt
new file mode 100644
index 0000000..4c77ffd
--- /dev/null
+++ b/tools/encoding/cp869.txt
@@ -0,0 +1,274 @@
+#
+#    Name:     cp869_DOSGreek2 to Unicode table
+#    Unicode version: 2.0
+#    Table version: 2.00
+#    Table format:  Format A
+#    Date:          04/24/96
+#    Authors:       Lori Brownell <loribr@microsoft.com>
+#                   K.D. Chang    <a-kchang@microsoft.com>
+#    General notes: none
+#
+#    Format: Three tab-separated columns
+#        Column #1 is the cp869_DOSGreek2 code (in hex)
+#        Column #2 is the Unicode (in hex as 0xXXXX)
+#        Column #3 is the Unicode name (follows a comment sign, '#')
+#
+#    The entries are in cp869_DOSGreek2 order
+#
+0x00	0x0000	#NULL
+0x01	0x0001	#START OF HEADING
+0x02	0x0002	#START OF TEXT
+0x03	0x0003	#END OF TEXT
+0x04	0x0004	#END OF TRANSMISSION
+0x05	0x0005	#ENQUIRY
+0x06	0x0006	#ACKNOWLEDGE
+0x07	0x0007	#BELL
+0x08	0x0008	#BACKSPACE
+0x09	0x0009	#HORIZONTAL TABULATION
+0x0a	0x000a	#LINE FEED
+0x0b	0x000b	#VERTICAL TABULATION
+0x0c	0x000c	#FORM FEED
+0x0d	0x000d	#CARRIAGE RETURN
+0x0e	0x000e	#SHIFT OUT
+0x0f	0x000f	#SHIFT IN
+0x10	0x0010	#DATA LINK ESCAPE
+0x11	0x0011	#DEVICE CONTROL ONE
+0x12	0x0012	#DEVICE CONTROL TWO
+0x13	0x0013	#DEVICE CONTROL THREE
+0x14	0x0014	#DEVICE CONTROL FOUR
+0x15	0x0015	#NEGATIVE ACKNOWLEDGE
+0x16	0x0016	#SYNCHRONOUS IDLE
+0x17	0x0017	#END OF TRANSMISSION BLOCK
+0x18	0x0018	#CANCEL
+0x19	0x0019	#END OF MEDIUM
+0x1a	0x001a	#SUBSTITUTE
+0x1b	0x001b	#ESCAPE
+0x1c	0x001c	#FILE SEPARATOR
+0x1d	0x001d	#GROUP SEPARATOR
+0x1e	0x001e	#RECORD SEPARATOR
+0x1f	0x001f	#UNIT SEPARATOR
+0x20	0x0020	#SPACE
+0x21	0x0021	#EXCLAMATION MARK
+0x22	0x0022	#QUOTATION MARK
+0x23	0x0023	#NUMBER SIGN
+0x24	0x0024	#DOLLAR SIGN
+0x25	0x0025	#PERCENT SIGN
+0x26	0x0026	#AMPERSAND
+0x27	0x0027	#APOSTROPHE
+0x28	0x0028	#LEFT PARENTHESIS
+0x29	0x0029	#RIGHT PARENTHESIS
+0x2a	0x002a	#ASTERISK
+0x2b	0x002b	#PLUS SIGN
+0x2c	0x002c	#COMMA
+0x2d	0x002d	#HYPHEN-MINUS
+0x2e	0x002e	#FULL STOP
+0x2f	0x002f	#SOLIDUS
+0x30	0x0030	#DIGIT ZERO
+0x31	0x0031	#DIGIT ONE
+0x32	0x0032	#DIGIT TWO
+0x33	0x0033	#DIGIT THREE
+0x34	0x0034	#DIGIT FOUR
+0x35	0x0035	#DIGIT FIVE
+0x36	0x0036	#DIGIT SIX
+0x37	0x0037	#DIGIT SEVEN
+0x38	0x0038	#DIGIT EIGHT
+0x39	0x0039	#DIGIT NINE
+0x3a	0x003a	#COLON
+0x3b	0x003b	#SEMICOLON
+0x3c	0x003c	#LESS-THAN SIGN
+0x3d	0x003d	#EQUALS SIGN
+0x3e	0x003e	#GREATER-THAN SIGN
+0x3f	0x003f	#QUESTION MARK
+0x40	0x0040	#COMMERCIAL AT
+0x41	0x0041	#LATIN CAPITAL LETTER A
+0x42	0x0042	#LATIN CAPITAL LETTER B
+0x43	0x0043	#LATIN CAPITAL LETTER C
+0x44	0x0044	#LATIN CAPITAL LETTER D
+0x45	0x0045	#LATIN CAPITAL LETTER E
+0x46	0x0046	#LATIN CAPITAL LETTER F
+0x47	0x0047	#LATIN CAPITAL LETTER G
+0x48	0x0048	#LATIN CAPITAL LETTER H
+0x49	0x0049	#LATIN CAPITAL LETTER I
+0x4a	0x004a	#LATIN CAPITAL LETTER J
+0x4b	0x004b	#LATIN CAPITAL LETTER K
+0x4c	0x004c	#LATIN CAPITAL LETTER L
+0x4d	0x004d	#LATIN CAPITAL LETTER M
+0x4e	0x004e	#LATIN CAPITAL LETTER N
+0x4f	0x004f	#LATIN CAPITAL LETTER O
+0x50	0x0050	#LATIN CAPITAL LETTER P
+0x51	0x0051	#LATIN CAPITAL LETTER Q
+0x52	0x0052	#LATIN CAPITAL LETTER R
+0x53	0x0053	#LATIN CAPITAL LETTER S
+0x54	0x0054	#LATIN CAPITAL LETTER T
+0x55	0x0055	#LATIN CAPITAL LETTER U
+0x56	0x0056	#LATIN CAPITAL LETTER V
+0x57	0x0057	#LATIN CAPITAL LETTER W
+0x58	0x0058	#LATIN CAPITAL LETTER X
+0x59	0x0059	#LATIN CAPITAL LETTER Y
+0x5a	0x005a	#LATIN CAPITAL LETTER Z
+0x5b	0x005b	#LEFT SQUARE BRACKET
+0x5c	0x005c	#REVERSE SOLIDUS
+0x5d	0x005d	#RIGHT SQUARE BRACKET
+0x5e	0x005e	#CIRCUMFLEX ACCENT
+0x5f	0x005f	#LOW LINE
+0x60	0x0060	#GRAVE ACCENT
+0x61	0x0061	#LATIN SMALL LETTER A
+0x62	0x0062	#LATIN SMALL LETTER B
+0x63	0x0063	#LATIN SMALL LETTER C
+0x64	0x0064	#LATIN SMALL LETTER D
+0x65	0x0065	#LATIN SMALL LETTER E
+0x66	0x0066	#LATIN SMALL LETTER F
+0x67	0x0067	#LATIN SMALL LETTER G
+0x68	0x0068	#LATIN SMALL LETTER H
+0x69	0x0069	#LATIN SMALL LETTER I
+0x6a	0x006a	#LATIN SMALL LETTER J
+0x6b	0x006b	#LATIN SMALL LETTER K
+0x6c	0x006c	#LATIN SMALL LETTER L
+0x6d	0x006d	#LATIN SMALL LETTER M
+0x6e	0x006e	#LATIN SMALL LETTER N
+0x6f	0x006f	#LATIN SMALL LETTER O
+0x70	0x0070	#LATIN SMALL LETTER P
+0x71	0x0071	#LATIN SMALL LETTER Q
+0x72	0x0072	#LATIN SMALL LETTER R
+0x73	0x0073	#LATIN SMALL LETTER S
+0x74	0x0074	#LATIN SMALL LETTER T
+0x75	0x0075	#LATIN SMALL LETTER U
+0x76	0x0076	#LATIN SMALL LETTER V
+0x77	0x0077	#LATIN SMALL LETTER W
+0x78	0x0078	#LATIN SMALL LETTER X
+0x79	0x0079	#LATIN SMALL LETTER Y
+0x7a	0x007a	#LATIN SMALL LETTER Z
+0x7b	0x007b	#LEFT CURLY BRACKET
+0x7c	0x007c	#VERTICAL LINE
+0x7d	0x007d	#RIGHT CURLY BRACKET
+0x7e	0x007e	#TILDE
+0x7f	0x007f	#DELETE
+0x80		#UNDEFINED
+0x81		#UNDEFINED
+0x82		#UNDEFINED
+0x83		#UNDEFINED
+0x84		#UNDEFINED
+0x85		#UNDEFINED
+0x86	0x0386	#GREEK CAPITAL LETTER ALPHA WITH TONOS
+0x87		#UNDEFINED
+0x88	0x00b7	#MIDDLE DOT
+0x89	0x00ac	#NOT SIGN
+0x8a	0x00a6	#BROKEN BAR
+0x8b	0x2018	#LEFT SINGLE QUOTATION MARK
+0x8c	0x2019	#RIGHT SINGLE QUOTATION MARK
+0x8d	0x0388	#GREEK CAPITAL LETTER EPSILON WITH TONOS
+0x8e	0x2015	#HORIZONTAL BAR
+0x8f	0x0389	#GREEK CAPITAL LETTER ETA WITH TONOS
+0x90	0x038a	#GREEK CAPITAL LETTER IOTA WITH TONOS
+0x91	0x03aa	#GREEK CAPITAL LETTER IOTA WITH DIALYTIKA
+0x92	0x038c	#GREEK CAPITAL LETTER OMICRON WITH TONOS
+0x93		#UNDEFINED
+0x94		#UNDEFINED
+0x95	0x038e	#GREEK CAPITAL LETTER UPSILON WITH TONOS
+0x96	0x03ab	#GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA
+0x97	0x00a9	#COPYRIGHT SIGN
+0x98	0x038f	#GREEK CAPITAL LETTER OMEGA WITH TONOS
+0x99	0x00b2	#SUPERSCRIPT TWO
+0x9a	0x00b3	#SUPERSCRIPT THREE
+0x9b	0x03ac	#GREEK SMALL LETTER ALPHA WITH TONOS
+0x9c	0x00a3	#POUND SIGN
+0x9d	0x03ad	#GREEK SMALL LETTER EPSILON WITH TONOS
+0x9e	0x03ae	#GREEK SMALL LETTER ETA WITH TONOS
+0x9f	0x03af	#GREEK SMALL LETTER IOTA WITH TONOS
+0xa0	0x03ca	#GREEK SMALL LETTER IOTA WITH DIALYTIKA
+0xa1	0x0390	#GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS
+0xa2	0x03cc	#GREEK SMALL LETTER OMICRON WITH TONOS
+0xa3	0x03cd	#GREEK SMALL LETTER UPSILON WITH TONOS
+0xa4	0x0391	#GREEK CAPITAL LETTER ALPHA
+0xa5	0x0392	#GREEK CAPITAL LETTER BETA
+0xa6	0x0393	#GREEK CAPITAL LETTER GAMMA
+0xa7	0x0394	#GREEK CAPITAL LETTER DELTA
+0xa8	0x0395	#GREEK CAPITAL LETTER EPSILON
+0xa9	0x0396	#GREEK CAPITAL LETTER ZETA
+0xaa	0x0397	#GREEK CAPITAL LETTER ETA
+0xab	0x00bd	#VULGAR FRACTION ONE HALF
+0xac	0x0398	#GREEK CAPITAL LETTER THETA
+0xad	0x0399	#GREEK CAPITAL LETTER IOTA
+0xae	0x00ab	#LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+0xaf	0x00bb	#RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+0xb0	0x2591	#LIGHT SHADE
+0xb1	0x2592	#MEDIUM SHADE
+0xb2	0x2593	#DARK SHADE
+0xb3	0x2502	#BOX DRAWINGS LIGHT VERTICAL
+0xb4	0x2524	#BOX DRAWINGS LIGHT VERTICAL AND LEFT
+0xb5	0x039a	#GREEK CAPITAL LETTER KAPPA
+0xb6	0x039b	#GREEK CAPITAL LETTER LAMDA
+0xb7	0x039c	#GREEK CAPITAL LETTER MU
+0xb8	0x039d	#GREEK CAPITAL LETTER NU
+0xb9	0x2563	#BOX DRAWINGS DOUBLE VERTICAL AND LEFT
+0xba	0x2551	#BOX DRAWINGS DOUBLE VERTICAL
+0xbb	0x2557	#BOX DRAWINGS DOUBLE DOWN AND LEFT
+0xbc	0x255d	#BOX DRAWINGS DOUBLE UP AND LEFT
+0xbd	0x039e	#GREEK CAPITAL LETTER XI
+0xbe	0x039f	#GREEK CAPITAL LETTER OMICRON
+0xbf	0x2510	#BOX DRAWINGS LIGHT DOWN AND LEFT
+0xc0	0x2514	#BOX DRAWINGS LIGHT UP AND RIGHT
+0xc1	0x2534	#BOX DRAWINGS LIGHT UP AND HORIZONTAL
+0xc2	0x252c	#BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
+0xc3	0x251c	#BOX DRAWINGS LIGHT VERTICAL AND RIGHT
+0xc4	0x2500	#BOX DRAWINGS LIGHT HORIZONTAL
+0xc5	0x253c	#BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
+0xc6	0x03a0	#GREEK CAPITAL LETTER PI
+0xc7	0x03a1	#GREEK CAPITAL LETTER RHO
+0xc8	0x255a	#BOX DRAWINGS DOUBLE UP AND RIGHT
+0xc9	0x2554	#BOX DRAWINGS DOUBLE DOWN AND RIGHT
+0xca	0x2569	#BOX DRAWINGS DOUBLE UP AND HORIZONTAL
+0xcb	0x2566	#BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL
+0xcc	0x2560	#BOX DRAWINGS DOUBLE VERTICAL AND RIGHT
+0xcd	0x2550	#BOX DRAWINGS DOUBLE HORIZONTAL
+0xce	0x256c	#BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL
+0xcf	0x03a3	#GREEK CAPITAL LETTER SIGMA
+0xd0	0x03a4	#GREEK CAPITAL LETTER TAU
+0xd1	0x03a5	#GREEK CAPITAL LETTER UPSILON
+0xd2	0x03a6	#GREEK CAPITAL LETTER PHI
+0xd3	0x03a7	#GREEK CAPITAL LETTER CHI
+0xd4	0x03a8	#GREEK CAPITAL LETTER PSI
+0xd5	0x03a9	#GREEK CAPITAL LETTER OMEGA
+0xd6	0x03b1	#GREEK SMALL LETTER ALPHA
+0xd7	0x03b2	#GREEK SMALL LETTER BETA
+0xd8	0x03b3	#GREEK SMALL LETTER GAMMA
+0xd9	0x2518	#BOX DRAWINGS LIGHT UP AND LEFT
+0xda	0x250c	#BOX DRAWINGS LIGHT DOWN AND RIGHT
+0xdb	0x2588	#FULL BLOCK
+0xdc	0x2584	#LOWER HALF BLOCK
+0xdd	0x03b4	#GREEK SMALL LETTER DELTA
+0xde	0x03b5	#GREEK SMALL LETTER EPSILON
+0xdf	0x2580	#UPPER HALF BLOCK
+0xe0	0x03b6	#GREEK SMALL LETTER ZETA
+0xe1	0x03b7	#GREEK SMALL LETTER ETA
+0xe2	0x03b8	#GREEK SMALL LETTER THETA
+0xe3	0x03b9	#GREEK SMALL LETTER IOTA
+0xe4	0x03ba	#GREEK SMALL LETTER KAPPA
+0xe5	0x03bb	#GREEK SMALL LETTER LAMDA
+0xe6	0x03bc	#GREEK SMALL LETTER MU
+0xe7	0x03bd	#GREEK SMALL LETTER NU
+0xe8	0x03be	#GREEK SMALL LETTER XI
+0xe9	0x03bf	#GREEK SMALL LETTER OMICRON
+0xea	0x03c0	#GREEK SMALL LETTER PI
+0xeb	0x03c1	#GREEK SMALL LETTER RHO
+0xec	0x03c3	#GREEK SMALL LETTER SIGMA
+0xed	0x03c2	#GREEK SMALL LETTER FINAL SIGMA
+0xee	0x03c4	#GREEK SMALL LETTER TAU
+0xef	0x0384	#GREEK TONOS
+0xf0	0x00ad	#SOFT HYPHEN
+0xf1	0x00b1	#PLUS-MINUS SIGN
+0xf2	0x03c5	#GREEK SMALL LETTER UPSILON
+0xf3	0x03c6	#GREEK SMALL LETTER PHI
+0xf4	0x03c7	#GREEK SMALL LETTER CHI
+0xf5	0x00a7	#SECTION SIGN
+0xf6	0x03c8	#GREEK SMALL LETTER PSI
+0xf7	0x0385	#GREEK DIALYTIKA TONOS
+0xf8	0x00b0	#DEGREE SIGN
+0xf9	0x00a8	#DIAERESIS
+0xfa	0x03c9	#GREEK SMALL LETTER OMEGA
+0xfb	0x03cb	#GREEK SMALL LETTER UPSILON WITH DIALYTIKA
+0xfc	0x03b0	#GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS
+0xfd	0x03ce	#GREEK SMALL LETTER OMEGA WITH TONOS
+0xfe	0x25a0	#BLACK SQUARE
+0xff	0x00a0	#NO-BREAK SPACE
+
diff --git a/tools/encoding/cp874.txt b/tools/encoding/cp874.txt
new file mode 100644
index 0000000..1eb71df
--- /dev/null
+++ b/tools/encoding/cp874.txt
@@ -0,0 +1,274 @@
+#
+#    Name:     cp874 to Unicode table
+#    Unicode version: 2.0
+#    Table version: 2.01
+#    Table format:  Format A
+#    Date:          02/28/98
+#
+#    Contact:       cpxlate@microsoft.com
+#
+#    General notes: none
+#
+#    Format: Three tab-separated columns
+#        Column #1 is the cp874 code (in hex)
+#        Column #2 is the Unicode (in hex as 0xXXXX)
+#        Column #3 is the Unicode name (follows a comment sign, '#')
+#
+#    The entries are in cp874 order
+#
+0x00	0x0000	#NULL
+0x01	0x0001	#START OF HEADING
+0x02	0x0002	#START OF TEXT
+0x03	0x0003	#END OF TEXT
+0x04	0x0004	#END OF TRANSMISSION
+0x05	0x0005	#ENQUIRY
+0x06	0x0006	#ACKNOWLEDGE
+0x07	0x0007	#BELL
+0x08	0x0008	#BACKSPACE
+0x09	0x0009	#HORIZONTAL TABULATION
+0x0A	0x000A	#LINE FEED
+0x0B	0x000B	#VERTICAL TABULATION
+0x0C	0x000C	#FORM FEED
+0x0D	0x000D	#CARRIAGE RETURN
+0x0E	0x000E	#SHIFT OUT
+0x0F	0x000F	#SHIFT IN
+0x10	0x0010	#DATA LINK ESCAPE
+0x11	0x0011	#DEVICE CONTROL ONE
+0x12	0x0012	#DEVICE CONTROL TWO
+0x13	0x0013	#DEVICE CONTROL THREE
+0x14	0x0014	#DEVICE CONTROL FOUR
+0x15	0x0015	#NEGATIVE ACKNOWLEDGE
+0x16	0x0016	#SYNCHRONOUS IDLE
+0x17	0x0017	#END OF TRANSMISSION BLOCK
+0x18	0x0018	#CANCEL
+0x19	0x0019	#END OF MEDIUM
+0x1A	0x001A	#SUBSTITUTE
+0x1B	0x001B	#ESCAPE
+0x1C	0x001C	#FILE SEPARATOR
+0x1D	0x001D	#GROUP SEPARATOR
+0x1E	0x001E	#RECORD SEPARATOR
+0x1F	0x001F	#UNIT SEPARATOR
+0x20	0x0020	#SPACE
+0x21	0x0021	#EXCLAMATION MARK
+0x22	0x0022	#QUOTATION MARK
+0x23	0x0023	#NUMBER SIGN
+0x24	0x0024	#DOLLAR SIGN
+0x25	0x0025	#PERCENT SIGN
+0x26	0x0026	#AMPERSAND
+0x27	0x0027	#APOSTROPHE
+0x28	0x0028	#LEFT PARENTHESIS
+0x29	0x0029	#RIGHT PARENTHESIS
+0x2A	0x002A	#ASTERISK
+0x2B	0x002B	#PLUS SIGN
+0x2C	0x002C	#COMMA
+0x2D	0x002D	#HYPHEN-MINUS
+0x2E	0x002E	#FULL STOP
+0x2F	0x002F	#SOLIDUS
+0x30	0x0030	#DIGIT ZERO
+0x31	0x0031	#DIGIT ONE
+0x32	0x0032	#DIGIT TWO
+0x33	0x0033	#DIGIT THREE
+0x34	0x0034	#DIGIT FOUR
+0x35	0x0035	#DIGIT FIVE
+0x36	0x0036	#DIGIT SIX
+0x37	0x0037	#DIGIT SEVEN
+0x38	0x0038	#DIGIT EIGHT
+0x39	0x0039	#DIGIT NINE
+0x3A	0x003A	#COLON
+0x3B	0x003B	#SEMICOLON
+0x3C	0x003C	#LESS-THAN SIGN
+0x3D	0x003D	#EQUALS SIGN
+0x3E	0x003E	#GREATER-THAN SIGN
+0x3F	0x003F	#QUESTION MARK
+0x40	0x0040	#COMMERCIAL AT
+0x41	0x0041	#LATIN CAPITAL LETTER A
+0x42	0x0042	#LATIN CAPITAL LETTER B
+0x43	0x0043	#LATIN CAPITAL LETTER C
+0x44	0x0044	#LATIN CAPITAL LETTER D
+0x45	0x0045	#LATIN CAPITAL LETTER E
+0x46	0x0046	#LATIN CAPITAL LETTER F
+0x47	0x0047	#LATIN CAPITAL LETTER G
+0x48	0x0048	#LATIN CAPITAL LETTER H
+0x49	0x0049	#LATIN CAPITAL LETTER I
+0x4A	0x004A	#LATIN CAPITAL LETTER J
+0x4B	0x004B	#LATIN CAPITAL LETTER K
+0x4C	0x004C	#LATIN CAPITAL LETTER L
+0x4D	0x004D	#LATIN CAPITAL LETTER M
+0x4E	0x004E	#LATIN CAPITAL LETTER N
+0x4F	0x004F	#LATIN CAPITAL LETTER O
+0x50	0x0050	#LATIN CAPITAL LETTER P
+0x51	0x0051	#LATIN CAPITAL LETTER Q
+0x52	0x0052	#LATIN CAPITAL LETTER R
+0x53	0x0053	#LATIN CAPITAL LETTER S
+0x54	0x0054	#LATIN CAPITAL LETTER T
+0x55	0x0055	#LATIN CAPITAL LETTER U
+0x56	0x0056	#LATIN CAPITAL LETTER V
+0x57	0x0057	#LATIN CAPITAL LETTER W
+0x58	0x0058	#LATIN CAPITAL LETTER X
+0x59	0x0059	#LATIN CAPITAL LETTER Y
+0x5A	0x005A	#LATIN CAPITAL LETTER Z
+0x5B	0x005B	#LEFT SQUARE BRACKET
+0x5C	0x005C	#REVERSE SOLIDUS
+0x5D	0x005D	#RIGHT SQUARE BRACKET
+0x5E	0x005E	#CIRCUMFLEX ACCENT
+0x5F	0x005F	#LOW LINE
+0x60	0x0060	#GRAVE ACCENT
+0x61	0x0061	#LATIN SMALL LETTER A
+0x62	0x0062	#LATIN SMALL LETTER B
+0x63	0x0063	#LATIN SMALL LETTER C
+0x64	0x0064	#LATIN SMALL LETTER D
+0x65	0x0065	#LATIN SMALL LETTER E
+0x66	0x0066	#LATIN SMALL LETTER F
+0x67	0x0067	#LATIN SMALL LETTER G
+0x68	0x0068	#LATIN SMALL LETTER H
+0x69	0x0069	#LATIN SMALL LETTER I
+0x6A	0x006A	#LATIN SMALL LETTER J
+0x6B	0x006B	#LATIN SMALL LETTER K
+0x6C	0x006C	#LATIN SMALL LETTER L
+0x6D	0x006D	#LATIN SMALL LETTER M
+0x6E	0x006E	#LATIN SMALL LETTER N
+0x6F	0x006F	#LATIN SMALL LETTER O
+0x70	0x0070	#LATIN SMALL LETTER P
+0x71	0x0071	#LATIN SMALL LETTER Q
+0x72	0x0072	#LATIN SMALL LETTER R
+0x73	0x0073	#LATIN SMALL LETTER S
+0x74	0x0074	#LATIN SMALL LETTER T
+0x75	0x0075	#LATIN SMALL LETTER U
+0x76	0x0076	#LATIN SMALL LETTER V
+0x77	0x0077	#LATIN SMALL LETTER W
+0x78	0x0078	#LATIN SMALL LETTER X
+0x79	0x0079	#LATIN SMALL LETTER Y
+0x7A	0x007A	#LATIN SMALL LETTER Z
+0x7B	0x007B	#LEFT CURLY BRACKET
+0x7C	0x007C	#VERTICAL LINE
+0x7D	0x007D	#RIGHT CURLY BRACKET
+0x7E	0x007E	#TILDE
+0x7F	0x007F	#DELETE
+0x80	0x20AC	#EURO SIGN
+0x81	      	#UNDEFINED
+0x82	      	#UNDEFINED
+0x83	      	#UNDEFINED
+0x84	      	#UNDEFINED
+0x85	0x2026	#HORIZONTAL ELLIPSIS
+0x86	      	#UNDEFINED
+0x87	      	#UNDEFINED
+0x88	      	#UNDEFINED
+0x89	      	#UNDEFINED
+0x8A	      	#UNDEFINED
+0x8B	      	#UNDEFINED
+0x8C	      	#UNDEFINED
+0x8D	      	#UNDEFINED
+0x8E	      	#UNDEFINED
+0x8F	      	#UNDEFINED
+0x90	      	#UNDEFINED
+0x91	0x2018	#LEFT SINGLE QUOTATION MARK
+0x92	0x2019	#RIGHT SINGLE QUOTATION MARK
+0x93	0x201C	#LEFT DOUBLE QUOTATION MARK
+0x94	0x201D	#RIGHT DOUBLE QUOTATION MARK
+0x95	0x2022	#BULLET
+0x96	0x2013	#EN DASH
+0x97	0x2014	#EM DASH
+0x98	      	#UNDEFINED
+0x99	      	#UNDEFINED
+0x9A	      	#UNDEFINED
+0x9B	      	#UNDEFINED
+0x9C	      	#UNDEFINED
+0x9D	      	#UNDEFINED
+0x9E	      	#UNDEFINED
+0x9F	      	#UNDEFINED
+0xA0	0x00A0	#NO-BREAK SPACE
+0xA1	0x0E01	#THAI CHARACTER KO KAI
+0xA2	0x0E02	#THAI CHARACTER KHO KHAI
+0xA3	0x0E03	#THAI CHARACTER KHO KHUAT
+0xA4	0x0E04	#THAI CHARACTER KHO KHWAI
+0xA5	0x0E05	#THAI CHARACTER KHO KHON
+0xA6	0x0E06	#THAI CHARACTER KHO RAKHANG
+0xA7	0x0E07	#THAI CHARACTER NGO NGU
+0xA8	0x0E08	#THAI CHARACTER CHO CHAN
+0xA9	0x0E09	#THAI CHARACTER CHO CHING
+0xAA	0x0E0A	#THAI CHARACTER CHO CHANG
+0xAB	0x0E0B	#THAI CHARACTER SO SO
+0xAC	0x0E0C	#THAI CHARACTER CHO CHOE
+0xAD	0x0E0D	#THAI CHARACTER YO YING
+0xAE	0x0E0E	#THAI CHARACTER DO CHADA
+0xAF	0x0E0F	#THAI CHARACTER TO PATAK
+0xB0	0x0E10	#THAI CHARACTER THO THAN
+0xB1	0x0E11	#THAI CHARACTER THO NANGMONTHO
+0xB2	0x0E12	#THAI CHARACTER THO PHUTHAO
+0xB3	0x0E13	#THAI CHARACTER NO NEN
+0xB4	0x0E14	#THAI CHARACTER DO DEK
+0xB5	0x0E15	#THAI CHARACTER TO TAO
+0xB6	0x0E16	#THAI CHARACTER THO THUNG
+0xB7	0x0E17	#THAI CHARACTER THO THAHAN
+0xB8	0x0E18	#THAI CHARACTER THO THONG
+0xB9	0x0E19	#THAI CHARACTER NO NU
+0xBA	0x0E1A	#THAI CHARACTER BO BAIMAI
+0xBB	0x0E1B	#THAI CHARACTER PO PLA
+0xBC	0x0E1C	#THAI CHARACTER PHO PHUNG
+0xBD	0x0E1D	#THAI CHARACTER FO FA
+0xBE	0x0E1E	#THAI CHARACTER PHO PHAN
+0xBF	0x0E1F	#THAI CHARACTER FO FAN
+0xC0	0x0E20	#THAI CHARACTER PHO SAMPHAO
+0xC1	0x0E21	#THAI CHARACTER MO MA
+0xC2	0x0E22	#THAI CHARACTER YO YAK
+0xC3	0x0E23	#THAI CHARACTER RO RUA
+0xC4	0x0E24	#THAI CHARACTER RU
+0xC5	0x0E25	#THAI CHARACTER LO LING
+0xC6	0x0E26	#THAI CHARACTER LU
+0xC7	0x0E27	#THAI CHARACTER WO WAEN
+0xC8	0x0E28	#THAI CHARACTER SO SALA
+0xC9	0x0E29	#THAI CHARACTER SO RUSI
+0xCA	0x0E2A	#THAI CHARACTER SO SUA
+0xCB	0x0E2B	#THAI CHARACTER HO HIP
+0xCC	0x0E2C	#THAI CHARACTER LO CHULA
+0xCD	0x0E2D	#THAI CHARACTER O ANG
+0xCE	0x0E2E	#THAI CHARACTER HO NOKHUK
+0xCF	0x0E2F	#THAI CHARACTER PAIYANNOI
+0xD0	0x0E30	#THAI CHARACTER SARA A
+0xD1	0x0E31	#THAI CHARACTER MAI HAN-AKAT
+0xD2	0x0E32	#THAI CHARACTER SARA AA
+0xD3	0x0E33	#THAI CHARACTER SARA AM
+0xD4	0x0E34	#THAI CHARACTER SARA I
+0xD5	0x0E35	#THAI CHARACTER SARA II
+0xD6	0x0E36	#THAI CHARACTER SARA UE
+0xD7	0x0E37	#THAI CHARACTER SARA UEE
+0xD8	0x0E38	#THAI CHARACTER SARA U
+0xD9	0x0E39	#THAI CHARACTER SARA UU
+0xDA	0x0E3A	#THAI CHARACTER PHINTHU
+0xDB	      	#UNDEFINED
+0xDC	      	#UNDEFINED
+0xDD	      	#UNDEFINED
+0xDE	      	#UNDEFINED
+0xDF	0x0E3F	#THAI CURRENCY SYMBOL BAHT
+0xE0	0x0E40	#THAI CHARACTER SARA E
+0xE1	0x0E41	#THAI CHARACTER SARA AE
+0xE2	0x0E42	#THAI CHARACTER SARA O
+0xE3	0x0E43	#THAI CHARACTER SARA AI MAIMUAN
+0xE4	0x0E44	#THAI CHARACTER SARA AI MAIMALAI
+0xE5	0x0E45	#THAI CHARACTER LAKKHANGYAO
+0xE6	0x0E46	#THAI CHARACTER MAIYAMOK
+0xE7	0x0E47	#THAI CHARACTER MAITAIKHU
+0xE8	0x0E48	#THAI CHARACTER MAI EK
+0xE9	0x0E49	#THAI CHARACTER MAI THO
+0xEA	0x0E4A	#THAI CHARACTER MAI TRI
+0xEB	0x0E4B	#THAI CHARACTER MAI CHATTAWA
+0xEC	0x0E4C	#THAI CHARACTER THANTHAKHAT
+0xED	0x0E4D	#THAI CHARACTER NIKHAHIT
+0xEE	0x0E4E	#THAI CHARACTER YAMAKKAN
+0xEF	0x0E4F	#THAI CHARACTER FONGMAN
+0xF0	0x0E50	#THAI DIGIT ZERO
+0xF1	0x0E51	#THAI DIGIT ONE
+0xF2	0x0E52	#THAI DIGIT TWO
+0xF3	0x0E53	#THAI DIGIT THREE
+0xF4	0x0E54	#THAI DIGIT FOUR
+0xF5	0x0E55	#THAI DIGIT FIVE
+0xF6	0x0E56	#THAI DIGIT SIX
+0xF7	0x0E57	#THAI DIGIT SEVEN
+0xF8	0x0E58	#THAI DIGIT EIGHT
+0xF9	0x0E59	#THAI DIGIT NINE
+0xFA	0x0E5A	#THAI CHARACTER ANGKHANKHU
+0xFB	0x0E5B	#THAI CHARACTER KHOMUT
+0xFC	      	#UNDEFINED
+0xFD	      	#UNDEFINED
+0xFE	      	#UNDEFINED
+0xFF	      	#UNDEFINED
diff --git a/tools/encoding/cp932.txt b/tools/encoding/cp932.txt
new file mode 100644
index 0000000..36bfdbf
--- /dev/null
+++ b/tools/encoding/cp932.txt
@@ -0,0 +1,7998 @@
+#
+#    Name:     cp932 to Unicode table
+#    Unicode version: 2.0
+#    Table version: 2.01
+#    Table format:  Format A
+#    Date:          04/15/98
+#
+#    Contact:       cpxlate@microsoft.com
+#
+#    General notes: none
+#
+#    Format: Three tab-separated columns
+#        Column #1 is the cp932 code (in hex)
+#        Column #2 is the Unicode (in hex as 0xXXXX)
+#        Column #3 is the Unicode name (follows a comment sign, '#')
+#
+#    The entries are in cp932 order
+#
+0x00	0x0000	#NULL
+0x01	0x0001	#START OF HEADING
+0x02	0x0002	#START OF TEXT
+0x03	0x0003	#END OF TEXT
+0x04	0x0004	#END OF TRANSMISSION
+0x05	0x0005	#ENQUIRY
+0x06	0x0006	#ACKNOWLEDGE
+0x07	0x0007	#BELL
+0x08	0x0008	#BACKSPACE
+0x09	0x0009	#HORIZONTAL TABULATION
+0x0A	0x000A	#LINE FEED
+0x0B	0x000B	#VERTICAL TABULATION
+0x0C	0x000C	#FORM FEED
+0x0D	0x000D	#CARRIAGE RETURN
+0x0E	0x000E	#SHIFT OUT
+0x0F	0x000F	#SHIFT IN
+0x10	0x0010	#DATA LINK ESCAPE
+0x11	0x0011	#DEVICE CONTROL ONE
+0x12	0x0012	#DEVICE CONTROL TWO
+0x13	0x0013	#DEVICE CONTROL THREE
+0x14	0x0014	#DEVICE CONTROL FOUR
+0x15	0x0015	#NEGATIVE ACKNOWLEDGE
+0x16	0x0016	#SYNCHRONOUS IDLE
+0x17	0x0017	#END OF TRANSMISSION BLOCK
+0x18	0x0018	#CANCEL
+0x19	0x0019	#END OF MEDIUM
+0x1A	0x001A	#SUBSTITUTE
+0x1B	0x001B	#ESCAPE
+0x1C	0x001C	#FILE SEPARATOR
+0x1D	0x001D	#GROUP SEPARATOR
+0x1E	0x001E	#RECORD SEPARATOR
+0x1F	0x001F	#UNIT SEPARATOR
+0x20	0x0020	#SPACE
+0x21	0x0021	#EXCLAMATION MARK
+0x22	0x0022	#QUOTATION MARK
+0x23	0x0023	#NUMBER SIGN
+0x24	0x0024	#DOLLAR SIGN
+0x25	0x0025	#PERCENT SIGN
+0x26	0x0026	#AMPERSAND
+0x27	0x0027	#APOSTROPHE
+0x28	0x0028	#LEFT PARENTHESIS
+0x29	0x0029	#RIGHT PARENTHESIS
+0x2A	0x002A	#ASTERISK
+0x2B	0x002B	#PLUS SIGN
+0x2C	0x002C	#COMMA
+0x2D	0x002D	#HYPHEN-MINUS
+0x2E	0x002E	#FULL STOP
+0x2F	0x002F	#SOLIDUS
+0x30	0x0030	#DIGIT ZERO
+0x31	0x0031	#DIGIT ONE
+0x32	0x0032	#DIGIT TWO
+0x33	0x0033	#DIGIT THREE
+0x34	0x0034	#DIGIT FOUR
+0x35	0x0035	#DIGIT FIVE
+0x36	0x0036	#DIGIT SIX
+0x37	0x0037	#DIGIT SEVEN
+0x38	0x0038	#DIGIT EIGHT
+0x39	0x0039	#DIGIT NINE
+0x3A	0x003A	#COLON
+0x3B	0x003B	#SEMICOLON
+0x3C	0x003C	#LESS-THAN SIGN
+0x3D	0x003D	#EQUALS SIGN
+0x3E	0x003E	#GREATER-THAN SIGN
+0x3F	0x003F	#QUESTION MARK
+0x40	0x0040	#COMMERCIAL AT
+0x41	0x0041	#LATIN CAPITAL LETTER A
+0x42	0x0042	#LATIN CAPITAL LETTER B
+0x43	0x0043	#LATIN CAPITAL LETTER C
+0x44	0x0044	#LATIN CAPITAL LETTER D
+0x45	0x0045	#LATIN CAPITAL LETTER E
+0x46	0x0046	#LATIN CAPITAL LETTER F
+0x47	0x0047	#LATIN CAPITAL LETTER G
+0x48	0x0048	#LATIN CAPITAL LETTER H
+0x49	0x0049	#LATIN CAPITAL LETTER I
+0x4A	0x004A	#LATIN CAPITAL LETTER J
+0x4B	0x004B	#LATIN CAPITAL LETTER K
+0x4C	0x004C	#LATIN CAPITAL LETTER L
+0x4D	0x004D	#LATIN CAPITAL LETTER M
+0x4E	0x004E	#LATIN CAPITAL LETTER N
+0x4F	0x004F	#LATIN CAPITAL LETTER O
+0x50	0x0050	#LATIN CAPITAL LETTER P
+0x51	0x0051	#LATIN CAPITAL LETTER Q
+0x52	0x0052	#LATIN CAPITAL LETTER R
+0x53	0x0053	#LATIN CAPITAL LETTER S
+0x54	0x0054	#LATIN CAPITAL LETTER T
+0x55	0x0055	#LATIN CAPITAL LETTER U
+0x56	0x0056	#LATIN CAPITAL LETTER V
+0x57	0x0057	#LATIN CAPITAL LETTER W
+0x58	0x0058	#LATIN CAPITAL LETTER X
+0x59	0x0059	#LATIN CAPITAL LETTER Y
+0x5A	0x005A	#LATIN CAPITAL LETTER Z
+0x5B	0x005B	#LEFT SQUARE BRACKET
+0x5C	0x005C	#REVERSE SOLIDUS
+0x5D	0x005D	#RIGHT SQUARE BRACKET
+0x5E	0x005E	#CIRCUMFLEX ACCENT
+0x5F	0x005F	#LOW LINE
+0x60	0x0060	#GRAVE ACCENT
+0x61	0x0061	#LATIN SMALL LETTER A
+0x62	0x0062	#LATIN SMALL LETTER B
+0x63	0x0063	#LATIN SMALL LETTER C
+0x64	0x0064	#LATIN SMALL LETTER D
+0x65	0x0065	#LATIN SMALL LETTER E
+0x66	0x0066	#LATIN SMALL LETTER F
+0x67	0x0067	#LATIN SMALL LETTER G
+0x68	0x0068	#LATIN SMALL LETTER H
+0x69	0x0069	#LATIN SMALL LETTER I
+0x6A	0x006A	#LATIN SMALL LETTER J
+0x6B	0x006B	#LATIN SMALL LETTER K
+0x6C	0x006C	#LATIN SMALL LETTER L
+0x6D	0x006D	#LATIN SMALL LETTER M
+0x6E	0x006E	#LATIN SMALL LETTER N
+0x6F	0x006F	#LATIN SMALL LETTER O
+0x70	0x0070	#LATIN SMALL LETTER P
+0x71	0x0071	#LATIN SMALL LETTER Q
+0x72	0x0072	#LATIN SMALL LETTER R
+0x73	0x0073	#LATIN SMALL LETTER S
+0x74	0x0074	#LATIN SMALL LETTER T
+0x75	0x0075	#LATIN SMALL LETTER U
+0x76	0x0076	#LATIN SMALL LETTER V
+0x77	0x0077	#LATIN SMALL LETTER W
+0x78	0x0078	#LATIN SMALL LETTER X
+0x79	0x0079	#LATIN SMALL LETTER Y
+0x7A	0x007A	#LATIN SMALL LETTER Z
+0x7B	0x007B	#LEFT CURLY BRACKET
+0x7C	0x007C	#VERTICAL LINE
+0x7D	0x007D	#RIGHT CURLY BRACKET
+0x7E	0x007E	#TILDE
+0x7F	0x007F	#DELETE
+0x80	      	#UNDEFINED
+0x81	      	#DBCS LEAD BYTE
+0x82	      	#DBCS LEAD BYTE
+0x83	      	#DBCS LEAD BYTE
+0x84	      	#DBCS LEAD BYTE
+0x85	      	#DBCS LEAD BYTE
+0x86	      	#DBCS LEAD BYTE
+0x87	      	#DBCS LEAD BYTE
+0x88	      	#DBCS LEAD BYTE
+0x89	      	#DBCS LEAD BYTE
+0x8A	      	#DBCS LEAD BYTE
+0x8B	      	#DBCS LEAD BYTE
+0x8C	      	#DBCS LEAD BYTE
+0x8D	      	#DBCS LEAD BYTE
+0x8E	      	#DBCS LEAD BYTE
+0x8F	      	#DBCS LEAD BYTE
+0x90	      	#DBCS LEAD BYTE
+0x91	      	#DBCS LEAD BYTE
+0x92	      	#DBCS LEAD BYTE
+0x93	      	#DBCS LEAD BYTE
+0x94	      	#DBCS LEAD BYTE
+0x95	      	#DBCS LEAD BYTE
+0x96	      	#DBCS LEAD BYTE
+0x97	      	#DBCS LEAD BYTE
+0x98	      	#DBCS LEAD BYTE
+0x99	      	#DBCS LEAD BYTE
+0x9A	      	#DBCS LEAD BYTE
+0x9B	      	#DBCS LEAD BYTE
+0x9C	      	#DBCS LEAD BYTE
+0x9D	      	#DBCS LEAD BYTE
+0x9E	      	#DBCS LEAD BYTE
+0x9F	      	#DBCS LEAD BYTE
+0xA0	      	#UNDEFINED
+0xA1	0xFF61	#HALFWIDTH IDEOGRAPHIC FULL STOP
+0xA2	0xFF62	#HALFWIDTH LEFT CORNER BRACKET
+0xA3	0xFF63	#HALFWIDTH RIGHT CORNER BRACKET
+0xA4	0xFF64	#HALFWIDTH IDEOGRAPHIC COMMA
+0xA5	0xFF65	#HALFWIDTH KATAKANA MIDDLE DOT
+0xA6	0xFF66	#HALFWIDTH KATAKANA LETTER WO
+0xA7	0xFF67	#HALFWIDTH KATAKANA LETTER SMALL A
+0xA8	0xFF68	#HALFWIDTH KATAKANA LETTER SMALL I
+0xA9	0xFF69	#HALFWIDTH KATAKANA LETTER SMALL U
+0xAA	0xFF6A	#HALFWIDTH KATAKANA LETTER SMALL E
+0xAB	0xFF6B	#HALFWIDTH KATAKANA LETTER SMALL O
+0xAC	0xFF6C	#HALFWIDTH KATAKANA LETTER SMALL YA
+0xAD	0xFF6D	#HALFWIDTH KATAKANA LETTER SMALL YU
+0xAE	0xFF6E	#HALFWIDTH KATAKANA LETTER SMALL YO
+0xAF	0xFF6F	#HALFWIDTH KATAKANA LETTER SMALL TU
+0xB0	0xFF70	#HALFWIDTH KATAKANA-HIRAGANA PROLONGED SOUND MARK
+0xB1	0xFF71	#HALFWIDTH KATAKANA LETTER A
+0xB2	0xFF72	#HALFWIDTH KATAKANA LETTER I
+0xB3	0xFF73	#HALFWIDTH KATAKANA LETTER U
+0xB4	0xFF74	#HALFWIDTH KATAKANA LETTER E
+0xB5	0xFF75	#HALFWIDTH KATAKANA LETTER O
+0xB6	0xFF76	#HALFWIDTH KATAKANA LETTER KA
+0xB7	0xFF77	#HALFWIDTH KATAKANA LETTER KI
+0xB8	0xFF78	#HALFWIDTH KATAKANA LETTER KU
+0xB9	0xFF79	#HALFWIDTH KATAKANA LETTER KE
+0xBA	0xFF7A	#HALFWIDTH KATAKANA LETTER KO
+0xBB	0xFF7B	#HALFWIDTH KATAKANA LETTER SA
+0xBC	0xFF7C	#HALFWIDTH KATAKANA LETTER SI
+0xBD	0xFF7D	#HALFWIDTH KATAKANA LETTER SU
+0xBE	0xFF7E	#HALFWIDTH KATAKANA LETTER SE
+0xBF	0xFF7F	#HALFWIDTH KATAKANA LETTER SO
+0xC0	0xFF80	#HALFWIDTH KATAKANA LETTER TA
+0xC1	0xFF81	#HALFWIDTH KATAKANA LETTER TI
+0xC2	0xFF82	#HALFWIDTH KATAKANA LETTER TU
+0xC3	0xFF83	#HALFWIDTH KATAKANA LETTER TE
+0xC4	0xFF84	#HALFWIDTH KATAKANA LETTER TO
+0xC5	0xFF85	#HALFWIDTH KATAKANA LETTER NA
+0xC6	0xFF86	#HALFWIDTH KATAKANA LETTER NI
+0xC7	0xFF87	#HALFWIDTH KATAKANA LETTER NU
+0xC8	0xFF88	#HALFWIDTH KATAKANA LETTER NE
+0xC9	0xFF89	#HALFWIDTH KATAKANA LETTER NO
+0xCA	0xFF8A	#HALFWIDTH KATAKANA LETTER HA
+0xCB	0xFF8B	#HALFWIDTH KATAKANA LETTER HI
+0xCC	0xFF8C	#HALFWIDTH KATAKANA LETTER HU
+0xCD	0xFF8D	#HALFWIDTH KATAKANA LETTER HE
+0xCE	0xFF8E	#HALFWIDTH KATAKANA LETTER HO
+0xCF	0xFF8F	#HALFWIDTH KATAKANA LETTER MA
+0xD0	0xFF90	#HALFWIDTH KATAKANA LETTER MI
+0xD1	0xFF91	#HALFWIDTH KATAKANA LETTER MU
+0xD2	0xFF92	#HALFWIDTH KATAKANA LETTER ME
+0xD3	0xFF93	#HALFWIDTH KATAKANA LETTER MO
+0xD4	0xFF94	#HALFWIDTH KATAKANA LETTER YA
+0xD5	0xFF95	#HALFWIDTH KATAKANA LETTER YU
+0xD6	0xFF96	#HALFWIDTH KATAKANA LETTER YO
+0xD7	0xFF97	#HALFWIDTH KATAKANA LETTER RA
+0xD8	0xFF98	#HALFWIDTH KATAKANA LETTER RI
+0xD9	0xFF99	#HALFWIDTH KATAKANA LETTER RU
+0xDA	0xFF9A	#HALFWIDTH KATAKANA LETTER RE
+0xDB	0xFF9B	#HALFWIDTH KATAKANA LETTER RO
+0xDC	0xFF9C	#HALFWIDTH KATAKANA LETTER WA
+0xDD	0xFF9D	#HALFWIDTH KATAKANA LETTER N
+0xDE	0xFF9E	#HALFWIDTH KATAKANA VOICED SOUND MARK
+0xDF	0xFF9F	#HALFWIDTH KATAKANA SEMI-VOICED SOUND MARK
+0xE0	      	#DBCS LEAD BYTE
+0xE1	      	#DBCS LEAD BYTE
+0xE2	      	#DBCS LEAD BYTE
+0xE3	      	#DBCS LEAD BYTE
+0xE4	      	#DBCS LEAD BYTE
+0xE5	      	#DBCS LEAD BYTE
+0xE6	      	#DBCS LEAD BYTE
+0xE7	      	#DBCS LEAD BYTE
+0xE8	      	#DBCS LEAD BYTE
+0xE9	      	#DBCS LEAD BYTE
+0xEA	      	#DBCS LEAD BYTE
+0xEB	      	#DBCS LEAD BYTE
+0xEC	      	#DBCS LEAD BYTE
+0xED	      	#DBCS LEAD BYTE
+0xEE	      	#DBCS LEAD BYTE
+0xEF	      	#DBCS LEAD BYTE
+0xF0	      	#DBCS LEAD BYTE
+0xF1	      	#DBCS LEAD BYTE
+0xF2	      	#DBCS LEAD BYTE
+0xF3	      	#DBCS LEAD BYTE
+0xF4	      	#DBCS LEAD BYTE
+0xF5	      	#DBCS LEAD BYTE
+0xF6	      	#DBCS LEAD BYTE
+0xF7	      	#DBCS LEAD BYTE
+0xF8	      	#DBCS LEAD BYTE
+0xF9	      	#DBCS LEAD BYTE
+0xFA	      	#DBCS LEAD BYTE
+0xFB	      	#DBCS LEAD BYTE
+0xFC	      	#DBCS LEAD BYTE
+0xFD	      	#UNDEFINED
+0xFE	      	#UNDEFINED
+0xFF	      	#UNDEFINED
+0x8140	0x3000	#IDEOGRAPHIC SPACE
+0x8141	0x3001	#IDEOGRAPHIC COMMA
+0x8142	0x3002	#IDEOGRAPHIC FULL STOP
+0x8143	0xFF0C	#FULLWIDTH COMMA
+0x8144	0xFF0E	#FULLWIDTH FULL STOP
+0x8145	0x30FB	#KATAKANA MIDDLE DOT
+0x8146	0xFF1A	#FULLWIDTH COLON
+0x8147	0xFF1B	#FULLWIDTH SEMICOLON
+0x8148	0xFF1F	#FULLWIDTH QUESTION MARK
+0x8149	0xFF01	#FULLWIDTH EXCLAMATION MARK
+0x814A	0x309B	#KATAKANA-HIRAGANA VOICED SOUND MARK
+0x814B	0x309C	#KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK
+0x814C	0x00B4	#ACUTE ACCENT
+0x814D	0xFF40	#FULLWIDTH GRAVE ACCENT
+0x814E	0x00A8	#DIAERESIS
+0x814F	0xFF3E	#FULLWIDTH CIRCUMFLEX ACCENT
+0x8150	0xFFE3	#FULLWIDTH MACRON
+0x8151	0xFF3F	#FULLWIDTH LOW LINE
+0x8152	0x30FD	#KATAKANA ITERATION MARK
+0x8153	0x30FE	#KATAKANA VOICED ITERATION MARK
+0x8154	0x309D	#HIRAGANA ITERATION MARK
+0x8155	0x309E	#HIRAGANA VOICED ITERATION MARK
+0x8156	0x3003	#DITTO MARK
+0x8157	0x4EDD	#CJK UNIFIED IDEOGRAPH
+0x8158	0x3005	#IDEOGRAPHIC ITERATION MARK
+0x8159	0x3006	#IDEOGRAPHIC CLOSING MARK
+0x815A	0x3007	#IDEOGRAPHIC NUMBER ZERO
+0x815B	0x30FC	#KATAKANA-HIRAGANA PROLONGED SOUND MARK
+0x815C	0x2015	#HORIZONTAL BAR
+0x815D	0x2010	#HYPHEN
+0x815E	0xFF0F	#FULLWIDTH SOLIDUS
+0x815F	0xFF3C	#FULLWIDTH REVERSE SOLIDUS
+0x8160	0xFF5E	#FULLWIDTH TILDE
+0x8161	0x2225	#PARALLEL TO
+0x8162	0xFF5C	#FULLWIDTH VERTICAL LINE
+0x8163	0x2026	#HORIZONTAL ELLIPSIS
+0x8164	0x2025	#TWO DOT LEADER
+0x8165	0x2018	#LEFT SINGLE QUOTATION MARK
+0x8166	0x2019	#RIGHT SINGLE QUOTATION MARK
+0x8167	0x201C	#LEFT DOUBLE QUOTATION MARK
+0x8168	0x201D	#RIGHT DOUBLE QUOTATION MARK
+0x8169	0xFF08	#FULLWIDTH LEFT PARENTHESIS
+0x816A	0xFF09	#FULLWIDTH RIGHT PARENTHESIS
+0x816B	0x3014	#LEFT TORTOISE SHELL BRACKET
+0x816C	0x3015	#RIGHT TORTOISE SHELL BRACKET
+0x816D	0xFF3B	#FULLWIDTH LEFT SQUARE BRACKET
+0x816E	0xFF3D	#FULLWIDTH RIGHT SQUARE BRACKET
+0x816F	0xFF5B	#FULLWIDTH LEFT CURLY BRACKET
+0x8170	0xFF5D	#FULLWIDTH RIGHT CURLY BRACKET
+0x8171	0x3008	#LEFT ANGLE BRACKET
+0x8172	0x3009	#RIGHT ANGLE BRACKET
+0x8173	0x300A	#LEFT DOUBLE ANGLE BRACKET
+0x8174	0x300B	#RIGHT DOUBLE ANGLE BRACKET
+0x8175	0x300C	#LEFT CORNER BRACKET
+0x8176	0x300D	#RIGHT CORNER BRACKET
+0x8177	0x300E	#LEFT WHITE CORNER BRACKET
+0x8178	0x300F	#RIGHT WHITE CORNER BRACKET
+0x8179	0x3010	#LEFT BLACK LENTICULAR BRACKET
+0x817A	0x3011	#RIGHT BLACK LENTICULAR BRACKET
+0x817B	0xFF0B	#FULLWIDTH PLUS SIGN
+0x817C	0xFF0D	#FULLWIDTH HYPHEN-MINUS
+0x817D	0x00B1	#PLUS-MINUS SIGN
+0x817E	0x00D7	#MULTIPLICATION SIGN
+0x8180	0x00F7	#DIVISION SIGN
+0x8181	0xFF1D	#FULLWIDTH EQUALS SIGN
+0x8182	0x2260	#NOT EQUAL TO
+0x8183	0xFF1C	#FULLWIDTH LESS-THAN SIGN
+0x8184	0xFF1E	#FULLWIDTH GREATER-THAN SIGN
+0x8185	0x2266	#LESS-THAN OVER EQUAL TO
+0x8186	0x2267	#GREATER-THAN OVER EQUAL TO
+0x8187	0x221E	#INFINITY
+0x8188	0x2234	#THEREFORE
+0x8189	0x2642	#MALE SIGN
+0x818A	0x2640	#FEMALE SIGN
+0x818B	0x00B0	#DEGREE SIGN
+0x818C	0x2032	#PRIME
+0x818D	0x2033	#DOUBLE PRIME
+0x818E	0x2103	#DEGREE CELSIUS
+0x818F	0xFFE5	#FULLWIDTH YEN SIGN
+0x8190	0xFF04	#FULLWIDTH DOLLAR SIGN
+0x8191	0xFFE0	#FULLWIDTH CENT SIGN
+0x8192	0xFFE1	#FULLWIDTH POUND SIGN
+0x8193	0xFF05	#FULLWIDTH PERCENT SIGN
+0x8194	0xFF03	#FULLWIDTH NUMBER SIGN
+0x8195	0xFF06	#FULLWIDTH AMPERSAND
+0x8196	0xFF0A	#FULLWIDTH ASTERISK
+0x8197	0xFF20	#FULLWIDTH COMMERCIAL AT
+0x8198	0x00A7	#SECTION SIGN
+0x8199	0x2606	#WHITE STAR
+0x819A	0x2605	#BLACK STAR
+0x819B	0x25CB	#WHITE CIRCLE
+0x819C	0x25CF	#BLACK CIRCLE
+0x819D	0x25CE	#BULLSEYE
+0x819E	0x25C7	#WHITE DIAMOND
+0x819F	0x25C6	#BLACK DIAMOND
+0x81A0	0x25A1	#WHITE SQUARE
+0x81A1	0x25A0	#BLACK SQUARE
+0x81A2	0x25B3	#WHITE UP-POINTING TRIANGLE
+0x81A3	0x25B2	#BLACK UP-POINTING TRIANGLE
+0x81A4	0x25BD	#WHITE DOWN-POINTING TRIANGLE
+0x81A5	0x25BC	#BLACK DOWN-POINTING TRIANGLE
+0x81A6	0x203B	#REFERENCE MARK
+0x81A7	0x3012	#POSTAL MARK
+0x81A8	0x2192	#RIGHTWARDS ARROW
+0x81A9	0x2190	#LEFTWARDS ARROW
+0x81AA	0x2191	#UPWARDS ARROW
+0x81AB	0x2193	#DOWNWARDS ARROW
+0x81AC	0x3013	#GETA MARK
+0x81B8	0x2208	#ELEMENT OF
+0x81B9	0x220B	#CONTAINS AS MEMBER
+0x81BA	0x2286	#SUBSET OF OR EQUAL TO
+0x81BB	0x2287	#SUPERSET OF OR EQUAL TO
+0x81BC	0x2282	#SUBSET OF
+0x81BD	0x2283	#SUPERSET OF
+0x81BE	0x222A	#UNION
+0x81BF	0x2229	#INTERSECTION
+0x81C8	0x2227	#LOGICAL AND
+0x81C9	0x2228	#LOGICAL OR
+0x81CA	0xFFE2	#FULLWIDTH NOT SIGN
+0x81CB	0x21D2	#RIGHTWARDS DOUBLE ARROW
+0x81CC	0x21D4	#LEFT RIGHT DOUBLE ARROW
+0x81CD	0x2200	#FOR ALL
+0x81CE	0x2203	#THERE EXISTS
+0x81DA	0x2220	#ANGLE
+0x81DB	0x22A5	#UP TACK
+0x81DC	0x2312	#ARC
+0x81DD	0x2202	#PARTIAL DIFFERENTIAL
+0x81DE	0x2207	#NABLA
+0x81DF	0x2261	#IDENTICAL TO
+0x81E0	0x2252	#APPROXIMATELY EQUAL TO OR THE IMAGE OF
+0x81E1	0x226A	#MUCH LESS-THAN
+0x81E2	0x226B	#MUCH GREATER-THAN
+0x81E3	0x221A	#SQUARE ROOT
+0x81E4	0x223D	#REVERSED TILDE
+0x81E5	0x221D	#PROPORTIONAL TO
+0x81E6	0x2235	#BECAUSE
+0x81E7	0x222B	#INTEGRAL
+0x81E8	0x222C	#DOUBLE INTEGRAL
+0x81F0	0x212B	#ANGSTROM SIGN
+0x81F1	0x2030	#PER MILLE SIGN
+0x81F2	0x266F	#MUSIC SHARP SIGN
+0x81F3	0x266D	#MUSIC FLAT SIGN
+0x81F4	0x266A	#EIGHTH NOTE
+0x81F5	0x2020	#DAGGER
+0x81F6	0x2021	#DOUBLE DAGGER
+0x81F7	0x00B6	#PILCROW SIGN
+0x81FC	0x25EF	#LARGE CIRCLE
+0x824F	0xFF10	#FULLWIDTH DIGIT ZERO
+0x8250	0xFF11	#FULLWIDTH DIGIT ONE
+0x8251	0xFF12	#FULLWIDTH DIGIT TWO
+0x8252	0xFF13	#FULLWIDTH DIGIT THREE
+0x8253	0xFF14	#FULLWIDTH DIGIT FOUR
+0x8254	0xFF15	#FULLWIDTH DIGIT FIVE
+0x8255	0xFF16	#FULLWIDTH DIGIT SIX
+0x8256	0xFF17	#FULLWIDTH DIGIT SEVEN
+0x8257	0xFF18	#FULLWIDTH DIGIT EIGHT
+0x8258	0xFF19	#FULLWIDTH DIGIT NINE
+0x8260	0xFF21	#FULLWIDTH LATIN CAPITAL LETTER A
+0x8261	0xFF22	#FULLWIDTH LATIN CAPITAL LETTER B
+0x8262	0xFF23	#FULLWIDTH LATIN CAPITAL LETTER C
+0x8263	0xFF24	#FULLWIDTH LATIN CAPITAL LETTER D
+0x8264	0xFF25	#FULLWIDTH LATIN CAPITAL LETTER E
+0x8265	0xFF26	#FULLWIDTH LATIN CAPITAL LETTER F
+0x8266	0xFF27	#FULLWIDTH LATIN CAPITAL LETTER G
+0x8267	0xFF28	#FULLWIDTH LATIN CAPITAL LETTER H
+0x8268	0xFF29	#FULLWIDTH LATIN CAPITAL LETTER I
+0x8269	0xFF2A	#FULLWIDTH LATIN CAPITAL LETTER J
+0x826A	0xFF2B	#FULLWIDTH LATIN CAPITAL LETTER K
+0x826B	0xFF2C	#FULLWIDTH LATIN CAPITAL LETTER L
+0x826C	0xFF2D	#FULLWIDTH LATIN CAPITAL LETTER M
+0x826D	0xFF2E	#FULLWIDTH LATIN CAPITAL LETTER N
+0x826E	0xFF2F	#FULLWIDTH LATIN CAPITAL LETTER O
+0x826F	0xFF30	#FULLWIDTH LATIN CAPITAL LETTER P
+0x8270	0xFF31	#FULLWIDTH LATIN CAPITAL LETTER Q
+0x8271	0xFF32	#FULLWIDTH LATIN CAPITAL LETTER R
+0x8272	0xFF33	#FULLWIDTH LATIN CAPITAL LETTER S
+0x8273	0xFF34	#FULLWIDTH LATIN CAPITAL LETTER T
+0x8274	0xFF35	#FULLWIDTH LATIN CAPITAL LETTER U
+0x8275	0xFF36	#FULLWIDTH LATIN CAPITAL LETTER V
+0x8276	0xFF37	#FULLWIDTH LATIN CAPITAL LETTER W
+0x8277	0xFF38	#FULLWIDTH LATIN CAPITAL LETTER X
+0x8278	0xFF39	#FULLWIDTH LATIN CAPITAL LETTER Y
+0x8279	0xFF3A	#FULLWIDTH LATIN CAPITAL LETTER Z
+0x8281	0xFF41	#FULLWIDTH LATIN SMALL LETTER A
+0x8282	0xFF42	#FULLWIDTH LATIN SMALL LETTER B
+0x8283	0xFF43	#FULLWIDTH LATIN SMALL LETTER C
+0x8284	0xFF44	#FULLWIDTH LATIN SMALL LETTER D
+0x8285	0xFF45	#FULLWIDTH LATIN SMALL LETTER E
+0x8286	0xFF46	#FULLWIDTH LATIN SMALL LETTER F
+0x8287	0xFF47	#FULLWIDTH LATIN SMALL LETTER G
+0x8288	0xFF48	#FULLWIDTH LATIN SMALL LETTER H
+0x8289	0xFF49	#FULLWIDTH LATIN SMALL LETTER I
+0x828A	0xFF4A	#FULLWIDTH LATIN SMALL LETTER J
+0x828B	0xFF4B	#FULLWIDTH LATIN SMALL LETTER K
+0x828C	0xFF4C	#FULLWIDTH LATIN SMALL LETTER L
+0x828D	0xFF4D	#FULLWIDTH LATIN SMALL LETTER M
+0x828E	0xFF4E	#FULLWIDTH LATIN SMALL LETTER N
+0x828F	0xFF4F	#FULLWIDTH LATIN SMALL LETTER O
+0x8290	0xFF50	#FULLWIDTH LATIN SMALL LETTER P
+0x8291	0xFF51	#FULLWIDTH LATIN SMALL LETTER Q
+0x8292	0xFF52	#FULLWIDTH LATIN SMALL LETTER R
+0x8293	0xFF53	#FULLWIDTH LATIN SMALL LETTER S
+0x8294	0xFF54	#FULLWIDTH LATIN SMALL LETTER T
+0x8295	0xFF55	#FULLWIDTH LATIN SMALL LETTER U
+0x8296	0xFF56	#FULLWIDTH LATIN SMALL LETTER V
+0x8297	0xFF57	#FULLWIDTH LATIN SMALL LETTER W
+0x8298	0xFF58	#FULLWIDTH LATIN SMALL LETTER X
+0x8299	0xFF59	#FULLWIDTH LATIN SMALL LETTER Y
+0x829A	0xFF5A	#FULLWIDTH LATIN SMALL LETTER Z
+0x829F	0x3041	#HIRAGANA LETTER SMALL A
+0x82A0	0x3042	#HIRAGANA LETTER A
+0x82A1	0x3043	#HIRAGANA LETTER SMALL I
+0x82A2	0x3044	#HIRAGANA LETTER I
+0x82A3	0x3045	#HIRAGANA LETTER SMALL U
+0x82A4	0x3046	#HIRAGANA LETTER U
+0x82A5	0x3047	#HIRAGANA LETTER SMALL E
+0x82A6	0x3048	#HIRAGANA LETTER E
+0x82A7	0x3049	#HIRAGANA LETTER SMALL O
+0x82A8	0x304A	#HIRAGANA LETTER O
+0x82A9	0x304B	#HIRAGANA LETTER KA
+0x82AA	0x304C	#HIRAGANA LETTER GA
+0x82AB	0x304D	#HIRAGANA LETTER KI
+0x82AC	0x304E	#HIRAGANA LETTER GI
+0x82AD	0x304F	#HIRAGANA LETTER KU
+0x82AE	0x3050	#HIRAGANA LETTER GU
+0x82AF	0x3051	#HIRAGANA LETTER KE
+0x82B0	0x3052	#HIRAGANA LETTER GE
+0x82B1	0x3053	#HIRAGANA LETTER KO
+0x82B2	0x3054	#HIRAGANA LETTER GO
+0x82B3	0x3055	#HIRAGANA LETTER SA
+0x82B4	0x3056	#HIRAGANA LETTER ZA
+0x82B5	0x3057	#HIRAGANA LETTER SI
+0x82B6	0x3058	#HIRAGANA LETTER ZI
+0x82B7	0x3059	#HIRAGANA LETTER SU
+0x82B8	0x305A	#HIRAGANA LETTER ZU
+0x82B9	0x305B	#HIRAGANA LETTER SE
+0x82BA	0x305C	#HIRAGANA LETTER ZE
+0x82BB	0x305D	#HIRAGANA LETTER SO
+0x82BC	0x305E	#HIRAGANA LETTER ZO
+0x82BD	0x305F	#HIRAGANA LETTER TA
+0x82BE	0x3060	#HIRAGANA LETTER DA
+0x82BF	0x3061	#HIRAGANA LETTER TI
+0x82C0	0x3062	#HIRAGANA LETTER DI
+0x82C1	0x3063	#HIRAGANA LETTER SMALL TU
+0x82C2	0x3064	#HIRAGANA LETTER TU
+0x82C3	0x3065	#HIRAGANA LETTER DU
+0x82C4	0x3066	#HIRAGANA LETTER TE
+0x82C5	0x3067	#HIRAGANA LETTER DE
+0x82C6	0x3068	#HIRAGANA LETTER TO
+0x82C7	0x3069	#HIRAGANA LETTER DO
+0x82C8	0x306A	#HIRAGANA LETTER NA
+0x82C9	0x306B	#HIRAGANA LETTER NI
+0x82CA	0x306C	#HIRAGANA LETTER NU
+0x82CB	0x306D	#HIRAGANA LETTER NE
+0x82CC	0x306E	#HIRAGANA LETTER NO
+0x82CD	0x306F	#HIRAGANA LETTER HA
+0x82CE	0x3070	#HIRAGANA LETTER BA
+0x82CF	0x3071	#HIRAGANA LETTER PA
+0x82D0	0x3072	#HIRAGANA LETTER HI
+0x82D1	0x3073	#HIRAGANA LETTER BI
+0x82D2	0x3074	#HIRAGANA LETTER PI
+0x82D3	0x3075	#HIRAGANA LETTER HU
+0x82D4	0x3076	#HIRAGANA LETTER BU
+0x82D5	0x3077	#HIRAGANA LETTER PU
+0x82D6	0x3078	#HIRAGANA LETTER HE
+0x82D7	0x3079	#HIRAGANA LETTER BE
+0x82D8	0x307A	#HIRAGANA LETTER PE
+0x82D9	0x307B	#HIRAGANA LETTER HO
+0x82DA	0x307C	#HIRAGANA LETTER BO
+0x82DB	0x307D	#HIRAGANA LETTER PO
+0x82DC	0x307E	#HIRAGANA LETTER MA
+0x82DD	0x307F	#HIRAGANA LETTER MI
+0x82DE	0x3080	#HIRAGANA LETTER MU
+0x82DF	0x3081	#HIRAGANA LETTER ME
+0x82E0	0x3082	#HIRAGANA LETTER MO
+0x82E1	0x3083	#HIRAGANA LETTER SMALL YA
+0x82E2	0x3084	#HIRAGANA LETTER YA
+0x82E3	0x3085	#HIRAGANA LETTER SMALL YU
+0x82E4	0x3086	#HIRAGANA LETTER YU
+0x82E5	0x3087	#HIRAGANA LETTER SMALL YO
+0x82E6	0x3088	#HIRAGANA LETTER YO
+0x82E7	0x3089	#HIRAGANA LETTER RA
+0x82E8	0x308A	#HIRAGANA LETTER RI
+0x82E9	0x308B	#HIRAGANA LETTER RU
+0x82EA	0x308C	#HIRAGANA LETTER RE
+0x82EB	0x308D	#HIRAGANA LETTER RO
+0x82EC	0x308E	#HIRAGANA LETTER SMALL WA
+0x82ED	0x308F	#HIRAGANA LETTER WA
+0x82EE	0x3090	#HIRAGANA LETTER WI
+0x82EF	0x3091	#HIRAGANA LETTER WE
+0x82F0	0x3092	#HIRAGANA LETTER WO
+0x82F1	0x3093	#HIRAGANA LETTER N
+0x8340	0x30A1	#KATAKANA LETTER SMALL A
+0x8341	0x30A2	#KATAKANA LETTER A
+0x8342	0x30A3	#KATAKANA LETTER SMALL I
+0x8343	0x30A4	#KATAKANA LETTER I
+0x8344	0x30A5	#KATAKANA LETTER SMALL U
+0x8345	0x30A6	#KATAKANA LETTER U
+0x8346	0x30A7	#KATAKANA LETTER SMALL E
+0x8347	0x30A8	#KATAKANA LETTER E
+0x8348	0x30A9	#KATAKANA LETTER SMALL O
+0x8349	0x30AA	#KATAKANA LETTER O
+0x834A	0x30AB	#KATAKANA LETTER KA
+0x834B	0x30AC	#KATAKANA LETTER GA
+0x834C	0x30AD	#KATAKANA LETTER KI
+0x834D	0x30AE	#KATAKANA LETTER GI
+0x834E	0x30AF	#KATAKANA LETTER KU
+0x834F	0x30B0	#KATAKANA LETTER GU
+0x8350	0x30B1	#KATAKANA LETTER KE
+0x8351	0x30B2	#KATAKANA LETTER GE
+0x8352	0x30B3	#KATAKANA LETTER KO
+0x8353	0x30B4	#KATAKANA LETTER GO
+0x8354	0x30B5	#KATAKANA LETTER SA
+0x8355	0x30B6	#KATAKANA LETTER ZA
+0x8356	0x30B7	#KATAKANA LETTER SI
+0x8357	0x30B8	#KATAKANA LETTER ZI
+0x8358	0x30B9	#KATAKANA LETTER SU
+0x8359	0x30BA	#KATAKANA LETTER ZU
+0x835A	0x30BB	#KATAKANA LETTER SE
+0x835B	0x30BC	#KATAKANA LETTER ZE
+0x835C	0x30BD	#KATAKANA LETTER SO
+0x835D	0x30BE	#KATAKANA LETTER ZO
+0x835E	0x30BF	#KATAKANA LETTER TA
+0x835F	0x30C0	#KATAKANA LETTER DA
+0x8360	0x30C1	#KATAKANA LETTER TI
+0x8361	0x30C2	#KATAKANA LETTER DI
+0x8362	0x30C3	#KATAKANA LETTER SMALL TU
+0x8363	0x30C4	#KATAKANA LETTER TU
+0x8364	0x30C5	#KATAKANA LETTER DU
+0x8365	0x30C6	#KATAKANA LETTER TE
+0x8366	0x30C7	#KATAKANA LETTER DE
+0x8367	0x30C8	#KATAKANA LETTER TO
+0x8368	0x30C9	#KATAKANA LETTER DO
+0x8369	0x30CA	#KATAKANA LETTER NA
+0x836A	0x30CB	#KATAKANA LETTER NI
+0x836B	0x30CC	#KATAKANA LETTER NU
+0x836C	0x30CD	#KATAKANA LETTER NE
+0x836D	0x30CE	#KATAKANA LETTER NO
+0x836E	0x30CF	#KATAKANA LETTER HA
+0x836F	0x30D0	#KATAKANA LETTER BA
+0x8370	0x30D1	#KATAKANA LETTER PA
+0x8371	0x30D2	#KATAKANA LETTER HI
+0x8372	0x30D3	#KATAKANA LETTER BI
+0x8373	0x30D4	#KATAKANA LETTER PI
+0x8374	0x30D5	#KATAKANA LETTER HU
+0x8375	0x30D6	#KATAKANA LETTER BU
+0x8376	0x30D7	#KATAKANA LETTER PU
+0x8377	0x30D8	#KATAKANA LETTER HE
+0x8378	0x30D9	#KATAKANA LETTER BE
+0x8379	0x30DA	#KATAKANA LETTER PE
+0x837A	0x30DB	#KATAKANA LETTER HO
+0x837B	0x30DC	#KATAKANA LETTER BO
+0x837C	0x30DD	#KATAKANA LETTER PO
+0x837D	0x30DE	#KATAKANA LETTER MA
+0x837E	0x30DF	#KATAKANA LETTER MI
+0x8380	0x30E0	#KATAKANA LETTER MU
+0x8381	0x30E1	#KATAKANA LETTER ME
+0x8382	0x30E2	#KATAKANA LETTER MO
+0x8383	0x30E3	#KATAKANA LETTER SMALL YA
+0x8384	0x30E4	#KATAKANA LETTER YA
+0x8385	0x30E5	#KATAKANA LETTER SMALL YU
+0x8386	0x30E6	#KATAKANA LETTER YU
+0x8387	0x30E7	#KATAKANA LETTER SMALL YO
+0x8388	0x30E8	#KATAKANA LETTER YO
+0x8389	0x30E9	#KATAKANA LETTER RA
+0x838A	0x30EA	#KATAKANA LETTER RI
+0x838B	0x30EB	#KATAKANA LETTER RU
+0x838C	0x30EC	#KATAKANA LETTER RE
+0x838D	0x30ED	#KATAKANA LETTER RO
+0x838E	0x30EE	#KATAKANA LETTER SMALL WA
+0x838F	0x30EF	#KATAKANA LETTER WA
+0x8390	0x30F0	#KATAKANA LETTER WI
+0x8391	0x30F1	#KATAKANA LETTER WE
+0x8392	0x30F2	#KATAKANA LETTER WO
+0x8393	0x30F3	#KATAKANA LETTER N
+0x8394	0x30F4	#KATAKANA LETTER VU
+0x8395	0x30F5	#KATAKANA LETTER SMALL KA
+0x8396	0x30F6	#KATAKANA LETTER SMALL KE
+0x839F	0x0391	#GREEK CAPITAL LETTER ALPHA
+0x83A0	0x0392	#GREEK CAPITAL LETTER BETA
+0x83A1	0x0393	#GREEK CAPITAL LETTER GAMMA
+0x83A2	0x0394	#GREEK CAPITAL LETTER DELTA
+0x83A3	0x0395	#GREEK CAPITAL LETTER EPSILON
+0x83A4	0x0396	#GREEK CAPITAL LETTER ZETA
+0x83A5	0x0397	#GREEK CAPITAL LETTER ETA
+0x83A6	0x0398	#GREEK CAPITAL LETTER THETA
+0x83A7	0x0399	#GREEK CAPITAL LETTER IOTA
+0x83A8	0x039A	#GREEK CAPITAL LETTER KAPPA
+0x83A9	0x039B	#GREEK CAPITAL LETTER LAMDA
+0x83AA	0x039C	#GREEK CAPITAL LETTER MU
+0x83AB	0x039D	#GREEK CAPITAL LETTER NU
+0x83AC	0x039E	#GREEK CAPITAL LETTER XI
+0x83AD	0x039F	#GREEK CAPITAL LETTER OMICRON
+0x83AE	0x03A0	#GREEK CAPITAL LETTER PI
+0x83AF	0x03A1	#GREEK CAPITAL LETTER RHO
+0x83B0	0x03A3	#GREEK CAPITAL LETTER SIGMA
+0x83B1	0x03A4	#GREEK CAPITAL LETTER TAU
+0x83B2	0x03A5	#GREEK CAPITAL LETTER UPSILON
+0x83B3	0x03A6	#GREEK CAPITAL LETTER PHI
+0x83B4	0x03A7	#GREEK CAPITAL LETTER CHI
+0x83B5	0x03A8	#GREEK CAPITAL LETTER PSI
+0x83B6	0x03A9	#GREEK CAPITAL LETTER OMEGA
+0x83BF	0x03B1	#GREEK SMALL LETTER ALPHA
+0x83C0	0x03B2	#GREEK SMALL LETTER BETA
+0x83C1	0x03B3	#GREEK SMALL LETTER GAMMA
+0x83C2	0x03B4	#GREEK SMALL LETTER DELTA
+0x83C3	0x03B5	#GREEK SMALL LETTER EPSILON
+0x83C4	0x03B6	#GREEK SMALL LETTER ZETA
+0x83C5	0x03B7	#GREEK SMALL LETTER ETA
+0x83C6	0x03B8	#GREEK SMALL LETTER THETA
+0x83C7	0x03B9	#GREEK SMALL LETTER IOTA
+0x83C8	0x03BA	#GREEK SMALL LETTER KAPPA
+0x83C9	0x03BB	#GREEK SMALL LETTER LAMDA
+0x83CA	0x03BC	#GREEK SMALL LETTER MU
+0x83CB	0x03BD	#GREEK SMALL LETTER NU
+0x83CC	0x03BE	#GREEK SMALL LETTER XI
+0x83CD	0x03BF	#GREEK SMALL LETTER OMICRON
+0x83CE	0x03C0	#GREEK SMALL LETTER PI
+0x83CF	0x03C1	#GREEK SMALL LETTER RHO
+0x83D0	0x03C3	#GREEK SMALL LETTER SIGMA
+0x83D1	0x03C4	#GREEK SMALL LETTER TAU
+0x83D2	0x03C5	#GREEK SMALL LETTER UPSILON
+0x83D3	0x03C6	#GREEK SMALL LETTER PHI
+0x83D4	0x03C7	#GREEK SMALL LETTER CHI
+0x83D5	0x03C8	#GREEK SMALL LETTER PSI
+0x83D6	0x03C9	#GREEK SMALL LETTER OMEGA
+0x8440	0x0410	#CYRILLIC CAPITAL LETTER A
+0x8441	0x0411	#CYRILLIC CAPITAL LETTER BE
+0x8442	0x0412	#CYRILLIC CAPITAL LETTER VE
+0x8443	0x0413	#CYRILLIC CAPITAL LETTER GHE
+0x8444	0x0414	#CYRILLIC CAPITAL LETTER DE
+0x8445	0x0415	#CYRILLIC CAPITAL LETTER IE
+0x8446	0x0401	#CYRILLIC CAPITAL LETTER IO
+0x8447	0x0416	#CYRILLIC CAPITAL LETTER ZHE
+0x8448	0x0417	#CYRILLIC CAPITAL LETTER ZE
+0x8449	0x0418	#CYRILLIC CAPITAL LETTER I
+0x844A	0x0419	#CYRILLIC CAPITAL LETTER SHORT I
+0x844B	0x041A	#CYRILLIC CAPITAL LETTER KA
+0x844C	0x041B	#CYRILLIC CAPITAL LETTER EL
+0x844D	0x041C	#CYRILLIC CAPITAL LETTER EM
+0x844E	0x041D	#CYRILLIC CAPITAL LETTER EN
+0x844F	0x041E	#CYRILLIC CAPITAL LETTER O
+0x8450	0x041F	#CYRILLIC CAPITAL LETTER PE
+0x8451	0x0420	#CYRILLIC CAPITAL LETTER ER
+0x8452	0x0421	#CYRILLIC CAPITAL LETTER ES
+0x8453	0x0422	#CYRILLIC CAPITAL LETTER TE
+0x8454	0x0423	#CYRILLIC CAPITAL LETTER U
+0x8455	0x0424	#CYRILLIC CAPITAL LETTER EF
+0x8456	0x0425	#CYRILLIC CAPITAL LETTER HA
+0x8457	0x0426	#CYRILLIC CAPITAL LETTER TSE
+0x8458	0x0427	#CYRILLIC CAPITAL LETTER CHE
+0x8459	0x0428	#CYRILLIC CAPITAL LETTER SHA
+0x845A	0x0429	#CYRILLIC CAPITAL LETTER SHCHA
+0x845B	0x042A	#CYRILLIC CAPITAL LETTER HARD SIGN
+0x845C	0x042B	#CYRILLIC CAPITAL LETTER YERU
+0x845D	0x042C	#CYRILLIC CAPITAL LETTER SOFT SIGN
+0x845E	0x042D	#CYRILLIC CAPITAL LETTER E
+0x845F	0x042E	#CYRILLIC CAPITAL LETTER YU
+0x8460	0x042F	#CYRILLIC CAPITAL LETTER YA
+0x8470	0x0430	#CYRILLIC SMALL LETTER A
+0x8471	0x0431	#CYRILLIC SMALL LETTER BE
+0x8472	0x0432	#CYRILLIC SMALL LETTER VE
+0x8473	0x0433	#CYRILLIC SMALL LETTER GHE
+0x8474	0x0434	#CYRILLIC SMALL LETTER DE
+0x8475	0x0435	#CYRILLIC SMALL LETTER IE
+0x8476	0x0451	#CYRILLIC SMALL LETTER IO
+0x8477	0x0436	#CYRILLIC SMALL LETTER ZHE
+0x8478	0x0437	#CYRILLIC SMALL LETTER ZE
+0x8479	0x0438	#CYRILLIC SMALL LETTER I
+0x847A	0x0439	#CYRILLIC SMALL LETTER SHORT I
+0x847B	0x043A	#CYRILLIC SMALL LETTER KA
+0x847C	0x043B	#CYRILLIC SMALL LETTER EL
+0x847D	0x043C	#CYRILLIC SMALL LETTER EM
+0x847E	0x043D	#CYRILLIC SMALL LETTER EN
+0x8480	0x043E	#CYRILLIC SMALL LETTER O
+0x8481	0x043F	#CYRILLIC SMALL LETTER PE
+0x8482	0x0440	#CYRILLIC SMALL LETTER ER
+0x8483	0x0441	#CYRILLIC SMALL LETTER ES
+0x8484	0x0442	#CYRILLIC SMALL LETTER TE
+0x8485	0x0443	#CYRILLIC SMALL LETTER U
+0x8486	0x0444	#CYRILLIC SMALL LETTER EF
+0x8487	0x0445	#CYRILLIC SMALL LETTER HA
+0x8488	0x0446	#CYRILLIC SMALL LETTER TSE
+0x8489	0x0447	#CYRILLIC SMALL LETTER CHE
+0x848A	0x0448	#CYRILLIC SMALL LETTER SHA
+0x848B	0x0449	#CYRILLIC SMALL LETTER SHCHA
+0x848C	0x044A	#CYRILLIC SMALL LETTER HARD SIGN
+0x848D	0x044B	#CYRILLIC SMALL LETTER YERU
+0x848E	0x044C	#CYRILLIC SMALL LETTER SOFT SIGN
+0x848F	0x044D	#CYRILLIC SMALL LETTER E
+0x8490	0x044E	#CYRILLIC SMALL LETTER YU
+0x8491	0x044F	#CYRILLIC SMALL LETTER YA
+0x849F	0x2500	#BOX DRAWINGS LIGHT HORIZONTAL
+0x84A0	0x2502	#BOX DRAWINGS LIGHT VERTICAL
+0x84A1	0x250C	#BOX DRAWINGS LIGHT DOWN AND RIGHT
+0x84A2	0x2510	#BOX DRAWINGS LIGHT DOWN AND LEFT
+0x84A3	0x2518	#BOX DRAWINGS LIGHT UP AND LEFT
+0x84A4	0x2514	#BOX DRAWINGS LIGHT UP AND RIGHT
+0x84A5	0x251C	#BOX DRAWINGS LIGHT VERTICAL AND RIGHT
+0x84A6	0x252C	#BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
+0x84A7	0x2524	#BOX DRAWINGS LIGHT VERTICAL AND LEFT
+0x84A8	0x2534	#BOX DRAWINGS LIGHT UP AND HORIZONTAL
+0x84A9	0x253C	#BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
+0x84AA	0x2501	#BOX DRAWINGS HEAVY HORIZONTAL
+0x84AB	0x2503	#BOX DRAWINGS HEAVY VERTICAL
+0x84AC	0x250F	#BOX DRAWINGS HEAVY DOWN AND RIGHT
+0x84AD	0x2513	#BOX DRAWINGS HEAVY DOWN AND LEFT
+0x84AE	0x251B	#BOX DRAWINGS HEAVY UP AND LEFT
+0x84AF	0x2517	#BOX DRAWINGS HEAVY UP AND RIGHT
+0x84B0	0x2523	#BOX DRAWINGS HEAVY VERTICAL AND RIGHT
+0x84B1	0x2533	#BOX DRAWINGS HEAVY DOWN AND HORIZONTAL
+0x84B2	0x252B	#BOX DRAWINGS HEAVY VERTICAL AND LEFT
+0x84B3	0x253B	#BOX DRAWINGS HEAVY UP AND HORIZONTAL
+0x84B4	0x254B	#BOX DRAWINGS HEAVY VERTICAL AND HORIZONTAL
+0x84B5	0x2520	#BOX DRAWINGS VERTICAL HEAVY AND RIGHT LIGHT
+0x84B6	0x252F	#BOX DRAWINGS DOWN LIGHT AND HORIZONTAL HEAVY
+0x84B7	0x2528	#BOX DRAWINGS VERTICAL HEAVY AND LEFT LIGHT
+0x84B8	0x2537	#BOX DRAWINGS UP LIGHT AND HORIZONTAL HEAVY
+0x84B9	0x253F	#BOX DRAWINGS VERTICAL LIGHT AND HORIZONTAL HEAVY
+0x84BA	0x251D	#BOX DRAWINGS VERTICAL LIGHT AND RIGHT HEAVY
+0x84BB	0x2530	#BOX DRAWINGS DOWN HEAVY AND HORIZONTAL LIGHT
+0x84BC	0x2525	#BOX DRAWINGS VERTICAL LIGHT AND LEFT HEAVY
+0x84BD	0x2538	#BOX DRAWINGS UP HEAVY AND HORIZONTAL LIGHT
+0x84BE	0x2542	#BOX DRAWINGS VERTICAL HEAVY AND HORIZONTAL LIGHT
+0x8740	0x2460	#CIRCLED DIGIT ONE
+0x8741	0x2461	#CIRCLED DIGIT TWO
+0x8742	0x2462	#CIRCLED DIGIT THREE
+0x8743	0x2463	#CIRCLED DIGIT FOUR
+0x8744	0x2464	#CIRCLED DIGIT FIVE
+0x8745	0x2465	#CIRCLED DIGIT SIX
+0x8746	0x2466	#CIRCLED DIGIT SEVEN
+0x8747	0x2467	#CIRCLED DIGIT EIGHT
+0x8748	0x2468	#CIRCLED DIGIT NINE
+0x8749	0x2469	#CIRCLED NUMBER TEN
+0x874A	0x246A	#CIRCLED NUMBER ELEVEN
+0x874B	0x246B	#CIRCLED NUMBER TWELVE
+0x874C	0x246C	#CIRCLED NUMBER THIRTEEN
+0x874D	0x246D	#CIRCLED NUMBER FOURTEEN
+0x874E	0x246E	#CIRCLED NUMBER FIFTEEN
+0x874F	0x246F	#CIRCLED NUMBER SIXTEEN
+0x8750	0x2470	#CIRCLED NUMBER SEVENTEEN
+0x8751	0x2471	#CIRCLED NUMBER EIGHTEEN
+0x8752	0x2472	#CIRCLED NUMBER NINETEEN
+0x8753	0x2473	#CIRCLED NUMBER TWENTY
+0x8754	0x2160	#ROMAN NUMERAL ONE
+0x8755	0x2161	#ROMAN NUMERAL TWO
+0x8756	0x2162	#ROMAN NUMERAL THREE
+0x8757	0x2163	#ROMAN NUMERAL FOUR
+0x8758	0x2164	#ROMAN NUMERAL FIVE
+0x8759	0x2165	#ROMAN NUMERAL SIX
+0x875A	0x2166	#ROMAN NUMERAL SEVEN
+0x875B	0x2167	#ROMAN NUMERAL EIGHT
+0x875C	0x2168	#ROMAN NUMERAL NINE
+0x875D	0x2169	#ROMAN NUMERAL TEN
+0x875F	0x3349	#SQUARE MIRI
+0x8760	0x3314	#SQUARE KIRO
+0x8761	0x3322	#SQUARE SENTI
+0x8762	0x334D	#SQUARE MEETORU
+0x8763	0x3318	#SQUARE GURAMU
+0x8764	0x3327	#SQUARE TON
+0x8765	0x3303	#SQUARE AARU
+0x8766	0x3336	#SQUARE HEKUTAARU
+0x8767	0x3351	#SQUARE RITTORU
+0x8768	0x3357	#SQUARE WATTO
+0x8769	0x330D	#SQUARE KARORII
+0x876A	0x3326	#SQUARE DORU
+0x876B	0x3323	#SQUARE SENTO
+0x876C	0x332B	#SQUARE PAASENTO
+0x876D	0x334A	#SQUARE MIRIBAARU
+0x876E	0x333B	#SQUARE PEEZI
+0x876F	0x339C	#SQUARE MM
+0x8770	0x339D	#SQUARE CM
+0x8771	0x339E	#SQUARE KM
+0x8772	0x338E	#SQUARE MG
+0x8773	0x338F	#SQUARE KG
+0x8774	0x33C4	#SQUARE CC
+0x8775	0x33A1	#SQUARE M SQUARED
+0x877E	0x337B	#SQUARE ERA NAME HEISEI
+0x8780	0x301D	#REVERSED DOUBLE PRIME QUOTATION MARK
+0x8781	0x301F	#LOW DOUBLE PRIME QUOTATION MARK
+0x8782	0x2116	#NUMERO SIGN
+0x8783	0x33CD	#SQUARE KK
+0x8784	0x2121	#TELEPHONE SIGN
+0x8785	0x32A4	#CIRCLED IDEOGRAPH HIGH
+0x8786	0x32A5	#CIRCLED IDEOGRAPH CENTRE
+0x8787	0x32A6	#CIRCLED IDEOGRAPH LOW
+0x8788	0x32A7	#CIRCLED IDEOGRAPH LEFT
+0x8789	0x32A8	#CIRCLED IDEOGRAPH RIGHT
+0x878A	0x3231	#PARENTHESIZED IDEOGRAPH STOCK
+0x878B	0x3232	#PARENTHESIZED IDEOGRAPH HAVE
+0x878C	0x3239	#PARENTHESIZED IDEOGRAPH REPRESENT
+0x878D	0x337E	#SQUARE ERA NAME MEIZI
+0x878E	0x337D	#SQUARE ERA NAME TAISYOU
+0x878F	0x337C	#SQUARE ERA NAME SYOUWA
+0x8790	0x2252	#APPROXIMATELY EQUAL TO OR THE IMAGE OF
+0x8791	0x2261	#IDENTICAL TO
+0x8792	0x222B	#INTEGRAL
+0x8793	0x222E	#CONTOUR INTEGRAL
+0x8794	0x2211	#N-ARY SUMMATION
+0x8795	0x221A	#SQUARE ROOT
+0x8796	0x22A5	#UP TACK
+0x8797	0x2220	#ANGLE
+0x8798	0x221F	#RIGHT ANGLE
+0x8799	0x22BF	#RIGHT TRIANGLE
+0x879A	0x2235	#BECAUSE
+0x879B	0x2229	#INTERSECTION
+0x879C	0x222A	#UNION
+0x889F	0x4E9C	#CJK UNIFIED IDEOGRAPH
+0x88A0	0x5516	#CJK UNIFIED IDEOGRAPH
+0x88A1	0x5A03	#CJK UNIFIED IDEOGRAPH
+0x88A2	0x963F	#CJK UNIFIED IDEOGRAPH
+0x88A3	0x54C0	#CJK UNIFIED IDEOGRAPH
+0x88A4	0x611B	#CJK UNIFIED IDEOGRAPH
+0x88A5	0x6328	#CJK UNIFIED IDEOGRAPH
+0x88A6	0x59F6	#CJK UNIFIED IDEOGRAPH
+0x88A7	0x9022	#CJK UNIFIED IDEOGRAPH
+0x88A8	0x8475	#CJK UNIFIED IDEOGRAPH
+0x88A9	0x831C	#CJK UNIFIED IDEOGRAPH
+0x88AA	0x7A50	#CJK UNIFIED IDEOGRAPH
+0x88AB	0x60AA	#CJK UNIFIED IDEOGRAPH
+0x88AC	0x63E1	#CJK UNIFIED IDEOGRAPH
+0x88AD	0x6E25	#CJK UNIFIED IDEOGRAPH
+0x88AE	0x65ED	#CJK UNIFIED IDEOGRAPH
+0x88AF	0x8466	#CJK UNIFIED IDEOGRAPH
+0x88B0	0x82A6	#CJK UNIFIED IDEOGRAPH
+0x88B1	0x9BF5	#CJK UNIFIED IDEOGRAPH
+0x88B2	0x6893	#CJK UNIFIED IDEOGRAPH
+0x88B3	0x5727	#CJK UNIFIED IDEOGRAPH
+0x88B4	0x65A1	#CJK UNIFIED IDEOGRAPH
+0x88B5	0x6271	#CJK UNIFIED IDEOGRAPH
+0x88B6	0x5B9B	#CJK UNIFIED IDEOGRAPH
+0x88B7	0x59D0	#CJK UNIFIED IDEOGRAPH
+0x88B8	0x867B	#CJK UNIFIED IDEOGRAPH
+0x88B9	0x98F4	#CJK UNIFIED IDEOGRAPH
+0x88BA	0x7D62	#CJK UNIFIED IDEOGRAPH
+0x88BB	0x7DBE	#CJK UNIFIED IDEOGRAPH
+0x88BC	0x9B8E	#CJK UNIFIED IDEOGRAPH
+0x88BD	0x6216	#CJK UNIFIED IDEOGRAPH
+0x88BE	0x7C9F	#CJK UNIFIED IDEOGRAPH
+0x88BF	0x88B7	#CJK UNIFIED IDEOGRAPH
+0x88C0	0x5B89	#CJK UNIFIED IDEOGRAPH
+0x88C1	0x5EB5	#CJK UNIFIED IDEOGRAPH
+0x88C2	0x6309	#CJK UNIFIED IDEOGRAPH
+0x88C3	0x6697	#CJK UNIFIED IDEOGRAPH
+0x88C4	0x6848	#CJK UNIFIED IDEOGRAPH
+0x88C5	0x95C7	#CJK UNIFIED IDEOGRAPH
+0x88C6	0x978D	#CJK UNIFIED IDEOGRAPH
+0x88C7	0x674F	#CJK UNIFIED IDEOGRAPH
+0x88C8	0x4EE5	#CJK UNIFIED IDEOGRAPH
+0x88C9	0x4F0A	#CJK UNIFIED IDEOGRAPH
+0x88CA	0x4F4D	#CJK UNIFIED IDEOGRAPH
+0x88CB	0x4F9D	#CJK UNIFIED IDEOGRAPH
+0x88CC	0x5049	#CJK UNIFIED IDEOGRAPH
+0x88CD	0x56F2	#CJK UNIFIED IDEOGRAPH
+0x88CE	0x5937	#CJK UNIFIED IDEOGRAPH
+0x88CF	0x59D4	#CJK UNIFIED IDEOGRAPH
+0x88D0	0x5A01	#CJK UNIFIED IDEOGRAPH
+0x88D1	0x5C09	#CJK UNIFIED IDEOGRAPH
+0x88D2	0x60DF	#CJK UNIFIED IDEOGRAPH
+0x88D3	0x610F	#CJK UNIFIED IDEOGRAPH
+0x88D4	0x6170	#CJK UNIFIED IDEOGRAPH
+0x88D5	0x6613	#CJK UNIFIED IDEOGRAPH
+0x88D6	0x6905	#CJK UNIFIED IDEOGRAPH
+0x88D7	0x70BA	#CJK UNIFIED IDEOGRAPH
+0x88D8	0x754F	#CJK UNIFIED IDEOGRAPH
+0x88D9	0x7570	#CJK UNIFIED IDEOGRAPH
+0x88DA	0x79FB	#CJK UNIFIED IDEOGRAPH
+0x88DB	0x7DAD	#CJK UNIFIED IDEOGRAPH
+0x88DC	0x7DEF	#CJK UNIFIED IDEOGRAPH
+0x88DD	0x80C3	#CJK UNIFIED IDEOGRAPH
+0x88DE	0x840E	#CJK UNIFIED IDEOGRAPH
+0x88DF	0x8863	#CJK UNIFIED IDEOGRAPH
+0x88E0	0x8B02	#CJK UNIFIED IDEOGRAPH
+0x88E1	0x9055	#CJK UNIFIED IDEOGRAPH
+0x88E2	0x907A	#CJK UNIFIED IDEOGRAPH
+0x88E3	0x533B	#CJK UNIFIED IDEOGRAPH
+0x88E4	0x4E95	#CJK UNIFIED IDEOGRAPH
+0x88E5	0x4EA5	#CJK UNIFIED IDEOGRAPH
+0x88E6	0x57DF	#CJK UNIFIED IDEOGRAPH
+0x88E7	0x80B2	#CJK UNIFIED IDEOGRAPH
+0x88E8	0x90C1	#CJK UNIFIED IDEOGRAPH
+0x88E9	0x78EF	#CJK UNIFIED IDEOGRAPH
+0x88EA	0x4E00	#CJK UNIFIED IDEOGRAPH
+0x88EB	0x58F1	#CJK UNIFIED IDEOGRAPH
+0x88EC	0x6EA2	#CJK UNIFIED IDEOGRAPH
+0x88ED	0x9038	#CJK UNIFIED IDEOGRAPH
+0x88EE	0x7A32	#CJK UNIFIED IDEOGRAPH
+0x88EF	0x8328	#CJK UNIFIED IDEOGRAPH
+0x88F0	0x828B	#CJK UNIFIED IDEOGRAPH
+0x88F1	0x9C2F	#CJK UNIFIED IDEOGRAPH
+0x88F2	0x5141	#CJK UNIFIED IDEOGRAPH
+0x88F3	0x5370	#CJK UNIFIED IDEOGRAPH
+0x88F4	0x54BD	#CJK UNIFIED IDEOGRAPH
+0x88F5	0x54E1	#CJK UNIFIED IDEOGRAPH
+0x88F6	0x56E0	#CJK UNIFIED IDEOGRAPH
+0x88F7	0x59FB	#CJK UNIFIED IDEOGRAPH
+0x88F8	0x5F15	#CJK UNIFIED IDEOGRAPH
+0x88F9	0x98F2	#CJK UNIFIED IDEOGRAPH
+0x88FA	0x6DEB	#CJK UNIFIED IDEOGRAPH
+0x88FB	0x80E4	#CJK UNIFIED IDEOGRAPH
+0x88FC	0x852D	#CJK UNIFIED IDEOGRAPH
+0x8940	0x9662	#CJK UNIFIED IDEOGRAPH
+0x8941	0x9670	#CJK UNIFIED IDEOGRAPH
+0x8942	0x96A0	#CJK UNIFIED IDEOGRAPH
+0x8943	0x97FB	#CJK UNIFIED IDEOGRAPH
+0x8944	0x540B	#CJK UNIFIED IDEOGRAPH
+0x8945	0x53F3	#CJK UNIFIED IDEOGRAPH
+0x8946	0x5B87	#CJK UNIFIED IDEOGRAPH
+0x8947	0x70CF	#CJK UNIFIED IDEOGRAPH
+0x8948	0x7FBD	#CJK UNIFIED IDEOGRAPH
+0x8949	0x8FC2	#CJK UNIFIED IDEOGRAPH
+0x894A	0x96E8	#CJK UNIFIED IDEOGRAPH
+0x894B	0x536F	#CJK UNIFIED IDEOGRAPH
+0x894C	0x9D5C	#CJK UNIFIED IDEOGRAPH
+0x894D	0x7ABA	#CJK UNIFIED IDEOGRAPH
+0x894E	0x4E11	#CJK UNIFIED IDEOGRAPH
+0x894F	0x7893	#CJK UNIFIED IDEOGRAPH
+0x8950	0x81FC	#CJK UNIFIED IDEOGRAPH
+0x8951	0x6E26	#CJK UNIFIED IDEOGRAPH
+0x8952	0x5618	#CJK UNIFIED IDEOGRAPH
+0x8953	0x5504	#CJK UNIFIED IDEOGRAPH
+0x8954	0x6B1D	#CJK UNIFIED IDEOGRAPH
+0x8955	0x851A	#CJK UNIFIED IDEOGRAPH
+0x8956	0x9C3B	#CJK UNIFIED IDEOGRAPH
+0x8957	0x59E5	#CJK UNIFIED IDEOGRAPH
+0x8958	0x53A9	#CJK UNIFIED IDEOGRAPH
+0x8959	0x6D66	#CJK UNIFIED IDEOGRAPH
+0x895A	0x74DC	#CJK UNIFIED IDEOGRAPH
+0x895B	0x958F	#CJK UNIFIED IDEOGRAPH
+0x895C	0x5642	#CJK UNIFIED IDEOGRAPH
+0x895D	0x4E91	#CJK UNIFIED IDEOGRAPH
+0x895E	0x904B	#CJK UNIFIED IDEOGRAPH
+0x895F	0x96F2	#CJK UNIFIED IDEOGRAPH
+0x8960	0x834F	#CJK UNIFIED IDEOGRAPH
+0x8961	0x990C	#CJK UNIFIED IDEOGRAPH
+0x8962	0x53E1	#CJK UNIFIED IDEOGRAPH
+0x8963	0x55B6	#CJK UNIFIED IDEOGRAPH
+0x8964	0x5B30	#CJK UNIFIED IDEOGRAPH
+0x8965	0x5F71	#CJK UNIFIED IDEOGRAPH
+0x8966	0x6620	#CJK UNIFIED IDEOGRAPH
+0x8967	0x66F3	#CJK UNIFIED IDEOGRAPH
+0x8968	0x6804	#CJK UNIFIED IDEOGRAPH
+0x8969	0x6C38	#CJK UNIFIED IDEOGRAPH
+0x896A	0x6CF3	#CJK UNIFIED IDEOGRAPH
+0x896B	0x6D29	#CJK UNIFIED IDEOGRAPH
+0x896C	0x745B	#CJK UNIFIED IDEOGRAPH
+0x896D	0x76C8	#CJK UNIFIED IDEOGRAPH
+0x896E	0x7A4E	#CJK UNIFIED IDEOGRAPH
+0x896F	0x9834	#CJK UNIFIED IDEOGRAPH
+0x8970	0x82F1	#CJK UNIFIED IDEOGRAPH
+0x8971	0x885B	#CJK UNIFIED IDEOGRAPH
+0x8972	0x8A60	#CJK UNIFIED IDEOGRAPH
+0x8973	0x92ED	#CJK UNIFIED IDEOGRAPH
+0x8974	0x6DB2	#CJK UNIFIED IDEOGRAPH
+0x8975	0x75AB	#CJK UNIFIED IDEOGRAPH
+0x8976	0x76CA	#CJK UNIFIED IDEOGRAPH
+0x8977	0x99C5	#CJK UNIFIED IDEOGRAPH
+0x8978	0x60A6	#CJK UNIFIED IDEOGRAPH
+0x8979	0x8B01	#CJK UNIFIED IDEOGRAPH
+0x897A	0x8D8A	#CJK UNIFIED IDEOGRAPH
+0x897B	0x95B2	#CJK UNIFIED IDEOGRAPH
+0x897C	0x698E	#CJK UNIFIED IDEOGRAPH
+0x897D	0x53AD	#CJK UNIFIED IDEOGRAPH
+0x897E	0x5186	#CJK UNIFIED IDEOGRAPH
+0x8980	0x5712	#CJK UNIFIED IDEOGRAPH
+0x8981	0x5830	#CJK UNIFIED IDEOGRAPH
+0x8982	0x5944	#CJK UNIFIED IDEOGRAPH
+0x8983	0x5BB4	#CJK UNIFIED IDEOGRAPH
+0x8984	0x5EF6	#CJK UNIFIED IDEOGRAPH
+0x8985	0x6028	#CJK UNIFIED IDEOGRAPH
+0x8986	0x63A9	#CJK UNIFIED IDEOGRAPH
+0x8987	0x63F4	#CJK UNIFIED IDEOGRAPH
+0x8988	0x6CBF	#CJK UNIFIED IDEOGRAPH
+0x8989	0x6F14	#CJK UNIFIED IDEOGRAPH
+0x898A	0x708E	#CJK UNIFIED IDEOGRAPH
+0x898B	0x7114	#CJK UNIFIED IDEOGRAPH
+0x898C	0x7159	#CJK UNIFIED IDEOGRAPH
+0x898D	0x71D5	#CJK UNIFIED IDEOGRAPH
+0x898E	0x733F	#CJK UNIFIED IDEOGRAPH
+0x898F	0x7E01	#CJK UNIFIED IDEOGRAPH
+0x8990	0x8276	#CJK UNIFIED IDEOGRAPH
+0x8991	0x82D1	#CJK UNIFIED IDEOGRAPH
+0x8992	0x8597	#CJK UNIFIED IDEOGRAPH
+0x8993	0x9060	#CJK UNIFIED IDEOGRAPH
+0x8994	0x925B	#CJK UNIFIED IDEOGRAPH
+0x8995	0x9D1B	#CJK UNIFIED IDEOGRAPH
+0x8996	0x5869	#CJK UNIFIED IDEOGRAPH
+0x8997	0x65BC	#CJK UNIFIED IDEOGRAPH
+0x8998	0x6C5A	#CJK UNIFIED IDEOGRAPH
+0x8999	0x7525	#CJK UNIFIED IDEOGRAPH
+0x899A	0x51F9	#CJK UNIFIED IDEOGRAPH
+0x899B	0x592E	#CJK UNIFIED IDEOGRAPH
+0x899C	0x5965	#CJK UNIFIED IDEOGRAPH
+0x899D	0x5F80	#CJK UNIFIED IDEOGRAPH
+0x899E	0x5FDC	#CJK UNIFIED IDEOGRAPH
+0x899F	0x62BC	#CJK UNIFIED IDEOGRAPH
+0x89A0	0x65FA	#CJK UNIFIED IDEOGRAPH
+0x89A1	0x6A2A	#CJK UNIFIED IDEOGRAPH
+0x89A2	0x6B27	#CJK UNIFIED IDEOGRAPH
+0x89A3	0x6BB4	#CJK UNIFIED IDEOGRAPH
+0x89A4	0x738B	#CJK UNIFIED IDEOGRAPH
+0x89A5	0x7FC1	#CJK UNIFIED IDEOGRAPH
+0x89A6	0x8956	#CJK UNIFIED IDEOGRAPH
+0x89A7	0x9D2C	#CJK UNIFIED IDEOGRAPH
+0x89A8	0x9D0E	#CJK UNIFIED IDEOGRAPH
+0x89A9	0x9EC4	#CJK UNIFIED IDEOGRAPH
+0x89AA	0x5CA1	#CJK UNIFIED IDEOGRAPH
+0x89AB	0x6C96	#CJK UNIFIED IDEOGRAPH
+0x89AC	0x837B	#CJK UNIFIED IDEOGRAPH
+0x89AD	0x5104	#CJK UNIFIED IDEOGRAPH
+0x89AE	0x5C4B	#CJK UNIFIED IDEOGRAPH
+0x89AF	0x61B6	#CJK UNIFIED IDEOGRAPH
+0x89B0	0x81C6	#CJK UNIFIED IDEOGRAPH
+0x89B1	0x6876	#CJK UNIFIED IDEOGRAPH
+0x89B2	0x7261	#CJK UNIFIED IDEOGRAPH
+0x89B3	0x4E59	#CJK UNIFIED IDEOGRAPH
+0x89B4	0x4FFA	#CJK UNIFIED IDEOGRAPH
+0x89B5	0x5378	#CJK UNIFIED IDEOGRAPH
+0x89B6	0x6069	#CJK UNIFIED IDEOGRAPH
+0x89B7	0x6E29	#CJK UNIFIED IDEOGRAPH
+0x89B8	0x7A4F	#CJK UNIFIED IDEOGRAPH
+0x89B9	0x97F3	#CJK UNIFIED IDEOGRAPH
+0x89BA	0x4E0B	#CJK UNIFIED IDEOGRAPH
+0x89BB	0x5316	#CJK UNIFIED IDEOGRAPH
+0x89BC	0x4EEE	#CJK UNIFIED IDEOGRAPH
+0x89BD	0x4F55	#CJK UNIFIED IDEOGRAPH
+0x89BE	0x4F3D	#CJK UNIFIED IDEOGRAPH
+0x89BF	0x4FA1	#CJK UNIFIED IDEOGRAPH
+0x89C0	0x4F73	#CJK UNIFIED IDEOGRAPH
+0x89C1	0x52A0	#CJK UNIFIED IDEOGRAPH
+0x89C2	0x53EF	#CJK UNIFIED IDEOGRAPH
+0x89C3	0x5609	#CJK UNIFIED IDEOGRAPH
+0x89C4	0x590F	#CJK UNIFIED IDEOGRAPH
+0x89C5	0x5AC1	#CJK UNIFIED IDEOGRAPH
+0x89C6	0x5BB6	#CJK UNIFIED IDEOGRAPH
+0x89C7	0x5BE1	#CJK UNIFIED IDEOGRAPH
+0x89C8	0x79D1	#CJK UNIFIED IDEOGRAPH
+0x89C9	0x6687	#CJK UNIFIED IDEOGRAPH
+0x89CA	0x679C	#CJK UNIFIED IDEOGRAPH
+0x89CB	0x67B6	#CJK UNIFIED IDEOGRAPH
+0x89CC	0x6B4C	#CJK UNIFIED IDEOGRAPH
+0x89CD	0x6CB3	#CJK UNIFIED IDEOGRAPH
+0x89CE	0x706B	#CJK UNIFIED IDEOGRAPH
+0x89CF	0x73C2	#CJK UNIFIED IDEOGRAPH
+0x89D0	0x798D	#CJK UNIFIED IDEOGRAPH
+0x89D1	0x79BE	#CJK UNIFIED IDEOGRAPH
+0x89D2	0x7A3C	#CJK UNIFIED IDEOGRAPH
+0x89D3	0x7B87	#CJK UNIFIED IDEOGRAPH
+0x89D4	0x82B1	#CJK UNIFIED IDEOGRAPH
+0x89D5	0x82DB	#CJK UNIFIED IDEOGRAPH
+0x89D6	0x8304	#CJK UNIFIED IDEOGRAPH
+0x89D7	0x8377	#CJK UNIFIED IDEOGRAPH
+0x89D8	0x83EF	#CJK UNIFIED IDEOGRAPH
+0x89D9	0x83D3	#CJK UNIFIED IDEOGRAPH
+0x89DA	0x8766	#CJK UNIFIED IDEOGRAPH
+0x89DB	0x8AB2	#CJK UNIFIED IDEOGRAPH
+0x89DC	0x5629	#CJK UNIFIED IDEOGRAPH
+0x89DD	0x8CA8	#CJK UNIFIED IDEOGRAPH
+0x89DE	0x8FE6	#CJK UNIFIED IDEOGRAPH
+0x89DF	0x904E	#CJK UNIFIED IDEOGRAPH
+0x89E0	0x971E	#CJK UNIFIED IDEOGRAPH
+0x89E1	0x868A	#CJK UNIFIED IDEOGRAPH
+0x89E2	0x4FC4	#CJK UNIFIED IDEOGRAPH
+0x89E3	0x5CE8	#CJK UNIFIED IDEOGRAPH
+0x89E4	0x6211	#CJK UNIFIED IDEOGRAPH
+0x89E5	0x7259	#CJK UNIFIED IDEOGRAPH
+0x89E6	0x753B	#CJK UNIFIED IDEOGRAPH
+0x89E7	0x81E5	#CJK UNIFIED IDEOGRAPH
+0x89E8	0x82BD	#CJK UNIFIED IDEOGRAPH
+0x89E9	0x86FE	#CJK UNIFIED IDEOGRAPH
+0x89EA	0x8CC0	#CJK UNIFIED IDEOGRAPH
+0x89EB	0x96C5	#CJK UNIFIED IDEOGRAPH
+0x89EC	0x9913	#CJK UNIFIED IDEOGRAPH
+0x89ED	0x99D5	#CJK UNIFIED IDEOGRAPH
+0x89EE	0x4ECB	#CJK UNIFIED IDEOGRAPH
+0x89EF	0x4F1A	#CJK UNIFIED IDEOGRAPH
+0x89F0	0x89E3	#CJK UNIFIED IDEOGRAPH
+0x89F1	0x56DE	#CJK UNIFIED IDEOGRAPH
+0x89F2	0x584A	#CJK UNIFIED IDEOGRAPH
+0x89F3	0x58CA	#CJK UNIFIED IDEOGRAPH
+0x89F4	0x5EFB	#CJK UNIFIED IDEOGRAPH
+0x89F5	0x5FEB	#CJK UNIFIED IDEOGRAPH
+0x89F6	0x602A	#CJK UNIFIED IDEOGRAPH
+0x89F7	0x6094	#CJK UNIFIED IDEOGRAPH
+0x89F8	0x6062	#CJK UNIFIED IDEOGRAPH
+0x89F9	0x61D0	#CJK UNIFIED IDEOGRAPH
+0x89FA	0x6212	#CJK UNIFIED IDEOGRAPH
+0x89FB	0x62D0	#CJK UNIFIED IDEOGRAPH
+0x89FC	0x6539	#CJK UNIFIED IDEOGRAPH
+0x8A40	0x9B41	#CJK UNIFIED IDEOGRAPH
+0x8A41	0x6666	#CJK UNIFIED IDEOGRAPH
+0x8A42	0x68B0	#CJK UNIFIED IDEOGRAPH
+0x8A43	0x6D77	#CJK UNIFIED IDEOGRAPH
+0x8A44	0x7070	#CJK UNIFIED IDEOGRAPH
+0x8A45	0x754C	#CJK UNIFIED IDEOGRAPH
+0x8A46	0x7686	#CJK UNIFIED IDEOGRAPH
+0x8A47	0x7D75	#CJK UNIFIED IDEOGRAPH
+0x8A48	0x82A5	#CJK UNIFIED IDEOGRAPH
+0x8A49	0x87F9	#CJK UNIFIED IDEOGRAPH
+0x8A4A	0x958B	#CJK UNIFIED IDEOGRAPH
+0x8A4B	0x968E	#CJK UNIFIED IDEOGRAPH
+0x8A4C	0x8C9D	#CJK UNIFIED IDEOGRAPH
+0x8A4D	0x51F1	#CJK UNIFIED IDEOGRAPH
+0x8A4E	0x52BE	#CJK UNIFIED IDEOGRAPH
+0x8A4F	0x5916	#CJK UNIFIED IDEOGRAPH
+0x8A50	0x54B3	#CJK UNIFIED IDEOGRAPH
+0x8A51	0x5BB3	#CJK UNIFIED IDEOGRAPH
+0x8A52	0x5D16	#CJK UNIFIED IDEOGRAPH
+0x8A53	0x6168	#CJK UNIFIED IDEOGRAPH
+0x8A54	0x6982	#CJK UNIFIED IDEOGRAPH
+0x8A55	0x6DAF	#CJK UNIFIED IDEOGRAPH
+0x8A56	0x788D	#CJK UNIFIED IDEOGRAPH
+0x8A57	0x84CB	#CJK UNIFIED IDEOGRAPH
+0x8A58	0x8857	#CJK UNIFIED IDEOGRAPH
+0x8A59	0x8A72	#CJK UNIFIED IDEOGRAPH
+0x8A5A	0x93A7	#CJK UNIFIED IDEOGRAPH
+0x8A5B	0x9AB8	#CJK UNIFIED IDEOGRAPH
+0x8A5C	0x6D6C	#CJK UNIFIED IDEOGRAPH
+0x8A5D	0x99A8	#CJK UNIFIED IDEOGRAPH
+0x8A5E	0x86D9	#CJK UNIFIED IDEOGRAPH
+0x8A5F	0x57A3	#CJK UNIFIED IDEOGRAPH
+0x8A60	0x67FF	#CJK UNIFIED IDEOGRAPH
+0x8A61	0x86CE	#CJK UNIFIED IDEOGRAPH
+0x8A62	0x920E	#CJK UNIFIED IDEOGRAPH
+0x8A63	0x5283	#CJK UNIFIED IDEOGRAPH
+0x8A64	0x5687	#CJK UNIFIED IDEOGRAPH
+0x8A65	0x5404	#CJK UNIFIED IDEOGRAPH
+0x8A66	0x5ED3	#CJK UNIFIED IDEOGRAPH
+0x8A67	0x62E1	#CJK UNIFIED IDEOGRAPH
+0x8A68	0x64B9	#CJK UNIFIED IDEOGRAPH
+0x8A69	0x683C	#CJK UNIFIED IDEOGRAPH
+0x8A6A	0x6838	#CJK UNIFIED IDEOGRAPH
+0x8A6B	0x6BBB	#CJK UNIFIED IDEOGRAPH
+0x8A6C	0x7372	#CJK UNIFIED IDEOGRAPH
+0x8A6D	0x78BA	#CJK UNIFIED IDEOGRAPH
+0x8A6E	0x7A6B	#CJK UNIFIED IDEOGRAPH
+0x8A6F	0x899A	#CJK UNIFIED IDEOGRAPH
+0x8A70	0x89D2	#CJK UNIFIED IDEOGRAPH
+0x8A71	0x8D6B	#CJK UNIFIED IDEOGRAPH
+0x8A72	0x8F03	#CJK UNIFIED IDEOGRAPH
+0x8A73	0x90ED	#CJK UNIFIED IDEOGRAPH
+0x8A74	0x95A3	#CJK UNIFIED IDEOGRAPH
+0x8A75	0x9694	#CJK UNIFIED IDEOGRAPH
+0x8A76	0x9769	#CJK UNIFIED IDEOGRAPH
+0x8A77	0x5B66	#CJK UNIFIED IDEOGRAPH
+0x8A78	0x5CB3	#CJK UNIFIED IDEOGRAPH
+0x8A79	0x697D	#CJK UNIFIED IDEOGRAPH
+0x8A7A	0x984D	#CJK UNIFIED IDEOGRAPH
+0x8A7B	0x984E	#CJK UNIFIED IDEOGRAPH
+0x8A7C	0x639B	#CJK UNIFIED IDEOGRAPH
+0x8A7D	0x7B20	#CJK UNIFIED IDEOGRAPH
+0x8A7E	0x6A2B	#CJK UNIFIED IDEOGRAPH
+0x8A80	0x6A7F	#CJK UNIFIED IDEOGRAPH
+0x8A81	0x68B6	#CJK UNIFIED IDEOGRAPH
+0x8A82	0x9C0D	#CJK UNIFIED IDEOGRAPH
+0x8A83	0x6F5F	#CJK UNIFIED IDEOGRAPH
+0x8A84	0x5272	#CJK UNIFIED IDEOGRAPH
+0x8A85	0x559D	#CJK UNIFIED IDEOGRAPH
+0x8A86	0x6070	#CJK UNIFIED IDEOGRAPH
+0x8A87	0x62EC	#CJK UNIFIED IDEOGRAPH
+0x8A88	0x6D3B	#CJK UNIFIED IDEOGRAPH
+0x8A89	0x6E07	#CJK UNIFIED IDEOGRAPH
+0x8A8A	0x6ED1	#CJK UNIFIED IDEOGRAPH
+0x8A8B	0x845B	#CJK UNIFIED IDEOGRAPH
+0x8A8C	0x8910	#CJK UNIFIED IDEOGRAPH
+0x8A8D	0x8F44	#CJK UNIFIED IDEOGRAPH
+0x8A8E	0x4E14	#CJK UNIFIED IDEOGRAPH
+0x8A8F	0x9C39	#CJK UNIFIED IDEOGRAPH
+0x8A90	0x53F6	#CJK UNIFIED IDEOGRAPH
+0x8A91	0x691B	#CJK UNIFIED IDEOGRAPH
+0x8A92	0x6A3A	#CJK UNIFIED IDEOGRAPH
+0x8A93	0x9784	#CJK UNIFIED IDEOGRAPH
+0x8A94	0x682A	#CJK UNIFIED IDEOGRAPH
+0x8A95	0x515C	#CJK UNIFIED IDEOGRAPH
+0x8A96	0x7AC3	#CJK UNIFIED IDEOGRAPH
+0x8A97	0x84B2	#CJK UNIFIED IDEOGRAPH
+0x8A98	0x91DC	#CJK UNIFIED IDEOGRAPH
+0x8A99	0x938C	#CJK UNIFIED IDEOGRAPH
+0x8A9A	0x565B	#CJK UNIFIED IDEOGRAPH
+0x8A9B	0x9D28	#CJK UNIFIED IDEOGRAPH
+0x8A9C	0x6822	#CJK UNIFIED IDEOGRAPH
+0x8A9D	0x8305	#CJK UNIFIED IDEOGRAPH
+0x8A9E	0x8431	#CJK UNIFIED IDEOGRAPH
+0x8A9F	0x7CA5	#CJK UNIFIED IDEOGRAPH
+0x8AA0	0x5208	#CJK UNIFIED IDEOGRAPH
+0x8AA1	0x82C5	#CJK UNIFIED IDEOGRAPH
+0x8AA2	0x74E6	#CJK UNIFIED IDEOGRAPH
+0x8AA3	0x4E7E	#CJK UNIFIED IDEOGRAPH
+0x8AA4	0x4F83	#CJK UNIFIED IDEOGRAPH
+0x8AA5	0x51A0	#CJK UNIFIED IDEOGRAPH
+0x8AA6	0x5BD2	#CJK UNIFIED IDEOGRAPH
+0x8AA7	0x520A	#CJK UNIFIED IDEOGRAPH
+0x8AA8	0x52D8	#CJK UNIFIED IDEOGRAPH
+0x8AA9	0x52E7	#CJK UNIFIED IDEOGRAPH
+0x8AAA	0x5DFB	#CJK UNIFIED IDEOGRAPH
+0x8AAB	0x559A	#CJK UNIFIED IDEOGRAPH
+0x8AAC	0x582A	#CJK UNIFIED IDEOGRAPH
+0x8AAD	0x59E6	#CJK UNIFIED IDEOGRAPH
+0x8AAE	0x5B8C	#CJK UNIFIED IDEOGRAPH
+0x8AAF	0x5B98	#CJK UNIFIED IDEOGRAPH
+0x8AB0	0x5BDB	#CJK UNIFIED IDEOGRAPH
+0x8AB1	0x5E72	#CJK UNIFIED IDEOGRAPH
+0x8AB2	0x5E79	#CJK UNIFIED IDEOGRAPH
+0x8AB3	0x60A3	#CJK UNIFIED IDEOGRAPH
+0x8AB4	0x611F	#CJK UNIFIED IDEOGRAPH
+0x8AB5	0x6163	#CJK UNIFIED IDEOGRAPH
+0x8AB6	0x61BE	#CJK UNIFIED IDEOGRAPH
+0x8AB7	0x63DB	#CJK UNIFIED IDEOGRAPH
+0x8AB8	0x6562	#CJK UNIFIED IDEOGRAPH
+0x8AB9	0x67D1	#CJK UNIFIED IDEOGRAPH
+0x8ABA	0x6853	#CJK UNIFIED IDEOGRAPH
+0x8ABB	0x68FA	#CJK UNIFIED IDEOGRAPH
+0x8ABC	0x6B3E	#CJK UNIFIED IDEOGRAPH
+0x8ABD	0x6B53	#CJK UNIFIED IDEOGRAPH
+0x8ABE	0x6C57	#CJK UNIFIED IDEOGRAPH
+0x8ABF	0x6F22	#CJK UNIFIED IDEOGRAPH
+0x8AC0	0x6F97	#CJK UNIFIED IDEOGRAPH
+0x8AC1	0x6F45	#CJK UNIFIED IDEOGRAPH
+0x8AC2	0x74B0	#CJK UNIFIED IDEOGRAPH
+0x8AC3	0x7518	#CJK UNIFIED IDEOGRAPH
+0x8AC4	0x76E3	#CJK UNIFIED IDEOGRAPH
+0x8AC5	0x770B	#CJK UNIFIED IDEOGRAPH
+0x8AC6	0x7AFF	#CJK UNIFIED IDEOGRAPH
+0x8AC7	0x7BA1	#CJK UNIFIED IDEOGRAPH
+0x8AC8	0x7C21	#CJK UNIFIED IDEOGRAPH
+0x8AC9	0x7DE9	#CJK UNIFIED IDEOGRAPH
+0x8ACA	0x7F36	#CJK UNIFIED IDEOGRAPH
+0x8ACB	0x7FF0	#CJK UNIFIED IDEOGRAPH
+0x8ACC	0x809D	#CJK UNIFIED IDEOGRAPH
+0x8ACD	0x8266	#CJK UNIFIED IDEOGRAPH
+0x8ACE	0x839E	#CJK UNIFIED IDEOGRAPH
+0x8ACF	0x89B3	#CJK UNIFIED IDEOGRAPH
+0x8AD0	0x8ACC	#CJK UNIFIED IDEOGRAPH
+0x8AD1	0x8CAB	#CJK UNIFIED IDEOGRAPH
+0x8AD2	0x9084	#CJK UNIFIED IDEOGRAPH
+0x8AD3	0x9451	#CJK UNIFIED IDEOGRAPH
+0x8AD4	0x9593	#CJK UNIFIED IDEOGRAPH
+0x8AD5	0x9591	#CJK UNIFIED IDEOGRAPH
+0x8AD6	0x95A2	#CJK UNIFIED IDEOGRAPH
+0x8AD7	0x9665	#CJK UNIFIED IDEOGRAPH
+0x8AD8	0x97D3	#CJK UNIFIED IDEOGRAPH
+0x8AD9	0x9928	#CJK UNIFIED IDEOGRAPH
+0x8ADA	0x8218	#CJK UNIFIED IDEOGRAPH
+0x8ADB	0x4E38	#CJK UNIFIED IDEOGRAPH
+0x8ADC	0x542B	#CJK UNIFIED IDEOGRAPH
+0x8ADD	0x5CB8	#CJK UNIFIED IDEOGRAPH
+0x8ADE	0x5DCC	#CJK UNIFIED IDEOGRAPH
+0x8ADF	0x73A9	#CJK UNIFIED IDEOGRAPH
+0x8AE0	0x764C	#CJK UNIFIED IDEOGRAPH
+0x8AE1	0x773C	#CJK UNIFIED IDEOGRAPH
+0x8AE2	0x5CA9	#CJK UNIFIED IDEOGRAPH
+0x8AE3	0x7FEB	#CJK UNIFIED IDEOGRAPH
+0x8AE4	0x8D0B	#CJK UNIFIED IDEOGRAPH
+0x8AE5	0x96C1	#CJK UNIFIED IDEOGRAPH
+0x8AE6	0x9811	#CJK UNIFIED IDEOGRAPH
+0x8AE7	0x9854	#CJK UNIFIED IDEOGRAPH
+0x8AE8	0x9858	#CJK UNIFIED IDEOGRAPH
+0x8AE9	0x4F01	#CJK UNIFIED IDEOGRAPH
+0x8AEA	0x4F0E	#CJK UNIFIED IDEOGRAPH
+0x8AEB	0x5371	#CJK UNIFIED IDEOGRAPH
+0x8AEC	0x559C	#CJK UNIFIED IDEOGRAPH
+0x8AED	0x5668	#CJK UNIFIED IDEOGRAPH
+0x8AEE	0x57FA	#CJK UNIFIED IDEOGRAPH
+0x8AEF	0x5947	#CJK UNIFIED IDEOGRAPH
+0x8AF0	0x5B09	#CJK UNIFIED IDEOGRAPH
+0x8AF1	0x5BC4	#CJK UNIFIED IDEOGRAPH
+0x8AF2	0x5C90	#CJK UNIFIED IDEOGRAPH
+0x8AF3	0x5E0C	#CJK UNIFIED IDEOGRAPH
+0x8AF4	0x5E7E	#CJK UNIFIED IDEOGRAPH
+0x8AF5	0x5FCC	#CJK UNIFIED IDEOGRAPH
+0x8AF6	0x63EE	#CJK UNIFIED IDEOGRAPH
+0x8AF7	0x673A	#CJK UNIFIED IDEOGRAPH
+0x8AF8	0x65D7	#CJK UNIFIED IDEOGRAPH
+0x8AF9	0x65E2	#CJK UNIFIED IDEOGRAPH
+0x8AFA	0x671F	#CJK UNIFIED IDEOGRAPH
+0x8AFB	0x68CB	#CJK UNIFIED IDEOGRAPH
+0x8AFC	0x68C4	#CJK UNIFIED IDEOGRAPH
+0x8B40	0x6A5F	#CJK UNIFIED IDEOGRAPH
+0x8B41	0x5E30	#CJK UNIFIED IDEOGRAPH
+0x8B42	0x6BC5	#CJK UNIFIED IDEOGRAPH
+0x8B43	0x6C17	#CJK UNIFIED IDEOGRAPH
+0x8B44	0x6C7D	#CJK UNIFIED IDEOGRAPH
+0x8B45	0x757F	#CJK UNIFIED IDEOGRAPH
+0x8B46	0x7948	#CJK UNIFIED IDEOGRAPH
+0x8B47	0x5B63	#CJK UNIFIED IDEOGRAPH
+0x8B48	0x7A00	#CJK UNIFIED IDEOGRAPH
+0x8B49	0x7D00	#CJK UNIFIED IDEOGRAPH
+0x8B4A	0x5FBD	#CJK UNIFIED IDEOGRAPH
+0x8B4B	0x898F	#CJK UNIFIED IDEOGRAPH
+0x8B4C	0x8A18	#CJK UNIFIED IDEOGRAPH
+0x8B4D	0x8CB4	#CJK UNIFIED IDEOGRAPH
+0x8B4E	0x8D77	#CJK UNIFIED IDEOGRAPH
+0x8B4F	0x8ECC	#CJK UNIFIED IDEOGRAPH
+0x8B50	0x8F1D	#CJK UNIFIED IDEOGRAPH
+0x8B51	0x98E2	#CJK UNIFIED IDEOGRAPH
+0x8B52	0x9A0E	#CJK UNIFIED IDEOGRAPH
+0x8B53	0x9B3C	#CJK UNIFIED IDEOGRAPH
+0x8B54	0x4E80	#CJK UNIFIED IDEOGRAPH
+0x8B55	0x507D	#CJK UNIFIED IDEOGRAPH
+0x8B56	0x5100	#CJK UNIFIED IDEOGRAPH
+0x8B57	0x5993	#CJK UNIFIED IDEOGRAPH
+0x8B58	0x5B9C	#CJK UNIFIED IDEOGRAPH
+0x8B59	0x622F	#CJK UNIFIED IDEOGRAPH
+0x8B5A	0x6280	#CJK UNIFIED IDEOGRAPH
+0x8B5B	0x64EC	#CJK UNIFIED IDEOGRAPH
+0x8B5C	0x6B3A	#CJK UNIFIED IDEOGRAPH
+0x8B5D	0x72A0	#CJK UNIFIED IDEOGRAPH
+0x8B5E	0x7591	#CJK UNIFIED IDEOGRAPH
+0x8B5F	0x7947	#CJK UNIFIED IDEOGRAPH
+0x8B60	0x7FA9	#CJK UNIFIED IDEOGRAPH
+0x8B61	0x87FB	#CJK UNIFIED IDEOGRAPH
+0x8B62	0x8ABC	#CJK UNIFIED IDEOGRAPH
+0x8B63	0x8B70	#CJK UNIFIED IDEOGRAPH
+0x8B64	0x63AC	#CJK UNIFIED IDEOGRAPH
+0x8B65	0x83CA	#CJK UNIFIED IDEOGRAPH
+0x8B66	0x97A0	#CJK UNIFIED IDEOGRAPH
+0x8B67	0x5409	#CJK UNIFIED IDEOGRAPH
+0x8B68	0x5403	#CJK UNIFIED IDEOGRAPH
+0x8B69	0x55AB	#CJK UNIFIED IDEOGRAPH
+0x8B6A	0x6854	#CJK UNIFIED IDEOGRAPH
+0x8B6B	0x6A58	#CJK UNIFIED IDEOGRAPH
+0x8B6C	0x8A70	#CJK UNIFIED IDEOGRAPH
+0x8B6D	0x7827	#CJK UNIFIED IDEOGRAPH
+0x8B6E	0x6775	#CJK UNIFIED IDEOGRAPH
+0x8B6F	0x9ECD	#CJK UNIFIED IDEOGRAPH
+0x8B70	0x5374	#CJK UNIFIED IDEOGRAPH
+0x8B71	0x5BA2	#CJK UNIFIED IDEOGRAPH
+0x8B72	0x811A	#CJK UNIFIED IDEOGRAPH
+0x8B73	0x8650	#CJK UNIFIED IDEOGRAPH
+0x8B74	0x9006	#CJK UNIFIED IDEOGRAPH
+0x8B75	0x4E18	#CJK UNIFIED IDEOGRAPH
+0x8B76	0x4E45	#CJK UNIFIED IDEOGRAPH
+0x8B77	0x4EC7	#CJK UNIFIED IDEOGRAPH
+0x8B78	0x4F11	#CJK UNIFIED IDEOGRAPH
+0x8B79	0x53CA	#CJK UNIFIED IDEOGRAPH
+0x8B7A	0x5438	#CJK UNIFIED IDEOGRAPH
+0x8B7B	0x5BAE	#CJK UNIFIED IDEOGRAPH
+0x8B7C	0x5F13	#CJK UNIFIED IDEOGRAPH
+0x8B7D	0x6025	#CJK UNIFIED IDEOGRAPH
+0x8B7E	0x6551	#CJK UNIFIED IDEOGRAPH
+0x8B80	0x673D	#CJK UNIFIED IDEOGRAPH
+0x8B81	0x6C42	#CJK UNIFIED IDEOGRAPH
+0x8B82	0x6C72	#CJK UNIFIED IDEOGRAPH
+0x8B83	0x6CE3	#CJK UNIFIED IDEOGRAPH
+0x8B84	0x7078	#CJK UNIFIED IDEOGRAPH
+0x8B85	0x7403	#CJK UNIFIED IDEOGRAPH
+0x8B86	0x7A76	#CJK UNIFIED IDEOGRAPH
+0x8B87	0x7AAE	#CJK UNIFIED IDEOGRAPH
+0x8B88	0x7B08	#CJK UNIFIED IDEOGRAPH
+0x8B89	0x7D1A	#CJK UNIFIED IDEOGRAPH
+0x8B8A	0x7CFE	#CJK UNIFIED IDEOGRAPH
+0x8B8B	0x7D66	#CJK UNIFIED IDEOGRAPH
+0x8B8C	0x65E7	#CJK UNIFIED IDEOGRAPH
+0x8B8D	0x725B	#CJK UNIFIED IDEOGRAPH
+0x8B8E	0x53BB	#CJK UNIFIED IDEOGRAPH
+0x8B8F	0x5C45	#CJK UNIFIED IDEOGRAPH
+0x8B90	0x5DE8	#CJK UNIFIED IDEOGRAPH
+0x8B91	0x62D2	#CJK UNIFIED IDEOGRAPH
+0x8B92	0x62E0	#CJK UNIFIED IDEOGRAPH
+0x8B93	0x6319	#CJK UNIFIED IDEOGRAPH
+0x8B94	0x6E20	#CJK UNIFIED IDEOGRAPH
+0x8B95	0x865A	#CJK UNIFIED IDEOGRAPH
+0x8B96	0x8A31	#CJK UNIFIED IDEOGRAPH
+0x8B97	0x8DDD	#CJK UNIFIED IDEOGRAPH
+0x8B98	0x92F8	#CJK UNIFIED IDEOGRAPH
+0x8B99	0x6F01	#CJK UNIFIED IDEOGRAPH
+0x8B9A	0x79A6	#CJK UNIFIED IDEOGRAPH
+0x8B9B	0x9B5A	#CJK UNIFIED IDEOGRAPH
+0x8B9C	0x4EA8	#CJK UNIFIED IDEOGRAPH
+0x8B9D	0x4EAB	#CJK UNIFIED IDEOGRAPH
+0x8B9E	0x4EAC	#CJK UNIFIED IDEOGRAPH
+0x8B9F	0x4F9B	#CJK UNIFIED IDEOGRAPH
+0x8BA0	0x4FA0	#CJK UNIFIED IDEOGRAPH
+0x8BA1	0x50D1	#CJK UNIFIED IDEOGRAPH
+0x8BA2	0x5147	#CJK UNIFIED IDEOGRAPH
+0x8BA3	0x7AF6	#CJK UNIFIED IDEOGRAPH
+0x8BA4	0x5171	#CJK UNIFIED IDEOGRAPH
+0x8BA5	0x51F6	#CJK UNIFIED IDEOGRAPH
+0x8BA6	0x5354	#CJK UNIFIED IDEOGRAPH
+0x8BA7	0x5321	#CJK UNIFIED IDEOGRAPH
+0x8BA8	0x537F	#CJK UNIFIED IDEOGRAPH
+0x8BA9	0x53EB	#CJK UNIFIED IDEOGRAPH
+0x8BAA	0x55AC	#CJK UNIFIED IDEOGRAPH
+0x8BAB	0x5883	#CJK UNIFIED IDEOGRAPH
+0x8BAC	0x5CE1	#CJK UNIFIED IDEOGRAPH
+0x8BAD	0x5F37	#CJK UNIFIED IDEOGRAPH
+0x8BAE	0x5F4A	#CJK UNIFIED IDEOGRAPH
+0x8BAF	0x602F	#CJK UNIFIED IDEOGRAPH
+0x8BB0	0x6050	#CJK UNIFIED IDEOGRAPH
+0x8BB1	0x606D	#CJK UNIFIED IDEOGRAPH
+0x8BB2	0x631F	#CJK UNIFIED IDEOGRAPH
+0x8BB3	0x6559	#CJK UNIFIED IDEOGRAPH
+0x8BB4	0x6A4B	#CJK UNIFIED IDEOGRAPH
+0x8BB5	0x6CC1	#CJK UNIFIED IDEOGRAPH
+0x8BB6	0x72C2	#CJK UNIFIED IDEOGRAPH
+0x8BB7	0x72ED	#CJK UNIFIED IDEOGRAPH
+0x8BB8	0x77EF	#CJK UNIFIED IDEOGRAPH
+0x8BB9	0x80F8	#CJK UNIFIED IDEOGRAPH
+0x8BBA	0x8105	#CJK UNIFIED IDEOGRAPH
+0x8BBB	0x8208	#CJK UNIFIED IDEOGRAPH
+0x8BBC	0x854E	#CJK UNIFIED IDEOGRAPH
+0x8BBD	0x90F7	#CJK UNIFIED IDEOGRAPH
+0x8BBE	0x93E1	#CJK UNIFIED IDEOGRAPH
+0x8BBF	0x97FF	#CJK UNIFIED IDEOGRAPH
+0x8BC0	0x9957	#CJK UNIFIED IDEOGRAPH
+0x8BC1	0x9A5A	#CJK UNIFIED IDEOGRAPH
+0x8BC2	0x4EF0	#CJK UNIFIED IDEOGRAPH
+0x8BC3	0x51DD	#CJK UNIFIED IDEOGRAPH
+0x8BC4	0x5C2D	#CJK UNIFIED IDEOGRAPH
+0x8BC5	0x6681	#CJK UNIFIED IDEOGRAPH
+0x8BC6	0x696D	#CJK UNIFIED IDEOGRAPH
+0x8BC7	0x5C40	#CJK UNIFIED IDEOGRAPH
+0x8BC8	0x66F2	#CJK UNIFIED IDEOGRAPH
+0x8BC9	0x6975	#CJK UNIFIED IDEOGRAPH
+0x8BCA	0x7389	#CJK UNIFIED IDEOGRAPH
+0x8BCB	0x6850	#CJK UNIFIED IDEOGRAPH
+0x8BCC	0x7C81	#CJK UNIFIED IDEOGRAPH
+0x8BCD	0x50C5	#CJK UNIFIED IDEOGRAPH
+0x8BCE	0x52E4	#CJK UNIFIED IDEOGRAPH
+0x8BCF	0x5747	#CJK UNIFIED IDEOGRAPH
+0x8BD0	0x5DFE	#CJK UNIFIED IDEOGRAPH
+0x8BD1	0x9326	#CJK UNIFIED IDEOGRAPH
+0x8BD2	0x65A4	#CJK UNIFIED IDEOGRAPH
+0x8BD3	0x6B23	#CJK UNIFIED IDEOGRAPH
+0x8BD4	0x6B3D	#CJK UNIFIED IDEOGRAPH
+0x8BD5	0x7434	#CJK UNIFIED IDEOGRAPH
+0x8BD6	0x7981	#CJK UNIFIED IDEOGRAPH
+0x8BD7	0x79BD	#CJK UNIFIED IDEOGRAPH
+0x8BD8	0x7B4B	#CJK UNIFIED IDEOGRAPH
+0x8BD9	0x7DCA	#CJK UNIFIED IDEOGRAPH
+0x8BDA	0x82B9	#CJK UNIFIED IDEOGRAPH
+0x8BDB	0x83CC	#CJK UNIFIED IDEOGRAPH
+0x8BDC	0x887F	#CJK UNIFIED IDEOGRAPH
+0x8BDD	0x895F	#CJK UNIFIED IDEOGRAPH
+0x8BDE	0x8B39	#CJK UNIFIED IDEOGRAPH
+0x8BDF	0x8FD1	#CJK UNIFIED IDEOGRAPH
+0x8BE0	0x91D1	#CJK UNIFIED IDEOGRAPH
+0x8BE1	0x541F	#CJK UNIFIED IDEOGRAPH
+0x8BE2	0x9280	#CJK UNIFIED IDEOGRAPH
+0x8BE3	0x4E5D	#CJK UNIFIED IDEOGRAPH
+0x8BE4	0x5036	#CJK UNIFIED IDEOGRAPH
+0x8BE5	0x53E5	#CJK UNIFIED IDEOGRAPH
+0x8BE6	0x533A	#CJK UNIFIED IDEOGRAPH
+0x8BE7	0x72D7	#CJK UNIFIED IDEOGRAPH
+0x8BE8	0x7396	#CJK UNIFIED IDEOGRAPH
+0x8BE9	0x77E9	#CJK UNIFIED IDEOGRAPH
+0x8BEA	0x82E6	#CJK UNIFIED IDEOGRAPH
+0x8BEB	0x8EAF	#CJK UNIFIED IDEOGRAPH
+0x8BEC	0x99C6	#CJK UNIFIED IDEOGRAPH
+0x8BED	0x99C8	#CJK UNIFIED IDEOGRAPH
+0x8BEE	0x99D2	#CJK UNIFIED IDEOGRAPH
+0x8BEF	0x5177	#CJK UNIFIED IDEOGRAPH
+0x8BF0	0x611A	#CJK UNIFIED IDEOGRAPH
+0x8BF1	0x865E	#CJK UNIFIED IDEOGRAPH
+0x8BF2	0x55B0	#CJK UNIFIED IDEOGRAPH
+0x8BF3	0x7A7A	#CJK UNIFIED IDEOGRAPH
+0x8BF4	0x5076	#CJK UNIFIED IDEOGRAPH
+0x8BF5	0x5BD3	#CJK UNIFIED IDEOGRAPH
+0x8BF6	0x9047	#CJK UNIFIED IDEOGRAPH
+0x8BF7	0x9685	#CJK UNIFIED IDEOGRAPH
+0x8BF8	0x4E32	#CJK UNIFIED IDEOGRAPH
+0x8BF9	0x6ADB	#CJK UNIFIED IDEOGRAPH
+0x8BFA	0x91E7	#CJK UNIFIED IDEOGRAPH
+0x8BFB	0x5C51	#CJK UNIFIED IDEOGRAPH
+0x8BFC	0x5C48	#CJK UNIFIED IDEOGRAPH
+0x8C40	0x6398	#CJK UNIFIED IDEOGRAPH
+0x8C41	0x7A9F	#CJK UNIFIED IDEOGRAPH
+0x8C42	0x6C93	#CJK UNIFIED IDEOGRAPH
+0x8C43	0x9774	#CJK UNIFIED IDEOGRAPH
+0x8C44	0x8F61	#CJK UNIFIED IDEOGRAPH
+0x8C45	0x7AAA	#CJK UNIFIED IDEOGRAPH
+0x8C46	0x718A	#CJK UNIFIED IDEOGRAPH
+0x8C47	0x9688	#CJK UNIFIED IDEOGRAPH
+0x8C48	0x7C82	#CJK UNIFIED IDEOGRAPH
+0x8C49	0x6817	#CJK UNIFIED IDEOGRAPH
+0x8C4A	0x7E70	#CJK UNIFIED IDEOGRAPH
+0x8C4B	0x6851	#CJK UNIFIED IDEOGRAPH
+0x8C4C	0x936C	#CJK UNIFIED IDEOGRAPH
+0x8C4D	0x52F2	#CJK UNIFIED IDEOGRAPH
+0x8C4E	0x541B	#CJK UNIFIED IDEOGRAPH
+0x8C4F	0x85AB	#CJK UNIFIED IDEOGRAPH
+0x8C50	0x8A13	#CJK UNIFIED IDEOGRAPH
+0x8C51	0x7FA4	#CJK UNIFIED IDEOGRAPH
+0x8C52	0x8ECD	#CJK UNIFIED IDEOGRAPH
+0x8C53	0x90E1	#CJK UNIFIED IDEOGRAPH
+0x8C54	0x5366	#CJK UNIFIED IDEOGRAPH
+0x8C55	0x8888	#CJK UNIFIED IDEOGRAPH
+0x8C56	0x7941	#CJK UNIFIED IDEOGRAPH
+0x8C57	0x4FC2	#CJK UNIFIED IDEOGRAPH
+0x8C58	0x50BE	#CJK UNIFIED IDEOGRAPH
+0x8C59	0x5211	#CJK UNIFIED IDEOGRAPH
+0x8C5A	0x5144	#CJK UNIFIED IDEOGRAPH
+0x8C5B	0x5553	#CJK UNIFIED IDEOGRAPH
+0x8C5C	0x572D	#CJK UNIFIED IDEOGRAPH
+0x8C5D	0x73EA	#CJK UNIFIED IDEOGRAPH
+0x8C5E	0x578B	#CJK UNIFIED IDEOGRAPH
+0x8C5F	0x5951	#CJK UNIFIED IDEOGRAPH
+0x8C60	0x5F62	#CJK UNIFIED IDEOGRAPH
+0x8C61	0x5F84	#CJK UNIFIED IDEOGRAPH
+0x8C62	0x6075	#CJK UNIFIED IDEOGRAPH
+0x8C63	0x6176	#CJK UNIFIED IDEOGRAPH
+0x8C64	0x6167	#CJK UNIFIED IDEOGRAPH
+0x8C65	0x61A9	#CJK UNIFIED IDEOGRAPH
+0x8C66	0x63B2	#CJK UNIFIED IDEOGRAPH
+0x8C67	0x643A	#CJK UNIFIED IDEOGRAPH
+0x8C68	0x656C	#CJK UNIFIED IDEOGRAPH
+0x8C69	0x666F	#CJK UNIFIED IDEOGRAPH
+0x8C6A	0x6842	#CJK UNIFIED IDEOGRAPH
+0x8C6B	0x6E13	#CJK UNIFIED IDEOGRAPH
+0x8C6C	0x7566	#CJK UNIFIED IDEOGRAPH
+0x8C6D	0x7A3D	#CJK UNIFIED IDEOGRAPH
+0x8C6E	0x7CFB	#CJK UNIFIED IDEOGRAPH
+0x8C6F	0x7D4C	#CJK UNIFIED IDEOGRAPH
+0x8C70	0x7D99	#CJK UNIFIED IDEOGRAPH
+0x8C71	0x7E4B	#CJK UNIFIED IDEOGRAPH
+0x8C72	0x7F6B	#CJK UNIFIED IDEOGRAPH
+0x8C73	0x830E	#CJK UNIFIED IDEOGRAPH
+0x8C74	0x834A	#CJK UNIFIED IDEOGRAPH
+0x8C75	0x86CD	#CJK UNIFIED IDEOGRAPH
+0x8C76	0x8A08	#CJK UNIFIED IDEOGRAPH
+0x8C77	0x8A63	#CJK UNIFIED IDEOGRAPH
+0x8C78	0x8B66	#CJK UNIFIED IDEOGRAPH
+0x8C79	0x8EFD	#CJK UNIFIED IDEOGRAPH
+0x8C7A	0x981A	#CJK UNIFIED IDEOGRAPH
+0x8C7B	0x9D8F	#CJK UNIFIED IDEOGRAPH
+0x8C7C	0x82B8	#CJK UNIFIED IDEOGRAPH
+0x8C7D	0x8FCE	#CJK UNIFIED IDEOGRAPH
+0x8C7E	0x9BE8	#CJK UNIFIED IDEOGRAPH
+0x8C80	0x5287	#CJK UNIFIED IDEOGRAPH
+0x8C81	0x621F	#CJK UNIFIED IDEOGRAPH
+0x8C82	0x6483	#CJK UNIFIED IDEOGRAPH
+0x8C83	0x6FC0	#CJK UNIFIED IDEOGRAPH
+0x8C84	0x9699	#CJK UNIFIED IDEOGRAPH
+0x8C85	0x6841	#CJK UNIFIED IDEOGRAPH
+0x8C86	0x5091	#CJK UNIFIED IDEOGRAPH
+0x8C87	0x6B20	#CJK UNIFIED IDEOGRAPH
+0x8C88	0x6C7A	#CJK UNIFIED IDEOGRAPH
+0x8C89	0x6F54	#CJK UNIFIED IDEOGRAPH
+0x8C8A	0x7A74	#CJK UNIFIED IDEOGRAPH
+0x8C8B	0x7D50	#CJK UNIFIED IDEOGRAPH
+0x8C8C	0x8840	#CJK UNIFIED IDEOGRAPH
+0x8C8D	0x8A23	#CJK UNIFIED IDEOGRAPH
+0x8C8E	0x6708	#CJK UNIFIED IDEOGRAPH
+0x8C8F	0x4EF6	#CJK UNIFIED IDEOGRAPH
+0x8C90	0x5039	#CJK UNIFIED IDEOGRAPH
+0x8C91	0x5026	#CJK UNIFIED IDEOGRAPH
+0x8C92	0x5065	#CJK UNIFIED IDEOGRAPH
+0x8C93	0x517C	#CJK UNIFIED IDEOGRAPH
+0x8C94	0x5238	#CJK UNIFIED IDEOGRAPH
+0x8C95	0x5263	#CJK UNIFIED IDEOGRAPH
+0x8C96	0x55A7	#CJK UNIFIED IDEOGRAPH
+0x8C97	0x570F	#CJK UNIFIED IDEOGRAPH
+0x8C98	0x5805	#CJK UNIFIED IDEOGRAPH
+0x8C99	0x5ACC	#CJK UNIFIED IDEOGRAPH
+0x8C9A	0x5EFA	#CJK UNIFIED IDEOGRAPH
+0x8C9B	0x61B2	#CJK UNIFIED IDEOGRAPH
+0x8C9C	0x61F8	#CJK UNIFIED IDEOGRAPH
+0x8C9D	0x62F3	#CJK UNIFIED IDEOGRAPH
+0x8C9E	0x6372	#CJK UNIFIED IDEOGRAPH
+0x8C9F	0x691C	#CJK UNIFIED IDEOGRAPH
+0x8CA0	0x6A29	#CJK UNIFIED IDEOGRAPH
+0x8CA1	0x727D	#CJK UNIFIED IDEOGRAPH
+0x8CA2	0x72AC	#CJK UNIFIED IDEOGRAPH
+0x8CA3	0x732E	#CJK UNIFIED IDEOGRAPH
+0x8CA4	0x7814	#CJK UNIFIED IDEOGRAPH
+0x8CA5	0x786F	#CJK UNIFIED IDEOGRAPH
+0x8CA6	0x7D79	#CJK UNIFIED IDEOGRAPH
+0x8CA7	0x770C	#CJK UNIFIED IDEOGRAPH
+0x8CA8	0x80A9	#CJK UNIFIED IDEOGRAPH
+0x8CA9	0x898B	#CJK UNIFIED IDEOGRAPH
+0x8CAA	0x8B19	#CJK UNIFIED IDEOGRAPH
+0x8CAB	0x8CE2	#CJK UNIFIED IDEOGRAPH
+0x8CAC	0x8ED2	#CJK UNIFIED IDEOGRAPH
+0x8CAD	0x9063	#CJK UNIFIED IDEOGRAPH
+0x8CAE	0x9375	#CJK UNIFIED IDEOGRAPH
+0x8CAF	0x967A	#CJK UNIFIED IDEOGRAPH
+0x8CB0	0x9855	#CJK UNIFIED IDEOGRAPH
+0x8CB1	0x9A13	#CJK UNIFIED IDEOGRAPH
+0x8CB2	0x9E78	#CJK UNIFIED IDEOGRAPH
+0x8CB3	0x5143	#CJK UNIFIED IDEOGRAPH
+0x8CB4	0x539F	#CJK UNIFIED IDEOGRAPH
+0x8CB5	0x53B3	#CJK UNIFIED IDEOGRAPH
+0x8CB6	0x5E7B	#CJK UNIFIED IDEOGRAPH
+0x8CB7	0x5F26	#CJK UNIFIED IDEOGRAPH
+0x8CB8	0x6E1B	#CJK UNIFIED IDEOGRAPH
+0x8CB9	0x6E90	#CJK UNIFIED IDEOGRAPH
+0x8CBA	0x7384	#CJK UNIFIED IDEOGRAPH
+0x8CBB	0x73FE	#CJK UNIFIED IDEOGRAPH
+0x8CBC	0x7D43	#CJK UNIFIED IDEOGRAPH
+0x8CBD	0x8237	#CJK UNIFIED IDEOGRAPH
+0x8CBE	0x8A00	#CJK UNIFIED IDEOGRAPH
+0x8CBF	0x8AFA	#CJK UNIFIED IDEOGRAPH
+0x8CC0	0x9650	#CJK UNIFIED IDEOGRAPH
+0x8CC1	0x4E4E	#CJK UNIFIED IDEOGRAPH
+0x8CC2	0x500B	#CJK UNIFIED IDEOGRAPH
+0x8CC3	0x53E4	#CJK UNIFIED IDEOGRAPH
+0x8CC4	0x547C	#CJK UNIFIED IDEOGRAPH
+0x8CC5	0x56FA	#CJK UNIFIED IDEOGRAPH
+0x8CC6	0x59D1	#CJK UNIFIED IDEOGRAPH
+0x8CC7	0x5B64	#CJK UNIFIED IDEOGRAPH
+0x8CC8	0x5DF1	#CJK UNIFIED IDEOGRAPH
+0x8CC9	0x5EAB	#CJK UNIFIED IDEOGRAPH
+0x8CCA	0x5F27	#CJK UNIFIED IDEOGRAPH
+0x8CCB	0x6238	#CJK UNIFIED IDEOGRAPH
+0x8CCC	0x6545	#CJK UNIFIED IDEOGRAPH
+0x8CCD	0x67AF	#CJK UNIFIED IDEOGRAPH
+0x8CCE	0x6E56	#CJK UNIFIED IDEOGRAPH
+0x8CCF	0x72D0	#CJK UNIFIED IDEOGRAPH
+0x8CD0	0x7CCA	#CJK UNIFIED IDEOGRAPH
+0x8CD1	0x88B4	#CJK UNIFIED IDEOGRAPH
+0x8CD2	0x80A1	#CJK UNIFIED IDEOGRAPH
+0x8CD3	0x80E1	#CJK UNIFIED IDEOGRAPH
+0x8CD4	0x83F0	#CJK UNIFIED IDEOGRAPH
+0x8CD5	0x864E	#CJK UNIFIED IDEOGRAPH
+0x8CD6	0x8A87	#CJK UNIFIED IDEOGRAPH
+0x8CD7	0x8DE8	#CJK UNIFIED IDEOGRAPH
+0x8CD8	0x9237	#CJK UNIFIED IDEOGRAPH
+0x8CD9	0x96C7	#CJK UNIFIED IDEOGRAPH
+0x8CDA	0x9867	#CJK UNIFIED IDEOGRAPH
+0x8CDB	0x9F13	#CJK UNIFIED IDEOGRAPH
+0x8CDC	0x4E94	#CJK UNIFIED IDEOGRAPH
+0x8CDD	0x4E92	#CJK UNIFIED IDEOGRAPH
+0x8CDE	0x4F0D	#CJK UNIFIED IDEOGRAPH
+0x8CDF	0x5348	#CJK UNIFIED IDEOGRAPH
+0x8CE0	0x5449	#CJK UNIFIED IDEOGRAPH
+0x8CE1	0x543E	#CJK UNIFIED IDEOGRAPH
+0x8CE2	0x5A2F	#CJK UNIFIED IDEOGRAPH
+0x8CE3	0x5F8C	#CJK UNIFIED IDEOGRAPH
+0x8CE4	0x5FA1	#CJK UNIFIED IDEOGRAPH
+0x8CE5	0x609F	#CJK UNIFIED IDEOGRAPH
+0x8CE6	0x68A7	#CJK UNIFIED IDEOGRAPH
+0x8CE7	0x6A8E	#CJK UNIFIED IDEOGRAPH
+0x8CE8	0x745A	#CJK UNIFIED IDEOGRAPH
+0x8CE9	0x7881	#CJK UNIFIED IDEOGRAPH
+0x8CEA	0x8A9E	#CJK UNIFIED IDEOGRAPH
+0x8CEB	0x8AA4	#CJK UNIFIED IDEOGRAPH
+0x8CEC	0x8B77	#CJK UNIFIED IDEOGRAPH
+0x8CED	0x9190	#CJK UNIFIED IDEOGRAPH
+0x8CEE	0x4E5E	#CJK UNIFIED IDEOGRAPH
+0x8CEF	0x9BC9	#CJK UNIFIED IDEOGRAPH
+0x8CF0	0x4EA4	#CJK UNIFIED IDEOGRAPH
+0x8CF1	0x4F7C	#CJK UNIFIED IDEOGRAPH
+0x8CF2	0x4FAF	#CJK UNIFIED IDEOGRAPH
+0x8CF3	0x5019	#CJK UNIFIED IDEOGRAPH
+0x8CF4	0x5016	#CJK UNIFIED IDEOGRAPH
+0x8CF5	0x5149	#CJK UNIFIED IDEOGRAPH
+0x8CF6	0x516C	#CJK UNIFIED IDEOGRAPH
+0x8CF7	0x529F	#CJK UNIFIED IDEOGRAPH
+0x8CF8	0x52B9	#CJK UNIFIED IDEOGRAPH
+0x8CF9	0x52FE	#CJK UNIFIED IDEOGRAPH
+0x8CFA	0x539A	#CJK UNIFIED IDEOGRAPH
+0x8CFB	0x53E3	#CJK UNIFIED IDEOGRAPH
+0x8CFC	0x5411	#CJK UNIFIED IDEOGRAPH
+0x8D40	0x540E	#CJK UNIFIED IDEOGRAPH
+0x8D41	0x5589	#CJK UNIFIED IDEOGRAPH
+0x8D42	0x5751	#CJK UNIFIED IDEOGRAPH
+0x8D43	0x57A2	#CJK UNIFIED IDEOGRAPH
+0x8D44	0x597D	#CJK UNIFIED IDEOGRAPH
+0x8D45	0x5B54	#CJK UNIFIED IDEOGRAPH
+0x8D46	0x5B5D	#CJK UNIFIED IDEOGRAPH
+0x8D47	0x5B8F	#CJK UNIFIED IDEOGRAPH
+0x8D48	0x5DE5	#CJK UNIFIED IDEOGRAPH
+0x8D49	0x5DE7	#CJK UNIFIED IDEOGRAPH
+0x8D4A	0x5DF7	#CJK UNIFIED IDEOGRAPH
+0x8D4B	0x5E78	#CJK UNIFIED IDEOGRAPH
+0x8D4C	0x5E83	#CJK UNIFIED IDEOGRAPH
+0x8D4D	0x5E9A	#CJK UNIFIED IDEOGRAPH
+0x8D4E	0x5EB7	#CJK UNIFIED IDEOGRAPH
+0x8D4F	0x5F18	#CJK UNIFIED IDEOGRAPH
+0x8D50	0x6052	#CJK UNIFIED IDEOGRAPH
+0x8D51	0x614C	#CJK UNIFIED IDEOGRAPH
+0x8D52	0x6297	#CJK UNIFIED IDEOGRAPH
+0x8D53	0x62D8	#CJK UNIFIED IDEOGRAPH
+0x8D54	0x63A7	#CJK UNIFIED IDEOGRAPH
+0x8D55	0x653B	#CJK UNIFIED IDEOGRAPH
+0x8D56	0x6602	#CJK UNIFIED IDEOGRAPH
+0x8D57	0x6643	#CJK UNIFIED IDEOGRAPH
+0x8D58	0x66F4	#CJK UNIFIED IDEOGRAPH
+0x8D59	0x676D	#CJK UNIFIED IDEOGRAPH
+0x8D5A	0x6821	#CJK UNIFIED IDEOGRAPH
+0x8D5B	0x6897	#CJK UNIFIED IDEOGRAPH
+0x8D5C	0x69CB	#CJK UNIFIED IDEOGRAPH
+0x8D5D	0x6C5F	#CJK UNIFIED IDEOGRAPH
+0x8D5E	0x6D2A	#CJK UNIFIED IDEOGRAPH
+0x8D5F	0x6D69	#CJK UNIFIED IDEOGRAPH
+0x8D60	0x6E2F	#CJK UNIFIED IDEOGRAPH
+0x8D61	0x6E9D	#CJK UNIFIED IDEOGRAPH
+0x8D62	0x7532	#CJK UNIFIED IDEOGRAPH
+0x8D63	0x7687	#CJK UNIFIED IDEOGRAPH
+0x8D64	0x786C	#CJK UNIFIED IDEOGRAPH
+0x8D65	0x7A3F	#CJK UNIFIED IDEOGRAPH
+0x8D66	0x7CE0	#CJK UNIFIED IDEOGRAPH
+0x8D67	0x7D05	#CJK UNIFIED IDEOGRAPH
+0x8D68	0x7D18	#CJK UNIFIED IDEOGRAPH
+0x8D69	0x7D5E	#CJK UNIFIED IDEOGRAPH
+0x8D6A	0x7DB1	#CJK UNIFIED IDEOGRAPH
+0x8D6B	0x8015	#CJK UNIFIED IDEOGRAPH
+0x8D6C	0x8003	#CJK UNIFIED IDEOGRAPH
+0x8D6D	0x80AF	#CJK UNIFIED IDEOGRAPH
+0x8D6E	0x80B1	#CJK UNIFIED IDEOGRAPH
+0x8D6F	0x8154	#CJK UNIFIED IDEOGRAPH
+0x8D70	0x818F	#CJK UNIFIED IDEOGRAPH
+0x8D71	0x822A	#CJK UNIFIED IDEOGRAPH
+0x8D72	0x8352	#CJK UNIFIED IDEOGRAPH
+0x8D73	0x884C	#CJK UNIFIED IDEOGRAPH
+0x8D74	0x8861	#CJK UNIFIED IDEOGRAPH
+0x8D75	0x8B1B	#CJK UNIFIED IDEOGRAPH
+0x8D76	0x8CA2	#CJK UNIFIED IDEOGRAPH
+0x8D77	0x8CFC	#CJK UNIFIED IDEOGRAPH
+0x8D78	0x90CA	#CJK UNIFIED IDEOGRAPH
+0x8D79	0x9175	#CJK UNIFIED IDEOGRAPH
+0x8D7A	0x9271	#CJK UNIFIED IDEOGRAPH
+0x8D7B	0x783F	#CJK UNIFIED IDEOGRAPH
+0x8D7C	0x92FC	#CJK UNIFIED IDEOGRAPH
+0x8D7D	0x95A4	#CJK UNIFIED IDEOGRAPH
+0x8D7E	0x964D	#CJK UNIFIED IDEOGRAPH
+0x8D80	0x9805	#CJK UNIFIED IDEOGRAPH
+0x8D81	0x9999	#CJK UNIFIED IDEOGRAPH
+0x8D82	0x9AD8	#CJK UNIFIED IDEOGRAPH
+0x8D83	0x9D3B	#CJK UNIFIED IDEOGRAPH
+0x8D84	0x525B	#CJK UNIFIED IDEOGRAPH
+0x8D85	0x52AB	#CJK UNIFIED IDEOGRAPH
+0x8D86	0x53F7	#CJK UNIFIED IDEOGRAPH
+0x8D87	0x5408	#CJK UNIFIED IDEOGRAPH
+0x8D88	0x58D5	#CJK UNIFIED IDEOGRAPH
+0x8D89	0x62F7	#CJK UNIFIED IDEOGRAPH
+0x8D8A	0x6FE0	#CJK UNIFIED IDEOGRAPH
+0x8D8B	0x8C6A	#CJK UNIFIED IDEOGRAPH
+0x8D8C	0x8F5F	#CJK UNIFIED IDEOGRAPH
+0x8D8D	0x9EB9	#CJK UNIFIED IDEOGRAPH
+0x8D8E	0x514B	#CJK UNIFIED IDEOGRAPH
+0x8D8F	0x523B	#CJK UNIFIED IDEOGRAPH
+0x8D90	0x544A	#CJK UNIFIED IDEOGRAPH
+0x8D91	0x56FD	#CJK UNIFIED IDEOGRAPH
+0x8D92	0x7A40	#CJK UNIFIED IDEOGRAPH
+0x8D93	0x9177	#CJK UNIFIED IDEOGRAPH
+0x8D94	0x9D60	#CJK UNIFIED IDEOGRAPH
+0x8D95	0x9ED2	#CJK UNIFIED IDEOGRAPH
+0x8D96	0x7344	#CJK UNIFIED IDEOGRAPH
+0x8D97	0x6F09	#CJK UNIFIED IDEOGRAPH
+0x8D98	0x8170	#CJK UNIFIED IDEOGRAPH
+0x8D99	0x7511	#CJK UNIFIED IDEOGRAPH
+0x8D9A	0x5FFD	#CJK UNIFIED IDEOGRAPH
+0x8D9B	0x60DA	#CJK UNIFIED IDEOGRAPH
+0x8D9C	0x9AA8	#CJK UNIFIED IDEOGRAPH
+0x8D9D	0x72DB	#CJK UNIFIED IDEOGRAPH
+0x8D9E	0x8FBC	#CJK UNIFIED IDEOGRAPH
+0x8D9F	0x6B64	#CJK UNIFIED IDEOGRAPH
+0x8DA0	0x9803	#CJK UNIFIED IDEOGRAPH
+0x8DA1	0x4ECA	#CJK UNIFIED IDEOGRAPH
+0x8DA2	0x56F0	#CJK UNIFIED IDEOGRAPH
+0x8DA3	0x5764	#CJK UNIFIED IDEOGRAPH
+0x8DA4	0x58BE	#CJK UNIFIED IDEOGRAPH
+0x8DA5	0x5A5A	#CJK UNIFIED IDEOGRAPH
+0x8DA6	0x6068	#CJK UNIFIED IDEOGRAPH
+0x8DA7	0x61C7	#CJK UNIFIED IDEOGRAPH
+0x8DA8	0x660F	#CJK UNIFIED IDEOGRAPH
+0x8DA9	0x6606	#CJK UNIFIED IDEOGRAPH
+0x8DAA	0x6839	#CJK UNIFIED IDEOGRAPH
+0x8DAB	0x68B1	#CJK UNIFIED IDEOGRAPH
+0x8DAC	0x6DF7	#CJK UNIFIED IDEOGRAPH
+0x8DAD	0x75D5	#CJK UNIFIED IDEOGRAPH
+0x8DAE	0x7D3A	#CJK UNIFIED IDEOGRAPH
+0x8DAF	0x826E	#CJK UNIFIED IDEOGRAPH
+0x8DB0	0x9B42	#CJK UNIFIED IDEOGRAPH
+0x8DB1	0x4E9B	#CJK UNIFIED IDEOGRAPH
+0x8DB2	0x4F50	#CJK UNIFIED IDEOGRAPH
+0x8DB3	0x53C9	#CJK UNIFIED IDEOGRAPH
+0x8DB4	0x5506	#CJK UNIFIED IDEOGRAPH
+0x8DB5	0x5D6F	#CJK UNIFIED IDEOGRAPH
+0x8DB6	0x5DE6	#CJK UNIFIED IDEOGRAPH
+0x8DB7	0x5DEE	#CJK UNIFIED IDEOGRAPH
+0x8DB8	0x67FB	#CJK UNIFIED IDEOGRAPH
+0x8DB9	0x6C99	#CJK UNIFIED IDEOGRAPH
+0x8DBA	0x7473	#CJK UNIFIED IDEOGRAPH
+0x8DBB	0x7802	#CJK UNIFIED IDEOGRAPH
+0x8DBC	0x8A50	#CJK UNIFIED IDEOGRAPH
+0x8DBD	0x9396	#CJK UNIFIED IDEOGRAPH
+0x8DBE	0x88DF	#CJK UNIFIED IDEOGRAPH
+0x8DBF	0x5750	#CJK UNIFIED IDEOGRAPH
+0x8DC0	0x5EA7	#CJK UNIFIED IDEOGRAPH
+0x8DC1	0x632B	#CJK UNIFIED IDEOGRAPH
+0x8DC2	0x50B5	#CJK UNIFIED IDEOGRAPH
+0x8DC3	0x50AC	#CJK UNIFIED IDEOGRAPH
+0x8DC4	0x518D	#CJK UNIFIED IDEOGRAPH
+0x8DC5	0x6700	#CJK UNIFIED IDEOGRAPH
+0x8DC6	0x54C9	#CJK UNIFIED IDEOGRAPH
+0x8DC7	0x585E	#CJK UNIFIED IDEOGRAPH
+0x8DC8	0x59BB	#CJK UNIFIED IDEOGRAPH
+0x8DC9	0x5BB0	#CJK UNIFIED IDEOGRAPH
+0x8DCA	0x5F69	#CJK UNIFIED IDEOGRAPH
+0x8DCB	0x624D	#CJK UNIFIED IDEOGRAPH
+0x8DCC	0x63A1	#CJK UNIFIED IDEOGRAPH
+0x8DCD	0x683D	#CJK UNIFIED IDEOGRAPH
+0x8DCE	0x6B73	#CJK UNIFIED IDEOGRAPH
+0x8DCF	0x6E08	#CJK UNIFIED IDEOGRAPH
+0x8DD0	0x707D	#CJK UNIFIED IDEOGRAPH
+0x8DD1	0x91C7	#CJK UNIFIED IDEOGRAPH
+0x8DD2	0x7280	#CJK UNIFIED IDEOGRAPH
+0x8DD3	0x7815	#CJK UNIFIED IDEOGRAPH
+0x8DD4	0x7826	#CJK UNIFIED IDEOGRAPH
+0x8DD5	0x796D	#CJK UNIFIED IDEOGRAPH
+0x8DD6	0x658E	#CJK UNIFIED IDEOGRAPH
+0x8DD7	0x7D30	#CJK UNIFIED IDEOGRAPH
+0x8DD8	0x83DC	#CJK UNIFIED IDEOGRAPH
+0x8DD9	0x88C1	#CJK UNIFIED IDEOGRAPH
+0x8DDA	0x8F09	#CJK UNIFIED IDEOGRAPH
+0x8DDB	0x969B	#CJK UNIFIED IDEOGRAPH
+0x8DDC	0x5264	#CJK UNIFIED IDEOGRAPH
+0x8DDD	0x5728	#CJK UNIFIED IDEOGRAPH
+0x8DDE	0x6750	#CJK UNIFIED IDEOGRAPH
+0x8DDF	0x7F6A	#CJK UNIFIED IDEOGRAPH
+0x8DE0	0x8CA1	#CJK UNIFIED IDEOGRAPH
+0x8DE1	0x51B4	#CJK UNIFIED IDEOGRAPH
+0x8DE2	0x5742	#CJK UNIFIED IDEOGRAPH
+0x8DE3	0x962A	#CJK UNIFIED IDEOGRAPH
+0x8DE4	0x583A	#CJK UNIFIED IDEOGRAPH
+0x8DE5	0x698A	#CJK UNIFIED IDEOGRAPH
+0x8DE6	0x80B4	#CJK UNIFIED IDEOGRAPH
+0x8DE7	0x54B2	#CJK UNIFIED IDEOGRAPH
+0x8DE8	0x5D0E	#CJK UNIFIED IDEOGRAPH
+0x8DE9	0x57FC	#CJK UNIFIED IDEOGRAPH
+0x8DEA	0x7895	#CJK UNIFIED IDEOGRAPH
+0x8DEB	0x9DFA	#CJK UNIFIED IDEOGRAPH
+0x8DEC	0x4F5C	#CJK UNIFIED IDEOGRAPH
+0x8DED	0x524A	#CJK UNIFIED IDEOGRAPH
+0x8DEE	0x548B	#CJK UNIFIED IDEOGRAPH
+0x8DEF	0x643E	#CJK UNIFIED IDEOGRAPH
+0x8DF0	0x6628	#CJK UNIFIED IDEOGRAPH
+0x8DF1	0x6714	#CJK UNIFIED IDEOGRAPH
+0x8DF2	0x67F5	#CJK UNIFIED IDEOGRAPH
+0x8DF3	0x7A84	#CJK UNIFIED IDEOGRAPH
+0x8DF4	0x7B56	#CJK UNIFIED IDEOGRAPH
+0x8DF5	0x7D22	#CJK UNIFIED IDEOGRAPH
+0x8DF6	0x932F	#CJK UNIFIED IDEOGRAPH
+0x8DF7	0x685C	#CJK UNIFIED IDEOGRAPH
+0x8DF8	0x9BAD	#CJK UNIFIED IDEOGRAPH
+0x8DF9	0x7B39	#CJK UNIFIED IDEOGRAPH
+0x8DFA	0x5319	#CJK UNIFIED IDEOGRAPH
+0x8DFB	0x518A	#CJK UNIFIED IDEOGRAPH
+0x8DFC	0x5237	#CJK UNIFIED IDEOGRAPH
+0x8E40	0x5BDF	#CJK UNIFIED IDEOGRAPH
+0x8E41	0x62F6	#CJK UNIFIED IDEOGRAPH
+0x8E42	0x64AE	#CJK UNIFIED IDEOGRAPH
+0x8E43	0x64E6	#CJK UNIFIED IDEOGRAPH
+0x8E44	0x672D	#CJK UNIFIED IDEOGRAPH
+0x8E45	0x6BBA	#CJK UNIFIED IDEOGRAPH
+0x8E46	0x85A9	#CJK UNIFIED IDEOGRAPH
+0x8E47	0x96D1	#CJK UNIFIED IDEOGRAPH
+0x8E48	0x7690	#CJK UNIFIED IDEOGRAPH
+0x8E49	0x9BD6	#CJK UNIFIED IDEOGRAPH
+0x8E4A	0x634C	#CJK UNIFIED IDEOGRAPH
+0x8E4B	0x9306	#CJK UNIFIED IDEOGRAPH
+0x8E4C	0x9BAB	#CJK UNIFIED IDEOGRAPH
+0x8E4D	0x76BF	#CJK UNIFIED IDEOGRAPH
+0x8E4E	0x6652	#CJK UNIFIED IDEOGRAPH
+0x8E4F	0x4E09	#CJK UNIFIED IDEOGRAPH
+0x8E50	0x5098	#CJK UNIFIED IDEOGRAPH
+0x8E51	0x53C2	#CJK UNIFIED IDEOGRAPH
+0x8E52	0x5C71	#CJK UNIFIED IDEOGRAPH
+0x8E53	0x60E8	#CJK UNIFIED IDEOGRAPH
+0x8E54	0x6492	#CJK UNIFIED IDEOGRAPH
+0x8E55	0x6563	#CJK UNIFIED IDEOGRAPH
+0x8E56	0x685F	#CJK UNIFIED IDEOGRAPH
+0x8E57	0x71E6	#CJK UNIFIED IDEOGRAPH
+0x8E58	0x73CA	#CJK UNIFIED IDEOGRAPH
+0x8E59	0x7523	#CJK UNIFIED IDEOGRAPH
+0x8E5A	0x7B97	#CJK UNIFIED IDEOGRAPH
+0x8E5B	0x7E82	#CJK UNIFIED IDEOGRAPH
+0x8E5C	0x8695	#CJK UNIFIED IDEOGRAPH
+0x8E5D	0x8B83	#CJK UNIFIED IDEOGRAPH
+0x8E5E	0x8CDB	#CJK UNIFIED IDEOGRAPH
+0x8E5F	0x9178	#CJK UNIFIED IDEOGRAPH
+0x8E60	0x9910	#CJK UNIFIED IDEOGRAPH
+0x8E61	0x65AC	#CJK UNIFIED IDEOGRAPH
+0x8E62	0x66AB	#CJK UNIFIED IDEOGRAPH
+0x8E63	0x6B8B	#CJK UNIFIED IDEOGRAPH
+0x8E64	0x4ED5	#CJK UNIFIED IDEOGRAPH
+0x8E65	0x4ED4	#CJK UNIFIED IDEOGRAPH
+0x8E66	0x4F3A	#CJK UNIFIED IDEOGRAPH
+0x8E67	0x4F7F	#CJK UNIFIED IDEOGRAPH
+0x8E68	0x523A	#CJK UNIFIED IDEOGRAPH
+0x8E69	0x53F8	#CJK UNIFIED IDEOGRAPH
+0x8E6A	0x53F2	#CJK UNIFIED IDEOGRAPH
+0x8E6B	0x55E3	#CJK UNIFIED IDEOGRAPH
+0x8E6C	0x56DB	#CJK UNIFIED IDEOGRAPH
+0x8E6D	0x58EB	#CJK UNIFIED IDEOGRAPH
+0x8E6E	0x59CB	#CJK UNIFIED IDEOGRAPH
+0x8E6F	0x59C9	#CJK UNIFIED IDEOGRAPH
+0x8E70	0x59FF	#CJK UNIFIED IDEOGRAPH
+0x8E71	0x5B50	#CJK UNIFIED IDEOGRAPH
+0x8E72	0x5C4D	#CJK UNIFIED IDEOGRAPH
+0x8E73	0x5E02	#CJK UNIFIED IDEOGRAPH
+0x8E74	0x5E2B	#CJK UNIFIED IDEOGRAPH
+0x8E75	0x5FD7	#CJK UNIFIED IDEOGRAPH
+0x8E76	0x601D	#CJK UNIFIED IDEOGRAPH
+0x8E77	0x6307	#CJK UNIFIED IDEOGRAPH
+0x8E78	0x652F	#CJK UNIFIED IDEOGRAPH
+0x8E79	0x5B5C	#CJK UNIFIED IDEOGRAPH
+0x8E7A	0x65AF	#CJK UNIFIED IDEOGRAPH
+0x8E7B	0x65BD	#CJK UNIFIED IDEOGRAPH
+0x8E7C	0x65E8	#CJK UNIFIED IDEOGRAPH
+0x8E7D	0x679D	#CJK UNIFIED IDEOGRAPH
+0x8E7E	0x6B62	#CJK UNIFIED IDEOGRAPH
+0x8E80	0x6B7B	#CJK UNIFIED IDEOGRAPH
+0x8E81	0x6C0F	#CJK UNIFIED IDEOGRAPH
+0x8E82	0x7345	#CJK UNIFIED IDEOGRAPH
+0x8E83	0x7949	#CJK UNIFIED IDEOGRAPH
+0x8E84	0x79C1	#CJK UNIFIED IDEOGRAPH
+0x8E85	0x7CF8	#CJK UNIFIED IDEOGRAPH
+0x8E86	0x7D19	#CJK UNIFIED IDEOGRAPH
+0x8E87	0x7D2B	#CJK UNIFIED IDEOGRAPH
+0x8E88	0x80A2	#CJK UNIFIED IDEOGRAPH
+0x8E89	0x8102	#CJK UNIFIED IDEOGRAPH
+0x8E8A	0x81F3	#CJK UNIFIED IDEOGRAPH
+0x8E8B	0x8996	#CJK UNIFIED IDEOGRAPH
+0x8E8C	0x8A5E	#CJK UNIFIED IDEOGRAPH
+0x8E8D	0x8A69	#CJK UNIFIED IDEOGRAPH
+0x8E8E	0x8A66	#CJK UNIFIED IDEOGRAPH
+0x8E8F	0x8A8C	#CJK UNIFIED IDEOGRAPH
+0x8E90	0x8AEE	#CJK UNIFIED IDEOGRAPH
+0x8E91	0x8CC7	#CJK UNIFIED IDEOGRAPH
+0x8E92	0x8CDC	#CJK UNIFIED IDEOGRAPH
+0x8E93	0x96CC	#CJK UNIFIED IDEOGRAPH
+0x8E94	0x98FC	#CJK UNIFIED IDEOGRAPH
+0x8E95	0x6B6F	#CJK UNIFIED IDEOGRAPH
+0x8E96	0x4E8B	#CJK UNIFIED IDEOGRAPH
+0x8E97	0x4F3C	#CJK UNIFIED IDEOGRAPH
+0x8E98	0x4F8D	#CJK UNIFIED IDEOGRAPH
+0x8E99	0x5150	#CJK UNIFIED IDEOGRAPH
+0x8E9A	0x5B57	#CJK UNIFIED IDEOGRAPH
+0x8E9B	0x5BFA	#CJK UNIFIED IDEOGRAPH
+0x8E9C	0x6148	#CJK UNIFIED IDEOGRAPH
+0x8E9D	0x6301	#CJK UNIFIED IDEOGRAPH
+0x8E9E	0x6642	#CJK UNIFIED IDEOGRAPH
+0x8E9F	0x6B21	#CJK UNIFIED IDEOGRAPH
+0x8EA0	0x6ECB	#CJK UNIFIED IDEOGRAPH
+0x8EA1	0x6CBB	#CJK UNIFIED IDEOGRAPH
+0x8EA2	0x723E	#CJK UNIFIED IDEOGRAPH
+0x8EA3	0x74BD	#CJK UNIFIED IDEOGRAPH
+0x8EA4	0x75D4	#CJK UNIFIED IDEOGRAPH
+0x8EA5	0x78C1	#CJK UNIFIED IDEOGRAPH
+0x8EA6	0x793A	#CJK UNIFIED IDEOGRAPH
+0x8EA7	0x800C	#CJK UNIFIED IDEOGRAPH
+0x8EA8	0x8033	#CJK UNIFIED IDEOGRAPH
+0x8EA9	0x81EA	#CJK UNIFIED IDEOGRAPH
+0x8EAA	0x8494	#CJK UNIFIED IDEOGRAPH
+0x8EAB	0x8F9E	#CJK UNIFIED IDEOGRAPH
+0x8EAC	0x6C50	#CJK UNIFIED IDEOGRAPH
+0x8EAD	0x9E7F	#CJK UNIFIED IDEOGRAPH
+0x8EAE	0x5F0F	#CJK UNIFIED IDEOGRAPH
+0x8EAF	0x8B58	#CJK UNIFIED IDEOGRAPH
+0x8EB0	0x9D2B	#CJK UNIFIED IDEOGRAPH
+0x8EB1	0x7AFA	#CJK UNIFIED IDEOGRAPH
+0x8EB2	0x8EF8	#CJK UNIFIED IDEOGRAPH
+0x8EB3	0x5B8D	#CJK UNIFIED IDEOGRAPH
+0x8EB4	0x96EB	#CJK UNIFIED IDEOGRAPH
+0x8EB5	0x4E03	#CJK UNIFIED IDEOGRAPH
+0x8EB6	0x53F1	#CJK UNIFIED IDEOGRAPH
+0x8EB7	0x57F7	#CJK UNIFIED IDEOGRAPH
+0x8EB8	0x5931	#CJK UNIFIED IDEOGRAPH
+0x8EB9	0x5AC9	#CJK UNIFIED IDEOGRAPH
+0x8EBA	0x5BA4	#CJK UNIFIED IDEOGRAPH
+0x8EBB	0x6089	#CJK UNIFIED IDEOGRAPH
+0x8EBC	0x6E7F	#CJK UNIFIED IDEOGRAPH
+0x8EBD	0x6F06	#CJK UNIFIED IDEOGRAPH
+0x8EBE	0x75BE	#CJK UNIFIED IDEOGRAPH
+0x8EBF	0x8CEA	#CJK UNIFIED IDEOGRAPH
+0x8EC0	0x5B9F	#CJK UNIFIED IDEOGRAPH
+0x8EC1	0x8500	#CJK UNIFIED IDEOGRAPH
+0x8EC2	0x7BE0	#CJK UNIFIED IDEOGRAPH
+0x8EC3	0x5072	#CJK UNIFIED IDEOGRAPH
+0x8EC4	0x67F4	#CJK UNIFIED IDEOGRAPH
+0x8EC5	0x829D	#CJK UNIFIED IDEOGRAPH
+0x8EC6	0x5C61	#CJK UNIFIED IDEOGRAPH
+0x8EC7	0x854A	#CJK UNIFIED IDEOGRAPH
+0x8EC8	0x7E1E	#CJK UNIFIED IDEOGRAPH
+0x8EC9	0x820E	#CJK UNIFIED IDEOGRAPH
+0x8ECA	0x5199	#CJK UNIFIED IDEOGRAPH
+0x8ECB	0x5C04	#CJK UNIFIED IDEOGRAPH
+0x8ECC	0x6368	#CJK UNIFIED IDEOGRAPH
+0x8ECD	0x8D66	#CJK UNIFIED IDEOGRAPH
+0x8ECE	0x659C	#CJK UNIFIED IDEOGRAPH
+0x8ECF	0x716E	#CJK UNIFIED IDEOGRAPH
+0x8ED0	0x793E	#CJK UNIFIED IDEOGRAPH
+0x8ED1	0x7D17	#CJK UNIFIED IDEOGRAPH
+0x8ED2	0x8005	#CJK UNIFIED IDEOGRAPH
+0x8ED3	0x8B1D	#CJK UNIFIED IDEOGRAPH
+0x8ED4	0x8ECA	#CJK UNIFIED IDEOGRAPH
+0x8ED5	0x906E	#CJK UNIFIED IDEOGRAPH
+0x8ED6	0x86C7	#CJK UNIFIED IDEOGRAPH
+0x8ED7	0x90AA	#CJK UNIFIED IDEOGRAPH
+0x8ED8	0x501F	#CJK UNIFIED IDEOGRAPH
+0x8ED9	0x52FA	#CJK UNIFIED IDEOGRAPH
+0x8EDA	0x5C3A	#CJK UNIFIED IDEOGRAPH
+0x8EDB	0x6753	#CJK UNIFIED IDEOGRAPH
+0x8EDC	0x707C	#CJK UNIFIED IDEOGRAPH
+0x8EDD	0x7235	#CJK UNIFIED IDEOGRAPH
+0x8EDE	0x914C	#CJK UNIFIED IDEOGRAPH
+0x8EDF	0x91C8	#CJK UNIFIED IDEOGRAPH
+0x8EE0	0x932B	#CJK UNIFIED IDEOGRAPH
+0x8EE1	0x82E5	#CJK UNIFIED IDEOGRAPH
+0x8EE2	0x5BC2	#CJK UNIFIED IDEOGRAPH
+0x8EE3	0x5F31	#CJK UNIFIED IDEOGRAPH
+0x8EE4	0x60F9	#CJK UNIFIED IDEOGRAPH
+0x8EE5	0x4E3B	#CJK UNIFIED IDEOGRAPH
+0x8EE6	0x53D6	#CJK UNIFIED IDEOGRAPH
+0x8EE7	0x5B88	#CJK UNIFIED IDEOGRAPH
+0x8EE8	0x624B	#CJK UNIFIED IDEOGRAPH
+0x8EE9	0x6731	#CJK UNIFIED IDEOGRAPH
+0x8EEA	0x6B8A	#CJK UNIFIED IDEOGRAPH
+0x8EEB	0x72E9	#CJK UNIFIED IDEOGRAPH
+0x8EEC	0x73E0	#CJK UNIFIED IDEOGRAPH
+0x8EED	0x7A2E	#CJK UNIFIED IDEOGRAPH
+0x8EEE	0x816B	#CJK UNIFIED IDEOGRAPH
+0x8EEF	0x8DA3	#CJK UNIFIED IDEOGRAPH
+0x8EF0	0x9152	#CJK UNIFIED IDEOGRAPH
+0x8EF1	0x9996	#CJK UNIFIED IDEOGRAPH
+0x8EF2	0x5112	#CJK UNIFIED IDEOGRAPH
+0x8EF3	0x53D7	#CJK UNIFIED IDEOGRAPH
+0x8EF4	0x546A	#CJK UNIFIED IDEOGRAPH
+0x8EF5	0x5BFF	#CJK UNIFIED IDEOGRAPH
+0x8EF6	0x6388	#CJK UNIFIED IDEOGRAPH
+0x8EF7	0x6A39	#CJK UNIFIED IDEOGRAPH
+0x8EF8	0x7DAC	#CJK UNIFIED IDEOGRAPH
+0x8EF9	0x9700	#CJK UNIFIED IDEOGRAPH
+0x8EFA	0x56DA	#CJK UNIFIED IDEOGRAPH
+0x8EFB	0x53CE	#CJK UNIFIED IDEOGRAPH
+0x8EFC	0x5468	#CJK UNIFIED IDEOGRAPH
+0x8F40	0x5B97	#CJK UNIFIED IDEOGRAPH
+0x8F41	0x5C31	#CJK UNIFIED IDEOGRAPH
+0x8F42	0x5DDE	#CJK UNIFIED IDEOGRAPH
+0x8F43	0x4FEE	#CJK UNIFIED IDEOGRAPH
+0x8F44	0x6101	#CJK UNIFIED IDEOGRAPH
+0x8F45	0x62FE	#CJK UNIFIED IDEOGRAPH
+0x8F46	0x6D32	#CJK UNIFIED IDEOGRAPH
+0x8F47	0x79C0	#CJK UNIFIED IDEOGRAPH
+0x8F48	0x79CB	#CJK UNIFIED IDEOGRAPH
+0x8F49	0x7D42	#CJK UNIFIED IDEOGRAPH
+0x8F4A	0x7E4D	#CJK UNIFIED IDEOGRAPH
+0x8F4B	0x7FD2	#CJK UNIFIED IDEOGRAPH
+0x8F4C	0x81ED	#CJK UNIFIED IDEOGRAPH
+0x8F4D	0x821F	#CJK UNIFIED IDEOGRAPH
+0x8F4E	0x8490	#CJK UNIFIED IDEOGRAPH
+0x8F4F	0x8846	#CJK UNIFIED IDEOGRAPH
+0x8F50	0x8972	#CJK UNIFIED IDEOGRAPH
+0x8F51	0x8B90	#CJK UNIFIED IDEOGRAPH
+0x8F52	0x8E74	#CJK UNIFIED IDEOGRAPH
+0x8F53	0x8F2F	#CJK UNIFIED IDEOGRAPH
+0x8F54	0x9031	#CJK UNIFIED IDEOGRAPH
+0x8F55	0x914B	#CJK UNIFIED IDEOGRAPH
+0x8F56	0x916C	#CJK UNIFIED IDEOGRAPH
+0x8F57	0x96C6	#CJK UNIFIED IDEOGRAPH
+0x8F58	0x919C	#CJK UNIFIED IDEOGRAPH
+0x8F59	0x4EC0	#CJK UNIFIED IDEOGRAPH
+0x8F5A	0x4F4F	#CJK UNIFIED IDEOGRAPH
+0x8F5B	0x5145	#CJK UNIFIED IDEOGRAPH
+0x8F5C	0x5341	#CJK UNIFIED IDEOGRAPH
+0x8F5D	0x5F93	#CJK UNIFIED IDEOGRAPH
+0x8F5E	0x620E	#CJK UNIFIED IDEOGRAPH
+0x8F5F	0x67D4	#CJK UNIFIED IDEOGRAPH
+0x8F60	0x6C41	#CJK UNIFIED IDEOGRAPH
+0x8F61	0x6E0B	#CJK UNIFIED IDEOGRAPH
+0x8F62	0x7363	#CJK UNIFIED IDEOGRAPH
+0x8F63	0x7E26	#CJK UNIFIED IDEOGRAPH
+0x8F64	0x91CD	#CJK UNIFIED IDEOGRAPH
+0x8F65	0x9283	#CJK UNIFIED IDEOGRAPH
+0x8F66	0x53D4	#CJK UNIFIED IDEOGRAPH
+0x8F67	0x5919	#CJK UNIFIED IDEOGRAPH
+0x8F68	0x5BBF	#CJK UNIFIED IDEOGRAPH
+0x8F69	0x6DD1	#CJK UNIFIED IDEOGRAPH
+0x8F6A	0x795D	#CJK UNIFIED IDEOGRAPH
+0x8F6B	0x7E2E	#CJK UNIFIED IDEOGRAPH
+0x8F6C	0x7C9B	#CJK UNIFIED IDEOGRAPH
+0x8F6D	0x587E	#CJK UNIFIED IDEOGRAPH
+0x8F6E	0x719F	#CJK UNIFIED IDEOGRAPH
+0x8F6F	0x51FA	#CJK UNIFIED IDEOGRAPH
+0x8F70	0x8853	#CJK UNIFIED IDEOGRAPH
+0x8F71	0x8FF0	#CJK UNIFIED IDEOGRAPH
+0x8F72	0x4FCA	#CJK UNIFIED IDEOGRAPH
+0x8F73	0x5CFB	#CJK UNIFIED IDEOGRAPH
+0x8F74	0x6625	#CJK UNIFIED IDEOGRAPH
+0x8F75	0x77AC	#CJK UNIFIED IDEOGRAPH
+0x8F76	0x7AE3	#CJK UNIFIED IDEOGRAPH
+0x8F77	0x821C	#CJK UNIFIED IDEOGRAPH
+0x8F78	0x99FF	#CJK UNIFIED IDEOGRAPH
+0x8F79	0x51C6	#CJK UNIFIED IDEOGRAPH
+0x8F7A	0x5FAA	#CJK UNIFIED IDEOGRAPH
+0x8F7B	0x65EC	#CJK UNIFIED IDEOGRAPH
+0x8F7C	0x696F	#CJK UNIFIED IDEOGRAPH
+0x8F7D	0x6B89	#CJK UNIFIED IDEOGRAPH
+0x8F7E	0x6DF3	#CJK UNIFIED IDEOGRAPH
+0x8F80	0x6E96	#CJK UNIFIED IDEOGRAPH
+0x8F81	0x6F64	#CJK UNIFIED IDEOGRAPH
+0x8F82	0x76FE	#CJK UNIFIED IDEOGRAPH
+0x8F83	0x7D14	#CJK UNIFIED IDEOGRAPH
+0x8F84	0x5DE1	#CJK UNIFIED IDEOGRAPH
+0x8F85	0x9075	#CJK UNIFIED IDEOGRAPH
+0x8F86	0x9187	#CJK UNIFIED IDEOGRAPH
+0x8F87	0x9806	#CJK UNIFIED IDEOGRAPH
+0x8F88	0x51E6	#CJK UNIFIED IDEOGRAPH
+0x8F89	0x521D	#CJK UNIFIED IDEOGRAPH
+0x8F8A	0x6240	#CJK UNIFIED IDEOGRAPH
+0x8F8B	0x6691	#CJK UNIFIED IDEOGRAPH
+0x8F8C	0x66D9	#CJK UNIFIED IDEOGRAPH
+0x8F8D	0x6E1A	#CJK UNIFIED IDEOGRAPH
+0x8F8E	0x5EB6	#CJK UNIFIED IDEOGRAPH
+0x8F8F	0x7DD2	#CJK UNIFIED IDEOGRAPH
+0x8F90	0x7F72	#CJK UNIFIED IDEOGRAPH
+0x8F91	0x66F8	#CJK UNIFIED IDEOGRAPH
+0x8F92	0x85AF	#CJK UNIFIED IDEOGRAPH
+0x8F93	0x85F7	#CJK UNIFIED IDEOGRAPH
+0x8F94	0x8AF8	#CJK UNIFIED IDEOGRAPH
+0x8F95	0x52A9	#CJK UNIFIED IDEOGRAPH
+0x8F96	0x53D9	#CJK UNIFIED IDEOGRAPH
+0x8F97	0x5973	#CJK UNIFIED IDEOGRAPH
+0x8F98	0x5E8F	#CJK UNIFIED IDEOGRAPH
+0x8F99	0x5F90	#CJK UNIFIED IDEOGRAPH
+0x8F9A	0x6055	#CJK UNIFIED IDEOGRAPH
+0x8F9B	0x92E4	#CJK UNIFIED IDEOGRAPH
+0x8F9C	0x9664	#CJK UNIFIED IDEOGRAPH
+0x8F9D	0x50B7	#CJK UNIFIED IDEOGRAPH
+0x8F9E	0x511F	#CJK UNIFIED IDEOGRAPH
+0x8F9F	0x52DD	#CJK UNIFIED IDEOGRAPH
+0x8FA0	0x5320	#CJK UNIFIED IDEOGRAPH
+0x8FA1	0x5347	#CJK UNIFIED IDEOGRAPH
+0x8FA2	0x53EC	#CJK UNIFIED IDEOGRAPH
+0x8FA3	0x54E8	#CJK UNIFIED IDEOGRAPH
+0x8FA4	0x5546	#CJK UNIFIED IDEOGRAPH
+0x8FA5	0x5531	#CJK UNIFIED IDEOGRAPH
+0x8FA6	0x5617	#CJK UNIFIED IDEOGRAPH
+0x8FA7	0x5968	#CJK UNIFIED IDEOGRAPH
+0x8FA8	0x59BE	#CJK UNIFIED IDEOGRAPH
+0x8FA9	0x5A3C	#CJK UNIFIED IDEOGRAPH
+0x8FAA	0x5BB5	#CJK UNIFIED IDEOGRAPH
+0x8FAB	0x5C06	#CJK UNIFIED IDEOGRAPH
+0x8FAC	0x5C0F	#CJK UNIFIED IDEOGRAPH
+0x8FAD	0x5C11	#CJK UNIFIED IDEOGRAPH
+0x8FAE	0x5C1A	#CJK UNIFIED IDEOGRAPH
+0x8FAF	0x5E84	#CJK UNIFIED IDEOGRAPH
+0x8FB0	0x5E8A	#CJK UNIFIED IDEOGRAPH
+0x8FB1	0x5EE0	#CJK UNIFIED IDEOGRAPH
+0x8FB2	0x5F70	#CJK UNIFIED IDEOGRAPH
+0x8FB3	0x627F	#CJK UNIFIED IDEOGRAPH
+0x8FB4	0x6284	#CJK UNIFIED IDEOGRAPH
+0x8FB5	0x62DB	#CJK UNIFIED IDEOGRAPH
+0x8FB6	0x638C	#CJK UNIFIED IDEOGRAPH
+0x8FB7	0x6377	#CJK UNIFIED IDEOGRAPH
+0x8FB8	0x6607	#CJK UNIFIED IDEOGRAPH
+0x8FB9	0x660C	#CJK UNIFIED IDEOGRAPH
+0x8FBA	0x662D	#CJK UNIFIED IDEOGRAPH
+0x8FBB	0x6676	#CJK UNIFIED IDEOGRAPH
+0x8FBC	0x677E	#CJK UNIFIED IDEOGRAPH
+0x8FBD	0x68A2	#CJK UNIFIED IDEOGRAPH
+0x8FBE	0x6A1F	#CJK UNIFIED IDEOGRAPH
+0x8FBF	0x6A35	#CJK UNIFIED IDEOGRAPH
+0x8FC0	0x6CBC	#CJK UNIFIED IDEOGRAPH
+0x8FC1	0x6D88	#CJK UNIFIED IDEOGRAPH
+0x8FC2	0x6E09	#CJK UNIFIED IDEOGRAPH
+0x8FC3	0x6E58	#CJK UNIFIED IDEOGRAPH
+0x8FC4	0x713C	#CJK UNIFIED IDEOGRAPH
+0x8FC5	0x7126	#CJK UNIFIED IDEOGRAPH
+0x8FC6	0x7167	#CJK UNIFIED IDEOGRAPH
+0x8FC7	0x75C7	#CJK UNIFIED IDEOGRAPH
+0x8FC8	0x7701	#CJK UNIFIED IDEOGRAPH
+0x8FC9	0x785D	#CJK UNIFIED IDEOGRAPH
+0x8FCA	0x7901	#CJK UNIFIED IDEOGRAPH
+0x8FCB	0x7965	#CJK UNIFIED IDEOGRAPH
+0x8FCC	0x79F0	#CJK UNIFIED IDEOGRAPH
+0x8FCD	0x7AE0	#CJK UNIFIED IDEOGRAPH
+0x8FCE	0x7B11	#CJK UNIFIED IDEOGRAPH
+0x8FCF	0x7CA7	#CJK UNIFIED IDEOGRAPH
+0x8FD0	0x7D39	#CJK UNIFIED IDEOGRAPH
+0x8FD1	0x8096	#CJK UNIFIED IDEOGRAPH
+0x8FD2	0x83D6	#CJK UNIFIED IDEOGRAPH
+0x8FD3	0x848B	#CJK UNIFIED IDEOGRAPH
+0x8FD4	0x8549	#CJK UNIFIED IDEOGRAPH
+0x8FD5	0x885D	#CJK UNIFIED IDEOGRAPH
+0x8FD6	0x88F3	#CJK UNIFIED IDEOGRAPH
+0x8FD7	0x8A1F	#CJK UNIFIED IDEOGRAPH
+0x8FD8	0x8A3C	#CJK UNIFIED IDEOGRAPH
+0x8FD9	0x8A54	#CJK UNIFIED IDEOGRAPH
+0x8FDA	0x8A73	#CJK UNIFIED IDEOGRAPH
+0x8FDB	0x8C61	#CJK UNIFIED IDEOGRAPH
+0x8FDC	0x8CDE	#CJK UNIFIED IDEOGRAPH
+0x8FDD	0x91A4	#CJK UNIFIED IDEOGRAPH
+0x8FDE	0x9266	#CJK UNIFIED IDEOGRAPH
+0x8FDF	0x937E	#CJK UNIFIED IDEOGRAPH
+0x8FE0	0x9418	#CJK UNIFIED IDEOGRAPH
+0x8FE1	0x969C	#CJK UNIFIED IDEOGRAPH
+0x8FE2	0x9798	#CJK UNIFIED IDEOGRAPH
+0x8FE3	0x4E0A	#CJK UNIFIED IDEOGRAPH
+0x8FE4	0x4E08	#CJK UNIFIED IDEOGRAPH
+0x8FE5	0x4E1E	#CJK UNIFIED IDEOGRAPH
+0x8FE6	0x4E57	#CJK UNIFIED IDEOGRAPH
+0x8FE7	0x5197	#CJK UNIFIED IDEOGRAPH
+0x8FE8	0x5270	#CJK UNIFIED IDEOGRAPH
+0x8FE9	0x57CE	#CJK UNIFIED IDEOGRAPH
+0x8FEA	0x5834	#CJK UNIFIED IDEOGRAPH
+0x8FEB	0x58CC	#CJK UNIFIED IDEOGRAPH
+0x8FEC	0x5B22	#CJK UNIFIED IDEOGRAPH
+0x8FED	0x5E38	#CJK UNIFIED IDEOGRAPH
+0x8FEE	0x60C5	#CJK UNIFIED IDEOGRAPH
+0x8FEF	0x64FE	#CJK UNIFIED IDEOGRAPH
+0x8FF0	0x6761	#CJK UNIFIED IDEOGRAPH
+0x8FF1	0x6756	#CJK UNIFIED IDEOGRAPH
+0x8FF2	0x6D44	#CJK UNIFIED IDEOGRAPH
+0x8FF3	0x72B6	#CJK UNIFIED IDEOGRAPH
+0x8FF4	0x7573	#CJK UNIFIED IDEOGRAPH
+0x8FF5	0x7A63	#CJK UNIFIED IDEOGRAPH
+0x8FF6	0x84B8	#CJK UNIFIED IDEOGRAPH
+0x8FF7	0x8B72	#CJK UNIFIED IDEOGRAPH
+0x8FF8	0x91B8	#CJK UNIFIED IDEOGRAPH
+0x8FF9	0x9320	#CJK UNIFIED IDEOGRAPH
+0x8FFA	0x5631	#CJK UNIFIED IDEOGRAPH
+0x8FFB	0x57F4	#CJK UNIFIED IDEOGRAPH
+0x8FFC	0x98FE	#CJK UNIFIED IDEOGRAPH
+0x9040	0x62ED	#CJK UNIFIED IDEOGRAPH
+0x9041	0x690D	#CJK UNIFIED IDEOGRAPH
+0x9042	0x6B96	#CJK UNIFIED IDEOGRAPH
+0x9043	0x71ED	#CJK UNIFIED IDEOGRAPH
+0x9044	0x7E54	#CJK UNIFIED IDEOGRAPH
+0x9045	0x8077	#CJK UNIFIED IDEOGRAPH
+0x9046	0x8272	#CJK UNIFIED IDEOGRAPH
+0x9047	0x89E6	#CJK UNIFIED IDEOGRAPH
+0x9048	0x98DF	#CJK UNIFIED IDEOGRAPH
+0x9049	0x8755	#CJK UNIFIED IDEOGRAPH
+0x904A	0x8FB1	#CJK UNIFIED IDEOGRAPH
+0x904B	0x5C3B	#CJK UNIFIED IDEOGRAPH
+0x904C	0x4F38	#CJK UNIFIED IDEOGRAPH
+0x904D	0x4FE1	#CJK UNIFIED IDEOGRAPH
+0x904E	0x4FB5	#CJK UNIFIED IDEOGRAPH
+0x904F	0x5507	#CJK UNIFIED IDEOGRAPH
+0x9050	0x5A20	#CJK UNIFIED IDEOGRAPH
+0x9051	0x5BDD	#CJK UNIFIED IDEOGRAPH
+0x9052	0x5BE9	#CJK UNIFIED IDEOGRAPH
+0x9053	0x5FC3	#CJK UNIFIED IDEOGRAPH
+0x9054	0x614E	#CJK UNIFIED IDEOGRAPH
+0x9055	0x632F	#CJK UNIFIED IDEOGRAPH
+0x9056	0x65B0	#CJK UNIFIED IDEOGRAPH
+0x9057	0x664B	#CJK UNIFIED IDEOGRAPH
+0x9058	0x68EE	#CJK UNIFIED IDEOGRAPH
+0x9059	0x699B	#CJK UNIFIED IDEOGRAPH
+0x905A	0x6D78	#CJK UNIFIED IDEOGRAPH
+0x905B	0x6DF1	#CJK UNIFIED IDEOGRAPH
+0x905C	0x7533	#CJK UNIFIED IDEOGRAPH
+0x905D	0x75B9	#CJK UNIFIED IDEOGRAPH
+0x905E	0x771F	#CJK UNIFIED IDEOGRAPH
+0x905F	0x795E	#CJK UNIFIED IDEOGRAPH
+0x9060	0x79E6	#CJK UNIFIED IDEOGRAPH
+0x9061	0x7D33	#CJK UNIFIED IDEOGRAPH
+0x9062	0x81E3	#CJK UNIFIED IDEOGRAPH
+0x9063	0x82AF	#CJK UNIFIED IDEOGRAPH
+0x9064	0x85AA	#CJK UNIFIED IDEOGRAPH
+0x9065	0x89AA	#CJK UNIFIED IDEOGRAPH
+0x9066	0x8A3A	#CJK UNIFIED IDEOGRAPH
+0x9067	0x8EAB	#CJK UNIFIED IDEOGRAPH
+0x9068	0x8F9B	#CJK UNIFIED IDEOGRAPH
+0x9069	0x9032	#CJK UNIFIED IDEOGRAPH
+0x906A	0x91DD	#CJK UNIFIED IDEOGRAPH
+0x906B	0x9707	#CJK UNIFIED IDEOGRAPH
+0x906C	0x4EBA	#CJK UNIFIED IDEOGRAPH
+0x906D	0x4EC1	#CJK UNIFIED IDEOGRAPH
+0x906E	0x5203	#CJK UNIFIED IDEOGRAPH
+0x906F	0x5875	#CJK UNIFIED IDEOGRAPH
+0x9070	0x58EC	#CJK UNIFIED IDEOGRAPH
+0x9071	0x5C0B	#CJK UNIFIED IDEOGRAPH
+0x9072	0x751A	#CJK UNIFIED IDEOGRAPH
+0x9073	0x5C3D	#CJK UNIFIED IDEOGRAPH
+0x9074	0x814E	#CJK UNIFIED IDEOGRAPH
+0x9075	0x8A0A	#CJK UNIFIED IDEOGRAPH
+0x9076	0x8FC5	#CJK UNIFIED IDEOGRAPH
+0x9077	0x9663	#CJK UNIFIED IDEOGRAPH
+0x9078	0x976D	#CJK UNIFIED IDEOGRAPH
+0x9079	0x7B25	#CJK UNIFIED IDEOGRAPH
+0x907A	0x8ACF	#CJK UNIFIED IDEOGRAPH
+0x907B	0x9808	#CJK UNIFIED IDEOGRAPH
+0x907C	0x9162	#CJK UNIFIED IDEOGRAPH
+0x907D	0x56F3	#CJK UNIFIED IDEOGRAPH
+0x907E	0x53A8	#CJK UNIFIED IDEOGRAPH
+0x9080	0x9017	#CJK UNIFIED IDEOGRAPH
+0x9081	0x5439	#CJK UNIFIED IDEOGRAPH
+0x9082	0x5782	#CJK UNIFIED IDEOGRAPH
+0x9083	0x5E25	#CJK UNIFIED IDEOGRAPH
+0x9084	0x63A8	#CJK UNIFIED IDEOGRAPH
+0x9085	0x6C34	#CJK UNIFIED IDEOGRAPH
+0x9086	0x708A	#CJK UNIFIED IDEOGRAPH
+0x9087	0x7761	#CJK UNIFIED IDEOGRAPH
+0x9088	0x7C8B	#CJK UNIFIED IDEOGRAPH
+0x9089	0x7FE0	#CJK UNIFIED IDEOGRAPH
+0x908A	0x8870	#CJK UNIFIED IDEOGRAPH
+0x908B	0x9042	#CJK UNIFIED IDEOGRAPH
+0x908C	0x9154	#CJK UNIFIED IDEOGRAPH
+0x908D	0x9310	#CJK UNIFIED IDEOGRAPH
+0x908E	0x9318	#CJK UNIFIED IDEOGRAPH
+0x908F	0x968F	#CJK UNIFIED IDEOGRAPH
+0x9090	0x745E	#CJK UNIFIED IDEOGRAPH
+0x9091	0x9AC4	#CJK UNIFIED IDEOGRAPH
+0x9092	0x5D07	#CJK UNIFIED IDEOGRAPH
+0x9093	0x5D69	#CJK UNIFIED IDEOGRAPH
+0x9094	0x6570	#CJK UNIFIED IDEOGRAPH
+0x9095	0x67A2	#CJK UNIFIED IDEOGRAPH
+0x9096	0x8DA8	#CJK UNIFIED IDEOGRAPH
+0x9097	0x96DB	#CJK UNIFIED IDEOGRAPH
+0x9098	0x636E	#CJK UNIFIED IDEOGRAPH
+0x9099	0x6749	#CJK UNIFIED IDEOGRAPH
+0x909A	0x6919	#CJK UNIFIED IDEOGRAPH
+0x909B	0x83C5	#CJK UNIFIED IDEOGRAPH
+0x909C	0x9817	#CJK UNIFIED IDEOGRAPH
+0x909D	0x96C0	#CJK UNIFIED IDEOGRAPH
+0x909E	0x88FE	#CJK UNIFIED IDEOGRAPH
+0x909F	0x6F84	#CJK UNIFIED IDEOGRAPH
+0x90A0	0x647A	#CJK UNIFIED IDEOGRAPH
+0x90A1	0x5BF8	#CJK UNIFIED IDEOGRAPH
+0x90A2	0x4E16	#CJK UNIFIED IDEOGRAPH
+0x90A3	0x702C	#CJK UNIFIED IDEOGRAPH
+0x90A4	0x755D	#CJK UNIFIED IDEOGRAPH
+0x90A5	0x662F	#CJK UNIFIED IDEOGRAPH
+0x90A6	0x51C4	#CJK UNIFIED IDEOGRAPH
+0x90A7	0x5236	#CJK UNIFIED IDEOGRAPH
+0x90A8	0x52E2	#CJK UNIFIED IDEOGRAPH
+0x90A9	0x59D3	#CJK UNIFIED IDEOGRAPH
+0x90AA	0x5F81	#CJK UNIFIED IDEOGRAPH
+0x90AB	0x6027	#CJK UNIFIED IDEOGRAPH
+0x90AC	0x6210	#CJK UNIFIED IDEOGRAPH
+0x90AD	0x653F	#CJK UNIFIED IDEOGRAPH
+0x90AE	0x6574	#CJK UNIFIED IDEOGRAPH
+0x90AF	0x661F	#CJK UNIFIED IDEOGRAPH
+0x90B0	0x6674	#CJK UNIFIED IDEOGRAPH
+0x90B1	0x68F2	#CJK UNIFIED IDEOGRAPH
+0x90B2	0x6816	#CJK UNIFIED IDEOGRAPH
+0x90B3	0x6B63	#CJK UNIFIED IDEOGRAPH
+0x90B4	0x6E05	#CJK UNIFIED IDEOGRAPH
+0x90B5	0x7272	#CJK UNIFIED IDEOGRAPH
+0x90B6	0x751F	#CJK UNIFIED IDEOGRAPH
+0x90B7	0x76DB	#CJK UNIFIED IDEOGRAPH
+0x90B8	0x7CBE	#CJK UNIFIED IDEOGRAPH
+0x90B9	0x8056	#CJK UNIFIED IDEOGRAPH
+0x90BA	0x58F0	#CJK UNIFIED IDEOGRAPH
+0x90BB	0x88FD	#CJK UNIFIED IDEOGRAPH
+0x90BC	0x897F	#CJK UNIFIED IDEOGRAPH
+0x90BD	0x8AA0	#CJK UNIFIED IDEOGRAPH
+0x90BE	0x8A93	#CJK UNIFIED IDEOGRAPH
+0x90BF	0x8ACB	#CJK UNIFIED IDEOGRAPH
+0x90C0	0x901D	#CJK UNIFIED IDEOGRAPH
+0x90C1	0x9192	#CJK UNIFIED IDEOGRAPH
+0x90C2	0x9752	#CJK UNIFIED IDEOGRAPH
+0x90C3	0x9759	#CJK UNIFIED IDEOGRAPH
+0x90C4	0x6589	#CJK UNIFIED IDEOGRAPH
+0x90C5	0x7A0E	#CJK UNIFIED IDEOGRAPH
+0x90C6	0x8106	#CJK UNIFIED IDEOGRAPH
+0x90C7	0x96BB	#CJK UNIFIED IDEOGRAPH
+0x90C8	0x5E2D	#CJK UNIFIED IDEOGRAPH
+0x90C9	0x60DC	#CJK UNIFIED IDEOGRAPH
+0x90CA	0x621A	#CJK UNIFIED IDEOGRAPH
+0x90CB	0x65A5	#CJK UNIFIED IDEOGRAPH
+0x90CC	0x6614	#CJK UNIFIED IDEOGRAPH
+0x90CD	0x6790	#CJK UNIFIED IDEOGRAPH
+0x90CE	0x77F3	#CJK UNIFIED IDEOGRAPH
+0x90CF	0x7A4D	#CJK UNIFIED IDEOGRAPH
+0x90D0	0x7C4D	#CJK UNIFIED IDEOGRAPH
+0x90D1	0x7E3E	#CJK UNIFIED IDEOGRAPH
+0x90D2	0x810A	#CJK UNIFIED IDEOGRAPH
+0x90D3	0x8CAC	#CJK UNIFIED IDEOGRAPH
+0x90D4	0x8D64	#CJK UNIFIED IDEOGRAPH
+0x90D5	0x8DE1	#CJK UNIFIED IDEOGRAPH
+0x90D6	0x8E5F	#CJK UNIFIED IDEOGRAPH
+0x90D7	0x78A9	#CJK UNIFIED IDEOGRAPH
+0x90D8	0x5207	#CJK UNIFIED IDEOGRAPH
+0x90D9	0x62D9	#CJK UNIFIED IDEOGRAPH
+0x90DA	0x63A5	#CJK UNIFIED IDEOGRAPH
+0x90DB	0x6442	#CJK UNIFIED IDEOGRAPH
+0x90DC	0x6298	#CJK UNIFIED IDEOGRAPH
+0x90DD	0x8A2D	#CJK UNIFIED IDEOGRAPH
+0x90DE	0x7A83	#CJK UNIFIED IDEOGRAPH
+0x90DF	0x7BC0	#CJK UNIFIED IDEOGRAPH
+0x90E0	0x8AAC	#CJK UNIFIED IDEOGRAPH
+0x90E1	0x96EA	#CJK UNIFIED IDEOGRAPH
+0x90E2	0x7D76	#CJK UNIFIED IDEOGRAPH
+0x90E3	0x820C	#CJK UNIFIED IDEOGRAPH
+0x90E4	0x8749	#CJK UNIFIED IDEOGRAPH
+0x90E5	0x4ED9	#CJK UNIFIED IDEOGRAPH
+0x90E6	0x5148	#CJK UNIFIED IDEOGRAPH
+0x90E7	0x5343	#CJK UNIFIED IDEOGRAPH
+0x90E8	0x5360	#CJK UNIFIED IDEOGRAPH
+0x90E9	0x5BA3	#CJK UNIFIED IDEOGRAPH
+0x90EA	0x5C02	#CJK UNIFIED IDEOGRAPH
+0x90EB	0x5C16	#CJK UNIFIED IDEOGRAPH
+0x90EC	0x5DDD	#CJK UNIFIED IDEOGRAPH
+0x90ED	0x6226	#CJK UNIFIED IDEOGRAPH
+0x90EE	0x6247	#CJK UNIFIED IDEOGRAPH
+0x90EF	0x64B0	#CJK UNIFIED IDEOGRAPH
+0x90F0	0x6813	#CJK UNIFIED IDEOGRAPH
+0x90F1	0x6834	#CJK UNIFIED IDEOGRAPH
+0x90F2	0x6CC9	#CJK UNIFIED IDEOGRAPH
+0x90F3	0x6D45	#CJK UNIFIED IDEOGRAPH
+0x90F4	0x6D17	#CJK UNIFIED IDEOGRAPH
+0x90F5	0x67D3	#CJK UNIFIED IDEOGRAPH
+0x90F6	0x6F5C	#CJK UNIFIED IDEOGRAPH
+0x90F7	0x714E	#CJK UNIFIED IDEOGRAPH
+0x90F8	0x717D	#CJK UNIFIED IDEOGRAPH
+0x90F9	0x65CB	#CJK UNIFIED IDEOGRAPH
+0x90FA	0x7A7F	#CJK UNIFIED IDEOGRAPH
+0x90FB	0x7BAD	#CJK UNIFIED IDEOGRAPH
+0x90FC	0x7DDA	#CJK UNIFIED IDEOGRAPH
+0x9140	0x7E4A	#CJK UNIFIED IDEOGRAPH
+0x9141	0x7FA8	#CJK UNIFIED IDEOGRAPH
+0x9142	0x817A	#CJK UNIFIED IDEOGRAPH
+0x9143	0x821B	#CJK UNIFIED IDEOGRAPH
+0x9144	0x8239	#CJK UNIFIED IDEOGRAPH
+0x9145	0x85A6	#CJK UNIFIED IDEOGRAPH
+0x9146	0x8A6E	#CJK UNIFIED IDEOGRAPH
+0x9147	0x8CCE	#CJK UNIFIED IDEOGRAPH
+0x9148	0x8DF5	#CJK UNIFIED IDEOGRAPH
+0x9149	0x9078	#CJK UNIFIED IDEOGRAPH
+0x914A	0x9077	#CJK UNIFIED IDEOGRAPH
+0x914B	0x92AD	#CJK UNIFIED IDEOGRAPH
+0x914C	0x9291	#CJK UNIFIED IDEOGRAPH
+0x914D	0x9583	#CJK UNIFIED IDEOGRAPH
+0x914E	0x9BAE	#CJK UNIFIED IDEOGRAPH
+0x914F	0x524D	#CJK UNIFIED IDEOGRAPH
+0x9150	0x5584	#CJK UNIFIED IDEOGRAPH
+0x9151	0x6F38	#CJK UNIFIED IDEOGRAPH
+0x9152	0x7136	#CJK UNIFIED IDEOGRAPH
+0x9153	0x5168	#CJK UNIFIED IDEOGRAPH
+0x9154	0x7985	#CJK UNIFIED IDEOGRAPH
+0x9155	0x7E55	#CJK UNIFIED IDEOGRAPH
+0x9156	0x81B3	#CJK UNIFIED IDEOGRAPH
+0x9157	0x7CCE	#CJK UNIFIED IDEOGRAPH
+0x9158	0x564C	#CJK UNIFIED IDEOGRAPH
+0x9159	0x5851	#CJK UNIFIED IDEOGRAPH
+0x915A	0x5CA8	#CJK UNIFIED IDEOGRAPH
+0x915B	0x63AA	#CJK UNIFIED IDEOGRAPH
+0x915C	0x66FE	#CJK UNIFIED IDEOGRAPH
+0x915D	0x66FD	#CJK UNIFIED IDEOGRAPH
+0x915E	0x695A	#CJK UNIFIED IDEOGRAPH
+0x915F	0x72D9	#CJK UNIFIED IDEOGRAPH
+0x9160	0x758F	#CJK UNIFIED IDEOGRAPH
+0x9161	0x758E	#CJK UNIFIED IDEOGRAPH
+0x9162	0x790E	#CJK UNIFIED IDEOGRAPH
+0x9163	0x7956	#CJK UNIFIED IDEOGRAPH
+0x9164	0x79DF	#CJK UNIFIED IDEOGRAPH
+0x9165	0x7C97	#CJK UNIFIED IDEOGRAPH
+0x9166	0x7D20	#CJK UNIFIED IDEOGRAPH
+0x9167	0x7D44	#CJK UNIFIED IDEOGRAPH
+0x9168	0x8607	#CJK UNIFIED IDEOGRAPH
+0x9169	0x8A34	#CJK UNIFIED IDEOGRAPH
+0x916A	0x963B	#CJK UNIFIED IDEOGRAPH
+0x916B	0x9061	#CJK UNIFIED IDEOGRAPH
+0x916C	0x9F20	#CJK UNIFIED IDEOGRAPH
+0x916D	0x50E7	#CJK UNIFIED IDEOGRAPH
+0x916E	0x5275	#CJK UNIFIED IDEOGRAPH
+0x916F	0x53CC	#CJK UNIFIED IDEOGRAPH
+0x9170	0x53E2	#CJK UNIFIED IDEOGRAPH
+0x9171	0x5009	#CJK UNIFIED IDEOGRAPH
+0x9172	0x55AA	#CJK UNIFIED IDEOGRAPH
+0x9173	0x58EE	#CJK UNIFIED IDEOGRAPH
+0x9174	0x594F	#CJK UNIFIED IDEOGRAPH
+0x9175	0x723D	#CJK UNIFIED IDEOGRAPH
+0x9176	0x5B8B	#CJK UNIFIED IDEOGRAPH
+0x9177	0x5C64	#CJK UNIFIED IDEOGRAPH
+0x9178	0x531D	#CJK UNIFIED IDEOGRAPH
+0x9179	0x60E3	#CJK UNIFIED IDEOGRAPH
+0x917A	0x60F3	#CJK UNIFIED IDEOGRAPH
+0x917B	0x635C	#CJK UNIFIED IDEOGRAPH
+0x917C	0x6383	#CJK UNIFIED IDEOGRAPH
+0x917D	0x633F	#CJK UNIFIED IDEOGRAPH
+0x917E	0x63BB	#CJK UNIFIED IDEOGRAPH
+0x9180	0x64CD	#CJK UNIFIED IDEOGRAPH
+0x9181	0x65E9	#CJK UNIFIED IDEOGRAPH
+0x9182	0x66F9	#CJK UNIFIED IDEOGRAPH
+0x9183	0x5DE3	#CJK UNIFIED IDEOGRAPH
+0x9184	0x69CD	#CJK UNIFIED IDEOGRAPH
+0x9185	0x69FD	#CJK UNIFIED IDEOGRAPH
+0x9186	0x6F15	#CJK UNIFIED IDEOGRAPH
+0x9187	0x71E5	#CJK UNIFIED IDEOGRAPH
+0x9188	0x4E89	#CJK UNIFIED IDEOGRAPH
+0x9189	0x75E9	#CJK UNIFIED IDEOGRAPH
+0x918A	0x76F8	#CJK UNIFIED IDEOGRAPH
+0x918B	0x7A93	#CJK UNIFIED IDEOGRAPH
+0x918C	0x7CDF	#CJK UNIFIED IDEOGRAPH
+0x918D	0x7DCF	#CJK UNIFIED IDEOGRAPH
+0x918E	0x7D9C	#CJK UNIFIED IDEOGRAPH
+0x918F	0x8061	#CJK UNIFIED IDEOGRAPH
+0x9190	0x8349	#CJK UNIFIED IDEOGRAPH
+0x9191	0x8358	#CJK UNIFIED IDEOGRAPH
+0x9192	0x846C	#CJK UNIFIED IDEOGRAPH
+0x9193	0x84BC	#CJK UNIFIED IDEOGRAPH
+0x9194	0x85FB	#CJK UNIFIED IDEOGRAPH
+0x9195	0x88C5	#CJK UNIFIED IDEOGRAPH
+0x9196	0x8D70	#CJK UNIFIED IDEOGRAPH
+0x9197	0x9001	#CJK UNIFIED IDEOGRAPH
+0x9198	0x906D	#CJK UNIFIED IDEOGRAPH
+0x9199	0x9397	#CJK UNIFIED IDEOGRAPH
+0x919A	0x971C	#CJK UNIFIED IDEOGRAPH
+0x919B	0x9A12	#CJK UNIFIED IDEOGRAPH
+0x919C	0x50CF	#CJK UNIFIED IDEOGRAPH
+0x919D	0x5897	#CJK UNIFIED IDEOGRAPH
+0x919E	0x618E	#CJK UNIFIED IDEOGRAPH
+0x919F	0x81D3	#CJK UNIFIED IDEOGRAPH
+0x91A0	0x8535	#CJK UNIFIED IDEOGRAPH
+0x91A1	0x8D08	#CJK UNIFIED IDEOGRAPH
+0x91A2	0x9020	#CJK UNIFIED IDEOGRAPH
+0x91A3	0x4FC3	#CJK UNIFIED IDEOGRAPH
+0x91A4	0x5074	#CJK UNIFIED IDEOGRAPH
+0x91A5	0x5247	#CJK UNIFIED IDEOGRAPH
+0x91A6	0x5373	#CJK UNIFIED IDEOGRAPH
+0x91A7	0x606F	#CJK UNIFIED IDEOGRAPH
+0x91A8	0x6349	#CJK UNIFIED IDEOGRAPH
+0x91A9	0x675F	#CJK UNIFIED IDEOGRAPH
+0x91AA	0x6E2C	#CJK UNIFIED IDEOGRAPH
+0x91AB	0x8DB3	#CJK UNIFIED IDEOGRAPH
+0x91AC	0x901F	#CJK UNIFIED IDEOGRAPH
+0x91AD	0x4FD7	#CJK UNIFIED IDEOGRAPH
+0x91AE	0x5C5E	#CJK UNIFIED IDEOGRAPH
+0x91AF	0x8CCA	#CJK UNIFIED IDEOGRAPH
+0x91B0	0x65CF	#CJK UNIFIED IDEOGRAPH
+0x91B1	0x7D9A	#CJK UNIFIED IDEOGRAPH
+0x91B2	0x5352	#CJK UNIFIED IDEOGRAPH
+0x91B3	0x8896	#CJK UNIFIED IDEOGRAPH
+0x91B4	0x5176	#CJK UNIFIED IDEOGRAPH
+0x91B5	0x63C3	#CJK UNIFIED IDEOGRAPH
+0x91B6	0x5B58	#CJK UNIFIED IDEOGRAPH
+0x91B7	0x5B6B	#CJK UNIFIED IDEOGRAPH
+0x91B8	0x5C0A	#CJK UNIFIED IDEOGRAPH
+0x91B9	0x640D	#CJK UNIFIED IDEOGRAPH
+0x91BA	0x6751	#CJK UNIFIED IDEOGRAPH
+0x91BB	0x905C	#CJK UNIFIED IDEOGRAPH
+0x91BC	0x4ED6	#CJK UNIFIED IDEOGRAPH
+0x91BD	0x591A	#CJK UNIFIED IDEOGRAPH
+0x91BE	0x592A	#CJK UNIFIED IDEOGRAPH
+0x91BF	0x6C70	#CJK UNIFIED IDEOGRAPH
+0x91C0	0x8A51	#CJK UNIFIED IDEOGRAPH
+0x91C1	0x553E	#CJK UNIFIED IDEOGRAPH
+0x91C2	0x5815	#CJK UNIFIED IDEOGRAPH
+0x91C3	0x59A5	#CJK UNIFIED IDEOGRAPH
+0x91C4	0x60F0	#CJK UNIFIED IDEOGRAPH
+0x91C5	0x6253	#CJK UNIFIED IDEOGRAPH
+0x91C6	0x67C1	#CJK UNIFIED IDEOGRAPH
+0x91C7	0x8235	#CJK UNIFIED IDEOGRAPH
+0x91C8	0x6955	#CJK UNIFIED IDEOGRAPH
+0x91C9	0x9640	#CJK UNIFIED IDEOGRAPH
+0x91CA	0x99C4	#CJK UNIFIED IDEOGRAPH
+0x91CB	0x9A28	#CJK UNIFIED IDEOGRAPH
+0x91CC	0x4F53	#CJK UNIFIED IDEOGRAPH
+0x91CD	0x5806	#CJK UNIFIED IDEOGRAPH
+0x91CE	0x5BFE	#CJK UNIFIED IDEOGRAPH
+0x91CF	0x8010	#CJK UNIFIED IDEOGRAPH
+0x91D0	0x5CB1	#CJK UNIFIED IDEOGRAPH
+0x91D1	0x5E2F	#CJK UNIFIED IDEOGRAPH
+0x91D2	0x5F85	#CJK UNIFIED IDEOGRAPH
+0x91D3	0x6020	#CJK UNIFIED IDEOGRAPH
+0x91D4	0x614B	#CJK UNIFIED IDEOGRAPH
+0x91D5	0x6234	#CJK UNIFIED IDEOGRAPH
+0x91D6	0x66FF	#CJK UNIFIED IDEOGRAPH
+0x91D7	0x6CF0	#CJK UNIFIED IDEOGRAPH
+0x91D8	0x6EDE	#CJK UNIFIED IDEOGRAPH
+0x91D9	0x80CE	#CJK UNIFIED IDEOGRAPH
+0x91DA	0x817F	#CJK UNIFIED IDEOGRAPH
+0x91DB	0x82D4	#CJK UNIFIED IDEOGRAPH
+0x91DC	0x888B	#CJK UNIFIED IDEOGRAPH
+0x91DD	0x8CB8	#CJK UNIFIED IDEOGRAPH
+0x91DE	0x9000	#CJK UNIFIED IDEOGRAPH
+0x91DF	0x902E	#CJK UNIFIED IDEOGRAPH
+0x91E0	0x968A	#CJK UNIFIED IDEOGRAPH
+0x91E1	0x9EDB	#CJK UNIFIED IDEOGRAPH
+0x91E2	0x9BDB	#CJK UNIFIED IDEOGRAPH
+0x91E3	0x4EE3	#CJK UNIFIED IDEOGRAPH
+0x91E4	0x53F0	#CJK UNIFIED IDEOGRAPH
+0x91E5	0x5927	#CJK UNIFIED IDEOGRAPH
+0x91E6	0x7B2C	#CJK UNIFIED IDEOGRAPH
+0x91E7	0x918D	#CJK UNIFIED IDEOGRAPH
+0x91E8	0x984C	#CJK UNIFIED IDEOGRAPH
+0x91E9	0x9DF9	#CJK UNIFIED IDEOGRAPH
+0x91EA	0x6EDD	#CJK UNIFIED IDEOGRAPH
+0x91EB	0x7027	#CJK UNIFIED IDEOGRAPH
+0x91EC	0x5353	#CJK UNIFIED IDEOGRAPH
+0x91ED	0x5544	#CJK UNIFIED IDEOGRAPH
+0x91EE	0x5B85	#CJK UNIFIED IDEOGRAPH
+0x91EF	0x6258	#CJK UNIFIED IDEOGRAPH
+0x91F0	0x629E	#CJK UNIFIED IDEOGRAPH
+0x91F1	0x62D3	#CJK UNIFIED IDEOGRAPH
+0x91F2	0x6CA2	#CJK UNIFIED IDEOGRAPH
+0x91F3	0x6FEF	#CJK UNIFIED IDEOGRAPH
+0x91F4	0x7422	#CJK UNIFIED IDEOGRAPH
+0x91F5	0x8A17	#CJK UNIFIED IDEOGRAPH
+0x91F6	0x9438	#CJK UNIFIED IDEOGRAPH
+0x91F7	0x6FC1	#CJK UNIFIED IDEOGRAPH
+0x91F8	0x8AFE	#CJK UNIFIED IDEOGRAPH
+0x91F9	0x8338	#CJK UNIFIED IDEOGRAPH
+0x91FA	0x51E7	#CJK UNIFIED IDEOGRAPH
+0x91FB	0x86F8	#CJK UNIFIED IDEOGRAPH
+0x91FC	0x53EA	#CJK UNIFIED IDEOGRAPH
+0x9240	0x53E9	#CJK UNIFIED IDEOGRAPH
+0x9241	0x4F46	#CJK UNIFIED IDEOGRAPH
+0x9242	0x9054	#CJK UNIFIED IDEOGRAPH
+0x9243	0x8FB0	#CJK UNIFIED IDEOGRAPH
+0x9244	0x596A	#CJK UNIFIED IDEOGRAPH
+0x9245	0x8131	#CJK UNIFIED IDEOGRAPH
+0x9246	0x5DFD	#CJK UNIFIED IDEOGRAPH
+0x9247	0x7AEA	#CJK UNIFIED IDEOGRAPH
+0x9248	0x8FBF	#CJK UNIFIED IDEOGRAPH
+0x9249	0x68DA	#CJK UNIFIED IDEOGRAPH
+0x924A	0x8C37	#CJK UNIFIED IDEOGRAPH
+0x924B	0x72F8	#CJK UNIFIED IDEOGRAPH
+0x924C	0x9C48	#CJK UNIFIED IDEOGRAPH
+0x924D	0x6A3D	#CJK UNIFIED IDEOGRAPH
+0x924E	0x8AB0	#CJK UNIFIED IDEOGRAPH
+0x924F	0x4E39	#CJK UNIFIED IDEOGRAPH
+0x9250	0x5358	#CJK UNIFIED IDEOGRAPH
+0x9251	0x5606	#CJK UNIFIED IDEOGRAPH
+0x9252	0x5766	#CJK UNIFIED IDEOGRAPH
+0x9253	0x62C5	#CJK UNIFIED IDEOGRAPH
+0x9254	0x63A2	#CJK UNIFIED IDEOGRAPH
+0x9255	0x65E6	#CJK UNIFIED IDEOGRAPH
+0x9256	0x6B4E	#CJK UNIFIED IDEOGRAPH
+0x9257	0x6DE1	#CJK UNIFIED IDEOGRAPH
+0x9258	0x6E5B	#CJK UNIFIED IDEOGRAPH
+0x9259	0x70AD	#CJK UNIFIED IDEOGRAPH
+0x925A	0x77ED	#CJK UNIFIED IDEOGRAPH
+0x925B	0x7AEF	#CJK UNIFIED IDEOGRAPH
+0x925C	0x7BAA	#CJK UNIFIED IDEOGRAPH
+0x925D	0x7DBB	#CJK UNIFIED IDEOGRAPH
+0x925E	0x803D	#CJK UNIFIED IDEOGRAPH
+0x925F	0x80C6	#CJK UNIFIED IDEOGRAPH
+0x9260	0x86CB	#CJK UNIFIED IDEOGRAPH
+0x9261	0x8A95	#CJK UNIFIED IDEOGRAPH
+0x9262	0x935B	#CJK UNIFIED IDEOGRAPH
+0x9263	0x56E3	#CJK UNIFIED IDEOGRAPH
+0x9264	0x58C7	#CJK UNIFIED IDEOGRAPH
+0x9265	0x5F3E	#CJK UNIFIED IDEOGRAPH
+0x9266	0x65AD	#CJK UNIFIED IDEOGRAPH
+0x9267	0x6696	#CJK UNIFIED IDEOGRAPH
+0x9268	0x6A80	#CJK UNIFIED IDEOGRAPH
+0x9269	0x6BB5	#CJK UNIFIED IDEOGRAPH
+0x926A	0x7537	#CJK UNIFIED IDEOGRAPH
+0x926B	0x8AC7	#CJK UNIFIED IDEOGRAPH
+0x926C	0x5024	#CJK UNIFIED IDEOGRAPH
+0x926D	0x77E5	#CJK UNIFIED IDEOGRAPH
+0x926E	0x5730	#CJK UNIFIED IDEOGRAPH
+0x926F	0x5F1B	#CJK UNIFIED IDEOGRAPH
+0x9270	0x6065	#CJK UNIFIED IDEOGRAPH
+0x9271	0x667A	#CJK UNIFIED IDEOGRAPH
+0x9272	0x6C60	#CJK UNIFIED IDEOGRAPH
+0x9273	0x75F4	#CJK UNIFIED IDEOGRAPH
+0x9274	0x7A1A	#CJK UNIFIED IDEOGRAPH
+0x9275	0x7F6E	#CJK UNIFIED IDEOGRAPH
+0x9276	0x81F4	#CJK UNIFIED IDEOGRAPH
+0x9277	0x8718	#CJK UNIFIED IDEOGRAPH
+0x9278	0x9045	#CJK UNIFIED IDEOGRAPH
+0x9279	0x99B3	#CJK UNIFIED IDEOGRAPH
+0x927A	0x7BC9	#CJK UNIFIED IDEOGRAPH
+0x927B	0x755C	#CJK UNIFIED IDEOGRAPH
+0x927C	0x7AF9	#CJK UNIFIED IDEOGRAPH
+0x927D	0x7B51	#CJK UNIFIED IDEOGRAPH
+0x927E	0x84C4	#CJK UNIFIED IDEOGRAPH
+0x9280	0x9010	#CJK UNIFIED IDEOGRAPH
+0x9281	0x79E9	#CJK UNIFIED IDEOGRAPH
+0x9282	0x7A92	#CJK UNIFIED IDEOGRAPH
+0x9283	0x8336	#CJK UNIFIED IDEOGRAPH
+0x9284	0x5AE1	#CJK UNIFIED IDEOGRAPH
+0x9285	0x7740	#CJK UNIFIED IDEOGRAPH
+0x9286	0x4E2D	#CJK UNIFIED IDEOGRAPH
+0x9287	0x4EF2	#CJK UNIFIED IDEOGRAPH
+0x9288	0x5B99	#CJK UNIFIED IDEOGRAPH
+0x9289	0x5FE0	#CJK UNIFIED IDEOGRAPH
+0x928A	0x62BD	#CJK UNIFIED IDEOGRAPH
+0x928B	0x663C	#CJK UNIFIED IDEOGRAPH
+0x928C	0x67F1	#CJK UNIFIED IDEOGRAPH
+0x928D	0x6CE8	#CJK UNIFIED IDEOGRAPH
+0x928E	0x866B	#CJK UNIFIED IDEOGRAPH
+0x928F	0x8877	#CJK UNIFIED IDEOGRAPH
+0x9290	0x8A3B	#CJK UNIFIED IDEOGRAPH
+0x9291	0x914E	#CJK UNIFIED IDEOGRAPH
+0x9292	0x92F3	#CJK UNIFIED IDEOGRAPH
+0x9293	0x99D0	#CJK UNIFIED IDEOGRAPH
+0x9294	0x6A17	#CJK UNIFIED IDEOGRAPH
+0x9295	0x7026	#CJK UNIFIED IDEOGRAPH
+0x9296	0x732A	#CJK UNIFIED IDEOGRAPH
+0x9297	0x82E7	#CJK UNIFIED IDEOGRAPH
+0x9298	0x8457	#CJK UNIFIED IDEOGRAPH
+0x9299	0x8CAF	#CJK UNIFIED IDEOGRAPH
+0x929A	0x4E01	#CJK UNIFIED IDEOGRAPH
+0x929B	0x5146	#CJK UNIFIED IDEOGRAPH
+0x929C	0x51CB	#CJK UNIFIED IDEOGRAPH
+0x929D	0x558B	#CJK UNIFIED IDEOGRAPH
+0x929E	0x5BF5	#CJK UNIFIED IDEOGRAPH
+0x929F	0x5E16	#CJK UNIFIED IDEOGRAPH
+0x92A0	0x5E33	#CJK UNIFIED IDEOGRAPH
+0x92A1	0x5E81	#CJK UNIFIED IDEOGRAPH
+0x92A2	0x5F14	#CJK UNIFIED IDEOGRAPH
+0x92A3	0x5F35	#CJK UNIFIED IDEOGRAPH
+0x92A4	0x5F6B	#CJK UNIFIED IDEOGRAPH
+0x92A5	0x5FB4	#CJK UNIFIED IDEOGRAPH
+0x92A6	0x61F2	#CJK UNIFIED IDEOGRAPH
+0x92A7	0x6311	#CJK UNIFIED IDEOGRAPH
+0x92A8	0x66A2	#CJK UNIFIED IDEOGRAPH
+0x92A9	0x671D	#CJK UNIFIED IDEOGRAPH
+0x92AA	0x6F6E	#CJK UNIFIED IDEOGRAPH
+0x92AB	0x7252	#CJK UNIFIED IDEOGRAPH
+0x92AC	0x753A	#CJK UNIFIED IDEOGRAPH
+0x92AD	0x773A	#CJK UNIFIED IDEOGRAPH
+0x92AE	0x8074	#CJK UNIFIED IDEOGRAPH
+0x92AF	0x8139	#CJK UNIFIED IDEOGRAPH
+0x92B0	0x8178	#CJK UNIFIED IDEOGRAPH
+0x92B1	0x8776	#CJK UNIFIED IDEOGRAPH
+0x92B2	0x8ABF	#CJK UNIFIED IDEOGRAPH
+0x92B3	0x8ADC	#CJK UNIFIED IDEOGRAPH
+0x92B4	0x8D85	#CJK UNIFIED IDEOGRAPH
+0x92B5	0x8DF3	#CJK UNIFIED IDEOGRAPH
+0x92B6	0x929A	#CJK UNIFIED IDEOGRAPH
+0x92B7	0x9577	#CJK UNIFIED IDEOGRAPH
+0x92B8	0x9802	#CJK UNIFIED IDEOGRAPH
+0x92B9	0x9CE5	#CJK UNIFIED IDEOGRAPH
+0x92BA	0x52C5	#CJK UNIFIED IDEOGRAPH
+0x92BB	0x6357	#CJK UNIFIED IDEOGRAPH
+0x92BC	0x76F4	#CJK UNIFIED IDEOGRAPH
+0x92BD	0x6715	#CJK UNIFIED IDEOGRAPH
+0x92BE	0x6C88	#CJK UNIFIED IDEOGRAPH
+0x92BF	0x73CD	#CJK UNIFIED IDEOGRAPH
+0x92C0	0x8CC3	#CJK UNIFIED IDEOGRAPH
+0x92C1	0x93AE	#CJK UNIFIED IDEOGRAPH
+0x92C2	0x9673	#CJK UNIFIED IDEOGRAPH
+0x92C3	0x6D25	#CJK UNIFIED IDEOGRAPH
+0x92C4	0x589C	#CJK UNIFIED IDEOGRAPH
+0x92C5	0x690E	#CJK UNIFIED IDEOGRAPH
+0x92C6	0x69CC	#CJK UNIFIED IDEOGRAPH
+0x92C7	0x8FFD	#CJK UNIFIED IDEOGRAPH
+0x92C8	0x939A	#CJK UNIFIED IDEOGRAPH
+0x92C9	0x75DB	#CJK UNIFIED IDEOGRAPH
+0x92CA	0x901A	#CJK UNIFIED IDEOGRAPH
+0x92CB	0x585A	#CJK UNIFIED IDEOGRAPH
+0x92CC	0x6802	#CJK UNIFIED IDEOGRAPH
+0x92CD	0x63B4	#CJK UNIFIED IDEOGRAPH
+0x92CE	0x69FB	#CJK UNIFIED IDEOGRAPH
+0x92CF	0x4F43	#CJK UNIFIED IDEOGRAPH
+0x92D0	0x6F2C	#CJK UNIFIED IDEOGRAPH
+0x92D1	0x67D8	#CJK UNIFIED IDEOGRAPH
+0x92D2	0x8FBB	#CJK UNIFIED IDEOGRAPH
+0x92D3	0x8526	#CJK UNIFIED IDEOGRAPH
+0x92D4	0x7DB4	#CJK UNIFIED IDEOGRAPH
+0x92D5	0x9354	#CJK UNIFIED IDEOGRAPH
+0x92D6	0x693F	#CJK UNIFIED IDEOGRAPH
+0x92D7	0x6F70	#CJK UNIFIED IDEOGRAPH
+0x92D8	0x576A	#CJK UNIFIED IDEOGRAPH
+0x92D9	0x58F7	#CJK UNIFIED IDEOGRAPH
+0x92DA	0x5B2C	#CJK UNIFIED IDEOGRAPH
+0x92DB	0x7D2C	#CJK UNIFIED IDEOGRAPH
+0x92DC	0x722A	#CJK UNIFIED IDEOGRAPH
+0x92DD	0x540A	#CJK UNIFIED IDEOGRAPH
+0x92DE	0x91E3	#CJK UNIFIED IDEOGRAPH
+0x92DF	0x9DB4	#CJK UNIFIED IDEOGRAPH
+0x92E0	0x4EAD	#CJK UNIFIED IDEOGRAPH
+0x92E1	0x4F4E	#CJK UNIFIED IDEOGRAPH
+0x92E2	0x505C	#CJK UNIFIED IDEOGRAPH
+0x92E3	0x5075	#CJK UNIFIED IDEOGRAPH
+0x92E4	0x5243	#CJK UNIFIED IDEOGRAPH
+0x92E5	0x8C9E	#CJK UNIFIED IDEOGRAPH
+0x92E6	0x5448	#CJK UNIFIED IDEOGRAPH
+0x92E7	0x5824	#CJK UNIFIED IDEOGRAPH
+0x92E8	0x5B9A	#CJK UNIFIED IDEOGRAPH
+0x92E9	0x5E1D	#CJK UNIFIED IDEOGRAPH
+0x92EA	0x5E95	#CJK UNIFIED IDEOGRAPH
+0x92EB	0x5EAD	#CJK UNIFIED IDEOGRAPH
+0x92EC	0x5EF7	#CJK UNIFIED IDEOGRAPH
+0x92ED	0x5F1F	#CJK UNIFIED IDEOGRAPH
+0x92EE	0x608C	#CJK UNIFIED IDEOGRAPH
+0x92EF	0x62B5	#CJK UNIFIED IDEOGRAPH
+0x92F0	0x633A	#CJK UNIFIED IDEOGRAPH
+0x92F1	0x63D0	#CJK UNIFIED IDEOGRAPH
+0x92F2	0x68AF	#CJK UNIFIED IDEOGRAPH
+0x92F3	0x6C40	#CJK UNIFIED IDEOGRAPH
+0x92F4	0x7887	#CJK UNIFIED IDEOGRAPH
+0x92F5	0x798E	#CJK UNIFIED IDEOGRAPH
+0x92F6	0x7A0B	#CJK UNIFIED IDEOGRAPH
+0x92F7	0x7DE0	#CJK UNIFIED IDEOGRAPH
+0x92F8	0x8247	#CJK UNIFIED IDEOGRAPH
+0x92F9	0x8A02	#CJK UNIFIED IDEOGRAPH
+0x92FA	0x8AE6	#CJK UNIFIED IDEOGRAPH
+0x92FB	0x8E44	#CJK UNIFIED IDEOGRAPH
+0x92FC	0x9013	#CJK UNIFIED IDEOGRAPH
+0x9340	0x90B8	#CJK UNIFIED IDEOGRAPH
+0x9341	0x912D	#CJK UNIFIED IDEOGRAPH
+0x9342	0x91D8	#CJK UNIFIED IDEOGRAPH
+0x9343	0x9F0E	#CJK UNIFIED IDEOGRAPH
+0x9344	0x6CE5	#CJK UNIFIED IDEOGRAPH
+0x9345	0x6458	#CJK UNIFIED IDEOGRAPH
+0x9346	0x64E2	#CJK UNIFIED IDEOGRAPH
+0x9347	0x6575	#CJK UNIFIED IDEOGRAPH
+0x9348	0x6EF4	#CJK UNIFIED IDEOGRAPH
+0x9349	0x7684	#CJK UNIFIED IDEOGRAPH
+0x934A	0x7B1B	#CJK UNIFIED IDEOGRAPH
+0x934B	0x9069	#CJK UNIFIED IDEOGRAPH
+0x934C	0x93D1	#CJK UNIFIED IDEOGRAPH
+0x934D	0x6EBA	#CJK UNIFIED IDEOGRAPH
+0x934E	0x54F2	#CJK UNIFIED IDEOGRAPH
+0x934F	0x5FB9	#CJK UNIFIED IDEOGRAPH
+0x9350	0x64A4	#CJK UNIFIED IDEOGRAPH
+0x9351	0x8F4D	#CJK UNIFIED IDEOGRAPH
+0x9352	0x8FED	#CJK UNIFIED IDEOGRAPH
+0x9353	0x9244	#CJK UNIFIED IDEOGRAPH
+0x9354	0x5178	#CJK UNIFIED IDEOGRAPH
+0x9355	0x586B	#CJK UNIFIED IDEOGRAPH
+0x9356	0x5929	#CJK UNIFIED IDEOGRAPH
+0x9357	0x5C55	#CJK UNIFIED IDEOGRAPH
+0x9358	0x5E97	#CJK UNIFIED IDEOGRAPH
+0x9359	0x6DFB	#CJK UNIFIED IDEOGRAPH
+0x935A	0x7E8F	#CJK UNIFIED IDEOGRAPH
+0x935B	0x751C	#CJK UNIFIED IDEOGRAPH
+0x935C	0x8CBC	#CJK UNIFIED IDEOGRAPH
+0x935D	0x8EE2	#CJK UNIFIED IDEOGRAPH
+0x935E	0x985B	#CJK UNIFIED IDEOGRAPH
+0x935F	0x70B9	#CJK UNIFIED IDEOGRAPH
+0x9360	0x4F1D	#CJK UNIFIED IDEOGRAPH
+0x9361	0x6BBF	#CJK UNIFIED IDEOGRAPH
+0x9362	0x6FB1	#CJK UNIFIED IDEOGRAPH
+0x9363	0x7530	#CJK UNIFIED IDEOGRAPH
+0x9364	0x96FB	#CJK UNIFIED IDEOGRAPH
+0x9365	0x514E	#CJK UNIFIED IDEOGRAPH
+0x9366	0x5410	#CJK UNIFIED IDEOGRAPH
+0x9367	0x5835	#CJK UNIFIED IDEOGRAPH
+0x9368	0x5857	#CJK UNIFIED IDEOGRAPH
+0x9369	0x59AC	#CJK UNIFIED IDEOGRAPH
+0x936A	0x5C60	#CJK UNIFIED IDEOGRAPH
+0x936B	0x5F92	#CJK UNIFIED IDEOGRAPH
+0x936C	0x6597	#CJK UNIFIED IDEOGRAPH
+0x936D	0x675C	#CJK UNIFIED IDEOGRAPH
+0x936E	0x6E21	#CJK UNIFIED IDEOGRAPH
+0x936F	0x767B	#CJK UNIFIED IDEOGRAPH
+0x9370	0x83DF	#CJK UNIFIED IDEOGRAPH
+0x9371	0x8CED	#CJK UNIFIED IDEOGRAPH
+0x9372	0x9014	#CJK UNIFIED IDEOGRAPH
+0x9373	0x90FD	#CJK UNIFIED IDEOGRAPH
+0x9374	0x934D	#CJK UNIFIED IDEOGRAPH
+0x9375	0x7825	#CJK UNIFIED IDEOGRAPH
+0x9376	0x783A	#CJK UNIFIED IDEOGRAPH
+0x9377	0x52AA	#CJK UNIFIED IDEOGRAPH
+0x9378	0x5EA6	#CJK UNIFIED IDEOGRAPH
+0x9379	0x571F	#CJK UNIFIED IDEOGRAPH
+0x937A	0x5974	#CJK UNIFIED IDEOGRAPH
+0x937B	0x6012	#CJK UNIFIED IDEOGRAPH
+0x937C	0x5012	#CJK UNIFIED IDEOGRAPH
+0x937D	0x515A	#CJK UNIFIED IDEOGRAPH
+0x937E	0x51AC	#CJK UNIFIED IDEOGRAPH
+0x9380	0x51CD	#CJK UNIFIED IDEOGRAPH
+0x9381	0x5200	#CJK UNIFIED IDEOGRAPH
+0x9382	0x5510	#CJK UNIFIED IDEOGRAPH
+0x9383	0x5854	#CJK UNIFIED IDEOGRAPH
+0x9384	0x5858	#CJK UNIFIED IDEOGRAPH
+0x9385	0x5957	#CJK UNIFIED IDEOGRAPH
+0x9386	0x5B95	#CJK UNIFIED IDEOGRAPH
+0x9387	0x5CF6	#CJK UNIFIED IDEOGRAPH
+0x9388	0x5D8B	#CJK UNIFIED IDEOGRAPH
+0x9389	0x60BC	#CJK UNIFIED IDEOGRAPH
+0x938A	0x6295	#CJK UNIFIED IDEOGRAPH
+0x938B	0x642D	#CJK UNIFIED IDEOGRAPH
+0x938C	0x6771	#CJK UNIFIED IDEOGRAPH
+0x938D	0x6843	#CJK UNIFIED IDEOGRAPH
+0x938E	0x68BC	#CJK UNIFIED IDEOGRAPH
+0x938F	0x68DF	#CJK UNIFIED IDEOGRAPH
+0x9390	0x76D7	#CJK UNIFIED IDEOGRAPH
+0x9391	0x6DD8	#CJK UNIFIED IDEOGRAPH
+0x9392	0x6E6F	#CJK UNIFIED IDEOGRAPH
+0x9393	0x6D9B	#CJK UNIFIED IDEOGRAPH
+0x9394	0x706F	#CJK UNIFIED IDEOGRAPH
+0x9395	0x71C8	#CJK UNIFIED IDEOGRAPH
+0x9396	0x5F53	#CJK UNIFIED IDEOGRAPH
+0x9397	0x75D8	#CJK UNIFIED IDEOGRAPH
+0x9398	0x7977	#CJK UNIFIED IDEOGRAPH
+0x9399	0x7B49	#CJK UNIFIED IDEOGRAPH
+0x939A	0x7B54	#CJK UNIFIED IDEOGRAPH
+0x939B	0x7B52	#CJK UNIFIED IDEOGRAPH
+0x939C	0x7CD6	#CJK UNIFIED IDEOGRAPH
+0x939D	0x7D71	#CJK UNIFIED IDEOGRAPH
+0x939E	0x5230	#CJK UNIFIED IDEOGRAPH
+0x939F	0x8463	#CJK UNIFIED IDEOGRAPH
+0x93A0	0x8569	#CJK UNIFIED IDEOGRAPH
+0x93A1	0x85E4	#CJK UNIFIED IDEOGRAPH
+0x93A2	0x8A0E	#CJK UNIFIED IDEOGRAPH
+0x93A3	0x8B04	#CJK UNIFIED IDEOGRAPH
+0x93A4	0x8C46	#CJK UNIFIED IDEOGRAPH
+0x93A5	0x8E0F	#CJK UNIFIED IDEOGRAPH
+0x93A6	0x9003	#CJK UNIFIED IDEOGRAPH
+0x93A7	0x900F	#CJK UNIFIED IDEOGRAPH
+0x93A8	0x9419	#CJK UNIFIED IDEOGRAPH
+0x93A9	0x9676	#CJK UNIFIED IDEOGRAPH
+0x93AA	0x982D	#CJK UNIFIED IDEOGRAPH
+0x93AB	0x9A30	#CJK UNIFIED IDEOGRAPH
+0x93AC	0x95D8	#CJK UNIFIED IDEOGRAPH
+0x93AD	0x50CD	#CJK UNIFIED IDEOGRAPH
+0x93AE	0x52D5	#CJK UNIFIED IDEOGRAPH
+0x93AF	0x540C	#CJK UNIFIED IDEOGRAPH
+0x93B0	0x5802	#CJK UNIFIED IDEOGRAPH
+0x93B1	0x5C0E	#CJK UNIFIED IDEOGRAPH
+0x93B2	0x61A7	#CJK UNIFIED IDEOGRAPH
+0x93B3	0x649E	#CJK UNIFIED IDEOGRAPH
+0x93B4	0x6D1E	#CJK UNIFIED IDEOGRAPH
+0x93B5	0x77B3	#CJK UNIFIED IDEOGRAPH
+0x93B6	0x7AE5	#CJK UNIFIED IDEOGRAPH
+0x93B7	0x80F4	#CJK UNIFIED IDEOGRAPH
+0x93B8	0x8404	#CJK UNIFIED IDEOGRAPH
+0x93B9	0x9053	#CJK UNIFIED IDEOGRAPH
+0x93BA	0x9285	#CJK UNIFIED IDEOGRAPH
+0x93BB	0x5CE0	#CJK UNIFIED IDEOGRAPH
+0x93BC	0x9D07	#CJK UNIFIED IDEOGRAPH
+0x93BD	0x533F	#CJK UNIFIED IDEOGRAPH
+0x93BE	0x5F97	#CJK UNIFIED IDEOGRAPH
+0x93BF	0x5FB3	#CJK UNIFIED IDEOGRAPH
+0x93C0	0x6D9C	#CJK UNIFIED IDEOGRAPH
+0x93C1	0x7279	#CJK UNIFIED IDEOGRAPH
+0x93C2	0x7763	#CJK UNIFIED IDEOGRAPH
+0x93C3	0x79BF	#CJK UNIFIED IDEOGRAPH
+0x93C4	0x7BE4	#CJK UNIFIED IDEOGRAPH
+0x93C5	0x6BD2	#CJK UNIFIED IDEOGRAPH
+0x93C6	0x72EC	#CJK UNIFIED IDEOGRAPH
+0x93C7	0x8AAD	#CJK UNIFIED IDEOGRAPH
+0x93C8	0x6803	#CJK UNIFIED IDEOGRAPH
+0x93C9	0x6A61	#CJK UNIFIED IDEOGRAPH
+0x93CA	0x51F8	#CJK UNIFIED IDEOGRAPH
+0x93CB	0x7A81	#CJK UNIFIED IDEOGRAPH
+0x93CC	0x6934	#CJK UNIFIED IDEOGRAPH
+0x93CD	0x5C4A	#CJK UNIFIED IDEOGRAPH
+0x93CE	0x9CF6	#CJK UNIFIED IDEOGRAPH
+0x93CF	0x82EB	#CJK UNIFIED IDEOGRAPH
+0x93D0	0x5BC5	#CJK UNIFIED IDEOGRAPH
+0x93D1	0x9149	#CJK UNIFIED IDEOGRAPH
+0x93D2	0x701E	#CJK UNIFIED IDEOGRAPH
+0x93D3	0x5678	#CJK UNIFIED IDEOGRAPH
+0x93D4	0x5C6F	#CJK UNIFIED IDEOGRAPH
+0x93D5	0x60C7	#CJK UNIFIED IDEOGRAPH
+0x93D6	0x6566	#CJK UNIFIED IDEOGRAPH
+0x93D7	0x6C8C	#CJK UNIFIED IDEOGRAPH
+0x93D8	0x8C5A	#CJK UNIFIED IDEOGRAPH
+0x93D9	0x9041	#CJK UNIFIED IDEOGRAPH
+0x93DA	0x9813	#CJK UNIFIED IDEOGRAPH
+0x93DB	0x5451	#CJK UNIFIED IDEOGRAPH
+0x93DC	0x66C7	#CJK UNIFIED IDEOGRAPH
+0x93DD	0x920D	#CJK UNIFIED IDEOGRAPH
+0x93DE	0x5948	#CJK UNIFIED IDEOGRAPH
+0x93DF	0x90A3	#CJK UNIFIED IDEOGRAPH
+0x93E0	0x5185	#CJK UNIFIED IDEOGRAPH
+0x93E1	0x4E4D	#CJK UNIFIED IDEOGRAPH
+0x93E2	0x51EA	#CJK UNIFIED IDEOGRAPH
+0x93E3	0x8599	#CJK UNIFIED IDEOGRAPH
+0x93E4	0x8B0E	#CJK UNIFIED IDEOGRAPH
+0x93E5	0x7058	#CJK UNIFIED IDEOGRAPH
+0x93E6	0x637A	#CJK UNIFIED IDEOGRAPH
+0x93E7	0x934B	#CJK UNIFIED IDEOGRAPH
+0x93E8	0x6962	#CJK UNIFIED IDEOGRAPH
+0x93E9	0x99B4	#CJK UNIFIED IDEOGRAPH
+0x93EA	0x7E04	#CJK UNIFIED IDEOGRAPH
+0x93EB	0x7577	#CJK UNIFIED IDEOGRAPH
+0x93EC	0x5357	#CJK UNIFIED IDEOGRAPH
+0x93ED	0x6960	#CJK UNIFIED IDEOGRAPH
+0x93EE	0x8EDF	#CJK UNIFIED IDEOGRAPH
+0x93EF	0x96E3	#CJK UNIFIED IDEOGRAPH
+0x93F0	0x6C5D	#CJK UNIFIED IDEOGRAPH
+0x93F1	0x4E8C	#CJK UNIFIED IDEOGRAPH
+0x93F2	0x5C3C	#CJK UNIFIED IDEOGRAPH
+0x93F3	0x5F10	#CJK UNIFIED IDEOGRAPH
+0x93F4	0x8FE9	#CJK UNIFIED IDEOGRAPH
+0x93F5	0x5302	#CJK UNIFIED IDEOGRAPH
+0x93F6	0x8CD1	#CJK UNIFIED IDEOGRAPH
+0x93F7	0x8089	#CJK UNIFIED IDEOGRAPH
+0x93F8	0x8679	#CJK UNIFIED IDEOGRAPH
+0x93F9	0x5EFF	#CJK UNIFIED IDEOGRAPH
+0x93FA	0x65E5	#CJK UNIFIED IDEOGRAPH
+0x93FB	0x4E73	#CJK UNIFIED IDEOGRAPH
+0x93FC	0x5165	#CJK UNIFIED IDEOGRAPH
+0x9440	0x5982	#CJK UNIFIED IDEOGRAPH
+0x9441	0x5C3F	#CJK UNIFIED IDEOGRAPH
+0x9442	0x97EE	#CJK UNIFIED IDEOGRAPH
+0x9443	0x4EFB	#CJK UNIFIED IDEOGRAPH
+0x9444	0x598A	#CJK UNIFIED IDEOGRAPH
+0x9445	0x5FCD	#CJK UNIFIED IDEOGRAPH
+0x9446	0x8A8D	#CJK UNIFIED IDEOGRAPH
+0x9447	0x6FE1	#CJK UNIFIED IDEOGRAPH
+0x9448	0x79B0	#CJK UNIFIED IDEOGRAPH
+0x9449	0x7962	#CJK UNIFIED IDEOGRAPH
+0x944A	0x5BE7	#CJK UNIFIED IDEOGRAPH
+0x944B	0x8471	#CJK UNIFIED IDEOGRAPH
+0x944C	0x732B	#CJK UNIFIED IDEOGRAPH
+0x944D	0x71B1	#CJK UNIFIED IDEOGRAPH
+0x944E	0x5E74	#CJK UNIFIED IDEOGRAPH
+0x944F	0x5FF5	#CJK UNIFIED IDEOGRAPH
+0x9450	0x637B	#CJK UNIFIED IDEOGRAPH
+0x9451	0x649A	#CJK UNIFIED IDEOGRAPH
+0x9452	0x71C3	#CJK UNIFIED IDEOGRAPH
+0x9453	0x7C98	#CJK UNIFIED IDEOGRAPH
+0x9454	0x4E43	#CJK UNIFIED IDEOGRAPH
+0x9455	0x5EFC	#CJK UNIFIED IDEOGRAPH
+0x9456	0x4E4B	#CJK UNIFIED IDEOGRAPH
+0x9457	0x57DC	#CJK UNIFIED IDEOGRAPH
+0x9458	0x56A2	#CJK UNIFIED IDEOGRAPH
+0x9459	0x60A9	#CJK UNIFIED IDEOGRAPH
+0x945A	0x6FC3	#CJK UNIFIED IDEOGRAPH
+0x945B	0x7D0D	#CJK UNIFIED IDEOGRAPH
+0x945C	0x80FD	#CJK UNIFIED IDEOGRAPH
+0x945D	0x8133	#CJK UNIFIED IDEOGRAPH
+0x945E	0x81BF	#CJK UNIFIED IDEOGRAPH
+0x945F	0x8FB2	#CJK UNIFIED IDEOGRAPH
+0x9460	0x8997	#CJK UNIFIED IDEOGRAPH
+0x9461	0x86A4	#CJK UNIFIED IDEOGRAPH
+0x9462	0x5DF4	#CJK UNIFIED IDEOGRAPH
+0x9463	0x628A	#CJK UNIFIED IDEOGRAPH
+0x9464	0x64AD	#CJK UNIFIED IDEOGRAPH
+0x9465	0x8987	#CJK UNIFIED IDEOGRAPH
+0x9466	0x6777	#CJK UNIFIED IDEOGRAPH
+0x9467	0x6CE2	#CJK UNIFIED IDEOGRAPH
+0x9468	0x6D3E	#CJK UNIFIED IDEOGRAPH
+0x9469	0x7436	#CJK UNIFIED IDEOGRAPH
+0x946A	0x7834	#CJK UNIFIED IDEOGRAPH
+0x946B	0x5A46	#CJK UNIFIED IDEOGRAPH
+0x946C	0x7F75	#CJK UNIFIED IDEOGRAPH
+0x946D	0x82AD	#CJK UNIFIED IDEOGRAPH
+0x946E	0x99AC	#CJK UNIFIED IDEOGRAPH
+0x946F	0x4FF3	#CJK UNIFIED IDEOGRAPH
+0x9470	0x5EC3	#CJK UNIFIED IDEOGRAPH
+0x9471	0x62DD	#CJK UNIFIED IDEOGRAPH
+0x9472	0x6392	#CJK UNIFIED IDEOGRAPH
+0x9473	0x6557	#CJK UNIFIED IDEOGRAPH
+0x9474	0x676F	#CJK UNIFIED IDEOGRAPH
+0x9475	0x76C3	#CJK UNIFIED IDEOGRAPH
+0x9476	0x724C	#CJK UNIFIED IDEOGRAPH
+0x9477	0x80CC	#CJK UNIFIED IDEOGRAPH
+0x9478	0x80BA	#CJK UNIFIED IDEOGRAPH
+0x9479	0x8F29	#CJK UNIFIED IDEOGRAPH
+0x947A	0x914D	#CJK UNIFIED IDEOGRAPH
+0x947B	0x500D	#CJK UNIFIED IDEOGRAPH
+0x947C	0x57F9	#CJK UNIFIED IDEOGRAPH
+0x947D	0x5A92	#CJK UNIFIED IDEOGRAPH
+0x947E	0x6885	#CJK UNIFIED IDEOGRAPH
+0x9480	0x6973	#CJK UNIFIED IDEOGRAPH
+0x9481	0x7164	#CJK UNIFIED IDEOGRAPH
+0x9482	0x72FD	#CJK UNIFIED IDEOGRAPH
+0x9483	0x8CB7	#CJK UNIFIED IDEOGRAPH
+0x9484	0x58F2	#CJK UNIFIED IDEOGRAPH
+0x9485	0x8CE0	#CJK UNIFIED IDEOGRAPH
+0x9486	0x966A	#CJK UNIFIED IDEOGRAPH
+0x9487	0x9019	#CJK UNIFIED IDEOGRAPH
+0x9488	0x877F	#CJK UNIFIED IDEOGRAPH
+0x9489	0x79E4	#CJK UNIFIED IDEOGRAPH
+0x948A	0x77E7	#CJK UNIFIED IDEOGRAPH
+0x948B	0x8429	#CJK UNIFIED IDEOGRAPH
+0x948C	0x4F2F	#CJK UNIFIED IDEOGRAPH
+0x948D	0x5265	#CJK UNIFIED IDEOGRAPH
+0x948E	0x535A	#CJK UNIFIED IDEOGRAPH
+0x948F	0x62CD	#CJK UNIFIED IDEOGRAPH
+0x9490	0x67CF	#CJK UNIFIED IDEOGRAPH
+0x9491	0x6CCA	#CJK UNIFIED IDEOGRAPH
+0x9492	0x767D	#CJK UNIFIED IDEOGRAPH
+0x9493	0x7B94	#CJK UNIFIED IDEOGRAPH
+0x9494	0x7C95	#CJK UNIFIED IDEOGRAPH
+0x9495	0x8236	#CJK UNIFIED IDEOGRAPH
+0x9496	0x8584	#CJK UNIFIED IDEOGRAPH
+0x9497	0x8FEB	#CJK UNIFIED IDEOGRAPH
+0x9498	0x66DD	#CJK UNIFIED IDEOGRAPH
+0x9499	0x6F20	#CJK UNIFIED IDEOGRAPH
+0x949A	0x7206	#CJK UNIFIED IDEOGRAPH
+0x949B	0x7E1B	#CJK UNIFIED IDEOGRAPH
+0x949C	0x83AB	#CJK UNIFIED IDEOGRAPH
+0x949D	0x99C1	#CJK UNIFIED IDEOGRAPH
+0x949E	0x9EA6	#CJK UNIFIED IDEOGRAPH
+0x949F	0x51FD	#CJK UNIFIED IDEOGRAPH
+0x94A0	0x7BB1	#CJK UNIFIED IDEOGRAPH
+0x94A1	0x7872	#CJK UNIFIED IDEOGRAPH
+0x94A2	0x7BB8	#CJK UNIFIED IDEOGRAPH
+0x94A3	0x8087	#CJK UNIFIED IDEOGRAPH
+0x94A4	0x7B48	#CJK UNIFIED IDEOGRAPH
+0x94A5	0x6AE8	#CJK UNIFIED IDEOGRAPH
+0x94A6	0x5E61	#CJK UNIFIED IDEOGRAPH
+0x94A7	0x808C	#CJK UNIFIED IDEOGRAPH
+0x94A8	0x7551	#CJK UNIFIED IDEOGRAPH
+0x94A9	0x7560	#CJK UNIFIED IDEOGRAPH
+0x94AA	0x516B	#CJK UNIFIED IDEOGRAPH
+0x94AB	0x9262	#CJK UNIFIED IDEOGRAPH
+0x94AC	0x6E8C	#CJK UNIFIED IDEOGRAPH
+0x94AD	0x767A	#CJK UNIFIED IDEOGRAPH
+0x94AE	0x9197	#CJK UNIFIED IDEOGRAPH
+0x94AF	0x9AEA	#CJK UNIFIED IDEOGRAPH
+0x94B0	0x4F10	#CJK UNIFIED IDEOGRAPH
+0x94B1	0x7F70	#CJK UNIFIED IDEOGRAPH
+0x94B2	0x629C	#CJK UNIFIED IDEOGRAPH
+0x94B3	0x7B4F	#CJK UNIFIED IDEOGRAPH
+0x94B4	0x95A5	#CJK UNIFIED IDEOGRAPH
+0x94B5	0x9CE9	#CJK UNIFIED IDEOGRAPH
+0x94B6	0x567A	#CJK UNIFIED IDEOGRAPH
+0x94B7	0x5859	#CJK UNIFIED IDEOGRAPH
+0x94B8	0x86E4	#CJK UNIFIED IDEOGRAPH
+0x94B9	0x96BC	#CJK UNIFIED IDEOGRAPH
+0x94BA	0x4F34	#CJK UNIFIED IDEOGRAPH
+0x94BB	0x5224	#CJK UNIFIED IDEOGRAPH
+0x94BC	0x534A	#CJK UNIFIED IDEOGRAPH
+0x94BD	0x53CD	#CJK UNIFIED IDEOGRAPH
+0x94BE	0x53DB	#CJK UNIFIED IDEOGRAPH
+0x94BF	0x5E06	#CJK UNIFIED IDEOGRAPH
+0x94C0	0x642C	#CJK UNIFIED IDEOGRAPH
+0x94C1	0x6591	#CJK UNIFIED IDEOGRAPH
+0x94C2	0x677F	#CJK UNIFIED IDEOGRAPH
+0x94C3	0x6C3E	#CJK UNIFIED IDEOGRAPH
+0x94C4	0x6C4E	#CJK UNIFIED IDEOGRAPH
+0x94C5	0x7248	#CJK UNIFIED IDEOGRAPH
+0x94C6	0x72AF	#CJK UNIFIED IDEOGRAPH
+0x94C7	0x73ED	#CJK UNIFIED IDEOGRAPH
+0x94C8	0x7554	#CJK UNIFIED IDEOGRAPH
+0x94C9	0x7E41	#CJK UNIFIED IDEOGRAPH
+0x94CA	0x822C	#CJK UNIFIED IDEOGRAPH
+0x94CB	0x85E9	#CJK UNIFIED IDEOGRAPH
+0x94CC	0x8CA9	#CJK UNIFIED IDEOGRAPH
+0x94CD	0x7BC4	#CJK UNIFIED IDEOGRAPH
+0x94CE	0x91C6	#CJK UNIFIED IDEOGRAPH
+0x94CF	0x7169	#CJK UNIFIED IDEOGRAPH
+0x94D0	0x9812	#CJK UNIFIED IDEOGRAPH
+0x94D1	0x98EF	#CJK UNIFIED IDEOGRAPH
+0x94D2	0x633D	#CJK UNIFIED IDEOGRAPH
+0x94D3	0x6669	#CJK UNIFIED IDEOGRAPH
+0x94D4	0x756A	#CJK UNIFIED IDEOGRAPH
+0x94D5	0x76E4	#CJK UNIFIED IDEOGRAPH
+0x94D6	0x78D0	#CJK UNIFIED IDEOGRAPH
+0x94D7	0x8543	#CJK UNIFIED IDEOGRAPH
+0x94D8	0x86EE	#CJK UNIFIED IDEOGRAPH
+0x94D9	0x532A	#CJK UNIFIED IDEOGRAPH
+0x94DA	0x5351	#CJK UNIFIED IDEOGRAPH
+0x94DB	0x5426	#CJK UNIFIED IDEOGRAPH
+0x94DC	0x5983	#CJK UNIFIED IDEOGRAPH
+0x94DD	0x5E87	#CJK UNIFIED IDEOGRAPH
+0x94DE	0x5F7C	#CJK UNIFIED IDEOGRAPH
+0x94DF	0x60B2	#CJK UNIFIED IDEOGRAPH
+0x94E0	0x6249	#CJK UNIFIED IDEOGRAPH
+0x94E1	0x6279	#CJK UNIFIED IDEOGRAPH
+0x94E2	0x62AB	#CJK UNIFIED IDEOGRAPH
+0x94E3	0x6590	#CJK UNIFIED IDEOGRAPH
+0x94E4	0x6BD4	#CJK UNIFIED IDEOGRAPH
+0x94E5	0x6CCC	#CJK UNIFIED IDEOGRAPH
+0x94E6	0x75B2	#CJK UNIFIED IDEOGRAPH
+0x94E7	0x76AE	#CJK UNIFIED IDEOGRAPH
+0x94E8	0x7891	#CJK UNIFIED IDEOGRAPH
+0x94E9	0x79D8	#CJK UNIFIED IDEOGRAPH
+0x94EA	0x7DCB	#CJK UNIFIED IDEOGRAPH
+0x94EB	0x7F77	#CJK UNIFIED IDEOGRAPH
+0x94EC	0x80A5	#CJK UNIFIED IDEOGRAPH
+0x94ED	0x88AB	#CJK UNIFIED IDEOGRAPH
+0x94EE	0x8AB9	#CJK UNIFIED IDEOGRAPH
+0x94EF	0x8CBB	#CJK UNIFIED IDEOGRAPH
+0x94F0	0x907F	#CJK UNIFIED IDEOGRAPH
+0x94F1	0x975E	#CJK UNIFIED IDEOGRAPH
+0x94F2	0x98DB	#CJK UNIFIED IDEOGRAPH
+0x94F3	0x6A0B	#CJK UNIFIED IDEOGRAPH
+0x94F4	0x7C38	#CJK UNIFIED IDEOGRAPH
+0x94F5	0x5099	#CJK UNIFIED IDEOGRAPH
+0x94F6	0x5C3E	#CJK UNIFIED IDEOGRAPH
+0x94F7	0x5FAE	#CJK UNIFIED IDEOGRAPH
+0x94F8	0x6787	#CJK UNIFIED IDEOGRAPH
+0x94F9	0x6BD8	#CJK UNIFIED IDEOGRAPH
+0x94FA	0x7435	#CJK UNIFIED IDEOGRAPH
+0x94FB	0x7709	#CJK UNIFIED IDEOGRAPH
+0x94FC	0x7F8E	#CJK UNIFIED IDEOGRAPH
+0x9540	0x9F3B	#CJK UNIFIED IDEOGRAPH
+0x9541	0x67CA	#CJK UNIFIED IDEOGRAPH
+0x9542	0x7A17	#CJK UNIFIED IDEOGRAPH
+0x9543	0x5339	#CJK UNIFIED IDEOGRAPH
+0x9544	0x758B	#CJK UNIFIED IDEOGRAPH
+0x9545	0x9AED	#CJK UNIFIED IDEOGRAPH
+0x9546	0x5F66	#CJK UNIFIED IDEOGRAPH
+0x9547	0x819D	#CJK UNIFIED IDEOGRAPH
+0x9548	0x83F1	#CJK UNIFIED IDEOGRAPH
+0x9549	0x8098	#CJK UNIFIED IDEOGRAPH
+0x954A	0x5F3C	#CJK UNIFIED IDEOGRAPH
+0x954B	0x5FC5	#CJK UNIFIED IDEOGRAPH
+0x954C	0x7562	#CJK UNIFIED IDEOGRAPH
+0x954D	0x7B46	#CJK UNIFIED IDEOGRAPH
+0x954E	0x903C	#CJK UNIFIED IDEOGRAPH
+0x954F	0x6867	#CJK UNIFIED IDEOGRAPH
+0x9550	0x59EB	#CJK UNIFIED IDEOGRAPH
+0x9551	0x5A9B	#CJK UNIFIED IDEOGRAPH
+0x9552	0x7D10	#CJK UNIFIED IDEOGRAPH
+0x9553	0x767E	#CJK UNIFIED IDEOGRAPH
+0x9554	0x8B2C	#CJK UNIFIED IDEOGRAPH
+0x9555	0x4FF5	#CJK UNIFIED IDEOGRAPH
+0x9556	0x5F6A	#CJK UNIFIED IDEOGRAPH
+0x9557	0x6A19	#CJK UNIFIED IDEOGRAPH
+0x9558	0x6C37	#CJK UNIFIED IDEOGRAPH
+0x9559	0x6F02	#CJK UNIFIED IDEOGRAPH
+0x955A	0x74E2	#CJK UNIFIED IDEOGRAPH
+0x955B	0x7968	#CJK UNIFIED IDEOGRAPH
+0x955C	0x8868	#CJK UNIFIED IDEOGRAPH
+0x955D	0x8A55	#CJK UNIFIED IDEOGRAPH
+0x955E	0x8C79	#CJK UNIFIED IDEOGRAPH
+0x955F	0x5EDF	#CJK UNIFIED IDEOGRAPH
+0x9560	0x63CF	#CJK UNIFIED IDEOGRAPH
+0x9561	0x75C5	#CJK UNIFIED IDEOGRAPH
+0x9562	0x79D2	#CJK UNIFIED IDEOGRAPH
+0x9563	0x82D7	#CJK UNIFIED IDEOGRAPH
+0x9564	0x9328	#CJK UNIFIED IDEOGRAPH
+0x9565	0x92F2	#CJK UNIFIED IDEOGRAPH
+0x9566	0x849C	#CJK UNIFIED IDEOGRAPH
+0x9567	0x86ED	#CJK UNIFIED IDEOGRAPH
+0x9568	0x9C2D	#CJK UNIFIED IDEOGRAPH
+0x9569	0x54C1	#CJK UNIFIED IDEOGRAPH
+0x956A	0x5F6C	#CJK UNIFIED IDEOGRAPH
+0x956B	0x658C	#CJK UNIFIED IDEOGRAPH
+0x956C	0x6D5C	#CJK UNIFIED IDEOGRAPH
+0x956D	0x7015	#CJK UNIFIED IDEOGRAPH
+0x956E	0x8CA7	#CJK UNIFIED IDEOGRAPH
+0x956F	0x8CD3	#CJK UNIFIED IDEOGRAPH
+0x9570	0x983B	#CJK UNIFIED IDEOGRAPH
+0x9571	0x654F	#CJK UNIFIED IDEOGRAPH
+0x9572	0x74F6	#CJK UNIFIED IDEOGRAPH
+0x9573	0x4E0D	#CJK UNIFIED IDEOGRAPH
+0x9574	0x4ED8	#CJK UNIFIED IDEOGRAPH
+0x9575	0x57E0	#CJK UNIFIED IDEOGRAPH
+0x9576	0x592B	#CJK UNIFIED IDEOGRAPH
+0x9577	0x5A66	#CJK UNIFIED IDEOGRAPH
+0x9578	0x5BCC	#CJK UNIFIED IDEOGRAPH
+0x9579	0x51A8	#CJK UNIFIED IDEOGRAPH
+0x957A	0x5E03	#CJK UNIFIED IDEOGRAPH
+0x957B	0x5E9C	#CJK UNIFIED IDEOGRAPH
+0x957C	0x6016	#CJK UNIFIED IDEOGRAPH
+0x957D	0x6276	#CJK UNIFIED IDEOGRAPH
+0x957E	0x6577	#CJK UNIFIED IDEOGRAPH
+0x9580	0x65A7	#CJK UNIFIED IDEOGRAPH
+0x9581	0x666E	#CJK UNIFIED IDEOGRAPH
+0x9582	0x6D6E	#CJK UNIFIED IDEOGRAPH
+0x9583	0x7236	#CJK UNIFIED IDEOGRAPH
+0x9584	0x7B26	#CJK UNIFIED IDEOGRAPH
+0x9585	0x8150	#CJK UNIFIED IDEOGRAPH
+0x9586	0x819A	#CJK UNIFIED IDEOGRAPH
+0x9587	0x8299	#CJK UNIFIED IDEOGRAPH
+0x9588	0x8B5C	#CJK UNIFIED IDEOGRAPH
+0x9589	0x8CA0	#CJK UNIFIED IDEOGRAPH
+0x958A	0x8CE6	#CJK UNIFIED IDEOGRAPH
+0x958B	0x8D74	#CJK UNIFIED IDEOGRAPH
+0x958C	0x961C	#CJK UNIFIED IDEOGRAPH
+0x958D	0x9644	#CJK UNIFIED IDEOGRAPH
+0x958E	0x4FAE	#CJK UNIFIED IDEOGRAPH
+0x958F	0x64AB	#CJK UNIFIED IDEOGRAPH
+0x9590	0x6B66	#CJK UNIFIED IDEOGRAPH
+0x9591	0x821E	#CJK UNIFIED IDEOGRAPH
+0x9592	0x8461	#CJK UNIFIED IDEOGRAPH
+0x9593	0x856A	#CJK UNIFIED IDEOGRAPH
+0x9594	0x90E8	#CJK UNIFIED IDEOGRAPH
+0x9595	0x5C01	#CJK UNIFIED IDEOGRAPH
+0x9596	0x6953	#CJK UNIFIED IDEOGRAPH
+0x9597	0x98A8	#CJK UNIFIED IDEOGRAPH
+0x9598	0x847A	#CJK UNIFIED IDEOGRAPH
+0x9599	0x8557	#CJK UNIFIED IDEOGRAPH
+0x959A	0x4F0F	#CJK UNIFIED IDEOGRAPH
+0x959B	0x526F	#CJK UNIFIED IDEOGRAPH
+0x959C	0x5FA9	#CJK UNIFIED IDEOGRAPH
+0x959D	0x5E45	#CJK UNIFIED IDEOGRAPH
+0x959E	0x670D	#CJK UNIFIED IDEOGRAPH
+0x959F	0x798F	#CJK UNIFIED IDEOGRAPH
+0x95A0	0x8179	#CJK UNIFIED IDEOGRAPH
+0x95A1	0x8907	#CJK UNIFIED IDEOGRAPH
+0x95A2	0x8986	#CJK UNIFIED IDEOGRAPH
+0x95A3	0x6DF5	#CJK UNIFIED IDEOGRAPH
+0x95A4	0x5F17	#CJK UNIFIED IDEOGRAPH
+0x95A5	0x6255	#CJK UNIFIED IDEOGRAPH
+0x95A6	0x6CB8	#CJK UNIFIED IDEOGRAPH
+0x95A7	0x4ECF	#CJK UNIFIED IDEOGRAPH
+0x95A8	0x7269	#CJK UNIFIED IDEOGRAPH
+0x95A9	0x9B92	#CJK UNIFIED IDEOGRAPH
+0x95AA	0x5206	#CJK UNIFIED IDEOGRAPH
+0x95AB	0x543B	#CJK UNIFIED IDEOGRAPH
+0x95AC	0x5674	#CJK UNIFIED IDEOGRAPH
+0x95AD	0x58B3	#CJK UNIFIED IDEOGRAPH
+0x95AE	0x61A4	#CJK UNIFIED IDEOGRAPH
+0x95AF	0x626E	#CJK UNIFIED IDEOGRAPH
+0x95B0	0x711A	#CJK UNIFIED IDEOGRAPH
+0x95B1	0x596E	#CJK UNIFIED IDEOGRAPH
+0x95B2	0x7C89	#CJK UNIFIED IDEOGRAPH
+0x95B3	0x7CDE	#CJK UNIFIED IDEOGRAPH
+0x95B4	0x7D1B	#CJK UNIFIED IDEOGRAPH
+0x95B5	0x96F0	#CJK UNIFIED IDEOGRAPH
+0x95B6	0x6587	#CJK UNIFIED IDEOGRAPH
+0x95B7	0x805E	#CJK UNIFIED IDEOGRAPH
+0x95B8	0x4E19	#CJK UNIFIED IDEOGRAPH
+0x95B9	0x4F75	#CJK UNIFIED IDEOGRAPH
+0x95BA	0x5175	#CJK UNIFIED IDEOGRAPH
+0x95BB	0x5840	#CJK UNIFIED IDEOGRAPH
+0x95BC	0x5E63	#CJK UNIFIED IDEOGRAPH
+0x95BD	0x5E73	#CJK UNIFIED IDEOGRAPH
+0x95BE	0x5F0A	#CJK UNIFIED IDEOGRAPH
+0x95BF	0x67C4	#CJK UNIFIED IDEOGRAPH
+0x95C0	0x4E26	#CJK UNIFIED IDEOGRAPH
+0x95C1	0x853D	#CJK UNIFIED IDEOGRAPH
+0x95C2	0x9589	#CJK UNIFIED IDEOGRAPH
+0x95C3	0x965B	#CJK UNIFIED IDEOGRAPH
+0x95C4	0x7C73	#CJK UNIFIED IDEOGRAPH
+0x95C5	0x9801	#CJK UNIFIED IDEOGRAPH
+0x95C6	0x50FB	#CJK UNIFIED IDEOGRAPH
+0x95C7	0x58C1	#CJK UNIFIED IDEOGRAPH
+0x95C8	0x7656	#CJK UNIFIED IDEOGRAPH
+0x95C9	0x78A7	#CJK UNIFIED IDEOGRAPH
+0x95CA	0x5225	#CJK UNIFIED IDEOGRAPH
+0x95CB	0x77A5	#CJK UNIFIED IDEOGRAPH
+0x95CC	0x8511	#CJK UNIFIED IDEOGRAPH
+0x95CD	0x7B86	#CJK UNIFIED IDEOGRAPH
+0x95CE	0x504F	#CJK UNIFIED IDEOGRAPH
+0x95CF	0x5909	#CJK UNIFIED IDEOGRAPH
+0x95D0	0x7247	#CJK UNIFIED IDEOGRAPH
+0x95D1	0x7BC7	#CJK UNIFIED IDEOGRAPH
+0x95D2	0x7DE8	#CJK UNIFIED IDEOGRAPH
+0x95D3	0x8FBA	#CJK UNIFIED IDEOGRAPH
+0x95D4	0x8FD4	#CJK UNIFIED IDEOGRAPH
+0x95D5	0x904D	#CJK UNIFIED IDEOGRAPH
+0x95D6	0x4FBF	#CJK UNIFIED IDEOGRAPH
+0x95D7	0x52C9	#CJK UNIFIED IDEOGRAPH
+0x95D8	0x5A29	#CJK UNIFIED IDEOGRAPH
+0x95D9	0x5F01	#CJK UNIFIED IDEOGRAPH
+0x95DA	0x97AD	#CJK UNIFIED IDEOGRAPH
+0x95DB	0x4FDD	#CJK UNIFIED IDEOGRAPH
+0x95DC	0x8217	#CJK UNIFIED IDEOGRAPH
+0x95DD	0x92EA	#CJK UNIFIED IDEOGRAPH
+0x95DE	0x5703	#CJK UNIFIED IDEOGRAPH
+0x95DF	0x6355	#CJK UNIFIED IDEOGRAPH
+0x95E0	0x6B69	#CJK UNIFIED IDEOGRAPH
+0x95E1	0x752B	#CJK UNIFIED IDEOGRAPH
+0x95E2	0x88DC	#CJK UNIFIED IDEOGRAPH
+0x95E3	0x8F14	#CJK UNIFIED IDEOGRAPH
+0x95E4	0x7A42	#CJK UNIFIED IDEOGRAPH
+0x95E5	0x52DF	#CJK UNIFIED IDEOGRAPH
+0x95E6	0x5893	#CJK UNIFIED IDEOGRAPH
+0x95E7	0x6155	#CJK UNIFIED IDEOGRAPH
+0x95E8	0x620A	#CJK UNIFIED IDEOGRAPH
+0x95E9	0x66AE	#CJK UNIFIED IDEOGRAPH
+0x95EA	0x6BCD	#CJK UNIFIED IDEOGRAPH
+0x95EB	0x7C3F	#CJK UNIFIED IDEOGRAPH
+0x95EC	0x83E9	#CJK UNIFIED IDEOGRAPH
+0x95ED	0x5023	#CJK UNIFIED IDEOGRAPH
+0x95EE	0x4FF8	#CJK UNIFIED IDEOGRAPH
+0x95EF	0x5305	#CJK UNIFIED IDEOGRAPH
+0x95F0	0x5446	#CJK UNIFIED IDEOGRAPH
+0x95F1	0x5831	#CJK UNIFIED IDEOGRAPH
+0x95F2	0x5949	#CJK UNIFIED IDEOGRAPH
+0x95F3	0x5B9D	#CJK UNIFIED IDEOGRAPH
+0x95F4	0x5CF0	#CJK UNIFIED IDEOGRAPH
+0x95F5	0x5CEF	#CJK UNIFIED IDEOGRAPH
+0x95F6	0x5D29	#CJK UNIFIED IDEOGRAPH
+0x95F7	0x5E96	#CJK UNIFIED IDEOGRAPH
+0x95F8	0x62B1	#CJK UNIFIED IDEOGRAPH
+0x95F9	0x6367	#CJK UNIFIED IDEOGRAPH
+0x95FA	0x653E	#CJK UNIFIED IDEOGRAPH
+0x95FB	0x65B9	#CJK UNIFIED IDEOGRAPH
+0x95FC	0x670B	#CJK UNIFIED IDEOGRAPH
+0x9640	0x6CD5	#CJK UNIFIED IDEOGRAPH
+0x9641	0x6CE1	#CJK UNIFIED IDEOGRAPH
+0x9642	0x70F9	#CJK UNIFIED IDEOGRAPH
+0x9643	0x7832	#CJK UNIFIED IDEOGRAPH
+0x9644	0x7E2B	#CJK UNIFIED IDEOGRAPH
+0x9645	0x80DE	#CJK UNIFIED IDEOGRAPH
+0x9646	0x82B3	#CJK UNIFIED IDEOGRAPH
+0x9647	0x840C	#CJK UNIFIED IDEOGRAPH
+0x9648	0x84EC	#CJK UNIFIED IDEOGRAPH
+0x9649	0x8702	#CJK UNIFIED IDEOGRAPH
+0x964A	0x8912	#CJK UNIFIED IDEOGRAPH
+0x964B	0x8A2A	#CJK UNIFIED IDEOGRAPH
+0x964C	0x8C4A	#CJK UNIFIED IDEOGRAPH
+0x964D	0x90A6	#CJK UNIFIED IDEOGRAPH
+0x964E	0x92D2	#CJK UNIFIED IDEOGRAPH
+0x964F	0x98FD	#CJK UNIFIED IDEOGRAPH
+0x9650	0x9CF3	#CJK UNIFIED IDEOGRAPH
+0x9651	0x9D6C	#CJK UNIFIED IDEOGRAPH
+0x9652	0x4E4F	#CJK UNIFIED IDEOGRAPH
+0x9653	0x4EA1	#CJK UNIFIED IDEOGRAPH
+0x9654	0x508D	#CJK UNIFIED IDEOGRAPH
+0x9655	0x5256	#CJK UNIFIED IDEOGRAPH
+0x9656	0x574A	#CJK UNIFIED IDEOGRAPH
+0x9657	0x59A8	#CJK UNIFIED IDEOGRAPH
+0x9658	0x5E3D	#CJK UNIFIED IDEOGRAPH
+0x9659	0x5FD8	#CJK UNIFIED IDEOGRAPH
+0x965A	0x5FD9	#CJK UNIFIED IDEOGRAPH
+0x965B	0x623F	#CJK UNIFIED IDEOGRAPH
+0x965C	0x66B4	#CJK UNIFIED IDEOGRAPH
+0x965D	0x671B	#CJK UNIFIED IDEOGRAPH
+0x965E	0x67D0	#CJK UNIFIED IDEOGRAPH
+0x965F	0x68D2	#CJK UNIFIED IDEOGRAPH
+0x9660	0x5192	#CJK UNIFIED IDEOGRAPH
+0x9661	0x7D21	#CJK UNIFIED IDEOGRAPH
+0x9662	0x80AA	#CJK UNIFIED IDEOGRAPH
+0x9663	0x81A8	#CJK UNIFIED IDEOGRAPH
+0x9664	0x8B00	#CJK UNIFIED IDEOGRAPH
+0x9665	0x8C8C	#CJK UNIFIED IDEOGRAPH
+0x9666	0x8CBF	#CJK UNIFIED IDEOGRAPH
+0x9667	0x927E	#CJK UNIFIED IDEOGRAPH
+0x9668	0x9632	#CJK UNIFIED IDEOGRAPH
+0x9669	0x5420	#CJK UNIFIED IDEOGRAPH
+0x966A	0x982C	#CJK UNIFIED IDEOGRAPH
+0x966B	0x5317	#CJK UNIFIED IDEOGRAPH
+0x966C	0x50D5	#CJK UNIFIED IDEOGRAPH
+0x966D	0x535C	#CJK UNIFIED IDEOGRAPH
+0x966E	0x58A8	#CJK UNIFIED IDEOGRAPH
+0x966F	0x64B2	#CJK UNIFIED IDEOGRAPH
+0x9670	0x6734	#CJK UNIFIED IDEOGRAPH
+0x9671	0x7267	#CJK UNIFIED IDEOGRAPH
+0x9672	0x7766	#CJK UNIFIED IDEOGRAPH
+0x9673	0x7A46	#CJK UNIFIED IDEOGRAPH
+0x9674	0x91E6	#CJK UNIFIED IDEOGRAPH
+0x9675	0x52C3	#CJK UNIFIED IDEOGRAPH
+0x9676	0x6CA1	#CJK UNIFIED IDEOGRAPH
+0x9677	0x6B86	#CJK UNIFIED IDEOGRAPH
+0x9678	0x5800	#CJK UNIFIED IDEOGRAPH
+0x9679	0x5E4C	#CJK UNIFIED IDEOGRAPH
+0x967A	0x5954	#CJK UNIFIED IDEOGRAPH
+0x967B	0x672C	#CJK UNIFIED IDEOGRAPH
+0x967C	0x7FFB	#CJK UNIFIED IDEOGRAPH
+0x967D	0x51E1	#CJK UNIFIED IDEOGRAPH
+0x967E	0x76C6	#CJK UNIFIED IDEOGRAPH
+0x9680	0x6469	#CJK UNIFIED IDEOGRAPH
+0x9681	0x78E8	#CJK UNIFIED IDEOGRAPH
+0x9682	0x9B54	#CJK UNIFIED IDEOGRAPH
+0x9683	0x9EBB	#CJK UNIFIED IDEOGRAPH
+0x9684	0x57CB	#CJK UNIFIED IDEOGRAPH
+0x9685	0x59B9	#CJK UNIFIED IDEOGRAPH
+0x9686	0x6627	#CJK UNIFIED IDEOGRAPH
+0x9687	0x679A	#CJK UNIFIED IDEOGRAPH
+0x9688	0x6BCE	#CJK UNIFIED IDEOGRAPH
+0x9689	0x54E9	#CJK UNIFIED IDEOGRAPH
+0x968A	0x69D9	#CJK UNIFIED IDEOGRAPH
+0x968B	0x5E55	#CJK UNIFIED IDEOGRAPH
+0x968C	0x819C	#CJK UNIFIED IDEOGRAPH
+0x968D	0x6795	#CJK UNIFIED IDEOGRAPH
+0x968E	0x9BAA	#CJK UNIFIED IDEOGRAPH
+0x968F	0x67FE	#CJK UNIFIED IDEOGRAPH
+0x9690	0x9C52	#CJK UNIFIED IDEOGRAPH
+0x9691	0x685D	#CJK UNIFIED IDEOGRAPH
+0x9692	0x4EA6	#CJK UNIFIED IDEOGRAPH
+0x9693	0x4FE3	#CJK UNIFIED IDEOGRAPH
+0x9694	0x53C8	#CJK UNIFIED IDEOGRAPH
+0x9695	0x62B9	#CJK UNIFIED IDEOGRAPH
+0x9696	0x672B	#CJK UNIFIED IDEOGRAPH
+0x9697	0x6CAB	#CJK UNIFIED IDEOGRAPH
+0x9698	0x8FC4	#CJK UNIFIED IDEOGRAPH
+0x9699	0x4FAD	#CJK UNIFIED IDEOGRAPH
+0x969A	0x7E6D	#CJK UNIFIED IDEOGRAPH
+0x969B	0x9EBF	#CJK UNIFIED IDEOGRAPH
+0x969C	0x4E07	#CJK UNIFIED IDEOGRAPH
+0x969D	0x6162	#CJK UNIFIED IDEOGRAPH
+0x969E	0x6E80	#CJK UNIFIED IDEOGRAPH
+0x969F	0x6F2B	#CJK UNIFIED IDEOGRAPH
+0x96A0	0x8513	#CJK UNIFIED IDEOGRAPH
+0x96A1	0x5473	#CJK UNIFIED IDEOGRAPH
+0x96A2	0x672A	#CJK UNIFIED IDEOGRAPH
+0x96A3	0x9B45	#CJK UNIFIED IDEOGRAPH
+0x96A4	0x5DF3	#CJK UNIFIED IDEOGRAPH
+0x96A5	0x7B95	#CJK UNIFIED IDEOGRAPH
+0x96A6	0x5CAC	#CJK UNIFIED IDEOGRAPH
+0x96A7	0x5BC6	#CJK UNIFIED IDEOGRAPH
+0x96A8	0x871C	#CJK UNIFIED IDEOGRAPH
+0x96A9	0x6E4A	#CJK UNIFIED IDEOGRAPH
+0x96AA	0x84D1	#CJK UNIFIED IDEOGRAPH
+0x96AB	0x7A14	#CJK UNIFIED IDEOGRAPH
+0x96AC	0x8108	#CJK UNIFIED IDEOGRAPH
+0x96AD	0x5999	#CJK UNIFIED IDEOGRAPH
+0x96AE	0x7C8D	#CJK UNIFIED IDEOGRAPH
+0x96AF	0x6C11	#CJK UNIFIED IDEOGRAPH
+0x96B0	0x7720	#CJK UNIFIED IDEOGRAPH
+0x96B1	0x52D9	#CJK UNIFIED IDEOGRAPH
+0x96B2	0x5922	#CJK UNIFIED IDEOGRAPH
+0x96B3	0x7121	#CJK UNIFIED IDEOGRAPH
+0x96B4	0x725F	#CJK UNIFIED IDEOGRAPH
+0x96B5	0x77DB	#CJK UNIFIED IDEOGRAPH
+0x96B6	0x9727	#CJK UNIFIED IDEOGRAPH
+0x96B7	0x9D61	#CJK UNIFIED IDEOGRAPH
+0x96B8	0x690B	#CJK UNIFIED IDEOGRAPH
+0x96B9	0x5A7F	#CJK UNIFIED IDEOGRAPH
+0x96BA	0x5A18	#CJK UNIFIED IDEOGRAPH
+0x96BB	0x51A5	#CJK UNIFIED IDEOGRAPH
+0x96BC	0x540D	#CJK UNIFIED IDEOGRAPH
+0x96BD	0x547D	#CJK UNIFIED IDEOGRAPH
+0x96BE	0x660E	#CJK UNIFIED IDEOGRAPH
+0x96BF	0x76DF	#CJK UNIFIED IDEOGRAPH
+0x96C0	0x8FF7	#CJK UNIFIED IDEOGRAPH
+0x96C1	0x9298	#CJK UNIFIED IDEOGRAPH
+0x96C2	0x9CF4	#CJK UNIFIED IDEOGRAPH
+0x96C3	0x59EA	#CJK UNIFIED IDEOGRAPH
+0x96C4	0x725D	#CJK UNIFIED IDEOGRAPH
+0x96C5	0x6EC5	#CJK UNIFIED IDEOGRAPH
+0x96C6	0x514D	#CJK UNIFIED IDEOGRAPH
+0x96C7	0x68C9	#CJK UNIFIED IDEOGRAPH
+0x96C8	0x7DBF	#CJK UNIFIED IDEOGRAPH
+0x96C9	0x7DEC	#CJK UNIFIED IDEOGRAPH
+0x96CA	0x9762	#CJK UNIFIED IDEOGRAPH
+0x96CB	0x9EBA	#CJK UNIFIED IDEOGRAPH
+0x96CC	0x6478	#CJK UNIFIED IDEOGRAPH
+0x96CD	0x6A21	#CJK UNIFIED IDEOGRAPH
+0x96CE	0x8302	#CJK UNIFIED IDEOGRAPH
+0x96CF	0x5984	#CJK UNIFIED IDEOGRAPH
+0x96D0	0x5B5F	#CJK UNIFIED IDEOGRAPH
+0x96D1	0x6BDB	#CJK UNIFIED IDEOGRAPH
+0x96D2	0x731B	#CJK UNIFIED IDEOGRAPH
+0x96D3	0x76F2	#CJK UNIFIED IDEOGRAPH
+0x96D4	0x7DB2	#CJK UNIFIED IDEOGRAPH
+0x96D5	0x8017	#CJK UNIFIED IDEOGRAPH
+0x96D6	0x8499	#CJK UNIFIED IDEOGRAPH
+0x96D7	0x5132	#CJK UNIFIED IDEOGRAPH
+0x96D8	0x6728	#CJK UNIFIED IDEOGRAPH
+0x96D9	0x9ED9	#CJK UNIFIED IDEOGRAPH
+0x96DA	0x76EE	#CJK UNIFIED IDEOGRAPH
+0x96DB	0x6762	#CJK UNIFIED IDEOGRAPH
+0x96DC	0x52FF	#CJK UNIFIED IDEOGRAPH
+0x96DD	0x9905	#CJK UNIFIED IDEOGRAPH
+0x96DE	0x5C24	#CJK UNIFIED IDEOGRAPH
+0x96DF	0x623B	#CJK UNIFIED IDEOGRAPH
+0x96E0	0x7C7E	#CJK UNIFIED IDEOGRAPH
+0x96E1	0x8CB0	#CJK UNIFIED IDEOGRAPH
+0x96E2	0x554F	#CJK UNIFIED IDEOGRAPH
+0x96E3	0x60B6	#CJK UNIFIED IDEOGRAPH
+0x96E4	0x7D0B	#CJK UNIFIED IDEOGRAPH
+0x96E5	0x9580	#CJK UNIFIED IDEOGRAPH
+0x96E6	0x5301	#CJK UNIFIED IDEOGRAPH
+0x96E7	0x4E5F	#CJK UNIFIED IDEOGRAPH
+0x96E8	0x51B6	#CJK UNIFIED IDEOGRAPH
+0x96E9	0x591C	#CJK UNIFIED IDEOGRAPH
+0x96EA	0x723A	#CJK UNIFIED IDEOGRAPH
+0x96EB	0x8036	#CJK UNIFIED IDEOGRAPH
+0x96EC	0x91CE	#CJK UNIFIED IDEOGRAPH
+0x96ED	0x5F25	#CJK UNIFIED IDEOGRAPH
+0x96EE	0x77E2	#CJK UNIFIED IDEOGRAPH
+0x96EF	0x5384	#CJK UNIFIED IDEOGRAPH
+0x96F0	0x5F79	#CJK UNIFIED IDEOGRAPH
+0x96F1	0x7D04	#CJK UNIFIED IDEOGRAPH
+0x96F2	0x85AC	#CJK UNIFIED IDEOGRAPH
+0x96F3	0x8A33	#CJK UNIFIED IDEOGRAPH
+0x96F4	0x8E8D	#CJK UNIFIED IDEOGRAPH
+0x96F5	0x9756	#CJK UNIFIED IDEOGRAPH
+0x96F6	0x67F3	#CJK UNIFIED IDEOGRAPH
+0x96F7	0x85AE	#CJK UNIFIED IDEOGRAPH
+0x96F8	0x9453	#CJK UNIFIED IDEOGRAPH
+0x96F9	0x6109	#CJK UNIFIED IDEOGRAPH
+0x96FA	0x6108	#CJK UNIFIED IDEOGRAPH
+0x96FB	0x6CB9	#CJK UNIFIED IDEOGRAPH
+0x96FC	0x7652	#CJK UNIFIED IDEOGRAPH
+0x9740	0x8AED	#CJK UNIFIED IDEOGRAPH
+0x9741	0x8F38	#CJK UNIFIED IDEOGRAPH
+0x9742	0x552F	#CJK UNIFIED IDEOGRAPH
+0x9743	0x4F51	#CJK UNIFIED IDEOGRAPH
+0x9744	0x512A	#CJK UNIFIED IDEOGRAPH
+0x9745	0x52C7	#CJK UNIFIED IDEOGRAPH
+0x9746	0x53CB	#CJK UNIFIED IDEOGRAPH
+0x9747	0x5BA5	#CJK UNIFIED IDEOGRAPH
+0x9748	0x5E7D	#CJK UNIFIED IDEOGRAPH
+0x9749	0x60A0	#CJK UNIFIED IDEOGRAPH
+0x974A	0x6182	#CJK UNIFIED IDEOGRAPH
+0x974B	0x63D6	#CJK UNIFIED IDEOGRAPH
+0x974C	0x6709	#CJK UNIFIED IDEOGRAPH
+0x974D	0x67DA	#CJK UNIFIED IDEOGRAPH
+0x974E	0x6E67	#CJK UNIFIED IDEOGRAPH
+0x974F	0x6D8C	#CJK UNIFIED IDEOGRAPH
+0x9750	0x7336	#CJK UNIFIED IDEOGRAPH
+0x9751	0x7337	#CJK UNIFIED IDEOGRAPH
+0x9752	0x7531	#CJK UNIFIED IDEOGRAPH
+0x9753	0x7950	#CJK UNIFIED IDEOGRAPH
+0x9754	0x88D5	#CJK UNIFIED IDEOGRAPH
+0x9755	0x8A98	#CJK UNIFIED IDEOGRAPH
+0x9756	0x904A	#CJK UNIFIED IDEOGRAPH
+0x9757	0x9091	#CJK UNIFIED IDEOGRAPH
+0x9758	0x90F5	#CJK UNIFIED IDEOGRAPH
+0x9759	0x96C4	#CJK UNIFIED IDEOGRAPH
+0x975A	0x878D	#CJK UNIFIED IDEOGRAPH
+0x975B	0x5915	#CJK UNIFIED IDEOGRAPH
+0x975C	0x4E88	#CJK UNIFIED IDEOGRAPH
+0x975D	0x4F59	#CJK UNIFIED IDEOGRAPH
+0x975E	0x4E0E	#CJK UNIFIED IDEOGRAPH
+0x975F	0x8A89	#CJK UNIFIED IDEOGRAPH
+0x9760	0x8F3F	#CJK UNIFIED IDEOGRAPH
+0x9761	0x9810	#CJK UNIFIED IDEOGRAPH
+0x9762	0x50AD	#CJK UNIFIED IDEOGRAPH
+0x9763	0x5E7C	#CJK UNIFIED IDEOGRAPH
+0x9764	0x5996	#CJK UNIFIED IDEOGRAPH
+0x9765	0x5BB9	#CJK UNIFIED IDEOGRAPH
+0x9766	0x5EB8	#CJK UNIFIED IDEOGRAPH
+0x9767	0x63DA	#CJK UNIFIED IDEOGRAPH
+0x9768	0x63FA	#CJK UNIFIED IDEOGRAPH
+0x9769	0x64C1	#CJK UNIFIED IDEOGRAPH
+0x976A	0x66DC	#CJK UNIFIED IDEOGRAPH
+0x976B	0x694A	#CJK UNIFIED IDEOGRAPH
+0x976C	0x69D8	#CJK UNIFIED IDEOGRAPH
+0x976D	0x6D0B	#CJK UNIFIED IDEOGRAPH
+0x976E	0x6EB6	#CJK UNIFIED IDEOGRAPH
+0x976F	0x7194	#CJK UNIFIED IDEOGRAPH
+0x9770	0x7528	#CJK UNIFIED IDEOGRAPH
+0x9771	0x7AAF	#CJK UNIFIED IDEOGRAPH
+0x9772	0x7F8A	#CJK UNIFIED IDEOGRAPH
+0x9773	0x8000	#CJK UNIFIED IDEOGRAPH
+0x9774	0x8449	#CJK UNIFIED IDEOGRAPH
+0x9775	0x84C9	#CJK UNIFIED IDEOGRAPH
+0x9776	0x8981	#CJK UNIFIED IDEOGRAPH
+0x9777	0x8B21	#CJK UNIFIED IDEOGRAPH
+0x9778	0x8E0A	#CJK UNIFIED IDEOGRAPH
+0x9779	0x9065	#CJK UNIFIED IDEOGRAPH
+0x977A	0x967D	#CJK UNIFIED IDEOGRAPH
+0x977B	0x990A	#CJK UNIFIED IDEOGRAPH
+0x977C	0x617E	#CJK UNIFIED IDEOGRAPH
+0x977D	0x6291	#CJK UNIFIED IDEOGRAPH
+0x977E	0x6B32	#CJK UNIFIED IDEOGRAPH
+0x9780	0x6C83	#CJK UNIFIED IDEOGRAPH
+0x9781	0x6D74	#CJK UNIFIED IDEOGRAPH
+0x9782	0x7FCC	#CJK UNIFIED IDEOGRAPH
+0x9783	0x7FFC	#CJK UNIFIED IDEOGRAPH
+0x9784	0x6DC0	#CJK UNIFIED IDEOGRAPH
+0x9785	0x7F85	#CJK UNIFIED IDEOGRAPH
+0x9786	0x87BA	#CJK UNIFIED IDEOGRAPH
+0x9787	0x88F8	#CJK UNIFIED IDEOGRAPH
+0x9788	0x6765	#CJK UNIFIED IDEOGRAPH
+0x9789	0x83B1	#CJK UNIFIED IDEOGRAPH
+0x978A	0x983C	#CJK UNIFIED IDEOGRAPH
+0x978B	0x96F7	#CJK UNIFIED IDEOGRAPH
+0x978C	0x6D1B	#CJK UNIFIED IDEOGRAPH
+0x978D	0x7D61	#CJK UNIFIED IDEOGRAPH
+0x978E	0x843D	#CJK UNIFIED IDEOGRAPH
+0x978F	0x916A	#CJK UNIFIED IDEOGRAPH
+0x9790	0x4E71	#CJK UNIFIED IDEOGRAPH
+0x9791	0x5375	#CJK UNIFIED IDEOGRAPH
+0x9792	0x5D50	#CJK UNIFIED IDEOGRAPH
+0x9793	0x6B04	#CJK UNIFIED IDEOGRAPH
+0x9794	0x6FEB	#CJK UNIFIED IDEOGRAPH
+0x9795	0x85CD	#CJK UNIFIED IDEOGRAPH
+0x9796	0x862D	#CJK UNIFIED IDEOGRAPH
+0x9797	0x89A7	#CJK UNIFIED IDEOGRAPH
+0x9798	0x5229	#CJK UNIFIED IDEOGRAPH
+0x9799	0x540F	#CJK UNIFIED IDEOGRAPH
+0x979A	0x5C65	#CJK UNIFIED IDEOGRAPH
+0x979B	0x674E	#CJK UNIFIED IDEOGRAPH
+0x979C	0x68A8	#CJK UNIFIED IDEOGRAPH
+0x979D	0x7406	#CJK UNIFIED IDEOGRAPH
+0x979E	0x7483	#CJK UNIFIED IDEOGRAPH
+0x979F	0x75E2	#CJK UNIFIED IDEOGRAPH
+0x97A0	0x88CF	#CJK UNIFIED IDEOGRAPH
+0x97A1	0x88E1	#CJK UNIFIED IDEOGRAPH
+0x97A2	0x91CC	#CJK UNIFIED IDEOGRAPH
+0x97A3	0x96E2	#CJK UNIFIED IDEOGRAPH
+0x97A4	0x9678	#CJK UNIFIED IDEOGRAPH
+0x97A5	0x5F8B	#CJK UNIFIED IDEOGRAPH
+0x97A6	0x7387	#CJK UNIFIED IDEOGRAPH
+0x97A7	0x7ACB	#CJK UNIFIED IDEOGRAPH
+0x97A8	0x844E	#CJK UNIFIED IDEOGRAPH
+0x97A9	0x63A0	#CJK UNIFIED IDEOGRAPH
+0x97AA	0x7565	#CJK UNIFIED IDEOGRAPH
+0x97AB	0x5289	#CJK UNIFIED IDEOGRAPH
+0x97AC	0x6D41	#CJK UNIFIED IDEOGRAPH
+0x97AD	0x6E9C	#CJK UNIFIED IDEOGRAPH
+0x97AE	0x7409	#CJK UNIFIED IDEOGRAPH
+0x97AF	0x7559	#CJK UNIFIED IDEOGRAPH
+0x97B0	0x786B	#CJK UNIFIED IDEOGRAPH
+0x97B1	0x7C92	#CJK UNIFIED IDEOGRAPH
+0x97B2	0x9686	#CJK UNIFIED IDEOGRAPH
+0x97B3	0x7ADC	#CJK UNIFIED IDEOGRAPH
+0x97B4	0x9F8D	#CJK UNIFIED IDEOGRAPH
+0x97B5	0x4FB6	#CJK UNIFIED IDEOGRAPH
+0x97B6	0x616E	#CJK UNIFIED IDEOGRAPH
+0x97B7	0x65C5	#CJK UNIFIED IDEOGRAPH
+0x97B8	0x865C	#CJK UNIFIED IDEOGRAPH
+0x97B9	0x4E86	#CJK UNIFIED IDEOGRAPH
+0x97BA	0x4EAE	#CJK UNIFIED IDEOGRAPH
+0x97BB	0x50DA	#CJK UNIFIED IDEOGRAPH
+0x97BC	0x4E21	#CJK UNIFIED IDEOGRAPH
+0x97BD	0x51CC	#CJK UNIFIED IDEOGRAPH
+0x97BE	0x5BEE	#CJK UNIFIED IDEOGRAPH
+0x97BF	0x6599	#CJK UNIFIED IDEOGRAPH
+0x97C0	0x6881	#CJK UNIFIED IDEOGRAPH
+0x97C1	0x6DBC	#CJK UNIFIED IDEOGRAPH
+0x97C2	0x731F	#CJK UNIFIED IDEOGRAPH
+0x97C3	0x7642	#CJK UNIFIED IDEOGRAPH
+0x97C4	0x77AD	#CJK UNIFIED IDEOGRAPH
+0x97C5	0x7A1C	#CJK UNIFIED IDEOGRAPH
+0x97C6	0x7CE7	#CJK UNIFIED IDEOGRAPH
+0x97C7	0x826F	#CJK UNIFIED IDEOGRAPH
+0x97C8	0x8AD2	#CJK UNIFIED IDEOGRAPH
+0x97C9	0x907C	#CJK UNIFIED IDEOGRAPH
+0x97CA	0x91CF	#CJK UNIFIED IDEOGRAPH
+0x97CB	0x9675	#CJK UNIFIED IDEOGRAPH
+0x97CC	0x9818	#CJK UNIFIED IDEOGRAPH
+0x97CD	0x529B	#CJK UNIFIED IDEOGRAPH
+0x97CE	0x7DD1	#CJK UNIFIED IDEOGRAPH
+0x97CF	0x502B	#CJK UNIFIED IDEOGRAPH
+0x97D0	0x5398	#CJK UNIFIED IDEOGRAPH
+0x97D1	0x6797	#CJK UNIFIED IDEOGRAPH
+0x97D2	0x6DCB	#CJK UNIFIED IDEOGRAPH
+0x97D3	0x71D0	#CJK UNIFIED IDEOGRAPH
+0x97D4	0x7433	#CJK UNIFIED IDEOGRAPH
+0x97D5	0x81E8	#CJK UNIFIED IDEOGRAPH
+0x97D6	0x8F2A	#CJK UNIFIED IDEOGRAPH
+0x97D7	0x96A3	#CJK UNIFIED IDEOGRAPH
+0x97D8	0x9C57	#CJK UNIFIED IDEOGRAPH
+0x97D9	0x9E9F	#CJK UNIFIED IDEOGRAPH
+0x97DA	0x7460	#CJK UNIFIED IDEOGRAPH
+0x97DB	0x5841	#CJK UNIFIED IDEOGRAPH
+0x97DC	0x6D99	#CJK UNIFIED IDEOGRAPH
+0x97DD	0x7D2F	#CJK UNIFIED IDEOGRAPH
+0x97DE	0x985E	#CJK UNIFIED IDEOGRAPH
+0x97DF	0x4EE4	#CJK UNIFIED IDEOGRAPH
+0x97E0	0x4F36	#CJK UNIFIED IDEOGRAPH
+0x97E1	0x4F8B	#CJK UNIFIED IDEOGRAPH
+0x97E2	0x51B7	#CJK UNIFIED IDEOGRAPH
+0x97E3	0x52B1	#CJK UNIFIED IDEOGRAPH
+0x97E4	0x5DBA	#CJK UNIFIED IDEOGRAPH
+0x97E5	0x601C	#CJK UNIFIED IDEOGRAPH
+0x97E6	0x73B2	#CJK UNIFIED IDEOGRAPH
+0x97E7	0x793C	#CJK UNIFIED IDEOGRAPH
+0x97E8	0x82D3	#CJK UNIFIED IDEOGRAPH
+0x97E9	0x9234	#CJK UNIFIED IDEOGRAPH
+0x97EA	0x96B7	#CJK UNIFIED IDEOGRAPH
+0x97EB	0x96F6	#CJK UNIFIED IDEOGRAPH
+0x97EC	0x970A	#CJK UNIFIED IDEOGRAPH
+0x97ED	0x9E97	#CJK UNIFIED IDEOGRAPH
+0x97EE	0x9F62	#CJK UNIFIED IDEOGRAPH
+0x97EF	0x66A6	#CJK UNIFIED IDEOGRAPH
+0x97F0	0x6B74	#CJK UNIFIED IDEOGRAPH
+0x97F1	0x5217	#CJK UNIFIED IDEOGRAPH
+0x97F2	0x52A3	#CJK UNIFIED IDEOGRAPH
+0x97F3	0x70C8	#CJK UNIFIED IDEOGRAPH
+0x97F4	0x88C2	#CJK UNIFIED IDEOGRAPH
+0x97F5	0x5EC9	#CJK UNIFIED IDEOGRAPH
+0x97F6	0x604B	#CJK UNIFIED IDEOGRAPH
+0x97F7	0x6190	#CJK UNIFIED IDEOGRAPH
+0x97F8	0x6F23	#CJK UNIFIED IDEOGRAPH
+0x97F9	0x7149	#CJK UNIFIED IDEOGRAPH
+0x97FA	0x7C3E	#CJK UNIFIED IDEOGRAPH
+0x97FB	0x7DF4	#CJK UNIFIED IDEOGRAPH
+0x97FC	0x806F	#CJK UNIFIED IDEOGRAPH
+0x9840	0x84EE	#CJK UNIFIED IDEOGRAPH
+0x9841	0x9023	#CJK UNIFIED IDEOGRAPH
+0x9842	0x932C	#CJK UNIFIED IDEOGRAPH
+0x9843	0x5442	#CJK UNIFIED IDEOGRAPH
+0x9844	0x9B6F	#CJK UNIFIED IDEOGRAPH
+0x9845	0x6AD3	#CJK UNIFIED IDEOGRAPH
+0x9846	0x7089	#CJK UNIFIED IDEOGRAPH
+0x9847	0x8CC2	#CJK UNIFIED IDEOGRAPH
+0x9848	0x8DEF	#CJK UNIFIED IDEOGRAPH
+0x9849	0x9732	#CJK UNIFIED IDEOGRAPH
+0x984A	0x52B4	#CJK UNIFIED IDEOGRAPH
+0x984B	0x5A41	#CJK UNIFIED IDEOGRAPH
+0x984C	0x5ECA	#CJK UNIFIED IDEOGRAPH
+0x984D	0x5F04	#CJK UNIFIED IDEOGRAPH
+0x984E	0x6717	#CJK UNIFIED IDEOGRAPH
+0x984F	0x697C	#CJK UNIFIED IDEOGRAPH
+0x9850	0x6994	#CJK UNIFIED IDEOGRAPH
+0x9851	0x6D6A	#CJK UNIFIED IDEOGRAPH
+0x9852	0x6F0F	#CJK UNIFIED IDEOGRAPH
+0x9853	0x7262	#CJK UNIFIED IDEOGRAPH
+0x9854	0x72FC	#CJK UNIFIED IDEOGRAPH
+0x9855	0x7BED	#CJK UNIFIED IDEOGRAPH
+0x9856	0x8001	#CJK UNIFIED IDEOGRAPH
+0x9857	0x807E	#CJK UNIFIED IDEOGRAPH
+0x9858	0x874B	#CJK UNIFIED IDEOGRAPH
+0x9859	0x90CE	#CJK UNIFIED IDEOGRAPH
+0x985A	0x516D	#CJK UNIFIED IDEOGRAPH
+0x985B	0x9E93	#CJK UNIFIED IDEOGRAPH
+0x985C	0x7984	#CJK UNIFIED IDEOGRAPH
+0x985D	0x808B	#CJK UNIFIED IDEOGRAPH
+0x985E	0x9332	#CJK UNIFIED IDEOGRAPH
+0x985F	0x8AD6	#CJK UNIFIED IDEOGRAPH
+0x9860	0x502D	#CJK UNIFIED IDEOGRAPH
+0x9861	0x548C	#CJK UNIFIED IDEOGRAPH
+0x9862	0x8A71	#CJK UNIFIED IDEOGRAPH
+0x9863	0x6B6A	#CJK UNIFIED IDEOGRAPH
+0x9864	0x8CC4	#CJK UNIFIED IDEOGRAPH
+0x9865	0x8107	#CJK UNIFIED IDEOGRAPH
+0x9866	0x60D1	#CJK UNIFIED IDEOGRAPH
+0x9867	0x67A0	#CJK UNIFIED IDEOGRAPH
+0x9868	0x9DF2	#CJK UNIFIED IDEOGRAPH
+0x9869	0x4E99	#CJK UNIFIED IDEOGRAPH
+0x986A	0x4E98	#CJK UNIFIED IDEOGRAPH
+0x986B	0x9C10	#CJK UNIFIED IDEOGRAPH
+0x986C	0x8A6B	#CJK UNIFIED IDEOGRAPH
+0x986D	0x85C1	#CJK UNIFIED IDEOGRAPH
+0x986E	0x8568	#CJK UNIFIED IDEOGRAPH
+0x986F	0x6900	#CJK UNIFIED IDEOGRAPH
+0x9870	0x6E7E	#CJK UNIFIED IDEOGRAPH
+0x9871	0x7897	#CJK UNIFIED IDEOGRAPH
+0x9872	0x8155	#CJK UNIFIED IDEOGRAPH
+0x989F	0x5F0C	#CJK UNIFIED IDEOGRAPH
+0x98A0	0x4E10	#CJK UNIFIED IDEOGRAPH
+0x98A1	0x4E15	#CJK UNIFIED IDEOGRAPH
+0x98A2	0x4E2A	#CJK UNIFIED IDEOGRAPH
+0x98A3	0x4E31	#CJK UNIFIED IDEOGRAPH
+0x98A4	0x4E36	#CJK UNIFIED IDEOGRAPH
+0x98A5	0x4E3C	#CJK UNIFIED IDEOGRAPH
+0x98A6	0x4E3F	#CJK UNIFIED IDEOGRAPH
+0x98A7	0x4E42	#CJK UNIFIED IDEOGRAPH
+0x98A8	0x4E56	#CJK UNIFIED IDEOGRAPH
+0x98A9	0x4E58	#CJK UNIFIED IDEOGRAPH
+0x98AA	0x4E82	#CJK UNIFIED IDEOGRAPH
+0x98AB	0x4E85	#CJK UNIFIED IDEOGRAPH
+0x98AC	0x8C6B	#CJK UNIFIED IDEOGRAPH
+0x98AD	0x4E8A	#CJK UNIFIED IDEOGRAPH
+0x98AE	0x8212	#CJK UNIFIED IDEOGRAPH
+0x98AF	0x5F0D	#CJK UNIFIED IDEOGRAPH
+0x98B0	0x4E8E	#CJK UNIFIED IDEOGRAPH
+0x98B1	0x4E9E	#CJK UNIFIED IDEOGRAPH
+0x98B2	0x4E9F	#CJK UNIFIED IDEOGRAPH
+0x98B3	0x4EA0	#CJK UNIFIED IDEOGRAPH
+0x98B4	0x4EA2	#CJK UNIFIED IDEOGRAPH
+0x98B5	0x4EB0	#CJK UNIFIED IDEOGRAPH
+0x98B6	0x4EB3	#CJK UNIFIED IDEOGRAPH
+0x98B7	0x4EB6	#CJK UNIFIED IDEOGRAPH
+0x98B8	0x4ECE	#CJK UNIFIED IDEOGRAPH
+0x98B9	0x4ECD	#CJK UNIFIED IDEOGRAPH
+0x98BA	0x4EC4	#CJK UNIFIED IDEOGRAPH
+0x98BB	0x4EC6	#CJK UNIFIED IDEOGRAPH
+0x98BC	0x4EC2	#CJK UNIFIED IDEOGRAPH
+0x98BD	0x4ED7	#CJK UNIFIED IDEOGRAPH
+0x98BE	0x4EDE	#CJK UNIFIED IDEOGRAPH
+0x98BF	0x4EED	#CJK UNIFIED IDEOGRAPH
+0x98C0	0x4EDF	#CJK UNIFIED IDEOGRAPH
+0x98C1	0x4EF7	#CJK UNIFIED IDEOGRAPH
+0x98C2	0x4F09	#CJK UNIFIED IDEOGRAPH
+0x98C3	0x4F5A	#CJK UNIFIED IDEOGRAPH
+0x98C4	0x4F30	#CJK UNIFIED IDEOGRAPH
+0x98C5	0x4F5B	#CJK UNIFIED IDEOGRAPH
+0x98C6	0x4F5D	#CJK UNIFIED IDEOGRAPH
+0x98C7	0x4F57	#CJK UNIFIED IDEOGRAPH
+0x98C8	0x4F47	#CJK UNIFIED IDEOGRAPH
+0x98C9	0x4F76	#CJK UNIFIED IDEOGRAPH
+0x98CA	0x4F88	#CJK UNIFIED IDEOGRAPH
+0x98CB	0x4F8F	#CJK UNIFIED IDEOGRAPH
+0x98CC	0x4F98	#CJK UNIFIED IDEOGRAPH
+0x98CD	0x4F7B	#CJK UNIFIED IDEOGRAPH
+0x98CE	0x4F69	#CJK UNIFIED IDEOGRAPH
+0x98CF	0x4F70	#CJK UNIFIED IDEOGRAPH
+0x98D0	0x4F91	#CJK UNIFIED IDEOGRAPH
+0x98D1	0x4F6F	#CJK UNIFIED IDEOGRAPH
+0x98D2	0x4F86	#CJK UNIFIED IDEOGRAPH
+0x98D3	0x4F96	#CJK UNIFIED IDEOGRAPH
+0x98D4	0x5118	#CJK UNIFIED IDEOGRAPH
+0x98D5	0x4FD4	#CJK UNIFIED IDEOGRAPH
+0x98D6	0x4FDF	#CJK UNIFIED IDEOGRAPH
+0x98D7	0x4FCE	#CJK UNIFIED IDEOGRAPH
+0x98D8	0x4FD8	#CJK UNIFIED IDEOGRAPH
+0x98D9	0x4FDB	#CJK UNIFIED IDEOGRAPH
+0x98DA	0x4FD1	#CJK UNIFIED IDEOGRAPH
+0x98DB	0x4FDA	#CJK UNIFIED IDEOGRAPH
+0x98DC	0x4FD0	#CJK UNIFIED IDEOGRAPH
+0x98DD	0x4FE4	#CJK UNIFIED IDEOGRAPH
+0x98DE	0x4FE5	#CJK UNIFIED IDEOGRAPH
+0x98DF	0x501A	#CJK UNIFIED IDEOGRAPH
+0x98E0	0x5028	#CJK UNIFIED IDEOGRAPH
+0x98E1	0x5014	#CJK UNIFIED IDEOGRAPH
+0x98E2	0x502A	#CJK UNIFIED IDEOGRAPH
+0x98E3	0x5025	#CJK UNIFIED IDEOGRAPH
+0x98E4	0x5005	#CJK UNIFIED IDEOGRAPH
+0x98E5	0x4F1C	#CJK UNIFIED IDEOGRAPH
+0x98E6	0x4FF6	#CJK UNIFIED IDEOGRAPH
+0x98E7	0x5021	#CJK UNIFIED IDEOGRAPH
+0x98E8	0x5029	#CJK UNIFIED IDEOGRAPH
+0x98E9	0x502C	#CJK UNIFIED IDEOGRAPH
+0x98EA	0x4FFE	#CJK UNIFIED IDEOGRAPH
+0x98EB	0x4FEF	#CJK UNIFIED IDEOGRAPH
+0x98EC	0x5011	#CJK UNIFIED IDEOGRAPH
+0x98ED	0x5006	#CJK UNIFIED IDEOGRAPH
+0x98EE	0x5043	#CJK UNIFIED IDEOGRAPH
+0x98EF	0x5047	#CJK UNIFIED IDEOGRAPH
+0x98F0	0x6703	#CJK UNIFIED IDEOGRAPH
+0x98F1	0x5055	#CJK UNIFIED IDEOGRAPH
+0x98F2	0x5050	#CJK UNIFIED IDEOGRAPH
+0x98F3	0x5048	#CJK UNIFIED IDEOGRAPH
+0x98F4	0x505A	#CJK UNIFIED IDEOGRAPH
+0x98F5	0x5056	#CJK UNIFIED IDEOGRAPH
+0x98F6	0x506C	#CJK UNIFIED IDEOGRAPH
+0x98F7	0x5078	#CJK UNIFIED IDEOGRAPH
+0x98F8	0x5080	#CJK UNIFIED IDEOGRAPH
+0x98F9	0x509A	#CJK UNIFIED IDEOGRAPH
+0x98FA	0x5085	#CJK UNIFIED IDEOGRAPH
+0x98FB	0x50B4	#CJK UNIFIED IDEOGRAPH
+0x98FC	0x50B2	#CJK UNIFIED IDEOGRAPH
+0x9940	0x50C9	#CJK UNIFIED IDEOGRAPH
+0x9941	0x50CA	#CJK UNIFIED IDEOGRAPH
+0x9942	0x50B3	#CJK UNIFIED IDEOGRAPH
+0x9943	0x50C2	#CJK UNIFIED IDEOGRAPH
+0x9944	0x50D6	#CJK UNIFIED IDEOGRAPH
+0x9945	0x50DE	#CJK UNIFIED IDEOGRAPH
+0x9946	0x50E5	#CJK UNIFIED IDEOGRAPH
+0x9947	0x50ED	#CJK UNIFIED IDEOGRAPH
+0x9948	0x50E3	#CJK UNIFIED IDEOGRAPH
+0x9949	0x50EE	#CJK UNIFIED IDEOGRAPH
+0x994A	0x50F9	#CJK UNIFIED IDEOGRAPH
+0x994B	0x50F5	#CJK UNIFIED IDEOGRAPH
+0x994C	0x5109	#CJK UNIFIED IDEOGRAPH
+0x994D	0x5101	#CJK UNIFIED IDEOGRAPH
+0x994E	0x5102	#CJK UNIFIED IDEOGRAPH
+0x994F	0x5116	#CJK UNIFIED IDEOGRAPH
+0x9950	0x5115	#CJK UNIFIED IDEOGRAPH
+0x9951	0x5114	#CJK UNIFIED IDEOGRAPH
+0x9952	0x511A	#CJK UNIFIED IDEOGRAPH
+0x9953	0x5121	#CJK UNIFIED IDEOGRAPH
+0x9954	0x513A	#CJK UNIFIED IDEOGRAPH
+0x9955	0x5137	#CJK UNIFIED IDEOGRAPH
+0x9956	0x513C	#CJK UNIFIED IDEOGRAPH
+0x9957	0x513B	#CJK UNIFIED IDEOGRAPH
+0x9958	0x513F	#CJK UNIFIED IDEOGRAPH
+0x9959	0x5140	#CJK UNIFIED IDEOGRAPH
+0x995A	0x5152	#CJK UNIFIED IDEOGRAPH
+0x995B	0x514C	#CJK UNIFIED IDEOGRAPH
+0x995C	0x5154	#CJK UNIFIED IDEOGRAPH
+0x995D	0x5162	#CJK UNIFIED IDEOGRAPH
+0x995E	0x7AF8	#CJK UNIFIED IDEOGRAPH
+0x995F	0x5169	#CJK UNIFIED IDEOGRAPH
+0x9960	0x516A	#CJK UNIFIED IDEOGRAPH
+0x9961	0x516E	#CJK UNIFIED IDEOGRAPH
+0x9962	0x5180	#CJK UNIFIED IDEOGRAPH
+0x9963	0x5182	#CJK UNIFIED IDEOGRAPH
+0x9964	0x56D8	#CJK UNIFIED IDEOGRAPH
+0x9965	0x518C	#CJK UNIFIED IDEOGRAPH
+0x9966	0x5189	#CJK UNIFIED IDEOGRAPH
+0x9967	0x518F	#CJK UNIFIED IDEOGRAPH
+0x9968	0x5191	#CJK UNIFIED IDEOGRAPH
+0x9969	0x5193	#CJK UNIFIED IDEOGRAPH
+0x996A	0x5195	#CJK UNIFIED IDEOGRAPH
+0x996B	0x5196	#CJK UNIFIED IDEOGRAPH
+0x996C	0x51A4	#CJK UNIFIED IDEOGRAPH
+0x996D	0x51A6	#CJK UNIFIED IDEOGRAPH
+0x996E	0x51A2	#CJK UNIFIED IDEOGRAPH
+0x996F	0x51A9	#CJK UNIFIED IDEOGRAPH
+0x9970	0x51AA	#CJK UNIFIED IDEOGRAPH
+0x9971	0x51AB	#CJK UNIFIED IDEOGRAPH
+0x9972	0x51B3	#CJK UNIFIED IDEOGRAPH
+0x9973	0x51B1	#CJK UNIFIED IDEOGRAPH
+0x9974	0x51B2	#CJK UNIFIED IDEOGRAPH
+0x9975	0x51B0	#CJK UNIFIED IDEOGRAPH
+0x9976	0x51B5	#CJK UNIFIED IDEOGRAPH
+0x9977	0x51BD	#CJK UNIFIED IDEOGRAPH
+0x9978	0x51C5	#CJK UNIFIED IDEOGRAPH
+0x9979	0x51C9	#CJK UNIFIED IDEOGRAPH
+0x997A	0x51DB	#CJK UNIFIED IDEOGRAPH
+0x997B	0x51E0	#CJK UNIFIED IDEOGRAPH
+0x997C	0x8655	#CJK UNIFIED IDEOGRAPH
+0x997D	0x51E9	#CJK UNIFIED IDEOGRAPH
+0x997E	0x51ED	#CJK UNIFIED IDEOGRAPH
+0x9980	0x51F0	#CJK UNIFIED IDEOGRAPH
+0x9981	0x51F5	#CJK UNIFIED IDEOGRAPH
+0x9982	0x51FE	#CJK UNIFIED IDEOGRAPH
+0x9983	0x5204	#CJK UNIFIED IDEOGRAPH
+0x9984	0x520B	#CJK UNIFIED IDEOGRAPH
+0x9985	0x5214	#CJK UNIFIED IDEOGRAPH
+0x9986	0x520E	#CJK UNIFIED IDEOGRAPH
+0x9987	0x5227	#CJK UNIFIED IDEOGRAPH
+0x9988	0x522A	#CJK UNIFIED IDEOGRAPH
+0x9989	0x522E	#CJK UNIFIED IDEOGRAPH
+0x998A	0x5233	#CJK UNIFIED IDEOGRAPH
+0x998B	0x5239	#CJK UNIFIED IDEOGRAPH
+0x998C	0x524F	#CJK UNIFIED IDEOGRAPH
+0x998D	0x5244	#CJK UNIFIED IDEOGRAPH
+0x998E	0x524B	#CJK UNIFIED IDEOGRAPH
+0x998F	0x524C	#CJK UNIFIED IDEOGRAPH
+0x9990	0x525E	#CJK UNIFIED IDEOGRAPH
+0x9991	0x5254	#CJK UNIFIED IDEOGRAPH
+0x9992	0x526A	#CJK UNIFIED IDEOGRAPH
+0x9993	0x5274	#CJK UNIFIED IDEOGRAPH
+0x9994	0x5269	#CJK UNIFIED IDEOGRAPH
+0x9995	0x5273	#CJK UNIFIED IDEOGRAPH
+0x9996	0x527F	#CJK UNIFIED IDEOGRAPH
+0x9997	0x527D	#CJK UNIFIED IDEOGRAPH
+0x9998	0x528D	#CJK UNIFIED IDEOGRAPH
+0x9999	0x5294	#CJK UNIFIED IDEOGRAPH
+0x999A	0x5292	#CJK UNIFIED IDEOGRAPH
+0x999B	0x5271	#CJK UNIFIED IDEOGRAPH
+0x999C	0x5288	#CJK UNIFIED IDEOGRAPH
+0x999D	0x5291	#CJK UNIFIED IDEOGRAPH
+0x999E	0x8FA8	#CJK UNIFIED IDEOGRAPH
+0x999F	0x8FA7	#CJK UNIFIED IDEOGRAPH
+0x99A0	0x52AC	#CJK UNIFIED IDEOGRAPH
+0x99A1	0x52AD	#CJK UNIFIED IDEOGRAPH
+0x99A2	0x52BC	#CJK UNIFIED IDEOGRAPH
+0x99A3	0x52B5	#CJK UNIFIED IDEOGRAPH
+0x99A4	0x52C1	#CJK UNIFIED IDEOGRAPH
+0x99A5	0x52CD	#CJK UNIFIED IDEOGRAPH
+0x99A6	0x52D7	#CJK UNIFIED IDEOGRAPH
+0x99A7	0x52DE	#CJK UNIFIED IDEOGRAPH
+0x99A8	0x52E3	#CJK UNIFIED IDEOGRAPH
+0x99A9	0x52E6	#CJK UNIFIED IDEOGRAPH
+0x99AA	0x98ED	#CJK UNIFIED IDEOGRAPH
+0x99AB	0x52E0	#CJK UNIFIED IDEOGRAPH
+0x99AC	0x52F3	#CJK UNIFIED IDEOGRAPH
+0x99AD	0x52F5	#CJK UNIFIED IDEOGRAPH
+0x99AE	0x52F8	#CJK UNIFIED IDEOGRAPH
+0x99AF	0x52F9	#CJK UNIFIED IDEOGRAPH
+0x99B0	0x5306	#CJK UNIFIED IDEOGRAPH
+0x99B1	0x5308	#CJK UNIFIED IDEOGRAPH
+0x99B2	0x7538	#CJK UNIFIED IDEOGRAPH
+0x99B3	0x530D	#CJK UNIFIED IDEOGRAPH
+0x99B4	0x5310	#CJK UNIFIED IDEOGRAPH
+0x99B5	0x530F	#CJK UNIFIED IDEOGRAPH
+0x99B6	0x5315	#CJK UNIFIED IDEOGRAPH
+0x99B7	0x531A	#CJK UNIFIED IDEOGRAPH
+0x99B8	0x5323	#CJK UNIFIED IDEOGRAPH
+0x99B9	0x532F	#CJK UNIFIED IDEOGRAPH
+0x99BA	0x5331	#CJK UNIFIED IDEOGRAPH
+0x99BB	0x5333	#CJK UNIFIED IDEOGRAPH
+0x99BC	0x5338	#CJK UNIFIED IDEOGRAPH
+0x99BD	0x5340	#CJK UNIFIED IDEOGRAPH
+0x99BE	0x5346	#CJK UNIFIED IDEOGRAPH
+0x99BF	0x5345	#CJK UNIFIED IDEOGRAPH
+0x99C0	0x4E17	#CJK UNIFIED IDEOGRAPH
+0x99C1	0x5349	#CJK UNIFIED IDEOGRAPH
+0x99C2	0x534D	#CJK UNIFIED IDEOGRAPH
+0x99C3	0x51D6	#CJK UNIFIED IDEOGRAPH
+0x99C4	0x535E	#CJK UNIFIED IDEOGRAPH
+0x99C5	0x5369	#CJK UNIFIED IDEOGRAPH
+0x99C6	0x536E	#CJK UNIFIED IDEOGRAPH
+0x99C7	0x5918	#CJK UNIFIED IDEOGRAPH
+0x99C8	0x537B	#CJK UNIFIED IDEOGRAPH
+0x99C9	0x5377	#CJK UNIFIED IDEOGRAPH
+0x99CA	0x5382	#CJK UNIFIED IDEOGRAPH
+0x99CB	0x5396	#CJK UNIFIED IDEOGRAPH
+0x99CC	0x53A0	#CJK UNIFIED IDEOGRAPH
+0x99CD	0x53A6	#CJK UNIFIED IDEOGRAPH
+0x99CE	0x53A5	#CJK UNIFIED IDEOGRAPH
+0x99CF	0x53AE	#CJK UNIFIED IDEOGRAPH
+0x99D0	0x53B0	#CJK UNIFIED IDEOGRAPH
+0x99D1	0x53B6	#CJK UNIFIED IDEOGRAPH
+0x99D2	0x53C3	#CJK UNIFIED IDEOGRAPH
+0x99D3	0x7C12	#CJK UNIFIED IDEOGRAPH
+0x99D4	0x96D9	#CJK UNIFIED IDEOGRAPH
+0x99D5	0x53DF	#CJK UNIFIED IDEOGRAPH
+0x99D6	0x66FC	#CJK UNIFIED IDEOGRAPH
+0x99D7	0x71EE	#CJK UNIFIED IDEOGRAPH
+0x99D8	0x53EE	#CJK UNIFIED IDEOGRAPH
+0x99D9	0x53E8	#CJK UNIFIED IDEOGRAPH
+0x99DA	0x53ED	#CJK UNIFIED IDEOGRAPH
+0x99DB	0x53FA	#CJK UNIFIED IDEOGRAPH
+0x99DC	0x5401	#CJK UNIFIED IDEOGRAPH
+0x99DD	0x543D	#CJK UNIFIED IDEOGRAPH
+0x99DE	0x5440	#CJK UNIFIED IDEOGRAPH
+0x99DF	0x542C	#CJK UNIFIED IDEOGRAPH
+0x99E0	0x542D	#CJK UNIFIED IDEOGRAPH
+0x99E1	0x543C	#CJK UNIFIED IDEOGRAPH
+0x99E2	0x542E	#CJK UNIFIED IDEOGRAPH
+0x99E3	0x5436	#CJK UNIFIED IDEOGRAPH
+0x99E4	0x5429	#CJK UNIFIED IDEOGRAPH
+0x99E5	0x541D	#CJK UNIFIED IDEOGRAPH
+0x99E6	0x544E	#CJK UNIFIED IDEOGRAPH
+0x99E7	0x548F	#CJK UNIFIED IDEOGRAPH
+0x99E8	0x5475	#CJK UNIFIED IDEOGRAPH
+0x99E9	0x548E	#CJK UNIFIED IDEOGRAPH
+0x99EA	0x545F	#CJK UNIFIED IDEOGRAPH
+0x99EB	0x5471	#CJK UNIFIED IDEOGRAPH
+0x99EC	0x5477	#CJK UNIFIED IDEOGRAPH
+0x99ED	0x5470	#CJK UNIFIED IDEOGRAPH
+0x99EE	0x5492	#CJK UNIFIED IDEOGRAPH
+0x99EF	0x547B	#CJK UNIFIED IDEOGRAPH
+0x99F0	0x5480	#CJK UNIFIED IDEOGRAPH
+0x99F1	0x5476	#CJK UNIFIED IDEOGRAPH
+0x99F2	0x5484	#CJK UNIFIED IDEOGRAPH
+0x99F3	0x5490	#CJK UNIFIED IDEOGRAPH
+0x99F4	0x5486	#CJK UNIFIED IDEOGRAPH
+0x99F5	0x54C7	#CJK UNIFIED IDEOGRAPH
+0x99F6	0x54A2	#CJK UNIFIED IDEOGRAPH
+0x99F7	0x54B8	#CJK UNIFIED IDEOGRAPH
+0x99F8	0x54A5	#CJK UNIFIED IDEOGRAPH
+0x99F9	0x54AC	#CJK UNIFIED IDEOGRAPH
+0x99FA	0x54C4	#CJK UNIFIED IDEOGRAPH
+0x99FB	0x54C8	#CJK UNIFIED IDEOGRAPH
+0x99FC	0x54A8	#CJK UNIFIED IDEOGRAPH
+0x9A40	0x54AB	#CJK UNIFIED IDEOGRAPH
+0x9A41	0x54C2	#CJK UNIFIED IDEOGRAPH
+0x9A42	0x54A4	#CJK UNIFIED IDEOGRAPH
+0x9A43	0x54BE	#CJK UNIFIED IDEOGRAPH
+0x9A44	0x54BC	#CJK UNIFIED IDEOGRAPH
+0x9A45	0x54D8	#CJK UNIFIED IDEOGRAPH
+0x9A46	0x54E5	#CJK UNIFIED IDEOGRAPH
+0x9A47	0x54E6	#CJK UNIFIED IDEOGRAPH
+0x9A48	0x550F	#CJK UNIFIED IDEOGRAPH
+0x9A49	0x5514	#CJK UNIFIED IDEOGRAPH
+0x9A4A	0x54FD	#CJK UNIFIED IDEOGRAPH
+0x9A4B	0x54EE	#CJK UNIFIED IDEOGRAPH
+0x9A4C	0x54ED	#CJK UNIFIED IDEOGRAPH
+0x9A4D	0x54FA	#CJK UNIFIED IDEOGRAPH
+0x9A4E	0x54E2	#CJK UNIFIED IDEOGRAPH
+0x9A4F	0x5539	#CJK UNIFIED IDEOGRAPH
+0x9A50	0x5540	#CJK UNIFIED IDEOGRAPH
+0x9A51	0x5563	#CJK UNIFIED IDEOGRAPH
+0x9A52	0x554C	#CJK UNIFIED IDEOGRAPH
+0x9A53	0x552E	#CJK UNIFIED IDEOGRAPH
+0x9A54	0x555C	#CJK UNIFIED IDEOGRAPH
+0x9A55	0x5545	#CJK UNIFIED IDEOGRAPH
+0x9A56	0x5556	#CJK UNIFIED IDEOGRAPH
+0x9A57	0x5557	#CJK UNIFIED IDEOGRAPH
+0x9A58	0x5538	#CJK UNIFIED IDEOGRAPH
+0x9A59	0x5533	#CJK UNIFIED IDEOGRAPH
+0x9A5A	0x555D	#CJK UNIFIED IDEOGRAPH
+0x9A5B	0x5599	#CJK UNIFIED IDEOGRAPH
+0x9A5C	0x5580	#CJK UNIFIED IDEOGRAPH
+0x9A5D	0x54AF	#CJK UNIFIED IDEOGRAPH
+0x9A5E	0x558A	#CJK UNIFIED IDEOGRAPH
+0x9A5F	0x559F	#CJK UNIFIED IDEOGRAPH
+0x9A60	0x557B	#CJK UNIFIED IDEOGRAPH
+0x9A61	0x557E	#CJK UNIFIED IDEOGRAPH
+0x9A62	0x5598	#CJK UNIFIED IDEOGRAPH
+0x9A63	0x559E	#CJK UNIFIED IDEOGRAPH
+0x9A64	0x55AE	#CJK UNIFIED IDEOGRAPH
+0x9A65	0x557C	#CJK UNIFIED IDEOGRAPH
+0x9A66	0x5583	#CJK UNIFIED IDEOGRAPH
+0x9A67	0x55A9	#CJK UNIFIED IDEOGRAPH
+0x9A68	0x5587	#CJK UNIFIED IDEOGRAPH
+0x9A69	0x55A8	#CJK UNIFIED IDEOGRAPH
+0x9A6A	0x55DA	#CJK UNIFIED IDEOGRAPH
+0x9A6B	0x55C5	#CJK UNIFIED IDEOGRAPH
+0x9A6C	0x55DF	#CJK UNIFIED IDEOGRAPH
+0x9A6D	0x55C4	#CJK UNIFIED IDEOGRAPH
+0x9A6E	0x55DC	#CJK UNIFIED IDEOGRAPH
+0x9A6F	0x55E4	#CJK UNIFIED IDEOGRAPH
+0x9A70	0x55D4	#CJK UNIFIED IDEOGRAPH
+0x9A71	0x5614	#CJK UNIFIED IDEOGRAPH
+0x9A72	0x55F7	#CJK UNIFIED IDEOGRAPH
+0x9A73	0x5616	#CJK UNIFIED IDEOGRAPH
+0x9A74	0x55FE	#CJK UNIFIED IDEOGRAPH
+0x9A75	0x55FD	#CJK UNIFIED IDEOGRAPH
+0x9A76	0x561B	#CJK UNIFIED IDEOGRAPH
+0x9A77	0x55F9	#CJK UNIFIED IDEOGRAPH
+0x9A78	0x564E	#CJK UNIFIED IDEOGRAPH
+0x9A79	0x5650	#CJK UNIFIED IDEOGRAPH
+0x9A7A	0x71DF	#CJK UNIFIED IDEOGRAPH
+0x9A7B	0x5634	#CJK UNIFIED IDEOGRAPH
+0x9A7C	0x5636	#CJK UNIFIED IDEOGRAPH
+0x9A7D	0x5632	#CJK UNIFIED IDEOGRAPH
+0x9A7E	0x5638	#CJK UNIFIED IDEOGRAPH
+0x9A80	0x566B	#CJK UNIFIED IDEOGRAPH
+0x9A81	0x5664	#CJK UNIFIED IDEOGRAPH
+0x9A82	0x562F	#CJK UNIFIED IDEOGRAPH
+0x9A83	0x566C	#CJK UNIFIED IDEOGRAPH
+0x9A84	0x566A	#CJK UNIFIED IDEOGRAPH
+0x9A85	0x5686	#CJK UNIFIED IDEOGRAPH
+0x9A86	0x5680	#CJK UNIFIED IDEOGRAPH
+0x9A87	0x568A	#CJK UNIFIED IDEOGRAPH
+0x9A88	0x56A0	#CJK UNIFIED IDEOGRAPH
+0x9A89	0x5694	#CJK UNIFIED IDEOGRAPH
+0x9A8A	0x568F	#CJK UNIFIED IDEOGRAPH
+0x9A8B	0x56A5	#CJK UNIFIED IDEOGRAPH
+0x9A8C	0x56AE	#CJK UNIFIED IDEOGRAPH
+0x9A8D	0x56B6	#CJK UNIFIED IDEOGRAPH
+0x9A8E	0x56B4	#CJK UNIFIED IDEOGRAPH
+0x9A8F	0x56C2	#CJK UNIFIED IDEOGRAPH
+0x9A90	0x56BC	#CJK UNIFIED IDEOGRAPH
+0x9A91	0x56C1	#CJK UNIFIED IDEOGRAPH
+0x9A92	0x56C3	#CJK UNIFIED IDEOGRAPH
+0x9A93	0x56C0	#CJK UNIFIED IDEOGRAPH
+0x9A94	0x56C8	#CJK UNIFIED IDEOGRAPH
+0x9A95	0x56CE	#CJK UNIFIED IDEOGRAPH
+0x9A96	0x56D1	#CJK UNIFIED IDEOGRAPH
+0x9A97	0x56D3	#CJK UNIFIED IDEOGRAPH
+0x9A98	0x56D7	#CJK UNIFIED IDEOGRAPH
+0x9A99	0x56EE	#CJK UNIFIED IDEOGRAPH
+0x9A9A	0x56F9	#CJK UNIFIED IDEOGRAPH
+0x9A9B	0x5700	#CJK UNIFIED IDEOGRAPH
+0x9A9C	0x56FF	#CJK UNIFIED IDEOGRAPH
+0x9A9D	0x5704	#CJK UNIFIED IDEOGRAPH
+0x9A9E	0x5709	#CJK UNIFIED IDEOGRAPH
+0x9A9F	0x5708	#CJK UNIFIED IDEOGRAPH
+0x9AA0	0x570B	#CJK UNIFIED IDEOGRAPH
+0x9AA1	0x570D	#CJK UNIFIED IDEOGRAPH
+0x9AA2	0x5713	#CJK UNIFIED IDEOGRAPH
+0x9AA3	0x5718	#CJK UNIFIED IDEOGRAPH
+0x9AA4	0x5716	#CJK UNIFIED IDEOGRAPH
+0x9AA5	0x55C7	#CJK UNIFIED IDEOGRAPH
+0x9AA6	0x571C	#CJK UNIFIED IDEOGRAPH
+0x9AA7	0x5726	#CJK UNIFIED IDEOGRAPH
+0x9AA8	0x5737	#CJK UNIFIED IDEOGRAPH
+0x9AA9	0x5738	#CJK UNIFIED IDEOGRAPH
+0x9AAA	0x574E	#CJK UNIFIED IDEOGRAPH
+0x9AAB	0x573B	#CJK UNIFIED IDEOGRAPH
+0x9AAC	0x5740	#CJK UNIFIED IDEOGRAPH
+0x9AAD	0x574F	#CJK UNIFIED IDEOGRAPH
+0x9AAE	0x5769	#CJK UNIFIED IDEOGRAPH
+0x9AAF	0x57C0	#CJK UNIFIED IDEOGRAPH
+0x9AB0	0x5788	#CJK UNIFIED IDEOGRAPH
+0x9AB1	0x5761	#CJK UNIFIED IDEOGRAPH
+0x9AB2	0x577F	#CJK UNIFIED IDEOGRAPH
+0x9AB3	0x5789	#CJK UNIFIED IDEOGRAPH
+0x9AB4	0x5793	#CJK UNIFIED IDEOGRAPH
+0x9AB5	0x57A0	#CJK UNIFIED IDEOGRAPH
+0x9AB6	0x57B3	#CJK UNIFIED IDEOGRAPH
+0x9AB7	0x57A4	#CJK UNIFIED IDEOGRAPH
+0x9AB8	0x57AA	#CJK UNIFIED IDEOGRAPH
+0x9AB9	0x57B0	#CJK UNIFIED IDEOGRAPH
+0x9ABA	0x57C3	#CJK UNIFIED IDEOGRAPH
+0x9ABB	0x57C6	#CJK UNIFIED IDEOGRAPH
+0x9ABC	0x57D4	#CJK UNIFIED IDEOGRAPH
+0x9ABD	0x57D2	#CJK UNIFIED IDEOGRAPH
+0x9ABE	0x57D3	#CJK UNIFIED IDEOGRAPH
+0x9ABF	0x580A	#CJK UNIFIED IDEOGRAPH
+0x9AC0	0x57D6	#CJK UNIFIED IDEOGRAPH
+0x9AC1	0x57E3	#CJK UNIFIED IDEOGRAPH
+0x9AC2	0x580B	#CJK UNIFIED IDEOGRAPH
+0x9AC3	0x5819	#CJK UNIFIED IDEOGRAPH
+0x9AC4	0x581D	#CJK UNIFIED IDEOGRAPH
+0x9AC5	0x5872	#CJK UNIFIED IDEOGRAPH
+0x9AC6	0x5821	#CJK UNIFIED IDEOGRAPH
+0x9AC7	0x5862	#CJK UNIFIED IDEOGRAPH
+0x9AC8	0x584B	#CJK UNIFIED IDEOGRAPH
+0x9AC9	0x5870	#CJK UNIFIED IDEOGRAPH
+0x9ACA	0x6BC0	#CJK UNIFIED IDEOGRAPH
+0x9ACB	0x5852	#CJK UNIFIED IDEOGRAPH
+0x9ACC	0x583D	#CJK UNIFIED IDEOGRAPH
+0x9ACD	0x5879	#CJK UNIFIED IDEOGRAPH
+0x9ACE	0x5885	#CJK UNIFIED IDEOGRAPH
+0x9ACF	0x58B9	#CJK UNIFIED IDEOGRAPH
+0x9AD0	0x589F	#CJK UNIFIED IDEOGRAPH
+0x9AD1	0x58AB	#CJK UNIFIED IDEOGRAPH
+0x9AD2	0x58BA	#CJK UNIFIED IDEOGRAPH
+0x9AD3	0x58DE	#CJK UNIFIED IDEOGRAPH
+0x9AD4	0x58BB	#CJK UNIFIED IDEOGRAPH
+0x9AD5	0x58B8	#CJK UNIFIED IDEOGRAPH
+0x9AD6	0x58AE	#CJK UNIFIED IDEOGRAPH
+0x9AD7	0x58C5	#CJK UNIFIED IDEOGRAPH
+0x9AD8	0x58D3	#CJK UNIFIED IDEOGRAPH
+0x9AD9	0x58D1	#CJK UNIFIED IDEOGRAPH
+0x9ADA	0x58D7	#CJK UNIFIED IDEOGRAPH
+0x9ADB	0x58D9	#CJK UNIFIED IDEOGRAPH
+0x9ADC	0x58D8	#CJK UNIFIED IDEOGRAPH
+0x9ADD	0x58E5	#CJK UNIFIED IDEOGRAPH
+0x9ADE	0x58DC	#CJK UNIFIED IDEOGRAPH
+0x9ADF	0x58E4	#CJK UNIFIED IDEOGRAPH
+0x9AE0	0x58DF	#CJK UNIFIED IDEOGRAPH
+0x9AE1	0x58EF	#CJK UNIFIED IDEOGRAPH
+0x9AE2	0x58FA	#CJK UNIFIED IDEOGRAPH
+0x9AE3	0x58F9	#CJK UNIFIED IDEOGRAPH
+0x9AE4	0x58FB	#CJK UNIFIED IDEOGRAPH
+0x9AE5	0x58FC	#CJK UNIFIED IDEOGRAPH
+0x9AE6	0x58FD	#CJK UNIFIED IDEOGRAPH
+0x9AE7	0x5902	#CJK UNIFIED IDEOGRAPH
+0x9AE8	0x590A	#CJK UNIFIED IDEOGRAPH
+0x9AE9	0x5910	#CJK UNIFIED IDEOGRAPH
+0x9AEA	0x591B	#CJK UNIFIED IDEOGRAPH
+0x9AEB	0x68A6	#CJK UNIFIED IDEOGRAPH
+0x9AEC	0x5925	#CJK UNIFIED IDEOGRAPH
+0x9AED	0x592C	#CJK UNIFIED IDEOGRAPH
+0x9AEE	0x592D	#CJK UNIFIED IDEOGRAPH
+0x9AEF	0x5932	#CJK UNIFIED IDEOGRAPH
+0x9AF0	0x5938	#CJK UNIFIED IDEOGRAPH
+0x9AF1	0x593E	#CJK UNIFIED IDEOGRAPH
+0x9AF2	0x7AD2	#CJK UNIFIED IDEOGRAPH
+0x9AF3	0x5955	#CJK UNIFIED IDEOGRAPH
+0x9AF4	0x5950	#CJK UNIFIED IDEOGRAPH
+0x9AF5	0x594E	#CJK UNIFIED IDEOGRAPH
+0x9AF6	0x595A	#CJK UNIFIED IDEOGRAPH
+0x9AF7	0x5958	#CJK UNIFIED IDEOGRAPH
+0x9AF8	0x5962	#CJK UNIFIED IDEOGRAPH
+0x9AF9	0x5960	#CJK UNIFIED IDEOGRAPH
+0x9AFA	0x5967	#CJK UNIFIED IDEOGRAPH
+0x9AFB	0x596C	#CJK UNIFIED IDEOGRAPH
+0x9AFC	0x5969	#CJK UNIFIED IDEOGRAPH
+0x9B40	0x5978	#CJK UNIFIED IDEOGRAPH
+0x9B41	0x5981	#CJK UNIFIED IDEOGRAPH
+0x9B42	0x599D	#CJK UNIFIED IDEOGRAPH
+0x9B43	0x4F5E	#CJK UNIFIED IDEOGRAPH
+0x9B44	0x4FAB	#CJK UNIFIED IDEOGRAPH
+0x9B45	0x59A3	#CJK UNIFIED IDEOGRAPH
+0x9B46	0x59B2	#CJK UNIFIED IDEOGRAPH
+0x9B47	0x59C6	#CJK UNIFIED IDEOGRAPH
+0x9B48	0x59E8	#CJK UNIFIED IDEOGRAPH
+0x9B49	0x59DC	#CJK UNIFIED IDEOGRAPH
+0x9B4A	0x598D	#CJK UNIFIED IDEOGRAPH
+0x9B4B	0x59D9	#CJK UNIFIED IDEOGRAPH
+0x9B4C	0x59DA	#CJK UNIFIED IDEOGRAPH
+0x9B4D	0x5A25	#CJK UNIFIED IDEOGRAPH
+0x9B4E	0x5A1F	#CJK UNIFIED IDEOGRAPH
+0x9B4F	0x5A11	#CJK UNIFIED IDEOGRAPH
+0x9B50	0x5A1C	#CJK UNIFIED IDEOGRAPH
+0x9B51	0x5A09	#CJK UNIFIED IDEOGRAPH
+0x9B52	0x5A1A	#CJK UNIFIED IDEOGRAPH
+0x9B53	0x5A40	#CJK UNIFIED IDEOGRAPH
+0x9B54	0x5A6C	#CJK UNIFIED IDEOGRAPH
+0x9B55	0x5A49	#CJK UNIFIED IDEOGRAPH
+0x9B56	0x5A35	#CJK UNIFIED IDEOGRAPH
+0x9B57	0x5A36	#CJK UNIFIED IDEOGRAPH
+0x9B58	0x5A62	#CJK UNIFIED IDEOGRAPH
+0x9B59	0x5A6A	#CJK UNIFIED IDEOGRAPH
+0x9B5A	0x5A9A	#CJK UNIFIED IDEOGRAPH
+0x9B5B	0x5ABC	#CJK UNIFIED IDEOGRAPH
+0x9B5C	0x5ABE	#CJK UNIFIED IDEOGRAPH
+0x9B5D	0x5ACB	#CJK UNIFIED IDEOGRAPH
+0x9B5E	0x5AC2	#CJK UNIFIED IDEOGRAPH
+0x9B5F	0x5ABD	#CJK UNIFIED IDEOGRAPH
+0x9B60	0x5AE3	#CJK UNIFIED IDEOGRAPH
+0x9B61	0x5AD7	#CJK UNIFIED IDEOGRAPH
+0x9B62	0x5AE6	#CJK UNIFIED IDEOGRAPH
+0x9B63	0x5AE9	#CJK UNIFIED IDEOGRAPH
+0x9B64	0x5AD6	#CJK UNIFIED IDEOGRAPH
+0x9B65	0x5AFA	#CJK UNIFIED IDEOGRAPH
+0x9B66	0x5AFB	#CJK UNIFIED IDEOGRAPH
+0x9B67	0x5B0C	#CJK UNIFIED IDEOGRAPH
+0x9B68	0x5B0B	#CJK UNIFIED IDEOGRAPH
+0x9B69	0x5B16	#CJK UNIFIED IDEOGRAPH
+0x9B6A	0x5B32	#CJK UNIFIED IDEOGRAPH
+0x9B6B	0x5AD0	#CJK UNIFIED IDEOGRAPH
+0x9B6C	0x5B2A	#CJK UNIFIED IDEOGRAPH
+0x9B6D	0x5B36	#CJK UNIFIED IDEOGRAPH
+0x9B6E	0x5B3E	#CJK UNIFIED IDEOGRAPH
+0x9B6F	0x5B43	#CJK UNIFIED IDEOGRAPH
+0x9B70	0x5B45	#CJK UNIFIED IDEOGRAPH
+0x9B71	0x5B40	#CJK UNIFIED IDEOGRAPH
+0x9B72	0x5B51	#CJK UNIFIED IDEOGRAPH
+0x9B73	0x5B55	#CJK UNIFIED IDEOGRAPH
+0x9B74	0x5B5A	#CJK UNIFIED IDEOGRAPH
+0x9B75	0x5B5B	#CJK UNIFIED IDEOGRAPH
+0x9B76	0x5B65	#CJK UNIFIED IDEOGRAPH
+0x9B77	0x5B69	#CJK UNIFIED IDEOGRAPH
+0x9B78	0x5B70	#CJK UNIFIED IDEOGRAPH
+0x9B79	0x5B73	#CJK UNIFIED IDEOGRAPH
+0x9B7A	0x5B75	#CJK UNIFIED IDEOGRAPH
+0x9B7B	0x5B78	#CJK UNIFIED IDEOGRAPH
+0x9B7C	0x6588	#CJK UNIFIED IDEOGRAPH
+0x9B7D	0x5B7A	#CJK UNIFIED IDEOGRAPH
+0x9B7E	0x5B80	#CJK UNIFIED IDEOGRAPH
+0x9B80	0x5B83	#CJK UNIFIED IDEOGRAPH
+0x9B81	0x5BA6	#CJK UNIFIED IDEOGRAPH
+0x9B82	0x5BB8	#CJK UNIFIED IDEOGRAPH
+0x9B83	0x5BC3	#CJK UNIFIED IDEOGRAPH
+0x9B84	0x5BC7	#CJK UNIFIED IDEOGRAPH
+0x9B85	0x5BC9	#CJK UNIFIED IDEOGRAPH
+0x9B86	0x5BD4	#CJK UNIFIED IDEOGRAPH
+0x9B87	0x5BD0	#CJK UNIFIED IDEOGRAPH
+0x9B88	0x5BE4	#CJK UNIFIED IDEOGRAPH
+0x9B89	0x5BE6	#CJK UNIFIED IDEOGRAPH
+0x9B8A	0x5BE2	#CJK UNIFIED IDEOGRAPH
+0x9B8B	0x5BDE	#CJK UNIFIED IDEOGRAPH
+0x9B8C	0x5BE5	#CJK UNIFIED IDEOGRAPH
+0x9B8D	0x5BEB	#CJK UNIFIED IDEOGRAPH
+0x9B8E	0x5BF0	#CJK UNIFIED IDEOGRAPH
+0x9B8F	0x5BF6	#CJK UNIFIED IDEOGRAPH
+0x9B90	0x5BF3	#CJK UNIFIED IDEOGRAPH
+0x9B91	0x5C05	#CJK UNIFIED IDEOGRAPH
+0x9B92	0x5C07	#CJK UNIFIED IDEOGRAPH
+0x9B93	0x5C08	#CJK UNIFIED IDEOGRAPH
+0x9B94	0x5C0D	#CJK UNIFIED IDEOGRAPH
+0x9B95	0x5C13	#CJK UNIFIED IDEOGRAPH
+0x9B96	0x5C20	#CJK UNIFIED IDEOGRAPH
+0x9B97	0x5C22	#CJK UNIFIED IDEOGRAPH
+0x9B98	0x5C28	#CJK UNIFIED IDEOGRAPH
+0x9B99	0x5C38	#CJK UNIFIED IDEOGRAPH
+0x9B9A	0x5C39	#CJK UNIFIED IDEOGRAPH
+0x9B9B	0x5C41	#CJK UNIFIED IDEOGRAPH
+0x9B9C	0x5C46	#CJK UNIFIED IDEOGRAPH
+0x9B9D	0x5C4E	#CJK UNIFIED IDEOGRAPH
+0x9B9E	0x5C53	#CJK UNIFIED IDEOGRAPH
+0x9B9F	0x5C50	#CJK UNIFIED IDEOGRAPH
+0x9BA0	0x5C4F	#CJK UNIFIED IDEOGRAPH
+0x9BA1	0x5B71	#CJK UNIFIED IDEOGRAPH
+0x9BA2	0x5C6C	#CJK UNIFIED IDEOGRAPH
+0x9BA3	0x5C6E	#CJK UNIFIED IDEOGRAPH
+0x9BA4	0x4E62	#CJK UNIFIED IDEOGRAPH
+0x9BA5	0x5C76	#CJK UNIFIED IDEOGRAPH
+0x9BA6	0x5C79	#CJK UNIFIED IDEOGRAPH
+0x9BA7	0x5C8C	#CJK UNIFIED IDEOGRAPH
+0x9BA8	0x5C91	#CJK UNIFIED IDEOGRAPH
+0x9BA9	0x5C94	#CJK UNIFIED IDEOGRAPH
+0x9BAA	0x599B	#CJK UNIFIED IDEOGRAPH
+0x9BAB	0x5CAB	#CJK UNIFIED IDEOGRAPH
+0x9BAC	0x5CBB	#CJK UNIFIED IDEOGRAPH
+0x9BAD	0x5CB6	#CJK UNIFIED IDEOGRAPH
+0x9BAE	0x5CBC	#CJK UNIFIED IDEOGRAPH
+0x9BAF	0x5CB7	#CJK UNIFIED IDEOGRAPH
+0x9BB0	0x5CC5	#CJK UNIFIED IDEOGRAPH
+0x9BB1	0x5CBE	#CJK UNIFIED IDEOGRAPH
+0x9BB2	0x5CC7	#CJK UNIFIED IDEOGRAPH
+0x9BB3	0x5CD9	#CJK UNIFIED IDEOGRAPH
+0x9BB4	0x5CE9	#CJK UNIFIED IDEOGRAPH
+0x9BB5	0x5CFD	#CJK UNIFIED IDEOGRAPH
+0x9BB6	0x5CFA	#CJK UNIFIED IDEOGRAPH
+0x9BB7	0x5CED	#CJK UNIFIED IDEOGRAPH
+0x9BB8	0x5D8C	#CJK UNIFIED IDEOGRAPH
+0x9BB9	0x5CEA	#CJK UNIFIED IDEOGRAPH
+0x9BBA	0x5D0B	#CJK UNIFIED IDEOGRAPH
+0x9BBB	0x5D15	#CJK UNIFIED IDEOGRAPH
+0x9BBC	0x5D17	#CJK UNIFIED IDEOGRAPH
+0x9BBD	0x5D5C	#CJK UNIFIED IDEOGRAPH
+0x9BBE	0x5D1F	#CJK UNIFIED IDEOGRAPH
+0x9BBF	0x5D1B	#CJK UNIFIED IDEOGRAPH
+0x9BC0	0x5D11	#CJK UNIFIED IDEOGRAPH
+0x9BC1	0x5D14	#CJK UNIFIED IDEOGRAPH
+0x9BC2	0x5D22	#CJK UNIFIED IDEOGRAPH
+0x9BC3	0x5D1A	#CJK UNIFIED IDEOGRAPH
+0x9BC4	0x5D19	#CJK UNIFIED IDEOGRAPH
+0x9BC5	0x5D18	#CJK UNIFIED IDEOGRAPH
+0x9BC6	0x5D4C	#CJK UNIFIED IDEOGRAPH
+0x9BC7	0x5D52	#CJK UNIFIED IDEOGRAPH
+0x9BC8	0x5D4E	#CJK UNIFIED IDEOGRAPH
+0x9BC9	0x5D4B	#CJK UNIFIED IDEOGRAPH
+0x9BCA	0x5D6C	#CJK UNIFIED IDEOGRAPH
+0x9BCB	0x5D73	#CJK UNIFIED IDEOGRAPH
+0x9BCC	0x5D76	#CJK UNIFIED IDEOGRAPH
+0x9BCD	0x5D87	#CJK UNIFIED IDEOGRAPH
+0x9BCE	0x5D84	#CJK UNIFIED IDEOGRAPH
+0x9BCF	0x5D82	#CJK UNIFIED IDEOGRAPH
+0x9BD0	0x5DA2	#CJK UNIFIED IDEOGRAPH
+0x9BD1	0x5D9D	#CJK UNIFIED IDEOGRAPH
+0x9BD2	0x5DAC	#CJK UNIFIED IDEOGRAPH
+0x9BD3	0x5DAE	#CJK UNIFIED IDEOGRAPH
+0x9BD4	0x5DBD	#CJK UNIFIED IDEOGRAPH
+0x9BD5	0x5D90	#CJK UNIFIED IDEOGRAPH
+0x9BD6	0x5DB7	#CJK UNIFIED IDEOGRAPH
+0x9BD7	0x5DBC	#CJK UNIFIED IDEOGRAPH
+0x9BD8	0x5DC9	#CJK UNIFIED IDEOGRAPH
+0x9BD9	0x5DCD	#CJK UNIFIED IDEOGRAPH
+0x9BDA	0x5DD3	#CJK UNIFIED IDEOGRAPH
+0x9BDB	0x5DD2	#CJK UNIFIED IDEOGRAPH
+0x9BDC	0x5DD6	#CJK UNIFIED IDEOGRAPH
+0x9BDD	0x5DDB	#CJK UNIFIED IDEOGRAPH
+0x9BDE	0x5DEB	#CJK UNIFIED IDEOGRAPH
+0x9BDF	0x5DF2	#CJK UNIFIED IDEOGRAPH
+0x9BE0	0x5DF5	#CJK UNIFIED IDEOGRAPH
+0x9BE1	0x5E0B	#CJK UNIFIED IDEOGRAPH
+0x9BE2	0x5E1A	#CJK UNIFIED IDEOGRAPH
+0x9BE3	0x5E19	#CJK UNIFIED IDEOGRAPH
+0x9BE4	0x5E11	#CJK UNIFIED IDEOGRAPH
+0x9BE5	0x5E1B	#CJK UNIFIED IDEOGRAPH
+0x9BE6	0x5E36	#CJK UNIFIED IDEOGRAPH
+0x9BE7	0x5E37	#CJK UNIFIED IDEOGRAPH
+0x9BE8	0x5E44	#CJK UNIFIED IDEOGRAPH
+0x9BE9	0x5E43	#CJK UNIFIED IDEOGRAPH
+0x9BEA	0x5E40	#CJK UNIFIED IDEOGRAPH
+0x9BEB	0x5E4E	#CJK UNIFIED IDEOGRAPH
+0x9BEC	0x5E57	#CJK UNIFIED IDEOGRAPH
+0x9BED	0x5E54	#CJK UNIFIED IDEOGRAPH
+0x9BEE	0x5E5F	#CJK UNIFIED IDEOGRAPH
+0x9BEF	0x5E62	#CJK UNIFIED IDEOGRAPH
+0x9BF0	0x5E64	#CJK UNIFIED IDEOGRAPH
+0x9BF1	0x5E47	#CJK UNIFIED IDEOGRAPH
+0x9BF2	0x5E75	#CJK UNIFIED IDEOGRAPH
+0x9BF3	0x5E76	#CJK UNIFIED IDEOGRAPH
+0x9BF4	0x5E7A	#CJK UNIFIED IDEOGRAPH
+0x9BF5	0x9EBC	#CJK UNIFIED IDEOGRAPH
+0x9BF6	0x5E7F	#CJK UNIFIED IDEOGRAPH
+0x9BF7	0x5EA0	#CJK UNIFIED IDEOGRAPH
+0x9BF8	0x5EC1	#CJK UNIFIED IDEOGRAPH
+0x9BF9	0x5EC2	#CJK UNIFIED IDEOGRAPH
+0x9BFA	0x5EC8	#CJK UNIFIED IDEOGRAPH
+0x9BFB	0x5ED0	#CJK UNIFIED IDEOGRAPH
+0x9BFC	0x5ECF	#CJK UNIFIED IDEOGRAPH
+0x9C40	0x5ED6	#CJK UNIFIED IDEOGRAPH
+0x9C41	0x5EE3	#CJK UNIFIED IDEOGRAPH
+0x9C42	0x5EDD	#CJK UNIFIED IDEOGRAPH
+0x9C43	0x5EDA	#CJK UNIFIED IDEOGRAPH
+0x9C44	0x5EDB	#CJK UNIFIED IDEOGRAPH
+0x9C45	0x5EE2	#CJK UNIFIED IDEOGRAPH
+0x9C46	0x5EE1	#CJK UNIFIED IDEOGRAPH
+0x9C47	0x5EE8	#CJK UNIFIED IDEOGRAPH
+0x9C48	0x5EE9	#CJK UNIFIED IDEOGRAPH
+0x9C49	0x5EEC	#CJK UNIFIED IDEOGRAPH
+0x9C4A	0x5EF1	#CJK UNIFIED IDEOGRAPH
+0x9C4B	0x5EF3	#CJK UNIFIED IDEOGRAPH
+0x9C4C	0x5EF0	#CJK UNIFIED IDEOGRAPH
+0x9C4D	0x5EF4	#CJK UNIFIED IDEOGRAPH
+0x9C4E	0x5EF8	#CJK UNIFIED IDEOGRAPH
+0x9C4F	0x5EFE	#CJK UNIFIED IDEOGRAPH
+0x9C50	0x5F03	#CJK UNIFIED IDEOGRAPH
+0x9C51	0x5F09	#CJK UNIFIED IDEOGRAPH
+0x9C52	0x5F5D	#CJK UNIFIED IDEOGRAPH
+0x9C53	0x5F5C	#CJK UNIFIED IDEOGRAPH
+0x9C54	0x5F0B	#CJK UNIFIED IDEOGRAPH
+0x9C55	0x5F11	#CJK UNIFIED IDEOGRAPH
+0x9C56	0x5F16	#CJK UNIFIED IDEOGRAPH
+0x9C57	0x5F29	#CJK UNIFIED IDEOGRAPH
+0x9C58	0x5F2D	#CJK UNIFIED IDEOGRAPH
+0x9C59	0x5F38	#CJK UNIFIED IDEOGRAPH
+0x9C5A	0x5F41	#CJK UNIFIED IDEOGRAPH
+0x9C5B	0x5F48	#CJK UNIFIED IDEOGRAPH
+0x9C5C	0x5F4C	#CJK UNIFIED IDEOGRAPH
+0x9C5D	0x5F4E	#CJK UNIFIED IDEOGRAPH
+0x9C5E	0x5F2F	#CJK UNIFIED IDEOGRAPH
+0x9C5F	0x5F51	#CJK UNIFIED IDEOGRAPH
+0x9C60	0x5F56	#CJK UNIFIED IDEOGRAPH
+0x9C61	0x5F57	#CJK UNIFIED IDEOGRAPH
+0x9C62	0x5F59	#CJK UNIFIED IDEOGRAPH
+0x9C63	0x5F61	#CJK UNIFIED IDEOGRAPH
+0x9C64	0x5F6D	#CJK UNIFIED IDEOGRAPH
+0x9C65	0x5F73	#CJK UNIFIED IDEOGRAPH
+0x9C66	0x5F77	#CJK UNIFIED IDEOGRAPH
+0x9C67	0x5F83	#CJK UNIFIED IDEOGRAPH
+0x9C68	0x5F82	#CJK UNIFIED IDEOGRAPH
+0x9C69	0x5F7F	#CJK UNIFIED IDEOGRAPH
+0x9C6A	0x5F8A	#CJK UNIFIED IDEOGRAPH
+0x9C6B	0x5F88	#CJK UNIFIED IDEOGRAPH
+0x9C6C	0x5F91	#CJK UNIFIED IDEOGRAPH
+0x9C6D	0x5F87	#CJK UNIFIED IDEOGRAPH
+0x9C6E	0x5F9E	#CJK UNIFIED IDEOGRAPH
+0x9C6F	0x5F99	#CJK UNIFIED IDEOGRAPH
+0x9C70	0x5F98	#CJK UNIFIED IDEOGRAPH
+0x9C71	0x5FA0	#CJK UNIFIED IDEOGRAPH
+0x9C72	0x5FA8	#CJK UNIFIED IDEOGRAPH
+0x9C73	0x5FAD	#CJK UNIFIED IDEOGRAPH
+0x9C74	0x5FBC	#CJK UNIFIED IDEOGRAPH
+0x9C75	0x5FD6	#CJK UNIFIED IDEOGRAPH
+0x9C76	0x5FFB	#CJK UNIFIED IDEOGRAPH
+0x9C77	0x5FE4	#CJK UNIFIED IDEOGRAPH
+0x9C78	0x5FF8	#CJK UNIFIED IDEOGRAPH
+0x9C79	0x5FF1	#CJK UNIFIED IDEOGRAPH
+0x9C7A	0x5FDD	#CJK UNIFIED IDEOGRAPH
+0x9C7B	0x60B3	#CJK UNIFIED IDEOGRAPH
+0x9C7C	0x5FFF	#CJK UNIFIED IDEOGRAPH
+0x9C7D	0x6021	#CJK UNIFIED IDEOGRAPH
+0x9C7E	0x6060	#CJK UNIFIED IDEOGRAPH
+0x9C80	0x6019	#CJK UNIFIED IDEOGRAPH
+0x9C81	0x6010	#CJK UNIFIED IDEOGRAPH
+0x9C82	0x6029	#CJK UNIFIED IDEOGRAPH
+0x9C83	0x600E	#CJK UNIFIED IDEOGRAPH
+0x9C84	0x6031	#CJK UNIFIED IDEOGRAPH
+0x9C85	0x601B	#CJK UNIFIED IDEOGRAPH
+0x9C86	0x6015	#CJK UNIFIED IDEOGRAPH
+0x9C87	0x602B	#CJK UNIFIED IDEOGRAPH
+0x9C88	0x6026	#CJK UNIFIED IDEOGRAPH
+0x9C89	0x600F	#CJK UNIFIED IDEOGRAPH
+0x9C8A	0x603A	#CJK UNIFIED IDEOGRAPH
+0x9C8B	0x605A	#CJK UNIFIED IDEOGRAPH
+0x9C8C	0x6041	#CJK UNIFIED IDEOGRAPH
+0x9C8D	0x606A	#CJK UNIFIED IDEOGRAPH
+0x9C8E	0x6077	#CJK UNIFIED IDEOGRAPH
+0x9C8F	0x605F	#CJK UNIFIED IDEOGRAPH
+0x9C90	0x604A	#CJK UNIFIED IDEOGRAPH
+0x9C91	0x6046	#CJK UNIFIED IDEOGRAPH
+0x9C92	0x604D	#CJK UNIFIED IDEOGRAPH
+0x9C93	0x6063	#CJK UNIFIED IDEOGRAPH
+0x9C94	0x6043	#CJK UNIFIED IDEOGRAPH
+0x9C95	0x6064	#CJK UNIFIED IDEOGRAPH
+0x9C96	0x6042	#CJK UNIFIED IDEOGRAPH
+0x9C97	0x606C	#CJK UNIFIED IDEOGRAPH
+0x9C98	0x606B	#CJK UNIFIED IDEOGRAPH
+0x9C99	0x6059	#CJK UNIFIED IDEOGRAPH
+0x9C9A	0x6081	#CJK UNIFIED IDEOGRAPH
+0x9C9B	0x608D	#CJK UNIFIED IDEOGRAPH
+0x9C9C	0x60E7	#CJK UNIFIED IDEOGRAPH
+0x9C9D	0x6083	#CJK UNIFIED IDEOGRAPH
+0x9C9E	0x609A	#CJK UNIFIED IDEOGRAPH
+0x9C9F	0x6084	#CJK UNIFIED IDEOGRAPH
+0x9CA0	0x609B	#CJK UNIFIED IDEOGRAPH
+0x9CA1	0x6096	#CJK UNIFIED IDEOGRAPH
+0x9CA2	0x6097	#CJK UNIFIED IDEOGRAPH
+0x9CA3	0x6092	#CJK UNIFIED IDEOGRAPH
+0x9CA4	0x60A7	#CJK UNIFIED IDEOGRAPH
+0x9CA5	0x608B	#CJK UNIFIED IDEOGRAPH
+0x9CA6	0x60E1	#CJK UNIFIED IDEOGRAPH
+0x9CA7	0x60B8	#CJK UNIFIED IDEOGRAPH
+0x9CA8	0x60E0	#CJK UNIFIED IDEOGRAPH
+0x9CA9	0x60D3	#CJK UNIFIED IDEOGRAPH
+0x9CAA	0x60B4	#CJK UNIFIED IDEOGRAPH
+0x9CAB	0x5FF0	#CJK UNIFIED IDEOGRAPH
+0x9CAC	0x60BD	#CJK UNIFIED IDEOGRAPH
+0x9CAD	0x60C6	#CJK UNIFIED IDEOGRAPH
+0x9CAE	0x60B5	#CJK UNIFIED IDEOGRAPH
+0x9CAF	0x60D8	#CJK UNIFIED IDEOGRAPH
+0x9CB0	0x614D	#CJK UNIFIED IDEOGRAPH
+0x9CB1	0x6115	#CJK UNIFIED IDEOGRAPH
+0x9CB2	0x6106	#CJK UNIFIED IDEOGRAPH
+0x9CB3	0x60F6	#CJK UNIFIED IDEOGRAPH
+0x9CB4	0x60F7	#CJK UNIFIED IDEOGRAPH
+0x9CB5	0x6100	#CJK UNIFIED IDEOGRAPH
+0x9CB6	0x60F4	#CJK UNIFIED IDEOGRAPH
+0x9CB7	0x60FA	#CJK UNIFIED IDEOGRAPH
+0x9CB8	0x6103	#CJK UNIFIED IDEOGRAPH
+0x9CB9	0x6121	#CJK UNIFIED IDEOGRAPH
+0x9CBA	0x60FB	#CJK UNIFIED IDEOGRAPH
+0x9CBB	0x60F1	#CJK UNIFIED IDEOGRAPH
+0x9CBC	0x610D	#CJK UNIFIED IDEOGRAPH
+0x9CBD	0x610E	#CJK UNIFIED IDEOGRAPH
+0x9CBE	0x6147	#CJK UNIFIED IDEOGRAPH
+0x9CBF	0x613E	#CJK UNIFIED IDEOGRAPH
+0x9CC0	0x6128	#CJK UNIFIED IDEOGRAPH
+0x9CC1	0x6127	#CJK UNIFIED IDEOGRAPH
+0x9CC2	0x614A	#CJK UNIFIED IDEOGRAPH
+0x9CC3	0x613F	#CJK UNIFIED IDEOGRAPH
+0x9CC4	0x613C	#CJK UNIFIED IDEOGRAPH
+0x9CC5	0x612C	#CJK UNIFIED IDEOGRAPH
+0x9CC6	0x6134	#CJK UNIFIED IDEOGRAPH
+0x9CC7	0x613D	#CJK UNIFIED IDEOGRAPH
+0x9CC8	0x6142	#CJK UNIFIED IDEOGRAPH
+0x9CC9	0x6144	#CJK UNIFIED IDEOGRAPH
+0x9CCA	0x6173	#CJK UNIFIED IDEOGRAPH
+0x9CCB	0x6177	#CJK UNIFIED IDEOGRAPH
+0x9CCC	0x6158	#CJK UNIFIED IDEOGRAPH
+0x9CCD	0x6159	#CJK UNIFIED IDEOGRAPH
+0x9CCE	0x615A	#CJK UNIFIED IDEOGRAPH
+0x9CCF	0x616B	#CJK UNIFIED IDEOGRAPH
+0x9CD0	0x6174	#CJK UNIFIED IDEOGRAPH
+0x9CD1	0x616F	#CJK UNIFIED IDEOGRAPH
+0x9CD2	0x6165	#CJK UNIFIED IDEOGRAPH
+0x9CD3	0x6171	#CJK UNIFIED IDEOGRAPH
+0x9CD4	0x615F	#CJK UNIFIED IDEOGRAPH
+0x9CD5	0x615D	#CJK UNIFIED IDEOGRAPH
+0x9CD6	0x6153	#CJK UNIFIED IDEOGRAPH
+0x9CD7	0x6175	#CJK UNIFIED IDEOGRAPH
+0x9CD8	0x6199	#CJK UNIFIED IDEOGRAPH
+0x9CD9	0x6196	#CJK UNIFIED IDEOGRAPH
+0x9CDA	0x6187	#CJK UNIFIED IDEOGRAPH
+0x9CDB	0x61AC	#CJK UNIFIED IDEOGRAPH
+0x9CDC	0x6194	#CJK UNIFIED IDEOGRAPH
+0x9CDD	0x619A	#CJK UNIFIED IDEOGRAPH
+0x9CDE	0x618A	#CJK UNIFIED IDEOGRAPH
+0x9CDF	0x6191	#CJK UNIFIED IDEOGRAPH
+0x9CE0	0x61AB	#CJK UNIFIED IDEOGRAPH
+0x9CE1	0x61AE	#CJK UNIFIED IDEOGRAPH
+0x9CE2	0x61CC	#CJK UNIFIED IDEOGRAPH
+0x9CE3	0x61CA	#CJK UNIFIED IDEOGRAPH
+0x9CE4	0x61C9	#CJK UNIFIED IDEOGRAPH
+0x9CE5	0x61F7	#CJK UNIFIED IDEOGRAPH
+0x9CE6	0x61C8	#CJK UNIFIED IDEOGRAPH
+0x9CE7	0x61C3	#CJK UNIFIED IDEOGRAPH
+0x9CE8	0x61C6	#CJK UNIFIED IDEOGRAPH
+0x9CE9	0x61BA	#CJK UNIFIED IDEOGRAPH
+0x9CEA	0x61CB	#CJK UNIFIED IDEOGRAPH
+0x9CEB	0x7F79	#CJK UNIFIED IDEOGRAPH
+0x9CEC	0x61CD	#CJK UNIFIED IDEOGRAPH
+0x9CED	0x61E6	#CJK UNIFIED IDEOGRAPH
+0x9CEE	0x61E3	#CJK UNIFIED IDEOGRAPH
+0x9CEF	0x61F6	#CJK UNIFIED IDEOGRAPH
+0x9CF0	0x61FA	#CJK UNIFIED IDEOGRAPH
+0x9CF1	0x61F4	#CJK UNIFIED IDEOGRAPH
+0x9CF2	0x61FF	#CJK UNIFIED IDEOGRAPH
+0x9CF3	0x61FD	#CJK UNIFIED IDEOGRAPH
+0x9CF4	0x61FC	#CJK UNIFIED IDEOGRAPH
+0x9CF5	0x61FE	#CJK UNIFIED IDEOGRAPH
+0x9CF6	0x6200	#CJK UNIFIED IDEOGRAPH
+0x9CF7	0x6208	#CJK UNIFIED IDEOGRAPH
+0x9CF8	0x6209	#CJK UNIFIED IDEOGRAPH
+0x9CF9	0x620D	#CJK UNIFIED IDEOGRAPH
+0x9CFA	0x620C	#CJK UNIFIED IDEOGRAPH
+0x9CFB	0x6214	#CJK UNIFIED IDEOGRAPH
+0x9CFC	0x621B	#CJK UNIFIED IDEOGRAPH
+0x9D40	0x621E	#CJK UNIFIED IDEOGRAPH
+0x9D41	0x6221	#CJK UNIFIED IDEOGRAPH
+0x9D42	0x622A	#CJK UNIFIED IDEOGRAPH
+0x9D43	0x622E	#CJK UNIFIED IDEOGRAPH
+0x9D44	0x6230	#CJK UNIFIED IDEOGRAPH
+0x9D45	0x6232	#CJK UNIFIED IDEOGRAPH
+0x9D46	0x6233	#CJK UNIFIED IDEOGRAPH
+0x9D47	0x6241	#CJK UNIFIED IDEOGRAPH
+0x9D48	0x624E	#CJK UNIFIED IDEOGRAPH
+0x9D49	0x625E	#CJK UNIFIED IDEOGRAPH
+0x9D4A	0x6263	#CJK UNIFIED IDEOGRAPH
+0x9D4B	0x625B	#CJK UNIFIED IDEOGRAPH
+0x9D4C	0x6260	#CJK UNIFIED IDEOGRAPH
+0x9D4D	0x6268	#CJK UNIFIED IDEOGRAPH
+0x9D4E	0x627C	#CJK UNIFIED IDEOGRAPH
+0x9D4F	0x6282	#CJK UNIFIED IDEOGRAPH
+0x9D50	0x6289	#CJK UNIFIED IDEOGRAPH
+0x9D51	0x627E	#CJK UNIFIED IDEOGRAPH
+0x9D52	0x6292	#CJK UNIFIED IDEOGRAPH
+0x9D53	0x6293	#CJK UNIFIED IDEOGRAPH
+0x9D54	0x6296	#CJK UNIFIED IDEOGRAPH
+0x9D55	0x62D4	#CJK UNIFIED IDEOGRAPH
+0x9D56	0x6283	#CJK UNIFIED IDEOGRAPH
+0x9D57	0x6294	#CJK UNIFIED IDEOGRAPH
+0x9D58	0x62D7	#CJK UNIFIED IDEOGRAPH
+0x9D59	0x62D1	#CJK UNIFIED IDEOGRAPH
+0x9D5A	0x62BB	#CJK UNIFIED IDEOGRAPH
+0x9D5B	0x62CF	#CJK UNIFIED IDEOGRAPH
+0x9D5C	0x62FF	#CJK UNIFIED IDEOGRAPH
+0x9D5D	0x62C6	#CJK UNIFIED IDEOGRAPH
+0x9D5E	0x64D4	#CJK UNIFIED IDEOGRAPH
+0x9D5F	0x62C8	#CJK UNIFIED IDEOGRAPH
+0x9D60	0x62DC	#CJK UNIFIED IDEOGRAPH
+0x9D61	0x62CC	#CJK UNIFIED IDEOGRAPH
+0x9D62	0x62CA	#CJK UNIFIED IDEOGRAPH
+0x9D63	0x62C2	#CJK UNIFIED IDEOGRAPH
+0x9D64	0x62C7	#CJK UNIFIED IDEOGRAPH
+0x9D65	0x629B	#CJK UNIFIED IDEOGRAPH
+0x9D66	0x62C9	#CJK UNIFIED IDEOGRAPH
+0x9D67	0x630C	#CJK UNIFIED IDEOGRAPH
+0x9D68	0x62EE	#CJK UNIFIED IDEOGRAPH
+0x9D69	0x62F1	#CJK UNIFIED IDEOGRAPH
+0x9D6A	0x6327	#CJK UNIFIED IDEOGRAPH
+0x9D6B	0x6302	#CJK UNIFIED IDEOGRAPH
+0x9D6C	0x6308	#CJK UNIFIED IDEOGRAPH
+0x9D6D	0x62EF	#CJK UNIFIED IDEOGRAPH
+0x9D6E	0x62F5	#CJK UNIFIED IDEOGRAPH
+0x9D6F	0x6350	#CJK UNIFIED IDEOGRAPH
+0x9D70	0x633E	#CJK UNIFIED IDEOGRAPH
+0x9D71	0x634D	#CJK UNIFIED IDEOGRAPH
+0x9D72	0x641C	#CJK UNIFIED IDEOGRAPH
+0x9D73	0x634F	#CJK UNIFIED IDEOGRAPH
+0x9D74	0x6396	#CJK UNIFIED IDEOGRAPH
+0x9D75	0x638E	#CJK UNIFIED IDEOGRAPH
+0x9D76	0x6380	#CJK UNIFIED IDEOGRAPH
+0x9D77	0x63AB	#CJK UNIFIED IDEOGRAPH
+0x9D78	0x6376	#CJK UNIFIED IDEOGRAPH
+0x9D79	0x63A3	#CJK UNIFIED IDEOGRAPH
+0x9D7A	0x638F	#CJK UNIFIED IDEOGRAPH
+0x9D7B	0x6389	#CJK UNIFIED IDEOGRAPH
+0x9D7C	0x639F	#CJK UNIFIED IDEOGRAPH
+0x9D7D	0x63B5	#CJK UNIFIED IDEOGRAPH
+0x9D7E	0x636B	#CJK UNIFIED IDEOGRAPH
+0x9D80	0x6369	#CJK UNIFIED IDEOGRAPH
+0x9D81	0x63BE	#CJK UNIFIED IDEOGRAPH
+0x9D82	0x63E9	#CJK UNIFIED IDEOGRAPH
+0x9D83	0x63C0	#CJK UNIFIED IDEOGRAPH
+0x9D84	0x63C6	#CJK UNIFIED IDEOGRAPH
+0x9D85	0x63E3	#CJK UNIFIED IDEOGRAPH
+0x9D86	0x63C9	#CJK UNIFIED IDEOGRAPH
+0x9D87	0x63D2	#CJK UNIFIED IDEOGRAPH
+0x9D88	0x63F6	#CJK UNIFIED IDEOGRAPH
+0x9D89	0x63C4	#CJK UNIFIED IDEOGRAPH
+0x9D8A	0x6416	#CJK UNIFIED IDEOGRAPH
+0x9D8B	0x6434	#CJK UNIFIED IDEOGRAPH
+0x9D8C	0x6406	#CJK UNIFIED IDEOGRAPH
+0x9D8D	0x6413	#CJK UNIFIED IDEOGRAPH
+0x9D8E	0x6426	#CJK UNIFIED IDEOGRAPH
+0x9D8F	0x6436	#CJK UNIFIED IDEOGRAPH
+0x9D90	0x651D	#CJK UNIFIED IDEOGRAPH
+0x9D91	0x6417	#CJK UNIFIED IDEOGRAPH
+0x9D92	0x6428	#CJK UNIFIED IDEOGRAPH
+0x9D93	0x640F	#CJK UNIFIED IDEOGRAPH
+0x9D94	0x6467	#CJK UNIFIED IDEOGRAPH
+0x9D95	0x646F	#CJK UNIFIED IDEOGRAPH
+0x9D96	0x6476	#CJK UNIFIED IDEOGRAPH
+0x9D97	0x644E	#CJK UNIFIED IDEOGRAPH
+0x9D98	0x652A	#CJK UNIFIED IDEOGRAPH
+0x9D99	0x6495	#CJK UNIFIED IDEOGRAPH
+0x9D9A	0x6493	#CJK UNIFIED IDEOGRAPH
+0x9D9B	0x64A5	#CJK UNIFIED IDEOGRAPH
+0x9D9C	0x64A9	#CJK UNIFIED IDEOGRAPH
+0x9D9D	0x6488	#CJK UNIFIED IDEOGRAPH
+0x9D9E	0x64BC	#CJK UNIFIED IDEOGRAPH
+0x9D9F	0x64DA	#CJK UNIFIED IDEOGRAPH
+0x9DA0	0x64D2	#CJK UNIFIED IDEOGRAPH
+0x9DA1	0x64C5	#CJK UNIFIED IDEOGRAPH
+0x9DA2	0x64C7	#CJK UNIFIED IDEOGRAPH
+0x9DA3	0x64BB	#CJK UNIFIED IDEOGRAPH
+0x9DA4	0x64D8	#CJK UNIFIED IDEOGRAPH
+0x9DA5	0x64C2	#CJK UNIFIED IDEOGRAPH
+0x9DA6	0x64F1	#CJK UNIFIED IDEOGRAPH
+0x9DA7	0x64E7	#CJK UNIFIED IDEOGRAPH
+0x9DA8	0x8209	#CJK UNIFIED IDEOGRAPH
+0x9DA9	0x64E0	#CJK UNIFIED IDEOGRAPH
+0x9DAA	0x64E1	#CJK UNIFIED IDEOGRAPH
+0x9DAB	0x62AC	#CJK UNIFIED IDEOGRAPH
+0x9DAC	0x64E3	#CJK UNIFIED IDEOGRAPH
+0x9DAD	0x64EF	#CJK UNIFIED IDEOGRAPH
+0x9DAE	0x652C	#CJK UNIFIED IDEOGRAPH
+0x9DAF	0x64F6	#CJK UNIFIED IDEOGRAPH
+0x9DB0	0x64F4	#CJK UNIFIED IDEOGRAPH
+0x9DB1	0x64F2	#CJK UNIFIED IDEOGRAPH
+0x9DB2	0x64FA	#CJK UNIFIED IDEOGRAPH
+0x9DB3	0x6500	#CJK UNIFIED IDEOGRAPH
+0x9DB4	0x64FD	#CJK UNIFIED IDEOGRAPH
+0x9DB5	0x6518	#CJK UNIFIED IDEOGRAPH
+0x9DB6	0x651C	#CJK UNIFIED IDEOGRAPH
+0x9DB7	0x6505	#CJK UNIFIED IDEOGRAPH
+0x9DB8	0x6524	#CJK UNIFIED IDEOGRAPH
+0x9DB9	0x6523	#CJK UNIFIED IDEOGRAPH
+0x9DBA	0x652B	#CJK UNIFIED IDEOGRAPH
+0x9DBB	0x6534	#CJK UNIFIED IDEOGRAPH
+0x9DBC	0x6535	#CJK UNIFIED IDEOGRAPH
+0x9DBD	0x6537	#CJK UNIFIED IDEOGRAPH
+0x9DBE	0x6536	#CJK UNIFIED IDEOGRAPH
+0x9DBF	0x6538	#CJK UNIFIED IDEOGRAPH
+0x9DC0	0x754B	#CJK UNIFIED IDEOGRAPH
+0x9DC1	0x6548	#CJK UNIFIED IDEOGRAPH
+0x9DC2	0x6556	#CJK UNIFIED IDEOGRAPH
+0x9DC3	0x6555	#CJK UNIFIED IDEOGRAPH
+0x9DC4	0x654D	#CJK UNIFIED IDEOGRAPH
+0x9DC5	0x6558	#CJK UNIFIED IDEOGRAPH
+0x9DC6	0x655E	#CJK UNIFIED IDEOGRAPH
+0x9DC7	0x655D	#CJK UNIFIED IDEOGRAPH
+0x9DC8	0x6572	#CJK UNIFIED IDEOGRAPH
+0x9DC9	0x6578	#CJK UNIFIED IDEOGRAPH
+0x9DCA	0x6582	#CJK UNIFIED IDEOGRAPH
+0x9DCB	0x6583	#CJK UNIFIED IDEOGRAPH
+0x9DCC	0x8B8A	#CJK UNIFIED IDEOGRAPH
+0x9DCD	0x659B	#CJK UNIFIED IDEOGRAPH
+0x9DCE	0x659F	#CJK UNIFIED IDEOGRAPH
+0x9DCF	0x65AB	#CJK UNIFIED IDEOGRAPH
+0x9DD0	0x65B7	#CJK UNIFIED IDEOGRAPH
+0x9DD1	0x65C3	#CJK UNIFIED IDEOGRAPH
+0x9DD2	0x65C6	#CJK UNIFIED IDEOGRAPH
+0x9DD3	0x65C1	#CJK UNIFIED IDEOGRAPH
+0x9DD4	0x65C4	#CJK UNIFIED IDEOGRAPH
+0x9DD5	0x65CC	#CJK UNIFIED IDEOGRAPH
+0x9DD6	0x65D2	#CJK UNIFIED IDEOGRAPH
+0x9DD7	0x65DB	#CJK UNIFIED IDEOGRAPH
+0x9DD8	0x65D9	#CJK UNIFIED IDEOGRAPH
+0x9DD9	0x65E0	#CJK UNIFIED IDEOGRAPH
+0x9DDA	0x65E1	#CJK UNIFIED IDEOGRAPH
+0x9DDB	0x65F1	#CJK UNIFIED IDEOGRAPH
+0x9DDC	0x6772	#CJK UNIFIED IDEOGRAPH
+0x9DDD	0x660A	#CJK UNIFIED IDEOGRAPH
+0x9DDE	0x6603	#CJK UNIFIED IDEOGRAPH
+0x9DDF	0x65FB	#CJK UNIFIED IDEOGRAPH
+0x9DE0	0x6773	#CJK UNIFIED IDEOGRAPH
+0x9DE1	0x6635	#CJK UNIFIED IDEOGRAPH
+0x9DE2	0x6636	#CJK UNIFIED IDEOGRAPH
+0x9DE3	0x6634	#CJK UNIFIED IDEOGRAPH
+0x9DE4	0x661C	#CJK UNIFIED IDEOGRAPH
+0x9DE5	0x664F	#CJK UNIFIED IDEOGRAPH
+0x9DE6	0x6644	#CJK UNIFIED IDEOGRAPH
+0x9DE7	0x6649	#CJK UNIFIED IDEOGRAPH
+0x9DE8	0x6641	#CJK UNIFIED IDEOGRAPH
+0x9DE9	0x665E	#CJK UNIFIED IDEOGRAPH
+0x9DEA	0x665D	#CJK UNIFIED IDEOGRAPH
+0x9DEB	0x6664	#CJK UNIFIED IDEOGRAPH
+0x9DEC	0x6667	#CJK UNIFIED IDEOGRAPH
+0x9DED	0x6668	#CJK UNIFIED IDEOGRAPH
+0x9DEE	0x665F	#CJK UNIFIED IDEOGRAPH
+0x9DEF	0x6662	#CJK UNIFIED IDEOGRAPH
+0x9DF0	0x6670	#CJK UNIFIED IDEOGRAPH
+0x9DF1	0x6683	#CJK UNIFIED IDEOGRAPH
+0x9DF2	0x6688	#CJK UNIFIED IDEOGRAPH
+0x9DF3	0x668E	#CJK UNIFIED IDEOGRAPH
+0x9DF4	0x6689	#CJK UNIFIED IDEOGRAPH
+0x9DF5	0x6684	#CJK UNIFIED IDEOGRAPH
+0x9DF6	0x6698	#CJK UNIFIED IDEOGRAPH
+0x9DF7	0x669D	#CJK UNIFIED IDEOGRAPH
+0x9DF8	0x66C1	#CJK UNIFIED IDEOGRAPH
+0x9DF9	0x66B9	#CJK UNIFIED IDEOGRAPH
+0x9DFA	0x66C9	#CJK UNIFIED IDEOGRAPH
+0x9DFB	0x66BE	#CJK UNIFIED IDEOGRAPH
+0x9DFC	0x66BC	#CJK UNIFIED IDEOGRAPH
+0x9E40	0x66C4	#CJK UNIFIED IDEOGRAPH
+0x9E41	0x66B8	#CJK UNIFIED IDEOGRAPH
+0x9E42	0x66D6	#CJK UNIFIED IDEOGRAPH
+0x9E43	0x66DA	#CJK UNIFIED IDEOGRAPH
+0x9E44	0x66E0	#CJK UNIFIED IDEOGRAPH
+0x9E45	0x663F	#CJK UNIFIED IDEOGRAPH
+0x9E46	0x66E6	#CJK UNIFIED IDEOGRAPH
+0x9E47	0x66E9	#CJK UNIFIED IDEOGRAPH
+0x9E48	0x66F0	#CJK UNIFIED IDEOGRAPH
+0x9E49	0x66F5	#CJK UNIFIED IDEOGRAPH
+0x9E4A	0x66F7	#CJK UNIFIED IDEOGRAPH
+0x9E4B	0x670F	#CJK UNIFIED IDEOGRAPH
+0x9E4C	0x6716	#CJK UNIFIED IDEOGRAPH
+0x9E4D	0x671E	#CJK UNIFIED IDEOGRAPH
+0x9E4E	0x6726	#CJK UNIFIED IDEOGRAPH
+0x9E4F	0x6727	#CJK UNIFIED IDEOGRAPH
+0x9E50	0x9738	#CJK UNIFIED IDEOGRAPH
+0x9E51	0x672E	#CJK UNIFIED IDEOGRAPH
+0x9E52	0x673F	#CJK UNIFIED IDEOGRAPH
+0x9E53	0x6736	#CJK UNIFIED IDEOGRAPH
+0x9E54	0x6741	#CJK UNIFIED IDEOGRAPH
+0x9E55	0x6738	#CJK UNIFIED IDEOGRAPH
+0x9E56	0x6737	#CJK UNIFIED IDEOGRAPH
+0x9E57	0x6746	#CJK UNIFIED IDEOGRAPH
+0x9E58	0x675E	#CJK UNIFIED IDEOGRAPH
+0x9E59	0x6760	#CJK UNIFIED IDEOGRAPH
+0x9E5A	0x6759	#CJK UNIFIED IDEOGRAPH
+0x9E5B	0x6763	#CJK UNIFIED IDEOGRAPH
+0x9E5C	0x6764	#CJK UNIFIED IDEOGRAPH
+0x9E5D	0x6789	#CJK UNIFIED IDEOGRAPH
+0x9E5E	0x6770	#CJK UNIFIED IDEOGRAPH
+0x9E5F	0x67A9	#CJK UNIFIED IDEOGRAPH
+0x9E60	0x677C	#CJK UNIFIED IDEOGRAPH
+0x9E61	0x676A	#CJK UNIFIED IDEOGRAPH
+0x9E62	0x678C	#CJK UNIFIED IDEOGRAPH
+0x9E63	0x678B	#CJK UNIFIED IDEOGRAPH
+0x9E64	0x67A6	#CJK UNIFIED IDEOGRAPH
+0x9E65	0x67A1	#CJK UNIFIED IDEOGRAPH
+0x9E66	0x6785	#CJK UNIFIED IDEOGRAPH
+0x9E67	0x67B7	#CJK UNIFIED IDEOGRAPH
+0x9E68	0x67EF	#CJK UNIFIED IDEOGRAPH
+0x9E69	0x67B4	#CJK UNIFIED IDEOGRAPH
+0x9E6A	0x67EC	#CJK UNIFIED IDEOGRAPH
+0x9E6B	0x67B3	#CJK UNIFIED IDEOGRAPH
+0x9E6C	0x67E9	#CJK UNIFIED IDEOGRAPH
+0x9E6D	0x67B8	#CJK UNIFIED IDEOGRAPH
+0x9E6E	0x67E4	#CJK UNIFIED IDEOGRAPH
+0x9E6F	0x67DE	#CJK UNIFIED IDEOGRAPH
+0x9E70	0x67DD	#CJK UNIFIED IDEOGRAPH
+0x9E71	0x67E2	#CJK UNIFIED IDEOGRAPH
+0x9E72	0x67EE	#CJK UNIFIED IDEOGRAPH
+0x9E73	0x67B9	#CJK UNIFIED IDEOGRAPH
+0x9E74	0x67CE	#CJK UNIFIED IDEOGRAPH
+0x9E75	0x67C6	#CJK UNIFIED IDEOGRAPH
+0x9E76	0x67E7	#CJK UNIFIED IDEOGRAPH
+0x9E77	0x6A9C	#CJK UNIFIED IDEOGRAPH
+0x9E78	0x681E	#CJK UNIFIED IDEOGRAPH
+0x9E79	0x6846	#CJK UNIFIED IDEOGRAPH
+0x9E7A	0x6829	#CJK UNIFIED IDEOGRAPH
+0x9E7B	0x6840	#CJK UNIFIED IDEOGRAPH
+0x9E7C	0x684D	#CJK UNIFIED IDEOGRAPH
+0x9E7D	0x6832	#CJK UNIFIED IDEOGRAPH
+0x9E7E	0x684E	#CJK UNIFIED IDEOGRAPH
+0x9E80	0x68B3	#CJK UNIFIED IDEOGRAPH
+0x9E81	0x682B	#CJK UNIFIED IDEOGRAPH
+0x9E82	0x6859	#CJK UNIFIED IDEOGRAPH
+0x9E83	0x6863	#CJK UNIFIED IDEOGRAPH
+0x9E84	0x6877	#CJK UNIFIED IDEOGRAPH
+0x9E85	0x687F	#CJK UNIFIED IDEOGRAPH
+0x9E86	0x689F	#CJK UNIFIED IDEOGRAPH
+0x9E87	0x688F	#CJK UNIFIED IDEOGRAPH
+0x9E88	0x68AD	#CJK UNIFIED IDEOGRAPH
+0x9E89	0x6894	#CJK UNIFIED IDEOGRAPH
+0x9E8A	0x689D	#CJK UNIFIED IDEOGRAPH
+0x9E8B	0x689B	#CJK UNIFIED IDEOGRAPH
+0x9E8C	0x6883	#CJK UNIFIED IDEOGRAPH
+0x9E8D	0x6AAE	#CJK UNIFIED IDEOGRAPH
+0x9E8E	0x68B9	#CJK UNIFIED IDEOGRAPH
+0x9E8F	0x6874	#CJK UNIFIED IDEOGRAPH
+0x9E90	0x68B5	#CJK UNIFIED IDEOGRAPH
+0x9E91	0x68A0	#CJK UNIFIED IDEOGRAPH
+0x9E92	0x68BA	#CJK UNIFIED IDEOGRAPH
+0x9E93	0x690F	#CJK UNIFIED IDEOGRAPH
+0x9E94	0x688D	#CJK UNIFIED IDEOGRAPH
+0x9E95	0x687E	#CJK UNIFIED IDEOGRAPH
+0x9E96	0x6901	#CJK UNIFIED IDEOGRAPH
+0x9E97	0x68CA	#CJK UNIFIED IDEOGRAPH
+0x9E98	0x6908	#CJK UNIFIED IDEOGRAPH
+0x9E99	0x68D8	#CJK UNIFIED IDEOGRAPH
+0x9E9A	0x6922	#CJK UNIFIED IDEOGRAPH
+0x9E9B	0x6926	#CJK UNIFIED IDEOGRAPH
+0x9E9C	0x68E1	#CJK UNIFIED IDEOGRAPH
+0x9E9D	0x690C	#CJK UNIFIED IDEOGRAPH
+0x9E9E	0x68CD	#CJK UNIFIED IDEOGRAPH
+0x9E9F	0x68D4	#CJK UNIFIED IDEOGRAPH
+0x9EA0	0x68E7	#CJK UNIFIED IDEOGRAPH
+0x9EA1	0x68D5	#CJK UNIFIED IDEOGRAPH
+0x9EA2	0x6936	#CJK UNIFIED IDEOGRAPH
+0x9EA3	0x6912	#CJK UNIFIED IDEOGRAPH
+0x9EA4	0x6904	#CJK UNIFIED IDEOGRAPH
+0x9EA5	0x68D7	#CJK UNIFIED IDEOGRAPH
+0x9EA6	0x68E3	#CJK UNIFIED IDEOGRAPH
+0x9EA7	0x6925	#CJK UNIFIED IDEOGRAPH
+0x9EA8	0x68F9	#CJK UNIFIED IDEOGRAPH
+0x9EA9	0x68E0	#CJK UNIFIED IDEOGRAPH
+0x9EAA	0x68EF	#CJK UNIFIED IDEOGRAPH
+0x9EAB	0x6928	#CJK UNIFIED IDEOGRAPH
+0x9EAC	0x692A	#CJK UNIFIED IDEOGRAPH
+0x9EAD	0x691A	#CJK UNIFIED IDEOGRAPH
+0x9EAE	0x6923	#CJK UNIFIED IDEOGRAPH
+0x9EAF	0x6921	#CJK UNIFIED IDEOGRAPH
+0x9EB0	0x68C6	#CJK UNIFIED IDEOGRAPH
+0x9EB1	0x6979	#CJK UNIFIED IDEOGRAPH
+0x9EB2	0x6977	#CJK UNIFIED IDEOGRAPH
+0x9EB3	0x695C	#CJK UNIFIED IDEOGRAPH
+0x9EB4	0x6978	#CJK UNIFIED IDEOGRAPH
+0x9EB5	0x696B	#CJK UNIFIED IDEOGRAPH
+0x9EB6	0x6954	#CJK UNIFIED IDEOGRAPH
+0x9EB7	0x697E	#CJK UNIFIED IDEOGRAPH
+0x9EB8	0x696E	#CJK UNIFIED IDEOGRAPH
+0x9EB9	0x6939	#CJK UNIFIED IDEOGRAPH
+0x9EBA	0x6974	#CJK UNIFIED IDEOGRAPH
+0x9EBB	0x693D	#CJK UNIFIED IDEOGRAPH
+0x9EBC	0x6959	#CJK UNIFIED IDEOGRAPH
+0x9EBD	0x6930	#CJK UNIFIED IDEOGRAPH
+0x9EBE	0x6961	#CJK UNIFIED IDEOGRAPH
+0x9EBF	0x695E	#CJK UNIFIED IDEOGRAPH
+0x9EC0	0x695D	#CJK UNIFIED IDEOGRAPH
+0x9EC1	0x6981	#CJK UNIFIED IDEOGRAPH
+0x9EC2	0x696A	#CJK UNIFIED IDEOGRAPH
+0x9EC3	0x69B2	#CJK UNIFIED IDEOGRAPH
+0x9EC4	0x69AE	#CJK UNIFIED IDEOGRAPH
+0x9EC5	0x69D0	#CJK UNIFIED IDEOGRAPH
+0x9EC6	0x69BF	#CJK UNIFIED IDEOGRAPH
+0x9EC7	0x69C1	#CJK UNIFIED IDEOGRAPH
+0x9EC8	0x69D3	#CJK UNIFIED IDEOGRAPH
+0x9EC9	0x69BE	#CJK UNIFIED IDEOGRAPH
+0x9ECA	0x69CE	#CJK UNIFIED IDEOGRAPH
+0x9ECB	0x5BE8	#CJK UNIFIED IDEOGRAPH
+0x9ECC	0x69CA	#CJK UNIFIED IDEOGRAPH
+0x9ECD	0x69DD	#CJK UNIFIED IDEOGRAPH
+0x9ECE	0x69BB	#CJK UNIFIED IDEOGRAPH
+0x9ECF	0x69C3	#CJK UNIFIED IDEOGRAPH
+0x9ED0	0x69A7	#CJK UNIFIED IDEOGRAPH
+0x9ED1	0x6A2E	#CJK UNIFIED IDEOGRAPH
+0x9ED2	0x6991	#CJK UNIFIED IDEOGRAPH
+0x9ED3	0x69A0	#CJK UNIFIED IDEOGRAPH
+0x9ED4	0x699C	#CJK UNIFIED IDEOGRAPH
+0x9ED5	0x6995	#CJK UNIFIED IDEOGRAPH
+0x9ED6	0x69B4	#CJK UNIFIED IDEOGRAPH
+0x9ED7	0x69DE	#CJK UNIFIED IDEOGRAPH
+0x9ED8	0x69E8	#CJK UNIFIED IDEOGRAPH
+0x9ED9	0x6A02	#CJK UNIFIED IDEOGRAPH
+0x9EDA	0x6A1B	#CJK UNIFIED IDEOGRAPH
+0x9EDB	0x69FF	#CJK UNIFIED IDEOGRAPH
+0x9EDC	0x6B0A	#CJK UNIFIED IDEOGRAPH
+0x9EDD	0x69F9	#CJK UNIFIED IDEOGRAPH
+0x9EDE	0x69F2	#CJK UNIFIED IDEOGRAPH
+0x9EDF	0x69E7	#CJK UNIFIED IDEOGRAPH
+0x9EE0	0x6A05	#CJK UNIFIED IDEOGRAPH
+0x9EE1	0x69B1	#CJK UNIFIED IDEOGRAPH
+0x9EE2	0x6A1E	#CJK UNIFIED IDEOGRAPH
+0x9EE3	0x69ED	#CJK UNIFIED IDEOGRAPH
+0x9EE4	0x6A14	#CJK UNIFIED IDEOGRAPH
+0x9EE5	0x69EB	#CJK UNIFIED IDEOGRAPH
+0x9EE6	0x6A0A	#CJK UNIFIED IDEOGRAPH
+0x9EE7	0x6A12	#CJK UNIFIED IDEOGRAPH
+0x9EE8	0x6AC1	#CJK UNIFIED IDEOGRAPH
+0x9EE9	0x6A23	#CJK UNIFIED IDEOGRAPH
+0x9EEA	0x6A13	#CJK UNIFIED IDEOGRAPH
+0x9EEB	0x6A44	#CJK UNIFIED IDEOGRAPH
+0x9EEC	0x6A0C	#CJK UNIFIED IDEOGRAPH
+0x9EED	0x6A72	#CJK UNIFIED IDEOGRAPH
+0x9EEE	0x6A36	#CJK UNIFIED IDEOGRAPH
+0x9EEF	0x6A78	#CJK UNIFIED IDEOGRAPH
+0x9EF0	0x6A47	#CJK UNIFIED IDEOGRAPH
+0x9EF1	0x6A62	#CJK UNIFIED IDEOGRAPH
+0x9EF2	0x6A59	#CJK UNIFIED IDEOGRAPH
+0x9EF3	0x6A66	#CJK UNIFIED IDEOGRAPH
+0x9EF4	0x6A48	#CJK UNIFIED IDEOGRAPH
+0x9EF5	0x6A38	#CJK UNIFIED IDEOGRAPH
+0x9EF6	0x6A22	#CJK UNIFIED IDEOGRAPH
+0x9EF7	0x6A90	#CJK UNIFIED IDEOGRAPH
+0x9EF8	0x6A8D	#CJK UNIFIED IDEOGRAPH
+0x9EF9	0x6AA0	#CJK UNIFIED IDEOGRAPH
+0x9EFA	0x6A84	#CJK UNIFIED IDEOGRAPH
+0x9EFB	0x6AA2	#CJK UNIFIED IDEOGRAPH
+0x9EFC	0x6AA3	#CJK UNIFIED IDEOGRAPH
+0x9F40	0x6A97	#CJK UNIFIED IDEOGRAPH
+0x9F41	0x8617	#CJK UNIFIED IDEOGRAPH
+0x9F42	0x6ABB	#CJK UNIFIED IDEOGRAPH
+0x9F43	0x6AC3	#CJK UNIFIED IDEOGRAPH
+0x9F44	0x6AC2	#CJK UNIFIED IDEOGRAPH
+0x9F45	0x6AB8	#CJK UNIFIED IDEOGRAPH
+0x9F46	0x6AB3	#CJK UNIFIED IDEOGRAPH
+0x9F47	0x6AAC	#CJK UNIFIED IDEOGRAPH
+0x9F48	0x6ADE	#CJK UNIFIED IDEOGRAPH
+0x9F49	0x6AD1	#CJK UNIFIED IDEOGRAPH
+0x9F4A	0x6ADF	#CJK UNIFIED IDEOGRAPH
+0x9F4B	0x6AAA	#CJK UNIFIED IDEOGRAPH
+0x9F4C	0x6ADA	#CJK UNIFIED IDEOGRAPH
+0x9F4D	0x6AEA	#CJK UNIFIED IDEOGRAPH
+0x9F4E	0x6AFB	#CJK UNIFIED IDEOGRAPH
+0x9F4F	0x6B05	#CJK UNIFIED IDEOGRAPH
+0x9F50	0x8616	#CJK UNIFIED IDEOGRAPH
+0x9F51	0x6AFA	#CJK UNIFIED IDEOGRAPH
+0x9F52	0x6B12	#CJK UNIFIED IDEOGRAPH
+0x9F53	0x6B16	#CJK UNIFIED IDEOGRAPH
+0x9F54	0x9B31	#CJK UNIFIED IDEOGRAPH
+0x9F55	0x6B1F	#CJK UNIFIED IDEOGRAPH
+0x9F56	0x6B38	#CJK UNIFIED IDEOGRAPH
+0x9F57	0x6B37	#CJK UNIFIED IDEOGRAPH
+0x9F58	0x76DC	#CJK UNIFIED IDEOGRAPH
+0x9F59	0x6B39	#CJK UNIFIED IDEOGRAPH
+0x9F5A	0x98EE	#CJK UNIFIED IDEOGRAPH
+0x9F5B	0x6B47	#CJK UNIFIED IDEOGRAPH
+0x9F5C	0x6B43	#CJK UNIFIED IDEOGRAPH
+0x9F5D	0x6B49	#CJK UNIFIED IDEOGRAPH
+0x9F5E	0x6B50	#CJK UNIFIED IDEOGRAPH
+0x9F5F	0x6B59	#CJK UNIFIED IDEOGRAPH
+0x9F60	0x6B54	#CJK UNIFIED IDEOGRAPH
+0x9F61	0x6B5B	#CJK UNIFIED IDEOGRAPH
+0x9F62	0x6B5F	#CJK UNIFIED IDEOGRAPH
+0x9F63	0x6B61	#CJK UNIFIED IDEOGRAPH
+0x9F64	0x6B78	#CJK UNIFIED IDEOGRAPH
+0x9F65	0x6B79	#CJK UNIFIED IDEOGRAPH
+0x9F66	0x6B7F	#CJK UNIFIED IDEOGRAPH
+0x9F67	0x6B80	#CJK UNIFIED IDEOGRAPH
+0x9F68	0x6B84	#CJK UNIFIED IDEOGRAPH
+0x9F69	0x6B83	#CJK UNIFIED IDEOGRAPH
+0x9F6A	0x6B8D	#CJK UNIFIED IDEOGRAPH
+0x9F6B	0x6B98	#CJK UNIFIED IDEOGRAPH
+0x9F6C	0x6B95	#CJK UNIFIED IDEOGRAPH
+0x9F6D	0x6B9E	#CJK UNIFIED IDEOGRAPH
+0x9F6E	0x6BA4	#CJK UNIFIED IDEOGRAPH
+0x9F6F	0x6BAA	#CJK UNIFIED IDEOGRAPH
+0x9F70	0x6BAB	#CJK UNIFIED IDEOGRAPH
+0x9F71	0x6BAF	#CJK UNIFIED IDEOGRAPH
+0x9F72	0x6BB2	#CJK UNIFIED IDEOGRAPH
+0x9F73	0x6BB1	#CJK UNIFIED IDEOGRAPH
+0x9F74	0x6BB3	#CJK UNIFIED IDEOGRAPH
+0x9F75	0x6BB7	#CJK UNIFIED IDEOGRAPH
+0x9F76	0x6BBC	#CJK UNIFIED IDEOGRAPH
+0x9F77	0x6BC6	#CJK UNIFIED IDEOGRAPH
+0x9F78	0x6BCB	#CJK UNIFIED IDEOGRAPH
+0x9F79	0x6BD3	#CJK UNIFIED IDEOGRAPH
+0x9F7A	0x6BDF	#CJK UNIFIED IDEOGRAPH
+0x9F7B	0x6BEC	#CJK UNIFIED IDEOGRAPH
+0x9F7C	0x6BEB	#CJK UNIFIED IDEOGRAPH
+0x9F7D	0x6BF3	#CJK UNIFIED IDEOGRAPH
+0x9F7E	0x6BEF	#CJK UNIFIED IDEOGRAPH
+0x9F80	0x9EBE	#CJK UNIFIED IDEOGRAPH
+0x9F81	0x6C08	#CJK UNIFIED IDEOGRAPH
+0x9F82	0x6C13	#CJK UNIFIED IDEOGRAPH
+0x9F83	0x6C14	#CJK UNIFIED IDEOGRAPH
+0x9F84	0x6C1B	#CJK UNIFIED IDEOGRAPH
+0x9F85	0x6C24	#CJK UNIFIED IDEOGRAPH
+0x9F86	0x6C23	#CJK UNIFIED IDEOGRAPH
+0x9F87	0x6C5E	#CJK UNIFIED IDEOGRAPH
+0x9F88	0x6C55	#CJK UNIFIED IDEOGRAPH
+0x9F89	0x6C62	#CJK UNIFIED IDEOGRAPH
+0x9F8A	0x6C6A	#CJK UNIFIED IDEOGRAPH
+0x9F8B	0x6C82	#CJK UNIFIED IDEOGRAPH
+0x9F8C	0x6C8D	#CJK UNIFIED IDEOGRAPH
+0x9F8D	0x6C9A	#CJK UNIFIED IDEOGRAPH
+0x9F8E	0x6C81	#CJK UNIFIED IDEOGRAPH
+0x9F8F	0x6C9B	#CJK UNIFIED IDEOGRAPH
+0x9F90	0x6C7E	#CJK UNIFIED IDEOGRAPH
+0x9F91	0x6C68	#CJK UNIFIED IDEOGRAPH
+0x9F92	0x6C73	#CJK UNIFIED IDEOGRAPH
+0x9F93	0x6C92	#CJK UNIFIED IDEOGRAPH
+0x9F94	0x6C90	#CJK UNIFIED IDEOGRAPH
+0x9F95	0x6CC4	#CJK UNIFIED IDEOGRAPH
+0x9F96	0x6CF1	#CJK UNIFIED IDEOGRAPH
+0x9F97	0x6CD3	#CJK UNIFIED IDEOGRAPH
+0x9F98	0x6CBD	#CJK UNIFIED IDEOGRAPH
+0x9F99	0x6CD7	#CJK UNIFIED IDEOGRAPH
+0x9F9A	0x6CC5	#CJK UNIFIED IDEOGRAPH
+0x9F9B	0x6CDD	#CJK UNIFIED IDEOGRAPH
+0x9F9C	0x6CAE	#CJK UNIFIED IDEOGRAPH
+0x9F9D	0x6CB1	#CJK UNIFIED IDEOGRAPH
+0x9F9E	0x6CBE	#CJK UNIFIED IDEOGRAPH
+0x9F9F	0x6CBA	#CJK UNIFIED IDEOGRAPH
+0x9FA0	0x6CDB	#CJK UNIFIED IDEOGRAPH
+0x9FA1	0x6CEF	#CJK UNIFIED IDEOGRAPH
+0x9FA2	0x6CD9	#CJK UNIFIED IDEOGRAPH
+0x9FA3	0x6CEA	#CJK UNIFIED IDEOGRAPH
+0x9FA4	0x6D1F	#CJK UNIFIED IDEOGRAPH
+0x9FA5	0x884D	#CJK UNIFIED IDEOGRAPH
+0x9FA6	0x6D36	#CJK UNIFIED IDEOGRAPH
+0x9FA7	0x6D2B	#CJK UNIFIED IDEOGRAPH
+0x9FA8	0x6D3D	#CJK UNIFIED IDEOGRAPH
+0x9FA9	0x6D38	#CJK UNIFIED IDEOGRAPH
+0x9FAA	0x6D19	#CJK UNIFIED IDEOGRAPH
+0x9FAB	0x6D35	#CJK UNIFIED IDEOGRAPH
+0x9FAC	0x6D33	#CJK UNIFIED IDEOGRAPH
+0x9FAD	0x6D12	#CJK UNIFIED IDEOGRAPH
+0x9FAE	0x6D0C	#CJK UNIFIED IDEOGRAPH
+0x9FAF	0x6D63	#CJK UNIFIED IDEOGRAPH
+0x9FB0	0x6D93	#CJK UNIFIED IDEOGRAPH
+0x9FB1	0x6D64	#CJK UNIFIED IDEOGRAPH
+0x9FB2	0x6D5A	#CJK UNIFIED IDEOGRAPH
+0x9FB3	0x6D79	#CJK UNIFIED IDEOGRAPH
+0x9FB4	0x6D59	#CJK UNIFIED IDEOGRAPH
+0x9FB5	0x6D8E	#CJK UNIFIED IDEOGRAPH
+0x9FB6	0x6D95	#CJK UNIFIED IDEOGRAPH
+0x9FB7	0x6FE4	#CJK UNIFIED IDEOGRAPH
+0x9FB8	0x6D85	#CJK UNIFIED IDEOGRAPH
+0x9FB9	0x6DF9	#CJK UNIFIED IDEOGRAPH
+0x9FBA	0x6E15	#CJK UNIFIED IDEOGRAPH
+0x9FBB	0x6E0A	#CJK UNIFIED IDEOGRAPH
+0x9FBC	0x6DB5	#CJK UNIFIED IDEOGRAPH
+0x9FBD	0x6DC7	#CJK UNIFIED IDEOGRAPH
+0x9FBE	0x6DE6	#CJK UNIFIED IDEOGRAPH
+0x9FBF	0x6DB8	#CJK UNIFIED IDEOGRAPH
+0x9FC0	0x6DC6	#CJK UNIFIED IDEOGRAPH
+0x9FC1	0x6DEC	#CJK UNIFIED IDEOGRAPH
+0x9FC2	0x6DDE	#CJK UNIFIED IDEOGRAPH
+0x9FC3	0x6DCC	#CJK UNIFIED IDEOGRAPH
+0x9FC4	0x6DE8	#CJK UNIFIED IDEOGRAPH
+0x9FC5	0x6DD2	#CJK UNIFIED IDEOGRAPH
+0x9FC6	0x6DC5	#CJK UNIFIED IDEOGRAPH
+0x9FC7	0x6DFA	#CJK UNIFIED IDEOGRAPH
+0x9FC8	0x6DD9	#CJK UNIFIED IDEOGRAPH
+0x9FC9	0x6DE4	#CJK UNIFIED IDEOGRAPH
+0x9FCA	0x6DD5	#CJK UNIFIED IDEOGRAPH
+0x9FCB	0x6DEA	#CJK UNIFIED IDEOGRAPH
+0x9FCC	0x6DEE	#CJK UNIFIED IDEOGRAPH
+0x9FCD	0x6E2D	#CJK UNIFIED IDEOGRAPH
+0x9FCE	0x6E6E	#CJK UNIFIED IDEOGRAPH
+0x9FCF	0x6E2E	#CJK UNIFIED IDEOGRAPH
+0x9FD0	0x6E19	#CJK UNIFIED IDEOGRAPH
+0x9FD1	0x6E72	#CJK UNIFIED IDEOGRAPH
+0x9FD2	0x6E5F	#CJK UNIFIED IDEOGRAPH
+0x9FD3	0x6E3E	#CJK UNIFIED IDEOGRAPH
+0x9FD4	0x6E23	#CJK UNIFIED IDEOGRAPH
+0x9FD5	0x6E6B	#CJK UNIFIED IDEOGRAPH
+0x9FD6	0x6E2B	#CJK UNIFIED IDEOGRAPH
+0x9FD7	0x6E76	#CJK UNIFIED IDEOGRAPH
+0x9FD8	0x6E4D	#CJK UNIFIED IDEOGRAPH
+0x9FD9	0x6E1F	#CJK UNIFIED IDEOGRAPH
+0x9FDA	0x6E43	#CJK UNIFIED IDEOGRAPH
+0x9FDB	0x6E3A	#CJK UNIFIED IDEOGRAPH
+0x9FDC	0x6E4E	#CJK UNIFIED IDEOGRAPH
+0x9FDD	0x6E24	#CJK UNIFIED IDEOGRAPH
+0x9FDE	0x6EFF	#CJK UNIFIED IDEOGRAPH
+0x9FDF	0x6E1D	#CJK UNIFIED IDEOGRAPH
+0x9FE0	0x6E38	#CJK UNIFIED IDEOGRAPH
+0x9FE1	0x6E82	#CJK UNIFIED IDEOGRAPH
+0x9FE2	0x6EAA	#CJK UNIFIED IDEOGRAPH
+0x9FE3	0x6E98	#CJK UNIFIED IDEOGRAPH
+0x9FE4	0x6EC9	#CJK UNIFIED IDEOGRAPH
+0x9FE5	0x6EB7	#CJK UNIFIED IDEOGRAPH
+0x9FE6	0x6ED3	#CJK UNIFIED IDEOGRAPH
+0x9FE7	0x6EBD	#CJK UNIFIED IDEOGRAPH
+0x9FE8	0x6EAF	#CJK UNIFIED IDEOGRAPH
+0x9FE9	0x6EC4	#CJK UNIFIED IDEOGRAPH
+0x9FEA	0x6EB2	#CJK UNIFIED IDEOGRAPH
+0x9FEB	0x6ED4	#CJK UNIFIED IDEOGRAPH
+0x9FEC	0x6ED5	#CJK UNIFIED IDEOGRAPH
+0x9FED	0x6E8F	#CJK UNIFIED IDEOGRAPH
+0x9FEE	0x6EA5	#CJK UNIFIED IDEOGRAPH
+0x9FEF	0x6EC2	#CJK UNIFIED IDEOGRAPH
+0x9FF0	0x6E9F	#CJK UNIFIED IDEOGRAPH
+0x9FF1	0x6F41	#CJK UNIFIED IDEOGRAPH
+0x9FF2	0x6F11	#CJK UNIFIED IDEOGRAPH
+0x9FF3	0x704C	#CJK UNIFIED IDEOGRAPH
+0x9FF4	0x6EEC	#CJK UNIFIED IDEOGRAPH
+0x9FF5	0x6EF8	#CJK UNIFIED IDEOGRAPH
+0x9FF6	0x6EFE	#CJK UNIFIED IDEOGRAPH
+0x9FF7	0x6F3F	#CJK UNIFIED IDEOGRAPH
+0x9FF8	0x6EF2	#CJK UNIFIED IDEOGRAPH
+0x9FF9	0x6F31	#CJK UNIFIED IDEOGRAPH
+0x9FFA	0x6EEF	#CJK UNIFIED IDEOGRAPH
+0x9FFB	0x6F32	#CJK UNIFIED IDEOGRAPH
+0x9FFC	0x6ECC	#CJK UNIFIED IDEOGRAPH
+0xE040	0x6F3E	#CJK UNIFIED IDEOGRAPH
+0xE041	0x6F13	#CJK UNIFIED IDEOGRAPH
+0xE042	0x6EF7	#CJK UNIFIED IDEOGRAPH
+0xE043	0x6F86	#CJK UNIFIED IDEOGRAPH
+0xE044	0x6F7A	#CJK UNIFIED IDEOGRAPH
+0xE045	0x6F78	#CJK UNIFIED IDEOGRAPH
+0xE046	0x6F81	#CJK UNIFIED IDEOGRAPH
+0xE047	0x6F80	#CJK UNIFIED IDEOGRAPH
+0xE048	0x6F6F	#CJK UNIFIED IDEOGRAPH
+0xE049	0x6F5B	#CJK UNIFIED IDEOGRAPH
+0xE04A	0x6FF3	#CJK UNIFIED IDEOGRAPH
+0xE04B	0x6F6D	#CJK UNIFIED IDEOGRAPH
+0xE04C	0x6F82	#CJK UNIFIED IDEOGRAPH
+0xE04D	0x6F7C	#CJK UNIFIED IDEOGRAPH
+0xE04E	0x6F58	#CJK UNIFIED IDEOGRAPH
+0xE04F	0x6F8E	#CJK UNIFIED IDEOGRAPH
+0xE050	0x6F91	#CJK UNIFIED IDEOGRAPH
+0xE051	0x6FC2	#CJK UNIFIED IDEOGRAPH
+0xE052	0x6F66	#CJK UNIFIED IDEOGRAPH
+0xE053	0x6FB3	#CJK UNIFIED IDEOGRAPH
+0xE054	0x6FA3	#CJK UNIFIED IDEOGRAPH
+0xE055	0x6FA1	#CJK UNIFIED IDEOGRAPH
+0xE056	0x6FA4	#CJK UNIFIED IDEOGRAPH
+0xE057	0x6FB9	#CJK UNIFIED IDEOGRAPH
+0xE058	0x6FC6	#CJK UNIFIED IDEOGRAPH
+0xE059	0x6FAA	#CJK UNIFIED IDEOGRAPH
+0xE05A	0x6FDF	#CJK UNIFIED IDEOGRAPH
+0xE05B	0x6FD5	#CJK UNIFIED IDEOGRAPH
+0xE05C	0x6FEC	#CJK UNIFIED IDEOGRAPH
+0xE05D	0x6FD4	#CJK UNIFIED IDEOGRAPH
+0xE05E	0x6FD8	#CJK UNIFIED IDEOGRAPH
+0xE05F	0x6FF1	#CJK UNIFIED IDEOGRAPH
+0xE060	0x6FEE	#CJK UNIFIED IDEOGRAPH
+0xE061	0x6FDB	#CJK UNIFIED IDEOGRAPH
+0xE062	0x7009	#CJK UNIFIED IDEOGRAPH
+0xE063	0x700B	#CJK UNIFIED IDEOGRAPH
+0xE064	0x6FFA	#CJK UNIFIED IDEOGRAPH
+0xE065	0x7011	#CJK UNIFIED IDEOGRAPH
+0xE066	0x7001	#CJK UNIFIED IDEOGRAPH
+0xE067	0x700F	#CJK UNIFIED IDEOGRAPH
+0xE068	0x6FFE	#CJK UNIFIED IDEOGRAPH
+0xE069	0x701B	#CJK UNIFIED IDEOGRAPH
+0xE06A	0x701A	#CJK UNIFIED IDEOGRAPH
+0xE06B	0x6F74	#CJK UNIFIED IDEOGRAPH
+0xE06C	0x701D	#CJK UNIFIED IDEOGRAPH
+0xE06D	0x7018	#CJK UNIFIED IDEOGRAPH
+0xE06E	0x701F	#CJK UNIFIED IDEOGRAPH
+0xE06F	0x7030	#CJK UNIFIED IDEOGRAPH
+0xE070	0x703E	#CJK UNIFIED IDEOGRAPH
+0xE071	0x7032	#CJK UNIFIED IDEOGRAPH
+0xE072	0x7051	#CJK UNIFIED IDEOGRAPH
+0xE073	0x7063	#CJK UNIFIED IDEOGRAPH
+0xE074	0x7099	#CJK UNIFIED IDEOGRAPH
+0xE075	0x7092	#CJK UNIFIED IDEOGRAPH
+0xE076	0x70AF	#CJK UNIFIED IDEOGRAPH
+0xE077	0x70F1	#CJK UNIFIED IDEOGRAPH
+0xE078	0x70AC	#CJK UNIFIED IDEOGRAPH
+0xE079	0x70B8	#CJK UNIFIED IDEOGRAPH
+0xE07A	0x70B3	#CJK UNIFIED IDEOGRAPH
+0xE07B	0x70AE	#CJK UNIFIED IDEOGRAPH
+0xE07C	0x70DF	#CJK UNIFIED IDEOGRAPH
+0xE07D	0x70CB	#CJK UNIFIED IDEOGRAPH
+0xE07E	0x70DD	#CJK UNIFIED IDEOGRAPH
+0xE080	0x70D9	#CJK UNIFIED IDEOGRAPH
+0xE081	0x7109	#CJK UNIFIED IDEOGRAPH
+0xE082	0x70FD	#CJK UNIFIED IDEOGRAPH
+0xE083	0x711C	#CJK UNIFIED IDEOGRAPH
+0xE084	0x7119	#CJK UNIFIED IDEOGRAPH
+0xE085	0x7165	#CJK UNIFIED IDEOGRAPH
+0xE086	0x7155	#CJK UNIFIED IDEOGRAPH
+0xE087	0x7188	#CJK UNIFIED IDEOGRAPH
+0xE088	0x7166	#CJK UNIFIED IDEOGRAPH
+0xE089	0x7162	#CJK UNIFIED IDEOGRAPH
+0xE08A	0x714C	#CJK UNIFIED IDEOGRAPH
+0xE08B	0x7156	#CJK UNIFIED IDEOGRAPH
+0xE08C	0x716C	#CJK UNIFIED IDEOGRAPH
+0xE08D	0x718F	#CJK UNIFIED IDEOGRAPH
+0xE08E	0x71FB	#CJK UNIFIED IDEOGRAPH
+0xE08F	0x7184	#CJK UNIFIED IDEOGRAPH
+0xE090	0x7195	#CJK UNIFIED IDEOGRAPH
+0xE091	0x71A8	#CJK UNIFIED IDEOGRAPH
+0xE092	0x71AC	#CJK UNIFIED IDEOGRAPH
+0xE093	0x71D7	#CJK UNIFIED IDEOGRAPH
+0xE094	0x71B9	#CJK UNIFIED IDEOGRAPH
+0xE095	0x71BE	#CJK UNIFIED IDEOGRAPH
+0xE096	0x71D2	#CJK UNIFIED IDEOGRAPH
+0xE097	0x71C9	#CJK UNIFIED IDEOGRAPH
+0xE098	0x71D4	#CJK UNIFIED IDEOGRAPH
+0xE099	0x71CE	#CJK UNIFIED IDEOGRAPH
+0xE09A	0x71E0	#CJK UNIFIED IDEOGRAPH
+0xE09B	0x71EC	#CJK UNIFIED IDEOGRAPH
+0xE09C	0x71E7	#CJK UNIFIED IDEOGRAPH
+0xE09D	0x71F5	#CJK UNIFIED IDEOGRAPH
+0xE09E	0x71FC	#CJK UNIFIED IDEOGRAPH
+0xE09F	0x71F9	#CJK UNIFIED IDEOGRAPH
+0xE0A0	0x71FF	#CJK UNIFIED IDEOGRAPH
+0xE0A1	0x720D	#CJK UNIFIED IDEOGRAPH
+0xE0A2	0x7210	#CJK UNIFIED IDEOGRAPH
+0xE0A3	0x721B	#CJK UNIFIED IDEOGRAPH
+0xE0A4	0x7228	#CJK UNIFIED IDEOGRAPH
+0xE0A5	0x722D	#CJK UNIFIED IDEOGRAPH
+0xE0A6	0x722C	#CJK UNIFIED IDEOGRAPH
+0xE0A7	0x7230	#CJK UNIFIED IDEOGRAPH
+0xE0A8	0x7232	#CJK UNIFIED IDEOGRAPH
+0xE0A9	0x723B	#CJK UNIFIED IDEOGRAPH
+0xE0AA	0x723C	#CJK UNIFIED IDEOGRAPH
+0xE0AB	0x723F	#CJK UNIFIED IDEOGRAPH
+0xE0AC	0x7240	#CJK UNIFIED IDEOGRAPH
+0xE0AD	0x7246	#CJK UNIFIED IDEOGRAPH
+0xE0AE	0x724B	#CJK UNIFIED IDEOGRAPH
+0xE0AF	0x7258	#CJK UNIFIED IDEOGRAPH
+0xE0B0	0x7274	#CJK UNIFIED IDEOGRAPH
+0xE0B1	0x727E	#CJK UNIFIED IDEOGRAPH
+0xE0B2	0x7282	#CJK UNIFIED IDEOGRAPH
+0xE0B3	0x7281	#CJK UNIFIED IDEOGRAPH
+0xE0B4	0x7287	#CJK UNIFIED IDEOGRAPH
+0xE0B5	0x7292	#CJK UNIFIED IDEOGRAPH
+0xE0B6	0x7296	#CJK UNIFIED IDEOGRAPH
+0xE0B7	0x72A2	#CJK UNIFIED IDEOGRAPH
+0xE0B8	0x72A7	#CJK UNIFIED IDEOGRAPH
+0xE0B9	0x72B9	#CJK UNIFIED IDEOGRAPH
+0xE0BA	0x72B2	#CJK UNIFIED IDEOGRAPH
+0xE0BB	0x72C3	#CJK UNIFIED IDEOGRAPH
+0xE0BC	0x72C6	#CJK UNIFIED IDEOGRAPH
+0xE0BD	0x72C4	#CJK UNIFIED IDEOGRAPH
+0xE0BE	0x72CE	#CJK UNIFIED IDEOGRAPH
+0xE0BF	0x72D2	#CJK UNIFIED IDEOGRAPH
+0xE0C0	0x72E2	#CJK UNIFIED IDEOGRAPH
+0xE0C1	0x72E0	#CJK UNIFIED IDEOGRAPH
+0xE0C2	0x72E1	#CJK UNIFIED IDEOGRAPH
+0xE0C3	0x72F9	#CJK UNIFIED IDEOGRAPH
+0xE0C4	0x72F7	#CJK UNIFIED IDEOGRAPH
+0xE0C5	0x500F	#CJK UNIFIED IDEOGRAPH
+0xE0C6	0x7317	#CJK UNIFIED IDEOGRAPH
+0xE0C7	0x730A	#CJK UNIFIED IDEOGRAPH
+0xE0C8	0x731C	#CJK UNIFIED IDEOGRAPH
+0xE0C9	0x7316	#CJK UNIFIED IDEOGRAPH
+0xE0CA	0x731D	#CJK UNIFIED IDEOGRAPH
+0xE0CB	0x7334	#CJK UNIFIED IDEOGRAPH
+0xE0CC	0x732F	#CJK UNIFIED IDEOGRAPH
+0xE0CD	0x7329	#CJK UNIFIED IDEOGRAPH
+0xE0CE	0x7325	#CJK UNIFIED IDEOGRAPH
+0xE0CF	0x733E	#CJK UNIFIED IDEOGRAPH
+0xE0D0	0x734E	#CJK UNIFIED IDEOGRAPH
+0xE0D1	0x734F	#CJK UNIFIED IDEOGRAPH
+0xE0D2	0x9ED8	#CJK UNIFIED IDEOGRAPH
+0xE0D3	0x7357	#CJK UNIFIED IDEOGRAPH
+0xE0D4	0x736A	#CJK UNIFIED IDEOGRAPH
+0xE0D5	0x7368	#CJK UNIFIED IDEOGRAPH
+0xE0D6	0x7370	#CJK UNIFIED IDEOGRAPH
+0xE0D7	0x7378	#CJK UNIFIED IDEOGRAPH
+0xE0D8	0x7375	#CJK UNIFIED IDEOGRAPH
+0xE0D9	0x737B	#CJK UNIFIED IDEOGRAPH
+0xE0DA	0x737A	#CJK UNIFIED IDEOGRAPH
+0xE0DB	0x73C8	#CJK UNIFIED IDEOGRAPH
+0xE0DC	0x73B3	#CJK UNIFIED IDEOGRAPH
+0xE0DD	0x73CE	#CJK UNIFIED IDEOGRAPH
+0xE0DE	0x73BB	#CJK UNIFIED IDEOGRAPH
+0xE0DF	0x73C0	#CJK UNIFIED IDEOGRAPH
+0xE0E0	0x73E5	#CJK UNIFIED IDEOGRAPH
+0xE0E1	0x73EE	#CJK UNIFIED IDEOGRAPH
+0xE0E2	0x73DE	#CJK UNIFIED IDEOGRAPH
+0xE0E3	0x74A2	#CJK UNIFIED IDEOGRAPH
+0xE0E4	0x7405	#CJK UNIFIED IDEOGRAPH
+0xE0E5	0x746F	#CJK UNIFIED IDEOGRAPH
+0xE0E6	0x7425	#CJK UNIFIED IDEOGRAPH
+0xE0E7	0x73F8	#CJK UNIFIED IDEOGRAPH
+0xE0E8	0x7432	#CJK UNIFIED IDEOGRAPH
+0xE0E9	0x743A	#CJK UNIFIED IDEOGRAPH
+0xE0EA	0x7455	#CJK UNIFIED IDEOGRAPH
+0xE0EB	0x743F	#CJK UNIFIED IDEOGRAPH
+0xE0EC	0x745F	#CJK UNIFIED IDEOGRAPH
+0xE0ED	0x7459	#CJK UNIFIED IDEOGRAPH
+0xE0EE	0x7441	#CJK UNIFIED IDEOGRAPH
+0xE0EF	0x745C	#CJK UNIFIED IDEOGRAPH
+0xE0F0	0x7469	#CJK UNIFIED IDEOGRAPH
+0xE0F1	0x7470	#CJK UNIFIED IDEOGRAPH
+0xE0F2	0x7463	#CJK UNIFIED IDEOGRAPH
+0xE0F3	0x746A	#CJK UNIFIED IDEOGRAPH
+0xE0F4	0x7476	#CJK UNIFIED IDEOGRAPH
+0xE0F5	0x747E	#CJK UNIFIED IDEOGRAPH
+0xE0F6	0x748B	#CJK UNIFIED IDEOGRAPH
+0xE0F7	0x749E	#CJK UNIFIED IDEOGRAPH
+0xE0F8	0x74A7	#CJK UNIFIED IDEOGRAPH
+0xE0F9	0x74CA	#CJK UNIFIED IDEOGRAPH
+0xE0FA	0x74CF	#CJK UNIFIED IDEOGRAPH
+0xE0FB	0x74D4	#CJK UNIFIED IDEOGRAPH
+0xE0FC	0x73F1	#CJK UNIFIED IDEOGRAPH
+0xE140	0x74E0	#CJK UNIFIED IDEOGRAPH
+0xE141	0x74E3	#CJK UNIFIED IDEOGRAPH
+0xE142	0x74E7	#CJK UNIFIED IDEOGRAPH
+0xE143	0x74E9	#CJK UNIFIED IDEOGRAPH
+0xE144	0x74EE	#CJK UNIFIED IDEOGRAPH
+0xE145	0x74F2	#CJK UNIFIED IDEOGRAPH
+0xE146	0x74F0	#CJK UNIFIED IDEOGRAPH
+0xE147	0x74F1	#CJK UNIFIED IDEOGRAPH
+0xE148	0x74F8	#CJK UNIFIED IDEOGRAPH
+0xE149	0x74F7	#CJK UNIFIED IDEOGRAPH
+0xE14A	0x7504	#CJK UNIFIED IDEOGRAPH
+0xE14B	0x7503	#CJK UNIFIED IDEOGRAPH
+0xE14C	0x7505	#CJK UNIFIED IDEOGRAPH
+0xE14D	0x750C	#CJK UNIFIED IDEOGRAPH
+0xE14E	0x750E	#CJK UNIFIED IDEOGRAPH
+0xE14F	0x750D	#CJK UNIFIED IDEOGRAPH
+0xE150	0x7515	#CJK UNIFIED IDEOGRAPH
+0xE151	0x7513	#CJK UNIFIED IDEOGRAPH
+0xE152	0x751E	#CJK UNIFIED IDEOGRAPH
+0xE153	0x7526	#CJK UNIFIED IDEOGRAPH
+0xE154	0x752C	#CJK UNIFIED IDEOGRAPH
+0xE155	0x753C	#CJK UNIFIED IDEOGRAPH
+0xE156	0x7544	#CJK UNIFIED IDEOGRAPH
+0xE157	0x754D	#CJK UNIFIED IDEOGRAPH
+0xE158	0x754A	#CJK UNIFIED IDEOGRAPH
+0xE159	0x7549	#CJK UNIFIED IDEOGRAPH
+0xE15A	0x755B	#CJK UNIFIED IDEOGRAPH
+0xE15B	0x7546	#CJK UNIFIED IDEOGRAPH
+0xE15C	0x755A	#CJK UNIFIED IDEOGRAPH
+0xE15D	0x7569	#CJK UNIFIED IDEOGRAPH
+0xE15E	0x7564	#CJK UNIFIED IDEOGRAPH
+0xE15F	0x7567	#CJK UNIFIED IDEOGRAPH
+0xE160	0x756B	#CJK UNIFIED IDEOGRAPH
+0xE161	0x756D	#CJK UNIFIED IDEOGRAPH
+0xE162	0x7578	#CJK UNIFIED IDEOGRAPH
+0xE163	0x7576	#CJK UNIFIED IDEOGRAPH
+0xE164	0x7586	#CJK UNIFIED IDEOGRAPH
+0xE165	0x7587	#CJK UNIFIED IDEOGRAPH
+0xE166	0x7574	#CJK UNIFIED IDEOGRAPH
+0xE167	0x758A	#CJK UNIFIED IDEOGRAPH
+0xE168	0x7589	#CJK UNIFIED IDEOGRAPH
+0xE169	0x7582	#CJK UNIFIED IDEOGRAPH
+0xE16A	0x7594	#CJK UNIFIED IDEOGRAPH
+0xE16B	0x759A	#CJK UNIFIED IDEOGRAPH
+0xE16C	0x759D	#CJK UNIFIED IDEOGRAPH
+0xE16D	0x75A5	#CJK UNIFIED IDEOGRAPH
+0xE16E	0x75A3	#CJK UNIFIED IDEOGRAPH
+0xE16F	0x75C2	#CJK UNIFIED IDEOGRAPH
+0xE170	0x75B3	#CJK UNIFIED IDEOGRAPH
+0xE171	0x75C3	#CJK UNIFIED IDEOGRAPH
+0xE172	0x75B5	#CJK UNIFIED IDEOGRAPH
+0xE173	0x75BD	#CJK UNIFIED IDEOGRAPH
+0xE174	0x75B8	#CJK UNIFIED IDEOGRAPH
+0xE175	0x75BC	#CJK UNIFIED IDEOGRAPH
+0xE176	0x75B1	#CJK UNIFIED IDEOGRAPH
+0xE177	0x75CD	#CJK UNIFIED IDEOGRAPH
+0xE178	0x75CA	#CJK UNIFIED IDEOGRAPH
+0xE179	0x75D2	#CJK UNIFIED IDEOGRAPH
+0xE17A	0x75D9	#CJK UNIFIED IDEOGRAPH
+0xE17B	0x75E3	#CJK UNIFIED IDEOGRAPH
+0xE17C	0x75DE	#CJK UNIFIED IDEOGRAPH
+0xE17D	0x75FE	#CJK UNIFIED IDEOGRAPH
+0xE17E	0x75FF	#CJK UNIFIED IDEOGRAPH
+0xE180	0x75FC	#CJK UNIFIED IDEOGRAPH
+0xE181	0x7601	#CJK UNIFIED IDEOGRAPH
+0xE182	0x75F0	#CJK UNIFIED IDEOGRAPH
+0xE183	0x75FA	#CJK UNIFIED IDEOGRAPH
+0xE184	0x75F2	#CJK UNIFIED IDEOGRAPH
+0xE185	0x75F3	#CJK UNIFIED IDEOGRAPH
+0xE186	0x760B	#CJK UNIFIED IDEOGRAPH
+0xE187	0x760D	#CJK UNIFIED IDEOGRAPH
+0xE188	0x7609	#CJK UNIFIED IDEOGRAPH
+0xE189	0x761F	#CJK UNIFIED IDEOGRAPH
+0xE18A	0x7627	#CJK UNIFIED IDEOGRAPH
+0xE18B	0x7620	#CJK UNIFIED IDEOGRAPH
+0xE18C	0x7621	#CJK UNIFIED IDEOGRAPH
+0xE18D	0x7622	#CJK UNIFIED IDEOGRAPH
+0xE18E	0x7624	#CJK UNIFIED IDEOGRAPH
+0xE18F	0x7634	#CJK UNIFIED IDEOGRAPH
+0xE190	0x7630	#CJK UNIFIED IDEOGRAPH
+0xE191	0x763B	#CJK UNIFIED IDEOGRAPH
+0xE192	0x7647	#CJK UNIFIED IDEOGRAPH
+0xE193	0x7648	#CJK UNIFIED IDEOGRAPH
+0xE194	0x7646	#CJK UNIFIED IDEOGRAPH
+0xE195	0x765C	#CJK UNIFIED IDEOGRAPH
+0xE196	0x7658	#CJK UNIFIED IDEOGRAPH
+0xE197	0x7661	#CJK UNIFIED IDEOGRAPH
+0xE198	0x7662	#CJK UNIFIED IDEOGRAPH
+0xE199	0x7668	#CJK UNIFIED IDEOGRAPH
+0xE19A	0x7669	#CJK UNIFIED IDEOGRAPH
+0xE19B	0x766A	#CJK UNIFIED IDEOGRAPH
+0xE19C	0x7667	#CJK UNIFIED IDEOGRAPH
+0xE19D	0x766C	#CJK UNIFIED IDEOGRAPH
+0xE19E	0x7670	#CJK UNIFIED IDEOGRAPH
+0xE19F	0x7672	#CJK UNIFIED IDEOGRAPH
+0xE1A0	0x7676	#CJK UNIFIED IDEOGRAPH
+0xE1A1	0x7678	#CJK UNIFIED IDEOGRAPH
+0xE1A2	0x767C	#CJK UNIFIED IDEOGRAPH
+0xE1A3	0x7680	#CJK UNIFIED IDEOGRAPH
+0xE1A4	0x7683	#CJK UNIFIED IDEOGRAPH
+0xE1A5	0x7688	#CJK UNIFIED IDEOGRAPH
+0xE1A6	0x768B	#CJK UNIFIED IDEOGRAPH
+0xE1A7	0x768E	#CJK UNIFIED IDEOGRAPH
+0xE1A8	0x7696	#CJK UNIFIED IDEOGRAPH
+0xE1A9	0x7693	#CJK UNIFIED IDEOGRAPH
+0xE1AA	0x7699	#CJK UNIFIED IDEOGRAPH
+0xE1AB	0x769A	#CJK UNIFIED IDEOGRAPH
+0xE1AC	0x76B0	#CJK UNIFIED IDEOGRAPH
+0xE1AD	0x76B4	#CJK UNIFIED IDEOGRAPH
+0xE1AE	0x76B8	#CJK UNIFIED IDEOGRAPH
+0xE1AF	0x76B9	#CJK UNIFIED IDEOGRAPH
+0xE1B0	0x76BA	#CJK UNIFIED IDEOGRAPH
+0xE1B1	0x76C2	#CJK UNIFIED IDEOGRAPH
+0xE1B2	0x76CD	#CJK UNIFIED IDEOGRAPH
+0xE1B3	0x76D6	#CJK UNIFIED IDEOGRAPH
+0xE1B4	0x76D2	#CJK UNIFIED IDEOGRAPH
+0xE1B5	0x76DE	#CJK UNIFIED IDEOGRAPH
+0xE1B6	0x76E1	#CJK UNIFIED IDEOGRAPH
+0xE1B7	0x76E5	#CJK UNIFIED IDEOGRAPH
+0xE1B8	0x76E7	#CJK UNIFIED IDEOGRAPH
+0xE1B9	0x76EA	#CJK UNIFIED IDEOGRAPH
+0xE1BA	0x862F	#CJK UNIFIED IDEOGRAPH
+0xE1BB	0x76FB	#CJK UNIFIED IDEOGRAPH
+0xE1BC	0x7708	#CJK UNIFIED IDEOGRAPH
+0xE1BD	0x7707	#CJK UNIFIED IDEOGRAPH
+0xE1BE	0x7704	#CJK UNIFIED IDEOGRAPH
+0xE1BF	0x7729	#CJK UNIFIED IDEOGRAPH
+0xE1C0	0x7724	#CJK UNIFIED IDEOGRAPH
+0xE1C1	0x771E	#CJK UNIFIED IDEOGRAPH
+0xE1C2	0x7725	#CJK UNIFIED IDEOGRAPH
+0xE1C3	0x7726	#CJK UNIFIED IDEOGRAPH
+0xE1C4	0x771B	#CJK UNIFIED IDEOGRAPH
+0xE1C5	0x7737	#CJK UNIFIED IDEOGRAPH
+0xE1C6	0x7738	#CJK UNIFIED IDEOGRAPH
+0xE1C7	0x7747	#CJK UNIFIED IDEOGRAPH
+0xE1C8	0x775A	#CJK UNIFIED IDEOGRAPH
+0xE1C9	0x7768	#CJK UNIFIED IDEOGRAPH
+0xE1CA	0x776B	#CJK UNIFIED IDEOGRAPH
+0xE1CB	0x775B	#CJK UNIFIED IDEOGRAPH
+0xE1CC	0x7765	#CJK UNIFIED IDEOGRAPH
+0xE1CD	0x777F	#CJK UNIFIED IDEOGRAPH
+0xE1CE	0x777E	#CJK UNIFIED IDEOGRAPH
+0xE1CF	0x7779	#CJK UNIFIED IDEOGRAPH
+0xE1D0	0x778E	#CJK UNIFIED IDEOGRAPH
+0xE1D1	0x778B	#CJK UNIFIED IDEOGRAPH
+0xE1D2	0x7791	#CJK UNIFIED IDEOGRAPH
+0xE1D3	0x77A0	#CJK UNIFIED IDEOGRAPH
+0xE1D4	0x779E	#CJK UNIFIED IDEOGRAPH
+0xE1D5	0x77B0	#CJK UNIFIED IDEOGRAPH
+0xE1D6	0x77B6	#CJK UNIFIED IDEOGRAPH
+0xE1D7	0x77B9	#CJK UNIFIED IDEOGRAPH
+0xE1D8	0x77BF	#CJK UNIFIED IDEOGRAPH
+0xE1D9	0x77BC	#CJK UNIFIED IDEOGRAPH
+0xE1DA	0x77BD	#CJK UNIFIED IDEOGRAPH
+0xE1DB	0x77BB	#CJK UNIFIED IDEOGRAPH
+0xE1DC	0x77C7	#CJK UNIFIED IDEOGRAPH
+0xE1DD	0x77CD	#CJK UNIFIED IDEOGRAPH
+0xE1DE	0x77D7	#CJK UNIFIED IDEOGRAPH
+0xE1DF	0x77DA	#CJK UNIFIED IDEOGRAPH
+0xE1E0	0x77DC	#CJK UNIFIED IDEOGRAPH
+0xE1E1	0x77E3	#CJK UNIFIED IDEOGRAPH
+0xE1E2	0x77EE	#CJK UNIFIED IDEOGRAPH
+0xE1E3	0x77FC	#CJK UNIFIED IDEOGRAPH
+0xE1E4	0x780C	#CJK UNIFIED IDEOGRAPH
+0xE1E5	0x7812	#CJK UNIFIED IDEOGRAPH
+0xE1E6	0x7926	#CJK UNIFIED IDEOGRAPH
+0xE1E7	0x7820	#CJK UNIFIED IDEOGRAPH
+0xE1E8	0x792A	#CJK UNIFIED IDEOGRAPH
+0xE1E9	0x7845	#CJK UNIFIED IDEOGRAPH
+0xE1EA	0x788E	#CJK UNIFIED IDEOGRAPH
+0xE1EB	0x7874	#CJK UNIFIED IDEOGRAPH
+0xE1EC	0x7886	#CJK UNIFIED IDEOGRAPH
+0xE1ED	0x787C	#CJK UNIFIED IDEOGRAPH
+0xE1EE	0x789A	#CJK UNIFIED IDEOGRAPH
+0xE1EF	0x788C	#CJK UNIFIED IDEOGRAPH
+0xE1F0	0x78A3	#CJK UNIFIED IDEOGRAPH
+0xE1F1	0x78B5	#CJK UNIFIED IDEOGRAPH
+0xE1F2	0x78AA	#CJK UNIFIED IDEOGRAPH
+0xE1F3	0x78AF	#CJK UNIFIED IDEOGRAPH
+0xE1F4	0x78D1	#CJK UNIFIED IDEOGRAPH
+0xE1F5	0x78C6	#CJK UNIFIED IDEOGRAPH
+0xE1F6	0x78CB	#CJK UNIFIED IDEOGRAPH
+0xE1F7	0x78D4	#CJK UNIFIED IDEOGRAPH
+0xE1F8	0x78BE	#CJK UNIFIED IDEOGRAPH
+0xE1F9	0x78BC	#CJK UNIFIED IDEOGRAPH
+0xE1FA	0x78C5	#CJK UNIFIED IDEOGRAPH
+0xE1FB	0x78CA	#CJK UNIFIED IDEOGRAPH
+0xE1FC	0x78EC	#CJK UNIFIED IDEOGRAPH
+0xE240	0x78E7	#CJK UNIFIED IDEOGRAPH
+0xE241	0x78DA	#CJK UNIFIED IDEOGRAPH
+0xE242	0x78FD	#CJK UNIFIED IDEOGRAPH
+0xE243	0x78F4	#CJK UNIFIED IDEOGRAPH
+0xE244	0x7907	#CJK UNIFIED IDEOGRAPH
+0xE245	0x7912	#CJK UNIFIED IDEOGRAPH
+0xE246	0x7911	#CJK UNIFIED IDEOGRAPH
+0xE247	0x7919	#CJK UNIFIED IDEOGRAPH
+0xE248	0x792C	#CJK UNIFIED IDEOGRAPH
+0xE249	0x792B	#CJK UNIFIED IDEOGRAPH
+0xE24A	0x7940	#CJK UNIFIED IDEOGRAPH
+0xE24B	0x7960	#CJK UNIFIED IDEOGRAPH
+0xE24C	0x7957	#CJK UNIFIED IDEOGRAPH
+0xE24D	0x795F	#CJK UNIFIED IDEOGRAPH
+0xE24E	0x795A	#CJK UNIFIED IDEOGRAPH
+0xE24F	0x7955	#CJK UNIFIED IDEOGRAPH
+0xE250	0x7953	#CJK UNIFIED IDEOGRAPH
+0xE251	0x797A	#CJK UNIFIED IDEOGRAPH
+0xE252	0x797F	#CJK UNIFIED IDEOGRAPH
+0xE253	0x798A	#CJK UNIFIED IDEOGRAPH
+0xE254	0x799D	#CJK UNIFIED IDEOGRAPH
+0xE255	0x79A7	#CJK UNIFIED IDEOGRAPH
+0xE256	0x9F4B	#CJK UNIFIED IDEOGRAPH
+0xE257	0x79AA	#CJK UNIFIED IDEOGRAPH
+0xE258	0x79AE	#CJK UNIFIED IDEOGRAPH
+0xE259	0x79B3	#CJK UNIFIED IDEOGRAPH
+0xE25A	0x79B9	#CJK UNIFIED IDEOGRAPH
+0xE25B	0x79BA	#CJK UNIFIED IDEOGRAPH
+0xE25C	0x79C9	#CJK UNIFIED IDEOGRAPH
+0xE25D	0x79D5	#CJK UNIFIED IDEOGRAPH
+0xE25E	0x79E7	#CJK UNIFIED IDEOGRAPH
+0xE25F	0x79EC	#CJK UNIFIED IDEOGRAPH
+0xE260	0x79E1	#CJK UNIFIED IDEOGRAPH
+0xE261	0x79E3	#CJK UNIFIED IDEOGRAPH
+0xE262	0x7A08	#CJK UNIFIED IDEOGRAPH
+0xE263	0x7A0D	#CJK UNIFIED IDEOGRAPH
+0xE264	0x7A18	#CJK UNIFIED IDEOGRAPH
+0xE265	0x7A19	#CJK UNIFIED IDEOGRAPH
+0xE266	0x7A20	#CJK UNIFIED IDEOGRAPH
+0xE267	0x7A1F	#CJK UNIFIED IDEOGRAPH
+0xE268	0x7980	#CJK UNIFIED IDEOGRAPH
+0xE269	0x7A31	#CJK UNIFIED IDEOGRAPH
+0xE26A	0x7A3B	#CJK UNIFIED IDEOGRAPH
+0xE26B	0x7A3E	#CJK UNIFIED IDEOGRAPH
+0xE26C	0x7A37	#CJK UNIFIED IDEOGRAPH
+0xE26D	0x7A43	#CJK UNIFIED IDEOGRAPH
+0xE26E	0x7A57	#CJK UNIFIED IDEOGRAPH
+0xE26F	0x7A49	#CJK UNIFIED IDEOGRAPH
+0xE270	0x7A61	#CJK UNIFIED IDEOGRAPH
+0xE271	0x7A62	#CJK UNIFIED IDEOGRAPH
+0xE272	0x7A69	#CJK UNIFIED IDEOGRAPH
+0xE273	0x9F9D	#CJK UNIFIED IDEOGRAPH
+0xE274	0x7A70	#CJK UNIFIED IDEOGRAPH
+0xE275	0x7A79	#CJK UNIFIED IDEOGRAPH
+0xE276	0x7A7D	#CJK UNIFIED IDEOGRAPH
+0xE277	0x7A88	#CJK UNIFIED IDEOGRAPH
+0xE278	0x7A97	#CJK UNIFIED IDEOGRAPH
+0xE279	0x7A95	#CJK UNIFIED IDEOGRAPH
+0xE27A	0x7A98	#CJK UNIFIED IDEOGRAPH
+0xE27B	0x7A96	#CJK UNIFIED IDEOGRAPH
+0xE27C	0x7AA9	#CJK UNIFIED IDEOGRAPH
+0xE27D	0x7AC8	#CJK UNIFIED IDEOGRAPH
+0xE27E	0x7AB0	#CJK UNIFIED IDEOGRAPH
+0xE280	0x7AB6	#CJK UNIFIED IDEOGRAPH
+0xE281	0x7AC5	#CJK UNIFIED IDEOGRAPH
+0xE282	0x7AC4	#CJK UNIFIED IDEOGRAPH
+0xE283	0x7ABF	#CJK UNIFIED IDEOGRAPH
+0xE284	0x9083	#CJK UNIFIED IDEOGRAPH
+0xE285	0x7AC7	#CJK UNIFIED IDEOGRAPH
+0xE286	0x7ACA	#CJK UNIFIED IDEOGRAPH
+0xE287	0x7ACD	#CJK UNIFIED IDEOGRAPH
+0xE288	0x7ACF	#CJK UNIFIED IDEOGRAPH
+0xE289	0x7AD5	#CJK UNIFIED IDEOGRAPH
+0xE28A	0x7AD3	#CJK UNIFIED IDEOGRAPH
+0xE28B	0x7AD9	#CJK UNIFIED IDEOGRAPH
+0xE28C	0x7ADA	#CJK UNIFIED IDEOGRAPH
+0xE28D	0x7ADD	#CJK UNIFIED IDEOGRAPH
+0xE28E	0x7AE1	#CJK UNIFIED IDEOGRAPH
+0xE28F	0x7AE2	#CJK UNIFIED IDEOGRAPH
+0xE290	0x7AE6	#CJK UNIFIED IDEOGRAPH
+0xE291	0x7AED	#CJK UNIFIED IDEOGRAPH
+0xE292	0x7AF0	#CJK UNIFIED IDEOGRAPH
+0xE293	0x7B02	#CJK UNIFIED IDEOGRAPH
+0xE294	0x7B0F	#CJK UNIFIED IDEOGRAPH
+0xE295	0x7B0A	#CJK UNIFIED IDEOGRAPH
+0xE296	0x7B06	#CJK UNIFIED IDEOGRAPH
+0xE297	0x7B33	#CJK UNIFIED IDEOGRAPH
+0xE298	0x7B18	#CJK UNIFIED IDEOGRAPH
+0xE299	0x7B19	#CJK UNIFIED IDEOGRAPH
+0xE29A	0x7B1E	#CJK UNIFIED IDEOGRAPH
+0xE29B	0x7B35	#CJK UNIFIED IDEOGRAPH
+0xE29C	0x7B28	#CJK UNIFIED IDEOGRAPH
+0xE29D	0x7B36	#CJK UNIFIED IDEOGRAPH
+0xE29E	0x7B50	#CJK UNIFIED IDEOGRAPH
+0xE29F	0x7B7A	#CJK UNIFIED IDEOGRAPH
+0xE2A0	0x7B04	#CJK UNIFIED IDEOGRAPH
+0xE2A1	0x7B4D	#CJK UNIFIED IDEOGRAPH
+0xE2A2	0x7B0B	#CJK UNIFIED IDEOGRAPH
+0xE2A3	0x7B4C	#CJK UNIFIED IDEOGRAPH
+0xE2A4	0x7B45	#CJK UNIFIED IDEOGRAPH
+0xE2A5	0x7B75	#CJK UNIFIED IDEOGRAPH
+0xE2A6	0x7B65	#CJK UNIFIED IDEOGRAPH
+0xE2A7	0x7B74	#CJK UNIFIED IDEOGRAPH
+0xE2A8	0x7B67	#CJK UNIFIED IDEOGRAPH
+0xE2A9	0x7B70	#CJK UNIFIED IDEOGRAPH
+0xE2AA	0x7B71	#CJK UNIFIED IDEOGRAPH
+0xE2AB	0x7B6C	#CJK UNIFIED IDEOGRAPH
+0xE2AC	0x7B6E	#CJK UNIFIED IDEOGRAPH
+0xE2AD	0x7B9D	#CJK UNIFIED IDEOGRAPH
+0xE2AE	0x7B98	#CJK UNIFIED IDEOGRAPH
+0xE2AF	0x7B9F	#CJK UNIFIED IDEOGRAPH
+0xE2B0	0x7B8D	#CJK UNIFIED IDEOGRAPH
+0xE2B1	0x7B9C	#CJK UNIFIED IDEOGRAPH
+0xE2B2	0x7B9A	#CJK UNIFIED IDEOGRAPH
+0xE2B3	0x7B8B	#CJK UNIFIED IDEOGRAPH
+0xE2B4	0x7B92	#CJK UNIFIED IDEOGRAPH
+0xE2B5	0x7B8F	#CJK UNIFIED IDEOGRAPH
+0xE2B6	0x7B5D	#CJK UNIFIED IDEOGRAPH
+0xE2B7	0x7B99	#CJK UNIFIED IDEOGRAPH
+0xE2B8	0x7BCB	#CJK UNIFIED IDEOGRAPH
+0xE2B9	0x7BC1	#CJK UNIFIED IDEOGRAPH
+0xE2BA	0x7BCC	#CJK UNIFIED IDEOGRAPH
+0xE2BB	0x7BCF	#CJK UNIFIED IDEOGRAPH
+0xE2BC	0x7BB4	#CJK UNIFIED IDEOGRAPH
+0xE2BD	0x7BC6	#CJK UNIFIED IDEOGRAPH
+0xE2BE	0x7BDD	#CJK UNIFIED IDEOGRAPH
+0xE2BF	0x7BE9	#CJK UNIFIED IDEOGRAPH
+0xE2C0	0x7C11	#CJK UNIFIED IDEOGRAPH
+0xE2C1	0x7C14	#CJK UNIFIED IDEOGRAPH
+0xE2C2	0x7BE6	#CJK UNIFIED IDEOGRAPH
+0xE2C3	0x7BE5	#CJK UNIFIED IDEOGRAPH
+0xE2C4	0x7C60	#CJK UNIFIED IDEOGRAPH
+0xE2C5	0x7C00	#CJK UNIFIED IDEOGRAPH
+0xE2C6	0x7C07	#CJK UNIFIED IDEOGRAPH
+0xE2C7	0x7C13	#CJK UNIFIED IDEOGRAPH
+0xE2C8	0x7BF3	#CJK UNIFIED IDEOGRAPH
+0xE2C9	0x7BF7	#CJK UNIFIED IDEOGRAPH
+0xE2CA	0x7C17	#CJK UNIFIED IDEOGRAPH
+0xE2CB	0x7C0D	#CJK UNIFIED IDEOGRAPH
+0xE2CC	0x7BF6	#CJK UNIFIED IDEOGRAPH
+0xE2CD	0x7C23	#CJK UNIFIED IDEOGRAPH
+0xE2CE	0x7C27	#CJK UNIFIED IDEOGRAPH
+0xE2CF	0x7C2A	#CJK UNIFIED IDEOGRAPH
+0xE2D0	0x7C1F	#CJK UNIFIED IDEOGRAPH
+0xE2D1	0x7C37	#CJK UNIFIED IDEOGRAPH
+0xE2D2	0x7C2B	#CJK UNIFIED IDEOGRAPH
+0xE2D3	0x7C3D	#CJK UNIFIED IDEOGRAPH
+0xE2D4	0x7C4C	#CJK UNIFIED IDEOGRAPH
+0xE2D5	0x7C43	#CJK UNIFIED IDEOGRAPH
+0xE2D6	0x7C54	#CJK UNIFIED IDEOGRAPH
+0xE2D7	0x7C4F	#CJK UNIFIED IDEOGRAPH
+0xE2D8	0x7C40	#CJK UNIFIED IDEOGRAPH
+0xE2D9	0x7C50	#CJK UNIFIED IDEOGRAPH
+0xE2DA	0x7C58	#CJK UNIFIED IDEOGRAPH
+0xE2DB	0x7C5F	#CJK UNIFIED IDEOGRAPH
+0xE2DC	0x7C64	#CJK UNIFIED IDEOGRAPH
+0xE2DD	0x7C56	#CJK UNIFIED IDEOGRAPH
+0xE2DE	0x7C65	#CJK UNIFIED IDEOGRAPH
+0xE2DF	0x7C6C	#CJK UNIFIED IDEOGRAPH
+0xE2E0	0x7C75	#CJK UNIFIED IDEOGRAPH
+0xE2E1	0x7C83	#CJK UNIFIED IDEOGRAPH
+0xE2E2	0x7C90	#CJK UNIFIED IDEOGRAPH
+0xE2E3	0x7CA4	#CJK UNIFIED IDEOGRAPH
+0xE2E4	0x7CAD	#CJK UNIFIED IDEOGRAPH
+0xE2E5	0x7CA2	#CJK UNIFIED IDEOGRAPH
+0xE2E6	0x7CAB	#CJK UNIFIED IDEOGRAPH
+0xE2E7	0x7CA1	#CJK UNIFIED IDEOGRAPH
+0xE2E8	0x7CA8	#CJK UNIFIED IDEOGRAPH
+0xE2E9	0x7CB3	#CJK UNIFIED IDEOGRAPH
+0xE2EA	0x7CB2	#CJK UNIFIED IDEOGRAPH
+0xE2EB	0x7CB1	#CJK UNIFIED IDEOGRAPH
+0xE2EC	0x7CAE	#CJK UNIFIED IDEOGRAPH
+0xE2ED	0x7CB9	#CJK UNIFIED IDEOGRAPH
+0xE2EE	0x7CBD	#CJK UNIFIED IDEOGRAPH
+0xE2EF	0x7CC0	#CJK UNIFIED IDEOGRAPH
+0xE2F0	0x7CC5	#CJK UNIFIED IDEOGRAPH
+0xE2F1	0x7CC2	#CJK UNIFIED IDEOGRAPH
+0xE2F2	0x7CD8	#CJK UNIFIED IDEOGRAPH
+0xE2F3	0x7CD2	#CJK UNIFIED IDEOGRAPH
+0xE2F4	0x7CDC	#CJK UNIFIED IDEOGRAPH
+0xE2F5	0x7CE2	#CJK UNIFIED IDEOGRAPH
+0xE2F6	0x9B3B	#CJK UNIFIED IDEOGRAPH
+0xE2F7	0x7CEF	#CJK UNIFIED IDEOGRAPH
+0xE2F8	0x7CF2	#CJK UNIFIED IDEOGRAPH
+0xE2F9	0x7CF4	#CJK UNIFIED IDEOGRAPH
+0xE2FA	0x7CF6	#CJK UNIFIED IDEOGRAPH
+0xE2FB	0x7CFA	#CJK UNIFIED IDEOGRAPH
+0xE2FC	0x7D06	#CJK UNIFIED IDEOGRAPH
+0xE340	0x7D02	#CJK UNIFIED IDEOGRAPH
+0xE341	0x7D1C	#CJK UNIFIED IDEOGRAPH
+0xE342	0x7D15	#CJK UNIFIED IDEOGRAPH
+0xE343	0x7D0A	#CJK UNIFIED IDEOGRAPH
+0xE344	0x7D45	#CJK UNIFIED IDEOGRAPH
+0xE345	0x7D4B	#CJK UNIFIED IDEOGRAPH
+0xE346	0x7D2E	#CJK UNIFIED IDEOGRAPH
+0xE347	0x7D32	#CJK UNIFIED IDEOGRAPH
+0xE348	0x7D3F	#CJK UNIFIED IDEOGRAPH
+0xE349	0x7D35	#CJK UNIFIED IDEOGRAPH
+0xE34A	0x7D46	#CJK UNIFIED IDEOGRAPH
+0xE34B	0x7D73	#CJK UNIFIED IDEOGRAPH
+0xE34C	0x7D56	#CJK UNIFIED IDEOGRAPH
+0xE34D	0x7D4E	#CJK UNIFIED IDEOGRAPH
+0xE34E	0x7D72	#CJK UNIFIED IDEOGRAPH
+0xE34F	0x7D68	#CJK UNIFIED IDEOGRAPH
+0xE350	0x7D6E	#CJK UNIFIED IDEOGRAPH
+0xE351	0x7D4F	#CJK UNIFIED IDEOGRAPH
+0xE352	0x7D63	#CJK UNIFIED IDEOGRAPH
+0xE353	0x7D93	#CJK UNIFIED IDEOGRAPH
+0xE354	0x7D89	#CJK UNIFIED IDEOGRAPH
+0xE355	0x7D5B	#CJK UNIFIED IDEOGRAPH
+0xE356	0x7D8F	#CJK UNIFIED IDEOGRAPH
+0xE357	0x7D7D	#CJK UNIFIED IDEOGRAPH
+0xE358	0x7D9B	#CJK UNIFIED IDEOGRAPH
+0xE359	0x7DBA	#CJK UNIFIED IDEOGRAPH
+0xE35A	0x7DAE	#CJK UNIFIED IDEOGRAPH
+0xE35B	0x7DA3	#CJK UNIFIED IDEOGRAPH
+0xE35C	0x7DB5	#CJK UNIFIED IDEOGRAPH
+0xE35D	0x7DC7	#CJK UNIFIED IDEOGRAPH
+0xE35E	0x7DBD	#CJK UNIFIED IDEOGRAPH
+0xE35F	0x7DAB	#CJK UNIFIED IDEOGRAPH
+0xE360	0x7E3D	#CJK UNIFIED IDEOGRAPH
+0xE361	0x7DA2	#CJK UNIFIED IDEOGRAPH
+0xE362	0x7DAF	#CJK UNIFIED IDEOGRAPH
+0xE363	0x7DDC	#CJK UNIFIED IDEOGRAPH
+0xE364	0x7DB8	#CJK UNIFIED IDEOGRAPH
+0xE365	0x7D9F	#CJK UNIFIED IDEOGRAPH
+0xE366	0x7DB0	#CJK UNIFIED IDEOGRAPH
+0xE367	0x7DD8	#CJK UNIFIED IDEOGRAPH
+0xE368	0x7DDD	#CJK UNIFIED IDEOGRAPH
+0xE369	0x7DE4	#CJK UNIFIED IDEOGRAPH
+0xE36A	0x7DDE	#CJK UNIFIED IDEOGRAPH
+0xE36B	0x7DFB	#CJK UNIFIED IDEOGRAPH
+0xE36C	0x7DF2	#CJK UNIFIED IDEOGRAPH
+0xE36D	0x7DE1	#CJK UNIFIED IDEOGRAPH
+0xE36E	0x7E05	#CJK UNIFIED IDEOGRAPH
+0xE36F	0x7E0A	#CJK UNIFIED IDEOGRAPH
+0xE370	0x7E23	#CJK UNIFIED IDEOGRAPH
+0xE371	0x7E21	#CJK UNIFIED IDEOGRAPH
+0xE372	0x7E12	#CJK UNIFIED IDEOGRAPH
+0xE373	0x7E31	#CJK UNIFIED IDEOGRAPH
+0xE374	0x7E1F	#CJK UNIFIED IDEOGRAPH
+0xE375	0x7E09	#CJK UNIFIED IDEOGRAPH
+0xE376	0x7E0B	#CJK UNIFIED IDEOGRAPH
+0xE377	0x7E22	#CJK UNIFIED IDEOGRAPH
+0xE378	0x7E46	#CJK UNIFIED IDEOGRAPH
+0xE379	0x7E66	#CJK UNIFIED IDEOGRAPH
+0xE37A	0x7E3B	#CJK UNIFIED IDEOGRAPH
+0xE37B	0x7E35	#CJK UNIFIED IDEOGRAPH
+0xE37C	0x7E39	#CJK UNIFIED IDEOGRAPH
+0xE37D	0x7E43	#CJK UNIFIED IDEOGRAPH
+0xE37E	0x7E37	#CJK UNIFIED IDEOGRAPH
+0xE380	0x7E32	#CJK UNIFIED IDEOGRAPH
+0xE381	0x7E3A	#CJK UNIFIED IDEOGRAPH
+0xE382	0x7E67	#CJK UNIFIED IDEOGRAPH
+0xE383	0x7E5D	#CJK UNIFIED IDEOGRAPH
+0xE384	0x7E56	#CJK UNIFIED IDEOGRAPH
+0xE385	0x7E5E	#CJK UNIFIED IDEOGRAPH
+0xE386	0x7E59	#CJK UNIFIED IDEOGRAPH
+0xE387	0x7E5A	#CJK UNIFIED IDEOGRAPH
+0xE388	0x7E79	#CJK UNIFIED IDEOGRAPH
+0xE389	0x7E6A	#CJK UNIFIED IDEOGRAPH
+0xE38A	0x7E69	#CJK UNIFIED IDEOGRAPH
+0xE38B	0x7E7C	#CJK UNIFIED IDEOGRAPH
+0xE38C	0x7E7B	#CJK UNIFIED IDEOGRAPH
+0xE38D	0x7E83	#CJK UNIFIED IDEOGRAPH
+0xE38E	0x7DD5	#CJK UNIFIED IDEOGRAPH
+0xE38F	0x7E7D	#CJK UNIFIED IDEOGRAPH
+0xE390	0x8FAE	#CJK UNIFIED IDEOGRAPH
+0xE391	0x7E7F	#CJK UNIFIED IDEOGRAPH
+0xE392	0x7E88	#CJK UNIFIED IDEOGRAPH
+0xE393	0x7E89	#CJK UNIFIED IDEOGRAPH
+0xE394	0x7E8C	#CJK UNIFIED IDEOGRAPH
+0xE395	0x7E92	#CJK UNIFIED IDEOGRAPH
+0xE396	0x7E90	#CJK UNIFIED IDEOGRAPH
+0xE397	0x7E93	#CJK UNIFIED IDEOGRAPH
+0xE398	0x7E94	#CJK UNIFIED IDEOGRAPH
+0xE399	0x7E96	#CJK UNIFIED IDEOGRAPH
+0xE39A	0x7E8E	#CJK UNIFIED IDEOGRAPH
+0xE39B	0x7E9B	#CJK UNIFIED IDEOGRAPH
+0xE39C	0x7E9C	#CJK UNIFIED IDEOGRAPH
+0xE39D	0x7F38	#CJK UNIFIED IDEOGRAPH
+0xE39E	0x7F3A	#CJK UNIFIED IDEOGRAPH
+0xE39F	0x7F45	#CJK UNIFIED IDEOGRAPH
+0xE3A0	0x7F4C	#CJK UNIFIED IDEOGRAPH
+0xE3A1	0x7F4D	#CJK UNIFIED IDEOGRAPH
+0xE3A2	0x7F4E	#CJK UNIFIED IDEOGRAPH
+0xE3A3	0x7F50	#CJK UNIFIED IDEOGRAPH
+0xE3A4	0x7F51	#CJK UNIFIED IDEOGRAPH
+0xE3A5	0x7F55	#CJK UNIFIED IDEOGRAPH
+0xE3A6	0x7F54	#CJK UNIFIED IDEOGRAPH
+0xE3A7	0x7F58	#CJK UNIFIED IDEOGRAPH
+0xE3A8	0x7F5F	#CJK UNIFIED IDEOGRAPH
+0xE3A9	0x7F60	#CJK UNIFIED IDEOGRAPH
+0xE3AA	0x7F68	#CJK UNIFIED IDEOGRAPH
+0xE3AB	0x7F69	#CJK UNIFIED IDEOGRAPH
+0xE3AC	0x7F67	#CJK UNIFIED IDEOGRAPH
+0xE3AD	0x7F78	#CJK UNIFIED IDEOGRAPH
+0xE3AE	0x7F82	#CJK UNIFIED IDEOGRAPH
+0xE3AF	0x7F86	#CJK UNIFIED IDEOGRAPH
+0xE3B0	0x7F83	#CJK UNIFIED IDEOGRAPH
+0xE3B1	0x7F88	#CJK UNIFIED IDEOGRAPH
+0xE3B2	0x7F87	#CJK UNIFIED IDEOGRAPH
+0xE3B3	0x7F8C	#CJK UNIFIED IDEOGRAPH
+0xE3B4	0x7F94	#CJK UNIFIED IDEOGRAPH
+0xE3B5	0x7F9E	#CJK UNIFIED IDEOGRAPH
+0xE3B6	0x7F9D	#CJK UNIFIED IDEOGRAPH
+0xE3B7	0x7F9A	#CJK UNIFIED IDEOGRAPH
+0xE3B8	0x7FA3	#CJK UNIFIED IDEOGRAPH
+0xE3B9	0x7FAF	#CJK UNIFIED IDEOGRAPH
+0xE3BA	0x7FB2	#CJK UNIFIED IDEOGRAPH
+0xE3BB	0x7FB9	#CJK UNIFIED IDEOGRAPH
+0xE3BC	0x7FAE	#CJK UNIFIED IDEOGRAPH
+0xE3BD	0x7FB6	#CJK UNIFIED IDEOGRAPH
+0xE3BE	0x7FB8	#CJK UNIFIED IDEOGRAPH
+0xE3BF	0x8B71	#CJK UNIFIED IDEOGRAPH
+0xE3C0	0x7FC5	#CJK UNIFIED IDEOGRAPH
+0xE3C1	0x7FC6	#CJK UNIFIED IDEOGRAPH
+0xE3C2	0x7FCA	#CJK UNIFIED IDEOGRAPH
+0xE3C3	0x7FD5	#CJK UNIFIED IDEOGRAPH
+0xE3C4	0x7FD4	#CJK UNIFIED IDEOGRAPH
+0xE3C5	0x7FE1	#CJK UNIFIED IDEOGRAPH
+0xE3C6	0x7FE6	#CJK UNIFIED IDEOGRAPH
+0xE3C7	0x7FE9	#CJK UNIFIED IDEOGRAPH
+0xE3C8	0x7FF3	#CJK UNIFIED IDEOGRAPH
+0xE3C9	0x7FF9	#CJK UNIFIED IDEOGRAPH
+0xE3CA	0x98DC	#CJK UNIFIED IDEOGRAPH
+0xE3CB	0x8006	#CJK UNIFIED IDEOGRAPH
+0xE3CC	0x8004	#CJK UNIFIED IDEOGRAPH
+0xE3CD	0x800B	#CJK UNIFIED IDEOGRAPH
+0xE3CE	0x8012	#CJK UNIFIED IDEOGRAPH
+0xE3CF	0x8018	#CJK UNIFIED IDEOGRAPH
+0xE3D0	0x8019	#CJK UNIFIED IDEOGRAPH
+0xE3D1	0x801C	#CJK UNIFIED IDEOGRAPH
+0xE3D2	0x8021	#CJK UNIFIED IDEOGRAPH
+0xE3D3	0x8028	#CJK UNIFIED IDEOGRAPH
+0xE3D4	0x803F	#CJK UNIFIED IDEOGRAPH
+0xE3D5	0x803B	#CJK UNIFIED IDEOGRAPH
+0xE3D6	0x804A	#CJK UNIFIED IDEOGRAPH
+0xE3D7	0x8046	#CJK UNIFIED IDEOGRAPH
+0xE3D8	0x8052	#CJK UNIFIED IDEOGRAPH
+0xE3D9	0x8058	#CJK UNIFIED IDEOGRAPH
+0xE3DA	0x805A	#CJK UNIFIED IDEOGRAPH
+0xE3DB	0x805F	#CJK UNIFIED IDEOGRAPH
+0xE3DC	0x8062	#CJK UNIFIED IDEOGRAPH
+0xE3DD	0x8068	#CJK UNIFIED IDEOGRAPH
+0xE3DE	0x8073	#CJK UNIFIED IDEOGRAPH
+0xE3DF	0x8072	#CJK UNIFIED IDEOGRAPH
+0xE3E0	0x8070	#CJK UNIFIED IDEOGRAPH
+0xE3E1	0x8076	#CJK UNIFIED IDEOGRAPH
+0xE3E2	0x8079	#CJK UNIFIED IDEOGRAPH
+0xE3E3	0x807D	#CJK UNIFIED IDEOGRAPH
+0xE3E4	0x807F	#CJK UNIFIED IDEOGRAPH
+0xE3E5	0x8084	#CJK UNIFIED IDEOGRAPH
+0xE3E6	0x8086	#CJK UNIFIED IDEOGRAPH
+0xE3E7	0x8085	#CJK UNIFIED IDEOGRAPH
+0xE3E8	0x809B	#CJK UNIFIED IDEOGRAPH
+0xE3E9	0x8093	#CJK UNIFIED IDEOGRAPH
+0xE3EA	0x809A	#CJK UNIFIED IDEOGRAPH
+0xE3EB	0x80AD	#CJK UNIFIED IDEOGRAPH
+0xE3EC	0x5190	#CJK UNIFIED IDEOGRAPH
+0xE3ED	0x80AC	#CJK UNIFIED IDEOGRAPH
+0xE3EE	0x80DB	#CJK UNIFIED IDEOGRAPH
+0xE3EF	0x80E5	#CJK UNIFIED IDEOGRAPH
+0xE3F0	0x80D9	#CJK UNIFIED IDEOGRAPH
+0xE3F1	0x80DD	#CJK UNIFIED IDEOGRAPH
+0xE3F2	0x80C4	#CJK UNIFIED IDEOGRAPH
+0xE3F3	0x80DA	#CJK UNIFIED IDEOGRAPH
+0xE3F4	0x80D6	#CJK UNIFIED IDEOGRAPH
+0xE3F5	0x8109	#CJK UNIFIED IDEOGRAPH
+0xE3F6	0x80EF	#CJK UNIFIED IDEOGRAPH
+0xE3F7	0x80F1	#CJK UNIFIED IDEOGRAPH
+0xE3F8	0x811B	#CJK UNIFIED IDEOGRAPH
+0xE3F9	0x8129	#CJK UNIFIED IDEOGRAPH
+0xE3FA	0x8123	#CJK UNIFIED IDEOGRAPH
+0xE3FB	0x812F	#CJK UNIFIED IDEOGRAPH
+0xE3FC	0x814B	#CJK UNIFIED IDEOGRAPH
+0xE440	0x968B	#CJK UNIFIED IDEOGRAPH
+0xE441	0x8146	#CJK UNIFIED IDEOGRAPH
+0xE442	0x813E	#CJK UNIFIED IDEOGRAPH
+0xE443	0x8153	#CJK UNIFIED IDEOGRAPH
+0xE444	0x8151	#CJK UNIFIED IDEOGRAPH
+0xE445	0x80FC	#CJK UNIFIED IDEOGRAPH
+0xE446	0x8171	#CJK UNIFIED IDEOGRAPH
+0xE447	0x816E	#CJK UNIFIED IDEOGRAPH
+0xE448	0x8165	#CJK UNIFIED IDEOGRAPH
+0xE449	0x8166	#CJK UNIFIED IDEOGRAPH
+0xE44A	0x8174	#CJK UNIFIED IDEOGRAPH
+0xE44B	0x8183	#CJK UNIFIED IDEOGRAPH
+0xE44C	0x8188	#CJK UNIFIED IDEOGRAPH
+0xE44D	0x818A	#CJK UNIFIED IDEOGRAPH
+0xE44E	0x8180	#CJK UNIFIED IDEOGRAPH
+0xE44F	0x8182	#CJK UNIFIED IDEOGRAPH
+0xE450	0x81A0	#CJK UNIFIED IDEOGRAPH
+0xE451	0x8195	#CJK UNIFIED IDEOGRAPH
+0xE452	0x81A4	#CJK UNIFIED IDEOGRAPH
+0xE453	0x81A3	#CJK UNIFIED IDEOGRAPH
+0xE454	0x815F	#CJK UNIFIED IDEOGRAPH
+0xE455	0x8193	#CJK UNIFIED IDEOGRAPH
+0xE456	0x81A9	#CJK UNIFIED IDEOGRAPH
+0xE457	0x81B0	#CJK UNIFIED IDEOGRAPH
+0xE458	0x81B5	#CJK UNIFIED IDEOGRAPH
+0xE459	0x81BE	#CJK UNIFIED IDEOGRAPH
+0xE45A	0x81B8	#CJK UNIFIED IDEOGRAPH
+0xE45B	0x81BD	#CJK UNIFIED IDEOGRAPH
+0xE45C	0x81C0	#CJK UNIFIED IDEOGRAPH
+0xE45D	0x81C2	#CJK UNIFIED IDEOGRAPH
+0xE45E	0x81BA	#CJK UNIFIED IDEOGRAPH
+0xE45F	0x81C9	#CJK UNIFIED IDEOGRAPH
+0xE460	0x81CD	#CJK UNIFIED IDEOGRAPH
+0xE461	0x81D1	#CJK UNIFIED IDEOGRAPH
+0xE462	0x81D9	#CJK UNIFIED IDEOGRAPH
+0xE463	0x81D8	#CJK UNIFIED IDEOGRAPH
+0xE464	0x81C8	#CJK UNIFIED IDEOGRAPH
+0xE465	0x81DA	#CJK UNIFIED IDEOGRAPH
+0xE466	0x81DF	#CJK UNIFIED IDEOGRAPH
+0xE467	0x81E0	#CJK UNIFIED IDEOGRAPH
+0xE468	0x81E7	#CJK UNIFIED IDEOGRAPH
+0xE469	0x81FA	#CJK UNIFIED IDEOGRAPH
+0xE46A	0x81FB	#CJK UNIFIED IDEOGRAPH
+0xE46B	0x81FE	#CJK UNIFIED IDEOGRAPH
+0xE46C	0x8201	#CJK UNIFIED IDEOGRAPH
+0xE46D	0x8202	#CJK UNIFIED IDEOGRAPH
+0xE46E	0x8205	#CJK UNIFIED IDEOGRAPH
+0xE46F	0x8207	#CJK UNIFIED IDEOGRAPH
+0xE470	0x820A	#CJK UNIFIED IDEOGRAPH
+0xE471	0x820D	#CJK UNIFIED IDEOGRAPH
+0xE472	0x8210	#CJK UNIFIED IDEOGRAPH
+0xE473	0x8216	#CJK UNIFIED IDEOGRAPH
+0xE474	0x8229	#CJK UNIFIED IDEOGRAPH
+0xE475	0x822B	#CJK UNIFIED IDEOGRAPH
+0xE476	0x8238	#CJK UNIFIED IDEOGRAPH
+0xE477	0x8233	#CJK UNIFIED IDEOGRAPH
+0xE478	0x8240	#CJK UNIFIED IDEOGRAPH
+0xE479	0x8259	#CJK UNIFIED IDEOGRAPH
+0xE47A	0x8258	#CJK UNIFIED IDEOGRAPH
+0xE47B	0x825D	#CJK UNIFIED IDEOGRAPH
+0xE47C	0x825A	#CJK UNIFIED IDEOGRAPH
+0xE47D	0x825F	#CJK UNIFIED IDEOGRAPH
+0xE47E	0x8264	#CJK UNIFIED IDEOGRAPH
+0xE480	0x8262	#CJK UNIFIED IDEOGRAPH
+0xE481	0x8268	#CJK UNIFIED IDEOGRAPH
+0xE482	0x826A	#CJK UNIFIED IDEOGRAPH
+0xE483	0x826B	#CJK UNIFIED IDEOGRAPH
+0xE484	0x822E	#CJK UNIFIED IDEOGRAPH
+0xE485	0x8271	#CJK UNIFIED IDEOGRAPH
+0xE486	0x8277	#CJK UNIFIED IDEOGRAPH
+0xE487	0x8278	#CJK UNIFIED IDEOGRAPH
+0xE488	0x827E	#CJK UNIFIED IDEOGRAPH
+0xE489	0x828D	#CJK UNIFIED IDEOGRAPH
+0xE48A	0x8292	#CJK UNIFIED IDEOGRAPH
+0xE48B	0x82AB	#CJK UNIFIED IDEOGRAPH
+0xE48C	0x829F	#CJK UNIFIED IDEOGRAPH
+0xE48D	0x82BB	#CJK UNIFIED IDEOGRAPH
+0xE48E	0x82AC	#CJK UNIFIED IDEOGRAPH
+0xE48F	0x82E1	#CJK UNIFIED IDEOGRAPH
+0xE490	0x82E3	#CJK UNIFIED IDEOGRAPH
+0xE491	0x82DF	#CJK UNIFIED IDEOGRAPH
+0xE492	0x82D2	#CJK UNIFIED IDEOGRAPH
+0xE493	0x82F4	#CJK UNIFIED IDEOGRAPH
+0xE494	0x82F3	#CJK UNIFIED IDEOGRAPH
+0xE495	0x82FA	#CJK UNIFIED IDEOGRAPH
+0xE496	0x8393	#CJK UNIFIED IDEOGRAPH
+0xE497	0x8303	#CJK UNIFIED IDEOGRAPH
+0xE498	0x82FB	#CJK UNIFIED IDEOGRAPH
+0xE499	0x82F9	#CJK UNIFIED IDEOGRAPH
+0xE49A	0x82DE	#CJK UNIFIED IDEOGRAPH
+0xE49B	0x8306	#CJK UNIFIED IDEOGRAPH
+0xE49C	0x82DC	#CJK UNIFIED IDEOGRAPH
+0xE49D	0x8309	#CJK UNIFIED IDEOGRAPH
+0xE49E	0x82D9	#CJK UNIFIED IDEOGRAPH
+0xE49F	0x8335	#CJK UNIFIED IDEOGRAPH
+0xE4A0	0x8334	#CJK UNIFIED IDEOGRAPH
+0xE4A1	0x8316	#CJK UNIFIED IDEOGRAPH
+0xE4A2	0x8332	#CJK UNIFIED IDEOGRAPH
+0xE4A3	0x8331	#CJK UNIFIED IDEOGRAPH
+0xE4A4	0x8340	#CJK UNIFIED IDEOGRAPH
+0xE4A5	0x8339	#CJK UNIFIED IDEOGRAPH
+0xE4A6	0x8350	#CJK UNIFIED IDEOGRAPH
+0xE4A7	0x8345	#CJK UNIFIED IDEOGRAPH
+0xE4A8	0x832F	#CJK UNIFIED IDEOGRAPH
+0xE4A9	0x832B	#CJK UNIFIED IDEOGRAPH
+0xE4AA	0x8317	#CJK UNIFIED IDEOGRAPH
+0xE4AB	0x8318	#CJK UNIFIED IDEOGRAPH
+0xE4AC	0x8385	#CJK UNIFIED IDEOGRAPH
+0xE4AD	0x839A	#CJK UNIFIED IDEOGRAPH
+0xE4AE	0x83AA	#CJK UNIFIED IDEOGRAPH
+0xE4AF	0x839F	#CJK UNIFIED IDEOGRAPH
+0xE4B0	0x83A2	#CJK UNIFIED IDEOGRAPH
+0xE4B1	0x8396	#CJK UNIFIED IDEOGRAPH
+0xE4B2	0x8323	#CJK UNIFIED IDEOGRAPH
+0xE4B3	0x838E	#CJK UNIFIED IDEOGRAPH
+0xE4B4	0x8387	#CJK UNIFIED IDEOGRAPH
+0xE4B5	0x838A	#CJK UNIFIED IDEOGRAPH
+0xE4B6	0x837C	#CJK UNIFIED IDEOGRAPH
+0xE4B7	0x83B5	#CJK UNIFIED IDEOGRAPH
+0xE4B8	0x8373	#CJK UNIFIED IDEOGRAPH
+0xE4B9	0x8375	#CJK UNIFIED IDEOGRAPH
+0xE4BA	0x83A0	#CJK UNIFIED IDEOGRAPH
+0xE4BB	0x8389	#CJK UNIFIED IDEOGRAPH
+0xE4BC	0x83A8	#CJK UNIFIED IDEOGRAPH
+0xE4BD	0x83F4	#CJK UNIFIED IDEOGRAPH
+0xE4BE	0x8413	#CJK UNIFIED IDEOGRAPH
+0xE4BF	0x83EB	#CJK UNIFIED IDEOGRAPH
+0xE4C0	0x83CE	#CJK UNIFIED IDEOGRAPH
+0xE4C1	0x83FD	#CJK UNIFIED IDEOGRAPH
+0xE4C2	0x8403	#CJK UNIFIED IDEOGRAPH
+0xE4C3	0x83D8	#CJK UNIFIED IDEOGRAPH
+0xE4C4	0x840B	#CJK UNIFIED IDEOGRAPH
+0xE4C5	0x83C1	#CJK UNIFIED IDEOGRAPH
+0xE4C6	0x83F7	#CJK UNIFIED IDEOGRAPH
+0xE4C7	0x8407	#CJK UNIFIED IDEOGRAPH
+0xE4C8	0x83E0	#CJK UNIFIED IDEOGRAPH
+0xE4C9	0x83F2	#CJK UNIFIED IDEOGRAPH
+0xE4CA	0x840D	#CJK UNIFIED IDEOGRAPH
+0xE4CB	0x8422	#CJK UNIFIED IDEOGRAPH
+0xE4CC	0x8420	#CJK UNIFIED IDEOGRAPH
+0xE4CD	0x83BD	#CJK UNIFIED IDEOGRAPH
+0xE4CE	0x8438	#CJK UNIFIED IDEOGRAPH
+0xE4CF	0x8506	#CJK UNIFIED IDEOGRAPH
+0xE4D0	0x83FB	#CJK UNIFIED IDEOGRAPH
+0xE4D1	0x846D	#CJK UNIFIED IDEOGRAPH
+0xE4D2	0x842A	#CJK UNIFIED IDEOGRAPH
+0xE4D3	0x843C	#CJK UNIFIED IDEOGRAPH
+0xE4D4	0x855A	#CJK UNIFIED IDEOGRAPH
+0xE4D5	0x8484	#CJK UNIFIED IDEOGRAPH
+0xE4D6	0x8477	#CJK UNIFIED IDEOGRAPH
+0xE4D7	0x846B	#CJK UNIFIED IDEOGRAPH
+0xE4D8	0x84AD	#CJK UNIFIED IDEOGRAPH
+0xE4D9	0x846E	#CJK UNIFIED IDEOGRAPH
+0xE4DA	0x8482	#CJK UNIFIED IDEOGRAPH
+0xE4DB	0x8469	#CJK UNIFIED IDEOGRAPH
+0xE4DC	0x8446	#CJK UNIFIED IDEOGRAPH
+0xE4DD	0x842C	#CJK UNIFIED IDEOGRAPH
+0xE4DE	0x846F	#CJK UNIFIED IDEOGRAPH
+0xE4DF	0x8479	#CJK UNIFIED IDEOGRAPH
+0xE4E0	0x8435	#CJK UNIFIED IDEOGRAPH
+0xE4E1	0x84CA	#CJK UNIFIED IDEOGRAPH
+0xE4E2	0x8462	#CJK UNIFIED IDEOGRAPH
+0xE4E3	0x84B9	#CJK UNIFIED IDEOGRAPH
+0xE4E4	0x84BF	#CJK UNIFIED IDEOGRAPH
+0xE4E5	0x849F	#CJK UNIFIED IDEOGRAPH
+0xE4E6	0x84D9	#CJK UNIFIED IDEOGRAPH
+0xE4E7	0x84CD	#CJK UNIFIED IDEOGRAPH
+0xE4E8	0x84BB	#CJK UNIFIED IDEOGRAPH
+0xE4E9	0x84DA	#CJK UNIFIED IDEOGRAPH
+0xE4EA	0x84D0	#CJK UNIFIED IDEOGRAPH
+0xE4EB	0x84C1	#CJK UNIFIED IDEOGRAPH
+0xE4EC	0x84C6	#CJK UNIFIED IDEOGRAPH
+0xE4ED	0x84D6	#CJK UNIFIED IDEOGRAPH
+0xE4EE	0x84A1	#CJK UNIFIED IDEOGRAPH
+0xE4EF	0x8521	#CJK UNIFIED IDEOGRAPH
+0xE4F0	0x84FF	#CJK UNIFIED IDEOGRAPH
+0xE4F1	0x84F4	#CJK UNIFIED IDEOGRAPH
+0xE4F2	0x8517	#CJK UNIFIED IDEOGRAPH
+0xE4F3	0x8518	#CJK UNIFIED IDEOGRAPH
+0xE4F4	0x852C	#CJK UNIFIED IDEOGRAPH
+0xE4F5	0x851F	#CJK UNIFIED IDEOGRAPH
+0xE4F6	0x8515	#CJK UNIFIED IDEOGRAPH
+0xE4F7	0x8514	#CJK UNIFIED IDEOGRAPH
+0xE4F8	0x84FC	#CJK UNIFIED IDEOGRAPH
+0xE4F9	0x8540	#CJK UNIFIED IDEOGRAPH
+0xE4FA	0x8563	#CJK UNIFIED IDEOGRAPH
+0xE4FB	0x8558	#CJK UNIFIED IDEOGRAPH
+0xE4FC	0x8548	#CJK UNIFIED IDEOGRAPH
+0xE540	0x8541	#CJK UNIFIED IDEOGRAPH
+0xE541	0x8602	#CJK UNIFIED IDEOGRAPH
+0xE542	0x854B	#CJK UNIFIED IDEOGRAPH
+0xE543	0x8555	#CJK UNIFIED IDEOGRAPH
+0xE544	0x8580	#CJK UNIFIED IDEOGRAPH
+0xE545	0x85A4	#CJK UNIFIED IDEOGRAPH
+0xE546	0x8588	#CJK UNIFIED IDEOGRAPH
+0xE547	0x8591	#CJK UNIFIED IDEOGRAPH
+0xE548	0x858A	#CJK UNIFIED IDEOGRAPH
+0xE549	0x85A8	#CJK UNIFIED IDEOGRAPH
+0xE54A	0x856D	#CJK UNIFIED IDEOGRAPH
+0xE54B	0x8594	#CJK UNIFIED IDEOGRAPH
+0xE54C	0x859B	#CJK UNIFIED IDEOGRAPH
+0xE54D	0x85EA	#CJK UNIFIED IDEOGRAPH
+0xE54E	0x8587	#CJK UNIFIED IDEOGRAPH
+0xE54F	0x859C	#CJK UNIFIED IDEOGRAPH
+0xE550	0x8577	#CJK UNIFIED IDEOGRAPH
+0xE551	0x857E	#CJK UNIFIED IDEOGRAPH
+0xE552	0x8590	#CJK UNIFIED IDEOGRAPH
+0xE553	0x85C9	#CJK UNIFIED IDEOGRAPH
+0xE554	0x85BA	#CJK UNIFIED IDEOGRAPH
+0xE555	0x85CF	#CJK UNIFIED IDEOGRAPH
+0xE556	0x85B9	#CJK UNIFIED IDEOGRAPH
+0xE557	0x85D0	#CJK UNIFIED IDEOGRAPH
+0xE558	0x85D5	#CJK UNIFIED IDEOGRAPH
+0xE559	0x85DD	#CJK UNIFIED IDEOGRAPH
+0xE55A	0x85E5	#CJK UNIFIED IDEOGRAPH
+0xE55B	0x85DC	#CJK UNIFIED IDEOGRAPH
+0xE55C	0x85F9	#CJK UNIFIED IDEOGRAPH
+0xE55D	0x860A	#CJK UNIFIED IDEOGRAPH
+0xE55E	0x8613	#CJK UNIFIED IDEOGRAPH
+0xE55F	0x860B	#CJK UNIFIED IDEOGRAPH
+0xE560	0x85FE	#CJK UNIFIED IDEOGRAPH
+0xE561	0x85FA	#CJK UNIFIED IDEOGRAPH
+0xE562	0x8606	#CJK UNIFIED IDEOGRAPH
+0xE563	0x8622	#CJK UNIFIED IDEOGRAPH
+0xE564	0x861A	#CJK UNIFIED IDEOGRAPH
+0xE565	0x8630	#CJK UNIFIED IDEOGRAPH
+0xE566	0x863F	#CJK UNIFIED IDEOGRAPH
+0xE567	0x864D	#CJK UNIFIED IDEOGRAPH
+0xE568	0x4E55	#CJK UNIFIED IDEOGRAPH
+0xE569	0x8654	#CJK UNIFIED IDEOGRAPH
+0xE56A	0x865F	#CJK UNIFIED IDEOGRAPH
+0xE56B	0x8667	#CJK UNIFIED IDEOGRAPH
+0xE56C	0x8671	#CJK UNIFIED IDEOGRAPH
+0xE56D	0x8693	#CJK UNIFIED IDEOGRAPH
+0xE56E	0x86A3	#CJK UNIFIED IDEOGRAPH
+0xE56F	0x86A9	#CJK UNIFIED IDEOGRAPH
+0xE570	0x86AA	#CJK UNIFIED IDEOGRAPH
+0xE571	0x868B	#CJK UNIFIED IDEOGRAPH
+0xE572	0x868C	#CJK UNIFIED IDEOGRAPH
+0xE573	0x86B6	#CJK UNIFIED IDEOGRAPH
+0xE574	0x86AF	#CJK UNIFIED IDEOGRAPH
+0xE575	0x86C4	#CJK UNIFIED IDEOGRAPH
+0xE576	0x86C6	#CJK UNIFIED IDEOGRAPH
+0xE577	0x86B0	#CJK UNIFIED IDEOGRAPH
+0xE578	0x86C9	#CJK UNIFIED IDEOGRAPH
+0xE579	0x8823	#CJK UNIFIED IDEOGRAPH
+0xE57A	0x86AB	#CJK UNIFIED IDEOGRAPH
+0xE57B	0x86D4	#CJK UNIFIED IDEOGRAPH
+0xE57C	0x86DE	#CJK UNIFIED IDEOGRAPH
+0xE57D	0x86E9	#CJK UNIFIED IDEOGRAPH
+0xE57E	0x86EC	#CJK UNIFIED IDEOGRAPH
+0xE580	0x86DF	#CJK UNIFIED IDEOGRAPH
+0xE581	0x86DB	#CJK UNIFIED IDEOGRAPH
+0xE582	0x86EF	#CJK UNIFIED IDEOGRAPH
+0xE583	0x8712	#CJK UNIFIED IDEOGRAPH
+0xE584	0x8706	#CJK UNIFIED IDEOGRAPH
+0xE585	0x8708	#CJK UNIFIED IDEOGRAPH
+0xE586	0x8700	#CJK UNIFIED IDEOGRAPH
+0xE587	0x8703	#CJK UNIFIED IDEOGRAPH
+0xE588	0x86FB	#CJK UNIFIED IDEOGRAPH
+0xE589	0x8711	#CJK UNIFIED IDEOGRAPH
+0xE58A	0x8709	#CJK UNIFIED IDEOGRAPH
+0xE58B	0x870D	#CJK UNIFIED IDEOGRAPH
+0xE58C	0x86F9	#CJK UNIFIED IDEOGRAPH
+0xE58D	0x870A	#CJK UNIFIED IDEOGRAPH
+0xE58E	0x8734	#CJK UNIFIED IDEOGRAPH
+0xE58F	0x873F	#CJK UNIFIED IDEOGRAPH
+0xE590	0x8737	#CJK UNIFIED IDEOGRAPH
+0xE591	0x873B	#CJK UNIFIED IDEOGRAPH
+0xE592	0x8725	#CJK UNIFIED IDEOGRAPH
+0xE593	0x8729	#CJK UNIFIED IDEOGRAPH
+0xE594	0x871A	#CJK UNIFIED IDEOGRAPH
+0xE595	0x8760	#CJK UNIFIED IDEOGRAPH
+0xE596	0x875F	#CJK UNIFIED IDEOGRAPH
+0xE597	0x8778	#CJK UNIFIED IDEOGRAPH
+0xE598	0x874C	#CJK UNIFIED IDEOGRAPH
+0xE599	0x874E	#CJK UNIFIED IDEOGRAPH
+0xE59A	0x8774	#CJK UNIFIED IDEOGRAPH
+0xE59B	0x8757	#CJK UNIFIED IDEOGRAPH
+0xE59C	0x8768	#CJK UNIFIED IDEOGRAPH
+0xE59D	0x876E	#CJK UNIFIED IDEOGRAPH
+0xE59E	0x8759	#CJK UNIFIED IDEOGRAPH
+0xE59F	0x8753	#CJK UNIFIED IDEOGRAPH
+0xE5A0	0x8763	#CJK UNIFIED IDEOGRAPH
+0xE5A1	0x876A	#CJK UNIFIED IDEOGRAPH
+0xE5A2	0x8805	#CJK UNIFIED IDEOGRAPH
+0xE5A3	0x87A2	#CJK UNIFIED IDEOGRAPH
+0xE5A4	0x879F	#CJK UNIFIED IDEOGRAPH
+0xE5A5	0x8782	#CJK UNIFIED IDEOGRAPH
+0xE5A6	0x87AF	#CJK UNIFIED IDEOGRAPH
+0xE5A7	0x87CB	#CJK UNIFIED IDEOGRAPH
+0xE5A8	0x87BD	#CJK UNIFIED IDEOGRAPH
+0xE5A9	0x87C0	#CJK UNIFIED IDEOGRAPH
+0xE5AA	0x87D0	#CJK UNIFIED IDEOGRAPH
+0xE5AB	0x96D6	#CJK UNIFIED IDEOGRAPH
+0xE5AC	0x87AB	#CJK UNIFIED IDEOGRAPH
+0xE5AD	0x87C4	#CJK UNIFIED IDEOGRAPH
+0xE5AE	0x87B3	#CJK UNIFIED IDEOGRAPH
+0xE5AF	0x87C7	#CJK UNIFIED IDEOGRAPH
+0xE5B0	0x87C6	#CJK UNIFIED IDEOGRAPH
+0xE5B1	0x87BB	#CJK UNIFIED IDEOGRAPH
+0xE5B2	0x87EF	#CJK UNIFIED IDEOGRAPH
+0xE5B3	0x87F2	#CJK UNIFIED IDEOGRAPH
+0xE5B4	0x87E0	#CJK UNIFIED IDEOGRAPH
+0xE5B5	0x880F	#CJK UNIFIED IDEOGRAPH
+0xE5B6	0x880D	#CJK UNIFIED IDEOGRAPH
+0xE5B7	0x87FE	#CJK UNIFIED IDEOGRAPH
+0xE5B8	0x87F6	#CJK UNIFIED IDEOGRAPH
+0xE5B9	0x87F7	#CJK UNIFIED IDEOGRAPH
+0xE5BA	0x880E	#CJK UNIFIED IDEOGRAPH
+0xE5BB	0x87D2	#CJK UNIFIED IDEOGRAPH
+0xE5BC	0x8811	#CJK UNIFIED IDEOGRAPH
+0xE5BD	0x8816	#CJK UNIFIED IDEOGRAPH
+0xE5BE	0x8815	#CJK UNIFIED IDEOGRAPH
+0xE5BF	0x8822	#CJK UNIFIED IDEOGRAPH
+0xE5C0	0x8821	#CJK UNIFIED IDEOGRAPH
+0xE5C1	0x8831	#CJK UNIFIED IDEOGRAPH
+0xE5C2	0x8836	#CJK UNIFIED IDEOGRAPH
+0xE5C3	0x8839	#CJK UNIFIED IDEOGRAPH
+0xE5C4	0x8827	#CJK UNIFIED IDEOGRAPH
+0xE5C5	0x883B	#CJK UNIFIED IDEOGRAPH
+0xE5C6	0x8844	#CJK UNIFIED IDEOGRAPH
+0xE5C7	0x8842	#CJK UNIFIED IDEOGRAPH
+0xE5C8	0x8852	#CJK UNIFIED IDEOGRAPH
+0xE5C9	0x8859	#CJK UNIFIED IDEOGRAPH
+0xE5CA	0x885E	#CJK UNIFIED IDEOGRAPH
+0xE5CB	0x8862	#CJK UNIFIED IDEOGRAPH
+0xE5CC	0x886B	#CJK UNIFIED IDEOGRAPH
+0xE5CD	0x8881	#CJK UNIFIED IDEOGRAPH
+0xE5CE	0x887E	#CJK UNIFIED IDEOGRAPH
+0xE5CF	0x889E	#CJK UNIFIED IDEOGRAPH
+0xE5D0	0x8875	#CJK UNIFIED IDEOGRAPH
+0xE5D1	0x887D	#CJK UNIFIED IDEOGRAPH
+0xE5D2	0x88B5	#CJK UNIFIED IDEOGRAPH
+0xE5D3	0x8872	#CJK UNIFIED IDEOGRAPH
+0xE5D4	0x8882	#CJK UNIFIED IDEOGRAPH
+0xE5D5	0x8897	#CJK UNIFIED IDEOGRAPH
+0xE5D6	0x8892	#CJK UNIFIED IDEOGRAPH
+0xE5D7	0x88AE	#CJK UNIFIED IDEOGRAPH
+0xE5D8	0x8899	#CJK UNIFIED IDEOGRAPH
+0xE5D9	0x88A2	#CJK UNIFIED IDEOGRAPH
+0xE5DA	0x888D	#CJK UNIFIED IDEOGRAPH
+0xE5DB	0x88A4	#CJK UNIFIED IDEOGRAPH
+0xE5DC	0x88B0	#CJK UNIFIED IDEOGRAPH
+0xE5DD	0x88BF	#CJK UNIFIED IDEOGRAPH
+0xE5DE	0x88B1	#CJK UNIFIED IDEOGRAPH
+0xE5DF	0x88C3	#CJK UNIFIED IDEOGRAPH
+0xE5E0	0x88C4	#CJK UNIFIED IDEOGRAPH
+0xE5E1	0x88D4	#CJK UNIFIED IDEOGRAPH
+0xE5E2	0x88D8	#CJK UNIFIED IDEOGRAPH
+0xE5E3	0x88D9	#CJK UNIFIED IDEOGRAPH
+0xE5E4	0x88DD	#CJK UNIFIED IDEOGRAPH
+0xE5E5	0x88F9	#CJK UNIFIED IDEOGRAPH
+0xE5E6	0x8902	#CJK UNIFIED IDEOGRAPH
+0xE5E7	0x88FC	#CJK UNIFIED IDEOGRAPH
+0xE5E8	0x88F4	#CJK UNIFIED IDEOGRAPH
+0xE5E9	0x88E8	#CJK UNIFIED IDEOGRAPH
+0xE5EA	0x88F2	#CJK UNIFIED IDEOGRAPH
+0xE5EB	0x8904	#CJK UNIFIED IDEOGRAPH
+0xE5EC	0x890C	#CJK UNIFIED IDEOGRAPH
+0xE5ED	0x890A	#CJK UNIFIED IDEOGRAPH
+0xE5EE	0x8913	#CJK UNIFIED IDEOGRAPH
+0xE5EF	0x8943	#CJK UNIFIED IDEOGRAPH
+0xE5F0	0x891E	#CJK UNIFIED IDEOGRAPH
+0xE5F1	0x8925	#CJK UNIFIED IDEOGRAPH
+0xE5F2	0x892A	#CJK UNIFIED IDEOGRAPH
+0xE5F3	0x892B	#CJK UNIFIED IDEOGRAPH
+0xE5F4	0x8941	#CJK UNIFIED IDEOGRAPH
+0xE5F5	0x8944	#CJK UNIFIED IDEOGRAPH
+0xE5F6	0x893B	#CJK UNIFIED IDEOGRAPH
+0xE5F7	0x8936	#CJK UNIFIED IDEOGRAPH
+0xE5F8	0x8938	#CJK UNIFIED IDEOGRAPH
+0xE5F9	0x894C	#CJK UNIFIED IDEOGRAPH
+0xE5FA	0x891D	#CJK UNIFIED IDEOGRAPH
+0xE5FB	0x8960	#CJK UNIFIED IDEOGRAPH
+0xE5FC	0x895E	#CJK UNIFIED IDEOGRAPH
+0xE640	0x8966	#CJK UNIFIED IDEOGRAPH
+0xE641	0x8964	#CJK UNIFIED IDEOGRAPH
+0xE642	0x896D	#CJK UNIFIED IDEOGRAPH
+0xE643	0x896A	#CJK UNIFIED IDEOGRAPH
+0xE644	0x896F	#CJK UNIFIED IDEOGRAPH
+0xE645	0x8974	#CJK UNIFIED IDEOGRAPH
+0xE646	0x8977	#CJK UNIFIED IDEOGRAPH
+0xE647	0x897E	#CJK UNIFIED IDEOGRAPH
+0xE648	0x8983	#CJK UNIFIED IDEOGRAPH
+0xE649	0x8988	#CJK UNIFIED IDEOGRAPH
+0xE64A	0x898A	#CJK UNIFIED IDEOGRAPH
+0xE64B	0x8993	#CJK UNIFIED IDEOGRAPH
+0xE64C	0x8998	#CJK UNIFIED IDEOGRAPH
+0xE64D	0x89A1	#CJK UNIFIED IDEOGRAPH
+0xE64E	0x89A9	#CJK UNIFIED IDEOGRAPH
+0xE64F	0x89A6	#CJK UNIFIED IDEOGRAPH
+0xE650	0x89AC	#CJK UNIFIED IDEOGRAPH
+0xE651	0x89AF	#CJK UNIFIED IDEOGRAPH
+0xE652	0x89B2	#CJK UNIFIED IDEOGRAPH
+0xE653	0x89BA	#CJK UNIFIED IDEOGRAPH
+0xE654	0x89BD	#CJK UNIFIED IDEOGRAPH
+0xE655	0x89BF	#CJK UNIFIED IDEOGRAPH
+0xE656	0x89C0	#CJK UNIFIED IDEOGRAPH
+0xE657	0x89DA	#CJK UNIFIED IDEOGRAPH
+0xE658	0x89DC	#CJK UNIFIED IDEOGRAPH
+0xE659	0x89DD	#CJK UNIFIED IDEOGRAPH
+0xE65A	0x89E7	#CJK UNIFIED IDEOGRAPH
+0xE65B	0x89F4	#CJK UNIFIED IDEOGRAPH
+0xE65C	0x89F8	#CJK UNIFIED IDEOGRAPH
+0xE65D	0x8A03	#CJK UNIFIED IDEOGRAPH
+0xE65E	0x8A16	#CJK UNIFIED IDEOGRAPH
+0xE65F	0x8A10	#CJK UNIFIED IDEOGRAPH
+0xE660	0x8A0C	#CJK UNIFIED IDEOGRAPH
+0xE661	0x8A1B	#CJK UNIFIED IDEOGRAPH
+0xE662	0x8A1D	#CJK UNIFIED IDEOGRAPH
+0xE663	0x8A25	#CJK UNIFIED IDEOGRAPH
+0xE664	0x8A36	#CJK UNIFIED IDEOGRAPH
+0xE665	0x8A41	#CJK UNIFIED IDEOGRAPH
+0xE666	0x8A5B	#CJK UNIFIED IDEOGRAPH
+0xE667	0x8A52	#CJK UNIFIED IDEOGRAPH
+0xE668	0x8A46	#CJK UNIFIED IDEOGRAPH
+0xE669	0x8A48	#CJK UNIFIED IDEOGRAPH
+0xE66A	0x8A7C	#CJK UNIFIED IDEOGRAPH
+0xE66B	0x8A6D	#CJK UNIFIED IDEOGRAPH
+0xE66C	0x8A6C	#CJK UNIFIED IDEOGRAPH
+0xE66D	0x8A62	#CJK UNIFIED IDEOGRAPH
+0xE66E	0x8A85	#CJK UNIFIED IDEOGRAPH
+0xE66F	0x8A82	#CJK UNIFIED IDEOGRAPH
+0xE670	0x8A84	#CJK UNIFIED IDEOGRAPH
+0xE671	0x8AA8	#CJK UNIFIED IDEOGRAPH
+0xE672	0x8AA1	#CJK UNIFIED IDEOGRAPH
+0xE673	0x8A91	#CJK UNIFIED IDEOGRAPH
+0xE674	0x8AA5	#CJK UNIFIED IDEOGRAPH
+0xE675	0x8AA6	#CJK UNIFIED IDEOGRAPH
+0xE676	0x8A9A	#CJK UNIFIED IDEOGRAPH
+0xE677	0x8AA3	#CJK UNIFIED IDEOGRAPH
+0xE678	0x8AC4	#CJK UNIFIED IDEOGRAPH
+0xE679	0x8ACD	#CJK UNIFIED IDEOGRAPH
+0xE67A	0x8AC2	#CJK UNIFIED IDEOGRAPH
+0xE67B	0x8ADA	#CJK UNIFIED IDEOGRAPH
+0xE67C	0x8AEB	#CJK UNIFIED IDEOGRAPH
+0xE67D	0x8AF3	#CJK UNIFIED IDEOGRAPH
+0xE67E	0x8AE7	#CJK UNIFIED IDEOGRAPH
+0xE680	0x8AE4	#CJK UNIFIED IDEOGRAPH
+0xE681	0x8AF1	#CJK UNIFIED IDEOGRAPH
+0xE682	0x8B14	#CJK UNIFIED IDEOGRAPH
+0xE683	0x8AE0	#CJK UNIFIED IDEOGRAPH
+0xE684	0x8AE2	#CJK UNIFIED IDEOGRAPH
+0xE685	0x8AF7	#CJK UNIFIED IDEOGRAPH
+0xE686	0x8ADE	#CJK UNIFIED IDEOGRAPH
+0xE687	0x8ADB	#CJK UNIFIED IDEOGRAPH
+0xE688	0x8B0C	#CJK UNIFIED IDEOGRAPH
+0xE689	0x8B07	#CJK UNIFIED IDEOGRAPH
+0xE68A	0x8B1A	#CJK UNIFIED IDEOGRAPH
+0xE68B	0x8AE1	#CJK UNIFIED IDEOGRAPH
+0xE68C	0x8B16	#CJK UNIFIED IDEOGRAPH
+0xE68D	0x8B10	#CJK UNIFIED IDEOGRAPH
+0xE68E	0x8B17	#CJK UNIFIED IDEOGRAPH
+0xE68F	0x8B20	#CJK UNIFIED IDEOGRAPH
+0xE690	0x8B33	#CJK UNIFIED IDEOGRAPH
+0xE691	0x97AB	#CJK UNIFIED IDEOGRAPH
+0xE692	0x8B26	#CJK UNIFIED IDEOGRAPH
+0xE693	0x8B2B	#CJK UNIFIED IDEOGRAPH
+0xE694	0x8B3E	#CJK UNIFIED IDEOGRAPH
+0xE695	0x8B28	#CJK UNIFIED IDEOGRAPH
+0xE696	0x8B41	#CJK UNIFIED IDEOGRAPH
+0xE697	0x8B4C	#CJK UNIFIED IDEOGRAPH
+0xE698	0x8B4F	#CJK UNIFIED IDEOGRAPH
+0xE699	0x8B4E	#CJK UNIFIED IDEOGRAPH
+0xE69A	0x8B49	#CJK UNIFIED IDEOGRAPH
+0xE69B	0x8B56	#CJK UNIFIED IDEOGRAPH
+0xE69C	0x8B5B	#CJK UNIFIED IDEOGRAPH
+0xE69D	0x8B5A	#CJK UNIFIED IDEOGRAPH
+0xE69E	0x8B6B	#CJK UNIFIED IDEOGRAPH
+0xE69F	0x8B5F	#CJK UNIFIED IDEOGRAPH
+0xE6A0	0x8B6C	#CJK UNIFIED IDEOGRAPH
+0xE6A1	0x8B6F	#CJK UNIFIED IDEOGRAPH
+0xE6A2	0x8B74	#CJK UNIFIED IDEOGRAPH
+0xE6A3	0x8B7D	#CJK UNIFIED IDEOGRAPH
+0xE6A4	0x8B80	#CJK UNIFIED IDEOGRAPH
+0xE6A5	0x8B8C	#CJK UNIFIED IDEOGRAPH
+0xE6A6	0x8B8E	#CJK UNIFIED IDEOGRAPH
+0xE6A7	0x8B92	#CJK UNIFIED IDEOGRAPH
+0xE6A8	0x8B93	#CJK UNIFIED IDEOGRAPH
+0xE6A9	0x8B96	#CJK UNIFIED IDEOGRAPH
+0xE6AA	0x8B99	#CJK UNIFIED IDEOGRAPH
+0xE6AB	0x8B9A	#CJK UNIFIED IDEOGRAPH
+0xE6AC	0x8C3A	#CJK UNIFIED IDEOGRAPH
+0xE6AD	0x8C41	#CJK UNIFIED IDEOGRAPH
+0xE6AE	0x8C3F	#CJK UNIFIED IDEOGRAPH
+0xE6AF	0x8C48	#CJK UNIFIED IDEOGRAPH
+0xE6B0	0x8C4C	#CJK UNIFIED IDEOGRAPH
+0xE6B1	0x8C4E	#CJK UNIFIED IDEOGRAPH
+0xE6B2	0x8C50	#CJK UNIFIED IDEOGRAPH
+0xE6B3	0x8C55	#CJK UNIFIED IDEOGRAPH
+0xE6B4	0x8C62	#CJK UNIFIED IDEOGRAPH
+0xE6B5	0x8C6C	#CJK UNIFIED IDEOGRAPH
+0xE6B6	0x8C78	#CJK UNIFIED IDEOGRAPH
+0xE6B7	0x8C7A	#CJK UNIFIED IDEOGRAPH
+0xE6B8	0x8C82	#CJK UNIFIED IDEOGRAPH
+0xE6B9	0x8C89	#CJK UNIFIED IDEOGRAPH
+0xE6BA	0x8C85	#CJK UNIFIED IDEOGRAPH
+0xE6BB	0x8C8A	#CJK UNIFIED IDEOGRAPH
+0xE6BC	0x8C8D	#CJK UNIFIED IDEOGRAPH
+0xE6BD	0x8C8E	#CJK UNIFIED IDEOGRAPH
+0xE6BE	0x8C94	#CJK UNIFIED IDEOGRAPH
+0xE6BF	0x8C7C	#CJK UNIFIED IDEOGRAPH
+0xE6C0	0x8C98	#CJK UNIFIED IDEOGRAPH
+0xE6C1	0x621D	#CJK UNIFIED IDEOGRAPH
+0xE6C2	0x8CAD	#CJK UNIFIED IDEOGRAPH
+0xE6C3	0x8CAA	#CJK UNIFIED IDEOGRAPH
+0xE6C4	0x8CBD	#CJK UNIFIED IDEOGRAPH
+0xE6C5	0x8CB2	#CJK UNIFIED IDEOGRAPH
+0xE6C6	0x8CB3	#CJK UNIFIED IDEOGRAPH
+0xE6C7	0x8CAE	#CJK UNIFIED IDEOGRAPH
+0xE6C8	0x8CB6	#CJK UNIFIED IDEOGRAPH
+0xE6C9	0x8CC8	#CJK UNIFIED IDEOGRAPH
+0xE6CA	0x8CC1	#CJK UNIFIED IDEOGRAPH
+0xE6CB	0x8CE4	#CJK UNIFIED IDEOGRAPH
+0xE6CC	0x8CE3	#CJK UNIFIED IDEOGRAPH
+0xE6CD	0x8CDA	#CJK UNIFIED IDEOGRAPH
+0xE6CE	0x8CFD	#CJK UNIFIED IDEOGRAPH
+0xE6CF	0x8CFA	#CJK UNIFIED IDEOGRAPH
+0xE6D0	0x8CFB	#CJK UNIFIED IDEOGRAPH
+0xE6D1	0x8D04	#CJK UNIFIED IDEOGRAPH
+0xE6D2	0x8D05	#CJK UNIFIED IDEOGRAPH
+0xE6D3	0x8D0A	#CJK UNIFIED IDEOGRAPH
+0xE6D4	0x8D07	#CJK UNIFIED IDEOGRAPH
+0xE6D5	0x8D0F	#CJK UNIFIED IDEOGRAPH
+0xE6D6	0x8D0D	#CJK UNIFIED IDEOGRAPH
+0xE6D7	0x8D10	#CJK UNIFIED IDEOGRAPH
+0xE6D8	0x9F4E	#CJK UNIFIED IDEOGRAPH
+0xE6D9	0x8D13	#CJK UNIFIED IDEOGRAPH
+0xE6DA	0x8CCD	#CJK UNIFIED IDEOGRAPH
+0xE6DB	0x8D14	#CJK UNIFIED IDEOGRAPH
+0xE6DC	0x8D16	#CJK UNIFIED IDEOGRAPH
+0xE6DD	0x8D67	#CJK UNIFIED IDEOGRAPH
+0xE6DE	0x8D6D	#CJK UNIFIED IDEOGRAPH
+0xE6DF	0x8D71	#CJK UNIFIED IDEOGRAPH
+0xE6E0	0x8D73	#CJK UNIFIED IDEOGRAPH
+0xE6E1	0x8D81	#CJK UNIFIED IDEOGRAPH
+0xE6E2	0x8D99	#CJK UNIFIED IDEOGRAPH
+0xE6E3	0x8DC2	#CJK UNIFIED IDEOGRAPH
+0xE6E4	0x8DBE	#CJK UNIFIED IDEOGRAPH
+0xE6E5	0x8DBA	#CJK UNIFIED IDEOGRAPH
+0xE6E6	0x8DCF	#CJK UNIFIED IDEOGRAPH
+0xE6E7	0x8DDA	#CJK UNIFIED IDEOGRAPH
+0xE6E8	0x8DD6	#CJK UNIFIED IDEOGRAPH
+0xE6E9	0x8DCC	#CJK UNIFIED IDEOGRAPH
+0xE6EA	0x8DDB	#CJK UNIFIED IDEOGRAPH
+0xE6EB	0x8DCB	#CJK UNIFIED IDEOGRAPH
+0xE6EC	0x8DEA	#CJK UNIFIED IDEOGRAPH
+0xE6ED	0x8DEB	#CJK UNIFIED IDEOGRAPH
+0xE6EE	0x8DDF	#CJK UNIFIED IDEOGRAPH
+0xE6EF	0x8DE3	#CJK UNIFIED IDEOGRAPH
+0xE6F0	0x8DFC	#CJK UNIFIED IDEOGRAPH
+0xE6F1	0x8E08	#CJK UNIFIED IDEOGRAPH
+0xE6F2	0x8E09	#CJK UNIFIED IDEOGRAPH
+0xE6F3	0x8DFF	#CJK UNIFIED IDEOGRAPH
+0xE6F4	0x8E1D	#CJK UNIFIED IDEOGRAPH
+0xE6F5	0x8E1E	#CJK UNIFIED IDEOGRAPH
+0xE6F6	0x8E10	#CJK UNIFIED IDEOGRAPH
+0xE6F7	0x8E1F	#CJK UNIFIED IDEOGRAPH
+0xE6F8	0x8E42	#CJK UNIFIED IDEOGRAPH
+0xE6F9	0x8E35	#CJK UNIFIED IDEOGRAPH
+0xE6FA	0x8E30	#CJK UNIFIED IDEOGRAPH
+0xE6FB	0x8E34	#CJK UNIFIED IDEOGRAPH
+0xE6FC	0x8E4A	#CJK UNIFIED IDEOGRAPH
+0xE740	0x8E47	#CJK UNIFIED IDEOGRAPH
+0xE741	0x8E49	#CJK UNIFIED IDEOGRAPH
+0xE742	0x8E4C	#CJK UNIFIED IDEOGRAPH
+0xE743	0x8E50	#CJK UNIFIED IDEOGRAPH
+0xE744	0x8E48	#CJK UNIFIED IDEOGRAPH
+0xE745	0x8E59	#CJK UNIFIED IDEOGRAPH
+0xE746	0x8E64	#CJK UNIFIED IDEOGRAPH
+0xE747	0x8E60	#CJK UNIFIED IDEOGRAPH
+0xE748	0x8E2A	#CJK UNIFIED IDEOGRAPH
+0xE749	0x8E63	#CJK UNIFIED IDEOGRAPH
+0xE74A	0x8E55	#CJK UNIFIED IDEOGRAPH
+0xE74B	0x8E76	#CJK UNIFIED IDEOGRAPH
+0xE74C	0x8E72	#CJK UNIFIED IDEOGRAPH
+0xE74D	0x8E7C	#CJK UNIFIED IDEOGRAPH
+0xE74E	0x8E81	#CJK UNIFIED IDEOGRAPH
+0xE74F	0x8E87	#CJK UNIFIED IDEOGRAPH
+0xE750	0x8E85	#CJK UNIFIED IDEOGRAPH
+0xE751	0x8E84	#CJK UNIFIED IDEOGRAPH
+0xE752	0x8E8B	#CJK UNIFIED IDEOGRAPH
+0xE753	0x8E8A	#CJK UNIFIED IDEOGRAPH
+0xE754	0x8E93	#CJK UNIFIED IDEOGRAPH
+0xE755	0x8E91	#CJK UNIFIED IDEOGRAPH
+0xE756	0x8E94	#CJK UNIFIED IDEOGRAPH
+0xE757	0x8E99	#CJK UNIFIED IDEOGRAPH
+0xE758	0x8EAA	#CJK UNIFIED IDEOGRAPH
+0xE759	0x8EA1	#CJK UNIFIED IDEOGRAPH
+0xE75A	0x8EAC	#CJK UNIFIED IDEOGRAPH
+0xE75B	0x8EB0	#CJK UNIFIED IDEOGRAPH
+0xE75C	0x8EC6	#CJK UNIFIED IDEOGRAPH
+0xE75D	0x8EB1	#CJK UNIFIED IDEOGRAPH
+0xE75E	0x8EBE	#CJK UNIFIED IDEOGRAPH
+0xE75F	0x8EC5	#CJK UNIFIED IDEOGRAPH
+0xE760	0x8EC8	#CJK UNIFIED IDEOGRAPH
+0xE761	0x8ECB	#CJK UNIFIED IDEOGRAPH
+0xE762	0x8EDB	#CJK UNIFIED IDEOGRAPH
+0xE763	0x8EE3	#CJK UNIFIED IDEOGRAPH
+0xE764	0x8EFC	#CJK UNIFIED IDEOGRAPH
+0xE765	0x8EFB	#CJK UNIFIED IDEOGRAPH
+0xE766	0x8EEB	#CJK UNIFIED IDEOGRAPH
+0xE767	0x8EFE	#CJK UNIFIED IDEOGRAPH
+0xE768	0x8F0A	#CJK UNIFIED IDEOGRAPH
+0xE769	0x8F05	#CJK UNIFIED IDEOGRAPH
+0xE76A	0x8F15	#CJK UNIFIED IDEOGRAPH
+0xE76B	0x8F12	#CJK UNIFIED IDEOGRAPH
+0xE76C	0x8F19	#CJK UNIFIED IDEOGRAPH
+0xE76D	0x8F13	#CJK UNIFIED IDEOGRAPH
+0xE76E	0x8F1C	#CJK UNIFIED IDEOGRAPH
+0xE76F	0x8F1F	#CJK UNIFIED IDEOGRAPH
+0xE770	0x8F1B	#CJK UNIFIED IDEOGRAPH
+0xE771	0x8F0C	#CJK UNIFIED IDEOGRAPH
+0xE772	0x8F26	#CJK UNIFIED IDEOGRAPH
+0xE773	0x8F33	#CJK UNIFIED IDEOGRAPH
+0xE774	0x8F3B	#CJK UNIFIED IDEOGRAPH
+0xE775	0x8F39	#CJK UNIFIED IDEOGRAPH
+0xE776	0x8F45	#CJK UNIFIED IDEOGRAPH
+0xE777	0x8F42	#CJK UNIFIED IDEOGRAPH
+0xE778	0x8F3E	#CJK UNIFIED IDEOGRAPH
+0xE779	0x8F4C	#CJK UNIFIED IDEOGRAPH
+0xE77A	0x8F49	#CJK UNIFIED IDEOGRAPH
+0xE77B	0x8F46	#CJK UNIFIED IDEOGRAPH
+0xE77C	0x8F4E	#CJK UNIFIED IDEOGRAPH
+0xE77D	0x8F57	#CJK UNIFIED IDEOGRAPH
+0xE77E	0x8F5C	#CJK UNIFIED IDEOGRAPH
+0xE780	0x8F62	#CJK UNIFIED IDEOGRAPH
+0xE781	0x8F63	#CJK UNIFIED IDEOGRAPH
+0xE782	0x8F64	#CJK UNIFIED IDEOGRAPH
+0xE783	0x8F9C	#CJK UNIFIED IDEOGRAPH
+0xE784	0x8F9F	#CJK UNIFIED IDEOGRAPH
+0xE785	0x8FA3	#CJK UNIFIED IDEOGRAPH
+0xE786	0x8FAD	#CJK UNIFIED IDEOGRAPH
+0xE787	0x8FAF	#CJK UNIFIED IDEOGRAPH
+0xE788	0x8FB7	#CJK UNIFIED IDEOGRAPH
+0xE789	0x8FDA	#CJK UNIFIED IDEOGRAPH
+0xE78A	0x8FE5	#CJK UNIFIED IDEOGRAPH
+0xE78B	0x8FE2	#CJK UNIFIED IDEOGRAPH
+0xE78C	0x8FEA	#CJK UNIFIED IDEOGRAPH
+0xE78D	0x8FEF	#CJK UNIFIED IDEOGRAPH
+0xE78E	0x9087	#CJK UNIFIED IDEOGRAPH
+0xE78F	0x8FF4	#CJK UNIFIED IDEOGRAPH
+0xE790	0x9005	#CJK UNIFIED IDEOGRAPH
+0xE791	0x8FF9	#CJK UNIFIED IDEOGRAPH
+0xE792	0x8FFA	#CJK UNIFIED IDEOGRAPH
+0xE793	0x9011	#CJK UNIFIED IDEOGRAPH
+0xE794	0x9015	#CJK UNIFIED IDEOGRAPH
+0xE795	0x9021	#CJK UNIFIED IDEOGRAPH
+0xE796	0x900D	#CJK UNIFIED IDEOGRAPH
+0xE797	0x901E	#CJK UNIFIED IDEOGRAPH
+0xE798	0x9016	#CJK UNIFIED IDEOGRAPH
+0xE799	0x900B	#CJK UNIFIED IDEOGRAPH
+0xE79A	0x9027	#CJK UNIFIED IDEOGRAPH
+0xE79B	0x9036	#CJK UNIFIED IDEOGRAPH
+0xE79C	0x9035	#CJK UNIFIED IDEOGRAPH
+0xE79D	0x9039	#CJK UNIFIED IDEOGRAPH
+0xE79E	0x8FF8	#CJK UNIFIED IDEOGRAPH
+0xE79F	0x904F	#CJK UNIFIED IDEOGRAPH
+0xE7A0	0x9050	#CJK UNIFIED IDEOGRAPH
+0xE7A1	0x9051	#CJK UNIFIED IDEOGRAPH
+0xE7A2	0x9052	#CJK UNIFIED IDEOGRAPH
+0xE7A3	0x900E	#CJK UNIFIED IDEOGRAPH
+0xE7A4	0x9049	#CJK UNIFIED IDEOGRAPH
+0xE7A5	0x903E	#CJK UNIFIED IDEOGRAPH
+0xE7A6	0x9056	#CJK UNIFIED IDEOGRAPH
+0xE7A7	0x9058	#CJK UNIFIED IDEOGRAPH
+0xE7A8	0x905E	#CJK UNIFIED IDEOGRAPH
+0xE7A9	0x9068	#CJK UNIFIED IDEOGRAPH
+0xE7AA	0x906F	#CJK UNIFIED IDEOGRAPH
+0xE7AB	0x9076	#CJK UNIFIED IDEOGRAPH
+0xE7AC	0x96A8	#CJK UNIFIED IDEOGRAPH
+0xE7AD	0x9072	#CJK UNIFIED IDEOGRAPH
+0xE7AE	0x9082	#CJK UNIFIED IDEOGRAPH
+0xE7AF	0x907D	#CJK UNIFIED IDEOGRAPH
+0xE7B0	0x9081	#CJK UNIFIED IDEOGRAPH
+0xE7B1	0x9080	#CJK UNIFIED IDEOGRAPH
+0xE7B2	0x908A	#CJK UNIFIED IDEOGRAPH
+0xE7B3	0x9089	#CJK UNIFIED IDEOGRAPH
+0xE7B4	0x908F	#CJK UNIFIED IDEOGRAPH
+0xE7B5	0x90A8	#CJK UNIFIED IDEOGRAPH
+0xE7B6	0x90AF	#CJK UNIFIED IDEOGRAPH
+0xE7B7	0x90B1	#CJK UNIFIED IDEOGRAPH
+0xE7B8	0x90B5	#CJK UNIFIED IDEOGRAPH
+0xE7B9	0x90E2	#CJK UNIFIED IDEOGRAPH
+0xE7BA	0x90E4	#CJK UNIFIED IDEOGRAPH
+0xE7BB	0x6248	#CJK UNIFIED IDEOGRAPH
+0xE7BC	0x90DB	#CJK UNIFIED IDEOGRAPH
+0xE7BD	0x9102	#CJK UNIFIED IDEOGRAPH
+0xE7BE	0x9112	#CJK UNIFIED IDEOGRAPH
+0xE7BF	0x9119	#CJK UNIFIED IDEOGRAPH
+0xE7C0	0x9132	#CJK UNIFIED IDEOGRAPH
+0xE7C1	0x9130	#CJK UNIFIED IDEOGRAPH
+0xE7C2	0x914A	#CJK UNIFIED IDEOGRAPH
+0xE7C3	0x9156	#CJK UNIFIED IDEOGRAPH
+0xE7C4	0x9158	#CJK UNIFIED IDEOGRAPH
+0xE7C5	0x9163	#CJK UNIFIED IDEOGRAPH
+0xE7C6	0x9165	#CJK UNIFIED IDEOGRAPH
+0xE7C7	0x9169	#CJK UNIFIED IDEOGRAPH
+0xE7C8	0x9173	#CJK UNIFIED IDEOGRAPH
+0xE7C9	0x9172	#CJK UNIFIED IDEOGRAPH
+0xE7CA	0x918B	#CJK UNIFIED IDEOGRAPH
+0xE7CB	0x9189	#CJK UNIFIED IDEOGRAPH
+0xE7CC	0x9182	#CJK UNIFIED IDEOGRAPH
+0xE7CD	0x91A2	#CJK UNIFIED IDEOGRAPH
+0xE7CE	0x91AB	#CJK UNIFIED IDEOGRAPH
+0xE7CF	0x91AF	#CJK UNIFIED IDEOGRAPH
+0xE7D0	0x91AA	#CJK UNIFIED IDEOGRAPH
+0xE7D1	0x91B5	#CJK UNIFIED IDEOGRAPH
+0xE7D2	0x91B4	#CJK UNIFIED IDEOGRAPH
+0xE7D3	0x91BA	#CJK UNIFIED IDEOGRAPH
+0xE7D4	0x91C0	#CJK UNIFIED IDEOGRAPH
+0xE7D5	0x91C1	#CJK UNIFIED IDEOGRAPH
+0xE7D6	0x91C9	#CJK UNIFIED IDEOGRAPH
+0xE7D7	0x91CB	#CJK UNIFIED IDEOGRAPH
+0xE7D8	0x91D0	#CJK UNIFIED IDEOGRAPH
+0xE7D9	0x91D6	#CJK UNIFIED IDEOGRAPH
+0xE7DA	0x91DF	#CJK UNIFIED IDEOGRAPH
+0xE7DB	0x91E1	#CJK UNIFIED IDEOGRAPH
+0xE7DC	0x91DB	#CJK UNIFIED IDEOGRAPH
+0xE7DD	0x91FC	#CJK UNIFIED IDEOGRAPH
+0xE7DE	0x91F5	#CJK UNIFIED IDEOGRAPH
+0xE7DF	0x91F6	#CJK UNIFIED IDEOGRAPH
+0xE7E0	0x921E	#CJK UNIFIED IDEOGRAPH
+0xE7E1	0x91FF	#CJK UNIFIED IDEOGRAPH
+0xE7E2	0x9214	#CJK UNIFIED IDEOGRAPH
+0xE7E3	0x922C	#CJK UNIFIED IDEOGRAPH
+0xE7E4	0x9215	#CJK UNIFIED IDEOGRAPH
+0xE7E5	0x9211	#CJK UNIFIED IDEOGRAPH
+0xE7E6	0x925E	#CJK UNIFIED IDEOGRAPH
+0xE7E7	0x9257	#CJK UNIFIED IDEOGRAPH
+0xE7E8	0x9245	#CJK UNIFIED IDEOGRAPH
+0xE7E9	0x9249	#CJK UNIFIED IDEOGRAPH
+0xE7EA	0x9264	#CJK UNIFIED IDEOGRAPH
+0xE7EB	0x9248	#CJK UNIFIED IDEOGRAPH
+0xE7EC	0x9295	#CJK UNIFIED IDEOGRAPH
+0xE7ED	0x923F	#CJK UNIFIED IDEOGRAPH
+0xE7EE	0x924B	#CJK UNIFIED IDEOGRAPH
+0xE7EF	0x9250	#CJK UNIFIED IDEOGRAPH
+0xE7F0	0x929C	#CJK UNIFIED IDEOGRAPH
+0xE7F1	0x9296	#CJK UNIFIED IDEOGRAPH
+0xE7F2	0x9293	#CJK UNIFIED IDEOGRAPH
+0xE7F3	0x929B	#CJK UNIFIED IDEOGRAPH
+0xE7F4	0x925A	#CJK UNIFIED IDEOGRAPH
+0xE7F5	0x92CF	#CJK UNIFIED IDEOGRAPH
+0xE7F6	0x92B9	#CJK UNIFIED IDEOGRAPH
+0xE7F7	0x92B7	#CJK UNIFIED IDEOGRAPH
+0xE7F8	0x92E9	#CJK UNIFIED IDEOGRAPH
+0xE7F9	0x930F	#CJK UNIFIED IDEOGRAPH
+0xE7FA	0x92FA	#CJK UNIFIED IDEOGRAPH
+0xE7FB	0x9344	#CJK UNIFIED IDEOGRAPH
+0xE7FC	0x932E	#CJK UNIFIED IDEOGRAPH
+0xE840	0x9319	#CJK UNIFIED IDEOGRAPH
+0xE841	0x9322	#CJK UNIFIED IDEOGRAPH
+0xE842	0x931A	#CJK UNIFIED IDEOGRAPH
+0xE843	0x9323	#CJK UNIFIED IDEOGRAPH
+0xE844	0x933A	#CJK UNIFIED IDEOGRAPH
+0xE845	0x9335	#CJK UNIFIED IDEOGRAPH
+0xE846	0x933B	#CJK UNIFIED IDEOGRAPH
+0xE847	0x935C	#CJK UNIFIED IDEOGRAPH
+0xE848	0x9360	#CJK UNIFIED IDEOGRAPH
+0xE849	0x937C	#CJK UNIFIED IDEOGRAPH
+0xE84A	0x936E	#CJK UNIFIED IDEOGRAPH
+0xE84B	0x9356	#CJK UNIFIED IDEOGRAPH
+0xE84C	0x93B0	#CJK UNIFIED IDEOGRAPH
+0xE84D	0x93AC	#CJK UNIFIED IDEOGRAPH
+0xE84E	0x93AD	#CJK UNIFIED IDEOGRAPH
+0xE84F	0x9394	#CJK UNIFIED IDEOGRAPH
+0xE850	0x93B9	#CJK UNIFIED IDEOGRAPH
+0xE851	0x93D6	#CJK UNIFIED IDEOGRAPH
+0xE852	0x93D7	#CJK UNIFIED IDEOGRAPH
+0xE853	0x93E8	#CJK UNIFIED IDEOGRAPH
+0xE854	0x93E5	#CJK UNIFIED IDEOGRAPH
+0xE855	0x93D8	#CJK UNIFIED IDEOGRAPH
+0xE856	0x93C3	#CJK UNIFIED IDEOGRAPH
+0xE857	0x93DD	#CJK UNIFIED IDEOGRAPH
+0xE858	0x93D0	#CJK UNIFIED IDEOGRAPH
+0xE859	0x93C8	#CJK UNIFIED IDEOGRAPH
+0xE85A	0x93E4	#CJK UNIFIED IDEOGRAPH
+0xE85B	0x941A	#CJK UNIFIED IDEOGRAPH
+0xE85C	0x9414	#CJK UNIFIED IDEOGRAPH
+0xE85D	0x9413	#CJK UNIFIED IDEOGRAPH
+0xE85E	0x9403	#CJK UNIFIED IDEOGRAPH
+0xE85F	0x9407	#CJK UNIFIED IDEOGRAPH
+0xE860	0x9410	#CJK UNIFIED IDEOGRAPH
+0xE861	0x9436	#CJK UNIFIED IDEOGRAPH
+0xE862	0x942B	#CJK UNIFIED IDEOGRAPH
+0xE863	0x9435	#CJK UNIFIED IDEOGRAPH
+0xE864	0x9421	#CJK UNIFIED IDEOGRAPH
+0xE865	0x943A	#CJK UNIFIED IDEOGRAPH
+0xE866	0x9441	#CJK UNIFIED IDEOGRAPH
+0xE867	0x9452	#CJK UNIFIED IDEOGRAPH
+0xE868	0x9444	#CJK UNIFIED IDEOGRAPH
+0xE869	0x945B	#CJK UNIFIED IDEOGRAPH
+0xE86A	0x9460	#CJK UNIFIED IDEOGRAPH
+0xE86B	0x9462	#CJK UNIFIED IDEOGRAPH
+0xE86C	0x945E	#CJK UNIFIED IDEOGRAPH
+0xE86D	0x946A	#CJK UNIFIED IDEOGRAPH
+0xE86E	0x9229	#CJK UNIFIED IDEOGRAPH
+0xE86F	0x9470	#CJK UNIFIED IDEOGRAPH
+0xE870	0x9475	#CJK UNIFIED IDEOGRAPH
+0xE871	0x9477	#CJK UNIFIED IDEOGRAPH
+0xE872	0x947D	#CJK UNIFIED IDEOGRAPH
+0xE873	0x945A	#CJK UNIFIED IDEOGRAPH
+0xE874	0x947C	#CJK UNIFIED IDEOGRAPH
+0xE875	0x947E	#CJK UNIFIED IDEOGRAPH
+0xE876	0x9481	#CJK UNIFIED IDEOGRAPH
+0xE877	0x947F	#CJK UNIFIED IDEOGRAPH
+0xE878	0x9582	#CJK UNIFIED IDEOGRAPH
+0xE879	0x9587	#CJK UNIFIED IDEOGRAPH
+0xE87A	0x958A	#CJK UNIFIED IDEOGRAPH
+0xE87B	0x9594	#CJK UNIFIED IDEOGRAPH
+0xE87C	0x9596	#CJK UNIFIED IDEOGRAPH
+0xE87D	0x9598	#CJK UNIFIED IDEOGRAPH
+0xE87E	0x9599	#CJK UNIFIED IDEOGRAPH
+0xE880	0x95A0	#CJK UNIFIED IDEOGRAPH
+0xE881	0x95A8	#CJK UNIFIED IDEOGRAPH
+0xE882	0x95A7	#CJK UNIFIED IDEOGRAPH
+0xE883	0x95AD	#CJK UNIFIED IDEOGRAPH
+0xE884	0x95BC	#CJK UNIFIED IDEOGRAPH
+0xE885	0x95BB	#CJK UNIFIED IDEOGRAPH
+0xE886	0x95B9	#CJK UNIFIED IDEOGRAPH
+0xE887	0x95BE	#CJK UNIFIED IDEOGRAPH
+0xE888	0x95CA	#CJK UNIFIED IDEOGRAPH
+0xE889	0x6FF6	#CJK UNIFIED IDEOGRAPH
+0xE88A	0x95C3	#CJK UNIFIED IDEOGRAPH
+0xE88B	0x95CD	#CJK UNIFIED IDEOGRAPH
+0xE88C	0x95CC	#CJK UNIFIED IDEOGRAPH
+0xE88D	0x95D5	#CJK UNIFIED IDEOGRAPH
+0xE88E	0x95D4	#CJK UNIFIED IDEOGRAPH
+0xE88F	0x95D6	#CJK UNIFIED IDEOGRAPH
+0xE890	0x95DC	#CJK UNIFIED IDEOGRAPH
+0xE891	0x95E1	#CJK UNIFIED IDEOGRAPH
+0xE892	0x95E5	#CJK UNIFIED IDEOGRAPH
+0xE893	0x95E2	#CJK UNIFIED IDEOGRAPH
+0xE894	0x9621	#CJK UNIFIED IDEOGRAPH
+0xE895	0x9628	#CJK UNIFIED IDEOGRAPH
+0xE896	0x962E	#CJK UNIFIED IDEOGRAPH
+0xE897	0x962F	#CJK UNIFIED IDEOGRAPH
+0xE898	0x9642	#CJK UNIFIED IDEOGRAPH
+0xE899	0x964C	#CJK UNIFIED IDEOGRAPH
+0xE89A	0x964F	#CJK UNIFIED IDEOGRAPH
+0xE89B	0x964B	#CJK UNIFIED IDEOGRAPH
+0xE89C	0x9677	#CJK UNIFIED IDEOGRAPH
+0xE89D	0x965C	#CJK UNIFIED IDEOGRAPH
+0xE89E	0x965E	#CJK UNIFIED IDEOGRAPH
+0xE89F	0x965D	#CJK UNIFIED IDEOGRAPH
+0xE8A0	0x965F	#CJK UNIFIED IDEOGRAPH
+0xE8A1	0x9666	#CJK UNIFIED IDEOGRAPH
+0xE8A2	0x9672	#CJK UNIFIED IDEOGRAPH
+0xE8A3	0x966C	#CJK UNIFIED IDEOGRAPH
+0xE8A4	0x968D	#CJK UNIFIED IDEOGRAPH
+0xE8A5	0x9698	#CJK UNIFIED IDEOGRAPH
+0xE8A6	0x9695	#CJK UNIFIED IDEOGRAPH
+0xE8A7	0x9697	#CJK UNIFIED IDEOGRAPH
+0xE8A8	0x96AA	#CJK UNIFIED IDEOGRAPH
+0xE8A9	0x96A7	#CJK UNIFIED IDEOGRAPH
+0xE8AA	0x96B1	#CJK UNIFIED IDEOGRAPH
+0xE8AB	0x96B2	#CJK UNIFIED IDEOGRAPH
+0xE8AC	0x96B0	#CJK UNIFIED IDEOGRAPH
+0xE8AD	0x96B4	#CJK UNIFIED IDEOGRAPH
+0xE8AE	0x96B6	#CJK UNIFIED IDEOGRAPH
+0xE8AF	0x96B8	#CJK UNIFIED IDEOGRAPH
+0xE8B0	0x96B9	#CJK UNIFIED IDEOGRAPH
+0xE8B1	0x96CE	#CJK UNIFIED IDEOGRAPH
+0xE8B2	0x96CB	#CJK UNIFIED IDEOGRAPH
+0xE8B3	0x96C9	#CJK UNIFIED IDEOGRAPH
+0xE8B4	0x96CD	#CJK UNIFIED IDEOGRAPH
+0xE8B5	0x894D	#CJK UNIFIED IDEOGRAPH
+0xE8B6	0x96DC	#CJK UNIFIED IDEOGRAPH
+0xE8B7	0x970D	#CJK UNIFIED IDEOGRAPH
+0xE8B8	0x96D5	#CJK UNIFIED IDEOGRAPH
+0xE8B9	0x96F9	#CJK UNIFIED IDEOGRAPH
+0xE8BA	0x9704	#CJK UNIFIED IDEOGRAPH
+0xE8BB	0x9706	#CJK UNIFIED IDEOGRAPH
+0xE8BC	0x9708	#CJK UNIFIED IDEOGRAPH
+0xE8BD	0x9713	#CJK UNIFIED IDEOGRAPH
+0xE8BE	0x970E	#CJK UNIFIED IDEOGRAPH
+0xE8BF	0x9711	#CJK UNIFIED IDEOGRAPH
+0xE8C0	0x970F	#CJK UNIFIED IDEOGRAPH
+0xE8C1	0x9716	#CJK UNIFIED IDEOGRAPH
+0xE8C2	0x9719	#CJK UNIFIED IDEOGRAPH
+0xE8C3	0x9724	#CJK UNIFIED IDEOGRAPH
+0xE8C4	0x972A	#CJK UNIFIED IDEOGRAPH
+0xE8C5	0x9730	#CJK UNIFIED IDEOGRAPH
+0xE8C6	0x9739	#CJK UNIFIED IDEOGRAPH
+0xE8C7	0x973D	#CJK UNIFIED IDEOGRAPH
+0xE8C8	0x973E	#CJK UNIFIED IDEOGRAPH
+0xE8C9	0x9744	#CJK UNIFIED IDEOGRAPH
+0xE8CA	0x9746	#CJK UNIFIED IDEOGRAPH
+0xE8CB	0x9748	#CJK UNIFIED IDEOGRAPH
+0xE8CC	0x9742	#CJK UNIFIED IDEOGRAPH
+0xE8CD	0x9749	#CJK UNIFIED IDEOGRAPH
+0xE8CE	0x975C	#CJK UNIFIED IDEOGRAPH
+0xE8CF	0x9760	#CJK UNIFIED IDEOGRAPH
+0xE8D0	0x9764	#CJK UNIFIED IDEOGRAPH
+0xE8D1	0x9766	#CJK UNIFIED IDEOGRAPH
+0xE8D2	0x9768	#CJK UNIFIED IDEOGRAPH
+0xE8D3	0x52D2	#CJK UNIFIED IDEOGRAPH
+0xE8D4	0x976B	#CJK UNIFIED IDEOGRAPH
+0xE8D5	0x9771	#CJK UNIFIED IDEOGRAPH
+0xE8D6	0x9779	#CJK UNIFIED IDEOGRAPH
+0xE8D7	0x9785	#CJK UNIFIED IDEOGRAPH
+0xE8D8	0x977C	#CJK UNIFIED IDEOGRAPH
+0xE8D9	0x9781	#CJK UNIFIED IDEOGRAPH
+0xE8DA	0x977A	#CJK UNIFIED IDEOGRAPH
+0xE8DB	0x9786	#CJK UNIFIED IDEOGRAPH
+0xE8DC	0x978B	#CJK UNIFIED IDEOGRAPH
+0xE8DD	0x978F	#CJK UNIFIED IDEOGRAPH
+0xE8DE	0x9790	#CJK UNIFIED IDEOGRAPH
+0xE8DF	0x979C	#CJK UNIFIED IDEOGRAPH
+0xE8E0	0x97A8	#CJK UNIFIED IDEOGRAPH
+0xE8E1	0x97A6	#CJK UNIFIED IDEOGRAPH
+0xE8E2	0x97A3	#CJK UNIFIED IDEOGRAPH
+0xE8E3	0x97B3	#CJK UNIFIED IDEOGRAPH
+0xE8E4	0x97B4	#CJK UNIFIED IDEOGRAPH
+0xE8E5	0x97C3	#CJK UNIFIED IDEOGRAPH
+0xE8E6	0x97C6	#CJK UNIFIED IDEOGRAPH
+0xE8E7	0x97C8	#CJK UNIFIED IDEOGRAPH
+0xE8E8	0x97CB	#CJK UNIFIED IDEOGRAPH
+0xE8E9	0x97DC	#CJK UNIFIED IDEOGRAPH
+0xE8EA	0x97ED	#CJK UNIFIED IDEOGRAPH
+0xE8EB	0x9F4F	#CJK UNIFIED IDEOGRAPH
+0xE8EC	0x97F2	#CJK UNIFIED IDEOGRAPH
+0xE8ED	0x7ADF	#CJK UNIFIED IDEOGRAPH
+0xE8EE	0x97F6	#CJK UNIFIED IDEOGRAPH
+0xE8EF	0x97F5	#CJK UNIFIED IDEOGRAPH
+0xE8F0	0x980F	#CJK UNIFIED IDEOGRAPH
+0xE8F1	0x980C	#CJK UNIFIED IDEOGRAPH
+0xE8F2	0x9838	#CJK UNIFIED IDEOGRAPH
+0xE8F3	0x9824	#CJK UNIFIED IDEOGRAPH
+0xE8F4	0x9821	#CJK UNIFIED IDEOGRAPH
+0xE8F5	0x9837	#CJK UNIFIED IDEOGRAPH
+0xE8F6	0x983D	#CJK UNIFIED IDEOGRAPH
+0xE8F7	0x9846	#CJK UNIFIED IDEOGRAPH
+0xE8F8	0x984F	#CJK UNIFIED IDEOGRAPH
+0xE8F9	0x984B	#CJK UNIFIED IDEOGRAPH
+0xE8FA	0x986B	#CJK UNIFIED IDEOGRAPH
+0xE8FB	0x986F	#CJK UNIFIED IDEOGRAPH
+0xE8FC	0x9870	#CJK UNIFIED IDEOGRAPH
+0xE940	0x9871	#CJK UNIFIED IDEOGRAPH
+0xE941	0x9874	#CJK UNIFIED IDEOGRAPH
+0xE942	0x9873	#CJK UNIFIED IDEOGRAPH
+0xE943	0x98AA	#CJK UNIFIED IDEOGRAPH
+0xE944	0x98AF	#CJK UNIFIED IDEOGRAPH
+0xE945	0x98B1	#CJK UNIFIED IDEOGRAPH
+0xE946	0x98B6	#CJK UNIFIED IDEOGRAPH
+0xE947	0x98C4	#CJK UNIFIED IDEOGRAPH
+0xE948	0x98C3	#CJK UNIFIED IDEOGRAPH
+0xE949	0x98C6	#CJK UNIFIED IDEOGRAPH
+0xE94A	0x98E9	#CJK UNIFIED IDEOGRAPH
+0xE94B	0x98EB	#CJK UNIFIED IDEOGRAPH
+0xE94C	0x9903	#CJK UNIFIED IDEOGRAPH
+0xE94D	0x9909	#CJK UNIFIED IDEOGRAPH
+0xE94E	0x9912	#CJK UNIFIED IDEOGRAPH
+0xE94F	0x9914	#CJK UNIFIED IDEOGRAPH
+0xE950	0x9918	#CJK UNIFIED IDEOGRAPH
+0xE951	0x9921	#CJK UNIFIED IDEOGRAPH
+0xE952	0x991D	#CJK UNIFIED IDEOGRAPH
+0xE953	0x991E	#CJK UNIFIED IDEOGRAPH
+0xE954	0x9924	#CJK UNIFIED IDEOGRAPH
+0xE955	0x9920	#CJK UNIFIED IDEOGRAPH
+0xE956	0x992C	#CJK UNIFIED IDEOGRAPH
+0xE957	0x992E	#CJK UNIFIED IDEOGRAPH
+0xE958	0x993D	#CJK UNIFIED IDEOGRAPH
+0xE959	0x993E	#CJK UNIFIED IDEOGRAPH
+0xE95A	0x9942	#CJK UNIFIED IDEOGRAPH
+0xE95B	0x9949	#CJK UNIFIED IDEOGRAPH
+0xE95C	0x9945	#CJK UNIFIED IDEOGRAPH
+0xE95D	0x9950	#CJK UNIFIED IDEOGRAPH
+0xE95E	0x994B	#CJK UNIFIED IDEOGRAPH
+0xE95F	0x9951	#CJK UNIFIED IDEOGRAPH
+0xE960	0x9952	#CJK UNIFIED IDEOGRAPH
+0xE961	0x994C	#CJK UNIFIED IDEOGRAPH
+0xE962	0x9955	#CJK UNIFIED IDEOGRAPH
+0xE963	0x9997	#CJK UNIFIED IDEOGRAPH
+0xE964	0x9998	#CJK UNIFIED IDEOGRAPH
+0xE965	0x99A5	#CJK UNIFIED IDEOGRAPH
+0xE966	0x99AD	#CJK UNIFIED IDEOGRAPH
+0xE967	0x99AE	#CJK UNIFIED IDEOGRAPH
+0xE968	0x99BC	#CJK UNIFIED IDEOGRAPH
+0xE969	0x99DF	#CJK UNIFIED IDEOGRAPH
+0xE96A	0x99DB	#CJK UNIFIED IDEOGRAPH
+0xE96B	0x99DD	#CJK UNIFIED IDEOGRAPH
+0xE96C	0x99D8	#CJK UNIFIED IDEOGRAPH
+0xE96D	0x99D1	#CJK UNIFIED IDEOGRAPH
+0xE96E	0x99ED	#CJK UNIFIED IDEOGRAPH
+0xE96F	0x99EE	#CJK UNIFIED IDEOGRAPH
+0xE970	0x99F1	#CJK UNIFIED IDEOGRAPH
+0xE971	0x99F2	#CJK UNIFIED IDEOGRAPH
+0xE972	0x99FB	#CJK UNIFIED IDEOGRAPH
+0xE973	0x99F8	#CJK UNIFIED IDEOGRAPH
+0xE974	0x9A01	#CJK UNIFIED IDEOGRAPH
+0xE975	0x9A0F	#CJK UNIFIED IDEOGRAPH
+0xE976	0x9A05	#CJK UNIFIED IDEOGRAPH
+0xE977	0x99E2	#CJK UNIFIED IDEOGRAPH
+0xE978	0x9A19	#CJK UNIFIED IDEOGRAPH
+0xE979	0x9A2B	#CJK UNIFIED IDEOGRAPH
+0xE97A	0x9A37	#CJK UNIFIED IDEOGRAPH
+0xE97B	0x9A45	#CJK UNIFIED IDEOGRAPH
+0xE97C	0x9A42	#CJK UNIFIED IDEOGRAPH
+0xE97D	0x9A40	#CJK UNIFIED IDEOGRAPH
+0xE97E	0x9A43	#CJK UNIFIED IDEOGRAPH
+0xE980	0x9A3E	#CJK UNIFIED IDEOGRAPH
+0xE981	0x9A55	#CJK UNIFIED IDEOGRAPH
+0xE982	0x9A4D	#CJK UNIFIED IDEOGRAPH
+0xE983	0x9A5B	#CJK UNIFIED IDEOGRAPH
+0xE984	0x9A57	#CJK UNIFIED IDEOGRAPH
+0xE985	0x9A5F	#CJK UNIFIED IDEOGRAPH
+0xE986	0x9A62	#CJK UNIFIED IDEOGRAPH
+0xE987	0x9A65	#CJK UNIFIED IDEOGRAPH
+0xE988	0x9A64	#CJK UNIFIED IDEOGRAPH
+0xE989	0x9A69	#CJK UNIFIED IDEOGRAPH
+0xE98A	0x9A6B	#CJK UNIFIED IDEOGRAPH
+0xE98B	0x9A6A	#CJK UNIFIED IDEOGRAPH
+0xE98C	0x9AAD	#CJK UNIFIED IDEOGRAPH
+0xE98D	0x9AB0	#CJK UNIFIED IDEOGRAPH
+0xE98E	0x9ABC	#CJK UNIFIED IDEOGRAPH
+0xE98F	0x9AC0	#CJK UNIFIED IDEOGRAPH
+0xE990	0x9ACF	#CJK UNIFIED IDEOGRAPH
+0xE991	0x9AD1	#CJK UNIFIED IDEOGRAPH
+0xE992	0x9AD3	#CJK UNIFIED IDEOGRAPH
+0xE993	0x9AD4	#CJK UNIFIED IDEOGRAPH
+0xE994	0x9ADE	#CJK UNIFIED IDEOGRAPH
+0xE995	0x9ADF	#CJK UNIFIED IDEOGRAPH
+0xE996	0x9AE2	#CJK UNIFIED IDEOGRAPH
+0xE997	0x9AE3	#CJK UNIFIED IDEOGRAPH
+0xE998	0x9AE6	#CJK UNIFIED IDEOGRAPH
+0xE999	0x9AEF	#CJK UNIFIED IDEOGRAPH
+0xE99A	0x9AEB	#CJK UNIFIED IDEOGRAPH
+0xE99B	0x9AEE	#CJK UNIFIED IDEOGRAPH
+0xE99C	0x9AF4	#CJK UNIFIED IDEOGRAPH
+0xE99D	0x9AF1	#CJK UNIFIED IDEOGRAPH
+0xE99E	0x9AF7	#CJK UNIFIED IDEOGRAPH
+0xE99F	0x9AFB	#CJK UNIFIED IDEOGRAPH
+0xE9A0	0x9B06	#CJK UNIFIED IDEOGRAPH
+0xE9A1	0x9B18	#CJK UNIFIED IDEOGRAPH
+0xE9A2	0x9B1A	#CJK UNIFIED IDEOGRAPH
+0xE9A3	0x9B1F	#CJK UNIFIED IDEOGRAPH
+0xE9A4	0x9B22	#CJK UNIFIED IDEOGRAPH
+0xE9A5	0x9B23	#CJK UNIFIED IDEOGRAPH
+0xE9A6	0x9B25	#CJK UNIFIED IDEOGRAPH
+0xE9A7	0x9B27	#CJK UNIFIED IDEOGRAPH
+0xE9A8	0x9B28	#CJK UNIFIED IDEOGRAPH
+0xE9A9	0x9B29	#CJK UNIFIED IDEOGRAPH
+0xE9AA	0x9B2A	#CJK UNIFIED IDEOGRAPH
+0xE9AB	0x9B2E	#CJK UNIFIED IDEOGRAPH
+0xE9AC	0x9B2F	#CJK UNIFIED IDEOGRAPH
+0xE9AD	0x9B32	#CJK UNIFIED IDEOGRAPH
+0xE9AE	0x9B44	#CJK UNIFIED IDEOGRAPH
+0xE9AF	0x9B43	#CJK UNIFIED IDEOGRAPH
+0xE9B0	0x9B4F	#CJK UNIFIED IDEOGRAPH
+0xE9B1	0x9B4D	#CJK UNIFIED IDEOGRAPH
+0xE9B2	0x9B4E	#CJK UNIFIED IDEOGRAPH
+0xE9B3	0x9B51	#CJK UNIFIED IDEOGRAPH
+0xE9B4	0x9B58	#CJK UNIFIED IDEOGRAPH
+0xE9B5	0x9B74	#CJK UNIFIED IDEOGRAPH
+0xE9B6	0x9B93	#CJK UNIFIED IDEOGRAPH
+0xE9B7	0x9B83	#CJK UNIFIED IDEOGRAPH
+0xE9B8	0x9B91	#CJK UNIFIED IDEOGRAPH
+0xE9B9	0x9B96	#CJK UNIFIED IDEOGRAPH
+0xE9BA	0x9B97	#CJK UNIFIED IDEOGRAPH
+0xE9BB	0x9B9F	#CJK UNIFIED IDEOGRAPH
+0xE9BC	0x9BA0	#CJK UNIFIED IDEOGRAPH
+0xE9BD	0x9BA8	#CJK UNIFIED IDEOGRAPH
+0xE9BE	0x9BB4	#CJK UNIFIED IDEOGRAPH
+0xE9BF	0x9BC0	#CJK UNIFIED IDEOGRAPH
+0xE9C0	0x9BCA	#CJK UNIFIED IDEOGRAPH
+0xE9C1	0x9BB9	#CJK UNIFIED IDEOGRAPH
+0xE9C2	0x9BC6	#CJK UNIFIED IDEOGRAPH
+0xE9C3	0x9BCF	#CJK UNIFIED IDEOGRAPH
+0xE9C4	0x9BD1	#CJK UNIFIED IDEOGRAPH
+0xE9C5	0x9BD2	#CJK UNIFIED IDEOGRAPH
+0xE9C6	0x9BE3	#CJK UNIFIED IDEOGRAPH
+0xE9C7	0x9BE2	#CJK UNIFIED IDEOGRAPH
+0xE9C8	0x9BE4	#CJK UNIFIED IDEOGRAPH
+0xE9C9	0x9BD4	#CJK UNIFIED IDEOGRAPH
+0xE9CA	0x9BE1	#CJK UNIFIED IDEOGRAPH
+0xE9CB	0x9C3A	#CJK UNIFIED IDEOGRAPH
+0xE9CC	0x9BF2	#CJK UNIFIED IDEOGRAPH
+0xE9CD	0x9BF1	#CJK UNIFIED IDEOGRAPH
+0xE9CE	0x9BF0	#CJK UNIFIED IDEOGRAPH
+0xE9CF	0x9C15	#CJK UNIFIED IDEOGRAPH
+0xE9D0	0x9C14	#CJK UNIFIED IDEOGRAPH
+0xE9D1	0x9C09	#CJK UNIFIED IDEOGRAPH
+0xE9D2	0x9C13	#CJK UNIFIED IDEOGRAPH
+0xE9D3	0x9C0C	#CJK UNIFIED IDEOGRAPH
+0xE9D4	0x9C06	#CJK UNIFIED IDEOGRAPH
+0xE9D5	0x9C08	#CJK UNIFIED IDEOGRAPH
+0xE9D6	0x9C12	#CJK UNIFIED IDEOGRAPH
+0xE9D7	0x9C0A	#CJK UNIFIED IDEOGRAPH
+0xE9D8	0x9C04	#CJK UNIFIED IDEOGRAPH
+0xE9D9	0x9C2E	#CJK UNIFIED IDEOGRAPH
+0xE9DA	0x9C1B	#CJK UNIFIED IDEOGRAPH
+0xE9DB	0x9C25	#CJK UNIFIED IDEOGRAPH
+0xE9DC	0x9C24	#CJK UNIFIED IDEOGRAPH
+0xE9DD	0x9C21	#CJK UNIFIED IDEOGRAPH
+0xE9DE	0x9C30	#CJK UNIFIED IDEOGRAPH
+0xE9DF	0x9C47	#CJK UNIFIED IDEOGRAPH
+0xE9E0	0x9C32	#CJK UNIFIED IDEOGRAPH
+0xE9E1	0x9C46	#CJK UNIFIED IDEOGRAPH
+0xE9E2	0x9C3E	#CJK UNIFIED IDEOGRAPH
+0xE9E3	0x9C5A	#CJK UNIFIED IDEOGRAPH
+0xE9E4	0x9C60	#CJK UNIFIED IDEOGRAPH
+0xE9E5	0x9C67	#CJK UNIFIED IDEOGRAPH
+0xE9E6	0x9C76	#CJK UNIFIED IDEOGRAPH
+0xE9E7	0x9C78	#CJK UNIFIED IDEOGRAPH
+0xE9E8	0x9CE7	#CJK UNIFIED IDEOGRAPH
+0xE9E9	0x9CEC	#CJK UNIFIED IDEOGRAPH
+0xE9EA	0x9CF0	#CJK UNIFIED IDEOGRAPH
+0xE9EB	0x9D09	#CJK UNIFIED IDEOGRAPH
+0xE9EC	0x9D08	#CJK UNIFIED IDEOGRAPH
+0xE9ED	0x9CEB	#CJK UNIFIED IDEOGRAPH
+0xE9EE	0x9D03	#CJK UNIFIED IDEOGRAPH
+0xE9EF	0x9D06	#CJK UNIFIED IDEOGRAPH
+0xE9F0	0x9D2A	#CJK UNIFIED IDEOGRAPH
+0xE9F1	0x9D26	#CJK UNIFIED IDEOGRAPH
+0xE9F2	0x9DAF	#CJK UNIFIED IDEOGRAPH
+0xE9F3	0x9D23	#CJK UNIFIED IDEOGRAPH
+0xE9F4	0x9D1F	#CJK UNIFIED IDEOGRAPH
+0xE9F5	0x9D44	#CJK UNIFIED IDEOGRAPH
+0xE9F6	0x9D15	#CJK UNIFIED IDEOGRAPH
+0xE9F7	0x9D12	#CJK UNIFIED IDEOGRAPH
+0xE9F8	0x9D41	#CJK UNIFIED IDEOGRAPH
+0xE9F9	0x9D3F	#CJK UNIFIED IDEOGRAPH
+0xE9FA	0x9D3E	#CJK UNIFIED IDEOGRAPH
+0xE9FB	0x9D46	#CJK UNIFIED IDEOGRAPH
+0xE9FC	0x9D48	#CJK UNIFIED IDEOGRAPH
+0xEA40	0x9D5D	#CJK UNIFIED IDEOGRAPH
+0xEA41	0x9D5E	#CJK UNIFIED IDEOGRAPH
+0xEA42	0x9D64	#CJK UNIFIED IDEOGRAPH
+0xEA43	0x9D51	#CJK UNIFIED IDEOGRAPH
+0xEA44	0x9D50	#CJK UNIFIED IDEOGRAPH
+0xEA45	0x9D59	#CJK UNIFIED IDEOGRAPH
+0xEA46	0x9D72	#CJK UNIFIED IDEOGRAPH
+0xEA47	0x9D89	#CJK UNIFIED IDEOGRAPH
+0xEA48	0x9D87	#CJK UNIFIED IDEOGRAPH
+0xEA49	0x9DAB	#CJK UNIFIED IDEOGRAPH
+0xEA4A	0x9D6F	#CJK UNIFIED IDEOGRAPH
+0xEA4B	0x9D7A	#CJK UNIFIED IDEOGRAPH
+0xEA4C	0x9D9A	#CJK UNIFIED IDEOGRAPH
+0xEA4D	0x9DA4	#CJK UNIFIED IDEOGRAPH
+0xEA4E	0x9DA9	#CJK UNIFIED IDEOGRAPH
+0xEA4F	0x9DB2	#CJK UNIFIED IDEOGRAPH
+0xEA50	0x9DC4	#CJK UNIFIED IDEOGRAPH
+0xEA51	0x9DC1	#CJK UNIFIED IDEOGRAPH
+0xEA52	0x9DBB	#CJK UNIFIED IDEOGRAPH
+0xEA53	0x9DB8	#CJK UNIFIED IDEOGRAPH
+0xEA54	0x9DBA	#CJK UNIFIED IDEOGRAPH
+0xEA55	0x9DC6	#CJK UNIFIED IDEOGRAPH
+0xEA56	0x9DCF	#CJK UNIFIED IDEOGRAPH
+0xEA57	0x9DC2	#CJK UNIFIED IDEOGRAPH
+0xEA58	0x9DD9	#CJK UNIFIED IDEOGRAPH
+0xEA59	0x9DD3	#CJK UNIFIED IDEOGRAPH
+0xEA5A	0x9DF8	#CJK UNIFIED IDEOGRAPH
+0xEA5B	0x9DE6	#CJK UNIFIED IDEOGRAPH
+0xEA5C	0x9DED	#CJK UNIFIED IDEOGRAPH
+0xEA5D	0x9DEF	#CJK UNIFIED IDEOGRAPH
+0xEA5E	0x9DFD	#CJK UNIFIED IDEOGRAPH
+0xEA5F	0x9E1A	#CJK UNIFIED IDEOGRAPH
+0xEA60	0x9E1B	#CJK UNIFIED IDEOGRAPH
+0xEA61	0x9E1E	#CJK UNIFIED IDEOGRAPH
+0xEA62	0x9E75	#CJK UNIFIED IDEOGRAPH
+0xEA63	0x9E79	#CJK UNIFIED IDEOGRAPH
+0xEA64	0x9E7D	#CJK UNIFIED IDEOGRAPH
+0xEA65	0x9E81	#CJK UNIFIED IDEOGRAPH
+0xEA66	0x9E88	#CJK UNIFIED IDEOGRAPH
+0xEA67	0x9E8B	#CJK UNIFIED IDEOGRAPH
+0xEA68	0x9E8C	#CJK UNIFIED IDEOGRAPH
+0xEA69	0x9E92	#CJK UNIFIED IDEOGRAPH
+0xEA6A	0x9E95	#CJK UNIFIED IDEOGRAPH
+0xEA6B	0x9E91	#CJK UNIFIED IDEOGRAPH
+0xEA6C	0x9E9D	#CJK UNIFIED IDEOGRAPH
+0xEA6D	0x9EA5	#CJK UNIFIED IDEOGRAPH
+0xEA6E	0x9EA9	#CJK UNIFIED IDEOGRAPH
+0xEA6F	0x9EB8	#CJK UNIFIED IDEOGRAPH
+0xEA70	0x9EAA	#CJK UNIFIED IDEOGRAPH
+0xEA71	0x9EAD	#CJK UNIFIED IDEOGRAPH
+0xEA72	0x9761	#CJK UNIFIED IDEOGRAPH
+0xEA73	0x9ECC	#CJK UNIFIED IDEOGRAPH
+0xEA74	0x9ECE	#CJK UNIFIED IDEOGRAPH
+0xEA75	0x9ECF	#CJK UNIFIED IDEOGRAPH
+0xEA76	0x9ED0	#CJK UNIFIED IDEOGRAPH
+0xEA77	0x9ED4	#CJK UNIFIED IDEOGRAPH
+0xEA78	0x9EDC	#CJK UNIFIED IDEOGRAPH
+0xEA79	0x9EDE	#CJK UNIFIED IDEOGRAPH
+0xEA7A	0x9EDD	#CJK UNIFIED IDEOGRAPH
+0xEA7B	0x9EE0	#CJK UNIFIED IDEOGRAPH
+0xEA7C	0x9EE5	#CJK UNIFIED IDEOGRAPH
+0xEA7D	0x9EE8	#CJK UNIFIED IDEOGRAPH
+0xEA7E	0x9EEF	#CJK UNIFIED IDEOGRAPH
+0xEA80	0x9EF4	#CJK UNIFIED IDEOGRAPH
+0xEA81	0x9EF6	#CJK UNIFIED IDEOGRAPH
+0xEA82	0x9EF7	#CJK UNIFIED IDEOGRAPH
+0xEA83	0x9EF9	#CJK UNIFIED IDEOGRAPH
+0xEA84	0x9EFB	#CJK UNIFIED IDEOGRAPH
+0xEA85	0x9EFC	#CJK UNIFIED IDEOGRAPH
+0xEA86	0x9EFD	#CJK UNIFIED IDEOGRAPH
+0xEA87	0x9F07	#CJK UNIFIED IDEOGRAPH
+0xEA88	0x9F08	#CJK UNIFIED IDEOGRAPH
+0xEA89	0x76B7	#CJK UNIFIED IDEOGRAPH
+0xEA8A	0x9F15	#CJK UNIFIED IDEOGRAPH
+0xEA8B	0x9F21	#CJK UNIFIED IDEOGRAPH
+0xEA8C	0x9F2C	#CJK UNIFIED IDEOGRAPH
+0xEA8D	0x9F3E	#CJK UNIFIED IDEOGRAPH
+0xEA8E	0x9F4A	#CJK UNIFIED IDEOGRAPH
+0xEA8F	0x9F52	#CJK UNIFIED IDEOGRAPH
+0xEA90	0x9F54	#CJK UNIFIED IDEOGRAPH
+0xEA91	0x9F63	#CJK UNIFIED IDEOGRAPH
+0xEA92	0x9F5F	#CJK UNIFIED IDEOGRAPH
+0xEA93	0x9F60	#CJK UNIFIED IDEOGRAPH
+0xEA94	0x9F61	#CJK UNIFIED IDEOGRAPH
+0xEA95	0x9F66	#CJK UNIFIED IDEOGRAPH
+0xEA96	0x9F67	#CJK UNIFIED IDEOGRAPH
+0xEA97	0x9F6C	#CJK UNIFIED IDEOGRAPH
+0xEA98	0x9F6A	#CJK UNIFIED IDEOGRAPH
+0xEA99	0x9F77	#CJK UNIFIED IDEOGRAPH
+0xEA9A	0x9F72	#CJK UNIFIED IDEOGRAPH
+0xEA9B	0x9F76	#CJK UNIFIED IDEOGRAPH
+0xEA9C	0x9F95	#CJK UNIFIED IDEOGRAPH
+0xEA9D	0x9F9C	#CJK UNIFIED IDEOGRAPH
+0xEA9E	0x9FA0	#CJK UNIFIED IDEOGRAPH
+0xEA9F	0x582F	#CJK UNIFIED IDEOGRAPH
+0xEAA0	0x69C7	#CJK UNIFIED IDEOGRAPH
+0xEAA1	0x9059	#CJK UNIFIED IDEOGRAPH
+0xEAA2	0x7464	#CJK UNIFIED IDEOGRAPH
+0xEAA3	0x51DC	#CJK UNIFIED IDEOGRAPH
+0xEAA4	0x7199	#CJK UNIFIED IDEOGRAPH
+0xED40	0x7E8A	#CJK UNIFIED IDEOGRAPH
+0xED41	0x891C	#CJK UNIFIED IDEOGRAPH
+0xED42	0x9348	#CJK UNIFIED IDEOGRAPH
+0xED43	0x9288	#CJK UNIFIED IDEOGRAPH
+0xED44	0x84DC	#CJK UNIFIED IDEOGRAPH
+0xED45	0x4FC9	#CJK UNIFIED IDEOGRAPH
+0xED46	0x70BB	#CJK UNIFIED IDEOGRAPH
+0xED47	0x6631	#CJK UNIFIED IDEOGRAPH
+0xED48	0x68C8	#CJK UNIFIED IDEOGRAPH
+0xED49	0x92F9	#CJK UNIFIED IDEOGRAPH
+0xED4A	0x66FB	#CJK UNIFIED IDEOGRAPH
+0xED4B	0x5F45	#CJK UNIFIED IDEOGRAPH
+0xED4C	0x4E28	#CJK UNIFIED IDEOGRAPH
+0xED4D	0x4EE1	#CJK UNIFIED IDEOGRAPH
+0xED4E	0x4EFC	#CJK UNIFIED IDEOGRAPH
+0xED4F	0x4F00	#CJK UNIFIED IDEOGRAPH
+0xED50	0x4F03	#CJK UNIFIED IDEOGRAPH
+0xED51	0x4F39	#CJK UNIFIED IDEOGRAPH
+0xED52	0x4F56	#CJK UNIFIED IDEOGRAPH
+0xED53	0x4F92	#CJK UNIFIED IDEOGRAPH
+0xED54	0x4F8A	#CJK UNIFIED IDEOGRAPH
+0xED55	0x4F9A	#CJK UNIFIED IDEOGRAPH
+0xED56	0x4F94	#CJK UNIFIED IDEOGRAPH
+0xED57	0x4FCD	#CJK UNIFIED IDEOGRAPH
+0xED58	0x5040	#CJK UNIFIED IDEOGRAPH
+0xED59	0x5022	#CJK UNIFIED IDEOGRAPH
+0xED5A	0x4FFF	#CJK UNIFIED IDEOGRAPH
+0xED5B	0x501E	#CJK UNIFIED IDEOGRAPH
+0xED5C	0x5046	#CJK UNIFIED IDEOGRAPH
+0xED5D	0x5070	#CJK UNIFIED IDEOGRAPH
+0xED5E	0x5042	#CJK UNIFIED IDEOGRAPH
+0xED5F	0x5094	#CJK UNIFIED IDEOGRAPH
+0xED60	0x50F4	#CJK UNIFIED IDEOGRAPH
+0xED61	0x50D8	#CJK UNIFIED IDEOGRAPH
+0xED62	0x514A	#CJK UNIFIED IDEOGRAPH
+0xED63	0x5164	#CJK UNIFIED IDEOGRAPH
+0xED64	0x519D	#CJK UNIFIED IDEOGRAPH
+0xED65	0x51BE	#CJK UNIFIED IDEOGRAPH
+0xED66	0x51EC	#CJK UNIFIED IDEOGRAPH
+0xED67	0x5215	#CJK UNIFIED IDEOGRAPH
+0xED68	0x529C	#CJK UNIFIED IDEOGRAPH
+0xED69	0x52A6	#CJK UNIFIED IDEOGRAPH
+0xED6A	0x52C0	#CJK UNIFIED IDEOGRAPH
+0xED6B	0x52DB	#CJK UNIFIED IDEOGRAPH
+0xED6C	0x5300	#CJK UNIFIED IDEOGRAPH
+0xED6D	0x5307	#CJK UNIFIED IDEOGRAPH
+0xED6E	0x5324	#CJK UNIFIED IDEOGRAPH
+0xED6F	0x5372	#CJK UNIFIED IDEOGRAPH
+0xED70	0x5393	#CJK UNIFIED IDEOGRAPH
+0xED71	0x53B2	#CJK UNIFIED IDEOGRAPH
+0xED72	0x53DD	#CJK UNIFIED IDEOGRAPH
+0xED73	0xFA0E	#CJK COMPATIBILITY IDEOGRAPH
+0xED74	0x549C	#CJK UNIFIED IDEOGRAPH
+0xED75	0x548A	#CJK UNIFIED IDEOGRAPH
+0xED76	0x54A9	#CJK UNIFIED IDEOGRAPH
+0xED77	0x54FF	#CJK UNIFIED IDEOGRAPH
+0xED78	0x5586	#CJK UNIFIED IDEOGRAPH
+0xED79	0x5759	#CJK UNIFIED IDEOGRAPH
+0xED7A	0x5765	#CJK UNIFIED IDEOGRAPH
+0xED7B	0x57AC	#CJK UNIFIED IDEOGRAPH
+0xED7C	0x57C8	#CJK UNIFIED IDEOGRAPH
+0xED7D	0x57C7	#CJK UNIFIED IDEOGRAPH
+0xED7E	0xFA0F	#CJK COMPATIBILITY IDEOGRAPH
+0xED80	0xFA10	#CJK COMPATIBILITY IDEOGRAPH
+0xED81	0x589E	#CJK UNIFIED IDEOGRAPH
+0xED82	0x58B2	#CJK UNIFIED IDEOGRAPH
+0xED83	0x590B	#CJK UNIFIED IDEOGRAPH
+0xED84	0x5953	#CJK UNIFIED IDEOGRAPH
+0xED85	0x595B	#CJK UNIFIED IDEOGRAPH
+0xED86	0x595D	#CJK UNIFIED IDEOGRAPH
+0xED87	0x5963	#CJK UNIFIED IDEOGRAPH
+0xED88	0x59A4	#CJK UNIFIED IDEOGRAPH
+0xED89	0x59BA	#CJK UNIFIED IDEOGRAPH
+0xED8A	0x5B56	#CJK UNIFIED IDEOGRAPH
+0xED8B	0x5BC0	#CJK UNIFIED IDEOGRAPH
+0xED8C	0x752F	#CJK UNIFIED IDEOGRAPH
+0xED8D	0x5BD8	#CJK UNIFIED IDEOGRAPH
+0xED8E	0x5BEC	#CJK UNIFIED IDEOGRAPH
+0xED8F	0x5C1E	#CJK UNIFIED IDEOGRAPH
+0xED90	0x5CA6	#CJK UNIFIED IDEOGRAPH
+0xED91	0x5CBA	#CJK UNIFIED IDEOGRAPH
+0xED92	0x5CF5	#CJK UNIFIED IDEOGRAPH
+0xED93	0x5D27	#CJK UNIFIED IDEOGRAPH
+0xED94	0x5D53	#CJK UNIFIED IDEOGRAPH
+0xED95	0xFA11	#CJK COMPATIBILITY IDEOGRAPH
+0xED96	0x5D42	#CJK UNIFIED IDEOGRAPH
+0xED97	0x5D6D	#CJK UNIFIED IDEOGRAPH
+0xED98	0x5DB8	#CJK UNIFIED IDEOGRAPH
+0xED99	0x5DB9	#CJK UNIFIED IDEOGRAPH
+0xED9A	0x5DD0	#CJK UNIFIED IDEOGRAPH
+0xED9B	0x5F21	#CJK UNIFIED IDEOGRAPH
+0xED9C	0x5F34	#CJK UNIFIED IDEOGRAPH
+0xED9D	0x5F67	#CJK UNIFIED IDEOGRAPH
+0xED9E	0x5FB7	#CJK UNIFIED IDEOGRAPH
+0xED9F	0x5FDE	#CJK UNIFIED IDEOGRAPH
+0xEDA0	0x605D	#CJK UNIFIED IDEOGRAPH
+0xEDA1	0x6085	#CJK UNIFIED IDEOGRAPH
+0xEDA2	0x608A	#CJK UNIFIED IDEOGRAPH
+0xEDA3	0x60DE	#CJK UNIFIED IDEOGRAPH
+0xEDA4	0x60D5	#CJK UNIFIED IDEOGRAPH
+0xEDA5	0x6120	#CJK UNIFIED IDEOGRAPH
+0xEDA6	0x60F2	#CJK UNIFIED IDEOGRAPH
+0xEDA7	0x6111	#CJK UNIFIED IDEOGRAPH
+0xEDA8	0x6137	#CJK UNIFIED IDEOGRAPH
+0xEDA9	0x6130	#CJK UNIFIED IDEOGRAPH
+0xEDAA	0x6198	#CJK UNIFIED IDEOGRAPH
+0xEDAB	0x6213	#CJK UNIFIED IDEOGRAPH
+0xEDAC	0x62A6	#CJK UNIFIED IDEOGRAPH
+0xEDAD	0x63F5	#CJK UNIFIED IDEOGRAPH
+0xEDAE	0x6460	#CJK UNIFIED IDEOGRAPH
+0xEDAF	0x649D	#CJK UNIFIED IDEOGRAPH
+0xEDB0	0x64CE	#CJK UNIFIED IDEOGRAPH
+0xEDB1	0x654E	#CJK UNIFIED IDEOGRAPH
+0xEDB2	0x6600	#CJK UNIFIED IDEOGRAPH
+0xEDB3	0x6615	#CJK UNIFIED IDEOGRAPH
+0xEDB4	0x663B	#CJK UNIFIED IDEOGRAPH
+0xEDB5	0x6609	#CJK UNIFIED IDEOGRAPH
+0xEDB6	0x662E	#CJK UNIFIED IDEOGRAPH
+0xEDB7	0x661E	#CJK UNIFIED IDEOGRAPH
+0xEDB8	0x6624	#CJK UNIFIED IDEOGRAPH
+0xEDB9	0x6665	#CJK UNIFIED IDEOGRAPH
+0xEDBA	0x6657	#CJK UNIFIED IDEOGRAPH
+0xEDBB	0x6659	#CJK UNIFIED IDEOGRAPH
+0xEDBC	0xFA12	#CJK COMPATIBILITY IDEOGRAPH
+0xEDBD	0x6673	#CJK UNIFIED IDEOGRAPH
+0xEDBE	0x6699	#CJK UNIFIED IDEOGRAPH
+0xEDBF	0x66A0	#CJK UNIFIED IDEOGRAPH
+0xEDC0	0x66B2	#CJK UNIFIED IDEOGRAPH
+0xEDC1	0x66BF	#CJK UNIFIED IDEOGRAPH
+0xEDC2	0x66FA	#CJK UNIFIED IDEOGRAPH
+0xEDC3	0x670E	#CJK UNIFIED IDEOGRAPH
+0xEDC4	0xF929	#CJK COMPATIBILITY IDEOGRAPH
+0xEDC5	0x6766	#CJK UNIFIED IDEOGRAPH
+0xEDC6	0x67BB	#CJK UNIFIED IDEOGRAPH
+0xEDC7	0x6852	#CJK UNIFIED IDEOGRAPH
+0xEDC8	0x67C0	#CJK UNIFIED IDEOGRAPH
+0xEDC9	0x6801	#CJK UNIFIED IDEOGRAPH
+0xEDCA	0x6844	#CJK UNIFIED IDEOGRAPH
+0xEDCB	0x68CF	#CJK UNIFIED IDEOGRAPH
+0xEDCC	0xFA13	#CJK COMPATIBILITY IDEOGRAPH
+0xEDCD	0x6968	#CJK UNIFIED IDEOGRAPH
+0xEDCE	0xFA14	#CJK COMPATIBILITY IDEOGRAPH
+0xEDCF	0x6998	#CJK UNIFIED IDEOGRAPH
+0xEDD0	0x69E2	#CJK UNIFIED IDEOGRAPH
+0xEDD1	0x6A30	#CJK UNIFIED IDEOGRAPH
+0xEDD2	0x6A6B	#CJK UNIFIED IDEOGRAPH
+0xEDD3	0x6A46	#CJK UNIFIED IDEOGRAPH
+0xEDD4	0x6A73	#CJK UNIFIED IDEOGRAPH
+0xEDD5	0x6A7E	#CJK UNIFIED IDEOGRAPH
+0xEDD6	0x6AE2	#CJK UNIFIED IDEOGRAPH
+0xEDD7	0x6AE4	#CJK UNIFIED IDEOGRAPH
+0xEDD8	0x6BD6	#CJK UNIFIED IDEOGRAPH
+0xEDD9	0x6C3F	#CJK UNIFIED IDEOGRAPH
+0xEDDA	0x6C5C	#CJK UNIFIED IDEOGRAPH
+0xEDDB	0x6C86	#CJK UNIFIED IDEOGRAPH
+0xEDDC	0x6C6F	#CJK UNIFIED IDEOGRAPH
+0xEDDD	0x6CDA	#CJK UNIFIED IDEOGRAPH
+0xEDDE	0x6D04	#CJK UNIFIED IDEOGRAPH
+0xEDDF	0x6D87	#CJK UNIFIED IDEOGRAPH
+0xEDE0	0x6D6F	#CJK UNIFIED IDEOGRAPH
+0xEDE1	0x6D96	#CJK UNIFIED IDEOGRAPH
+0xEDE2	0x6DAC	#CJK UNIFIED IDEOGRAPH
+0xEDE3	0x6DCF	#CJK UNIFIED IDEOGRAPH
+0xEDE4	0x6DF8	#CJK UNIFIED IDEOGRAPH
+0xEDE5	0x6DF2	#CJK UNIFIED IDEOGRAPH
+0xEDE6	0x6DFC	#CJK UNIFIED IDEOGRAPH
+0xEDE7	0x6E39	#CJK UNIFIED IDEOGRAPH
+0xEDE8	0x6E5C	#CJK UNIFIED IDEOGRAPH
+0xEDE9	0x6E27	#CJK UNIFIED IDEOGRAPH
+0xEDEA	0x6E3C	#CJK UNIFIED IDEOGRAPH
+0xEDEB	0x6EBF	#CJK UNIFIED IDEOGRAPH
+0xEDEC	0x6F88	#CJK UNIFIED IDEOGRAPH
+0xEDED	0x6FB5	#CJK UNIFIED IDEOGRAPH
+0xEDEE	0x6FF5	#CJK UNIFIED IDEOGRAPH
+0xEDEF	0x7005	#CJK UNIFIED IDEOGRAPH
+0xEDF0	0x7007	#CJK UNIFIED IDEOGRAPH
+0xEDF1	0x7028	#CJK UNIFIED IDEOGRAPH
+0xEDF2	0x7085	#CJK UNIFIED IDEOGRAPH
+0xEDF3	0x70AB	#CJK UNIFIED IDEOGRAPH
+0xEDF4	0x710F	#CJK UNIFIED IDEOGRAPH
+0xEDF5	0x7104	#CJK UNIFIED IDEOGRAPH
+0xEDF6	0x715C	#CJK UNIFIED IDEOGRAPH
+0xEDF7	0x7146	#CJK UNIFIED IDEOGRAPH
+0xEDF8	0x7147	#CJK UNIFIED IDEOGRAPH
+0xEDF9	0xFA15	#CJK COMPATIBILITY IDEOGRAPH
+0xEDFA	0x71C1	#CJK UNIFIED IDEOGRAPH
+0xEDFB	0x71FE	#CJK UNIFIED IDEOGRAPH
+0xEDFC	0x72B1	#CJK UNIFIED IDEOGRAPH
+0xEE40	0x72BE	#CJK UNIFIED IDEOGRAPH
+0xEE41	0x7324	#CJK UNIFIED IDEOGRAPH
+0xEE42	0xFA16	#CJK COMPATIBILITY IDEOGRAPH
+0xEE43	0x7377	#CJK UNIFIED IDEOGRAPH
+0xEE44	0x73BD	#CJK UNIFIED IDEOGRAPH
+0xEE45	0x73C9	#CJK UNIFIED IDEOGRAPH
+0xEE46	0x73D6	#CJK UNIFIED IDEOGRAPH
+0xEE47	0x73E3	#CJK UNIFIED IDEOGRAPH
+0xEE48	0x73D2	#CJK UNIFIED IDEOGRAPH
+0xEE49	0x7407	#CJK UNIFIED IDEOGRAPH
+0xEE4A	0x73F5	#CJK UNIFIED IDEOGRAPH
+0xEE4B	0x7426	#CJK UNIFIED IDEOGRAPH
+0xEE4C	0x742A	#CJK UNIFIED IDEOGRAPH
+0xEE4D	0x7429	#CJK UNIFIED IDEOGRAPH
+0xEE4E	0x742E	#CJK UNIFIED IDEOGRAPH
+0xEE4F	0x7462	#CJK UNIFIED IDEOGRAPH
+0xEE50	0x7489	#CJK UNIFIED IDEOGRAPH
+0xEE51	0x749F	#CJK UNIFIED IDEOGRAPH
+0xEE52	0x7501	#CJK UNIFIED IDEOGRAPH
+0xEE53	0x756F	#CJK UNIFIED IDEOGRAPH
+0xEE54	0x7682	#CJK UNIFIED IDEOGRAPH
+0xEE55	0x769C	#CJK UNIFIED IDEOGRAPH
+0xEE56	0x769E	#CJK UNIFIED IDEOGRAPH
+0xEE57	0x769B	#CJK UNIFIED IDEOGRAPH
+0xEE58	0x76A6	#CJK UNIFIED IDEOGRAPH
+0xEE59	0xFA17	#CJK COMPATIBILITY IDEOGRAPH
+0xEE5A	0x7746	#CJK UNIFIED IDEOGRAPH
+0xEE5B	0x52AF	#CJK UNIFIED IDEOGRAPH
+0xEE5C	0x7821	#CJK UNIFIED IDEOGRAPH
+0xEE5D	0x784E	#CJK UNIFIED IDEOGRAPH
+0xEE5E	0x7864	#CJK UNIFIED IDEOGRAPH
+0xEE5F	0x787A	#CJK UNIFIED IDEOGRAPH
+0xEE60	0x7930	#CJK UNIFIED IDEOGRAPH
+0xEE61	0xFA18	#CJK COMPATIBILITY IDEOGRAPH
+0xEE62	0xFA19	#CJK COMPATIBILITY IDEOGRAPH
+0xEE63	0xFA1A	#CJK COMPATIBILITY IDEOGRAPH
+0xEE64	0x7994	#CJK UNIFIED IDEOGRAPH
+0xEE65	0xFA1B	#CJK COMPATIBILITY IDEOGRAPH
+0xEE66	0x799B	#CJK UNIFIED IDEOGRAPH
+0xEE67	0x7AD1	#CJK UNIFIED IDEOGRAPH
+0xEE68	0x7AE7	#CJK UNIFIED IDEOGRAPH
+0xEE69	0xFA1C	#CJK COMPATIBILITY IDEOGRAPH
+0xEE6A	0x7AEB	#CJK UNIFIED IDEOGRAPH
+0xEE6B	0x7B9E	#CJK UNIFIED IDEOGRAPH
+0xEE6C	0xFA1D	#CJK COMPATIBILITY IDEOGRAPH
+0xEE6D	0x7D48	#CJK UNIFIED IDEOGRAPH
+0xEE6E	0x7D5C	#CJK UNIFIED IDEOGRAPH
+0xEE6F	0x7DB7	#CJK UNIFIED IDEOGRAPH
+0xEE70	0x7DA0	#CJK UNIFIED IDEOGRAPH
+0xEE71	0x7DD6	#CJK UNIFIED IDEOGRAPH
+0xEE72	0x7E52	#CJK UNIFIED IDEOGRAPH
+0xEE73	0x7F47	#CJK UNIFIED IDEOGRAPH
+0xEE74	0x7FA1	#CJK UNIFIED IDEOGRAPH
+0xEE75	0xFA1E	#CJK COMPATIBILITY IDEOGRAPH
+0xEE76	0x8301	#CJK UNIFIED IDEOGRAPH
+0xEE77	0x8362	#CJK UNIFIED IDEOGRAPH
+0xEE78	0x837F	#CJK UNIFIED IDEOGRAPH
+0xEE79	0x83C7	#CJK UNIFIED IDEOGRAPH
+0xEE7A	0x83F6	#CJK UNIFIED IDEOGRAPH
+0xEE7B	0x8448	#CJK UNIFIED IDEOGRAPH
+0xEE7C	0x84B4	#CJK UNIFIED IDEOGRAPH
+0xEE7D	0x8553	#CJK UNIFIED IDEOGRAPH
+0xEE7E	0x8559	#CJK UNIFIED IDEOGRAPH
+0xEE80	0x856B	#CJK UNIFIED IDEOGRAPH
+0xEE81	0xFA1F	#CJK COMPATIBILITY IDEOGRAPH
+0xEE82	0x85B0	#CJK UNIFIED IDEOGRAPH
+0xEE83	0xFA20	#CJK COMPATIBILITY IDEOGRAPH
+0xEE84	0xFA21	#CJK COMPATIBILITY IDEOGRAPH
+0xEE85	0x8807	#CJK UNIFIED IDEOGRAPH
+0xEE86	0x88F5	#CJK UNIFIED IDEOGRAPH
+0xEE87	0x8A12	#CJK UNIFIED IDEOGRAPH
+0xEE88	0x8A37	#CJK UNIFIED IDEOGRAPH
+0xEE89	0x8A79	#CJK UNIFIED IDEOGRAPH
+0xEE8A	0x8AA7	#CJK UNIFIED IDEOGRAPH
+0xEE8B	0x8ABE	#CJK UNIFIED IDEOGRAPH
+0xEE8C	0x8ADF	#CJK UNIFIED IDEOGRAPH
+0xEE8D	0xFA22	#CJK COMPATIBILITY IDEOGRAPH
+0xEE8E	0x8AF6	#CJK UNIFIED IDEOGRAPH
+0xEE8F	0x8B53	#CJK UNIFIED IDEOGRAPH
+0xEE90	0x8B7F	#CJK UNIFIED IDEOGRAPH
+0xEE91	0x8CF0	#CJK UNIFIED IDEOGRAPH
+0xEE92	0x8CF4	#CJK UNIFIED IDEOGRAPH
+0xEE93	0x8D12	#CJK UNIFIED IDEOGRAPH
+0xEE94	0x8D76	#CJK UNIFIED IDEOGRAPH
+0xEE95	0xFA23	#CJK COMPATIBILITY IDEOGRAPH
+0xEE96	0x8ECF	#CJK UNIFIED IDEOGRAPH
+0xEE97	0xFA24	#CJK COMPATIBILITY IDEOGRAPH
+0xEE98	0xFA25	#CJK COMPATIBILITY IDEOGRAPH
+0xEE99	0x9067	#CJK UNIFIED IDEOGRAPH
+0xEE9A	0x90DE	#CJK UNIFIED IDEOGRAPH
+0xEE9B	0xFA26	#CJK COMPATIBILITY IDEOGRAPH
+0xEE9C	0x9115	#CJK UNIFIED IDEOGRAPH
+0xEE9D	0x9127	#CJK UNIFIED IDEOGRAPH
+0xEE9E	0x91DA	#CJK UNIFIED IDEOGRAPH
+0xEE9F	0x91D7	#CJK UNIFIED IDEOGRAPH
+0xEEA0	0x91DE	#CJK UNIFIED IDEOGRAPH
+0xEEA1	0x91ED	#CJK UNIFIED IDEOGRAPH
+0xEEA2	0x91EE	#CJK UNIFIED IDEOGRAPH
+0xEEA3	0x91E4	#CJK UNIFIED IDEOGRAPH
+0xEEA4	0x91E5	#CJK UNIFIED IDEOGRAPH
+0xEEA5	0x9206	#CJK UNIFIED IDEOGRAPH
+0xEEA6	0x9210	#CJK UNIFIED IDEOGRAPH
+0xEEA7	0x920A	#CJK UNIFIED IDEOGRAPH
+0xEEA8	0x923A	#CJK UNIFIED IDEOGRAPH
+0xEEA9	0x9240	#CJK UNIFIED IDEOGRAPH
+0xEEAA	0x923C	#CJK UNIFIED IDEOGRAPH
+0xEEAB	0x924E	#CJK UNIFIED IDEOGRAPH
+0xEEAC	0x9259	#CJK UNIFIED IDEOGRAPH
+0xEEAD	0x9251	#CJK UNIFIED IDEOGRAPH
+0xEEAE	0x9239	#CJK UNIFIED IDEOGRAPH
+0xEEAF	0x9267	#CJK UNIFIED IDEOGRAPH
+0xEEB0	0x92A7	#CJK UNIFIED IDEOGRAPH
+0xEEB1	0x9277	#CJK UNIFIED IDEOGRAPH
+0xEEB2	0x9278	#CJK UNIFIED IDEOGRAPH
+0xEEB3	0x92E7	#CJK UNIFIED IDEOGRAPH
+0xEEB4	0x92D7	#CJK UNIFIED IDEOGRAPH
+0xEEB5	0x92D9	#CJK UNIFIED IDEOGRAPH
+0xEEB6	0x92D0	#CJK UNIFIED IDEOGRAPH
+0xEEB7	0xFA27	#CJK COMPATIBILITY IDEOGRAPH
+0xEEB8	0x92D5	#CJK UNIFIED IDEOGRAPH
+0xEEB9	0x92E0	#CJK UNIFIED IDEOGRAPH
+0xEEBA	0x92D3	#CJK UNIFIED IDEOGRAPH
+0xEEBB	0x9325	#CJK UNIFIED IDEOGRAPH
+0xEEBC	0x9321	#CJK UNIFIED IDEOGRAPH
+0xEEBD	0x92FB	#CJK UNIFIED IDEOGRAPH
+0xEEBE	0xFA28	#CJK COMPATIBILITY IDEOGRAPH
+0xEEBF	0x931E	#CJK UNIFIED IDEOGRAPH
+0xEEC0	0x92FF	#CJK UNIFIED IDEOGRAPH
+0xEEC1	0x931D	#CJK UNIFIED IDEOGRAPH
+0xEEC2	0x9302	#CJK UNIFIED IDEOGRAPH
+0xEEC3	0x9370	#CJK UNIFIED IDEOGRAPH
+0xEEC4	0x9357	#CJK UNIFIED IDEOGRAPH
+0xEEC5	0x93A4	#CJK UNIFIED IDEOGRAPH
+0xEEC6	0x93C6	#CJK UNIFIED IDEOGRAPH
+0xEEC7	0x93DE	#CJK UNIFIED IDEOGRAPH
+0xEEC8	0x93F8	#CJK UNIFIED IDEOGRAPH
+0xEEC9	0x9431	#CJK UNIFIED IDEOGRAPH
+0xEECA	0x9445	#CJK UNIFIED IDEOGRAPH
+0xEECB	0x9448	#CJK UNIFIED IDEOGRAPH
+0xEECC	0x9592	#CJK UNIFIED IDEOGRAPH
+0xEECD	0xF9DC	#CJK COMPATIBILITY IDEOGRAPH
+0xEECE	0xFA29	#CJK COMPATIBILITY IDEOGRAPH
+0xEECF	0x969D	#CJK UNIFIED IDEOGRAPH
+0xEED0	0x96AF	#CJK UNIFIED IDEOGRAPH
+0xEED1	0x9733	#CJK UNIFIED IDEOGRAPH
+0xEED2	0x973B	#CJK UNIFIED IDEOGRAPH
+0xEED3	0x9743	#CJK UNIFIED IDEOGRAPH
+0xEED4	0x974D	#CJK UNIFIED IDEOGRAPH
+0xEED5	0x974F	#CJK UNIFIED IDEOGRAPH
+0xEED6	0x9751	#CJK UNIFIED IDEOGRAPH
+0xEED7	0x9755	#CJK UNIFIED IDEOGRAPH
+0xEED8	0x9857	#CJK UNIFIED IDEOGRAPH
+0xEED9	0x9865	#CJK UNIFIED IDEOGRAPH
+0xEEDA	0xFA2A	#CJK COMPATIBILITY IDEOGRAPH
+0xEEDB	0xFA2B	#CJK COMPATIBILITY IDEOGRAPH
+0xEEDC	0x9927	#CJK UNIFIED IDEOGRAPH
+0xEEDD	0xFA2C	#CJK COMPATIBILITY IDEOGRAPH
+0xEEDE	0x999E	#CJK UNIFIED IDEOGRAPH
+0xEEDF	0x9A4E	#CJK UNIFIED IDEOGRAPH
+0xEEE0	0x9AD9	#CJK UNIFIED IDEOGRAPH
+0xEEE1	0x9ADC	#CJK UNIFIED IDEOGRAPH
+0xEEE2	0x9B75	#CJK UNIFIED IDEOGRAPH
+0xEEE3	0x9B72	#CJK UNIFIED IDEOGRAPH
+0xEEE4	0x9B8F	#CJK UNIFIED IDEOGRAPH
+0xEEE5	0x9BB1	#CJK UNIFIED IDEOGRAPH
+0xEEE6	0x9BBB	#CJK UNIFIED IDEOGRAPH
+0xEEE7	0x9C00	#CJK UNIFIED IDEOGRAPH
+0xEEE8	0x9D70	#CJK UNIFIED IDEOGRAPH
+0xEEE9	0x9D6B	#CJK UNIFIED IDEOGRAPH
+0xEEEA	0xFA2D	#CJK COMPATIBILITY IDEOGRAPH
+0xEEEB	0x9E19	#CJK UNIFIED IDEOGRAPH
+0xEEEC	0x9ED1	#CJK UNIFIED IDEOGRAPH
+0xEEEF	0x2170	#SMALL ROMAN NUMERAL ONE
+0xEEF0	0x2171	#SMALL ROMAN NUMERAL TWO
+0xEEF1	0x2172	#SMALL ROMAN NUMERAL THREE
+0xEEF2	0x2173	#SMALL ROMAN NUMERAL FOUR
+0xEEF3	0x2174	#SMALL ROMAN NUMERAL FIVE
+0xEEF4	0x2175	#SMALL ROMAN NUMERAL SIX
+0xEEF5	0x2176	#SMALL ROMAN NUMERAL SEVEN
+0xEEF6	0x2177	#SMALL ROMAN NUMERAL EIGHT
+0xEEF7	0x2178	#SMALL ROMAN NUMERAL NINE
+0xEEF8	0x2179	#SMALL ROMAN NUMERAL TEN
+0xEEF9	0xFFE2	#FULLWIDTH NOT SIGN
+0xEEFA	0xFFE4	#FULLWIDTH BROKEN BAR
+0xEEFB	0xFF07	#FULLWIDTH APOSTROPHE
+0xEEFC	0xFF02	#FULLWIDTH QUOTATION MARK
+0xFA40	0x2170	#SMALL ROMAN NUMERAL ONE
+0xFA41	0x2171	#SMALL ROMAN NUMERAL TWO
+0xFA42	0x2172	#SMALL ROMAN NUMERAL THREE
+0xFA43	0x2173	#SMALL ROMAN NUMERAL FOUR
+0xFA44	0x2174	#SMALL ROMAN NUMERAL FIVE
+0xFA45	0x2175	#SMALL ROMAN NUMERAL SIX
+0xFA46	0x2176	#SMALL ROMAN NUMERAL SEVEN
+0xFA47	0x2177	#SMALL ROMAN NUMERAL EIGHT
+0xFA48	0x2178	#SMALL ROMAN NUMERAL NINE
+0xFA49	0x2179	#SMALL ROMAN NUMERAL TEN
+0xFA4A	0x2160	#ROMAN NUMERAL ONE
+0xFA4B	0x2161	#ROMAN NUMERAL TWO
+0xFA4C	0x2162	#ROMAN NUMERAL THREE
+0xFA4D	0x2163	#ROMAN NUMERAL FOUR
+0xFA4E	0x2164	#ROMAN NUMERAL FIVE
+0xFA4F	0x2165	#ROMAN NUMERAL SIX
+0xFA50	0x2166	#ROMAN NUMERAL SEVEN
+0xFA51	0x2167	#ROMAN NUMERAL EIGHT
+0xFA52	0x2168	#ROMAN NUMERAL NINE
+0xFA53	0x2169	#ROMAN NUMERAL TEN
+0xFA54	0xFFE2	#FULLWIDTH NOT SIGN
+0xFA55	0xFFE4	#FULLWIDTH BROKEN BAR
+0xFA56	0xFF07	#FULLWIDTH APOSTROPHE
+0xFA57	0xFF02	#FULLWIDTH QUOTATION MARK
+0xFA58	0x3231	#PARENTHESIZED IDEOGRAPH STOCK
+0xFA59	0x2116	#NUMERO SIGN
+0xFA5A	0x2121	#TELEPHONE SIGN
+0xFA5B	0x2235	#BECAUSE
+0xFA5C	0x7E8A	#CJK UNIFIED IDEOGRAPH
+0xFA5D	0x891C	#CJK UNIFIED IDEOGRAPH
+0xFA5E	0x9348	#CJK UNIFIED IDEOGRAPH
+0xFA5F	0x9288	#CJK UNIFIED IDEOGRAPH
+0xFA60	0x84DC	#CJK UNIFIED IDEOGRAPH
+0xFA61	0x4FC9	#CJK UNIFIED IDEOGRAPH
+0xFA62	0x70BB	#CJK UNIFIED IDEOGRAPH
+0xFA63	0x6631	#CJK UNIFIED IDEOGRAPH
+0xFA64	0x68C8	#CJK UNIFIED IDEOGRAPH
+0xFA65	0x92F9	#CJK UNIFIED IDEOGRAPH
+0xFA66	0x66FB	#CJK UNIFIED IDEOGRAPH
+0xFA67	0x5F45	#CJK UNIFIED IDEOGRAPH
+0xFA68	0x4E28	#CJK UNIFIED IDEOGRAPH
+0xFA69	0x4EE1	#CJK UNIFIED IDEOGRAPH
+0xFA6A	0x4EFC	#CJK UNIFIED IDEOGRAPH
+0xFA6B	0x4F00	#CJK UNIFIED IDEOGRAPH
+0xFA6C	0x4F03	#CJK UNIFIED IDEOGRAPH
+0xFA6D	0x4F39	#CJK UNIFIED IDEOGRAPH
+0xFA6E	0x4F56	#CJK UNIFIED IDEOGRAPH
+0xFA6F	0x4F92	#CJK UNIFIED IDEOGRAPH
+0xFA70	0x4F8A	#CJK UNIFIED IDEOGRAPH
+0xFA71	0x4F9A	#CJK UNIFIED IDEOGRAPH
+0xFA72	0x4F94	#CJK UNIFIED IDEOGRAPH
+0xFA73	0x4FCD	#CJK UNIFIED IDEOGRAPH
+0xFA74	0x5040	#CJK UNIFIED IDEOGRAPH
+0xFA75	0x5022	#CJK UNIFIED IDEOGRAPH
+0xFA76	0x4FFF	#CJK UNIFIED IDEOGRAPH
+0xFA77	0x501E	#CJK UNIFIED IDEOGRAPH
+0xFA78	0x5046	#CJK UNIFIED IDEOGRAPH
+0xFA79	0x5070	#CJK UNIFIED IDEOGRAPH
+0xFA7A	0x5042	#CJK UNIFIED IDEOGRAPH
+0xFA7B	0x5094	#CJK UNIFIED IDEOGRAPH
+0xFA7C	0x50F4	#CJK UNIFIED IDEOGRAPH
+0xFA7D	0x50D8	#CJK UNIFIED IDEOGRAPH
+0xFA7E	0x514A	#CJK UNIFIED IDEOGRAPH
+0xFA80	0x5164	#CJK UNIFIED IDEOGRAPH
+0xFA81	0x519D	#CJK UNIFIED IDEOGRAPH
+0xFA82	0x51BE	#CJK UNIFIED IDEOGRAPH
+0xFA83	0x51EC	#CJK UNIFIED IDEOGRAPH
+0xFA84	0x5215	#CJK UNIFIED IDEOGRAPH
+0xFA85	0x529C	#CJK UNIFIED IDEOGRAPH
+0xFA86	0x52A6	#CJK UNIFIED IDEOGRAPH
+0xFA87	0x52C0	#CJK UNIFIED IDEOGRAPH
+0xFA88	0x52DB	#CJK UNIFIED IDEOGRAPH
+0xFA89	0x5300	#CJK UNIFIED IDEOGRAPH
+0xFA8A	0x5307	#CJK UNIFIED IDEOGRAPH
+0xFA8B	0x5324	#CJK UNIFIED IDEOGRAPH
+0xFA8C	0x5372	#CJK UNIFIED IDEOGRAPH
+0xFA8D	0x5393	#CJK UNIFIED IDEOGRAPH
+0xFA8E	0x53B2	#CJK UNIFIED IDEOGRAPH
+0xFA8F	0x53DD	#CJK UNIFIED IDEOGRAPH
+0xFA90	0xFA0E	#CJK COMPATIBILITY IDEOGRAPH
+0xFA91	0x549C	#CJK UNIFIED IDEOGRAPH
+0xFA92	0x548A	#CJK UNIFIED IDEOGRAPH
+0xFA93	0x54A9	#CJK UNIFIED IDEOGRAPH
+0xFA94	0x54FF	#CJK UNIFIED IDEOGRAPH
+0xFA95	0x5586	#CJK UNIFIED IDEOGRAPH
+0xFA96	0x5759	#CJK UNIFIED IDEOGRAPH
+0xFA97	0x5765	#CJK UNIFIED IDEOGRAPH
+0xFA98	0x57AC	#CJK UNIFIED IDEOGRAPH
+0xFA99	0x57C8	#CJK UNIFIED IDEOGRAPH
+0xFA9A	0x57C7	#CJK UNIFIED IDEOGRAPH
+0xFA9B	0xFA0F	#CJK COMPATIBILITY IDEOGRAPH
+0xFA9C	0xFA10	#CJK COMPATIBILITY IDEOGRAPH
+0xFA9D	0x589E	#CJK UNIFIED IDEOGRAPH
+0xFA9E	0x58B2	#CJK UNIFIED IDEOGRAPH
+0xFA9F	0x590B	#CJK UNIFIED IDEOGRAPH
+0xFAA0	0x5953	#CJK UNIFIED IDEOGRAPH
+0xFAA1	0x595B	#CJK UNIFIED IDEOGRAPH
+0xFAA2	0x595D	#CJK UNIFIED IDEOGRAPH
+0xFAA3	0x5963	#CJK UNIFIED IDEOGRAPH
+0xFAA4	0x59A4	#CJK UNIFIED IDEOGRAPH
+0xFAA5	0x59BA	#CJK UNIFIED IDEOGRAPH
+0xFAA6	0x5B56	#CJK UNIFIED IDEOGRAPH
+0xFAA7	0x5BC0	#CJK UNIFIED IDEOGRAPH
+0xFAA8	0x752F	#CJK UNIFIED IDEOGRAPH
+0xFAA9	0x5BD8	#CJK UNIFIED IDEOGRAPH
+0xFAAA	0x5BEC	#CJK UNIFIED IDEOGRAPH
+0xFAAB	0x5C1E	#CJK UNIFIED IDEOGRAPH
+0xFAAC	0x5CA6	#CJK UNIFIED IDEOGRAPH
+0xFAAD	0x5CBA	#CJK UNIFIED IDEOGRAPH
+0xFAAE	0x5CF5	#CJK UNIFIED IDEOGRAPH
+0xFAAF	0x5D27	#CJK UNIFIED IDEOGRAPH
+0xFAB0	0x5D53	#CJK UNIFIED IDEOGRAPH
+0xFAB1	0xFA11	#CJK COMPATIBILITY IDEOGRAPH
+0xFAB2	0x5D42	#CJK UNIFIED IDEOGRAPH
+0xFAB3	0x5D6D	#CJK UNIFIED IDEOGRAPH
+0xFAB4	0x5DB8	#CJK UNIFIED IDEOGRAPH
+0xFAB5	0x5DB9	#CJK UNIFIED IDEOGRAPH
+0xFAB6	0x5DD0	#CJK UNIFIED IDEOGRAPH
+0xFAB7	0x5F21	#CJK UNIFIED IDEOGRAPH
+0xFAB8	0x5F34	#CJK UNIFIED IDEOGRAPH
+0xFAB9	0x5F67	#CJK UNIFIED IDEOGRAPH
+0xFABA	0x5FB7	#CJK UNIFIED IDEOGRAPH
+0xFABB	0x5FDE	#CJK UNIFIED IDEOGRAPH
+0xFABC	0x605D	#CJK UNIFIED IDEOGRAPH
+0xFABD	0x6085	#CJK UNIFIED IDEOGRAPH
+0xFABE	0x608A	#CJK UNIFIED IDEOGRAPH
+0xFABF	0x60DE	#CJK UNIFIED IDEOGRAPH
+0xFAC0	0x60D5	#CJK UNIFIED IDEOGRAPH
+0xFAC1	0x6120	#CJK UNIFIED IDEOGRAPH
+0xFAC2	0x60F2	#CJK UNIFIED IDEOGRAPH
+0xFAC3	0x6111	#CJK UNIFIED IDEOGRAPH
+0xFAC4	0x6137	#CJK UNIFIED IDEOGRAPH
+0xFAC5	0x6130	#CJK UNIFIED IDEOGRAPH
+0xFAC6	0x6198	#CJK UNIFIED IDEOGRAPH
+0xFAC7	0x6213	#CJK UNIFIED IDEOGRAPH
+0xFAC8	0x62A6	#CJK UNIFIED IDEOGRAPH
+0xFAC9	0x63F5	#CJK UNIFIED IDEOGRAPH
+0xFACA	0x6460	#CJK UNIFIED IDEOGRAPH
+0xFACB	0x649D	#CJK UNIFIED IDEOGRAPH
+0xFACC	0x64CE	#CJK UNIFIED IDEOGRAPH
+0xFACD	0x654E	#CJK UNIFIED IDEOGRAPH
+0xFACE	0x6600	#CJK UNIFIED IDEOGRAPH
+0xFACF	0x6615	#CJK UNIFIED IDEOGRAPH
+0xFAD0	0x663B	#CJK UNIFIED IDEOGRAPH
+0xFAD1	0x6609	#CJK UNIFIED IDEOGRAPH
+0xFAD2	0x662E	#CJK UNIFIED IDEOGRAPH
+0xFAD3	0x661E	#CJK UNIFIED IDEOGRAPH
+0xFAD4	0x6624	#CJK UNIFIED IDEOGRAPH
+0xFAD5	0x6665	#CJK UNIFIED IDEOGRAPH
+0xFAD6	0x6657	#CJK UNIFIED IDEOGRAPH
+0xFAD7	0x6659	#CJK UNIFIED IDEOGRAPH
+0xFAD8	0xFA12	#CJK COMPATIBILITY IDEOGRAPH
+0xFAD9	0x6673	#CJK UNIFIED IDEOGRAPH
+0xFADA	0x6699	#CJK UNIFIED IDEOGRAPH
+0xFADB	0x66A0	#CJK UNIFIED IDEOGRAPH
+0xFADC	0x66B2	#CJK UNIFIED IDEOGRAPH
+0xFADD	0x66BF	#CJK UNIFIED IDEOGRAPH
+0xFADE	0x66FA	#CJK UNIFIED IDEOGRAPH
+0xFADF	0x670E	#CJK UNIFIED IDEOGRAPH
+0xFAE0	0xF929	#CJK COMPATIBILITY IDEOGRAPH
+0xFAE1	0x6766	#CJK UNIFIED IDEOGRAPH
+0xFAE2	0x67BB	#CJK UNIFIED IDEOGRAPH
+0xFAE3	0x6852	#CJK UNIFIED IDEOGRAPH
+0xFAE4	0x67C0	#CJK UNIFIED IDEOGRAPH
+0xFAE5	0x6801	#CJK UNIFIED IDEOGRAPH
+0xFAE6	0x6844	#CJK UNIFIED IDEOGRAPH
+0xFAE7	0x68CF	#CJK UNIFIED IDEOGRAPH
+0xFAE8	0xFA13	#CJK COMPATIBILITY IDEOGRAPH
+0xFAE9	0x6968	#CJK UNIFIED IDEOGRAPH
+0xFAEA	0xFA14	#CJK COMPATIBILITY IDEOGRAPH
+0xFAEB	0x6998	#CJK UNIFIED IDEOGRAPH
+0xFAEC	0x69E2	#CJK UNIFIED IDEOGRAPH
+0xFAED	0x6A30	#CJK UNIFIED IDEOGRAPH
+0xFAEE	0x6A6B	#CJK UNIFIED IDEOGRAPH
+0xFAEF	0x6A46	#CJK UNIFIED IDEOGRAPH
+0xFAF0	0x6A73	#CJK UNIFIED IDEOGRAPH
+0xFAF1	0x6A7E	#CJK UNIFIED IDEOGRAPH
+0xFAF2	0x6AE2	#CJK UNIFIED IDEOGRAPH
+0xFAF3	0x6AE4	#CJK UNIFIED IDEOGRAPH
+0xFAF4	0x6BD6	#CJK UNIFIED IDEOGRAPH
+0xFAF5	0x6C3F	#CJK UNIFIED IDEOGRAPH
+0xFAF6	0x6C5C	#CJK UNIFIED IDEOGRAPH
+0xFAF7	0x6C86	#CJK UNIFIED IDEOGRAPH
+0xFAF8	0x6C6F	#CJK UNIFIED IDEOGRAPH
+0xFAF9	0x6CDA	#CJK UNIFIED IDEOGRAPH
+0xFAFA	0x6D04	#CJK UNIFIED IDEOGRAPH
+0xFAFB	0x6D87	#CJK UNIFIED IDEOGRAPH
+0xFAFC	0x6D6F	#CJK UNIFIED IDEOGRAPH
+0xFB40	0x6D96	#CJK UNIFIED IDEOGRAPH
+0xFB41	0x6DAC	#CJK UNIFIED IDEOGRAPH
+0xFB42	0x6DCF	#CJK UNIFIED IDEOGRAPH
+0xFB43	0x6DF8	#CJK UNIFIED IDEOGRAPH
+0xFB44	0x6DF2	#CJK UNIFIED IDEOGRAPH
+0xFB45	0x6DFC	#CJK UNIFIED IDEOGRAPH
+0xFB46	0x6E39	#CJK UNIFIED IDEOGRAPH
+0xFB47	0x6E5C	#CJK UNIFIED IDEOGRAPH
+0xFB48	0x6E27	#CJK UNIFIED IDEOGRAPH
+0xFB49	0x6E3C	#CJK UNIFIED IDEOGRAPH
+0xFB4A	0x6EBF	#CJK UNIFIED IDEOGRAPH
+0xFB4B	0x6F88	#CJK UNIFIED IDEOGRAPH
+0xFB4C	0x6FB5	#CJK UNIFIED IDEOGRAPH
+0xFB4D	0x6FF5	#CJK UNIFIED IDEOGRAPH
+0xFB4E	0x7005	#CJK UNIFIED IDEOGRAPH
+0xFB4F	0x7007	#CJK UNIFIED IDEOGRAPH
+0xFB50	0x7028	#CJK UNIFIED IDEOGRAPH
+0xFB51	0x7085	#CJK UNIFIED IDEOGRAPH
+0xFB52	0x70AB	#CJK UNIFIED IDEOGRAPH
+0xFB53	0x710F	#CJK UNIFIED IDEOGRAPH
+0xFB54	0x7104	#CJK UNIFIED IDEOGRAPH
+0xFB55	0x715C	#CJK UNIFIED IDEOGRAPH
+0xFB56	0x7146	#CJK UNIFIED IDEOGRAPH
+0xFB57	0x7147	#CJK UNIFIED IDEOGRAPH
+0xFB58	0xFA15	#CJK COMPATIBILITY IDEOGRAPH
+0xFB59	0x71C1	#CJK UNIFIED IDEOGRAPH
+0xFB5A	0x71FE	#CJK UNIFIED IDEOGRAPH
+0xFB5B	0x72B1	#CJK UNIFIED IDEOGRAPH
+0xFB5C	0x72BE	#CJK UNIFIED IDEOGRAPH
+0xFB5D	0x7324	#CJK UNIFIED IDEOGRAPH
+0xFB5E	0xFA16	#CJK COMPATIBILITY IDEOGRAPH
+0xFB5F	0x7377	#CJK UNIFIED IDEOGRAPH
+0xFB60	0x73BD	#CJK UNIFIED IDEOGRAPH
+0xFB61	0x73C9	#CJK UNIFIED IDEOGRAPH
+0xFB62	0x73D6	#CJK UNIFIED IDEOGRAPH
+0xFB63	0x73E3	#CJK UNIFIED IDEOGRAPH
+0xFB64	0x73D2	#CJK UNIFIED IDEOGRAPH
+0xFB65	0x7407	#CJK UNIFIED IDEOGRAPH
+0xFB66	0x73F5	#CJK UNIFIED IDEOGRAPH
+0xFB67	0x7426	#CJK UNIFIED IDEOGRAPH
+0xFB68	0x742A	#CJK UNIFIED IDEOGRAPH
+0xFB69	0x7429	#CJK UNIFIED IDEOGRAPH
+0xFB6A	0x742E	#CJK UNIFIED IDEOGRAPH
+0xFB6B	0x7462	#CJK UNIFIED IDEOGRAPH
+0xFB6C	0x7489	#CJK UNIFIED IDEOGRAPH
+0xFB6D	0x749F	#CJK UNIFIED IDEOGRAPH
+0xFB6E	0x7501	#CJK UNIFIED IDEOGRAPH
+0xFB6F	0x756F	#CJK UNIFIED IDEOGRAPH
+0xFB70	0x7682	#CJK UNIFIED IDEOGRAPH
+0xFB71	0x769C	#CJK UNIFIED IDEOGRAPH
+0xFB72	0x769E	#CJK UNIFIED IDEOGRAPH
+0xFB73	0x769B	#CJK UNIFIED IDEOGRAPH
+0xFB74	0x76A6	#CJK UNIFIED IDEOGRAPH
+0xFB75	0xFA17	#CJK COMPATIBILITY IDEOGRAPH
+0xFB76	0x7746	#CJK UNIFIED IDEOGRAPH
+0xFB77	0x52AF	#CJK UNIFIED IDEOGRAPH
+0xFB78	0x7821	#CJK UNIFIED IDEOGRAPH
+0xFB79	0x784E	#CJK UNIFIED IDEOGRAPH
+0xFB7A	0x7864	#CJK UNIFIED IDEOGRAPH
+0xFB7B	0x787A	#CJK UNIFIED IDEOGRAPH
+0xFB7C	0x7930	#CJK UNIFIED IDEOGRAPH
+0xFB7D	0xFA18	#CJK COMPATIBILITY IDEOGRAPH
+0xFB7E	0xFA19	#CJK COMPATIBILITY IDEOGRAPH
+0xFB80	0xFA1A	#CJK COMPATIBILITY IDEOGRAPH
+0xFB81	0x7994	#CJK UNIFIED IDEOGRAPH
+0xFB82	0xFA1B	#CJK COMPATIBILITY IDEOGRAPH
+0xFB83	0x799B	#CJK UNIFIED IDEOGRAPH
+0xFB84	0x7AD1	#CJK UNIFIED IDEOGRAPH
+0xFB85	0x7AE7	#CJK UNIFIED IDEOGRAPH
+0xFB86	0xFA1C	#CJK COMPATIBILITY IDEOGRAPH
+0xFB87	0x7AEB	#CJK UNIFIED IDEOGRAPH
+0xFB88	0x7B9E	#CJK UNIFIED IDEOGRAPH
+0xFB89	0xFA1D	#CJK COMPATIBILITY IDEOGRAPH
+0xFB8A	0x7D48	#CJK UNIFIED IDEOGRAPH
+0xFB8B	0x7D5C	#CJK UNIFIED IDEOGRAPH
+0xFB8C	0x7DB7	#CJK UNIFIED IDEOGRAPH
+0xFB8D	0x7DA0	#CJK UNIFIED IDEOGRAPH
+0xFB8E	0x7DD6	#CJK UNIFIED IDEOGRAPH
+0xFB8F	0x7E52	#CJK UNIFIED IDEOGRAPH
+0xFB90	0x7F47	#CJK UNIFIED IDEOGRAPH
+0xFB91	0x7FA1	#CJK UNIFIED IDEOGRAPH
+0xFB92	0xFA1E	#CJK COMPATIBILITY IDEOGRAPH
+0xFB93	0x8301	#CJK UNIFIED IDEOGRAPH
+0xFB94	0x8362	#CJK UNIFIED IDEOGRAPH
+0xFB95	0x837F	#CJK UNIFIED IDEOGRAPH
+0xFB96	0x83C7	#CJK UNIFIED IDEOGRAPH
+0xFB97	0x83F6	#CJK UNIFIED IDEOGRAPH
+0xFB98	0x8448	#CJK UNIFIED IDEOGRAPH
+0xFB99	0x84B4	#CJK UNIFIED IDEOGRAPH
+0xFB9A	0x8553	#CJK UNIFIED IDEOGRAPH
+0xFB9B	0x8559	#CJK UNIFIED IDEOGRAPH
+0xFB9C	0x856B	#CJK UNIFIED IDEOGRAPH
+0xFB9D	0xFA1F	#CJK COMPATIBILITY IDEOGRAPH
+0xFB9E	0x85B0	#CJK UNIFIED IDEOGRAPH
+0xFB9F	0xFA20	#CJK COMPATIBILITY IDEOGRAPH
+0xFBA0	0xFA21	#CJK COMPATIBILITY IDEOGRAPH
+0xFBA1	0x8807	#CJK UNIFIED IDEOGRAPH
+0xFBA2	0x88F5	#CJK UNIFIED IDEOGRAPH
+0xFBA3	0x8A12	#CJK UNIFIED IDEOGRAPH
+0xFBA4	0x8A37	#CJK UNIFIED IDEOGRAPH
+0xFBA5	0x8A79	#CJK UNIFIED IDEOGRAPH
+0xFBA6	0x8AA7	#CJK UNIFIED IDEOGRAPH
+0xFBA7	0x8ABE	#CJK UNIFIED IDEOGRAPH
+0xFBA8	0x8ADF	#CJK UNIFIED IDEOGRAPH
+0xFBA9	0xFA22	#CJK COMPATIBILITY IDEOGRAPH
+0xFBAA	0x8AF6	#CJK UNIFIED IDEOGRAPH
+0xFBAB	0x8B53	#CJK UNIFIED IDEOGRAPH
+0xFBAC	0x8B7F	#CJK UNIFIED IDEOGRAPH
+0xFBAD	0x8CF0	#CJK UNIFIED IDEOGRAPH
+0xFBAE	0x8CF4	#CJK UNIFIED IDEOGRAPH
+0xFBAF	0x8D12	#CJK UNIFIED IDEOGRAPH
+0xFBB0	0x8D76	#CJK UNIFIED IDEOGRAPH
+0xFBB1	0xFA23	#CJK COMPATIBILITY IDEOGRAPH
+0xFBB2	0x8ECF	#CJK UNIFIED IDEOGRAPH
+0xFBB3	0xFA24	#CJK COMPATIBILITY IDEOGRAPH
+0xFBB4	0xFA25	#CJK COMPATIBILITY IDEOGRAPH
+0xFBB5	0x9067	#CJK UNIFIED IDEOGRAPH
+0xFBB6	0x90DE	#CJK UNIFIED IDEOGRAPH
+0xFBB7	0xFA26	#CJK COMPATIBILITY IDEOGRAPH
+0xFBB8	0x9115	#CJK UNIFIED IDEOGRAPH
+0xFBB9	0x9127	#CJK UNIFIED IDEOGRAPH
+0xFBBA	0x91DA	#CJK UNIFIED IDEOGRAPH
+0xFBBB	0x91D7	#CJK UNIFIED IDEOGRAPH
+0xFBBC	0x91DE	#CJK UNIFIED IDEOGRAPH
+0xFBBD	0x91ED	#CJK UNIFIED IDEOGRAPH
+0xFBBE	0x91EE	#CJK UNIFIED IDEOGRAPH
+0xFBBF	0x91E4	#CJK UNIFIED IDEOGRAPH
+0xFBC0	0x91E5	#CJK UNIFIED IDEOGRAPH
+0xFBC1	0x9206	#CJK UNIFIED IDEOGRAPH
+0xFBC2	0x9210	#CJK UNIFIED IDEOGRAPH
+0xFBC3	0x920A	#CJK UNIFIED IDEOGRAPH
+0xFBC4	0x923A	#CJK UNIFIED IDEOGRAPH
+0xFBC5	0x9240	#CJK UNIFIED IDEOGRAPH
+0xFBC6	0x923C	#CJK UNIFIED IDEOGRAPH
+0xFBC7	0x924E	#CJK UNIFIED IDEOGRAPH
+0xFBC8	0x9259	#CJK UNIFIED IDEOGRAPH
+0xFBC9	0x9251	#CJK UNIFIED IDEOGRAPH
+0xFBCA	0x9239	#CJK UNIFIED IDEOGRAPH
+0xFBCB	0x9267	#CJK UNIFIED IDEOGRAPH
+0xFBCC	0x92A7	#CJK UNIFIED IDEOGRAPH
+0xFBCD	0x9277	#CJK UNIFIED IDEOGRAPH
+0xFBCE	0x9278	#CJK UNIFIED IDEOGRAPH
+0xFBCF	0x92E7	#CJK UNIFIED IDEOGRAPH
+0xFBD0	0x92D7	#CJK UNIFIED IDEOGRAPH
+0xFBD1	0x92D9	#CJK UNIFIED IDEOGRAPH
+0xFBD2	0x92D0	#CJK UNIFIED IDEOGRAPH
+0xFBD3	0xFA27	#CJK COMPATIBILITY IDEOGRAPH
+0xFBD4	0x92D5	#CJK UNIFIED IDEOGRAPH
+0xFBD5	0x92E0	#CJK UNIFIED IDEOGRAPH
+0xFBD6	0x92D3	#CJK UNIFIED IDEOGRAPH
+0xFBD7	0x9325	#CJK UNIFIED IDEOGRAPH
+0xFBD8	0x9321	#CJK UNIFIED IDEOGRAPH
+0xFBD9	0x92FB	#CJK UNIFIED IDEOGRAPH
+0xFBDA	0xFA28	#CJK COMPATIBILITY IDEOGRAPH
+0xFBDB	0x931E	#CJK UNIFIED IDEOGRAPH
+0xFBDC	0x92FF	#CJK UNIFIED IDEOGRAPH
+0xFBDD	0x931D	#CJK UNIFIED IDEOGRAPH
+0xFBDE	0x9302	#CJK UNIFIED IDEOGRAPH
+0xFBDF	0x9370	#CJK UNIFIED IDEOGRAPH
+0xFBE0	0x9357	#CJK UNIFIED IDEOGRAPH
+0xFBE1	0x93A4	#CJK UNIFIED IDEOGRAPH
+0xFBE2	0x93C6	#CJK UNIFIED IDEOGRAPH
+0xFBE3	0x93DE	#CJK UNIFIED IDEOGRAPH
+0xFBE4	0x93F8	#CJK UNIFIED IDEOGRAPH
+0xFBE5	0x9431	#CJK UNIFIED IDEOGRAPH
+0xFBE6	0x9445	#CJK UNIFIED IDEOGRAPH
+0xFBE7	0x9448	#CJK UNIFIED IDEOGRAPH
+0xFBE8	0x9592	#CJK UNIFIED IDEOGRAPH
+0xFBE9	0xF9DC	#CJK COMPATIBILITY IDEOGRAPH
+0xFBEA	0xFA29	#CJK COMPATIBILITY IDEOGRAPH
+0xFBEB	0x969D	#CJK UNIFIED IDEOGRAPH
+0xFBEC	0x96AF	#CJK UNIFIED IDEOGRAPH
+0xFBED	0x9733	#CJK UNIFIED IDEOGRAPH
+0xFBEE	0x973B	#CJK UNIFIED IDEOGRAPH
+0xFBEF	0x9743	#CJK UNIFIED IDEOGRAPH
+0xFBF0	0x974D	#CJK UNIFIED IDEOGRAPH
+0xFBF1	0x974F	#CJK UNIFIED IDEOGRAPH
+0xFBF2	0x9751	#CJK UNIFIED IDEOGRAPH
+0xFBF3	0x9755	#CJK UNIFIED IDEOGRAPH
+0xFBF4	0x9857	#CJK UNIFIED IDEOGRAPH
+0xFBF5	0x9865	#CJK UNIFIED IDEOGRAPH
+0xFBF6	0xFA2A	#CJK COMPATIBILITY IDEOGRAPH
+0xFBF7	0xFA2B	#CJK COMPATIBILITY IDEOGRAPH
+0xFBF8	0x9927	#CJK UNIFIED IDEOGRAPH
+0xFBF9	0xFA2C	#CJK COMPATIBILITY IDEOGRAPH
+0xFBFA	0x999E	#CJK UNIFIED IDEOGRAPH
+0xFBFB	0x9A4E	#CJK UNIFIED IDEOGRAPH
+0xFBFC	0x9AD9	#CJK UNIFIED IDEOGRAPH
+0xFC40	0x9ADC	#CJK UNIFIED IDEOGRAPH
+0xFC41	0x9B75	#CJK UNIFIED IDEOGRAPH
+0xFC42	0x9B72	#CJK UNIFIED IDEOGRAPH
+0xFC43	0x9B8F	#CJK UNIFIED IDEOGRAPH
+0xFC44	0x9BB1	#CJK UNIFIED IDEOGRAPH
+0xFC45	0x9BBB	#CJK UNIFIED IDEOGRAPH
+0xFC46	0x9C00	#CJK UNIFIED IDEOGRAPH
+0xFC47	0x9D70	#CJK UNIFIED IDEOGRAPH
+0xFC48	0x9D6B	#CJK UNIFIED IDEOGRAPH
+0xFC49	0xFA2D	#CJK COMPATIBILITY IDEOGRAPH
+0xFC4A	0x9E19	#CJK UNIFIED IDEOGRAPH
+0xFC4B	0x9ED1	#CJK UNIFIED IDEOGRAPH
diff --git a/tools/encoding/cp936.txt b/tools/encoding/cp936.txt
new file mode 100644
index 0000000..66a541b
--- /dev/null
+++ b/tools/encoding/cp936.txt
@@ -0,0 +1,22065 @@
+#
+#    Name:     cp936 to Unicode table
+#    Unicode version: 2.0
+#    Table version: 2.01
+#    Table format:  Format A
+#    Date:          1/7/2000
+#
+#    Contact:       cpxlate@microsoft.com
+#
+#    General notes: none
+#
+#    Format: Three tab-separated columns
+#        Column #1 is the cp936 code (in hex)
+#        Column #2 is the Unicode (in hex as 0xXXXX)
+#        Column #3 is the Unicode name (follows a comment sign, '#')
+#
+#    The entries are in cp936 order
+#
+0x00	0x0000	#NULL
+0x01	0x0001	#START OF HEADING
+0x02	0x0002	#START OF TEXT
+0x03	0x0003	#END OF TEXT
+0x04	0x0004	#END OF TRANSMISSION
+0x05	0x0005	#ENQUIRY
+0x06	0x0006	#ACKNOWLEDGE
+0x07	0x0007	#BELL
+0x08	0x0008	#BACKSPACE
+0x09	0x0009	#HORIZONTAL TABULATION
+0x0A	0x000A	#LINE FEED
+0x0B	0x000B	#VERTICAL TABULATION
+0x0C	0x000C	#FORM FEED
+0x0D	0x000D	#CARRIAGE RETURN
+0x0E	0x000E	#SHIFT OUT
+0x0F	0x000F	#SHIFT IN
+0x10	0x0010	#DATA LINK ESCAPE
+0x11	0x0011	#DEVICE CONTROL ONE
+0x12	0x0012	#DEVICE CONTROL TWO
+0x13	0x0013	#DEVICE CONTROL THREE
+0x14	0x0014	#DEVICE CONTROL FOUR
+0x15	0x0015	#NEGATIVE ACKNOWLEDGE
+0x16	0x0016	#SYNCHRONOUS IDLE
+0x17	0x0017	#END OF TRANSMISSION BLOCK
+0x18	0x0018	#CANCEL
+0x19	0x0019	#END OF MEDIUM
+0x1A	0x001A	#SUBSTITUTE
+0x1B	0x001B	#ESCAPE
+0x1C	0x001C	#FILE SEPARATOR
+0x1D	0x001D	#GROUP SEPARATOR
+0x1E	0x001E	#RECORD SEPARATOR
+0x1F	0x001F	#UNIT SEPARATOR
+0x20	0x0020	#SPACE
+0x21	0x0021	#EXCLAMATION MARK
+0x22	0x0022	#QUOTATION MARK
+0x23	0x0023	#NUMBER SIGN
+0x24	0x0024	#DOLLAR SIGN
+0x25	0x0025	#PERCENT SIGN
+0x26	0x0026	#AMPERSAND
+0x27	0x0027	#APOSTROPHE
+0x28	0x0028	#LEFT PARENTHESIS
+0x29	0x0029	#RIGHT PARENTHESIS
+0x2A	0x002A	#ASTERISK
+0x2B	0x002B	#PLUS SIGN
+0x2C	0x002C	#COMMA
+0x2D	0x002D	#HYPHEN-MINUS
+0x2E	0x002E	#FULL STOP
+0x2F	0x002F	#SOLIDUS
+0x30	0x0030	#DIGIT ZERO
+0x31	0x0031	#DIGIT ONE
+0x32	0x0032	#DIGIT TWO
+0x33	0x0033	#DIGIT THREE
+0x34	0x0034	#DIGIT FOUR
+0x35	0x0035	#DIGIT FIVE
+0x36	0x0036	#DIGIT SIX
+0x37	0x0037	#DIGIT SEVEN
+0x38	0x0038	#DIGIT EIGHT
+0x39	0x0039	#DIGIT NINE
+0x3A	0x003A	#COLON
+0x3B	0x003B	#SEMICOLON
+0x3C	0x003C	#LESS-THAN SIGN
+0x3D	0x003D	#EQUALS SIGN
+0x3E	0x003E	#GREATER-THAN SIGN
+0x3F	0x003F	#QUESTION MARK
+0x40	0x0040	#COMMERCIAL AT
+0x41	0x0041	#LATIN CAPITAL LETTER A
+0x42	0x0042	#LATIN CAPITAL LETTER B
+0x43	0x0043	#LATIN CAPITAL LETTER C
+0x44	0x0044	#LATIN CAPITAL LETTER D
+0x45	0x0045	#LATIN CAPITAL LETTER E
+0x46	0x0046	#LATIN CAPITAL LETTER F
+0x47	0x0047	#LATIN CAPITAL LETTER G
+0x48	0x0048	#LATIN CAPITAL LETTER H
+0x49	0x0049	#LATIN CAPITAL LETTER I
+0x4A	0x004A	#LATIN CAPITAL LETTER J
+0x4B	0x004B	#LATIN CAPITAL LETTER K
+0x4C	0x004C	#LATIN CAPITAL LETTER L
+0x4D	0x004D	#LATIN CAPITAL LETTER M
+0x4E	0x004E	#LATIN CAPITAL LETTER N
+0x4F	0x004F	#LATIN CAPITAL LETTER O
+0x50	0x0050	#LATIN CAPITAL LETTER P
+0x51	0x0051	#LATIN CAPITAL LETTER Q
+0x52	0x0052	#LATIN CAPITAL LETTER R
+0x53	0x0053	#LATIN CAPITAL LETTER S
+0x54	0x0054	#LATIN CAPITAL LETTER T
+0x55	0x0055	#LATIN CAPITAL LETTER U
+0x56	0x0056	#LATIN CAPITAL LETTER V
+0x57	0x0057	#LATIN CAPITAL LETTER W
+0x58	0x0058	#LATIN CAPITAL LETTER X
+0x59	0x0059	#LATIN CAPITAL LETTER Y
+0x5A	0x005A	#LATIN CAPITAL LETTER Z
+0x5B	0x005B	#LEFT SQUARE BRACKET
+0x5C	0x005C	#REVERSE SOLIDUS
+0x5D	0x005D	#RIGHT SQUARE BRACKET
+0x5E	0x005E	#CIRCUMFLEX ACCENT
+0x5F	0x005F	#LOW LINE
+0x60	0x0060	#GRAVE ACCENT
+0x61	0x0061	#LATIN SMALL LETTER A
+0x62	0x0062	#LATIN SMALL LETTER B
+0x63	0x0063	#LATIN SMALL LETTER C
+0x64	0x0064	#LATIN SMALL LETTER D
+0x65	0x0065	#LATIN SMALL LETTER E
+0x66	0x0066	#LATIN SMALL LETTER F
+0x67	0x0067	#LATIN SMALL LETTER G
+0x68	0x0068	#LATIN SMALL LETTER H
+0x69	0x0069	#LATIN SMALL LETTER I
+0x6A	0x006A	#LATIN SMALL LETTER J
+0x6B	0x006B	#LATIN SMALL LETTER K
+0x6C	0x006C	#LATIN SMALL LETTER L
+0x6D	0x006D	#LATIN SMALL LETTER M
+0x6E	0x006E	#LATIN SMALL LETTER N
+0x6F	0x006F	#LATIN SMALL LETTER O
+0x70	0x0070	#LATIN SMALL LETTER P
+0x71	0x0071	#LATIN SMALL LETTER Q
+0x72	0x0072	#LATIN SMALL LETTER R
+0x73	0x0073	#LATIN SMALL LETTER S
+0x74	0x0074	#LATIN SMALL LETTER T
+0x75	0x0075	#LATIN SMALL LETTER U
+0x76	0x0076	#LATIN SMALL LETTER V
+0x77	0x0077	#LATIN SMALL LETTER W
+0x78	0x0078	#LATIN SMALL LETTER X
+0x79	0x0079	#LATIN SMALL LETTER Y
+0x7A	0x007A	#LATIN SMALL LETTER Z
+0x7B	0x007B	#LEFT CURLY BRACKET
+0x7C	0x007C	#VERTICAL LINE
+0x7D	0x007D	#RIGHT CURLY BRACKET
+0x7E	0x007E	#TILDE
+0x7F	0x007F	#DELETE
+0x80	0x20AC	#EURO SIGN
+0x81	      	#DBCS LEAD BYTE
+0x82	      	#DBCS LEAD BYTE
+0x83	      	#DBCS LEAD BYTE
+0x84	      	#DBCS LEAD BYTE
+0x85	      	#DBCS LEAD BYTE
+0x86	      	#DBCS LEAD BYTE
+0x87	      	#DBCS LEAD BYTE
+0x88	      	#DBCS LEAD BYTE
+0x89	      	#DBCS LEAD BYTE
+0x8A	      	#DBCS LEAD BYTE
+0x8B	      	#DBCS LEAD BYTE
+0x8C	      	#DBCS LEAD BYTE
+0x8D	      	#DBCS LEAD BYTE
+0x8E	      	#DBCS LEAD BYTE
+0x8F	      	#DBCS LEAD BYTE
+0x90	      	#DBCS LEAD BYTE
+0x91	      	#DBCS LEAD BYTE
+0x92	      	#DBCS LEAD BYTE
+0x93	      	#DBCS LEAD BYTE
+0x94	      	#DBCS LEAD BYTE
+0x95	      	#DBCS LEAD BYTE
+0x96	      	#DBCS LEAD BYTE
+0x97	      	#DBCS LEAD BYTE
+0x98	      	#DBCS LEAD BYTE
+0x99	      	#DBCS LEAD BYTE
+0x9A	      	#DBCS LEAD BYTE
+0x9B	      	#DBCS LEAD BYTE
+0x9C	      	#DBCS LEAD BYTE
+0x9D	      	#DBCS LEAD BYTE
+0x9E	      	#DBCS LEAD BYTE
+0x9F	      	#DBCS LEAD BYTE
+0xA0	      	#DBCS LEAD BYTE
+0xA1	      	#DBCS LEAD BYTE
+0xA2	      	#DBCS LEAD BYTE
+0xA3	      	#DBCS LEAD BYTE
+0xA4	      	#DBCS LEAD BYTE
+0xA5	      	#DBCS LEAD BYTE
+0xA6	      	#DBCS LEAD BYTE
+0xA7	      	#DBCS LEAD BYTE
+0xA8	      	#DBCS LEAD BYTE
+0xA9	      	#DBCS LEAD BYTE
+0xAA	      	#DBCS LEAD BYTE
+0xAB	      	#DBCS LEAD BYTE
+0xAC	      	#DBCS LEAD BYTE
+0xAD	      	#DBCS LEAD BYTE
+0xAE	      	#DBCS LEAD BYTE
+0xAF	      	#DBCS LEAD BYTE
+0xB0	      	#DBCS LEAD BYTE
+0xB1	      	#DBCS LEAD BYTE
+0xB2	      	#DBCS LEAD BYTE
+0xB3	      	#DBCS LEAD BYTE
+0xB4	      	#DBCS LEAD BYTE
+0xB5	      	#DBCS LEAD BYTE
+0xB6	      	#DBCS LEAD BYTE
+0xB7	      	#DBCS LEAD BYTE
+0xB8	      	#DBCS LEAD BYTE
+0xB9	      	#DBCS LEAD BYTE
+0xBA	      	#DBCS LEAD BYTE
+0xBB	      	#DBCS LEAD BYTE
+0xBC	      	#DBCS LEAD BYTE
+0xBD	      	#DBCS LEAD BYTE
+0xBE	      	#DBCS LEAD BYTE
+0xBF	      	#DBCS LEAD BYTE
+0xC0	      	#DBCS LEAD BYTE
+0xC1	      	#DBCS LEAD BYTE
+0xC2	      	#DBCS LEAD BYTE
+0xC3	      	#DBCS LEAD BYTE
+0xC4	      	#DBCS LEAD BYTE
+0xC5	      	#DBCS LEAD BYTE
+0xC6	      	#DBCS LEAD BYTE
+0xC7	      	#DBCS LEAD BYTE
+0xC8	      	#DBCS LEAD BYTE
+0xC9	      	#DBCS LEAD BYTE
+0xCA	      	#DBCS LEAD BYTE
+0xCB	      	#DBCS LEAD BYTE
+0xCC	      	#DBCS LEAD BYTE
+0xCD	      	#DBCS LEAD BYTE
+0xCE	      	#DBCS LEAD BYTE
+0xCF	      	#DBCS LEAD BYTE
+0xD0	      	#DBCS LEAD BYTE
+0xD1	      	#DBCS LEAD BYTE
+0xD2	      	#DBCS LEAD BYTE
+0xD3	      	#DBCS LEAD BYTE
+0xD4	      	#DBCS LEAD BYTE
+0xD5	      	#DBCS LEAD BYTE
+0xD6	      	#DBCS LEAD BYTE
+0xD7	      	#DBCS LEAD BYTE
+0xD8	      	#DBCS LEAD BYTE
+0xD9	      	#DBCS LEAD BYTE
+0xDA	      	#DBCS LEAD BYTE
+0xDB	      	#DBCS LEAD BYTE
+0xDC	      	#DBCS LEAD BYTE
+0xDD	      	#DBCS LEAD BYTE
+0xDE	      	#DBCS LEAD BYTE
+0xDF	      	#DBCS LEAD BYTE
+0xE0	      	#DBCS LEAD BYTE
+0xE1	      	#DBCS LEAD BYTE
+0xE2	      	#DBCS LEAD BYTE
+0xE3	      	#DBCS LEAD BYTE
+0xE4	      	#DBCS LEAD BYTE
+0xE5	      	#DBCS LEAD BYTE
+0xE6	      	#DBCS LEAD BYTE
+0xE7	      	#DBCS LEAD BYTE
+0xE8	      	#DBCS LEAD BYTE
+0xE9	      	#DBCS LEAD BYTE
+0xEA	      	#DBCS LEAD BYTE
+0xEB	      	#DBCS LEAD BYTE
+0xEC	      	#DBCS LEAD BYTE
+0xED	      	#DBCS LEAD BYTE
+0xEE	      	#DBCS LEAD BYTE
+0xEF	      	#DBCS LEAD BYTE
+0xF0	      	#DBCS LEAD BYTE
+0xF1	      	#DBCS LEAD BYTE
+0xF2	      	#DBCS LEAD BYTE
+0xF3	      	#DBCS LEAD BYTE
+0xF4	      	#DBCS LEAD BYTE
+0xF5	      	#DBCS LEAD BYTE
+0xF6	      	#DBCS LEAD BYTE
+0xF7	      	#DBCS LEAD BYTE
+0xF8	      	#DBCS LEAD BYTE
+0xF9	      	#DBCS LEAD BYTE
+0xFA	      	#DBCS LEAD BYTE
+0xFB	      	#DBCS LEAD BYTE
+0xFC	      	#DBCS LEAD BYTE
+0xFD	      	#DBCS LEAD BYTE
+0xFE	      	#DBCS LEAD BYTE
+0xFF	      	#UNDEFINED
+0x8140	0x4E02	#CJK UNIFIED IDEOGRAPH
+0x8141	0x4E04	#CJK UNIFIED IDEOGRAPH
+0x8142	0x4E05	#CJK UNIFIED IDEOGRAPH
+0x8143	0x4E06	#CJK UNIFIED IDEOGRAPH
+0x8144	0x4E0F	#CJK UNIFIED IDEOGRAPH
+0x8145	0x4E12	#CJK UNIFIED IDEOGRAPH
+0x8146	0x4E17	#CJK UNIFIED IDEOGRAPH
+0x8147	0x4E1F	#CJK UNIFIED IDEOGRAPH
+0x8148	0x4E20	#CJK UNIFIED IDEOGRAPH
+0x8149	0x4E21	#CJK UNIFIED IDEOGRAPH
+0x814A	0x4E23	#CJK UNIFIED IDEOGRAPH
+0x814B	0x4E26	#CJK UNIFIED IDEOGRAPH
+0x814C	0x4E29	#CJK UNIFIED IDEOGRAPH
+0x814D	0x4E2E	#CJK UNIFIED IDEOGRAPH
+0x814E	0x4E2F	#CJK UNIFIED IDEOGRAPH
+0x814F	0x4E31	#CJK UNIFIED IDEOGRAPH
+0x8150	0x4E33	#CJK UNIFIED IDEOGRAPH
+0x8151	0x4E35	#CJK UNIFIED IDEOGRAPH
+0x8152	0x4E37	#CJK UNIFIED IDEOGRAPH
+0x8153	0x4E3C	#CJK UNIFIED IDEOGRAPH
+0x8154	0x4E40	#CJK UNIFIED IDEOGRAPH
+0x8155	0x4E41	#CJK UNIFIED IDEOGRAPH
+0x8156	0x4E42	#CJK UNIFIED IDEOGRAPH
+0x8157	0x4E44	#CJK UNIFIED IDEOGRAPH
+0x8158	0x4E46	#CJK UNIFIED IDEOGRAPH
+0x8159	0x4E4A	#CJK UNIFIED IDEOGRAPH
+0x815A	0x4E51	#CJK UNIFIED IDEOGRAPH
+0x815B	0x4E55	#CJK UNIFIED IDEOGRAPH
+0x815C	0x4E57	#CJK UNIFIED IDEOGRAPH
+0x815D	0x4E5A	#CJK UNIFIED IDEOGRAPH
+0x815E	0x4E5B	#CJK UNIFIED IDEOGRAPH
+0x815F	0x4E62	#CJK UNIFIED IDEOGRAPH
+0x8160	0x4E63	#CJK UNIFIED IDEOGRAPH
+0x8161	0x4E64	#CJK UNIFIED IDEOGRAPH
+0x8162	0x4E65	#CJK UNIFIED IDEOGRAPH
+0x8163	0x4E67	#CJK UNIFIED IDEOGRAPH
+0x8164	0x4E68	#CJK UNIFIED IDEOGRAPH
+0x8165	0x4E6A	#CJK UNIFIED IDEOGRAPH
+0x8166	0x4E6B	#CJK UNIFIED IDEOGRAPH
+0x8167	0x4E6C	#CJK UNIFIED IDEOGRAPH
+0x8168	0x4E6D	#CJK UNIFIED IDEOGRAPH
+0x8169	0x4E6E	#CJK UNIFIED IDEOGRAPH
+0x816A	0x4E6F	#CJK UNIFIED IDEOGRAPH
+0x816B	0x4E72	#CJK UNIFIED IDEOGRAPH
+0x816C	0x4E74	#CJK UNIFIED IDEOGRAPH
+0x816D	0x4E75	#CJK UNIFIED IDEOGRAPH
+0x816E	0x4E76	#CJK UNIFIED IDEOGRAPH
+0x816F	0x4E77	#CJK UNIFIED IDEOGRAPH
+0x8170	0x4E78	#CJK UNIFIED IDEOGRAPH
+0x8171	0x4E79	#CJK UNIFIED IDEOGRAPH
+0x8172	0x4E7A	#CJK UNIFIED IDEOGRAPH
+0x8173	0x4E7B	#CJK UNIFIED IDEOGRAPH
+0x8174	0x4E7C	#CJK UNIFIED IDEOGRAPH
+0x8175	0x4E7D	#CJK UNIFIED IDEOGRAPH
+0x8176	0x4E7F	#CJK UNIFIED IDEOGRAPH
+0x8177	0x4E80	#CJK UNIFIED IDEOGRAPH
+0x8178	0x4E81	#CJK UNIFIED IDEOGRAPH
+0x8179	0x4E82	#CJK UNIFIED IDEOGRAPH
+0x817A	0x4E83	#CJK UNIFIED IDEOGRAPH
+0x817B	0x4E84	#CJK UNIFIED IDEOGRAPH
+0x817C	0x4E85	#CJK UNIFIED IDEOGRAPH
+0x817D	0x4E87	#CJK UNIFIED IDEOGRAPH
+0x817E	0x4E8A	#CJK UNIFIED IDEOGRAPH
+0x8180	0x4E90	#CJK UNIFIED IDEOGRAPH
+0x8181	0x4E96	#CJK UNIFIED IDEOGRAPH
+0x8182	0x4E97	#CJK UNIFIED IDEOGRAPH
+0x8183	0x4E99	#CJK UNIFIED IDEOGRAPH
+0x8184	0x4E9C	#CJK UNIFIED IDEOGRAPH
+0x8185	0x4E9D	#CJK UNIFIED IDEOGRAPH
+0x8186	0x4E9E	#CJK UNIFIED IDEOGRAPH
+0x8187	0x4EA3	#CJK UNIFIED IDEOGRAPH
+0x8188	0x4EAA	#CJK UNIFIED IDEOGRAPH
+0x8189	0x4EAF	#CJK UNIFIED IDEOGRAPH
+0x818A	0x4EB0	#CJK UNIFIED IDEOGRAPH
+0x818B	0x4EB1	#CJK UNIFIED IDEOGRAPH
+0x818C	0x4EB4	#CJK UNIFIED IDEOGRAPH
+0x818D	0x4EB6	#CJK UNIFIED IDEOGRAPH
+0x818E	0x4EB7	#CJK UNIFIED IDEOGRAPH
+0x818F	0x4EB8	#CJK UNIFIED IDEOGRAPH
+0x8190	0x4EB9	#CJK UNIFIED IDEOGRAPH
+0x8191	0x4EBC	#CJK UNIFIED IDEOGRAPH
+0x8192	0x4EBD	#CJK UNIFIED IDEOGRAPH
+0x8193	0x4EBE	#CJK UNIFIED IDEOGRAPH
+0x8194	0x4EC8	#CJK UNIFIED IDEOGRAPH
+0x8195	0x4ECC	#CJK UNIFIED IDEOGRAPH
+0x8196	0x4ECF	#CJK UNIFIED IDEOGRAPH
+0x8197	0x4ED0	#CJK UNIFIED IDEOGRAPH
+0x8198	0x4ED2	#CJK UNIFIED IDEOGRAPH
+0x8199	0x4EDA	#CJK UNIFIED IDEOGRAPH
+0x819A	0x4EDB	#CJK UNIFIED IDEOGRAPH
+0x819B	0x4EDC	#CJK UNIFIED IDEOGRAPH
+0x819C	0x4EE0	#CJK UNIFIED IDEOGRAPH
+0x819D	0x4EE2	#CJK UNIFIED IDEOGRAPH
+0x819E	0x4EE6	#CJK UNIFIED IDEOGRAPH
+0x819F	0x4EE7	#CJK UNIFIED IDEOGRAPH
+0x81A0	0x4EE9	#CJK UNIFIED IDEOGRAPH
+0x81A1	0x4EED	#CJK UNIFIED IDEOGRAPH
+0x81A2	0x4EEE	#CJK UNIFIED IDEOGRAPH
+0x81A3	0x4EEF	#CJK UNIFIED IDEOGRAPH
+0x81A4	0x4EF1	#CJK UNIFIED IDEOGRAPH
+0x81A5	0x4EF4	#CJK UNIFIED IDEOGRAPH
+0x81A6	0x4EF8	#CJK UNIFIED IDEOGRAPH
+0x81A7	0x4EF9	#CJK UNIFIED IDEOGRAPH
+0x81A8	0x4EFA	#CJK UNIFIED IDEOGRAPH
+0x81A9	0x4EFC	#CJK UNIFIED IDEOGRAPH
+0x81AA	0x4EFE	#CJK UNIFIED IDEOGRAPH
+0x81AB	0x4F00	#CJK UNIFIED IDEOGRAPH
+0x81AC	0x4F02	#CJK UNIFIED IDEOGRAPH
+0x81AD	0x4F03	#CJK UNIFIED IDEOGRAPH
+0x81AE	0x4F04	#CJK UNIFIED IDEOGRAPH
+0x81AF	0x4F05	#CJK UNIFIED IDEOGRAPH
+0x81B0	0x4F06	#CJK UNIFIED IDEOGRAPH
+0x81B1	0x4F07	#CJK UNIFIED IDEOGRAPH
+0x81B2	0x4F08	#CJK UNIFIED IDEOGRAPH
+0x81B3	0x4F0B	#CJK UNIFIED IDEOGRAPH
+0x81B4	0x4F0C	#CJK UNIFIED IDEOGRAPH
+0x81B5	0x4F12	#CJK UNIFIED IDEOGRAPH
+0x81B6	0x4F13	#CJK UNIFIED IDEOGRAPH
+0x81B7	0x4F14	#CJK UNIFIED IDEOGRAPH
+0x81B8	0x4F15	#CJK UNIFIED IDEOGRAPH
+0x81B9	0x4F16	#CJK UNIFIED IDEOGRAPH
+0x81BA	0x4F1C	#CJK UNIFIED IDEOGRAPH
+0x81BB	0x4F1D	#CJK UNIFIED IDEOGRAPH
+0x81BC	0x4F21	#CJK UNIFIED IDEOGRAPH
+0x81BD	0x4F23	#CJK UNIFIED IDEOGRAPH
+0x81BE	0x4F28	#CJK UNIFIED IDEOGRAPH
+0x81BF	0x4F29	#CJK UNIFIED IDEOGRAPH
+0x81C0	0x4F2C	#CJK UNIFIED IDEOGRAPH
+0x81C1	0x4F2D	#CJK UNIFIED IDEOGRAPH
+0x81C2	0x4F2E	#CJK UNIFIED IDEOGRAPH
+0x81C3	0x4F31	#CJK UNIFIED IDEOGRAPH
+0x81C4	0x4F33	#CJK UNIFIED IDEOGRAPH
+0x81C5	0x4F35	#CJK UNIFIED IDEOGRAPH
+0x81C6	0x4F37	#CJK UNIFIED IDEOGRAPH
+0x81C7	0x4F39	#CJK UNIFIED IDEOGRAPH
+0x81C8	0x4F3B	#CJK UNIFIED IDEOGRAPH
+0x81C9	0x4F3E	#CJK UNIFIED IDEOGRAPH
+0x81CA	0x4F3F	#CJK UNIFIED IDEOGRAPH
+0x81CB	0x4F40	#CJK UNIFIED IDEOGRAPH
+0x81CC	0x4F41	#CJK UNIFIED IDEOGRAPH
+0x81CD	0x4F42	#CJK UNIFIED IDEOGRAPH
+0x81CE	0x4F44	#CJK UNIFIED IDEOGRAPH
+0x81CF	0x4F45	#CJK UNIFIED IDEOGRAPH
+0x81D0	0x4F47	#CJK UNIFIED IDEOGRAPH
+0x81D1	0x4F48	#CJK UNIFIED IDEOGRAPH
+0x81D2	0x4F49	#CJK UNIFIED IDEOGRAPH
+0x81D3	0x4F4A	#CJK UNIFIED IDEOGRAPH
+0x81D4	0x4F4B	#CJK UNIFIED IDEOGRAPH
+0x81D5	0x4F4C	#CJK UNIFIED IDEOGRAPH
+0x81D6	0x4F52	#CJK UNIFIED IDEOGRAPH
+0x81D7	0x4F54	#CJK UNIFIED IDEOGRAPH
+0x81D8	0x4F56	#CJK UNIFIED IDEOGRAPH
+0x81D9	0x4F61	#CJK UNIFIED IDEOGRAPH
+0x81DA	0x4F62	#CJK UNIFIED IDEOGRAPH
+0x81DB	0x4F66	#CJK UNIFIED IDEOGRAPH
+0x81DC	0x4F68	#CJK UNIFIED IDEOGRAPH
+0x81DD	0x4F6A	#CJK UNIFIED IDEOGRAPH
+0x81DE	0x4F6B	#CJK UNIFIED IDEOGRAPH
+0x81DF	0x4F6D	#CJK UNIFIED IDEOGRAPH
+0x81E0	0x4F6E	#CJK UNIFIED IDEOGRAPH
+0x81E1	0x4F71	#CJK UNIFIED IDEOGRAPH
+0x81E2	0x4F72	#CJK UNIFIED IDEOGRAPH
+0x81E3	0x4F75	#CJK UNIFIED IDEOGRAPH
+0x81E4	0x4F77	#CJK UNIFIED IDEOGRAPH
+0x81E5	0x4F78	#CJK UNIFIED IDEOGRAPH
+0x81E6	0x4F79	#CJK UNIFIED IDEOGRAPH
+0x81E7	0x4F7A	#CJK UNIFIED IDEOGRAPH
+0x81E8	0x4F7D	#CJK UNIFIED IDEOGRAPH
+0x81E9	0x4F80	#CJK UNIFIED IDEOGRAPH
+0x81EA	0x4F81	#CJK UNIFIED IDEOGRAPH
+0x81EB	0x4F82	#CJK UNIFIED IDEOGRAPH
+0x81EC	0x4F85	#CJK UNIFIED IDEOGRAPH
+0x81ED	0x4F86	#CJK UNIFIED IDEOGRAPH
+0x81EE	0x4F87	#CJK UNIFIED IDEOGRAPH
+0x81EF	0x4F8A	#CJK UNIFIED IDEOGRAPH
+0x81F0	0x4F8C	#CJK UNIFIED IDEOGRAPH
+0x81F1	0x4F8E	#CJK UNIFIED IDEOGRAPH
+0x81F2	0x4F90	#CJK UNIFIED IDEOGRAPH
+0x81F3	0x4F92	#CJK UNIFIED IDEOGRAPH
+0x81F4	0x4F93	#CJK UNIFIED IDEOGRAPH
+0x81F5	0x4F95	#CJK UNIFIED IDEOGRAPH
+0x81F6	0x4F96	#CJK UNIFIED IDEOGRAPH
+0x81F7	0x4F98	#CJK UNIFIED IDEOGRAPH
+0x81F8	0x4F99	#CJK UNIFIED IDEOGRAPH
+0x81F9	0x4F9A	#CJK UNIFIED IDEOGRAPH
+0x81FA	0x4F9C	#CJK UNIFIED IDEOGRAPH
+0x81FB	0x4F9E	#CJK UNIFIED IDEOGRAPH
+0x81FC	0x4F9F	#CJK UNIFIED IDEOGRAPH
+0x81FD	0x4FA1	#CJK UNIFIED IDEOGRAPH
+0x81FE	0x4FA2	#CJK UNIFIED IDEOGRAPH
+0x8240	0x4FA4	#CJK UNIFIED IDEOGRAPH
+0x8241	0x4FAB	#CJK UNIFIED IDEOGRAPH
+0x8242	0x4FAD	#CJK UNIFIED IDEOGRAPH
+0x8243	0x4FB0	#CJK UNIFIED IDEOGRAPH
+0x8244	0x4FB1	#CJK UNIFIED IDEOGRAPH
+0x8245	0x4FB2	#CJK UNIFIED IDEOGRAPH
+0x8246	0x4FB3	#CJK UNIFIED IDEOGRAPH
+0x8247	0x4FB4	#CJK UNIFIED IDEOGRAPH
+0x8248	0x4FB6	#CJK UNIFIED IDEOGRAPH
+0x8249	0x4FB7	#CJK UNIFIED IDEOGRAPH
+0x824A	0x4FB8	#CJK UNIFIED IDEOGRAPH
+0x824B	0x4FB9	#CJK UNIFIED IDEOGRAPH
+0x824C	0x4FBA	#CJK UNIFIED IDEOGRAPH
+0x824D	0x4FBB	#CJK UNIFIED IDEOGRAPH
+0x824E	0x4FBC	#CJK UNIFIED IDEOGRAPH
+0x824F	0x4FBD	#CJK UNIFIED IDEOGRAPH
+0x8250	0x4FBE	#CJK UNIFIED IDEOGRAPH
+0x8251	0x4FC0	#CJK UNIFIED IDEOGRAPH
+0x8252	0x4FC1	#CJK UNIFIED IDEOGRAPH
+0x8253	0x4FC2	#CJK UNIFIED IDEOGRAPH
+0x8254	0x4FC6	#CJK UNIFIED IDEOGRAPH
+0x8255	0x4FC7	#CJK UNIFIED IDEOGRAPH
+0x8256	0x4FC8	#CJK UNIFIED IDEOGRAPH
+0x8257	0x4FC9	#CJK UNIFIED IDEOGRAPH
+0x8258	0x4FCB	#CJK UNIFIED IDEOGRAPH
+0x8259	0x4FCC	#CJK UNIFIED IDEOGRAPH
+0x825A	0x4FCD	#CJK UNIFIED IDEOGRAPH
+0x825B	0x4FD2	#CJK UNIFIED IDEOGRAPH
+0x825C	0x4FD3	#CJK UNIFIED IDEOGRAPH
+0x825D	0x4FD4	#CJK UNIFIED IDEOGRAPH
+0x825E	0x4FD5	#CJK UNIFIED IDEOGRAPH
+0x825F	0x4FD6	#CJK UNIFIED IDEOGRAPH
+0x8260	0x4FD9	#CJK UNIFIED IDEOGRAPH
+0x8261	0x4FDB	#CJK UNIFIED IDEOGRAPH
+0x8262	0x4FE0	#CJK UNIFIED IDEOGRAPH
+0x8263	0x4FE2	#CJK UNIFIED IDEOGRAPH
+0x8264	0x4FE4	#CJK UNIFIED IDEOGRAPH
+0x8265	0x4FE5	#CJK UNIFIED IDEOGRAPH
+0x8266	0x4FE7	#CJK UNIFIED IDEOGRAPH
+0x8267	0x4FEB	#CJK UNIFIED IDEOGRAPH
+0x8268	0x4FEC	#CJK UNIFIED IDEOGRAPH
+0x8269	0x4FF0	#CJK UNIFIED IDEOGRAPH
+0x826A	0x4FF2	#CJK UNIFIED IDEOGRAPH
+0x826B	0x4FF4	#CJK UNIFIED IDEOGRAPH
+0x826C	0x4FF5	#CJK UNIFIED IDEOGRAPH
+0x826D	0x4FF6	#CJK UNIFIED IDEOGRAPH
+0x826E	0x4FF7	#CJK UNIFIED IDEOGRAPH
+0x826F	0x4FF9	#CJK UNIFIED IDEOGRAPH
+0x8270	0x4FFB	#CJK UNIFIED IDEOGRAPH
+0x8271	0x4FFC	#CJK UNIFIED IDEOGRAPH
+0x8272	0x4FFD	#CJK UNIFIED IDEOGRAPH
+0x8273	0x4FFF	#CJK UNIFIED IDEOGRAPH
+0x8274	0x5000	#CJK UNIFIED IDEOGRAPH
+0x8275	0x5001	#CJK UNIFIED IDEOGRAPH
+0x8276	0x5002	#CJK UNIFIED IDEOGRAPH
+0x8277	0x5003	#CJK UNIFIED IDEOGRAPH
+0x8278	0x5004	#CJK UNIFIED IDEOGRAPH
+0x8279	0x5005	#CJK UNIFIED IDEOGRAPH
+0x827A	0x5006	#CJK UNIFIED IDEOGRAPH
+0x827B	0x5007	#CJK UNIFIED IDEOGRAPH
+0x827C	0x5008	#CJK UNIFIED IDEOGRAPH
+0x827D	0x5009	#CJK UNIFIED IDEOGRAPH
+0x827E	0x500A	#CJK UNIFIED IDEOGRAPH
+0x8280	0x500B	#CJK UNIFIED IDEOGRAPH
+0x8281	0x500E	#CJK UNIFIED IDEOGRAPH
+0x8282	0x5010	#CJK UNIFIED IDEOGRAPH
+0x8283	0x5011	#CJK UNIFIED IDEOGRAPH
+0x8284	0x5013	#CJK UNIFIED IDEOGRAPH
+0x8285	0x5015	#CJK UNIFIED IDEOGRAPH
+0x8286	0x5016	#CJK UNIFIED IDEOGRAPH
+0x8287	0x5017	#CJK UNIFIED IDEOGRAPH
+0x8288	0x501B	#CJK UNIFIED IDEOGRAPH
+0x8289	0x501D	#CJK UNIFIED IDEOGRAPH
+0x828A	0x501E	#CJK UNIFIED IDEOGRAPH
+0x828B	0x5020	#CJK UNIFIED IDEOGRAPH
+0x828C	0x5022	#CJK UNIFIED IDEOGRAPH
+0x828D	0x5023	#CJK UNIFIED IDEOGRAPH
+0x828E	0x5024	#CJK UNIFIED IDEOGRAPH
+0x828F	0x5027	#CJK UNIFIED IDEOGRAPH
+0x8290	0x502B	#CJK UNIFIED IDEOGRAPH
+0x8291	0x502F	#CJK UNIFIED IDEOGRAPH
+0x8292	0x5030	#CJK UNIFIED IDEOGRAPH
+0x8293	0x5031	#CJK UNIFIED IDEOGRAPH
+0x8294	0x5032	#CJK UNIFIED IDEOGRAPH
+0x8295	0x5033	#CJK UNIFIED IDEOGRAPH
+0x8296	0x5034	#CJK UNIFIED IDEOGRAPH
+0x8297	0x5035	#CJK UNIFIED IDEOGRAPH
+0x8298	0x5036	#CJK UNIFIED IDEOGRAPH
+0x8299	0x5037	#CJK UNIFIED IDEOGRAPH
+0x829A	0x5038	#CJK UNIFIED IDEOGRAPH
+0x829B	0x5039	#CJK UNIFIED IDEOGRAPH
+0x829C	0x503B	#CJK UNIFIED IDEOGRAPH
+0x829D	0x503D	#CJK UNIFIED IDEOGRAPH
+0x829E	0x503F	#CJK UNIFIED IDEOGRAPH
+0x829F	0x5040	#CJK UNIFIED IDEOGRAPH
+0x82A0	0x5041	#CJK UNIFIED IDEOGRAPH
+0x82A1	0x5042	#CJK UNIFIED IDEOGRAPH
+0x82A2	0x5044	#CJK UNIFIED IDEOGRAPH
+0x82A3	0x5045	#CJK UNIFIED IDEOGRAPH
+0x82A4	0x5046	#CJK UNIFIED IDEOGRAPH
+0x82A5	0x5049	#CJK UNIFIED IDEOGRAPH
+0x82A6	0x504A	#CJK UNIFIED IDEOGRAPH
+0x82A7	0x504B	#CJK UNIFIED IDEOGRAPH
+0x82A8	0x504D	#CJK UNIFIED IDEOGRAPH
+0x82A9	0x5050	#CJK UNIFIED IDEOGRAPH
+0x82AA	0x5051	#CJK UNIFIED IDEOGRAPH
+0x82AB	0x5052	#CJK UNIFIED IDEOGRAPH
+0x82AC	0x5053	#CJK UNIFIED IDEOGRAPH
+0x82AD	0x5054	#CJK UNIFIED IDEOGRAPH
+0x82AE	0x5056	#CJK UNIFIED IDEOGRAPH
+0x82AF	0x5057	#CJK UNIFIED IDEOGRAPH
+0x82B0	0x5058	#CJK UNIFIED IDEOGRAPH
+0x82B1	0x5059	#CJK UNIFIED IDEOGRAPH
+0x82B2	0x505B	#CJK UNIFIED IDEOGRAPH
+0x82B3	0x505D	#CJK UNIFIED IDEOGRAPH
+0x82B4	0x505E	#CJK UNIFIED IDEOGRAPH
+0x82B5	0x505F	#CJK UNIFIED IDEOGRAPH
+0x82B6	0x5060	#CJK UNIFIED IDEOGRAPH
+0x82B7	0x5061	#CJK UNIFIED IDEOGRAPH
+0x82B8	0x5062	#CJK UNIFIED IDEOGRAPH
+0x82B9	0x5063	#CJK UNIFIED IDEOGRAPH
+0x82BA	0x5064	#CJK UNIFIED IDEOGRAPH
+0x82BB	0x5066	#CJK UNIFIED IDEOGRAPH
+0x82BC	0x5067	#CJK UNIFIED IDEOGRAPH
+0x82BD	0x5068	#CJK UNIFIED IDEOGRAPH
+0x82BE	0x5069	#CJK UNIFIED IDEOGRAPH
+0x82BF	0x506A	#CJK UNIFIED IDEOGRAPH
+0x82C0	0x506B	#CJK UNIFIED IDEOGRAPH
+0x82C1	0x506D	#CJK UNIFIED IDEOGRAPH
+0x82C2	0x506E	#CJK UNIFIED IDEOGRAPH
+0x82C3	0x506F	#CJK UNIFIED IDEOGRAPH
+0x82C4	0x5070	#CJK UNIFIED IDEOGRAPH
+0x82C5	0x5071	#CJK UNIFIED IDEOGRAPH
+0x82C6	0x5072	#CJK UNIFIED IDEOGRAPH
+0x82C7	0x5073	#CJK UNIFIED IDEOGRAPH
+0x82C8	0x5074	#CJK UNIFIED IDEOGRAPH
+0x82C9	0x5075	#CJK UNIFIED IDEOGRAPH
+0x82CA	0x5078	#CJK UNIFIED IDEOGRAPH
+0x82CB	0x5079	#CJK UNIFIED IDEOGRAPH
+0x82CC	0x507A	#CJK UNIFIED IDEOGRAPH
+0x82CD	0x507C	#CJK UNIFIED IDEOGRAPH
+0x82CE	0x507D	#CJK UNIFIED IDEOGRAPH
+0x82CF	0x5081	#CJK UNIFIED IDEOGRAPH
+0x82D0	0x5082	#CJK UNIFIED IDEOGRAPH
+0x82D1	0x5083	#CJK UNIFIED IDEOGRAPH
+0x82D2	0x5084	#CJK UNIFIED IDEOGRAPH
+0x82D3	0x5086	#CJK UNIFIED IDEOGRAPH
+0x82D4	0x5087	#CJK UNIFIED IDEOGRAPH
+0x82D5	0x5089	#CJK UNIFIED IDEOGRAPH
+0x82D6	0x508A	#CJK UNIFIED IDEOGRAPH
+0x82D7	0x508B	#CJK UNIFIED IDEOGRAPH
+0x82D8	0x508C	#CJK UNIFIED IDEOGRAPH
+0x82D9	0x508E	#CJK UNIFIED IDEOGRAPH
+0x82DA	0x508F	#CJK UNIFIED IDEOGRAPH
+0x82DB	0x5090	#CJK UNIFIED IDEOGRAPH
+0x82DC	0x5091	#CJK UNIFIED IDEOGRAPH
+0x82DD	0x5092	#CJK UNIFIED IDEOGRAPH
+0x82DE	0x5093	#CJK UNIFIED IDEOGRAPH
+0x82DF	0x5094	#CJK UNIFIED IDEOGRAPH
+0x82E0	0x5095	#CJK UNIFIED IDEOGRAPH
+0x82E1	0x5096	#CJK UNIFIED IDEOGRAPH
+0x82E2	0x5097	#CJK UNIFIED IDEOGRAPH
+0x82E3	0x5098	#CJK UNIFIED IDEOGRAPH
+0x82E4	0x5099	#CJK UNIFIED IDEOGRAPH
+0x82E5	0x509A	#CJK UNIFIED IDEOGRAPH
+0x82E6	0x509B	#CJK UNIFIED IDEOGRAPH
+0x82E7	0x509C	#CJK UNIFIED IDEOGRAPH
+0x82E8	0x509D	#CJK UNIFIED IDEOGRAPH
+0x82E9	0x509E	#CJK UNIFIED IDEOGRAPH
+0x82EA	0x509F	#CJK UNIFIED IDEOGRAPH
+0x82EB	0x50A0	#CJK UNIFIED IDEOGRAPH
+0x82EC	0x50A1	#CJK UNIFIED IDEOGRAPH
+0x82ED	0x50A2	#CJK UNIFIED IDEOGRAPH
+0x82EE	0x50A4	#CJK UNIFIED IDEOGRAPH
+0x82EF	0x50A6	#CJK UNIFIED IDEOGRAPH
+0x82F0	0x50AA	#CJK UNIFIED IDEOGRAPH
+0x82F1	0x50AB	#CJK UNIFIED IDEOGRAPH
+0x82F2	0x50AD	#CJK UNIFIED IDEOGRAPH
+0x82F3	0x50AE	#CJK UNIFIED IDEOGRAPH
+0x82F4	0x50AF	#CJK UNIFIED IDEOGRAPH
+0x82F5	0x50B0	#CJK UNIFIED IDEOGRAPH
+0x82F6	0x50B1	#CJK UNIFIED IDEOGRAPH
+0x82F7	0x50B3	#CJK UNIFIED IDEOGRAPH
+0x82F8	0x50B4	#CJK UNIFIED IDEOGRAPH
+0x82F9	0x50B5	#CJK UNIFIED IDEOGRAPH
+0x82FA	0x50B6	#CJK UNIFIED IDEOGRAPH
+0x82FB	0x50B7	#CJK UNIFIED IDEOGRAPH
+0x82FC	0x50B8	#CJK UNIFIED IDEOGRAPH
+0x82FD	0x50B9	#CJK UNIFIED IDEOGRAPH
+0x82FE	0x50BC	#CJK UNIFIED IDEOGRAPH
+0x8340	0x50BD	#CJK UNIFIED IDEOGRAPH
+0x8341	0x50BE	#CJK UNIFIED IDEOGRAPH
+0x8342	0x50BF	#CJK UNIFIED IDEOGRAPH
+0x8343	0x50C0	#CJK UNIFIED IDEOGRAPH
+0x8344	0x50C1	#CJK UNIFIED IDEOGRAPH
+0x8345	0x50C2	#CJK UNIFIED IDEOGRAPH
+0x8346	0x50C3	#CJK UNIFIED IDEOGRAPH
+0x8347	0x50C4	#CJK UNIFIED IDEOGRAPH
+0x8348	0x50C5	#CJK UNIFIED IDEOGRAPH
+0x8349	0x50C6	#CJK UNIFIED IDEOGRAPH
+0x834A	0x50C7	#CJK UNIFIED IDEOGRAPH
+0x834B	0x50C8	#CJK UNIFIED IDEOGRAPH
+0x834C	0x50C9	#CJK UNIFIED IDEOGRAPH
+0x834D	0x50CA	#CJK UNIFIED IDEOGRAPH
+0x834E	0x50CB	#CJK UNIFIED IDEOGRAPH
+0x834F	0x50CC	#CJK UNIFIED IDEOGRAPH
+0x8350	0x50CD	#CJK UNIFIED IDEOGRAPH
+0x8351	0x50CE	#CJK UNIFIED IDEOGRAPH
+0x8352	0x50D0	#CJK UNIFIED IDEOGRAPH
+0x8353	0x50D1	#CJK UNIFIED IDEOGRAPH
+0x8354	0x50D2	#CJK UNIFIED IDEOGRAPH
+0x8355	0x50D3	#CJK UNIFIED IDEOGRAPH
+0x8356	0x50D4	#CJK UNIFIED IDEOGRAPH
+0x8357	0x50D5	#CJK UNIFIED IDEOGRAPH
+0x8358	0x50D7	#CJK UNIFIED IDEOGRAPH
+0x8359	0x50D8	#CJK UNIFIED IDEOGRAPH
+0x835A	0x50D9	#CJK UNIFIED IDEOGRAPH
+0x835B	0x50DB	#CJK UNIFIED IDEOGRAPH
+0x835C	0x50DC	#CJK UNIFIED IDEOGRAPH
+0x835D	0x50DD	#CJK UNIFIED IDEOGRAPH
+0x835E	0x50DE	#CJK UNIFIED IDEOGRAPH
+0x835F	0x50DF	#CJK UNIFIED IDEOGRAPH
+0x8360	0x50E0	#CJK UNIFIED IDEOGRAPH
+0x8361	0x50E1	#CJK UNIFIED IDEOGRAPH
+0x8362	0x50E2	#CJK UNIFIED IDEOGRAPH
+0x8363	0x50E3	#CJK UNIFIED IDEOGRAPH
+0x8364	0x50E4	#CJK UNIFIED IDEOGRAPH
+0x8365	0x50E5	#CJK UNIFIED IDEOGRAPH
+0x8366	0x50E8	#CJK UNIFIED IDEOGRAPH
+0x8367	0x50E9	#CJK UNIFIED IDEOGRAPH
+0x8368	0x50EA	#CJK UNIFIED IDEOGRAPH
+0x8369	0x50EB	#CJK UNIFIED IDEOGRAPH
+0x836A	0x50EF	#CJK UNIFIED IDEOGRAPH
+0x836B	0x50F0	#CJK UNIFIED IDEOGRAPH
+0x836C	0x50F1	#CJK UNIFIED IDEOGRAPH
+0x836D	0x50F2	#CJK UNIFIED IDEOGRAPH
+0x836E	0x50F4	#CJK UNIFIED IDEOGRAPH
+0x836F	0x50F6	#CJK UNIFIED IDEOGRAPH
+0x8370	0x50F7	#CJK UNIFIED IDEOGRAPH
+0x8371	0x50F8	#CJK UNIFIED IDEOGRAPH
+0x8372	0x50F9	#CJK UNIFIED IDEOGRAPH
+0x8373	0x50FA	#CJK UNIFIED IDEOGRAPH
+0x8374	0x50FC	#CJK UNIFIED IDEOGRAPH
+0x8375	0x50FD	#CJK UNIFIED IDEOGRAPH
+0x8376	0x50FE	#CJK UNIFIED IDEOGRAPH
+0x8377	0x50FF	#CJK UNIFIED IDEOGRAPH
+0x8378	0x5100	#CJK UNIFIED IDEOGRAPH
+0x8379	0x5101	#CJK UNIFIED IDEOGRAPH
+0x837A	0x5102	#CJK UNIFIED IDEOGRAPH
+0x837B	0x5103	#CJK UNIFIED IDEOGRAPH
+0x837C	0x5104	#CJK UNIFIED IDEOGRAPH
+0x837D	0x5105	#CJK UNIFIED IDEOGRAPH
+0x837E	0x5108	#CJK UNIFIED IDEOGRAPH
+0x8380	0x5109	#CJK UNIFIED IDEOGRAPH
+0x8381	0x510A	#CJK UNIFIED IDEOGRAPH
+0x8382	0x510C	#CJK UNIFIED IDEOGRAPH
+0x8383	0x510D	#CJK UNIFIED IDEOGRAPH
+0x8384	0x510E	#CJK UNIFIED IDEOGRAPH
+0x8385	0x510F	#CJK UNIFIED IDEOGRAPH
+0x8386	0x5110	#CJK UNIFIED IDEOGRAPH
+0x8387	0x5111	#CJK UNIFIED IDEOGRAPH
+0x8388	0x5113	#CJK UNIFIED IDEOGRAPH
+0x8389	0x5114	#CJK UNIFIED IDEOGRAPH
+0x838A	0x5115	#CJK UNIFIED IDEOGRAPH
+0x838B	0x5116	#CJK UNIFIED IDEOGRAPH
+0x838C	0x5117	#CJK UNIFIED IDEOGRAPH
+0x838D	0x5118	#CJK UNIFIED IDEOGRAPH
+0x838E	0x5119	#CJK UNIFIED IDEOGRAPH
+0x838F	0x511A	#CJK UNIFIED IDEOGRAPH
+0x8390	0x511B	#CJK UNIFIED IDEOGRAPH
+0x8391	0x511C	#CJK UNIFIED IDEOGRAPH
+0x8392	0x511D	#CJK UNIFIED IDEOGRAPH
+0x8393	0x511E	#CJK UNIFIED IDEOGRAPH
+0x8394	0x511F	#CJK UNIFIED IDEOGRAPH
+0x8395	0x5120	#CJK UNIFIED IDEOGRAPH
+0x8396	0x5122	#CJK UNIFIED IDEOGRAPH
+0x8397	0x5123	#CJK UNIFIED IDEOGRAPH
+0x8398	0x5124	#CJK UNIFIED IDEOGRAPH
+0x8399	0x5125	#CJK UNIFIED IDEOGRAPH
+0x839A	0x5126	#CJK UNIFIED IDEOGRAPH
+0x839B	0x5127	#CJK UNIFIED IDEOGRAPH
+0x839C	0x5128	#CJK UNIFIED IDEOGRAPH
+0x839D	0x5129	#CJK UNIFIED IDEOGRAPH
+0x839E	0x512A	#CJK UNIFIED IDEOGRAPH
+0x839F	0x512B	#CJK UNIFIED IDEOGRAPH
+0x83A0	0x512C	#CJK UNIFIED IDEOGRAPH
+0x83A1	0x512D	#CJK UNIFIED IDEOGRAPH
+0x83A2	0x512E	#CJK UNIFIED IDEOGRAPH
+0x83A3	0x512F	#CJK UNIFIED IDEOGRAPH
+0x83A4	0x5130	#CJK UNIFIED IDEOGRAPH
+0x83A5	0x5131	#CJK UNIFIED IDEOGRAPH
+0x83A6	0x5132	#CJK UNIFIED IDEOGRAPH
+0x83A7	0x5133	#CJK UNIFIED IDEOGRAPH
+0x83A8	0x5134	#CJK UNIFIED IDEOGRAPH
+0x83A9	0x5135	#CJK UNIFIED IDEOGRAPH
+0x83AA	0x5136	#CJK UNIFIED IDEOGRAPH
+0x83AB	0x5137	#CJK UNIFIED IDEOGRAPH
+0x83AC	0x5138	#CJK UNIFIED IDEOGRAPH
+0x83AD	0x5139	#CJK UNIFIED IDEOGRAPH
+0x83AE	0x513A	#CJK UNIFIED IDEOGRAPH
+0x83AF	0x513B	#CJK UNIFIED IDEOGRAPH
+0x83B0	0x513C	#CJK UNIFIED IDEOGRAPH
+0x83B1	0x513D	#CJK UNIFIED IDEOGRAPH
+0x83B2	0x513E	#CJK UNIFIED IDEOGRAPH
+0x83B3	0x5142	#CJK UNIFIED IDEOGRAPH
+0x83B4	0x5147	#CJK UNIFIED IDEOGRAPH
+0x83B5	0x514A	#CJK UNIFIED IDEOGRAPH
+0x83B6	0x514C	#CJK UNIFIED IDEOGRAPH
+0x83B7	0x514E	#CJK UNIFIED IDEOGRAPH
+0x83B8	0x514F	#CJK UNIFIED IDEOGRAPH
+0x83B9	0x5150	#CJK UNIFIED IDEOGRAPH
+0x83BA	0x5152	#CJK UNIFIED IDEOGRAPH
+0x83BB	0x5153	#CJK UNIFIED IDEOGRAPH
+0x83BC	0x5157	#CJK UNIFIED IDEOGRAPH
+0x83BD	0x5158	#CJK UNIFIED IDEOGRAPH
+0x83BE	0x5159	#CJK UNIFIED IDEOGRAPH
+0x83BF	0x515B	#CJK UNIFIED IDEOGRAPH
+0x83C0	0x515D	#CJK UNIFIED IDEOGRAPH
+0x83C1	0x515E	#CJK UNIFIED IDEOGRAPH
+0x83C2	0x515F	#CJK UNIFIED IDEOGRAPH
+0x83C3	0x5160	#CJK UNIFIED IDEOGRAPH
+0x83C4	0x5161	#CJK UNIFIED IDEOGRAPH
+0x83C5	0x5163	#CJK UNIFIED IDEOGRAPH
+0x83C6	0x5164	#CJK UNIFIED IDEOGRAPH
+0x83C7	0x5166	#CJK UNIFIED IDEOGRAPH
+0x83C8	0x5167	#CJK UNIFIED IDEOGRAPH
+0x83C9	0x5169	#CJK UNIFIED IDEOGRAPH
+0x83CA	0x516A	#CJK UNIFIED IDEOGRAPH
+0x83CB	0x516F	#CJK UNIFIED IDEOGRAPH
+0x83CC	0x5172	#CJK UNIFIED IDEOGRAPH
+0x83CD	0x517A	#CJK UNIFIED IDEOGRAPH
+0x83CE	0x517E	#CJK UNIFIED IDEOGRAPH
+0x83CF	0x517F	#CJK UNIFIED IDEOGRAPH
+0x83D0	0x5183	#CJK UNIFIED IDEOGRAPH
+0x83D1	0x5184	#CJK UNIFIED IDEOGRAPH
+0x83D2	0x5186	#CJK UNIFIED IDEOGRAPH
+0x83D3	0x5187	#CJK UNIFIED IDEOGRAPH
+0x83D4	0x518A	#CJK UNIFIED IDEOGRAPH
+0x83D5	0x518B	#CJK UNIFIED IDEOGRAPH
+0x83D6	0x518E	#CJK UNIFIED IDEOGRAPH
+0x83D7	0x518F	#CJK UNIFIED IDEOGRAPH
+0x83D8	0x5190	#CJK UNIFIED IDEOGRAPH
+0x83D9	0x5191	#CJK UNIFIED IDEOGRAPH
+0x83DA	0x5193	#CJK UNIFIED IDEOGRAPH
+0x83DB	0x5194	#CJK UNIFIED IDEOGRAPH
+0x83DC	0x5198	#CJK UNIFIED IDEOGRAPH
+0x83DD	0x519A	#CJK UNIFIED IDEOGRAPH
+0x83DE	0x519D	#CJK UNIFIED IDEOGRAPH
+0x83DF	0x519E	#CJK UNIFIED IDEOGRAPH
+0x83E0	0x519F	#CJK UNIFIED IDEOGRAPH
+0x83E1	0x51A1	#CJK UNIFIED IDEOGRAPH
+0x83E2	0x51A3	#CJK UNIFIED IDEOGRAPH
+0x83E3	0x51A6	#CJK UNIFIED IDEOGRAPH
+0x83E4	0x51A7	#CJK UNIFIED IDEOGRAPH
+0x83E5	0x51A8	#CJK UNIFIED IDEOGRAPH
+0x83E6	0x51A9	#CJK UNIFIED IDEOGRAPH
+0x83E7	0x51AA	#CJK UNIFIED IDEOGRAPH
+0x83E8	0x51AD	#CJK UNIFIED IDEOGRAPH
+0x83E9	0x51AE	#CJK UNIFIED IDEOGRAPH
+0x83EA	0x51B4	#CJK UNIFIED IDEOGRAPH
+0x83EB	0x51B8	#CJK UNIFIED IDEOGRAPH
+0x83EC	0x51B9	#CJK UNIFIED IDEOGRAPH
+0x83ED	0x51BA	#CJK UNIFIED IDEOGRAPH
+0x83EE	0x51BE	#CJK UNIFIED IDEOGRAPH
+0x83EF	0x51BF	#CJK UNIFIED IDEOGRAPH
+0x83F0	0x51C1	#CJK UNIFIED IDEOGRAPH
+0x83F1	0x51C2	#CJK UNIFIED IDEOGRAPH
+0x83F2	0x51C3	#CJK UNIFIED IDEOGRAPH
+0x83F3	0x51C5	#CJK UNIFIED IDEOGRAPH
+0x83F4	0x51C8	#CJK UNIFIED IDEOGRAPH
+0x83F5	0x51CA	#CJK UNIFIED IDEOGRAPH
+0x83F6	0x51CD	#CJK UNIFIED IDEOGRAPH
+0x83F7	0x51CE	#CJK UNIFIED IDEOGRAPH
+0x83F8	0x51D0	#CJK UNIFIED IDEOGRAPH
+0x83F9	0x51D2	#CJK UNIFIED IDEOGRAPH
+0x83FA	0x51D3	#CJK UNIFIED IDEOGRAPH
+0x83FB	0x51D4	#CJK UNIFIED IDEOGRAPH
+0x83FC	0x51D5	#CJK UNIFIED IDEOGRAPH
+0x83FD	0x51D6	#CJK UNIFIED IDEOGRAPH
+0x83FE	0x51D7	#CJK UNIFIED IDEOGRAPH
+0x8440	0x51D8	#CJK UNIFIED IDEOGRAPH
+0x8441	0x51D9	#CJK UNIFIED IDEOGRAPH
+0x8442	0x51DA	#CJK UNIFIED IDEOGRAPH
+0x8443	0x51DC	#CJK UNIFIED IDEOGRAPH
+0x8444	0x51DE	#CJK UNIFIED IDEOGRAPH
+0x8445	0x51DF	#CJK UNIFIED IDEOGRAPH
+0x8446	0x51E2	#CJK UNIFIED IDEOGRAPH
+0x8447	0x51E3	#CJK UNIFIED IDEOGRAPH
+0x8448	0x51E5	#CJK UNIFIED IDEOGRAPH
+0x8449	0x51E6	#CJK UNIFIED IDEOGRAPH
+0x844A	0x51E7	#CJK UNIFIED IDEOGRAPH
+0x844B	0x51E8	#CJK UNIFIED IDEOGRAPH
+0x844C	0x51E9	#CJK UNIFIED IDEOGRAPH
+0x844D	0x51EA	#CJK UNIFIED IDEOGRAPH
+0x844E	0x51EC	#CJK UNIFIED IDEOGRAPH
+0x844F	0x51EE	#CJK UNIFIED IDEOGRAPH
+0x8450	0x51F1	#CJK UNIFIED IDEOGRAPH
+0x8451	0x51F2	#CJK UNIFIED IDEOGRAPH
+0x8452	0x51F4	#CJK UNIFIED IDEOGRAPH
+0x8453	0x51F7	#CJK UNIFIED IDEOGRAPH
+0x8454	0x51FE	#CJK UNIFIED IDEOGRAPH
+0x8455	0x5204	#CJK UNIFIED IDEOGRAPH
+0x8456	0x5205	#CJK UNIFIED IDEOGRAPH
+0x8457	0x5209	#CJK UNIFIED IDEOGRAPH
+0x8458	0x520B	#CJK UNIFIED IDEOGRAPH
+0x8459	0x520C	#CJK UNIFIED IDEOGRAPH
+0x845A	0x520F	#CJK UNIFIED IDEOGRAPH
+0x845B	0x5210	#CJK UNIFIED IDEOGRAPH
+0x845C	0x5213	#CJK UNIFIED IDEOGRAPH
+0x845D	0x5214	#CJK UNIFIED IDEOGRAPH
+0x845E	0x5215	#CJK UNIFIED IDEOGRAPH
+0x845F	0x521C	#CJK UNIFIED IDEOGRAPH
+0x8460	0x521E	#CJK UNIFIED IDEOGRAPH
+0x8461	0x521F	#CJK UNIFIED IDEOGRAPH
+0x8462	0x5221	#CJK UNIFIED IDEOGRAPH
+0x8463	0x5222	#CJK UNIFIED IDEOGRAPH
+0x8464	0x5223	#CJK UNIFIED IDEOGRAPH
+0x8465	0x5225	#CJK UNIFIED IDEOGRAPH
+0x8466	0x5226	#CJK UNIFIED IDEOGRAPH
+0x8467	0x5227	#CJK UNIFIED IDEOGRAPH
+0x8468	0x522A	#CJK UNIFIED IDEOGRAPH
+0x8469	0x522C	#CJK UNIFIED IDEOGRAPH
+0x846A	0x522F	#CJK UNIFIED IDEOGRAPH
+0x846B	0x5231	#CJK UNIFIED IDEOGRAPH
+0x846C	0x5232	#CJK UNIFIED IDEOGRAPH
+0x846D	0x5234	#CJK UNIFIED IDEOGRAPH
+0x846E	0x5235	#CJK UNIFIED IDEOGRAPH
+0x846F	0x523C	#CJK UNIFIED IDEOGRAPH
+0x8470	0x523E	#CJK UNIFIED IDEOGRAPH
+0x8471	0x5244	#CJK UNIFIED IDEOGRAPH
+0x8472	0x5245	#CJK UNIFIED IDEOGRAPH
+0x8473	0x5246	#CJK UNIFIED IDEOGRAPH
+0x8474	0x5247	#CJK UNIFIED IDEOGRAPH
+0x8475	0x5248	#CJK UNIFIED IDEOGRAPH
+0x8476	0x5249	#CJK UNIFIED IDEOGRAPH
+0x8477	0x524B	#CJK UNIFIED IDEOGRAPH
+0x8478	0x524E	#CJK UNIFIED IDEOGRAPH
+0x8479	0x524F	#CJK UNIFIED IDEOGRAPH
+0x847A	0x5252	#CJK UNIFIED IDEOGRAPH
+0x847B	0x5253	#CJK UNIFIED IDEOGRAPH
+0x847C	0x5255	#CJK UNIFIED IDEOGRAPH
+0x847D	0x5257	#CJK UNIFIED IDEOGRAPH
+0x847E	0x5258	#CJK UNIFIED IDEOGRAPH
+0x8480	0x5259	#CJK UNIFIED IDEOGRAPH
+0x8481	0x525A	#CJK UNIFIED IDEOGRAPH
+0x8482	0x525B	#CJK UNIFIED IDEOGRAPH
+0x8483	0x525D	#CJK UNIFIED IDEOGRAPH
+0x8484	0x525F	#CJK UNIFIED IDEOGRAPH
+0x8485	0x5260	#CJK UNIFIED IDEOGRAPH
+0x8486	0x5262	#CJK UNIFIED IDEOGRAPH
+0x8487	0x5263	#CJK UNIFIED IDEOGRAPH
+0x8488	0x5264	#CJK UNIFIED IDEOGRAPH
+0x8489	0x5266	#CJK UNIFIED IDEOGRAPH
+0x848A	0x5268	#CJK UNIFIED IDEOGRAPH
+0x848B	0x526B	#CJK UNIFIED IDEOGRAPH
+0x848C	0x526C	#CJK UNIFIED IDEOGRAPH
+0x848D	0x526D	#CJK UNIFIED IDEOGRAPH
+0x848E	0x526E	#CJK UNIFIED IDEOGRAPH
+0x848F	0x5270	#CJK UNIFIED IDEOGRAPH
+0x8490	0x5271	#CJK UNIFIED IDEOGRAPH
+0x8491	0x5273	#CJK UNIFIED IDEOGRAPH
+0x8492	0x5274	#CJK UNIFIED IDEOGRAPH
+0x8493	0x5275	#CJK UNIFIED IDEOGRAPH
+0x8494	0x5276	#CJK UNIFIED IDEOGRAPH
+0x8495	0x5277	#CJK UNIFIED IDEOGRAPH
+0x8496	0x5278	#CJK UNIFIED IDEOGRAPH
+0x8497	0x5279	#CJK UNIFIED IDEOGRAPH
+0x8498	0x527A	#CJK UNIFIED IDEOGRAPH
+0x8499	0x527B	#CJK UNIFIED IDEOGRAPH
+0x849A	0x527C	#CJK UNIFIED IDEOGRAPH
+0x849B	0x527E	#CJK UNIFIED IDEOGRAPH
+0x849C	0x5280	#CJK UNIFIED IDEOGRAPH
+0x849D	0x5283	#CJK UNIFIED IDEOGRAPH
+0x849E	0x5284	#CJK UNIFIED IDEOGRAPH
+0x849F	0x5285	#CJK UNIFIED IDEOGRAPH
+0x84A0	0x5286	#CJK UNIFIED IDEOGRAPH
+0x84A1	0x5287	#CJK UNIFIED IDEOGRAPH
+0x84A2	0x5289	#CJK UNIFIED IDEOGRAPH
+0x84A3	0x528A	#CJK UNIFIED IDEOGRAPH
+0x84A4	0x528B	#CJK UNIFIED IDEOGRAPH
+0x84A5	0x528C	#CJK UNIFIED IDEOGRAPH
+0x84A6	0x528D	#CJK UNIFIED IDEOGRAPH
+0x84A7	0x528E	#CJK UNIFIED IDEOGRAPH
+0x84A8	0x528F	#CJK UNIFIED IDEOGRAPH
+0x84A9	0x5291	#CJK UNIFIED IDEOGRAPH
+0x84AA	0x5292	#CJK UNIFIED IDEOGRAPH
+0x84AB	0x5294	#CJK UNIFIED IDEOGRAPH
+0x84AC	0x5295	#CJK UNIFIED IDEOGRAPH
+0x84AD	0x5296	#CJK UNIFIED IDEOGRAPH
+0x84AE	0x5297	#CJK UNIFIED IDEOGRAPH
+0x84AF	0x5298	#CJK UNIFIED IDEOGRAPH
+0x84B0	0x5299	#CJK UNIFIED IDEOGRAPH
+0x84B1	0x529A	#CJK UNIFIED IDEOGRAPH
+0x84B2	0x529C	#CJK UNIFIED IDEOGRAPH
+0x84B3	0x52A4	#CJK UNIFIED IDEOGRAPH
+0x84B4	0x52A5	#CJK UNIFIED IDEOGRAPH
+0x84B5	0x52A6	#CJK UNIFIED IDEOGRAPH
+0x84B6	0x52A7	#CJK UNIFIED IDEOGRAPH
+0x84B7	0x52AE	#CJK UNIFIED IDEOGRAPH
+0x84B8	0x52AF	#CJK UNIFIED IDEOGRAPH
+0x84B9	0x52B0	#CJK UNIFIED IDEOGRAPH
+0x84BA	0x52B4	#CJK UNIFIED IDEOGRAPH
+0x84BB	0x52B5	#CJK UNIFIED IDEOGRAPH
+0x84BC	0x52B6	#CJK UNIFIED IDEOGRAPH
+0x84BD	0x52B7	#CJK UNIFIED IDEOGRAPH
+0x84BE	0x52B8	#CJK UNIFIED IDEOGRAPH
+0x84BF	0x52B9	#CJK UNIFIED IDEOGRAPH
+0x84C0	0x52BA	#CJK UNIFIED IDEOGRAPH
+0x84C1	0x52BB	#CJK UNIFIED IDEOGRAPH
+0x84C2	0x52BC	#CJK UNIFIED IDEOGRAPH
+0x84C3	0x52BD	#CJK UNIFIED IDEOGRAPH
+0x84C4	0x52C0	#CJK UNIFIED IDEOGRAPH
+0x84C5	0x52C1	#CJK UNIFIED IDEOGRAPH
+0x84C6	0x52C2	#CJK UNIFIED IDEOGRAPH
+0x84C7	0x52C4	#CJK UNIFIED IDEOGRAPH
+0x84C8	0x52C5	#CJK UNIFIED IDEOGRAPH
+0x84C9	0x52C6	#CJK UNIFIED IDEOGRAPH
+0x84CA	0x52C8	#CJK UNIFIED IDEOGRAPH
+0x84CB	0x52CA	#CJK UNIFIED IDEOGRAPH
+0x84CC	0x52CC	#CJK UNIFIED IDEOGRAPH
+0x84CD	0x52CD	#CJK UNIFIED IDEOGRAPH
+0x84CE	0x52CE	#CJK UNIFIED IDEOGRAPH
+0x84CF	0x52CF	#CJK UNIFIED IDEOGRAPH
+0x84D0	0x52D1	#CJK UNIFIED IDEOGRAPH
+0x84D1	0x52D3	#CJK UNIFIED IDEOGRAPH
+0x84D2	0x52D4	#CJK UNIFIED IDEOGRAPH
+0x84D3	0x52D5	#CJK UNIFIED IDEOGRAPH
+0x84D4	0x52D7	#CJK UNIFIED IDEOGRAPH
+0x84D5	0x52D9	#CJK UNIFIED IDEOGRAPH
+0x84D6	0x52DA	#CJK UNIFIED IDEOGRAPH
+0x84D7	0x52DB	#CJK UNIFIED IDEOGRAPH
+0x84D8	0x52DC	#CJK UNIFIED IDEOGRAPH
+0x84D9	0x52DD	#CJK UNIFIED IDEOGRAPH
+0x84DA	0x52DE	#CJK UNIFIED IDEOGRAPH
+0x84DB	0x52E0	#CJK UNIFIED IDEOGRAPH
+0x84DC	0x52E1	#CJK UNIFIED IDEOGRAPH
+0x84DD	0x52E2	#CJK UNIFIED IDEOGRAPH
+0x84DE	0x52E3	#CJK UNIFIED IDEOGRAPH
+0x84DF	0x52E5	#CJK UNIFIED IDEOGRAPH
+0x84E0	0x52E6	#CJK UNIFIED IDEOGRAPH
+0x84E1	0x52E7	#CJK UNIFIED IDEOGRAPH
+0x84E2	0x52E8	#CJK UNIFIED IDEOGRAPH
+0x84E3	0x52E9	#CJK UNIFIED IDEOGRAPH
+0x84E4	0x52EA	#CJK UNIFIED IDEOGRAPH
+0x84E5	0x52EB	#CJK UNIFIED IDEOGRAPH
+0x84E6	0x52EC	#CJK UNIFIED IDEOGRAPH
+0x84E7	0x52ED	#CJK UNIFIED IDEOGRAPH
+0x84E8	0x52EE	#CJK UNIFIED IDEOGRAPH
+0x84E9	0x52EF	#CJK UNIFIED IDEOGRAPH
+0x84EA	0x52F1	#CJK UNIFIED IDEOGRAPH
+0x84EB	0x52F2	#CJK UNIFIED IDEOGRAPH
+0x84EC	0x52F3	#CJK UNIFIED IDEOGRAPH
+0x84ED	0x52F4	#CJK UNIFIED IDEOGRAPH
+0x84EE	0x52F5	#CJK UNIFIED IDEOGRAPH
+0x84EF	0x52F6	#CJK UNIFIED IDEOGRAPH
+0x84F0	0x52F7	#CJK UNIFIED IDEOGRAPH
+0x84F1	0x52F8	#CJK UNIFIED IDEOGRAPH
+0x84F2	0x52FB	#CJK UNIFIED IDEOGRAPH
+0x84F3	0x52FC	#CJK UNIFIED IDEOGRAPH
+0x84F4	0x52FD	#CJK UNIFIED IDEOGRAPH
+0x84F5	0x5301	#CJK UNIFIED IDEOGRAPH
+0x84F6	0x5302	#CJK UNIFIED IDEOGRAPH
+0x84F7	0x5303	#CJK UNIFIED IDEOGRAPH
+0x84F8	0x5304	#CJK UNIFIED IDEOGRAPH
+0x84F9	0x5307	#CJK UNIFIED IDEOGRAPH
+0x84FA	0x5309	#CJK UNIFIED IDEOGRAPH
+0x84FB	0x530A	#CJK UNIFIED IDEOGRAPH
+0x84FC	0x530B	#CJK UNIFIED IDEOGRAPH
+0x84FD	0x530C	#CJK UNIFIED IDEOGRAPH
+0x84FE	0x530E	#CJK UNIFIED IDEOGRAPH
+0x8540	0x5311	#CJK UNIFIED IDEOGRAPH
+0x8541	0x5312	#CJK UNIFIED IDEOGRAPH
+0x8542	0x5313	#CJK UNIFIED IDEOGRAPH
+0x8543	0x5314	#CJK UNIFIED IDEOGRAPH
+0x8544	0x5318	#CJK UNIFIED IDEOGRAPH
+0x8545	0x531B	#CJK UNIFIED IDEOGRAPH
+0x8546	0x531C	#CJK UNIFIED IDEOGRAPH
+0x8547	0x531E	#CJK UNIFIED IDEOGRAPH
+0x8548	0x531F	#CJK UNIFIED IDEOGRAPH
+0x8549	0x5322	#CJK UNIFIED IDEOGRAPH
+0x854A	0x5324	#CJK UNIFIED IDEOGRAPH
+0x854B	0x5325	#CJK UNIFIED IDEOGRAPH
+0x854C	0x5327	#CJK UNIFIED IDEOGRAPH
+0x854D	0x5328	#CJK UNIFIED IDEOGRAPH
+0x854E	0x5329	#CJK UNIFIED IDEOGRAPH
+0x854F	0x532B	#CJK UNIFIED IDEOGRAPH
+0x8550	0x532C	#CJK UNIFIED IDEOGRAPH
+0x8551	0x532D	#CJK UNIFIED IDEOGRAPH
+0x8552	0x532F	#CJK UNIFIED IDEOGRAPH
+0x8553	0x5330	#CJK UNIFIED IDEOGRAPH
+0x8554	0x5331	#CJK UNIFIED IDEOGRAPH
+0x8555	0x5332	#CJK UNIFIED IDEOGRAPH
+0x8556	0x5333	#CJK UNIFIED IDEOGRAPH
+0x8557	0x5334	#CJK UNIFIED IDEOGRAPH
+0x8558	0x5335	#CJK UNIFIED IDEOGRAPH
+0x8559	0x5336	#CJK UNIFIED IDEOGRAPH
+0x855A	0x5337	#CJK UNIFIED IDEOGRAPH
+0x855B	0x5338	#CJK UNIFIED IDEOGRAPH
+0x855C	0x533C	#CJK UNIFIED IDEOGRAPH
+0x855D	0x533D	#CJK UNIFIED IDEOGRAPH
+0x855E	0x5340	#CJK UNIFIED IDEOGRAPH
+0x855F	0x5342	#CJK UNIFIED IDEOGRAPH
+0x8560	0x5344	#CJK UNIFIED IDEOGRAPH
+0x8561	0x5346	#CJK UNIFIED IDEOGRAPH
+0x8562	0x534B	#CJK UNIFIED IDEOGRAPH
+0x8563	0x534C	#CJK UNIFIED IDEOGRAPH
+0x8564	0x534D	#CJK UNIFIED IDEOGRAPH
+0x8565	0x5350	#CJK UNIFIED IDEOGRAPH
+0x8566	0x5354	#CJK UNIFIED IDEOGRAPH
+0x8567	0x5358	#CJK UNIFIED IDEOGRAPH
+0x8568	0x5359	#CJK UNIFIED IDEOGRAPH
+0x8569	0x535B	#CJK UNIFIED IDEOGRAPH
+0x856A	0x535D	#CJK UNIFIED IDEOGRAPH
+0x856B	0x5365	#CJK UNIFIED IDEOGRAPH
+0x856C	0x5368	#CJK UNIFIED IDEOGRAPH
+0x856D	0x536A	#CJK UNIFIED IDEOGRAPH
+0x856E	0x536C	#CJK UNIFIED IDEOGRAPH
+0x856F	0x536D	#CJK UNIFIED IDEOGRAPH
+0x8570	0x5372	#CJK UNIFIED IDEOGRAPH
+0x8571	0x5376	#CJK UNIFIED IDEOGRAPH
+0x8572	0x5379	#CJK UNIFIED IDEOGRAPH
+0x8573	0x537B	#CJK UNIFIED IDEOGRAPH
+0x8574	0x537C	#CJK UNIFIED IDEOGRAPH
+0x8575	0x537D	#CJK UNIFIED IDEOGRAPH
+0x8576	0x537E	#CJK UNIFIED IDEOGRAPH
+0x8577	0x5380	#CJK UNIFIED IDEOGRAPH
+0x8578	0x5381	#CJK UNIFIED IDEOGRAPH
+0x8579	0x5383	#CJK UNIFIED IDEOGRAPH
+0x857A	0x5387	#CJK UNIFIED IDEOGRAPH
+0x857B	0x5388	#CJK UNIFIED IDEOGRAPH
+0x857C	0x538A	#CJK UNIFIED IDEOGRAPH
+0x857D	0x538E	#CJK UNIFIED IDEOGRAPH
+0x857E	0x538F	#CJK UNIFIED IDEOGRAPH
+0x8580	0x5390	#CJK UNIFIED IDEOGRAPH
+0x8581	0x5391	#CJK UNIFIED IDEOGRAPH
+0x8582	0x5392	#CJK UNIFIED IDEOGRAPH
+0x8583	0x5393	#CJK UNIFIED IDEOGRAPH
+0x8584	0x5394	#CJK UNIFIED IDEOGRAPH
+0x8585	0x5396	#CJK UNIFIED IDEOGRAPH
+0x8586	0x5397	#CJK UNIFIED IDEOGRAPH
+0x8587	0x5399	#CJK UNIFIED IDEOGRAPH
+0x8588	0x539B	#CJK UNIFIED IDEOGRAPH
+0x8589	0x539C	#CJK UNIFIED IDEOGRAPH
+0x858A	0x539E	#CJK UNIFIED IDEOGRAPH
+0x858B	0x53A0	#CJK UNIFIED IDEOGRAPH
+0x858C	0x53A1	#CJK UNIFIED IDEOGRAPH
+0x858D	0x53A4	#CJK UNIFIED IDEOGRAPH
+0x858E	0x53A7	#CJK UNIFIED IDEOGRAPH
+0x858F	0x53AA	#CJK UNIFIED IDEOGRAPH
+0x8590	0x53AB	#CJK UNIFIED IDEOGRAPH
+0x8591	0x53AC	#CJK UNIFIED IDEOGRAPH
+0x8592	0x53AD	#CJK UNIFIED IDEOGRAPH
+0x8593	0x53AF	#CJK UNIFIED IDEOGRAPH
+0x8594	0x53B0	#CJK UNIFIED IDEOGRAPH
+0x8595	0x53B1	#CJK UNIFIED IDEOGRAPH
+0x8596	0x53B2	#CJK UNIFIED IDEOGRAPH
+0x8597	0x53B3	#CJK UNIFIED IDEOGRAPH
+0x8598	0x53B4	#CJK UNIFIED IDEOGRAPH
+0x8599	0x53B5	#CJK UNIFIED IDEOGRAPH
+0x859A	0x53B7	#CJK UNIFIED IDEOGRAPH
+0x859B	0x53B8	#CJK UNIFIED IDEOGRAPH
+0x859C	0x53B9	#CJK UNIFIED IDEOGRAPH
+0x859D	0x53BA	#CJK UNIFIED IDEOGRAPH
+0x859E	0x53BC	#CJK UNIFIED IDEOGRAPH
+0x859F	0x53BD	#CJK UNIFIED IDEOGRAPH
+0x85A0	0x53BE	#CJK UNIFIED IDEOGRAPH
+0x85A1	0x53C0	#CJK UNIFIED IDEOGRAPH
+0x85A2	0x53C3	#CJK UNIFIED IDEOGRAPH
+0x85A3	0x53C4	#CJK UNIFIED IDEOGRAPH
+0x85A4	0x53C5	#CJK UNIFIED IDEOGRAPH
+0x85A5	0x53C6	#CJK UNIFIED IDEOGRAPH
+0x85A6	0x53C7	#CJK UNIFIED IDEOGRAPH
+0x85A7	0x53CE	#CJK UNIFIED IDEOGRAPH
+0x85A8	0x53CF	#CJK UNIFIED IDEOGRAPH
+0x85A9	0x53D0	#CJK UNIFIED IDEOGRAPH
+0x85AA	0x53D2	#CJK UNIFIED IDEOGRAPH
+0x85AB	0x53D3	#CJK UNIFIED IDEOGRAPH
+0x85AC	0x53D5	#CJK UNIFIED IDEOGRAPH
+0x85AD	0x53DA	#CJK UNIFIED IDEOGRAPH
+0x85AE	0x53DC	#CJK UNIFIED IDEOGRAPH
+0x85AF	0x53DD	#CJK UNIFIED IDEOGRAPH
+0x85B0	0x53DE	#CJK UNIFIED IDEOGRAPH
+0x85B1	0x53E1	#CJK UNIFIED IDEOGRAPH
+0x85B2	0x53E2	#CJK UNIFIED IDEOGRAPH
+0x85B3	0x53E7	#CJK UNIFIED IDEOGRAPH
+0x85B4	0x53F4	#CJK UNIFIED IDEOGRAPH
+0x85B5	0x53FA	#CJK UNIFIED IDEOGRAPH
+0x85B6	0x53FE	#CJK UNIFIED IDEOGRAPH
+0x85B7	0x53FF	#CJK UNIFIED IDEOGRAPH
+0x85B8	0x5400	#CJK UNIFIED IDEOGRAPH
+0x85B9	0x5402	#CJK UNIFIED IDEOGRAPH
+0x85BA	0x5405	#CJK UNIFIED IDEOGRAPH
+0x85BB	0x5407	#CJK UNIFIED IDEOGRAPH
+0x85BC	0x540B	#CJK UNIFIED IDEOGRAPH
+0x85BD	0x5414	#CJK UNIFIED IDEOGRAPH
+0x85BE	0x5418	#CJK UNIFIED IDEOGRAPH
+0x85BF	0x5419	#CJK UNIFIED IDEOGRAPH
+0x85C0	0x541A	#CJK UNIFIED IDEOGRAPH
+0x85C1	0x541C	#CJK UNIFIED IDEOGRAPH
+0x85C2	0x5422	#CJK UNIFIED IDEOGRAPH
+0x85C3	0x5424	#CJK UNIFIED IDEOGRAPH
+0x85C4	0x5425	#CJK UNIFIED IDEOGRAPH
+0x85C5	0x542A	#CJK UNIFIED IDEOGRAPH
+0x85C6	0x5430	#CJK UNIFIED IDEOGRAPH
+0x85C7	0x5433	#CJK UNIFIED IDEOGRAPH
+0x85C8	0x5436	#CJK UNIFIED IDEOGRAPH
+0x85C9	0x5437	#CJK UNIFIED IDEOGRAPH
+0x85CA	0x543A	#CJK UNIFIED IDEOGRAPH
+0x85CB	0x543D	#CJK UNIFIED IDEOGRAPH
+0x85CC	0x543F	#CJK UNIFIED IDEOGRAPH
+0x85CD	0x5441	#CJK UNIFIED IDEOGRAPH
+0x85CE	0x5442	#CJK UNIFIED IDEOGRAPH
+0x85CF	0x5444	#CJK UNIFIED IDEOGRAPH
+0x85D0	0x5445	#CJK UNIFIED IDEOGRAPH
+0x85D1	0x5447	#CJK UNIFIED IDEOGRAPH
+0x85D2	0x5449	#CJK UNIFIED IDEOGRAPH
+0x85D3	0x544C	#CJK UNIFIED IDEOGRAPH
+0x85D4	0x544D	#CJK UNIFIED IDEOGRAPH
+0x85D5	0x544E	#CJK UNIFIED IDEOGRAPH
+0x85D6	0x544F	#CJK UNIFIED IDEOGRAPH
+0x85D7	0x5451	#CJK UNIFIED IDEOGRAPH
+0x85D8	0x545A	#CJK UNIFIED IDEOGRAPH
+0x85D9	0x545D	#CJK UNIFIED IDEOGRAPH
+0x85DA	0x545E	#CJK UNIFIED IDEOGRAPH
+0x85DB	0x545F	#CJK UNIFIED IDEOGRAPH
+0x85DC	0x5460	#CJK UNIFIED IDEOGRAPH
+0x85DD	0x5461	#CJK UNIFIED IDEOGRAPH
+0x85DE	0x5463	#CJK UNIFIED IDEOGRAPH
+0x85DF	0x5465	#CJK UNIFIED IDEOGRAPH
+0x85E0	0x5467	#CJK UNIFIED IDEOGRAPH
+0x85E1	0x5469	#CJK UNIFIED IDEOGRAPH
+0x85E2	0x546A	#CJK UNIFIED IDEOGRAPH
+0x85E3	0x546B	#CJK UNIFIED IDEOGRAPH
+0x85E4	0x546C	#CJK UNIFIED IDEOGRAPH
+0x85E5	0x546D	#CJK UNIFIED IDEOGRAPH
+0x85E6	0x546E	#CJK UNIFIED IDEOGRAPH
+0x85E7	0x546F	#CJK UNIFIED IDEOGRAPH
+0x85E8	0x5470	#CJK UNIFIED IDEOGRAPH
+0x85E9	0x5474	#CJK UNIFIED IDEOGRAPH
+0x85EA	0x5479	#CJK UNIFIED IDEOGRAPH
+0x85EB	0x547A	#CJK UNIFIED IDEOGRAPH
+0x85EC	0x547E	#CJK UNIFIED IDEOGRAPH
+0x85ED	0x547F	#CJK UNIFIED IDEOGRAPH
+0x85EE	0x5481	#CJK UNIFIED IDEOGRAPH
+0x85EF	0x5483	#CJK UNIFIED IDEOGRAPH
+0x85F0	0x5485	#CJK UNIFIED IDEOGRAPH
+0x85F1	0x5487	#CJK UNIFIED IDEOGRAPH
+0x85F2	0x5488	#CJK UNIFIED IDEOGRAPH
+0x85F3	0x5489	#CJK UNIFIED IDEOGRAPH
+0x85F4	0x548A	#CJK UNIFIED IDEOGRAPH
+0x85F5	0x548D	#CJK UNIFIED IDEOGRAPH
+0x85F6	0x5491	#CJK UNIFIED IDEOGRAPH
+0x85F7	0x5493	#CJK UNIFIED IDEOGRAPH
+0x85F8	0x5497	#CJK UNIFIED IDEOGRAPH
+0x85F9	0x5498	#CJK UNIFIED IDEOGRAPH
+0x85FA	0x549C	#CJK UNIFIED IDEOGRAPH
+0x85FB	0x549E	#CJK UNIFIED IDEOGRAPH
+0x85FC	0x549F	#CJK UNIFIED IDEOGRAPH
+0x85FD	0x54A0	#CJK UNIFIED IDEOGRAPH
+0x85FE	0x54A1	#CJK UNIFIED IDEOGRAPH
+0x8640	0x54A2	#CJK UNIFIED IDEOGRAPH
+0x8641	0x54A5	#CJK UNIFIED IDEOGRAPH
+0x8642	0x54AE	#CJK UNIFIED IDEOGRAPH
+0x8643	0x54B0	#CJK UNIFIED IDEOGRAPH
+0x8644	0x54B2	#CJK UNIFIED IDEOGRAPH
+0x8645	0x54B5	#CJK UNIFIED IDEOGRAPH
+0x8646	0x54B6	#CJK UNIFIED IDEOGRAPH
+0x8647	0x54B7	#CJK UNIFIED IDEOGRAPH
+0x8648	0x54B9	#CJK UNIFIED IDEOGRAPH
+0x8649	0x54BA	#CJK UNIFIED IDEOGRAPH
+0x864A	0x54BC	#CJK UNIFIED IDEOGRAPH
+0x864B	0x54BE	#CJK UNIFIED IDEOGRAPH
+0x864C	0x54C3	#CJK UNIFIED IDEOGRAPH
+0x864D	0x54C5	#CJK UNIFIED IDEOGRAPH
+0x864E	0x54CA	#CJK UNIFIED IDEOGRAPH
+0x864F	0x54CB	#CJK UNIFIED IDEOGRAPH
+0x8650	0x54D6	#CJK UNIFIED IDEOGRAPH
+0x8651	0x54D8	#CJK UNIFIED IDEOGRAPH
+0x8652	0x54DB	#CJK UNIFIED IDEOGRAPH
+0x8653	0x54E0	#CJK UNIFIED IDEOGRAPH
+0x8654	0x54E1	#CJK UNIFIED IDEOGRAPH
+0x8655	0x54E2	#CJK UNIFIED IDEOGRAPH
+0x8656	0x54E3	#CJK UNIFIED IDEOGRAPH
+0x8657	0x54E4	#CJK UNIFIED IDEOGRAPH
+0x8658	0x54EB	#CJK UNIFIED IDEOGRAPH
+0x8659	0x54EC	#CJK UNIFIED IDEOGRAPH
+0x865A	0x54EF	#CJK UNIFIED IDEOGRAPH
+0x865B	0x54F0	#CJK UNIFIED IDEOGRAPH
+0x865C	0x54F1	#CJK UNIFIED IDEOGRAPH
+0x865D	0x54F4	#CJK UNIFIED IDEOGRAPH
+0x865E	0x54F5	#CJK UNIFIED IDEOGRAPH
+0x865F	0x54F6	#CJK UNIFIED IDEOGRAPH
+0x8660	0x54F7	#CJK UNIFIED IDEOGRAPH
+0x8661	0x54F8	#CJK UNIFIED IDEOGRAPH
+0x8662	0x54F9	#CJK UNIFIED IDEOGRAPH
+0x8663	0x54FB	#CJK UNIFIED IDEOGRAPH
+0x8664	0x54FE	#CJK UNIFIED IDEOGRAPH
+0x8665	0x5500	#CJK UNIFIED IDEOGRAPH
+0x8666	0x5502	#CJK UNIFIED IDEOGRAPH
+0x8667	0x5503	#CJK UNIFIED IDEOGRAPH
+0x8668	0x5504	#CJK UNIFIED IDEOGRAPH
+0x8669	0x5505	#CJK UNIFIED IDEOGRAPH
+0x866A	0x5508	#CJK UNIFIED IDEOGRAPH
+0x866B	0x550A	#CJK UNIFIED IDEOGRAPH
+0x866C	0x550B	#CJK UNIFIED IDEOGRAPH
+0x866D	0x550C	#CJK UNIFIED IDEOGRAPH
+0x866E	0x550D	#CJK UNIFIED IDEOGRAPH
+0x866F	0x550E	#CJK UNIFIED IDEOGRAPH
+0x8670	0x5512	#CJK UNIFIED IDEOGRAPH
+0x8671	0x5513	#CJK UNIFIED IDEOGRAPH
+0x8672	0x5515	#CJK UNIFIED IDEOGRAPH
+0x8673	0x5516	#CJK UNIFIED IDEOGRAPH
+0x8674	0x5517	#CJK UNIFIED IDEOGRAPH
+0x8675	0x5518	#CJK UNIFIED IDEOGRAPH
+0x8676	0x5519	#CJK UNIFIED IDEOGRAPH
+0x8677	0x551A	#CJK UNIFIED IDEOGRAPH
+0x8678	0x551C	#CJK UNIFIED IDEOGRAPH
+0x8679	0x551D	#CJK UNIFIED IDEOGRAPH
+0x867A	0x551E	#CJK UNIFIED IDEOGRAPH
+0x867B	0x551F	#CJK UNIFIED IDEOGRAPH
+0x867C	0x5521	#CJK UNIFIED IDEOGRAPH
+0x867D	0x5525	#CJK UNIFIED IDEOGRAPH
+0x867E	0x5526	#CJK UNIFIED IDEOGRAPH
+0x8680	0x5528	#CJK UNIFIED IDEOGRAPH
+0x8681	0x5529	#CJK UNIFIED IDEOGRAPH
+0x8682	0x552B	#CJK UNIFIED IDEOGRAPH
+0x8683	0x552D	#CJK UNIFIED IDEOGRAPH
+0x8684	0x5532	#CJK UNIFIED IDEOGRAPH
+0x8685	0x5534	#CJK UNIFIED IDEOGRAPH
+0x8686	0x5535	#CJK UNIFIED IDEOGRAPH
+0x8687	0x5536	#CJK UNIFIED IDEOGRAPH
+0x8688	0x5538	#CJK UNIFIED IDEOGRAPH
+0x8689	0x5539	#CJK UNIFIED IDEOGRAPH
+0x868A	0x553A	#CJK UNIFIED IDEOGRAPH
+0x868B	0x553B	#CJK UNIFIED IDEOGRAPH
+0x868C	0x553D	#CJK UNIFIED IDEOGRAPH
+0x868D	0x5540	#CJK UNIFIED IDEOGRAPH
+0x868E	0x5542	#CJK UNIFIED IDEOGRAPH
+0x868F	0x5545	#CJK UNIFIED IDEOGRAPH
+0x8690	0x5547	#CJK UNIFIED IDEOGRAPH
+0x8691	0x5548	#CJK UNIFIED IDEOGRAPH
+0x8692	0x554B	#CJK UNIFIED IDEOGRAPH
+0x8693	0x554C	#CJK UNIFIED IDEOGRAPH
+0x8694	0x554D	#CJK UNIFIED IDEOGRAPH
+0x8695	0x554E	#CJK UNIFIED IDEOGRAPH
+0x8696	0x554F	#CJK UNIFIED IDEOGRAPH
+0x8697	0x5551	#CJK UNIFIED IDEOGRAPH
+0x8698	0x5552	#CJK UNIFIED IDEOGRAPH
+0x8699	0x5553	#CJK UNIFIED IDEOGRAPH
+0x869A	0x5554	#CJK UNIFIED IDEOGRAPH
+0x869B	0x5557	#CJK UNIFIED IDEOGRAPH
+0x869C	0x5558	#CJK UNIFIED IDEOGRAPH
+0x869D	0x5559	#CJK UNIFIED IDEOGRAPH
+0x869E	0x555A	#CJK UNIFIED IDEOGRAPH
+0x869F	0x555B	#CJK UNIFIED IDEOGRAPH
+0x86A0	0x555D	#CJK UNIFIED IDEOGRAPH
+0x86A1	0x555E	#CJK UNIFIED IDEOGRAPH
+0x86A2	0x555F	#CJK UNIFIED IDEOGRAPH
+0x86A3	0x5560	#CJK UNIFIED IDEOGRAPH
+0x86A4	0x5562	#CJK UNIFIED IDEOGRAPH
+0x86A5	0x5563	#CJK UNIFIED IDEOGRAPH
+0x86A6	0x5568	#CJK UNIFIED IDEOGRAPH
+0x86A7	0x5569	#CJK UNIFIED IDEOGRAPH
+0x86A8	0x556B	#CJK UNIFIED IDEOGRAPH
+0x86A9	0x556F	#CJK UNIFIED IDEOGRAPH
+0x86AA	0x5570	#CJK UNIFIED IDEOGRAPH
+0x86AB	0x5571	#CJK UNIFIED IDEOGRAPH
+0x86AC	0x5572	#CJK UNIFIED IDEOGRAPH
+0x86AD	0x5573	#CJK UNIFIED IDEOGRAPH
+0x86AE	0x5574	#CJK UNIFIED IDEOGRAPH
+0x86AF	0x5579	#CJK UNIFIED IDEOGRAPH
+0x86B0	0x557A	#CJK UNIFIED IDEOGRAPH
+0x86B1	0x557D	#CJK UNIFIED IDEOGRAPH
+0x86B2	0x557F	#CJK UNIFIED IDEOGRAPH
+0x86B3	0x5585	#CJK UNIFIED IDEOGRAPH
+0x86B4	0x5586	#CJK UNIFIED IDEOGRAPH
+0x86B5	0x558C	#CJK UNIFIED IDEOGRAPH
+0x86B6	0x558D	#CJK UNIFIED IDEOGRAPH
+0x86B7	0x558E	#CJK UNIFIED IDEOGRAPH
+0x86B8	0x5590	#CJK UNIFIED IDEOGRAPH
+0x86B9	0x5592	#CJK UNIFIED IDEOGRAPH
+0x86BA	0x5593	#CJK UNIFIED IDEOGRAPH
+0x86BB	0x5595	#CJK UNIFIED IDEOGRAPH
+0x86BC	0x5596	#CJK UNIFIED IDEOGRAPH
+0x86BD	0x5597	#CJK UNIFIED IDEOGRAPH
+0x86BE	0x559A	#CJK UNIFIED IDEOGRAPH
+0x86BF	0x559B	#CJK UNIFIED IDEOGRAPH
+0x86C0	0x559E	#CJK UNIFIED IDEOGRAPH
+0x86C1	0x55A0	#CJK UNIFIED IDEOGRAPH
+0x86C2	0x55A1	#CJK UNIFIED IDEOGRAPH
+0x86C3	0x55A2	#CJK UNIFIED IDEOGRAPH
+0x86C4	0x55A3	#CJK UNIFIED IDEOGRAPH
+0x86C5	0x55A4	#CJK UNIFIED IDEOGRAPH
+0x86C6	0x55A5	#CJK UNIFIED IDEOGRAPH
+0x86C7	0x55A6	#CJK UNIFIED IDEOGRAPH
+0x86C8	0x55A8	#CJK UNIFIED IDEOGRAPH
+0x86C9	0x55A9	#CJK UNIFIED IDEOGRAPH
+0x86CA	0x55AA	#CJK UNIFIED IDEOGRAPH
+0x86CB	0x55AB	#CJK UNIFIED IDEOGRAPH
+0x86CC	0x55AC	#CJK UNIFIED IDEOGRAPH
+0x86CD	0x55AD	#CJK UNIFIED IDEOGRAPH
+0x86CE	0x55AE	#CJK UNIFIED IDEOGRAPH
+0x86CF	0x55AF	#CJK UNIFIED IDEOGRAPH
+0x86D0	0x55B0	#CJK UNIFIED IDEOGRAPH
+0x86D1	0x55B2	#CJK UNIFIED IDEOGRAPH
+0x86D2	0x55B4	#CJK UNIFIED IDEOGRAPH
+0x86D3	0x55B6	#CJK UNIFIED IDEOGRAPH
+0x86D4	0x55B8	#CJK UNIFIED IDEOGRAPH
+0x86D5	0x55BA	#CJK UNIFIED IDEOGRAPH
+0x86D6	0x55BC	#CJK UNIFIED IDEOGRAPH
+0x86D7	0x55BF	#CJK UNIFIED IDEOGRAPH
+0x86D8	0x55C0	#CJK UNIFIED IDEOGRAPH
+0x86D9	0x55C1	#CJK UNIFIED IDEOGRAPH
+0x86DA	0x55C2	#CJK UNIFIED IDEOGRAPH
+0x86DB	0x55C3	#CJK UNIFIED IDEOGRAPH
+0x86DC	0x55C6	#CJK UNIFIED IDEOGRAPH
+0x86DD	0x55C7	#CJK UNIFIED IDEOGRAPH
+0x86DE	0x55C8	#CJK UNIFIED IDEOGRAPH
+0x86DF	0x55CA	#CJK UNIFIED IDEOGRAPH
+0x86E0	0x55CB	#CJK UNIFIED IDEOGRAPH
+0x86E1	0x55CE	#CJK UNIFIED IDEOGRAPH
+0x86E2	0x55CF	#CJK UNIFIED IDEOGRAPH
+0x86E3	0x55D0	#CJK UNIFIED IDEOGRAPH
+0x86E4	0x55D5	#CJK UNIFIED IDEOGRAPH
+0x86E5	0x55D7	#CJK UNIFIED IDEOGRAPH
+0x86E6	0x55D8	#CJK UNIFIED IDEOGRAPH
+0x86E7	0x55D9	#CJK UNIFIED IDEOGRAPH
+0x86E8	0x55DA	#CJK UNIFIED IDEOGRAPH
+0x86E9	0x55DB	#CJK UNIFIED IDEOGRAPH
+0x86EA	0x55DE	#CJK UNIFIED IDEOGRAPH
+0x86EB	0x55E0	#CJK UNIFIED IDEOGRAPH
+0x86EC	0x55E2	#CJK UNIFIED IDEOGRAPH
+0x86ED	0x55E7	#CJK UNIFIED IDEOGRAPH
+0x86EE	0x55E9	#CJK UNIFIED IDEOGRAPH
+0x86EF	0x55ED	#CJK UNIFIED IDEOGRAPH
+0x86F0	0x55EE	#CJK UNIFIED IDEOGRAPH
+0x86F1	0x55F0	#CJK UNIFIED IDEOGRAPH
+0x86F2	0x55F1	#CJK UNIFIED IDEOGRAPH
+0x86F3	0x55F4	#CJK UNIFIED IDEOGRAPH
+0x86F4	0x55F6	#CJK UNIFIED IDEOGRAPH
+0x86F5	0x55F8	#CJK UNIFIED IDEOGRAPH
+0x86F6	0x55F9	#CJK UNIFIED IDEOGRAPH
+0x86F7	0x55FA	#CJK UNIFIED IDEOGRAPH
+0x86F8	0x55FB	#CJK UNIFIED IDEOGRAPH
+0x86F9	0x55FC	#CJK UNIFIED IDEOGRAPH
+0x86FA	0x55FF	#CJK UNIFIED IDEOGRAPH
+0x86FB	0x5602	#CJK UNIFIED IDEOGRAPH
+0x86FC	0x5603	#CJK UNIFIED IDEOGRAPH
+0x86FD	0x5604	#CJK UNIFIED IDEOGRAPH
+0x86FE	0x5605	#CJK UNIFIED IDEOGRAPH
+0x8740	0x5606	#CJK UNIFIED IDEOGRAPH
+0x8741	0x5607	#CJK UNIFIED IDEOGRAPH
+0x8742	0x560A	#CJK UNIFIED IDEOGRAPH
+0x8743	0x560B	#CJK UNIFIED IDEOGRAPH
+0x8744	0x560D	#CJK UNIFIED IDEOGRAPH
+0x8745	0x5610	#CJK UNIFIED IDEOGRAPH
+0x8746	0x5611	#CJK UNIFIED IDEOGRAPH
+0x8747	0x5612	#CJK UNIFIED IDEOGRAPH
+0x8748	0x5613	#CJK UNIFIED IDEOGRAPH
+0x8749	0x5614	#CJK UNIFIED IDEOGRAPH
+0x874A	0x5615	#CJK UNIFIED IDEOGRAPH
+0x874B	0x5616	#CJK UNIFIED IDEOGRAPH
+0x874C	0x5617	#CJK UNIFIED IDEOGRAPH
+0x874D	0x5619	#CJK UNIFIED IDEOGRAPH
+0x874E	0x561A	#CJK UNIFIED IDEOGRAPH
+0x874F	0x561C	#CJK UNIFIED IDEOGRAPH
+0x8750	0x561D	#CJK UNIFIED IDEOGRAPH
+0x8751	0x5620	#CJK UNIFIED IDEOGRAPH
+0x8752	0x5621	#CJK UNIFIED IDEOGRAPH
+0x8753	0x5622	#CJK UNIFIED IDEOGRAPH
+0x8754	0x5625	#CJK UNIFIED IDEOGRAPH
+0x8755	0x5626	#CJK UNIFIED IDEOGRAPH
+0x8756	0x5628	#CJK UNIFIED IDEOGRAPH
+0x8757	0x5629	#CJK UNIFIED IDEOGRAPH
+0x8758	0x562A	#CJK UNIFIED IDEOGRAPH
+0x8759	0x562B	#CJK UNIFIED IDEOGRAPH
+0x875A	0x562E	#CJK UNIFIED IDEOGRAPH
+0x875B	0x562F	#CJK UNIFIED IDEOGRAPH
+0x875C	0x5630	#CJK UNIFIED IDEOGRAPH
+0x875D	0x5633	#CJK UNIFIED IDEOGRAPH
+0x875E	0x5635	#CJK UNIFIED IDEOGRAPH
+0x875F	0x5637	#CJK UNIFIED IDEOGRAPH
+0x8760	0x5638	#CJK UNIFIED IDEOGRAPH
+0x8761	0x563A	#CJK UNIFIED IDEOGRAPH
+0x8762	0x563C	#CJK UNIFIED IDEOGRAPH
+0x8763	0x563D	#CJK UNIFIED IDEOGRAPH
+0x8764	0x563E	#CJK UNIFIED IDEOGRAPH
+0x8765	0x5640	#CJK UNIFIED IDEOGRAPH
+0x8766	0x5641	#CJK UNIFIED IDEOGRAPH
+0x8767	0x5642	#CJK UNIFIED IDEOGRAPH
+0x8768	0x5643	#CJK UNIFIED IDEOGRAPH
+0x8769	0x5644	#CJK UNIFIED IDEOGRAPH
+0x876A	0x5645	#CJK UNIFIED IDEOGRAPH
+0x876B	0x5646	#CJK UNIFIED IDEOGRAPH
+0x876C	0x5647	#CJK UNIFIED IDEOGRAPH
+0x876D	0x5648	#CJK UNIFIED IDEOGRAPH
+0x876E	0x5649	#CJK UNIFIED IDEOGRAPH
+0x876F	0x564A	#CJK UNIFIED IDEOGRAPH
+0x8770	0x564B	#CJK UNIFIED IDEOGRAPH
+0x8771	0x564F	#CJK UNIFIED IDEOGRAPH
+0x8772	0x5650	#CJK UNIFIED IDEOGRAPH
+0x8773	0x5651	#CJK UNIFIED IDEOGRAPH
+0x8774	0x5652	#CJK UNIFIED IDEOGRAPH
+0x8775	0x5653	#CJK UNIFIED IDEOGRAPH
+0x8776	0x5655	#CJK UNIFIED IDEOGRAPH
+0x8777	0x5656	#CJK UNIFIED IDEOGRAPH
+0x8778	0x565A	#CJK UNIFIED IDEOGRAPH
+0x8779	0x565B	#CJK UNIFIED IDEOGRAPH
+0x877A	0x565D	#CJK UNIFIED IDEOGRAPH
+0x877B	0x565E	#CJK UNIFIED IDEOGRAPH
+0x877C	0x565F	#CJK UNIFIED IDEOGRAPH
+0x877D	0x5660	#CJK UNIFIED IDEOGRAPH
+0x877E	0x5661	#CJK UNIFIED IDEOGRAPH
+0x8780	0x5663	#CJK UNIFIED IDEOGRAPH
+0x8781	0x5665	#CJK UNIFIED IDEOGRAPH
+0x8782	0x5666	#CJK UNIFIED IDEOGRAPH
+0x8783	0x5667	#CJK UNIFIED IDEOGRAPH
+0x8784	0x566D	#CJK UNIFIED IDEOGRAPH
+0x8785	0x566E	#CJK UNIFIED IDEOGRAPH
+0x8786	0x566F	#CJK UNIFIED IDEOGRAPH
+0x8787	0x5670	#CJK UNIFIED IDEOGRAPH
+0x8788	0x5672	#CJK UNIFIED IDEOGRAPH
+0x8789	0x5673	#CJK UNIFIED IDEOGRAPH
+0x878A	0x5674	#CJK UNIFIED IDEOGRAPH
+0x878B	0x5675	#CJK UNIFIED IDEOGRAPH
+0x878C	0x5677	#CJK UNIFIED IDEOGRAPH
+0x878D	0x5678	#CJK UNIFIED IDEOGRAPH
+0x878E	0x5679	#CJK UNIFIED IDEOGRAPH
+0x878F	0x567A	#CJK UNIFIED IDEOGRAPH
+0x8790	0x567D	#CJK UNIFIED IDEOGRAPH
+0x8791	0x567E	#CJK UNIFIED IDEOGRAPH
+0x8792	0x567F	#CJK UNIFIED IDEOGRAPH
+0x8793	0x5680	#CJK UNIFIED IDEOGRAPH
+0x8794	0x5681	#CJK UNIFIED IDEOGRAPH
+0x8795	0x5682	#CJK UNIFIED IDEOGRAPH
+0x8796	0x5683	#CJK UNIFIED IDEOGRAPH
+0x8797	0x5684	#CJK UNIFIED IDEOGRAPH
+0x8798	0x5687	#CJK UNIFIED IDEOGRAPH
+0x8799	0x5688	#CJK UNIFIED IDEOGRAPH
+0x879A	0x5689	#CJK UNIFIED IDEOGRAPH
+0x879B	0x568A	#CJK UNIFIED IDEOGRAPH
+0x879C	0x568B	#CJK UNIFIED IDEOGRAPH
+0x879D	0x568C	#CJK UNIFIED IDEOGRAPH
+0x879E	0x568D	#CJK UNIFIED IDEOGRAPH
+0x879F	0x5690	#CJK UNIFIED IDEOGRAPH
+0x87A0	0x5691	#CJK UNIFIED IDEOGRAPH
+0x87A1	0x5692	#CJK UNIFIED IDEOGRAPH
+0x87A2	0x5694	#CJK UNIFIED IDEOGRAPH
+0x87A3	0x5695	#CJK UNIFIED IDEOGRAPH
+0x87A4	0x5696	#CJK UNIFIED IDEOGRAPH
+0x87A5	0x5697	#CJK UNIFIED IDEOGRAPH
+0x87A6	0x5698	#CJK UNIFIED IDEOGRAPH
+0x87A7	0x5699	#CJK UNIFIED IDEOGRAPH
+0x87A8	0x569A	#CJK UNIFIED IDEOGRAPH
+0x87A9	0x569B	#CJK UNIFIED IDEOGRAPH
+0x87AA	0x569C	#CJK UNIFIED IDEOGRAPH
+0x87AB	0x569D	#CJK UNIFIED IDEOGRAPH
+0x87AC	0x569E	#CJK UNIFIED IDEOGRAPH
+0x87AD	0x569F	#CJK UNIFIED IDEOGRAPH
+0x87AE	0x56A0	#CJK UNIFIED IDEOGRAPH
+0x87AF	0x56A1	#CJK UNIFIED IDEOGRAPH
+0x87B0	0x56A2	#CJK UNIFIED IDEOGRAPH
+0x87B1	0x56A4	#CJK UNIFIED IDEOGRAPH
+0x87B2	0x56A5	#CJK UNIFIED IDEOGRAPH
+0x87B3	0x56A6	#CJK UNIFIED IDEOGRAPH
+0x87B4	0x56A7	#CJK UNIFIED IDEOGRAPH
+0x87B5	0x56A8	#CJK UNIFIED IDEOGRAPH
+0x87B6	0x56A9	#CJK UNIFIED IDEOGRAPH
+0x87B7	0x56AA	#CJK UNIFIED IDEOGRAPH
+0x87B8	0x56AB	#CJK UNIFIED IDEOGRAPH
+0x87B9	0x56AC	#CJK UNIFIED IDEOGRAPH
+0x87BA	0x56AD	#CJK UNIFIED IDEOGRAPH
+0x87BB	0x56AE	#CJK UNIFIED IDEOGRAPH
+0x87BC	0x56B0	#CJK UNIFIED IDEOGRAPH
+0x87BD	0x56B1	#CJK UNIFIED IDEOGRAPH
+0x87BE	0x56B2	#CJK UNIFIED IDEOGRAPH
+0x87BF	0x56B3	#CJK UNIFIED IDEOGRAPH
+0x87C0	0x56B4	#CJK UNIFIED IDEOGRAPH
+0x87C1	0x56B5	#CJK UNIFIED IDEOGRAPH
+0x87C2	0x56B6	#CJK UNIFIED IDEOGRAPH
+0x87C3	0x56B8	#CJK UNIFIED IDEOGRAPH
+0x87C4	0x56B9	#CJK UNIFIED IDEOGRAPH
+0x87C5	0x56BA	#CJK UNIFIED IDEOGRAPH
+0x87C6	0x56BB	#CJK UNIFIED IDEOGRAPH
+0x87C7	0x56BD	#CJK UNIFIED IDEOGRAPH
+0x87C8	0x56BE	#CJK UNIFIED IDEOGRAPH
+0x87C9	0x56BF	#CJK UNIFIED IDEOGRAPH
+0x87CA	0x56C0	#CJK UNIFIED IDEOGRAPH
+0x87CB	0x56C1	#CJK UNIFIED IDEOGRAPH
+0x87CC	0x56C2	#CJK UNIFIED IDEOGRAPH
+0x87CD	0x56C3	#CJK UNIFIED IDEOGRAPH
+0x87CE	0x56C4	#CJK UNIFIED IDEOGRAPH
+0x87CF	0x56C5	#CJK UNIFIED IDEOGRAPH
+0x87D0	0x56C6	#CJK UNIFIED IDEOGRAPH
+0x87D1	0x56C7	#CJK UNIFIED IDEOGRAPH
+0x87D2	0x56C8	#CJK UNIFIED IDEOGRAPH
+0x87D3	0x56C9	#CJK UNIFIED IDEOGRAPH
+0x87D4	0x56CB	#CJK UNIFIED IDEOGRAPH
+0x87D5	0x56CC	#CJK UNIFIED IDEOGRAPH
+0x87D6	0x56CD	#CJK UNIFIED IDEOGRAPH
+0x87D7	0x56CE	#CJK UNIFIED IDEOGRAPH
+0x87D8	0x56CF	#CJK UNIFIED IDEOGRAPH
+0x87D9	0x56D0	#CJK UNIFIED IDEOGRAPH
+0x87DA	0x56D1	#CJK UNIFIED IDEOGRAPH
+0x87DB	0x56D2	#CJK UNIFIED IDEOGRAPH
+0x87DC	0x56D3	#CJK UNIFIED IDEOGRAPH
+0x87DD	0x56D5	#CJK UNIFIED IDEOGRAPH
+0x87DE	0x56D6	#CJK UNIFIED IDEOGRAPH
+0x87DF	0x56D8	#CJK UNIFIED IDEOGRAPH
+0x87E0	0x56D9	#CJK UNIFIED IDEOGRAPH
+0x87E1	0x56DC	#CJK UNIFIED IDEOGRAPH
+0x87E2	0x56E3	#CJK UNIFIED IDEOGRAPH
+0x87E3	0x56E5	#CJK UNIFIED IDEOGRAPH
+0x87E4	0x56E6	#CJK UNIFIED IDEOGRAPH
+0x87E5	0x56E7	#CJK UNIFIED IDEOGRAPH
+0x87E6	0x56E8	#CJK UNIFIED IDEOGRAPH
+0x87E7	0x56E9	#CJK UNIFIED IDEOGRAPH
+0x87E8	0x56EA	#CJK UNIFIED IDEOGRAPH
+0x87E9	0x56EC	#CJK UNIFIED IDEOGRAPH
+0x87EA	0x56EE	#CJK UNIFIED IDEOGRAPH
+0x87EB	0x56EF	#CJK UNIFIED IDEOGRAPH
+0x87EC	0x56F2	#CJK UNIFIED IDEOGRAPH
+0x87ED	0x56F3	#CJK UNIFIED IDEOGRAPH
+0x87EE	0x56F6	#CJK UNIFIED IDEOGRAPH
+0x87EF	0x56F7	#CJK UNIFIED IDEOGRAPH
+0x87F0	0x56F8	#CJK UNIFIED IDEOGRAPH
+0x87F1	0x56FB	#CJK UNIFIED IDEOGRAPH
+0x87F2	0x56FC	#CJK UNIFIED IDEOGRAPH
+0x87F3	0x5700	#CJK UNIFIED IDEOGRAPH
+0x87F4	0x5701	#CJK UNIFIED IDEOGRAPH
+0x87F5	0x5702	#CJK UNIFIED IDEOGRAPH
+0x87F6	0x5705	#CJK UNIFIED IDEOGRAPH
+0x87F7	0x5707	#CJK UNIFIED IDEOGRAPH
+0x87F8	0x570B	#CJK UNIFIED IDEOGRAPH
+0x87F9	0x570C	#CJK UNIFIED IDEOGRAPH
+0x87FA	0x570D	#CJK UNIFIED IDEOGRAPH
+0x87FB	0x570E	#CJK UNIFIED IDEOGRAPH
+0x87FC	0x570F	#CJK UNIFIED IDEOGRAPH
+0x87FD	0x5710	#CJK UNIFIED IDEOGRAPH
+0x87FE	0x5711	#CJK UNIFIED IDEOGRAPH
+0x8840	0x5712	#CJK UNIFIED IDEOGRAPH
+0x8841	0x5713	#CJK UNIFIED IDEOGRAPH
+0x8842	0x5714	#CJK UNIFIED IDEOGRAPH
+0x8843	0x5715	#CJK UNIFIED IDEOGRAPH
+0x8844	0x5716	#CJK UNIFIED IDEOGRAPH
+0x8845	0x5717	#CJK UNIFIED IDEOGRAPH
+0x8846	0x5718	#CJK UNIFIED IDEOGRAPH
+0x8847	0x5719	#CJK UNIFIED IDEOGRAPH
+0x8848	0x571A	#CJK UNIFIED IDEOGRAPH
+0x8849	0x571B	#CJK UNIFIED IDEOGRAPH
+0x884A	0x571D	#CJK UNIFIED IDEOGRAPH
+0x884B	0x571E	#CJK UNIFIED IDEOGRAPH
+0x884C	0x5720	#CJK UNIFIED IDEOGRAPH
+0x884D	0x5721	#CJK UNIFIED IDEOGRAPH
+0x884E	0x5722	#CJK UNIFIED IDEOGRAPH
+0x884F	0x5724	#CJK UNIFIED IDEOGRAPH
+0x8850	0x5725	#CJK UNIFIED IDEOGRAPH
+0x8851	0x5726	#CJK UNIFIED IDEOGRAPH
+0x8852	0x5727	#CJK UNIFIED IDEOGRAPH
+0x8853	0x572B	#CJK UNIFIED IDEOGRAPH
+0x8854	0x5731	#CJK UNIFIED IDEOGRAPH
+0x8855	0x5732	#CJK UNIFIED IDEOGRAPH
+0x8856	0x5734	#CJK UNIFIED IDEOGRAPH
+0x8857	0x5735	#CJK UNIFIED IDEOGRAPH
+0x8858	0x5736	#CJK UNIFIED IDEOGRAPH
+0x8859	0x5737	#CJK UNIFIED IDEOGRAPH
+0x885A	0x5738	#CJK UNIFIED IDEOGRAPH
+0x885B	0x573C	#CJK UNIFIED IDEOGRAPH
+0x885C	0x573D	#CJK UNIFIED IDEOGRAPH
+0x885D	0x573F	#CJK UNIFIED IDEOGRAPH
+0x885E	0x5741	#CJK UNIFIED IDEOGRAPH
+0x885F	0x5743	#CJK UNIFIED IDEOGRAPH
+0x8860	0x5744	#CJK UNIFIED IDEOGRAPH
+0x8861	0x5745	#CJK UNIFIED IDEOGRAPH
+0x8862	0x5746	#CJK UNIFIED IDEOGRAPH
+0x8863	0x5748	#CJK UNIFIED IDEOGRAPH
+0x8864	0x5749	#CJK UNIFIED IDEOGRAPH
+0x8865	0x574B	#CJK UNIFIED IDEOGRAPH
+0x8866	0x5752	#CJK UNIFIED IDEOGRAPH
+0x8867	0x5753	#CJK UNIFIED IDEOGRAPH
+0x8868	0x5754	#CJK UNIFIED IDEOGRAPH
+0x8869	0x5755	#CJK UNIFIED IDEOGRAPH
+0x886A	0x5756	#CJK UNIFIED IDEOGRAPH
+0x886B	0x5758	#CJK UNIFIED IDEOGRAPH
+0x886C	0x5759	#CJK UNIFIED IDEOGRAPH
+0x886D	0x5762	#CJK UNIFIED IDEOGRAPH
+0x886E	0x5763	#CJK UNIFIED IDEOGRAPH
+0x886F	0x5765	#CJK UNIFIED IDEOGRAPH
+0x8870	0x5767	#CJK UNIFIED IDEOGRAPH
+0x8871	0x576C	#CJK UNIFIED IDEOGRAPH
+0x8872	0x576E	#CJK UNIFIED IDEOGRAPH
+0x8873	0x5770	#CJK UNIFIED IDEOGRAPH
+0x8874	0x5771	#CJK UNIFIED IDEOGRAPH
+0x8875	0x5772	#CJK UNIFIED IDEOGRAPH
+0x8876	0x5774	#CJK UNIFIED IDEOGRAPH
+0x8877	0x5775	#CJK UNIFIED IDEOGRAPH
+0x8878	0x5778	#CJK UNIFIED IDEOGRAPH
+0x8879	0x5779	#CJK UNIFIED IDEOGRAPH
+0x887A	0x577A	#CJK UNIFIED IDEOGRAPH
+0x887B	0x577D	#CJK UNIFIED IDEOGRAPH
+0x887C	0x577E	#CJK UNIFIED IDEOGRAPH
+0x887D	0x577F	#CJK UNIFIED IDEOGRAPH
+0x887E	0x5780	#CJK UNIFIED IDEOGRAPH
+0x8880	0x5781	#CJK UNIFIED IDEOGRAPH
+0x8881	0x5787	#CJK UNIFIED IDEOGRAPH
+0x8882	0x5788	#CJK UNIFIED IDEOGRAPH
+0x8883	0x5789	#CJK UNIFIED IDEOGRAPH
+0x8884	0x578A	#CJK UNIFIED IDEOGRAPH
+0x8885	0x578D	#CJK UNIFIED IDEOGRAPH
+0x8886	0x578E	#CJK UNIFIED IDEOGRAPH
+0x8887	0x578F	#CJK UNIFIED IDEOGRAPH
+0x8888	0x5790	#CJK UNIFIED IDEOGRAPH
+0x8889	0x5791	#CJK UNIFIED IDEOGRAPH
+0x888A	0x5794	#CJK UNIFIED IDEOGRAPH
+0x888B	0x5795	#CJK UNIFIED IDEOGRAPH
+0x888C	0x5796	#CJK UNIFIED IDEOGRAPH
+0x888D	0x5797	#CJK UNIFIED IDEOGRAPH
+0x888E	0x5798	#CJK UNIFIED IDEOGRAPH
+0x888F	0x5799	#CJK UNIFIED IDEOGRAPH
+0x8890	0x579A	#CJK UNIFIED IDEOGRAPH
+0x8891	0x579C	#CJK UNIFIED IDEOGRAPH
+0x8892	0x579D	#CJK UNIFIED IDEOGRAPH
+0x8893	0x579E	#CJK UNIFIED IDEOGRAPH
+0x8894	0x579F	#CJK UNIFIED IDEOGRAPH
+0x8895	0x57A5	#CJK UNIFIED IDEOGRAPH
+0x8896	0x57A8	#CJK UNIFIED IDEOGRAPH
+0x8897	0x57AA	#CJK UNIFIED IDEOGRAPH
+0x8898	0x57AC	#CJK UNIFIED IDEOGRAPH
+0x8899	0x57AF	#CJK UNIFIED IDEOGRAPH
+0x889A	0x57B0	#CJK UNIFIED IDEOGRAPH
+0x889B	0x57B1	#CJK UNIFIED IDEOGRAPH
+0x889C	0x57B3	#CJK UNIFIED IDEOGRAPH
+0x889D	0x57B5	#CJK UNIFIED IDEOGRAPH
+0x889E	0x57B6	#CJK UNIFIED IDEOGRAPH
+0x889F	0x57B7	#CJK UNIFIED IDEOGRAPH
+0x88A0	0x57B9	#CJK UNIFIED IDEOGRAPH
+0x88A1	0x57BA	#CJK UNIFIED IDEOGRAPH
+0x88A2	0x57BB	#CJK UNIFIED IDEOGRAPH
+0x88A3	0x57BC	#CJK UNIFIED IDEOGRAPH
+0x88A4	0x57BD	#CJK UNIFIED IDEOGRAPH
+0x88A5	0x57BE	#CJK UNIFIED IDEOGRAPH
+0x88A6	0x57BF	#CJK UNIFIED IDEOGRAPH
+0x88A7	0x57C0	#CJK UNIFIED IDEOGRAPH
+0x88A8	0x57C1	#CJK UNIFIED IDEOGRAPH
+0x88A9	0x57C4	#CJK UNIFIED IDEOGRAPH
+0x88AA	0x57C5	#CJK UNIFIED IDEOGRAPH
+0x88AB	0x57C6	#CJK UNIFIED IDEOGRAPH
+0x88AC	0x57C7	#CJK UNIFIED IDEOGRAPH
+0x88AD	0x57C8	#CJK UNIFIED IDEOGRAPH
+0x88AE	0x57C9	#CJK UNIFIED IDEOGRAPH
+0x88AF	0x57CA	#CJK UNIFIED IDEOGRAPH
+0x88B0	0x57CC	#CJK UNIFIED IDEOGRAPH
+0x88B1	0x57CD	#CJK UNIFIED IDEOGRAPH
+0x88B2	0x57D0	#CJK UNIFIED IDEOGRAPH
+0x88B3	0x57D1	#CJK UNIFIED IDEOGRAPH
+0x88B4	0x57D3	#CJK UNIFIED IDEOGRAPH
+0x88B5	0x57D6	#CJK UNIFIED IDEOGRAPH
+0x88B6	0x57D7	#CJK UNIFIED IDEOGRAPH
+0x88B7	0x57DB	#CJK UNIFIED IDEOGRAPH
+0x88B8	0x57DC	#CJK UNIFIED IDEOGRAPH
+0x88B9	0x57DE	#CJK UNIFIED IDEOGRAPH
+0x88BA	0x57E1	#CJK UNIFIED IDEOGRAPH
+0x88BB	0x57E2	#CJK UNIFIED IDEOGRAPH
+0x88BC	0x57E3	#CJK UNIFIED IDEOGRAPH
+0x88BD	0x57E5	#CJK UNIFIED IDEOGRAPH
+0x88BE	0x57E6	#CJK UNIFIED IDEOGRAPH
+0x88BF	0x57E7	#CJK UNIFIED IDEOGRAPH
+0x88C0	0x57E8	#CJK UNIFIED IDEOGRAPH
+0x88C1	0x57E9	#CJK UNIFIED IDEOGRAPH
+0x88C2	0x57EA	#CJK UNIFIED IDEOGRAPH
+0x88C3	0x57EB	#CJK UNIFIED IDEOGRAPH
+0x88C4	0x57EC	#CJK UNIFIED IDEOGRAPH
+0x88C5	0x57EE	#CJK UNIFIED IDEOGRAPH
+0x88C6	0x57F0	#CJK UNIFIED IDEOGRAPH
+0x88C7	0x57F1	#CJK UNIFIED IDEOGRAPH
+0x88C8	0x57F2	#CJK UNIFIED IDEOGRAPH
+0x88C9	0x57F3	#CJK UNIFIED IDEOGRAPH
+0x88CA	0x57F5	#CJK UNIFIED IDEOGRAPH
+0x88CB	0x57F6	#CJK UNIFIED IDEOGRAPH
+0x88CC	0x57F7	#CJK UNIFIED IDEOGRAPH
+0x88CD	0x57FB	#CJK UNIFIED IDEOGRAPH
+0x88CE	0x57FC	#CJK UNIFIED IDEOGRAPH
+0x88CF	0x57FE	#CJK UNIFIED IDEOGRAPH
+0x88D0	0x57FF	#CJK UNIFIED IDEOGRAPH
+0x88D1	0x5801	#CJK UNIFIED IDEOGRAPH
+0x88D2	0x5803	#CJK UNIFIED IDEOGRAPH
+0x88D3	0x5804	#CJK UNIFIED IDEOGRAPH
+0x88D4	0x5805	#CJK UNIFIED IDEOGRAPH
+0x88D5	0x5808	#CJK UNIFIED IDEOGRAPH
+0x88D6	0x5809	#CJK UNIFIED IDEOGRAPH
+0x88D7	0x580A	#CJK UNIFIED IDEOGRAPH
+0x88D8	0x580C	#CJK UNIFIED IDEOGRAPH
+0x88D9	0x580E	#CJK UNIFIED IDEOGRAPH
+0x88DA	0x580F	#CJK UNIFIED IDEOGRAPH
+0x88DB	0x5810	#CJK UNIFIED IDEOGRAPH
+0x88DC	0x5812	#CJK UNIFIED IDEOGRAPH
+0x88DD	0x5813	#CJK UNIFIED IDEOGRAPH
+0x88DE	0x5814	#CJK UNIFIED IDEOGRAPH
+0x88DF	0x5816	#CJK UNIFIED IDEOGRAPH
+0x88E0	0x5817	#CJK UNIFIED IDEOGRAPH
+0x88E1	0x5818	#CJK UNIFIED IDEOGRAPH
+0x88E2	0x581A	#CJK UNIFIED IDEOGRAPH
+0x88E3	0x581B	#CJK UNIFIED IDEOGRAPH
+0x88E4	0x581C	#CJK UNIFIED IDEOGRAPH
+0x88E5	0x581D	#CJK UNIFIED IDEOGRAPH
+0x88E6	0x581F	#CJK UNIFIED IDEOGRAPH
+0x88E7	0x5822	#CJK UNIFIED IDEOGRAPH
+0x88E8	0x5823	#CJK UNIFIED IDEOGRAPH
+0x88E9	0x5825	#CJK UNIFIED IDEOGRAPH
+0x88EA	0x5826	#CJK UNIFIED IDEOGRAPH
+0x88EB	0x5827	#CJK UNIFIED IDEOGRAPH
+0x88EC	0x5828	#CJK UNIFIED IDEOGRAPH
+0x88ED	0x5829	#CJK UNIFIED IDEOGRAPH
+0x88EE	0x582B	#CJK UNIFIED IDEOGRAPH
+0x88EF	0x582C	#CJK UNIFIED IDEOGRAPH
+0x88F0	0x582D	#CJK UNIFIED IDEOGRAPH
+0x88F1	0x582E	#CJK UNIFIED IDEOGRAPH
+0x88F2	0x582F	#CJK UNIFIED IDEOGRAPH
+0x88F3	0x5831	#CJK UNIFIED IDEOGRAPH
+0x88F4	0x5832	#CJK UNIFIED IDEOGRAPH
+0x88F5	0x5833	#CJK UNIFIED IDEOGRAPH
+0x88F6	0x5834	#CJK UNIFIED IDEOGRAPH
+0x88F7	0x5836	#CJK UNIFIED IDEOGRAPH
+0x88F8	0x5837	#CJK UNIFIED IDEOGRAPH
+0x88F9	0x5838	#CJK UNIFIED IDEOGRAPH
+0x88FA	0x5839	#CJK UNIFIED IDEOGRAPH
+0x88FB	0x583A	#CJK UNIFIED IDEOGRAPH
+0x88FC	0x583B	#CJK UNIFIED IDEOGRAPH
+0x88FD	0x583C	#CJK UNIFIED IDEOGRAPH
+0x88FE	0x583D	#CJK UNIFIED IDEOGRAPH
+0x8940	0x583E	#CJK UNIFIED IDEOGRAPH
+0x8941	0x583F	#CJK UNIFIED IDEOGRAPH
+0x8942	0x5840	#CJK UNIFIED IDEOGRAPH
+0x8943	0x5841	#CJK UNIFIED IDEOGRAPH
+0x8944	0x5842	#CJK UNIFIED IDEOGRAPH
+0x8945	0x5843	#CJK UNIFIED IDEOGRAPH
+0x8946	0x5845	#CJK UNIFIED IDEOGRAPH
+0x8947	0x5846	#CJK UNIFIED IDEOGRAPH
+0x8948	0x5847	#CJK UNIFIED IDEOGRAPH
+0x8949	0x5848	#CJK UNIFIED IDEOGRAPH
+0x894A	0x5849	#CJK UNIFIED IDEOGRAPH
+0x894B	0x584A	#CJK UNIFIED IDEOGRAPH
+0x894C	0x584B	#CJK UNIFIED IDEOGRAPH
+0x894D	0x584E	#CJK UNIFIED IDEOGRAPH
+0x894E	0x584F	#CJK UNIFIED IDEOGRAPH
+0x894F	0x5850	#CJK UNIFIED IDEOGRAPH
+0x8950	0x5852	#CJK UNIFIED IDEOGRAPH
+0x8951	0x5853	#CJK UNIFIED IDEOGRAPH
+0x8952	0x5855	#CJK UNIFIED IDEOGRAPH
+0x8953	0x5856	#CJK UNIFIED IDEOGRAPH
+0x8954	0x5857	#CJK UNIFIED IDEOGRAPH
+0x8955	0x5859	#CJK UNIFIED IDEOGRAPH
+0x8956	0x585A	#CJK UNIFIED IDEOGRAPH
+0x8957	0x585B	#CJK UNIFIED IDEOGRAPH
+0x8958	0x585C	#CJK UNIFIED IDEOGRAPH
+0x8959	0x585D	#CJK UNIFIED IDEOGRAPH
+0x895A	0x585F	#CJK UNIFIED IDEOGRAPH
+0x895B	0x5860	#CJK UNIFIED IDEOGRAPH
+0x895C	0x5861	#CJK UNIFIED IDEOGRAPH
+0x895D	0x5862	#CJK UNIFIED IDEOGRAPH
+0x895E	0x5863	#CJK UNIFIED IDEOGRAPH
+0x895F	0x5864	#CJK UNIFIED IDEOGRAPH
+0x8960	0x5866	#CJK UNIFIED IDEOGRAPH
+0x8961	0x5867	#CJK UNIFIED IDEOGRAPH
+0x8962	0x5868	#CJK UNIFIED IDEOGRAPH
+0x8963	0x5869	#CJK UNIFIED IDEOGRAPH
+0x8964	0x586A	#CJK UNIFIED IDEOGRAPH
+0x8965	0x586D	#CJK UNIFIED IDEOGRAPH
+0x8966	0x586E	#CJK UNIFIED IDEOGRAPH
+0x8967	0x586F	#CJK UNIFIED IDEOGRAPH
+0x8968	0x5870	#CJK UNIFIED IDEOGRAPH
+0x8969	0x5871	#CJK UNIFIED IDEOGRAPH
+0x896A	0x5872	#CJK UNIFIED IDEOGRAPH
+0x896B	0x5873	#CJK UNIFIED IDEOGRAPH
+0x896C	0x5874	#CJK UNIFIED IDEOGRAPH
+0x896D	0x5875	#CJK UNIFIED IDEOGRAPH
+0x896E	0x5876	#CJK UNIFIED IDEOGRAPH
+0x896F	0x5877	#CJK UNIFIED IDEOGRAPH
+0x8970	0x5878	#CJK UNIFIED IDEOGRAPH
+0x8971	0x5879	#CJK UNIFIED IDEOGRAPH
+0x8972	0x587A	#CJK UNIFIED IDEOGRAPH
+0x8973	0x587B	#CJK UNIFIED IDEOGRAPH
+0x8974	0x587C	#CJK UNIFIED IDEOGRAPH
+0x8975	0x587D	#CJK UNIFIED IDEOGRAPH
+0x8976	0x587F	#CJK UNIFIED IDEOGRAPH
+0x8977	0x5882	#CJK UNIFIED IDEOGRAPH
+0x8978	0x5884	#CJK UNIFIED IDEOGRAPH
+0x8979	0x5886	#CJK UNIFIED IDEOGRAPH
+0x897A	0x5887	#CJK UNIFIED IDEOGRAPH
+0x897B	0x5888	#CJK UNIFIED IDEOGRAPH
+0x897C	0x588A	#CJK UNIFIED IDEOGRAPH
+0x897D	0x588B	#CJK UNIFIED IDEOGRAPH
+0x897E	0x588C	#CJK UNIFIED IDEOGRAPH
+0x8980	0x588D	#CJK UNIFIED IDEOGRAPH
+0x8981	0x588E	#CJK UNIFIED IDEOGRAPH
+0x8982	0x588F	#CJK UNIFIED IDEOGRAPH
+0x8983	0x5890	#CJK UNIFIED IDEOGRAPH
+0x8984	0x5891	#CJK UNIFIED IDEOGRAPH
+0x8985	0x5894	#CJK UNIFIED IDEOGRAPH
+0x8986	0x5895	#CJK UNIFIED IDEOGRAPH
+0x8987	0x5896	#CJK UNIFIED IDEOGRAPH
+0x8988	0x5897	#CJK UNIFIED IDEOGRAPH
+0x8989	0x5898	#CJK UNIFIED IDEOGRAPH
+0x898A	0x589B	#CJK UNIFIED IDEOGRAPH
+0x898B	0x589C	#CJK UNIFIED IDEOGRAPH
+0x898C	0x589D	#CJK UNIFIED IDEOGRAPH
+0x898D	0x58A0	#CJK UNIFIED IDEOGRAPH
+0x898E	0x58A1	#CJK UNIFIED IDEOGRAPH
+0x898F	0x58A2	#CJK UNIFIED IDEOGRAPH
+0x8990	0x58A3	#CJK UNIFIED IDEOGRAPH
+0x8991	0x58A4	#CJK UNIFIED IDEOGRAPH
+0x8992	0x58A5	#CJK UNIFIED IDEOGRAPH
+0x8993	0x58A6	#CJK UNIFIED IDEOGRAPH
+0x8994	0x58A7	#CJK UNIFIED IDEOGRAPH
+0x8995	0x58AA	#CJK UNIFIED IDEOGRAPH
+0x8996	0x58AB	#CJK UNIFIED IDEOGRAPH
+0x8997	0x58AC	#CJK UNIFIED IDEOGRAPH
+0x8998	0x58AD	#CJK UNIFIED IDEOGRAPH
+0x8999	0x58AE	#CJK UNIFIED IDEOGRAPH
+0x899A	0x58AF	#CJK UNIFIED IDEOGRAPH
+0x899B	0x58B0	#CJK UNIFIED IDEOGRAPH
+0x899C	0x58B1	#CJK UNIFIED IDEOGRAPH
+0x899D	0x58B2	#CJK UNIFIED IDEOGRAPH
+0x899E	0x58B3	#CJK UNIFIED IDEOGRAPH
+0x899F	0x58B4	#CJK UNIFIED IDEOGRAPH
+0x89A0	0x58B5	#CJK UNIFIED IDEOGRAPH
+0x89A1	0x58B6	#CJK UNIFIED IDEOGRAPH
+0x89A2	0x58B7	#CJK UNIFIED IDEOGRAPH
+0x89A3	0x58B8	#CJK UNIFIED IDEOGRAPH
+0x89A4	0x58B9	#CJK UNIFIED IDEOGRAPH
+0x89A5	0x58BA	#CJK UNIFIED IDEOGRAPH
+0x89A6	0x58BB	#CJK UNIFIED IDEOGRAPH
+0x89A7	0x58BD	#CJK UNIFIED IDEOGRAPH
+0x89A8	0x58BE	#CJK UNIFIED IDEOGRAPH
+0x89A9	0x58BF	#CJK UNIFIED IDEOGRAPH
+0x89AA	0x58C0	#CJK UNIFIED IDEOGRAPH
+0x89AB	0x58C2	#CJK UNIFIED IDEOGRAPH
+0x89AC	0x58C3	#CJK UNIFIED IDEOGRAPH
+0x89AD	0x58C4	#CJK UNIFIED IDEOGRAPH
+0x89AE	0x58C6	#CJK UNIFIED IDEOGRAPH
+0x89AF	0x58C7	#CJK UNIFIED IDEOGRAPH
+0x89B0	0x58C8	#CJK UNIFIED IDEOGRAPH
+0x89B1	0x58C9	#CJK UNIFIED IDEOGRAPH
+0x89B2	0x58CA	#CJK UNIFIED IDEOGRAPH
+0x89B3	0x58CB	#CJK UNIFIED IDEOGRAPH
+0x89B4	0x58CC	#CJK UNIFIED IDEOGRAPH
+0x89B5	0x58CD	#CJK UNIFIED IDEOGRAPH
+0x89B6	0x58CE	#CJK UNIFIED IDEOGRAPH
+0x89B7	0x58CF	#CJK UNIFIED IDEOGRAPH
+0x89B8	0x58D0	#CJK UNIFIED IDEOGRAPH
+0x89B9	0x58D2	#CJK UNIFIED IDEOGRAPH
+0x89BA	0x58D3	#CJK UNIFIED IDEOGRAPH
+0x89BB	0x58D4	#CJK UNIFIED IDEOGRAPH
+0x89BC	0x58D6	#CJK UNIFIED IDEOGRAPH
+0x89BD	0x58D7	#CJK UNIFIED IDEOGRAPH
+0x89BE	0x58D8	#CJK UNIFIED IDEOGRAPH
+0x89BF	0x58D9	#CJK UNIFIED IDEOGRAPH
+0x89C0	0x58DA	#CJK UNIFIED IDEOGRAPH
+0x89C1	0x58DB	#CJK UNIFIED IDEOGRAPH
+0x89C2	0x58DC	#CJK UNIFIED IDEOGRAPH
+0x89C3	0x58DD	#CJK UNIFIED IDEOGRAPH
+0x89C4	0x58DE	#CJK UNIFIED IDEOGRAPH
+0x89C5	0x58DF	#CJK UNIFIED IDEOGRAPH
+0x89C6	0x58E0	#CJK UNIFIED IDEOGRAPH
+0x89C7	0x58E1	#CJK UNIFIED IDEOGRAPH
+0x89C8	0x58E2	#CJK UNIFIED IDEOGRAPH
+0x89C9	0x58E3	#CJK UNIFIED IDEOGRAPH
+0x89CA	0x58E5	#CJK UNIFIED IDEOGRAPH
+0x89CB	0x58E6	#CJK UNIFIED IDEOGRAPH
+0x89CC	0x58E7	#CJK UNIFIED IDEOGRAPH
+0x89CD	0x58E8	#CJK UNIFIED IDEOGRAPH
+0x89CE	0x58E9	#CJK UNIFIED IDEOGRAPH
+0x89CF	0x58EA	#CJK UNIFIED IDEOGRAPH
+0x89D0	0x58ED	#CJK UNIFIED IDEOGRAPH
+0x89D1	0x58EF	#CJK UNIFIED IDEOGRAPH
+0x89D2	0x58F1	#CJK UNIFIED IDEOGRAPH
+0x89D3	0x58F2	#CJK UNIFIED IDEOGRAPH
+0x89D4	0x58F4	#CJK UNIFIED IDEOGRAPH
+0x89D5	0x58F5	#CJK UNIFIED IDEOGRAPH
+0x89D6	0x58F7	#CJK UNIFIED IDEOGRAPH
+0x89D7	0x58F8	#CJK UNIFIED IDEOGRAPH
+0x89D8	0x58FA	#CJK UNIFIED IDEOGRAPH
+0x89D9	0x58FB	#CJK UNIFIED IDEOGRAPH
+0x89DA	0x58FC	#CJK UNIFIED IDEOGRAPH
+0x89DB	0x58FD	#CJK UNIFIED IDEOGRAPH
+0x89DC	0x58FE	#CJK UNIFIED IDEOGRAPH
+0x89DD	0x58FF	#CJK UNIFIED IDEOGRAPH
+0x89DE	0x5900	#CJK UNIFIED IDEOGRAPH
+0x89DF	0x5901	#CJK UNIFIED IDEOGRAPH
+0x89E0	0x5903	#CJK UNIFIED IDEOGRAPH
+0x89E1	0x5905	#CJK UNIFIED IDEOGRAPH
+0x89E2	0x5906	#CJK UNIFIED IDEOGRAPH
+0x89E3	0x5908	#CJK UNIFIED IDEOGRAPH
+0x89E4	0x5909	#CJK UNIFIED IDEOGRAPH
+0x89E5	0x590A	#CJK UNIFIED IDEOGRAPH
+0x89E6	0x590B	#CJK UNIFIED IDEOGRAPH
+0x89E7	0x590C	#CJK UNIFIED IDEOGRAPH
+0x89E8	0x590E	#CJK UNIFIED IDEOGRAPH
+0x89E9	0x5910	#CJK UNIFIED IDEOGRAPH
+0x89EA	0x5911	#CJK UNIFIED IDEOGRAPH
+0x89EB	0x5912	#CJK UNIFIED IDEOGRAPH
+0x89EC	0x5913	#CJK UNIFIED IDEOGRAPH
+0x89ED	0x5917	#CJK UNIFIED IDEOGRAPH
+0x89EE	0x5918	#CJK UNIFIED IDEOGRAPH
+0x89EF	0x591B	#CJK UNIFIED IDEOGRAPH
+0x89F0	0x591D	#CJK UNIFIED IDEOGRAPH
+0x89F1	0x591E	#CJK UNIFIED IDEOGRAPH
+0x89F2	0x5920	#CJK UNIFIED IDEOGRAPH
+0x89F3	0x5921	#CJK UNIFIED IDEOGRAPH
+0x89F4	0x5922	#CJK UNIFIED IDEOGRAPH
+0x89F5	0x5923	#CJK UNIFIED IDEOGRAPH
+0x89F6	0x5926	#CJK UNIFIED IDEOGRAPH
+0x89F7	0x5928	#CJK UNIFIED IDEOGRAPH
+0x89F8	0x592C	#CJK UNIFIED IDEOGRAPH
+0x89F9	0x5930	#CJK UNIFIED IDEOGRAPH
+0x89FA	0x5932	#CJK UNIFIED IDEOGRAPH
+0x89FB	0x5933	#CJK UNIFIED IDEOGRAPH
+0x89FC	0x5935	#CJK UNIFIED IDEOGRAPH
+0x89FD	0x5936	#CJK UNIFIED IDEOGRAPH
+0x89FE	0x593B	#CJK UNIFIED IDEOGRAPH
+0x8A40	0x593D	#CJK UNIFIED IDEOGRAPH
+0x8A41	0x593E	#CJK UNIFIED IDEOGRAPH
+0x8A42	0x593F	#CJK UNIFIED IDEOGRAPH
+0x8A43	0x5940	#CJK UNIFIED IDEOGRAPH
+0x8A44	0x5943	#CJK UNIFIED IDEOGRAPH
+0x8A45	0x5945	#CJK UNIFIED IDEOGRAPH
+0x8A46	0x5946	#CJK UNIFIED IDEOGRAPH
+0x8A47	0x594A	#CJK UNIFIED IDEOGRAPH
+0x8A48	0x594C	#CJK UNIFIED IDEOGRAPH
+0x8A49	0x594D	#CJK UNIFIED IDEOGRAPH
+0x8A4A	0x5950	#CJK UNIFIED IDEOGRAPH
+0x8A4B	0x5952	#CJK UNIFIED IDEOGRAPH
+0x8A4C	0x5953	#CJK UNIFIED IDEOGRAPH
+0x8A4D	0x5959	#CJK UNIFIED IDEOGRAPH
+0x8A4E	0x595B	#CJK UNIFIED IDEOGRAPH
+0x8A4F	0x595C	#CJK UNIFIED IDEOGRAPH
+0x8A50	0x595D	#CJK UNIFIED IDEOGRAPH
+0x8A51	0x595E	#CJK UNIFIED IDEOGRAPH
+0x8A52	0x595F	#CJK UNIFIED IDEOGRAPH
+0x8A53	0x5961	#CJK UNIFIED IDEOGRAPH
+0x8A54	0x5963	#CJK UNIFIED IDEOGRAPH
+0x8A55	0x5964	#CJK UNIFIED IDEOGRAPH
+0x8A56	0x5966	#CJK UNIFIED IDEOGRAPH
+0x8A57	0x5967	#CJK UNIFIED IDEOGRAPH
+0x8A58	0x5968	#CJK UNIFIED IDEOGRAPH
+0x8A59	0x5969	#CJK UNIFIED IDEOGRAPH
+0x8A5A	0x596A	#CJK UNIFIED IDEOGRAPH
+0x8A5B	0x596B	#CJK UNIFIED IDEOGRAPH
+0x8A5C	0x596C	#CJK UNIFIED IDEOGRAPH
+0x8A5D	0x596D	#CJK UNIFIED IDEOGRAPH
+0x8A5E	0x596E	#CJK UNIFIED IDEOGRAPH
+0x8A5F	0x596F	#CJK UNIFIED IDEOGRAPH
+0x8A60	0x5970	#CJK UNIFIED IDEOGRAPH
+0x8A61	0x5971	#CJK UNIFIED IDEOGRAPH
+0x8A62	0x5972	#CJK UNIFIED IDEOGRAPH
+0x8A63	0x5975	#CJK UNIFIED IDEOGRAPH
+0x8A64	0x5977	#CJK UNIFIED IDEOGRAPH
+0x8A65	0x597A	#CJK UNIFIED IDEOGRAPH
+0x8A66	0x597B	#CJK UNIFIED IDEOGRAPH
+0x8A67	0x597C	#CJK UNIFIED IDEOGRAPH
+0x8A68	0x597E	#CJK UNIFIED IDEOGRAPH
+0x8A69	0x597F	#CJK UNIFIED IDEOGRAPH
+0x8A6A	0x5980	#CJK UNIFIED IDEOGRAPH
+0x8A6B	0x5985	#CJK UNIFIED IDEOGRAPH
+0x8A6C	0x5989	#CJK UNIFIED IDEOGRAPH
+0x8A6D	0x598B	#CJK UNIFIED IDEOGRAPH
+0x8A6E	0x598C	#CJK UNIFIED IDEOGRAPH
+0x8A6F	0x598E	#CJK UNIFIED IDEOGRAPH
+0x8A70	0x598F	#CJK UNIFIED IDEOGRAPH
+0x8A71	0x5990	#CJK UNIFIED IDEOGRAPH
+0x8A72	0x5991	#CJK UNIFIED IDEOGRAPH
+0x8A73	0x5994	#CJK UNIFIED IDEOGRAPH
+0x8A74	0x5995	#CJK UNIFIED IDEOGRAPH
+0x8A75	0x5998	#CJK UNIFIED IDEOGRAPH
+0x8A76	0x599A	#CJK UNIFIED IDEOGRAPH
+0x8A77	0x599B	#CJK UNIFIED IDEOGRAPH
+0x8A78	0x599C	#CJK UNIFIED IDEOGRAPH
+0x8A79	0x599D	#CJK UNIFIED IDEOGRAPH
+0x8A7A	0x599F	#CJK UNIFIED IDEOGRAPH
+0x8A7B	0x59A0	#CJK UNIFIED IDEOGRAPH
+0x8A7C	0x59A1	#CJK UNIFIED IDEOGRAPH
+0x8A7D	0x59A2	#CJK UNIFIED IDEOGRAPH
+0x8A7E	0x59A6	#CJK UNIFIED IDEOGRAPH
+0x8A80	0x59A7	#CJK UNIFIED IDEOGRAPH
+0x8A81	0x59AC	#CJK UNIFIED IDEOGRAPH
+0x8A82	0x59AD	#CJK UNIFIED IDEOGRAPH
+0x8A83	0x59B0	#CJK UNIFIED IDEOGRAPH
+0x8A84	0x59B1	#CJK UNIFIED IDEOGRAPH
+0x8A85	0x59B3	#CJK UNIFIED IDEOGRAPH
+0x8A86	0x59B4	#CJK UNIFIED IDEOGRAPH
+0x8A87	0x59B5	#CJK UNIFIED IDEOGRAPH
+0x8A88	0x59B6	#CJK UNIFIED IDEOGRAPH
+0x8A89	0x59B7	#CJK UNIFIED IDEOGRAPH
+0x8A8A	0x59B8	#CJK UNIFIED IDEOGRAPH
+0x8A8B	0x59BA	#CJK UNIFIED IDEOGRAPH
+0x8A8C	0x59BC	#CJK UNIFIED IDEOGRAPH
+0x8A8D	0x59BD	#CJK UNIFIED IDEOGRAPH
+0x8A8E	0x59BF	#CJK UNIFIED IDEOGRAPH
+0x8A8F	0x59C0	#CJK UNIFIED IDEOGRAPH
+0x8A90	0x59C1	#CJK UNIFIED IDEOGRAPH
+0x8A91	0x59C2	#CJK UNIFIED IDEOGRAPH
+0x8A92	0x59C3	#CJK UNIFIED IDEOGRAPH
+0x8A93	0x59C4	#CJK UNIFIED IDEOGRAPH
+0x8A94	0x59C5	#CJK UNIFIED IDEOGRAPH
+0x8A95	0x59C7	#CJK UNIFIED IDEOGRAPH
+0x8A96	0x59C8	#CJK UNIFIED IDEOGRAPH
+0x8A97	0x59C9	#CJK UNIFIED IDEOGRAPH
+0x8A98	0x59CC	#CJK UNIFIED IDEOGRAPH
+0x8A99	0x59CD	#CJK UNIFIED IDEOGRAPH
+0x8A9A	0x59CE	#CJK UNIFIED IDEOGRAPH
+0x8A9B	0x59CF	#CJK UNIFIED IDEOGRAPH
+0x8A9C	0x59D5	#CJK UNIFIED IDEOGRAPH
+0x8A9D	0x59D6	#CJK UNIFIED IDEOGRAPH
+0x8A9E	0x59D9	#CJK UNIFIED IDEOGRAPH
+0x8A9F	0x59DB	#CJK UNIFIED IDEOGRAPH
+0x8AA0	0x59DE	#CJK UNIFIED IDEOGRAPH
+0x8AA1	0x59DF	#CJK UNIFIED IDEOGRAPH
+0x8AA2	0x59E0	#CJK UNIFIED IDEOGRAPH
+0x8AA3	0x59E1	#CJK UNIFIED IDEOGRAPH
+0x8AA4	0x59E2	#CJK UNIFIED IDEOGRAPH
+0x8AA5	0x59E4	#CJK UNIFIED IDEOGRAPH
+0x8AA6	0x59E6	#CJK UNIFIED IDEOGRAPH
+0x8AA7	0x59E7	#CJK UNIFIED IDEOGRAPH
+0x8AA8	0x59E9	#CJK UNIFIED IDEOGRAPH
+0x8AA9	0x59EA	#CJK UNIFIED IDEOGRAPH
+0x8AAA	0x59EB	#CJK UNIFIED IDEOGRAPH
+0x8AAB	0x59ED	#CJK UNIFIED IDEOGRAPH
+0x8AAC	0x59EE	#CJK UNIFIED IDEOGRAPH
+0x8AAD	0x59EF	#CJK UNIFIED IDEOGRAPH
+0x8AAE	0x59F0	#CJK UNIFIED IDEOGRAPH
+0x8AAF	0x59F1	#CJK UNIFIED IDEOGRAPH
+0x8AB0	0x59F2	#CJK UNIFIED IDEOGRAPH
+0x8AB1	0x59F3	#CJK UNIFIED IDEOGRAPH
+0x8AB2	0x59F4	#CJK UNIFIED IDEOGRAPH
+0x8AB3	0x59F5	#CJK UNIFIED IDEOGRAPH
+0x8AB4	0x59F6	#CJK UNIFIED IDEOGRAPH
+0x8AB5	0x59F7	#CJK UNIFIED IDEOGRAPH
+0x8AB6	0x59F8	#CJK UNIFIED IDEOGRAPH
+0x8AB7	0x59FA	#CJK UNIFIED IDEOGRAPH
+0x8AB8	0x59FC	#CJK UNIFIED IDEOGRAPH
+0x8AB9	0x59FD	#CJK UNIFIED IDEOGRAPH
+0x8ABA	0x59FE	#CJK UNIFIED IDEOGRAPH
+0x8ABB	0x5A00	#CJK UNIFIED IDEOGRAPH
+0x8ABC	0x5A02	#CJK UNIFIED IDEOGRAPH
+0x8ABD	0x5A0A	#CJK UNIFIED IDEOGRAPH
+0x8ABE	0x5A0B	#CJK UNIFIED IDEOGRAPH
+0x8ABF	0x5A0D	#CJK UNIFIED IDEOGRAPH
+0x8AC0	0x5A0E	#CJK UNIFIED IDEOGRAPH
+0x8AC1	0x5A0F	#CJK UNIFIED IDEOGRAPH
+0x8AC2	0x5A10	#CJK UNIFIED IDEOGRAPH
+0x8AC3	0x5A12	#CJK UNIFIED IDEOGRAPH
+0x8AC4	0x5A14	#CJK UNIFIED IDEOGRAPH
+0x8AC5	0x5A15	#CJK UNIFIED IDEOGRAPH
+0x8AC6	0x5A16	#CJK UNIFIED IDEOGRAPH
+0x8AC7	0x5A17	#CJK UNIFIED IDEOGRAPH
+0x8AC8	0x5A19	#CJK UNIFIED IDEOGRAPH
+0x8AC9	0x5A1A	#CJK UNIFIED IDEOGRAPH
+0x8ACA	0x5A1B	#CJK UNIFIED IDEOGRAPH
+0x8ACB	0x5A1D	#CJK UNIFIED IDEOGRAPH
+0x8ACC	0x5A1E	#CJK UNIFIED IDEOGRAPH
+0x8ACD	0x5A21	#CJK UNIFIED IDEOGRAPH
+0x8ACE	0x5A22	#CJK UNIFIED IDEOGRAPH
+0x8ACF	0x5A24	#CJK UNIFIED IDEOGRAPH
+0x8AD0	0x5A26	#CJK UNIFIED IDEOGRAPH
+0x8AD1	0x5A27	#CJK UNIFIED IDEOGRAPH
+0x8AD2	0x5A28	#CJK UNIFIED IDEOGRAPH
+0x8AD3	0x5A2A	#CJK UNIFIED IDEOGRAPH
+0x8AD4	0x5A2B	#CJK UNIFIED IDEOGRAPH
+0x8AD5	0x5A2C	#CJK UNIFIED IDEOGRAPH
+0x8AD6	0x5A2D	#CJK UNIFIED IDEOGRAPH
+0x8AD7	0x5A2E	#CJK UNIFIED IDEOGRAPH
+0x8AD8	0x5A2F	#CJK UNIFIED IDEOGRAPH
+0x8AD9	0x5A30	#CJK UNIFIED IDEOGRAPH
+0x8ADA	0x5A33	#CJK UNIFIED IDEOGRAPH
+0x8ADB	0x5A35	#CJK UNIFIED IDEOGRAPH
+0x8ADC	0x5A37	#CJK UNIFIED IDEOGRAPH
+0x8ADD	0x5A38	#CJK UNIFIED IDEOGRAPH
+0x8ADE	0x5A39	#CJK UNIFIED IDEOGRAPH
+0x8ADF	0x5A3A	#CJK UNIFIED IDEOGRAPH
+0x8AE0	0x5A3B	#CJK UNIFIED IDEOGRAPH
+0x8AE1	0x5A3D	#CJK UNIFIED IDEOGRAPH
+0x8AE2	0x5A3E	#CJK UNIFIED IDEOGRAPH
+0x8AE3	0x5A3F	#CJK UNIFIED IDEOGRAPH
+0x8AE4	0x5A41	#CJK UNIFIED IDEOGRAPH
+0x8AE5	0x5A42	#CJK UNIFIED IDEOGRAPH
+0x8AE6	0x5A43	#CJK UNIFIED IDEOGRAPH
+0x8AE7	0x5A44	#CJK UNIFIED IDEOGRAPH
+0x8AE8	0x5A45	#CJK UNIFIED IDEOGRAPH
+0x8AE9	0x5A47	#CJK UNIFIED IDEOGRAPH
+0x8AEA	0x5A48	#CJK UNIFIED IDEOGRAPH
+0x8AEB	0x5A4B	#CJK UNIFIED IDEOGRAPH
+0x8AEC	0x5A4C	#CJK UNIFIED IDEOGRAPH
+0x8AED	0x5A4D	#CJK UNIFIED IDEOGRAPH
+0x8AEE	0x5A4E	#CJK UNIFIED IDEOGRAPH
+0x8AEF	0x5A4F	#CJK UNIFIED IDEOGRAPH
+0x8AF0	0x5A50	#CJK UNIFIED IDEOGRAPH
+0x8AF1	0x5A51	#CJK UNIFIED IDEOGRAPH
+0x8AF2	0x5A52	#CJK UNIFIED IDEOGRAPH
+0x8AF3	0x5A53	#CJK UNIFIED IDEOGRAPH
+0x8AF4	0x5A54	#CJK UNIFIED IDEOGRAPH
+0x8AF5	0x5A56	#CJK UNIFIED IDEOGRAPH
+0x8AF6	0x5A57	#CJK UNIFIED IDEOGRAPH
+0x8AF7	0x5A58	#CJK UNIFIED IDEOGRAPH
+0x8AF8	0x5A59	#CJK UNIFIED IDEOGRAPH
+0x8AF9	0x5A5B	#CJK UNIFIED IDEOGRAPH
+0x8AFA	0x5A5C	#CJK UNIFIED IDEOGRAPH
+0x8AFB	0x5A5D	#CJK UNIFIED IDEOGRAPH
+0x8AFC	0x5A5E	#CJK UNIFIED IDEOGRAPH
+0x8AFD	0x5A5F	#CJK UNIFIED IDEOGRAPH
+0x8AFE	0x5A60	#CJK UNIFIED IDEOGRAPH
+0x8B40	0x5A61	#CJK UNIFIED IDEOGRAPH
+0x8B41	0x5A63	#CJK UNIFIED IDEOGRAPH
+0x8B42	0x5A64	#CJK UNIFIED IDEOGRAPH
+0x8B43	0x5A65	#CJK UNIFIED IDEOGRAPH
+0x8B44	0x5A66	#CJK UNIFIED IDEOGRAPH
+0x8B45	0x5A68	#CJK UNIFIED IDEOGRAPH
+0x8B46	0x5A69	#CJK UNIFIED IDEOGRAPH
+0x8B47	0x5A6B	#CJK UNIFIED IDEOGRAPH
+0x8B48	0x5A6C	#CJK UNIFIED IDEOGRAPH
+0x8B49	0x5A6D	#CJK UNIFIED IDEOGRAPH
+0x8B4A	0x5A6E	#CJK UNIFIED IDEOGRAPH
+0x8B4B	0x5A6F	#CJK UNIFIED IDEOGRAPH
+0x8B4C	0x5A70	#CJK UNIFIED IDEOGRAPH
+0x8B4D	0x5A71	#CJK UNIFIED IDEOGRAPH
+0x8B4E	0x5A72	#CJK UNIFIED IDEOGRAPH
+0x8B4F	0x5A73	#CJK UNIFIED IDEOGRAPH
+0x8B50	0x5A78	#CJK UNIFIED IDEOGRAPH
+0x8B51	0x5A79	#CJK UNIFIED IDEOGRAPH
+0x8B52	0x5A7B	#CJK UNIFIED IDEOGRAPH
+0x8B53	0x5A7C	#CJK UNIFIED IDEOGRAPH
+0x8B54	0x5A7D	#CJK UNIFIED IDEOGRAPH
+0x8B55	0x5A7E	#CJK UNIFIED IDEOGRAPH
+0x8B56	0x5A80	#CJK UNIFIED IDEOGRAPH
+0x8B57	0x5A81	#CJK UNIFIED IDEOGRAPH
+0x8B58	0x5A82	#CJK UNIFIED IDEOGRAPH
+0x8B59	0x5A83	#CJK UNIFIED IDEOGRAPH
+0x8B5A	0x5A84	#CJK UNIFIED IDEOGRAPH
+0x8B5B	0x5A85	#CJK UNIFIED IDEOGRAPH
+0x8B5C	0x5A86	#CJK UNIFIED IDEOGRAPH
+0x8B5D	0x5A87	#CJK UNIFIED IDEOGRAPH
+0x8B5E	0x5A88	#CJK UNIFIED IDEOGRAPH
+0x8B5F	0x5A89	#CJK UNIFIED IDEOGRAPH
+0x8B60	0x5A8A	#CJK UNIFIED IDEOGRAPH
+0x8B61	0x5A8B	#CJK UNIFIED IDEOGRAPH
+0x8B62	0x5A8C	#CJK UNIFIED IDEOGRAPH
+0x8B63	0x5A8D	#CJK UNIFIED IDEOGRAPH
+0x8B64	0x5A8E	#CJK UNIFIED IDEOGRAPH
+0x8B65	0x5A8F	#CJK UNIFIED IDEOGRAPH
+0x8B66	0x5A90	#CJK UNIFIED IDEOGRAPH
+0x8B67	0x5A91	#CJK UNIFIED IDEOGRAPH
+0x8B68	0x5A93	#CJK UNIFIED IDEOGRAPH
+0x8B69	0x5A94	#CJK UNIFIED IDEOGRAPH
+0x8B6A	0x5A95	#CJK UNIFIED IDEOGRAPH
+0x8B6B	0x5A96	#CJK UNIFIED IDEOGRAPH
+0x8B6C	0x5A97	#CJK UNIFIED IDEOGRAPH
+0x8B6D	0x5A98	#CJK UNIFIED IDEOGRAPH
+0x8B6E	0x5A99	#CJK UNIFIED IDEOGRAPH
+0x8B6F	0x5A9C	#CJK UNIFIED IDEOGRAPH
+0x8B70	0x5A9D	#CJK UNIFIED IDEOGRAPH
+0x8B71	0x5A9E	#CJK UNIFIED IDEOGRAPH
+0x8B72	0x5A9F	#CJK UNIFIED IDEOGRAPH
+0x8B73	0x5AA0	#CJK UNIFIED IDEOGRAPH
+0x8B74	0x5AA1	#CJK UNIFIED IDEOGRAPH
+0x8B75	0x5AA2	#CJK UNIFIED IDEOGRAPH
+0x8B76	0x5AA3	#CJK UNIFIED IDEOGRAPH
+0x8B77	0x5AA4	#CJK UNIFIED IDEOGRAPH
+0x8B78	0x5AA5	#CJK UNIFIED IDEOGRAPH
+0x8B79	0x5AA6	#CJK UNIFIED IDEOGRAPH
+0x8B7A	0x5AA7	#CJK UNIFIED IDEOGRAPH
+0x8B7B	0x5AA8	#CJK UNIFIED IDEOGRAPH
+0x8B7C	0x5AA9	#CJK UNIFIED IDEOGRAPH
+0x8B7D	0x5AAB	#CJK UNIFIED IDEOGRAPH
+0x8B7E	0x5AAC	#CJK UNIFIED IDEOGRAPH
+0x8B80	0x5AAD	#CJK UNIFIED IDEOGRAPH
+0x8B81	0x5AAE	#CJK UNIFIED IDEOGRAPH
+0x8B82	0x5AAF	#CJK UNIFIED IDEOGRAPH
+0x8B83	0x5AB0	#CJK UNIFIED IDEOGRAPH
+0x8B84	0x5AB1	#CJK UNIFIED IDEOGRAPH
+0x8B85	0x5AB4	#CJK UNIFIED IDEOGRAPH
+0x8B86	0x5AB6	#CJK UNIFIED IDEOGRAPH
+0x8B87	0x5AB7	#CJK UNIFIED IDEOGRAPH
+0x8B88	0x5AB9	#CJK UNIFIED IDEOGRAPH
+0x8B89	0x5ABA	#CJK UNIFIED IDEOGRAPH
+0x8B8A	0x5ABB	#CJK UNIFIED IDEOGRAPH
+0x8B8B	0x5ABC	#CJK UNIFIED IDEOGRAPH
+0x8B8C	0x5ABD	#CJK UNIFIED IDEOGRAPH
+0x8B8D	0x5ABF	#CJK UNIFIED IDEOGRAPH
+0x8B8E	0x5AC0	#CJK UNIFIED IDEOGRAPH
+0x8B8F	0x5AC3	#CJK UNIFIED IDEOGRAPH
+0x8B90	0x5AC4	#CJK UNIFIED IDEOGRAPH
+0x8B91	0x5AC5	#CJK UNIFIED IDEOGRAPH
+0x8B92	0x5AC6	#CJK UNIFIED IDEOGRAPH
+0x8B93	0x5AC7	#CJK UNIFIED IDEOGRAPH
+0x8B94	0x5AC8	#CJK UNIFIED IDEOGRAPH
+0x8B95	0x5ACA	#CJK UNIFIED IDEOGRAPH
+0x8B96	0x5ACB	#CJK UNIFIED IDEOGRAPH
+0x8B97	0x5ACD	#CJK UNIFIED IDEOGRAPH
+0x8B98	0x5ACE	#CJK UNIFIED IDEOGRAPH
+0x8B99	0x5ACF	#CJK UNIFIED IDEOGRAPH
+0x8B9A	0x5AD0	#CJK UNIFIED IDEOGRAPH
+0x8B9B	0x5AD1	#CJK UNIFIED IDEOGRAPH
+0x8B9C	0x5AD3	#CJK UNIFIED IDEOGRAPH
+0x8B9D	0x5AD5	#CJK UNIFIED IDEOGRAPH
+0x8B9E	0x5AD7	#CJK UNIFIED IDEOGRAPH
+0x8B9F	0x5AD9	#CJK UNIFIED IDEOGRAPH
+0x8BA0	0x5ADA	#CJK UNIFIED IDEOGRAPH
+0x8BA1	0x5ADB	#CJK UNIFIED IDEOGRAPH
+0x8BA2	0x5ADD	#CJK UNIFIED IDEOGRAPH
+0x8BA3	0x5ADE	#CJK UNIFIED IDEOGRAPH
+0x8BA4	0x5ADF	#CJK UNIFIED IDEOGRAPH
+0x8BA5	0x5AE2	#CJK UNIFIED IDEOGRAPH
+0x8BA6	0x5AE4	#CJK UNIFIED IDEOGRAPH
+0x8BA7	0x5AE5	#CJK UNIFIED IDEOGRAPH
+0x8BA8	0x5AE7	#CJK UNIFIED IDEOGRAPH
+0x8BA9	0x5AE8	#CJK UNIFIED IDEOGRAPH
+0x8BAA	0x5AEA	#CJK UNIFIED IDEOGRAPH
+0x8BAB	0x5AEC	#CJK UNIFIED IDEOGRAPH
+0x8BAC	0x5AED	#CJK UNIFIED IDEOGRAPH
+0x8BAD	0x5AEE	#CJK UNIFIED IDEOGRAPH
+0x8BAE	0x5AEF	#CJK UNIFIED IDEOGRAPH
+0x8BAF	0x5AF0	#CJK UNIFIED IDEOGRAPH
+0x8BB0	0x5AF2	#CJK UNIFIED IDEOGRAPH
+0x8BB1	0x5AF3	#CJK UNIFIED IDEOGRAPH
+0x8BB2	0x5AF4	#CJK UNIFIED IDEOGRAPH
+0x8BB3	0x5AF5	#CJK UNIFIED IDEOGRAPH
+0x8BB4	0x5AF6	#CJK UNIFIED IDEOGRAPH
+0x8BB5	0x5AF7	#CJK UNIFIED IDEOGRAPH
+0x8BB6	0x5AF8	#CJK UNIFIED IDEOGRAPH
+0x8BB7	0x5AF9	#CJK UNIFIED IDEOGRAPH
+0x8BB8	0x5AFA	#CJK UNIFIED IDEOGRAPH
+0x8BB9	0x5AFB	#CJK UNIFIED IDEOGRAPH
+0x8BBA	0x5AFC	#CJK UNIFIED IDEOGRAPH
+0x8BBB	0x5AFD	#CJK UNIFIED IDEOGRAPH
+0x8BBC	0x5AFE	#CJK UNIFIED IDEOGRAPH
+0x8BBD	0x5AFF	#CJK UNIFIED IDEOGRAPH
+0x8BBE	0x5B00	#CJK UNIFIED IDEOGRAPH
+0x8BBF	0x5B01	#CJK UNIFIED IDEOGRAPH
+0x8BC0	0x5B02	#CJK UNIFIED IDEOGRAPH
+0x8BC1	0x5B03	#CJK UNIFIED IDEOGRAPH
+0x8BC2	0x5B04	#CJK UNIFIED IDEOGRAPH
+0x8BC3	0x5B05	#CJK UNIFIED IDEOGRAPH
+0x8BC4	0x5B06	#CJK UNIFIED IDEOGRAPH
+0x8BC5	0x5B07	#CJK UNIFIED IDEOGRAPH
+0x8BC6	0x5B08	#CJK UNIFIED IDEOGRAPH
+0x8BC7	0x5B0A	#CJK UNIFIED IDEOGRAPH
+0x8BC8	0x5B0B	#CJK UNIFIED IDEOGRAPH
+0x8BC9	0x5B0C	#CJK UNIFIED IDEOGRAPH
+0x8BCA	0x5B0D	#CJK UNIFIED IDEOGRAPH
+0x8BCB	0x5B0E	#CJK UNIFIED IDEOGRAPH
+0x8BCC	0x5B0F	#CJK UNIFIED IDEOGRAPH
+0x8BCD	0x5B10	#CJK UNIFIED IDEOGRAPH
+0x8BCE	0x5B11	#CJK UNIFIED IDEOGRAPH
+0x8BCF	0x5B12	#CJK UNIFIED IDEOGRAPH
+0x8BD0	0x5B13	#CJK UNIFIED IDEOGRAPH
+0x8BD1	0x5B14	#CJK UNIFIED IDEOGRAPH
+0x8BD2	0x5B15	#CJK UNIFIED IDEOGRAPH
+0x8BD3	0x5B18	#CJK UNIFIED IDEOGRAPH
+0x8BD4	0x5B19	#CJK UNIFIED IDEOGRAPH
+0x8BD5	0x5B1A	#CJK UNIFIED IDEOGRAPH
+0x8BD6	0x5B1B	#CJK UNIFIED IDEOGRAPH
+0x8BD7	0x5B1C	#CJK UNIFIED IDEOGRAPH
+0x8BD8	0x5B1D	#CJK UNIFIED IDEOGRAPH
+0x8BD9	0x5B1E	#CJK UNIFIED IDEOGRAPH
+0x8BDA	0x5B1F	#CJK UNIFIED IDEOGRAPH
+0x8BDB	0x5B20	#CJK UNIFIED IDEOGRAPH
+0x8BDC	0x5B21	#CJK UNIFIED IDEOGRAPH
+0x8BDD	0x5B22	#CJK UNIFIED IDEOGRAPH
+0x8BDE	0x5B23	#CJK UNIFIED IDEOGRAPH
+0x8BDF	0x5B24	#CJK UNIFIED IDEOGRAPH
+0x8BE0	0x5B25	#CJK UNIFIED IDEOGRAPH
+0x8BE1	0x5B26	#CJK UNIFIED IDEOGRAPH
+0x8BE2	0x5B27	#CJK UNIFIED IDEOGRAPH
+0x8BE3	0x5B28	#CJK UNIFIED IDEOGRAPH
+0x8BE4	0x5B29	#CJK UNIFIED IDEOGRAPH
+0x8BE5	0x5B2A	#CJK UNIFIED IDEOGRAPH
+0x8BE6	0x5B2B	#CJK UNIFIED IDEOGRAPH
+0x8BE7	0x5B2C	#CJK UNIFIED IDEOGRAPH
+0x8BE8	0x5B2D	#CJK UNIFIED IDEOGRAPH
+0x8BE9	0x5B2E	#CJK UNIFIED IDEOGRAPH
+0x8BEA	0x5B2F	#CJK UNIFIED IDEOGRAPH
+0x8BEB	0x5B30	#CJK UNIFIED IDEOGRAPH
+0x8BEC	0x5B31	#CJK UNIFIED IDEOGRAPH
+0x8BED	0x5B33	#CJK UNIFIED IDEOGRAPH
+0x8BEE	0x5B35	#CJK UNIFIED IDEOGRAPH
+0x8BEF	0x5B36	#CJK UNIFIED IDEOGRAPH
+0x8BF0	0x5B38	#CJK UNIFIED IDEOGRAPH
+0x8BF1	0x5B39	#CJK UNIFIED IDEOGRAPH
+0x8BF2	0x5B3A	#CJK UNIFIED IDEOGRAPH
+0x8BF3	0x5B3B	#CJK UNIFIED IDEOGRAPH
+0x8BF4	0x5B3C	#CJK UNIFIED IDEOGRAPH
+0x8BF5	0x5B3D	#CJK UNIFIED IDEOGRAPH
+0x8BF6	0x5B3E	#CJK UNIFIED IDEOGRAPH
+0x8BF7	0x5B3F	#CJK UNIFIED IDEOGRAPH
+0x8BF8	0x5B41	#CJK UNIFIED IDEOGRAPH
+0x8BF9	0x5B42	#CJK UNIFIED IDEOGRAPH
+0x8BFA	0x5B43	#CJK UNIFIED IDEOGRAPH
+0x8BFB	0x5B44	#CJK UNIFIED IDEOGRAPH
+0x8BFC	0x5B45	#CJK UNIFIED IDEOGRAPH
+0x8BFD	0x5B46	#CJK UNIFIED IDEOGRAPH
+0x8BFE	0x5B47	#CJK UNIFIED IDEOGRAPH
+0x8C40	0x5B48	#CJK UNIFIED IDEOGRAPH
+0x8C41	0x5B49	#CJK UNIFIED IDEOGRAPH
+0x8C42	0x5B4A	#CJK UNIFIED IDEOGRAPH
+0x8C43	0x5B4B	#CJK UNIFIED IDEOGRAPH
+0x8C44	0x5B4C	#CJK UNIFIED IDEOGRAPH
+0x8C45	0x5B4D	#CJK UNIFIED IDEOGRAPH
+0x8C46	0x5B4E	#CJK UNIFIED IDEOGRAPH
+0x8C47	0x5B4F	#CJK UNIFIED IDEOGRAPH
+0x8C48	0x5B52	#CJK UNIFIED IDEOGRAPH
+0x8C49	0x5B56	#CJK UNIFIED IDEOGRAPH
+0x8C4A	0x5B5E	#CJK UNIFIED IDEOGRAPH
+0x8C4B	0x5B60	#CJK UNIFIED IDEOGRAPH
+0x8C4C	0x5B61	#CJK UNIFIED IDEOGRAPH
+0x8C4D	0x5B67	#CJK UNIFIED IDEOGRAPH
+0x8C4E	0x5B68	#CJK UNIFIED IDEOGRAPH
+0x8C4F	0x5B6B	#CJK UNIFIED IDEOGRAPH
+0x8C50	0x5B6D	#CJK UNIFIED IDEOGRAPH
+0x8C51	0x5B6E	#CJK UNIFIED IDEOGRAPH
+0x8C52	0x5B6F	#CJK UNIFIED IDEOGRAPH
+0x8C53	0x5B72	#CJK UNIFIED IDEOGRAPH
+0x8C54	0x5B74	#CJK UNIFIED IDEOGRAPH
+0x8C55	0x5B76	#CJK UNIFIED IDEOGRAPH
+0x8C56	0x5B77	#CJK UNIFIED IDEOGRAPH
+0x8C57	0x5B78	#CJK UNIFIED IDEOGRAPH
+0x8C58	0x5B79	#CJK UNIFIED IDEOGRAPH
+0x8C59	0x5B7B	#CJK UNIFIED IDEOGRAPH
+0x8C5A	0x5B7C	#CJK UNIFIED IDEOGRAPH
+0x8C5B	0x5B7E	#CJK UNIFIED IDEOGRAPH
+0x8C5C	0x5B7F	#CJK UNIFIED IDEOGRAPH
+0x8C5D	0x5B82	#CJK UNIFIED IDEOGRAPH
+0x8C5E	0x5B86	#CJK UNIFIED IDEOGRAPH
+0x8C5F	0x5B8A	#CJK UNIFIED IDEOGRAPH
+0x8C60	0x5B8D	#CJK UNIFIED IDEOGRAPH
+0x8C61	0x5B8E	#CJK UNIFIED IDEOGRAPH
+0x8C62	0x5B90	#CJK UNIFIED IDEOGRAPH
+0x8C63	0x5B91	#CJK UNIFIED IDEOGRAPH
+0x8C64	0x5B92	#CJK UNIFIED IDEOGRAPH
+0x8C65	0x5B94	#CJK UNIFIED IDEOGRAPH
+0x8C66	0x5B96	#CJK UNIFIED IDEOGRAPH
+0x8C67	0x5B9F	#CJK UNIFIED IDEOGRAPH
+0x8C68	0x5BA7	#CJK UNIFIED IDEOGRAPH
+0x8C69	0x5BA8	#CJK UNIFIED IDEOGRAPH
+0x8C6A	0x5BA9	#CJK UNIFIED IDEOGRAPH
+0x8C6B	0x5BAC	#CJK UNIFIED IDEOGRAPH
+0x8C6C	0x5BAD	#CJK UNIFIED IDEOGRAPH
+0x8C6D	0x5BAE	#CJK UNIFIED IDEOGRAPH
+0x8C6E	0x5BAF	#CJK UNIFIED IDEOGRAPH
+0x8C6F	0x5BB1	#CJK UNIFIED IDEOGRAPH
+0x8C70	0x5BB2	#CJK UNIFIED IDEOGRAPH
+0x8C71	0x5BB7	#CJK UNIFIED IDEOGRAPH
+0x8C72	0x5BBA	#CJK UNIFIED IDEOGRAPH
+0x8C73	0x5BBB	#CJK UNIFIED IDEOGRAPH
+0x8C74	0x5BBC	#CJK UNIFIED IDEOGRAPH
+0x8C75	0x5BC0	#CJK UNIFIED IDEOGRAPH
+0x8C76	0x5BC1	#CJK UNIFIED IDEOGRAPH
+0x8C77	0x5BC3	#CJK UNIFIED IDEOGRAPH
+0x8C78	0x5BC8	#CJK UNIFIED IDEOGRAPH
+0x8C79	0x5BC9	#CJK UNIFIED IDEOGRAPH
+0x8C7A	0x5BCA	#CJK UNIFIED IDEOGRAPH
+0x8C7B	0x5BCB	#CJK UNIFIED IDEOGRAPH
+0x8C7C	0x5BCD	#CJK UNIFIED IDEOGRAPH
+0x8C7D	0x5BCE	#CJK UNIFIED IDEOGRAPH
+0x8C7E	0x5BCF	#CJK UNIFIED IDEOGRAPH
+0x8C80	0x5BD1	#CJK UNIFIED IDEOGRAPH
+0x8C81	0x5BD4	#CJK UNIFIED IDEOGRAPH
+0x8C82	0x5BD5	#CJK UNIFIED IDEOGRAPH
+0x8C83	0x5BD6	#CJK UNIFIED IDEOGRAPH
+0x8C84	0x5BD7	#CJK UNIFIED IDEOGRAPH
+0x8C85	0x5BD8	#CJK UNIFIED IDEOGRAPH
+0x8C86	0x5BD9	#CJK UNIFIED IDEOGRAPH
+0x8C87	0x5BDA	#CJK UNIFIED IDEOGRAPH
+0x8C88	0x5BDB	#CJK UNIFIED IDEOGRAPH
+0x8C89	0x5BDC	#CJK UNIFIED IDEOGRAPH
+0x8C8A	0x5BE0	#CJK UNIFIED IDEOGRAPH
+0x8C8B	0x5BE2	#CJK UNIFIED IDEOGRAPH
+0x8C8C	0x5BE3	#CJK UNIFIED IDEOGRAPH
+0x8C8D	0x5BE6	#CJK UNIFIED IDEOGRAPH
+0x8C8E	0x5BE7	#CJK UNIFIED IDEOGRAPH
+0x8C8F	0x5BE9	#CJK UNIFIED IDEOGRAPH
+0x8C90	0x5BEA	#CJK UNIFIED IDEOGRAPH
+0x8C91	0x5BEB	#CJK UNIFIED IDEOGRAPH
+0x8C92	0x5BEC	#CJK UNIFIED IDEOGRAPH
+0x8C93	0x5BED	#CJK UNIFIED IDEOGRAPH
+0x8C94	0x5BEF	#CJK UNIFIED IDEOGRAPH
+0x8C95	0x5BF1	#CJK UNIFIED IDEOGRAPH
+0x8C96	0x5BF2	#CJK UNIFIED IDEOGRAPH
+0x8C97	0x5BF3	#CJK UNIFIED IDEOGRAPH
+0x8C98	0x5BF4	#CJK UNIFIED IDEOGRAPH
+0x8C99	0x5BF5	#CJK UNIFIED IDEOGRAPH
+0x8C9A	0x5BF6	#CJK UNIFIED IDEOGRAPH
+0x8C9B	0x5BF7	#CJK UNIFIED IDEOGRAPH
+0x8C9C	0x5BFD	#CJK UNIFIED IDEOGRAPH
+0x8C9D	0x5BFE	#CJK UNIFIED IDEOGRAPH
+0x8C9E	0x5C00	#CJK UNIFIED IDEOGRAPH
+0x8C9F	0x5C02	#CJK UNIFIED IDEOGRAPH
+0x8CA0	0x5C03	#CJK UNIFIED IDEOGRAPH
+0x8CA1	0x5C05	#CJK UNIFIED IDEOGRAPH
+0x8CA2	0x5C07	#CJK UNIFIED IDEOGRAPH
+0x8CA3	0x5C08	#CJK UNIFIED IDEOGRAPH
+0x8CA4	0x5C0B	#CJK UNIFIED IDEOGRAPH
+0x8CA5	0x5C0C	#CJK UNIFIED IDEOGRAPH
+0x8CA6	0x5C0D	#CJK UNIFIED IDEOGRAPH
+0x8CA7	0x5C0E	#CJK UNIFIED IDEOGRAPH
+0x8CA8	0x5C10	#CJK UNIFIED IDEOGRAPH
+0x8CA9	0x5C12	#CJK UNIFIED IDEOGRAPH
+0x8CAA	0x5C13	#CJK UNIFIED IDEOGRAPH
+0x8CAB	0x5C17	#CJK UNIFIED IDEOGRAPH
+0x8CAC	0x5C19	#CJK UNIFIED IDEOGRAPH
+0x8CAD	0x5C1B	#CJK UNIFIED IDEOGRAPH
+0x8CAE	0x5C1E	#CJK UNIFIED IDEOGRAPH
+0x8CAF	0x5C1F	#CJK UNIFIED IDEOGRAPH
+0x8CB0	0x5C20	#CJK UNIFIED IDEOGRAPH
+0x8CB1	0x5C21	#CJK UNIFIED IDEOGRAPH
+0x8CB2	0x5C23	#CJK UNIFIED IDEOGRAPH
+0x8CB3	0x5C26	#CJK UNIFIED IDEOGRAPH
+0x8CB4	0x5C28	#CJK UNIFIED IDEOGRAPH
+0x8CB5	0x5C29	#CJK UNIFIED IDEOGRAPH
+0x8CB6	0x5C2A	#CJK UNIFIED IDEOGRAPH
+0x8CB7	0x5C2B	#CJK UNIFIED IDEOGRAPH
+0x8CB8	0x5C2D	#CJK UNIFIED IDEOGRAPH
+0x8CB9	0x5C2E	#CJK UNIFIED IDEOGRAPH
+0x8CBA	0x5C2F	#CJK UNIFIED IDEOGRAPH
+0x8CBB	0x5C30	#CJK UNIFIED IDEOGRAPH
+0x8CBC	0x5C32	#CJK UNIFIED IDEOGRAPH
+0x8CBD	0x5C33	#CJK UNIFIED IDEOGRAPH
+0x8CBE	0x5C35	#CJK UNIFIED IDEOGRAPH
+0x8CBF	0x5C36	#CJK UNIFIED IDEOGRAPH
+0x8CC0	0x5C37	#CJK UNIFIED IDEOGRAPH
+0x8CC1	0x5C43	#CJK UNIFIED IDEOGRAPH
+0x8CC2	0x5C44	#CJK UNIFIED IDEOGRAPH
+0x8CC3	0x5C46	#CJK UNIFIED IDEOGRAPH
+0x8CC4	0x5C47	#CJK UNIFIED IDEOGRAPH
+0x8CC5	0x5C4C	#CJK UNIFIED IDEOGRAPH
+0x8CC6	0x5C4D	#CJK UNIFIED IDEOGRAPH
+0x8CC7	0x5C52	#CJK UNIFIED IDEOGRAPH
+0x8CC8	0x5C53	#CJK UNIFIED IDEOGRAPH
+0x8CC9	0x5C54	#CJK UNIFIED IDEOGRAPH
+0x8CCA	0x5C56	#CJK UNIFIED IDEOGRAPH
+0x8CCB	0x5C57	#CJK UNIFIED IDEOGRAPH
+0x8CCC	0x5C58	#CJK UNIFIED IDEOGRAPH
+0x8CCD	0x5C5A	#CJK UNIFIED IDEOGRAPH
+0x8CCE	0x5C5B	#CJK UNIFIED IDEOGRAPH
+0x8CCF	0x5C5C	#CJK UNIFIED IDEOGRAPH
+0x8CD0	0x5C5D	#CJK UNIFIED IDEOGRAPH
+0x8CD1	0x5C5F	#CJK UNIFIED IDEOGRAPH
+0x8CD2	0x5C62	#CJK UNIFIED IDEOGRAPH
+0x8CD3	0x5C64	#CJK UNIFIED IDEOGRAPH
+0x8CD4	0x5C67	#CJK UNIFIED IDEOGRAPH
+0x8CD5	0x5C68	#CJK UNIFIED IDEOGRAPH
+0x8CD6	0x5C69	#CJK UNIFIED IDEOGRAPH
+0x8CD7	0x5C6A	#CJK UNIFIED IDEOGRAPH
+0x8CD8	0x5C6B	#CJK UNIFIED IDEOGRAPH
+0x8CD9	0x5C6C	#CJK UNIFIED IDEOGRAPH
+0x8CDA	0x5C6D	#CJK UNIFIED IDEOGRAPH
+0x8CDB	0x5C70	#CJK UNIFIED IDEOGRAPH
+0x8CDC	0x5C72	#CJK UNIFIED IDEOGRAPH
+0x8CDD	0x5C73	#CJK UNIFIED IDEOGRAPH
+0x8CDE	0x5C74	#CJK UNIFIED IDEOGRAPH
+0x8CDF	0x5C75	#CJK UNIFIED IDEOGRAPH
+0x8CE0	0x5C76	#CJK UNIFIED IDEOGRAPH
+0x8CE1	0x5C77	#CJK UNIFIED IDEOGRAPH
+0x8CE2	0x5C78	#CJK UNIFIED IDEOGRAPH
+0x8CE3	0x5C7B	#CJK UNIFIED IDEOGRAPH
+0x8CE4	0x5C7C	#CJK UNIFIED IDEOGRAPH
+0x8CE5	0x5C7D	#CJK UNIFIED IDEOGRAPH
+0x8CE6	0x5C7E	#CJK UNIFIED IDEOGRAPH
+0x8CE7	0x5C80	#CJK UNIFIED IDEOGRAPH
+0x8CE8	0x5C83	#CJK UNIFIED IDEOGRAPH
+0x8CE9	0x5C84	#CJK UNIFIED IDEOGRAPH
+0x8CEA	0x5C85	#CJK UNIFIED IDEOGRAPH
+0x8CEB	0x5C86	#CJK UNIFIED IDEOGRAPH
+0x8CEC	0x5C87	#CJK UNIFIED IDEOGRAPH
+0x8CED	0x5C89	#CJK UNIFIED IDEOGRAPH
+0x8CEE	0x5C8A	#CJK UNIFIED IDEOGRAPH
+0x8CEF	0x5C8B	#CJK UNIFIED IDEOGRAPH
+0x8CF0	0x5C8E	#CJK UNIFIED IDEOGRAPH
+0x8CF1	0x5C8F	#CJK UNIFIED IDEOGRAPH
+0x8CF2	0x5C92	#CJK UNIFIED IDEOGRAPH
+0x8CF3	0x5C93	#CJK UNIFIED IDEOGRAPH
+0x8CF4	0x5C95	#CJK UNIFIED IDEOGRAPH
+0x8CF5	0x5C9D	#CJK UNIFIED IDEOGRAPH
+0x8CF6	0x5C9E	#CJK UNIFIED IDEOGRAPH
+0x8CF7	0x5C9F	#CJK UNIFIED IDEOGRAPH
+0x8CF8	0x5CA0	#CJK UNIFIED IDEOGRAPH
+0x8CF9	0x5CA1	#CJK UNIFIED IDEOGRAPH
+0x8CFA	0x5CA4	#CJK UNIFIED IDEOGRAPH
+0x8CFB	0x5CA5	#CJK UNIFIED IDEOGRAPH
+0x8CFC	0x5CA6	#CJK UNIFIED IDEOGRAPH
+0x8CFD	0x5CA7	#CJK UNIFIED IDEOGRAPH
+0x8CFE	0x5CA8	#CJK UNIFIED IDEOGRAPH
+0x8D40	0x5CAA	#CJK UNIFIED IDEOGRAPH
+0x8D41	0x5CAE	#CJK UNIFIED IDEOGRAPH
+0x8D42	0x5CAF	#CJK UNIFIED IDEOGRAPH
+0x8D43	0x5CB0	#CJK UNIFIED IDEOGRAPH
+0x8D44	0x5CB2	#CJK UNIFIED IDEOGRAPH
+0x8D45	0x5CB4	#CJK UNIFIED IDEOGRAPH
+0x8D46	0x5CB6	#CJK UNIFIED IDEOGRAPH
+0x8D47	0x5CB9	#CJK UNIFIED IDEOGRAPH
+0x8D48	0x5CBA	#CJK UNIFIED IDEOGRAPH
+0x8D49	0x5CBB	#CJK UNIFIED IDEOGRAPH
+0x8D4A	0x5CBC	#CJK UNIFIED IDEOGRAPH
+0x8D4B	0x5CBE	#CJK UNIFIED IDEOGRAPH
+0x8D4C	0x5CC0	#CJK UNIFIED IDEOGRAPH
+0x8D4D	0x5CC2	#CJK UNIFIED IDEOGRAPH
+0x8D4E	0x5CC3	#CJK UNIFIED IDEOGRAPH
+0x8D4F	0x5CC5	#CJK UNIFIED IDEOGRAPH
+0x8D50	0x5CC6	#CJK UNIFIED IDEOGRAPH
+0x8D51	0x5CC7	#CJK UNIFIED IDEOGRAPH
+0x8D52	0x5CC8	#CJK UNIFIED IDEOGRAPH
+0x8D53	0x5CC9	#CJK UNIFIED IDEOGRAPH
+0x8D54	0x5CCA	#CJK UNIFIED IDEOGRAPH
+0x8D55	0x5CCC	#CJK UNIFIED IDEOGRAPH
+0x8D56	0x5CCD	#CJK UNIFIED IDEOGRAPH
+0x8D57	0x5CCE	#CJK UNIFIED IDEOGRAPH
+0x8D58	0x5CCF	#CJK UNIFIED IDEOGRAPH
+0x8D59	0x5CD0	#CJK UNIFIED IDEOGRAPH
+0x8D5A	0x5CD1	#CJK UNIFIED IDEOGRAPH
+0x8D5B	0x5CD3	#CJK UNIFIED IDEOGRAPH
+0x8D5C	0x5CD4	#CJK UNIFIED IDEOGRAPH
+0x8D5D	0x5CD5	#CJK UNIFIED IDEOGRAPH
+0x8D5E	0x5CD6	#CJK UNIFIED IDEOGRAPH
+0x8D5F	0x5CD7	#CJK UNIFIED IDEOGRAPH
+0x8D60	0x5CD8	#CJK UNIFIED IDEOGRAPH
+0x8D61	0x5CDA	#CJK UNIFIED IDEOGRAPH
+0x8D62	0x5CDB	#CJK UNIFIED IDEOGRAPH
+0x8D63	0x5CDC	#CJK UNIFIED IDEOGRAPH
+0x8D64	0x5CDD	#CJK UNIFIED IDEOGRAPH
+0x8D65	0x5CDE	#CJK UNIFIED IDEOGRAPH
+0x8D66	0x5CDF	#CJK UNIFIED IDEOGRAPH
+0x8D67	0x5CE0	#CJK UNIFIED IDEOGRAPH
+0x8D68	0x5CE2	#CJK UNIFIED IDEOGRAPH
+0x8D69	0x5CE3	#CJK UNIFIED IDEOGRAPH
+0x8D6A	0x5CE7	#CJK UNIFIED IDEOGRAPH
+0x8D6B	0x5CE9	#CJK UNIFIED IDEOGRAPH
+0x8D6C	0x5CEB	#CJK UNIFIED IDEOGRAPH
+0x8D6D	0x5CEC	#CJK UNIFIED IDEOGRAPH
+0x8D6E	0x5CEE	#CJK UNIFIED IDEOGRAPH
+0x8D6F	0x5CEF	#CJK UNIFIED IDEOGRAPH
+0x8D70	0x5CF1	#CJK UNIFIED IDEOGRAPH
+0x8D71	0x5CF2	#CJK UNIFIED IDEOGRAPH
+0x8D72	0x5CF3	#CJK UNIFIED IDEOGRAPH
+0x8D73	0x5CF4	#CJK UNIFIED IDEOGRAPH
+0x8D74	0x5CF5	#CJK UNIFIED IDEOGRAPH
+0x8D75	0x5CF6	#CJK UNIFIED IDEOGRAPH
+0x8D76	0x5CF7	#CJK UNIFIED IDEOGRAPH
+0x8D77	0x5CF8	#CJK UNIFIED IDEOGRAPH
+0x8D78	0x5CF9	#CJK UNIFIED IDEOGRAPH
+0x8D79	0x5CFA	#CJK UNIFIED IDEOGRAPH
+0x8D7A	0x5CFC	#CJK UNIFIED IDEOGRAPH
+0x8D7B	0x5CFD	#CJK UNIFIED IDEOGRAPH
+0x8D7C	0x5CFE	#CJK UNIFIED IDEOGRAPH
+0x8D7D	0x5CFF	#CJK UNIFIED IDEOGRAPH
+0x8D7E	0x5D00	#CJK UNIFIED IDEOGRAPH
+0x8D80	0x5D01	#CJK UNIFIED IDEOGRAPH
+0x8D81	0x5D04	#CJK UNIFIED IDEOGRAPH
+0x8D82	0x5D05	#CJK UNIFIED IDEOGRAPH
+0x8D83	0x5D08	#CJK UNIFIED IDEOGRAPH
+0x8D84	0x5D09	#CJK UNIFIED IDEOGRAPH
+0x8D85	0x5D0A	#CJK UNIFIED IDEOGRAPH
+0x8D86	0x5D0B	#CJK UNIFIED IDEOGRAPH
+0x8D87	0x5D0C	#CJK UNIFIED IDEOGRAPH
+0x8D88	0x5D0D	#CJK UNIFIED IDEOGRAPH
+0x8D89	0x5D0F	#CJK UNIFIED IDEOGRAPH
+0x8D8A	0x5D10	#CJK UNIFIED IDEOGRAPH
+0x8D8B	0x5D11	#CJK UNIFIED IDEOGRAPH
+0x8D8C	0x5D12	#CJK UNIFIED IDEOGRAPH
+0x8D8D	0x5D13	#CJK UNIFIED IDEOGRAPH
+0x8D8E	0x5D15	#CJK UNIFIED IDEOGRAPH
+0x8D8F	0x5D17	#CJK UNIFIED IDEOGRAPH
+0x8D90	0x5D18	#CJK UNIFIED IDEOGRAPH
+0x8D91	0x5D19	#CJK UNIFIED IDEOGRAPH
+0x8D92	0x5D1A	#CJK UNIFIED IDEOGRAPH
+0x8D93	0x5D1C	#CJK UNIFIED IDEOGRAPH
+0x8D94	0x5D1D	#CJK UNIFIED IDEOGRAPH
+0x8D95	0x5D1F	#CJK UNIFIED IDEOGRAPH
+0x8D96	0x5D20	#CJK UNIFIED IDEOGRAPH
+0x8D97	0x5D21	#CJK UNIFIED IDEOGRAPH
+0x8D98	0x5D22	#CJK UNIFIED IDEOGRAPH
+0x8D99	0x5D23	#CJK UNIFIED IDEOGRAPH
+0x8D9A	0x5D25	#CJK UNIFIED IDEOGRAPH
+0x8D9B	0x5D28	#CJK UNIFIED IDEOGRAPH
+0x8D9C	0x5D2A	#CJK UNIFIED IDEOGRAPH
+0x8D9D	0x5D2B	#CJK UNIFIED IDEOGRAPH
+0x8D9E	0x5D2C	#CJK UNIFIED IDEOGRAPH
+0x8D9F	0x5D2F	#CJK UNIFIED IDEOGRAPH
+0x8DA0	0x5D30	#CJK UNIFIED IDEOGRAPH
+0x8DA1	0x5D31	#CJK UNIFIED IDEOGRAPH
+0x8DA2	0x5D32	#CJK UNIFIED IDEOGRAPH
+0x8DA3	0x5D33	#CJK UNIFIED IDEOGRAPH
+0x8DA4	0x5D35	#CJK UNIFIED IDEOGRAPH
+0x8DA5	0x5D36	#CJK UNIFIED IDEOGRAPH
+0x8DA6	0x5D37	#CJK UNIFIED IDEOGRAPH
+0x8DA7	0x5D38	#CJK UNIFIED IDEOGRAPH
+0x8DA8	0x5D39	#CJK UNIFIED IDEOGRAPH
+0x8DA9	0x5D3A	#CJK UNIFIED IDEOGRAPH
+0x8DAA	0x5D3B	#CJK UNIFIED IDEOGRAPH
+0x8DAB	0x5D3C	#CJK UNIFIED IDEOGRAPH
+0x8DAC	0x5D3F	#CJK UNIFIED IDEOGRAPH
+0x8DAD	0x5D40	#CJK UNIFIED IDEOGRAPH
+0x8DAE	0x5D41	#CJK UNIFIED IDEOGRAPH
+0x8DAF	0x5D42	#CJK UNIFIED IDEOGRAPH
+0x8DB0	0x5D43	#CJK UNIFIED IDEOGRAPH
+0x8DB1	0x5D44	#CJK UNIFIED IDEOGRAPH
+0x8DB2	0x5D45	#CJK UNIFIED IDEOGRAPH
+0x8DB3	0x5D46	#CJK UNIFIED IDEOGRAPH
+0x8DB4	0x5D48	#CJK UNIFIED IDEOGRAPH
+0x8DB5	0x5D49	#CJK UNIFIED IDEOGRAPH
+0x8DB6	0x5D4D	#CJK UNIFIED IDEOGRAPH
+0x8DB7	0x5D4E	#CJK UNIFIED IDEOGRAPH
+0x8DB8	0x5D4F	#CJK UNIFIED IDEOGRAPH
+0x8DB9	0x5D50	#CJK UNIFIED IDEOGRAPH
+0x8DBA	0x5D51	#CJK UNIFIED IDEOGRAPH
+0x8DBB	0x5D52	#CJK UNIFIED IDEOGRAPH
+0x8DBC	0x5D53	#CJK UNIFIED IDEOGRAPH
+0x8DBD	0x5D54	#CJK UNIFIED IDEOGRAPH
+0x8DBE	0x5D55	#CJK UNIFIED IDEOGRAPH
+0x8DBF	0x5D56	#CJK UNIFIED IDEOGRAPH
+0x8DC0	0x5D57	#CJK UNIFIED IDEOGRAPH
+0x8DC1	0x5D59	#CJK UNIFIED IDEOGRAPH
+0x8DC2	0x5D5A	#CJK UNIFIED IDEOGRAPH
+0x8DC3	0x5D5C	#CJK UNIFIED IDEOGRAPH
+0x8DC4	0x5D5E	#CJK UNIFIED IDEOGRAPH
+0x8DC5	0x5D5F	#CJK UNIFIED IDEOGRAPH
+0x8DC6	0x5D60	#CJK UNIFIED IDEOGRAPH
+0x8DC7	0x5D61	#CJK UNIFIED IDEOGRAPH
+0x8DC8	0x5D62	#CJK UNIFIED IDEOGRAPH
+0x8DC9	0x5D63	#CJK UNIFIED IDEOGRAPH
+0x8DCA	0x5D64	#CJK UNIFIED IDEOGRAPH
+0x8DCB	0x5D65	#CJK UNIFIED IDEOGRAPH
+0x8DCC	0x5D66	#CJK UNIFIED IDEOGRAPH
+0x8DCD	0x5D67	#CJK UNIFIED IDEOGRAPH
+0x8DCE	0x5D68	#CJK UNIFIED IDEOGRAPH
+0x8DCF	0x5D6A	#CJK UNIFIED IDEOGRAPH
+0x8DD0	0x5D6D	#CJK UNIFIED IDEOGRAPH
+0x8DD1	0x5D6E	#CJK UNIFIED IDEOGRAPH
+0x8DD2	0x5D70	#CJK UNIFIED IDEOGRAPH
+0x8DD3	0x5D71	#CJK UNIFIED IDEOGRAPH
+0x8DD4	0x5D72	#CJK UNIFIED IDEOGRAPH
+0x8DD5	0x5D73	#CJK UNIFIED IDEOGRAPH
+0x8DD6	0x5D75	#CJK UNIFIED IDEOGRAPH
+0x8DD7	0x5D76	#CJK UNIFIED IDEOGRAPH
+0x8DD8	0x5D77	#CJK UNIFIED IDEOGRAPH
+0x8DD9	0x5D78	#CJK UNIFIED IDEOGRAPH
+0x8DDA	0x5D79	#CJK UNIFIED IDEOGRAPH
+0x8DDB	0x5D7A	#CJK UNIFIED IDEOGRAPH
+0x8DDC	0x5D7B	#CJK UNIFIED IDEOGRAPH
+0x8DDD	0x5D7C	#CJK UNIFIED IDEOGRAPH
+0x8DDE	0x5D7D	#CJK UNIFIED IDEOGRAPH
+0x8DDF	0x5D7E	#CJK UNIFIED IDEOGRAPH
+0x8DE0	0x5D7F	#CJK UNIFIED IDEOGRAPH
+0x8DE1	0x5D80	#CJK UNIFIED IDEOGRAPH
+0x8DE2	0x5D81	#CJK UNIFIED IDEOGRAPH
+0x8DE3	0x5D83	#CJK UNIFIED IDEOGRAPH
+0x8DE4	0x5D84	#CJK UNIFIED IDEOGRAPH
+0x8DE5	0x5D85	#CJK UNIFIED IDEOGRAPH
+0x8DE6	0x5D86	#CJK UNIFIED IDEOGRAPH
+0x8DE7	0x5D87	#CJK UNIFIED IDEOGRAPH
+0x8DE8	0x5D88	#CJK UNIFIED IDEOGRAPH
+0x8DE9	0x5D89	#CJK UNIFIED IDEOGRAPH
+0x8DEA	0x5D8A	#CJK UNIFIED IDEOGRAPH
+0x8DEB	0x5D8B	#CJK UNIFIED IDEOGRAPH
+0x8DEC	0x5D8C	#CJK UNIFIED IDEOGRAPH
+0x8DED	0x5D8D	#CJK UNIFIED IDEOGRAPH
+0x8DEE	0x5D8E	#CJK UNIFIED IDEOGRAPH
+0x8DEF	0x5D8F	#CJK UNIFIED IDEOGRAPH
+0x8DF0	0x5D90	#CJK UNIFIED IDEOGRAPH
+0x8DF1	0x5D91	#CJK UNIFIED IDEOGRAPH
+0x8DF2	0x5D92	#CJK UNIFIED IDEOGRAPH
+0x8DF3	0x5D93	#CJK UNIFIED IDEOGRAPH
+0x8DF4	0x5D94	#CJK UNIFIED IDEOGRAPH
+0x8DF5	0x5D95	#CJK UNIFIED IDEOGRAPH
+0x8DF6	0x5D96	#CJK UNIFIED IDEOGRAPH
+0x8DF7	0x5D97	#CJK UNIFIED IDEOGRAPH
+0x8DF8	0x5D98	#CJK UNIFIED IDEOGRAPH
+0x8DF9	0x5D9A	#CJK UNIFIED IDEOGRAPH
+0x8DFA	0x5D9B	#CJK UNIFIED IDEOGRAPH
+0x8DFB	0x5D9C	#CJK UNIFIED IDEOGRAPH
+0x8DFC	0x5D9E	#CJK UNIFIED IDEOGRAPH
+0x8DFD	0x5D9F	#CJK UNIFIED IDEOGRAPH
+0x8DFE	0x5DA0	#CJK UNIFIED IDEOGRAPH
+0x8E40	0x5DA1	#CJK UNIFIED IDEOGRAPH
+0x8E41	0x5DA2	#CJK UNIFIED IDEOGRAPH
+0x8E42	0x5DA3	#CJK UNIFIED IDEOGRAPH
+0x8E43	0x5DA4	#CJK UNIFIED IDEOGRAPH
+0x8E44	0x5DA5	#CJK UNIFIED IDEOGRAPH
+0x8E45	0x5DA6	#CJK UNIFIED IDEOGRAPH
+0x8E46	0x5DA7	#CJK UNIFIED IDEOGRAPH
+0x8E47	0x5DA8	#CJK UNIFIED IDEOGRAPH
+0x8E48	0x5DA9	#CJK UNIFIED IDEOGRAPH
+0x8E49	0x5DAA	#CJK UNIFIED IDEOGRAPH
+0x8E4A	0x5DAB	#CJK UNIFIED IDEOGRAPH
+0x8E4B	0x5DAC	#CJK UNIFIED IDEOGRAPH
+0x8E4C	0x5DAD	#CJK UNIFIED IDEOGRAPH
+0x8E4D	0x5DAE	#CJK UNIFIED IDEOGRAPH
+0x8E4E	0x5DAF	#CJK UNIFIED IDEOGRAPH
+0x8E4F	0x5DB0	#CJK UNIFIED IDEOGRAPH
+0x8E50	0x5DB1	#CJK UNIFIED IDEOGRAPH
+0x8E51	0x5DB2	#CJK UNIFIED IDEOGRAPH
+0x8E52	0x5DB3	#CJK UNIFIED IDEOGRAPH
+0x8E53	0x5DB4	#CJK UNIFIED IDEOGRAPH
+0x8E54	0x5DB5	#CJK UNIFIED IDEOGRAPH
+0x8E55	0x5DB6	#CJK UNIFIED IDEOGRAPH
+0x8E56	0x5DB8	#CJK UNIFIED IDEOGRAPH
+0x8E57	0x5DB9	#CJK UNIFIED IDEOGRAPH
+0x8E58	0x5DBA	#CJK UNIFIED IDEOGRAPH
+0x8E59	0x5DBB	#CJK UNIFIED IDEOGRAPH
+0x8E5A	0x5DBC	#CJK UNIFIED IDEOGRAPH
+0x8E5B	0x5DBD	#CJK UNIFIED IDEOGRAPH
+0x8E5C	0x5DBE	#CJK UNIFIED IDEOGRAPH
+0x8E5D	0x5DBF	#CJK UNIFIED IDEOGRAPH
+0x8E5E	0x5DC0	#CJK UNIFIED IDEOGRAPH
+0x8E5F	0x5DC1	#CJK UNIFIED IDEOGRAPH
+0x8E60	0x5DC2	#CJK UNIFIED IDEOGRAPH
+0x8E61	0x5DC3	#CJK UNIFIED IDEOGRAPH
+0x8E62	0x5DC4	#CJK UNIFIED IDEOGRAPH
+0x8E63	0x5DC6	#CJK UNIFIED IDEOGRAPH
+0x8E64	0x5DC7	#CJK UNIFIED IDEOGRAPH
+0x8E65	0x5DC8	#CJK UNIFIED IDEOGRAPH
+0x8E66	0x5DC9	#CJK UNIFIED IDEOGRAPH
+0x8E67	0x5DCA	#CJK UNIFIED IDEOGRAPH
+0x8E68	0x5DCB	#CJK UNIFIED IDEOGRAPH
+0x8E69	0x5DCC	#CJK UNIFIED IDEOGRAPH
+0x8E6A	0x5DCE	#CJK UNIFIED IDEOGRAPH
+0x8E6B	0x5DCF	#CJK UNIFIED IDEOGRAPH
+0x8E6C	0x5DD0	#CJK UNIFIED IDEOGRAPH
+0x8E6D	0x5DD1	#CJK UNIFIED IDEOGRAPH
+0x8E6E	0x5DD2	#CJK UNIFIED IDEOGRAPH
+0x8E6F	0x5DD3	#CJK UNIFIED IDEOGRAPH
+0x8E70	0x5DD4	#CJK UNIFIED IDEOGRAPH
+0x8E71	0x5DD5	#CJK UNIFIED IDEOGRAPH
+0x8E72	0x5DD6	#CJK UNIFIED IDEOGRAPH
+0x8E73	0x5DD7	#CJK UNIFIED IDEOGRAPH
+0x8E74	0x5DD8	#CJK UNIFIED IDEOGRAPH
+0x8E75	0x5DD9	#CJK UNIFIED IDEOGRAPH
+0x8E76	0x5DDA	#CJK UNIFIED IDEOGRAPH
+0x8E77	0x5DDC	#CJK UNIFIED IDEOGRAPH
+0x8E78	0x5DDF	#CJK UNIFIED IDEOGRAPH
+0x8E79	0x5DE0	#CJK UNIFIED IDEOGRAPH
+0x8E7A	0x5DE3	#CJK UNIFIED IDEOGRAPH
+0x8E7B	0x5DE4	#CJK UNIFIED IDEOGRAPH
+0x8E7C	0x5DEA	#CJK UNIFIED IDEOGRAPH
+0x8E7D	0x5DEC	#CJK UNIFIED IDEOGRAPH
+0x8E7E	0x5DED	#CJK UNIFIED IDEOGRAPH
+0x8E80	0x5DF0	#CJK UNIFIED IDEOGRAPH
+0x8E81	0x5DF5	#CJK UNIFIED IDEOGRAPH
+0x8E82	0x5DF6	#CJK UNIFIED IDEOGRAPH
+0x8E83	0x5DF8	#CJK UNIFIED IDEOGRAPH
+0x8E84	0x5DF9	#CJK UNIFIED IDEOGRAPH
+0x8E85	0x5DFA	#CJK UNIFIED IDEOGRAPH
+0x8E86	0x5DFB	#CJK UNIFIED IDEOGRAPH
+0x8E87	0x5DFC	#CJK UNIFIED IDEOGRAPH
+0x8E88	0x5DFF	#CJK UNIFIED IDEOGRAPH
+0x8E89	0x5E00	#CJK UNIFIED IDEOGRAPH
+0x8E8A	0x5E04	#CJK UNIFIED IDEOGRAPH
+0x8E8B	0x5E07	#CJK UNIFIED IDEOGRAPH
+0x8E8C	0x5E09	#CJK UNIFIED IDEOGRAPH
+0x8E8D	0x5E0A	#CJK UNIFIED IDEOGRAPH
+0x8E8E	0x5E0B	#CJK UNIFIED IDEOGRAPH
+0x8E8F	0x5E0D	#CJK UNIFIED IDEOGRAPH
+0x8E90	0x5E0E	#CJK UNIFIED IDEOGRAPH
+0x8E91	0x5E12	#CJK UNIFIED IDEOGRAPH
+0x8E92	0x5E13	#CJK UNIFIED IDEOGRAPH
+0x8E93	0x5E17	#CJK UNIFIED IDEOGRAPH
+0x8E94	0x5E1E	#CJK UNIFIED IDEOGRAPH
+0x8E95	0x5E1F	#CJK UNIFIED IDEOGRAPH
+0x8E96	0x5E20	#CJK UNIFIED IDEOGRAPH
+0x8E97	0x5E21	#CJK UNIFIED IDEOGRAPH
+0x8E98	0x5E22	#CJK UNIFIED IDEOGRAPH
+0x8E99	0x5E23	#CJK UNIFIED IDEOGRAPH
+0x8E9A	0x5E24	#CJK UNIFIED IDEOGRAPH
+0x8E9B	0x5E25	#CJK UNIFIED IDEOGRAPH
+0x8E9C	0x5E28	#CJK UNIFIED IDEOGRAPH
+0x8E9D	0x5E29	#CJK UNIFIED IDEOGRAPH
+0x8E9E	0x5E2A	#CJK UNIFIED IDEOGRAPH
+0x8E9F	0x5E2B	#CJK UNIFIED IDEOGRAPH
+0x8EA0	0x5E2C	#CJK UNIFIED IDEOGRAPH
+0x8EA1	0x5E2F	#CJK UNIFIED IDEOGRAPH
+0x8EA2	0x5E30	#CJK UNIFIED IDEOGRAPH
+0x8EA3	0x5E32	#CJK UNIFIED IDEOGRAPH
+0x8EA4	0x5E33	#CJK UNIFIED IDEOGRAPH
+0x8EA5	0x5E34	#CJK UNIFIED IDEOGRAPH
+0x8EA6	0x5E35	#CJK UNIFIED IDEOGRAPH
+0x8EA7	0x5E36	#CJK UNIFIED IDEOGRAPH
+0x8EA8	0x5E39	#CJK UNIFIED IDEOGRAPH
+0x8EA9	0x5E3A	#CJK UNIFIED IDEOGRAPH
+0x8EAA	0x5E3E	#CJK UNIFIED IDEOGRAPH
+0x8EAB	0x5E3F	#CJK UNIFIED IDEOGRAPH
+0x8EAC	0x5E40	#CJK UNIFIED IDEOGRAPH
+0x8EAD	0x5E41	#CJK UNIFIED IDEOGRAPH
+0x8EAE	0x5E43	#CJK UNIFIED IDEOGRAPH
+0x8EAF	0x5E46	#CJK UNIFIED IDEOGRAPH
+0x8EB0	0x5E47	#CJK UNIFIED IDEOGRAPH
+0x8EB1	0x5E48	#CJK UNIFIED IDEOGRAPH
+0x8EB2	0x5E49	#CJK UNIFIED IDEOGRAPH
+0x8EB3	0x5E4A	#CJK UNIFIED IDEOGRAPH
+0x8EB4	0x5E4B	#CJK UNIFIED IDEOGRAPH
+0x8EB5	0x5E4D	#CJK UNIFIED IDEOGRAPH
+0x8EB6	0x5E4E	#CJK UNIFIED IDEOGRAPH
+0x8EB7	0x5E4F	#CJK UNIFIED IDEOGRAPH
+0x8EB8	0x5E50	#CJK UNIFIED IDEOGRAPH
+0x8EB9	0x5E51	#CJK UNIFIED IDEOGRAPH
+0x8EBA	0x5E52	#CJK UNIFIED IDEOGRAPH
+0x8EBB	0x5E53	#CJK UNIFIED IDEOGRAPH
+0x8EBC	0x5E56	#CJK UNIFIED IDEOGRAPH
+0x8EBD	0x5E57	#CJK UNIFIED IDEOGRAPH
+0x8EBE	0x5E58	#CJK UNIFIED IDEOGRAPH
+0x8EBF	0x5E59	#CJK UNIFIED IDEOGRAPH
+0x8EC0	0x5E5A	#CJK UNIFIED IDEOGRAPH
+0x8EC1	0x5E5C	#CJK UNIFIED IDEOGRAPH
+0x8EC2	0x5E5D	#CJK UNIFIED IDEOGRAPH
+0x8EC3	0x5E5F	#CJK UNIFIED IDEOGRAPH
+0x8EC4	0x5E60	#CJK UNIFIED IDEOGRAPH
+0x8EC5	0x5E63	#CJK UNIFIED IDEOGRAPH
+0x8EC6	0x5E64	#CJK UNIFIED IDEOGRAPH
+0x8EC7	0x5E65	#CJK UNIFIED IDEOGRAPH
+0x8EC8	0x5E66	#CJK UNIFIED IDEOGRAPH
+0x8EC9	0x5E67	#CJK UNIFIED IDEOGRAPH
+0x8ECA	0x5E68	#CJK UNIFIED IDEOGRAPH
+0x8ECB	0x5E69	#CJK UNIFIED IDEOGRAPH
+0x8ECC	0x5E6A	#CJK UNIFIED IDEOGRAPH
+0x8ECD	0x5E6B	#CJK UNIFIED IDEOGRAPH
+0x8ECE	0x5E6C	#CJK UNIFIED IDEOGRAPH
+0x8ECF	0x5E6D	#CJK UNIFIED IDEOGRAPH
+0x8ED0	0x5E6E	#CJK UNIFIED IDEOGRAPH
+0x8ED1	0x5E6F	#CJK UNIFIED IDEOGRAPH
+0x8ED2	0x5E70	#CJK UNIFIED IDEOGRAPH
+0x8ED3	0x5E71	#CJK UNIFIED IDEOGRAPH
+0x8ED4	0x5E75	#CJK UNIFIED IDEOGRAPH
+0x8ED5	0x5E77	#CJK UNIFIED IDEOGRAPH
+0x8ED6	0x5E79	#CJK UNIFIED IDEOGRAPH
+0x8ED7	0x5E7E	#CJK UNIFIED IDEOGRAPH
+0x8ED8	0x5E81	#CJK UNIFIED IDEOGRAPH
+0x8ED9	0x5E82	#CJK UNIFIED IDEOGRAPH
+0x8EDA	0x5E83	#CJK UNIFIED IDEOGRAPH
+0x8EDB	0x5E85	#CJK UNIFIED IDEOGRAPH
+0x8EDC	0x5E88	#CJK UNIFIED IDEOGRAPH
+0x8EDD	0x5E89	#CJK UNIFIED IDEOGRAPH
+0x8EDE	0x5E8C	#CJK UNIFIED IDEOGRAPH
+0x8EDF	0x5E8D	#CJK UNIFIED IDEOGRAPH
+0x8EE0	0x5E8E	#CJK UNIFIED IDEOGRAPH
+0x8EE1	0x5E92	#CJK UNIFIED IDEOGRAPH
+0x8EE2	0x5E98	#CJK UNIFIED IDEOGRAPH
+0x8EE3	0x5E9B	#CJK UNIFIED IDEOGRAPH
+0x8EE4	0x5E9D	#CJK UNIFIED IDEOGRAPH
+0x8EE5	0x5EA1	#CJK UNIFIED IDEOGRAPH
+0x8EE6	0x5EA2	#CJK UNIFIED IDEOGRAPH
+0x8EE7	0x5EA3	#CJK UNIFIED IDEOGRAPH
+0x8EE8	0x5EA4	#CJK UNIFIED IDEOGRAPH
+0x8EE9	0x5EA8	#CJK UNIFIED IDEOGRAPH
+0x8EEA	0x5EA9	#CJK UNIFIED IDEOGRAPH
+0x8EEB	0x5EAA	#CJK UNIFIED IDEOGRAPH
+0x8EEC	0x5EAB	#CJK UNIFIED IDEOGRAPH
+0x8EED	0x5EAC	#CJK UNIFIED IDEOGRAPH
+0x8EEE	0x5EAE	#CJK UNIFIED IDEOGRAPH
+0x8EEF	0x5EAF	#CJK UNIFIED IDEOGRAPH
+0x8EF0	0x5EB0	#CJK UNIFIED IDEOGRAPH
+0x8EF1	0x5EB1	#CJK UNIFIED IDEOGRAPH
+0x8EF2	0x5EB2	#CJK UNIFIED IDEOGRAPH
+0x8EF3	0x5EB4	#CJK UNIFIED IDEOGRAPH
+0x8EF4	0x5EBA	#CJK UNIFIED IDEOGRAPH
+0x8EF5	0x5EBB	#CJK UNIFIED IDEOGRAPH
+0x8EF6	0x5EBC	#CJK UNIFIED IDEOGRAPH
+0x8EF7	0x5EBD	#CJK UNIFIED IDEOGRAPH
+0x8EF8	0x5EBF	#CJK UNIFIED IDEOGRAPH
+0x8EF9	0x5EC0	#CJK UNIFIED IDEOGRAPH
+0x8EFA	0x5EC1	#CJK UNIFIED IDEOGRAPH
+0x8EFB	0x5EC2	#CJK UNIFIED IDEOGRAPH
+0x8EFC	0x5EC3	#CJK UNIFIED IDEOGRAPH
+0x8EFD	0x5EC4	#CJK UNIFIED IDEOGRAPH
+0x8EFE	0x5EC5	#CJK UNIFIED IDEOGRAPH
+0x8F40	0x5EC6	#CJK UNIFIED IDEOGRAPH
+0x8F41	0x5EC7	#CJK UNIFIED IDEOGRAPH
+0x8F42	0x5EC8	#CJK UNIFIED IDEOGRAPH
+0x8F43	0x5ECB	#CJK UNIFIED IDEOGRAPH
+0x8F44	0x5ECC	#CJK UNIFIED IDEOGRAPH
+0x8F45	0x5ECD	#CJK UNIFIED IDEOGRAPH
+0x8F46	0x5ECE	#CJK UNIFIED IDEOGRAPH
+0x8F47	0x5ECF	#CJK UNIFIED IDEOGRAPH
+0x8F48	0x5ED0	#CJK UNIFIED IDEOGRAPH
+0x8F49	0x5ED4	#CJK UNIFIED IDEOGRAPH
+0x8F4A	0x5ED5	#CJK UNIFIED IDEOGRAPH
+0x8F4B	0x5ED7	#CJK UNIFIED IDEOGRAPH
+0x8F4C	0x5ED8	#CJK UNIFIED IDEOGRAPH
+0x8F4D	0x5ED9	#CJK UNIFIED IDEOGRAPH
+0x8F4E	0x5EDA	#CJK UNIFIED IDEOGRAPH
+0x8F4F	0x5EDC	#CJK UNIFIED IDEOGRAPH
+0x8F50	0x5EDD	#CJK UNIFIED IDEOGRAPH
+0x8F51	0x5EDE	#CJK UNIFIED IDEOGRAPH
+0x8F52	0x5EDF	#CJK UNIFIED IDEOGRAPH
+0x8F53	0x5EE0	#CJK UNIFIED IDEOGRAPH
+0x8F54	0x5EE1	#CJK UNIFIED IDEOGRAPH
+0x8F55	0x5EE2	#CJK UNIFIED IDEOGRAPH
+0x8F56	0x5EE3	#CJK UNIFIED IDEOGRAPH
+0x8F57	0x5EE4	#CJK UNIFIED IDEOGRAPH
+0x8F58	0x5EE5	#CJK UNIFIED IDEOGRAPH
+0x8F59	0x5EE6	#CJK UNIFIED IDEOGRAPH
+0x8F5A	0x5EE7	#CJK UNIFIED IDEOGRAPH
+0x8F5B	0x5EE9	#CJK UNIFIED IDEOGRAPH
+0x8F5C	0x5EEB	#CJK UNIFIED IDEOGRAPH
+0x8F5D	0x5EEC	#CJK UNIFIED IDEOGRAPH
+0x8F5E	0x5EED	#CJK UNIFIED IDEOGRAPH
+0x8F5F	0x5EEE	#CJK UNIFIED IDEOGRAPH
+0x8F60	0x5EEF	#CJK UNIFIED IDEOGRAPH
+0x8F61	0x5EF0	#CJK UNIFIED IDEOGRAPH
+0x8F62	0x5EF1	#CJK UNIFIED IDEOGRAPH
+0x8F63	0x5EF2	#CJK UNIFIED IDEOGRAPH
+0x8F64	0x5EF3	#CJK UNIFIED IDEOGRAPH
+0x8F65	0x5EF5	#CJK UNIFIED IDEOGRAPH
+0x8F66	0x5EF8	#CJK UNIFIED IDEOGRAPH
+0x8F67	0x5EF9	#CJK UNIFIED IDEOGRAPH
+0x8F68	0x5EFB	#CJK UNIFIED IDEOGRAPH
+0x8F69	0x5EFC	#CJK UNIFIED IDEOGRAPH
+0x8F6A	0x5EFD	#CJK UNIFIED IDEOGRAPH
+0x8F6B	0x5F05	#CJK UNIFIED IDEOGRAPH
+0x8F6C	0x5F06	#CJK UNIFIED IDEOGRAPH
+0x8F6D	0x5F07	#CJK UNIFIED IDEOGRAPH
+0x8F6E	0x5F09	#CJK UNIFIED IDEOGRAPH
+0x8F6F	0x5F0C	#CJK UNIFIED IDEOGRAPH
+0x8F70	0x5F0D	#CJK UNIFIED IDEOGRAPH
+0x8F71	0x5F0E	#CJK UNIFIED IDEOGRAPH
+0x8F72	0x5F10	#CJK UNIFIED IDEOGRAPH
+0x8F73	0x5F12	#CJK UNIFIED IDEOGRAPH
+0x8F74	0x5F14	#CJK UNIFIED IDEOGRAPH
+0x8F75	0x5F16	#CJK UNIFIED IDEOGRAPH
+0x8F76	0x5F19	#CJK UNIFIED IDEOGRAPH
+0x8F77	0x5F1A	#CJK UNIFIED IDEOGRAPH
+0x8F78	0x5F1C	#CJK UNIFIED IDEOGRAPH
+0x8F79	0x5F1D	#CJK UNIFIED IDEOGRAPH
+0x8F7A	0x5F1E	#CJK UNIFIED IDEOGRAPH
+0x8F7B	0x5F21	#CJK UNIFIED IDEOGRAPH
+0x8F7C	0x5F22	#CJK UNIFIED IDEOGRAPH
+0x8F7D	0x5F23	#CJK UNIFIED IDEOGRAPH
+0x8F7E	0x5F24	#CJK UNIFIED IDEOGRAPH
+0x8F80	0x5F28	#CJK UNIFIED IDEOGRAPH
+0x8F81	0x5F2B	#CJK UNIFIED IDEOGRAPH
+0x8F82	0x5F2C	#CJK UNIFIED IDEOGRAPH
+0x8F83	0x5F2E	#CJK UNIFIED IDEOGRAPH
+0x8F84	0x5F30	#CJK UNIFIED IDEOGRAPH
+0x8F85	0x5F32	#CJK UNIFIED IDEOGRAPH
+0x8F86	0x5F33	#CJK UNIFIED IDEOGRAPH
+0x8F87	0x5F34	#CJK UNIFIED IDEOGRAPH
+0x8F88	0x5F35	#CJK UNIFIED IDEOGRAPH
+0x8F89	0x5F36	#CJK UNIFIED IDEOGRAPH
+0x8F8A	0x5F37	#CJK UNIFIED IDEOGRAPH
+0x8F8B	0x5F38	#CJK UNIFIED IDEOGRAPH
+0x8F8C	0x5F3B	#CJK UNIFIED IDEOGRAPH
+0x8F8D	0x5F3D	#CJK UNIFIED IDEOGRAPH
+0x8F8E	0x5F3E	#CJK UNIFIED IDEOGRAPH
+0x8F8F	0x5F3F	#CJK UNIFIED IDEOGRAPH
+0x8F90	0x5F41	#CJK UNIFIED IDEOGRAPH
+0x8F91	0x5F42	#CJK UNIFIED IDEOGRAPH
+0x8F92	0x5F43	#CJK UNIFIED IDEOGRAPH
+0x8F93	0x5F44	#CJK UNIFIED IDEOGRAPH
+0x8F94	0x5F45	#CJK UNIFIED IDEOGRAPH
+0x8F95	0x5F46	#CJK UNIFIED IDEOGRAPH
+0x8F96	0x5F47	#CJK UNIFIED IDEOGRAPH
+0x8F97	0x5F48	#CJK UNIFIED IDEOGRAPH
+0x8F98	0x5F49	#CJK UNIFIED IDEOGRAPH
+0x8F99	0x5F4A	#CJK UNIFIED IDEOGRAPH
+0x8F9A	0x5F4B	#CJK UNIFIED IDEOGRAPH
+0x8F9B	0x5F4C	#CJK UNIFIED IDEOGRAPH
+0x8F9C	0x5F4D	#CJK UNIFIED IDEOGRAPH
+0x8F9D	0x5F4E	#CJK UNIFIED IDEOGRAPH
+0x8F9E	0x5F4F	#CJK UNIFIED IDEOGRAPH
+0x8F9F	0x5F51	#CJK UNIFIED IDEOGRAPH
+0x8FA0	0x5F54	#CJK UNIFIED IDEOGRAPH
+0x8FA1	0x5F59	#CJK UNIFIED IDEOGRAPH
+0x8FA2	0x5F5A	#CJK UNIFIED IDEOGRAPH
+0x8FA3	0x5F5B	#CJK UNIFIED IDEOGRAPH
+0x8FA4	0x5F5C	#CJK UNIFIED IDEOGRAPH
+0x8FA5	0x5F5E	#CJK UNIFIED IDEOGRAPH
+0x8FA6	0x5F5F	#CJK UNIFIED IDEOGRAPH
+0x8FA7	0x5F60	#CJK UNIFIED IDEOGRAPH
+0x8FA8	0x5F63	#CJK UNIFIED IDEOGRAPH
+0x8FA9	0x5F65	#CJK UNIFIED IDEOGRAPH
+0x8FAA	0x5F67	#CJK UNIFIED IDEOGRAPH
+0x8FAB	0x5F68	#CJK UNIFIED IDEOGRAPH
+0x8FAC	0x5F6B	#CJK UNIFIED IDEOGRAPH
+0x8FAD	0x5F6E	#CJK UNIFIED IDEOGRAPH
+0x8FAE	0x5F6F	#CJK UNIFIED IDEOGRAPH
+0x8FAF	0x5F72	#CJK UNIFIED IDEOGRAPH
+0x8FB0	0x5F74	#CJK UNIFIED IDEOGRAPH
+0x8FB1	0x5F75	#CJK UNIFIED IDEOGRAPH
+0x8FB2	0x5F76	#CJK UNIFIED IDEOGRAPH
+0x8FB3	0x5F78	#CJK UNIFIED IDEOGRAPH
+0x8FB4	0x5F7A	#CJK UNIFIED IDEOGRAPH
+0x8FB5	0x5F7D	#CJK UNIFIED IDEOGRAPH
+0x8FB6	0x5F7E	#CJK UNIFIED IDEOGRAPH
+0x8FB7	0x5F7F	#CJK UNIFIED IDEOGRAPH
+0x8FB8	0x5F83	#CJK UNIFIED IDEOGRAPH
+0x8FB9	0x5F86	#CJK UNIFIED IDEOGRAPH
+0x8FBA	0x5F8D	#CJK UNIFIED IDEOGRAPH
+0x8FBB	0x5F8E	#CJK UNIFIED IDEOGRAPH
+0x8FBC	0x5F8F	#CJK UNIFIED IDEOGRAPH
+0x8FBD	0x5F91	#CJK UNIFIED IDEOGRAPH
+0x8FBE	0x5F93	#CJK UNIFIED IDEOGRAPH
+0x8FBF	0x5F94	#CJK UNIFIED IDEOGRAPH
+0x8FC0	0x5F96	#CJK UNIFIED IDEOGRAPH
+0x8FC1	0x5F9A	#CJK UNIFIED IDEOGRAPH
+0x8FC2	0x5F9B	#CJK UNIFIED IDEOGRAPH
+0x8FC3	0x5F9D	#CJK UNIFIED IDEOGRAPH
+0x8FC4	0x5F9E	#CJK UNIFIED IDEOGRAPH
+0x8FC5	0x5F9F	#CJK UNIFIED IDEOGRAPH
+0x8FC6	0x5FA0	#CJK UNIFIED IDEOGRAPH
+0x8FC7	0x5FA2	#CJK UNIFIED IDEOGRAPH
+0x8FC8	0x5FA3	#CJK UNIFIED IDEOGRAPH
+0x8FC9	0x5FA4	#CJK UNIFIED IDEOGRAPH
+0x8FCA	0x5FA5	#CJK UNIFIED IDEOGRAPH
+0x8FCB	0x5FA6	#CJK UNIFIED IDEOGRAPH
+0x8FCC	0x5FA7	#CJK UNIFIED IDEOGRAPH
+0x8FCD	0x5FA9	#CJK UNIFIED IDEOGRAPH
+0x8FCE	0x5FAB	#CJK UNIFIED IDEOGRAPH
+0x8FCF	0x5FAC	#CJK UNIFIED IDEOGRAPH
+0x8FD0	0x5FAF	#CJK UNIFIED IDEOGRAPH
+0x8FD1	0x5FB0	#CJK UNIFIED IDEOGRAPH
+0x8FD2	0x5FB1	#CJK UNIFIED IDEOGRAPH
+0x8FD3	0x5FB2	#CJK UNIFIED IDEOGRAPH
+0x8FD4	0x5FB3	#CJK UNIFIED IDEOGRAPH
+0x8FD5	0x5FB4	#CJK UNIFIED IDEOGRAPH
+0x8FD6	0x5FB6	#CJK UNIFIED IDEOGRAPH
+0x8FD7	0x5FB8	#CJK UNIFIED IDEOGRAPH
+0x8FD8	0x5FB9	#CJK UNIFIED IDEOGRAPH
+0x8FD9	0x5FBA	#CJK UNIFIED IDEOGRAPH
+0x8FDA	0x5FBB	#CJK UNIFIED IDEOGRAPH
+0x8FDB	0x5FBE	#CJK UNIFIED IDEOGRAPH
+0x8FDC	0x5FBF	#CJK UNIFIED IDEOGRAPH
+0x8FDD	0x5FC0	#CJK UNIFIED IDEOGRAPH
+0x8FDE	0x5FC1	#CJK UNIFIED IDEOGRAPH
+0x8FDF	0x5FC2	#CJK UNIFIED IDEOGRAPH
+0x8FE0	0x5FC7	#CJK UNIFIED IDEOGRAPH
+0x8FE1	0x5FC8	#CJK UNIFIED IDEOGRAPH
+0x8FE2	0x5FCA	#CJK UNIFIED IDEOGRAPH
+0x8FE3	0x5FCB	#CJK UNIFIED IDEOGRAPH
+0x8FE4	0x5FCE	#CJK UNIFIED IDEOGRAPH
+0x8FE5	0x5FD3	#CJK UNIFIED IDEOGRAPH
+0x8FE6	0x5FD4	#CJK UNIFIED IDEOGRAPH
+0x8FE7	0x5FD5	#CJK UNIFIED IDEOGRAPH
+0x8FE8	0x5FDA	#CJK UNIFIED IDEOGRAPH
+0x8FE9	0x5FDB	#CJK UNIFIED IDEOGRAPH
+0x8FEA	0x5FDC	#CJK UNIFIED IDEOGRAPH
+0x8FEB	0x5FDE	#CJK UNIFIED IDEOGRAPH
+0x8FEC	0x5FDF	#CJK UNIFIED IDEOGRAPH
+0x8FED	0x5FE2	#CJK UNIFIED IDEOGRAPH
+0x8FEE	0x5FE3	#CJK UNIFIED IDEOGRAPH
+0x8FEF	0x5FE5	#CJK UNIFIED IDEOGRAPH
+0x8FF0	0x5FE6	#CJK UNIFIED IDEOGRAPH
+0x8FF1	0x5FE8	#CJK UNIFIED IDEOGRAPH
+0x8FF2	0x5FE9	#CJK UNIFIED IDEOGRAPH
+0x8FF3	0x5FEC	#CJK UNIFIED IDEOGRAPH
+0x8FF4	0x5FEF	#CJK UNIFIED IDEOGRAPH
+0x8FF5	0x5FF0	#CJK UNIFIED IDEOGRAPH
+0x8FF6	0x5FF2	#CJK UNIFIED IDEOGRAPH
+0x8FF7	0x5FF3	#CJK UNIFIED IDEOGRAPH
+0x8FF8	0x5FF4	#CJK UNIFIED IDEOGRAPH
+0x8FF9	0x5FF6	#CJK UNIFIED IDEOGRAPH
+0x8FFA	0x5FF7	#CJK UNIFIED IDEOGRAPH
+0x8FFB	0x5FF9	#CJK UNIFIED IDEOGRAPH
+0x8FFC	0x5FFA	#CJK UNIFIED IDEOGRAPH
+0x8FFD	0x5FFC	#CJK UNIFIED IDEOGRAPH
+0x8FFE	0x6007	#CJK UNIFIED IDEOGRAPH
+0x9040	0x6008	#CJK UNIFIED IDEOGRAPH
+0x9041	0x6009	#CJK UNIFIED IDEOGRAPH
+0x9042	0x600B	#CJK UNIFIED IDEOGRAPH
+0x9043	0x600C	#CJK UNIFIED IDEOGRAPH
+0x9044	0x6010	#CJK UNIFIED IDEOGRAPH
+0x9045	0x6011	#CJK UNIFIED IDEOGRAPH
+0x9046	0x6013	#CJK UNIFIED IDEOGRAPH
+0x9047	0x6017	#CJK UNIFIED IDEOGRAPH
+0x9048	0x6018	#CJK UNIFIED IDEOGRAPH
+0x9049	0x601A	#CJK UNIFIED IDEOGRAPH
+0x904A	0x601E	#CJK UNIFIED IDEOGRAPH
+0x904B	0x601F	#CJK UNIFIED IDEOGRAPH
+0x904C	0x6022	#CJK UNIFIED IDEOGRAPH
+0x904D	0x6023	#CJK UNIFIED IDEOGRAPH
+0x904E	0x6024	#CJK UNIFIED IDEOGRAPH
+0x904F	0x602C	#CJK UNIFIED IDEOGRAPH
+0x9050	0x602D	#CJK UNIFIED IDEOGRAPH
+0x9051	0x602E	#CJK UNIFIED IDEOGRAPH
+0x9052	0x6030	#CJK UNIFIED IDEOGRAPH
+0x9053	0x6031	#CJK UNIFIED IDEOGRAPH
+0x9054	0x6032	#CJK UNIFIED IDEOGRAPH
+0x9055	0x6033	#CJK UNIFIED IDEOGRAPH
+0x9056	0x6034	#CJK UNIFIED IDEOGRAPH
+0x9057	0x6036	#CJK UNIFIED IDEOGRAPH
+0x9058	0x6037	#CJK UNIFIED IDEOGRAPH
+0x9059	0x6038	#CJK UNIFIED IDEOGRAPH
+0x905A	0x6039	#CJK UNIFIED IDEOGRAPH
+0x905B	0x603A	#CJK UNIFIED IDEOGRAPH
+0x905C	0x603D	#CJK UNIFIED IDEOGRAPH
+0x905D	0x603E	#CJK UNIFIED IDEOGRAPH
+0x905E	0x6040	#CJK UNIFIED IDEOGRAPH
+0x905F	0x6044	#CJK UNIFIED IDEOGRAPH
+0x9060	0x6045	#CJK UNIFIED IDEOGRAPH
+0x9061	0x6046	#CJK UNIFIED IDEOGRAPH
+0x9062	0x6047	#CJK UNIFIED IDEOGRAPH
+0x9063	0x6048	#CJK UNIFIED IDEOGRAPH
+0x9064	0x6049	#CJK UNIFIED IDEOGRAPH
+0x9065	0x604A	#CJK UNIFIED IDEOGRAPH
+0x9066	0x604C	#CJK UNIFIED IDEOGRAPH
+0x9067	0x604E	#CJK UNIFIED IDEOGRAPH
+0x9068	0x604F	#CJK UNIFIED IDEOGRAPH
+0x9069	0x6051	#CJK UNIFIED IDEOGRAPH
+0x906A	0x6053	#CJK UNIFIED IDEOGRAPH
+0x906B	0x6054	#CJK UNIFIED IDEOGRAPH
+0x906C	0x6056	#CJK UNIFIED IDEOGRAPH
+0x906D	0x6057	#CJK UNIFIED IDEOGRAPH
+0x906E	0x6058	#CJK UNIFIED IDEOGRAPH
+0x906F	0x605B	#CJK UNIFIED IDEOGRAPH
+0x9070	0x605C	#CJK UNIFIED IDEOGRAPH
+0x9071	0x605E	#CJK UNIFIED IDEOGRAPH
+0x9072	0x605F	#CJK UNIFIED IDEOGRAPH
+0x9073	0x6060	#CJK UNIFIED IDEOGRAPH
+0x9074	0x6061	#CJK UNIFIED IDEOGRAPH
+0x9075	0x6065	#CJK UNIFIED IDEOGRAPH
+0x9076	0x6066	#CJK UNIFIED IDEOGRAPH
+0x9077	0x606E	#CJK UNIFIED IDEOGRAPH
+0x9078	0x6071	#CJK UNIFIED IDEOGRAPH
+0x9079	0x6072	#CJK UNIFIED IDEOGRAPH
+0x907A	0x6074	#CJK UNIFIED IDEOGRAPH
+0x907B	0x6075	#CJK UNIFIED IDEOGRAPH
+0x907C	0x6077	#CJK UNIFIED IDEOGRAPH
+0x907D	0x607E	#CJK UNIFIED IDEOGRAPH
+0x907E	0x6080	#CJK UNIFIED IDEOGRAPH
+0x9080	0x6081	#CJK UNIFIED IDEOGRAPH
+0x9081	0x6082	#CJK UNIFIED IDEOGRAPH
+0x9082	0x6085	#CJK UNIFIED IDEOGRAPH
+0x9083	0x6086	#CJK UNIFIED IDEOGRAPH
+0x9084	0x6087	#CJK UNIFIED IDEOGRAPH
+0x9085	0x6088	#CJK UNIFIED IDEOGRAPH
+0x9086	0x608A	#CJK UNIFIED IDEOGRAPH
+0x9087	0x608B	#CJK UNIFIED IDEOGRAPH
+0x9088	0x608E	#CJK UNIFIED IDEOGRAPH
+0x9089	0x608F	#CJK UNIFIED IDEOGRAPH
+0x908A	0x6090	#CJK UNIFIED IDEOGRAPH
+0x908B	0x6091	#CJK UNIFIED IDEOGRAPH
+0x908C	0x6093	#CJK UNIFIED IDEOGRAPH
+0x908D	0x6095	#CJK UNIFIED IDEOGRAPH
+0x908E	0x6097	#CJK UNIFIED IDEOGRAPH
+0x908F	0x6098	#CJK UNIFIED IDEOGRAPH
+0x9090	0x6099	#CJK UNIFIED IDEOGRAPH
+0x9091	0x609C	#CJK UNIFIED IDEOGRAPH
+0x9092	0x609E	#CJK UNIFIED IDEOGRAPH
+0x9093	0x60A1	#CJK UNIFIED IDEOGRAPH
+0x9094	0x60A2	#CJK UNIFIED IDEOGRAPH
+0x9095	0x60A4	#CJK UNIFIED IDEOGRAPH
+0x9096	0x60A5	#CJK UNIFIED IDEOGRAPH
+0x9097	0x60A7	#CJK UNIFIED IDEOGRAPH
+0x9098	0x60A9	#CJK UNIFIED IDEOGRAPH
+0x9099	0x60AA	#CJK UNIFIED IDEOGRAPH
+0x909A	0x60AE	#CJK UNIFIED IDEOGRAPH
+0x909B	0x60B0	#CJK UNIFIED IDEOGRAPH
+0x909C	0x60B3	#CJK UNIFIED IDEOGRAPH
+0x909D	0x60B5	#CJK UNIFIED IDEOGRAPH
+0x909E	0x60B6	#CJK UNIFIED IDEOGRAPH
+0x909F	0x60B7	#CJK UNIFIED IDEOGRAPH
+0x90A0	0x60B9	#CJK UNIFIED IDEOGRAPH
+0x90A1	0x60BA	#CJK UNIFIED IDEOGRAPH
+0x90A2	0x60BD	#CJK UNIFIED IDEOGRAPH
+0x90A3	0x60BE	#CJK UNIFIED IDEOGRAPH
+0x90A4	0x60BF	#CJK UNIFIED IDEOGRAPH
+0x90A5	0x60C0	#CJK UNIFIED IDEOGRAPH
+0x90A6	0x60C1	#CJK UNIFIED IDEOGRAPH
+0x90A7	0x60C2	#CJK UNIFIED IDEOGRAPH
+0x90A8	0x60C3	#CJK UNIFIED IDEOGRAPH
+0x90A9	0x60C4	#CJK UNIFIED IDEOGRAPH
+0x90AA	0x60C7	#CJK UNIFIED IDEOGRAPH
+0x90AB	0x60C8	#CJK UNIFIED IDEOGRAPH
+0x90AC	0x60C9	#CJK UNIFIED IDEOGRAPH
+0x90AD	0x60CC	#CJK UNIFIED IDEOGRAPH
+0x90AE	0x60CD	#CJK UNIFIED IDEOGRAPH
+0x90AF	0x60CE	#CJK UNIFIED IDEOGRAPH
+0x90B0	0x60CF	#CJK UNIFIED IDEOGRAPH
+0x90B1	0x60D0	#CJK UNIFIED IDEOGRAPH
+0x90B2	0x60D2	#CJK UNIFIED IDEOGRAPH
+0x90B3	0x60D3	#CJK UNIFIED IDEOGRAPH
+0x90B4	0x60D4	#CJK UNIFIED IDEOGRAPH
+0x90B5	0x60D6	#CJK UNIFIED IDEOGRAPH
+0x90B6	0x60D7	#CJK UNIFIED IDEOGRAPH
+0x90B7	0x60D9	#CJK UNIFIED IDEOGRAPH
+0x90B8	0x60DB	#CJK UNIFIED IDEOGRAPH
+0x90B9	0x60DE	#CJK UNIFIED IDEOGRAPH
+0x90BA	0x60E1	#CJK UNIFIED IDEOGRAPH
+0x90BB	0x60E2	#CJK UNIFIED IDEOGRAPH
+0x90BC	0x60E3	#CJK UNIFIED IDEOGRAPH
+0x90BD	0x60E4	#CJK UNIFIED IDEOGRAPH
+0x90BE	0x60E5	#CJK UNIFIED IDEOGRAPH
+0x90BF	0x60EA	#CJK UNIFIED IDEOGRAPH
+0x90C0	0x60F1	#CJK UNIFIED IDEOGRAPH
+0x90C1	0x60F2	#CJK UNIFIED IDEOGRAPH
+0x90C2	0x60F5	#CJK UNIFIED IDEOGRAPH
+0x90C3	0x60F7	#CJK UNIFIED IDEOGRAPH
+0x90C4	0x60F8	#CJK UNIFIED IDEOGRAPH
+0x90C5	0x60FB	#CJK UNIFIED IDEOGRAPH
+0x90C6	0x60FC	#CJK UNIFIED IDEOGRAPH
+0x90C7	0x60FD	#CJK UNIFIED IDEOGRAPH
+0x90C8	0x60FE	#CJK UNIFIED IDEOGRAPH
+0x90C9	0x60FF	#CJK UNIFIED IDEOGRAPH
+0x90CA	0x6102	#CJK UNIFIED IDEOGRAPH
+0x90CB	0x6103	#CJK UNIFIED IDEOGRAPH
+0x90CC	0x6104	#CJK UNIFIED IDEOGRAPH
+0x90CD	0x6105	#CJK UNIFIED IDEOGRAPH
+0x90CE	0x6107	#CJK UNIFIED IDEOGRAPH
+0x90CF	0x610A	#CJK UNIFIED IDEOGRAPH
+0x90D0	0x610B	#CJK UNIFIED IDEOGRAPH
+0x90D1	0x610C	#CJK UNIFIED IDEOGRAPH
+0x90D2	0x6110	#CJK UNIFIED IDEOGRAPH
+0x90D3	0x6111	#CJK UNIFIED IDEOGRAPH
+0x90D4	0x6112	#CJK UNIFIED IDEOGRAPH
+0x90D5	0x6113	#CJK UNIFIED IDEOGRAPH
+0x90D6	0x6114	#CJK UNIFIED IDEOGRAPH
+0x90D7	0x6116	#CJK UNIFIED IDEOGRAPH
+0x90D8	0x6117	#CJK UNIFIED IDEOGRAPH
+0x90D9	0x6118	#CJK UNIFIED IDEOGRAPH
+0x90DA	0x6119	#CJK UNIFIED IDEOGRAPH
+0x90DB	0x611B	#CJK UNIFIED IDEOGRAPH
+0x90DC	0x611C	#CJK UNIFIED IDEOGRAPH
+0x90DD	0x611D	#CJK UNIFIED IDEOGRAPH
+0x90DE	0x611E	#CJK UNIFIED IDEOGRAPH
+0x90DF	0x6121	#CJK UNIFIED IDEOGRAPH
+0x90E0	0x6122	#CJK UNIFIED IDEOGRAPH
+0x90E1	0x6125	#CJK UNIFIED IDEOGRAPH
+0x90E2	0x6128	#CJK UNIFIED IDEOGRAPH
+0x90E3	0x6129	#CJK UNIFIED IDEOGRAPH
+0x90E4	0x612A	#CJK UNIFIED IDEOGRAPH
+0x90E5	0x612C	#CJK UNIFIED IDEOGRAPH
+0x90E6	0x612D	#CJK UNIFIED IDEOGRAPH
+0x90E7	0x612E	#CJK UNIFIED IDEOGRAPH
+0x90E8	0x612F	#CJK UNIFIED IDEOGRAPH
+0x90E9	0x6130	#CJK UNIFIED IDEOGRAPH
+0x90EA	0x6131	#CJK UNIFIED IDEOGRAPH
+0x90EB	0x6132	#CJK UNIFIED IDEOGRAPH
+0x90EC	0x6133	#CJK UNIFIED IDEOGRAPH
+0x90ED	0x6134	#CJK UNIFIED IDEOGRAPH
+0x90EE	0x6135	#CJK UNIFIED IDEOGRAPH
+0x90EF	0x6136	#CJK UNIFIED IDEOGRAPH
+0x90F0	0x6137	#CJK UNIFIED IDEOGRAPH
+0x90F1	0x6138	#CJK UNIFIED IDEOGRAPH
+0x90F2	0x6139	#CJK UNIFIED IDEOGRAPH
+0x90F3	0x613A	#CJK UNIFIED IDEOGRAPH
+0x90F4	0x613B	#CJK UNIFIED IDEOGRAPH
+0x90F5	0x613C	#CJK UNIFIED IDEOGRAPH
+0x90F6	0x613D	#CJK UNIFIED IDEOGRAPH
+0x90F7	0x613E	#CJK UNIFIED IDEOGRAPH
+0x90F8	0x6140	#CJK UNIFIED IDEOGRAPH
+0x90F9	0x6141	#CJK UNIFIED IDEOGRAPH
+0x90FA	0x6142	#CJK UNIFIED IDEOGRAPH
+0x90FB	0x6143	#CJK UNIFIED IDEOGRAPH
+0x90FC	0x6144	#CJK UNIFIED IDEOGRAPH
+0x90FD	0x6145	#CJK UNIFIED IDEOGRAPH
+0x90FE	0x6146	#CJK UNIFIED IDEOGRAPH
+0x9140	0x6147	#CJK UNIFIED IDEOGRAPH
+0x9141	0x6149	#CJK UNIFIED IDEOGRAPH
+0x9142	0x614B	#CJK UNIFIED IDEOGRAPH
+0x9143	0x614D	#CJK UNIFIED IDEOGRAPH
+0x9144	0x614F	#CJK UNIFIED IDEOGRAPH
+0x9145	0x6150	#CJK UNIFIED IDEOGRAPH
+0x9146	0x6152	#CJK UNIFIED IDEOGRAPH
+0x9147	0x6153	#CJK UNIFIED IDEOGRAPH
+0x9148	0x6154	#CJK UNIFIED IDEOGRAPH
+0x9149	0x6156	#CJK UNIFIED IDEOGRAPH
+0x914A	0x6157	#CJK UNIFIED IDEOGRAPH
+0x914B	0x6158	#CJK UNIFIED IDEOGRAPH
+0x914C	0x6159	#CJK UNIFIED IDEOGRAPH
+0x914D	0x615A	#CJK UNIFIED IDEOGRAPH
+0x914E	0x615B	#CJK UNIFIED IDEOGRAPH
+0x914F	0x615C	#CJK UNIFIED IDEOGRAPH
+0x9150	0x615E	#CJK UNIFIED IDEOGRAPH
+0x9151	0x615F	#CJK UNIFIED IDEOGRAPH
+0x9152	0x6160	#CJK UNIFIED IDEOGRAPH
+0x9153	0x6161	#CJK UNIFIED IDEOGRAPH
+0x9154	0x6163	#CJK UNIFIED IDEOGRAPH
+0x9155	0x6164	#CJK UNIFIED IDEOGRAPH
+0x9156	0x6165	#CJK UNIFIED IDEOGRAPH
+0x9157	0x6166	#CJK UNIFIED IDEOGRAPH
+0x9158	0x6169	#CJK UNIFIED IDEOGRAPH
+0x9159	0x616A	#CJK UNIFIED IDEOGRAPH
+0x915A	0x616B	#CJK UNIFIED IDEOGRAPH
+0x915B	0x616C	#CJK UNIFIED IDEOGRAPH
+0x915C	0x616D	#CJK UNIFIED IDEOGRAPH
+0x915D	0x616E	#CJK UNIFIED IDEOGRAPH
+0x915E	0x616F	#CJK UNIFIED IDEOGRAPH
+0x915F	0x6171	#CJK UNIFIED IDEOGRAPH
+0x9160	0x6172	#CJK UNIFIED IDEOGRAPH
+0x9161	0x6173	#CJK UNIFIED IDEOGRAPH
+0x9162	0x6174	#CJK UNIFIED IDEOGRAPH
+0x9163	0x6176	#CJK UNIFIED IDEOGRAPH
+0x9164	0x6178	#CJK UNIFIED IDEOGRAPH
+0x9165	0x6179	#CJK UNIFIED IDEOGRAPH
+0x9166	0x617A	#CJK UNIFIED IDEOGRAPH
+0x9167	0x617B	#CJK UNIFIED IDEOGRAPH
+0x9168	0x617C	#CJK UNIFIED IDEOGRAPH
+0x9169	0x617D	#CJK UNIFIED IDEOGRAPH
+0x916A	0x617E	#CJK UNIFIED IDEOGRAPH
+0x916B	0x617F	#CJK UNIFIED IDEOGRAPH
+0x916C	0x6180	#CJK UNIFIED IDEOGRAPH
+0x916D	0x6181	#CJK UNIFIED IDEOGRAPH
+0x916E	0x6182	#CJK UNIFIED IDEOGRAPH
+0x916F	0x6183	#CJK UNIFIED IDEOGRAPH
+0x9170	0x6184	#CJK UNIFIED IDEOGRAPH
+0x9171	0x6185	#CJK UNIFIED IDEOGRAPH
+0x9172	0x6186	#CJK UNIFIED IDEOGRAPH
+0x9173	0x6187	#CJK UNIFIED IDEOGRAPH
+0x9174	0x6188	#CJK UNIFIED IDEOGRAPH
+0x9175	0x6189	#CJK UNIFIED IDEOGRAPH
+0x9176	0x618A	#CJK UNIFIED IDEOGRAPH
+0x9177	0x618C	#CJK UNIFIED IDEOGRAPH
+0x9178	0x618D	#CJK UNIFIED IDEOGRAPH
+0x9179	0x618F	#CJK UNIFIED IDEOGRAPH
+0x917A	0x6190	#CJK UNIFIED IDEOGRAPH
+0x917B	0x6191	#CJK UNIFIED IDEOGRAPH
+0x917C	0x6192	#CJK UNIFIED IDEOGRAPH
+0x917D	0x6193	#CJK UNIFIED IDEOGRAPH
+0x917E	0x6195	#CJK UNIFIED IDEOGRAPH
+0x9180	0x6196	#CJK UNIFIED IDEOGRAPH
+0x9181	0x6197	#CJK UNIFIED IDEOGRAPH
+0x9182	0x6198	#CJK UNIFIED IDEOGRAPH
+0x9183	0x6199	#CJK UNIFIED IDEOGRAPH
+0x9184	0x619A	#CJK UNIFIED IDEOGRAPH
+0x9185	0x619B	#CJK UNIFIED IDEOGRAPH
+0x9186	0x619C	#CJK UNIFIED IDEOGRAPH
+0x9187	0x619E	#CJK UNIFIED IDEOGRAPH
+0x9188	0x619F	#CJK UNIFIED IDEOGRAPH
+0x9189	0x61A0	#CJK UNIFIED IDEOGRAPH
+0x918A	0x61A1	#CJK UNIFIED IDEOGRAPH
+0x918B	0x61A2	#CJK UNIFIED IDEOGRAPH
+0x918C	0x61A3	#CJK UNIFIED IDEOGRAPH
+0x918D	0x61A4	#CJK UNIFIED IDEOGRAPH
+0x918E	0x61A5	#CJK UNIFIED IDEOGRAPH
+0x918F	0x61A6	#CJK UNIFIED IDEOGRAPH
+0x9190	0x61AA	#CJK UNIFIED IDEOGRAPH
+0x9191	0x61AB	#CJK UNIFIED IDEOGRAPH
+0x9192	0x61AD	#CJK UNIFIED IDEOGRAPH
+0x9193	0x61AE	#CJK UNIFIED IDEOGRAPH
+0x9194	0x61AF	#CJK UNIFIED IDEOGRAPH
+0x9195	0x61B0	#CJK UNIFIED IDEOGRAPH
+0x9196	0x61B1	#CJK UNIFIED IDEOGRAPH
+0x9197	0x61B2	#CJK UNIFIED IDEOGRAPH
+0x9198	0x61B3	#CJK UNIFIED IDEOGRAPH
+0x9199	0x61B4	#CJK UNIFIED IDEOGRAPH
+0x919A	0x61B5	#CJK UNIFIED IDEOGRAPH
+0x919B	0x61B6	#CJK UNIFIED IDEOGRAPH
+0x919C	0x61B8	#CJK UNIFIED IDEOGRAPH
+0x919D	0x61B9	#CJK UNIFIED IDEOGRAPH
+0x919E	0x61BA	#CJK UNIFIED IDEOGRAPH
+0x919F	0x61BB	#CJK UNIFIED IDEOGRAPH
+0x91A0	0x61BC	#CJK UNIFIED IDEOGRAPH
+0x91A1	0x61BD	#CJK UNIFIED IDEOGRAPH
+0x91A2	0x61BF	#CJK UNIFIED IDEOGRAPH
+0x91A3	0x61C0	#CJK UNIFIED IDEOGRAPH
+0x91A4	0x61C1	#CJK UNIFIED IDEOGRAPH
+0x91A5	0x61C3	#CJK UNIFIED IDEOGRAPH
+0x91A6	0x61C4	#CJK UNIFIED IDEOGRAPH
+0x91A7	0x61C5	#CJK UNIFIED IDEOGRAPH
+0x91A8	0x61C6	#CJK UNIFIED IDEOGRAPH
+0x91A9	0x61C7	#CJK UNIFIED IDEOGRAPH
+0x91AA	0x61C9	#CJK UNIFIED IDEOGRAPH
+0x91AB	0x61CC	#CJK UNIFIED IDEOGRAPH
+0x91AC	0x61CD	#CJK UNIFIED IDEOGRAPH
+0x91AD	0x61CE	#CJK UNIFIED IDEOGRAPH
+0x91AE	0x61CF	#CJK UNIFIED IDEOGRAPH
+0x91AF	0x61D0	#CJK UNIFIED IDEOGRAPH
+0x91B0	0x61D3	#CJK UNIFIED IDEOGRAPH
+0x91B1	0x61D5	#CJK UNIFIED IDEOGRAPH
+0x91B2	0x61D6	#CJK UNIFIED IDEOGRAPH
+0x91B3	0x61D7	#CJK UNIFIED IDEOGRAPH
+0x91B4	0x61D8	#CJK UNIFIED IDEOGRAPH
+0x91B5	0x61D9	#CJK UNIFIED IDEOGRAPH
+0x91B6	0x61DA	#CJK UNIFIED IDEOGRAPH
+0x91B7	0x61DB	#CJK UNIFIED IDEOGRAPH
+0x91B8	0x61DC	#CJK UNIFIED IDEOGRAPH
+0x91B9	0x61DD	#CJK UNIFIED IDEOGRAPH
+0x91BA	0x61DE	#CJK UNIFIED IDEOGRAPH
+0x91BB	0x61DF	#CJK UNIFIED IDEOGRAPH
+0x91BC	0x61E0	#CJK UNIFIED IDEOGRAPH
+0x91BD	0x61E1	#CJK UNIFIED IDEOGRAPH
+0x91BE	0x61E2	#CJK UNIFIED IDEOGRAPH
+0x91BF	0x61E3	#CJK UNIFIED IDEOGRAPH
+0x91C0	0x61E4	#CJK UNIFIED IDEOGRAPH
+0x91C1	0x61E5	#CJK UNIFIED IDEOGRAPH
+0x91C2	0x61E7	#CJK UNIFIED IDEOGRAPH
+0x91C3	0x61E8	#CJK UNIFIED IDEOGRAPH
+0x91C4	0x61E9	#CJK UNIFIED IDEOGRAPH
+0x91C5	0x61EA	#CJK UNIFIED IDEOGRAPH
+0x91C6	0x61EB	#CJK UNIFIED IDEOGRAPH
+0x91C7	0x61EC	#CJK UNIFIED IDEOGRAPH
+0x91C8	0x61ED	#CJK UNIFIED IDEOGRAPH
+0x91C9	0x61EE	#CJK UNIFIED IDEOGRAPH
+0x91CA	0x61EF	#CJK UNIFIED IDEOGRAPH
+0x91CB	0x61F0	#CJK UNIFIED IDEOGRAPH
+0x91CC	0x61F1	#CJK UNIFIED IDEOGRAPH
+0x91CD	0x61F2	#CJK UNIFIED IDEOGRAPH
+0x91CE	0x61F3	#CJK UNIFIED IDEOGRAPH
+0x91CF	0x61F4	#CJK UNIFIED IDEOGRAPH
+0x91D0	0x61F6	#CJK UNIFIED IDEOGRAPH
+0x91D1	0x61F7	#CJK UNIFIED IDEOGRAPH
+0x91D2	0x61F8	#CJK UNIFIED IDEOGRAPH
+0x91D3	0x61F9	#CJK UNIFIED IDEOGRAPH
+0x91D4	0x61FA	#CJK UNIFIED IDEOGRAPH
+0x91D5	0x61FB	#CJK UNIFIED IDEOGRAPH
+0x91D6	0x61FC	#CJK UNIFIED IDEOGRAPH
+0x91D7	0x61FD	#CJK UNIFIED IDEOGRAPH
+0x91D8	0x61FE	#CJK UNIFIED IDEOGRAPH
+0x91D9	0x6200	#CJK UNIFIED IDEOGRAPH
+0x91DA	0x6201	#CJK UNIFIED IDEOGRAPH
+0x91DB	0x6202	#CJK UNIFIED IDEOGRAPH
+0x91DC	0x6203	#CJK UNIFIED IDEOGRAPH
+0x91DD	0x6204	#CJK UNIFIED IDEOGRAPH
+0x91DE	0x6205	#CJK UNIFIED IDEOGRAPH
+0x91DF	0x6207	#CJK UNIFIED IDEOGRAPH
+0x91E0	0x6209	#CJK UNIFIED IDEOGRAPH
+0x91E1	0x6213	#CJK UNIFIED IDEOGRAPH
+0x91E2	0x6214	#CJK UNIFIED IDEOGRAPH
+0x91E3	0x6219	#CJK UNIFIED IDEOGRAPH
+0x91E4	0x621C	#CJK UNIFIED IDEOGRAPH
+0x91E5	0x621D	#CJK UNIFIED IDEOGRAPH
+0x91E6	0x621E	#CJK UNIFIED IDEOGRAPH
+0x91E7	0x6220	#CJK UNIFIED IDEOGRAPH
+0x91E8	0x6223	#CJK UNIFIED IDEOGRAPH
+0x91E9	0x6226	#CJK UNIFIED IDEOGRAPH
+0x91EA	0x6227	#CJK UNIFIED IDEOGRAPH
+0x91EB	0x6228	#CJK UNIFIED IDEOGRAPH
+0x91EC	0x6229	#CJK UNIFIED IDEOGRAPH
+0x91ED	0x622B	#CJK UNIFIED IDEOGRAPH
+0x91EE	0x622D	#CJK UNIFIED IDEOGRAPH
+0x91EF	0x622F	#CJK UNIFIED IDEOGRAPH
+0x91F0	0x6230	#CJK UNIFIED IDEOGRAPH
+0x91F1	0x6231	#CJK UNIFIED IDEOGRAPH
+0x91F2	0x6232	#CJK UNIFIED IDEOGRAPH
+0x91F3	0x6235	#CJK UNIFIED IDEOGRAPH
+0x91F4	0x6236	#CJK UNIFIED IDEOGRAPH
+0x91F5	0x6238	#CJK UNIFIED IDEOGRAPH
+0x91F6	0x6239	#CJK UNIFIED IDEOGRAPH
+0x91F7	0x623A	#CJK UNIFIED IDEOGRAPH
+0x91F8	0x623B	#CJK UNIFIED IDEOGRAPH
+0x91F9	0x623C	#CJK UNIFIED IDEOGRAPH
+0x91FA	0x6242	#CJK UNIFIED IDEOGRAPH
+0x91FB	0x6244	#CJK UNIFIED IDEOGRAPH
+0x91FC	0x6245	#CJK UNIFIED IDEOGRAPH
+0x91FD	0x6246	#CJK UNIFIED IDEOGRAPH
+0x91FE	0x624A	#CJK UNIFIED IDEOGRAPH
+0x9240	0x624F	#CJK UNIFIED IDEOGRAPH
+0x9241	0x6250	#CJK UNIFIED IDEOGRAPH
+0x9242	0x6255	#CJK UNIFIED IDEOGRAPH
+0x9243	0x6256	#CJK UNIFIED IDEOGRAPH
+0x9244	0x6257	#CJK UNIFIED IDEOGRAPH
+0x9245	0x6259	#CJK UNIFIED IDEOGRAPH
+0x9246	0x625A	#CJK UNIFIED IDEOGRAPH
+0x9247	0x625C	#CJK UNIFIED IDEOGRAPH
+0x9248	0x625D	#CJK UNIFIED IDEOGRAPH
+0x9249	0x625E	#CJK UNIFIED IDEOGRAPH
+0x924A	0x625F	#CJK UNIFIED IDEOGRAPH
+0x924B	0x6260	#CJK UNIFIED IDEOGRAPH
+0x924C	0x6261	#CJK UNIFIED IDEOGRAPH
+0x924D	0x6262	#CJK UNIFIED IDEOGRAPH
+0x924E	0x6264	#CJK UNIFIED IDEOGRAPH
+0x924F	0x6265	#CJK UNIFIED IDEOGRAPH
+0x9250	0x6268	#CJK UNIFIED IDEOGRAPH
+0x9251	0x6271	#CJK UNIFIED IDEOGRAPH
+0x9252	0x6272	#CJK UNIFIED IDEOGRAPH
+0x9253	0x6274	#CJK UNIFIED IDEOGRAPH
+0x9254	0x6275	#CJK UNIFIED IDEOGRAPH
+0x9255	0x6277	#CJK UNIFIED IDEOGRAPH
+0x9256	0x6278	#CJK UNIFIED IDEOGRAPH
+0x9257	0x627A	#CJK UNIFIED IDEOGRAPH
+0x9258	0x627B	#CJK UNIFIED IDEOGRAPH
+0x9259	0x627D	#CJK UNIFIED IDEOGRAPH
+0x925A	0x6281	#CJK UNIFIED IDEOGRAPH
+0x925B	0x6282	#CJK UNIFIED IDEOGRAPH
+0x925C	0x6283	#CJK UNIFIED IDEOGRAPH
+0x925D	0x6285	#CJK UNIFIED IDEOGRAPH
+0x925E	0x6286	#CJK UNIFIED IDEOGRAPH
+0x925F	0x6287	#CJK UNIFIED IDEOGRAPH
+0x9260	0x6288	#CJK UNIFIED IDEOGRAPH
+0x9261	0x628B	#CJK UNIFIED IDEOGRAPH
+0x9262	0x628C	#CJK UNIFIED IDEOGRAPH
+0x9263	0x628D	#CJK UNIFIED IDEOGRAPH
+0x9264	0x628E	#CJK UNIFIED IDEOGRAPH
+0x9265	0x628F	#CJK UNIFIED IDEOGRAPH
+0x9266	0x6290	#CJK UNIFIED IDEOGRAPH
+0x9267	0x6294	#CJK UNIFIED IDEOGRAPH
+0x9268	0x6299	#CJK UNIFIED IDEOGRAPH
+0x9269	0x629C	#CJK UNIFIED IDEOGRAPH
+0x926A	0x629D	#CJK UNIFIED IDEOGRAPH
+0x926B	0x629E	#CJK UNIFIED IDEOGRAPH
+0x926C	0x62A3	#CJK UNIFIED IDEOGRAPH
+0x926D	0x62A6	#CJK UNIFIED IDEOGRAPH
+0x926E	0x62A7	#CJK UNIFIED IDEOGRAPH
+0x926F	0x62A9	#CJK UNIFIED IDEOGRAPH
+0x9270	0x62AA	#CJK UNIFIED IDEOGRAPH
+0x9271	0x62AD	#CJK UNIFIED IDEOGRAPH
+0x9272	0x62AE	#CJK UNIFIED IDEOGRAPH
+0x9273	0x62AF	#CJK UNIFIED IDEOGRAPH
+0x9274	0x62B0	#CJK UNIFIED IDEOGRAPH
+0x9275	0x62B2	#CJK UNIFIED IDEOGRAPH
+0x9276	0x62B3	#CJK UNIFIED IDEOGRAPH
+0x9277	0x62B4	#CJK UNIFIED IDEOGRAPH
+0x9278	0x62B6	#CJK UNIFIED IDEOGRAPH
+0x9279	0x62B7	#CJK UNIFIED IDEOGRAPH
+0x927A	0x62B8	#CJK UNIFIED IDEOGRAPH
+0x927B	0x62BA	#CJK UNIFIED IDEOGRAPH
+0x927C	0x62BE	#CJK UNIFIED IDEOGRAPH
+0x927D	0x62C0	#CJK UNIFIED IDEOGRAPH
+0x927E	0x62C1	#CJK UNIFIED IDEOGRAPH
+0x9280	0x62C3	#CJK UNIFIED IDEOGRAPH
+0x9281	0x62CB	#CJK UNIFIED IDEOGRAPH
+0x9282	0x62CF	#CJK UNIFIED IDEOGRAPH
+0x9283	0x62D1	#CJK UNIFIED IDEOGRAPH
+0x9284	0x62D5	#CJK UNIFIED IDEOGRAPH
+0x9285	0x62DD	#CJK UNIFIED IDEOGRAPH
+0x9286	0x62DE	#CJK UNIFIED IDEOGRAPH
+0x9287	0x62E0	#CJK UNIFIED IDEOGRAPH
+0x9288	0x62E1	#CJK UNIFIED IDEOGRAPH
+0x9289	0x62E4	#CJK UNIFIED IDEOGRAPH
+0x928A	0x62EA	#CJK UNIFIED IDEOGRAPH
+0x928B	0x62EB	#CJK UNIFIED IDEOGRAPH
+0x928C	0x62F0	#CJK UNIFIED IDEOGRAPH
+0x928D	0x62F2	#CJK UNIFIED IDEOGRAPH
+0x928E	0x62F5	#CJK UNIFIED IDEOGRAPH
+0x928F	0x62F8	#CJK UNIFIED IDEOGRAPH
+0x9290	0x62F9	#CJK UNIFIED IDEOGRAPH
+0x9291	0x62FA	#CJK UNIFIED IDEOGRAPH
+0x9292	0x62FB	#CJK UNIFIED IDEOGRAPH
+0x9293	0x6300	#CJK UNIFIED IDEOGRAPH
+0x9294	0x6303	#CJK UNIFIED IDEOGRAPH
+0x9295	0x6304	#CJK UNIFIED IDEOGRAPH
+0x9296	0x6305	#CJK UNIFIED IDEOGRAPH
+0x9297	0x6306	#CJK UNIFIED IDEOGRAPH
+0x9298	0x630A	#CJK UNIFIED IDEOGRAPH
+0x9299	0x630B	#CJK UNIFIED IDEOGRAPH
+0x929A	0x630C	#CJK UNIFIED IDEOGRAPH
+0x929B	0x630D	#CJK UNIFIED IDEOGRAPH
+0x929C	0x630F	#CJK UNIFIED IDEOGRAPH
+0x929D	0x6310	#CJK UNIFIED IDEOGRAPH
+0x929E	0x6312	#CJK UNIFIED IDEOGRAPH
+0x929F	0x6313	#CJK UNIFIED IDEOGRAPH
+0x92A0	0x6314	#CJK UNIFIED IDEOGRAPH
+0x92A1	0x6315	#CJK UNIFIED IDEOGRAPH
+0x92A2	0x6317	#CJK UNIFIED IDEOGRAPH
+0x92A3	0x6318	#CJK UNIFIED IDEOGRAPH
+0x92A4	0x6319	#CJK UNIFIED IDEOGRAPH
+0x92A5	0x631C	#CJK UNIFIED IDEOGRAPH
+0x92A6	0x6326	#CJK UNIFIED IDEOGRAPH
+0x92A7	0x6327	#CJK UNIFIED IDEOGRAPH
+0x92A8	0x6329	#CJK UNIFIED IDEOGRAPH
+0x92A9	0x632C	#CJK UNIFIED IDEOGRAPH
+0x92AA	0x632D	#CJK UNIFIED IDEOGRAPH
+0x92AB	0x632E	#CJK UNIFIED IDEOGRAPH
+0x92AC	0x6330	#CJK UNIFIED IDEOGRAPH
+0x92AD	0x6331	#CJK UNIFIED IDEOGRAPH
+0x92AE	0x6333	#CJK UNIFIED IDEOGRAPH
+0x92AF	0x6334	#CJK UNIFIED IDEOGRAPH
+0x92B0	0x6335	#CJK UNIFIED IDEOGRAPH
+0x92B1	0x6336	#CJK UNIFIED IDEOGRAPH
+0x92B2	0x6337	#CJK UNIFIED IDEOGRAPH
+0x92B3	0x6338	#CJK UNIFIED IDEOGRAPH
+0x92B4	0x633B	#CJK UNIFIED IDEOGRAPH
+0x92B5	0x633C	#CJK UNIFIED IDEOGRAPH
+0x92B6	0x633E	#CJK UNIFIED IDEOGRAPH
+0x92B7	0x633F	#CJK UNIFIED IDEOGRAPH
+0x92B8	0x6340	#CJK UNIFIED IDEOGRAPH
+0x92B9	0x6341	#CJK UNIFIED IDEOGRAPH
+0x92BA	0x6344	#CJK UNIFIED IDEOGRAPH
+0x92BB	0x6347	#CJK UNIFIED IDEOGRAPH
+0x92BC	0x6348	#CJK UNIFIED IDEOGRAPH
+0x92BD	0x634A	#CJK UNIFIED IDEOGRAPH
+0x92BE	0x6351	#CJK UNIFIED IDEOGRAPH
+0x92BF	0x6352	#CJK UNIFIED IDEOGRAPH
+0x92C0	0x6353	#CJK UNIFIED IDEOGRAPH
+0x92C1	0x6354	#CJK UNIFIED IDEOGRAPH
+0x92C2	0x6356	#CJK UNIFIED IDEOGRAPH
+0x92C3	0x6357	#CJK UNIFIED IDEOGRAPH
+0x92C4	0x6358	#CJK UNIFIED IDEOGRAPH
+0x92C5	0x6359	#CJK UNIFIED IDEOGRAPH
+0x92C6	0x635A	#CJK UNIFIED IDEOGRAPH
+0x92C7	0x635B	#CJK UNIFIED IDEOGRAPH
+0x92C8	0x635C	#CJK UNIFIED IDEOGRAPH
+0x92C9	0x635D	#CJK UNIFIED IDEOGRAPH
+0x92CA	0x6360	#CJK UNIFIED IDEOGRAPH
+0x92CB	0x6364	#CJK UNIFIED IDEOGRAPH
+0x92CC	0x6365	#CJK UNIFIED IDEOGRAPH
+0x92CD	0x6366	#CJK UNIFIED IDEOGRAPH
+0x92CE	0x6368	#CJK UNIFIED IDEOGRAPH
+0x92CF	0x636A	#CJK UNIFIED IDEOGRAPH
+0x92D0	0x636B	#CJK UNIFIED IDEOGRAPH
+0x92D1	0x636C	#CJK UNIFIED IDEOGRAPH
+0x92D2	0x636F	#CJK UNIFIED IDEOGRAPH
+0x92D3	0x6370	#CJK UNIFIED IDEOGRAPH
+0x92D4	0x6372	#CJK UNIFIED IDEOGRAPH
+0x92D5	0x6373	#CJK UNIFIED IDEOGRAPH
+0x92D6	0x6374	#CJK UNIFIED IDEOGRAPH
+0x92D7	0x6375	#CJK UNIFIED IDEOGRAPH
+0x92D8	0x6378	#CJK UNIFIED IDEOGRAPH
+0x92D9	0x6379	#CJK UNIFIED IDEOGRAPH
+0x92DA	0x637C	#CJK UNIFIED IDEOGRAPH
+0x92DB	0x637D	#CJK UNIFIED IDEOGRAPH
+0x92DC	0x637E	#CJK UNIFIED IDEOGRAPH
+0x92DD	0x637F	#CJK UNIFIED IDEOGRAPH
+0x92DE	0x6381	#CJK UNIFIED IDEOGRAPH
+0x92DF	0x6383	#CJK UNIFIED IDEOGRAPH
+0x92E0	0x6384	#CJK UNIFIED IDEOGRAPH
+0x92E1	0x6385	#CJK UNIFIED IDEOGRAPH
+0x92E2	0x6386	#CJK UNIFIED IDEOGRAPH
+0x92E3	0x638B	#CJK UNIFIED IDEOGRAPH
+0x92E4	0x638D	#CJK UNIFIED IDEOGRAPH
+0x92E5	0x6391	#CJK UNIFIED IDEOGRAPH
+0x92E6	0x6393	#CJK UNIFIED IDEOGRAPH
+0x92E7	0x6394	#CJK UNIFIED IDEOGRAPH
+0x92E8	0x6395	#CJK UNIFIED IDEOGRAPH
+0x92E9	0x6397	#CJK UNIFIED IDEOGRAPH
+0x92EA	0x6399	#CJK UNIFIED IDEOGRAPH
+0x92EB	0x639A	#CJK UNIFIED IDEOGRAPH
+0x92EC	0x639B	#CJK UNIFIED IDEOGRAPH
+0x92ED	0x639C	#CJK UNIFIED IDEOGRAPH
+0x92EE	0x639D	#CJK UNIFIED IDEOGRAPH
+0x92EF	0x639E	#CJK UNIFIED IDEOGRAPH
+0x92F0	0x639F	#CJK UNIFIED IDEOGRAPH
+0x92F1	0x63A1	#CJK UNIFIED IDEOGRAPH
+0x92F2	0x63A4	#CJK UNIFIED IDEOGRAPH
+0x92F3	0x63A6	#CJK UNIFIED IDEOGRAPH
+0x92F4	0x63AB	#CJK UNIFIED IDEOGRAPH
+0x92F5	0x63AF	#CJK UNIFIED IDEOGRAPH
+0x92F6	0x63B1	#CJK UNIFIED IDEOGRAPH
+0x92F7	0x63B2	#CJK UNIFIED IDEOGRAPH
+0x92F8	0x63B5	#CJK UNIFIED IDEOGRAPH
+0x92F9	0x63B6	#CJK UNIFIED IDEOGRAPH
+0x92FA	0x63B9	#CJK UNIFIED IDEOGRAPH
+0x92FB	0x63BB	#CJK UNIFIED IDEOGRAPH
+0x92FC	0x63BD	#CJK UNIFIED IDEOGRAPH
+0x92FD	0x63BF	#CJK UNIFIED IDEOGRAPH
+0x92FE	0x63C0	#CJK UNIFIED IDEOGRAPH
+0x9340	0x63C1	#CJK UNIFIED IDEOGRAPH
+0x9341	0x63C2	#CJK UNIFIED IDEOGRAPH
+0x9342	0x63C3	#CJK UNIFIED IDEOGRAPH
+0x9343	0x63C5	#CJK UNIFIED IDEOGRAPH
+0x9344	0x63C7	#CJK UNIFIED IDEOGRAPH
+0x9345	0x63C8	#CJK UNIFIED IDEOGRAPH
+0x9346	0x63CA	#CJK UNIFIED IDEOGRAPH
+0x9347	0x63CB	#CJK UNIFIED IDEOGRAPH
+0x9348	0x63CC	#CJK UNIFIED IDEOGRAPH
+0x9349	0x63D1	#CJK UNIFIED IDEOGRAPH
+0x934A	0x63D3	#CJK UNIFIED IDEOGRAPH
+0x934B	0x63D4	#CJK UNIFIED IDEOGRAPH
+0x934C	0x63D5	#CJK UNIFIED IDEOGRAPH
+0x934D	0x63D7	#CJK UNIFIED IDEOGRAPH
+0x934E	0x63D8	#CJK UNIFIED IDEOGRAPH
+0x934F	0x63D9	#CJK UNIFIED IDEOGRAPH
+0x9350	0x63DA	#CJK UNIFIED IDEOGRAPH
+0x9351	0x63DB	#CJK UNIFIED IDEOGRAPH
+0x9352	0x63DC	#CJK UNIFIED IDEOGRAPH
+0x9353	0x63DD	#CJK UNIFIED IDEOGRAPH
+0x9354	0x63DF	#CJK UNIFIED IDEOGRAPH
+0x9355	0x63E2	#CJK UNIFIED IDEOGRAPH
+0x9356	0x63E4	#CJK UNIFIED IDEOGRAPH
+0x9357	0x63E5	#CJK UNIFIED IDEOGRAPH
+0x9358	0x63E6	#CJK UNIFIED IDEOGRAPH
+0x9359	0x63E7	#CJK UNIFIED IDEOGRAPH
+0x935A	0x63E8	#CJK UNIFIED IDEOGRAPH
+0x935B	0x63EB	#CJK UNIFIED IDEOGRAPH
+0x935C	0x63EC	#CJK UNIFIED IDEOGRAPH
+0x935D	0x63EE	#CJK UNIFIED IDEOGRAPH
+0x935E	0x63EF	#CJK UNIFIED IDEOGRAPH
+0x935F	0x63F0	#CJK UNIFIED IDEOGRAPH
+0x9360	0x63F1	#CJK UNIFIED IDEOGRAPH
+0x9361	0x63F3	#CJK UNIFIED IDEOGRAPH
+0x9362	0x63F5	#CJK UNIFIED IDEOGRAPH
+0x9363	0x63F7	#CJK UNIFIED IDEOGRAPH
+0x9364	0x63F9	#CJK UNIFIED IDEOGRAPH
+0x9365	0x63FA	#CJK UNIFIED IDEOGRAPH
+0x9366	0x63FB	#CJK UNIFIED IDEOGRAPH
+0x9367	0x63FC	#CJK UNIFIED IDEOGRAPH
+0x9368	0x63FE	#CJK UNIFIED IDEOGRAPH
+0x9369	0x6403	#CJK UNIFIED IDEOGRAPH
+0x936A	0x6404	#CJK UNIFIED IDEOGRAPH
+0x936B	0x6406	#CJK UNIFIED IDEOGRAPH
+0x936C	0x6407	#CJK UNIFIED IDEOGRAPH
+0x936D	0x6408	#CJK UNIFIED IDEOGRAPH
+0x936E	0x6409	#CJK UNIFIED IDEOGRAPH
+0x936F	0x640A	#CJK UNIFIED IDEOGRAPH
+0x9370	0x640D	#CJK UNIFIED IDEOGRAPH
+0x9371	0x640E	#CJK UNIFIED IDEOGRAPH
+0x9372	0x6411	#CJK UNIFIED IDEOGRAPH
+0x9373	0x6412	#CJK UNIFIED IDEOGRAPH
+0x9374	0x6415	#CJK UNIFIED IDEOGRAPH
+0x9375	0x6416	#CJK UNIFIED IDEOGRAPH
+0x9376	0x6417	#CJK UNIFIED IDEOGRAPH
+0x9377	0x6418	#CJK UNIFIED IDEOGRAPH
+0x9378	0x6419	#CJK UNIFIED IDEOGRAPH
+0x9379	0x641A	#CJK UNIFIED IDEOGRAPH
+0x937A	0x641D	#CJK UNIFIED IDEOGRAPH
+0x937B	0x641F	#CJK UNIFIED IDEOGRAPH
+0x937C	0x6422	#CJK UNIFIED IDEOGRAPH
+0x937D	0x6423	#CJK UNIFIED IDEOGRAPH
+0x937E	0x6424	#CJK UNIFIED IDEOGRAPH
+0x9380	0x6425	#CJK UNIFIED IDEOGRAPH
+0x9381	0x6427	#CJK UNIFIED IDEOGRAPH
+0x9382	0x6428	#CJK UNIFIED IDEOGRAPH
+0x9383	0x6429	#CJK UNIFIED IDEOGRAPH
+0x9384	0x642B	#CJK UNIFIED IDEOGRAPH
+0x9385	0x642E	#CJK UNIFIED IDEOGRAPH
+0x9386	0x642F	#CJK UNIFIED IDEOGRAPH
+0x9387	0x6430	#CJK UNIFIED IDEOGRAPH
+0x9388	0x6431	#CJK UNIFIED IDEOGRAPH
+0x9389	0x6432	#CJK UNIFIED IDEOGRAPH
+0x938A	0x6433	#CJK UNIFIED IDEOGRAPH
+0x938B	0x6435	#CJK UNIFIED IDEOGRAPH
+0x938C	0x6436	#CJK UNIFIED IDEOGRAPH
+0x938D	0x6437	#CJK UNIFIED IDEOGRAPH
+0x938E	0x6438	#CJK UNIFIED IDEOGRAPH
+0x938F	0x6439	#CJK UNIFIED IDEOGRAPH
+0x9390	0x643B	#CJK UNIFIED IDEOGRAPH
+0x9391	0x643C	#CJK UNIFIED IDEOGRAPH
+0x9392	0x643E	#CJK UNIFIED IDEOGRAPH
+0x9393	0x6440	#CJK UNIFIED IDEOGRAPH
+0x9394	0x6442	#CJK UNIFIED IDEOGRAPH
+0x9395	0x6443	#CJK UNIFIED IDEOGRAPH
+0x9396	0x6449	#CJK UNIFIED IDEOGRAPH
+0x9397	0x644B	#CJK UNIFIED IDEOGRAPH
+0x9398	0x644C	#CJK UNIFIED IDEOGRAPH
+0x9399	0x644D	#CJK UNIFIED IDEOGRAPH
+0x939A	0x644E	#CJK UNIFIED IDEOGRAPH
+0x939B	0x644F	#CJK UNIFIED IDEOGRAPH
+0x939C	0x6450	#CJK UNIFIED IDEOGRAPH
+0x939D	0x6451	#CJK UNIFIED IDEOGRAPH
+0x939E	0x6453	#CJK UNIFIED IDEOGRAPH
+0x939F	0x6455	#CJK UNIFIED IDEOGRAPH
+0x93A0	0x6456	#CJK UNIFIED IDEOGRAPH
+0x93A1	0x6457	#CJK UNIFIED IDEOGRAPH
+0x93A2	0x6459	#CJK UNIFIED IDEOGRAPH
+0x93A3	0x645A	#CJK UNIFIED IDEOGRAPH
+0x93A4	0x645B	#CJK UNIFIED IDEOGRAPH
+0x93A5	0x645C	#CJK UNIFIED IDEOGRAPH
+0x93A6	0x645D	#CJK UNIFIED IDEOGRAPH
+0x93A7	0x645F	#CJK UNIFIED IDEOGRAPH
+0x93A8	0x6460	#CJK UNIFIED IDEOGRAPH
+0x93A9	0x6461	#CJK UNIFIED IDEOGRAPH
+0x93AA	0x6462	#CJK UNIFIED IDEOGRAPH
+0x93AB	0x6463	#CJK UNIFIED IDEOGRAPH
+0x93AC	0x6464	#CJK UNIFIED IDEOGRAPH
+0x93AD	0x6465	#CJK UNIFIED IDEOGRAPH
+0x93AE	0x6466	#CJK UNIFIED IDEOGRAPH
+0x93AF	0x6468	#CJK UNIFIED IDEOGRAPH
+0x93B0	0x646A	#CJK UNIFIED IDEOGRAPH
+0x93B1	0x646B	#CJK UNIFIED IDEOGRAPH
+0x93B2	0x646C	#CJK UNIFIED IDEOGRAPH
+0x93B3	0x646E	#CJK UNIFIED IDEOGRAPH
+0x93B4	0x646F	#CJK UNIFIED IDEOGRAPH
+0x93B5	0x6470	#CJK UNIFIED IDEOGRAPH
+0x93B6	0x6471	#CJK UNIFIED IDEOGRAPH
+0x93B7	0x6472	#CJK UNIFIED IDEOGRAPH
+0x93B8	0x6473	#CJK UNIFIED IDEOGRAPH
+0x93B9	0x6474	#CJK UNIFIED IDEOGRAPH
+0x93BA	0x6475	#CJK UNIFIED IDEOGRAPH
+0x93BB	0x6476	#CJK UNIFIED IDEOGRAPH
+0x93BC	0x6477	#CJK UNIFIED IDEOGRAPH
+0x93BD	0x647B	#CJK UNIFIED IDEOGRAPH
+0x93BE	0x647C	#CJK UNIFIED IDEOGRAPH
+0x93BF	0x647D	#CJK UNIFIED IDEOGRAPH
+0x93C0	0x647E	#CJK UNIFIED IDEOGRAPH
+0x93C1	0x647F	#CJK UNIFIED IDEOGRAPH
+0x93C2	0x6480	#CJK UNIFIED IDEOGRAPH
+0x93C3	0x6481	#CJK UNIFIED IDEOGRAPH
+0x93C4	0x6483	#CJK UNIFIED IDEOGRAPH
+0x93C5	0x6486	#CJK UNIFIED IDEOGRAPH
+0x93C6	0x6488	#CJK UNIFIED IDEOGRAPH
+0x93C7	0x6489	#CJK UNIFIED IDEOGRAPH
+0x93C8	0x648A	#CJK UNIFIED IDEOGRAPH
+0x93C9	0x648B	#CJK UNIFIED IDEOGRAPH
+0x93CA	0x648C	#CJK UNIFIED IDEOGRAPH
+0x93CB	0x648D	#CJK UNIFIED IDEOGRAPH
+0x93CC	0x648E	#CJK UNIFIED IDEOGRAPH
+0x93CD	0x648F	#CJK UNIFIED IDEOGRAPH
+0x93CE	0x6490	#CJK UNIFIED IDEOGRAPH
+0x93CF	0x6493	#CJK UNIFIED IDEOGRAPH
+0x93D0	0x6494	#CJK UNIFIED IDEOGRAPH
+0x93D1	0x6497	#CJK UNIFIED IDEOGRAPH
+0x93D2	0x6498	#CJK UNIFIED IDEOGRAPH
+0x93D3	0x649A	#CJK UNIFIED IDEOGRAPH
+0x93D4	0x649B	#CJK UNIFIED IDEOGRAPH
+0x93D5	0x649C	#CJK UNIFIED IDEOGRAPH
+0x93D6	0x649D	#CJK UNIFIED IDEOGRAPH
+0x93D7	0x649F	#CJK UNIFIED IDEOGRAPH
+0x93D8	0x64A0	#CJK UNIFIED IDEOGRAPH
+0x93D9	0x64A1	#CJK UNIFIED IDEOGRAPH
+0x93DA	0x64A2	#CJK UNIFIED IDEOGRAPH
+0x93DB	0x64A3	#CJK UNIFIED IDEOGRAPH
+0x93DC	0x64A5	#CJK UNIFIED IDEOGRAPH
+0x93DD	0x64A6	#CJK UNIFIED IDEOGRAPH
+0x93DE	0x64A7	#CJK UNIFIED IDEOGRAPH
+0x93DF	0x64A8	#CJK UNIFIED IDEOGRAPH
+0x93E0	0x64AA	#CJK UNIFIED IDEOGRAPH
+0x93E1	0x64AB	#CJK UNIFIED IDEOGRAPH
+0x93E2	0x64AF	#CJK UNIFIED IDEOGRAPH
+0x93E3	0x64B1	#CJK UNIFIED IDEOGRAPH
+0x93E4	0x64B2	#CJK UNIFIED IDEOGRAPH
+0x93E5	0x64B3	#CJK UNIFIED IDEOGRAPH
+0x93E6	0x64B4	#CJK UNIFIED IDEOGRAPH
+0x93E7	0x64B6	#CJK UNIFIED IDEOGRAPH
+0x93E8	0x64B9	#CJK UNIFIED IDEOGRAPH
+0x93E9	0x64BB	#CJK UNIFIED IDEOGRAPH
+0x93EA	0x64BD	#CJK UNIFIED IDEOGRAPH
+0x93EB	0x64BE	#CJK UNIFIED IDEOGRAPH
+0x93EC	0x64BF	#CJK UNIFIED IDEOGRAPH
+0x93ED	0x64C1	#CJK UNIFIED IDEOGRAPH
+0x93EE	0x64C3	#CJK UNIFIED IDEOGRAPH
+0x93EF	0x64C4	#CJK UNIFIED IDEOGRAPH
+0x93F0	0x64C6	#CJK UNIFIED IDEOGRAPH
+0x93F1	0x64C7	#CJK UNIFIED IDEOGRAPH
+0x93F2	0x64C8	#CJK UNIFIED IDEOGRAPH
+0x93F3	0x64C9	#CJK UNIFIED IDEOGRAPH
+0x93F4	0x64CA	#CJK UNIFIED IDEOGRAPH
+0x93F5	0x64CB	#CJK UNIFIED IDEOGRAPH
+0x93F6	0x64CC	#CJK UNIFIED IDEOGRAPH
+0x93F7	0x64CF	#CJK UNIFIED IDEOGRAPH
+0x93F8	0x64D1	#CJK UNIFIED IDEOGRAPH
+0x93F9	0x64D3	#CJK UNIFIED IDEOGRAPH
+0x93FA	0x64D4	#CJK UNIFIED IDEOGRAPH
+0x93FB	0x64D5	#CJK UNIFIED IDEOGRAPH
+0x93FC	0x64D6	#CJK UNIFIED IDEOGRAPH
+0x93FD	0x64D9	#CJK UNIFIED IDEOGRAPH
+0x93FE	0x64DA	#CJK UNIFIED IDEOGRAPH
+0x9440	0x64DB	#CJK UNIFIED IDEOGRAPH
+0x9441	0x64DC	#CJK UNIFIED IDEOGRAPH
+0x9442	0x64DD	#CJK UNIFIED IDEOGRAPH
+0x9443	0x64DF	#CJK UNIFIED IDEOGRAPH
+0x9444	0x64E0	#CJK UNIFIED IDEOGRAPH
+0x9445	0x64E1	#CJK UNIFIED IDEOGRAPH
+0x9446	0x64E3	#CJK UNIFIED IDEOGRAPH
+0x9447	0x64E5	#CJK UNIFIED IDEOGRAPH
+0x9448	0x64E7	#CJK UNIFIED IDEOGRAPH
+0x9449	0x64E8	#CJK UNIFIED IDEOGRAPH
+0x944A	0x64E9	#CJK UNIFIED IDEOGRAPH
+0x944B	0x64EA	#CJK UNIFIED IDEOGRAPH
+0x944C	0x64EB	#CJK UNIFIED IDEOGRAPH
+0x944D	0x64EC	#CJK UNIFIED IDEOGRAPH
+0x944E	0x64ED	#CJK UNIFIED IDEOGRAPH
+0x944F	0x64EE	#CJK UNIFIED IDEOGRAPH
+0x9450	0x64EF	#CJK UNIFIED IDEOGRAPH
+0x9451	0x64F0	#CJK UNIFIED IDEOGRAPH
+0x9452	0x64F1	#CJK UNIFIED IDEOGRAPH
+0x9453	0x64F2	#CJK UNIFIED IDEOGRAPH
+0x9454	0x64F3	#CJK UNIFIED IDEOGRAPH
+0x9455	0x64F4	#CJK UNIFIED IDEOGRAPH
+0x9456	0x64F5	#CJK UNIFIED IDEOGRAPH
+0x9457	0x64F6	#CJK UNIFIED IDEOGRAPH
+0x9458	0x64F7	#CJK UNIFIED IDEOGRAPH
+0x9459	0x64F8	#CJK UNIFIED IDEOGRAPH
+0x945A	0x64F9	#CJK UNIFIED IDEOGRAPH
+0x945B	0x64FA	#CJK UNIFIED IDEOGRAPH
+0x945C	0x64FB	#CJK UNIFIED IDEOGRAPH
+0x945D	0x64FC	#CJK UNIFIED IDEOGRAPH
+0x945E	0x64FD	#CJK UNIFIED IDEOGRAPH
+0x945F	0x64FE	#CJK UNIFIED IDEOGRAPH
+0x9460	0x64FF	#CJK UNIFIED IDEOGRAPH
+0x9461	0x6501	#CJK UNIFIED IDEOGRAPH
+0x9462	0x6502	#CJK UNIFIED IDEOGRAPH
+0x9463	0x6503	#CJK UNIFIED IDEOGRAPH
+0x9464	0x6504	#CJK UNIFIED IDEOGRAPH
+0x9465	0x6505	#CJK UNIFIED IDEOGRAPH
+0x9466	0x6506	#CJK UNIFIED IDEOGRAPH
+0x9467	0x6507	#CJK UNIFIED IDEOGRAPH
+0x9468	0x6508	#CJK UNIFIED IDEOGRAPH
+0x9469	0x650A	#CJK UNIFIED IDEOGRAPH
+0x946A	0x650B	#CJK UNIFIED IDEOGRAPH
+0x946B	0x650C	#CJK UNIFIED IDEOGRAPH
+0x946C	0x650D	#CJK UNIFIED IDEOGRAPH
+0x946D	0x650E	#CJK UNIFIED IDEOGRAPH
+0x946E	0x650F	#CJK UNIFIED IDEOGRAPH
+0x946F	0x6510	#CJK UNIFIED IDEOGRAPH
+0x9470	0x6511	#CJK UNIFIED IDEOGRAPH
+0x9471	0x6513	#CJK UNIFIED IDEOGRAPH
+0x9472	0x6514	#CJK UNIFIED IDEOGRAPH
+0x9473	0x6515	#CJK UNIFIED IDEOGRAPH
+0x9474	0x6516	#CJK UNIFIED IDEOGRAPH
+0x9475	0x6517	#CJK UNIFIED IDEOGRAPH
+0x9476	0x6519	#CJK UNIFIED IDEOGRAPH
+0x9477	0x651A	#CJK UNIFIED IDEOGRAPH
+0x9478	0x651B	#CJK UNIFIED IDEOGRAPH
+0x9479	0x651C	#CJK UNIFIED IDEOGRAPH
+0x947A	0x651D	#CJK UNIFIED IDEOGRAPH
+0x947B	0x651E	#CJK UNIFIED IDEOGRAPH
+0x947C	0x651F	#CJK UNIFIED IDEOGRAPH
+0x947D	0x6520	#CJK UNIFIED IDEOGRAPH
+0x947E	0x6521	#CJK UNIFIED IDEOGRAPH
+0x9480	0x6522	#CJK UNIFIED IDEOGRAPH
+0x9481	0x6523	#CJK UNIFIED IDEOGRAPH
+0x9482	0x6524	#CJK UNIFIED IDEOGRAPH
+0x9483	0x6526	#CJK UNIFIED IDEOGRAPH
+0x9484	0x6527	#CJK UNIFIED IDEOGRAPH
+0x9485	0x6528	#CJK UNIFIED IDEOGRAPH
+0x9486	0x6529	#CJK UNIFIED IDEOGRAPH
+0x9487	0x652A	#CJK UNIFIED IDEOGRAPH
+0x9488	0x652C	#CJK UNIFIED IDEOGRAPH
+0x9489	0x652D	#CJK UNIFIED IDEOGRAPH
+0x948A	0x6530	#CJK UNIFIED IDEOGRAPH
+0x948B	0x6531	#CJK UNIFIED IDEOGRAPH
+0x948C	0x6532	#CJK UNIFIED IDEOGRAPH
+0x948D	0x6533	#CJK UNIFIED IDEOGRAPH
+0x948E	0x6537	#CJK UNIFIED IDEOGRAPH
+0x948F	0x653A	#CJK UNIFIED IDEOGRAPH
+0x9490	0x653C	#CJK UNIFIED IDEOGRAPH
+0x9491	0x653D	#CJK UNIFIED IDEOGRAPH
+0x9492	0x6540	#CJK UNIFIED IDEOGRAPH
+0x9493	0x6541	#CJK UNIFIED IDEOGRAPH
+0x9494	0x6542	#CJK UNIFIED IDEOGRAPH
+0x9495	0x6543	#CJK UNIFIED IDEOGRAPH
+0x9496	0x6544	#CJK UNIFIED IDEOGRAPH
+0x9497	0x6546	#CJK UNIFIED IDEOGRAPH
+0x9498	0x6547	#CJK UNIFIED IDEOGRAPH
+0x9499	0x654A	#CJK UNIFIED IDEOGRAPH
+0x949A	0x654B	#CJK UNIFIED IDEOGRAPH
+0x949B	0x654D	#CJK UNIFIED IDEOGRAPH
+0x949C	0x654E	#CJK UNIFIED IDEOGRAPH
+0x949D	0x6550	#CJK UNIFIED IDEOGRAPH
+0x949E	0x6552	#CJK UNIFIED IDEOGRAPH
+0x949F	0x6553	#CJK UNIFIED IDEOGRAPH
+0x94A0	0x6554	#CJK UNIFIED IDEOGRAPH
+0x94A1	0x6557	#CJK UNIFIED IDEOGRAPH
+0x94A2	0x6558	#CJK UNIFIED IDEOGRAPH
+0x94A3	0x655A	#CJK UNIFIED IDEOGRAPH
+0x94A4	0x655C	#CJK UNIFIED IDEOGRAPH
+0x94A5	0x655F	#CJK UNIFIED IDEOGRAPH
+0x94A6	0x6560	#CJK UNIFIED IDEOGRAPH
+0x94A7	0x6561	#CJK UNIFIED IDEOGRAPH
+0x94A8	0x6564	#CJK UNIFIED IDEOGRAPH
+0x94A9	0x6565	#CJK UNIFIED IDEOGRAPH
+0x94AA	0x6567	#CJK UNIFIED IDEOGRAPH
+0x94AB	0x6568	#CJK UNIFIED IDEOGRAPH
+0x94AC	0x6569	#CJK UNIFIED IDEOGRAPH
+0x94AD	0x656A	#CJK UNIFIED IDEOGRAPH
+0x94AE	0x656D	#CJK UNIFIED IDEOGRAPH
+0x94AF	0x656E	#CJK UNIFIED IDEOGRAPH
+0x94B0	0x656F	#CJK UNIFIED IDEOGRAPH
+0x94B1	0x6571	#CJK UNIFIED IDEOGRAPH
+0x94B2	0x6573	#CJK UNIFIED IDEOGRAPH
+0x94B3	0x6575	#CJK UNIFIED IDEOGRAPH
+0x94B4	0x6576	#CJK UNIFIED IDEOGRAPH
+0x94B5	0x6578	#CJK UNIFIED IDEOGRAPH
+0x94B6	0x6579	#CJK UNIFIED IDEOGRAPH
+0x94B7	0x657A	#CJK UNIFIED IDEOGRAPH
+0x94B8	0x657B	#CJK UNIFIED IDEOGRAPH
+0x94B9	0x657C	#CJK UNIFIED IDEOGRAPH
+0x94BA	0x657D	#CJK UNIFIED IDEOGRAPH
+0x94BB	0x657E	#CJK UNIFIED IDEOGRAPH
+0x94BC	0x657F	#CJK UNIFIED IDEOGRAPH
+0x94BD	0x6580	#CJK UNIFIED IDEOGRAPH
+0x94BE	0x6581	#CJK UNIFIED IDEOGRAPH
+0x94BF	0x6582	#CJK UNIFIED IDEOGRAPH
+0x94C0	0x6583	#CJK UNIFIED IDEOGRAPH
+0x94C1	0x6584	#CJK UNIFIED IDEOGRAPH
+0x94C2	0x6585	#CJK UNIFIED IDEOGRAPH
+0x94C3	0x6586	#CJK UNIFIED IDEOGRAPH
+0x94C4	0x6588	#CJK UNIFIED IDEOGRAPH
+0x94C5	0x6589	#CJK UNIFIED IDEOGRAPH
+0x94C6	0x658A	#CJK UNIFIED IDEOGRAPH
+0x94C7	0x658D	#CJK UNIFIED IDEOGRAPH
+0x94C8	0x658E	#CJK UNIFIED IDEOGRAPH
+0x94C9	0x658F	#CJK UNIFIED IDEOGRAPH
+0x94CA	0x6592	#CJK UNIFIED IDEOGRAPH
+0x94CB	0x6594	#CJK UNIFIED IDEOGRAPH
+0x94CC	0x6595	#CJK UNIFIED IDEOGRAPH
+0x94CD	0x6596	#CJK UNIFIED IDEOGRAPH
+0x94CE	0x6598	#CJK UNIFIED IDEOGRAPH
+0x94CF	0x659A	#CJK UNIFIED IDEOGRAPH
+0x94D0	0x659D	#CJK UNIFIED IDEOGRAPH
+0x94D1	0x659E	#CJK UNIFIED IDEOGRAPH
+0x94D2	0x65A0	#CJK UNIFIED IDEOGRAPH
+0x94D3	0x65A2	#CJK UNIFIED IDEOGRAPH
+0x94D4	0x65A3	#CJK UNIFIED IDEOGRAPH
+0x94D5	0x65A6	#CJK UNIFIED IDEOGRAPH
+0x94D6	0x65A8	#CJK UNIFIED IDEOGRAPH
+0x94D7	0x65AA	#CJK UNIFIED IDEOGRAPH
+0x94D8	0x65AC	#CJK UNIFIED IDEOGRAPH
+0x94D9	0x65AE	#CJK UNIFIED IDEOGRAPH
+0x94DA	0x65B1	#CJK UNIFIED IDEOGRAPH
+0x94DB	0x65B2	#CJK UNIFIED IDEOGRAPH
+0x94DC	0x65B3	#CJK UNIFIED IDEOGRAPH
+0x94DD	0x65B4	#CJK UNIFIED IDEOGRAPH
+0x94DE	0x65B5	#CJK UNIFIED IDEOGRAPH
+0x94DF	0x65B6	#CJK UNIFIED IDEOGRAPH
+0x94E0	0x65B7	#CJK UNIFIED IDEOGRAPH
+0x94E1	0x65B8	#CJK UNIFIED IDEOGRAPH
+0x94E2	0x65BA	#CJK UNIFIED IDEOGRAPH
+0x94E3	0x65BB	#CJK UNIFIED IDEOGRAPH
+0x94E4	0x65BE	#CJK UNIFIED IDEOGRAPH
+0x94E5	0x65BF	#CJK UNIFIED IDEOGRAPH
+0x94E6	0x65C0	#CJK UNIFIED IDEOGRAPH
+0x94E7	0x65C2	#CJK UNIFIED IDEOGRAPH
+0x94E8	0x65C7	#CJK UNIFIED IDEOGRAPH
+0x94E9	0x65C8	#CJK UNIFIED IDEOGRAPH
+0x94EA	0x65C9	#CJK UNIFIED IDEOGRAPH
+0x94EB	0x65CA	#CJK UNIFIED IDEOGRAPH
+0x94EC	0x65CD	#CJK UNIFIED IDEOGRAPH
+0x94ED	0x65D0	#CJK UNIFIED IDEOGRAPH
+0x94EE	0x65D1	#CJK UNIFIED IDEOGRAPH
+0x94EF	0x65D3	#CJK UNIFIED IDEOGRAPH
+0x94F0	0x65D4	#CJK UNIFIED IDEOGRAPH
+0x94F1	0x65D5	#CJK UNIFIED IDEOGRAPH
+0x94F2	0x65D8	#CJK UNIFIED IDEOGRAPH
+0x94F3	0x65D9	#CJK UNIFIED IDEOGRAPH
+0x94F4	0x65DA	#CJK UNIFIED IDEOGRAPH
+0x94F5	0x65DB	#CJK UNIFIED IDEOGRAPH
+0x94F6	0x65DC	#CJK UNIFIED IDEOGRAPH
+0x94F7	0x65DD	#CJK UNIFIED IDEOGRAPH
+0x94F8	0x65DE	#CJK UNIFIED IDEOGRAPH
+0x94F9	0x65DF	#CJK UNIFIED IDEOGRAPH
+0x94FA	0x65E1	#CJK UNIFIED IDEOGRAPH
+0x94FB	0x65E3	#CJK UNIFIED IDEOGRAPH
+0x94FC	0x65E4	#CJK UNIFIED IDEOGRAPH
+0x94FD	0x65EA	#CJK UNIFIED IDEOGRAPH
+0x94FE	0x65EB	#CJK UNIFIED IDEOGRAPH
+0x9540	0x65F2	#CJK UNIFIED IDEOGRAPH
+0x9541	0x65F3	#CJK UNIFIED IDEOGRAPH
+0x9542	0x65F4	#CJK UNIFIED IDEOGRAPH
+0x9543	0x65F5	#CJK UNIFIED IDEOGRAPH
+0x9544	0x65F8	#CJK UNIFIED IDEOGRAPH
+0x9545	0x65F9	#CJK UNIFIED IDEOGRAPH
+0x9546	0x65FB	#CJK UNIFIED IDEOGRAPH
+0x9547	0x65FC	#CJK UNIFIED IDEOGRAPH
+0x9548	0x65FD	#CJK UNIFIED IDEOGRAPH
+0x9549	0x65FE	#CJK UNIFIED IDEOGRAPH
+0x954A	0x65FF	#CJK UNIFIED IDEOGRAPH
+0x954B	0x6601	#CJK UNIFIED IDEOGRAPH
+0x954C	0x6604	#CJK UNIFIED IDEOGRAPH
+0x954D	0x6605	#CJK UNIFIED IDEOGRAPH
+0x954E	0x6607	#CJK UNIFIED IDEOGRAPH
+0x954F	0x6608	#CJK UNIFIED IDEOGRAPH
+0x9550	0x6609	#CJK UNIFIED IDEOGRAPH
+0x9551	0x660B	#CJK UNIFIED IDEOGRAPH
+0x9552	0x660D	#CJK UNIFIED IDEOGRAPH
+0x9553	0x6610	#CJK UNIFIED IDEOGRAPH
+0x9554	0x6611	#CJK UNIFIED IDEOGRAPH
+0x9555	0x6612	#CJK UNIFIED IDEOGRAPH
+0x9556	0x6616	#CJK UNIFIED IDEOGRAPH
+0x9557	0x6617	#CJK UNIFIED IDEOGRAPH
+0x9558	0x6618	#CJK UNIFIED IDEOGRAPH
+0x9559	0x661A	#CJK UNIFIED IDEOGRAPH
+0x955A	0x661B	#CJK UNIFIED IDEOGRAPH
+0x955B	0x661C	#CJK UNIFIED IDEOGRAPH
+0x955C	0x661E	#CJK UNIFIED IDEOGRAPH
+0x955D	0x6621	#CJK UNIFIED IDEOGRAPH
+0x955E	0x6622	#CJK UNIFIED IDEOGRAPH
+0x955F	0x6623	#CJK UNIFIED IDEOGRAPH
+0x9560	0x6624	#CJK UNIFIED IDEOGRAPH
+0x9561	0x6626	#CJK UNIFIED IDEOGRAPH
+0x9562	0x6629	#CJK UNIFIED IDEOGRAPH
+0x9563	0x662A	#CJK UNIFIED IDEOGRAPH
+0x9564	0x662B	#CJK UNIFIED IDEOGRAPH
+0x9565	0x662C	#CJK UNIFIED IDEOGRAPH
+0x9566	0x662E	#CJK UNIFIED IDEOGRAPH
+0x9567	0x6630	#CJK UNIFIED IDEOGRAPH
+0x9568	0x6632	#CJK UNIFIED IDEOGRAPH
+0x9569	0x6633	#CJK UNIFIED IDEOGRAPH
+0x956A	0x6637	#CJK UNIFIED IDEOGRAPH
+0x956B	0x6638	#CJK UNIFIED IDEOGRAPH
+0x956C	0x6639	#CJK UNIFIED IDEOGRAPH
+0x956D	0x663A	#CJK UNIFIED IDEOGRAPH
+0x956E	0x663B	#CJK UNIFIED IDEOGRAPH
+0x956F	0x663D	#CJK UNIFIED IDEOGRAPH
+0x9570	0x663F	#CJK UNIFIED IDEOGRAPH
+0x9571	0x6640	#CJK UNIFIED IDEOGRAPH
+0x9572	0x6642	#CJK UNIFIED IDEOGRAPH
+0x9573	0x6644	#CJK UNIFIED IDEOGRAPH
+0x9574	0x6645	#CJK UNIFIED IDEOGRAPH
+0x9575	0x6646	#CJK UNIFIED IDEOGRAPH
+0x9576	0x6647	#CJK UNIFIED IDEOGRAPH
+0x9577	0x6648	#CJK UNIFIED IDEOGRAPH
+0x9578	0x6649	#CJK UNIFIED IDEOGRAPH
+0x9579	0x664A	#CJK UNIFIED IDEOGRAPH
+0x957A	0x664D	#CJK UNIFIED IDEOGRAPH
+0x957B	0x664E	#CJK UNIFIED IDEOGRAPH
+0x957C	0x6650	#CJK UNIFIED IDEOGRAPH
+0x957D	0x6651	#CJK UNIFIED IDEOGRAPH
+0x957E	0x6658	#CJK UNIFIED IDEOGRAPH
+0x9580	0x6659	#CJK UNIFIED IDEOGRAPH
+0x9581	0x665B	#CJK UNIFIED IDEOGRAPH
+0x9582	0x665C	#CJK UNIFIED IDEOGRAPH
+0x9583	0x665D	#CJK UNIFIED IDEOGRAPH
+0x9584	0x665E	#CJK UNIFIED IDEOGRAPH
+0x9585	0x6660	#CJK UNIFIED IDEOGRAPH
+0x9586	0x6662	#CJK UNIFIED IDEOGRAPH
+0x9587	0x6663	#CJK UNIFIED IDEOGRAPH
+0x9588	0x6665	#CJK UNIFIED IDEOGRAPH
+0x9589	0x6667	#CJK UNIFIED IDEOGRAPH
+0x958A	0x6669	#CJK UNIFIED IDEOGRAPH
+0x958B	0x666A	#CJK UNIFIED IDEOGRAPH
+0x958C	0x666B	#CJK UNIFIED IDEOGRAPH
+0x958D	0x666C	#CJK UNIFIED IDEOGRAPH
+0x958E	0x666D	#CJK UNIFIED IDEOGRAPH
+0x958F	0x6671	#CJK UNIFIED IDEOGRAPH
+0x9590	0x6672	#CJK UNIFIED IDEOGRAPH
+0x9591	0x6673	#CJK UNIFIED IDEOGRAPH
+0x9592	0x6675	#CJK UNIFIED IDEOGRAPH
+0x9593	0x6678	#CJK UNIFIED IDEOGRAPH
+0x9594	0x6679	#CJK UNIFIED IDEOGRAPH
+0x9595	0x667B	#CJK UNIFIED IDEOGRAPH
+0x9596	0x667C	#CJK UNIFIED IDEOGRAPH
+0x9597	0x667D	#CJK UNIFIED IDEOGRAPH
+0x9598	0x667F	#CJK UNIFIED IDEOGRAPH
+0x9599	0x6680	#CJK UNIFIED IDEOGRAPH
+0x959A	0x6681	#CJK UNIFIED IDEOGRAPH
+0x959B	0x6683	#CJK UNIFIED IDEOGRAPH
+0x959C	0x6685	#CJK UNIFIED IDEOGRAPH
+0x959D	0x6686	#CJK UNIFIED IDEOGRAPH
+0x959E	0x6688	#CJK UNIFIED IDEOGRAPH
+0x959F	0x6689	#CJK UNIFIED IDEOGRAPH
+0x95A0	0x668A	#CJK UNIFIED IDEOGRAPH
+0x95A1	0x668B	#CJK UNIFIED IDEOGRAPH
+0x95A2	0x668D	#CJK UNIFIED IDEOGRAPH
+0x95A3	0x668E	#CJK UNIFIED IDEOGRAPH
+0x95A4	0x668F	#CJK UNIFIED IDEOGRAPH
+0x95A5	0x6690	#CJK UNIFIED IDEOGRAPH
+0x95A6	0x6692	#CJK UNIFIED IDEOGRAPH
+0x95A7	0x6693	#CJK UNIFIED IDEOGRAPH
+0x95A8	0x6694	#CJK UNIFIED IDEOGRAPH
+0x95A9	0x6695	#CJK UNIFIED IDEOGRAPH
+0x95AA	0x6698	#CJK UNIFIED IDEOGRAPH
+0x95AB	0x6699	#CJK UNIFIED IDEOGRAPH
+0x95AC	0x669A	#CJK UNIFIED IDEOGRAPH
+0x95AD	0x669B	#CJK UNIFIED IDEOGRAPH
+0x95AE	0x669C	#CJK UNIFIED IDEOGRAPH
+0x95AF	0x669E	#CJK UNIFIED IDEOGRAPH
+0x95B0	0x669F	#CJK UNIFIED IDEOGRAPH
+0x95B1	0x66A0	#CJK UNIFIED IDEOGRAPH
+0x95B2	0x66A1	#CJK UNIFIED IDEOGRAPH
+0x95B3	0x66A2	#CJK UNIFIED IDEOGRAPH
+0x95B4	0x66A3	#CJK UNIFIED IDEOGRAPH
+0x95B5	0x66A4	#CJK UNIFIED IDEOGRAPH
+0x95B6	0x66A5	#CJK UNIFIED IDEOGRAPH
+0x95B7	0x66A6	#CJK UNIFIED IDEOGRAPH
+0x95B8	0x66A9	#CJK UNIFIED IDEOGRAPH
+0x95B9	0x66AA	#CJK UNIFIED IDEOGRAPH
+0x95BA	0x66AB	#CJK UNIFIED IDEOGRAPH
+0x95BB	0x66AC	#CJK UNIFIED IDEOGRAPH
+0x95BC	0x66AD	#CJK UNIFIED IDEOGRAPH
+0x95BD	0x66AF	#CJK UNIFIED IDEOGRAPH
+0x95BE	0x66B0	#CJK UNIFIED IDEOGRAPH
+0x95BF	0x66B1	#CJK UNIFIED IDEOGRAPH
+0x95C0	0x66B2	#CJK UNIFIED IDEOGRAPH
+0x95C1	0x66B3	#CJK UNIFIED IDEOGRAPH
+0x95C2	0x66B5	#CJK UNIFIED IDEOGRAPH
+0x95C3	0x66B6	#CJK UNIFIED IDEOGRAPH
+0x95C4	0x66B7	#CJK UNIFIED IDEOGRAPH
+0x95C5	0x66B8	#CJK UNIFIED IDEOGRAPH
+0x95C6	0x66BA	#CJK UNIFIED IDEOGRAPH
+0x95C7	0x66BB	#CJK UNIFIED IDEOGRAPH
+0x95C8	0x66BC	#CJK UNIFIED IDEOGRAPH
+0x95C9	0x66BD	#CJK UNIFIED IDEOGRAPH
+0x95CA	0x66BF	#CJK UNIFIED IDEOGRAPH
+0x95CB	0x66C0	#CJK UNIFIED IDEOGRAPH
+0x95CC	0x66C1	#CJK UNIFIED IDEOGRAPH
+0x95CD	0x66C2	#CJK UNIFIED IDEOGRAPH
+0x95CE	0x66C3	#CJK UNIFIED IDEOGRAPH
+0x95CF	0x66C4	#CJK UNIFIED IDEOGRAPH
+0x95D0	0x66C5	#CJK UNIFIED IDEOGRAPH
+0x95D1	0x66C6	#CJK UNIFIED IDEOGRAPH
+0x95D2	0x66C7	#CJK UNIFIED IDEOGRAPH
+0x95D3	0x66C8	#CJK UNIFIED IDEOGRAPH
+0x95D4	0x66C9	#CJK UNIFIED IDEOGRAPH
+0x95D5	0x66CA	#CJK UNIFIED IDEOGRAPH
+0x95D6	0x66CB	#CJK UNIFIED IDEOGRAPH
+0x95D7	0x66CC	#CJK UNIFIED IDEOGRAPH
+0x95D8	0x66CD	#CJK UNIFIED IDEOGRAPH
+0x95D9	0x66CE	#CJK UNIFIED IDEOGRAPH
+0x95DA	0x66CF	#CJK UNIFIED IDEOGRAPH
+0x95DB	0x66D0	#CJK UNIFIED IDEOGRAPH
+0x95DC	0x66D1	#CJK UNIFIED IDEOGRAPH
+0x95DD	0x66D2	#CJK UNIFIED IDEOGRAPH
+0x95DE	0x66D3	#CJK UNIFIED IDEOGRAPH
+0x95DF	0x66D4	#CJK UNIFIED IDEOGRAPH
+0x95E0	0x66D5	#CJK UNIFIED IDEOGRAPH
+0x95E1	0x66D6	#CJK UNIFIED IDEOGRAPH
+0x95E2	0x66D7	#CJK UNIFIED IDEOGRAPH
+0x95E3	0x66D8	#CJK UNIFIED IDEOGRAPH
+0x95E4	0x66DA	#CJK UNIFIED IDEOGRAPH
+0x95E5	0x66DE	#CJK UNIFIED IDEOGRAPH
+0x95E6	0x66DF	#CJK UNIFIED IDEOGRAPH
+0x95E7	0x66E0	#CJK UNIFIED IDEOGRAPH
+0x95E8	0x66E1	#CJK UNIFIED IDEOGRAPH
+0x95E9	0x66E2	#CJK UNIFIED IDEOGRAPH
+0x95EA	0x66E3	#CJK UNIFIED IDEOGRAPH
+0x95EB	0x66E4	#CJK UNIFIED IDEOGRAPH
+0x95EC	0x66E5	#CJK UNIFIED IDEOGRAPH
+0x95ED	0x66E7	#CJK UNIFIED IDEOGRAPH
+0x95EE	0x66E8	#CJK UNIFIED IDEOGRAPH
+0x95EF	0x66EA	#CJK UNIFIED IDEOGRAPH
+0x95F0	0x66EB	#CJK UNIFIED IDEOGRAPH
+0x95F1	0x66EC	#CJK UNIFIED IDEOGRAPH
+0x95F2	0x66ED	#CJK UNIFIED IDEOGRAPH
+0x95F3	0x66EE	#CJK UNIFIED IDEOGRAPH
+0x95F4	0x66EF	#CJK UNIFIED IDEOGRAPH
+0x95F5	0x66F1	#CJK UNIFIED IDEOGRAPH
+0x95F6	0x66F5	#CJK UNIFIED IDEOGRAPH
+0x95F7	0x66F6	#CJK UNIFIED IDEOGRAPH
+0x95F8	0x66F8	#CJK UNIFIED IDEOGRAPH
+0x95F9	0x66FA	#CJK UNIFIED IDEOGRAPH
+0x95FA	0x66FB	#CJK UNIFIED IDEOGRAPH
+0x95FB	0x66FD	#CJK UNIFIED IDEOGRAPH
+0x95FC	0x6701	#CJK UNIFIED IDEOGRAPH
+0x95FD	0x6702	#CJK UNIFIED IDEOGRAPH
+0x95FE	0x6703	#CJK UNIFIED IDEOGRAPH
+0x9640	0x6704	#CJK UNIFIED IDEOGRAPH
+0x9641	0x6705	#CJK UNIFIED IDEOGRAPH
+0x9642	0x6706	#CJK UNIFIED IDEOGRAPH
+0x9643	0x6707	#CJK UNIFIED IDEOGRAPH
+0x9644	0x670C	#CJK UNIFIED IDEOGRAPH
+0x9645	0x670E	#CJK UNIFIED IDEOGRAPH
+0x9646	0x670F	#CJK UNIFIED IDEOGRAPH
+0x9647	0x6711	#CJK UNIFIED IDEOGRAPH
+0x9648	0x6712	#CJK UNIFIED IDEOGRAPH
+0x9649	0x6713	#CJK UNIFIED IDEOGRAPH
+0x964A	0x6716	#CJK UNIFIED IDEOGRAPH
+0x964B	0x6718	#CJK UNIFIED IDEOGRAPH
+0x964C	0x6719	#CJK UNIFIED IDEOGRAPH
+0x964D	0x671A	#CJK UNIFIED IDEOGRAPH
+0x964E	0x671C	#CJK UNIFIED IDEOGRAPH
+0x964F	0x671E	#CJK UNIFIED IDEOGRAPH
+0x9650	0x6720	#CJK UNIFIED IDEOGRAPH
+0x9651	0x6721	#CJK UNIFIED IDEOGRAPH
+0x9652	0x6722	#CJK UNIFIED IDEOGRAPH
+0x9653	0x6723	#CJK UNIFIED IDEOGRAPH
+0x9654	0x6724	#CJK UNIFIED IDEOGRAPH
+0x9655	0x6725	#CJK UNIFIED IDEOGRAPH
+0x9656	0x6727	#CJK UNIFIED IDEOGRAPH
+0x9657	0x6729	#CJK UNIFIED IDEOGRAPH
+0x9658	0x672E	#CJK UNIFIED IDEOGRAPH
+0x9659	0x6730	#CJK UNIFIED IDEOGRAPH
+0x965A	0x6732	#CJK UNIFIED IDEOGRAPH
+0x965B	0x6733	#CJK UNIFIED IDEOGRAPH
+0x965C	0x6736	#CJK UNIFIED IDEOGRAPH
+0x965D	0x6737	#CJK UNIFIED IDEOGRAPH
+0x965E	0x6738	#CJK UNIFIED IDEOGRAPH
+0x965F	0x6739	#CJK UNIFIED IDEOGRAPH
+0x9660	0x673B	#CJK UNIFIED IDEOGRAPH
+0x9661	0x673C	#CJK UNIFIED IDEOGRAPH
+0x9662	0x673E	#CJK UNIFIED IDEOGRAPH
+0x9663	0x673F	#CJK UNIFIED IDEOGRAPH
+0x9664	0x6741	#CJK UNIFIED IDEOGRAPH
+0x9665	0x6744	#CJK UNIFIED IDEOGRAPH
+0x9666	0x6745	#CJK UNIFIED IDEOGRAPH
+0x9667	0x6747	#CJK UNIFIED IDEOGRAPH
+0x9668	0x674A	#CJK UNIFIED IDEOGRAPH
+0x9669	0x674B	#CJK UNIFIED IDEOGRAPH
+0x966A	0x674D	#CJK UNIFIED IDEOGRAPH
+0x966B	0x6752	#CJK UNIFIED IDEOGRAPH
+0x966C	0x6754	#CJK UNIFIED IDEOGRAPH
+0x966D	0x6755	#CJK UNIFIED IDEOGRAPH
+0x966E	0x6757	#CJK UNIFIED IDEOGRAPH
+0x966F	0x6758	#CJK UNIFIED IDEOGRAPH
+0x9670	0x6759	#CJK UNIFIED IDEOGRAPH
+0x9671	0x675A	#CJK UNIFIED IDEOGRAPH
+0x9672	0x675B	#CJK UNIFIED IDEOGRAPH
+0x9673	0x675D	#CJK UNIFIED IDEOGRAPH
+0x9674	0x6762	#CJK UNIFIED IDEOGRAPH
+0x9675	0x6763	#CJK UNIFIED IDEOGRAPH
+0x9676	0x6764	#CJK UNIFIED IDEOGRAPH
+0x9677	0x6766	#CJK UNIFIED IDEOGRAPH
+0x9678	0x6767	#CJK UNIFIED IDEOGRAPH
+0x9679	0x676B	#CJK UNIFIED IDEOGRAPH
+0x967A	0x676C	#CJK UNIFIED IDEOGRAPH
+0x967B	0x676E	#CJK UNIFIED IDEOGRAPH
+0x967C	0x6771	#CJK UNIFIED IDEOGRAPH
+0x967D	0x6774	#CJK UNIFIED IDEOGRAPH
+0x967E	0x6776	#CJK UNIFIED IDEOGRAPH
+0x9680	0x6778	#CJK UNIFIED IDEOGRAPH
+0x9681	0x6779	#CJK UNIFIED IDEOGRAPH
+0x9682	0x677A	#CJK UNIFIED IDEOGRAPH
+0x9683	0x677B	#CJK UNIFIED IDEOGRAPH
+0x9684	0x677D	#CJK UNIFIED IDEOGRAPH
+0x9685	0x6780	#CJK UNIFIED IDEOGRAPH
+0x9686	0x6782	#CJK UNIFIED IDEOGRAPH
+0x9687	0x6783	#CJK UNIFIED IDEOGRAPH
+0x9688	0x6785	#CJK UNIFIED IDEOGRAPH
+0x9689	0x6786	#CJK UNIFIED IDEOGRAPH
+0x968A	0x6788	#CJK UNIFIED IDEOGRAPH
+0x968B	0x678A	#CJK UNIFIED IDEOGRAPH
+0x968C	0x678C	#CJK UNIFIED IDEOGRAPH
+0x968D	0x678D	#CJK UNIFIED IDEOGRAPH
+0x968E	0x678E	#CJK UNIFIED IDEOGRAPH
+0x968F	0x678F	#CJK UNIFIED IDEOGRAPH
+0x9690	0x6791	#CJK UNIFIED IDEOGRAPH
+0x9691	0x6792	#CJK UNIFIED IDEOGRAPH
+0x9692	0x6793	#CJK UNIFIED IDEOGRAPH
+0x9693	0x6794	#CJK UNIFIED IDEOGRAPH
+0x9694	0x6796	#CJK UNIFIED IDEOGRAPH
+0x9695	0x6799	#CJK UNIFIED IDEOGRAPH
+0x9696	0x679B	#CJK UNIFIED IDEOGRAPH
+0x9697	0x679F	#CJK UNIFIED IDEOGRAPH
+0x9698	0x67A0	#CJK UNIFIED IDEOGRAPH
+0x9699	0x67A1	#CJK UNIFIED IDEOGRAPH
+0x969A	0x67A4	#CJK UNIFIED IDEOGRAPH
+0x969B	0x67A6	#CJK UNIFIED IDEOGRAPH
+0x969C	0x67A9	#CJK UNIFIED IDEOGRAPH
+0x969D	0x67AC	#CJK UNIFIED IDEOGRAPH
+0x969E	0x67AE	#CJK UNIFIED IDEOGRAPH
+0x969F	0x67B1	#CJK UNIFIED IDEOGRAPH
+0x96A0	0x67B2	#CJK UNIFIED IDEOGRAPH
+0x96A1	0x67B4	#CJK UNIFIED IDEOGRAPH
+0x96A2	0x67B9	#CJK UNIFIED IDEOGRAPH
+0x96A3	0x67BA	#CJK UNIFIED IDEOGRAPH
+0x96A4	0x67BB	#CJK UNIFIED IDEOGRAPH
+0x96A5	0x67BC	#CJK UNIFIED IDEOGRAPH
+0x96A6	0x67BD	#CJK UNIFIED IDEOGRAPH
+0x96A7	0x67BE	#CJK UNIFIED IDEOGRAPH
+0x96A8	0x67BF	#CJK UNIFIED IDEOGRAPH
+0x96A9	0x67C0	#CJK UNIFIED IDEOGRAPH
+0x96AA	0x67C2	#CJK UNIFIED IDEOGRAPH
+0x96AB	0x67C5	#CJK UNIFIED IDEOGRAPH
+0x96AC	0x67C6	#CJK UNIFIED IDEOGRAPH
+0x96AD	0x67C7	#CJK UNIFIED IDEOGRAPH
+0x96AE	0x67C8	#CJK UNIFIED IDEOGRAPH
+0x96AF	0x67C9	#CJK UNIFIED IDEOGRAPH
+0x96B0	0x67CA	#CJK UNIFIED IDEOGRAPH
+0x96B1	0x67CB	#CJK UNIFIED IDEOGRAPH
+0x96B2	0x67CC	#CJK UNIFIED IDEOGRAPH
+0x96B3	0x67CD	#CJK UNIFIED IDEOGRAPH
+0x96B4	0x67CE	#CJK UNIFIED IDEOGRAPH
+0x96B5	0x67D5	#CJK UNIFIED IDEOGRAPH
+0x96B6	0x67D6	#CJK UNIFIED IDEOGRAPH
+0x96B7	0x67D7	#CJK UNIFIED IDEOGRAPH
+0x96B8	0x67DB	#CJK UNIFIED IDEOGRAPH
+0x96B9	0x67DF	#CJK UNIFIED IDEOGRAPH
+0x96BA	0x67E1	#CJK UNIFIED IDEOGRAPH
+0x96BB	0x67E3	#CJK UNIFIED IDEOGRAPH
+0x96BC	0x67E4	#CJK UNIFIED IDEOGRAPH
+0x96BD	0x67E6	#CJK UNIFIED IDEOGRAPH
+0x96BE	0x67E7	#CJK UNIFIED IDEOGRAPH
+0x96BF	0x67E8	#CJK UNIFIED IDEOGRAPH
+0x96C0	0x67EA	#CJK UNIFIED IDEOGRAPH
+0x96C1	0x67EB	#CJK UNIFIED IDEOGRAPH
+0x96C2	0x67ED	#CJK UNIFIED IDEOGRAPH
+0x96C3	0x67EE	#CJK UNIFIED IDEOGRAPH
+0x96C4	0x67F2	#CJK UNIFIED IDEOGRAPH
+0x96C5	0x67F5	#CJK UNIFIED IDEOGRAPH
+0x96C6	0x67F6	#CJK UNIFIED IDEOGRAPH
+0x96C7	0x67F7	#CJK UNIFIED IDEOGRAPH
+0x96C8	0x67F8	#CJK UNIFIED IDEOGRAPH
+0x96C9	0x67F9	#CJK UNIFIED IDEOGRAPH
+0x96CA	0x67FA	#CJK UNIFIED IDEOGRAPH
+0x96CB	0x67FB	#CJK UNIFIED IDEOGRAPH
+0x96CC	0x67FC	#CJK UNIFIED IDEOGRAPH
+0x96CD	0x67FE	#CJK UNIFIED IDEOGRAPH
+0x96CE	0x6801	#CJK UNIFIED IDEOGRAPH
+0x96CF	0x6802	#CJK UNIFIED IDEOGRAPH
+0x96D0	0x6803	#CJK UNIFIED IDEOGRAPH
+0x96D1	0x6804	#CJK UNIFIED IDEOGRAPH
+0x96D2	0x6806	#CJK UNIFIED IDEOGRAPH
+0x96D3	0x680D	#CJK UNIFIED IDEOGRAPH
+0x96D4	0x6810	#CJK UNIFIED IDEOGRAPH
+0x96D5	0x6812	#CJK UNIFIED IDEOGRAPH
+0x96D6	0x6814	#CJK UNIFIED IDEOGRAPH
+0x96D7	0x6815	#CJK UNIFIED IDEOGRAPH
+0x96D8	0x6818	#CJK UNIFIED IDEOGRAPH
+0x96D9	0x6819	#CJK UNIFIED IDEOGRAPH
+0x96DA	0x681A	#CJK UNIFIED IDEOGRAPH
+0x96DB	0x681B	#CJK UNIFIED IDEOGRAPH
+0x96DC	0x681C	#CJK UNIFIED IDEOGRAPH
+0x96DD	0x681E	#CJK UNIFIED IDEOGRAPH
+0x96DE	0x681F	#CJK UNIFIED IDEOGRAPH
+0x96DF	0x6820	#CJK UNIFIED IDEOGRAPH
+0x96E0	0x6822	#CJK UNIFIED IDEOGRAPH
+0x96E1	0x6823	#CJK UNIFIED IDEOGRAPH
+0x96E2	0x6824	#CJK UNIFIED IDEOGRAPH
+0x96E3	0x6825	#CJK UNIFIED IDEOGRAPH
+0x96E4	0x6826	#CJK UNIFIED IDEOGRAPH
+0x96E5	0x6827	#CJK UNIFIED IDEOGRAPH
+0x96E6	0x6828	#CJK UNIFIED IDEOGRAPH
+0x96E7	0x682B	#CJK UNIFIED IDEOGRAPH
+0x96E8	0x682C	#CJK UNIFIED IDEOGRAPH
+0x96E9	0x682D	#CJK UNIFIED IDEOGRAPH
+0x96EA	0x682E	#CJK UNIFIED IDEOGRAPH
+0x96EB	0x682F	#CJK UNIFIED IDEOGRAPH
+0x96EC	0x6830	#CJK UNIFIED IDEOGRAPH
+0x96ED	0x6831	#CJK UNIFIED IDEOGRAPH
+0x96EE	0x6834	#CJK UNIFIED IDEOGRAPH
+0x96EF	0x6835	#CJK UNIFIED IDEOGRAPH
+0x96F0	0x6836	#CJK UNIFIED IDEOGRAPH
+0x96F1	0x683A	#CJK UNIFIED IDEOGRAPH
+0x96F2	0x683B	#CJK UNIFIED IDEOGRAPH
+0x96F3	0x683F	#CJK UNIFIED IDEOGRAPH
+0x96F4	0x6847	#CJK UNIFIED IDEOGRAPH
+0x96F5	0x684B	#CJK UNIFIED IDEOGRAPH
+0x96F6	0x684D	#CJK UNIFIED IDEOGRAPH
+0x96F7	0x684F	#CJK UNIFIED IDEOGRAPH
+0x96F8	0x6852	#CJK UNIFIED IDEOGRAPH
+0x96F9	0x6856	#CJK UNIFIED IDEOGRAPH
+0x96FA	0x6857	#CJK UNIFIED IDEOGRAPH
+0x96FB	0x6858	#CJK UNIFIED IDEOGRAPH
+0x96FC	0x6859	#CJK UNIFIED IDEOGRAPH
+0x96FD	0x685A	#CJK UNIFIED IDEOGRAPH
+0x96FE	0x685B	#CJK UNIFIED IDEOGRAPH
+0x9740	0x685C	#CJK UNIFIED IDEOGRAPH
+0x9741	0x685D	#CJK UNIFIED IDEOGRAPH
+0x9742	0x685E	#CJK UNIFIED IDEOGRAPH
+0x9743	0x685F	#CJK UNIFIED IDEOGRAPH
+0x9744	0x686A	#CJK UNIFIED IDEOGRAPH
+0x9745	0x686C	#CJK UNIFIED IDEOGRAPH
+0x9746	0x686D	#CJK UNIFIED IDEOGRAPH
+0x9747	0x686E	#CJK UNIFIED IDEOGRAPH
+0x9748	0x686F	#CJK UNIFIED IDEOGRAPH
+0x9749	0x6870	#CJK UNIFIED IDEOGRAPH
+0x974A	0x6871	#CJK UNIFIED IDEOGRAPH
+0x974B	0x6872	#CJK UNIFIED IDEOGRAPH
+0x974C	0x6873	#CJK UNIFIED IDEOGRAPH
+0x974D	0x6875	#CJK UNIFIED IDEOGRAPH
+0x974E	0x6878	#CJK UNIFIED IDEOGRAPH
+0x974F	0x6879	#CJK UNIFIED IDEOGRAPH
+0x9750	0x687A	#CJK UNIFIED IDEOGRAPH
+0x9751	0x687B	#CJK UNIFIED IDEOGRAPH
+0x9752	0x687C	#CJK UNIFIED IDEOGRAPH
+0x9753	0x687D	#CJK UNIFIED IDEOGRAPH
+0x9754	0x687E	#CJK UNIFIED IDEOGRAPH
+0x9755	0x687F	#CJK UNIFIED IDEOGRAPH
+0x9756	0x6880	#CJK UNIFIED IDEOGRAPH
+0x9757	0x6882	#CJK UNIFIED IDEOGRAPH
+0x9758	0x6884	#CJK UNIFIED IDEOGRAPH
+0x9759	0x6887	#CJK UNIFIED IDEOGRAPH
+0x975A	0x6888	#CJK UNIFIED IDEOGRAPH
+0x975B	0x6889	#CJK UNIFIED IDEOGRAPH
+0x975C	0x688A	#CJK UNIFIED IDEOGRAPH
+0x975D	0x688B	#CJK UNIFIED IDEOGRAPH
+0x975E	0x688C	#CJK UNIFIED IDEOGRAPH
+0x975F	0x688D	#CJK UNIFIED IDEOGRAPH
+0x9760	0x688E	#CJK UNIFIED IDEOGRAPH
+0x9761	0x6890	#CJK UNIFIED IDEOGRAPH
+0x9762	0x6891	#CJK UNIFIED IDEOGRAPH
+0x9763	0x6892	#CJK UNIFIED IDEOGRAPH
+0x9764	0x6894	#CJK UNIFIED IDEOGRAPH
+0x9765	0x6895	#CJK UNIFIED IDEOGRAPH
+0x9766	0x6896	#CJK UNIFIED IDEOGRAPH
+0x9767	0x6898	#CJK UNIFIED IDEOGRAPH
+0x9768	0x6899	#CJK UNIFIED IDEOGRAPH
+0x9769	0x689A	#CJK UNIFIED IDEOGRAPH
+0x976A	0x689B	#CJK UNIFIED IDEOGRAPH
+0x976B	0x689C	#CJK UNIFIED IDEOGRAPH
+0x976C	0x689D	#CJK UNIFIED IDEOGRAPH
+0x976D	0x689E	#CJK UNIFIED IDEOGRAPH
+0x976E	0x689F	#CJK UNIFIED IDEOGRAPH
+0x976F	0x68A0	#CJK UNIFIED IDEOGRAPH
+0x9770	0x68A1	#CJK UNIFIED IDEOGRAPH
+0x9771	0x68A3	#CJK UNIFIED IDEOGRAPH
+0x9772	0x68A4	#CJK UNIFIED IDEOGRAPH
+0x9773	0x68A5	#CJK UNIFIED IDEOGRAPH
+0x9774	0x68A9	#CJK UNIFIED IDEOGRAPH
+0x9775	0x68AA	#CJK UNIFIED IDEOGRAPH
+0x9776	0x68AB	#CJK UNIFIED IDEOGRAPH
+0x9777	0x68AC	#CJK UNIFIED IDEOGRAPH
+0x9778	0x68AE	#CJK UNIFIED IDEOGRAPH
+0x9779	0x68B1	#CJK UNIFIED IDEOGRAPH
+0x977A	0x68B2	#CJK UNIFIED IDEOGRAPH
+0x977B	0x68B4	#CJK UNIFIED IDEOGRAPH
+0x977C	0x68B6	#CJK UNIFIED IDEOGRAPH
+0x977D	0x68B7	#CJK UNIFIED IDEOGRAPH
+0x977E	0x68B8	#CJK UNIFIED IDEOGRAPH
+0x9780	0x68B9	#CJK UNIFIED IDEOGRAPH
+0x9781	0x68BA	#CJK UNIFIED IDEOGRAPH
+0x9782	0x68BB	#CJK UNIFIED IDEOGRAPH
+0x9783	0x68BC	#CJK UNIFIED IDEOGRAPH
+0x9784	0x68BD	#CJK UNIFIED IDEOGRAPH
+0x9785	0x68BE	#CJK UNIFIED IDEOGRAPH
+0x9786	0x68BF	#CJK UNIFIED IDEOGRAPH
+0x9787	0x68C1	#CJK UNIFIED IDEOGRAPH
+0x9788	0x68C3	#CJK UNIFIED IDEOGRAPH
+0x9789	0x68C4	#CJK UNIFIED IDEOGRAPH
+0x978A	0x68C5	#CJK UNIFIED IDEOGRAPH
+0x978B	0x68C6	#CJK UNIFIED IDEOGRAPH
+0x978C	0x68C7	#CJK UNIFIED IDEOGRAPH
+0x978D	0x68C8	#CJK UNIFIED IDEOGRAPH
+0x978E	0x68CA	#CJK UNIFIED IDEOGRAPH
+0x978F	0x68CC	#CJK UNIFIED IDEOGRAPH
+0x9790	0x68CE	#CJK UNIFIED IDEOGRAPH
+0x9791	0x68CF	#CJK UNIFIED IDEOGRAPH
+0x9792	0x68D0	#CJK UNIFIED IDEOGRAPH
+0x9793	0x68D1	#CJK UNIFIED IDEOGRAPH
+0x9794	0x68D3	#CJK UNIFIED IDEOGRAPH
+0x9795	0x68D4	#CJK UNIFIED IDEOGRAPH
+0x9796	0x68D6	#CJK UNIFIED IDEOGRAPH
+0x9797	0x68D7	#CJK UNIFIED IDEOGRAPH
+0x9798	0x68D9	#CJK UNIFIED IDEOGRAPH
+0x9799	0x68DB	#CJK UNIFIED IDEOGRAPH
+0x979A	0x68DC	#CJK UNIFIED IDEOGRAPH
+0x979B	0x68DD	#CJK UNIFIED IDEOGRAPH
+0x979C	0x68DE	#CJK UNIFIED IDEOGRAPH
+0x979D	0x68DF	#CJK UNIFIED IDEOGRAPH
+0x979E	0x68E1	#CJK UNIFIED IDEOGRAPH
+0x979F	0x68E2	#CJK UNIFIED IDEOGRAPH
+0x97A0	0x68E4	#CJK UNIFIED IDEOGRAPH
+0x97A1	0x68E5	#CJK UNIFIED IDEOGRAPH
+0x97A2	0x68E6	#CJK UNIFIED IDEOGRAPH
+0x97A3	0x68E7	#CJK UNIFIED IDEOGRAPH
+0x97A4	0x68E8	#CJK UNIFIED IDEOGRAPH
+0x97A5	0x68E9	#CJK UNIFIED IDEOGRAPH
+0x97A6	0x68EA	#CJK UNIFIED IDEOGRAPH
+0x97A7	0x68EB	#CJK UNIFIED IDEOGRAPH
+0x97A8	0x68EC	#CJK UNIFIED IDEOGRAPH
+0x97A9	0x68ED	#CJK UNIFIED IDEOGRAPH
+0x97AA	0x68EF	#CJK UNIFIED IDEOGRAPH
+0x97AB	0x68F2	#CJK UNIFIED IDEOGRAPH
+0x97AC	0x68F3	#CJK UNIFIED IDEOGRAPH
+0x97AD	0x68F4	#CJK UNIFIED IDEOGRAPH
+0x97AE	0x68F6	#CJK UNIFIED IDEOGRAPH
+0x97AF	0x68F7	#CJK UNIFIED IDEOGRAPH
+0x97B0	0x68F8	#CJK UNIFIED IDEOGRAPH
+0x97B1	0x68FB	#CJK UNIFIED IDEOGRAPH
+0x97B2	0x68FD	#CJK UNIFIED IDEOGRAPH
+0x97B3	0x68FE	#CJK UNIFIED IDEOGRAPH
+0x97B4	0x68FF	#CJK UNIFIED IDEOGRAPH
+0x97B5	0x6900	#CJK UNIFIED IDEOGRAPH
+0x97B6	0x6902	#CJK UNIFIED IDEOGRAPH
+0x97B7	0x6903	#CJK UNIFIED IDEOGRAPH
+0x97B8	0x6904	#CJK UNIFIED IDEOGRAPH
+0x97B9	0x6906	#CJK UNIFIED IDEOGRAPH
+0x97BA	0x6907	#CJK UNIFIED IDEOGRAPH
+0x97BB	0x6908	#CJK UNIFIED IDEOGRAPH
+0x97BC	0x6909	#CJK UNIFIED IDEOGRAPH
+0x97BD	0x690A	#CJK UNIFIED IDEOGRAPH
+0x97BE	0x690C	#CJK UNIFIED IDEOGRAPH
+0x97BF	0x690F	#CJK UNIFIED IDEOGRAPH
+0x97C0	0x6911	#CJK UNIFIED IDEOGRAPH
+0x97C1	0x6913	#CJK UNIFIED IDEOGRAPH
+0x97C2	0x6914	#CJK UNIFIED IDEOGRAPH
+0x97C3	0x6915	#CJK UNIFIED IDEOGRAPH
+0x97C4	0x6916	#CJK UNIFIED IDEOGRAPH
+0x97C5	0x6917	#CJK UNIFIED IDEOGRAPH
+0x97C6	0x6918	#CJK UNIFIED IDEOGRAPH
+0x97C7	0x6919	#CJK UNIFIED IDEOGRAPH
+0x97C8	0x691A	#CJK UNIFIED IDEOGRAPH
+0x97C9	0x691B	#CJK UNIFIED IDEOGRAPH
+0x97CA	0x691C	#CJK UNIFIED IDEOGRAPH
+0x97CB	0x691D	#CJK UNIFIED IDEOGRAPH
+0x97CC	0x691E	#CJK UNIFIED IDEOGRAPH
+0x97CD	0x6921	#CJK UNIFIED IDEOGRAPH
+0x97CE	0x6922	#CJK UNIFIED IDEOGRAPH
+0x97CF	0x6923	#CJK UNIFIED IDEOGRAPH
+0x97D0	0x6925	#CJK UNIFIED IDEOGRAPH
+0x97D1	0x6926	#CJK UNIFIED IDEOGRAPH
+0x97D2	0x6927	#CJK UNIFIED IDEOGRAPH
+0x97D3	0x6928	#CJK UNIFIED IDEOGRAPH
+0x97D4	0x6929	#CJK UNIFIED IDEOGRAPH
+0x97D5	0x692A	#CJK UNIFIED IDEOGRAPH
+0x97D6	0x692B	#CJK UNIFIED IDEOGRAPH
+0x97D7	0x692C	#CJK UNIFIED IDEOGRAPH
+0x97D8	0x692E	#CJK UNIFIED IDEOGRAPH
+0x97D9	0x692F	#CJK UNIFIED IDEOGRAPH
+0x97DA	0x6931	#CJK UNIFIED IDEOGRAPH
+0x97DB	0x6932	#CJK UNIFIED IDEOGRAPH
+0x97DC	0x6933	#CJK UNIFIED IDEOGRAPH
+0x97DD	0x6935	#CJK UNIFIED IDEOGRAPH
+0x97DE	0x6936	#CJK UNIFIED IDEOGRAPH
+0x97DF	0x6937	#CJK UNIFIED IDEOGRAPH
+0x97E0	0x6938	#CJK UNIFIED IDEOGRAPH
+0x97E1	0x693A	#CJK UNIFIED IDEOGRAPH
+0x97E2	0x693B	#CJK UNIFIED IDEOGRAPH
+0x97E3	0x693C	#CJK UNIFIED IDEOGRAPH
+0x97E4	0x693E	#CJK UNIFIED IDEOGRAPH
+0x97E5	0x6940	#CJK UNIFIED IDEOGRAPH
+0x97E6	0x6941	#CJK UNIFIED IDEOGRAPH
+0x97E7	0x6943	#CJK UNIFIED IDEOGRAPH
+0x97E8	0x6944	#CJK UNIFIED IDEOGRAPH
+0x97E9	0x6945	#CJK UNIFIED IDEOGRAPH
+0x97EA	0x6946	#CJK UNIFIED IDEOGRAPH
+0x97EB	0x6947	#CJK UNIFIED IDEOGRAPH
+0x97EC	0x6948	#CJK UNIFIED IDEOGRAPH
+0x97ED	0x6949	#CJK UNIFIED IDEOGRAPH
+0x97EE	0x694A	#CJK UNIFIED IDEOGRAPH
+0x97EF	0x694B	#CJK UNIFIED IDEOGRAPH
+0x97F0	0x694C	#CJK UNIFIED IDEOGRAPH
+0x97F1	0x694D	#CJK UNIFIED IDEOGRAPH
+0x97F2	0x694E	#CJK UNIFIED IDEOGRAPH
+0x97F3	0x694F	#CJK UNIFIED IDEOGRAPH
+0x97F4	0x6950	#CJK UNIFIED IDEOGRAPH
+0x97F5	0x6951	#CJK UNIFIED IDEOGRAPH
+0x97F6	0x6952	#CJK UNIFIED IDEOGRAPH
+0x97F7	0x6953	#CJK UNIFIED IDEOGRAPH
+0x97F8	0x6955	#CJK UNIFIED IDEOGRAPH
+0x97F9	0x6956	#CJK UNIFIED IDEOGRAPH
+0x97FA	0x6958	#CJK UNIFIED IDEOGRAPH
+0x97FB	0x6959	#CJK UNIFIED IDEOGRAPH
+0x97FC	0x695B	#CJK UNIFIED IDEOGRAPH
+0x97FD	0x695C	#CJK UNIFIED IDEOGRAPH
+0x97FE	0x695F	#CJK UNIFIED IDEOGRAPH
+0x9840	0x6961	#CJK UNIFIED IDEOGRAPH
+0x9841	0x6962	#CJK UNIFIED IDEOGRAPH
+0x9842	0x6964	#CJK UNIFIED IDEOGRAPH
+0x9843	0x6965	#CJK UNIFIED IDEOGRAPH
+0x9844	0x6967	#CJK UNIFIED IDEOGRAPH
+0x9845	0x6968	#CJK UNIFIED IDEOGRAPH
+0x9846	0x6969	#CJK UNIFIED IDEOGRAPH
+0x9847	0x696A	#CJK UNIFIED IDEOGRAPH
+0x9848	0x696C	#CJK UNIFIED IDEOGRAPH
+0x9849	0x696D	#CJK UNIFIED IDEOGRAPH
+0x984A	0x696F	#CJK UNIFIED IDEOGRAPH
+0x984B	0x6970	#CJK UNIFIED IDEOGRAPH
+0x984C	0x6972	#CJK UNIFIED IDEOGRAPH
+0x984D	0x6973	#CJK UNIFIED IDEOGRAPH
+0x984E	0x6974	#CJK UNIFIED IDEOGRAPH
+0x984F	0x6975	#CJK UNIFIED IDEOGRAPH
+0x9850	0x6976	#CJK UNIFIED IDEOGRAPH
+0x9851	0x697A	#CJK UNIFIED IDEOGRAPH
+0x9852	0x697B	#CJK UNIFIED IDEOGRAPH
+0x9853	0x697D	#CJK UNIFIED IDEOGRAPH
+0x9854	0x697E	#CJK UNIFIED IDEOGRAPH
+0x9855	0x697F	#CJK UNIFIED IDEOGRAPH
+0x9856	0x6981	#CJK UNIFIED IDEOGRAPH
+0x9857	0x6983	#CJK UNIFIED IDEOGRAPH
+0x9858	0x6985	#CJK UNIFIED IDEOGRAPH
+0x9859	0x698A	#CJK UNIFIED IDEOGRAPH
+0x985A	0x698B	#CJK UNIFIED IDEOGRAPH
+0x985B	0x698C	#CJK UNIFIED IDEOGRAPH
+0x985C	0x698E	#CJK UNIFIED IDEOGRAPH
+0x985D	0x698F	#CJK UNIFIED IDEOGRAPH
+0x985E	0x6990	#CJK UNIFIED IDEOGRAPH
+0x985F	0x6991	#CJK UNIFIED IDEOGRAPH
+0x9860	0x6992	#CJK UNIFIED IDEOGRAPH
+0x9861	0x6993	#CJK UNIFIED IDEOGRAPH
+0x9862	0x6996	#CJK UNIFIED IDEOGRAPH
+0x9863	0x6997	#CJK UNIFIED IDEOGRAPH
+0x9864	0x6999	#CJK UNIFIED IDEOGRAPH
+0x9865	0x699A	#CJK UNIFIED IDEOGRAPH
+0x9866	0x699D	#CJK UNIFIED IDEOGRAPH
+0x9867	0x699E	#CJK UNIFIED IDEOGRAPH
+0x9868	0x699F	#CJK UNIFIED IDEOGRAPH
+0x9869	0x69A0	#CJK UNIFIED IDEOGRAPH
+0x986A	0x69A1	#CJK UNIFIED IDEOGRAPH
+0x986B	0x69A2	#CJK UNIFIED IDEOGRAPH
+0x986C	0x69A3	#CJK UNIFIED IDEOGRAPH
+0x986D	0x69A4	#CJK UNIFIED IDEOGRAPH
+0x986E	0x69A5	#CJK UNIFIED IDEOGRAPH
+0x986F	0x69A6	#CJK UNIFIED IDEOGRAPH
+0x9870	0x69A9	#CJK UNIFIED IDEOGRAPH
+0x9871	0x69AA	#CJK UNIFIED IDEOGRAPH
+0x9872	0x69AC	#CJK UNIFIED IDEOGRAPH
+0x9873	0x69AE	#CJK UNIFIED IDEOGRAPH
+0x9874	0x69AF	#CJK UNIFIED IDEOGRAPH
+0x9875	0x69B0	#CJK UNIFIED IDEOGRAPH
+0x9876	0x69B2	#CJK UNIFIED IDEOGRAPH
+0x9877	0x69B3	#CJK UNIFIED IDEOGRAPH
+0x9878	0x69B5	#CJK UNIFIED IDEOGRAPH
+0x9879	0x69B6	#CJK UNIFIED IDEOGRAPH
+0x987A	0x69B8	#CJK UNIFIED IDEOGRAPH
+0x987B	0x69B9	#CJK UNIFIED IDEOGRAPH
+0x987C	0x69BA	#CJK UNIFIED IDEOGRAPH
+0x987D	0x69BC	#CJK UNIFIED IDEOGRAPH
+0x987E	0x69BD	#CJK UNIFIED IDEOGRAPH
+0x9880	0x69BE	#CJK UNIFIED IDEOGRAPH
+0x9881	0x69BF	#CJK UNIFIED IDEOGRAPH
+0x9882	0x69C0	#CJK UNIFIED IDEOGRAPH
+0x9883	0x69C2	#CJK UNIFIED IDEOGRAPH
+0x9884	0x69C3	#CJK UNIFIED IDEOGRAPH
+0x9885	0x69C4	#CJK UNIFIED IDEOGRAPH
+0x9886	0x69C5	#CJK UNIFIED IDEOGRAPH
+0x9887	0x69C6	#CJK UNIFIED IDEOGRAPH
+0x9888	0x69C7	#CJK UNIFIED IDEOGRAPH
+0x9889	0x69C8	#CJK UNIFIED IDEOGRAPH
+0x988A	0x69C9	#CJK UNIFIED IDEOGRAPH
+0x988B	0x69CB	#CJK UNIFIED IDEOGRAPH
+0x988C	0x69CD	#CJK UNIFIED IDEOGRAPH
+0x988D	0x69CF	#CJK UNIFIED IDEOGRAPH
+0x988E	0x69D1	#CJK UNIFIED IDEOGRAPH
+0x988F	0x69D2	#CJK UNIFIED IDEOGRAPH
+0x9890	0x69D3	#CJK UNIFIED IDEOGRAPH
+0x9891	0x69D5	#CJK UNIFIED IDEOGRAPH
+0x9892	0x69D6	#CJK UNIFIED IDEOGRAPH
+0x9893	0x69D7	#CJK UNIFIED IDEOGRAPH
+0x9894	0x69D8	#CJK UNIFIED IDEOGRAPH
+0x9895	0x69D9	#CJK UNIFIED IDEOGRAPH
+0x9896	0x69DA	#CJK UNIFIED IDEOGRAPH
+0x9897	0x69DC	#CJK UNIFIED IDEOGRAPH
+0x9898	0x69DD	#CJK UNIFIED IDEOGRAPH
+0x9899	0x69DE	#CJK UNIFIED IDEOGRAPH
+0x989A	0x69E1	#CJK UNIFIED IDEOGRAPH
+0x989B	0x69E2	#CJK UNIFIED IDEOGRAPH
+0x989C	0x69E3	#CJK UNIFIED IDEOGRAPH
+0x989D	0x69E4	#CJK UNIFIED IDEOGRAPH
+0x989E	0x69E5	#CJK UNIFIED IDEOGRAPH
+0x989F	0x69E6	#CJK UNIFIED IDEOGRAPH
+0x98A0	0x69E7	#CJK UNIFIED IDEOGRAPH
+0x98A1	0x69E8	#CJK UNIFIED IDEOGRAPH
+0x98A2	0x69E9	#CJK UNIFIED IDEOGRAPH
+0x98A3	0x69EA	#CJK UNIFIED IDEOGRAPH
+0x98A4	0x69EB	#CJK UNIFIED IDEOGRAPH
+0x98A5	0x69EC	#CJK UNIFIED IDEOGRAPH
+0x98A6	0x69EE	#CJK UNIFIED IDEOGRAPH
+0x98A7	0x69EF	#CJK UNIFIED IDEOGRAPH
+0x98A8	0x69F0	#CJK UNIFIED IDEOGRAPH
+0x98A9	0x69F1	#CJK UNIFIED IDEOGRAPH
+0x98AA	0x69F3	#CJK UNIFIED IDEOGRAPH
+0x98AB	0x69F4	#CJK UNIFIED IDEOGRAPH
+0x98AC	0x69F5	#CJK UNIFIED IDEOGRAPH
+0x98AD	0x69F6	#CJK UNIFIED IDEOGRAPH
+0x98AE	0x69F7	#CJK UNIFIED IDEOGRAPH
+0x98AF	0x69F8	#CJK UNIFIED IDEOGRAPH
+0x98B0	0x69F9	#CJK UNIFIED IDEOGRAPH
+0x98B1	0x69FA	#CJK UNIFIED IDEOGRAPH
+0x98B2	0x69FB	#CJK UNIFIED IDEOGRAPH
+0x98B3	0x69FC	#CJK UNIFIED IDEOGRAPH
+0x98B4	0x69FE	#CJK UNIFIED IDEOGRAPH
+0x98B5	0x6A00	#CJK UNIFIED IDEOGRAPH
+0x98B6	0x6A01	#CJK UNIFIED IDEOGRAPH
+0x98B7	0x6A02	#CJK UNIFIED IDEOGRAPH
+0x98B8	0x6A03	#CJK UNIFIED IDEOGRAPH
+0x98B9	0x6A04	#CJK UNIFIED IDEOGRAPH
+0x98BA	0x6A05	#CJK UNIFIED IDEOGRAPH
+0x98BB	0x6A06	#CJK UNIFIED IDEOGRAPH
+0x98BC	0x6A07	#CJK UNIFIED IDEOGRAPH
+0x98BD	0x6A08	#CJK UNIFIED IDEOGRAPH
+0x98BE	0x6A09	#CJK UNIFIED IDEOGRAPH
+0x98BF	0x6A0B	#CJK UNIFIED IDEOGRAPH
+0x98C0	0x6A0C	#CJK UNIFIED IDEOGRAPH
+0x98C1	0x6A0D	#CJK UNIFIED IDEOGRAPH
+0x98C2	0x6A0E	#CJK UNIFIED IDEOGRAPH
+0x98C3	0x6A0F	#CJK UNIFIED IDEOGRAPH
+0x98C4	0x6A10	#CJK UNIFIED IDEOGRAPH
+0x98C5	0x6A11	#CJK UNIFIED IDEOGRAPH
+0x98C6	0x6A12	#CJK UNIFIED IDEOGRAPH
+0x98C7	0x6A13	#CJK UNIFIED IDEOGRAPH
+0x98C8	0x6A14	#CJK UNIFIED IDEOGRAPH
+0x98C9	0x6A15	#CJK UNIFIED IDEOGRAPH
+0x98CA	0x6A16	#CJK UNIFIED IDEOGRAPH
+0x98CB	0x6A19	#CJK UNIFIED IDEOGRAPH
+0x98CC	0x6A1A	#CJK UNIFIED IDEOGRAPH
+0x98CD	0x6A1B	#CJK UNIFIED IDEOGRAPH
+0x98CE	0x6A1C	#CJK UNIFIED IDEOGRAPH
+0x98CF	0x6A1D	#CJK UNIFIED IDEOGRAPH
+0x98D0	0x6A1E	#CJK UNIFIED IDEOGRAPH
+0x98D1	0x6A20	#CJK UNIFIED IDEOGRAPH
+0x98D2	0x6A22	#CJK UNIFIED IDEOGRAPH
+0x98D3	0x6A23	#CJK UNIFIED IDEOGRAPH
+0x98D4	0x6A24	#CJK UNIFIED IDEOGRAPH
+0x98D5	0x6A25	#CJK UNIFIED IDEOGRAPH
+0x98D6	0x6A26	#CJK UNIFIED IDEOGRAPH
+0x98D7	0x6A27	#CJK UNIFIED IDEOGRAPH
+0x98D8	0x6A29	#CJK UNIFIED IDEOGRAPH
+0x98D9	0x6A2B	#CJK UNIFIED IDEOGRAPH
+0x98DA	0x6A2C	#CJK UNIFIED IDEOGRAPH
+0x98DB	0x6A2D	#CJK UNIFIED IDEOGRAPH
+0x98DC	0x6A2E	#CJK UNIFIED IDEOGRAPH
+0x98DD	0x6A30	#CJK UNIFIED IDEOGRAPH
+0x98DE	0x6A32	#CJK UNIFIED IDEOGRAPH
+0x98DF	0x6A33	#CJK UNIFIED IDEOGRAPH
+0x98E0	0x6A34	#CJK UNIFIED IDEOGRAPH
+0x98E1	0x6A36	#CJK UNIFIED IDEOGRAPH
+0x98E2	0x6A37	#CJK UNIFIED IDEOGRAPH
+0x98E3	0x6A38	#CJK UNIFIED IDEOGRAPH
+0x98E4	0x6A39	#CJK UNIFIED IDEOGRAPH
+0x98E5	0x6A3A	#CJK UNIFIED IDEOGRAPH
+0x98E6	0x6A3B	#CJK UNIFIED IDEOGRAPH
+0x98E7	0x6A3C	#CJK UNIFIED IDEOGRAPH
+0x98E8	0x6A3F	#CJK UNIFIED IDEOGRAPH
+0x98E9	0x6A40	#CJK UNIFIED IDEOGRAPH
+0x98EA	0x6A41	#CJK UNIFIED IDEOGRAPH
+0x98EB	0x6A42	#CJK UNIFIED IDEOGRAPH
+0x98EC	0x6A43	#CJK UNIFIED IDEOGRAPH
+0x98ED	0x6A45	#CJK UNIFIED IDEOGRAPH
+0x98EE	0x6A46	#CJK UNIFIED IDEOGRAPH
+0x98EF	0x6A48	#CJK UNIFIED IDEOGRAPH
+0x98F0	0x6A49	#CJK UNIFIED IDEOGRAPH
+0x98F1	0x6A4A	#CJK UNIFIED IDEOGRAPH
+0x98F2	0x6A4B	#CJK UNIFIED IDEOGRAPH
+0x98F3	0x6A4C	#CJK UNIFIED IDEOGRAPH
+0x98F4	0x6A4D	#CJK UNIFIED IDEOGRAPH
+0x98F5	0x6A4E	#CJK UNIFIED IDEOGRAPH
+0x98F6	0x6A4F	#CJK UNIFIED IDEOGRAPH
+0x98F7	0x6A51	#CJK UNIFIED IDEOGRAPH
+0x98F8	0x6A52	#CJK UNIFIED IDEOGRAPH
+0x98F9	0x6A53	#CJK UNIFIED IDEOGRAPH
+0x98FA	0x6A54	#CJK UNIFIED IDEOGRAPH
+0x98FB	0x6A55	#CJK UNIFIED IDEOGRAPH
+0x98FC	0x6A56	#CJK UNIFIED IDEOGRAPH
+0x98FD	0x6A57	#CJK UNIFIED IDEOGRAPH
+0x98FE	0x6A5A	#CJK UNIFIED IDEOGRAPH
+0x9940	0x6A5C	#CJK UNIFIED IDEOGRAPH
+0x9941	0x6A5D	#CJK UNIFIED IDEOGRAPH
+0x9942	0x6A5E	#CJK UNIFIED IDEOGRAPH
+0x9943	0x6A5F	#CJK UNIFIED IDEOGRAPH
+0x9944	0x6A60	#CJK UNIFIED IDEOGRAPH
+0x9945	0x6A62	#CJK UNIFIED IDEOGRAPH
+0x9946	0x6A63	#CJK UNIFIED IDEOGRAPH
+0x9947	0x6A64	#CJK UNIFIED IDEOGRAPH
+0x9948	0x6A66	#CJK UNIFIED IDEOGRAPH
+0x9949	0x6A67	#CJK UNIFIED IDEOGRAPH
+0x994A	0x6A68	#CJK UNIFIED IDEOGRAPH
+0x994B	0x6A69	#CJK UNIFIED IDEOGRAPH
+0x994C	0x6A6A	#CJK UNIFIED IDEOGRAPH
+0x994D	0x6A6B	#CJK UNIFIED IDEOGRAPH
+0x994E	0x6A6C	#CJK UNIFIED IDEOGRAPH
+0x994F	0x6A6D	#CJK UNIFIED IDEOGRAPH
+0x9950	0x6A6E	#CJK UNIFIED IDEOGRAPH
+0x9951	0x6A6F	#CJK UNIFIED IDEOGRAPH
+0x9952	0x6A70	#CJK UNIFIED IDEOGRAPH
+0x9953	0x6A72	#CJK UNIFIED IDEOGRAPH
+0x9954	0x6A73	#CJK UNIFIED IDEOGRAPH
+0x9955	0x6A74	#CJK UNIFIED IDEOGRAPH
+0x9956	0x6A75	#CJK UNIFIED IDEOGRAPH
+0x9957	0x6A76	#CJK UNIFIED IDEOGRAPH
+0x9958	0x6A77	#CJK UNIFIED IDEOGRAPH
+0x9959	0x6A78	#CJK UNIFIED IDEOGRAPH
+0x995A	0x6A7A	#CJK UNIFIED IDEOGRAPH
+0x995B	0x6A7B	#CJK UNIFIED IDEOGRAPH
+0x995C	0x6A7D	#CJK UNIFIED IDEOGRAPH
+0x995D	0x6A7E	#CJK UNIFIED IDEOGRAPH
+0x995E	0x6A7F	#CJK UNIFIED IDEOGRAPH
+0x995F	0x6A81	#CJK UNIFIED IDEOGRAPH
+0x9960	0x6A82	#CJK UNIFIED IDEOGRAPH
+0x9961	0x6A83	#CJK UNIFIED IDEOGRAPH
+0x9962	0x6A85	#CJK UNIFIED IDEOGRAPH
+0x9963	0x6A86	#CJK UNIFIED IDEOGRAPH
+0x9964	0x6A87	#CJK UNIFIED IDEOGRAPH
+0x9965	0x6A88	#CJK UNIFIED IDEOGRAPH
+0x9966	0x6A89	#CJK UNIFIED IDEOGRAPH
+0x9967	0x6A8A	#CJK UNIFIED IDEOGRAPH
+0x9968	0x6A8B	#CJK UNIFIED IDEOGRAPH
+0x9969	0x6A8C	#CJK UNIFIED IDEOGRAPH
+0x996A	0x6A8D	#CJK UNIFIED IDEOGRAPH
+0x996B	0x6A8F	#CJK UNIFIED IDEOGRAPH
+0x996C	0x6A92	#CJK UNIFIED IDEOGRAPH
+0x996D	0x6A93	#CJK UNIFIED IDEOGRAPH
+0x996E	0x6A94	#CJK UNIFIED IDEOGRAPH
+0x996F	0x6A95	#CJK UNIFIED IDEOGRAPH
+0x9970	0x6A96	#CJK UNIFIED IDEOGRAPH
+0x9971	0x6A98	#CJK UNIFIED IDEOGRAPH
+0x9972	0x6A99	#CJK UNIFIED IDEOGRAPH
+0x9973	0x6A9A	#CJK UNIFIED IDEOGRAPH
+0x9974	0x6A9B	#CJK UNIFIED IDEOGRAPH
+0x9975	0x6A9C	#CJK UNIFIED IDEOGRAPH
+0x9976	0x6A9D	#CJK UNIFIED IDEOGRAPH
+0x9977	0x6A9E	#CJK UNIFIED IDEOGRAPH
+0x9978	0x6A9F	#CJK UNIFIED IDEOGRAPH
+0x9979	0x6AA1	#CJK UNIFIED IDEOGRAPH
+0x997A	0x6AA2	#CJK UNIFIED IDEOGRAPH
+0x997B	0x6AA3	#CJK UNIFIED IDEOGRAPH
+0x997C	0x6AA4	#CJK UNIFIED IDEOGRAPH
+0x997D	0x6AA5	#CJK UNIFIED IDEOGRAPH
+0x997E	0x6AA6	#CJK UNIFIED IDEOGRAPH
+0x9980	0x6AA7	#CJK UNIFIED IDEOGRAPH
+0x9981	0x6AA8	#CJK UNIFIED IDEOGRAPH
+0x9982	0x6AAA	#CJK UNIFIED IDEOGRAPH
+0x9983	0x6AAD	#CJK UNIFIED IDEOGRAPH
+0x9984	0x6AAE	#CJK UNIFIED IDEOGRAPH
+0x9985	0x6AAF	#CJK UNIFIED IDEOGRAPH
+0x9986	0x6AB0	#CJK UNIFIED IDEOGRAPH
+0x9987	0x6AB1	#CJK UNIFIED IDEOGRAPH
+0x9988	0x6AB2	#CJK UNIFIED IDEOGRAPH
+0x9989	0x6AB3	#CJK UNIFIED IDEOGRAPH
+0x998A	0x6AB4	#CJK UNIFIED IDEOGRAPH
+0x998B	0x6AB5	#CJK UNIFIED IDEOGRAPH
+0x998C	0x6AB6	#CJK UNIFIED IDEOGRAPH
+0x998D	0x6AB7	#CJK UNIFIED IDEOGRAPH
+0x998E	0x6AB8	#CJK UNIFIED IDEOGRAPH
+0x998F	0x6AB9	#CJK UNIFIED IDEOGRAPH
+0x9990	0x6ABA	#CJK UNIFIED IDEOGRAPH
+0x9991	0x6ABB	#CJK UNIFIED IDEOGRAPH
+0x9992	0x6ABC	#CJK UNIFIED IDEOGRAPH
+0x9993	0x6ABD	#CJK UNIFIED IDEOGRAPH
+0x9994	0x6ABE	#CJK UNIFIED IDEOGRAPH
+0x9995	0x6ABF	#CJK UNIFIED IDEOGRAPH
+0x9996	0x6AC0	#CJK UNIFIED IDEOGRAPH
+0x9997	0x6AC1	#CJK UNIFIED IDEOGRAPH
+0x9998	0x6AC2	#CJK UNIFIED IDEOGRAPH
+0x9999	0x6AC3	#CJK UNIFIED IDEOGRAPH
+0x999A	0x6AC4	#CJK UNIFIED IDEOGRAPH
+0x999B	0x6AC5	#CJK UNIFIED IDEOGRAPH
+0x999C	0x6AC6	#CJK UNIFIED IDEOGRAPH
+0x999D	0x6AC7	#CJK UNIFIED IDEOGRAPH
+0x999E	0x6AC8	#CJK UNIFIED IDEOGRAPH
+0x999F	0x6AC9	#CJK UNIFIED IDEOGRAPH
+0x99A0	0x6ACA	#CJK UNIFIED IDEOGRAPH
+0x99A1	0x6ACB	#CJK UNIFIED IDEOGRAPH
+0x99A2	0x6ACC	#CJK UNIFIED IDEOGRAPH
+0x99A3	0x6ACD	#CJK UNIFIED IDEOGRAPH
+0x99A4	0x6ACE	#CJK UNIFIED IDEOGRAPH
+0x99A5	0x6ACF	#CJK UNIFIED IDEOGRAPH
+0x99A6	0x6AD0	#CJK UNIFIED IDEOGRAPH
+0x99A7	0x6AD1	#CJK UNIFIED IDEOGRAPH
+0x99A8	0x6AD2	#CJK UNIFIED IDEOGRAPH
+0x99A9	0x6AD3	#CJK UNIFIED IDEOGRAPH
+0x99AA	0x6AD4	#CJK UNIFIED IDEOGRAPH
+0x99AB	0x6AD5	#CJK UNIFIED IDEOGRAPH
+0x99AC	0x6AD6	#CJK UNIFIED IDEOGRAPH
+0x99AD	0x6AD7	#CJK UNIFIED IDEOGRAPH
+0x99AE	0x6AD8	#CJK UNIFIED IDEOGRAPH
+0x99AF	0x6AD9	#CJK UNIFIED IDEOGRAPH
+0x99B0	0x6ADA	#CJK UNIFIED IDEOGRAPH
+0x99B1	0x6ADB	#CJK UNIFIED IDEOGRAPH
+0x99B2	0x6ADC	#CJK UNIFIED IDEOGRAPH
+0x99B3	0x6ADD	#CJK UNIFIED IDEOGRAPH
+0x99B4	0x6ADE	#CJK UNIFIED IDEOGRAPH
+0x99B5	0x6ADF	#CJK UNIFIED IDEOGRAPH
+0x99B6	0x6AE0	#CJK UNIFIED IDEOGRAPH
+0x99B7	0x6AE1	#CJK UNIFIED IDEOGRAPH
+0x99B8	0x6AE2	#CJK UNIFIED IDEOGRAPH
+0x99B9	0x6AE3	#CJK UNIFIED IDEOGRAPH
+0x99BA	0x6AE4	#CJK UNIFIED IDEOGRAPH
+0x99BB	0x6AE5	#CJK UNIFIED IDEOGRAPH
+0x99BC	0x6AE6	#CJK UNIFIED IDEOGRAPH
+0x99BD	0x6AE7	#CJK UNIFIED IDEOGRAPH
+0x99BE	0x6AE8	#CJK UNIFIED IDEOGRAPH
+0x99BF	0x6AE9	#CJK UNIFIED IDEOGRAPH
+0x99C0	0x6AEA	#CJK UNIFIED IDEOGRAPH
+0x99C1	0x6AEB	#CJK UNIFIED IDEOGRAPH
+0x99C2	0x6AEC	#CJK UNIFIED IDEOGRAPH
+0x99C3	0x6AED	#CJK UNIFIED IDEOGRAPH
+0x99C4	0x6AEE	#CJK UNIFIED IDEOGRAPH
+0x99C5	0x6AEF	#CJK UNIFIED IDEOGRAPH
+0x99C6	0x6AF0	#CJK UNIFIED IDEOGRAPH
+0x99C7	0x6AF1	#CJK UNIFIED IDEOGRAPH
+0x99C8	0x6AF2	#CJK UNIFIED IDEOGRAPH
+0x99C9	0x6AF3	#CJK UNIFIED IDEOGRAPH
+0x99CA	0x6AF4	#CJK UNIFIED IDEOGRAPH
+0x99CB	0x6AF5	#CJK UNIFIED IDEOGRAPH
+0x99CC	0x6AF6	#CJK UNIFIED IDEOGRAPH
+0x99CD	0x6AF7	#CJK UNIFIED IDEOGRAPH
+0x99CE	0x6AF8	#CJK UNIFIED IDEOGRAPH
+0x99CF	0x6AF9	#CJK UNIFIED IDEOGRAPH
+0x99D0	0x6AFA	#CJK UNIFIED IDEOGRAPH
+0x99D1	0x6AFB	#CJK UNIFIED IDEOGRAPH
+0x99D2	0x6AFC	#CJK UNIFIED IDEOGRAPH
+0x99D3	0x6AFD	#CJK UNIFIED IDEOGRAPH
+0x99D4	0x6AFE	#CJK UNIFIED IDEOGRAPH
+0x99D5	0x6AFF	#CJK UNIFIED IDEOGRAPH
+0x99D6	0x6B00	#CJK UNIFIED IDEOGRAPH
+0x99D7	0x6B01	#CJK UNIFIED IDEOGRAPH
+0x99D8	0x6B02	#CJK UNIFIED IDEOGRAPH
+0x99D9	0x6B03	#CJK UNIFIED IDEOGRAPH
+0x99DA	0x6B04	#CJK UNIFIED IDEOGRAPH
+0x99DB	0x6B05	#CJK UNIFIED IDEOGRAPH
+0x99DC	0x6B06	#CJK UNIFIED IDEOGRAPH
+0x99DD	0x6B07	#CJK UNIFIED IDEOGRAPH
+0x99DE	0x6B08	#CJK UNIFIED IDEOGRAPH
+0x99DF	0x6B09	#CJK UNIFIED IDEOGRAPH
+0x99E0	0x6B0A	#CJK UNIFIED IDEOGRAPH
+0x99E1	0x6B0B	#CJK UNIFIED IDEOGRAPH
+0x99E2	0x6B0C	#CJK UNIFIED IDEOGRAPH
+0x99E3	0x6B0D	#CJK UNIFIED IDEOGRAPH
+0x99E4	0x6B0E	#CJK UNIFIED IDEOGRAPH
+0x99E5	0x6B0F	#CJK UNIFIED IDEOGRAPH
+0x99E6	0x6B10	#CJK UNIFIED IDEOGRAPH
+0x99E7	0x6B11	#CJK UNIFIED IDEOGRAPH
+0x99E8	0x6B12	#CJK UNIFIED IDEOGRAPH
+0x99E9	0x6B13	#CJK UNIFIED IDEOGRAPH
+0x99EA	0x6B14	#CJK UNIFIED IDEOGRAPH
+0x99EB	0x6B15	#CJK UNIFIED IDEOGRAPH
+0x99EC	0x6B16	#CJK UNIFIED IDEOGRAPH
+0x99ED	0x6B17	#CJK UNIFIED IDEOGRAPH
+0x99EE	0x6B18	#CJK UNIFIED IDEOGRAPH
+0x99EF	0x6B19	#CJK UNIFIED IDEOGRAPH
+0x99F0	0x6B1A	#CJK UNIFIED IDEOGRAPH
+0x99F1	0x6B1B	#CJK UNIFIED IDEOGRAPH
+0x99F2	0x6B1C	#CJK UNIFIED IDEOGRAPH
+0x99F3	0x6B1D	#CJK UNIFIED IDEOGRAPH
+0x99F4	0x6B1E	#CJK UNIFIED IDEOGRAPH
+0x99F5	0x6B1F	#CJK UNIFIED IDEOGRAPH
+0x99F6	0x6B25	#CJK UNIFIED IDEOGRAPH
+0x99F7	0x6B26	#CJK UNIFIED IDEOGRAPH
+0x99F8	0x6B28	#CJK UNIFIED IDEOGRAPH
+0x99F9	0x6B29	#CJK UNIFIED IDEOGRAPH
+0x99FA	0x6B2A	#CJK UNIFIED IDEOGRAPH
+0x99FB	0x6B2B	#CJK UNIFIED IDEOGRAPH
+0x99FC	0x6B2C	#CJK UNIFIED IDEOGRAPH
+0x99FD	0x6B2D	#CJK UNIFIED IDEOGRAPH
+0x99FE	0x6B2E	#CJK UNIFIED IDEOGRAPH
+0x9A40	0x6B2F	#CJK UNIFIED IDEOGRAPH
+0x9A41	0x6B30	#CJK UNIFIED IDEOGRAPH
+0x9A42	0x6B31	#CJK UNIFIED IDEOGRAPH
+0x9A43	0x6B33	#CJK UNIFIED IDEOGRAPH
+0x9A44	0x6B34	#CJK UNIFIED IDEOGRAPH
+0x9A45	0x6B35	#CJK UNIFIED IDEOGRAPH
+0x9A46	0x6B36	#CJK UNIFIED IDEOGRAPH
+0x9A47	0x6B38	#CJK UNIFIED IDEOGRAPH
+0x9A48	0x6B3B	#CJK UNIFIED IDEOGRAPH
+0x9A49	0x6B3C	#CJK UNIFIED IDEOGRAPH
+0x9A4A	0x6B3D	#CJK UNIFIED IDEOGRAPH
+0x9A4B	0x6B3F	#CJK UNIFIED IDEOGRAPH
+0x9A4C	0x6B40	#CJK UNIFIED IDEOGRAPH
+0x9A4D	0x6B41	#CJK UNIFIED IDEOGRAPH
+0x9A4E	0x6B42	#CJK UNIFIED IDEOGRAPH
+0x9A4F	0x6B44	#CJK UNIFIED IDEOGRAPH
+0x9A50	0x6B45	#CJK UNIFIED IDEOGRAPH
+0x9A51	0x6B48	#CJK UNIFIED IDEOGRAPH
+0x9A52	0x6B4A	#CJK UNIFIED IDEOGRAPH
+0x9A53	0x6B4B	#CJK UNIFIED IDEOGRAPH
+0x9A54	0x6B4D	#CJK UNIFIED IDEOGRAPH
+0x9A55	0x6B4E	#CJK UNIFIED IDEOGRAPH
+0x9A56	0x6B4F	#CJK UNIFIED IDEOGRAPH
+0x9A57	0x6B50	#CJK UNIFIED IDEOGRAPH
+0x9A58	0x6B51	#CJK UNIFIED IDEOGRAPH
+0x9A59	0x6B52	#CJK UNIFIED IDEOGRAPH
+0x9A5A	0x6B53	#CJK UNIFIED IDEOGRAPH
+0x9A5B	0x6B54	#CJK UNIFIED IDEOGRAPH
+0x9A5C	0x6B55	#CJK UNIFIED IDEOGRAPH
+0x9A5D	0x6B56	#CJK UNIFIED IDEOGRAPH
+0x9A5E	0x6B57	#CJK UNIFIED IDEOGRAPH
+0x9A5F	0x6B58	#CJK UNIFIED IDEOGRAPH
+0x9A60	0x6B5A	#CJK UNIFIED IDEOGRAPH
+0x9A61	0x6B5B	#CJK UNIFIED IDEOGRAPH
+0x9A62	0x6B5C	#CJK UNIFIED IDEOGRAPH
+0x9A63	0x6B5D	#CJK UNIFIED IDEOGRAPH
+0x9A64	0x6B5E	#CJK UNIFIED IDEOGRAPH
+0x9A65	0x6B5F	#CJK UNIFIED IDEOGRAPH
+0x9A66	0x6B60	#CJK UNIFIED IDEOGRAPH
+0x9A67	0x6B61	#CJK UNIFIED IDEOGRAPH
+0x9A68	0x6B68	#CJK UNIFIED IDEOGRAPH
+0x9A69	0x6B69	#CJK UNIFIED IDEOGRAPH
+0x9A6A	0x6B6B	#CJK UNIFIED IDEOGRAPH
+0x9A6B	0x6B6C	#CJK UNIFIED IDEOGRAPH
+0x9A6C	0x6B6D	#CJK UNIFIED IDEOGRAPH
+0x9A6D	0x6B6E	#CJK UNIFIED IDEOGRAPH
+0x9A6E	0x6B6F	#CJK UNIFIED IDEOGRAPH
+0x9A6F	0x6B70	#CJK UNIFIED IDEOGRAPH
+0x9A70	0x6B71	#CJK UNIFIED IDEOGRAPH
+0x9A71	0x6B72	#CJK UNIFIED IDEOGRAPH
+0x9A72	0x6B73	#CJK UNIFIED IDEOGRAPH
+0x9A73	0x6B74	#CJK UNIFIED IDEOGRAPH
+0x9A74	0x6B75	#CJK UNIFIED IDEOGRAPH
+0x9A75	0x6B76	#CJK UNIFIED IDEOGRAPH
+0x9A76	0x6B77	#CJK UNIFIED IDEOGRAPH
+0x9A77	0x6B78	#CJK UNIFIED IDEOGRAPH
+0x9A78	0x6B7A	#CJK UNIFIED IDEOGRAPH
+0x9A79	0x6B7D	#CJK UNIFIED IDEOGRAPH
+0x9A7A	0x6B7E	#CJK UNIFIED IDEOGRAPH
+0x9A7B	0x6B7F	#CJK UNIFIED IDEOGRAPH
+0x9A7C	0x6B80	#CJK UNIFIED IDEOGRAPH
+0x9A7D	0x6B85	#CJK UNIFIED IDEOGRAPH
+0x9A7E	0x6B88	#CJK UNIFIED IDEOGRAPH
+0x9A80	0x6B8C	#CJK UNIFIED IDEOGRAPH
+0x9A81	0x6B8E	#CJK UNIFIED IDEOGRAPH
+0x9A82	0x6B8F	#CJK UNIFIED IDEOGRAPH
+0x9A83	0x6B90	#CJK UNIFIED IDEOGRAPH
+0x9A84	0x6B91	#CJK UNIFIED IDEOGRAPH
+0x9A85	0x6B94	#CJK UNIFIED IDEOGRAPH
+0x9A86	0x6B95	#CJK UNIFIED IDEOGRAPH
+0x9A87	0x6B97	#CJK UNIFIED IDEOGRAPH
+0x9A88	0x6B98	#CJK UNIFIED IDEOGRAPH
+0x9A89	0x6B99	#CJK UNIFIED IDEOGRAPH
+0x9A8A	0x6B9C	#CJK UNIFIED IDEOGRAPH
+0x9A8B	0x6B9D	#CJK UNIFIED IDEOGRAPH
+0x9A8C	0x6B9E	#CJK UNIFIED IDEOGRAPH
+0x9A8D	0x6B9F	#CJK UNIFIED IDEOGRAPH
+0x9A8E	0x6BA0	#CJK UNIFIED IDEOGRAPH
+0x9A8F	0x6BA2	#CJK UNIFIED IDEOGRAPH
+0x9A90	0x6BA3	#CJK UNIFIED IDEOGRAPH
+0x9A91	0x6BA4	#CJK UNIFIED IDEOGRAPH
+0x9A92	0x6BA5	#CJK UNIFIED IDEOGRAPH
+0x9A93	0x6BA6	#CJK UNIFIED IDEOGRAPH
+0x9A94	0x6BA7	#CJK UNIFIED IDEOGRAPH
+0x9A95	0x6BA8	#CJK UNIFIED IDEOGRAPH
+0x9A96	0x6BA9	#CJK UNIFIED IDEOGRAPH
+0x9A97	0x6BAB	#CJK UNIFIED IDEOGRAPH
+0x9A98	0x6BAC	#CJK UNIFIED IDEOGRAPH
+0x9A99	0x6BAD	#CJK UNIFIED IDEOGRAPH
+0x9A9A	0x6BAE	#CJK UNIFIED IDEOGRAPH
+0x9A9B	0x6BAF	#CJK UNIFIED IDEOGRAPH
+0x9A9C	0x6BB0	#CJK UNIFIED IDEOGRAPH
+0x9A9D	0x6BB1	#CJK UNIFIED IDEOGRAPH
+0x9A9E	0x6BB2	#CJK UNIFIED IDEOGRAPH
+0x9A9F	0x6BB6	#CJK UNIFIED IDEOGRAPH
+0x9AA0	0x6BB8	#CJK UNIFIED IDEOGRAPH
+0x9AA1	0x6BB9	#CJK UNIFIED IDEOGRAPH
+0x9AA2	0x6BBA	#CJK UNIFIED IDEOGRAPH
+0x9AA3	0x6BBB	#CJK UNIFIED IDEOGRAPH
+0x9AA4	0x6BBC	#CJK UNIFIED IDEOGRAPH
+0x9AA5	0x6BBD	#CJK UNIFIED IDEOGRAPH
+0x9AA6	0x6BBE	#CJK UNIFIED IDEOGRAPH
+0x9AA7	0x6BC0	#CJK UNIFIED IDEOGRAPH
+0x9AA8	0x6BC3	#CJK UNIFIED IDEOGRAPH
+0x9AA9	0x6BC4	#CJK UNIFIED IDEOGRAPH
+0x9AAA	0x6BC6	#CJK UNIFIED IDEOGRAPH
+0x9AAB	0x6BC7	#CJK UNIFIED IDEOGRAPH
+0x9AAC	0x6BC8	#CJK UNIFIED IDEOGRAPH
+0x9AAD	0x6BC9	#CJK UNIFIED IDEOGRAPH
+0x9AAE	0x6BCA	#CJK UNIFIED IDEOGRAPH
+0x9AAF	0x6BCC	#CJK UNIFIED IDEOGRAPH
+0x9AB0	0x6BCE	#CJK UNIFIED IDEOGRAPH
+0x9AB1	0x6BD0	#CJK UNIFIED IDEOGRAPH
+0x9AB2	0x6BD1	#CJK UNIFIED IDEOGRAPH
+0x9AB3	0x6BD8	#CJK UNIFIED IDEOGRAPH
+0x9AB4	0x6BDA	#CJK UNIFIED IDEOGRAPH
+0x9AB5	0x6BDC	#CJK UNIFIED IDEOGRAPH
+0x9AB6	0x6BDD	#CJK UNIFIED IDEOGRAPH
+0x9AB7	0x6BDE	#CJK UNIFIED IDEOGRAPH
+0x9AB8	0x6BDF	#CJK UNIFIED IDEOGRAPH
+0x9AB9	0x6BE0	#CJK UNIFIED IDEOGRAPH
+0x9ABA	0x6BE2	#CJK UNIFIED IDEOGRAPH
+0x9ABB	0x6BE3	#CJK UNIFIED IDEOGRAPH
+0x9ABC	0x6BE4	#CJK UNIFIED IDEOGRAPH
+0x9ABD	0x6BE5	#CJK UNIFIED IDEOGRAPH
+0x9ABE	0x6BE6	#CJK UNIFIED IDEOGRAPH
+0x9ABF	0x6BE7	#CJK UNIFIED IDEOGRAPH
+0x9AC0	0x6BE8	#CJK UNIFIED IDEOGRAPH
+0x9AC1	0x6BE9	#CJK UNIFIED IDEOGRAPH
+0x9AC2	0x6BEC	#CJK UNIFIED IDEOGRAPH
+0x9AC3	0x6BED	#CJK UNIFIED IDEOGRAPH
+0x9AC4	0x6BEE	#CJK UNIFIED IDEOGRAPH
+0x9AC5	0x6BF0	#CJK UNIFIED IDEOGRAPH
+0x9AC6	0x6BF1	#CJK UNIFIED IDEOGRAPH
+0x9AC7	0x6BF2	#CJK UNIFIED IDEOGRAPH
+0x9AC8	0x6BF4	#CJK UNIFIED IDEOGRAPH
+0x9AC9	0x6BF6	#CJK UNIFIED IDEOGRAPH
+0x9ACA	0x6BF7	#CJK UNIFIED IDEOGRAPH
+0x9ACB	0x6BF8	#CJK UNIFIED IDEOGRAPH
+0x9ACC	0x6BFA	#CJK UNIFIED IDEOGRAPH
+0x9ACD	0x6BFB	#CJK UNIFIED IDEOGRAPH
+0x9ACE	0x6BFC	#CJK UNIFIED IDEOGRAPH
+0x9ACF	0x6BFE	#CJK UNIFIED IDEOGRAPH
+0x9AD0	0x6BFF	#CJK UNIFIED IDEOGRAPH
+0x9AD1	0x6C00	#CJK UNIFIED IDEOGRAPH
+0x9AD2	0x6C01	#CJK UNIFIED IDEOGRAPH
+0x9AD3	0x6C02	#CJK UNIFIED IDEOGRAPH
+0x9AD4	0x6C03	#CJK UNIFIED IDEOGRAPH
+0x9AD5	0x6C04	#CJK UNIFIED IDEOGRAPH
+0x9AD6	0x6C08	#CJK UNIFIED IDEOGRAPH
+0x9AD7	0x6C09	#CJK UNIFIED IDEOGRAPH
+0x9AD8	0x6C0A	#CJK UNIFIED IDEOGRAPH
+0x9AD9	0x6C0B	#CJK UNIFIED IDEOGRAPH
+0x9ADA	0x6C0C	#CJK UNIFIED IDEOGRAPH
+0x9ADB	0x6C0E	#CJK UNIFIED IDEOGRAPH
+0x9ADC	0x6C12	#CJK UNIFIED IDEOGRAPH
+0x9ADD	0x6C17	#CJK UNIFIED IDEOGRAPH
+0x9ADE	0x6C1C	#CJK UNIFIED IDEOGRAPH
+0x9ADF	0x6C1D	#CJK UNIFIED IDEOGRAPH
+0x9AE0	0x6C1E	#CJK UNIFIED IDEOGRAPH
+0x9AE1	0x6C20	#CJK UNIFIED IDEOGRAPH
+0x9AE2	0x6C23	#CJK UNIFIED IDEOGRAPH
+0x9AE3	0x6C25	#CJK UNIFIED IDEOGRAPH
+0x9AE4	0x6C2B	#CJK UNIFIED IDEOGRAPH
+0x9AE5	0x6C2C	#CJK UNIFIED IDEOGRAPH
+0x9AE6	0x6C2D	#CJK UNIFIED IDEOGRAPH
+0x9AE7	0x6C31	#CJK UNIFIED IDEOGRAPH
+0x9AE8	0x6C33	#CJK UNIFIED IDEOGRAPH
+0x9AE9	0x6C36	#CJK UNIFIED IDEOGRAPH
+0x9AEA	0x6C37	#CJK UNIFIED IDEOGRAPH
+0x9AEB	0x6C39	#CJK UNIFIED IDEOGRAPH
+0x9AEC	0x6C3A	#CJK UNIFIED IDEOGRAPH
+0x9AED	0x6C3B	#CJK UNIFIED IDEOGRAPH
+0x9AEE	0x6C3C	#CJK UNIFIED IDEOGRAPH
+0x9AEF	0x6C3E	#CJK UNIFIED IDEOGRAPH
+0x9AF0	0x6C3F	#CJK UNIFIED IDEOGRAPH
+0x9AF1	0x6C43	#CJK UNIFIED IDEOGRAPH
+0x9AF2	0x6C44	#CJK UNIFIED IDEOGRAPH
+0x9AF3	0x6C45	#CJK UNIFIED IDEOGRAPH
+0x9AF4	0x6C48	#CJK UNIFIED IDEOGRAPH
+0x9AF5	0x6C4B	#CJK UNIFIED IDEOGRAPH
+0x9AF6	0x6C4C	#CJK UNIFIED IDEOGRAPH
+0x9AF7	0x6C4D	#CJK UNIFIED IDEOGRAPH
+0x9AF8	0x6C4E	#CJK UNIFIED IDEOGRAPH
+0x9AF9	0x6C4F	#CJK UNIFIED IDEOGRAPH
+0x9AFA	0x6C51	#CJK UNIFIED IDEOGRAPH
+0x9AFB	0x6C52	#CJK UNIFIED IDEOGRAPH
+0x9AFC	0x6C53	#CJK UNIFIED IDEOGRAPH
+0x9AFD	0x6C56	#CJK UNIFIED IDEOGRAPH
+0x9AFE	0x6C58	#CJK UNIFIED IDEOGRAPH
+0x9B40	0x6C59	#CJK UNIFIED IDEOGRAPH
+0x9B41	0x6C5A	#CJK UNIFIED IDEOGRAPH
+0x9B42	0x6C62	#CJK UNIFIED IDEOGRAPH
+0x9B43	0x6C63	#CJK UNIFIED IDEOGRAPH
+0x9B44	0x6C65	#CJK UNIFIED IDEOGRAPH
+0x9B45	0x6C66	#CJK UNIFIED IDEOGRAPH
+0x9B46	0x6C67	#CJK UNIFIED IDEOGRAPH
+0x9B47	0x6C6B	#CJK UNIFIED IDEOGRAPH
+0x9B48	0x6C6C	#CJK UNIFIED IDEOGRAPH
+0x9B49	0x6C6D	#CJK UNIFIED IDEOGRAPH
+0x9B4A	0x6C6E	#CJK UNIFIED IDEOGRAPH
+0x9B4B	0x6C6F	#CJK UNIFIED IDEOGRAPH
+0x9B4C	0x6C71	#CJK UNIFIED IDEOGRAPH
+0x9B4D	0x6C73	#CJK UNIFIED IDEOGRAPH
+0x9B4E	0x6C75	#CJK UNIFIED IDEOGRAPH
+0x9B4F	0x6C77	#CJK UNIFIED IDEOGRAPH
+0x9B50	0x6C78	#CJK UNIFIED IDEOGRAPH
+0x9B51	0x6C7A	#CJK UNIFIED IDEOGRAPH
+0x9B52	0x6C7B	#CJK UNIFIED IDEOGRAPH
+0x9B53	0x6C7C	#CJK UNIFIED IDEOGRAPH
+0x9B54	0x6C7F	#CJK UNIFIED IDEOGRAPH
+0x9B55	0x6C80	#CJK UNIFIED IDEOGRAPH
+0x9B56	0x6C84	#CJK UNIFIED IDEOGRAPH
+0x9B57	0x6C87	#CJK UNIFIED IDEOGRAPH
+0x9B58	0x6C8A	#CJK UNIFIED IDEOGRAPH
+0x9B59	0x6C8B	#CJK UNIFIED IDEOGRAPH
+0x9B5A	0x6C8D	#CJK UNIFIED IDEOGRAPH
+0x9B5B	0x6C8E	#CJK UNIFIED IDEOGRAPH
+0x9B5C	0x6C91	#CJK UNIFIED IDEOGRAPH
+0x9B5D	0x6C92	#CJK UNIFIED IDEOGRAPH
+0x9B5E	0x6C95	#CJK UNIFIED IDEOGRAPH
+0x9B5F	0x6C96	#CJK UNIFIED IDEOGRAPH
+0x9B60	0x6C97	#CJK UNIFIED IDEOGRAPH
+0x9B61	0x6C98	#CJK UNIFIED IDEOGRAPH
+0x9B62	0x6C9A	#CJK UNIFIED IDEOGRAPH
+0x9B63	0x6C9C	#CJK UNIFIED IDEOGRAPH
+0x9B64	0x6C9D	#CJK UNIFIED IDEOGRAPH
+0x9B65	0x6C9E	#CJK UNIFIED IDEOGRAPH
+0x9B66	0x6CA0	#CJK UNIFIED IDEOGRAPH
+0x9B67	0x6CA2	#CJK UNIFIED IDEOGRAPH
+0x9B68	0x6CA8	#CJK UNIFIED IDEOGRAPH
+0x9B69	0x6CAC	#CJK UNIFIED IDEOGRAPH
+0x9B6A	0x6CAF	#CJK UNIFIED IDEOGRAPH
+0x9B6B	0x6CB0	#CJK UNIFIED IDEOGRAPH
+0x9B6C	0x6CB4	#CJK UNIFIED IDEOGRAPH
+0x9B6D	0x6CB5	#CJK UNIFIED IDEOGRAPH
+0x9B6E	0x6CB6	#CJK UNIFIED IDEOGRAPH
+0x9B6F	0x6CB7	#CJK UNIFIED IDEOGRAPH
+0x9B70	0x6CBA	#CJK UNIFIED IDEOGRAPH
+0x9B71	0x6CC0	#CJK UNIFIED IDEOGRAPH
+0x9B72	0x6CC1	#CJK UNIFIED IDEOGRAPH
+0x9B73	0x6CC2	#CJK UNIFIED IDEOGRAPH
+0x9B74	0x6CC3	#CJK UNIFIED IDEOGRAPH
+0x9B75	0x6CC6	#CJK UNIFIED IDEOGRAPH
+0x9B76	0x6CC7	#CJK UNIFIED IDEOGRAPH
+0x9B77	0x6CC8	#CJK UNIFIED IDEOGRAPH
+0x9B78	0x6CCB	#CJK UNIFIED IDEOGRAPH
+0x9B79	0x6CCD	#CJK UNIFIED IDEOGRAPH
+0x9B7A	0x6CCE	#CJK UNIFIED IDEOGRAPH
+0x9B7B	0x6CCF	#CJK UNIFIED IDEOGRAPH
+0x9B7C	0x6CD1	#CJK UNIFIED IDEOGRAPH
+0x9B7D	0x6CD2	#CJK UNIFIED IDEOGRAPH
+0x9B7E	0x6CD8	#CJK UNIFIED IDEOGRAPH
+0x9B80	0x6CD9	#CJK UNIFIED IDEOGRAPH
+0x9B81	0x6CDA	#CJK UNIFIED IDEOGRAPH
+0x9B82	0x6CDC	#CJK UNIFIED IDEOGRAPH
+0x9B83	0x6CDD	#CJK UNIFIED IDEOGRAPH
+0x9B84	0x6CDF	#CJK UNIFIED IDEOGRAPH
+0x9B85	0x6CE4	#CJK UNIFIED IDEOGRAPH
+0x9B86	0x6CE6	#CJK UNIFIED IDEOGRAPH
+0x9B87	0x6CE7	#CJK UNIFIED IDEOGRAPH
+0x9B88	0x6CE9	#CJK UNIFIED IDEOGRAPH
+0x9B89	0x6CEC	#CJK UNIFIED IDEOGRAPH
+0x9B8A	0x6CED	#CJK UNIFIED IDEOGRAPH
+0x9B8B	0x6CF2	#CJK UNIFIED IDEOGRAPH
+0x9B8C	0x6CF4	#CJK UNIFIED IDEOGRAPH
+0x9B8D	0x6CF9	#CJK UNIFIED IDEOGRAPH
+0x9B8E	0x6CFF	#CJK UNIFIED IDEOGRAPH
+0x9B8F	0x6D00	#CJK UNIFIED IDEOGRAPH
+0x9B90	0x6D02	#CJK UNIFIED IDEOGRAPH
+0x9B91	0x6D03	#CJK UNIFIED IDEOGRAPH
+0x9B92	0x6D05	#CJK UNIFIED IDEOGRAPH
+0x9B93	0x6D06	#CJK UNIFIED IDEOGRAPH
+0x9B94	0x6D08	#CJK UNIFIED IDEOGRAPH
+0x9B95	0x6D09	#CJK UNIFIED IDEOGRAPH
+0x9B96	0x6D0A	#CJK UNIFIED IDEOGRAPH
+0x9B97	0x6D0D	#CJK UNIFIED IDEOGRAPH
+0x9B98	0x6D0F	#CJK UNIFIED IDEOGRAPH
+0x9B99	0x6D10	#CJK UNIFIED IDEOGRAPH
+0x9B9A	0x6D11	#CJK UNIFIED IDEOGRAPH
+0x9B9B	0x6D13	#CJK UNIFIED IDEOGRAPH
+0x9B9C	0x6D14	#CJK UNIFIED IDEOGRAPH
+0x9B9D	0x6D15	#CJK UNIFIED IDEOGRAPH
+0x9B9E	0x6D16	#CJK UNIFIED IDEOGRAPH
+0x9B9F	0x6D18	#CJK UNIFIED IDEOGRAPH
+0x9BA0	0x6D1C	#CJK UNIFIED IDEOGRAPH
+0x9BA1	0x6D1D	#CJK UNIFIED IDEOGRAPH
+0x9BA2	0x6D1F	#CJK UNIFIED IDEOGRAPH
+0x9BA3	0x6D20	#CJK UNIFIED IDEOGRAPH
+0x9BA4	0x6D21	#CJK UNIFIED IDEOGRAPH
+0x9BA5	0x6D22	#CJK UNIFIED IDEOGRAPH
+0x9BA6	0x6D23	#CJK UNIFIED IDEOGRAPH
+0x9BA7	0x6D24	#CJK UNIFIED IDEOGRAPH
+0x9BA8	0x6D26	#CJK UNIFIED IDEOGRAPH
+0x9BA9	0x6D28	#CJK UNIFIED IDEOGRAPH
+0x9BAA	0x6D29	#CJK UNIFIED IDEOGRAPH
+0x9BAB	0x6D2C	#CJK UNIFIED IDEOGRAPH
+0x9BAC	0x6D2D	#CJK UNIFIED IDEOGRAPH
+0x9BAD	0x6D2F	#CJK UNIFIED IDEOGRAPH
+0x9BAE	0x6D30	#CJK UNIFIED IDEOGRAPH
+0x9BAF	0x6D34	#CJK UNIFIED IDEOGRAPH
+0x9BB0	0x6D36	#CJK UNIFIED IDEOGRAPH
+0x9BB1	0x6D37	#CJK UNIFIED IDEOGRAPH
+0x9BB2	0x6D38	#CJK UNIFIED IDEOGRAPH
+0x9BB3	0x6D3A	#CJK UNIFIED IDEOGRAPH
+0x9BB4	0x6D3F	#CJK UNIFIED IDEOGRAPH
+0x9BB5	0x6D40	#CJK UNIFIED IDEOGRAPH
+0x9BB6	0x6D42	#CJK UNIFIED IDEOGRAPH
+0x9BB7	0x6D44	#CJK UNIFIED IDEOGRAPH
+0x9BB8	0x6D49	#CJK UNIFIED IDEOGRAPH
+0x9BB9	0x6D4C	#CJK UNIFIED IDEOGRAPH
+0x9BBA	0x6D50	#CJK UNIFIED IDEOGRAPH
+0x9BBB	0x6D55	#CJK UNIFIED IDEOGRAPH
+0x9BBC	0x6D56	#CJK UNIFIED IDEOGRAPH
+0x9BBD	0x6D57	#CJK UNIFIED IDEOGRAPH
+0x9BBE	0x6D58	#CJK UNIFIED IDEOGRAPH
+0x9BBF	0x6D5B	#CJK UNIFIED IDEOGRAPH
+0x9BC0	0x6D5D	#CJK UNIFIED IDEOGRAPH
+0x9BC1	0x6D5F	#CJK UNIFIED IDEOGRAPH
+0x9BC2	0x6D61	#CJK UNIFIED IDEOGRAPH
+0x9BC3	0x6D62	#CJK UNIFIED IDEOGRAPH
+0x9BC4	0x6D64	#CJK UNIFIED IDEOGRAPH
+0x9BC5	0x6D65	#CJK UNIFIED IDEOGRAPH
+0x9BC6	0x6D67	#CJK UNIFIED IDEOGRAPH
+0x9BC7	0x6D68	#CJK UNIFIED IDEOGRAPH
+0x9BC8	0x6D6B	#CJK UNIFIED IDEOGRAPH
+0x9BC9	0x6D6C	#CJK UNIFIED IDEOGRAPH
+0x9BCA	0x6D6D	#CJK UNIFIED IDEOGRAPH
+0x9BCB	0x6D70	#CJK UNIFIED IDEOGRAPH
+0x9BCC	0x6D71	#CJK UNIFIED IDEOGRAPH
+0x9BCD	0x6D72	#CJK UNIFIED IDEOGRAPH
+0x9BCE	0x6D73	#CJK UNIFIED IDEOGRAPH
+0x9BCF	0x6D75	#CJK UNIFIED IDEOGRAPH
+0x9BD0	0x6D76	#CJK UNIFIED IDEOGRAPH
+0x9BD1	0x6D79	#CJK UNIFIED IDEOGRAPH
+0x9BD2	0x6D7A	#CJK UNIFIED IDEOGRAPH
+0x9BD3	0x6D7B	#CJK UNIFIED IDEOGRAPH
+0x9BD4	0x6D7D	#CJK UNIFIED IDEOGRAPH
+0x9BD5	0x6D7E	#CJK UNIFIED IDEOGRAPH
+0x9BD6	0x6D7F	#CJK UNIFIED IDEOGRAPH
+0x9BD7	0x6D80	#CJK UNIFIED IDEOGRAPH
+0x9BD8	0x6D81	#CJK UNIFIED IDEOGRAPH
+0x9BD9	0x6D83	#CJK UNIFIED IDEOGRAPH
+0x9BDA	0x6D84	#CJK UNIFIED IDEOGRAPH
+0x9BDB	0x6D86	#CJK UNIFIED IDEOGRAPH
+0x9BDC	0x6D87	#CJK UNIFIED IDEOGRAPH
+0x9BDD	0x6D8A	#CJK UNIFIED IDEOGRAPH
+0x9BDE	0x6D8B	#CJK UNIFIED IDEOGRAPH
+0x9BDF	0x6D8D	#CJK UNIFIED IDEOGRAPH
+0x9BE0	0x6D8F	#CJK UNIFIED IDEOGRAPH
+0x9BE1	0x6D90	#CJK UNIFIED IDEOGRAPH
+0x9BE2	0x6D92	#CJK UNIFIED IDEOGRAPH
+0x9BE3	0x6D96	#CJK UNIFIED IDEOGRAPH
+0x9BE4	0x6D97	#CJK UNIFIED IDEOGRAPH
+0x9BE5	0x6D98	#CJK UNIFIED IDEOGRAPH
+0x9BE6	0x6D99	#CJK UNIFIED IDEOGRAPH
+0x9BE7	0x6D9A	#CJK UNIFIED IDEOGRAPH
+0x9BE8	0x6D9C	#CJK UNIFIED IDEOGRAPH
+0x9BE9	0x6DA2	#CJK UNIFIED IDEOGRAPH
+0x9BEA	0x6DA5	#CJK UNIFIED IDEOGRAPH
+0x9BEB	0x6DAC	#CJK UNIFIED IDEOGRAPH
+0x9BEC	0x6DAD	#CJK UNIFIED IDEOGRAPH
+0x9BED	0x6DB0	#CJK UNIFIED IDEOGRAPH
+0x9BEE	0x6DB1	#CJK UNIFIED IDEOGRAPH
+0x9BEF	0x6DB3	#CJK UNIFIED IDEOGRAPH
+0x9BF0	0x6DB4	#CJK UNIFIED IDEOGRAPH
+0x9BF1	0x6DB6	#CJK UNIFIED IDEOGRAPH
+0x9BF2	0x6DB7	#CJK UNIFIED IDEOGRAPH
+0x9BF3	0x6DB9	#CJK UNIFIED IDEOGRAPH
+0x9BF4	0x6DBA	#CJK UNIFIED IDEOGRAPH
+0x9BF5	0x6DBB	#CJK UNIFIED IDEOGRAPH
+0x9BF6	0x6DBC	#CJK UNIFIED IDEOGRAPH
+0x9BF7	0x6DBD	#CJK UNIFIED IDEOGRAPH
+0x9BF8	0x6DBE	#CJK UNIFIED IDEOGRAPH
+0x9BF9	0x6DC1	#CJK UNIFIED IDEOGRAPH
+0x9BFA	0x6DC2	#CJK UNIFIED IDEOGRAPH
+0x9BFB	0x6DC3	#CJK UNIFIED IDEOGRAPH
+0x9BFC	0x6DC8	#CJK UNIFIED IDEOGRAPH
+0x9BFD	0x6DC9	#CJK UNIFIED IDEOGRAPH
+0x9BFE	0x6DCA	#CJK UNIFIED IDEOGRAPH
+0x9C40	0x6DCD	#CJK UNIFIED IDEOGRAPH
+0x9C41	0x6DCE	#CJK UNIFIED IDEOGRAPH
+0x9C42	0x6DCF	#CJK UNIFIED IDEOGRAPH
+0x9C43	0x6DD0	#CJK UNIFIED IDEOGRAPH
+0x9C44	0x6DD2	#CJK UNIFIED IDEOGRAPH
+0x9C45	0x6DD3	#CJK UNIFIED IDEOGRAPH
+0x9C46	0x6DD4	#CJK UNIFIED IDEOGRAPH
+0x9C47	0x6DD5	#CJK UNIFIED IDEOGRAPH
+0x9C48	0x6DD7	#CJK UNIFIED IDEOGRAPH
+0x9C49	0x6DDA	#CJK UNIFIED IDEOGRAPH
+0x9C4A	0x6DDB	#CJK UNIFIED IDEOGRAPH
+0x9C4B	0x6DDC	#CJK UNIFIED IDEOGRAPH
+0x9C4C	0x6DDF	#CJK UNIFIED IDEOGRAPH
+0x9C4D	0x6DE2	#CJK UNIFIED IDEOGRAPH
+0x9C4E	0x6DE3	#CJK UNIFIED IDEOGRAPH
+0x9C4F	0x6DE5	#CJK UNIFIED IDEOGRAPH
+0x9C50	0x6DE7	#CJK UNIFIED IDEOGRAPH
+0x9C51	0x6DE8	#CJK UNIFIED IDEOGRAPH
+0x9C52	0x6DE9	#CJK UNIFIED IDEOGRAPH
+0x9C53	0x6DEA	#CJK UNIFIED IDEOGRAPH
+0x9C54	0x6DED	#CJK UNIFIED IDEOGRAPH
+0x9C55	0x6DEF	#CJK UNIFIED IDEOGRAPH
+0x9C56	0x6DF0	#CJK UNIFIED IDEOGRAPH
+0x9C57	0x6DF2	#CJK UNIFIED IDEOGRAPH
+0x9C58	0x6DF4	#CJK UNIFIED IDEOGRAPH
+0x9C59	0x6DF5	#CJK UNIFIED IDEOGRAPH
+0x9C5A	0x6DF6	#CJK UNIFIED IDEOGRAPH
+0x9C5B	0x6DF8	#CJK UNIFIED IDEOGRAPH
+0x9C5C	0x6DFA	#CJK UNIFIED IDEOGRAPH
+0x9C5D	0x6DFD	#CJK UNIFIED IDEOGRAPH
+0x9C5E	0x6DFE	#CJK UNIFIED IDEOGRAPH
+0x9C5F	0x6DFF	#CJK UNIFIED IDEOGRAPH
+0x9C60	0x6E00	#CJK UNIFIED IDEOGRAPH
+0x9C61	0x6E01	#CJK UNIFIED IDEOGRAPH
+0x9C62	0x6E02	#CJK UNIFIED IDEOGRAPH
+0x9C63	0x6E03	#CJK UNIFIED IDEOGRAPH
+0x9C64	0x6E04	#CJK UNIFIED IDEOGRAPH
+0x9C65	0x6E06	#CJK UNIFIED IDEOGRAPH
+0x9C66	0x6E07	#CJK UNIFIED IDEOGRAPH
+0x9C67	0x6E08	#CJK UNIFIED IDEOGRAPH
+0x9C68	0x6E09	#CJK UNIFIED IDEOGRAPH
+0x9C69	0x6E0B	#CJK UNIFIED IDEOGRAPH
+0x9C6A	0x6E0F	#CJK UNIFIED IDEOGRAPH
+0x9C6B	0x6E12	#CJK UNIFIED IDEOGRAPH
+0x9C6C	0x6E13	#CJK UNIFIED IDEOGRAPH
+0x9C6D	0x6E15	#CJK UNIFIED IDEOGRAPH
+0x9C6E	0x6E18	#CJK UNIFIED IDEOGRAPH
+0x9C6F	0x6E19	#CJK UNIFIED IDEOGRAPH
+0x9C70	0x6E1B	#CJK UNIFIED IDEOGRAPH
+0x9C71	0x6E1C	#CJK UNIFIED IDEOGRAPH
+0x9C72	0x6E1E	#CJK UNIFIED IDEOGRAPH
+0x9C73	0x6E1F	#CJK UNIFIED IDEOGRAPH
+0x9C74	0x6E22	#CJK UNIFIED IDEOGRAPH
+0x9C75	0x6E26	#CJK UNIFIED IDEOGRAPH
+0x9C76	0x6E27	#CJK UNIFIED IDEOGRAPH
+0x9C77	0x6E28	#CJK UNIFIED IDEOGRAPH
+0x9C78	0x6E2A	#CJK UNIFIED IDEOGRAPH
+0x9C79	0x6E2C	#CJK UNIFIED IDEOGRAPH
+0x9C7A	0x6E2E	#CJK UNIFIED IDEOGRAPH
+0x9C7B	0x6E30	#CJK UNIFIED IDEOGRAPH
+0x9C7C	0x6E31	#CJK UNIFIED IDEOGRAPH
+0x9C7D	0x6E33	#CJK UNIFIED IDEOGRAPH
+0x9C7E	0x6E35	#CJK UNIFIED IDEOGRAPH
+0x9C80	0x6E36	#CJK UNIFIED IDEOGRAPH
+0x9C81	0x6E37	#CJK UNIFIED IDEOGRAPH
+0x9C82	0x6E39	#CJK UNIFIED IDEOGRAPH
+0x9C83	0x6E3B	#CJK UNIFIED IDEOGRAPH
+0x9C84	0x6E3C	#CJK UNIFIED IDEOGRAPH
+0x9C85	0x6E3D	#CJK UNIFIED IDEOGRAPH
+0x9C86	0x6E3E	#CJK UNIFIED IDEOGRAPH
+0x9C87	0x6E3F	#CJK UNIFIED IDEOGRAPH
+0x9C88	0x6E40	#CJK UNIFIED IDEOGRAPH
+0x9C89	0x6E41	#CJK UNIFIED IDEOGRAPH
+0x9C8A	0x6E42	#CJK UNIFIED IDEOGRAPH
+0x9C8B	0x6E45	#CJK UNIFIED IDEOGRAPH
+0x9C8C	0x6E46	#CJK UNIFIED IDEOGRAPH
+0x9C8D	0x6E47	#CJK UNIFIED IDEOGRAPH
+0x9C8E	0x6E48	#CJK UNIFIED IDEOGRAPH
+0x9C8F	0x6E49	#CJK UNIFIED IDEOGRAPH
+0x9C90	0x6E4A	#CJK UNIFIED IDEOGRAPH
+0x9C91	0x6E4B	#CJK UNIFIED IDEOGRAPH
+0x9C92	0x6E4C	#CJK UNIFIED IDEOGRAPH
+0x9C93	0x6E4F	#CJK UNIFIED IDEOGRAPH
+0x9C94	0x6E50	#CJK UNIFIED IDEOGRAPH
+0x9C95	0x6E51	#CJK UNIFIED IDEOGRAPH
+0x9C96	0x6E52	#CJK UNIFIED IDEOGRAPH
+0x9C97	0x6E55	#CJK UNIFIED IDEOGRAPH
+0x9C98	0x6E57	#CJK UNIFIED IDEOGRAPH
+0x9C99	0x6E59	#CJK UNIFIED IDEOGRAPH
+0x9C9A	0x6E5A	#CJK UNIFIED IDEOGRAPH
+0x9C9B	0x6E5C	#CJK UNIFIED IDEOGRAPH
+0x9C9C	0x6E5D	#CJK UNIFIED IDEOGRAPH
+0x9C9D	0x6E5E	#CJK UNIFIED IDEOGRAPH
+0x9C9E	0x6E60	#CJK UNIFIED IDEOGRAPH
+0x9C9F	0x6E61	#CJK UNIFIED IDEOGRAPH
+0x9CA0	0x6E62	#CJK UNIFIED IDEOGRAPH
+0x9CA1	0x6E63	#CJK UNIFIED IDEOGRAPH
+0x9CA2	0x6E64	#CJK UNIFIED IDEOGRAPH
+0x9CA3	0x6E65	#CJK UNIFIED IDEOGRAPH
+0x9CA4	0x6E66	#CJK UNIFIED IDEOGRAPH
+0x9CA5	0x6E67	#CJK UNIFIED IDEOGRAPH
+0x9CA6	0x6E68	#CJK UNIFIED IDEOGRAPH
+0x9CA7	0x6E69	#CJK UNIFIED IDEOGRAPH
+0x9CA8	0x6E6A	#CJK UNIFIED IDEOGRAPH
+0x9CA9	0x6E6C	#CJK UNIFIED IDEOGRAPH
+0x9CAA	0x6E6D	#CJK UNIFIED IDEOGRAPH
+0x9CAB	0x6E6F	#CJK UNIFIED IDEOGRAPH
+0x9CAC	0x6E70	#CJK UNIFIED IDEOGRAPH
+0x9CAD	0x6E71	#CJK UNIFIED IDEOGRAPH
+0x9CAE	0x6E72	#CJK UNIFIED IDEOGRAPH
+0x9CAF	0x6E73	#CJK UNIFIED IDEOGRAPH
+0x9CB0	0x6E74	#CJK UNIFIED IDEOGRAPH
+0x9CB1	0x6E75	#CJK UNIFIED IDEOGRAPH
+0x9CB2	0x6E76	#CJK UNIFIED IDEOGRAPH
+0x9CB3	0x6E77	#CJK UNIFIED IDEOGRAPH
+0x9CB4	0x6E78	#CJK UNIFIED IDEOGRAPH
+0x9CB5	0x6E79	#CJK UNIFIED IDEOGRAPH
+0x9CB6	0x6E7A	#CJK UNIFIED IDEOGRAPH
+0x9CB7	0x6E7B	#CJK UNIFIED IDEOGRAPH
+0x9CB8	0x6E7C	#CJK UNIFIED IDEOGRAPH
+0x9CB9	0x6E7D	#CJK UNIFIED IDEOGRAPH
+0x9CBA	0x6E80	#CJK UNIFIED IDEOGRAPH
+0x9CBB	0x6E81	#CJK UNIFIED IDEOGRAPH
+0x9CBC	0x6E82	#CJK UNIFIED IDEOGRAPH
+0x9CBD	0x6E84	#CJK UNIFIED IDEOGRAPH
+0x9CBE	0x6E87	#CJK UNIFIED IDEOGRAPH
+0x9CBF	0x6E88	#CJK UNIFIED IDEOGRAPH
+0x9CC0	0x6E8A	#CJK UNIFIED IDEOGRAPH
+0x9CC1	0x6E8B	#CJK UNIFIED IDEOGRAPH
+0x9CC2	0x6E8C	#CJK UNIFIED IDEOGRAPH
+0x9CC3	0x6E8D	#CJK UNIFIED IDEOGRAPH
+0x9CC4	0x6E8E	#CJK UNIFIED IDEOGRAPH
+0x9CC5	0x6E91	#CJK UNIFIED IDEOGRAPH
+0x9CC6	0x6E92	#CJK UNIFIED IDEOGRAPH
+0x9CC7	0x6E93	#CJK UNIFIED IDEOGRAPH
+0x9CC8	0x6E94	#CJK UNIFIED IDEOGRAPH
+0x9CC9	0x6E95	#CJK UNIFIED IDEOGRAPH
+0x9CCA	0x6E96	#CJK UNIFIED IDEOGRAPH
+0x9CCB	0x6E97	#CJK UNIFIED IDEOGRAPH
+0x9CCC	0x6E99	#CJK UNIFIED IDEOGRAPH
+0x9CCD	0x6E9A	#CJK UNIFIED IDEOGRAPH
+0x9CCE	0x6E9B	#CJK UNIFIED IDEOGRAPH
+0x9CCF	0x6E9D	#CJK UNIFIED IDEOGRAPH
+0x9CD0	0x6E9E	#CJK UNIFIED IDEOGRAPH
+0x9CD1	0x6EA0	#CJK UNIFIED IDEOGRAPH
+0x9CD2	0x6EA1	#CJK UNIFIED IDEOGRAPH
+0x9CD3	0x6EA3	#CJK UNIFIED IDEOGRAPH
+0x9CD4	0x6EA4	#CJK UNIFIED IDEOGRAPH
+0x9CD5	0x6EA6	#CJK UNIFIED IDEOGRAPH
+0x9CD6	0x6EA8	#CJK UNIFIED IDEOGRAPH
+0x9CD7	0x6EA9	#CJK UNIFIED IDEOGRAPH
+0x9CD8	0x6EAB	#CJK UNIFIED IDEOGRAPH
+0x9CD9	0x6EAC	#CJK UNIFIED IDEOGRAPH
+0x9CDA	0x6EAD	#CJK UNIFIED IDEOGRAPH
+0x9CDB	0x6EAE	#CJK UNIFIED IDEOGRAPH
+0x9CDC	0x6EB0	#CJK UNIFIED IDEOGRAPH
+0x9CDD	0x6EB3	#CJK UNIFIED IDEOGRAPH
+0x9CDE	0x6EB5	#CJK UNIFIED IDEOGRAPH
+0x9CDF	0x6EB8	#CJK UNIFIED IDEOGRAPH
+0x9CE0	0x6EB9	#CJK UNIFIED IDEOGRAPH
+0x9CE1	0x6EBC	#CJK UNIFIED IDEOGRAPH
+0x9CE2	0x6EBE	#CJK UNIFIED IDEOGRAPH
+0x9CE3	0x6EBF	#CJK UNIFIED IDEOGRAPH
+0x9CE4	0x6EC0	#CJK UNIFIED IDEOGRAPH
+0x9CE5	0x6EC3	#CJK UNIFIED IDEOGRAPH
+0x9CE6	0x6EC4	#CJK UNIFIED IDEOGRAPH
+0x9CE7	0x6EC5	#CJK UNIFIED IDEOGRAPH
+0x9CE8	0x6EC6	#CJK UNIFIED IDEOGRAPH
+0x9CE9	0x6EC8	#CJK UNIFIED IDEOGRAPH
+0x9CEA	0x6EC9	#CJK UNIFIED IDEOGRAPH
+0x9CEB	0x6ECA	#CJK UNIFIED IDEOGRAPH
+0x9CEC	0x6ECC	#CJK UNIFIED IDEOGRAPH
+0x9CED	0x6ECD	#CJK UNIFIED IDEOGRAPH
+0x9CEE	0x6ECE	#CJK UNIFIED IDEOGRAPH
+0x9CEF	0x6ED0	#CJK UNIFIED IDEOGRAPH
+0x9CF0	0x6ED2	#CJK UNIFIED IDEOGRAPH
+0x9CF1	0x6ED6	#CJK UNIFIED IDEOGRAPH
+0x9CF2	0x6ED8	#CJK UNIFIED IDEOGRAPH
+0x9CF3	0x6ED9	#CJK UNIFIED IDEOGRAPH
+0x9CF4	0x6EDB	#CJK UNIFIED IDEOGRAPH
+0x9CF5	0x6EDC	#CJK UNIFIED IDEOGRAPH
+0x9CF6	0x6EDD	#CJK UNIFIED IDEOGRAPH
+0x9CF7	0x6EE3	#CJK UNIFIED IDEOGRAPH
+0x9CF8	0x6EE7	#CJK UNIFIED IDEOGRAPH
+0x9CF9	0x6EEA	#CJK UNIFIED IDEOGRAPH
+0x9CFA	0x6EEB	#CJK UNIFIED IDEOGRAPH
+0x9CFB	0x6EEC	#CJK UNIFIED IDEOGRAPH
+0x9CFC	0x6EED	#CJK UNIFIED IDEOGRAPH
+0x9CFD	0x6EEE	#CJK UNIFIED IDEOGRAPH
+0x9CFE	0x6EEF	#CJK UNIFIED IDEOGRAPH
+0x9D40	0x6EF0	#CJK UNIFIED IDEOGRAPH
+0x9D41	0x6EF1	#CJK UNIFIED IDEOGRAPH
+0x9D42	0x6EF2	#CJK UNIFIED IDEOGRAPH
+0x9D43	0x6EF3	#CJK UNIFIED IDEOGRAPH
+0x9D44	0x6EF5	#CJK UNIFIED IDEOGRAPH
+0x9D45	0x6EF6	#CJK UNIFIED IDEOGRAPH
+0x9D46	0x6EF7	#CJK UNIFIED IDEOGRAPH
+0x9D47	0x6EF8	#CJK UNIFIED IDEOGRAPH
+0x9D48	0x6EFA	#CJK UNIFIED IDEOGRAPH
+0x9D49	0x6EFB	#CJK UNIFIED IDEOGRAPH
+0x9D4A	0x6EFC	#CJK UNIFIED IDEOGRAPH
+0x9D4B	0x6EFD	#CJK UNIFIED IDEOGRAPH
+0x9D4C	0x6EFE	#CJK UNIFIED IDEOGRAPH
+0x9D4D	0x6EFF	#CJK UNIFIED IDEOGRAPH
+0x9D4E	0x6F00	#CJK UNIFIED IDEOGRAPH
+0x9D4F	0x6F01	#CJK UNIFIED IDEOGRAPH
+0x9D50	0x6F03	#CJK UNIFIED IDEOGRAPH
+0x9D51	0x6F04	#CJK UNIFIED IDEOGRAPH
+0x9D52	0x6F05	#CJK UNIFIED IDEOGRAPH
+0x9D53	0x6F07	#CJK UNIFIED IDEOGRAPH
+0x9D54	0x6F08	#CJK UNIFIED IDEOGRAPH
+0x9D55	0x6F0A	#CJK UNIFIED IDEOGRAPH
+0x9D56	0x6F0B	#CJK UNIFIED IDEOGRAPH
+0x9D57	0x6F0C	#CJK UNIFIED IDEOGRAPH
+0x9D58	0x6F0D	#CJK UNIFIED IDEOGRAPH
+0x9D59	0x6F0E	#CJK UNIFIED IDEOGRAPH
+0x9D5A	0x6F10	#CJK UNIFIED IDEOGRAPH
+0x9D5B	0x6F11	#CJK UNIFIED IDEOGRAPH
+0x9D5C	0x6F12	#CJK UNIFIED IDEOGRAPH
+0x9D5D	0x6F16	#CJK UNIFIED IDEOGRAPH
+0x9D5E	0x6F17	#CJK UNIFIED IDEOGRAPH
+0x9D5F	0x6F18	#CJK UNIFIED IDEOGRAPH
+0x9D60	0x6F19	#CJK UNIFIED IDEOGRAPH
+0x9D61	0x6F1A	#CJK UNIFIED IDEOGRAPH
+0x9D62	0x6F1B	#CJK UNIFIED IDEOGRAPH
+0x9D63	0x6F1C	#CJK UNIFIED IDEOGRAPH
+0x9D64	0x6F1D	#CJK UNIFIED IDEOGRAPH
+0x9D65	0x6F1E	#CJK UNIFIED IDEOGRAPH
+0x9D66	0x6F1F	#CJK UNIFIED IDEOGRAPH
+0x9D67	0x6F21	#CJK UNIFIED IDEOGRAPH
+0x9D68	0x6F22	#CJK UNIFIED IDEOGRAPH
+0x9D69	0x6F23	#CJK UNIFIED IDEOGRAPH
+0x9D6A	0x6F25	#CJK UNIFIED IDEOGRAPH
+0x9D6B	0x6F26	#CJK UNIFIED IDEOGRAPH
+0x9D6C	0x6F27	#CJK UNIFIED IDEOGRAPH
+0x9D6D	0x6F28	#CJK UNIFIED IDEOGRAPH
+0x9D6E	0x6F2C	#CJK UNIFIED IDEOGRAPH
+0x9D6F	0x6F2E	#CJK UNIFIED IDEOGRAPH
+0x9D70	0x6F30	#CJK UNIFIED IDEOGRAPH
+0x9D71	0x6F32	#CJK UNIFIED IDEOGRAPH
+0x9D72	0x6F34	#CJK UNIFIED IDEOGRAPH
+0x9D73	0x6F35	#CJK UNIFIED IDEOGRAPH
+0x9D74	0x6F37	#CJK UNIFIED IDEOGRAPH
+0x9D75	0x6F38	#CJK UNIFIED IDEOGRAPH
+0x9D76	0x6F39	#CJK UNIFIED IDEOGRAPH
+0x9D77	0x6F3A	#CJK UNIFIED IDEOGRAPH
+0x9D78	0x6F3B	#CJK UNIFIED IDEOGRAPH
+0x9D79	0x6F3C	#CJK UNIFIED IDEOGRAPH
+0x9D7A	0x6F3D	#CJK UNIFIED IDEOGRAPH
+0x9D7B	0x6F3F	#CJK UNIFIED IDEOGRAPH
+0x9D7C	0x6F40	#CJK UNIFIED IDEOGRAPH
+0x9D7D	0x6F41	#CJK UNIFIED IDEOGRAPH
+0x9D7E	0x6F42	#CJK UNIFIED IDEOGRAPH
+0x9D80	0x6F43	#CJK UNIFIED IDEOGRAPH
+0x9D81	0x6F44	#CJK UNIFIED IDEOGRAPH
+0x9D82	0x6F45	#CJK UNIFIED IDEOGRAPH
+0x9D83	0x6F48	#CJK UNIFIED IDEOGRAPH
+0x9D84	0x6F49	#CJK UNIFIED IDEOGRAPH
+0x9D85	0x6F4A	#CJK UNIFIED IDEOGRAPH
+0x9D86	0x6F4C	#CJK UNIFIED IDEOGRAPH
+0x9D87	0x6F4E	#CJK UNIFIED IDEOGRAPH
+0x9D88	0x6F4F	#CJK UNIFIED IDEOGRAPH
+0x9D89	0x6F50	#CJK UNIFIED IDEOGRAPH
+0x9D8A	0x6F51	#CJK UNIFIED IDEOGRAPH
+0x9D8B	0x6F52	#CJK UNIFIED IDEOGRAPH
+0x9D8C	0x6F53	#CJK UNIFIED IDEOGRAPH
+0x9D8D	0x6F54	#CJK UNIFIED IDEOGRAPH
+0x9D8E	0x6F55	#CJK UNIFIED IDEOGRAPH
+0x9D8F	0x6F56	#CJK UNIFIED IDEOGRAPH
+0x9D90	0x6F57	#CJK UNIFIED IDEOGRAPH
+0x9D91	0x6F59	#CJK UNIFIED IDEOGRAPH
+0x9D92	0x6F5A	#CJK UNIFIED IDEOGRAPH
+0x9D93	0x6F5B	#CJK UNIFIED IDEOGRAPH
+0x9D94	0x6F5D	#CJK UNIFIED IDEOGRAPH
+0x9D95	0x6F5F	#CJK UNIFIED IDEOGRAPH
+0x9D96	0x6F60	#CJK UNIFIED IDEOGRAPH
+0x9D97	0x6F61	#CJK UNIFIED IDEOGRAPH
+0x9D98	0x6F63	#CJK UNIFIED IDEOGRAPH
+0x9D99	0x6F64	#CJK UNIFIED IDEOGRAPH
+0x9D9A	0x6F65	#CJK UNIFIED IDEOGRAPH
+0x9D9B	0x6F67	#CJK UNIFIED IDEOGRAPH
+0x9D9C	0x6F68	#CJK UNIFIED IDEOGRAPH
+0x9D9D	0x6F69	#CJK UNIFIED IDEOGRAPH
+0x9D9E	0x6F6A	#CJK UNIFIED IDEOGRAPH
+0x9D9F	0x6F6B	#CJK UNIFIED IDEOGRAPH
+0x9DA0	0x6F6C	#CJK UNIFIED IDEOGRAPH
+0x9DA1	0x6F6F	#CJK UNIFIED IDEOGRAPH
+0x9DA2	0x6F70	#CJK UNIFIED IDEOGRAPH
+0x9DA3	0x6F71	#CJK UNIFIED IDEOGRAPH
+0x9DA4	0x6F73	#CJK UNIFIED IDEOGRAPH
+0x9DA5	0x6F75	#CJK UNIFIED IDEOGRAPH
+0x9DA6	0x6F76	#CJK UNIFIED IDEOGRAPH
+0x9DA7	0x6F77	#CJK UNIFIED IDEOGRAPH
+0x9DA8	0x6F79	#CJK UNIFIED IDEOGRAPH
+0x9DA9	0x6F7B	#CJK UNIFIED IDEOGRAPH
+0x9DAA	0x6F7D	#CJK UNIFIED IDEOGRAPH
+0x9DAB	0x6F7E	#CJK UNIFIED IDEOGRAPH
+0x9DAC	0x6F7F	#CJK UNIFIED IDEOGRAPH
+0x9DAD	0x6F80	#CJK UNIFIED IDEOGRAPH
+0x9DAE	0x6F81	#CJK UNIFIED IDEOGRAPH
+0x9DAF	0x6F82	#CJK UNIFIED IDEOGRAPH
+0x9DB0	0x6F83	#CJK UNIFIED IDEOGRAPH
+0x9DB1	0x6F85	#CJK UNIFIED IDEOGRAPH
+0x9DB2	0x6F86	#CJK UNIFIED IDEOGRAPH
+0x9DB3	0x6F87	#CJK UNIFIED IDEOGRAPH
+0x9DB4	0x6F8A	#CJK UNIFIED IDEOGRAPH
+0x9DB5	0x6F8B	#CJK UNIFIED IDEOGRAPH
+0x9DB6	0x6F8F	#CJK UNIFIED IDEOGRAPH
+0x9DB7	0x6F90	#CJK UNIFIED IDEOGRAPH
+0x9DB8	0x6F91	#CJK UNIFIED IDEOGRAPH
+0x9DB9	0x6F92	#CJK UNIFIED IDEOGRAPH
+0x9DBA	0x6F93	#CJK UNIFIED IDEOGRAPH
+0x9DBB	0x6F94	#CJK UNIFIED IDEOGRAPH
+0x9DBC	0x6F95	#CJK UNIFIED IDEOGRAPH
+0x9DBD	0x6F96	#CJK UNIFIED IDEOGRAPH
+0x9DBE	0x6F97	#CJK UNIFIED IDEOGRAPH
+0x9DBF	0x6F98	#CJK UNIFIED IDEOGRAPH
+0x9DC0	0x6F99	#CJK UNIFIED IDEOGRAPH
+0x9DC1	0x6F9A	#CJK UNIFIED IDEOGRAPH
+0x9DC2	0x6F9B	#CJK UNIFIED IDEOGRAPH
+0x9DC3	0x6F9D	#CJK UNIFIED IDEOGRAPH
+0x9DC4	0x6F9E	#CJK UNIFIED IDEOGRAPH
+0x9DC5	0x6F9F	#CJK UNIFIED IDEOGRAPH
+0x9DC6	0x6FA0	#CJK UNIFIED IDEOGRAPH
+0x9DC7	0x6FA2	#CJK UNIFIED IDEOGRAPH
+0x9DC8	0x6FA3	#CJK UNIFIED IDEOGRAPH
+0x9DC9	0x6FA4	#CJK UNIFIED IDEOGRAPH
+0x9DCA	0x6FA5	#CJK UNIFIED IDEOGRAPH
+0x9DCB	0x6FA6	#CJK UNIFIED IDEOGRAPH
+0x9DCC	0x6FA8	#CJK UNIFIED IDEOGRAPH
+0x9DCD	0x6FA9	#CJK UNIFIED IDEOGRAPH
+0x9DCE	0x6FAA	#CJK UNIFIED IDEOGRAPH
+0x9DCF	0x6FAB	#CJK UNIFIED IDEOGRAPH
+0x9DD0	0x6FAC	#CJK UNIFIED IDEOGRAPH
+0x9DD1	0x6FAD	#CJK UNIFIED IDEOGRAPH
+0x9DD2	0x6FAE	#CJK UNIFIED IDEOGRAPH
+0x9DD3	0x6FAF	#CJK UNIFIED IDEOGRAPH
+0x9DD4	0x6FB0	#CJK UNIFIED IDEOGRAPH
+0x9DD5	0x6FB1	#CJK UNIFIED IDEOGRAPH
+0x9DD6	0x6FB2	#CJK UNIFIED IDEOGRAPH
+0x9DD7	0x6FB4	#CJK UNIFIED IDEOGRAPH
+0x9DD8	0x6FB5	#CJK UNIFIED IDEOGRAPH
+0x9DD9	0x6FB7	#CJK UNIFIED IDEOGRAPH
+0x9DDA	0x6FB8	#CJK UNIFIED IDEOGRAPH
+0x9DDB	0x6FBA	#CJK UNIFIED IDEOGRAPH
+0x9DDC	0x6FBB	#CJK UNIFIED IDEOGRAPH
+0x9DDD	0x6FBC	#CJK UNIFIED IDEOGRAPH
+0x9DDE	0x6FBD	#CJK UNIFIED IDEOGRAPH
+0x9DDF	0x6FBE	#CJK UNIFIED IDEOGRAPH
+0x9DE0	0x6FBF	#CJK UNIFIED IDEOGRAPH
+0x9DE1	0x6FC1	#CJK UNIFIED IDEOGRAPH
+0x9DE2	0x6FC3	#CJK UNIFIED IDEOGRAPH
+0x9DE3	0x6FC4	#CJK UNIFIED IDEOGRAPH
+0x9DE4	0x6FC5	#CJK UNIFIED IDEOGRAPH
+0x9DE5	0x6FC6	#CJK UNIFIED IDEOGRAPH
+0x9DE6	0x6FC7	#CJK UNIFIED IDEOGRAPH
+0x9DE7	0x6FC8	#CJK UNIFIED IDEOGRAPH
+0x9DE8	0x6FCA	#CJK UNIFIED IDEOGRAPH
+0x9DE9	0x6FCB	#CJK UNIFIED IDEOGRAPH
+0x9DEA	0x6FCC	#CJK UNIFIED IDEOGRAPH
+0x9DEB	0x6FCD	#CJK UNIFIED IDEOGRAPH
+0x9DEC	0x6FCE	#CJK UNIFIED IDEOGRAPH
+0x9DED	0x6FCF	#CJK UNIFIED IDEOGRAPH
+0x9DEE	0x6FD0	#CJK UNIFIED IDEOGRAPH
+0x9DEF	0x6FD3	#CJK UNIFIED IDEOGRAPH
+0x9DF0	0x6FD4	#CJK UNIFIED IDEOGRAPH
+0x9DF1	0x6FD5	#CJK UNIFIED IDEOGRAPH
+0x9DF2	0x6FD6	#CJK UNIFIED IDEOGRAPH
+0x9DF3	0x6FD7	#CJK UNIFIED IDEOGRAPH
+0x9DF4	0x6FD8	#CJK UNIFIED IDEOGRAPH
+0x9DF5	0x6FD9	#CJK UNIFIED IDEOGRAPH
+0x9DF6	0x6FDA	#CJK UNIFIED IDEOGRAPH
+0x9DF7	0x6FDB	#CJK UNIFIED IDEOGRAPH
+0x9DF8	0x6FDC	#CJK UNIFIED IDEOGRAPH
+0x9DF9	0x6FDD	#CJK UNIFIED IDEOGRAPH
+0x9DFA	0x6FDF	#CJK UNIFIED IDEOGRAPH
+0x9DFB	0x6FE2	#CJK UNIFIED IDEOGRAPH
+0x9DFC	0x6FE3	#CJK UNIFIED IDEOGRAPH
+0x9DFD	0x6FE4	#CJK UNIFIED IDEOGRAPH
+0x9DFE	0x6FE5	#CJK UNIFIED IDEOGRAPH
+0x9E40	0x6FE6	#CJK UNIFIED IDEOGRAPH
+0x9E41	0x6FE7	#CJK UNIFIED IDEOGRAPH
+0x9E42	0x6FE8	#CJK UNIFIED IDEOGRAPH
+0x9E43	0x6FE9	#CJK UNIFIED IDEOGRAPH
+0x9E44	0x6FEA	#CJK UNIFIED IDEOGRAPH
+0x9E45	0x6FEB	#CJK UNIFIED IDEOGRAPH
+0x9E46	0x6FEC	#CJK UNIFIED IDEOGRAPH
+0x9E47	0x6FED	#CJK UNIFIED IDEOGRAPH
+0x9E48	0x6FF0	#CJK UNIFIED IDEOGRAPH
+0x9E49	0x6FF1	#CJK UNIFIED IDEOGRAPH
+0x9E4A	0x6FF2	#CJK UNIFIED IDEOGRAPH
+0x9E4B	0x6FF3	#CJK UNIFIED IDEOGRAPH
+0x9E4C	0x6FF4	#CJK UNIFIED IDEOGRAPH
+0x9E4D	0x6FF5	#CJK UNIFIED IDEOGRAPH
+0x9E4E	0x6FF6	#CJK UNIFIED IDEOGRAPH
+0x9E4F	0x6FF7	#CJK UNIFIED IDEOGRAPH
+0x9E50	0x6FF8	#CJK UNIFIED IDEOGRAPH
+0x9E51	0x6FF9	#CJK UNIFIED IDEOGRAPH
+0x9E52	0x6FFA	#CJK UNIFIED IDEOGRAPH
+0x9E53	0x6FFB	#CJK UNIFIED IDEOGRAPH
+0x9E54	0x6FFC	#CJK UNIFIED IDEOGRAPH
+0x9E55	0x6FFD	#CJK UNIFIED IDEOGRAPH
+0x9E56	0x6FFE	#CJK UNIFIED IDEOGRAPH
+0x9E57	0x6FFF	#CJK UNIFIED IDEOGRAPH
+0x9E58	0x7000	#CJK UNIFIED IDEOGRAPH
+0x9E59	0x7001	#CJK UNIFIED IDEOGRAPH
+0x9E5A	0x7002	#CJK UNIFIED IDEOGRAPH
+0x9E5B	0x7003	#CJK UNIFIED IDEOGRAPH
+0x9E5C	0x7004	#CJK UNIFIED IDEOGRAPH
+0x9E5D	0x7005	#CJK UNIFIED IDEOGRAPH
+0x9E5E	0x7006	#CJK UNIFIED IDEOGRAPH
+0x9E5F	0x7007	#CJK UNIFIED IDEOGRAPH
+0x9E60	0x7008	#CJK UNIFIED IDEOGRAPH
+0x9E61	0x7009	#CJK UNIFIED IDEOGRAPH
+0x9E62	0x700A	#CJK UNIFIED IDEOGRAPH
+0x9E63	0x700B	#CJK UNIFIED IDEOGRAPH
+0x9E64	0x700C	#CJK UNIFIED IDEOGRAPH
+0x9E65	0x700D	#CJK UNIFIED IDEOGRAPH
+0x9E66	0x700E	#CJK UNIFIED IDEOGRAPH
+0x9E67	0x700F	#CJK UNIFIED IDEOGRAPH
+0x9E68	0x7010	#CJK UNIFIED IDEOGRAPH
+0x9E69	0x7012	#CJK UNIFIED IDEOGRAPH
+0x9E6A	0x7013	#CJK UNIFIED IDEOGRAPH
+0x9E6B	0x7014	#CJK UNIFIED IDEOGRAPH
+0x9E6C	0x7015	#CJK UNIFIED IDEOGRAPH
+0x9E6D	0x7016	#CJK UNIFIED IDEOGRAPH
+0x9E6E	0x7017	#CJK UNIFIED IDEOGRAPH
+0x9E6F	0x7018	#CJK UNIFIED IDEOGRAPH
+0x9E70	0x7019	#CJK UNIFIED IDEOGRAPH
+0x9E71	0x701C	#CJK UNIFIED IDEOGRAPH
+0x9E72	0x701D	#CJK UNIFIED IDEOGRAPH
+0x9E73	0x701E	#CJK UNIFIED IDEOGRAPH
+0x9E74	0x701F	#CJK UNIFIED IDEOGRAPH
+0x9E75	0x7020	#CJK UNIFIED IDEOGRAPH
+0x9E76	0x7021	#CJK UNIFIED IDEOGRAPH
+0x9E77	0x7022	#CJK UNIFIED IDEOGRAPH
+0x9E78	0x7024	#CJK UNIFIED IDEOGRAPH
+0x9E79	0x7025	#CJK UNIFIED IDEOGRAPH
+0x9E7A	0x7026	#CJK UNIFIED IDEOGRAPH
+0x9E7B	0x7027	#CJK UNIFIED IDEOGRAPH
+0x9E7C	0x7028	#CJK UNIFIED IDEOGRAPH
+0x9E7D	0x7029	#CJK UNIFIED IDEOGRAPH
+0x9E7E	0x702A	#CJK UNIFIED IDEOGRAPH
+0x9E80	0x702B	#CJK UNIFIED IDEOGRAPH
+0x9E81	0x702C	#CJK UNIFIED IDEOGRAPH
+0x9E82	0x702D	#CJK UNIFIED IDEOGRAPH
+0x9E83	0x702E	#CJK UNIFIED IDEOGRAPH
+0x9E84	0x702F	#CJK UNIFIED IDEOGRAPH
+0x9E85	0x7030	#CJK UNIFIED IDEOGRAPH
+0x9E86	0x7031	#CJK UNIFIED IDEOGRAPH
+0x9E87	0x7032	#CJK UNIFIED IDEOGRAPH
+0x9E88	0x7033	#CJK UNIFIED IDEOGRAPH
+0x9E89	0x7034	#CJK UNIFIED IDEOGRAPH
+0x9E8A	0x7036	#CJK UNIFIED IDEOGRAPH
+0x9E8B	0x7037	#CJK UNIFIED IDEOGRAPH
+0x9E8C	0x7038	#CJK UNIFIED IDEOGRAPH
+0x9E8D	0x703A	#CJK UNIFIED IDEOGRAPH
+0x9E8E	0x703B	#CJK UNIFIED IDEOGRAPH
+0x9E8F	0x703C	#CJK UNIFIED IDEOGRAPH
+0x9E90	0x703D	#CJK UNIFIED IDEOGRAPH
+0x9E91	0x703E	#CJK UNIFIED IDEOGRAPH
+0x9E92	0x703F	#CJK UNIFIED IDEOGRAPH
+0x9E93	0x7040	#CJK UNIFIED IDEOGRAPH
+0x9E94	0x7041	#CJK UNIFIED IDEOGRAPH
+0x9E95	0x7042	#CJK UNIFIED IDEOGRAPH
+0x9E96	0x7043	#CJK UNIFIED IDEOGRAPH
+0x9E97	0x7044	#CJK UNIFIED IDEOGRAPH
+0x9E98	0x7045	#CJK UNIFIED IDEOGRAPH
+0x9E99	0x7046	#CJK UNIFIED IDEOGRAPH
+0x9E9A	0x7047	#CJK UNIFIED IDEOGRAPH
+0x9E9B	0x7048	#CJK UNIFIED IDEOGRAPH
+0x9E9C	0x7049	#CJK UNIFIED IDEOGRAPH
+0x9E9D	0x704A	#CJK UNIFIED IDEOGRAPH
+0x9E9E	0x704B	#CJK UNIFIED IDEOGRAPH
+0x9E9F	0x704D	#CJK UNIFIED IDEOGRAPH
+0x9EA0	0x704E	#CJK UNIFIED IDEOGRAPH
+0x9EA1	0x7050	#CJK UNIFIED IDEOGRAPH
+0x9EA2	0x7051	#CJK UNIFIED IDEOGRAPH
+0x9EA3	0x7052	#CJK UNIFIED IDEOGRAPH
+0x9EA4	0x7053	#CJK UNIFIED IDEOGRAPH
+0x9EA5	0x7054	#CJK UNIFIED IDEOGRAPH
+0x9EA6	0x7055	#CJK UNIFIED IDEOGRAPH
+0x9EA7	0x7056	#CJK UNIFIED IDEOGRAPH
+0x9EA8	0x7057	#CJK UNIFIED IDEOGRAPH
+0x9EA9	0x7058	#CJK UNIFIED IDEOGRAPH
+0x9EAA	0x7059	#CJK UNIFIED IDEOGRAPH
+0x9EAB	0x705A	#CJK UNIFIED IDEOGRAPH
+0x9EAC	0x705B	#CJK UNIFIED IDEOGRAPH
+0x9EAD	0x705C	#CJK UNIFIED IDEOGRAPH
+0x9EAE	0x705D	#CJK UNIFIED IDEOGRAPH
+0x9EAF	0x705F	#CJK UNIFIED IDEOGRAPH
+0x9EB0	0x7060	#CJK UNIFIED IDEOGRAPH
+0x9EB1	0x7061	#CJK UNIFIED IDEOGRAPH
+0x9EB2	0x7062	#CJK UNIFIED IDEOGRAPH
+0x9EB3	0x7063	#CJK UNIFIED IDEOGRAPH
+0x9EB4	0x7064	#CJK UNIFIED IDEOGRAPH
+0x9EB5	0x7065	#CJK UNIFIED IDEOGRAPH
+0x9EB6	0x7066	#CJK UNIFIED IDEOGRAPH
+0x9EB7	0x7067	#CJK UNIFIED IDEOGRAPH
+0x9EB8	0x7068	#CJK UNIFIED IDEOGRAPH
+0x9EB9	0x7069	#CJK UNIFIED IDEOGRAPH
+0x9EBA	0x706A	#CJK UNIFIED IDEOGRAPH
+0x9EBB	0x706E	#CJK UNIFIED IDEOGRAPH
+0x9EBC	0x7071	#CJK UNIFIED IDEOGRAPH
+0x9EBD	0x7072	#CJK UNIFIED IDEOGRAPH
+0x9EBE	0x7073	#CJK UNIFIED IDEOGRAPH
+0x9EBF	0x7074	#CJK UNIFIED IDEOGRAPH
+0x9EC0	0x7077	#CJK UNIFIED IDEOGRAPH
+0x9EC1	0x7079	#CJK UNIFIED IDEOGRAPH
+0x9EC2	0x707A	#CJK UNIFIED IDEOGRAPH
+0x9EC3	0x707B	#CJK UNIFIED IDEOGRAPH
+0x9EC4	0x707D	#CJK UNIFIED IDEOGRAPH
+0x9EC5	0x7081	#CJK UNIFIED IDEOGRAPH
+0x9EC6	0x7082	#CJK UNIFIED IDEOGRAPH
+0x9EC7	0x7083	#CJK UNIFIED IDEOGRAPH
+0x9EC8	0x7084	#CJK UNIFIED IDEOGRAPH
+0x9EC9	0x7086	#CJK UNIFIED IDEOGRAPH
+0x9ECA	0x7087	#CJK UNIFIED IDEOGRAPH
+0x9ECB	0x7088	#CJK UNIFIED IDEOGRAPH
+0x9ECC	0x708B	#CJK UNIFIED IDEOGRAPH
+0x9ECD	0x708C	#CJK UNIFIED IDEOGRAPH
+0x9ECE	0x708D	#CJK UNIFIED IDEOGRAPH
+0x9ECF	0x708F	#CJK UNIFIED IDEOGRAPH
+0x9ED0	0x7090	#CJK UNIFIED IDEOGRAPH
+0x9ED1	0x7091	#CJK UNIFIED IDEOGRAPH
+0x9ED2	0x7093	#CJK UNIFIED IDEOGRAPH
+0x9ED3	0x7097	#CJK UNIFIED IDEOGRAPH
+0x9ED4	0x7098	#CJK UNIFIED IDEOGRAPH
+0x9ED5	0x709A	#CJK UNIFIED IDEOGRAPH
+0x9ED6	0x709B	#CJK UNIFIED IDEOGRAPH
+0x9ED7	0x709E	#CJK UNIFIED IDEOGRAPH
+0x9ED8	0x709F	#CJK UNIFIED IDEOGRAPH
+0x9ED9	0x70A0	#CJK UNIFIED IDEOGRAPH
+0x9EDA	0x70A1	#CJK UNIFIED IDEOGRAPH
+0x9EDB	0x70A2	#CJK UNIFIED IDEOGRAPH
+0x9EDC	0x70A3	#CJK UNIFIED IDEOGRAPH
+0x9EDD	0x70A4	#CJK UNIFIED IDEOGRAPH
+0x9EDE	0x70A5	#CJK UNIFIED IDEOGRAPH
+0x9EDF	0x70A6	#CJK UNIFIED IDEOGRAPH
+0x9EE0	0x70A7	#CJK UNIFIED IDEOGRAPH
+0x9EE1	0x70A8	#CJK UNIFIED IDEOGRAPH
+0x9EE2	0x70A9	#CJK UNIFIED IDEOGRAPH
+0x9EE3	0x70AA	#CJK UNIFIED IDEOGRAPH
+0x9EE4	0x70B0	#CJK UNIFIED IDEOGRAPH
+0x9EE5	0x70B2	#CJK UNIFIED IDEOGRAPH
+0x9EE6	0x70B4	#CJK UNIFIED IDEOGRAPH
+0x9EE7	0x70B5	#CJK UNIFIED IDEOGRAPH
+0x9EE8	0x70B6	#CJK UNIFIED IDEOGRAPH
+0x9EE9	0x70BA	#CJK UNIFIED IDEOGRAPH
+0x9EEA	0x70BE	#CJK UNIFIED IDEOGRAPH
+0x9EEB	0x70BF	#CJK UNIFIED IDEOGRAPH
+0x9EEC	0x70C4	#CJK UNIFIED IDEOGRAPH
+0x9EED	0x70C5	#CJK UNIFIED IDEOGRAPH
+0x9EEE	0x70C6	#CJK UNIFIED IDEOGRAPH
+0x9EEF	0x70C7	#CJK UNIFIED IDEOGRAPH
+0x9EF0	0x70C9	#CJK UNIFIED IDEOGRAPH
+0x9EF1	0x70CB	#CJK UNIFIED IDEOGRAPH
+0x9EF2	0x70CC	#CJK UNIFIED IDEOGRAPH
+0x9EF3	0x70CD	#CJK UNIFIED IDEOGRAPH
+0x9EF4	0x70CE	#CJK UNIFIED IDEOGRAPH
+0x9EF5	0x70CF	#CJK UNIFIED IDEOGRAPH
+0x9EF6	0x70D0	#CJK UNIFIED IDEOGRAPH
+0x9EF7	0x70D1	#CJK UNIFIED IDEOGRAPH
+0x9EF8	0x70D2	#CJK UNIFIED IDEOGRAPH
+0x9EF9	0x70D3	#CJK UNIFIED IDEOGRAPH
+0x9EFA	0x70D4	#CJK UNIFIED IDEOGRAPH
+0x9EFB	0x70D5	#CJK UNIFIED IDEOGRAPH
+0x9EFC	0x70D6	#CJK UNIFIED IDEOGRAPH
+0x9EFD	0x70D7	#CJK UNIFIED IDEOGRAPH
+0x9EFE	0x70DA	#CJK UNIFIED IDEOGRAPH
+0x9F40	0x70DC	#CJK UNIFIED IDEOGRAPH
+0x9F41	0x70DD	#CJK UNIFIED IDEOGRAPH
+0x9F42	0x70DE	#CJK UNIFIED IDEOGRAPH
+0x9F43	0x70E0	#CJK UNIFIED IDEOGRAPH
+0x9F44	0x70E1	#CJK UNIFIED IDEOGRAPH
+0x9F45	0x70E2	#CJK UNIFIED IDEOGRAPH
+0x9F46	0x70E3	#CJK UNIFIED IDEOGRAPH
+0x9F47	0x70E5	#CJK UNIFIED IDEOGRAPH
+0x9F48	0x70EA	#CJK UNIFIED IDEOGRAPH
+0x9F49	0x70EE	#CJK UNIFIED IDEOGRAPH
+0x9F4A	0x70F0	#CJK UNIFIED IDEOGRAPH
+0x9F4B	0x70F1	#CJK UNIFIED IDEOGRAPH
+0x9F4C	0x70F2	#CJK UNIFIED IDEOGRAPH
+0x9F4D	0x70F3	#CJK UNIFIED IDEOGRAPH
+0x9F4E	0x70F4	#CJK UNIFIED IDEOGRAPH
+0x9F4F	0x70F5	#CJK UNIFIED IDEOGRAPH
+0x9F50	0x70F6	#CJK UNIFIED IDEOGRAPH
+0x9F51	0x70F8	#CJK UNIFIED IDEOGRAPH
+0x9F52	0x70FA	#CJK UNIFIED IDEOGRAPH
+0x9F53	0x70FB	#CJK UNIFIED IDEOGRAPH
+0x9F54	0x70FC	#CJK UNIFIED IDEOGRAPH
+0x9F55	0x70FE	#CJK UNIFIED IDEOGRAPH
+0x9F56	0x70FF	#CJK UNIFIED IDEOGRAPH
+0x9F57	0x7100	#CJK UNIFIED IDEOGRAPH
+0x9F58	0x7101	#CJK UNIFIED IDEOGRAPH
+0x9F59	0x7102	#CJK UNIFIED IDEOGRAPH
+0x9F5A	0x7103	#CJK UNIFIED IDEOGRAPH
+0x9F5B	0x7104	#CJK UNIFIED IDEOGRAPH
+0x9F5C	0x7105	#CJK UNIFIED IDEOGRAPH
+0x9F5D	0x7106	#CJK UNIFIED IDEOGRAPH
+0x9F5E	0x7107	#CJK UNIFIED IDEOGRAPH
+0x9F5F	0x7108	#CJK UNIFIED IDEOGRAPH
+0x9F60	0x710B	#CJK UNIFIED IDEOGRAPH
+0x9F61	0x710C	#CJK UNIFIED IDEOGRAPH
+0x9F62	0x710D	#CJK UNIFIED IDEOGRAPH
+0x9F63	0x710E	#CJK UNIFIED IDEOGRAPH
+0x9F64	0x710F	#CJK UNIFIED IDEOGRAPH
+0x9F65	0x7111	#CJK UNIFIED IDEOGRAPH
+0x9F66	0x7112	#CJK UNIFIED IDEOGRAPH
+0x9F67	0x7114	#CJK UNIFIED IDEOGRAPH
+0x9F68	0x7117	#CJK UNIFIED IDEOGRAPH
+0x9F69	0x711B	#CJK UNIFIED IDEOGRAPH
+0x9F6A	0x711C	#CJK UNIFIED IDEOGRAPH
+0x9F6B	0x711D	#CJK UNIFIED IDEOGRAPH
+0x9F6C	0x711E	#CJK UNIFIED IDEOGRAPH
+0x9F6D	0x711F	#CJK UNIFIED IDEOGRAPH
+0x9F6E	0x7120	#CJK UNIFIED IDEOGRAPH
+0x9F6F	0x7121	#CJK UNIFIED IDEOGRAPH
+0x9F70	0x7122	#CJK UNIFIED IDEOGRAPH
+0x9F71	0x7123	#CJK UNIFIED IDEOGRAPH
+0x9F72	0x7124	#CJK UNIFIED IDEOGRAPH
+0x9F73	0x7125	#CJK UNIFIED IDEOGRAPH
+0x9F74	0x7127	#CJK UNIFIED IDEOGRAPH
+0x9F75	0x7128	#CJK UNIFIED IDEOGRAPH
+0x9F76	0x7129	#CJK UNIFIED IDEOGRAPH
+0x9F77	0x712A	#CJK UNIFIED IDEOGRAPH
+0x9F78	0x712B	#CJK UNIFIED IDEOGRAPH
+0x9F79	0x712C	#CJK UNIFIED IDEOGRAPH
+0x9F7A	0x712D	#CJK UNIFIED IDEOGRAPH
+0x9F7B	0x712E	#CJK UNIFIED IDEOGRAPH
+0x9F7C	0x7132	#CJK UNIFIED IDEOGRAPH
+0x9F7D	0x7133	#CJK UNIFIED IDEOGRAPH
+0x9F7E	0x7134	#CJK UNIFIED IDEOGRAPH
+0x9F80	0x7135	#CJK UNIFIED IDEOGRAPH
+0x9F81	0x7137	#CJK UNIFIED IDEOGRAPH
+0x9F82	0x7138	#CJK UNIFIED IDEOGRAPH
+0x9F83	0x7139	#CJK UNIFIED IDEOGRAPH
+0x9F84	0x713A	#CJK UNIFIED IDEOGRAPH
+0x9F85	0x713B	#CJK UNIFIED IDEOGRAPH
+0x9F86	0x713C	#CJK UNIFIED IDEOGRAPH
+0x9F87	0x713D	#CJK UNIFIED IDEOGRAPH
+0x9F88	0x713E	#CJK UNIFIED IDEOGRAPH
+0x9F89	0x713F	#CJK UNIFIED IDEOGRAPH
+0x9F8A	0x7140	#CJK UNIFIED IDEOGRAPH
+0x9F8B	0x7141	#CJK UNIFIED IDEOGRAPH
+0x9F8C	0x7142	#CJK UNIFIED IDEOGRAPH
+0x9F8D	0x7143	#CJK UNIFIED IDEOGRAPH
+0x9F8E	0x7144	#CJK UNIFIED IDEOGRAPH
+0x9F8F	0x7146	#CJK UNIFIED IDEOGRAPH
+0x9F90	0x7147	#CJK UNIFIED IDEOGRAPH
+0x9F91	0x7148	#CJK UNIFIED IDEOGRAPH
+0x9F92	0x7149	#CJK UNIFIED IDEOGRAPH
+0x9F93	0x714B	#CJK UNIFIED IDEOGRAPH
+0x9F94	0x714D	#CJK UNIFIED IDEOGRAPH
+0x9F95	0x714F	#CJK UNIFIED IDEOGRAPH
+0x9F96	0x7150	#CJK UNIFIED IDEOGRAPH
+0x9F97	0x7151	#CJK UNIFIED IDEOGRAPH
+0x9F98	0x7152	#CJK UNIFIED IDEOGRAPH
+0x9F99	0x7153	#CJK UNIFIED IDEOGRAPH
+0x9F9A	0x7154	#CJK UNIFIED IDEOGRAPH
+0x9F9B	0x7155	#CJK UNIFIED IDEOGRAPH
+0x9F9C	0x7156	#CJK UNIFIED IDEOGRAPH
+0x9F9D	0x7157	#CJK UNIFIED IDEOGRAPH
+0x9F9E	0x7158	#CJK UNIFIED IDEOGRAPH
+0x9F9F	0x7159	#CJK UNIFIED IDEOGRAPH
+0x9FA0	0x715A	#CJK UNIFIED IDEOGRAPH
+0x9FA1	0x715B	#CJK UNIFIED IDEOGRAPH
+0x9FA2	0x715D	#CJK UNIFIED IDEOGRAPH
+0x9FA3	0x715F	#CJK UNIFIED IDEOGRAPH
+0x9FA4	0x7160	#CJK UNIFIED IDEOGRAPH
+0x9FA5	0x7161	#CJK UNIFIED IDEOGRAPH
+0x9FA6	0x7162	#CJK UNIFIED IDEOGRAPH
+0x9FA7	0x7163	#CJK UNIFIED IDEOGRAPH
+0x9FA8	0x7165	#CJK UNIFIED IDEOGRAPH
+0x9FA9	0x7169	#CJK UNIFIED IDEOGRAPH
+0x9FAA	0x716A	#CJK UNIFIED IDEOGRAPH
+0x9FAB	0x716B	#CJK UNIFIED IDEOGRAPH
+0x9FAC	0x716C	#CJK UNIFIED IDEOGRAPH
+0x9FAD	0x716D	#CJK UNIFIED IDEOGRAPH
+0x9FAE	0x716F	#CJK UNIFIED IDEOGRAPH
+0x9FAF	0x7170	#CJK UNIFIED IDEOGRAPH
+0x9FB0	0x7171	#CJK UNIFIED IDEOGRAPH
+0x9FB1	0x7174	#CJK UNIFIED IDEOGRAPH
+0x9FB2	0x7175	#CJK UNIFIED IDEOGRAPH
+0x9FB3	0x7176	#CJK UNIFIED IDEOGRAPH
+0x9FB4	0x7177	#CJK UNIFIED IDEOGRAPH
+0x9FB5	0x7179	#CJK UNIFIED IDEOGRAPH
+0x9FB6	0x717B	#CJK UNIFIED IDEOGRAPH
+0x9FB7	0x717C	#CJK UNIFIED IDEOGRAPH
+0x9FB8	0x717E	#CJK UNIFIED IDEOGRAPH
+0x9FB9	0x717F	#CJK UNIFIED IDEOGRAPH
+0x9FBA	0x7180	#CJK UNIFIED IDEOGRAPH
+0x9FBB	0x7181	#CJK UNIFIED IDEOGRAPH
+0x9FBC	0x7182	#CJK UNIFIED IDEOGRAPH
+0x9FBD	0x7183	#CJK UNIFIED IDEOGRAPH
+0x9FBE	0x7185	#CJK UNIFIED IDEOGRAPH
+0x9FBF	0x7186	#CJK UNIFIED IDEOGRAPH
+0x9FC0	0x7187	#CJK UNIFIED IDEOGRAPH
+0x9FC1	0x7188	#CJK UNIFIED IDEOGRAPH
+0x9FC2	0x7189	#CJK UNIFIED IDEOGRAPH
+0x9FC3	0x718B	#CJK UNIFIED IDEOGRAPH
+0x9FC4	0x718C	#CJK UNIFIED IDEOGRAPH
+0x9FC5	0x718D	#CJK UNIFIED IDEOGRAPH
+0x9FC6	0x718E	#CJK UNIFIED IDEOGRAPH
+0x9FC7	0x7190	#CJK UNIFIED IDEOGRAPH
+0x9FC8	0x7191	#CJK UNIFIED IDEOGRAPH
+0x9FC9	0x7192	#CJK UNIFIED IDEOGRAPH
+0x9FCA	0x7193	#CJK UNIFIED IDEOGRAPH
+0x9FCB	0x7195	#CJK UNIFIED IDEOGRAPH
+0x9FCC	0x7196	#CJK UNIFIED IDEOGRAPH
+0x9FCD	0x7197	#CJK UNIFIED IDEOGRAPH
+0x9FCE	0x719A	#CJK UNIFIED IDEOGRAPH
+0x9FCF	0x719B	#CJK UNIFIED IDEOGRAPH
+0x9FD0	0x719C	#CJK UNIFIED IDEOGRAPH
+0x9FD1	0x719D	#CJK UNIFIED IDEOGRAPH
+0x9FD2	0x719E	#CJK UNIFIED IDEOGRAPH
+0x9FD3	0x71A1	#CJK UNIFIED IDEOGRAPH
+0x9FD4	0x71A2	#CJK UNIFIED IDEOGRAPH
+0x9FD5	0x71A3	#CJK UNIFIED IDEOGRAPH
+0x9FD6	0x71A4	#CJK UNIFIED IDEOGRAPH
+0x9FD7	0x71A5	#CJK UNIFIED IDEOGRAPH
+0x9FD8	0x71A6	#CJK UNIFIED IDEOGRAPH
+0x9FD9	0x71A7	#CJK UNIFIED IDEOGRAPH
+0x9FDA	0x71A9	#CJK UNIFIED IDEOGRAPH
+0x9FDB	0x71AA	#CJK UNIFIED IDEOGRAPH
+0x9FDC	0x71AB	#CJK UNIFIED IDEOGRAPH
+0x9FDD	0x71AD	#CJK UNIFIED IDEOGRAPH
+0x9FDE	0x71AE	#CJK UNIFIED IDEOGRAPH
+0x9FDF	0x71AF	#CJK UNIFIED IDEOGRAPH
+0x9FE0	0x71B0	#CJK UNIFIED IDEOGRAPH
+0x9FE1	0x71B1	#CJK UNIFIED IDEOGRAPH
+0x9FE2	0x71B2	#CJK UNIFIED IDEOGRAPH
+0x9FE3	0x71B4	#CJK UNIFIED IDEOGRAPH
+0x9FE4	0x71B6	#CJK UNIFIED IDEOGRAPH
+0x9FE5	0x71B7	#CJK UNIFIED IDEOGRAPH
+0x9FE6	0x71B8	#CJK UNIFIED IDEOGRAPH
+0x9FE7	0x71BA	#CJK UNIFIED IDEOGRAPH
+0x9FE8	0x71BB	#CJK UNIFIED IDEOGRAPH
+0x9FE9	0x71BC	#CJK UNIFIED IDEOGRAPH
+0x9FEA	0x71BD	#CJK UNIFIED IDEOGRAPH
+0x9FEB	0x71BE	#CJK UNIFIED IDEOGRAPH
+0x9FEC	0x71BF	#CJK UNIFIED IDEOGRAPH
+0x9FED	0x71C0	#CJK UNIFIED IDEOGRAPH
+0x9FEE	0x71C1	#CJK UNIFIED IDEOGRAPH
+0x9FEF	0x71C2	#CJK UNIFIED IDEOGRAPH
+0x9FF0	0x71C4	#CJK UNIFIED IDEOGRAPH
+0x9FF1	0x71C5	#CJK UNIFIED IDEOGRAPH
+0x9FF2	0x71C6	#CJK UNIFIED IDEOGRAPH
+0x9FF3	0x71C7	#CJK UNIFIED IDEOGRAPH
+0x9FF4	0x71C8	#CJK UNIFIED IDEOGRAPH
+0x9FF5	0x71C9	#CJK UNIFIED IDEOGRAPH
+0x9FF6	0x71CA	#CJK UNIFIED IDEOGRAPH
+0x9FF7	0x71CB	#CJK UNIFIED IDEOGRAPH
+0x9FF8	0x71CC	#CJK UNIFIED IDEOGRAPH
+0x9FF9	0x71CD	#CJK UNIFIED IDEOGRAPH
+0x9FFA	0x71CF	#CJK UNIFIED IDEOGRAPH
+0x9FFB	0x71D0	#CJK UNIFIED IDEOGRAPH
+0x9FFC	0x71D1	#CJK UNIFIED IDEOGRAPH
+0x9FFD	0x71D2	#CJK UNIFIED IDEOGRAPH
+0x9FFE	0x71D3	#CJK UNIFIED IDEOGRAPH
+0xA040	0x71D6	#CJK UNIFIED IDEOGRAPH
+0xA041	0x71D7	#CJK UNIFIED IDEOGRAPH
+0xA042	0x71D8	#CJK UNIFIED IDEOGRAPH
+0xA043	0x71D9	#CJK UNIFIED IDEOGRAPH
+0xA044	0x71DA	#CJK UNIFIED IDEOGRAPH
+0xA045	0x71DB	#CJK UNIFIED IDEOGRAPH
+0xA046	0x71DC	#CJK UNIFIED IDEOGRAPH
+0xA047	0x71DD	#CJK UNIFIED IDEOGRAPH
+0xA048	0x71DE	#CJK UNIFIED IDEOGRAPH
+0xA049	0x71DF	#CJK UNIFIED IDEOGRAPH
+0xA04A	0x71E1	#CJK UNIFIED IDEOGRAPH
+0xA04B	0x71E2	#CJK UNIFIED IDEOGRAPH
+0xA04C	0x71E3	#CJK UNIFIED IDEOGRAPH
+0xA04D	0x71E4	#CJK UNIFIED IDEOGRAPH
+0xA04E	0x71E6	#CJK UNIFIED IDEOGRAPH
+0xA04F	0x71E8	#CJK UNIFIED IDEOGRAPH
+0xA050	0x71E9	#CJK UNIFIED IDEOGRAPH
+0xA051	0x71EA	#CJK UNIFIED IDEOGRAPH
+0xA052	0x71EB	#CJK UNIFIED IDEOGRAPH
+0xA053	0x71EC	#CJK UNIFIED IDEOGRAPH
+0xA054	0x71ED	#CJK UNIFIED IDEOGRAPH
+0xA055	0x71EF	#CJK UNIFIED IDEOGRAPH
+0xA056	0x71F0	#CJK UNIFIED IDEOGRAPH
+0xA057	0x71F1	#CJK UNIFIED IDEOGRAPH
+0xA058	0x71F2	#CJK UNIFIED IDEOGRAPH
+0xA059	0x71F3	#CJK UNIFIED IDEOGRAPH
+0xA05A	0x71F4	#CJK UNIFIED IDEOGRAPH
+0xA05B	0x71F5	#CJK UNIFIED IDEOGRAPH
+0xA05C	0x71F6	#CJK UNIFIED IDEOGRAPH
+0xA05D	0x71F7	#CJK UNIFIED IDEOGRAPH
+0xA05E	0x71F8	#CJK UNIFIED IDEOGRAPH
+0xA05F	0x71FA	#CJK UNIFIED IDEOGRAPH
+0xA060	0x71FB	#CJK UNIFIED IDEOGRAPH
+0xA061	0x71FC	#CJK UNIFIED IDEOGRAPH
+0xA062	0x71FD	#CJK UNIFIED IDEOGRAPH
+0xA063	0x71FE	#CJK UNIFIED IDEOGRAPH
+0xA064	0x71FF	#CJK UNIFIED IDEOGRAPH
+0xA065	0x7200	#CJK UNIFIED IDEOGRAPH
+0xA066	0x7201	#CJK UNIFIED IDEOGRAPH
+0xA067	0x7202	#CJK UNIFIED IDEOGRAPH
+0xA068	0x7203	#CJK UNIFIED IDEOGRAPH
+0xA069	0x7204	#CJK UNIFIED IDEOGRAPH
+0xA06A	0x7205	#CJK UNIFIED IDEOGRAPH
+0xA06B	0x7207	#CJK UNIFIED IDEOGRAPH
+0xA06C	0x7208	#CJK UNIFIED IDEOGRAPH
+0xA06D	0x7209	#CJK UNIFIED IDEOGRAPH
+0xA06E	0x720A	#CJK UNIFIED IDEOGRAPH
+0xA06F	0x720B	#CJK UNIFIED IDEOGRAPH
+0xA070	0x720C	#CJK UNIFIED IDEOGRAPH
+0xA071	0x720D	#CJK UNIFIED IDEOGRAPH
+0xA072	0x720E	#CJK UNIFIED IDEOGRAPH
+0xA073	0x720F	#CJK UNIFIED IDEOGRAPH
+0xA074	0x7210	#CJK UNIFIED IDEOGRAPH
+0xA075	0x7211	#CJK UNIFIED IDEOGRAPH
+0xA076	0x7212	#CJK UNIFIED IDEOGRAPH
+0xA077	0x7213	#CJK UNIFIED IDEOGRAPH
+0xA078	0x7214	#CJK UNIFIED IDEOGRAPH
+0xA079	0x7215	#CJK UNIFIED IDEOGRAPH
+0xA07A	0x7216	#CJK UNIFIED IDEOGRAPH
+0xA07B	0x7217	#CJK UNIFIED IDEOGRAPH
+0xA07C	0x7218	#CJK UNIFIED IDEOGRAPH
+0xA07D	0x7219	#CJK UNIFIED IDEOGRAPH
+0xA07E	0x721A	#CJK UNIFIED IDEOGRAPH
+0xA080	0x721B	#CJK UNIFIED IDEOGRAPH
+0xA081	0x721C	#CJK UNIFIED IDEOGRAPH
+0xA082	0x721E	#CJK UNIFIED IDEOGRAPH
+0xA083	0x721F	#CJK UNIFIED IDEOGRAPH
+0xA084	0x7220	#CJK UNIFIED IDEOGRAPH
+0xA085	0x7221	#CJK UNIFIED IDEOGRAPH
+0xA086	0x7222	#CJK UNIFIED IDEOGRAPH
+0xA087	0x7223	#CJK UNIFIED IDEOGRAPH
+0xA088	0x7224	#CJK UNIFIED IDEOGRAPH
+0xA089	0x7225	#CJK UNIFIED IDEOGRAPH
+0xA08A	0x7226	#CJK UNIFIED IDEOGRAPH
+0xA08B	0x7227	#CJK UNIFIED IDEOGRAPH
+0xA08C	0x7229	#CJK UNIFIED IDEOGRAPH
+0xA08D	0x722B	#CJK UNIFIED IDEOGRAPH
+0xA08E	0x722D	#CJK UNIFIED IDEOGRAPH
+0xA08F	0x722E	#CJK UNIFIED IDEOGRAPH
+0xA090	0x722F	#CJK UNIFIED IDEOGRAPH
+0xA091	0x7232	#CJK UNIFIED IDEOGRAPH
+0xA092	0x7233	#CJK UNIFIED IDEOGRAPH
+0xA093	0x7234	#CJK UNIFIED IDEOGRAPH
+0xA094	0x723A	#CJK UNIFIED IDEOGRAPH
+0xA095	0x723C	#CJK UNIFIED IDEOGRAPH
+0xA096	0x723E	#CJK UNIFIED IDEOGRAPH
+0xA097	0x7240	#CJK UNIFIED IDEOGRAPH
+0xA098	0x7241	#CJK UNIFIED IDEOGRAPH
+0xA099	0x7242	#CJK UNIFIED IDEOGRAPH
+0xA09A	0x7243	#CJK UNIFIED IDEOGRAPH
+0xA09B	0x7244	#CJK UNIFIED IDEOGRAPH
+0xA09C	0x7245	#CJK UNIFIED IDEOGRAPH
+0xA09D	0x7246	#CJK UNIFIED IDEOGRAPH
+0xA09E	0x7249	#CJK UNIFIED IDEOGRAPH
+0xA09F	0x724A	#CJK UNIFIED IDEOGRAPH
+0xA0A0	0x724B	#CJK UNIFIED IDEOGRAPH
+0xA0A1	0x724E	#CJK UNIFIED IDEOGRAPH
+0xA0A2	0x724F	#CJK UNIFIED IDEOGRAPH
+0xA0A3	0x7250	#CJK UNIFIED IDEOGRAPH
+0xA0A4	0x7251	#CJK UNIFIED IDEOGRAPH
+0xA0A5	0x7253	#CJK UNIFIED IDEOGRAPH
+0xA0A6	0x7254	#CJK UNIFIED IDEOGRAPH
+0xA0A7	0x7255	#CJK UNIFIED IDEOGRAPH
+0xA0A8	0x7257	#CJK UNIFIED IDEOGRAPH
+0xA0A9	0x7258	#CJK UNIFIED IDEOGRAPH
+0xA0AA	0x725A	#CJK UNIFIED IDEOGRAPH
+0xA0AB	0x725C	#CJK UNIFIED IDEOGRAPH
+0xA0AC	0x725E	#CJK UNIFIED IDEOGRAPH
+0xA0AD	0x7260	#CJK UNIFIED IDEOGRAPH
+0xA0AE	0x7263	#CJK UNIFIED IDEOGRAPH
+0xA0AF	0x7264	#CJK UNIFIED IDEOGRAPH
+0xA0B0	0x7265	#CJK UNIFIED IDEOGRAPH
+0xA0B1	0x7268	#CJK UNIFIED IDEOGRAPH
+0xA0B2	0x726A	#CJK UNIFIED IDEOGRAPH
+0xA0B3	0x726B	#CJK UNIFIED IDEOGRAPH
+0xA0B4	0x726C	#CJK UNIFIED IDEOGRAPH
+0xA0B5	0x726D	#CJK UNIFIED IDEOGRAPH
+0xA0B6	0x7270	#CJK UNIFIED IDEOGRAPH
+0xA0B7	0x7271	#CJK UNIFIED IDEOGRAPH
+0xA0B8	0x7273	#CJK UNIFIED IDEOGRAPH
+0xA0B9	0x7274	#CJK UNIFIED IDEOGRAPH
+0xA0BA	0x7276	#CJK UNIFIED IDEOGRAPH
+0xA0BB	0x7277	#CJK UNIFIED IDEOGRAPH
+0xA0BC	0x7278	#CJK UNIFIED IDEOGRAPH
+0xA0BD	0x727B	#CJK UNIFIED IDEOGRAPH
+0xA0BE	0x727C	#CJK UNIFIED IDEOGRAPH
+0xA0BF	0x727D	#CJK UNIFIED IDEOGRAPH
+0xA0C0	0x7282	#CJK UNIFIED IDEOGRAPH
+0xA0C1	0x7283	#CJK UNIFIED IDEOGRAPH
+0xA0C2	0x7285	#CJK UNIFIED IDEOGRAPH
+0xA0C3	0x7286	#CJK UNIFIED IDEOGRAPH
+0xA0C4	0x7287	#CJK UNIFIED IDEOGRAPH
+0xA0C5	0x7288	#CJK UNIFIED IDEOGRAPH
+0xA0C6	0x7289	#CJK UNIFIED IDEOGRAPH
+0xA0C7	0x728C	#CJK UNIFIED IDEOGRAPH
+0xA0C8	0x728E	#CJK UNIFIED IDEOGRAPH
+0xA0C9	0x7290	#CJK UNIFIED IDEOGRAPH
+0xA0CA	0x7291	#CJK UNIFIED IDEOGRAPH
+0xA0CB	0x7293	#CJK UNIFIED IDEOGRAPH
+0xA0CC	0x7294	#CJK UNIFIED IDEOGRAPH
+0xA0CD	0x7295	#CJK UNIFIED IDEOGRAPH
+0xA0CE	0x7296	#CJK UNIFIED IDEOGRAPH
+0xA0CF	0x7297	#CJK UNIFIED IDEOGRAPH
+0xA0D0	0x7298	#CJK UNIFIED IDEOGRAPH
+0xA0D1	0x7299	#CJK UNIFIED IDEOGRAPH
+0xA0D2	0x729A	#CJK UNIFIED IDEOGRAPH
+0xA0D3	0x729B	#CJK UNIFIED IDEOGRAPH
+0xA0D4	0x729C	#CJK UNIFIED IDEOGRAPH
+0xA0D5	0x729D	#CJK UNIFIED IDEOGRAPH
+0xA0D6	0x729E	#CJK UNIFIED IDEOGRAPH
+0xA0D7	0x72A0	#CJK UNIFIED IDEOGRAPH
+0xA0D8	0x72A1	#CJK UNIFIED IDEOGRAPH
+0xA0D9	0x72A2	#CJK UNIFIED IDEOGRAPH
+0xA0DA	0x72A3	#CJK UNIFIED IDEOGRAPH
+0xA0DB	0x72A4	#CJK UNIFIED IDEOGRAPH
+0xA0DC	0x72A5	#CJK UNIFIED IDEOGRAPH
+0xA0DD	0x72A6	#CJK UNIFIED IDEOGRAPH
+0xA0DE	0x72A7	#CJK UNIFIED IDEOGRAPH
+0xA0DF	0x72A8	#CJK UNIFIED IDEOGRAPH
+0xA0E0	0x72A9	#CJK UNIFIED IDEOGRAPH
+0xA0E1	0x72AA	#CJK UNIFIED IDEOGRAPH
+0xA0E2	0x72AB	#CJK UNIFIED IDEOGRAPH
+0xA0E3	0x72AE	#CJK UNIFIED IDEOGRAPH
+0xA0E4	0x72B1	#CJK UNIFIED IDEOGRAPH
+0xA0E5	0x72B2	#CJK UNIFIED IDEOGRAPH
+0xA0E6	0x72B3	#CJK UNIFIED IDEOGRAPH
+0xA0E7	0x72B5	#CJK UNIFIED IDEOGRAPH
+0xA0E8	0x72BA	#CJK UNIFIED IDEOGRAPH
+0xA0E9	0x72BB	#CJK UNIFIED IDEOGRAPH
+0xA0EA	0x72BC	#CJK UNIFIED IDEOGRAPH
+0xA0EB	0x72BD	#CJK UNIFIED IDEOGRAPH
+0xA0EC	0x72BE	#CJK UNIFIED IDEOGRAPH
+0xA0ED	0x72BF	#CJK UNIFIED IDEOGRAPH
+0xA0EE	0x72C0	#CJK UNIFIED IDEOGRAPH
+0xA0EF	0x72C5	#CJK UNIFIED IDEOGRAPH
+0xA0F0	0x72C6	#CJK UNIFIED IDEOGRAPH
+0xA0F1	0x72C7	#CJK UNIFIED IDEOGRAPH
+0xA0F2	0x72C9	#CJK UNIFIED IDEOGRAPH
+0xA0F3	0x72CA	#CJK UNIFIED IDEOGRAPH
+0xA0F4	0x72CB	#CJK UNIFIED IDEOGRAPH
+0xA0F5	0x72CC	#CJK UNIFIED IDEOGRAPH
+0xA0F6	0x72CF	#CJK UNIFIED IDEOGRAPH
+0xA0F7	0x72D1	#CJK UNIFIED IDEOGRAPH
+0xA0F8	0x72D3	#CJK UNIFIED IDEOGRAPH
+0xA0F9	0x72D4	#CJK UNIFIED IDEOGRAPH
+0xA0FA	0x72D5	#CJK UNIFIED IDEOGRAPH
+0xA0FB	0x72D6	#CJK UNIFIED IDEOGRAPH
+0xA0FC	0x72D8	#CJK UNIFIED IDEOGRAPH
+0xA0FD	0x72DA	#CJK UNIFIED IDEOGRAPH
+0xA0FE	0x72DB	#CJK UNIFIED IDEOGRAPH
+0xA1A1	0x3000	#IDEOGRAPHIC SPACE
+0xA1A2	0x3001	#IDEOGRAPHIC COMMA
+0xA1A3	0x3002	#IDEOGRAPHIC FULL STOP
+0xA1A4	0x00B7	#MIDDLE DOT
+0xA1A5	0x02C9	#MODIFIER LETTER MACRON
+0xA1A6	0x02C7	#CARON
+0xA1A7	0x00A8	#DIAERESIS
+0xA1A8	0x3003	#DITTO MARK
+0xA1A9	0x3005	#IDEOGRAPHIC ITERATION MARK
+0xA1AA	0x2014	#EM DASH
+0xA1AB	0xFF5E	#FULLWIDTH TILDE
+0xA1AC	0x2016	#DOUBLE VERTICAL LINE
+0xA1AD	0x2026	#HORIZONTAL ELLIPSIS
+0xA1AE	0x2018	#LEFT SINGLE QUOTATION MARK
+0xA1AF	0x2019	#RIGHT SINGLE QUOTATION MARK
+0xA1B0	0x201C	#LEFT DOUBLE QUOTATION MARK
+0xA1B1	0x201D	#RIGHT DOUBLE QUOTATION MARK
+0xA1B2	0x3014	#LEFT TORTOISE SHELL BRACKET
+0xA1B3	0x3015	#RIGHT TORTOISE SHELL BRACKET
+0xA1B4	0x3008	#LEFT ANGLE BRACKET
+0xA1B5	0x3009	#RIGHT ANGLE BRACKET
+0xA1B6	0x300A	#LEFT DOUBLE ANGLE BRACKET
+0xA1B7	0x300B	#RIGHT DOUBLE ANGLE BRACKET
+0xA1B8	0x300C	#LEFT CORNER BRACKET
+0xA1B9	0x300D	#RIGHT CORNER BRACKET
+0xA1BA	0x300E	#LEFT WHITE CORNER BRACKET
+0xA1BB	0x300F	#RIGHT WHITE CORNER BRACKET
+0xA1BC	0x3016	#LEFT WHITE LENTICULAR BRACKET
+0xA1BD	0x3017	#RIGHT WHITE LENTICULAR BRACKET
+0xA1BE	0x3010	#LEFT BLACK LENTICULAR BRACKET
+0xA1BF	0x3011	#RIGHT BLACK LENTICULAR BRACKET
+0xA1C0	0x00B1	#PLUS-MINUS SIGN
+0xA1C1	0x00D7	#MULTIPLICATION SIGN
+0xA1C2	0x00F7	#DIVISION SIGN
+0xA1C3	0x2236	#RATIO
+0xA1C4	0x2227	#LOGICAL AND
+0xA1C5	0x2228	#LOGICAL OR
+0xA1C6	0x2211	#N-ARY SUMMATION
+0xA1C7	0x220F	#N-ARY PRODUCT
+0xA1C8	0x222A	#UNION
+0xA1C9	0x2229	#INTERSECTION
+0xA1CA	0x2208	#ELEMENT OF
+0xA1CB	0x2237	#PROPORTION
+0xA1CC	0x221A	#SQUARE ROOT
+0xA1CD	0x22A5	#UP TACK
+0xA1CE	0x2225	#PARALLEL TO
+0xA1CF	0x2220	#ANGLE
+0xA1D0	0x2312	#ARC
+0xA1D1	0x2299	#CIRCLED DOT OPERATOR
+0xA1D2	0x222B	#INTEGRAL
+0xA1D3	0x222E	#CONTOUR INTEGRAL
+0xA1D4	0x2261	#IDENTICAL TO
+0xA1D5	0x224C	#ALL EQUAL TO
+0xA1D6	0x2248	#ALMOST EQUAL TO
+0xA1D7	0x223D	#REVERSED TILDE
+0xA1D8	0x221D	#PROPORTIONAL TO
+0xA1D9	0x2260	#NOT EQUAL TO
+0xA1DA	0x226E	#NOT LESS-THAN
+0xA1DB	0x226F	#NOT GREATER-THAN
+0xA1DC	0x2264	#LESS-THAN OR EQUAL TO
+0xA1DD	0x2265	#GREATER-THAN OR EQUAL TO
+0xA1DE	0x221E	#INFINITY
+0xA1DF	0x2235	#BECAUSE
+0xA1E0	0x2234	#THEREFORE
+0xA1E1	0x2642	#MALE SIGN
+0xA1E2	0x2640	#FEMALE SIGN
+0xA1E3	0x00B0	#DEGREE SIGN
+0xA1E4	0x2032	#PRIME
+0xA1E5	0x2033	#DOUBLE PRIME
+0xA1E6	0x2103	#DEGREE CELSIUS
+0xA1E7	0xFF04	#FULLWIDTH DOLLAR SIGN
+0xA1E8	0x00A4	#CURRENCY SIGN
+0xA1E9	0xFFE0	#FULLWIDTH CENT SIGN
+0xA1EA	0xFFE1	#FULLWIDTH POUND SIGN
+0xA1EB	0x2030	#PER MILLE SIGN
+0xA1EC	0x00A7	#SECTION SIGN
+0xA1ED	0x2116	#NUMERO SIGN
+0xA1EE	0x2606	#WHITE STAR
+0xA1EF	0x2605	#BLACK STAR
+0xA1F0	0x25CB	#WHITE CIRCLE
+0xA1F1	0x25CF	#BLACK CIRCLE
+0xA1F2	0x25CE	#BULLSEYE
+0xA1F3	0x25C7	#WHITE DIAMOND
+0xA1F4	0x25C6	#BLACK DIAMOND
+0xA1F5	0x25A1	#WHITE SQUARE
+0xA1F6	0x25A0	#BLACK SQUARE
+0xA1F7	0x25B3	#WHITE UP-POINTING TRIANGLE
+0xA1F8	0x25B2	#BLACK UP-POINTING TRIANGLE
+0xA1F9	0x203B	#REFERENCE MARK
+0xA1FA	0x2192	#RIGHTWARDS ARROW
+0xA1FB	0x2190	#LEFTWARDS ARROW
+0xA1FC	0x2191	#UPWARDS ARROW
+0xA1FD	0x2193	#DOWNWARDS ARROW
+0xA1FE	0x3013	#GETA MARK
+0xA2A1	0x2170	#SMALL ROMAN NUMERAL ONE
+0xA2A2	0x2171	#SMALL ROMAN NUMERAL TWO
+0xA2A3	0x2172	#SMALL ROMAN NUMERAL THREE
+0xA2A4	0x2173	#SMALL ROMAN NUMERAL FOUR
+0xA2A5	0x2174	#SMALL ROMAN NUMERAL FIVE
+0xA2A6	0x2175	#SMALL ROMAN NUMERAL SIX
+0xA2A7	0x2176	#SMALL ROMAN NUMERAL SEVEN
+0xA2A8	0x2177	#SMALL ROMAN NUMERAL EIGHT
+0xA2A9	0x2178	#SMALL ROMAN NUMERAL NINE
+0xA2AA	0x2179	#SMALL ROMAN NUMERAL TEN
+0xA2B1	0x2488	#DIGIT ONE FULL STOP
+0xA2B2	0x2489	#DIGIT TWO FULL STOP
+0xA2B3	0x248A	#DIGIT THREE FULL STOP
+0xA2B4	0x248B	#DIGIT FOUR FULL STOP
+0xA2B5	0x248C	#DIGIT FIVE FULL STOP
+0xA2B6	0x248D	#DIGIT SIX FULL STOP
+0xA2B7	0x248E	#DIGIT SEVEN FULL STOP
+0xA2B8	0x248F	#DIGIT EIGHT FULL STOP
+0xA2B9	0x2490	#DIGIT NINE FULL STOP
+0xA2BA	0x2491	#NUMBER TEN FULL STOP
+0xA2BB	0x2492	#NUMBER ELEVEN FULL STOP
+0xA2BC	0x2493	#NUMBER TWELVE FULL STOP
+0xA2BD	0x2494	#NUMBER THIRTEEN FULL STOP
+0xA2BE	0x2495	#NUMBER FOURTEEN FULL STOP
+0xA2BF	0x2496	#NUMBER FIFTEEN FULL STOP
+0xA2C0	0x2497	#NUMBER SIXTEEN FULL STOP
+0xA2C1	0x2498	#NUMBER SEVENTEEN FULL STOP
+0xA2C2	0x2499	#NUMBER EIGHTEEN FULL STOP
+0xA2C3	0x249A	#NUMBER NINETEEN FULL STOP
+0xA2C4	0x249B	#NUMBER TWENTY FULL STOP
+0xA2C5	0x2474	#PARENTHESIZED DIGIT ONE
+0xA2C6	0x2475	#PARENTHESIZED DIGIT TWO
+0xA2C7	0x2476	#PARENTHESIZED DIGIT THREE
+0xA2C8	0x2477	#PARENTHESIZED DIGIT FOUR
+0xA2C9	0x2478	#PARENTHESIZED DIGIT FIVE
+0xA2CA	0x2479	#PARENTHESIZED DIGIT SIX
+0xA2CB	0x247A	#PARENTHESIZED DIGIT SEVEN
+0xA2CC	0x247B	#PARENTHESIZED DIGIT EIGHT
+0xA2CD	0x247C	#PARENTHESIZED DIGIT NINE
+0xA2CE	0x247D	#PARENTHESIZED NUMBER TEN
+0xA2CF	0x247E	#PARENTHESIZED NUMBER ELEVEN
+0xA2D0	0x247F	#PARENTHESIZED NUMBER TWELVE
+0xA2D1	0x2480	#PARENTHESIZED NUMBER THIRTEEN
+0xA2D2	0x2481	#PARENTHESIZED NUMBER FOURTEEN
+0xA2D3	0x2482	#PARENTHESIZED NUMBER FIFTEEN
+0xA2D4	0x2483	#PARENTHESIZED NUMBER SIXTEEN
+0xA2D5	0x2484	#PARENTHESIZED NUMBER SEVENTEEN
+0xA2D6	0x2485	#PARENTHESIZED NUMBER EIGHTEEN
+0xA2D7	0x2486	#PARENTHESIZED NUMBER NINETEEN
+0xA2D8	0x2487	#PARENTHESIZED NUMBER TWENTY
+0xA2D9	0x2460	#CIRCLED DIGIT ONE
+0xA2DA	0x2461	#CIRCLED DIGIT TWO
+0xA2DB	0x2462	#CIRCLED DIGIT THREE
+0xA2DC	0x2463	#CIRCLED DIGIT FOUR
+0xA2DD	0x2464	#CIRCLED DIGIT FIVE
+0xA2DE	0x2465	#CIRCLED DIGIT SIX
+0xA2DF	0x2466	#CIRCLED DIGIT SEVEN
+0xA2E0	0x2467	#CIRCLED DIGIT EIGHT
+0xA2E1	0x2468	#CIRCLED DIGIT NINE
+0xA2E2	0x2469	#CIRCLED NUMBER TEN
+0xA2E5	0x3220	#PARENTHESIZED IDEOGRAPH ONE
+0xA2E6	0x3221	#PARENTHESIZED IDEOGRAPH TWO
+0xA2E7	0x3222	#PARENTHESIZED IDEOGRAPH THREE
+0xA2E8	0x3223	#PARENTHESIZED IDEOGRAPH FOUR
+0xA2E9	0x3224	#PARENTHESIZED IDEOGRAPH FIVE
+0xA2EA	0x3225	#PARENTHESIZED IDEOGRAPH SIX
+0xA2EB	0x3226	#PARENTHESIZED IDEOGRAPH SEVEN
+0xA2EC	0x3227	#PARENTHESIZED IDEOGRAPH EIGHT
+0xA2ED	0x3228	#PARENTHESIZED IDEOGRAPH NINE
+0xA2EE	0x3229	#PARENTHESIZED IDEOGRAPH TEN
+0xA2F1	0x2160	#ROMAN NUMERAL ONE
+0xA2F2	0x2161	#ROMAN NUMERAL TWO
+0xA2F3	0x2162	#ROMAN NUMERAL THREE
+0xA2F4	0x2163	#ROMAN NUMERAL FOUR
+0xA2F5	0x2164	#ROMAN NUMERAL FIVE
+0xA2F6	0x2165	#ROMAN NUMERAL SIX
+0xA2F7	0x2166	#ROMAN NUMERAL SEVEN
+0xA2F8	0x2167	#ROMAN NUMERAL EIGHT
+0xA2F9	0x2168	#ROMAN NUMERAL NINE
+0xA2FA	0x2169	#ROMAN NUMERAL TEN
+0xA2FB	0x216A	#ROMAN NUMERAL ELEVEN
+0xA2FC	0x216B	#ROMAN NUMERAL TWELVE
+0xA3A1	0xFF01	#FULLWIDTH EXCLAMATION MARK
+0xA3A2	0xFF02	#FULLWIDTH QUOTATION MARK
+0xA3A3	0xFF03	#FULLWIDTH NUMBER SIGN
+0xA3A4	0xFFE5	#FULLWIDTH YEN SIGN
+0xA3A5	0xFF05	#FULLWIDTH PERCENT SIGN
+0xA3A6	0xFF06	#FULLWIDTH AMPERSAND
+0xA3A7	0xFF07	#FULLWIDTH APOSTROPHE
+0xA3A8	0xFF08	#FULLWIDTH LEFT PARENTHESIS
+0xA3A9	0xFF09	#FULLWIDTH RIGHT PARENTHESIS
+0xA3AA	0xFF0A	#FULLWIDTH ASTERISK
+0xA3AB	0xFF0B	#FULLWIDTH PLUS SIGN
+0xA3AC	0xFF0C	#FULLWIDTH COMMA
+0xA3AD	0xFF0D	#FULLWIDTH HYPHEN-MINUS
+0xA3AE	0xFF0E	#FULLWIDTH FULL STOP
+0xA3AF	0xFF0F	#FULLWIDTH SOLIDUS
+0xA3B0	0xFF10	#FULLWIDTH DIGIT ZERO
+0xA3B1	0xFF11	#FULLWIDTH DIGIT ONE
+0xA3B2	0xFF12	#FULLWIDTH DIGIT TWO
+0xA3B3	0xFF13	#FULLWIDTH DIGIT THREE
+0xA3B4	0xFF14	#FULLWIDTH DIGIT FOUR
+0xA3B5	0xFF15	#FULLWIDTH DIGIT FIVE
+0xA3B6	0xFF16	#FULLWIDTH DIGIT SIX
+0xA3B7	0xFF17	#FULLWIDTH DIGIT SEVEN
+0xA3B8	0xFF18	#FULLWIDTH DIGIT EIGHT
+0xA3B9	0xFF19	#FULLWIDTH DIGIT NINE
+0xA3BA	0xFF1A	#FULLWIDTH COLON
+0xA3BB	0xFF1B	#FULLWIDTH SEMICOLON
+0xA3BC	0xFF1C	#FULLWIDTH LESS-THAN SIGN
+0xA3BD	0xFF1D	#FULLWIDTH EQUALS SIGN
+0xA3BE	0xFF1E	#FULLWIDTH GREATER-THAN SIGN
+0xA3BF	0xFF1F	#FULLWIDTH QUESTION MARK
+0xA3C0	0xFF20	#FULLWIDTH COMMERCIAL AT
+0xA3C1	0xFF21	#FULLWIDTH LATIN CAPITAL LETTER A
+0xA3C2	0xFF22	#FULLWIDTH LATIN CAPITAL LETTER B
+0xA3C3	0xFF23	#FULLWIDTH LATIN CAPITAL LETTER C
+0xA3C4	0xFF24	#FULLWIDTH LATIN CAPITAL LETTER D
+0xA3C5	0xFF25	#FULLWIDTH LATIN CAPITAL LETTER E
+0xA3C6	0xFF26	#FULLWIDTH LATIN CAPITAL LETTER F
+0xA3C7	0xFF27	#FULLWIDTH LATIN CAPITAL LETTER G
+0xA3C8	0xFF28	#FULLWIDTH LATIN CAPITAL LETTER H
+0xA3C9	0xFF29	#FULLWIDTH LATIN CAPITAL LETTER I
+0xA3CA	0xFF2A	#FULLWIDTH LATIN CAPITAL LETTER J
+0xA3CB	0xFF2B	#FULLWIDTH LATIN CAPITAL LETTER K
+0xA3CC	0xFF2C	#FULLWIDTH LATIN CAPITAL LETTER L
+0xA3CD	0xFF2D	#FULLWIDTH LATIN CAPITAL LETTER M
+0xA3CE	0xFF2E	#FULLWIDTH LATIN CAPITAL LETTER N
+0xA3CF	0xFF2F	#FULLWIDTH LATIN CAPITAL LETTER O
+0xA3D0	0xFF30	#FULLWIDTH LATIN CAPITAL LETTER P
+0xA3D1	0xFF31	#FULLWIDTH LATIN CAPITAL LETTER Q
+0xA3D2	0xFF32	#FULLWIDTH LATIN CAPITAL LETTER R
+0xA3D3	0xFF33	#FULLWIDTH LATIN CAPITAL LETTER S
+0xA3D4	0xFF34	#FULLWIDTH LATIN CAPITAL LETTER T
+0xA3D5	0xFF35	#FULLWIDTH LATIN CAPITAL LETTER U
+0xA3D6	0xFF36	#FULLWIDTH LATIN CAPITAL LETTER V
+0xA3D7	0xFF37	#FULLWIDTH LATIN CAPITAL LETTER W
+0xA3D8	0xFF38	#FULLWIDTH LATIN CAPITAL LETTER X
+0xA3D9	0xFF39	#FULLWIDTH LATIN CAPITAL LETTER Y
+0xA3DA	0xFF3A	#FULLWIDTH LATIN CAPITAL LETTER Z
+0xA3DB	0xFF3B	#FULLWIDTH LEFT SQUARE BRACKET
+0xA3DC	0xFF3C	#FULLWIDTH REVERSE SOLIDUS
+0xA3DD	0xFF3D	#FULLWIDTH RIGHT SQUARE BRACKET
+0xA3DE	0xFF3E	#FULLWIDTH CIRCUMFLEX ACCENT
+0xA3DF	0xFF3F	#FULLWIDTH LOW LINE
+0xA3E0	0xFF40	#FULLWIDTH GRAVE ACCENT
+0xA3E1	0xFF41	#FULLWIDTH LATIN SMALL LETTER A
+0xA3E2	0xFF42	#FULLWIDTH LATIN SMALL LETTER B
+0xA3E3	0xFF43	#FULLWIDTH LATIN SMALL LETTER C
+0xA3E4	0xFF44	#FULLWIDTH LATIN SMALL LETTER D
+0xA3E5	0xFF45	#FULLWIDTH LATIN SMALL LETTER E
+0xA3E6	0xFF46	#FULLWIDTH LATIN SMALL LETTER F
+0xA3E7	0xFF47	#FULLWIDTH LATIN SMALL LETTER G
+0xA3E8	0xFF48	#FULLWIDTH LATIN SMALL LETTER H
+0xA3E9	0xFF49	#FULLWIDTH LATIN SMALL LETTER I
+0xA3EA	0xFF4A	#FULLWIDTH LATIN SMALL LETTER J
+0xA3EB	0xFF4B	#FULLWIDTH LATIN SMALL LETTER K
+0xA3EC	0xFF4C	#FULLWIDTH LATIN SMALL LETTER L
+0xA3ED	0xFF4D	#FULLWIDTH LATIN SMALL LETTER M
+0xA3EE	0xFF4E	#FULLWIDTH LATIN SMALL LETTER N
+0xA3EF	0xFF4F	#FULLWIDTH LATIN SMALL LETTER O
+0xA3F0	0xFF50	#FULLWIDTH LATIN SMALL LETTER P
+0xA3F1	0xFF51	#FULLWIDTH LATIN SMALL LETTER Q
+0xA3F2	0xFF52	#FULLWIDTH LATIN SMALL LETTER R
+0xA3F3	0xFF53	#FULLWIDTH LATIN SMALL LETTER S
+0xA3F4	0xFF54	#FULLWIDTH LATIN SMALL LETTER T
+0xA3F5	0xFF55	#FULLWIDTH LATIN SMALL LETTER U
+0xA3F6	0xFF56	#FULLWIDTH LATIN SMALL LETTER V
+0xA3F7	0xFF57	#FULLWIDTH LATIN SMALL LETTER W
+0xA3F8	0xFF58	#FULLWIDTH LATIN SMALL LETTER X
+0xA3F9	0xFF59	#FULLWIDTH LATIN SMALL LETTER Y
+0xA3FA	0xFF5A	#FULLWIDTH LATIN SMALL LETTER Z
+0xA3FB	0xFF5B	#FULLWIDTH LEFT CURLY BRACKET
+0xA3FC	0xFF5C	#FULLWIDTH VERTICAL LINE
+0xA3FD	0xFF5D	#FULLWIDTH RIGHT CURLY BRACKET
+0xA3FE	0xFFE3	#FULLWIDTH MACRON
+0xA4A1	0x3041	#HIRAGANA LETTER SMALL A
+0xA4A2	0x3042	#HIRAGANA LETTER A
+0xA4A3	0x3043	#HIRAGANA LETTER SMALL I
+0xA4A4	0x3044	#HIRAGANA LETTER I
+0xA4A5	0x3045	#HIRAGANA LETTER SMALL U
+0xA4A6	0x3046	#HIRAGANA LETTER U
+0xA4A7	0x3047	#HIRAGANA LETTER SMALL E
+0xA4A8	0x3048	#HIRAGANA LETTER E
+0xA4A9	0x3049	#HIRAGANA LETTER SMALL O
+0xA4AA	0x304A	#HIRAGANA LETTER O
+0xA4AB	0x304B	#HIRAGANA LETTER KA
+0xA4AC	0x304C	#HIRAGANA LETTER GA
+0xA4AD	0x304D	#HIRAGANA LETTER KI
+0xA4AE	0x304E	#HIRAGANA LETTER GI
+0xA4AF	0x304F	#HIRAGANA LETTER KU
+0xA4B0	0x3050	#HIRAGANA LETTER GU
+0xA4B1	0x3051	#HIRAGANA LETTER KE
+0xA4B2	0x3052	#HIRAGANA LETTER GE
+0xA4B3	0x3053	#HIRAGANA LETTER KO
+0xA4B4	0x3054	#HIRAGANA LETTER GO
+0xA4B5	0x3055	#HIRAGANA LETTER SA
+0xA4B6	0x3056	#HIRAGANA LETTER ZA
+0xA4B7	0x3057	#HIRAGANA LETTER SI
+0xA4B8	0x3058	#HIRAGANA LETTER ZI
+0xA4B9	0x3059	#HIRAGANA LETTER SU
+0xA4BA	0x305A	#HIRAGANA LETTER ZU
+0xA4BB	0x305B	#HIRAGANA LETTER SE
+0xA4BC	0x305C	#HIRAGANA LETTER ZE
+0xA4BD	0x305D	#HIRAGANA LETTER SO
+0xA4BE	0x305E	#HIRAGANA LETTER ZO
+0xA4BF	0x305F	#HIRAGANA LETTER TA
+0xA4C0	0x3060	#HIRAGANA LETTER DA
+0xA4C1	0x3061	#HIRAGANA LETTER TI
+0xA4C2	0x3062	#HIRAGANA LETTER DI
+0xA4C3	0x3063	#HIRAGANA LETTER SMALL TU
+0xA4C4	0x3064	#HIRAGANA LETTER TU
+0xA4C5	0x3065	#HIRAGANA LETTER DU
+0xA4C6	0x3066	#HIRAGANA LETTER TE
+0xA4C7	0x3067	#HIRAGANA LETTER DE
+0xA4C8	0x3068	#HIRAGANA LETTER TO
+0xA4C9	0x3069	#HIRAGANA LETTER DO
+0xA4CA	0x306A	#HIRAGANA LETTER NA
+0xA4CB	0x306B	#HIRAGANA LETTER NI
+0xA4CC	0x306C	#HIRAGANA LETTER NU
+0xA4CD	0x306D	#HIRAGANA LETTER NE
+0xA4CE	0x306E	#HIRAGANA LETTER NO
+0xA4CF	0x306F	#HIRAGANA LETTER HA
+0xA4D0	0x3070	#HIRAGANA LETTER BA
+0xA4D1	0x3071	#HIRAGANA LETTER PA
+0xA4D2	0x3072	#HIRAGANA LETTER HI
+0xA4D3	0x3073	#HIRAGANA LETTER BI
+0xA4D4	0x3074	#HIRAGANA LETTER PI
+0xA4D5	0x3075	#HIRAGANA LETTER HU
+0xA4D6	0x3076	#HIRAGANA LETTER BU
+0xA4D7	0x3077	#HIRAGANA LETTER PU
+0xA4D8	0x3078	#HIRAGANA LETTER HE
+0xA4D9	0x3079	#HIRAGANA LETTER BE
+0xA4DA	0x307A	#HIRAGANA LETTER PE
+0xA4DB	0x307B	#HIRAGANA LETTER HO
+0xA4DC	0x307C	#HIRAGANA LETTER BO
+0xA4DD	0x307D	#HIRAGANA LETTER PO
+0xA4DE	0x307E	#HIRAGANA LETTER MA
+0xA4DF	0x307F	#HIRAGANA LETTER MI
+0xA4E0	0x3080	#HIRAGANA LETTER MU
+0xA4E1	0x3081	#HIRAGANA LETTER ME
+0xA4E2	0x3082	#HIRAGANA LETTER MO
+0xA4E3	0x3083	#HIRAGANA LETTER SMALL YA
+0xA4E4	0x3084	#HIRAGANA LETTER YA
+0xA4E5	0x3085	#HIRAGANA LETTER SMALL YU
+0xA4E6	0x3086	#HIRAGANA LETTER YU
+0xA4E7	0x3087	#HIRAGANA LETTER SMALL YO
+0xA4E8	0x3088	#HIRAGANA LETTER YO
+0xA4E9	0x3089	#HIRAGANA LETTER RA
+0xA4EA	0x308A	#HIRAGANA LETTER RI
+0xA4EB	0x308B	#HIRAGANA LETTER RU
+0xA4EC	0x308C	#HIRAGANA LETTER RE
+0xA4ED	0x308D	#HIRAGANA LETTER RO
+0xA4EE	0x308E	#HIRAGANA LETTER SMALL WA
+0xA4EF	0x308F	#HIRAGANA LETTER WA
+0xA4F0	0x3090	#HIRAGANA LETTER WI
+0xA4F1	0x3091	#HIRAGANA LETTER WE
+0xA4F2	0x3092	#HIRAGANA LETTER WO
+0xA4F3	0x3093	#HIRAGANA LETTER N
+0xA5A1	0x30A1	#KATAKANA LETTER SMALL A
+0xA5A2	0x30A2	#KATAKANA LETTER A
+0xA5A3	0x30A3	#KATAKANA LETTER SMALL I
+0xA5A4	0x30A4	#KATAKANA LETTER I
+0xA5A5	0x30A5	#KATAKANA LETTER SMALL U
+0xA5A6	0x30A6	#KATAKANA LETTER U
+0xA5A7	0x30A7	#KATAKANA LETTER SMALL E
+0xA5A8	0x30A8	#KATAKANA LETTER E
+0xA5A9	0x30A9	#KATAKANA LETTER SMALL O
+0xA5AA	0x30AA	#KATAKANA LETTER O
+0xA5AB	0x30AB	#KATAKANA LETTER KA
+0xA5AC	0x30AC	#KATAKANA LETTER GA
+0xA5AD	0x30AD	#KATAKANA LETTER KI
+0xA5AE	0x30AE	#KATAKANA LETTER GI
+0xA5AF	0x30AF	#KATAKANA LETTER KU
+0xA5B0	0x30B0	#KATAKANA LETTER GU
+0xA5B1	0x30B1	#KATAKANA LETTER KE
+0xA5B2	0x30B2	#KATAKANA LETTER GE
+0xA5B3	0x30B3	#KATAKANA LETTER KO
+0xA5B4	0x30B4	#KATAKANA LETTER GO
+0xA5B5	0x30B5	#KATAKANA LETTER SA
+0xA5B6	0x30B6	#KATAKANA LETTER ZA
+0xA5B7	0x30B7	#KATAKANA LETTER SI
+0xA5B8	0x30B8	#KATAKANA LETTER ZI
+0xA5B9	0x30B9	#KATAKANA LETTER SU
+0xA5BA	0x30BA	#KATAKANA LETTER ZU
+0xA5BB	0x30BB	#KATAKANA LETTER SE
+0xA5BC	0x30BC	#KATAKANA LETTER ZE
+0xA5BD	0x30BD	#KATAKANA LETTER SO
+0xA5BE	0x30BE	#KATAKANA LETTER ZO
+0xA5BF	0x30BF	#KATAKANA LETTER TA
+0xA5C0	0x30C0	#KATAKANA LETTER DA
+0xA5C1	0x30C1	#KATAKANA LETTER TI
+0xA5C2	0x30C2	#KATAKANA LETTER DI
+0xA5C3	0x30C3	#KATAKANA LETTER SMALL TU
+0xA5C4	0x30C4	#KATAKANA LETTER TU
+0xA5C5	0x30C5	#KATAKANA LETTER DU
+0xA5C6	0x30C6	#KATAKANA LETTER TE
+0xA5C7	0x30C7	#KATAKANA LETTER DE
+0xA5C8	0x30C8	#KATAKANA LETTER TO
+0xA5C9	0x30C9	#KATAKANA LETTER DO
+0xA5CA	0x30CA	#KATAKANA LETTER NA
+0xA5CB	0x30CB	#KATAKANA LETTER NI
+0xA5CC	0x30CC	#KATAKANA LETTER NU
+0xA5CD	0x30CD	#KATAKANA LETTER NE
+0xA5CE	0x30CE	#KATAKANA LETTER NO
+0xA5CF	0x30CF	#KATAKANA LETTER HA
+0xA5D0	0x30D0	#KATAKANA LETTER BA
+0xA5D1	0x30D1	#KATAKANA LETTER PA
+0xA5D2	0x30D2	#KATAKANA LETTER HI
+0xA5D3	0x30D3	#KATAKANA LETTER BI
+0xA5D4	0x30D4	#KATAKANA LETTER PI
+0xA5D5	0x30D5	#KATAKANA LETTER HU
+0xA5D6	0x30D6	#KATAKANA LETTER BU
+0xA5D7	0x30D7	#KATAKANA LETTER PU
+0xA5D8	0x30D8	#KATAKANA LETTER HE
+0xA5D9	0x30D9	#KATAKANA LETTER BE
+0xA5DA	0x30DA	#KATAKANA LETTER PE
+0xA5DB	0x30DB	#KATAKANA LETTER HO
+0xA5DC	0x30DC	#KATAKANA LETTER BO
+0xA5DD	0x30DD	#KATAKANA LETTER PO
+0xA5DE	0x30DE	#KATAKANA LETTER MA
+0xA5DF	0x30DF	#KATAKANA LETTER MI
+0xA5E0	0x30E0	#KATAKANA LETTER MU
+0xA5E1	0x30E1	#KATAKANA LETTER ME
+0xA5E2	0x30E2	#KATAKANA LETTER MO
+0xA5E3	0x30E3	#KATAKANA LETTER SMALL YA
+0xA5E4	0x30E4	#KATAKANA LETTER YA
+0xA5E5	0x30E5	#KATAKANA LETTER SMALL YU
+0xA5E6	0x30E6	#KATAKANA LETTER YU
+0xA5E7	0x30E7	#KATAKANA LETTER SMALL YO
+0xA5E8	0x30E8	#KATAKANA LETTER YO
+0xA5E9	0x30E9	#KATAKANA LETTER RA
+0xA5EA	0x30EA	#KATAKANA LETTER RI
+0xA5EB	0x30EB	#KATAKANA LETTER RU
+0xA5EC	0x30EC	#KATAKANA LETTER RE
+0xA5ED	0x30ED	#KATAKANA LETTER RO
+0xA5EE	0x30EE	#KATAKANA LETTER SMALL WA
+0xA5EF	0x30EF	#KATAKANA LETTER WA
+0xA5F0	0x30F0	#KATAKANA LETTER WI
+0xA5F1	0x30F1	#KATAKANA LETTER WE
+0xA5F2	0x30F2	#KATAKANA LETTER WO
+0xA5F3	0x30F3	#KATAKANA LETTER N
+0xA5F4	0x30F4	#KATAKANA LETTER VU
+0xA5F5	0x30F5	#KATAKANA LETTER SMALL KA
+0xA5F6	0x30F6	#KATAKANA LETTER SMALL KE
+0xA6A1	0x0391	#GREEK CAPITAL LETTER ALPHA
+0xA6A2	0x0392	#GREEK CAPITAL LETTER BETA
+0xA6A3	0x0393	#GREEK CAPITAL LETTER GAMMA
+0xA6A4	0x0394	#GREEK CAPITAL LETTER DELTA
+0xA6A5	0x0395	#GREEK CAPITAL LETTER EPSILON
+0xA6A6	0x0396	#GREEK CAPITAL LETTER ZETA
+0xA6A7	0x0397	#GREEK CAPITAL LETTER ETA
+0xA6A8	0x0398	#GREEK CAPITAL LETTER THETA
+0xA6A9	0x0399	#GREEK CAPITAL LETTER IOTA
+0xA6AA	0x039A	#GREEK CAPITAL LETTER KAPPA
+0xA6AB	0x039B	#GREEK CAPITAL LETTER LAMDA
+0xA6AC	0x039C	#GREEK CAPITAL LETTER MU
+0xA6AD	0x039D	#GREEK CAPITAL LETTER NU
+0xA6AE	0x039E	#GREEK CAPITAL LETTER XI
+0xA6AF	0x039F	#GREEK CAPITAL LETTER OMICRON
+0xA6B0	0x03A0	#GREEK CAPITAL LETTER PI
+0xA6B1	0x03A1	#GREEK CAPITAL LETTER RHO
+0xA6B2	0x03A3	#GREEK CAPITAL LETTER SIGMA
+0xA6B3	0x03A4	#GREEK CAPITAL LETTER TAU
+0xA6B4	0x03A5	#GREEK CAPITAL LETTER UPSILON
+0xA6B5	0x03A6	#GREEK CAPITAL LETTER PHI
+0xA6B6	0x03A7	#GREEK CAPITAL LETTER CHI
+0xA6B7	0x03A8	#GREEK CAPITAL LETTER PSI
+0xA6B8	0x03A9	#GREEK CAPITAL LETTER OMEGA
+0xA6C1	0x03B1	#GREEK SMALL LETTER ALPHA
+0xA6C2	0x03B2	#GREEK SMALL LETTER BETA
+0xA6C3	0x03B3	#GREEK SMALL LETTER GAMMA
+0xA6C4	0x03B4	#GREEK SMALL LETTER DELTA
+0xA6C5	0x03B5	#GREEK SMALL LETTER EPSILON
+0xA6C6	0x03B6	#GREEK SMALL LETTER ZETA
+0xA6C7	0x03B7	#GREEK SMALL LETTER ETA
+0xA6C8	0x03B8	#GREEK SMALL LETTER THETA
+0xA6C9	0x03B9	#GREEK SMALL LETTER IOTA
+0xA6CA	0x03BA	#GREEK SMALL LETTER KAPPA
+0xA6CB	0x03BB	#GREEK SMALL LETTER LAMDA
+0xA6CC	0x03BC	#GREEK SMALL LETTER MU
+0xA6CD	0x03BD	#GREEK SMALL LETTER NU
+0xA6CE	0x03BE	#GREEK SMALL LETTER XI
+0xA6CF	0x03BF	#GREEK SMALL LETTER OMICRON
+0xA6D0	0x03C0	#GREEK SMALL LETTER PI
+0xA6D1	0x03C1	#GREEK SMALL LETTER RHO
+0xA6D2	0x03C3	#GREEK SMALL LETTER SIGMA
+0xA6D3	0x03C4	#GREEK SMALL LETTER TAU
+0xA6D4	0x03C5	#GREEK SMALL LETTER UPSILON
+0xA6D5	0x03C6	#GREEK SMALL LETTER PHI
+0xA6D6	0x03C7	#GREEK SMALL LETTER CHI
+0xA6D7	0x03C8	#GREEK SMALL LETTER PSI
+0xA6D8	0x03C9	#GREEK SMALL LETTER OMEGA
+0xA6E0	0xFE35	#PRESENTATION FORM FOR VERTICAL LEFT PARENTHESIS
+0xA6E1	0xFE36	#PRESENTATION FORM FOR VERTICAL RIGHT PARENTHESIS
+0xA6E2	0xFE39	#PRESENTATION FORM FOR VERTICAL LEFT TORTOISE SHELL BRACKET
+0xA6E3	0xFE3A	#PRESENTATION FORM FOR VERTICAL RIGHT TORTOISE SHELL BRACKET
+0xA6E4	0xFE3F	#PRESENTATION FORM FOR VERTICAL LEFT ANGLE BRACKET
+0xA6E5	0xFE40	#PRESENTATION FORM FOR VERTICAL RIGHT ANGLE BRACKET
+0xA6E6	0xFE3D	#PRESENTATION FORM FOR VERTICAL LEFT DOUBLE ANGLE BRACKET
+0xA6E7	0xFE3E	#PRESENTATION FORM FOR VERTICAL RIGHT DOUBLE ANGLE BRACKET
+0xA6E8	0xFE41	#PRESENTATION FORM FOR VERTICAL LEFT CORNER BRACKET
+0xA6E9	0xFE42	#PRESENTATION FORM FOR VERTICAL RIGHT CORNER BRACKET
+0xA6EA	0xFE43	#PRESENTATION FORM FOR VERTICAL LEFT WHITE CORNER BRACKET
+0xA6EB	0xFE44	#PRESENTATION FORM FOR VERTICAL RIGHT WHITE CORNER BRACKET
+0xA6EE	0xFE3B	#PRESENTATION FORM FOR VERTICAL LEFT BLACK LENTICULAR BRACKET
+0xA6EF	0xFE3C	#PRESENTATION FORM FOR VERTICAL RIGHT BLACK LENTICULAR BRACKET
+0xA6F0	0xFE37	#PRESENTATION FORM FOR VERTICAL LEFT CURLY BRACKET
+0xA6F1	0xFE38	#PRESENTATION FORM FOR VERTICAL RIGHT CURLY BRACKET
+0xA6F2	0xFE31	#PRESENTATION FORM FOR VERTICAL EM DASH
+0xA6F4	0xFE33	#PRESENTATION FORM FOR VERTICAL LOW LINE
+0xA6F5	0xFE34	#PRESENTATION FORM FOR VERTICAL WAVY LOW LINE
+0xA7A1	0x0410	#CYRILLIC CAPITAL LETTER A
+0xA7A2	0x0411	#CYRILLIC CAPITAL LETTER BE
+0xA7A3	0x0412	#CYRILLIC CAPITAL LETTER VE
+0xA7A4	0x0413	#CYRILLIC CAPITAL LETTER GHE
+0xA7A5	0x0414	#CYRILLIC CAPITAL LETTER DE
+0xA7A6	0x0415	#CYRILLIC CAPITAL LETTER IE
+0xA7A7	0x0401	#CYRILLIC CAPITAL LETTER IO
+0xA7A8	0x0416	#CYRILLIC CAPITAL LETTER ZHE
+0xA7A9	0x0417	#CYRILLIC CAPITAL LETTER ZE
+0xA7AA	0x0418	#CYRILLIC CAPITAL LETTER I
+0xA7AB	0x0419	#CYRILLIC CAPITAL LETTER SHORT I
+0xA7AC	0x041A	#CYRILLIC CAPITAL LETTER KA
+0xA7AD	0x041B	#CYRILLIC CAPITAL LETTER EL
+0xA7AE	0x041C	#CYRILLIC CAPITAL LETTER EM
+0xA7AF	0x041D	#CYRILLIC CAPITAL LETTER EN
+0xA7B0	0x041E	#CYRILLIC CAPITAL LETTER O
+0xA7B1	0x041F	#CYRILLIC CAPITAL LETTER PE
+0xA7B2	0x0420	#CYRILLIC CAPITAL LETTER ER
+0xA7B3	0x0421	#CYRILLIC CAPITAL LETTER ES
+0xA7B4	0x0422	#CYRILLIC CAPITAL LETTER TE
+0xA7B5	0x0423	#CYRILLIC CAPITAL LETTER U
+0xA7B6	0x0424	#CYRILLIC CAPITAL LETTER EF
+0xA7B7	0x0425	#CYRILLIC CAPITAL LETTER HA
+0xA7B8	0x0426	#CYRILLIC CAPITAL LETTER TSE
+0xA7B9	0x0427	#CYRILLIC CAPITAL LETTER CHE
+0xA7BA	0x0428	#CYRILLIC CAPITAL LETTER SHA
+0xA7BB	0x0429	#CYRILLIC CAPITAL LETTER SHCHA
+0xA7BC	0x042A	#CYRILLIC CAPITAL LETTER HARD SIGN
+0xA7BD	0x042B	#CYRILLIC CAPITAL LETTER YERU
+0xA7BE	0x042C	#CYRILLIC CAPITAL LETTER SOFT SIGN
+0xA7BF	0x042D	#CYRILLIC CAPITAL LETTER E
+0xA7C0	0x042E	#CYRILLIC CAPITAL LETTER YU
+0xA7C1	0x042F	#CYRILLIC CAPITAL LETTER YA
+0xA7D1	0x0430	#CYRILLIC SMALL LETTER A
+0xA7D2	0x0431	#CYRILLIC SMALL LETTER BE
+0xA7D3	0x0432	#CYRILLIC SMALL LETTER VE
+0xA7D4	0x0433	#CYRILLIC SMALL LETTER GHE
+0xA7D5	0x0434	#CYRILLIC SMALL LETTER DE
+0xA7D6	0x0435	#CYRILLIC SMALL LETTER IE
+0xA7D7	0x0451	#CYRILLIC SMALL LETTER IO
+0xA7D8	0x0436	#CYRILLIC SMALL LETTER ZHE
+0xA7D9	0x0437	#CYRILLIC SMALL LETTER ZE
+0xA7DA	0x0438	#CYRILLIC SMALL LETTER I
+0xA7DB	0x0439	#CYRILLIC SMALL LETTER SHORT I
+0xA7DC	0x043A	#CYRILLIC SMALL LETTER KA
+0xA7DD	0x043B	#CYRILLIC SMALL LETTER EL
+0xA7DE	0x043C	#CYRILLIC SMALL LETTER EM
+0xA7DF	0x043D	#CYRILLIC SMALL LETTER EN
+0xA7E0	0x043E	#CYRILLIC SMALL LETTER O
+0xA7E1	0x043F	#CYRILLIC SMALL LETTER PE
+0xA7E2	0x0440	#CYRILLIC SMALL LETTER ER
+0xA7E3	0x0441	#CYRILLIC SMALL LETTER ES
+0xA7E4	0x0442	#CYRILLIC SMALL LETTER TE
+0xA7E5	0x0443	#CYRILLIC SMALL LETTER U
+0xA7E6	0x0444	#CYRILLIC SMALL LETTER EF
+0xA7E7	0x0445	#CYRILLIC SMALL LETTER HA
+0xA7E8	0x0446	#CYRILLIC SMALL LETTER TSE
+0xA7E9	0x0447	#CYRILLIC SMALL LETTER CHE
+0xA7EA	0x0448	#CYRILLIC SMALL LETTER SHA
+0xA7EB	0x0449	#CYRILLIC SMALL LETTER SHCHA
+0xA7EC	0x044A	#CYRILLIC SMALL LETTER HARD SIGN
+0xA7ED	0x044B	#CYRILLIC SMALL LETTER YERU
+0xA7EE	0x044C	#CYRILLIC SMALL LETTER SOFT SIGN
+0xA7EF	0x044D	#CYRILLIC SMALL LETTER E
+0xA7F0	0x044E	#CYRILLIC SMALL LETTER YU
+0xA7F1	0x044F	#CYRILLIC SMALL LETTER YA
+0xA840	0x02CA	#MODIFIER LETTER ACUTE ACCENT
+0xA841	0x02CB	#MODIFIER LETTER GRAVE ACCENT
+0xA842	0x02D9	#DOT ABOVE
+0xA843	0x2013	#EN DASH
+0xA844	0x2015	#HORIZONTAL BAR
+0xA845	0x2025	#TWO DOT LEADER
+0xA846	0x2035	#REVERSED PRIME
+0xA847	0x2105	#CARE OF
+0xA848	0x2109	#DEGREE FAHRENHEIT
+0xA849	0x2196	#NORTH WEST ARROW
+0xA84A	0x2197	#NORTH EAST ARROW
+0xA84B	0x2198	#SOUTH EAST ARROW
+0xA84C	0x2199	#SOUTH WEST ARROW
+0xA84D	0x2215	#DIVISION SLASH
+0xA84E	0x221F	#RIGHT ANGLE
+0xA84F	0x2223	#DIVIDES
+0xA850	0x2252	#APPROXIMATELY EQUAL TO OR THE IMAGE OF
+0xA851	0x2266	#LESS-THAN OVER EQUAL TO
+0xA852	0x2267	#GREATER-THAN OVER EQUAL TO
+0xA853	0x22BF	#RIGHT TRIANGLE
+0xA854	0x2550	#BOX DRAWINGS DOUBLE HORIZONTAL
+0xA855	0x2551	#BOX DRAWINGS DOUBLE VERTICAL
+0xA856	0x2552	#BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE
+0xA857	0x2553	#BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE
+0xA858	0x2554	#BOX DRAWINGS DOUBLE DOWN AND RIGHT
+0xA859	0x2555	#BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE
+0xA85A	0x2556	#BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE
+0xA85B	0x2557	#BOX DRAWINGS DOUBLE DOWN AND LEFT
+0xA85C	0x2558	#BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE
+0xA85D	0x2559	#BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE
+0xA85E	0x255A	#BOX DRAWINGS DOUBLE UP AND RIGHT
+0xA85F	0x255B	#BOX DRAWINGS UP SINGLE AND LEFT DOUBLE
+0xA860	0x255C	#BOX DRAWINGS UP DOUBLE AND LEFT SINGLE
+0xA861	0x255D	#BOX DRAWINGS DOUBLE UP AND LEFT
+0xA862	0x255E	#BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE
+0xA863	0x255F	#BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE
+0xA864	0x2560	#BOX DRAWINGS DOUBLE VERTICAL AND RIGHT
+0xA865	0x2561	#BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE
+0xA866	0x2562	#BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE
+0xA867	0x2563	#BOX DRAWINGS DOUBLE VERTICAL AND LEFT
+0xA868	0x2564	#BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE
+0xA869	0x2565	#BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE
+0xA86A	0x2566	#BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL
+0xA86B	0x2567	#BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE
+0xA86C	0x2568	#BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE
+0xA86D	0x2569	#BOX DRAWINGS DOUBLE UP AND HORIZONTAL
+0xA86E	0x256A	#BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE
+0xA86F	0x256B	#BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE
+0xA870	0x256C	#BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL
+0xA871	0x256D	#BOX DRAWINGS LIGHT ARC DOWN AND RIGHT
+0xA872	0x256E	#BOX DRAWINGS LIGHT ARC DOWN AND LEFT
+0xA873	0x256F	#BOX DRAWINGS LIGHT ARC UP AND LEFT
+0xA874	0x2570	#BOX DRAWINGS LIGHT ARC UP AND RIGHT
+0xA875	0x2571	#BOX DRAWINGS LIGHT DIAGONAL UPPER RIGHT TO LOWER LEFT
+0xA876	0x2572	#BOX DRAWINGS LIGHT DIAGONAL UPPER LEFT TO LOWER RIGHT
+0xA877	0x2573	#BOX DRAWINGS LIGHT DIAGONAL CROSS
+0xA878	0x2581	#LOWER ONE EIGHTH BLOCK
+0xA879	0x2582	#LOWER ONE QUARTER BLOCK
+0xA87A	0x2583	#LOWER THREE EIGHTHS BLOCK
+0xA87B	0x2584	#LOWER HALF BLOCK
+0xA87C	0x2585	#LOWER FIVE EIGHTHS BLOCK
+0xA87D	0x2586	#LOWER THREE QUARTERS BLOCK
+0xA87E	0x2587	#LOWER SEVEN EIGHTHS BLOCK
+0xA880	0x2588	#FULL BLOCK
+0xA881	0x2589	#LEFT SEVEN EIGHTHS BLOCK
+0xA882	0x258A	#LEFT THREE QUARTERS BLOCK
+0xA883	0x258B	#LEFT FIVE EIGHTHS BLOCK
+0xA884	0x258C	#LEFT HALF BLOCK
+0xA885	0x258D	#LEFT THREE EIGHTHS BLOCK
+0xA886	0x258E	#LEFT ONE QUARTER BLOCK
+0xA887	0x258F	#LEFT ONE EIGHTH BLOCK
+0xA888	0x2593	#DARK SHADE
+0xA889	0x2594	#UPPER ONE EIGHTH BLOCK
+0xA88A	0x2595	#RIGHT ONE EIGHTH BLOCK
+0xA88B	0x25BC	#BLACK DOWN-POINTING TRIANGLE
+0xA88C	0x25BD	#WHITE DOWN-POINTING TRIANGLE
+0xA88D	0x25E2	#BLACK LOWER RIGHT TRIANGLE
+0xA88E	0x25E3	#BLACK LOWER LEFT TRIANGLE
+0xA88F	0x25E4	#BLACK UPPER LEFT TRIANGLE
+0xA890	0x25E5	#BLACK UPPER RIGHT TRIANGLE
+0xA891	0x2609	#SUN
+0xA892	0x2295	#CIRCLED PLUS
+0xA893	0x3012	#POSTAL MARK
+0xA894	0x301D	#REVERSED DOUBLE PRIME QUOTATION MARK
+0xA895	0x301E	#DOUBLE PRIME QUOTATION MARK
+0xA8A1	0x0101	#LATIN SMALL LETTER A WITH MACRON
+0xA8A2	0x00E1	#LATIN SMALL LETTER A WITH ACUTE
+0xA8A3	0x01CE	#LATIN SMALL LETTER A WITH CARON
+0xA8A4	0x00E0	#LATIN SMALL LETTER A WITH GRAVE
+0xA8A5	0x0113	#LATIN SMALL LETTER E WITH MACRON
+0xA8A6	0x00E9	#LATIN SMALL LETTER E WITH ACUTE
+0xA8A7	0x011B	#LATIN SMALL LETTER E WITH CARON
+0xA8A8	0x00E8	#LATIN SMALL LETTER E WITH GRAVE
+0xA8A9	0x012B	#LATIN SMALL LETTER I WITH MACRON
+0xA8AA	0x00ED	#LATIN SMALL LETTER I WITH ACUTE
+0xA8AB	0x01D0	#LATIN SMALL LETTER I WITH CARON
+0xA8AC	0x00EC	#LATIN SMALL LETTER I WITH GRAVE
+0xA8AD	0x014D	#LATIN SMALL LETTER O WITH MACRON
+0xA8AE	0x00F3	#LATIN SMALL LETTER O WITH ACUTE
+0xA8AF	0x01D2	#LATIN SMALL LETTER O WITH CARON
+0xA8B0	0x00F2	#LATIN SMALL LETTER O WITH GRAVE
+0xA8B1	0x016B	#LATIN SMALL LETTER U WITH MACRON
+0xA8B2	0x00FA	#LATIN SMALL LETTER U WITH ACUTE
+0xA8B3	0x01D4	#LATIN SMALL LETTER U WITH CARON
+0xA8B4	0x00F9	#LATIN SMALL LETTER U WITH GRAVE
+0xA8B5	0x01D6	#LATIN SMALL LETTER U WITH DIAERESIS AND MACRON
+0xA8B6	0x01D8	#LATIN SMALL LETTER U WITH DIAERESIS AND ACUTE
+0xA8B7	0x01DA	#LATIN SMALL LETTER U WITH DIAERESIS AND CARON
+0xA8B8	0x01DC	#LATIN SMALL LETTER U WITH DIAERESIS AND GRAVE
+0xA8B9	0x00FC	#LATIN SMALL LETTER U WITH DIAERESIS
+0xA8BA	0x00EA	#LATIN SMALL LETTER E WITH CIRCUMFLEX
+0xA8BB	0x0251	#LATIN SMALL LETTER ALPHA
+0xA8BD	0x0144	#LATIN SMALL LETTER N WITH ACUTE
+0xA8BE	0x0148	#LATIN SMALL LETTER N WITH CARON
+0xA8C0	0x0261	#LATIN SMALL LETTER SCRIPT G
+0xA8C5	0x3105	#BOPOMOFO LETTER B
+0xA8C6	0x3106	#BOPOMOFO LETTER P
+0xA8C7	0x3107	#BOPOMOFO LETTER M
+0xA8C8	0x3108	#BOPOMOFO LETTER F
+0xA8C9	0x3109	#BOPOMOFO LETTER D
+0xA8CA	0x310A	#BOPOMOFO LETTER T
+0xA8CB	0x310B	#BOPOMOFO LETTER N
+0xA8CC	0x310C	#BOPOMOFO LETTER L
+0xA8CD	0x310D	#BOPOMOFO LETTER G
+0xA8CE	0x310E	#BOPOMOFO LETTER K
+0xA8CF	0x310F	#BOPOMOFO LETTER H
+0xA8D0	0x3110	#BOPOMOFO LETTER J
+0xA8D1	0x3111	#BOPOMOFO LETTER Q
+0xA8D2	0x3112	#BOPOMOFO LETTER X
+0xA8D3	0x3113	#BOPOMOFO LETTER ZH
+0xA8D4	0x3114	#BOPOMOFO LETTER CH
+0xA8D5	0x3115	#BOPOMOFO LETTER SH
+0xA8D6	0x3116	#BOPOMOFO LETTER R
+0xA8D7	0x3117	#BOPOMOFO LETTER Z
+0xA8D8	0x3118	#BOPOMOFO LETTER C
+0xA8D9	0x3119	#BOPOMOFO LETTER S
+0xA8DA	0x311A	#BOPOMOFO LETTER A
+0xA8DB	0x311B	#BOPOMOFO LETTER O
+0xA8DC	0x311C	#BOPOMOFO LETTER E
+0xA8DD	0x311D	#BOPOMOFO LETTER EH
+0xA8DE	0x311E	#BOPOMOFO LETTER AI
+0xA8DF	0x311F	#BOPOMOFO LETTER EI
+0xA8E0	0x3120	#BOPOMOFO LETTER AU
+0xA8E1	0x3121	#BOPOMOFO LETTER OU
+0xA8E2	0x3122	#BOPOMOFO LETTER AN
+0xA8E3	0x3123	#BOPOMOFO LETTER EN
+0xA8E4	0x3124	#BOPOMOFO LETTER ANG
+0xA8E5	0x3125	#BOPOMOFO LETTER ENG
+0xA8E6	0x3126	#BOPOMOFO LETTER ER
+0xA8E7	0x3127	#BOPOMOFO LETTER I
+0xA8E8	0x3128	#BOPOMOFO LETTER U
+0xA8E9	0x3129	#BOPOMOFO LETTER IU
+0xA940	0x3021	#HANGZHOU NUMERAL ONE
+0xA941	0x3022	#HANGZHOU NUMERAL TWO
+0xA942	0x3023	#HANGZHOU NUMERAL THREE
+0xA943	0x3024	#HANGZHOU NUMERAL FOUR
+0xA944	0x3025	#HANGZHOU NUMERAL FIVE
+0xA945	0x3026	#HANGZHOU NUMERAL SIX
+0xA946	0x3027	#HANGZHOU NUMERAL SEVEN
+0xA947	0x3028	#HANGZHOU NUMERAL EIGHT
+0xA948	0x3029	#HANGZHOU NUMERAL NINE
+0xA949	0x32A3	#CIRCLED IDEOGRAPH CORRECT
+0xA94A	0x338E	#SQUARE MG
+0xA94B	0x338F	#SQUARE KG
+0xA94C	0x339C	#SQUARE MM
+0xA94D	0x339D	#SQUARE CM
+0xA94E	0x339E	#SQUARE KM
+0xA94F	0x33A1	#SQUARE M SQUARED
+0xA950	0x33C4	#SQUARE CC
+0xA951	0x33CE	#SQUARE KM CAPITAL
+0xA952	0x33D1	#SQUARE LN
+0xA953	0x33D2	#SQUARE LOG
+0xA954	0x33D5	#SQUARE MIL
+0xA955	0xFE30	#PRESENTATION FORM FOR VERTICAL TWO DOT LEADER
+0xA956	0xFFE2	#FULLWIDTH NOT SIGN
+0xA957	0xFFE4	#FULLWIDTH BROKEN BAR
+0xA959	0x2121	#TELEPHONE SIGN
+0xA95A	0x3231	#PARENTHESIZED IDEOGRAPH STOCK
+0xA95C	0x2010	#HYPHEN
+0xA960	0x30FC	#KATAKANA-HIRAGANA PROLONGED SOUND MARK
+0xA961	0x309B	#KATAKANA-HIRAGANA VOICED SOUND MARK
+0xA962	0x309C	#KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK
+0xA963	0x30FD	#KATAKANA ITERATION MARK
+0xA964	0x30FE	#KATAKANA VOICED ITERATION MARK
+0xA965	0x3006	#IDEOGRAPHIC CLOSING MARK
+0xA966	0x309D	#HIRAGANA ITERATION MARK
+0xA967	0x309E	#HIRAGANA VOICED ITERATION MARK
+0xA968	0xFE49	#DASHED OVERLINE
+0xA969	0xFE4A	#CENTRELINE OVERLINE
+0xA96A	0xFE4B	#WAVY OVERLINE
+0xA96B	0xFE4C	#DOUBLE WAVY OVERLINE
+0xA96C	0xFE4D	#DASHED LOW LINE
+0xA96D	0xFE4E	#CENTRELINE LOW LINE
+0xA96E	0xFE4F	#WAVY LOW LINE
+0xA96F	0xFE50	#SMALL COMMA
+0xA970	0xFE51	#SMALL IDEOGRAPHIC COMMA
+0xA971	0xFE52	#SMALL FULL STOP
+0xA972	0xFE54	#SMALL SEMICOLON
+0xA973	0xFE55	#SMALL COLON
+0xA974	0xFE56	#SMALL QUESTION MARK
+0xA975	0xFE57	#SMALL EXCLAMATION MARK
+0xA976	0xFE59	#SMALL LEFT PARENTHESIS
+0xA977	0xFE5A	#SMALL RIGHT PARENTHESIS
+0xA978	0xFE5B	#SMALL LEFT CURLY BRACKET
+0xA979	0xFE5C	#SMALL RIGHT CURLY BRACKET
+0xA97A	0xFE5D	#SMALL LEFT TORTOISE SHELL BRACKET
+0xA97B	0xFE5E	#SMALL RIGHT TORTOISE SHELL BRACKET
+0xA97C	0xFE5F	#SMALL NUMBER SIGN
+0xA97D	0xFE60	#SMALL AMPERSAND
+0xA97E	0xFE61	#SMALL ASTERISK
+0xA980	0xFE62	#SMALL PLUS SIGN
+0xA981	0xFE63	#SMALL HYPHEN-MINUS
+0xA982	0xFE64	#SMALL LESS-THAN SIGN
+0xA983	0xFE65	#SMALL GREATER-THAN SIGN
+0xA984	0xFE66	#SMALL EQUALS SIGN
+0xA985	0xFE68	#SMALL REVERSE SOLIDUS
+0xA986	0xFE69	#SMALL DOLLAR SIGN
+0xA987	0xFE6A	#SMALL PERCENT SIGN
+0xA988	0xFE6B	#SMALL COMMERCIAL AT
+0xA996	0x3007	#IDEOGRAPHIC NUMBER ZERO
+0xA9A4	0x2500	#BOX DRAWINGS LIGHT HORIZONTAL
+0xA9A5	0x2501	#BOX DRAWINGS HEAVY HORIZONTAL
+0xA9A6	0x2502	#BOX DRAWINGS LIGHT VERTICAL
+0xA9A7	0x2503	#BOX DRAWINGS HEAVY VERTICAL
+0xA9A8	0x2504	#BOX DRAWINGS LIGHT TRIPLE DASH HORIZONTAL
+0xA9A9	0x2505	#BOX DRAWINGS HEAVY TRIPLE DASH HORIZONTAL
+0xA9AA	0x2506	#BOX DRAWINGS LIGHT TRIPLE DASH VERTICAL
+0xA9AB	0x2507	#BOX DRAWINGS HEAVY TRIPLE DASH VERTICAL
+0xA9AC	0x2508	#BOX DRAWINGS LIGHT QUADRUPLE DASH HORIZONTAL
+0xA9AD	0x2509	#BOX DRAWINGS HEAVY QUADRUPLE DASH HORIZONTAL
+0xA9AE	0x250A	#BOX DRAWINGS LIGHT QUADRUPLE DASH VERTICAL
+0xA9AF	0x250B	#BOX DRAWINGS HEAVY QUADRUPLE DASH VERTICAL
+0xA9B0	0x250C	#BOX DRAWINGS LIGHT DOWN AND RIGHT
+0xA9B1	0x250D	#BOX DRAWINGS DOWN LIGHT AND RIGHT HEAVY
+0xA9B2	0x250E	#BOX DRAWINGS DOWN HEAVY AND RIGHT LIGHT
+0xA9B3	0x250F	#BOX DRAWINGS HEAVY DOWN AND RIGHT
+0xA9B4	0x2510	#BOX DRAWINGS LIGHT DOWN AND LEFT
+0xA9B5	0x2511	#BOX DRAWINGS DOWN LIGHT AND LEFT HEAVY
+0xA9B6	0x2512	#BOX DRAWINGS DOWN HEAVY AND LEFT LIGHT
+0xA9B7	0x2513	#BOX DRAWINGS HEAVY DOWN AND LEFT
+0xA9B8	0x2514	#BOX DRAWINGS LIGHT UP AND RIGHT
+0xA9B9	0x2515	#BOX DRAWINGS UP LIGHT AND RIGHT HEAVY
+0xA9BA	0x2516	#BOX DRAWINGS UP HEAVY AND RIGHT LIGHT
+0xA9BB	0x2517	#BOX DRAWINGS HEAVY UP AND RIGHT
+0xA9BC	0x2518	#BOX DRAWINGS LIGHT UP AND LEFT
+0xA9BD	0x2519	#BOX DRAWINGS UP LIGHT AND LEFT HEAVY
+0xA9BE	0x251A	#BOX DRAWINGS UP HEAVY AND LEFT LIGHT
+0xA9BF	0x251B	#BOX DRAWINGS HEAVY UP AND LEFT
+0xA9C0	0x251C	#BOX DRAWINGS LIGHT VERTICAL AND RIGHT
+0xA9C1	0x251D	#BOX DRAWINGS VERTICAL LIGHT AND RIGHT HEAVY
+0xA9C2	0x251E	#BOX DRAWINGS UP HEAVY AND RIGHT DOWN LIGHT
+0xA9C3	0x251F	#BOX DRAWINGS DOWN HEAVY AND RIGHT UP LIGHT
+0xA9C4	0x2520	#BOX DRAWINGS VERTICAL HEAVY AND RIGHT LIGHT
+0xA9C5	0x2521	#BOX DRAWINGS DOWN LIGHT AND RIGHT UP HEAVY
+0xA9C6	0x2522	#BOX DRAWINGS UP LIGHT AND RIGHT DOWN HEAVY
+0xA9C7	0x2523	#BOX DRAWINGS HEAVY VERTICAL AND RIGHT
+0xA9C8	0x2524	#BOX DRAWINGS LIGHT VERTICAL AND LEFT
+0xA9C9	0x2525	#BOX DRAWINGS VERTICAL LIGHT AND LEFT HEAVY
+0xA9CA	0x2526	#BOX DRAWINGS UP HEAVY AND LEFT DOWN LIGHT
+0xA9CB	0x2527	#BOX DRAWINGS DOWN HEAVY AND LEFT UP LIGHT
+0xA9CC	0x2528	#BOX DRAWINGS VERTICAL HEAVY AND LEFT LIGHT
+0xA9CD	0x2529	#BOX DRAWINGS DOWN LIGHT AND LEFT UP HEAVY
+0xA9CE	0x252A	#BOX DRAWINGS UP LIGHT AND LEFT DOWN HEAVY
+0xA9CF	0x252B	#BOX DRAWINGS HEAVY VERTICAL AND LEFT
+0xA9D0	0x252C	#BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
+0xA9D1	0x252D	#BOX DRAWINGS LEFT HEAVY AND RIGHT DOWN LIGHT
+0xA9D2	0x252E	#BOX DRAWINGS RIGHT HEAVY AND LEFT DOWN LIGHT
+0xA9D3	0x252F	#BOX DRAWINGS DOWN LIGHT AND HORIZONTAL HEAVY
+0xA9D4	0x2530	#BOX DRAWINGS DOWN HEAVY AND HORIZONTAL LIGHT
+0xA9D5	0x2531	#BOX DRAWINGS RIGHT LIGHT AND LEFT DOWN HEAVY
+0xA9D6	0x2532	#BOX DRAWINGS LEFT LIGHT AND RIGHT DOWN HEAVY
+0xA9D7	0x2533	#BOX DRAWINGS HEAVY DOWN AND HORIZONTAL
+0xA9D8	0x2534	#BOX DRAWINGS LIGHT UP AND HORIZONTAL
+0xA9D9	0x2535	#BOX DRAWINGS LEFT HEAVY AND RIGHT UP LIGHT
+0xA9DA	0x2536	#BOX DRAWINGS RIGHT HEAVY AND LEFT UP LIGHT
+0xA9DB	0x2537	#BOX DRAWINGS UP LIGHT AND HORIZONTAL HEAVY
+0xA9DC	0x2538	#BOX DRAWINGS UP HEAVY AND HORIZONTAL LIGHT
+0xA9DD	0x2539	#BOX DRAWINGS RIGHT LIGHT AND LEFT UP HEAVY
+0xA9DE	0x253A	#BOX DRAWINGS LEFT LIGHT AND RIGHT UP HEAVY
+0xA9DF	0x253B	#BOX DRAWINGS HEAVY UP AND HORIZONTAL
+0xA9E0	0x253C	#BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
+0xA9E1	0x253D	#BOX DRAWINGS LEFT HEAVY AND RIGHT VERTICAL LIGHT
+0xA9E2	0x253E	#BOX DRAWINGS RIGHT HEAVY AND LEFT VERTICAL LIGHT
+0xA9E3	0x253F	#BOX DRAWINGS VERTICAL LIGHT AND HORIZONTAL HEAVY
+0xA9E4	0x2540	#BOX DRAWINGS UP HEAVY AND DOWN HORIZONTAL LIGHT
+0xA9E5	0x2541	#BOX DRAWINGS DOWN HEAVY AND UP HORIZONTAL LIGHT
+0xA9E6	0x2542	#BOX DRAWINGS VERTICAL HEAVY AND HORIZONTAL LIGHT
+0xA9E7	0x2543	#BOX DRAWINGS LEFT UP HEAVY AND RIGHT DOWN LIGHT
+0xA9E8	0x2544	#BOX DRAWINGS RIGHT UP HEAVY AND LEFT DOWN LIGHT
+0xA9E9	0x2545	#BOX DRAWINGS LEFT DOWN HEAVY AND RIGHT UP LIGHT
+0xA9EA	0x2546	#BOX DRAWINGS RIGHT DOWN HEAVY AND LEFT UP LIGHT
+0xA9EB	0x2547	#BOX DRAWINGS DOWN LIGHT AND UP HORIZONTAL HEAVY
+0xA9EC	0x2548	#BOX DRAWINGS UP LIGHT AND DOWN HORIZONTAL HEAVY
+0xA9ED	0x2549	#BOX DRAWINGS RIGHT LIGHT AND LEFT VERTICAL HEAVY
+0xA9EE	0x254A	#BOX DRAWINGS LEFT LIGHT AND RIGHT VERTICAL HEAVY
+0xA9EF	0x254B	#BOX DRAWINGS HEAVY VERTICAL AND HORIZONTAL
+0xAA40	0x72DC	#CJK UNIFIED IDEOGRAPH
+0xAA41	0x72DD	#CJK UNIFIED IDEOGRAPH
+0xAA42	0x72DF	#CJK UNIFIED IDEOGRAPH
+0xAA43	0x72E2	#CJK UNIFIED IDEOGRAPH
+0xAA44	0x72E3	#CJK UNIFIED IDEOGRAPH
+0xAA45	0x72E4	#CJK UNIFIED IDEOGRAPH
+0xAA46	0x72E5	#CJK UNIFIED IDEOGRAPH
+0xAA47	0x72E6	#CJK UNIFIED IDEOGRAPH
+0xAA48	0x72E7	#CJK UNIFIED IDEOGRAPH
+0xAA49	0x72EA	#CJK UNIFIED IDEOGRAPH
+0xAA4A	0x72EB	#CJK UNIFIED IDEOGRAPH
+0xAA4B	0x72F5	#CJK UNIFIED IDEOGRAPH
+0xAA4C	0x72F6	#CJK UNIFIED IDEOGRAPH
+0xAA4D	0x72F9	#CJK UNIFIED IDEOGRAPH
+0xAA4E	0x72FD	#CJK UNIFIED IDEOGRAPH
+0xAA4F	0x72FE	#CJK UNIFIED IDEOGRAPH
+0xAA50	0x72FF	#CJK UNIFIED IDEOGRAPH
+0xAA51	0x7300	#CJK UNIFIED IDEOGRAPH
+0xAA52	0x7302	#CJK UNIFIED IDEOGRAPH
+0xAA53	0x7304	#CJK UNIFIED IDEOGRAPH
+0xAA54	0x7305	#CJK UNIFIED IDEOGRAPH
+0xAA55	0x7306	#CJK UNIFIED IDEOGRAPH
+0xAA56	0x7307	#CJK UNIFIED IDEOGRAPH
+0xAA57	0x7308	#CJK UNIFIED IDEOGRAPH
+0xAA58	0x7309	#CJK UNIFIED IDEOGRAPH
+0xAA59	0x730B	#CJK UNIFIED IDEOGRAPH
+0xAA5A	0x730C	#CJK UNIFIED IDEOGRAPH
+0xAA5B	0x730D	#CJK UNIFIED IDEOGRAPH
+0xAA5C	0x730F	#CJK UNIFIED IDEOGRAPH
+0xAA5D	0x7310	#CJK UNIFIED IDEOGRAPH
+0xAA5E	0x7311	#CJK UNIFIED IDEOGRAPH
+0xAA5F	0x7312	#CJK UNIFIED IDEOGRAPH
+0xAA60	0x7314	#CJK UNIFIED IDEOGRAPH
+0xAA61	0x7318	#CJK UNIFIED IDEOGRAPH
+0xAA62	0x7319	#CJK UNIFIED IDEOGRAPH
+0xAA63	0x731A	#CJK UNIFIED IDEOGRAPH
+0xAA64	0x731F	#CJK UNIFIED IDEOGRAPH
+0xAA65	0x7320	#CJK UNIFIED IDEOGRAPH
+0xAA66	0x7323	#CJK UNIFIED IDEOGRAPH
+0xAA67	0x7324	#CJK UNIFIED IDEOGRAPH
+0xAA68	0x7326	#CJK UNIFIED IDEOGRAPH
+0xAA69	0x7327	#CJK UNIFIED IDEOGRAPH
+0xAA6A	0x7328	#CJK UNIFIED IDEOGRAPH
+0xAA6B	0x732D	#CJK UNIFIED IDEOGRAPH
+0xAA6C	0x732F	#CJK UNIFIED IDEOGRAPH
+0xAA6D	0x7330	#CJK UNIFIED IDEOGRAPH
+0xAA6E	0x7332	#CJK UNIFIED IDEOGRAPH
+0xAA6F	0x7333	#CJK UNIFIED IDEOGRAPH
+0xAA70	0x7335	#CJK UNIFIED IDEOGRAPH
+0xAA71	0x7336	#CJK UNIFIED IDEOGRAPH
+0xAA72	0x733A	#CJK UNIFIED IDEOGRAPH
+0xAA73	0x733B	#CJK UNIFIED IDEOGRAPH
+0xAA74	0x733C	#CJK UNIFIED IDEOGRAPH
+0xAA75	0x733D	#CJK UNIFIED IDEOGRAPH
+0xAA76	0x7340	#CJK UNIFIED IDEOGRAPH
+0xAA77	0x7341	#CJK UNIFIED IDEOGRAPH
+0xAA78	0x7342	#CJK UNIFIED IDEOGRAPH
+0xAA79	0x7343	#CJK UNIFIED IDEOGRAPH
+0xAA7A	0x7344	#CJK UNIFIED IDEOGRAPH
+0xAA7B	0x7345	#CJK UNIFIED IDEOGRAPH
+0xAA7C	0x7346	#CJK UNIFIED IDEOGRAPH
+0xAA7D	0x7347	#CJK UNIFIED IDEOGRAPH
+0xAA7E	0x7348	#CJK UNIFIED IDEOGRAPH
+0xAA80	0x7349	#CJK UNIFIED IDEOGRAPH
+0xAA81	0x734A	#CJK UNIFIED IDEOGRAPH
+0xAA82	0x734B	#CJK UNIFIED IDEOGRAPH
+0xAA83	0x734C	#CJK UNIFIED IDEOGRAPH
+0xAA84	0x734E	#CJK UNIFIED IDEOGRAPH
+0xAA85	0x734F	#CJK UNIFIED IDEOGRAPH
+0xAA86	0x7351	#CJK UNIFIED IDEOGRAPH
+0xAA87	0x7353	#CJK UNIFIED IDEOGRAPH
+0xAA88	0x7354	#CJK UNIFIED IDEOGRAPH
+0xAA89	0x7355	#CJK UNIFIED IDEOGRAPH
+0xAA8A	0x7356	#CJK UNIFIED IDEOGRAPH
+0xAA8B	0x7358	#CJK UNIFIED IDEOGRAPH
+0xAA8C	0x7359	#CJK UNIFIED IDEOGRAPH
+0xAA8D	0x735A	#CJK UNIFIED IDEOGRAPH
+0xAA8E	0x735B	#CJK UNIFIED IDEOGRAPH
+0xAA8F	0x735C	#CJK UNIFIED IDEOGRAPH
+0xAA90	0x735D	#CJK UNIFIED IDEOGRAPH
+0xAA91	0x735E	#CJK UNIFIED IDEOGRAPH
+0xAA92	0x735F	#CJK UNIFIED IDEOGRAPH
+0xAA93	0x7361	#CJK UNIFIED IDEOGRAPH
+0xAA94	0x7362	#CJK UNIFIED IDEOGRAPH
+0xAA95	0x7363	#CJK UNIFIED IDEOGRAPH
+0xAA96	0x7364	#CJK UNIFIED IDEOGRAPH
+0xAA97	0x7365	#CJK UNIFIED IDEOGRAPH
+0xAA98	0x7366	#CJK UNIFIED IDEOGRAPH
+0xAA99	0x7367	#CJK UNIFIED IDEOGRAPH
+0xAA9A	0x7368	#CJK UNIFIED IDEOGRAPH
+0xAA9B	0x7369	#CJK UNIFIED IDEOGRAPH
+0xAA9C	0x736A	#CJK UNIFIED IDEOGRAPH
+0xAA9D	0x736B	#CJK UNIFIED IDEOGRAPH
+0xAA9E	0x736E	#CJK UNIFIED IDEOGRAPH
+0xAA9F	0x7370	#CJK UNIFIED IDEOGRAPH
+0xAAA0	0x7371	#CJK UNIFIED IDEOGRAPH
+0xAB40	0x7372	#CJK UNIFIED IDEOGRAPH
+0xAB41	0x7373	#CJK UNIFIED IDEOGRAPH
+0xAB42	0x7374	#CJK UNIFIED IDEOGRAPH
+0xAB43	0x7375	#CJK UNIFIED IDEOGRAPH
+0xAB44	0x7376	#CJK UNIFIED IDEOGRAPH
+0xAB45	0x7377	#CJK UNIFIED IDEOGRAPH
+0xAB46	0x7378	#CJK UNIFIED IDEOGRAPH
+0xAB47	0x7379	#CJK UNIFIED IDEOGRAPH
+0xAB48	0x737A	#CJK UNIFIED IDEOGRAPH
+0xAB49	0x737B	#CJK UNIFIED IDEOGRAPH
+0xAB4A	0x737C	#CJK UNIFIED IDEOGRAPH
+0xAB4B	0x737D	#CJK UNIFIED IDEOGRAPH
+0xAB4C	0x737F	#CJK UNIFIED IDEOGRAPH
+0xAB4D	0x7380	#CJK UNIFIED IDEOGRAPH
+0xAB4E	0x7381	#CJK UNIFIED IDEOGRAPH
+0xAB4F	0x7382	#CJK UNIFIED IDEOGRAPH
+0xAB50	0x7383	#CJK UNIFIED IDEOGRAPH
+0xAB51	0x7385	#CJK UNIFIED IDEOGRAPH
+0xAB52	0x7386	#CJK UNIFIED IDEOGRAPH
+0xAB53	0x7388	#CJK UNIFIED IDEOGRAPH
+0xAB54	0x738A	#CJK UNIFIED IDEOGRAPH
+0xAB55	0x738C	#CJK UNIFIED IDEOGRAPH
+0xAB56	0x738D	#CJK UNIFIED IDEOGRAPH
+0xAB57	0x738F	#CJK UNIFIED IDEOGRAPH
+0xAB58	0x7390	#CJK UNIFIED IDEOGRAPH
+0xAB59	0x7392	#CJK UNIFIED IDEOGRAPH
+0xAB5A	0x7393	#CJK UNIFIED IDEOGRAPH
+0xAB5B	0x7394	#CJK UNIFIED IDEOGRAPH
+0xAB5C	0x7395	#CJK UNIFIED IDEOGRAPH
+0xAB5D	0x7397	#CJK UNIFIED IDEOGRAPH
+0xAB5E	0x7398	#CJK UNIFIED IDEOGRAPH
+0xAB5F	0x7399	#CJK UNIFIED IDEOGRAPH
+0xAB60	0x739A	#CJK UNIFIED IDEOGRAPH
+0xAB61	0x739C	#CJK UNIFIED IDEOGRAPH
+0xAB62	0x739D	#CJK UNIFIED IDEOGRAPH
+0xAB63	0x739E	#CJK UNIFIED IDEOGRAPH
+0xAB64	0x73A0	#CJK UNIFIED IDEOGRAPH
+0xAB65	0x73A1	#CJK UNIFIED IDEOGRAPH
+0xAB66	0x73A3	#CJK UNIFIED IDEOGRAPH
+0xAB67	0x73A4	#CJK UNIFIED IDEOGRAPH
+0xAB68	0x73A5	#CJK UNIFIED IDEOGRAPH
+0xAB69	0x73A6	#CJK UNIFIED IDEOGRAPH
+0xAB6A	0x73A7	#CJK UNIFIED IDEOGRAPH
+0xAB6B	0x73A8	#CJK UNIFIED IDEOGRAPH
+0xAB6C	0x73AA	#CJK UNIFIED IDEOGRAPH
+0xAB6D	0x73AC	#CJK UNIFIED IDEOGRAPH
+0xAB6E	0x73AD	#CJK UNIFIED IDEOGRAPH
+0xAB6F	0x73B1	#CJK UNIFIED IDEOGRAPH
+0xAB70	0x73B4	#CJK UNIFIED IDEOGRAPH
+0xAB71	0x73B5	#CJK UNIFIED IDEOGRAPH
+0xAB72	0x73B6	#CJK UNIFIED IDEOGRAPH
+0xAB73	0x73B8	#CJK UNIFIED IDEOGRAPH
+0xAB74	0x73B9	#CJK UNIFIED IDEOGRAPH
+0xAB75	0x73BC	#CJK UNIFIED IDEOGRAPH
+0xAB76	0x73BD	#CJK UNIFIED IDEOGRAPH
+0xAB77	0x73BE	#CJK UNIFIED IDEOGRAPH
+0xAB78	0x73BF	#CJK UNIFIED IDEOGRAPH
+0xAB79	0x73C1	#CJK UNIFIED IDEOGRAPH
+0xAB7A	0x73C3	#CJK UNIFIED IDEOGRAPH
+0xAB7B	0x73C4	#CJK UNIFIED IDEOGRAPH
+0xAB7C	0x73C5	#CJK UNIFIED IDEOGRAPH
+0xAB7D	0x73C6	#CJK UNIFIED IDEOGRAPH
+0xAB7E	0x73C7	#CJK UNIFIED IDEOGRAPH
+0xAB80	0x73CB	#CJK UNIFIED IDEOGRAPH
+0xAB81	0x73CC	#CJK UNIFIED IDEOGRAPH
+0xAB82	0x73CE	#CJK UNIFIED IDEOGRAPH
+0xAB83	0x73D2	#CJK UNIFIED IDEOGRAPH
+0xAB84	0x73D3	#CJK UNIFIED IDEOGRAPH
+0xAB85	0x73D4	#CJK UNIFIED IDEOGRAPH
+0xAB86	0x73D5	#CJK UNIFIED IDEOGRAPH
+0xAB87	0x73D6	#CJK UNIFIED IDEOGRAPH
+0xAB88	0x73D7	#CJK UNIFIED IDEOGRAPH
+0xAB89	0x73D8	#CJK UNIFIED IDEOGRAPH
+0xAB8A	0x73DA	#CJK UNIFIED IDEOGRAPH
+0xAB8B	0x73DB	#CJK UNIFIED IDEOGRAPH
+0xAB8C	0x73DC	#CJK UNIFIED IDEOGRAPH
+0xAB8D	0x73DD	#CJK UNIFIED IDEOGRAPH
+0xAB8E	0x73DF	#CJK UNIFIED IDEOGRAPH
+0xAB8F	0x73E1	#CJK UNIFIED IDEOGRAPH
+0xAB90	0x73E2	#CJK UNIFIED IDEOGRAPH
+0xAB91	0x73E3	#CJK UNIFIED IDEOGRAPH
+0xAB92	0x73E4	#CJK UNIFIED IDEOGRAPH
+0xAB93	0x73E6	#CJK UNIFIED IDEOGRAPH
+0xAB94	0x73E8	#CJK UNIFIED IDEOGRAPH
+0xAB95	0x73EA	#CJK UNIFIED IDEOGRAPH
+0xAB96	0x73EB	#CJK UNIFIED IDEOGRAPH
+0xAB97	0x73EC	#CJK UNIFIED IDEOGRAPH
+0xAB98	0x73EE	#CJK UNIFIED IDEOGRAPH
+0xAB99	0x73EF	#CJK UNIFIED IDEOGRAPH
+0xAB9A	0x73F0	#CJK UNIFIED IDEOGRAPH
+0xAB9B	0x73F1	#CJK UNIFIED IDEOGRAPH
+0xAB9C	0x73F3	#CJK UNIFIED IDEOGRAPH
+0xAB9D	0x73F4	#CJK UNIFIED IDEOGRAPH
+0xAB9E	0x73F5	#CJK UNIFIED IDEOGRAPH
+0xAB9F	0x73F6	#CJK UNIFIED IDEOGRAPH
+0xABA0	0x73F7	#CJK UNIFIED IDEOGRAPH
+0xAC40	0x73F8	#CJK UNIFIED IDEOGRAPH
+0xAC41	0x73F9	#CJK UNIFIED IDEOGRAPH
+0xAC42	0x73FA	#CJK UNIFIED IDEOGRAPH
+0xAC43	0x73FB	#CJK UNIFIED IDEOGRAPH
+0xAC44	0x73FC	#CJK UNIFIED IDEOGRAPH
+0xAC45	0x73FD	#CJK UNIFIED IDEOGRAPH
+0xAC46	0x73FE	#CJK UNIFIED IDEOGRAPH
+0xAC47	0x73FF	#CJK UNIFIED IDEOGRAPH
+0xAC48	0x7400	#CJK UNIFIED IDEOGRAPH
+0xAC49	0x7401	#CJK UNIFIED IDEOGRAPH
+0xAC4A	0x7402	#CJK UNIFIED IDEOGRAPH
+0xAC4B	0x7404	#CJK UNIFIED IDEOGRAPH
+0xAC4C	0x7407	#CJK UNIFIED IDEOGRAPH
+0xAC4D	0x7408	#CJK UNIFIED IDEOGRAPH
+0xAC4E	0x740B	#CJK UNIFIED IDEOGRAPH
+0xAC4F	0x740C	#CJK UNIFIED IDEOGRAPH
+0xAC50	0x740D	#CJK UNIFIED IDEOGRAPH
+0xAC51	0x740E	#CJK UNIFIED IDEOGRAPH
+0xAC52	0x7411	#CJK UNIFIED IDEOGRAPH
+0xAC53	0x7412	#CJK UNIFIED IDEOGRAPH
+0xAC54	0x7413	#CJK UNIFIED IDEOGRAPH
+0xAC55	0x7414	#CJK UNIFIED IDEOGRAPH
+0xAC56	0x7415	#CJK UNIFIED IDEOGRAPH
+0xAC57	0x7416	#CJK UNIFIED IDEOGRAPH
+0xAC58	0x7417	#CJK UNIFIED IDEOGRAPH
+0xAC59	0x7418	#CJK UNIFIED IDEOGRAPH
+0xAC5A	0x7419	#CJK UNIFIED IDEOGRAPH
+0xAC5B	0x741C	#CJK UNIFIED IDEOGRAPH
+0xAC5C	0x741D	#CJK UNIFIED IDEOGRAPH
+0xAC5D	0x741E	#CJK UNIFIED IDEOGRAPH
+0xAC5E	0x741F	#CJK UNIFIED IDEOGRAPH
+0xAC5F	0x7420	#CJK UNIFIED IDEOGRAPH
+0xAC60	0x7421	#CJK UNIFIED IDEOGRAPH
+0xAC61	0x7423	#CJK UNIFIED IDEOGRAPH
+0xAC62	0x7424	#CJK UNIFIED IDEOGRAPH
+0xAC63	0x7427	#CJK UNIFIED IDEOGRAPH
+0xAC64	0x7429	#CJK UNIFIED IDEOGRAPH
+0xAC65	0x742B	#CJK UNIFIED IDEOGRAPH
+0xAC66	0x742D	#CJK UNIFIED IDEOGRAPH
+0xAC67	0x742F	#CJK UNIFIED IDEOGRAPH
+0xAC68	0x7431	#CJK UNIFIED IDEOGRAPH
+0xAC69	0x7432	#CJK UNIFIED IDEOGRAPH
+0xAC6A	0x7437	#CJK UNIFIED IDEOGRAPH
+0xAC6B	0x7438	#CJK UNIFIED IDEOGRAPH
+0xAC6C	0x7439	#CJK UNIFIED IDEOGRAPH
+0xAC6D	0x743A	#CJK UNIFIED IDEOGRAPH
+0xAC6E	0x743B	#CJK UNIFIED IDEOGRAPH
+0xAC6F	0x743D	#CJK UNIFIED IDEOGRAPH
+0xAC70	0x743E	#CJK UNIFIED IDEOGRAPH
+0xAC71	0x743F	#CJK UNIFIED IDEOGRAPH
+0xAC72	0x7440	#CJK UNIFIED IDEOGRAPH
+0xAC73	0x7442	#CJK UNIFIED IDEOGRAPH
+0xAC74	0x7443	#CJK UNIFIED IDEOGRAPH
+0xAC75	0x7444	#CJK UNIFIED IDEOGRAPH
+0xAC76	0x7445	#CJK UNIFIED IDEOGRAPH
+0xAC77	0x7446	#CJK UNIFIED IDEOGRAPH
+0xAC78	0x7447	#CJK UNIFIED IDEOGRAPH
+0xAC79	0x7448	#CJK UNIFIED IDEOGRAPH
+0xAC7A	0x7449	#CJK UNIFIED IDEOGRAPH
+0xAC7B	0x744A	#CJK UNIFIED IDEOGRAPH
+0xAC7C	0x744B	#CJK UNIFIED IDEOGRAPH
+0xAC7D	0x744C	#CJK UNIFIED IDEOGRAPH
+0xAC7E	0x744D	#CJK UNIFIED IDEOGRAPH
+0xAC80	0x744E	#CJK UNIFIED IDEOGRAPH
+0xAC81	0x744F	#CJK UNIFIED IDEOGRAPH
+0xAC82	0x7450	#CJK UNIFIED IDEOGRAPH
+0xAC83	0x7451	#CJK UNIFIED IDEOGRAPH
+0xAC84	0x7452	#CJK UNIFIED IDEOGRAPH
+0xAC85	0x7453	#CJK UNIFIED IDEOGRAPH
+0xAC86	0x7454	#CJK UNIFIED IDEOGRAPH
+0xAC87	0x7456	#CJK UNIFIED IDEOGRAPH
+0xAC88	0x7458	#CJK UNIFIED IDEOGRAPH
+0xAC89	0x745D	#CJK UNIFIED IDEOGRAPH
+0xAC8A	0x7460	#CJK UNIFIED IDEOGRAPH
+0xAC8B	0x7461	#CJK UNIFIED IDEOGRAPH
+0xAC8C	0x7462	#CJK UNIFIED IDEOGRAPH
+0xAC8D	0x7463	#CJK UNIFIED IDEOGRAPH
+0xAC8E	0x7464	#CJK UNIFIED IDEOGRAPH
+0xAC8F	0x7465	#CJK UNIFIED IDEOGRAPH
+0xAC90	0x7466	#CJK UNIFIED IDEOGRAPH
+0xAC91	0x7467	#CJK UNIFIED IDEOGRAPH
+0xAC92	0x7468	#CJK UNIFIED IDEOGRAPH
+0xAC93	0x7469	#CJK UNIFIED IDEOGRAPH
+0xAC94	0x746A	#CJK UNIFIED IDEOGRAPH
+0xAC95	0x746B	#CJK UNIFIED IDEOGRAPH
+0xAC96	0x746C	#CJK UNIFIED IDEOGRAPH
+0xAC97	0x746E	#CJK UNIFIED IDEOGRAPH
+0xAC98	0x746F	#CJK UNIFIED IDEOGRAPH
+0xAC99	0x7471	#CJK UNIFIED IDEOGRAPH
+0xAC9A	0x7472	#CJK UNIFIED IDEOGRAPH
+0xAC9B	0x7473	#CJK UNIFIED IDEOGRAPH
+0xAC9C	0x7474	#CJK UNIFIED IDEOGRAPH
+0xAC9D	0x7475	#CJK UNIFIED IDEOGRAPH
+0xAC9E	0x7478	#CJK UNIFIED IDEOGRAPH
+0xAC9F	0x7479	#CJK UNIFIED IDEOGRAPH
+0xACA0	0x747A	#CJK UNIFIED IDEOGRAPH
+0xAD40	0x747B	#CJK UNIFIED IDEOGRAPH
+0xAD41	0x747C	#CJK UNIFIED IDEOGRAPH
+0xAD42	0x747D	#CJK UNIFIED IDEOGRAPH
+0xAD43	0x747F	#CJK UNIFIED IDEOGRAPH
+0xAD44	0x7482	#CJK UNIFIED IDEOGRAPH
+0xAD45	0x7484	#CJK UNIFIED IDEOGRAPH
+0xAD46	0x7485	#CJK UNIFIED IDEOGRAPH
+0xAD47	0x7486	#CJK UNIFIED IDEOGRAPH
+0xAD48	0x7488	#CJK UNIFIED IDEOGRAPH
+0xAD49	0x7489	#CJK UNIFIED IDEOGRAPH
+0xAD4A	0x748A	#CJK UNIFIED IDEOGRAPH
+0xAD4B	0x748C	#CJK UNIFIED IDEOGRAPH
+0xAD4C	0x748D	#CJK UNIFIED IDEOGRAPH
+0xAD4D	0x748F	#CJK UNIFIED IDEOGRAPH
+0xAD4E	0x7491	#CJK UNIFIED IDEOGRAPH
+0xAD4F	0x7492	#CJK UNIFIED IDEOGRAPH
+0xAD50	0x7493	#CJK UNIFIED IDEOGRAPH
+0xAD51	0x7494	#CJK UNIFIED IDEOGRAPH
+0xAD52	0x7495	#CJK UNIFIED IDEOGRAPH
+0xAD53	0x7496	#CJK UNIFIED IDEOGRAPH
+0xAD54	0x7497	#CJK UNIFIED IDEOGRAPH
+0xAD55	0x7498	#CJK UNIFIED IDEOGRAPH
+0xAD56	0x7499	#CJK UNIFIED IDEOGRAPH
+0xAD57	0x749A	#CJK UNIFIED IDEOGRAPH
+0xAD58	0x749B	#CJK UNIFIED IDEOGRAPH
+0xAD59	0x749D	#CJK UNIFIED IDEOGRAPH
+0xAD5A	0x749F	#CJK UNIFIED IDEOGRAPH
+0xAD5B	0x74A0	#CJK UNIFIED IDEOGRAPH
+0xAD5C	0x74A1	#CJK UNIFIED IDEOGRAPH
+0xAD5D	0x74A2	#CJK UNIFIED IDEOGRAPH
+0xAD5E	0x74A3	#CJK UNIFIED IDEOGRAPH
+0xAD5F	0x74A4	#CJK UNIFIED IDEOGRAPH
+0xAD60	0x74A5	#CJK UNIFIED IDEOGRAPH
+0xAD61	0x74A6	#CJK UNIFIED IDEOGRAPH
+0xAD62	0x74AA	#CJK UNIFIED IDEOGRAPH
+0xAD63	0x74AB	#CJK UNIFIED IDEOGRAPH
+0xAD64	0x74AC	#CJK UNIFIED IDEOGRAPH
+0xAD65	0x74AD	#CJK UNIFIED IDEOGRAPH
+0xAD66	0x74AE	#CJK UNIFIED IDEOGRAPH
+0xAD67	0x74AF	#CJK UNIFIED IDEOGRAPH
+0xAD68	0x74B0	#CJK UNIFIED IDEOGRAPH
+0xAD69	0x74B1	#CJK UNIFIED IDEOGRAPH
+0xAD6A	0x74B2	#CJK UNIFIED IDEOGRAPH
+0xAD6B	0x74B3	#CJK UNIFIED IDEOGRAPH
+0xAD6C	0x74B4	#CJK UNIFIED IDEOGRAPH
+0xAD6D	0x74B5	#CJK UNIFIED IDEOGRAPH
+0xAD6E	0x74B6	#CJK UNIFIED IDEOGRAPH
+0xAD6F	0x74B7	#CJK UNIFIED IDEOGRAPH
+0xAD70	0x74B8	#CJK UNIFIED IDEOGRAPH
+0xAD71	0x74B9	#CJK UNIFIED IDEOGRAPH
+0xAD72	0x74BB	#CJK UNIFIED IDEOGRAPH
+0xAD73	0x74BC	#CJK UNIFIED IDEOGRAPH
+0xAD74	0x74BD	#CJK UNIFIED IDEOGRAPH
+0xAD75	0x74BE	#CJK UNIFIED IDEOGRAPH
+0xAD76	0x74BF	#CJK UNIFIED IDEOGRAPH
+0xAD77	0x74C0	#CJK UNIFIED IDEOGRAPH
+0xAD78	0x74C1	#CJK UNIFIED IDEOGRAPH
+0xAD79	0x74C2	#CJK UNIFIED IDEOGRAPH
+0xAD7A	0x74C3	#CJK UNIFIED IDEOGRAPH
+0xAD7B	0x74C4	#CJK UNIFIED IDEOGRAPH
+0xAD7C	0x74C5	#CJK UNIFIED IDEOGRAPH
+0xAD7D	0x74C6	#CJK UNIFIED IDEOGRAPH
+0xAD7E	0x74C7	#CJK UNIFIED IDEOGRAPH
+0xAD80	0x74C8	#CJK UNIFIED IDEOGRAPH
+0xAD81	0x74C9	#CJK UNIFIED IDEOGRAPH
+0xAD82	0x74CA	#CJK UNIFIED IDEOGRAPH
+0xAD83	0x74CB	#CJK UNIFIED IDEOGRAPH
+0xAD84	0x74CC	#CJK UNIFIED IDEOGRAPH
+0xAD85	0x74CD	#CJK UNIFIED IDEOGRAPH
+0xAD86	0x74CE	#CJK UNIFIED IDEOGRAPH
+0xAD87	0x74CF	#CJK UNIFIED IDEOGRAPH
+0xAD88	0x74D0	#CJK UNIFIED IDEOGRAPH
+0xAD89	0x74D1	#CJK UNIFIED IDEOGRAPH
+0xAD8A	0x74D3	#CJK UNIFIED IDEOGRAPH
+0xAD8B	0x74D4	#CJK UNIFIED IDEOGRAPH
+0xAD8C	0x74D5	#CJK UNIFIED IDEOGRAPH
+0xAD8D	0x74D6	#CJK UNIFIED IDEOGRAPH
+0xAD8E	0x74D7	#CJK UNIFIED IDEOGRAPH
+0xAD8F	0x74D8	#CJK UNIFIED IDEOGRAPH
+0xAD90	0x74D9	#CJK UNIFIED IDEOGRAPH
+0xAD91	0x74DA	#CJK UNIFIED IDEOGRAPH
+0xAD92	0x74DB	#CJK UNIFIED IDEOGRAPH
+0xAD93	0x74DD	#CJK UNIFIED IDEOGRAPH
+0xAD94	0x74DF	#CJK UNIFIED IDEOGRAPH
+0xAD95	0x74E1	#CJK UNIFIED IDEOGRAPH
+0xAD96	0x74E5	#CJK UNIFIED IDEOGRAPH
+0xAD97	0x74E7	#CJK UNIFIED IDEOGRAPH
+0xAD98	0x74E8	#CJK UNIFIED IDEOGRAPH
+0xAD99	0x74E9	#CJK UNIFIED IDEOGRAPH
+0xAD9A	0x74EA	#CJK UNIFIED IDEOGRAPH
+0xAD9B	0x74EB	#CJK UNIFIED IDEOGRAPH
+0xAD9C	0x74EC	#CJK UNIFIED IDEOGRAPH
+0xAD9D	0x74ED	#CJK UNIFIED IDEOGRAPH
+0xAD9E	0x74F0	#CJK UNIFIED IDEOGRAPH
+0xAD9F	0x74F1	#CJK UNIFIED IDEOGRAPH
+0xADA0	0x74F2	#CJK UNIFIED IDEOGRAPH
+0xAE40	0x74F3	#CJK UNIFIED IDEOGRAPH
+0xAE41	0x74F5	#CJK UNIFIED IDEOGRAPH
+0xAE42	0x74F8	#CJK UNIFIED IDEOGRAPH
+0xAE43	0x74F9	#CJK UNIFIED IDEOGRAPH
+0xAE44	0x74FA	#CJK UNIFIED IDEOGRAPH
+0xAE45	0x74FB	#CJK UNIFIED IDEOGRAPH
+0xAE46	0x74FC	#CJK UNIFIED IDEOGRAPH
+0xAE47	0x74FD	#CJK UNIFIED IDEOGRAPH
+0xAE48	0x74FE	#CJK UNIFIED IDEOGRAPH
+0xAE49	0x7500	#CJK UNIFIED IDEOGRAPH
+0xAE4A	0x7501	#CJK UNIFIED IDEOGRAPH
+0xAE4B	0x7502	#CJK UNIFIED IDEOGRAPH
+0xAE4C	0x7503	#CJK UNIFIED IDEOGRAPH
+0xAE4D	0x7505	#CJK UNIFIED IDEOGRAPH
+0xAE4E	0x7506	#CJK UNIFIED IDEOGRAPH
+0xAE4F	0x7507	#CJK UNIFIED IDEOGRAPH
+0xAE50	0x7508	#CJK UNIFIED IDEOGRAPH
+0xAE51	0x7509	#CJK UNIFIED IDEOGRAPH
+0xAE52	0x750A	#CJK UNIFIED IDEOGRAPH
+0xAE53	0x750B	#CJK UNIFIED IDEOGRAPH
+0xAE54	0x750C	#CJK UNIFIED IDEOGRAPH
+0xAE55	0x750E	#CJK UNIFIED IDEOGRAPH
+0xAE56	0x7510	#CJK UNIFIED IDEOGRAPH
+0xAE57	0x7512	#CJK UNIFIED IDEOGRAPH
+0xAE58	0x7514	#CJK UNIFIED IDEOGRAPH
+0xAE59	0x7515	#CJK UNIFIED IDEOGRAPH
+0xAE5A	0x7516	#CJK UNIFIED IDEOGRAPH
+0xAE5B	0x7517	#CJK UNIFIED IDEOGRAPH
+0xAE5C	0x751B	#CJK UNIFIED IDEOGRAPH
+0xAE5D	0x751D	#CJK UNIFIED IDEOGRAPH
+0xAE5E	0x751E	#CJK UNIFIED IDEOGRAPH
+0xAE5F	0x7520	#CJK UNIFIED IDEOGRAPH
+0xAE60	0x7521	#CJK UNIFIED IDEOGRAPH
+0xAE61	0x7522	#CJK UNIFIED IDEOGRAPH
+0xAE62	0x7523	#CJK UNIFIED IDEOGRAPH
+0xAE63	0x7524	#CJK UNIFIED IDEOGRAPH
+0xAE64	0x7526	#CJK UNIFIED IDEOGRAPH
+0xAE65	0x7527	#CJK UNIFIED IDEOGRAPH
+0xAE66	0x752A	#CJK UNIFIED IDEOGRAPH
+0xAE67	0x752E	#CJK UNIFIED IDEOGRAPH
+0xAE68	0x7534	#CJK UNIFIED IDEOGRAPH
+0xAE69	0x7536	#CJK UNIFIED IDEOGRAPH
+0xAE6A	0x7539	#CJK UNIFIED IDEOGRAPH
+0xAE6B	0x753C	#CJK UNIFIED IDEOGRAPH
+0xAE6C	0x753D	#CJK UNIFIED IDEOGRAPH
+0xAE6D	0x753F	#CJK UNIFIED IDEOGRAPH
+0xAE6E	0x7541	#CJK UNIFIED IDEOGRAPH
+0xAE6F	0x7542	#CJK UNIFIED IDEOGRAPH
+0xAE70	0x7543	#CJK UNIFIED IDEOGRAPH
+0xAE71	0x7544	#CJK UNIFIED IDEOGRAPH
+0xAE72	0x7546	#CJK UNIFIED IDEOGRAPH
+0xAE73	0x7547	#CJK UNIFIED IDEOGRAPH
+0xAE74	0x7549	#CJK UNIFIED IDEOGRAPH
+0xAE75	0x754A	#CJK UNIFIED IDEOGRAPH
+0xAE76	0x754D	#CJK UNIFIED IDEOGRAPH
+0xAE77	0x7550	#CJK UNIFIED IDEOGRAPH
+0xAE78	0x7551	#CJK UNIFIED IDEOGRAPH
+0xAE79	0x7552	#CJK UNIFIED IDEOGRAPH
+0xAE7A	0x7553	#CJK UNIFIED IDEOGRAPH
+0xAE7B	0x7555	#CJK UNIFIED IDEOGRAPH
+0xAE7C	0x7556	#CJK UNIFIED IDEOGRAPH
+0xAE7D	0x7557	#CJK UNIFIED IDEOGRAPH
+0xAE7E	0x7558	#CJK UNIFIED IDEOGRAPH
+0xAE80	0x755D	#CJK UNIFIED IDEOGRAPH
+0xAE81	0x755E	#CJK UNIFIED IDEOGRAPH
+0xAE82	0x755F	#CJK UNIFIED IDEOGRAPH
+0xAE83	0x7560	#CJK UNIFIED IDEOGRAPH
+0xAE84	0x7561	#CJK UNIFIED IDEOGRAPH
+0xAE85	0x7562	#CJK UNIFIED IDEOGRAPH
+0xAE86	0x7563	#CJK UNIFIED IDEOGRAPH
+0xAE87	0x7564	#CJK UNIFIED IDEOGRAPH
+0xAE88	0x7567	#CJK UNIFIED IDEOGRAPH
+0xAE89	0x7568	#CJK UNIFIED IDEOGRAPH
+0xAE8A	0x7569	#CJK UNIFIED IDEOGRAPH
+0xAE8B	0x756B	#CJK UNIFIED IDEOGRAPH
+0xAE8C	0x756C	#CJK UNIFIED IDEOGRAPH
+0xAE8D	0x756D	#CJK UNIFIED IDEOGRAPH
+0xAE8E	0x756E	#CJK UNIFIED IDEOGRAPH
+0xAE8F	0x756F	#CJK UNIFIED IDEOGRAPH
+0xAE90	0x7570	#CJK UNIFIED IDEOGRAPH
+0xAE91	0x7571	#CJK UNIFIED IDEOGRAPH
+0xAE92	0x7573	#CJK UNIFIED IDEOGRAPH
+0xAE93	0x7575	#CJK UNIFIED IDEOGRAPH
+0xAE94	0x7576	#CJK UNIFIED IDEOGRAPH
+0xAE95	0x7577	#CJK UNIFIED IDEOGRAPH
+0xAE96	0x757A	#CJK UNIFIED IDEOGRAPH
+0xAE97	0x757B	#CJK UNIFIED IDEOGRAPH
+0xAE98	0x757C	#CJK UNIFIED IDEOGRAPH
+0xAE99	0x757D	#CJK UNIFIED IDEOGRAPH
+0xAE9A	0x757E	#CJK UNIFIED IDEOGRAPH
+0xAE9B	0x7580	#CJK UNIFIED IDEOGRAPH
+0xAE9C	0x7581	#CJK UNIFIED IDEOGRAPH
+0xAE9D	0x7582	#CJK UNIFIED IDEOGRAPH
+0xAE9E	0x7584	#CJK UNIFIED IDEOGRAPH
+0xAE9F	0x7585	#CJK UNIFIED IDEOGRAPH
+0xAEA0	0x7587	#CJK UNIFIED IDEOGRAPH
+0xAF40	0x7588	#CJK UNIFIED IDEOGRAPH
+0xAF41	0x7589	#CJK UNIFIED IDEOGRAPH
+0xAF42	0x758A	#CJK UNIFIED IDEOGRAPH
+0xAF43	0x758C	#CJK UNIFIED IDEOGRAPH
+0xAF44	0x758D	#CJK UNIFIED IDEOGRAPH
+0xAF45	0x758E	#CJK UNIFIED IDEOGRAPH
+0xAF46	0x7590	#CJK UNIFIED IDEOGRAPH
+0xAF47	0x7593	#CJK UNIFIED IDEOGRAPH
+0xAF48	0x7595	#CJK UNIFIED IDEOGRAPH
+0xAF49	0x7598	#CJK UNIFIED IDEOGRAPH
+0xAF4A	0x759B	#CJK UNIFIED IDEOGRAPH
+0xAF4B	0x759C	#CJK UNIFIED IDEOGRAPH
+0xAF4C	0x759E	#CJK UNIFIED IDEOGRAPH
+0xAF4D	0x75A2	#CJK UNIFIED IDEOGRAPH
+0xAF4E	0x75A6	#CJK UNIFIED IDEOGRAPH
+0xAF4F	0x75A7	#CJK UNIFIED IDEOGRAPH
+0xAF50	0x75A8	#CJK UNIFIED IDEOGRAPH
+0xAF51	0x75A9	#CJK UNIFIED IDEOGRAPH
+0xAF52	0x75AA	#CJK UNIFIED IDEOGRAPH
+0xAF53	0x75AD	#CJK UNIFIED IDEOGRAPH
+0xAF54	0x75B6	#CJK UNIFIED IDEOGRAPH
+0xAF55	0x75B7	#CJK UNIFIED IDEOGRAPH
+0xAF56	0x75BA	#CJK UNIFIED IDEOGRAPH
+0xAF57	0x75BB	#CJK UNIFIED IDEOGRAPH
+0xAF58	0x75BF	#CJK UNIFIED IDEOGRAPH
+0xAF59	0x75C0	#CJK UNIFIED IDEOGRAPH
+0xAF5A	0x75C1	#CJK UNIFIED IDEOGRAPH
+0xAF5B	0x75C6	#CJK UNIFIED IDEOGRAPH
+0xAF5C	0x75CB	#CJK UNIFIED IDEOGRAPH
+0xAF5D	0x75CC	#CJK UNIFIED IDEOGRAPH
+0xAF5E	0x75CE	#CJK UNIFIED IDEOGRAPH
+0xAF5F	0x75CF	#CJK UNIFIED IDEOGRAPH
+0xAF60	0x75D0	#CJK UNIFIED IDEOGRAPH
+0xAF61	0x75D1	#CJK UNIFIED IDEOGRAPH
+0xAF62	0x75D3	#CJK UNIFIED IDEOGRAPH
+0xAF63	0x75D7	#CJK UNIFIED IDEOGRAPH
+0xAF64	0x75D9	#CJK UNIFIED IDEOGRAPH
+0xAF65	0x75DA	#CJK UNIFIED IDEOGRAPH
+0xAF66	0x75DC	#CJK UNIFIED IDEOGRAPH
+0xAF67	0x75DD	#CJK UNIFIED IDEOGRAPH
+0xAF68	0x75DF	#CJK UNIFIED IDEOGRAPH
+0xAF69	0x75E0	#CJK UNIFIED IDEOGRAPH
+0xAF6A	0x75E1	#CJK UNIFIED IDEOGRAPH
+0xAF6B	0x75E5	#CJK UNIFIED IDEOGRAPH
+0xAF6C	0x75E9	#CJK UNIFIED IDEOGRAPH
+0xAF6D	0x75EC	#CJK UNIFIED IDEOGRAPH
+0xAF6E	0x75ED	#CJK UNIFIED IDEOGRAPH
+0xAF6F	0x75EE	#CJK UNIFIED IDEOGRAPH
+0xAF70	0x75EF	#CJK UNIFIED IDEOGRAPH
+0xAF71	0x75F2	#CJK UNIFIED IDEOGRAPH
+0xAF72	0x75F3	#CJK UNIFIED IDEOGRAPH
+0xAF73	0x75F5	#CJK UNIFIED IDEOGRAPH
+0xAF74	0x75F6	#CJK UNIFIED IDEOGRAPH
+0xAF75	0x75F7	#CJK UNIFIED IDEOGRAPH
+0xAF76	0x75F8	#CJK UNIFIED IDEOGRAPH
+0xAF77	0x75FA	#CJK UNIFIED IDEOGRAPH
+0xAF78	0x75FB	#CJK UNIFIED IDEOGRAPH
+0xAF79	0x75FD	#CJK UNIFIED IDEOGRAPH
+0xAF7A	0x75FE	#CJK UNIFIED IDEOGRAPH
+0xAF7B	0x7602	#CJK UNIFIED IDEOGRAPH
+0xAF7C	0x7604	#CJK UNIFIED IDEOGRAPH
+0xAF7D	0x7606	#CJK UNIFIED IDEOGRAPH
+0xAF7E	0x7607	#CJK UNIFIED IDEOGRAPH
+0xAF80	0x7608	#CJK UNIFIED IDEOGRAPH
+0xAF81	0x7609	#CJK UNIFIED IDEOGRAPH
+0xAF82	0x760B	#CJK UNIFIED IDEOGRAPH
+0xAF83	0x760D	#CJK UNIFIED IDEOGRAPH
+0xAF84	0x760E	#CJK UNIFIED IDEOGRAPH
+0xAF85	0x760F	#CJK UNIFIED IDEOGRAPH
+0xAF86	0x7611	#CJK UNIFIED IDEOGRAPH
+0xAF87	0x7612	#CJK UNIFIED IDEOGRAPH
+0xAF88	0x7613	#CJK UNIFIED IDEOGRAPH
+0xAF89	0x7614	#CJK UNIFIED IDEOGRAPH
+0xAF8A	0x7616	#CJK UNIFIED IDEOGRAPH
+0xAF8B	0x761A	#CJK UNIFIED IDEOGRAPH
+0xAF8C	0x761C	#CJK UNIFIED IDEOGRAPH
+0xAF8D	0x761D	#CJK UNIFIED IDEOGRAPH
+0xAF8E	0x761E	#CJK UNIFIED IDEOGRAPH
+0xAF8F	0x7621	#CJK UNIFIED IDEOGRAPH
+0xAF90	0x7623	#CJK UNIFIED IDEOGRAPH
+0xAF91	0x7627	#CJK UNIFIED IDEOGRAPH
+0xAF92	0x7628	#CJK UNIFIED IDEOGRAPH
+0xAF93	0x762C	#CJK UNIFIED IDEOGRAPH
+0xAF94	0x762E	#CJK UNIFIED IDEOGRAPH
+0xAF95	0x762F	#CJK UNIFIED IDEOGRAPH
+0xAF96	0x7631	#CJK UNIFIED IDEOGRAPH
+0xAF97	0x7632	#CJK UNIFIED IDEOGRAPH
+0xAF98	0x7636	#CJK UNIFIED IDEOGRAPH
+0xAF99	0x7637	#CJK UNIFIED IDEOGRAPH
+0xAF9A	0x7639	#CJK UNIFIED IDEOGRAPH
+0xAF9B	0x763A	#CJK UNIFIED IDEOGRAPH
+0xAF9C	0x763B	#CJK UNIFIED IDEOGRAPH
+0xAF9D	0x763D	#CJK UNIFIED IDEOGRAPH
+0xAF9E	0x7641	#CJK UNIFIED IDEOGRAPH
+0xAF9F	0x7642	#CJK UNIFIED IDEOGRAPH
+0xAFA0	0x7644	#CJK UNIFIED IDEOGRAPH
+0xB040	0x7645	#CJK UNIFIED IDEOGRAPH
+0xB041	0x7646	#CJK UNIFIED IDEOGRAPH
+0xB042	0x7647	#CJK UNIFIED IDEOGRAPH
+0xB043	0x7648	#CJK UNIFIED IDEOGRAPH
+0xB044	0x7649	#CJK UNIFIED IDEOGRAPH
+0xB045	0x764A	#CJK UNIFIED IDEOGRAPH
+0xB046	0x764B	#CJK UNIFIED IDEOGRAPH
+0xB047	0x764E	#CJK UNIFIED IDEOGRAPH
+0xB048	0x764F	#CJK UNIFIED IDEOGRAPH
+0xB049	0x7650	#CJK UNIFIED IDEOGRAPH
+0xB04A	0x7651	#CJK UNIFIED IDEOGRAPH
+0xB04B	0x7652	#CJK UNIFIED IDEOGRAPH
+0xB04C	0x7653	#CJK UNIFIED IDEOGRAPH
+0xB04D	0x7655	#CJK UNIFIED IDEOGRAPH
+0xB04E	0x7657	#CJK UNIFIED IDEOGRAPH
+0xB04F	0x7658	#CJK UNIFIED IDEOGRAPH
+0xB050	0x7659	#CJK UNIFIED IDEOGRAPH
+0xB051	0x765A	#CJK UNIFIED IDEOGRAPH
+0xB052	0x765B	#CJK UNIFIED IDEOGRAPH
+0xB053	0x765D	#CJK UNIFIED IDEOGRAPH
+0xB054	0x765F	#CJK UNIFIED IDEOGRAPH
+0xB055	0x7660	#CJK UNIFIED IDEOGRAPH
+0xB056	0x7661	#CJK UNIFIED IDEOGRAPH
+0xB057	0x7662	#CJK UNIFIED IDEOGRAPH
+0xB058	0x7664	#CJK UNIFIED IDEOGRAPH
+0xB059	0x7665	#CJK UNIFIED IDEOGRAPH
+0xB05A	0x7666	#CJK UNIFIED IDEOGRAPH
+0xB05B	0x7667	#CJK UNIFIED IDEOGRAPH
+0xB05C	0x7668	#CJK UNIFIED IDEOGRAPH
+0xB05D	0x7669	#CJK UNIFIED IDEOGRAPH
+0xB05E	0x766A	#CJK UNIFIED IDEOGRAPH
+0xB05F	0x766C	#CJK UNIFIED IDEOGRAPH
+0xB060	0x766D	#CJK UNIFIED IDEOGRAPH
+0xB061	0x766E	#CJK UNIFIED IDEOGRAPH
+0xB062	0x7670	#CJK UNIFIED IDEOGRAPH
+0xB063	0x7671	#CJK UNIFIED IDEOGRAPH
+0xB064	0x7672	#CJK UNIFIED IDEOGRAPH
+0xB065	0x7673	#CJK UNIFIED IDEOGRAPH
+0xB066	0x7674	#CJK UNIFIED IDEOGRAPH
+0xB067	0x7675	#CJK UNIFIED IDEOGRAPH
+0xB068	0x7676	#CJK UNIFIED IDEOGRAPH
+0xB069	0x7677	#CJK UNIFIED IDEOGRAPH
+0xB06A	0x7679	#CJK UNIFIED IDEOGRAPH
+0xB06B	0x767A	#CJK UNIFIED IDEOGRAPH
+0xB06C	0x767C	#CJK UNIFIED IDEOGRAPH
+0xB06D	0x767F	#CJK UNIFIED IDEOGRAPH
+0xB06E	0x7680	#CJK UNIFIED IDEOGRAPH
+0xB06F	0x7681	#CJK UNIFIED IDEOGRAPH
+0xB070	0x7683	#CJK UNIFIED IDEOGRAPH
+0xB071	0x7685	#CJK UNIFIED IDEOGRAPH
+0xB072	0x7689	#CJK UNIFIED IDEOGRAPH
+0xB073	0x768A	#CJK UNIFIED IDEOGRAPH
+0xB074	0x768C	#CJK UNIFIED IDEOGRAPH
+0xB075	0x768D	#CJK UNIFIED IDEOGRAPH
+0xB076	0x768F	#CJK UNIFIED IDEOGRAPH
+0xB077	0x7690	#CJK UNIFIED IDEOGRAPH
+0xB078	0x7692	#CJK UNIFIED IDEOGRAPH
+0xB079	0x7694	#CJK UNIFIED IDEOGRAPH
+0xB07A	0x7695	#CJK UNIFIED IDEOGRAPH
+0xB07B	0x7697	#CJK UNIFIED IDEOGRAPH
+0xB07C	0x7698	#CJK UNIFIED IDEOGRAPH
+0xB07D	0x769A	#CJK UNIFIED IDEOGRAPH
+0xB07E	0x769B	#CJK UNIFIED IDEOGRAPH
+0xB080	0x769C	#CJK UNIFIED IDEOGRAPH
+0xB081	0x769D	#CJK UNIFIED IDEOGRAPH
+0xB082	0x769E	#CJK UNIFIED IDEOGRAPH
+0xB083	0x769F	#CJK UNIFIED IDEOGRAPH
+0xB084	0x76A0	#CJK UNIFIED IDEOGRAPH
+0xB085	0x76A1	#CJK UNIFIED IDEOGRAPH
+0xB086	0x76A2	#CJK UNIFIED IDEOGRAPH
+0xB087	0x76A3	#CJK UNIFIED IDEOGRAPH
+0xB088	0x76A5	#CJK UNIFIED IDEOGRAPH
+0xB089	0x76A6	#CJK UNIFIED IDEOGRAPH
+0xB08A	0x76A7	#CJK UNIFIED IDEOGRAPH
+0xB08B	0x76A8	#CJK UNIFIED IDEOGRAPH
+0xB08C	0x76A9	#CJK UNIFIED IDEOGRAPH
+0xB08D	0x76AA	#CJK UNIFIED IDEOGRAPH
+0xB08E	0x76AB	#CJK UNIFIED IDEOGRAPH
+0xB08F	0x76AC	#CJK UNIFIED IDEOGRAPH
+0xB090	0x76AD	#CJK UNIFIED IDEOGRAPH
+0xB091	0x76AF	#CJK UNIFIED IDEOGRAPH
+0xB092	0x76B0	#CJK UNIFIED IDEOGRAPH
+0xB093	0x76B3	#CJK UNIFIED IDEOGRAPH
+0xB094	0x76B5	#CJK UNIFIED IDEOGRAPH
+0xB095	0x76B6	#CJK UNIFIED IDEOGRAPH
+0xB096	0x76B7	#CJK UNIFIED IDEOGRAPH
+0xB097	0x76B8	#CJK UNIFIED IDEOGRAPH
+0xB098	0x76B9	#CJK UNIFIED IDEOGRAPH
+0xB099	0x76BA	#CJK UNIFIED IDEOGRAPH
+0xB09A	0x76BB	#CJK UNIFIED IDEOGRAPH
+0xB09B	0x76BC	#CJK UNIFIED IDEOGRAPH
+0xB09C	0x76BD	#CJK UNIFIED IDEOGRAPH
+0xB09D	0x76BE	#CJK UNIFIED IDEOGRAPH
+0xB09E	0x76C0	#CJK UNIFIED IDEOGRAPH
+0xB09F	0x76C1	#CJK UNIFIED IDEOGRAPH
+0xB0A0	0x76C3	#CJK UNIFIED IDEOGRAPH
+0xB0A1	0x554A	#CJK UNIFIED IDEOGRAPH
+0xB0A2	0x963F	#CJK UNIFIED IDEOGRAPH
+0xB0A3	0x57C3	#CJK UNIFIED IDEOGRAPH
+0xB0A4	0x6328	#CJK UNIFIED IDEOGRAPH
+0xB0A5	0x54CE	#CJK UNIFIED IDEOGRAPH
+0xB0A6	0x5509	#CJK UNIFIED IDEOGRAPH
+0xB0A7	0x54C0	#CJK UNIFIED IDEOGRAPH
+0xB0A8	0x7691	#CJK UNIFIED IDEOGRAPH
+0xB0A9	0x764C	#CJK UNIFIED IDEOGRAPH
+0xB0AA	0x853C	#CJK UNIFIED IDEOGRAPH
+0xB0AB	0x77EE	#CJK UNIFIED IDEOGRAPH
+0xB0AC	0x827E	#CJK UNIFIED IDEOGRAPH
+0xB0AD	0x788D	#CJK UNIFIED IDEOGRAPH
+0xB0AE	0x7231	#CJK UNIFIED IDEOGRAPH
+0xB0AF	0x9698	#CJK UNIFIED IDEOGRAPH
+0xB0B0	0x978D	#CJK UNIFIED IDEOGRAPH
+0xB0B1	0x6C28	#CJK UNIFIED IDEOGRAPH
+0xB0B2	0x5B89	#CJK UNIFIED IDEOGRAPH
+0xB0B3	0x4FFA	#CJK UNIFIED IDEOGRAPH
+0xB0B4	0x6309	#CJK UNIFIED IDEOGRAPH
+0xB0B5	0x6697	#CJK UNIFIED IDEOGRAPH
+0xB0B6	0x5CB8	#CJK UNIFIED IDEOGRAPH
+0xB0B7	0x80FA	#CJK UNIFIED IDEOGRAPH
+0xB0B8	0x6848	#CJK UNIFIED IDEOGRAPH
+0xB0B9	0x80AE	#CJK UNIFIED IDEOGRAPH
+0xB0BA	0x6602	#CJK UNIFIED IDEOGRAPH
+0xB0BB	0x76CE	#CJK UNIFIED IDEOGRAPH
+0xB0BC	0x51F9	#CJK UNIFIED IDEOGRAPH
+0xB0BD	0x6556	#CJK UNIFIED IDEOGRAPH
+0xB0BE	0x71AC	#CJK UNIFIED IDEOGRAPH
+0xB0BF	0x7FF1	#CJK UNIFIED IDEOGRAPH
+0xB0C0	0x8884	#CJK UNIFIED IDEOGRAPH
+0xB0C1	0x50B2	#CJK UNIFIED IDEOGRAPH
+0xB0C2	0x5965	#CJK UNIFIED IDEOGRAPH
+0xB0C3	0x61CA	#CJK UNIFIED IDEOGRAPH
+0xB0C4	0x6FB3	#CJK UNIFIED IDEOGRAPH
+0xB0C5	0x82AD	#CJK UNIFIED IDEOGRAPH
+0xB0C6	0x634C	#CJK UNIFIED IDEOGRAPH
+0xB0C7	0x6252	#CJK UNIFIED IDEOGRAPH
+0xB0C8	0x53ED	#CJK UNIFIED IDEOGRAPH
+0xB0C9	0x5427	#CJK UNIFIED IDEOGRAPH
+0xB0CA	0x7B06	#CJK UNIFIED IDEOGRAPH
+0xB0CB	0x516B	#CJK UNIFIED IDEOGRAPH
+0xB0CC	0x75A4	#CJK UNIFIED IDEOGRAPH
+0xB0CD	0x5DF4	#CJK UNIFIED IDEOGRAPH
+0xB0CE	0x62D4	#CJK UNIFIED IDEOGRAPH
+0xB0CF	0x8DCB	#CJK UNIFIED IDEOGRAPH
+0xB0D0	0x9776	#CJK UNIFIED IDEOGRAPH
+0xB0D1	0x628A	#CJK UNIFIED IDEOGRAPH
+0xB0D2	0x8019	#CJK UNIFIED IDEOGRAPH
+0xB0D3	0x575D	#CJK UNIFIED IDEOGRAPH
+0xB0D4	0x9738	#CJK UNIFIED IDEOGRAPH
+0xB0D5	0x7F62	#CJK UNIFIED IDEOGRAPH
+0xB0D6	0x7238	#CJK UNIFIED IDEOGRAPH
+0xB0D7	0x767D	#CJK UNIFIED IDEOGRAPH
+0xB0D8	0x67CF	#CJK UNIFIED IDEOGRAPH
+0xB0D9	0x767E	#CJK UNIFIED IDEOGRAPH
+0xB0DA	0x6446	#CJK UNIFIED IDEOGRAPH
+0xB0DB	0x4F70	#CJK UNIFIED IDEOGRAPH
+0xB0DC	0x8D25	#CJK UNIFIED IDEOGRAPH
+0xB0DD	0x62DC	#CJK UNIFIED IDEOGRAPH
+0xB0DE	0x7A17	#CJK UNIFIED IDEOGRAPH
+0xB0DF	0x6591	#CJK UNIFIED IDEOGRAPH
+0xB0E0	0x73ED	#CJK UNIFIED IDEOGRAPH
+0xB0E1	0x642C	#CJK UNIFIED IDEOGRAPH
+0xB0E2	0x6273	#CJK UNIFIED IDEOGRAPH
+0xB0E3	0x822C	#CJK UNIFIED IDEOGRAPH
+0xB0E4	0x9881	#CJK UNIFIED IDEOGRAPH
+0xB0E5	0x677F	#CJK UNIFIED IDEOGRAPH
+0xB0E6	0x7248	#CJK UNIFIED IDEOGRAPH
+0xB0E7	0x626E	#CJK UNIFIED IDEOGRAPH
+0xB0E8	0x62CC	#CJK UNIFIED IDEOGRAPH
+0xB0E9	0x4F34	#CJK UNIFIED IDEOGRAPH
+0xB0EA	0x74E3	#CJK UNIFIED IDEOGRAPH
+0xB0EB	0x534A	#CJK UNIFIED IDEOGRAPH
+0xB0EC	0x529E	#CJK UNIFIED IDEOGRAPH
+0xB0ED	0x7ECA	#CJK UNIFIED IDEOGRAPH
+0xB0EE	0x90A6	#CJK UNIFIED IDEOGRAPH
+0xB0EF	0x5E2E	#CJK UNIFIED IDEOGRAPH
+0xB0F0	0x6886	#CJK UNIFIED IDEOGRAPH
+0xB0F1	0x699C	#CJK UNIFIED IDEOGRAPH
+0xB0F2	0x8180	#CJK UNIFIED IDEOGRAPH
+0xB0F3	0x7ED1	#CJK UNIFIED IDEOGRAPH
+0xB0F4	0x68D2	#CJK UNIFIED IDEOGRAPH
+0xB0F5	0x78C5	#CJK UNIFIED IDEOGRAPH
+0xB0F6	0x868C	#CJK UNIFIED IDEOGRAPH
+0xB0F7	0x9551	#CJK UNIFIED IDEOGRAPH
+0xB0F8	0x508D	#CJK UNIFIED IDEOGRAPH
+0xB0F9	0x8C24	#CJK UNIFIED IDEOGRAPH
+0xB0FA	0x82DE	#CJK UNIFIED IDEOGRAPH
+0xB0FB	0x80DE	#CJK UNIFIED IDEOGRAPH
+0xB0FC	0x5305	#CJK UNIFIED IDEOGRAPH
+0xB0FD	0x8912	#CJK UNIFIED IDEOGRAPH
+0xB0FE	0x5265	#CJK UNIFIED IDEOGRAPH
+0xB140	0x76C4	#CJK UNIFIED IDEOGRAPH
+0xB141	0x76C7	#CJK UNIFIED IDEOGRAPH
+0xB142	0x76C9	#CJK UNIFIED IDEOGRAPH
+0xB143	0x76CB	#CJK UNIFIED IDEOGRAPH
+0xB144	0x76CC	#CJK UNIFIED IDEOGRAPH
+0xB145	0x76D3	#CJK UNIFIED IDEOGRAPH
+0xB146	0x76D5	#CJK UNIFIED IDEOGRAPH
+0xB147	0x76D9	#CJK UNIFIED IDEOGRAPH
+0xB148	0x76DA	#CJK UNIFIED IDEOGRAPH
+0xB149	0x76DC	#CJK UNIFIED IDEOGRAPH
+0xB14A	0x76DD	#CJK UNIFIED IDEOGRAPH
+0xB14B	0x76DE	#CJK UNIFIED IDEOGRAPH
+0xB14C	0x76E0	#CJK UNIFIED IDEOGRAPH
+0xB14D	0x76E1	#CJK UNIFIED IDEOGRAPH
+0xB14E	0x76E2	#CJK UNIFIED IDEOGRAPH
+0xB14F	0x76E3	#CJK UNIFIED IDEOGRAPH
+0xB150	0x76E4	#CJK UNIFIED IDEOGRAPH
+0xB151	0x76E6	#CJK UNIFIED IDEOGRAPH
+0xB152	0x76E7	#CJK UNIFIED IDEOGRAPH
+0xB153	0x76E8	#CJK UNIFIED IDEOGRAPH
+0xB154	0x76E9	#CJK UNIFIED IDEOGRAPH
+0xB155	0x76EA	#CJK UNIFIED IDEOGRAPH
+0xB156	0x76EB	#CJK UNIFIED IDEOGRAPH
+0xB157	0x76EC	#CJK UNIFIED IDEOGRAPH
+0xB158	0x76ED	#CJK UNIFIED IDEOGRAPH
+0xB159	0x76F0	#CJK UNIFIED IDEOGRAPH
+0xB15A	0x76F3	#CJK UNIFIED IDEOGRAPH
+0xB15B	0x76F5	#CJK UNIFIED IDEOGRAPH
+0xB15C	0x76F6	#CJK UNIFIED IDEOGRAPH
+0xB15D	0x76F7	#CJK UNIFIED IDEOGRAPH
+0xB15E	0x76FA	#CJK UNIFIED IDEOGRAPH
+0xB15F	0x76FB	#CJK UNIFIED IDEOGRAPH
+0xB160	0x76FD	#CJK UNIFIED IDEOGRAPH
+0xB161	0x76FF	#CJK UNIFIED IDEOGRAPH
+0xB162	0x7700	#CJK UNIFIED IDEOGRAPH
+0xB163	0x7702	#CJK UNIFIED IDEOGRAPH
+0xB164	0x7703	#CJK UNIFIED IDEOGRAPH
+0xB165	0x7705	#CJK UNIFIED IDEOGRAPH
+0xB166	0x7706	#CJK UNIFIED IDEOGRAPH
+0xB167	0x770A	#CJK UNIFIED IDEOGRAPH
+0xB168	0x770C	#CJK UNIFIED IDEOGRAPH
+0xB169	0x770E	#CJK UNIFIED IDEOGRAPH
+0xB16A	0x770F	#CJK UNIFIED IDEOGRAPH
+0xB16B	0x7710	#CJK UNIFIED IDEOGRAPH
+0xB16C	0x7711	#CJK UNIFIED IDEOGRAPH
+0xB16D	0x7712	#CJK UNIFIED IDEOGRAPH
+0xB16E	0x7713	#CJK UNIFIED IDEOGRAPH
+0xB16F	0x7714	#CJK UNIFIED IDEOGRAPH
+0xB170	0x7715	#CJK UNIFIED IDEOGRAPH
+0xB171	0x7716	#CJK UNIFIED IDEOGRAPH
+0xB172	0x7717	#CJK UNIFIED IDEOGRAPH
+0xB173	0x7718	#CJK UNIFIED IDEOGRAPH
+0xB174	0x771B	#CJK UNIFIED IDEOGRAPH
+0xB175	0x771C	#CJK UNIFIED IDEOGRAPH
+0xB176	0x771D	#CJK UNIFIED IDEOGRAPH
+0xB177	0x771E	#CJK UNIFIED IDEOGRAPH
+0xB178	0x7721	#CJK UNIFIED IDEOGRAPH
+0xB179	0x7723	#CJK UNIFIED IDEOGRAPH
+0xB17A	0x7724	#CJK UNIFIED IDEOGRAPH
+0xB17B	0x7725	#CJK UNIFIED IDEOGRAPH
+0xB17C	0x7727	#CJK UNIFIED IDEOGRAPH
+0xB17D	0x772A	#CJK UNIFIED IDEOGRAPH
+0xB17E	0x772B	#CJK UNIFIED IDEOGRAPH
+0xB180	0x772C	#CJK UNIFIED IDEOGRAPH
+0xB181	0x772E	#CJK UNIFIED IDEOGRAPH
+0xB182	0x7730	#CJK UNIFIED IDEOGRAPH
+0xB183	0x7731	#CJK UNIFIED IDEOGRAPH
+0xB184	0x7732	#CJK UNIFIED IDEOGRAPH
+0xB185	0x7733	#CJK UNIFIED IDEOGRAPH
+0xB186	0x7734	#CJK UNIFIED IDEOGRAPH
+0xB187	0x7739	#CJK UNIFIED IDEOGRAPH
+0xB188	0x773B	#CJK UNIFIED IDEOGRAPH
+0xB189	0x773D	#CJK UNIFIED IDEOGRAPH
+0xB18A	0x773E	#CJK UNIFIED IDEOGRAPH
+0xB18B	0x773F	#CJK UNIFIED IDEOGRAPH
+0xB18C	0x7742	#CJK UNIFIED IDEOGRAPH
+0xB18D	0x7744	#CJK UNIFIED IDEOGRAPH
+0xB18E	0x7745	#CJK UNIFIED IDEOGRAPH
+0xB18F	0x7746	#CJK UNIFIED IDEOGRAPH
+0xB190	0x7748	#CJK UNIFIED IDEOGRAPH
+0xB191	0x7749	#CJK UNIFIED IDEOGRAPH
+0xB192	0x774A	#CJK UNIFIED IDEOGRAPH
+0xB193	0x774B	#CJK UNIFIED IDEOGRAPH
+0xB194	0x774C	#CJK UNIFIED IDEOGRAPH
+0xB195	0x774D	#CJK UNIFIED IDEOGRAPH
+0xB196	0x774E	#CJK UNIFIED IDEOGRAPH
+0xB197	0x774F	#CJK UNIFIED IDEOGRAPH
+0xB198	0x7752	#CJK UNIFIED IDEOGRAPH
+0xB199	0x7753	#CJK UNIFIED IDEOGRAPH
+0xB19A	0x7754	#CJK UNIFIED IDEOGRAPH
+0xB19B	0x7755	#CJK UNIFIED IDEOGRAPH
+0xB19C	0x7756	#CJK UNIFIED IDEOGRAPH
+0xB19D	0x7757	#CJK UNIFIED IDEOGRAPH
+0xB19E	0x7758	#CJK UNIFIED IDEOGRAPH
+0xB19F	0x7759	#CJK UNIFIED IDEOGRAPH
+0xB1A0	0x775C	#CJK UNIFIED IDEOGRAPH
+0xB1A1	0x8584	#CJK UNIFIED IDEOGRAPH
+0xB1A2	0x96F9	#CJK UNIFIED IDEOGRAPH
+0xB1A3	0x4FDD	#CJK UNIFIED IDEOGRAPH
+0xB1A4	0x5821	#CJK UNIFIED IDEOGRAPH
+0xB1A5	0x9971	#CJK UNIFIED IDEOGRAPH
+0xB1A6	0x5B9D	#CJK UNIFIED IDEOGRAPH
+0xB1A7	0x62B1	#CJK UNIFIED IDEOGRAPH
+0xB1A8	0x62A5	#CJK UNIFIED IDEOGRAPH
+0xB1A9	0x66B4	#CJK UNIFIED IDEOGRAPH
+0xB1AA	0x8C79	#CJK UNIFIED IDEOGRAPH
+0xB1AB	0x9C8D	#CJK UNIFIED IDEOGRAPH
+0xB1AC	0x7206	#CJK UNIFIED IDEOGRAPH
+0xB1AD	0x676F	#CJK UNIFIED IDEOGRAPH
+0xB1AE	0x7891	#CJK UNIFIED IDEOGRAPH
+0xB1AF	0x60B2	#CJK UNIFIED IDEOGRAPH
+0xB1B0	0x5351	#CJK UNIFIED IDEOGRAPH
+0xB1B1	0x5317	#CJK UNIFIED IDEOGRAPH
+0xB1B2	0x8F88	#CJK UNIFIED IDEOGRAPH
+0xB1B3	0x80CC	#CJK UNIFIED IDEOGRAPH
+0xB1B4	0x8D1D	#CJK UNIFIED IDEOGRAPH
+0xB1B5	0x94A1	#CJK UNIFIED IDEOGRAPH
+0xB1B6	0x500D	#CJK UNIFIED IDEOGRAPH
+0xB1B7	0x72C8	#CJK UNIFIED IDEOGRAPH
+0xB1B8	0x5907	#CJK UNIFIED IDEOGRAPH
+0xB1B9	0x60EB	#CJK UNIFIED IDEOGRAPH
+0xB1BA	0x7119	#CJK UNIFIED IDEOGRAPH
+0xB1BB	0x88AB	#CJK UNIFIED IDEOGRAPH
+0xB1BC	0x5954	#CJK UNIFIED IDEOGRAPH
+0xB1BD	0x82EF	#CJK UNIFIED IDEOGRAPH
+0xB1BE	0x672C	#CJK UNIFIED IDEOGRAPH
+0xB1BF	0x7B28	#CJK UNIFIED IDEOGRAPH
+0xB1C0	0x5D29	#CJK UNIFIED IDEOGRAPH
+0xB1C1	0x7EF7	#CJK UNIFIED IDEOGRAPH
+0xB1C2	0x752D	#CJK UNIFIED IDEOGRAPH
+0xB1C3	0x6CF5	#CJK UNIFIED IDEOGRAPH
+0xB1C4	0x8E66	#CJK UNIFIED IDEOGRAPH
+0xB1C5	0x8FF8	#CJK UNIFIED IDEOGRAPH
+0xB1C6	0x903C	#CJK UNIFIED IDEOGRAPH
+0xB1C7	0x9F3B	#CJK UNIFIED IDEOGRAPH
+0xB1C8	0x6BD4	#CJK UNIFIED IDEOGRAPH
+0xB1C9	0x9119	#CJK UNIFIED IDEOGRAPH
+0xB1CA	0x7B14	#CJK UNIFIED IDEOGRAPH
+0xB1CB	0x5F7C	#CJK UNIFIED IDEOGRAPH
+0xB1CC	0x78A7	#CJK UNIFIED IDEOGRAPH
+0xB1CD	0x84D6	#CJK UNIFIED IDEOGRAPH
+0xB1CE	0x853D	#CJK UNIFIED IDEOGRAPH
+0xB1CF	0x6BD5	#CJK UNIFIED IDEOGRAPH
+0xB1D0	0x6BD9	#CJK UNIFIED IDEOGRAPH
+0xB1D1	0x6BD6	#CJK UNIFIED IDEOGRAPH
+0xB1D2	0x5E01	#CJK UNIFIED IDEOGRAPH
+0xB1D3	0x5E87	#CJK UNIFIED IDEOGRAPH
+0xB1D4	0x75F9	#CJK UNIFIED IDEOGRAPH
+0xB1D5	0x95ED	#CJK UNIFIED IDEOGRAPH
+0xB1D6	0x655D	#CJK UNIFIED IDEOGRAPH
+0xB1D7	0x5F0A	#CJK UNIFIED IDEOGRAPH
+0xB1D8	0x5FC5	#CJK UNIFIED IDEOGRAPH
+0xB1D9	0x8F9F	#CJK UNIFIED IDEOGRAPH
+0xB1DA	0x58C1	#CJK UNIFIED IDEOGRAPH
+0xB1DB	0x81C2	#CJK UNIFIED IDEOGRAPH
+0xB1DC	0x907F	#CJK UNIFIED IDEOGRAPH
+0xB1DD	0x965B	#CJK UNIFIED IDEOGRAPH
+0xB1DE	0x97AD	#CJK UNIFIED IDEOGRAPH
+0xB1DF	0x8FB9	#CJK UNIFIED IDEOGRAPH
+0xB1E0	0x7F16	#CJK UNIFIED IDEOGRAPH
+0xB1E1	0x8D2C	#CJK UNIFIED IDEOGRAPH
+0xB1E2	0x6241	#CJK UNIFIED IDEOGRAPH
+0xB1E3	0x4FBF	#CJK UNIFIED IDEOGRAPH
+0xB1E4	0x53D8	#CJK UNIFIED IDEOGRAPH
+0xB1E5	0x535E	#CJK UNIFIED IDEOGRAPH
+0xB1E6	0x8FA8	#CJK UNIFIED IDEOGRAPH
+0xB1E7	0x8FA9	#CJK UNIFIED IDEOGRAPH
+0xB1E8	0x8FAB	#CJK UNIFIED IDEOGRAPH
+0xB1E9	0x904D	#CJK UNIFIED IDEOGRAPH
+0xB1EA	0x6807	#CJK UNIFIED IDEOGRAPH
+0xB1EB	0x5F6A	#CJK UNIFIED IDEOGRAPH
+0xB1EC	0x8198	#CJK UNIFIED IDEOGRAPH
+0xB1ED	0x8868	#CJK UNIFIED IDEOGRAPH
+0xB1EE	0x9CD6	#CJK UNIFIED IDEOGRAPH
+0xB1EF	0x618B	#CJK UNIFIED IDEOGRAPH
+0xB1F0	0x522B	#CJK UNIFIED IDEOGRAPH
+0xB1F1	0x762A	#CJK UNIFIED IDEOGRAPH
+0xB1F2	0x5F6C	#CJK UNIFIED IDEOGRAPH
+0xB1F3	0x658C	#CJK UNIFIED IDEOGRAPH
+0xB1F4	0x6FD2	#CJK UNIFIED IDEOGRAPH
+0xB1F5	0x6EE8	#CJK UNIFIED IDEOGRAPH
+0xB1F6	0x5BBE	#CJK UNIFIED IDEOGRAPH
+0xB1F7	0x6448	#CJK UNIFIED IDEOGRAPH
+0xB1F8	0x5175	#CJK UNIFIED IDEOGRAPH
+0xB1F9	0x51B0	#CJK UNIFIED IDEOGRAPH
+0xB1FA	0x67C4	#CJK UNIFIED IDEOGRAPH
+0xB1FB	0x4E19	#CJK UNIFIED IDEOGRAPH
+0xB1FC	0x79C9	#CJK UNIFIED IDEOGRAPH
+0xB1FD	0x997C	#CJK UNIFIED IDEOGRAPH
+0xB1FE	0x70B3	#CJK UNIFIED IDEOGRAPH
+0xB240	0x775D	#CJK UNIFIED IDEOGRAPH
+0xB241	0x775E	#CJK UNIFIED IDEOGRAPH
+0xB242	0x775F	#CJK UNIFIED IDEOGRAPH
+0xB243	0x7760	#CJK UNIFIED IDEOGRAPH
+0xB244	0x7764	#CJK UNIFIED IDEOGRAPH
+0xB245	0x7767	#CJK UNIFIED IDEOGRAPH
+0xB246	0x7769	#CJK UNIFIED IDEOGRAPH
+0xB247	0x776A	#CJK UNIFIED IDEOGRAPH
+0xB248	0x776D	#CJK UNIFIED IDEOGRAPH
+0xB249	0x776E	#CJK UNIFIED IDEOGRAPH
+0xB24A	0x776F	#CJK UNIFIED IDEOGRAPH
+0xB24B	0x7770	#CJK UNIFIED IDEOGRAPH
+0xB24C	0x7771	#CJK UNIFIED IDEOGRAPH
+0xB24D	0x7772	#CJK UNIFIED IDEOGRAPH
+0xB24E	0x7773	#CJK UNIFIED IDEOGRAPH
+0xB24F	0x7774	#CJK UNIFIED IDEOGRAPH
+0xB250	0x7775	#CJK UNIFIED IDEOGRAPH
+0xB251	0x7776	#CJK UNIFIED IDEOGRAPH
+0xB252	0x7777	#CJK UNIFIED IDEOGRAPH
+0xB253	0x7778	#CJK UNIFIED IDEOGRAPH
+0xB254	0x777A	#CJK UNIFIED IDEOGRAPH
+0xB255	0x777B	#CJK UNIFIED IDEOGRAPH
+0xB256	0x777C	#CJK UNIFIED IDEOGRAPH
+0xB257	0x7781	#CJK UNIFIED IDEOGRAPH
+0xB258	0x7782	#CJK UNIFIED IDEOGRAPH
+0xB259	0x7783	#CJK UNIFIED IDEOGRAPH
+0xB25A	0x7786	#CJK UNIFIED IDEOGRAPH
+0xB25B	0x7787	#CJK UNIFIED IDEOGRAPH
+0xB25C	0x7788	#CJK UNIFIED IDEOGRAPH
+0xB25D	0x7789	#CJK UNIFIED IDEOGRAPH
+0xB25E	0x778A	#CJK UNIFIED IDEOGRAPH
+0xB25F	0x778B	#CJK UNIFIED IDEOGRAPH
+0xB260	0x778F	#CJK UNIFIED IDEOGRAPH
+0xB261	0x7790	#CJK UNIFIED IDEOGRAPH
+0xB262	0x7793	#CJK UNIFIED IDEOGRAPH
+0xB263	0x7794	#CJK UNIFIED IDEOGRAPH
+0xB264	0x7795	#CJK UNIFIED IDEOGRAPH
+0xB265	0x7796	#CJK UNIFIED IDEOGRAPH
+0xB266	0x7797	#CJK UNIFIED IDEOGRAPH
+0xB267	0x7798	#CJK UNIFIED IDEOGRAPH
+0xB268	0x7799	#CJK UNIFIED IDEOGRAPH
+0xB269	0x779A	#CJK UNIFIED IDEOGRAPH
+0xB26A	0x779B	#CJK UNIFIED IDEOGRAPH
+0xB26B	0x779C	#CJK UNIFIED IDEOGRAPH
+0xB26C	0x779D	#CJK UNIFIED IDEOGRAPH
+0xB26D	0x779E	#CJK UNIFIED IDEOGRAPH
+0xB26E	0x77A1	#CJK UNIFIED IDEOGRAPH
+0xB26F	0x77A3	#CJK UNIFIED IDEOGRAPH
+0xB270	0x77A4	#CJK UNIFIED IDEOGRAPH
+0xB271	0x77A6	#CJK UNIFIED IDEOGRAPH
+0xB272	0x77A8	#CJK UNIFIED IDEOGRAPH
+0xB273	0x77AB	#CJK UNIFIED IDEOGRAPH
+0xB274	0x77AD	#CJK UNIFIED IDEOGRAPH
+0xB275	0x77AE	#CJK UNIFIED IDEOGRAPH
+0xB276	0x77AF	#CJK UNIFIED IDEOGRAPH
+0xB277	0x77B1	#CJK UNIFIED IDEOGRAPH
+0xB278	0x77B2	#CJK UNIFIED IDEOGRAPH
+0xB279	0x77B4	#CJK UNIFIED IDEOGRAPH
+0xB27A	0x77B6	#CJK UNIFIED IDEOGRAPH
+0xB27B	0x77B7	#CJK UNIFIED IDEOGRAPH
+0xB27C	0x77B8	#CJK UNIFIED IDEOGRAPH
+0xB27D	0x77B9	#CJK UNIFIED IDEOGRAPH
+0xB27E	0x77BA	#CJK UNIFIED IDEOGRAPH
+0xB280	0x77BC	#CJK UNIFIED IDEOGRAPH
+0xB281	0x77BE	#CJK UNIFIED IDEOGRAPH
+0xB282	0x77C0	#CJK UNIFIED IDEOGRAPH
+0xB283	0x77C1	#CJK UNIFIED IDEOGRAPH
+0xB284	0x77C2	#CJK UNIFIED IDEOGRAPH
+0xB285	0x77C3	#CJK UNIFIED IDEOGRAPH
+0xB286	0x77C4	#CJK UNIFIED IDEOGRAPH
+0xB287	0x77C5	#CJK UNIFIED IDEOGRAPH
+0xB288	0x77C6	#CJK UNIFIED IDEOGRAPH
+0xB289	0x77C7	#CJK UNIFIED IDEOGRAPH
+0xB28A	0x77C8	#CJK UNIFIED IDEOGRAPH
+0xB28B	0x77C9	#CJK UNIFIED IDEOGRAPH
+0xB28C	0x77CA	#CJK UNIFIED IDEOGRAPH
+0xB28D	0x77CB	#CJK UNIFIED IDEOGRAPH
+0xB28E	0x77CC	#CJK UNIFIED IDEOGRAPH
+0xB28F	0x77CE	#CJK UNIFIED IDEOGRAPH
+0xB290	0x77CF	#CJK UNIFIED IDEOGRAPH
+0xB291	0x77D0	#CJK UNIFIED IDEOGRAPH
+0xB292	0x77D1	#CJK UNIFIED IDEOGRAPH
+0xB293	0x77D2	#CJK UNIFIED IDEOGRAPH
+0xB294	0x77D3	#CJK UNIFIED IDEOGRAPH
+0xB295	0x77D4	#CJK UNIFIED IDEOGRAPH
+0xB296	0x77D5	#CJK UNIFIED IDEOGRAPH
+0xB297	0x77D6	#CJK UNIFIED IDEOGRAPH
+0xB298	0x77D8	#CJK UNIFIED IDEOGRAPH
+0xB299	0x77D9	#CJK UNIFIED IDEOGRAPH
+0xB29A	0x77DA	#CJK UNIFIED IDEOGRAPH
+0xB29B	0x77DD	#CJK UNIFIED IDEOGRAPH
+0xB29C	0x77DE	#CJK UNIFIED IDEOGRAPH
+0xB29D	0x77DF	#CJK UNIFIED IDEOGRAPH
+0xB29E	0x77E0	#CJK UNIFIED IDEOGRAPH
+0xB29F	0x77E1	#CJK UNIFIED IDEOGRAPH
+0xB2A0	0x77E4	#CJK UNIFIED IDEOGRAPH
+0xB2A1	0x75C5	#CJK UNIFIED IDEOGRAPH
+0xB2A2	0x5E76	#CJK UNIFIED IDEOGRAPH
+0xB2A3	0x73BB	#CJK UNIFIED IDEOGRAPH
+0xB2A4	0x83E0	#CJK UNIFIED IDEOGRAPH
+0xB2A5	0x64AD	#CJK UNIFIED IDEOGRAPH
+0xB2A6	0x62E8	#CJK UNIFIED IDEOGRAPH
+0xB2A7	0x94B5	#CJK UNIFIED IDEOGRAPH
+0xB2A8	0x6CE2	#CJK UNIFIED IDEOGRAPH
+0xB2A9	0x535A	#CJK UNIFIED IDEOGRAPH
+0xB2AA	0x52C3	#CJK UNIFIED IDEOGRAPH
+0xB2AB	0x640F	#CJK UNIFIED IDEOGRAPH
+0xB2AC	0x94C2	#CJK UNIFIED IDEOGRAPH
+0xB2AD	0x7B94	#CJK UNIFIED IDEOGRAPH
+0xB2AE	0x4F2F	#CJK UNIFIED IDEOGRAPH
+0xB2AF	0x5E1B	#CJK UNIFIED IDEOGRAPH
+0xB2B0	0x8236	#CJK UNIFIED IDEOGRAPH
+0xB2B1	0x8116	#CJK UNIFIED IDEOGRAPH
+0xB2B2	0x818A	#CJK UNIFIED IDEOGRAPH
+0xB2B3	0x6E24	#CJK UNIFIED IDEOGRAPH
+0xB2B4	0x6CCA	#CJK UNIFIED IDEOGRAPH
+0xB2B5	0x9A73	#CJK UNIFIED IDEOGRAPH
+0xB2B6	0x6355	#CJK UNIFIED IDEOGRAPH
+0xB2B7	0x535C	#CJK UNIFIED IDEOGRAPH
+0xB2B8	0x54FA	#CJK UNIFIED IDEOGRAPH
+0xB2B9	0x8865	#CJK UNIFIED IDEOGRAPH
+0xB2BA	0x57E0	#CJK UNIFIED IDEOGRAPH
+0xB2BB	0x4E0D	#CJK UNIFIED IDEOGRAPH
+0xB2BC	0x5E03	#CJK UNIFIED IDEOGRAPH
+0xB2BD	0x6B65	#CJK UNIFIED IDEOGRAPH
+0xB2BE	0x7C3F	#CJK UNIFIED IDEOGRAPH
+0xB2BF	0x90E8	#CJK UNIFIED IDEOGRAPH
+0xB2C0	0x6016	#CJK UNIFIED IDEOGRAPH
+0xB2C1	0x64E6	#CJK UNIFIED IDEOGRAPH
+0xB2C2	0x731C	#CJK UNIFIED IDEOGRAPH
+0xB2C3	0x88C1	#CJK UNIFIED IDEOGRAPH
+0xB2C4	0x6750	#CJK UNIFIED IDEOGRAPH
+0xB2C5	0x624D	#CJK UNIFIED IDEOGRAPH
+0xB2C6	0x8D22	#CJK UNIFIED IDEOGRAPH
+0xB2C7	0x776C	#CJK UNIFIED IDEOGRAPH
+0xB2C8	0x8E29	#CJK UNIFIED IDEOGRAPH
+0xB2C9	0x91C7	#CJK UNIFIED IDEOGRAPH
+0xB2CA	0x5F69	#CJK UNIFIED IDEOGRAPH
+0xB2CB	0x83DC	#CJK UNIFIED IDEOGRAPH
+0xB2CC	0x8521	#CJK UNIFIED IDEOGRAPH
+0xB2CD	0x9910	#CJK UNIFIED IDEOGRAPH
+0xB2CE	0x53C2	#CJK UNIFIED IDEOGRAPH
+0xB2CF	0x8695	#CJK UNIFIED IDEOGRAPH
+0xB2D0	0x6B8B	#CJK UNIFIED IDEOGRAPH
+0xB2D1	0x60ED	#CJK UNIFIED IDEOGRAPH
+0xB2D2	0x60E8	#CJK UNIFIED IDEOGRAPH
+0xB2D3	0x707F	#CJK UNIFIED IDEOGRAPH
+0xB2D4	0x82CD	#CJK UNIFIED IDEOGRAPH
+0xB2D5	0x8231	#CJK UNIFIED IDEOGRAPH
+0xB2D6	0x4ED3	#CJK UNIFIED IDEOGRAPH
+0xB2D7	0x6CA7	#CJK UNIFIED IDEOGRAPH
+0xB2D8	0x85CF	#CJK UNIFIED IDEOGRAPH
+0xB2D9	0x64CD	#CJK UNIFIED IDEOGRAPH
+0xB2DA	0x7CD9	#CJK UNIFIED IDEOGRAPH
+0xB2DB	0x69FD	#CJK UNIFIED IDEOGRAPH
+0xB2DC	0x66F9	#CJK UNIFIED IDEOGRAPH
+0xB2DD	0x8349	#CJK UNIFIED IDEOGRAPH
+0xB2DE	0x5395	#CJK UNIFIED IDEOGRAPH
+0xB2DF	0x7B56	#CJK UNIFIED IDEOGRAPH
+0xB2E0	0x4FA7	#CJK UNIFIED IDEOGRAPH
+0xB2E1	0x518C	#CJK UNIFIED IDEOGRAPH
+0xB2E2	0x6D4B	#CJK UNIFIED IDEOGRAPH
+0xB2E3	0x5C42	#CJK UNIFIED IDEOGRAPH
+0xB2E4	0x8E6D	#CJK UNIFIED IDEOGRAPH
+0xB2E5	0x63D2	#CJK UNIFIED IDEOGRAPH
+0xB2E6	0x53C9	#CJK UNIFIED IDEOGRAPH
+0xB2E7	0x832C	#CJK UNIFIED IDEOGRAPH
+0xB2E8	0x8336	#CJK UNIFIED IDEOGRAPH
+0xB2E9	0x67E5	#CJK UNIFIED IDEOGRAPH
+0xB2EA	0x78B4	#CJK UNIFIED IDEOGRAPH
+0xB2EB	0x643D	#CJK UNIFIED IDEOGRAPH
+0xB2EC	0x5BDF	#CJK UNIFIED IDEOGRAPH
+0xB2ED	0x5C94	#CJK UNIFIED IDEOGRAPH
+0xB2EE	0x5DEE	#CJK UNIFIED IDEOGRAPH
+0xB2EF	0x8BE7	#CJK UNIFIED IDEOGRAPH
+0xB2F0	0x62C6	#CJK UNIFIED IDEOGRAPH
+0xB2F1	0x67F4	#CJK UNIFIED IDEOGRAPH
+0xB2F2	0x8C7A	#CJK UNIFIED IDEOGRAPH
+0xB2F3	0x6400	#CJK UNIFIED IDEOGRAPH
+0xB2F4	0x63BA	#CJK UNIFIED IDEOGRAPH
+0xB2F5	0x8749	#CJK UNIFIED IDEOGRAPH
+0xB2F6	0x998B	#CJK UNIFIED IDEOGRAPH
+0xB2F7	0x8C17	#CJK UNIFIED IDEOGRAPH
+0xB2F8	0x7F20	#CJK UNIFIED IDEOGRAPH
+0xB2F9	0x94F2	#CJK UNIFIED IDEOGRAPH
+0xB2FA	0x4EA7	#CJK UNIFIED IDEOGRAPH
+0xB2FB	0x9610	#CJK UNIFIED IDEOGRAPH
+0xB2FC	0x98A4	#CJK UNIFIED IDEOGRAPH
+0xB2FD	0x660C	#CJK UNIFIED IDEOGRAPH
+0xB2FE	0x7316	#CJK UNIFIED IDEOGRAPH
+0xB340	0x77E6	#CJK UNIFIED IDEOGRAPH
+0xB341	0x77E8	#CJK UNIFIED IDEOGRAPH
+0xB342	0x77EA	#CJK UNIFIED IDEOGRAPH
+0xB343	0x77EF	#CJK UNIFIED IDEOGRAPH
+0xB344	0x77F0	#CJK UNIFIED IDEOGRAPH
+0xB345	0x77F1	#CJK UNIFIED IDEOGRAPH
+0xB346	0x77F2	#CJK UNIFIED IDEOGRAPH
+0xB347	0x77F4	#CJK UNIFIED IDEOGRAPH
+0xB348	0x77F5	#CJK UNIFIED IDEOGRAPH
+0xB349	0x77F7	#CJK UNIFIED IDEOGRAPH
+0xB34A	0x77F9	#CJK UNIFIED IDEOGRAPH
+0xB34B	0x77FA	#CJK UNIFIED IDEOGRAPH
+0xB34C	0x77FB	#CJK UNIFIED IDEOGRAPH
+0xB34D	0x77FC	#CJK UNIFIED IDEOGRAPH
+0xB34E	0x7803	#CJK UNIFIED IDEOGRAPH
+0xB34F	0x7804	#CJK UNIFIED IDEOGRAPH
+0xB350	0x7805	#CJK UNIFIED IDEOGRAPH
+0xB351	0x7806	#CJK UNIFIED IDEOGRAPH
+0xB352	0x7807	#CJK UNIFIED IDEOGRAPH
+0xB353	0x7808	#CJK UNIFIED IDEOGRAPH
+0xB354	0x780A	#CJK UNIFIED IDEOGRAPH
+0xB355	0x780B	#CJK UNIFIED IDEOGRAPH
+0xB356	0x780E	#CJK UNIFIED IDEOGRAPH
+0xB357	0x780F	#CJK UNIFIED IDEOGRAPH
+0xB358	0x7810	#CJK UNIFIED IDEOGRAPH
+0xB359	0x7813	#CJK UNIFIED IDEOGRAPH
+0xB35A	0x7815	#CJK UNIFIED IDEOGRAPH
+0xB35B	0x7819	#CJK UNIFIED IDEOGRAPH
+0xB35C	0x781B	#CJK UNIFIED IDEOGRAPH
+0xB35D	0x781E	#CJK UNIFIED IDEOGRAPH
+0xB35E	0x7820	#CJK UNIFIED IDEOGRAPH
+0xB35F	0x7821	#CJK UNIFIED IDEOGRAPH
+0xB360	0x7822	#CJK UNIFIED IDEOGRAPH
+0xB361	0x7824	#CJK UNIFIED IDEOGRAPH
+0xB362	0x7828	#CJK UNIFIED IDEOGRAPH
+0xB363	0x782A	#CJK UNIFIED IDEOGRAPH
+0xB364	0x782B	#CJK UNIFIED IDEOGRAPH
+0xB365	0x782E	#CJK UNIFIED IDEOGRAPH
+0xB366	0x782F	#CJK UNIFIED IDEOGRAPH
+0xB367	0x7831	#CJK UNIFIED IDEOGRAPH
+0xB368	0x7832	#CJK UNIFIED IDEOGRAPH
+0xB369	0x7833	#CJK UNIFIED IDEOGRAPH
+0xB36A	0x7835	#CJK UNIFIED IDEOGRAPH
+0xB36B	0x7836	#CJK UNIFIED IDEOGRAPH
+0xB36C	0x783D	#CJK UNIFIED IDEOGRAPH
+0xB36D	0x783F	#CJK UNIFIED IDEOGRAPH
+0xB36E	0x7841	#CJK UNIFIED IDEOGRAPH
+0xB36F	0x7842	#CJK UNIFIED IDEOGRAPH
+0xB370	0x7843	#CJK UNIFIED IDEOGRAPH
+0xB371	0x7844	#CJK UNIFIED IDEOGRAPH
+0xB372	0x7846	#CJK UNIFIED IDEOGRAPH
+0xB373	0x7848	#CJK UNIFIED IDEOGRAPH
+0xB374	0x7849	#CJK UNIFIED IDEOGRAPH
+0xB375	0x784A	#CJK UNIFIED IDEOGRAPH
+0xB376	0x784B	#CJK UNIFIED IDEOGRAPH
+0xB377	0x784D	#CJK UNIFIED IDEOGRAPH
+0xB378	0x784F	#CJK UNIFIED IDEOGRAPH
+0xB379	0x7851	#CJK UNIFIED IDEOGRAPH
+0xB37A	0x7853	#CJK UNIFIED IDEOGRAPH
+0xB37B	0x7854	#CJK UNIFIED IDEOGRAPH
+0xB37C	0x7858	#CJK UNIFIED IDEOGRAPH
+0xB37D	0x7859	#CJK UNIFIED IDEOGRAPH
+0xB37E	0x785A	#CJK UNIFIED IDEOGRAPH
+0xB380	0x785B	#CJK UNIFIED IDEOGRAPH
+0xB381	0x785C	#CJK UNIFIED IDEOGRAPH
+0xB382	0x785E	#CJK UNIFIED IDEOGRAPH
+0xB383	0x785F	#CJK UNIFIED IDEOGRAPH
+0xB384	0x7860	#CJK UNIFIED IDEOGRAPH
+0xB385	0x7861	#CJK UNIFIED IDEOGRAPH
+0xB386	0x7862	#CJK UNIFIED IDEOGRAPH
+0xB387	0x7863	#CJK UNIFIED IDEOGRAPH
+0xB388	0x7864	#CJK UNIFIED IDEOGRAPH
+0xB389	0x7865	#CJK UNIFIED IDEOGRAPH
+0xB38A	0x7866	#CJK UNIFIED IDEOGRAPH
+0xB38B	0x7867	#CJK UNIFIED IDEOGRAPH
+0xB38C	0x7868	#CJK UNIFIED IDEOGRAPH
+0xB38D	0x7869	#CJK UNIFIED IDEOGRAPH
+0xB38E	0x786F	#CJK UNIFIED IDEOGRAPH
+0xB38F	0x7870	#CJK UNIFIED IDEOGRAPH
+0xB390	0x7871	#CJK UNIFIED IDEOGRAPH
+0xB391	0x7872	#CJK UNIFIED IDEOGRAPH
+0xB392	0x7873	#CJK UNIFIED IDEOGRAPH
+0xB393	0x7874	#CJK UNIFIED IDEOGRAPH
+0xB394	0x7875	#CJK UNIFIED IDEOGRAPH
+0xB395	0x7876	#CJK UNIFIED IDEOGRAPH
+0xB396	0x7878	#CJK UNIFIED IDEOGRAPH
+0xB397	0x7879	#CJK UNIFIED IDEOGRAPH
+0xB398	0x787A	#CJK UNIFIED IDEOGRAPH
+0xB399	0x787B	#CJK UNIFIED IDEOGRAPH
+0xB39A	0x787D	#CJK UNIFIED IDEOGRAPH
+0xB39B	0x787E	#CJK UNIFIED IDEOGRAPH
+0xB39C	0x787F	#CJK UNIFIED IDEOGRAPH
+0xB39D	0x7880	#CJK UNIFIED IDEOGRAPH
+0xB39E	0x7881	#CJK UNIFIED IDEOGRAPH
+0xB39F	0x7882	#CJK UNIFIED IDEOGRAPH
+0xB3A0	0x7883	#CJK UNIFIED IDEOGRAPH
+0xB3A1	0x573A	#CJK UNIFIED IDEOGRAPH
+0xB3A2	0x5C1D	#CJK UNIFIED IDEOGRAPH
+0xB3A3	0x5E38	#CJK UNIFIED IDEOGRAPH
+0xB3A4	0x957F	#CJK UNIFIED IDEOGRAPH
+0xB3A5	0x507F	#CJK UNIFIED IDEOGRAPH
+0xB3A6	0x80A0	#CJK UNIFIED IDEOGRAPH
+0xB3A7	0x5382	#CJK UNIFIED IDEOGRAPH
+0xB3A8	0x655E	#CJK UNIFIED IDEOGRAPH
+0xB3A9	0x7545	#CJK UNIFIED IDEOGRAPH
+0xB3AA	0x5531	#CJK UNIFIED IDEOGRAPH
+0xB3AB	0x5021	#CJK UNIFIED IDEOGRAPH
+0xB3AC	0x8D85	#CJK UNIFIED IDEOGRAPH
+0xB3AD	0x6284	#CJK UNIFIED IDEOGRAPH
+0xB3AE	0x949E	#CJK UNIFIED IDEOGRAPH
+0xB3AF	0x671D	#CJK UNIFIED IDEOGRAPH
+0xB3B0	0x5632	#CJK UNIFIED IDEOGRAPH
+0xB3B1	0x6F6E	#CJK UNIFIED IDEOGRAPH
+0xB3B2	0x5DE2	#CJK UNIFIED IDEOGRAPH
+0xB3B3	0x5435	#CJK UNIFIED IDEOGRAPH
+0xB3B4	0x7092	#CJK UNIFIED IDEOGRAPH
+0xB3B5	0x8F66	#CJK UNIFIED IDEOGRAPH
+0xB3B6	0x626F	#CJK UNIFIED IDEOGRAPH
+0xB3B7	0x64A4	#CJK UNIFIED IDEOGRAPH
+0xB3B8	0x63A3	#CJK UNIFIED IDEOGRAPH
+0xB3B9	0x5F7B	#CJK UNIFIED IDEOGRAPH
+0xB3BA	0x6F88	#CJK UNIFIED IDEOGRAPH
+0xB3BB	0x90F4	#CJK UNIFIED IDEOGRAPH
+0xB3BC	0x81E3	#CJK UNIFIED IDEOGRAPH
+0xB3BD	0x8FB0	#CJK UNIFIED IDEOGRAPH
+0xB3BE	0x5C18	#CJK UNIFIED IDEOGRAPH
+0xB3BF	0x6668	#CJK UNIFIED IDEOGRAPH
+0xB3C0	0x5FF1	#CJK UNIFIED IDEOGRAPH
+0xB3C1	0x6C89	#CJK UNIFIED IDEOGRAPH
+0xB3C2	0x9648	#CJK UNIFIED IDEOGRAPH
+0xB3C3	0x8D81	#CJK UNIFIED IDEOGRAPH
+0xB3C4	0x886C	#CJK UNIFIED IDEOGRAPH
+0xB3C5	0x6491	#CJK UNIFIED IDEOGRAPH
+0xB3C6	0x79F0	#CJK UNIFIED IDEOGRAPH
+0xB3C7	0x57CE	#CJK UNIFIED IDEOGRAPH
+0xB3C8	0x6A59	#CJK UNIFIED IDEOGRAPH
+0xB3C9	0x6210	#CJK UNIFIED IDEOGRAPH
+0xB3CA	0x5448	#CJK UNIFIED IDEOGRAPH
+0xB3CB	0x4E58	#CJK UNIFIED IDEOGRAPH
+0xB3CC	0x7A0B	#CJK UNIFIED IDEOGRAPH
+0xB3CD	0x60E9	#CJK UNIFIED IDEOGRAPH
+0xB3CE	0x6F84	#CJK UNIFIED IDEOGRAPH
+0xB3CF	0x8BDA	#CJK UNIFIED IDEOGRAPH
+0xB3D0	0x627F	#CJK UNIFIED IDEOGRAPH
+0xB3D1	0x901E	#CJK UNIFIED IDEOGRAPH
+0xB3D2	0x9A8B	#CJK UNIFIED IDEOGRAPH
+0xB3D3	0x79E4	#CJK UNIFIED IDEOGRAPH
+0xB3D4	0x5403	#CJK UNIFIED IDEOGRAPH
+0xB3D5	0x75F4	#CJK UNIFIED IDEOGRAPH
+0xB3D6	0x6301	#CJK UNIFIED IDEOGRAPH
+0xB3D7	0x5319	#CJK UNIFIED IDEOGRAPH
+0xB3D8	0x6C60	#CJK UNIFIED IDEOGRAPH
+0xB3D9	0x8FDF	#CJK UNIFIED IDEOGRAPH
+0xB3DA	0x5F1B	#CJK UNIFIED IDEOGRAPH
+0xB3DB	0x9A70	#CJK UNIFIED IDEOGRAPH
+0xB3DC	0x803B	#CJK UNIFIED IDEOGRAPH
+0xB3DD	0x9F7F	#CJK UNIFIED IDEOGRAPH
+0xB3DE	0x4F88	#CJK UNIFIED IDEOGRAPH
+0xB3DF	0x5C3A	#CJK UNIFIED IDEOGRAPH
+0xB3E0	0x8D64	#CJK UNIFIED IDEOGRAPH
+0xB3E1	0x7FC5	#CJK UNIFIED IDEOGRAPH
+0xB3E2	0x65A5	#CJK UNIFIED IDEOGRAPH
+0xB3E3	0x70BD	#CJK UNIFIED IDEOGRAPH
+0xB3E4	0x5145	#CJK UNIFIED IDEOGRAPH
+0xB3E5	0x51B2	#CJK UNIFIED IDEOGRAPH
+0xB3E6	0x866B	#CJK UNIFIED IDEOGRAPH
+0xB3E7	0x5D07	#CJK UNIFIED IDEOGRAPH
+0xB3E8	0x5BA0	#CJK UNIFIED IDEOGRAPH
+0xB3E9	0x62BD	#CJK UNIFIED IDEOGRAPH
+0xB3EA	0x916C	#CJK UNIFIED IDEOGRAPH
+0xB3EB	0x7574	#CJK UNIFIED IDEOGRAPH
+0xB3EC	0x8E0C	#CJK UNIFIED IDEOGRAPH
+0xB3ED	0x7A20	#CJK UNIFIED IDEOGRAPH
+0xB3EE	0x6101	#CJK UNIFIED IDEOGRAPH
+0xB3EF	0x7B79	#CJK UNIFIED IDEOGRAPH
+0xB3F0	0x4EC7	#CJK UNIFIED IDEOGRAPH
+0xB3F1	0x7EF8	#CJK UNIFIED IDEOGRAPH
+0xB3F2	0x7785	#CJK UNIFIED IDEOGRAPH
+0xB3F3	0x4E11	#CJK UNIFIED IDEOGRAPH
+0xB3F4	0x81ED	#CJK UNIFIED IDEOGRAPH
+0xB3F5	0x521D	#CJK UNIFIED IDEOGRAPH
+0xB3F6	0x51FA	#CJK UNIFIED IDEOGRAPH
+0xB3F7	0x6A71	#CJK UNIFIED IDEOGRAPH
+0xB3F8	0x53A8	#CJK UNIFIED IDEOGRAPH
+0xB3F9	0x8E87	#CJK UNIFIED IDEOGRAPH
+0xB3FA	0x9504	#CJK UNIFIED IDEOGRAPH
+0xB3FB	0x96CF	#CJK UNIFIED IDEOGRAPH
+0xB3FC	0x6EC1	#CJK UNIFIED IDEOGRAPH
+0xB3FD	0x9664	#CJK UNIFIED IDEOGRAPH
+0xB3FE	0x695A	#CJK UNIFIED IDEOGRAPH
+0xB440	0x7884	#CJK UNIFIED IDEOGRAPH
+0xB441	0x7885	#CJK UNIFIED IDEOGRAPH
+0xB442	0x7886	#CJK UNIFIED IDEOGRAPH
+0xB443	0x7888	#CJK UNIFIED IDEOGRAPH
+0xB444	0x788A	#CJK UNIFIED IDEOGRAPH
+0xB445	0x788B	#CJK UNIFIED IDEOGRAPH
+0xB446	0x788F	#CJK UNIFIED IDEOGRAPH
+0xB447	0x7890	#CJK UNIFIED IDEOGRAPH
+0xB448	0x7892	#CJK UNIFIED IDEOGRAPH
+0xB449	0x7894	#CJK UNIFIED IDEOGRAPH
+0xB44A	0x7895	#CJK UNIFIED IDEOGRAPH
+0xB44B	0x7896	#CJK UNIFIED IDEOGRAPH
+0xB44C	0x7899	#CJK UNIFIED IDEOGRAPH
+0xB44D	0x789D	#CJK UNIFIED IDEOGRAPH
+0xB44E	0x789E	#CJK UNIFIED IDEOGRAPH
+0xB44F	0x78A0	#CJK UNIFIED IDEOGRAPH
+0xB450	0x78A2	#CJK UNIFIED IDEOGRAPH
+0xB451	0x78A4	#CJK UNIFIED IDEOGRAPH
+0xB452	0x78A6	#CJK UNIFIED IDEOGRAPH
+0xB453	0x78A8	#CJK UNIFIED IDEOGRAPH
+0xB454	0x78A9	#CJK UNIFIED IDEOGRAPH
+0xB455	0x78AA	#CJK UNIFIED IDEOGRAPH
+0xB456	0x78AB	#CJK UNIFIED IDEOGRAPH
+0xB457	0x78AC	#CJK UNIFIED IDEOGRAPH
+0xB458	0x78AD	#CJK UNIFIED IDEOGRAPH
+0xB459	0x78AE	#CJK UNIFIED IDEOGRAPH
+0xB45A	0x78AF	#CJK UNIFIED IDEOGRAPH
+0xB45B	0x78B5	#CJK UNIFIED IDEOGRAPH
+0xB45C	0x78B6	#CJK UNIFIED IDEOGRAPH
+0xB45D	0x78B7	#CJK UNIFIED IDEOGRAPH
+0xB45E	0x78B8	#CJK UNIFIED IDEOGRAPH
+0xB45F	0x78BA	#CJK UNIFIED IDEOGRAPH
+0xB460	0x78BB	#CJK UNIFIED IDEOGRAPH
+0xB461	0x78BC	#CJK UNIFIED IDEOGRAPH
+0xB462	0x78BD	#CJK UNIFIED IDEOGRAPH
+0xB463	0x78BF	#CJK UNIFIED IDEOGRAPH
+0xB464	0x78C0	#CJK UNIFIED IDEOGRAPH
+0xB465	0x78C2	#CJK UNIFIED IDEOGRAPH
+0xB466	0x78C3	#CJK UNIFIED IDEOGRAPH
+0xB467	0x78C4	#CJK UNIFIED IDEOGRAPH
+0xB468	0x78C6	#CJK UNIFIED IDEOGRAPH
+0xB469	0x78C7	#CJK UNIFIED IDEOGRAPH
+0xB46A	0x78C8	#CJK UNIFIED IDEOGRAPH
+0xB46B	0x78CC	#CJK UNIFIED IDEOGRAPH
+0xB46C	0x78CD	#CJK UNIFIED IDEOGRAPH
+0xB46D	0x78CE	#CJK UNIFIED IDEOGRAPH
+0xB46E	0x78CF	#CJK UNIFIED IDEOGRAPH
+0xB46F	0x78D1	#CJK UNIFIED IDEOGRAPH
+0xB470	0x78D2	#CJK UNIFIED IDEOGRAPH
+0xB471	0x78D3	#CJK UNIFIED IDEOGRAPH
+0xB472	0x78D6	#CJK UNIFIED IDEOGRAPH
+0xB473	0x78D7	#CJK UNIFIED IDEOGRAPH
+0xB474	0x78D8	#CJK UNIFIED IDEOGRAPH
+0xB475	0x78DA	#CJK UNIFIED IDEOGRAPH
+0xB476	0x78DB	#CJK UNIFIED IDEOGRAPH
+0xB477	0x78DC	#CJK UNIFIED IDEOGRAPH
+0xB478	0x78DD	#CJK UNIFIED IDEOGRAPH
+0xB479	0x78DE	#CJK UNIFIED IDEOGRAPH
+0xB47A	0x78DF	#CJK UNIFIED IDEOGRAPH
+0xB47B	0x78E0	#CJK UNIFIED IDEOGRAPH
+0xB47C	0x78E1	#CJK UNIFIED IDEOGRAPH
+0xB47D	0x78E2	#CJK UNIFIED IDEOGRAPH
+0xB47E	0x78E3	#CJK UNIFIED IDEOGRAPH
+0xB480	0x78E4	#CJK UNIFIED IDEOGRAPH
+0xB481	0x78E5	#CJK UNIFIED IDEOGRAPH
+0xB482	0x78E6	#CJK UNIFIED IDEOGRAPH
+0xB483	0x78E7	#CJK UNIFIED IDEOGRAPH
+0xB484	0x78E9	#CJK UNIFIED IDEOGRAPH
+0xB485	0x78EA	#CJK UNIFIED IDEOGRAPH
+0xB486	0x78EB	#CJK UNIFIED IDEOGRAPH
+0xB487	0x78ED	#CJK UNIFIED IDEOGRAPH
+0xB488	0x78EE	#CJK UNIFIED IDEOGRAPH
+0xB489	0x78EF	#CJK UNIFIED IDEOGRAPH
+0xB48A	0x78F0	#CJK UNIFIED IDEOGRAPH
+0xB48B	0x78F1	#CJK UNIFIED IDEOGRAPH
+0xB48C	0x78F3	#CJK UNIFIED IDEOGRAPH
+0xB48D	0x78F5	#CJK UNIFIED IDEOGRAPH
+0xB48E	0x78F6	#CJK UNIFIED IDEOGRAPH
+0xB48F	0x78F8	#CJK UNIFIED IDEOGRAPH
+0xB490	0x78F9	#CJK UNIFIED IDEOGRAPH
+0xB491	0x78FB	#CJK UNIFIED IDEOGRAPH
+0xB492	0x78FC	#CJK UNIFIED IDEOGRAPH
+0xB493	0x78FD	#CJK UNIFIED IDEOGRAPH
+0xB494	0x78FE	#CJK UNIFIED IDEOGRAPH
+0xB495	0x78FF	#CJK UNIFIED IDEOGRAPH
+0xB496	0x7900	#CJK UNIFIED IDEOGRAPH
+0xB497	0x7902	#CJK UNIFIED IDEOGRAPH
+0xB498	0x7903	#CJK UNIFIED IDEOGRAPH
+0xB499	0x7904	#CJK UNIFIED IDEOGRAPH
+0xB49A	0x7906	#CJK UNIFIED IDEOGRAPH
+0xB49B	0x7907	#CJK UNIFIED IDEOGRAPH
+0xB49C	0x7908	#CJK UNIFIED IDEOGRAPH
+0xB49D	0x7909	#CJK UNIFIED IDEOGRAPH
+0xB49E	0x790A	#CJK UNIFIED IDEOGRAPH
+0xB49F	0x790B	#CJK UNIFIED IDEOGRAPH
+0xB4A0	0x790C	#CJK UNIFIED IDEOGRAPH
+0xB4A1	0x7840	#CJK UNIFIED IDEOGRAPH
+0xB4A2	0x50A8	#CJK UNIFIED IDEOGRAPH
+0xB4A3	0x77D7	#CJK UNIFIED IDEOGRAPH
+0xB4A4	0x6410	#CJK UNIFIED IDEOGRAPH
+0xB4A5	0x89E6	#CJK UNIFIED IDEOGRAPH
+0xB4A6	0x5904	#CJK UNIFIED IDEOGRAPH
+0xB4A7	0x63E3	#CJK UNIFIED IDEOGRAPH
+0xB4A8	0x5DDD	#CJK UNIFIED IDEOGRAPH
+0xB4A9	0x7A7F	#CJK UNIFIED IDEOGRAPH
+0xB4AA	0x693D	#CJK UNIFIED IDEOGRAPH
+0xB4AB	0x4F20	#CJK UNIFIED IDEOGRAPH
+0xB4AC	0x8239	#CJK UNIFIED IDEOGRAPH
+0xB4AD	0x5598	#CJK UNIFIED IDEOGRAPH
+0xB4AE	0x4E32	#CJK UNIFIED IDEOGRAPH
+0xB4AF	0x75AE	#CJK UNIFIED IDEOGRAPH
+0xB4B0	0x7A97	#CJK UNIFIED IDEOGRAPH
+0xB4B1	0x5E62	#CJK UNIFIED IDEOGRAPH
+0xB4B2	0x5E8A	#CJK UNIFIED IDEOGRAPH
+0xB4B3	0x95EF	#CJK UNIFIED IDEOGRAPH
+0xB4B4	0x521B	#CJK UNIFIED IDEOGRAPH
+0xB4B5	0x5439	#CJK UNIFIED IDEOGRAPH
+0xB4B6	0x708A	#CJK UNIFIED IDEOGRAPH
+0xB4B7	0x6376	#CJK UNIFIED IDEOGRAPH
+0xB4B8	0x9524	#CJK UNIFIED IDEOGRAPH
+0xB4B9	0x5782	#CJK UNIFIED IDEOGRAPH
+0xB4BA	0x6625	#CJK UNIFIED IDEOGRAPH
+0xB4BB	0x693F	#CJK UNIFIED IDEOGRAPH
+0xB4BC	0x9187	#CJK UNIFIED IDEOGRAPH
+0xB4BD	0x5507	#CJK UNIFIED IDEOGRAPH
+0xB4BE	0x6DF3	#CJK UNIFIED IDEOGRAPH
+0xB4BF	0x7EAF	#CJK UNIFIED IDEOGRAPH
+0xB4C0	0x8822	#CJK UNIFIED IDEOGRAPH
+0xB4C1	0x6233	#CJK UNIFIED IDEOGRAPH
+0xB4C2	0x7EF0	#CJK UNIFIED IDEOGRAPH
+0xB4C3	0x75B5	#CJK UNIFIED IDEOGRAPH
+0xB4C4	0x8328	#CJK UNIFIED IDEOGRAPH
+0xB4C5	0x78C1	#CJK UNIFIED IDEOGRAPH
+0xB4C6	0x96CC	#CJK UNIFIED IDEOGRAPH
+0xB4C7	0x8F9E	#CJK UNIFIED IDEOGRAPH
+0xB4C8	0x6148	#CJK UNIFIED IDEOGRAPH
+0xB4C9	0x74F7	#CJK UNIFIED IDEOGRAPH
+0xB4CA	0x8BCD	#CJK UNIFIED IDEOGRAPH
+0xB4CB	0x6B64	#CJK UNIFIED IDEOGRAPH
+0xB4CC	0x523A	#CJK UNIFIED IDEOGRAPH
+0xB4CD	0x8D50	#CJK UNIFIED IDEOGRAPH
+0xB4CE	0x6B21	#CJK UNIFIED IDEOGRAPH
+0xB4CF	0x806A	#CJK UNIFIED IDEOGRAPH
+0xB4D0	0x8471	#CJK UNIFIED IDEOGRAPH
+0xB4D1	0x56F1	#CJK UNIFIED IDEOGRAPH
+0xB4D2	0x5306	#CJK UNIFIED IDEOGRAPH
+0xB4D3	0x4ECE	#CJK UNIFIED IDEOGRAPH
+0xB4D4	0x4E1B	#CJK UNIFIED IDEOGRAPH
+0xB4D5	0x51D1	#CJK UNIFIED IDEOGRAPH
+0xB4D6	0x7C97	#CJK UNIFIED IDEOGRAPH
+0xB4D7	0x918B	#CJK UNIFIED IDEOGRAPH
+0xB4D8	0x7C07	#CJK UNIFIED IDEOGRAPH
+0xB4D9	0x4FC3	#CJK UNIFIED IDEOGRAPH
+0xB4DA	0x8E7F	#CJK UNIFIED IDEOGRAPH
+0xB4DB	0x7BE1	#CJK UNIFIED IDEOGRAPH
+0xB4DC	0x7A9C	#CJK UNIFIED IDEOGRAPH
+0xB4DD	0x6467	#CJK UNIFIED IDEOGRAPH
+0xB4DE	0x5D14	#CJK UNIFIED IDEOGRAPH
+0xB4DF	0x50AC	#CJK UNIFIED IDEOGRAPH
+0xB4E0	0x8106	#CJK UNIFIED IDEOGRAPH
+0xB4E1	0x7601	#CJK UNIFIED IDEOGRAPH
+0xB4E2	0x7CB9	#CJK UNIFIED IDEOGRAPH
+0xB4E3	0x6DEC	#CJK UNIFIED IDEOGRAPH
+0xB4E4	0x7FE0	#CJK UNIFIED IDEOGRAPH
+0xB4E5	0x6751	#CJK UNIFIED IDEOGRAPH
+0xB4E6	0x5B58	#CJK UNIFIED IDEOGRAPH
+0xB4E7	0x5BF8	#CJK UNIFIED IDEOGRAPH
+0xB4E8	0x78CB	#CJK UNIFIED IDEOGRAPH
+0xB4E9	0x64AE	#CJK UNIFIED IDEOGRAPH
+0xB4EA	0x6413	#CJK UNIFIED IDEOGRAPH
+0xB4EB	0x63AA	#CJK UNIFIED IDEOGRAPH
+0xB4EC	0x632B	#CJK UNIFIED IDEOGRAPH
+0xB4ED	0x9519	#CJK UNIFIED IDEOGRAPH
+0xB4EE	0x642D	#CJK UNIFIED IDEOGRAPH
+0xB4EF	0x8FBE	#CJK UNIFIED IDEOGRAPH
+0xB4F0	0x7B54	#CJK UNIFIED IDEOGRAPH
+0xB4F1	0x7629	#CJK UNIFIED IDEOGRAPH
+0xB4F2	0x6253	#CJK UNIFIED IDEOGRAPH
+0xB4F3	0x5927	#CJK UNIFIED IDEOGRAPH
+0xB4F4	0x5446	#CJK UNIFIED IDEOGRAPH
+0xB4F5	0x6B79	#CJK UNIFIED IDEOGRAPH
+0xB4F6	0x50A3	#CJK UNIFIED IDEOGRAPH
+0xB4F7	0x6234	#CJK UNIFIED IDEOGRAPH
+0xB4F8	0x5E26	#CJK UNIFIED IDEOGRAPH
+0xB4F9	0x6B86	#CJK UNIFIED IDEOGRAPH
+0xB4FA	0x4EE3	#CJK UNIFIED IDEOGRAPH
+0xB4FB	0x8D37	#CJK UNIFIED IDEOGRAPH
+0xB4FC	0x888B	#CJK UNIFIED IDEOGRAPH
+0xB4FD	0x5F85	#CJK UNIFIED IDEOGRAPH
+0xB4FE	0x902E	#CJK UNIFIED IDEOGRAPH
+0xB540	0x790D	#CJK UNIFIED IDEOGRAPH
+0xB541	0x790E	#CJK UNIFIED IDEOGRAPH
+0xB542	0x790F	#CJK UNIFIED IDEOGRAPH
+0xB543	0x7910	#CJK UNIFIED IDEOGRAPH
+0xB544	0x7911	#CJK UNIFIED IDEOGRAPH
+0xB545	0x7912	#CJK UNIFIED IDEOGRAPH
+0xB546	0x7914	#CJK UNIFIED IDEOGRAPH
+0xB547	0x7915	#CJK UNIFIED IDEOGRAPH
+0xB548	0x7916	#CJK UNIFIED IDEOGRAPH
+0xB549	0x7917	#CJK UNIFIED IDEOGRAPH
+0xB54A	0x7918	#CJK UNIFIED IDEOGRAPH
+0xB54B	0x7919	#CJK UNIFIED IDEOGRAPH
+0xB54C	0x791A	#CJK UNIFIED IDEOGRAPH
+0xB54D	0x791B	#CJK UNIFIED IDEOGRAPH
+0xB54E	0x791C	#CJK UNIFIED IDEOGRAPH
+0xB54F	0x791D	#CJK UNIFIED IDEOGRAPH
+0xB550	0x791F	#CJK UNIFIED IDEOGRAPH
+0xB551	0x7920	#CJK UNIFIED IDEOGRAPH
+0xB552	0x7921	#CJK UNIFIED IDEOGRAPH
+0xB553	0x7922	#CJK UNIFIED IDEOGRAPH
+0xB554	0x7923	#CJK UNIFIED IDEOGRAPH
+0xB555	0x7925	#CJK UNIFIED IDEOGRAPH
+0xB556	0x7926	#CJK UNIFIED IDEOGRAPH
+0xB557	0x7927	#CJK UNIFIED IDEOGRAPH
+0xB558	0x7928	#CJK UNIFIED IDEOGRAPH
+0xB559	0x7929	#CJK UNIFIED IDEOGRAPH
+0xB55A	0x792A	#CJK UNIFIED IDEOGRAPH
+0xB55B	0x792B	#CJK UNIFIED IDEOGRAPH
+0xB55C	0x792C	#CJK UNIFIED IDEOGRAPH
+0xB55D	0x792D	#CJK UNIFIED IDEOGRAPH
+0xB55E	0x792E	#CJK UNIFIED IDEOGRAPH
+0xB55F	0x792F	#CJK UNIFIED IDEOGRAPH
+0xB560	0x7930	#CJK UNIFIED IDEOGRAPH
+0xB561	0x7931	#CJK UNIFIED IDEOGRAPH
+0xB562	0x7932	#CJK UNIFIED IDEOGRAPH
+0xB563	0x7933	#CJK UNIFIED IDEOGRAPH
+0xB564	0x7935	#CJK UNIFIED IDEOGRAPH
+0xB565	0x7936	#CJK UNIFIED IDEOGRAPH
+0xB566	0x7937	#CJK UNIFIED IDEOGRAPH
+0xB567	0x7938	#CJK UNIFIED IDEOGRAPH
+0xB568	0x7939	#CJK UNIFIED IDEOGRAPH
+0xB569	0x793D	#CJK UNIFIED IDEOGRAPH
+0xB56A	0x793F	#CJK UNIFIED IDEOGRAPH
+0xB56B	0x7942	#CJK UNIFIED IDEOGRAPH
+0xB56C	0x7943	#CJK UNIFIED IDEOGRAPH
+0xB56D	0x7944	#CJK UNIFIED IDEOGRAPH
+0xB56E	0x7945	#CJK UNIFIED IDEOGRAPH
+0xB56F	0x7947	#CJK UNIFIED IDEOGRAPH
+0xB570	0x794A	#CJK UNIFIED IDEOGRAPH
+0xB571	0x794B	#CJK UNIFIED IDEOGRAPH
+0xB572	0x794C	#CJK UNIFIED IDEOGRAPH
+0xB573	0x794D	#CJK UNIFIED IDEOGRAPH
+0xB574	0x794E	#CJK UNIFIED IDEOGRAPH
+0xB575	0x794F	#CJK UNIFIED IDEOGRAPH
+0xB576	0x7950	#CJK UNIFIED IDEOGRAPH
+0xB577	0x7951	#CJK UNIFIED IDEOGRAPH
+0xB578	0x7952	#CJK UNIFIED IDEOGRAPH
+0xB579	0x7954	#CJK UNIFIED IDEOGRAPH
+0xB57A	0x7955	#CJK UNIFIED IDEOGRAPH
+0xB57B	0x7958	#CJK UNIFIED IDEOGRAPH
+0xB57C	0x7959	#CJK UNIFIED IDEOGRAPH
+0xB57D	0x7961	#CJK UNIFIED IDEOGRAPH
+0xB57E	0x7963	#CJK UNIFIED IDEOGRAPH
+0xB580	0x7964	#CJK UNIFIED IDEOGRAPH
+0xB581	0x7966	#CJK UNIFIED IDEOGRAPH
+0xB582	0x7969	#CJK UNIFIED IDEOGRAPH
+0xB583	0x796A	#CJK UNIFIED IDEOGRAPH
+0xB584	0x796B	#CJK UNIFIED IDEOGRAPH
+0xB585	0x796C	#CJK UNIFIED IDEOGRAPH
+0xB586	0x796E	#CJK UNIFIED IDEOGRAPH
+0xB587	0x7970	#CJK UNIFIED IDEOGRAPH
+0xB588	0x7971	#CJK UNIFIED IDEOGRAPH
+0xB589	0x7972	#CJK UNIFIED IDEOGRAPH
+0xB58A	0x7973	#CJK UNIFIED IDEOGRAPH
+0xB58B	0x7974	#CJK UNIFIED IDEOGRAPH
+0xB58C	0x7975	#CJK UNIFIED IDEOGRAPH
+0xB58D	0x7976	#CJK UNIFIED IDEOGRAPH
+0xB58E	0x7979	#CJK UNIFIED IDEOGRAPH
+0xB58F	0x797B	#CJK UNIFIED IDEOGRAPH
+0xB590	0x797C	#CJK UNIFIED IDEOGRAPH
+0xB591	0x797D	#CJK UNIFIED IDEOGRAPH
+0xB592	0x797E	#CJK UNIFIED IDEOGRAPH
+0xB593	0x797F	#CJK UNIFIED IDEOGRAPH
+0xB594	0x7982	#CJK UNIFIED IDEOGRAPH
+0xB595	0x7983	#CJK UNIFIED IDEOGRAPH
+0xB596	0x7986	#CJK UNIFIED IDEOGRAPH
+0xB597	0x7987	#CJK UNIFIED IDEOGRAPH
+0xB598	0x7988	#CJK UNIFIED IDEOGRAPH
+0xB599	0x7989	#CJK UNIFIED IDEOGRAPH
+0xB59A	0x798B	#CJK UNIFIED IDEOGRAPH
+0xB59B	0x798C	#CJK UNIFIED IDEOGRAPH
+0xB59C	0x798D	#CJK UNIFIED IDEOGRAPH
+0xB59D	0x798E	#CJK UNIFIED IDEOGRAPH
+0xB59E	0x7990	#CJK UNIFIED IDEOGRAPH
+0xB59F	0x7991	#CJK UNIFIED IDEOGRAPH
+0xB5A0	0x7992	#CJK UNIFIED IDEOGRAPH
+0xB5A1	0x6020	#CJK UNIFIED IDEOGRAPH
+0xB5A2	0x803D	#CJK UNIFIED IDEOGRAPH
+0xB5A3	0x62C5	#CJK UNIFIED IDEOGRAPH
+0xB5A4	0x4E39	#CJK UNIFIED IDEOGRAPH
+0xB5A5	0x5355	#CJK UNIFIED IDEOGRAPH
+0xB5A6	0x90F8	#CJK UNIFIED IDEOGRAPH
+0xB5A7	0x63B8	#CJK UNIFIED IDEOGRAPH
+0xB5A8	0x80C6	#CJK UNIFIED IDEOGRAPH
+0xB5A9	0x65E6	#CJK UNIFIED IDEOGRAPH
+0xB5AA	0x6C2E	#CJK UNIFIED IDEOGRAPH
+0xB5AB	0x4F46	#CJK UNIFIED IDEOGRAPH
+0xB5AC	0x60EE	#CJK UNIFIED IDEOGRAPH
+0xB5AD	0x6DE1	#CJK UNIFIED IDEOGRAPH
+0xB5AE	0x8BDE	#CJK UNIFIED IDEOGRAPH
+0xB5AF	0x5F39	#CJK UNIFIED IDEOGRAPH
+0xB5B0	0x86CB	#CJK UNIFIED IDEOGRAPH
+0xB5B1	0x5F53	#CJK UNIFIED IDEOGRAPH
+0xB5B2	0x6321	#CJK UNIFIED IDEOGRAPH
+0xB5B3	0x515A	#CJK UNIFIED IDEOGRAPH
+0xB5B4	0x8361	#CJK UNIFIED IDEOGRAPH
+0xB5B5	0x6863	#CJK UNIFIED IDEOGRAPH
+0xB5B6	0x5200	#CJK UNIFIED IDEOGRAPH
+0xB5B7	0x6363	#CJK UNIFIED IDEOGRAPH
+0xB5B8	0x8E48	#CJK UNIFIED IDEOGRAPH
+0xB5B9	0x5012	#CJK UNIFIED IDEOGRAPH
+0xB5BA	0x5C9B	#CJK UNIFIED IDEOGRAPH
+0xB5BB	0x7977	#CJK UNIFIED IDEOGRAPH
+0xB5BC	0x5BFC	#CJK UNIFIED IDEOGRAPH
+0xB5BD	0x5230	#CJK UNIFIED IDEOGRAPH
+0xB5BE	0x7A3B	#CJK UNIFIED IDEOGRAPH
+0xB5BF	0x60BC	#CJK UNIFIED IDEOGRAPH
+0xB5C0	0x9053	#CJK UNIFIED IDEOGRAPH
+0xB5C1	0x76D7	#CJK UNIFIED IDEOGRAPH
+0xB5C2	0x5FB7	#CJK UNIFIED IDEOGRAPH
+0xB5C3	0x5F97	#CJK UNIFIED IDEOGRAPH
+0xB5C4	0x7684	#CJK UNIFIED IDEOGRAPH
+0xB5C5	0x8E6C	#CJK UNIFIED IDEOGRAPH
+0xB5C6	0x706F	#CJK UNIFIED IDEOGRAPH
+0xB5C7	0x767B	#CJK UNIFIED IDEOGRAPH
+0xB5C8	0x7B49	#CJK UNIFIED IDEOGRAPH
+0xB5C9	0x77AA	#CJK UNIFIED IDEOGRAPH
+0xB5CA	0x51F3	#CJK UNIFIED IDEOGRAPH
+0xB5CB	0x9093	#CJK UNIFIED IDEOGRAPH
+0xB5CC	0x5824	#CJK UNIFIED IDEOGRAPH
+0xB5CD	0x4F4E	#CJK UNIFIED IDEOGRAPH
+0xB5CE	0x6EF4	#CJK UNIFIED IDEOGRAPH
+0xB5CF	0x8FEA	#CJK UNIFIED IDEOGRAPH
+0xB5D0	0x654C	#CJK UNIFIED IDEOGRAPH
+0xB5D1	0x7B1B	#CJK UNIFIED IDEOGRAPH
+0xB5D2	0x72C4	#CJK UNIFIED IDEOGRAPH
+0xB5D3	0x6DA4	#CJK UNIFIED IDEOGRAPH
+0xB5D4	0x7FDF	#CJK UNIFIED IDEOGRAPH
+0xB5D5	0x5AE1	#CJK UNIFIED IDEOGRAPH
+0xB5D6	0x62B5	#CJK UNIFIED IDEOGRAPH
+0xB5D7	0x5E95	#CJK UNIFIED IDEOGRAPH
+0xB5D8	0x5730	#CJK UNIFIED IDEOGRAPH
+0xB5D9	0x8482	#CJK UNIFIED IDEOGRAPH
+0xB5DA	0x7B2C	#CJK UNIFIED IDEOGRAPH
+0xB5DB	0x5E1D	#CJK UNIFIED IDEOGRAPH
+0xB5DC	0x5F1F	#CJK UNIFIED IDEOGRAPH
+0xB5DD	0x9012	#CJK UNIFIED IDEOGRAPH
+0xB5DE	0x7F14	#CJK UNIFIED IDEOGRAPH
+0xB5DF	0x98A0	#CJK UNIFIED IDEOGRAPH
+0xB5E0	0x6382	#CJK UNIFIED IDEOGRAPH
+0xB5E1	0x6EC7	#CJK UNIFIED IDEOGRAPH
+0xB5E2	0x7898	#CJK UNIFIED IDEOGRAPH
+0xB5E3	0x70B9	#CJK UNIFIED IDEOGRAPH
+0xB5E4	0x5178	#CJK UNIFIED IDEOGRAPH
+0xB5E5	0x975B	#CJK UNIFIED IDEOGRAPH
+0xB5E6	0x57AB	#CJK UNIFIED IDEOGRAPH
+0xB5E7	0x7535	#CJK UNIFIED IDEOGRAPH
+0xB5E8	0x4F43	#CJK UNIFIED IDEOGRAPH
+0xB5E9	0x7538	#CJK UNIFIED IDEOGRAPH
+0xB5EA	0x5E97	#CJK UNIFIED IDEOGRAPH
+0xB5EB	0x60E6	#CJK UNIFIED IDEOGRAPH
+0xB5EC	0x5960	#CJK UNIFIED IDEOGRAPH
+0xB5ED	0x6DC0	#CJK UNIFIED IDEOGRAPH
+0xB5EE	0x6BBF	#CJK UNIFIED IDEOGRAPH
+0xB5EF	0x7889	#CJK UNIFIED IDEOGRAPH
+0xB5F0	0x53FC	#CJK UNIFIED IDEOGRAPH
+0xB5F1	0x96D5	#CJK UNIFIED IDEOGRAPH
+0xB5F2	0x51CB	#CJK UNIFIED IDEOGRAPH
+0xB5F3	0x5201	#CJK UNIFIED IDEOGRAPH
+0xB5F4	0x6389	#CJK UNIFIED IDEOGRAPH
+0xB5F5	0x540A	#CJK UNIFIED IDEOGRAPH
+0xB5F6	0x9493	#CJK UNIFIED IDEOGRAPH
+0xB5F7	0x8C03	#CJK UNIFIED IDEOGRAPH
+0xB5F8	0x8DCC	#CJK UNIFIED IDEOGRAPH
+0xB5F9	0x7239	#CJK UNIFIED IDEOGRAPH
+0xB5FA	0x789F	#CJK UNIFIED IDEOGRAPH
+0xB5FB	0x8776	#CJK UNIFIED IDEOGRAPH
+0xB5FC	0x8FED	#CJK UNIFIED IDEOGRAPH
+0xB5FD	0x8C0D	#CJK UNIFIED IDEOGRAPH
+0xB5FE	0x53E0	#CJK UNIFIED IDEOGRAPH
+0xB640	0x7993	#CJK UNIFIED IDEOGRAPH
+0xB641	0x7994	#CJK UNIFIED IDEOGRAPH
+0xB642	0x7995	#CJK UNIFIED IDEOGRAPH
+0xB643	0x7996	#CJK UNIFIED IDEOGRAPH
+0xB644	0x7997	#CJK UNIFIED IDEOGRAPH
+0xB645	0x7998	#CJK UNIFIED IDEOGRAPH
+0xB646	0x7999	#CJK UNIFIED IDEOGRAPH
+0xB647	0x799B	#CJK UNIFIED IDEOGRAPH
+0xB648	0x799C	#CJK UNIFIED IDEOGRAPH
+0xB649	0x799D	#CJK UNIFIED IDEOGRAPH
+0xB64A	0x799E	#CJK UNIFIED IDEOGRAPH
+0xB64B	0x799F	#CJK UNIFIED IDEOGRAPH
+0xB64C	0x79A0	#CJK UNIFIED IDEOGRAPH
+0xB64D	0x79A1	#CJK UNIFIED IDEOGRAPH
+0xB64E	0x79A2	#CJK UNIFIED IDEOGRAPH
+0xB64F	0x79A3	#CJK UNIFIED IDEOGRAPH
+0xB650	0x79A4	#CJK UNIFIED IDEOGRAPH
+0xB651	0x79A5	#CJK UNIFIED IDEOGRAPH
+0xB652	0x79A6	#CJK UNIFIED IDEOGRAPH
+0xB653	0x79A8	#CJK UNIFIED IDEOGRAPH
+0xB654	0x79A9	#CJK UNIFIED IDEOGRAPH
+0xB655	0x79AA	#CJK UNIFIED IDEOGRAPH
+0xB656	0x79AB	#CJK UNIFIED IDEOGRAPH
+0xB657	0x79AC	#CJK UNIFIED IDEOGRAPH
+0xB658	0x79AD	#CJK UNIFIED IDEOGRAPH
+0xB659	0x79AE	#CJK UNIFIED IDEOGRAPH
+0xB65A	0x79AF	#CJK UNIFIED IDEOGRAPH
+0xB65B	0x79B0	#CJK UNIFIED IDEOGRAPH
+0xB65C	0x79B1	#CJK UNIFIED IDEOGRAPH
+0xB65D	0x79B2	#CJK UNIFIED IDEOGRAPH
+0xB65E	0x79B4	#CJK UNIFIED IDEOGRAPH
+0xB65F	0x79B5	#CJK UNIFIED IDEOGRAPH
+0xB660	0x79B6	#CJK UNIFIED IDEOGRAPH
+0xB661	0x79B7	#CJK UNIFIED IDEOGRAPH
+0xB662	0x79B8	#CJK UNIFIED IDEOGRAPH
+0xB663	0x79BC	#CJK UNIFIED IDEOGRAPH
+0xB664	0x79BF	#CJK UNIFIED IDEOGRAPH
+0xB665	0x79C2	#CJK UNIFIED IDEOGRAPH
+0xB666	0x79C4	#CJK UNIFIED IDEOGRAPH
+0xB667	0x79C5	#CJK UNIFIED IDEOGRAPH
+0xB668	0x79C7	#CJK UNIFIED IDEOGRAPH
+0xB669	0x79C8	#CJK UNIFIED IDEOGRAPH
+0xB66A	0x79CA	#CJK UNIFIED IDEOGRAPH
+0xB66B	0x79CC	#CJK UNIFIED IDEOGRAPH
+0xB66C	0x79CE	#CJK UNIFIED IDEOGRAPH
+0xB66D	0x79CF	#CJK UNIFIED IDEOGRAPH
+0xB66E	0x79D0	#CJK UNIFIED IDEOGRAPH
+0xB66F	0x79D3	#CJK UNIFIED IDEOGRAPH
+0xB670	0x79D4	#CJK UNIFIED IDEOGRAPH
+0xB671	0x79D6	#CJK UNIFIED IDEOGRAPH
+0xB672	0x79D7	#CJK UNIFIED IDEOGRAPH
+0xB673	0x79D9	#CJK UNIFIED IDEOGRAPH
+0xB674	0x79DA	#CJK UNIFIED IDEOGRAPH
+0xB675	0x79DB	#CJK UNIFIED IDEOGRAPH
+0xB676	0x79DC	#CJK UNIFIED IDEOGRAPH
+0xB677	0x79DD	#CJK UNIFIED IDEOGRAPH
+0xB678	0x79DE	#CJK UNIFIED IDEOGRAPH
+0xB679	0x79E0	#CJK UNIFIED IDEOGRAPH
+0xB67A	0x79E1	#CJK UNIFIED IDEOGRAPH
+0xB67B	0x79E2	#CJK UNIFIED IDEOGRAPH
+0xB67C	0x79E5	#CJK UNIFIED IDEOGRAPH
+0xB67D	0x79E8	#CJK UNIFIED IDEOGRAPH
+0xB67E	0x79EA	#CJK UNIFIED IDEOGRAPH
+0xB680	0x79EC	#CJK UNIFIED IDEOGRAPH
+0xB681	0x79EE	#CJK UNIFIED IDEOGRAPH
+0xB682	0x79F1	#CJK UNIFIED IDEOGRAPH
+0xB683	0x79F2	#CJK UNIFIED IDEOGRAPH
+0xB684	0x79F3	#CJK UNIFIED IDEOGRAPH
+0xB685	0x79F4	#CJK UNIFIED IDEOGRAPH
+0xB686	0x79F5	#CJK UNIFIED IDEOGRAPH
+0xB687	0x79F6	#CJK UNIFIED IDEOGRAPH
+0xB688	0x79F7	#CJK UNIFIED IDEOGRAPH
+0xB689	0x79F9	#CJK UNIFIED IDEOGRAPH
+0xB68A	0x79FA	#CJK UNIFIED IDEOGRAPH
+0xB68B	0x79FC	#CJK UNIFIED IDEOGRAPH
+0xB68C	0x79FE	#CJK UNIFIED IDEOGRAPH
+0xB68D	0x79FF	#CJK UNIFIED IDEOGRAPH
+0xB68E	0x7A01	#CJK UNIFIED IDEOGRAPH
+0xB68F	0x7A04	#CJK UNIFIED IDEOGRAPH
+0xB690	0x7A05	#CJK UNIFIED IDEOGRAPH
+0xB691	0x7A07	#CJK UNIFIED IDEOGRAPH
+0xB692	0x7A08	#CJK UNIFIED IDEOGRAPH
+0xB693	0x7A09	#CJK UNIFIED IDEOGRAPH
+0xB694	0x7A0A	#CJK UNIFIED IDEOGRAPH
+0xB695	0x7A0C	#CJK UNIFIED IDEOGRAPH
+0xB696	0x7A0F	#CJK UNIFIED IDEOGRAPH
+0xB697	0x7A10	#CJK UNIFIED IDEOGRAPH
+0xB698	0x7A11	#CJK UNIFIED IDEOGRAPH
+0xB699	0x7A12	#CJK UNIFIED IDEOGRAPH
+0xB69A	0x7A13	#CJK UNIFIED IDEOGRAPH
+0xB69B	0x7A15	#CJK UNIFIED IDEOGRAPH
+0xB69C	0x7A16	#CJK UNIFIED IDEOGRAPH
+0xB69D	0x7A18	#CJK UNIFIED IDEOGRAPH
+0xB69E	0x7A19	#CJK UNIFIED IDEOGRAPH
+0xB69F	0x7A1B	#CJK UNIFIED IDEOGRAPH
+0xB6A0	0x7A1C	#CJK UNIFIED IDEOGRAPH
+0xB6A1	0x4E01	#CJK UNIFIED IDEOGRAPH
+0xB6A2	0x76EF	#CJK UNIFIED IDEOGRAPH
+0xB6A3	0x53EE	#CJK UNIFIED IDEOGRAPH
+0xB6A4	0x9489	#CJK UNIFIED IDEOGRAPH
+0xB6A5	0x9876	#CJK UNIFIED IDEOGRAPH
+0xB6A6	0x9F0E	#CJK UNIFIED IDEOGRAPH
+0xB6A7	0x952D	#CJK UNIFIED IDEOGRAPH
+0xB6A8	0x5B9A	#CJK UNIFIED IDEOGRAPH
+0xB6A9	0x8BA2	#CJK UNIFIED IDEOGRAPH
+0xB6AA	0x4E22	#CJK UNIFIED IDEOGRAPH
+0xB6AB	0x4E1C	#CJK UNIFIED IDEOGRAPH
+0xB6AC	0x51AC	#CJK UNIFIED IDEOGRAPH
+0xB6AD	0x8463	#CJK UNIFIED IDEOGRAPH
+0xB6AE	0x61C2	#CJK UNIFIED IDEOGRAPH
+0xB6AF	0x52A8	#CJK UNIFIED IDEOGRAPH
+0xB6B0	0x680B	#CJK UNIFIED IDEOGRAPH
+0xB6B1	0x4F97	#CJK UNIFIED IDEOGRAPH
+0xB6B2	0x606B	#CJK UNIFIED IDEOGRAPH
+0xB6B3	0x51BB	#CJK UNIFIED IDEOGRAPH
+0xB6B4	0x6D1E	#CJK UNIFIED IDEOGRAPH
+0xB6B5	0x515C	#CJK UNIFIED IDEOGRAPH
+0xB6B6	0x6296	#CJK UNIFIED IDEOGRAPH
+0xB6B7	0x6597	#CJK UNIFIED IDEOGRAPH
+0xB6B8	0x9661	#CJK UNIFIED IDEOGRAPH
+0xB6B9	0x8C46	#CJK UNIFIED IDEOGRAPH
+0xB6BA	0x9017	#CJK UNIFIED IDEOGRAPH
+0xB6BB	0x75D8	#CJK UNIFIED IDEOGRAPH
+0xB6BC	0x90FD	#CJK UNIFIED IDEOGRAPH
+0xB6BD	0x7763	#CJK UNIFIED IDEOGRAPH
+0xB6BE	0x6BD2	#CJK UNIFIED IDEOGRAPH
+0xB6BF	0x728A	#CJK UNIFIED IDEOGRAPH
+0xB6C0	0x72EC	#CJK UNIFIED IDEOGRAPH
+0xB6C1	0x8BFB	#CJK UNIFIED IDEOGRAPH
+0xB6C2	0x5835	#CJK UNIFIED IDEOGRAPH
+0xB6C3	0x7779	#CJK UNIFIED IDEOGRAPH
+0xB6C4	0x8D4C	#CJK UNIFIED IDEOGRAPH
+0xB6C5	0x675C	#CJK UNIFIED IDEOGRAPH
+0xB6C6	0x9540	#CJK UNIFIED IDEOGRAPH
+0xB6C7	0x809A	#CJK UNIFIED IDEOGRAPH
+0xB6C8	0x5EA6	#CJK UNIFIED IDEOGRAPH
+0xB6C9	0x6E21	#CJK UNIFIED IDEOGRAPH
+0xB6CA	0x5992	#CJK UNIFIED IDEOGRAPH
+0xB6CB	0x7AEF	#CJK UNIFIED IDEOGRAPH
+0xB6CC	0x77ED	#CJK UNIFIED IDEOGRAPH
+0xB6CD	0x953B	#CJK UNIFIED IDEOGRAPH
+0xB6CE	0x6BB5	#CJK UNIFIED IDEOGRAPH
+0xB6CF	0x65AD	#CJK UNIFIED IDEOGRAPH
+0xB6D0	0x7F0E	#CJK UNIFIED IDEOGRAPH
+0xB6D1	0x5806	#CJK UNIFIED IDEOGRAPH
+0xB6D2	0x5151	#CJK UNIFIED IDEOGRAPH
+0xB6D3	0x961F	#CJK UNIFIED IDEOGRAPH
+0xB6D4	0x5BF9	#CJK UNIFIED IDEOGRAPH
+0xB6D5	0x58A9	#CJK UNIFIED IDEOGRAPH
+0xB6D6	0x5428	#CJK UNIFIED IDEOGRAPH
+0xB6D7	0x8E72	#CJK UNIFIED IDEOGRAPH
+0xB6D8	0x6566	#CJK UNIFIED IDEOGRAPH
+0xB6D9	0x987F	#CJK UNIFIED IDEOGRAPH
+0xB6DA	0x56E4	#CJK UNIFIED IDEOGRAPH
+0xB6DB	0x949D	#CJK UNIFIED IDEOGRAPH
+0xB6DC	0x76FE	#CJK UNIFIED IDEOGRAPH
+0xB6DD	0x9041	#CJK UNIFIED IDEOGRAPH
+0xB6DE	0x6387	#CJK UNIFIED IDEOGRAPH
+0xB6DF	0x54C6	#CJK UNIFIED IDEOGRAPH
+0xB6E0	0x591A	#CJK UNIFIED IDEOGRAPH
+0xB6E1	0x593A	#CJK UNIFIED IDEOGRAPH
+0xB6E2	0x579B	#CJK UNIFIED IDEOGRAPH
+0xB6E3	0x8EB2	#CJK UNIFIED IDEOGRAPH
+0xB6E4	0x6735	#CJK UNIFIED IDEOGRAPH
+0xB6E5	0x8DFA	#CJK UNIFIED IDEOGRAPH
+0xB6E6	0x8235	#CJK UNIFIED IDEOGRAPH
+0xB6E7	0x5241	#CJK UNIFIED IDEOGRAPH
+0xB6E8	0x60F0	#CJK UNIFIED IDEOGRAPH
+0xB6E9	0x5815	#CJK UNIFIED IDEOGRAPH
+0xB6EA	0x86FE	#CJK UNIFIED IDEOGRAPH
+0xB6EB	0x5CE8	#CJK UNIFIED IDEOGRAPH
+0xB6EC	0x9E45	#CJK UNIFIED IDEOGRAPH
+0xB6ED	0x4FC4	#CJK UNIFIED IDEOGRAPH
+0xB6EE	0x989D	#CJK UNIFIED IDEOGRAPH
+0xB6EF	0x8BB9	#CJK UNIFIED IDEOGRAPH
+0xB6F0	0x5A25	#CJK UNIFIED IDEOGRAPH
+0xB6F1	0x6076	#CJK UNIFIED IDEOGRAPH
+0xB6F2	0x5384	#CJK UNIFIED IDEOGRAPH
+0xB6F3	0x627C	#CJK UNIFIED IDEOGRAPH
+0xB6F4	0x904F	#CJK UNIFIED IDEOGRAPH
+0xB6F5	0x9102	#CJK UNIFIED IDEOGRAPH
+0xB6F6	0x997F	#CJK UNIFIED IDEOGRAPH
+0xB6F7	0x6069	#CJK UNIFIED IDEOGRAPH
+0xB6F8	0x800C	#CJK UNIFIED IDEOGRAPH
+0xB6F9	0x513F	#CJK UNIFIED IDEOGRAPH
+0xB6FA	0x8033	#CJK UNIFIED IDEOGRAPH
+0xB6FB	0x5C14	#CJK UNIFIED IDEOGRAPH
+0xB6FC	0x9975	#CJK UNIFIED IDEOGRAPH
+0xB6FD	0x6D31	#CJK UNIFIED IDEOGRAPH
+0xB6FE	0x4E8C	#CJK UNIFIED IDEOGRAPH
+0xB740	0x7A1D	#CJK UNIFIED IDEOGRAPH
+0xB741	0x7A1F	#CJK UNIFIED IDEOGRAPH
+0xB742	0x7A21	#CJK UNIFIED IDEOGRAPH
+0xB743	0x7A22	#CJK UNIFIED IDEOGRAPH
+0xB744	0x7A24	#CJK UNIFIED IDEOGRAPH
+0xB745	0x7A25	#CJK UNIFIED IDEOGRAPH
+0xB746	0x7A26	#CJK UNIFIED IDEOGRAPH
+0xB747	0x7A27	#CJK UNIFIED IDEOGRAPH
+0xB748	0x7A28	#CJK UNIFIED IDEOGRAPH
+0xB749	0x7A29	#CJK UNIFIED IDEOGRAPH
+0xB74A	0x7A2A	#CJK UNIFIED IDEOGRAPH
+0xB74B	0x7A2B	#CJK UNIFIED IDEOGRAPH
+0xB74C	0x7A2C	#CJK UNIFIED IDEOGRAPH
+0xB74D	0x7A2D	#CJK UNIFIED IDEOGRAPH
+0xB74E	0x7A2E	#CJK UNIFIED IDEOGRAPH
+0xB74F	0x7A2F	#CJK UNIFIED IDEOGRAPH
+0xB750	0x7A30	#CJK UNIFIED IDEOGRAPH
+0xB751	0x7A31	#CJK UNIFIED IDEOGRAPH
+0xB752	0x7A32	#CJK UNIFIED IDEOGRAPH
+0xB753	0x7A34	#CJK UNIFIED IDEOGRAPH
+0xB754	0x7A35	#CJK UNIFIED IDEOGRAPH
+0xB755	0x7A36	#CJK UNIFIED IDEOGRAPH
+0xB756	0x7A38	#CJK UNIFIED IDEOGRAPH
+0xB757	0x7A3A	#CJK UNIFIED IDEOGRAPH
+0xB758	0x7A3E	#CJK UNIFIED IDEOGRAPH
+0xB759	0x7A40	#CJK UNIFIED IDEOGRAPH
+0xB75A	0x7A41	#CJK UNIFIED IDEOGRAPH
+0xB75B	0x7A42	#CJK UNIFIED IDEOGRAPH
+0xB75C	0x7A43	#CJK UNIFIED IDEOGRAPH
+0xB75D	0x7A44	#CJK UNIFIED IDEOGRAPH
+0xB75E	0x7A45	#CJK UNIFIED IDEOGRAPH
+0xB75F	0x7A47	#CJK UNIFIED IDEOGRAPH
+0xB760	0x7A48	#CJK UNIFIED IDEOGRAPH
+0xB761	0x7A49	#CJK UNIFIED IDEOGRAPH
+0xB762	0x7A4A	#CJK UNIFIED IDEOGRAPH
+0xB763	0x7A4B	#CJK UNIFIED IDEOGRAPH
+0xB764	0x7A4C	#CJK UNIFIED IDEOGRAPH
+0xB765	0x7A4D	#CJK UNIFIED IDEOGRAPH
+0xB766	0x7A4E	#CJK UNIFIED IDEOGRAPH
+0xB767	0x7A4F	#CJK UNIFIED IDEOGRAPH
+0xB768	0x7A50	#CJK UNIFIED IDEOGRAPH
+0xB769	0x7A52	#CJK UNIFIED IDEOGRAPH
+0xB76A	0x7A53	#CJK UNIFIED IDEOGRAPH
+0xB76B	0x7A54	#CJK UNIFIED IDEOGRAPH
+0xB76C	0x7A55	#CJK UNIFIED IDEOGRAPH
+0xB76D	0x7A56	#CJK UNIFIED IDEOGRAPH
+0xB76E	0x7A58	#CJK UNIFIED IDEOGRAPH
+0xB76F	0x7A59	#CJK UNIFIED IDEOGRAPH
+0xB770	0x7A5A	#CJK UNIFIED IDEOGRAPH
+0xB771	0x7A5B	#CJK UNIFIED IDEOGRAPH
+0xB772	0x7A5C	#CJK UNIFIED IDEOGRAPH
+0xB773	0x7A5D	#CJK UNIFIED IDEOGRAPH
+0xB774	0x7A5E	#CJK UNIFIED IDEOGRAPH
+0xB775	0x7A5F	#CJK UNIFIED IDEOGRAPH
+0xB776	0x7A60	#CJK UNIFIED IDEOGRAPH
+0xB777	0x7A61	#CJK UNIFIED IDEOGRAPH
+0xB778	0x7A62	#CJK UNIFIED IDEOGRAPH
+0xB779	0x7A63	#CJK UNIFIED IDEOGRAPH
+0xB77A	0x7A64	#CJK UNIFIED IDEOGRAPH
+0xB77B	0x7A65	#CJK UNIFIED IDEOGRAPH
+0xB77C	0x7A66	#CJK UNIFIED IDEOGRAPH
+0xB77D	0x7A67	#CJK UNIFIED IDEOGRAPH
+0xB77E	0x7A68	#CJK UNIFIED IDEOGRAPH
+0xB780	0x7A69	#CJK UNIFIED IDEOGRAPH
+0xB781	0x7A6A	#CJK UNIFIED IDEOGRAPH
+0xB782	0x7A6B	#CJK UNIFIED IDEOGRAPH
+0xB783	0x7A6C	#CJK UNIFIED IDEOGRAPH
+0xB784	0x7A6D	#CJK UNIFIED IDEOGRAPH
+0xB785	0x7A6E	#CJK UNIFIED IDEOGRAPH
+0xB786	0x7A6F	#CJK UNIFIED IDEOGRAPH
+0xB787	0x7A71	#CJK UNIFIED IDEOGRAPH
+0xB788	0x7A72	#CJK UNIFIED IDEOGRAPH
+0xB789	0x7A73	#CJK UNIFIED IDEOGRAPH
+0xB78A	0x7A75	#CJK UNIFIED IDEOGRAPH
+0xB78B	0x7A7B	#CJK UNIFIED IDEOGRAPH
+0xB78C	0x7A7C	#CJK UNIFIED IDEOGRAPH
+0xB78D	0x7A7D	#CJK UNIFIED IDEOGRAPH
+0xB78E	0x7A7E	#CJK UNIFIED IDEOGRAPH
+0xB78F	0x7A82	#CJK UNIFIED IDEOGRAPH
+0xB790	0x7A85	#CJK UNIFIED IDEOGRAPH
+0xB791	0x7A87	#CJK UNIFIED IDEOGRAPH
+0xB792	0x7A89	#CJK UNIFIED IDEOGRAPH
+0xB793	0x7A8A	#CJK UNIFIED IDEOGRAPH
+0xB794	0x7A8B	#CJK UNIFIED IDEOGRAPH
+0xB795	0x7A8C	#CJK UNIFIED IDEOGRAPH
+0xB796	0x7A8E	#CJK UNIFIED IDEOGRAPH
+0xB797	0x7A8F	#CJK UNIFIED IDEOGRAPH
+0xB798	0x7A90	#CJK UNIFIED IDEOGRAPH
+0xB799	0x7A93	#CJK UNIFIED IDEOGRAPH
+0xB79A	0x7A94	#CJK UNIFIED IDEOGRAPH
+0xB79B	0x7A99	#CJK UNIFIED IDEOGRAPH
+0xB79C	0x7A9A	#CJK UNIFIED IDEOGRAPH
+0xB79D	0x7A9B	#CJK UNIFIED IDEOGRAPH
+0xB79E	0x7A9E	#CJK UNIFIED IDEOGRAPH
+0xB79F	0x7AA1	#CJK UNIFIED IDEOGRAPH
+0xB7A0	0x7AA2	#CJK UNIFIED IDEOGRAPH
+0xB7A1	0x8D30	#CJK UNIFIED IDEOGRAPH
+0xB7A2	0x53D1	#CJK UNIFIED IDEOGRAPH
+0xB7A3	0x7F5A	#CJK UNIFIED IDEOGRAPH
+0xB7A4	0x7B4F	#CJK UNIFIED IDEOGRAPH
+0xB7A5	0x4F10	#CJK UNIFIED IDEOGRAPH
+0xB7A6	0x4E4F	#CJK UNIFIED IDEOGRAPH
+0xB7A7	0x9600	#CJK UNIFIED IDEOGRAPH
+0xB7A8	0x6CD5	#CJK UNIFIED IDEOGRAPH
+0xB7A9	0x73D0	#CJK UNIFIED IDEOGRAPH
+0xB7AA	0x85E9	#CJK UNIFIED IDEOGRAPH
+0xB7AB	0x5E06	#CJK UNIFIED IDEOGRAPH
+0xB7AC	0x756A	#CJK UNIFIED IDEOGRAPH
+0xB7AD	0x7FFB	#CJK UNIFIED IDEOGRAPH
+0xB7AE	0x6A0A	#CJK UNIFIED IDEOGRAPH
+0xB7AF	0x77FE	#CJK UNIFIED IDEOGRAPH
+0xB7B0	0x9492	#CJK UNIFIED IDEOGRAPH
+0xB7B1	0x7E41	#CJK UNIFIED IDEOGRAPH
+0xB7B2	0x51E1	#CJK UNIFIED IDEOGRAPH
+0xB7B3	0x70E6	#CJK UNIFIED IDEOGRAPH
+0xB7B4	0x53CD	#CJK UNIFIED IDEOGRAPH
+0xB7B5	0x8FD4	#CJK UNIFIED IDEOGRAPH
+0xB7B6	0x8303	#CJK UNIFIED IDEOGRAPH
+0xB7B7	0x8D29	#CJK UNIFIED IDEOGRAPH
+0xB7B8	0x72AF	#CJK UNIFIED IDEOGRAPH
+0xB7B9	0x996D	#CJK UNIFIED IDEOGRAPH
+0xB7BA	0x6CDB	#CJK UNIFIED IDEOGRAPH
+0xB7BB	0x574A	#CJK UNIFIED IDEOGRAPH
+0xB7BC	0x82B3	#CJK UNIFIED IDEOGRAPH
+0xB7BD	0x65B9	#CJK UNIFIED IDEOGRAPH
+0xB7BE	0x80AA	#CJK UNIFIED IDEOGRAPH
+0xB7BF	0x623F	#CJK UNIFIED IDEOGRAPH
+0xB7C0	0x9632	#CJK UNIFIED IDEOGRAPH
+0xB7C1	0x59A8	#CJK UNIFIED IDEOGRAPH
+0xB7C2	0x4EFF	#CJK UNIFIED IDEOGRAPH
+0xB7C3	0x8BBF	#CJK UNIFIED IDEOGRAPH
+0xB7C4	0x7EBA	#CJK UNIFIED IDEOGRAPH
+0xB7C5	0x653E	#CJK UNIFIED IDEOGRAPH
+0xB7C6	0x83F2	#CJK UNIFIED IDEOGRAPH
+0xB7C7	0x975E	#CJK UNIFIED IDEOGRAPH
+0xB7C8	0x5561	#CJK UNIFIED IDEOGRAPH
+0xB7C9	0x98DE	#CJK UNIFIED IDEOGRAPH
+0xB7CA	0x80A5	#CJK UNIFIED IDEOGRAPH
+0xB7CB	0x532A	#CJK UNIFIED IDEOGRAPH
+0xB7CC	0x8BFD	#CJK UNIFIED IDEOGRAPH
+0xB7CD	0x5420	#CJK UNIFIED IDEOGRAPH
+0xB7CE	0x80BA	#CJK UNIFIED IDEOGRAPH
+0xB7CF	0x5E9F	#CJK UNIFIED IDEOGRAPH
+0xB7D0	0x6CB8	#CJK UNIFIED IDEOGRAPH
+0xB7D1	0x8D39	#CJK UNIFIED IDEOGRAPH
+0xB7D2	0x82AC	#CJK UNIFIED IDEOGRAPH
+0xB7D3	0x915A	#CJK UNIFIED IDEOGRAPH
+0xB7D4	0x5429	#CJK UNIFIED IDEOGRAPH
+0xB7D5	0x6C1B	#CJK UNIFIED IDEOGRAPH
+0xB7D6	0x5206	#CJK UNIFIED IDEOGRAPH
+0xB7D7	0x7EB7	#CJK UNIFIED IDEOGRAPH
+0xB7D8	0x575F	#CJK UNIFIED IDEOGRAPH
+0xB7D9	0x711A	#CJK UNIFIED IDEOGRAPH
+0xB7DA	0x6C7E	#CJK UNIFIED IDEOGRAPH
+0xB7DB	0x7C89	#CJK UNIFIED IDEOGRAPH
+0xB7DC	0x594B	#CJK UNIFIED IDEOGRAPH
+0xB7DD	0x4EFD	#CJK UNIFIED IDEOGRAPH
+0xB7DE	0x5FFF	#CJK UNIFIED IDEOGRAPH
+0xB7DF	0x6124	#CJK UNIFIED IDEOGRAPH
+0xB7E0	0x7CAA	#CJK UNIFIED IDEOGRAPH
+0xB7E1	0x4E30	#CJK UNIFIED IDEOGRAPH
+0xB7E2	0x5C01	#CJK UNIFIED IDEOGRAPH
+0xB7E3	0x67AB	#CJK UNIFIED IDEOGRAPH
+0xB7E4	0x8702	#CJK UNIFIED IDEOGRAPH
+0xB7E5	0x5CF0	#CJK UNIFIED IDEOGRAPH
+0xB7E6	0x950B	#CJK UNIFIED IDEOGRAPH
+0xB7E7	0x98CE	#CJK UNIFIED IDEOGRAPH
+0xB7E8	0x75AF	#CJK UNIFIED IDEOGRAPH
+0xB7E9	0x70FD	#CJK UNIFIED IDEOGRAPH
+0xB7EA	0x9022	#CJK UNIFIED IDEOGRAPH
+0xB7EB	0x51AF	#CJK UNIFIED IDEOGRAPH
+0xB7EC	0x7F1D	#CJK UNIFIED IDEOGRAPH
+0xB7ED	0x8BBD	#CJK UNIFIED IDEOGRAPH
+0xB7EE	0x5949	#CJK UNIFIED IDEOGRAPH
+0xB7EF	0x51E4	#CJK UNIFIED IDEOGRAPH
+0xB7F0	0x4F5B	#CJK UNIFIED IDEOGRAPH
+0xB7F1	0x5426	#CJK UNIFIED IDEOGRAPH
+0xB7F2	0x592B	#CJK UNIFIED IDEOGRAPH
+0xB7F3	0x6577	#CJK UNIFIED IDEOGRAPH
+0xB7F4	0x80A4	#CJK UNIFIED IDEOGRAPH
+0xB7F5	0x5B75	#CJK UNIFIED IDEOGRAPH
+0xB7F6	0x6276	#CJK UNIFIED IDEOGRAPH
+0xB7F7	0x62C2	#CJK UNIFIED IDEOGRAPH
+0xB7F8	0x8F90	#CJK UNIFIED IDEOGRAPH
+0xB7F9	0x5E45	#CJK UNIFIED IDEOGRAPH
+0xB7FA	0x6C1F	#CJK UNIFIED IDEOGRAPH
+0xB7FB	0x7B26	#CJK UNIFIED IDEOGRAPH
+0xB7FC	0x4F0F	#CJK UNIFIED IDEOGRAPH
+0xB7FD	0x4FD8	#CJK UNIFIED IDEOGRAPH
+0xB7FE	0x670D	#CJK UNIFIED IDEOGRAPH
+0xB840	0x7AA3	#CJK UNIFIED IDEOGRAPH
+0xB841	0x7AA4	#CJK UNIFIED IDEOGRAPH
+0xB842	0x7AA7	#CJK UNIFIED IDEOGRAPH
+0xB843	0x7AA9	#CJK UNIFIED IDEOGRAPH
+0xB844	0x7AAA	#CJK UNIFIED IDEOGRAPH
+0xB845	0x7AAB	#CJK UNIFIED IDEOGRAPH
+0xB846	0x7AAE	#CJK UNIFIED IDEOGRAPH
+0xB847	0x7AAF	#CJK UNIFIED IDEOGRAPH
+0xB848	0x7AB0	#CJK UNIFIED IDEOGRAPH
+0xB849	0x7AB1	#CJK UNIFIED IDEOGRAPH
+0xB84A	0x7AB2	#CJK UNIFIED IDEOGRAPH
+0xB84B	0x7AB4	#CJK UNIFIED IDEOGRAPH
+0xB84C	0x7AB5	#CJK UNIFIED IDEOGRAPH
+0xB84D	0x7AB6	#CJK UNIFIED IDEOGRAPH
+0xB84E	0x7AB7	#CJK UNIFIED IDEOGRAPH
+0xB84F	0x7AB8	#CJK UNIFIED IDEOGRAPH
+0xB850	0x7AB9	#CJK UNIFIED IDEOGRAPH
+0xB851	0x7ABA	#CJK UNIFIED IDEOGRAPH
+0xB852	0x7ABB	#CJK UNIFIED IDEOGRAPH
+0xB853	0x7ABC	#CJK UNIFIED IDEOGRAPH
+0xB854	0x7ABD	#CJK UNIFIED IDEOGRAPH
+0xB855	0x7ABE	#CJK UNIFIED IDEOGRAPH
+0xB856	0x7AC0	#CJK UNIFIED IDEOGRAPH
+0xB857	0x7AC1	#CJK UNIFIED IDEOGRAPH
+0xB858	0x7AC2	#CJK UNIFIED IDEOGRAPH
+0xB859	0x7AC3	#CJK UNIFIED IDEOGRAPH
+0xB85A	0x7AC4	#CJK UNIFIED IDEOGRAPH
+0xB85B	0x7AC5	#CJK UNIFIED IDEOGRAPH
+0xB85C	0x7AC6	#CJK UNIFIED IDEOGRAPH
+0xB85D	0x7AC7	#CJK UNIFIED IDEOGRAPH
+0xB85E	0x7AC8	#CJK UNIFIED IDEOGRAPH
+0xB85F	0x7AC9	#CJK UNIFIED IDEOGRAPH
+0xB860	0x7ACA	#CJK UNIFIED IDEOGRAPH
+0xB861	0x7ACC	#CJK UNIFIED IDEOGRAPH
+0xB862	0x7ACD	#CJK UNIFIED IDEOGRAPH
+0xB863	0x7ACE	#CJK UNIFIED IDEOGRAPH
+0xB864	0x7ACF	#CJK UNIFIED IDEOGRAPH
+0xB865	0x7AD0	#CJK UNIFIED IDEOGRAPH
+0xB866	0x7AD1	#CJK UNIFIED IDEOGRAPH
+0xB867	0x7AD2	#CJK UNIFIED IDEOGRAPH
+0xB868	0x7AD3	#CJK UNIFIED IDEOGRAPH
+0xB869	0x7AD4	#CJK UNIFIED IDEOGRAPH
+0xB86A	0x7AD5	#CJK UNIFIED IDEOGRAPH
+0xB86B	0x7AD7	#CJK UNIFIED IDEOGRAPH
+0xB86C	0x7AD8	#CJK UNIFIED IDEOGRAPH
+0xB86D	0x7ADA	#CJK UNIFIED IDEOGRAPH
+0xB86E	0x7ADB	#CJK UNIFIED IDEOGRAPH
+0xB86F	0x7ADC	#CJK UNIFIED IDEOGRAPH
+0xB870	0x7ADD	#CJK UNIFIED IDEOGRAPH
+0xB871	0x7AE1	#CJK UNIFIED IDEOGRAPH
+0xB872	0x7AE2	#CJK UNIFIED IDEOGRAPH
+0xB873	0x7AE4	#CJK UNIFIED IDEOGRAPH
+0xB874	0x7AE7	#CJK UNIFIED IDEOGRAPH
+0xB875	0x7AE8	#CJK UNIFIED IDEOGRAPH
+0xB876	0x7AE9	#CJK UNIFIED IDEOGRAPH
+0xB877	0x7AEA	#CJK UNIFIED IDEOGRAPH
+0xB878	0x7AEB	#CJK UNIFIED IDEOGRAPH
+0xB879	0x7AEC	#CJK UNIFIED IDEOGRAPH
+0xB87A	0x7AEE	#CJK UNIFIED IDEOGRAPH
+0xB87B	0x7AF0	#CJK UNIFIED IDEOGRAPH
+0xB87C	0x7AF1	#CJK UNIFIED IDEOGRAPH
+0xB87D	0x7AF2	#CJK UNIFIED IDEOGRAPH
+0xB87E	0x7AF3	#CJK UNIFIED IDEOGRAPH
+0xB880	0x7AF4	#CJK UNIFIED IDEOGRAPH
+0xB881	0x7AF5	#CJK UNIFIED IDEOGRAPH
+0xB882	0x7AF6	#CJK UNIFIED IDEOGRAPH
+0xB883	0x7AF7	#CJK UNIFIED IDEOGRAPH
+0xB884	0x7AF8	#CJK UNIFIED IDEOGRAPH
+0xB885	0x7AFB	#CJK UNIFIED IDEOGRAPH
+0xB886	0x7AFC	#CJK UNIFIED IDEOGRAPH
+0xB887	0x7AFE	#CJK UNIFIED IDEOGRAPH
+0xB888	0x7B00	#CJK UNIFIED IDEOGRAPH
+0xB889	0x7B01	#CJK UNIFIED IDEOGRAPH
+0xB88A	0x7B02	#CJK UNIFIED IDEOGRAPH
+0xB88B	0x7B05	#CJK UNIFIED IDEOGRAPH
+0xB88C	0x7B07	#CJK UNIFIED IDEOGRAPH
+0xB88D	0x7B09	#CJK UNIFIED IDEOGRAPH
+0xB88E	0x7B0C	#CJK UNIFIED IDEOGRAPH
+0xB88F	0x7B0D	#CJK UNIFIED IDEOGRAPH
+0xB890	0x7B0E	#CJK UNIFIED IDEOGRAPH
+0xB891	0x7B10	#CJK UNIFIED IDEOGRAPH
+0xB892	0x7B12	#CJK UNIFIED IDEOGRAPH
+0xB893	0x7B13	#CJK UNIFIED IDEOGRAPH
+0xB894	0x7B16	#CJK UNIFIED IDEOGRAPH
+0xB895	0x7B17	#CJK UNIFIED IDEOGRAPH
+0xB896	0x7B18	#CJK UNIFIED IDEOGRAPH
+0xB897	0x7B1A	#CJK UNIFIED IDEOGRAPH
+0xB898	0x7B1C	#CJK UNIFIED IDEOGRAPH
+0xB899	0x7B1D	#CJK UNIFIED IDEOGRAPH
+0xB89A	0x7B1F	#CJK UNIFIED IDEOGRAPH
+0xB89B	0x7B21	#CJK UNIFIED IDEOGRAPH
+0xB89C	0x7B22	#CJK UNIFIED IDEOGRAPH
+0xB89D	0x7B23	#CJK UNIFIED IDEOGRAPH
+0xB89E	0x7B27	#CJK UNIFIED IDEOGRAPH
+0xB89F	0x7B29	#CJK UNIFIED IDEOGRAPH
+0xB8A0	0x7B2D	#CJK UNIFIED IDEOGRAPH
+0xB8A1	0x6D6E	#CJK UNIFIED IDEOGRAPH
+0xB8A2	0x6DAA	#CJK UNIFIED IDEOGRAPH
+0xB8A3	0x798F	#CJK UNIFIED IDEOGRAPH
+0xB8A4	0x88B1	#CJK UNIFIED IDEOGRAPH
+0xB8A5	0x5F17	#CJK UNIFIED IDEOGRAPH
+0xB8A6	0x752B	#CJK UNIFIED IDEOGRAPH
+0xB8A7	0x629A	#CJK UNIFIED IDEOGRAPH
+0xB8A8	0x8F85	#CJK UNIFIED IDEOGRAPH
+0xB8A9	0x4FEF	#CJK UNIFIED IDEOGRAPH
+0xB8AA	0x91DC	#CJK UNIFIED IDEOGRAPH
+0xB8AB	0x65A7	#CJK UNIFIED IDEOGRAPH
+0xB8AC	0x812F	#CJK UNIFIED IDEOGRAPH
+0xB8AD	0x8151	#CJK UNIFIED IDEOGRAPH
+0xB8AE	0x5E9C	#CJK UNIFIED IDEOGRAPH
+0xB8AF	0x8150	#CJK UNIFIED IDEOGRAPH
+0xB8B0	0x8D74	#CJK UNIFIED IDEOGRAPH
+0xB8B1	0x526F	#CJK UNIFIED IDEOGRAPH
+0xB8B2	0x8986	#CJK UNIFIED IDEOGRAPH
+0xB8B3	0x8D4B	#CJK UNIFIED IDEOGRAPH
+0xB8B4	0x590D	#CJK UNIFIED IDEOGRAPH
+0xB8B5	0x5085	#CJK UNIFIED IDEOGRAPH
+0xB8B6	0x4ED8	#CJK UNIFIED IDEOGRAPH
+0xB8B7	0x961C	#CJK UNIFIED IDEOGRAPH
+0xB8B8	0x7236	#CJK UNIFIED IDEOGRAPH
+0xB8B9	0x8179	#CJK UNIFIED IDEOGRAPH
+0xB8BA	0x8D1F	#CJK UNIFIED IDEOGRAPH
+0xB8BB	0x5BCC	#CJK UNIFIED IDEOGRAPH
+0xB8BC	0x8BA3	#CJK UNIFIED IDEOGRAPH
+0xB8BD	0x9644	#CJK UNIFIED IDEOGRAPH
+0xB8BE	0x5987	#CJK UNIFIED IDEOGRAPH
+0xB8BF	0x7F1A	#CJK UNIFIED IDEOGRAPH
+0xB8C0	0x5490	#CJK UNIFIED IDEOGRAPH
+0xB8C1	0x5676	#CJK UNIFIED IDEOGRAPH
+0xB8C2	0x560E	#CJK UNIFIED IDEOGRAPH
+0xB8C3	0x8BE5	#CJK UNIFIED IDEOGRAPH
+0xB8C4	0x6539	#CJK UNIFIED IDEOGRAPH
+0xB8C5	0x6982	#CJK UNIFIED IDEOGRAPH
+0xB8C6	0x9499	#CJK UNIFIED IDEOGRAPH
+0xB8C7	0x76D6	#CJK UNIFIED IDEOGRAPH
+0xB8C8	0x6E89	#CJK UNIFIED IDEOGRAPH
+0xB8C9	0x5E72	#CJK UNIFIED IDEOGRAPH
+0xB8CA	0x7518	#CJK UNIFIED IDEOGRAPH
+0xB8CB	0x6746	#CJK UNIFIED IDEOGRAPH
+0xB8CC	0x67D1	#CJK UNIFIED IDEOGRAPH
+0xB8CD	0x7AFF	#CJK UNIFIED IDEOGRAPH
+0xB8CE	0x809D	#CJK UNIFIED IDEOGRAPH
+0xB8CF	0x8D76	#CJK UNIFIED IDEOGRAPH
+0xB8D0	0x611F	#CJK UNIFIED IDEOGRAPH
+0xB8D1	0x79C6	#CJK UNIFIED IDEOGRAPH
+0xB8D2	0x6562	#CJK UNIFIED IDEOGRAPH
+0xB8D3	0x8D63	#CJK UNIFIED IDEOGRAPH
+0xB8D4	0x5188	#CJK UNIFIED IDEOGRAPH
+0xB8D5	0x521A	#CJK UNIFIED IDEOGRAPH
+0xB8D6	0x94A2	#CJK UNIFIED IDEOGRAPH
+0xB8D7	0x7F38	#CJK UNIFIED IDEOGRAPH
+0xB8D8	0x809B	#CJK UNIFIED IDEOGRAPH
+0xB8D9	0x7EB2	#CJK UNIFIED IDEOGRAPH
+0xB8DA	0x5C97	#CJK UNIFIED IDEOGRAPH
+0xB8DB	0x6E2F	#CJK UNIFIED IDEOGRAPH
+0xB8DC	0x6760	#CJK UNIFIED IDEOGRAPH
+0xB8DD	0x7BD9	#CJK UNIFIED IDEOGRAPH
+0xB8DE	0x768B	#CJK UNIFIED IDEOGRAPH
+0xB8DF	0x9AD8	#CJK UNIFIED IDEOGRAPH
+0xB8E0	0x818F	#CJK UNIFIED IDEOGRAPH
+0xB8E1	0x7F94	#CJK UNIFIED IDEOGRAPH
+0xB8E2	0x7CD5	#CJK UNIFIED IDEOGRAPH
+0xB8E3	0x641E	#CJK UNIFIED IDEOGRAPH
+0xB8E4	0x9550	#CJK UNIFIED IDEOGRAPH
+0xB8E5	0x7A3F	#CJK UNIFIED IDEOGRAPH
+0xB8E6	0x544A	#CJK UNIFIED IDEOGRAPH
+0xB8E7	0x54E5	#CJK UNIFIED IDEOGRAPH
+0xB8E8	0x6B4C	#CJK UNIFIED IDEOGRAPH
+0xB8E9	0x6401	#CJK UNIFIED IDEOGRAPH
+0xB8EA	0x6208	#CJK UNIFIED IDEOGRAPH
+0xB8EB	0x9E3D	#CJK UNIFIED IDEOGRAPH
+0xB8EC	0x80F3	#CJK UNIFIED IDEOGRAPH
+0xB8ED	0x7599	#CJK UNIFIED IDEOGRAPH
+0xB8EE	0x5272	#CJK UNIFIED IDEOGRAPH
+0xB8EF	0x9769	#CJK UNIFIED IDEOGRAPH
+0xB8F0	0x845B	#CJK UNIFIED IDEOGRAPH
+0xB8F1	0x683C	#CJK UNIFIED IDEOGRAPH
+0xB8F2	0x86E4	#CJK UNIFIED IDEOGRAPH
+0xB8F3	0x9601	#CJK UNIFIED IDEOGRAPH
+0xB8F4	0x9694	#CJK UNIFIED IDEOGRAPH
+0xB8F5	0x94EC	#CJK UNIFIED IDEOGRAPH
+0xB8F6	0x4E2A	#CJK UNIFIED IDEOGRAPH
+0xB8F7	0x5404	#CJK UNIFIED IDEOGRAPH
+0xB8F8	0x7ED9	#CJK UNIFIED IDEOGRAPH
+0xB8F9	0x6839	#CJK UNIFIED IDEOGRAPH
+0xB8FA	0x8DDF	#CJK UNIFIED IDEOGRAPH
+0xB8FB	0x8015	#CJK UNIFIED IDEOGRAPH
+0xB8FC	0x66F4	#CJK UNIFIED IDEOGRAPH
+0xB8FD	0x5E9A	#CJK UNIFIED IDEOGRAPH
+0xB8FE	0x7FB9	#CJK UNIFIED IDEOGRAPH
+0xB940	0x7B2F	#CJK UNIFIED IDEOGRAPH
+0xB941	0x7B30	#CJK UNIFIED IDEOGRAPH
+0xB942	0x7B32	#CJK UNIFIED IDEOGRAPH
+0xB943	0x7B34	#CJK UNIFIED IDEOGRAPH
+0xB944	0x7B35	#CJK UNIFIED IDEOGRAPH
+0xB945	0x7B36	#CJK UNIFIED IDEOGRAPH
+0xB946	0x7B37	#CJK UNIFIED IDEOGRAPH
+0xB947	0x7B39	#CJK UNIFIED IDEOGRAPH
+0xB948	0x7B3B	#CJK UNIFIED IDEOGRAPH
+0xB949	0x7B3D	#CJK UNIFIED IDEOGRAPH
+0xB94A	0x7B3F	#CJK UNIFIED IDEOGRAPH
+0xB94B	0x7B40	#CJK UNIFIED IDEOGRAPH
+0xB94C	0x7B41	#CJK UNIFIED IDEOGRAPH
+0xB94D	0x7B42	#CJK UNIFIED IDEOGRAPH
+0xB94E	0x7B43	#CJK UNIFIED IDEOGRAPH
+0xB94F	0x7B44	#CJK UNIFIED IDEOGRAPH
+0xB950	0x7B46	#CJK UNIFIED IDEOGRAPH
+0xB951	0x7B48	#CJK UNIFIED IDEOGRAPH
+0xB952	0x7B4A	#CJK UNIFIED IDEOGRAPH
+0xB953	0x7B4D	#CJK UNIFIED IDEOGRAPH
+0xB954	0x7B4E	#CJK UNIFIED IDEOGRAPH
+0xB955	0x7B53	#CJK UNIFIED IDEOGRAPH
+0xB956	0x7B55	#CJK UNIFIED IDEOGRAPH
+0xB957	0x7B57	#CJK UNIFIED IDEOGRAPH
+0xB958	0x7B59	#CJK UNIFIED IDEOGRAPH
+0xB959	0x7B5C	#CJK UNIFIED IDEOGRAPH
+0xB95A	0x7B5E	#CJK UNIFIED IDEOGRAPH
+0xB95B	0x7B5F	#CJK UNIFIED IDEOGRAPH
+0xB95C	0x7B61	#CJK UNIFIED IDEOGRAPH
+0xB95D	0x7B63	#CJK UNIFIED IDEOGRAPH
+0xB95E	0x7B64	#CJK UNIFIED IDEOGRAPH
+0xB95F	0x7B65	#CJK UNIFIED IDEOGRAPH
+0xB960	0x7B66	#CJK UNIFIED IDEOGRAPH
+0xB961	0x7B67	#CJK UNIFIED IDEOGRAPH
+0xB962	0x7B68	#CJK UNIFIED IDEOGRAPH
+0xB963	0x7B69	#CJK UNIFIED IDEOGRAPH
+0xB964	0x7B6A	#CJK UNIFIED IDEOGRAPH
+0xB965	0x7B6B	#CJK UNIFIED IDEOGRAPH
+0xB966	0x7B6C	#CJK UNIFIED IDEOGRAPH
+0xB967	0x7B6D	#CJK UNIFIED IDEOGRAPH
+0xB968	0x7B6F	#CJK UNIFIED IDEOGRAPH
+0xB969	0x7B70	#CJK UNIFIED IDEOGRAPH
+0xB96A	0x7B73	#CJK UNIFIED IDEOGRAPH
+0xB96B	0x7B74	#CJK UNIFIED IDEOGRAPH
+0xB96C	0x7B76	#CJK UNIFIED IDEOGRAPH
+0xB96D	0x7B78	#CJK UNIFIED IDEOGRAPH
+0xB96E	0x7B7A	#CJK UNIFIED IDEOGRAPH
+0xB96F	0x7B7C	#CJK UNIFIED IDEOGRAPH
+0xB970	0x7B7D	#CJK UNIFIED IDEOGRAPH
+0xB971	0x7B7F	#CJK UNIFIED IDEOGRAPH
+0xB972	0x7B81	#CJK UNIFIED IDEOGRAPH
+0xB973	0x7B82	#CJK UNIFIED IDEOGRAPH
+0xB974	0x7B83	#CJK UNIFIED IDEOGRAPH
+0xB975	0x7B84	#CJK UNIFIED IDEOGRAPH
+0xB976	0x7B86	#CJK UNIFIED IDEOGRAPH
+0xB977	0x7B87	#CJK UNIFIED IDEOGRAPH
+0xB978	0x7B88	#CJK UNIFIED IDEOGRAPH
+0xB979	0x7B89	#CJK UNIFIED IDEOGRAPH
+0xB97A	0x7B8A	#CJK UNIFIED IDEOGRAPH
+0xB97B	0x7B8B	#CJK UNIFIED IDEOGRAPH
+0xB97C	0x7B8C	#CJK UNIFIED IDEOGRAPH
+0xB97D	0x7B8E	#CJK UNIFIED IDEOGRAPH
+0xB97E	0x7B8F	#CJK UNIFIED IDEOGRAPH
+0xB980	0x7B91	#CJK UNIFIED IDEOGRAPH
+0xB981	0x7B92	#CJK UNIFIED IDEOGRAPH
+0xB982	0x7B93	#CJK UNIFIED IDEOGRAPH
+0xB983	0x7B96	#CJK UNIFIED IDEOGRAPH
+0xB984	0x7B98	#CJK UNIFIED IDEOGRAPH
+0xB985	0x7B99	#CJK UNIFIED IDEOGRAPH
+0xB986	0x7B9A	#CJK UNIFIED IDEOGRAPH
+0xB987	0x7B9B	#CJK UNIFIED IDEOGRAPH
+0xB988	0x7B9E	#CJK UNIFIED IDEOGRAPH
+0xB989	0x7B9F	#CJK UNIFIED IDEOGRAPH
+0xB98A	0x7BA0	#CJK UNIFIED IDEOGRAPH
+0xB98B	0x7BA3	#CJK UNIFIED IDEOGRAPH
+0xB98C	0x7BA4	#CJK UNIFIED IDEOGRAPH
+0xB98D	0x7BA5	#CJK UNIFIED IDEOGRAPH
+0xB98E	0x7BAE	#CJK UNIFIED IDEOGRAPH
+0xB98F	0x7BAF	#CJK UNIFIED IDEOGRAPH
+0xB990	0x7BB0	#CJK UNIFIED IDEOGRAPH
+0xB991	0x7BB2	#CJK UNIFIED IDEOGRAPH
+0xB992	0x7BB3	#CJK UNIFIED IDEOGRAPH
+0xB993	0x7BB5	#CJK UNIFIED IDEOGRAPH
+0xB994	0x7BB6	#CJK UNIFIED IDEOGRAPH
+0xB995	0x7BB7	#CJK UNIFIED IDEOGRAPH
+0xB996	0x7BB9	#CJK UNIFIED IDEOGRAPH
+0xB997	0x7BBA	#CJK UNIFIED IDEOGRAPH
+0xB998	0x7BBB	#CJK UNIFIED IDEOGRAPH
+0xB999	0x7BBC	#CJK UNIFIED IDEOGRAPH
+0xB99A	0x7BBD	#CJK UNIFIED IDEOGRAPH
+0xB99B	0x7BBE	#CJK UNIFIED IDEOGRAPH
+0xB99C	0x7BBF	#CJK UNIFIED IDEOGRAPH
+0xB99D	0x7BC0	#CJK UNIFIED IDEOGRAPH
+0xB99E	0x7BC2	#CJK UNIFIED IDEOGRAPH
+0xB99F	0x7BC3	#CJK UNIFIED IDEOGRAPH
+0xB9A0	0x7BC4	#CJK UNIFIED IDEOGRAPH
+0xB9A1	0x57C2	#CJK UNIFIED IDEOGRAPH
+0xB9A2	0x803F	#CJK UNIFIED IDEOGRAPH
+0xB9A3	0x6897	#CJK UNIFIED IDEOGRAPH
+0xB9A4	0x5DE5	#CJK UNIFIED IDEOGRAPH
+0xB9A5	0x653B	#CJK UNIFIED IDEOGRAPH
+0xB9A6	0x529F	#CJK UNIFIED IDEOGRAPH
+0xB9A7	0x606D	#CJK UNIFIED IDEOGRAPH
+0xB9A8	0x9F9A	#CJK UNIFIED IDEOGRAPH
+0xB9A9	0x4F9B	#CJK UNIFIED IDEOGRAPH
+0xB9AA	0x8EAC	#CJK UNIFIED IDEOGRAPH
+0xB9AB	0x516C	#CJK UNIFIED IDEOGRAPH
+0xB9AC	0x5BAB	#CJK UNIFIED IDEOGRAPH
+0xB9AD	0x5F13	#CJK UNIFIED IDEOGRAPH
+0xB9AE	0x5DE9	#CJK UNIFIED IDEOGRAPH
+0xB9AF	0x6C5E	#CJK UNIFIED IDEOGRAPH
+0xB9B0	0x62F1	#CJK UNIFIED IDEOGRAPH
+0xB9B1	0x8D21	#CJK UNIFIED IDEOGRAPH
+0xB9B2	0x5171	#CJK UNIFIED IDEOGRAPH
+0xB9B3	0x94A9	#CJK UNIFIED IDEOGRAPH
+0xB9B4	0x52FE	#CJK UNIFIED IDEOGRAPH
+0xB9B5	0x6C9F	#CJK UNIFIED IDEOGRAPH
+0xB9B6	0x82DF	#CJK UNIFIED IDEOGRAPH
+0xB9B7	0x72D7	#CJK UNIFIED IDEOGRAPH
+0xB9B8	0x57A2	#CJK UNIFIED IDEOGRAPH
+0xB9B9	0x6784	#CJK UNIFIED IDEOGRAPH
+0xB9BA	0x8D2D	#CJK UNIFIED IDEOGRAPH
+0xB9BB	0x591F	#CJK UNIFIED IDEOGRAPH
+0xB9BC	0x8F9C	#CJK UNIFIED IDEOGRAPH
+0xB9BD	0x83C7	#CJK UNIFIED IDEOGRAPH
+0xB9BE	0x5495	#CJK UNIFIED IDEOGRAPH
+0xB9BF	0x7B8D	#CJK UNIFIED IDEOGRAPH
+0xB9C0	0x4F30	#CJK UNIFIED IDEOGRAPH
+0xB9C1	0x6CBD	#CJK UNIFIED IDEOGRAPH
+0xB9C2	0x5B64	#CJK UNIFIED IDEOGRAPH
+0xB9C3	0x59D1	#CJK UNIFIED IDEOGRAPH
+0xB9C4	0x9F13	#CJK UNIFIED IDEOGRAPH
+0xB9C5	0x53E4	#CJK UNIFIED IDEOGRAPH
+0xB9C6	0x86CA	#CJK UNIFIED IDEOGRAPH
+0xB9C7	0x9AA8	#CJK UNIFIED IDEOGRAPH
+0xB9C8	0x8C37	#CJK UNIFIED IDEOGRAPH
+0xB9C9	0x80A1	#CJK UNIFIED IDEOGRAPH
+0xB9CA	0x6545	#CJK UNIFIED IDEOGRAPH
+0xB9CB	0x987E	#CJK UNIFIED IDEOGRAPH
+0xB9CC	0x56FA	#CJK UNIFIED IDEOGRAPH
+0xB9CD	0x96C7	#CJK UNIFIED IDEOGRAPH
+0xB9CE	0x522E	#CJK UNIFIED IDEOGRAPH
+0xB9CF	0x74DC	#CJK UNIFIED IDEOGRAPH
+0xB9D0	0x5250	#CJK UNIFIED IDEOGRAPH
+0xB9D1	0x5BE1	#CJK UNIFIED IDEOGRAPH
+0xB9D2	0x6302	#CJK UNIFIED IDEOGRAPH
+0xB9D3	0x8902	#CJK UNIFIED IDEOGRAPH
+0xB9D4	0x4E56	#CJK UNIFIED IDEOGRAPH
+0xB9D5	0x62D0	#CJK UNIFIED IDEOGRAPH
+0xB9D6	0x602A	#CJK UNIFIED IDEOGRAPH
+0xB9D7	0x68FA	#CJK UNIFIED IDEOGRAPH
+0xB9D8	0x5173	#CJK UNIFIED IDEOGRAPH
+0xB9D9	0x5B98	#CJK UNIFIED IDEOGRAPH
+0xB9DA	0x51A0	#CJK UNIFIED IDEOGRAPH
+0xB9DB	0x89C2	#CJK UNIFIED IDEOGRAPH
+0xB9DC	0x7BA1	#CJK UNIFIED IDEOGRAPH
+0xB9DD	0x9986	#CJK UNIFIED IDEOGRAPH
+0xB9DE	0x7F50	#CJK UNIFIED IDEOGRAPH
+0xB9DF	0x60EF	#CJK UNIFIED IDEOGRAPH
+0xB9E0	0x704C	#CJK UNIFIED IDEOGRAPH
+0xB9E1	0x8D2F	#CJK UNIFIED IDEOGRAPH
+0xB9E2	0x5149	#CJK UNIFIED IDEOGRAPH
+0xB9E3	0x5E7F	#CJK UNIFIED IDEOGRAPH
+0xB9E4	0x901B	#CJK UNIFIED IDEOGRAPH
+0xB9E5	0x7470	#CJK UNIFIED IDEOGRAPH
+0xB9E6	0x89C4	#CJK UNIFIED IDEOGRAPH
+0xB9E7	0x572D	#CJK UNIFIED IDEOGRAPH
+0xB9E8	0x7845	#CJK UNIFIED IDEOGRAPH
+0xB9E9	0x5F52	#CJK UNIFIED IDEOGRAPH
+0xB9EA	0x9F9F	#CJK UNIFIED IDEOGRAPH
+0xB9EB	0x95FA	#CJK UNIFIED IDEOGRAPH
+0xB9EC	0x8F68	#CJK UNIFIED IDEOGRAPH
+0xB9ED	0x9B3C	#CJK UNIFIED IDEOGRAPH
+0xB9EE	0x8BE1	#CJK UNIFIED IDEOGRAPH
+0xB9EF	0x7678	#CJK UNIFIED IDEOGRAPH
+0xB9F0	0x6842	#CJK UNIFIED IDEOGRAPH
+0xB9F1	0x67DC	#CJK UNIFIED IDEOGRAPH
+0xB9F2	0x8DEA	#CJK UNIFIED IDEOGRAPH
+0xB9F3	0x8D35	#CJK UNIFIED IDEOGRAPH
+0xB9F4	0x523D	#CJK UNIFIED IDEOGRAPH
+0xB9F5	0x8F8A	#CJK UNIFIED IDEOGRAPH
+0xB9F6	0x6EDA	#CJK UNIFIED IDEOGRAPH
+0xB9F7	0x68CD	#CJK UNIFIED IDEOGRAPH
+0xB9F8	0x9505	#CJK UNIFIED IDEOGRAPH
+0xB9F9	0x90ED	#CJK UNIFIED IDEOGRAPH
+0xB9FA	0x56FD	#CJK UNIFIED IDEOGRAPH
+0xB9FB	0x679C	#CJK UNIFIED IDEOGRAPH
+0xB9FC	0x88F9	#CJK UNIFIED IDEOGRAPH
+0xB9FD	0x8FC7	#CJK UNIFIED IDEOGRAPH
+0xB9FE	0x54C8	#CJK UNIFIED IDEOGRAPH
+0xBA40	0x7BC5	#CJK UNIFIED IDEOGRAPH
+0xBA41	0x7BC8	#CJK UNIFIED IDEOGRAPH
+0xBA42	0x7BC9	#CJK UNIFIED IDEOGRAPH
+0xBA43	0x7BCA	#CJK UNIFIED IDEOGRAPH
+0xBA44	0x7BCB	#CJK UNIFIED IDEOGRAPH
+0xBA45	0x7BCD	#CJK UNIFIED IDEOGRAPH
+0xBA46	0x7BCE	#CJK UNIFIED IDEOGRAPH
+0xBA47	0x7BCF	#CJK UNIFIED IDEOGRAPH
+0xBA48	0x7BD0	#CJK UNIFIED IDEOGRAPH
+0xBA49	0x7BD2	#CJK UNIFIED IDEOGRAPH
+0xBA4A	0x7BD4	#CJK UNIFIED IDEOGRAPH
+0xBA4B	0x7BD5	#CJK UNIFIED IDEOGRAPH
+0xBA4C	0x7BD6	#CJK UNIFIED IDEOGRAPH
+0xBA4D	0x7BD7	#CJK UNIFIED IDEOGRAPH
+0xBA4E	0x7BD8	#CJK UNIFIED IDEOGRAPH
+0xBA4F	0x7BDB	#CJK UNIFIED IDEOGRAPH
+0xBA50	0x7BDC	#CJK UNIFIED IDEOGRAPH
+0xBA51	0x7BDE	#CJK UNIFIED IDEOGRAPH
+0xBA52	0x7BDF	#CJK UNIFIED IDEOGRAPH
+0xBA53	0x7BE0	#CJK UNIFIED IDEOGRAPH
+0xBA54	0x7BE2	#CJK UNIFIED IDEOGRAPH
+0xBA55	0x7BE3	#CJK UNIFIED IDEOGRAPH
+0xBA56	0x7BE4	#CJK UNIFIED IDEOGRAPH
+0xBA57	0x7BE7	#CJK UNIFIED IDEOGRAPH
+0xBA58	0x7BE8	#CJK UNIFIED IDEOGRAPH
+0xBA59	0x7BE9	#CJK UNIFIED IDEOGRAPH
+0xBA5A	0x7BEB	#CJK UNIFIED IDEOGRAPH
+0xBA5B	0x7BEC	#CJK UNIFIED IDEOGRAPH
+0xBA5C	0x7BED	#CJK UNIFIED IDEOGRAPH
+0xBA5D	0x7BEF	#CJK UNIFIED IDEOGRAPH
+0xBA5E	0x7BF0	#CJK UNIFIED IDEOGRAPH
+0xBA5F	0x7BF2	#CJK UNIFIED IDEOGRAPH
+0xBA60	0x7BF3	#CJK UNIFIED IDEOGRAPH
+0xBA61	0x7BF4	#CJK UNIFIED IDEOGRAPH
+0xBA62	0x7BF5	#CJK UNIFIED IDEOGRAPH
+0xBA63	0x7BF6	#CJK UNIFIED IDEOGRAPH
+0xBA64	0x7BF8	#CJK UNIFIED IDEOGRAPH
+0xBA65	0x7BF9	#CJK UNIFIED IDEOGRAPH
+0xBA66	0x7BFA	#CJK UNIFIED IDEOGRAPH
+0xBA67	0x7BFB	#CJK UNIFIED IDEOGRAPH
+0xBA68	0x7BFD	#CJK UNIFIED IDEOGRAPH
+0xBA69	0x7BFF	#CJK UNIFIED IDEOGRAPH
+0xBA6A	0x7C00	#CJK UNIFIED IDEOGRAPH
+0xBA6B	0x7C01	#CJK UNIFIED IDEOGRAPH
+0xBA6C	0x7C02	#CJK UNIFIED IDEOGRAPH
+0xBA6D	0x7C03	#CJK UNIFIED IDEOGRAPH
+0xBA6E	0x7C04	#CJK UNIFIED IDEOGRAPH
+0xBA6F	0x7C05	#CJK UNIFIED IDEOGRAPH
+0xBA70	0x7C06	#CJK UNIFIED IDEOGRAPH
+0xBA71	0x7C08	#CJK UNIFIED IDEOGRAPH
+0xBA72	0x7C09	#CJK UNIFIED IDEOGRAPH
+0xBA73	0x7C0A	#CJK UNIFIED IDEOGRAPH
+0xBA74	0x7C0D	#CJK UNIFIED IDEOGRAPH
+0xBA75	0x7C0E	#CJK UNIFIED IDEOGRAPH
+0xBA76	0x7C10	#CJK UNIFIED IDEOGRAPH
+0xBA77	0x7C11	#CJK UNIFIED IDEOGRAPH
+0xBA78	0x7C12	#CJK UNIFIED IDEOGRAPH
+0xBA79	0x7C13	#CJK UNIFIED IDEOGRAPH
+0xBA7A	0x7C14	#CJK UNIFIED IDEOGRAPH
+0xBA7B	0x7C15	#CJK UNIFIED IDEOGRAPH
+0xBA7C	0x7C17	#CJK UNIFIED IDEOGRAPH
+0xBA7D	0x7C18	#CJK UNIFIED IDEOGRAPH
+0xBA7E	0x7C19	#CJK UNIFIED IDEOGRAPH
+0xBA80	0x7C1A	#CJK UNIFIED IDEOGRAPH
+0xBA81	0x7C1B	#CJK UNIFIED IDEOGRAPH
+0xBA82	0x7C1C	#CJK UNIFIED IDEOGRAPH
+0xBA83	0x7C1D	#CJK UNIFIED IDEOGRAPH
+0xBA84	0x7C1E	#CJK UNIFIED IDEOGRAPH
+0xBA85	0x7C20	#CJK UNIFIED IDEOGRAPH
+0xBA86	0x7C21	#CJK UNIFIED IDEOGRAPH
+0xBA87	0x7C22	#CJK UNIFIED IDEOGRAPH
+0xBA88	0x7C23	#CJK UNIFIED IDEOGRAPH
+0xBA89	0x7C24	#CJK UNIFIED IDEOGRAPH
+0xBA8A	0x7C25	#CJK UNIFIED IDEOGRAPH
+0xBA8B	0x7C28	#CJK UNIFIED IDEOGRAPH
+0xBA8C	0x7C29	#CJK UNIFIED IDEOGRAPH
+0xBA8D	0x7C2B	#CJK UNIFIED IDEOGRAPH
+0xBA8E	0x7C2C	#CJK UNIFIED IDEOGRAPH
+0xBA8F	0x7C2D	#CJK UNIFIED IDEOGRAPH
+0xBA90	0x7C2E	#CJK UNIFIED IDEOGRAPH
+0xBA91	0x7C2F	#CJK UNIFIED IDEOGRAPH
+0xBA92	0x7C30	#CJK UNIFIED IDEOGRAPH
+0xBA93	0x7C31	#CJK UNIFIED IDEOGRAPH
+0xBA94	0x7C32	#CJK UNIFIED IDEOGRAPH
+0xBA95	0x7C33	#CJK UNIFIED IDEOGRAPH
+0xBA96	0x7C34	#CJK UNIFIED IDEOGRAPH
+0xBA97	0x7C35	#CJK UNIFIED IDEOGRAPH
+0xBA98	0x7C36	#CJK UNIFIED IDEOGRAPH
+0xBA99	0x7C37	#CJK UNIFIED IDEOGRAPH
+0xBA9A	0x7C39	#CJK UNIFIED IDEOGRAPH
+0xBA9B	0x7C3A	#CJK UNIFIED IDEOGRAPH
+0xBA9C	0x7C3B	#CJK UNIFIED IDEOGRAPH
+0xBA9D	0x7C3C	#CJK UNIFIED IDEOGRAPH
+0xBA9E	0x7C3D	#CJK UNIFIED IDEOGRAPH
+0xBA9F	0x7C3E	#CJK UNIFIED IDEOGRAPH
+0xBAA0	0x7C42	#CJK UNIFIED IDEOGRAPH
+0xBAA1	0x9AB8	#CJK UNIFIED IDEOGRAPH
+0xBAA2	0x5B69	#CJK UNIFIED IDEOGRAPH
+0xBAA3	0x6D77	#CJK UNIFIED IDEOGRAPH
+0xBAA4	0x6C26	#CJK UNIFIED IDEOGRAPH
+0xBAA5	0x4EA5	#CJK UNIFIED IDEOGRAPH
+0xBAA6	0x5BB3	#CJK UNIFIED IDEOGRAPH
+0xBAA7	0x9A87	#CJK UNIFIED IDEOGRAPH
+0xBAA8	0x9163	#CJK UNIFIED IDEOGRAPH
+0xBAA9	0x61A8	#CJK UNIFIED IDEOGRAPH
+0xBAAA	0x90AF	#CJK UNIFIED IDEOGRAPH
+0xBAAB	0x97E9	#CJK UNIFIED IDEOGRAPH
+0xBAAC	0x542B	#CJK UNIFIED IDEOGRAPH
+0xBAAD	0x6DB5	#CJK UNIFIED IDEOGRAPH
+0xBAAE	0x5BD2	#CJK UNIFIED IDEOGRAPH
+0xBAAF	0x51FD	#CJK UNIFIED IDEOGRAPH
+0xBAB0	0x558A	#CJK UNIFIED IDEOGRAPH
+0xBAB1	0x7F55	#CJK UNIFIED IDEOGRAPH
+0xBAB2	0x7FF0	#CJK UNIFIED IDEOGRAPH
+0xBAB3	0x64BC	#CJK UNIFIED IDEOGRAPH
+0xBAB4	0x634D	#CJK UNIFIED IDEOGRAPH
+0xBAB5	0x65F1	#CJK UNIFIED IDEOGRAPH
+0xBAB6	0x61BE	#CJK UNIFIED IDEOGRAPH
+0xBAB7	0x608D	#CJK UNIFIED IDEOGRAPH
+0xBAB8	0x710A	#CJK UNIFIED IDEOGRAPH
+0xBAB9	0x6C57	#CJK UNIFIED IDEOGRAPH
+0xBABA	0x6C49	#CJK UNIFIED IDEOGRAPH
+0xBABB	0x592F	#CJK UNIFIED IDEOGRAPH
+0xBABC	0x676D	#CJK UNIFIED IDEOGRAPH
+0xBABD	0x822A	#CJK UNIFIED IDEOGRAPH
+0xBABE	0x58D5	#CJK UNIFIED IDEOGRAPH
+0xBABF	0x568E	#CJK UNIFIED IDEOGRAPH
+0xBAC0	0x8C6A	#CJK UNIFIED IDEOGRAPH
+0xBAC1	0x6BEB	#CJK UNIFIED IDEOGRAPH
+0xBAC2	0x90DD	#CJK UNIFIED IDEOGRAPH
+0xBAC3	0x597D	#CJK UNIFIED IDEOGRAPH
+0xBAC4	0x8017	#CJK UNIFIED IDEOGRAPH
+0xBAC5	0x53F7	#CJK UNIFIED IDEOGRAPH
+0xBAC6	0x6D69	#CJK UNIFIED IDEOGRAPH
+0xBAC7	0x5475	#CJK UNIFIED IDEOGRAPH
+0xBAC8	0x559D	#CJK UNIFIED IDEOGRAPH
+0xBAC9	0x8377	#CJK UNIFIED IDEOGRAPH
+0xBACA	0x83CF	#CJK UNIFIED IDEOGRAPH
+0xBACB	0x6838	#CJK UNIFIED IDEOGRAPH
+0xBACC	0x79BE	#CJK UNIFIED IDEOGRAPH
+0xBACD	0x548C	#CJK UNIFIED IDEOGRAPH
+0xBACE	0x4F55	#CJK UNIFIED IDEOGRAPH
+0xBACF	0x5408	#CJK UNIFIED IDEOGRAPH
+0xBAD0	0x76D2	#CJK UNIFIED IDEOGRAPH
+0xBAD1	0x8C89	#CJK UNIFIED IDEOGRAPH
+0xBAD2	0x9602	#CJK UNIFIED IDEOGRAPH
+0xBAD3	0x6CB3	#CJK UNIFIED IDEOGRAPH
+0xBAD4	0x6DB8	#CJK UNIFIED IDEOGRAPH
+0xBAD5	0x8D6B	#CJK UNIFIED IDEOGRAPH
+0xBAD6	0x8910	#CJK UNIFIED IDEOGRAPH
+0xBAD7	0x9E64	#CJK UNIFIED IDEOGRAPH
+0xBAD8	0x8D3A	#CJK UNIFIED IDEOGRAPH
+0xBAD9	0x563F	#CJK UNIFIED IDEOGRAPH
+0xBADA	0x9ED1	#CJK UNIFIED IDEOGRAPH
+0xBADB	0x75D5	#CJK UNIFIED IDEOGRAPH
+0xBADC	0x5F88	#CJK UNIFIED IDEOGRAPH
+0xBADD	0x72E0	#CJK UNIFIED IDEOGRAPH
+0xBADE	0x6068	#CJK UNIFIED IDEOGRAPH
+0xBADF	0x54FC	#CJK UNIFIED IDEOGRAPH
+0xBAE0	0x4EA8	#CJK UNIFIED IDEOGRAPH
+0xBAE1	0x6A2A	#CJK UNIFIED IDEOGRAPH
+0xBAE2	0x8861	#CJK UNIFIED IDEOGRAPH
+0xBAE3	0x6052	#CJK UNIFIED IDEOGRAPH
+0xBAE4	0x8F70	#CJK UNIFIED IDEOGRAPH
+0xBAE5	0x54C4	#CJK UNIFIED IDEOGRAPH
+0xBAE6	0x70D8	#CJK UNIFIED IDEOGRAPH
+0xBAE7	0x8679	#CJK UNIFIED IDEOGRAPH
+0xBAE8	0x9E3F	#CJK UNIFIED IDEOGRAPH
+0xBAE9	0x6D2A	#CJK UNIFIED IDEOGRAPH
+0xBAEA	0x5B8F	#CJK UNIFIED IDEOGRAPH
+0xBAEB	0x5F18	#CJK UNIFIED IDEOGRAPH
+0xBAEC	0x7EA2	#CJK UNIFIED IDEOGRAPH
+0xBAED	0x5589	#CJK UNIFIED IDEOGRAPH
+0xBAEE	0x4FAF	#CJK UNIFIED IDEOGRAPH
+0xBAEF	0x7334	#CJK UNIFIED IDEOGRAPH
+0xBAF0	0x543C	#CJK UNIFIED IDEOGRAPH
+0xBAF1	0x539A	#CJK UNIFIED IDEOGRAPH
+0xBAF2	0x5019	#CJK UNIFIED IDEOGRAPH
+0xBAF3	0x540E	#CJK UNIFIED IDEOGRAPH
+0xBAF4	0x547C	#CJK UNIFIED IDEOGRAPH
+0xBAF5	0x4E4E	#CJK UNIFIED IDEOGRAPH
+0xBAF6	0x5FFD	#CJK UNIFIED IDEOGRAPH
+0xBAF7	0x745A	#CJK UNIFIED IDEOGRAPH
+0xBAF8	0x58F6	#CJK UNIFIED IDEOGRAPH
+0xBAF9	0x846B	#CJK UNIFIED IDEOGRAPH
+0xBAFA	0x80E1	#CJK UNIFIED IDEOGRAPH
+0xBAFB	0x8774	#CJK UNIFIED IDEOGRAPH
+0xBAFC	0x72D0	#CJK UNIFIED IDEOGRAPH
+0xBAFD	0x7CCA	#CJK UNIFIED IDEOGRAPH
+0xBAFE	0x6E56	#CJK UNIFIED IDEOGRAPH
+0xBB40	0x7C43	#CJK UNIFIED IDEOGRAPH
+0xBB41	0x7C44	#CJK UNIFIED IDEOGRAPH
+0xBB42	0x7C45	#CJK UNIFIED IDEOGRAPH
+0xBB43	0x7C46	#CJK UNIFIED IDEOGRAPH
+0xBB44	0x7C47	#CJK UNIFIED IDEOGRAPH
+0xBB45	0x7C48	#CJK UNIFIED IDEOGRAPH
+0xBB46	0x7C49	#CJK UNIFIED IDEOGRAPH
+0xBB47	0x7C4A	#CJK UNIFIED IDEOGRAPH
+0xBB48	0x7C4B	#CJK UNIFIED IDEOGRAPH
+0xBB49	0x7C4C	#CJK UNIFIED IDEOGRAPH
+0xBB4A	0x7C4E	#CJK UNIFIED IDEOGRAPH
+0xBB4B	0x7C4F	#CJK UNIFIED IDEOGRAPH
+0xBB4C	0x7C50	#CJK UNIFIED IDEOGRAPH
+0xBB4D	0x7C51	#CJK UNIFIED IDEOGRAPH
+0xBB4E	0x7C52	#CJK UNIFIED IDEOGRAPH
+0xBB4F	0x7C53	#CJK UNIFIED IDEOGRAPH
+0xBB50	0x7C54	#CJK UNIFIED IDEOGRAPH
+0xBB51	0x7C55	#CJK UNIFIED IDEOGRAPH
+0xBB52	0x7C56	#CJK UNIFIED IDEOGRAPH
+0xBB53	0x7C57	#CJK UNIFIED IDEOGRAPH
+0xBB54	0x7C58	#CJK UNIFIED IDEOGRAPH
+0xBB55	0x7C59	#CJK UNIFIED IDEOGRAPH
+0xBB56	0x7C5A	#CJK UNIFIED IDEOGRAPH
+0xBB57	0x7C5B	#CJK UNIFIED IDEOGRAPH
+0xBB58	0x7C5C	#CJK UNIFIED IDEOGRAPH
+0xBB59	0x7C5D	#CJK UNIFIED IDEOGRAPH
+0xBB5A	0x7C5E	#CJK UNIFIED IDEOGRAPH
+0xBB5B	0x7C5F	#CJK UNIFIED IDEOGRAPH
+0xBB5C	0x7C60	#CJK UNIFIED IDEOGRAPH
+0xBB5D	0x7C61	#CJK UNIFIED IDEOGRAPH
+0xBB5E	0x7C62	#CJK UNIFIED IDEOGRAPH
+0xBB5F	0x7C63	#CJK UNIFIED IDEOGRAPH
+0xBB60	0x7C64	#CJK UNIFIED IDEOGRAPH
+0xBB61	0x7C65	#CJK UNIFIED IDEOGRAPH
+0xBB62	0x7C66	#CJK UNIFIED IDEOGRAPH
+0xBB63	0x7C67	#CJK UNIFIED IDEOGRAPH
+0xBB64	0x7C68	#CJK UNIFIED IDEOGRAPH
+0xBB65	0x7C69	#CJK UNIFIED IDEOGRAPH
+0xBB66	0x7C6A	#CJK UNIFIED IDEOGRAPH
+0xBB67	0x7C6B	#CJK UNIFIED IDEOGRAPH
+0xBB68	0x7C6C	#CJK UNIFIED IDEOGRAPH
+0xBB69	0x7C6D	#CJK UNIFIED IDEOGRAPH
+0xBB6A	0x7C6E	#CJK UNIFIED IDEOGRAPH
+0xBB6B	0x7C6F	#CJK UNIFIED IDEOGRAPH
+0xBB6C	0x7C70	#CJK UNIFIED IDEOGRAPH
+0xBB6D	0x7C71	#CJK UNIFIED IDEOGRAPH
+0xBB6E	0x7C72	#CJK UNIFIED IDEOGRAPH
+0xBB6F	0x7C75	#CJK UNIFIED IDEOGRAPH
+0xBB70	0x7C76	#CJK UNIFIED IDEOGRAPH
+0xBB71	0x7C77	#CJK UNIFIED IDEOGRAPH
+0xBB72	0x7C78	#CJK UNIFIED IDEOGRAPH
+0xBB73	0x7C79	#CJK UNIFIED IDEOGRAPH
+0xBB74	0x7C7A	#CJK UNIFIED IDEOGRAPH
+0xBB75	0x7C7E	#CJK UNIFIED IDEOGRAPH
+0xBB76	0x7C7F	#CJK UNIFIED IDEOGRAPH
+0xBB77	0x7C80	#CJK UNIFIED IDEOGRAPH
+0xBB78	0x7C81	#CJK UNIFIED IDEOGRAPH
+0xBB79	0x7C82	#CJK UNIFIED IDEOGRAPH
+0xBB7A	0x7C83	#CJK UNIFIED IDEOGRAPH
+0xBB7B	0x7C84	#CJK UNIFIED IDEOGRAPH
+0xBB7C	0x7C85	#CJK UNIFIED IDEOGRAPH
+0xBB7D	0x7C86	#CJK UNIFIED IDEOGRAPH
+0xBB7E	0x7C87	#CJK UNIFIED IDEOGRAPH
+0xBB80	0x7C88	#CJK UNIFIED IDEOGRAPH
+0xBB81	0x7C8A	#CJK UNIFIED IDEOGRAPH
+0xBB82	0x7C8B	#CJK UNIFIED IDEOGRAPH
+0xBB83	0x7C8C	#CJK UNIFIED IDEOGRAPH
+0xBB84	0x7C8D	#CJK UNIFIED IDEOGRAPH
+0xBB85	0x7C8E	#CJK UNIFIED IDEOGRAPH
+0xBB86	0x7C8F	#CJK UNIFIED IDEOGRAPH
+0xBB87	0x7C90	#CJK UNIFIED IDEOGRAPH
+0xBB88	0x7C93	#CJK UNIFIED IDEOGRAPH
+0xBB89	0x7C94	#CJK UNIFIED IDEOGRAPH
+0xBB8A	0x7C96	#CJK UNIFIED IDEOGRAPH
+0xBB8B	0x7C99	#CJK UNIFIED IDEOGRAPH
+0xBB8C	0x7C9A	#CJK UNIFIED IDEOGRAPH
+0xBB8D	0x7C9B	#CJK UNIFIED IDEOGRAPH
+0xBB8E	0x7CA0	#CJK UNIFIED IDEOGRAPH
+0xBB8F	0x7CA1	#CJK UNIFIED IDEOGRAPH
+0xBB90	0x7CA3	#CJK UNIFIED IDEOGRAPH
+0xBB91	0x7CA6	#CJK UNIFIED IDEOGRAPH
+0xBB92	0x7CA7	#CJK UNIFIED IDEOGRAPH
+0xBB93	0x7CA8	#CJK UNIFIED IDEOGRAPH
+0xBB94	0x7CA9	#CJK UNIFIED IDEOGRAPH
+0xBB95	0x7CAB	#CJK UNIFIED IDEOGRAPH
+0xBB96	0x7CAC	#CJK UNIFIED IDEOGRAPH
+0xBB97	0x7CAD	#CJK UNIFIED IDEOGRAPH
+0xBB98	0x7CAF	#CJK UNIFIED IDEOGRAPH
+0xBB99	0x7CB0	#CJK UNIFIED IDEOGRAPH
+0xBB9A	0x7CB4	#CJK UNIFIED IDEOGRAPH
+0xBB9B	0x7CB5	#CJK UNIFIED IDEOGRAPH
+0xBB9C	0x7CB6	#CJK UNIFIED IDEOGRAPH
+0xBB9D	0x7CB7	#CJK UNIFIED IDEOGRAPH
+0xBB9E	0x7CB8	#CJK UNIFIED IDEOGRAPH
+0xBB9F	0x7CBA	#CJK UNIFIED IDEOGRAPH
+0xBBA0	0x7CBB	#CJK UNIFIED IDEOGRAPH
+0xBBA1	0x5F27	#CJK UNIFIED IDEOGRAPH
+0xBBA2	0x864E	#CJK UNIFIED IDEOGRAPH
+0xBBA3	0x552C	#CJK UNIFIED IDEOGRAPH
+0xBBA4	0x62A4	#CJK UNIFIED IDEOGRAPH
+0xBBA5	0x4E92	#CJK UNIFIED IDEOGRAPH
+0xBBA6	0x6CAA	#CJK UNIFIED IDEOGRAPH
+0xBBA7	0x6237	#CJK UNIFIED IDEOGRAPH
+0xBBA8	0x82B1	#CJK UNIFIED IDEOGRAPH
+0xBBA9	0x54D7	#CJK UNIFIED IDEOGRAPH
+0xBBAA	0x534E	#CJK UNIFIED IDEOGRAPH
+0xBBAB	0x733E	#CJK UNIFIED IDEOGRAPH
+0xBBAC	0x6ED1	#CJK UNIFIED IDEOGRAPH
+0xBBAD	0x753B	#CJK UNIFIED IDEOGRAPH
+0xBBAE	0x5212	#CJK UNIFIED IDEOGRAPH
+0xBBAF	0x5316	#CJK UNIFIED IDEOGRAPH
+0xBBB0	0x8BDD	#CJK UNIFIED IDEOGRAPH
+0xBBB1	0x69D0	#CJK UNIFIED IDEOGRAPH
+0xBBB2	0x5F8A	#CJK UNIFIED IDEOGRAPH
+0xBBB3	0x6000	#CJK UNIFIED IDEOGRAPH
+0xBBB4	0x6DEE	#CJK UNIFIED IDEOGRAPH
+0xBBB5	0x574F	#CJK UNIFIED IDEOGRAPH
+0xBBB6	0x6B22	#CJK UNIFIED IDEOGRAPH
+0xBBB7	0x73AF	#CJK UNIFIED IDEOGRAPH
+0xBBB8	0x6853	#CJK UNIFIED IDEOGRAPH
+0xBBB9	0x8FD8	#CJK UNIFIED IDEOGRAPH
+0xBBBA	0x7F13	#CJK UNIFIED IDEOGRAPH
+0xBBBB	0x6362	#CJK UNIFIED IDEOGRAPH
+0xBBBC	0x60A3	#CJK UNIFIED IDEOGRAPH
+0xBBBD	0x5524	#CJK UNIFIED IDEOGRAPH
+0xBBBE	0x75EA	#CJK UNIFIED IDEOGRAPH
+0xBBBF	0x8C62	#CJK UNIFIED IDEOGRAPH
+0xBBC0	0x7115	#CJK UNIFIED IDEOGRAPH
+0xBBC1	0x6DA3	#CJK UNIFIED IDEOGRAPH
+0xBBC2	0x5BA6	#CJK UNIFIED IDEOGRAPH
+0xBBC3	0x5E7B	#CJK UNIFIED IDEOGRAPH
+0xBBC4	0x8352	#CJK UNIFIED IDEOGRAPH
+0xBBC5	0x614C	#CJK UNIFIED IDEOGRAPH
+0xBBC6	0x9EC4	#CJK UNIFIED IDEOGRAPH
+0xBBC7	0x78FA	#CJK UNIFIED IDEOGRAPH
+0xBBC8	0x8757	#CJK UNIFIED IDEOGRAPH
+0xBBC9	0x7C27	#CJK UNIFIED IDEOGRAPH
+0xBBCA	0x7687	#CJK UNIFIED IDEOGRAPH
+0xBBCB	0x51F0	#CJK UNIFIED IDEOGRAPH
+0xBBCC	0x60F6	#CJK UNIFIED IDEOGRAPH
+0xBBCD	0x714C	#CJK UNIFIED IDEOGRAPH
+0xBBCE	0x6643	#CJK UNIFIED IDEOGRAPH
+0xBBCF	0x5E4C	#CJK UNIFIED IDEOGRAPH
+0xBBD0	0x604D	#CJK UNIFIED IDEOGRAPH
+0xBBD1	0x8C0E	#CJK UNIFIED IDEOGRAPH
+0xBBD2	0x7070	#CJK UNIFIED IDEOGRAPH
+0xBBD3	0x6325	#CJK UNIFIED IDEOGRAPH
+0xBBD4	0x8F89	#CJK UNIFIED IDEOGRAPH
+0xBBD5	0x5FBD	#CJK UNIFIED IDEOGRAPH
+0xBBD6	0x6062	#CJK UNIFIED IDEOGRAPH
+0xBBD7	0x86D4	#CJK UNIFIED IDEOGRAPH
+0xBBD8	0x56DE	#CJK UNIFIED IDEOGRAPH
+0xBBD9	0x6BC1	#CJK UNIFIED IDEOGRAPH
+0xBBDA	0x6094	#CJK UNIFIED IDEOGRAPH
+0xBBDB	0x6167	#CJK UNIFIED IDEOGRAPH
+0xBBDC	0x5349	#CJK UNIFIED IDEOGRAPH
+0xBBDD	0x60E0	#CJK UNIFIED IDEOGRAPH
+0xBBDE	0x6666	#CJK UNIFIED IDEOGRAPH
+0xBBDF	0x8D3F	#CJK UNIFIED IDEOGRAPH
+0xBBE0	0x79FD	#CJK UNIFIED IDEOGRAPH
+0xBBE1	0x4F1A	#CJK UNIFIED IDEOGRAPH
+0xBBE2	0x70E9	#CJK UNIFIED IDEOGRAPH
+0xBBE3	0x6C47	#CJK UNIFIED IDEOGRAPH
+0xBBE4	0x8BB3	#CJK UNIFIED IDEOGRAPH
+0xBBE5	0x8BF2	#CJK UNIFIED IDEOGRAPH
+0xBBE6	0x7ED8	#CJK UNIFIED IDEOGRAPH
+0xBBE7	0x8364	#CJK UNIFIED IDEOGRAPH
+0xBBE8	0x660F	#CJK UNIFIED IDEOGRAPH
+0xBBE9	0x5A5A	#CJK UNIFIED IDEOGRAPH
+0xBBEA	0x9B42	#CJK UNIFIED IDEOGRAPH
+0xBBEB	0x6D51	#CJK UNIFIED IDEOGRAPH
+0xBBEC	0x6DF7	#CJK UNIFIED IDEOGRAPH
+0xBBED	0x8C41	#CJK UNIFIED IDEOGRAPH
+0xBBEE	0x6D3B	#CJK UNIFIED IDEOGRAPH
+0xBBEF	0x4F19	#CJK UNIFIED IDEOGRAPH
+0xBBF0	0x706B	#CJK UNIFIED IDEOGRAPH
+0xBBF1	0x83B7	#CJK UNIFIED IDEOGRAPH
+0xBBF2	0x6216	#CJK UNIFIED IDEOGRAPH
+0xBBF3	0x60D1	#CJK UNIFIED IDEOGRAPH
+0xBBF4	0x970D	#CJK UNIFIED IDEOGRAPH
+0xBBF5	0x8D27	#CJK UNIFIED IDEOGRAPH
+0xBBF6	0x7978	#CJK UNIFIED IDEOGRAPH
+0xBBF7	0x51FB	#CJK UNIFIED IDEOGRAPH
+0xBBF8	0x573E	#CJK UNIFIED IDEOGRAPH
+0xBBF9	0x57FA	#CJK UNIFIED IDEOGRAPH
+0xBBFA	0x673A	#CJK UNIFIED IDEOGRAPH
+0xBBFB	0x7578	#CJK UNIFIED IDEOGRAPH
+0xBBFC	0x7A3D	#CJK UNIFIED IDEOGRAPH
+0xBBFD	0x79EF	#CJK UNIFIED IDEOGRAPH
+0xBBFE	0x7B95	#CJK UNIFIED IDEOGRAPH
+0xBC40	0x7CBF	#CJK UNIFIED IDEOGRAPH
+0xBC41	0x7CC0	#CJK UNIFIED IDEOGRAPH
+0xBC42	0x7CC2	#CJK UNIFIED IDEOGRAPH
+0xBC43	0x7CC3	#CJK UNIFIED IDEOGRAPH
+0xBC44	0x7CC4	#CJK UNIFIED IDEOGRAPH
+0xBC45	0x7CC6	#CJK UNIFIED IDEOGRAPH
+0xBC46	0x7CC9	#CJK UNIFIED IDEOGRAPH
+0xBC47	0x7CCB	#CJK UNIFIED IDEOGRAPH
+0xBC48	0x7CCE	#CJK UNIFIED IDEOGRAPH
+0xBC49	0x7CCF	#CJK UNIFIED IDEOGRAPH
+0xBC4A	0x7CD0	#CJK UNIFIED IDEOGRAPH
+0xBC4B	0x7CD1	#CJK UNIFIED IDEOGRAPH
+0xBC4C	0x7CD2	#CJK UNIFIED IDEOGRAPH
+0xBC4D	0x7CD3	#CJK UNIFIED IDEOGRAPH
+0xBC4E	0x7CD4	#CJK UNIFIED IDEOGRAPH
+0xBC4F	0x7CD8	#CJK UNIFIED IDEOGRAPH
+0xBC50	0x7CDA	#CJK UNIFIED IDEOGRAPH
+0xBC51	0x7CDB	#CJK UNIFIED IDEOGRAPH
+0xBC52	0x7CDD	#CJK UNIFIED IDEOGRAPH
+0xBC53	0x7CDE	#CJK UNIFIED IDEOGRAPH
+0xBC54	0x7CE1	#CJK UNIFIED IDEOGRAPH
+0xBC55	0x7CE2	#CJK UNIFIED IDEOGRAPH
+0xBC56	0x7CE3	#CJK UNIFIED IDEOGRAPH
+0xBC57	0x7CE4	#CJK UNIFIED IDEOGRAPH
+0xBC58	0x7CE5	#CJK UNIFIED IDEOGRAPH
+0xBC59	0x7CE6	#CJK UNIFIED IDEOGRAPH
+0xBC5A	0x7CE7	#CJK UNIFIED IDEOGRAPH
+0xBC5B	0x7CE9	#CJK UNIFIED IDEOGRAPH
+0xBC5C	0x7CEA	#CJK UNIFIED IDEOGRAPH
+0xBC5D	0x7CEB	#CJK UNIFIED IDEOGRAPH
+0xBC5E	0x7CEC	#CJK UNIFIED IDEOGRAPH
+0xBC5F	0x7CED	#CJK UNIFIED IDEOGRAPH
+0xBC60	0x7CEE	#CJK UNIFIED IDEOGRAPH
+0xBC61	0x7CF0	#CJK UNIFIED IDEOGRAPH
+0xBC62	0x7CF1	#CJK UNIFIED IDEOGRAPH
+0xBC63	0x7CF2	#CJK UNIFIED IDEOGRAPH
+0xBC64	0x7CF3	#CJK UNIFIED IDEOGRAPH
+0xBC65	0x7CF4	#CJK UNIFIED IDEOGRAPH
+0xBC66	0x7CF5	#CJK UNIFIED IDEOGRAPH
+0xBC67	0x7CF6	#CJK UNIFIED IDEOGRAPH
+0xBC68	0x7CF7	#CJK UNIFIED IDEOGRAPH
+0xBC69	0x7CF9	#CJK UNIFIED IDEOGRAPH
+0xBC6A	0x7CFA	#CJK UNIFIED IDEOGRAPH
+0xBC6B	0x7CFC	#CJK UNIFIED IDEOGRAPH
+0xBC6C	0x7CFD	#CJK UNIFIED IDEOGRAPH
+0xBC6D	0x7CFE	#CJK UNIFIED IDEOGRAPH
+0xBC6E	0x7CFF	#CJK UNIFIED IDEOGRAPH
+0xBC6F	0x7D00	#CJK UNIFIED IDEOGRAPH
+0xBC70	0x7D01	#CJK UNIFIED IDEOGRAPH
+0xBC71	0x7D02	#CJK UNIFIED IDEOGRAPH
+0xBC72	0x7D03	#CJK UNIFIED IDEOGRAPH
+0xBC73	0x7D04	#CJK UNIFIED IDEOGRAPH
+0xBC74	0x7D05	#CJK UNIFIED IDEOGRAPH
+0xBC75	0x7D06	#CJK UNIFIED IDEOGRAPH
+0xBC76	0x7D07	#CJK UNIFIED IDEOGRAPH
+0xBC77	0x7D08	#CJK UNIFIED IDEOGRAPH
+0xBC78	0x7D09	#CJK UNIFIED IDEOGRAPH
+0xBC79	0x7D0B	#CJK UNIFIED IDEOGRAPH
+0xBC7A	0x7D0C	#CJK UNIFIED IDEOGRAPH
+0xBC7B	0x7D0D	#CJK UNIFIED IDEOGRAPH
+0xBC7C	0x7D0E	#CJK UNIFIED IDEOGRAPH
+0xBC7D	0x7D0F	#CJK UNIFIED IDEOGRAPH
+0xBC7E	0x7D10	#CJK UNIFIED IDEOGRAPH
+0xBC80	0x7D11	#CJK UNIFIED IDEOGRAPH
+0xBC81	0x7D12	#CJK UNIFIED IDEOGRAPH
+0xBC82	0x7D13	#CJK UNIFIED IDEOGRAPH
+0xBC83	0x7D14	#CJK UNIFIED IDEOGRAPH
+0xBC84	0x7D15	#CJK UNIFIED IDEOGRAPH
+0xBC85	0x7D16	#CJK UNIFIED IDEOGRAPH
+0xBC86	0x7D17	#CJK UNIFIED IDEOGRAPH
+0xBC87	0x7D18	#CJK UNIFIED IDEOGRAPH
+0xBC88	0x7D19	#CJK UNIFIED IDEOGRAPH
+0xBC89	0x7D1A	#CJK UNIFIED IDEOGRAPH
+0xBC8A	0x7D1B	#CJK UNIFIED IDEOGRAPH
+0xBC8B	0x7D1C	#CJK UNIFIED IDEOGRAPH
+0xBC8C	0x7D1D	#CJK UNIFIED IDEOGRAPH
+0xBC8D	0x7D1E	#CJK UNIFIED IDEOGRAPH
+0xBC8E	0x7D1F	#CJK UNIFIED IDEOGRAPH
+0xBC8F	0x7D21	#CJK UNIFIED IDEOGRAPH
+0xBC90	0x7D23	#CJK UNIFIED IDEOGRAPH
+0xBC91	0x7D24	#CJK UNIFIED IDEOGRAPH
+0xBC92	0x7D25	#CJK UNIFIED IDEOGRAPH
+0xBC93	0x7D26	#CJK UNIFIED IDEOGRAPH
+0xBC94	0x7D28	#CJK UNIFIED IDEOGRAPH
+0xBC95	0x7D29	#CJK UNIFIED IDEOGRAPH
+0xBC96	0x7D2A	#CJK UNIFIED IDEOGRAPH
+0xBC97	0x7D2C	#CJK UNIFIED IDEOGRAPH
+0xBC98	0x7D2D	#CJK UNIFIED IDEOGRAPH
+0xBC99	0x7D2E	#CJK UNIFIED IDEOGRAPH
+0xBC9A	0x7D30	#CJK UNIFIED IDEOGRAPH
+0xBC9B	0x7D31	#CJK UNIFIED IDEOGRAPH
+0xBC9C	0x7D32	#CJK UNIFIED IDEOGRAPH
+0xBC9D	0x7D33	#CJK UNIFIED IDEOGRAPH
+0xBC9E	0x7D34	#CJK UNIFIED IDEOGRAPH
+0xBC9F	0x7D35	#CJK UNIFIED IDEOGRAPH
+0xBCA0	0x7D36	#CJK UNIFIED IDEOGRAPH
+0xBCA1	0x808C	#CJK UNIFIED IDEOGRAPH
+0xBCA2	0x9965	#CJK UNIFIED IDEOGRAPH
+0xBCA3	0x8FF9	#CJK UNIFIED IDEOGRAPH
+0xBCA4	0x6FC0	#CJK UNIFIED IDEOGRAPH
+0xBCA5	0x8BA5	#CJK UNIFIED IDEOGRAPH
+0xBCA6	0x9E21	#CJK UNIFIED IDEOGRAPH
+0xBCA7	0x59EC	#CJK UNIFIED IDEOGRAPH
+0xBCA8	0x7EE9	#CJK UNIFIED IDEOGRAPH
+0xBCA9	0x7F09	#CJK UNIFIED IDEOGRAPH
+0xBCAA	0x5409	#CJK UNIFIED IDEOGRAPH
+0xBCAB	0x6781	#CJK UNIFIED IDEOGRAPH
+0xBCAC	0x68D8	#CJK UNIFIED IDEOGRAPH
+0xBCAD	0x8F91	#CJK UNIFIED IDEOGRAPH
+0xBCAE	0x7C4D	#CJK UNIFIED IDEOGRAPH
+0xBCAF	0x96C6	#CJK UNIFIED IDEOGRAPH
+0xBCB0	0x53CA	#CJK UNIFIED IDEOGRAPH
+0xBCB1	0x6025	#CJK UNIFIED IDEOGRAPH
+0xBCB2	0x75BE	#CJK UNIFIED IDEOGRAPH
+0xBCB3	0x6C72	#CJK UNIFIED IDEOGRAPH
+0xBCB4	0x5373	#CJK UNIFIED IDEOGRAPH
+0xBCB5	0x5AC9	#CJK UNIFIED IDEOGRAPH
+0xBCB6	0x7EA7	#CJK UNIFIED IDEOGRAPH
+0xBCB7	0x6324	#CJK UNIFIED IDEOGRAPH
+0xBCB8	0x51E0	#CJK UNIFIED IDEOGRAPH
+0xBCB9	0x810A	#CJK UNIFIED IDEOGRAPH
+0xBCBA	0x5DF1	#CJK UNIFIED IDEOGRAPH
+0xBCBB	0x84DF	#CJK UNIFIED IDEOGRAPH
+0xBCBC	0x6280	#CJK UNIFIED IDEOGRAPH
+0xBCBD	0x5180	#CJK UNIFIED IDEOGRAPH
+0xBCBE	0x5B63	#CJK UNIFIED IDEOGRAPH
+0xBCBF	0x4F0E	#CJK UNIFIED IDEOGRAPH
+0xBCC0	0x796D	#CJK UNIFIED IDEOGRAPH
+0xBCC1	0x5242	#CJK UNIFIED IDEOGRAPH
+0xBCC2	0x60B8	#CJK UNIFIED IDEOGRAPH
+0xBCC3	0x6D4E	#CJK UNIFIED IDEOGRAPH
+0xBCC4	0x5BC4	#CJK UNIFIED IDEOGRAPH
+0xBCC5	0x5BC2	#CJK UNIFIED IDEOGRAPH
+0xBCC6	0x8BA1	#CJK UNIFIED IDEOGRAPH
+0xBCC7	0x8BB0	#CJK UNIFIED IDEOGRAPH
+0xBCC8	0x65E2	#CJK UNIFIED IDEOGRAPH
+0xBCC9	0x5FCC	#CJK UNIFIED IDEOGRAPH
+0xBCCA	0x9645	#CJK UNIFIED IDEOGRAPH
+0xBCCB	0x5993	#CJK UNIFIED IDEOGRAPH
+0xBCCC	0x7EE7	#CJK UNIFIED IDEOGRAPH
+0xBCCD	0x7EAA	#CJK UNIFIED IDEOGRAPH
+0xBCCE	0x5609	#CJK UNIFIED IDEOGRAPH
+0xBCCF	0x67B7	#CJK UNIFIED IDEOGRAPH
+0xBCD0	0x5939	#CJK UNIFIED IDEOGRAPH
+0xBCD1	0x4F73	#CJK UNIFIED IDEOGRAPH
+0xBCD2	0x5BB6	#CJK UNIFIED IDEOGRAPH
+0xBCD3	0x52A0	#CJK UNIFIED IDEOGRAPH
+0xBCD4	0x835A	#CJK UNIFIED IDEOGRAPH
+0xBCD5	0x988A	#CJK UNIFIED IDEOGRAPH
+0xBCD6	0x8D3E	#CJK UNIFIED IDEOGRAPH
+0xBCD7	0x7532	#CJK UNIFIED IDEOGRAPH
+0xBCD8	0x94BE	#CJK UNIFIED IDEOGRAPH
+0xBCD9	0x5047	#CJK UNIFIED IDEOGRAPH
+0xBCDA	0x7A3C	#CJK UNIFIED IDEOGRAPH
+0xBCDB	0x4EF7	#CJK UNIFIED IDEOGRAPH
+0xBCDC	0x67B6	#CJK UNIFIED IDEOGRAPH
+0xBCDD	0x9A7E	#CJK UNIFIED IDEOGRAPH
+0xBCDE	0x5AC1	#CJK UNIFIED IDEOGRAPH
+0xBCDF	0x6B7C	#CJK UNIFIED IDEOGRAPH
+0xBCE0	0x76D1	#CJK UNIFIED IDEOGRAPH
+0xBCE1	0x575A	#CJK UNIFIED IDEOGRAPH
+0xBCE2	0x5C16	#CJK UNIFIED IDEOGRAPH
+0xBCE3	0x7B3A	#CJK UNIFIED IDEOGRAPH
+0xBCE4	0x95F4	#CJK UNIFIED IDEOGRAPH
+0xBCE5	0x714E	#CJK UNIFIED IDEOGRAPH
+0xBCE6	0x517C	#CJK UNIFIED IDEOGRAPH
+0xBCE7	0x80A9	#CJK UNIFIED IDEOGRAPH
+0xBCE8	0x8270	#CJK UNIFIED IDEOGRAPH
+0xBCE9	0x5978	#CJK UNIFIED IDEOGRAPH
+0xBCEA	0x7F04	#CJK UNIFIED IDEOGRAPH
+0xBCEB	0x8327	#CJK UNIFIED IDEOGRAPH
+0xBCEC	0x68C0	#CJK UNIFIED IDEOGRAPH
+0xBCED	0x67EC	#CJK UNIFIED IDEOGRAPH
+0xBCEE	0x78B1	#CJK UNIFIED IDEOGRAPH
+0xBCEF	0x7877	#CJK UNIFIED IDEOGRAPH
+0xBCF0	0x62E3	#CJK UNIFIED IDEOGRAPH
+0xBCF1	0x6361	#CJK UNIFIED IDEOGRAPH
+0xBCF2	0x7B80	#CJK UNIFIED IDEOGRAPH
+0xBCF3	0x4FED	#CJK UNIFIED IDEOGRAPH
+0xBCF4	0x526A	#CJK UNIFIED IDEOGRAPH
+0xBCF5	0x51CF	#CJK UNIFIED IDEOGRAPH
+0xBCF6	0x8350	#CJK UNIFIED IDEOGRAPH
+0xBCF7	0x69DB	#CJK UNIFIED IDEOGRAPH
+0xBCF8	0x9274	#CJK UNIFIED IDEOGRAPH
+0xBCF9	0x8DF5	#CJK UNIFIED IDEOGRAPH
+0xBCFA	0x8D31	#CJK UNIFIED IDEOGRAPH
+0xBCFB	0x89C1	#CJK UNIFIED IDEOGRAPH
+0xBCFC	0x952E	#CJK UNIFIED IDEOGRAPH
+0xBCFD	0x7BAD	#CJK UNIFIED IDEOGRAPH
+0xBCFE	0x4EF6	#CJK UNIFIED IDEOGRAPH
+0xBD40	0x7D37	#CJK UNIFIED IDEOGRAPH
+0xBD41	0x7D38	#CJK UNIFIED IDEOGRAPH
+0xBD42	0x7D39	#CJK UNIFIED IDEOGRAPH
+0xBD43	0x7D3A	#CJK UNIFIED IDEOGRAPH
+0xBD44	0x7D3B	#CJK UNIFIED IDEOGRAPH
+0xBD45	0x7D3C	#CJK UNIFIED IDEOGRAPH
+0xBD46	0x7D3D	#CJK UNIFIED IDEOGRAPH
+0xBD47	0x7D3E	#CJK UNIFIED IDEOGRAPH
+0xBD48	0x7D3F	#CJK UNIFIED IDEOGRAPH
+0xBD49	0x7D40	#CJK UNIFIED IDEOGRAPH
+0xBD4A	0x7D41	#CJK UNIFIED IDEOGRAPH
+0xBD4B	0x7D42	#CJK UNIFIED IDEOGRAPH
+0xBD4C	0x7D43	#CJK UNIFIED IDEOGRAPH
+0xBD4D	0x7D44	#CJK UNIFIED IDEOGRAPH
+0xBD4E	0x7D45	#CJK UNIFIED IDEOGRAPH
+0xBD4F	0x7D46	#CJK UNIFIED IDEOGRAPH
+0xBD50	0x7D47	#CJK UNIFIED IDEOGRAPH
+0xBD51	0x7D48	#CJK UNIFIED IDEOGRAPH
+0xBD52	0x7D49	#CJK UNIFIED IDEOGRAPH
+0xBD53	0x7D4A	#CJK UNIFIED IDEOGRAPH
+0xBD54	0x7D4B	#CJK UNIFIED IDEOGRAPH
+0xBD55	0x7D4C	#CJK UNIFIED IDEOGRAPH
+0xBD56	0x7D4D	#CJK UNIFIED IDEOGRAPH
+0xBD57	0x7D4E	#CJK UNIFIED IDEOGRAPH
+0xBD58	0x7D4F	#CJK UNIFIED IDEOGRAPH
+0xBD59	0x7D50	#CJK UNIFIED IDEOGRAPH
+0xBD5A	0x7D51	#CJK UNIFIED IDEOGRAPH
+0xBD5B	0x7D52	#CJK UNIFIED IDEOGRAPH
+0xBD5C	0x7D53	#CJK UNIFIED IDEOGRAPH
+0xBD5D	0x7D54	#CJK UNIFIED IDEOGRAPH
+0xBD5E	0x7D55	#CJK UNIFIED IDEOGRAPH
+0xBD5F	0x7D56	#CJK UNIFIED IDEOGRAPH
+0xBD60	0x7D57	#CJK UNIFIED IDEOGRAPH
+0xBD61	0x7D58	#CJK UNIFIED IDEOGRAPH
+0xBD62	0x7D59	#CJK UNIFIED IDEOGRAPH
+0xBD63	0x7D5A	#CJK UNIFIED IDEOGRAPH
+0xBD64	0x7D5B	#CJK UNIFIED IDEOGRAPH
+0xBD65	0x7D5C	#CJK UNIFIED IDEOGRAPH
+0xBD66	0x7D5D	#CJK UNIFIED IDEOGRAPH
+0xBD67	0x7D5E	#CJK UNIFIED IDEOGRAPH
+0xBD68	0x7D5F	#CJK UNIFIED IDEOGRAPH
+0xBD69	0x7D60	#CJK UNIFIED IDEOGRAPH
+0xBD6A	0x7D61	#CJK UNIFIED IDEOGRAPH
+0xBD6B	0x7D62	#CJK UNIFIED IDEOGRAPH
+0xBD6C	0x7D63	#CJK UNIFIED IDEOGRAPH
+0xBD6D	0x7D64	#CJK UNIFIED IDEOGRAPH
+0xBD6E	0x7D65	#CJK UNIFIED IDEOGRAPH
+0xBD6F	0x7D66	#CJK UNIFIED IDEOGRAPH
+0xBD70	0x7D67	#CJK UNIFIED IDEOGRAPH
+0xBD71	0x7D68	#CJK UNIFIED IDEOGRAPH
+0xBD72	0x7D69	#CJK UNIFIED IDEOGRAPH
+0xBD73	0x7D6A	#CJK UNIFIED IDEOGRAPH
+0xBD74	0x7D6B	#CJK UNIFIED IDEOGRAPH
+0xBD75	0x7D6C	#CJK UNIFIED IDEOGRAPH
+0xBD76	0x7D6D	#CJK UNIFIED IDEOGRAPH
+0xBD77	0x7D6F	#CJK UNIFIED IDEOGRAPH
+0xBD78	0x7D70	#CJK UNIFIED IDEOGRAPH
+0xBD79	0x7D71	#CJK UNIFIED IDEOGRAPH
+0xBD7A	0x7D72	#CJK UNIFIED IDEOGRAPH
+0xBD7B	0x7D73	#CJK UNIFIED IDEOGRAPH
+0xBD7C	0x7D74	#CJK UNIFIED IDEOGRAPH
+0xBD7D	0x7D75	#CJK UNIFIED IDEOGRAPH
+0xBD7E	0x7D76	#CJK UNIFIED IDEOGRAPH
+0xBD80	0x7D78	#CJK UNIFIED IDEOGRAPH
+0xBD81	0x7D79	#CJK UNIFIED IDEOGRAPH
+0xBD82	0x7D7A	#CJK UNIFIED IDEOGRAPH
+0xBD83	0x7D7B	#CJK UNIFIED IDEOGRAPH
+0xBD84	0x7D7C	#CJK UNIFIED IDEOGRAPH
+0xBD85	0x7D7D	#CJK UNIFIED IDEOGRAPH
+0xBD86	0x7D7E	#CJK UNIFIED IDEOGRAPH
+0xBD87	0x7D7F	#CJK UNIFIED IDEOGRAPH
+0xBD88	0x7D80	#CJK UNIFIED IDEOGRAPH
+0xBD89	0x7D81	#CJK UNIFIED IDEOGRAPH
+0xBD8A	0x7D82	#CJK UNIFIED IDEOGRAPH
+0xBD8B	0x7D83	#CJK UNIFIED IDEOGRAPH
+0xBD8C	0x7D84	#CJK UNIFIED IDEOGRAPH
+0xBD8D	0x7D85	#CJK UNIFIED IDEOGRAPH
+0xBD8E	0x7D86	#CJK UNIFIED IDEOGRAPH
+0xBD8F	0x7D87	#CJK UNIFIED IDEOGRAPH
+0xBD90	0x7D88	#CJK UNIFIED IDEOGRAPH
+0xBD91	0x7D89	#CJK UNIFIED IDEOGRAPH
+0xBD92	0x7D8A	#CJK UNIFIED IDEOGRAPH
+0xBD93	0x7D8B	#CJK UNIFIED IDEOGRAPH
+0xBD94	0x7D8C	#CJK UNIFIED IDEOGRAPH
+0xBD95	0x7D8D	#CJK UNIFIED IDEOGRAPH
+0xBD96	0x7D8E	#CJK UNIFIED IDEOGRAPH
+0xBD97	0x7D8F	#CJK UNIFIED IDEOGRAPH
+0xBD98	0x7D90	#CJK UNIFIED IDEOGRAPH
+0xBD99	0x7D91	#CJK UNIFIED IDEOGRAPH
+0xBD9A	0x7D92	#CJK UNIFIED IDEOGRAPH
+0xBD9B	0x7D93	#CJK UNIFIED IDEOGRAPH
+0xBD9C	0x7D94	#CJK UNIFIED IDEOGRAPH
+0xBD9D	0x7D95	#CJK UNIFIED IDEOGRAPH
+0xBD9E	0x7D96	#CJK UNIFIED IDEOGRAPH
+0xBD9F	0x7D97	#CJK UNIFIED IDEOGRAPH
+0xBDA0	0x7D98	#CJK UNIFIED IDEOGRAPH
+0xBDA1	0x5065	#CJK UNIFIED IDEOGRAPH
+0xBDA2	0x8230	#CJK UNIFIED IDEOGRAPH
+0xBDA3	0x5251	#CJK UNIFIED IDEOGRAPH
+0xBDA4	0x996F	#CJK UNIFIED IDEOGRAPH
+0xBDA5	0x6E10	#CJK UNIFIED IDEOGRAPH
+0xBDA6	0x6E85	#CJK UNIFIED IDEOGRAPH
+0xBDA7	0x6DA7	#CJK UNIFIED IDEOGRAPH
+0xBDA8	0x5EFA	#CJK UNIFIED IDEOGRAPH
+0xBDA9	0x50F5	#CJK UNIFIED IDEOGRAPH
+0xBDAA	0x59DC	#CJK UNIFIED IDEOGRAPH
+0xBDAB	0x5C06	#CJK UNIFIED IDEOGRAPH
+0xBDAC	0x6D46	#CJK UNIFIED IDEOGRAPH
+0xBDAD	0x6C5F	#CJK UNIFIED IDEOGRAPH
+0xBDAE	0x7586	#CJK UNIFIED IDEOGRAPH
+0xBDAF	0x848B	#CJK UNIFIED IDEOGRAPH
+0xBDB0	0x6868	#CJK UNIFIED IDEOGRAPH
+0xBDB1	0x5956	#CJK UNIFIED IDEOGRAPH
+0xBDB2	0x8BB2	#CJK UNIFIED IDEOGRAPH
+0xBDB3	0x5320	#CJK UNIFIED IDEOGRAPH
+0xBDB4	0x9171	#CJK UNIFIED IDEOGRAPH
+0xBDB5	0x964D	#CJK UNIFIED IDEOGRAPH
+0xBDB6	0x8549	#CJK UNIFIED IDEOGRAPH
+0xBDB7	0x6912	#CJK UNIFIED IDEOGRAPH
+0xBDB8	0x7901	#CJK UNIFIED IDEOGRAPH
+0xBDB9	0x7126	#CJK UNIFIED IDEOGRAPH
+0xBDBA	0x80F6	#CJK UNIFIED IDEOGRAPH
+0xBDBB	0x4EA4	#CJK UNIFIED IDEOGRAPH
+0xBDBC	0x90CA	#CJK UNIFIED IDEOGRAPH
+0xBDBD	0x6D47	#CJK UNIFIED IDEOGRAPH
+0xBDBE	0x9A84	#CJK UNIFIED IDEOGRAPH
+0xBDBF	0x5A07	#CJK UNIFIED IDEOGRAPH
+0xBDC0	0x56BC	#CJK UNIFIED IDEOGRAPH
+0xBDC1	0x6405	#CJK UNIFIED IDEOGRAPH
+0xBDC2	0x94F0	#CJK UNIFIED IDEOGRAPH
+0xBDC3	0x77EB	#CJK UNIFIED IDEOGRAPH
+0xBDC4	0x4FA5	#CJK UNIFIED IDEOGRAPH
+0xBDC5	0x811A	#CJK UNIFIED IDEOGRAPH
+0xBDC6	0x72E1	#CJK UNIFIED IDEOGRAPH
+0xBDC7	0x89D2	#CJK UNIFIED IDEOGRAPH
+0xBDC8	0x997A	#CJK UNIFIED IDEOGRAPH
+0xBDC9	0x7F34	#CJK UNIFIED IDEOGRAPH
+0xBDCA	0x7EDE	#CJK UNIFIED IDEOGRAPH
+0xBDCB	0x527F	#CJK UNIFIED IDEOGRAPH
+0xBDCC	0x6559	#CJK UNIFIED IDEOGRAPH
+0xBDCD	0x9175	#CJK UNIFIED IDEOGRAPH
+0xBDCE	0x8F7F	#CJK UNIFIED IDEOGRAPH
+0xBDCF	0x8F83	#CJK UNIFIED IDEOGRAPH
+0xBDD0	0x53EB	#CJK UNIFIED IDEOGRAPH
+0xBDD1	0x7A96	#CJK UNIFIED IDEOGRAPH
+0xBDD2	0x63ED	#CJK UNIFIED IDEOGRAPH
+0xBDD3	0x63A5	#CJK UNIFIED IDEOGRAPH
+0xBDD4	0x7686	#CJK UNIFIED IDEOGRAPH
+0xBDD5	0x79F8	#CJK UNIFIED IDEOGRAPH
+0xBDD6	0x8857	#CJK UNIFIED IDEOGRAPH
+0xBDD7	0x9636	#CJK UNIFIED IDEOGRAPH
+0xBDD8	0x622A	#CJK UNIFIED IDEOGRAPH
+0xBDD9	0x52AB	#CJK UNIFIED IDEOGRAPH
+0xBDDA	0x8282	#CJK UNIFIED IDEOGRAPH
+0xBDDB	0x6854	#CJK UNIFIED IDEOGRAPH
+0xBDDC	0x6770	#CJK UNIFIED IDEOGRAPH
+0xBDDD	0x6377	#CJK UNIFIED IDEOGRAPH
+0xBDDE	0x776B	#CJK UNIFIED IDEOGRAPH
+0xBDDF	0x7AED	#CJK UNIFIED IDEOGRAPH
+0xBDE0	0x6D01	#CJK UNIFIED IDEOGRAPH
+0xBDE1	0x7ED3	#CJK UNIFIED IDEOGRAPH
+0xBDE2	0x89E3	#CJK UNIFIED IDEOGRAPH
+0xBDE3	0x59D0	#CJK UNIFIED IDEOGRAPH
+0xBDE4	0x6212	#CJK UNIFIED IDEOGRAPH
+0xBDE5	0x85C9	#CJK UNIFIED IDEOGRAPH
+0xBDE6	0x82A5	#CJK UNIFIED IDEOGRAPH
+0xBDE7	0x754C	#CJK UNIFIED IDEOGRAPH
+0xBDE8	0x501F	#CJK UNIFIED IDEOGRAPH
+0xBDE9	0x4ECB	#CJK UNIFIED IDEOGRAPH
+0xBDEA	0x75A5	#CJK UNIFIED IDEOGRAPH
+0xBDEB	0x8BEB	#CJK UNIFIED IDEOGRAPH
+0xBDEC	0x5C4A	#CJK UNIFIED IDEOGRAPH
+0xBDED	0x5DFE	#CJK UNIFIED IDEOGRAPH
+0xBDEE	0x7B4B	#CJK UNIFIED IDEOGRAPH
+0xBDEF	0x65A4	#CJK UNIFIED IDEOGRAPH
+0xBDF0	0x91D1	#CJK UNIFIED IDEOGRAPH
+0xBDF1	0x4ECA	#CJK UNIFIED IDEOGRAPH
+0xBDF2	0x6D25	#CJK UNIFIED IDEOGRAPH
+0xBDF3	0x895F	#CJK UNIFIED IDEOGRAPH
+0xBDF4	0x7D27	#CJK UNIFIED IDEOGRAPH
+0xBDF5	0x9526	#CJK UNIFIED IDEOGRAPH
+0xBDF6	0x4EC5	#CJK UNIFIED IDEOGRAPH
+0xBDF7	0x8C28	#CJK UNIFIED IDEOGRAPH
+0xBDF8	0x8FDB	#CJK UNIFIED IDEOGRAPH
+0xBDF9	0x9773	#CJK UNIFIED IDEOGRAPH
+0xBDFA	0x664B	#CJK UNIFIED IDEOGRAPH
+0xBDFB	0x7981	#CJK UNIFIED IDEOGRAPH
+0xBDFC	0x8FD1	#CJK UNIFIED IDEOGRAPH
+0xBDFD	0x70EC	#CJK UNIFIED IDEOGRAPH
+0xBDFE	0x6D78	#CJK UNIFIED IDEOGRAPH
+0xBE40	0x7D99	#CJK UNIFIED IDEOGRAPH
+0xBE41	0x7D9A	#CJK UNIFIED IDEOGRAPH
+0xBE42	0x7D9B	#CJK UNIFIED IDEOGRAPH
+0xBE43	0x7D9C	#CJK UNIFIED IDEOGRAPH
+0xBE44	0x7D9D	#CJK UNIFIED IDEOGRAPH
+0xBE45	0x7D9E	#CJK UNIFIED IDEOGRAPH
+0xBE46	0x7D9F	#CJK UNIFIED IDEOGRAPH
+0xBE47	0x7DA0	#CJK UNIFIED IDEOGRAPH
+0xBE48	0x7DA1	#CJK UNIFIED IDEOGRAPH
+0xBE49	0x7DA2	#CJK UNIFIED IDEOGRAPH
+0xBE4A	0x7DA3	#CJK UNIFIED IDEOGRAPH
+0xBE4B	0x7DA4	#CJK UNIFIED IDEOGRAPH
+0xBE4C	0x7DA5	#CJK UNIFIED IDEOGRAPH
+0xBE4D	0x7DA7	#CJK UNIFIED IDEOGRAPH
+0xBE4E	0x7DA8	#CJK UNIFIED IDEOGRAPH
+0xBE4F	0x7DA9	#CJK UNIFIED IDEOGRAPH
+0xBE50	0x7DAA	#CJK UNIFIED IDEOGRAPH
+0xBE51	0x7DAB	#CJK UNIFIED IDEOGRAPH
+0xBE52	0x7DAC	#CJK UNIFIED IDEOGRAPH
+0xBE53	0x7DAD	#CJK UNIFIED IDEOGRAPH
+0xBE54	0x7DAF	#CJK UNIFIED IDEOGRAPH
+0xBE55	0x7DB0	#CJK UNIFIED IDEOGRAPH
+0xBE56	0x7DB1	#CJK UNIFIED IDEOGRAPH
+0xBE57	0x7DB2	#CJK UNIFIED IDEOGRAPH
+0xBE58	0x7DB3	#CJK UNIFIED IDEOGRAPH
+0xBE59	0x7DB4	#CJK UNIFIED IDEOGRAPH
+0xBE5A	0x7DB5	#CJK UNIFIED IDEOGRAPH
+0xBE5B	0x7DB6	#CJK UNIFIED IDEOGRAPH
+0xBE5C	0x7DB7	#CJK UNIFIED IDEOGRAPH
+0xBE5D	0x7DB8	#CJK UNIFIED IDEOGRAPH
+0xBE5E	0x7DB9	#CJK UNIFIED IDEOGRAPH
+0xBE5F	0x7DBA	#CJK UNIFIED IDEOGRAPH
+0xBE60	0x7DBB	#CJK UNIFIED IDEOGRAPH
+0xBE61	0x7DBC	#CJK UNIFIED IDEOGRAPH
+0xBE62	0x7DBD	#CJK UNIFIED IDEOGRAPH
+0xBE63	0x7DBE	#CJK UNIFIED IDEOGRAPH
+0xBE64	0x7DBF	#CJK UNIFIED IDEOGRAPH
+0xBE65	0x7DC0	#CJK UNIFIED IDEOGRAPH
+0xBE66	0x7DC1	#CJK UNIFIED IDEOGRAPH
+0xBE67	0x7DC2	#CJK UNIFIED IDEOGRAPH
+0xBE68	0x7DC3	#CJK UNIFIED IDEOGRAPH
+0xBE69	0x7DC4	#CJK UNIFIED IDEOGRAPH
+0xBE6A	0x7DC5	#CJK UNIFIED IDEOGRAPH
+0xBE6B	0x7DC6	#CJK UNIFIED IDEOGRAPH
+0xBE6C	0x7DC7	#CJK UNIFIED IDEOGRAPH
+0xBE6D	0x7DC8	#CJK UNIFIED IDEOGRAPH
+0xBE6E	0x7DC9	#CJK UNIFIED IDEOGRAPH
+0xBE6F	0x7DCA	#CJK UNIFIED IDEOGRAPH
+0xBE70	0x7DCB	#CJK UNIFIED IDEOGRAPH
+0xBE71	0x7DCC	#CJK UNIFIED IDEOGRAPH
+0xBE72	0x7DCD	#CJK UNIFIED IDEOGRAPH
+0xBE73	0x7DCE	#CJK UNIFIED IDEOGRAPH
+0xBE74	0x7DCF	#CJK UNIFIED IDEOGRAPH
+0xBE75	0x7DD0	#CJK UNIFIED IDEOGRAPH
+0xBE76	0x7DD1	#CJK UNIFIED IDEOGRAPH
+0xBE77	0x7DD2	#CJK UNIFIED IDEOGRAPH
+0xBE78	0x7DD3	#CJK UNIFIED IDEOGRAPH
+0xBE79	0x7DD4	#CJK UNIFIED IDEOGRAPH
+0xBE7A	0x7DD5	#CJK UNIFIED IDEOGRAPH
+0xBE7B	0x7DD6	#CJK UNIFIED IDEOGRAPH
+0xBE7C	0x7DD7	#CJK UNIFIED IDEOGRAPH
+0xBE7D	0x7DD8	#CJK UNIFIED IDEOGRAPH
+0xBE7E	0x7DD9	#CJK UNIFIED IDEOGRAPH
+0xBE80	0x7DDA	#CJK UNIFIED IDEOGRAPH
+0xBE81	0x7DDB	#CJK UNIFIED IDEOGRAPH
+0xBE82	0x7DDC	#CJK UNIFIED IDEOGRAPH
+0xBE83	0x7DDD	#CJK UNIFIED IDEOGRAPH
+0xBE84	0x7DDE	#CJK UNIFIED IDEOGRAPH
+0xBE85	0x7DDF	#CJK UNIFIED IDEOGRAPH
+0xBE86	0x7DE0	#CJK UNIFIED IDEOGRAPH
+0xBE87	0x7DE1	#CJK UNIFIED IDEOGRAPH
+0xBE88	0x7DE2	#CJK UNIFIED IDEOGRAPH
+0xBE89	0x7DE3	#CJK UNIFIED IDEOGRAPH
+0xBE8A	0x7DE4	#CJK UNIFIED IDEOGRAPH
+0xBE8B	0x7DE5	#CJK UNIFIED IDEOGRAPH
+0xBE8C	0x7DE6	#CJK UNIFIED IDEOGRAPH
+0xBE8D	0x7DE7	#CJK UNIFIED IDEOGRAPH
+0xBE8E	0x7DE8	#CJK UNIFIED IDEOGRAPH
+0xBE8F	0x7DE9	#CJK UNIFIED IDEOGRAPH
+0xBE90	0x7DEA	#CJK UNIFIED IDEOGRAPH
+0xBE91	0x7DEB	#CJK UNIFIED IDEOGRAPH
+0xBE92	0x7DEC	#CJK UNIFIED IDEOGRAPH
+0xBE93	0x7DED	#CJK UNIFIED IDEOGRAPH
+0xBE94	0x7DEE	#CJK UNIFIED IDEOGRAPH
+0xBE95	0x7DEF	#CJK UNIFIED IDEOGRAPH
+0xBE96	0x7DF0	#CJK UNIFIED IDEOGRAPH
+0xBE97	0x7DF1	#CJK UNIFIED IDEOGRAPH
+0xBE98	0x7DF2	#CJK UNIFIED IDEOGRAPH
+0xBE99	0x7DF3	#CJK UNIFIED IDEOGRAPH
+0xBE9A	0x7DF4	#CJK UNIFIED IDEOGRAPH
+0xBE9B	0x7DF5	#CJK UNIFIED IDEOGRAPH
+0xBE9C	0x7DF6	#CJK UNIFIED IDEOGRAPH
+0xBE9D	0x7DF7	#CJK UNIFIED IDEOGRAPH
+0xBE9E	0x7DF8	#CJK UNIFIED IDEOGRAPH
+0xBE9F	0x7DF9	#CJK UNIFIED IDEOGRAPH
+0xBEA0	0x7DFA	#CJK UNIFIED IDEOGRAPH
+0xBEA1	0x5C3D	#CJK UNIFIED IDEOGRAPH
+0xBEA2	0x52B2	#CJK UNIFIED IDEOGRAPH
+0xBEA3	0x8346	#CJK UNIFIED IDEOGRAPH
+0xBEA4	0x5162	#CJK UNIFIED IDEOGRAPH
+0xBEA5	0x830E	#CJK UNIFIED IDEOGRAPH
+0xBEA6	0x775B	#CJK UNIFIED IDEOGRAPH
+0xBEA7	0x6676	#CJK UNIFIED IDEOGRAPH
+0xBEA8	0x9CB8	#CJK UNIFIED IDEOGRAPH
+0xBEA9	0x4EAC	#CJK UNIFIED IDEOGRAPH
+0xBEAA	0x60CA	#CJK UNIFIED IDEOGRAPH
+0xBEAB	0x7CBE	#CJK UNIFIED IDEOGRAPH
+0xBEAC	0x7CB3	#CJK UNIFIED IDEOGRAPH
+0xBEAD	0x7ECF	#CJK UNIFIED IDEOGRAPH
+0xBEAE	0x4E95	#CJK UNIFIED IDEOGRAPH
+0xBEAF	0x8B66	#CJK UNIFIED IDEOGRAPH
+0xBEB0	0x666F	#CJK UNIFIED IDEOGRAPH
+0xBEB1	0x9888	#CJK UNIFIED IDEOGRAPH
+0xBEB2	0x9759	#CJK UNIFIED IDEOGRAPH
+0xBEB3	0x5883	#CJK UNIFIED IDEOGRAPH
+0xBEB4	0x656C	#CJK UNIFIED IDEOGRAPH
+0xBEB5	0x955C	#CJK UNIFIED IDEOGRAPH
+0xBEB6	0x5F84	#CJK UNIFIED IDEOGRAPH
+0xBEB7	0x75C9	#CJK UNIFIED IDEOGRAPH
+0xBEB8	0x9756	#CJK UNIFIED IDEOGRAPH
+0xBEB9	0x7ADF	#CJK UNIFIED IDEOGRAPH
+0xBEBA	0x7ADE	#CJK UNIFIED IDEOGRAPH
+0xBEBB	0x51C0	#CJK UNIFIED IDEOGRAPH
+0xBEBC	0x70AF	#CJK UNIFIED IDEOGRAPH
+0xBEBD	0x7A98	#CJK UNIFIED IDEOGRAPH
+0xBEBE	0x63EA	#CJK UNIFIED IDEOGRAPH
+0xBEBF	0x7A76	#CJK UNIFIED IDEOGRAPH
+0xBEC0	0x7EA0	#CJK UNIFIED IDEOGRAPH
+0xBEC1	0x7396	#CJK UNIFIED IDEOGRAPH
+0xBEC2	0x97ED	#CJK UNIFIED IDEOGRAPH
+0xBEC3	0x4E45	#CJK UNIFIED IDEOGRAPH
+0xBEC4	0x7078	#CJK UNIFIED IDEOGRAPH
+0xBEC5	0x4E5D	#CJK UNIFIED IDEOGRAPH
+0xBEC6	0x9152	#CJK UNIFIED IDEOGRAPH
+0xBEC7	0x53A9	#CJK UNIFIED IDEOGRAPH
+0xBEC8	0x6551	#CJK UNIFIED IDEOGRAPH
+0xBEC9	0x65E7	#CJK UNIFIED IDEOGRAPH
+0xBECA	0x81FC	#CJK UNIFIED IDEOGRAPH
+0xBECB	0x8205	#CJK UNIFIED IDEOGRAPH
+0xBECC	0x548E	#CJK UNIFIED IDEOGRAPH
+0xBECD	0x5C31	#CJK UNIFIED IDEOGRAPH
+0xBECE	0x759A	#CJK UNIFIED IDEOGRAPH
+0xBECF	0x97A0	#CJK UNIFIED IDEOGRAPH
+0xBED0	0x62D8	#CJK UNIFIED IDEOGRAPH
+0xBED1	0x72D9	#CJK UNIFIED IDEOGRAPH
+0xBED2	0x75BD	#CJK UNIFIED IDEOGRAPH
+0xBED3	0x5C45	#CJK UNIFIED IDEOGRAPH
+0xBED4	0x9A79	#CJK UNIFIED IDEOGRAPH
+0xBED5	0x83CA	#CJK UNIFIED IDEOGRAPH
+0xBED6	0x5C40	#CJK UNIFIED IDEOGRAPH
+0xBED7	0x5480	#CJK UNIFIED IDEOGRAPH
+0xBED8	0x77E9	#CJK UNIFIED IDEOGRAPH
+0xBED9	0x4E3E	#CJK UNIFIED IDEOGRAPH
+0xBEDA	0x6CAE	#CJK UNIFIED IDEOGRAPH
+0xBEDB	0x805A	#CJK UNIFIED IDEOGRAPH
+0xBEDC	0x62D2	#CJK UNIFIED IDEOGRAPH
+0xBEDD	0x636E	#CJK UNIFIED IDEOGRAPH
+0xBEDE	0x5DE8	#CJK UNIFIED IDEOGRAPH
+0xBEDF	0x5177	#CJK UNIFIED IDEOGRAPH
+0xBEE0	0x8DDD	#CJK UNIFIED IDEOGRAPH
+0xBEE1	0x8E1E	#CJK UNIFIED IDEOGRAPH
+0xBEE2	0x952F	#CJK UNIFIED IDEOGRAPH
+0xBEE3	0x4FF1	#CJK UNIFIED IDEOGRAPH
+0xBEE4	0x53E5	#CJK UNIFIED IDEOGRAPH
+0xBEE5	0x60E7	#CJK UNIFIED IDEOGRAPH
+0xBEE6	0x70AC	#CJK UNIFIED IDEOGRAPH
+0xBEE7	0x5267	#CJK UNIFIED IDEOGRAPH
+0xBEE8	0x6350	#CJK UNIFIED IDEOGRAPH
+0xBEE9	0x9E43	#CJK UNIFIED IDEOGRAPH
+0xBEEA	0x5A1F	#CJK UNIFIED IDEOGRAPH
+0xBEEB	0x5026	#CJK UNIFIED IDEOGRAPH
+0xBEEC	0x7737	#CJK UNIFIED IDEOGRAPH
+0xBEED	0x5377	#CJK UNIFIED IDEOGRAPH
+0xBEEE	0x7EE2	#CJK UNIFIED IDEOGRAPH
+0xBEEF	0x6485	#CJK UNIFIED IDEOGRAPH
+0xBEF0	0x652B	#CJK UNIFIED IDEOGRAPH
+0xBEF1	0x6289	#CJK UNIFIED IDEOGRAPH
+0xBEF2	0x6398	#CJK UNIFIED IDEOGRAPH
+0xBEF3	0x5014	#CJK UNIFIED IDEOGRAPH
+0xBEF4	0x7235	#CJK UNIFIED IDEOGRAPH
+0xBEF5	0x89C9	#CJK UNIFIED IDEOGRAPH
+0xBEF6	0x51B3	#CJK UNIFIED IDEOGRAPH
+0xBEF7	0x8BC0	#CJK UNIFIED IDEOGRAPH
+0xBEF8	0x7EDD	#CJK UNIFIED IDEOGRAPH
+0xBEF9	0x5747	#CJK UNIFIED IDEOGRAPH
+0xBEFA	0x83CC	#CJK UNIFIED IDEOGRAPH
+0xBEFB	0x94A7	#CJK UNIFIED IDEOGRAPH
+0xBEFC	0x519B	#CJK UNIFIED IDEOGRAPH
+0xBEFD	0x541B	#CJK UNIFIED IDEOGRAPH
+0xBEFE	0x5CFB	#CJK UNIFIED IDEOGRAPH
+0xBF40	0x7DFB	#CJK UNIFIED IDEOGRAPH
+0xBF41	0x7DFC	#CJK UNIFIED IDEOGRAPH
+0xBF42	0x7DFD	#CJK UNIFIED IDEOGRAPH
+0xBF43	0x7DFE	#CJK UNIFIED IDEOGRAPH
+0xBF44	0x7DFF	#CJK UNIFIED IDEOGRAPH
+0xBF45	0x7E00	#CJK UNIFIED IDEOGRAPH
+0xBF46	0x7E01	#CJK UNIFIED IDEOGRAPH
+0xBF47	0x7E02	#CJK UNIFIED IDEOGRAPH
+0xBF48	0x7E03	#CJK UNIFIED IDEOGRAPH
+0xBF49	0x7E04	#CJK UNIFIED IDEOGRAPH
+0xBF4A	0x7E05	#CJK UNIFIED IDEOGRAPH
+0xBF4B	0x7E06	#CJK UNIFIED IDEOGRAPH
+0xBF4C	0x7E07	#CJK UNIFIED IDEOGRAPH
+0xBF4D	0x7E08	#CJK UNIFIED IDEOGRAPH
+0xBF4E	0x7E09	#CJK UNIFIED IDEOGRAPH
+0xBF4F	0x7E0A	#CJK UNIFIED IDEOGRAPH
+0xBF50	0x7E0B	#CJK UNIFIED IDEOGRAPH
+0xBF51	0x7E0C	#CJK UNIFIED IDEOGRAPH
+0xBF52	0x7E0D	#CJK UNIFIED IDEOGRAPH
+0xBF53	0x7E0E	#CJK UNIFIED IDEOGRAPH
+0xBF54	0x7E0F	#CJK UNIFIED IDEOGRAPH
+0xBF55	0x7E10	#CJK UNIFIED IDEOGRAPH
+0xBF56	0x7E11	#CJK UNIFIED IDEOGRAPH
+0xBF57	0x7E12	#CJK UNIFIED IDEOGRAPH
+0xBF58	0x7E13	#CJK UNIFIED IDEOGRAPH
+0xBF59	0x7E14	#CJK UNIFIED IDEOGRAPH
+0xBF5A	0x7E15	#CJK UNIFIED IDEOGRAPH
+0xBF5B	0x7E16	#CJK UNIFIED IDEOGRAPH
+0xBF5C	0x7E17	#CJK UNIFIED IDEOGRAPH
+0xBF5D	0x7E18	#CJK UNIFIED IDEOGRAPH
+0xBF5E	0x7E19	#CJK UNIFIED IDEOGRAPH
+0xBF5F	0x7E1A	#CJK UNIFIED IDEOGRAPH
+0xBF60	0x7E1B	#CJK UNIFIED IDEOGRAPH
+0xBF61	0x7E1C	#CJK UNIFIED IDEOGRAPH
+0xBF62	0x7E1D	#CJK UNIFIED IDEOGRAPH
+0xBF63	0x7E1E	#CJK UNIFIED IDEOGRAPH
+0xBF64	0x7E1F	#CJK UNIFIED IDEOGRAPH
+0xBF65	0x7E20	#CJK UNIFIED IDEOGRAPH
+0xBF66	0x7E21	#CJK UNIFIED IDEOGRAPH
+0xBF67	0x7E22	#CJK UNIFIED IDEOGRAPH
+0xBF68	0x7E23	#CJK UNIFIED IDEOGRAPH
+0xBF69	0x7E24	#CJK UNIFIED IDEOGRAPH
+0xBF6A	0x7E25	#CJK UNIFIED IDEOGRAPH
+0xBF6B	0x7E26	#CJK UNIFIED IDEOGRAPH
+0xBF6C	0x7E27	#CJK UNIFIED IDEOGRAPH
+0xBF6D	0x7E28	#CJK UNIFIED IDEOGRAPH
+0xBF6E	0x7E29	#CJK UNIFIED IDEOGRAPH
+0xBF6F	0x7E2A	#CJK UNIFIED IDEOGRAPH
+0xBF70	0x7E2B	#CJK UNIFIED IDEOGRAPH
+0xBF71	0x7E2C	#CJK UNIFIED IDEOGRAPH
+0xBF72	0x7E2D	#CJK UNIFIED IDEOGRAPH
+0xBF73	0x7E2E	#CJK UNIFIED IDEOGRAPH
+0xBF74	0x7E2F	#CJK UNIFIED IDEOGRAPH
+0xBF75	0x7E30	#CJK UNIFIED IDEOGRAPH
+0xBF76	0x7E31	#CJK UNIFIED IDEOGRAPH
+0xBF77	0x7E32	#CJK UNIFIED IDEOGRAPH
+0xBF78	0x7E33	#CJK UNIFIED IDEOGRAPH
+0xBF79	0x7E34	#CJK UNIFIED IDEOGRAPH
+0xBF7A	0x7E35	#CJK UNIFIED IDEOGRAPH
+0xBF7B	0x7E36	#CJK UNIFIED IDEOGRAPH
+0xBF7C	0x7E37	#CJK UNIFIED IDEOGRAPH
+0xBF7D	0x7E38	#CJK UNIFIED IDEOGRAPH
+0xBF7E	0x7E39	#CJK UNIFIED IDEOGRAPH
+0xBF80	0x7E3A	#CJK UNIFIED IDEOGRAPH
+0xBF81	0x7E3C	#CJK UNIFIED IDEOGRAPH
+0xBF82	0x7E3D	#CJK UNIFIED IDEOGRAPH
+0xBF83	0x7E3E	#CJK UNIFIED IDEOGRAPH
+0xBF84	0x7E3F	#CJK UNIFIED IDEOGRAPH
+0xBF85	0x7E40	#CJK UNIFIED IDEOGRAPH
+0xBF86	0x7E42	#CJK UNIFIED IDEOGRAPH
+0xBF87	0x7E43	#CJK UNIFIED IDEOGRAPH
+0xBF88	0x7E44	#CJK UNIFIED IDEOGRAPH
+0xBF89	0x7E45	#CJK UNIFIED IDEOGRAPH
+0xBF8A	0x7E46	#CJK UNIFIED IDEOGRAPH
+0xBF8B	0x7E48	#CJK UNIFIED IDEOGRAPH
+0xBF8C	0x7E49	#CJK UNIFIED IDEOGRAPH
+0xBF8D	0x7E4A	#CJK UNIFIED IDEOGRAPH
+0xBF8E	0x7E4B	#CJK UNIFIED IDEOGRAPH
+0xBF8F	0x7E4C	#CJK UNIFIED IDEOGRAPH
+0xBF90	0x7E4D	#CJK UNIFIED IDEOGRAPH
+0xBF91	0x7E4E	#CJK UNIFIED IDEOGRAPH
+0xBF92	0x7E4F	#CJK UNIFIED IDEOGRAPH
+0xBF93	0x7E50	#CJK UNIFIED IDEOGRAPH
+0xBF94	0x7E51	#CJK UNIFIED IDEOGRAPH
+0xBF95	0x7E52	#CJK UNIFIED IDEOGRAPH
+0xBF96	0x7E53	#CJK UNIFIED IDEOGRAPH
+0xBF97	0x7E54	#CJK UNIFIED IDEOGRAPH
+0xBF98	0x7E55	#CJK UNIFIED IDEOGRAPH
+0xBF99	0x7E56	#CJK UNIFIED IDEOGRAPH
+0xBF9A	0x7E57	#CJK UNIFIED IDEOGRAPH
+0xBF9B	0x7E58	#CJK UNIFIED IDEOGRAPH
+0xBF9C	0x7E59	#CJK UNIFIED IDEOGRAPH
+0xBF9D	0x7E5A	#CJK UNIFIED IDEOGRAPH
+0xBF9E	0x7E5B	#CJK UNIFIED IDEOGRAPH
+0xBF9F	0x7E5C	#CJK UNIFIED IDEOGRAPH
+0xBFA0	0x7E5D	#CJK UNIFIED IDEOGRAPH
+0xBFA1	0x4FCA	#CJK UNIFIED IDEOGRAPH
+0xBFA2	0x7AE3	#CJK UNIFIED IDEOGRAPH
+0xBFA3	0x6D5A	#CJK UNIFIED IDEOGRAPH
+0xBFA4	0x90E1	#CJK UNIFIED IDEOGRAPH
+0xBFA5	0x9A8F	#CJK UNIFIED IDEOGRAPH
+0xBFA6	0x5580	#CJK UNIFIED IDEOGRAPH
+0xBFA7	0x5496	#CJK UNIFIED IDEOGRAPH
+0xBFA8	0x5361	#CJK UNIFIED IDEOGRAPH
+0xBFA9	0x54AF	#CJK UNIFIED IDEOGRAPH
+0xBFAA	0x5F00	#CJK UNIFIED IDEOGRAPH
+0xBFAB	0x63E9	#CJK UNIFIED IDEOGRAPH
+0xBFAC	0x6977	#CJK UNIFIED IDEOGRAPH
+0xBFAD	0x51EF	#CJK UNIFIED IDEOGRAPH
+0xBFAE	0x6168	#CJK UNIFIED IDEOGRAPH
+0xBFAF	0x520A	#CJK UNIFIED IDEOGRAPH
+0xBFB0	0x582A	#CJK UNIFIED IDEOGRAPH
+0xBFB1	0x52D8	#CJK UNIFIED IDEOGRAPH
+0xBFB2	0x574E	#CJK UNIFIED IDEOGRAPH
+0xBFB3	0x780D	#CJK UNIFIED IDEOGRAPH
+0xBFB4	0x770B	#CJK UNIFIED IDEOGRAPH
+0xBFB5	0x5EB7	#CJK UNIFIED IDEOGRAPH
+0xBFB6	0x6177	#CJK UNIFIED IDEOGRAPH
+0xBFB7	0x7CE0	#CJK UNIFIED IDEOGRAPH
+0xBFB8	0x625B	#CJK UNIFIED IDEOGRAPH
+0xBFB9	0x6297	#CJK UNIFIED IDEOGRAPH
+0xBFBA	0x4EA2	#CJK UNIFIED IDEOGRAPH
+0xBFBB	0x7095	#CJK UNIFIED IDEOGRAPH
+0xBFBC	0x8003	#CJK UNIFIED IDEOGRAPH
+0xBFBD	0x62F7	#CJK UNIFIED IDEOGRAPH
+0xBFBE	0x70E4	#CJK UNIFIED IDEOGRAPH
+0xBFBF	0x9760	#CJK UNIFIED IDEOGRAPH
+0xBFC0	0x5777	#CJK UNIFIED IDEOGRAPH
+0xBFC1	0x82DB	#CJK UNIFIED IDEOGRAPH
+0xBFC2	0x67EF	#CJK UNIFIED IDEOGRAPH
+0xBFC3	0x68F5	#CJK UNIFIED IDEOGRAPH
+0xBFC4	0x78D5	#CJK UNIFIED IDEOGRAPH
+0xBFC5	0x9897	#CJK UNIFIED IDEOGRAPH
+0xBFC6	0x79D1	#CJK UNIFIED IDEOGRAPH
+0xBFC7	0x58F3	#CJK UNIFIED IDEOGRAPH
+0xBFC8	0x54B3	#CJK UNIFIED IDEOGRAPH
+0xBFC9	0x53EF	#CJK UNIFIED IDEOGRAPH
+0xBFCA	0x6E34	#CJK UNIFIED IDEOGRAPH
+0xBFCB	0x514B	#CJK UNIFIED IDEOGRAPH
+0xBFCC	0x523B	#CJK UNIFIED IDEOGRAPH
+0xBFCD	0x5BA2	#CJK UNIFIED IDEOGRAPH
+0xBFCE	0x8BFE	#CJK UNIFIED IDEOGRAPH
+0xBFCF	0x80AF	#CJK UNIFIED IDEOGRAPH
+0xBFD0	0x5543	#CJK UNIFIED IDEOGRAPH
+0xBFD1	0x57A6	#CJK UNIFIED IDEOGRAPH
+0xBFD2	0x6073	#CJK UNIFIED IDEOGRAPH
+0xBFD3	0x5751	#CJK UNIFIED IDEOGRAPH
+0xBFD4	0x542D	#CJK UNIFIED IDEOGRAPH
+0xBFD5	0x7A7A	#CJK UNIFIED IDEOGRAPH
+0xBFD6	0x6050	#CJK UNIFIED IDEOGRAPH
+0xBFD7	0x5B54	#CJK UNIFIED IDEOGRAPH
+0xBFD8	0x63A7	#CJK UNIFIED IDEOGRAPH
+0xBFD9	0x62A0	#CJK UNIFIED IDEOGRAPH
+0xBFDA	0x53E3	#CJK UNIFIED IDEOGRAPH
+0xBFDB	0x6263	#CJK UNIFIED IDEOGRAPH
+0xBFDC	0x5BC7	#CJK UNIFIED IDEOGRAPH
+0xBFDD	0x67AF	#CJK UNIFIED IDEOGRAPH
+0xBFDE	0x54ED	#CJK UNIFIED IDEOGRAPH
+0xBFDF	0x7A9F	#CJK UNIFIED IDEOGRAPH
+0xBFE0	0x82E6	#CJK UNIFIED IDEOGRAPH
+0xBFE1	0x9177	#CJK UNIFIED IDEOGRAPH
+0xBFE2	0x5E93	#CJK UNIFIED IDEOGRAPH
+0xBFE3	0x88E4	#CJK UNIFIED IDEOGRAPH
+0xBFE4	0x5938	#CJK UNIFIED IDEOGRAPH
+0xBFE5	0x57AE	#CJK UNIFIED IDEOGRAPH
+0xBFE6	0x630E	#CJK UNIFIED IDEOGRAPH
+0xBFE7	0x8DE8	#CJK UNIFIED IDEOGRAPH
+0xBFE8	0x80EF	#CJK UNIFIED IDEOGRAPH
+0xBFE9	0x5757	#CJK UNIFIED IDEOGRAPH
+0xBFEA	0x7B77	#CJK UNIFIED IDEOGRAPH
+0xBFEB	0x4FA9	#CJK UNIFIED IDEOGRAPH
+0xBFEC	0x5FEB	#CJK UNIFIED IDEOGRAPH
+0xBFED	0x5BBD	#CJK UNIFIED IDEOGRAPH
+0xBFEE	0x6B3E	#CJK UNIFIED IDEOGRAPH
+0xBFEF	0x5321	#CJK UNIFIED IDEOGRAPH
+0xBFF0	0x7B50	#CJK UNIFIED IDEOGRAPH
+0xBFF1	0x72C2	#CJK UNIFIED IDEOGRAPH
+0xBFF2	0x6846	#CJK UNIFIED IDEOGRAPH
+0xBFF3	0x77FF	#CJK UNIFIED IDEOGRAPH
+0xBFF4	0x7736	#CJK UNIFIED IDEOGRAPH
+0xBFF5	0x65F7	#CJK UNIFIED IDEOGRAPH
+0xBFF6	0x51B5	#CJK UNIFIED IDEOGRAPH
+0xBFF7	0x4E8F	#CJK UNIFIED IDEOGRAPH
+0xBFF8	0x76D4	#CJK UNIFIED IDEOGRAPH
+0xBFF9	0x5CBF	#CJK UNIFIED IDEOGRAPH
+0xBFFA	0x7AA5	#CJK UNIFIED IDEOGRAPH
+0xBFFB	0x8475	#CJK UNIFIED IDEOGRAPH
+0xBFFC	0x594E	#CJK UNIFIED IDEOGRAPH
+0xBFFD	0x9B41	#CJK UNIFIED IDEOGRAPH
+0xBFFE	0x5080	#CJK UNIFIED IDEOGRAPH
+0xC040	0x7E5E	#CJK UNIFIED IDEOGRAPH
+0xC041	0x7E5F	#CJK UNIFIED IDEOGRAPH
+0xC042	0x7E60	#CJK UNIFIED IDEOGRAPH
+0xC043	0x7E61	#CJK UNIFIED IDEOGRAPH
+0xC044	0x7E62	#CJK UNIFIED IDEOGRAPH
+0xC045	0x7E63	#CJK UNIFIED IDEOGRAPH
+0xC046	0x7E64	#CJK UNIFIED IDEOGRAPH
+0xC047	0x7E65	#CJK UNIFIED IDEOGRAPH
+0xC048	0x7E66	#CJK UNIFIED IDEOGRAPH
+0xC049	0x7E67	#CJK UNIFIED IDEOGRAPH
+0xC04A	0x7E68	#CJK UNIFIED IDEOGRAPH
+0xC04B	0x7E69	#CJK UNIFIED IDEOGRAPH
+0xC04C	0x7E6A	#CJK UNIFIED IDEOGRAPH
+0xC04D	0x7E6B	#CJK UNIFIED IDEOGRAPH
+0xC04E	0x7E6C	#CJK UNIFIED IDEOGRAPH
+0xC04F	0x7E6D	#CJK UNIFIED IDEOGRAPH
+0xC050	0x7E6E	#CJK UNIFIED IDEOGRAPH
+0xC051	0x7E6F	#CJK UNIFIED IDEOGRAPH
+0xC052	0x7E70	#CJK UNIFIED IDEOGRAPH
+0xC053	0x7E71	#CJK UNIFIED IDEOGRAPH
+0xC054	0x7E72	#CJK UNIFIED IDEOGRAPH
+0xC055	0x7E73	#CJK UNIFIED IDEOGRAPH
+0xC056	0x7E74	#CJK UNIFIED IDEOGRAPH
+0xC057	0x7E75	#CJK UNIFIED IDEOGRAPH
+0xC058	0x7E76	#CJK UNIFIED IDEOGRAPH
+0xC059	0x7E77	#CJK UNIFIED IDEOGRAPH
+0xC05A	0x7E78	#CJK UNIFIED IDEOGRAPH
+0xC05B	0x7E79	#CJK UNIFIED IDEOGRAPH
+0xC05C	0x7E7A	#CJK UNIFIED IDEOGRAPH
+0xC05D	0x7E7B	#CJK UNIFIED IDEOGRAPH
+0xC05E	0x7E7C	#CJK UNIFIED IDEOGRAPH
+0xC05F	0x7E7D	#CJK UNIFIED IDEOGRAPH
+0xC060	0x7E7E	#CJK UNIFIED IDEOGRAPH
+0xC061	0x7E7F	#CJK UNIFIED IDEOGRAPH
+0xC062	0x7E80	#CJK UNIFIED IDEOGRAPH
+0xC063	0x7E81	#CJK UNIFIED IDEOGRAPH
+0xC064	0x7E83	#CJK UNIFIED IDEOGRAPH
+0xC065	0x7E84	#CJK UNIFIED IDEOGRAPH
+0xC066	0x7E85	#CJK UNIFIED IDEOGRAPH
+0xC067	0x7E86	#CJK UNIFIED IDEOGRAPH
+0xC068	0x7E87	#CJK UNIFIED IDEOGRAPH
+0xC069	0x7E88	#CJK UNIFIED IDEOGRAPH
+0xC06A	0x7E89	#CJK UNIFIED IDEOGRAPH
+0xC06B	0x7E8A	#CJK UNIFIED IDEOGRAPH
+0xC06C	0x7E8B	#CJK UNIFIED IDEOGRAPH
+0xC06D	0x7E8C	#CJK UNIFIED IDEOGRAPH
+0xC06E	0x7E8D	#CJK UNIFIED IDEOGRAPH
+0xC06F	0x7E8E	#CJK UNIFIED IDEOGRAPH
+0xC070	0x7E8F	#CJK UNIFIED IDEOGRAPH
+0xC071	0x7E90	#CJK UNIFIED IDEOGRAPH
+0xC072	0x7E91	#CJK UNIFIED IDEOGRAPH
+0xC073	0x7E92	#CJK UNIFIED IDEOGRAPH
+0xC074	0x7E93	#CJK UNIFIED IDEOGRAPH
+0xC075	0x7E94	#CJK UNIFIED IDEOGRAPH
+0xC076	0x7E95	#CJK UNIFIED IDEOGRAPH
+0xC077	0x7E96	#CJK UNIFIED IDEOGRAPH
+0xC078	0x7E97	#CJK UNIFIED IDEOGRAPH
+0xC079	0x7E98	#CJK UNIFIED IDEOGRAPH
+0xC07A	0x7E99	#CJK UNIFIED IDEOGRAPH
+0xC07B	0x7E9A	#CJK UNIFIED IDEOGRAPH
+0xC07C	0x7E9C	#CJK UNIFIED IDEOGRAPH
+0xC07D	0x7E9D	#CJK UNIFIED IDEOGRAPH
+0xC07E	0x7E9E	#CJK UNIFIED IDEOGRAPH
+0xC080	0x7EAE	#CJK UNIFIED IDEOGRAPH
+0xC081	0x7EB4	#CJK UNIFIED IDEOGRAPH
+0xC082	0x7EBB	#CJK UNIFIED IDEOGRAPH
+0xC083	0x7EBC	#CJK UNIFIED IDEOGRAPH
+0xC084	0x7ED6	#CJK UNIFIED IDEOGRAPH
+0xC085	0x7EE4	#CJK UNIFIED IDEOGRAPH
+0xC086	0x7EEC	#CJK UNIFIED IDEOGRAPH
+0xC087	0x7EF9	#CJK UNIFIED IDEOGRAPH
+0xC088	0x7F0A	#CJK UNIFIED IDEOGRAPH
+0xC089	0x7F10	#CJK UNIFIED IDEOGRAPH
+0xC08A	0x7F1E	#CJK UNIFIED IDEOGRAPH
+0xC08B	0x7F37	#CJK UNIFIED IDEOGRAPH
+0xC08C	0x7F39	#CJK UNIFIED IDEOGRAPH
+0xC08D	0x7F3B	#CJK UNIFIED IDEOGRAPH
+0xC08E	0x7F3C	#CJK UNIFIED IDEOGRAPH
+0xC08F	0x7F3D	#CJK UNIFIED IDEOGRAPH
+0xC090	0x7F3E	#CJK UNIFIED IDEOGRAPH
+0xC091	0x7F3F	#CJK UNIFIED IDEOGRAPH
+0xC092	0x7F40	#CJK UNIFIED IDEOGRAPH
+0xC093	0x7F41	#CJK UNIFIED IDEOGRAPH
+0xC094	0x7F43	#CJK UNIFIED IDEOGRAPH
+0xC095	0x7F46	#CJK UNIFIED IDEOGRAPH
+0xC096	0x7F47	#CJK UNIFIED IDEOGRAPH
+0xC097	0x7F48	#CJK UNIFIED IDEOGRAPH
+0xC098	0x7F49	#CJK UNIFIED IDEOGRAPH
+0xC099	0x7F4A	#CJK UNIFIED IDEOGRAPH
+0xC09A	0x7F4B	#CJK UNIFIED IDEOGRAPH
+0xC09B	0x7F4C	#CJK UNIFIED IDEOGRAPH
+0xC09C	0x7F4D	#CJK UNIFIED IDEOGRAPH
+0xC09D	0x7F4E	#CJK UNIFIED IDEOGRAPH
+0xC09E	0x7F4F	#CJK UNIFIED IDEOGRAPH
+0xC09F	0x7F52	#CJK UNIFIED IDEOGRAPH
+0xC0A0	0x7F53	#CJK UNIFIED IDEOGRAPH
+0xC0A1	0x9988	#CJK UNIFIED IDEOGRAPH
+0xC0A2	0x6127	#CJK UNIFIED IDEOGRAPH
+0xC0A3	0x6E83	#CJK UNIFIED IDEOGRAPH
+0xC0A4	0x5764	#CJK UNIFIED IDEOGRAPH
+0xC0A5	0x6606	#CJK UNIFIED IDEOGRAPH
+0xC0A6	0x6346	#CJK UNIFIED IDEOGRAPH
+0xC0A7	0x56F0	#CJK UNIFIED IDEOGRAPH
+0xC0A8	0x62EC	#CJK UNIFIED IDEOGRAPH
+0xC0A9	0x6269	#CJK UNIFIED IDEOGRAPH
+0xC0AA	0x5ED3	#CJK UNIFIED IDEOGRAPH
+0xC0AB	0x9614	#CJK UNIFIED IDEOGRAPH
+0xC0AC	0x5783	#CJK UNIFIED IDEOGRAPH
+0xC0AD	0x62C9	#CJK UNIFIED IDEOGRAPH
+0xC0AE	0x5587	#CJK UNIFIED IDEOGRAPH
+0xC0AF	0x8721	#CJK UNIFIED IDEOGRAPH
+0xC0B0	0x814A	#CJK UNIFIED IDEOGRAPH
+0xC0B1	0x8FA3	#CJK UNIFIED IDEOGRAPH
+0xC0B2	0x5566	#CJK UNIFIED IDEOGRAPH
+0xC0B3	0x83B1	#CJK UNIFIED IDEOGRAPH
+0xC0B4	0x6765	#CJK UNIFIED IDEOGRAPH
+0xC0B5	0x8D56	#CJK UNIFIED IDEOGRAPH
+0xC0B6	0x84DD	#CJK UNIFIED IDEOGRAPH
+0xC0B7	0x5A6A	#CJK UNIFIED IDEOGRAPH
+0xC0B8	0x680F	#CJK UNIFIED IDEOGRAPH
+0xC0B9	0x62E6	#CJK UNIFIED IDEOGRAPH
+0xC0BA	0x7BEE	#CJK UNIFIED IDEOGRAPH
+0xC0BB	0x9611	#CJK UNIFIED IDEOGRAPH
+0xC0BC	0x5170	#CJK UNIFIED IDEOGRAPH
+0xC0BD	0x6F9C	#CJK UNIFIED IDEOGRAPH
+0xC0BE	0x8C30	#CJK UNIFIED IDEOGRAPH
+0xC0BF	0x63FD	#CJK UNIFIED IDEOGRAPH
+0xC0C0	0x89C8	#CJK UNIFIED IDEOGRAPH
+0xC0C1	0x61D2	#CJK UNIFIED IDEOGRAPH
+0xC0C2	0x7F06	#CJK UNIFIED IDEOGRAPH
+0xC0C3	0x70C2	#CJK UNIFIED IDEOGRAPH
+0xC0C4	0x6EE5	#CJK UNIFIED IDEOGRAPH
+0xC0C5	0x7405	#CJK UNIFIED IDEOGRAPH
+0xC0C6	0x6994	#CJK UNIFIED IDEOGRAPH
+0xC0C7	0x72FC	#CJK UNIFIED IDEOGRAPH
+0xC0C8	0x5ECA	#CJK UNIFIED IDEOGRAPH
+0xC0C9	0x90CE	#CJK UNIFIED IDEOGRAPH
+0xC0CA	0x6717	#CJK UNIFIED IDEOGRAPH
+0xC0CB	0x6D6A	#CJK UNIFIED IDEOGRAPH
+0xC0CC	0x635E	#CJK UNIFIED IDEOGRAPH
+0xC0CD	0x52B3	#CJK UNIFIED IDEOGRAPH
+0xC0CE	0x7262	#CJK UNIFIED IDEOGRAPH
+0xC0CF	0x8001	#CJK UNIFIED IDEOGRAPH
+0xC0D0	0x4F6C	#CJK UNIFIED IDEOGRAPH
+0xC0D1	0x59E5	#CJK UNIFIED IDEOGRAPH
+0xC0D2	0x916A	#CJK UNIFIED IDEOGRAPH
+0xC0D3	0x70D9	#CJK UNIFIED IDEOGRAPH
+0xC0D4	0x6D9D	#CJK UNIFIED IDEOGRAPH
+0xC0D5	0x52D2	#CJK UNIFIED IDEOGRAPH
+0xC0D6	0x4E50	#CJK UNIFIED IDEOGRAPH
+0xC0D7	0x96F7	#CJK UNIFIED IDEOGRAPH
+0xC0D8	0x956D	#CJK UNIFIED IDEOGRAPH
+0xC0D9	0x857E	#CJK UNIFIED IDEOGRAPH
+0xC0DA	0x78CA	#CJK UNIFIED IDEOGRAPH
+0xC0DB	0x7D2F	#CJK UNIFIED IDEOGRAPH
+0xC0DC	0x5121	#CJK UNIFIED IDEOGRAPH
+0xC0DD	0x5792	#CJK UNIFIED IDEOGRAPH
+0xC0DE	0x64C2	#CJK UNIFIED IDEOGRAPH
+0xC0DF	0x808B	#CJK UNIFIED IDEOGRAPH
+0xC0E0	0x7C7B	#CJK UNIFIED IDEOGRAPH
+0xC0E1	0x6CEA	#CJK UNIFIED IDEOGRAPH
+0xC0E2	0x68F1	#CJK UNIFIED IDEOGRAPH
+0xC0E3	0x695E	#CJK UNIFIED IDEOGRAPH
+0xC0E4	0x51B7	#CJK UNIFIED IDEOGRAPH
+0xC0E5	0x5398	#CJK UNIFIED IDEOGRAPH
+0xC0E6	0x68A8	#CJK UNIFIED IDEOGRAPH
+0xC0E7	0x7281	#CJK UNIFIED IDEOGRAPH
+0xC0E8	0x9ECE	#CJK UNIFIED IDEOGRAPH
+0xC0E9	0x7BF1	#CJK UNIFIED IDEOGRAPH
+0xC0EA	0x72F8	#CJK UNIFIED IDEOGRAPH
+0xC0EB	0x79BB	#CJK UNIFIED IDEOGRAPH
+0xC0EC	0x6F13	#CJK UNIFIED IDEOGRAPH
+0xC0ED	0x7406	#CJK UNIFIED IDEOGRAPH
+0xC0EE	0x674E	#CJK UNIFIED IDEOGRAPH
+0xC0EF	0x91CC	#CJK UNIFIED IDEOGRAPH
+0xC0F0	0x9CA4	#CJK UNIFIED IDEOGRAPH
+0xC0F1	0x793C	#CJK UNIFIED IDEOGRAPH
+0xC0F2	0x8389	#CJK UNIFIED IDEOGRAPH
+0xC0F3	0x8354	#CJK UNIFIED IDEOGRAPH
+0xC0F4	0x540F	#CJK UNIFIED IDEOGRAPH
+0xC0F5	0x6817	#CJK UNIFIED IDEOGRAPH
+0xC0F6	0x4E3D	#CJK UNIFIED IDEOGRAPH
+0xC0F7	0x5389	#CJK UNIFIED IDEOGRAPH
+0xC0F8	0x52B1	#CJK UNIFIED IDEOGRAPH
+0xC0F9	0x783E	#CJK UNIFIED IDEOGRAPH
+0xC0FA	0x5386	#CJK UNIFIED IDEOGRAPH
+0xC0FB	0x5229	#CJK UNIFIED IDEOGRAPH
+0xC0FC	0x5088	#CJK UNIFIED IDEOGRAPH
+0xC0FD	0x4F8B	#CJK UNIFIED IDEOGRAPH
+0xC0FE	0x4FD0	#CJK UNIFIED IDEOGRAPH
+0xC140	0x7F56	#CJK UNIFIED IDEOGRAPH
+0xC141	0x7F59	#CJK UNIFIED IDEOGRAPH
+0xC142	0x7F5B	#CJK UNIFIED IDEOGRAPH
+0xC143	0x7F5C	#CJK UNIFIED IDEOGRAPH
+0xC144	0x7F5D	#CJK UNIFIED IDEOGRAPH
+0xC145	0x7F5E	#CJK UNIFIED IDEOGRAPH
+0xC146	0x7F60	#CJK UNIFIED IDEOGRAPH
+0xC147	0x7F63	#CJK UNIFIED IDEOGRAPH
+0xC148	0x7F64	#CJK UNIFIED IDEOGRAPH
+0xC149	0x7F65	#CJK UNIFIED IDEOGRAPH
+0xC14A	0x7F66	#CJK UNIFIED IDEOGRAPH
+0xC14B	0x7F67	#CJK UNIFIED IDEOGRAPH
+0xC14C	0x7F6B	#CJK UNIFIED IDEOGRAPH
+0xC14D	0x7F6C	#CJK UNIFIED IDEOGRAPH
+0xC14E	0x7F6D	#CJK UNIFIED IDEOGRAPH
+0xC14F	0x7F6F	#CJK UNIFIED IDEOGRAPH
+0xC150	0x7F70	#CJK UNIFIED IDEOGRAPH
+0xC151	0x7F73	#CJK UNIFIED IDEOGRAPH
+0xC152	0x7F75	#CJK UNIFIED IDEOGRAPH
+0xC153	0x7F76	#CJK UNIFIED IDEOGRAPH
+0xC154	0x7F77	#CJK UNIFIED IDEOGRAPH
+0xC155	0x7F78	#CJK UNIFIED IDEOGRAPH
+0xC156	0x7F7A	#CJK UNIFIED IDEOGRAPH
+0xC157	0x7F7B	#CJK UNIFIED IDEOGRAPH
+0xC158	0x7F7C	#CJK UNIFIED IDEOGRAPH
+0xC159	0x7F7D	#CJK UNIFIED IDEOGRAPH
+0xC15A	0x7F7F	#CJK UNIFIED IDEOGRAPH
+0xC15B	0x7F80	#CJK UNIFIED IDEOGRAPH
+0xC15C	0x7F82	#CJK UNIFIED IDEOGRAPH
+0xC15D	0x7F83	#CJK UNIFIED IDEOGRAPH
+0xC15E	0x7F84	#CJK UNIFIED IDEOGRAPH
+0xC15F	0x7F85	#CJK UNIFIED IDEOGRAPH
+0xC160	0x7F86	#CJK UNIFIED IDEOGRAPH
+0xC161	0x7F87	#CJK UNIFIED IDEOGRAPH
+0xC162	0x7F88	#CJK UNIFIED IDEOGRAPH
+0xC163	0x7F89	#CJK UNIFIED IDEOGRAPH
+0xC164	0x7F8B	#CJK UNIFIED IDEOGRAPH
+0xC165	0x7F8D	#CJK UNIFIED IDEOGRAPH
+0xC166	0x7F8F	#CJK UNIFIED IDEOGRAPH
+0xC167	0x7F90	#CJK UNIFIED IDEOGRAPH
+0xC168	0x7F91	#CJK UNIFIED IDEOGRAPH
+0xC169	0x7F92	#CJK UNIFIED IDEOGRAPH
+0xC16A	0x7F93	#CJK UNIFIED IDEOGRAPH
+0xC16B	0x7F95	#CJK UNIFIED IDEOGRAPH
+0xC16C	0x7F96	#CJK UNIFIED IDEOGRAPH
+0xC16D	0x7F97	#CJK UNIFIED IDEOGRAPH
+0xC16E	0x7F98	#CJK UNIFIED IDEOGRAPH
+0xC16F	0x7F99	#CJK UNIFIED IDEOGRAPH
+0xC170	0x7F9B	#CJK UNIFIED IDEOGRAPH
+0xC171	0x7F9C	#CJK UNIFIED IDEOGRAPH
+0xC172	0x7FA0	#CJK UNIFIED IDEOGRAPH
+0xC173	0x7FA2	#CJK UNIFIED IDEOGRAPH
+0xC174	0x7FA3	#CJK UNIFIED IDEOGRAPH
+0xC175	0x7FA5	#CJK UNIFIED IDEOGRAPH
+0xC176	0x7FA6	#CJK UNIFIED IDEOGRAPH
+0xC177	0x7FA8	#CJK UNIFIED IDEOGRAPH
+0xC178	0x7FA9	#CJK UNIFIED IDEOGRAPH
+0xC179	0x7FAA	#CJK UNIFIED IDEOGRAPH
+0xC17A	0x7FAB	#CJK UNIFIED IDEOGRAPH
+0xC17B	0x7FAC	#CJK UNIFIED IDEOGRAPH
+0xC17C	0x7FAD	#CJK UNIFIED IDEOGRAPH
+0xC17D	0x7FAE	#CJK UNIFIED IDEOGRAPH
+0xC17E	0x7FB1	#CJK UNIFIED IDEOGRAPH
+0xC180	0x7FB3	#CJK UNIFIED IDEOGRAPH
+0xC181	0x7FB4	#CJK UNIFIED IDEOGRAPH
+0xC182	0x7FB5	#CJK UNIFIED IDEOGRAPH
+0xC183	0x7FB6	#CJK UNIFIED IDEOGRAPH
+0xC184	0x7FB7	#CJK UNIFIED IDEOGRAPH
+0xC185	0x7FBA	#CJK UNIFIED IDEOGRAPH
+0xC186	0x7FBB	#CJK UNIFIED IDEOGRAPH
+0xC187	0x7FBE	#CJK UNIFIED IDEOGRAPH
+0xC188	0x7FC0	#CJK UNIFIED IDEOGRAPH
+0xC189	0x7FC2	#CJK UNIFIED IDEOGRAPH
+0xC18A	0x7FC3	#CJK UNIFIED IDEOGRAPH
+0xC18B	0x7FC4	#CJK UNIFIED IDEOGRAPH
+0xC18C	0x7FC6	#CJK UNIFIED IDEOGRAPH
+0xC18D	0x7FC7	#CJK UNIFIED IDEOGRAPH
+0xC18E	0x7FC8	#CJK UNIFIED IDEOGRAPH
+0xC18F	0x7FC9	#CJK UNIFIED IDEOGRAPH
+0xC190	0x7FCB	#CJK UNIFIED IDEOGRAPH
+0xC191	0x7FCD	#CJK UNIFIED IDEOGRAPH
+0xC192	0x7FCF	#CJK UNIFIED IDEOGRAPH
+0xC193	0x7FD0	#CJK UNIFIED IDEOGRAPH
+0xC194	0x7FD1	#CJK UNIFIED IDEOGRAPH
+0xC195	0x7FD2	#CJK UNIFIED IDEOGRAPH
+0xC196	0x7FD3	#CJK UNIFIED IDEOGRAPH
+0xC197	0x7FD6	#CJK UNIFIED IDEOGRAPH
+0xC198	0x7FD7	#CJK UNIFIED IDEOGRAPH
+0xC199	0x7FD9	#CJK UNIFIED IDEOGRAPH
+0xC19A	0x7FDA	#CJK UNIFIED IDEOGRAPH
+0xC19B	0x7FDB	#CJK UNIFIED IDEOGRAPH
+0xC19C	0x7FDC	#CJK UNIFIED IDEOGRAPH
+0xC19D	0x7FDD	#CJK UNIFIED IDEOGRAPH
+0xC19E	0x7FDE	#CJK UNIFIED IDEOGRAPH
+0xC19F	0x7FE2	#CJK UNIFIED IDEOGRAPH
+0xC1A0	0x7FE3	#CJK UNIFIED IDEOGRAPH
+0xC1A1	0x75E2	#CJK UNIFIED IDEOGRAPH
+0xC1A2	0x7ACB	#CJK UNIFIED IDEOGRAPH
+0xC1A3	0x7C92	#CJK UNIFIED IDEOGRAPH
+0xC1A4	0x6CA5	#CJK UNIFIED IDEOGRAPH
+0xC1A5	0x96B6	#CJK UNIFIED IDEOGRAPH
+0xC1A6	0x529B	#CJK UNIFIED IDEOGRAPH
+0xC1A7	0x7483	#CJK UNIFIED IDEOGRAPH
+0xC1A8	0x54E9	#CJK UNIFIED IDEOGRAPH
+0xC1A9	0x4FE9	#CJK UNIFIED IDEOGRAPH
+0xC1AA	0x8054	#CJK UNIFIED IDEOGRAPH
+0xC1AB	0x83B2	#CJK UNIFIED IDEOGRAPH
+0xC1AC	0x8FDE	#CJK UNIFIED IDEOGRAPH
+0xC1AD	0x9570	#CJK UNIFIED IDEOGRAPH
+0xC1AE	0x5EC9	#CJK UNIFIED IDEOGRAPH
+0xC1AF	0x601C	#CJK UNIFIED IDEOGRAPH
+0xC1B0	0x6D9F	#CJK UNIFIED IDEOGRAPH
+0xC1B1	0x5E18	#CJK UNIFIED IDEOGRAPH
+0xC1B2	0x655B	#CJK UNIFIED IDEOGRAPH
+0xC1B3	0x8138	#CJK UNIFIED IDEOGRAPH
+0xC1B4	0x94FE	#CJK UNIFIED IDEOGRAPH
+0xC1B5	0x604B	#CJK UNIFIED IDEOGRAPH
+0xC1B6	0x70BC	#CJK UNIFIED IDEOGRAPH
+0xC1B7	0x7EC3	#CJK UNIFIED IDEOGRAPH
+0xC1B8	0x7CAE	#CJK UNIFIED IDEOGRAPH
+0xC1B9	0x51C9	#CJK UNIFIED IDEOGRAPH
+0xC1BA	0x6881	#CJK UNIFIED IDEOGRAPH
+0xC1BB	0x7CB1	#CJK UNIFIED IDEOGRAPH
+0xC1BC	0x826F	#CJK UNIFIED IDEOGRAPH
+0xC1BD	0x4E24	#CJK UNIFIED IDEOGRAPH
+0xC1BE	0x8F86	#CJK UNIFIED IDEOGRAPH
+0xC1BF	0x91CF	#CJK UNIFIED IDEOGRAPH
+0xC1C0	0x667E	#CJK UNIFIED IDEOGRAPH
+0xC1C1	0x4EAE	#CJK UNIFIED IDEOGRAPH
+0xC1C2	0x8C05	#CJK UNIFIED IDEOGRAPH
+0xC1C3	0x64A9	#CJK UNIFIED IDEOGRAPH
+0xC1C4	0x804A	#CJK UNIFIED IDEOGRAPH
+0xC1C5	0x50DA	#CJK UNIFIED IDEOGRAPH
+0xC1C6	0x7597	#CJK UNIFIED IDEOGRAPH
+0xC1C7	0x71CE	#CJK UNIFIED IDEOGRAPH
+0xC1C8	0x5BE5	#CJK UNIFIED IDEOGRAPH
+0xC1C9	0x8FBD	#CJK UNIFIED IDEOGRAPH
+0xC1CA	0x6F66	#CJK UNIFIED IDEOGRAPH
+0xC1CB	0x4E86	#CJK UNIFIED IDEOGRAPH
+0xC1CC	0x6482	#CJK UNIFIED IDEOGRAPH
+0xC1CD	0x9563	#CJK UNIFIED IDEOGRAPH
+0xC1CE	0x5ED6	#CJK UNIFIED IDEOGRAPH
+0xC1CF	0x6599	#CJK UNIFIED IDEOGRAPH
+0xC1D0	0x5217	#CJK UNIFIED IDEOGRAPH
+0xC1D1	0x88C2	#CJK UNIFIED IDEOGRAPH
+0xC1D2	0x70C8	#CJK UNIFIED IDEOGRAPH
+0xC1D3	0x52A3	#CJK UNIFIED IDEOGRAPH
+0xC1D4	0x730E	#CJK UNIFIED IDEOGRAPH
+0xC1D5	0x7433	#CJK UNIFIED IDEOGRAPH
+0xC1D6	0x6797	#CJK UNIFIED IDEOGRAPH
+0xC1D7	0x78F7	#CJK UNIFIED IDEOGRAPH
+0xC1D8	0x9716	#CJK UNIFIED IDEOGRAPH
+0xC1D9	0x4E34	#CJK UNIFIED IDEOGRAPH
+0xC1DA	0x90BB	#CJK UNIFIED IDEOGRAPH
+0xC1DB	0x9CDE	#CJK UNIFIED IDEOGRAPH
+0xC1DC	0x6DCB	#CJK UNIFIED IDEOGRAPH
+0xC1DD	0x51DB	#CJK UNIFIED IDEOGRAPH
+0xC1DE	0x8D41	#CJK UNIFIED IDEOGRAPH
+0xC1DF	0x541D	#CJK UNIFIED IDEOGRAPH
+0xC1E0	0x62CE	#CJK UNIFIED IDEOGRAPH
+0xC1E1	0x73B2	#CJK UNIFIED IDEOGRAPH
+0xC1E2	0x83F1	#CJK UNIFIED IDEOGRAPH
+0xC1E3	0x96F6	#CJK UNIFIED IDEOGRAPH
+0xC1E4	0x9F84	#CJK UNIFIED IDEOGRAPH
+0xC1E5	0x94C3	#CJK UNIFIED IDEOGRAPH
+0xC1E6	0x4F36	#CJK UNIFIED IDEOGRAPH
+0xC1E7	0x7F9A	#CJK UNIFIED IDEOGRAPH
+0xC1E8	0x51CC	#CJK UNIFIED IDEOGRAPH
+0xC1E9	0x7075	#CJK UNIFIED IDEOGRAPH
+0xC1EA	0x9675	#CJK UNIFIED IDEOGRAPH
+0xC1EB	0x5CAD	#CJK UNIFIED IDEOGRAPH
+0xC1EC	0x9886	#CJK UNIFIED IDEOGRAPH
+0xC1ED	0x53E6	#CJK UNIFIED IDEOGRAPH
+0xC1EE	0x4EE4	#CJK UNIFIED IDEOGRAPH
+0xC1EF	0x6E9C	#CJK UNIFIED IDEOGRAPH
+0xC1F0	0x7409	#CJK UNIFIED IDEOGRAPH
+0xC1F1	0x69B4	#CJK UNIFIED IDEOGRAPH
+0xC1F2	0x786B	#CJK UNIFIED IDEOGRAPH
+0xC1F3	0x998F	#CJK UNIFIED IDEOGRAPH
+0xC1F4	0x7559	#CJK UNIFIED IDEOGRAPH
+0xC1F5	0x5218	#CJK UNIFIED IDEOGRAPH
+0xC1F6	0x7624	#CJK UNIFIED IDEOGRAPH
+0xC1F7	0x6D41	#CJK UNIFIED IDEOGRAPH
+0xC1F8	0x67F3	#CJK UNIFIED IDEOGRAPH
+0xC1F9	0x516D	#CJK UNIFIED IDEOGRAPH
+0xC1FA	0x9F99	#CJK UNIFIED IDEOGRAPH
+0xC1FB	0x804B	#CJK UNIFIED IDEOGRAPH
+0xC1FC	0x5499	#CJK UNIFIED IDEOGRAPH
+0xC1FD	0x7B3C	#CJK UNIFIED IDEOGRAPH
+0xC1FE	0x7ABF	#CJK UNIFIED IDEOGRAPH
+0xC240	0x7FE4	#CJK UNIFIED IDEOGRAPH
+0xC241	0x7FE7	#CJK UNIFIED IDEOGRAPH
+0xC242	0x7FE8	#CJK UNIFIED IDEOGRAPH
+0xC243	0x7FEA	#CJK UNIFIED IDEOGRAPH
+0xC244	0x7FEB	#CJK UNIFIED IDEOGRAPH
+0xC245	0x7FEC	#CJK UNIFIED IDEOGRAPH
+0xC246	0x7FED	#CJK UNIFIED IDEOGRAPH
+0xC247	0x7FEF	#CJK UNIFIED IDEOGRAPH
+0xC248	0x7FF2	#CJK UNIFIED IDEOGRAPH
+0xC249	0x7FF4	#CJK UNIFIED IDEOGRAPH
+0xC24A	0x7FF5	#CJK UNIFIED IDEOGRAPH
+0xC24B	0x7FF6	#CJK UNIFIED IDEOGRAPH
+0xC24C	0x7FF7	#CJK UNIFIED IDEOGRAPH
+0xC24D	0x7FF8	#CJK UNIFIED IDEOGRAPH
+0xC24E	0x7FF9	#CJK UNIFIED IDEOGRAPH
+0xC24F	0x7FFA	#CJK UNIFIED IDEOGRAPH
+0xC250	0x7FFD	#CJK UNIFIED IDEOGRAPH
+0xC251	0x7FFE	#CJK UNIFIED IDEOGRAPH
+0xC252	0x7FFF	#CJK UNIFIED IDEOGRAPH
+0xC253	0x8002	#CJK UNIFIED IDEOGRAPH
+0xC254	0x8007	#CJK UNIFIED IDEOGRAPH
+0xC255	0x8008	#CJK UNIFIED IDEOGRAPH
+0xC256	0x8009	#CJK UNIFIED IDEOGRAPH
+0xC257	0x800A	#CJK UNIFIED IDEOGRAPH
+0xC258	0x800E	#CJK UNIFIED IDEOGRAPH
+0xC259	0x800F	#CJK UNIFIED IDEOGRAPH
+0xC25A	0x8011	#CJK UNIFIED IDEOGRAPH
+0xC25B	0x8013	#CJK UNIFIED IDEOGRAPH
+0xC25C	0x801A	#CJK UNIFIED IDEOGRAPH
+0xC25D	0x801B	#CJK UNIFIED IDEOGRAPH
+0xC25E	0x801D	#CJK UNIFIED IDEOGRAPH
+0xC25F	0x801E	#CJK UNIFIED IDEOGRAPH
+0xC260	0x801F	#CJK UNIFIED IDEOGRAPH
+0xC261	0x8021	#CJK UNIFIED IDEOGRAPH
+0xC262	0x8023	#CJK UNIFIED IDEOGRAPH
+0xC263	0x8024	#CJK UNIFIED IDEOGRAPH
+0xC264	0x802B	#CJK UNIFIED IDEOGRAPH
+0xC265	0x802C	#CJK UNIFIED IDEOGRAPH
+0xC266	0x802D	#CJK UNIFIED IDEOGRAPH
+0xC267	0x802E	#CJK UNIFIED IDEOGRAPH
+0xC268	0x802F	#CJK UNIFIED IDEOGRAPH
+0xC269	0x8030	#CJK UNIFIED IDEOGRAPH
+0xC26A	0x8032	#CJK UNIFIED IDEOGRAPH
+0xC26B	0x8034	#CJK UNIFIED IDEOGRAPH
+0xC26C	0x8039	#CJK UNIFIED IDEOGRAPH
+0xC26D	0x803A	#CJK UNIFIED IDEOGRAPH
+0xC26E	0x803C	#CJK UNIFIED IDEOGRAPH
+0xC26F	0x803E	#CJK UNIFIED IDEOGRAPH
+0xC270	0x8040	#CJK UNIFIED IDEOGRAPH
+0xC271	0x8041	#CJK UNIFIED IDEOGRAPH
+0xC272	0x8044	#CJK UNIFIED IDEOGRAPH
+0xC273	0x8045	#CJK UNIFIED IDEOGRAPH
+0xC274	0x8047	#CJK UNIFIED IDEOGRAPH
+0xC275	0x8048	#CJK UNIFIED IDEOGRAPH
+0xC276	0x8049	#CJK UNIFIED IDEOGRAPH
+0xC277	0x804E	#CJK UNIFIED IDEOGRAPH
+0xC278	0x804F	#CJK UNIFIED IDEOGRAPH
+0xC279	0x8050	#CJK UNIFIED IDEOGRAPH
+0xC27A	0x8051	#CJK UNIFIED IDEOGRAPH
+0xC27B	0x8053	#CJK UNIFIED IDEOGRAPH
+0xC27C	0x8055	#CJK UNIFIED IDEOGRAPH
+0xC27D	0x8056	#CJK UNIFIED IDEOGRAPH
+0xC27E	0x8057	#CJK UNIFIED IDEOGRAPH
+0xC280	0x8059	#CJK UNIFIED IDEOGRAPH
+0xC281	0x805B	#CJK UNIFIED IDEOGRAPH
+0xC282	0x805C	#CJK UNIFIED IDEOGRAPH
+0xC283	0x805D	#CJK UNIFIED IDEOGRAPH
+0xC284	0x805E	#CJK UNIFIED IDEOGRAPH
+0xC285	0x805F	#CJK UNIFIED IDEOGRAPH
+0xC286	0x8060	#CJK UNIFIED IDEOGRAPH
+0xC287	0x8061	#CJK UNIFIED IDEOGRAPH
+0xC288	0x8062	#CJK UNIFIED IDEOGRAPH
+0xC289	0x8063	#CJK UNIFIED IDEOGRAPH
+0xC28A	0x8064	#CJK UNIFIED IDEOGRAPH
+0xC28B	0x8065	#CJK UNIFIED IDEOGRAPH
+0xC28C	0x8066	#CJK UNIFIED IDEOGRAPH
+0xC28D	0x8067	#CJK UNIFIED IDEOGRAPH
+0xC28E	0x8068	#CJK UNIFIED IDEOGRAPH
+0xC28F	0x806B	#CJK UNIFIED IDEOGRAPH
+0xC290	0x806C	#CJK UNIFIED IDEOGRAPH
+0xC291	0x806D	#CJK UNIFIED IDEOGRAPH
+0xC292	0x806E	#CJK UNIFIED IDEOGRAPH
+0xC293	0x806F	#CJK UNIFIED IDEOGRAPH
+0xC294	0x8070	#CJK UNIFIED IDEOGRAPH
+0xC295	0x8072	#CJK UNIFIED IDEOGRAPH
+0xC296	0x8073	#CJK UNIFIED IDEOGRAPH
+0xC297	0x8074	#CJK UNIFIED IDEOGRAPH
+0xC298	0x8075	#CJK UNIFIED IDEOGRAPH
+0xC299	0x8076	#CJK UNIFIED IDEOGRAPH
+0xC29A	0x8077	#CJK UNIFIED IDEOGRAPH
+0xC29B	0x8078	#CJK UNIFIED IDEOGRAPH
+0xC29C	0x8079	#CJK UNIFIED IDEOGRAPH
+0xC29D	0x807A	#CJK UNIFIED IDEOGRAPH
+0xC29E	0x807B	#CJK UNIFIED IDEOGRAPH
+0xC29F	0x807C	#CJK UNIFIED IDEOGRAPH
+0xC2A0	0x807D	#CJK UNIFIED IDEOGRAPH
+0xC2A1	0x9686	#CJK UNIFIED IDEOGRAPH
+0xC2A2	0x5784	#CJK UNIFIED IDEOGRAPH
+0xC2A3	0x62E2	#CJK UNIFIED IDEOGRAPH
+0xC2A4	0x9647	#CJK UNIFIED IDEOGRAPH
+0xC2A5	0x697C	#CJK UNIFIED IDEOGRAPH
+0xC2A6	0x5A04	#CJK UNIFIED IDEOGRAPH
+0xC2A7	0x6402	#CJK UNIFIED IDEOGRAPH
+0xC2A8	0x7BD3	#CJK UNIFIED IDEOGRAPH
+0xC2A9	0x6F0F	#CJK UNIFIED IDEOGRAPH
+0xC2AA	0x964B	#CJK UNIFIED IDEOGRAPH
+0xC2AB	0x82A6	#CJK UNIFIED IDEOGRAPH
+0xC2AC	0x5362	#CJK UNIFIED IDEOGRAPH
+0xC2AD	0x9885	#CJK UNIFIED IDEOGRAPH
+0xC2AE	0x5E90	#CJK UNIFIED IDEOGRAPH
+0xC2AF	0x7089	#CJK UNIFIED IDEOGRAPH
+0xC2B0	0x63B3	#CJK UNIFIED IDEOGRAPH
+0xC2B1	0x5364	#CJK UNIFIED IDEOGRAPH
+0xC2B2	0x864F	#CJK UNIFIED IDEOGRAPH
+0xC2B3	0x9C81	#CJK UNIFIED IDEOGRAPH
+0xC2B4	0x9E93	#CJK UNIFIED IDEOGRAPH
+0xC2B5	0x788C	#CJK UNIFIED IDEOGRAPH
+0xC2B6	0x9732	#CJK UNIFIED IDEOGRAPH
+0xC2B7	0x8DEF	#CJK UNIFIED IDEOGRAPH
+0xC2B8	0x8D42	#CJK UNIFIED IDEOGRAPH
+0xC2B9	0x9E7F	#CJK UNIFIED IDEOGRAPH
+0xC2BA	0x6F5E	#CJK UNIFIED IDEOGRAPH
+0xC2BB	0x7984	#CJK UNIFIED IDEOGRAPH
+0xC2BC	0x5F55	#CJK UNIFIED IDEOGRAPH
+0xC2BD	0x9646	#CJK UNIFIED IDEOGRAPH
+0xC2BE	0x622E	#CJK UNIFIED IDEOGRAPH
+0xC2BF	0x9A74	#CJK UNIFIED IDEOGRAPH
+0xC2C0	0x5415	#CJK UNIFIED IDEOGRAPH
+0xC2C1	0x94DD	#CJK UNIFIED IDEOGRAPH
+0xC2C2	0x4FA3	#CJK UNIFIED IDEOGRAPH
+0xC2C3	0x65C5	#CJK UNIFIED IDEOGRAPH
+0xC2C4	0x5C65	#CJK UNIFIED IDEOGRAPH
+0xC2C5	0x5C61	#CJK UNIFIED IDEOGRAPH
+0xC2C6	0x7F15	#CJK UNIFIED IDEOGRAPH
+0xC2C7	0x8651	#CJK UNIFIED IDEOGRAPH
+0xC2C8	0x6C2F	#CJK UNIFIED IDEOGRAPH
+0xC2C9	0x5F8B	#CJK UNIFIED IDEOGRAPH
+0xC2CA	0x7387	#CJK UNIFIED IDEOGRAPH
+0xC2CB	0x6EE4	#CJK UNIFIED IDEOGRAPH
+0xC2CC	0x7EFF	#CJK UNIFIED IDEOGRAPH
+0xC2CD	0x5CE6	#CJK UNIFIED IDEOGRAPH
+0xC2CE	0x631B	#CJK UNIFIED IDEOGRAPH
+0xC2CF	0x5B6A	#CJK UNIFIED IDEOGRAPH
+0xC2D0	0x6EE6	#CJK UNIFIED IDEOGRAPH
+0xC2D1	0x5375	#CJK UNIFIED IDEOGRAPH
+0xC2D2	0x4E71	#CJK UNIFIED IDEOGRAPH
+0xC2D3	0x63A0	#CJK UNIFIED IDEOGRAPH
+0xC2D4	0x7565	#CJK UNIFIED IDEOGRAPH
+0xC2D5	0x62A1	#CJK UNIFIED IDEOGRAPH
+0xC2D6	0x8F6E	#CJK UNIFIED IDEOGRAPH
+0xC2D7	0x4F26	#CJK UNIFIED IDEOGRAPH
+0xC2D8	0x4ED1	#CJK UNIFIED IDEOGRAPH
+0xC2D9	0x6CA6	#CJK UNIFIED IDEOGRAPH
+0xC2DA	0x7EB6	#CJK UNIFIED IDEOGRAPH
+0xC2DB	0x8BBA	#CJK UNIFIED IDEOGRAPH
+0xC2DC	0x841D	#CJK UNIFIED IDEOGRAPH
+0xC2DD	0x87BA	#CJK UNIFIED IDEOGRAPH
+0xC2DE	0x7F57	#CJK UNIFIED IDEOGRAPH
+0xC2DF	0x903B	#CJK UNIFIED IDEOGRAPH
+0xC2E0	0x9523	#CJK UNIFIED IDEOGRAPH
+0xC2E1	0x7BA9	#CJK UNIFIED IDEOGRAPH
+0xC2E2	0x9AA1	#CJK UNIFIED IDEOGRAPH
+0xC2E3	0x88F8	#CJK UNIFIED IDEOGRAPH
+0xC2E4	0x843D	#CJK UNIFIED IDEOGRAPH
+0xC2E5	0x6D1B	#CJK UNIFIED IDEOGRAPH
+0xC2E6	0x9A86	#CJK UNIFIED IDEOGRAPH
+0xC2E7	0x7EDC	#CJK UNIFIED IDEOGRAPH
+0xC2E8	0x5988	#CJK UNIFIED IDEOGRAPH
+0xC2E9	0x9EBB	#CJK UNIFIED IDEOGRAPH
+0xC2EA	0x739B	#CJK UNIFIED IDEOGRAPH
+0xC2EB	0x7801	#CJK UNIFIED IDEOGRAPH
+0xC2EC	0x8682	#CJK UNIFIED IDEOGRAPH
+0xC2ED	0x9A6C	#CJK UNIFIED IDEOGRAPH
+0xC2EE	0x9A82	#CJK UNIFIED IDEOGRAPH
+0xC2EF	0x561B	#CJK UNIFIED IDEOGRAPH
+0xC2F0	0x5417	#CJK UNIFIED IDEOGRAPH
+0xC2F1	0x57CB	#CJK UNIFIED IDEOGRAPH
+0xC2F2	0x4E70	#CJK UNIFIED IDEOGRAPH
+0xC2F3	0x9EA6	#CJK UNIFIED IDEOGRAPH
+0xC2F4	0x5356	#CJK UNIFIED IDEOGRAPH
+0xC2F5	0x8FC8	#CJK UNIFIED IDEOGRAPH
+0xC2F6	0x8109	#CJK UNIFIED IDEOGRAPH
+0xC2F7	0x7792	#CJK UNIFIED IDEOGRAPH
+0xC2F8	0x9992	#CJK UNIFIED IDEOGRAPH
+0xC2F9	0x86EE	#CJK UNIFIED IDEOGRAPH
+0xC2FA	0x6EE1	#CJK UNIFIED IDEOGRAPH
+0xC2FB	0x8513	#CJK UNIFIED IDEOGRAPH
+0xC2FC	0x66FC	#CJK UNIFIED IDEOGRAPH
+0xC2FD	0x6162	#CJK UNIFIED IDEOGRAPH
+0xC2FE	0x6F2B	#CJK UNIFIED IDEOGRAPH
+0xC340	0x807E	#CJK UNIFIED IDEOGRAPH
+0xC341	0x8081	#CJK UNIFIED IDEOGRAPH
+0xC342	0x8082	#CJK UNIFIED IDEOGRAPH
+0xC343	0x8085	#CJK UNIFIED IDEOGRAPH
+0xC344	0x8088	#CJK UNIFIED IDEOGRAPH
+0xC345	0x808A	#CJK UNIFIED IDEOGRAPH
+0xC346	0x808D	#CJK UNIFIED IDEOGRAPH
+0xC347	0x808E	#CJK UNIFIED IDEOGRAPH
+0xC348	0x808F	#CJK UNIFIED IDEOGRAPH
+0xC349	0x8090	#CJK UNIFIED IDEOGRAPH
+0xC34A	0x8091	#CJK UNIFIED IDEOGRAPH
+0xC34B	0x8092	#CJK UNIFIED IDEOGRAPH
+0xC34C	0x8094	#CJK UNIFIED IDEOGRAPH
+0xC34D	0x8095	#CJK UNIFIED IDEOGRAPH
+0xC34E	0x8097	#CJK UNIFIED IDEOGRAPH
+0xC34F	0x8099	#CJK UNIFIED IDEOGRAPH
+0xC350	0x809E	#CJK UNIFIED IDEOGRAPH
+0xC351	0x80A3	#CJK UNIFIED IDEOGRAPH
+0xC352	0x80A6	#CJK UNIFIED IDEOGRAPH
+0xC353	0x80A7	#CJK UNIFIED IDEOGRAPH
+0xC354	0x80A8	#CJK UNIFIED IDEOGRAPH
+0xC355	0x80AC	#CJK UNIFIED IDEOGRAPH
+0xC356	0x80B0	#CJK UNIFIED IDEOGRAPH
+0xC357	0x80B3	#CJK UNIFIED IDEOGRAPH
+0xC358	0x80B5	#CJK UNIFIED IDEOGRAPH
+0xC359	0x80B6	#CJK UNIFIED IDEOGRAPH
+0xC35A	0x80B8	#CJK UNIFIED IDEOGRAPH
+0xC35B	0x80B9	#CJK UNIFIED IDEOGRAPH
+0xC35C	0x80BB	#CJK UNIFIED IDEOGRAPH
+0xC35D	0x80C5	#CJK UNIFIED IDEOGRAPH
+0xC35E	0x80C7	#CJK UNIFIED IDEOGRAPH
+0xC35F	0x80C8	#CJK UNIFIED IDEOGRAPH
+0xC360	0x80C9	#CJK UNIFIED IDEOGRAPH
+0xC361	0x80CA	#CJK UNIFIED IDEOGRAPH
+0xC362	0x80CB	#CJK UNIFIED IDEOGRAPH
+0xC363	0x80CF	#CJK UNIFIED IDEOGRAPH
+0xC364	0x80D0	#CJK UNIFIED IDEOGRAPH
+0xC365	0x80D1	#CJK UNIFIED IDEOGRAPH
+0xC366	0x80D2	#CJK UNIFIED IDEOGRAPH
+0xC367	0x80D3	#CJK UNIFIED IDEOGRAPH
+0xC368	0x80D4	#CJK UNIFIED IDEOGRAPH
+0xC369	0x80D5	#CJK UNIFIED IDEOGRAPH
+0xC36A	0x80D8	#CJK UNIFIED IDEOGRAPH
+0xC36B	0x80DF	#CJK UNIFIED IDEOGRAPH
+0xC36C	0x80E0	#CJK UNIFIED IDEOGRAPH
+0xC36D	0x80E2	#CJK UNIFIED IDEOGRAPH
+0xC36E	0x80E3	#CJK UNIFIED IDEOGRAPH
+0xC36F	0x80E6	#CJK UNIFIED IDEOGRAPH
+0xC370	0x80EE	#CJK UNIFIED IDEOGRAPH
+0xC371	0x80F5	#CJK UNIFIED IDEOGRAPH
+0xC372	0x80F7	#CJK UNIFIED IDEOGRAPH
+0xC373	0x80F9	#CJK UNIFIED IDEOGRAPH
+0xC374	0x80FB	#CJK UNIFIED IDEOGRAPH
+0xC375	0x80FE	#CJK UNIFIED IDEOGRAPH
+0xC376	0x80FF	#CJK UNIFIED IDEOGRAPH
+0xC377	0x8100	#CJK UNIFIED IDEOGRAPH
+0xC378	0x8101	#CJK UNIFIED IDEOGRAPH
+0xC379	0x8103	#CJK UNIFIED IDEOGRAPH
+0xC37A	0x8104	#CJK UNIFIED IDEOGRAPH
+0xC37B	0x8105	#CJK UNIFIED IDEOGRAPH
+0xC37C	0x8107	#CJK UNIFIED IDEOGRAPH
+0xC37D	0x8108	#CJK UNIFIED IDEOGRAPH
+0xC37E	0x810B	#CJK UNIFIED IDEOGRAPH
+0xC380	0x810C	#CJK UNIFIED IDEOGRAPH
+0xC381	0x8115	#CJK UNIFIED IDEOGRAPH
+0xC382	0x8117	#CJK UNIFIED IDEOGRAPH
+0xC383	0x8119	#CJK UNIFIED IDEOGRAPH
+0xC384	0x811B	#CJK UNIFIED IDEOGRAPH
+0xC385	0x811C	#CJK UNIFIED IDEOGRAPH
+0xC386	0x811D	#CJK UNIFIED IDEOGRAPH
+0xC387	0x811F	#CJK UNIFIED IDEOGRAPH
+0xC388	0x8120	#CJK UNIFIED IDEOGRAPH
+0xC389	0x8121	#CJK UNIFIED IDEOGRAPH
+0xC38A	0x8122	#CJK UNIFIED IDEOGRAPH
+0xC38B	0x8123	#CJK UNIFIED IDEOGRAPH
+0xC38C	0x8124	#CJK UNIFIED IDEOGRAPH
+0xC38D	0x8125	#CJK UNIFIED IDEOGRAPH
+0xC38E	0x8126	#CJK UNIFIED IDEOGRAPH
+0xC38F	0x8127	#CJK UNIFIED IDEOGRAPH
+0xC390	0x8128	#CJK UNIFIED IDEOGRAPH
+0xC391	0x8129	#CJK UNIFIED IDEOGRAPH
+0xC392	0x812A	#CJK UNIFIED IDEOGRAPH
+0xC393	0x812B	#CJK UNIFIED IDEOGRAPH
+0xC394	0x812D	#CJK UNIFIED IDEOGRAPH
+0xC395	0x812E	#CJK UNIFIED IDEOGRAPH
+0xC396	0x8130	#CJK UNIFIED IDEOGRAPH
+0xC397	0x8133	#CJK UNIFIED IDEOGRAPH
+0xC398	0x8134	#CJK UNIFIED IDEOGRAPH
+0xC399	0x8135	#CJK UNIFIED IDEOGRAPH
+0xC39A	0x8137	#CJK UNIFIED IDEOGRAPH
+0xC39B	0x8139	#CJK UNIFIED IDEOGRAPH
+0xC39C	0x813A	#CJK UNIFIED IDEOGRAPH
+0xC39D	0x813B	#CJK UNIFIED IDEOGRAPH
+0xC39E	0x813C	#CJK UNIFIED IDEOGRAPH
+0xC39F	0x813D	#CJK UNIFIED IDEOGRAPH
+0xC3A0	0x813F	#CJK UNIFIED IDEOGRAPH
+0xC3A1	0x8C29	#CJK UNIFIED IDEOGRAPH
+0xC3A2	0x8292	#CJK UNIFIED IDEOGRAPH
+0xC3A3	0x832B	#CJK UNIFIED IDEOGRAPH
+0xC3A4	0x76F2	#CJK UNIFIED IDEOGRAPH
+0xC3A5	0x6C13	#CJK UNIFIED IDEOGRAPH
+0xC3A6	0x5FD9	#CJK UNIFIED IDEOGRAPH
+0xC3A7	0x83BD	#CJK UNIFIED IDEOGRAPH
+0xC3A8	0x732B	#CJK UNIFIED IDEOGRAPH
+0xC3A9	0x8305	#CJK UNIFIED IDEOGRAPH
+0xC3AA	0x951A	#CJK UNIFIED IDEOGRAPH
+0xC3AB	0x6BDB	#CJK UNIFIED IDEOGRAPH
+0xC3AC	0x77DB	#CJK UNIFIED IDEOGRAPH
+0xC3AD	0x94C6	#CJK UNIFIED IDEOGRAPH
+0xC3AE	0x536F	#CJK UNIFIED IDEOGRAPH
+0xC3AF	0x8302	#CJK UNIFIED IDEOGRAPH
+0xC3B0	0x5192	#CJK UNIFIED IDEOGRAPH
+0xC3B1	0x5E3D	#CJK UNIFIED IDEOGRAPH
+0xC3B2	0x8C8C	#CJK UNIFIED IDEOGRAPH
+0xC3B3	0x8D38	#CJK UNIFIED IDEOGRAPH
+0xC3B4	0x4E48	#CJK UNIFIED IDEOGRAPH
+0xC3B5	0x73AB	#CJK UNIFIED IDEOGRAPH
+0xC3B6	0x679A	#CJK UNIFIED IDEOGRAPH
+0xC3B7	0x6885	#CJK UNIFIED IDEOGRAPH
+0xC3B8	0x9176	#CJK UNIFIED IDEOGRAPH
+0xC3B9	0x9709	#CJK UNIFIED IDEOGRAPH
+0xC3BA	0x7164	#CJK UNIFIED IDEOGRAPH
+0xC3BB	0x6CA1	#CJK UNIFIED IDEOGRAPH
+0xC3BC	0x7709	#CJK UNIFIED IDEOGRAPH
+0xC3BD	0x5A92	#CJK UNIFIED IDEOGRAPH
+0xC3BE	0x9541	#CJK UNIFIED IDEOGRAPH
+0xC3BF	0x6BCF	#CJK UNIFIED IDEOGRAPH
+0xC3C0	0x7F8E	#CJK UNIFIED IDEOGRAPH
+0xC3C1	0x6627	#CJK UNIFIED IDEOGRAPH
+0xC3C2	0x5BD0	#CJK UNIFIED IDEOGRAPH
+0xC3C3	0x59B9	#CJK UNIFIED IDEOGRAPH
+0xC3C4	0x5A9A	#CJK UNIFIED IDEOGRAPH
+0xC3C5	0x95E8	#CJK UNIFIED IDEOGRAPH
+0xC3C6	0x95F7	#CJK UNIFIED IDEOGRAPH
+0xC3C7	0x4EEC	#CJK UNIFIED IDEOGRAPH
+0xC3C8	0x840C	#CJK UNIFIED IDEOGRAPH
+0xC3C9	0x8499	#CJK UNIFIED IDEOGRAPH
+0xC3CA	0x6AAC	#CJK UNIFIED IDEOGRAPH
+0xC3CB	0x76DF	#CJK UNIFIED IDEOGRAPH
+0xC3CC	0x9530	#CJK UNIFIED IDEOGRAPH
+0xC3CD	0x731B	#CJK UNIFIED IDEOGRAPH
+0xC3CE	0x68A6	#CJK UNIFIED IDEOGRAPH
+0xC3CF	0x5B5F	#CJK UNIFIED IDEOGRAPH
+0xC3D0	0x772F	#CJK UNIFIED IDEOGRAPH
+0xC3D1	0x919A	#CJK UNIFIED IDEOGRAPH
+0xC3D2	0x9761	#CJK UNIFIED IDEOGRAPH
+0xC3D3	0x7CDC	#CJK UNIFIED IDEOGRAPH
+0xC3D4	0x8FF7	#CJK UNIFIED IDEOGRAPH
+0xC3D5	0x8C1C	#CJK UNIFIED IDEOGRAPH
+0xC3D6	0x5F25	#CJK UNIFIED IDEOGRAPH
+0xC3D7	0x7C73	#CJK UNIFIED IDEOGRAPH
+0xC3D8	0x79D8	#CJK UNIFIED IDEOGRAPH
+0xC3D9	0x89C5	#CJK UNIFIED IDEOGRAPH
+0xC3DA	0x6CCC	#CJK UNIFIED IDEOGRAPH
+0xC3DB	0x871C	#CJK UNIFIED IDEOGRAPH
+0xC3DC	0x5BC6	#CJK UNIFIED IDEOGRAPH
+0xC3DD	0x5E42	#CJK UNIFIED IDEOGRAPH
+0xC3DE	0x68C9	#CJK UNIFIED IDEOGRAPH
+0xC3DF	0x7720	#CJK UNIFIED IDEOGRAPH
+0xC3E0	0x7EF5	#CJK UNIFIED IDEOGRAPH
+0xC3E1	0x5195	#CJK UNIFIED IDEOGRAPH
+0xC3E2	0x514D	#CJK UNIFIED IDEOGRAPH
+0xC3E3	0x52C9	#CJK UNIFIED IDEOGRAPH
+0xC3E4	0x5A29	#CJK UNIFIED IDEOGRAPH
+0xC3E5	0x7F05	#CJK UNIFIED IDEOGRAPH
+0xC3E6	0x9762	#CJK UNIFIED IDEOGRAPH
+0xC3E7	0x82D7	#CJK UNIFIED IDEOGRAPH
+0xC3E8	0x63CF	#CJK UNIFIED IDEOGRAPH
+0xC3E9	0x7784	#CJK UNIFIED IDEOGRAPH
+0xC3EA	0x85D0	#CJK UNIFIED IDEOGRAPH
+0xC3EB	0x79D2	#CJK UNIFIED IDEOGRAPH
+0xC3EC	0x6E3A	#CJK UNIFIED IDEOGRAPH
+0xC3ED	0x5E99	#CJK UNIFIED IDEOGRAPH
+0xC3EE	0x5999	#CJK UNIFIED IDEOGRAPH
+0xC3EF	0x8511	#CJK UNIFIED IDEOGRAPH
+0xC3F0	0x706D	#CJK UNIFIED IDEOGRAPH
+0xC3F1	0x6C11	#CJK UNIFIED IDEOGRAPH
+0xC3F2	0x62BF	#CJK UNIFIED IDEOGRAPH
+0xC3F3	0x76BF	#CJK UNIFIED IDEOGRAPH
+0xC3F4	0x654F	#CJK UNIFIED IDEOGRAPH
+0xC3F5	0x60AF	#CJK UNIFIED IDEOGRAPH
+0xC3F6	0x95FD	#CJK UNIFIED IDEOGRAPH
+0xC3F7	0x660E	#CJK UNIFIED IDEOGRAPH
+0xC3F8	0x879F	#CJK UNIFIED IDEOGRAPH
+0xC3F9	0x9E23	#CJK UNIFIED IDEOGRAPH
+0xC3FA	0x94ED	#CJK UNIFIED IDEOGRAPH
+0xC3FB	0x540D	#CJK UNIFIED IDEOGRAPH
+0xC3FC	0x547D	#CJK UNIFIED IDEOGRAPH
+0xC3FD	0x8C2C	#CJK UNIFIED IDEOGRAPH
+0xC3FE	0x6478	#CJK UNIFIED IDEOGRAPH
+0xC440	0x8140	#CJK UNIFIED IDEOGRAPH
+0xC441	0x8141	#CJK UNIFIED IDEOGRAPH
+0xC442	0x8142	#CJK UNIFIED IDEOGRAPH
+0xC443	0x8143	#CJK UNIFIED IDEOGRAPH
+0xC444	0x8144	#CJK UNIFIED IDEOGRAPH
+0xC445	0x8145	#CJK UNIFIED IDEOGRAPH
+0xC446	0x8147	#CJK UNIFIED IDEOGRAPH
+0xC447	0x8149	#CJK UNIFIED IDEOGRAPH
+0xC448	0x814D	#CJK UNIFIED IDEOGRAPH
+0xC449	0x814E	#CJK UNIFIED IDEOGRAPH
+0xC44A	0x814F	#CJK UNIFIED IDEOGRAPH
+0xC44B	0x8152	#CJK UNIFIED IDEOGRAPH
+0xC44C	0x8156	#CJK UNIFIED IDEOGRAPH
+0xC44D	0x8157	#CJK UNIFIED IDEOGRAPH
+0xC44E	0x8158	#CJK UNIFIED IDEOGRAPH
+0xC44F	0x815B	#CJK UNIFIED IDEOGRAPH
+0xC450	0x815C	#CJK UNIFIED IDEOGRAPH
+0xC451	0x815D	#CJK UNIFIED IDEOGRAPH
+0xC452	0x815E	#CJK UNIFIED IDEOGRAPH
+0xC453	0x815F	#CJK UNIFIED IDEOGRAPH
+0xC454	0x8161	#CJK UNIFIED IDEOGRAPH
+0xC455	0x8162	#CJK UNIFIED IDEOGRAPH
+0xC456	0x8163	#CJK UNIFIED IDEOGRAPH
+0xC457	0x8164	#CJK UNIFIED IDEOGRAPH
+0xC458	0x8166	#CJK UNIFIED IDEOGRAPH
+0xC459	0x8168	#CJK UNIFIED IDEOGRAPH
+0xC45A	0x816A	#CJK UNIFIED IDEOGRAPH
+0xC45B	0x816B	#CJK UNIFIED IDEOGRAPH
+0xC45C	0x816C	#CJK UNIFIED IDEOGRAPH
+0xC45D	0x816F	#CJK UNIFIED IDEOGRAPH
+0xC45E	0x8172	#CJK UNIFIED IDEOGRAPH
+0xC45F	0x8173	#CJK UNIFIED IDEOGRAPH
+0xC460	0x8175	#CJK UNIFIED IDEOGRAPH
+0xC461	0x8176	#CJK UNIFIED IDEOGRAPH
+0xC462	0x8177	#CJK UNIFIED IDEOGRAPH
+0xC463	0x8178	#CJK UNIFIED IDEOGRAPH
+0xC464	0x8181	#CJK UNIFIED IDEOGRAPH
+0xC465	0x8183	#CJK UNIFIED IDEOGRAPH
+0xC466	0x8184	#CJK UNIFIED IDEOGRAPH
+0xC467	0x8185	#CJK UNIFIED IDEOGRAPH
+0xC468	0x8186	#CJK UNIFIED IDEOGRAPH
+0xC469	0x8187	#CJK UNIFIED IDEOGRAPH
+0xC46A	0x8189	#CJK UNIFIED IDEOGRAPH
+0xC46B	0x818B	#CJK UNIFIED IDEOGRAPH
+0xC46C	0x818C	#CJK UNIFIED IDEOGRAPH
+0xC46D	0x818D	#CJK UNIFIED IDEOGRAPH
+0xC46E	0x818E	#CJK UNIFIED IDEOGRAPH
+0xC46F	0x8190	#CJK UNIFIED IDEOGRAPH
+0xC470	0x8192	#CJK UNIFIED IDEOGRAPH
+0xC471	0x8193	#CJK UNIFIED IDEOGRAPH
+0xC472	0x8194	#CJK UNIFIED IDEOGRAPH
+0xC473	0x8195	#CJK UNIFIED IDEOGRAPH
+0xC474	0x8196	#CJK UNIFIED IDEOGRAPH
+0xC475	0x8197	#CJK UNIFIED IDEOGRAPH
+0xC476	0x8199	#CJK UNIFIED IDEOGRAPH
+0xC477	0x819A	#CJK UNIFIED IDEOGRAPH
+0xC478	0x819E	#CJK UNIFIED IDEOGRAPH
+0xC479	0x819F	#CJK UNIFIED IDEOGRAPH
+0xC47A	0x81A0	#CJK UNIFIED IDEOGRAPH
+0xC47B	0x81A1	#CJK UNIFIED IDEOGRAPH
+0xC47C	0x81A2	#CJK UNIFIED IDEOGRAPH
+0xC47D	0x81A4	#CJK UNIFIED IDEOGRAPH
+0xC47E	0x81A5	#CJK UNIFIED IDEOGRAPH
+0xC480	0x81A7	#CJK UNIFIED IDEOGRAPH
+0xC481	0x81A9	#CJK UNIFIED IDEOGRAPH
+0xC482	0x81AB	#CJK UNIFIED IDEOGRAPH
+0xC483	0x81AC	#CJK UNIFIED IDEOGRAPH
+0xC484	0x81AD	#CJK UNIFIED IDEOGRAPH
+0xC485	0x81AE	#CJK UNIFIED IDEOGRAPH
+0xC486	0x81AF	#CJK UNIFIED IDEOGRAPH
+0xC487	0x81B0	#CJK UNIFIED IDEOGRAPH
+0xC488	0x81B1	#CJK UNIFIED IDEOGRAPH
+0xC489	0x81B2	#CJK UNIFIED IDEOGRAPH
+0xC48A	0x81B4	#CJK UNIFIED IDEOGRAPH
+0xC48B	0x81B5	#CJK UNIFIED IDEOGRAPH
+0xC48C	0x81B6	#CJK UNIFIED IDEOGRAPH
+0xC48D	0x81B7	#CJK UNIFIED IDEOGRAPH
+0xC48E	0x81B8	#CJK UNIFIED IDEOGRAPH
+0xC48F	0x81B9	#CJK UNIFIED IDEOGRAPH
+0xC490	0x81BC	#CJK UNIFIED IDEOGRAPH
+0xC491	0x81BD	#CJK UNIFIED IDEOGRAPH
+0xC492	0x81BE	#CJK UNIFIED IDEOGRAPH
+0xC493	0x81BF	#CJK UNIFIED IDEOGRAPH
+0xC494	0x81C4	#CJK UNIFIED IDEOGRAPH
+0xC495	0x81C5	#CJK UNIFIED IDEOGRAPH
+0xC496	0x81C7	#CJK UNIFIED IDEOGRAPH
+0xC497	0x81C8	#CJK UNIFIED IDEOGRAPH
+0xC498	0x81C9	#CJK UNIFIED IDEOGRAPH
+0xC499	0x81CB	#CJK UNIFIED IDEOGRAPH
+0xC49A	0x81CD	#CJK UNIFIED IDEOGRAPH
+0xC49B	0x81CE	#CJK UNIFIED IDEOGRAPH
+0xC49C	0x81CF	#CJK UNIFIED IDEOGRAPH
+0xC49D	0x81D0	#CJK UNIFIED IDEOGRAPH
+0xC49E	0x81D1	#CJK UNIFIED IDEOGRAPH
+0xC49F	0x81D2	#CJK UNIFIED IDEOGRAPH
+0xC4A0	0x81D3	#CJK UNIFIED IDEOGRAPH
+0xC4A1	0x6479	#CJK UNIFIED IDEOGRAPH
+0xC4A2	0x8611	#CJK UNIFIED IDEOGRAPH
+0xC4A3	0x6A21	#CJK UNIFIED IDEOGRAPH
+0xC4A4	0x819C	#CJK UNIFIED IDEOGRAPH
+0xC4A5	0x78E8	#CJK UNIFIED IDEOGRAPH
+0xC4A6	0x6469	#CJK UNIFIED IDEOGRAPH
+0xC4A7	0x9B54	#CJK UNIFIED IDEOGRAPH
+0xC4A8	0x62B9	#CJK UNIFIED IDEOGRAPH
+0xC4A9	0x672B	#CJK UNIFIED IDEOGRAPH
+0xC4AA	0x83AB	#CJK UNIFIED IDEOGRAPH
+0xC4AB	0x58A8	#CJK UNIFIED IDEOGRAPH
+0xC4AC	0x9ED8	#CJK UNIFIED IDEOGRAPH
+0xC4AD	0x6CAB	#CJK UNIFIED IDEOGRAPH
+0xC4AE	0x6F20	#CJK UNIFIED IDEOGRAPH
+0xC4AF	0x5BDE	#CJK UNIFIED IDEOGRAPH
+0xC4B0	0x964C	#CJK UNIFIED IDEOGRAPH
+0xC4B1	0x8C0B	#CJK UNIFIED IDEOGRAPH
+0xC4B2	0x725F	#CJK UNIFIED IDEOGRAPH
+0xC4B3	0x67D0	#CJK UNIFIED IDEOGRAPH
+0xC4B4	0x62C7	#CJK UNIFIED IDEOGRAPH
+0xC4B5	0x7261	#CJK UNIFIED IDEOGRAPH
+0xC4B6	0x4EA9	#CJK UNIFIED IDEOGRAPH
+0xC4B7	0x59C6	#CJK UNIFIED IDEOGRAPH
+0xC4B8	0x6BCD	#CJK UNIFIED IDEOGRAPH
+0xC4B9	0x5893	#CJK UNIFIED IDEOGRAPH
+0xC4BA	0x66AE	#CJK UNIFIED IDEOGRAPH
+0xC4BB	0x5E55	#CJK UNIFIED IDEOGRAPH
+0xC4BC	0x52DF	#CJK UNIFIED IDEOGRAPH
+0xC4BD	0x6155	#CJK UNIFIED IDEOGRAPH
+0xC4BE	0x6728	#CJK UNIFIED IDEOGRAPH
+0xC4BF	0x76EE	#CJK UNIFIED IDEOGRAPH
+0xC4C0	0x7766	#CJK UNIFIED IDEOGRAPH
+0xC4C1	0x7267	#CJK UNIFIED IDEOGRAPH
+0xC4C2	0x7A46	#CJK UNIFIED IDEOGRAPH
+0xC4C3	0x62FF	#CJK UNIFIED IDEOGRAPH
+0xC4C4	0x54EA	#CJK UNIFIED IDEOGRAPH
+0xC4C5	0x5450	#CJK UNIFIED IDEOGRAPH
+0xC4C6	0x94A0	#CJK UNIFIED IDEOGRAPH
+0xC4C7	0x90A3	#CJK UNIFIED IDEOGRAPH
+0xC4C8	0x5A1C	#CJK UNIFIED IDEOGRAPH
+0xC4C9	0x7EB3	#CJK UNIFIED IDEOGRAPH
+0xC4CA	0x6C16	#CJK UNIFIED IDEOGRAPH
+0xC4CB	0x4E43	#CJK UNIFIED IDEOGRAPH
+0xC4CC	0x5976	#CJK UNIFIED IDEOGRAPH
+0xC4CD	0x8010	#CJK UNIFIED IDEOGRAPH
+0xC4CE	0x5948	#CJK UNIFIED IDEOGRAPH
+0xC4CF	0x5357	#CJK UNIFIED IDEOGRAPH
+0xC4D0	0x7537	#CJK UNIFIED IDEOGRAPH
+0xC4D1	0x96BE	#CJK UNIFIED IDEOGRAPH
+0xC4D2	0x56CA	#CJK UNIFIED IDEOGRAPH
+0xC4D3	0x6320	#CJK UNIFIED IDEOGRAPH
+0xC4D4	0x8111	#CJK UNIFIED IDEOGRAPH
+0xC4D5	0x607C	#CJK UNIFIED IDEOGRAPH
+0xC4D6	0x95F9	#CJK UNIFIED IDEOGRAPH
+0xC4D7	0x6DD6	#CJK UNIFIED IDEOGRAPH
+0xC4D8	0x5462	#CJK UNIFIED IDEOGRAPH
+0xC4D9	0x9981	#CJK UNIFIED IDEOGRAPH
+0xC4DA	0x5185	#CJK UNIFIED IDEOGRAPH
+0xC4DB	0x5AE9	#CJK UNIFIED IDEOGRAPH
+0xC4DC	0x80FD	#CJK UNIFIED IDEOGRAPH
+0xC4DD	0x59AE	#CJK UNIFIED IDEOGRAPH
+0xC4DE	0x9713	#CJK UNIFIED IDEOGRAPH
+0xC4DF	0x502A	#CJK UNIFIED IDEOGRAPH
+0xC4E0	0x6CE5	#CJK UNIFIED IDEOGRAPH
+0xC4E1	0x5C3C	#CJK UNIFIED IDEOGRAPH
+0xC4E2	0x62DF	#CJK UNIFIED IDEOGRAPH
+0xC4E3	0x4F60	#CJK UNIFIED IDEOGRAPH
+0xC4E4	0x533F	#CJK UNIFIED IDEOGRAPH
+0xC4E5	0x817B	#CJK UNIFIED IDEOGRAPH
+0xC4E6	0x9006	#CJK UNIFIED IDEOGRAPH
+0xC4E7	0x6EBA	#CJK UNIFIED IDEOGRAPH
+0xC4E8	0x852B	#CJK UNIFIED IDEOGRAPH
+0xC4E9	0x62C8	#CJK UNIFIED IDEOGRAPH
+0xC4EA	0x5E74	#CJK UNIFIED IDEOGRAPH
+0xC4EB	0x78BE	#CJK UNIFIED IDEOGRAPH
+0xC4EC	0x64B5	#CJK UNIFIED IDEOGRAPH
+0xC4ED	0x637B	#CJK UNIFIED IDEOGRAPH
+0xC4EE	0x5FF5	#CJK UNIFIED IDEOGRAPH
+0xC4EF	0x5A18	#CJK UNIFIED IDEOGRAPH
+0xC4F0	0x917F	#CJK UNIFIED IDEOGRAPH
+0xC4F1	0x9E1F	#CJK UNIFIED IDEOGRAPH
+0xC4F2	0x5C3F	#CJK UNIFIED IDEOGRAPH
+0xC4F3	0x634F	#CJK UNIFIED IDEOGRAPH
+0xC4F4	0x8042	#CJK UNIFIED IDEOGRAPH
+0xC4F5	0x5B7D	#CJK UNIFIED IDEOGRAPH
+0xC4F6	0x556E	#CJK UNIFIED IDEOGRAPH
+0xC4F7	0x954A	#CJK UNIFIED IDEOGRAPH
+0xC4F8	0x954D	#CJK UNIFIED IDEOGRAPH
+0xC4F9	0x6D85	#CJK UNIFIED IDEOGRAPH
+0xC4FA	0x60A8	#CJK UNIFIED IDEOGRAPH
+0xC4FB	0x67E0	#CJK UNIFIED IDEOGRAPH
+0xC4FC	0x72DE	#CJK UNIFIED IDEOGRAPH
+0xC4FD	0x51DD	#CJK UNIFIED IDEOGRAPH
+0xC4FE	0x5B81	#CJK UNIFIED IDEOGRAPH
+0xC540	0x81D4	#CJK UNIFIED IDEOGRAPH
+0xC541	0x81D5	#CJK UNIFIED IDEOGRAPH
+0xC542	0x81D6	#CJK UNIFIED IDEOGRAPH
+0xC543	0x81D7	#CJK UNIFIED IDEOGRAPH
+0xC544	0x81D8	#CJK UNIFIED IDEOGRAPH
+0xC545	0x81D9	#CJK UNIFIED IDEOGRAPH
+0xC546	0x81DA	#CJK UNIFIED IDEOGRAPH
+0xC547	0x81DB	#CJK UNIFIED IDEOGRAPH
+0xC548	0x81DC	#CJK UNIFIED IDEOGRAPH
+0xC549	0x81DD	#CJK UNIFIED IDEOGRAPH
+0xC54A	0x81DE	#CJK UNIFIED IDEOGRAPH
+0xC54B	0x81DF	#CJK UNIFIED IDEOGRAPH
+0xC54C	0x81E0	#CJK UNIFIED IDEOGRAPH
+0xC54D	0x81E1	#CJK UNIFIED IDEOGRAPH
+0xC54E	0x81E2	#CJK UNIFIED IDEOGRAPH
+0xC54F	0x81E4	#CJK UNIFIED IDEOGRAPH
+0xC550	0x81E5	#CJK UNIFIED IDEOGRAPH
+0xC551	0x81E6	#CJK UNIFIED IDEOGRAPH
+0xC552	0x81E8	#CJK UNIFIED IDEOGRAPH
+0xC553	0x81E9	#CJK UNIFIED IDEOGRAPH
+0xC554	0x81EB	#CJK UNIFIED IDEOGRAPH
+0xC555	0x81EE	#CJK UNIFIED IDEOGRAPH
+0xC556	0x81EF	#CJK UNIFIED IDEOGRAPH
+0xC557	0x81F0	#CJK UNIFIED IDEOGRAPH
+0xC558	0x81F1	#CJK UNIFIED IDEOGRAPH
+0xC559	0x81F2	#CJK UNIFIED IDEOGRAPH
+0xC55A	0x81F5	#CJK UNIFIED IDEOGRAPH
+0xC55B	0x81F6	#CJK UNIFIED IDEOGRAPH
+0xC55C	0x81F7	#CJK UNIFIED IDEOGRAPH
+0xC55D	0x81F8	#CJK UNIFIED IDEOGRAPH
+0xC55E	0x81F9	#CJK UNIFIED IDEOGRAPH
+0xC55F	0x81FA	#CJK UNIFIED IDEOGRAPH
+0xC560	0x81FD	#CJK UNIFIED IDEOGRAPH
+0xC561	0x81FF	#CJK UNIFIED IDEOGRAPH
+0xC562	0x8203	#CJK UNIFIED IDEOGRAPH
+0xC563	0x8207	#CJK UNIFIED IDEOGRAPH
+0xC564	0x8208	#CJK UNIFIED IDEOGRAPH
+0xC565	0x8209	#CJK UNIFIED IDEOGRAPH
+0xC566	0x820A	#CJK UNIFIED IDEOGRAPH
+0xC567	0x820B	#CJK UNIFIED IDEOGRAPH
+0xC568	0x820E	#CJK UNIFIED IDEOGRAPH
+0xC569	0x820F	#CJK UNIFIED IDEOGRAPH
+0xC56A	0x8211	#CJK UNIFIED IDEOGRAPH
+0xC56B	0x8213	#CJK UNIFIED IDEOGRAPH
+0xC56C	0x8215	#CJK UNIFIED IDEOGRAPH
+0xC56D	0x8216	#CJK UNIFIED IDEOGRAPH
+0xC56E	0x8217	#CJK UNIFIED IDEOGRAPH
+0xC56F	0x8218	#CJK UNIFIED IDEOGRAPH
+0xC570	0x8219	#CJK UNIFIED IDEOGRAPH
+0xC571	0x821A	#CJK UNIFIED IDEOGRAPH
+0xC572	0x821D	#CJK UNIFIED IDEOGRAPH
+0xC573	0x8220	#CJK UNIFIED IDEOGRAPH
+0xC574	0x8224	#CJK UNIFIED IDEOGRAPH
+0xC575	0x8225	#CJK UNIFIED IDEOGRAPH
+0xC576	0x8226	#CJK UNIFIED IDEOGRAPH
+0xC577	0x8227	#CJK UNIFIED IDEOGRAPH
+0xC578	0x8229	#CJK UNIFIED IDEOGRAPH
+0xC579	0x822E	#CJK UNIFIED IDEOGRAPH
+0xC57A	0x8232	#CJK UNIFIED IDEOGRAPH
+0xC57B	0x823A	#CJK UNIFIED IDEOGRAPH
+0xC57C	0x823C	#CJK UNIFIED IDEOGRAPH
+0xC57D	0x823D	#CJK UNIFIED IDEOGRAPH
+0xC57E	0x823F	#CJK UNIFIED IDEOGRAPH
+0xC580	0x8240	#CJK UNIFIED IDEOGRAPH
+0xC581	0x8241	#CJK UNIFIED IDEOGRAPH
+0xC582	0x8242	#CJK UNIFIED IDEOGRAPH
+0xC583	0x8243	#CJK UNIFIED IDEOGRAPH
+0xC584	0x8245	#CJK UNIFIED IDEOGRAPH
+0xC585	0x8246	#CJK UNIFIED IDEOGRAPH
+0xC586	0x8248	#CJK UNIFIED IDEOGRAPH
+0xC587	0x824A	#CJK UNIFIED IDEOGRAPH
+0xC588	0x824C	#CJK UNIFIED IDEOGRAPH
+0xC589	0x824D	#CJK UNIFIED IDEOGRAPH
+0xC58A	0x824E	#CJK UNIFIED IDEOGRAPH
+0xC58B	0x8250	#CJK UNIFIED IDEOGRAPH
+0xC58C	0x8251	#CJK UNIFIED IDEOGRAPH
+0xC58D	0x8252	#CJK UNIFIED IDEOGRAPH
+0xC58E	0x8253	#CJK UNIFIED IDEOGRAPH
+0xC58F	0x8254	#CJK UNIFIED IDEOGRAPH
+0xC590	0x8255	#CJK UNIFIED IDEOGRAPH
+0xC591	0x8256	#CJK UNIFIED IDEOGRAPH
+0xC592	0x8257	#CJK UNIFIED IDEOGRAPH
+0xC593	0x8259	#CJK UNIFIED IDEOGRAPH
+0xC594	0x825B	#CJK UNIFIED IDEOGRAPH
+0xC595	0x825C	#CJK UNIFIED IDEOGRAPH
+0xC596	0x825D	#CJK UNIFIED IDEOGRAPH
+0xC597	0x825E	#CJK UNIFIED IDEOGRAPH
+0xC598	0x8260	#CJK UNIFIED IDEOGRAPH
+0xC599	0x8261	#CJK UNIFIED IDEOGRAPH
+0xC59A	0x8262	#CJK UNIFIED IDEOGRAPH
+0xC59B	0x8263	#CJK UNIFIED IDEOGRAPH
+0xC59C	0x8264	#CJK UNIFIED IDEOGRAPH
+0xC59D	0x8265	#CJK UNIFIED IDEOGRAPH
+0xC59E	0x8266	#CJK UNIFIED IDEOGRAPH
+0xC59F	0x8267	#CJK UNIFIED IDEOGRAPH
+0xC5A0	0x8269	#CJK UNIFIED IDEOGRAPH
+0xC5A1	0x62E7	#CJK UNIFIED IDEOGRAPH
+0xC5A2	0x6CDE	#CJK UNIFIED IDEOGRAPH
+0xC5A3	0x725B	#CJK UNIFIED IDEOGRAPH
+0xC5A4	0x626D	#CJK UNIFIED IDEOGRAPH
+0xC5A5	0x94AE	#CJK UNIFIED IDEOGRAPH
+0xC5A6	0x7EBD	#CJK UNIFIED IDEOGRAPH
+0xC5A7	0x8113	#CJK UNIFIED IDEOGRAPH
+0xC5A8	0x6D53	#CJK UNIFIED IDEOGRAPH
+0xC5A9	0x519C	#CJK UNIFIED IDEOGRAPH
+0xC5AA	0x5F04	#CJK UNIFIED IDEOGRAPH
+0xC5AB	0x5974	#CJK UNIFIED IDEOGRAPH
+0xC5AC	0x52AA	#CJK UNIFIED IDEOGRAPH
+0xC5AD	0x6012	#CJK UNIFIED IDEOGRAPH
+0xC5AE	0x5973	#CJK UNIFIED IDEOGRAPH
+0xC5AF	0x6696	#CJK UNIFIED IDEOGRAPH
+0xC5B0	0x8650	#CJK UNIFIED IDEOGRAPH
+0xC5B1	0x759F	#CJK UNIFIED IDEOGRAPH
+0xC5B2	0x632A	#CJK UNIFIED IDEOGRAPH
+0xC5B3	0x61E6	#CJK UNIFIED IDEOGRAPH
+0xC5B4	0x7CEF	#CJK UNIFIED IDEOGRAPH
+0xC5B5	0x8BFA	#CJK UNIFIED IDEOGRAPH
+0xC5B6	0x54E6	#CJK UNIFIED IDEOGRAPH
+0xC5B7	0x6B27	#CJK UNIFIED IDEOGRAPH
+0xC5B8	0x9E25	#CJK UNIFIED IDEOGRAPH
+0xC5B9	0x6BB4	#CJK UNIFIED IDEOGRAPH
+0xC5BA	0x85D5	#CJK UNIFIED IDEOGRAPH
+0xC5BB	0x5455	#CJK UNIFIED IDEOGRAPH
+0xC5BC	0x5076	#CJK UNIFIED IDEOGRAPH
+0xC5BD	0x6CA4	#CJK UNIFIED IDEOGRAPH
+0xC5BE	0x556A	#CJK UNIFIED IDEOGRAPH
+0xC5BF	0x8DB4	#CJK UNIFIED IDEOGRAPH
+0xC5C0	0x722C	#CJK UNIFIED IDEOGRAPH
+0xC5C1	0x5E15	#CJK UNIFIED IDEOGRAPH
+0xC5C2	0x6015	#CJK UNIFIED IDEOGRAPH
+0xC5C3	0x7436	#CJK UNIFIED IDEOGRAPH
+0xC5C4	0x62CD	#CJK UNIFIED IDEOGRAPH
+0xC5C5	0x6392	#CJK UNIFIED IDEOGRAPH
+0xC5C6	0x724C	#CJK UNIFIED IDEOGRAPH
+0xC5C7	0x5F98	#CJK UNIFIED IDEOGRAPH
+0xC5C8	0x6E43	#CJK UNIFIED IDEOGRAPH
+0xC5C9	0x6D3E	#CJK UNIFIED IDEOGRAPH
+0xC5CA	0x6500	#CJK UNIFIED IDEOGRAPH
+0xC5CB	0x6F58	#CJK UNIFIED IDEOGRAPH
+0xC5CC	0x76D8	#CJK UNIFIED IDEOGRAPH
+0xC5CD	0x78D0	#CJK UNIFIED IDEOGRAPH
+0xC5CE	0x76FC	#CJK UNIFIED IDEOGRAPH
+0xC5CF	0x7554	#CJK UNIFIED IDEOGRAPH
+0xC5D0	0x5224	#CJK UNIFIED IDEOGRAPH
+0xC5D1	0x53DB	#CJK UNIFIED IDEOGRAPH
+0xC5D2	0x4E53	#CJK UNIFIED IDEOGRAPH
+0xC5D3	0x5E9E	#CJK UNIFIED IDEOGRAPH
+0xC5D4	0x65C1	#CJK UNIFIED IDEOGRAPH
+0xC5D5	0x802A	#CJK UNIFIED IDEOGRAPH
+0xC5D6	0x80D6	#CJK UNIFIED IDEOGRAPH
+0xC5D7	0x629B	#CJK UNIFIED IDEOGRAPH
+0xC5D8	0x5486	#CJK UNIFIED IDEOGRAPH
+0xC5D9	0x5228	#CJK UNIFIED IDEOGRAPH
+0xC5DA	0x70AE	#CJK UNIFIED IDEOGRAPH
+0xC5DB	0x888D	#CJK UNIFIED IDEOGRAPH
+0xC5DC	0x8DD1	#CJK UNIFIED IDEOGRAPH
+0xC5DD	0x6CE1	#CJK UNIFIED IDEOGRAPH
+0xC5DE	0x5478	#CJK UNIFIED IDEOGRAPH
+0xC5DF	0x80DA	#CJK UNIFIED IDEOGRAPH
+0xC5E0	0x57F9	#CJK UNIFIED IDEOGRAPH
+0xC5E1	0x88F4	#CJK UNIFIED IDEOGRAPH
+0xC5E2	0x8D54	#CJK UNIFIED IDEOGRAPH
+0xC5E3	0x966A	#CJK UNIFIED IDEOGRAPH
+0xC5E4	0x914D	#CJK UNIFIED IDEOGRAPH
+0xC5E5	0x4F69	#CJK UNIFIED IDEOGRAPH
+0xC5E6	0x6C9B	#CJK UNIFIED IDEOGRAPH
+0xC5E7	0x55B7	#CJK UNIFIED IDEOGRAPH
+0xC5E8	0x76C6	#CJK UNIFIED IDEOGRAPH
+0xC5E9	0x7830	#CJK UNIFIED IDEOGRAPH
+0xC5EA	0x62A8	#CJK UNIFIED IDEOGRAPH
+0xC5EB	0x70F9	#CJK UNIFIED IDEOGRAPH
+0xC5EC	0x6F8E	#CJK UNIFIED IDEOGRAPH
+0xC5ED	0x5F6D	#CJK UNIFIED IDEOGRAPH
+0xC5EE	0x84EC	#CJK UNIFIED IDEOGRAPH
+0xC5EF	0x68DA	#CJK UNIFIED IDEOGRAPH
+0xC5F0	0x787C	#CJK UNIFIED IDEOGRAPH
+0xC5F1	0x7BF7	#CJK UNIFIED IDEOGRAPH
+0xC5F2	0x81A8	#CJK UNIFIED IDEOGRAPH
+0xC5F3	0x670B	#CJK UNIFIED IDEOGRAPH
+0xC5F4	0x9E4F	#CJK UNIFIED IDEOGRAPH
+0xC5F5	0x6367	#CJK UNIFIED IDEOGRAPH
+0xC5F6	0x78B0	#CJK UNIFIED IDEOGRAPH
+0xC5F7	0x576F	#CJK UNIFIED IDEOGRAPH
+0xC5F8	0x7812	#CJK UNIFIED IDEOGRAPH
+0xC5F9	0x9739	#CJK UNIFIED IDEOGRAPH
+0xC5FA	0x6279	#CJK UNIFIED IDEOGRAPH
+0xC5FB	0x62AB	#CJK UNIFIED IDEOGRAPH
+0xC5FC	0x5288	#CJK UNIFIED IDEOGRAPH
+0xC5FD	0x7435	#CJK UNIFIED IDEOGRAPH
+0xC5FE	0x6BD7	#CJK UNIFIED IDEOGRAPH
+0xC640	0x826A	#CJK UNIFIED IDEOGRAPH
+0xC641	0x826B	#CJK UNIFIED IDEOGRAPH
+0xC642	0x826C	#CJK UNIFIED IDEOGRAPH
+0xC643	0x826D	#CJK UNIFIED IDEOGRAPH
+0xC644	0x8271	#CJK UNIFIED IDEOGRAPH
+0xC645	0x8275	#CJK UNIFIED IDEOGRAPH
+0xC646	0x8276	#CJK UNIFIED IDEOGRAPH
+0xC647	0x8277	#CJK UNIFIED IDEOGRAPH
+0xC648	0x8278	#CJK UNIFIED IDEOGRAPH
+0xC649	0x827B	#CJK UNIFIED IDEOGRAPH
+0xC64A	0x827C	#CJK UNIFIED IDEOGRAPH
+0xC64B	0x8280	#CJK UNIFIED IDEOGRAPH
+0xC64C	0x8281	#CJK UNIFIED IDEOGRAPH
+0xC64D	0x8283	#CJK UNIFIED IDEOGRAPH
+0xC64E	0x8285	#CJK UNIFIED IDEOGRAPH
+0xC64F	0x8286	#CJK UNIFIED IDEOGRAPH
+0xC650	0x8287	#CJK UNIFIED IDEOGRAPH
+0xC651	0x8289	#CJK UNIFIED IDEOGRAPH
+0xC652	0x828C	#CJK UNIFIED IDEOGRAPH
+0xC653	0x8290	#CJK UNIFIED IDEOGRAPH
+0xC654	0x8293	#CJK UNIFIED IDEOGRAPH
+0xC655	0x8294	#CJK UNIFIED IDEOGRAPH
+0xC656	0x8295	#CJK UNIFIED IDEOGRAPH
+0xC657	0x8296	#CJK UNIFIED IDEOGRAPH
+0xC658	0x829A	#CJK UNIFIED IDEOGRAPH
+0xC659	0x829B	#CJK UNIFIED IDEOGRAPH
+0xC65A	0x829E	#CJK UNIFIED IDEOGRAPH
+0xC65B	0x82A0	#CJK UNIFIED IDEOGRAPH
+0xC65C	0x82A2	#CJK UNIFIED IDEOGRAPH
+0xC65D	0x82A3	#CJK UNIFIED IDEOGRAPH
+0xC65E	0x82A7	#CJK UNIFIED IDEOGRAPH
+0xC65F	0x82B2	#CJK UNIFIED IDEOGRAPH
+0xC660	0x82B5	#CJK UNIFIED IDEOGRAPH
+0xC661	0x82B6	#CJK UNIFIED IDEOGRAPH
+0xC662	0x82BA	#CJK UNIFIED IDEOGRAPH
+0xC663	0x82BB	#CJK UNIFIED IDEOGRAPH
+0xC664	0x82BC	#CJK UNIFIED IDEOGRAPH
+0xC665	0x82BF	#CJK UNIFIED IDEOGRAPH
+0xC666	0x82C0	#CJK UNIFIED IDEOGRAPH
+0xC667	0x82C2	#CJK UNIFIED IDEOGRAPH
+0xC668	0x82C3	#CJK UNIFIED IDEOGRAPH
+0xC669	0x82C5	#CJK UNIFIED IDEOGRAPH
+0xC66A	0x82C6	#CJK UNIFIED IDEOGRAPH
+0xC66B	0x82C9	#CJK UNIFIED IDEOGRAPH
+0xC66C	0x82D0	#CJK UNIFIED IDEOGRAPH
+0xC66D	0x82D6	#CJK UNIFIED IDEOGRAPH
+0xC66E	0x82D9	#CJK UNIFIED IDEOGRAPH
+0xC66F	0x82DA	#CJK UNIFIED IDEOGRAPH
+0xC670	0x82DD	#CJK UNIFIED IDEOGRAPH
+0xC671	0x82E2	#CJK UNIFIED IDEOGRAPH
+0xC672	0x82E7	#CJK UNIFIED IDEOGRAPH
+0xC673	0x82E8	#CJK UNIFIED IDEOGRAPH
+0xC674	0x82E9	#CJK UNIFIED IDEOGRAPH
+0xC675	0x82EA	#CJK UNIFIED IDEOGRAPH
+0xC676	0x82EC	#CJK UNIFIED IDEOGRAPH
+0xC677	0x82ED	#CJK UNIFIED IDEOGRAPH
+0xC678	0x82EE	#CJK UNIFIED IDEOGRAPH
+0xC679	0x82F0	#CJK UNIFIED IDEOGRAPH
+0xC67A	0x82F2	#CJK UNIFIED IDEOGRAPH
+0xC67B	0x82F3	#CJK UNIFIED IDEOGRAPH
+0xC67C	0x82F5	#CJK UNIFIED IDEOGRAPH
+0xC67D	0x82F6	#CJK UNIFIED IDEOGRAPH
+0xC67E	0x82F8	#CJK UNIFIED IDEOGRAPH
+0xC680	0x82FA	#CJK UNIFIED IDEOGRAPH
+0xC681	0x82FC	#CJK UNIFIED IDEOGRAPH
+0xC682	0x82FD	#CJK UNIFIED IDEOGRAPH
+0xC683	0x82FE	#CJK UNIFIED IDEOGRAPH
+0xC684	0x82FF	#CJK UNIFIED IDEOGRAPH
+0xC685	0x8300	#CJK UNIFIED IDEOGRAPH
+0xC686	0x830A	#CJK UNIFIED IDEOGRAPH
+0xC687	0x830B	#CJK UNIFIED IDEOGRAPH
+0xC688	0x830D	#CJK UNIFIED IDEOGRAPH
+0xC689	0x8310	#CJK UNIFIED IDEOGRAPH
+0xC68A	0x8312	#CJK UNIFIED IDEOGRAPH
+0xC68B	0x8313	#CJK UNIFIED IDEOGRAPH
+0xC68C	0x8316	#CJK UNIFIED IDEOGRAPH
+0xC68D	0x8318	#CJK UNIFIED IDEOGRAPH
+0xC68E	0x8319	#CJK UNIFIED IDEOGRAPH
+0xC68F	0x831D	#CJK UNIFIED IDEOGRAPH
+0xC690	0x831E	#CJK UNIFIED IDEOGRAPH
+0xC691	0x831F	#CJK UNIFIED IDEOGRAPH
+0xC692	0x8320	#CJK UNIFIED IDEOGRAPH
+0xC693	0x8321	#CJK UNIFIED IDEOGRAPH
+0xC694	0x8322	#CJK UNIFIED IDEOGRAPH
+0xC695	0x8323	#CJK UNIFIED IDEOGRAPH
+0xC696	0x8324	#CJK UNIFIED IDEOGRAPH
+0xC697	0x8325	#CJK UNIFIED IDEOGRAPH
+0xC698	0x8326	#CJK UNIFIED IDEOGRAPH
+0xC699	0x8329	#CJK UNIFIED IDEOGRAPH
+0xC69A	0x832A	#CJK UNIFIED IDEOGRAPH
+0xC69B	0x832E	#CJK UNIFIED IDEOGRAPH
+0xC69C	0x8330	#CJK UNIFIED IDEOGRAPH
+0xC69D	0x8332	#CJK UNIFIED IDEOGRAPH
+0xC69E	0x8337	#CJK UNIFIED IDEOGRAPH
+0xC69F	0x833B	#CJK UNIFIED IDEOGRAPH
+0xC6A0	0x833D	#CJK UNIFIED IDEOGRAPH
+0xC6A1	0x5564	#CJK UNIFIED IDEOGRAPH
+0xC6A2	0x813E	#CJK UNIFIED IDEOGRAPH
+0xC6A3	0x75B2	#CJK UNIFIED IDEOGRAPH
+0xC6A4	0x76AE	#CJK UNIFIED IDEOGRAPH
+0xC6A5	0x5339	#CJK UNIFIED IDEOGRAPH
+0xC6A6	0x75DE	#CJK UNIFIED IDEOGRAPH
+0xC6A7	0x50FB	#CJK UNIFIED IDEOGRAPH
+0xC6A8	0x5C41	#CJK UNIFIED IDEOGRAPH
+0xC6A9	0x8B6C	#CJK UNIFIED IDEOGRAPH
+0xC6AA	0x7BC7	#CJK UNIFIED IDEOGRAPH
+0xC6AB	0x504F	#CJK UNIFIED IDEOGRAPH
+0xC6AC	0x7247	#CJK UNIFIED IDEOGRAPH
+0xC6AD	0x9A97	#CJK UNIFIED IDEOGRAPH
+0xC6AE	0x98D8	#CJK UNIFIED IDEOGRAPH
+0xC6AF	0x6F02	#CJK UNIFIED IDEOGRAPH
+0xC6B0	0x74E2	#CJK UNIFIED IDEOGRAPH
+0xC6B1	0x7968	#CJK UNIFIED IDEOGRAPH
+0xC6B2	0x6487	#CJK UNIFIED IDEOGRAPH
+0xC6B3	0x77A5	#CJK UNIFIED IDEOGRAPH
+0xC6B4	0x62FC	#CJK UNIFIED IDEOGRAPH
+0xC6B5	0x9891	#CJK UNIFIED IDEOGRAPH
+0xC6B6	0x8D2B	#CJK UNIFIED IDEOGRAPH
+0xC6B7	0x54C1	#CJK UNIFIED IDEOGRAPH
+0xC6B8	0x8058	#CJK UNIFIED IDEOGRAPH
+0xC6B9	0x4E52	#CJK UNIFIED IDEOGRAPH
+0xC6BA	0x576A	#CJK UNIFIED IDEOGRAPH
+0xC6BB	0x82F9	#CJK UNIFIED IDEOGRAPH
+0xC6BC	0x840D	#CJK UNIFIED IDEOGRAPH
+0xC6BD	0x5E73	#CJK UNIFIED IDEOGRAPH
+0xC6BE	0x51ED	#CJK UNIFIED IDEOGRAPH
+0xC6BF	0x74F6	#CJK UNIFIED IDEOGRAPH
+0xC6C0	0x8BC4	#CJK UNIFIED IDEOGRAPH
+0xC6C1	0x5C4F	#CJK UNIFIED IDEOGRAPH
+0xC6C2	0x5761	#CJK UNIFIED IDEOGRAPH
+0xC6C3	0x6CFC	#CJK UNIFIED IDEOGRAPH
+0xC6C4	0x9887	#CJK UNIFIED IDEOGRAPH
+0xC6C5	0x5A46	#CJK UNIFIED IDEOGRAPH
+0xC6C6	0x7834	#CJK UNIFIED IDEOGRAPH
+0xC6C7	0x9B44	#CJK UNIFIED IDEOGRAPH
+0xC6C8	0x8FEB	#CJK UNIFIED IDEOGRAPH
+0xC6C9	0x7C95	#CJK UNIFIED IDEOGRAPH
+0xC6CA	0x5256	#CJK UNIFIED IDEOGRAPH
+0xC6CB	0x6251	#CJK UNIFIED IDEOGRAPH
+0xC6CC	0x94FA	#CJK UNIFIED IDEOGRAPH
+0xC6CD	0x4EC6	#CJK UNIFIED IDEOGRAPH
+0xC6CE	0x8386	#CJK UNIFIED IDEOGRAPH
+0xC6CF	0x8461	#CJK UNIFIED IDEOGRAPH
+0xC6D0	0x83E9	#CJK UNIFIED IDEOGRAPH
+0xC6D1	0x84B2	#CJK UNIFIED IDEOGRAPH
+0xC6D2	0x57D4	#CJK UNIFIED IDEOGRAPH
+0xC6D3	0x6734	#CJK UNIFIED IDEOGRAPH
+0xC6D4	0x5703	#CJK UNIFIED IDEOGRAPH
+0xC6D5	0x666E	#CJK UNIFIED IDEOGRAPH
+0xC6D6	0x6D66	#CJK UNIFIED IDEOGRAPH
+0xC6D7	0x8C31	#CJK UNIFIED IDEOGRAPH
+0xC6D8	0x66DD	#CJK UNIFIED IDEOGRAPH
+0xC6D9	0x7011	#CJK UNIFIED IDEOGRAPH
+0xC6DA	0x671F	#CJK UNIFIED IDEOGRAPH
+0xC6DB	0x6B3A	#CJK UNIFIED IDEOGRAPH
+0xC6DC	0x6816	#CJK UNIFIED IDEOGRAPH
+0xC6DD	0x621A	#CJK UNIFIED IDEOGRAPH
+0xC6DE	0x59BB	#CJK UNIFIED IDEOGRAPH
+0xC6DF	0x4E03	#CJK UNIFIED IDEOGRAPH
+0xC6E0	0x51C4	#CJK UNIFIED IDEOGRAPH
+0xC6E1	0x6F06	#CJK UNIFIED IDEOGRAPH
+0xC6E2	0x67D2	#CJK UNIFIED IDEOGRAPH
+0xC6E3	0x6C8F	#CJK UNIFIED IDEOGRAPH
+0xC6E4	0x5176	#CJK UNIFIED IDEOGRAPH
+0xC6E5	0x68CB	#CJK UNIFIED IDEOGRAPH
+0xC6E6	0x5947	#CJK UNIFIED IDEOGRAPH
+0xC6E7	0x6B67	#CJK UNIFIED IDEOGRAPH
+0xC6E8	0x7566	#CJK UNIFIED IDEOGRAPH
+0xC6E9	0x5D0E	#CJK UNIFIED IDEOGRAPH
+0xC6EA	0x8110	#CJK UNIFIED IDEOGRAPH
+0xC6EB	0x9F50	#CJK UNIFIED IDEOGRAPH
+0xC6EC	0x65D7	#CJK UNIFIED IDEOGRAPH
+0xC6ED	0x7948	#CJK UNIFIED IDEOGRAPH
+0xC6EE	0x7941	#CJK UNIFIED IDEOGRAPH
+0xC6EF	0x9A91	#CJK UNIFIED IDEOGRAPH
+0xC6F0	0x8D77	#CJK UNIFIED IDEOGRAPH
+0xC6F1	0x5C82	#CJK UNIFIED IDEOGRAPH
+0xC6F2	0x4E5E	#CJK UNIFIED IDEOGRAPH
+0xC6F3	0x4F01	#CJK UNIFIED IDEOGRAPH
+0xC6F4	0x542F	#CJK UNIFIED IDEOGRAPH
+0xC6F5	0x5951	#CJK UNIFIED IDEOGRAPH
+0xC6F6	0x780C	#CJK UNIFIED IDEOGRAPH
+0xC6F7	0x5668	#CJK UNIFIED IDEOGRAPH
+0xC6F8	0x6C14	#CJK UNIFIED IDEOGRAPH
+0xC6F9	0x8FC4	#CJK UNIFIED IDEOGRAPH
+0xC6FA	0x5F03	#CJK UNIFIED IDEOGRAPH
+0xC6FB	0x6C7D	#CJK UNIFIED IDEOGRAPH
+0xC6FC	0x6CE3	#CJK UNIFIED IDEOGRAPH
+0xC6FD	0x8BAB	#CJK UNIFIED IDEOGRAPH
+0xC6FE	0x6390	#CJK UNIFIED IDEOGRAPH
+0xC740	0x833E	#CJK UNIFIED IDEOGRAPH
+0xC741	0x833F	#CJK UNIFIED IDEOGRAPH
+0xC742	0x8341	#CJK UNIFIED IDEOGRAPH
+0xC743	0x8342	#CJK UNIFIED IDEOGRAPH
+0xC744	0x8344	#CJK UNIFIED IDEOGRAPH
+0xC745	0x8345	#CJK UNIFIED IDEOGRAPH
+0xC746	0x8348	#CJK UNIFIED IDEOGRAPH
+0xC747	0x834A	#CJK UNIFIED IDEOGRAPH
+0xC748	0x834B	#CJK UNIFIED IDEOGRAPH
+0xC749	0x834C	#CJK UNIFIED IDEOGRAPH
+0xC74A	0x834D	#CJK UNIFIED IDEOGRAPH
+0xC74B	0x834E	#CJK UNIFIED IDEOGRAPH
+0xC74C	0x8353	#CJK UNIFIED IDEOGRAPH
+0xC74D	0x8355	#CJK UNIFIED IDEOGRAPH
+0xC74E	0x8356	#CJK UNIFIED IDEOGRAPH
+0xC74F	0x8357	#CJK UNIFIED IDEOGRAPH
+0xC750	0x8358	#CJK UNIFIED IDEOGRAPH
+0xC751	0x8359	#CJK UNIFIED IDEOGRAPH
+0xC752	0x835D	#CJK UNIFIED IDEOGRAPH
+0xC753	0x8362	#CJK UNIFIED IDEOGRAPH
+0xC754	0x8370	#CJK UNIFIED IDEOGRAPH
+0xC755	0x8371	#CJK UNIFIED IDEOGRAPH
+0xC756	0x8372	#CJK UNIFIED IDEOGRAPH
+0xC757	0x8373	#CJK UNIFIED IDEOGRAPH
+0xC758	0x8374	#CJK UNIFIED IDEOGRAPH
+0xC759	0x8375	#CJK UNIFIED IDEOGRAPH
+0xC75A	0x8376	#CJK UNIFIED IDEOGRAPH
+0xC75B	0x8379	#CJK UNIFIED IDEOGRAPH
+0xC75C	0x837A	#CJK UNIFIED IDEOGRAPH
+0xC75D	0x837E	#CJK UNIFIED IDEOGRAPH
+0xC75E	0x837F	#CJK UNIFIED IDEOGRAPH
+0xC75F	0x8380	#CJK UNIFIED IDEOGRAPH
+0xC760	0x8381	#CJK UNIFIED IDEOGRAPH
+0xC761	0x8382	#CJK UNIFIED IDEOGRAPH
+0xC762	0x8383	#CJK UNIFIED IDEOGRAPH
+0xC763	0x8384	#CJK UNIFIED IDEOGRAPH
+0xC764	0x8387	#CJK UNIFIED IDEOGRAPH
+0xC765	0x8388	#CJK UNIFIED IDEOGRAPH
+0xC766	0x838A	#CJK UNIFIED IDEOGRAPH
+0xC767	0x838B	#CJK UNIFIED IDEOGRAPH
+0xC768	0x838C	#CJK UNIFIED IDEOGRAPH
+0xC769	0x838D	#CJK UNIFIED IDEOGRAPH
+0xC76A	0x838F	#CJK UNIFIED IDEOGRAPH
+0xC76B	0x8390	#CJK UNIFIED IDEOGRAPH
+0xC76C	0x8391	#CJK UNIFIED IDEOGRAPH
+0xC76D	0x8394	#CJK UNIFIED IDEOGRAPH
+0xC76E	0x8395	#CJK UNIFIED IDEOGRAPH
+0xC76F	0x8396	#CJK UNIFIED IDEOGRAPH
+0xC770	0x8397	#CJK UNIFIED IDEOGRAPH
+0xC771	0x8399	#CJK UNIFIED IDEOGRAPH
+0xC772	0x839A	#CJK UNIFIED IDEOGRAPH
+0xC773	0x839D	#CJK UNIFIED IDEOGRAPH
+0xC774	0x839F	#CJK UNIFIED IDEOGRAPH
+0xC775	0x83A1	#CJK UNIFIED IDEOGRAPH
+0xC776	0x83A2	#CJK UNIFIED IDEOGRAPH
+0xC777	0x83A3	#CJK UNIFIED IDEOGRAPH
+0xC778	0x83A4	#CJK UNIFIED IDEOGRAPH
+0xC779	0x83A5	#CJK UNIFIED IDEOGRAPH
+0xC77A	0x83A6	#CJK UNIFIED IDEOGRAPH
+0xC77B	0x83A7	#CJK UNIFIED IDEOGRAPH
+0xC77C	0x83AC	#CJK UNIFIED IDEOGRAPH
+0xC77D	0x83AD	#CJK UNIFIED IDEOGRAPH
+0xC77E	0x83AE	#CJK UNIFIED IDEOGRAPH
+0xC780	0x83AF	#CJK UNIFIED IDEOGRAPH
+0xC781	0x83B5	#CJK UNIFIED IDEOGRAPH
+0xC782	0x83BB	#CJK UNIFIED IDEOGRAPH
+0xC783	0x83BE	#CJK UNIFIED IDEOGRAPH
+0xC784	0x83BF	#CJK UNIFIED IDEOGRAPH
+0xC785	0x83C2	#CJK UNIFIED IDEOGRAPH
+0xC786	0x83C3	#CJK UNIFIED IDEOGRAPH
+0xC787	0x83C4	#CJK UNIFIED IDEOGRAPH
+0xC788	0x83C6	#CJK UNIFIED IDEOGRAPH
+0xC789	0x83C8	#CJK UNIFIED IDEOGRAPH
+0xC78A	0x83C9	#CJK UNIFIED IDEOGRAPH
+0xC78B	0x83CB	#CJK UNIFIED IDEOGRAPH
+0xC78C	0x83CD	#CJK UNIFIED IDEOGRAPH
+0xC78D	0x83CE	#CJK UNIFIED IDEOGRAPH
+0xC78E	0x83D0	#CJK UNIFIED IDEOGRAPH
+0xC78F	0x83D1	#CJK UNIFIED IDEOGRAPH
+0xC790	0x83D2	#CJK UNIFIED IDEOGRAPH
+0xC791	0x83D3	#CJK UNIFIED IDEOGRAPH
+0xC792	0x83D5	#CJK UNIFIED IDEOGRAPH
+0xC793	0x83D7	#CJK UNIFIED IDEOGRAPH
+0xC794	0x83D9	#CJK UNIFIED IDEOGRAPH
+0xC795	0x83DA	#CJK UNIFIED IDEOGRAPH
+0xC796	0x83DB	#CJK UNIFIED IDEOGRAPH
+0xC797	0x83DE	#CJK UNIFIED IDEOGRAPH
+0xC798	0x83E2	#CJK UNIFIED IDEOGRAPH
+0xC799	0x83E3	#CJK UNIFIED IDEOGRAPH
+0xC79A	0x83E4	#CJK UNIFIED IDEOGRAPH
+0xC79B	0x83E6	#CJK UNIFIED IDEOGRAPH
+0xC79C	0x83E7	#CJK UNIFIED IDEOGRAPH
+0xC79D	0x83E8	#CJK UNIFIED IDEOGRAPH
+0xC79E	0x83EB	#CJK UNIFIED IDEOGRAPH
+0xC79F	0x83EC	#CJK UNIFIED IDEOGRAPH
+0xC7A0	0x83ED	#CJK UNIFIED IDEOGRAPH
+0xC7A1	0x6070	#CJK UNIFIED IDEOGRAPH
+0xC7A2	0x6D3D	#CJK UNIFIED IDEOGRAPH
+0xC7A3	0x7275	#CJK UNIFIED IDEOGRAPH
+0xC7A4	0x6266	#CJK UNIFIED IDEOGRAPH
+0xC7A5	0x948E	#CJK UNIFIED IDEOGRAPH
+0xC7A6	0x94C5	#CJK UNIFIED IDEOGRAPH
+0xC7A7	0x5343	#CJK UNIFIED IDEOGRAPH
+0xC7A8	0x8FC1	#CJK UNIFIED IDEOGRAPH
+0xC7A9	0x7B7E	#CJK UNIFIED IDEOGRAPH
+0xC7AA	0x4EDF	#CJK UNIFIED IDEOGRAPH
+0xC7AB	0x8C26	#CJK UNIFIED IDEOGRAPH
+0xC7AC	0x4E7E	#CJK UNIFIED IDEOGRAPH
+0xC7AD	0x9ED4	#CJK UNIFIED IDEOGRAPH
+0xC7AE	0x94B1	#CJK UNIFIED IDEOGRAPH
+0xC7AF	0x94B3	#CJK UNIFIED IDEOGRAPH
+0xC7B0	0x524D	#CJK UNIFIED IDEOGRAPH
+0xC7B1	0x6F5C	#CJK UNIFIED IDEOGRAPH
+0xC7B2	0x9063	#CJK UNIFIED IDEOGRAPH
+0xC7B3	0x6D45	#CJK UNIFIED IDEOGRAPH
+0xC7B4	0x8C34	#CJK UNIFIED IDEOGRAPH
+0xC7B5	0x5811	#CJK UNIFIED IDEOGRAPH
+0xC7B6	0x5D4C	#CJK UNIFIED IDEOGRAPH
+0xC7B7	0x6B20	#CJK UNIFIED IDEOGRAPH
+0xC7B8	0x6B49	#CJK UNIFIED IDEOGRAPH
+0xC7B9	0x67AA	#CJK UNIFIED IDEOGRAPH
+0xC7BA	0x545B	#CJK UNIFIED IDEOGRAPH
+0xC7BB	0x8154	#CJK UNIFIED IDEOGRAPH
+0xC7BC	0x7F8C	#CJK UNIFIED IDEOGRAPH
+0xC7BD	0x5899	#CJK UNIFIED IDEOGRAPH
+0xC7BE	0x8537	#CJK UNIFIED IDEOGRAPH
+0xC7BF	0x5F3A	#CJK UNIFIED IDEOGRAPH
+0xC7C0	0x62A2	#CJK UNIFIED IDEOGRAPH
+0xC7C1	0x6A47	#CJK UNIFIED IDEOGRAPH
+0xC7C2	0x9539	#CJK UNIFIED IDEOGRAPH
+0xC7C3	0x6572	#CJK UNIFIED IDEOGRAPH
+0xC7C4	0x6084	#CJK UNIFIED IDEOGRAPH
+0xC7C5	0x6865	#CJK UNIFIED IDEOGRAPH
+0xC7C6	0x77A7	#CJK UNIFIED IDEOGRAPH
+0xC7C7	0x4E54	#CJK UNIFIED IDEOGRAPH
+0xC7C8	0x4FA8	#CJK UNIFIED IDEOGRAPH
+0xC7C9	0x5DE7	#CJK UNIFIED IDEOGRAPH
+0xC7CA	0x9798	#CJK UNIFIED IDEOGRAPH
+0xC7CB	0x64AC	#CJK UNIFIED IDEOGRAPH
+0xC7CC	0x7FD8	#CJK UNIFIED IDEOGRAPH
+0xC7CD	0x5CED	#CJK UNIFIED IDEOGRAPH
+0xC7CE	0x4FCF	#CJK UNIFIED IDEOGRAPH
+0xC7CF	0x7A8D	#CJK UNIFIED IDEOGRAPH
+0xC7D0	0x5207	#CJK UNIFIED IDEOGRAPH
+0xC7D1	0x8304	#CJK UNIFIED IDEOGRAPH
+0xC7D2	0x4E14	#CJK UNIFIED IDEOGRAPH
+0xC7D3	0x602F	#CJK UNIFIED IDEOGRAPH
+0xC7D4	0x7A83	#CJK UNIFIED IDEOGRAPH
+0xC7D5	0x94A6	#CJK UNIFIED IDEOGRAPH
+0xC7D6	0x4FB5	#CJK UNIFIED IDEOGRAPH
+0xC7D7	0x4EB2	#CJK UNIFIED IDEOGRAPH
+0xC7D8	0x79E6	#CJK UNIFIED IDEOGRAPH
+0xC7D9	0x7434	#CJK UNIFIED IDEOGRAPH
+0xC7DA	0x52E4	#CJK UNIFIED IDEOGRAPH
+0xC7DB	0x82B9	#CJK UNIFIED IDEOGRAPH
+0xC7DC	0x64D2	#CJK UNIFIED IDEOGRAPH
+0xC7DD	0x79BD	#CJK UNIFIED IDEOGRAPH
+0xC7DE	0x5BDD	#CJK UNIFIED IDEOGRAPH
+0xC7DF	0x6C81	#CJK UNIFIED IDEOGRAPH
+0xC7E0	0x9752	#CJK UNIFIED IDEOGRAPH
+0xC7E1	0x8F7B	#CJK UNIFIED IDEOGRAPH
+0xC7E2	0x6C22	#CJK UNIFIED IDEOGRAPH
+0xC7E3	0x503E	#CJK UNIFIED IDEOGRAPH
+0xC7E4	0x537F	#CJK UNIFIED IDEOGRAPH
+0xC7E5	0x6E05	#CJK UNIFIED IDEOGRAPH
+0xC7E6	0x64CE	#CJK UNIFIED IDEOGRAPH
+0xC7E7	0x6674	#CJK UNIFIED IDEOGRAPH
+0xC7E8	0x6C30	#CJK UNIFIED IDEOGRAPH
+0xC7E9	0x60C5	#CJK UNIFIED IDEOGRAPH
+0xC7EA	0x9877	#CJK UNIFIED IDEOGRAPH
+0xC7EB	0x8BF7	#CJK UNIFIED IDEOGRAPH
+0xC7EC	0x5E86	#CJK UNIFIED IDEOGRAPH
+0xC7ED	0x743C	#CJK UNIFIED IDEOGRAPH
+0xC7EE	0x7A77	#CJK UNIFIED IDEOGRAPH
+0xC7EF	0x79CB	#CJK UNIFIED IDEOGRAPH
+0xC7F0	0x4E18	#CJK UNIFIED IDEOGRAPH
+0xC7F1	0x90B1	#CJK UNIFIED IDEOGRAPH
+0xC7F2	0x7403	#CJK UNIFIED IDEOGRAPH
+0xC7F3	0x6C42	#CJK UNIFIED IDEOGRAPH
+0xC7F4	0x56DA	#CJK UNIFIED IDEOGRAPH
+0xC7F5	0x914B	#CJK UNIFIED IDEOGRAPH
+0xC7F6	0x6CC5	#CJK UNIFIED IDEOGRAPH
+0xC7F7	0x8D8B	#CJK UNIFIED IDEOGRAPH
+0xC7F8	0x533A	#CJK UNIFIED IDEOGRAPH
+0xC7F9	0x86C6	#CJK UNIFIED IDEOGRAPH
+0xC7FA	0x66F2	#CJK UNIFIED IDEOGRAPH
+0xC7FB	0x8EAF	#CJK UNIFIED IDEOGRAPH
+0xC7FC	0x5C48	#CJK UNIFIED IDEOGRAPH
+0xC7FD	0x9A71	#CJK UNIFIED IDEOGRAPH
+0xC7FE	0x6E20	#CJK UNIFIED IDEOGRAPH
+0xC840	0x83EE	#CJK UNIFIED IDEOGRAPH
+0xC841	0x83EF	#CJK UNIFIED IDEOGRAPH
+0xC842	0x83F3	#CJK UNIFIED IDEOGRAPH
+0xC843	0x83F4	#CJK UNIFIED IDEOGRAPH
+0xC844	0x83F5	#CJK UNIFIED IDEOGRAPH
+0xC845	0x83F6	#CJK UNIFIED IDEOGRAPH
+0xC846	0x83F7	#CJK UNIFIED IDEOGRAPH
+0xC847	0x83FA	#CJK UNIFIED IDEOGRAPH
+0xC848	0x83FB	#CJK UNIFIED IDEOGRAPH
+0xC849	0x83FC	#CJK UNIFIED IDEOGRAPH
+0xC84A	0x83FE	#CJK UNIFIED IDEOGRAPH
+0xC84B	0x83FF	#CJK UNIFIED IDEOGRAPH
+0xC84C	0x8400	#CJK UNIFIED IDEOGRAPH
+0xC84D	0x8402	#CJK UNIFIED IDEOGRAPH
+0xC84E	0x8405	#CJK UNIFIED IDEOGRAPH
+0xC84F	0x8407	#CJK UNIFIED IDEOGRAPH
+0xC850	0x8408	#CJK UNIFIED IDEOGRAPH
+0xC851	0x8409	#CJK UNIFIED IDEOGRAPH
+0xC852	0x840A	#CJK UNIFIED IDEOGRAPH
+0xC853	0x8410	#CJK UNIFIED IDEOGRAPH
+0xC854	0x8412	#CJK UNIFIED IDEOGRAPH
+0xC855	0x8413	#CJK UNIFIED IDEOGRAPH
+0xC856	0x8414	#CJK UNIFIED IDEOGRAPH
+0xC857	0x8415	#CJK UNIFIED IDEOGRAPH
+0xC858	0x8416	#CJK UNIFIED IDEOGRAPH
+0xC859	0x8417	#CJK UNIFIED IDEOGRAPH
+0xC85A	0x8419	#CJK UNIFIED IDEOGRAPH
+0xC85B	0x841A	#CJK UNIFIED IDEOGRAPH
+0xC85C	0x841B	#CJK UNIFIED IDEOGRAPH
+0xC85D	0x841E	#CJK UNIFIED IDEOGRAPH
+0xC85E	0x841F	#CJK UNIFIED IDEOGRAPH
+0xC85F	0x8420	#CJK UNIFIED IDEOGRAPH
+0xC860	0x8421	#CJK UNIFIED IDEOGRAPH
+0xC861	0x8422	#CJK UNIFIED IDEOGRAPH
+0xC862	0x8423	#CJK UNIFIED IDEOGRAPH
+0xC863	0x8429	#CJK UNIFIED IDEOGRAPH
+0xC864	0x842A	#CJK UNIFIED IDEOGRAPH
+0xC865	0x842B	#CJK UNIFIED IDEOGRAPH
+0xC866	0x842C	#CJK UNIFIED IDEOGRAPH
+0xC867	0x842D	#CJK UNIFIED IDEOGRAPH
+0xC868	0x842E	#CJK UNIFIED IDEOGRAPH
+0xC869	0x842F	#CJK UNIFIED IDEOGRAPH
+0xC86A	0x8430	#CJK UNIFIED IDEOGRAPH
+0xC86B	0x8432	#CJK UNIFIED IDEOGRAPH
+0xC86C	0x8433	#CJK UNIFIED IDEOGRAPH
+0xC86D	0x8434	#CJK UNIFIED IDEOGRAPH
+0xC86E	0x8435	#CJK UNIFIED IDEOGRAPH
+0xC86F	0x8436	#CJK UNIFIED IDEOGRAPH
+0xC870	0x8437	#CJK UNIFIED IDEOGRAPH
+0xC871	0x8439	#CJK UNIFIED IDEOGRAPH
+0xC872	0x843A	#CJK UNIFIED IDEOGRAPH
+0xC873	0x843B	#CJK UNIFIED IDEOGRAPH
+0xC874	0x843E	#CJK UNIFIED IDEOGRAPH
+0xC875	0x843F	#CJK UNIFIED IDEOGRAPH
+0xC876	0x8440	#CJK UNIFIED IDEOGRAPH
+0xC877	0x8441	#CJK UNIFIED IDEOGRAPH
+0xC878	0x8442	#CJK UNIFIED IDEOGRAPH
+0xC879	0x8443	#CJK UNIFIED IDEOGRAPH
+0xC87A	0x8444	#CJK UNIFIED IDEOGRAPH
+0xC87B	0x8445	#CJK UNIFIED IDEOGRAPH
+0xC87C	0x8447	#CJK UNIFIED IDEOGRAPH
+0xC87D	0x8448	#CJK UNIFIED IDEOGRAPH
+0xC87E	0x8449	#CJK UNIFIED IDEOGRAPH
+0xC880	0x844A	#CJK UNIFIED IDEOGRAPH
+0xC881	0x844B	#CJK UNIFIED IDEOGRAPH
+0xC882	0x844C	#CJK UNIFIED IDEOGRAPH
+0xC883	0x844D	#CJK UNIFIED IDEOGRAPH
+0xC884	0x844E	#CJK UNIFIED IDEOGRAPH
+0xC885	0x844F	#CJK UNIFIED IDEOGRAPH
+0xC886	0x8450	#CJK UNIFIED IDEOGRAPH
+0xC887	0x8452	#CJK UNIFIED IDEOGRAPH
+0xC888	0x8453	#CJK UNIFIED IDEOGRAPH
+0xC889	0x8454	#CJK UNIFIED IDEOGRAPH
+0xC88A	0x8455	#CJK UNIFIED IDEOGRAPH
+0xC88B	0x8456	#CJK UNIFIED IDEOGRAPH
+0xC88C	0x8458	#CJK UNIFIED IDEOGRAPH
+0xC88D	0x845D	#CJK UNIFIED IDEOGRAPH
+0xC88E	0x845E	#CJK UNIFIED IDEOGRAPH
+0xC88F	0x845F	#CJK UNIFIED IDEOGRAPH
+0xC890	0x8460	#CJK UNIFIED IDEOGRAPH
+0xC891	0x8462	#CJK UNIFIED IDEOGRAPH
+0xC892	0x8464	#CJK UNIFIED IDEOGRAPH
+0xC893	0x8465	#CJK UNIFIED IDEOGRAPH
+0xC894	0x8466	#CJK UNIFIED IDEOGRAPH
+0xC895	0x8467	#CJK UNIFIED IDEOGRAPH
+0xC896	0x8468	#CJK UNIFIED IDEOGRAPH
+0xC897	0x846A	#CJK UNIFIED IDEOGRAPH
+0xC898	0x846E	#CJK UNIFIED IDEOGRAPH
+0xC899	0x846F	#CJK UNIFIED IDEOGRAPH
+0xC89A	0x8470	#CJK UNIFIED IDEOGRAPH
+0xC89B	0x8472	#CJK UNIFIED IDEOGRAPH
+0xC89C	0x8474	#CJK UNIFIED IDEOGRAPH
+0xC89D	0x8477	#CJK UNIFIED IDEOGRAPH
+0xC89E	0x8479	#CJK UNIFIED IDEOGRAPH
+0xC89F	0x847B	#CJK UNIFIED IDEOGRAPH
+0xC8A0	0x847C	#CJK UNIFIED IDEOGRAPH
+0xC8A1	0x53D6	#CJK UNIFIED IDEOGRAPH
+0xC8A2	0x5A36	#CJK UNIFIED IDEOGRAPH
+0xC8A3	0x9F8B	#CJK UNIFIED IDEOGRAPH
+0xC8A4	0x8DA3	#CJK UNIFIED IDEOGRAPH
+0xC8A5	0x53BB	#CJK UNIFIED IDEOGRAPH
+0xC8A6	0x5708	#CJK UNIFIED IDEOGRAPH
+0xC8A7	0x98A7	#CJK UNIFIED IDEOGRAPH
+0xC8A8	0x6743	#CJK UNIFIED IDEOGRAPH
+0xC8A9	0x919B	#CJK UNIFIED IDEOGRAPH
+0xC8AA	0x6CC9	#CJK UNIFIED IDEOGRAPH
+0xC8AB	0x5168	#CJK UNIFIED IDEOGRAPH
+0xC8AC	0x75CA	#CJK UNIFIED IDEOGRAPH
+0xC8AD	0x62F3	#CJK UNIFIED IDEOGRAPH
+0xC8AE	0x72AC	#CJK UNIFIED IDEOGRAPH
+0xC8AF	0x5238	#CJK UNIFIED IDEOGRAPH
+0xC8B0	0x529D	#CJK UNIFIED IDEOGRAPH
+0xC8B1	0x7F3A	#CJK UNIFIED IDEOGRAPH
+0xC8B2	0x7094	#CJK UNIFIED IDEOGRAPH
+0xC8B3	0x7638	#CJK UNIFIED IDEOGRAPH
+0xC8B4	0x5374	#CJK UNIFIED IDEOGRAPH
+0xC8B5	0x9E4A	#CJK UNIFIED IDEOGRAPH
+0xC8B6	0x69B7	#CJK UNIFIED IDEOGRAPH
+0xC8B7	0x786E	#CJK UNIFIED IDEOGRAPH
+0xC8B8	0x96C0	#CJK UNIFIED IDEOGRAPH
+0xC8B9	0x88D9	#CJK UNIFIED IDEOGRAPH
+0xC8BA	0x7FA4	#CJK UNIFIED IDEOGRAPH
+0xC8BB	0x7136	#CJK UNIFIED IDEOGRAPH
+0xC8BC	0x71C3	#CJK UNIFIED IDEOGRAPH
+0xC8BD	0x5189	#CJK UNIFIED IDEOGRAPH
+0xC8BE	0x67D3	#CJK UNIFIED IDEOGRAPH
+0xC8BF	0x74E4	#CJK UNIFIED IDEOGRAPH
+0xC8C0	0x58E4	#CJK UNIFIED IDEOGRAPH
+0xC8C1	0x6518	#CJK UNIFIED IDEOGRAPH
+0xC8C2	0x56B7	#CJK UNIFIED IDEOGRAPH
+0xC8C3	0x8BA9	#CJK UNIFIED IDEOGRAPH
+0xC8C4	0x9976	#CJK UNIFIED IDEOGRAPH
+0xC8C5	0x6270	#CJK UNIFIED IDEOGRAPH
+0xC8C6	0x7ED5	#CJK UNIFIED IDEOGRAPH
+0xC8C7	0x60F9	#CJK UNIFIED IDEOGRAPH
+0xC8C8	0x70ED	#CJK UNIFIED IDEOGRAPH
+0xC8C9	0x58EC	#CJK UNIFIED IDEOGRAPH
+0xC8CA	0x4EC1	#CJK UNIFIED IDEOGRAPH
+0xC8CB	0x4EBA	#CJK UNIFIED IDEOGRAPH
+0xC8CC	0x5FCD	#CJK UNIFIED IDEOGRAPH
+0xC8CD	0x97E7	#CJK UNIFIED IDEOGRAPH
+0xC8CE	0x4EFB	#CJK UNIFIED IDEOGRAPH
+0xC8CF	0x8BA4	#CJK UNIFIED IDEOGRAPH
+0xC8D0	0x5203	#CJK UNIFIED IDEOGRAPH
+0xC8D1	0x598A	#CJK UNIFIED IDEOGRAPH
+0xC8D2	0x7EAB	#CJK UNIFIED IDEOGRAPH
+0xC8D3	0x6254	#CJK UNIFIED IDEOGRAPH
+0xC8D4	0x4ECD	#CJK UNIFIED IDEOGRAPH
+0xC8D5	0x65E5	#CJK UNIFIED IDEOGRAPH
+0xC8D6	0x620E	#CJK UNIFIED IDEOGRAPH
+0xC8D7	0x8338	#CJK UNIFIED IDEOGRAPH
+0xC8D8	0x84C9	#CJK UNIFIED IDEOGRAPH
+0xC8D9	0x8363	#CJK UNIFIED IDEOGRAPH
+0xC8DA	0x878D	#CJK UNIFIED IDEOGRAPH
+0xC8DB	0x7194	#CJK UNIFIED IDEOGRAPH
+0xC8DC	0x6EB6	#CJK UNIFIED IDEOGRAPH
+0xC8DD	0x5BB9	#CJK UNIFIED IDEOGRAPH
+0xC8DE	0x7ED2	#CJK UNIFIED IDEOGRAPH
+0xC8DF	0x5197	#CJK UNIFIED IDEOGRAPH
+0xC8E0	0x63C9	#CJK UNIFIED IDEOGRAPH
+0xC8E1	0x67D4	#CJK UNIFIED IDEOGRAPH
+0xC8E2	0x8089	#CJK UNIFIED IDEOGRAPH
+0xC8E3	0x8339	#CJK UNIFIED IDEOGRAPH
+0xC8E4	0x8815	#CJK UNIFIED IDEOGRAPH
+0xC8E5	0x5112	#CJK UNIFIED IDEOGRAPH
+0xC8E6	0x5B7A	#CJK UNIFIED IDEOGRAPH
+0xC8E7	0x5982	#CJK UNIFIED IDEOGRAPH
+0xC8E8	0x8FB1	#CJK UNIFIED IDEOGRAPH
+0xC8E9	0x4E73	#CJK UNIFIED IDEOGRAPH
+0xC8EA	0x6C5D	#CJK UNIFIED IDEOGRAPH
+0xC8EB	0x5165	#CJK UNIFIED IDEOGRAPH
+0xC8EC	0x8925	#CJK UNIFIED IDEOGRAPH
+0xC8ED	0x8F6F	#CJK UNIFIED IDEOGRAPH
+0xC8EE	0x962E	#CJK UNIFIED IDEOGRAPH
+0xC8EF	0x854A	#CJK UNIFIED IDEOGRAPH
+0xC8F0	0x745E	#CJK UNIFIED IDEOGRAPH
+0xC8F1	0x9510	#CJK UNIFIED IDEOGRAPH
+0xC8F2	0x95F0	#CJK UNIFIED IDEOGRAPH
+0xC8F3	0x6DA6	#CJK UNIFIED IDEOGRAPH
+0xC8F4	0x82E5	#CJK UNIFIED IDEOGRAPH
+0xC8F5	0x5F31	#CJK UNIFIED IDEOGRAPH
+0xC8F6	0x6492	#CJK UNIFIED IDEOGRAPH
+0xC8F7	0x6D12	#CJK UNIFIED IDEOGRAPH
+0xC8F8	0x8428	#CJK UNIFIED IDEOGRAPH
+0xC8F9	0x816E	#CJK UNIFIED IDEOGRAPH
+0xC8FA	0x9CC3	#CJK UNIFIED IDEOGRAPH
+0xC8FB	0x585E	#CJK UNIFIED IDEOGRAPH
+0xC8FC	0x8D5B	#CJK UNIFIED IDEOGRAPH
+0xC8FD	0x4E09	#CJK UNIFIED IDEOGRAPH
+0xC8FE	0x53C1	#CJK UNIFIED IDEOGRAPH
+0xC940	0x847D	#CJK UNIFIED IDEOGRAPH
+0xC941	0x847E	#CJK UNIFIED IDEOGRAPH
+0xC942	0x847F	#CJK UNIFIED IDEOGRAPH
+0xC943	0x8480	#CJK UNIFIED IDEOGRAPH
+0xC944	0x8481	#CJK UNIFIED IDEOGRAPH
+0xC945	0x8483	#CJK UNIFIED IDEOGRAPH
+0xC946	0x8484	#CJK UNIFIED IDEOGRAPH
+0xC947	0x8485	#CJK UNIFIED IDEOGRAPH
+0xC948	0x8486	#CJK UNIFIED IDEOGRAPH
+0xC949	0x848A	#CJK UNIFIED IDEOGRAPH
+0xC94A	0x848D	#CJK UNIFIED IDEOGRAPH
+0xC94B	0x848F	#CJK UNIFIED IDEOGRAPH
+0xC94C	0x8490	#CJK UNIFIED IDEOGRAPH
+0xC94D	0x8491	#CJK UNIFIED IDEOGRAPH
+0xC94E	0x8492	#CJK UNIFIED IDEOGRAPH
+0xC94F	0x8493	#CJK UNIFIED IDEOGRAPH
+0xC950	0x8494	#CJK UNIFIED IDEOGRAPH
+0xC951	0x8495	#CJK UNIFIED IDEOGRAPH
+0xC952	0x8496	#CJK UNIFIED IDEOGRAPH
+0xC953	0x8498	#CJK UNIFIED IDEOGRAPH
+0xC954	0x849A	#CJK UNIFIED IDEOGRAPH
+0xC955	0x849B	#CJK UNIFIED IDEOGRAPH
+0xC956	0x849D	#CJK UNIFIED IDEOGRAPH
+0xC957	0x849E	#CJK UNIFIED IDEOGRAPH
+0xC958	0x849F	#CJK UNIFIED IDEOGRAPH
+0xC959	0x84A0	#CJK UNIFIED IDEOGRAPH
+0xC95A	0x84A2	#CJK UNIFIED IDEOGRAPH
+0xC95B	0x84A3	#CJK UNIFIED IDEOGRAPH
+0xC95C	0x84A4	#CJK UNIFIED IDEOGRAPH
+0xC95D	0x84A5	#CJK UNIFIED IDEOGRAPH
+0xC95E	0x84A6	#CJK UNIFIED IDEOGRAPH
+0xC95F	0x84A7	#CJK UNIFIED IDEOGRAPH
+0xC960	0x84A8	#CJK UNIFIED IDEOGRAPH
+0xC961	0x84A9	#CJK UNIFIED IDEOGRAPH
+0xC962	0x84AA	#CJK UNIFIED IDEOGRAPH
+0xC963	0x84AB	#CJK UNIFIED IDEOGRAPH
+0xC964	0x84AC	#CJK UNIFIED IDEOGRAPH
+0xC965	0x84AD	#CJK UNIFIED IDEOGRAPH
+0xC966	0x84AE	#CJK UNIFIED IDEOGRAPH
+0xC967	0x84B0	#CJK UNIFIED IDEOGRAPH
+0xC968	0x84B1	#CJK UNIFIED IDEOGRAPH
+0xC969	0x84B3	#CJK UNIFIED IDEOGRAPH
+0xC96A	0x84B5	#CJK UNIFIED IDEOGRAPH
+0xC96B	0x84B6	#CJK UNIFIED IDEOGRAPH
+0xC96C	0x84B7	#CJK UNIFIED IDEOGRAPH
+0xC96D	0x84BB	#CJK UNIFIED IDEOGRAPH
+0xC96E	0x84BC	#CJK UNIFIED IDEOGRAPH
+0xC96F	0x84BE	#CJK UNIFIED IDEOGRAPH
+0xC970	0x84C0	#CJK UNIFIED IDEOGRAPH
+0xC971	0x84C2	#CJK UNIFIED IDEOGRAPH
+0xC972	0x84C3	#CJK UNIFIED IDEOGRAPH
+0xC973	0x84C5	#CJK UNIFIED IDEOGRAPH
+0xC974	0x84C6	#CJK UNIFIED IDEOGRAPH
+0xC975	0x84C7	#CJK UNIFIED IDEOGRAPH
+0xC976	0x84C8	#CJK UNIFIED IDEOGRAPH
+0xC977	0x84CB	#CJK UNIFIED IDEOGRAPH
+0xC978	0x84CC	#CJK UNIFIED IDEOGRAPH
+0xC979	0x84CE	#CJK UNIFIED IDEOGRAPH
+0xC97A	0x84CF	#CJK UNIFIED IDEOGRAPH
+0xC97B	0x84D2	#CJK UNIFIED IDEOGRAPH
+0xC97C	0x84D4	#CJK UNIFIED IDEOGRAPH
+0xC97D	0x84D5	#CJK UNIFIED IDEOGRAPH
+0xC97E	0x84D7	#CJK UNIFIED IDEOGRAPH
+0xC980	0x84D8	#CJK UNIFIED IDEOGRAPH
+0xC981	0x84D9	#CJK UNIFIED IDEOGRAPH
+0xC982	0x84DA	#CJK UNIFIED IDEOGRAPH
+0xC983	0x84DB	#CJK UNIFIED IDEOGRAPH
+0xC984	0x84DC	#CJK UNIFIED IDEOGRAPH
+0xC985	0x84DE	#CJK UNIFIED IDEOGRAPH
+0xC986	0x84E1	#CJK UNIFIED IDEOGRAPH
+0xC987	0x84E2	#CJK UNIFIED IDEOGRAPH
+0xC988	0x84E4	#CJK UNIFIED IDEOGRAPH
+0xC989	0x84E7	#CJK UNIFIED IDEOGRAPH
+0xC98A	0x84E8	#CJK UNIFIED IDEOGRAPH
+0xC98B	0x84E9	#CJK UNIFIED IDEOGRAPH
+0xC98C	0x84EA	#CJK UNIFIED IDEOGRAPH
+0xC98D	0x84EB	#CJK UNIFIED IDEOGRAPH
+0xC98E	0x84ED	#CJK UNIFIED IDEOGRAPH
+0xC98F	0x84EE	#CJK UNIFIED IDEOGRAPH
+0xC990	0x84EF	#CJK UNIFIED IDEOGRAPH
+0xC991	0x84F1	#CJK UNIFIED IDEOGRAPH
+0xC992	0x84F2	#CJK UNIFIED IDEOGRAPH
+0xC993	0x84F3	#CJK UNIFIED IDEOGRAPH
+0xC994	0x84F4	#CJK UNIFIED IDEOGRAPH
+0xC995	0x84F5	#CJK UNIFIED IDEOGRAPH
+0xC996	0x84F6	#CJK UNIFIED IDEOGRAPH
+0xC997	0x84F7	#CJK UNIFIED IDEOGRAPH
+0xC998	0x84F8	#CJK UNIFIED IDEOGRAPH
+0xC999	0x84F9	#CJK UNIFIED IDEOGRAPH
+0xC99A	0x84FA	#CJK UNIFIED IDEOGRAPH
+0xC99B	0x84FB	#CJK UNIFIED IDEOGRAPH
+0xC99C	0x84FD	#CJK UNIFIED IDEOGRAPH
+0xC99D	0x84FE	#CJK UNIFIED IDEOGRAPH
+0xC99E	0x8500	#CJK UNIFIED IDEOGRAPH
+0xC99F	0x8501	#CJK UNIFIED IDEOGRAPH
+0xC9A0	0x8502	#CJK UNIFIED IDEOGRAPH
+0xC9A1	0x4F1E	#CJK UNIFIED IDEOGRAPH
+0xC9A2	0x6563	#CJK UNIFIED IDEOGRAPH
+0xC9A3	0x6851	#CJK UNIFIED IDEOGRAPH
+0xC9A4	0x55D3	#CJK UNIFIED IDEOGRAPH
+0xC9A5	0x4E27	#CJK UNIFIED IDEOGRAPH
+0xC9A6	0x6414	#CJK UNIFIED IDEOGRAPH
+0xC9A7	0x9A9A	#CJK UNIFIED IDEOGRAPH
+0xC9A8	0x626B	#CJK UNIFIED IDEOGRAPH
+0xC9A9	0x5AC2	#CJK UNIFIED IDEOGRAPH
+0xC9AA	0x745F	#CJK UNIFIED IDEOGRAPH
+0xC9AB	0x8272	#CJK UNIFIED IDEOGRAPH
+0xC9AC	0x6DA9	#CJK UNIFIED IDEOGRAPH
+0xC9AD	0x68EE	#CJK UNIFIED IDEOGRAPH
+0xC9AE	0x50E7	#CJK UNIFIED IDEOGRAPH
+0xC9AF	0x838E	#CJK UNIFIED IDEOGRAPH
+0xC9B0	0x7802	#CJK UNIFIED IDEOGRAPH
+0xC9B1	0x6740	#CJK UNIFIED IDEOGRAPH
+0xC9B2	0x5239	#CJK UNIFIED IDEOGRAPH
+0xC9B3	0x6C99	#CJK UNIFIED IDEOGRAPH
+0xC9B4	0x7EB1	#CJK UNIFIED IDEOGRAPH
+0xC9B5	0x50BB	#CJK UNIFIED IDEOGRAPH
+0xC9B6	0x5565	#CJK UNIFIED IDEOGRAPH
+0xC9B7	0x715E	#CJK UNIFIED IDEOGRAPH
+0xC9B8	0x7B5B	#CJK UNIFIED IDEOGRAPH
+0xC9B9	0x6652	#CJK UNIFIED IDEOGRAPH
+0xC9BA	0x73CA	#CJK UNIFIED IDEOGRAPH
+0xC9BB	0x82EB	#CJK UNIFIED IDEOGRAPH
+0xC9BC	0x6749	#CJK UNIFIED IDEOGRAPH
+0xC9BD	0x5C71	#CJK UNIFIED IDEOGRAPH
+0xC9BE	0x5220	#CJK UNIFIED IDEOGRAPH
+0xC9BF	0x717D	#CJK UNIFIED IDEOGRAPH
+0xC9C0	0x886B	#CJK UNIFIED IDEOGRAPH
+0xC9C1	0x95EA	#CJK UNIFIED IDEOGRAPH
+0xC9C2	0x9655	#CJK UNIFIED IDEOGRAPH
+0xC9C3	0x64C5	#CJK UNIFIED IDEOGRAPH
+0xC9C4	0x8D61	#CJK UNIFIED IDEOGRAPH
+0xC9C5	0x81B3	#CJK UNIFIED IDEOGRAPH
+0xC9C6	0x5584	#CJK UNIFIED IDEOGRAPH
+0xC9C7	0x6C55	#CJK UNIFIED IDEOGRAPH
+0xC9C8	0x6247	#CJK UNIFIED IDEOGRAPH
+0xC9C9	0x7F2E	#CJK UNIFIED IDEOGRAPH
+0xC9CA	0x5892	#CJK UNIFIED IDEOGRAPH
+0xC9CB	0x4F24	#CJK UNIFIED IDEOGRAPH
+0xC9CC	0x5546	#CJK UNIFIED IDEOGRAPH
+0xC9CD	0x8D4F	#CJK UNIFIED IDEOGRAPH
+0xC9CE	0x664C	#CJK UNIFIED IDEOGRAPH
+0xC9CF	0x4E0A	#CJK UNIFIED IDEOGRAPH
+0xC9D0	0x5C1A	#CJK UNIFIED IDEOGRAPH
+0xC9D1	0x88F3	#CJK UNIFIED IDEOGRAPH
+0xC9D2	0x68A2	#CJK UNIFIED IDEOGRAPH
+0xC9D3	0x634E	#CJK UNIFIED IDEOGRAPH
+0xC9D4	0x7A0D	#CJK UNIFIED IDEOGRAPH
+0xC9D5	0x70E7	#CJK UNIFIED IDEOGRAPH
+0xC9D6	0x828D	#CJK UNIFIED IDEOGRAPH
+0xC9D7	0x52FA	#CJK UNIFIED IDEOGRAPH
+0xC9D8	0x97F6	#CJK UNIFIED IDEOGRAPH
+0xC9D9	0x5C11	#CJK UNIFIED IDEOGRAPH
+0xC9DA	0x54E8	#CJK UNIFIED IDEOGRAPH
+0xC9DB	0x90B5	#CJK UNIFIED IDEOGRAPH
+0xC9DC	0x7ECD	#CJK UNIFIED IDEOGRAPH
+0xC9DD	0x5962	#CJK UNIFIED IDEOGRAPH
+0xC9DE	0x8D4A	#CJK UNIFIED IDEOGRAPH
+0xC9DF	0x86C7	#CJK UNIFIED IDEOGRAPH
+0xC9E0	0x820C	#CJK UNIFIED IDEOGRAPH
+0xC9E1	0x820D	#CJK UNIFIED IDEOGRAPH
+0xC9E2	0x8D66	#CJK UNIFIED IDEOGRAPH
+0xC9E3	0x6444	#CJK UNIFIED IDEOGRAPH
+0xC9E4	0x5C04	#CJK UNIFIED IDEOGRAPH
+0xC9E5	0x6151	#CJK UNIFIED IDEOGRAPH
+0xC9E6	0x6D89	#CJK UNIFIED IDEOGRAPH
+0xC9E7	0x793E	#CJK UNIFIED IDEOGRAPH
+0xC9E8	0x8BBE	#CJK UNIFIED IDEOGRAPH
+0xC9E9	0x7837	#CJK UNIFIED IDEOGRAPH
+0xC9EA	0x7533	#CJK UNIFIED IDEOGRAPH
+0xC9EB	0x547B	#CJK UNIFIED IDEOGRAPH
+0xC9EC	0x4F38	#CJK UNIFIED IDEOGRAPH
+0xC9ED	0x8EAB	#CJK UNIFIED IDEOGRAPH
+0xC9EE	0x6DF1	#CJK UNIFIED IDEOGRAPH
+0xC9EF	0x5A20	#CJK UNIFIED IDEOGRAPH
+0xC9F0	0x7EC5	#CJK UNIFIED IDEOGRAPH
+0xC9F1	0x795E	#CJK UNIFIED IDEOGRAPH
+0xC9F2	0x6C88	#CJK UNIFIED IDEOGRAPH
+0xC9F3	0x5BA1	#CJK UNIFIED IDEOGRAPH
+0xC9F4	0x5A76	#CJK UNIFIED IDEOGRAPH
+0xC9F5	0x751A	#CJK UNIFIED IDEOGRAPH
+0xC9F6	0x80BE	#CJK UNIFIED IDEOGRAPH
+0xC9F7	0x614E	#CJK UNIFIED IDEOGRAPH
+0xC9F8	0x6E17	#CJK UNIFIED IDEOGRAPH
+0xC9F9	0x58F0	#CJK UNIFIED IDEOGRAPH
+0xC9FA	0x751F	#CJK UNIFIED IDEOGRAPH
+0xC9FB	0x7525	#CJK UNIFIED IDEOGRAPH
+0xC9FC	0x7272	#CJK UNIFIED IDEOGRAPH
+0xC9FD	0x5347	#CJK UNIFIED IDEOGRAPH
+0xC9FE	0x7EF3	#CJK UNIFIED IDEOGRAPH
+0xCA40	0x8503	#CJK UNIFIED IDEOGRAPH
+0xCA41	0x8504	#CJK UNIFIED IDEOGRAPH
+0xCA42	0x8505	#CJK UNIFIED IDEOGRAPH
+0xCA43	0x8506	#CJK UNIFIED IDEOGRAPH
+0xCA44	0x8507	#CJK UNIFIED IDEOGRAPH
+0xCA45	0x8508	#CJK UNIFIED IDEOGRAPH
+0xCA46	0x8509	#CJK UNIFIED IDEOGRAPH
+0xCA47	0x850A	#CJK UNIFIED IDEOGRAPH
+0xCA48	0x850B	#CJK UNIFIED IDEOGRAPH
+0xCA49	0x850D	#CJK UNIFIED IDEOGRAPH
+0xCA4A	0x850E	#CJK UNIFIED IDEOGRAPH
+0xCA4B	0x850F	#CJK UNIFIED IDEOGRAPH
+0xCA4C	0x8510	#CJK UNIFIED IDEOGRAPH
+0xCA4D	0x8512	#CJK UNIFIED IDEOGRAPH
+0xCA4E	0x8514	#CJK UNIFIED IDEOGRAPH
+0xCA4F	0x8515	#CJK UNIFIED IDEOGRAPH
+0xCA50	0x8516	#CJK UNIFIED IDEOGRAPH
+0xCA51	0x8518	#CJK UNIFIED IDEOGRAPH
+0xCA52	0x8519	#CJK UNIFIED IDEOGRAPH
+0xCA53	0x851B	#CJK UNIFIED IDEOGRAPH
+0xCA54	0x851C	#CJK UNIFIED IDEOGRAPH
+0xCA55	0x851D	#CJK UNIFIED IDEOGRAPH
+0xCA56	0x851E	#CJK UNIFIED IDEOGRAPH
+0xCA57	0x8520	#CJK UNIFIED IDEOGRAPH
+0xCA58	0x8522	#CJK UNIFIED IDEOGRAPH
+0xCA59	0x8523	#CJK UNIFIED IDEOGRAPH
+0xCA5A	0x8524	#CJK UNIFIED IDEOGRAPH
+0xCA5B	0x8525	#CJK UNIFIED IDEOGRAPH
+0xCA5C	0x8526	#CJK UNIFIED IDEOGRAPH
+0xCA5D	0x8527	#CJK UNIFIED IDEOGRAPH
+0xCA5E	0x8528	#CJK UNIFIED IDEOGRAPH
+0xCA5F	0x8529	#CJK UNIFIED IDEOGRAPH
+0xCA60	0x852A	#CJK UNIFIED IDEOGRAPH
+0xCA61	0x852D	#CJK UNIFIED IDEOGRAPH
+0xCA62	0x852E	#CJK UNIFIED IDEOGRAPH
+0xCA63	0x852F	#CJK UNIFIED IDEOGRAPH
+0xCA64	0x8530	#CJK UNIFIED IDEOGRAPH
+0xCA65	0x8531	#CJK UNIFIED IDEOGRAPH
+0xCA66	0x8532	#CJK UNIFIED IDEOGRAPH
+0xCA67	0x8533	#CJK UNIFIED IDEOGRAPH
+0xCA68	0x8534	#CJK UNIFIED IDEOGRAPH
+0xCA69	0x8535	#CJK UNIFIED IDEOGRAPH
+0xCA6A	0x8536	#CJK UNIFIED IDEOGRAPH
+0xCA6B	0x853E	#CJK UNIFIED IDEOGRAPH
+0xCA6C	0x853F	#CJK UNIFIED IDEOGRAPH
+0xCA6D	0x8540	#CJK UNIFIED IDEOGRAPH
+0xCA6E	0x8541	#CJK UNIFIED IDEOGRAPH
+0xCA6F	0x8542	#CJK UNIFIED IDEOGRAPH
+0xCA70	0x8544	#CJK UNIFIED IDEOGRAPH
+0xCA71	0x8545	#CJK UNIFIED IDEOGRAPH
+0xCA72	0x8546	#CJK UNIFIED IDEOGRAPH
+0xCA73	0x8547	#CJK UNIFIED IDEOGRAPH
+0xCA74	0x854B	#CJK UNIFIED IDEOGRAPH
+0xCA75	0x854C	#CJK UNIFIED IDEOGRAPH
+0xCA76	0x854D	#CJK UNIFIED IDEOGRAPH
+0xCA77	0x854E	#CJK UNIFIED IDEOGRAPH
+0xCA78	0x854F	#CJK UNIFIED IDEOGRAPH
+0xCA79	0x8550	#CJK UNIFIED IDEOGRAPH
+0xCA7A	0x8551	#CJK UNIFIED IDEOGRAPH
+0xCA7B	0x8552	#CJK UNIFIED IDEOGRAPH
+0xCA7C	0x8553	#CJK UNIFIED IDEOGRAPH
+0xCA7D	0x8554	#CJK UNIFIED IDEOGRAPH
+0xCA7E	0x8555	#CJK UNIFIED IDEOGRAPH
+0xCA80	0x8557	#CJK UNIFIED IDEOGRAPH
+0xCA81	0x8558	#CJK UNIFIED IDEOGRAPH
+0xCA82	0x855A	#CJK UNIFIED IDEOGRAPH
+0xCA83	0x855B	#CJK UNIFIED IDEOGRAPH
+0xCA84	0x855C	#CJK UNIFIED IDEOGRAPH
+0xCA85	0x855D	#CJK UNIFIED IDEOGRAPH
+0xCA86	0x855F	#CJK UNIFIED IDEOGRAPH
+0xCA87	0x8560	#CJK UNIFIED IDEOGRAPH
+0xCA88	0x8561	#CJK UNIFIED IDEOGRAPH
+0xCA89	0x8562	#CJK UNIFIED IDEOGRAPH
+0xCA8A	0x8563	#CJK UNIFIED IDEOGRAPH
+0xCA8B	0x8565	#CJK UNIFIED IDEOGRAPH
+0xCA8C	0x8566	#CJK UNIFIED IDEOGRAPH
+0xCA8D	0x8567	#CJK UNIFIED IDEOGRAPH
+0xCA8E	0x8569	#CJK UNIFIED IDEOGRAPH
+0xCA8F	0x856A	#CJK UNIFIED IDEOGRAPH
+0xCA90	0x856B	#CJK UNIFIED IDEOGRAPH
+0xCA91	0x856C	#CJK UNIFIED IDEOGRAPH
+0xCA92	0x856D	#CJK UNIFIED IDEOGRAPH
+0xCA93	0x856E	#CJK UNIFIED IDEOGRAPH
+0xCA94	0x856F	#CJK UNIFIED IDEOGRAPH
+0xCA95	0x8570	#CJK UNIFIED IDEOGRAPH
+0xCA96	0x8571	#CJK UNIFIED IDEOGRAPH
+0xCA97	0x8573	#CJK UNIFIED IDEOGRAPH
+0xCA98	0x8575	#CJK UNIFIED IDEOGRAPH
+0xCA99	0x8576	#CJK UNIFIED IDEOGRAPH
+0xCA9A	0x8577	#CJK UNIFIED IDEOGRAPH
+0xCA9B	0x8578	#CJK UNIFIED IDEOGRAPH
+0xCA9C	0x857C	#CJK UNIFIED IDEOGRAPH
+0xCA9D	0x857D	#CJK UNIFIED IDEOGRAPH
+0xCA9E	0x857F	#CJK UNIFIED IDEOGRAPH
+0xCA9F	0x8580	#CJK UNIFIED IDEOGRAPH
+0xCAA0	0x8581	#CJK UNIFIED IDEOGRAPH
+0xCAA1	0x7701	#CJK UNIFIED IDEOGRAPH
+0xCAA2	0x76DB	#CJK UNIFIED IDEOGRAPH
+0xCAA3	0x5269	#CJK UNIFIED IDEOGRAPH
+0xCAA4	0x80DC	#CJK UNIFIED IDEOGRAPH
+0xCAA5	0x5723	#CJK UNIFIED IDEOGRAPH
+0xCAA6	0x5E08	#CJK UNIFIED IDEOGRAPH
+0xCAA7	0x5931	#CJK UNIFIED IDEOGRAPH
+0xCAA8	0x72EE	#CJK UNIFIED IDEOGRAPH
+0xCAA9	0x65BD	#CJK UNIFIED IDEOGRAPH
+0xCAAA	0x6E7F	#CJK UNIFIED IDEOGRAPH
+0xCAAB	0x8BD7	#CJK UNIFIED IDEOGRAPH
+0xCAAC	0x5C38	#CJK UNIFIED IDEOGRAPH
+0xCAAD	0x8671	#CJK UNIFIED IDEOGRAPH
+0xCAAE	0x5341	#CJK UNIFIED IDEOGRAPH
+0xCAAF	0x77F3	#CJK UNIFIED IDEOGRAPH
+0xCAB0	0x62FE	#CJK UNIFIED IDEOGRAPH
+0xCAB1	0x65F6	#CJK UNIFIED IDEOGRAPH
+0xCAB2	0x4EC0	#CJK UNIFIED IDEOGRAPH
+0xCAB3	0x98DF	#CJK UNIFIED IDEOGRAPH
+0xCAB4	0x8680	#CJK UNIFIED IDEOGRAPH
+0xCAB5	0x5B9E	#CJK UNIFIED IDEOGRAPH
+0xCAB6	0x8BC6	#CJK UNIFIED IDEOGRAPH
+0xCAB7	0x53F2	#CJK UNIFIED IDEOGRAPH
+0xCAB8	0x77E2	#CJK UNIFIED IDEOGRAPH
+0xCAB9	0x4F7F	#CJK UNIFIED IDEOGRAPH
+0xCABA	0x5C4E	#CJK UNIFIED IDEOGRAPH
+0xCABB	0x9A76	#CJK UNIFIED IDEOGRAPH
+0xCABC	0x59CB	#CJK UNIFIED IDEOGRAPH
+0xCABD	0x5F0F	#CJK UNIFIED IDEOGRAPH
+0xCABE	0x793A	#CJK UNIFIED IDEOGRAPH
+0xCABF	0x58EB	#CJK UNIFIED IDEOGRAPH
+0xCAC0	0x4E16	#CJK UNIFIED IDEOGRAPH
+0xCAC1	0x67FF	#CJK UNIFIED IDEOGRAPH
+0xCAC2	0x4E8B	#CJK UNIFIED IDEOGRAPH
+0xCAC3	0x62ED	#CJK UNIFIED IDEOGRAPH
+0xCAC4	0x8A93	#CJK UNIFIED IDEOGRAPH
+0xCAC5	0x901D	#CJK UNIFIED IDEOGRAPH
+0xCAC6	0x52BF	#CJK UNIFIED IDEOGRAPH
+0xCAC7	0x662F	#CJK UNIFIED IDEOGRAPH
+0xCAC8	0x55DC	#CJK UNIFIED IDEOGRAPH
+0xCAC9	0x566C	#CJK UNIFIED IDEOGRAPH
+0xCACA	0x9002	#CJK UNIFIED IDEOGRAPH
+0xCACB	0x4ED5	#CJK UNIFIED IDEOGRAPH
+0xCACC	0x4F8D	#CJK UNIFIED IDEOGRAPH
+0xCACD	0x91CA	#CJK UNIFIED IDEOGRAPH
+0xCACE	0x9970	#CJK UNIFIED IDEOGRAPH
+0xCACF	0x6C0F	#CJK UNIFIED IDEOGRAPH
+0xCAD0	0x5E02	#CJK UNIFIED IDEOGRAPH
+0xCAD1	0x6043	#CJK UNIFIED IDEOGRAPH
+0xCAD2	0x5BA4	#CJK UNIFIED IDEOGRAPH
+0xCAD3	0x89C6	#CJK UNIFIED IDEOGRAPH
+0xCAD4	0x8BD5	#CJK UNIFIED IDEOGRAPH
+0xCAD5	0x6536	#CJK UNIFIED IDEOGRAPH
+0xCAD6	0x624B	#CJK UNIFIED IDEOGRAPH
+0xCAD7	0x9996	#CJK UNIFIED IDEOGRAPH
+0xCAD8	0x5B88	#CJK UNIFIED IDEOGRAPH
+0xCAD9	0x5BFF	#CJK UNIFIED IDEOGRAPH
+0xCADA	0x6388	#CJK UNIFIED IDEOGRAPH
+0xCADB	0x552E	#CJK UNIFIED IDEOGRAPH
+0xCADC	0x53D7	#CJK UNIFIED IDEOGRAPH
+0xCADD	0x7626	#CJK UNIFIED IDEOGRAPH
+0xCADE	0x517D	#CJK UNIFIED IDEOGRAPH
+0xCADF	0x852C	#CJK UNIFIED IDEOGRAPH
+0xCAE0	0x67A2	#CJK UNIFIED IDEOGRAPH
+0xCAE1	0x68B3	#CJK UNIFIED IDEOGRAPH
+0xCAE2	0x6B8A	#CJK UNIFIED IDEOGRAPH
+0xCAE3	0x6292	#CJK UNIFIED IDEOGRAPH
+0xCAE4	0x8F93	#CJK UNIFIED IDEOGRAPH
+0xCAE5	0x53D4	#CJK UNIFIED IDEOGRAPH
+0xCAE6	0x8212	#CJK UNIFIED IDEOGRAPH
+0xCAE7	0x6DD1	#CJK UNIFIED IDEOGRAPH
+0xCAE8	0x758F	#CJK UNIFIED IDEOGRAPH
+0xCAE9	0x4E66	#CJK UNIFIED IDEOGRAPH
+0xCAEA	0x8D4E	#CJK UNIFIED IDEOGRAPH
+0xCAEB	0x5B70	#CJK UNIFIED IDEOGRAPH
+0xCAEC	0x719F	#CJK UNIFIED IDEOGRAPH
+0xCAED	0x85AF	#CJK UNIFIED IDEOGRAPH
+0xCAEE	0x6691	#CJK UNIFIED IDEOGRAPH
+0xCAEF	0x66D9	#CJK UNIFIED IDEOGRAPH
+0xCAF0	0x7F72	#CJK UNIFIED IDEOGRAPH
+0xCAF1	0x8700	#CJK UNIFIED IDEOGRAPH
+0xCAF2	0x9ECD	#CJK UNIFIED IDEOGRAPH
+0xCAF3	0x9F20	#CJK UNIFIED IDEOGRAPH
+0xCAF4	0x5C5E	#CJK UNIFIED IDEOGRAPH
+0xCAF5	0x672F	#CJK UNIFIED IDEOGRAPH
+0xCAF6	0x8FF0	#CJK UNIFIED IDEOGRAPH
+0xCAF7	0x6811	#CJK UNIFIED IDEOGRAPH
+0xCAF8	0x675F	#CJK UNIFIED IDEOGRAPH
+0xCAF9	0x620D	#CJK UNIFIED IDEOGRAPH
+0xCAFA	0x7AD6	#CJK UNIFIED IDEOGRAPH
+0xCAFB	0x5885	#CJK UNIFIED IDEOGRAPH
+0xCAFC	0x5EB6	#CJK UNIFIED IDEOGRAPH
+0xCAFD	0x6570	#CJK UNIFIED IDEOGRAPH
+0xCAFE	0x6F31	#CJK UNIFIED IDEOGRAPH
+0xCB40	0x8582	#CJK UNIFIED IDEOGRAPH
+0xCB41	0x8583	#CJK UNIFIED IDEOGRAPH
+0xCB42	0x8586	#CJK UNIFIED IDEOGRAPH
+0xCB43	0x8588	#CJK UNIFIED IDEOGRAPH
+0xCB44	0x8589	#CJK UNIFIED IDEOGRAPH
+0xCB45	0x858A	#CJK UNIFIED IDEOGRAPH
+0xCB46	0x858B	#CJK UNIFIED IDEOGRAPH
+0xCB47	0x858C	#CJK UNIFIED IDEOGRAPH
+0xCB48	0x858D	#CJK UNIFIED IDEOGRAPH
+0xCB49	0x858E	#CJK UNIFIED IDEOGRAPH
+0xCB4A	0x8590	#CJK UNIFIED IDEOGRAPH
+0xCB4B	0x8591	#CJK UNIFIED IDEOGRAPH
+0xCB4C	0x8592	#CJK UNIFIED IDEOGRAPH
+0xCB4D	0x8593	#CJK UNIFIED IDEOGRAPH
+0xCB4E	0x8594	#CJK UNIFIED IDEOGRAPH
+0xCB4F	0x8595	#CJK UNIFIED IDEOGRAPH
+0xCB50	0x8596	#CJK UNIFIED IDEOGRAPH
+0xCB51	0x8597	#CJK UNIFIED IDEOGRAPH
+0xCB52	0x8598	#CJK UNIFIED IDEOGRAPH
+0xCB53	0x8599	#CJK UNIFIED IDEOGRAPH
+0xCB54	0x859A	#CJK UNIFIED IDEOGRAPH
+0xCB55	0x859D	#CJK UNIFIED IDEOGRAPH
+0xCB56	0x859E	#CJK UNIFIED IDEOGRAPH
+0xCB57	0x859F	#CJK UNIFIED IDEOGRAPH
+0xCB58	0x85A0	#CJK UNIFIED IDEOGRAPH
+0xCB59	0x85A1	#CJK UNIFIED IDEOGRAPH
+0xCB5A	0x85A2	#CJK UNIFIED IDEOGRAPH
+0xCB5B	0x85A3	#CJK UNIFIED IDEOGRAPH
+0xCB5C	0x85A5	#CJK UNIFIED IDEOGRAPH
+0xCB5D	0x85A6	#CJK UNIFIED IDEOGRAPH
+0xCB5E	0x85A7	#CJK UNIFIED IDEOGRAPH
+0xCB5F	0x85A9	#CJK UNIFIED IDEOGRAPH
+0xCB60	0x85AB	#CJK UNIFIED IDEOGRAPH
+0xCB61	0x85AC	#CJK UNIFIED IDEOGRAPH
+0xCB62	0x85AD	#CJK UNIFIED IDEOGRAPH
+0xCB63	0x85B1	#CJK UNIFIED IDEOGRAPH
+0xCB64	0x85B2	#CJK UNIFIED IDEOGRAPH
+0xCB65	0x85B3	#CJK UNIFIED IDEOGRAPH
+0xCB66	0x85B4	#CJK UNIFIED IDEOGRAPH
+0xCB67	0x85B5	#CJK UNIFIED IDEOGRAPH
+0xCB68	0x85B6	#CJK UNIFIED IDEOGRAPH
+0xCB69	0x85B8	#CJK UNIFIED IDEOGRAPH
+0xCB6A	0x85BA	#CJK UNIFIED IDEOGRAPH
+0xCB6B	0x85BB	#CJK UNIFIED IDEOGRAPH
+0xCB6C	0x85BC	#CJK UNIFIED IDEOGRAPH
+0xCB6D	0x85BD	#CJK UNIFIED IDEOGRAPH
+0xCB6E	0x85BE	#CJK UNIFIED IDEOGRAPH
+0xCB6F	0x85BF	#CJK UNIFIED IDEOGRAPH
+0xCB70	0x85C0	#CJK UNIFIED IDEOGRAPH
+0xCB71	0x85C2	#CJK UNIFIED IDEOGRAPH
+0xCB72	0x85C3	#CJK UNIFIED IDEOGRAPH
+0xCB73	0x85C4	#CJK UNIFIED IDEOGRAPH
+0xCB74	0x85C5	#CJK UNIFIED IDEOGRAPH
+0xCB75	0x85C6	#CJK UNIFIED IDEOGRAPH
+0xCB76	0x85C7	#CJK UNIFIED IDEOGRAPH
+0xCB77	0x85C8	#CJK UNIFIED IDEOGRAPH
+0xCB78	0x85CA	#CJK UNIFIED IDEOGRAPH
+0xCB79	0x85CB	#CJK UNIFIED IDEOGRAPH
+0xCB7A	0x85CC	#CJK UNIFIED IDEOGRAPH
+0xCB7B	0x85CD	#CJK UNIFIED IDEOGRAPH
+0xCB7C	0x85CE	#CJK UNIFIED IDEOGRAPH
+0xCB7D	0x85D1	#CJK UNIFIED IDEOGRAPH
+0xCB7E	0x85D2	#CJK UNIFIED IDEOGRAPH
+0xCB80	0x85D4	#CJK UNIFIED IDEOGRAPH
+0xCB81	0x85D6	#CJK UNIFIED IDEOGRAPH
+0xCB82	0x85D7	#CJK UNIFIED IDEOGRAPH
+0xCB83	0x85D8	#CJK UNIFIED IDEOGRAPH
+0xCB84	0x85D9	#CJK UNIFIED IDEOGRAPH
+0xCB85	0x85DA	#CJK UNIFIED IDEOGRAPH
+0xCB86	0x85DB	#CJK UNIFIED IDEOGRAPH
+0xCB87	0x85DD	#CJK UNIFIED IDEOGRAPH
+0xCB88	0x85DE	#CJK UNIFIED IDEOGRAPH
+0xCB89	0x85DF	#CJK UNIFIED IDEOGRAPH
+0xCB8A	0x85E0	#CJK UNIFIED IDEOGRAPH
+0xCB8B	0x85E1	#CJK UNIFIED IDEOGRAPH
+0xCB8C	0x85E2	#CJK UNIFIED IDEOGRAPH
+0xCB8D	0x85E3	#CJK UNIFIED IDEOGRAPH
+0xCB8E	0x85E5	#CJK UNIFIED IDEOGRAPH
+0xCB8F	0x85E6	#CJK UNIFIED IDEOGRAPH
+0xCB90	0x85E7	#CJK UNIFIED IDEOGRAPH
+0xCB91	0x85E8	#CJK UNIFIED IDEOGRAPH
+0xCB92	0x85EA	#CJK UNIFIED IDEOGRAPH
+0xCB93	0x85EB	#CJK UNIFIED IDEOGRAPH
+0xCB94	0x85EC	#CJK UNIFIED IDEOGRAPH
+0xCB95	0x85ED	#CJK UNIFIED IDEOGRAPH
+0xCB96	0x85EE	#CJK UNIFIED IDEOGRAPH
+0xCB97	0x85EF	#CJK UNIFIED IDEOGRAPH
+0xCB98	0x85F0	#CJK UNIFIED IDEOGRAPH
+0xCB99	0x85F1	#CJK UNIFIED IDEOGRAPH
+0xCB9A	0x85F2	#CJK UNIFIED IDEOGRAPH
+0xCB9B	0x85F3	#CJK UNIFIED IDEOGRAPH
+0xCB9C	0x85F4	#CJK UNIFIED IDEOGRAPH
+0xCB9D	0x85F5	#CJK UNIFIED IDEOGRAPH
+0xCB9E	0x85F6	#CJK UNIFIED IDEOGRAPH
+0xCB9F	0x85F7	#CJK UNIFIED IDEOGRAPH
+0xCBA0	0x85F8	#CJK UNIFIED IDEOGRAPH
+0xCBA1	0x6055	#CJK UNIFIED IDEOGRAPH
+0xCBA2	0x5237	#CJK UNIFIED IDEOGRAPH
+0xCBA3	0x800D	#CJK UNIFIED IDEOGRAPH
+0xCBA4	0x6454	#CJK UNIFIED IDEOGRAPH
+0xCBA5	0x8870	#CJK UNIFIED IDEOGRAPH
+0xCBA6	0x7529	#CJK UNIFIED IDEOGRAPH
+0xCBA7	0x5E05	#CJK UNIFIED IDEOGRAPH
+0xCBA8	0x6813	#CJK UNIFIED IDEOGRAPH
+0xCBA9	0x62F4	#CJK UNIFIED IDEOGRAPH
+0xCBAA	0x971C	#CJK UNIFIED IDEOGRAPH
+0xCBAB	0x53CC	#CJK UNIFIED IDEOGRAPH
+0xCBAC	0x723D	#CJK UNIFIED IDEOGRAPH
+0xCBAD	0x8C01	#CJK UNIFIED IDEOGRAPH
+0xCBAE	0x6C34	#CJK UNIFIED IDEOGRAPH
+0xCBAF	0x7761	#CJK UNIFIED IDEOGRAPH
+0xCBB0	0x7A0E	#CJK UNIFIED IDEOGRAPH
+0xCBB1	0x542E	#CJK UNIFIED IDEOGRAPH
+0xCBB2	0x77AC	#CJK UNIFIED IDEOGRAPH
+0xCBB3	0x987A	#CJK UNIFIED IDEOGRAPH
+0xCBB4	0x821C	#CJK UNIFIED IDEOGRAPH
+0xCBB5	0x8BF4	#CJK UNIFIED IDEOGRAPH
+0xCBB6	0x7855	#CJK UNIFIED IDEOGRAPH
+0xCBB7	0x6714	#CJK UNIFIED IDEOGRAPH
+0xCBB8	0x70C1	#CJK UNIFIED IDEOGRAPH
+0xCBB9	0x65AF	#CJK UNIFIED IDEOGRAPH
+0xCBBA	0x6495	#CJK UNIFIED IDEOGRAPH
+0xCBBB	0x5636	#CJK UNIFIED IDEOGRAPH
+0xCBBC	0x601D	#CJK UNIFIED IDEOGRAPH
+0xCBBD	0x79C1	#CJK UNIFIED IDEOGRAPH
+0xCBBE	0x53F8	#CJK UNIFIED IDEOGRAPH
+0xCBBF	0x4E1D	#CJK UNIFIED IDEOGRAPH
+0xCBC0	0x6B7B	#CJK UNIFIED IDEOGRAPH
+0xCBC1	0x8086	#CJK UNIFIED IDEOGRAPH
+0xCBC2	0x5BFA	#CJK UNIFIED IDEOGRAPH
+0xCBC3	0x55E3	#CJK UNIFIED IDEOGRAPH
+0xCBC4	0x56DB	#CJK UNIFIED IDEOGRAPH
+0xCBC5	0x4F3A	#CJK UNIFIED IDEOGRAPH
+0xCBC6	0x4F3C	#CJK UNIFIED IDEOGRAPH
+0xCBC7	0x9972	#CJK UNIFIED IDEOGRAPH
+0xCBC8	0x5DF3	#CJK UNIFIED IDEOGRAPH
+0xCBC9	0x677E	#CJK UNIFIED IDEOGRAPH
+0xCBCA	0x8038	#CJK UNIFIED IDEOGRAPH
+0xCBCB	0x6002	#CJK UNIFIED IDEOGRAPH
+0xCBCC	0x9882	#CJK UNIFIED IDEOGRAPH
+0xCBCD	0x9001	#CJK UNIFIED IDEOGRAPH
+0xCBCE	0x5B8B	#CJK UNIFIED IDEOGRAPH
+0xCBCF	0x8BBC	#CJK UNIFIED IDEOGRAPH
+0xCBD0	0x8BF5	#CJK UNIFIED IDEOGRAPH
+0xCBD1	0x641C	#CJK UNIFIED IDEOGRAPH
+0xCBD2	0x8258	#CJK UNIFIED IDEOGRAPH
+0xCBD3	0x64DE	#CJK UNIFIED IDEOGRAPH
+0xCBD4	0x55FD	#CJK UNIFIED IDEOGRAPH
+0xCBD5	0x82CF	#CJK UNIFIED IDEOGRAPH
+0xCBD6	0x9165	#CJK UNIFIED IDEOGRAPH
+0xCBD7	0x4FD7	#CJK UNIFIED IDEOGRAPH
+0xCBD8	0x7D20	#CJK UNIFIED IDEOGRAPH
+0xCBD9	0x901F	#CJK UNIFIED IDEOGRAPH
+0xCBDA	0x7C9F	#CJK UNIFIED IDEOGRAPH
+0xCBDB	0x50F3	#CJK UNIFIED IDEOGRAPH
+0xCBDC	0x5851	#CJK UNIFIED IDEOGRAPH
+0xCBDD	0x6EAF	#CJK UNIFIED IDEOGRAPH
+0xCBDE	0x5BBF	#CJK UNIFIED IDEOGRAPH
+0xCBDF	0x8BC9	#CJK UNIFIED IDEOGRAPH
+0xCBE0	0x8083	#CJK UNIFIED IDEOGRAPH
+0xCBE1	0x9178	#CJK UNIFIED IDEOGRAPH
+0xCBE2	0x849C	#CJK UNIFIED IDEOGRAPH
+0xCBE3	0x7B97	#CJK UNIFIED IDEOGRAPH
+0xCBE4	0x867D	#CJK UNIFIED IDEOGRAPH
+0xCBE5	0x968B	#CJK UNIFIED IDEOGRAPH
+0xCBE6	0x968F	#CJK UNIFIED IDEOGRAPH
+0xCBE7	0x7EE5	#CJK UNIFIED IDEOGRAPH
+0xCBE8	0x9AD3	#CJK UNIFIED IDEOGRAPH
+0xCBE9	0x788E	#CJK UNIFIED IDEOGRAPH
+0xCBEA	0x5C81	#CJK UNIFIED IDEOGRAPH
+0xCBEB	0x7A57	#CJK UNIFIED IDEOGRAPH
+0xCBEC	0x9042	#CJK UNIFIED IDEOGRAPH
+0xCBED	0x96A7	#CJK UNIFIED IDEOGRAPH
+0xCBEE	0x795F	#CJK UNIFIED IDEOGRAPH
+0xCBEF	0x5B59	#CJK UNIFIED IDEOGRAPH
+0xCBF0	0x635F	#CJK UNIFIED IDEOGRAPH
+0xCBF1	0x7B0B	#CJK UNIFIED IDEOGRAPH
+0xCBF2	0x84D1	#CJK UNIFIED IDEOGRAPH
+0xCBF3	0x68AD	#CJK UNIFIED IDEOGRAPH
+0xCBF4	0x5506	#CJK UNIFIED IDEOGRAPH
+0xCBF5	0x7F29	#CJK UNIFIED IDEOGRAPH
+0xCBF6	0x7410	#CJK UNIFIED IDEOGRAPH
+0xCBF7	0x7D22	#CJK UNIFIED IDEOGRAPH
+0xCBF8	0x9501	#CJK UNIFIED IDEOGRAPH
+0xCBF9	0x6240	#CJK UNIFIED IDEOGRAPH
+0xCBFA	0x584C	#CJK UNIFIED IDEOGRAPH
+0xCBFB	0x4ED6	#CJK UNIFIED IDEOGRAPH
+0xCBFC	0x5B83	#CJK UNIFIED IDEOGRAPH
+0xCBFD	0x5979	#CJK UNIFIED IDEOGRAPH
+0xCBFE	0x5854	#CJK UNIFIED IDEOGRAPH
+0xCC40	0x85F9	#CJK UNIFIED IDEOGRAPH
+0xCC41	0x85FA	#CJK UNIFIED IDEOGRAPH
+0xCC42	0x85FC	#CJK UNIFIED IDEOGRAPH
+0xCC43	0x85FD	#CJK UNIFIED IDEOGRAPH
+0xCC44	0x85FE	#CJK UNIFIED IDEOGRAPH
+0xCC45	0x8600	#CJK UNIFIED IDEOGRAPH
+0xCC46	0x8601	#CJK UNIFIED IDEOGRAPH
+0xCC47	0x8602	#CJK UNIFIED IDEOGRAPH
+0xCC48	0x8603	#CJK UNIFIED IDEOGRAPH
+0xCC49	0x8604	#CJK UNIFIED IDEOGRAPH
+0xCC4A	0x8606	#CJK UNIFIED IDEOGRAPH
+0xCC4B	0x8607	#CJK UNIFIED IDEOGRAPH
+0xCC4C	0x8608	#CJK UNIFIED IDEOGRAPH
+0xCC4D	0x8609	#CJK UNIFIED IDEOGRAPH
+0xCC4E	0x860A	#CJK UNIFIED IDEOGRAPH
+0xCC4F	0x860B	#CJK UNIFIED IDEOGRAPH
+0xCC50	0x860C	#CJK UNIFIED IDEOGRAPH
+0xCC51	0x860D	#CJK UNIFIED IDEOGRAPH
+0xCC52	0x860E	#CJK UNIFIED IDEOGRAPH
+0xCC53	0x860F	#CJK UNIFIED IDEOGRAPH
+0xCC54	0x8610	#CJK UNIFIED IDEOGRAPH
+0xCC55	0x8612	#CJK UNIFIED IDEOGRAPH
+0xCC56	0x8613	#CJK UNIFIED IDEOGRAPH
+0xCC57	0x8614	#CJK UNIFIED IDEOGRAPH
+0xCC58	0x8615	#CJK UNIFIED IDEOGRAPH
+0xCC59	0x8617	#CJK UNIFIED IDEOGRAPH
+0xCC5A	0x8618	#CJK UNIFIED IDEOGRAPH
+0xCC5B	0x8619	#CJK UNIFIED IDEOGRAPH
+0xCC5C	0x861A	#CJK UNIFIED IDEOGRAPH
+0xCC5D	0x861B	#CJK UNIFIED IDEOGRAPH
+0xCC5E	0x861C	#CJK UNIFIED IDEOGRAPH
+0xCC5F	0x861D	#CJK UNIFIED IDEOGRAPH
+0xCC60	0x861E	#CJK UNIFIED IDEOGRAPH
+0xCC61	0x861F	#CJK UNIFIED IDEOGRAPH
+0xCC62	0x8620	#CJK UNIFIED IDEOGRAPH
+0xCC63	0x8621	#CJK UNIFIED IDEOGRAPH
+0xCC64	0x8622	#CJK UNIFIED IDEOGRAPH
+0xCC65	0x8623	#CJK UNIFIED IDEOGRAPH
+0xCC66	0x8624	#CJK UNIFIED IDEOGRAPH
+0xCC67	0x8625	#CJK UNIFIED IDEOGRAPH
+0xCC68	0x8626	#CJK UNIFIED IDEOGRAPH
+0xCC69	0x8628	#CJK UNIFIED IDEOGRAPH
+0xCC6A	0x862A	#CJK UNIFIED IDEOGRAPH
+0xCC6B	0x862B	#CJK UNIFIED IDEOGRAPH
+0xCC6C	0x862C	#CJK UNIFIED IDEOGRAPH
+0xCC6D	0x862D	#CJK UNIFIED IDEOGRAPH
+0xCC6E	0x862E	#CJK UNIFIED IDEOGRAPH
+0xCC6F	0x862F	#CJK UNIFIED IDEOGRAPH
+0xCC70	0x8630	#CJK UNIFIED IDEOGRAPH
+0xCC71	0x8631	#CJK UNIFIED IDEOGRAPH
+0xCC72	0x8632	#CJK UNIFIED IDEOGRAPH
+0xCC73	0x8633	#CJK UNIFIED IDEOGRAPH
+0xCC74	0x8634	#CJK UNIFIED IDEOGRAPH
+0xCC75	0x8635	#CJK UNIFIED IDEOGRAPH
+0xCC76	0x8636	#CJK UNIFIED IDEOGRAPH
+0xCC77	0x8637	#CJK UNIFIED IDEOGRAPH
+0xCC78	0x8639	#CJK UNIFIED IDEOGRAPH
+0xCC79	0x863A	#CJK UNIFIED IDEOGRAPH
+0xCC7A	0x863B	#CJK UNIFIED IDEOGRAPH
+0xCC7B	0x863D	#CJK UNIFIED IDEOGRAPH
+0xCC7C	0x863E	#CJK UNIFIED IDEOGRAPH
+0xCC7D	0x863F	#CJK UNIFIED IDEOGRAPH
+0xCC7E	0x8640	#CJK UNIFIED IDEOGRAPH
+0xCC80	0x8641	#CJK UNIFIED IDEOGRAPH
+0xCC81	0x8642	#CJK UNIFIED IDEOGRAPH
+0xCC82	0x8643	#CJK UNIFIED IDEOGRAPH
+0xCC83	0x8644	#CJK UNIFIED IDEOGRAPH
+0xCC84	0x8645	#CJK UNIFIED IDEOGRAPH
+0xCC85	0x8646	#CJK UNIFIED IDEOGRAPH
+0xCC86	0x8647	#CJK UNIFIED IDEOGRAPH
+0xCC87	0x8648	#CJK UNIFIED IDEOGRAPH
+0xCC88	0x8649	#CJK UNIFIED IDEOGRAPH
+0xCC89	0x864A	#CJK UNIFIED IDEOGRAPH
+0xCC8A	0x864B	#CJK UNIFIED IDEOGRAPH
+0xCC8B	0x864C	#CJK UNIFIED IDEOGRAPH
+0xCC8C	0x8652	#CJK UNIFIED IDEOGRAPH
+0xCC8D	0x8653	#CJK UNIFIED IDEOGRAPH
+0xCC8E	0x8655	#CJK UNIFIED IDEOGRAPH
+0xCC8F	0x8656	#CJK UNIFIED IDEOGRAPH
+0xCC90	0x8657	#CJK UNIFIED IDEOGRAPH
+0xCC91	0x8658	#CJK UNIFIED IDEOGRAPH
+0xCC92	0x8659	#CJK UNIFIED IDEOGRAPH
+0xCC93	0x865B	#CJK UNIFIED IDEOGRAPH
+0xCC94	0x865C	#CJK UNIFIED IDEOGRAPH
+0xCC95	0x865D	#CJK UNIFIED IDEOGRAPH
+0xCC96	0x865F	#CJK UNIFIED IDEOGRAPH
+0xCC97	0x8660	#CJK UNIFIED IDEOGRAPH
+0xCC98	0x8661	#CJK UNIFIED IDEOGRAPH
+0xCC99	0x8663	#CJK UNIFIED IDEOGRAPH
+0xCC9A	0x8664	#CJK UNIFIED IDEOGRAPH
+0xCC9B	0x8665	#CJK UNIFIED IDEOGRAPH
+0xCC9C	0x8666	#CJK UNIFIED IDEOGRAPH
+0xCC9D	0x8667	#CJK UNIFIED IDEOGRAPH
+0xCC9E	0x8668	#CJK UNIFIED IDEOGRAPH
+0xCC9F	0x8669	#CJK UNIFIED IDEOGRAPH
+0xCCA0	0x866A	#CJK UNIFIED IDEOGRAPH
+0xCCA1	0x736D	#CJK UNIFIED IDEOGRAPH
+0xCCA2	0x631E	#CJK UNIFIED IDEOGRAPH
+0xCCA3	0x8E4B	#CJK UNIFIED IDEOGRAPH
+0xCCA4	0x8E0F	#CJK UNIFIED IDEOGRAPH
+0xCCA5	0x80CE	#CJK UNIFIED IDEOGRAPH
+0xCCA6	0x82D4	#CJK UNIFIED IDEOGRAPH
+0xCCA7	0x62AC	#CJK UNIFIED IDEOGRAPH
+0xCCA8	0x53F0	#CJK UNIFIED IDEOGRAPH
+0xCCA9	0x6CF0	#CJK UNIFIED IDEOGRAPH
+0xCCAA	0x915E	#CJK UNIFIED IDEOGRAPH
+0xCCAB	0x592A	#CJK UNIFIED IDEOGRAPH
+0xCCAC	0x6001	#CJK UNIFIED IDEOGRAPH
+0xCCAD	0x6C70	#CJK UNIFIED IDEOGRAPH
+0xCCAE	0x574D	#CJK UNIFIED IDEOGRAPH
+0xCCAF	0x644A	#CJK UNIFIED IDEOGRAPH
+0xCCB0	0x8D2A	#CJK UNIFIED IDEOGRAPH
+0xCCB1	0x762B	#CJK UNIFIED IDEOGRAPH
+0xCCB2	0x6EE9	#CJK UNIFIED IDEOGRAPH
+0xCCB3	0x575B	#CJK UNIFIED IDEOGRAPH
+0xCCB4	0x6A80	#CJK UNIFIED IDEOGRAPH
+0xCCB5	0x75F0	#CJK UNIFIED IDEOGRAPH
+0xCCB6	0x6F6D	#CJK UNIFIED IDEOGRAPH
+0xCCB7	0x8C2D	#CJK UNIFIED IDEOGRAPH
+0xCCB8	0x8C08	#CJK UNIFIED IDEOGRAPH
+0xCCB9	0x5766	#CJK UNIFIED IDEOGRAPH
+0xCCBA	0x6BEF	#CJK UNIFIED IDEOGRAPH
+0xCCBB	0x8892	#CJK UNIFIED IDEOGRAPH
+0xCCBC	0x78B3	#CJK UNIFIED IDEOGRAPH
+0xCCBD	0x63A2	#CJK UNIFIED IDEOGRAPH
+0xCCBE	0x53F9	#CJK UNIFIED IDEOGRAPH
+0xCCBF	0x70AD	#CJK UNIFIED IDEOGRAPH
+0xCCC0	0x6C64	#CJK UNIFIED IDEOGRAPH
+0xCCC1	0x5858	#CJK UNIFIED IDEOGRAPH
+0xCCC2	0x642A	#CJK UNIFIED IDEOGRAPH
+0xCCC3	0x5802	#CJK UNIFIED IDEOGRAPH
+0xCCC4	0x68E0	#CJK UNIFIED IDEOGRAPH
+0xCCC5	0x819B	#CJK UNIFIED IDEOGRAPH
+0xCCC6	0x5510	#CJK UNIFIED IDEOGRAPH
+0xCCC7	0x7CD6	#CJK UNIFIED IDEOGRAPH
+0xCCC8	0x5018	#CJK UNIFIED IDEOGRAPH
+0xCCC9	0x8EBA	#CJK UNIFIED IDEOGRAPH
+0xCCCA	0x6DCC	#CJK UNIFIED IDEOGRAPH
+0xCCCB	0x8D9F	#CJK UNIFIED IDEOGRAPH
+0xCCCC	0x70EB	#CJK UNIFIED IDEOGRAPH
+0xCCCD	0x638F	#CJK UNIFIED IDEOGRAPH
+0xCCCE	0x6D9B	#CJK UNIFIED IDEOGRAPH
+0xCCCF	0x6ED4	#CJK UNIFIED IDEOGRAPH
+0xCCD0	0x7EE6	#CJK UNIFIED IDEOGRAPH
+0xCCD1	0x8404	#CJK UNIFIED IDEOGRAPH
+0xCCD2	0x6843	#CJK UNIFIED IDEOGRAPH
+0xCCD3	0x9003	#CJK UNIFIED IDEOGRAPH
+0xCCD4	0x6DD8	#CJK UNIFIED IDEOGRAPH
+0xCCD5	0x9676	#CJK UNIFIED IDEOGRAPH
+0xCCD6	0x8BA8	#CJK UNIFIED IDEOGRAPH
+0xCCD7	0x5957	#CJK UNIFIED IDEOGRAPH
+0xCCD8	0x7279	#CJK UNIFIED IDEOGRAPH
+0xCCD9	0x85E4	#CJK UNIFIED IDEOGRAPH
+0xCCDA	0x817E	#CJK UNIFIED IDEOGRAPH
+0xCCDB	0x75BC	#CJK UNIFIED IDEOGRAPH
+0xCCDC	0x8A8A	#CJK UNIFIED IDEOGRAPH
+0xCCDD	0x68AF	#CJK UNIFIED IDEOGRAPH
+0xCCDE	0x5254	#CJK UNIFIED IDEOGRAPH
+0xCCDF	0x8E22	#CJK UNIFIED IDEOGRAPH
+0xCCE0	0x9511	#CJK UNIFIED IDEOGRAPH
+0xCCE1	0x63D0	#CJK UNIFIED IDEOGRAPH
+0xCCE2	0x9898	#CJK UNIFIED IDEOGRAPH
+0xCCE3	0x8E44	#CJK UNIFIED IDEOGRAPH
+0xCCE4	0x557C	#CJK UNIFIED IDEOGRAPH
+0xCCE5	0x4F53	#CJK UNIFIED IDEOGRAPH
+0xCCE6	0x66FF	#CJK UNIFIED IDEOGRAPH
+0xCCE7	0x568F	#CJK UNIFIED IDEOGRAPH
+0xCCE8	0x60D5	#CJK UNIFIED IDEOGRAPH
+0xCCE9	0x6D95	#CJK UNIFIED IDEOGRAPH
+0xCCEA	0x5243	#CJK UNIFIED IDEOGRAPH
+0xCCEB	0x5C49	#CJK UNIFIED IDEOGRAPH
+0xCCEC	0x5929	#CJK UNIFIED IDEOGRAPH
+0xCCED	0x6DFB	#CJK UNIFIED IDEOGRAPH
+0xCCEE	0x586B	#CJK UNIFIED IDEOGRAPH
+0xCCEF	0x7530	#CJK UNIFIED IDEOGRAPH
+0xCCF0	0x751C	#CJK UNIFIED IDEOGRAPH
+0xCCF1	0x606C	#CJK UNIFIED IDEOGRAPH
+0xCCF2	0x8214	#CJK UNIFIED IDEOGRAPH
+0xCCF3	0x8146	#CJK UNIFIED IDEOGRAPH
+0xCCF4	0x6311	#CJK UNIFIED IDEOGRAPH
+0xCCF5	0x6761	#CJK UNIFIED IDEOGRAPH
+0xCCF6	0x8FE2	#CJK UNIFIED IDEOGRAPH
+0xCCF7	0x773A	#CJK UNIFIED IDEOGRAPH
+0xCCF8	0x8DF3	#CJK UNIFIED IDEOGRAPH
+0xCCF9	0x8D34	#CJK UNIFIED IDEOGRAPH
+0xCCFA	0x94C1	#CJK UNIFIED IDEOGRAPH
+0xCCFB	0x5E16	#CJK UNIFIED IDEOGRAPH
+0xCCFC	0x5385	#CJK UNIFIED IDEOGRAPH
+0xCCFD	0x542C	#CJK UNIFIED IDEOGRAPH
+0xCCFE	0x70C3	#CJK UNIFIED IDEOGRAPH
+0xCD40	0x866D	#CJK UNIFIED IDEOGRAPH
+0xCD41	0x866F	#CJK UNIFIED IDEOGRAPH
+0xCD42	0x8670	#CJK UNIFIED IDEOGRAPH
+0xCD43	0x8672	#CJK UNIFIED IDEOGRAPH
+0xCD44	0x8673	#CJK UNIFIED IDEOGRAPH
+0xCD45	0x8674	#CJK UNIFIED IDEOGRAPH
+0xCD46	0x8675	#CJK UNIFIED IDEOGRAPH
+0xCD47	0x8676	#CJK UNIFIED IDEOGRAPH
+0xCD48	0x8677	#CJK UNIFIED IDEOGRAPH
+0xCD49	0x8678	#CJK UNIFIED IDEOGRAPH
+0xCD4A	0x8683	#CJK UNIFIED IDEOGRAPH
+0xCD4B	0x8684	#CJK UNIFIED IDEOGRAPH
+0xCD4C	0x8685	#CJK UNIFIED IDEOGRAPH
+0xCD4D	0x8686	#CJK UNIFIED IDEOGRAPH
+0xCD4E	0x8687	#CJK UNIFIED IDEOGRAPH
+0xCD4F	0x8688	#CJK UNIFIED IDEOGRAPH
+0xCD50	0x8689	#CJK UNIFIED IDEOGRAPH
+0xCD51	0x868E	#CJK UNIFIED IDEOGRAPH
+0xCD52	0x868F	#CJK UNIFIED IDEOGRAPH
+0xCD53	0x8690	#CJK UNIFIED IDEOGRAPH
+0xCD54	0x8691	#CJK UNIFIED IDEOGRAPH
+0xCD55	0x8692	#CJK UNIFIED IDEOGRAPH
+0xCD56	0x8694	#CJK UNIFIED IDEOGRAPH
+0xCD57	0x8696	#CJK UNIFIED IDEOGRAPH
+0xCD58	0x8697	#CJK UNIFIED IDEOGRAPH
+0xCD59	0x8698	#CJK UNIFIED IDEOGRAPH
+0xCD5A	0x8699	#CJK UNIFIED IDEOGRAPH
+0xCD5B	0x869A	#CJK UNIFIED IDEOGRAPH
+0xCD5C	0x869B	#CJK UNIFIED IDEOGRAPH
+0xCD5D	0x869E	#CJK UNIFIED IDEOGRAPH
+0xCD5E	0x869F	#CJK UNIFIED IDEOGRAPH
+0xCD5F	0x86A0	#CJK UNIFIED IDEOGRAPH
+0xCD60	0x86A1	#CJK UNIFIED IDEOGRAPH
+0xCD61	0x86A2	#CJK UNIFIED IDEOGRAPH
+0xCD62	0x86A5	#CJK UNIFIED IDEOGRAPH
+0xCD63	0x86A6	#CJK UNIFIED IDEOGRAPH
+0xCD64	0x86AB	#CJK UNIFIED IDEOGRAPH
+0xCD65	0x86AD	#CJK UNIFIED IDEOGRAPH
+0xCD66	0x86AE	#CJK UNIFIED IDEOGRAPH
+0xCD67	0x86B2	#CJK UNIFIED IDEOGRAPH
+0xCD68	0x86B3	#CJK UNIFIED IDEOGRAPH
+0xCD69	0x86B7	#CJK UNIFIED IDEOGRAPH
+0xCD6A	0x86B8	#CJK UNIFIED IDEOGRAPH
+0xCD6B	0x86B9	#CJK UNIFIED IDEOGRAPH
+0xCD6C	0x86BB	#CJK UNIFIED IDEOGRAPH
+0xCD6D	0x86BC	#CJK UNIFIED IDEOGRAPH
+0xCD6E	0x86BD	#CJK UNIFIED IDEOGRAPH
+0xCD6F	0x86BE	#CJK UNIFIED IDEOGRAPH
+0xCD70	0x86BF	#CJK UNIFIED IDEOGRAPH
+0xCD71	0x86C1	#CJK UNIFIED IDEOGRAPH
+0xCD72	0x86C2	#CJK UNIFIED IDEOGRAPH
+0xCD73	0x86C3	#CJK UNIFIED IDEOGRAPH
+0xCD74	0x86C5	#CJK UNIFIED IDEOGRAPH
+0xCD75	0x86C8	#CJK UNIFIED IDEOGRAPH
+0xCD76	0x86CC	#CJK UNIFIED IDEOGRAPH
+0xCD77	0x86CD	#CJK UNIFIED IDEOGRAPH
+0xCD78	0x86D2	#CJK UNIFIED IDEOGRAPH
+0xCD79	0x86D3	#CJK UNIFIED IDEOGRAPH
+0xCD7A	0x86D5	#CJK UNIFIED IDEOGRAPH
+0xCD7B	0x86D6	#CJK UNIFIED IDEOGRAPH
+0xCD7C	0x86D7	#CJK UNIFIED IDEOGRAPH
+0xCD7D	0x86DA	#CJK UNIFIED IDEOGRAPH
+0xCD7E	0x86DC	#CJK UNIFIED IDEOGRAPH
+0xCD80	0x86DD	#CJK UNIFIED IDEOGRAPH
+0xCD81	0x86E0	#CJK UNIFIED IDEOGRAPH
+0xCD82	0x86E1	#CJK UNIFIED IDEOGRAPH
+0xCD83	0x86E2	#CJK UNIFIED IDEOGRAPH
+0xCD84	0x86E3	#CJK UNIFIED IDEOGRAPH
+0xCD85	0x86E5	#CJK UNIFIED IDEOGRAPH
+0xCD86	0x86E6	#CJK UNIFIED IDEOGRAPH
+0xCD87	0x86E7	#CJK UNIFIED IDEOGRAPH
+0xCD88	0x86E8	#CJK UNIFIED IDEOGRAPH
+0xCD89	0x86EA	#CJK UNIFIED IDEOGRAPH
+0xCD8A	0x86EB	#CJK UNIFIED IDEOGRAPH
+0xCD8B	0x86EC	#CJK UNIFIED IDEOGRAPH
+0xCD8C	0x86EF	#CJK UNIFIED IDEOGRAPH
+0xCD8D	0x86F5	#CJK UNIFIED IDEOGRAPH
+0xCD8E	0x86F6	#CJK UNIFIED IDEOGRAPH
+0xCD8F	0x86F7	#CJK UNIFIED IDEOGRAPH
+0xCD90	0x86FA	#CJK UNIFIED IDEOGRAPH
+0xCD91	0x86FB	#CJK UNIFIED IDEOGRAPH
+0xCD92	0x86FC	#CJK UNIFIED IDEOGRAPH
+0xCD93	0x86FD	#CJK UNIFIED IDEOGRAPH
+0xCD94	0x86FF	#CJK UNIFIED IDEOGRAPH
+0xCD95	0x8701	#CJK UNIFIED IDEOGRAPH
+0xCD96	0x8704	#CJK UNIFIED IDEOGRAPH
+0xCD97	0x8705	#CJK UNIFIED IDEOGRAPH
+0xCD98	0x8706	#CJK UNIFIED IDEOGRAPH
+0xCD99	0x870B	#CJK UNIFIED IDEOGRAPH
+0xCD9A	0x870C	#CJK UNIFIED IDEOGRAPH
+0xCD9B	0x870E	#CJK UNIFIED IDEOGRAPH
+0xCD9C	0x870F	#CJK UNIFIED IDEOGRAPH
+0xCD9D	0x8710	#CJK UNIFIED IDEOGRAPH
+0xCD9E	0x8711	#CJK UNIFIED IDEOGRAPH
+0xCD9F	0x8714	#CJK UNIFIED IDEOGRAPH
+0xCDA0	0x8716	#CJK UNIFIED IDEOGRAPH
+0xCDA1	0x6C40	#CJK UNIFIED IDEOGRAPH
+0xCDA2	0x5EF7	#CJK UNIFIED IDEOGRAPH
+0xCDA3	0x505C	#CJK UNIFIED IDEOGRAPH
+0xCDA4	0x4EAD	#CJK UNIFIED IDEOGRAPH
+0xCDA5	0x5EAD	#CJK UNIFIED IDEOGRAPH
+0xCDA6	0x633A	#CJK UNIFIED IDEOGRAPH
+0xCDA7	0x8247	#CJK UNIFIED IDEOGRAPH
+0xCDA8	0x901A	#CJK UNIFIED IDEOGRAPH
+0xCDA9	0x6850	#CJK UNIFIED IDEOGRAPH
+0xCDAA	0x916E	#CJK UNIFIED IDEOGRAPH
+0xCDAB	0x77B3	#CJK UNIFIED IDEOGRAPH
+0xCDAC	0x540C	#CJK UNIFIED IDEOGRAPH
+0xCDAD	0x94DC	#CJK UNIFIED IDEOGRAPH
+0xCDAE	0x5F64	#CJK UNIFIED IDEOGRAPH
+0xCDAF	0x7AE5	#CJK UNIFIED IDEOGRAPH
+0xCDB0	0x6876	#CJK UNIFIED IDEOGRAPH
+0xCDB1	0x6345	#CJK UNIFIED IDEOGRAPH
+0xCDB2	0x7B52	#CJK UNIFIED IDEOGRAPH
+0xCDB3	0x7EDF	#CJK UNIFIED IDEOGRAPH
+0xCDB4	0x75DB	#CJK UNIFIED IDEOGRAPH
+0xCDB5	0x5077	#CJK UNIFIED IDEOGRAPH
+0xCDB6	0x6295	#CJK UNIFIED IDEOGRAPH
+0xCDB7	0x5934	#CJK UNIFIED IDEOGRAPH
+0xCDB8	0x900F	#CJK UNIFIED IDEOGRAPH
+0xCDB9	0x51F8	#CJK UNIFIED IDEOGRAPH
+0xCDBA	0x79C3	#CJK UNIFIED IDEOGRAPH
+0xCDBB	0x7A81	#CJK UNIFIED IDEOGRAPH
+0xCDBC	0x56FE	#CJK UNIFIED IDEOGRAPH
+0xCDBD	0x5F92	#CJK UNIFIED IDEOGRAPH
+0xCDBE	0x9014	#CJK UNIFIED IDEOGRAPH
+0xCDBF	0x6D82	#CJK UNIFIED IDEOGRAPH
+0xCDC0	0x5C60	#CJK UNIFIED IDEOGRAPH
+0xCDC1	0x571F	#CJK UNIFIED IDEOGRAPH
+0xCDC2	0x5410	#CJK UNIFIED IDEOGRAPH
+0xCDC3	0x5154	#CJK UNIFIED IDEOGRAPH
+0xCDC4	0x6E4D	#CJK UNIFIED IDEOGRAPH
+0xCDC5	0x56E2	#CJK UNIFIED IDEOGRAPH
+0xCDC6	0x63A8	#CJK UNIFIED IDEOGRAPH
+0xCDC7	0x9893	#CJK UNIFIED IDEOGRAPH
+0xCDC8	0x817F	#CJK UNIFIED IDEOGRAPH
+0xCDC9	0x8715	#CJK UNIFIED IDEOGRAPH
+0xCDCA	0x892A	#CJK UNIFIED IDEOGRAPH
+0xCDCB	0x9000	#CJK UNIFIED IDEOGRAPH
+0xCDCC	0x541E	#CJK UNIFIED IDEOGRAPH
+0xCDCD	0x5C6F	#CJK UNIFIED IDEOGRAPH
+0xCDCE	0x81C0	#CJK UNIFIED IDEOGRAPH
+0xCDCF	0x62D6	#CJK UNIFIED IDEOGRAPH
+0xCDD0	0x6258	#CJK UNIFIED IDEOGRAPH
+0xCDD1	0x8131	#CJK UNIFIED IDEOGRAPH
+0xCDD2	0x9E35	#CJK UNIFIED IDEOGRAPH
+0xCDD3	0x9640	#CJK UNIFIED IDEOGRAPH
+0xCDD4	0x9A6E	#CJK UNIFIED IDEOGRAPH
+0xCDD5	0x9A7C	#CJK UNIFIED IDEOGRAPH
+0xCDD6	0x692D	#CJK UNIFIED IDEOGRAPH
+0xCDD7	0x59A5	#CJK UNIFIED IDEOGRAPH
+0xCDD8	0x62D3	#CJK UNIFIED IDEOGRAPH
+0xCDD9	0x553E	#CJK UNIFIED IDEOGRAPH
+0xCDDA	0x6316	#CJK UNIFIED IDEOGRAPH
+0xCDDB	0x54C7	#CJK UNIFIED IDEOGRAPH
+0xCDDC	0x86D9	#CJK UNIFIED IDEOGRAPH
+0xCDDD	0x6D3C	#CJK UNIFIED IDEOGRAPH
+0xCDDE	0x5A03	#CJK UNIFIED IDEOGRAPH
+0xCDDF	0x74E6	#CJK UNIFIED IDEOGRAPH
+0xCDE0	0x889C	#CJK UNIFIED IDEOGRAPH
+0xCDE1	0x6B6A	#CJK UNIFIED IDEOGRAPH
+0xCDE2	0x5916	#CJK UNIFIED IDEOGRAPH
+0xCDE3	0x8C4C	#CJK UNIFIED IDEOGRAPH
+0xCDE4	0x5F2F	#CJK UNIFIED IDEOGRAPH
+0xCDE5	0x6E7E	#CJK UNIFIED IDEOGRAPH
+0xCDE6	0x73A9	#CJK UNIFIED IDEOGRAPH
+0xCDE7	0x987D	#CJK UNIFIED IDEOGRAPH
+0xCDE8	0x4E38	#CJK UNIFIED IDEOGRAPH
+0xCDE9	0x70F7	#CJK UNIFIED IDEOGRAPH
+0xCDEA	0x5B8C	#CJK UNIFIED IDEOGRAPH
+0xCDEB	0x7897	#CJK UNIFIED IDEOGRAPH
+0xCDEC	0x633D	#CJK UNIFIED IDEOGRAPH
+0xCDED	0x665A	#CJK UNIFIED IDEOGRAPH
+0xCDEE	0x7696	#CJK UNIFIED IDEOGRAPH
+0xCDEF	0x60CB	#CJK UNIFIED IDEOGRAPH
+0xCDF0	0x5B9B	#CJK UNIFIED IDEOGRAPH
+0xCDF1	0x5A49	#CJK UNIFIED IDEOGRAPH
+0xCDF2	0x4E07	#CJK UNIFIED IDEOGRAPH
+0xCDF3	0x8155	#CJK UNIFIED IDEOGRAPH
+0xCDF4	0x6C6A	#CJK UNIFIED IDEOGRAPH
+0xCDF5	0x738B	#CJK UNIFIED IDEOGRAPH
+0xCDF6	0x4EA1	#CJK UNIFIED IDEOGRAPH
+0xCDF7	0x6789	#CJK UNIFIED IDEOGRAPH
+0xCDF8	0x7F51	#CJK UNIFIED IDEOGRAPH
+0xCDF9	0x5F80	#CJK UNIFIED IDEOGRAPH
+0xCDFA	0x65FA	#CJK UNIFIED IDEOGRAPH
+0xCDFB	0x671B	#CJK UNIFIED IDEOGRAPH
+0xCDFC	0x5FD8	#CJK UNIFIED IDEOGRAPH
+0xCDFD	0x5984	#CJK UNIFIED IDEOGRAPH
+0xCDFE	0x5A01	#CJK UNIFIED IDEOGRAPH
+0xCE40	0x8719	#CJK UNIFIED IDEOGRAPH
+0xCE41	0x871B	#CJK UNIFIED IDEOGRAPH
+0xCE42	0x871D	#CJK UNIFIED IDEOGRAPH
+0xCE43	0x871F	#CJK UNIFIED IDEOGRAPH
+0xCE44	0x8720	#CJK UNIFIED IDEOGRAPH
+0xCE45	0x8724	#CJK UNIFIED IDEOGRAPH
+0xCE46	0x8726	#CJK UNIFIED IDEOGRAPH
+0xCE47	0x8727	#CJK UNIFIED IDEOGRAPH
+0xCE48	0x8728	#CJK UNIFIED IDEOGRAPH
+0xCE49	0x872A	#CJK UNIFIED IDEOGRAPH
+0xCE4A	0x872B	#CJK UNIFIED IDEOGRAPH
+0xCE4B	0x872C	#CJK UNIFIED IDEOGRAPH
+0xCE4C	0x872D	#CJK UNIFIED IDEOGRAPH
+0xCE4D	0x872F	#CJK UNIFIED IDEOGRAPH
+0xCE4E	0x8730	#CJK UNIFIED IDEOGRAPH
+0xCE4F	0x8732	#CJK UNIFIED IDEOGRAPH
+0xCE50	0x8733	#CJK UNIFIED IDEOGRAPH
+0xCE51	0x8735	#CJK UNIFIED IDEOGRAPH
+0xCE52	0x8736	#CJK UNIFIED IDEOGRAPH
+0xCE53	0x8738	#CJK UNIFIED IDEOGRAPH
+0xCE54	0x8739	#CJK UNIFIED IDEOGRAPH
+0xCE55	0x873A	#CJK UNIFIED IDEOGRAPH
+0xCE56	0x873C	#CJK UNIFIED IDEOGRAPH
+0xCE57	0x873D	#CJK UNIFIED IDEOGRAPH
+0xCE58	0x8740	#CJK UNIFIED IDEOGRAPH
+0xCE59	0x8741	#CJK UNIFIED IDEOGRAPH
+0xCE5A	0x8742	#CJK UNIFIED IDEOGRAPH
+0xCE5B	0x8743	#CJK UNIFIED IDEOGRAPH
+0xCE5C	0x8744	#CJK UNIFIED IDEOGRAPH
+0xCE5D	0x8745	#CJK UNIFIED IDEOGRAPH
+0xCE5E	0x8746	#CJK UNIFIED IDEOGRAPH
+0xCE5F	0x874A	#CJK UNIFIED IDEOGRAPH
+0xCE60	0x874B	#CJK UNIFIED IDEOGRAPH
+0xCE61	0x874D	#CJK UNIFIED IDEOGRAPH
+0xCE62	0x874F	#CJK UNIFIED IDEOGRAPH
+0xCE63	0x8750	#CJK UNIFIED IDEOGRAPH
+0xCE64	0x8751	#CJK UNIFIED IDEOGRAPH
+0xCE65	0x8752	#CJK UNIFIED IDEOGRAPH
+0xCE66	0x8754	#CJK UNIFIED IDEOGRAPH
+0xCE67	0x8755	#CJK UNIFIED IDEOGRAPH
+0xCE68	0x8756	#CJK UNIFIED IDEOGRAPH
+0xCE69	0x8758	#CJK UNIFIED IDEOGRAPH
+0xCE6A	0x875A	#CJK UNIFIED IDEOGRAPH
+0xCE6B	0x875B	#CJK UNIFIED IDEOGRAPH
+0xCE6C	0x875C	#CJK UNIFIED IDEOGRAPH
+0xCE6D	0x875D	#CJK UNIFIED IDEOGRAPH
+0xCE6E	0x875E	#CJK UNIFIED IDEOGRAPH
+0xCE6F	0x875F	#CJK UNIFIED IDEOGRAPH
+0xCE70	0x8761	#CJK UNIFIED IDEOGRAPH
+0xCE71	0x8762	#CJK UNIFIED IDEOGRAPH
+0xCE72	0x8766	#CJK UNIFIED IDEOGRAPH
+0xCE73	0x8767	#CJK UNIFIED IDEOGRAPH
+0xCE74	0x8768	#CJK UNIFIED IDEOGRAPH
+0xCE75	0x8769	#CJK UNIFIED IDEOGRAPH
+0xCE76	0x876A	#CJK UNIFIED IDEOGRAPH
+0xCE77	0x876B	#CJK UNIFIED IDEOGRAPH
+0xCE78	0x876C	#CJK UNIFIED IDEOGRAPH
+0xCE79	0x876D	#CJK UNIFIED IDEOGRAPH
+0xCE7A	0x876F	#CJK UNIFIED IDEOGRAPH
+0xCE7B	0x8771	#CJK UNIFIED IDEOGRAPH
+0xCE7C	0x8772	#CJK UNIFIED IDEOGRAPH
+0xCE7D	0x8773	#CJK UNIFIED IDEOGRAPH
+0xCE7E	0x8775	#CJK UNIFIED IDEOGRAPH
+0xCE80	0x8777	#CJK UNIFIED IDEOGRAPH
+0xCE81	0x8778	#CJK UNIFIED IDEOGRAPH
+0xCE82	0x8779	#CJK UNIFIED IDEOGRAPH
+0xCE83	0x877A	#CJK UNIFIED IDEOGRAPH
+0xCE84	0x877F	#CJK UNIFIED IDEOGRAPH
+0xCE85	0x8780	#CJK UNIFIED IDEOGRAPH
+0xCE86	0x8781	#CJK UNIFIED IDEOGRAPH
+0xCE87	0x8784	#CJK UNIFIED IDEOGRAPH
+0xCE88	0x8786	#CJK UNIFIED IDEOGRAPH
+0xCE89	0x8787	#CJK UNIFIED IDEOGRAPH
+0xCE8A	0x8789	#CJK UNIFIED IDEOGRAPH
+0xCE8B	0x878A	#CJK UNIFIED IDEOGRAPH
+0xCE8C	0x878C	#CJK UNIFIED IDEOGRAPH
+0xCE8D	0x878E	#CJK UNIFIED IDEOGRAPH
+0xCE8E	0x878F	#CJK UNIFIED IDEOGRAPH
+0xCE8F	0x8790	#CJK UNIFIED IDEOGRAPH
+0xCE90	0x8791	#CJK UNIFIED IDEOGRAPH
+0xCE91	0x8792	#CJK UNIFIED IDEOGRAPH
+0xCE92	0x8794	#CJK UNIFIED IDEOGRAPH
+0xCE93	0x8795	#CJK UNIFIED IDEOGRAPH
+0xCE94	0x8796	#CJK UNIFIED IDEOGRAPH
+0xCE95	0x8798	#CJK UNIFIED IDEOGRAPH
+0xCE96	0x8799	#CJK UNIFIED IDEOGRAPH
+0xCE97	0x879A	#CJK UNIFIED IDEOGRAPH
+0xCE98	0x879B	#CJK UNIFIED IDEOGRAPH
+0xCE99	0x879C	#CJK UNIFIED IDEOGRAPH
+0xCE9A	0x879D	#CJK UNIFIED IDEOGRAPH
+0xCE9B	0x879E	#CJK UNIFIED IDEOGRAPH
+0xCE9C	0x87A0	#CJK UNIFIED IDEOGRAPH
+0xCE9D	0x87A1	#CJK UNIFIED IDEOGRAPH
+0xCE9E	0x87A2	#CJK UNIFIED IDEOGRAPH
+0xCE9F	0x87A3	#CJK UNIFIED IDEOGRAPH
+0xCEA0	0x87A4	#CJK UNIFIED IDEOGRAPH
+0xCEA1	0x5DCD	#CJK UNIFIED IDEOGRAPH
+0xCEA2	0x5FAE	#CJK UNIFIED IDEOGRAPH
+0xCEA3	0x5371	#CJK UNIFIED IDEOGRAPH
+0xCEA4	0x97E6	#CJK UNIFIED IDEOGRAPH
+0xCEA5	0x8FDD	#CJK UNIFIED IDEOGRAPH
+0xCEA6	0x6845	#CJK UNIFIED IDEOGRAPH
+0xCEA7	0x56F4	#CJK UNIFIED IDEOGRAPH
+0xCEA8	0x552F	#CJK UNIFIED IDEOGRAPH
+0xCEA9	0x60DF	#CJK UNIFIED IDEOGRAPH
+0xCEAA	0x4E3A	#CJK UNIFIED IDEOGRAPH
+0xCEAB	0x6F4D	#CJK UNIFIED IDEOGRAPH
+0xCEAC	0x7EF4	#CJK UNIFIED IDEOGRAPH
+0xCEAD	0x82C7	#CJK UNIFIED IDEOGRAPH
+0xCEAE	0x840E	#CJK UNIFIED IDEOGRAPH
+0xCEAF	0x59D4	#CJK UNIFIED IDEOGRAPH
+0xCEB0	0x4F1F	#CJK UNIFIED IDEOGRAPH
+0xCEB1	0x4F2A	#CJK UNIFIED IDEOGRAPH
+0xCEB2	0x5C3E	#CJK UNIFIED IDEOGRAPH
+0xCEB3	0x7EAC	#CJK UNIFIED IDEOGRAPH
+0xCEB4	0x672A	#CJK UNIFIED IDEOGRAPH
+0xCEB5	0x851A	#CJK UNIFIED IDEOGRAPH
+0xCEB6	0x5473	#CJK UNIFIED IDEOGRAPH
+0xCEB7	0x754F	#CJK UNIFIED IDEOGRAPH
+0xCEB8	0x80C3	#CJK UNIFIED IDEOGRAPH
+0xCEB9	0x5582	#CJK UNIFIED IDEOGRAPH
+0xCEBA	0x9B4F	#CJK UNIFIED IDEOGRAPH
+0xCEBB	0x4F4D	#CJK UNIFIED IDEOGRAPH
+0xCEBC	0x6E2D	#CJK UNIFIED IDEOGRAPH
+0xCEBD	0x8C13	#CJK UNIFIED IDEOGRAPH
+0xCEBE	0x5C09	#CJK UNIFIED IDEOGRAPH
+0xCEBF	0x6170	#CJK UNIFIED IDEOGRAPH
+0xCEC0	0x536B	#CJK UNIFIED IDEOGRAPH
+0xCEC1	0x761F	#CJK UNIFIED IDEOGRAPH
+0xCEC2	0x6E29	#CJK UNIFIED IDEOGRAPH
+0xCEC3	0x868A	#CJK UNIFIED IDEOGRAPH
+0xCEC4	0x6587	#CJK UNIFIED IDEOGRAPH
+0xCEC5	0x95FB	#CJK UNIFIED IDEOGRAPH
+0xCEC6	0x7EB9	#CJK UNIFIED IDEOGRAPH
+0xCEC7	0x543B	#CJK UNIFIED IDEOGRAPH
+0xCEC8	0x7A33	#CJK UNIFIED IDEOGRAPH
+0xCEC9	0x7D0A	#CJK UNIFIED IDEOGRAPH
+0xCECA	0x95EE	#CJK UNIFIED IDEOGRAPH
+0xCECB	0x55E1	#CJK UNIFIED IDEOGRAPH
+0xCECC	0x7FC1	#CJK UNIFIED IDEOGRAPH
+0xCECD	0x74EE	#CJK UNIFIED IDEOGRAPH
+0xCECE	0x631D	#CJK UNIFIED IDEOGRAPH
+0xCECF	0x8717	#CJK UNIFIED IDEOGRAPH
+0xCED0	0x6DA1	#CJK UNIFIED IDEOGRAPH
+0xCED1	0x7A9D	#CJK UNIFIED IDEOGRAPH
+0xCED2	0x6211	#CJK UNIFIED IDEOGRAPH
+0xCED3	0x65A1	#CJK UNIFIED IDEOGRAPH
+0xCED4	0x5367	#CJK UNIFIED IDEOGRAPH
+0xCED5	0x63E1	#CJK UNIFIED IDEOGRAPH
+0xCED6	0x6C83	#CJK UNIFIED IDEOGRAPH
+0xCED7	0x5DEB	#CJK UNIFIED IDEOGRAPH
+0xCED8	0x545C	#CJK UNIFIED IDEOGRAPH
+0xCED9	0x94A8	#CJK UNIFIED IDEOGRAPH
+0xCEDA	0x4E4C	#CJK UNIFIED IDEOGRAPH
+0xCEDB	0x6C61	#CJK UNIFIED IDEOGRAPH
+0xCEDC	0x8BEC	#CJK UNIFIED IDEOGRAPH
+0xCEDD	0x5C4B	#CJK UNIFIED IDEOGRAPH
+0xCEDE	0x65E0	#CJK UNIFIED IDEOGRAPH
+0xCEDF	0x829C	#CJK UNIFIED IDEOGRAPH
+0xCEE0	0x68A7	#CJK UNIFIED IDEOGRAPH
+0xCEE1	0x543E	#CJK UNIFIED IDEOGRAPH
+0xCEE2	0x5434	#CJK UNIFIED IDEOGRAPH
+0xCEE3	0x6BCB	#CJK UNIFIED IDEOGRAPH
+0xCEE4	0x6B66	#CJK UNIFIED IDEOGRAPH
+0xCEE5	0x4E94	#CJK UNIFIED IDEOGRAPH
+0xCEE6	0x6342	#CJK UNIFIED IDEOGRAPH
+0xCEE7	0x5348	#CJK UNIFIED IDEOGRAPH
+0xCEE8	0x821E	#CJK UNIFIED IDEOGRAPH
+0xCEE9	0x4F0D	#CJK UNIFIED IDEOGRAPH
+0xCEEA	0x4FAE	#CJK UNIFIED IDEOGRAPH
+0xCEEB	0x575E	#CJK UNIFIED IDEOGRAPH
+0xCEEC	0x620A	#CJK UNIFIED IDEOGRAPH
+0xCEED	0x96FE	#CJK UNIFIED IDEOGRAPH
+0xCEEE	0x6664	#CJK UNIFIED IDEOGRAPH
+0xCEEF	0x7269	#CJK UNIFIED IDEOGRAPH
+0xCEF0	0x52FF	#CJK UNIFIED IDEOGRAPH
+0xCEF1	0x52A1	#CJK UNIFIED IDEOGRAPH
+0xCEF2	0x609F	#CJK UNIFIED IDEOGRAPH
+0xCEF3	0x8BEF	#CJK UNIFIED IDEOGRAPH
+0xCEF4	0x6614	#CJK UNIFIED IDEOGRAPH
+0xCEF5	0x7199	#CJK UNIFIED IDEOGRAPH
+0xCEF6	0x6790	#CJK UNIFIED IDEOGRAPH
+0xCEF7	0x897F	#CJK UNIFIED IDEOGRAPH
+0xCEF8	0x7852	#CJK UNIFIED IDEOGRAPH
+0xCEF9	0x77FD	#CJK UNIFIED IDEOGRAPH
+0xCEFA	0x6670	#CJK UNIFIED IDEOGRAPH
+0xCEFB	0x563B	#CJK UNIFIED IDEOGRAPH
+0xCEFC	0x5438	#CJK UNIFIED IDEOGRAPH
+0xCEFD	0x9521	#CJK UNIFIED IDEOGRAPH
+0xCEFE	0x727A	#CJK UNIFIED IDEOGRAPH
+0xCF40	0x87A5	#CJK UNIFIED IDEOGRAPH
+0xCF41	0x87A6	#CJK UNIFIED IDEOGRAPH
+0xCF42	0x87A7	#CJK UNIFIED IDEOGRAPH
+0xCF43	0x87A9	#CJK UNIFIED IDEOGRAPH
+0xCF44	0x87AA	#CJK UNIFIED IDEOGRAPH
+0xCF45	0x87AE	#CJK UNIFIED IDEOGRAPH
+0xCF46	0x87B0	#CJK UNIFIED IDEOGRAPH
+0xCF47	0x87B1	#CJK UNIFIED IDEOGRAPH
+0xCF48	0x87B2	#CJK UNIFIED IDEOGRAPH
+0xCF49	0x87B4	#CJK UNIFIED IDEOGRAPH
+0xCF4A	0x87B6	#CJK UNIFIED IDEOGRAPH
+0xCF4B	0x87B7	#CJK UNIFIED IDEOGRAPH
+0xCF4C	0x87B8	#CJK UNIFIED IDEOGRAPH
+0xCF4D	0x87B9	#CJK UNIFIED IDEOGRAPH
+0xCF4E	0x87BB	#CJK UNIFIED IDEOGRAPH
+0xCF4F	0x87BC	#CJK UNIFIED IDEOGRAPH
+0xCF50	0x87BE	#CJK UNIFIED IDEOGRAPH
+0xCF51	0x87BF	#CJK UNIFIED IDEOGRAPH
+0xCF52	0x87C1	#CJK UNIFIED IDEOGRAPH
+0xCF53	0x87C2	#CJK UNIFIED IDEOGRAPH
+0xCF54	0x87C3	#CJK UNIFIED IDEOGRAPH
+0xCF55	0x87C4	#CJK UNIFIED IDEOGRAPH
+0xCF56	0x87C5	#CJK UNIFIED IDEOGRAPH
+0xCF57	0x87C7	#CJK UNIFIED IDEOGRAPH
+0xCF58	0x87C8	#CJK UNIFIED IDEOGRAPH
+0xCF59	0x87C9	#CJK UNIFIED IDEOGRAPH
+0xCF5A	0x87CC	#CJK UNIFIED IDEOGRAPH
+0xCF5B	0x87CD	#CJK UNIFIED IDEOGRAPH
+0xCF5C	0x87CE	#CJK UNIFIED IDEOGRAPH
+0xCF5D	0x87CF	#CJK UNIFIED IDEOGRAPH
+0xCF5E	0x87D0	#CJK UNIFIED IDEOGRAPH
+0xCF5F	0x87D4	#CJK UNIFIED IDEOGRAPH
+0xCF60	0x87D5	#CJK UNIFIED IDEOGRAPH
+0xCF61	0x87D6	#CJK UNIFIED IDEOGRAPH
+0xCF62	0x87D7	#CJK UNIFIED IDEOGRAPH
+0xCF63	0x87D8	#CJK UNIFIED IDEOGRAPH
+0xCF64	0x87D9	#CJK UNIFIED IDEOGRAPH
+0xCF65	0x87DA	#CJK UNIFIED IDEOGRAPH
+0xCF66	0x87DC	#CJK UNIFIED IDEOGRAPH
+0xCF67	0x87DD	#CJK UNIFIED IDEOGRAPH
+0xCF68	0x87DE	#CJK UNIFIED IDEOGRAPH
+0xCF69	0x87DF	#CJK UNIFIED IDEOGRAPH
+0xCF6A	0x87E1	#CJK UNIFIED IDEOGRAPH
+0xCF6B	0x87E2	#CJK UNIFIED IDEOGRAPH
+0xCF6C	0x87E3	#CJK UNIFIED IDEOGRAPH
+0xCF6D	0x87E4	#CJK UNIFIED IDEOGRAPH
+0xCF6E	0x87E6	#CJK UNIFIED IDEOGRAPH
+0xCF6F	0x87E7	#CJK UNIFIED IDEOGRAPH
+0xCF70	0x87E8	#CJK UNIFIED IDEOGRAPH
+0xCF71	0x87E9	#CJK UNIFIED IDEOGRAPH
+0xCF72	0x87EB	#CJK UNIFIED IDEOGRAPH
+0xCF73	0x87EC	#CJK UNIFIED IDEOGRAPH
+0xCF74	0x87ED	#CJK UNIFIED IDEOGRAPH
+0xCF75	0x87EF	#CJK UNIFIED IDEOGRAPH
+0xCF76	0x87F0	#CJK UNIFIED IDEOGRAPH
+0xCF77	0x87F1	#CJK UNIFIED IDEOGRAPH
+0xCF78	0x87F2	#CJK UNIFIED IDEOGRAPH
+0xCF79	0x87F3	#CJK UNIFIED IDEOGRAPH
+0xCF7A	0x87F4	#CJK UNIFIED IDEOGRAPH
+0xCF7B	0x87F5	#CJK UNIFIED IDEOGRAPH
+0xCF7C	0x87F6	#CJK UNIFIED IDEOGRAPH
+0xCF7D	0x87F7	#CJK UNIFIED IDEOGRAPH
+0xCF7E	0x87F8	#CJK UNIFIED IDEOGRAPH
+0xCF80	0x87FA	#CJK UNIFIED IDEOGRAPH
+0xCF81	0x87FB	#CJK UNIFIED IDEOGRAPH
+0xCF82	0x87FC	#CJK UNIFIED IDEOGRAPH
+0xCF83	0x87FD	#CJK UNIFIED IDEOGRAPH
+0xCF84	0x87FF	#CJK UNIFIED IDEOGRAPH
+0xCF85	0x8800	#CJK UNIFIED IDEOGRAPH
+0xCF86	0x8801	#CJK UNIFIED IDEOGRAPH
+0xCF87	0x8802	#CJK UNIFIED IDEOGRAPH
+0xCF88	0x8804	#CJK UNIFIED IDEOGRAPH
+0xCF89	0x8805	#CJK UNIFIED IDEOGRAPH
+0xCF8A	0x8806	#CJK UNIFIED IDEOGRAPH
+0xCF8B	0x8807	#CJK UNIFIED IDEOGRAPH
+0xCF8C	0x8808	#CJK UNIFIED IDEOGRAPH
+0xCF8D	0x8809	#CJK UNIFIED IDEOGRAPH
+0xCF8E	0x880B	#CJK UNIFIED IDEOGRAPH
+0xCF8F	0x880C	#CJK UNIFIED IDEOGRAPH
+0xCF90	0x880D	#CJK UNIFIED IDEOGRAPH
+0xCF91	0x880E	#CJK UNIFIED IDEOGRAPH
+0xCF92	0x880F	#CJK UNIFIED IDEOGRAPH
+0xCF93	0x8810	#CJK UNIFIED IDEOGRAPH
+0xCF94	0x8811	#CJK UNIFIED IDEOGRAPH
+0xCF95	0x8812	#CJK UNIFIED IDEOGRAPH
+0xCF96	0x8814	#CJK UNIFIED IDEOGRAPH
+0xCF97	0x8817	#CJK UNIFIED IDEOGRAPH
+0xCF98	0x8818	#CJK UNIFIED IDEOGRAPH
+0xCF99	0x8819	#CJK UNIFIED IDEOGRAPH
+0xCF9A	0x881A	#CJK UNIFIED IDEOGRAPH
+0xCF9B	0x881C	#CJK UNIFIED IDEOGRAPH
+0xCF9C	0x881D	#CJK UNIFIED IDEOGRAPH
+0xCF9D	0x881E	#CJK UNIFIED IDEOGRAPH
+0xCF9E	0x881F	#CJK UNIFIED IDEOGRAPH
+0xCF9F	0x8820	#CJK UNIFIED IDEOGRAPH
+0xCFA0	0x8823	#CJK UNIFIED IDEOGRAPH
+0xCFA1	0x7A00	#CJK UNIFIED IDEOGRAPH
+0xCFA2	0x606F	#CJK UNIFIED IDEOGRAPH
+0xCFA3	0x5E0C	#CJK UNIFIED IDEOGRAPH
+0xCFA4	0x6089	#CJK UNIFIED IDEOGRAPH
+0xCFA5	0x819D	#CJK UNIFIED IDEOGRAPH
+0xCFA6	0x5915	#CJK UNIFIED IDEOGRAPH
+0xCFA7	0x60DC	#CJK UNIFIED IDEOGRAPH
+0xCFA8	0x7184	#CJK UNIFIED IDEOGRAPH
+0xCFA9	0x70EF	#CJK UNIFIED IDEOGRAPH
+0xCFAA	0x6EAA	#CJK UNIFIED IDEOGRAPH
+0xCFAB	0x6C50	#CJK UNIFIED IDEOGRAPH
+0xCFAC	0x7280	#CJK UNIFIED IDEOGRAPH
+0xCFAD	0x6A84	#CJK UNIFIED IDEOGRAPH
+0xCFAE	0x88AD	#CJK UNIFIED IDEOGRAPH
+0xCFAF	0x5E2D	#CJK UNIFIED IDEOGRAPH
+0xCFB0	0x4E60	#CJK UNIFIED IDEOGRAPH
+0xCFB1	0x5AB3	#CJK UNIFIED IDEOGRAPH
+0xCFB2	0x559C	#CJK UNIFIED IDEOGRAPH
+0xCFB3	0x94E3	#CJK UNIFIED IDEOGRAPH
+0xCFB4	0x6D17	#CJK UNIFIED IDEOGRAPH
+0xCFB5	0x7CFB	#CJK UNIFIED IDEOGRAPH
+0xCFB6	0x9699	#CJK UNIFIED IDEOGRAPH
+0xCFB7	0x620F	#CJK UNIFIED IDEOGRAPH
+0xCFB8	0x7EC6	#CJK UNIFIED IDEOGRAPH
+0xCFB9	0x778E	#CJK UNIFIED IDEOGRAPH
+0xCFBA	0x867E	#CJK UNIFIED IDEOGRAPH
+0xCFBB	0x5323	#CJK UNIFIED IDEOGRAPH
+0xCFBC	0x971E	#CJK UNIFIED IDEOGRAPH
+0xCFBD	0x8F96	#CJK UNIFIED IDEOGRAPH
+0xCFBE	0x6687	#CJK UNIFIED IDEOGRAPH
+0xCFBF	0x5CE1	#CJK UNIFIED IDEOGRAPH
+0xCFC0	0x4FA0	#CJK UNIFIED IDEOGRAPH
+0xCFC1	0x72ED	#CJK UNIFIED IDEOGRAPH
+0xCFC2	0x4E0B	#CJK UNIFIED IDEOGRAPH
+0xCFC3	0x53A6	#CJK UNIFIED IDEOGRAPH
+0xCFC4	0x590F	#CJK UNIFIED IDEOGRAPH
+0xCFC5	0x5413	#CJK UNIFIED IDEOGRAPH
+0xCFC6	0x6380	#CJK UNIFIED IDEOGRAPH
+0xCFC7	0x9528	#CJK UNIFIED IDEOGRAPH
+0xCFC8	0x5148	#CJK UNIFIED IDEOGRAPH
+0xCFC9	0x4ED9	#CJK UNIFIED IDEOGRAPH
+0xCFCA	0x9C9C	#CJK UNIFIED IDEOGRAPH
+0xCFCB	0x7EA4	#CJK UNIFIED IDEOGRAPH
+0xCFCC	0x54B8	#CJK UNIFIED IDEOGRAPH
+0xCFCD	0x8D24	#CJK UNIFIED IDEOGRAPH
+0xCFCE	0x8854	#CJK UNIFIED IDEOGRAPH
+0xCFCF	0x8237	#CJK UNIFIED IDEOGRAPH
+0xCFD0	0x95F2	#CJK UNIFIED IDEOGRAPH
+0xCFD1	0x6D8E	#CJK UNIFIED IDEOGRAPH
+0xCFD2	0x5F26	#CJK UNIFIED IDEOGRAPH
+0xCFD3	0x5ACC	#CJK UNIFIED IDEOGRAPH
+0xCFD4	0x663E	#CJK UNIFIED IDEOGRAPH
+0xCFD5	0x9669	#CJK UNIFIED IDEOGRAPH
+0xCFD6	0x73B0	#CJK UNIFIED IDEOGRAPH
+0xCFD7	0x732E	#CJK UNIFIED IDEOGRAPH
+0xCFD8	0x53BF	#CJK UNIFIED IDEOGRAPH
+0xCFD9	0x817A	#CJK UNIFIED IDEOGRAPH
+0xCFDA	0x9985	#CJK UNIFIED IDEOGRAPH
+0xCFDB	0x7FA1	#CJK UNIFIED IDEOGRAPH
+0xCFDC	0x5BAA	#CJK UNIFIED IDEOGRAPH
+0xCFDD	0x9677	#CJK UNIFIED IDEOGRAPH
+0xCFDE	0x9650	#CJK UNIFIED IDEOGRAPH
+0xCFDF	0x7EBF	#CJK UNIFIED IDEOGRAPH
+0xCFE0	0x76F8	#CJK UNIFIED IDEOGRAPH
+0xCFE1	0x53A2	#CJK UNIFIED IDEOGRAPH
+0xCFE2	0x9576	#CJK UNIFIED IDEOGRAPH
+0xCFE3	0x9999	#CJK UNIFIED IDEOGRAPH
+0xCFE4	0x7BB1	#CJK UNIFIED IDEOGRAPH
+0xCFE5	0x8944	#CJK UNIFIED IDEOGRAPH
+0xCFE6	0x6E58	#CJK UNIFIED IDEOGRAPH
+0xCFE7	0x4E61	#CJK UNIFIED IDEOGRAPH
+0xCFE8	0x7FD4	#CJK UNIFIED IDEOGRAPH
+0xCFE9	0x7965	#CJK UNIFIED IDEOGRAPH
+0xCFEA	0x8BE6	#CJK UNIFIED IDEOGRAPH
+0xCFEB	0x60F3	#CJK UNIFIED IDEOGRAPH
+0xCFEC	0x54CD	#CJK UNIFIED IDEOGRAPH
+0xCFED	0x4EAB	#CJK UNIFIED IDEOGRAPH
+0xCFEE	0x9879	#CJK UNIFIED IDEOGRAPH
+0xCFEF	0x5DF7	#CJK UNIFIED IDEOGRAPH
+0xCFF0	0x6A61	#CJK UNIFIED IDEOGRAPH
+0xCFF1	0x50CF	#CJK UNIFIED IDEOGRAPH
+0xCFF2	0x5411	#CJK UNIFIED IDEOGRAPH
+0xCFF3	0x8C61	#CJK UNIFIED IDEOGRAPH
+0xCFF4	0x8427	#CJK UNIFIED IDEOGRAPH
+0xCFF5	0x785D	#CJK UNIFIED IDEOGRAPH
+0xCFF6	0x9704	#CJK UNIFIED IDEOGRAPH
+0xCFF7	0x524A	#CJK UNIFIED IDEOGRAPH
+0xCFF8	0x54EE	#CJK UNIFIED IDEOGRAPH
+0xCFF9	0x56A3	#CJK UNIFIED IDEOGRAPH
+0xCFFA	0x9500	#CJK UNIFIED IDEOGRAPH
+0xCFFB	0x6D88	#CJK UNIFIED IDEOGRAPH
+0xCFFC	0x5BB5	#CJK UNIFIED IDEOGRAPH
+0xCFFD	0x6DC6	#CJK UNIFIED IDEOGRAPH
+0xCFFE	0x6653	#CJK UNIFIED IDEOGRAPH
+0xD040	0x8824	#CJK UNIFIED IDEOGRAPH
+0xD041	0x8825	#CJK UNIFIED IDEOGRAPH
+0xD042	0x8826	#CJK UNIFIED IDEOGRAPH
+0xD043	0x8827	#CJK UNIFIED IDEOGRAPH
+0xD044	0x8828	#CJK UNIFIED IDEOGRAPH
+0xD045	0x8829	#CJK UNIFIED IDEOGRAPH
+0xD046	0x882A	#CJK UNIFIED IDEOGRAPH
+0xD047	0x882B	#CJK UNIFIED IDEOGRAPH
+0xD048	0x882C	#CJK UNIFIED IDEOGRAPH
+0xD049	0x882D	#CJK UNIFIED IDEOGRAPH
+0xD04A	0x882E	#CJK UNIFIED IDEOGRAPH
+0xD04B	0x882F	#CJK UNIFIED IDEOGRAPH
+0xD04C	0x8830	#CJK UNIFIED IDEOGRAPH
+0xD04D	0x8831	#CJK UNIFIED IDEOGRAPH
+0xD04E	0x8833	#CJK UNIFIED IDEOGRAPH
+0xD04F	0x8834	#CJK UNIFIED IDEOGRAPH
+0xD050	0x8835	#CJK UNIFIED IDEOGRAPH
+0xD051	0x8836	#CJK UNIFIED IDEOGRAPH
+0xD052	0x8837	#CJK UNIFIED IDEOGRAPH
+0xD053	0x8838	#CJK UNIFIED IDEOGRAPH
+0xD054	0x883A	#CJK UNIFIED IDEOGRAPH
+0xD055	0x883B	#CJK UNIFIED IDEOGRAPH
+0xD056	0x883D	#CJK UNIFIED IDEOGRAPH
+0xD057	0x883E	#CJK UNIFIED IDEOGRAPH
+0xD058	0x883F	#CJK UNIFIED IDEOGRAPH
+0xD059	0x8841	#CJK UNIFIED IDEOGRAPH
+0xD05A	0x8842	#CJK UNIFIED IDEOGRAPH
+0xD05B	0x8843	#CJK UNIFIED IDEOGRAPH
+0xD05C	0x8846	#CJK UNIFIED IDEOGRAPH
+0xD05D	0x8847	#CJK UNIFIED IDEOGRAPH
+0xD05E	0x8848	#CJK UNIFIED IDEOGRAPH
+0xD05F	0x8849	#CJK UNIFIED IDEOGRAPH
+0xD060	0x884A	#CJK UNIFIED IDEOGRAPH
+0xD061	0x884B	#CJK UNIFIED IDEOGRAPH
+0xD062	0x884E	#CJK UNIFIED IDEOGRAPH
+0xD063	0x884F	#CJK UNIFIED IDEOGRAPH
+0xD064	0x8850	#CJK UNIFIED IDEOGRAPH
+0xD065	0x8851	#CJK UNIFIED IDEOGRAPH
+0xD066	0x8852	#CJK UNIFIED IDEOGRAPH
+0xD067	0x8853	#CJK UNIFIED IDEOGRAPH
+0xD068	0x8855	#CJK UNIFIED IDEOGRAPH
+0xD069	0x8856	#CJK UNIFIED IDEOGRAPH
+0xD06A	0x8858	#CJK UNIFIED IDEOGRAPH
+0xD06B	0x885A	#CJK UNIFIED IDEOGRAPH
+0xD06C	0x885B	#CJK UNIFIED IDEOGRAPH
+0xD06D	0x885C	#CJK UNIFIED IDEOGRAPH
+0xD06E	0x885D	#CJK UNIFIED IDEOGRAPH
+0xD06F	0x885E	#CJK UNIFIED IDEOGRAPH
+0xD070	0x885F	#CJK UNIFIED IDEOGRAPH
+0xD071	0x8860	#CJK UNIFIED IDEOGRAPH
+0xD072	0x8866	#CJK UNIFIED IDEOGRAPH
+0xD073	0x8867	#CJK UNIFIED IDEOGRAPH
+0xD074	0x886A	#CJK UNIFIED IDEOGRAPH
+0xD075	0x886D	#CJK UNIFIED IDEOGRAPH
+0xD076	0x886F	#CJK UNIFIED IDEOGRAPH
+0xD077	0x8871	#CJK UNIFIED IDEOGRAPH
+0xD078	0x8873	#CJK UNIFIED IDEOGRAPH
+0xD079	0x8874	#CJK UNIFIED IDEOGRAPH
+0xD07A	0x8875	#CJK UNIFIED IDEOGRAPH
+0xD07B	0x8876	#CJK UNIFIED IDEOGRAPH
+0xD07C	0x8878	#CJK UNIFIED IDEOGRAPH
+0xD07D	0x8879	#CJK UNIFIED IDEOGRAPH
+0xD07E	0x887A	#CJK UNIFIED IDEOGRAPH
+0xD080	0x887B	#CJK UNIFIED IDEOGRAPH
+0xD081	0x887C	#CJK UNIFIED IDEOGRAPH
+0xD082	0x8880	#CJK UNIFIED IDEOGRAPH
+0xD083	0x8883	#CJK UNIFIED IDEOGRAPH
+0xD084	0x8886	#CJK UNIFIED IDEOGRAPH
+0xD085	0x8887	#CJK UNIFIED IDEOGRAPH
+0xD086	0x8889	#CJK UNIFIED IDEOGRAPH
+0xD087	0x888A	#CJK UNIFIED IDEOGRAPH
+0xD088	0x888C	#CJK UNIFIED IDEOGRAPH
+0xD089	0x888E	#CJK UNIFIED IDEOGRAPH
+0xD08A	0x888F	#CJK UNIFIED IDEOGRAPH
+0xD08B	0x8890	#CJK UNIFIED IDEOGRAPH
+0xD08C	0x8891	#CJK UNIFIED IDEOGRAPH
+0xD08D	0x8893	#CJK UNIFIED IDEOGRAPH
+0xD08E	0x8894	#CJK UNIFIED IDEOGRAPH
+0xD08F	0x8895	#CJK UNIFIED IDEOGRAPH
+0xD090	0x8897	#CJK UNIFIED IDEOGRAPH
+0xD091	0x8898	#CJK UNIFIED IDEOGRAPH
+0xD092	0x8899	#CJK UNIFIED IDEOGRAPH
+0xD093	0x889A	#CJK UNIFIED IDEOGRAPH
+0xD094	0x889B	#CJK UNIFIED IDEOGRAPH
+0xD095	0x889D	#CJK UNIFIED IDEOGRAPH
+0xD096	0x889E	#CJK UNIFIED IDEOGRAPH
+0xD097	0x889F	#CJK UNIFIED IDEOGRAPH
+0xD098	0x88A0	#CJK UNIFIED IDEOGRAPH
+0xD099	0x88A1	#CJK UNIFIED IDEOGRAPH
+0xD09A	0x88A3	#CJK UNIFIED IDEOGRAPH
+0xD09B	0x88A5	#CJK UNIFIED IDEOGRAPH
+0xD09C	0x88A6	#CJK UNIFIED IDEOGRAPH
+0xD09D	0x88A7	#CJK UNIFIED IDEOGRAPH
+0xD09E	0x88A8	#CJK UNIFIED IDEOGRAPH
+0xD09F	0x88A9	#CJK UNIFIED IDEOGRAPH
+0xD0A0	0x88AA	#CJK UNIFIED IDEOGRAPH
+0xD0A1	0x5C0F	#CJK UNIFIED IDEOGRAPH
+0xD0A2	0x5B5D	#CJK UNIFIED IDEOGRAPH
+0xD0A3	0x6821	#CJK UNIFIED IDEOGRAPH
+0xD0A4	0x8096	#CJK UNIFIED IDEOGRAPH
+0xD0A5	0x5578	#CJK UNIFIED IDEOGRAPH
+0xD0A6	0x7B11	#CJK UNIFIED IDEOGRAPH
+0xD0A7	0x6548	#CJK UNIFIED IDEOGRAPH
+0xD0A8	0x6954	#CJK UNIFIED IDEOGRAPH
+0xD0A9	0x4E9B	#CJK UNIFIED IDEOGRAPH
+0xD0AA	0x6B47	#CJK UNIFIED IDEOGRAPH
+0xD0AB	0x874E	#CJK UNIFIED IDEOGRAPH
+0xD0AC	0x978B	#CJK UNIFIED IDEOGRAPH
+0xD0AD	0x534F	#CJK UNIFIED IDEOGRAPH
+0xD0AE	0x631F	#CJK UNIFIED IDEOGRAPH
+0xD0AF	0x643A	#CJK UNIFIED IDEOGRAPH
+0xD0B0	0x90AA	#CJK UNIFIED IDEOGRAPH
+0xD0B1	0x659C	#CJK UNIFIED IDEOGRAPH
+0xD0B2	0x80C1	#CJK UNIFIED IDEOGRAPH
+0xD0B3	0x8C10	#CJK UNIFIED IDEOGRAPH
+0xD0B4	0x5199	#CJK UNIFIED IDEOGRAPH
+0xD0B5	0x68B0	#CJK UNIFIED IDEOGRAPH
+0xD0B6	0x5378	#CJK UNIFIED IDEOGRAPH
+0xD0B7	0x87F9	#CJK UNIFIED IDEOGRAPH
+0xD0B8	0x61C8	#CJK UNIFIED IDEOGRAPH
+0xD0B9	0x6CC4	#CJK UNIFIED IDEOGRAPH
+0xD0BA	0x6CFB	#CJK UNIFIED IDEOGRAPH
+0xD0BB	0x8C22	#CJK UNIFIED IDEOGRAPH
+0xD0BC	0x5C51	#CJK UNIFIED IDEOGRAPH
+0xD0BD	0x85AA	#CJK UNIFIED IDEOGRAPH
+0xD0BE	0x82AF	#CJK UNIFIED IDEOGRAPH
+0xD0BF	0x950C	#CJK UNIFIED IDEOGRAPH
+0xD0C0	0x6B23	#CJK UNIFIED IDEOGRAPH
+0xD0C1	0x8F9B	#CJK UNIFIED IDEOGRAPH
+0xD0C2	0x65B0	#CJK UNIFIED IDEOGRAPH
+0xD0C3	0x5FFB	#CJK UNIFIED IDEOGRAPH
+0xD0C4	0x5FC3	#CJK UNIFIED IDEOGRAPH
+0xD0C5	0x4FE1	#CJK UNIFIED IDEOGRAPH
+0xD0C6	0x8845	#CJK UNIFIED IDEOGRAPH
+0xD0C7	0x661F	#CJK UNIFIED IDEOGRAPH
+0xD0C8	0x8165	#CJK UNIFIED IDEOGRAPH
+0xD0C9	0x7329	#CJK UNIFIED IDEOGRAPH
+0xD0CA	0x60FA	#CJK UNIFIED IDEOGRAPH
+0xD0CB	0x5174	#CJK UNIFIED IDEOGRAPH
+0xD0CC	0x5211	#CJK UNIFIED IDEOGRAPH
+0xD0CD	0x578B	#CJK UNIFIED IDEOGRAPH
+0xD0CE	0x5F62	#CJK UNIFIED IDEOGRAPH
+0xD0CF	0x90A2	#CJK UNIFIED IDEOGRAPH
+0xD0D0	0x884C	#CJK UNIFIED IDEOGRAPH
+0xD0D1	0x9192	#CJK UNIFIED IDEOGRAPH
+0xD0D2	0x5E78	#CJK UNIFIED IDEOGRAPH
+0xD0D3	0x674F	#CJK UNIFIED IDEOGRAPH
+0xD0D4	0x6027	#CJK UNIFIED IDEOGRAPH
+0xD0D5	0x59D3	#CJK UNIFIED IDEOGRAPH
+0xD0D6	0x5144	#CJK UNIFIED IDEOGRAPH
+0xD0D7	0x51F6	#CJK UNIFIED IDEOGRAPH
+0xD0D8	0x80F8	#CJK UNIFIED IDEOGRAPH
+0xD0D9	0x5308	#CJK UNIFIED IDEOGRAPH
+0xD0DA	0x6C79	#CJK UNIFIED IDEOGRAPH
+0xD0DB	0x96C4	#CJK UNIFIED IDEOGRAPH
+0xD0DC	0x718A	#CJK UNIFIED IDEOGRAPH
+0xD0DD	0x4F11	#CJK UNIFIED IDEOGRAPH
+0xD0DE	0x4FEE	#CJK UNIFIED IDEOGRAPH
+0xD0DF	0x7F9E	#CJK UNIFIED IDEOGRAPH
+0xD0E0	0x673D	#CJK UNIFIED IDEOGRAPH
+0xD0E1	0x55C5	#CJK UNIFIED IDEOGRAPH
+0xD0E2	0x9508	#CJK UNIFIED IDEOGRAPH
+0xD0E3	0x79C0	#CJK UNIFIED IDEOGRAPH
+0xD0E4	0x8896	#CJK UNIFIED IDEOGRAPH
+0xD0E5	0x7EE3	#CJK UNIFIED IDEOGRAPH
+0xD0E6	0x589F	#CJK UNIFIED IDEOGRAPH
+0xD0E7	0x620C	#CJK UNIFIED IDEOGRAPH
+0xD0E8	0x9700	#CJK UNIFIED IDEOGRAPH
+0xD0E9	0x865A	#CJK UNIFIED IDEOGRAPH
+0xD0EA	0x5618	#CJK UNIFIED IDEOGRAPH
+0xD0EB	0x987B	#CJK UNIFIED IDEOGRAPH
+0xD0EC	0x5F90	#CJK UNIFIED IDEOGRAPH
+0xD0ED	0x8BB8	#CJK UNIFIED IDEOGRAPH
+0xD0EE	0x84C4	#CJK UNIFIED IDEOGRAPH
+0xD0EF	0x9157	#CJK UNIFIED IDEOGRAPH
+0xD0F0	0x53D9	#CJK UNIFIED IDEOGRAPH
+0xD0F1	0x65ED	#CJK UNIFIED IDEOGRAPH
+0xD0F2	0x5E8F	#CJK UNIFIED IDEOGRAPH
+0xD0F3	0x755C	#CJK UNIFIED IDEOGRAPH
+0xD0F4	0x6064	#CJK UNIFIED IDEOGRAPH
+0xD0F5	0x7D6E	#CJK UNIFIED IDEOGRAPH
+0xD0F6	0x5A7F	#CJK UNIFIED IDEOGRAPH
+0xD0F7	0x7EEA	#CJK UNIFIED IDEOGRAPH
+0xD0F8	0x7EED	#CJK UNIFIED IDEOGRAPH
+0xD0F9	0x8F69	#CJK UNIFIED IDEOGRAPH
+0xD0FA	0x55A7	#CJK UNIFIED IDEOGRAPH
+0xD0FB	0x5BA3	#CJK UNIFIED IDEOGRAPH
+0xD0FC	0x60AC	#CJK UNIFIED IDEOGRAPH
+0xD0FD	0x65CB	#CJK UNIFIED IDEOGRAPH
+0xD0FE	0x7384	#CJK UNIFIED IDEOGRAPH
+0xD140	0x88AC	#CJK UNIFIED IDEOGRAPH
+0xD141	0x88AE	#CJK UNIFIED IDEOGRAPH
+0xD142	0x88AF	#CJK UNIFIED IDEOGRAPH
+0xD143	0x88B0	#CJK UNIFIED IDEOGRAPH
+0xD144	0x88B2	#CJK UNIFIED IDEOGRAPH
+0xD145	0x88B3	#CJK UNIFIED IDEOGRAPH
+0xD146	0x88B4	#CJK UNIFIED IDEOGRAPH
+0xD147	0x88B5	#CJK UNIFIED IDEOGRAPH
+0xD148	0x88B6	#CJK UNIFIED IDEOGRAPH
+0xD149	0x88B8	#CJK UNIFIED IDEOGRAPH
+0xD14A	0x88B9	#CJK UNIFIED IDEOGRAPH
+0xD14B	0x88BA	#CJK UNIFIED IDEOGRAPH
+0xD14C	0x88BB	#CJK UNIFIED IDEOGRAPH
+0xD14D	0x88BD	#CJK UNIFIED IDEOGRAPH
+0xD14E	0x88BE	#CJK UNIFIED IDEOGRAPH
+0xD14F	0x88BF	#CJK UNIFIED IDEOGRAPH
+0xD150	0x88C0	#CJK UNIFIED IDEOGRAPH
+0xD151	0x88C3	#CJK UNIFIED IDEOGRAPH
+0xD152	0x88C4	#CJK UNIFIED IDEOGRAPH
+0xD153	0x88C7	#CJK UNIFIED IDEOGRAPH
+0xD154	0x88C8	#CJK UNIFIED IDEOGRAPH
+0xD155	0x88CA	#CJK UNIFIED IDEOGRAPH
+0xD156	0x88CB	#CJK UNIFIED IDEOGRAPH
+0xD157	0x88CC	#CJK UNIFIED IDEOGRAPH
+0xD158	0x88CD	#CJK UNIFIED IDEOGRAPH
+0xD159	0x88CF	#CJK UNIFIED IDEOGRAPH
+0xD15A	0x88D0	#CJK UNIFIED IDEOGRAPH
+0xD15B	0x88D1	#CJK UNIFIED IDEOGRAPH
+0xD15C	0x88D3	#CJK UNIFIED IDEOGRAPH
+0xD15D	0x88D6	#CJK UNIFIED IDEOGRAPH
+0xD15E	0x88D7	#CJK UNIFIED IDEOGRAPH
+0xD15F	0x88DA	#CJK UNIFIED IDEOGRAPH
+0xD160	0x88DB	#CJK UNIFIED IDEOGRAPH
+0xD161	0x88DC	#CJK UNIFIED IDEOGRAPH
+0xD162	0x88DD	#CJK UNIFIED IDEOGRAPH
+0xD163	0x88DE	#CJK UNIFIED IDEOGRAPH
+0xD164	0x88E0	#CJK UNIFIED IDEOGRAPH
+0xD165	0x88E1	#CJK UNIFIED IDEOGRAPH
+0xD166	0x88E6	#CJK UNIFIED IDEOGRAPH
+0xD167	0x88E7	#CJK UNIFIED IDEOGRAPH
+0xD168	0x88E9	#CJK UNIFIED IDEOGRAPH
+0xD169	0x88EA	#CJK UNIFIED IDEOGRAPH
+0xD16A	0x88EB	#CJK UNIFIED IDEOGRAPH
+0xD16B	0x88EC	#CJK UNIFIED IDEOGRAPH
+0xD16C	0x88ED	#CJK UNIFIED IDEOGRAPH
+0xD16D	0x88EE	#CJK UNIFIED IDEOGRAPH
+0xD16E	0x88EF	#CJK UNIFIED IDEOGRAPH
+0xD16F	0x88F2	#CJK UNIFIED IDEOGRAPH
+0xD170	0x88F5	#CJK UNIFIED IDEOGRAPH
+0xD171	0x88F6	#CJK UNIFIED IDEOGRAPH
+0xD172	0x88F7	#CJK UNIFIED IDEOGRAPH
+0xD173	0x88FA	#CJK UNIFIED IDEOGRAPH
+0xD174	0x88FB	#CJK UNIFIED IDEOGRAPH
+0xD175	0x88FD	#CJK UNIFIED IDEOGRAPH
+0xD176	0x88FF	#CJK UNIFIED IDEOGRAPH
+0xD177	0x8900	#CJK UNIFIED IDEOGRAPH
+0xD178	0x8901	#CJK UNIFIED IDEOGRAPH
+0xD179	0x8903	#CJK UNIFIED IDEOGRAPH
+0xD17A	0x8904	#CJK UNIFIED IDEOGRAPH
+0xD17B	0x8905	#CJK UNIFIED IDEOGRAPH
+0xD17C	0x8906	#CJK UNIFIED IDEOGRAPH
+0xD17D	0x8907	#CJK UNIFIED IDEOGRAPH
+0xD17E	0x8908	#CJK UNIFIED IDEOGRAPH
+0xD180	0x8909	#CJK UNIFIED IDEOGRAPH
+0xD181	0x890B	#CJK UNIFIED IDEOGRAPH
+0xD182	0x890C	#CJK UNIFIED IDEOGRAPH
+0xD183	0x890D	#CJK UNIFIED IDEOGRAPH
+0xD184	0x890E	#CJK UNIFIED IDEOGRAPH
+0xD185	0x890F	#CJK UNIFIED IDEOGRAPH
+0xD186	0x8911	#CJK UNIFIED IDEOGRAPH
+0xD187	0x8914	#CJK UNIFIED IDEOGRAPH
+0xD188	0x8915	#CJK UNIFIED IDEOGRAPH
+0xD189	0x8916	#CJK UNIFIED IDEOGRAPH
+0xD18A	0x8917	#CJK UNIFIED IDEOGRAPH
+0xD18B	0x8918	#CJK UNIFIED IDEOGRAPH
+0xD18C	0x891C	#CJK UNIFIED IDEOGRAPH
+0xD18D	0x891D	#CJK UNIFIED IDEOGRAPH
+0xD18E	0x891E	#CJK UNIFIED IDEOGRAPH
+0xD18F	0x891F	#CJK UNIFIED IDEOGRAPH
+0xD190	0x8920	#CJK UNIFIED IDEOGRAPH
+0xD191	0x8922	#CJK UNIFIED IDEOGRAPH
+0xD192	0x8923	#CJK UNIFIED IDEOGRAPH
+0xD193	0x8924	#CJK UNIFIED IDEOGRAPH
+0xD194	0x8926	#CJK UNIFIED IDEOGRAPH
+0xD195	0x8927	#CJK UNIFIED IDEOGRAPH
+0xD196	0x8928	#CJK UNIFIED IDEOGRAPH
+0xD197	0x8929	#CJK UNIFIED IDEOGRAPH
+0xD198	0x892C	#CJK UNIFIED IDEOGRAPH
+0xD199	0x892D	#CJK UNIFIED IDEOGRAPH
+0xD19A	0x892E	#CJK UNIFIED IDEOGRAPH
+0xD19B	0x892F	#CJK UNIFIED IDEOGRAPH
+0xD19C	0x8931	#CJK UNIFIED IDEOGRAPH
+0xD19D	0x8932	#CJK UNIFIED IDEOGRAPH
+0xD19E	0x8933	#CJK UNIFIED IDEOGRAPH
+0xD19F	0x8935	#CJK UNIFIED IDEOGRAPH
+0xD1A0	0x8937	#CJK UNIFIED IDEOGRAPH
+0xD1A1	0x9009	#CJK UNIFIED IDEOGRAPH
+0xD1A2	0x7663	#CJK UNIFIED IDEOGRAPH
+0xD1A3	0x7729	#CJK UNIFIED IDEOGRAPH
+0xD1A4	0x7EDA	#CJK UNIFIED IDEOGRAPH
+0xD1A5	0x9774	#CJK UNIFIED IDEOGRAPH
+0xD1A6	0x859B	#CJK UNIFIED IDEOGRAPH
+0xD1A7	0x5B66	#CJK UNIFIED IDEOGRAPH
+0xD1A8	0x7A74	#CJK UNIFIED IDEOGRAPH
+0xD1A9	0x96EA	#CJK UNIFIED IDEOGRAPH
+0xD1AA	0x8840	#CJK UNIFIED IDEOGRAPH
+0xD1AB	0x52CB	#CJK UNIFIED IDEOGRAPH
+0xD1AC	0x718F	#CJK UNIFIED IDEOGRAPH
+0xD1AD	0x5FAA	#CJK UNIFIED IDEOGRAPH
+0xD1AE	0x65EC	#CJK UNIFIED IDEOGRAPH
+0xD1AF	0x8BE2	#CJK UNIFIED IDEOGRAPH
+0xD1B0	0x5BFB	#CJK UNIFIED IDEOGRAPH
+0xD1B1	0x9A6F	#CJK UNIFIED IDEOGRAPH
+0xD1B2	0x5DE1	#CJK UNIFIED IDEOGRAPH
+0xD1B3	0x6B89	#CJK UNIFIED IDEOGRAPH
+0xD1B4	0x6C5B	#CJK UNIFIED IDEOGRAPH
+0xD1B5	0x8BAD	#CJK UNIFIED IDEOGRAPH
+0xD1B6	0x8BAF	#CJK UNIFIED IDEOGRAPH
+0xD1B7	0x900A	#CJK UNIFIED IDEOGRAPH
+0xD1B8	0x8FC5	#CJK UNIFIED IDEOGRAPH
+0xD1B9	0x538B	#CJK UNIFIED IDEOGRAPH
+0xD1BA	0x62BC	#CJK UNIFIED IDEOGRAPH
+0xD1BB	0x9E26	#CJK UNIFIED IDEOGRAPH
+0xD1BC	0x9E2D	#CJK UNIFIED IDEOGRAPH
+0xD1BD	0x5440	#CJK UNIFIED IDEOGRAPH
+0xD1BE	0x4E2B	#CJK UNIFIED IDEOGRAPH
+0xD1BF	0x82BD	#CJK UNIFIED IDEOGRAPH
+0xD1C0	0x7259	#CJK UNIFIED IDEOGRAPH
+0xD1C1	0x869C	#CJK UNIFIED IDEOGRAPH
+0xD1C2	0x5D16	#CJK UNIFIED IDEOGRAPH
+0xD1C3	0x8859	#CJK UNIFIED IDEOGRAPH
+0xD1C4	0x6DAF	#CJK UNIFIED IDEOGRAPH
+0xD1C5	0x96C5	#CJK UNIFIED IDEOGRAPH
+0xD1C6	0x54D1	#CJK UNIFIED IDEOGRAPH
+0xD1C7	0x4E9A	#CJK UNIFIED IDEOGRAPH
+0xD1C8	0x8BB6	#CJK UNIFIED IDEOGRAPH
+0xD1C9	0x7109	#CJK UNIFIED IDEOGRAPH
+0xD1CA	0x54BD	#CJK UNIFIED IDEOGRAPH
+0xD1CB	0x9609	#CJK UNIFIED IDEOGRAPH
+0xD1CC	0x70DF	#CJK UNIFIED IDEOGRAPH
+0xD1CD	0x6DF9	#CJK UNIFIED IDEOGRAPH
+0xD1CE	0x76D0	#CJK UNIFIED IDEOGRAPH
+0xD1CF	0x4E25	#CJK UNIFIED IDEOGRAPH
+0xD1D0	0x7814	#CJK UNIFIED IDEOGRAPH
+0xD1D1	0x8712	#CJK UNIFIED IDEOGRAPH
+0xD1D2	0x5CA9	#CJK UNIFIED IDEOGRAPH
+0xD1D3	0x5EF6	#CJK UNIFIED IDEOGRAPH
+0xD1D4	0x8A00	#CJK UNIFIED IDEOGRAPH
+0xD1D5	0x989C	#CJK UNIFIED IDEOGRAPH
+0xD1D6	0x960E	#CJK UNIFIED IDEOGRAPH
+0xD1D7	0x708E	#CJK UNIFIED IDEOGRAPH
+0xD1D8	0x6CBF	#CJK UNIFIED IDEOGRAPH
+0xD1D9	0x5944	#CJK UNIFIED IDEOGRAPH
+0xD1DA	0x63A9	#CJK UNIFIED IDEOGRAPH
+0xD1DB	0x773C	#CJK UNIFIED IDEOGRAPH
+0xD1DC	0x884D	#CJK UNIFIED IDEOGRAPH
+0xD1DD	0x6F14	#CJK UNIFIED IDEOGRAPH
+0xD1DE	0x8273	#CJK UNIFIED IDEOGRAPH
+0xD1DF	0x5830	#CJK UNIFIED IDEOGRAPH
+0xD1E0	0x71D5	#CJK UNIFIED IDEOGRAPH
+0xD1E1	0x538C	#CJK UNIFIED IDEOGRAPH
+0xD1E2	0x781A	#CJK UNIFIED IDEOGRAPH
+0xD1E3	0x96C1	#CJK UNIFIED IDEOGRAPH
+0xD1E4	0x5501	#CJK UNIFIED IDEOGRAPH
+0xD1E5	0x5F66	#CJK UNIFIED IDEOGRAPH
+0xD1E6	0x7130	#CJK UNIFIED IDEOGRAPH
+0xD1E7	0x5BB4	#CJK UNIFIED IDEOGRAPH
+0xD1E8	0x8C1A	#CJK UNIFIED IDEOGRAPH
+0xD1E9	0x9A8C	#CJK UNIFIED IDEOGRAPH
+0xD1EA	0x6B83	#CJK UNIFIED IDEOGRAPH
+0xD1EB	0x592E	#CJK UNIFIED IDEOGRAPH
+0xD1EC	0x9E2F	#CJK UNIFIED IDEOGRAPH
+0xD1ED	0x79E7	#CJK UNIFIED IDEOGRAPH
+0xD1EE	0x6768	#CJK UNIFIED IDEOGRAPH
+0xD1EF	0x626C	#CJK UNIFIED IDEOGRAPH
+0xD1F0	0x4F6F	#CJK UNIFIED IDEOGRAPH
+0xD1F1	0x75A1	#CJK UNIFIED IDEOGRAPH
+0xD1F2	0x7F8A	#CJK UNIFIED IDEOGRAPH
+0xD1F3	0x6D0B	#CJK UNIFIED IDEOGRAPH
+0xD1F4	0x9633	#CJK UNIFIED IDEOGRAPH
+0xD1F5	0x6C27	#CJK UNIFIED IDEOGRAPH
+0xD1F6	0x4EF0	#CJK UNIFIED IDEOGRAPH
+0xD1F7	0x75D2	#CJK UNIFIED IDEOGRAPH
+0xD1F8	0x517B	#CJK UNIFIED IDEOGRAPH
+0xD1F9	0x6837	#CJK UNIFIED IDEOGRAPH
+0xD1FA	0x6F3E	#CJK UNIFIED IDEOGRAPH
+0xD1FB	0x9080	#CJK UNIFIED IDEOGRAPH
+0xD1FC	0x8170	#CJK UNIFIED IDEOGRAPH
+0xD1FD	0x5996	#CJK UNIFIED IDEOGRAPH
+0xD1FE	0x7476	#CJK UNIFIED IDEOGRAPH
+0xD240	0x8938	#CJK UNIFIED IDEOGRAPH
+0xD241	0x8939	#CJK UNIFIED IDEOGRAPH
+0xD242	0x893A	#CJK UNIFIED IDEOGRAPH
+0xD243	0x893B	#CJK UNIFIED IDEOGRAPH
+0xD244	0x893C	#CJK UNIFIED IDEOGRAPH
+0xD245	0x893D	#CJK UNIFIED IDEOGRAPH
+0xD246	0x893E	#CJK UNIFIED IDEOGRAPH
+0xD247	0x893F	#CJK UNIFIED IDEOGRAPH
+0xD248	0x8940	#CJK UNIFIED IDEOGRAPH
+0xD249	0x8942	#CJK UNIFIED IDEOGRAPH
+0xD24A	0x8943	#CJK UNIFIED IDEOGRAPH
+0xD24B	0x8945	#CJK UNIFIED IDEOGRAPH
+0xD24C	0x8946	#CJK UNIFIED IDEOGRAPH
+0xD24D	0x8947	#CJK UNIFIED IDEOGRAPH
+0xD24E	0x8948	#CJK UNIFIED IDEOGRAPH
+0xD24F	0x8949	#CJK UNIFIED IDEOGRAPH
+0xD250	0x894A	#CJK UNIFIED IDEOGRAPH
+0xD251	0x894B	#CJK UNIFIED IDEOGRAPH
+0xD252	0x894C	#CJK UNIFIED IDEOGRAPH
+0xD253	0x894D	#CJK UNIFIED IDEOGRAPH
+0xD254	0x894E	#CJK UNIFIED IDEOGRAPH
+0xD255	0x894F	#CJK UNIFIED IDEOGRAPH
+0xD256	0x8950	#CJK UNIFIED IDEOGRAPH
+0xD257	0x8951	#CJK UNIFIED IDEOGRAPH
+0xD258	0x8952	#CJK UNIFIED IDEOGRAPH
+0xD259	0x8953	#CJK UNIFIED IDEOGRAPH
+0xD25A	0x8954	#CJK UNIFIED IDEOGRAPH
+0xD25B	0x8955	#CJK UNIFIED IDEOGRAPH
+0xD25C	0x8956	#CJK UNIFIED IDEOGRAPH
+0xD25D	0x8957	#CJK UNIFIED IDEOGRAPH
+0xD25E	0x8958	#CJK UNIFIED IDEOGRAPH
+0xD25F	0x8959	#CJK UNIFIED IDEOGRAPH
+0xD260	0x895A	#CJK UNIFIED IDEOGRAPH
+0xD261	0x895B	#CJK UNIFIED IDEOGRAPH
+0xD262	0x895C	#CJK UNIFIED IDEOGRAPH
+0xD263	0x895D	#CJK UNIFIED IDEOGRAPH
+0xD264	0x8960	#CJK UNIFIED IDEOGRAPH
+0xD265	0x8961	#CJK UNIFIED IDEOGRAPH
+0xD266	0x8962	#CJK UNIFIED IDEOGRAPH
+0xD267	0x8963	#CJK UNIFIED IDEOGRAPH
+0xD268	0x8964	#CJK UNIFIED IDEOGRAPH
+0xD269	0x8965	#CJK UNIFIED IDEOGRAPH
+0xD26A	0x8967	#CJK UNIFIED IDEOGRAPH
+0xD26B	0x8968	#CJK UNIFIED IDEOGRAPH
+0xD26C	0x8969	#CJK UNIFIED IDEOGRAPH
+0xD26D	0x896A	#CJK UNIFIED IDEOGRAPH
+0xD26E	0x896B	#CJK UNIFIED IDEOGRAPH
+0xD26F	0x896C	#CJK UNIFIED IDEOGRAPH
+0xD270	0x896D	#CJK UNIFIED IDEOGRAPH
+0xD271	0x896E	#CJK UNIFIED IDEOGRAPH
+0xD272	0x896F	#CJK UNIFIED IDEOGRAPH
+0xD273	0x8970	#CJK UNIFIED IDEOGRAPH
+0xD274	0x8971	#CJK UNIFIED IDEOGRAPH
+0xD275	0x8972	#CJK UNIFIED IDEOGRAPH
+0xD276	0x8973	#CJK UNIFIED IDEOGRAPH
+0xD277	0x8974	#CJK UNIFIED IDEOGRAPH
+0xD278	0x8975	#CJK UNIFIED IDEOGRAPH
+0xD279	0x8976	#CJK UNIFIED IDEOGRAPH
+0xD27A	0x8977	#CJK UNIFIED IDEOGRAPH
+0xD27B	0x8978	#CJK UNIFIED IDEOGRAPH
+0xD27C	0x8979	#CJK UNIFIED IDEOGRAPH
+0xD27D	0x897A	#CJK UNIFIED IDEOGRAPH
+0xD27E	0x897C	#CJK UNIFIED IDEOGRAPH
+0xD280	0x897D	#CJK UNIFIED IDEOGRAPH
+0xD281	0x897E	#CJK UNIFIED IDEOGRAPH
+0xD282	0x8980	#CJK UNIFIED IDEOGRAPH
+0xD283	0x8982	#CJK UNIFIED IDEOGRAPH
+0xD284	0x8984	#CJK UNIFIED IDEOGRAPH
+0xD285	0x8985	#CJK UNIFIED IDEOGRAPH
+0xD286	0x8987	#CJK UNIFIED IDEOGRAPH
+0xD287	0x8988	#CJK UNIFIED IDEOGRAPH
+0xD288	0x8989	#CJK UNIFIED IDEOGRAPH
+0xD289	0x898A	#CJK UNIFIED IDEOGRAPH
+0xD28A	0x898B	#CJK UNIFIED IDEOGRAPH
+0xD28B	0x898C	#CJK UNIFIED IDEOGRAPH
+0xD28C	0x898D	#CJK UNIFIED IDEOGRAPH
+0xD28D	0x898E	#CJK UNIFIED IDEOGRAPH
+0xD28E	0x898F	#CJK UNIFIED IDEOGRAPH
+0xD28F	0x8990	#CJK UNIFIED IDEOGRAPH
+0xD290	0x8991	#CJK UNIFIED IDEOGRAPH
+0xD291	0x8992	#CJK UNIFIED IDEOGRAPH
+0xD292	0x8993	#CJK UNIFIED IDEOGRAPH
+0xD293	0x8994	#CJK UNIFIED IDEOGRAPH
+0xD294	0x8995	#CJK UNIFIED IDEOGRAPH
+0xD295	0x8996	#CJK UNIFIED IDEOGRAPH
+0xD296	0x8997	#CJK UNIFIED IDEOGRAPH
+0xD297	0x8998	#CJK UNIFIED IDEOGRAPH
+0xD298	0x8999	#CJK UNIFIED IDEOGRAPH
+0xD299	0x899A	#CJK UNIFIED IDEOGRAPH
+0xD29A	0x899B	#CJK UNIFIED IDEOGRAPH
+0xD29B	0x899C	#CJK UNIFIED IDEOGRAPH
+0xD29C	0x899D	#CJK UNIFIED IDEOGRAPH
+0xD29D	0x899E	#CJK UNIFIED IDEOGRAPH
+0xD29E	0x899F	#CJK UNIFIED IDEOGRAPH
+0xD29F	0x89A0	#CJK UNIFIED IDEOGRAPH
+0xD2A0	0x89A1	#CJK UNIFIED IDEOGRAPH
+0xD2A1	0x6447	#CJK UNIFIED IDEOGRAPH
+0xD2A2	0x5C27	#CJK UNIFIED IDEOGRAPH
+0xD2A3	0x9065	#CJK UNIFIED IDEOGRAPH
+0xD2A4	0x7A91	#CJK UNIFIED IDEOGRAPH
+0xD2A5	0x8C23	#CJK UNIFIED IDEOGRAPH
+0xD2A6	0x59DA	#CJK UNIFIED IDEOGRAPH
+0xD2A7	0x54AC	#CJK UNIFIED IDEOGRAPH
+0xD2A8	0x8200	#CJK UNIFIED IDEOGRAPH
+0xD2A9	0x836F	#CJK UNIFIED IDEOGRAPH
+0xD2AA	0x8981	#CJK UNIFIED IDEOGRAPH
+0xD2AB	0x8000	#CJK UNIFIED IDEOGRAPH
+0xD2AC	0x6930	#CJK UNIFIED IDEOGRAPH
+0xD2AD	0x564E	#CJK UNIFIED IDEOGRAPH
+0xD2AE	0x8036	#CJK UNIFIED IDEOGRAPH
+0xD2AF	0x7237	#CJK UNIFIED IDEOGRAPH
+0xD2B0	0x91CE	#CJK UNIFIED IDEOGRAPH
+0xD2B1	0x51B6	#CJK UNIFIED IDEOGRAPH
+0xD2B2	0x4E5F	#CJK UNIFIED IDEOGRAPH
+0xD2B3	0x9875	#CJK UNIFIED IDEOGRAPH
+0xD2B4	0x6396	#CJK UNIFIED IDEOGRAPH
+0xD2B5	0x4E1A	#CJK UNIFIED IDEOGRAPH
+0xD2B6	0x53F6	#CJK UNIFIED IDEOGRAPH
+0xD2B7	0x66F3	#CJK UNIFIED IDEOGRAPH
+0xD2B8	0x814B	#CJK UNIFIED IDEOGRAPH
+0xD2B9	0x591C	#CJK UNIFIED IDEOGRAPH
+0xD2BA	0x6DB2	#CJK UNIFIED IDEOGRAPH
+0xD2BB	0x4E00	#CJK UNIFIED IDEOGRAPH
+0xD2BC	0x58F9	#CJK UNIFIED IDEOGRAPH
+0xD2BD	0x533B	#CJK UNIFIED IDEOGRAPH
+0xD2BE	0x63D6	#CJK UNIFIED IDEOGRAPH
+0xD2BF	0x94F1	#CJK UNIFIED IDEOGRAPH
+0xD2C0	0x4F9D	#CJK UNIFIED IDEOGRAPH
+0xD2C1	0x4F0A	#CJK UNIFIED IDEOGRAPH
+0xD2C2	0x8863	#CJK UNIFIED IDEOGRAPH
+0xD2C3	0x9890	#CJK UNIFIED IDEOGRAPH
+0xD2C4	0x5937	#CJK UNIFIED IDEOGRAPH
+0xD2C5	0x9057	#CJK UNIFIED IDEOGRAPH
+0xD2C6	0x79FB	#CJK UNIFIED IDEOGRAPH
+0xD2C7	0x4EEA	#CJK UNIFIED IDEOGRAPH
+0xD2C8	0x80F0	#CJK UNIFIED IDEOGRAPH
+0xD2C9	0x7591	#CJK UNIFIED IDEOGRAPH
+0xD2CA	0x6C82	#CJK UNIFIED IDEOGRAPH
+0xD2CB	0x5B9C	#CJK UNIFIED IDEOGRAPH
+0xD2CC	0x59E8	#CJK UNIFIED IDEOGRAPH
+0xD2CD	0x5F5D	#CJK UNIFIED IDEOGRAPH
+0xD2CE	0x6905	#CJK UNIFIED IDEOGRAPH
+0xD2CF	0x8681	#CJK UNIFIED IDEOGRAPH
+0xD2D0	0x501A	#CJK UNIFIED IDEOGRAPH
+0xD2D1	0x5DF2	#CJK UNIFIED IDEOGRAPH
+0xD2D2	0x4E59	#CJK UNIFIED IDEOGRAPH
+0xD2D3	0x77E3	#CJK UNIFIED IDEOGRAPH
+0xD2D4	0x4EE5	#CJK UNIFIED IDEOGRAPH
+0xD2D5	0x827A	#CJK UNIFIED IDEOGRAPH
+0xD2D6	0x6291	#CJK UNIFIED IDEOGRAPH
+0xD2D7	0x6613	#CJK UNIFIED IDEOGRAPH
+0xD2D8	0x9091	#CJK UNIFIED IDEOGRAPH
+0xD2D9	0x5C79	#CJK UNIFIED IDEOGRAPH
+0xD2DA	0x4EBF	#CJK UNIFIED IDEOGRAPH
+0xD2DB	0x5F79	#CJK UNIFIED IDEOGRAPH
+0xD2DC	0x81C6	#CJK UNIFIED IDEOGRAPH
+0xD2DD	0x9038	#CJK UNIFIED IDEOGRAPH
+0xD2DE	0x8084	#CJK UNIFIED IDEOGRAPH
+0xD2DF	0x75AB	#CJK UNIFIED IDEOGRAPH
+0xD2E0	0x4EA6	#CJK UNIFIED IDEOGRAPH
+0xD2E1	0x88D4	#CJK UNIFIED IDEOGRAPH
+0xD2E2	0x610F	#CJK UNIFIED IDEOGRAPH
+0xD2E3	0x6BC5	#CJK UNIFIED IDEOGRAPH
+0xD2E4	0x5FC6	#CJK UNIFIED IDEOGRAPH
+0xD2E5	0x4E49	#CJK UNIFIED IDEOGRAPH
+0xD2E6	0x76CA	#CJK UNIFIED IDEOGRAPH
+0xD2E7	0x6EA2	#CJK UNIFIED IDEOGRAPH
+0xD2E8	0x8BE3	#CJK UNIFIED IDEOGRAPH
+0xD2E9	0x8BAE	#CJK UNIFIED IDEOGRAPH
+0xD2EA	0x8C0A	#CJK UNIFIED IDEOGRAPH
+0xD2EB	0x8BD1	#CJK UNIFIED IDEOGRAPH
+0xD2EC	0x5F02	#CJK UNIFIED IDEOGRAPH
+0xD2ED	0x7FFC	#CJK UNIFIED IDEOGRAPH
+0xD2EE	0x7FCC	#CJK UNIFIED IDEOGRAPH
+0xD2EF	0x7ECE	#CJK UNIFIED IDEOGRAPH
+0xD2F0	0x8335	#CJK UNIFIED IDEOGRAPH
+0xD2F1	0x836B	#CJK UNIFIED IDEOGRAPH
+0xD2F2	0x56E0	#CJK UNIFIED IDEOGRAPH
+0xD2F3	0x6BB7	#CJK UNIFIED IDEOGRAPH
+0xD2F4	0x97F3	#CJK UNIFIED IDEOGRAPH
+0xD2F5	0x9634	#CJK UNIFIED IDEOGRAPH
+0xD2F6	0x59FB	#CJK UNIFIED IDEOGRAPH
+0xD2F7	0x541F	#CJK UNIFIED IDEOGRAPH
+0xD2F8	0x94F6	#CJK UNIFIED IDEOGRAPH
+0xD2F9	0x6DEB	#CJK UNIFIED IDEOGRAPH
+0xD2FA	0x5BC5	#CJK UNIFIED IDEOGRAPH
+0xD2FB	0x996E	#CJK UNIFIED IDEOGRAPH
+0xD2FC	0x5C39	#CJK UNIFIED IDEOGRAPH
+0xD2FD	0x5F15	#CJK UNIFIED IDEOGRAPH
+0xD2FE	0x9690	#CJK UNIFIED IDEOGRAPH
+0xD340	0x89A2	#CJK UNIFIED IDEOGRAPH
+0xD341	0x89A3	#CJK UNIFIED IDEOGRAPH
+0xD342	0x89A4	#CJK UNIFIED IDEOGRAPH
+0xD343	0x89A5	#CJK UNIFIED IDEOGRAPH
+0xD344	0x89A6	#CJK UNIFIED IDEOGRAPH
+0xD345	0x89A7	#CJK UNIFIED IDEOGRAPH
+0xD346	0x89A8	#CJK UNIFIED IDEOGRAPH
+0xD347	0x89A9	#CJK UNIFIED IDEOGRAPH
+0xD348	0x89AA	#CJK UNIFIED IDEOGRAPH
+0xD349	0x89AB	#CJK UNIFIED IDEOGRAPH
+0xD34A	0x89AC	#CJK UNIFIED IDEOGRAPH
+0xD34B	0x89AD	#CJK UNIFIED IDEOGRAPH
+0xD34C	0x89AE	#CJK UNIFIED IDEOGRAPH
+0xD34D	0x89AF	#CJK UNIFIED IDEOGRAPH
+0xD34E	0x89B0	#CJK UNIFIED IDEOGRAPH
+0xD34F	0x89B1	#CJK UNIFIED IDEOGRAPH
+0xD350	0x89B2	#CJK UNIFIED IDEOGRAPH
+0xD351	0x89B3	#CJK UNIFIED IDEOGRAPH
+0xD352	0x89B4	#CJK UNIFIED IDEOGRAPH
+0xD353	0x89B5	#CJK UNIFIED IDEOGRAPH
+0xD354	0x89B6	#CJK UNIFIED IDEOGRAPH
+0xD355	0x89B7	#CJK UNIFIED IDEOGRAPH
+0xD356	0x89B8	#CJK UNIFIED IDEOGRAPH
+0xD357	0x89B9	#CJK UNIFIED IDEOGRAPH
+0xD358	0x89BA	#CJK UNIFIED IDEOGRAPH
+0xD359	0x89BB	#CJK UNIFIED IDEOGRAPH
+0xD35A	0x89BC	#CJK UNIFIED IDEOGRAPH
+0xD35B	0x89BD	#CJK UNIFIED IDEOGRAPH
+0xD35C	0x89BE	#CJK UNIFIED IDEOGRAPH
+0xD35D	0x89BF	#CJK UNIFIED IDEOGRAPH
+0xD35E	0x89C0	#CJK UNIFIED IDEOGRAPH
+0xD35F	0x89C3	#CJK UNIFIED IDEOGRAPH
+0xD360	0x89CD	#CJK UNIFIED IDEOGRAPH
+0xD361	0x89D3	#CJK UNIFIED IDEOGRAPH
+0xD362	0x89D4	#CJK UNIFIED IDEOGRAPH
+0xD363	0x89D5	#CJK UNIFIED IDEOGRAPH
+0xD364	0x89D7	#CJK UNIFIED IDEOGRAPH
+0xD365	0x89D8	#CJK UNIFIED IDEOGRAPH
+0xD366	0x89D9	#CJK UNIFIED IDEOGRAPH
+0xD367	0x89DB	#CJK UNIFIED IDEOGRAPH
+0xD368	0x89DD	#CJK UNIFIED IDEOGRAPH
+0xD369	0x89DF	#CJK UNIFIED IDEOGRAPH
+0xD36A	0x89E0	#CJK UNIFIED IDEOGRAPH
+0xD36B	0x89E1	#CJK UNIFIED IDEOGRAPH
+0xD36C	0x89E2	#CJK UNIFIED IDEOGRAPH
+0xD36D	0x89E4	#CJK UNIFIED IDEOGRAPH
+0xD36E	0x89E7	#CJK UNIFIED IDEOGRAPH
+0xD36F	0x89E8	#CJK UNIFIED IDEOGRAPH
+0xD370	0x89E9	#CJK UNIFIED IDEOGRAPH
+0xD371	0x89EA	#CJK UNIFIED IDEOGRAPH
+0xD372	0x89EC	#CJK UNIFIED IDEOGRAPH
+0xD373	0x89ED	#CJK UNIFIED IDEOGRAPH
+0xD374	0x89EE	#CJK UNIFIED IDEOGRAPH
+0xD375	0x89F0	#CJK UNIFIED IDEOGRAPH
+0xD376	0x89F1	#CJK UNIFIED IDEOGRAPH
+0xD377	0x89F2	#CJK UNIFIED IDEOGRAPH
+0xD378	0x89F4	#CJK UNIFIED IDEOGRAPH
+0xD379	0x89F5	#CJK UNIFIED IDEOGRAPH
+0xD37A	0x89F6	#CJK UNIFIED IDEOGRAPH
+0xD37B	0x89F7	#CJK UNIFIED IDEOGRAPH
+0xD37C	0x89F8	#CJK UNIFIED IDEOGRAPH
+0xD37D	0x89F9	#CJK UNIFIED IDEOGRAPH
+0xD37E	0x89FA	#CJK UNIFIED IDEOGRAPH
+0xD380	0x89FB	#CJK UNIFIED IDEOGRAPH
+0xD381	0x89FC	#CJK UNIFIED IDEOGRAPH
+0xD382	0x89FD	#CJK UNIFIED IDEOGRAPH
+0xD383	0x89FE	#CJK UNIFIED IDEOGRAPH
+0xD384	0x89FF	#CJK UNIFIED IDEOGRAPH
+0xD385	0x8A01	#CJK UNIFIED IDEOGRAPH
+0xD386	0x8A02	#CJK UNIFIED IDEOGRAPH
+0xD387	0x8A03	#CJK UNIFIED IDEOGRAPH
+0xD388	0x8A04	#CJK UNIFIED IDEOGRAPH
+0xD389	0x8A05	#CJK UNIFIED IDEOGRAPH
+0xD38A	0x8A06	#CJK UNIFIED IDEOGRAPH
+0xD38B	0x8A08	#CJK UNIFIED IDEOGRAPH
+0xD38C	0x8A09	#CJK UNIFIED IDEOGRAPH
+0xD38D	0x8A0A	#CJK UNIFIED IDEOGRAPH
+0xD38E	0x8A0B	#CJK UNIFIED IDEOGRAPH
+0xD38F	0x8A0C	#CJK UNIFIED IDEOGRAPH
+0xD390	0x8A0D	#CJK UNIFIED IDEOGRAPH
+0xD391	0x8A0E	#CJK UNIFIED IDEOGRAPH
+0xD392	0x8A0F	#CJK UNIFIED IDEOGRAPH
+0xD393	0x8A10	#CJK UNIFIED IDEOGRAPH
+0xD394	0x8A11	#CJK UNIFIED IDEOGRAPH
+0xD395	0x8A12	#CJK UNIFIED IDEOGRAPH
+0xD396	0x8A13	#CJK UNIFIED IDEOGRAPH
+0xD397	0x8A14	#CJK UNIFIED IDEOGRAPH
+0xD398	0x8A15	#CJK UNIFIED IDEOGRAPH
+0xD399	0x8A16	#CJK UNIFIED IDEOGRAPH
+0xD39A	0x8A17	#CJK UNIFIED IDEOGRAPH
+0xD39B	0x8A18	#CJK UNIFIED IDEOGRAPH
+0xD39C	0x8A19	#CJK UNIFIED IDEOGRAPH
+0xD39D	0x8A1A	#CJK UNIFIED IDEOGRAPH
+0xD39E	0x8A1B	#CJK UNIFIED IDEOGRAPH
+0xD39F	0x8A1C	#CJK UNIFIED IDEOGRAPH
+0xD3A0	0x8A1D	#CJK UNIFIED IDEOGRAPH
+0xD3A1	0x5370	#CJK UNIFIED IDEOGRAPH
+0xD3A2	0x82F1	#CJK UNIFIED IDEOGRAPH
+0xD3A3	0x6A31	#CJK UNIFIED IDEOGRAPH
+0xD3A4	0x5A74	#CJK UNIFIED IDEOGRAPH
+0xD3A5	0x9E70	#CJK UNIFIED IDEOGRAPH
+0xD3A6	0x5E94	#CJK UNIFIED IDEOGRAPH
+0xD3A7	0x7F28	#CJK UNIFIED IDEOGRAPH
+0xD3A8	0x83B9	#CJK UNIFIED IDEOGRAPH
+0xD3A9	0x8424	#CJK UNIFIED IDEOGRAPH
+0xD3AA	0x8425	#CJK UNIFIED IDEOGRAPH
+0xD3AB	0x8367	#CJK UNIFIED IDEOGRAPH
+0xD3AC	0x8747	#CJK UNIFIED IDEOGRAPH
+0xD3AD	0x8FCE	#CJK UNIFIED IDEOGRAPH
+0xD3AE	0x8D62	#CJK UNIFIED IDEOGRAPH
+0xD3AF	0x76C8	#CJK UNIFIED IDEOGRAPH
+0xD3B0	0x5F71	#CJK UNIFIED IDEOGRAPH
+0xD3B1	0x9896	#CJK UNIFIED IDEOGRAPH
+0xD3B2	0x786C	#CJK UNIFIED IDEOGRAPH
+0xD3B3	0x6620	#CJK UNIFIED IDEOGRAPH
+0xD3B4	0x54DF	#CJK UNIFIED IDEOGRAPH
+0xD3B5	0x62E5	#CJK UNIFIED IDEOGRAPH
+0xD3B6	0x4F63	#CJK UNIFIED IDEOGRAPH
+0xD3B7	0x81C3	#CJK UNIFIED IDEOGRAPH
+0xD3B8	0x75C8	#CJK UNIFIED IDEOGRAPH
+0xD3B9	0x5EB8	#CJK UNIFIED IDEOGRAPH
+0xD3BA	0x96CD	#CJK UNIFIED IDEOGRAPH
+0xD3BB	0x8E0A	#CJK UNIFIED IDEOGRAPH
+0xD3BC	0x86F9	#CJK UNIFIED IDEOGRAPH
+0xD3BD	0x548F	#CJK UNIFIED IDEOGRAPH
+0xD3BE	0x6CF3	#CJK UNIFIED IDEOGRAPH
+0xD3BF	0x6D8C	#CJK UNIFIED IDEOGRAPH
+0xD3C0	0x6C38	#CJK UNIFIED IDEOGRAPH
+0xD3C1	0x607F	#CJK UNIFIED IDEOGRAPH
+0xD3C2	0x52C7	#CJK UNIFIED IDEOGRAPH
+0xD3C3	0x7528	#CJK UNIFIED IDEOGRAPH
+0xD3C4	0x5E7D	#CJK UNIFIED IDEOGRAPH
+0xD3C5	0x4F18	#CJK UNIFIED IDEOGRAPH
+0xD3C6	0x60A0	#CJK UNIFIED IDEOGRAPH
+0xD3C7	0x5FE7	#CJK UNIFIED IDEOGRAPH
+0xD3C8	0x5C24	#CJK UNIFIED IDEOGRAPH
+0xD3C9	0x7531	#CJK UNIFIED IDEOGRAPH
+0xD3CA	0x90AE	#CJK UNIFIED IDEOGRAPH
+0xD3CB	0x94C0	#CJK UNIFIED IDEOGRAPH
+0xD3CC	0x72B9	#CJK UNIFIED IDEOGRAPH
+0xD3CD	0x6CB9	#CJK UNIFIED IDEOGRAPH
+0xD3CE	0x6E38	#CJK UNIFIED IDEOGRAPH
+0xD3CF	0x9149	#CJK UNIFIED IDEOGRAPH
+0xD3D0	0x6709	#CJK UNIFIED IDEOGRAPH
+0xD3D1	0x53CB	#CJK UNIFIED IDEOGRAPH
+0xD3D2	0x53F3	#CJK UNIFIED IDEOGRAPH
+0xD3D3	0x4F51	#CJK UNIFIED IDEOGRAPH
+0xD3D4	0x91C9	#CJK UNIFIED IDEOGRAPH
+0xD3D5	0x8BF1	#CJK UNIFIED IDEOGRAPH
+0xD3D6	0x53C8	#CJK UNIFIED IDEOGRAPH
+0xD3D7	0x5E7C	#CJK UNIFIED IDEOGRAPH
+0xD3D8	0x8FC2	#CJK UNIFIED IDEOGRAPH
+0xD3D9	0x6DE4	#CJK UNIFIED IDEOGRAPH
+0xD3DA	0x4E8E	#CJK UNIFIED IDEOGRAPH
+0xD3DB	0x76C2	#CJK UNIFIED IDEOGRAPH
+0xD3DC	0x6986	#CJK UNIFIED IDEOGRAPH
+0xD3DD	0x865E	#CJK UNIFIED IDEOGRAPH
+0xD3DE	0x611A	#CJK UNIFIED IDEOGRAPH
+0xD3DF	0x8206	#CJK UNIFIED IDEOGRAPH
+0xD3E0	0x4F59	#CJK UNIFIED IDEOGRAPH
+0xD3E1	0x4FDE	#CJK UNIFIED IDEOGRAPH
+0xD3E2	0x903E	#CJK UNIFIED IDEOGRAPH
+0xD3E3	0x9C7C	#CJK UNIFIED IDEOGRAPH
+0xD3E4	0x6109	#CJK UNIFIED IDEOGRAPH
+0xD3E5	0x6E1D	#CJK UNIFIED IDEOGRAPH
+0xD3E6	0x6E14	#CJK UNIFIED IDEOGRAPH
+0xD3E7	0x9685	#CJK UNIFIED IDEOGRAPH
+0xD3E8	0x4E88	#CJK UNIFIED IDEOGRAPH
+0xD3E9	0x5A31	#CJK UNIFIED IDEOGRAPH
+0xD3EA	0x96E8	#CJK UNIFIED IDEOGRAPH
+0xD3EB	0x4E0E	#CJK UNIFIED IDEOGRAPH
+0xD3EC	0x5C7F	#CJK UNIFIED IDEOGRAPH
+0xD3ED	0x79B9	#CJK UNIFIED IDEOGRAPH
+0xD3EE	0x5B87	#CJK UNIFIED IDEOGRAPH
+0xD3EF	0x8BED	#CJK UNIFIED IDEOGRAPH
+0xD3F0	0x7FBD	#CJK UNIFIED IDEOGRAPH
+0xD3F1	0x7389	#CJK UNIFIED IDEOGRAPH
+0xD3F2	0x57DF	#CJK UNIFIED IDEOGRAPH
+0xD3F3	0x828B	#CJK UNIFIED IDEOGRAPH
+0xD3F4	0x90C1	#CJK UNIFIED IDEOGRAPH
+0xD3F5	0x5401	#CJK UNIFIED IDEOGRAPH
+0xD3F6	0x9047	#CJK UNIFIED IDEOGRAPH
+0xD3F7	0x55BB	#CJK UNIFIED IDEOGRAPH
+0xD3F8	0x5CEA	#CJK UNIFIED IDEOGRAPH
+0xD3F9	0x5FA1	#CJK UNIFIED IDEOGRAPH
+0xD3FA	0x6108	#CJK UNIFIED IDEOGRAPH
+0xD3FB	0x6B32	#CJK UNIFIED IDEOGRAPH
+0xD3FC	0x72F1	#CJK UNIFIED IDEOGRAPH
+0xD3FD	0x80B2	#CJK UNIFIED IDEOGRAPH
+0xD3FE	0x8A89	#CJK UNIFIED IDEOGRAPH
+0xD440	0x8A1E	#CJK UNIFIED IDEOGRAPH
+0xD441	0x8A1F	#CJK UNIFIED IDEOGRAPH
+0xD442	0x8A20	#CJK UNIFIED IDEOGRAPH
+0xD443	0x8A21	#CJK UNIFIED IDEOGRAPH
+0xD444	0x8A22	#CJK UNIFIED IDEOGRAPH
+0xD445	0x8A23	#CJK UNIFIED IDEOGRAPH
+0xD446	0x8A24	#CJK UNIFIED IDEOGRAPH
+0xD447	0x8A25	#CJK UNIFIED IDEOGRAPH
+0xD448	0x8A26	#CJK UNIFIED IDEOGRAPH
+0xD449	0x8A27	#CJK UNIFIED IDEOGRAPH
+0xD44A	0x8A28	#CJK UNIFIED IDEOGRAPH
+0xD44B	0x8A29	#CJK UNIFIED IDEOGRAPH
+0xD44C	0x8A2A	#CJK UNIFIED IDEOGRAPH
+0xD44D	0x8A2B	#CJK UNIFIED IDEOGRAPH
+0xD44E	0x8A2C	#CJK UNIFIED IDEOGRAPH
+0xD44F	0x8A2D	#CJK UNIFIED IDEOGRAPH
+0xD450	0x8A2E	#CJK UNIFIED IDEOGRAPH
+0xD451	0x8A2F	#CJK UNIFIED IDEOGRAPH
+0xD452	0x8A30	#CJK UNIFIED IDEOGRAPH
+0xD453	0x8A31	#CJK UNIFIED IDEOGRAPH
+0xD454	0x8A32	#CJK UNIFIED IDEOGRAPH
+0xD455	0x8A33	#CJK UNIFIED IDEOGRAPH
+0xD456	0x8A34	#CJK UNIFIED IDEOGRAPH
+0xD457	0x8A35	#CJK UNIFIED IDEOGRAPH
+0xD458	0x8A36	#CJK UNIFIED IDEOGRAPH
+0xD459	0x8A37	#CJK UNIFIED IDEOGRAPH
+0xD45A	0x8A38	#CJK UNIFIED IDEOGRAPH
+0xD45B	0x8A39	#CJK UNIFIED IDEOGRAPH
+0xD45C	0x8A3A	#CJK UNIFIED IDEOGRAPH
+0xD45D	0x8A3B	#CJK UNIFIED IDEOGRAPH
+0xD45E	0x8A3C	#CJK UNIFIED IDEOGRAPH
+0xD45F	0x8A3D	#CJK UNIFIED IDEOGRAPH
+0xD460	0x8A3F	#CJK UNIFIED IDEOGRAPH
+0xD461	0x8A40	#CJK UNIFIED IDEOGRAPH
+0xD462	0x8A41	#CJK UNIFIED IDEOGRAPH
+0xD463	0x8A42	#CJK UNIFIED IDEOGRAPH
+0xD464	0x8A43	#CJK UNIFIED IDEOGRAPH
+0xD465	0x8A44	#CJK UNIFIED IDEOGRAPH
+0xD466	0x8A45	#CJK UNIFIED IDEOGRAPH
+0xD467	0x8A46	#CJK UNIFIED IDEOGRAPH
+0xD468	0x8A47	#CJK UNIFIED IDEOGRAPH
+0xD469	0x8A49	#CJK UNIFIED IDEOGRAPH
+0xD46A	0x8A4A	#CJK UNIFIED IDEOGRAPH
+0xD46B	0x8A4B	#CJK UNIFIED IDEOGRAPH
+0xD46C	0x8A4C	#CJK UNIFIED IDEOGRAPH
+0xD46D	0x8A4D	#CJK UNIFIED IDEOGRAPH
+0xD46E	0x8A4E	#CJK UNIFIED IDEOGRAPH
+0xD46F	0x8A4F	#CJK UNIFIED IDEOGRAPH
+0xD470	0x8A50	#CJK UNIFIED IDEOGRAPH
+0xD471	0x8A51	#CJK UNIFIED IDEOGRAPH
+0xD472	0x8A52	#CJK UNIFIED IDEOGRAPH
+0xD473	0x8A53	#CJK UNIFIED IDEOGRAPH
+0xD474	0x8A54	#CJK UNIFIED IDEOGRAPH
+0xD475	0x8A55	#CJK UNIFIED IDEOGRAPH
+0xD476	0x8A56	#CJK UNIFIED IDEOGRAPH
+0xD477	0x8A57	#CJK UNIFIED IDEOGRAPH
+0xD478	0x8A58	#CJK UNIFIED IDEOGRAPH
+0xD479	0x8A59	#CJK UNIFIED IDEOGRAPH
+0xD47A	0x8A5A	#CJK UNIFIED IDEOGRAPH
+0xD47B	0x8A5B	#CJK UNIFIED IDEOGRAPH
+0xD47C	0x8A5C	#CJK UNIFIED IDEOGRAPH
+0xD47D	0x8A5D	#CJK UNIFIED IDEOGRAPH
+0xD47E	0x8A5E	#CJK UNIFIED IDEOGRAPH
+0xD480	0x8A5F	#CJK UNIFIED IDEOGRAPH
+0xD481	0x8A60	#CJK UNIFIED IDEOGRAPH
+0xD482	0x8A61	#CJK UNIFIED IDEOGRAPH
+0xD483	0x8A62	#CJK UNIFIED IDEOGRAPH
+0xD484	0x8A63	#CJK UNIFIED IDEOGRAPH
+0xD485	0x8A64	#CJK UNIFIED IDEOGRAPH
+0xD486	0x8A65	#CJK UNIFIED IDEOGRAPH
+0xD487	0x8A66	#CJK UNIFIED IDEOGRAPH
+0xD488	0x8A67	#CJK UNIFIED IDEOGRAPH
+0xD489	0x8A68	#CJK UNIFIED IDEOGRAPH
+0xD48A	0x8A69	#CJK UNIFIED IDEOGRAPH
+0xD48B	0x8A6A	#CJK UNIFIED IDEOGRAPH
+0xD48C	0x8A6B	#CJK UNIFIED IDEOGRAPH
+0xD48D	0x8A6C	#CJK UNIFIED IDEOGRAPH
+0xD48E	0x8A6D	#CJK UNIFIED IDEOGRAPH
+0xD48F	0x8A6E	#CJK UNIFIED IDEOGRAPH
+0xD490	0x8A6F	#CJK UNIFIED IDEOGRAPH
+0xD491	0x8A70	#CJK UNIFIED IDEOGRAPH
+0xD492	0x8A71	#CJK UNIFIED IDEOGRAPH
+0xD493	0x8A72	#CJK UNIFIED IDEOGRAPH
+0xD494	0x8A73	#CJK UNIFIED IDEOGRAPH
+0xD495	0x8A74	#CJK UNIFIED IDEOGRAPH
+0xD496	0x8A75	#CJK UNIFIED IDEOGRAPH
+0xD497	0x8A76	#CJK UNIFIED IDEOGRAPH
+0xD498	0x8A77	#CJK UNIFIED IDEOGRAPH
+0xD499	0x8A78	#CJK UNIFIED IDEOGRAPH
+0xD49A	0x8A7A	#CJK UNIFIED IDEOGRAPH
+0xD49B	0x8A7B	#CJK UNIFIED IDEOGRAPH
+0xD49C	0x8A7C	#CJK UNIFIED IDEOGRAPH
+0xD49D	0x8A7D	#CJK UNIFIED IDEOGRAPH
+0xD49E	0x8A7E	#CJK UNIFIED IDEOGRAPH
+0xD49F	0x8A7F	#CJK UNIFIED IDEOGRAPH
+0xD4A0	0x8A80	#CJK UNIFIED IDEOGRAPH
+0xD4A1	0x6D74	#CJK UNIFIED IDEOGRAPH
+0xD4A2	0x5BD3	#CJK UNIFIED IDEOGRAPH
+0xD4A3	0x88D5	#CJK UNIFIED IDEOGRAPH
+0xD4A4	0x9884	#CJK UNIFIED IDEOGRAPH
+0xD4A5	0x8C6B	#CJK UNIFIED IDEOGRAPH
+0xD4A6	0x9A6D	#CJK UNIFIED IDEOGRAPH
+0xD4A7	0x9E33	#CJK UNIFIED IDEOGRAPH
+0xD4A8	0x6E0A	#CJK UNIFIED IDEOGRAPH
+0xD4A9	0x51A4	#CJK UNIFIED IDEOGRAPH
+0xD4AA	0x5143	#CJK UNIFIED IDEOGRAPH
+0xD4AB	0x57A3	#CJK UNIFIED IDEOGRAPH
+0xD4AC	0x8881	#CJK UNIFIED IDEOGRAPH
+0xD4AD	0x539F	#CJK UNIFIED IDEOGRAPH
+0xD4AE	0x63F4	#CJK UNIFIED IDEOGRAPH
+0xD4AF	0x8F95	#CJK UNIFIED IDEOGRAPH
+0xD4B0	0x56ED	#CJK UNIFIED IDEOGRAPH
+0xD4B1	0x5458	#CJK UNIFIED IDEOGRAPH
+0xD4B2	0x5706	#CJK UNIFIED IDEOGRAPH
+0xD4B3	0x733F	#CJK UNIFIED IDEOGRAPH
+0xD4B4	0x6E90	#CJK UNIFIED IDEOGRAPH
+0xD4B5	0x7F18	#CJK UNIFIED IDEOGRAPH
+0xD4B6	0x8FDC	#CJK UNIFIED IDEOGRAPH
+0xD4B7	0x82D1	#CJK UNIFIED IDEOGRAPH
+0xD4B8	0x613F	#CJK UNIFIED IDEOGRAPH
+0xD4B9	0x6028	#CJK UNIFIED IDEOGRAPH
+0xD4BA	0x9662	#CJK UNIFIED IDEOGRAPH
+0xD4BB	0x66F0	#CJK UNIFIED IDEOGRAPH
+0xD4BC	0x7EA6	#CJK UNIFIED IDEOGRAPH
+0xD4BD	0x8D8A	#CJK UNIFIED IDEOGRAPH
+0xD4BE	0x8DC3	#CJK UNIFIED IDEOGRAPH
+0xD4BF	0x94A5	#CJK UNIFIED IDEOGRAPH
+0xD4C0	0x5CB3	#CJK UNIFIED IDEOGRAPH
+0xD4C1	0x7CA4	#CJK UNIFIED IDEOGRAPH
+0xD4C2	0x6708	#CJK UNIFIED IDEOGRAPH
+0xD4C3	0x60A6	#CJK UNIFIED IDEOGRAPH
+0xD4C4	0x9605	#CJK UNIFIED IDEOGRAPH
+0xD4C5	0x8018	#CJK UNIFIED IDEOGRAPH
+0xD4C6	0x4E91	#CJK UNIFIED IDEOGRAPH
+0xD4C7	0x90E7	#CJK UNIFIED IDEOGRAPH
+0xD4C8	0x5300	#CJK UNIFIED IDEOGRAPH
+0xD4C9	0x9668	#CJK UNIFIED IDEOGRAPH
+0xD4CA	0x5141	#CJK UNIFIED IDEOGRAPH
+0xD4CB	0x8FD0	#CJK UNIFIED IDEOGRAPH
+0xD4CC	0x8574	#CJK UNIFIED IDEOGRAPH
+0xD4CD	0x915D	#CJK UNIFIED IDEOGRAPH
+0xD4CE	0x6655	#CJK UNIFIED IDEOGRAPH
+0xD4CF	0x97F5	#CJK UNIFIED IDEOGRAPH
+0xD4D0	0x5B55	#CJK UNIFIED IDEOGRAPH
+0xD4D1	0x531D	#CJK UNIFIED IDEOGRAPH
+0xD4D2	0x7838	#CJK UNIFIED IDEOGRAPH
+0xD4D3	0x6742	#CJK UNIFIED IDEOGRAPH
+0xD4D4	0x683D	#CJK UNIFIED IDEOGRAPH
+0xD4D5	0x54C9	#CJK UNIFIED IDEOGRAPH
+0xD4D6	0x707E	#CJK UNIFIED IDEOGRAPH
+0xD4D7	0x5BB0	#CJK UNIFIED IDEOGRAPH
+0xD4D8	0x8F7D	#CJK UNIFIED IDEOGRAPH
+0xD4D9	0x518D	#CJK UNIFIED IDEOGRAPH
+0xD4DA	0x5728	#CJK UNIFIED IDEOGRAPH
+0xD4DB	0x54B1	#CJK UNIFIED IDEOGRAPH
+0xD4DC	0x6512	#CJK UNIFIED IDEOGRAPH
+0xD4DD	0x6682	#CJK UNIFIED IDEOGRAPH
+0xD4DE	0x8D5E	#CJK UNIFIED IDEOGRAPH
+0xD4DF	0x8D43	#CJK UNIFIED IDEOGRAPH
+0xD4E0	0x810F	#CJK UNIFIED IDEOGRAPH
+0xD4E1	0x846C	#CJK UNIFIED IDEOGRAPH
+0xD4E2	0x906D	#CJK UNIFIED IDEOGRAPH
+0xD4E3	0x7CDF	#CJK UNIFIED IDEOGRAPH
+0xD4E4	0x51FF	#CJK UNIFIED IDEOGRAPH
+0xD4E5	0x85FB	#CJK UNIFIED IDEOGRAPH
+0xD4E6	0x67A3	#CJK UNIFIED IDEOGRAPH
+0xD4E7	0x65E9	#CJK UNIFIED IDEOGRAPH
+0xD4E8	0x6FA1	#CJK UNIFIED IDEOGRAPH
+0xD4E9	0x86A4	#CJK UNIFIED IDEOGRAPH
+0xD4EA	0x8E81	#CJK UNIFIED IDEOGRAPH
+0xD4EB	0x566A	#CJK UNIFIED IDEOGRAPH
+0xD4EC	0x9020	#CJK UNIFIED IDEOGRAPH
+0xD4ED	0x7682	#CJK UNIFIED IDEOGRAPH
+0xD4EE	0x7076	#CJK UNIFIED IDEOGRAPH
+0xD4EF	0x71E5	#CJK UNIFIED IDEOGRAPH
+0xD4F0	0x8D23	#CJK UNIFIED IDEOGRAPH
+0xD4F1	0x62E9	#CJK UNIFIED IDEOGRAPH
+0xD4F2	0x5219	#CJK UNIFIED IDEOGRAPH
+0xD4F3	0x6CFD	#CJK UNIFIED IDEOGRAPH
+0xD4F4	0x8D3C	#CJK UNIFIED IDEOGRAPH
+0xD4F5	0x600E	#CJK UNIFIED IDEOGRAPH
+0xD4F6	0x589E	#CJK UNIFIED IDEOGRAPH
+0xD4F7	0x618E	#CJK UNIFIED IDEOGRAPH
+0xD4F8	0x66FE	#CJK UNIFIED IDEOGRAPH
+0xD4F9	0x8D60	#CJK UNIFIED IDEOGRAPH
+0xD4FA	0x624E	#CJK UNIFIED IDEOGRAPH
+0xD4FB	0x55B3	#CJK UNIFIED IDEOGRAPH
+0xD4FC	0x6E23	#CJK UNIFIED IDEOGRAPH
+0xD4FD	0x672D	#CJK UNIFIED IDEOGRAPH
+0xD4FE	0x8F67	#CJK UNIFIED IDEOGRAPH
+0xD540	0x8A81	#CJK UNIFIED IDEOGRAPH
+0xD541	0x8A82	#CJK UNIFIED IDEOGRAPH
+0xD542	0x8A83	#CJK UNIFIED IDEOGRAPH
+0xD543	0x8A84	#CJK UNIFIED IDEOGRAPH
+0xD544	0x8A85	#CJK UNIFIED IDEOGRAPH
+0xD545	0x8A86	#CJK UNIFIED IDEOGRAPH
+0xD546	0x8A87	#CJK UNIFIED IDEOGRAPH
+0xD547	0x8A88	#CJK UNIFIED IDEOGRAPH
+0xD548	0x8A8B	#CJK UNIFIED IDEOGRAPH
+0xD549	0x8A8C	#CJK UNIFIED IDEOGRAPH
+0xD54A	0x8A8D	#CJK UNIFIED IDEOGRAPH
+0xD54B	0x8A8E	#CJK UNIFIED IDEOGRAPH
+0xD54C	0x8A8F	#CJK UNIFIED IDEOGRAPH
+0xD54D	0x8A90	#CJK UNIFIED IDEOGRAPH
+0xD54E	0x8A91	#CJK UNIFIED IDEOGRAPH
+0xD54F	0x8A92	#CJK UNIFIED IDEOGRAPH
+0xD550	0x8A94	#CJK UNIFIED IDEOGRAPH
+0xD551	0x8A95	#CJK UNIFIED IDEOGRAPH
+0xD552	0x8A96	#CJK UNIFIED IDEOGRAPH
+0xD553	0x8A97	#CJK UNIFIED IDEOGRAPH
+0xD554	0x8A98	#CJK UNIFIED IDEOGRAPH
+0xD555	0x8A99	#CJK UNIFIED IDEOGRAPH
+0xD556	0x8A9A	#CJK UNIFIED IDEOGRAPH
+0xD557	0x8A9B	#CJK UNIFIED IDEOGRAPH
+0xD558	0x8A9C	#CJK UNIFIED IDEOGRAPH
+0xD559	0x8A9D	#CJK UNIFIED IDEOGRAPH
+0xD55A	0x8A9E	#CJK UNIFIED IDEOGRAPH
+0xD55B	0x8A9F	#CJK UNIFIED IDEOGRAPH
+0xD55C	0x8AA0	#CJK UNIFIED IDEOGRAPH
+0xD55D	0x8AA1	#CJK UNIFIED IDEOGRAPH
+0xD55E	0x8AA2	#CJK UNIFIED IDEOGRAPH
+0xD55F	0x8AA3	#CJK UNIFIED IDEOGRAPH
+0xD560	0x8AA4	#CJK UNIFIED IDEOGRAPH
+0xD561	0x8AA5	#CJK UNIFIED IDEOGRAPH
+0xD562	0x8AA6	#CJK UNIFIED IDEOGRAPH
+0xD563	0x8AA7	#CJK UNIFIED IDEOGRAPH
+0xD564	0x8AA8	#CJK UNIFIED IDEOGRAPH
+0xD565	0x8AA9	#CJK UNIFIED IDEOGRAPH
+0xD566	0x8AAA	#CJK UNIFIED IDEOGRAPH
+0xD567	0x8AAB	#CJK UNIFIED IDEOGRAPH
+0xD568	0x8AAC	#CJK UNIFIED IDEOGRAPH
+0xD569	0x8AAD	#CJK UNIFIED IDEOGRAPH
+0xD56A	0x8AAE	#CJK UNIFIED IDEOGRAPH
+0xD56B	0x8AAF	#CJK UNIFIED IDEOGRAPH
+0xD56C	0x8AB0	#CJK UNIFIED IDEOGRAPH
+0xD56D	0x8AB1	#CJK UNIFIED IDEOGRAPH
+0xD56E	0x8AB2	#CJK UNIFIED IDEOGRAPH
+0xD56F	0x8AB3	#CJK UNIFIED IDEOGRAPH
+0xD570	0x8AB4	#CJK UNIFIED IDEOGRAPH
+0xD571	0x8AB5	#CJK UNIFIED IDEOGRAPH
+0xD572	0x8AB6	#CJK UNIFIED IDEOGRAPH
+0xD573	0x8AB7	#CJK UNIFIED IDEOGRAPH
+0xD574	0x8AB8	#CJK UNIFIED IDEOGRAPH
+0xD575	0x8AB9	#CJK UNIFIED IDEOGRAPH
+0xD576	0x8ABA	#CJK UNIFIED IDEOGRAPH
+0xD577	0x8ABB	#CJK UNIFIED IDEOGRAPH
+0xD578	0x8ABC	#CJK UNIFIED IDEOGRAPH
+0xD579	0x8ABD	#CJK UNIFIED IDEOGRAPH
+0xD57A	0x8ABE	#CJK UNIFIED IDEOGRAPH
+0xD57B	0x8ABF	#CJK UNIFIED IDEOGRAPH
+0xD57C	0x8AC0	#CJK UNIFIED IDEOGRAPH
+0xD57D	0x8AC1	#CJK UNIFIED IDEOGRAPH
+0xD57E	0x8AC2	#CJK UNIFIED IDEOGRAPH
+0xD580	0x8AC3	#CJK UNIFIED IDEOGRAPH
+0xD581	0x8AC4	#CJK UNIFIED IDEOGRAPH
+0xD582	0x8AC5	#CJK UNIFIED IDEOGRAPH
+0xD583	0x8AC6	#CJK UNIFIED IDEOGRAPH
+0xD584	0x8AC7	#CJK UNIFIED IDEOGRAPH
+0xD585	0x8AC8	#CJK UNIFIED IDEOGRAPH
+0xD586	0x8AC9	#CJK UNIFIED IDEOGRAPH
+0xD587	0x8ACA	#CJK UNIFIED IDEOGRAPH
+0xD588	0x8ACB	#CJK UNIFIED IDEOGRAPH
+0xD589	0x8ACC	#CJK UNIFIED IDEOGRAPH
+0xD58A	0x8ACD	#CJK UNIFIED IDEOGRAPH
+0xD58B	0x8ACE	#CJK UNIFIED IDEOGRAPH
+0xD58C	0x8ACF	#CJK UNIFIED IDEOGRAPH
+0xD58D	0x8AD0	#CJK UNIFIED IDEOGRAPH
+0xD58E	0x8AD1	#CJK UNIFIED IDEOGRAPH
+0xD58F	0x8AD2	#CJK UNIFIED IDEOGRAPH
+0xD590	0x8AD3	#CJK UNIFIED IDEOGRAPH
+0xD591	0x8AD4	#CJK UNIFIED IDEOGRAPH
+0xD592	0x8AD5	#CJK UNIFIED IDEOGRAPH
+0xD593	0x8AD6	#CJK UNIFIED IDEOGRAPH
+0xD594	0x8AD7	#CJK UNIFIED IDEOGRAPH
+0xD595	0x8AD8	#CJK UNIFIED IDEOGRAPH
+0xD596	0x8AD9	#CJK UNIFIED IDEOGRAPH
+0xD597	0x8ADA	#CJK UNIFIED IDEOGRAPH
+0xD598	0x8ADB	#CJK UNIFIED IDEOGRAPH
+0xD599	0x8ADC	#CJK UNIFIED IDEOGRAPH
+0xD59A	0x8ADD	#CJK UNIFIED IDEOGRAPH
+0xD59B	0x8ADE	#CJK UNIFIED IDEOGRAPH
+0xD59C	0x8ADF	#CJK UNIFIED IDEOGRAPH
+0xD59D	0x8AE0	#CJK UNIFIED IDEOGRAPH
+0xD59E	0x8AE1	#CJK UNIFIED IDEOGRAPH
+0xD59F	0x8AE2	#CJK UNIFIED IDEOGRAPH
+0xD5A0	0x8AE3	#CJK UNIFIED IDEOGRAPH
+0xD5A1	0x94E1	#CJK UNIFIED IDEOGRAPH
+0xD5A2	0x95F8	#CJK UNIFIED IDEOGRAPH
+0xD5A3	0x7728	#CJK UNIFIED IDEOGRAPH
+0xD5A4	0x6805	#CJK UNIFIED IDEOGRAPH
+0xD5A5	0x69A8	#CJK UNIFIED IDEOGRAPH
+0xD5A6	0x548B	#CJK UNIFIED IDEOGRAPH
+0xD5A7	0x4E4D	#CJK UNIFIED IDEOGRAPH
+0xD5A8	0x70B8	#CJK UNIFIED IDEOGRAPH
+0xD5A9	0x8BC8	#CJK UNIFIED IDEOGRAPH
+0xD5AA	0x6458	#CJK UNIFIED IDEOGRAPH
+0xD5AB	0x658B	#CJK UNIFIED IDEOGRAPH
+0xD5AC	0x5B85	#CJK UNIFIED IDEOGRAPH
+0xD5AD	0x7A84	#CJK UNIFIED IDEOGRAPH
+0xD5AE	0x503A	#CJK UNIFIED IDEOGRAPH
+0xD5AF	0x5BE8	#CJK UNIFIED IDEOGRAPH
+0xD5B0	0x77BB	#CJK UNIFIED IDEOGRAPH
+0xD5B1	0x6BE1	#CJK UNIFIED IDEOGRAPH
+0xD5B2	0x8A79	#CJK UNIFIED IDEOGRAPH
+0xD5B3	0x7C98	#CJK UNIFIED IDEOGRAPH
+0xD5B4	0x6CBE	#CJK UNIFIED IDEOGRAPH
+0xD5B5	0x76CF	#CJK UNIFIED IDEOGRAPH
+0xD5B6	0x65A9	#CJK UNIFIED IDEOGRAPH
+0xD5B7	0x8F97	#CJK UNIFIED IDEOGRAPH
+0xD5B8	0x5D2D	#CJK UNIFIED IDEOGRAPH
+0xD5B9	0x5C55	#CJK UNIFIED IDEOGRAPH
+0xD5BA	0x8638	#CJK UNIFIED IDEOGRAPH
+0xD5BB	0x6808	#CJK UNIFIED IDEOGRAPH
+0xD5BC	0x5360	#CJK UNIFIED IDEOGRAPH
+0xD5BD	0x6218	#CJK UNIFIED IDEOGRAPH
+0xD5BE	0x7AD9	#CJK UNIFIED IDEOGRAPH
+0xD5BF	0x6E5B	#CJK UNIFIED IDEOGRAPH
+0xD5C0	0x7EFD	#CJK UNIFIED IDEOGRAPH
+0xD5C1	0x6A1F	#CJK UNIFIED IDEOGRAPH
+0xD5C2	0x7AE0	#CJK UNIFIED IDEOGRAPH
+0xD5C3	0x5F70	#CJK UNIFIED IDEOGRAPH
+0xD5C4	0x6F33	#CJK UNIFIED IDEOGRAPH
+0xD5C5	0x5F20	#CJK UNIFIED IDEOGRAPH
+0xD5C6	0x638C	#CJK UNIFIED IDEOGRAPH
+0xD5C7	0x6DA8	#CJK UNIFIED IDEOGRAPH
+0xD5C8	0x6756	#CJK UNIFIED IDEOGRAPH
+0xD5C9	0x4E08	#CJK UNIFIED IDEOGRAPH
+0xD5CA	0x5E10	#CJK UNIFIED IDEOGRAPH
+0xD5CB	0x8D26	#CJK UNIFIED IDEOGRAPH
+0xD5CC	0x4ED7	#CJK UNIFIED IDEOGRAPH
+0xD5CD	0x80C0	#CJK UNIFIED IDEOGRAPH
+0xD5CE	0x7634	#CJK UNIFIED IDEOGRAPH
+0xD5CF	0x969C	#CJK UNIFIED IDEOGRAPH
+0xD5D0	0x62DB	#CJK UNIFIED IDEOGRAPH
+0xD5D1	0x662D	#CJK UNIFIED IDEOGRAPH
+0xD5D2	0x627E	#CJK UNIFIED IDEOGRAPH
+0xD5D3	0x6CBC	#CJK UNIFIED IDEOGRAPH
+0xD5D4	0x8D75	#CJK UNIFIED IDEOGRAPH
+0xD5D5	0x7167	#CJK UNIFIED IDEOGRAPH
+0xD5D6	0x7F69	#CJK UNIFIED IDEOGRAPH
+0xD5D7	0x5146	#CJK UNIFIED IDEOGRAPH
+0xD5D8	0x8087	#CJK UNIFIED IDEOGRAPH
+0xD5D9	0x53EC	#CJK UNIFIED IDEOGRAPH
+0xD5DA	0x906E	#CJK UNIFIED IDEOGRAPH
+0xD5DB	0x6298	#CJK UNIFIED IDEOGRAPH
+0xD5DC	0x54F2	#CJK UNIFIED IDEOGRAPH
+0xD5DD	0x86F0	#CJK UNIFIED IDEOGRAPH
+0xD5DE	0x8F99	#CJK UNIFIED IDEOGRAPH
+0xD5DF	0x8005	#CJK UNIFIED IDEOGRAPH
+0xD5E0	0x9517	#CJK UNIFIED IDEOGRAPH
+0xD5E1	0x8517	#CJK UNIFIED IDEOGRAPH
+0xD5E2	0x8FD9	#CJK UNIFIED IDEOGRAPH
+0xD5E3	0x6D59	#CJK UNIFIED IDEOGRAPH
+0xD5E4	0x73CD	#CJK UNIFIED IDEOGRAPH
+0xD5E5	0x659F	#CJK UNIFIED IDEOGRAPH
+0xD5E6	0x771F	#CJK UNIFIED IDEOGRAPH
+0xD5E7	0x7504	#CJK UNIFIED IDEOGRAPH
+0xD5E8	0x7827	#CJK UNIFIED IDEOGRAPH
+0xD5E9	0x81FB	#CJK UNIFIED IDEOGRAPH
+0xD5EA	0x8D1E	#CJK UNIFIED IDEOGRAPH
+0xD5EB	0x9488	#CJK UNIFIED IDEOGRAPH
+0xD5EC	0x4FA6	#CJK UNIFIED IDEOGRAPH
+0xD5ED	0x6795	#CJK UNIFIED IDEOGRAPH
+0xD5EE	0x75B9	#CJK UNIFIED IDEOGRAPH
+0xD5EF	0x8BCA	#CJK UNIFIED IDEOGRAPH
+0xD5F0	0x9707	#CJK UNIFIED IDEOGRAPH
+0xD5F1	0x632F	#CJK UNIFIED IDEOGRAPH
+0xD5F2	0x9547	#CJK UNIFIED IDEOGRAPH
+0xD5F3	0x9635	#CJK UNIFIED IDEOGRAPH
+0xD5F4	0x84B8	#CJK UNIFIED IDEOGRAPH
+0xD5F5	0x6323	#CJK UNIFIED IDEOGRAPH
+0xD5F6	0x7741	#CJK UNIFIED IDEOGRAPH
+0xD5F7	0x5F81	#CJK UNIFIED IDEOGRAPH
+0xD5F8	0x72F0	#CJK UNIFIED IDEOGRAPH
+0xD5F9	0x4E89	#CJK UNIFIED IDEOGRAPH
+0xD5FA	0x6014	#CJK UNIFIED IDEOGRAPH
+0xD5FB	0x6574	#CJK UNIFIED IDEOGRAPH
+0xD5FC	0x62EF	#CJK UNIFIED IDEOGRAPH
+0xD5FD	0x6B63	#CJK UNIFIED IDEOGRAPH
+0xD5FE	0x653F	#CJK UNIFIED IDEOGRAPH
+0xD640	0x8AE4	#CJK UNIFIED IDEOGRAPH
+0xD641	0x8AE5	#CJK UNIFIED IDEOGRAPH
+0xD642	0x8AE6	#CJK UNIFIED IDEOGRAPH
+0xD643	0x8AE7	#CJK UNIFIED IDEOGRAPH
+0xD644	0x8AE8	#CJK UNIFIED IDEOGRAPH
+0xD645	0x8AE9	#CJK UNIFIED IDEOGRAPH
+0xD646	0x8AEA	#CJK UNIFIED IDEOGRAPH
+0xD647	0x8AEB	#CJK UNIFIED IDEOGRAPH
+0xD648	0x8AEC	#CJK UNIFIED IDEOGRAPH
+0xD649	0x8AED	#CJK UNIFIED IDEOGRAPH
+0xD64A	0x8AEE	#CJK UNIFIED IDEOGRAPH
+0xD64B	0x8AEF	#CJK UNIFIED IDEOGRAPH
+0xD64C	0x8AF0	#CJK UNIFIED IDEOGRAPH
+0xD64D	0x8AF1	#CJK UNIFIED IDEOGRAPH
+0xD64E	0x8AF2	#CJK UNIFIED IDEOGRAPH
+0xD64F	0x8AF3	#CJK UNIFIED IDEOGRAPH
+0xD650	0x8AF4	#CJK UNIFIED IDEOGRAPH
+0xD651	0x8AF5	#CJK UNIFIED IDEOGRAPH
+0xD652	0x8AF6	#CJK UNIFIED IDEOGRAPH
+0xD653	0x8AF7	#CJK UNIFIED IDEOGRAPH
+0xD654	0x8AF8	#CJK UNIFIED IDEOGRAPH
+0xD655	0x8AF9	#CJK UNIFIED IDEOGRAPH
+0xD656	0x8AFA	#CJK UNIFIED IDEOGRAPH
+0xD657	0x8AFB	#CJK UNIFIED IDEOGRAPH
+0xD658	0x8AFC	#CJK UNIFIED IDEOGRAPH
+0xD659	0x8AFD	#CJK UNIFIED IDEOGRAPH
+0xD65A	0x8AFE	#CJK UNIFIED IDEOGRAPH
+0xD65B	0x8AFF	#CJK UNIFIED IDEOGRAPH
+0xD65C	0x8B00	#CJK UNIFIED IDEOGRAPH
+0xD65D	0x8B01	#CJK UNIFIED IDEOGRAPH
+0xD65E	0x8B02	#CJK UNIFIED IDEOGRAPH
+0xD65F	0x8B03	#CJK UNIFIED IDEOGRAPH
+0xD660	0x8B04	#CJK UNIFIED IDEOGRAPH
+0xD661	0x8B05	#CJK UNIFIED IDEOGRAPH
+0xD662	0x8B06	#CJK UNIFIED IDEOGRAPH
+0xD663	0x8B08	#CJK UNIFIED IDEOGRAPH
+0xD664	0x8B09	#CJK UNIFIED IDEOGRAPH
+0xD665	0x8B0A	#CJK UNIFIED IDEOGRAPH
+0xD666	0x8B0B	#CJK UNIFIED IDEOGRAPH
+0xD667	0x8B0C	#CJK UNIFIED IDEOGRAPH
+0xD668	0x8B0D	#CJK UNIFIED IDEOGRAPH
+0xD669	0x8B0E	#CJK UNIFIED IDEOGRAPH
+0xD66A	0x8B0F	#CJK UNIFIED IDEOGRAPH
+0xD66B	0x8B10	#CJK UNIFIED IDEOGRAPH
+0xD66C	0x8B11	#CJK UNIFIED IDEOGRAPH
+0xD66D	0x8B12	#CJK UNIFIED IDEOGRAPH
+0xD66E	0x8B13	#CJK UNIFIED IDEOGRAPH
+0xD66F	0x8B14	#CJK UNIFIED IDEOGRAPH
+0xD670	0x8B15	#CJK UNIFIED IDEOGRAPH
+0xD671	0x8B16	#CJK UNIFIED IDEOGRAPH
+0xD672	0x8B17	#CJK UNIFIED IDEOGRAPH
+0xD673	0x8B18	#CJK UNIFIED IDEOGRAPH
+0xD674	0x8B19	#CJK UNIFIED IDEOGRAPH
+0xD675	0x8B1A	#CJK UNIFIED IDEOGRAPH
+0xD676	0x8B1B	#CJK UNIFIED IDEOGRAPH
+0xD677	0x8B1C	#CJK UNIFIED IDEOGRAPH
+0xD678	0x8B1D	#CJK UNIFIED IDEOGRAPH
+0xD679	0x8B1E	#CJK UNIFIED IDEOGRAPH
+0xD67A	0x8B1F	#CJK UNIFIED IDEOGRAPH
+0xD67B	0x8B20	#CJK UNIFIED IDEOGRAPH
+0xD67C	0x8B21	#CJK UNIFIED IDEOGRAPH
+0xD67D	0x8B22	#CJK UNIFIED IDEOGRAPH
+0xD67E	0x8B23	#CJK UNIFIED IDEOGRAPH
+0xD680	0x8B24	#CJK UNIFIED IDEOGRAPH
+0xD681	0x8B25	#CJK UNIFIED IDEOGRAPH
+0xD682	0x8B27	#CJK UNIFIED IDEOGRAPH
+0xD683	0x8B28	#CJK UNIFIED IDEOGRAPH
+0xD684	0x8B29	#CJK UNIFIED IDEOGRAPH
+0xD685	0x8B2A	#CJK UNIFIED IDEOGRAPH
+0xD686	0x8B2B	#CJK UNIFIED IDEOGRAPH
+0xD687	0x8B2C	#CJK UNIFIED IDEOGRAPH
+0xD688	0x8B2D	#CJK UNIFIED IDEOGRAPH
+0xD689	0x8B2E	#CJK UNIFIED IDEOGRAPH
+0xD68A	0x8B2F	#CJK UNIFIED IDEOGRAPH
+0xD68B	0x8B30	#CJK UNIFIED IDEOGRAPH
+0xD68C	0x8B31	#CJK UNIFIED IDEOGRAPH
+0xD68D	0x8B32	#CJK UNIFIED IDEOGRAPH
+0xD68E	0x8B33	#CJK UNIFIED IDEOGRAPH
+0xD68F	0x8B34	#CJK UNIFIED IDEOGRAPH
+0xD690	0x8B35	#CJK UNIFIED IDEOGRAPH
+0xD691	0x8B36	#CJK UNIFIED IDEOGRAPH
+0xD692	0x8B37	#CJK UNIFIED IDEOGRAPH
+0xD693	0x8B38	#CJK UNIFIED IDEOGRAPH
+0xD694	0x8B39	#CJK UNIFIED IDEOGRAPH
+0xD695	0x8B3A	#CJK UNIFIED IDEOGRAPH
+0xD696	0x8B3B	#CJK UNIFIED IDEOGRAPH
+0xD697	0x8B3C	#CJK UNIFIED IDEOGRAPH
+0xD698	0x8B3D	#CJK UNIFIED IDEOGRAPH
+0xD699	0x8B3E	#CJK UNIFIED IDEOGRAPH
+0xD69A	0x8B3F	#CJK UNIFIED IDEOGRAPH
+0xD69B	0x8B40	#CJK UNIFIED IDEOGRAPH
+0xD69C	0x8B41	#CJK UNIFIED IDEOGRAPH
+0xD69D	0x8B42	#CJK UNIFIED IDEOGRAPH
+0xD69E	0x8B43	#CJK UNIFIED IDEOGRAPH
+0xD69F	0x8B44	#CJK UNIFIED IDEOGRAPH
+0xD6A0	0x8B45	#CJK UNIFIED IDEOGRAPH
+0xD6A1	0x5E27	#CJK UNIFIED IDEOGRAPH
+0xD6A2	0x75C7	#CJK UNIFIED IDEOGRAPH
+0xD6A3	0x90D1	#CJK UNIFIED IDEOGRAPH
+0xD6A4	0x8BC1	#CJK UNIFIED IDEOGRAPH
+0xD6A5	0x829D	#CJK UNIFIED IDEOGRAPH
+0xD6A6	0x679D	#CJK UNIFIED IDEOGRAPH
+0xD6A7	0x652F	#CJK UNIFIED IDEOGRAPH
+0xD6A8	0x5431	#CJK UNIFIED IDEOGRAPH
+0xD6A9	0x8718	#CJK UNIFIED IDEOGRAPH
+0xD6AA	0x77E5	#CJK UNIFIED IDEOGRAPH
+0xD6AB	0x80A2	#CJK UNIFIED IDEOGRAPH
+0xD6AC	0x8102	#CJK UNIFIED IDEOGRAPH
+0xD6AD	0x6C41	#CJK UNIFIED IDEOGRAPH
+0xD6AE	0x4E4B	#CJK UNIFIED IDEOGRAPH
+0xD6AF	0x7EC7	#CJK UNIFIED IDEOGRAPH
+0xD6B0	0x804C	#CJK UNIFIED IDEOGRAPH
+0xD6B1	0x76F4	#CJK UNIFIED IDEOGRAPH
+0xD6B2	0x690D	#CJK UNIFIED IDEOGRAPH
+0xD6B3	0x6B96	#CJK UNIFIED IDEOGRAPH
+0xD6B4	0x6267	#CJK UNIFIED IDEOGRAPH
+0xD6B5	0x503C	#CJK UNIFIED IDEOGRAPH
+0xD6B6	0x4F84	#CJK UNIFIED IDEOGRAPH
+0xD6B7	0x5740	#CJK UNIFIED IDEOGRAPH
+0xD6B8	0x6307	#CJK UNIFIED IDEOGRAPH
+0xD6B9	0x6B62	#CJK UNIFIED IDEOGRAPH
+0xD6BA	0x8DBE	#CJK UNIFIED IDEOGRAPH
+0xD6BB	0x53EA	#CJK UNIFIED IDEOGRAPH
+0xD6BC	0x65E8	#CJK UNIFIED IDEOGRAPH
+0xD6BD	0x7EB8	#CJK UNIFIED IDEOGRAPH
+0xD6BE	0x5FD7	#CJK UNIFIED IDEOGRAPH
+0xD6BF	0x631A	#CJK UNIFIED IDEOGRAPH
+0xD6C0	0x63B7	#CJK UNIFIED IDEOGRAPH
+0xD6C1	0x81F3	#CJK UNIFIED IDEOGRAPH
+0xD6C2	0x81F4	#CJK UNIFIED IDEOGRAPH
+0xD6C3	0x7F6E	#CJK UNIFIED IDEOGRAPH
+0xD6C4	0x5E1C	#CJK UNIFIED IDEOGRAPH
+0xD6C5	0x5CD9	#CJK UNIFIED IDEOGRAPH
+0xD6C6	0x5236	#CJK UNIFIED IDEOGRAPH
+0xD6C7	0x667A	#CJK UNIFIED IDEOGRAPH
+0xD6C8	0x79E9	#CJK UNIFIED IDEOGRAPH
+0xD6C9	0x7A1A	#CJK UNIFIED IDEOGRAPH
+0xD6CA	0x8D28	#CJK UNIFIED IDEOGRAPH
+0xD6CB	0x7099	#CJK UNIFIED IDEOGRAPH
+0xD6CC	0x75D4	#CJK UNIFIED IDEOGRAPH
+0xD6CD	0x6EDE	#CJK UNIFIED IDEOGRAPH
+0xD6CE	0x6CBB	#CJK UNIFIED IDEOGRAPH
+0xD6CF	0x7A92	#CJK UNIFIED IDEOGRAPH
+0xD6D0	0x4E2D	#CJK UNIFIED IDEOGRAPH
+0xD6D1	0x76C5	#CJK UNIFIED IDEOGRAPH
+0xD6D2	0x5FE0	#CJK UNIFIED IDEOGRAPH
+0xD6D3	0x949F	#CJK UNIFIED IDEOGRAPH
+0xD6D4	0x8877	#CJK UNIFIED IDEOGRAPH
+0xD6D5	0x7EC8	#CJK UNIFIED IDEOGRAPH
+0xD6D6	0x79CD	#CJK UNIFIED IDEOGRAPH
+0xD6D7	0x80BF	#CJK UNIFIED IDEOGRAPH
+0xD6D8	0x91CD	#CJK UNIFIED IDEOGRAPH
+0xD6D9	0x4EF2	#CJK UNIFIED IDEOGRAPH
+0xD6DA	0x4F17	#CJK UNIFIED IDEOGRAPH
+0xD6DB	0x821F	#CJK UNIFIED IDEOGRAPH
+0xD6DC	0x5468	#CJK UNIFIED IDEOGRAPH
+0xD6DD	0x5DDE	#CJK UNIFIED IDEOGRAPH
+0xD6DE	0x6D32	#CJK UNIFIED IDEOGRAPH
+0xD6DF	0x8BCC	#CJK UNIFIED IDEOGRAPH
+0xD6E0	0x7CA5	#CJK UNIFIED IDEOGRAPH
+0xD6E1	0x8F74	#CJK UNIFIED IDEOGRAPH
+0xD6E2	0x8098	#CJK UNIFIED IDEOGRAPH
+0xD6E3	0x5E1A	#CJK UNIFIED IDEOGRAPH
+0xD6E4	0x5492	#CJK UNIFIED IDEOGRAPH
+0xD6E5	0x76B1	#CJK UNIFIED IDEOGRAPH
+0xD6E6	0x5B99	#CJK UNIFIED IDEOGRAPH
+0xD6E7	0x663C	#CJK UNIFIED IDEOGRAPH
+0xD6E8	0x9AA4	#CJK UNIFIED IDEOGRAPH
+0xD6E9	0x73E0	#CJK UNIFIED IDEOGRAPH
+0xD6EA	0x682A	#CJK UNIFIED IDEOGRAPH
+0xD6EB	0x86DB	#CJK UNIFIED IDEOGRAPH
+0xD6EC	0x6731	#CJK UNIFIED IDEOGRAPH
+0xD6ED	0x732A	#CJK UNIFIED IDEOGRAPH
+0xD6EE	0x8BF8	#CJK UNIFIED IDEOGRAPH
+0xD6EF	0x8BDB	#CJK UNIFIED IDEOGRAPH
+0xD6F0	0x9010	#CJK UNIFIED IDEOGRAPH
+0xD6F1	0x7AF9	#CJK UNIFIED IDEOGRAPH
+0xD6F2	0x70DB	#CJK UNIFIED IDEOGRAPH
+0xD6F3	0x716E	#CJK UNIFIED IDEOGRAPH
+0xD6F4	0x62C4	#CJK UNIFIED IDEOGRAPH
+0xD6F5	0x77A9	#CJK UNIFIED IDEOGRAPH
+0xD6F6	0x5631	#CJK UNIFIED IDEOGRAPH
+0xD6F7	0x4E3B	#CJK UNIFIED IDEOGRAPH
+0xD6F8	0x8457	#CJK UNIFIED IDEOGRAPH
+0xD6F9	0x67F1	#CJK UNIFIED IDEOGRAPH
+0xD6FA	0x52A9	#CJK UNIFIED IDEOGRAPH
+0xD6FB	0x86C0	#CJK UNIFIED IDEOGRAPH
+0xD6FC	0x8D2E	#CJK UNIFIED IDEOGRAPH
+0xD6FD	0x94F8	#CJK UNIFIED IDEOGRAPH
+0xD6FE	0x7B51	#CJK UNIFIED IDEOGRAPH
+0xD740	0x8B46	#CJK UNIFIED IDEOGRAPH
+0xD741	0x8B47	#CJK UNIFIED IDEOGRAPH
+0xD742	0x8B48	#CJK UNIFIED IDEOGRAPH
+0xD743	0x8B49	#CJK UNIFIED IDEOGRAPH
+0xD744	0x8B4A	#CJK UNIFIED IDEOGRAPH
+0xD745	0x8B4B	#CJK UNIFIED IDEOGRAPH
+0xD746	0x8B4C	#CJK UNIFIED IDEOGRAPH
+0xD747	0x8B4D	#CJK UNIFIED IDEOGRAPH
+0xD748	0x8B4E	#CJK UNIFIED IDEOGRAPH
+0xD749	0x8B4F	#CJK UNIFIED IDEOGRAPH
+0xD74A	0x8B50	#CJK UNIFIED IDEOGRAPH
+0xD74B	0x8B51	#CJK UNIFIED IDEOGRAPH
+0xD74C	0x8B52	#CJK UNIFIED IDEOGRAPH
+0xD74D	0x8B53	#CJK UNIFIED IDEOGRAPH
+0xD74E	0x8B54	#CJK UNIFIED IDEOGRAPH
+0xD74F	0x8B55	#CJK UNIFIED IDEOGRAPH
+0xD750	0x8B56	#CJK UNIFIED IDEOGRAPH
+0xD751	0x8B57	#CJK UNIFIED IDEOGRAPH
+0xD752	0x8B58	#CJK UNIFIED IDEOGRAPH
+0xD753	0x8B59	#CJK UNIFIED IDEOGRAPH
+0xD754	0x8B5A	#CJK UNIFIED IDEOGRAPH
+0xD755	0x8B5B	#CJK UNIFIED IDEOGRAPH
+0xD756	0x8B5C	#CJK UNIFIED IDEOGRAPH
+0xD757	0x8B5D	#CJK UNIFIED IDEOGRAPH
+0xD758	0x8B5E	#CJK UNIFIED IDEOGRAPH
+0xD759	0x8B5F	#CJK UNIFIED IDEOGRAPH
+0xD75A	0x8B60	#CJK UNIFIED IDEOGRAPH
+0xD75B	0x8B61	#CJK UNIFIED IDEOGRAPH
+0xD75C	0x8B62	#CJK UNIFIED IDEOGRAPH
+0xD75D	0x8B63	#CJK UNIFIED IDEOGRAPH
+0xD75E	0x8B64	#CJK UNIFIED IDEOGRAPH
+0xD75F	0x8B65	#CJK UNIFIED IDEOGRAPH
+0xD760	0x8B67	#CJK UNIFIED IDEOGRAPH
+0xD761	0x8B68	#CJK UNIFIED IDEOGRAPH
+0xD762	0x8B69	#CJK UNIFIED IDEOGRAPH
+0xD763	0x8B6A	#CJK UNIFIED IDEOGRAPH
+0xD764	0x8B6B	#CJK UNIFIED IDEOGRAPH
+0xD765	0x8B6D	#CJK UNIFIED IDEOGRAPH
+0xD766	0x8B6E	#CJK UNIFIED IDEOGRAPH
+0xD767	0x8B6F	#CJK UNIFIED IDEOGRAPH
+0xD768	0x8B70	#CJK UNIFIED IDEOGRAPH
+0xD769	0x8B71	#CJK UNIFIED IDEOGRAPH
+0xD76A	0x8B72	#CJK UNIFIED IDEOGRAPH
+0xD76B	0x8B73	#CJK UNIFIED IDEOGRAPH
+0xD76C	0x8B74	#CJK UNIFIED IDEOGRAPH
+0xD76D	0x8B75	#CJK UNIFIED IDEOGRAPH
+0xD76E	0x8B76	#CJK UNIFIED IDEOGRAPH
+0xD76F	0x8B77	#CJK UNIFIED IDEOGRAPH
+0xD770	0x8B78	#CJK UNIFIED IDEOGRAPH
+0xD771	0x8B79	#CJK UNIFIED IDEOGRAPH
+0xD772	0x8B7A	#CJK UNIFIED IDEOGRAPH
+0xD773	0x8B7B	#CJK UNIFIED IDEOGRAPH
+0xD774	0x8B7C	#CJK UNIFIED IDEOGRAPH
+0xD775	0x8B7D	#CJK UNIFIED IDEOGRAPH
+0xD776	0x8B7E	#CJK UNIFIED IDEOGRAPH
+0xD777	0x8B7F	#CJK UNIFIED IDEOGRAPH
+0xD778	0x8B80	#CJK UNIFIED IDEOGRAPH
+0xD779	0x8B81	#CJK UNIFIED IDEOGRAPH
+0xD77A	0x8B82	#CJK UNIFIED IDEOGRAPH
+0xD77B	0x8B83	#CJK UNIFIED IDEOGRAPH
+0xD77C	0x8B84	#CJK UNIFIED IDEOGRAPH
+0xD77D	0x8B85	#CJK UNIFIED IDEOGRAPH
+0xD77E	0x8B86	#CJK UNIFIED IDEOGRAPH
+0xD780	0x8B87	#CJK UNIFIED IDEOGRAPH
+0xD781	0x8B88	#CJK UNIFIED IDEOGRAPH
+0xD782	0x8B89	#CJK UNIFIED IDEOGRAPH
+0xD783	0x8B8A	#CJK UNIFIED IDEOGRAPH
+0xD784	0x8B8B	#CJK UNIFIED IDEOGRAPH
+0xD785	0x8B8C	#CJK UNIFIED IDEOGRAPH
+0xD786	0x8B8D	#CJK UNIFIED IDEOGRAPH
+0xD787	0x8B8E	#CJK UNIFIED IDEOGRAPH
+0xD788	0x8B8F	#CJK UNIFIED IDEOGRAPH
+0xD789	0x8B90	#CJK UNIFIED IDEOGRAPH
+0xD78A	0x8B91	#CJK UNIFIED IDEOGRAPH
+0xD78B	0x8B92	#CJK UNIFIED IDEOGRAPH
+0xD78C	0x8B93	#CJK UNIFIED IDEOGRAPH
+0xD78D	0x8B94	#CJK UNIFIED IDEOGRAPH
+0xD78E	0x8B95	#CJK UNIFIED IDEOGRAPH
+0xD78F	0x8B96	#CJK UNIFIED IDEOGRAPH
+0xD790	0x8B97	#CJK UNIFIED IDEOGRAPH
+0xD791	0x8B98	#CJK UNIFIED IDEOGRAPH
+0xD792	0x8B99	#CJK UNIFIED IDEOGRAPH
+0xD793	0x8B9A	#CJK UNIFIED IDEOGRAPH
+0xD794	0x8B9B	#CJK UNIFIED IDEOGRAPH
+0xD795	0x8B9C	#CJK UNIFIED IDEOGRAPH
+0xD796	0x8B9D	#CJK UNIFIED IDEOGRAPH
+0xD797	0x8B9E	#CJK UNIFIED IDEOGRAPH
+0xD798	0x8B9F	#CJK UNIFIED IDEOGRAPH
+0xD799	0x8BAC	#CJK UNIFIED IDEOGRAPH
+0xD79A	0x8BB1	#CJK UNIFIED IDEOGRAPH
+0xD79B	0x8BBB	#CJK UNIFIED IDEOGRAPH
+0xD79C	0x8BC7	#CJK UNIFIED IDEOGRAPH
+0xD79D	0x8BD0	#CJK UNIFIED IDEOGRAPH
+0xD79E	0x8BEA	#CJK UNIFIED IDEOGRAPH
+0xD79F	0x8C09	#CJK UNIFIED IDEOGRAPH
+0xD7A0	0x8C1E	#CJK UNIFIED IDEOGRAPH
+0xD7A1	0x4F4F	#CJK UNIFIED IDEOGRAPH
+0xD7A2	0x6CE8	#CJK UNIFIED IDEOGRAPH
+0xD7A3	0x795D	#CJK UNIFIED IDEOGRAPH
+0xD7A4	0x9A7B	#CJK UNIFIED IDEOGRAPH
+0xD7A5	0x6293	#CJK UNIFIED IDEOGRAPH
+0xD7A6	0x722A	#CJK UNIFIED IDEOGRAPH
+0xD7A7	0x62FD	#CJK UNIFIED IDEOGRAPH
+0xD7A8	0x4E13	#CJK UNIFIED IDEOGRAPH
+0xD7A9	0x7816	#CJK UNIFIED IDEOGRAPH
+0xD7AA	0x8F6C	#CJK UNIFIED IDEOGRAPH
+0xD7AB	0x64B0	#CJK UNIFIED IDEOGRAPH
+0xD7AC	0x8D5A	#CJK UNIFIED IDEOGRAPH
+0xD7AD	0x7BC6	#CJK UNIFIED IDEOGRAPH
+0xD7AE	0x6869	#CJK UNIFIED IDEOGRAPH
+0xD7AF	0x5E84	#CJK UNIFIED IDEOGRAPH
+0xD7B0	0x88C5	#CJK UNIFIED IDEOGRAPH
+0xD7B1	0x5986	#CJK UNIFIED IDEOGRAPH
+0xD7B2	0x649E	#CJK UNIFIED IDEOGRAPH
+0xD7B3	0x58EE	#CJK UNIFIED IDEOGRAPH
+0xD7B4	0x72B6	#CJK UNIFIED IDEOGRAPH
+0xD7B5	0x690E	#CJK UNIFIED IDEOGRAPH
+0xD7B6	0x9525	#CJK UNIFIED IDEOGRAPH
+0xD7B7	0x8FFD	#CJK UNIFIED IDEOGRAPH
+0xD7B8	0x8D58	#CJK UNIFIED IDEOGRAPH
+0xD7B9	0x5760	#CJK UNIFIED IDEOGRAPH
+0xD7BA	0x7F00	#CJK UNIFIED IDEOGRAPH
+0xD7BB	0x8C06	#CJK UNIFIED IDEOGRAPH
+0xD7BC	0x51C6	#CJK UNIFIED IDEOGRAPH
+0xD7BD	0x6349	#CJK UNIFIED IDEOGRAPH
+0xD7BE	0x62D9	#CJK UNIFIED IDEOGRAPH
+0xD7BF	0x5353	#CJK UNIFIED IDEOGRAPH
+0xD7C0	0x684C	#CJK UNIFIED IDEOGRAPH
+0xD7C1	0x7422	#CJK UNIFIED IDEOGRAPH
+0xD7C2	0x8301	#CJK UNIFIED IDEOGRAPH
+0xD7C3	0x914C	#CJK UNIFIED IDEOGRAPH
+0xD7C4	0x5544	#CJK UNIFIED IDEOGRAPH
+0xD7C5	0x7740	#CJK UNIFIED IDEOGRAPH
+0xD7C6	0x707C	#CJK UNIFIED IDEOGRAPH
+0xD7C7	0x6D4A	#CJK UNIFIED IDEOGRAPH
+0xD7C8	0x5179	#CJK UNIFIED IDEOGRAPH
+0xD7C9	0x54A8	#CJK UNIFIED IDEOGRAPH
+0xD7CA	0x8D44	#CJK UNIFIED IDEOGRAPH
+0xD7CB	0x59FF	#CJK UNIFIED IDEOGRAPH
+0xD7CC	0x6ECB	#CJK UNIFIED IDEOGRAPH
+0xD7CD	0x6DC4	#CJK UNIFIED IDEOGRAPH
+0xD7CE	0x5B5C	#CJK UNIFIED IDEOGRAPH
+0xD7CF	0x7D2B	#CJK UNIFIED IDEOGRAPH
+0xD7D0	0x4ED4	#CJK UNIFIED IDEOGRAPH
+0xD7D1	0x7C7D	#CJK UNIFIED IDEOGRAPH
+0xD7D2	0x6ED3	#CJK UNIFIED IDEOGRAPH
+0xD7D3	0x5B50	#CJK UNIFIED IDEOGRAPH
+0xD7D4	0x81EA	#CJK UNIFIED IDEOGRAPH
+0xD7D5	0x6E0D	#CJK UNIFIED IDEOGRAPH
+0xD7D6	0x5B57	#CJK UNIFIED IDEOGRAPH
+0xD7D7	0x9B03	#CJK UNIFIED IDEOGRAPH
+0xD7D8	0x68D5	#CJK UNIFIED IDEOGRAPH
+0xD7D9	0x8E2A	#CJK UNIFIED IDEOGRAPH
+0xD7DA	0x5B97	#CJK UNIFIED IDEOGRAPH
+0xD7DB	0x7EFC	#CJK UNIFIED IDEOGRAPH
+0xD7DC	0x603B	#CJK UNIFIED IDEOGRAPH
+0xD7DD	0x7EB5	#CJK UNIFIED IDEOGRAPH
+0xD7DE	0x90B9	#CJK UNIFIED IDEOGRAPH
+0xD7DF	0x8D70	#CJK UNIFIED IDEOGRAPH
+0xD7E0	0x594F	#CJK UNIFIED IDEOGRAPH
+0xD7E1	0x63CD	#CJK UNIFIED IDEOGRAPH
+0xD7E2	0x79DF	#CJK UNIFIED IDEOGRAPH
+0xD7E3	0x8DB3	#CJK UNIFIED IDEOGRAPH
+0xD7E4	0x5352	#CJK UNIFIED IDEOGRAPH
+0xD7E5	0x65CF	#CJK UNIFIED IDEOGRAPH
+0xD7E6	0x7956	#CJK UNIFIED IDEOGRAPH
+0xD7E7	0x8BC5	#CJK UNIFIED IDEOGRAPH
+0xD7E8	0x963B	#CJK UNIFIED IDEOGRAPH
+0xD7E9	0x7EC4	#CJK UNIFIED IDEOGRAPH
+0xD7EA	0x94BB	#CJK UNIFIED IDEOGRAPH
+0xD7EB	0x7E82	#CJK UNIFIED IDEOGRAPH
+0xD7EC	0x5634	#CJK UNIFIED IDEOGRAPH
+0xD7ED	0x9189	#CJK UNIFIED IDEOGRAPH
+0xD7EE	0x6700	#CJK UNIFIED IDEOGRAPH
+0xD7EF	0x7F6A	#CJK UNIFIED IDEOGRAPH
+0xD7F0	0x5C0A	#CJK UNIFIED IDEOGRAPH
+0xD7F1	0x9075	#CJK UNIFIED IDEOGRAPH
+0xD7F2	0x6628	#CJK UNIFIED IDEOGRAPH
+0xD7F3	0x5DE6	#CJK UNIFIED IDEOGRAPH
+0xD7F4	0x4F50	#CJK UNIFIED IDEOGRAPH
+0xD7F5	0x67DE	#CJK UNIFIED IDEOGRAPH
+0xD7F6	0x505A	#CJK UNIFIED IDEOGRAPH
+0xD7F7	0x4F5C	#CJK UNIFIED IDEOGRAPH
+0xD7F8	0x5750	#CJK UNIFIED IDEOGRAPH
+0xD7F9	0x5EA7	#CJK UNIFIED IDEOGRAPH
+0xD840	0x8C38	#CJK UNIFIED IDEOGRAPH
+0xD841	0x8C39	#CJK UNIFIED IDEOGRAPH
+0xD842	0x8C3A	#CJK UNIFIED IDEOGRAPH
+0xD843	0x8C3B	#CJK UNIFIED IDEOGRAPH
+0xD844	0x8C3C	#CJK UNIFIED IDEOGRAPH
+0xD845	0x8C3D	#CJK UNIFIED IDEOGRAPH
+0xD846	0x8C3E	#CJK UNIFIED IDEOGRAPH
+0xD847	0x8C3F	#CJK UNIFIED IDEOGRAPH
+0xD848	0x8C40	#CJK UNIFIED IDEOGRAPH
+0xD849	0x8C42	#CJK UNIFIED IDEOGRAPH
+0xD84A	0x8C43	#CJK UNIFIED IDEOGRAPH
+0xD84B	0x8C44	#CJK UNIFIED IDEOGRAPH
+0xD84C	0x8C45	#CJK UNIFIED IDEOGRAPH
+0xD84D	0x8C48	#CJK UNIFIED IDEOGRAPH
+0xD84E	0x8C4A	#CJK UNIFIED IDEOGRAPH
+0xD84F	0x8C4B	#CJK UNIFIED IDEOGRAPH
+0xD850	0x8C4D	#CJK UNIFIED IDEOGRAPH
+0xD851	0x8C4E	#CJK UNIFIED IDEOGRAPH
+0xD852	0x8C4F	#CJK UNIFIED IDEOGRAPH
+0xD853	0x8C50	#CJK UNIFIED IDEOGRAPH
+0xD854	0x8C51	#CJK UNIFIED IDEOGRAPH
+0xD855	0x8C52	#CJK UNIFIED IDEOGRAPH
+0xD856	0x8C53	#CJK UNIFIED IDEOGRAPH
+0xD857	0x8C54	#CJK UNIFIED IDEOGRAPH
+0xD858	0x8C56	#CJK UNIFIED IDEOGRAPH
+0xD859	0x8C57	#CJK UNIFIED IDEOGRAPH
+0xD85A	0x8C58	#CJK UNIFIED IDEOGRAPH
+0xD85B	0x8C59	#CJK UNIFIED IDEOGRAPH
+0xD85C	0x8C5B	#CJK UNIFIED IDEOGRAPH
+0xD85D	0x8C5C	#CJK UNIFIED IDEOGRAPH
+0xD85E	0x8C5D	#CJK UNIFIED IDEOGRAPH
+0xD85F	0x8C5E	#CJK UNIFIED IDEOGRAPH
+0xD860	0x8C5F	#CJK UNIFIED IDEOGRAPH
+0xD861	0x8C60	#CJK UNIFIED IDEOGRAPH
+0xD862	0x8C63	#CJK UNIFIED IDEOGRAPH
+0xD863	0x8C64	#CJK UNIFIED IDEOGRAPH
+0xD864	0x8C65	#CJK UNIFIED IDEOGRAPH
+0xD865	0x8C66	#CJK UNIFIED IDEOGRAPH
+0xD866	0x8C67	#CJK UNIFIED IDEOGRAPH
+0xD867	0x8C68	#CJK UNIFIED IDEOGRAPH
+0xD868	0x8C69	#CJK UNIFIED IDEOGRAPH
+0xD869	0x8C6C	#CJK UNIFIED IDEOGRAPH
+0xD86A	0x8C6D	#CJK UNIFIED IDEOGRAPH
+0xD86B	0x8C6E	#CJK UNIFIED IDEOGRAPH
+0xD86C	0x8C6F	#CJK UNIFIED IDEOGRAPH
+0xD86D	0x8C70	#CJK UNIFIED IDEOGRAPH
+0xD86E	0x8C71	#CJK UNIFIED IDEOGRAPH
+0xD86F	0x8C72	#CJK UNIFIED IDEOGRAPH
+0xD870	0x8C74	#CJK UNIFIED IDEOGRAPH
+0xD871	0x8C75	#CJK UNIFIED IDEOGRAPH
+0xD872	0x8C76	#CJK UNIFIED IDEOGRAPH
+0xD873	0x8C77	#CJK UNIFIED IDEOGRAPH
+0xD874	0x8C7B	#CJK UNIFIED IDEOGRAPH
+0xD875	0x8C7C	#CJK UNIFIED IDEOGRAPH
+0xD876	0x8C7D	#CJK UNIFIED IDEOGRAPH
+0xD877	0x8C7E	#CJK UNIFIED IDEOGRAPH
+0xD878	0x8C7F	#CJK UNIFIED IDEOGRAPH
+0xD879	0x8C80	#CJK UNIFIED IDEOGRAPH
+0xD87A	0x8C81	#CJK UNIFIED IDEOGRAPH
+0xD87B	0x8C83	#CJK UNIFIED IDEOGRAPH
+0xD87C	0x8C84	#CJK UNIFIED IDEOGRAPH
+0xD87D	0x8C86	#CJK UNIFIED IDEOGRAPH
+0xD87E	0x8C87	#CJK UNIFIED IDEOGRAPH
+0xD880	0x8C88	#CJK UNIFIED IDEOGRAPH
+0xD881	0x8C8B	#CJK UNIFIED IDEOGRAPH
+0xD882	0x8C8D	#CJK UNIFIED IDEOGRAPH
+0xD883	0x8C8E	#CJK UNIFIED IDEOGRAPH
+0xD884	0x8C8F	#CJK UNIFIED IDEOGRAPH
+0xD885	0x8C90	#CJK UNIFIED IDEOGRAPH
+0xD886	0x8C91	#CJK UNIFIED IDEOGRAPH
+0xD887	0x8C92	#CJK UNIFIED IDEOGRAPH
+0xD888	0x8C93	#CJK UNIFIED IDEOGRAPH
+0xD889	0x8C95	#CJK UNIFIED IDEOGRAPH
+0xD88A	0x8C96	#CJK UNIFIED IDEOGRAPH
+0xD88B	0x8C97	#CJK UNIFIED IDEOGRAPH
+0xD88C	0x8C99	#CJK UNIFIED IDEOGRAPH
+0xD88D	0x8C9A	#CJK UNIFIED IDEOGRAPH
+0xD88E	0x8C9B	#CJK UNIFIED IDEOGRAPH
+0xD88F	0x8C9C	#CJK UNIFIED IDEOGRAPH
+0xD890	0x8C9D	#CJK UNIFIED IDEOGRAPH
+0xD891	0x8C9E	#CJK UNIFIED IDEOGRAPH
+0xD892	0x8C9F	#CJK UNIFIED IDEOGRAPH
+0xD893	0x8CA0	#CJK UNIFIED IDEOGRAPH
+0xD894	0x8CA1	#CJK UNIFIED IDEOGRAPH
+0xD895	0x8CA2	#CJK UNIFIED IDEOGRAPH
+0xD896	0x8CA3	#CJK UNIFIED IDEOGRAPH
+0xD897	0x8CA4	#CJK UNIFIED IDEOGRAPH
+0xD898	0x8CA5	#CJK UNIFIED IDEOGRAPH
+0xD899	0x8CA6	#CJK UNIFIED IDEOGRAPH
+0xD89A	0x8CA7	#CJK UNIFIED IDEOGRAPH
+0xD89B	0x8CA8	#CJK UNIFIED IDEOGRAPH
+0xD89C	0x8CA9	#CJK UNIFIED IDEOGRAPH
+0xD89D	0x8CAA	#CJK UNIFIED IDEOGRAPH
+0xD89E	0x8CAB	#CJK UNIFIED IDEOGRAPH
+0xD89F	0x8CAC	#CJK UNIFIED IDEOGRAPH
+0xD8A0	0x8CAD	#CJK UNIFIED IDEOGRAPH
+0xD8A1	0x4E8D	#CJK UNIFIED IDEOGRAPH
+0xD8A2	0x4E0C	#CJK UNIFIED IDEOGRAPH
+0xD8A3	0x5140	#CJK UNIFIED IDEOGRAPH
+0xD8A4	0x4E10	#CJK UNIFIED IDEOGRAPH
+0xD8A5	0x5EFF	#CJK UNIFIED IDEOGRAPH
+0xD8A6	0x5345	#CJK UNIFIED IDEOGRAPH
+0xD8A7	0x4E15	#CJK UNIFIED IDEOGRAPH
+0xD8A8	0x4E98	#CJK UNIFIED IDEOGRAPH
+0xD8A9	0x4E1E	#CJK UNIFIED IDEOGRAPH
+0xD8AA	0x9B32	#CJK UNIFIED IDEOGRAPH
+0xD8AB	0x5B6C	#CJK UNIFIED IDEOGRAPH
+0xD8AC	0x5669	#CJK UNIFIED IDEOGRAPH
+0xD8AD	0x4E28	#CJK UNIFIED IDEOGRAPH
+0xD8AE	0x79BA	#CJK UNIFIED IDEOGRAPH
+0xD8AF	0x4E3F	#CJK UNIFIED IDEOGRAPH
+0xD8B0	0x5315	#CJK UNIFIED IDEOGRAPH
+0xD8B1	0x4E47	#CJK UNIFIED IDEOGRAPH
+0xD8B2	0x592D	#CJK UNIFIED IDEOGRAPH
+0xD8B3	0x723B	#CJK UNIFIED IDEOGRAPH
+0xD8B4	0x536E	#CJK UNIFIED IDEOGRAPH
+0xD8B5	0x6C10	#CJK UNIFIED IDEOGRAPH
+0xD8B6	0x56DF	#CJK UNIFIED IDEOGRAPH
+0xD8B7	0x80E4	#CJK UNIFIED IDEOGRAPH
+0xD8B8	0x9997	#CJK UNIFIED IDEOGRAPH
+0xD8B9	0x6BD3	#CJK UNIFIED IDEOGRAPH
+0xD8BA	0x777E	#CJK UNIFIED IDEOGRAPH
+0xD8BB	0x9F17	#CJK UNIFIED IDEOGRAPH
+0xD8BC	0x4E36	#CJK UNIFIED IDEOGRAPH
+0xD8BD	0x4E9F	#CJK UNIFIED IDEOGRAPH
+0xD8BE	0x9F10	#CJK UNIFIED IDEOGRAPH
+0xD8BF	0x4E5C	#CJK UNIFIED IDEOGRAPH
+0xD8C0	0x4E69	#CJK UNIFIED IDEOGRAPH
+0xD8C1	0x4E93	#CJK UNIFIED IDEOGRAPH
+0xD8C2	0x8288	#CJK UNIFIED IDEOGRAPH
+0xD8C3	0x5B5B	#CJK UNIFIED IDEOGRAPH
+0xD8C4	0x556C	#CJK UNIFIED IDEOGRAPH
+0xD8C5	0x560F	#CJK UNIFIED IDEOGRAPH
+0xD8C6	0x4EC4	#CJK UNIFIED IDEOGRAPH
+0xD8C7	0x538D	#CJK UNIFIED IDEOGRAPH
+0xD8C8	0x539D	#CJK UNIFIED IDEOGRAPH
+0xD8C9	0x53A3	#CJK UNIFIED IDEOGRAPH
+0xD8CA	0x53A5	#CJK UNIFIED IDEOGRAPH
+0xD8CB	0x53AE	#CJK UNIFIED IDEOGRAPH
+0xD8CC	0x9765	#CJK UNIFIED IDEOGRAPH
+0xD8CD	0x8D5D	#CJK UNIFIED IDEOGRAPH
+0xD8CE	0x531A	#CJK UNIFIED IDEOGRAPH
+0xD8CF	0x53F5	#CJK UNIFIED IDEOGRAPH
+0xD8D0	0x5326	#CJK UNIFIED IDEOGRAPH
+0xD8D1	0x532E	#CJK UNIFIED IDEOGRAPH
+0xD8D2	0x533E	#CJK UNIFIED IDEOGRAPH
+0xD8D3	0x8D5C	#CJK UNIFIED IDEOGRAPH
+0xD8D4	0x5366	#CJK UNIFIED IDEOGRAPH
+0xD8D5	0x5363	#CJK UNIFIED IDEOGRAPH
+0xD8D6	0x5202	#CJK UNIFIED IDEOGRAPH
+0xD8D7	0x5208	#CJK UNIFIED IDEOGRAPH
+0xD8D8	0x520E	#CJK UNIFIED IDEOGRAPH
+0xD8D9	0x522D	#CJK UNIFIED IDEOGRAPH
+0xD8DA	0x5233	#CJK UNIFIED IDEOGRAPH
+0xD8DB	0x523F	#CJK UNIFIED IDEOGRAPH
+0xD8DC	0x5240	#CJK UNIFIED IDEOGRAPH
+0xD8DD	0x524C	#CJK UNIFIED IDEOGRAPH
+0xD8DE	0x525E	#CJK UNIFIED IDEOGRAPH
+0xD8DF	0x5261	#CJK UNIFIED IDEOGRAPH
+0xD8E0	0x525C	#CJK UNIFIED IDEOGRAPH
+0xD8E1	0x84AF	#CJK UNIFIED IDEOGRAPH
+0xD8E2	0x527D	#CJK UNIFIED IDEOGRAPH
+0xD8E3	0x5282	#CJK UNIFIED IDEOGRAPH
+0xD8E4	0x5281	#CJK UNIFIED IDEOGRAPH
+0xD8E5	0x5290	#CJK UNIFIED IDEOGRAPH
+0xD8E6	0x5293	#CJK UNIFIED IDEOGRAPH
+0xD8E7	0x5182	#CJK UNIFIED IDEOGRAPH
+0xD8E8	0x7F54	#CJK UNIFIED IDEOGRAPH
+0xD8E9	0x4EBB	#CJK UNIFIED IDEOGRAPH
+0xD8EA	0x4EC3	#CJK UNIFIED IDEOGRAPH
+0xD8EB	0x4EC9	#CJK UNIFIED IDEOGRAPH
+0xD8EC	0x4EC2	#CJK UNIFIED IDEOGRAPH
+0xD8ED	0x4EE8	#CJK UNIFIED IDEOGRAPH
+0xD8EE	0x4EE1	#CJK UNIFIED IDEOGRAPH
+0xD8EF	0x4EEB	#CJK UNIFIED IDEOGRAPH
+0xD8F0	0x4EDE	#CJK UNIFIED IDEOGRAPH
+0xD8F1	0x4F1B	#CJK UNIFIED IDEOGRAPH
+0xD8F2	0x4EF3	#CJK UNIFIED IDEOGRAPH
+0xD8F3	0x4F22	#CJK UNIFIED IDEOGRAPH
+0xD8F4	0x4F64	#CJK UNIFIED IDEOGRAPH
+0xD8F5	0x4EF5	#CJK UNIFIED IDEOGRAPH
+0xD8F6	0x4F25	#CJK UNIFIED IDEOGRAPH
+0xD8F7	0x4F27	#CJK UNIFIED IDEOGRAPH
+0xD8F8	0x4F09	#CJK UNIFIED IDEOGRAPH
+0xD8F9	0x4F2B	#CJK UNIFIED IDEOGRAPH
+0xD8FA	0x4F5E	#CJK UNIFIED IDEOGRAPH
+0xD8FB	0x4F67	#CJK UNIFIED IDEOGRAPH
+0xD8FC	0x6538	#CJK UNIFIED IDEOGRAPH
+0xD8FD	0x4F5A	#CJK UNIFIED IDEOGRAPH
+0xD8FE	0x4F5D	#CJK UNIFIED IDEOGRAPH
+0xD940	0x8CAE	#CJK UNIFIED IDEOGRAPH
+0xD941	0x8CAF	#CJK UNIFIED IDEOGRAPH
+0xD942	0x8CB0	#CJK UNIFIED IDEOGRAPH
+0xD943	0x8CB1	#CJK UNIFIED IDEOGRAPH
+0xD944	0x8CB2	#CJK UNIFIED IDEOGRAPH
+0xD945	0x8CB3	#CJK UNIFIED IDEOGRAPH
+0xD946	0x8CB4	#CJK UNIFIED IDEOGRAPH
+0xD947	0x8CB5	#CJK UNIFIED IDEOGRAPH
+0xD948	0x8CB6	#CJK UNIFIED IDEOGRAPH
+0xD949	0x8CB7	#CJK UNIFIED IDEOGRAPH
+0xD94A	0x8CB8	#CJK UNIFIED IDEOGRAPH
+0xD94B	0x8CB9	#CJK UNIFIED IDEOGRAPH
+0xD94C	0x8CBA	#CJK UNIFIED IDEOGRAPH
+0xD94D	0x8CBB	#CJK UNIFIED IDEOGRAPH
+0xD94E	0x8CBC	#CJK UNIFIED IDEOGRAPH
+0xD94F	0x8CBD	#CJK UNIFIED IDEOGRAPH
+0xD950	0x8CBE	#CJK UNIFIED IDEOGRAPH
+0xD951	0x8CBF	#CJK UNIFIED IDEOGRAPH
+0xD952	0x8CC0	#CJK UNIFIED IDEOGRAPH
+0xD953	0x8CC1	#CJK UNIFIED IDEOGRAPH
+0xD954	0x8CC2	#CJK UNIFIED IDEOGRAPH
+0xD955	0x8CC3	#CJK UNIFIED IDEOGRAPH
+0xD956	0x8CC4	#CJK UNIFIED IDEOGRAPH
+0xD957	0x8CC5	#CJK UNIFIED IDEOGRAPH
+0xD958	0x8CC6	#CJK UNIFIED IDEOGRAPH
+0xD959	0x8CC7	#CJK UNIFIED IDEOGRAPH
+0xD95A	0x8CC8	#CJK UNIFIED IDEOGRAPH
+0xD95B	0x8CC9	#CJK UNIFIED IDEOGRAPH
+0xD95C	0x8CCA	#CJK UNIFIED IDEOGRAPH
+0xD95D	0x8CCB	#CJK UNIFIED IDEOGRAPH
+0xD95E	0x8CCC	#CJK UNIFIED IDEOGRAPH
+0xD95F	0x8CCD	#CJK UNIFIED IDEOGRAPH
+0xD960	0x8CCE	#CJK UNIFIED IDEOGRAPH
+0xD961	0x8CCF	#CJK UNIFIED IDEOGRAPH
+0xD962	0x8CD0	#CJK UNIFIED IDEOGRAPH
+0xD963	0x8CD1	#CJK UNIFIED IDEOGRAPH
+0xD964	0x8CD2	#CJK UNIFIED IDEOGRAPH
+0xD965	0x8CD3	#CJK UNIFIED IDEOGRAPH
+0xD966	0x8CD4	#CJK UNIFIED IDEOGRAPH
+0xD967	0x8CD5	#CJK UNIFIED IDEOGRAPH
+0xD968	0x8CD6	#CJK UNIFIED IDEOGRAPH
+0xD969	0x8CD7	#CJK UNIFIED IDEOGRAPH
+0xD96A	0x8CD8	#CJK UNIFIED IDEOGRAPH
+0xD96B	0x8CD9	#CJK UNIFIED IDEOGRAPH
+0xD96C	0x8CDA	#CJK UNIFIED IDEOGRAPH
+0xD96D	0x8CDB	#CJK UNIFIED IDEOGRAPH
+0xD96E	0x8CDC	#CJK UNIFIED IDEOGRAPH
+0xD96F	0x8CDD	#CJK UNIFIED IDEOGRAPH
+0xD970	0x8CDE	#CJK UNIFIED IDEOGRAPH
+0xD971	0x8CDF	#CJK UNIFIED IDEOGRAPH
+0xD972	0x8CE0	#CJK UNIFIED IDEOGRAPH
+0xD973	0x8CE1	#CJK UNIFIED IDEOGRAPH
+0xD974	0x8CE2	#CJK UNIFIED IDEOGRAPH
+0xD975	0x8CE3	#CJK UNIFIED IDEOGRAPH
+0xD976	0x8CE4	#CJK UNIFIED IDEOGRAPH
+0xD977	0x8CE5	#CJK UNIFIED IDEOGRAPH
+0xD978	0x8CE6	#CJK UNIFIED IDEOGRAPH
+0xD979	0x8CE7	#CJK UNIFIED IDEOGRAPH
+0xD97A	0x8CE8	#CJK UNIFIED IDEOGRAPH
+0xD97B	0x8CE9	#CJK UNIFIED IDEOGRAPH
+0xD97C	0x8CEA	#CJK UNIFIED IDEOGRAPH
+0xD97D	0x8CEB	#CJK UNIFIED IDEOGRAPH
+0xD97E	0x8CEC	#CJK UNIFIED IDEOGRAPH
+0xD980	0x8CED	#CJK UNIFIED IDEOGRAPH
+0xD981	0x8CEE	#CJK UNIFIED IDEOGRAPH
+0xD982	0x8CEF	#CJK UNIFIED IDEOGRAPH
+0xD983	0x8CF0	#CJK UNIFIED IDEOGRAPH
+0xD984	0x8CF1	#CJK UNIFIED IDEOGRAPH
+0xD985	0x8CF2	#CJK UNIFIED IDEOGRAPH
+0xD986	0x8CF3	#CJK UNIFIED IDEOGRAPH
+0xD987	0x8CF4	#CJK UNIFIED IDEOGRAPH
+0xD988	0x8CF5	#CJK UNIFIED IDEOGRAPH
+0xD989	0x8CF6	#CJK UNIFIED IDEOGRAPH
+0xD98A	0x8CF7	#CJK UNIFIED IDEOGRAPH
+0xD98B	0x8CF8	#CJK UNIFIED IDEOGRAPH
+0xD98C	0x8CF9	#CJK UNIFIED IDEOGRAPH
+0xD98D	0x8CFA	#CJK UNIFIED IDEOGRAPH
+0xD98E	0x8CFB	#CJK UNIFIED IDEOGRAPH
+0xD98F	0x8CFC	#CJK UNIFIED IDEOGRAPH
+0xD990	0x8CFD	#CJK UNIFIED IDEOGRAPH
+0xD991	0x8CFE	#CJK UNIFIED IDEOGRAPH
+0xD992	0x8CFF	#CJK UNIFIED IDEOGRAPH
+0xD993	0x8D00	#CJK UNIFIED IDEOGRAPH
+0xD994	0x8D01	#CJK UNIFIED IDEOGRAPH
+0xD995	0x8D02	#CJK UNIFIED IDEOGRAPH
+0xD996	0x8D03	#CJK UNIFIED IDEOGRAPH
+0xD997	0x8D04	#CJK UNIFIED IDEOGRAPH
+0xD998	0x8D05	#CJK UNIFIED IDEOGRAPH
+0xD999	0x8D06	#CJK UNIFIED IDEOGRAPH
+0xD99A	0x8D07	#CJK UNIFIED IDEOGRAPH
+0xD99B	0x8D08	#CJK UNIFIED IDEOGRAPH
+0xD99C	0x8D09	#CJK UNIFIED IDEOGRAPH
+0xD99D	0x8D0A	#CJK UNIFIED IDEOGRAPH
+0xD99E	0x8D0B	#CJK UNIFIED IDEOGRAPH
+0xD99F	0x8D0C	#CJK UNIFIED IDEOGRAPH
+0xD9A0	0x8D0D	#CJK UNIFIED IDEOGRAPH
+0xD9A1	0x4F5F	#CJK UNIFIED IDEOGRAPH
+0xD9A2	0x4F57	#CJK UNIFIED IDEOGRAPH
+0xD9A3	0x4F32	#CJK UNIFIED IDEOGRAPH
+0xD9A4	0x4F3D	#CJK UNIFIED IDEOGRAPH
+0xD9A5	0x4F76	#CJK UNIFIED IDEOGRAPH
+0xD9A6	0x4F74	#CJK UNIFIED IDEOGRAPH
+0xD9A7	0x4F91	#CJK UNIFIED IDEOGRAPH
+0xD9A8	0x4F89	#CJK UNIFIED IDEOGRAPH
+0xD9A9	0x4F83	#CJK UNIFIED IDEOGRAPH
+0xD9AA	0x4F8F	#CJK UNIFIED IDEOGRAPH
+0xD9AB	0x4F7E	#CJK UNIFIED IDEOGRAPH
+0xD9AC	0x4F7B	#CJK UNIFIED IDEOGRAPH
+0xD9AD	0x4FAA	#CJK UNIFIED IDEOGRAPH
+0xD9AE	0x4F7C	#CJK UNIFIED IDEOGRAPH
+0xD9AF	0x4FAC	#CJK UNIFIED IDEOGRAPH
+0xD9B0	0x4F94	#CJK UNIFIED IDEOGRAPH
+0xD9B1	0x4FE6	#CJK UNIFIED IDEOGRAPH
+0xD9B2	0x4FE8	#CJK UNIFIED IDEOGRAPH
+0xD9B3	0x4FEA	#CJK UNIFIED IDEOGRAPH
+0xD9B4	0x4FC5	#CJK UNIFIED IDEOGRAPH
+0xD9B5	0x4FDA	#CJK UNIFIED IDEOGRAPH
+0xD9B6	0x4FE3	#CJK UNIFIED IDEOGRAPH
+0xD9B7	0x4FDC	#CJK UNIFIED IDEOGRAPH
+0xD9B8	0x4FD1	#CJK UNIFIED IDEOGRAPH
+0xD9B9	0x4FDF	#CJK UNIFIED IDEOGRAPH
+0xD9BA	0x4FF8	#CJK UNIFIED IDEOGRAPH
+0xD9BB	0x5029	#CJK UNIFIED IDEOGRAPH
+0xD9BC	0x504C	#CJK UNIFIED IDEOGRAPH
+0xD9BD	0x4FF3	#CJK UNIFIED IDEOGRAPH
+0xD9BE	0x502C	#CJK UNIFIED IDEOGRAPH
+0xD9BF	0x500F	#CJK UNIFIED IDEOGRAPH
+0xD9C0	0x502E	#CJK UNIFIED IDEOGRAPH
+0xD9C1	0x502D	#CJK UNIFIED IDEOGRAPH
+0xD9C2	0x4FFE	#CJK UNIFIED IDEOGRAPH
+0xD9C3	0x501C	#CJK UNIFIED IDEOGRAPH
+0xD9C4	0x500C	#CJK UNIFIED IDEOGRAPH
+0xD9C5	0x5025	#CJK UNIFIED IDEOGRAPH
+0xD9C6	0x5028	#CJK UNIFIED IDEOGRAPH
+0xD9C7	0x507E	#CJK UNIFIED IDEOGRAPH
+0xD9C8	0x5043	#CJK UNIFIED IDEOGRAPH
+0xD9C9	0x5055	#CJK UNIFIED IDEOGRAPH
+0xD9CA	0x5048	#CJK UNIFIED IDEOGRAPH
+0xD9CB	0x504E	#CJK UNIFIED IDEOGRAPH
+0xD9CC	0x506C	#CJK UNIFIED IDEOGRAPH
+0xD9CD	0x507B	#CJK UNIFIED IDEOGRAPH
+0xD9CE	0x50A5	#CJK UNIFIED IDEOGRAPH
+0xD9CF	0x50A7	#CJK UNIFIED IDEOGRAPH
+0xD9D0	0x50A9	#CJK UNIFIED IDEOGRAPH
+0xD9D1	0x50BA	#CJK UNIFIED IDEOGRAPH
+0xD9D2	0x50D6	#CJK UNIFIED IDEOGRAPH
+0xD9D3	0x5106	#CJK UNIFIED IDEOGRAPH
+0xD9D4	0x50ED	#CJK UNIFIED IDEOGRAPH
+0xD9D5	0x50EC	#CJK UNIFIED IDEOGRAPH
+0xD9D6	0x50E6	#CJK UNIFIED IDEOGRAPH
+0xD9D7	0x50EE	#CJK UNIFIED IDEOGRAPH
+0xD9D8	0x5107	#CJK UNIFIED IDEOGRAPH
+0xD9D9	0x510B	#CJK UNIFIED IDEOGRAPH
+0xD9DA	0x4EDD	#CJK UNIFIED IDEOGRAPH
+0xD9DB	0x6C3D	#CJK UNIFIED IDEOGRAPH
+0xD9DC	0x4F58	#CJK UNIFIED IDEOGRAPH
+0xD9DD	0x4F65	#CJK UNIFIED IDEOGRAPH
+0xD9DE	0x4FCE	#CJK UNIFIED IDEOGRAPH
+0xD9DF	0x9FA0	#CJK UNIFIED IDEOGRAPH
+0xD9E0	0x6C46	#CJK UNIFIED IDEOGRAPH
+0xD9E1	0x7C74	#CJK UNIFIED IDEOGRAPH
+0xD9E2	0x516E	#CJK UNIFIED IDEOGRAPH
+0xD9E3	0x5DFD	#CJK UNIFIED IDEOGRAPH
+0xD9E4	0x9EC9	#CJK UNIFIED IDEOGRAPH
+0xD9E5	0x9998	#CJK UNIFIED IDEOGRAPH
+0xD9E6	0x5181	#CJK UNIFIED IDEOGRAPH
+0xD9E7	0x5914	#CJK UNIFIED IDEOGRAPH
+0xD9E8	0x52F9	#CJK UNIFIED IDEOGRAPH
+0xD9E9	0x530D	#CJK UNIFIED IDEOGRAPH
+0xD9EA	0x8A07	#CJK UNIFIED IDEOGRAPH
+0xD9EB	0x5310	#CJK UNIFIED IDEOGRAPH
+0xD9EC	0x51EB	#CJK UNIFIED IDEOGRAPH
+0xD9ED	0x5919	#CJK UNIFIED IDEOGRAPH
+0xD9EE	0x5155	#CJK UNIFIED IDEOGRAPH
+0xD9EF	0x4EA0	#CJK UNIFIED IDEOGRAPH
+0xD9F0	0x5156	#CJK UNIFIED IDEOGRAPH
+0xD9F1	0x4EB3	#CJK UNIFIED IDEOGRAPH
+0xD9F2	0x886E	#CJK UNIFIED IDEOGRAPH
+0xD9F3	0x88A4	#CJK UNIFIED IDEOGRAPH
+0xD9F4	0x4EB5	#CJK UNIFIED IDEOGRAPH
+0xD9F5	0x8114	#CJK UNIFIED IDEOGRAPH
+0xD9F6	0x88D2	#CJK UNIFIED IDEOGRAPH
+0xD9F7	0x7980	#CJK UNIFIED IDEOGRAPH
+0xD9F8	0x5B34	#CJK UNIFIED IDEOGRAPH
+0xD9F9	0x8803	#CJK UNIFIED IDEOGRAPH
+0xD9FA	0x7FB8	#CJK UNIFIED IDEOGRAPH
+0xD9FB	0x51AB	#CJK UNIFIED IDEOGRAPH
+0xD9FC	0x51B1	#CJK UNIFIED IDEOGRAPH
+0xD9FD	0x51BD	#CJK UNIFIED IDEOGRAPH
+0xD9FE	0x51BC	#CJK UNIFIED IDEOGRAPH
+0xDA40	0x8D0E	#CJK UNIFIED IDEOGRAPH
+0xDA41	0x8D0F	#CJK UNIFIED IDEOGRAPH
+0xDA42	0x8D10	#CJK UNIFIED IDEOGRAPH
+0xDA43	0x8D11	#CJK UNIFIED IDEOGRAPH
+0xDA44	0x8D12	#CJK UNIFIED IDEOGRAPH
+0xDA45	0x8D13	#CJK UNIFIED IDEOGRAPH
+0xDA46	0x8D14	#CJK UNIFIED IDEOGRAPH
+0xDA47	0x8D15	#CJK UNIFIED IDEOGRAPH
+0xDA48	0x8D16	#CJK UNIFIED IDEOGRAPH
+0xDA49	0x8D17	#CJK UNIFIED IDEOGRAPH
+0xDA4A	0x8D18	#CJK UNIFIED IDEOGRAPH
+0xDA4B	0x8D19	#CJK UNIFIED IDEOGRAPH
+0xDA4C	0x8D1A	#CJK UNIFIED IDEOGRAPH
+0xDA4D	0x8D1B	#CJK UNIFIED IDEOGRAPH
+0xDA4E	0x8D1C	#CJK UNIFIED IDEOGRAPH
+0xDA4F	0x8D20	#CJK UNIFIED IDEOGRAPH
+0xDA50	0x8D51	#CJK UNIFIED IDEOGRAPH
+0xDA51	0x8D52	#CJK UNIFIED IDEOGRAPH
+0xDA52	0x8D57	#CJK UNIFIED IDEOGRAPH
+0xDA53	0x8D5F	#CJK UNIFIED IDEOGRAPH
+0xDA54	0x8D65	#CJK UNIFIED IDEOGRAPH
+0xDA55	0x8D68	#CJK UNIFIED IDEOGRAPH
+0xDA56	0x8D69	#CJK UNIFIED IDEOGRAPH
+0xDA57	0x8D6A	#CJK UNIFIED IDEOGRAPH
+0xDA58	0x8D6C	#CJK UNIFIED IDEOGRAPH
+0xDA59	0x8D6E	#CJK UNIFIED IDEOGRAPH
+0xDA5A	0x8D6F	#CJK UNIFIED IDEOGRAPH
+0xDA5B	0x8D71	#CJK UNIFIED IDEOGRAPH
+0xDA5C	0x8D72	#CJK UNIFIED IDEOGRAPH
+0xDA5D	0x8D78	#CJK UNIFIED IDEOGRAPH
+0xDA5E	0x8D79	#CJK UNIFIED IDEOGRAPH
+0xDA5F	0x8D7A	#CJK UNIFIED IDEOGRAPH
+0xDA60	0x8D7B	#CJK UNIFIED IDEOGRAPH
+0xDA61	0x8D7C	#CJK UNIFIED IDEOGRAPH
+0xDA62	0x8D7D	#CJK UNIFIED IDEOGRAPH
+0xDA63	0x8D7E	#CJK UNIFIED IDEOGRAPH
+0xDA64	0x8D7F	#CJK UNIFIED IDEOGRAPH
+0xDA65	0x8D80	#CJK UNIFIED IDEOGRAPH
+0xDA66	0x8D82	#CJK UNIFIED IDEOGRAPH
+0xDA67	0x8D83	#CJK UNIFIED IDEOGRAPH
+0xDA68	0x8D86	#CJK UNIFIED IDEOGRAPH
+0xDA69	0x8D87	#CJK UNIFIED IDEOGRAPH
+0xDA6A	0x8D88	#CJK UNIFIED IDEOGRAPH
+0xDA6B	0x8D89	#CJK UNIFIED IDEOGRAPH
+0xDA6C	0x8D8C	#CJK UNIFIED IDEOGRAPH
+0xDA6D	0x8D8D	#CJK UNIFIED IDEOGRAPH
+0xDA6E	0x8D8E	#CJK UNIFIED IDEOGRAPH
+0xDA6F	0x8D8F	#CJK UNIFIED IDEOGRAPH
+0xDA70	0x8D90	#CJK UNIFIED IDEOGRAPH
+0xDA71	0x8D92	#CJK UNIFIED IDEOGRAPH
+0xDA72	0x8D93	#CJK UNIFIED IDEOGRAPH
+0xDA73	0x8D95	#CJK UNIFIED IDEOGRAPH
+0xDA74	0x8D96	#CJK UNIFIED IDEOGRAPH
+0xDA75	0x8D97	#CJK UNIFIED IDEOGRAPH
+0xDA76	0x8D98	#CJK UNIFIED IDEOGRAPH
+0xDA77	0x8D99	#CJK UNIFIED IDEOGRAPH
+0xDA78	0x8D9A	#CJK UNIFIED IDEOGRAPH
+0xDA79	0x8D9B	#CJK UNIFIED IDEOGRAPH
+0xDA7A	0x8D9C	#CJK UNIFIED IDEOGRAPH
+0xDA7B	0x8D9D	#CJK UNIFIED IDEOGRAPH
+0xDA7C	0x8D9E	#CJK UNIFIED IDEOGRAPH
+0xDA7D	0x8DA0	#CJK UNIFIED IDEOGRAPH
+0xDA7E	0x8DA1	#CJK UNIFIED IDEOGRAPH
+0xDA80	0x8DA2	#CJK UNIFIED IDEOGRAPH
+0xDA81	0x8DA4	#CJK UNIFIED IDEOGRAPH
+0xDA82	0x8DA5	#CJK UNIFIED IDEOGRAPH
+0xDA83	0x8DA6	#CJK UNIFIED IDEOGRAPH
+0xDA84	0x8DA7	#CJK UNIFIED IDEOGRAPH
+0xDA85	0x8DA8	#CJK UNIFIED IDEOGRAPH
+0xDA86	0x8DA9	#CJK UNIFIED IDEOGRAPH
+0xDA87	0x8DAA	#CJK UNIFIED IDEOGRAPH
+0xDA88	0x8DAB	#CJK UNIFIED IDEOGRAPH
+0xDA89	0x8DAC	#CJK UNIFIED IDEOGRAPH
+0xDA8A	0x8DAD	#CJK UNIFIED IDEOGRAPH
+0xDA8B	0x8DAE	#CJK UNIFIED IDEOGRAPH
+0xDA8C	0x8DAF	#CJK UNIFIED IDEOGRAPH
+0xDA8D	0x8DB0	#CJK UNIFIED IDEOGRAPH
+0xDA8E	0x8DB2	#CJK UNIFIED IDEOGRAPH
+0xDA8F	0x8DB6	#CJK UNIFIED IDEOGRAPH
+0xDA90	0x8DB7	#CJK UNIFIED IDEOGRAPH
+0xDA91	0x8DB9	#CJK UNIFIED IDEOGRAPH
+0xDA92	0x8DBB	#CJK UNIFIED IDEOGRAPH
+0xDA93	0x8DBD	#CJK UNIFIED IDEOGRAPH
+0xDA94	0x8DC0	#CJK UNIFIED IDEOGRAPH
+0xDA95	0x8DC1	#CJK UNIFIED IDEOGRAPH
+0xDA96	0x8DC2	#CJK UNIFIED IDEOGRAPH
+0xDA97	0x8DC5	#CJK UNIFIED IDEOGRAPH
+0xDA98	0x8DC7	#CJK UNIFIED IDEOGRAPH
+0xDA99	0x8DC8	#CJK UNIFIED IDEOGRAPH
+0xDA9A	0x8DC9	#CJK UNIFIED IDEOGRAPH
+0xDA9B	0x8DCA	#CJK UNIFIED IDEOGRAPH
+0xDA9C	0x8DCD	#CJK UNIFIED IDEOGRAPH
+0xDA9D	0x8DD0	#CJK UNIFIED IDEOGRAPH
+0xDA9E	0x8DD2	#CJK UNIFIED IDEOGRAPH
+0xDA9F	0x8DD3	#CJK UNIFIED IDEOGRAPH
+0xDAA0	0x8DD4	#CJK UNIFIED IDEOGRAPH
+0xDAA1	0x51C7	#CJK UNIFIED IDEOGRAPH
+0xDAA2	0x5196	#CJK UNIFIED IDEOGRAPH
+0xDAA3	0x51A2	#CJK UNIFIED IDEOGRAPH
+0xDAA4	0x51A5	#CJK UNIFIED IDEOGRAPH
+0xDAA5	0x8BA0	#CJK UNIFIED IDEOGRAPH
+0xDAA6	0x8BA6	#CJK UNIFIED IDEOGRAPH
+0xDAA7	0x8BA7	#CJK UNIFIED IDEOGRAPH
+0xDAA8	0x8BAA	#CJK UNIFIED IDEOGRAPH
+0xDAA9	0x8BB4	#CJK UNIFIED IDEOGRAPH
+0xDAAA	0x8BB5	#CJK UNIFIED IDEOGRAPH
+0xDAAB	0x8BB7	#CJK UNIFIED IDEOGRAPH
+0xDAAC	0x8BC2	#CJK UNIFIED IDEOGRAPH
+0xDAAD	0x8BC3	#CJK UNIFIED IDEOGRAPH
+0xDAAE	0x8BCB	#CJK UNIFIED IDEOGRAPH
+0xDAAF	0x8BCF	#CJK UNIFIED IDEOGRAPH
+0xDAB0	0x8BCE	#CJK UNIFIED IDEOGRAPH
+0xDAB1	0x8BD2	#CJK UNIFIED IDEOGRAPH
+0xDAB2	0x8BD3	#CJK UNIFIED IDEOGRAPH
+0xDAB3	0x8BD4	#CJK UNIFIED IDEOGRAPH
+0xDAB4	0x8BD6	#CJK UNIFIED IDEOGRAPH
+0xDAB5	0x8BD8	#CJK UNIFIED IDEOGRAPH
+0xDAB6	0x8BD9	#CJK UNIFIED IDEOGRAPH
+0xDAB7	0x8BDC	#CJK UNIFIED IDEOGRAPH
+0xDAB8	0x8BDF	#CJK UNIFIED IDEOGRAPH
+0xDAB9	0x8BE0	#CJK UNIFIED IDEOGRAPH
+0xDABA	0x8BE4	#CJK UNIFIED IDEOGRAPH
+0xDABB	0x8BE8	#CJK UNIFIED IDEOGRAPH
+0xDABC	0x8BE9	#CJK UNIFIED IDEOGRAPH
+0xDABD	0x8BEE	#CJK UNIFIED IDEOGRAPH
+0xDABE	0x8BF0	#CJK UNIFIED IDEOGRAPH
+0xDABF	0x8BF3	#CJK UNIFIED IDEOGRAPH
+0xDAC0	0x8BF6	#CJK UNIFIED IDEOGRAPH
+0xDAC1	0x8BF9	#CJK UNIFIED IDEOGRAPH
+0xDAC2	0x8BFC	#CJK UNIFIED IDEOGRAPH
+0xDAC3	0x8BFF	#CJK UNIFIED IDEOGRAPH
+0xDAC4	0x8C00	#CJK UNIFIED IDEOGRAPH
+0xDAC5	0x8C02	#CJK UNIFIED IDEOGRAPH
+0xDAC6	0x8C04	#CJK UNIFIED IDEOGRAPH
+0xDAC7	0x8C07	#CJK UNIFIED IDEOGRAPH
+0xDAC8	0x8C0C	#CJK UNIFIED IDEOGRAPH
+0xDAC9	0x8C0F	#CJK UNIFIED IDEOGRAPH
+0xDACA	0x8C11	#CJK UNIFIED IDEOGRAPH
+0xDACB	0x8C12	#CJK UNIFIED IDEOGRAPH
+0xDACC	0x8C14	#CJK UNIFIED IDEOGRAPH
+0xDACD	0x8C15	#CJK UNIFIED IDEOGRAPH
+0xDACE	0x8C16	#CJK UNIFIED IDEOGRAPH
+0xDACF	0x8C19	#CJK UNIFIED IDEOGRAPH
+0xDAD0	0x8C1B	#CJK UNIFIED IDEOGRAPH
+0xDAD1	0x8C18	#CJK UNIFIED IDEOGRAPH
+0xDAD2	0x8C1D	#CJK UNIFIED IDEOGRAPH
+0xDAD3	0x8C1F	#CJK UNIFIED IDEOGRAPH
+0xDAD4	0x8C20	#CJK UNIFIED IDEOGRAPH
+0xDAD5	0x8C21	#CJK UNIFIED IDEOGRAPH
+0xDAD6	0x8C25	#CJK UNIFIED IDEOGRAPH
+0xDAD7	0x8C27	#CJK UNIFIED IDEOGRAPH
+0xDAD8	0x8C2A	#CJK UNIFIED IDEOGRAPH
+0xDAD9	0x8C2B	#CJK UNIFIED IDEOGRAPH
+0xDADA	0x8C2E	#CJK UNIFIED IDEOGRAPH
+0xDADB	0x8C2F	#CJK UNIFIED IDEOGRAPH
+0xDADC	0x8C32	#CJK UNIFIED IDEOGRAPH
+0xDADD	0x8C33	#CJK UNIFIED IDEOGRAPH
+0xDADE	0x8C35	#CJK UNIFIED IDEOGRAPH
+0xDADF	0x8C36	#CJK UNIFIED IDEOGRAPH
+0xDAE0	0x5369	#CJK UNIFIED IDEOGRAPH
+0xDAE1	0x537A	#CJK UNIFIED IDEOGRAPH
+0xDAE2	0x961D	#CJK UNIFIED IDEOGRAPH
+0xDAE3	0x9622	#CJK UNIFIED IDEOGRAPH
+0xDAE4	0x9621	#CJK UNIFIED IDEOGRAPH
+0xDAE5	0x9631	#CJK UNIFIED IDEOGRAPH
+0xDAE6	0x962A	#CJK UNIFIED IDEOGRAPH
+0xDAE7	0x963D	#CJK UNIFIED IDEOGRAPH
+0xDAE8	0x963C	#CJK UNIFIED IDEOGRAPH
+0xDAE9	0x9642	#CJK UNIFIED IDEOGRAPH
+0xDAEA	0x9649	#CJK UNIFIED IDEOGRAPH
+0xDAEB	0x9654	#CJK UNIFIED IDEOGRAPH
+0xDAEC	0x965F	#CJK UNIFIED IDEOGRAPH
+0xDAED	0x9667	#CJK UNIFIED IDEOGRAPH
+0xDAEE	0x966C	#CJK UNIFIED IDEOGRAPH
+0xDAEF	0x9672	#CJK UNIFIED IDEOGRAPH
+0xDAF0	0x9674	#CJK UNIFIED IDEOGRAPH
+0xDAF1	0x9688	#CJK UNIFIED IDEOGRAPH
+0xDAF2	0x968D	#CJK UNIFIED IDEOGRAPH
+0xDAF3	0x9697	#CJK UNIFIED IDEOGRAPH
+0xDAF4	0x96B0	#CJK UNIFIED IDEOGRAPH
+0xDAF5	0x9097	#CJK UNIFIED IDEOGRAPH
+0xDAF6	0x909B	#CJK UNIFIED IDEOGRAPH
+0xDAF7	0x909D	#CJK UNIFIED IDEOGRAPH
+0xDAF8	0x9099	#CJK UNIFIED IDEOGRAPH
+0xDAF9	0x90AC	#CJK UNIFIED IDEOGRAPH
+0xDAFA	0x90A1	#CJK UNIFIED IDEOGRAPH
+0xDAFB	0x90B4	#CJK UNIFIED IDEOGRAPH
+0xDAFC	0x90B3	#CJK UNIFIED IDEOGRAPH
+0xDAFD	0x90B6	#CJK UNIFIED IDEOGRAPH
+0xDAFE	0x90BA	#CJK UNIFIED IDEOGRAPH
+0xDB40	0x8DD5	#CJK UNIFIED IDEOGRAPH
+0xDB41	0x8DD8	#CJK UNIFIED IDEOGRAPH
+0xDB42	0x8DD9	#CJK UNIFIED IDEOGRAPH
+0xDB43	0x8DDC	#CJK UNIFIED IDEOGRAPH
+0xDB44	0x8DE0	#CJK UNIFIED IDEOGRAPH
+0xDB45	0x8DE1	#CJK UNIFIED IDEOGRAPH
+0xDB46	0x8DE2	#CJK UNIFIED IDEOGRAPH
+0xDB47	0x8DE5	#CJK UNIFIED IDEOGRAPH
+0xDB48	0x8DE6	#CJK UNIFIED IDEOGRAPH
+0xDB49	0x8DE7	#CJK UNIFIED IDEOGRAPH
+0xDB4A	0x8DE9	#CJK UNIFIED IDEOGRAPH
+0xDB4B	0x8DED	#CJK UNIFIED IDEOGRAPH
+0xDB4C	0x8DEE	#CJK UNIFIED IDEOGRAPH
+0xDB4D	0x8DF0	#CJK UNIFIED IDEOGRAPH
+0xDB4E	0x8DF1	#CJK UNIFIED IDEOGRAPH
+0xDB4F	0x8DF2	#CJK UNIFIED IDEOGRAPH
+0xDB50	0x8DF4	#CJK UNIFIED IDEOGRAPH
+0xDB51	0x8DF6	#CJK UNIFIED IDEOGRAPH
+0xDB52	0x8DFC	#CJK UNIFIED IDEOGRAPH
+0xDB53	0x8DFE	#CJK UNIFIED IDEOGRAPH
+0xDB54	0x8DFF	#CJK UNIFIED IDEOGRAPH
+0xDB55	0x8E00	#CJK UNIFIED IDEOGRAPH
+0xDB56	0x8E01	#CJK UNIFIED IDEOGRAPH
+0xDB57	0x8E02	#CJK UNIFIED IDEOGRAPH
+0xDB58	0x8E03	#CJK UNIFIED IDEOGRAPH
+0xDB59	0x8E04	#CJK UNIFIED IDEOGRAPH
+0xDB5A	0x8E06	#CJK UNIFIED IDEOGRAPH
+0xDB5B	0x8E07	#CJK UNIFIED IDEOGRAPH
+0xDB5C	0x8E08	#CJK UNIFIED IDEOGRAPH
+0xDB5D	0x8E0B	#CJK UNIFIED IDEOGRAPH
+0xDB5E	0x8E0D	#CJK UNIFIED IDEOGRAPH
+0xDB5F	0x8E0E	#CJK UNIFIED IDEOGRAPH
+0xDB60	0x8E10	#CJK UNIFIED IDEOGRAPH
+0xDB61	0x8E11	#CJK UNIFIED IDEOGRAPH
+0xDB62	0x8E12	#CJK UNIFIED IDEOGRAPH
+0xDB63	0x8E13	#CJK UNIFIED IDEOGRAPH
+0xDB64	0x8E15	#CJK UNIFIED IDEOGRAPH
+0xDB65	0x8E16	#CJK UNIFIED IDEOGRAPH
+0xDB66	0x8E17	#CJK UNIFIED IDEOGRAPH
+0xDB67	0x8E18	#CJK UNIFIED IDEOGRAPH
+0xDB68	0x8E19	#CJK UNIFIED IDEOGRAPH
+0xDB69	0x8E1A	#CJK UNIFIED IDEOGRAPH
+0xDB6A	0x8E1B	#CJK UNIFIED IDEOGRAPH
+0xDB6B	0x8E1C	#CJK UNIFIED IDEOGRAPH
+0xDB6C	0x8E20	#CJK UNIFIED IDEOGRAPH
+0xDB6D	0x8E21	#CJK UNIFIED IDEOGRAPH
+0xDB6E	0x8E24	#CJK UNIFIED IDEOGRAPH
+0xDB6F	0x8E25	#CJK UNIFIED IDEOGRAPH
+0xDB70	0x8E26	#CJK UNIFIED IDEOGRAPH
+0xDB71	0x8E27	#CJK UNIFIED IDEOGRAPH
+0xDB72	0x8E28	#CJK UNIFIED IDEOGRAPH
+0xDB73	0x8E2B	#CJK UNIFIED IDEOGRAPH
+0xDB74	0x8E2D	#CJK UNIFIED IDEOGRAPH
+0xDB75	0x8E30	#CJK UNIFIED IDEOGRAPH
+0xDB76	0x8E32	#CJK UNIFIED IDEOGRAPH
+0xDB77	0x8E33	#CJK UNIFIED IDEOGRAPH
+0xDB78	0x8E34	#CJK UNIFIED IDEOGRAPH
+0xDB79	0x8E36	#CJK UNIFIED IDEOGRAPH
+0xDB7A	0x8E37	#CJK UNIFIED IDEOGRAPH
+0xDB7B	0x8E38	#CJK UNIFIED IDEOGRAPH
+0xDB7C	0x8E3B	#CJK UNIFIED IDEOGRAPH
+0xDB7D	0x8E3C	#CJK UNIFIED IDEOGRAPH
+0xDB7E	0x8E3E	#CJK UNIFIED IDEOGRAPH
+0xDB80	0x8E3F	#CJK UNIFIED IDEOGRAPH
+0xDB81	0x8E43	#CJK UNIFIED IDEOGRAPH
+0xDB82	0x8E45	#CJK UNIFIED IDEOGRAPH
+0xDB83	0x8E46	#CJK UNIFIED IDEOGRAPH
+0xDB84	0x8E4C	#CJK UNIFIED IDEOGRAPH
+0xDB85	0x8E4D	#CJK UNIFIED IDEOGRAPH
+0xDB86	0x8E4E	#CJK UNIFIED IDEOGRAPH
+0xDB87	0x8E4F	#CJK UNIFIED IDEOGRAPH
+0xDB88	0x8E50	#CJK UNIFIED IDEOGRAPH
+0xDB89	0x8E53	#CJK UNIFIED IDEOGRAPH
+0xDB8A	0x8E54	#CJK UNIFIED IDEOGRAPH
+0xDB8B	0x8E55	#CJK UNIFIED IDEOGRAPH
+0xDB8C	0x8E56	#CJK UNIFIED IDEOGRAPH
+0xDB8D	0x8E57	#CJK UNIFIED IDEOGRAPH
+0xDB8E	0x8E58	#CJK UNIFIED IDEOGRAPH
+0xDB8F	0x8E5A	#CJK UNIFIED IDEOGRAPH
+0xDB90	0x8E5B	#CJK UNIFIED IDEOGRAPH
+0xDB91	0x8E5C	#CJK UNIFIED IDEOGRAPH
+0xDB92	0x8E5D	#CJK UNIFIED IDEOGRAPH
+0xDB93	0x8E5E	#CJK UNIFIED IDEOGRAPH
+0xDB94	0x8E5F	#CJK UNIFIED IDEOGRAPH
+0xDB95	0x8E60	#CJK UNIFIED IDEOGRAPH
+0xDB96	0x8E61	#CJK UNIFIED IDEOGRAPH
+0xDB97	0x8E62	#CJK UNIFIED IDEOGRAPH
+0xDB98	0x8E63	#CJK UNIFIED IDEOGRAPH
+0xDB99	0x8E64	#CJK UNIFIED IDEOGRAPH
+0xDB9A	0x8E65	#CJK UNIFIED IDEOGRAPH
+0xDB9B	0x8E67	#CJK UNIFIED IDEOGRAPH
+0xDB9C	0x8E68	#CJK UNIFIED IDEOGRAPH
+0xDB9D	0x8E6A	#CJK UNIFIED IDEOGRAPH
+0xDB9E	0x8E6B	#CJK UNIFIED IDEOGRAPH
+0xDB9F	0x8E6E	#CJK UNIFIED IDEOGRAPH
+0xDBA0	0x8E71	#CJK UNIFIED IDEOGRAPH
+0xDBA1	0x90B8	#CJK UNIFIED IDEOGRAPH
+0xDBA2	0x90B0	#CJK UNIFIED IDEOGRAPH
+0xDBA3	0x90CF	#CJK UNIFIED IDEOGRAPH
+0xDBA4	0x90C5	#CJK UNIFIED IDEOGRAPH
+0xDBA5	0x90BE	#CJK UNIFIED IDEOGRAPH
+0xDBA6	0x90D0	#CJK UNIFIED IDEOGRAPH
+0xDBA7	0x90C4	#CJK UNIFIED IDEOGRAPH
+0xDBA8	0x90C7	#CJK UNIFIED IDEOGRAPH
+0xDBA9	0x90D3	#CJK UNIFIED IDEOGRAPH
+0xDBAA	0x90E6	#CJK UNIFIED IDEOGRAPH
+0xDBAB	0x90E2	#CJK UNIFIED IDEOGRAPH
+0xDBAC	0x90DC	#CJK UNIFIED IDEOGRAPH
+0xDBAD	0x90D7	#CJK UNIFIED IDEOGRAPH
+0xDBAE	0x90DB	#CJK UNIFIED IDEOGRAPH
+0xDBAF	0x90EB	#CJK UNIFIED IDEOGRAPH
+0xDBB0	0x90EF	#CJK UNIFIED IDEOGRAPH
+0xDBB1	0x90FE	#CJK UNIFIED IDEOGRAPH
+0xDBB2	0x9104	#CJK UNIFIED IDEOGRAPH
+0xDBB3	0x9122	#CJK UNIFIED IDEOGRAPH
+0xDBB4	0x911E	#CJK UNIFIED IDEOGRAPH
+0xDBB5	0x9123	#CJK UNIFIED IDEOGRAPH
+0xDBB6	0x9131	#CJK UNIFIED IDEOGRAPH
+0xDBB7	0x912F	#CJK UNIFIED IDEOGRAPH
+0xDBB8	0x9139	#CJK UNIFIED IDEOGRAPH
+0xDBB9	0x9143	#CJK UNIFIED IDEOGRAPH
+0xDBBA	0x9146	#CJK UNIFIED IDEOGRAPH
+0xDBBB	0x520D	#CJK UNIFIED IDEOGRAPH
+0xDBBC	0x5942	#CJK UNIFIED IDEOGRAPH
+0xDBBD	0x52A2	#CJK UNIFIED IDEOGRAPH
+0xDBBE	0x52AC	#CJK UNIFIED IDEOGRAPH
+0xDBBF	0x52AD	#CJK UNIFIED IDEOGRAPH
+0xDBC0	0x52BE	#CJK UNIFIED IDEOGRAPH
+0xDBC1	0x54FF	#CJK UNIFIED IDEOGRAPH
+0xDBC2	0x52D0	#CJK UNIFIED IDEOGRAPH
+0xDBC3	0x52D6	#CJK UNIFIED IDEOGRAPH
+0xDBC4	0x52F0	#CJK UNIFIED IDEOGRAPH
+0xDBC5	0x53DF	#CJK UNIFIED IDEOGRAPH
+0xDBC6	0x71EE	#CJK UNIFIED IDEOGRAPH
+0xDBC7	0x77CD	#CJK UNIFIED IDEOGRAPH
+0xDBC8	0x5EF4	#CJK UNIFIED IDEOGRAPH
+0xDBC9	0x51F5	#CJK UNIFIED IDEOGRAPH
+0xDBCA	0x51FC	#CJK UNIFIED IDEOGRAPH
+0xDBCB	0x9B2F	#CJK UNIFIED IDEOGRAPH
+0xDBCC	0x53B6	#CJK UNIFIED IDEOGRAPH
+0xDBCD	0x5F01	#CJK UNIFIED IDEOGRAPH
+0xDBCE	0x755A	#CJK UNIFIED IDEOGRAPH
+0xDBCF	0x5DEF	#CJK UNIFIED IDEOGRAPH
+0xDBD0	0x574C	#CJK UNIFIED IDEOGRAPH
+0xDBD1	0x57A9	#CJK UNIFIED IDEOGRAPH
+0xDBD2	0x57A1	#CJK UNIFIED IDEOGRAPH
+0xDBD3	0x587E	#CJK UNIFIED IDEOGRAPH
+0xDBD4	0x58BC	#CJK UNIFIED IDEOGRAPH
+0xDBD5	0x58C5	#CJK UNIFIED IDEOGRAPH
+0xDBD6	0x58D1	#CJK UNIFIED IDEOGRAPH
+0xDBD7	0x5729	#CJK UNIFIED IDEOGRAPH
+0xDBD8	0x572C	#CJK UNIFIED IDEOGRAPH
+0xDBD9	0x572A	#CJK UNIFIED IDEOGRAPH
+0xDBDA	0x5733	#CJK UNIFIED IDEOGRAPH
+0xDBDB	0x5739	#CJK UNIFIED IDEOGRAPH
+0xDBDC	0x572E	#CJK UNIFIED IDEOGRAPH
+0xDBDD	0x572F	#CJK UNIFIED IDEOGRAPH
+0xDBDE	0x575C	#CJK UNIFIED IDEOGRAPH
+0xDBDF	0x573B	#CJK UNIFIED IDEOGRAPH
+0xDBE0	0x5742	#CJK UNIFIED IDEOGRAPH
+0xDBE1	0x5769	#CJK UNIFIED IDEOGRAPH
+0xDBE2	0x5785	#CJK UNIFIED IDEOGRAPH
+0xDBE3	0x576B	#CJK UNIFIED IDEOGRAPH
+0xDBE4	0x5786	#CJK UNIFIED IDEOGRAPH
+0xDBE5	0x577C	#CJK UNIFIED IDEOGRAPH
+0xDBE6	0x577B	#CJK UNIFIED IDEOGRAPH
+0xDBE7	0x5768	#CJK UNIFIED IDEOGRAPH
+0xDBE8	0x576D	#CJK UNIFIED IDEOGRAPH
+0xDBE9	0x5776	#CJK UNIFIED IDEOGRAPH
+0xDBEA	0x5773	#CJK UNIFIED IDEOGRAPH
+0xDBEB	0x57AD	#CJK UNIFIED IDEOGRAPH
+0xDBEC	0x57A4	#CJK UNIFIED IDEOGRAPH
+0xDBED	0x578C	#CJK UNIFIED IDEOGRAPH
+0xDBEE	0x57B2	#CJK UNIFIED IDEOGRAPH
+0xDBEF	0x57CF	#CJK UNIFIED IDEOGRAPH
+0xDBF0	0x57A7	#CJK UNIFIED IDEOGRAPH
+0xDBF1	0x57B4	#CJK UNIFIED IDEOGRAPH
+0xDBF2	0x5793	#CJK UNIFIED IDEOGRAPH
+0xDBF3	0x57A0	#CJK UNIFIED IDEOGRAPH
+0xDBF4	0x57D5	#CJK UNIFIED IDEOGRAPH
+0xDBF5	0x57D8	#CJK UNIFIED IDEOGRAPH
+0xDBF6	0x57DA	#CJK UNIFIED IDEOGRAPH
+0xDBF7	0x57D9	#CJK UNIFIED IDEOGRAPH
+0xDBF8	0x57D2	#CJK UNIFIED IDEOGRAPH
+0xDBF9	0x57B8	#CJK UNIFIED IDEOGRAPH
+0xDBFA	0x57F4	#CJK UNIFIED IDEOGRAPH
+0xDBFB	0x57EF	#CJK UNIFIED IDEOGRAPH
+0xDBFC	0x57F8	#CJK UNIFIED IDEOGRAPH
+0xDBFD	0x57E4	#CJK UNIFIED IDEOGRAPH
+0xDBFE	0x57DD	#CJK UNIFIED IDEOGRAPH
+0xDC40	0x8E73	#CJK UNIFIED IDEOGRAPH
+0xDC41	0x8E75	#CJK UNIFIED IDEOGRAPH
+0xDC42	0x8E77	#CJK UNIFIED IDEOGRAPH
+0xDC43	0x8E78	#CJK UNIFIED IDEOGRAPH
+0xDC44	0x8E79	#CJK UNIFIED IDEOGRAPH
+0xDC45	0x8E7A	#CJK UNIFIED IDEOGRAPH
+0xDC46	0x8E7B	#CJK UNIFIED IDEOGRAPH
+0xDC47	0x8E7D	#CJK UNIFIED IDEOGRAPH
+0xDC48	0x8E7E	#CJK UNIFIED IDEOGRAPH
+0xDC49	0x8E80	#CJK UNIFIED IDEOGRAPH
+0xDC4A	0x8E82	#CJK UNIFIED IDEOGRAPH
+0xDC4B	0x8E83	#CJK UNIFIED IDEOGRAPH
+0xDC4C	0x8E84	#CJK UNIFIED IDEOGRAPH
+0xDC4D	0x8E86	#CJK UNIFIED IDEOGRAPH
+0xDC4E	0x8E88	#CJK UNIFIED IDEOGRAPH
+0xDC4F	0x8E89	#CJK UNIFIED IDEOGRAPH
+0xDC50	0x8E8A	#CJK UNIFIED IDEOGRAPH
+0xDC51	0x8E8B	#CJK UNIFIED IDEOGRAPH
+0xDC52	0x8E8C	#CJK UNIFIED IDEOGRAPH
+0xDC53	0x8E8D	#CJK UNIFIED IDEOGRAPH
+0xDC54	0x8E8E	#CJK UNIFIED IDEOGRAPH
+0xDC55	0x8E91	#CJK UNIFIED IDEOGRAPH
+0xDC56	0x8E92	#CJK UNIFIED IDEOGRAPH
+0xDC57	0x8E93	#CJK UNIFIED IDEOGRAPH
+0xDC58	0x8E95	#CJK UNIFIED IDEOGRAPH
+0xDC59	0x8E96	#CJK UNIFIED IDEOGRAPH
+0xDC5A	0x8E97	#CJK UNIFIED IDEOGRAPH
+0xDC5B	0x8E98	#CJK UNIFIED IDEOGRAPH
+0xDC5C	0x8E99	#CJK UNIFIED IDEOGRAPH
+0xDC5D	0x8E9A	#CJK UNIFIED IDEOGRAPH
+0xDC5E	0x8E9B	#CJK UNIFIED IDEOGRAPH
+0xDC5F	0x8E9D	#CJK UNIFIED IDEOGRAPH
+0xDC60	0x8E9F	#CJK UNIFIED IDEOGRAPH
+0xDC61	0x8EA0	#CJK UNIFIED IDEOGRAPH
+0xDC62	0x8EA1	#CJK UNIFIED IDEOGRAPH
+0xDC63	0x8EA2	#CJK UNIFIED IDEOGRAPH
+0xDC64	0x8EA3	#CJK UNIFIED IDEOGRAPH
+0xDC65	0x8EA4	#CJK UNIFIED IDEOGRAPH
+0xDC66	0x8EA5	#CJK UNIFIED IDEOGRAPH
+0xDC67	0x8EA6	#CJK UNIFIED IDEOGRAPH
+0xDC68	0x8EA7	#CJK UNIFIED IDEOGRAPH
+0xDC69	0x8EA8	#CJK UNIFIED IDEOGRAPH
+0xDC6A	0x8EA9	#CJK UNIFIED IDEOGRAPH
+0xDC6B	0x8EAA	#CJK UNIFIED IDEOGRAPH
+0xDC6C	0x8EAD	#CJK UNIFIED IDEOGRAPH
+0xDC6D	0x8EAE	#CJK UNIFIED IDEOGRAPH
+0xDC6E	0x8EB0	#CJK UNIFIED IDEOGRAPH
+0xDC6F	0x8EB1	#CJK UNIFIED IDEOGRAPH
+0xDC70	0x8EB3	#CJK UNIFIED IDEOGRAPH
+0xDC71	0x8EB4	#CJK UNIFIED IDEOGRAPH
+0xDC72	0x8EB5	#CJK UNIFIED IDEOGRAPH
+0xDC73	0x8EB6	#CJK UNIFIED IDEOGRAPH
+0xDC74	0x8EB7	#CJK UNIFIED IDEOGRAPH
+0xDC75	0x8EB8	#CJK UNIFIED IDEOGRAPH
+0xDC76	0x8EB9	#CJK UNIFIED IDEOGRAPH
+0xDC77	0x8EBB	#CJK UNIFIED IDEOGRAPH
+0xDC78	0x8EBC	#CJK UNIFIED IDEOGRAPH
+0xDC79	0x8EBD	#CJK UNIFIED IDEOGRAPH
+0xDC7A	0x8EBE	#CJK UNIFIED IDEOGRAPH
+0xDC7B	0x8EBF	#CJK UNIFIED IDEOGRAPH
+0xDC7C	0x8EC0	#CJK UNIFIED IDEOGRAPH
+0xDC7D	0x8EC1	#CJK UNIFIED IDEOGRAPH
+0xDC7E	0x8EC2	#CJK UNIFIED IDEOGRAPH
+0xDC80	0x8EC3	#CJK UNIFIED IDEOGRAPH
+0xDC81	0x8EC4	#CJK UNIFIED IDEOGRAPH
+0xDC82	0x8EC5	#CJK UNIFIED IDEOGRAPH
+0xDC83	0x8EC6	#CJK UNIFIED IDEOGRAPH
+0xDC84	0x8EC7	#CJK UNIFIED IDEOGRAPH
+0xDC85	0x8EC8	#CJK UNIFIED IDEOGRAPH
+0xDC86	0x8EC9	#CJK UNIFIED IDEOGRAPH
+0xDC87	0x8ECA	#CJK UNIFIED IDEOGRAPH
+0xDC88	0x8ECB	#CJK UNIFIED IDEOGRAPH
+0xDC89	0x8ECC	#CJK UNIFIED IDEOGRAPH
+0xDC8A	0x8ECD	#CJK UNIFIED IDEOGRAPH
+0xDC8B	0x8ECF	#CJK UNIFIED IDEOGRAPH
+0xDC8C	0x8ED0	#CJK UNIFIED IDEOGRAPH
+0xDC8D	0x8ED1	#CJK UNIFIED IDEOGRAPH
+0xDC8E	0x8ED2	#CJK UNIFIED IDEOGRAPH
+0xDC8F	0x8ED3	#CJK UNIFIED IDEOGRAPH
+0xDC90	0x8ED4	#CJK UNIFIED IDEOGRAPH
+0xDC91	0x8ED5	#CJK UNIFIED IDEOGRAPH
+0xDC92	0x8ED6	#CJK UNIFIED IDEOGRAPH
+0xDC93	0x8ED7	#CJK UNIFIED IDEOGRAPH
+0xDC94	0x8ED8	#CJK UNIFIED IDEOGRAPH
+0xDC95	0x8ED9	#CJK UNIFIED IDEOGRAPH
+0xDC96	0x8EDA	#CJK UNIFIED IDEOGRAPH
+0xDC97	0x8EDB	#CJK UNIFIED IDEOGRAPH
+0xDC98	0x8EDC	#CJK UNIFIED IDEOGRAPH
+0xDC99	0x8EDD	#CJK UNIFIED IDEOGRAPH
+0xDC9A	0x8EDE	#CJK UNIFIED IDEOGRAPH
+0xDC9B	0x8EDF	#CJK UNIFIED IDEOGRAPH
+0xDC9C	0x8EE0	#CJK UNIFIED IDEOGRAPH
+0xDC9D	0x8EE1	#CJK UNIFIED IDEOGRAPH
+0xDC9E	0x8EE2	#CJK UNIFIED IDEOGRAPH
+0xDC9F	0x8EE3	#CJK UNIFIED IDEOGRAPH
+0xDCA0	0x8EE4	#CJK UNIFIED IDEOGRAPH
+0xDCA1	0x580B	#CJK UNIFIED IDEOGRAPH
+0xDCA2	0x580D	#CJK UNIFIED IDEOGRAPH
+0xDCA3	0x57FD	#CJK UNIFIED IDEOGRAPH
+0xDCA4	0x57ED	#CJK UNIFIED IDEOGRAPH
+0xDCA5	0x5800	#CJK UNIFIED IDEOGRAPH
+0xDCA6	0x581E	#CJK UNIFIED IDEOGRAPH
+0xDCA7	0x5819	#CJK UNIFIED IDEOGRAPH
+0xDCA8	0x5844	#CJK UNIFIED IDEOGRAPH
+0xDCA9	0x5820	#CJK UNIFIED IDEOGRAPH
+0xDCAA	0x5865	#CJK UNIFIED IDEOGRAPH
+0xDCAB	0x586C	#CJK UNIFIED IDEOGRAPH
+0xDCAC	0x5881	#CJK UNIFIED IDEOGRAPH
+0xDCAD	0x5889	#CJK UNIFIED IDEOGRAPH
+0xDCAE	0x589A	#CJK UNIFIED IDEOGRAPH
+0xDCAF	0x5880	#CJK UNIFIED IDEOGRAPH
+0xDCB0	0x99A8	#CJK UNIFIED IDEOGRAPH
+0xDCB1	0x9F19	#CJK UNIFIED IDEOGRAPH
+0xDCB2	0x61FF	#CJK UNIFIED IDEOGRAPH
+0xDCB3	0x8279	#CJK UNIFIED IDEOGRAPH
+0xDCB4	0x827D	#CJK UNIFIED IDEOGRAPH
+0xDCB5	0x827F	#CJK UNIFIED IDEOGRAPH
+0xDCB6	0x828F	#CJK UNIFIED IDEOGRAPH
+0xDCB7	0x828A	#CJK UNIFIED IDEOGRAPH
+0xDCB8	0x82A8	#CJK UNIFIED IDEOGRAPH
+0xDCB9	0x8284	#CJK UNIFIED IDEOGRAPH
+0xDCBA	0x828E	#CJK UNIFIED IDEOGRAPH
+0xDCBB	0x8291	#CJK UNIFIED IDEOGRAPH
+0xDCBC	0x8297	#CJK UNIFIED IDEOGRAPH
+0xDCBD	0x8299	#CJK UNIFIED IDEOGRAPH
+0xDCBE	0x82AB	#CJK UNIFIED IDEOGRAPH
+0xDCBF	0x82B8	#CJK UNIFIED IDEOGRAPH
+0xDCC0	0x82BE	#CJK UNIFIED IDEOGRAPH
+0xDCC1	0x82B0	#CJK UNIFIED IDEOGRAPH
+0xDCC2	0x82C8	#CJK UNIFIED IDEOGRAPH
+0xDCC3	0x82CA	#CJK UNIFIED IDEOGRAPH
+0xDCC4	0x82E3	#CJK UNIFIED IDEOGRAPH
+0xDCC5	0x8298	#CJK UNIFIED IDEOGRAPH
+0xDCC6	0x82B7	#CJK UNIFIED IDEOGRAPH
+0xDCC7	0x82AE	#CJK UNIFIED IDEOGRAPH
+0xDCC8	0x82CB	#CJK UNIFIED IDEOGRAPH
+0xDCC9	0x82CC	#CJK UNIFIED IDEOGRAPH
+0xDCCA	0x82C1	#CJK UNIFIED IDEOGRAPH
+0xDCCB	0x82A9	#CJK UNIFIED IDEOGRAPH
+0xDCCC	0x82B4	#CJK UNIFIED IDEOGRAPH
+0xDCCD	0x82A1	#CJK UNIFIED IDEOGRAPH
+0xDCCE	0x82AA	#CJK UNIFIED IDEOGRAPH
+0xDCCF	0x829F	#CJK UNIFIED IDEOGRAPH
+0xDCD0	0x82C4	#CJK UNIFIED IDEOGRAPH
+0xDCD1	0x82CE	#CJK UNIFIED IDEOGRAPH
+0xDCD2	0x82A4	#CJK UNIFIED IDEOGRAPH
+0xDCD3	0x82E1	#CJK UNIFIED IDEOGRAPH
+0xDCD4	0x8309	#CJK UNIFIED IDEOGRAPH
+0xDCD5	0x82F7	#CJK UNIFIED IDEOGRAPH
+0xDCD6	0x82E4	#CJK UNIFIED IDEOGRAPH
+0xDCD7	0x830F	#CJK UNIFIED IDEOGRAPH
+0xDCD8	0x8307	#CJK UNIFIED IDEOGRAPH
+0xDCD9	0x82DC	#CJK UNIFIED IDEOGRAPH
+0xDCDA	0x82F4	#CJK UNIFIED IDEOGRAPH
+0xDCDB	0x82D2	#CJK UNIFIED IDEOGRAPH
+0xDCDC	0x82D8	#CJK UNIFIED IDEOGRAPH
+0xDCDD	0x830C	#CJK UNIFIED IDEOGRAPH
+0xDCDE	0x82FB	#CJK UNIFIED IDEOGRAPH
+0xDCDF	0x82D3	#CJK UNIFIED IDEOGRAPH
+0xDCE0	0x8311	#CJK UNIFIED IDEOGRAPH
+0xDCE1	0x831A	#CJK UNIFIED IDEOGRAPH
+0xDCE2	0x8306	#CJK UNIFIED IDEOGRAPH
+0xDCE3	0x8314	#CJK UNIFIED IDEOGRAPH
+0xDCE4	0x8315	#CJK UNIFIED IDEOGRAPH
+0xDCE5	0x82E0	#CJK UNIFIED IDEOGRAPH
+0xDCE6	0x82D5	#CJK UNIFIED IDEOGRAPH
+0xDCE7	0x831C	#CJK UNIFIED IDEOGRAPH
+0xDCE8	0x8351	#CJK UNIFIED IDEOGRAPH
+0xDCE9	0x835B	#CJK UNIFIED IDEOGRAPH
+0xDCEA	0x835C	#CJK UNIFIED IDEOGRAPH
+0xDCEB	0x8308	#CJK UNIFIED IDEOGRAPH
+0xDCEC	0x8392	#CJK UNIFIED IDEOGRAPH
+0xDCED	0x833C	#CJK UNIFIED IDEOGRAPH
+0xDCEE	0x8334	#CJK UNIFIED IDEOGRAPH
+0xDCEF	0x8331	#CJK UNIFIED IDEOGRAPH
+0xDCF0	0x839B	#CJK UNIFIED IDEOGRAPH
+0xDCF1	0x835E	#CJK UNIFIED IDEOGRAPH
+0xDCF2	0x832F	#CJK UNIFIED IDEOGRAPH
+0xDCF3	0x834F	#CJK UNIFIED IDEOGRAPH
+0xDCF4	0x8347	#CJK UNIFIED IDEOGRAPH
+0xDCF5	0x8343	#CJK UNIFIED IDEOGRAPH
+0xDCF6	0x835F	#CJK UNIFIED IDEOGRAPH
+0xDCF7	0x8340	#CJK UNIFIED IDEOGRAPH
+0xDCF8	0x8317	#CJK UNIFIED IDEOGRAPH
+0xDCF9	0x8360	#CJK UNIFIED IDEOGRAPH
+0xDCFA	0x832D	#CJK UNIFIED IDEOGRAPH
+0xDCFB	0x833A	#CJK UNIFIED IDEOGRAPH
+0xDCFC	0x8333	#CJK UNIFIED IDEOGRAPH
+0xDCFD	0x8366	#CJK UNIFIED IDEOGRAPH
+0xDCFE	0x8365	#CJK UNIFIED IDEOGRAPH
+0xDD40	0x8EE5	#CJK UNIFIED IDEOGRAPH
+0xDD41	0x8EE6	#CJK UNIFIED IDEOGRAPH
+0xDD42	0x8EE7	#CJK UNIFIED IDEOGRAPH
+0xDD43	0x8EE8	#CJK UNIFIED IDEOGRAPH
+0xDD44	0x8EE9	#CJK UNIFIED IDEOGRAPH
+0xDD45	0x8EEA	#CJK UNIFIED IDEOGRAPH
+0xDD46	0x8EEB	#CJK UNIFIED IDEOGRAPH
+0xDD47	0x8EEC	#CJK UNIFIED IDEOGRAPH
+0xDD48	0x8EED	#CJK UNIFIED IDEOGRAPH
+0xDD49	0x8EEE	#CJK UNIFIED IDEOGRAPH
+0xDD4A	0x8EEF	#CJK UNIFIED IDEOGRAPH
+0xDD4B	0x8EF0	#CJK UNIFIED IDEOGRAPH
+0xDD4C	0x8EF1	#CJK UNIFIED IDEOGRAPH
+0xDD4D	0x8EF2	#CJK UNIFIED IDEOGRAPH
+0xDD4E	0x8EF3	#CJK UNIFIED IDEOGRAPH
+0xDD4F	0x8EF4	#CJK UNIFIED IDEOGRAPH
+0xDD50	0x8EF5	#CJK UNIFIED IDEOGRAPH
+0xDD51	0x8EF6	#CJK UNIFIED IDEOGRAPH
+0xDD52	0x8EF7	#CJK UNIFIED IDEOGRAPH
+0xDD53	0x8EF8	#CJK UNIFIED IDEOGRAPH
+0xDD54	0x8EF9	#CJK UNIFIED IDEOGRAPH
+0xDD55	0x8EFA	#CJK UNIFIED IDEOGRAPH
+0xDD56	0x8EFB	#CJK UNIFIED IDEOGRAPH
+0xDD57	0x8EFC	#CJK UNIFIED IDEOGRAPH
+0xDD58	0x8EFD	#CJK UNIFIED IDEOGRAPH
+0xDD59	0x8EFE	#CJK UNIFIED IDEOGRAPH
+0xDD5A	0x8EFF	#CJK UNIFIED IDEOGRAPH
+0xDD5B	0x8F00	#CJK UNIFIED IDEOGRAPH
+0xDD5C	0x8F01	#CJK UNIFIED IDEOGRAPH
+0xDD5D	0x8F02	#CJK UNIFIED IDEOGRAPH
+0xDD5E	0x8F03	#CJK UNIFIED IDEOGRAPH
+0xDD5F	0x8F04	#CJK UNIFIED IDEOGRAPH
+0xDD60	0x8F05	#CJK UNIFIED IDEOGRAPH
+0xDD61	0x8F06	#CJK UNIFIED IDEOGRAPH
+0xDD62	0x8F07	#CJK UNIFIED IDEOGRAPH
+0xDD63	0x8F08	#CJK UNIFIED IDEOGRAPH
+0xDD64	0x8F09	#CJK UNIFIED IDEOGRAPH
+0xDD65	0x8F0A	#CJK UNIFIED IDEOGRAPH
+0xDD66	0x8F0B	#CJK UNIFIED IDEOGRAPH
+0xDD67	0x8F0C	#CJK UNIFIED IDEOGRAPH
+0xDD68	0x8F0D	#CJK UNIFIED IDEOGRAPH
+0xDD69	0x8F0E	#CJK UNIFIED IDEOGRAPH
+0xDD6A	0x8F0F	#CJK UNIFIED IDEOGRAPH
+0xDD6B	0x8F10	#CJK UNIFIED IDEOGRAPH
+0xDD6C	0x8F11	#CJK UNIFIED IDEOGRAPH
+0xDD6D	0x8F12	#CJK UNIFIED IDEOGRAPH
+0xDD6E	0x8F13	#CJK UNIFIED IDEOGRAPH
+0xDD6F	0x8F14	#CJK UNIFIED IDEOGRAPH
+0xDD70	0x8F15	#CJK UNIFIED IDEOGRAPH
+0xDD71	0x8F16	#CJK UNIFIED IDEOGRAPH
+0xDD72	0x8F17	#CJK UNIFIED IDEOGRAPH
+0xDD73	0x8F18	#CJK UNIFIED IDEOGRAPH
+0xDD74	0x8F19	#CJK UNIFIED IDEOGRAPH
+0xDD75	0x8F1A	#CJK UNIFIED IDEOGRAPH
+0xDD76	0x8F1B	#CJK UNIFIED IDEOGRAPH
+0xDD77	0x8F1C	#CJK UNIFIED IDEOGRAPH
+0xDD78	0x8F1D	#CJK UNIFIED IDEOGRAPH
+0xDD79	0x8F1E	#CJK UNIFIED IDEOGRAPH
+0xDD7A	0x8F1F	#CJK UNIFIED IDEOGRAPH
+0xDD7B	0x8F20	#CJK UNIFIED IDEOGRAPH
+0xDD7C	0x8F21	#CJK UNIFIED IDEOGRAPH
+0xDD7D	0x8F22	#CJK UNIFIED IDEOGRAPH
+0xDD7E	0x8F23	#CJK UNIFIED IDEOGRAPH
+0xDD80	0x8F24	#CJK UNIFIED IDEOGRAPH
+0xDD81	0x8F25	#CJK UNIFIED IDEOGRAPH
+0xDD82	0x8F26	#CJK UNIFIED IDEOGRAPH
+0xDD83	0x8F27	#CJK UNIFIED IDEOGRAPH
+0xDD84	0x8F28	#CJK UNIFIED IDEOGRAPH
+0xDD85	0x8F29	#CJK UNIFIED IDEOGRAPH
+0xDD86	0x8F2A	#CJK UNIFIED IDEOGRAPH
+0xDD87	0x8F2B	#CJK UNIFIED IDEOGRAPH
+0xDD88	0x8F2C	#CJK UNIFIED IDEOGRAPH
+0xDD89	0x8F2D	#CJK UNIFIED IDEOGRAPH
+0xDD8A	0x8F2E	#CJK UNIFIED IDEOGRAPH
+0xDD8B	0x8F2F	#CJK UNIFIED IDEOGRAPH
+0xDD8C	0x8F30	#CJK UNIFIED IDEOGRAPH
+0xDD8D	0x8F31	#CJK UNIFIED IDEOGRAPH
+0xDD8E	0x8F32	#CJK UNIFIED IDEOGRAPH
+0xDD8F	0x8F33	#CJK UNIFIED IDEOGRAPH
+0xDD90	0x8F34	#CJK UNIFIED IDEOGRAPH
+0xDD91	0x8F35	#CJK UNIFIED IDEOGRAPH
+0xDD92	0x8F36	#CJK UNIFIED IDEOGRAPH
+0xDD93	0x8F37	#CJK UNIFIED IDEOGRAPH
+0xDD94	0x8F38	#CJK UNIFIED IDEOGRAPH
+0xDD95	0x8F39	#CJK UNIFIED IDEOGRAPH
+0xDD96	0x8F3A	#CJK UNIFIED IDEOGRAPH
+0xDD97	0x8F3B	#CJK UNIFIED IDEOGRAPH
+0xDD98	0x8F3C	#CJK UNIFIED IDEOGRAPH
+0xDD99	0x8F3D	#CJK UNIFIED IDEOGRAPH
+0xDD9A	0x8F3E	#CJK UNIFIED IDEOGRAPH
+0xDD9B	0x8F3F	#CJK UNIFIED IDEOGRAPH
+0xDD9C	0x8F40	#CJK UNIFIED IDEOGRAPH
+0xDD9D	0x8F41	#CJK UNIFIED IDEOGRAPH
+0xDD9E	0x8F42	#CJK UNIFIED IDEOGRAPH
+0xDD9F	0x8F43	#CJK UNIFIED IDEOGRAPH
+0xDDA0	0x8F44	#CJK UNIFIED IDEOGRAPH
+0xDDA1	0x8368	#CJK UNIFIED IDEOGRAPH
+0xDDA2	0x831B	#CJK UNIFIED IDEOGRAPH
+0xDDA3	0x8369	#CJK UNIFIED IDEOGRAPH
+0xDDA4	0x836C	#CJK UNIFIED IDEOGRAPH
+0xDDA5	0x836A	#CJK UNIFIED IDEOGRAPH
+0xDDA6	0x836D	#CJK UNIFIED IDEOGRAPH
+0xDDA7	0x836E	#CJK UNIFIED IDEOGRAPH
+0xDDA8	0x83B0	#CJK UNIFIED IDEOGRAPH
+0xDDA9	0x8378	#CJK UNIFIED IDEOGRAPH
+0xDDAA	0x83B3	#CJK UNIFIED IDEOGRAPH
+0xDDAB	0x83B4	#CJK UNIFIED IDEOGRAPH
+0xDDAC	0x83A0	#CJK UNIFIED IDEOGRAPH
+0xDDAD	0x83AA	#CJK UNIFIED IDEOGRAPH
+0xDDAE	0x8393	#CJK UNIFIED IDEOGRAPH
+0xDDAF	0x839C	#CJK UNIFIED IDEOGRAPH
+0xDDB0	0x8385	#CJK UNIFIED IDEOGRAPH
+0xDDB1	0x837C	#CJK UNIFIED IDEOGRAPH
+0xDDB2	0x83B6	#CJK UNIFIED IDEOGRAPH
+0xDDB3	0x83A9	#CJK UNIFIED IDEOGRAPH
+0xDDB4	0x837D	#CJK UNIFIED IDEOGRAPH
+0xDDB5	0x83B8	#CJK UNIFIED IDEOGRAPH
+0xDDB6	0x837B	#CJK UNIFIED IDEOGRAPH
+0xDDB7	0x8398	#CJK UNIFIED IDEOGRAPH
+0xDDB8	0x839E	#CJK UNIFIED IDEOGRAPH
+0xDDB9	0x83A8	#CJK UNIFIED IDEOGRAPH
+0xDDBA	0x83BA	#CJK UNIFIED IDEOGRAPH
+0xDDBB	0x83BC	#CJK UNIFIED IDEOGRAPH
+0xDDBC	0x83C1	#CJK UNIFIED IDEOGRAPH
+0xDDBD	0x8401	#CJK UNIFIED IDEOGRAPH
+0xDDBE	0x83E5	#CJK UNIFIED IDEOGRAPH
+0xDDBF	0x83D8	#CJK UNIFIED IDEOGRAPH
+0xDDC0	0x5807	#CJK UNIFIED IDEOGRAPH
+0xDDC1	0x8418	#CJK UNIFIED IDEOGRAPH
+0xDDC2	0x840B	#CJK UNIFIED IDEOGRAPH
+0xDDC3	0x83DD	#CJK UNIFIED IDEOGRAPH
+0xDDC4	0x83FD	#CJK UNIFIED IDEOGRAPH
+0xDDC5	0x83D6	#CJK UNIFIED IDEOGRAPH
+0xDDC6	0x841C	#CJK UNIFIED IDEOGRAPH
+0xDDC7	0x8438	#CJK UNIFIED IDEOGRAPH
+0xDDC8	0x8411	#CJK UNIFIED IDEOGRAPH
+0xDDC9	0x8406	#CJK UNIFIED IDEOGRAPH
+0xDDCA	0x83D4	#CJK UNIFIED IDEOGRAPH
+0xDDCB	0x83DF	#CJK UNIFIED IDEOGRAPH
+0xDDCC	0x840F	#CJK UNIFIED IDEOGRAPH
+0xDDCD	0x8403	#CJK UNIFIED IDEOGRAPH
+0xDDCE	0x83F8	#CJK UNIFIED IDEOGRAPH
+0xDDCF	0x83F9	#CJK UNIFIED IDEOGRAPH
+0xDDD0	0x83EA	#CJK UNIFIED IDEOGRAPH
+0xDDD1	0x83C5	#CJK UNIFIED IDEOGRAPH
+0xDDD2	0x83C0	#CJK UNIFIED IDEOGRAPH
+0xDDD3	0x8426	#CJK UNIFIED IDEOGRAPH
+0xDDD4	0x83F0	#CJK UNIFIED IDEOGRAPH
+0xDDD5	0x83E1	#CJK UNIFIED IDEOGRAPH
+0xDDD6	0x845C	#CJK UNIFIED IDEOGRAPH
+0xDDD7	0x8451	#CJK UNIFIED IDEOGRAPH
+0xDDD8	0x845A	#CJK UNIFIED IDEOGRAPH
+0xDDD9	0x8459	#CJK UNIFIED IDEOGRAPH
+0xDDDA	0x8473	#CJK UNIFIED IDEOGRAPH
+0xDDDB	0x8487	#CJK UNIFIED IDEOGRAPH
+0xDDDC	0x8488	#CJK UNIFIED IDEOGRAPH
+0xDDDD	0x847A	#CJK UNIFIED IDEOGRAPH
+0xDDDE	0x8489	#CJK UNIFIED IDEOGRAPH
+0xDDDF	0x8478	#CJK UNIFIED IDEOGRAPH
+0xDDE0	0x843C	#CJK UNIFIED IDEOGRAPH
+0xDDE1	0x8446	#CJK UNIFIED IDEOGRAPH
+0xDDE2	0x8469	#CJK UNIFIED IDEOGRAPH
+0xDDE3	0x8476	#CJK UNIFIED IDEOGRAPH
+0xDDE4	0x848C	#CJK UNIFIED IDEOGRAPH
+0xDDE5	0x848E	#CJK UNIFIED IDEOGRAPH
+0xDDE6	0x8431	#CJK UNIFIED IDEOGRAPH
+0xDDE7	0x846D	#CJK UNIFIED IDEOGRAPH
+0xDDE8	0x84C1	#CJK UNIFIED IDEOGRAPH
+0xDDE9	0x84CD	#CJK UNIFIED IDEOGRAPH
+0xDDEA	0x84D0	#CJK UNIFIED IDEOGRAPH
+0xDDEB	0x84E6	#CJK UNIFIED IDEOGRAPH
+0xDDEC	0x84BD	#CJK UNIFIED IDEOGRAPH
+0xDDED	0x84D3	#CJK UNIFIED IDEOGRAPH
+0xDDEE	0x84CA	#CJK UNIFIED IDEOGRAPH
+0xDDEF	0x84BF	#CJK UNIFIED IDEOGRAPH
+0xDDF0	0x84BA	#CJK UNIFIED IDEOGRAPH
+0xDDF1	0x84E0	#CJK UNIFIED IDEOGRAPH
+0xDDF2	0x84A1	#CJK UNIFIED IDEOGRAPH
+0xDDF3	0x84B9	#CJK UNIFIED IDEOGRAPH
+0xDDF4	0x84B4	#CJK UNIFIED IDEOGRAPH
+0xDDF5	0x8497	#CJK UNIFIED IDEOGRAPH
+0xDDF6	0x84E5	#CJK UNIFIED IDEOGRAPH
+0xDDF7	0x84E3	#CJK UNIFIED IDEOGRAPH
+0xDDF8	0x850C	#CJK UNIFIED IDEOGRAPH
+0xDDF9	0x750D	#CJK UNIFIED IDEOGRAPH
+0xDDFA	0x8538	#CJK UNIFIED IDEOGRAPH
+0xDDFB	0x84F0	#CJK UNIFIED IDEOGRAPH
+0xDDFC	0x8539	#CJK UNIFIED IDEOGRAPH
+0xDDFD	0x851F	#CJK UNIFIED IDEOGRAPH
+0xDDFE	0x853A	#CJK UNIFIED IDEOGRAPH
+0xDE40	0x8F45	#CJK UNIFIED IDEOGRAPH
+0xDE41	0x8F46	#CJK UNIFIED IDEOGRAPH
+0xDE42	0x8F47	#CJK UNIFIED IDEOGRAPH
+0xDE43	0x8F48	#CJK UNIFIED IDEOGRAPH
+0xDE44	0x8F49	#CJK UNIFIED IDEOGRAPH
+0xDE45	0x8F4A	#CJK UNIFIED IDEOGRAPH
+0xDE46	0x8F4B	#CJK UNIFIED IDEOGRAPH
+0xDE47	0x8F4C	#CJK UNIFIED IDEOGRAPH
+0xDE48	0x8F4D	#CJK UNIFIED IDEOGRAPH
+0xDE49	0x8F4E	#CJK UNIFIED IDEOGRAPH
+0xDE4A	0x8F4F	#CJK UNIFIED IDEOGRAPH
+0xDE4B	0x8F50	#CJK UNIFIED IDEOGRAPH
+0xDE4C	0x8F51	#CJK UNIFIED IDEOGRAPH
+0xDE4D	0x8F52	#CJK UNIFIED IDEOGRAPH
+0xDE4E	0x8F53	#CJK UNIFIED IDEOGRAPH
+0xDE4F	0x8F54	#CJK UNIFIED IDEOGRAPH
+0xDE50	0x8F55	#CJK UNIFIED IDEOGRAPH
+0xDE51	0x8F56	#CJK UNIFIED IDEOGRAPH
+0xDE52	0x8F57	#CJK UNIFIED IDEOGRAPH
+0xDE53	0x8F58	#CJK UNIFIED IDEOGRAPH
+0xDE54	0x8F59	#CJK UNIFIED IDEOGRAPH
+0xDE55	0x8F5A	#CJK UNIFIED IDEOGRAPH
+0xDE56	0x8F5B	#CJK UNIFIED IDEOGRAPH
+0xDE57	0x8F5C	#CJK UNIFIED IDEOGRAPH
+0xDE58	0x8F5D	#CJK UNIFIED IDEOGRAPH
+0xDE59	0x8F5E	#CJK UNIFIED IDEOGRAPH
+0xDE5A	0x8F5F	#CJK UNIFIED IDEOGRAPH
+0xDE5B	0x8F60	#CJK UNIFIED IDEOGRAPH
+0xDE5C	0x8F61	#CJK UNIFIED IDEOGRAPH
+0xDE5D	0x8F62	#CJK UNIFIED IDEOGRAPH
+0xDE5E	0x8F63	#CJK UNIFIED IDEOGRAPH
+0xDE5F	0x8F64	#CJK UNIFIED IDEOGRAPH
+0xDE60	0x8F65	#CJK UNIFIED IDEOGRAPH
+0xDE61	0x8F6A	#CJK UNIFIED IDEOGRAPH
+0xDE62	0x8F80	#CJK UNIFIED IDEOGRAPH
+0xDE63	0x8F8C	#CJK UNIFIED IDEOGRAPH
+0xDE64	0x8F92	#CJK UNIFIED IDEOGRAPH
+0xDE65	0x8F9D	#CJK UNIFIED IDEOGRAPH
+0xDE66	0x8FA0	#CJK UNIFIED IDEOGRAPH
+0xDE67	0x8FA1	#CJK UNIFIED IDEOGRAPH
+0xDE68	0x8FA2	#CJK UNIFIED IDEOGRAPH
+0xDE69	0x8FA4	#CJK UNIFIED IDEOGRAPH
+0xDE6A	0x8FA5	#CJK UNIFIED IDEOGRAPH
+0xDE6B	0x8FA6	#CJK UNIFIED IDEOGRAPH
+0xDE6C	0x8FA7	#CJK UNIFIED IDEOGRAPH
+0xDE6D	0x8FAA	#CJK UNIFIED IDEOGRAPH
+0xDE6E	0x8FAC	#CJK UNIFIED IDEOGRAPH
+0xDE6F	0x8FAD	#CJK UNIFIED IDEOGRAPH
+0xDE70	0x8FAE	#CJK UNIFIED IDEOGRAPH
+0xDE71	0x8FAF	#CJK UNIFIED IDEOGRAPH
+0xDE72	0x8FB2	#CJK UNIFIED IDEOGRAPH
+0xDE73	0x8FB3	#CJK UNIFIED IDEOGRAPH
+0xDE74	0x8FB4	#CJK UNIFIED IDEOGRAPH
+0xDE75	0x8FB5	#CJK UNIFIED IDEOGRAPH
+0xDE76	0x8FB7	#CJK UNIFIED IDEOGRAPH
+0xDE77	0x8FB8	#CJK UNIFIED IDEOGRAPH
+0xDE78	0x8FBA	#CJK UNIFIED IDEOGRAPH
+0xDE79	0x8FBB	#CJK UNIFIED IDEOGRAPH
+0xDE7A	0x8FBC	#CJK UNIFIED IDEOGRAPH
+0xDE7B	0x8FBF	#CJK UNIFIED IDEOGRAPH
+0xDE7C	0x8FC0	#CJK UNIFIED IDEOGRAPH
+0xDE7D	0x8FC3	#CJK UNIFIED IDEOGRAPH
+0xDE7E	0x8FC6	#CJK UNIFIED IDEOGRAPH
+0xDE80	0x8FC9	#CJK UNIFIED IDEOGRAPH
+0xDE81	0x8FCA	#CJK UNIFIED IDEOGRAPH
+0xDE82	0x8FCB	#CJK UNIFIED IDEOGRAPH
+0xDE83	0x8FCC	#CJK UNIFIED IDEOGRAPH
+0xDE84	0x8FCD	#CJK UNIFIED IDEOGRAPH
+0xDE85	0x8FCF	#CJK UNIFIED IDEOGRAPH
+0xDE86	0x8FD2	#CJK UNIFIED IDEOGRAPH
+0xDE87	0x8FD6	#CJK UNIFIED IDEOGRAPH
+0xDE88	0x8FD7	#CJK UNIFIED IDEOGRAPH
+0xDE89	0x8FDA	#CJK UNIFIED IDEOGRAPH
+0xDE8A	0x8FE0	#CJK UNIFIED IDEOGRAPH
+0xDE8B	0x8FE1	#CJK UNIFIED IDEOGRAPH
+0xDE8C	0x8FE3	#CJK UNIFIED IDEOGRAPH
+0xDE8D	0x8FE7	#CJK UNIFIED IDEOGRAPH
+0xDE8E	0x8FEC	#CJK UNIFIED IDEOGRAPH
+0xDE8F	0x8FEF	#CJK UNIFIED IDEOGRAPH
+0xDE90	0x8FF1	#CJK UNIFIED IDEOGRAPH
+0xDE91	0x8FF2	#CJK UNIFIED IDEOGRAPH
+0xDE92	0x8FF4	#CJK UNIFIED IDEOGRAPH
+0xDE93	0x8FF5	#CJK UNIFIED IDEOGRAPH
+0xDE94	0x8FF6	#CJK UNIFIED IDEOGRAPH
+0xDE95	0x8FFA	#CJK UNIFIED IDEOGRAPH
+0xDE96	0x8FFB	#CJK UNIFIED IDEOGRAPH
+0xDE97	0x8FFC	#CJK UNIFIED IDEOGRAPH
+0xDE98	0x8FFE	#CJK UNIFIED IDEOGRAPH
+0xDE99	0x8FFF	#CJK UNIFIED IDEOGRAPH
+0xDE9A	0x9007	#CJK UNIFIED IDEOGRAPH
+0xDE9B	0x9008	#CJK UNIFIED IDEOGRAPH
+0xDE9C	0x900C	#CJK UNIFIED IDEOGRAPH
+0xDE9D	0x900E	#CJK UNIFIED IDEOGRAPH
+0xDE9E	0x9013	#CJK UNIFIED IDEOGRAPH
+0xDE9F	0x9015	#CJK UNIFIED IDEOGRAPH
+0xDEA0	0x9018	#CJK UNIFIED IDEOGRAPH
+0xDEA1	0x8556	#CJK UNIFIED IDEOGRAPH
+0xDEA2	0x853B	#CJK UNIFIED IDEOGRAPH
+0xDEA3	0x84FF	#CJK UNIFIED IDEOGRAPH
+0xDEA4	0x84FC	#CJK UNIFIED IDEOGRAPH
+0xDEA5	0x8559	#CJK UNIFIED IDEOGRAPH
+0xDEA6	0x8548	#CJK UNIFIED IDEOGRAPH
+0xDEA7	0x8568	#CJK UNIFIED IDEOGRAPH
+0xDEA8	0x8564	#CJK UNIFIED IDEOGRAPH
+0xDEA9	0x855E	#CJK UNIFIED IDEOGRAPH
+0xDEAA	0x857A	#CJK UNIFIED IDEOGRAPH
+0xDEAB	0x77A2	#CJK UNIFIED IDEOGRAPH
+0xDEAC	0x8543	#CJK UNIFIED IDEOGRAPH
+0xDEAD	0x8572	#CJK UNIFIED IDEOGRAPH
+0xDEAE	0x857B	#CJK UNIFIED IDEOGRAPH
+0xDEAF	0x85A4	#CJK UNIFIED IDEOGRAPH
+0xDEB0	0x85A8	#CJK UNIFIED IDEOGRAPH
+0xDEB1	0x8587	#CJK UNIFIED IDEOGRAPH
+0xDEB2	0x858F	#CJK UNIFIED IDEOGRAPH
+0xDEB3	0x8579	#CJK UNIFIED IDEOGRAPH
+0xDEB4	0x85AE	#CJK UNIFIED IDEOGRAPH
+0xDEB5	0x859C	#CJK UNIFIED IDEOGRAPH
+0xDEB6	0x8585	#CJK UNIFIED IDEOGRAPH
+0xDEB7	0x85B9	#CJK UNIFIED IDEOGRAPH
+0xDEB8	0x85B7	#CJK UNIFIED IDEOGRAPH
+0xDEB9	0x85B0	#CJK UNIFIED IDEOGRAPH
+0xDEBA	0x85D3	#CJK UNIFIED IDEOGRAPH
+0xDEBB	0x85C1	#CJK UNIFIED IDEOGRAPH
+0xDEBC	0x85DC	#CJK UNIFIED IDEOGRAPH
+0xDEBD	0x85FF	#CJK UNIFIED IDEOGRAPH
+0xDEBE	0x8627	#CJK UNIFIED IDEOGRAPH
+0xDEBF	0x8605	#CJK UNIFIED IDEOGRAPH
+0xDEC0	0x8629	#CJK UNIFIED IDEOGRAPH
+0xDEC1	0x8616	#CJK UNIFIED IDEOGRAPH
+0xDEC2	0x863C	#CJK UNIFIED IDEOGRAPH
+0xDEC3	0x5EFE	#CJK UNIFIED IDEOGRAPH
+0xDEC4	0x5F08	#CJK UNIFIED IDEOGRAPH
+0xDEC5	0x593C	#CJK UNIFIED IDEOGRAPH
+0xDEC6	0x5941	#CJK UNIFIED IDEOGRAPH
+0xDEC7	0x8037	#CJK UNIFIED IDEOGRAPH
+0xDEC8	0x5955	#CJK UNIFIED IDEOGRAPH
+0xDEC9	0x595A	#CJK UNIFIED IDEOGRAPH
+0xDECA	0x5958	#CJK UNIFIED IDEOGRAPH
+0xDECB	0x530F	#CJK UNIFIED IDEOGRAPH
+0xDECC	0x5C22	#CJK UNIFIED IDEOGRAPH
+0xDECD	0x5C25	#CJK UNIFIED IDEOGRAPH
+0xDECE	0x5C2C	#CJK UNIFIED IDEOGRAPH
+0xDECF	0x5C34	#CJK UNIFIED IDEOGRAPH
+0xDED0	0x624C	#CJK UNIFIED IDEOGRAPH
+0xDED1	0x626A	#CJK UNIFIED IDEOGRAPH
+0xDED2	0x629F	#CJK UNIFIED IDEOGRAPH
+0xDED3	0x62BB	#CJK UNIFIED IDEOGRAPH
+0xDED4	0x62CA	#CJK UNIFIED IDEOGRAPH
+0xDED5	0x62DA	#CJK UNIFIED IDEOGRAPH
+0xDED6	0x62D7	#CJK UNIFIED IDEOGRAPH
+0xDED7	0x62EE	#CJK UNIFIED IDEOGRAPH
+0xDED8	0x6322	#CJK UNIFIED IDEOGRAPH
+0xDED9	0x62F6	#CJK UNIFIED IDEOGRAPH
+0xDEDA	0x6339	#CJK UNIFIED IDEOGRAPH
+0xDEDB	0x634B	#CJK UNIFIED IDEOGRAPH
+0xDEDC	0x6343	#CJK UNIFIED IDEOGRAPH
+0xDEDD	0x63AD	#CJK UNIFIED IDEOGRAPH
+0xDEDE	0x63F6	#CJK UNIFIED IDEOGRAPH
+0xDEDF	0x6371	#CJK UNIFIED IDEOGRAPH
+0xDEE0	0x637A	#CJK UNIFIED IDEOGRAPH
+0xDEE1	0x638E	#CJK UNIFIED IDEOGRAPH
+0xDEE2	0x63B4	#CJK UNIFIED IDEOGRAPH
+0xDEE3	0x636D	#CJK UNIFIED IDEOGRAPH
+0xDEE4	0x63AC	#CJK UNIFIED IDEOGRAPH
+0xDEE5	0x638A	#CJK UNIFIED IDEOGRAPH
+0xDEE6	0x6369	#CJK UNIFIED IDEOGRAPH
+0xDEE7	0x63AE	#CJK UNIFIED IDEOGRAPH
+0xDEE8	0x63BC	#CJK UNIFIED IDEOGRAPH
+0xDEE9	0x63F2	#CJK UNIFIED IDEOGRAPH
+0xDEEA	0x63F8	#CJK UNIFIED IDEOGRAPH
+0xDEEB	0x63E0	#CJK UNIFIED IDEOGRAPH
+0xDEEC	0x63FF	#CJK UNIFIED IDEOGRAPH
+0xDEED	0x63C4	#CJK UNIFIED IDEOGRAPH
+0xDEEE	0x63DE	#CJK UNIFIED IDEOGRAPH
+0xDEEF	0x63CE	#CJK UNIFIED IDEOGRAPH
+0xDEF0	0x6452	#CJK UNIFIED IDEOGRAPH
+0xDEF1	0x63C6	#CJK UNIFIED IDEOGRAPH
+0xDEF2	0x63BE	#CJK UNIFIED IDEOGRAPH
+0xDEF3	0x6445	#CJK UNIFIED IDEOGRAPH
+0xDEF4	0x6441	#CJK UNIFIED IDEOGRAPH
+0xDEF5	0x640B	#CJK UNIFIED IDEOGRAPH
+0xDEF6	0x641B	#CJK UNIFIED IDEOGRAPH
+0xDEF7	0x6420	#CJK UNIFIED IDEOGRAPH
+0xDEF8	0x640C	#CJK UNIFIED IDEOGRAPH
+0xDEF9	0x6426	#CJK UNIFIED IDEOGRAPH
+0xDEFA	0x6421	#CJK UNIFIED IDEOGRAPH
+0xDEFB	0x645E	#CJK UNIFIED IDEOGRAPH
+0xDEFC	0x6484	#CJK UNIFIED IDEOGRAPH
+0xDEFD	0x646D	#CJK UNIFIED IDEOGRAPH
+0xDEFE	0x6496	#CJK UNIFIED IDEOGRAPH
+0xDF40	0x9019	#CJK UNIFIED IDEOGRAPH
+0xDF41	0x901C	#CJK UNIFIED IDEOGRAPH
+0xDF42	0x9023	#CJK UNIFIED IDEOGRAPH
+0xDF43	0x9024	#CJK UNIFIED IDEOGRAPH
+0xDF44	0x9025	#CJK UNIFIED IDEOGRAPH
+0xDF45	0x9027	#CJK UNIFIED IDEOGRAPH
+0xDF46	0x9028	#CJK UNIFIED IDEOGRAPH
+0xDF47	0x9029	#CJK UNIFIED IDEOGRAPH
+0xDF48	0x902A	#CJK UNIFIED IDEOGRAPH
+0xDF49	0x902B	#CJK UNIFIED IDEOGRAPH
+0xDF4A	0x902C	#CJK UNIFIED IDEOGRAPH
+0xDF4B	0x9030	#CJK UNIFIED IDEOGRAPH
+0xDF4C	0x9031	#CJK UNIFIED IDEOGRAPH
+0xDF4D	0x9032	#CJK UNIFIED IDEOGRAPH
+0xDF4E	0x9033	#CJK UNIFIED IDEOGRAPH
+0xDF4F	0x9034	#CJK UNIFIED IDEOGRAPH
+0xDF50	0x9037	#CJK UNIFIED IDEOGRAPH
+0xDF51	0x9039	#CJK UNIFIED IDEOGRAPH
+0xDF52	0x903A	#CJK UNIFIED IDEOGRAPH
+0xDF53	0x903D	#CJK UNIFIED IDEOGRAPH
+0xDF54	0x903F	#CJK UNIFIED IDEOGRAPH
+0xDF55	0x9040	#CJK UNIFIED IDEOGRAPH
+0xDF56	0x9043	#CJK UNIFIED IDEOGRAPH
+0xDF57	0x9045	#CJK UNIFIED IDEOGRAPH
+0xDF58	0x9046	#CJK UNIFIED IDEOGRAPH
+0xDF59	0x9048	#CJK UNIFIED IDEOGRAPH
+0xDF5A	0x9049	#CJK UNIFIED IDEOGRAPH
+0xDF5B	0x904A	#CJK UNIFIED IDEOGRAPH
+0xDF5C	0x904B	#CJK UNIFIED IDEOGRAPH
+0xDF5D	0x904C	#CJK UNIFIED IDEOGRAPH
+0xDF5E	0x904E	#CJK UNIFIED IDEOGRAPH
+0xDF5F	0x9054	#CJK UNIFIED IDEOGRAPH
+0xDF60	0x9055	#CJK UNIFIED IDEOGRAPH
+0xDF61	0x9056	#CJK UNIFIED IDEOGRAPH
+0xDF62	0x9059	#CJK UNIFIED IDEOGRAPH
+0xDF63	0x905A	#CJK UNIFIED IDEOGRAPH
+0xDF64	0x905C	#CJK UNIFIED IDEOGRAPH
+0xDF65	0x905D	#CJK UNIFIED IDEOGRAPH
+0xDF66	0x905E	#CJK UNIFIED IDEOGRAPH
+0xDF67	0x905F	#CJK UNIFIED IDEOGRAPH
+0xDF68	0x9060	#CJK UNIFIED IDEOGRAPH
+0xDF69	0x9061	#CJK UNIFIED IDEOGRAPH
+0xDF6A	0x9064	#CJK UNIFIED IDEOGRAPH
+0xDF6B	0x9066	#CJK UNIFIED IDEOGRAPH
+0xDF6C	0x9067	#CJK UNIFIED IDEOGRAPH
+0xDF6D	0x9069	#CJK UNIFIED IDEOGRAPH
+0xDF6E	0x906A	#CJK UNIFIED IDEOGRAPH
+0xDF6F	0x906B	#CJK UNIFIED IDEOGRAPH
+0xDF70	0x906C	#CJK UNIFIED IDEOGRAPH
+0xDF71	0x906F	#CJK UNIFIED IDEOGRAPH
+0xDF72	0x9070	#CJK UNIFIED IDEOGRAPH
+0xDF73	0x9071	#CJK UNIFIED IDEOGRAPH
+0xDF74	0x9072	#CJK UNIFIED IDEOGRAPH
+0xDF75	0x9073	#CJK UNIFIED IDEOGRAPH
+0xDF76	0x9076	#CJK UNIFIED IDEOGRAPH
+0xDF77	0x9077	#CJK UNIFIED IDEOGRAPH
+0xDF78	0x9078	#CJK UNIFIED IDEOGRAPH
+0xDF79	0x9079	#CJK UNIFIED IDEOGRAPH
+0xDF7A	0x907A	#CJK UNIFIED IDEOGRAPH
+0xDF7B	0x907B	#CJK UNIFIED IDEOGRAPH
+0xDF7C	0x907C	#CJK UNIFIED IDEOGRAPH
+0xDF7D	0x907E	#CJK UNIFIED IDEOGRAPH
+0xDF7E	0x9081	#CJK UNIFIED IDEOGRAPH
+0xDF80	0x9084	#CJK UNIFIED IDEOGRAPH
+0xDF81	0x9085	#CJK UNIFIED IDEOGRAPH
+0xDF82	0x9086	#CJK UNIFIED IDEOGRAPH
+0xDF83	0x9087	#CJK UNIFIED IDEOGRAPH
+0xDF84	0x9089	#CJK UNIFIED IDEOGRAPH
+0xDF85	0x908A	#CJK UNIFIED IDEOGRAPH
+0xDF86	0x908C	#CJK UNIFIED IDEOGRAPH
+0xDF87	0x908D	#CJK UNIFIED IDEOGRAPH
+0xDF88	0x908E	#CJK UNIFIED IDEOGRAPH
+0xDF89	0x908F	#CJK UNIFIED IDEOGRAPH
+0xDF8A	0x9090	#CJK UNIFIED IDEOGRAPH
+0xDF8B	0x9092	#CJK UNIFIED IDEOGRAPH
+0xDF8C	0x9094	#CJK UNIFIED IDEOGRAPH
+0xDF8D	0x9096	#CJK UNIFIED IDEOGRAPH
+0xDF8E	0x9098	#CJK UNIFIED IDEOGRAPH
+0xDF8F	0x909A	#CJK UNIFIED IDEOGRAPH
+0xDF90	0x909C	#CJK UNIFIED IDEOGRAPH
+0xDF91	0x909E	#CJK UNIFIED IDEOGRAPH
+0xDF92	0x909F	#CJK UNIFIED IDEOGRAPH
+0xDF93	0x90A0	#CJK UNIFIED IDEOGRAPH
+0xDF94	0x90A4	#CJK UNIFIED IDEOGRAPH
+0xDF95	0x90A5	#CJK UNIFIED IDEOGRAPH
+0xDF96	0x90A7	#CJK UNIFIED IDEOGRAPH
+0xDF97	0x90A8	#CJK UNIFIED IDEOGRAPH
+0xDF98	0x90A9	#CJK UNIFIED IDEOGRAPH
+0xDF99	0x90AB	#CJK UNIFIED IDEOGRAPH
+0xDF9A	0x90AD	#CJK UNIFIED IDEOGRAPH
+0xDF9B	0x90B2	#CJK UNIFIED IDEOGRAPH
+0xDF9C	0x90B7	#CJK UNIFIED IDEOGRAPH
+0xDF9D	0x90BC	#CJK UNIFIED IDEOGRAPH
+0xDF9E	0x90BD	#CJK UNIFIED IDEOGRAPH
+0xDF9F	0x90BF	#CJK UNIFIED IDEOGRAPH
+0xDFA0	0x90C0	#CJK UNIFIED IDEOGRAPH
+0xDFA1	0x647A	#CJK UNIFIED IDEOGRAPH
+0xDFA2	0x64B7	#CJK UNIFIED IDEOGRAPH
+0xDFA3	0x64B8	#CJK UNIFIED IDEOGRAPH
+0xDFA4	0x6499	#CJK UNIFIED IDEOGRAPH
+0xDFA5	0x64BA	#CJK UNIFIED IDEOGRAPH
+0xDFA6	0x64C0	#CJK UNIFIED IDEOGRAPH
+0xDFA7	0x64D0	#CJK UNIFIED IDEOGRAPH
+0xDFA8	0x64D7	#CJK UNIFIED IDEOGRAPH
+0xDFA9	0x64E4	#CJK UNIFIED IDEOGRAPH
+0xDFAA	0x64E2	#CJK UNIFIED IDEOGRAPH
+0xDFAB	0x6509	#CJK UNIFIED IDEOGRAPH
+0xDFAC	0x6525	#CJK UNIFIED IDEOGRAPH
+0xDFAD	0x652E	#CJK UNIFIED IDEOGRAPH
+0xDFAE	0x5F0B	#CJK UNIFIED IDEOGRAPH
+0xDFAF	0x5FD2	#CJK UNIFIED IDEOGRAPH
+0xDFB0	0x7519	#CJK UNIFIED IDEOGRAPH
+0xDFB1	0x5F11	#CJK UNIFIED IDEOGRAPH
+0xDFB2	0x535F	#CJK UNIFIED IDEOGRAPH
+0xDFB3	0x53F1	#CJK UNIFIED IDEOGRAPH
+0xDFB4	0x53FD	#CJK UNIFIED IDEOGRAPH
+0xDFB5	0x53E9	#CJK UNIFIED IDEOGRAPH
+0xDFB6	0x53E8	#CJK UNIFIED IDEOGRAPH
+0xDFB7	0x53FB	#CJK UNIFIED IDEOGRAPH
+0xDFB8	0x5412	#CJK UNIFIED IDEOGRAPH
+0xDFB9	0x5416	#CJK UNIFIED IDEOGRAPH
+0xDFBA	0x5406	#CJK UNIFIED IDEOGRAPH
+0xDFBB	0x544B	#CJK UNIFIED IDEOGRAPH
+0xDFBC	0x5452	#CJK UNIFIED IDEOGRAPH
+0xDFBD	0x5453	#CJK UNIFIED IDEOGRAPH
+0xDFBE	0x5454	#CJK UNIFIED IDEOGRAPH
+0xDFBF	0x5456	#CJK UNIFIED IDEOGRAPH
+0xDFC0	0x5443	#CJK UNIFIED IDEOGRAPH
+0xDFC1	0x5421	#CJK UNIFIED IDEOGRAPH
+0xDFC2	0x5457	#CJK UNIFIED IDEOGRAPH
+0xDFC3	0x5459	#CJK UNIFIED IDEOGRAPH
+0xDFC4	0x5423	#CJK UNIFIED IDEOGRAPH
+0xDFC5	0x5432	#CJK UNIFIED IDEOGRAPH
+0xDFC6	0x5482	#CJK UNIFIED IDEOGRAPH
+0xDFC7	0x5494	#CJK UNIFIED IDEOGRAPH
+0xDFC8	0x5477	#CJK UNIFIED IDEOGRAPH
+0xDFC9	0x5471	#CJK UNIFIED IDEOGRAPH
+0xDFCA	0x5464	#CJK UNIFIED IDEOGRAPH
+0xDFCB	0x549A	#CJK UNIFIED IDEOGRAPH
+0xDFCC	0x549B	#CJK UNIFIED IDEOGRAPH
+0xDFCD	0x5484	#CJK UNIFIED IDEOGRAPH
+0xDFCE	0x5476	#CJK UNIFIED IDEOGRAPH
+0xDFCF	0x5466	#CJK UNIFIED IDEOGRAPH
+0xDFD0	0x549D	#CJK UNIFIED IDEOGRAPH
+0xDFD1	0x54D0	#CJK UNIFIED IDEOGRAPH
+0xDFD2	0x54AD	#CJK UNIFIED IDEOGRAPH
+0xDFD3	0x54C2	#CJK UNIFIED IDEOGRAPH
+0xDFD4	0x54B4	#CJK UNIFIED IDEOGRAPH
+0xDFD5	0x54D2	#CJK UNIFIED IDEOGRAPH
+0xDFD6	0x54A7	#CJK UNIFIED IDEOGRAPH
+0xDFD7	0x54A6	#CJK UNIFIED IDEOGRAPH
+0xDFD8	0x54D3	#CJK UNIFIED IDEOGRAPH
+0xDFD9	0x54D4	#CJK UNIFIED IDEOGRAPH
+0xDFDA	0x5472	#CJK UNIFIED IDEOGRAPH
+0xDFDB	0x54A3	#CJK UNIFIED IDEOGRAPH
+0xDFDC	0x54D5	#CJK UNIFIED IDEOGRAPH
+0xDFDD	0x54BB	#CJK UNIFIED IDEOGRAPH
+0xDFDE	0x54BF	#CJK UNIFIED IDEOGRAPH
+0xDFDF	0x54CC	#CJK UNIFIED IDEOGRAPH
+0xDFE0	0x54D9	#CJK UNIFIED IDEOGRAPH
+0xDFE1	0x54DA	#CJK UNIFIED IDEOGRAPH
+0xDFE2	0x54DC	#CJK UNIFIED IDEOGRAPH
+0xDFE3	0x54A9	#CJK UNIFIED IDEOGRAPH
+0xDFE4	0x54AA	#CJK UNIFIED IDEOGRAPH
+0xDFE5	0x54A4	#CJK UNIFIED IDEOGRAPH
+0xDFE6	0x54DD	#CJK UNIFIED IDEOGRAPH
+0xDFE7	0x54CF	#CJK UNIFIED IDEOGRAPH
+0xDFE8	0x54DE	#CJK UNIFIED IDEOGRAPH
+0xDFE9	0x551B	#CJK UNIFIED IDEOGRAPH
+0xDFEA	0x54E7	#CJK UNIFIED IDEOGRAPH
+0xDFEB	0x5520	#CJK UNIFIED IDEOGRAPH
+0xDFEC	0x54FD	#CJK UNIFIED IDEOGRAPH
+0xDFED	0x5514	#CJK UNIFIED IDEOGRAPH
+0xDFEE	0x54F3	#CJK UNIFIED IDEOGRAPH
+0xDFEF	0x5522	#CJK UNIFIED IDEOGRAPH
+0xDFF0	0x5523	#CJK UNIFIED IDEOGRAPH
+0xDFF1	0x550F	#CJK UNIFIED IDEOGRAPH
+0xDFF2	0x5511	#CJK UNIFIED IDEOGRAPH
+0xDFF3	0x5527	#CJK UNIFIED IDEOGRAPH
+0xDFF4	0x552A	#CJK UNIFIED IDEOGRAPH
+0xDFF5	0x5567	#CJK UNIFIED IDEOGRAPH
+0xDFF6	0x558F	#CJK UNIFIED IDEOGRAPH
+0xDFF7	0x55B5	#CJK UNIFIED IDEOGRAPH
+0xDFF8	0x5549	#CJK UNIFIED IDEOGRAPH
+0xDFF9	0x556D	#CJK UNIFIED IDEOGRAPH
+0xDFFA	0x5541	#CJK UNIFIED IDEOGRAPH
+0xDFFB	0x5555	#CJK UNIFIED IDEOGRAPH
+0xDFFC	0x553F	#CJK UNIFIED IDEOGRAPH
+0xDFFD	0x5550	#CJK UNIFIED IDEOGRAPH
+0xDFFE	0x553C	#CJK UNIFIED IDEOGRAPH
+0xE040	0x90C2	#CJK UNIFIED IDEOGRAPH
+0xE041	0x90C3	#CJK UNIFIED IDEOGRAPH
+0xE042	0x90C6	#CJK UNIFIED IDEOGRAPH
+0xE043	0x90C8	#CJK UNIFIED IDEOGRAPH
+0xE044	0x90C9	#CJK UNIFIED IDEOGRAPH
+0xE045	0x90CB	#CJK UNIFIED IDEOGRAPH
+0xE046	0x90CC	#CJK UNIFIED IDEOGRAPH
+0xE047	0x90CD	#CJK UNIFIED IDEOGRAPH
+0xE048	0x90D2	#CJK UNIFIED IDEOGRAPH
+0xE049	0x90D4	#CJK UNIFIED IDEOGRAPH
+0xE04A	0x90D5	#CJK UNIFIED IDEOGRAPH
+0xE04B	0x90D6	#CJK UNIFIED IDEOGRAPH
+0xE04C	0x90D8	#CJK UNIFIED IDEOGRAPH
+0xE04D	0x90D9	#CJK UNIFIED IDEOGRAPH
+0xE04E	0x90DA	#CJK UNIFIED IDEOGRAPH
+0xE04F	0x90DE	#CJK UNIFIED IDEOGRAPH
+0xE050	0x90DF	#CJK UNIFIED IDEOGRAPH
+0xE051	0x90E0	#CJK UNIFIED IDEOGRAPH
+0xE052	0x90E3	#CJK UNIFIED IDEOGRAPH
+0xE053	0x90E4	#CJK UNIFIED IDEOGRAPH
+0xE054	0x90E5	#CJK UNIFIED IDEOGRAPH
+0xE055	0x90E9	#CJK UNIFIED IDEOGRAPH
+0xE056	0x90EA	#CJK UNIFIED IDEOGRAPH
+0xE057	0x90EC	#CJK UNIFIED IDEOGRAPH
+0xE058	0x90EE	#CJK UNIFIED IDEOGRAPH
+0xE059	0x90F0	#CJK UNIFIED IDEOGRAPH
+0xE05A	0x90F1	#CJK UNIFIED IDEOGRAPH
+0xE05B	0x90F2	#CJK UNIFIED IDEOGRAPH
+0xE05C	0x90F3	#CJK UNIFIED IDEOGRAPH
+0xE05D	0x90F5	#CJK UNIFIED IDEOGRAPH
+0xE05E	0x90F6	#CJK UNIFIED IDEOGRAPH
+0xE05F	0x90F7	#CJK UNIFIED IDEOGRAPH
+0xE060	0x90F9	#CJK UNIFIED IDEOGRAPH
+0xE061	0x90FA	#CJK UNIFIED IDEOGRAPH
+0xE062	0x90FB	#CJK UNIFIED IDEOGRAPH
+0xE063	0x90FC	#CJK UNIFIED IDEOGRAPH
+0xE064	0x90FF	#CJK UNIFIED IDEOGRAPH
+0xE065	0x9100	#CJK UNIFIED IDEOGRAPH
+0xE066	0x9101	#CJK UNIFIED IDEOGRAPH
+0xE067	0x9103	#CJK UNIFIED IDEOGRAPH
+0xE068	0x9105	#CJK UNIFIED IDEOGRAPH
+0xE069	0x9106	#CJK UNIFIED IDEOGRAPH
+0xE06A	0x9107	#CJK UNIFIED IDEOGRAPH
+0xE06B	0x9108	#CJK UNIFIED IDEOGRAPH
+0xE06C	0x9109	#CJK UNIFIED IDEOGRAPH
+0xE06D	0x910A	#CJK UNIFIED IDEOGRAPH
+0xE06E	0x910B	#CJK UNIFIED IDEOGRAPH
+0xE06F	0x910C	#CJK UNIFIED IDEOGRAPH
+0xE070	0x910D	#CJK UNIFIED IDEOGRAPH
+0xE071	0x910E	#CJK UNIFIED IDEOGRAPH
+0xE072	0x910F	#CJK UNIFIED IDEOGRAPH
+0xE073	0x9110	#CJK UNIFIED IDEOGRAPH
+0xE074	0x9111	#CJK UNIFIED IDEOGRAPH
+0xE075	0x9112	#CJK UNIFIED IDEOGRAPH
+0xE076	0x9113	#CJK UNIFIED IDEOGRAPH
+0xE077	0x9114	#CJK UNIFIED IDEOGRAPH
+0xE078	0x9115	#CJK UNIFIED IDEOGRAPH
+0xE079	0x9116	#CJK UNIFIED IDEOGRAPH
+0xE07A	0x9117	#CJK UNIFIED IDEOGRAPH
+0xE07B	0x9118	#CJK UNIFIED IDEOGRAPH
+0xE07C	0x911A	#CJK UNIFIED IDEOGRAPH
+0xE07D	0x911B	#CJK UNIFIED IDEOGRAPH
+0xE07E	0x911C	#CJK UNIFIED IDEOGRAPH
+0xE080	0x911D	#CJK UNIFIED IDEOGRAPH
+0xE081	0x911F	#CJK UNIFIED IDEOGRAPH
+0xE082	0x9120	#CJK UNIFIED IDEOGRAPH
+0xE083	0x9121	#CJK UNIFIED IDEOGRAPH
+0xE084	0x9124	#CJK UNIFIED IDEOGRAPH
+0xE085	0x9125	#CJK UNIFIED IDEOGRAPH
+0xE086	0x9126	#CJK UNIFIED IDEOGRAPH
+0xE087	0x9127	#CJK UNIFIED IDEOGRAPH
+0xE088	0x9128	#CJK UNIFIED IDEOGRAPH
+0xE089	0x9129	#CJK UNIFIED IDEOGRAPH
+0xE08A	0x912A	#CJK UNIFIED IDEOGRAPH
+0xE08B	0x912B	#CJK UNIFIED IDEOGRAPH
+0xE08C	0x912C	#CJK UNIFIED IDEOGRAPH
+0xE08D	0x912D	#CJK UNIFIED IDEOGRAPH
+0xE08E	0x912E	#CJK UNIFIED IDEOGRAPH
+0xE08F	0x9130	#CJK UNIFIED IDEOGRAPH
+0xE090	0x9132	#CJK UNIFIED IDEOGRAPH
+0xE091	0x9133	#CJK UNIFIED IDEOGRAPH
+0xE092	0x9134	#CJK UNIFIED IDEOGRAPH
+0xE093	0x9135	#CJK UNIFIED IDEOGRAPH
+0xE094	0x9136	#CJK UNIFIED IDEOGRAPH
+0xE095	0x9137	#CJK UNIFIED IDEOGRAPH
+0xE096	0x9138	#CJK UNIFIED IDEOGRAPH
+0xE097	0x913A	#CJK UNIFIED IDEOGRAPH
+0xE098	0x913B	#CJK UNIFIED IDEOGRAPH
+0xE099	0x913C	#CJK UNIFIED IDEOGRAPH
+0xE09A	0x913D	#CJK UNIFIED IDEOGRAPH
+0xE09B	0x913E	#CJK UNIFIED IDEOGRAPH
+0xE09C	0x913F	#CJK UNIFIED IDEOGRAPH
+0xE09D	0x9140	#CJK UNIFIED IDEOGRAPH
+0xE09E	0x9141	#CJK UNIFIED IDEOGRAPH
+0xE09F	0x9142	#CJK UNIFIED IDEOGRAPH
+0xE0A0	0x9144	#CJK UNIFIED IDEOGRAPH
+0xE0A1	0x5537	#CJK UNIFIED IDEOGRAPH
+0xE0A2	0x5556	#CJK UNIFIED IDEOGRAPH
+0xE0A3	0x5575	#CJK UNIFIED IDEOGRAPH
+0xE0A4	0x5576	#CJK UNIFIED IDEOGRAPH
+0xE0A5	0x5577	#CJK UNIFIED IDEOGRAPH
+0xE0A6	0x5533	#CJK UNIFIED IDEOGRAPH
+0xE0A7	0x5530	#CJK UNIFIED IDEOGRAPH
+0xE0A8	0x555C	#CJK UNIFIED IDEOGRAPH
+0xE0A9	0x558B	#CJK UNIFIED IDEOGRAPH
+0xE0AA	0x55D2	#CJK UNIFIED IDEOGRAPH
+0xE0AB	0x5583	#CJK UNIFIED IDEOGRAPH
+0xE0AC	0x55B1	#CJK UNIFIED IDEOGRAPH
+0xE0AD	0x55B9	#CJK UNIFIED IDEOGRAPH
+0xE0AE	0x5588	#CJK UNIFIED IDEOGRAPH
+0xE0AF	0x5581	#CJK UNIFIED IDEOGRAPH
+0xE0B0	0x559F	#CJK UNIFIED IDEOGRAPH
+0xE0B1	0x557E	#CJK UNIFIED IDEOGRAPH
+0xE0B2	0x55D6	#CJK UNIFIED IDEOGRAPH
+0xE0B3	0x5591	#CJK UNIFIED IDEOGRAPH
+0xE0B4	0x557B	#CJK UNIFIED IDEOGRAPH
+0xE0B5	0x55DF	#CJK UNIFIED IDEOGRAPH
+0xE0B6	0x55BD	#CJK UNIFIED IDEOGRAPH
+0xE0B7	0x55BE	#CJK UNIFIED IDEOGRAPH
+0xE0B8	0x5594	#CJK UNIFIED IDEOGRAPH
+0xE0B9	0x5599	#CJK UNIFIED IDEOGRAPH
+0xE0BA	0x55EA	#CJK UNIFIED IDEOGRAPH
+0xE0BB	0x55F7	#CJK UNIFIED IDEOGRAPH
+0xE0BC	0x55C9	#CJK UNIFIED IDEOGRAPH
+0xE0BD	0x561F	#CJK UNIFIED IDEOGRAPH
+0xE0BE	0x55D1	#CJK UNIFIED IDEOGRAPH
+0xE0BF	0x55EB	#CJK UNIFIED IDEOGRAPH
+0xE0C0	0x55EC	#CJK UNIFIED IDEOGRAPH
+0xE0C1	0x55D4	#CJK UNIFIED IDEOGRAPH
+0xE0C2	0x55E6	#CJK UNIFIED IDEOGRAPH
+0xE0C3	0x55DD	#CJK UNIFIED IDEOGRAPH
+0xE0C4	0x55C4	#CJK UNIFIED IDEOGRAPH
+0xE0C5	0x55EF	#CJK UNIFIED IDEOGRAPH
+0xE0C6	0x55E5	#CJK UNIFIED IDEOGRAPH
+0xE0C7	0x55F2	#CJK UNIFIED IDEOGRAPH
+0xE0C8	0x55F3	#CJK UNIFIED IDEOGRAPH
+0xE0C9	0x55CC	#CJK UNIFIED IDEOGRAPH
+0xE0CA	0x55CD	#CJK UNIFIED IDEOGRAPH
+0xE0CB	0x55E8	#CJK UNIFIED IDEOGRAPH
+0xE0CC	0x55F5	#CJK UNIFIED IDEOGRAPH
+0xE0CD	0x55E4	#CJK UNIFIED IDEOGRAPH
+0xE0CE	0x8F94	#CJK UNIFIED IDEOGRAPH
+0xE0CF	0x561E	#CJK UNIFIED IDEOGRAPH
+0xE0D0	0x5608	#CJK UNIFIED IDEOGRAPH
+0xE0D1	0x560C	#CJK UNIFIED IDEOGRAPH
+0xE0D2	0x5601	#CJK UNIFIED IDEOGRAPH
+0xE0D3	0x5624	#CJK UNIFIED IDEOGRAPH
+0xE0D4	0x5623	#CJK UNIFIED IDEOGRAPH
+0xE0D5	0x55FE	#CJK UNIFIED IDEOGRAPH
+0xE0D6	0x5600	#CJK UNIFIED IDEOGRAPH
+0xE0D7	0x5627	#CJK UNIFIED IDEOGRAPH
+0xE0D8	0x562D	#CJK UNIFIED IDEOGRAPH
+0xE0D9	0x5658	#CJK UNIFIED IDEOGRAPH
+0xE0DA	0x5639	#CJK UNIFIED IDEOGRAPH
+0xE0DB	0x5657	#CJK UNIFIED IDEOGRAPH
+0xE0DC	0x562C	#CJK UNIFIED IDEOGRAPH
+0xE0DD	0x564D	#CJK UNIFIED IDEOGRAPH
+0xE0DE	0x5662	#CJK UNIFIED IDEOGRAPH
+0xE0DF	0x5659	#CJK UNIFIED IDEOGRAPH
+0xE0E0	0x565C	#CJK UNIFIED IDEOGRAPH
+0xE0E1	0x564C	#CJK UNIFIED IDEOGRAPH
+0xE0E2	0x5654	#CJK UNIFIED IDEOGRAPH
+0xE0E3	0x5686	#CJK UNIFIED IDEOGRAPH
+0xE0E4	0x5664	#CJK UNIFIED IDEOGRAPH
+0xE0E5	0x5671	#CJK UNIFIED IDEOGRAPH
+0xE0E6	0x566B	#CJK UNIFIED IDEOGRAPH
+0xE0E7	0x567B	#CJK UNIFIED IDEOGRAPH
+0xE0E8	0x567C	#CJK UNIFIED IDEOGRAPH
+0xE0E9	0x5685	#CJK UNIFIED IDEOGRAPH
+0xE0EA	0x5693	#CJK UNIFIED IDEOGRAPH
+0xE0EB	0x56AF	#CJK UNIFIED IDEOGRAPH
+0xE0EC	0x56D4	#CJK UNIFIED IDEOGRAPH
+0xE0ED	0x56D7	#CJK UNIFIED IDEOGRAPH
+0xE0EE	0x56DD	#CJK UNIFIED IDEOGRAPH
+0xE0EF	0x56E1	#CJK UNIFIED IDEOGRAPH
+0xE0F0	0x56F5	#CJK UNIFIED IDEOGRAPH
+0xE0F1	0x56EB	#CJK UNIFIED IDEOGRAPH
+0xE0F2	0x56F9	#CJK UNIFIED IDEOGRAPH
+0xE0F3	0x56FF	#CJK UNIFIED IDEOGRAPH
+0xE0F4	0x5704	#CJK UNIFIED IDEOGRAPH
+0xE0F5	0x570A	#CJK UNIFIED IDEOGRAPH
+0xE0F6	0x5709	#CJK UNIFIED IDEOGRAPH
+0xE0F7	0x571C	#CJK UNIFIED IDEOGRAPH
+0xE0F8	0x5E0F	#CJK UNIFIED IDEOGRAPH
+0xE0F9	0x5E19	#CJK UNIFIED IDEOGRAPH
+0xE0FA	0x5E14	#CJK UNIFIED IDEOGRAPH
+0xE0FB	0x5E11	#CJK UNIFIED IDEOGRAPH
+0xE0FC	0x5E31	#CJK UNIFIED IDEOGRAPH
+0xE0FD	0x5E3B	#CJK UNIFIED IDEOGRAPH
+0xE0FE	0x5E3C	#CJK UNIFIED IDEOGRAPH
+0xE140	0x9145	#CJK UNIFIED IDEOGRAPH
+0xE141	0x9147	#CJK UNIFIED IDEOGRAPH
+0xE142	0x9148	#CJK UNIFIED IDEOGRAPH
+0xE143	0x9151	#CJK UNIFIED IDEOGRAPH
+0xE144	0x9153	#CJK UNIFIED IDEOGRAPH
+0xE145	0x9154	#CJK UNIFIED IDEOGRAPH
+0xE146	0x9155	#CJK UNIFIED IDEOGRAPH
+0xE147	0x9156	#CJK UNIFIED IDEOGRAPH
+0xE148	0x9158	#CJK UNIFIED IDEOGRAPH
+0xE149	0x9159	#CJK UNIFIED IDEOGRAPH
+0xE14A	0x915B	#CJK UNIFIED IDEOGRAPH
+0xE14B	0x915C	#CJK UNIFIED IDEOGRAPH
+0xE14C	0x915F	#CJK UNIFIED IDEOGRAPH
+0xE14D	0x9160	#CJK UNIFIED IDEOGRAPH
+0xE14E	0x9166	#CJK UNIFIED IDEOGRAPH
+0xE14F	0x9167	#CJK UNIFIED IDEOGRAPH
+0xE150	0x9168	#CJK UNIFIED IDEOGRAPH
+0xE151	0x916B	#CJK UNIFIED IDEOGRAPH
+0xE152	0x916D	#CJK UNIFIED IDEOGRAPH
+0xE153	0x9173	#CJK UNIFIED IDEOGRAPH
+0xE154	0x917A	#CJK UNIFIED IDEOGRAPH
+0xE155	0x917B	#CJK UNIFIED IDEOGRAPH
+0xE156	0x917C	#CJK UNIFIED IDEOGRAPH
+0xE157	0x9180	#CJK UNIFIED IDEOGRAPH
+0xE158	0x9181	#CJK UNIFIED IDEOGRAPH
+0xE159	0x9182	#CJK UNIFIED IDEOGRAPH
+0xE15A	0x9183	#CJK UNIFIED IDEOGRAPH
+0xE15B	0x9184	#CJK UNIFIED IDEOGRAPH
+0xE15C	0x9186	#CJK UNIFIED IDEOGRAPH
+0xE15D	0x9188	#CJK UNIFIED IDEOGRAPH
+0xE15E	0x918A	#CJK UNIFIED IDEOGRAPH
+0xE15F	0x918E	#CJK UNIFIED IDEOGRAPH
+0xE160	0x918F	#CJK UNIFIED IDEOGRAPH
+0xE161	0x9193	#CJK UNIFIED IDEOGRAPH
+0xE162	0x9194	#CJK UNIFIED IDEOGRAPH
+0xE163	0x9195	#CJK UNIFIED IDEOGRAPH
+0xE164	0x9196	#CJK UNIFIED IDEOGRAPH
+0xE165	0x9197	#CJK UNIFIED IDEOGRAPH
+0xE166	0x9198	#CJK UNIFIED IDEOGRAPH
+0xE167	0x9199	#CJK UNIFIED IDEOGRAPH
+0xE168	0x919C	#CJK UNIFIED IDEOGRAPH
+0xE169	0x919D	#CJK UNIFIED IDEOGRAPH
+0xE16A	0x919E	#CJK UNIFIED IDEOGRAPH
+0xE16B	0x919F	#CJK UNIFIED IDEOGRAPH
+0xE16C	0x91A0	#CJK UNIFIED IDEOGRAPH
+0xE16D	0x91A1	#CJK UNIFIED IDEOGRAPH
+0xE16E	0x91A4	#CJK UNIFIED IDEOGRAPH
+0xE16F	0x91A5	#CJK UNIFIED IDEOGRAPH
+0xE170	0x91A6	#CJK UNIFIED IDEOGRAPH
+0xE171	0x91A7	#CJK UNIFIED IDEOGRAPH
+0xE172	0x91A8	#CJK UNIFIED IDEOGRAPH
+0xE173	0x91A9	#CJK UNIFIED IDEOGRAPH
+0xE174	0x91AB	#CJK UNIFIED IDEOGRAPH
+0xE175	0x91AC	#CJK UNIFIED IDEOGRAPH
+0xE176	0x91B0	#CJK UNIFIED IDEOGRAPH
+0xE177	0x91B1	#CJK UNIFIED IDEOGRAPH
+0xE178	0x91B2	#CJK UNIFIED IDEOGRAPH
+0xE179	0x91B3	#CJK UNIFIED IDEOGRAPH
+0xE17A	0x91B6	#CJK UNIFIED IDEOGRAPH
+0xE17B	0x91B7	#CJK UNIFIED IDEOGRAPH
+0xE17C	0x91B8	#CJK UNIFIED IDEOGRAPH
+0xE17D	0x91B9	#CJK UNIFIED IDEOGRAPH
+0xE17E	0x91BB	#CJK UNIFIED IDEOGRAPH
+0xE180	0x91BC	#CJK UNIFIED IDEOGRAPH
+0xE181	0x91BD	#CJK UNIFIED IDEOGRAPH
+0xE182	0x91BE	#CJK UNIFIED IDEOGRAPH
+0xE183	0x91BF	#CJK UNIFIED IDEOGRAPH
+0xE184	0x91C0	#CJK UNIFIED IDEOGRAPH
+0xE185	0x91C1	#CJK UNIFIED IDEOGRAPH
+0xE186	0x91C2	#CJK UNIFIED IDEOGRAPH
+0xE187	0x91C3	#CJK UNIFIED IDEOGRAPH
+0xE188	0x91C4	#CJK UNIFIED IDEOGRAPH
+0xE189	0x91C5	#CJK UNIFIED IDEOGRAPH
+0xE18A	0x91C6	#CJK UNIFIED IDEOGRAPH
+0xE18B	0x91C8	#CJK UNIFIED IDEOGRAPH
+0xE18C	0x91CB	#CJK UNIFIED IDEOGRAPH
+0xE18D	0x91D0	#CJK UNIFIED IDEOGRAPH
+0xE18E	0x91D2	#CJK UNIFIED IDEOGRAPH
+0xE18F	0x91D3	#CJK UNIFIED IDEOGRAPH
+0xE190	0x91D4	#CJK UNIFIED IDEOGRAPH
+0xE191	0x91D5	#CJK UNIFIED IDEOGRAPH
+0xE192	0x91D6	#CJK UNIFIED IDEOGRAPH
+0xE193	0x91D7	#CJK UNIFIED IDEOGRAPH
+0xE194	0x91D8	#CJK UNIFIED IDEOGRAPH
+0xE195	0x91D9	#CJK UNIFIED IDEOGRAPH
+0xE196	0x91DA	#CJK UNIFIED IDEOGRAPH
+0xE197	0x91DB	#CJK UNIFIED IDEOGRAPH
+0xE198	0x91DD	#CJK UNIFIED IDEOGRAPH
+0xE199	0x91DE	#CJK UNIFIED IDEOGRAPH
+0xE19A	0x91DF	#CJK UNIFIED IDEOGRAPH
+0xE19B	0x91E0	#CJK UNIFIED IDEOGRAPH
+0xE19C	0x91E1	#CJK UNIFIED IDEOGRAPH
+0xE19D	0x91E2	#CJK UNIFIED IDEOGRAPH
+0xE19E	0x91E3	#CJK UNIFIED IDEOGRAPH
+0xE19F	0x91E4	#CJK UNIFIED IDEOGRAPH
+0xE1A0	0x91E5	#CJK UNIFIED IDEOGRAPH
+0xE1A1	0x5E37	#CJK UNIFIED IDEOGRAPH
+0xE1A2	0x5E44	#CJK UNIFIED IDEOGRAPH
+0xE1A3	0x5E54	#CJK UNIFIED IDEOGRAPH
+0xE1A4	0x5E5B	#CJK UNIFIED IDEOGRAPH
+0xE1A5	0x5E5E	#CJK UNIFIED IDEOGRAPH
+0xE1A6	0x5E61	#CJK UNIFIED IDEOGRAPH
+0xE1A7	0x5C8C	#CJK UNIFIED IDEOGRAPH
+0xE1A8	0x5C7A	#CJK UNIFIED IDEOGRAPH
+0xE1A9	0x5C8D	#CJK UNIFIED IDEOGRAPH
+0xE1AA	0x5C90	#CJK UNIFIED IDEOGRAPH
+0xE1AB	0x5C96	#CJK UNIFIED IDEOGRAPH
+0xE1AC	0x5C88	#CJK UNIFIED IDEOGRAPH
+0xE1AD	0x5C98	#CJK UNIFIED IDEOGRAPH
+0xE1AE	0x5C99	#CJK UNIFIED IDEOGRAPH
+0xE1AF	0x5C91	#CJK UNIFIED IDEOGRAPH
+0xE1B0	0x5C9A	#CJK UNIFIED IDEOGRAPH
+0xE1B1	0x5C9C	#CJK UNIFIED IDEOGRAPH
+0xE1B2	0x5CB5	#CJK UNIFIED IDEOGRAPH
+0xE1B3	0x5CA2	#CJK UNIFIED IDEOGRAPH
+0xE1B4	0x5CBD	#CJK UNIFIED IDEOGRAPH
+0xE1B5	0x5CAC	#CJK UNIFIED IDEOGRAPH
+0xE1B6	0x5CAB	#CJK UNIFIED IDEOGRAPH
+0xE1B7	0x5CB1	#CJK UNIFIED IDEOGRAPH
+0xE1B8	0x5CA3	#CJK UNIFIED IDEOGRAPH
+0xE1B9	0x5CC1	#CJK UNIFIED IDEOGRAPH
+0xE1BA	0x5CB7	#CJK UNIFIED IDEOGRAPH
+0xE1BB	0x5CC4	#CJK UNIFIED IDEOGRAPH
+0xE1BC	0x5CD2	#CJK UNIFIED IDEOGRAPH
+0xE1BD	0x5CE4	#CJK UNIFIED IDEOGRAPH
+0xE1BE	0x5CCB	#CJK UNIFIED IDEOGRAPH
+0xE1BF	0x5CE5	#CJK UNIFIED IDEOGRAPH
+0xE1C0	0x5D02	#CJK UNIFIED IDEOGRAPH
+0xE1C1	0x5D03	#CJK UNIFIED IDEOGRAPH
+0xE1C2	0x5D27	#CJK UNIFIED IDEOGRAPH
+0xE1C3	0x5D26	#CJK UNIFIED IDEOGRAPH
+0xE1C4	0x5D2E	#CJK UNIFIED IDEOGRAPH
+0xE1C5	0x5D24	#CJK UNIFIED IDEOGRAPH
+0xE1C6	0x5D1E	#CJK UNIFIED IDEOGRAPH
+0xE1C7	0x5D06	#CJK UNIFIED IDEOGRAPH
+0xE1C8	0x5D1B	#CJK UNIFIED IDEOGRAPH
+0xE1C9	0x5D58	#CJK UNIFIED IDEOGRAPH
+0xE1CA	0x5D3E	#CJK UNIFIED IDEOGRAPH
+0xE1CB	0x5D34	#CJK UNIFIED IDEOGRAPH
+0xE1CC	0x5D3D	#CJK UNIFIED IDEOGRAPH
+0xE1CD	0x5D6C	#CJK UNIFIED IDEOGRAPH
+0xE1CE	0x5D5B	#CJK UNIFIED IDEOGRAPH
+0xE1CF	0x5D6F	#CJK UNIFIED IDEOGRAPH
+0xE1D0	0x5D5D	#CJK UNIFIED IDEOGRAPH
+0xE1D1	0x5D6B	#CJK UNIFIED IDEOGRAPH
+0xE1D2	0x5D4B	#CJK UNIFIED IDEOGRAPH
+0xE1D3	0x5D4A	#CJK UNIFIED IDEOGRAPH
+0xE1D4	0x5D69	#CJK UNIFIED IDEOGRAPH
+0xE1D5	0x5D74	#CJK UNIFIED IDEOGRAPH
+0xE1D6	0x5D82	#CJK UNIFIED IDEOGRAPH
+0xE1D7	0x5D99	#CJK UNIFIED IDEOGRAPH
+0xE1D8	0x5D9D	#CJK UNIFIED IDEOGRAPH
+0xE1D9	0x8C73	#CJK UNIFIED IDEOGRAPH
+0xE1DA	0x5DB7	#CJK UNIFIED IDEOGRAPH
+0xE1DB	0x5DC5	#CJK UNIFIED IDEOGRAPH
+0xE1DC	0x5F73	#CJK UNIFIED IDEOGRAPH
+0xE1DD	0x5F77	#CJK UNIFIED IDEOGRAPH
+0xE1DE	0x5F82	#CJK UNIFIED IDEOGRAPH
+0xE1DF	0x5F87	#CJK UNIFIED IDEOGRAPH
+0xE1E0	0x5F89	#CJK UNIFIED IDEOGRAPH
+0xE1E1	0x5F8C	#CJK UNIFIED IDEOGRAPH
+0xE1E2	0x5F95	#CJK UNIFIED IDEOGRAPH
+0xE1E3	0x5F99	#CJK UNIFIED IDEOGRAPH
+0xE1E4	0x5F9C	#CJK UNIFIED IDEOGRAPH
+0xE1E5	0x5FA8	#CJK UNIFIED IDEOGRAPH
+0xE1E6	0x5FAD	#CJK UNIFIED IDEOGRAPH
+0xE1E7	0x5FB5	#CJK UNIFIED IDEOGRAPH
+0xE1E8	0x5FBC	#CJK UNIFIED IDEOGRAPH
+0xE1E9	0x8862	#CJK UNIFIED IDEOGRAPH
+0xE1EA	0x5F61	#CJK UNIFIED IDEOGRAPH
+0xE1EB	0x72AD	#CJK UNIFIED IDEOGRAPH
+0xE1EC	0x72B0	#CJK UNIFIED IDEOGRAPH
+0xE1ED	0x72B4	#CJK UNIFIED IDEOGRAPH
+0xE1EE	0x72B7	#CJK UNIFIED IDEOGRAPH
+0xE1EF	0x72B8	#CJK UNIFIED IDEOGRAPH
+0xE1F0	0x72C3	#CJK UNIFIED IDEOGRAPH
+0xE1F1	0x72C1	#CJK UNIFIED IDEOGRAPH
+0xE1F2	0x72CE	#CJK UNIFIED IDEOGRAPH
+0xE1F3	0x72CD	#CJK UNIFIED IDEOGRAPH
+0xE1F4	0x72D2	#CJK UNIFIED IDEOGRAPH
+0xE1F5	0x72E8	#CJK UNIFIED IDEOGRAPH
+0xE1F6	0x72EF	#CJK UNIFIED IDEOGRAPH
+0xE1F7	0x72E9	#CJK UNIFIED IDEOGRAPH
+0xE1F8	0x72F2	#CJK UNIFIED IDEOGRAPH
+0xE1F9	0x72F4	#CJK UNIFIED IDEOGRAPH
+0xE1FA	0x72F7	#CJK UNIFIED IDEOGRAPH
+0xE1FB	0x7301	#CJK UNIFIED IDEOGRAPH
+0xE1FC	0x72F3	#CJK UNIFIED IDEOGRAPH
+0xE1FD	0x7303	#CJK UNIFIED IDEOGRAPH
+0xE1FE	0x72FA	#CJK UNIFIED IDEOGRAPH
+0xE240	0x91E6	#CJK UNIFIED IDEOGRAPH
+0xE241	0x91E7	#CJK UNIFIED IDEOGRAPH
+0xE242	0x91E8	#CJK UNIFIED IDEOGRAPH
+0xE243	0x91E9	#CJK UNIFIED IDEOGRAPH
+0xE244	0x91EA	#CJK UNIFIED IDEOGRAPH
+0xE245	0x91EB	#CJK UNIFIED IDEOGRAPH
+0xE246	0x91EC	#CJK UNIFIED IDEOGRAPH
+0xE247	0x91ED	#CJK UNIFIED IDEOGRAPH
+0xE248	0x91EE	#CJK UNIFIED IDEOGRAPH
+0xE249	0x91EF	#CJK UNIFIED IDEOGRAPH
+0xE24A	0x91F0	#CJK UNIFIED IDEOGRAPH
+0xE24B	0x91F1	#CJK UNIFIED IDEOGRAPH
+0xE24C	0x91F2	#CJK UNIFIED IDEOGRAPH
+0xE24D	0x91F3	#CJK UNIFIED IDEOGRAPH
+0xE24E	0x91F4	#CJK UNIFIED IDEOGRAPH
+0xE24F	0x91F5	#CJK UNIFIED IDEOGRAPH
+0xE250	0x91F6	#CJK UNIFIED IDEOGRAPH
+0xE251	0x91F7	#CJK UNIFIED IDEOGRAPH
+0xE252	0x91F8	#CJK UNIFIED IDEOGRAPH
+0xE253	0x91F9	#CJK UNIFIED IDEOGRAPH
+0xE254	0x91FA	#CJK UNIFIED IDEOGRAPH
+0xE255	0x91FB	#CJK UNIFIED IDEOGRAPH
+0xE256	0x91FC	#CJK UNIFIED IDEOGRAPH
+0xE257	0x91FD	#CJK UNIFIED IDEOGRAPH
+0xE258	0x91FE	#CJK UNIFIED IDEOGRAPH
+0xE259	0x91FF	#CJK UNIFIED IDEOGRAPH
+0xE25A	0x9200	#CJK UNIFIED IDEOGRAPH
+0xE25B	0x9201	#CJK UNIFIED IDEOGRAPH
+0xE25C	0x9202	#CJK UNIFIED IDEOGRAPH
+0xE25D	0x9203	#CJK UNIFIED IDEOGRAPH
+0xE25E	0x9204	#CJK UNIFIED IDEOGRAPH
+0xE25F	0x9205	#CJK UNIFIED IDEOGRAPH
+0xE260	0x9206	#CJK UNIFIED IDEOGRAPH
+0xE261	0x9207	#CJK UNIFIED IDEOGRAPH
+0xE262	0x9208	#CJK UNIFIED IDEOGRAPH
+0xE263	0x9209	#CJK UNIFIED IDEOGRAPH
+0xE264	0x920A	#CJK UNIFIED IDEOGRAPH
+0xE265	0x920B	#CJK UNIFIED IDEOGRAPH
+0xE266	0x920C	#CJK UNIFIED IDEOGRAPH
+0xE267	0x920D	#CJK UNIFIED IDEOGRAPH
+0xE268	0x920E	#CJK UNIFIED IDEOGRAPH
+0xE269	0x920F	#CJK UNIFIED IDEOGRAPH
+0xE26A	0x9210	#CJK UNIFIED IDEOGRAPH
+0xE26B	0x9211	#CJK UNIFIED IDEOGRAPH
+0xE26C	0x9212	#CJK UNIFIED IDEOGRAPH
+0xE26D	0x9213	#CJK UNIFIED IDEOGRAPH
+0xE26E	0x9214	#CJK UNIFIED IDEOGRAPH
+0xE26F	0x9215	#CJK UNIFIED IDEOGRAPH
+0xE270	0x9216	#CJK UNIFIED IDEOGRAPH
+0xE271	0x9217	#CJK UNIFIED IDEOGRAPH
+0xE272	0x9218	#CJK UNIFIED IDEOGRAPH
+0xE273	0x9219	#CJK UNIFIED IDEOGRAPH
+0xE274	0x921A	#CJK UNIFIED IDEOGRAPH
+0xE275	0x921B	#CJK UNIFIED IDEOGRAPH
+0xE276	0x921C	#CJK UNIFIED IDEOGRAPH
+0xE277	0x921D	#CJK UNIFIED IDEOGRAPH
+0xE278	0x921E	#CJK UNIFIED IDEOGRAPH
+0xE279	0x921F	#CJK UNIFIED IDEOGRAPH
+0xE27A	0x9220	#CJK UNIFIED IDEOGRAPH
+0xE27B	0x9221	#CJK UNIFIED IDEOGRAPH
+0xE27C	0x9222	#CJK UNIFIED IDEOGRAPH
+0xE27D	0x9223	#CJK UNIFIED IDEOGRAPH
+0xE27E	0x9224	#CJK UNIFIED IDEOGRAPH
+0xE280	0x9225	#CJK UNIFIED IDEOGRAPH
+0xE281	0x9226	#CJK UNIFIED IDEOGRAPH
+0xE282	0x9227	#CJK UNIFIED IDEOGRAPH
+0xE283	0x9228	#CJK UNIFIED IDEOGRAPH
+0xE284	0x9229	#CJK UNIFIED IDEOGRAPH
+0xE285	0x922A	#CJK UNIFIED IDEOGRAPH
+0xE286	0x922B	#CJK UNIFIED IDEOGRAPH
+0xE287	0x922C	#CJK UNIFIED IDEOGRAPH
+0xE288	0x922D	#CJK UNIFIED IDEOGRAPH
+0xE289	0x922E	#CJK UNIFIED IDEOGRAPH
+0xE28A	0x922F	#CJK UNIFIED IDEOGRAPH
+0xE28B	0x9230	#CJK UNIFIED IDEOGRAPH
+0xE28C	0x9231	#CJK UNIFIED IDEOGRAPH
+0xE28D	0x9232	#CJK UNIFIED IDEOGRAPH
+0xE28E	0x9233	#CJK UNIFIED IDEOGRAPH
+0xE28F	0x9234	#CJK UNIFIED IDEOGRAPH
+0xE290	0x9235	#CJK UNIFIED IDEOGRAPH
+0xE291	0x9236	#CJK UNIFIED IDEOGRAPH
+0xE292	0x9237	#CJK UNIFIED IDEOGRAPH
+0xE293	0x9238	#CJK UNIFIED IDEOGRAPH
+0xE294	0x9239	#CJK UNIFIED IDEOGRAPH
+0xE295	0x923A	#CJK UNIFIED IDEOGRAPH
+0xE296	0x923B	#CJK UNIFIED IDEOGRAPH
+0xE297	0x923C	#CJK UNIFIED IDEOGRAPH
+0xE298	0x923D	#CJK UNIFIED IDEOGRAPH
+0xE299	0x923E	#CJK UNIFIED IDEOGRAPH
+0xE29A	0x923F	#CJK UNIFIED IDEOGRAPH
+0xE29B	0x9240	#CJK UNIFIED IDEOGRAPH
+0xE29C	0x9241	#CJK UNIFIED IDEOGRAPH
+0xE29D	0x9242	#CJK UNIFIED IDEOGRAPH
+0xE29E	0x9243	#CJK UNIFIED IDEOGRAPH
+0xE29F	0x9244	#CJK UNIFIED IDEOGRAPH
+0xE2A0	0x9245	#CJK UNIFIED IDEOGRAPH
+0xE2A1	0x72FB	#CJK UNIFIED IDEOGRAPH
+0xE2A2	0x7317	#CJK UNIFIED IDEOGRAPH
+0xE2A3	0x7313	#CJK UNIFIED IDEOGRAPH
+0xE2A4	0x7321	#CJK UNIFIED IDEOGRAPH
+0xE2A5	0x730A	#CJK UNIFIED IDEOGRAPH
+0xE2A6	0x731E	#CJK UNIFIED IDEOGRAPH
+0xE2A7	0x731D	#CJK UNIFIED IDEOGRAPH
+0xE2A8	0x7315	#CJK UNIFIED IDEOGRAPH
+0xE2A9	0x7322	#CJK UNIFIED IDEOGRAPH
+0xE2AA	0x7339	#CJK UNIFIED IDEOGRAPH
+0xE2AB	0x7325	#CJK UNIFIED IDEOGRAPH
+0xE2AC	0x732C	#CJK UNIFIED IDEOGRAPH
+0xE2AD	0x7338	#CJK UNIFIED IDEOGRAPH
+0xE2AE	0x7331	#CJK UNIFIED IDEOGRAPH
+0xE2AF	0x7350	#CJK UNIFIED IDEOGRAPH
+0xE2B0	0x734D	#CJK UNIFIED IDEOGRAPH
+0xE2B1	0x7357	#CJK UNIFIED IDEOGRAPH
+0xE2B2	0x7360	#CJK UNIFIED IDEOGRAPH
+0xE2B3	0x736C	#CJK UNIFIED IDEOGRAPH
+0xE2B4	0x736F	#CJK UNIFIED IDEOGRAPH
+0xE2B5	0x737E	#CJK UNIFIED IDEOGRAPH
+0xE2B6	0x821B	#CJK UNIFIED IDEOGRAPH
+0xE2B7	0x5925	#CJK UNIFIED IDEOGRAPH
+0xE2B8	0x98E7	#CJK UNIFIED IDEOGRAPH
+0xE2B9	0x5924	#CJK UNIFIED IDEOGRAPH
+0xE2BA	0x5902	#CJK UNIFIED IDEOGRAPH
+0xE2BB	0x9963	#CJK UNIFIED IDEOGRAPH
+0xE2BC	0x9967	#CJK UNIFIED IDEOGRAPH
+0xE2BD	0x9968	#CJK UNIFIED IDEOGRAPH
+0xE2BE	0x9969	#CJK UNIFIED IDEOGRAPH
+0xE2BF	0x996A	#CJK UNIFIED IDEOGRAPH
+0xE2C0	0x996B	#CJK UNIFIED IDEOGRAPH
+0xE2C1	0x996C	#CJK UNIFIED IDEOGRAPH
+0xE2C2	0x9974	#CJK UNIFIED IDEOGRAPH
+0xE2C3	0x9977	#CJK UNIFIED IDEOGRAPH
+0xE2C4	0x997D	#CJK UNIFIED IDEOGRAPH
+0xE2C5	0x9980	#CJK UNIFIED IDEOGRAPH
+0xE2C6	0x9984	#CJK UNIFIED IDEOGRAPH
+0xE2C7	0x9987	#CJK UNIFIED IDEOGRAPH
+0xE2C8	0x998A	#CJK UNIFIED IDEOGRAPH
+0xE2C9	0x998D	#CJK UNIFIED IDEOGRAPH
+0xE2CA	0x9990	#CJK UNIFIED IDEOGRAPH
+0xE2CB	0x9991	#CJK UNIFIED IDEOGRAPH
+0xE2CC	0x9993	#CJK UNIFIED IDEOGRAPH
+0xE2CD	0x9994	#CJK UNIFIED IDEOGRAPH
+0xE2CE	0x9995	#CJK UNIFIED IDEOGRAPH
+0xE2CF	0x5E80	#CJK UNIFIED IDEOGRAPH
+0xE2D0	0x5E91	#CJK UNIFIED IDEOGRAPH
+0xE2D1	0x5E8B	#CJK UNIFIED IDEOGRAPH
+0xE2D2	0x5E96	#CJK UNIFIED IDEOGRAPH
+0xE2D3	0x5EA5	#CJK UNIFIED IDEOGRAPH
+0xE2D4	0x5EA0	#CJK UNIFIED IDEOGRAPH
+0xE2D5	0x5EB9	#CJK UNIFIED IDEOGRAPH
+0xE2D6	0x5EB5	#CJK UNIFIED IDEOGRAPH
+0xE2D7	0x5EBE	#CJK UNIFIED IDEOGRAPH
+0xE2D8	0x5EB3	#CJK UNIFIED IDEOGRAPH
+0xE2D9	0x8D53	#CJK UNIFIED IDEOGRAPH
+0xE2DA	0x5ED2	#CJK UNIFIED IDEOGRAPH
+0xE2DB	0x5ED1	#CJK UNIFIED IDEOGRAPH
+0xE2DC	0x5EDB	#CJK UNIFIED IDEOGRAPH
+0xE2DD	0x5EE8	#CJK UNIFIED IDEOGRAPH
+0xE2DE	0x5EEA	#CJK UNIFIED IDEOGRAPH
+0xE2DF	0x81BA	#CJK UNIFIED IDEOGRAPH
+0xE2E0	0x5FC4	#CJK UNIFIED IDEOGRAPH
+0xE2E1	0x5FC9	#CJK UNIFIED IDEOGRAPH
+0xE2E2	0x5FD6	#CJK UNIFIED IDEOGRAPH
+0xE2E3	0x5FCF	#CJK UNIFIED IDEOGRAPH
+0xE2E4	0x6003	#CJK UNIFIED IDEOGRAPH
+0xE2E5	0x5FEE	#CJK UNIFIED IDEOGRAPH
+0xE2E6	0x6004	#CJK UNIFIED IDEOGRAPH
+0xE2E7	0x5FE1	#CJK UNIFIED IDEOGRAPH
+0xE2E8	0x5FE4	#CJK UNIFIED IDEOGRAPH
+0xE2E9	0x5FFE	#CJK UNIFIED IDEOGRAPH
+0xE2EA	0x6005	#CJK UNIFIED IDEOGRAPH
+0xE2EB	0x6006	#CJK UNIFIED IDEOGRAPH
+0xE2EC	0x5FEA	#CJK UNIFIED IDEOGRAPH
+0xE2ED	0x5FED	#CJK UNIFIED IDEOGRAPH
+0xE2EE	0x5FF8	#CJK UNIFIED IDEOGRAPH
+0xE2EF	0x6019	#CJK UNIFIED IDEOGRAPH
+0xE2F0	0x6035	#CJK UNIFIED IDEOGRAPH
+0xE2F1	0x6026	#CJK UNIFIED IDEOGRAPH
+0xE2F2	0x601B	#CJK UNIFIED IDEOGRAPH
+0xE2F3	0x600F	#CJK UNIFIED IDEOGRAPH
+0xE2F4	0x600D	#CJK UNIFIED IDEOGRAPH
+0xE2F5	0x6029	#CJK UNIFIED IDEOGRAPH
+0xE2F6	0x602B	#CJK UNIFIED IDEOGRAPH
+0xE2F7	0x600A	#CJK UNIFIED IDEOGRAPH
+0xE2F8	0x603F	#CJK UNIFIED IDEOGRAPH
+0xE2F9	0x6021	#CJK UNIFIED IDEOGRAPH
+0xE2FA	0x6078	#CJK UNIFIED IDEOGRAPH
+0xE2FB	0x6079	#CJK UNIFIED IDEOGRAPH
+0xE2FC	0x607B	#CJK UNIFIED IDEOGRAPH
+0xE2FD	0x607A	#CJK UNIFIED IDEOGRAPH
+0xE2FE	0x6042	#CJK UNIFIED IDEOGRAPH
+0xE340	0x9246	#CJK UNIFIED IDEOGRAPH
+0xE341	0x9247	#CJK UNIFIED IDEOGRAPH
+0xE342	0x9248	#CJK UNIFIED IDEOGRAPH
+0xE343	0x9249	#CJK UNIFIED IDEOGRAPH
+0xE344	0x924A	#CJK UNIFIED IDEOGRAPH
+0xE345	0x924B	#CJK UNIFIED IDEOGRAPH
+0xE346	0x924C	#CJK UNIFIED IDEOGRAPH
+0xE347	0x924D	#CJK UNIFIED IDEOGRAPH
+0xE348	0x924E	#CJK UNIFIED IDEOGRAPH
+0xE349	0x924F	#CJK UNIFIED IDEOGRAPH
+0xE34A	0x9250	#CJK UNIFIED IDEOGRAPH
+0xE34B	0x9251	#CJK UNIFIED IDEOGRAPH
+0xE34C	0x9252	#CJK UNIFIED IDEOGRAPH
+0xE34D	0x9253	#CJK UNIFIED IDEOGRAPH
+0xE34E	0x9254	#CJK UNIFIED IDEOGRAPH
+0xE34F	0x9255	#CJK UNIFIED IDEOGRAPH
+0xE350	0x9256	#CJK UNIFIED IDEOGRAPH
+0xE351	0x9257	#CJK UNIFIED IDEOGRAPH
+0xE352	0x9258	#CJK UNIFIED IDEOGRAPH
+0xE353	0x9259	#CJK UNIFIED IDEOGRAPH
+0xE354	0x925A	#CJK UNIFIED IDEOGRAPH
+0xE355	0x925B	#CJK UNIFIED IDEOGRAPH
+0xE356	0x925C	#CJK UNIFIED IDEOGRAPH
+0xE357	0x925D	#CJK UNIFIED IDEOGRAPH
+0xE358	0x925E	#CJK UNIFIED IDEOGRAPH
+0xE359	0x925F	#CJK UNIFIED IDEOGRAPH
+0xE35A	0x9260	#CJK UNIFIED IDEOGRAPH
+0xE35B	0x9261	#CJK UNIFIED IDEOGRAPH
+0xE35C	0x9262	#CJK UNIFIED IDEOGRAPH
+0xE35D	0x9263	#CJK UNIFIED IDEOGRAPH
+0xE35E	0x9264	#CJK UNIFIED IDEOGRAPH
+0xE35F	0x9265	#CJK UNIFIED IDEOGRAPH
+0xE360	0x9266	#CJK UNIFIED IDEOGRAPH
+0xE361	0x9267	#CJK UNIFIED IDEOGRAPH
+0xE362	0x9268	#CJK UNIFIED IDEOGRAPH
+0xE363	0x9269	#CJK UNIFIED IDEOGRAPH
+0xE364	0x926A	#CJK UNIFIED IDEOGRAPH
+0xE365	0x926B	#CJK UNIFIED IDEOGRAPH
+0xE366	0x926C	#CJK UNIFIED IDEOGRAPH
+0xE367	0x926D	#CJK UNIFIED IDEOGRAPH
+0xE368	0x926E	#CJK UNIFIED IDEOGRAPH
+0xE369	0x926F	#CJK UNIFIED IDEOGRAPH
+0xE36A	0x9270	#CJK UNIFIED IDEOGRAPH
+0xE36B	0x9271	#CJK UNIFIED IDEOGRAPH
+0xE36C	0x9272	#CJK UNIFIED IDEOGRAPH
+0xE36D	0x9273	#CJK UNIFIED IDEOGRAPH
+0xE36E	0x9275	#CJK UNIFIED IDEOGRAPH
+0xE36F	0x9276	#CJK UNIFIED IDEOGRAPH
+0xE370	0x9277	#CJK UNIFIED IDEOGRAPH
+0xE371	0x9278	#CJK UNIFIED IDEOGRAPH
+0xE372	0x9279	#CJK UNIFIED IDEOGRAPH
+0xE373	0x927A	#CJK UNIFIED IDEOGRAPH
+0xE374	0x927B	#CJK UNIFIED IDEOGRAPH
+0xE375	0x927C	#CJK UNIFIED IDEOGRAPH
+0xE376	0x927D	#CJK UNIFIED IDEOGRAPH
+0xE377	0x927E	#CJK UNIFIED IDEOGRAPH
+0xE378	0x927F	#CJK UNIFIED IDEOGRAPH
+0xE379	0x9280	#CJK UNIFIED IDEOGRAPH
+0xE37A	0x9281	#CJK UNIFIED IDEOGRAPH
+0xE37B	0x9282	#CJK UNIFIED IDEOGRAPH
+0xE37C	0x9283	#CJK UNIFIED IDEOGRAPH
+0xE37D	0x9284	#CJK UNIFIED IDEOGRAPH
+0xE37E	0x9285	#CJK UNIFIED IDEOGRAPH
+0xE380	0x9286	#CJK UNIFIED IDEOGRAPH
+0xE381	0x9287	#CJK UNIFIED IDEOGRAPH
+0xE382	0x9288	#CJK UNIFIED IDEOGRAPH
+0xE383	0x9289	#CJK UNIFIED IDEOGRAPH
+0xE384	0x928A	#CJK UNIFIED IDEOGRAPH
+0xE385	0x928B	#CJK UNIFIED IDEOGRAPH
+0xE386	0x928C	#CJK UNIFIED IDEOGRAPH
+0xE387	0x928D	#CJK UNIFIED IDEOGRAPH
+0xE388	0x928F	#CJK UNIFIED IDEOGRAPH
+0xE389	0x9290	#CJK UNIFIED IDEOGRAPH
+0xE38A	0x9291	#CJK UNIFIED IDEOGRAPH
+0xE38B	0x9292	#CJK UNIFIED IDEOGRAPH
+0xE38C	0x9293	#CJK UNIFIED IDEOGRAPH
+0xE38D	0x9294	#CJK UNIFIED IDEOGRAPH
+0xE38E	0x9295	#CJK UNIFIED IDEOGRAPH
+0xE38F	0x9296	#CJK UNIFIED IDEOGRAPH
+0xE390	0x9297	#CJK UNIFIED IDEOGRAPH
+0xE391	0x9298	#CJK UNIFIED IDEOGRAPH
+0xE392	0x9299	#CJK UNIFIED IDEOGRAPH
+0xE393	0x929A	#CJK UNIFIED IDEOGRAPH
+0xE394	0x929B	#CJK UNIFIED IDEOGRAPH
+0xE395	0x929C	#CJK UNIFIED IDEOGRAPH
+0xE396	0x929D	#CJK UNIFIED IDEOGRAPH
+0xE397	0x929E	#CJK UNIFIED IDEOGRAPH
+0xE398	0x929F	#CJK UNIFIED IDEOGRAPH
+0xE399	0x92A0	#CJK UNIFIED IDEOGRAPH
+0xE39A	0x92A1	#CJK UNIFIED IDEOGRAPH
+0xE39B	0x92A2	#CJK UNIFIED IDEOGRAPH
+0xE39C	0x92A3	#CJK UNIFIED IDEOGRAPH
+0xE39D	0x92A4	#CJK UNIFIED IDEOGRAPH
+0xE39E	0x92A5	#CJK UNIFIED IDEOGRAPH
+0xE39F	0x92A6	#CJK UNIFIED IDEOGRAPH
+0xE3A0	0x92A7	#CJK UNIFIED IDEOGRAPH
+0xE3A1	0x606A	#CJK UNIFIED IDEOGRAPH
+0xE3A2	0x607D	#CJK UNIFIED IDEOGRAPH
+0xE3A3	0x6096	#CJK UNIFIED IDEOGRAPH
+0xE3A4	0x609A	#CJK UNIFIED IDEOGRAPH
+0xE3A5	0x60AD	#CJK UNIFIED IDEOGRAPH
+0xE3A6	0x609D	#CJK UNIFIED IDEOGRAPH
+0xE3A7	0x6083	#CJK UNIFIED IDEOGRAPH
+0xE3A8	0x6092	#CJK UNIFIED IDEOGRAPH
+0xE3A9	0x608C	#CJK UNIFIED IDEOGRAPH
+0xE3AA	0x609B	#CJK UNIFIED IDEOGRAPH
+0xE3AB	0x60EC	#CJK UNIFIED IDEOGRAPH
+0xE3AC	0x60BB	#CJK UNIFIED IDEOGRAPH
+0xE3AD	0x60B1	#CJK UNIFIED IDEOGRAPH
+0xE3AE	0x60DD	#CJK UNIFIED IDEOGRAPH
+0xE3AF	0x60D8	#CJK UNIFIED IDEOGRAPH
+0xE3B0	0x60C6	#CJK UNIFIED IDEOGRAPH
+0xE3B1	0x60DA	#CJK UNIFIED IDEOGRAPH
+0xE3B2	0x60B4	#CJK UNIFIED IDEOGRAPH
+0xE3B3	0x6120	#CJK UNIFIED IDEOGRAPH
+0xE3B4	0x6126	#CJK UNIFIED IDEOGRAPH
+0xE3B5	0x6115	#CJK UNIFIED IDEOGRAPH
+0xE3B6	0x6123	#CJK UNIFIED IDEOGRAPH
+0xE3B7	0x60F4	#CJK UNIFIED IDEOGRAPH
+0xE3B8	0x6100	#CJK UNIFIED IDEOGRAPH
+0xE3B9	0x610E	#CJK UNIFIED IDEOGRAPH
+0xE3BA	0x612B	#CJK UNIFIED IDEOGRAPH
+0xE3BB	0x614A	#CJK UNIFIED IDEOGRAPH
+0xE3BC	0x6175	#CJK UNIFIED IDEOGRAPH
+0xE3BD	0x61AC	#CJK UNIFIED IDEOGRAPH
+0xE3BE	0x6194	#CJK UNIFIED IDEOGRAPH
+0xE3BF	0x61A7	#CJK UNIFIED IDEOGRAPH
+0xE3C0	0x61B7	#CJK UNIFIED IDEOGRAPH
+0xE3C1	0x61D4	#CJK UNIFIED IDEOGRAPH
+0xE3C2	0x61F5	#CJK UNIFIED IDEOGRAPH
+0xE3C3	0x5FDD	#CJK UNIFIED IDEOGRAPH
+0xE3C4	0x96B3	#CJK UNIFIED IDEOGRAPH
+0xE3C5	0x95E9	#CJK UNIFIED IDEOGRAPH
+0xE3C6	0x95EB	#CJK UNIFIED IDEOGRAPH
+0xE3C7	0x95F1	#CJK UNIFIED IDEOGRAPH
+0xE3C8	0x95F3	#CJK UNIFIED IDEOGRAPH
+0xE3C9	0x95F5	#CJK UNIFIED IDEOGRAPH
+0xE3CA	0x95F6	#CJK UNIFIED IDEOGRAPH
+0xE3CB	0x95FC	#CJK UNIFIED IDEOGRAPH
+0xE3CC	0x95FE	#CJK UNIFIED IDEOGRAPH
+0xE3CD	0x9603	#CJK UNIFIED IDEOGRAPH
+0xE3CE	0x9604	#CJK UNIFIED IDEOGRAPH
+0xE3CF	0x9606	#CJK UNIFIED IDEOGRAPH
+0xE3D0	0x9608	#CJK UNIFIED IDEOGRAPH
+0xE3D1	0x960A	#CJK UNIFIED IDEOGRAPH
+0xE3D2	0x960B	#CJK UNIFIED IDEOGRAPH
+0xE3D3	0x960C	#CJK UNIFIED IDEOGRAPH
+0xE3D4	0x960D	#CJK UNIFIED IDEOGRAPH
+0xE3D5	0x960F	#CJK UNIFIED IDEOGRAPH
+0xE3D6	0x9612	#CJK UNIFIED IDEOGRAPH
+0xE3D7	0x9615	#CJK UNIFIED IDEOGRAPH
+0xE3D8	0x9616	#CJK UNIFIED IDEOGRAPH
+0xE3D9	0x9617	#CJK UNIFIED IDEOGRAPH
+0xE3DA	0x9619	#CJK UNIFIED IDEOGRAPH
+0xE3DB	0x961A	#CJK UNIFIED IDEOGRAPH
+0xE3DC	0x4E2C	#CJK UNIFIED IDEOGRAPH
+0xE3DD	0x723F	#CJK UNIFIED IDEOGRAPH
+0xE3DE	0x6215	#CJK UNIFIED IDEOGRAPH
+0xE3DF	0x6C35	#CJK UNIFIED IDEOGRAPH
+0xE3E0	0x6C54	#CJK UNIFIED IDEOGRAPH
+0xE3E1	0x6C5C	#CJK UNIFIED IDEOGRAPH
+0xE3E2	0x6C4A	#CJK UNIFIED IDEOGRAPH
+0xE3E3	0x6CA3	#CJK UNIFIED IDEOGRAPH
+0xE3E4	0x6C85	#CJK UNIFIED IDEOGRAPH
+0xE3E5	0x6C90	#CJK UNIFIED IDEOGRAPH
+0xE3E6	0x6C94	#CJK UNIFIED IDEOGRAPH
+0xE3E7	0x6C8C	#CJK UNIFIED IDEOGRAPH
+0xE3E8	0x6C68	#CJK UNIFIED IDEOGRAPH
+0xE3E9	0x6C69	#CJK UNIFIED IDEOGRAPH
+0xE3EA	0x6C74	#CJK UNIFIED IDEOGRAPH
+0xE3EB	0x6C76	#CJK UNIFIED IDEOGRAPH
+0xE3EC	0x6C86	#CJK UNIFIED IDEOGRAPH
+0xE3ED	0x6CA9	#CJK UNIFIED IDEOGRAPH
+0xE3EE	0x6CD0	#CJK UNIFIED IDEOGRAPH
+0xE3EF	0x6CD4	#CJK UNIFIED IDEOGRAPH
+0xE3F0	0x6CAD	#CJK UNIFIED IDEOGRAPH
+0xE3F1	0x6CF7	#CJK UNIFIED IDEOGRAPH
+0xE3F2	0x6CF8	#CJK UNIFIED IDEOGRAPH
+0xE3F3	0x6CF1	#CJK UNIFIED IDEOGRAPH
+0xE3F4	0x6CD7	#CJK UNIFIED IDEOGRAPH
+0xE3F5	0x6CB2	#CJK UNIFIED IDEOGRAPH
+0xE3F6	0x6CE0	#CJK UNIFIED IDEOGRAPH
+0xE3F7	0x6CD6	#CJK UNIFIED IDEOGRAPH
+0xE3F8	0x6CFA	#CJK UNIFIED IDEOGRAPH
+0xE3F9	0x6CEB	#CJK UNIFIED IDEOGRAPH
+0xE3FA	0x6CEE	#CJK UNIFIED IDEOGRAPH
+0xE3FB	0x6CB1	#CJK UNIFIED IDEOGRAPH
+0xE3FC	0x6CD3	#CJK UNIFIED IDEOGRAPH
+0xE3FD	0x6CEF	#CJK UNIFIED IDEOGRAPH
+0xE3FE	0x6CFE	#CJK UNIFIED IDEOGRAPH
+0xE440	0x92A8	#CJK UNIFIED IDEOGRAPH
+0xE441	0x92A9	#CJK UNIFIED IDEOGRAPH
+0xE442	0x92AA	#CJK UNIFIED IDEOGRAPH
+0xE443	0x92AB	#CJK UNIFIED IDEOGRAPH
+0xE444	0x92AC	#CJK UNIFIED IDEOGRAPH
+0xE445	0x92AD	#CJK UNIFIED IDEOGRAPH
+0xE446	0x92AF	#CJK UNIFIED IDEOGRAPH
+0xE447	0x92B0	#CJK UNIFIED IDEOGRAPH
+0xE448	0x92B1	#CJK UNIFIED IDEOGRAPH
+0xE449	0x92B2	#CJK UNIFIED IDEOGRAPH
+0xE44A	0x92B3	#CJK UNIFIED IDEOGRAPH
+0xE44B	0x92B4	#CJK UNIFIED IDEOGRAPH
+0xE44C	0x92B5	#CJK UNIFIED IDEOGRAPH
+0xE44D	0x92B6	#CJK UNIFIED IDEOGRAPH
+0xE44E	0x92B7	#CJK UNIFIED IDEOGRAPH
+0xE44F	0x92B8	#CJK UNIFIED IDEOGRAPH
+0xE450	0x92B9	#CJK UNIFIED IDEOGRAPH
+0xE451	0x92BA	#CJK UNIFIED IDEOGRAPH
+0xE452	0x92BB	#CJK UNIFIED IDEOGRAPH
+0xE453	0x92BC	#CJK UNIFIED IDEOGRAPH
+0xE454	0x92BD	#CJK UNIFIED IDEOGRAPH
+0xE455	0x92BE	#CJK UNIFIED IDEOGRAPH
+0xE456	0x92BF	#CJK UNIFIED IDEOGRAPH
+0xE457	0x92C0	#CJK UNIFIED IDEOGRAPH
+0xE458	0x92C1	#CJK UNIFIED IDEOGRAPH
+0xE459	0x92C2	#CJK UNIFIED IDEOGRAPH
+0xE45A	0x92C3	#CJK UNIFIED IDEOGRAPH
+0xE45B	0x92C4	#CJK UNIFIED IDEOGRAPH
+0xE45C	0x92C5	#CJK UNIFIED IDEOGRAPH
+0xE45D	0x92C6	#CJK UNIFIED IDEOGRAPH
+0xE45E	0x92C7	#CJK UNIFIED IDEOGRAPH
+0xE45F	0x92C9	#CJK UNIFIED IDEOGRAPH
+0xE460	0x92CA	#CJK UNIFIED IDEOGRAPH
+0xE461	0x92CB	#CJK UNIFIED IDEOGRAPH
+0xE462	0x92CC	#CJK UNIFIED IDEOGRAPH
+0xE463	0x92CD	#CJK UNIFIED IDEOGRAPH
+0xE464	0x92CE	#CJK UNIFIED IDEOGRAPH
+0xE465	0x92CF	#CJK UNIFIED IDEOGRAPH
+0xE466	0x92D0	#CJK UNIFIED IDEOGRAPH
+0xE467	0x92D1	#CJK UNIFIED IDEOGRAPH
+0xE468	0x92D2	#CJK UNIFIED IDEOGRAPH
+0xE469	0x92D3	#CJK UNIFIED IDEOGRAPH
+0xE46A	0x92D4	#CJK UNIFIED IDEOGRAPH
+0xE46B	0x92D5	#CJK UNIFIED IDEOGRAPH
+0xE46C	0x92D6	#CJK UNIFIED IDEOGRAPH
+0xE46D	0x92D7	#CJK UNIFIED IDEOGRAPH
+0xE46E	0x92D8	#CJK UNIFIED IDEOGRAPH
+0xE46F	0x92D9	#CJK UNIFIED IDEOGRAPH
+0xE470	0x92DA	#CJK UNIFIED IDEOGRAPH
+0xE471	0x92DB	#CJK UNIFIED IDEOGRAPH
+0xE472	0x92DC	#CJK UNIFIED IDEOGRAPH
+0xE473	0x92DD	#CJK UNIFIED IDEOGRAPH
+0xE474	0x92DE	#CJK UNIFIED IDEOGRAPH
+0xE475	0x92DF	#CJK UNIFIED IDEOGRAPH
+0xE476	0x92E0	#CJK UNIFIED IDEOGRAPH
+0xE477	0x92E1	#CJK UNIFIED IDEOGRAPH
+0xE478	0x92E2	#CJK UNIFIED IDEOGRAPH
+0xE479	0x92E3	#CJK UNIFIED IDEOGRAPH
+0xE47A	0x92E4	#CJK UNIFIED IDEOGRAPH
+0xE47B	0x92E5	#CJK UNIFIED IDEOGRAPH
+0xE47C	0x92E6	#CJK UNIFIED IDEOGRAPH
+0xE47D	0x92E7	#CJK UNIFIED IDEOGRAPH
+0xE47E	0x92E8	#CJK UNIFIED IDEOGRAPH
+0xE480	0x92E9	#CJK UNIFIED IDEOGRAPH
+0xE481	0x92EA	#CJK UNIFIED IDEOGRAPH
+0xE482	0x92EB	#CJK UNIFIED IDEOGRAPH
+0xE483	0x92EC	#CJK UNIFIED IDEOGRAPH
+0xE484	0x92ED	#CJK UNIFIED IDEOGRAPH
+0xE485	0x92EE	#CJK UNIFIED IDEOGRAPH
+0xE486	0x92EF	#CJK UNIFIED IDEOGRAPH
+0xE487	0x92F0	#CJK UNIFIED IDEOGRAPH
+0xE488	0x92F1	#CJK UNIFIED IDEOGRAPH
+0xE489	0x92F2	#CJK UNIFIED IDEOGRAPH
+0xE48A	0x92F3	#CJK UNIFIED IDEOGRAPH
+0xE48B	0x92F4	#CJK UNIFIED IDEOGRAPH
+0xE48C	0x92F5	#CJK UNIFIED IDEOGRAPH
+0xE48D	0x92F6	#CJK UNIFIED IDEOGRAPH
+0xE48E	0x92F7	#CJK UNIFIED IDEOGRAPH
+0xE48F	0x92F8	#CJK UNIFIED IDEOGRAPH
+0xE490	0x92F9	#CJK UNIFIED IDEOGRAPH
+0xE491	0x92FA	#CJK UNIFIED IDEOGRAPH
+0xE492	0x92FB	#CJK UNIFIED IDEOGRAPH
+0xE493	0x92FC	#CJK UNIFIED IDEOGRAPH
+0xE494	0x92FD	#CJK UNIFIED IDEOGRAPH
+0xE495	0x92FE	#CJK UNIFIED IDEOGRAPH
+0xE496	0x92FF	#CJK UNIFIED IDEOGRAPH
+0xE497	0x9300	#CJK UNIFIED IDEOGRAPH
+0xE498	0x9301	#CJK UNIFIED IDEOGRAPH
+0xE499	0x9302	#CJK UNIFIED IDEOGRAPH
+0xE49A	0x9303	#CJK UNIFIED IDEOGRAPH
+0xE49B	0x9304	#CJK UNIFIED IDEOGRAPH
+0xE49C	0x9305	#CJK UNIFIED IDEOGRAPH
+0xE49D	0x9306	#CJK UNIFIED IDEOGRAPH
+0xE49E	0x9307	#CJK UNIFIED IDEOGRAPH
+0xE49F	0x9308	#CJK UNIFIED IDEOGRAPH
+0xE4A0	0x9309	#CJK UNIFIED IDEOGRAPH
+0xE4A1	0x6D39	#CJK UNIFIED IDEOGRAPH
+0xE4A2	0x6D27	#CJK UNIFIED IDEOGRAPH
+0xE4A3	0x6D0C	#CJK UNIFIED IDEOGRAPH
+0xE4A4	0x6D43	#CJK UNIFIED IDEOGRAPH
+0xE4A5	0x6D48	#CJK UNIFIED IDEOGRAPH
+0xE4A6	0x6D07	#CJK UNIFIED IDEOGRAPH
+0xE4A7	0x6D04	#CJK UNIFIED IDEOGRAPH
+0xE4A8	0x6D19	#CJK UNIFIED IDEOGRAPH
+0xE4A9	0x6D0E	#CJK UNIFIED IDEOGRAPH
+0xE4AA	0x6D2B	#CJK UNIFIED IDEOGRAPH
+0xE4AB	0x6D4D	#CJK UNIFIED IDEOGRAPH
+0xE4AC	0x6D2E	#CJK UNIFIED IDEOGRAPH
+0xE4AD	0x6D35	#CJK UNIFIED IDEOGRAPH
+0xE4AE	0x6D1A	#CJK UNIFIED IDEOGRAPH
+0xE4AF	0x6D4F	#CJK UNIFIED IDEOGRAPH
+0xE4B0	0x6D52	#CJK UNIFIED IDEOGRAPH
+0xE4B1	0x6D54	#CJK UNIFIED IDEOGRAPH
+0xE4B2	0x6D33	#CJK UNIFIED IDEOGRAPH
+0xE4B3	0x6D91	#CJK UNIFIED IDEOGRAPH
+0xE4B4	0x6D6F	#CJK UNIFIED IDEOGRAPH
+0xE4B5	0x6D9E	#CJK UNIFIED IDEOGRAPH
+0xE4B6	0x6DA0	#CJK UNIFIED IDEOGRAPH
+0xE4B7	0x6D5E	#CJK UNIFIED IDEOGRAPH
+0xE4B8	0x6D93	#CJK UNIFIED IDEOGRAPH
+0xE4B9	0x6D94	#CJK UNIFIED IDEOGRAPH
+0xE4BA	0x6D5C	#CJK UNIFIED IDEOGRAPH
+0xE4BB	0x6D60	#CJK UNIFIED IDEOGRAPH
+0xE4BC	0x6D7C	#CJK UNIFIED IDEOGRAPH
+0xE4BD	0x6D63	#CJK UNIFIED IDEOGRAPH
+0xE4BE	0x6E1A	#CJK UNIFIED IDEOGRAPH
+0xE4BF	0x6DC7	#CJK UNIFIED IDEOGRAPH
+0xE4C0	0x6DC5	#CJK UNIFIED IDEOGRAPH
+0xE4C1	0x6DDE	#CJK UNIFIED IDEOGRAPH
+0xE4C2	0x6E0E	#CJK UNIFIED IDEOGRAPH
+0xE4C3	0x6DBF	#CJK UNIFIED IDEOGRAPH
+0xE4C4	0x6DE0	#CJK UNIFIED IDEOGRAPH
+0xE4C5	0x6E11	#CJK UNIFIED IDEOGRAPH
+0xE4C6	0x6DE6	#CJK UNIFIED IDEOGRAPH
+0xE4C7	0x6DDD	#CJK UNIFIED IDEOGRAPH
+0xE4C8	0x6DD9	#CJK UNIFIED IDEOGRAPH
+0xE4C9	0x6E16	#CJK UNIFIED IDEOGRAPH
+0xE4CA	0x6DAB	#CJK UNIFIED IDEOGRAPH
+0xE4CB	0x6E0C	#CJK UNIFIED IDEOGRAPH
+0xE4CC	0x6DAE	#CJK UNIFIED IDEOGRAPH
+0xE4CD	0x6E2B	#CJK UNIFIED IDEOGRAPH
+0xE4CE	0x6E6E	#CJK UNIFIED IDEOGRAPH
+0xE4CF	0x6E4E	#CJK UNIFIED IDEOGRAPH
+0xE4D0	0x6E6B	#CJK UNIFIED IDEOGRAPH
+0xE4D1	0x6EB2	#CJK UNIFIED IDEOGRAPH
+0xE4D2	0x6E5F	#CJK UNIFIED IDEOGRAPH
+0xE4D3	0x6E86	#CJK UNIFIED IDEOGRAPH
+0xE4D4	0x6E53	#CJK UNIFIED IDEOGRAPH
+0xE4D5	0x6E54	#CJK UNIFIED IDEOGRAPH
+0xE4D6	0x6E32	#CJK UNIFIED IDEOGRAPH
+0xE4D7	0x6E25	#CJK UNIFIED IDEOGRAPH
+0xE4D8	0x6E44	#CJK UNIFIED IDEOGRAPH
+0xE4D9	0x6EDF	#CJK UNIFIED IDEOGRAPH
+0xE4DA	0x6EB1	#CJK UNIFIED IDEOGRAPH
+0xE4DB	0x6E98	#CJK UNIFIED IDEOGRAPH
+0xE4DC	0x6EE0	#CJK UNIFIED IDEOGRAPH
+0xE4DD	0x6F2D	#CJK UNIFIED IDEOGRAPH
+0xE4DE	0x6EE2	#CJK UNIFIED IDEOGRAPH
+0xE4DF	0x6EA5	#CJK UNIFIED IDEOGRAPH
+0xE4E0	0x6EA7	#CJK UNIFIED IDEOGRAPH
+0xE4E1	0x6EBD	#CJK UNIFIED IDEOGRAPH
+0xE4E2	0x6EBB	#CJK UNIFIED IDEOGRAPH
+0xE4E3	0x6EB7	#CJK UNIFIED IDEOGRAPH
+0xE4E4	0x6ED7	#CJK UNIFIED IDEOGRAPH
+0xE4E5	0x6EB4	#CJK UNIFIED IDEOGRAPH
+0xE4E6	0x6ECF	#CJK UNIFIED IDEOGRAPH
+0xE4E7	0x6E8F	#CJK UNIFIED IDEOGRAPH
+0xE4E8	0x6EC2	#CJK UNIFIED IDEOGRAPH
+0xE4E9	0x6E9F	#CJK UNIFIED IDEOGRAPH
+0xE4EA	0x6F62	#CJK UNIFIED IDEOGRAPH
+0xE4EB	0x6F46	#CJK UNIFIED IDEOGRAPH
+0xE4EC	0x6F47	#CJK UNIFIED IDEOGRAPH
+0xE4ED	0x6F24	#CJK UNIFIED IDEOGRAPH
+0xE4EE	0x6F15	#CJK UNIFIED IDEOGRAPH
+0xE4EF	0x6EF9	#CJK UNIFIED IDEOGRAPH
+0xE4F0	0x6F2F	#CJK UNIFIED IDEOGRAPH
+0xE4F1	0x6F36	#CJK UNIFIED IDEOGRAPH
+0xE4F2	0x6F4B	#CJK UNIFIED IDEOGRAPH
+0xE4F3	0x6F74	#CJK UNIFIED IDEOGRAPH
+0xE4F4	0x6F2A	#CJK UNIFIED IDEOGRAPH
+0xE4F5	0x6F09	#CJK UNIFIED IDEOGRAPH
+0xE4F6	0x6F29	#CJK UNIFIED IDEOGRAPH
+0xE4F7	0x6F89	#CJK UNIFIED IDEOGRAPH
+0xE4F8	0x6F8D	#CJK UNIFIED IDEOGRAPH
+0xE4F9	0x6F8C	#CJK UNIFIED IDEOGRAPH
+0xE4FA	0x6F78	#CJK UNIFIED IDEOGRAPH
+0xE4FB	0x6F72	#CJK UNIFIED IDEOGRAPH
+0xE4FC	0x6F7C	#CJK UNIFIED IDEOGRAPH
+0xE4FD	0x6F7A	#CJK UNIFIED IDEOGRAPH
+0xE4FE	0x6FD1	#CJK UNIFIED IDEOGRAPH
+0xE540	0x930A	#CJK UNIFIED IDEOGRAPH
+0xE541	0x930B	#CJK UNIFIED IDEOGRAPH
+0xE542	0x930C	#CJK UNIFIED IDEOGRAPH
+0xE543	0x930D	#CJK UNIFIED IDEOGRAPH
+0xE544	0x930E	#CJK UNIFIED IDEOGRAPH
+0xE545	0x930F	#CJK UNIFIED IDEOGRAPH
+0xE546	0x9310	#CJK UNIFIED IDEOGRAPH
+0xE547	0x9311	#CJK UNIFIED IDEOGRAPH
+0xE548	0x9312	#CJK UNIFIED IDEOGRAPH
+0xE549	0x9313	#CJK UNIFIED IDEOGRAPH
+0xE54A	0x9314	#CJK UNIFIED IDEOGRAPH
+0xE54B	0x9315	#CJK UNIFIED IDEOGRAPH
+0xE54C	0x9316	#CJK UNIFIED IDEOGRAPH
+0xE54D	0x9317	#CJK UNIFIED IDEOGRAPH
+0xE54E	0x9318	#CJK UNIFIED IDEOGRAPH
+0xE54F	0x9319	#CJK UNIFIED IDEOGRAPH
+0xE550	0x931A	#CJK UNIFIED IDEOGRAPH
+0xE551	0x931B	#CJK UNIFIED IDEOGRAPH
+0xE552	0x931C	#CJK UNIFIED IDEOGRAPH
+0xE553	0x931D	#CJK UNIFIED IDEOGRAPH
+0xE554	0x931E	#CJK UNIFIED IDEOGRAPH
+0xE555	0x931F	#CJK UNIFIED IDEOGRAPH
+0xE556	0x9320	#CJK UNIFIED IDEOGRAPH
+0xE557	0x9321	#CJK UNIFIED IDEOGRAPH
+0xE558	0x9322	#CJK UNIFIED IDEOGRAPH
+0xE559	0x9323	#CJK UNIFIED IDEOGRAPH
+0xE55A	0x9324	#CJK UNIFIED IDEOGRAPH
+0xE55B	0x9325	#CJK UNIFIED IDEOGRAPH
+0xE55C	0x9326	#CJK UNIFIED IDEOGRAPH
+0xE55D	0x9327	#CJK UNIFIED IDEOGRAPH
+0xE55E	0x9328	#CJK UNIFIED IDEOGRAPH
+0xE55F	0x9329	#CJK UNIFIED IDEOGRAPH
+0xE560	0x932A	#CJK UNIFIED IDEOGRAPH
+0xE561	0x932B	#CJK UNIFIED IDEOGRAPH
+0xE562	0x932C	#CJK UNIFIED IDEOGRAPH
+0xE563	0x932D	#CJK UNIFIED IDEOGRAPH
+0xE564	0x932E	#CJK UNIFIED IDEOGRAPH
+0xE565	0x932F	#CJK UNIFIED IDEOGRAPH
+0xE566	0x9330	#CJK UNIFIED IDEOGRAPH
+0xE567	0x9331	#CJK UNIFIED IDEOGRAPH
+0xE568	0x9332	#CJK UNIFIED IDEOGRAPH
+0xE569	0x9333	#CJK UNIFIED IDEOGRAPH
+0xE56A	0x9334	#CJK UNIFIED IDEOGRAPH
+0xE56B	0x9335	#CJK UNIFIED IDEOGRAPH
+0xE56C	0x9336	#CJK UNIFIED IDEOGRAPH
+0xE56D	0x9337	#CJK UNIFIED IDEOGRAPH
+0xE56E	0x9338	#CJK UNIFIED IDEOGRAPH
+0xE56F	0x9339	#CJK UNIFIED IDEOGRAPH
+0xE570	0x933A	#CJK UNIFIED IDEOGRAPH
+0xE571	0x933B	#CJK UNIFIED IDEOGRAPH
+0xE572	0x933C	#CJK UNIFIED IDEOGRAPH
+0xE573	0x933D	#CJK UNIFIED IDEOGRAPH
+0xE574	0x933F	#CJK UNIFIED IDEOGRAPH
+0xE575	0x9340	#CJK UNIFIED IDEOGRAPH
+0xE576	0x9341	#CJK UNIFIED IDEOGRAPH
+0xE577	0x9342	#CJK UNIFIED IDEOGRAPH
+0xE578	0x9343	#CJK UNIFIED IDEOGRAPH
+0xE579	0x9344	#CJK UNIFIED IDEOGRAPH
+0xE57A	0x9345	#CJK UNIFIED IDEOGRAPH
+0xE57B	0x9346	#CJK UNIFIED IDEOGRAPH
+0xE57C	0x9347	#CJK UNIFIED IDEOGRAPH
+0xE57D	0x9348	#CJK UNIFIED IDEOGRAPH
+0xE57E	0x9349	#CJK UNIFIED IDEOGRAPH
+0xE580	0x934A	#CJK UNIFIED IDEOGRAPH
+0xE581	0x934B	#CJK UNIFIED IDEOGRAPH
+0xE582	0x934C	#CJK UNIFIED IDEOGRAPH
+0xE583	0x934D	#CJK UNIFIED IDEOGRAPH
+0xE584	0x934E	#CJK UNIFIED IDEOGRAPH
+0xE585	0x934F	#CJK UNIFIED IDEOGRAPH
+0xE586	0x9350	#CJK UNIFIED IDEOGRAPH
+0xE587	0x9351	#CJK UNIFIED IDEOGRAPH
+0xE588	0x9352	#CJK UNIFIED IDEOGRAPH
+0xE589	0x9353	#CJK UNIFIED IDEOGRAPH
+0xE58A	0x9354	#CJK UNIFIED IDEOGRAPH
+0xE58B	0x9355	#CJK UNIFIED IDEOGRAPH
+0xE58C	0x9356	#CJK UNIFIED IDEOGRAPH
+0xE58D	0x9357	#CJK UNIFIED IDEOGRAPH
+0xE58E	0x9358	#CJK UNIFIED IDEOGRAPH
+0xE58F	0x9359	#CJK UNIFIED IDEOGRAPH
+0xE590	0x935A	#CJK UNIFIED IDEOGRAPH
+0xE591	0x935B	#CJK UNIFIED IDEOGRAPH
+0xE592	0x935C	#CJK UNIFIED IDEOGRAPH
+0xE593	0x935D	#CJK UNIFIED IDEOGRAPH
+0xE594	0x935E	#CJK UNIFIED IDEOGRAPH
+0xE595	0x935F	#CJK UNIFIED IDEOGRAPH
+0xE596	0x9360	#CJK UNIFIED IDEOGRAPH
+0xE597	0x9361	#CJK UNIFIED IDEOGRAPH
+0xE598	0x9362	#CJK UNIFIED IDEOGRAPH
+0xE599	0x9363	#CJK UNIFIED IDEOGRAPH
+0xE59A	0x9364	#CJK UNIFIED IDEOGRAPH
+0xE59B	0x9365	#CJK UNIFIED IDEOGRAPH
+0xE59C	0x9366	#CJK UNIFIED IDEOGRAPH
+0xE59D	0x9367	#CJK UNIFIED IDEOGRAPH
+0xE59E	0x9368	#CJK UNIFIED IDEOGRAPH
+0xE59F	0x9369	#CJK UNIFIED IDEOGRAPH
+0xE5A0	0x936B	#CJK UNIFIED IDEOGRAPH
+0xE5A1	0x6FC9	#CJK UNIFIED IDEOGRAPH
+0xE5A2	0x6FA7	#CJK UNIFIED IDEOGRAPH
+0xE5A3	0x6FB9	#CJK UNIFIED IDEOGRAPH
+0xE5A4	0x6FB6	#CJK UNIFIED IDEOGRAPH
+0xE5A5	0x6FC2	#CJK UNIFIED IDEOGRAPH
+0xE5A6	0x6FE1	#CJK UNIFIED IDEOGRAPH
+0xE5A7	0x6FEE	#CJK UNIFIED IDEOGRAPH
+0xE5A8	0x6FDE	#CJK UNIFIED IDEOGRAPH
+0xE5A9	0x6FE0	#CJK UNIFIED IDEOGRAPH
+0xE5AA	0x6FEF	#CJK UNIFIED IDEOGRAPH
+0xE5AB	0x701A	#CJK UNIFIED IDEOGRAPH
+0xE5AC	0x7023	#CJK UNIFIED IDEOGRAPH
+0xE5AD	0x701B	#CJK UNIFIED IDEOGRAPH
+0xE5AE	0x7039	#CJK UNIFIED IDEOGRAPH
+0xE5AF	0x7035	#CJK UNIFIED IDEOGRAPH
+0xE5B0	0x704F	#CJK UNIFIED IDEOGRAPH
+0xE5B1	0x705E	#CJK UNIFIED IDEOGRAPH
+0xE5B2	0x5B80	#CJK UNIFIED IDEOGRAPH
+0xE5B3	0x5B84	#CJK UNIFIED IDEOGRAPH
+0xE5B4	0x5B95	#CJK UNIFIED IDEOGRAPH
+0xE5B5	0x5B93	#CJK UNIFIED IDEOGRAPH
+0xE5B6	0x5BA5	#CJK UNIFIED IDEOGRAPH
+0xE5B7	0x5BB8	#CJK UNIFIED IDEOGRAPH
+0xE5B8	0x752F	#CJK UNIFIED IDEOGRAPH
+0xE5B9	0x9A9E	#CJK UNIFIED IDEOGRAPH
+0xE5BA	0x6434	#CJK UNIFIED IDEOGRAPH
+0xE5BB	0x5BE4	#CJK UNIFIED IDEOGRAPH
+0xE5BC	0x5BEE	#CJK UNIFIED IDEOGRAPH
+0xE5BD	0x8930	#CJK UNIFIED IDEOGRAPH
+0xE5BE	0x5BF0	#CJK UNIFIED IDEOGRAPH
+0xE5BF	0x8E47	#CJK UNIFIED IDEOGRAPH
+0xE5C0	0x8B07	#CJK UNIFIED IDEOGRAPH
+0xE5C1	0x8FB6	#CJK UNIFIED IDEOGRAPH
+0xE5C2	0x8FD3	#CJK UNIFIED IDEOGRAPH
+0xE5C3	0x8FD5	#CJK UNIFIED IDEOGRAPH
+0xE5C4	0x8FE5	#CJK UNIFIED IDEOGRAPH
+0xE5C5	0x8FEE	#CJK UNIFIED IDEOGRAPH
+0xE5C6	0x8FE4	#CJK UNIFIED IDEOGRAPH
+0xE5C7	0x8FE9	#CJK UNIFIED IDEOGRAPH
+0xE5C8	0x8FE6	#CJK UNIFIED IDEOGRAPH
+0xE5C9	0x8FF3	#CJK UNIFIED IDEOGRAPH
+0xE5CA	0x8FE8	#CJK UNIFIED IDEOGRAPH
+0xE5CB	0x9005	#CJK UNIFIED IDEOGRAPH
+0xE5CC	0x9004	#CJK UNIFIED IDEOGRAPH
+0xE5CD	0x900B	#CJK UNIFIED IDEOGRAPH
+0xE5CE	0x9026	#CJK UNIFIED IDEOGRAPH
+0xE5CF	0x9011	#CJK UNIFIED IDEOGRAPH
+0xE5D0	0x900D	#CJK UNIFIED IDEOGRAPH
+0xE5D1	0x9016	#CJK UNIFIED IDEOGRAPH
+0xE5D2	0x9021	#CJK UNIFIED IDEOGRAPH
+0xE5D3	0x9035	#CJK UNIFIED IDEOGRAPH
+0xE5D4	0x9036	#CJK UNIFIED IDEOGRAPH
+0xE5D5	0x902D	#CJK UNIFIED IDEOGRAPH
+0xE5D6	0x902F	#CJK UNIFIED IDEOGRAPH
+0xE5D7	0x9044	#CJK UNIFIED IDEOGRAPH
+0xE5D8	0x9051	#CJK UNIFIED IDEOGRAPH
+0xE5D9	0x9052	#CJK UNIFIED IDEOGRAPH
+0xE5DA	0x9050	#CJK UNIFIED IDEOGRAPH
+0xE5DB	0x9068	#CJK UNIFIED IDEOGRAPH
+0xE5DC	0x9058	#CJK UNIFIED IDEOGRAPH
+0xE5DD	0x9062	#CJK UNIFIED IDEOGRAPH
+0xE5DE	0x905B	#CJK UNIFIED IDEOGRAPH
+0xE5DF	0x66B9	#CJK UNIFIED IDEOGRAPH
+0xE5E0	0x9074	#CJK UNIFIED IDEOGRAPH
+0xE5E1	0x907D	#CJK UNIFIED IDEOGRAPH
+0xE5E2	0x9082	#CJK UNIFIED IDEOGRAPH
+0xE5E3	0x9088	#CJK UNIFIED IDEOGRAPH
+0xE5E4	0x9083	#CJK UNIFIED IDEOGRAPH
+0xE5E5	0x908B	#CJK UNIFIED IDEOGRAPH
+0xE5E6	0x5F50	#CJK UNIFIED IDEOGRAPH
+0xE5E7	0x5F57	#CJK UNIFIED IDEOGRAPH
+0xE5E8	0x5F56	#CJK UNIFIED IDEOGRAPH
+0xE5E9	0x5F58	#CJK UNIFIED IDEOGRAPH
+0xE5EA	0x5C3B	#CJK UNIFIED IDEOGRAPH
+0xE5EB	0x54AB	#CJK UNIFIED IDEOGRAPH
+0xE5EC	0x5C50	#CJK UNIFIED IDEOGRAPH
+0xE5ED	0x5C59	#CJK UNIFIED IDEOGRAPH
+0xE5EE	0x5B71	#CJK UNIFIED IDEOGRAPH
+0xE5EF	0x5C63	#CJK UNIFIED IDEOGRAPH
+0xE5F0	0x5C66	#CJK UNIFIED IDEOGRAPH
+0xE5F1	0x7FBC	#CJK UNIFIED IDEOGRAPH
+0xE5F2	0x5F2A	#CJK UNIFIED IDEOGRAPH
+0xE5F3	0x5F29	#CJK UNIFIED IDEOGRAPH
+0xE5F4	0x5F2D	#CJK UNIFIED IDEOGRAPH
+0xE5F5	0x8274	#CJK UNIFIED IDEOGRAPH
+0xE5F6	0x5F3C	#CJK UNIFIED IDEOGRAPH
+0xE5F7	0x9B3B	#CJK UNIFIED IDEOGRAPH
+0xE5F8	0x5C6E	#CJK UNIFIED IDEOGRAPH
+0xE5F9	0x5981	#CJK UNIFIED IDEOGRAPH
+0xE5FA	0x5983	#CJK UNIFIED IDEOGRAPH
+0xE5FB	0x598D	#CJK UNIFIED IDEOGRAPH
+0xE5FC	0x59A9	#CJK UNIFIED IDEOGRAPH
+0xE5FD	0x59AA	#CJK UNIFIED IDEOGRAPH
+0xE5FE	0x59A3	#CJK UNIFIED IDEOGRAPH
+0xE640	0x936C	#CJK UNIFIED IDEOGRAPH
+0xE641	0x936D	#CJK UNIFIED IDEOGRAPH
+0xE642	0x936E	#CJK UNIFIED IDEOGRAPH
+0xE643	0x936F	#CJK UNIFIED IDEOGRAPH
+0xE644	0x9370	#CJK UNIFIED IDEOGRAPH
+0xE645	0x9371	#CJK UNIFIED IDEOGRAPH
+0xE646	0x9372	#CJK UNIFIED IDEOGRAPH
+0xE647	0x9373	#CJK UNIFIED IDEOGRAPH
+0xE648	0x9374	#CJK UNIFIED IDEOGRAPH
+0xE649	0x9375	#CJK UNIFIED IDEOGRAPH
+0xE64A	0x9376	#CJK UNIFIED IDEOGRAPH
+0xE64B	0x9377	#CJK UNIFIED IDEOGRAPH
+0xE64C	0x9378	#CJK UNIFIED IDEOGRAPH
+0xE64D	0x9379	#CJK UNIFIED IDEOGRAPH
+0xE64E	0x937A	#CJK UNIFIED IDEOGRAPH
+0xE64F	0x937B	#CJK UNIFIED IDEOGRAPH
+0xE650	0x937C	#CJK UNIFIED IDEOGRAPH
+0xE651	0x937D	#CJK UNIFIED IDEOGRAPH
+0xE652	0x937E	#CJK UNIFIED IDEOGRAPH
+0xE653	0x937F	#CJK UNIFIED IDEOGRAPH
+0xE654	0x9380	#CJK UNIFIED IDEOGRAPH
+0xE655	0x9381	#CJK UNIFIED IDEOGRAPH
+0xE656	0x9382	#CJK UNIFIED IDEOGRAPH
+0xE657	0x9383	#CJK UNIFIED IDEOGRAPH
+0xE658	0x9384	#CJK UNIFIED IDEOGRAPH
+0xE659	0x9385	#CJK UNIFIED IDEOGRAPH
+0xE65A	0x9386	#CJK UNIFIED IDEOGRAPH
+0xE65B	0x9387	#CJK UNIFIED IDEOGRAPH
+0xE65C	0x9388	#CJK UNIFIED IDEOGRAPH
+0xE65D	0x9389	#CJK UNIFIED IDEOGRAPH
+0xE65E	0x938A	#CJK UNIFIED IDEOGRAPH
+0xE65F	0x938B	#CJK UNIFIED IDEOGRAPH
+0xE660	0x938C	#CJK UNIFIED IDEOGRAPH
+0xE661	0x938D	#CJK UNIFIED IDEOGRAPH
+0xE662	0x938E	#CJK UNIFIED IDEOGRAPH
+0xE663	0x9390	#CJK UNIFIED IDEOGRAPH
+0xE664	0x9391	#CJK UNIFIED IDEOGRAPH
+0xE665	0x9392	#CJK UNIFIED IDEOGRAPH
+0xE666	0x9393	#CJK UNIFIED IDEOGRAPH
+0xE667	0x9394	#CJK UNIFIED IDEOGRAPH
+0xE668	0x9395	#CJK UNIFIED IDEOGRAPH
+0xE669	0x9396	#CJK UNIFIED IDEOGRAPH
+0xE66A	0x9397	#CJK UNIFIED IDEOGRAPH
+0xE66B	0x9398	#CJK UNIFIED IDEOGRAPH
+0xE66C	0x9399	#CJK UNIFIED IDEOGRAPH
+0xE66D	0x939A	#CJK UNIFIED IDEOGRAPH
+0xE66E	0x939B	#CJK UNIFIED IDEOGRAPH
+0xE66F	0x939C	#CJK UNIFIED IDEOGRAPH
+0xE670	0x939D	#CJK UNIFIED IDEOGRAPH
+0xE671	0x939E	#CJK UNIFIED IDEOGRAPH
+0xE672	0x939F	#CJK UNIFIED IDEOGRAPH
+0xE673	0x93A0	#CJK UNIFIED IDEOGRAPH
+0xE674	0x93A1	#CJK UNIFIED IDEOGRAPH
+0xE675	0x93A2	#CJK UNIFIED IDEOGRAPH
+0xE676	0x93A3	#CJK UNIFIED IDEOGRAPH
+0xE677	0x93A4	#CJK UNIFIED IDEOGRAPH
+0xE678	0x93A5	#CJK UNIFIED IDEOGRAPH
+0xE679	0x93A6	#CJK UNIFIED IDEOGRAPH
+0xE67A	0x93A7	#CJK UNIFIED IDEOGRAPH
+0xE67B	0x93A8	#CJK UNIFIED IDEOGRAPH
+0xE67C	0x93A9	#CJK UNIFIED IDEOGRAPH
+0xE67D	0x93AA	#CJK UNIFIED IDEOGRAPH
+0xE67E	0x93AB	#CJK UNIFIED IDEOGRAPH
+0xE680	0x93AC	#CJK UNIFIED IDEOGRAPH
+0xE681	0x93AD	#CJK UNIFIED IDEOGRAPH
+0xE682	0x93AE	#CJK UNIFIED IDEOGRAPH
+0xE683	0x93AF	#CJK UNIFIED IDEOGRAPH
+0xE684	0x93B0	#CJK UNIFIED IDEOGRAPH
+0xE685	0x93B1	#CJK UNIFIED IDEOGRAPH
+0xE686	0x93B2	#CJK UNIFIED IDEOGRAPH
+0xE687	0x93B3	#CJK UNIFIED IDEOGRAPH
+0xE688	0x93B4	#CJK UNIFIED IDEOGRAPH
+0xE689	0x93B5	#CJK UNIFIED IDEOGRAPH
+0xE68A	0x93B6	#CJK UNIFIED IDEOGRAPH
+0xE68B	0x93B7	#CJK UNIFIED IDEOGRAPH
+0xE68C	0x93B8	#CJK UNIFIED IDEOGRAPH
+0xE68D	0x93B9	#CJK UNIFIED IDEOGRAPH
+0xE68E	0x93BA	#CJK UNIFIED IDEOGRAPH
+0xE68F	0x93BB	#CJK UNIFIED IDEOGRAPH
+0xE690	0x93BC	#CJK UNIFIED IDEOGRAPH
+0xE691	0x93BD	#CJK UNIFIED IDEOGRAPH
+0xE692	0x93BE	#CJK UNIFIED IDEOGRAPH
+0xE693	0x93BF	#CJK UNIFIED IDEOGRAPH
+0xE694	0x93C0	#CJK UNIFIED IDEOGRAPH
+0xE695	0x93C1	#CJK UNIFIED IDEOGRAPH
+0xE696	0x93C2	#CJK UNIFIED IDEOGRAPH
+0xE697	0x93C3	#CJK UNIFIED IDEOGRAPH
+0xE698	0x93C4	#CJK UNIFIED IDEOGRAPH
+0xE699	0x93C5	#CJK UNIFIED IDEOGRAPH
+0xE69A	0x93C6	#CJK UNIFIED IDEOGRAPH
+0xE69B	0x93C7	#CJK UNIFIED IDEOGRAPH
+0xE69C	0x93C8	#CJK UNIFIED IDEOGRAPH
+0xE69D	0x93C9	#CJK UNIFIED IDEOGRAPH
+0xE69E	0x93CB	#CJK UNIFIED IDEOGRAPH
+0xE69F	0x93CC	#CJK UNIFIED IDEOGRAPH
+0xE6A0	0x93CD	#CJK UNIFIED IDEOGRAPH
+0xE6A1	0x5997	#CJK UNIFIED IDEOGRAPH
+0xE6A2	0x59CA	#CJK UNIFIED IDEOGRAPH
+0xE6A3	0x59AB	#CJK UNIFIED IDEOGRAPH
+0xE6A4	0x599E	#CJK UNIFIED IDEOGRAPH
+0xE6A5	0x59A4	#CJK UNIFIED IDEOGRAPH
+0xE6A6	0x59D2	#CJK UNIFIED IDEOGRAPH
+0xE6A7	0x59B2	#CJK UNIFIED IDEOGRAPH
+0xE6A8	0x59AF	#CJK UNIFIED IDEOGRAPH
+0xE6A9	0x59D7	#CJK UNIFIED IDEOGRAPH
+0xE6AA	0x59BE	#CJK UNIFIED IDEOGRAPH
+0xE6AB	0x5A05	#CJK UNIFIED IDEOGRAPH
+0xE6AC	0x5A06	#CJK UNIFIED IDEOGRAPH
+0xE6AD	0x59DD	#CJK UNIFIED IDEOGRAPH
+0xE6AE	0x5A08	#CJK UNIFIED IDEOGRAPH
+0xE6AF	0x59E3	#CJK UNIFIED IDEOGRAPH
+0xE6B0	0x59D8	#CJK UNIFIED IDEOGRAPH
+0xE6B1	0x59F9	#CJK UNIFIED IDEOGRAPH
+0xE6B2	0x5A0C	#CJK UNIFIED IDEOGRAPH
+0xE6B3	0x5A09	#CJK UNIFIED IDEOGRAPH
+0xE6B4	0x5A32	#CJK UNIFIED IDEOGRAPH
+0xE6B5	0x5A34	#CJK UNIFIED IDEOGRAPH
+0xE6B6	0x5A11	#CJK UNIFIED IDEOGRAPH
+0xE6B7	0x5A23	#CJK UNIFIED IDEOGRAPH
+0xE6B8	0x5A13	#CJK UNIFIED IDEOGRAPH
+0xE6B9	0x5A40	#CJK UNIFIED IDEOGRAPH
+0xE6BA	0x5A67	#CJK UNIFIED IDEOGRAPH
+0xE6BB	0x5A4A	#CJK UNIFIED IDEOGRAPH
+0xE6BC	0x5A55	#CJK UNIFIED IDEOGRAPH
+0xE6BD	0x5A3C	#CJK UNIFIED IDEOGRAPH
+0xE6BE	0x5A62	#CJK UNIFIED IDEOGRAPH
+0xE6BF	0x5A75	#CJK UNIFIED IDEOGRAPH
+0xE6C0	0x80EC	#CJK UNIFIED IDEOGRAPH
+0xE6C1	0x5AAA	#CJK UNIFIED IDEOGRAPH
+0xE6C2	0x5A9B	#CJK UNIFIED IDEOGRAPH
+0xE6C3	0x5A77	#CJK UNIFIED IDEOGRAPH
+0xE6C4	0x5A7A	#CJK UNIFIED IDEOGRAPH
+0xE6C5	0x5ABE	#CJK UNIFIED IDEOGRAPH
+0xE6C6	0x5AEB	#CJK UNIFIED IDEOGRAPH
+0xE6C7	0x5AB2	#CJK UNIFIED IDEOGRAPH
+0xE6C8	0x5AD2	#CJK UNIFIED IDEOGRAPH
+0xE6C9	0x5AD4	#CJK UNIFIED IDEOGRAPH
+0xE6CA	0x5AB8	#CJK UNIFIED IDEOGRAPH
+0xE6CB	0x5AE0	#CJK UNIFIED IDEOGRAPH
+0xE6CC	0x5AE3	#CJK UNIFIED IDEOGRAPH
+0xE6CD	0x5AF1	#CJK UNIFIED IDEOGRAPH
+0xE6CE	0x5AD6	#CJK UNIFIED IDEOGRAPH
+0xE6CF	0x5AE6	#CJK UNIFIED IDEOGRAPH
+0xE6D0	0x5AD8	#CJK UNIFIED IDEOGRAPH
+0xE6D1	0x5ADC	#CJK UNIFIED IDEOGRAPH
+0xE6D2	0x5B09	#CJK UNIFIED IDEOGRAPH
+0xE6D3	0x5B17	#CJK UNIFIED IDEOGRAPH
+0xE6D4	0x5B16	#CJK UNIFIED IDEOGRAPH
+0xE6D5	0x5B32	#CJK UNIFIED IDEOGRAPH
+0xE6D6	0x5B37	#CJK UNIFIED IDEOGRAPH
+0xE6D7	0x5B40	#CJK UNIFIED IDEOGRAPH
+0xE6D8	0x5C15	#CJK UNIFIED IDEOGRAPH
+0xE6D9	0x5C1C	#CJK UNIFIED IDEOGRAPH
+0xE6DA	0x5B5A	#CJK UNIFIED IDEOGRAPH
+0xE6DB	0x5B65	#CJK UNIFIED IDEOGRAPH
+0xE6DC	0x5B73	#CJK UNIFIED IDEOGRAPH
+0xE6DD	0x5B51	#CJK UNIFIED IDEOGRAPH
+0xE6DE	0x5B53	#CJK UNIFIED IDEOGRAPH
+0xE6DF	0x5B62	#CJK UNIFIED IDEOGRAPH
+0xE6E0	0x9A75	#CJK UNIFIED IDEOGRAPH
+0xE6E1	0x9A77	#CJK UNIFIED IDEOGRAPH
+0xE6E2	0x9A78	#CJK UNIFIED IDEOGRAPH
+0xE6E3	0x9A7A	#CJK UNIFIED IDEOGRAPH
+0xE6E4	0x9A7F	#CJK UNIFIED IDEOGRAPH
+0xE6E5	0x9A7D	#CJK UNIFIED IDEOGRAPH
+0xE6E6	0x9A80	#CJK UNIFIED IDEOGRAPH
+0xE6E7	0x9A81	#CJK UNIFIED IDEOGRAPH
+0xE6E8	0x9A85	#CJK UNIFIED IDEOGRAPH
+0xE6E9	0x9A88	#CJK UNIFIED IDEOGRAPH
+0xE6EA	0x9A8A	#CJK UNIFIED IDEOGRAPH
+0xE6EB	0x9A90	#CJK UNIFIED IDEOGRAPH
+0xE6EC	0x9A92	#CJK UNIFIED IDEOGRAPH
+0xE6ED	0x9A93	#CJK UNIFIED IDEOGRAPH
+0xE6EE	0x9A96	#CJK UNIFIED IDEOGRAPH
+0xE6EF	0x9A98	#CJK UNIFIED IDEOGRAPH
+0xE6F0	0x9A9B	#CJK UNIFIED IDEOGRAPH
+0xE6F1	0x9A9C	#CJK UNIFIED IDEOGRAPH
+0xE6F2	0x9A9D	#CJK UNIFIED IDEOGRAPH
+0xE6F3	0x9A9F	#CJK UNIFIED IDEOGRAPH
+0xE6F4	0x9AA0	#CJK UNIFIED IDEOGRAPH
+0xE6F5	0x9AA2	#CJK UNIFIED IDEOGRAPH
+0xE6F6	0x9AA3	#CJK UNIFIED IDEOGRAPH
+0xE6F7	0x9AA5	#CJK UNIFIED IDEOGRAPH
+0xE6F8	0x9AA7	#CJK UNIFIED IDEOGRAPH
+0xE6F9	0x7E9F	#CJK UNIFIED IDEOGRAPH
+0xE6FA	0x7EA1	#CJK UNIFIED IDEOGRAPH
+0xE6FB	0x7EA3	#CJK UNIFIED IDEOGRAPH
+0xE6FC	0x7EA5	#CJK UNIFIED IDEOGRAPH
+0xE6FD	0x7EA8	#CJK UNIFIED IDEOGRAPH
+0xE6FE	0x7EA9	#CJK UNIFIED IDEOGRAPH
+0xE740	0x93CE	#CJK UNIFIED IDEOGRAPH
+0xE741	0x93CF	#CJK UNIFIED IDEOGRAPH
+0xE742	0x93D0	#CJK UNIFIED IDEOGRAPH
+0xE743	0x93D1	#CJK UNIFIED IDEOGRAPH
+0xE744	0x93D2	#CJK UNIFIED IDEOGRAPH
+0xE745	0x93D3	#CJK UNIFIED IDEOGRAPH
+0xE746	0x93D4	#CJK UNIFIED IDEOGRAPH
+0xE747	0x93D5	#CJK UNIFIED IDEOGRAPH
+0xE748	0x93D7	#CJK UNIFIED IDEOGRAPH
+0xE749	0x93D8	#CJK UNIFIED IDEOGRAPH
+0xE74A	0x93D9	#CJK UNIFIED IDEOGRAPH
+0xE74B	0x93DA	#CJK UNIFIED IDEOGRAPH
+0xE74C	0x93DB	#CJK UNIFIED IDEOGRAPH
+0xE74D	0x93DC	#CJK UNIFIED IDEOGRAPH
+0xE74E	0x93DD	#CJK UNIFIED IDEOGRAPH
+0xE74F	0x93DE	#CJK UNIFIED IDEOGRAPH
+0xE750	0x93DF	#CJK UNIFIED IDEOGRAPH
+0xE751	0x93E0	#CJK UNIFIED IDEOGRAPH
+0xE752	0x93E1	#CJK UNIFIED IDEOGRAPH
+0xE753	0x93E2	#CJK UNIFIED IDEOGRAPH
+0xE754	0x93E3	#CJK UNIFIED IDEOGRAPH
+0xE755	0x93E4	#CJK UNIFIED IDEOGRAPH
+0xE756	0x93E5	#CJK UNIFIED IDEOGRAPH
+0xE757	0x93E6	#CJK UNIFIED IDEOGRAPH
+0xE758	0x93E7	#CJK UNIFIED IDEOGRAPH
+0xE759	0x93E8	#CJK UNIFIED IDEOGRAPH
+0xE75A	0x93E9	#CJK UNIFIED IDEOGRAPH
+0xE75B	0x93EA	#CJK UNIFIED IDEOGRAPH
+0xE75C	0x93EB	#CJK UNIFIED IDEOGRAPH
+0xE75D	0x93EC	#CJK UNIFIED IDEOGRAPH
+0xE75E	0x93ED	#CJK UNIFIED IDEOGRAPH
+0xE75F	0x93EE	#CJK UNIFIED IDEOGRAPH
+0xE760	0x93EF	#CJK UNIFIED IDEOGRAPH
+0xE761	0x93F0	#CJK UNIFIED IDEOGRAPH
+0xE762	0x93F1	#CJK UNIFIED IDEOGRAPH
+0xE763	0x93F2	#CJK UNIFIED IDEOGRAPH
+0xE764	0x93F3	#CJK UNIFIED IDEOGRAPH
+0xE765	0x93F4	#CJK UNIFIED IDEOGRAPH
+0xE766	0x93F5	#CJK UNIFIED IDEOGRAPH
+0xE767	0x93F6	#CJK UNIFIED IDEOGRAPH
+0xE768	0x93F7	#CJK UNIFIED IDEOGRAPH
+0xE769	0x93F8	#CJK UNIFIED IDEOGRAPH
+0xE76A	0x93F9	#CJK UNIFIED IDEOGRAPH
+0xE76B	0x93FA	#CJK UNIFIED IDEOGRAPH
+0xE76C	0x93FB	#CJK UNIFIED IDEOGRAPH
+0xE76D	0x93FC	#CJK UNIFIED IDEOGRAPH
+0xE76E	0x93FD	#CJK UNIFIED IDEOGRAPH
+0xE76F	0x93FE	#CJK UNIFIED IDEOGRAPH
+0xE770	0x93FF	#CJK UNIFIED IDEOGRAPH
+0xE771	0x9400	#CJK UNIFIED IDEOGRAPH
+0xE772	0x9401	#CJK UNIFIED IDEOGRAPH
+0xE773	0x9402	#CJK UNIFIED IDEOGRAPH
+0xE774	0x9403	#CJK UNIFIED IDEOGRAPH
+0xE775	0x9404	#CJK UNIFIED IDEOGRAPH
+0xE776	0x9405	#CJK UNIFIED IDEOGRAPH
+0xE777	0x9406	#CJK UNIFIED IDEOGRAPH
+0xE778	0x9407	#CJK UNIFIED IDEOGRAPH
+0xE779	0x9408	#CJK UNIFIED IDEOGRAPH
+0xE77A	0x9409	#CJK UNIFIED IDEOGRAPH
+0xE77B	0x940A	#CJK UNIFIED IDEOGRAPH
+0xE77C	0x940B	#CJK UNIFIED IDEOGRAPH
+0xE77D	0x940C	#CJK UNIFIED IDEOGRAPH
+0xE77E	0x940D	#CJK UNIFIED IDEOGRAPH
+0xE780	0x940E	#CJK UNIFIED IDEOGRAPH
+0xE781	0x940F	#CJK UNIFIED IDEOGRAPH
+0xE782	0x9410	#CJK UNIFIED IDEOGRAPH
+0xE783	0x9411	#CJK UNIFIED IDEOGRAPH
+0xE784	0x9412	#CJK UNIFIED IDEOGRAPH
+0xE785	0x9413	#CJK UNIFIED IDEOGRAPH
+0xE786	0x9414	#CJK UNIFIED IDEOGRAPH
+0xE787	0x9415	#CJK UNIFIED IDEOGRAPH
+0xE788	0x9416	#CJK UNIFIED IDEOGRAPH
+0xE789	0x9417	#CJK UNIFIED IDEOGRAPH
+0xE78A	0x9418	#CJK UNIFIED IDEOGRAPH
+0xE78B	0x9419	#CJK UNIFIED IDEOGRAPH
+0xE78C	0x941A	#CJK UNIFIED IDEOGRAPH
+0xE78D	0x941B	#CJK UNIFIED IDEOGRAPH
+0xE78E	0x941C	#CJK UNIFIED IDEOGRAPH
+0xE78F	0x941D	#CJK UNIFIED IDEOGRAPH
+0xE790	0x941E	#CJK UNIFIED IDEOGRAPH
+0xE791	0x941F	#CJK UNIFIED IDEOGRAPH
+0xE792	0x9420	#CJK UNIFIED IDEOGRAPH
+0xE793	0x9421	#CJK UNIFIED IDEOGRAPH
+0xE794	0x9422	#CJK UNIFIED IDEOGRAPH
+0xE795	0x9423	#CJK UNIFIED IDEOGRAPH
+0xE796	0x9424	#CJK UNIFIED IDEOGRAPH
+0xE797	0x9425	#CJK UNIFIED IDEOGRAPH
+0xE798	0x9426	#CJK UNIFIED IDEOGRAPH
+0xE799	0x9427	#CJK UNIFIED IDEOGRAPH
+0xE79A	0x9428	#CJK UNIFIED IDEOGRAPH
+0xE79B	0x9429	#CJK UNIFIED IDEOGRAPH
+0xE79C	0x942A	#CJK UNIFIED IDEOGRAPH
+0xE79D	0x942B	#CJK UNIFIED IDEOGRAPH
+0xE79E	0x942C	#CJK UNIFIED IDEOGRAPH
+0xE79F	0x942D	#CJK UNIFIED IDEOGRAPH
+0xE7A0	0x942E	#CJK UNIFIED IDEOGRAPH
+0xE7A1	0x7EAD	#CJK UNIFIED IDEOGRAPH
+0xE7A2	0x7EB0	#CJK UNIFIED IDEOGRAPH
+0xE7A3	0x7EBE	#CJK UNIFIED IDEOGRAPH
+0xE7A4	0x7EC0	#CJK UNIFIED IDEOGRAPH
+0xE7A5	0x7EC1	#CJK UNIFIED IDEOGRAPH
+0xE7A6	0x7EC2	#CJK UNIFIED IDEOGRAPH
+0xE7A7	0x7EC9	#CJK UNIFIED IDEOGRAPH
+0xE7A8	0x7ECB	#CJK UNIFIED IDEOGRAPH
+0xE7A9	0x7ECC	#CJK UNIFIED IDEOGRAPH
+0xE7AA	0x7ED0	#CJK UNIFIED IDEOGRAPH
+0xE7AB	0x7ED4	#CJK UNIFIED IDEOGRAPH
+0xE7AC	0x7ED7	#CJK UNIFIED IDEOGRAPH
+0xE7AD	0x7EDB	#CJK UNIFIED IDEOGRAPH
+0xE7AE	0x7EE0	#CJK UNIFIED IDEOGRAPH
+0xE7AF	0x7EE1	#CJK UNIFIED IDEOGRAPH
+0xE7B0	0x7EE8	#CJK UNIFIED IDEOGRAPH
+0xE7B1	0x7EEB	#CJK UNIFIED IDEOGRAPH
+0xE7B2	0x7EEE	#CJK UNIFIED IDEOGRAPH
+0xE7B3	0x7EEF	#CJK UNIFIED IDEOGRAPH
+0xE7B4	0x7EF1	#CJK UNIFIED IDEOGRAPH
+0xE7B5	0x7EF2	#CJK UNIFIED IDEOGRAPH
+0xE7B6	0x7F0D	#CJK UNIFIED IDEOGRAPH
+0xE7B7	0x7EF6	#CJK UNIFIED IDEOGRAPH
+0xE7B8	0x7EFA	#CJK UNIFIED IDEOGRAPH
+0xE7B9	0x7EFB	#CJK UNIFIED IDEOGRAPH
+0xE7BA	0x7EFE	#CJK UNIFIED IDEOGRAPH
+0xE7BB	0x7F01	#CJK UNIFIED IDEOGRAPH
+0xE7BC	0x7F02	#CJK UNIFIED IDEOGRAPH
+0xE7BD	0x7F03	#CJK UNIFIED IDEOGRAPH
+0xE7BE	0x7F07	#CJK UNIFIED IDEOGRAPH
+0xE7BF	0x7F08	#CJK UNIFIED IDEOGRAPH
+0xE7C0	0x7F0B	#CJK UNIFIED IDEOGRAPH
+0xE7C1	0x7F0C	#CJK UNIFIED IDEOGRAPH
+0xE7C2	0x7F0F	#CJK UNIFIED IDEOGRAPH
+0xE7C3	0x7F11	#CJK UNIFIED IDEOGRAPH
+0xE7C4	0x7F12	#CJK UNIFIED IDEOGRAPH
+0xE7C5	0x7F17	#CJK UNIFIED IDEOGRAPH
+0xE7C6	0x7F19	#CJK UNIFIED IDEOGRAPH
+0xE7C7	0x7F1C	#CJK UNIFIED IDEOGRAPH
+0xE7C8	0x7F1B	#CJK UNIFIED IDEOGRAPH
+0xE7C9	0x7F1F	#CJK UNIFIED IDEOGRAPH
+0xE7CA	0x7F21	#CJK UNIFIED IDEOGRAPH
+0xE7CB	0x7F22	#CJK UNIFIED IDEOGRAPH
+0xE7CC	0x7F23	#CJK UNIFIED IDEOGRAPH
+0xE7CD	0x7F24	#CJK UNIFIED IDEOGRAPH
+0xE7CE	0x7F25	#CJK UNIFIED IDEOGRAPH
+0xE7CF	0x7F26	#CJK UNIFIED IDEOGRAPH
+0xE7D0	0x7F27	#CJK UNIFIED IDEOGRAPH
+0xE7D1	0x7F2A	#CJK UNIFIED IDEOGRAPH
+0xE7D2	0x7F2B	#CJK UNIFIED IDEOGRAPH
+0xE7D3	0x7F2C	#CJK UNIFIED IDEOGRAPH
+0xE7D4	0x7F2D	#CJK UNIFIED IDEOGRAPH
+0xE7D5	0x7F2F	#CJK UNIFIED IDEOGRAPH
+0xE7D6	0x7F30	#CJK UNIFIED IDEOGRAPH
+0xE7D7	0x7F31	#CJK UNIFIED IDEOGRAPH
+0xE7D8	0x7F32	#CJK UNIFIED IDEOGRAPH
+0xE7D9	0x7F33	#CJK UNIFIED IDEOGRAPH
+0xE7DA	0x7F35	#CJK UNIFIED IDEOGRAPH
+0xE7DB	0x5E7A	#CJK UNIFIED IDEOGRAPH
+0xE7DC	0x757F	#CJK UNIFIED IDEOGRAPH
+0xE7DD	0x5DDB	#CJK UNIFIED IDEOGRAPH
+0xE7DE	0x753E	#CJK UNIFIED IDEOGRAPH
+0xE7DF	0x9095	#CJK UNIFIED IDEOGRAPH
+0xE7E0	0x738E	#CJK UNIFIED IDEOGRAPH
+0xE7E1	0x7391	#CJK UNIFIED IDEOGRAPH
+0xE7E2	0x73AE	#CJK UNIFIED IDEOGRAPH
+0xE7E3	0x73A2	#CJK UNIFIED IDEOGRAPH
+0xE7E4	0x739F	#CJK UNIFIED IDEOGRAPH
+0xE7E5	0x73CF	#CJK UNIFIED IDEOGRAPH
+0xE7E6	0x73C2	#CJK UNIFIED IDEOGRAPH
+0xE7E7	0x73D1	#CJK UNIFIED IDEOGRAPH
+0xE7E8	0x73B7	#CJK UNIFIED IDEOGRAPH
+0xE7E9	0x73B3	#CJK UNIFIED IDEOGRAPH
+0xE7EA	0x73C0	#CJK UNIFIED IDEOGRAPH
+0xE7EB	0x73C9	#CJK UNIFIED IDEOGRAPH
+0xE7EC	0x73C8	#CJK UNIFIED IDEOGRAPH
+0xE7ED	0x73E5	#CJK UNIFIED IDEOGRAPH
+0xE7EE	0x73D9	#CJK UNIFIED IDEOGRAPH
+0xE7EF	0x987C	#CJK UNIFIED IDEOGRAPH
+0xE7F0	0x740A	#CJK UNIFIED IDEOGRAPH
+0xE7F1	0x73E9	#CJK UNIFIED IDEOGRAPH
+0xE7F2	0x73E7	#CJK UNIFIED IDEOGRAPH
+0xE7F3	0x73DE	#CJK UNIFIED IDEOGRAPH
+0xE7F4	0x73BA	#CJK UNIFIED IDEOGRAPH
+0xE7F5	0x73F2	#CJK UNIFIED IDEOGRAPH
+0xE7F6	0x740F	#CJK UNIFIED IDEOGRAPH
+0xE7F7	0x742A	#CJK UNIFIED IDEOGRAPH
+0xE7F8	0x745B	#CJK UNIFIED IDEOGRAPH
+0xE7F9	0x7426	#CJK UNIFIED IDEOGRAPH
+0xE7FA	0x7425	#CJK UNIFIED IDEOGRAPH
+0xE7FB	0x7428	#CJK UNIFIED IDEOGRAPH
+0xE7FC	0x7430	#CJK UNIFIED IDEOGRAPH
+0xE7FD	0x742E	#CJK UNIFIED IDEOGRAPH
+0xE7FE	0x742C	#CJK UNIFIED IDEOGRAPH
+0xE840	0x942F	#CJK UNIFIED IDEOGRAPH
+0xE841	0x9430	#CJK UNIFIED IDEOGRAPH
+0xE842	0x9431	#CJK UNIFIED IDEOGRAPH
+0xE843	0x9432	#CJK UNIFIED IDEOGRAPH
+0xE844	0x9433	#CJK UNIFIED IDEOGRAPH
+0xE845	0x9434	#CJK UNIFIED IDEOGRAPH
+0xE846	0x9435	#CJK UNIFIED IDEOGRAPH
+0xE847	0x9436	#CJK UNIFIED IDEOGRAPH
+0xE848	0x9437	#CJK UNIFIED IDEOGRAPH
+0xE849	0x9438	#CJK UNIFIED IDEOGRAPH
+0xE84A	0x9439	#CJK UNIFIED IDEOGRAPH
+0xE84B	0x943A	#CJK UNIFIED IDEOGRAPH
+0xE84C	0x943B	#CJK UNIFIED IDEOGRAPH
+0xE84D	0x943C	#CJK UNIFIED IDEOGRAPH
+0xE84E	0x943D	#CJK UNIFIED IDEOGRAPH
+0xE84F	0x943F	#CJK UNIFIED IDEOGRAPH
+0xE850	0x9440	#CJK UNIFIED IDEOGRAPH
+0xE851	0x9441	#CJK UNIFIED IDEOGRAPH
+0xE852	0x9442	#CJK UNIFIED IDEOGRAPH
+0xE853	0x9443	#CJK UNIFIED IDEOGRAPH
+0xE854	0x9444	#CJK UNIFIED IDEOGRAPH
+0xE855	0x9445	#CJK UNIFIED IDEOGRAPH
+0xE856	0x9446	#CJK UNIFIED IDEOGRAPH
+0xE857	0x9447	#CJK UNIFIED IDEOGRAPH
+0xE858	0x9448	#CJK UNIFIED IDEOGRAPH
+0xE859	0x9449	#CJK UNIFIED IDEOGRAPH
+0xE85A	0x944A	#CJK UNIFIED IDEOGRAPH
+0xE85B	0x944B	#CJK UNIFIED IDEOGRAPH
+0xE85C	0x944C	#CJK UNIFIED IDEOGRAPH
+0xE85D	0x944D	#CJK UNIFIED IDEOGRAPH
+0xE85E	0x944E	#CJK UNIFIED IDEOGRAPH
+0xE85F	0x944F	#CJK UNIFIED IDEOGRAPH
+0xE860	0x9450	#CJK UNIFIED IDEOGRAPH
+0xE861	0x9451	#CJK UNIFIED IDEOGRAPH
+0xE862	0x9452	#CJK UNIFIED IDEOGRAPH
+0xE863	0x9453	#CJK UNIFIED IDEOGRAPH
+0xE864	0x9454	#CJK UNIFIED IDEOGRAPH
+0xE865	0x9455	#CJK UNIFIED IDEOGRAPH
+0xE866	0x9456	#CJK UNIFIED IDEOGRAPH
+0xE867	0x9457	#CJK UNIFIED IDEOGRAPH
+0xE868	0x9458	#CJK UNIFIED IDEOGRAPH
+0xE869	0x9459	#CJK UNIFIED IDEOGRAPH
+0xE86A	0x945A	#CJK UNIFIED IDEOGRAPH
+0xE86B	0x945B	#CJK UNIFIED IDEOGRAPH
+0xE86C	0x945C	#CJK UNIFIED IDEOGRAPH
+0xE86D	0x945D	#CJK UNIFIED IDEOGRAPH
+0xE86E	0x945E	#CJK UNIFIED IDEOGRAPH
+0xE86F	0x945F	#CJK UNIFIED IDEOGRAPH
+0xE870	0x9460	#CJK UNIFIED IDEOGRAPH
+0xE871	0x9461	#CJK UNIFIED IDEOGRAPH
+0xE872	0x9462	#CJK UNIFIED IDEOGRAPH
+0xE873	0x9463	#CJK UNIFIED IDEOGRAPH
+0xE874	0x9464	#CJK UNIFIED IDEOGRAPH
+0xE875	0x9465	#CJK UNIFIED IDEOGRAPH
+0xE876	0x9466	#CJK UNIFIED IDEOGRAPH
+0xE877	0x9467	#CJK UNIFIED IDEOGRAPH
+0xE878	0x9468	#CJK UNIFIED IDEOGRAPH
+0xE879	0x9469	#CJK UNIFIED IDEOGRAPH
+0xE87A	0x946A	#CJK UNIFIED IDEOGRAPH
+0xE87B	0x946C	#CJK UNIFIED IDEOGRAPH
+0xE87C	0x946D	#CJK UNIFIED IDEOGRAPH
+0xE87D	0x946E	#CJK UNIFIED IDEOGRAPH
+0xE87E	0x946F	#CJK UNIFIED IDEOGRAPH
+0xE880	0x9470	#CJK UNIFIED IDEOGRAPH
+0xE881	0x9471	#CJK UNIFIED IDEOGRAPH
+0xE882	0x9472	#CJK UNIFIED IDEOGRAPH
+0xE883	0x9473	#CJK UNIFIED IDEOGRAPH
+0xE884	0x9474	#CJK UNIFIED IDEOGRAPH
+0xE885	0x9475	#CJK UNIFIED IDEOGRAPH
+0xE886	0x9476	#CJK UNIFIED IDEOGRAPH
+0xE887	0x9477	#CJK UNIFIED IDEOGRAPH
+0xE888	0x9478	#CJK UNIFIED IDEOGRAPH
+0xE889	0x9479	#CJK UNIFIED IDEOGRAPH
+0xE88A	0x947A	#CJK UNIFIED IDEOGRAPH
+0xE88B	0x947B	#CJK UNIFIED IDEOGRAPH
+0xE88C	0x947C	#CJK UNIFIED IDEOGRAPH
+0xE88D	0x947D	#CJK UNIFIED IDEOGRAPH
+0xE88E	0x947E	#CJK UNIFIED IDEOGRAPH
+0xE88F	0x947F	#CJK UNIFIED IDEOGRAPH
+0xE890	0x9480	#CJK UNIFIED IDEOGRAPH
+0xE891	0x9481	#CJK UNIFIED IDEOGRAPH
+0xE892	0x9482	#CJK UNIFIED IDEOGRAPH
+0xE893	0x9483	#CJK UNIFIED IDEOGRAPH
+0xE894	0x9484	#CJK UNIFIED IDEOGRAPH
+0xE895	0x9491	#CJK UNIFIED IDEOGRAPH
+0xE896	0x9496	#CJK UNIFIED IDEOGRAPH
+0xE897	0x9498	#CJK UNIFIED IDEOGRAPH
+0xE898	0x94C7	#CJK UNIFIED IDEOGRAPH
+0xE899	0x94CF	#CJK UNIFIED IDEOGRAPH
+0xE89A	0x94D3	#CJK UNIFIED IDEOGRAPH
+0xE89B	0x94D4	#CJK UNIFIED IDEOGRAPH
+0xE89C	0x94DA	#CJK UNIFIED IDEOGRAPH
+0xE89D	0x94E6	#CJK UNIFIED IDEOGRAPH
+0xE89E	0x94FB	#CJK UNIFIED IDEOGRAPH
+0xE89F	0x951C	#CJK UNIFIED IDEOGRAPH
+0xE8A0	0x9520	#CJK UNIFIED IDEOGRAPH
+0xE8A1	0x741B	#CJK UNIFIED IDEOGRAPH
+0xE8A2	0x741A	#CJK UNIFIED IDEOGRAPH
+0xE8A3	0x7441	#CJK UNIFIED IDEOGRAPH
+0xE8A4	0x745C	#CJK UNIFIED IDEOGRAPH
+0xE8A5	0x7457	#CJK UNIFIED IDEOGRAPH
+0xE8A6	0x7455	#CJK UNIFIED IDEOGRAPH
+0xE8A7	0x7459	#CJK UNIFIED IDEOGRAPH
+0xE8A8	0x7477	#CJK UNIFIED IDEOGRAPH
+0xE8A9	0x746D	#CJK UNIFIED IDEOGRAPH
+0xE8AA	0x747E	#CJK UNIFIED IDEOGRAPH
+0xE8AB	0x749C	#CJK UNIFIED IDEOGRAPH
+0xE8AC	0x748E	#CJK UNIFIED IDEOGRAPH
+0xE8AD	0x7480	#CJK UNIFIED IDEOGRAPH
+0xE8AE	0x7481	#CJK UNIFIED IDEOGRAPH
+0xE8AF	0x7487	#CJK UNIFIED IDEOGRAPH
+0xE8B0	0x748B	#CJK UNIFIED IDEOGRAPH
+0xE8B1	0x749E	#CJK UNIFIED IDEOGRAPH
+0xE8B2	0x74A8	#CJK UNIFIED IDEOGRAPH
+0xE8B3	0x74A9	#CJK UNIFIED IDEOGRAPH
+0xE8B4	0x7490	#CJK UNIFIED IDEOGRAPH
+0xE8B5	0x74A7	#CJK UNIFIED IDEOGRAPH
+0xE8B6	0x74D2	#CJK UNIFIED IDEOGRAPH
+0xE8B7	0x74BA	#CJK UNIFIED IDEOGRAPH
+0xE8B8	0x97EA	#CJK UNIFIED IDEOGRAPH
+0xE8B9	0x97EB	#CJK UNIFIED IDEOGRAPH
+0xE8BA	0x97EC	#CJK UNIFIED IDEOGRAPH
+0xE8BB	0x674C	#CJK UNIFIED IDEOGRAPH
+0xE8BC	0x6753	#CJK UNIFIED IDEOGRAPH
+0xE8BD	0x675E	#CJK UNIFIED IDEOGRAPH
+0xE8BE	0x6748	#CJK UNIFIED IDEOGRAPH
+0xE8BF	0x6769	#CJK UNIFIED IDEOGRAPH
+0xE8C0	0x67A5	#CJK UNIFIED IDEOGRAPH
+0xE8C1	0x6787	#CJK UNIFIED IDEOGRAPH
+0xE8C2	0x676A	#CJK UNIFIED IDEOGRAPH
+0xE8C3	0x6773	#CJK UNIFIED IDEOGRAPH
+0xE8C4	0x6798	#CJK UNIFIED IDEOGRAPH
+0xE8C5	0x67A7	#CJK UNIFIED IDEOGRAPH
+0xE8C6	0x6775	#CJK UNIFIED IDEOGRAPH
+0xE8C7	0x67A8	#CJK UNIFIED IDEOGRAPH
+0xE8C8	0x679E	#CJK UNIFIED IDEOGRAPH
+0xE8C9	0x67AD	#CJK UNIFIED IDEOGRAPH
+0xE8CA	0x678B	#CJK UNIFIED IDEOGRAPH
+0xE8CB	0x6777	#CJK UNIFIED IDEOGRAPH
+0xE8CC	0x677C	#CJK UNIFIED IDEOGRAPH
+0xE8CD	0x67F0	#CJK UNIFIED IDEOGRAPH
+0xE8CE	0x6809	#CJK UNIFIED IDEOGRAPH
+0xE8CF	0x67D8	#CJK UNIFIED IDEOGRAPH
+0xE8D0	0x680A	#CJK UNIFIED IDEOGRAPH
+0xE8D1	0x67E9	#CJK UNIFIED IDEOGRAPH
+0xE8D2	0x67B0	#CJK UNIFIED IDEOGRAPH
+0xE8D3	0x680C	#CJK UNIFIED IDEOGRAPH
+0xE8D4	0x67D9	#CJK UNIFIED IDEOGRAPH
+0xE8D5	0x67B5	#CJK UNIFIED IDEOGRAPH
+0xE8D6	0x67DA	#CJK UNIFIED IDEOGRAPH
+0xE8D7	0x67B3	#CJK UNIFIED IDEOGRAPH
+0xE8D8	0x67DD	#CJK UNIFIED IDEOGRAPH
+0xE8D9	0x6800	#CJK UNIFIED IDEOGRAPH
+0xE8DA	0x67C3	#CJK UNIFIED IDEOGRAPH
+0xE8DB	0x67B8	#CJK UNIFIED IDEOGRAPH
+0xE8DC	0x67E2	#CJK UNIFIED IDEOGRAPH
+0xE8DD	0x680E	#CJK UNIFIED IDEOGRAPH
+0xE8DE	0x67C1	#CJK UNIFIED IDEOGRAPH
+0xE8DF	0x67FD	#CJK UNIFIED IDEOGRAPH
+0xE8E0	0x6832	#CJK UNIFIED IDEOGRAPH
+0xE8E1	0x6833	#CJK UNIFIED IDEOGRAPH
+0xE8E2	0x6860	#CJK UNIFIED IDEOGRAPH
+0xE8E3	0x6861	#CJK UNIFIED IDEOGRAPH
+0xE8E4	0x684E	#CJK UNIFIED IDEOGRAPH
+0xE8E5	0x6862	#CJK UNIFIED IDEOGRAPH
+0xE8E6	0x6844	#CJK UNIFIED IDEOGRAPH
+0xE8E7	0x6864	#CJK UNIFIED IDEOGRAPH
+0xE8E8	0x6883	#CJK UNIFIED IDEOGRAPH
+0xE8E9	0x681D	#CJK UNIFIED IDEOGRAPH
+0xE8EA	0x6855	#CJK UNIFIED IDEOGRAPH
+0xE8EB	0x6866	#CJK UNIFIED IDEOGRAPH
+0xE8EC	0x6841	#CJK UNIFIED IDEOGRAPH
+0xE8ED	0x6867	#CJK UNIFIED IDEOGRAPH
+0xE8EE	0x6840	#CJK UNIFIED IDEOGRAPH
+0xE8EF	0x683E	#CJK UNIFIED IDEOGRAPH
+0xE8F0	0x684A	#CJK UNIFIED IDEOGRAPH
+0xE8F1	0x6849	#CJK UNIFIED IDEOGRAPH
+0xE8F2	0x6829	#CJK UNIFIED IDEOGRAPH
+0xE8F3	0x68B5	#CJK UNIFIED IDEOGRAPH
+0xE8F4	0x688F	#CJK UNIFIED IDEOGRAPH
+0xE8F5	0x6874	#CJK UNIFIED IDEOGRAPH
+0xE8F6	0x6877	#CJK UNIFIED IDEOGRAPH
+0xE8F7	0x6893	#CJK UNIFIED IDEOGRAPH
+0xE8F8	0x686B	#CJK UNIFIED IDEOGRAPH
+0xE8F9	0x68C2	#CJK UNIFIED IDEOGRAPH
+0xE8FA	0x696E	#CJK UNIFIED IDEOGRAPH
+0xE8FB	0x68FC	#CJK UNIFIED IDEOGRAPH
+0xE8FC	0x691F	#CJK UNIFIED IDEOGRAPH
+0xE8FD	0x6920	#CJK UNIFIED IDEOGRAPH
+0xE8FE	0x68F9	#CJK UNIFIED IDEOGRAPH
+0xE940	0x9527	#CJK UNIFIED IDEOGRAPH
+0xE941	0x9533	#CJK UNIFIED IDEOGRAPH
+0xE942	0x953D	#CJK UNIFIED IDEOGRAPH
+0xE943	0x9543	#CJK UNIFIED IDEOGRAPH
+0xE944	0x9548	#CJK UNIFIED IDEOGRAPH
+0xE945	0x954B	#CJK UNIFIED IDEOGRAPH
+0xE946	0x9555	#CJK UNIFIED IDEOGRAPH
+0xE947	0x955A	#CJK UNIFIED IDEOGRAPH
+0xE948	0x9560	#CJK UNIFIED IDEOGRAPH
+0xE949	0x956E	#CJK UNIFIED IDEOGRAPH
+0xE94A	0x9574	#CJK UNIFIED IDEOGRAPH
+0xE94B	0x9575	#CJK UNIFIED IDEOGRAPH
+0xE94C	0x9577	#CJK UNIFIED IDEOGRAPH
+0xE94D	0x9578	#CJK UNIFIED IDEOGRAPH
+0xE94E	0x9579	#CJK UNIFIED IDEOGRAPH
+0xE94F	0x957A	#CJK UNIFIED IDEOGRAPH
+0xE950	0x957B	#CJK UNIFIED IDEOGRAPH
+0xE951	0x957C	#CJK UNIFIED IDEOGRAPH
+0xE952	0x957D	#CJK UNIFIED IDEOGRAPH
+0xE953	0x957E	#CJK UNIFIED IDEOGRAPH
+0xE954	0x9580	#CJK UNIFIED IDEOGRAPH
+0xE955	0x9581	#CJK UNIFIED IDEOGRAPH
+0xE956	0x9582	#CJK UNIFIED IDEOGRAPH
+0xE957	0x9583	#CJK UNIFIED IDEOGRAPH
+0xE958	0x9584	#CJK UNIFIED IDEOGRAPH
+0xE959	0x9585	#CJK UNIFIED IDEOGRAPH
+0xE95A	0x9586	#CJK UNIFIED IDEOGRAPH
+0xE95B	0x9587	#CJK UNIFIED IDEOGRAPH
+0xE95C	0x9588	#CJK UNIFIED IDEOGRAPH
+0xE95D	0x9589	#CJK UNIFIED IDEOGRAPH
+0xE95E	0x958A	#CJK UNIFIED IDEOGRAPH
+0xE95F	0x958B	#CJK UNIFIED IDEOGRAPH
+0xE960	0x958C	#CJK UNIFIED IDEOGRAPH
+0xE961	0x958D	#CJK UNIFIED IDEOGRAPH
+0xE962	0x958E	#CJK UNIFIED IDEOGRAPH
+0xE963	0x958F	#CJK UNIFIED IDEOGRAPH
+0xE964	0x9590	#CJK UNIFIED IDEOGRAPH
+0xE965	0x9591	#CJK UNIFIED IDEOGRAPH
+0xE966	0x9592	#CJK UNIFIED IDEOGRAPH
+0xE967	0x9593	#CJK UNIFIED IDEOGRAPH
+0xE968	0x9594	#CJK UNIFIED IDEOGRAPH
+0xE969	0x9595	#CJK UNIFIED IDEOGRAPH
+0xE96A	0x9596	#CJK UNIFIED IDEOGRAPH
+0xE96B	0x9597	#CJK UNIFIED IDEOGRAPH
+0xE96C	0x9598	#CJK UNIFIED IDEOGRAPH
+0xE96D	0x9599	#CJK UNIFIED IDEOGRAPH
+0xE96E	0x959A	#CJK UNIFIED IDEOGRAPH
+0xE96F	0x959B	#CJK UNIFIED IDEOGRAPH
+0xE970	0x959C	#CJK UNIFIED IDEOGRAPH
+0xE971	0x959D	#CJK UNIFIED IDEOGRAPH
+0xE972	0x959E	#CJK UNIFIED IDEOGRAPH
+0xE973	0x959F	#CJK UNIFIED IDEOGRAPH
+0xE974	0x95A0	#CJK UNIFIED IDEOGRAPH
+0xE975	0x95A1	#CJK UNIFIED IDEOGRAPH
+0xE976	0x95A2	#CJK UNIFIED IDEOGRAPH
+0xE977	0x95A3	#CJK UNIFIED IDEOGRAPH
+0xE978	0x95A4	#CJK UNIFIED IDEOGRAPH
+0xE979	0x95A5	#CJK UNIFIED IDEOGRAPH
+0xE97A	0x95A6	#CJK UNIFIED IDEOGRAPH
+0xE97B	0x95A7	#CJK UNIFIED IDEOGRAPH
+0xE97C	0x95A8	#CJK UNIFIED IDEOGRAPH
+0xE97D	0x95A9	#CJK UNIFIED IDEOGRAPH
+0xE97E	0x95AA	#CJK UNIFIED IDEOGRAPH
+0xE980	0x95AB	#CJK UNIFIED IDEOGRAPH
+0xE981	0x95AC	#CJK UNIFIED IDEOGRAPH
+0xE982	0x95AD	#CJK UNIFIED IDEOGRAPH
+0xE983	0x95AE	#CJK UNIFIED IDEOGRAPH
+0xE984	0x95AF	#CJK UNIFIED IDEOGRAPH
+0xE985	0x95B0	#CJK UNIFIED IDEOGRAPH
+0xE986	0x95B1	#CJK UNIFIED IDEOGRAPH
+0xE987	0x95B2	#CJK UNIFIED IDEOGRAPH
+0xE988	0x95B3	#CJK UNIFIED IDEOGRAPH
+0xE989	0x95B4	#CJK UNIFIED IDEOGRAPH
+0xE98A	0x95B5	#CJK UNIFIED IDEOGRAPH
+0xE98B	0x95B6	#CJK UNIFIED IDEOGRAPH
+0xE98C	0x95B7	#CJK UNIFIED IDEOGRAPH
+0xE98D	0x95B8	#CJK UNIFIED IDEOGRAPH
+0xE98E	0x95B9	#CJK UNIFIED IDEOGRAPH
+0xE98F	0x95BA	#CJK UNIFIED IDEOGRAPH
+0xE990	0x95BB	#CJK UNIFIED IDEOGRAPH
+0xE991	0x95BC	#CJK UNIFIED IDEOGRAPH
+0xE992	0x95BD	#CJK UNIFIED IDEOGRAPH
+0xE993	0x95BE	#CJK UNIFIED IDEOGRAPH
+0xE994	0x95BF	#CJK UNIFIED IDEOGRAPH
+0xE995	0x95C0	#CJK UNIFIED IDEOGRAPH
+0xE996	0x95C1	#CJK UNIFIED IDEOGRAPH
+0xE997	0x95C2	#CJK UNIFIED IDEOGRAPH
+0xE998	0x95C3	#CJK UNIFIED IDEOGRAPH
+0xE999	0x95C4	#CJK UNIFIED IDEOGRAPH
+0xE99A	0x95C5	#CJK UNIFIED IDEOGRAPH
+0xE99B	0x95C6	#CJK UNIFIED IDEOGRAPH
+0xE99C	0x95C7	#CJK UNIFIED IDEOGRAPH
+0xE99D	0x95C8	#CJK UNIFIED IDEOGRAPH
+0xE99E	0x95C9	#CJK UNIFIED IDEOGRAPH
+0xE99F	0x95CA	#CJK UNIFIED IDEOGRAPH
+0xE9A0	0x95CB	#CJK UNIFIED IDEOGRAPH
+0xE9A1	0x6924	#CJK UNIFIED IDEOGRAPH
+0xE9A2	0x68F0	#CJK UNIFIED IDEOGRAPH
+0xE9A3	0x690B	#CJK UNIFIED IDEOGRAPH
+0xE9A4	0x6901	#CJK UNIFIED IDEOGRAPH
+0xE9A5	0x6957	#CJK UNIFIED IDEOGRAPH
+0xE9A6	0x68E3	#CJK UNIFIED IDEOGRAPH
+0xE9A7	0x6910	#CJK UNIFIED IDEOGRAPH
+0xE9A8	0x6971	#CJK UNIFIED IDEOGRAPH
+0xE9A9	0x6939	#CJK UNIFIED IDEOGRAPH
+0xE9AA	0x6960	#CJK UNIFIED IDEOGRAPH
+0xE9AB	0x6942	#CJK UNIFIED IDEOGRAPH
+0xE9AC	0x695D	#CJK UNIFIED IDEOGRAPH
+0xE9AD	0x6984	#CJK UNIFIED IDEOGRAPH
+0xE9AE	0x696B	#CJK UNIFIED IDEOGRAPH
+0xE9AF	0x6980	#CJK UNIFIED IDEOGRAPH
+0xE9B0	0x6998	#CJK UNIFIED IDEOGRAPH
+0xE9B1	0x6978	#CJK UNIFIED IDEOGRAPH
+0xE9B2	0x6934	#CJK UNIFIED IDEOGRAPH
+0xE9B3	0x69CC	#CJK UNIFIED IDEOGRAPH
+0xE9B4	0x6987	#CJK UNIFIED IDEOGRAPH
+0xE9B5	0x6988	#CJK UNIFIED IDEOGRAPH
+0xE9B6	0x69CE	#CJK UNIFIED IDEOGRAPH
+0xE9B7	0x6989	#CJK UNIFIED IDEOGRAPH
+0xE9B8	0x6966	#CJK UNIFIED IDEOGRAPH
+0xE9B9	0x6963	#CJK UNIFIED IDEOGRAPH
+0xE9BA	0x6979	#CJK UNIFIED IDEOGRAPH
+0xE9BB	0x699B	#CJK UNIFIED IDEOGRAPH
+0xE9BC	0x69A7	#CJK UNIFIED IDEOGRAPH
+0xE9BD	0x69BB	#CJK UNIFIED IDEOGRAPH
+0xE9BE	0x69AB	#CJK UNIFIED IDEOGRAPH
+0xE9BF	0x69AD	#CJK UNIFIED IDEOGRAPH
+0xE9C0	0x69D4	#CJK UNIFIED IDEOGRAPH
+0xE9C1	0x69B1	#CJK UNIFIED IDEOGRAPH
+0xE9C2	0x69C1	#CJK UNIFIED IDEOGRAPH
+0xE9C3	0x69CA	#CJK UNIFIED IDEOGRAPH
+0xE9C4	0x69DF	#CJK UNIFIED IDEOGRAPH
+0xE9C5	0x6995	#CJK UNIFIED IDEOGRAPH
+0xE9C6	0x69E0	#CJK UNIFIED IDEOGRAPH
+0xE9C7	0x698D	#CJK UNIFIED IDEOGRAPH
+0xE9C8	0x69FF	#CJK UNIFIED IDEOGRAPH
+0xE9C9	0x6A2F	#CJK UNIFIED IDEOGRAPH
+0xE9CA	0x69ED	#CJK UNIFIED IDEOGRAPH
+0xE9CB	0x6A17	#CJK UNIFIED IDEOGRAPH
+0xE9CC	0x6A18	#CJK UNIFIED IDEOGRAPH
+0xE9CD	0x6A65	#CJK UNIFIED IDEOGRAPH
+0xE9CE	0x69F2	#CJK UNIFIED IDEOGRAPH
+0xE9CF	0x6A44	#CJK UNIFIED IDEOGRAPH
+0xE9D0	0x6A3E	#CJK UNIFIED IDEOGRAPH
+0xE9D1	0x6AA0	#CJK UNIFIED IDEOGRAPH
+0xE9D2	0x6A50	#CJK UNIFIED IDEOGRAPH
+0xE9D3	0x6A5B	#CJK UNIFIED IDEOGRAPH
+0xE9D4	0x6A35	#CJK UNIFIED IDEOGRAPH
+0xE9D5	0x6A8E	#CJK UNIFIED IDEOGRAPH
+0xE9D6	0x6A79	#CJK UNIFIED IDEOGRAPH
+0xE9D7	0x6A3D	#CJK UNIFIED IDEOGRAPH
+0xE9D8	0x6A28	#CJK UNIFIED IDEOGRAPH
+0xE9D9	0x6A58	#CJK UNIFIED IDEOGRAPH
+0xE9DA	0x6A7C	#CJK UNIFIED IDEOGRAPH
+0xE9DB	0x6A91	#CJK UNIFIED IDEOGRAPH
+0xE9DC	0x6A90	#CJK UNIFIED IDEOGRAPH
+0xE9DD	0x6AA9	#CJK UNIFIED IDEOGRAPH
+0xE9DE	0x6A97	#CJK UNIFIED IDEOGRAPH
+0xE9DF	0x6AAB	#CJK UNIFIED IDEOGRAPH
+0xE9E0	0x7337	#CJK UNIFIED IDEOGRAPH
+0xE9E1	0x7352	#CJK UNIFIED IDEOGRAPH
+0xE9E2	0x6B81	#CJK UNIFIED IDEOGRAPH
+0xE9E3	0x6B82	#CJK UNIFIED IDEOGRAPH
+0xE9E4	0x6B87	#CJK UNIFIED IDEOGRAPH
+0xE9E5	0x6B84	#CJK UNIFIED IDEOGRAPH
+0xE9E6	0x6B92	#CJK UNIFIED IDEOGRAPH
+0xE9E7	0x6B93	#CJK UNIFIED IDEOGRAPH
+0xE9E8	0x6B8D	#CJK UNIFIED IDEOGRAPH
+0xE9E9	0x6B9A	#CJK UNIFIED IDEOGRAPH
+0xE9EA	0x6B9B	#CJK UNIFIED IDEOGRAPH
+0xE9EB	0x6BA1	#CJK UNIFIED IDEOGRAPH
+0xE9EC	0x6BAA	#CJK UNIFIED IDEOGRAPH
+0xE9ED	0x8F6B	#CJK UNIFIED IDEOGRAPH
+0xE9EE	0x8F6D	#CJK UNIFIED IDEOGRAPH
+0xE9EF	0x8F71	#CJK UNIFIED IDEOGRAPH
+0xE9F0	0x8F72	#CJK UNIFIED IDEOGRAPH
+0xE9F1	0x8F73	#CJK UNIFIED IDEOGRAPH
+0xE9F2	0x8F75	#CJK UNIFIED IDEOGRAPH
+0xE9F3	0x8F76	#CJK UNIFIED IDEOGRAPH
+0xE9F4	0x8F78	#CJK UNIFIED IDEOGRAPH
+0xE9F5	0x8F77	#CJK UNIFIED IDEOGRAPH
+0xE9F6	0x8F79	#CJK UNIFIED IDEOGRAPH
+0xE9F7	0x8F7A	#CJK UNIFIED IDEOGRAPH
+0xE9F8	0x8F7C	#CJK UNIFIED IDEOGRAPH
+0xE9F9	0x8F7E	#CJK UNIFIED IDEOGRAPH
+0xE9FA	0x8F81	#CJK UNIFIED IDEOGRAPH
+0xE9FB	0x8F82	#CJK UNIFIED IDEOGRAPH
+0xE9FC	0x8F84	#CJK UNIFIED IDEOGRAPH
+0xE9FD	0x8F87	#CJK UNIFIED IDEOGRAPH
+0xE9FE	0x8F8B	#CJK UNIFIED IDEOGRAPH
+0xEA40	0x95CC	#CJK UNIFIED IDEOGRAPH
+0xEA41	0x95CD	#CJK UNIFIED IDEOGRAPH
+0xEA42	0x95CE	#CJK UNIFIED IDEOGRAPH
+0xEA43	0x95CF	#CJK UNIFIED IDEOGRAPH
+0xEA44	0x95D0	#CJK UNIFIED IDEOGRAPH
+0xEA45	0x95D1	#CJK UNIFIED IDEOGRAPH
+0xEA46	0x95D2	#CJK UNIFIED IDEOGRAPH
+0xEA47	0x95D3	#CJK UNIFIED IDEOGRAPH
+0xEA48	0x95D4	#CJK UNIFIED IDEOGRAPH
+0xEA49	0x95D5	#CJK UNIFIED IDEOGRAPH
+0xEA4A	0x95D6	#CJK UNIFIED IDEOGRAPH
+0xEA4B	0x95D7	#CJK UNIFIED IDEOGRAPH
+0xEA4C	0x95D8	#CJK UNIFIED IDEOGRAPH
+0xEA4D	0x95D9	#CJK UNIFIED IDEOGRAPH
+0xEA4E	0x95DA	#CJK UNIFIED IDEOGRAPH
+0xEA4F	0x95DB	#CJK UNIFIED IDEOGRAPH
+0xEA50	0x95DC	#CJK UNIFIED IDEOGRAPH
+0xEA51	0x95DD	#CJK UNIFIED IDEOGRAPH
+0xEA52	0x95DE	#CJK UNIFIED IDEOGRAPH
+0xEA53	0x95DF	#CJK UNIFIED IDEOGRAPH
+0xEA54	0x95E0	#CJK UNIFIED IDEOGRAPH
+0xEA55	0x95E1	#CJK UNIFIED IDEOGRAPH
+0xEA56	0x95E2	#CJK UNIFIED IDEOGRAPH
+0xEA57	0x95E3	#CJK UNIFIED IDEOGRAPH
+0xEA58	0x95E4	#CJK UNIFIED IDEOGRAPH
+0xEA59	0x95E5	#CJK UNIFIED IDEOGRAPH
+0xEA5A	0x95E6	#CJK UNIFIED IDEOGRAPH
+0xEA5B	0x95E7	#CJK UNIFIED IDEOGRAPH
+0xEA5C	0x95EC	#CJK UNIFIED IDEOGRAPH
+0xEA5D	0x95FF	#CJK UNIFIED IDEOGRAPH
+0xEA5E	0x9607	#CJK UNIFIED IDEOGRAPH
+0xEA5F	0x9613	#CJK UNIFIED IDEOGRAPH
+0xEA60	0x9618	#CJK UNIFIED IDEOGRAPH
+0xEA61	0x961B	#CJK UNIFIED IDEOGRAPH
+0xEA62	0x961E	#CJK UNIFIED IDEOGRAPH
+0xEA63	0x9620	#CJK UNIFIED IDEOGRAPH
+0xEA64	0x9623	#CJK UNIFIED IDEOGRAPH
+0xEA65	0x9624	#CJK UNIFIED IDEOGRAPH
+0xEA66	0x9625	#CJK UNIFIED IDEOGRAPH
+0xEA67	0x9626	#CJK UNIFIED IDEOGRAPH
+0xEA68	0x9627	#CJK UNIFIED IDEOGRAPH
+0xEA69	0x9628	#CJK UNIFIED IDEOGRAPH
+0xEA6A	0x9629	#CJK UNIFIED IDEOGRAPH
+0xEA6B	0x962B	#CJK UNIFIED IDEOGRAPH
+0xEA6C	0x962C	#CJK UNIFIED IDEOGRAPH
+0xEA6D	0x962D	#CJK UNIFIED IDEOGRAPH
+0xEA6E	0x962F	#CJK UNIFIED IDEOGRAPH
+0xEA6F	0x9630	#CJK UNIFIED IDEOGRAPH
+0xEA70	0x9637	#CJK UNIFIED IDEOGRAPH
+0xEA71	0x9638	#CJK UNIFIED IDEOGRAPH
+0xEA72	0x9639	#CJK UNIFIED IDEOGRAPH
+0xEA73	0x963A	#CJK UNIFIED IDEOGRAPH
+0xEA74	0x963E	#CJK UNIFIED IDEOGRAPH
+0xEA75	0x9641	#CJK UNIFIED IDEOGRAPH
+0xEA76	0x9643	#CJK UNIFIED IDEOGRAPH
+0xEA77	0x964A	#CJK UNIFIED IDEOGRAPH
+0xEA78	0x964E	#CJK UNIFIED IDEOGRAPH
+0xEA79	0x964F	#CJK UNIFIED IDEOGRAPH
+0xEA7A	0x9651	#CJK UNIFIED IDEOGRAPH
+0xEA7B	0x9652	#CJK UNIFIED IDEOGRAPH
+0xEA7C	0x9653	#CJK UNIFIED IDEOGRAPH
+0xEA7D	0x9656	#CJK UNIFIED IDEOGRAPH
+0xEA7E	0x9657	#CJK UNIFIED IDEOGRAPH
+0xEA80	0x9658	#CJK UNIFIED IDEOGRAPH
+0xEA81	0x9659	#CJK UNIFIED IDEOGRAPH
+0xEA82	0x965A	#CJK UNIFIED IDEOGRAPH
+0xEA83	0x965C	#CJK UNIFIED IDEOGRAPH
+0xEA84	0x965D	#CJK UNIFIED IDEOGRAPH
+0xEA85	0x965E	#CJK UNIFIED IDEOGRAPH
+0xEA86	0x9660	#CJK UNIFIED IDEOGRAPH
+0xEA87	0x9663	#CJK UNIFIED IDEOGRAPH
+0xEA88	0x9665	#CJK UNIFIED IDEOGRAPH
+0xEA89	0x9666	#CJK UNIFIED IDEOGRAPH
+0xEA8A	0x966B	#CJK UNIFIED IDEOGRAPH
+0xEA8B	0x966D	#CJK UNIFIED IDEOGRAPH
+0xEA8C	0x966E	#CJK UNIFIED IDEOGRAPH
+0xEA8D	0x966F	#CJK UNIFIED IDEOGRAPH
+0xEA8E	0x9670	#CJK UNIFIED IDEOGRAPH
+0xEA8F	0x9671	#CJK UNIFIED IDEOGRAPH
+0xEA90	0x9673	#CJK UNIFIED IDEOGRAPH
+0xEA91	0x9678	#CJK UNIFIED IDEOGRAPH
+0xEA92	0x9679	#CJK UNIFIED IDEOGRAPH
+0xEA93	0x967A	#CJK UNIFIED IDEOGRAPH
+0xEA94	0x967B	#CJK UNIFIED IDEOGRAPH
+0xEA95	0x967C	#CJK UNIFIED IDEOGRAPH
+0xEA96	0x967D	#CJK UNIFIED IDEOGRAPH
+0xEA97	0x967E	#CJK UNIFIED IDEOGRAPH
+0xEA98	0x967F	#CJK UNIFIED IDEOGRAPH
+0xEA99	0x9680	#CJK UNIFIED IDEOGRAPH
+0xEA9A	0x9681	#CJK UNIFIED IDEOGRAPH
+0xEA9B	0x9682	#CJK UNIFIED IDEOGRAPH
+0xEA9C	0x9683	#CJK UNIFIED IDEOGRAPH
+0xEA9D	0x9684	#CJK UNIFIED IDEOGRAPH
+0xEA9E	0x9687	#CJK UNIFIED IDEOGRAPH
+0xEA9F	0x9689	#CJK UNIFIED IDEOGRAPH
+0xEAA0	0x968A	#CJK UNIFIED IDEOGRAPH
+0xEAA1	0x8F8D	#CJK UNIFIED IDEOGRAPH
+0xEAA2	0x8F8E	#CJK UNIFIED IDEOGRAPH
+0xEAA3	0x8F8F	#CJK UNIFIED IDEOGRAPH
+0xEAA4	0x8F98	#CJK UNIFIED IDEOGRAPH
+0xEAA5	0x8F9A	#CJK UNIFIED IDEOGRAPH
+0xEAA6	0x8ECE	#CJK UNIFIED IDEOGRAPH
+0xEAA7	0x620B	#CJK UNIFIED IDEOGRAPH
+0xEAA8	0x6217	#CJK UNIFIED IDEOGRAPH
+0xEAA9	0x621B	#CJK UNIFIED IDEOGRAPH
+0xEAAA	0x621F	#CJK UNIFIED IDEOGRAPH
+0xEAAB	0x6222	#CJK UNIFIED IDEOGRAPH
+0xEAAC	0x6221	#CJK UNIFIED IDEOGRAPH
+0xEAAD	0x6225	#CJK UNIFIED IDEOGRAPH
+0xEAAE	0x6224	#CJK UNIFIED IDEOGRAPH
+0xEAAF	0x622C	#CJK UNIFIED IDEOGRAPH
+0xEAB0	0x81E7	#CJK UNIFIED IDEOGRAPH
+0xEAB1	0x74EF	#CJK UNIFIED IDEOGRAPH
+0xEAB2	0x74F4	#CJK UNIFIED IDEOGRAPH
+0xEAB3	0x74FF	#CJK UNIFIED IDEOGRAPH
+0xEAB4	0x750F	#CJK UNIFIED IDEOGRAPH
+0xEAB5	0x7511	#CJK UNIFIED IDEOGRAPH
+0xEAB6	0x7513	#CJK UNIFIED IDEOGRAPH
+0xEAB7	0x6534	#CJK UNIFIED IDEOGRAPH
+0xEAB8	0x65EE	#CJK UNIFIED IDEOGRAPH
+0xEAB9	0x65EF	#CJK UNIFIED IDEOGRAPH
+0xEABA	0x65F0	#CJK UNIFIED IDEOGRAPH
+0xEABB	0x660A	#CJK UNIFIED IDEOGRAPH
+0xEABC	0x6619	#CJK UNIFIED IDEOGRAPH
+0xEABD	0x6772	#CJK UNIFIED IDEOGRAPH
+0xEABE	0x6603	#CJK UNIFIED IDEOGRAPH
+0xEABF	0x6615	#CJK UNIFIED IDEOGRAPH
+0xEAC0	0x6600	#CJK UNIFIED IDEOGRAPH
+0xEAC1	0x7085	#CJK UNIFIED IDEOGRAPH
+0xEAC2	0x66F7	#CJK UNIFIED IDEOGRAPH
+0xEAC3	0x661D	#CJK UNIFIED IDEOGRAPH
+0xEAC4	0x6634	#CJK UNIFIED IDEOGRAPH
+0xEAC5	0x6631	#CJK UNIFIED IDEOGRAPH
+0xEAC6	0x6636	#CJK UNIFIED IDEOGRAPH
+0xEAC7	0x6635	#CJK UNIFIED IDEOGRAPH
+0xEAC8	0x8006	#CJK UNIFIED IDEOGRAPH
+0xEAC9	0x665F	#CJK UNIFIED IDEOGRAPH
+0xEACA	0x6654	#CJK UNIFIED IDEOGRAPH
+0xEACB	0x6641	#CJK UNIFIED IDEOGRAPH
+0xEACC	0x664F	#CJK UNIFIED IDEOGRAPH
+0xEACD	0x6656	#CJK UNIFIED IDEOGRAPH
+0xEACE	0x6661	#CJK UNIFIED IDEOGRAPH
+0xEACF	0x6657	#CJK UNIFIED IDEOGRAPH
+0xEAD0	0x6677	#CJK UNIFIED IDEOGRAPH
+0xEAD1	0x6684	#CJK UNIFIED IDEOGRAPH
+0xEAD2	0x668C	#CJK UNIFIED IDEOGRAPH
+0xEAD3	0x66A7	#CJK UNIFIED IDEOGRAPH
+0xEAD4	0x669D	#CJK UNIFIED IDEOGRAPH
+0xEAD5	0x66BE	#CJK UNIFIED IDEOGRAPH
+0xEAD6	0x66DB	#CJK UNIFIED IDEOGRAPH
+0xEAD7	0x66DC	#CJK UNIFIED IDEOGRAPH
+0xEAD8	0x66E6	#CJK UNIFIED IDEOGRAPH
+0xEAD9	0x66E9	#CJK UNIFIED IDEOGRAPH
+0xEADA	0x8D32	#CJK UNIFIED IDEOGRAPH
+0xEADB	0x8D33	#CJK UNIFIED IDEOGRAPH
+0xEADC	0x8D36	#CJK UNIFIED IDEOGRAPH
+0xEADD	0x8D3B	#CJK UNIFIED IDEOGRAPH
+0xEADE	0x8D3D	#CJK UNIFIED IDEOGRAPH
+0xEADF	0x8D40	#CJK UNIFIED IDEOGRAPH
+0xEAE0	0x8D45	#CJK UNIFIED IDEOGRAPH
+0xEAE1	0x8D46	#CJK UNIFIED IDEOGRAPH
+0xEAE2	0x8D48	#CJK UNIFIED IDEOGRAPH
+0xEAE3	0x8D49	#CJK UNIFIED IDEOGRAPH
+0xEAE4	0x8D47	#CJK UNIFIED IDEOGRAPH
+0xEAE5	0x8D4D	#CJK UNIFIED IDEOGRAPH
+0xEAE6	0x8D55	#CJK UNIFIED IDEOGRAPH
+0xEAE7	0x8D59	#CJK UNIFIED IDEOGRAPH
+0xEAE8	0x89C7	#CJK UNIFIED IDEOGRAPH
+0xEAE9	0x89CA	#CJK UNIFIED IDEOGRAPH
+0xEAEA	0x89CB	#CJK UNIFIED IDEOGRAPH
+0xEAEB	0x89CC	#CJK UNIFIED IDEOGRAPH
+0xEAEC	0x89CE	#CJK UNIFIED IDEOGRAPH
+0xEAED	0x89CF	#CJK UNIFIED IDEOGRAPH
+0xEAEE	0x89D0	#CJK UNIFIED IDEOGRAPH
+0xEAEF	0x89D1	#CJK UNIFIED IDEOGRAPH
+0xEAF0	0x726E	#CJK UNIFIED IDEOGRAPH
+0xEAF1	0x729F	#CJK UNIFIED IDEOGRAPH
+0xEAF2	0x725D	#CJK UNIFIED IDEOGRAPH
+0xEAF3	0x7266	#CJK UNIFIED IDEOGRAPH
+0xEAF4	0x726F	#CJK UNIFIED IDEOGRAPH
+0xEAF5	0x727E	#CJK UNIFIED IDEOGRAPH
+0xEAF6	0x727F	#CJK UNIFIED IDEOGRAPH
+0xEAF7	0x7284	#CJK UNIFIED IDEOGRAPH
+0xEAF8	0x728B	#CJK UNIFIED IDEOGRAPH
+0xEAF9	0x728D	#CJK UNIFIED IDEOGRAPH
+0xEAFA	0x728F	#CJK UNIFIED IDEOGRAPH
+0xEAFB	0x7292	#CJK UNIFIED IDEOGRAPH
+0xEAFC	0x6308	#CJK UNIFIED IDEOGRAPH
+0xEAFD	0x6332	#CJK UNIFIED IDEOGRAPH
+0xEAFE	0x63B0	#CJK UNIFIED IDEOGRAPH
+0xEB40	0x968C	#CJK UNIFIED IDEOGRAPH
+0xEB41	0x968E	#CJK UNIFIED IDEOGRAPH
+0xEB42	0x9691	#CJK UNIFIED IDEOGRAPH
+0xEB43	0x9692	#CJK UNIFIED IDEOGRAPH
+0xEB44	0x9693	#CJK UNIFIED IDEOGRAPH
+0xEB45	0x9695	#CJK UNIFIED IDEOGRAPH
+0xEB46	0x9696	#CJK UNIFIED IDEOGRAPH
+0xEB47	0x969A	#CJK UNIFIED IDEOGRAPH
+0xEB48	0x969B	#CJK UNIFIED IDEOGRAPH
+0xEB49	0x969D	#CJK UNIFIED IDEOGRAPH
+0xEB4A	0x969E	#CJK UNIFIED IDEOGRAPH
+0xEB4B	0x969F	#CJK UNIFIED IDEOGRAPH
+0xEB4C	0x96A0	#CJK UNIFIED IDEOGRAPH
+0xEB4D	0x96A1	#CJK UNIFIED IDEOGRAPH
+0xEB4E	0x96A2	#CJK UNIFIED IDEOGRAPH
+0xEB4F	0x96A3	#CJK UNIFIED IDEOGRAPH
+0xEB50	0x96A4	#CJK UNIFIED IDEOGRAPH
+0xEB51	0x96A5	#CJK UNIFIED IDEOGRAPH
+0xEB52	0x96A6	#CJK UNIFIED IDEOGRAPH
+0xEB53	0x96A8	#CJK UNIFIED IDEOGRAPH
+0xEB54	0x96A9	#CJK UNIFIED IDEOGRAPH
+0xEB55	0x96AA	#CJK UNIFIED IDEOGRAPH
+0xEB56	0x96AB	#CJK UNIFIED IDEOGRAPH
+0xEB57	0x96AC	#CJK UNIFIED IDEOGRAPH
+0xEB58	0x96AD	#CJK UNIFIED IDEOGRAPH
+0xEB59	0x96AE	#CJK UNIFIED IDEOGRAPH
+0xEB5A	0x96AF	#CJK UNIFIED IDEOGRAPH
+0xEB5B	0x96B1	#CJK UNIFIED IDEOGRAPH
+0xEB5C	0x96B2	#CJK UNIFIED IDEOGRAPH
+0xEB5D	0x96B4	#CJK UNIFIED IDEOGRAPH
+0xEB5E	0x96B5	#CJK UNIFIED IDEOGRAPH
+0xEB5F	0x96B7	#CJK UNIFIED IDEOGRAPH
+0xEB60	0x96B8	#CJK UNIFIED IDEOGRAPH
+0xEB61	0x96BA	#CJK UNIFIED IDEOGRAPH
+0xEB62	0x96BB	#CJK UNIFIED IDEOGRAPH
+0xEB63	0x96BF	#CJK UNIFIED IDEOGRAPH
+0xEB64	0x96C2	#CJK UNIFIED IDEOGRAPH
+0xEB65	0x96C3	#CJK UNIFIED IDEOGRAPH
+0xEB66	0x96C8	#CJK UNIFIED IDEOGRAPH
+0xEB67	0x96CA	#CJK UNIFIED IDEOGRAPH
+0xEB68	0x96CB	#CJK UNIFIED IDEOGRAPH
+0xEB69	0x96D0	#CJK UNIFIED IDEOGRAPH
+0xEB6A	0x96D1	#CJK UNIFIED IDEOGRAPH
+0xEB6B	0x96D3	#CJK UNIFIED IDEOGRAPH
+0xEB6C	0x96D4	#CJK UNIFIED IDEOGRAPH
+0xEB6D	0x96D6	#CJK UNIFIED IDEOGRAPH
+0xEB6E	0x96D7	#CJK UNIFIED IDEOGRAPH
+0xEB6F	0x96D8	#CJK UNIFIED IDEOGRAPH
+0xEB70	0x96D9	#CJK UNIFIED IDEOGRAPH
+0xEB71	0x96DA	#CJK UNIFIED IDEOGRAPH
+0xEB72	0x96DB	#CJK UNIFIED IDEOGRAPH
+0xEB73	0x96DC	#CJK UNIFIED IDEOGRAPH
+0xEB74	0x96DD	#CJK UNIFIED IDEOGRAPH
+0xEB75	0x96DE	#CJK UNIFIED IDEOGRAPH
+0xEB76	0x96DF	#CJK UNIFIED IDEOGRAPH
+0xEB77	0x96E1	#CJK UNIFIED IDEOGRAPH
+0xEB78	0x96E2	#CJK UNIFIED IDEOGRAPH
+0xEB79	0x96E3	#CJK UNIFIED IDEOGRAPH
+0xEB7A	0x96E4	#CJK UNIFIED IDEOGRAPH
+0xEB7B	0x96E5	#CJK UNIFIED IDEOGRAPH
+0xEB7C	0x96E6	#CJK UNIFIED IDEOGRAPH
+0xEB7D	0x96E7	#CJK UNIFIED IDEOGRAPH
+0xEB7E	0x96EB	#CJK UNIFIED IDEOGRAPH
+0xEB80	0x96EC	#CJK UNIFIED IDEOGRAPH
+0xEB81	0x96ED	#CJK UNIFIED IDEOGRAPH
+0xEB82	0x96EE	#CJK UNIFIED IDEOGRAPH
+0xEB83	0x96F0	#CJK UNIFIED IDEOGRAPH
+0xEB84	0x96F1	#CJK UNIFIED IDEOGRAPH
+0xEB85	0x96F2	#CJK UNIFIED IDEOGRAPH
+0xEB86	0x96F4	#CJK UNIFIED IDEOGRAPH
+0xEB87	0x96F5	#CJK UNIFIED IDEOGRAPH
+0xEB88	0x96F8	#CJK UNIFIED IDEOGRAPH
+0xEB89	0x96FA	#CJK UNIFIED IDEOGRAPH
+0xEB8A	0x96FB	#CJK UNIFIED IDEOGRAPH
+0xEB8B	0x96FC	#CJK UNIFIED IDEOGRAPH
+0xEB8C	0x96FD	#CJK UNIFIED IDEOGRAPH
+0xEB8D	0x96FF	#CJK UNIFIED IDEOGRAPH
+0xEB8E	0x9702	#CJK UNIFIED IDEOGRAPH
+0xEB8F	0x9703	#CJK UNIFIED IDEOGRAPH
+0xEB90	0x9705	#CJK UNIFIED IDEOGRAPH
+0xEB91	0x970A	#CJK UNIFIED IDEOGRAPH
+0xEB92	0x970B	#CJK UNIFIED IDEOGRAPH
+0xEB93	0x970C	#CJK UNIFIED IDEOGRAPH
+0xEB94	0x9710	#CJK UNIFIED IDEOGRAPH
+0xEB95	0x9711	#CJK UNIFIED IDEOGRAPH
+0xEB96	0x9712	#CJK UNIFIED IDEOGRAPH
+0xEB97	0x9714	#CJK UNIFIED IDEOGRAPH
+0xEB98	0x9715	#CJK UNIFIED IDEOGRAPH
+0xEB99	0x9717	#CJK UNIFIED IDEOGRAPH
+0xEB9A	0x9718	#CJK UNIFIED IDEOGRAPH
+0xEB9B	0x9719	#CJK UNIFIED IDEOGRAPH
+0xEB9C	0x971A	#CJK UNIFIED IDEOGRAPH
+0xEB9D	0x971B	#CJK UNIFIED IDEOGRAPH
+0xEB9E	0x971D	#CJK UNIFIED IDEOGRAPH
+0xEB9F	0x971F	#CJK UNIFIED IDEOGRAPH
+0xEBA0	0x9720	#CJK UNIFIED IDEOGRAPH
+0xEBA1	0x643F	#CJK UNIFIED IDEOGRAPH
+0xEBA2	0x64D8	#CJK UNIFIED IDEOGRAPH
+0xEBA3	0x8004	#CJK UNIFIED IDEOGRAPH
+0xEBA4	0x6BEA	#CJK UNIFIED IDEOGRAPH
+0xEBA5	0x6BF3	#CJK UNIFIED IDEOGRAPH
+0xEBA6	0x6BFD	#CJK UNIFIED IDEOGRAPH
+0xEBA7	0x6BF5	#CJK UNIFIED IDEOGRAPH
+0xEBA8	0x6BF9	#CJK UNIFIED IDEOGRAPH
+0xEBA9	0x6C05	#CJK UNIFIED IDEOGRAPH
+0xEBAA	0x6C07	#CJK UNIFIED IDEOGRAPH
+0xEBAB	0x6C06	#CJK UNIFIED IDEOGRAPH
+0xEBAC	0x6C0D	#CJK UNIFIED IDEOGRAPH
+0xEBAD	0x6C15	#CJK UNIFIED IDEOGRAPH
+0xEBAE	0x6C18	#CJK UNIFIED IDEOGRAPH
+0xEBAF	0x6C19	#CJK UNIFIED IDEOGRAPH
+0xEBB0	0x6C1A	#CJK UNIFIED IDEOGRAPH
+0xEBB1	0x6C21	#CJK UNIFIED IDEOGRAPH
+0xEBB2	0x6C29	#CJK UNIFIED IDEOGRAPH
+0xEBB3	0x6C24	#CJK UNIFIED IDEOGRAPH
+0xEBB4	0x6C2A	#CJK UNIFIED IDEOGRAPH
+0xEBB5	0x6C32	#CJK UNIFIED IDEOGRAPH
+0xEBB6	0x6535	#CJK UNIFIED IDEOGRAPH
+0xEBB7	0x6555	#CJK UNIFIED IDEOGRAPH
+0xEBB8	0x656B	#CJK UNIFIED IDEOGRAPH
+0xEBB9	0x724D	#CJK UNIFIED IDEOGRAPH
+0xEBBA	0x7252	#CJK UNIFIED IDEOGRAPH
+0xEBBB	0x7256	#CJK UNIFIED IDEOGRAPH
+0xEBBC	0x7230	#CJK UNIFIED IDEOGRAPH
+0xEBBD	0x8662	#CJK UNIFIED IDEOGRAPH
+0xEBBE	0x5216	#CJK UNIFIED IDEOGRAPH
+0xEBBF	0x809F	#CJK UNIFIED IDEOGRAPH
+0xEBC0	0x809C	#CJK UNIFIED IDEOGRAPH
+0xEBC1	0x8093	#CJK UNIFIED IDEOGRAPH
+0xEBC2	0x80BC	#CJK UNIFIED IDEOGRAPH
+0xEBC3	0x670A	#CJK UNIFIED IDEOGRAPH
+0xEBC4	0x80BD	#CJK UNIFIED IDEOGRAPH
+0xEBC5	0x80B1	#CJK UNIFIED IDEOGRAPH
+0xEBC6	0x80AB	#CJK UNIFIED IDEOGRAPH
+0xEBC7	0x80AD	#CJK UNIFIED IDEOGRAPH
+0xEBC8	0x80B4	#CJK UNIFIED IDEOGRAPH
+0xEBC9	0x80B7	#CJK UNIFIED IDEOGRAPH
+0xEBCA	0x80E7	#CJK UNIFIED IDEOGRAPH
+0xEBCB	0x80E8	#CJK UNIFIED IDEOGRAPH
+0xEBCC	0x80E9	#CJK UNIFIED IDEOGRAPH
+0xEBCD	0x80EA	#CJK UNIFIED IDEOGRAPH
+0xEBCE	0x80DB	#CJK UNIFIED IDEOGRAPH
+0xEBCF	0x80C2	#CJK UNIFIED IDEOGRAPH
+0xEBD0	0x80C4	#CJK UNIFIED IDEOGRAPH
+0xEBD1	0x80D9	#CJK UNIFIED IDEOGRAPH
+0xEBD2	0x80CD	#CJK UNIFIED IDEOGRAPH
+0xEBD3	0x80D7	#CJK UNIFIED IDEOGRAPH
+0xEBD4	0x6710	#CJK UNIFIED IDEOGRAPH
+0xEBD5	0x80DD	#CJK UNIFIED IDEOGRAPH
+0xEBD6	0x80EB	#CJK UNIFIED IDEOGRAPH
+0xEBD7	0x80F1	#CJK UNIFIED IDEOGRAPH
+0xEBD8	0x80F4	#CJK UNIFIED IDEOGRAPH
+0xEBD9	0x80ED	#CJK UNIFIED IDEOGRAPH
+0xEBDA	0x810D	#CJK UNIFIED IDEOGRAPH
+0xEBDB	0x810E	#CJK UNIFIED IDEOGRAPH
+0xEBDC	0x80F2	#CJK UNIFIED IDEOGRAPH
+0xEBDD	0x80FC	#CJK UNIFIED IDEOGRAPH
+0xEBDE	0x6715	#CJK UNIFIED IDEOGRAPH
+0xEBDF	0x8112	#CJK UNIFIED IDEOGRAPH
+0xEBE0	0x8C5A	#CJK UNIFIED IDEOGRAPH
+0xEBE1	0x8136	#CJK UNIFIED IDEOGRAPH
+0xEBE2	0x811E	#CJK UNIFIED IDEOGRAPH
+0xEBE3	0x812C	#CJK UNIFIED IDEOGRAPH
+0xEBE4	0x8118	#CJK UNIFIED IDEOGRAPH
+0xEBE5	0x8132	#CJK UNIFIED IDEOGRAPH
+0xEBE6	0x8148	#CJK UNIFIED IDEOGRAPH
+0xEBE7	0x814C	#CJK UNIFIED IDEOGRAPH
+0xEBE8	0x8153	#CJK UNIFIED IDEOGRAPH
+0xEBE9	0x8174	#CJK UNIFIED IDEOGRAPH
+0xEBEA	0x8159	#CJK UNIFIED IDEOGRAPH
+0xEBEB	0x815A	#CJK UNIFIED IDEOGRAPH
+0xEBEC	0x8171	#CJK UNIFIED IDEOGRAPH
+0xEBED	0x8160	#CJK UNIFIED IDEOGRAPH
+0xEBEE	0x8169	#CJK UNIFIED IDEOGRAPH
+0xEBEF	0x817C	#CJK UNIFIED IDEOGRAPH
+0xEBF0	0x817D	#CJK UNIFIED IDEOGRAPH
+0xEBF1	0x816D	#CJK UNIFIED IDEOGRAPH
+0xEBF2	0x8167	#CJK UNIFIED IDEOGRAPH
+0xEBF3	0x584D	#CJK UNIFIED IDEOGRAPH
+0xEBF4	0x5AB5	#CJK UNIFIED IDEOGRAPH
+0xEBF5	0x8188	#CJK UNIFIED IDEOGRAPH
+0xEBF6	0x8182	#CJK UNIFIED IDEOGRAPH
+0xEBF7	0x8191	#CJK UNIFIED IDEOGRAPH
+0xEBF8	0x6ED5	#CJK UNIFIED IDEOGRAPH
+0xEBF9	0x81A3	#CJK UNIFIED IDEOGRAPH
+0xEBFA	0x81AA	#CJK UNIFIED IDEOGRAPH
+0xEBFB	0x81CC	#CJK UNIFIED IDEOGRAPH
+0xEBFC	0x6726	#CJK UNIFIED IDEOGRAPH
+0xEBFD	0x81CA	#CJK UNIFIED IDEOGRAPH
+0xEBFE	0x81BB	#CJK UNIFIED IDEOGRAPH
+0xEC40	0x9721	#CJK UNIFIED IDEOGRAPH
+0xEC41	0x9722	#CJK UNIFIED IDEOGRAPH
+0xEC42	0x9723	#CJK UNIFIED IDEOGRAPH
+0xEC43	0x9724	#CJK UNIFIED IDEOGRAPH
+0xEC44	0x9725	#CJK UNIFIED IDEOGRAPH
+0xEC45	0x9726	#CJK UNIFIED IDEOGRAPH
+0xEC46	0x9727	#CJK UNIFIED IDEOGRAPH
+0xEC47	0x9728	#CJK UNIFIED IDEOGRAPH
+0xEC48	0x9729	#CJK UNIFIED IDEOGRAPH
+0xEC49	0x972B	#CJK UNIFIED IDEOGRAPH
+0xEC4A	0x972C	#CJK UNIFIED IDEOGRAPH
+0xEC4B	0x972E	#CJK UNIFIED IDEOGRAPH
+0xEC4C	0x972F	#CJK UNIFIED IDEOGRAPH
+0xEC4D	0x9731	#CJK UNIFIED IDEOGRAPH
+0xEC4E	0x9733	#CJK UNIFIED IDEOGRAPH
+0xEC4F	0x9734	#CJK UNIFIED IDEOGRAPH
+0xEC50	0x9735	#CJK UNIFIED IDEOGRAPH
+0xEC51	0x9736	#CJK UNIFIED IDEOGRAPH
+0xEC52	0x9737	#CJK UNIFIED IDEOGRAPH
+0xEC53	0x973A	#CJK UNIFIED IDEOGRAPH
+0xEC54	0x973B	#CJK UNIFIED IDEOGRAPH
+0xEC55	0x973C	#CJK UNIFIED IDEOGRAPH
+0xEC56	0x973D	#CJK UNIFIED IDEOGRAPH
+0xEC57	0x973F	#CJK UNIFIED IDEOGRAPH
+0xEC58	0x9740	#CJK UNIFIED IDEOGRAPH
+0xEC59	0x9741	#CJK UNIFIED IDEOGRAPH
+0xEC5A	0x9742	#CJK UNIFIED IDEOGRAPH
+0xEC5B	0x9743	#CJK UNIFIED IDEOGRAPH
+0xEC5C	0x9744	#CJK UNIFIED IDEOGRAPH
+0xEC5D	0x9745	#CJK UNIFIED IDEOGRAPH
+0xEC5E	0x9746	#CJK UNIFIED IDEOGRAPH
+0xEC5F	0x9747	#CJK UNIFIED IDEOGRAPH
+0xEC60	0x9748	#CJK UNIFIED IDEOGRAPH
+0xEC61	0x9749	#CJK UNIFIED IDEOGRAPH
+0xEC62	0x974A	#CJK UNIFIED IDEOGRAPH
+0xEC63	0x974B	#CJK UNIFIED IDEOGRAPH
+0xEC64	0x974C	#CJK UNIFIED IDEOGRAPH
+0xEC65	0x974D	#CJK UNIFIED IDEOGRAPH
+0xEC66	0x974E	#CJK UNIFIED IDEOGRAPH
+0xEC67	0x974F	#CJK UNIFIED IDEOGRAPH
+0xEC68	0x9750	#CJK UNIFIED IDEOGRAPH
+0xEC69	0x9751	#CJK UNIFIED IDEOGRAPH
+0xEC6A	0x9754	#CJK UNIFIED IDEOGRAPH
+0xEC6B	0x9755	#CJK UNIFIED IDEOGRAPH
+0xEC6C	0x9757	#CJK UNIFIED IDEOGRAPH
+0xEC6D	0x9758	#CJK UNIFIED IDEOGRAPH
+0xEC6E	0x975A	#CJK UNIFIED IDEOGRAPH
+0xEC6F	0x975C	#CJK UNIFIED IDEOGRAPH
+0xEC70	0x975D	#CJK UNIFIED IDEOGRAPH
+0xEC71	0x975F	#CJK UNIFIED IDEOGRAPH
+0xEC72	0x9763	#CJK UNIFIED IDEOGRAPH
+0xEC73	0x9764	#CJK UNIFIED IDEOGRAPH
+0xEC74	0x9766	#CJK UNIFIED IDEOGRAPH
+0xEC75	0x9767	#CJK UNIFIED IDEOGRAPH
+0xEC76	0x9768	#CJK UNIFIED IDEOGRAPH
+0xEC77	0x976A	#CJK UNIFIED IDEOGRAPH
+0xEC78	0x976B	#CJK UNIFIED IDEOGRAPH
+0xEC79	0x976C	#CJK UNIFIED IDEOGRAPH
+0xEC7A	0x976D	#CJK UNIFIED IDEOGRAPH
+0xEC7B	0x976E	#CJK UNIFIED IDEOGRAPH
+0xEC7C	0x976F	#CJK UNIFIED IDEOGRAPH
+0xEC7D	0x9770	#CJK UNIFIED IDEOGRAPH
+0xEC7E	0x9771	#CJK UNIFIED IDEOGRAPH
+0xEC80	0x9772	#CJK UNIFIED IDEOGRAPH
+0xEC81	0x9775	#CJK UNIFIED IDEOGRAPH
+0xEC82	0x9777	#CJK UNIFIED IDEOGRAPH
+0xEC83	0x9778	#CJK UNIFIED IDEOGRAPH
+0xEC84	0x9779	#CJK UNIFIED IDEOGRAPH
+0xEC85	0x977A	#CJK UNIFIED IDEOGRAPH
+0xEC86	0x977B	#CJK UNIFIED IDEOGRAPH
+0xEC87	0x977D	#CJK UNIFIED IDEOGRAPH
+0xEC88	0x977E	#CJK UNIFIED IDEOGRAPH
+0xEC89	0x977F	#CJK UNIFIED IDEOGRAPH
+0xEC8A	0x9780	#CJK UNIFIED IDEOGRAPH
+0xEC8B	0x9781	#CJK UNIFIED IDEOGRAPH
+0xEC8C	0x9782	#CJK UNIFIED IDEOGRAPH
+0xEC8D	0x9783	#CJK UNIFIED IDEOGRAPH
+0xEC8E	0x9784	#CJK UNIFIED IDEOGRAPH
+0xEC8F	0x9786	#CJK UNIFIED IDEOGRAPH
+0xEC90	0x9787	#CJK UNIFIED IDEOGRAPH
+0xEC91	0x9788	#CJK UNIFIED IDEOGRAPH
+0xEC92	0x9789	#CJK UNIFIED IDEOGRAPH
+0xEC93	0x978A	#CJK UNIFIED IDEOGRAPH
+0xEC94	0x978C	#CJK UNIFIED IDEOGRAPH
+0xEC95	0x978E	#CJK UNIFIED IDEOGRAPH
+0xEC96	0x978F	#CJK UNIFIED IDEOGRAPH
+0xEC97	0x9790	#CJK UNIFIED IDEOGRAPH
+0xEC98	0x9793	#CJK UNIFIED IDEOGRAPH
+0xEC99	0x9795	#CJK UNIFIED IDEOGRAPH
+0xEC9A	0x9796	#CJK UNIFIED IDEOGRAPH
+0xEC9B	0x9797	#CJK UNIFIED IDEOGRAPH
+0xEC9C	0x9799	#CJK UNIFIED IDEOGRAPH
+0xEC9D	0x979A	#CJK UNIFIED IDEOGRAPH
+0xEC9E	0x979B	#CJK UNIFIED IDEOGRAPH
+0xEC9F	0x979C	#CJK UNIFIED IDEOGRAPH
+0xECA0	0x979D	#CJK UNIFIED IDEOGRAPH
+0xECA1	0x81C1	#CJK UNIFIED IDEOGRAPH
+0xECA2	0x81A6	#CJK UNIFIED IDEOGRAPH
+0xECA3	0x6B24	#CJK UNIFIED IDEOGRAPH
+0xECA4	0x6B37	#CJK UNIFIED IDEOGRAPH
+0xECA5	0x6B39	#CJK UNIFIED IDEOGRAPH
+0xECA6	0x6B43	#CJK UNIFIED IDEOGRAPH
+0xECA7	0x6B46	#CJK UNIFIED IDEOGRAPH
+0xECA8	0x6B59	#CJK UNIFIED IDEOGRAPH
+0xECA9	0x98D1	#CJK UNIFIED IDEOGRAPH
+0xECAA	0x98D2	#CJK UNIFIED IDEOGRAPH
+0xECAB	0x98D3	#CJK UNIFIED IDEOGRAPH
+0xECAC	0x98D5	#CJK UNIFIED IDEOGRAPH
+0xECAD	0x98D9	#CJK UNIFIED IDEOGRAPH
+0xECAE	0x98DA	#CJK UNIFIED IDEOGRAPH
+0xECAF	0x6BB3	#CJK UNIFIED IDEOGRAPH
+0xECB0	0x5F40	#CJK UNIFIED IDEOGRAPH
+0xECB1	0x6BC2	#CJK UNIFIED IDEOGRAPH
+0xECB2	0x89F3	#CJK UNIFIED IDEOGRAPH
+0xECB3	0x6590	#CJK UNIFIED IDEOGRAPH
+0xECB4	0x9F51	#CJK UNIFIED IDEOGRAPH
+0xECB5	0x6593	#CJK UNIFIED IDEOGRAPH
+0xECB6	0x65BC	#CJK UNIFIED IDEOGRAPH
+0xECB7	0x65C6	#CJK UNIFIED IDEOGRAPH
+0xECB8	0x65C4	#CJK UNIFIED IDEOGRAPH
+0xECB9	0x65C3	#CJK UNIFIED IDEOGRAPH
+0xECBA	0x65CC	#CJK UNIFIED IDEOGRAPH
+0xECBB	0x65CE	#CJK UNIFIED IDEOGRAPH
+0xECBC	0x65D2	#CJK UNIFIED IDEOGRAPH
+0xECBD	0x65D6	#CJK UNIFIED IDEOGRAPH
+0xECBE	0x7080	#CJK UNIFIED IDEOGRAPH
+0xECBF	0x709C	#CJK UNIFIED IDEOGRAPH
+0xECC0	0x7096	#CJK UNIFIED IDEOGRAPH
+0xECC1	0x709D	#CJK UNIFIED IDEOGRAPH
+0xECC2	0x70BB	#CJK UNIFIED IDEOGRAPH
+0xECC3	0x70C0	#CJK UNIFIED IDEOGRAPH
+0xECC4	0x70B7	#CJK UNIFIED IDEOGRAPH
+0xECC5	0x70AB	#CJK UNIFIED IDEOGRAPH
+0xECC6	0x70B1	#CJK UNIFIED IDEOGRAPH
+0xECC7	0x70E8	#CJK UNIFIED IDEOGRAPH
+0xECC8	0x70CA	#CJK UNIFIED IDEOGRAPH
+0xECC9	0x7110	#CJK UNIFIED IDEOGRAPH
+0xECCA	0x7113	#CJK UNIFIED IDEOGRAPH
+0xECCB	0x7116	#CJK UNIFIED IDEOGRAPH
+0xECCC	0x712F	#CJK UNIFIED IDEOGRAPH
+0xECCD	0x7131	#CJK UNIFIED IDEOGRAPH
+0xECCE	0x7173	#CJK UNIFIED IDEOGRAPH
+0xECCF	0x715C	#CJK UNIFIED IDEOGRAPH
+0xECD0	0x7168	#CJK UNIFIED IDEOGRAPH
+0xECD1	0x7145	#CJK UNIFIED IDEOGRAPH
+0xECD2	0x7172	#CJK UNIFIED IDEOGRAPH
+0xECD3	0x714A	#CJK UNIFIED IDEOGRAPH
+0xECD4	0x7178	#CJK UNIFIED IDEOGRAPH
+0xECD5	0x717A	#CJK UNIFIED IDEOGRAPH
+0xECD6	0x7198	#CJK UNIFIED IDEOGRAPH
+0xECD7	0x71B3	#CJK UNIFIED IDEOGRAPH
+0xECD8	0x71B5	#CJK UNIFIED IDEOGRAPH
+0xECD9	0x71A8	#CJK UNIFIED IDEOGRAPH
+0xECDA	0x71A0	#CJK UNIFIED IDEOGRAPH
+0xECDB	0x71E0	#CJK UNIFIED IDEOGRAPH
+0xECDC	0x71D4	#CJK UNIFIED IDEOGRAPH
+0xECDD	0x71E7	#CJK UNIFIED IDEOGRAPH
+0xECDE	0x71F9	#CJK UNIFIED IDEOGRAPH
+0xECDF	0x721D	#CJK UNIFIED IDEOGRAPH
+0xECE0	0x7228	#CJK UNIFIED IDEOGRAPH
+0xECE1	0x706C	#CJK UNIFIED IDEOGRAPH
+0xECE2	0x7118	#CJK UNIFIED IDEOGRAPH
+0xECE3	0x7166	#CJK UNIFIED IDEOGRAPH
+0xECE4	0x71B9	#CJK UNIFIED IDEOGRAPH
+0xECE5	0x623E	#CJK UNIFIED IDEOGRAPH
+0xECE6	0x623D	#CJK UNIFIED IDEOGRAPH
+0xECE7	0x6243	#CJK UNIFIED IDEOGRAPH
+0xECE8	0x6248	#CJK UNIFIED IDEOGRAPH
+0xECE9	0x6249	#CJK UNIFIED IDEOGRAPH
+0xECEA	0x793B	#CJK UNIFIED IDEOGRAPH
+0xECEB	0x7940	#CJK UNIFIED IDEOGRAPH
+0xECEC	0x7946	#CJK UNIFIED IDEOGRAPH
+0xECED	0x7949	#CJK UNIFIED IDEOGRAPH
+0xECEE	0x795B	#CJK UNIFIED IDEOGRAPH
+0xECEF	0x795C	#CJK UNIFIED IDEOGRAPH
+0xECF0	0x7953	#CJK UNIFIED IDEOGRAPH
+0xECF1	0x795A	#CJK UNIFIED IDEOGRAPH
+0xECF2	0x7962	#CJK UNIFIED IDEOGRAPH
+0xECF3	0x7957	#CJK UNIFIED IDEOGRAPH
+0xECF4	0x7960	#CJK UNIFIED IDEOGRAPH
+0xECF5	0x796F	#CJK UNIFIED IDEOGRAPH
+0xECF6	0x7967	#CJK UNIFIED IDEOGRAPH
+0xECF7	0x797A	#CJK UNIFIED IDEOGRAPH
+0xECF8	0x7985	#CJK UNIFIED IDEOGRAPH
+0xECF9	0x798A	#CJK UNIFIED IDEOGRAPH
+0xECFA	0x799A	#CJK UNIFIED IDEOGRAPH
+0xECFB	0x79A7	#CJK UNIFIED IDEOGRAPH
+0xECFC	0x79B3	#CJK UNIFIED IDEOGRAPH
+0xECFD	0x5FD1	#CJK UNIFIED IDEOGRAPH
+0xECFE	0x5FD0	#CJK UNIFIED IDEOGRAPH
+0xED40	0x979E	#CJK UNIFIED IDEOGRAPH
+0xED41	0x979F	#CJK UNIFIED IDEOGRAPH
+0xED42	0x97A1	#CJK UNIFIED IDEOGRAPH
+0xED43	0x97A2	#CJK UNIFIED IDEOGRAPH
+0xED44	0x97A4	#CJK UNIFIED IDEOGRAPH
+0xED45	0x97A5	#CJK UNIFIED IDEOGRAPH
+0xED46	0x97A6	#CJK UNIFIED IDEOGRAPH
+0xED47	0x97A7	#CJK UNIFIED IDEOGRAPH
+0xED48	0x97A8	#CJK UNIFIED IDEOGRAPH
+0xED49	0x97A9	#CJK UNIFIED IDEOGRAPH
+0xED4A	0x97AA	#CJK UNIFIED IDEOGRAPH
+0xED4B	0x97AC	#CJK UNIFIED IDEOGRAPH
+0xED4C	0x97AE	#CJK UNIFIED IDEOGRAPH
+0xED4D	0x97B0	#CJK UNIFIED IDEOGRAPH
+0xED4E	0x97B1	#CJK UNIFIED IDEOGRAPH
+0xED4F	0x97B3	#CJK UNIFIED IDEOGRAPH
+0xED50	0x97B5	#CJK UNIFIED IDEOGRAPH
+0xED51	0x97B6	#CJK UNIFIED IDEOGRAPH
+0xED52	0x97B7	#CJK UNIFIED IDEOGRAPH
+0xED53	0x97B8	#CJK UNIFIED IDEOGRAPH
+0xED54	0x97B9	#CJK UNIFIED IDEOGRAPH
+0xED55	0x97BA	#CJK UNIFIED IDEOGRAPH
+0xED56	0x97BB	#CJK UNIFIED IDEOGRAPH
+0xED57	0x97BC	#CJK UNIFIED IDEOGRAPH
+0xED58	0x97BD	#CJK UNIFIED IDEOGRAPH
+0xED59	0x97BE	#CJK UNIFIED IDEOGRAPH
+0xED5A	0x97BF	#CJK UNIFIED IDEOGRAPH
+0xED5B	0x97C0	#CJK UNIFIED IDEOGRAPH
+0xED5C	0x97C1	#CJK UNIFIED IDEOGRAPH
+0xED5D	0x97C2	#CJK UNIFIED IDEOGRAPH
+0xED5E	0x97C3	#CJK UNIFIED IDEOGRAPH
+0xED5F	0x97C4	#CJK UNIFIED IDEOGRAPH
+0xED60	0x97C5	#CJK UNIFIED IDEOGRAPH
+0xED61	0x97C6	#CJK UNIFIED IDEOGRAPH
+0xED62	0x97C7	#CJK UNIFIED IDEOGRAPH
+0xED63	0x97C8	#CJK UNIFIED IDEOGRAPH
+0xED64	0x97C9	#CJK UNIFIED IDEOGRAPH
+0xED65	0x97CA	#CJK UNIFIED IDEOGRAPH
+0xED66	0x97CB	#CJK UNIFIED IDEOGRAPH
+0xED67	0x97CC	#CJK UNIFIED IDEOGRAPH
+0xED68	0x97CD	#CJK UNIFIED IDEOGRAPH
+0xED69	0x97CE	#CJK UNIFIED IDEOGRAPH
+0xED6A	0x97CF	#CJK UNIFIED IDEOGRAPH
+0xED6B	0x97D0	#CJK UNIFIED IDEOGRAPH
+0xED6C	0x97D1	#CJK UNIFIED IDEOGRAPH
+0xED6D	0x97D2	#CJK UNIFIED IDEOGRAPH
+0xED6E	0x97D3	#CJK UNIFIED IDEOGRAPH
+0xED6F	0x97D4	#CJK UNIFIED IDEOGRAPH
+0xED70	0x97D5	#CJK UNIFIED IDEOGRAPH
+0xED71	0x97D6	#CJK UNIFIED IDEOGRAPH
+0xED72	0x97D7	#CJK UNIFIED IDEOGRAPH
+0xED73	0x97D8	#CJK UNIFIED IDEOGRAPH
+0xED74	0x97D9	#CJK UNIFIED IDEOGRAPH
+0xED75	0x97DA	#CJK UNIFIED IDEOGRAPH
+0xED76	0x97DB	#CJK UNIFIED IDEOGRAPH
+0xED77	0x97DC	#CJK UNIFIED IDEOGRAPH
+0xED78	0x97DD	#CJK UNIFIED IDEOGRAPH
+0xED79	0x97DE	#CJK UNIFIED IDEOGRAPH
+0xED7A	0x97DF	#CJK UNIFIED IDEOGRAPH
+0xED7B	0x97E0	#CJK UNIFIED IDEOGRAPH
+0xED7C	0x97E1	#CJK UNIFIED IDEOGRAPH
+0xED7D	0x97E2	#CJK UNIFIED IDEOGRAPH
+0xED7E	0x97E3	#CJK UNIFIED IDEOGRAPH
+0xED80	0x97E4	#CJK UNIFIED IDEOGRAPH
+0xED81	0x97E5	#CJK UNIFIED IDEOGRAPH
+0xED82	0x97E8	#CJK UNIFIED IDEOGRAPH
+0xED83	0x97EE	#CJK UNIFIED IDEOGRAPH
+0xED84	0x97EF	#CJK UNIFIED IDEOGRAPH
+0xED85	0x97F0	#CJK UNIFIED IDEOGRAPH
+0xED86	0x97F1	#CJK UNIFIED IDEOGRAPH
+0xED87	0x97F2	#CJK UNIFIED IDEOGRAPH
+0xED88	0x97F4	#CJK UNIFIED IDEOGRAPH
+0xED89	0x97F7	#CJK UNIFIED IDEOGRAPH
+0xED8A	0x97F8	#CJK UNIFIED IDEOGRAPH
+0xED8B	0x97F9	#CJK UNIFIED IDEOGRAPH
+0xED8C	0x97FA	#CJK UNIFIED IDEOGRAPH
+0xED8D	0x97FB	#CJK UNIFIED IDEOGRAPH
+0xED8E	0x97FC	#CJK UNIFIED IDEOGRAPH
+0xED8F	0x97FD	#CJK UNIFIED IDEOGRAPH
+0xED90	0x97FE	#CJK UNIFIED IDEOGRAPH
+0xED91	0x97FF	#CJK UNIFIED IDEOGRAPH
+0xED92	0x9800	#CJK UNIFIED IDEOGRAPH
+0xED93	0x9801	#CJK UNIFIED IDEOGRAPH
+0xED94	0x9802	#CJK UNIFIED IDEOGRAPH
+0xED95	0x9803	#CJK UNIFIED IDEOGRAPH
+0xED96	0x9804	#CJK UNIFIED IDEOGRAPH
+0xED97	0x9805	#CJK UNIFIED IDEOGRAPH
+0xED98	0x9806	#CJK UNIFIED IDEOGRAPH
+0xED99	0x9807	#CJK UNIFIED IDEOGRAPH
+0xED9A	0x9808	#CJK UNIFIED IDEOGRAPH
+0xED9B	0x9809	#CJK UNIFIED IDEOGRAPH
+0xED9C	0x980A	#CJK UNIFIED IDEOGRAPH
+0xED9D	0x980B	#CJK UNIFIED IDEOGRAPH
+0xED9E	0x980C	#CJK UNIFIED IDEOGRAPH
+0xED9F	0x980D	#CJK UNIFIED IDEOGRAPH
+0xEDA0	0x980E	#CJK UNIFIED IDEOGRAPH
+0xEDA1	0x603C	#CJK UNIFIED IDEOGRAPH
+0xEDA2	0x605D	#CJK UNIFIED IDEOGRAPH
+0xEDA3	0x605A	#CJK UNIFIED IDEOGRAPH
+0xEDA4	0x6067	#CJK UNIFIED IDEOGRAPH
+0xEDA5	0x6041	#CJK UNIFIED IDEOGRAPH
+0xEDA6	0x6059	#CJK UNIFIED IDEOGRAPH
+0xEDA7	0x6063	#CJK UNIFIED IDEOGRAPH
+0xEDA8	0x60AB	#CJK UNIFIED IDEOGRAPH
+0xEDA9	0x6106	#CJK UNIFIED IDEOGRAPH
+0xEDAA	0x610D	#CJK UNIFIED IDEOGRAPH
+0xEDAB	0x615D	#CJK UNIFIED IDEOGRAPH
+0xEDAC	0x61A9	#CJK UNIFIED IDEOGRAPH
+0xEDAD	0x619D	#CJK UNIFIED IDEOGRAPH
+0xEDAE	0x61CB	#CJK UNIFIED IDEOGRAPH
+0xEDAF	0x61D1	#CJK UNIFIED IDEOGRAPH
+0xEDB0	0x6206	#CJK UNIFIED IDEOGRAPH
+0xEDB1	0x8080	#CJK UNIFIED IDEOGRAPH
+0xEDB2	0x807F	#CJK UNIFIED IDEOGRAPH
+0xEDB3	0x6C93	#CJK UNIFIED IDEOGRAPH
+0xEDB4	0x6CF6	#CJK UNIFIED IDEOGRAPH
+0xEDB5	0x6DFC	#CJK UNIFIED IDEOGRAPH
+0xEDB6	0x77F6	#CJK UNIFIED IDEOGRAPH
+0xEDB7	0x77F8	#CJK UNIFIED IDEOGRAPH
+0xEDB8	0x7800	#CJK UNIFIED IDEOGRAPH
+0xEDB9	0x7809	#CJK UNIFIED IDEOGRAPH
+0xEDBA	0x7817	#CJK UNIFIED IDEOGRAPH
+0xEDBB	0x7818	#CJK UNIFIED IDEOGRAPH
+0xEDBC	0x7811	#CJK UNIFIED IDEOGRAPH
+0xEDBD	0x65AB	#CJK UNIFIED IDEOGRAPH
+0xEDBE	0x782D	#CJK UNIFIED IDEOGRAPH
+0xEDBF	0x781C	#CJK UNIFIED IDEOGRAPH
+0xEDC0	0x781D	#CJK UNIFIED IDEOGRAPH
+0xEDC1	0x7839	#CJK UNIFIED IDEOGRAPH
+0xEDC2	0x783A	#CJK UNIFIED IDEOGRAPH
+0xEDC3	0x783B	#CJK UNIFIED IDEOGRAPH
+0xEDC4	0x781F	#CJK UNIFIED IDEOGRAPH
+0xEDC5	0x783C	#CJK UNIFIED IDEOGRAPH
+0xEDC6	0x7825	#CJK UNIFIED IDEOGRAPH
+0xEDC7	0x782C	#CJK UNIFIED IDEOGRAPH
+0xEDC8	0x7823	#CJK UNIFIED IDEOGRAPH
+0xEDC9	0x7829	#CJK UNIFIED IDEOGRAPH
+0xEDCA	0x784E	#CJK UNIFIED IDEOGRAPH
+0xEDCB	0x786D	#CJK UNIFIED IDEOGRAPH
+0xEDCC	0x7856	#CJK UNIFIED IDEOGRAPH
+0xEDCD	0x7857	#CJK UNIFIED IDEOGRAPH
+0xEDCE	0x7826	#CJK UNIFIED IDEOGRAPH
+0xEDCF	0x7850	#CJK UNIFIED IDEOGRAPH
+0xEDD0	0x7847	#CJK UNIFIED IDEOGRAPH
+0xEDD1	0x784C	#CJK UNIFIED IDEOGRAPH
+0xEDD2	0x786A	#CJK UNIFIED IDEOGRAPH
+0xEDD3	0x789B	#CJK UNIFIED IDEOGRAPH
+0xEDD4	0x7893	#CJK UNIFIED IDEOGRAPH
+0xEDD5	0x789A	#CJK UNIFIED IDEOGRAPH
+0xEDD6	0x7887	#CJK UNIFIED IDEOGRAPH
+0xEDD7	0x789C	#CJK UNIFIED IDEOGRAPH
+0xEDD8	0x78A1	#CJK UNIFIED IDEOGRAPH
+0xEDD9	0x78A3	#CJK UNIFIED IDEOGRAPH
+0xEDDA	0x78B2	#CJK UNIFIED IDEOGRAPH
+0xEDDB	0x78B9	#CJK UNIFIED IDEOGRAPH
+0xEDDC	0x78A5	#CJK UNIFIED IDEOGRAPH
+0xEDDD	0x78D4	#CJK UNIFIED IDEOGRAPH
+0xEDDE	0x78D9	#CJK UNIFIED IDEOGRAPH
+0xEDDF	0x78C9	#CJK UNIFIED IDEOGRAPH
+0xEDE0	0x78EC	#CJK UNIFIED IDEOGRAPH
+0xEDE1	0x78F2	#CJK UNIFIED IDEOGRAPH
+0xEDE2	0x7905	#CJK UNIFIED IDEOGRAPH
+0xEDE3	0x78F4	#CJK UNIFIED IDEOGRAPH
+0xEDE4	0x7913	#CJK UNIFIED IDEOGRAPH
+0xEDE5	0x7924	#CJK UNIFIED IDEOGRAPH
+0xEDE6	0x791E	#CJK UNIFIED IDEOGRAPH
+0xEDE7	0x7934	#CJK UNIFIED IDEOGRAPH
+0xEDE8	0x9F9B	#CJK UNIFIED IDEOGRAPH
+0xEDE9	0x9EF9	#CJK UNIFIED IDEOGRAPH
+0xEDEA	0x9EFB	#CJK UNIFIED IDEOGRAPH
+0xEDEB	0x9EFC	#CJK UNIFIED IDEOGRAPH
+0xEDEC	0x76F1	#CJK UNIFIED IDEOGRAPH
+0xEDED	0x7704	#CJK UNIFIED IDEOGRAPH
+0xEDEE	0x770D	#CJK UNIFIED IDEOGRAPH
+0xEDEF	0x76F9	#CJK UNIFIED IDEOGRAPH
+0xEDF0	0x7707	#CJK UNIFIED IDEOGRAPH
+0xEDF1	0x7708	#CJK UNIFIED IDEOGRAPH
+0xEDF2	0x771A	#CJK UNIFIED IDEOGRAPH
+0xEDF3	0x7722	#CJK UNIFIED IDEOGRAPH
+0xEDF4	0x7719	#CJK UNIFIED IDEOGRAPH
+0xEDF5	0x772D	#CJK UNIFIED IDEOGRAPH
+0xEDF6	0x7726	#CJK UNIFIED IDEOGRAPH
+0xEDF7	0x7735	#CJK UNIFIED IDEOGRAPH
+0xEDF8	0x7738	#CJK UNIFIED IDEOGRAPH
+0xEDF9	0x7750	#CJK UNIFIED IDEOGRAPH
+0xEDFA	0x7751	#CJK UNIFIED IDEOGRAPH
+0xEDFB	0x7747	#CJK UNIFIED IDEOGRAPH
+0xEDFC	0x7743	#CJK UNIFIED IDEOGRAPH
+0xEDFD	0x775A	#CJK UNIFIED IDEOGRAPH
+0xEDFE	0x7768	#CJK UNIFIED IDEOGRAPH
+0xEE40	0x980F	#CJK UNIFIED IDEOGRAPH
+0xEE41	0x9810	#CJK UNIFIED IDEOGRAPH
+0xEE42	0x9811	#CJK UNIFIED IDEOGRAPH
+0xEE43	0x9812	#CJK UNIFIED IDEOGRAPH
+0xEE44	0x9813	#CJK UNIFIED IDEOGRAPH
+0xEE45	0x9814	#CJK UNIFIED IDEOGRAPH
+0xEE46	0x9815	#CJK UNIFIED IDEOGRAPH
+0xEE47	0x9816	#CJK UNIFIED IDEOGRAPH
+0xEE48	0x9817	#CJK UNIFIED IDEOGRAPH
+0xEE49	0x9818	#CJK UNIFIED IDEOGRAPH
+0xEE4A	0x9819	#CJK UNIFIED IDEOGRAPH
+0xEE4B	0x981A	#CJK UNIFIED IDEOGRAPH
+0xEE4C	0x981B	#CJK UNIFIED IDEOGRAPH
+0xEE4D	0x981C	#CJK UNIFIED IDEOGRAPH
+0xEE4E	0x981D	#CJK UNIFIED IDEOGRAPH
+0xEE4F	0x981E	#CJK UNIFIED IDEOGRAPH
+0xEE50	0x981F	#CJK UNIFIED IDEOGRAPH
+0xEE51	0x9820	#CJK UNIFIED IDEOGRAPH
+0xEE52	0x9821	#CJK UNIFIED IDEOGRAPH
+0xEE53	0x9822	#CJK UNIFIED IDEOGRAPH
+0xEE54	0x9823	#CJK UNIFIED IDEOGRAPH
+0xEE55	0x9824	#CJK UNIFIED IDEOGRAPH
+0xEE56	0x9825	#CJK UNIFIED IDEOGRAPH
+0xEE57	0x9826	#CJK UNIFIED IDEOGRAPH
+0xEE58	0x9827	#CJK UNIFIED IDEOGRAPH
+0xEE59	0x9828	#CJK UNIFIED IDEOGRAPH
+0xEE5A	0x9829	#CJK UNIFIED IDEOGRAPH
+0xEE5B	0x982A	#CJK UNIFIED IDEOGRAPH
+0xEE5C	0x982B	#CJK UNIFIED IDEOGRAPH
+0xEE5D	0x982C	#CJK UNIFIED IDEOGRAPH
+0xEE5E	0x982D	#CJK UNIFIED IDEOGRAPH
+0xEE5F	0x982E	#CJK UNIFIED IDEOGRAPH
+0xEE60	0x982F	#CJK UNIFIED IDEOGRAPH
+0xEE61	0x9830	#CJK UNIFIED IDEOGRAPH
+0xEE62	0x9831	#CJK UNIFIED IDEOGRAPH
+0xEE63	0x9832	#CJK UNIFIED IDEOGRAPH
+0xEE64	0x9833	#CJK UNIFIED IDEOGRAPH
+0xEE65	0x9834	#CJK UNIFIED IDEOGRAPH
+0xEE66	0x9835	#CJK UNIFIED IDEOGRAPH
+0xEE67	0x9836	#CJK UNIFIED IDEOGRAPH
+0xEE68	0x9837	#CJK UNIFIED IDEOGRAPH
+0xEE69	0x9838	#CJK UNIFIED IDEOGRAPH
+0xEE6A	0x9839	#CJK UNIFIED IDEOGRAPH
+0xEE6B	0x983A	#CJK UNIFIED IDEOGRAPH
+0xEE6C	0x983B	#CJK UNIFIED IDEOGRAPH
+0xEE6D	0x983C	#CJK UNIFIED IDEOGRAPH
+0xEE6E	0x983D	#CJK UNIFIED IDEOGRAPH
+0xEE6F	0x983E	#CJK UNIFIED IDEOGRAPH
+0xEE70	0x983F	#CJK UNIFIED IDEOGRAPH
+0xEE71	0x9840	#CJK UNIFIED IDEOGRAPH
+0xEE72	0x9841	#CJK UNIFIED IDEOGRAPH
+0xEE73	0x9842	#CJK UNIFIED IDEOGRAPH
+0xEE74	0x9843	#CJK UNIFIED IDEOGRAPH
+0xEE75	0x9844	#CJK UNIFIED IDEOGRAPH
+0xEE76	0x9845	#CJK UNIFIED IDEOGRAPH
+0xEE77	0x9846	#CJK UNIFIED IDEOGRAPH
+0xEE78	0x9847	#CJK UNIFIED IDEOGRAPH
+0xEE79	0x9848	#CJK UNIFIED IDEOGRAPH
+0xEE7A	0x9849	#CJK UNIFIED IDEOGRAPH
+0xEE7B	0x984A	#CJK UNIFIED IDEOGRAPH
+0xEE7C	0x984B	#CJK UNIFIED IDEOGRAPH
+0xEE7D	0x984C	#CJK UNIFIED IDEOGRAPH
+0xEE7E	0x984D	#CJK UNIFIED IDEOGRAPH
+0xEE80	0x984E	#CJK UNIFIED IDEOGRAPH
+0xEE81	0x984F	#CJK UNIFIED IDEOGRAPH
+0xEE82	0x9850	#CJK UNIFIED IDEOGRAPH
+0xEE83	0x9851	#CJK UNIFIED IDEOGRAPH
+0xEE84	0x9852	#CJK UNIFIED IDEOGRAPH
+0xEE85	0x9853	#CJK UNIFIED IDEOGRAPH
+0xEE86	0x9854	#CJK UNIFIED IDEOGRAPH
+0xEE87	0x9855	#CJK UNIFIED IDEOGRAPH
+0xEE88	0x9856	#CJK UNIFIED IDEOGRAPH
+0xEE89	0x9857	#CJK UNIFIED IDEOGRAPH
+0xEE8A	0x9858	#CJK UNIFIED IDEOGRAPH
+0xEE8B	0x9859	#CJK UNIFIED IDEOGRAPH
+0xEE8C	0x985A	#CJK UNIFIED IDEOGRAPH
+0xEE8D	0x985B	#CJK UNIFIED IDEOGRAPH
+0xEE8E	0x985C	#CJK UNIFIED IDEOGRAPH
+0xEE8F	0x985D	#CJK UNIFIED IDEOGRAPH
+0xEE90	0x985E	#CJK UNIFIED IDEOGRAPH
+0xEE91	0x985F	#CJK UNIFIED IDEOGRAPH
+0xEE92	0x9860	#CJK UNIFIED IDEOGRAPH
+0xEE93	0x9861	#CJK UNIFIED IDEOGRAPH
+0xEE94	0x9862	#CJK UNIFIED IDEOGRAPH
+0xEE95	0x9863	#CJK UNIFIED IDEOGRAPH
+0xEE96	0x9864	#CJK UNIFIED IDEOGRAPH
+0xEE97	0x9865	#CJK UNIFIED IDEOGRAPH
+0xEE98	0x9866	#CJK UNIFIED IDEOGRAPH
+0xEE99	0x9867	#CJK UNIFIED IDEOGRAPH
+0xEE9A	0x9868	#CJK UNIFIED IDEOGRAPH
+0xEE9B	0x9869	#CJK UNIFIED IDEOGRAPH
+0xEE9C	0x986A	#CJK UNIFIED IDEOGRAPH
+0xEE9D	0x986B	#CJK UNIFIED IDEOGRAPH
+0xEE9E	0x986C	#CJK UNIFIED IDEOGRAPH
+0xEE9F	0x986D	#CJK UNIFIED IDEOGRAPH
+0xEEA0	0x986E	#CJK UNIFIED IDEOGRAPH
+0xEEA1	0x7762	#CJK UNIFIED IDEOGRAPH
+0xEEA2	0x7765	#CJK UNIFIED IDEOGRAPH
+0xEEA3	0x777F	#CJK UNIFIED IDEOGRAPH
+0xEEA4	0x778D	#CJK UNIFIED IDEOGRAPH
+0xEEA5	0x777D	#CJK UNIFIED IDEOGRAPH
+0xEEA6	0x7780	#CJK UNIFIED IDEOGRAPH
+0xEEA7	0x778C	#CJK UNIFIED IDEOGRAPH
+0xEEA8	0x7791	#CJK UNIFIED IDEOGRAPH
+0xEEA9	0x779F	#CJK UNIFIED IDEOGRAPH
+0xEEAA	0x77A0	#CJK UNIFIED IDEOGRAPH
+0xEEAB	0x77B0	#CJK UNIFIED IDEOGRAPH
+0xEEAC	0x77B5	#CJK UNIFIED IDEOGRAPH
+0xEEAD	0x77BD	#CJK UNIFIED IDEOGRAPH
+0xEEAE	0x753A	#CJK UNIFIED IDEOGRAPH
+0xEEAF	0x7540	#CJK UNIFIED IDEOGRAPH
+0xEEB0	0x754E	#CJK UNIFIED IDEOGRAPH
+0xEEB1	0x754B	#CJK UNIFIED IDEOGRAPH
+0xEEB2	0x7548	#CJK UNIFIED IDEOGRAPH
+0xEEB3	0x755B	#CJK UNIFIED IDEOGRAPH
+0xEEB4	0x7572	#CJK UNIFIED IDEOGRAPH
+0xEEB5	0x7579	#CJK UNIFIED IDEOGRAPH
+0xEEB6	0x7583	#CJK UNIFIED IDEOGRAPH
+0xEEB7	0x7F58	#CJK UNIFIED IDEOGRAPH
+0xEEB8	0x7F61	#CJK UNIFIED IDEOGRAPH
+0xEEB9	0x7F5F	#CJK UNIFIED IDEOGRAPH
+0xEEBA	0x8A48	#CJK UNIFIED IDEOGRAPH
+0xEEBB	0x7F68	#CJK UNIFIED IDEOGRAPH
+0xEEBC	0x7F74	#CJK UNIFIED IDEOGRAPH
+0xEEBD	0x7F71	#CJK UNIFIED IDEOGRAPH
+0xEEBE	0x7F79	#CJK UNIFIED IDEOGRAPH
+0xEEBF	0x7F81	#CJK UNIFIED IDEOGRAPH
+0xEEC0	0x7F7E	#CJK UNIFIED IDEOGRAPH
+0xEEC1	0x76CD	#CJK UNIFIED IDEOGRAPH
+0xEEC2	0x76E5	#CJK UNIFIED IDEOGRAPH
+0xEEC3	0x8832	#CJK UNIFIED IDEOGRAPH
+0xEEC4	0x9485	#CJK UNIFIED IDEOGRAPH
+0xEEC5	0x9486	#CJK UNIFIED IDEOGRAPH
+0xEEC6	0x9487	#CJK UNIFIED IDEOGRAPH
+0xEEC7	0x948B	#CJK UNIFIED IDEOGRAPH
+0xEEC8	0x948A	#CJK UNIFIED IDEOGRAPH
+0xEEC9	0x948C	#CJK UNIFIED IDEOGRAPH
+0xEECA	0x948D	#CJK UNIFIED IDEOGRAPH
+0xEECB	0x948F	#CJK UNIFIED IDEOGRAPH
+0xEECC	0x9490	#CJK UNIFIED IDEOGRAPH
+0xEECD	0x9494	#CJK UNIFIED IDEOGRAPH
+0xEECE	0x9497	#CJK UNIFIED IDEOGRAPH
+0xEECF	0x9495	#CJK UNIFIED IDEOGRAPH
+0xEED0	0x949A	#CJK UNIFIED IDEOGRAPH
+0xEED1	0x949B	#CJK UNIFIED IDEOGRAPH
+0xEED2	0x949C	#CJK UNIFIED IDEOGRAPH
+0xEED3	0x94A3	#CJK UNIFIED IDEOGRAPH
+0xEED4	0x94A4	#CJK UNIFIED IDEOGRAPH
+0xEED5	0x94AB	#CJK UNIFIED IDEOGRAPH
+0xEED6	0x94AA	#CJK UNIFIED IDEOGRAPH
+0xEED7	0x94AD	#CJK UNIFIED IDEOGRAPH
+0xEED8	0x94AC	#CJK UNIFIED IDEOGRAPH
+0xEED9	0x94AF	#CJK UNIFIED IDEOGRAPH
+0xEEDA	0x94B0	#CJK UNIFIED IDEOGRAPH
+0xEEDB	0x94B2	#CJK UNIFIED IDEOGRAPH
+0xEEDC	0x94B4	#CJK UNIFIED IDEOGRAPH
+0xEEDD	0x94B6	#CJK UNIFIED IDEOGRAPH
+0xEEDE	0x94B7	#CJK UNIFIED IDEOGRAPH
+0xEEDF	0x94B8	#CJK UNIFIED IDEOGRAPH
+0xEEE0	0x94B9	#CJK UNIFIED IDEOGRAPH
+0xEEE1	0x94BA	#CJK UNIFIED IDEOGRAPH
+0xEEE2	0x94BC	#CJK UNIFIED IDEOGRAPH
+0xEEE3	0x94BD	#CJK UNIFIED IDEOGRAPH
+0xEEE4	0x94BF	#CJK UNIFIED IDEOGRAPH
+0xEEE5	0x94C4	#CJK UNIFIED IDEOGRAPH
+0xEEE6	0x94C8	#CJK UNIFIED IDEOGRAPH
+0xEEE7	0x94C9	#CJK UNIFIED IDEOGRAPH
+0xEEE8	0x94CA	#CJK UNIFIED IDEOGRAPH
+0xEEE9	0x94CB	#CJK UNIFIED IDEOGRAPH
+0xEEEA	0x94CC	#CJK UNIFIED IDEOGRAPH
+0xEEEB	0x94CD	#CJK UNIFIED IDEOGRAPH
+0xEEEC	0x94CE	#CJK UNIFIED IDEOGRAPH
+0xEEED	0x94D0	#CJK UNIFIED IDEOGRAPH
+0xEEEE	0x94D1	#CJK UNIFIED IDEOGRAPH
+0xEEEF	0x94D2	#CJK UNIFIED IDEOGRAPH
+0xEEF0	0x94D5	#CJK UNIFIED IDEOGRAPH
+0xEEF1	0x94D6	#CJK UNIFIED IDEOGRAPH
+0xEEF2	0x94D7	#CJK UNIFIED IDEOGRAPH
+0xEEF3	0x94D9	#CJK UNIFIED IDEOGRAPH
+0xEEF4	0x94D8	#CJK UNIFIED IDEOGRAPH
+0xEEF5	0x94DB	#CJK UNIFIED IDEOGRAPH
+0xEEF6	0x94DE	#CJK UNIFIED IDEOGRAPH
+0xEEF7	0x94DF	#CJK UNIFIED IDEOGRAPH
+0xEEF8	0x94E0	#CJK UNIFIED IDEOGRAPH
+0xEEF9	0x94E2	#CJK UNIFIED IDEOGRAPH
+0xEEFA	0x94E4	#CJK UNIFIED IDEOGRAPH
+0xEEFB	0x94E5	#CJK UNIFIED IDEOGRAPH
+0xEEFC	0x94E7	#CJK UNIFIED IDEOGRAPH
+0xEEFD	0x94E8	#CJK UNIFIED IDEOGRAPH
+0xEEFE	0x94EA	#CJK UNIFIED IDEOGRAPH
+0xEF40	0x986F	#CJK UNIFIED IDEOGRAPH
+0xEF41	0x9870	#CJK UNIFIED IDEOGRAPH
+0xEF42	0x9871	#CJK UNIFIED IDEOGRAPH
+0xEF43	0x9872	#CJK UNIFIED IDEOGRAPH
+0xEF44	0x9873	#CJK UNIFIED IDEOGRAPH
+0xEF45	0x9874	#CJK UNIFIED IDEOGRAPH
+0xEF46	0x988B	#CJK UNIFIED IDEOGRAPH
+0xEF47	0x988E	#CJK UNIFIED IDEOGRAPH
+0xEF48	0x9892	#CJK UNIFIED IDEOGRAPH
+0xEF49	0x9895	#CJK UNIFIED IDEOGRAPH
+0xEF4A	0x9899	#CJK UNIFIED IDEOGRAPH
+0xEF4B	0x98A3	#CJK UNIFIED IDEOGRAPH
+0xEF4C	0x98A8	#CJK UNIFIED IDEOGRAPH
+0xEF4D	0x98A9	#CJK UNIFIED IDEOGRAPH
+0xEF4E	0x98AA	#CJK UNIFIED IDEOGRAPH
+0xEF4F	0x98AB	#CJK UNIFIED IDEOGRAPH
+0xEF50	0x98AC	#CJK UNIFIED IDEOGRAPH
+0xEF51	0x98AD	#CJK UNIFIED IDEOGRAPH
+0xEF52	0x98AE	#CJK UNIFIED IDEOGRAPH
+0xEF53	0x98AF	#CJK UNIFIED IDEOGRAPH
+0xEF54	0x98B0	#CJK UNIFIED IDEOGRAPH
+0xEF55	0x98B1	#CJK UNIFIED IDEOGRAPH
+0xEF56	0x98B2	#CJK UNIFIED IDEOGRAPH
+0xEF57	0x98B3	#CJK UNIFIED IDEOGRAPH
+0xEF58	0x98B4	#CJK UNIFIED IDEOGRAPH
+0xEF59	0x98B5	#CJK UNIFIED IDEOGRAPH
+0xEF5A	0x98B6	#CJK UNIFIED IDEOGRAPH
+0xEF5B	0x98B7	#CJK UNIFIED IDEOGRAPH
+0xEF5C	0x98B8	#CJK UNIFIED IDEOGRAPH
+0xEF5D	0x98B9	#CJK UNIFIED IDEOGRAPH
+0xEF5E	0x98BA	#CJK UNIFIED IDEOGRAPH
+0xEF5F	0x98BB	#CJK UNIFIED IDEOGRAPH
+0xEF60	0x98BC	#CJK UNIFIED IDEOGRAPH
+0xEF61	0x98BD	#CJK UNIFIED IDEOGRAPH
+0xEF62	0x98BE	#CJK UNIFIED IDEOGRAPH
+0xEF63	0x98BF	#CJK UNIFIED IDEOGRAPH
+0xEF64	0x98C0	#CJK UNIFIED IDEOGRAPH
+0xEF65	0x98C1	#CJK UNIFIED IDEOGRAPH
+0xEF66	0x98C2	#CJK UNIFIED IDEOGRAPH
+0xEF67	0x98C3	#CJK UNIFIED IDEOGRAPH
+0xEF68	0x98C4	#CJK UNIFIED IDEOGRAPH
+0xEF69	0x98C5	#CJK UNIFIED IDEOGRAPH
+0xEF6A	0x98C6	#CJK UNIFIED IDEOGRAPH
+0xEF6B	0x98C7	#CJK UNIFIED IDEOGRAPH
+0xEF6C	0x98C8	#CJK UNIFIED IDEOGRAPH
+0xEF6D	0x98C9	#CJK UNIFIED IDEOGRAPH
+0xEF6E	0x98CA	#CJK UNIFIED IDEOGRAPH
+0xEF6F	0x98CB	#CJK UNIFIED IDEOGRAPH
+0xEF70	0x98CC	#CJK UNIFIED IDEOGRAPH
+0xEF71	0x98CD	#CJK UNIFIED IDEOGRAPH
+0xEF72	0x98CF	#CJK UNIFIED IDEOGRAPH
+0xEF73	0x98D0	#CJK UNIFIED IDEOGRAPH
+0xEF74	0x98D4	#CJK UNIFIED IDEOGRAPH
+0xEF75	0x98D6	#CJK UNIFIED IDEOGRAPH
+0xEF76	0x98D7	#CJK UNIFIED IDEOGRAPH
+0xEF77	0x98DB	#CJK UNIFIED IDEOGRAPH
+0xEF78	0x98DC	#CJK UNIFIED IDEOGRAPH
+0xEF79	0x98DD	#CJK UNIFIED IDEOGRAPH
+0xEF7A	0x98E0	#CJK UNIFIED IDEOGRAPH
+0xEF7B	0x98E1	#CJK UNIFIED IDEOGRAPH
+0xEF7C	0x98E2	#CJK UNIFIED IDEOGRAPH
+0xEF7D	0x98E3	#CJK UNIFIED IDEOGRAPH
+0xEF7E	0x98E4	#CJK UNIFIED IDEOGRAPH
+0xEF80	0x98E5	#CJK UNIFIED IDEOGRAPH
+0xEF81	0x98E6	#CJK UNIFIED IDEOGRAPH
+0xEF82	0x98E9	#CJK UNIFIED IDEOGRAPH
+0xEF83	0x98EA	#CJK UNIFIED IDEOGRAPH
+0xEF84	0x98EB	#CJK UNIFIED IDEOGRAPH
+0xEF85	0x98EC	#CJK UNIFIED IDEOGRAPH
+0xEF86	0x98ED	#CJK UNIFIED IDEOGRAPH
+0xEF87	0x98EE	#CJK UNIFIED IDEOGRAPH
+0xEF88	0x98EF	#CJK UNIFIED IDEOGRAPH
+0xEF89	0x98F0	#CJK UNIFIED IDEOGRAPH
+0xEF8A	0x98F1	#CJK UNIFIED IDEOGRAPH
+0xEF8B	0x98F2	#CJK UNIFIED IDEOGRAPH
+0xEF8C	0x98F3	#CJK UNIFIED IDEOGRAPH
+0xEF8D	0x98F4	#CJK UNIFIED IDEOGRAPH
+0xEF8E	0x98F5	#CJK UNIFIED IDEOGRAPH
+0xEF8F	0x98F6	#CJK UNIFIED IDEOGRAPH
+0xEF90	0x98F7	#CJK UNIFIED IDEOGRAPH
+0xEF91	0x98F8	#CJK UNIFIED IDEOGRAPH
+0xEF92	0x98F9	#CJK UNIFIED IDEOGRAPH
+0xEF93	0x98FA	#CJK UNIFIED IDEOGRAPH
+0xEF94	0x98FB	#CJK UNIFIED IDEOGRAPH
+0xEF95	0x98FC	#CJK UNIFIED IDEOGRAPH
+0xEF96	0x98FD	#CJK UNIFIED IDEOGRAPH
+0xEF97	0x98FE	#CJK UNIFIED IDEOGRAPH
+0xEF98	0x98FF	#CJK UNIFIED IDEOGRAPH
+0xEF99	0x9900	#CJK UNIFIED IDEOGRAPH
+0xEF9A	0x9901	#CJK UNIFIED IDEOGRAPH
+0xEF9B	0x9902	#CJK UNIFIED IDEOGRAPH
+0xEF9C	0x9903	#CJK UNIFIED IDEOGRAPH
+0xEF9D	0x9904	#CJK UNIFIED IDEOGRAPH
+0xEF9E	0x9905	#CJK UNIFIED IDEOGRAPH
+0xEF9F	0x9906	#CJK UNIFIED IDEOGRAPH
+0xEFA0	0x9907	#CJK UNIFIED IDEOGRAPH
+0xEFA1	0x94E9	#CJK UNIFIED IDEOGRAPH
+0xEFA2	0x94EB	#CJK UNIFIED IDEOGRAPH
+0xEFA3	0x94EE	#CJK UNIFIED IDEOGRAPH
+0xEFA4	0x94EF	#CJK UNIFIED IDEOGRAPH
+0xEFA5	0x94F3	#CJK UNIFIED IDEOGRAPH
+0xEFA6	0x94F4	#CJK UNIFIED IDEOGRAPH
+0xEFA7	0x94F5	#CJK UNIFIED IDEOGRAPH
+0xEFA8	0x94F7	#CJK UNIFIED IDEOGRAPH
+0xEFA9	0x94F9	#CJK UNIFIED IDEOGRAPH
+0xEFAA	0x94FC	#CJK UNIFIED IDEOGRAPH
+0xEFAB	0x94FD	#CJK UNIFIED IDEOGRAPH
+0xEFAC	0x94FF	#CJK UNIFIED IDEOGRAPH
+0xEFAD	0x9503	#CJK UNIFIED IDEOGRAPH
+0xEFAE	0x9502	#CJK UNIFIED IDEOGRAPH
+0xEFAF	0x9506	#CJK UNIFIED IDEOGRAPH
+0xEFB0	0x9507	#CJK UNIFIED IDEOGRAPH
+0xEFB1	0x9509	#CJK UNIFIED IDEOGRAPH
+0xEFB2	0x950A	#CJK UNIFIED IDEOGRAPH
+0xEFB3	0x950D	#CJK UNIFIED IDEOGRAPH
+0xEFB4	0x950E	#CJK UNIFIED IDEOGRAPH
+0xEFB5	0x950F	#CJK UNIFIED IDEOGRAPH
+0xEFB6	0x9512	#CJK UNIFIED IDEOGRAPH
+0xEFB7	0x9513	#CJK UNIFIED IDEOGRAPH
+0xEFB8	0x9514	#CJK UNIFIED IDEOGRAPH
+0xEFB9	0x9515	#CJK UNIFIED IDEOGRAPH
+0xEFBA	0x9516	#CJK UNIFIED IDEOGRAPH
+0xEFBB	0x9518	#CJK UNIFIED IDEOGRAPH
+0xEFBC	0x951B	#CJK UNIFIED IDEOGRAPH
+0xEFBD	0x951D	#CJK UNIFIED IDEOGRAPH
+0xEFBE	0x951E	#CJK UNIFIED IDEOGRAPH
+0xEFBF	0x951F	#CJK UNIFIED IDEOGRAPH
+0xEFC0	0x9522	#CJK UNIFIED IDEOGRAPH
+0xEFC1	0x952A	#CJK UNIFIED IDEOGRAPH
+0xEFC2	0x952B	#CJK UNIFIED IDEOGRAPH
+0xEFC3	0x9529	#CJK UNIFIED IDEOGRAPH
+0xEFC4	0x952C	#CJK UNIFIED IDEOGRAPH
+0xEFC5	0x9531	#CJK UNIFIED IDEOGRAPH
+0xEFC6	0x9532	#CJK UNIFIED IDEOGRAPH
+0xEFC7	0x9534	#CJK UNIFIED IDEOGRAPH
+0xEFC8	0x9536	#CJK UNIFIED IDEOGRAPH
+0xEFC9	0x9537	#CJK UNIFIED IDEOGRAPH
+0xEFCA	0x9538	#CJK UNIFIED IDEOGRAPH
+0xEFCB	0x953C	#CJK UNIFIED IDEOGRAPH
+0xEFCC	0x953E	#CJK UNIFIED IDEOGRAPH
+0xEFCD	0x953F	#CJK UNIFIED IDEOGRAPH
+0xEFCE	0x9542	#CJK UNIFIED IDEOGRAPH
+0xEFCF	0x9535	#CJK UNIFIED IDEOGRAPH
+0xEFD0	0x9544	#CJK UNIFIED IDEOGRAPH
+0xEFD1	0x9545	#CJK UNIFIED IDEOGRAPH
+0xEFD2	0x9546	#CJK UNIFIED IDEOGRAPH
+0xEFD3	0x9549	#CJK UNIFIED IDEOGRAPH
+0xEFD4	0x954C	#CJK UNIFIED IDEOGRAPH
+0xEFD5	0x954E	#CJK UNIFIED IDEOGRAPH
+0xEFD6	0x954F	#CJK UNIFIED IDEOGRAPH
+0xEFD7	0x9552	#CJK UNIFIED IDEOGRAPH
+0xEFD8	0x9553	#CJK UNIFIED IDEOGRAPH
+0xEFD9	0x9554	#CJK UNIFIED IDEOGRAPH
+0xEFDA	0x9556	#CJK UNIFIED IDEOGRAPH
+0xEFDB	0x9557	#CJK UNIFIED IDEOGRAPH
+0xEFDC	0x9558	#CJK UNIFIED IDEOGRAPH
+0xEFDD	0x9559	#CJK UNIFIED IDEOGRAPH
+0xEFDE	0x955B	#CJK UNIFIED IDEOGRAPH
+0xEFDF	0x955E	#CJK UNIFIED IDEOGRAPH
+0xEFE0	0x955F	#CJK UNIFIED IDEOGRAPH
+0xEFE1	0x955D	#CJK UNIFIED IDEOGRAPH
+0xEFE2	0x9561	#CJK UNIFIED IDEOGRAPH
+0xEFE3	0x9562	#CJK UNIFIED IDEOGRAPH
+0xEFE4	0x9564	#CJK UNIFIED IDEOGRAPH
+0xEFE5	0x9565	#CJK UNIFIED IDEOGRAPH
+0xEFE6	0x9566	#CJK UNIFIED IDEOGRAPH
+0xEFE7	0x9567	#CJK UNIFIED IDEOGRAPH
+0xEFE8	0x9568	#CJK UNIFIED IDEOGRAPH
+0xEFE9	0x9569	#CJK UNIFIED IDEOGRAPH
+0xEFEA	0x956A	#CJK UNIFIED IDEOGRAPH
+0xEFEB	0x956B	#CJK UNIFIED IDEOGRAPH
+0xEFEC	0x956C	#CJK UNIFIED IDEOGRAPH
+0xEFED	0x956F	#CJK UNIFIED IDEOGRAPH
+0xEFEE	0x9571	#CJK UNIFIED IDEOGRAPH
+0xEFEF	0x9572	#CJK UNIFIED IDEOGRAPH
+0xEFF0	0x9573	#CJK UNIFIED IDEOGRAPH
+0xEFF1	0x953A	#CJK UNIFIED IDEOGRAPH
+0xEFF2	0x77E7	#CJK UNIFIED IDEOGRAPH
+0xEFF3	0x77EC	#CJK UNIFIED IDEOGRAPH
+0xEFF4	0x96C9	#CJK UNIFIED IDEOGRAPH
+0xEFF5	0x79D5	#CJK UNIFIED IDEOGRAPH
+0xEFF6	0x79ED	#CJK UNIFIED IDEOGRAPH
+0xEFF7	0x79E3	#CJK UNIFIED IDEOGRAPH
+0xEFF8	0x79EB	#CJK UNIFIED IDEOGRAPH
+0xEFF9	0x7A06	#CJK UNIFIED IDEOGRAPH
+0xEFFA	0x5D47	#CJK UNIFIED IDEOGRAPH
+0xEFFB	0x7A03	#CJK UNIFIED IDEOGRAPH
+0xEFFC	0x7A02	#CJK UNIFIED IDEOGRAPH
+0xEFFD	0x7A1E	#CJK UNIFIED IDEOGRAPH
+0xEFFE	0x7A14	#CJK UNIFIED IDEOGRAPH
+0xF040	0x9908	#CJK UNIFIED IDEOGRAPH
+0xF041	0x9909	#CJK UNIFIED IDEOGRAPH
+0xF042	0x990A	#CJK UNIFIED IDEOGRAPH
+0xF043	0x990B	#CJK UNIFIED IDEOGRAPH
+0xF044	0x990C	#CJK UNIFIED IDEOGRAPH
+0xF045	0x990E	#CJK UNIFIED IDEOGRAPH
+0xF046	0x990F	#CJK UNIFIED IDEOGRAPH
+0xF047	0x9911	#CJK UNIFIED IDEOGRAPH
+0xF048	0x9912	#CJK UNIFIED IDEOGRAPH
+0xF049	0x9913	#CJK UNIFIED IDEOGRAPH
+0xF04A	0x9914	#CJK UNIFIED IDEOGRAPH
+0xF04B	0x9915	#CJK UNIFIED IDEOGRAPH
+0xF04C	0x9916	#CJK UNIFIED IDEOGRAPH
+0xF04D	0x9917	#CJK UNIFIED IDEOGRAPH
+0xF04E	0x9918	#CJK UNIFIED IDEOGRAPH
+0xF04F	0x9919	#CJK UNIFIED IDEOGRAPH
+0xF050	0x991A	#CJK UNIFIED IDEOGRAPH
+0xF051	0x991B	#CJK UNIFIED IDEOGRAPH
+0xF052	0x991C	#CJK UNIFIED IDEOGRAPH
+0xF053	0x991D	#CJK UNIFIED IDEOGRAPH
+0xF054	0x991E	#CJK UNIFIED IDEOGRAPH
+0xF055	0x991F	#CJK UNIFIED IDEOGRAPH
+0xF056	0x9920	#CJK UNIFIED IDEOGRAPH
+0xF057	0x9921	#CJK UNIFIED IDEOGRAPH
+0xF058	0x9922	#CJK UNIFIED IDEOGRAPH
+0xF059	0x9923	#CJK UNIFIED IDEOGRAPH
+0xF05A	0x9924	#CJK UNIFIED IDEOGRAPH
+0xF05B	0x9925	#CJK UNIFIED IDEOGRAPH
+0xF05C	0x9926	#CJK UNIFIED IDEOGRAPH
+0xF05D	0x9927	#CJK UNIFIED IDEOGRAPH
+0xF05E	0x9928	#CJK UNIFIED IDEOGRAPH
+0xF05F	0x9929	#CJK UNIFIED IDEOGRAPH
+0xF060	0x992A	#CJK UNIFIED IDEOGRAPH
+0xF061	0x992B	#CJK UNIFIED IDEOGRAPH
+0xF062	0x992C	#CJK UNIFIED IDEOGRAPH
+0xF063	0x992D	#CJK UNIFIED IDEOGRAPH
+0xF064	0x992F	#CJK UNIFIED IDEOGRAPH
+0xF065	0x9930	#CJK UNIFIED IDEOGRAPH
+0xF066	0x9931	#CJK UNIFIED IDEOGRAPH
+0xF067	0x9932	#CJK UNIFIED IDEOGRAPH
+0xF068	0x9933	#CJK UNIFIED IDEOGRAPH
+0xF069	0x9934	#CJK UNIFIED IDEOGRAPH
+0xF06A	0x9935	#CJK UNIFIED IDEOGRAPH
+0xF06B	0x9936	#CJK UNIFIED IDEOGRAPH
+0xF06C	0x9937	#CJK UNIFIED IDEOGRAPH
+0xF06D	0x9938	#CJK UNIFIED IDEOGRAPH
+0xF06E	0x9939	#CJK UNIFIED IDEOGRAPH
+0xF06F	0x993A	#CJK UNIFIED IDEOGRAPH
+0xF070	0x993B	#CJK UNIFIED IDEOGRAPH
+0xF071	0x993C	#CJK UNIFIED IDEOGRAPH
+0xF072	0x993D	#CJK UNIFIED IDEOGRAPH
+0xF073	0x993E	#CJK UNIFIED IDEOGRAPH
+0xF074	0x993F	#CJK UNIFIED IDEOGRAPH
+0xF075	0x9940	#CJK UNIFIED IDEOGRAPH
+0xF076	0x9941	#CJK UNIFIED IDEOGRAPH
+0xF077	0x9942	#CJK UNIFIED IDEOGRAPH
+0xF078	0x9943	#CJK UNIFIED IDEOGRAPH
+0xF079	0x9944	#CJK UNIFIED IDEOGRAPH
+0xF07A	0x9945	#CJK UNIFIED IDEOGRAPH
+0xF07B	0x9946	#CJK UNIFIED IDEOGRAPH
+0xF07C	0x9947	#CJK UNIFIED IDEOGRAPH
+0xF07D	0x9948	#CJK UNIFIED IDEOGRAPH
+0xF07E	0x9949	#CJK UNIFIED IDEOGRAPH
+0xF080	0x994A	#CJK UNIFIED IDEOGRAPH
+0xF081	0x994B	#CJK UNIFIED IDEOGRAPH
+0xF082	0x994C	#CJK UNIFIED IDEOGRAPH
+0xF083	0x994D	#CJK UNIFIED IDEOGRAPH
+0xF084	0x994E	#CJK UNIFIED IDEOGRAPH
+0xF085	0x994F	#CJK UNIFIED IDEOGRAPH
+0xF086	0x9950	#CJK UNIFIED IDEOGRAPH
+0xF087	0x9951	#CJK UNIFIED IDEOGRAPH
+0xF088	0x9952	#CJK UNIFIED IDEOGRAPH
+0xF089	0x9953	#CJK UNIFIED IDEOGRAPH
+0xF08A	0x9956	#CJK UNIFIED IDEOGRAPH
+0xF08B	0x9957	#CJK UNIFIED IDEOGRAPH
+0xF08C	0x9958	#CJK UNIFIED IDEOGRAPH
+0xF08D	0x9959	#CJK UNIFIED IDEOGRAPH
+0xF08E	0x995A	#CJK UNIFIED IDEOGRAPH
+0xF08F	0x995B	#CJK UNIFIED IDEOGRAPH
+0xF090	0x995C	#CJK UNIFIED IDEOGRAPH
+0xF091	0x995D	#CJK UNIFIED IDEOGRAPH
+0xF092	0x995E	#CJK UNIFIED IDEOGRAPH
+0xF093	0x995F	#CJK UNIFIED IDEOGRAPH
+0xF094	0x9960	#CJK UNIFIED IDEOGRAPH
+0xF095	0x9961	#CJK UNIFIED IDEOGRAPH
+0xF096	0x9962	#CJK UNIFIED IDEOGRAPH
+0xF097	0x9964	#CJK UNIFIED IDEOGRAPH
+0xF098	0x9966	#CJK UNIFIED IDEOGRAPH
+0xF099	0x9973	#CJK UNIFIED IDEOGRAPH
+0xF09A	0x9978	#CJK UNIFIED IDEOGRAPH
+0xF09B	0x9979	#CJK UNIFIED IDEOGRAPH
+0xF09C	0x997B	#CJK UNIFIED IDEOGRAPH
+0xF09D	0x997E	#CJK UNIFIED IDEOGRAPH
+0xF09E	0x9982	#CJK UNIFIED IDEOGRAPH
+0xF09F	0x9983	#CJK UNIFIED IDEOGRAPH
+0xF0A0	0x9989	#CJK UNIFIED IDEOGRAPH
+0xF0A1	0x7A39	#CJK UNIFIED IDEOGRAPH
+0xF0A2	0x7A37	#CJK UNIFIED IDEOGRAPH
+0xF0A3	0x7A51	#CJK UNIFIED IDEOGRAPH
+0xF0A4	0x9ECF	#CJK UNIFIED IDEOGRAPH
+0xF0A5	0x99A5	#CJK UNIFIED IDEOGRAPH
+0xF0A6	0x7A70	#CJK UNIFIED IDEOGRAPH
+0xF0A7	0x7688	#CJK UNIFIED IDEOGRAPH
+0xF0A8	0x768E	#CJK UNIFIED IDEOGRAPH
+0xF0A9	0x7693	#CJK UNIFIED IDEOGRAPH
+0xF0AA	0x7699	#CJK UNIFIED IDEOGRAPH
+0xF0AB	0x76A4	#CJK UNIFIED IDEOGRAPH
+0xF0AC	0x74DE	#CJK UNIFIED IDEOGRAPH
+0xF0AD	0x74E0	#CJK UNIFIED IDEOGRAPH
+0xF0AE	0x752C	#CJK UNIFIED IDEOGRAPH
+0xF0AF	0x9E20	#CJK UNIFIED IDEOGRAPH
+0xF0B0	0x9E22	#CJK UNIFIED IDEOGRAPH
+0xF0B1	0x9E28	#CJK UNIFIED IDEOGRAPH
+0xF0B2	0x9E29	#CJK UNIFIED IDEOGRAPH
+0xF0B3	0x9E2A	#CJK UNIFIED IDEOGRAPH
+0xF0B4	0x9E2B	#CJK UNIFIED IDEOGRAPH
+0xF0B5	0x9E2C	#CJK UNIFIED IDEOGRAPH
+0xF0B6	0x9E32	#CJK UNIFIED IDEOGRAPH
+0xF0B7	0x9E31	#CJK UNIFIED IDEOGRAPH
+0xF0B8	0x9E36	#CJK UNIFIED IDEOGRAPH
+0xF0B9	0x9E38	#CJK UNIFIED IDEOGRAPH
+0xF0BA	0x9E37	#CJK UNIFIED IDEOGRAPH
+0xF0BB	0x9E39	#CJK UNIFIED IDEOGRAPH
+0xF0BC	0x9E3A	#CJK UNIFIED IDEOGRAPH
+0xF0BD	0x9E3E	#CJK UNIFIED IDEOGRAPH
+0xF0BE	0x9E41	#CJK UNIFIED IDEOGRAPH
+0xF0BF	0x9E42	#CJK UNIFIED IDEOGRAPH
+0xF0C0	0x9E44	#CJK UNIFIED IDEOGRAPH
+0xF0C1	0x9E46	#CJK UNIFIED IDEOGRAPH
+0xF0C2	0x9E47	#CJK UNIFIED IDEOGRAPH
+0xF0C3	0x9E48	#CJK UNIFIED IDEOGRAPH
+0xF0C4	0x9E49	#CJK UNIFIED IDEOGRAPH
+0xF0C5	0x9E4B	#CJK UNIFIED IDEOGRAPH
+0xF0C6	0x9E4C	#CJK UNIFIED IDEOGRAPH
+0xF0C7	0x9E4E	#CJK UNIFIED IDEOGRAPH
+0xF0C8	0x9E51	#CJK UNIFIED IDEOGRAPH
+0xF0C9	0x9E55	#CJK UNIFIED IDEOGRAPH
+0xF0CA	0x9E57	#CJK UNIFIED IDEOGRAPH
+0xF0CB	0x9E5A	#CJK UNIFIED IDEOGRAPH
+0xF0CC	0x9E5B	#CJK UNIFIED IDEOGRAPH
+0xF0CD	0x9E5C	#CJK UNIFIED IDEOGRAPH
+0xF0CE	0x9E5E	#CJK UNIFIED IDEOGRAPH
+0xF0CF	0x9E63	#CJK UNIFIED IDEOGRAPH
+0xF0D0	0x9E66	#CJK UNIFIED IDEOGRAPH
+0xF0D1	0x9E67	#CJK UNIFIED IDEOGRAPH
+0xF0D2	0x9E68	#CJK UNIFIED IDEOGRAPH
+0xF0D3	0x9E69	#CJK UNIFIED IDEOGRAPH
+0xF0D4	0x9E6A	#CJK UNIFIED IDEOGRAPH
+0xF0D5	0x9E6B	#CJK UNIFIED IDEOGRAPH
+0xF0D6	0x9E6C	#CJK UNIFIED IDEOGRAPH
+0xF0D7	0x9E71	#CJK UNIFIED IDEOGRAPH
+0xF0D8	0x9E6D	#CJK UNIFIED IDEOGRAPH
+0xF0D9	0x9E73	#CJK UNIFIED IDEOGRAPH
+0xF0DA	0x7592	#CJK UNIFIED IDEOGRAPH
+0xF0DB	0x7594	#CJK UNIFIED IDEOGRAPH
+0xF0DC	0x7596	#CJK UNIFIED IDEOGRAPH
+0xF0DD	0x75A0	#CJK UNIFIED IDEOGRAPH
+0xF0DE	0x759D	#CJK UNIFIED IDEOGRAPH
+0xF0DF	0x75AC	#CJK UNIFIED IDEOGRAPH
+0xF0E0	0x75A3	#CJK UNIFIED IDEOGRAPH
+0xF0E1	0x75B3	#CJK UNIFIED IDEOGRAPH
+0xF0E2	0x75B4	#CJK UNIFIED IDEOGRAPH
+0xF0E3	0x75B8	#CJK UNIFIED IDEOGRAPH
+0xF0E4	0x75C4	#CJK UNIFIED IDEOGRAPH
+0xF0E5	0x75B1	#CJK UNIFIED IDEOGRAPH
+0xF0E6	0x75B0	#CJK UNIFIED IDEOGRAPH
+0xF0E7	0x75C3	#CJK UNIFIED IDEOGRAPH
+0xF0E8	0x75C2	#CJK UNIFIED IDEOGRAPH
+0xF0E9	0x75D6	#CJK UNIFIED IDEOGRAPH
+0xF0EA	0x75CD	#CJK UNIFIED IDEOGRAPH
+0xF0EB	0x75E3	#CJK UNIFIED IDEOGRAPH
+0xF0EC	0x75E8	#CJK UNIFIED IDEOGRAPH
+0xF0ED	0x75E6	#CJK UNIFIED IDEOGRAPH
+0xF0EE	0x75E4	#CJK UNIFIED IDEOGRAPH
+0xF0EF	0x75EB	#CJK UNIFIED IDEOGRAPH
+0xF0F0	0x75E7	#CJK UNIFIED IDEOGRAPH
+0xF0F1	0x7603	#CJK UNIFIED IDEOGRAPH
+0xF0F2	0x75F1	#CJK UNIFIED IDEOGRAPH
+0xF0F3	0x75FC	#CJK UNIFIED IDEOGRAPH
+0xF0F4	0x75FF	#CJK UNIFIED IDEOGRAPH
+0xF0F5	0x7610	#CJK UNIFIED IDEOGRAPH
+0xF0F6	0x7600	#CJK UNIFIED IDEOGRAPH
+0xF0F7	0x7605	#CJK UNIFIED IDEOGRAPH
+0xF0F8	0x760C	#CJK UNIFIED IDEOGRAPH
+0xF0F9	0x7617	#CJK UNIFIED IDEOGRAPH
+0xF0FA	0x760A	#CJK UNIFIED IDEOGRAPH
+0xF0FB	0x7625	#CJK UNIFIED IDEOGRAPH
+0xF0FC	0x7618	#CJK UNIFIED IDEOGRAPH
+0xF0FD	0x7615	#CJK UNIFIED IDEOGRAPH
+0xF0FE	0x7619	#CJK UNIFIED IDEOGRAPH
+0xF140	0x998C	#CJK UNIFIED IDEOGRAPH
+0xF141	0x998E	#CJK UNIFIED IDEOGRAPH
+0xF142	0x999A	#CJK UNIFIED IDEOGRAPH
+0xF143	0x999B	#CJK UNIFIED IDEOGRAPH
+0xF144	0x999C	#CJK UNIFIED IDEOGRAPH
+0xF145	0x999D	#CJK UNIFIED IDEOGRAPH
+0xF146	0x999E	#CJK UNIFIED IDEOGRAPH
+0xF147	0x999F	#CJK UNIFIED IDEOGRAPH
+0xF148	0x99A0	#CJK UNIFIED IDEOGRAPH
+0xF149	0x99A1	#CJK UNIFIED IDEOGRAPH
+0xF14A	0x99A2	#CJK UNIFIED IDEOGRAPH
+0xF14B	0x99A3	#CJK UNIFIED IDEOGRAPH
+0xF14C	0x99A4	#CJK UNIFIED IDEOGRAPH
+0xF14D	0x99A6	#CJK UNIFIED IDEOGRAPH
+0xF14E	0x99A7	#CJK UNIFIED IDEOGRAPH
+0xF14F	0x99A9	#CJK UNIFIED IDEOGRAPH
+0xF150	0x99AA	#CJK UNIFIED IDEOGRAPH
+0xF151	0x99AB	#CJK UNIFIED IDEOGRAPH
+0xF152	0x99AC	#CJK UNIFIED IDEOGRAPH
+0xF153	0x99AD	#CJK UNIFIED IDEOGRAPH
+0xF154	0x99AE	#CJK UNIFIED IDEOGRAPH
+0xF155	0x99AF	#CJK UNIFIED IDEOGRAPH
+0xF156	0x99B0	#CJK UNIFIED IDEOGRAPH
+0xF157	0x99B1	#CJK UNIFIED IDEOGRAPH
+0xF158	0x99B2	#CJK UNIFIED IDEOGRAPH
+0xF159	0x99B3	#CJK UNIFIED IDEOGRAPH
+0xF15A	0x99B4	#CJK UNIFIED IDEOGRAPH
+0xF15B	0x99B5	#CJK UNIFIED IDEOGRAPH
+0xF15C	0x99B6	#CJK UNIFIED IDEOGRAPH
+0xF15D	0x99B7	#CJK UNIFIED IDEOGRAPH
+0xF15E	0x99B8	#CJK UNIFIED IDEOGRAPH
+0xF15F	0x99B9	#CJK UNIFIED IDEOGRAPH
+0xF160	0x99BA	#CJK UNIFIED IDEOGRAPH
+0xF161	0x99BB	#CJK UNIFIED IDEOGRAPH
+0xF162	0x99BC	#CJK UNIFIED IDEOGRAPH
+0xF163	0x99BD	#CJK UNIFIED IDEOGRAPH
+0xF164	0x99BE	#CJK UNIFIED IDEOGRAPH
+0xF165	0x99BF	#CJK UNIFIED IDEOGRAPH
+0xF166	0x99C0	#CJK UNIFIED IDEOGRAPH
+0xF167	0x99C1	#CJK UNIFIED IDEOGRAPH
+0xF168	0x99C2	#CJK UNIFIED IDEOGRAPH
+0xF169	0x99C3	#CJK UNIFIED IDEOGRAPH
+0xF16A	0x99C4	#CJK UNIFIED IDEOGRAPH
+0xF16B	0x99C5	#CJK UNIFIED IDEOGRAPH
+0xF16C	0x99C6	#CJK UNIFIED IDEOGRAPH
+0xF16D	0x99C7	#CJK UNIFIED IDEOGRAPH
+0xF16E	0x99C8	#CJK UNIFIED IDEOGRAPH
+0xF16F	0x99C9	#CJK UNIFIED IDEOGRAPH
+0xF170	0x99CA	#CJK UNIFIED IDEOGRAPH
+0xF171	0x99CB	#CJK UNIFIED IDEOGRAPH
+0xF172	0x99CC	#CJK UNIFIED IDEOGRAPH
+0xF173	0x99CD	#CJK UNIFIED IDEOGRAPH
+0xF174	0x99CE	#CJK UNIFIED IDEOGRAPH
+0xF175	0x99CF	#CJK UNIFIED IDEOGRAPH
+0xF176	0x99D0	#CJK UNIFIED IDEOGRAPH
+0xF177	0x99D1	#CJK UNIFIED IDEOGRAPH
+0xF178	0x99D2	#CJK UNIFIED IDEOGRAPH
+0xF179	0x99D3	#CJK UNIFIED IDEOGRAPH
+0xF17A	0x99D4	#CJK UNIFIED IDEOGRAPH
+0xF17B	0x99D5	#CJK UNIFIED IDEOGRAPH
+0xF17C	0x99D6	#CJK UNIFIED IDEOGRAPH
+0xF17D	0x99D7	#CJK UNIFIED IDEOGRAPH
+0xF17E	0x99D8	#CJK UNIFIED IDEOGRAPH
+0xF180	0x99D9	#CJK UNIFIED IDEOGRAPH
+0xF181	0x99DA	#CJK UNIFIED IDEOGRAPH
+0xF182	0x99DB	#CJK UNIFIED IDEOGRAPH
+0xF183	0x99DC	#CJK UNIFIED IDEOGRAPH
+0xF184	0x99DD	#CJK UNIFIED IDEOGRAPH
+0xF185	0x99DE	#CJK UNIFIED IDEOGRAPH
+0xF186	0x99DF	#CJK UNIFIED IDEOGRAPH
+0xF187	0x99E0	#CJK UNIFIED IDEOGRAPH
+0xF188	0x99E1	#CJK UNIFIED IDEOGRAPH
+0xF189	0x99E2	#CJK UNIFIED IDEOGRAPH
+0xF18A	0x99E3	#CJK UNIFIED IDEOGRAPH
+0xF18B	0x99E4	#CJK UNIFIED IDEOGRAPH
+0xF18C	0x99E5	#CJK UNIFIED IDEOGRAPH
+0xF18D	0x99E6	#CJK UNIFIED IDEOGRAPH
+0xF18E	0x99E7	#CJK UNIFIED IDEOGRAPH
+0xF18F	0x99E8	#CJK UNIFIED IDEOGRAPH
+0xF190	0x99E9	#CJK UNIFIED IDEOGRAPH
+0xF191	0x99EA	#CJK UNIFIED IDEOGRAPH
+0xF192	0x99EB	#CJK UNIFIED IDEOGRAPH
+0xF193	0x99EC	#CJK UNIFIED IDEOGRAPH
+0xF194	0x99ED	#CJK UNIFIED IDEOGRAPH
+0xF195	0x99EE	#CJK UNIFIED IDEOGRAPH
+0xF196	0x99EF	#CJK UNIFIED IDEOGRAPH
+0xF197	0x99F0	#CJK UNIFIED IDEOGRAPH
+0xF198	0x99F1	#CJK UNIFIED IDEOGRAPH
+0xF199	0x99F2	#CJK UNIFIED IDEOGRAPH
+0xF19A	0x99F3	#CJK UNIFIED IDEOGRAPH
+0xF19B	0x99F4	#CJK UNIFIED IDEOGRAPH
+0xF19C	0x99F5	#CJK UNIFIED IDEOGRAPH
+0xF19D	0x99F6	#CJK UNIFIED IDEOGRAPH
+0xF19E	0x99F7	#CJK UNIFIED IDEOGRAPH
+0xF19F	0x99F8	#CJK UNIFIED IDEOGRAPH
+0xF1A0	0x99F9	#CJK UNIFIED IDEOGRAPH
+0xF1A1	0x761B	#CJK UNIFIED IDEOGRAPH
+0xF1A2	0x763C	#CJK UNIFIED IDEOGRAPH
+0xF1A3	0x7622	#CJK UNIFIED IDEOGRAPH
+0xF1A4	0x7620	#CJK UNIFIED IDEOGRAPH
+0xF1A5	0x7640	#CJK UNIFIED IDEOGRAPH
+0xF1A6	0x762D	#CJK UNIFIED IDEOGRAPH
+0xF1A7	0x7630	#CJK UNIFIED IDEOGRAPH
+0xF1A8	0x763F	#CJK UNIFIED IDEOGRAPH
+0xF1A9	0x7635	#CJK UNIFIED IDEOGRAPH
+0xF1AA	0x7643	#CJK UNIFIED IDEOGRAPH
+0xF1AB	0x763E	#CJK UNIFIED IDEOGRAPH
+0xF1AC	0x7633	#CJK UNIFIED IDEOGRAPH
+0xF1AD	0x764D	#CJK UNIFIED IDEOGRAPH
+0xF1AE	0x765E	#CJK UNIFIED IDEOGRAPH
+0xF1AF	0x7654	#CJK UNIFIED IDEOGRAPH
+0xF1B0	0x765C	#CJK UNIFIED IDEOGRAPH
+0xF1B1	0x7656	#CJK UNIFIED IDEOGRAPH
+0xF1B2	0x766B	#CJK UNIFIED IDEOGRAPH
+0xF1B3	0x766F	#CJK UNIFIED IDEOGRAPH
+0xF1B4	0x7FCA	#CJK UNIFIED IDEOGRAPH
+0xF1B5	0x7AE6	#CJK UNIFIED IDEOGRAPH
+0xF1B6	0x7A78	#CJK UNIFIED IDEOGRAPH
+0xF1B7	0x7A79	#CJK UNIFIED IDEOGRAPH
+0xF1B8	0x7A80	#CJK UNIFIED IDEOGRAPH
+0xF1B9	0x7A86	#CJK UNIFIED IDEOGRAPH
+0xF1BA	0x7A88	#CJK UNIFIED IDEOGRAPH
+0xF1BB	0x7A95	#CJK UNIFIED IDEOGRAPH
+0xF1BC	0x7AA6	#CJK UNIFIED IDEOGRAPH
+0xF1BD	0x7AA0	#CJK UNIFIED IDEOGRAPH
+0xF1BE	0x7AAC	#CJK UNIFIED IDEOGRAPH
+0xF1BF	0x7AA8	#CJK UNIFIED IDEOGRAPH
+0xF1C0	0x7AAD	#CJK UNIFIED IDEOGRAPH
+0xF1C1	0x7AB3	#CJK UNIFIED IDEOGRAPH
+0xF1C2	0x8864	#CJK UNIFIED IDEOGRAPH
+0xF1C3	0x8869	#CJK UNIFIED IDEOGRAPH
+0xF1C4	0x8872	#CJK UNIFIED IDEOGRAPH
+0xF1C5	0x887D	#CJK UNIFIED IDEOGRAPH
+0xF1C6	0x887F	#CJK UNIFIED IDEOGRAPH
+0xF1C7	0x8882	#CJK UNIFIED IDEOGRAPH
+0xF1C8	0x88A2	#CJK UNIFIED IDEOGRAPH
+0xF1C9	0x88C6	#CJK UNIFIED IDEOGRAPH
+0xF1CA	0x88B7	#CJK UNIFIED IDEOGRAPH
+0xF1CB	0x88BC	#CJK UNIFIED IDEOGRAPH
+0xF1CC	0x88C9	#CJK UNIFIED IDEOGRAPH
+0xF1CD	0x88E2	#CJK UNIFIED IDEOGRAPH
+0xF1CE	0x88CE	#CJK UNIFIED IDEOGRAPH
+0xF1CF	0x88E3	#CJK UNIFIED IDEOGRAPH
+0xF1D0	0x88E5	#CJK UNIFIED IDEOGRAPH
+0xF1D1	0x88F1	#CJK UNIFIED IDEOGRAPH
+0xF1D2	0x891A	#CJK UNIFIED IDEOGRAPH
+0xF1D3	0x88FC	#CJK UNIFIED IDEOGRAPH
+0xF1D4	0x88E8	#CJK UNIFIED IDEOGRAPH
+0xF1D5	0x88FE	#CJK UNIFIED IDEOGRAPH
+0xF1D6	0x88F0	#CJK UNIFIED IDEOGRAPH
+0xF1D7	0x8921	#CJK UNIFIED IDEOGRAPH
+0xF1D8	0x8919	#CJK UNIFIED IDEOGRAPH
+0xF1D9	0x8913	#CJK UNIFIED IDEOGRAPH
+0xF1DA	0x891B	#CJK UNIFIED IDEOGRAPH
+0xF1DB	0x890A	#CJK UNIFIED IDEOGRAPH
+0xF1DC	0x8934	#CJK UNIFIED IDEOGRAPH
+0xF1DD	0x892B	#CJK UNIFIED IDEOGRAPH
+0xF1DE	0x8936	#CJK UNIFIED IDEOGRAPH
+0xF1DF	0x8941	#CJK UNIFIED IDEOGRAPH
+0xF1E0	0x8966	#CJK UNIFIED IDEOGRAPH
+0xF1E1	0x897B	#CJK UNIFIED IDEOGRAPH
+0xF1E2	0x758B	#CJK UNIFIED IDEOGRAPH
+0xF1E3	0x80E5	#CJK UNIFIED IDEOGRAPH
+0xF1E4	0x76B2	#CJK UNIFIED IDEOGRAPH
+0xF1E5	0x76B4	#CJK UNIFIED IDEOGRAPH
+0xF1E6	0x77DC	#CJK UNIFIED IDEOGRAPH
+0xF1E7	0x8012	#CJK UNIFIED IDEOGRAPH
+0xF1E8	0x8014	#CJK UNIFIED IDEOGRAPH
+0xF1E9	0x8016	#CJK UNIFIED IDEOGRAPH
+0xF1EA	0x801C	#CJK UNIFIED IDEOGRAPH
+0xF1EB	0x8020	#CJK UNIFIED IDEOGRAPH
+0xF1EC	0x8022	#CJK UNIFIED IDEOGRAPH
+0xF1ED	0x8025	#CJK UNIFIED IDEOGRAPH
+0xF1EE	0x8026	#CJK UNIFIED IDEOGRAPH
+0xF1EF	0x8027	#CJK UNIFIED IDEOGRAPH
+0xF1F0	0x8029	#CJK UNIFIED IDEOGRAPH
+0xF1F1	0x8028	#CJK UNIFIED IDEOGRAPH
+0xF1F2	0x8031	#CJK UNIFIED IDEOGRAPH
+0xF1F3	0x800B	#CJK UNIFIED IDEOGRAPH
+0xF1F4	0x8035	#CJK UNIFIED IDEOGRAPH
+0xF1F5	0x8043	#CJK UNIFIED IDEOGRAPH
+0xF1F6	0x8046	#CJK UNIFIED IDEOGRAPH
+0xF1F7	0x804D	#CJK UNIFIED IDEOGRAPH
+0xF1F8	0x8052	#CJK UNIFIED IDEOGRAPH
+0xF1F9	0x8069	#CJK UNIFIED IDEOGRAPH
+0xF1FA	0x8071	#CJK UNIFIED IDEOGRAPH
+0xF1FB	0x8983	#CJK UNIFIED IDEOGRAPH
+0xF1FC	0x9878	#CJK UNIFIED IDEOGRAPH
+0xF1FD	0x9880	#CJK UNIFIED IDEOGRAPH
+0xF1FE	0x9883	#CJK UNIFIED IDEOGRAPH
+0xF240	0x99FA	#CJK UNIFIED IDEOGRAPH
+0xF241	0x99FB	#CJK UNIFIED IDEOGRAPH
+0xF242	0x99FC	#CJK UNIFIED IDEOGRAPH
+0xF243	0x99FD	#CJK UNIFIED IDEOGRAPH
+0xF244	0x99FE	#CJK UNIFIED IDEOGRAPH
+0xF245	0x99FF	#CJK UNIFIED IDEOGRAPH
+0xF246	0x9A00	#CJK UNIFIED IDEOGRAPH
+0xF247	0x9A01	#CJK UNIFIED IDEOGRAPH
+0xF248	0x9A02	#CJK UNIFIED IDEOGRAPH
+0xF249	0x9A03	#CJK UNIFIED IDEOGRAPH
+0xF24A	0x9A04	#CJK UNIFIED IDEOGRAPH
+0xF24B	0x9A05	#CJK UNIFIED IDEOGRAPH
+0xF24C	0x9A06	#CJK UNIFIED IDEOGRAPH
+0xF24D	0x9A07	#CJK UNIFIED IDEOGRAPH
+0xF24E	0x9A08	#CJK UNIFIED IDEOGRAPH
+0xF24F	0x9A09	#CJK UNIFIED IDEOGRAPH
+0xF250	0x9A0A	#CJK UNIFIED IDEOGRAPH
+0xF251	0x9A0B	#CJK UNIFIED IDEOGRAPH
+0xF252	0x9A0C	#CJK UNIFIED IDEOGRAPH
+0xF253	0x9A0D	#CJK UNIFIED IDEOGRAPH
+0xF254	0x9A0E	#CJK UNIFIED IDEOGRAPH
+0xF255	0x9A0F	#CJK UNIFIED IDEOGRAPH
+0xF256	0x9A10	#CJK UNIFIED IDEOGRAPH
+0xF257	0x9A11	#CJK UNIFIED IDEOGRAPH
+0xF258	0x9A12	#CJK UNIFIED IDEOGRAPH
+0xF259	0x9A13	#CJK UNIFIED IDEOGRAPH
+0xF25A	0x9A14	#CJK UNIFIED IDEOGRAPH
+0xF25B	0x9A15	#CJK UNIFIED IDEOGRAPH
+0xF25C	0x9A16	#CJK UNIFIED IDEOGRAPH
+0xF25D	0x9A17	#CJK UNIFIED IDEOGRAPH
+0xF25E	0x9A18	#CJK UNIFIED IDEOGRAPH
+0xF25F	0x9A19	#CJK UNIFIED IDEOGRAPH
+0xF260	0x9A1A	#CJK UNIFIED IDEOGRAPH
+0xF261	0x9A1B	#CJK UNIFIED IDEOGRAPH
+0xF262	0x9A1C	#CJK UNIFIED IDEOGRAPH
+0xF263	0x9A1D	#CJK UNIFIED IDEOGRAPH
+0xF264	0x9A1E	#CJK UNIFIED IDEOGRAPH
+0xF265	0x9A1F	#CJK UNIFIED IDEOGRAPH
+0xF266	0x9A20	#CJK UNIFIED IDEOGRAPH
+0xF267	0x9A21	#CJK UNIFIED IDEOGRAPH
+0xF268	0x9A22	#CJK UNIFIED IDEOGRAPH
+0xF269	0x9A23	#CJK UNIFIED IDEOGRAPH
+0xF26A	0x9A24	#CJK UNIFIED IDEOGRAPH
+0xF26B	0x9A25	#CJK UNIFIED IDEOGRAPH
+0xF26C	0x9A26	#CJK UNIFIED IDEOGRAPH
+0xF26D	0x9A27	#CJK UNIFIED IDEOGRAPH
+0xF26E	0x9A28	#CJK UNIFIED IDEOGRAPH
+0xF26F	0x9A29	#CJK UNIFIED IDEOGRAPH
+0xF270	0x9A2A	#CJK UNIFIED IDEOGRAPH
+0xF271	0x9A2B	#CJK UNIFIED IDEOGRAPH
+0xF272	0x9A2C	#CJK UNIFIED IDEOGRAPH
+0xF273	0x9A2D	#CJK UNIFIED IDEOGRAPH
+0xF274	0x9A2E	#CJK UNIFIED IDEOGRAPH
+0xF275	0x9A2F	#CJK UNIFIED IDEOGRAPH
+0xF276	0x9A30	#CJK UNIFIED IDEOGRAPH
+0xF277	0x9A31	#CJK UNIFIED IDEOGRAPH
+0xF278	0x9A32	#CJK UNIFIED IDEOGRAPH
+0xF279	0x9A33	#CJK UNIFIED IDEOGRAPH
+0xF27A	0x9A34	#CJK UNIFIED IDEOGRAPH
+0xF27B	0x9A35	#CJK UNIFIED IDEOGRAPH
+0xF27C	0x9A36	#CJK UNIFIED IDEOGRAPH
+0xF27D	0x9A37	#CJK UNIFIED IDEOGRAPH
+0xF27E	0x9A38	#CJK UNIFIED IDEOGRAPH
+0xF280	0x9A39	#CJK UNIFIED IDEOGRAPH
+0xF281	0x9A3A	#CJK UNIFIED IDEOGRAPH
+0xF282	0x9A3B	#CJK UNIFIED IDEOGRAPH
+0xF283	0x9A3C	#CJK UNIFIED IDEOGRAPH
+0xF284	0x9A3D	#CJK UNIFIED IDEOGRAPH
+0xF285	0x9A3E	#CJK UNIFIED IDEOGRAPH
+0xF286	0x9A3F	#CJK UNIFIED IDEOGRAPH
+0xF287	0x9A40	#CJK UNIFIED IDEOGRAPH
+0xF288	0x9A41	#CJK UNIFIED IDEOGRAPH
+0xF289	0x9A42	#CJK UNIFIED IDEOGRAPH
+0xF28A	0x9A43	#CJK UNIFIED IDEOGRAPH
+0xF28B	0x9A44	#CJK UNIFIED IDEOGRAPH
+0xF28C	0x9A45	#CJK UNIFIED IDEOGRAPH
+0xF28D	0x9A46	#CJK UNIFIED IDEOGRAPH
+0xF28E	0x9A47	#CJK UNIFIED IDEOGRAPH
+0xF28F	0x9A48	#CJK UNIFIED IDEOGRAPH
+0xF290	0x9A49	#CJK UNIFIED IDEOGRAPH
+0xF291	0x9A4A	#CJK UNIFIED IDEOGRAPH
+0xF292	0x9A4B	#CJK UNIFIED IDEOGRAPH
+0xF293	0x9A4C	#CJK UNIFIED IDEOGRAPH
+0xF294	0x9A4D	#CJK UNIFIED IDEOGRAPH
+0xF295	0x9A4E	#CJK UNIFIED IDEOGRAPH
+0xF296	0x9A4F	#CJK UNIFIED IDEOGRAPH
+0xF297	0x9A50	#CJK UNIFIED IDEOGRAPH
+0xF298	0x9A51	#CJK UNIFIED IDEOGRAPH
+0xF299	0x9A52	#CJK UNIFIED IDEOGRAPH
+0xF29A	0x9A53	#CJK UNIFIED IDEOGRAPH
+0xF29B	0x9A54	#CJK UNIFIED IDEOGRAPH
+0xF29C	0x9A55	#CJK UNIFIED IDEOGRAPH
+0xF29D	0x9A56	#CJK UNIFIED IDEOGRAPH
+0xF29E	0x9A57	#CJK UNIFIED IDEOGRAPH
+0xF29F	0x9A58	#CJK UNIFIED IDEOGRAPH
+0xF2A0	0x9A59	#CJK UNIFIED IDEOGRAPH
+0xF2A1	0x9889	#CJK UNIFIED IDEOGRAPH
+0xF2A2	0x988C	#CJK UNIFIED IDEOGRAPH
+0xF2A3	0x988D	#CJK UNIFIED IDEOGRAPH
+0xF2A4	0x988F	#CJK UNIFIED IDEOGRAPH
+0xF2A5	0x9894	#CJK UNIFIED IDEOGRAPH
+0xF2A6	0x989A	#CJK UNIFIED IDEOGRAPH
+0xF2A7	0x989B	#CJK UNIFIED IDEOGRAPH
+0xF2A8	0x989E	#CJK UNIFIED IDEOGRAPH
+0xF2A9	0x989F	#CJK UNIFIED IDEOGRAPH
+0xF2AA	0x98A1	#CJK UNIFIED IDEOGRAPH
+0xF2AB	0x98A2	#CJK UNIFIED IDEOGRAPH
+0xF2AC	0x98A5	#CJK UNIFIED IDEOGRAPH
+0xF2AD	0x98A6	#CJK UNIFIED IDEOGRAPH
+0xF2AE	0x864D	#CJK UNIFIED IDEOGRAPH
+0xF2AF	0x8654	#CJK UNIFIED IDEOGRAPH
+0xF2B0	0x866C	#CJK UNIFIED IDEOGRAPH
+0xF2B1	0x866E	#CJK UNIFIED IDEOGRAPH
+0xF2B2	0x867F	#CJK UNIFIED IDEOGRAPH
+0xF2B3	0x867A	#CJK UNIFIED IDEOGRAPH
+0xF2B4	0x867C	#CJK UNIFIED IDEOGRAPH
+0xF2B5	0x867B	#CJK UNIFIED IDEOGRAPH
+0xF2B6	0x86A8	#CJK UNIFIED IDEOGRAPH
+0xF2B7	0x868D	#CJK UNIFIED IDEOGRAPH
+0xF2B8	0x868B	#CJK UNIFIED IDEOGRAPH
+0xF2B9	0x86AC	#CJK UNIFIED IDEOGRAPH
+0xF2BA	0x869D	#CJK UNIFIED IDEOGRAPH
+0xF2BB	0x86A7	#CJK UNIFIED IDEOGRAPH
+0xF2BC	0x86A3	#CJK UNIFIED IDEOGRAPH
+0xF2BD	0x86AA	#CJK UNIFIED IDEOGRAPH
+0xF2BE	0x8693	#CJK UNIFIED IDEOGRAPH
+0xF2BF	0x86A9	#CJK UNIFIED IDEOGRAPH
+0xF2C0	0x86B6	#CJK UNIFIED IDEOGRAPH
+0xF2C1	0x86C4	#CJK UNIFIED IDEOGRAPH
+0xF2C2	0x86B5	#CJK UNIFIED IDEOGRAPH
+0xF2C3	0x86CE	#CJK UNIFIED IDEOGRAPH
+0xF2C4	0x86B0	#CJK UNIFIED IDEOGRAPH
+0xF2C5	0x86BA	#CJK UNIFIED IDEOGRAPH
+0xF2C6	0x86B1	#CJK UNIFIED IDEOGRAPH
+0xF2C7	0x86AF	#CJK UNIFIED IDEOGRAPH
+0xF2C8	0x86C9	#CJK UNIFIED IDEOGRAPH
+0xF2C9	0x86CF	#CJK UNIFIED IDEOGRAPH
+0xF2CA	0x86B4	#CJK UNIFIED IDEOGRAPH
+0xF2CB	0x86E9	#CJK UNIFIED IDEOGRAPH
+0xF2CC	0x86F1	#CJK UNIFIED IDEOGRAPH
+0xF2CD	0x86F2	#CJK UNIFIED IDEOGRAPH
+0xF2CE	0x86ED	#CJK UNIFIED IDEOGRAPH
+0xF2CF	0x86F3	#CJK UNIFIED IDEOGRAPH
+0xF2D0	0x86D0	#CJK UNIFIED IDEOGRAPH
+0xF2D1	0x8713	#CJK UNIFIED IDEOGRAPH
+0xF2D2	0x86DE	#CJK UNIFIED IDEOGRAPH
+0xF2D3	0x86F4	#CJK UNIFIED IDEOGRAPH
+0xF2D4	0x86DF	#CJK UNIFIED IDEOGRAPH
+0xF2D5	0x86D8	#CJK UNIFIED IDEOGRAPH
+0xF2D6	0x86D1	#CJK UNIFIED IDEOGRAPH
+0xF2D7	0x8703	#CJK UNIFIED IDEOGRAPH
+0xF2D8	0x8707	#CJK UNIFIED IDEOGRAPH
+0xF2D9	0x86F8	#CJK UNIFIED IDEOGRAPH
+0xF2DA	0x8708	#CJK UNIFIED IDEOGRAPH
+0xF2DB	0x870A	#CJK UNIFIED IDEOGRAPH
+0xF2DC	0x870D	#CJK UNIFIED IDEOGRAPH
+0xF2DD	0x8709	#CJK UNIFIED IDEOGRAPH
+0xF2DE	0x8723	#CJK UNIFIED IDEOGRAPH
+0xF2DF	0x873B	#CJK UNIFIED IDEOGRAPH
+0xF2E0	0x871E	#CJK UNIFIED IDEOGRAPH
+0xF2E1	0x8725	#CJK UNIFIED IDEOGRAPH
+0xF2E2	0x872E	#CJK UNIFIED IDEOGRAPH
+0xF2E3	0x871A	#CJK UNIFIED IDEOGRAPH
+0xF2E4	0x873E	#CJK UNIFIED IDEOGRAPH
+0xF2E5	0x8748	#CJK UNIFIED IDEOGRAPH
+0xF2E6	0x8734	#CJK UNIFIED IDEOGRAPH
+0xF2E7	0x8731	#CJK UNIFIED IDEOGRAPH
+0xF2E8	0x8729	#CJK UNIFIED IDEOGRAPH
+0xF2E9	0x8737	#CJK UNIFIED IDEOGRAPH
+0xF2EA	0x873F	#CJK UNIFIED IDEOGRAPH
+0xF2EB	0x8782	#CJK UNIFIED IDEOGRAPH
+0xF2EC	0x8722	#CJK UNIFIED IDEOGRAPH
+0xF2ED	0x877D	#CJK UNIFIED IDEOGRAPH
+0xF2EE	0x877E	#CJK UNIFIED IDEOGRAPH
+0xF2EF	0x877B	#CJK UNIFIED IDEOGRAPH
+0xF2F0	0x8760	#CJK UNIFIED IDEOGRAPH
+0xF2F1	0x8770	#CJK UNIFIED IDEOGRAPH
+0xF2F2	0x874C	#CJK UNIFIED IDEOGRAPH
+0xF2F3	0x876E	#CJK UNIFIED IDEOGRAPH
+0xF2F4	0x878B	#CJK UNIFIED IDEOGRAPH
+0xF2F5	0x8753	#CJK UNIFIED IDEOGRAPH
+0xF2F6	0x8763	#CJK UNIFIED IDEOGRAPH
+0xF2F7	0x877C	#CJK UNIFIED IDEOGRAPH
+0xF2F8	0x8764	#CJK UNIFIED IDEOGRAPH
+0xF2F9	0x8759	#CJK UNIFIED IDEOGRAPH
+0xF2FA	0x8765	#CJK UNIFIED IDEOGRAPH
+0xF2FB	0x8793	#CJK UNIFIED IDEOGRAPH
+0xF2FC	0x87AF	#CJK UNIFIED IDEOGRAPH
+0xF2FD	0x87A8	#CJK UNIFIED IDEOGRAPH
+0xF2FE	0x87D2	#CJK UNIFIED IDEOGRAPH
+0xF340	0x9A5A	#CJK UNIFIED IDEOGRAPH
+0xF341	0x9A5B	#CJK UNIFIED IDEOGRAPH
+0xF342	0x9A5C	#CJK UNIFIED IDEOGRAPH
+0xF343	0x9A5D	#CJK UNIFIED IDEOGRAPH
+0xF344	0x9A5E	#CJK UNIFIED IDEOGRAPH
+0xF345	0x9A5F	#CJK UNIFIED IDEOGRAPH
+0xF346	0x9A60	#CJK UNIFIED IDEOGRAPH
+0xF347	0x9A61	#CJK UNIFIED IDEOGRAPH
+0xF348	0x9A62	#CJK UNIFIED IDEOGRAPH
+0xF349	0x9A63	#CJK UNIFIED IDEOGRAPH
+0xF34A	0x9A64	#CJK UNIFIED IDEOGRAPH
+0xF34B	0x9A65	#CJK UNIFIED IDEOGRAPH
+0xF34C	0x9A66	#CJK UNIFIED IDEOGRAPH
+0xF34D	0x9A67	#CJK UNIFIED IDEOGRAPH
+0xF34E	0x9A68	#CJK UNIFIED IDEOGRAPH
+0xF34F	0x9A69	#CJK UNIFIED IDEOGRAPH
+0xF350	0x9A6A	#CJK UNIFIED IDEOGRAPH
+0xF351	0x9A6B	#CJK UNIFIED IDEOGRAPH
+0xF352	0x9A72	#CJK UNIFIED IDEOGRAPH
+0xF353	0x9A83	#CJK UNIFIED IDEOGRAPH
+0xF354	0x9A89	#CJK UNIFIED IDEOGRAPH
+0xF355	0x9A8D	#CJK UNIFIED IDEOGRAPH
+0xF356	0x9A8E	#CJK UNIFIED IDEOGRAPH
+0xF357	0x9A94	#CJK UNIFIED IDEOGRAPH
+0xF358	0x9A95	#CJK UNIFIED IDEOGRAPH
+0xF359	0x9A99	#CJK UNIFIED IDEOGRAPH
+0xF35A	0x9AA6	#CJK UNIFIED IDEOGRAPH
+0xF35B	0x9AA9	#CJK UNIFIED IDEOGRAPH
+0xF35C	0x9AAA	#CJK UNIFIED IDEOGRAPH
+0xF35D	0x9AAB	#CJK UNIFIED IDEOGRAPH
+0xF35E	0x9AAC	#CJK UNIFIED IDEOGRAPH
+0xF35F	0x9AAD	#CJK UNIFIED IDEOGRAPH
+0xF360	0x9AAE	#CJK UNIFIED IDEOGRAPH
+0xF361	0x9AAF	#CJK UNIFIED IDEOGRAPH
+0xF362	0x9AB2	#CJK UNIFIED IDEOGRAPH
+0xF363	0x9AB3	#CJK UNIFIED IDEOGRAPH
+0xF364	0x9AB4	#CJK UNIFIED IDEOGRAPH
+0xF365	0x9AB5	#CJK UNIFIED IDEOGRAPH
+0xF366	0x9AB9	#CJK UNIFIED IDEOGRAPH
+0xF367	0x9ABB	#CJK UNIFIED IDEOGRAPH
+0xF368	0x9ABD	#CJK UNIFIED IDEOGRAPH
+0xF369	0x9ABE	#CJK UNIFIED IDEOGRAPH
+0xF36A	0x9ABF	#CJK UNIFIED IDEOGRAPH
+0xF36B	0x9AC3	#CJK UNIFIED IDEOGRAPH
+0xF36C	0x9AC4	#CJK UNIFIED IDEOGRAPH
+0xF36D	0x9AC6	#CJK UNIFIED IDEOGRAPH
+0xF36E	0x9AC7	#CJK UNIFIED IDEOGRAPH
+0xF36F	0x9AC8	#CJK UNIFIED IDEOGRAPH
+0xF370	0x9AC9	#CJK UNIFIED IDEOGRAPH
+0xF371	0x9ACA	#CJK UNIFIED IDEOGRAPH
+0xF372	0x9ACD	#CJK UNIFIED IDEOGRAPH
+0xF373	0x9ACE	#CJK UNIFIED IDEOGRAPH
+0xF374	0x9ACF	#CJK UNIFIED IDEOGRAPH
+0xF375	0x9AD0	#CJK UNIFIED IDEOGRAPH
+0xF376	0x9AD2	#CJK UNIFIED IDEOGRAPH
+0xF377	0x9AD4	#CJK UNIFIED IDEOGRAPH
+0xF378	0x9AD5	#CJK UNIFIED IDEOGRAPH
+0xF379	0x9AD6	#CJK UNIFIED IDEOGRAPH
+0xF37A	0x9AD7	#CJK UNIFIED IDEOGRAPH
+0xF37B	0x9AD9	#CJK UNIFIED IDEOGRAPH
+0xF37C	0x9ADA	#CJK UNIFIED IDEOGRAPH
+0xF37D	0x9ADB	#CJK UNIFIED IDEOGRAPH
+0xF37E	0x9ADC	#CJK UNIFIED IDEOGRAPH
+0xF380	0x9ADD	#CJK UNIFIED IDEOGRAPH
+0xF381	0x9ADE	#CJK UNIFIED IDEOGRAPH
+0xF382	0x9AE0	#CJK UNIFIED IDEOGRAPH
+0xF383	0x9AE2	#CJK UNIFIED IDEOGRAPH
+0xF384	0x9AE3	#CJK UNIFIED IDEOGRAPH
+0xF385	0x9AE4	#CJK UNIFIED IDEOGRAPH
+0xF386	0x9AE5	#CJK UNIFIED IDEOGRAPH
+0xF387	0x9AE7	#CJK UNIFIED IDEOGRAPH
+0xF388	0x9AE8	#CJK UNIFIED IDEOGRAPH
+0xF389	0x9AE9	#CJK UNIFIED IDEOGRAPH
+0xF38A	0x9AEA	#CJK UNIFIED IDEOGRAPH
+0xF38B	0x9AEC	#CJK UNIFIED IDEOGRAPH
+0xF38C	0x9AEE	#CJK UNIFIED IDEOGRAPH
+0xF38D	0x9AF0	#CJK UNIFIED IDEOGRAPH
+0xF38E	0x9AF1	#CJK UNIFIED IDEOGRAPH
+0xF38F	0x9AF2	#CJK UNIFIED IDEOGRAPH
+0xF390	0x9AF3	#CJK UNIFIED IDEOGRAPH
+0xF391	0x9AF4	#CJK UNIFIED IDEOGRAPH
+0xF392	0x9AF5	#CJK UNIFIED IDEOGRAPH
+0xF393	0x9AF6	#CJK UNIFIED IDEOGRAPH
+0xF394	0x9AF7	#CJK UNIFIED IDEOGRAPH
+0xF395	0x9AF8	#CJK UNIFIED IDEOGRAPH
+0xF396	0x9AFA	#CJK UNIFIED IDEOGRAPH
+0xF397	0x9AFC	#CJK UNIFIED IDEOGRAPH
+0xF398	0x9AFD	#CJK UNIFIED IDEOGRAPH
+0xF399	0x9AFE	#CJK UNIFIED IDEOGRAPH
+0xF39A	0x9AFF	#CJK UNIFIED IDEOGRAPH
+0xF39B	0x9B00	#CJK UNIFIED IDEOGRAPH
+0xF39C	0x9B01	#CJK UNIFIED IDEOGRAPH
+0xF39D	0x9B02	#CJK UNIFIED IDEOGRAPH
+0xF39E	0x9B04	#CJK UNIFIED IDEOGRAPH
+0xF39F	0x9B05	#CJK UNIFIED IDEOGRAPH
+0xF3A0	0x9B06	#CJK UNIFIED IDEOGRAPH
+0xF3A1	0x87C6	#CJK UNIFIED IDEOGRAPH
+0xF3A2	0x8788	#CJK UNIFIED IDEOGRAPH
+0xF3A3	0x8785	#CJK UNIFIED IDEOGRAPH
+0xF3A4	0x87AD	#CJK UNIFIED IDEOGRAPH
+0xF3A5	0x8797	#CJK UNIFIED IDEOGRAPH
+0xF3A6	0x8783	#CJK UNIFIED IDEOGRAPH
+0xF3A7	0x87AB	#CJK UNIFIED IDEOGRAPH
+0xF3A8	0x87E5	#CJK UNIFIED IDEOGRAPH
+0xF3A9	0x87AC	#CJK UNIFIED IDEOGRAPH
+0xF3AA	0x87B5	#CJK UNIFIED IDEOGRAPH
+0xF3AB	0x87B3	#CJK UNIFIED IDEOGRAPH
+0xF3AC	0x87CB	#CJK UNIFIED IDEOGRAPH
+0xF3AD	0x87D3	#CJK UNIFIED IDEOGRAPH
+0xF3AE	0x87BD	#CJK UNIFIED IDEOGRAPH
+0xF3AF	0x87D1	#CJK UNIFIED IDEOGRAPH
+0xF3B0	0x87C0	#CJK UNIFIED IDEOGRAPH
+0xF3B1	0x87CA	#CJK UNIFIED IDEOGRAPH
+0xF3B2	0x87DB	#CJK UNIFIED IDEOGRAPH
+0xF3B3	0x87EA	#CJK UNIFIED IDEOGRAPH
+0xF3B4	0x87E0	#CJK UNIFIED IDEOGRAPH
+0xF3B5	0x87EE	#CJK UNIFIED IDEOGRAPH
+0xF3B6	0x8816	#CJK UNIFIED IDEOGRAPH
+0xF3B7	0x8813	#CJK UNIFIED IDEOGRAPH
+0xF3B8	0x87FE	#CJK UNIFIED IDEOGRAPH
+0xF3B9	0x880A	#CJK UNIFIED IDEOGRAPH
+0xF3BA	0x881B	#CJK UNIFIED IDEOGRAPH
+0xF3BB	0x8821	#CJK UNIFIED IDEOGRAPH
+0xF3BC	0x8839	#CJK UNIFIED IDEOGRAPH
+0xF3BD	0x883C	#CJK UNIFIED IDEOGRAPH
+0xF3BE	0x7F36	#CJK UNIFIED IDEOGRAPH
+0xF3BF	0x7F42	#CJK UNIFIED IDEOGRAPH
+0xF3C0	0x7F44	#CJK UNIFIED IDEOGRAPH
+0xF3C1	0x7F45	#CJK UNIFIED IDEOGRAPH
+0xF3C2	0x8210	#CJK UNIFIED IDEOGRAPH
+0xF3C3	0x7AFA	#CJK UNIFIED IDEOGRAPH
+0xF3C4	0x7AFD	#CJK UNIFIED IDEOGRAPH
+0xF3C5	0x7B08	#CJK UNIFIED IDEOGRAPH
+0xF3C6	0x7B03	#CJK UNIFIED IDEOGRAPH
+0xF3C7	0x7B04	#CJK UNIFIED IDEOGRAPH
+0xF3C8	0x7B15	#CJK UNIFIED IDEOGRAPH
+0xF3C9	0x7B0A	#CJK UNIFIED IDEOGRAPH
+0xF3CA	0x7B2B	#CJK UNIFIED IDEOGRAPH
+0xF3CB	0x7B0F	#CJK UNIFIED IDEOGRAPH
+0xF3CC	0x7B47	#CJK UNIFIED IDEOGRAPH
+0xF3CD	0x7B38	#CJK UNIFIED IDEOGRAPH
+0xF3CE	0x7B2A	#CJK UNIFIED IDEOGRAPH
+0xF3CF	0x7B19	#CJK UNIFIED IDEOGRAPH
+0xF3D0	0x7B2E	#CJK UNIFIED IDEOGRAPH
+0xF3D1	0x7B31	#CJK UNIFIED IDEOGRAPH
+0xF3D2	0x7B20	#CJK UNIFIED IDEOGRAPH
+0xF3D3	0x7B25	#CJK UNIFIED IDEOGRAPH
+0xF3D4	0x7B24	#CJK UNIFIED IDEOGRAPH
+0xF3D5	0x7B33	#CJK UNIFIED IDEOGRAPH
+0xF3D6	0x7B3E	#CJK UNIFIED IDEOGRAPH
+0xF3D7	0x7B1E	#CJK UNIFIED IDEOGRAPH
+0xF3D8	0x7B58	#CJK UNIFIED IDEOGRAPH
+0xF3D9	0x7B5A	#CJK UNIFIED IDEOGRAPH
+0xF3DA	0x7B45	#CJK UNIFIED IDEOGRAPH
+0xF3DB	0x7B75	#CJK UNIFIED IDEOGRAPH
+0xF3DC	0x7B4C	#CJK UNIFIED IDEOGRAPH
+0xF3DD	0x7B5D	#CJK UNIFIED IDEOGRAPH
+0xF3DE	0x7B60	#CJK UNIFIED IDEOGRAPH
+0xF3DF	0x7B6E	#CJK UNIFIED IDEOGRAPH
+0xF3E0	0x7B7B	#CJK UNIFIED IDEOGRAPH
+0xF3E1	0x7B62	#CJK UNIFIED IDEOGRAPH
+0xF3E2	0x7B72	#CJK UNIFIED IDEOGRAPH
+0xF3E3	0x7B71	#CJK UNIFIED IDEOGRAPH
+0xF3E4	0x7B90	#CJK UNIFIED IDEOGRAPH
+0xF3E5	0x7BA6	#CJK UNIFIED IDEOGRAPH
+0xF3E6	0x7BA7	#CJK UNIFIED IDEOGRAPH
+0xF3E7	0x7BB8	#CJK UNIFIED IDEOGRAPH
+0xF3E8	0x7BAC	#CJK UNIFIED IDEOGRAPH
+0xF3E9	0x7B9D	#CJK UNIFIED IDEOGRAPH
+0xF3EA	0x7BA8	#CJK UNIFIED IDEOGRAPH
+0xF3EB	0x7B85	#CJK UNIFIED IDEOGRAPH
+0xF3EC	0x7BAA	#CJK UNIFIED IDEOGRAPH
+0xF3ED	0x7B9C	#CJK UNIFIED IDEOGRAPH
+0xF3EE	0x7BA2	#CJK UNIFIED IDEOGRAPH
+0xF3EF	0x7BAB	#CJK UNIFIED IDEOGRAPH
+0xF3F0	0x7BB4	#CJK UNIFIED IDEOGRAPH
+0xF3F1	0x7BD1	#CJK UNIFIED IDEOGRAPH
+0xF3F2	0x7BC1	#CJK UNIFIED IDEOGRAPH
+0xF3F3	0x7BCC	#CJK UNIFIED IDEOGRAPH
+0xF3F4	0x7BDD	#CJK UNIFIED IDEOGRAPH
+0xF3F5	0x7BDA	#CJK UNIFIED IDEOGRAPH
+0xF3F6	0x7BE5	#CJK UNIFIED IDEOGRAPH
+0xF3F7	0x7BE6	#CJK UNIFIED IDEOGRAPH
+0xF3F8	0x7BEA	#CJK UNIFIED IDEOGRAPH
+0xF3F9	0x7C0C	#CJK UNIFIED IDEOGRAPH
+0xF3FA	0x7BFE	#CJK UNIFIED IDEOGRAPH
+0xF3FB	0x7BFC	#CJK UNIFIED IDEOGRAPH
+0xF3FC	0x7C0F	#CJK UNIFIED IDEOGRAPH
+0xF3FD	0x7C16	#CJK UNIFIED IDEOGRAPH
+0xF3FE	0x7C0B	#CJK UNIFIED IDEOGRAPH
+0xF440	0x9B07	#CJK UNIFIED IDEOGRAPH
+0xF441	0x9B09	#CJK UNIFIED IDEOGRAPH
+0xF442	0x9B0A	#CJK UNIFIED IDEOGRAPH
+0xF443	0x9B0B	#CJK UNIFIED IDEOGRAPH
+0xF444	0x9B0C	#CJK UNIFIED IDEOGRAPH
+0xF445	0x9B0D	#CJK UNIFIED IDEOGRAPH
+0xF446	0x9B0E	#CJK UNIFIED IDEOGRAPH
+0xF447	0x9B10	#CJK UNIFIED IDEOGRAPH
+0xF448	0x9B11	#CJK UNIFIED IDEOGRAPH
+0xF449	0x9B12	#CJK UNIFIED IDEOGRAPH
+0xF44A	0x9B14	#CJK UNIFIED IDEOGRAPH
+0xF44B	0x9B15	#CJK UNIFIED IDEOGRAPH
+0xF44C	0x9B16	#CJK UNIFIED IDEOGRAPH
+0xF44D	0x9B17	#CJK UNIFIED IDEOGRAPH
+0xF44E	0x9B18	#CJK UNIFIED IDEOGRAPH
+0xF44F	0x9B19	#CJK UNIFIED IDEOGRAPH
+0xF450	0x9B1A	#CJK UNIFIED IDEOGRAPH
+0xF451	0x9B1B	#CJK UNIFIED IDEOGRAPH
+0xF452	0x9B1C	#CJK UNIFIED IDEOGRAPH
+0xF453	0x9B1D	#CJK UNIFIED IDEOGRAPH
+0xF454	0x9B1E	#CJK UNIFIED IDEOGRAPH
+0xF455	0x9B20	#CJK UNIFIED IDEOGRAPH
+0xF456	0x9B21	#CJK UNIFIED IDEOGRAPH
+0xF457	0x9B22	#CJK UNIFIED IDEOGRAPH
+0xF458	0x9B24	#CJK UNIFIED IDEOGRAPH
+0xF459	0x9B25	#CJK UNIFIED IDEOGRAPH
+0xF45A	0x9B26	#CJK UNIFIED IDEOGRAPH
+0xF45B	0x9B27	#CJK UNIFIED IDEOGRAPH
+0xF45C	0x9B28	#CJK UNIFIED IDEOGRAPH
+0xF45D	0x9B29	#CJK UNIFIED IDEOGRAPH
+0xF45E	0x9B2A	#CJK UNIFIED IDEOGRAPH
+0xF45F	0x9B2B	#CJK UNIFIED IDEOGRAPH
+0xF460	0x9B2C	#CJK UNIFIED IDEOGRAPH
+0xF461	0x9B2D	#CJK UNIFIED IDEOGRAPH
+0xF462	0x9B2E	#CJK UNIFIED IDEOGRAPH
+0xF463	0x9B30	#CJK UNIFIED IDEOGRAPH
+0xF464	0x9B31	#CJK UNIFIED IDEOGRAPH
+0xF465	0x9B33	#CJK UNIFIED IDEOGRAPH
+0xF466	0x9B34	#CJK UNIFIED IDEOGRAPH
+0xF467	0x9B35	#CJK UNIFIED IDEOGRAPH
+0xF468	0x9B36	#CJK UNIFIED IDEOGRAPH
+0xF469	0x9B37	#CJK UNIFIED IDEOGRAPH
+0xF46A	0x9B38	#CJK UNIFIED IDEOGRAPH
+0xF46B	0x9B39	#CJK UNIFIED IDEOGRAPH
+0xF46C	0x9B3A	#CJK UNIFIED IDEOGRAPH
+0xF46D	0x9B3D	#CJK UNIFIED IDEOGRAPH
+0xF46E	0x9B3E	#CJK UNIFIED IDEOGRAPH
+0xF46F	0x9B3F	#CJK UNIFIED IDEOGRAPH
+0xF470	0x9B40	#CJK UNIFIED IDEOGRAPH
+0xF471	0x9B46	#CJK UNIFIED IDEOGRAPH
+0xF472	0x9B4A	#CJK UNIFIED IDEOGRAPH
+0xF473	0x9B4B	#CJK UNIFIED IDEOGRAPH
+0xF474	0x9B4C	#CJK UNIFIED IDEOGRAPH
+0xF475	0x9B4E	#CJK UNIFIED IDEOGRAPH
+0xF476	0x9B50	#CJK UNIFIED IDEOGRAPH
+0xF477	0x9B52	#CJK UNIFIED IDEOGRAPH
+0xF478	0x9B53	#CJK UNIFIED IDEOGRAPH
+0xF479	0x9B55	#CJK UNIFIED IDEOGRAPH
+0xF47A	0x9B56	#CJK UNIFIED IDEOGRAPH
+0xF47B	0x9B57	#CJK UNIFIED IDEOGRAPH
+0xF47C	0x9B58	#CJK UNIFIED IDEOGRAPH
+0xF47D	0x9B59	#CJK UNIFIED IDEOGRAPH
+0xF47E	0x9B5A	#CJK UNIFIED IDEOGRAPH
+0xF480	0x9B5B	#CJK UNIFIED IDEOGRAPH
+0xF481	0x9B5C	#CJK UNIFIED IDEOGRAPH
+0xF482	0x9B5D	#CJK UNIFIED IDEOGRAPH
+0xF483	0x9B5E	#CJK UNIFIED IDEOGRAPH
+0xF484	0x9B5F	#CJK UNIFIED IDEOGRAPH
+0xF485	0x9B60	#CJK UNIFIED IDEOGRAPH
+0xF486	0x9B61	#CJK UNIFIED IDEOGRAPH
+0xF487	0x9B62	#CJK UNIFIED IDEOGRAPH
+0xF488	0x9B63	#CJK UNIFIED IDEOGRAPH
+0xF489	0x9B64	#CJK UNIFIED IDEOGRAPH
+0xF48A	0x9B65	#CJK UNIFIED IDEOGRAPH
+0xF48B	0x9B66	#CJK UNIFIED IDEOGRAPH
+0xF48C	0x9B67	#CJK UNIFIED IDEOGRAPH
+0xF48D	0x9B68	#CJK UNIFIED IDEOGRAPH
+0xF48E	0x9B69	#CJK UNIFIED IDEOGRAPH
+0xF48F	0x9B6A	#CJK UNIFIED IDEOGRAPH
+0xF490	0x9B6B	#CJK UNIFIED IDEOGRAPH
+0xF491	0x9B6C	#CJK UNIFIED IDEOGRAPH
+0xF492	0x9B6D	#CJK UNIFIED IDEOGRAPH
+0xF493	0x9B6E	#CJK UNIFIED IDEOGRAPH
+0xF494	0x9B6F	#CJK UNIFIED IDEOGRAPH
+0xF495	0x9B70	#CJK UNIFIED IDEOGRAPH
+0xF496	0x9B71	#CJK UNIFIED IDEOGRAPH
+0xF497	0x9B72	#CJK UNIFIED IDEOGRAPH
+0xF498	0x9B73	#CJK UNIFIED IDEOGRAPH
+0xF499	0x9B74	#CJK UNIFIED IDEOGRAPH
+0xF49A	0x9B75	#CJK UNIFIED IDEOGRAPH
+0xF49B	0x9B76	#CJK UNIFIED IDEOGRAPH
+0xF49C	0x9B77	#CJK UNIFIED IDEOGRAPH
+0xF49D	0x9B78	#CJK UNIFIED IDEOGRAPH
+0xF49E	0x9B79	#CJK UNIFIED IDEOGRAPH
+0xF49F	0x9B7A	#CJK UNIFIED IDEOGRAPH
+0xF4A0	0x9B7B	#CJK UNIFIED IDEOGRAPH
+0xF4A1	0x7C1F	#CJK UNIFIED IDEOGRAPH
+0xF4A2	0x7C2A	#CJK UNIFIED IDEOGRAPH
+0xF4A3	0x7C26	#CJK UNIFIED IDEOGRAPH
+0xF4A4	0x7C38	#CJK UNIFIED IDEOGRAPH
+0xF4A5	0x7C41	#CJK UNIFIED IDEOGRAPH
+0xF4A6	0x7C40	#CJK UNIFIED IDEOGRAPH
+0xF4A7	0x81FE	#CJK UNIFIED IDEOGRAPH
+0xF4A8	0x8201	#CJK UNIFIED IDEOGRAPH
+0xF4A9	0x8202	#CJK UNIFIED IDEOGRAPH
+0xF4AA	0x8204	#CJK UNIFIED IDEOGRAPH
+0xF4AB	0x81EC	#CJK UNIFIED IDEOGRAPH
+0xF4AC	0x8844	#CJK UNIFIED IDEOGRAPH
+0xF4AD	0x8221	#CJK UNIFIED IDEOGRAPH
+0xF4AE	0x8222	#CJK UNIFIED IDEOGRAPH
+0xF4AF	0x8223	#CJK UNIFIED IDEOGRAPH
+0xF4B0	0x822D	#CJK UNIFIED IDEOGRAPH
+0xF4B1	0x822F	#CJK UNIFIED IDEOGRAPH
+0xF4B2	0x8228	#CJK UNIFIED IDEOGRAPH
+0xF4B3	0x822B	#CJK UNIFIED IDEOGRAPH
+0xF4B4	0x8238	#CJK UNIFIED IDEOGRAPH
+0xF4B5	0x823B	#CJK UNIFIED IDEOGRAPH
+0xF4B6	0x8233	#CJK UNIFIED IDEOGRAPH
+0xF4B7	0x8234	#CJK UNIFIED IDEOGRAPH
+0xF4B8	0x823E	#CJK UNIFIED IDEOGRAPH
+0xF4B9	0x8244	#CJK UNIFIED IDEOGRAPH
+0xF4BA	0x8249	#CJK UNIFIED IDEOGRAPH
+0xF4BB	0x824B	#CJK UNIFIED IDEOGRAPH
+0xF4BC	0x824F	#CJK UNIFIED IDEOGRAPH
+0xF4BD	0x825A	#CJK UNIFIED IDEOGRAPH
+0xF4BE	0x825F	#CJK UNIFIED IDEOGRAPH
+0xF4BF	0x8268	#CJK UNIFIED IDEOGRAPH
+0xF4C0	0x887E	#CJK UNIFIED IDEOGRAPH
+0xF4C1	0x8885	#CJK UNIFIED IDEOGRAPH
+0xF4C2	0x8888	#CJK UNIFIED IDEOGRAPH
+0xF4C3	0x88D8	#CJK UNIFIED IDEOGRAPH
+0xF4C4	0x88DF	#CJK UNIFIED IDEOGRAPH
+0xF4C5	0x895E	#CJK UNIFIED IDEOGRAPH
+0xF4C6	0x7F9D	#CJK UNIFIED IDEOGRAPH
+0xF4C7	0x7F9F	#CJK UNIFIED IDEOGRAPH
+0xF4C8	0x7FA7	#CJK UNIFIED IDEOGRAPH
+0xF4C9	0x7FAF	#CJK UNIFIED IDEOGRAPH
+0xF4CA	0x7FB0	#CJK UNIFIED IDEOGRAPH
+0xF4CB	0x7FB2	#CJK UNIFIED IDEOGRAPH
+0xF4CC	0x7C7C	#CJK UNIFIED IDEOGRAPH
+0xF4CD	0x6549	#CJK UNIFIED IDEOGRAPH
+0xF4CE	0x7C91	#CJK UNIFIED IDEOGRAPH
+0xF4CF	0x7C9D	#CJK UNIFIED IDEOGRAPH
+0xF4D0	0x7C9C	#CJK UNIFIED IDEOGRAPH
+0xF4D1	0x7C9E	#CJK UNIFIED IDEOGRAPH
+0xF4D2	0x7CA2	#CJK UNIFIED IDEOGRAPH
+0xF4D3	0x7CB2	#CJK UNIFIED IDEOGRAPH
+0xF4D4	0x7CBC	#CJK UNIFIED IDEOGRAPH
+0xF4D5	0x7CBD	#CJK UNIFIED IDEOGRAPH
+0xF4D6	0x7CC1	#CJK UNIFIED IDEOGRAPH
+0xF4D7	0x7CC7	#CJK UNIFIED IDEOGRAPH
+0xF4D8	0x7CCC	#CJK UNIFIED IDEOGRAPH
+0xF4D9	0x7CCD	#CJK UNIFIED IDEOGRAPH
+0xF4DA	0x7CC8	#CJK UNIFIED IDEOGRAPH
+0xF4DB	0x7CC5	#CJK UNIFIED IDEOGRAPH
+0xF4DC	0x7CD7	#CJK UNIFIED IDEOGRAPH
+0xF4DD	0x7CE8	#CJK UNIFIED IDEOGRAPH
+0xF4DE	0x826E	#CJK UNIFIED IDEOGRAPH
+0xF4DF	0x66A8	#CJK UNIFIED IDEOGRAPH
+0xF4E0	0x7FBF	#CJK UNIFIED IDEOGRAPH
+0xF4E1	0x7FCE	#CJK UNIFIED IDEOGRAPH
+0xF4E2	0x7FD5	#CJK UNIFIED IDEOGRAPH
+0xF4E3	0x7FE5	#CJK UNIFIED IDEOGRAPH
+0xF4E4	0x7FE1	#CJK UNIFIED IDEOGRAPH
+0xF4E5	0x7FE6	#CJK UNIFIED IDEOGRAPH
+0xF4E6	0x7FE9	#CJK UNIFIED IDEOGRAPH
+0xF4E7	0x7FEE	#CJK UNIFIED IDEOGRAPH
+0xF4E8	0x7FF3	#CJK UNIFIED IDEOGRAPH
+0xF4E9	0x7CF8	#CJK UNIFIED IDEOGRAPH
+0xF4EA	0x7D77	#CJK UNIFIED IDEOGRAPH
+0xF4EB	0x7DA6	#CJK UNIFIED IDEOGRAPH
+0xF4EC	0x7DAE	#CJK UNIFIED IDEOGRAPH
+0xF4ED	0x7E47	#CJK UNIFIED IDEOGRAPH
+0xF4EE	0x7E9B	#CJK UNIFIED IDEOGRAPH
+0xF4EF	0x9EB8	#CJK UNIFIED IDEOGRAPH
+0xF4F0	0x9EB4	#CJK UNIFIED IDEOGRAPH
+0xF4F1	0x8D73	#CJK UNIFIED IDEOGRAPH
+0xF4F2	0x8D84	#CJK UNIFIED IDEOGRAPH
+0xF4F3	0x8D94	#CJK UNIFIED IDEOGRAPH
+0xF4F4	0x8D91	#CJK UNIFIED IDEOGRAPH
+0xF4F5	0x8DB1	#CJK UNIFIED IDEOGRAPH
+0xF4F6	0x8D67	#CJK UNIFIED IDEOGRAPH
+0xF4F7	0x8D6D	#CJK UNIFIED IDEOGRAPH
+0xF4F8	0x8C47	#CJK UNIFIED IDEOGRAPH
+0xF4F9	0x8C49	#CJK UNIFIED IDEOGRAPH
+0xF4FA	0x914A	#CJK UNIFIED IDEOGRAPH
+0xF4FB	0x9150	#CJK UNIFIED IDEOGRAPH
+0xF4FC	0x914E	#CJK UNIFIED IDEOGRAPH
+0xF4FD	0x914F	#CJK UNIFIED IDEOGRAPH
+0xF4FE	0x9164	#CJK UNIFIED IDEOGRAPH
+0xF540	0x9B7C	#CJK UNIFIED IDEOGRAPH
+0xF541	0x9B7D	#CJK UNIFIED IDEOGRAPH
+0xF542	0x9B7E	#CJK UNIFIED IDEOGRAPH
+0xF543	0x9B7F	#CJK UNIFIED IDEOGRAPH
+0xF544	0x9B80	#CJK UNIFIED IDEOGRAPH
+0xF545	0x9B81	#CJK UNIFIED IDEOGRAPH
+0xF546	0x9B82	#CJK UNIFIED IDEOGRAPH
+0xF547	0x9B83	#CJK UNIFIED IDEOGRAPH
+0xF548	0x9B84	#CJK UNIFIED IDEOGRAPH
+0xF549	0x9B85	#CJK UNIFIED IDEOGRAPH
+0xF54A	0x9B86	#CJK UNIFIED IDEOGRAPH
+0xF54B	0x9B87	#CJK UNIFIED IDEOGRAPH
+0xF54C	0x9B88	#CJK UNIFIED IDEOGRAPH
+0xF54D	0x9B89	#CJK UNIFIED IDEOGRAPH
+0xF54E	0x9B8A	#CJK UNIFIED IDEOGRAPH
+0xF54F	0x9B8B	#CJK UNIFIED IDEOGRAPH
+0xF550	0x9B8C	#CJK UNIFIED IDEOGRAPH
+0xF551	0x9B8D	#CJK UNIFIED IDEOGRAPH
+0xF552	0x9B8E	#CJK UNIFIED IDEOGRAPH
+0xF553	0x9B8F	#CJK UNIFIED IDEOGRAPH
+0xF554	0x9B90	#CJK UNIFIED IDEOGRAPH
+0xF555	0x9B91	#CJK UNIFIED IDEOGRAPH
+0xF556	0x9B92	#CJK UNIFIED IDEOGRAPH
+0xF557	0x9B93	#CJK UNIFIED IDEOGRAPH
+0xF558	0x9B94	#CJK UNIFIED IDEOGRAPH
+0xF559	0x9B95	#CJK UNIFIED IDEOGRAPH
+0xF55A	0x9B96	#CJK UNIFIED IDEOGRAPH
+0xF55B	0x9B97	#CJK UNIFIED IDEOGRAPH
+0xF55C	0x9B98	#CJK UNIFIED IDEOGRAPH
+0xF55D	0x9B99	#CJK UNIFIED IDEOGRAPH
+0xF55E	0x9B9A	#CJK UNIFIED IDEOGRAPH
+0xF55F	0x9B9B	#CJK UNIFIED IDEOGRAPH
+0xF560	0x9B9C	#CJK UNIFIED IDEOGRAPH
+0xF561	0x9B9D	#CJK UNIFIED IDEOGRAPH
+0xF562	0x9B9E	#CJK UNIFIED IDEOGRAPH
+0xF563	0x9B9F	#CJK UNIFIED IDEOGRAPH
+0xF564	0x9BA0	#CJK UNIFIED IDEOGRAPH
+0xF565	0x9BA1	#CJK UNIFIED IDEOGRAPH
+0xF566	0x9BA2	#CJK UNIFIED IDEOGRAPH
+0xF567	0x9BA3	#CJK UNIFIED IDEOGRAPH
+0xF568	0x9BA4	#CJK UNIFIED IDEOGRAPH
+0xF569	0x9BA5	#CJK UNIFIED IDEOGRAPH
+0xF56A	0x9BA6	#CJK UNIFIED IDEOGRAPH
+0xF56B	0x9BA7	#CJK UNIFIED IDEOGRAPH
+0xF56C	0x9BA8	#CJK UNIFIED IDEOGRAPH
+0xF56D	0x9BA9	#CJK UNIFIED IDEOGRAPH
+0xF56E	0x9BAA	#CJK UNIFIED IDEOGRAPH
+0xF56F	0x9BAB	#CJK UNIFIED IDEOGRAPH
+0xF570	0x9BAC	#CJK UNIFIED IDEOGRAPH
+0xF571	0x9BAD	#CJK UNIFIED IDEOGRAPH
+0xF572	0x9BAE	#CJK UNIFIED IDEOGRAPH
+0xF573	0x9BAF	#CJK UNIFIED IDEOGRAPH
+0xF574	0x9BB0	#CJK UNIFIED IDEOGRAPH
+0xF575	0x9BB1	#CJK UNIFIED IDEOGRAPH
+0xF576	0x9BB2	#CJK UNIFIED IDEOGRAPH
+0xF577	0x9BB3	#CJK UNIFIED IDEOGRAPH
+0xF578	0x9BB4	#CJK UNIFIED IDEOGRAPH
+0xF579	0x9BB5	#CJK UNIFIED IDEOGRAPH
+0xF57A	0x9BB6	#CJK UNIFIED IDEOGRAPH
+0xF57B	0x9BB7	#CJK UNIFIED IDEOGRAPH
+0xF57C	0x9BB8	#CJK UNIFIED IDEOGRAPH
+0xF57D	0x9BB9	#CJK UNIFIED IDEOGRAPH
+0xF57E	0x9BBA	#CJK UNIFIED IDEOGRAPH
+0xF580	0x9BBB	#CJK UNIFIED IDEOGRAPH
+0xF581	0x9BBC	#CJK UNIFIED IDEOGRAPH
+0xF582	0x9BBD	#CJK UNIFIED IDEOGRAPH
+0xF583	0x9BBE	#CJK UNIFIED IDEOGRAPH
+0xF584	0x9BBF	#CJK UNIFIED IDEOGRAPH
+0xF585	0x9BC0	#CJK UNIFIED IDEOGRAPH
+0xF586	0x9BC1	#CJK UNIFIED IDEOGRAPH
+0xF587	0x9BC2	#CJK UNIFIED IDEOGRAPH
+0xF588	0x9BC3	#CJK UNIFIED IDEOGRAPH
+0xF589	0x9BC4	#CJK UNIFIED IDEOGRAPH
+0xF58A	0x9BC5	#CJK UNIFIED IDEOGRAPH
+0xF58B	0x9BC6	#CJK UNIFIED IDEOGRAPH
+0xF58C	0x9BC7	#CJK UNIFIED IDEOGRAPH
+0xF58D	0x9BC8	#CJK UNIFIED IDEOGRAPH
+0xF58E	0x9BC9	#CJK UNIFIED IDEOGRAPH
+0xF58F	0x9BCA	#CJK UNIFIED IDEOGRAPH
+0xF590	0x9BCB	#CJK UNIFIED IDEOGRAPH
+0xF591	0x9BCC	#CJK UNIFIED IDEOGRAPH
+0xF592	0x9BCD	#CJK UNIFIED IDEOGRAPH
+0xF593	0x9BCE	#CJK UNIFIED IDEOGRAPH
+0xF594	0x9BCF	#CJK UNIFIED IDEOGRAPH
+0xF595	0x9BD0	#CJK UNIFIED IDEOGRAPH
+0xF596	0x9BD1	#CJK UNIFIED IDEOGRAPH
+0xF597	0x9BD2	#CJK UNIFIED IDEOGRAPH
+0xF598	0x9BD3	#CJK UNIFIED IDEOGRAPH
+0xF599	0x9BD4	#CJK UNIFIED IDEOGRAPH
+0xF59A	0x9BD5	#CJK UNIFIED IDEOGRAPH
+0xF59B	0x9BD6	#CJK UNIFIED IDEOGRAPH
+0xF59C	0x9BD7	#CJK UNIFIED IDEOGRAPH
+0xF59D	0x9BD8	#CJK UNIFIED IDEOGRAPH
+0xF59E	0x9BD9	#CJK UNIFIED IDEOGRAPH
+0xF59F	0x9BDA	#CJK UNIFIED IDEOGRAPH
+0xF5A0	0x9BDB	#CJK UNIFIED IDEOGRAPH
+0xF5A1	0x9162	#CJK UNIFIED IDEOGRAPH
+0xF5A2	0x9161	#CJK UNIFIED IDEOGRAPH
+0xF5A3	0x9170	#CJK UNIFIED IDEOGRAPH
+0xF5A4	0x9169	#CJK UNIFIED IDEOGRAPH
+0xF5A5	0x916F	#CJK UNIFIED IDEOGRAPH
+0xF5A6	0x917D	#CJK UNIFIED IDEOGRAPH
+0xF5A7	0x917E	#CJK UNIFIED IDEOGRAPH
+0xF5A8	0x9172	#CJK UNIFIED IDEOGRAPH
+0xF5A9	0x9174	#CJK UNIFIED IDEOGRAPH
+0xF5AA	0x9179	#CJK UNIFIED IDEOGRAPH
+0xF5AB	0x918C	#CJK UNIFIED IDEOGRAPH
+0xF5AC	0x9185	#CJK UNIFIED IDEOGRAPH
+0xF5AD	0x9190	#CJK UNIFIED IDEOGRAPH
+0xF5AE	0x918D	#CJK UNIFIED IDEOGRAPH
+0xF5AF	0x9191	#CJK UNIFIED IDEOGRAPH
+0xF5B0	0x91A2	#CJK UNIFIED IDEOGRAPH
+0xF5B1	0x91A3	#CJK UNIFIED IDEOGRAPH
+0xF5B2	0x91AA	#CJK UNIFIED IDEOGRAPH
+0xF5B3	0x91AD	#CJK UNIFIED IDEOGRAPH
+0xF5B4	0x91AE	#CJK UNIFIED IDEOGRAPH
+0xF5B5	0x91AF	#CJK UNIFIED IDEOGRAPH
+0xF5B6	0x91B5	#CJK UNIFIED IDEOGRAPH
+0xF5B7	0x91B4	#CJK UNIFIED IDEOGRAPH
+0xF5B8	0x91BA	#CJK UNIFIED IDEOGRAPH
+0xF5B9	0x8C55	#CJK UNIFIED IDEOGRAPH
+0xF5BA	0x9E7E	#CJK UNIFIED IDEOGRAPH
+0xF5BB	0x8DB8	#CJK UNIFIED IDEOGRAPH
+0xF5BC	0x8DEB	#CJK UNIFIED IDEOGRAPH
+0xF5BD	0x8E05	#CJK UNIFIED IDEOGRAPH
+0xF5BE	0x8E59	#CJK UNIFIED IDEOGRAPH
+0xF5BF	0x8E69	#CJK UNIFIED IDEOGRAPH
+0xF5C0	0x8DB5	#CJK UNIFIED IDEOGRAPH
+0xF5C1	0x8DBF	#CJK UNIFIED IDEOGRAPH
+0xF5C2	0x8DBC	#CJK UNIFIED IDEOGRAPH
+0xF5C3	0x8DBA	#CJK UNIFIED IDEOGRAPH
+0xF5C4	0x8DC4	#CJK UNIFIED IDEOGRAPH
+0xF5C5	0x8DD6	#CJK UNIFIED IDEOGRAPH
+0xF5C6	0x8DD7	#CJK UNIFIED IDEOGRAPH
+0xF5C7	0x8DDA	#CJK UNIFIED IDEOGRAPH
+0xF5C8	0x8DDE	#CJK UNIFIED IDEOGRAPH
+0xF5C9	0x8DCE	#CJK UNIFIED IDEOGRAPH
+0xF5CA	0x8DCF	#CJK UNIFIED IDEOGRAPH
+0xF5CB	0x8DDB	#CJK UNIFIED IDEOGRAPH
+0xF5CC	0x8DC6	#CJK UNIFIED IDEOGRAPH
+0xF5CD	0x8DEC	#CJK UNIFIED IDEOGRAPH
+0xF5CE	0x8DF7	#CJK UNIFIED IDEOGRAPH
+0xF5CF	0x8DF8	#CJK UNIFIED IDEOGRAPH
+0xF5D0	0x8DE3	#CJK UNIFIED IDEOGRAPH
+0xF5D1	0x8DF9	#CJK UNIFIED IDEOGRAPH
+0xF5D2	0x8DFB	#CJK UNIFIED IDEOGRAPH
+0xF5D3	0x8DE4	#CJK UNIFIED IDEOGRAPH
+0xF5D4	0x8E09	#CJK UNIFIED IDEOGRAPH
+0xF5D5	0x8DFD	#CJK UNIFIED IDEOGRAPH
+0xF5D6	0x8E14	#CJK UNIFIED IDEOGRAPH
+0xF5D7	0x8E1D	#CJK UNIFIED IDEOGRAPH
+0xF5D8	0x8E1F	#CJK UNIFIED IDEOGRAPH
+0xF5D9	0x8E2C	#CJK UNIFIED IDEOGRAPH
+0xF5DA	0x8E2E	#CJK UNIFIED IDEOGRAPH
+0xF5DB	0x8E23	#CJK UNIFIED IDEOGRAPH
+0xF5DC	0x8E2F	#CJK UNIFIED IDEOGRAPH
+0xF5DD	0x8E3A	#CJK UNIFIED IDEOGRAPH
+0xF5DE	0x8E40	#CJK UNIFIED IDEOGRAPH
+0xF5DF	0x8E39	#CJK UNIFIED IDEOGRAPH
+0xF5E0	0x8E35	#CJK UNIFIED IDEOGRAPH
+0xF5E1	0x8E3D	#CJK UNIFIED IDEOGRAPH
+0xF5E2	0x8E31	#CJK UNIFIED IDEOGRAPH
+0xF5E3	0x8E49	#CJK UNIFIED IDEOGRAPH
+0xF5E4	0x8E41	#CJK UNIFIED IDEOGRAPH
+0xF5E5	0x8E42	#CJK UNIFIED IDEOGRAPH
+0xF5E6	0x8E51	#CJK UNIFIED IDEOGRAPH
+0xF5E7	0x8E52	#CJK UNIFIED IDEOGRAPH
+0xF5E8	0x8E4A	#CJK UNIFIED IDEOGRAPH
+0xF5E9	0x8E70	#CJK UNIFIED IDEOGRAPH
+0xF5EA	0x8E76	#CJK UNIFIED IDEOGRAPH
+0xF5EB	0x8E7C	#CJK UNIFIED IDEOGRAPH
+0xF5EC	0x8E6F	#CJK UNIFIED IDEOGRAPH
+0xF5ED	0x8E74	#CJK UNIFIED IDEOGRAPH
+0xF5EE	0x8E85	#CJK UNIFIED IDEOGRAPH
+0xF5EF	0x8E8F	#CJK UNIFIED IDEOGRAPH
+0xF5F0	0x8E94	#CJK UNIFIED IDEOGRAPH
+0xF5F1	0x8E90	#CJK UNIFIED IDEOGRAPH
+0xF5F2	0x8E9C	#CJK UNIFIED IDEOGRAPH
+0xF5F3	0x8E9E	#CJK UNIFIED IDEOGRAPH
+0xF5F4	0x8C78	#CJK UNIFIED IDEOGRAPH
+0xF5F5	0x8C82	#CJK UNIFIED IDEOGRAPH
+0xF5F6	0x8C8A	#CJK UNIFIED IDEOGRAPH
+0xF5F7	0x8C85	#CJK UNIFIED IDEOGRAPH
+0xF5F8	0x8C98	#CJK UNIFIED IDEOGRAPH
+0xF5F9	0x8C94	#CJK UNIFIED IDEOGRAPH
+0xF5FA	0x659B	#CJK UNIFIED IDEOGRAPH
+0xF5FB	0x89D6	#CJK UNIFIED IDEOGRAPH
+0xF5FC	0x89DE	#CJK UNIFIED IDEOGRAPH
+0xF5FD	0x89DA	#CJK UNIFIED IDEOGRAPH
+0xF5FE	0x89DC	#CJK UNIFIED IDEOGRAPH
+0xF640	0x9BDC	#CJK UNIFIED IDEOGRAPH
+0xF641	0x9BDD	#CJK UNIFIED IDEOGRAPH
+0xF642	0x9BDE	#CJK UNIFIED IDEOGRAPH
+0xF643	0x9BDF	#CJK UNIFIED IDEOGRAPH
+0xF644	0x9BE0	#CJK UNIFIED IDEOGRAPH
+0xF645	0x9BE1	#CJK UNIFIED IDEOGRAPH
+0xF646	0x9BE2	#CJK UNIFIED IDEOGRAPH
+0xF647	0x9BE3	#CJK UNIFIED IDEOGRAPH
+0xF648	0x9BE4	#CJK UNIFIED IDEOGRAPH
+0xF649	0x9BE5	#CJK UNIFIED IDEOGRAPH
+0xF64A	0x9BE6	#CJK UNIFIED IDEOGRAPH
+0xF64B	0x9BE7	#CJK UNIFIED IDEOGRAPH
+0xF64C	0x9BE8	#CJK UNIFIED IDEOGRAPH
+0xF64D	0x9BE9	#CJK UNIFIED IDEOGRAPH
+0xF64E	0x9BEA	#CJK UNIFIED IDEOGRAPH
+0xF64F	0x9BEB	#CJK UNIFIED IDEOGRAPH
+0xF650	0x9BEC	#CJK UNIFIED IDEOGRAPH
+0xF651	0x9BED	#CJK UNIFIED IDEOGRAPH
+0xF652	0x9BEE	#CJK UNIFIED IDEOGRAPH
+0xF653	0x9BEF	#CJK UNIFIED IDEOGRAPH
+0xF654	0x9BF0	#CJK UNIFIED IDEOGRAPH
+0xF655	0x9BF1	#CJK UNIFIED IDEOGRAPH
+0xF656	0x9BF2	#CJK UNIFIED IDEOGRAPH
+0xF657	0x9BF3	#CJK UNIFIED IDEOGRAPH
+0xF658	0x9BF4	#CJK UNIFIED IDEOGRAPH
+0xF659	0x9BF5	#CJK UNIFIED IDEOGRAPH
+0xF65A	0x9BF6	#CJK UNIFIED IDEOGRAPH
+0xF65B	0x9BF7	#CJK UNIFIED IDEOGRAPH
+0xF65C	0x9BF8	#CJK UNIFIED IDEOGRAPH
+0xF65D	0x9BF9	#CJK UNIFIED IDEOGRAPH
+0xF65E	0x9BFA	#CJK UNIFIED IDEOGRAPH
+0xF65F	0x9BFB	#CJK UNIFIED IDEOGRAPH
+0xF660	0x9BFC	#CJK UNIFIED IDEOGRAPH
+0xF661	0x9BFD	#CJK UNIFIED IDEOGRAPH
+0xF662	0x9BFE	#CJK UNIFIED IDEOGRAPH
+0xF663	0x9BFF	#CJK UNIFIED IDEOGRAPH
+0xF664	0x9C00	#CJK UNIFIED IDEOGRAPH
+0xF665	0x9C01	#CJK UNIFIED IDEOGRAPH
+0xF666	0x9C02	#CJK UNIFIED IDEOGRAPH
+0xF667	0x9C03	#CJK UNIFIED IDEOGRAPH
+0xF668	0x9C04	#CJK UNIFIED IDEOGRAPH
+0xF669	0x9C05	#CJK UNIFIED IDEOGRAPH
+0xF66A	0x9C06	#CJK UNIFIED IDEOGRAPH
+0xF66B	0x9C07	#CJK UNIFIED IDEOGRAPH
+0xF66C	0x9C08	#CJK UNIFIED IDEOGRAPH
+0xF66D	0x9C09	#CJK UNIFIED IDEOGRAPH
+0xF66E	0x9C0A	#CJK UNIFIED IDEOGRAPH
+0xF66F	0x9C0B	#CJK UNIFIED IDEOGRAPH
+0xF670	0x9C0C	#CJK UNIFIED IDEOGRAPH
+0xF671	0x9C0D	#CJK UNIFIED IDEOGRAPH
+0xF672	0x9C0E	#CJK UNIFIED IDEOGRAPH
+0xF673	0x9C0F	#CJK UNIFIED IDEOGRAPH
+0xF674	0x9C10	#CJK UNIFIED IDEOGRAPH
+0xF675	0x9C11	#CJK UNIFIED IDEOGRAPH
+0xF676	0x9C12	#CJK UNIFIED IDEOGRAPH
+0xF677	0x9C13	#CJK UNIFIED IDEOGRAPH
+0xF678	0x9C14	#CJK UNIFIED IDEOGRAPH
+0xF679	0x9C15	#CJK UNIFIED IDEOGRAPH
+0xF67A	0x9C16	#CJK UNIFIED IDEOGRAPH
+0xF67B	0x9C17	#CJK UNIFIED IDEOGRAPH
+0xF67C	0x9C18	#CJK UNIFIED IDEOGRAPH
+0xF67D	0x9C19	#CJK UNIFIED IDEOGRAPH
+0xF67E	0x9C1A	#CJK UNIFIED IDEOGRAPH
+0xF680	0x9C1B	#CJK UNIFIED IDEOGRAPH
+0xF681	0x9C1C	#CJK UNIFIED IDEOGRAPH
+0xF682	0x9C1D	#CJK UNIFIED IDEOGRAPH
+0xF683	0x9C1E	#CJK UNIFIED IDEOGRAPH
+0xF684	0x9C1F	#CJK UNIFIED IDEOGRAPH
+0xF685	0x9C20	#CJK UNIFIED IDEOGRAPH
+0xF686	0x9C21	#CJK UNIFIED IDEOGRAPH
+0xF687	0x9C22	#CJK UNIFIED IDEOGRAPH
+0xF688	0x9C23	#CJK UNIFIED IDEOGRAPH
+0xF689	0x9C24	#CJK UNIFIED IDEOGRAPH
+0xF68A	0x9C25	#CJK UNIFIED IDEOGRAPH
+0xF68B	0x9C26	#CJK UNIFIED IDEOGRAPH
+0xF68C	0x9C27	#CJK UNIFIED IDEOGRAPH
+0xF68D	0x9C28	#CJK UNIFIED IDEOGRAPH
+0xF68E	0x9C29	#CJK UNIFIED IDEOGRAPH
+0xF68F	0x9C2A	#CJK UNIFIED IDEOGRAPH
+0xF690	0x9C2B	#CJK UNIFIED IDEOGRAPH
+0xF691	0x9C2C	#CJK UNIFIED IDEOGRAPH
+0xF692	0x9C2D	#CJK UNIFIED IDEOGRAPH
+0xF693	0x9C2E	#CJK UNIFIED IDEOGRAPH
+0xF694	0x9C2F	#CJK UNIFIED IDEOGRAPH
+0xF695	0x9C30	#CJK UNIFIED IDEOGRAPH
+0xF696	0x9C31	#CJK UNIFIED IDEOGRAPH
+0xF697	0x9C32	#CJK UNIFIED IDEOGRAPH
+0xF698	0x9C33	#CJK UNIFIED IDEOGRAPH
+0xF699	0x9C34	#CJK UNIFIED IDEOGRAPH
+0xF69A	0x9C35	#CJK UNIFIED IDEOGRAPH
+0xF69B	0x9C36	#CJK UNIFIED IDEOGRAPH
+0xF69C	0x9C37	#CJK UNIFIED IDEOGRAPH
+0xF69D	0x9C38	#CJK UNIFIED IDEOGRAPH
+0xF69E	0x9C39	#CJK UNIFIED IDEOGRAPH
+0xF69F	0x9C3A	#CJK UNIFIED IDEOGRAPH
+0xF6A0	0x9C3B	#CJK UNIFIED IDEOGRAPH
+0xF6A1	0x89E5	#CJK UNIFIED IDEOGRAPH
+0xF6A2	0x89EB	#CJK UNIFIED IDEOGRAPH
+0xF6A3	0x89EF	#CJK UNIFIED IDEOGRAPH
+0xF6A4	0x8A3E	#CJK UNIFIED IDEOGRAPH
+0xF6A5	0x8B26	#CJK UNIFIED IDEOGRAPH
+0xF6A6	0x9753	#CJK UNIFIED IDEOGRAPH
+0xF6A7	0x96E9	#CJK UNIFIED IDEOGRAPH
+0xF6A8	0x96F3	#CJK UNIFIED IDEOGRAPH
+0xF6A9	0x96EF	#CJK UNIFIED IDEOGRAPH
+0xF6AA	0x9706	#CJK UNIFIED IDEOGRAPH
+0xF6AB	0x9701	#CJK UNIFIED IDEOGRAPH
+0xF6AC	0x9708	#CJK UNIFIED IDEOGRAPH
+0xF6AD	0x970F	#CJK UNIFIED IDEOGRAPH
+0xF6AE	0x970E	#CJK UNIFIED IDEOGRAPH
+0xF6AF	0x972A	#CJK UNIFIED IDEOGRAPH
+0xF6B0	0x972D	#CJK UNIFIED IDEOGRAPH
+0xF6B1	0x9730	#CJK UNIFIED IDEOGRAPH
+0xF6B2	0x973E	#CJK UNIFIED IDEOGRAPH
+0xF6B3	0x9F80	#CJK UNIFIED IDEOGRAPH
+0xF6B4	0x9F83	#CJK UNIFIED IDEOGRAPH
+0xF6B5	0x9F85	#CJK UNIFIED IDEOGRAPH
+0xF6B6	0x9F86	#CJK UNIFIED IDEOGRAPH
+0xF6B7	0x9F87	#CJK UNIFIED IDEOGRAPH
+0xF6B8	0x9F88	#CJK UNIFIED IDEOGRAPH
+0xF6B9	0x9F89	#CJK UNIFIED IDEOGRAPH
+0xF6BA	0x9F8A	#CJK UNIFIED IDEOGRAPH
+0xF6BB	0x9F8C	#CJK UNIFIED IDEOGRAPH
+0xF6BC	0x9EFE	#CJK UNIFIED IDEOGRAPH
+0xF6BD	0x9F0B	#CJK UNIFIED IDEOGRAPH
+0xF6BE	0x9F0D	#CJK UNIFIED IDEOGRAPH
+0xF6BF	0x96B9	#CJK UNIFIED IDEOGRAPH
+0xF6C0	0x96BC	#CJK UNIFIED IDEOGRAPH
+0xF6C1	0x96BD	#CJK UNIFIED IDEOGRAPH
+0xF6C2	0x96CE	#CJK UNIFIED IDEOGRAPH
+0xF6C3	0x96D2	#CJK UNIFIED IDEOGRAPH
+0xF6C4	0x77BF	#CJK UNIFIED IDEOGRAPH
+0xF6C5	0x96E0	#CJK UNIFIED IDEOGRAPH
+0xF6C6	0x928E	#CJK UNIFIED IDEOGRAPH
+0xF6C7	0x92AE	#CJK UNIFIED IDEOGRAPH
+0xF6C8	0x92C8	#CJK UNIFIED IDEOGRAPH
+0xF6C9	0x933E	#CJK UNIFIED IDEOGRAPH
+0xF6CA	0x936A	#CJK UNIFIED IDEOGRAPH
+0xF6CB	0x93CA	#CJK UNIFIED IDEOGRAPH
+0xF6CC	0x938F	#CJK UNIFIED IDEOGRAPH
+0xF6CD	0x943E	#CJK UNIFIED IDEOGRAPH
+0xF6CE	0x946B	#CJK UNIFIED IDEOGRAPH
+0xF6CF	0x9C7F	#CJK UNIFIED IDEOGRAPH
+0xF6D0	0x9C82	#CJK UNIFIED IDEOGRAPH
+0xF6D1	0x9C85	#CJK UNIFIED IDEOGRAPH
+0xF6D2	0x9C86	#CJK UNIFIED IDEOGRAPH
+0xF6D3	0x9C87	#CJK UNIFIED IDEOGRAPH
+0xF6D4	0x9C88	#CJK UNIFIED IDEOGRAPH
+0xF6D5	0x7A23	#CJK UNIFIED IDEOGRAPH
+0xF6D6	0x9C8B	#CJK UNIFIED IDEOGRAPH
+0xF6D7	0x9C8E	#CJK UNIFIED IDEOGRAPH
+0xF6D8	0x9C90	#CJK UNIFIED IDEOGRAPH
+0xF6D9	0x9C91	#CJK UNIFIED IDEOGRAPH
+0xF6DA	0x9C92	#CJK UNIFIED IDEOGRAPH
+0xF6DB	0x9C94	#CJK UNIFIED IDEOGRAPH
+0xF6DC	0x9C95	#CJK UNIFIED IDEOGRAPH
+0xF6DD	0x9C9A	#CJK UNIFIED IDEOGRAPH
+0xF6DE	0x9C9B	#CJK UNIFIED IDEOGRAPH
+0xF6DF	0x9C9E	#CJK UNIFIED IDEOGRAPH
+0xF6E0	0x9C9F	#CJK UNIFIED IDEOGRAPH
+0xF6E1	0x9CA0	#CJK UNIFIED IDEOGRAPH
+0xF6E2	0x9CA1	#CJK UNIFIED IDEOGRAPH
+0xF6E3	0x9CA2	#CJK UNIFIED IDEOGRAPH
+0xF6E4	0x9CA3	#CJK UNIFIED IDEOGRAPH
+0xF6E5	0x9CA5	#CJK UNIFIED IDEOGRAPH
+0xF6E6	0x9CA6	#CJK UNIFIED IDEOGRAPH
+0xF6E7	0x9CA7	#CJK UNIFIED IDEOGRAPH
+0xF6E8	0x9CA8	#CJK UNIFIED IDEOGRAPH
+0xF6E9	0x9CA9	#CJK UNIFIED IDEOGRAPH
+0xF6EA	0x9CAB	#CJK UNIFIED IDEOGRAPH
+0xF6EB	0x9CAD	#CJK UNIFIED IDEOGRAPH
+0xF6EC	0x9CAE	#CJK UNIFIED IDEOGRAPH
+0xF6ED	0x9CB0	#CJK UNIFIED IDEOGRAPH
+0xF6EE	0x9CB1	#CJK UNIFIED IDEOGRAPH
+0xF6EF	0x9CB2	#CJK UNIFIED IDEOGRAPH
+0xF6F0	0x9CB3	#CJK UNIFIED IDEOGRAPH
+0xF6F1	0x9CB4	#CJK UNIFIED IDEOGRAPH
+0xF6F2	0x9CB5	#CJK UNIFIED IDEOGRAPH
+0xF6F3	0x9CB6	#CJK UNIFIED IDEOGRAPH
+0xF6F4	0x9CB7	#CJK UNIFIED IDEOGRAPH
+0xF6F5	0x9CBA	#CJK UNIFIED IDEOGRAPH
+0xF6F6	0x9CBB	#CJK UNIFIED IDEOGRAPH
+0xF6F7	0x9CBC	#CJK UNIFIED IDEOGRAPH
+0xF6F8	0x9CBD	#CJK UNIFIED IDEOGRAPH
+0xF6F9	0x9CC4	#CJK UNIFIED IDEOGRAPH
+0xF6FA	0x9CC5	#CJK UNIFIED IDEOGRAPH
+0xF6FB	0x9CC6	#CJK UNIFIED IDEOGRAPH
+0xF6FC	0x9CC7	#CJK UNIFIED IDEOGRAPH
+0xF6FD	0x9CCA	#CJK UNIFIED IDEOGRAPH
+0xF6FE	0x9CCB	#CJK UNIFIED IDEOGRAPH
+0xF740	0x9C3C	#CJK UNIFIED IDEOGRAPH
+0xF741	0x9C3D	#CJK UNIFIED IDEOGRAPH
+0xF742	0x9C3E	#CJK UNIFIED IDEOGRAPH
+0xF743	0x9C3F	#CJK UNIFIED IDEOGRAPH
+0xF744	0x9C40	#CJK UNIFIED IDEOGRAPH
+0xF745	0x9C41	#CJK UNIFIED IDEOGRAPH
+0xF746	0x9C42	#CJK UNIFIED IDEOGRAPH
+0xF747	0x9C43	#CJK UNIFIED IDEOGRAPH
+0xF748	0x9C44	#CJK UNIFIED IDEOGRAPH
+0xF749	0x9C45	#CJK UNIFIED IDEOGRAPH
+0xF74A	0x9C46	#CJK UNIFIED IDEOGRAPH
+0xF74B	0x9C47	#CJK UNIFIED IDEOGRAPH
+0xF74C	0x9C48	#CJK UNIFIED IDEOGRAPH
+0xF74D	0x9C49	#CJK UNIFIED IDEOGRAPH
+0xF74E	0x9C4A	#CJK UNIFIED IDEOGRAPH
+0xF74F	0x9C4B	#CJK UNIFIED IDEOGRAPH
+0xF750	0x9C4C	#CJK UNIFIED IDEOGRAPH
+0xF751	0x9C4D	#CJK UNIFIED IDEOGRAPH
+0xF752	0x9C4E	#CJK UNIFIED IDEOGRAPH
+0xF753	0x9C4F	#CJK UNIFIED IDEOGRAPH
+0xF754	0x9C50	#CJK UNIFIED IDEOGRAPH
+0xF755	0x9C51	#CJK UNIFIED IDEOGRAPH
+0xF756	0x9C52	#CJK UNIFIED IDEOGRAPH
+0xF757	0x9C53	#CJK UNIFIED IDEOGRAPH
+0xF758	0x9C54	#CJK UNIFIED IDEOGRAPH
+0xF759	0x9C55	#CJK UNIFIED IDEOGRAPH
+0xF75A	0x9C56	#CJK UNIFIED IDEOGRAPH
+0xF75B	0x9C57	#CJK UNIFIED IDEOGRAPH
+0xF75C	0x9C58	#CJK UNIFIED IDEOGRAPH
+0xF75D	0x9C59	#CJK UNIFIED IDEOGRAPH
+0xF75E	0x9C5A	#CJK UNIFIED IDEOGRAPH
+0xF75F	0x9C5B	#CJK UNIFIED IDEOGRAPH
+0xF760	0x9C5C	#CJK UNIFIED IDEOGRAPH
+0xF761	0x9C5D	#CJK UNIFIED IDEOGRAPH
+0xF762	0x9C5E	#CJK UNIFIED IDEOGRAPH
+0xF763	0x9C5F	#CJK UNIFIED IDEOGRAPH
+0xF764	0x9C60	#CJK UNIFIED IDEOGRAPH
+0xF765	0x9C61	#CJK UNIFIED IDEOGRAPH
+0xF766	0x9C62	#CJK UNIFIED IDEOGRAPH
+0xF767	0x9C63	#CJK UNIFIED IDEOGRAPH
+0xF768	0x9C64	#CJK UNIFIED IDEOGRAPH
+0xF769	0x9C65	#CJK UNIFIED IDEOGRAPH
+0xF76A	0x9C66	#CJK UNIFIED IDEOGRAPH
+0xF76B	0x9C67	#CJK UNIFIED IDEOGRAPH
+0xF76C	0x9C68	#CJK UNIFIED IDEOGRAPH
+0xF76D	0x9C69	#CJK UNIFIED IDEOGRAPH
+0xF76E	0x9C6A	#CJK UNIFIED IDEOGRAPH
+0xF76F	0x9C6B	#CJK UNIFIED IDEOGRAPH
+0xF770	0x9C6C	#CJK UNIFIED IDEOGRAPH
+0xF771	0x9C6D	#CJK UNIFIED IDEOGRAPH
+0xF772	0x9C6E	#CJK UNIFIED IDEOGRAPH
+0xF773	0x9C6F	#CJK UNIFIED IDEOGRAPH
+0xF774	0x9C70	#CJK UNIFIED IDEOGRAPH
+0xF775	0x9C71	#CJK UNIFIED IDEOGRAPH
+0xF776	0x9C72	#CJK UNIFIED IDEOGRAPH
+0xF777	0x9C73	#CJK UNIFIED IDEOGRAPH
+0xF778	0x9C74	#CJK UNIFIED IDEOGRAPH
+0xF779	0x9C75	#CJK UNIFIED IDEOGRAPH
+0xF77A	0x9C76	#CJK UNIFIED IDEOGRAPH
+0xF77B	0x9C77	#CJK UNIFIED IDEOGRAPH
+0xF77C	0x9C78	#CJK UNIFIED IDEOGRAPH
+0xF77D	0x9C79	#CJK UNIFIED IDEOGRAPH
+0xF77E	0x9C7A	#CJK UNIFIED IDEOGRAPH
+0xF780	0x9C7B	#CJK UNIFIED IDEOGRAPH
+0xF781	0x9C7D	#CJK UNIFIED IDEOGRAPH
+0xF782	0x9C7E	#CJK UNIFIED IDEOGRAPH
+0xF783	0x9C80	#CJK UNIFIED IDEOGRAPH
+0xF784	0x9C83	#CJK UNIFIED IDEOGRAPH
+0xF785	0x9C84	#CJK UNIFIED IDEOGRAPH
+0xF786	0x9C89	#CJK UNIFIED IDEOGRAPH
+0xF787	0x9C8A	#CJK UNIFIED IDEOGRAPH
+0xF788	0x9C8C	#CJK UNIFIED IDEOGRAPH
+0xF789	0x9C8F	#CJK UNIFIED IDEOGRAPH
+0xF78A	0x9C93	#CJK UNIFIED IDEOGRAPH
+0xF78B	0x9C96	#CJK UNIFIED IDEOGRAPH
+0xF78C	0x9C97	#CJK UNIFIED IDEOGRAPH
+0xF78D	0x9C98	#CJK UNIFIED IDEOGRAPH
+0xF78E	0x9C99	#CJK UNIFIED IDEOGRAPH
+0xF78F	0x9C9D	#CJK UNIFIED IDEOGRAPH
+0xF790	0x9CAA	#CJK UNIFIED IDEOGRAPH
+0xF791	0x9CAC	#CJK UNIFIED IDEOGRAPH
+0xF792	0x9CAF	#CJK UNIFIED IDEOGRAPH
+0xF793	0x9CB9	#CJK UNIFIED IDEOGRAPH
+0xF794	0x9CBE	#CJK UNIFIED IDEOGRAPH
+0xF795	0x9CBF	#CJK UNIFIED IDEOGRAPH
+0xF796	0x9CC0	#CJK UNIFIED IDEOGRAPH
+0xF797	0x9CC1	#CJK UNIFIED IDEOGRAPH
+0xF798	0x9CC2	#CJK UNIFIED IDEOGRAPH
+0xF799	0x9CC8	#CJK UNIFIED IDEOGRAPH
+0xF79A	0x9CC9	#CJK UNIFIED IDEOGRAPH
+0xF79B	0x9CD1	#CJK UNIFIED IDEOGRAPH
+0xF79C	0x9CD2	#CJK UNIFIED IDEOGRAPH
+0xF79D	0x9CDA	#CJK UNIFIED IDEOGRAPH
+0xF79E	0x9CDB	#CJK UNIFIED IDEOGRAPH
+0xF79F	0x9CE0	#CJK UNIFIED IDEOGRAPH
+0xF7A0	0x9CE1	#CJK UNIFIED IDEOGRAPH
+0xF7A1	0x9CCC	#CJK UNIFIED IDEOGRAPH
+0xF7A2	0x9CCD	#CJK UNIFIED IDEOGRAPH
+0xF7A3	0x9CCE	#CJK UNIFIED IDEOGRAPH
+0xF7A4	0x9CCF	#CJK UNIFIED IDEOGRAPH
+0xF7A5	0x9CD0	#CJK UNIFIED IDEOGRAPH
+0xF7A6	0x9CD3	#CJK UNIFIED IDEOGRAPH
+0xF7A7	0x9CD4	#CJK UNIFIED IDEOGRAPH
+0xF7A8	0x9CD5	#CJK UNIFIED IDEOGRAPH
+0xF7A9	0x9CD7	#CJK UNIFIED IDEOGRAPH
+0xF7AA	0x9CD8	#CJK UNIFIED IDEOGRAPH
+0xF7AB	0x9CD9	#CJK UNIFIED IDEOGRAPH
+0xF7AC	0x9CDC	#CJK UNIFIED IDEOGRAPH
+0xF7AD	0x9CDD	#CJK UNIFIED IDEOGRAPH
+0xF7AE	0x9CDF	#CJK UNIFIED IDEOGRAPH
+0xF7AF	0x9CE2	#CJK UNIFIED IDEOGRAPH
+0xF7B0	0x977C	#CJK UNIFIED IDEOGRAPH
+0xF7B1	0x9785	#CJK UNIFIED IDEOGRAPH
+0xF7B2	0x9791	#CJK UNIFIED IDEOGRAPH
+0xF7B3	0x9792	#CJK UNIFIED IDEOGRAPH
+0xF7B4	0x9794	#CJK UNIFIED IDEOGRAPH
+0xF7B5	0x97AF	#CJK UNIFIED IDEOGRAPH
+0xF7B6	0x97AB	#CJK UNIFIED IDEOGRAPH
+0xF7B7	0x97A3	#CJK UNIFIED IDEOGRAPH
+0xF7B8	0x97B2	#CJK UNIFIED IDEOGRAPH
+0xF7B9	0x97B4	#CJK UNIFIED IDEOGRAPH
+0xF7BA	0x9AB1	#CJK UNIFIED IDEOGRAPH
+0xF7BB	0x9AB0	#CJK UNIFIED IDEOGRAPH
+0xF7BC	0x9AB7	#CJK UNIFIED IDEOGRAPH
+0xF7BD	0x9E58	#CJK UNIFIED IDEOGRAPH
+0xF7BE	0x9AB6	#CJK UNIFIED IDEOGRAPH
+0xF7BF	0x9ABA	#CJK UNIFIED IDEOGRAPH
+0xF7C0	0x9ABC	#CJK UNIFIED IDEOGRAPH
+0xF7C1	0x9AC1	#CJK UNIFIED IDEOGRAPH
+0xF7C2	0x9AC0	#CJK UNIFIED IDEOGRAPH
+0xF7C3	0x9AC5	#CJK UNIFIED IDEOGRAPH
+0xF7C4	0x9AC2	#CJK UNIFIED IDEOGRAPH
+0xF7C5	0x9ACB	#CJK UNIFIED IDEOGRAPH
+0xF7C6	0x9ACC	#CJK UNIFIED IDEOGRAPH
+0xF7C7	0x9AD1	#CJK UNIFIED IDEOGRAPH
+0xF7C8	0x9B45	#CJK UNIFIED IDEOGRAPH
+0xF7C9	0x9B43	#CJK UNIFIED IDEOGRAPH
+0xF7CA	0x9B47	#CJK UNIFIED IDEOGRAPH
+0xF7CB	0x9B49	#CJK UNIFIED IDEOGRAPH
+0xF7CC	0x9B48	#CJK UNIFIED IDEOGRAPH
+0xF7CD	0x9B4D	#CJK UNIFIED IDEOGRAPH
+0xF7CE	0x9B51	#CJK UNIFIED IDEOGRAPH
+0xF7CF	0x98E8	#CJK UNIFIED IDEOGRAPH
+0xF7D0	0x990D	#CJK UNIFIED IDEOGRAPH
+0xF7D1	0x992E	#CJK UNIFIED IDEOGRAPH
+0xF7D2	0x9955	#CJK UNIFIED IDEOGRAPH
+0xF7D3	0x9954	#CJK UNIFIED IDEOGRAPH
+0xF7D4	0x9ADF	#CJK UNIFIED IDEOGRAPH
+0xF7D5	0x9AE1	#CJK UNIFIED IDEOGRAPH
+0xF7D6	0x9AE6	#CJK UNIFIED IDEOGRAPH
+0xF7D7	0x9AEF	#CJK UNIFIED IDEOGRAPH
+0xF7D8	0x9AEB	#CJK UNIFIED IDEOGRAPH
+0xF7D9	0x9AFB	#CJK UNIFIED IDEOGRAPH
+0xF7DA	0x9AED	#CJK UNIFIED IDEOGRAPH
+0xF7DB	0x9AF9	#CJK UNIFIED IDEOGRAPH
+0xF7DC	0x9B08	#CJK UNIFIED IDEOGRAPH
+0xF7DD	0x9B0F	#CJK UNIFIED IDEOGRAPH
+0xF7DE	0x9B13	#CJK UNIFIED IDEOGRAPH
+0xF7DF	0x9B1F	#CJK UNIFIED IDEOGRAPH
+0xF7E0	0x9B23	#CJK UNIFIED IDEOGRAPH
+0xF7E1	0x9EBD	#CJK UNIFIED IDEOGRAPH
+0xF7E2	0x9EBE	#CJK UNIFIED IDEOGRAPH
+0xF7E3	0x7E3B	#CJK UNIFIED IDEOGRAPH
+0xF7E4	0x9E82	#CJK UNIFIED IDEOGRAPH
+0xF7E5	0x9E87	#CJK UNIFIED IDEOGRAPH
+0xF7E6	0x9E88	#CJK UNIFIED IDEOGRAPH
+0xF7E7	0x9E8B	#CJK UNIFIED IDEOGRAPH
+0xF7E8	0x9E92	#CJK UNIFIED IDEOGRAPH
+0xF7E9	0x93D6	#CJK UNIFIED IDEOGRAPH
+0xF7EA	0x9E9D	#CJK UNIFIED IDEOGRAPH
+0xF7EB	0x9E9F	#CJK UNIFIED IDEOGRAPH
+0xF7EC	0x9EDB	#CJK UNIFIED IDEOGRAPH
+0xF7ED	0x9EDC	#CJK UNIFIED IDEOGRAPH
+0xF7EE	0x9EDD	#CJK UNIFIED IDEOGRAPH
+0xF7EF	0x9EE0	#CJK UNIFIED IDEOGRAPH
+0xF7F0	0x9EDF	#CJK UNIFIED IDEOGRAPH
+0xF7F1	0x9EE2	#CJK UNIFIED IDEOGRAPH
+0xF7F2	0x9EE9	#CJK UNIFIED IDEOGRAPH
+0xF7F3	0x9EE7	#CJK UNIFIED IDEOGRAPH
+0xF7F4	0x9EE5	#CJK UNIFIED IDEOGRAPH
+0xF7F5	0x9EEA	#CJK UNIFIED IDEOGRAPH
+0xF7F6	0x9EEF	#CJK UNIFIED IDEOGRAPH
+0xF7F7	0x9F22	#CJK UNIFIED IDEOGRAPH
+0xF7F8	0x9F2C	#CJK UNIFIED IDEOGRAPH
+0xF7F9	0x9F2F	#CJK UNIFIED IDEOGRAPH
+0xF7FA	0x9F39	#CJK UNIFIED IDEOGRAPH
+0xF7FB	0x9F37	#CJK UNIFIED IDEOGRAPH
+0xF7FC	0x9F3D	#CJK UNIFIED IDEOGRAPH
+0xF7FD	0x9F3E	#CJK UNIFIED IDEOGRAPH
+0xF7FE	0x9F44	#CJK UNIFIED IDEOGRAPH
+0xF840	0x9CE3	#CJK UNIFIED IDEOGRAPH
+0xF841	0x9CE4	#CJK UNIFIED IDEOGRAPH
+0xF842	0x9CE5	#CJK UNIFIED IDEOGRAPH
+0xF843	0x9CE6	#CJK UNIFIED IDEOGRAPH
+0xF844	0x9CE7	#CJK UNIFIED IDEOGRAPH
+0xF845	0x9CE8	#CJK UNIFIED IDEOGRAPH
+0xF846	0x9CE9	#CJK UNIFIED IDEOGRAPH
+0xF847	0x9CEA	#CJK UNIFIED IDEOGRAPH
+0xF848	0x9CEB	#CJK UNIFIED IDEOGRAPH
+0xF849	0x9CEC	#CJK UNIFIED IDEOGRAPH
+0xF84A	0x9CED	#CJK UNIFIED IDEOGRAPH
+0xF84B	0x9CEE	#CJK UNIFIED IDEOGRAPH
+0xF84C	0x9CEF	#CJK UNIFIED IDEOGRAPH
+0xF84D	0x9CF0	#CJK UNIFIED IDEOGRAPH
+0xF84E	0x9CF1	#CJK UNIFIED IDEOGRAPH
+0xF84F	0x9CF2	#CJK UNIFIED IDEOGRAPH
+0xF850	0x9CF3	#CJK UNIFIED IDEOGRAPH
+0xF851	0x9CF4	#CJK UNIFIED IDEOGRAPH
+0xF852	0x9CF5	#CJK UNIFIED IDEOGRAPH
+0xF853	0x9CF6	#CJK UNIFIED IDEOGRAPH
+0xF854	0x9CF7	#CJK UNIFIED IDEOGRAPH
+0xF855	0x9CF8	#CJK UNIFIED IDEOGRAPH
+0xF856	0x9CF9	#CJK UNIFIED IDEOGRAPH
+0xF857	0x9CFA	#CJK UNIFIED IDEOGRAPH
+0xF858	0x9CFB	#CJK UNIFIED IDEOGRAPH
+0xF859	0x9CFC	#CJK UNIFIED IDEOGRAPH
+0xF85A	0x9CFD	#CJK UNIFIED IDEOGRAPH
+0xF85B	0x9CFE	#CJK UNIFIED IDEOGRAPH
+0xF85C	0x9CFF	#CJK UNIFIED IDEOGRAPH
+0xF85D	0x9D00	#CJK UNIFIED IDEOGRAPH
+0xF85E	0x9D01	#CJK UNIFIED IDEOGRAPH
+0xF85F	0x9D02	#CJK UNIFIED IDEOGRAPH
+0xF860	0x9D03	#CJK UNIFIED IDEOGRAPH
+0xF861	0x9D04	#CJK UNIFIED IDEOGRAPH
+0xF862	0x9D05	#CJK UNIFIED IDEOGRAPH
+0xF863	0x9D06	#CJK UNIFIED IDEOGRAPH
+0xF864	0x9D07	#CJK UNIFIED IDEOGRAPH
+0xF865	0x9D08	#CJK UNIFIED IDEOGRAPH
+0xF866	0x9D09	#CJK UNIFIED IDEOGRAPH
+0xF867	0x9D0A	#CJK UNIFIED IDEOGRAPH
+0xF868	0x9D0B	#CJK UNIFIED IDEOGRAPH
+0xF869	0x9D0C	#CJK UNIFIED IDEOGRAPH
+0xF86A	0x9D0D	#CJK UNIFIED IDEOGRAPH
+0xF86B	0x9D0E	#CJK UNIFIED IDEOGRAPH
+0xF86C	0x9D0F	#CJK UNIFIED IDEOGRAPH
+0xF86D	0x9D10	#CJK UNIFIED IDEOGRAPH
+0xF86E	0x9D11	#CJK UNIFIED IDEOGRAPH
+0xF86F	0x9D12	#CJK UNIFIED IDEOGRAPH
+0xF870	0x9D13	#CJK UNIFIED IDEOGRAPH
+0xF871	0x9D14	#CJK UNIFIED IDEOGRAPH
+0xF872	0x9D15	#CJK UNIFIED IDEOGRAPH
+0xF873	0x9D16	#CJK UNIFIED IDEOGRAPH
+0xF874	0x9D17	#CJK UNIFIED IDEOGRAPH
+0xF875	0x9D18	#CJK UNIFIED IDEOGRAPH
+0xF876	0x9D19	#CJK UNIFIED IDEOGRAPH
+0xF877	0x9D1A	#CJK UNIFIED IDEOGRAPH
+0xF878	0x9D1B	#CJK UNIFIED IDEOGRAPH
+0xF879	0x9D1C	#CJK UNIFIED IDEOGRAPH
+0xF87A	0x9D1D	#CJK UNIFIED IDEOGRAPH
+0xF87B	0x9D1E	#CJK UNIFIED IDEOGRAPH
+0xF87C	0x9D1F	#CJK UNIFIED IDEOGRAPH
+0xF87D	0x9D20	#CJK UNIFIED IDEOGRAPH
+0xF87E	0x9D21	#CJK UNIFIED IDEOGRAPH
+0xF880	0x9D22	#CJK UNIFIED IDEOGRAPH
+0xF881	0x9D23	#CJK UNIFIED IDEOGRAPH
+0xF882	0x9D24	#CJK UNIFIED IDEOGRAPH
+0xF883	0x9D25	#CJK UNIFIED IDEOGRAPH
+0xF884	0x9D26	#CJK UNIFIED IDEOGRAPH
+0xF885	0x9D27	#CJK UNIFIED IDEOGRAPH
+0xF886	0x9D28	#CJK UNIFIED IDEOGRAPH
+0xF887	0x9D29	#CJK UNIFIED IDEOGRAPH
+0xF888	0x9D2A	#CJK UNIFIED IDEOGRAPH
+0xF889	0x9D2B	#CJK UNIFIED IDEOGRAPH
+0xF88A	0x9D2C	#CJK UNIFIED IDEOGRAPH
+0xF88B	0x9D2D	#CJK UNIFIED IDEOGRAPH
+0xF88C	0x9D2E	#CJK UNIFIED IDEOGRAPH
+0xF88D	0x9D2F	#CJK UNIFIED IDEOGRAPH
+0xF88E	0x9D30	#CJK UNIFIED IDEOGRAPH
+0xF88F	0x9D31	#CJK UNIFIED IDEOGRAPH
+0xF890	0x9D32	#CJK UNIFIED IDEOGRAPH
+0xF891	0x9D33	#CJK UNIFIED IDEOGRAPH
+0xF892	0x9D34	#CJK UNIFIED IDEOGRAPH
+0xF893	0x9D35	#CJK UNIFIED IDEOGRAPH
+0xF894	0x9D36	#CJK UNIFIED IDEOGRAPH
+0xF895	0x9D37	#CJK UNIFIED IDEOGRAPH
+0xF896	0x9D38	#CJK UNIFIED IDEOGRAPH
+0xF897	0x9D39	#CJK UNIFIED IDEOGRAPH
+0xF898	0x9D3A	#CJK UNIFIED IDEOGRAPH
+0xF899	0x9D3B	#CJK UNIFIED IDEOGRAPH
+0xF89A	0x9D3C	#CJK UNIFIED IDEOGRAPH
+0xF89B	0x9D3D	#CJK UNIFIED IDEOGRAPH
+0xF89C	0x9D3E	#CJK UNIFIED IDEOGRAPH
+0xF89D	0x9D3F	#CJK UNIFIED IDEOGRAPH
+0xF89E	0x9D40	#CJK UNIFIED IDEOGRAPH
+0xF89F	0x9D41	#CJK UNIFIED IDEOGRAPH
+0xF8A0	0x9D42	#CJK UNIFIED IDEOGRAPH
+0xF940	0x9D43	#CJK UNIFIED IDEOGRAPH
+0xF941	0x9D44	#CJK UNIFIED IDEOGRAPH
+0xF942	0x9D45	#CJK UNIFIED IDEOGRAPH
+0xF943	0x9D46	#CJK UNIFIED IDEOGRAPH
+0xF944	0x9D47	#CJK UNIFIED IDEOGRAPH
+0xF945	0x9D48	#CJK UNIFIED IDEOGRAPH
+0xF946	0x9D49	#CJK UNIFIED IDEOGRAPH
+0xF947	0x9D4A	#CJK UNIFIED IDEOGRAPH
+0xF948	0x9D4B	#CJK UNIFIED IDEOGRAPH
+0xF949	0x9D4C	#CJK UNIFIED IDEOGRAPH
+0xF94A	0x9D4D	#CJK UNIFIED IDEOGRAPH
+0xF94B	0x9D4E	#CJK UNIFIED IDEOGRAPH
+0xF94C	0x9D4F	#CJK UNIFIED IDEOGRAPH
+0xF94D	0x9D50	#CJK UNIFIED IDEOGRAPH
+0xF94E	0x9D51	#CJK UNIFIED IDEOGRAPH
+0xF94F	0x9D52	#CJK UNIFIED IDEOGRAPH
+0xF950	0x9D53	#CJK UNIFIED IDEOGRAPH
+0xF951	0x9D54	#CJK UNIFIED IDEOGRAPH
+0xF952	0x9D55	#CJK UNIFIED IDEOGRAPH
+0xF953	0x9D56	#CJK UNIFIED IDEOGRAPH
+0xF954	0x9D57	#CJK UNIFIED IDEOGRAPH
+0xF955	0x9D58	#CJK UNIFIED IDEOGRAPH
+0xF956	0x9D59	#CJK UNIFIED IDEOGRAPH
+0xF957	0x9D5A	#CJK UNIFIED IDEOGRAPH
+0xF958	0x9D5B	#CJK UNIFIED IDEOGRAPH
+0xF959	0x9D5C	#CJK UNIFIED IDEOGRAPH
+0xF95A	0x9D5D	#CJK UNIFIED IDEOGRAPH
+0xF95B	0x9D5E	#CJK UNIFIED IDEOGRAPH
+0xF95C	0x9D5F	#CJK UNIFIED IDEOGRAPH
+0xF95D	0x9D60	#CJK UNIFIED IDEOGRAPH
+0xF95E	0x9D61	#CJK UNIFIED IDEOGRAPH
+0xF95F	0x9D62	#CJK UNIFIED IDEOGRAPH
+0xF960	0x9D63	#CJK UNIFIED IDEOGRAPH
+0xF961	0x9D64	#CJK UNIFIED IDEOGRAPH
+0xF962	0x9D65	#CJK UNIFIED IDEOGRAPH
+0xF963	0x9D66	#CJK UNIFIED IDEOGRAPH
+0xF964	0x9D67	#CJK UNIFIED IDEOGRAPH
+0xF965	0x9D68	#CJK UNIFIED IDEOGRAPH
+0xF966	0x9D69	#CJK UNIFIED IDEOGRAPH
+0xF967	0x9D6A	#CJK UNIFIED IDEOGRAPH
+0xF968	0x9D6B	#CJK UNIFIED IDEOGRAPH
+0xF969	0x9D6C	#CJK UNIFIED IDEOGRAPH
+0xF96A	0x9D6D	#CJK UNIFIED IDEOGRAPH
+0xF96B	0x9D6E	#CJK UNIFIED IDEOGRAPH
+0xF96C	0x9D6F	#CJK UNIFIED IDEOGRAPH
+0xF96D	0x9D70	#CJK UNIFIED IDEOGRAPH
+0xF96E	0x9D71	#CJK UNIFIED IDEOGRAPH
+0xF96F	0x9D72	#CJK UNIFIED IDEOGRAPH
+0xF970	0x9D73	#CJK UNIFIED IDEOGRAPH
+0xF971	0x9D74	#CJK UNIFIED IDEOGRAPH
+0xF972	0x9D75	#CJK UNIFIED IDEOGRAPH
+0xF973	0x9D76	#CJK UNIFIED IDEOGRAPH
+0xF974	0x9D77	#CJK UNIFIED IDEOGRAPH
+0xF975	0x9D78	#CJK UNIFIED IDEOGRAPH
+0xF976	0x9D79	#CJK UNIFIED IDEOGRAPH
+0xF977	0x9D7A	#CJK UNIFIED IDEOGRAPH
+0xF978	0x9D7B	#CJK UNIFIED IDEOGRAPH
+0xF979	0x9D7C	#CJK UNIFIED IDEOGRAPH
+0xF97A	0x9D7D	#CJK UNIFIED IDEOGRAPH
+0xF97B	0x9D7E	#CJK UNIFIED IDEOGRAPH
+0xF97C	0x9D7F	#CJK UNIFIED IDEOGRAPH
+0xF97D	0x9D80	#CJK UNIFIED IDEOGRAPH
+0xF97E	0x9D81	#CJK UNIFIED IDEOGRAPH
+0xF980	0x9D82	#CJK UNIFIED IDEOGRAPH
+0xF981	0x9D83	#CJK UNIFIED IDEOGRAPH
+0xF982	0x9D84	#CJK UNIFIED IDEOGRAPH
+0xF983	0x9D85	#CJK UNIFIED IDEOGRAPH
+0xF984	0x9D86	#CJK UNIFIED IDEOGRAPH
+0xF985	0x9D87	#CJK UNIFIED IDEOGRAPH
+0xF986	0x9D88	#CJK UNIFIED IDEOGRAPH
+0xF987	0x9D89	#CJK UNIFIED IDEOGRAPH
+0xF988	0x9D8A	#CJK UNIFIED IDEOGRAPH
+0xF989	0x9D8B	#CJK UNIFIED IDEOGRAPH
+0xF98A	0x9D8C	#CJK UNIFIED IDEOGRAPH
+0xF98B	0x9D8D	#CJK UNIFIED IDEOGRAPH
+0xF98C	0x9D8E	#CJK UNIFIED IDEOGRAPH
+0xF98D	0x9D8F	#CJK UNIFIED IDEOGRAPH
+0xF98E	0x9D90	#CJK UNIFIED IDEOGRAPH
+0xF98F	0x9D91	#CJK UNIFIED IDEOGRAPH
+0xF990	0x9D92	#CJK UNIFIED IDEOGRAPH
+0xF991	0x9D93	#CJK UNIFIED IDEOGRAPH
+0xF992	0x9D94	#CJK UNIFIED IDEOGRAPH
+0xF993	0x9D95	#CJK UNIFIED IDEOGRAPH
+0xF994	0x9D96	#CJK UNIFIED IDEOGRAPH
+0xF995	0x9D97	#CJK UNIFIED IDEOGRAPH
+0xF996	0x9D98	#CJK UNIFIED IDEOGRAPH
+0xF997	0x9D99	#CJK UNIFIED IDEOGRAPH
+0xF998	0x9D9A	#CJK UNIFIED IDEOGRAPH
+0xF999	0x9D9B	#CJK UNIFIED IDEOGRAPH
+0xF99A	0x9D9C	#CJK UNIFIED IDEOGRAPH
+0xF99B	0x9D9D	#CJK UNIFIED IDEOGRAPH
+0xF99C	0x9D9E	#CJK UNIFIED IDEOGRAPH
+0xF99D	0x9D9F	#CJK UNIFIED IDEOGRAPH
+0xF99E	0x9DA0	#CJK UNIFIED IDEOGRAPH
+0xF99F	0x9DA1	#CJK UNIFIED IDEOGRAPH
+0xF9A0	0x9DA2	#CJK UNIFIED IDEOGRAPH
+0xFA40	0x9DA3	#CJK UNIFIED IDEOGRAPH
+0xFA41	0x9DA4	#CJK UNIFIED IDEOGRAPH
+0xFA42	0x9DA5	#CJK UNIFIED IDEOGRAPH
+0xFA43	0x9DA6	#CJK UNIFIED IDEOGRAPH
+0xFA44	0x9DA7	#CJK UNIFIED IDEOGRAPH
+0xFA45	0x9DA8	#CJK UNIFIED IDEOGRAPH
+0xFA46	0x9DA9	#CJK UNIFIED IDEOGRAPH
+0xFA47	0x9DAA	#CJK UNIFIED IDEOGRAPH
+0xFA48	0x9DAB	#CJK UNIFIED IDEOGRAPH
+0xFA49	0x9DAC	#CJK UNIFIED IDEOGRAPH
+0xFA4A	0x9DAD	#CJK UNIFIED IDEOGRAPH
+0xFA4B	0x9DAE	#CJK UNIFIED IDEOGRAPH
+0xFA4C	0x9DAF	#CJK UNIFIED IDEOGRAPH
+0xFA4D	0x9DB0	#CJK UNIFIED IDEOGRAPH
+0xFA4E	0x9DB1	#CJK UNIFIED IDEOGRAPH
+0xFA4F	0x9DB2	#CJK UNIFIED IDEOGRAPH
+0xFA50	0x9DB3	#CJK UNIFIED IDEOGRAPH
+0xFA51	0x9DB4	#CJK UNIFIED IDEOGRAPH
+0xFA52	0x9DB5	#CJK UNIFIED IDEOGRAPH
+0xFA53	0x9DB6	#CJK UNIFIED IDEOGRAPH
+0xFA54	0x9DB7	#CJK UNIFIED IDEOGRAPH
+0xFA55	0x9DB8	#CJK UNIFIED IDEOGRAPH
+0xFA56	0x9DB9	#CJK UNIFIED IDEOGRAPH
+0xFA57	0x9DBA	#CJK UNIFIED IDEOGRAPH
+0xFA58	0x9DBB	#CJK UNIFIED IDEOGRAPH
+0xFA59	0x9DBC	#CJK UNIFIED IDEOGRAPH
+0xFA5A	0x9DBD	#CJK UNIFIED IDEOGRAPH
+0xFA5B	0x9DBE	#CJK UNIFIED IDEOGRAPH
+0xFA5C	0x9DBF	#CJK UNIFIED IDEOGRAPH
+0xFA5D	0x9DC0	#CJK UNIFIED IDEOGRAPH
+0xFA5E	0x9DC1	#CJK UNIFIED IDEOGRAPH
+0xFA5F	0x9DC2	#CJK UNIFIED IDEOGRAPH
+0xFA60	0x9DC3	#CJK UNIFIED IDEOGRAPH
+0xFA61	0x9DC4	#CJK UNIFIED IDEOGRAPH
+0xFA62	0x9DC5	#CJK UNIFIED IDEOGRAPH
+0xFA63	0x9DC6	#CJK UNIFIED IDEOGRAPH
+0xFA64	0x9DC7	#CJK UNIFIED IDEOGRAPH
+0xFA65	0x9DC8	#CJK UNIFIED IDEOGRAPH
+0xFA66	0x9DC9	#CJK UNIFIED IDEOGRAPH
+0xFA67	0x9DCA	#CJK UNIFIED IDEOGRAPH
+0xFA68	0x9DCB	#CJK UNIFIED IDEOGRAPH
+0xFA69	0x9DCC	#CJK UNIFIED IDEOGRAPH
+0xFA6A	0x9DCD	#CJK UNIFIED IDEOGRAPH
+0xFA6B	0x9DCE	#CJK UNIFIED IDEOGRAPH
+0xFA6C	0x9DCF	#CJK UNIFIED IDEOGRAPH
+0xFA6D	0x9DD0	#CJK UNIFIED IDEOGRAPH
+0xFA6E	0x9DD1	#CJK UNIFIED IDEOGRAPH
+0xFA6F	0x9DD2	#CJK UNIFIED IDEOGRAPH
+0xFA70	0x9DD3	#CJK UNIFIED IDEOGRAPH
+0xFA71	0x9DD4	#CJK UNIFIED IDEOGRAPH
+0xFA72	0x9DD5	#CJK UNIFIED IDEOGRAPH
+0xFA73	0x9DD6	#CJK UNIFIED IDEOGRAPH
+0xFA74	0x9DD7	#CJK UNIFIED IDEOGRAPH
+0xFA75	0x9DD8	#CJK UNIFIED IDEOGRAPH
+0xFA76	0x9DD9	#CJK UNIFIED IDEOGRAPH
+0xFA77	0x9DDA	#CJK UNIFIED IDEOGRAPH
+0xFA78	0x9DDB	#CJK UNIFIED IDEOGRAPH
+0xFA79	0x9DDC	#CJK UNIFIED IDEOGRAPH
+0xFA7A	0x9DDD	#CJK UNIFIED IDEOGRAPH
+0xFA7B	0x9DDE	#CJK UNIFIED IDEOGRAPH
+0xFA7C	0x9DDF	#CJK UNIFIED IDEOGRAPH
+0xFA7D	0x9DE0	#CJK UNIFIED IDEOGRAPH
+0xFA7E	0x9DE1	#CJK UNIFIED IDEOGRAPH
+0xFA80	0x9DE2	#CJK UNIFIED IDEOGRAPH
+0xFA81	0x9DE3	#CJK UNIFIED IDEOGRAPH
+0xFA82	0x9DE4	#CJK UNIFIED IDEOGRAPH
+0xFA83	0x9DE5	#CJK UNIFIED IDEOGRAPH
+0xFA84	0x9DE6	#CJK UNIFIED IDEOGRAPH
+0xFA85	0x9DE7	#CJK UNIFIED IDEOGRAPH
+0xFA86	0x9DE8	#CJK UNIFIED IDEOGRAPH
+0xFA87	0x9DE9	#CJK UNIFIED IDEOGRAPH
+0xFA88	0x9DEA	#CJK UNIFIED IDEOGRAPH
+0xFA89	0x9DEB	#CJK UNIFIED IDEOGRAPH
+0xFA8A	0x9DEC	#CJK UNIFIED IDEOGRAPH
+0xFA8B	0x9DED	#CJK UNIFIED IDEOGRAPH
+0xFA8C	0x9DEE	#CJK UNIFIED IDEOGRAPH
+0xFA8D	0x9DEF	#CJK UNIFIED IDEOGRAPH
+0xFA8E	0x9DF0	#CJK UNIFIED IDEOGRAPH
+0xFA8F	0x9DF1	#CJK UNIFIED IDEOGRAPH
+0xFA90	0x9DF2	#CJK UNIFIED IDEOGRAPH
+0xFA91	0x9DF3	#CJK UNIFIED IDEOGRAPH
+0xFA92	0x9DF4	#CJK UNIFIED IDEOGRAPH
+0xFA93	0x9DF5	#CJK UNIFIED IDEOGRAPH
+0xFA94	0x9DF6	#CJK UNIFIED IDEOGRAPH
+0xFA95	0x9DF7	#CJK UNIFIED IDEOGRAPH
+0xFA96	0x9DF8	#CJK UNIFIED IDEOGRAPH
+0xFA97	0x9DF9	#CJK UNIFIED IDEOGRAPH
+0xFA98	0x9DFA	#CJK UNIFIED IDEOGRAPH
+0xFA99	0x9DFB	#CJK UNIFIED IDEOGRAPH
+0xFA9A	0x9DFC	#CJK UNIFIED IDEOGRAPH
+0xFA9B	0x9DFD	#CJK UNIFIED IDEOGRAPH
+0xFA9C	0x9DFE	#CJK UNIFIED IDEOGRAPH
+0xFA9D	0x9DFF	#CJK UNIFIED IDEOGRAPH
+0xFA9E	0x9E00	#CJK UNIFIED IDEOGRAPH
+0xFA9F	0x9E01	#CJK UNIFIED IDEOGRAPH
+0xFAA0	0x9E02	#CJK UNIFIED IDEOGRAPH
+0xFB40	0x9E03	#CJK UNIFIED IDEOGRAPH
+0xFB41	0x9E04	#CJK UNIFIED IDEOGRAPH
+0xFB42	0x9E05	#CJK UNIFIED IDEOGRAPH
+0xFB43	0x9E06	#CJK UNIFIED IDEOGRAPH
+0xFB44	0x9E07	#CJK UNIFIED IDEOGRAPH
+0xFB45	0x9E08	#CJK UNIFIED IDEOGRAPH
+0xFB46	0x9E09	#CJK UNIFIED IDEOGRAPH
+0xFB47	0x9E0A	#CJK UNIFIED IDEOGRAPH
+0xFB48	0x9E0B	#CJK UNIFIED IDEOGRAPH
+0xFB49	0x9E0C	#CJK UNIFIED IDEOGRAPH
+0xFB4A	0x9E0D	#CJK UNIFIED IDEOGRAPH
+0xFB4B	0x9E0E	#CJK UNIFIED IDEOGRAPH
+0xFB4C	0x9E0F	#CJK UNIFIED IDEOGRAPH
+0xFB4D	0x9E10	#CJK UNIFIED IDEOGRAPH
+0xFB4E	0x9E11	#CJK UNIFIED IDEOGRAPH
+0xFB4F	0x9E12	#CJK UNIFIED IDEOGRAPH
+0xFB50	0x9E13	#CJK UNIFIED IDEOGRAPH
+0xFB51	0x9E14	#CJK UNIFIED IDEOGRAPH
+0xFB52	0x9E15	#CJK UNIFIED IDEOGRAPH
+0xFB53	0x9E16	#CJK UNIFIED IDEOGRAPH
+0xFB54	0x9E17	#CJK UNIFIED IDEOGRAPH
+0xFB55	0x9E18	#CJK UNIFIED IDEOGRAPH
+0xFB56	0x9E19	#CJK UNIFIED IDEOGRAPH
+0xFB57	0x9E1A	#CJK UNIFIED IDEOGRAPH
+0xFB58	0x9E1B	#CJK UNIFIED IDEOGRAPH
+0xFB59	0x9E1C	#CJK UNIFIED IDEOGRAPH
+0xFB5A	0x9E1D	#CJK UNIFIED IDEOGRAPH
+0xFB5B	0x9E1E	#CJK UNIFIED IDEOGRAPH
+0xFB5C	0x9E24	#CJK UNIFIED IDEOGRAPH
+0xFB5D	0x9E27	#CJK UNIFIED IDEOGRAPH
+0xFB5E	0x9E2E	#CJK UNIFIED IDEOGRAPH
+0xFB5F	0x9E30	#CJK UNIFIED IDEOGRAPH
+0xFB60	0x9E34	#CJK UNIFIED IDEOGRAPH
+0xFB61	0x9E3B	#CJK UNIFIED IDEOGRAPH
+0xFB62	0x9E3C	#CJK UNIFIED IDEOGRAPH
+0xFB63	0x9E40	#CJK UNIFIED IDEOGRAPH
+0xFB64	0x9E4D	#CJK UNIFIED IDEOGRAPH
+0xFB65	0x9E50	#CJK UNIFIED IDEOGRAPH
+0xFB66	0x9E52	#CJK UNIFIED IDEOGRAPH
+0xFB67	0x9E53	#CJK UNIFIED IDEOGRAPH
+0xFB68	0x9E54	#CJK UNIFIED IDEOGRAPH
+0xFB69	0x9E56	#CJK UNIFIED IDEOGRAPH
+0xFB6A	0x9E59	#CJK UNIFIED IDEOGRAPH
+0xFB6B	0x9E5D	#CJK UNIFIED IDEOGRAPH
+0xFB6C	0x9E5F	#CJK UNIFIED IDEOGRAPH
+0xFB6D	0x9E60	#CJK UNIFIED IDEOGRAPH
+0xFB6E	0x9E61	#CJK UNIFIED IDEOGRAPH
+0xFB6F	0x9E62	#CJK UNIFIED IDEOGRAPH
+0xFB70	0x9E65	#CJK UNIFIED IDEOGRAPH
+0xFB71	0x9E6E	#CJK UNIFIED IDEOGRAPH
+0xFB72	0x9E6F	#CJK UNIFIED IDEOGRAPH
+0xFB73	0x9E72	#CJK UNIFIED IDEOGRAPH
+0xFB74	0x9E74	#CJK UNIFIED IDEOGRAPH
+0xFB75	0x9E75	#CJK UNIFIED IDEOGRAPH
+0xFB76	0x9E76	#CJK UNIFIED IDEOGRAPH
+0xFB77	0x9E77	#CJK UNIFIED IDEOGRAPH
+0xFB78	0x9E78	#CJK UNIFIED IDEOGRAPH
+0xFB79	0x9E79	#CJK UNIFIED IDEOGRAPH
+0xFB7A	0x9E7A	#CJK UNIFIED IDEOGRAPH
+0xFB7B	0x9E7B	#CJK UNIFIED IDEOGRAPH
+0xFB7C	0x9E7C	#CJK UNIFIED IDEOGRAPH
+0xFB7D	0x9E7D	#CJK UNIFIED IDEOGRAPH
+0xFB7E	0x9E80	#CJK UNIFIED IDEOGRAPH
+0xFB80	0x9E81	#CJK UNIFIED IDEOGRAPH
+0xFB81	0x9E83	#CJK UNIFIED IDEOGRAPH
+0xFB82	0x9E84	#CJK UNIFIED IDEOGRAPH
+0xFB83	0x9E85	#CJK UNIFIED IDEOGRAPH
+0xFB84	0x9E86	#CJK UNIFIED IDEOGRAPH
+0xFB85	0x9E89	#CJK UNIFIED IDEOGRAPH
+0xFB86	0x9E8A	#CJK UNIFIED IDEOGRAPH
+0xFB87	0x9E8C	#CJK UNIFIED IDEOGRAPH
+0xFB88	0x9E8D	#CJK UNIFIED IDEOGRAPH
+0xFB89	0x9E8E	#CJK UNIFIED IDEOGRAPH
+0xFB8A	0x9E8F	#CJK UNIFIED IDEOGRAPH
+0xFB8B	0x9E90	#CJK UNIFIED IDEOGRAPH
+0xFB8C	0x9E91	#CJK UNIFIED IDEOGRAPH
+0xFB8D	0x9E94	#CJK UNIFIED IDEOGRAPH
+0xFB8E	0x9E95	#CJK UNIFIED IDEOGRAPH
+0xFB8F	0x9E96	#CJK UNIFIED IDEOGRAPH
+0xFB90	0x9E97	#CJK UNIFIED IDEOGRAPH
+0xFB91	0x9E98	#CJK UNIFIED IDEOGRAPH
+0xFB92	0x9E99	#CJK UNIFIED IDEOGRAPH
+0xFB93	0x9E9A	#CJK UNIFIED IDEOGRAPH
+0xFB94	0x9E9B	#CJK UNIFIED IDEOGRAPH
+0xFB95	0x9E9C	#CJK UNIFIED IDEOGRAPH
+0xFB96	0x9E9E	#CJK UNIFIED IDEOGRAPH
+0xFB97	0x9EA0	#CJK UNIFIED IDEOGRAPH
+0xFB98	0x9EA1	#CJK UNIFIED IDEOGRAPH
+0xFB99	0x9EA2	#CJK UNIFIED IDEOGRAPH
+0xFB9A	0x9EA3	#CJK UNIFIED IDEOGRAPH
+0xFB9B	0x9EA4	#CJK UNIFIED IDEOGRAPH
+0xFB9C	0x9EA5	#CJK UNIFIED IDEOGRAPH
+0xFB9D	0x9EA7	#CJK UNIFIED IDEOGRAPH
+0xFB9E	0x9EA8	#CJK UNIFIED IDEOGRAPH
+0xFB9F	0x9EA9	#CJK UNIFIED IDEOGRAPH
+0xFBA0	0x9EAA	#CJK UNIFIED IDEOGRAPH
+0xFC40	0x9EAB	#CJK UNIFIED IDEOGRAPH
+0xFC41	0x9EAC	#CJK UNIFIED IDEOGRAPH
+0xFC42	0x9EAD	#CJK UNIFIED IDEOGRAPH
+0xFC43	0x9EAE	#CJK UNIFIED IDEOGRAPH
+0xFC44	0x9EAF	#CJK UNIFIED IDEOGRAPH
+0xFC45	0x9EB0	#CJK UNIFIED IDEOGRAPH
+0xFC46	0x9EB1	#CJK UNIFIED IDEOGRAPH
+0xFC47	0x9EB2	#CJK UNIFIED IDEOGRAPH
+0xFC48	0x9EB3	#CJK UNIFIED IDEOGRAPH
+0xFC49	0x9EB5	#CJK UNIFIED IDEOGRAPH
+0xFC4A	0x9EB6	#CJK UNIFIED IDEOGRAPH
+0xFC4B	0x9EB7	#CJK UNIFIED IDEOGRAPH
+0xFC4C	0x9EB9	#CJK UNIFIED IDEOGRAPH
+0xFC4D	0x9EBA	#CJK UNIFIED IDEOGRAPH
+0xFC4E	0x9EBC	#CJK UNIFIED IDEOGRAPH
+0xFC4F	0x9EBF	#CJK UNIFIED IDEOGRAPH
+0xFC50	0x9EC0	#CJK UNIFIED IDEOGRAPH
+0xFC51	0x9EC1	#CJK UNIFIED IDEOGRAPH
+0xFC52	0x9EC2	#CJK UNIFIED IDEOGRAPH
+0xFC53	0x9EC3	#CJK UNIFIED IDEOGRAPH
+0xFC54	0x9EC5	#CJK UNIFIED IDEOGRAPH
+0xFC55	0x9EC6	#CJK UNIFIED IDEOGRAPH
+0xFC56	0x9EC7	#CJK UNIFIED IDEOGRAPH
+0xFC57	0x9EC8	#CJK UNIFIED IDEOGRAPH
+0xFC58	0x9ECA	#CJK UNIFIED IDEOGRAPH
+0xFC59	0x9ECB	#CJK UNIFIED IDEOGRAPH
+0xFC5A	0x9ECC	#CJK UNIFIED IDEOGRAPH
+0xFC5B	0x9ED0	#CJK UNIFIED IDEOGRAPH
+0xFC5C	0x9ED2	#CJK UNIFIED IDEOGRAPH
+0xFC5D	0x9ED3	#CJK UNIFIED IDEOGRAPH
+0xFC5E	0x9ED5	#CJK UNIFIED IDEOGRAPH
+0xFC5F	0x9ED6	#CJK UNIFIED IDEOGRAPH
+0xFC60	0x9ED7	#CJK UNIFIED IDEOGRAPH
+0xFC61	0x9ED9	#CJK UNIFIED IDEOGRAPH
+0xFC62	0x9EDA	#CJK UNIFIED IDEOGRAPH
+0xFC63	0x9EDE	#CJK UNIFIED IDEOGRAPH
+0xFC64	0x9EE1	#CJK UNIFIED IDEOGRAPH
+0xFC65	0x9EE3	#CJK UNIFIED IDEOGRAPH
+0xFC66	0x9EE4	#CJK UNIFIED IDEOGRAPH
+0xFC67	0x9EE6	#CJK UNIFIED IDEOGRAPH
+0xFC68	0x9EE8	#CJK UNIFIED IDEOGRAPH
+0xFC69	0x9EEB	#CJK UNIFIED IDEOGRAPH
+0xFC6A	0x9EEC	#CJK UNIFIED IDEOGRAPH
+0xFC6B	0x9EED	#CJK UNIFIED IDEOGRAPH
+0xFC6C	0x9EEE	#CJK UNIFIED IDEOGRAPH
+0xFC6D	0x9EF0	#CJK UNIFIED IDEOGRAPH
+0xFC6E	0x9EF1	#CJK UNIFIED IDEOGRAPH
+0xFC6F	0x9EF2	#CJK UNIFIED IDEOGRAPH
+0xFC70	0x9EF3	#CJK UNIFIED IDEOGRAPH
+0xFC71	0x9EF4	#CJK UNIFIED IDEOGRAPH
+0xFC72	0x9EF5	#CJK UNIFIED IDEOGRAPH
+0xFC73	0x9EF6	#CJK UNIFIED IDEOGRAPH
+0xFC74	0x9EF7	#CJK UNIFIED IDEOGRAPH
+0xFC75	0x9EF8	#CJK UNIFIED IDEOGRAPH
+0xFC76	0x9EFA	#CJK UNIFIED IDEOGRAPH
+0xFC77	0x9EFD	#CJK UNIFIED IDEOGRAPH
+0xFC78	0x9EFF	#CJK UNIFIED IDEOGRAPH
+0xFC79	0x9F00	#CJK UNIFIED IDEOGRAPH
+0xFC7A	0x9F01	#CJK UNIFIED IDEOGRAPH
+0xFC7B	0x9F02	#CJK UNIFIED IDEOGRAPH
+0xFC7C	0x9F03	#CJK UNIFIED IDEOGRAPH
+0xFC7D	0x9F04	#CJK UNIFIED IDEOGRAPH
+0xFC7E	0x9F05	#CJK UNIFIED IDEOGRAPH
+0xFC80	0x9F06	#CJK UNIFIED IDEOGRAPH
+0xFC81	0x9F07	#CJK UNIFIED IDEOGRAPH
+0xFC82	0x9F08	#CJK UNIFIED IDEOGRAPH
+0xFC83	0x9F09	#CJK UNIFIED IDEOGRAPH
+0xFC84	0x9F0A	#CJK UNIFIED IDEOGRAPH
+0xFC85	0x9F0C	#CJK UNIFIED IDEOGRAPH
+0xFC86	0x9F0F	#CJK UNIFIED IDEOGRAPH
+0xFC87	0x9F11	#CJK UNIFIED IDEOGRAPH
+0xFC88	0x9F12	#CJK UNIFIED IDEOGRAPH
+0xFC89	0x9F14	#CJK UNIFIED IDEOGRAPH
+0xFC8A	0x9F15	#CJK UNIFIED IDEOGRAPH
+0xFC8B	0x9F16	#CJK UNIFIED IDEOGRAPH
+0xFC8C	0x9F18	#CJK UNIFIED IDEOGRAPH
+0xFC8D	0x9F1A	#CJK UNIFIED IDEOGRAPH
+0xFC8E	0x9F1B	#CJK UNIFIED IDEOGRAPH
+0xFC8F	0x9F1C	#CJK UNIFIED IDEOGRAPH
+0xFC90	0x9F1D	#CJK UNIFIED IDEOGRAPH
+0xFC91	0x9F1E	#CJK UNIFIED IDEOGRAPH
+0xFC92	0x9F1F	#CJK UNIFIED IDEOGRAPH
+0xFC93	0x9F21	#CJK UNIFIED IDEOGRAPH
+0xFC94	0x9F23	#CJK UNIFIED IDEOGRAPH
+0xFC95	0x9F24	#CJK UNIFIED IDEOGRAPH
+0xFC96	0x9F25	#CJK UNIFIED IDEOGRAPH
+0xFC97	0x9F26	#CJK UNIFIED IDEOGRAPH
+0xFC98	0x9F27	#CJK UNIFIED IDEOGRAPH
+0xFC99	0x9F28	#CJK UNIFIED IDEOGRAPH
+0xFC9A	0x9F29	#CJK UNIFIED IDEOGRAPH
+0xFC9B	0x9F2A	#CJK UNIFIED IDEOGRAPH
+0xFC9C	0x9F2B	#CJK UNIFIED IDEOGRAPH
+0xFC9D	0x9F2D	#CJK UNIFIED IDEOGRAPH
+0xFC9E	0x9F2E	#CJK UNIFIED IDEOGRAPH
+0xFC9F	0x9F30	#CJK UNIFIED IDEOGRAPH
+0xFCA0	0x9F31	#CJK UNIFIED IDEOGRAPH
+0xFD40	0x9F32	#CJK UNIFIED IDEOGRAPH
+0xFD41	0x9F33	#CJK UNIFIED IDEOGRAPH
+0xFD42	0x9F34	#CJK UNIFIED IDEOGRAPH
+0xFD43	0x9F35	#CJK UNIFIED IDEOGRAPH
+0xFD44	0x9F36	#CJK UNIFIED IDEOGRAPH
+0xFD45	0x9F38	#CJK UNIFIED IDEOGRAPH
+0xFD46	0x9F3A	#CJK UNIFIED IDEOGRAPH
+0xFD47	0x9F3C	#CJK UNIFIED IDEOGRAPH
+0xFD48	0x9F3F	#CJK UNIFIED IDEOGRAPH
+0xFD49	0x9F40	#CJK UNIFIED IDEOGRAPH
+0xFD4A	0x9F41	#CJK UNIFIED IDEOGRAPH
+0xFD4B	0x9F42	#CJK UNIFIED IDEOGRAPH
+0xFD4C	0x9F43	#CJK UNIFIED IDEOGRAPH
+0xFD4D	0x9F45	#CJK UNIFIED IDEOGRAPH
+0xFD4E	0x9F46	#CJK UNIFIED IDEOGRAPH
+0xFD4F	0x9F47	#CJK UNIFIED IDEOGRAPH
+0xFD50	0x9F48	#CJK UNIFIED IDEOGRAPH
+0xFD51	0x9F49	#CJK UNIFIED IDEOGRAPH
+0xFD52	0x9F4A	#CJK UNIFIED IDEOGRAPH
+0xFD53	0x9F4B	#CJK UNIFIED IDEOGRAPH
+0xFD54	0x9F4C	#CJK UNIFIED IDEOGRAPH
+0xFD55	0x9F4D	#CJK UNIFIED IDEOGRAPH
+0xFD56	0x9F4E	#CJK UNIFIED IDEOGRAPH
+0xFD57	0x9F4F	#CJK UNIFIED IDEOGRAPH
+0xFD58	0x9F52	#CJK UNIFIED IDEOGRAPH
+0xFD59	0x9F53	#CJK UNIFIED IDEOGRAPH
+0xFD5A	0x9F54	#CJK UNIFIED IDEOGRAPH
+0xFD5B	0x9F55	#CJK UNIFIED IDEOGRAPH
+0xFD5C	0x9F56	#CJK UNIFIED IDEOGRAPH
+0xFD5D	0x9F57	#CJK UNIFIED IDEOGRAPH
+0xFD5E	0x9F58	#CJK UNIFIED IDEOGRAPH
+0xFD5F	0x9F59	#CJK UNIFIED IDEOGRAPH
+0xFD60	0x9F5A	#CJK UNIFIED IDEOGRAPH
+0xFD61	0x9F5B	#CJK UNIFIED IDEOGRAPH
+0xFD62	0x9F5C	#CJK UNIFIED IDEOGRAPH
+0xFD63	0x9F5D	#CJK UNIFIED IDEOGRAPH
+0xFD64	0x9F5E	#CJK UNIFIED IDEOGRAPH
+0xFD65	0x9F5F	#CJK UNIFIED IDEOGRAPH
+0xFD66	0x9F60	#CJK UNIFIED IDEOGRAPH
+0xFD67	0x9F61	#CJK UNIFIED IDEOGRAPH
+0xFD68	0x9F62	#CJK UNIFIED IDEOGRAPH
+0xFD69	0x9F63	#CJK UNIFIED IDEOGRAPH
+0xFD6A	0x9F64	#CJK UNIFIED IDEOGRAPH
+0xFD6B	0x9F65	#CJK UNIFIED IDEOGRAPH
+0xFD6C	0x9F66	#CJK UNIFIED IDEOGRAPH
+0xFD6D	0x9F67	#CJK UNIFIED IDEOGRAPH
+0xFD6E	0x9F68	#CJK UNIFIED IDEOGRAPH
+0xFD6F	0x9F69	#CJK UNIFIED IDEOGRAPH
+0xFD70	0x9F6A	#CJK UNIFIED IDEOGRAPH
+0xFD71	0x9F6B	#CJK UNIFIED IDEOGRAPH
+0xFD72	0x9F6C	#CJK UNIFIED IDEOGRAPH
+0xFD73	0x9F6D	#CJK UNIFIED IDEOGRAPH
+0xFD74	0x9F6E	#CJK UNIFIED IDEOGRAPH
+0xFD75	0x9F6F	#CJK UNIFIED IDEOGRAPH
+0xFD76	0x9F70	#CJK UNIFIED IDEOGRAPH
+0xFD77	0x9F71	#CJK UNIFIED IDEOGRAPH
+0xFD78	0x9F72	#CJK UNIFIED IDEOGRAPH
+0xFD79	0x9F73	#CJK UNIFIED IDEOGRAPH
+0xFD7A	0x9F74	#CJK UNIFIED IDEOGRAPH
+0xFD7B	0x9F75	#CJK UNIFIED IDEOGRAPH
+0xFD7C	0x9F76	#CJK UNIFIED IDEOGRAPH
+0xFD7D	0x9F77	#CJK UNIFIED IDEOGRAPH
+0xFD7E	0x9F78	#CJK UNIFIED IDEOGRAPH
+0xFD80	0x9F79	#CJK UNIFIED IDEOGRAPH
+0xFD81	0x9F7A	#CJK UNIFIED IDEOGRAPH
+0xFD82	0x9F7B	#CJK UNIFIED IDEOGRAPH
+0xFD83	0x9F7C	#CJK UNIFIED IDEOGRAPH
+0xFD84	0x9F7D	#CJK UNIFIED IDEOGRAPH
+0xFD85	0x9F7E	#CJK UNIFIED IDEOGRAPH
+0xFD86	0x9F81	#CJK UNIFIED IDEOGRAPH
+0xFD87	0x9F82	#CJK UNIFIED IDEOGRAPH
+0xFD88	0x9F8D	#CJK UNIFIED IDEOGRAPH
+0xFD89	0x9F8E	#CJK UNIFIED IDEOGRAPH
+0xFD8A	0x9F8F	#CJK UNIFIED IDEOGRAPH
+0xFD8B	0x9F90	#CJK UNIFIED IDEOGRAPH
+0xFD8C	0x9F91	#CJK UNIFIED IDEOGRAPH
+0xFD8D	0x9F92	#CJK UNIFIED IDEOGRAPH
+0xFD8E	0x9F93	#CJK UNIFIED IDEOGRAPH
+0xFD8F	0x9F94	#CJK UNIFIED IDEOGRAPH
+0xFD90	0x9F95	#CJK UNIFIED IDEOGRAPH
+0xFD91	0x9F96	#CJK UNIFIED IDEOGRAPH
+0xFD92	0x9F97	#CJK UNIFIED IDEOGRAPH
+0xFD93	0x9F98	#CJK UNIFIED IDEOGRAPH
+0xFD94	0x9F9C	#CJK UNIFIED IDEOGRAPH
+0xFD95	0x9F9D	#CJK UNIFIED IDEOGRAPH
+0xFD96	0x9F9E	#CJK UNIFIED IDEOGRAPH
+0xFD97	0x9FA1	#CJK UNIFIED IDEOGRAPH
+0xFD98	0x9FA2	#CJK UNIFIED IDEOGRAPH
+0xFD99	0x9FA3	#CJK UNIFIED IDEOGRAPH
+0xFD9A	0x9FA4	#CJK UNIFIED IDEOGRAPH
+0xFD9B	0x9FA5	#CJK UNIFIED IDEOGRAPH
+0xFD9C	0xF92C	#CJK COMPATIBILITY IDEOGRAPH
+0xFD9D	0xF979	#CJK COMPATIBILITY IDEOGRAPH
+0xFD9E	0xF995	#CJK COMPATIBILITY IDEOGRAPH
+0xFD9F	0xF9E7	#CJK COMPATIBILITY IDEOGRAPH
+0xFDA0	0xF9F1	#CJK COMPATIBILITY IDEOGRAPH
+0xFE40	0xFA0C	#CJK COMPATIBILITY IDEOGRAPH
+0xFE41	0xFA0D	#CJK COMPATIBILITY IDEOGRAPH
+0xFE42	0xFA0E	#CJK COMPATIBILITY IDEOGRAPH
+0xFE43	0xFA0F	#CJK COMPATIBILITY IDEOGRAPH
+0xFE44	0xFA11	#CJK COMPATIBILITY IDEOGRAPH
+0xFE45	0xFA13	#CJK COMPATIBILITY IDEOGRAPH
+0xFE46	0xFA14	#CJK COMPATIBILITY IDEOGRAPH
+0xFE47	0xFA18	#CJK COMPATIBILITY IDEOGRAPH
+0xFE48	0xFA1F	#CJK COMPATIBILITY IDEOGRAPH
+0xFE49	0xFA20	#CJK COMPATIBILITY IDEOGRAPH
+0xFE4A	0xFA21	#CJK COMPATIBILITY IDEOGRAPH
+0xFE4B	0xFA23	#CJK COMPATIBILITY IDEOGRAPH
+0xFE4C	0xFA24	#CJK COMPATIBILITY IDEOGRAPH
+0xFE4D	0xFA27	#CJK COMPATIBILITY IDEOGRAPH
+0xFE4E	0xFA28	#CJK COMPATIBILITY IDEOGRAPH
+0xFE4F	0xFA29	#CJK COMPATIBILITY IDEOGRAPH
diff --git a/tools/encoding/cp949.txt b/tools/encoding/cp949.txt
new file mode 100644
index 0000000..6bbda39
--- /dev/null
+++ b/tools/encoding/cp949.txt
@@ -0,0 +1,17322 @@
+#
+#    Name:     cp949 to Unicode table
+#    Unicode version: 2.0
+#    Table version: 2.01
+#    Table format:  Format A
+#    Date:          1/7/2000
+#
+#    Contact:       cpxlate@microsoft.com
+#
+#    General notes: none
+#
+#    Format: Three tab-separated columns
+#        Column #1 is the cp949 code (in hex)
+#        Column #2 is the Unicode (in hex as 0xXXXX)
+#        Column #3 is the Unicode name (follows a comment sign, '#')
+#
+#    The entries are in cp949 order
+#
+0x00	0x0000	#NULL
+0x01	0x0001	#START OF HEADING
+0x02	0x0002	#START OF TEXT
+0x03	0x0003	#END OF TEXT
+0x04	0x0004	#END OF TRANSMISSION
+0x05	0x0005	#ENQUIRY
+0x06	0x0006	#ACKNOWLEDGE
+0x07	0x0007	#BELL
+0x08	0x0008	#BACKSPACE
+0x09	0x0009	#HORIZONTAL TABULATION
+0x0A	0x000A	#LINE FEED
+0x0B	0x000B	#VERTICAL TABULATION
+0x0C	0x000C	#FORM FEED
+0x0D	0x000D	#CARRIAGE RETURN
+0x0E	0x000E	#SHIFT OUT
+0x0F	0x000F	#SHIFT IN
+0x10	0x0010	#DATA LINK ESCAPE
+0x11	0x0011	#DEVICE CONTROL ONE
+0x12	0x0012	#DEVICE CONTROL TWO
+0x13	0x0013	#DEVICE CONTROL THREE
+0x14	0x0014	#DEVICE CONTROL FOUR
+0x15	0x0015	#NEGATIVE ACKNOWLEDGE
+0x16	0x0016	#SYNCHRONOUS IDLE
+0x17	0x0017	#END OF TRANSMISSION BLOCK
+0x18	0x0018	#CANCEL
+0x19	0x0019	#END OF MEDIUM
+0x1A	0x001A	#SUBSTITUTE
+0x1B	0x001B	#ESCAPE
+0x1C	0x001C	#FILE SEPARATOR
+0x1D	0x001D	#GROUP SEPARATOR
+0x1E	0x001E	#RECORD SEPARATOR
+0x1F	0x001F	#UNIT SEPARATOR
+0x20	0x0020	#SPACE
+0x21	0x0021	#EXCLAMATION MARK
+0x22	0x0022	#QUOTATION MARK
+0x23	0x0023	#NUMBER SIGN
+0x24	0x0024	#DOLLAR SIGN
+0x25	0x0025	#PERCENT SIGN
+0x26	0x0026	#AMPERSAND
+0x27	0x0027	#APOSTROPHE
+0x28	0x0028	#LEFT PARENTHESIS
+0x29	0x0029	#RIGHT PARENTHESIS
+0x2A	0x002A	#ASTERISK
+0x2B	0x002B	#PLUS SIGN
+0x2C	0x002C	#COMMA
+0x2D	0x002D	#HYPHEN-MINUS
+0x2E	0x002E	#FULL STOP
+0x2F	0x002F	#SOLIDUS
+0x30	0x0030	#DIGIT ZERO
+0x31	0x0031	#DIGIT ONE
+0x32	0x0032	#DIGIT TWO
+0x33	0x0033	#DIGIT THREE
+0x34	0x0034	#DIGIT FOUR
+0x35	0x0035	#DIGIT FIVE
+0x36	0x0036	#DIGIT SIX
+0x37	0x0037	#DIGIT SEVEN
+0x38	0x0038	#DIGIT EIGHT
+0x39	0x0039	#DIGIT NINE
+0x3A	0x003A	#COLON
+0x3B	0x003B	#SEMICOLON
+0x3C	0x003C	#LESS-THAN SIGN
+0x3D	0x003D	#EQUALS SIGN
+0x3E	0x003E	#GREATER-THAN SIGN
+0x3F	0x003F	#QUESTION MARK
+0x40	0x0040	#COMMERCIAL AT
+0x41	0x0041	#LATIN CAPITAL LETTER A
+0x42	0x0042	#LATIN CAPITAL LETTER B
+0x43	0x0043	#LATIN CAPITAL LETTER C
+0x44	0x0044	#LATIN CAPITAL LETTER D
+0x45	0x0045	#LATIN CAPITAL LETTER E
+0x46	0x0046	#LATIN CAPITAL LETTER F
+0x47	0x0047	#LATIN CAPITAL LETTER G
+0x48	0x0048	#LATIN CAPITAL LETTER H
+0x49	0x0049	#LATIN CAPITAL LETTER I
+0x4A	0x004A	#LATIN CAPITAL LETTER J
+0x4B	0x004B	#LATIN CAPITAL LETTER K
+0x4C	0x004C	#LATIN CAPITAL LETTER L
+0x4D	0x004D	#LATIN CAPITAL LETTER M
+0x4E	0x004E	#LATIN CAPITAL LETTER N
+0x4F	0x004F	#LATIN CAPITAL LETTER O
+0x50	0x0050	#LATIN CAPITAL LETTER P
+0x51	0x0051	#LATIN CAPITAL LETTER Q
+0x52	0x0052	#LATIN CAPITAL LETTER R
+0x53	0x0053	#LATIN CAPITAL LETTER S
+0x54	0x0054	#LATIN CAPITAL LETTER T
+0x55	0x0055	#LATIN CAPITAL LETTER U
+0x56	0x0056	#LATIN CAPITAL LETTER V
+0x57	0x0057	#LATIN CAPITAL LETTER W
+0x58	0x0058	#LATIN CAPITAL LETTER X
+0x59	0x0059	#LATIN CAPITAL LETTER Y
+0x5A	0x005A	#LATIN CAPITAL LETTER Z
+0x5B	0x005B	#LEFT SQUARE BRACKET
+0x5C	0x005C	#REVERSE SOLIDUS
+0x5D	0x005D	#RIGHT SQUARE BRACKET
+0x5E	0x005E	#CIRCUMFLEX ACCENT
+0x5F	0x005F	#LOW LINE
+0x60	0x0060	#GRAVE ACCENT
+0x61	0x0061	#LATIN SMALL LETTER A
+0x62	0x0062	#LATIN SMALL LETTER B
+0x63	0x0063	#LATIN SMALL LETTER C
+0x64	0x0064	#LATIN SMALL LETTER D
+0x65	0x0065	#LATIN SMALL LETTER E
+0x66	0x0066	#LATIN SMALL LETTER F
+0x67	0x0067	#LATIN SMALL LETTER G
+0x68	0x0068	#LATIN SMALL LETTER H
+0x69	0x0069	#LATIN SMALL LETTER I
+0x6A	0x006A	#LATIN SMALL LETTER J
+0x6B	0x006B	#LATIN SMALL LETTER K
+0x6C	0x006C	#LATIN SMALL LETTER L
+0x6D	0x006D	#LATIN SMALL LETTER M
+0x6E	0x006E	#LATIN SMALL LETTER N
+0x6F	0x006F	#LATIN SMALL LETTER O
+0x70	0x0070	#LATIN SMALL LETTER P
+0x71	0x0071	#LATIN SMALL LETTER Q
+0x72	0x0072	#LATIN SMALL LETTER R
+0x73	0x0073	#LATIN SMALL LETTER S
+0x74	0x0074	#LATIN SMALL LETTER T
+0x75	0x0075	#LATIN SMALL LETTER U
+0x76	0x0076	#LATIN SMALL LETTER V
+0x77	0x0077	#LATIN SMALL LETTER W
+0x78	0x0078	#LATIN SMALL LETTER X
+0x79	0x0079	#LATIN SMALL LETTER Y
+0x7A	0x007A	#LATIN SMALL LETTER Z
+0x7B	0x007B	#LEFT CURLY BRACKET
+0x7C	0x007C	#VERTICAL LINE
+0x7D	0x007D	#RIGHT CURLY BRACKET
+0x7E	0x007E	#TILDE
+0x7F	0x007F	#DELETE
+0x80	      	#UNDEFINED
+0x81	      	#DBCS LEAD BYTE
+0x82	      	#DBCS LEAD BYTE
+0x83	      	#DBCS LEAD BYTE
+0x84	      	#DBCS LEAD BYTE
+0x85	      	#DBCS LEAD BYTE
+0x86	      	#DBCS LEAD BYTE
+0x87	      	#DBCS LEAD BYTE
+0x88	      	#DBCS LEAD BYTE
+0x89	      	#DBCS LEAD BYTE
+0x8A	      	#DBCS LEAD BYTE
+0x8B	      	#DBCS LEAD BYTE
+0x8C	      	#DBCS LEAD BYTE
+0x8D	      	#DBCS LEAD BYTE
+0x8E	      	#DBCS LEAD BYTE
+0x8F	      	#DBCS LEAD BYTE
+0x90	      	#DBCS LEAD BYTE
+0x91	      	#DBCS LEAD BYTE
+0x92	      	#DBCS LEAD BYTE
+0x93	      	#DBCS LEAD BYTE
+0x94	      	#DBCS LEAD BYTE
+0x95	      	#DBCS LEAD BYTE
+0x96	      	#DBCS LEAD BYTE
+0x97	      	#DBCS LEAD BYTE
+0x98	      	#DBCS LEAD BYTE
+0x99	      	#DBCS LEAD BYTE
+0x9A	      	#DBCS LEAD BYTE
+0x9B	      	#DBCS LEAD BYTE
+0x9C	      	#DBCS LEAD BYTE
+0x9D	      	#DBCS LEAD BYTE
+0x9E	      	#DBCS LEAD BYTE
+0x9F	      	#DBCS LEAD BYTE
+0xA0	      	#DBCS LEAD BYTE
+0xA1	      	#DBCS LEAD BYTE
+0xA2	      	#DBCS LEAD BYTE
+0xA3	      	#DBCS LEAD BYTE
+0xA4	      	#DBCS LEAD BYTE
+0xA5	      	#DBCS LEAD BYTE
+0xA6	      	#DBCS LEAD BYTE
+0xA7	      	#DBCS LEAD BYTE
+0xA8	      	#DBCS LEAD BYTE
+0xA9	      	#DBCS LEAD BYTE
+0xAA	      	#DBCS LEAD BYTE
+0xAB	      	#DBCS LEAD BYTE
+0xAC	      	#DBCS LEAD BYTE
+0xAD	      	#DBCS LEAD BYTE
+0xAE	      	#DBCS LEAD BYTE
+0xAF	      	#DBCS LEAD BYTE
+0xB0	      	#DBCS LEAD BYTE
+0xB1	      	#DBCS LEAD BYTE
+0xB2	      	#DBCS LEAD BYTE
+0xB3	      	#DBCS LEAD BYTE
+0xB4	      	#DBCS LEAD BYTE
+0xB5	      	#DBCS LEAD BYTE
+0xB6	      	#DBCS LEAD BYTE
+0xB7	      	#DBCS LEAD BYTE
+0xB8	      	#DBCS LEAD BYTE
+0xB9	      	#DBCS LEAD BYTE
+0xBA	      	#DBCS LEAD BYTE
+0xBB	      	#DBCS LEAD BYTE
+0xBC	      	#DBCS LEAD BYTE
+0xBD	      	#DBCS LEAD BYTE
+0xBE	      	#DBCS LEAD BYTE
+0xBF	      	#DBCS LEAD BYTE
+0xC0	      	#DBCS LEAD BYTE
+0xC1	      	#DBCS LEAD BYTE
+0xC2	      	#DBCS LEAD BYTE
+0xC3	      	#DBCS LEAD BYTE
+0xC4	      	#DBCS LEAD BYTE
+0xC5	      	#DBCS LEAD BYTE
+0xC6	      	#DBCS LEAD BYTE
+0xC7	      	#DBCS LEAD BYTE
+0xC8	      	#DBCS LEAD BYTE
+0xC9	      	#DBCS LEAD BYTE
+0xCA	      	#DBCS LEAD BYTE
+0xCB	      	#DBCS LEAD BYTE
+0xCC	      	#DBCS LEAD BYTE
+0xCD	      	#DBCS LEAD BYTE
+0xCE	      	#DBCS LEAD BYTE
+0xCF	      	#DBCS LEAD BYTE
+0xD0	      	#DBCS LEAD BYTE
+0xD1	      	#DBCS LEAD BYTE
+0xD2	      	#DBCS LEAD BYTE
+0xD3	      	#DBCS LEAD BYTE
+0xD4	      	#DBCS LEAD BYTE
+0xD5	      	#DBCS LEAD BYTE
+0xD6	      	#DBCS LEAD BYTE
+0xD7	      	#DBCS LEAD BYTE
+0xD8	      	#DBCS LEAD BYTE
+0xD9	      	#DBCS LEAD BYTE
+0xDA	      	#DBCS LEAD BYTE
+0xDB	      	#DBCS LEAD BYTE
+0xDC	      	#DBCS LEAD BYTE
+0xDD	      	#DBCS LEAD BYTE
+0xDE	      	#DBCS LEAD BYTE
+0xDF	      	#DBCS LEAD BYTE
+0xE0	      	#DBCS LEAD BYTE
+0xE1	      	#DBCS LEAD BYTE
+0xE2	      	#DBCS LEAD BYTE
+0xE3	      	#DBCS LEAD BYTE
+0xE4	      	#DBCS LEAD BYTE
+0xE5	      	#DBCS LEAD BYTE
+0xE6	      	#DBCS LEAD BYTE
+0xE7	      	#DBCS LEAD BYTE
+0xE8	      	#DBCS LEAD BYTE
+0xE9	      	#DBCS LEAD BYTE
+0xEA	      	#DBCS LEAD BYTE
+0xEB	      	#DBCS LEAD BYTE
+0xEC	      	#DBCS LEAD BYTE
+0xED	      	#DBCS LEAD BYTE
+0xEE	      	#DBCS LEAD BYTE
+0xEF	      	#DBCS LEAD BYTE
+0xF0	      	#DBCS LEAD BYTE
+0xF1	      	#DBCS LEAD BYTE
+0xF2	      	#DBCS LEAD BYTE
+0xF3	      	#DBCS LEAD BYTE
+0xF4	      	#DBCS LEAD BYTE
+0xF5	      	#DBCS LEAD BYTE
+0xF6	      	#DBCS LEAD BYTE
+0xF7	      	#DBCS LEAD BYTE
+0xF8	      	#DBCS LEAD BYTE
+0xF9	      	#DBCS LEAD BYTE
+0xFA	      	#DBCS LEAD BYTE
+0xFB	      	#DBCS LEAD BYTE
+0xFC	      	#DBCS LEAD BYTE
+0xFD	      	#DBCS LEAD BYTE
+0xFE	      	#DBCS LEAD BYTE
+0xFF	      	#UNDEFINED
+0x8141	0xAC02	#HANGUL SYLLABLE KIYEOK A SSANGKIYEOK
+0x8142	0xAC03	#HANGUL SYLLABLE KIYEOK A KIYEOKSIOS
+0x8143	0xAC05	#HANGUL SYLLABLE KIYEOK A NIEUNCIEUC
+0x8144	0xAC06	#HANGUL SYLLABLE KIYEOK A NIEUNHIEUH
+0x8145	0xAC0B	#HANGUL SYLLABLE KIYEOK A RIEULPIEUP
+0x8146	0xAC0C	#HANGUL SYLLABLE KIYEOK A RIEULSIOS
+0x8147	0xAC0D	#HANGUL SYLLABLE KIYEOK A RIEULTHIEUTH
+0x8148	0xAC0E	#HANGUL SYLLABLE KIYEOK A RIEULPHIEUPH
+0x8149	0xAC0F	#HANGUL SYLLABLE KIYEOK A RIEULHIEUH
+0x814A	0xAC18	#HANGUL SYLLABLE KIYEOK A KHIEUKH
+0x814B	0xAC1E	#HANGUL SYLLABLE KIYEOK AE SSANGKIYEOK
+0x814C	0xAC1F	#HANGUL SYLLABLE KIYEOK AE KIYEOKSIOS
+0x814D	0xAC21	#HANGUL SYLLABLE KIYEOK AE NIEUNCIEUC
+0x814E	0xAC22	#HANGUL SYLLABLE KIYEOK AE NIEUNHIEUH
+0x814F	0xAC23	#HANGUL SYLLABLE KIYEOK AE TIKEUT
+0x8150	0xAC25	#HANGUL SYLLABLE KIYEOK AE RIEULKIYEOK
+0x8151	0xAC26	#HANGUL SYLLABLE KIYEOK AE RIEULMIEUM
+0x8152	0xAC27	#HANGUL SYLLABLE KIYEOK AE RIEULPIEUP
+0x8153	0xAC28	#HANGUL SYLLABLE KIYEOK AE RIEULSIOS
+0x8154	0xAC29	#HANGUL SYLLABLE KIYEOK AE RIEULTHIEUTH
+0x8155	0xAC2A	#HANGUL SYLLABLE KIYEOK AE RIEULPHIEUPH
+0x8156	0xAC2B	#HANGUL SYLLABLE KIYEOK AE RIEULHIEUH
+0x8157	0xAC2E	#HANGUL SYLLABLE KIYEOK AE PIEUPSIOS
+0x8158	0xAC32	#HANGUL SYLLABLE KIYEOK AE CIEUC
+0x8159	0xAC33	#HANGUL SYLLABLE KIYEOK AE CHIEUCH
+0x815A	0xAC34	#HANGUL SYLLABLE KIYEOK AE KHIEUKH
+0x8161	0xAC35	#HANGUL SYLLABLE KIYEOK AE THIEUTH
+0x8162	0xAC36	#HANGUL SYLLABLE KIYEOK AE PHIEUPH
+0x8163	0xAC37	#HANGUL SYLLABLE KIYEOK AE HIEUH
+0x8164	0xAC3A	#HANGUL SYLLABLE KIYEOK YA SSANGKIYEOK
+0x8165	0xAC3B	#HANGUL SYLLABLE KIYEOK YA KIYEOKSIOS
+0x8166	0xAC3D	#HANGUL SYLLABLE KIYEOK YA NIEUNCIEUC
+0x8167	0xAC3E	#HANGUL SYLLABLE KIYEOK YA NIEUNHIEUH
+0x8168	0xAC3F	#HANGUL SYLLABLE KIYEOK YA TIKEUT
+0x8169	0xAC41	#HANGUL SYLLABLE KIYEOK YA RIEULKIYEOK
+0x816A	0xAC42	#HANGUL SYLLABLE KIYEOK YA RIEULMIEUM
+0x816B	0xAC43	#HANGUL SYLLABLE KIYEOK YA RIEULPIEUP
+0x816C	0xAC44	#HANGUL SYLLABLE KIYEOK YA RIEULSIOS
+0x816D	0xAC45	#HANGUL SYLLABLE KIYEOK YA RIEULTHIEUTH
+0x816E	0xAC46	#HANGUL SYLLABLE KIYEOK YA RIEULPHIEUPH
+0x816F	0xAC47	#HANGUL SYLLABLE KIYEOK YA RIEULHIEUH
+0x8170	0xAC48	#HANGUL SYLLABLE KIYEOK YA MIEUM
+0x8171	0xAC49	#HANGUL SYLLABLE KIYEOK YA PIEUP
+0x8172	0xAC4A	#HANGUL SYLLABLE KIYEOK YA PIEUPSIOS
+0x8173	0xAC4C	#HANGUL SYLLABLE KIYEOK YA SSANGSIOS
+0x8174	0xAC4E	#HANGUL SYLLABLE KIYEOK YA CIEUC
+0x8175	0xAC4F	#HANGUL SYLLABLE KIYEOK YA CHIEUCH
+0x8176	0xAC50	#HANGUL SYLLABLE KIYEOK YA KHIEUKH
+0x8177	0xAC51	#HANGUL SYLLABLE KIYEOK YA THIEUTH
+0x8178	0xAC52	#HANGUL SYLLABLE KIYEOK YA PHIEUPH
+0x8179	0xAC53	#HANGUL SYLLABLE KIYEOK YA HIEUH
+0x817A	0xAC55	#HANGUL SYLLABLE KIYEOK YAE KIYEOK
+0x8181	0xAC56	#HANGUL SYLLABLE KIYEOK YAE SSANGKIYEOK
+0x8182	0xAC57	#HANGUL SYLLABLE KIYEOK YAE KIYEOKSIOS
+0x8183	0xAC59	#HANGUL SYLLABLE KIYEOK YAE NIEUNCIEUC
+0x8184	0xAC5A	#HANGUL SYLLABLE KIYEOK YAE NIEUNHIEUH
+0x8185	0xAC5B	#HANGUL SYLLABLE KIYEOK YAE TIKEUT
+0x8186	0xAC5D	#HANGUL SYLLABLE KIYEOK YAE RIEULKIYEOK
+0x8187	0xAC5E	#HANGUL SYLLABLE KIYEOK YAE RIEULMIEUM
+0x8188	0xAC5F	#HANGUL SYLLABLE KIYEOK YAE RIEULPIEUP
+0x8189	0xAC60	#HANGUL SYLLABLE KIYEOK YAE RIEULSIOS
+0x818A	0xAC61	#HANGUL SYLLABLE KIYEOK YAE RIEULTHIEUTH
+0x818B	0xAC62	#HANGUL SYLLABLE KIYEOK YAE RIEULPHIEUPH
+0x818C	0xAC63	#HANGUL SYLLABLE KIYEOK YAE RIEULHIEUH
+0x818D	0xAC64	#HANGUL SYLLABLE KIYEOK YAE MIEUM
+0x818E	0xAC65	#HANGUL SYLLABLE KIYEOK YAE PIEUP
+0x818F	0xAC66	#HANGUL SYLLABLE KIYEOK YAE PIEUPSIOS
+0x8190	0xAC67	#HANGUL SYLLABLE KIYEOK YAE SIOS
+0x8191	0xAC68	#HANGUL SYLLABLE KIYEOK YAE SSANGSIOS
+0x8192	0xAC69	#HANGUL SYLLABLE KIYEOK YAE IEUNG
+0x8193	0xAC6A	#HANGUL SYLLABLE KIYEOK YAE CIEUC
+0x8194	0xAC6B	#HANGUL SYLLABLE KIYEOK YAE CHIEUCH
+0x8195	0xAC6C	#HANGUL SYLLABLE KIYEOK YAE KHIEUKH
+0x8196	0xAC6D	#HANGUL SYLLABLE KIYEOK YAE THIEUTH
+0x8197	0xAC6E	#HANGUL SYLLABLE KIYEOK YAE PHIEUPH
+0x8198	0xAC6F	#HANGUL SYLLABLE KIYEOK YAE HIEUH
+0x8199	0xAC72	#HANGUL SYLLABLE KIYEOK EO SSANGKIYEOK
+0x819A	0xAC73	#HANGUL SYLLABLE KIYEOK EO KIYEOKSIOS
+0x819B	0xAC75	#HANGUL SYLLABLE KIYEOK EO NIEUNCIEUC
+0x819C	0xAC76	#HANGUL SYLLABLE KIYEOK EO NIEUNHIEUH
+0x819D	0xAC79	#HANGUL SYLLABLE KIYEOK EO RIEULKIYEOK
+0x819E	0xAC7B	#HANGUL SYLLABLE KIYEOK EO RIEULPIEUP
+0x819F	0xAC7C	#HANGUL SYLLABLE KIYEOK EO RIEULSIOS
+0x81A0	0xAC7D	#HANGUL SYLLABLE KIYEOK EO RIEULTHIEUTH
+0x81A1	0xAC7E	#HANGUL SYLLABLE KIYEOK EO RIEULPHIEUPH
+0x81A2	0xAC7F	#HANGUL SYLLABLE KIYEOK EO RIEULHIEUH
+0x81A3	0xAC82	#HANGUL SYLLABLE KIYEOK EO PIEUPSIOS
+0x81A4	0xAC87	#HANGUL SYLLABLE KIYEOK EO CHIEUCH
+0x81A5	0xAC88	#HANGUL SYLLABLE KIYEOK EO KHIEUKH
+0x81A6	0xAC8D	#HANGUL SYLLABLE KIYEOK E KIYEOK
+0x81A7	0xAC8E	#HANGUL SYLLABLE KIYEOK E SSANGKIYEOK
+0x81A8	0xAC8F	#HANGUL SYLLABLE KIYEOK E KIYEOKSIOS
+0x81A9	0xAC91	#HANGUL SYLLABLE KIYEOK E NIEUNCIEUC
+0x81AA	0xAC92	#HANGUL SYLLABLE KIYEOK E NIEUNHIEUH
+0x81AB	0xAC93	#HANGUL SYLLABLE KIYEOK E TIKEUT
+0x81AC	0xAC95	#HANGUL SYLLABLE KIYEOK E RIEULKIYEOK
+0x81AD	0xAC96	#HANGUL SYLLABLE KIYEOK E RIEULMIEUM
+0x81AE	0xAC97	#HANGUL SYLLABLE KIYEOK E RIEULPIEUP
+0x81AF	0xAC98	#HANGUL SYLLABLE KIYEOK E RIEULSIOS
+0x81B0	0xAC99	#HANGUL SYLLABLE KIYEOK E RIEULTHIEUTH
+0x81B1	0xAC9A	#HANGUL SYLLABLE KIYEOK E RIEULPHIEUPH
+0x81B2	0xAC9B	#HANGUL SYLLABLE KIYEOK E RIEULHIEUH
+0x81B3	0xAC9E	#HANGUL SYLLABLE KIYEOK E PIEUPSIOS
+0x81B4	0xACA2	#HANGUL SYLLABLE KIYEOK E CIEUC
+0x81B5	0xACA3	#HANGUL SYLLABLE KIYEOK E CHIEUCH
+0x81B6	0xACA4	#HANGUL SYLLABLE KIYEOK E KHIEUKH
+0x81B7	0xACA5	#HANGUL SYLLABLE KIYEOK E THIEUTH
+0x81B8	0xACA6	#HANGUL SYLLABLE KIYEOK E PHIEUPH
+0x81B9	0xACA7	#HANGUL SYLLABLE KIYEOK E HIEUH
+0x81BA	0xACAB	#HANGUL SYLLABLE KIYEOK YEO KIYEOKSIOS
+0x81BB	0xACAD	#HANGUL SYLLABLE KIYEOK YEO NIEUNCIEUC
+0x81BC	0xACAE	#HANGUL SYLLABLE KIYEOK YEO NIEUNHIEUH
+0x81BD	0xACB1	#HANGUL SYLLABLE KIYEOK YEO RIEULKIYEOK
+0x81BE	0xACB2	#HANGUL SYLLABLE KIYEOK YEO RIEULMIEUM
+0x81BF	0xACB3	#HANGUL SYLLABLE KIYEOK YEO RIEULPIEUP
+0x81C0	0xACB4	#HANGUL SYLLABLE KIYEOK YEO RIEULSIOS
+0x81C1	0xACB5	#HANGUL SYLLABLE KIYEOK YEO RIEULTHIEUTH
+0x81C2	0xACB6	#HANGUL SYLLABLE KIYEOK YEO RIEULPHIEUPH
+0x81C3	0xACB7	#HANGUL SYLLABLE KIYEOK YEO RIEULHIEUH
+0x81C4	0xACBA	#HANGUL SYLLABLE KIYEOK YEO PIEUPSIOS
+0x81C5	0xACBE	#HANGUL SYLLABLE KIYEOK YEO CIEUC
+0x81C6	0xACBF	#HANGUL SYLLABLE KIYEOK YEO CHIEUCH
+0x81C7	0xACC0	#HANGUL SYLLABLE KIYEOK YEO KHIEUKH
+0x81C8	0xACC2	#HANGUL SYLLABLE KIYEOK YEO PHIEUPH
+0x81C9	0xACC3	#HANGUL SYLLABLE KIYEOK YEO HIEUH
+0x81CA	0xACC5	#HANGUL SYLLABLE KIYEOK YE KIYEOK
+0x81CB	0xACC6	#HANGUL SYLLABLE KIYEOK YE SSANGKIYEOK
+0x81CC	0xACC7	#HANGUL SYLLABLE KIYEOK YE KIYEOKSIOS
+0x81CD	0xACC9	#HANGUL SYLLABLE KIYEOK YE NIEUNCIEUC
+0x81CE	0xACCA	#HANGUL SYLLABLE KIYEOK YE NIEUNHIEUH
+0x81CF	0xACCB	#HANGUL SYLLABLE KIYEOK YE TIKEUT
+0x81D0	0xACCD	#HANGUL SYLLABLE KIYEOK YE RIEULKIYEOK
+0x81D1	0xACCE	#HANGUL SYLLABLE KIYEOK YE RIEULMIEUM
+0x81D2	0xACCF	#HANGUL SYLLABLE KIYEOK YE RIEULPIEUP
+0x81D3	0xACD0	#HANGUL SYLLABLE KIYEOK YE RIEULSIOS
+0x81D4	0xACD1	#HANGUL SYLLABLE KIYEOK YE RIEULTHIEUTH
+0x81D5	0xACD2	#HANGUL SYLLABLE KIYEOK YE RIEULPHIEUPH
+0x81D6	0xACD3	#HANGUL SYLLABLE KIYEOK YE RIEULHIEUH
+0x81D7	0xACD4	#HANGUL SYLLABLE KIYEOK YE MIEUM
+0x81D8	0xACD6	#HANGUL SYLLABLE KIYEOK YE PIEUPSIOS
+0x81D9	0xACD8	#HANGUL SYLLABLE KIYEOK YE SSANGSIOS
+0x81DA	0xACD9	#HANGUL SYLLABLE KIYEOK YE IEUNG
+0x81DB	0xACDA	#HANGUL SYLLABLE KIYEOK YE CIEUC
+0x81DC	0xACDB	#HANGUL SYLLABLE KIYEOK YE CHIEUCH
+0x81DD	0xACDC	#HANGUL SYLLABLE KIYEOK YE KHIEUKH
+0x81DE	0xACDD	#HANGUL SYLLABLE KIYEOK YE THIEUTH
+0x81DF	0xACDE	#HANGUL SYLLABLE KIYEOK YE PHIEUPH
+0x81E0	0xACDF	#HANGUL SYLLABLE KIYEOK YE HIEUH
+0x81E1	0xACE2	#HANGUL SYLLABLE KIYEOK O SSANGKIYEOK
+0x81E2	0xACE3	#HANGUL SYLLABLE KIYEOK O KIYEOKSIOS
+0x81E3	0xACE5	#HANGUL SYLLABLE KIYEOK O NIEUNCIEUC
+0x81E4	0xACE6	#HANGUL SYLLABLE KIYEOK O NIEUNHIEUH
+0x81E5	0xACE9	#HANGUL SYLLABLE KIYEOK O RIEULKIYEOK
+0x81E6	0xACEB	#HANGUL SYLLABLE KIYEOK O RIEULPIEUP
+0x81E7	0xACED	#HANGUL SYLLABLE KIYEOK O RIEULTHIEUTH
+0x81E8	0xACEE	#HANGUL SYLLABLE KIYEOK O RIEULPHIEUPH
+0x81E9	0xACF2	#HANGUL SYLLABLE KIYEOK O PIEUPSIOS
+0x81EA	0xACF4	#HANGUL SYLLABLE KIYEOK O SSANGSIOS
+0x81EB	0xACF7	#HANGUL SYLLABLE KIYEOK O CHIEUCH
+0x81EC	0xACF8	#HANGUL SYLLABLE KIYEOK O KHIEUKH
+0x81ED	0xACF9	#HANGUL SYLLABLE KIYEOK O THIEUTH
+0x81EE	0xACFA	#HANGUL SYLLABLE KIYEOK O PHIEUPH
+0x81EF	0xACFB	#HANGUL SYLLABLE KIYEOK O HIEUH
+0x81F0	0xACFE	#HANGUL SYLLABLE KIYEOK WA SSANGKIYEOK
+0x81F1	0xACFF	#HANGUL SYLLABLE KIYEOK WA KIYEOKSIOS
+0x81F2	0xAD01	#HANGUL SYLLABLE KIYEOK WA NIEUNCIEUC
+0x81F3	0xAD02	#HANGUL SYLLABLE KIYEOK WA NIEUNHIEUH
+0x81F4	0xAD03	#HANGUL SYLLABLE KIYEOK WA TIKEUT
+0x81F5	0xAD05	#HANGUL SYLLABLE KIYEOK WA RIEULKIYEOK
+0x81F6	0xAD07	#HANGUL SYLLABLE KIYEOK WA RIEULPIEUP
+0x81F7	0xAD08	#HANGUL SYLLABLE KIYEOK WA RIEULSIOS
+0x81F8	0xAD09	#HANGUL SYLLABLE KIYEOK WA RIEULTHIEUTH
+0x81F9	0xAD0A	#HANGUL SYLLABLE KIYEOK WA RIEULPHIEUPH
+0x81FA	0xAD0B	#HANGUL SYLLABLE KIYEOK WA RIEULHIEUH
+0x81FB	0xAD0E	#HANGUL SYLLABLE KIYEOK WA PIEUPSIOS
+0x81FC	0xAD10	#HANGUL SYLLABLE KIYEOK WA SSANGSIOS
+0x81FD	0xAD12	#HANGUL SYLLABLE KIYEOK WA CIEUC
+0x81FE	0xAD13	#HANGUL SYLLABLE KIYEOK WA CHIEUCH
+0x8241	0xAD14	#HANGUL SYLLABLE KIYEOK WA KHIEUKH
+0x8242	0xAD15	#HANGUL SYLLABLE KIYEOK WA THIEUTH
+0x8243	0xAD16	#HANGUL SYLLABLE KIYEOK WA PHIEUPH
+0x8244	0xAD17	#HANGUL SYLLABLE KIYEOK WA HIEUH
+0x8245	0xAD19	#HANGUL SYLLABLE KIYEOK WAE KIYEOK
+0x8246	0xAD1A	#HANGUL SYLLABLE KIYEOK WAE SSANGKIYEOK
+0x8247	0xAD1B	#HANGUL SYLLABLE KIYEOK WAE KIYEOKSIOS
+0x8248	0xAD1D	#HANGUL SYLLABLE KIYEOK WAE NIEUNCIEUC
+0x8249	0xAD1E	#HANGUL SYLLABLE KIYEOK WAE NIEUNHIEUH
+0x824A	0xAD1F	#HANGUL SYLLABLE KIYEOK WAE TIKEUT
+0x824B	0xAD21	#HANGUL SYLLABLE KIYEOK WAE RIEULKIYEOK
+0x824C	0xAD22	#HANGUL SYLLABLE KIYEOK WAE RIEULMIEUM
+0x824D	0xAD23	#HANGUL SYLLABLE KIYEOK WAE RIEULPIEUP
+0x824E	0xAD24	#HANGUL SYLLABLE KIYEOK WAE RIEULSIOS
+0x824F	0xAD25	#HANGUL SYLLABLE KIYEOK WAE RIEULTHIEUTH
+0x8250	0xAD26	#HANGUL SYLLABLE KIYEOK WAE RIEULPHIEUPH
+0x8251	0xAD27	#HANGUL SYLLABLE KIYEOK WAE RIEULHIEUH
+0x8252	0xAD28	#HANGUL SYLLABLE KIYEOK WAE MIEUM
+0x8253	0xAD2A	#HANGUL SYLLABLE KIYEOK WAE PIEUPSIOS
+0x8254	0xAD2B	#HANGUL SYLLABLE KIYEOK WAE SIOS
+0x8255	0xAD2E	#HANGUL SYLLABLE KIYEOK WAE CIEUC
+0x8256	0xAD2F	#HANGUL SYLLABLE KIYEOK WAE CHIEUCH
+0x8257	0xAD30	#HANGUL SYLLABLE KIYEOK WAE KHIEUKH
+0x8258	0xAD31	#HANGUL SYLLABLE KIYEOK WAE THIEUTH
+0x8259	0xAD32	#HANGUL SYLLABLE KIYEOK WAE PHIEUPH
+0x825A	0xAD33	#HANGUL SYLLABLE KIYEOK WAE HIEUH
+0x8261	0xAD36	#HANGUL SYLLABLE KIYEOK OE SSANGKIYEOK
+0x8262	0xAD37	#HANGUL SYLLABLE KIYEOK OE KIYEOKSIOS
+0x8263	0xAD39	#HANGUL SYLLABLE KIYEOK OE NIEUNCIEUC
+0x8264	0xAD3A	#HANGUL SYLLABLE KIYEOK OE NIEUNHIEUH
+0x8265	0xAD3B	#HANGUL SYLLABLE KIYEOK OE TIKEUT
+0x8266	0xAD3D	#HANGUL SYLLABLE KIYEOK OE RIEULKIYEOK
+0x8267	0xAD3E	#HANGUL SYLLABLE KIYEOK OE RIEULMIEUM
+0x8268	0xAD3F	#HANGUL SYLLABLE KIYEOK OE RIEULPIEUP
+0x8269	0xAD40	#HANGUL SYLLABLE KIYEOK OE RIEULSIOS
+0x826A	0xAD41	#HANGUL SYLLABLE KIYEOK OE RIEULTHIEUTH
+0x826B	0xAD42	#HANGUL SYLLABLE KIYEOK OE RIEULPHIEUPH
+0x826C	0xAD43	#HANGUL SYLLABLE KIYEOK OE RIEULHIEUH
+0x826D	0xAD46	#HANGUL SYLLABLE KIYEOK OE PIEUPSIOS
+0x826E	0xAD48	#HANGUL SYLLABLE KIYEOK OE SSANGSIOS
+0x826F	0xAD4A	#HANGUL SYLLABLE KIYEOK OE CIEUC
+0x8270	0xAD4B	#HANGUL SYLLABLE KIYEOK OE CHIEUCH
+0x8271	0xAD4C	#HANGUL SYLLABLE KIYEOK OE KHIEUKH
+0x8272	0xAD4D	#HANGUL SYLLABLE KIYEOK OE THIEUTH
+0x8273	0xAD4E	#HANGUL SYLLABLE KIYEOK OE PHIEUPH
+0x8274	0xAD4F	#HANGUL SYLLABLE KIYEOK OE HIEUH
+0x8275	0xAD51	#HANGUL SYLLABLE KIYEOK YO KIYEOK
+0x8276	0xAD52	#HANGUL SYLLABLE KIYEOK YO SSANGKIYEOK
+0x8277	0xAD53	#HANGUL SYLLABLE KIYEOK YO KIYEOKSIOS
+0x8278	0xAD55	#HANGUL SYLLABLE KIYEOK YO NIEUNCIEUC
+0x8279	0xAD56	#HANGUL SYLLABLE KIYEOK YO NIEUNHIEUH
+0x827A	0xAD57	#HANGUL SYLLABLE KIYEOK YO TIKEUT
+0x8281	0xAD59	#HANGUL SYLLABLE KIYEOK YO RIEULKIYEOK
+0x8282	0xAD5A	#HANGUL SYLLABLE KIYEOK YO RIEULMIEUM
+0x8283	0xAD5B	#HANGUL SYLLABLE KIYEOK YO RIEULPIEUP
+0x8284	0xAD5C	#HANGUL SYLLABLE KIYEOK YO RIEULSIOS
+0x8285	0xAD5D	#HANGUL SYLLABLE KIYEOK YO RIEULTHIEUTH
+0x8286	0xAD5E	#HANGUL SYLLABLE KIYEOK YO RIEULPHIEUPH
+0x8287	0xAD5F	#HANGUL SYLLABLE KIYEOK YO RIEULHIEUH
+0x8288	0xAD60	#HANGUL SYLLABLE KIYEOK YO MIEUM
+0x8289	0xAD62	#HANGUL SYLLABLE KIYEOK YO PIEUPSIOS
+0x828A	0xAD64	#HANGUL SYLLABLE KIYEOK YO SSANGSIOS
+0x828B	0xAD65	#HANGUL SYLLABLE KIYEOK YO IEUNG
+0x828C	0xAD66	#HANGUL SYLLABLE KIYEOK YO CIEUC
+0x828D	0xAD67	#HANGUL SYLLABLE KIYEOK YO CHIEUCH
+0x828E	0xAD68	#HANGUL SYLLABLE KIYEOK YO KHIEUKH
+0x828F	0xAD69	#HANGUL SYLLABLE KIYEOK YO THIEUTH
+0x8290	0xAD6A	#HANGUL SYLLABLE KIYEOK YO PHIEUPH
+0x8291	0xAD6B	#HANGUL SYLLABLE KIYEOK YO HIEUH
+0x8292	0xAD6E	#HANGUL SYLLABLE KIYEOK U SSANGKIYEOK
+0x8293	0xAD6F	#HANGUL SYLLABLE KIYEOK U KIYEOKSIOS
+0x8294	0xAD71	#HANGUL SYLLABLE KIYEOK U NIEUNCIEUC
+0x8295	0xAD72	#HANGUL SYLLABLE KIYEOK U NIEUNHIEUH
+0x8296	0xAD77	#HANGUL SYLLABLE KIYEOK U RIEULPIEUP
+0x8297	0xAD78	#HANGUL SYLLABLE KIYEOK U RIEULSIOS
+0x8298	0xAD79	#HANGUL SYLLABLE KIYEOK U RIEULTHIEUTH
+0x8299	0xAD7A	#HANGUL SYLLABLE KIYEOK U RIEULPHIEUPH
+0x829A	0xAD7E	#HANGUL SYLLABLE KIYEOK U PIEUPSIOS
+0x829B	0xAD80	#HANGUL SYLLABLE KIYEOK U SSANGSIOS
+0x829C	0xAD83	#HANGUL SYLLABLE KIYEOK U CHIEUCH
+0x829D	0xAD84	#HANGUL SYLLABLE KIYEOK U KHIEUKH
+0x829E	0xAD85	#HANGUL SYLLABLE KIYEOK U THIEUTH
+0x829F	0xAD86	#HANGUL SYLLABLE KIYEOK U PHIEUPH
+0x82A0	0xAD87	#HANGUL SYLLABLE KIYEOK U HIEUH
+0x82A1	0xAD8A	#HANGUL SYLLABLE KIYEOK WEO SSANGKIYEOK
+0x82A2	0xAD8B	#HANGUL SYLLABLE KIYEOK WEO KIYEOKSIOS
+0x82A3	0xAD8D	#HANGUL SYLLABLE KIYEOK WEO NIEUNCIEUC
+0x82A4	0xAD8E	#HANGUL SYLLABLE KIYEOK WEO NIEUNHIEUH
+0x82A5	0xAD8F	#HANGUL SYLLABLE KIYEOK WEO TIKEUT
+0x82A6	0xAD91	#HANGUL SYLLABLE KIYEOK WEO RIEULKIYEOK
+0x82A7	0xAD92	#HANGUL SYLLABLE KIYEOK WEO RIEULMIEUM
+0x82A8	0xAD93	#HANGUL SYLLABLE KIYEOK WEO RIEULPIEUP
+0x82A9	0xAD94	#HANGUL SYLLABLE KIYEOK WEO RIEULSIOS
+0x82AA	0xAD95	#HANGUL SYLLABLE KIYEOK WEO RIEULTHIEUTH
+0x82AB	0xAD96	#HANGUL SYLLABLE KIYEOK WEO RIEULPHIEUPH
+0x82AC	0xAD97	#HANGUL SYLLABLE KIYEOK WEO RIEULHIEUH
+0x82AD	0xAD98	#HANGUL SYLLABLE KIYEOK WEO MIEUM
+0x82AE	0xAD99	#HANGUL SYLLABLE KIYEOK WEO PIEUP
+0x82AF	0xAD9A	#HANGUL SYLLABLE KIYEOK WEO PIEUPSIOS
+0x82B0	0xAD9B	#HANGUL SYLLABLE KIYEOK WEO SIOS
+0x82B1	0xAD9E	#HANGUL SYLLABLE KIYEOK WEO CIEUC
+0x82B2	0xAD9F	#HANGUL SYLLABLE KIYEOK WEO CHIEUCH
+0x82B3	0xADA0	#HANGUL SYLLABLE KIYEOK WEO KHIEUKH
+0x82B4	0xADA1	#HANGUL SYLLABLE KIYEOK WEO THIEUTH
+0x82B5	0xADA2	#HANGUL SYLLABLE KIYEOK WEO PHIEUPH
+0x82B6	0xADA3	#HANGUL SYLLABLE KIYEOK WEO HIEUH
+0x82B7	0xADA5	#HANGUL SYLLABLE KIYEOK WE KIYEOK
+0x82B8	0xADA6	#HANGUL SYLLABLE KIYEOK WE SSANGKIYEOK
+0x82B9	0xADA7	#HANGUL SYLLABLE KIYEOK WE KIYEOKSIOS
+0x82BA	0xADA8	#HANGUL SYLLABLE KIYEOK WE NIEUN
+0x82BB	0xADA9	#HANGUL SYLLABLE KIYEOK WE NIEUNCIEUC
+0x82BC	0xADAA	#HANGUL SYLLABLE KIYEOK WE NIEUNHIEUH
+0x82BD	0xADAB	#HANGUL SYLLABLE KIYEOK WE TIKEUT
+0x82BE	0xADAC	#HANGUL SYLLABLE KIYEOK WE RIEUL
+0x82BF	0xADAD	#HANGUL SYLLABLE KIYEOK WE RIEULKIYEOK
+0x82C0	0xADAE	#HANGUL SYLLABLE KIYEOK WE RIEULMIEUM
+0x82C1	0xADAF	#HANGUL SYLLABLE KIYEOK WE RIEULPIEUP
+0x82C2	0xADB0	#HANGUL SYLLABLE KIYEOK WE RIEULSIOS
+0x82C3	0xADB1	#HANGUL SYLLABLE KIYEOK WE RIEULTHIEUTH
+0x82C4	0xADB2	#HANGUL SYLLABLE KIYEOK WE RIEULPHIEUPH
+0x82C5	0xADB3	#HANGUL SYLLABLE KIYEOK WE RIEULHIEUH
+0x82C6	0xADB4	#HANGUL SYLLABLE KIYEOK WE MIEUM
+0x82C7	0xADB5	#HANGUL SYLLABLE KIYEOK WE PIEUP
+0x82C8	0xADB6	#HANGUL SYLLABLE KIYEOK WE PIEUPSIOS
+0x82C9	0xADB8	#HANGUL SYLLABLE KIYEOK WE SSANGSIOS
+0x82CA	0xADB9	#HANGUL SYLLABLE KIYEOK WE IEUNG
+0x82CB	0xADBA	#HANGUL SYLLABLE KIYEOK WE CIEUC
+0x82CC	0xADBB	#HANGUL SYLLABLE KIYEOK WE CHIEUCH
+0x82CD	0xADBC	#HANGUL SYLLABLE KIYEOK WE KHIEUKH
+0x82CE	0xADBD	#HANGUL SYLLABLE KIYEOK WE THIEUTH
+0x82CF	0xADBE	#HANGUL SYLLABLE KIYEOK WE PHIEUPH
+0x82D0	0xADBF	#HANGUL SYLLABLE KIYEOK WE HIEUH
+0x82D1	0xADC2	#HANGUL SYLLABLE KIYEOK WI SSANGKIYEOK
+0x82D2	0xADC3	#HANGUL SYLLABLE KIYEOK WI KIYEOKSIOS
+0x82D3	0xADC5	#HANGUL SYLLABLE KIYEOK WI NIEUNCIEUC
+0x82D4	0xADC6	#HANGUL SYLLABLE KIYEOK WI NIEUNHIEUH
+0x82D5	0xADC7	#HANGUL SYLLABLE KIYEOK WI TIKEUT
+0x82D6	0xADC9	#HANGUL SYLLABLE KIYEOK WI RIEULKIYEOK
+0x82D7	0xADCA	#HANGUL SYLLABLE KIYEOK WI RIEULMIEUM
+0x82D8	0xADCB	#HANGUL SYLLABLE KIYEOK WI RIEULPIEUP
+0x82D9	0xADCC	#HANGUL SYLLABLE KIYEOK WI RIEULSIOS
+0x82DA	0xADCD	#HANGUL SYLLABLE KIYEOK WI RIEULTHIEUTH
+0x82DB	0xADCE	#HANGUL SYLLABLE KIYEOK WI RIEULPHIEUPH
+0x82DC	0xADCF	#HANGUL SYLLABLE KIYEOK WI RIEULHIEUH
+0x82DD	0xADD2	#HANGUL SYLLABLE KIYEOK WI PIEUPSIOS
+0x82DE	0xADD4	#HANGUL SYLLABLE KIYEOK WI SSANGSIOS
+0x82DF	0xADD5	#HANGUL SYLLABLE KIYEOK WI IEUNG
+0x82E0	0xADD6	#HANGUL SYLLABLE KIYEOK WI CIEUC
+0x82E1	0xADD7	#HANGUL SYLLABLE KIYEOK WI CHIEUCH
+0x82E2	0xADD8	#HANGUL SYLLABLE KIYEOK WI KHIEUKH
+0x82E3	0xADD9	#HANGUL SYLLABLE KIYEOK WI THIEUTH
+0x82E4	0xADDA	#HANGUL SYLLABLE KIYEOK WI PHIEUPH
+0x82E5	0xADDB	#HANGUL SYLLABLE KIYEOK WI HIEUH
+0x82E6	0xADDD	#HANGUL SYLLABLE KIYEOK YU KIYEOK
+0x82E7	0xADDE	#HANGUL SYLLABLE KIYEOK YU SSANGKIYEOK
+0x82E8	0xADDF	#HANGUL SYLLABLE KIYEOK YU KIYEOKSIOS
+0x82E9	0xADE1	#HANGUL SYLLABLE KIYEOK YU NIEUNCIEUC
+0x82EA	0xADE2	#HANGUL SYLLABLE KIYEOK YU NIEUNHIEUH
+0x82EB	0xADE3	#HANGUL SYLLABLE KIYEOK YU TIKEUT
+0x82EC	0xADE5	#HANGUL SYLLABLE KIYEOK YU RIEULKIYEOK
+0x82ED	0xADE6	#HANGUL SYLLABLE KIYEOK YU RIEULMIEUM
+0x82EE	0xADE7	#HANGUL SYLLABLE KIYEOK YU RIEULPIEUP
+0x82EF	0xADE8	#HANGUL SYLLABLE KIYEOK YU RIEULSIOS
+0x82F0	0xADE9	#HANGUL SYLLABLE KIYEOK YU RIEULTHIEUTH
+0x82F1	0xADEA	#HANGUL SYLLABLE KIYEOK YU RIEULPHIEUPH
+0x82F2	0xADEB	#HANGUL SYLLABLE KIYEOK YU RIEULHIEUH
+0x82F3	0xADEC	#HANGUL SYLLABLE KIYEOK YU MIEUM
+0x82F4	0xADED	#HANGUL SYLLABLE KIYEOK YU PIEUP
+0x82F5	0xADEE	#HANGUL SYLLABLE KIYEOK YU PIEUPSIOS
+0x82F6	0xADEF	#HANGUL SYLLABLE KIYEOK YU SIOS
+0x82F7	0xADF0	#HANGUL SYLLABLE KIYEOK YU SSANGSIOS
+0x82F8	0xADF1	#HANGUL SYLLABLE KIYEOK YU IEUNG
+0x82F9	0xADF2	#HANGUL SYLLABLE KIYEOK YU CIEUC
+0x82FA	0xADF3	#HANGUL SYLLABLE KIYEOK YU CHIEUCH
+0x82FB	0xADF4	#HANGUL SYLLABLE KIYEOK YU KHIEUKH
+0x82FC	0xADF5	#HANGUL SYLLABLE KIYEOK YU THIEUTH
+0x82FD	0xADF6	#HANGUL SYLLABLE KIYEOK YU PHIEUPH
+0x82FE	0xADF7	#HANGUL SYLLABLE KIYEOK YU HIEUH
+0x8341	0xADFA	#HANGUL SYLLABLE KIYEOK EU SSANGKIYEOK
+0x8342	0xADFB	#HANGUL SYLLABLE KIYEOK EU KIYEOKSIOS
+0x8343	0xADFD	#HANGUL SYLLABLE KIYEOK EU NIEUNCIEUC
+0x8344	0xADFE	#HANGUL SYLLABLE KIYEOK EU NIEUNHIEUH
+0x8345	0xAE02	#HANGUL SYLLABLE KIYEOK EU RIEULMIEUM
+0x8346	0xAE03	#HANGUL SYLLABLE KIYEOK EU RIEULPIEUP
+0x8347	0xAE04	#HANGUL SYLLABLE KIYEOK EU RIEULSIOS
+0x8348	0xAE05	#HANGUL SYLLABLE KIYEOK EU RIEULTHIEUTH
+0x8349	0xAE06	#HANGUL SYLLABLE KIYEOK EU RIEULPHIEUPH
+0x834A	0xAE07	#HANGUL SYLLABLE KIYEOK EU RIEULHIEUH
+0x834B	0xAE0A	#HANGUL SYLLABLE KIYEOK EU PIEUPSIOS
+0x834C	0xAE0C	#HANGUL SYLLABLE KIYEOK EU SSANGSIOS
+0x834D	0xAE0E	#HANGUL SYLLABLE KIYEOK EU CIEUC
+0x834E	0xAE0F	#HANGUL SYLLABLE KIYEOK EU CHIEUCH
+0x834F	0xAE10	#HANGUL SYLLABLE KIYEOK EU KHIEUKH
+0x8350	0xAE11	#HANGUL SYLLABLE KIYEOK EU THIEUTH
+0x8351	0xAE12	#HANGUL SYLLABLE KIYEOK EU PHIEUPH
+0x8352	0xAE13	#HANGUL SYLLABLE KIYEOK EU HIEUH
+0x8353	0xAE15	#HANGUL SYLLABLE KIYEOK YI KIYEOK
+0x8354	0xAE16	#HANGUL SYLLABLE KIYEOK YI SSANGKIYEOK
+0x8355	0xAE17	#HANGUL SYLLABLE KIYEOK YI KIYEOKSIOS
+0x8356	0xAE18	#HANGUL SYLLABLE KIYEOK YI NIEUN
+0x8357	0xAE19	#HANGUL SYLLABLE KIYEOK YI NIEUNCIEUC
+0x8358	0xAE1A	#HANGUL SYLLABLE KIYEOK YI NIEUNHIEUH
+0x8359	0xAE1B	#HANGUL SYLLABLE KIYEOK YI TIKEUT
+0x835A	0xAE1C	#HANGUL SYLLABLE KIYEOK YI RIEUL
+0x8361	0xAE1D	#HANGUL SYLLABLE KIYEOK YI RIEULKIYEOK
+0x8362	0xAE1E	#HANGUL SYLLABLE KIYEOK YI RIEULMIEUM
+0x8363	0xAE1F	#HANGUL SYLLABLE KIYEOK YI RIEULPIEUP
+0x8364	0xAE20	#HANGUL SYLLABLE KIYEOK YI RIEULSIOS
+0x8365	0xAE21	#HANGUL SYLLABLE KIYEOK YI RIEULTHIEUTH
+0x8366	0xAE22	#HANGUL SYLLABLE KIYEOK YI RIEULPHIEUPH
+0x8367	0xAE23	#HANGUL SYLLABLE KIYEOK YI RIEULHIEUH
+0x8368	0xAE24	#HANGUL SYLLABLE KIYEOK YI MIEUM
+0x8369	0xAE25	#HANGUL SYLLABLE KIYEOK YI PIEUP
+0x836A	0xAE26	#HANGUL SYLLABLE KIYEOK YI PIEUPSIOS
+0x836B	0xAE27	#HANGUL SYLLABLE KIYEOK YI SIOS
+0x836C	0xAE28	#HANGUL SYLLABLE KIYEOK YI SSANGSIOS
+0x836D	0xAE29	#HANGUL SYLLABLE KIYEOK YI IEUNG
+0x836E	0xAE2A	#HANGUL SYLLABLE KIYEOK YI CIEUC
+0x836F	0xAE2B	#HANGUL SYLLABLE KIYEOK YI CHIEUCH
+0x8370	0xAE2C	#HANGUL SYLLABLE KIYEOK YI KHIEUKH
+0x8371	0xAE2D	#HANGUL SYLLABLE KIYEOK YI THIEUTH
+0x8372	0xAE2E	#HANGUL SYLLABLE KIYEOK YI PHIEUPH
+0x8373	0xAE2F	#HANGUL SYLLABLE KIYEOK YI HIEUH
+0x8374	0xAE32	#HANGUL SYLLABLE KIYEOK I SSANGKIYEOK
+0x8375	0xAE33	#HANGUL SYLLABLE KIYEOK I KIYEOKSIOS
+0x8376	0xAE35	#HANGUL SYLLABLE KIYEOK I NIEUNCIEUC
+0x8377	0xAE36	#HANGUL SYLLABLE KIYEOK I NIEUNHIEUH
+0x8378	0xAE39	#HANGUL SYLLABLE KIYEOK I RIEULKIYEOK
+0x8379	0xAE3B	#HANGUL SYLLABLE KIYEOK I RIEULPIEUP
+0x837A	0xAE3C	#HANGUL SYLLABLE KIYEOK I RIEULSIOS
+0x8381	0xAE3D	#HANGUL SYLLABLE KIYEOK I RIEULTHIEUTH
+0x8382	0xAE3E	#HANGUL SYLLABLE KIYEOK I RIEULPHIEUPH
+0x8383	0xAE3F	#HANGUL SYLLABLE KIYEOK I RIEULHIEUH
+0x8384	0xAE42	#HANGUL SYLLABLE KIYEOK I PIEUPSIOS
+0x8385	0xAE44	#HANGUL SYLLABLE KIYEOK I SSANGSIOS
+0x8386	0xAE47	#HANGUL SYLLABLE KIYEOK I CHIEUCH
+0x8387	0xAE48	#HANGUL SYLLABLE KIYEOK I KHIEUKH
+0x8388	0xAE49	#HANGUL SYLLABLE KIYEOK I THIEUTH
+0x8389	0xAE4B	#HANGUL SYLLABLE KIYEOK I HIEUH
+0x838A	0xAE4F	#HANGUL SYLLABLE SSANGKIYEOK A KIYEOKSIOS
+0x838B	0xAE51	#HANGUL SYLLABLE SSANGKIYEOK A NIEUNCIEUC
+0x838C	0xAE52	#HANGUL SYLLABLE SSANGKIYEOK A NIEUNHIEUH
+0x838D	0xAE53	#HANGUL SYLLABLE SSANGKIYEOK A TIKEUT
+0x838E	0xAE55	#HANGUL SYLLABLE SSANGKIYEOK A RIEULKIYEOK
+0x838F	0xAE57	#HANGUL SYLLABLE SSANGKIYEOK A RIEULPIEUP
+0x8390	0xAE58	#HANGUL SYLLABLE SSANGKIYEOK A RIEULSIOS
+0x8391	0xAE59	#HANGUL SYLLABLE SSANGKIYEOK A RIEULTHIEUTH
+0x8392	0xAE5A	#HANGUL SYLLABLE SSANGKIYEOK A RIEULPHIEUPH
+0x8393	0xAE5B	#HANGUL SYLLABLE SSANGKIYEOK A RIEULHIEUH
+0x8394	0xAE5E	#HANGUL SYLLABLE SSANGKIYEOK A PIEUPSIOS
+0x8395	0xAE62	#HANGUL SYLLABLE SSANGKIYEOK A CIEUC
+0x8396	0xAE63	#HANGUL SYLLABLE SSANGKIYEOK A CHIEUCH
+0x8397	0xAE64	#HANGUL SYLLABLE SSANGKIYEOK A KHIEUKH
+0x8398	0xAE66	#HANGUL SYLLABLE SSANGKIYEOK A PHIEUPH
+0x8399	0xAE67	#HANGUL SYLLABLE SSANGKIYEOK A HIEUH
+0x839A	0xAE6A	#HANGUL SYLLABLE SSANGKIYEOK AE SSANGKIYEOK
+0x839B	0xAE6B	#HANGUL SYLLABLE SSANGKIYEOK AE KIYEOKSIOS
+0x839C	0xAE6D	#HANGUL SYLLABLE SSANGKIYEOK AE NIEUNCIEUC
+0x839D	0xAE6E	#HANGUL SYLLABLE SSANGKIYEOK AE NIEUNHIEUH
+0x839E	0xAE6F	#HANGUL SYLLABLE SSANGKIYEOK AE TIKEUT
+0x839F	0xAE71	#HANGUL SYLLABLE SSANGKIYEOK AE RIEULKIYEOK
+0x83A0	0xAE72	#HANGUL SYLLABLE SSANGKIYEOK AE RIEULMIEUM
+0x83A1	0xAE73	#HANGUL SYLLABLE SSANGKIYEOK AE RIEULPIEUP
+0x83A2	0xAE74	#HANGUL SYLLABLE SSANGKIYEOK AE RIEULSIOS
+0x83A3	0xAE75	#HANGUL SYLLABLE SSANGKIYEOK AE RIEULTHIEUTH
+0x83A4	0xAE76	#HANGUL SYLLABLE SSANGKIYEOK AE RIEULPHIEUPH
+0x83A5	0xAE77	#HANGUL SYLLABLE SSANGKIYEOK AE RIEULHIEUH
+0x83A6	0xAE7A	#HANGUL SYLLABLE SSANGKIYEOK AE PIEUPSIOS
+0x83A7	0xAE7E	#HANGUL SYLLABLE SSANGKIYEOK AE CIEUC
+0x83A8	0xAE7F	#HANGUL SYLLABLE SSANGKIYEOK AE CHIEUCH
+0x83A9	0xAE80	#HANGUL SYLLABLE SSANGKIYEOK AE KHIEUKH
+0x83AA	0xAE81	#HANGUL SYLLABLE SSANGKIYEOK AE THIEUTH
+0x83AB	0xAE82	#HANGUL SYLLABLE SSANGKIYEOK AE PHIEUPH
+0x83AC	0xAE83	#HANGUL SYLLABLE SSANGKIYEOK AE HIEUH
+0x83AD	0xAE86	#HANGUL SYLLABLE SSANGKIYEOK YA SSANGKIYEOK
+0x83AE	0xAE87	#HANGUL SYLLABLE SSANGKIYEOK YA KIYEOKSIOS
+0x83AF	0xAE88	#HANGUL SYLLABLE SSANGKIYEOK YA NIEUN
+0x83B0	0xAE89	#HANGUL SYLLABLE SSANGKIYEOK YA NIEUNCIEUC
+0x83B1	0xAE8A	#HANGUL SYLLABLE SSANGKIYEOK YA NIEUNHIEUH
+0x83B2	0xAE8B	#HANGUL SYLLABLE SSANGKIYEOK YA TIKEUT
+0x83B3	0xAE8D	#HANGUL SYLLABLE SSANGKIYEOK YA RIEULKIYEOK
+0x83B4	0xAE8E	#HANGUL SYLLABLE SSANGKIYEOK YA RIEULMIEUM
+0x83B5	0xAE8F	#HANGUL SYLLABLE SSANGKIYEOK YA RIEULPIEUP
+0x83B6	0xAE90	#HANGUL SYLLABLE SSANGKIYEOK YA RIEULSIOS
+0x83B7	0xAE91	#HANGUL SYLLABLE SSANGKIYEOK YA RIEULTHIEUTH
+0x83B8	0xAE92	#HANGUL SYLLABLE SSANGKIYEOK YA RIEULPHIEUPH
+0x83B9	0xAE93	#HANGUL SYLLABLE SSANGKIYEOK YA RIEULHIEUH
+0x83BA	0xAE94	#HANGUL SYLLABLE SSANGKIYEOK YA MIEUM
+0x83BB	0xAE95	#HANGUL SYLLABLE SSANGKIYEOK YA PIEUP
+0x83BC	0xAE96	#HANGUL SYLLABLE SSANGKIYEOK YA PIEUPSIOS
+0x83BD	0xAE97	#HANGUL SYLLABLE SSANGKIYEOK YA SIOS
+0x83BE	0xAE98	#HANGUL SYLLABLE SSANGKIYEOK YA SSANGSIOS
+0x83BF	0xAE99	#HANGUL SYLLABLE SSANGKIYEOK YA IEUNG
+0x83C0	0xAE9A	#HANGUL SYLLABLE SSANGKIYEOK YA CIEUC
+0x83C1	0xAE9B	#HANGUL SYLLABLE SSANGKIYEOK YA CHIEUCH
+0x83C2	0xAE9C	#HANGUL SYLLABLE SSANGKIYEOK YA KHIEUKH
+0x83C3	0xAE9D	#HANGUL SYLLABLE SSANGKIYEOK YA THIEUTH
+0x83C4	0xAE9E	#HANGUL SYLLABLE SSANGKIYEOK YA PHIEUPH
+0x83C5	0xAE9F	#HANGUL SYLLABLE SSANGKIYEOK YA HIEUH
+0x83C6	0xAEA0	#HANGUL SYLLABLE SSANGKIYEOK YAE
+0x83C7	0xAEA1	#HANGUL SYLLABLE SSANGKIYEOK YAE KIYEOK
+0x83C8	0xAEA2	#HANGUL SYLLABLE SSANGKIYEOK YAE SSANGKIYEOK
+0x83C9	0xAEA3	#HANGUL SYLLABLE SSANGKIYEOK YAE KIYEOKSIOS
+0x83CA	0xAEA4	#HANGUL SYLLABLE SSANGKIYEOK YAE NIEUN
+0x83CB	0xAEA5	#HANGUL SYLLABLE SSANGKIYEOK YAE NIEUNCIEUC
+0x83CC	0xAEA6	#HANGUL SYLLABLE SSANGKIYEOK YAE NIEUNHIEUH
+0x83CD	0xAEA7	#HANGUL SYLLABLE SSANGKIYEOK YAE TIKEUT
+0x83CE	0xAEA8	#HANGUL SYLLABLE SSANGKIYEOK YAE RIEUL
+0x83CF	0xAEA9	#HANGUL SYLLABLE SSANGKIYEOK YAE RIEULKIYEOK
+0x83D0	0xAEAA	#HANGUL SYLLABLE SSANGKIYEOK YAE RIEULMIEUM
+0x83D1	0xAEAB	#HANGUL SYLLABLE SSANGKIYEOK YAE RIEULPIEUP
+0x83D2	0xAEAC	#HANGUL SYLLABLE SSANGKIYEOK YAE RIEULSIOS
+0x83D3	0xAEAD	#HANGUL SYLLABLE SSANGKIYEOK YAE RIEULTHIEUTH
+0x83D4	0xAEAE	#HANGUL SYLLABLE SSANGKIYEOK YAE RIEULPHIEUPH
+0x83D5	0xAEAF	#HANGUL SYLLABLE SSANGKIYEOK YAE RIEULHIEUH
+0x83D6	0xAEB0	#HANGUL SYLLABLE SSANGKIYEOK YAE MIEUM
+0x83D7	0xAEB1	#HANGUL SYLLABLE SSANGKIYEOK YAE PIEUP
+0x83D8	0xAEB2	#HANGUL SYLLABLE SSANGKIYEOK YAE PIEUPSIOS
+0x83D9	0xAEB3	#HANGUL SYLLABLE SSANGKIYEOK YAE SIOS
+0x83DA	0xAEB4	#HANGUL SYLLABLE SSANGKIYEOK YAE SSANGSIOS
+0x83DB	0xAEB5	#HANGUL SYLLABLE SSANGKIYEOK YAE IEUNG
+0x83DC	0xAEB6	#HANGUL SYLLABLE SSANGKIYEOK YAE CIEUC
+0x83DD	0xAEB7	#HANGUL SYLLABLE SSANGKIYEOK YAE CHIEUCH
+0x83DE	0xAEB8	#HANGUL SYLLABLE SSANGKIYEOK YAE KHIEUKH
+0x83DF	0xAEB9	#HANGUL SYLLABLE SSANGKIYEOK YAE THIEUTH
+0x83E0	0xAEBA	#HANGUL SYLLABLE SSANGKIYEOK YAE PHIEUPH
+0x83E1	0xAEBB	#HANGUL SYLLABLE SSANGKIYEOK YAE HIEUH
+0x83E2	0xAEBF	#HANGUL SYLLABLE SSANGKIYEOK EO KIYEOKSIOS
+0x83E3	0xAEC1	#HANGUL SYLLABLE SSANGKIYEOK EO NIEUNCIEUC
+0x83E4	0xAEC2	#HANGUL SYLLABLE SSANGKIYEOK EO NIEUNHIEUH
+0x83E5	0xAEC3	#HANGUL SYLLABLE SSANGKIYEOK EO TIKEUT
+0x83E6	0xAEC5	#HANGUL SYLLABLE SSANGKIYEOK EO RIEULKIYEOK
+0x83E7	0xAEC6	#HANGUL SYLLABLE SSANGKIYEOK EO RIEULMIEUM
+0x83E8	0xAEC7	#HANGUL SYLLABLE SSANGKIYEOK EO RIEULPIEUP
+0x83E9	0xAEC8	#HANGUL SYLLABLE SSANGKIYEOK EO RIEULSIOS
+0x83EA	0xAEC9	#HANGUL SYLLABLE SSANGKIYEOK EO RIEULTHIEUTH
+0x83EB	0xAECA	#HANGUL SYLLABLE SSANGKIYEOK EO RIEULPHIEUPH
+0x83EC	0xAECB	#HANGUL SYLLABLE SSANGKIYEOK EO RIEULHIEUH
+0x83ED	0xAECE	#HANGUL SYLLABLE SSANGKIYEOK EO PIEUPSIOS
+0x83EE	0xAED2	#HANGUL SYLLABLE SSANGKIYEOK EO CIEUC
+0x83EF	0xAED3	#HANGUL SYLLABLE SSANGKIYEOK EO CHIEUCH
+0x83F0	0xAED4	#HANGUL SYLLABLE SSANGKIYEOK EO KHIEUKH
+0x83F1	0xAED5	#HANGUL SYLLABLE SSANGKIYEOK EO THIEUTH
+0x83F2	0xAED6	#HANGUL SYLLABLE SSANGKIYEOK EO PHIEUPH
+0x83F3	0xAED7	#HANGUL SYLLABLE SSANGKIYEOK EO HIEUH
+0x83F4	0xAEDA	#HANGUL SYLLABLE SSANGKIYEOK E SSANGKIYEOK
+0x83F5	0xAEDB	#HANGUL SYLLABLE SSANGKIYEOK E KIYEOKSIOS
+0x83F6	0xAEDD	#HANGUL SYLLABLE SSANGKIYEOK E NIEUNCIEUC
+0x83F7	0xAEDE	#HANGUL SYLLABLE SSANGKIYEOK E NIEUNHIEUH
+0x83F8	0xAEDF	#HANGUL SYLLABLE SSANGKIYEOK E TIKEUT
+0x83F9	0xAEE0	#HANGUL SYLLABLE SSANGKIYEOK E RIEUL
+0x83FA	0xAEE1	#HANGUL SYLLABLE SSANGKIYEOK E RIEULKIYEOK
+0x83FB	0xAEE2	#HANGUL SYLLABLE SSANGKIYEOK E RIEULMIEUM
+0x83FC	0xAEE3	#HANGUL SYLLABLE SSANGKIYEOK E RIEULPIEUP
+0x83FD	0xAEE4	#HANGUL SYLLABLE SSANGKIYEOK E RIEULSIOS
+0x83FE	0xAEE5	#HANGUL SYLLABLE SSANGKIYEOK E RIEULTHIEUTH
+0x8441	0xAEE6	#HANGUL SYLLABLE SSANGKIYEOK E RIEULPHIEUPH
+0x8442	0xAEE7	#HANGUL SYLLABLE SSANGKIYEOK E RIEULHIEUH
+0x8443	0xAEE9	#HANGUL SYLLABLE SSANGKIYEOK E PIEUP
+0x8444	0xAEEA	#HANGUL SYLLABLE SSANGKIYEOK E PIEUPSIOS
+0x8445	0xAEEC	#HANGUL SYLLABLE SSANGKIYEOK E SSANGSIOS
+0x8446	0xAEEE	#HANGUL SYLLABLE SSANGKIYEOK E CIEUC
+0x8447	0xAEEF	#HANGUL SYLLABLE SSANGKIYEOK E CHIEUCH
+0x8448	0xAEF0	#HANGUL SYLLABLE SSANGKIYEOK E KHIEUKH
+0x8449	0xAEF1	#HANGUL SYLLABLE SSANGKIYEOK E THIEUTH
+0x844A	0xAEF2	#HANGUL SYLLABLE SSANGKIYEOK E PHIEUPH
+0x844B	0xAEF3	#HANGUL SYLLABLE SSANGKIYEOK E HIEUH
+0x844C	0xAEF5	#HANGUL SYLLABLE SSANGKIYEOK YEO KIYEOK
+0x844D	0xAEF6	#HANGUL SYLLABLE SSANGKIYEOK YEO SSANGKIYEOK
+0x844E	0xAEF7	#HANGUL SYLLABLE SSANGKIYEOK YEO KIYEOKSIOS
+0x844F	0xAEF9	#HANGUL SYLLABLE SSANGKIYEOK YEO NIEUNCIEUC
+0x8450	0xAEFA	#HANGUL SYLLABLE SSANGKIYEOK YEO NIEUNHIEUH
+0x8451	0xAEFB	#HANGUL SYLLABLE SSANGKIYEOK YEO TIKEUT
+0x8452	0xAEFD	#HANGUL SYLLABLE SSANGKIYEOK YEO RIEULKIYEOK
+0x8453	0xAEFE	#HANGUL SYLLABLE SSANGKIYEOK YEO RIEULMIEUM
+0x8454	0xAEFF	#HANGUL SYLLABLE SSANGKIYEOK YEO RIEULPIEUP
+0x8455	0xAF00	#HANGUL SYLLABLE SSANGKIYEOK YEO RIEULSIOS
+0x8456	0xAF01	#HANGUL SYLLABLE SSANGKIYEOK YEO RIEULTHIEUTH
+0x8457	0xAF02	#HANGUL SYLLABLE SSANGKIYEOK YEO RIEULPHIEUPH
+0x8458	0xAF03	#HANGUL SYLLABLE SSANGKIYEOK YEO RIEULHIEUH
+0x8459	0xAF04	#HANGUL SYLLABLE SSANGKIYEOK YEO MIEUM
+0x845A	0xAF05	#HANGUL SYLLABLE SSANGKIYEOK YEO PIEUP
+0x8461	0xAF06	#HANGUL SYLLABLE SSANGKIYEOK YEO PIEUPSIOS
+0x8462	0xAF09	#HANGUL SYLLABLE SSANGKIYEOK YEO IEUNG
+0x8463	0xAF0A	#HANGUL SYLLABLE SSANGKIYEOK YEO CIEUC
+0x8464	0xAF0B	#HANGUL SYLLABLE SSANGKIYEOK YEO CHIEUCH
+0x8465	0xAF0C	#HANGUL SYLLABLE SSANGKIYEOK YEO KHIEUKH
+0x8466	0xAF0E	#HANGUL SYLLABLE SSANGKIYEOK YEO PHIEUPH
+0x8467	0xAF0F	#HANGUL SYLLABLE SSANGKIYEOK YEO HIEUH
+0x8468	0xAF11	#HANGUL SYLLABLE SSANGKIYEOK YE KIYEOK
+0x8469	0xAF12	#HANGUL SYLLABLE SSANGKIYEOK YE SSANGKIYEOK
+0x846A	0xAF13	#HANGUL SYLLABLE SSANGKIYEOK YE KIYEOKSIOS
+0x846B	0xAF14	#HANGUL SYLLABLE SSANGKIYEOK YE NIEUN
+0x846C	0xAF15	#HANGUL SYLLABLE SSANGKIYEOK YE NIEUNCIEUC
+0x846D	0xAF16	#HANGUL SYLLABLE SSANGKIYEOK YE NIEUNHIEUH
+0x846E	0xAF17	#HANGUL SYLLABLE SSANGKIYEOK YE TIKEUT
+0x846F	0xAF18	#HANGUL SYLLABLE SSANGKIYEOK YE RIEUL
+0x8470	0xAF19	#HANGUL SYLLABLE SSANGKIYEOK YE RIEULKIYEOK
+0x8471	0xAF1A	#HANGUL SYLLABLE SSANGKIYEOK YE RIEULMIEUM
+0x8472	0xAF1B	#HANGUL SYLLABLE SSANGKIYEOK YE RIEULPIEUP
+0x8473	0xAF1C	#HANGUL SYLLABLE SSANGKIYEOK YE RIEULSIOS
+0x8474	0xAF1D	#HANGUL SYLLABLE SSANGKIYEOK YE RIEULTHIEUTH
+0x8475	0xAF1E	#HANGUL SYLLABLE SSANGKIYEOK YE RIEULPHIEUPH
+0x8476	0xAF1F	#HANGUL SYLLABLE SSANGKIYEOK YE RIEULHIEUH
+0x8477	0xAF20	#HANGUL SYLLABLE SSANGKIYEOK YE MIEUM
+0x8478	0xAF21	#HANGUL SYLLABLE SSANGKIYEOK YE PIEUP
+0x8479	0xAF22	#HANGUL SYLLABLE SSANGKIYEOK YE PIEUPSIOS
+0x847A	0xAF23	#HANGUL SYLLABLE SSANGKIYEOK YE SIOS
+0x8481	0xAF24	#HANGUL SYLLABLE SSANGKIYEOK YE SSANGSIOS
+0x8482	0xAF25	#HANGUL SYLLABLE SSANGKIYEOK YE IEUNG
+0x8483	0xAF26	#HANGUL SYLLABLE SSANGKIYEOK YE CIEUC
+0x8484	0xAF27	#HANGUL SYLLABLE SSANGKIYEOK YE CHIEUCH
+0x8485	0xAF28	#HANGUL SYLLABLE SSANGKIYEOK YE KHIEUKH
+0x8486	0xAF29	#HANGUL SYLLABLE SSANGKIYEOK YE THIEUTH
+0x8487	0xAF2A	#HANGUL SYLLABLE SSANGKIYEOK YE PHIEUPH
+0x8488	0xAF2B	#HANGUL SYLLABLE SSANGKIYEOK YE HIEUH
+0x8489	0xAF2E	#HANGUL SYLLABLE SSANGKIYEOK O SSANGKIYEOK
+0x848A	0xAF2F	#HANGUL SYLLABLE SSANGKIYEOK O KIYEOKSIOS
+0x848B	0xAF31	#HANGUL SYLLABLE SSANGKIYEOK O NIEUNCIEUC
+0x848C	0xAF33	#HANGUL SYLLABLE SSANGKIYEOK O TIKEUT
+0x848D	0xAF35	#HANGUL SYLLABLE SSANGKIYEOK O RIEULKIYEOK
+0x848E	0xAF36	#HANGUL SYLLABLE SSANGKIYEOK O RIEULMIEUM
+0x848F	0xAF37	#HANGUL SYLLABLE SSANGKIYEOK O RIEULPIEUP
+0x8490	0xAF38	#HANGUL SYLLABLE SSANGKIYEOK O RIEULSIOS
+0x8491	0xAF39	#HANGUL SYLLABLE SSANGKIYEOK O RIEULTHIEUTH
+0x8492	0xAF3A	#HANGUL SYLLABLE SSANGKIYEOK O RIEULPHIEUPH
+0x8493	0xAF3B	#HANGUL SYLLABLE SSANGKIYEOK O RIEULHIEUH
+0x8494	0xAF3E	#HANGUL SYLLABLE SSANGKIYEOK O PIEUPSIOS
+0x8495	0xAF40	#HANGUL SYLLABLE SSANGKIYEOK O SSANGSIOS
+0x8496	0xAF44	#HANGUL SYLLABLE SSANGKIYEOK O KHIEUKH
+0x8497	0xAF45	#HANGUL SYLLABLE SSANGKIYEOK O THIEUTH
+0x8498	0xAF46	#HANGUL SYLLABLE SSANGKIYEOK O PHIEUPH
+0x8499	0xAF47	#HANGUL SYLLABLE SSANGKIYEOK O HIEUH
+0x849A	0xAF4A	#HANGUL SYLLABLE SSANGKIYEOK WA SSANGKIYEOK
+0x849B	0xAF4B	#HANGUL SYLLABLE SSANGKIYEOK WA KIYEOKSIOS
+0x849C	0xAF4C	#HANGUL SYLLABLE SSANGKIYEOK WA NIEUN
+0x849D	0xAF4D	#HANGUL SYLLABLE SSANGKIYEOK WA NIEUNCIEUC
+0x849E	0xAF4E	#HANGUL SYLLABLE SSANGKIYEOK WA NIEUNHIEUH
+0x849F	0xAF4F	#HANGUL SYLLABLE SSANGKIYEOK WA TIKEUT
+0x84A0	0xAF51	#HANGUL SYLLABLE SSANGKIYEOK WA RIEULKIYEOK
+0x84A1	0xAF52	#HANGUL SYLLABLE SSANGKIYEOK WA RIEULMIEUM
+0x84A2	0xAF53	#HANGUL SYLLABLE SSANGKIYEOK WA RIEULPIEUP
+0x84A3	0xAF54	#HANGUL SYLLABLE SSANGKIYEOK WA RIEULSIOS
+0x84A4	0xAF55	#HANGUL SYLLABLE SSANGKIYEOK WA RIEULTHIEUTH
+0x84A5	0xAF56	#HANGUL SYLLABLE SSANGKIYEOK WA RIEULPHIEUPH
+0x84A6	0xAF57	#HANGUL SYLLABLE SSANGKIYEOK WA RIEULHIEUH
+0x84A7	0xAF58	#HANGUL SYLLABLE SSANGKIYEOK WA MIEUM
+0x84A8	0xAF59	#HANGUL SYLLABLE SSANGKIYEOK WA PIEUP
+0x84A9	0xAF5A	#HANGUL SYLLABLE SSANGKIYEOK WA PIEUPSIOS
+0x84AA	0xAF5B	#HANGUL SYLLABLE SSANGKIYEOK WA SIOS
+0x84AB	0xAF5E	#HANGUL SYLLABLE SSANGKIYEOK WA CIEUC
+0x84AC	0xAF5F	#HANGUL SYLLABLE SSANGKIYEOK WA CHIEUCH
+0x84AD	0xAF60	#HANGUL SYLLABLE SSANGKIYEOK WA KHIEUKH
+0x84AE	0xAF61	#HANGUL SYLLABLE SSANGKIYEOK WA THIEUTH
+0x84AF	0xAF62	#HANGUL SYLLABLE SSANGKIYEOK WA PHIEUPH
+0x84B0	0xAF63	#HANGUL SYLLABLE SSANGKIYEOK WA HIEUH
+0x84B1	0xAF66	#HANGUL SYLLABLE SSANGKIYEOK WAE SSANGKIYEOK
+0x84B2	0xAF67	#HANGUL SYLLABLE SSANGKIYEOK WAE KIYEOKSIOS
+0x84B3	0xAF68	#HANGUL SYLLABLE SSANGKIYEOK WAE NIEUN
+0x84B4	0xAF69	#HANGUL SYLLABLE SSANGKIYEOK WAE NIEUNCIEUC
+0x84B5	0xAF6A	#HANGUL SYLLABLE SSANGKIYEOK WAE NIEUNHIEUH
+0x84B6	0xAF6B	#HANGUL SYLLABLE SSANGKIYEOK WAE TIKEUT
+0x84B7	0xAF6C	#HANGUL SYLLABLE SSANGKIYEOK WAE RIEUL
+0x84B8	0xAF6D	#HANGUL SYLLABLE SSANGKIYEOK WAE RIEULKIYEOK
+0x84B9	0xAF6E	#HANGUL SYLLABLE SSANGKIYEOK WAE RIEULMIEUM
+0x84BA	0xAF6F	#HANGUL SYLLABLE SSANGKIYEOK WAE RIEULPIEUP
+0x84BB	0xAF70	#HANGUL SYLLABLE SSANGKIYEOK WAE RIEULSIOS
+0x84BC	0xAF71	#HANGUL SYLLABLE SSANGKIYEOK WAE RIEULTHIEUTH
+0x84BD	0xAF72	#HANGUL SYLLABLE SSANGKIYEOK WAE RIEULPHIEUPH
+0x84BE	0xAF73	#HANGUL SYLLABLE SSANGKIYEOK WAE RIEULHIEUH
+0x84BF	0xAF74	#HANGUL SYLLABLE SSANGKIYEOK WAE MIEUM
+0x84C0	0xAF75	#HANGUL SYLLABLE SSANGKIYEOK WAE PIEUP
+0x84C1	0xAF76	#HANGUL SYLLABLE SSANGKIYEOK WAE PIEUPSIOS
+0x84C2	0xAF77	#HANGUL SYLLABLE SSANGKIYEOK WAE SIOS
+0x84C3	0xAF78	#HANGUL SYLLABLE SSANGKIYEOK WAE SSANGSIOS
+0x84C4	0xAF7A	#HANGUL SYLLABLE SSANGKIYEOK WAE CIEUC
+0x84C5	0xAF7B	#HANGUL SYLLABLE SSANGKIYEOK WAE CHIEUCH
+0x84C6	0xAF7C	#HANGUL SYLLABLE SSANGKIYEOK WAE KHIEUKH
+0x84C7	0xAF7D	#HANGUL SYLLABLE SSANGKIYEOK WAE THIEUTH
+0x84C8	0xAF7E	#HANGUL SYLLABLE SSANGKIYEOK WAE PHIEUPH
+0x84C9	0xAF7F	#HANGUL SYLLABLE SSANGKIYEOK WAE HIEUH
+0x84CA	0xAF81	#HANGUL SYLLABLE SSANGKIYEOK OE KIYEOK
+0x84CB	0xAF82	#HANGUL SYLLABLE SSANGKIYEOK OE SSANGKIYEOK
+0x84CC	0xAF83	#HANGUL SYLLABLE SSANGKIYEOK OE KIYEOKSIOS
+0x84CD	0xAF85	#HANGUL SYLLABLE SSANGKIYEOK OE NIEUNCIEUC
+0x84CE	0xAF86	#HANGUL SYLLABLE SSANGKIYEOK OE NIEUNHIEUH
+0x84CF	0xAF87	#HANGUL SYLLABLE SSANGKIYEOK OE TIKEUT
+0x84D0	0xAF89	#HANGUL SYLLABLE SSANGKIYEOK OE RIEULKIYEOK
+0x84D1	0xAF8A	#HANGUL SYLLABLE SSANGKIYEOK OE RIEULMIEUM
+0x84D2	0xAF8B	#HANGUL SYLLABLE SSANGKIYEOK OE RIEULPIEUP
+0x84D3	0xAF8C	#HANGUL SYLLABLE SSANGKIYEOK OE RIEULSIOS
+0x84D4	0xAF8D	#HANGUL SYLLABLE SSANGKIYEOK OE RIEULTHIEUTH
+0x84D5	0xAF8E	#HANGUL SYLLABLE SSANGKIYEOK OE RIEULPHIEUPH
+0x84D6	0xAF8F	#HANGUL SYLLABLE SSANGKIYEOK OE RIEULHIEUH
+0x84D7	0xAF92	#HANGUL SYLLABLE SSANGKIYEOK OE PIEUPSIOS
+0x84D8	0xAF93	#HANGUL SYLLABLE SSANGKIYEOK OE SIOS
+0x84D9	0xAF94	#HANGUL SYLLABLE SSANGKIYEOK OE SSANGSIOS
+0x84DA	0xAF96	#HANGUL SYLLABLE SSANGKIYEOK OE CIEUC
+0x84DB	0xAF97	#HANGUL SYLLABLE SSANGKIYEOK OE CHIEUCH
+0x84DC	0xAF98	#HANGUL SYLLABLE SSANGKIYEOK OE KHIEUKH
+0x84DD	0xAF99	#HANGUL SYLLABLE SSANGKIYEOK OE THIEUTH
+0x84DE	0xAF9A	#HANGUL SYLLABLE SSANGKIYEOK OE PHIEUPH
+0x84DF	0xAF9B	#HANGUL SYLLABLE SSANGKIYEOK OE HIEUH
+0x84E0	0xAF9D	#HANGUL SYLLABLE SSANGKIYEOK YO KIYEOK
+0x84E1	0xAF9E	#HANGUL SYLLABLE SSANGKIYEOK YO SSANGKIYEOK
+0x84E2	0xAF9F	#HANGUL SYLLABLE SSANGKIYEOK YO KIYEOKSIOS
+0x84E3	0xAFA0	#HANGUL SYLLABLE SSANGKIYEOK YO NIEUN
+0x84E4	0xAFA1	#HANGUL SYLLABLE SSANGKIYEOK YO NIEUNCIEUC
+0x84E5	0xAFA2	#HANGUL SYLLABLE SSANGKIYEOK YO NIEUNHIEUH
+0x84E6	0xAFA3	#HANGUL SYLLABLE SSANGKIYEOK YO TIKEUT
+0x84E7	0xAFA4	#HANGUL SYLLABLE SSANGKIYEOK YO RIEUL
+0x84E8	0xAFA5	#HANGUL SYLLABLE SSANGKIYEOK YO RIEULKIYEOK
+0x84E9	0xAFA6	#HANGUL SYLLABLE SSANGKIYEOK YO RIEULMIEUM
+0x84EA	0xAFA7	#HANGUL SYLLABLE SSANGKIYEOK YO RIEULPIEUP
+0x84EB	0xAFA8	#HANGUL SYLLABLE SSANGKIYEOK YO RIEULSIOS
+0x84EC	0xAFA9	#HANGUL SYLLABLE SSANGKIYEOK YO RIEULTHIEUTH
+0x84ED	0xAFAA	#HANGUL SYLLABLE SSANGKIYEOK YO RIEULPHIEUPH
+0x84EE	0xAFAB	#HANGUL SYLLABLE SSANGKIYEOK YO RIEULHIEUH
+0x84EF	0xAFAC	#HANGUL SYLLABLE SSANGKIYEOK YO MIEUM
+0x84F0	0xAFAD	#HANGUL SYLLABLE SSANGKIYEOK YO PIEUP
+0x84F1	0xAFAE	#HANGUL SYLLABLE SSANGKIYEOK YO PIEUPSIOS
+0x84F2	0xAFAF	#HANGUL SYLLABLE SSANGKIYEOK YO SIOS
+0x84F3	0xAFB0	#HANGUL SYLLABLE SSANGKIYEOK YO SSANGSIOS
+0x84F4	0xAFB1	#HANGUL SYLLABLE SSANGKIYEOK YO IEUNG
+0x84F5	0xAFB2	#HANGUL SYLLABLE SSANGKIYEOK YO CIEUC
+0x84F6	0xAFB3	#HANGUL SYLLABLE SSANGKIYEOK YO CHIEUCH
+0x84F7	0xAFB4	#HANGUL SYLLABLE SSANGKIYEOK YO KHIEUKH
+0x84F8	0xAFB5	#HANGUL SYLLABLE SSANGKIYEOK YO THIEUTH
+0x84F9	0xAFB6	#HANGUL SYLLABLE SSANGKIYEOK YO PHIEUPH
+0x84FA	0xAFB7	#HANGUL SYLLABLE SSANGKIYEOK YO HIEUH
+0x84FB	0xAFBA	#HANGUL SYLLABLE SSANGKIYEOK U SSANGKIYEOK
+0x84FC	0xAFBB	#HANGUL SYLLABLE SSANGKIYEOK U KIYEOKSIOS
+0x84FD	0xAFBD	#HANGUL SYLLABLE SSANGKIYEOK U NIEUNCIEUC
+0x84FE	0xAFBE	#HANGUL SYLLABLE SSANGKIYEOK U NIEUNHIEUH
+0x8541	0xAFBF	#HANGUL SYLLABLE SSANGKIYEOK U TIKEUT
+0x8542	0xAFC1	#HANGUL SYLLABLE SSANGKIYEOK U RIEULKIYEOK
+0x8543	0xAFC2	#HANGUL SYLLABLE SSANGKIYEOK U RIEULMIEUM
+0x8544	0xAFC3	#HANGUL SYLLABLE SSANGKIYEOK U RIEULPIEUP
+0x8545	0xAFC4	#HANGUL SYLLABLE SSANGKIYEOK U RIEULSIOS
+0x8546	0xAFC5	#HANGUL SYLLABLE SSANGKIYEOK U RIEULTHIEUTH
+0x8547	0xAFC6	#HANGUL SYLLABLE SSANGKIYEOK U RIEULPHIEUPH
+0x8548	0xAFCA	#HANGUL SYLLABLE SSANGKIYEOK U PIEUPSIOS
+0x8549	0xAFCC	#HANGUL SYLLABLE SSANGKIYEOK U SSANGSIOS
+0x854A	0xAFCF	#HANGUL SYLLABLE SSANGKIYEOK U CHIEUCH
+0x854B	0xAFD0	#HANGUL SYLLABLE SSANGKIYEOK U KHIEUKH
+0x854C	0xAFD1	#HANGUL SYLLABLE SSANGKIYEOK U THIEUTH
+0x854D	0xAFD2	#HANGUL SYLLABLE SSANGKIYEOK U PHIEUPH
+0x854E	0xAFD3	#HANGUL SYLLABLE SSANGKIYEOK U HIEUH
+0x854F	0xAFD5	#HANGUL SYLLABLE SSANGKIYEOK WEO KIYEOK
+0x8550	0xAFD6	#HANGUL SYLLABLE SSANGKIYEOK WEO SSANGKIYEOK
+0x8551	0xAFD7	#HANGUL SYLLABLE SSANGKIYEOK WEO KIYEOKSIOS
+0x8552	0xAFD8	#HANGUL SYLLABLE SSANGKIYEOK WEO NIEUN
+0x8553	0xAFD9	#HANGUL SYLLABLE SSANGKIYEOK WEO NIEUNCIEUC
+0x8554	0xAFDA	#HANGUL SYLLABLE SSANGKIYEOK WEO NIEUNHIEUH
+0x8555	0xAFDB	#HANGUL SYLLABLE SSANGKIYEOK WEO TIKEUT
+0x8556	0xAFDD	#HANGUL SYLLABLE SSANGKIYEOK WEO RIEULKIYEOK
+0x8557	0xAFDE	#HANGUL SYLLABLE SSANGKIYEOK WEO RIEULMIEUM
+0x8558	0xAFDF	#HANGUL SYLLABLE SSANGKIYEOK WEO RIEULPIEUP
+0x8559	0xAFE0	#HANGUL SYLLABLE SSANGKIYEOK WEO RIEULSIOS
+0x855A	0xAFE1	#HANGUL SYLLABLE SSANGKIYEOK WEO RIEULTHIEUTH
+0x8561	0xAFE2	#HANGUL SYLLABLE SSANGKIYEOK WEO RIEULPHIEUPH
+0x8562	0xAFE3	#HANGUL SYLLABLE SSANGKIYEOK WEO RIEULHIEUH
+0x8563	0xAFE4	#HANGUL SYLLABLE SSANGKIYEOK WEO MIEUM
+0x8564	0xAFE5	#HANGUL SYLLABLE SSANGKIYEOK WEO PIEUP
+0x8565	0xAFE6	#HANGUL SYLLABLE SSANGKIYEOK WEO PIEUPSIOS
+0x8566	0xAFE7	#HANGUL SYLLABLE SSANGKIYEOK WEO SIOS
+0x8567	0xAFEA	#HANGUL SYLLABLE SSANGKIYEOK WEO CIEUC
+0x8568	0xAFEB	#HANGUL SYLLABLE SSANGKIYEOK WEO CHIEUCH
+0x8569	0xAFEC	#HANGUL SYLLABLE SSANGKIYEOK WEO KHIEUKH
+0x856A	0xAFED	#HANGUL SYLLABLE SSANGKIYEOK WEO THIEUTH
+0x856B	0xAFEE	#HANGUL SYLLABLE SSANGKIYEOK WEO PHIEUPH
+0x856C	0xAFEF	#HANGUL SYLLABLE SSANGKIYEOK WEO HIEUH
+0x856D	0xAFF2	#HANGUL SYLLABLE SSANGKIYEOK WE SSANGKIYEOK
+0x856E	0xAFF3	#HANGUL SYLLABLE SSANGKIYEOK WE KIYEOKSIOS
+0x856F	0xAFF5	#HANGUL SYLLABLE SSANGKIYEOK WE NIEUNCIEUC
+0x8570	0xAFF6	#HANGUL SYLLABLE SSANGKIYEOK WE NIEUNHIEUH
+0x8571	0xAFF7	#HANGUL SYLLABLE SSANGKIYEOK WE TIKEUT
+0x8572	0xAFF9	#HANGUL SYLLABLE SSANGKIYEOK WE RIEULKIYEOK
+0x8573	0xAFFA	#HANGUL SYLLABLE SSANGKIYEOK WE RIEULMIEUM
+0x8574	0xAFFB	#HANGUL SYLLABLE SSANGKIYEOK WE RIEULPIEUP
+0x8575	0xAFFC	#HANGUL SYLLABLE SSANGKIYEOK WE RIEULSIOS
+0x8576	0xAFFD	#HANGUL SYLLABLE SSANGKIYEOK WE RIEULTHIEUTH
+0x8577	0xAFFE	#HANGUL SYLLABLE SSANGKIYEOK WE RIEULPHIEUPH
+0x8578	0xAFFF	#HANGUL SYLLABLE SSANGKIYEOK WE RIEULHIEUH
+0x8579	0xB002	#HANGUL SYLLABLE SSANGKIYEOK WE PIEUPSIOS
+0x857A	0xB003	#HANGUL SYLLABLE SSANGKIYEOK WE SIOS
+0x8581	0xB005	#HANGUL SYLLABLE SSANGKIYEOK WE IEUNG
+0x8582	0xB006	#HANGUL SYLLABLE SSANGKIYEOK WE CIEUC
+0x8583	0xB007	#HANGUL SYLLABLE SSANGKIYEOK WE CHIEUCH
+0x8584	0xB008	#HANGUL SYLLABLE SSANGKIYEOK WE KHIEUKH
+0x8585	0xB009	#HANGUL SYLLABLE SSANGKIYEOK WE THIEUTH
+0x8586	0xB00A	#HANGUL SYLLABLE SSANGKIYEOK WE PHIEUPH
+0x8587	0xB00B	#HANGUL SYLLABLE SSANGKIYEOK WE HIEUH
+0x8588	0xB00D	#HANGUL SYLLABLE SSANGKIYEOK WI KIYEOK
+0x8589	0xB00E	#HANGUL SYLLABLE SSANGKIYEOK WI SSANGKIYEOK
+0x858A	0xB00F	#HANGUL SYLLABLE SSANGKIYEOK WI KIYEOKSIOS
+0x858B	0xB011	#HANGUL SYLLABLE SSANGKIYEOK WI NIEUNCIEUC
+0x858C	0xB012	#HANGUL SYLLABLE SSANGKIYEOK WI NIEUNHIEUH
+0x858D	0xB013	#HANGUL SYLLABLE SSANGKIYEOK WI TIKEUT
+0x858E	0xB015	#HANGUL SYLLABLE SSANGKIYEOK WI RIEULKIYEOK
+0x858F	0xB016	#HANGUL SYLLABLE SSANGKIYEOK WI RIEULMIEUM
+0x8590	0xB017	#HANGUL SYLLABLE SSANGKIYEOK WI RIEULPIEUP
+0x8591	0xB018	#HANGUL SYLLABLE SSANGKIYEOK WI RIEULSIOS
+0x8592	0xB019	#HANGUL SYLLABLE SSANGKIYEOK WI RIEULTHIEUTH
+0x8593	0xB01A	#HANGUL SYLLABLE SSANGKIYEOK WI RIEULPHIEUPH
+0x8594	0xB01B	#HANGUL SYLLABLE SSANGKIYEOK WI RIEULHIEUH
+0x8595	0xB01E	#HANGUL SYLLABLE SSANGKIYEOK WI PIEUPSIOS
+0x8596	0xB01F	#HANGUL SYLLABLE SSANGKIYEOK WI SIOS
+0x8597	0xB020	#HANGUL SYLLABLE SSANGKIYEOK WI SSANGSIOS
+0x8598	0xB021	#HANGUL SYLLABLE SSANGKIYEOK WI IEUNG
+0x8599	0xB022	#HANGUL SYLLABLE SSANGKIYEOK WI CIEUC
+0x859A	0xB023	#HANGUL SYLLABLE SSANGKIYEOK WI CHIEUCH
+0x859B	0xB024	#HANGUL SYLLABLE SSANGKIYEOK WI KHIEUKH
+0x859C	0xB025	#HANGUL SYLLABLE SSANGKIYEOK WI THIEUTH
+0x859D	0xB026	#HANGUL SYLLABLE SSANGKIYEOK WI PHIEUPH
+0x859E	0xB027	#HANGUL SYLLABLE SSANGKIYEOK WI HIEUH
+0x859F	0xB029	#HANGUL SYLLABLE SSANGKIYEOK YU KIYEOK
+0x85A0	0xB02A	#HANGUL SYLLABLE SSANGKIYEOK YU SSANGKIYEOK
+0x85A1	0xB02B	#HANGUL SYLLABLE SSANGKIYEOK YU KIYEOKSIOS
+0x85A2	0xB02C	#HANGUL SYLLABLE SSANGKIYEOK YU NIEUN
+0x85A3	0xB02D	#HANGUL SYLLABLE SSANGKIYEOK YU NIEUNCIEUC
+0x85A4	0xB02E	#HANGUL SYLLABLE SSANGKIYEOK YU NIEUNHIEUH
+0x85A5	0xB02F	#HANGUL SYLLABLE SSANGKIYEOK YU TIKEUT
+0x85A6	0xB030	#HANGUL SYLLABLE SSANGKIYEOK YU RIEUL
+0x85A7	0xB031	#HANGUL SYLLABLE SSANGKIYEOK YU RIEULKIYEOK
+0x85A8	0xB032	#HANGUL SYLLABLE SSANGKIYEOK YU RIEULMIEUM
+0x85A9	0xB033	#HANGUL SYLLABLE SSANGKIYEOK YU RIEULPIEUP
+0x85AA	0xB034	#HANGUL SYLLABLE SSANGKIYEOK YU RIEULSIOS
+0x85AB	0xB035	#HANGUL SYLLABLE SSANGKIYEOK YU RIEULTHIEUTH
+0x85AC	0xB036	#HANGUL SYLLABLE SSANGKIYEOK YU RIEULPHIEUPH
+0x85AD	0xB037	#HANGUL SYLLABLE SSANGKIYEOK YU RIEULHIEUH
+0x85AE	0xB038	#HANGUL SYLLABLE SSANGKIYEOK YU MIEUM
+0x85AF	0xB039	#HANGUL SYLLABLE SSANGKIYEOK YU PIEUP
+0x85B0	0xB03A	#HANGUL SYLLABLE SSANGKIYEOK YU PIEUPSIOS
+0x85B1	0xB03B	#HANGUL SYLLABLE SSANGKIYEOK YU SIOS
+0x85B2	0xB03C	#HANGUL SYLLABLE SSANGKIYEOK YU SSANGSIOS
+0x85B3	0xB03D	#HANGUL SYLLABLE SSANGKIYEOK YU IEUNG
+0x85B4	0xB03E	#HANGUL SYLLABLE SSANGKIYEOK YU CIEUC
+0x85B5	0xB03F	#HANGUL SYLLABLE SSANGKIYEOK YU CHIEUCH
+0x85B6	0xB040	#HANGUL SYLLABLE SSANGKIYEOK YU KHIEUKH
+0x85B7	0xB041	#HANGUL SYLLABLE SSANGKIYEOK YU THIEUTH
+0x85B8	0xB042	#HANGUL SYLLABLE SSANGKIYEOK YU PHIEUPH
+0x85B9	0xB043	#HANGUL SYLLABLE SSANGKIYEOK YU HIEUH
+0x85BA	0xB046	#HANGUL SYLLABLE SSANGKIYEOK EU SSANGKIYEOK
+0x85BB	0xB047	#HANGUL SYLLABLE SSANGKIYEOK EU KIYEOKSIOS
+0x85BC	0xB049	#HANGUL SYLLABLE SSANGKIYEOK EU NIEUNCIEUC
+0x85BD	0xB04B	#HANGUL SYLLABLE SSANGKIYEOK EU TIKEUT
+0x85BE	0xB04D	#HANGUL SYLLABLE SSANGKIYEOK EU RIEULKIYEOK
+0x85BF	0xB04F	#HANGUL SYLLABLE SSANGKIYEOK EU RIEULPIEUP
+0x85C0	0xB050	#HANGUL SYLLABLE SSANGKIYEOK EU RIEULSIOS
+0x85C1	0xB051	#HANGUL SYLLABLE SSANGKIYEOK EU RIEULTHIEUTH
+0x85C2	0xB052	#HANGUL SYLLABLE SSANGKIYEOK EU RIEULPHIEUPH
+0x85C3	0xB056	#HANGUL SYLLABLE SSANGKIYEOK EU PIEUPSIOS
+0x85C4	0xB058	#HANGUL SYLLABLE SSANGKIYEOK EU SSANGSIOS
+0x85C5	0xB05A	#HANGUL SYLLABLE SSANGKIYEOK EU CIEUC
+0x85C6	0xB05B	#HANGUL SYLLABLE SSANGKIYEOK EU CHIEUCH
+0x85C7	0xB05C	#HANGUL SYLLABLE SSANGKIYEOK EU KHIEUKH
+0x85C8	0xB05E	#HANGUL SYLLABLE SSANGKIYEOK EU PHIEUPH
+0x85C9	0xB05F	#HANGUL SYLLABLE SSANGKIYEOK EU HIEUH
+0x85CA	0xB060	#HANGUL SYLLABLE SSANGKIYEOK YI
+0x85CB	0xB061	#HANGUL SYLLABLE SSANGKIYEOK YI KIYEOK
+0x85CC	0xB062	#HANGUL SYLLABLE SSANGKIYEOK YI SSANGKIYEOK
+0x85CD	0xB063	#HANGUL SYLLABLE SSANGKIYEOK YI KIYEOKSIOS
+0x85CE	0xB064	#HANGUL SYLLABLE SSANGKIYEOK YI NIEUN
+0x85CF	0xB065	#HANGUL SYLLABLE SSANGKIYEOK YI NIEUNCIEUC
+0x85D0	0xB066	#HANGUL SYLLABLE SSANGKIYEOK YI NIEUNHIEUH
+0x85D1	0xB067	#HANGUL SYLLABLE SSANGKIYEOK YI TIKEUT
+0x85D2	0xB068	#HANGUL SYLLABLE SSANGKIYEOK YI RIEUL
+0x85D3	0xB069	#HANGUL SYLLABLE SSANGKIYEOK YI RIEULKIYEOK
+0x85D4	0xB06A	#HANGUL SYLLABLE SSANGKIYEOK YI RIEULMIEUM
+0x85D5	0xB06B	#HANGUL SYLLABLE SSANGKIYEOK YI RIEULPIEUP
+0x85D6	0xB06C	#HANGUL SYLLABLE SSANGKIYEOK YI RIEULSIOS
+0x85D7	0xB06D	#HANGUL SYLLABLE SSANGKIYEOK YI RIEULTHIEUTH
+0x85D8	0xB06E	#HANGUL SYLLABLE SSANGKIYEOK YI RIEULPHIEUPH
+0x85D9	0xB06F	#HANGUL SYLLABLE SSANGKIYEOK YI RIEULHIEUH
+0x85DA	0xB070	#HANGUL SYLLABLE SSANGKIYEOK YI MIEUM
+0x85DB	0xB071	#HANGUL SYLLABLE SSANGKIYEOK YI PIEUP
+0x85DC	0xB072	#HANGUL SYLLABLE SSANGKIYEOK YI PIEUPSIOS
+0x85DD	0xB073	#HANGUL SYLLABLE SSANGKIYEOK YI SIOS
+0x85DE	0xB074	#HANGUL SYLLABLE SSANGKIYEOK YI SSANGSIOS
+0x85DF	0xB075	#HANGUL SYLLABLE SSANGKIYEOK YI IEUNG
+0x85E0	0xB076	#HANGUL SYLLABLE SSANGKIYEOK YI CIEUC
+0x85E1	0xB077	#HANGUL SYLLABLE SSANGKIYEOK YI CHIEUCH
+0x85E2	0xB078	#HANGUL SYLLABLE SSANGKIYEOK YI KHIEUKH
+0x85E3	0xB079	#HANGUL SYLLABLE SSANGKIYEOK YI THIEUTH
+0x85E4	0xB07A	#HANGUL SYLLABLE SSANGKIYEOK YI PHIEUPH
+0x85E5	0xB07B	#HANGUL SYLLABLE SSANGKIYEOK YI HIEUH
+0x85E6	0xB07E	#HANGUL SYLLABLE SSANGKIYEOK I SSANGKIYEOK
+0x85E7	0xB07F	#HANGUL SYLLABLE SSANGKIYEOK I KIYEOKSIOS
+0x85E8	0xB081	#HANGUL SYLLABLE SSANGKIYEOK I NIEUNCIEUC
+0x85E9	0xB082	#HANGUL SYLLABLE SSANGKIYEOK I NIEUNHIEUH
+0x85EA	0xB083	#HANGUL SYLLABLE SSANGKIYEOK I TIKEUT
+0x85EB	0xB085	#HANGUL SYLLABLE SSANGKIYEOK I RIEULKIYEOK
+0x85EC	0xB086	#HANGUL SYLLABLE SSANGKIYEOK I RIEULMIEUM
+0x85ED	0xB087	#HANGUL SYLLABLE SSANGKIYEOK I RIEULPIEUP
+0x85EE	0xB088	#HANGUL SYLLABLE SSANGKIYEOK I RIEULSIOS
+0x85EF	0xB089	#HANGUL SYLLABLE SSANGKIYEOK I RIEULTHIEUTH
+0x85F0	0xB08A	#HANGUL SYLLABLE SSANGKIYEOK I RIEULPHIEUPH
+0x85F1	0xB08B	#HANGUL SYLLABLE SSANGKIYEOK I RIEULHIEUH
+0x85F2	0xB08E	#HANGUL SYLLABLE SSANGKIYEOK I PIEUPSIOS
+0x85F3	0xB090	#HANGUL SYLLABLE SSANGKIYEOK I SSANGSIOS
+0x85F4	0xB092	#HANGUL SYLLABLE SSANGKIYEOK I CIEUC
+0x85F5	0xB093	#HANGUL SYLLABLE SSANGKIYEOK I CHIEUCH
+0x85F6	0xB094	#HANGUL SYLLABLE SSANGKIYEOK I KHIEUKH
+0x85F7	0xB095	#HANGUL SYLLABLE SSANGKIYEOK I THIEUTH
+0x85F8	0xB096	#HANGUL SYLLABLE SSANGKIYEOK I PHIEUPH
+0x85F9	0xB097	#HANGUL SYLLABLE SSANGKIYEOK I HIEUH
+0x85FA	0xB09B	#HANGUL SYLLABLE NIEUN A KIYEOKSIOS
+0x85FB	0xB09D	#HANGUL SYLLABLE NIEUN A NIEUNCIEUC
+0x85FC	0xB09E	#HANGUL SYLLABLE NIEUN A NIEUNHIEUH
+0x85FD	0xB0A3	#HANGUL SYLLABLE NIEUN A RIEULPIEUP
+0x85FE	0xB0A4	#HANGUL SYLLABLE NIEUN A RIEULSIOS
+0x8641	0xB0A5	#HANGUL SYLLABLE NIEUN A RIEULTHIEUTH
+0x8642	0xB0A6	#HANGUL SYLLABLE NIEUN A RIEULPHIEUPH
+0x8643	0xB0A7	#HANGUL SYLLABLE NIEUN A RIEULHIEUH
+0x8644	0xB0AA	#HANGUL SYLLABLE NIEUN A PIEUPSIOS
+0x8645	0xB0B0	#HANGUL SYLLABLE NIEUN A KHIEUKH
+0x8646	0xB0B2	#HANGUL SYLLABLE NIEUN A PHIEUPH
+0x8647	0xB0B6	#HANGUL SYLLABLE NIEUN AE SSANGKIYEOK
+0x8648	0xB0B7	#HANGUL SYLLABLE NIEUN AE KIYEOKSIOS
+0x8649	0xB0B9	#HANGUL SYLLABLE NIEUN AE NIEUNCIEUC
+0x864A	0xB0BA	#HANGUL SYLLABLE NIEUN AE NIEUNHIEUH
+0x864B	0xB0BB	#HANGUL SYLLABLE NIEUN AE TIKEUT
+0x864C	0xB0BD	#HANGUL SYLLABLE NIEUN AE RIEULKIYEOK
+0x864D	0xB0BE	#HANGUL SYLLABLE NIEUN AE RIEULMIEUM
+0x864E	0xB0BF	#HANGUL SYLLABLE NIEUN AE RIEULPIEUP
+0x864F	0xB0C0	#HANGUL SYLLABLE NIEUN AE RIEULSIOS
+0x8650	0xB0C1	#HANGUL SYLLABLE NIEUN AE RIEULTHIEUTH
+0x8651	0xB0C2	#HANGUL SYLLABLE NIEUN AE RIEULPHIEUPH
+0x8652	0xB0C3	#HANGUL SYLLABLE NIEUN AE RIEULHIEUH
+0x8653	0xB0C6	#HANGUL SYLLABLE NIEUN AE PIEUPSIOS
+0x8654	0xB0CA	#HANGUL SYLLABLE NIEUN AE CIEUC
+0x8655	0xB0CB	#HANGUL SYLLABLE NIEUN AE CHIEUCH
+0x8656	0xB0CC	#HANGUL SYLLABLE NIEUN AE KHIEUKH
+0x8657	0xB0CD	#HANGUL SYLLABLE NIEUN AE THIEUTH
+0x8658	0xB0CE	#HANGUL SYLLABLE NIEUN AE PHIEUPH
+0x8659	0xB0CF	#HANGUL SYLLABLE NIEUN AE HIEUH
+0x865A	0xB0D2	#HANGUL SYLLABLE NIEUN YA SSANGKIYEOK
+0x8661	0xB0D3	#HANGUL SYLLABLE NIEUN YA KIYEOKSIOS
+0x8662	0xB0D5	#HANGUL SYLLABLE NIEUN YA NIEUNCIEUC
+0x8663	0xB0D6	#HANGUL SYLLABLE NIEUN YA NIEUNHIEUH
+0x8664	0xB0D7	#HANGUL SYLLABLE NIEUN YA TIKEUT
+0x8665	0xB0D9	#HANGUL SYLLABLE NIEUN YA RIEULKIYEOK
+0x8666	0xB0DA	#HANGUL SYLLABLE NIEUN YA RIEULMIEUM
+0x8667	0xB0DB	#HANGUL SYLLABLE NIEUN YA RIEULPIEUP
+0x8668	0xB0DC	#HANGUL SYLLABLE NIEUN YA RIEULSIOS
+0x8669	0xB0DD	#HANGUL SYLLABLE NIEUN YA RIEULTHIEUTH
+0x866A	0xB0DE	#HANGUL SYLLABLE NIEUN YA RIEULPHIEUPH
+0x866B	0xB0DF	#HANGUL SYLLABLE NIEUN YA RIEULHIEUH
+0x866C	0xB0E1	#HANGUL SYLLABLE NIEUN YA PIEUP
+0x866D	0xB0E2	#HANGUL SYLLABLE NIEUN YA PIEUPSIOS
+0x866E	0xB0E3	#HANGUL SYLLABLE NIEUN YA SIOS
+0x866F	0xB0E4	#HANGUL SYLLABLE NIEUN YA SSANGSIOS
+0x8670	0xB0E6	#HANGUL SYLLABLE NIEUN YA CIEUC
+0x8671	0xB0E7	#HANGUL SYLLABLE NIEUN YA CHIEUCH
+0x8672	0xB0E8	#HANGUL SYLLABLE NIEUN YA KHIEUKH
+0x8673	0xB0E9	#HANGUL SYLLABLE NIEUN YA THIEUTH
+0x8674	0xB0EA	#HANGUL SYLLABLE NIEUN YA PHIEUPH
+0x8675	0xB0EB	#HANGUL SYLLABLE NIEUN YA HIEUH
+0x8676	0xB0EC	#HANGUL SYLLABLE NIEUN YAE
+0x8677	0xB0ED	#HANGUL SYLLABLE NIEUN YAE KIYEOK
+0x8678	0xB0EE	#HANGUL SYLLABLE NIEUN YAE SSANGKIYEOK
+0x8679	0xB0EF	#HANGUL SYLLABLE NIEUN YAE KIYEOKSIOS
+0x867A	0xB0F0	#HANGUL SYLLABLE NIEUN YAE NIEUN
+0x8681	0xB0F1	#HANGUL SYLLABLE NIEUN YAE NIEUNCIEUC
+0x8682	0xB0F2	#HANGUL SYLLABLE NIEUN YAE NIEUNHIEUH
+0x8683	0xB0F3	#HANGUL SYLLABLE NIEUN YAE TIKEUT
+0x8684	0xB0F4	#HANGUL SYLLABLE NIEUN YAE RIEUL
+0x8685	0xB0F5	#HANGUL SYLLABLE NIEUN YAE RIEULKIYEOK
+0x8686	0xB0F6	#HANGUL SYLLABLE NIEUN YAE RIEULMIEUM
+0x8687	0xB0F7	#HANGUL SYLLABLE NIEUN YAE RIEULPIEUP
+0x8688	0xB0F8	#HANGUL SYLLABLE NIEUN YAE RIEULSIOS
+0x8689	0xB0F9	#HANGUL SYLLABLE NIEUN YAE RIEULTHIEUTH
+0x868A	0xB0FA	#HANGUL SYLLABLE NIEUN YAE RIEULPHIEUPH
+0x868B	0xB0FB	#HANGUL SYLLABLE NIEUN YAE RIEULHIEUH
+0x868C	0xB0FC	#HANGUL SYLLABLE NIEUN YAE MIEUM
+0x868D	0xB0FD	#HANGUL SYLLABLE NIEUN YAE PIEUP
+0x868E	0xB0FE	#HANGUL SYLLABLE NIEUN YAE PIEUPSIOS
+0x868F	0xB0FF	#HANGUL SYLLABLE NIEUN YAE SIOS
+0x8690	0xB100	#HANGUL SYLLABLE NIEUN YAE SSANGSIOS
+0x8691	0xB101	#HANGUL SYLLABLE NIEUN YAE IEUNG
+0x8692	0xB102	#HANGUL SYLLABLE NIEUN YAE CIEUC
+0x8693	0xB103	#HANGUL SYLLABLE NIEUN YAE CHIEUCH
+0x8694	0xB104	#HANGUL SYLLABLE NIEUN YAE KHIEUKH
+0x8695	0xB105	#HANGUL SYLLABLE NIEUN YAE THIEUTH
+0x8696	0xB106	#HANGUL SYLLABLE NIEUN YAE PHIEUPH
+0x8697	0xB107	#HANGUL SYLLABLE NIEUN YAE HIEUH
+0x8698	0xB10A	#HANGUL SYLLABLE NIEUN EO SSANGKIYEOK
+0x8699	0xB10D	#HANGUL SYLLABLE NIEUN EO NIEUNCIEUC
+0x869A	0xB10E	#HANGUL SYLLABLE NIEUN EO NIEUNHIEUH
+0x869B	0xB10F	#HANGUL SYLLABLE NIEUN EO TIKEUT
+0x869C	0xB111	#HANGUL SYLLABLE NIEUN EO RIEULKIYEOK
+0x869D	0xB114	#HANGUL SYLLABLE NIEUN EO RIEULSIOS
+0x869E	0xB115	#HANGUL SYLLABLE NIEUN EO RIEULTHIEUTH
+0x869F	0xB116	#HANGUL SYLLABLE NIEUN EO RIEULPHIEUPH
+0x86A0	0xB117	#HANGUL SYLLABLE NIEUN EO RIEULHIEUH
+0x86A1	0xB11A	#HANGUL SYLLABLE NIEUN EO PIEUPSIOS
+0x86A2	0xB11E	#HANGUL SYLLABLE NIEUN EO CIEUC
+0x86A3	0xB11F	#HANGUL SYLLABLE NIEUN EO CHIEUCH
+0x86A4	0xB120	#HANGUL SYLLABLE NIEUN EO KHIEUKH
+0x86A5	0xB121	#HANGUL SYLLABLE NIEUN EO THIEUTH
+0x86A6	0xB122	#HANGUL SYLLABLE NIEUN EO PHIEUPH
+0x86A7	0xB126	#HANGUL SYLLABLE NIEUN E SSANGKIYEOK
+0x86A8	0xB127	#HANGUL SYLLABLE NIEUN E KIYEOKSIOS
+0x86A9	0xB129	#HANGUL SYLLABLE NIEUN E NIEUNCIEUC
+0x86AA	0xB12A	#HANGUL SYLLABLE NIEUN E NIEUNHIEUH
+0x86AB	0xB12B	#HANGUL SYLLABLE NIEUN E TIKEUT
+0x86AC	0xB12D	#HANGUL SYLLABLE NIEUN E RIEULKIYEOK
+0x86AD	0xB12E	#HANGUL SYLLABLE NIEUN E RIEULMIEUM
+0x86AE	0xB12F	#HANGUL SYLLABLE NIEUN E RIEULPIEUP
+0x86AF	0xB130	#HANGUL SYLLABLE NIEUN E RIEULSIOS
+0x86B0	0xB131	#HANGUL SYLLABLE NIEUN E RIEULTHIEUTH
+0x86B1	0xB132	#HANGUL SYLLABLE NIEUN E RIEULPHIEUPH
+0x86B2	0xB133	#HANGUL SYLLABLE NIEUN E RIEULHIEUH
+0x86B3	0xB136	#HANGUL SYLLABLE NIEUN E PIEUPSIOS
+0x86B4	0xB13A	#HANGUL SYLLABLE NIEUN E CIEUC
+0x86B5	0xB13B	#HANGUL SYLLABLE NIEUN E CHIEUCH
+0x86B6	0xB13C	#HANGUL SYLLABLE NIEUN E KHIEUKH
+0x86B7	0xB13D	#HANGUL SYLLABLE NIEUN E THIEUTH
+0x86B8	0xB13E	#HANGUL SYLLABLE NIEUN E PHIEUPH
+0x86B9	0xB13F	#HANGUL SYLLABLE NIEUN E HIEUH
+0x86BA	0xB142	#HANGUL SYLLABLE NIEUN YEO SSANGKIYEOK
+0x86BB	0xB143	#HANGUL SYLLABLE NIEUN YEO KIYEOKSIOS
+0x86BC	0xB145	#HANGUL SYLLABLE NIEUN YEO NIEUNCIEUC
+0x86BD	0xB146	#HANGUL SYLLABLE NIEUN YEO NIEUNHIEUH
+0x86BE	0xB147	#HANGUL SYLLABLE NIEUN YEO TIKEUT
+0x86BF	0xB149	#HANGUL SYLLABLE NIEUN YEO RIEULKIYEOK
+0x86C0	0xB14A	#HANGUL SYLLABLE NIEUN YEO RIEULMIEUM
+0x86C1	0xB14B	#HANGUL SYLLABLE NIEUN YEO RIEULPIEUP
+0x86C2	0xB14C	#HANGUL SYLLABLE NIEUN YEO RIEULSIOS
+0x86C3	0xB14D	#HANGUL SYLLABLE NIEUN YEO RIEULTHIEUTH
+0x86C4	0xB14E	#HANGUL SYLLABLE NIEUN YEO RIEULPHIEUPH
+0x86C5	0xB14F	#HANGUL SYLLABLE NIEUN YEO RIEULHIEUH
+0x86C6	0xB152	#HANGUL SYLLABLE NIEUN YEO PIEUPSIOS
+0x86C7	0xB153	#HANGUL SYLLABLE NIEUN YEO SIOS
+0x86C8	0xB156	#HANGUL SYLLABLE NIEUN YEO CIEUC
+0x86C9	0xB157	#HANGUL SYLLABLE NIEUN YEO CHIEUCH
+0x86CA	0xB159	#HANGUL SYLLABLE NIEUN YEO THIEUTH
+0x86CB	0xB15A	#HANGUL SYLLABLE NIEUN YEO PHIEUPH
+0x86CC	0xB15B	#HANGUL SYLLABLE NIEUN YEO HIEUH
+0x86CD	0xB15D	#HANGUL SYLLABLE NIEUN YE KIYEOK
+0x86CE	0xB15E	#HANGUL SYLLABLE NIEUN YE SSANGKIYEOK
+0x86CF	0xB15F	#HANGUL SYLLABLE NIEUN YE KIYEOKSIOS
+0x86D0	0xB161	#HANGUL SYLLABLE NIEUN YE NIEUNCIEUC
+0x86D1	0xB162	#HANGUL SYLLABLE NIEUN YE NIEUNHIEUH
+0x86D2	0xB163	#HANGUL SYLLABLE NIEUN YE TIKEUT
+0x86D3	0xB164	#HANGUL SYLLABLE NIEUN YE RIEUL
+0x86D4	0xB165	#HANGUL SYLLABLE NIEUN YE RIEULKIYEOK
+0x86D5	0xB166	#HANGUL SYLLABLE NIEUN YE RIEULMIEUM
+0x86D6	0xB167	#HANGUL SYLLABLE NIEUN YE RIEULPIEUP
+0x86D7	0xB168	#HANGUL SYLLABLE NIEUN YE RIEULSIOS
+0x86D8	0xB169	#HANGUL SYLLABLE NIEUN YE RIEULTHIEUTH
+0x86D9	0xB16A	#HANGUL SYLLABLE NIEUN YE RIEULPHIEUPH
+0x86DA	0xB16B	#HANGUL SYLLABLE NIEUN YE RIEULHIEUH
+0x86DB	0xB16C	#HANGUL SYLLABLE NIEUN YE MIEUM
+0x86DC	0xB16D	#HANGUL SYLLABLE NIEUN YE PIEUP
+0x86DD	0xB16E	#HANGUL SYLLABLE NIEUN YE PIEUPSIOS
+0x86DE	0xB16F	#HANGUL SYLLABLE NIEUN YE SIOS
+0x86DF	0xB170	#HANGUL SYLLABLE NIEUN YE SSANGSIOS
+0x86E0	0xB171	#HANGUL SYLLABLE NIEUN YE IEUNG
+0x86E1	0xB172	#HANGUL SYLLABLE NIEUN YE CIEUC
+0x86E2	0xB173	#HANGUL SYLLABLE NIEUN YE CHIEUCH
+0x86E3	0xB174	#HANGUL SYLLABLE NIEUN YE KHIEUKH
+0x86E4	0xB175	#HANGUL SYLLABLE NIEUN YE THIEUTH
+0x86E5	0xB176	#HANGUL SYLLABLE NIEUN YE PHIEUPH
+0x86E6	0xB177	#HANGUL SYLLABLE NIEUN YE HIEUH
+0x86E7	0xB17A	#HANGUL SYLLABLE NIEUN O SSANGKIYEOK
+0x86E8	0xB17B	#HANGUL SYLLABLE NIEUN O KIYEOKSIOS
+0x86E9	0xB17D	#HANGUL SYLLABLE NIEUN O NIEUNCIEUC
+0x86EA	0xB17E	#HANGUL SYLLABLE NIEUN O NIEUNHIEUH
+0x86EB	0xB17F	#HANGUL SYLLABLE NIEUN O TIKEUT
+0x86EC	0xB181	#HANGUL SYLLABLE NIEUN O RIEULKIYEOK
+0x86ED	0xB183	#HANGUL SYLLABLE NIEUN O RIEULPIEUP
+0x86EE	0xB184	#HANGUL SYLLABLE NIEUN O RIEULSIOS
+0x86EF	0xB185	#HANGUL SYLLABLE NIEUN O RIEULTHIEUTH
+0x86F0	0xB186	#HANGUL SYLLABLE NIEUN O RIEULPHIEUPH
+0x86F1	0xB187	#HANGUL SYLLABLE NIEUN O RIEULHIEUH
+0x86F2	0xB18A	#HANGUL SYLLABLE NIEUN O PIEUPSIOS
+0x86F3	0xB18C	#HANGUL SYLLABLE NIEUN O SSANGSIOS
+0x86F4	0xB18E	#HANGUL SYLLABLE NIEUN O CIEUC
+0x86F5	0xB18F	#HANGUL SYLLABLE NIEUN O CHIEUCH
+0x86F6	0xB190	#HANGUL SYLLABLE NIEUN O KHIEUKH
+0x86F7	0xB191	#HANGUL SYLLABLE NIEUN O THIEUTH
+0x86F8	0xB195	#HANGUL SYLLABLE NIEUN WA KIYEOK
+0x86F9	0xB196	#HANGUL SYLLABLE NIEUN WA SSANGKIYEOK
+0x86FA	0xB197	#HANGUL SYLLABLE NIEUN WA KIYEOKSIOS
+0x86FB	0xB199	#HANGUL SYLLABLE NIEUN WA NIEUNCIEUC
+0x86FC	0xB19A	#HANGUL SYLLABLE NIEUN WA NIEUNHIEUH
+0x86FD	0xB19B	#HANGUL SYLLABLE NIEUN WA TIKEUT
+0x86FE	0xB19D	#HANGUL SYLLABLE NIEUN WA RIEULKIYEOK
+0x8741	0xB19E	#HANGUL SYLLABLE NIEUN WA RIEULMIEUM
+0x8742	0xB19F	#HANGUL SYLLABLE NIEUN WA RIEULPIEUP
+0x8743	0xB1A0	#HANGUL SYLLABLE NIEUN WA RIEULSIOS
+0x8744	0xB1A1	#HANGUL SYLLABLE NIEUN WA RIEULTHIEUTH
+0x8745	0xB1A2	#HANGUL SYLLABLE NIEUN WA RIEULPHIEUPH
+0x8746	0xB1A3	#HANGUL SYLLABLE NIEUN WA RIEULHIEUH
+0x8747	0xB1A4	#HANGUL SYLLABLE NIEUN WA MIEUM
+0x8748	0xB1A5	#HANGUL SYLLABLE NIEUN WA PIEUP
+0x8749	0xB1A6	#HANGUL SYLLABLE NIEUN WA PIEUPSIOS
+0x874A	0xB1A7	#HANGUL SYLLABLE NIEUN WA SIOS
+0x874B	0xB1A9	#HANGUL SYLLABLE NIEUN WA IEUNG
+0x874C	0xB1AA	#HANGUL SYLLABLE NIEUN WA CIEUC
+0x874D	0xB1AB	#HANGUL SYLLABLE NIEUN WA CHIEUCH
+0x874E	0xB1AC	#HANGUL SYLLABLE NIEUN WA KHIEUKH
+0x874F	0xB1AD	#HANGUL SYLLABLE NIEUN WA THIEUTH
+0x8750	0xB1AE	#HANGUL SYLLABLE NIEUN WA PHIEUPH
+0x8751	0xB1AF	#HANGUL SYLLABLE NIEUN WA HIEUH
+0x8752	0xB1B0	#HANGUL SYLLABLE NIEUN WAE
+0x8753	0xB1B1	#HANGUL SYLLABLE NIEUN WAE KIYEOK
+0x8754	0xB1B2	#HANGUL SYLLABLE NIEUN WAE SSANGKIYEOK
+0x8755	0xB1B3	#HANGUL SYLLABLE NIEUN WAE KIYEOKSIOS
+0x8756	0xB1B4	#HANGUL SYLLABLE NIEUN WAE NIEUN
+0x8757	0xB1B5	#HANGUL SYLLABLE NIEUN WAE NIEUNCIEUC
+0x8758	0xB1B6	#HANGUL SYLLABLE NIEUN WAE NIEUNHIEUH
+0x8759	0xB1B7	#HANGUL SYLLABLE NIEUN WAE TIKEUT
+0x875A	0xB1B8	#HANGUL SYLLABLE NIEUN WAE RIEUL
+0x8761	0xB1B9	#HANGUL SYLLABLE NIEUN WAE RIEULKIYEOK
+0x8762	0xB1BA	#HANGUL SYLLABLE NIEUN WAE RIEULMIEUM
+0x8763	0xB1BB	#HANGUL SYLLABLE NIEUN WAE RIEULPIEUP
+0x8764	0xB1BC	#HANGUL SYLLABLE NIEUN WAE RIEULSIOS
+0x8765	0xB1BD	#HANGUL SYLLABLE NIEUN WAE RIEULTHIEUTH
+0x8766	0xB1BE	#HANGUL SYLLABLE NIEUN WAE RIEULPHIEUPH
+0x8767	0xB1BF	#HANGUL SYLLABLE NIEUN WAE RIEULHIEUH
+0x8768	0xB1C0	#HANGUL SYLLABLE NIEUN WAE MIEUM
+0x8769	0xB1C1	#HANGUL SYLLABLE NIEUN WAE PIEUP
+0x876A	0xB1C2	#HANGUL SYLLABLE NIEUN WAE PIEUPSIOS
+0x876B	0xB1C3	#HANGUL SYLLABLE NIEUN WAE SIOS
+0x876C	0xB1C4	#HANGUL SYLLABLE NIEUN WAE SSANGSIOS
+0x876D	0xB1C5	#HANGUL SYLLABLE NIEUN WAE IEUNG
+0x876E	0xB1C6	#HANGUL SYLLABLE NIEUN WAE CIEUC
+0x876F	0xB1C7	#HANGUL SYLLABLE NIEUN WAE CHIEUCH
+0x8770	0xB1C8	#HANGUL SYLLABLE NIEUN WAE KHIEUKH
+0x8771	0xB1C9	#HANGUL SYLLABLE NIEUN WAE THIEUTH
+0x8772	0xB1CA	#HANGUL SYLLABLE NIEUN WAE PHIEUPH
+0x8773	0xB1CB	#HANGUL SYLLABLE NIEUN WAE HIEUH
+0x8774	0xB1CD	#HANGUL SYLLABLE NIEUN OE KIYEOK
+0x8775	0xB1CE	#HANGUL SYLLABLE NIEUN OE SSANGKIYEOK
+0x8776	0xB1CF	#HANGUL SYLLABLE NIEUN OE KIYEOKSIOS
+0x8777	0xB1D1	#HANGUL SYLLABLE NIEUN OE NIEUNCIEUC
+0x8778	0xB1D2	#HANGUL SYLLABLE NIEUN OE NIEUNHIEUH
+0x8779	0xB1D3	#HANGUL SYLLABLE NIEUN OE TIKEUT
+0x877A	0xB1D5	#HANGUL SYLLABLE NIEUN OE RIEULKIYEOK
+0x8781	0xB1D6	#HANGUL SYLLABLE NIEUN OE RIEULMIEUM
+0x8782	0xB1D7	#HANGUL SYLLABLE NIEUN OE RIEULPIEUP
+0x8783	0xB1D8	#HANGUL SYLLABLE NIEUN OE RIEULSIOS
+0x8784	0xB1D9	#HANGUL SYLLABLE NIEUN OE RIEULTHIEUTH
+0x8785	0xB1DA	#HANGUL SYLLABLE NIEUN OE RIEULPHIEUPH
+0x8786	0xB1DB	#HANGUL SYLLABLE NIEUN OE RIEULHIEUH
+0x8787	0xB1DE	#HANGUL SYLLABLE NIEUN OE PIEUPSIOS
+0x8788	0xB1E0	#HANGUL SYLLABLE NIEUN OE SSANGSIOS
+0x8789	0xB1E1	#HANGUL SYLLABLE NIEUN OE IEUNG
+0x878A	0xB1E2	#HANGUL SYLLABLE NIEUN OE CIEUC
+0x878B	0xB1E3	#HANGUL SYLLABLE NIEUN OE CHIEUCH
+0x878C	0xB1E4	#HANGUL SYLLABLE NIEUN OE KHIEUKH
+0x878D	0xB1E5	#HANGUL SYLLABLE NIEUN OE THIEUTH
+0x878E	0xB1E6	#HANGUL SYLLABLE NIEUN OE PHIEUPH
+0x878F	0xB1E7	#HANGUL SYLLABLE NIEUN OE HIEUH
+0x8790	0xB1EA	#HANGUL SYLLABLE NIEUN YO SSANGKIYEOK
+0x8791	0xB1EB	#HANGUL SYLLABLE NIEUN YO KIYEOKSIOS
+0x8792	0xB1ED	#HANGUL SYLLABLE NIEUN YO NIEUNCIEUC
+0x8793	0xB1EE	#HANGUL SYLLABLE NIEUN YO NIEUNHIEUH
+0x8794	0xB1EF	#HANGUL SYLLABLE NIEUN YO TIKEUT
+0x8795	0xB1F1	#HANGUL SYLLABLE NIEUN YO RIEULKIYEOK
+0x8796	0xB1F2	#HANGUL SYLLABLE NIEUN YO RIEULMIEUM
+0x8797	0xB1F3	#HANGUL SYLLABLE NIEUN YO RIEULPIEUP
+0x8798	0xB1F4	#HANGUL SYLLABLE NIEUN YO RIEULSIOS
+0x8799	0xB1F5	#HANGUL SYLLABLE NIEUN YO RIEULTHIEUTH
+0x879A	0xB1F6	#HANGUL SYLLABLE NIEUN YO RIEULPHIEUPH
+0x879B	0xB1F7	#HANGUL SYLLABLE NIEUN YO RIEULHIEUH
+0x879C	0xB1F8	#HANGUL SYLLABLE NIEUN YO MIEUM
+0x879D	0xB1FA	#HANGUL SYLLABLE NIEUN YO PIEUPSIOS
+0x879E	0xB1FC	#HANGUL SYLLABLE NIEUN YO SSANGSIOS
+0x879F	0xB1FE	#HANGUL SYLLABLE NIEUN YO CIEUC
+0x87A0	0xB1FF	#HANGUL SYLLABLE NIEUN YO CHIEUCH
+0x87A1	0xB200	#HANGUL SYLLABLE NIEUN YO KHIEUKH
+0x87A2	0xB201	#HANGUL SYLLABLE NIEUN YO THIEUTH
+0x87A3	0xB202	#HANGUL SYLLABLE NIEUN YO PHIEUPH
+0x87A4	0xB203	#HANGUL SYLLABLE NIEUN YO HIEUH
+0x87A5	0xB206	#HANGUL SYLLABLE NIEUN U SSANGKIYEOK
+0x87A6	0xB207	#HANGUL SYLLABLE NIEUN U KIYEOKSIOS
+0x87A7	0xB209	#HANGUL SYLLABLE NIEUN U NIEUNCIEUC
+0x87A8	0xB20A	#HANGUL SYLLABLE NIEUN U NIEUNHIEUH
+0x87A9	0xB20D	#HANGUL SYLLABLE NIEUN U RIEULKIYEOK
+0x87AA	0xB20E	#HANGUL SYLLABLE NIEUN U RIEULMIEUM
+0x87AB	0xB20F	#HANGUL SYLLABLE NIEUN U RIEULPIEUP
+0x87AC	0xB210	#HANGUL SYLLABLE NIEUN U RIEULSIOS
+0x87AD	0xB211	#HANGUL SYLLABLE NIEUN U RIEULTHIEUTH
+0x87AE	0xB212	#HANGUL SYLLABLE NIEUN U RIEULPHIEUPH
+0x87AF	0xB213	#HANGUL SYLLABLE NIEUN U RIEULHIEUH
+0x87B0	0xB216	#HANGUL SYLLABLE NIEUN U PIEUPSIOS
+0x87B1	0xB218	#HANGUL SYLLABLE NIEUN U SSANGSIOS
+0x87B2	0xB21A	#HANGUL SYLLABLE NIEUN U CIEUC
+0x87B3	0xB21B	#HANGUL SYLLABLE NIEUN U CHIEUCH
+0x87B4	0xB21C	#HANGUL SYLLABLE NIEUN U KHIEUKH
+0x87B5	0xB21D	#HANGUL SYLLABLE NIEUN U THIEUTH
+0x87B6	0xB21E	#HANGUL SYLLABLE NIEUN U PHIEUPH
+0x87B7	0xB21F	#HANGUL SYLLABLE NIEUN U HIEUH
+0x87B8	0xB221	#HANGUL SYLLABLE NIEUN WEO KIYEOK
+0x87B9	0xB222	#HANGUL SYLLABLE NIEUN WEO SSANGKIYEOK
+0x87BA	0xB223	#HANGUL SYLLABLE NIEUN WEO KIYEOKSIOS
+0x87BB	0xB224	#HANGUL SYLLABLE NIEUN WEO NIEUN
+0x87BC	0xB225	#HANGUL SYLLABLE NIEUN WEO NIEUNCIEUC
+0x87BD	0xB226	#HANGUL SYLLABLE NIEUN WEO NIEUNHIEUH
+0x87BE	0xB227	#HANGUL SYLLABLE NIEUN WEO TIKEUT
+0x87BF	0xB228	#HANGUL SYLLABLE NIEUN WEO RIEUL
+0x87C0	0xB229	#HANGUL SYLLABLE NIEUN WEO RIEULKIYEOK
+0x87C1	0xB22A	#HANGUL SYLLABLE NIEUN WEO RIEULMIEUM
+0x87C2	0xB22B	#HANGUL SYLLABLE NIEUN WEO RIEULPIEUP
+0x87C3	0xB22C	#HANGUL SYLLABLE NIEUN WEO RIEULSIOS
+0x87C4	0xB22D	#HANGUL SYLLABLE NIEUN WEO RIEULTHIEUTH
+0x87C5	0xB22E	#HANGUL SYLLABLE NIEUN WEO RIEULPHIEUPH
+0x87C6	0xB22F	#HANGUL SYLLABLE NIEUN WEO RIEULHIEUH
+0x87C7	0xB230	#HANGUL SYLLABLE NIEUN WEO MIEUM
+0x87C8	0xB231	#HANGUL SYLLABLE NIEUN WEO PIEUP
+0x87C9	0xB232	#HANGUL SYLLABLE NIEUN WEO PIEUPSIOS
+0x87CA	0xB233	#HANGUL SYLLABLE NIEUN WEO SIOS
+0x87CB	0xB235	#HANGUL SYLLABLE NIEUN WEO IEUNG
+0x87CC	0xB236	#HANGUL SYLLABLE NIEUN WEO CIEUC
+0x87CD	0xB237	#HANGUL SYLLABLE NIEUN WEO CHIEUCH
+0x87CE	0xB238	#HANGUL SYLLABLE NIEUN WEO KHIEUKH
+0x87CF	0xB239	#HANGUL SYLLABLE NIEUN WEO THIEUTH
+0x87D0	0xB23A	#HANGUL SYLLABLE NIEUN WEO PHIEUPH
+0x87D1	0xB23B	#HANGUL SYLLABLE NIEUN WEO HIEUH
+0x87D2	0xB23D	#HANGUL SYLLABLE NIEUN WE KIYEOK
+0x87D3	0xB23E	#HANGUL SYLLABLE NIEUN WE SSANGKIYEOK
+0x87D4	0xB23F	#HANGUL SYLLABLE NIEUN WE KIYEOKSIOS
+0x87D5	0xB240	#HANGUL SYLLABLE NIEUN WE NIEUN
+0x87D6	0xB241	#HANGUL SYLLABLE NIEUN WE NIEUNCIEUC
+0x87D7	0xB242	#HANGUL SYLLABLE NIEUN WE NIEUNHIEUH
+0x87D8	0xB243	#HANGUL SYLLABLE NIEUN WE TIKEUT
+0x87D9	0xB244	#HANGUL SYLLABLE NIEUN WE RIEUL
+0x87DA	0xB245	#HANGUL SYLLABLE NIEUN WE RIEULKIYEOK
+0x87DB	0xB246	#HANGUL SYLLABLE NIEUN WE RIEULMIEUM
+0x87DC	0xB247	#HANGUL SYLLABLE NIEUN WE RIEULPIEUP
+0x87DD	0xB248	#HANGUL SYLLABLE NIEUN WE RIEULSIOS
+0x87DE	0xB249	#HANGUL SYLLABLE NIEUN WE RIEULTHIEUTH
+0x87DF	0xB24A	#HANGUL SYLLABLE NIEUN WE RIEULPHIEUPH
+0x87E0	0xB24B	#HANGUL SYLLABLE NIEUN WE RIEULHIEUH
+0x87E1	0xB24C	#HANGUL SYLLABLE NIEUN WE MIEUM
+0x87E2	0xB24D	#HANGUL SYLLABLE NIEUN WE PIEUP
+0x87E3	0xB24E	#HANGUL SYLLABLE NIEUN WE PIEUPSIOS
+0x87E4	0xB24F	#HANGUL SYLLABLE NIEUN WE SIOS
+0x87E5	0xB250	#HANGUL SYLLABLE NIEUN WE SSANGSIOS
+0x87E6	0xB251	#HANGUL SYLLABLE NIEUN WE IEUNG
+0x87E7	0xB252	#HANGUL SYLLABLE NIEUN WE CIEUC
+0x87E8	0xB253	#HANGUL SYLLABLE NIEUN WE CHIEUCH
+0x87E9	0xB254	#HANGUL SYLLABLE NIEUN WE KHIEUKH
+0x87EA	0xB255	#HANGUL SYLLABLE NIEUN WE THIEUTH
+0x87EB	0xB256	#HANGUL SYLLABLE NIEUN WE PHIEUPH
+0x87EC	0xB257	#HANGUL SYLLABLE NIEUN WE HIEUH
+0x87ED	0xB259	#HANGUL SYLLABLE NIEUN WI KIYEOK
+0x87EE	0xB25A	#HANGUL SYLLABLE NIEUN WI SSANGKIYEOK
+0x87EF	0xB25B	#HANGUL SYLLABLE NIEUN WI KIYEOKSIOS
+0x87F0	0xB25D	#HANGUL SYLLABLE NIEUN WI NIEUNCIEUC
+0x87F1	0xB25E	#HANGUL SYLLABLE NIEUN WI NIEUNHIEUH
+0x87F2	0xB25F	#HANGUL SYLLABLE NIEUN WI TIKEUT
+0x87F3	0xB261	#HANGUL SYLLABLE NIEUN WI RIEULKIYEOK
+0x87F4	0xB262	#HANGUL SYLLABLE NIEUN WI RIEULMIEUM
+0x87F5	0xB263	#HANGUL SYLLABLE NIEUN WI RIEULPIEUP
+0x87F6	0xB264	#HANGUL SYLLABLE NIEUN WI RIEULSIOS
+0x87F7	0xB265	#HANGUL SYLLABLE NIEUN WI RIEULTHIEUTH
+0x87F8	0xB266	#HANGUL SYLLABLE NIEUN WI RIEULPHIEUPH
+0x87F9	0xB267	#HANGUL SYLLABLE NIEUN WI RIEULHIEUH
+0x87FA	0xB26A	#HANGUL SYLLABLE NIEUN WI PIEUPSIOS
+0x87FB	0xB26B	#HANGUL SYLLABLE NIEUN WI SIOS
+0x87FC	0xB26C	#HANGUL SYLLABLE NIEUN WI SSANGSIOS
+0x87FD	0xB26D	#HANGUL SYLLABLE NIEUN WI IEUNG
+0x87FE	0xB26E	#HANGUL SYLLABLE NIEUN WI CIEUC
+0x8841	0xB26F	#HANGUL SYLLABLE NIEUN WI CHIEUCH
+0x8842	0xB270	#HANGUL SYLLABLE NIEUN WI KHIEUKH
+0x8843	0xB271	#HANGUL SYLLABLE NIEUN WI THIEUTH
+0x8844	0xB272	#HANGUL SYLLABLE NIEUN WI PHIEUPH
+0x8845	0xB273	#HANGUL SYLLABLE NIEUN WI HIEUH
+0x8846	0xB276	#HANGUL SYLLABLE NIEUN YU SSANGKIYEOK
+0x8847	0xB277	#HANGUL SYLLABLE NIEUN YU KIYEOKSIOS
+0x8848	0xB278	#HANGUL SYLLABLE NIEUN YU NIEUN
+0x8849	0xB279	#HANGUL SYLLABLE NIEUN YU NIEUNCIEUC
+0x884A	0xB27A	#HANGUL SYLLABLE NIEUN YU NIEUNHIEUH
+0x884B	0xB27B	#HANGUL SYLLABLE NIEUN YU TIKEUT
+0x884C	0xB27D	#HANGUL SYLLABLE NIEUN YU RIEULKIYEOK
+0x884D	0xB27E	#HANGUL SYLLABLE NIEUN YU RIEULMIEUM
+0x884E	0xB27F	#HANGUL SYLLABLE NIEUN YU RIEULPIEUP
+0x884F	0xB280	#HANGUL SYLLABLE NIEUN YU RIEULSIOS
+0x8850	0xB281	#HANGUL SYLLABLE NIEUN YU RIEULTHIEUTH
+0x8851	0xB282	#HANGUL SYLLABLE NIEUN YU RIEULPHIEUPH
+0x8852	0xB283	#HANGUL SYLLABLE NIEUN YU RIEULHIEUH
+0x8853	0xB286	#HANGUL SYLLABLE NIEUN YU PIEUPSIOS
+0x8854	0xB287	#HANGUL SYLLABLE NIEUN YU SIOS
+0x8855	0xB288	#HANGUL SYLLABLE NIEUN YU SSANGSIOS
+0x8856	0xB28A	#HANGUL SYLLABLE NIEUN YU CIEUC
+0x8857	0xB28B	#HANGUL SYLLABLE NIEUN YU CHIEUCH
+0x8858	0xB28C	#HANGUL SYLLABLE NIEUN YU KHIEUKH
+0x8859	0xB28D	#HANGUL SYLLABLE NIEUN YU THIEUTH
+0x885A	0xB28E	#HANGUL SYLLABLE NIEUN YU PHIEUPH
+0x8861	0xB28F	#HANGUL SYLLABLE NIEUN YU HIEUH
+0x8862	0xB292	#HANGUL SYLLABLE NIEUN EU SSANGKIYEOK
+0x8863	0xB293	#HANGUL SYLLABLE NIEUN EU KIYEOKSIOS
+0x8864	0xB295	#HANGUL SYLLABLE NIEUN EU NIEUNCIEUC
+0x8865	0xB296	#HANGUL SYLLABLE NIEUN EU NIEUNHIEUH
+0x8866	0xB297	#HANGUL SYLLABLE NIEUN EU TIKEUT
+0x8867	0xB29B	#HANGUL SYLLABLE NIEUN EU RIEULPIEUP
+0x8868	0xB29C	#HANGUL SYLLABLE NIEUN EU RIEULSIOS
+0x8869	0xB29D	#HANGUL SYLLABLE NIEUN EU RIEULTHIEUTH
+0x886A	0xB29E	#HANGUL SYLLABLE NIEUN EU RIEULPHIEUPH
+0x886B	0xB29F	#HANGUL SYLLABLE NIEUN EU RIEULHIEUH
+0x886C	0xB2A2	#HANGUL SYLLABLE NIEUN EU PIEUPSIOS
+0x886D	0xB2A4	#HANGUL SYLLABLE NIEUN EU SSANGSIOS
+0x886E	0xB2A7	#HANGUL SYLLABLE NIEUN EU CHIEUCH
+0x886F	0xB2A8	#HANGUL SYLLABLE NIEUN EU KHIEUKH
+0x8870	0xB2A9	#HANGUL SYLLABLE NIEUN EU THIEUTH
+0x8871	0xB2AB	#HANGUL SYLLABLE NIEUN EU HIEUH
+0x8872	0xB2AD	#HANGUL SYLLABLE NIEUN YI KIYEOK
+0x8873	0xB2AE	#HANGUL SYLLABLE NIEUN YI SSANGKIYEOK
+0x8874	0xB2AF	#HANGUL SYLLABLE NIEUN YI KIYEOKSIOS
+0x8875	0xB2B1	#HANGUL SYLLABLE NIEUN YI NIEUNCIEUC
+0x8876	0xB2B2	#HANGUL SYLLABLE NIEUN YI NIEUNHIEUH
+0x8877	0xB2B3	#HANGUL SYLLABLE NIEUN YI TIKEUT
+0x8878	0xB2B5	#HANGUL SYLLABLE NIEUN YI RIEULKIYEOK
+0x8879	0xB2B6	#HANGUL SYLLABLE NIEUN YI RIEULMIEUM
+0x887A	0xB2B7	#HANGUL SYLLABLE NIEUN YI RIEULPIEUP
+0x8881	0xB2B8	#HANGUL SYLLABLE NIEUN YI RIEULSIOS
+0x8882	0xB2B9	#HANGUL SYLLABLE NIEUN YI RIEULTHIEUTH
+0x8883	0xB2BA	#HANGUL SYLLABLE NIEUN YI RIEULPHIEUPH
+0x8884	0xB2BB	#HANGUL SYLLABLE NIEUN YI RIEULHIEUH
+0x8885	0xB2BC	#HANGUL SYLLABLE NIEUN YI MIEUM
+0x8886	0xB2BD	#HANGUL SYLLABLE NIEUN YI PIEUP
+0x8887	0xB2BE	#HANGUL SYLLABLE NIEUN YI PIEUPSIOS
+0x8888	0xB2BF	#HANGUL SYLLABLE NIEUN YI SIOS
+0x8889	0xB2C0	#HANGUL SYLLABLE NIEUN YI SSANGSIOS
+0x888A	0xB2C1	#HANGUL SYLLABLE NIEUN YI IEUNG
+0x888B	0xB2C2	#HANGUL SYLLABLE NIEUN YI CIEUC
+0x888C	0xB2C3	#HANGUL SYLLABLE NIEUN YI CHIEUCH
+0x888D	0xB2C4	#HANGUL SYLLABLE NIEUN YI KHIEUKH
+0x888E	0xB2C5	#HANGUL SYLLABLE NIEUN YI THIEUTH
+0x888F	0xB2C6	#HANGUL SYLLABLE NIEUN YI PHIEUPH
+0x8890	0xB2C7	#HANGUL SYLLABLE NIEUN YI HIEUH
+0x8891	0xB2CA	#HANGUL SYLLABLE NIEUN I SSANGKIYEOK
+0x8892	0xB2CB	#HANGUL SYLLABLE NIEUN I KIYEOKSIOS
+0x8893	0xB2CD	#HANGUL SYLLABLE NIEUN I NIEUNCIEUC
+0x8894	0xB2CE	#HANGUL SYLLABLE NIEUN I NIEUNHIEUH
+0x8895	0xB2CF	#HANGUL SYLLABLE NIEUN I TIKEUT
+0x8896	0xB2D1	#HANGUL SYLLABLE NIEUN I RIEULKIYEOK
+0x8897	0xB2D3	#HANGUL SYLLABLE NIEUN I RIEULPIEUP
+0x8898	0xB2D4	#HANGUL SYLLABLE NIEUN I RIEULSIOS
+0x8899	0xB2D5	#HANGUL SYLLABLE NIEUN I RIEULTHIEUTH
+0x889A	0xB2D6	#HANGUL SYLLABLE NIEUN I RIEULPHIEUPH
+0x889B	0xB2D7	#HANGUL SYLLABLE NIEUN I RIEULHIEUH
+0x889C	0xB2DA	#HANGUL SYLLABLE NIEUN I PIEUPSIOS
+0x889D	0xB2DC	#HANGUL SYLLABLE NIEUN I SSANGSIOS
+0x889E	0xB2DE	#HANGUL SYLLABLE NIEUN I CIEUC
+0x889F	0xB2DF	#HANGUL SYLLABLE NIEUN I CHIEUCH
+0x88A0	0xB2E0	#HANGUL SYLLABLE NIEUN I KHIEUKH
+0x88A1	0xB2E1	#HANGUL SYLLABLE NIEUN I THIEUTH
+0x88A2	0xB2E3	#HANGUL SYLLABLE NIEUN I HIEUH
+0x88A3	0xB2E7	#HANGUL SYLLABLE TIKEUT A KIYEOKSIOS
+0x88A4	0xB2E9	#HANGUL SYLLABLE TIKEUT A NIEUNCIEUC
+0x88A5	0xB2EA	#HANGUL SYLLABLE TIKEUT A NIEUNHIEUH
+0x88A6	0xB2F0	#HANGUL SYLLABLE TIKEUT A RIEULSIOS
+0x88A7	0xB2F1	#HANGUL SYLLABLE TIKEUT A RIEULTHIEUTH
+0x88A8	0xB2F2	#HANGUL SYLLABLE TIKEUT A RIEULPHIEUPH
+0x88A9	0xB2F6	#HANGUL SYLLABLE TIKEUT A PIEUPSIOS
+0x88AA	0xB2FC	#HANGUL SYLLABLE TIKEUT A KHIEUKH
+0x88AB	0xB2FD	#HANGUL SYLLABLE TIKEUT A THIEUTH
+0x88AC	0xB2FE	#HANGUL SYLLABLE TIKEUT A PHIEUPH
+0x88AD	0xB302	#HANGUL SYLLABLE TIKEUT AE SSANGKIYEOK
+0x88AE	0xB303	#HANGUL SYLLABLE TIKEUT AE KIYEOKSIOS
+0x88AF	0xB305	#HANGUL SYLLABLE TIKEUT AE NIEUNCIEUC
+0x88B0	0xB306	#HANGUL SYLLABLE TIKEUT AE NIEUNHIEUH
+0x88B1	0xB307	#HANGUL SYLLABLE TIKEUT AE TIKEUT
+0x88B2	0xB309	#HANGUL SYLLABLE TIKEUT AE RIEULKIYEOK
+0x88B3	0xB30A	#HANGUL SYLLABLE TIKEUT AE RIEULMIEUM
+0x88B4	0xB30B	#HANGUL SYLLABLE TIKEUT AE RIEULPIEUP
+0x88B5	0xB30C	#HANGUL SYLLABLE TIKEUT AE RIEULSIOS
+0x88B6	0xB30D	#HANGUL SYLLABLE TIKEUT AE RIEULTHIEUTH
+0x88B7	0xB30E	#HANGUL SYLLABLE TIKEUT AE RIEULPHIEUPH
+0x88B8	0xB30F	#HANGUL SYLLABLE TIKEUT AE RIEULHIEUH
+0x88B9	0xB312	#HANGUL SYLLABLE TIKEUT AE PIEUPSIOS
+0x88BA	0xB316	#HANGUL SYLLABLE TIKEUT AE CIEUC
+0x88BB	0xB317	#HANGUL SYLLABLE TIKEUT AE CHIEUCH
+0x88BC	0xB318	#HANGUL SYLLABLE TIKEUT AE KHIEUKH
+0x88BD	0xB319	#HANGUL SYLLABLE TIKEUT AE THIEUTH
+0x88BE	0xB31A	#HANGUL SYLLABLE TIKEUT AE PHIEUPH
+0x88BF	0xB31B	#HANGUL SYLLABLE TIKEUT AE HIEUH
+0x88C0	0xB31D	#HANGUL SYLLABLE TIKEUT YA KIYEOK
+0x88C1	0xB31E	#HANGUL SYLLABLE TIKEUT YA SSANGKIYEOK
+0x88C2	0xB31F	#HANGUL SYLLABLE TIKEUT YA KIYEOKSIOS
+0x88C3	0xB320	#HANGUL SYLLABLE TIKEUT YA NIEUN
+0x88C4	0xB321	#HANGUL SYLLABLE TIKEUT YA NIEUNCIEUC
+0x88C5	0xB322	#HANGUL SYLLABLE TIKEUT YA NIEUNHIEUH
+0x88C6	0xB323	#HANGUL SYLLABLE TIKEUT YA TIKEUT
+0x88C7	0xB324	#HANGUL SYLLABLE TIKEUT YA RIEUL
+0x88C8	0xB325	#HANGUL SYLLABLE TIKEUT YA RIEULKIYEOK
+0x88C9	0xB326	#HANGUL SYLLABLE TIKEUT YA RIEULMIEUM
+0x88CA	0xB327	#HANGUL SYLLABLE TIKEUT YA RIEULPIEUP
+0x88CB	0xB328	#HANGUL SYLLABLE TIKEUT YA RIEULSIOS
+0x88CC	0xB329	#HANGUL SYLLABLE TIKEUT YA RIEULTHIEUTH
+0x88CD	0xB32A	#HANGUL SYLLABLE TIKEUT YA RIEULPHIEUPH
+0x88CE	0xB32B	#HANGUL SYLLABLE TIKEUT YA RIEULHIEUH
+0x88CF	0xB32C	#HANGUL SYLLABLE TIKEUT YA MIEUM
+0x88D0	0xB32D	#HANGUL SYLLABLE TIKEUT YA PIEUP
+0x88D1	0xB32E	#HANGUL SYLLABLE TIKEUT YA PIEUPSIOS
+0x88D2	0xB32F	#HANGUL SYLLABLE TIKEUT YA SIOS
+0x88D3	0xB330	#HANGUL SYLLABLE TIKEUT YA SSANGSIOS
+0x88D4	0xB331	#HANGUL SYLLABLE TIKEUT YA IEUNG
+0x88D5	0xB332	#HANGUL SYLLABLE TIKEUT YA CIEUC
+0x88D6	0xB333	#HANGUL SYLLABLE TIKEUT YA CHIEUCH
+0x88D7	0xB334	#HANGUL SYLLABLE TIKEUT YA KHIEUKH
+0x88D8	0xB335	#HANGUL SYLLABLE TIKEUT YA THIEUTH
+0x88D9	0xB336	#HANGUL SYLLABLE TIKEUT YA PHIEUPH
+0x88DA	0xB337	#HANGUL SYLLABLE TIKEUT YA HIEUH
+0x88DB	0xB338	#HANGUL SYLLABLE TIKEUT YAE
+0x88DC	0xB339	#HANGUL SYLLABLE TIKEUT YAE KIYEOK
+0x88DD	0xB33A	#HANGUL SYLLABLE TIKEUT YAE SSANGKIYEOK
+0x88DE	0xB33B	#HANGUL SYLLABLE TIKEUT YAE KIYEOKSIOS
+0x88DF	0xB33C	#HANGUL SYLLABLE TIKEUT YAE NIEUN
+0x88E0	0xB33D	#HANGUL SYLLABLE TIKEUT YAE NIEUNCIEUC
+0x88E1	0xB33E	#HANGUL SYLLABLE TIKEUT YAE NIEUNHIEUH
+0x88E2	0xB33F	#HANGUL SYLLABLE TIKEUT YAE TIKEUT
+0x88E3	0xB340	#HANGUL SYLLABLE TIKEUT YAE RIEUL
+0x88E4	0xB341	#HANGUL SYLLABLE TIKEUT YAE RIEULKIYEOK
+0x88E5	0xB342	#HANGUL SYLLABLE TIKEUT YAE RIEULMIEUM
+0x88E6	0xB343	#HANGUL SYLLABLE TIKEUT YAE RIEULPIEUP
+0x88E7	0xB344	#HANGUL SYLLABLE TIKEUT YAE RIEULSIOS
+0x88E8	0xB345	#HANGUL SYLLABLE TIKEUT YAE RIEULTHIEUTH
+0x88E9	0xB346	#HANGUL SYLLABLE TIKEUT YAE RIEULPHIEUPH
+0x88EA	0xB347	#HANGUL SYLLABLE TIKEUT YAE RIEULHIEUH
+0x88EB	0xB348	#HANGUL SYLLABLE TIKEUT YAE MIEUM
+0x88EC	0xB349	#HANGUL SYLLABLE TIKEUT YAE PIEUP
+0x88ED	0xB34A	#HANGUL SYLLABLE TIKEUT YAE PIEUPSIOS
+0x88EE	0xB34B	#HANGUL SYLLABLE TIKEUT YAE SIOS
+0x88EF	0xB34C	#HANGUL SYLLABLE TIKEUT YAE SSANGSIOS
+0x88F0	0xB34D	#HANGUL SYLLABLE TIKEUT YAE IEUNG
+0x88F1	0xB34E	#HANGUL SYLLABLE TIKEUT YAE CIEUC
+0x88F2	0xB34F	#HANGUL SYLLABLE TIKEUT YAE CHIEUCH
+0x88F3	0xB350	#HANGUL SYLLABLE TIKEUT YAE KHIEUKH
+0x88F4	0xB351	#HANGUL SYLLABLE TIKEUT YAE THIEUTH
+0x88F5	0xB352	#HANGUL SYLLABLE TIKEUT YAE PHIEUPH
+0x88F6	0xB353	#HANGUL SYLLABLE TIKEUT YAE HIEUH
+0x88F7	0xB357	#HANGUL SYLLABLE TIKEUT EO KIYEOKSIOS
+0x88F8	0xB359	#HANGUL SYLLABLE TIKEUT EO NIEUNCIEUC
+0x88F9	0xB35A	#HANGUL SYLLABLE TIKEUT EO NIEUNHIEUH
+0x88FA	0xB35D	#HANGUL SYLLABLE TIKEUT EO RIEULKIYEOK
+0x88FB	0xB360	#HANGUL SYLLABLE TIKEUT EO RIEULSIOS
+0x88FC	0xB361	#HANGUL SYLLABLE TIKEUT EO RIEULTHIEUTH
+0x88FD	0xB362	#HANGUL SYLLABLE TIKEUT EO RIEULPHIEUPH
+0x88FE	0xB363	#HANGUL SYLLABLE TIKEUT EO RIEULHIEUH
+0x8941	0xB366	#HANGUL SYLLABLE TIKEUT EO PIEUPSIOS
+0x8942	0xB368	#HANGUL SYLLABLE TIKEUT EO SSANGSIOS
+0x8943	0xB36A	#HANGUL SYLLABLE TIKEUT EO CIEUC
+0x8944	0xB36C	#HANGUL SYLLABLE TIKEUT EO KHIEUKH
+0x8945	0xB36D	#HANGUL SYLLABLE TIKEUT EO THIEUTH
+0x8946	0xB36F	#HANGUL SYLLABLE TIKEUT EO HIEUH
+0x8947	0xB372	#HANGUL SYLLABLE TIKEUT E SSANGKIYEOK
+0x8948	0xB373	#HANGUL SYLLABLE TIKEUT E KIYEOKSIOS
+0x8949	0xB375	#HANGUL SYLLABLE TIKEUT E NIEUNCIEUC
+0x894A	0xB376	#HANGUL SYLLABLE TIKEUT E NIEUNHIEUH
+0x894B	0xB377	#HANGUL SYLLABLE TIKEUT E TIKEUT
+0x894C	0xB379	#HANGUL SYLLABLE TIKEUT E RIEULKIYEOK
+0x894D	0xB37A	#HANGUL SYLLABLE TIKEUT E RIEULMIEUM
+0x894E	0xB37B	#HANGUL SYLLABLE TIKEUT E RIEULPIEUP
+0x894F	0xB37C	#HANGUL SYLLABLE TIKEUT E RIEULSIOS
+0x8950	0xB37D	#HANGUL SYLLABLE TIKEUT E RIEULTHIEUTH
+0x8951	0xB37E	#HANGUL SYLLABLE TIKEUT E RIEULPHIEUPH
+0x8952	0xB37F	#HANGUL SYLLABLE TIKEUT E RIEULHIEUH
+0x8953	0xB382	#HANGUL SYLLABLE TIKEUT E PIEUPSIOS
+0x8954	0xB386	#HANGUL SYLLABLE TIKEUT E CIEUC
+0x8955	0xB387	#HANGUL SYLLABLE TIKEUT E CHIEUCH
+0x8956	0xB388	#HANGUL SYLLABLE TIKEUT E KHIEUKH
+0x8957	0xB389	#HANGUL SYLLABLE TIKEUT E THIEUTH
+0x8958	0xB38A	#HANGUL SYLLABLE TIKEUT E PHIEUPH
+0x8959	0xB38B	#HANGUL SYLLABLE TIKEUT E HIEUH
+0x895A	0xB38D	#HANGUL SYLLABLE TIKEUT YEO KIYEOK
+0x8961	0xB38E	#HANGUL SYLLABLE TIKEUT YEO SSANGKIYEOK
+0x8962	0xB38F	#HANGUL SYLLABLE TIKEUT YEO KIYEOKSIOS
+0x8963	0xB391	#HANGUL SYLLABLE TIKEUT YEO NIEUNCIEUC
+0x8964	0xB392	#HANGUL SYLLABLE TIKEUT YEO NIEUNHIEUH
+0x8965	0xB393	#HANGUL SYLLABLE TIKEUT YEO TIKEUT
+0x8966	0xB395	#HANGUL SYLLABLE TIKEUT YEO RIEULKIYEOK
+0x8967	0xB396	#HANGUL SYLLABLE TIKEUT YEO RIEULMIEUM
+0x8968	0xB397	#HANGUL SYLLABLE TIKEUT YEO RIEULPIEUP
+0x8969	0xB398	#HANGUL SYLLABLE TIKEUT YEO RIEULSIOS
+0x896A	0xB399	#HANGUL SYLLABLE TIKEUT YEO RIEULTHIEUTH
+0x896B	0xB39A	#HANGUL SYLLABLE TIKEUT YEO RIEULPHIEUPH
+0x896C	0xB39B	#HANGUL SYLLABLE TIKEUT YEO RIEULHIEUH
+0x896D	0xB39C	#HANGUL SYLLABLE TIKEUT YEO MIEUM
+0x896E	0xB39D	#HANGUL SYLLABLE TIKEUT YEO PIEUP
+0x896F	0xB39E	#HANGUL SYLLABLE TIKEUT YEO PIEUPSIOS
+0x8970	0xB39F	#HANGUL SYLLABLE TIKEUT YEO SIOS
+0x8971	0xB3A2	#HANGUL SYLLABLE TIKEUT YEO CIEUC
+0x8972	0xB3A3	#HANGUL SYLLABLE TIKEUT YEO CHIEUCH
+0x8973	0xB3A4	#HANGUL SYLLABLE TIKEUT YEO KHIEUKH
+0x8974	0xB3A5	#HANGUL SYLLABLE TIKEUT YEO THIEUTH
+0x8975	0xB3A6	#HANGUL SYLLABLE TIKEUT YEO PHIEUPH
+0x8976	0xB3A7	#HANGUL SYLLABLE TIKEUT YEO HIEUH
+0x8977	0xB3A9	#HANGUL SYLLABLE TIKEUT YE KIYEOK
+0x8978	0xB3AA	#HANGUL SYLLABLE TIKEUT YE SSANGKIYEOK
+0x8979	0xB3AB	#HANGUL SYLLABLE TIKEUT YE KIYEOKSIOS
+0x897A	0xB3AD	#HANGUL SYLLABLE TIKEUT YE NIEUNCIEUC
+0x8981	0xB3AE	#HANGUL SYLLABLE TIKEUT YE NIEUNHIEUH
+0x8982	0xB3AF	#HANGUL SYLLABLE TIKEUT YE TIKEUT
+0x8983	0xB3B0	#HANGUL SYLLABLE TIKEUT YE RIEUL
+0x8984	0xB3B1	#HANGUL SYLLABLE TIKEUT YE RIEULKIYEOK
+0x8985	0xB3B2	#HANGUL SYLLABLE TIKEUT YE RIEULMIEUM
+0x8986	0xB3B3	#HANGUL SYLLABLE TIKEUT YE RIEULPIEUP
+0x8987	0xB3B4	#HANGUL SYLLABLE TIKEUT YE RIEULSIOS
+0x8988	0xB3B5	#HANGUL SYLLABLE TIKEUT YE RIEULTHIEUTH
+0x8989	0xB3B6	#HANGUL SYLLABLE TIKEUT YE RIEULPHIEUPH
+0x898A	0xB3B7	#HANGUL SYLLABLE TIKEUT YE RIEULHIEUH
+0x898B	0xB3B8	#HANGUL SYLLABLE TIKEUT YE MIEUM
+0x898C	0xB3B9	#HANGUL SYLLABLE TIKEUT YE PIEUP
+0x898D	0xB3BA	#HANGUL SYLLABLE TIKEUT YE PIEUPSIOS
+0x898E	0xB3BB	#HANGUL SYLLABLE TIKEUT YE SIOS
+0x898F	0xB3BC	#HANGUL SYLLABLE TIKEUT YE SSANGSIOS
+0x8990	0xB3BD	#HANGUL SYLLABLE TIKEUT YE IEUNG
+0x8991	0xB3BE	#HANGUL SYLLABLE TIKEUT YE CIEUC
+0x8992	0xB3BF	#HANGUL SYLLABLE TIKEUT YE CHIEUCH
+0x8993	0xB3C0	#HANGUL SYLLABLE TIKEUT YE KHIEUKH
+0x8994	0xB3C1	#HANGUL SYLLABLE TIKEUT YE THIEUTH
+0x8995	0xB3C2	#HANGUL SYLLABLE TIKEUT YE PHIEUPH
+0x8996	0xB3C3	#HANGUL SYLLABLE TIKEUT YE HIEUH
+0x8997	0xB3C6	#HANGUL SYLLABLE TIKEUT O SSANGKIYEOK
+0x8998	0xB3C7	#HANGUL SYLLABLE TIKEUT O KIYEOKSIOS
+0x8999	0xB3C9	#HANGUL SYLLABLE TIKEUT O NIEUNCIEUC
+0x899A	0xB3CA	#HANGUL SYLLABLE TIKEUT O NIEUNHIEUH
+0x899B	0xB3CD	#HANGUL SYLLABLE TIKEUT O RIEULKIYEOK
+0x899C	0xB3CF	#HANGUL SYLLABLE TIKEUT O RIEULPIEUP
+0x899D	0xB3D1	#HANGUL SYLLABLE TIKEUT O RIEULTHIEUTH
+0x899E	0xB3D2	#HANGUL SYLLABLE TIKEUT O RIEULPHIEUPH
+0x899F	0xB3D3	#HANGUL SYLLABLE TIKEUT O RIEULHIEUH
+0x89A0	0xB3D6	#HANGUL SYLLABLE TIKEUT O PIEUPSIOS
+0x89A1	0xB3D8	#HANGUL SYLLABLE TIKEUT O SSANGSIOS
+0x89A2	0xB3DA	#HANGUL SYLLABLE TIKEUT O CIEUC
+0x89A3	0xB3DC	#HANGUL SYLLABLE TIKEUT O KHIEUKH
+0x89A4	0xB3DE	#HANGUL SYLLABLE TIKEUT O PHIEUPH
+0x89A5	0xB3DF	#HANGUL SYLLABLE TIKEUT O HIEUH
+0x89A6	0xB3E1	#HANGUL SYLLABLE TIKEUT WA KIYEOK
+0x89A7	0xB3E2	#HANGUL SYLLABLE TIKEUT WA SSANGKIYEOK
+0x89A8	0xB3E3	#HANGUL SYLLABLE TIKEUT WA KIYEOKSIOS
+0x89A9	0xB3E5	#HANGUL SYLLABLE TIKEUT WA NIEUNCIEUC
+0x89AA	0xB3E6	#HANGUL SYLLABLE TIKEUT WA NIEUNHIEUH
+0x89AB	0xB3E7	#HANGUL SYLLABLE TIKEUT WA TIKEUT
+0x89AC	0xB3E9	#HANGUL SYLLABLE TIKEUT WA RIEULKIYEOK
+0x89AD	0xB3EA	#HANGUL SYLLABLE TIKEUT WA RIEULMIEUM
+0x89AE	0xB3EB	#HANGUL SYLLABLE TIKEUT WA RIEULPIEUP
+0x89AF	0xB3EC	#HANGUL SYLLABLE TIKEUT WA RIEULSIOS
+0x89B0	0xB3ED	#HANGUL SYLLABLE TIKEUT WA RIEULTHIEUTH
+0x89B1	0xB3EE	#HANGUL SYLLABLE TIKEUT WA RIEULPHIEUPH
+0x89B2	0xB3EF	#HANGUL SYLLABLE TIKEUT WA RIEULHIEUH
+0x89B3	0xB3F0	#HANGUL SYLLABLE TIKEUT WA MIEUM
+0x89B4	0xB3F1	#HANGUL SYLLABLE TIKEUT WA PIEUP
+0x89B5	0xB3F2	#HANGUL SYLLABLE TIKEUT WA PIEUPSIOS
+0x89B6	0xB3F3	#HANGUL SYLLABLE TIKEUT WA SIOS
+0x89B7	0xB3F4	#HANGUL SYLLABLE TIKEUT WA SSANGSIOS
+0x89B8	0xB3F5	#HANGUL SYLLABLE TIKEUT WA IEUNG
+0x89B9	0xB3F6	#HANGUL SYLLABLE TIKEUT WA CIEUC
+0x89BA	0xB3F7	#HANGUL SYLLABLE TIKEUT WA CHIEUCH
+0x89BB	0xB3F8	#HANGUL SYLLABLE TIKEUT WA KHIEUKH
+0x89BC	0xB3F9	#HANGUL SYLLABLE TIKEUT WA THIEUTH
+0x89BD	0xB3FA	#HANGUL SYLLABLE TIKEUT WA PHIEUPH
+0x89BE	0xB3FB	#HANGUL SYLLABLE TIKEUT WA HIEUH
+0x89BF	0xB3FD	#HANGUL SYLLABLE TIKEUT WAE KIYEOK
+0x89C0	0xB3FE	#HANGUL SYLLABLE TIKEUT WAE SSANGKIYEOK
+0x89C1	0xB3FF	#HANGUL SYLLABLE TIKEUT WAE KIYEOKSIOS
+0x89C2	0xB400	#HANGUL SYLLABLE TIKEUT WAE NIEUN
+0x89C3	0xB401	#HANGUL SYLLABLE TIKEUT WAE NIEUNCIEUC
+0x89C4	0xB402	#HANGUL SYLLABLE TIKEUT WAE NIEUNHIEUH
+0x89C5	0xB403	#HANGUL SYLLABLE TIKEUT WAE TIKEUT
+0x89C6	0xB404	#HANGUL SYLLABLE TIKEUT WAE RIEUL
+0x89C7	0xB405	#HANGUL SYLLABLE TIKEUT WAE RIEULKIYEOK
+0x89C8	0xB406	#HANGUL SYLLABLE TIKEUT WAE RIEULMIEUM
+0x89C9	0xB407	#HANGUL SYLLABLE TIKEUT WAE RIEULPIEUP
+0x89CA	0xB408	#HANGUL SYLLABLE TIKEUT WAE RIEULSIOS
+0x89CB	0xB409	#HANGUL SYLLABLE TIKEUT WAE RIEULTHIEUTH
+0x89CC	0xB40A	#HANGUL SYLLABLE TIKEUT WAE RIEULPHIEUPH
+0x89CD	0xB40B	#HANGUL SYLLABLE TIKEUT WAE RIEULHIEUH
+0x89CE	0xB40C	#HANGUL SYLLABLE TIKEUT WAE MIEUM
+0x89CF	0xB40D	#HANGUL SYLLABLE TIKEUT WAE PIEUP
+0x89D0	0xB40E	#HANGUL SYLLABLE TIKEUT WAE PIEUPSIOS
+0x89D1	0xB40F	#HANGUL SYLLABLE TIKEUT WAE SIOS
+0x89D2	0xB411	#HANGUL SYLLABLE TIKEUT WAE IEUNG
+0x89D3	0xB412	#HANGUL SYLLABLE TIKEUT WAE CIEUC
+0x89D4	0xB413	#HANGUL SYLLABLE TIKEUT WAE CHIEUCH
+0x89D5	0xB414	#HANGUL SYLLABLE TIKEUT WAE KHIEUKH
+0x89D6	0xB415	#HANGUL SYLLABLE TIKEUT WAE THIEUTH
+0x89D7	0xB416	#HANGUL SYLLABLE TIKEUT WAE PHIEUPH
+0x89D8	0xB417	#HANGUL SYLLABLE TIKEUT WAE HIEUH
+0x89D9	0xB419	#HANGUL SYLLABLE TIKEUT OE KIYEOK
+0x89DA	0xB41A	#HANGUL SYLLABLE TIKEUT OE SSANGKIYEOK
+0x89DB	0xB41B	#HANGUL SYLLABLE TIKEUT OE KIYEOKSIOS
+0x89DC	0xB41D	#HANGUL SYLLABLE TIKEUT OE NIEUNCIEUC
+0x89DD	0xB41E	#HANGUL SYLLABLE TIKEUT OE NIEUNHIEUH
+0x89DE	0xB41F	#HANGUL SYLLABLE TIKEUT OE TIKEUT
+0x89DF	0xB421	#HANGUL SYLLABLE TIKEUT OE RIEULKIYEOK
+0x89E0	0xB422	#HANGUL SYLLABLE TIKEUT OE RIEULMIEUM
+0x89E1	0xB423	#HANGUL SYLLABLE TIKEUT OE RIEULPIEUP
+0x89E2	0xB424	#HANGUL SYLLABLE TIKEUT OE RIEULSIOS
+0x89E3	0xB425	#HANGUL SYLLABLE TIKEUT OE RIEULTHIEUTH
+0x89E4	0xB426	#HANGUL SYLLABLE TIKEUT OE RIEULPHIEUPH
+0x89E5	0xB427	#HANGUL SYLLABLE TIKEUT OE RIEULHIEUH
+0x89E6	0xB42A	#HANGUL SYLLABLE TIKEUT OE PIEUPSIOS
+0x89E7	0xB42C	#HANGUL SYLLABLE TIKEUT OE SSANGSIOS
+0x89E8	0xB42D	#HANGUL SYLLABLE TIKEUT OE IEUNG
+0x89E9	0xB42E	#HANGUL SYLLABLE TIKEUT OE CIEUC
+0x89EA	0xB42F	#HANGUL SYLLABLE TIKEUT OE CHIEUCH
+0x89EB	0xB430	#HANGUL SYLLABLE TIKEUT OE KHIEUKH
+0x89EC	0xB431	#HANGUL SYLLABLE TIKEUT OE THIEUTH
+0x89ED	0xB432	#HANGUL SYLLABLE TIKEUT OE PHIEUPH
+0x89EE	0xB433	#HANGUL SYLLABLE TIKEUT OE HIEUH
+0x89EF	0xB435	#HANGUL SYLLABLE TIKEUT YO KIYEOK
+0x89F0	0xB436	#HANGUL SYLLABLE TIKEUT YO SSANGKIYEOK
+0x89F1	0xB437	#HANGUL SYLLABLE TIKEUT YO KIYEOKSIOS
+0x89F2	0xB438	#HANGUL SYLLABLE TIKEUT YO NIEUN
+0x89F3	0xB439	#HANGUL SYLLABLE TIKEUT YO NIEUNCIEUC
+0x89F4	0xB43A	#HANGUL SYLLABLE TIKEUT YO NIEUNHIEUH
+0x89F5	0xB43B	#HANGUL SYLLABLE TIKEUT YO TIKEUT
+0x89F6	0xB43C	#HANGUL SYLLABLE TIKEUT YO RIEUL
+0x89F7	0xB43D	#HANGUL SYLLABLE TIKEUT YO RIEULKIYEOK
+0x89F8	0xB43E	#HANGUL SYLLABLE TIKEUT YO RIEULMIEUM
+0x89F9	0xB43F	#HANGUL SYLLABLE TIKEUT YO RIEULPIEUP
+0x89FA	0xB440	#HANGUL SYLLABLE TIKEUT YO RIEULSIOS
+0x89FB	0xB441	#HANGUL SYLLABLE TIKEUT YO RIEULTHIEUTH
+0x89FC	0xB442	#HANGUL SYLLABLE TIKEUT YO RIEULPHIEUPH
+0x89FD	0xB443	#HANGUL SYLLABLE TIKEUT YO RIEULHIEUH
+0x89FE	0xB444	#HANGUL SYLLABLE TIKEUT YO MIEUM
+0x8A41	0xB445	#HANGUL SYLLABLE TIKEUT YO PIEUP
+0x8A42	0xB446	#HANGUL SYLLABLE TIKEUT YO PIEUPSIOS
+0x8A43	0xB447	#HANGUL SYLLABLE TIKEUT YO SIOS
+0x8A44	0xB448	#HANGUL SYLLABLE TIKEUT YO SSANGSIOS
+0x8A45	0xB449	#HANGUL SYLLABLE TIKEUT YO IEUNG
+0x8A46	0xB44A	#HANGUL SYLLABLE TIKEUT YO CIEUC
+0x8A47	0xB44B	#HANGUL SYLLABLE TIKEUT YO CHIEUCH
+0x8A48	0xB44C	#HANGUL SYLLABLE TIKEUT YO KHIEUKH
+0x8A49	0xB44D	#HANGUL SYLLABLE TIKEUT YO THIEUTH
+0x8A4A	0xB44E	#HANGUL SYLLABLE TIKEUT YO PHIEUPH
+0x8A4B	0xB44F	#HANGUL SYLLABLE TIKEUT YO HIEUH
+0x8A4C	0xB452	#HANGUL SYLLABLE TIKEUT U SSANGKIYEOK
+0x8A4D	0xB453	#HANGUL SYLLABLE TIKEUT U KIYEOKSIOS
+0x8A4E	0xB455	#HANGUL SYLLABLE TIKEUT U NIEUNCIEUC
+0x8A4F	0xB456	#HANGUL SYLLABLE TIKEUT U NIEUNHIEUH
+0x8A50	0xB457	#HANGUL SYLLABLE TIKEUT U TIKEUT
+0x8A51	0xB459	#HANGUL SYLLABLE TIKEUT U RIEULKIYEOK
+0x8A52	0xB45A	#HANGUL SYLLABLE TIKEUT U RIEULMIEUM
+0x8A53	0xB45B	#HANGUL SYLLABLE TIKEUT U RIEULPIEUP
+0x8A54	0xB45C	#HANGUL SYLLABLE TIKEUT U RIEULSIOS
+0x8A55	0xB45D	#HANGUL SYLLABLE TIKEUT U RIEULTHIEUTH
+0x8A56	0xB45E	#HANGUL SYLLABLE TIKEUT U RIEULPHIEUPH
+0x8A57	0xB45F	#HANGUL SYLLABLE TIKEUT U RIEULHIEUH
+0x8A58	0xB462	#HANGUL SYLLABLE TIKEUT U PIEUPSIOS
+0x8A59	0xB464	#HANGUL SYLLABLE TIKEUT U SSANGSIOS
+0x8A5A	0xB466	#HANGUL SYLLABLE TIKEUT U CIEUC
+0x8A61	0xB467	#HANGUL SYLLABLE TIKEUT U CHIEUCH
+0x8A62	0xB468	#HANGUL SYLLABLE TIKEUT U KHIEUKH
+0x8A63	0xB469	#HANGUL SYLLABLE TIKEUT U THIEUTH
+0x8A64	0xB46A	#HANGUL SYLLABLE TIKEUT U PHIEUPH
+0x8A65	0xB46B	#HANGUL SYLLABLE TIKEUT U HIEUH
+0x8A66	0xB46D	#HANGUL SYLLABLE TIKEUT WEO KIYEOK
+0x8A67	0xB46E	#HANGUL SYLLABLE TIKEUT WEO SSANGKIYEOK
+0x8A68	0xB46F	#HANGUL SYLLABLE TIKEUT WEO KIYEOKSIOS
+0x8A69	0xB470	#HANGUL SYLLABLE TIKEUT WEO NIEUN
+0x8A6A	0xB471	#HANGUL SYLLABLE TIKEUT WEO NIEUNCIEUC
+0x8A6B	0xB472	#HANGUL SYLLABLE TIKEUT WEO NIEUNHIEUH
+0x8A6C	0xB473	#HANGUL SYLLABLE TIKEUT WEO TIKEUT
+0x8A6D	0xB474	#HANGUL SYLLABLE TIKEUT WEO RIEUL
+0x8A6E	0xB475	#HANGUL SYLLABLE TIKEUT WEO RIEULKIYEOK
+0x8A6F	0xB476	#HANGUL SYLLABLE TIKEUT WEO RIEULMIEUM
+0x8A70	0xB477	#HANGUL SYLLABLE TIKEUT WEO RIEULPIEUP
+0x8A71	0xB478	#HANGUL SYLLABLE TIKEUT WEO RIEULSIOS
+0x8A72	0xB479	#HANGUL SYLLABLE TIKEUT WEO RIEULTHIEUTH
+0x8A73	0xB47A	#HANGUL SYLLABLE TIKEUT WEO RIEULPHIEUPH
+0x8A74	0xB47B	#HANGUL SYLLABLE TIKEUT WEO RIEULHIEUH
+0x8A75	0xB47C	#HANGUL SYLLABLE TIKEUT WEO MIEUM
+0x8A76	0xB47D	#HANGUL SYLLABLE TIKEUT WEO PIEUP
+0x8A77	0xB47E	#HANGUL SYLLABLE TIKEUT WEO PIEUPSIOS
+0x8A78	0xB47F	#HANGUL SYLLABLE TIKEUT WEO SIOS
+0x8A79	0xB481	#HANGUL SYLLABLE TIKEUT WEO IEUNG
+0x8A7A	0xB482	#HANGUL SYLLABLE TIKEUT WEO CIEUC
+0x8A81	0xB483	#HANGUL SYLLABLE TIKEUT WEO CHIEUCH
+0x8A82	0xB484	#HANGUL SYLLABLE TIKEUT WEO KHIEUKH
+0x8A83	0xB485	#HANGUL SYLLABLE TIKEUT WEO THIEUTH
+0x8A84	0xB486	#HANGUL SYLLABLE TIKEUT WEO PHIEUPH
+0x8A85	0xB487	#HANGUL SYLLABLE TIKEUT WEO HIEUH
+0x8A86	0xB489	#HANGUL SYLLABLE TIKEUT WE KIYEOK
+0x8A87	0xB48A	#HANGUL SYLLABLE TIKEUT WE SSANGKIYEOK
+0x8A88	0xB48B	#HANGUL SYLLABLE TIKEUT WE KIYEOKSIOS
+0x8A89	0xB48C	#HANGUL SYLLABLE TIKEUT WE NIEUN
+0x8A8A	0xB48D	#HANGUL SYLLABLE TIKEUT WE NIEUNCIEUC
+0x8A8B	0xB48E	#HANGUL SYLLABLE TIKEUT WE NIEUNHIEUH
+0x8A8C	0xB48F	#HANGUL SYLLABLE TIKEUT WE TIKEUT
+0x8A8D	0xB490	#HANGUL SYLLABLE TIKEUT WE RIEUL
+0x8A8E	0xB491	#HANGUL SYLLABLE TIKEUT WE RIEULKIYEOK
+0x8A8F	0xB492	#HANGUL SYLLABLE TIKEUT WE RIEULMIEUM
+0x8A90	0xB493	#HANGUL SYLLABLE TIKEUT WE RIEULPIEUP
+0x8A91	0xB494	#HANGUL SYLLABLE TIKEUT WE RIEULSIOS
+0x8A92	0xB495	#HANGUL SYLLABLE TIKEUT WE RIEULTHIEUTH
+0x8A93	0xB496	#HANGUL SYLLABLE TIKEUT WE RIEULPHIEUPH
+0x8A94	0xB497	#HANGUL SYLLABLE TIKEUT WE RIEULHIEUH
+0x8A95	0xB498	#HANGUL SYLLABLE TIKEUT WE MIEUM
+0x8A96	0xB499	#HANGUL SYLLABLE TIKEUT WE PIEUP
+0x8A97	0xB49A	#HANGUL SYLLABLE TIKEUT WE PIEUPSIOS
+0x8A98	0xB49B	#HANGUL SYLLABLE TIKEUT WE SIOS
+0x8A99	0xB49C	#HANGUL SYLLABLE TIKEUT WE SSANGSIOS
+0x8A9A	0xB49E	#HANGUL SYLLABLE TIKEUT WE CIEUC
+0x8A9B	0xB49F	#HANGUL SYLLABLE TIKEUT WE CHIEUCH
+0x8A9C	0xB4A0	#HANGUL SYLLABLE TIKEUT WE KHIEUKH
+0x8A9D	0xB4A1	#HANGUL SYLLABLE TIKEUT WE THIEUTH
+0x8A9E	0xB4A2	#HANGUL SYLLABLE TIKEUT WE PHIEUPH
+0x8A9F	0xB4A3	#HANGUL SYLLABLE TIKEUT WE HIEUH
+0x8AA0	0xB4A5	#HANGUL SYLLABLE TIKEUT WI KIYEOK
+0x8AA1	0xB4A6	#HANGUL SYLLABLE TIKEUT WI SSANGKIYEOK
+0x8AA2	0xB4A7	#HANGUL SYLLABLE TIKEUT WI KIYEOKSIOS
+0x8AA3	0xB4A9	#HANGUL SYLLABLE TIKEUT WI NIEUNCIEUC
+0x8AA4	0xB4AA	#HANGUL SYLLABLE TIKEUT WI NIEUNHIEUH
+0x8AA5	0xB4AB	#HANGUL SYLLABLE TIKEUT WI TIKEUT
+0x8AA6	0xB4AD	#HANGUL SYLLABLE TIKEUT WI RIEULKIYEOK
+0x8AA7	0xB4AE	#HANGUL SYLLABLE TIKEUT WI RIEULMIEUM
+0x8AA8	0xB4AF	#HANGUL SYLLABLE TIKEUT WI RIEULPIEUP
+0x8AA9	0xB4B0	#HANGUL SYLLABLE TIKEUT WI RIEULSIOS
+0x8AAA	0xB4B1	#HANGUL SYLLABLE TIKEUT WI RIEULTHIEUTH
+0x8AAB	0xB4B2	#HANGUL SYLLABLE TIKEUT WI RIEULPHIEUPH
+0x8AAC	0xB4B3	#HANGUL SYLLABLE TIKEUT WI RIEULHIEUH
+0x8AAD	0xB4B4	#HANGUL SYLLABLE TIKEUT WI MIEUM
+0x8AAE	0xB4B6	#HANGUL SYLLABLE TIKEUT WI PIEUPSIOS
+0x8AAF	0xB4B8	#HANGUL SYLLABLE TIKEUT WI SSANGSIOS
+0x8AB0	0xB4BA	#HANGUL SYLLABLE TIKEUT WI CIEUC
+0x8AB1	0xB4BB	#HANGUL SYLLABLE TIKEUT WI CHIEUCH
+0x8AB2	0xB4BC	#HANGUL SYLLABLE TIKEUT WI KHIEUKH
+0x8AB3	0xB4BD	#HANGUL SYLLABLE TIKEUT WI THIEUTH
+0x8AB4	0xB4BE	#HANGUL SYLLABLE TIKEUT WI PHIEUPH
+0x8AB5	0xB4BF	#HANGUL SYLLABLE TIKEUT WI HIEUH
+0x8AB6	0xB4C1	#HANGUL SYLLABLE TIKEUT YU KIYEOK
+0x8AB7	0xB4C2	#HANGUL SYLLABLE TIKEUT YU SSANGKIYEOK
+0x8AB8	0xB4C3	#HANGUL SYLLABLE TIKEUT YU KIYEOKSIOS
+0x8AB9	0xB4C5	#HANGUL SYLLABLE TIKEUT YU NIEUNCIEUC
+0x8ABA	0xB4C6	#HANGUL SYLLABLE TIKEUT YU NIEUNHIEUH
+0x8ABB	0xB4C7	#HANGUL SYLLABLE TIKEUT YU TIKEUT
+0x8ABC	0xB4C9	#HANGUL SYLLABLE TIKEUT YU RIEULKIYEOK
+0x8ABD	0xB4CA	#HANGUL SYLLABLE TIKEUT YU RIEULMIEUM
+0x8ABE	0xB4CB	#HANGUL SYLLABLE TIKEUT YU RIEULPIEUP
+0x8ABF	0xB4CC	#HANGUL SYLLABLE TIKEUT YU RIEULSIOS
+0x8AC0	0xB4CD	#HANGUL SYLLABLE TIKEUT YU RIEULTHIEUTH
+0x8AC1	0xB4CE	#HANGUL SYLLABLE TIKEUT YU RIEULPHIEUPH
+0x8AC2	0xB4CF	#HANGUL SYLLABLE TIKEUT YU RIEULHIEUH
+0x8AC3	0xB4D1	#HANGUL SYLLABLE TIKEUT YU PIEUP
+0x8AC4	0xB4D2	#HANGUL SYLLABLE TIKEUT YU PIEUPSIOS
+0x8AC5	0xB4D3	#HANGUL SYLLABLE TIKEUT YU SIOS
+0x8AC6	0xB4D4	#HANGUL SYLLABLE TIKEUT YU SSANGSIOS
+0x8AC7	0xB4D6	#HANGUL SYLLABLE TIKEUT YU CIEUC
+0x8AC8	0xB4D7	#HANGUL SYLLABLE TIKEUT YU CHIEUCH
+0x8AC9	0xB4D8	#HANGUL SYLLABLE TIKEUT YU KHIEUKH
+0x8ACA	0xB4D9	#HANGUL SYLLABLE TIKEUT YU THIEUTH
+0x8ACB	0xB4DA	#HANGUL SYLLABLE TIKEUT YU PHIEUPH
+0x8ACC	0xB4DB	#HANGUL SYLLABLE TIKEUT YU HIEUH
+0x8ACD	0xB4DE	#HANGUL SYLLABLE TIKEUT EU SSANGKIYEOK
+0x8ACE	0xB4DF	#HANGUL SYLLABLE TIKEUT EU KIYEOKSIOS
+0x8ACF	0xB4E1	#HANGUL SYLLABLE TIKEUT EU NIEUNCIEUC
+0x8AD0	0xB4E2	#HANGUL SYLLABLE TIKEUT EU NIEUNHIEUH
+0x8AD1	0xB4E5	#HANGUL SYLLABLE TIKEUT EU RIEULKIYEOK
+0x8AD2	0xB4E7	#HANGUL SYLLABLE TIKEUT EU RIEULPIEUP
+0x8AD3	0xB4E8	#HANGUL SYLLABLE TIKEUT EU RIEULSIOS
+0x8AD4	0xB4E9	#HANGUL SYLLABLE TIKEUT EU RIEULTHIEUTH
+0x8AD5	0xB4EA	#HANGUL SYLLABLE TIKEUT EU RIEULPHIEUPH
+0x8AD6	0xB4EB	#HANGUL SYLLABLE TIKEUT EU RIEULHIEUH
+0x8AD7	0xB4EE	#HANGUL SYLLABLE TIKEUT EU PIEUPSIOS
+0x8AD8	0xB4F0	#HANGUL SYLLABLE TIKEUT EU SSANGSIOS
+0x8AD9	0xB4F2	#HANGUL SYLLABLE TIKEUT EU CIEUC
+0x8ADA	0xB4F3	#HANGUL SYLLABLE TIKEUT EU CHIEUCH
+0x8ADB	0xB4F4	#HANGUL SYLLABLE TIKEUT EU KHIEUKH
+0x8ADC	0xB4F5	#HANGUL SYLLABLE TIKEUT EU THIEUTH
+0x8ADD	0xB4F6	#HANGUL SYLLABLE TIKEUT EU PHIEUPH
+0x8ADE	0xB4F7	#HANGUL SYLLABLE TIKEUT EU HIEUH
+0x8ADF	0xB4F9	#HANGUL SYLLABLE TIKEUT YI KIYEOK
+0x8AE0	0xB4FA	#HANGUL SYLLABLE TIKEUT YI SSANGKIYEOK
+0x8AE1	0xB4FB	#HANGUL SYLLABLE TIKEUT YI KIYEOKSIOS
+0x8AE2	0xB4FC	#HANGUL SYLLABLE TIKEUT YI NIEUN
+0x8AE3	0xB4FD	#HANGUL SYLLABLE TIKEUT YI NIEUNCIEUC
+0x8AE4	0xB4FE	#HANGUL SYLLABLE TIKEUT YI NIEUNHIEUH
+0x8AE5	0xB4FF	#HANGUL SYLLABLE TIKEUT YI TIKEUT
+0x8AE6	0xB500	#HANGUL SYLLABLE TIKEUT YI RIEUL
+0x8AE7	0xB501	#HANGUL SYLLABLE TIKEUT YI RIEULKIYEOK
+0x8AE8	0xB502	#HANGUL SYLLABLE TIKEUT YI RIEULMIEUM
+0x8AE9	0xB503	#HANGUL SYLLABLE TIKEUT YI RIEULPIEUP
+0x8AEA	0xB504	#HANGUL SYLLABLE TIKEUT YI RIEULSIOS
+0x8AEB	0xB505	#HANGUL SYLLABLE TIKEUT YI RIEULTHIEUTH
+0x8AEC	0xB506	#HANGUL SYLLABLE TIKEUT YI RIEULPHIEUPH
+0x8AED	0xB507	#HANGUL SYLLABLE TIKEUT YI RIEULHIEUH
+0x8AEE	0xB508	#HANGUL SYLLABLE TIKEUT YI MIEUM
+0x8AEF	0xB509	#HANGUL SYLLABLE TIKEUT YI PIEUP
+0x8AF0	0xB50A	#HANGUL SYLLABLE TIKEUT YI PIEUPSIOS
+0x8AF1	0xB50B	#HANGUL SYLLABLE TIKEUT YI SIOS
+0x8AF2	0xB50C	#HANGUL SYLLABLE TIKEUT YI SSANGSIOS
+0x8AF3	0xB50D	#HANGUL SYLLABLE TIKEUT YI IEUNG
+0x8AF4	0xB50E	#HANGUL SYLLABLE TIKEUT YI CIEUC
+0x8AF5	0xB50F	#HANGUL SYLLABLE TIKEUT YI CHIEUCH
+0x8AF6	0xB510	#HANGUL SYLLABLE TIKEUT YI KHIEUKH
+0x8AF7	0xB511	#HANGUL SYLLABLE TIKEUT YI THIEUTH
+0x8AF8	0xB512	#HANGUL SYLLABLE TIKEUT YI PHIEUPH
+0x8AF9	0xB513	#HANGUL SYLLABLE TIKEUT YI HIEUH
+0x8AFA	0xB516	#HANGUL SYLLABLE TIKEUT I SSANGKIYEOK
+0x8AFB	0xB517	#HANGUL SYLLABLE TIKEUT I KIYEOKSIOS
+0x8AFC	0xB519	#HANGUL SYLLABLE TIKEUT I NIEUNCIEUC
+0x8AFD	0xB51A	#HANGUL SYLLABLE TIKEUT I NIEUNHIEUH
+0x8AFE	0xB51D	#HANGUL SYLLABLE TIKEUT I RIEULKIYEOK
+0x8B41	0xB51E	#HANGUL SYLLABLE TIKEUT I RIEULMIEUM
+0x8B42	0xB51F	#HANGUL SYLLABLE TIKEUT I RIEULPIEUP
+0x8B43	0xB520	#HANGUL SYLLABLE TIKEUT I RIEULSIOS
+0x8B44	0xB521	#HANGUL SYLLABLE TIKEUT I RIEULTHIEUTH
+0x8B45	0xB522	#HANGUL SYLLABLE TIKEUT I RIEULPHIEUPH
+0x8B46	0xB523	#HANGUL SYLLABLE TIKEUT I RIEULHIEUH
+0x8B47	0xB526	#HANGUL SYLLABLE TIKEUT I PIEUPSIOS
+0x8B48	0xB52B	#HANGUL SYLLABLE TIKEUT I CHIEUCH
+0x8B49	0xB52C	#HANGUL SYLLABLE TIKEUT I KHIEUKH
+0x8B4A	0xB52D	#HANGUL SYLLABLE TIKEUT I THIEUTH
+0x8B4B	0xB52E	#HANGUL SYLLABLE TIKEUT I PHIEUPH
+0x8B4C	0xB52F	#HANGUL SYLLABLE TIKEUT I HIEUH
+0x8B4D	0xB532	#HANGUL SYLLABLE SSANGTIKEUT A SSANGKIYEOK
+0x8B4E	0xB533	#HANGUL SYLLABLE SSANGTIKEUT A KIYEOKSIOS
+0x8B4F	0xB535	#HANGUL SYLLABLE SSANGTIKEUT A NIEUNCIEUC
+0x8B50	0xB536	#HANGUL SYLLABLE SSANGTIKEUT A NIEUNHIEUH
+0x8B51	0xB537	#HANGUL SYLLABLE SSANGTIKEUT A TIKEUT
+0x8B52	0xB539	#HANGUL SYLLABLE SSANGTIKEUT A RIEULKIYEOK
+0x8B53	0xB53A	#HANGUL SYLLABLE SSANGTIKEUT A RIEULMIEUM
+0x8B54	0xB53B	#HANGUL SYLLABLE SSANGTIKEUT A RIEULPIEUP
+0x8B55	0xB53C	#HANGUL SYLLABLE SSANGTIKEUT A RIEULSIOS
+0x8B56	0xB53D	#HANGUL SYLLABLE SSANGTIKEUT A RIEULTHIEUTH
+0x8B57	0xB53E	#HANGUL SYLLABLE SSANGTIKEUT A RIEULPHIEUPH
+0x8B58	0xB53F	#HANGUL SYLLABLE SSANGTIKEUT A RIEULHIEUH
+0x8B59	0xB542	#HANGUL SYLLABLE SSANGTIKEUT A PIEUPSIOS
+0x8B5A	0xB546	#HANGUL SYLLABLE SSANGTIKEUT A CIEUC
+0x8B61	0xB547	#HANGUL SYLLABLE SSANGTIKEUT A CHIEUCH
+0x8B62	0xB548	#HANGUL SYLLABLE SSANGTIKEUT A KHIEUKH
+0x8B63	0xB549	#HANGUL SYLLABLE SSANGTIKEUT A THIEUTH
+0x8B64	0xB54A	#HANGUL SYLLABLE SSANGTIKEUT A PHIEUPH
+0x8B65	0xB54E	#HANGUL SYLLABLE SSANGTIKEUT AE SSANGKIYEOK
+0x8B66	0xB54F	#HANGUL SYLLABLE SSANGTIKEUT AE KIYEOKSIOS
+0x8B67	0xB551	#HANGUL SYLLABLE SSANGTIKEUT AE NIEUNCIEUC
+0x8B68	0xB552	#HANGUL SYLLABLE SSANGTIKEUT AE NIEUNHIEUH
+0x8B69	0xB553	#HANGUL SYLLABLE SSANGTIKEUT AE TIKEUT
+0x8B6A	0xB555	#HANGUL SYLLABLE SSANGTIKEUT AE RIEULKIYEOK
+0x8B6B	0xB556	#HANGUL SYLLABLE SSANGTIKEUT AE RIEULMIEUM
+0x8B6C	0xB557	#HANGUL SYLLABLE SSANGTIKEUT AE RIEULPIEUP
+0x8B6D	0xB558	#HANGUL SYLLABLE SSANGTIKEUT AE RIEULSIOS
+0x8B6E	0xB559	#HANGUL SYLLABLE SSANGTIKEUT AE RIEULTHIEUTH
+0x8B6F	0xB55A	#HANGUL SYLLABLE SSANGTIKEUT AE RIEULPHIEUPH
+0x8B70	0xB55B	#HANGUL SYLLABLE SSANGTIKEUT AE RIEULHIEUH
+0x8B71	0xB55E	#HANGUL SYLLABLE SSANGTIKEUT AE PIEUPSIOS
+0x8B72	0xB562	#HANGUL SYLLABLE SSANGTIKEUT AE CIEUC
+0x8B73	0xB563	#HANGUL SYLLABLE SSANGTIKEUT AE CHIEUCH
+0x8B74	0xB564	#HANGUL SYLLABLE SSANGTIKEUT AE KHIEUKH
+0x8B75	0xB565	#HANGUL SYLLABLE SSANGTIKEUT AE THIEUTH
+0x8B76	0xB566	#HANGUL SYLLABLE SSANGTIKEUT AE PHIEUPH
+0x8B77	0xB567	#HANGUL SYLLABLE SSANGTIKEUT AE HIEUH
+0x8B78	0xB568	#HANGUL SYLLABLE SSANGTIKEUT YA
+0x8B79	0xB569	#HANGUL SYLLABLE SSANGTIKEUT YA KIYEOK
+0x8B7A	0xB56A	#HANGUL SYLLABLE SSANGTIKEUT YA SSANGKIYEOK
+0x8B81	0xB56B	#HANGUL SYLLABLE SSANGTIKEUT YA KIYEOKSIOS
+0x8B82	0xB56C	#HANGUL SYLLABLE SSANGTIKEUT YA NIEUN
+0x8B83	0xB56D	#HANGUL SYLLABLE SSANGTIKEUT YA NIEUNCIEUC
+0x8B84	0xB56E	#HANGUL SYLLABLE SSANGTIKEUT YA NIEUNHIEUH
+0x8B85	0xB56F	#HANGUL SYLLABLE SSANGTIKEUT YA TIKEUT
+0x8B86	0xB570	#HANGUL SYLLABLE SSANGTIKEUT YA RIEUL
+0x8B87	0xB571	#HANGUL SYLLABLE SSANGTIKEUT YA RIEULKIYEOK
+0x8B88	0xB572	#HANGUL SYLLABLE SSANGTIKEUT YA RIEULMIEUM
+0x8B89	0xB573	#HANGUL SYLLABLE SSANGTIKEUT YA RIEULPIEUP
+0x8B8A	0xB574	#HANGUL SYLLABLE SSANGTIKEUT YA RIEULSIOS
+0x8B8B	0xB575	#HANGUL SYLLABLE SSANGTIKEUT YA RIEULTHIEUTH
+0x8B8C	0xB576	#HANGUL SYLLABLE SSANGTIKEUT YA RIEULPHIEUPH
+0x8B8D	0xB577	#HANGUL SYLLABLE SSANGTIKEUT YA RIEULHIEUH
+0x8B8E	0xB578	#HANGUL SYLLABLE SSANGTIKEUT YA MIEUM
+0x8B8F	0xB579	#HANGUL SYLLABLE SSANGTIKEUT YA PIEUP
+0x8B90	0xB57A	#HANGUL SYLLABLE SSANGTIKEUT YA PIEUPSIOS
+0x8B91	0xB57B	#HANGUL SYLLABLE SSANGTIKEUT YA SIOS
+0x8B92	0xB57C	#HANGUL SYLLABLE SSANGTIKEUT YA SSANGSIOS
+0x8B93	0xB57D	#HANGUL SYLLABLE SSANGTIKEUT YA IEUNG
+0x8B94	0xB57E	#HANGUL SYLLABLE SSANGTIKEUT YA CIEUC
+0x8B95	0xB57F	#HANGUL SYLLABLE SSANGTIKEUT YA CHIEUCH
+0x8B96	0xB580	#HANGUL SYLLABLE SSANGTIKEUT YA KHIEUKH
+0x8B97	0xB581	#HANGUL SYLLABLE SSANGTIKEUT YA THIEUTH
+0x8B98	0xB582	#HANGUL SYLLABLE SSANGTIKEUT YA PHIEUPH
+0x8B99	0xB583	#HANGUL SYLLABLE SSANGTIKEUT YA HIEUH
+0x8B9A	0xB584	#HANGUL SYLLABLE SSANGTIKEUT YAE
+0x8B9B	0xB585	#HANGUL SYLLABLE SSANGTIKEUT YAE KIYEOK
+0x8B9C	0xB586	#HANGUL SYLLABLE SSANGTIKEUT YAE SSANGKIYEOK
+0x8B9D	0xB587	#HANGUL SYLLABLE SSANGTIKEUT YAE KIYEOKSIOS
+0x8B9E	0xB588	#HANGUL SYLLABLE SSANGTIKEUT YAE NIEUN
+0x8B9F	0xB589	#HANGUL SYLLABLE SSANGTIKEUT YAE NIEUNCIEUC
+0x8BA0	0xB58A	#HANGUL SYLLABLE SSANGTIKEUT YAE NIEUNHIEUH
+0x8BA1	0xB58B	#HANGUL SYLLABLE SSANGTIKEUT YAE TIKEUT
+0x8BA2	0xB58C	#HANGUL SYLLABLE SSANGTIKEUT YAE RIEUL
+0x8BA3	0xB58D	#HANGUL SYLLABLE SSANGTIKEUT YAE RIEULKIYEOK
+0x8BA4	0xB58E	#HANGUL SYLLABLE SSANGTIKEUT YAE RIEULMIEUM
+0x8BA5	0xB58F	#HANGUL SYLLABLE SSANGTIKEUT YAE RIEULPIEUP
+0x8BA6	0xB590	#HANGUL SYLLABLE SSANGTIKEUT YAE RIEULSIOS
+0x8BA7	0xB591	#HANGUL SYLLABLE SSANGTIKEUT YAE RIEULTHIEUTH
+0x8BA8	0xB592	#HANGUL SYLLABLE SSANGTIKEUT YAE RIEULPHIEUPH
+0x8BA9	0xB593	#HANGUL SYLLABLE SSANGTIKEUT YAE RIEULHIEUH
+0x8BAA	0xB594	#HANGUL SYLLABLE SSANGTIKEUT YAE MIEUM
+0x8BAB	0xB595	#HANGUL SYLLABLE SSANGTIKEUT YAE PIEUP
+0x8BAC	0xB596	#HANGUL SYLLABLE SSANGTIKEUT YAE PIEUPSIOS
+0x8BAD	0xB597	#HANGUL SYLLABLE SSANGTIKEUT YAE SIOS
+0x8BAE	0xB598	#HANGUL SYLLABLE SSANGTIKEUT YAE SSANGSIOS
+0x8BAF	0xB599	#HANGUL SYLLABLE SSANGTIKEUT YAE IEUNG
+0x8BB0	0xB59A	#HANGUL SYLLABLE SSANGTIKEUT YAE CIEUC
+0x8BB1	0xB59B	#HANGUL SYLLABLE SSANGTIKEUT YAE CHIEUCH
+0x8BB2	0xB59C	#HANGUL SYLLABLE SSANGTIKEUT YAE KHIEUKH
+0x8BB3	0xB59D	#HANGUL SYLLABLE SSANGTIKEUT YAE THIEUTH
+0x8BB4	0xB59E	#HANGUL SYLLABLE SSANGTIKEUT YAE PHIEUPH
+0x8BB5	0xB59F	#HANGUL SYLLABLE SSANGTIKEUT YAE HIEUH
+0x8BB6	0xB5A2	#HANGUL SYLLABLE SSANGTIKEUT EO SSANGKIYEOK
+0x8BB7	0xB5A3	#HANGUL SYLLABLE SSANGTIKEUT EO KIYEOKSIOS
+0x8BB8	0xB5A5	#HANGUL SYLLABLE SSANGTIKEUT EO NIEUNCIEUC
+0x8BB9	0xB5A6	#HANGUL SYLLABLE SSANGTIKEUT EO NIEUNHIEUH
+0x8BBA	0xB5A7	#HANGUL SYLLABLE SSANGTIKEUT EO TIKEUT
+0x8BBB	0xB5A9	#HANGUL SYLLABLE SSANGTIKEUT EO RIEULKIYEOK
+0x8BBC	0xB5AC	#HANGUL SYLLABLE SSANGTIKEUT EO RIEULSIOS
+0x8BBD	0xB5AD	#HANGUL SYLLABLE SSANGTIKEUT EO RIEULTHIEUTH
+0x8BBE	0xB5AE	#HANGUL SYLLABLE SSANGTIKEUT EO RIEULPHIEUPH
+0x8BBF	0xB5AF	#HANGUL SYLLABLE SSANGTIKEUT EO RIEULHIEUH
+0x8BC0	0xB5B2	#HANGUL SYLLABLE SSANGTIKEUT EO PIEUPSIOS
+0x8BC1	0xB5B6	#HANGUL SYLLABLE SSANGTIKEUT EO CIEUC
+0x8BC2	0xB5B7	#HANGUL SYLLABLE SSANGTIKEUT EO CHIEUCH
+0x8BC3	0xB5B8	#HANGUL SYLLABLE SSANGTIKEUT EO KHIEUKH
+0x8BC4	0xB5B9	#HANGUL SYLLABLE SSANGTIKEUT EO THIEUTH
+0x8BC5	0xB5BA	#HANGUL SYLLABLE SSANGTIKEUT EO PHIEUPH
+0x8BC6	0xB5BE	#HANGUL SYLLABLE SSANGTIKEUT E SSANGKIYEOK
+0x8BC7	0xB5BF	#HANGUL SYLLABLE SSANGTIKEUT E KIYEOKSIOS
+0x8BC8	0xB5C1	#HANGUL SYLLABLE SSANGTIKEUT E NIEUNCIEUC
+0x8BC9	0xB5C2	#HANGUL SYLLABLE SSANGTIKEUT E NIEUNHIEUH
+0x8BCA	0xB5C3	#HANGUL SYLLABLE SSANGTIKEUT E TIKEUT
+0x8BCB	0xB5C5	#HANGUL SYLLABLE SSANGTIKEUT E RIEULKIYEOK
+0x8BCC	0xB5C6	#HANGUL SYLLABLE SSANGTIKEUT E RIEULMIEUM
+0x8BCD	0xB5C7	#HANGUL SYLLABLE SSANGTIKEUT E RIEULPIEUP
+0x8BCE	0xB5C8	#HANGUL SYLLABLE SSANGTIKEUT E RIEULSIOS
+0x8BCF	0xB5C9	#HANGUL SYLLABLE SSANGTIKEUT E RIEULTHIEUTH
+0x8BD0	0xB5CA	#HANGUL SYLLABLE SSANGTIKEUT E RIEULPHIEUPH
+0x8BD1	0xB5CB	#HANGUL SYLLABLE SSANGTIKEUT E RIEULHIEUH
+0x8BD2	0xB5CE	#HANGUL SYLLABLE SSANGTIKEUT E PIEUPSIOS
+0x8BD3	0xB5D2	#HANGUL SYLLABLE SSANGTIKEUT E CIEUC
+0x8BD4	0xB5D3	#HANGUL SYLLABLE SSANGTIKEUT E CHIEUCH
+0x8BD5	0xB5D4	#HANGUL SYLLABLE SSANGTIKEUT E KHIEUKH
+0x8BD6	0xB5D5	#HANGUL SYLLABLE SSANGTIKEUT E THIEUTH
+0x8BD7	0xB5D6	#HANGUL SYLLABLE SSANGTIKEUT E PHIEUPH
+0x8BD8	0xB5D7	#HANGUL SYLLABLE SSANGTIKEUT E HIEUH
+0x8BD9	0xB5D9	#HANGUL SYLLABLE SSANGTIKEUT YEO KIYEOK
+0x8BDA	0xB5DA	#HANGUL SYLLABLE SSANGTIKEUT YEO SSANGKIYEOK
+0x8BDB	0xB5DB	#HANGUL SYLLABLE SSANGTIKEUT YEO KIYEOKSIOS
+0x8BDC	0xB5DC	#HANGUL SYLLABLE SSANGTIKEUT YEO NIEUN
+0x8BDD	0xB5DD	#HANGUL SYLLABLE SSANGTIKEUT YEO NIEUNCIEUC
+0x8BDE	0xB5DE	#HANGUL SYLLABLE SSANGTIKEUT YEO NIEUNHIEUH
+0x8BDF	0xB5DF	#HANGUL SYLLABLE SSANGTIKEUT YEO TIKEUT
+0x8BE0	0xB5E0	#HANGUL SYLLABLE SSANGTIKEUT YEO RIEUL
+0x8BE1	0xB5E1	#HANGUL SYLLABLE SSANGTIKEUT YEO RIEULKIYEOK
+0x8BE2	0xB5E2	#HANGUL SYLLABLE SSANGTIKEUT YEO RIEULMIEUM
+0x8BE3	0xB5E3	#HANGUL SYLLABLE SSANGTIKEUT YEO RIEULPIEUP
+0x8BE4	0xB5E4	#HANGUL SYLLABLE SSANGTIKEUT YEO RIEULSIOS
+0x8BE5	0xB5E5	#HANGUL SYLLABLE SSANGTIKEUT YEO RIEULTHIEUTH
+0x8BE6	0xB5E6	#HANGUL SYLLABLE SSANGTIKEUT YEO RIEULPHIEUPH
+0x8BE7	0xB5E7	#HANGUL SYLLABLE SSANGTIKEUT YEO RIEULHIEUH
+0x8BE8	0xB5E8	#HANGUL SYLLABLE SSANGTIKEUT YEO MIEUM
+0x8BE9	0xB5E9	#HANGUL SYLLABLE SSANGTIKEUT YEO PIEUP
+0x8BEA	0xB5EA	#HANGUL SYLLABLE SSANGTIKEUT YEO PIEUPSIOS
+0x8BEB	0xB5EB	#HANGUL SYLLABLE SSANGTIKEUT YEO SIOS
+0x8BEC	0xB5ED	#HANGUL SYLLABLE SSANGTIKEUT YEO IEUNG
+0x8BED	0xB5EE	#HANGUL SYLLABLE SSANGTIKEUT YEO CIEUC
+0x8BEE	0xB5EF	#HANGUL SYLLABLE SSANGTIKEUT YEO CHIEUCH
+0x8BEF	0xB5F0	#HANGUL SYLLABLE SSANGTIKEUT YEO KHIEUKH
+0x8BF0	0xB5F1	#HANGUL SYLLABLE SSANGTIKEUT YEO THIEUTH
+0x8BF1	0xB5F2	#HANGUL SYLLABLE SSANGTIKEUT YEO PHIEUPH
+0x8BF2	0xB5F3	#HANGUL SYLLABLE SSANGTIKEUT YEO HIEUH
+0x8BF3	0xB5F4	#HANGUL SYLLABLE SSANGTIKEUT YE
+0x8BF4	0xB5F5	#HANGUL SYLLABLE SSANGTIKEUT YE KIYEOK
+0x8BF5	0xB5F6	#HANGUL SYLLABLE SSANGTIKEUT YE SSANGKIYEOK
+0x8BF6	0xB5F7	#HANGUL SYLLABLE SSANGTIKEUT YE KIYEOKSIOS
+0x8BF7	0xB5F8	#HANGUL SYLLABLE SSANGTIKEUT YE NIEUN
+0x8BF8	0xB5F9	#HANGUL SYLLABLE SSANGTIKEUT YE NIEUNCIEUC
+0x8BF9	0xB5FA	#HANGUL SYLLABLE SSANGTIKEUT YE NIEUNHIEUH
+0x8BFA	0xB5FB	#HANGUL SYLLABLE SSANGTIKEUT YE TIKEUT
+0x8BFB	0xB5FC	#HANGUL SYLLABLE SSANGTIKEUT YE RIEUL
+0x8BFC	0xB5FD	#HANGUL SYLLABLE SSANGTIKEUT YE RIEULKIYEOK
+0x8BFD	0xB5FE	#HANGUL SYLLABLE SSANGTIKEUT YE RIEULMIEUM
+0x8BFE	0xB5FF	#HANGUL SYLLABLE SSANGTIKEUT YE RIEULPIEUP
+0x8C41	0xB600	#HANGUL SYLLABLE SSANGTIKEUT YE RIEULSIOS
+0x8C42	0xB601	#HANGUL SYLLABLE SSANGTIKEUT YE RIEULTHIEUTH
+0x8C43	0xB602	#HANGUL SYLLABLE SSANGTIKEUT YE RIEULPHIEUPH
+0x8C44	0xB603	#HANGUL SYLLABLE SSANGTIKEUT YE RIEULHIEUH
+0x8C45	0xB604	#HANGUL SYLLABLE SSANGTIKEUT YE MIEUM
+0x8C46	0xB605	#HANGUL SYLLABLE SSANGTIKEUT YE PIEUP
+0x8C47	0xB606	#HANGUL SYLLABLE SSANGTIKEUT YE PIEUPSIOS
+0x8C48	0xB607	#HANGUL SYLLABLE SSANGTIKEUT YE SIOS
+0x8C49	0xB608	#HANGUL SYLLABLE SSANGTIKEUT YE SSANGSIOS
+0x8C4A	0xB609	#HANGUL SYLLABLE SSANGTIKEUT YE IEUNG
+0x8C4B	0xB60A	#HANGUL SYLLABLE SSANGTIKEUT YE CIEUC
+0x8C4C	0xB60B	#HANGUL SYLLABLE SSANGTIKEUT YE CHIEUCH
+0x8C4D	0xB60C	#HANGUL SYLLABLE SSANGTIKEUT YE KHIEUKH
+0x8C4E	0xB60D	#HANGUL SYLLABLE SSANGTIKEUT YE THIEUTH
+0x8C4F	0xB60E	#HANGUL SYLLABLE SSANGTIKEUT YE PHIEUPH
+0x8C50	0xB60F	#HANGUL SYLLABLE SSANGTIKEUT YE HIEUH
+0x8C51	0xB612	#HANGUL SYLLABLE SSANGTIKEUT O SSANGKIYEOK
+0x8C52	0xB613	#HANGUL SYLLABLE SSANGTIKEUT O KIYEOKSIOS
+0x8C53	0xB615	#HANGUL SYLLABLE SSANGTIKEUT O NIEUNCIEUC
+0x8C54	0xB616	#HANGUL SYLLABLE SSANGTIKEUT O NIEUNHIEUH
+0x8C55	0xB617	#HANGUL SYLLABLE SSANGTIKEUT O TIKEUT
+0x8C56	0xB619	#HANGUL SYLLABLE SSANGTIKEUT O RIEULKIYEOK
+0x8C57	0xB61A	#HANGUL SYLLABLE SSANGTIKEUT O RIEULMIEUM
+0x8C58	0xB61B	#HANGUL SYLLABLE SSANGTIKEUT O RIEULPIEUP
+0x8C59	0xB61C	#HANGUL SYLLABLE SSANGTIKEUT O RIEULSIOS
+0x8C5A	0xB61D	#HANGUL SYLLABLE SSANGTIKEUT O RIEULTHIEUTH
+0x8C61	0xB61E	#HANGUL SYLLABLE SSANGTIKEUT O RIEULPHIEUPH
+0x8C62	0xB61F	#HANGUL SYLLABLE SSANGTIKEUT O RIEULHIEUH
+0x8C63	0xB620	#HANGUL SYLLABLE SSANGTIKEUT O MIEUM
+0x8C64	0xB621	#HANGUL SYLLABLE SSANGTIKEUT O PIEUP
+0x8C65	0xB622	#HANGUL SYLLABLE SSANGTIKEUT O PIEUPSIOS
+0x8C66	0xB623	#HANGUL SYLLABLE SSANGTIKEUT O SIOS
+0x8C67	0xB624	#HANGUL SYLLABLE SSANGTIKEUT O SSANGSIOS
+0x8C68	0xB626	#HANGUL SYLLABLE SSANGTIKEUT O CIEUC
+0x8C69	0xB627	#HANGUL SYLLABLE SSANGTIKEUT O CHIEUCH
+0x8C6A	0xB628	#HANGUL SYLLABLE SSANGTIKEUT O KHIEUKH
+0x8C6B	0xB629	#HANGUL SYLLABLE SSANGTIKEUT O THIEUTH
+0x8C6C	0xB62A	#HANGUL SYLLABLE SSANGTIKEUT O PHIEUPH
+0x8C6D	0xB62B	#HANGUL SYLLABLE SSANGTIKEUT O HIEUH
+0x8C6E	0xB62D	#HANGUL SYLLABLE SSANGTIKEUT WA KIYEOK
+0x8C6F	0xB62E	#HANGUL SYLLABLE SSANGTIKEUT WA SSANGKIYEOK
+0x8C70	0xB62F	#HANGUL SYLLABLE SSANGTIKEUT WA KIYEOKSIOS
+0x8C71	0xB630	#HANGUL SYLLABLE SSANGTIKEUT WA NIEUN
+0x8C72	0xB631	#HANGUL SYLLABLE SSANGTIKEUT WA NIEUNCIEUC
+0x8C73	0xB632	#HANGUL SYLLABLE SSANGTIKEUT WA NIEUNHIEUH
+0x8C74	0xB633	#HANGUL SYLLABLE SSANGTIKEUT WA TIKEUT
+0x8C75	0xB635	#HANGUL SYLLABLE SSANGTIKEUT WA RIEULKIYEOK
+0x8C76	0xB636	#HANGUL SYLLABLE SSANGTIKEUT WA RIEULMIEUM
+0x8C77	0xB637	#HANGUL SYLLABLE SSANGTIKEUT WA RIEULPIEUP
+0x8C78	0xB638	#HANGUL SYLLABLE SSANGTIKEUT WA RIEULSIOS
+0x8C79	0xB639	#HANGUL SYLLABLE SSANGTIKEUT WA RIEULTHIEUTH
+0x8C7A	0xB63A	#HANGUL SYLLABLE SSANGTIKEUT WA RIEULPHIEUPH
+0x8C81	0xB63B	#HANGUL SYLLABLE SSANGTIKEUT WA RIEULHIEUH
+0x8C82	0xB63C	#HANGUL SYLLABLE SSANGTIKEUT WA MIEUM
+0x8C83	0xB63D	#HANGUL SYLLABLE SSANGTIKEUT WA PIEUP
+0x8C84	0xB63E	#HANGUL SYLLABLE SSANGTIKEUT WA PIEUPSIOS
+0x8C85	0xB63F	#HANGUL SYLLABLE SSANGTIKEUT WA SIOS
+0x8C86	0xB640	#HANGUL SYLLABLE SSANGTIKEUT WA SSANGSIOS
+0x8C87	0xB641	#HANGUL SYLLABLE SSANGTIKEUT WA IEUNG
+0x8C88	0xB642	#HANGUL SYLLABLE SSANGTIKEUT WA CIEUC
+0x8C89	0xB643	#HANGUL SYLLABLE SSANGTIKEUT WA CHIEUCH
+0x8C8A	0xB644	#HANGUL SYLLABLE SSANGTIKEUT WA KHIEUKH
+0x8C8B	0xB645	#HANGUL SYLLABLE SSANGTIKEUT WA THIEUTH
+0x8C8C	0xB646	#HANGUL SYLLABLE SSANGTIKEUT WA PHIEUPH
+0x8C8D	0xB647	#HANGUL SYLLABLE SSANGTIKEUT WA HIEUH
+0x8C8E	0xB649	#HANGUL SYLLABLE SSANGTIKEUT WAE KIYEOK
+0x8C8F	0xB64A	#HANGUL SYLLABLE SSANGTIKEUT WAE SSANGKIYEOK
+0x8C90	0xB64B	#HANGUL SYLLABLE SSANGTIKEUT WAE KIYEOKSIOS
+0x8C91	0xB64C	#HANGUL SYLLABLE SSANGTIKEUT WAE NIEUN
+0x8C92	0xB64D	#HANGUL SYLLABLE SSANGTIKEUT WAE NIEUNCIEUC
+0x8C93	0xB64E	#HANGUL SYLLABLE SSANGTIKEUT WAE NIEUNHIEUH
+0x8C94	0xB64F	#HANGUL SYLLABLE SSANGTIKEUT WAE TIKEUT
+0x8C95	0xB650	#HANGUL SYLLABLE SSANGTIKEUT WAE RIEUL
+0x8C96	0xB651	#HANGUL SYLLABLE SSANGTIKEUT WAE RIEULKIYEOK
+0x8C97	0xB652	#HANGUL SYLLABLE SSANGTIKEUT WAE RIEULMIEUM
+0x8C98	0xB653	#HANGUL SYLLABLE SSANGTIKEUT WAE RIEULPIEUP
+0x8C99	0xB654	#HANGUL SYLLABLE SSANGTIKEUT WAE RIEULSIOS
+0x8C9A	0xB655	#HANGUL SYLLABLE SSANGTIKEUT WAE RIEULTHIEUTH
+0x8C9B	0xB656	#HANGUL SYLLABLE SSANGTIKEUT WAE RIEULPHIEUPH
+0x8C9C	0xB657	#HANGUL SYLLABLE SSANGTIKEUT WAE RIEULHIEUH
+0x8C9D	0xB658	#HANGUL SYLLABLE SSANGTIKEUT WAE MIEUM
+0x8C9E	0xB659	#HANGUL SYLLABLE SSANGTIKEUT WAE PIEUP
+0x8C9F	0xB65A	#HANGUL SYLLABLE SSANGTIKEUT WAE PIEUPSIOS
+0x8CA0	0xB65B	#HANGUL SYLLABLE SSANGTIKEUT WAE SIOS
+0x8CA1	0xB65C	#HANGUL SYLLABLE SSANGTIKEUT WAE SSANGSIOS
+0x8CA2	0xB65D	#HANGUL SYLLABLE SSANGTIKEUT WAE IEUNG
+0x8CA3	0xB65E	#HANGUL SYLLABLE SSANGTIKEUT WAE CIEUC
+0x8CA4	0xB65F	#HANGUL SYLLABLE SSANGTIKEUT WAE CHIEUCH
+0x8CA5	0xB660	#HANGUL SYLLABLE SSANGTIKEUT WAE KHIEUKH
+0x8CA6	0xB661	#HANGUL SYLLABLE SSANGTIKEUT WAE THIEUTH
+0x8CA7	0xB662	#HANGUL SYLLABLE SSANGTIKEUT WAE PHIEUPH
+0x8CA8	0xB663	#HANGUL SYLLABLE SSANGTIKEUT WAE HIEUH
+0x8CA9	0xB665	#HANGUL SYLLABLE SSANGTIKEUT OE KIYEOK
+0x8CAA	0xB666	#HANGUL SYLLABLE SSANGTIKEUT OE SSANGKIYEOK
+0x8CAB	0xB667	#HANGUL SYLLABLE SSANGTIKEUT OE KIYEOKSIOS
+0x8CAC	0xB669	#HANGUL SYLLABLE SSANGTIKEUT OE NIEUNCIEUC
+0x8CAD	0xB66A	#HANGUL SYLLABLE SSANGTIKEUT OE NIEUNHIEUH
+0x8CAE	0xB66B	#HANGUL SYLLABLE SSANGTIKEUT OE TIKEUT
+0x8CAF	0xB66C	#HANGUL SYLLABLE SSANGTIKEUT OE RIEUL
+0x8CB0	0xB66D	#HANGUL SYLLABLE SSANGTIKEUT OE RIEULKIYEOK
+0x8CB1	0xB66E	#HANGUL SYLLABLE SSANGTIKEUT OE RIEULMIEUM
+0x8CB2	0xB66F	#HANGUL SYLLABLE SSANGTIKEUT OE RIEULPIEUP
+0x8CB3	0xB670	#HANGUL SYLLABLE SSANGTIKEUT OE RIEULSIOS
+0x8CB4	0xB671	#HANGUL SYLLABLE SSANGTIKEUT OE RIEULTHIEUTH
+0x8CB5	0xB672	#HANGUL SYLLABLE SSANGTIKEUT OE RIEULPHIEUPH
+0x8CB6	0xB673	#HANGUL SYLLABLE SSANGTIKEUT OE RIEULHIEUH
+0x8CB7	0xB674	#HANGUL SYLLABLE SSANGTIKEUT OE MIEUM
+0x8CB8	0xB675	#HANGUL SYLLABLE SSANGTIKEUT OE PIEUP
+0x8CB9	0xB676	#HANGUL SYLLABLE SSANGTIKEUT OE PIEUPSIOS
+0x8CBA	0xB677	#HANGUL SYLLABLE SSANGTIKEUT OE SIOS
+0x8CBB	0xB678	#HANGUL SYLLABLE SSANGTIKEUT OE SSANGSIOS
+0x8CBC	0xB679	#HANGUL SYLLABLE SSANGTIKEUT OE IEUNG
+0x8CBD	0xB67A	#HANGUL SYLLABLE SSANGTIKEUT OE CIEUC
+0x8CBE	0xB67B	#HANGUL SYLLABLE SSANGTIKEUT OE CHIEUCH
+0x8CBF	0xB67C	#HANGUL SYLLABLE SSANGTIKEUT OE KHIEUKH
+0x8CC0	0xB67D	#HANGUL SYLLABLE SSANGTIKEUT OE THIEUTH
+0x8CC1	0xB67E	#HANGUL SYLLABLE SSANGTIKEUT OE PHIEUPH
+0x8CC2	0xB67F	#HANGUL SYLLABLE SSANGTIKEUT OE HIEUH
+0x8CC3	0xB680	#HANGUL SYLLABLE SSANGTIKEUT YO
+0x8CC4	0xB681	#HANGUL SYLLABLE SSANGTIKEUT YO KIYEOK
+0x8CC5	0xB682	#HANGUL SYLLABLE SSANGTIKEUT YO SSANGKIYEOK
+0x8CC6	0xB683	#HANGUL SYLLABLE SSANGTIKEUT YO KIYEOKSIOS
+0x8CC7	0xB684	#HANGUL SYLLABLE SSANGTIKEUT YO NIEUN
+0x8CC8	0xB685	#HANGUL SYLLABLE SSANGTIKEUT YO NIEUNCIEUC
+0x8CC9	0xB686	#HANGUL SYLLABLE SSANGTIKEUT YO NIEUNHIEUH
+0x8CCA	0xB687	#HANGUL SYLLABLE SSANGTIKEUT YO TIKEUT
+0x8CCB	0xB688	#HANGUL SYLLABLE SSANGTIKEUT YO RIEUL
+0x8CCC	0xB689	#HANGUL SYLLABLE SSANGTIKEUT YO RIEULKIYEOK
+0x8CCD	0xB68A	#HANGUL SYLLABLE SSANGTIKEUT YO RIEULMIEUM
+0x8CCE	0xB68B	#HANGUL SYLLABLE SSANGTIKEUT YO RIEULPIEUP
+0x8CCF	0xB68C	#HANGUL SYLLABLE SSANGTIKEUT YO RIEULSIOS
+0x8CD0	0xB68D	#HANGUL SYLLABLE SSANGTIKEUT YO RIEULTHIEUTH
+0x8CD1	0xB68E	#HANGUL SYLLABLE SSANGTIKEUT YO RIEULPHIEUPH
+0x8CD2	0xB68F	#HANGUL SYLLABLE SSANGTIKEUT YO RIEULHIEUH
+0x8CD3	0xB690	#HANGUL SYLLABLE SSANGTIKEUT YO MIEUM
+0x8CD4	0xB691	#HANGUL SYLLABLE SSANGTIKEUT YO PIEUP
+0x8CD5	0xB692	#HANGUL SYLLABLE SSANGTIKEUT YO PIEUPSIOS
+0x8CD6	0xB693	#HANGUL SYLLABLE SSANGTIKEUT YO SIOS
+0x8CD7	0xB694	#HANGUL SYLLABLE SSANGTIKEUT YO SSANGSIOS
+0x8CD8	0xB695	#HANGUL SYLLABLE SSANGTIKEUT YO IEUNG
+0x8CD9	0xB696	#HANGUL SYLLABLE SSANGTIKEUT YO CIEUC
+0x8CDA	0xB697	#HANGUL SYLLABLE SSANGTIKEUT YO CHIEUCH
+0x8CDB	0xB698	#HANGUL SYLLABLE SSANGTIKEUT YO KHIEUKH
+0x8CDC	0xB699	#HANGUL SYLLABLE SSANGTIKEUT YO THIEUTH
+0x8CDD	0xB69A	#HANGUL SYLLABLE SSANGTIKEUT YO PHIEUPH
+0x8CDE	0xB69B	#HANGUL SYLLABLE SSANGTIKEUT YO HIEUH
+0x8CDF	0xB69E	#HANGUL SYLLABLE SSANGTIKEUT U SSANGKIYEOK
+0x8CE0	0xB69F	#HANGUL SYLLABLE SSANGTIKEUT U KIYEOKSIOS
+0x8CE1	0xB6A1	#HANGUL SYLLABLE SSANGTIKEUT U NIEUNCIEUC
+0x8CE2	0xB6A2	#HANGUL SYLLABLE SSANGTIKEUT U NIEUNHIEUH
+0x8CE3	0xB6A3	#HANGUL SYLLABLE SSANGTIKEUT U TIKEUT
+0x8CE4	0xB6A5	#HANGUL SYLLABLE SSANGTIKEUT U RIEULKIYEOK
+0x8CE5	0xB6A6	#HANGUL SYLLABLE SSANGTIKEUT U RIEULMIEUM
+0x8CE6	0xB6A7	#HANGUL SYLLABLE SSANGTIKEUT U RIEULPIEUP
+0x8CE7	0xB6A8	#HANGUL SYLLABLE SSANGTIKEUT U RIEULSIOS
+0x8CE8	0xB6A9	#HANGUL SYLLABLE SSANGTIKEUT U RIEULTHIEUTH
+0x8CE9	0xB6AA	#HANGUL SYLLABLE SSANGTIKEUT U RIEULPHIEUPH
+0x8CEA	0xB6AD	#HANGUL SYLLABLE SSANGTIKEUT U PIEUP
+0x8CEB	0xB6AE	#HANGUL SYLLABLE SSANGTIKEUT U PIEUPSIOS
+0x8CEC	0xB6AF	#HANGUL SYLLABLE SSANGTIKEUT U SIOS
+0x8CED	0xB6B0	#HANGUL SYLLABLE SSANGTIKEUT U SSANGSIOS
+0x8CEE	0xB6B2	#HANGUL SYLLABLE SSANGTIKEUT U CIEUC
+0x8CEF	0xB6B3	#HANGUL SYLLABLE SSANGTIKEUT U CHIEUCH
+0x8CF0	0xB6B4	#HANGUL SYLLABLE SSANGTIKEUT U KHIEUKH
+0x8CF1	0xB6B5	#HANGUL SYLLABLE SSANGTIKEUT U THIEUTH
+0x8CF2	0xB6B6	#HANGUL SYLLABLE SSANGTIKEUT U PHIEUPH
+0x8CF3	0xB6B7	#HANGUL SYLLABLE SSANGTIKEUT U HIEUH
+0x8CF4	0xB6B8	#HANGUL SYLLABLE SSANGTIKEUT WEO
+0x8CF5	0xB6B9	#HANGUL SYLLABLE SSANGTIKEUT WEO KIYEOK
+0x8CF6	0xB6BA	#HANGUL SYLLABLE SSANGTIKEUT WEO SSANGKIYEOK
+0x8CF7	0xB6BB	#HANGUL SYLLABLE SSANGTIKEUT WEO KIYEOKSIOS
+0x8CF8	0xB6BC	#HANGUL SYLLABLE SSANGTIKEUT WEO NIEUN
+0x8CF9	0xB6BD	#HANGUL SYLLABLE SSANGTIKEUT WEO NIEUNCIEUC
+0x8CFA	0xB6BE	#HANGUL SYLLABLE SSANGTIKEUT WEO NIEUNHIEUH
+0x8CFB	0xB6BF	#HANGUL SYLLABLE SSANGTIKEUT WEO TIKEUT
+0x8CFC	0xB6C0	#HANGUL SYLLABLE SSANGTIKEUT WEO RIEUL
+0x8CFD	0xB6C1	#HANGUL SYLLABLE SSANGTIKEUT WEO RIEULKIYEOK
+0x8CFE	0xB6C2	#HANGUL SYLLABLE SSANGTIKEUT WEO RIEULMIEUM
+0x8D41	0xB6C3	#HANGUL SYLLABLE SSANGTIKEUT WEO RIEULPIEUP
+0x8D42	0xB6C4	#HANGUL SYLLABLE SSANGTIKEUT WEO RIEULSIOS
+0x8D43	0xB6C5	#HANGUL SYLLABLE SSANGTIKEUT WEO RIEULTHIEUTH
+0x8D44	0xB6C6	#HANGUL SYLLABLE SSANGTIKEUT WEO RIEULPHIEUPH
+0x8D45	0xB6C7	#HANGUL SYLLABLE SSANGTIKEUT WEO RIEULHIEUH
+0x8D46	0xB6C8	#HANGUL SYLLABLE SSANGTIKEUT WEO MIEUM
+0x8D47	0xB6C9	#HANGUL SYLLABLE SSANGTIKEUT WEO PIEUP
+0x8D48	0xB6CA	#HANGUL SYLLABLE SSANGTIKEUT WEO PIEUPSIOS
+0x8D49	0xB6CB	#HANGUL SYLLABLE SSANGTIKEUT WEO SIOS
+0x8D4A	0xB6CC	#HANGUL SYLLABLE SSANGTIKEUT WEO SSANGSIOS
+0x8D4B	0xB6CD	#HANGUL SYLLABLE SSANGTIKEUT WEO IEUNG
+0x8D4C	0xB6CE	#HANGUL SYLLABLE SSANGTIKEUT WEO CIEUC
+0x8D4D	0xB6CF	#HANGUL SYLLABLE SSANGTIKEUT WEO CHIEUCH
+0x8D4E	0xB6D0	#HANGUL SYLLABLE SSANGTIKEUT WEO KHIEUKH
+0x8D4F	0xB6D1	#HANGUL SYLLABLE SSANGTIKEUT WEO THIEUTH
+0x8D50	0xB6D2	#HANGUL SYLLABLE SSANGTIKEUT WEO PHIEUPH
+0x8D51	0xB6D3	#HANGUL SYLLABLE SSANGTIKEUT WEO HIEUH
+0x8D52	0xB6D5	#HANGUL SYLLABLE SSANGTIKEUT WE KIYEOK
+0x8D53	0xB6D6	#HANGUL SYLLABLE SSANGTIKEUT WE SSANGKIYEOK
+0x8D54	0xB6D7	#HANGUL SYLLABLE SSANGTIKEUT WE KIYEOKSIOS
+0x8D55	0xB6D8	#HANGUL SYLLABLE SSANGTIKEUT WE NIEUN
+0x8D56	0xB6D9	#HANGUL SYLLABLE SSANGTIKEUT WE NIEUNCIEUC
+0x8D57	0xB6DA	#HANGUL SYLLABLE SSANGTIKEUT WE NIEUNHIEUH
+0x8D58	0xB6DB	#HANGUL SYLLABLE SSANGTIKEUT WE TIKEUT
+0x8D59	0xB6DC	#HANGUL SYLLABLE SSANGTIKEUT WE RIEUL
+0x8D5A	0xB6DD	#HANGUL SYLLABLE SSANGTIKEUT WE RIEULKIYEOK
+0x8D61	0xB6DE	#HANGUL SYLLABLE SSANGTIKEUT WE RIEULMIEUM
+0x8D62	0xB6DF	#HANGUL SYLLABLE SSANGTIKEUT WE RIEULPIEUP
+0x8D63	0xB6E0	#HANGUL SYLLABLE SSANGTIKEUT WE RIEULSIOS
+0x8D64	0xB6E1	#HANGUL SYLLABLE SSANGTIKEUT WE RIEULTHIEUTH
+0x8D65	0xB6E2	#HANGUL SYLLABLE SSANGTIKEUT WE RIEULPHIEUPH
+0x8D66	0xB6E3	#HANGUL SYLLABLE SSANGTIKEUT WE RIEULHIEUH
+0x8D67	0xB6E4	#HANGUL SYLLABLE SSANGTIKEUT WE MIEUM
+0x8D68	0xB6E5	#HANGUL SYLLABLE SSANGTIKEUT WE PIEUP
+0x8D69	0xB6E6	#HANGUL SYLLABLE SSANGTIKEUT WE PIEUPSIOS
+0x8D6A	0xB6E7	#HANGUL SYLLABLE SSANGTIKEUT WE SIOS
+0x8D6B	0xB6E8	#HANGUL SYLLABLE SSANGTIKEUT WE SSANGSIOS
+0x8D6C	0xB6E9	#HANGUL SYLLABLE SSANGTIKEUT WE IEUNG
+0x8D6D	0xB6EA	#HANGUL SYLLABLE SSANGTIKEUT WE CIEUC
+0x8D6E	0xB6EB	#HANGUL SYLLABLE SSANGTIKEUT WE CHIEUCH
+0x8D6F	0xB6EC	#HANGUL SYLLABLE SSANGTIKEUT WE KHIEUKH
+0x8D70	0xB6ED	#HANGUL SYLLABLE SSANGTIKEUT WE THIEUTH
+0x8D71	0xB6EE	#HANGUL SYLLABLE SSANGTIKEUT WE PHIEUPH
+0x8D72	0xB6EF	#HANGUL SYLLABLE SSANGTIKEUT WE HIEUH
+0x8D73	0xB6F1	#HANGUL SYLLABLE SSANGTIKEUT WI KIYEOK
+0x8D74	0xB6F2	#HANGUL SYLLABLE SSANGTIKEUT WI SSANGKIYEOK
+0x8D75	0xB6F3	#HANGUL SYLLABLE SSANGTIKEUT WI KIYEOKSIOS
+0x8D76	0xB6F5	#HANGUL SYLLABLE SSANGTIKEUT WI NIEUNCIEUC
+0x8D77	0xB6F6	#HANGUL SYLLABLE SSANGTIKEUT WI NIEUNHIEUH
+0x8D78	0xB6F7	#HANGUL SYLLABLE SSANGTIKEUT WI TIKEUT
+0x8D79	0xB6F9	#HANGUL SYLLABLE SSANGTIKEUT WI RIEULKIYEOK
+0x8D7A	0xB6FA	#HANGUL SYLLABLE SSANGTIKEUT WI RIEULMIEUM
+0x8D81	0xB6FB	#HANGUL SYLLABLE SSANGTIKEUT WI RIEULPIEUP
+0x8D82	0xB6FC	#HANGUL SYLLABLE SSANGTIKEUT WI RIEULSIOS
+0x8D83	0xB6FD	#HANGUL SYLLABLE SSANGTIKEUT WI RIEULTHIEUTH
+0x8D84	0xB6FE	#HANGUL SYLLABLE SSANGTIKEUT WI RIEULPHIEUPH
+0x8D85	0xB6FF	#HANGUL SYLLABLE SSANGTIKEUT WI RIEULHIEUH
+0x8D86	0xB702	#HANGUL SYLLABLE SSANGTIKEUT WI PIEUPSIOS
+0x8D87	0xB703	#HANGUL SYLLABLE SSANGTIKEUT WI SIOS
+0x8D88	0xB704	#HANGUL SYLLABLE SSANGTIKEUT WI SSANGSIOS
+0x8D89	0xB706	#HANGUL SYLLABLE SSANGTIKEUT WI CIEUC
+0x8D8A	0xB707	#HANGUL SYLLABLE SSANGTIKEUT WI CHIEUCH
+0x8D8B	0xB708	#HANGUL SYLLABLE SSANGTIKEUT WI KHIEUKH
+0x8D8C	0xB709	#HANGUL SYLLABLE SSANGTIKEUT WI THIEUTH
+0x8D8D	0xB70A	#HANGUL SYLLABLE SSANGTIKEUT WI PHIEUPH
+0x8D8E	0xB70B	#HANGUL SYLLABLE SSANGTIKEUT WI HIEUH
+0x8D8F	0xB70C	#HANGUL SYLLABLE SSANGTIKEUT YU
+0x8D90	0xB70D	#HANGUL SYLLABLE SSANGTIKEUT YU KIYEOK
+0x8D91	0xB70E	#HANGUL SYLLABLE SSANGTIKEUT YU SSANGKIYEOK
+0x8D92	0xB70F	#HANGUL SYLLABLE SSANGTIKEUT YU KIYEOKSIOS
+0x8D93	0xB710	#HANGUL SYLLABLE SSANGTIKEUT YU NIEUN
+0x8D94	0xB711	#HANGUL SYLLABLE SSANGTIKEUT YU NIEUNCIEUC
+0x8D95	0xB712	#HANGUL SYLLABLE SSANGTIKEUT YU NIEUNHIEUH
+0x8D96	0xB713	#HANGUL SYLLABLE SSANGTIKEUT YU TIKEUT
+0x8D97	0xB714	#HANGUL SYLLABLE SSANGTIKEUT YU RIEUL
+0x8D98	0xB715	#HANGUL SYLLABLE SSANGTIKEUT YU RIEULKIYEOK
+0x8D99	0xB716	#HANGUL SYLLABLE SSANGTIKEUT YU RIEULMIEUM
+0x8D9A	0xB717	#HANGUL SYLLABLE SSANGTIKEUT YU RIEULPIEUP
+0x8D9B	0xB718	#HANGUL SYLLABLE SSANGTIKEUT YU RIEULSIOS
+0x8D9C	0xB719	#HANGUL SYLLABLE SSANGTIKEUT YU RIEULTHIEUTH
+0x8D9D	0xB71A	#HANGUL SYLLABLE SSANGTIKEUT YU RIEULPHIEUPH
+0x8D9E	0xB71B	#HANGUL SYLLABLE SSANGTIKEUT YU RIEULHIEUH
+0x8D9F	0xB71C	#HANGUL SYLLABLE SSANGTIKEUT YU MIEUM
+0x8DA0	0xB71D	#HANGUL SYLLABLE SSANGTIKEUT YU PIEUP
+0x8DA1	0xB71E	#HANGUL SYLLABLE SSANGTIKEUT YU PIEUPSIOS
+0x8DA2	0xB71F	#HANGUL SYLLABLE SSANGTIKEUT YU SIOS
+0x8DA3	0xB720	#HANGUL SYLLABLE SSANGTIKEUT YU SSANGSIOS
+0x8DA4	0xB721	#HANGUL SYLLABLE SSANGTIKEUT YU IEUNG
+0x8DA5	0xB722	#HANGUL SYLLABLE SSANGTIKEUT YU CIEUC
+0x8DA6	0xB723	#HANGUL SYLLABLE SSANGTIKEUT YU CHIEUCH
+0x8DA7	0xB724	#HANGUL SYLLABLE SSANGTIKEUT YU KHIEUKH
+0x8DA8	0xB725	#HANGUL SYLLABLE SSANGTIKEUT YU THIEUTH
+0x8DA9	0xB726	#HANGUL SYLLABLE SSANGTIKEUT YU PHIEUPH
+0x8DAA	0xB727	#HANGUL SYLLABLE SSANGTIKEUT YU HIEUH
+0x8DAB	0xB72A	#HANGUL SYLLABLE SSANGTIKEUT EU SSANGKIYEOK
+0x8DAC	0xB72B	#HANGUL SYLLABLE SSANGTIKEUT EU KIYEOKSIOS
+0x8DAD	0xB72D	#HANGUL SYLLABLE SSANGTIKEUT EU NIEUNCIEUC
+0x8DAE	0xB72E	#HANGUL SYLLABLE SSANGTIKEUT EU NIEUNHIEUH
+0x8DAF	0xB731	#HANGUL SYLLABLE SSANGTIKEUT EU RIEULKIYEOK
+0x8DB0	0xB732	#HANGUL SYLLABLE SSANGTIKEUT EU RIEULMIEUM
+0x8DB1	0xB733	#HANGUL SYLLABLE SSANGTIKEUT EU RIEULPIEUP
+0x8DB2	0xB734	#HANGUL SYLLABLE SSANGTIKEUT EU RIEULSIOS
+0x8DB3	0xB735	#HANGUL SYLLABLE SSANGTIKEUT EU RIEULTHIEUTH
+0x8DB4	0xB736	#HANGUL SYLLABLE SSANGTIKEUT EU RIEULPHIEUPH
+0x8DB5	0xB737	#HANGUL SYLLABLE SSANGTIKEUT EU RIEULHIEUH
+0x8DB6	0xB73A	#HANGUL SYLLABLE SSANGTIKEUT EU PIEUPSIOS
+0x8DB7	0xB73C	#HANGUL SYLLABLE SSANGTIKEUT EU SSANGSIOS
+0x8DB8	0xB73D	#HANGUL SYLLABLE SSANGTIKEUT EU IEUNG
+0x8DB9	0xB73E	#HANGUL SYLLABLE SSANGTIKEUT EU CIEUC
+0x8DBA	0xB73F	#HANGUL SYLLABLE SSANGTIKEUT EU CHIEUCH
+0x8DBB	0xB740	#HANGUL SYLLABLE SSANGTIKEUT EU KHIEUKH
+0x8DBC	0xB741	#HANGUL SYLLABLE SSANGTIKEUT EU THIEUTH
+0x8DBD	0xB742	#HANGUL SYLLABLE SSANGTIKEUT EU PHIEUPH
+0x8DBE	0xB743	#HANGUL SYLLABLE SSANGTIKEUT EU HIEUH
+0x8DBF	0xB745	#HANGUL SYLLABLE SSANGTIKEUT YI KIYEOK
+0x8DC0	0xB746	#HANGUL SYLLABLE SSANGTIKEUT YI SSANGKIYEOK
+0x8DC1	0xB747	#HANGUL SYLLABLE SSANGTIKEUT YI KIYEOKSIOS
+0x8DC2	0xB749	#HANGUL SYLLABLE SSANGTIKEUT YI NIEUNCIEUC
+0x8DC3	0xB74A	#HANGUL SYLLABLE SSANGTIKEUT YI NIEUNHIEUH
+0x8DC4	0xB74B	#HANGUL SYLLABLE SSANGTIKEUT YI TIKEUT
+0x8DC5	0xB74D	#HANGUL SYLLABLE SSANGTIKEUT YI RIEULKIYEOK
+0x8DC6	0xB74E	#HANGUL SYLLABLE SSANGTIKEUT YI RIEULMIEUM
+0x8DC7	0xB74F	#HANGUL SYLLABLE SSANGTIKEUT YI RIEULPIEUP
+0x8DC8	0xB750	#HANGUL SYLLABLE SSANGTIKEUT YI RIEULSIOS
+0x8DC9	0xB751	#HANGUL SYLLABLE SSANGTIKEUT YI RIEULTHIEUTH
+0x8DCA	0xB752	#HANGUL SYLLABLE SSANGTIKEUT YI RIEULPHIEUPH
+0x8DCB	0xB753	#HANGUL SYLLABLE SSANGTIKEUT YI RIEULHIEUH
+0x8DCC	0xB756	#HANGUL SYLLABLE SSANGTIKEUT YI PIEUPSIOS
+0x8DCD	0xB757	#HANGUL SYLLABLE SSANGTIKEUT YI SIOS
+0x8DCE	0xB758	#HANGUL SYLLABLE SSANGTIKEUT YI SSANGSIOS
+0x8DCF	0xB759	#HANGUL SYLLABLE SSANGTIKEUT YI IEUNG
+0x8DD0	0xB75A	#HANGUL SYLLABLE SSANGTIKEUT YI CIEUC
+0x8DD1	0xB75B	#HANGUL SYLLABLE SSANGTIKEUT YI CHIEUCH
+0x8DD2	0xB75C	#HANGUL SYLLABLE SSANGTIKEUT YI KHIEUKH
+0x8DD3	0xB75D	#HANGUL SYLLABLE SSANGTIKEUT YI THIEUTH
+0x8DD4	0xB75E	#HANGUL SYLLABLE SSANGTIKEUT YI PHIEUPH
+0x8DD5	0xB75F	#HANGUL SYLLABLE SSANGTIKEUT YI HIEUH
+0x8DD6	0xB761	#HANGUL SYLLABLE SSANGTIKEUT I KIYEOK
+0x8DD7	0xB762	#HANGUL SYLLABLE SSANGTIKEUT I SSANGKIYEOK
+0x8DD8	0xB763	#HANGUL SYLLABLE SSANGTIKEUT I KIYEOKSIOS
+0x8DD9	0xB765	#HANGUL SYLLABLE SSANGTIKEUT I NIEUNCIEUC
+0x8DDA	0xB766	#HANGUL SYLLABLE SSANGTIKEUT I NIEUNHIEUH
+0x8DDB	0xB767	#HANGUL SYLLABLE SSANGTIKEUT I TIKEUT
+0x8DDC	0xB769	#HANGUL SYLLABLE SSANGTIKEUT I RIEULKIYEOK
+0x8DDD	0xB76A	#HANGUL SYLLABLE SSANGTIKEUT I RIEULMIEUM
+0x8DDE	0xB76B	#HANGUL SYLLABLE SSANGTIKEUT I RIEULPIEUP
+0x8DDF	0xB76C	#HANGUL SYLLABLE SSANGTIKEUT I RIEULSIOS
+0x8DE0	0xB76D	#HANGUL SYLLABLE SSANGTIKEUT I RIEULTHIEUTH
+0x8DE1	0xB76E	#HANGUL SYLLABLE SSANGTIKEUT I RIEULPHIEUPH
+0x8DE2	0xB76F	#HANGUL SYLLABLE SSANGTIKEUT I RIEULHIEUH
+0x8DE3	0xB772	#HANGUL SYLLABLE SSANGTIKEUT I PIEUPSIOS
+0x8DE4	0xB774	#HANGUL SYLLABLE SSANGTIKEUT I SSANGSIOS
+0x8DE5	0xB776	#HANGUL SYLLABLE SSANGTIKEUT I CIEUC
+0x8DE6	0xB777	#HANGUL SYLLABLE SSANGTIKEUT I CHIEUCH
+0x8DE7	0xB778	#HANGUL SYLLABLE SSANGTIKEUT I KHIEUKH
+0x8DE8	0xB779	#HANGUL SYLLABLE SSANGTIKEUT I THIEUTH
+0x8DE9	0xB77A	#HANGUL SYLLABLE SSANGTIKEUT I PHIEUPH
+0x8DEA	0xB77B	#HANGUL SYLLABLE SSANGTIKEUT I HIEUH
+0x8DEB	0xB77E	#HANGUL SYLLABLE RIEUL A SSANGKIYEOK
+0x8DEC	0xB77F	#HANGUL SYLLABLE RIEUL A KIYEOKSIOS
+0x8DED	0xB781	#HANGUL SYLLABLE RIEUL A NIEUNCIEUC
+0x8DEE	0xB782	#HANGUL SYLLABLE RIEUL A NIEUNHIEUH
+0x8DEF	0xB783	#HANGUL SYLLABLE RIEUL A TIKEUT
+0x8DF0	0xB785	#HANGUL SYLLABLE RIEUL A RIEULKIYEOK
+0x8DF1	0xB786	#HANGUL SYLLABLE RIEUL A RIEULMIEUM
+0x8DF2	0xB787	#HANGUL SYLLABLE RIEUL A RIEULPIEUP
+0x8DF3	0xB788	#HANGUL SYLLABLE RIEUL A RIEULSIOS
+0x8DF4	0xB789	#HANGUL SYLLABLE RIEUL A RIEULTHIEUTH
+0x8DF5	0xB78A	#HANGUL SYLLABLE RIEUL A RIEULPHIEUPH
+0x8DF6	0xB78B	#HANGUL SYLLABLE RIEUL A RIEULHIEUH
+0x8DF7	0xB78E	#HANGUL SYLLABLE RIEUL A PIEUPSIOS
+0x8DF8	0xB793	#HANGUL SYLLABLE RIEUL A CHIEUCH
+0x8DF9	0xB794	#HANGUL SYLLABLE RIEUL A KHIEUKH
+0x8DFA	0xB795	#HANGUL SYLLABLE RIEUL A THIEUTH
+0x8DFB	0xB79A	#HANGUL SYLLABLE RIEUL AE SSANGKIYEOK
+0x8DFC	0xB79B	#HANGUL SYLLABLE RIEUL AE KIYEOKSIOS
+0x8DFD	0xB79D	#HANGUL SYLLABLE RIEUL AE NIEUNCIEUC
+0x8DFE	0xB79E	#HANGUL SYLLABLE RIEUL AE NIEUNHIEUH
+0x8E41	0xB79F	#HANGUL SYLLABLE RIEUL AE TIKEUT
+0x8E42	0xB7A1	#HANGUL SYLLABLE RIEUL AE RIEULKIYEOK
+0x8E43	0xB7A2	#HANGUL SYLLABLE RIEUL AE RIEULMIEUM
+0x8E44	0xB7A3	#HANGUL SYLLABLE RIEUL AE RIEULPIEUP
+0x8E45	0xB7A4	#HANGUL SYLLABLE RIEUL AE RIEULSIOS
+0x8E46	0xB7A5	#HANGUL SYLLABLE RIEUL AE RIEULTHIEUTH
+0x8E47	0xB7A6	#HANGUL SYLLABLE RIEUL AE RIEULPHIEUPH
+0x8E48	0xB7A7	#HANGUL SYLLABLE RIEUL AE RIEULHIEUH
+0x8E49	0xB7AA	#HANGUL SYLLABLE RIEUL AE PIEUPSIOS
+0x8E4A	0xB7AE	#HANGUL SYLLABLE RIEUL AE CIEUC
+0x8E4B	0xB7AF	#HANGUL SYLLABLE RIEUL AE CHIEUCH
+0x8E4C	0xB7B0	#HANGUL SYLLABLE RIEUL AE KHIEUKH
+0x8E4D	0xB7B1	#HANGUL SYLLABLE RIEUL AE THIEUTH
+0x8E4E	0xB7B2	#HANGUL SYLLABLE RIEUL AE PHIEUPH
+0x8E4F	0xB7B3	#HANGUL SYLLABLE RIEUL AE HIEUH
+0x8E50	0xB7B6	#HANGUL SYLLABLE RIEUL YA SSANGKIYEOK
+0x8E51	0xB7B7	#HANGUL SYLLABLE RIEUL YA KIYEOKSIOS
+0x8E52	0xB7B9	#HANGUL SYLLABLE RIEUL YA NIEUNCIEUC
+0x8E53	0xB7BA	#HANGUL SYLLABLE RIEUL YA NIEUNHIEUH
+0x8E54	0xB7BB	#HANGUL SYLLABLE RIEUL YA TIKEUT
+0x8E55	0xB7BC	#HANGUL SYLLABLE RIEUL YA RIEUL
+0x8E56	0xB7BD	#HANGUL SYLLABLE RIEUL YA RIEULKIYEOK
+0x8E57	0xB7BE	#HANGUL SYLLABLE RIEUL YA RIEULMIEUM
+0x8E58	0xB7BF	#HANGUL SYLLABLE RIEUL YA RIEULPIEUP
+0x8E59	0xB7C0	#HANGUL SYLLABLE RIEUL YA RIEULSIOS
+0x8E5A	0xB7C1	#HANGUL SYLLABLE RIEUL YA RIEULTHIEUTH
+0x8E61	0xB7C2	#HANGUL SYLLABLE RIEUL YA RIEULPHIEUPH
+0x8E62	0xB7C3	#HANGUL SYLLABLE RIEUL YA RIEULHIEUH
+0x8E63	0xB7C4	#HANGUL SYLLABLE RIEUL YA MIEUM
+0x8E64	0xB7C5	#HANGUL SYLLABLE RIEUL YA PIEUP
+0x8E65	0xB7C6	#HANGUL SYLLABLE RIEUL YA PIEUPSIOS
+0x8E66	0xB7C8	#HANGUL SYLLABLE RIEUL YA SSANGSIOS
+0x8E67	0xB7CA	#HANGUL SYLLABLE RIEUL YA CIEUC
+0x8E68	0xB7CB	#HANGUL SYLLABLE RIEUL YA CHIEUCH
+0x8E69	0xB7CC	#HANGUL SYLLABLE RIEUL YA KHIEUKH
+0x8E6A	0xB7CD	#HANGUL SYLLABLE RIEUL YA THIEUTH
+0x8E6B	0xB7CE	#HANGUL SYLLABLE RIEUL YA PHIEUPH
+0x8E6C	0xB7CF	#HANGUL SYLLABLE RIEUL YA HIEUH
+0x8E6D	0xB7D0	#HANGUL SYLLABLE RIEUL YAE
+0x8E6E	0xB7D1	#HANGUL SYLLABLE RIEUL YAE KIYEOK
+0x8E6F	0xB7D2	#HANGUL SYLLABLE RIEUL YAE SSANGKIYEOK
+0x8E70	0xB7D3	#HANGUL SYLLABLE RIEUL YAE KIYEOKSIOS
+0x8E71	0xB7D4	#HANGUL SYLLABLE RIEUL YAE NIEUN
+0x8E72	0xB7D5	#HANGUL SYLLABLE RIEUL YAE NIEUNCIEUC
+0x8E73	0xB7D6	#HANGUL SYLLABLE RIEUL YAE NIEUNHIEUH
+0x8E74	0xB7D7	#HANGUL SYLLABLE RIEUL YAE TIKEUT
+0x8E75	0xB7D8	#HANGUL SYLLABLE RIEUL YAE RIEUL
+0x8E76	0xB7D9	#HANGUL SYLLABLE RIEUL YAE RIEULKIYEOK
+0x8E77	0xB7DA	#HANGUL SYLLABLE RIEUL YAE RIEULMIEUM
+0x8E78	0xB7DB	#HANGUL SYLLABLE RIEUL YAE RIEULPIEUP
+0x8E79	0xB7DC	#HANGUL SYLLABLE RIEUL YAE RIEULSIOS
+0x8E7A	0xB7DD	#HANGUL SYLLABLE RIEUL YAE RIEULTHIEUTH
+0x8E81	0xB7DE	#HANGUL SYLLABLE RIEUL YAE RIEULPHIEUPH
+0x8E82	0xB7DF	#HANGUL SYLLABLE RIEUL YAE RIEULHIEUH
+0x8E83	0xB7E0	#HANGUL SYLLABLE RIEUL YAE MIEUM
+0x8E84	0xB7E1	#HANGUL SYLLABLE RIEUL YAE PIEUP
+0x8E85	0xB7E2	#HANGUL SYLLABLE RIEUL YAE PIEUPSIOS
+0x8E86	0xB7E3	#HANGUL SYLLABLE RIEUL YAE SIOS
+0x8E87	0xB7E4	#HANGUL SYLLABLE RIEUL YAE SSANGSIOS
+0x8E88	0xB7E5	#HANGUL SYLLABLE RIEUL YAE IEUNG
+0x8E89	0xB7E6	#HANGUL SYLLABLE RIEUL YAE CIEUC
+0x8E8A	0xB7E7	#HANGUL SYLLABLE RIEUL YAE CHIEUCH
+0x8E8B	0xB7E8	#HANGUL SYLLABLE RIEUL YAE KHIEUKH
+0x8E8C	0xB7E9	#HANGUL SYLLABLE RIEUL YAE THIEUTH
+0x8E8D	0xB7EA	#HANGUL SYLLABLE RIEUL YAE PHIEUPH
+0x8E8E	0xB7EB	#HANGUL SYLLABLE RIEUL YAE HIEUH
+0x8E8F	0xB7EE	#HANGUL SYLLABLE RIEUL EO SSANGKIYEOK
+0x8E90	0xB7EF	#HANGUL SYLLABLE RIEUL EO KIYEOKSIOS
+0x8E91	0xB7F1	#HANGUL SYLLABLE RIEUL EO NIEUNCIEUC
+0x8E92	0xB7F2	#HANGUL SYLLABLE RIEUL EO NIEUNHIEUH
+0x8E93	0xB7F3	#HANGUL SYLLABLE RIEUL EO TIKEUT
+0x8E94	0xB7F5	#HANGUL SYLLABLE RIEUL EO RIEULKIYEOK
+0x8E95	0xB7F6	#HANGUL SYLLABLE RIEUL EO RIEULMIEUM
+0x8E96	0xB7F7	#HANGUL SYLLABLE RIEUL EO RIEULPIEUP
+0x8E97	0xB7F8	#HANGUL SYLLABLE RIEUL EO RIEULSIOS
+0x8E98	0xB7F9	#HANGUL SYLLABLE RIEUL EO RIEULTHIEUTH
+0x8E99	0xB7FA	#HANGUL SYLLABLE RIEUL EO RIEULPHIEUPH
+0x8E9A	0xB7FB	#HANGUL SYLLABLE RIEUL EO RIEULHIEUH
+0x8E9B	0xB7FE	#HANGUL SYLLABLE RIEUL EO PIEUPSIOS
+0x8E9C	0xB802	#HANGUL SYLLABLE RIEUL EO CIEUC
+0x8E9D	0xB803	#HANGUL SYLLABLE RIEUL EO CHIEUCH
+0x8E9E	0xB804	#HANGUL SYLLABLE RIEUL EO KHIEUKH
+0x8E9F	0xB805	#HANGUL SYLLABLE RIEUL EO THIEUTH
+0x8EA0	0xB806	#HANGUL SYLLABLE RIEUL EO PHIEUPH
+0x8EA1	0xB80A	#HANGUL SYLLABLE RIEUL E SSANGKIYEOK
+0x8EA2	0xB80B	#HANGUL SYLLABLE RIEUL E KIYEOKSIOS
+0x8EA3	0xB80D	#HANGUL SYLLABLE RIEUL E NIEUNCIEUC
+0x8EA4	0xB80E	#HANGUL SYLLABLE RIEUL E NIEUNHIEUH
+0x8EA5	0xB80F	#HANGUL SYLLABLE RIEUL E TIKEUT
+0x8EA6	0xB811	#HANGUL SYLLABLE RIEUL E RIEULKIYEOK
+0x8EA7	0xB812	#HANGUL SYLLABLE RIEUL E RIEULMIEUM
+0x8EA8	0xB813	#HANGUL SYLLABLE RIEUL E RIEULPIEUP
+0x8EA9	0xB814	#HANGUL SYLLABLE RIEUL E RIEULSIOS
+0x8EAA	0xB815	#HANGUL SYLLABLE RIEUL E RIEULTHIEUTH
+0x8EAB	0xB816	#HANGUL SYLLABLE RIEUL E RIEULPHIEUPH
+0x8EAC	0xB817	#HANGUL SYLLABLE RIEUL E RIEULHIEUH
+0x8EAD	0xB81A	#HANGUL SYLLABLE RIEUL E PIEUPSIOS
+0x8EAE	0xB81C	#HANGUL SYLLABLE RIEUL E SSANGSIOS
+0x8EAF	0xB81E	#HANGUL SYLLABLE RIEUL E CIEUC
+0x8EB0	0xB81F	#HANGUL SYLLABLE RIEUL E CHIEUCH
+0x8EB1	0xB820	#HANGUL SYLLABLE RIEUL E KHIEUKH
+0x8EB2	0xB821	#HANGUL SYLLABLE RIEUL E THIEUTH
+0x8EB3	0xB822	#HANGUL SYLLABLE RIEUL E PHIEUPH
+0x8EB4	0xB823	#HANGUL SYLLABLE RIEUL E HIEUH
+0x8EB5	0xB826	#HANGUL SYLLABLE RIEUL YEO SSANGKIYEOK
+0x8EB6	0xB827	#HANGUL SYLLABLE RIEUL YEO KIYEOKSIOS
+0x8EB7	0xB829	#HANGUL SYLLABLE RIEUL YEO NIEUNCIEUC
+0x8EB8	0xB82A	#HANGUL SYLLABLE RIEUL YEO NIEUNHIEUH
+0x8EB9	0xB82B	#HANGUL SYLLABLE RIEUL YEO TIKEUT
+0x8EBA	0xB82D	#HANGUL SYLLABLE RIEUL YEO RIEULKIYEOK
+0x8EBB	0xB82E	#HANGUL SYLLABLE RIEUL YEO RIEULMIEUM
+0x8EBC	0xB82F	#HANGUL SYLLABLE RIEUL YEO RIEULPIEUP
+0x8EBD	0xB830	#HANGUL SYLLABLE RIEUL YEO RIEULSIOS
+0x8EBE	0xB831	#HANGUL SYLLABLE RIEUL YEO RIEULTHIEUTH
+0x8EBF	0xB832	#HANGUL SYLLABLE RIEUL YEO RIEULPHIEUPH
+0x8EC0	0xB833	#HANGUL SYLLABLE RIEUL YEO RIEULHIEUH
+0x8EC1	0xB836	#HANGUL SYLLABLE RIEUL YEO PIEUPSIOS
+0x8EC2	0xB83A	#HANGUL SYLLABLE RIEUL YEO CIEUC
+0x8EC3	0xB83B	#HANGUL SYLLABLE RIEUL YEO CHIEUCH
+0x8EC4	0xB83C	#HANGUL SYLLABLE RIEUL YEO KHIEUKH
+0x8EC5	0xB83D	#HANGUL SYLLABLE RIEUL YEO THIEUTH
+0x8EC6	0xB83E	#HANGUL SYLLABLE RIEUL YEO PHIEUPH
+0x8EC7	0xB83F	#HANGUL SYLLABLE RIEUL YEO HIEUH
+0x8EC8	0xB841	#HANGUL SYLLABLE RIEUL YE KIYEOK
+0x8EC9	0xB842	#HANGUL SYLLABLE RIEUL YE SSANGKIYEOK
+0x8ECA	0xB843	#HANGUL SYLLABLE RIEUL YE KIYEOKSIOS
+0x8ECB	0xB845	#HANGUL SYLLABLE RIEUL YE NIEUNCIEUC
+0x8ECC	0xB846	#HANGUL SYLLABLE RIEUL YE NIEUNHIEUH
+0x8ECD	0xB847	#HANGUL SYLLABLE RIEUL YE TIKEUT
+0x8ECE	0xB848	#HANGUL SYLLABLE RIEUL YE RIEUL
+0x8ECF	0xB849	#HANGUL SYLLABLE RIEUL YE RIEULKIYEOK
+0x8ED0	0xB84A	#HANGUL SYLLABLE RIEUL YE RIEULMIEUM
+0x8ED1	0xB84B	#HANGUL SYLLABLE RIEUL YE RIEULPIEUP
+0x8ED2	0xB84C	#HANGUL SYLLABLE RIEUL YE RIEULSIOS
+0x8ED3	0xB84D	#HANGUL SYLLABLE RIEUL YE RIEULTHIEUTH
+0x8ED4	0xB84E	#HANGUL SYLLABLE RIEUL YE RIEULPHIEUPH
+0x8ED5	0xB84F	#HANGUL SYLLABLE RIEUL YE RIEULHIEUH
+0x8ED6	0xB850	#HANGUL SYLLABLE RIEUL YE MIEUM
+0x8ED7	0xB852	#HANGUL SYLLABLE RIEUL YE PIEUPSIOS
+0x8ED8	0xB854	#HANGUL SYLLABLE RIEUL YE SSANGSIOS
+0x8ED9	0xB855	#HANGUL SYLLABLE RIEUL YE IEUNG
+0x8EDA	0xB856	#HANGUL SYLLABLE RIEUL YE CIEUC
+0x8EDB	0xB857	#HANGUL SYLLABLE RIEUL YE CHIEUCH
+0x8EDC	0xB858	#HANGUL SYLLABLE RIEUL YE KHIEUKH
+0x8EDD	0xB859	#HANGUL SYLLABLE RIEUL YE THIEUTH
+0x8EDE	0xB85A	#HANGUL SYLLABLE RIEUL YE PHIEUPH
+0x8EDF	0xB85B	#HANGUL SYLLABLE RIEUL YE HIEUH
+0x8EE0	0xB85E	#HANGUL SYLLABLE RIEUL O SSANGKIYEOK
+0x8EE1	0xB85F	#HANGUL SYLLABLE RIEUL O KIYEOKSIOS
+0x8EE2	0xB861	#HANGUL SYLLABLE RIEUL O NIEUNCIEUC
+0x8EE3	0xB862	#HANGUL SYLLABLE RIEUL O NIEUNHIEUH
+0x8EE4	0xB863	#HANGUL SYLLABLE RIEUL O TIKEUT
+0x8EE5	0xB865	#HANGUL SYLLABLE RIEUL O RIEULKIYEOK
+0x8EE6	0xB866	#HANGUL SYLLABLE RIEUL O RIEULMIEUM
+0x8EE7	0xB867	#HANGUL SYLLABLE RIEUL O RIEULPIEUP
+0x8EE8	0xB868	#HANGUL SYLLABLE RIEUL O RIEULSIOS
+0x8EE9	0xB869	#HANGUL SYLLABLE RIEUL O RIEULTHIEUTH
+0x8EEA	0xB86A	#HANGUL SYLLABLE RIEUL O RIEULPHIEUPH
+0x8EEB	0xB86B	#HANGUL SYLLABLE RIEUL O RIEULHIEUH
+0x8EEC	0xB86E	#HANGUL SYLLABLE RIEUL O PIEUPSIOS
+0x8EED	0xB870	#HANGUL SYLLABLE RIEUL O SSANGSIOS
+0x8EEE	0xB872	#HANGUL SYLLABLE RIEUL O CIEUC
+0x8EEF	0xB873	#HANGUL SYLLABLE RIEUL O CHIEUCH
+0x8EF0	0xB874	#HANGUL SYLLABLE RIEUL O KHIEUKH
+0x8EF1	0xB875	#HANGUL SYLLABLE RIEUL O THIEUTH
+0x8EF2	0xB876	#HANGUL SYLLABLE RIEUL O PHIEUPH
+0x8EF3	0xB877	#HANGUL SYLLABLE RIEUL O HIEUH
+0x8EF4	0xB879	#HANGUL SYLLABLE RIEUL WA KIYEOK
+0x8EF5	0xB87A	#HANGUL SYLLABLE RIEUL WA SSANGKIYEOK
+0x8EF6	0xB87B	#HANGUL SYLLABLE RIEUL WA KIYEOKSIOS
+0x8EF7	0xB87D	#HANGUL SYLLABLE RIEUL WA NIEUNCIEUC
+0x8EF8	0xB87E	#HANGUL SYLLABLE RIEUL WA NIEUNHIEUH
+0x8EF9	0xB87F	#HANGUL SYLLABLE RIEUL WA TIKEUT
+0x8EFA	0xB880	#HANGUL SYLLABLE RIEUL WA RIEUL
+0x8EFB	0xB881	#HANGUL SYLLABLE RIEUL WA RIEULKIYEOK
+0x8EFC	0xB882	#HANGUL SYLLABLE RIEUL WA RIEULMIEUM
+0x8EFD	0xB883	#HANGUL SYLLABLE RIEUL WA RIEULPIEUP
+0x8EFE	0xB884	#HANGUL SYLLABLE RIEUL WA RIEULSIOS
+0x8F41	0xB885	#HANGUL SYLLABLE RIEUL WA RIEULTHIEUTH
+0x8F42	0xB886	#HANGUL SYLLABLE RIEUL WA RIEULPHIEUPH
+0x8F43	0xB887	#HANGUL SYLLABLE RIEUL WA RIEULHIEUH
+0x8F44	0xB888	#HANGUL SYLLABLE RIEUL WA MIEUM
+0x8F45	0xB889	#HANGUL SYLLABLE RIEUL WA PIEUP
+0x8F46	0xB88A	#HANGUL SYLLABLE RIEUL WA PIEUPSIOS
+0x8F47	0xB88B	#HANGUL SYLLABLE RIEUL WA SIOS
+0x8F48	0xB88C	#HANGUL SYLLABLE RIEUL WA SSANGSIOS
+0x8F49	0xB88E	#HANGUL SYLLABLE RIEUL WA CIEUC
+0x8F4A	0xB88F	#HANGUL SYLLABLE RIEUL WA CHIEUCH
+0x8F4B	0xB890	#HANGUL SYLLABLE RIEUL WA KHIEUKH
+0x8F4C	0xB891	#HANGUL SYLLABLE RIEUL WA THIEUTH
+0x8F4D	0xB892	#HANGUL SYLLABLE RIEUL WA PHIEUPH
+0x8F4E	0xB893	#HANGUL SYLLABLE RIEUL WA HIEUH
+0x8F4F	0xB894	#HANGUL SYLLABLE RIEUL WAE
+0x8F50	0xB895	#HANGUL SYLLABLE RIEUL WAE KIYEOK
+0x8F51	0xB896	#HANGUL SYLLABLE RIEUL WAE SSANGKIYEOK
+0x8F52	0xB897	#HANGUL SYLLABLE RIEUL WAE KIYEOKSIOS
+0x8F53	0xB898	#HANGUL SYLLABLE RIEUL WAE NIEUN
+0x8F54	0xB899	#HANGUL SYLLABLE RIEUL WAE NIEUNCIEUC
+0x8F55	0xB89A	#HANGUL SYLLABLE RIEUL WAE NIEUNHIEUH
+0x8F56	0xB89B	#HANGUL SYLLABLE RIEUL WAE TIKEUT
+0x8F57	0xB89C	#HANGUL SYLLABLE RIEUL WAE RIEUL
+0x8F58	0xB89D	#HANGUL SYLLABLE RIEUL WAE RIEULKIYEOK
+0x8F59	0xB89E	#HANGUL SYLLABLE RIEUL WAE RIEULMIEUM
+0x8F5A	0xB89F	#HANGUL SYLLABLE RIEUL WAE RIEULPIEUP
+0x8F61	0xB8A0	#HANGUL SYLLABLE RIEUL WAE RIEULSIOS
+0x8F62	0xB8A1	#HANGUL SYLLABLE RIEUL WAE RIEULTHIEUTH
+0x8F63	0xB8A2	#HANGUL SYLLABLE RIEUL WAE RIEULPHIEUPH
+0x8F64	0xB8A3	#HANGUL SYLLABLE RIEUL WAE RIEULHIEUH
+0x8F65	0xB8A4	#HANGUL SYLLABLE RIEUL WAE MIEUM
+0x8F66	0xB8A5	#HANGUL SYLLABLE RIEUL WAE PIEUP
+0x8F67	0xB8A6	#HANGUL SYLLABLE RIEUL WAE PIEUPSIOS
+0x8F68	0xB8A7	#HANGUL SYLLABLE RIEUL WAE SIOS
+0x8F69	0xB8A9	#HANGUL SYLLABLE RIEUL WAE IEUNG
+0x8F6A	0xB8AA	#HANGUL SYLLABLE RIEUL WAE CIEUC
+0x8F6B	0xB8AB	#HANGUL SYLLABLE RIEUL WAE CHIEUCH
+0x8F6C	0xB8AC	#HANGUL SYLLABLE RIEUL WAE KHIEUKH
+0x8F6D	0xB8AD	#HANGUL SYLLABLE RIEUL WAE THIEUTH
+0x8F6E	0xB8AE	#HANGUL SYLLABLE RIEUL WAE PHIEUPH
+0x8F6F	0xB8AF	#HANGUL SYLLABLE RIEUL WAE HIEUH
+0x8F70	0xB8B1	#HANGUL SYLLABLE RIEUL OE KIYEOK
+0x8F71	0xB8B2	#HANGUL SYLLABLE RIEUL OE SSANGKIYEOK
+0x8F72	0xB8B3	#HANGUL SYLLABLE RIEUL OE KIYEOKSIOS
+0x8F73	0xB8B5	#HANGUL SYLLABLE RIEUL OE NIEUNCIEUC
+0x8F74	0xB8B6	#HANGUL SYLLABLE RIEUL OE NIEUNHIEUH
+0x8F75	0xB8B7	#HANGUL SYLLABLE RIEUL OE TIKEUT
+0x8F76	0xB8B9	#HANGUL SYLLABLE RIEUL OE RIEULKIYEOK
+0x8F77	0xB8BA	#HANGUL SYLLABLE RIEUL OE RIEULMIEUM
+0x8F78	0xB8BB	#HANGUL SYLLABLE RIEUL OE RIEULPIEUP
+0x8F79	0xB8BC	#HANGUL SYLLABLE RIEUL OE RIEULSIOS
+0x8F7A	0xB8BD	#HANGUL SYLLABLE RIEUL OE RIEULTHIEUTH
+0x8F81	0xB8BE	#HANGUL SYLLABLE RIEUL OE RIEULPHIEUPH
+0x8F82	0xB8BF	#HANGUL SYLLABLE RIEUL OE RIEULHIEUH
+0x8F83	0xB8C2	#HANGUL SYLLABLE RIEUL OE PIEUPSIOS
+0x8F84	0xB8C4	#HANGUL SYLLABLE RIEUL OE SSANGSIOS
+0x8F85	0xB8C6	#HANGUL SYLLABLE RIEUL OE CIEUC
+0x8F86	0xB8C7	#HANGUL SYLLABLE RIEUL OE CHIEUCH
+0x8F87	0xB8C8	#HANGUL SYLLABLE RIEUL OE KHIEUKH
+0x8F88	0xB8C9	#HANGUL SYLLABLE RIEUL OE THIEUTH
+0x8F89	0xB8CA	#HANGUL SYLLABLE RIEUL OE PHIEUPH
+0x8F8A	0xB8CB	#HANGUL SYLLABLE RIEUL OE HIEUH
+0x8F8B	0xB8CD	#HANGUL SYLLABLE RIEUL YO KIYEOK
+0x8F8C	0xB8CE	#HANGUL SYLLABLE RIEUL YO SSANGKIYEOK
+0x8F8D	0xB8CF	#HANGUL SYLLABLE RIEUL YO KIYEOKSIOS
+0x8F8E	0xB8D1	#HANGUL SYLLABLE RIEUL YO NIEUNCIEUC
+0x8F8F	0xB8D2	#HANGUL SYLLABLE RIEUL YO NIEUNHIEUH
+0x8F90	0xB8D3	#HANGUL SYLLABLE RIEUL YO TIKEUT
+0x8F91	0xB8D5	#HANGUL SYLLABLE RIEUL YO RIEULKIYEOK
+0x8F92	0xB8D6	#HANGUL SYLLABLE RIEUL YO RIEULMIEUM
+0x8F93	0xB8D7	#HANGUL SYLLABLE RIEUL YO RIEULPIEUP
+0x8F94	0xB8D8	#HANGUL SYLLABLE RIEUL YO RIEULSIOS
+0x8F95	0xB8D9	#HANGUL SYLLABLE RIEUL YO RIEULTHIEUTH
+0x8F96	0xB8DA	#HANGUL SYLLABLE RIEUL YO RIEULPHIEUPH
+0x8F97	0xB8DB	#HANGUL SYLLABLE RIEUL YO RIEULHIEUH
+0x8F98	0xB8DC	#HANGUL SYLLABLE RIEUL YO MIEUM
+0x8F99	0xB8DE	#HANGUL SYLLABLE RIEUL YO PIEUPSIOS
+0x8F9A	0xB8E0	#HANGUL SYLLABLE RIEUL YO SSANGSIOS
+0x8F9B	0xB8E2	#HANGUL SYLLABLE RIEUL YO CIEUC
+0x8F9C	0xB8E3	#HANGUL SYLLABLE RIEUL YO CHIEUCH
+0x8F9D	0xB8E4	#HANGUL SYLLABLE RIEUL YO KHIEUKH
+0x8F9E	0xB8E5	#HANGUL SYLLABLE RIEUL YO THIEUTH
+0x8F9F	0xB8E6	#HANGUL SYLLABLE RIEUL YO PHIEUPH
+0x8FA0	0xB8E7	#HANGUL SYLLABLE RIEUL YO HIEUH
+0x8FA1	0xB8EA	#HANGUL SYLLABLE RIEUL U SSANGKIYEOK
+0x8FA2	0xB8EB	#HANGUL SYLLABLE RIEUL U KIYEOKSIOS
+0x8FA3	0xB8ED	#HANGUL SYLLABLE RIEUL U NIEUNCIEUC
+0x8FA4	0xB8EE	#HANGUL SYLLABLE RIEUL U NIEUNHIEUH
+0x8FA5	0xB8EF	#HANGUL SYLLABLE RIEUL U TIKEUT
+0x8FA6	0xB8F1	#HANGUL SYLLABLE RIEUL U RIEULKIYEOK
+0x8FA7	0xB8F2	#HANGUL SYLLABLE RIEUL U RIEULMIEUM
+0x8FA8	0xB8F3	#HANGUL SYLLABLE RIEUL U RIEULPIEUP
+0x8FA9	0xB8F4	#HANGUL SYLLABLE RIEUL U RIEULSIOS
+0x8FAA	0xB8F5	#HANGUL SYLLABLE RIEUL U RIEULTHIEUTH
+0x8FAB	0xB8F6	#HANGUL SYLLABLE RIEUL U RIEULPHIEUPH
+0x8FAC	0xB8F7	#HANGUL SYLLABLE RIEUL U RIEULHIEUH
+0x8FAD	0xB8FA	#HANGUL SYLLABLE RIEUL U PIEUPSIOS
+0x8FAE	0xB8FC	#HANGUL SYLLABLE RIEUL U SSANGSIOS
+0x8FAF	0xB8FE	#HANGUL SYLLABLE RIEUL U CIEUC
+0x8FB0	0xB8FF	#HANGUL SYLLABLE RIEUL U CHIEUCH
+0x8FB1	0xB900	#HANGUL SYLLABLE RIEUL U KHIEUKH
+0x8FB2	0xB901	#HANGUL SYLLABLE RIEUL U THIEUTH
+0x8FB3	0xB902	#HANGUL SYLLABLE RIEUL U PHIEUPH
+0x8FB4	0xB903	#HANGUL SYLLABLE RIEUL U HIEUH
+0x8FB5	0xB905	#HANGUL SYLLABLE RIEUL WEO KIYEOK
+0x8FB6	0xB906	#HANGUL SYLLABLE RIEUL WEO SSANGKIYEOK
+0x8FB7	0xB907	#HANGUL SYLLABLE RIEUL WEO KIYEOKSIOS
+0x8FB8	0xB908	#HANGUL SYLLABLE RIEUL WEO NIEUN
+0x8FB9	0xB909	#HANGUL SYLLABLE RIEUL WEO NIEUNCIEUC
+0x8FBA	0xB90A	#HANGUL SYLLABLE RIEUL WEO NIEUNHIEUH
+0x8FBB	0xB90B	#HANGUL SYLLABLE RIEUL WEO TIKEUT
+0x8FBC	0xB90C	#HANGUL SYLLABLE RIEUL WEO RIEUL
+0x8FBD	0xB90D	#HANGUL SYLLABLE RIEUL WEO RIEULKIYEOK
+0x8FBE	0xB90E	#HANGUL SYLLABLE RIEUL WEO RIEULMIEUM
+0x8FBF	0xB90F	#HANGUL SYLLABLE RIEUL WEO RIEULPIEUP
+0x8FC0	0xB910	#HANGUL SYLLABLE RIEUL WEO RIEULSIOS
+0x8FC1	0xB911	#HANGUL SYLLABLE RIEUL WEO RIEULTHIEUTH
+0x8FC2	0xB912	#HANGUL SYLLABLE RIEUL WEO RIEULPHIEUPH
+0x8FC3	0xB913	#HANGUL SYLLABLE RIEUL WEO RIEULHIEUH
+0x8FC4	0xB914	#HANGUL SYLLABLE RIEUL WEO MIEUM
+0x8FC5	0xB915	#HANGUL SYLLABLE RIEUL WEO PIEUP
+0x8FC6	0xB916	#HANGUL SYLLABLE RIEUL WEO PIEUPSIOS
+0x8FC7	0xB917	#HANGUL SYLLABLE RIEUL WEO SIOS
+0x8FC8	0xB919	#HANGUL SYLLABLE RIEUL WEO IEUNG
+0x8FC9	0xB91A	#HANGUL SYLLABLE RIEUL WEO CIEUC
+0x8FCA	0xB91B	#HANGUL SYLLABLE RIEUL WEO CHIEUCH
+0x8FCB	0xB91C	#HANGUL SYLLABLE RIEUL WEO KHIEUKH
+0x8FCC	0xB91D	#HANGUL SYLLABLE RIEUL WEO THIEUTH
+0x8FCD	0xB91E	#HANGUL SYLLABLE RIEUL WEO PHIEUPH
+0x8FCE	0xB91F	#HANGUL SYLLABLE RIEUL WEO HIEUH
+0x8FCF	0xB921	#HANGUL SYLLABLE RIEUL WE KIYEOK
+0x8FD0	0xB922	#HANGUL SYLLABLE RIEUL WE SSANGKIYEOK
+0x8FD1	0xB923	#HANGUL SYLLABLE RIEUL WE KIYEOKSIOS
+0x8FD2	0xB924	#HANGUL SYLLABLE RIEUL WE NIEUN
+0x8FD3	0xB925	#HANGUL SYLLABLE RIEUL WE NIEUNCIEUC
+0x8FD4	0xB926	#HANGUL SYLLABLE RIEUL WE NIEUNHIEUH
+0x8FD5	0xB927	#HANGUL SYLLABLE RIEUL WE TIKEUT
+0x8FD6	0xB928	#HANGUL SYLLABLE RIEUL WE RIEUL
+0x8FD7	0xB929	#HANGUL SYLLABLE RIEUL WE RIEULKIYEOK
+0x8FD8	0xB92A	#HANGUL SYLLABLE RIEUL WE RIEULMIEUM
+0x8FD9	0xB92B	#HANGUL SYLLABLE RIEUL WE RIEULPIEUP
+0x8FDA	0xB92C	#HANGUL SYLLABLE RIEUL WE RIEULSIOS
+0x8FDB	0xB92D	#HANGUL SYLLABLE RIEUL WE RIEULTHIEUTH
+0x8FDC	0xB92E	#HANGUL SYLLABLE RIEUL WE RIEULPHIEUPH
+0x8FDD	0xB92F	#HANGUL SYLLABLE RIEUL WE RIEULHIEUH
+0x8FDE	0xB930	#HANGUL SYLLABLE RIEUL WE MIEUM
+0x8FDF	0xB931	#HANGUL SYLLABLE RIEUL WE PIEUP
+0x8FE0	0xB932	#HANGUL SYLLABLE RIEUL WE PIEUPSIOS
+0x8FE1	0xB933	#HANGUL SYLLABLE RIEUL WE SIOS
+0x8FE2	0xB934	#HANGUL SYLLABLE RIEUL WE SSANGSIOS
+0x8FE3	0xB935	#HANGUL SYLLABLE RIEUL WE IEUNG
+0x8FE4	0xB936	#HANGUL SYLLABLE RIEUL WE CIEUC
+0x8FE5	0xB937	#HANGUL SYLLABLE RIEUL WE CHIEUCH
+0x8FE6	0xB938	#HANGUL SYLLABLE RIEUL WE KHIEUKH
+0x8FE7	0xB939	#HANGUL SYLLABLE RIEUL WE THIEUTH
+0x8FE8	0xB93A	#HANGUL SYLLABLE RIEUL WE PHIEUPH
+0x8FE9	0xB93B	#HANGUL SYLLABLE RIEUL WE HIEUH
+0x8FEA	0xB93E	#HANGUL SYLLABLE RIEUL WI SSANGKIYEOK
+0x8FEB	0xB93F	#HANGUL SYLLABLE RIEUL WI KIYEOKSIOS
+0x8FEC	0xB941	#HANGUL SYLLABLE RIEUL WI NIEUNCIEUC
+0x8FED	0xB942	#HANGUL SYLLABLE RIEUL WI NIEUNHIEUH
+0x8FEE	0xB943	#HANGUL SYLLABLE RIEUL WI TIKEUT
+0x8FEF	0xB945	#HANGUL SYLLABLE RIEUL WI RIEULKIYEOK
+0x8FF0	0xB946	#HANGUL SYLLABLE RIEUL WI RIEULMIEUM
+0x8FF1	0xB947	#HANGUL SYLLABLE RIEUL WI RIEULPIEUP
+0x8FF2	0xB948	#HANGUL SYLLABLE RIEUL WI RIEULSIOS
+0x8FF3	0xB949	#HANGUL SYLLABLE RIEUL WI RIEULTHIEUTH
+0x8FF4	0xB94A	#HANGUL SYLLABLE RIEUL WI RIEULPHIEUPH
+0x8FF5	0xB94B	#HANGUL SYLLABLE RIEUL WI RIEULHIEUH
+0x8FF6	0xB94D	#HANGUL SYLLABLE RIEUL WI PIEUP
+0x8FF7	0xB94E	#HANGUL SYLLABLE RIEUL WI PIEUPSIOS
+0x8FF8	0xB950	#HANGUL SYLLABLE RIEUL WI SSANGSIOS
+0x8FF9	0xB952	#HANGUL SYLLABLE RIEUL WI CIEUC
+0x8FFA	0xB953	#HANGUL SYLLABLE RIEUL WI CHIEUCH
+0x8FFB	0xB954	#HANGUL SYLLABLE RIEUL WI KHIEUKH
+0x8FFC	0xB955	#HANGUL SYLLABLE RIEUL WI THIEUTH
+0x8FFD	0xB956	#HANGUL SYLLABLE RIEUL WI PHIEUPH
+0x8FFE	0xB957	#HANGUL SYLLABLE RIEUL WI HIEUH
+0x9041	0xB95A	#HANGUL SYLLABLE RIEUL YU SSANGKIYEOK
+0x9042	0xB95B	#HANGUL SYLLABLE RIEUL YU KIYEOKSIOS
+0x9043	0xB95D	#HANGUL SYLLABLE RIEUL YU NIEUNCIEUC
+0x9044	0xB95E	#HANGUL SYLLABLE RIEUL YU NIEUNHIEUH
+0x9045	0xB95F	#HANGUL SYLLABLE RIEUL YU TIKEUT
+0x9046	0xB961	#HANGUL SYLLABLE RIEUL YU RIEULKIYEOK
+0x9047	0xB962	#HANGUL SYLLABLE RIEUL YU RIEULMIEUM
+0x9048	0xB963	#HANGUL SYLLABLE RIEUL YU RIEULPIEUP
+0x9049	0xB964	#HANGUL SYLLABLE RIEUL YU RIEULSIOS
+0x904A	0xB965	#HANGUL SYLLABLE RIEUL YU RIEULTHIEUTH
+0x904B	0xB966	#HANGUL SYLLABLE RIEUL YU RIEULPHIEUPH
+0x904C	0xB967	#HANGUL SYLLABLE RIEUL YU RIEULHIEUH
+0x904D	0xB96A	#HANGUL SYLLABLE RIEUL YU PIEUPSIOS
+0x904E	0xB96C	#HANGUL SYLLABLE RIEUL YU SSANGSIOS
+0x904F	0xB96E	#HANGUL SYLLABLE RIEUL YU CIEUC
+0x9050	0xB96F	#HANGUL SYLLABLE RIEUL YU CHIEUCH
+0x9051	0xB970	#HANGUL SYLLABLE RIEUL YU KHIEUKH
+0x9052	0xB971	#HANGUL SYLLABLE RIEUL YU THIEUTH
+0x9053	0xB972	#HANGUL SYLLABLE RIEUL YU PHIEUPH
+0x9054	0xB973	#HANGUL SYLLABLE RIEUL YU HIEUH
+0x9055	0xB976	#HANGUL SYLLABLE RIEUL EU SSANGKIYEOK
+0x9056	0xB977	#HANGUL SYLLABLE RIEUL EU KIYEOKSIOS
+0x9057	0xB979	#HANGUL SYLLABLE RIEUL EU NIEUNCIEUC
+0x9058	0xB97A	#HANGUL SYLLABLE RIEUL EU NIEUNHIEUH
+0x9059	0xB97B	#HANGUL SYLLABLE RIEUL EU TIKEUT
+0x905A	0xB97D	#HANGUL SYLLABLE RIEUL EU RIEULKIYEOK
+0x9061	0xB97E	#HANGUL SYLLABLE RIEUL EU RIEULMIEUM
+0x9062	0xB97F	#HANGUL SYLLABLE RIEUL EU RIEULPIEUP
+0x9063	0xB980	#HANGUL SYLLABLE RIEUL EU RIEULSIOS
+0x9064	0xB981	#HANGUL SYLLABLE RIEUL EU RIEULTHIEUTH
+0x9065	0xB982	#HANGUL SYLLABLE RIEUL EU RIEULPHIEUPH
+0x9066	0xB983	#HANGUL SYLLABLE RIEUL EU RIEULHIEUH
+0x9067	0xB986	#HANGUL SYLLABLE RIEUL EU PIEUPSIOS
+0x9068	0xB988	#HANGUL SYLLABLE RIEUL EU SSANGSIOS
+0x9069	0xB98B	#HANGUL SYLLABLE RIEUL EU CHIEUCH
+0x906A	0xB98C	#HANGUL SYLLABLE RIEUL EU KHIEUKH
+0x906B	0xB98F	#HANGUL SYLLABLE RIEUL EU HIEUH
+0x906C	0xB990	#HANGUL SYLLABLE RIEUL YI
+0x906D	0xB991	#HANGUL SYLLABLE RIEUL YI KIYEOK
+0x906E	0xB992	#HANGUL SYLLABLE RIEUL YI SSANGKIYEOK
+0x906F	0xB993	#HANGUL SYLLABLE RIEUL YI KIYEOKSIOS
+0x9070	0xB994	#HANGUL SYLLABLE RIEUL YI NIEUN
+0x9071	0xB995	#HANGUL SYLLABLE RIEUL YI NIEUNCIEUC
+0x9072	0xB996	#HANGUL SYLLABLE RIEUL YI NIEUNHIEUH
+0x9073	0xB997	#HANGUL SYLLABLE RIEUL YI TIKEUT
+0x9074	0xB998	#HANGUL SYLLABLE RIEUL YI RIEUL
+0x9075	0xB999	#HANGUL SYLLABLE RIEUL YI RIEULKIYEOK
+0x9076	0xB99A	#HANGUL SYLLABLE RIEUL YI RIEULMIEUM
+0x9077	0xB99B	#HANGUL SYLLABLE RIEUL YI RIEULPIEUP
+0x9078	0xB99C	#HANGUL SYLLABLE RIEUL YI RIEULSIOS
+0x9079	0xB99D	#HANGUL SYLLABLE RIEUL YI RIEULTHIEUTH
+0x907A	0xB99E	#HANGUL SYLLABLE RIEUL YI RIEULPHIEUPH
+0x9081	0xB99F	#HANGUL SYLLABLE RIEUL YI RIEULHIEUH
+0x9082	0xB9A0	#HANGUL SYLLABLE RIEUL YI MIEUM
+0x9083	0xB9A1	#HANGUL SYLLABLE RIEUL YI PIEUP
+0x9084	0xB9A2	#HANGUL SYLLABLE RIEUL YI PIEUPSIOS
+0x9085	0xB9A3	#HANGUL SYLLABLE RIEUL YI SIOS
+0x9086	0xB9A4	#HANGUL SYLLABLE RIEUL YI SSANGSIOS
+0x9087	0xB9A5	#HANGUL SYLLABLE RIEUL YI IEUNG
+0x9088	0xB9A6	#HANGUL SYLLABLE RIEUL YI CIEUC
+0x9089	0xB9A7	#HANGUL SYLLABLE RIEUL YI CHIEUCH
+0x908A	0xB9A8	#HANGUL SYLLABLE RIEUL YI KHIEUKH
+0x908B	0xB9A9	#HANGUL SYLLABLE RIEUL YI THIEUTH
+0x908C	0xB9AA	#HANGUL SYLLABLE RIEUL YI PHIEUPH
+0x908D	0xB9AB	#HANGUL SYLLABLE RIEUL YI HIEUH
+0x908E	0xB9AE	#HANGUL SYLLABLE RIEUL I SSANGKIYEOK
+0x908F	0xB9AF	#HANGUL SYLLABLE RIEUL I KIYEOKSIOS
+0x9090	0xB9B1	#HANGUL SYLLABLE RIEUL I NIEUNCIEUC
+0x9091	0xB9B2	#HANGUL SYLLABLE RIEUL I NIEUNHIEUH
+0x9092	0xB9B3	#HANGUL SYLLABLE RIEUL I TIKEUT
+0x9093	0xB9B5	#HANGUL SYLLABLE RIEUL I RIEULKIYEOK
+0x9094	0xB9B6	#HANGUL SYLLABLE RIEUL I RIEULMIEUM
+0x9095	0xB9B7	#HANGUL SYLLABLE RIEUL I RIEULPIEUP
+0x9096	0xB9B8	#HANGUL SYLLABLE RIEUL I RIEULSIOS
+0x9097	0xB9B9	#HANGUL SYLLABLE RIEUL I RIEULTHIEUTH
+0x9098	0xB9BA	#HANGUL SYLLABLE RIEUL I RIEULPHIEUPH
+0x9099	0xB9BB	#HANGUL SYLLABLE RIEUL I RIEULHIEUH
+0x909A	0xB9BE	#HANGUL SYLLABLE RIEUL I PIEUPSIOS
+0x909B	0xB9C0	#HANGUL SYLLABLE RIEUL I SSANGSIOS
+0x909C	0xB9C2	#HANGUL SYLLABLE RIEUL I CIEUC
+0x909D	0xB9C3	#HANGUL SYLLABLE RIEUL I CHIEUCH
+0x909E	0xB9C4	#HANGUL SYLLABLE RIEUL I KHIEUKH
+0x909F	0xB9C5	#HANGUL SYLLABLE RIEUL I THIEUTH
+0x90A0	0xB9C6	#HANGUL SYLLABLE RIEUL I PHIEUPH
+0x90A1	0xB9C7	#HANGUL SYLLABLE RIEUL I HIEUH
+0x90A2	0xB9CA	#HANGUL SYLLABLE MIEUM A SSANGKIYEOK
+0x90A3	0xB9CB	#HANGUL SYLLABLE MIEUM A KIYEOKSIOS
+0x90A4	0xB9CD	#HANGUL SYLLABLE MIEUM A NIEUNCIEUC
+0x90A5	0xB9D3	#HANGUL SYLLABLE MIEUM A RIEULPIEUP
+0x90A6	0xB9D4	#HANGUL SYLLABLE MIEUM A RIEULSIOS
+0x90A7	0xB9D5	#HANGUL SYLLABLE MIEUM A RIEULTHIEUTH
+0x90A8	0xB9D6	#HANGUL SYLLABLE MIEUM A RIEULPHIEUPH
+0x90A9	0xB9D7	#HANGUL SYLLABLE MIEUM A RIEULHIEUH
+0x90AA	0xB9DA	#HANGUL SYLLABLE MIEUM A PIEUPSIOS
+0x90AB	0xB9DC	#HANGUL SYLLABLE MIEUM A SSANGSIOS
+0x90AC	0xB9DF	#HANGUL SYLLABLE MIEUM A CHIEUCH
+0x90AD	0xB9E0	#HANGUL SYLLABLE MIEUM A KHIEUKH
+0x90AE	0xB9E2	#HANGUL SYLLABLE MIEUM A PHIEUPH
+0x90AF	0xB9E6	#HANGUL SYLLABLE MIEUM AE SSANGKIYEOK
+0x90B0	0xB9E7	#HANGUL SYLLABLE MIEUM AE KIYEOKSIOS
+0x90B1	0xB9E9	#HANGUL SYLLABLE MIEUM AE NIEUNCIEUC
+0x90B2	0xB9EA	#HANGUL SYLLABLE MIEUM AE NIEUNHIEUH
+0x90B3	0xB9EB	#HANGUL SYLLABLE MIEUM AE TIKEUT
+0x90B4	0xB9ED	#HANGUL SYLLABLE MIEUM AE RIEULKIYEOK
+0x90B5	0xB9EE	#HANGUL SYLLABLE MIEUM AE RIEULMIEUM
+0x90B6	0xB9EF	#HANGUL SYLLABLE MIEUM AE RIEULPIEUP
+0x90B7	0xB9F0	#HANGUL SYLLABLE MIEUM AE RIEULSIOS
+0x90B8	0xB9F1	#HANGUL SYLLABLE MIEUM AE RIEULTHIEUTH
+0x90B9	0xB9F2	#HANGUL SYLLABLE MIEUM AE RIEULPHIEUPH
+0x90BA	0xB9F3	#HANGUL SYLLABLE MIEUM AE RIEULHIEUH
+0x90BB	0xB9F6	#HANGUL SYLLABLE MIEUM AE PIEUPSIOS
+0x90BC	0xB9FB	#HANGUL SYLLABLE MIEUM AE CHIEUCH
+0x90BD	0xB9FC	#HANGUL SYLLABLE MIEUM AE KHIEUKH
+0x90BE	0xB9FD	#HANGUL SYLLABLE MIEUM AE THIEUTH
+0x90BF	0xB9FE	#HANGUL SYLLABLE MIEUM AE PHIEUPH
+0x90C0	0xB9FF	#HANGUL SYLLABLE MIEUM AE HIEUH
+0x90C1	0xBA02	#HANGUL SYLLABLE MIEUM YA SSANGKIYEOK
+0x90C2	0xBA03	#HANGUL SYLLABLE MIEUM YA KIYEOKSIOS
+0x90C3	0xBA04	#HANGUL SYLLABLE MIEUM YA NIEUN
+0x90C4	0xBA05	#HANGUL SYLLABLE MIEUM YA NIEUNCIEUC
+0x90C5	0xBA06	#HANGUL SYLLABLE MIEUM YA NIEUNHIEUH
+0x90C6	0xBA07	#HANGUL SYLLABLE MIEUM YA TIKEUT
+0x90C7	0xBA09	#HANGUL SYLLABLE MIEUM YA RIEULKIYEOK
+0x90C8	0xBA0A	#HANGUL SYLLABLE MIEUM YA RIEULMIEUM
+0x90C9	0xBA0B	#HANGUL SYLLABLE MIEUM YA RIEULPIEUP
+0x90CA	0xBA0C	#HANGUL SYLLABLE MIEUM YA RIEULSIOS
+0x90CB	0xBA0D	#HANGUL SYLLABLE MIEUM YA RIEULTHIEUTH
+0x90CC	0xBA0E	#HANGUL SYLLABLE MIEUM YA RIEULPHIEUPH
+0x90CD	0xBA0F	#HANGUL SYLLABLE MIEUM YA RIEULHIEUH
+0x90CE	0xBA10	#HANGUL SYLLABLE MIEUM YA MIEUM
+0x90CF	0xBA11	#HANGUL SYLLABLE MIEUM YA PIEUP
+0x90D0	0xBA12	#HANGUL SYLLABLE MIEUM YA PIEUPSIOS
+0x90D1	0xBA13	#HANGUL SYLLABLE MIEUM YA SIOS
+0x90D2	0xBA14	#HANGUL SYLLABLE MIEUM YA SSANGSIOS
+0x90D3	0xBA16	#HANGUL SYLLABLE MIEUM YA CIEUC
+0x90D4	0xBA17	#HANGUL SYLLABLE MIEUM YA CHIEUCH
+0x90D5	0xBA18	#HANGUL SYLLABLE MIEUM YA KHIEUKH
+0x90D6	0xBA19	#HANGUL SYLLABLE MIEUM YA THIEUTH
+0x90D7	0xBA1A	#HANGUL SYLLABLE MIEUM YA PHIEUPH
+0x90D8	0xBA1B	#HANGUL SYLLABLE MIEUM YA HIEUH
+0x90D9	0xBA1C	#HANGUL SYLLABLE MIEUM YAE
+0x90DA	0xBA1D	#HANGUL SYLLABLE MIEUM YAE KIYEOK
+0x90DB	0xBA1E	#HANGUL SYLLABLE MIEUM YAE SSANGKIYEOK
+0x90DC	0xBA1F	#HANGUL SYLLABLE MIEUM YAE KIYEOKSIOS
+0x90DD	0xBA20	#HANGUL SYLLABLE MIEUM YAE NIEUN
+0x90DE	0xBA21	#HANGUL SYLLABLE MIEUM YAE NIEUNCIEUC
+0x90DF	0xBA22	#HANGUL SYLLABLE MIEUM YAE NIEUNHIEUH
+0x90E0	0xBA23	#HANGUL SYLLABLE MIEUM YAE TIKEUT
+0x90E1	0xBA24	#HANGUL SYLLABLE MIEUM YAE RIEUL
+0x90E2	0xBA25	#HANGUL SYLLABLE MIEUM YAE RIEULKIYEOK
+0x90E3	0xBA26	#HANGUL SYLLABLE MIEUM YAE RIEULMIEUM
+0x90E4	0xBA27	#HANGUL SYLLABLE MIEUM YAE RIEULPIEUP
+0x90E5	0xBA28	#HANGUL SYLLABLE MIEUM YAE RIEULSIOS
+0x90E6	0xBA29	#HANGUL SYLLABLE MIEUM YAE RIEULTHIEUTH
+0x90E7	0xBA2A	#HANGUL SYLLABLE MIEUM YAE RIEULPHIEUPH
+0x90E8	0xBA2B	#HANGUL SYLLABLE MIEUM YAE RIEULHIEUH
+0x90E9	0xBA2C	#HANGUL SYLLABLE MIEUM YAE MIEUM
+0x90EA	0xBA2D	#HANGUL SYLLABLE MIEUM YAE PIEUP
+0x90EB	0xBA2E	#HANGUL SYLLABLE MIEUM YAE PIEUPSIOS
+0x90EC	0xBA2F	#HANGUL SYLLABLE MIEUM YAE SIOS
+0x90ED	0xBA30	#HANGUL SYLLABLE MIEUM YAE SSANGSIOS
+0x90EE	0xBA31	#HANGUL SYLLABLE MIEUM YAE IEUNG
+0x90EF	0xBA32	#HANGUL SYLLABLE MIEUM YAE CIEUC
+0x90F0	0xBA33	#HANGUL SYLLABLE MIEUM YAE CHIEUCH
+0x90F1	0xBA34	#HANGUL SYLLABLE MIEUM YAE KHIEUKH
+0x90F2	0xBA35	#HANGUL SYLLABLE MIEUM YAE THIEUTH
+0x90F3	0xBA36	#HANGUL SYLLABLE MIEUM YAE PHIEUPH
+0x90F4	0xBA37	#HANGUL SYLLABLE MIEUM YAE HIEUH
+0x90F5	0xBA3A	#HANGUL SYLLABLE MIEUM EO SSANGKIYEOK
+0x90F6	0xBA3B	#HANGUL SYLLABLE MIEUM EO KIYEOKSIOS
+0x90F7	0xBA3D	#HANGUL SYLLABLE MIEUM EO NIEUNCIEUC
+0x90F8	0xBA3E	#HANGUL SYLLABLE MIEUM EO NIEUNHIEUH
+0x90F9	0xBA3F	#HANGUL SYLLABLE MIEUM EO TIKEUT
+0x90FA	0xBA41	#HANGUL SYLLABLE MIEUM EO RIEULKIYEOK
+0x90FB	0xBA43	#HANGUL SYLLABLE MIEUM EO RIEULPIEUP
+0x90FC	0xBA44	#HANGUL SYLLABLE MIEUM EO RIEULSIOS
+0x90FD	0xBA45	#HANGUL SYLLABLE MIEUM EO RIEULTHIEUTH
+0x90FE	0xBA46	#HANGUL SYLLABLE MIEUM EO RIEULPHIEUPH
+0x9141	0xBA47	#HANGUL SYLLABLE MIEUM EO RIEULHIEUH
+0x9142	0xBA4A	#HANGUL SYLLABLE MIEUM EO PIEUPSIOS
+0x9143	0xBA4C	#HANGUL SYLLABLE MIEUM EO SSANGSIOS
+0x9144	0xBA4F	#HANGUL SYLLABLE MIEUM EO CHIEUCH
+0x9145	0xBA50	#HANGUL SYLLABLE MIEUM EO KHIEUKH
+0x9146	0xBA51	#HANGUL SYLLABLE MIEUM EO THIEUTH
+0x9147	0xBA52	#HANGUL SYLLABLE MIEUM EO PHIEUPH
+0x9148	0xBA56	#HANGUL SYLLABLE MIEUM E SSANGKIYEOK
+0x9149	0xBA57	#HANGUL SYLLABLE MIEUM E KIYEOKSIOS
+0x914A	0xBA59	#HANGUL SYLLABLE MIEUM E NIEUNCIEUC
+0x914B	0xBA5A	#HANGUL SYLLABLE MIEUM E NIEUNHIEUH
+0x914C	0xBA5B	#HANGUL SYLLABLE MIEUM E TIKEUT
+0x914D	0xBA5D	#HANGUL SYLLABLE MIEUM E RIEULKIYEOK
+0x914E	0xBA5E	#HANGUL SYLLABLE MIEUM E RIEULMIEUM
+0x914F	0xBA5F	#HANGUL SYLLABLE MIEUM E RIEULPIEUP
+0x9150	0xBA60	#HANGUL SYLLABLE MIEUM E RIEULSIOS
+0x9151	0xBA61	#HANGUL SYLLABLE MIEUM E RIEULTHIEUTH
+0x9152	0xBA62	#HANGUL SYLLABLE MIEUM E RIEULPHIEUPH
+0x9153	0xBA63	#HANGUL SYLLABLE MIEUM E RIEULHIEUH
+0x9154	0xBA66	#HANGUL SYLLABLE MIEUM E PIEUPSIOS
+0x9155	0xBA6A	#HANGUL SYLLABLE MIEUM E CIEUC
+0x9156	0xBA6B	#HANGUL SYLLABLE MIEUM E CHIEUCH
+0x9157	0xBA6C	#HANGUL SYLLABLE MIEUM E KHIEUKH
+0x9158	0xBA6D	#HANGUL SYLLABLE MIEUM E THIEUTH
+0x9159	0xBA6E	#HANGUL SYLLABLE MIEUM E PHIEUPH
+0x915A	0xBA6F	#HANGUL SYLLABLE MIEUM E HIEUH
+0x9161	0xBA72	#HANGUL SYLLABLE MIEUM YEO SSANGKIYEOK
+0x9162	0xBA73	#HANGUL SYLLABLE MIEUM YEO KIYEOKSIOS
+0x9163	0xBA75	#HANGUL SYLLABLE MIEUM YEO NIEUNCIEUC
+0x9164	0xBA76	#HANGUL SYLLABLE MIEUM YEO NIEUNHIEUH
+0x9165	0xBA77	#HANGUL SYLLABLE MIEUM YEO TIKEUT
+0x9166	0xBA79	#HANGUL SYLLABLE MIEUM YEO RIEULKIYEOK
+0x9167	0xBA7A	#HANGUL SYLLABLE MIEUM YEO RIEULMIEUM
+0x9168	0xBA7B	#HANGUL SYLLABLE MIEUM YEO RIEULPIEUP
+0x9169	0xBA7C	#HANGUL SYLLABLE MIEUM YEO RIEULSIOS
+0x916A	0xBA7D	#HANGUL SYLLABLE MIEUM YEO RIEULTHIEUTH
+0x916B	0xBA7E	#HANGUL SYLLABLE MIEUM YEO RIEULPHIEUPH
+0x916C	0xBA7F	#HANGUL SYLLABLE MIEUM YEO RIEULHIEUH
+0x916D	0xBA80	#HANGUL SYLLABLE MIEUM YEO MIEUM
+0x916E	0xBA81	#HANGUL SYLLABLE MIEUM YEO PIEUP
+0x916F	0xBA82	#HANGUL SYLLABLE MIEUM YEO PIEUPSIOS
+0x9170	0xBA86	#HANGUL SYLLABLE MIEUM YEO CIEUC
+0x9171	0xBA88	#HANGUL SYLLABLE MIEUM YEO KHIEUKH
+0x9172	0xBA89	#HANGUL SYLLABLE MIEUM YEO THIEUTH
+0x9173	0xBA8A	#HANGUL SYLLABLE MIEUM YEO PHIEUPH
+0x9174	0xBA8B	#HANGUL SYLLABLE MIEUM YEO HIEUH
+0x9175	0xBA8D	#HANGUL SYLLABLE MIEUM YE KIYEOK
+0x9176	0xBA8E	#HANGUL SYLLABLE MIEUM YE SSANGKIYEOK
+0x9177	0xBA8F	#HANGUL SYLLABLE MIEUM YE KIYEOKSIOS
+0x9178	0xBA90	#HANGUL SYLLABLE MIEUM YE NIEUN
+0x9179	0xBA91	#HANGUL SYLLABLE MIEUM YE NIEUNCIEUC
+0x917A	0xBA92	#HANGUL SYLLABLE MIEUM YE NIEUNHIEUH
+0x9181	0xBA93	#HANGUL SYLLABLE MIEUM YE TIKEUT
+0x9182	0xBA94	#HANGUL SYLLABLE MIEUM YE RIEUL
+0x9183	0xBA95	#HANGUL SYLLABLE MIEUM YE RIEULKIYEOK
+0x9184	0xBA96	#HANGUL SYLLABLE MIEUM YE RIEULMIEUM
+0x9185	0xBA97	#HANGUL SYLLABLE MIEUM YE RIEULPIEUP
+0x9186	0xBA98	#HANGUL SYLLABLE MIEUM YE RIEULSIOS
+0x9187	0xBA99	#HANGUL SYLLABLE MIEUM YE RIEULTHIEUTH
+0x9188	0xBA9A	#HANGUL SYLLABLE MIEUM YE RIEULPHIEUPH
+0x9189	0xBA9B	#HANGUL SYLLABLE MIEUM YE RIEULHIEUH
+0x918A	0xBA9C	#HANGUL SYLLABLE MIEUM YE MIEUM
+0x918B	0xBA9D	#HANGUL SYLLABLE MIEUM YE PIEUP
+0x918C	0xBA9E	#HANGUL SYLLABLE MIEUM YE PIEUPSIOS
+0x918D	0xBA9F	#HANGUL SYLLABLE MIEUM YE SIOS
+0x918E	0xBAA0	#HANGUL SYLLABLE MIEUM YE SSANGSIOS
+0x918F	0xBAA1	#HANGUL SYLLABLE MIEUM YE IEUNG
+0x9190	0xBAA2	#HANGUL SYLLABLE MIEUM YE CIEUC
+0x9191	0xBAA3	#HANGUL SYLLABLE MIEUM YE CHIEUCH
+0x9192	0xBAA4	#HANGUL SYLLABLE MIEUM YE KHIEUKH
+0x9193	0xBAA5	#HANGUL SYLLABLE MIEUM YE THIEUTH
+0x9194	0xBAA6	#HANGUL SYLLABLE MIEUM YE PHIEUPH
+0x9195	0xBAA7	#HANGUL SYLLABLE MIEUM YE HIEUH
+0x9196	0xBAAA	#HANGUL SYLLABLE MIEUM O SSANGKIYEOK
+0x9197	0xBAAD	#HANGUL SYLLABLE MIEUM O NIEUNCIEUC
+0x9198	0xBAAE	#HANGUL SYLLABLE MIEUM O NIEUNHIEUH
+0x9199	0xBAAF	#HANGUL SYLLABLE MIEUM O TIKEUT
+0x919A	0xBAB1	#HANGUL SYLLABLE MIEUM O RIEULKIYEOK
+0x919B	0xBAB3	#HANGUL SYLLABLE MIEUM O RIEULPIEUP
+0x919C	0xBAB4	#HANGUL SYLLABLE MIEUM O RIEULSIOS
+0x919D	0xBAB5	#HANGUL SYLLABLE MIEUM O RIEULTHIEUTH
+0x919E	0xBAB6	#HANGUL SYLLABLE MIEUM O RIEULPHIEUPH
+0x919F	0xBAB7	#HANGUL SYLLABLE MIEUM O RIEULHIEUH
+0x91A0	0xBABA	#HANGUL SYLLABLE MIEUM O PIEUPSIOS
+0x91A1	0xBABC	#HANGUL SYLLABLE MIEUM O SSANGSIOS
+0x91A2	0xBABE	#HANGUL SYLLABLE MIEUM O CIEUC
+0x91A3	0xBABF	#HANGUL SYLLABLE MIEUM O CHIEUCH
+0x91A4	0xBAC0	#HANGUL SYLLABLE MIEUM O KHIEUKH
+0x91A5	0xBAC1	#HANGUL SYLLABLE MIEUM O THIEUTH
+0x91A6	0xBAC2	#HANGUL SYLLABLE MIEUM O PHIEUPH
+0x91A7	0xBAC3	#HANGUL SYLLABLE MIEUM O HIEUH
+0x91A8	0xBAC5	#HANGUL SYLLABLE MIEUM WA KIYEOK
+0x91A9	0xBAC6	#HANGUL SYLLABLE MIEUM WA SSANGKIYEOK
+0x91AA	0xBAC7	#HANGUL SYLLABLE MIEUM WA KIYEOKSIOS
+0x91AB	0xBAC9	#HANGUL SYLLABLE MIEUM WA NIEUNCIEUC
+0x91AC	0xBACA	#HANGUL SYLLABLE MIEUM WA NIEUNHIEUH
+0x91AD	0xBACB	#HANGUL SYLLABLE MIEUM WA TIKEUT
+0x91AE	0xBACC	#HANGUL SYLLABLE MIEUM WA RIEUL
+0x91AF	0xBACD	#HANGUL SYLLABLE MIEUM WA RIEULKIYEOK
+0x91B0	0xBACE	#HANGUL SYLLABLE MIEUM WA RIEULMIEUM
+0x91B1	0xBACF	#HANGUL SYLLABLE MIEUM WA RIEULPIEUP
+0x91B2	0xBAD0	#HANGUL SYLLABLE MIEUM WA RIEULSIOS
+0x91B3	0xBAD1	#HANGUL SYLLABLE MIEUM WA RIEULTHIEUTH
+0x91B4	0xBAD2	#HANGUL SYLLABLE MIEUM WA RIEULPHIEUPH
+0x91B5	0xBAD3	#HANGUL SYLLABLE MIEUM WA RIEULHIEUH
+0x91B6	0xBAD4	#HANGUL SYLLABLE MIEUM WA MIEUM
+0x91B7	0xBAD5	#HANGUL SYLLABLE MIEUM WA PIEUP
+0x91B8	0xBAD6	#HANGUL SYLLABLE MIEUM WA PIEUPSIOS
+0x91B9	0xBAD7	#HANGUL SYLLABLE MIEUM WA SIOS
+0x91BA	0xBADA	#HANGUL SYLLABLE MIEUM WA CIEUC
+0x91BB	0xBADB	#HANGUL SYLLABLE MIEUM WA CHIEUCH
+0x91BC	0xBADC	#HANGUL SYLLABLE MIEUM WA KHIEUKH
+0x91BD	0xBADD	#HANGUL SYLLABLE MIEUM WA THIEUTH
+0x91BE	0xBADE	#HANGUL SYLLABLE MIEUM WA PHIEUPH
+0x91BF	0xBADF	#HANGUL SYLLABLE MIEUM WA HIEUH
+0x91C0	0xBAE0	#HANGUL SYLLABLE MIEUM WAE
+0x91C1	0xBAE1	#HANGUL SYLLABLE MIEUM WAE KIYEOK
+0x91C2	0xBAE2	#HANGUL SYLLABLE MIEUM WAE SSANGKIYEOK
+0x91C3	0xBAE3	#HANGUL SYLLABLE MIEUM WAE KIYEOKSIOS
+0x91C4	0xBAE4	#HANGUL SYLLABLE MIEUM WAE NIEUN
+0x91C5	0xBAE5	#HANGUL SYLLABLE MIEUM WAE NIEUNCIEUC
+0x91C6	0xBAE6	#HANGUL SYLLABLE MIEUM WAE NIEUNHIEUH
+0x91C7	0xBAE7	#HANGUL SYLLABLE MIEUM WAE TIKEUT
+0x91C8	0xBAE8	#HANGUL SYLLABLE MIEUM WAE RIEUL
+0x91C9	0xBAE9	#HANGUL SYLLABLE MIEUM WAE RIEULKIYEOK
+0x91CA	0xBAEA	#HANGUL SYLLABLE MIEUM WAE RIEULMIEUM
+0x91CB	0xBAEB	#HANGUL SYLLABLE MIEUM WAE RIEULPIEUP
+0x91CC	0xBAEC	#HANGUL SYLLABLE MIEUM WAE RIEULSIOS
+0x91CD	0xBAED	#HANGUL SYLLABLE MIEUM WAE RIEULTHIEUTH
+0x91CE	0xBAEE	#HANGUL SYLLABLE MIEUM WAE RIEULPHIEUPH
+0x91CF	0xBAEF	#HANGUL SYLLABLE MIEUM WAE RIEULHIEUH
+0x91D0	0xBAF0	#HANGUL SYLLABLE MIEUM WAE MIEUM
+0x91D1	0xBAF1	#HANGUL SYLLABLE MIEUM WAE PIEUP
+0x91D2	0xBAF2	#HANGUL SYLLABLE MIEUM WAE PIEUPSIOS
+0x91D3	0xBAF3	#HANGUL SYLLABLE MIEUM WAE SIOS
+0x91D4	0xBAF4	#HANGUL SYLLABLE MIEUM WAE SSANGSIOS
+0x91D5	0xBAF5	#HANGUL SYLLABLE MIEUM WAE IEUNG
+0x91D6	0xBAF6	#HANGUL SYLLABLE MIEUM WAE CIEUC
+0x91D7	0xBAF7	#HANGUL SYLLABLE MIEUM WAE CHIEUCH
+0x91D8	0xBAF8	#HANGUL SYLLABLE MIEUM WAE KHIEUKH
+0x91D9	0xBAF9	#HANGUL SYLLABLE MIEUM WAE THIEUTH
+0x91DA	0xBAFA	#HANGUL SYLLABLE MIEUM WAE PHIEUPH
+0x91DB	0xBAFB	#HANGUL SYLLABLE MIEUM WAE HIEUH
+0x91DC	0xBAFD	#HANGUL SYLLABLE MIEUM OE KIYEOK
+0x91DD	0xBAFE	#HANGUL SYLLABLE MIEUM OE SSANGKIYEOK
+0x91DE	0xBAFF	#HANGUL SYLLABLE MIEUM OE KIYEOKSIOS
+0x91DF	0xBB01	#HANGUL SYLLABLE MIEUM OE NIEUNCIEUC
+0x91E0	0xBB02	#HANGUL SYLLABLE MIEUM OE NIEUNHIEUH
+0x91E1	0xBB03	#HANGUL SYLLABLE MIEUM OE TIKEUT
+0x91E2	0xBB05	#HANGUL SYLLABLE MIEUM OE RIEULKIYEOK
+0x91E3	0xBB06	#HANGUL SYLLABLE MIEUM OE RIEULMIEUM
+0x91E4	0xBB07	#HANGUL SYLLABLE MIEUM OE RIEULPIEUP
+0x91E5	0xBB08	#HANGUL SYLLABLE MIEUM OE RIEULSIOS
+0x91E6	0xBB09	#HANGUL SYLLABLE MIEUM OE RIEULTHIEUTH
+0x91E7	0xBB0A	#HANGUL SYLLABLE MIEUM OE RIEULPHIEUPH
+0x91E8	0xBB0B	#HANGUL SYLLABLE MIEUM OE RIEULHIEUH
+0x91E9	0xBB0C	#HANGUL SYLLABLE MIEUM OE MIEUM
+0x91EA	0xBB0E	#HANGUL SYLLABLE MIEUM OE PIEUPSIOS
+0x91EB	0xBB10	#HANGUL SYLLABLE MIEUM OE SSANGSIOS
+0x91EC	0xBB12	#HANGUL SYLLABLE MIEUM OE CIEUC
+0x91ED	0xBB13	#HANGUL SYLLABLE MIEUM OE CHIEUCH
+0x91EE	0xBB14	#HANGUL SYLLABLE MIEUM OE KHIEUKH
+0x91EF	0xBB15	#HANGUL SYLLABLE MIEUM OE THIEUTH
+0x91F0	0xBB16	#HANGUL SYLLABLE MIEUM OE PHIEUPH
+0x91F1	0xBB17	#HANGUL SYLLABLE MIEUM OE HIEUH
+0x91F2	0xBB19	#HANGUL SYLLABLE MIEUM YO KIYEOK
+0x91F3	0xBB1A	#HANGUL SYLLABLE MIEUM YO SSANGKIYEOK
+0x91F4	0xBB1B	#HANGUL SYLLABLE MIEUM YO KIYEOKSIOS
+0x91F5	0xBB1D	#HANGUL SYLLABLE MIEUM YO NIEUNCIEUC
+0x91F6	0xBB1E	#HANGUL SYLLABLE MIEUM YO NIEUNHIEUH
+0x91F7	0xBB1F	#HANGUL SYLLABLE MIEUM YO TIKEUT
+0x91F8	0xBB21	#HANGUL SYLLABLE MIEUM YO RIEULKIYEOK
+0x91F9	0xBB22	#HANGUL SYLLABLE MIEUM YO RIEULMIEUM
+0x91FA	0xBB23	#HANGUL SYLLABLE MIEUM YO RIEULPIEUP
+0x91FB	0xBB24	#HANGUL SYLLABLE MIEUM YO RIEULSIOS
+0x91FC	0xBB25	#HANGUL SYLLABLE MIEUM YO RIEULTHIEUTH
+0x91FD	0xBB26	#HANGUL SYLLABLE MIEUM YO RIEULPHIEUPH
+0x91FE	0xBB27	#HANGUL SYLLABLE MIEUM YO RIEULHIEUH
+0x9241	0xBB28	#HANGUL SYLLABLE MIEUM YO MIEUM
+0x9242	0xBB2A	#HANGUL SYLLABLE MIEUM YO PIEUPSIOS
+0x9243	0xBB2C	#HANGUL SYLLABLE MIEUM YO SSANGSIOS
+0x9244	0xBB2D	#HANGUL SYLLABLE MIEUM YO IEUNG
+0x9245	0xBB2E	#HANGUL SYLLABLE MIEUM YO CIEUC
+0x9246	0xBB2F	#HANGUL SYLLABLE MIEUM YO CHIEUCH
+0x9247	0xBB30	#HANGUL SYLLABLE MIEUM YO KHIEUKH
+0x9248	0xBB31	#HANGUL SYLLABLE MIEUM YO THIEUTH
+0x9249	0xBB32	#HANGUL SYLLABLE MIEUM YO PHIEUPH
+0x924A	0xBB33	#HANGUL SYLLABLE MIEUM YO HIEUH
+0x924B	0xBB37	#HANGUL SYLLABLE MIEUM U KIYEOKSIOS
+0x924C	0xBB39	#HANGUL SYLLABLE MIEUM U NIEUNCIEUC
+0x924D	0xBB3A	#HANGUL SYLLABLE MIEUM U NIEUNHIEUH
+0x924E	0xBB3F	#HANGUL SYLLABLE MIEUM U RIEULPIEUP
+0x924F	0xBB40	#HANGUL SYLLABLE MIEUM U RIEULSIOS
+0x9250	0xBB41	#HANGUL SYLLABLE MIEUM U RIEULTHIEUTH
+0x9251	0xBB42	#HANGUL SYLLABLE MIEUM U RIEULPHIEUPH
+0x9252	0xBB43	#HANGUL SYLLABLE MIEUM U RIEULHIEUH
+0x9253	0xBB46	#HANGUL SYLLABLE MIEUM U PIEUPSIOS
+0x9254	0xBB48	#HANGUL SYLLABLE MIEUM U SSANGSIOS
+0x9255	0xBB4A	#HANGUL SYLLABLE MIEUM U CIEUC
+0x9256	0xBB4B	#HANGUL SYLLABLE MIEUM U CHIEUCH
+0x9257	0xBB4C	#HANGUL SYLLABLE MIEUM U KHIEUKH
+0x9258	0xBB4E	#HANGUL SYLLABLE MIEUM U PHIEUPH
+0x9259	0xBB51	#HANGUL SYLLABLE MIEUM WEO KIYEOK
+0x925A	0xBB52	#HANGUL SYLLABLE MIEUM WEO SSANGKIYEOK
+0x9261	0xBB53	#HANGUL SYLLABLE MIEUM WEO KIYEOKSIOS
+0x9262	0xBB55	#HANGUL SYLLABLE MIEUM WEO NIEUNCIEUC
+0x9263	0xBB56	#HANGUL SYLLABLE MIEUM WEO NIEUNHIEUH
+0x9264	0xBB57	#HANGUL SYLLABLE MIEUM WEO TIKEUT
+0x9265	0xBB59	#HANGUL SYLLABLE MIEUM WEO RIEULKIYEOK
+0x9266	0xBB5A	#HANGUL SYLLABLE MIEUM WEO RIEULMIEUM
+0x9267	0xBB5B	#HANGUL SYLLABLE MIEUM WEO RIEULPIEUP
+0x9268	0xBB5C	#HANGUL SYLLABLE MIEUM WEO RIEULSIOS
+0x9269	0xBB5D	#HANGUL SYLLABLE MIEUM WEO RIEULTHIEUTH
+0x926A	0xBB5E	#HANGUL SYLLABLE MIEUM WEO RIEULPHIEUPH
+0x926B	0xBB5F	#HANGUL SYLLABLE MIEUM WEO RIEULHIEUH
+0x926C	0xBB60	#HANGUL SYLLABLE MIEUM WEO MIEUM
+0x926D	0xBB62	#HANGUL SYLLABLE MIEUM WEO PIEUPSIOS
+0x926E	0xBB64	#HANGUL SYLLABLE MIEUM WEO SSANGSIOS
+0x926F	0xBB65	#HANGUL SYLLABLE MIEUM WEO IEUNG
+0x9270	0xBB66	#HANGUL SYLLABLE MIEUM WEO CIEUC
+0x9271	0xBB67	#HANGUL SYLLABLE MIEUM WEO CHIEUCH
+0x9272	0xBB68	#HANGUL SYLLABLE MIEUM WEO KHIEUKH
+0x9273	0xBB69	#HANGUL SYLLABLE MIEUM WEO THIEUTH
+0x9274	0xBB6A	#HANGUL SYLLABLE MIEUM WEO PHIEUPH
+0x9275	0xBB6B	#HANGUL SYLLABLE MIEUM WEO HIEUH
+0x9276	0xBB6D	#HANGUL SYLLABLE MIEUM WE KIYEOK
+0x9277	0xBB6E	#HANGUL SYLLABLE MIEUM WE SSANGKIYEOK
+0x9278	0xBB6F	#HANGUL SYLLABLE MIEUM WE KIYEOKSIOS
+0x9279	0xBB70	#HANGUL SYLLABLE MIEUM WE NIEUN
+0x927A	0xBB71	#HANGUL SYLLABLE MIEUM WE NIEUNCIEUC
+0x9281	0xBB72	#HANGUL SYLLABLE MIEUM WE NIEUNHIEUH
+0x9282	0xBB73	#HANGUL SYLLABLE MIEUM WE TIKEUT
+0x9283	0xBB74	#HANGUL SYLLABLE MIEUM WE RIEUL
+0x9284	0xBB75	#HANGUL SYLLABLE MIEUM WE RIEULKIYEOK
+0x9285	0xBB76	#HANGUL SYLLABLE MIEUM WE RIEULMIEUM
+0x9286	0xBB77	#HANGUL SYLLABLE MIEUM WE RIEULPIEUP
+0x9287	0xBB78	#HANGUL SYLLABLE MIEUM WE RIEULSIOS
+0x9288	0xBB79	#HANGUL SYLLABLE MIEUM WE RIEULTHIEUTH
+0x9289	0xBB7A	#HANGUL SYLLABLE MIEUM WE RIEULPHIEUPH
+0x928A	0xBB7B	#HANGUL SYLLABLE MIEUM WE RIEULHIEUH
+0x928B	0xBB7C	#HANGUL SYLLABLE MIEUM WE MIEUM
+0x928C	0xBB7D	#HANGUL SYLLABLE MIEUM WE PIEUP
+0x928D	0xBB7E	#HANGUL SYLLABLE MIEUM WE PIEUPSIOS
+0x928E	0xBB7F	#HANGUL SYLLABLE MIEUM WE SIOS
+0x928F	0xBB80	#HANGUL SYLLABLE MIEUM WE SSANGSIOS
+0x9290	0xBB81	#HANGUL SYLLABLE MIEUM WE IEUNG
+0x9291	0xBB82	#HANGUL SYLLABLE MIEUM WE CIEUC
+0x9292	0xBB83	#HANGUL SYLLABLE MIEUM WE CHIEUCH
+0x9293	0xBB84	#HANGUL SYLLABLE MIEUM WE KHIEUKH
+0x9294	0xBB85	#HANGUL SYLLABLE MIEUM WE THIEUTH
+0x9295	0xBB86	#HANGUL SYLLABLE MIEUM WE PHIEUPH
+0x9296	0xBB87	#HANGUL SYLLABLE MIEUM WE HIEUH
+0x9297	0xBB89	#HANGUL SYLLABLE MIEUM WI KIYEOK
+0x9298	0xBB8A	#HANGUL SYLLABLE MIEUM WI SSANGKIYEOK
+0x9299	0xBB8B	#HANGUL SYLLABLE MIEUM WI KIYEOKSIOS
+0x929A	0xBB8D	#HANGUL SYLLABLE MIEUM WI NIEUNCIEUC
+0x929B	0xBB8E	#HANGUL SYLLABLE MIEUM WI NIEUNHIEUH
+0x929C	0xBB8F	#HANGUL SYLLABLE MIEUM WI TIKEUT
+0x929D	0xBB91	#HANGUL SYLLABLE MIEUM WI RIEULKIYEOK
+0x929E	0xBB92	#HANGUL SYLLABLE MIEUM WI RIEULMIEUM
+0x929F	0xBB93	#HANGUL SYLLABLE MIEUM WI RIEULPIEUP
+0x92A0	0xBB94	#HANGUL SYLLABLE MIEUM WI RIEULSIOS
+0x92A1	0xBB95	#HANGUL SYLLABLE MIEUM WI RIEULTHIEUTH
+0x92A2	0xBB96	#HANGUL SYLLABLE MIEUM WI RIEULPHIEUPH
+0x92A3	0xBB97	#HANGUL SYLLABLE MIEUM WI RIEULHIEUH
+0x92A4	0xBB98	#HANGUL SYLLABLE MIEUM WI MIEUM
+0x92A5	0xBB99	#HANGUL SYLLABLE MIEUM WI PIEUP
+0x92A6	0xBB9A	#HANGUL SYLLABLE MIEUM WI PIEUPSIOS
+0x92A7	0xBB9B	#HANGUL SYLLABLE MIEUM WI SIOS
+0x92A8	0xBB9C	#HANGUL SYLLABLE MIEUM WI SSANGSIOS
+0x92A9	0xBB9D	#HANGUL SYLLABLE MIEUM WI IEUNG
+0x92AA	0xBB9E	#HANGUL SYLLABLE MIEUM WI CIEUC
+0x92AB	0xBB9F	#HANGUL SYLLABLE MIEUM WI CHIEUCH
+0x92AC	0xBBA0	#HANGUL SYLLABLE MIEUM WI KHIEUKH
+0x92AD	0xBBA1	#HANGUL SYLLABLE MIEUM WI THIEUTH
+0x92AE	0xBBA2	#HANGUL SYLLABLE MIEUM WI PHIEUPH
+0x92AF	0xBBA3	#HANGUL SYLLABLE MIEUM WI HIEUH
+0x92B0	0xBBA5	#HANGUL SYLLABLE MIEUM YU KIYEOK
+0x92B1	0xBBA6	#HANGUL SYLLABLE MIEUM YU SSANGKIYEOK
+0x92B2	0xBBA7	#HANGUL SYLLABLE MIEUM YU KIYEOKSIOS
+0x92B3	0xBBA9	#HANGUL SYLLABLE MIEUM YU NIEUNCIEUC
+0x92B4	0xBBAA	#HANGUL SYLLABLE MIEUM YU NIEUNHIEUH
+0x92B5	0xBBAB	#HANGUL SYLLABLE MIEUM YU TIKEUT
+0x92B6	0xBBAD	#HANGUL SYLLABLE MIEUM YU RIEULKIYEOK
+0x92B7	0xBBAE	#HANGUL SYLLABLE MIEUM YU RIEULMIEUM
+0x92B8	0xBBAF	#HANGUL SYLLABLE MIEUM YU RIEULPIEUP
+0x92B9	0xBBB0	#HANGUL SYLLABLE MIEUM YU RIEULSIOS
+0x92BA	0xBBB1	#HANGUL SYLLABLE MIEUM YU RIEULTHIEUTH
+0x92BB	0xBBB2	#HANGUL SYLLABLE MIEUM YU RIEULPHIEUPH
+0x92BC	0xBBB3	#HANGUL SYLLABLE MIEUM YU RIEULHIEUH
+0x92BD	0xBBB5	#HANGUL SYLLABLE MIEUM YU PIEUP
+0x92BE	0xBBB6	#HANGUL SYLLABLE MIEUM YU PIEUPSIOS
+0x92BF	0xBBB8	#HANGUL SYLLABLE MIEUM YU SSANGSIOS
+0x92C0	0xBBB9	#HANGUL SYLLABLE MIEUM YU IEUNG
+0x92C1	0xBBBA	#HANGUL SYLLABLE MIEUM YU CIEUC
+0x92C2	0xBBBB	#HANGUL SYLLABLE MIEUM YU CHIEUCH
+0x92C3	0xBBBC	#HANGUL SYLLABLE MIEUM YU KHIEUKH
+0x92C4	0xBBBD	#HANGUL SYLLABLE MIEUM YU THIEUTH
+0x92C5	0xBBBE	#HANGUL SYLLABLE MIEUM YU PHIEUPH
+0x92C6	0xBBBF	#HANGUL SYLLABLE MIEUM YU HIEUH
+0x92C7	0xBBC1	#HANGUL SYLLABLE MIEUM EU KIYEOK
+0x92C8	0xBBC2	#HANGUL SYLLABLE MIEUM EU SSANGKIYEOK
+0x92C9	0xBBC3	#HANGUL SYLLABLE MIEUM EU KIYEOKSIOS
+0x92CA	0xBBC5	#HANGUL SYLLABLE MIEUM EU NIEUNCIEUC
+0x92CB	0xBBC6	#HANGUL SYLLABLE MIEUM EU NIEUNHIEUH
+0x92CC	0xBBC7	#HANGUL SYLLABLE MIEUM EU TIKEUT
+0x92CD	0xBBC9	#HANGUL SYLLABLE MIEUM EU RIEULKIYEOK
+0x92CE	0xBBCA	#HANGUL SYLLABLE MIEUM EU RIEULMIEUM
+0x92CF	0xBBCB	#HANGUL SYLLABLE MIEUM EU RIEULPIEUP
+0x92D0	0xBBCC	#HANGUL SYLLABLE MIEUM EU RIEULSIOS
+0x92D1	0xBBCD	#HANGUL SYLLABLE MIEUM EU RIEULTHIEUTH
+0x92D2	0xBBCE	#HANGUL SYLLABLE MIEUM EU RIEULPHIEUPH
+0x92D3	0xBBCF	#HANGUL SYLLABLE MIEUM EU RIEULHIEUH
+0x92D4	0xBBD1	#HANGUL SYLLABLE MIEUM EU PIEUP
+0x92D5	0xBBD2	#HANGUL SYLLABLE MIEUM EU PIEUPSIOS
+0x92D6	0xBBD4	#HANGUL SYLLABLE MIEUM EU SSANGSIOS
+0x92D7	0xBBD5	#HANGUL SYLLABLE MIEUM EU IEUNG
+0x92D8	0xBBD6	#HANGUL SYLLABLE MIEUM EU CIEUC
+0x92D9	0xBBD7	#HANGUL SYLLABLE MIEUM EU CHIEUCH
+0x92DA	0xBBD8	#HANGUL SYLLABLE MIEUM EU KHIEUKH
+0x92DB	0xBBD9	#HANGUL SYLLABLE MIEUM EU THIEUTH
+0x92DC	0xBBDA	#HANGUL SYLLABLE MIEUM EU PHIEUPH
+0x92DD	0xBBDB	#HANGUL SYLLABLE MIEUM EU HIEUH
+0x92DE	0xBBDC	#HANGUL SYLLABLE MIEUM YI
+0x92DF	0xBBDD	#HANGUL SYLLABLE MIEUM YI KIYEOK
+0x92E0	0xBBDE	#HANGUL SYLLABLE MIEUM YI SSANGKIYEOK
+0x92E1	0xBBDF	#HANGUL SYLLABLE MIEUM YI KIYEOKSIOS
+0x92E2	0xBBE0	#HANGUL SYLLABLE MIEUM YI NIEUN
+0x92E3	0xBBE1	#HANGUL SYLLABLE MIEUM YI NIEUNCIEUC
+0x92E4	0xBBE2	#HANGUL SYLLABLE MIEUM YI NIEUNHIEUH
+0x92E5	0xBBE3	#HANGUL SYLLABLE MIEUM YI TIKEUT
+0x92E6	0xBBE4	#HANGUL SYLLABLE MIEUM YI RIEUL
+0x92E7	0xBBE5	#HANGUL SYLLABLE MIEUM YI RIEULKIYEOK
+0x92E8	0xBBE6	#HANGUL SYLLABLE MIEUM YI RIEULMIEUM
+0x92E9	0xBBE7	#HANGUL SYLLABLE MIEUM YI RIEULPIEUP
+0x92EA	0xBBE8	#HANGUL SYLLABLE MIEUM YI RIEULSIOS
+0x92EB	0xBBE9	#HANGUL SYLLABLE MIEUM YI RIEULTHIEUTH
+0x92EC	0xBBEA	#HANGUL SYLLABLE MIEUM YI RIEULPHIEUPH
+0x92ED	0xBBEB	#HANGUL SYLLABLE MIEUM YI RIEULHIEUH
+0x92EE	0xBBEC	#HANGUL SYLLABLE MIEUM YI MIEUM
+0x92EF	0xBBED	#HANGUL SYLLABLE MIEUM YI PIEUP
+0x92F0	0xBBEE	#HANGUL SYLLABLE MIEUM YI PIEUPSIOS
+0x92F1	0xBBEF	#HANGUL SYLLABLE MIEUM YI SIOS
+0x92F2	0xBBF0	#HANGUL SYLLABLE MIEUM YI SSANGSIOS
+0x92F3	0xBBF1	#HANGUL SYLLABLE MIEUM YI IEUNG
+0x92F4	0xBBF2	#HANGUL SYLLABLE MIEUM YI CIEUC
+0x92F5	0xBBF3	#HANGUL SYLLABLE MIEUM YI CHIEUCH
+0x92F6	0xBBF4	#HANGUL SYLLABLE MIEUM YI KHIEUKH
+0x92F7	0xBBF5	#HANGUL SYLLABLE MIEUM YI THIEUTH
+0x92F8	0xBBF6	#HANGUL SYLLABLE MIEUM YI PHIEUPH
+0x92F9	0xBBF7	#HANGUL SYLLABLE MIEUM YI HIEUH
+0x92FA	0xBBFA	#HANGUL SYLLABLE MIEUM I SSANGKIYEOK
+0x92FB	0xBBFB	#HANGUL SYLLABLE MIEUM I KIYEOKSIOS
+0x92FC	0xBBFD	#HANGUL SYLLABLE MIEUM I NIEUNCIEUC
+0x92FD	0xBBFE	#HANGUL SYLLABLE MIEUM I NIEUNHIEUH
+0x92FE	0xBC01	#HANGUL SYLLABLE MIEUM I RIEULKIYEOK
+0x9341	0xBC03	#HANGUL SYLLABLE MIEUM I RIEULPIEUP
+0x9342	0xBC04	#HANGUL SYLLABLE MIEUM I RIEULSIOS
+0x9343	0xBC05	#HANGUL SYLLABLE MIEUM I RIEULTHIEUTH
+0x9344	0xBC06	#HANGUL SYLLABLE MIEUM I RIEULPHIEUPH
+0x9345	0xBC07	#HANGUL SYLLABLE MIEUM I RIEULHIEUH
+0x9346	0xBC0A	#HANGUL SYLLABLE MIEUM I PIEUPSIOS
+0x9347	0xBC0E	#HANGUL SYLLABLE MIEUM I CIEUC
+0x9348	0xBC10	#HANGUL SYLLABLE MIEUM I KHIEUKH
+0x9349	0xBC12	#HANGUL SYLLABLE MIEUM I PHIEUPH
+0x934A	0xBC13	#HANGUL SYLLABLE MIEUM I HIEUH
+0x934B	0xBC19	#HANGUL SYLLABLE PIEUP A NIEUNCIEUC
+0x934C	0xBC1A	#HANGUL SYLLABLE PIEUP A NIEUNHIEUH
+0x934D	0xBC20	#HANGUL SYLLABLE PIEUP A RIEULSIOS
+0x934E	0xBC21	#HANGUL SYLLABLE PIEUP A RIEULTHIEUTH
+0x934F	0xBC22	#HANGUL SYLLABLE PIEUP A RIEULPHIEUPH
+0x9350	0xBC23	#HANGUL SYLLABLE PIEUP A RIEULHIEUH
+0x9351	0xBC26	#HANGUL SYLLABLE PIEUP A PIEUPSIOS
+0x9352	0xBC28	#HANGUL SYLLABLE PIEUP A SSANGSIOS
+0x9353	0xBC2A	#HANGUL SYLLABLE PIEUP A CIEUC
+0x9354	0xBC2B	#HANGUL SYLLABLE PIEUP A CHIEUCH
+0x9355	0xBC2C	#HANGUL SYLLABLE PIEUP A KHIEUKH
+0x9356	0xBC2E	#HANGUL SYLLABLE PIEUP A PHIEUPH
+0x9357	0xBC2F	#HANGUL SYLLABLE PIEUP A HIEUH
+0x9358	0xBC32	#HANGUL SYLLABLE PIEUP AE SSANGKIYEOK
+0x9359	0xBC33	#HANGUL SYLLABLE PIEUP AE KIYEOKSIOS
+0x935A	0xBC35	#HANGUL SYLLABLE PIEUP AE NIEUNCIEUC
+0x9361	0xBC36	#HANGUL SYLLABLE PIEUP AE NIEUNHIEUH
+0x9362	0xBC37	#HANGUL SYLLABLE PIEUP AE TIKEUT
+0x9363	0xBC39	#HANGUL SYLLABLE PIEUP AE RIEULKIYEOK
+0x9364	0xBC3A	#HANGUL SYLLABLE PIEUP AE RIEULMIEUM
+0x9365	0xBC3B	#HANGUL SYLLABLE PIEUP AE RIEULPIEUP
+0x9366	0xBC3C	#HANGUL SYLLABLE PIEUP AE RIEULSIOS
+0x9367	0xBC3D	#HANGUL SYLLABLE PIEUP AE RIEULTHIEUTH
+0x9368	0xBC3E	#HANGUL SYLLABLE PIEUP AE RIEULPHIEUPH
+0x9369	0xBC3F	#HANGUL SYLLABLE PIEUP AE RIEULHIEUH
+0x936A	0xBC42	#HANGUL SYLLABLE PIEUP AE PIEUPSIOS
+0x936B	0xBC46	#HANGUL SYLLABLE PIEUP AE CIEUC
+0x936C	0xBC47	#HANGUL SYLLABLE PIEUP AE CHIEUCH
+0x936D	0xBC48	#HANGUL SYLLABLE PIEUP AE KHIEUKH
+0x936E	0xBC4A	#HANGUL SYLLABLE PIEUP AE PHIEUPH
+0x936F	0xBC4B	#HANGUL SYLLABLE PIEUP AE HIEUH
+0x9370	0xBC4E	#HANGUL SYLLABLE PIEUP YA SSANGKIYEOK
+0x9371	0xBC4F	#HANGUL SYLLABLE PIEUP YA KIYEOKSIOS
+0x9372	0xBC51	#HANGUL SYLLABLE PIEUP YA NIEUNCIEUC
+0x9373	0xBC52	#HANGUL SYLLABLE PIEUP YA NIEUNHIEUH
+0x9374	0xBC53	#HANGUL SYLLABLE PIEUP YA TIKEUT
+0x9375	0xBC54	#HANGUL SYLLABLE PIEUP YA RIEUL
+0x9376	0xBC55	#HANGUL SYLLABLE PIEUP YA RIEULKIYEOK
+0x9377	0xBC56	#HANGUL SYLLABLE PIEUP YA RIEULMIEUM
+0x9378	0xBC57	#HANGUL SYLLABLE PIEUP YA RIEULPIEUP
+0x9379	0xBC58	#HANGUL SYLLABLE PIEUP YA RIEULSIOS
+0x937A	0xBC59	#HANGUL SYLLABLE PIEUP YA RIEULTHIEUTH
+0x9381	0xBC5A	#HANGUL SYLLABLE PIEUP YA RIEULPHIEUPH
+0x9382	0xBC5B	#HANGUL SYLLABLE PIEUP YA RIEULHIEUH
+0x9383	0xBC5C	#HANGUL SYLLABLE PIEUP YA MIEUM
+0x9384	0xBC5E	#HANGUL SYLLABLE PIEUP YA PIEUPSIOS
+0x9385	0xBC5F	#HANGUL SYLLABLE PIEUP YA SIOS
+0x9386	0xBC60	#HANGUL SYLLABLE PIEUP YA SSANGSIOS
+0x9387	0xBC61	#HANGUL SYLLABLE PIEUP YA IEUNG
+0x9388	0xBC62	#HANGUL SYLLABLE PIEUP YA CIEUC
+0x9389	0xBC63	#HANGUL SYLLABLE PIEUP YA CHIEUCH
+0x938A	0xBC64	#HANGUL SYLLABLE PIEUP YA KHIEUKH
+0x938B	0xBC65	#HANGUL SYLLABLE PIEUP YA THIEUTH
+0x938C	0xBC66	#HANGUL SYLLABLE PIEUP YA PHIEUPH
+0x938D	0xBC67	#HANGUL SYLLABLE PIEUP YA HIEUH
+0x938E	0xBC68	#HANGUL SYLLABLE PIEUP YAE
+0x938F	0xBC69	#HANGUL SYLLABLE PIEUP YAE KIYEOK
+0x9390	0xBC6A	#HANGUL SYLLABLE PIEUP YAE SSANGKIYEOK
+0x9391	0xBC6B	#HANGUL SYLLABLE PIEUP YAE KIYEOKSIOS
+0x9392	0xBC6C	#HANGUL SYLLABLE PIEUP YAE NIEUN
+0x9393	0xBC6D	#HANGUL SYLLABLE PIEUP YAE NIEUNCIEUC
+0x9394	0xBC6E	#HANGUL SYLLABLE PIEUP YAE NIEUNHIEUH
+0x9395	0xBC6F	#HANGUL SYLLABLE PIEUP YAE TIKEUT
+0x9396	0xBC70	#HANGUL SYLLABLE PIEUP YAE RIEUL
+0x9397	0xBC71	#HANGUL SYLLABLE PIEUP YAE RIEULKIYEOK
+0x9398	0xBC72	#HANGUL SYLLABLE PIEUP YAE RIEULMIEUM
+0x9399	0xBC73	#HANGUL SYLLABLE PIEUP YAE RIEULPIEUP
+0x939A	0xBC74	#HANGUL SYLLABLE PIEUP YAE RIEULSIOS
+0x939B	0xBC75	#HANGUL SYLLABLE PIEUP YAE RIEULTHIEUTH
+0x939C	0xBC76	#HANGUL SYLLABLE PIEUP YAE RIEULPHIEUPH
+0x939D	0xBC77	#HANGUL SYLLABLE PIEUP YAE RIEULHIEUH
+0x939E	0xBC78	#HANGUL SYLLABLE PIEUP YAE MIEUM
+0x939F	0xBC79	#HANGUL SYLLABLE PIEUP YAE PIEUP
+0x93A0	0xBC7A	#HANGUL SYLLABLE PIEUP YAE PIEUPSIOS
+0x93A1	0xBC7B	#HANGUL SYLLABLE PIEUP YAE SIOS
+0x93A2	0xBC7C	#HANGUL SYLLABLE PIEUP YAE SSANGSIOS
+0x93A3	0xBC7D	#HANGUL SYLLABLE PIEUP YAE IEUNG
+0x93A4	0xBC7E	#HANGUL SYLLABLE PIEUP YAE CIEUC
+0x93A5	0xBC7F	#HANGUL SYLLABLE PIEUP YAE CHIEUCH
+0x93A6	0xBC80	#HANGUL SYLLABLE PIEUP YAE KHIEUKH
+0x93A7	0xBC81	#HANGUL SYLLABLE PIEUP YAE THIEUTH
+0x93A8	0xBC82	#HANGUL SYLLABLE PIEUP YAE PHIEUPH
+0x93A9	0xBC83	#HANGUL SYLLABLE PIEUP YAE HIEUH
+0x93AA	0xBC86	#HANGUL SYLLABLE PIEUP EO SSANGKIYEOK
+0x93AB	0xBC87	#HANGUL SYLLABLE PIEUP EO KIYEOKSIOS
+0x93AC	0xBC89	#HANGUL SYLLABLE PIEUP EO NIEUNCIEUC
+0x93AD	0xBC8A	#HANGUL SYLLABLE PIEUP EO NIEUNHIEUH
+0x93AE	0xBC8D	#HANGUL SYLLABLE PIEUP EO RIEULKIYEOK
+0x93AF	0xBC8F	#HANGUL SYLLABLE PIEUP EO RIEULPIEUP
+0x93B0	0xBC90	#HANGUL SYLLABLE PIEUP EO RIEULSIOS
+0x93B1	0xBC91	#HANGUL SYLLABLE PIEUP EO RIEULTHIEUTH
+0x93B2	0xBC92	#HANGUL SYLLABLE PIEUP EO RIEULPHIEUPH
+0x93B3	0xBC93	#HANGUL SYLLABLE PIEUP EO RIEULHIEUH
+0x93B4	0xBC96	#HANGUL SYLLABLE PIEUP EO PIEUPSIOS
+0x93B5	0xBC98	#HANGUL SYLLABLE PIEUP EO SSANGSIOS
+0x93B6	0xBC9B	#HANGUL SYLLABLE PIEUP EO CHIEUCH
+0x93B7	0xBC9C	#HANGUL SYLLABLE PIEUP EO KHIEUKH
+0x93B8	0xBC9D	#HANGUL SYLLABLE PIEUP EO THIEUTH
+0x93B9	0xBC9E	#HANGUL SYLLABLE PIEUP EO PHIEUPH
+0x93BA	0xBC9F	#HANGUL SYLLABLE PIEUP EO HIEUH
+0x93BB	0xBCA2	#HANGUL SYLLABLE PIEUP E SSANGKIYEOK
+0x93BC	0xBCA3	#HANGUL SYLLABLE PIEUP E KIYEOKSIOS
+0x93BD	0xBCA5	#HANGUL SYLLABLE PIEUP E NIEUNCIEUC
+0x93BE	0xBCA6	#HANGUL SYLLABLE PIEUP E NIEUNHIEUH
+0x93BF	0xBCA9	#HANGUL SYLLABLE PIEUP E RIEULKIYEOK
+0x93C0	0xBCAA	#HANGUL SYLLABLE PIEUP E RIEULMIEUM
+0x93C1	0xBCAB	#HANGUL SYLLABLE PIEUP E RIEULPIEUP
+0x93C2	0xBCAC	#HANGUL SYLLABLE PIEUP E RIEULSIOS
+0x93C3	0xBCAD	#HANGUL SYLLABLE PIEUP E RIEULTHIEUTH
+0x93C4	0xBCAE	#HANGUL SYLLABLE PIEUP E RIEULPHIEUPH
+0x93C5	0xBCAF	#HANGUL SYLLABLE PIEUP E RIEULHIEUH
+0x93C6	0xBCB2	#HANGUL SYLLABLE PIEUP E PIEUPSIOS
+0x93C7	0xBCB6	#HANGUL SYLLABLE PIEUP E CIEUC
+0x93C8	0xBCB7	#HANGUL SYLLABLE PIEUP E CHIEUCH
+0x93C9	0xBCB8	#HANGUL SYLLABLE PIEUP E KHIEUKH
+0x93CA	0xBCB9	#HANGUL SYLLABLE PIEUP E THIEUTH
+0x93CB	0xBCBA	#HANGUL SYLLABLE PIEUP E PHIEUPH
+0x93CC	0xBCBB	#HANGUL SYLLABLE PIEUP E HIEUH
+0x93CD	0xBCBE	#HANGUL SYLLABLE PIEUP YEO SSANGKIYEOK
+0x93CE	0xBCBF	#HANGUL SYLLABLE PIEUP YEO KIYEOKSIOS
+0x93CF	0xBCC1	#HANGUL SYLLABLE PIEUP YEO NIEUNCIEUC
+0x93D0	0xBCC2	#HANGUL SYLLABLE PIEUP YEO NIEUNHIEUH
+0x93D1	0xBCC3	#HANGUL SYLLABLE PIEUP YEO TIKEUT
+0x93D2	0xBCC5	#HANGUL SYLLABLE PIEUP YEO RIEULKIYEOK
+0x93D3	0xBCC6	#HANGUL SYLLABLE PIEUP YEO RIEULMIEUM
+0x93D4	0xBCC7	#HANGUL SYLLABLE PIEUP YEO RIEULPIEUP
+0x93D5	0xBCC8	#HANGUL SYLLABLE PIEUP YEO RIEULSIOS
+0x93D6	0xBCC9	#HANGUL SYLLABLE PIEUP YEO RIEULTHIEUTH
+0x93D7	0xBCCA	#HANGUL SYLLABLE PIEUP YEO RIEULPHIEUPH
+0x93D8	0xBCCB	#HANGUL SYLLABLE PIEUP YEO RIEULHIEUH
+0x93D9	0xBCCC	#HANGUL SYLLABLE PIEUP YEO MIEUM
+0x93DA	0xBCCE	#HANGUL SYLLABLE PIEUP YEO PIEUPSIOS
+0x93DB	0xBCD2	#HANGUL SYLLABLE PIEUP YEO CIEUC
+0x93DC	0xBCD3	#HANGUL SYLLABLE PIEUP YEO CHIEUCH
+0x93DD	0xBCD4	#HANGUL SYLLABLE PIEUP YEO KHIEUKH
+0x93DE	0xBCD6	#HANGUL SYLLABLE PIEUP YEO PHIEUPH
+0x93DF	0xBCD7	#HANGUL SYLLABLE PIEUP YEO HIEUH
+0x93E0	0xBCD9	#HANGUL SYLLABLE PIEUP YE KIYEOK
+0x93E1	0xBCDA	#HANGUL SYLLABLE PIEUP YE SSANGKIYEOK
+0x93E2	0xBCDB	#HANGUL SYLLABLE PIEUP YE KIYEOKSIOS
+0x93E3	0xBCDD	#HANGUL SYLLABLE PIEUP YE NIEUNCIEUC
+0x93E4	0xBCDE	#HANGUL SYLLABLE PIEUP YE NIEUNHIEUH
+0x93E5	0xBCDF	#HANGUL SYLLABLE PIEUP YE TIKEUT
+0x93E6	0xBCE0	#HANGUL SYLLABLE PIEUP YE RIEUL
+0x93E7	0xBCE1	#HANGUL SYLLABLE PIEUP YE RIEULKIYEOK
+0x93E8	0xBCE2	#HANGUL SYLLABLE PIEUP YE RIEULMIEUM
+0x93E9	0xBCE3	#HANGUL SYLLABLE PIEUP YE RIEULPIEUP
+0x93EA	0xBCE4	#HANGUL SYLLABLE PIEUP YE RIEULSIOS
+0x93EB	0xBCE5	#HANGUL SYLLABLE PIEUP YE RIEULTHIEUTH
+0x93EC	0xBCE6	#HANGUL SYLLABLE PIEUP YE RIEULPHIEUPH
+0x93ED	0xBCE7	#HANGUL SYLLABLE PIEUP YE RIEULHIEUH
+0x93EE	0xBCE8	#HANGUL SYLLABLE PIEUP YE MIEUM
+0x93EF	0xBCE9	#HANGUL SYLLABLE PIEUP YE PIEUP
+0x93F0	0xBCEA	#HANGUL SYLLABLE PIEUP YE PIEUPSIOS
+0x93F1	0xBCEB	#HANGUL SYLLABLE PIEUP YE SIOS
+0x93F2	0xBCEC	#HANGUL SYLLABLE PIEUP YE SSANGSIOS
+0x93F3	0xBCED	#HANGUL SYLLABLE PIEUP YE IEUNG
+0x93F4	0xBCEE	#HANGUL SYLLABLE PIEUP YE CIEUC
+0x93F5	0xBCEF	#HANGUL SYLLABLE PIEUP YE CHIEUCH
+0x93F6	0xBCF0	#HANGUL SYLLABLE PIEUP YE KHIEUKH
+0x93F7	0xBCF1	#HANGUL SYLLABLE PIEUP YE THIEUTH
+0x93F8	0xBCF2	#HANGUL SYLLABLE PIEUP YE PHIEUPH
+0x93F9	0xBCF3	#HANGUL SYLLABLE PIEUP YE HIEUH
+0x93FA	0xBCF7	#HANGUL SYLLABLE PIEUP O KIYEOKSIOS
+0x93FB	0xBCF9	#HANGUL SYLLABLE PIEUP O NIEUNCIEUC
+0x93FC	0xBCFA	#HANGUL SYLLABLE PIEUP O NIEUNHIEUH
+0x93FD	0xBCFB	#HANGUL SYLLABLE PIEUP O TIKEUT
+0x93FE	0xBCFD	#HANGUL SYLLABLE PIEUP O RIEULKIYEOK
+0x9441	0xBCFE	#HANGUL SYLLABLE PIEUP O RIEULMIEUM
+0x9442	0xBCFF	#HANGUL SYLLABLE PIEUP O RIEULPIEUP
+0x9443	0xBD00	#HANGUL SYLLABLE PIEUP O RIEULSIOS
+0x9444	0xBD01	#HANGUL SYLLABLE PIEUP O RIEULTHIEUTH
+0x9445	0xBD02	#HANGUL SYLLABLE PIEUP O RIEULPHIEUPH
+0x9446	0xBD03	#HANGUL SYLLABLE PIEUP O RIEULHIEUH
+0x9447	0xBD06	#HANGUL SYLLABLE PIEUP O PIEUPSIOS
+0x9448	0xBD08	#HANGUL SYLLABLE PIEUP O SSANGSIOS
+0x9449	0xBD0A	#HANGUL SYLLABLE PIEUP O CIEUC
+0x944A	0xBD0B	#HANGUL SYLLABLE PIEUP O CHIEUCH
+0x944B	0xBD0C	#HANGUL SYLLABLE PIEUP O KHIEUKH
+0x944C	0xBD0D	#HANGUL SYLLABLE PIEUP O THIEUTH
+0x944D	0xBD0E	#HANGUL SYLLABLE PIEUP O PHIEUPH
+0x944E	0xBD0F	#HANGUL SYLLABLE PIEUP O HIEUH
+0x944F	0xBD11	#HANGUL SYLLABLE PIEUP WA KIYEOK
+0x9450	0xBD12	#HANGUL SYLLABLE PIEUP WA SSANGKIYEOK
+0x9451	0xBD13	#HANGUL SYLLABLE PIEUP WA KIYEOKSIOS
+0x9452	0xBD15	#HANGUL SYLLABLE PIEUP WA NIEUNCIEUC
+0x9453	0xBD16	#HANGUL SYLLABLE PIEUP WA NIEUNHIEUH
+0x9454	0xBD17	#HANGUL SYLLABLE PIEUP WA TIKEUT
+0x9455	0xBD18	#HANGUL SYLLABLE PIEUP WA RIEUL
+0x9456	0xBD19	#HANGUL SYLLABLE PIEUP WA RIEULKIYEOK
+0x9457	0xBD1A	#HANGUL SYLLABLE PIEUP WA RIEULMIEUM
+0x9458	0xBD1B	#HANGUL SYLLABLE PIEUP WA RIEULPIEUP
+0x9459	0xBD1C	#HANGUL SYLLABLE PIEUP WA RIEULSIOS
+0x945A	0xBD1D	#HANGUL SYLLABLE PIEUP WA RIEULTHIEUTH
+0x9461	0xBD1E	#HANGUL SYLLABLE PIEUP WA RIEULPHIEUPH
+0x9462	0xBD1F	#HANGUL SYLLABLE PIEUP WA RIEULHIEUH
+0x9463	0xBD20	#HANGUL SYLLABLE PIEUP WA MIEUM
+0x9464	0xBD21	#HANGUL SYLLABLE PIEUP WA PIEUP
+0x9465	0xBD22	#HANGUL SYLLABLE PIEUP WA PIEUPSIOS
+0x9466	0xBD23	#HANGUL SYLLABLE PIEUP WA SIOS
+0x9467	0xBD25	#HANGUL SYLLABLE PIEUP WA IEUNG
+0x9468	0xBD26	#HANGUL SYLLABLE PIEUP WA CIEUC
+0x9469	0xBD27	#HANGUL SYLLABLE PIEUP WA CHIEUCH
+0x946A	0xBD28	#HANGUL SYLLABLE PIEUP WA KHIEUKH
+0x946B	0xBD29	#HANGUL SYLLABLE PIEUP WA THIEUTH
+0x946C	0xBD2A	#HANGUL SYLLABLE PIEUP WA PHIEUPH
+0x946D	0xBD2B	#HANGUL SYLLABLE PIEUP WA HIEUH
+0x946E	0xBD2D	#HANGUL SYLLABLE PIEUP WAE KIYEOK
+0x946F	0xBD2E	#HANGUL SYLLABLE PIEUP WAE SSANGKIYEOK
+0x9470	0xBD2F	#HANGUL SYLLABLE PIEUP WAE KIYEOKSIOS
+0x9471	0xBD30	#HANGUL SYLLABLE PIEUP WAE NIEUN
+0x9472	0xBD31	#HANGUL SYLLABLE PIEUP WAE NIEUNCIEUC
+0x9473	0xBD32	#HANGUL SYLLABLE PIEUP WAE NIEUNHIEUH
+0x9474	0xBD33	#HANGUL SYLLABLE PIEUP WAE TIKEUT
+0x9475	0xBD34	#HANGUL SYLLABLE PIEUP WAE RIEUL
+0x9476	0xBD35	#HANGUL SYLLABLE PIEUP WAE RIEULKIYEOK
+0x9477	0xBD36	#HANGUL SYLLABLE PIEUP WAE RIEULMIEUM
+0x9478	0xBD37	#HANGUL SYLLABLE PIEUP WAE RIEULPIEUP
+0x9479	0xBD38	#HANGUL SYLLABLE PIEUP WAE RIEULSIOS
+0x947A	0xBD39	#HANGUL SYLLABLE PIEUP WAE RIEULTHIEUTH
+0x9481	0xBD3A	#HANGUL SYLLABLE PIEUP WAE RIEULPHIEUPH
+0x9482	0xBD3B	#HANGUL SYLLABLE PIEUP WAE RIEULHIEUH
+0x9483	0xBD3C	#HANGUL SYLLABLE PIEUP WAE MIEUM
+0x9484	0xBD3D	#HANGUL SYLLABLE PIEUP WAE PIEUP
+0x9485	0xBD3E	#HANGUL SYLLABLE PIEUP WAE PIEUPSIOS
+0x9486	0xBD3F	#HANGUL SYLLABLE PIEUP WAE SIOS
+0x9487	0xBD41	#HANGUL SYLLABLE PIEUP WAE IEUNG
+0x9488	0xBD42	#HANGUL SYLLABLE PIEUP WAE CIEUC
+0x9489	0xBD43	#HANGUL SYLLABLE PIEUP WAE CHIEUCH
+0x948A	0xBD44	#HANGUL SYLLABLE PIEUP WAE KHIEUKH
+0x948B	0xBD45	#HANGUL SYLLABLE PIEUP WAE THIEUTH
+0x948C	0xBD46	#HANGUL SYLLABLE PIEUP WAE PHIEUPH
+0x948D	0xBD47	#HANGUL SYLLABLE PIEUP WAE HIEUH
+0x948E	0xBD4A	#HANGUL SYLLABLE PIEUP OE SSANGKIYEOK
+0x948F	0xBD4B	#HANGUL SYLLABLE PIEUP OE KIYEOKSIOS
+0x9490	0xBD4D	#HANGUL SYLLABLE PIEUP OE NIEUNCIEUC
+0x9491	0xBD4E	#HANGUL SYLLABLE PIEUP OE NIEUNHIEUH
+0x9492	0xBD4F	#HANGUL SYLLABLE PIEUP OE TIKEUT
+0x9493	0xBD51	#HANGUL SYLLABLE PIEUP OE RIEULKIYEOK
+0x9494	0xBD52	#HANGUL SYLLABLE PIEUP OE RIEULMIEUM
+0x9495	0xBD53	#HANGUL SYLLABLE PIEUP OE RIEULPIEUP
+0x9496	0xBD54	#HANGUL SYLLABLE PIEUP OE RIEULSIOS
+0x9497	0xBD55	#HANGUL SYLLABLE PIEUP OE RIEULTHIEUTH
+0x9498	0xBD56	#HANGUL SYLLABLE PIEUP OE RIEULPHIEUPH
+0x9499	0xBD57	#HANGUL SYLLABLE PIEUP OE RIEULHIEUH
+0x949A	0xBD5A	#HANGUL SYLLABLE PIEUP OE PIEUPSIOS
+0x949B	0xBD5B	#HANGUL SYLLABLE PIEUP OE SIOS
+0x949C	0xBD5C	#HANGUL SYLLABLE PIEUP OE SSANGSIOS
+0x949D	0xBD5D	#HANGUL SYLLABLE PIEUP OE IEUNG
+0x949E	0xBD5E	#HANGUL SYLLABLE PIEUP OE CIEUC
+0x949F	0xBD5F	#HANGUL SYLLABLE PIEUP OE CHIEUCH
+0x94A0	0xBD60	#HANGUL SYLLABLE PIEUP OE KHIEUKH
+0x94A1	0xBD61	#HANGUL SYLLABLE PIEUP OE THIEUTH
+0x94A2	0xBD62	#HANGUL SYLLABLE PIEUP OE PHIEUPH
+0x94A3	0xBD63	#HANGUL SYLLABLE PIEUP OE HIEUH
+0x94A4	0xBD65	#HANGUL SYLLABLE PIEUP YO KIYEOK
+0x94A5	0xBD66	#HANGUL SYLLABLE PIEUP YO SSANGKIYEOK
+0x94A6	0xBD67	#HANGUL SYLLABLE PIEUP YO KIYEOKSIOS
+0x94A7	0xBD69	#HANGUL SYLLABLE PIEUP YO NIEUNCIEUC
+0x94A8	0xBD6A	#HANGUL SYLLABLE PIEUP YO NIEUNHIEUH
+0x94A9	0xBD6B	#HANGUL SYLLABLE PIEUP YO TIKEUT
+0x94AA	0xBD6C	#HANGUL SYLLABLE PIEUP YO RIEUL
+0x94AB	0xBD6D	#HANGUL SYLLABLE PIEUP YO RIEULKIYEOK
+0x94AC	0xBD6E	#HANGUL SYLLABLE PIEUP YO RIEULMIEUM
+0x94AD	0xBD6F	#HANGUL SYLLABLE PIEUP YO RIEULPIEUP
+0x94AE	0xBD70	#HANGUL SYLLABLE PIEUP YO RIEULSIOS
+0x94AF	0xBD71	#HANGUL SYLLABLE PIEUP YO RIEULTHIEUTH
+0x94B0	0xBD72	#HANGUL SYLLABLE PIEUP YO RIEULPHIEUPH
+0x94B1	0xBD73	#HANGUL SYLLABLE PIEUP YO RIEULHIEUH
+0x94B2	0xBD74	#HANGUL SYLLABLE PIEUP YO MIEUM
+0x94B3	0xBD75	#HANGUL SYLLABLE PIEUP YO PIEUP
+0x94B4	0xBD76	#HANGUL SYLLABLE PIEUP YO PIEUPSIOS
+0x94B5	0xBD77	#HANGUL SYLLABLE PIEUP YO SIOS
+0x94B6	0xBD78	#HANGUL SYLLABLE PIEUP YO SSANGSIOS
+0x94B7	0xBD79	#HANGUL SYLLABLE PIEUP YO IEUNG
+0x94B8	0xBD7A	#HANGUL SYLLABLE PIEUP YO CIEUC
+0x94B9	0xBD7B	#HANGUL SYLLABLE PIEUP YO CHIEUCH
+0x94BA	0xBD7C	#HANGUL SYLLABLE PIEUP YO KHIEUKH
+0x94BB	0xBD7D	#HANGUL SYLLABLE PIEUP YO THIEUTH
+0x94BC	0xBD7E	#HANGUL SYLLABLE PIEUP YO PHIEUPH
+0x94BD	0xBD7F	#HANGUL SYLLABLE PIEUP YO HIEUH
+0x94BE	0xBD82	#HANGUL SYLLABLE PIEUP U SSANGKIYEOK
+0x94BF	0xBD83	#HANGUL SYLLABLE PIEUP U KIYEOKSIOS
+0x94C0	0xBD85	#HANGUL SYLLABLE PIEUP U NIEUNCIEUC
+0x94C1	0xBD86	#HANGUL SYLLABLE PIEUP U NIEUNHIEUH
+0x94C2	0xBD8B	#HANGUL SYLLABLE PIEUP U RIEULPIEUP
+0x94C3	0xBD8C	#HANGUL SYLLABLE PIEUP U RIEULSIOS
+0x94C4	0xBD8D	#HANGUL SYLLABLE PIEUP U RIEULTHIEUTH
+0x94C5	0xBD8E	#HANGUL SYLLABLE PIEUP U RIEULPHIEUPH
+0x94C6	0xBD8F	#HANGUL SYLLABLE PIEUP U RIEULHIEUH
+0x94C7	0xBD92	#HANGUL SYLLABLE PIEUP U PIEUPSIOS
+0x94C8	0xBD94	#HANGUL SYLLABLE PIEUP U SSANGSIOS
+0x94C9	0xBD96	#HANGUL SYLLABLE PIEUP U CIEUC
+0x94CA	0xBD97	#HANGUL SYLLABLE PIEUP U CHIEUCH
+0x94CB	0xBD98	#HANGUL SYLLABLE PIEUP U KHIEUKH
+0x94CC	0xBD9B	#HANGUL SYLLABLE PIEUP U HIEUH
+0x94CD	0xBD9D	#HANGUL SYLLABLE PIEUP WEO KIYEOK
+0x94CE	0xBD9E	#HANGUL SYLLABLE PIEUP WEO SSANGKIYEOK
+0x94CF	0xBD9F	#HANGUL SYLLABLE PIEUP WEO KIYEOKSIOS
+0x94D0	0xBDA0	#HANGUL SYLLABLE PIEUP WEO NIEUN
+0x94D1	0xBDA1	#HANGUL SYLLABLE PIEUP WEO NIEUNCIEUC
+0x94D2	0xBDA2	#HANGUL SYLLABLE PIEUP WEO NIEUNHIEUH
+0x94D3	0xBDA3	#HANGUL SYLLABLE PIEUP WEO TIKEUT
+0x94D4	0xBDA5	#HANGUL SYLLABLE PIEUP WEO RIEULKIYEOK
+0x94D5	0xBDA6	#HANGUL SYLLABLE PIEUP WEO RIEULMIEUM
+0x94D6	0xBDA7	#HANGUL SYLLABLE PIEUP WEO RIEULPIEUP
+0x94D7	0xBDA8	#HANGUL SYLLABLE PIEUP WEO RIEULSIOS
+0x94D8	0xBDA9	#HANGUL SYLLABLE PIEUP WEO RIEULTHIEUTH
+0x94D9	0xBDAA	#HANGUL SYLLABLE PIEUP WEO RIEULPHIEUPH
+0x94DA	0xBDAB	#HANGUL SYLLABLE PIEUP WEO RIEULHIEUH
+0x94DB	0xBDAC	#HANGUL SYLLABLE PIEUP WEO MIEUM
+0x94DC	0xBDAD	#HANGUL SYLLABLE PIEUP WEO PIEUP
+0x94DD	0xBDAE	#HANGUL SYLLABLE PIEUP WEO PIEUPSIOS
+0x94DE	0xBDAF	#HANGUL SYLLABLE PIEUP WEO SIOS
+0x94DF	0xBDB1	#HANGUL SYLLABLE PIEUP WEO IEUNG
+0x94E0	0xBDB2	#HANGUL SYLLABLE PIEUP WEO CIEUC
+0x94E1	0xBDB3	#HANGUL SYLLABLE PIEUP WEO CHIEUCH
+0x94E2	0xBDB4	#HANGUL SYLLABLE PIEUP WEO KHIEUKH
+0x94E3	0xBDB5	#HANGUL SYLLABLE PIEUP WEO THIEUTH
+0x94E4	0xBDB6	#HANGUL SYLLABLE PIEUP WEO PHIEUPH
+0x94E5	0xBDB7	#HANGUL SYLLABLE PIEUP WEO HIEUH
+0x94E6	0xBDB9	#HANGUL SYLLABLE PIEUP WE KIYEOK
+0x94E7	0xBDBA	#HANGUL SYLLABLE PIEUP WE SSANGKIYEOK
+0x94E8	0xBDBB	#HANGUL SYLLABLE PIEUP WE KIYEOKSIOS
+0x94E9	0xBDBC	#HANGUL SYLLABLE PIEUP WE NIEUN
+0x94EA	0xBDBD	#HANGUL SYLLABLE PIEUP WE NIEUNCIEUC
+0x94EB	0xBDBE	#HANGUL SYLLABLE PIEUP WE NIEUNHIEUH
+0x94EC	0xBDBF	#HANGUL SYLLABLE PIEUP WE TIKEUT
+0x94ED	0xBDC0	#HANGUL SYLLABLE PIEUP WE RIEUL
+0x94EE	0xBDC1	#HANGUL SYLLABLE PIEUP WE RIEULKIYEOK
+0x94EF	0xBDC2	#HANGUL SYLLABLE PIEUP WE RIEULMIEUM
+0x94F0	0xBDC3	#HANGUL SYLLABLE PIEUP WE RIEULPIEUP
+0x94F1	0xBDC4	#HANGUL SYLLABLE PIEUP WE RIEULSIOS
+0x94F2	0xBDC5	#HANGUL SYLLABLE PIEUP WE RIEULTHIEUTH
+0x94F3	0xBDC6	#HANGUL SYLLABLE PIEUP WE RIEULPHIEUPH
+0x94F4	0xBDC7	#HANGUL SYLLABLE PIEUP WE RIEULHIEUH
+0x94F5	0xBDC8	#HANGUL SYLLABLE PIEUP WE MIEUM
+0x94F6	0xBDC9	#HANGUL SYLLABLE PIEUP WE PIEUP
+0x94F7	0xBDCA	#HANGUL SYLLABLE PIEUP WE PIEUPSIOS
+0x94F8	0xBDCB	#HANGUL SYLLABLE PIEUP WE SIOS
+0x94F9	0xBDCC	#HANGUL SYLLABLE PIEUP WE SSANGSIOS
+0x94FA	0xBDCD	#HANGUL SYLLABLE PIEUP WE IEUNG
+0x94FB	0xBDCE	#HANGUL SYLLABLE PIEUP WE CIEUC
+0x94FC	0xBDCF	#HANGUL SYLLABLE PIEUP WE CHIEUCH
+0x94FD	0xBDD0	#HANGUL SYLLABLE PIEUP WE KHIEUKH
+0x94FE	0xBDD1	#HANGUL SYLLABLE PIEUP WE THIEUTH
+0x9541	0xBDD2	#HANGUL SYLLABLE PIEUP WE PHIEUPH
+0x9542	0xBDD3	#HANGUL SYLLABLE PIEUP WE HIEUH
+0x9543	0xBDD6	#HANGUL SYLLABLE PIEUP WI SSANGKIYEOK
+0x9544	0xBDD7	#HANGUL SYLLABLE PIEUP WI KIYEOKSIOS
+0x9545	0xBDD9	#HANGUL SYLLABLE PIEUP WI NIEUNCIEUC
+0x9546	0xBDDA	#HANGUL SYLLABLE PIEUP WI NIEUNHIEUH
+0x9547	0xBDDB	#HANGUL SYLLABLE PIEUP WI TIKEUT
+0x9548	0xBDDD	#HANGUL SYLLABLE PIEUP WI RIEULKIYEOK
+0x9549	0xBDDE	#HANGUL SYLLABLE PIEUP WI RIEULMIEUM
+0x954A	0xBDDF	#HANGUL SYLLABLE PIEUP WI RIEULPIEUP
+0x954B	0xBDE0	#HANGUL SYLLABLE PIEUP WI RIEULSIOS
+0x954C	0xBDE1	#HANGUL SYLLABLE PIEUP WI RIEULTHIEUTH
+0x954D	0xBDE2	#HANGUL SYLLABLE PIEUP WI RIEULPHIEUPH
+0x954E	0xBDE3	#HANGUL SYLLABLE PIEUP WI RIEULHIEUH
+0x954F	0xBDE4	#HANGUL SYLLABLE PIEUP WI MIEUM
+0x9550	0xBDE5	#HANGUL SYLLABLE PIEUP WI PIEUP
+0x9551	0xBDE6	#HANGUL SYLLABLE PIEUP WI PIEUPSIOS
+0x9552	0xBDE7	#HANGUL SYLLABLE PIEUP WI SIOS
+0x9553	0xBDE8	#HANGUL SYLLABLE PIEUP WI SSANGSIOS
+0x9554	0xBDEA	#HANGUL SYLLABLE PIEUP WI CIEUC
+0x9555	0xBDEB	#HANGUL SYLLABLE PIEUP WI CHIEUCH
+0x9556	0xBDEC	#HANGUL SYLLABLE PIEUP WI KHIEUKH
+0x9557	0xBDED	#HANGUL SYLLABLE PIEUP WI THIEUTH
+0x9558	0xBDEE	#HANGUL SYLLABLE PIEUP WI PHIEUPH
+0x9559	0xBDEF	#HANGUL SYLLABLE PIEUP WI HIEUH
+0x955A	0xBDF1	#HANGUL SYLLABLE PIEUP YU KIYEOK
+0x9561	0xBDF2	#HANGUL SYLLABLE PIEUP YU SSANGKIYEOK
+0x9562	0xBDF3	#HANGUL SYLLABLE PIEUP YU KIYEOKSIOS
+0x9563	0xBDF5	#HANGUL SYLLABLE PIEUP YU NIEUNCIEUC
+0x9564	0xBDF6	#HANGUL SYLLABLE PIEUP YU NIEUNHIEUH
+0x9565	0xBDF7	#HANGUL SYLLABLE PIEUP YU TIKEUT
+0x9566	0xBDF9	#HANGUL SYLLABLE PIEUP YU RIEULKIYEOK
+0x9567	0xBDFA	#HANGUL SYLLABLE PIEUP YU RIEULMIEUM
+0x9568	0xBDFB	#HANGUL SYLLABLE PIEUP YU RIEULPIEUP
+0x9569	0xBDFC	#HANGUL SYLLABLE PIEUP YU RIEULSIOS
+0x956A	0xBDFD	#HANGUL SYLLABLE PIEUP YU RIEULTHIEUTH
+0x956B	0xBDFE	#HANGUL SYLLABLE PIEUP YU RIEULPHIEUPH
+0x956C	0xBDFF	#HANGUL SYLLABLE PIEUP YU RIEULHIEUH
+0x956D	0xBE01	#HANGUL SYLLABLE PIEUP YU PIEUP
+0x956E	0xBE02	#HANGUL SYLLABLE PIEUP YU PIEUPSIOS
+0x956F	0xBE04	#HANGUL SYLLABLE PIEUP YU SSANGSIOS
+0x9570	0xBE06	#HANGUL SYLLABLE PIEUP YU CIEUC
+0x9571	0xBE07	#HANGUL SYLLABLE PIEUP YU CHIEUCH
+0x9572	0xBE08	#HANGUL SYLLABLE PIEUP YU KHIEUKH
+0x9573	0xBE09	#HANGUL SYLLABLE PIEUP YU THIEUTH
+0x9574	0xBE0A	#HANGUL SYLLABLE PIEUP YU PHIEUPH
+0x9575	0xBE0B	#HANGUL SYLLABLE PIEUP YU HIEUH
+0x9576	0xBE0E	#HANGUL SYLLABLE PIEUP EU SSANGKIYEOK
+0x9577	0xBE0F	#HANGUL SYLLABLE PIEUP EU KIYEOKSIOS
+0x9578	0xBE11	#HANGUL SYLLABLE PIEUP EU NIEUNCIEUC
+0x9579	0xBE12	#HANGUL SYLLABLE PIEUP EU NIEUNHIEUH
+0x957A	0xBE13	#HANGUL SYLLABLE PIEUP EU TIKEUT
+0x9581	0xBE15	#HANGUL SYLLABLE PIEUP EU RIEULKIYEOK
+0x9582	0xBE16	#HANGUL SYLLABLE PIEUP EU RIEULMIEUM
+0x9583	0xBE17	#HANGUL SYLLABLE PIEUP EU RIEULPIEUP
+0x9584	0xBE18	#HANGUL SYLLABLE PIEUP EU RIEULSIOS
+0x9585	0xBE19	#HANGUL SYLLABLE PIEUP EU RIEULTHIEUTH
+0x9586	0xBE1A	#HANGUL SYLLABLE PIEUP EU RIEULPHIEUPH
+0x9587	0xBE1B	#HANGUL SYLLABLE PIEUP EU RIEULHIEUH
+0x9588	0xBE1E	#HANGUL SYLLABLE PIEUP EU PIEUPSIOS
+0x9589	0xBE20	#HANGUL SYLLABLE PIEUP EU SSANGSIOS
+0x958A	0xBE21	#HANGUL SYLLABLE PIEUP EU IEUNG
+0x958B	0xBE22	#HANGUL SYLLABLE PIEUP EU CIEUC
+0x958C	0xBE23	#HANGUL SYLLABLE PIEUP EU CHIEUCH
+0x958D	0xBE24	#HANGUL SYLLABLE PIEUP EU KHIEUKH
+0x958E	0xBE25	#HANGUL SYLLABLE PIEUP EU THIEUTH
+0x958F	0xBE26	#HANGUL SYLLABLE PIEUP EU PHIEUPH
+0x9590	0xBE27	#HANGUL SYLLABLE PIEUP EU HIEUH
+0x9591	0xBE28	#HANGUL SYLLABLE PIEUP YI
+0x9592	0xBE29	#HANGUL SYLLABLE PIEUP YI KIYEOK
+0x9593	0xBE2A	#HANGUL SYLLABLE PIEUP YI SSANGKIYEOK
+0x9594	0xBE2B	#HANGUL SYLLABLE PIEUP YI KIYEOKSIOS
+0x9595	0xBE2C	#HANGUL SYLLABLE PIEUP YI NIEUN
+0x9596	0xBE2D	#HANGUL SYLLABLE PIEUP YI NIEUNCIEUC
+0x9597	0xBE2E	#HANGUL SYLLABLE PIEUP YI NIEUNHIEUH
+0x9598	0xBE2F	#HANGUL SYLLABLE PIEUP YI TIKEUT
+0x9599	0xBE30	#HANGUL SYLLABLE PIEUP YI RIEUL
+0x959A	0xBE31	#HANGUL SYLLABLE PIEUP YI RIEULKIYEOK
+0x959B	0xBE32	#HANGUL SYLLABLE PIEUP YI RIEULMIEUM
+0x959C	0xBE33	#HANGUL SYLLABLE PIEUP YI RIEULPIEUP
+0x959D	0xBE34	#HANGUL SYLLABLE PIEUP YI RIEULSIOS
+0x959E	0xBE35	#HANGUL SYLLABLE PIEUP YI RIEULTHIEUTH
+0x959F	0xBE36	#HANGUL SYLLABLE PIEUP YI RIEULPHIEUPH
+0x95A0	0xBE37	#HANGUL SYLLABLE PIEUP YI RIEULHIEUH
+0x95A1	0xBE38	#HANGUL SYLLABLE PIEUP YI MIEUM
+0x95A2	0xBE39	#HANGUL SYLLABLE PIEUP YI PIEUP
+0x95A3	0xBE3A	#HANGUL SYLLABLE PIEUP YI PIEUPSIOS
+0x95A4	0xBE3B	#HANGUL SYLLABLE PIEUP YI SIOS
+0x95A5	0xBE3C	#HANGUL SYLLABLE PIEUP YI SSANGSIOS
+0x95A6	0xBE3D	#HANGUL SYLLABLE PIEUP YI IEUNG
+0x95A7	0xBE3E	#HANGUL SYLLABLE PIEUP YI CIEUC
+0x95A8	0xBE3F	#HANGUL SYLLABLE PIEUP YI CHIEUCH
+0x95A9	0xBE40	#HANGUL SYLLABLE PIEUP YI KHIEUKH
+0x95AA	0xBE41	#HANGUL SYLLABLE PIEUP YI THIEUTH
+0x95AB	0xBE42	#HANGUL SYLLABLE PIEUP YI PHIEUPH
+0x95AC	0xBE43	#HANGUL SYLLABLE PIEUP YI HIEUH
+0x95AD	0xBE46	#HANGUL SYLLABLE PIEUP I SSANGKIYEOK
+0x95AE	0xBE47	#HANGUL SYLLABLE PIEUP I KIYEOKSIOS
+0x95AF	0xBE49	#HANGUL SYLLABLE PIEUP I NIEUNCIEUC
+0x95B0	0xBE4A	#HANGUL SYLLABLE PIEUP I NIEUNHIEUH
+0x95B1	0xBE4B	#HANGUL SYLLABLE PIEUP I TIKEUT
+0x95B2	0xBE4D	#HANGUL SYLLABLE PIEUP I RIEULKIYEOK
+0x95B3	0xBE4F	#HANGUL SYLLABLE PIEUP I RIEULPIEUP
+0x95B4	0xBE50	#HANGUL SYLLABLE PIEUP I RIEULSIOS
+0x95B5	0xBE51	#HANGUL SYLLABLE PIEUP I RIEULTHIEUTH
+0x95B6	0xBE52	#HANGUL SYLLABLE PIEUP I RIEULPHIEUPH
+0x95B7	0xBE53	#HANGUL SYLLABLE PIEUP I RIEULHIEUH
+0x95B8	0xBE56	#HANGUL SYLLABLE PIEUP I PIEUPSIOS
+0x95B9	0xBE58	#HANGUL SYLLABLE PIEUP I SSANGSIOS
+0x95BA	0xBE5C	#HANGUL SYLLABLE PIEUP I KHIEUKH
+0x95BB	0xBE5D	#HANGUL SYLLABLE PIEUP I THIEUTH
+0x95BC	0xBE5E	#HANGUL SYLLABLE PIEUP I PHIEUPH
+0x95BD	0xBE5F	#HANGUL SYLLABLE PIEUP I HIEUH
+0x95BE	0xBE62	#HANGUL SYLLABLE SSANGPIEUP A SSANGKIYEOK
+0x95BF	0xBE63	#HANGUL SYLLABLE SSANGPIEUP A KIYEOKSIOS
+0x95C0	0xBE65	#HANGUL SYLLABLE SSANGPIEUP A NIEUNCIEUC
+0x95C1	0xBE66	#HANGUL SYLLABLE SSANGPIEUP A NIEUNHIEUH
+0x95C2	0xBE67	#HANGUL SYLLABLE SSANGPIEUP A TIKEUT
+0x95C3	0xBE69	#HANGUL SYLLABLE SSANGPIEUP A RIEULKIYEOK
+0x95C4	0xBE6B	#HANGUL SYLLABLE SSANGPIEUP A RIEULPIEUP
+0x95C5	0xBE6C	#HANGUL SYLLABLE SSANGPIEUP A RIEULSIOS
+0x95C6	0xBE6D	#HANGUL SYLLABLE SSANGPIEUP A RIEULTHIEUTH
+0x95C7	0xBE6E	#HANGUL SYLLABLE SSANGPIEUP A RIEULPHIEUPH
+0x95C8	0xBE6F	#HANGUL SYLLABLE SSANGPIEUP A RIEULHIEUH
+0x95C9	0xBE72	#HANGUL SYLLABLE SSANGPIEUP A PIEUPSIOS
+0x95CA	0xBE76	#HANGUL SYLLABLE SSANGPIEUP A CIEUC
+0x95CB	0xBE77	#HANGUL SYLLABLE SSANGPIEUP A CHIEUCH
+0x95CC	0xBE78	#HANGUL SYLLABLE SSANGPIEUP A KHIEUKH
+0x95CD	0xBE79	#HANGUL SYLLABLE SSANGPIEUP A THIEUTH
+0x95CE	0xBE7A	#HANGUL SYLLABLE SSANGPIEUP A PHIEUPH
+0x95CF	0xBE7E	#HANGUL SYLLABLE SSANGPIEUP AE SSANGKIYEOK
+0x95D0	0xBE7F	#HANGUL SYLLABLE SSANGPIEUP AE KIYEOKSIOS
+0x95D1	0xBE81	#HANGUL SYLLABLE SSANGPIEUP AE NIEUNCIEUC
+0x95D2	0xBE82	#HANGUL SYLLABLE SSANGPIEUP AE NIEUNHIEUH
+0x95D3	0xBE83	#HANGUL SYLLABLE SSANGPIEUP AE TIKEUT
+0x95D4	0xBE85	#HANGUL SYLLABLE SSANGPIEUP AE RIEULKIYEOK
+0x95D5	0xBE86	#HANGUL SYLLABLE SSANGPIEUP AE RIEULMIEUM
+0x95D6	0xBE87	#HANGUL SYLLABLE SSANGPIEUP AE RIEULPIEUP
+0x95D7	0xBE88	#HANGUL SYLLABLE SSANGPIEUP AE RIEULSIOS
+0x95D8	0xBE89	#HANGUL SYLLABLE SSANGPIEUP AE RIEULTHIEUTH
+0x95D9	0xBE8A	#HANGUL SYLLABLE SSANGPIEUP AE RIEULPHIEUPH
+0x95DA	0xBE8B	#HANGUL SYLLABLE SSANGPIEUP AE RIEULHIEUH
+0x95DB	0xBE8E	#HANGUL SYLLABLE SSANGPIEUP AE PIEUPSIOS
+0x95DC	0xBE92	#HANGUL SYLLABLE SSANGPIEUP AE CIEUC
+0x95DD	0xBE93	#HANGUL SYLLABLE SSANGPIEUP AE CHIEUCH
+0x95DE	0xBE94	#HANGUL SYLLABLE SSANGPIEUP AE KHIEUKH
+0x95DF	0xBE95	#HANGUL SYLLABLE SSANGPIEUP AE THIEUTH
+0x95E0	0xBE96	#HANGUL SYLLABLE SSANGPIEUP AE PHIEUPH
+0x95E1	0xBE97	#HANGUL SYLLABLE SSANGPIEUP AE HIEUH
+0x95E2	0xBE9A	#HANGUL SYLLABLE SSANGPIEUP YA SSANGKIYEOK
+0x95E3	0xBE9B	#HANGUL SYLLABLE SSANGPIEUP YA KIYEOKSIOS
+0x95E4	0xBE9C	#HANGUL SYLLABLE SSANGPIEUP YA NIEUN
+0x95E5	0xBE9D	#HANGUL SYLLABLE SSANGPIEUP YA NIEUNCIEUC
+0x95E6	0xBE9E	#HANGUL SYLLABLE SSANGPIEUP YA NIEUNHIEUH
+0x95E7	0xBE9F	#HANGUL SYLLABLE SSANGPIEUP YA TIKEUT
+0x95E8	0xBEA0	#HANGUL SYLLABLE SSANGPIEUP YA RIEUL
+0x95E9	0xBEA1	#HANGUL SYLLABLE SSANGPIEUP YA RIEULKIYEOK
+0x95EA	0xBEA2	#HANGUL SYLLABLE SSANGPIEUP YA RIEULMIEUM
+0x95EB	0xBEA3	#HANGUL SYLLABLE SSANGPIEUP YA RIEULPIEUP
+0x95EC	0xBEA4	#HANGUL SYLLABLE SSANGPIEUP YA RIEULSIOS
+0x95ED	0xBEA5	#HANGUL SYLLABLE SSANGPIEUP YA RIEULTHIEUTH
+0x95EE	0xBEA6	#HANGUL SYLLABLE SSANGPIEUP YA RIEULPHIEUPH
+0x95EF	0xBEA7	#HANGUL SYLLABLE SSANGPIEUP YA RIEULHIEUH
+0x95F0	0xBEA9	#HANGUL SYLLABLE SSANGPIEUP YA PIEUP
+0x95F1	0xBEAA	#HANGUL SYLLABLE SSANGPIEUP YA PIEUPSIOS
+0x95F2	0xBEAB	#HANGUL SYLLABLE SSANGPIEUP YA SIOS
+0x95F3	0xBEAC	#HANGUL SYLLABLE SSANGPIEUP YA SSANGSIOS
+0x95F4	0xBEAD	#HANGUL SYLLABLE SSANGPIEUP YA IEUNG
+0x95F5	0xBEAE	#HANGUL SYLLABLE SSANGPIEUP YA CIEUC
+0x95F6	0xBEAF	#HANGUL SYLLABLE SSANGPIEUP YA CHIEUCH
+0x95F7	0xBEB0	#HANGUL SYLLABLE SSANGPIEUP YA KHIEUKH
+0x95F8	0xBEB1	#HANGUL SYLLABLE SSANGPIEUP YA THIEUTH
+0x95F9	0xBEB2	#HANGUL SYLLABLE SSANGPIEUP YA PHIEUPH
+0x95FA	0xBEB3	#HANGUL SYLLABLE SSANGPIEUP YA HIEUH
+0x95FB	0xBEB4	#HANGUL SYLLABLE SSANGPIEUP YAE
+0x95FC	0xBEB5	#HANGUL SYLLABLE SSANGPIEUP YAE KIYEOK
+0x95FD	0xBEB6	#HANGUL SYLLABLE SSANGPIEUP YAE SSANGKIYEOK
+0x95FE	0xBEB7	#HANGUL SYLLABLE SSANGPIEUP YAE KIYEOKSIOS
+0x9641	0xBEB8	#HANGUL SYLLABLE SSANGPIEUP YAE NIEUN
+0x9642	0xBEB9	#HANGUL SYLLABLE SSANGPIEUP YAE NIEUNCIEUC
+0x9643	0xBEBA	#HANGUL SYLLABLE SSANGPIEUP YAE NIEUNHIEUH
+0x9644	0xBEBB	#HANGUL SYLLABLE SSANGPIEUP YAE TIKEUT
+0x9645	0xBEBC	#HANGUL SYLLABLE SSANGPIEUP YAE RIEUL
+0x9646	0xBEBD	#HANGUL SYLLABLE SSANGPIEUP YAE RIEULKIYEOK
+0x9647	0xBEBE	#HANGUL SYLLABLE SSANGPIEUP YAE RIEULMIEUM
+0x9648	0xBEBF	#HANGUL SYLLABLE SSANGPIEUP YAE RIEULPIEUP
+0x9649	0xBEC0	#HANGUL SYLLABLE SSANGPIEUP YAE RIEULSIOS
+0x964A	0xBEC1	#HANGUL SYLLABLE SSANGPIEUP YAE RIEULTHIEUTH
+0x964B	0xBEC2	#HANGUL SYLLABLE SSANGPIEUP YAE RIEULPHIEUPH
+0x964C	0xBEC3	#HANGUL SYLLABLE SSANGPIEUP YAE RIEULHIEUH
+0x964D	0xBEC4	#HANGUL SYLLABLE SSANGPIEUP YAE MIEUM
+0x964E	0xBEC5	#HANGUL SYLLABLE SSANGPIEUP YAE PIEUP
+0x964F	0xBEC6	#HANGUL SYLLABLE SSANGPIEUP YAE PIEUPSIOS
+0x9650	0xBEC7	#HANGUL SYLLABLE SSANGPIEUP YAE SIOS
+0x9651	0xBEC8	#HANGUL SYLLABLE SSANGPIEUP YAE SSANGSIOS
+0x9652	0xBEC9	#HANGUL SYLLABLE SSANGPIEUP YAE IEUNG
+0x9653	0xBECA	#HANGUL SYLLABLE SSANGPIEUP YAE CIEUC
+0x9654	0xBECB	#HANGUL SYLLABLE SSANGPIEUP YAE CHIEUCH
+0x9655	0xBECC	#HANGUL SYLLABLE SSANGPIEUP YAE KHIEUKH
+0x9656	0xBECD	#HANGUL SYLLABLE SSANGPIEUP YAE THIEUTH
+0x9657	0xBECE	#HANGUL SYLLABLE SSANGPIEUP YAE PHIEUPH
+0x9658	0xBECF	#HANGUL SYLLABLE SSANGPIEUP YAE HIEUH
+0x9659	0xBED2	#HANGUL SYLLABLE SSANGPIEUP EO SSANGKIYEOK
+0x965A	0xBED3	#HANGUL SYLLABLE SSANGPIEUP EO KIYEOKSIOS
+0x9661	0xBED5	#HANGUL SYLLABLE SSANGPIEUP EO NIEUNCIEUC
+0x9662	0xBED6	#HANGUL SYLLABLE SSANGPIEUP EO NIEUNHIEUH
+0x9663	0xBED9	#HANGUL SYLLABLE SSANGPIEUP EO RIEULKIYEOK
+0x9664	0xBEDA	#HANGUL SYLLABLE SSANGPIEUP EO RIEULMIEUM
+0x9665	0xBEDB	#HANGUL SYLLABLE SSANGPIEUP EO RIEULPIEUP
+0x9666	0xBEDC	#HANGUL SYLLABLE SSANGPIEUP EO RIEULSIOS
+0x9667	0xBEDD	#HANGUL SYLLABLE SSANGPIEUP EO RIEULTHIEUTH
+0x9668	0xBEDE	#HANGUL SYLLABLE SSANGPIEUP EO RIEULPHIEUPH
+0x9669	0xBEDF	#HANGUL SYLLABLE SSANGPIEUP EO RIEULHIEUH
+0x966A	0xBEE1	#HANGUL SYLLABLE SSANGPIEUP EO PIEUP
+0x966B	0xBEE2	#HANGUL SYLLABLE SSANGPIEUP EO PIEUPSIOS
+0x966C	0xBEE6	#HANGUL SYLLABLE SSANGPIEUP EO CIEUC
+0x966D	0xBEE7	#HANGUL SYLLABLE SSANGPIEUP EO CHIEUCH
+0x966E	0xBEE8	#HANGUL SYLLABLE SSANGPIEUP EO KHIEUKH
+0x966F	0xBEE9	#HANGUL SYLLABLE SSANGPIEUP EO THIEUTH
+0x9670	0xBEEA	#HANGUL SYLLABLE SSANGPIEUP EO PHIEUPH
+0x9671	0xBEEB	#HANGUL SYLLABLE SSANGPIEUP EO HIEUH
+0x9672	0xBEED	#HANGUL SYLLABLE SSANGPIEUP E KIYEOK
+0x9673	0xBEEE	#HANGUL SYLLABLE SSANGPIEUP E SSANGKIYEOK
+0x9674	0xBEEF	#HANGUL SYLLABLE SSANGPIEUP E KIYEOKSIOS
+0x9675	0xBEF0	#HANGUL SYLLABLE SSANGPIEUP E NIEUN
+0x9676	0xBEF1	#HANGUL SYLLABLE SSANGPIEUP E NIEUNCIEUC
+0x9677	0xBEF2	#HANGUL SYLLABLE SSANGPIEUP E NIEUNHIEUH
+0x9678	0xBEF3	#HANGUL SYLLABLE SSANGPIEUP E TIKEUT
+0x9679	0xBEF4	#HANGUL SYLLABLE SSANGPIEUP E RIEUL
+0x967A	0xBEF5	#HANGUL SYLLABLE SSANGPIEUP E RIEULKIYEOK
+0x9681	0xBEF6	#HANGUL SYLLABLE SSANGPIEUP E RIEULMIEUM
+0x9682	0xBEF7	#HANGUL SYLLABLE SSANGPIEUP E RIEULPIEUP
+0x9683	0xBEF8	#HANGUL SYLLABLE SSANGPIEUP E RIEULSIOS
+0x9684	0xBEF9	#HANGUL SYLLABLE SSANGPIEUP E RIEULTHIEUTH
+0x9685	0xBEFA	#HANGUL SYLLABLE SSANGPIEUP E RIEULPHIEUPH
+0x9686	0xBEFB	#HANGUL SYLLABLE SSANGPIEUP E RIEULHIEUH
+0x9687	0xBEFC	#HANGUL SYLLABLE SSANGPIEUP E MIEUM
+0x9688	0xBEFD	#HANGUL SYLLABLE SSANGPIEUP E PIEUP
+0x9689	0xBEFE	#HANGUL SYLLABLE SSANGPIEUP E PIEUPSIOS
+0x968A	0xBEFF	#HANGUL SYLLABLE SSANGPIEUP E SIOS
+0x968B	0xBF00	#HANGUL SYLLABLE SSANGPIEUP E SSANGSIOS
+0x968C	0xBF02	#HANGUL SYLLABLE SSANGPIEUP E CIEUC
+0x968D	0xBF03	#HANGUL SYLLABLE SSANGPIEUP E CHIEUCH
+0x968E	0xBF04	#HANGUL SYLLABLE SSANGPIEUP E KHIEUKH
+0x968F	0xBF05	#HANGUL SYLLABLE SSANGPIEUP E THIEUTH
+0x9690	0xBF06	#HANGUL SYLLABLE SSANGPIEUP E PHIEUPH
+0x9691	0xBF07	#HANGUL SYLLABLE SSANGPIEUP E HIEUH
+0x9692	0xBF0A	#HANGUL SYLLABLE SSANGPIEUP YEO SSANGKIYEOK
+0x9693	0xBF0B	#HANGUL SYLLABLE SSANGPIEUP YEO KIYEOKSIOS
+0x9694	0xBF0C	#HANGUL SYLLABLE SSANGPIEUP YEO NIEUN
+0x9695	0xBF0D	#HANGUL SYLLABLE SSANGPIEUP YEO NIEUNCIEUC
+0x9696	0xBF0E	#HANGUL SYLLABLE SSANGPIEUP YEO NIEUNHIEUH
+0x9697	0xBF0F	#HANGUL SYLLABLE SSANGPIEUP YEO TIKEUT
+0x9698	0xBF10	#HANGUL SYLLABLE SSANGPIEUP YEO RIEUL
+0x9699	0xBF11	#HANGUL SYLLABLE SSANGPIEUP YEO RIEULKIYEOK
+0x969A	0xBF12	#HANGUL SYLLABLE SSANGPIEUP YEO RIEULMIEUM
+0x969B	0xBF13	#HANGUL SYLLABLE SSANGPIEUP YEO RIEULPIEUP
+0x969C	0xBF14	#HANGUL SYLLABLE SSANGPIEUP YEO RIEULSIOS
+0x969D	0xBF15	#HANGUL SYLLABLE SSANGPIEUP YEO RIEULTHIEUTH
+0x969E	0xBF16	#HANGUL SYLLABLE SSANGPIEUP YEO RIEULPHIEUPH
+0x969F	0xBF17	#HANGUL SYLLABLE SSANGPIEUP YEO RIEULHIEUH
+0x96A0	0xBF1A	#HANGUL SYLLABLE SSANGPIEUP YEO PIEUPSIOS
+0x96A1	0xBF1E	#HANGUL SYLLABLE SSANGPIEUP YEO CIEUC
+0x96A2	0xBF1F	#HANGUL SYLLABLE SSANGPIEUP YEO CHIEUCH
+0x96A3	0xBF20	#HANGUL SYLLABLE SSANGPIEUP YEO KHIEUKH
+0x96A4	0xBF21	#HANGUL SYLLABLE SSANGPIEUP YEO THIEUTH
+0x96A5	0xBF22	#HANGUL SYLLABLE SSANGPIEUP YEO PHIEUPH
+0x96A6	0xBF23	#HANGUL SYLLABLE SSANGPIEUP YEO HIEUH
+0x96A7	0xBF24	#HANGUL SYLLABLE SSANGPIEUP YE
+0x96A8	0xBF25	#HANGUL SYLLABLE SSANGPIEUP YE KIYEOK
+0x96A9	0xBF26	#HANGUL SYLLABLE SSANGPIEUP YE SSANGKIYEOK
+0x96AA	0xBF27	#HANGUL SYLLABLE SSANGPIEUP YE KIYEOKSIOS
+0x96AB	0xBF28	#HANGUL SYLLABLE SSANGPIEUP YE NIEUN
+0x96AC	0xBF29	#HANGUL SYLLABLE SSANGPIEUP YE NIEUNCIEUC
+0x96AD	0xBF2A	#HANGUL SYLLABLE SSANGPIEUP YE NIEUNHIEUH
+0x96AE	0xBF2B	#HANGUL SYLLABLE SSANGPIEUP YE TIKEUT
+0x96AF	0xBF2C	#HANGUL SYLLABLE SSANGPIEUP YE RIEUL
+0x96B0	0xBF2D	#HANGUL SYLLABLE SSANGPIEUP YE RIEULKIYEOK
+0x96B1	0xBF2E	#HANGUL SYLLABLE SSANGPIEUP YE RIEULMIEUM
+0x96B2	0xBF2F	#HANGUL SYLLABLE SSANGPIEUP YE RIEULPIEUP
+0x96B3	0xBF30	#HANGUL SYLLABLE SSANGPIEUP YE RIEULSIOS
+0x96B4	0xBF31	#HANGUL SYLLABLE SSANGPIEUP YE RIEULTHIEUTH
+0x96B5	0xBF32	#HANGUL SYLLABLE SSANGPIEUP YE RIEULPHIEUPH
+0x96B6	0xBF33	#HANGUL SYLLABLE SSANGPIEUP YE RIEULHIEUH
+0x96B7	0xBF34	#HANGUL SYLLABLE SSANGPIEUP YE MIEUM
+0x96B8	0xBF35	#HANGUL SYLLABLE SSANGPIEUP YE PIEUP
+0x96B9	0xBF36	#HANGUL SYLLABLE SSANGPIEUP YE PIEUPSIOS
+0x96BA	0xBF37	#HANGUL SYLLABLE SSANGPIEUP YE SIOS
+0x96BB	0xBF38	#HANGUL SYLLABLE SSANGPIEUP YE SSANGSIOS
+0x96BC	0xBF39	#HANGUL SYLLABLE SSANGPIEUP YE IEUNG
+0x96BD	0xBF3A	#HANGUL SYLLABLE SSANGPIEUP YE CIEUC
+0x96BE	0xBF3B	#HANGUL SYLLABLE SSANGPIEUP YE CHIEUCH
+0x96BF	0xBF3C	#HANGUL SYLLABLE SSANGPIEUP YE KHIEUKH
+0x96C0	0xBF3D	#HANGUL SYLLABLE SSANGPIEUP YE THIEUTH
+0x96C1	0xBF3E	#HANGUL SYLLABLE SSANGPIEUP YE PHIEUPH
+0x96C2	0xBF3F	#HANGUL SYLLABLE SSANGPIEUP YE HIEUH
+0x96C3	0xBF42	#HANGUL SYLLABLE SSANGPIEUP O SSANGKIYEOK
+0x96C4	0xBF43	#HANGUL SYLLABLE SSANGPIEUP O KIYEOKSIOS
+0x96C5	0xBF45	#HANGUL SYLLABLE SSANGPIEUP O NIEUNCIEUC
+0x96C6	0xBF46	#HANGUL SYLLABLE SSANGPIEUP O NIEUNHIEUH
+0x96C7	0xBF47	#HANGUL SYLLABLE SSANGPIEUP O TIKEUT
+0x96C8	0xBF49	#HANGUL SYLLABLE SSANGPIEUP O RIEULKIYEOK
+0x96C9	0xBF4A	#HANGUL SYLLABLE SSANGPIEUP O RIEULMIEUM
+0x96CA	0xBF4B	#HANGUL SYLLABLE SSANGPIEUP O RIEULPIEUP
+0x96CB	0xBF4C	#HANGUL SYLLABLE SSANGPIEUP O RIEULSIOS
+0x96CC	0xBF4D	#HANGUL SYLLABLE SSANGPIEUP O RIEULTHIEUTH
+0x96CD	0xBF4E	#HANGUL SYLLABLE SSANGPIEUP O RIEULPHIEUPH
+0x96CE	0xBF4F	#HANGUL SYLLABLE SSANGPIEUP O RIEULHIEUH
+0x96CF	0xBF52	#HANGUL SYLLABLE SSANGPIEUP O PIEUPSIOS
+0x96D0	0xBF53	#HANGUL SYLLABLE SSANGPIEUP O SIOS
+0x96D1	0xBF54	#HANGUL SYLLABLE SSANGPIEUP O SSANGSIOS
+0x96D2	0xBF56	#HANGUL SYLLABLE SSANGPIEUP O CIEUC
+0x96D3	0xBF57	#HANGUL SYLLABLE SSANGPIEUP O CHIEUCH
+0x96D4	0xBF58	#HANGUL SYLLABLE SSANGPIEUP O KHIEUKH
+0x96D5	0xBF59	#HANGUL SYLLABLE SSANGPIEUP O THIEUTH
+0x96D6	0xBF5A	#HANGUL SYLLABLE SSANGPIEUP O PHIEUPH
+0x96D7	0xBF5B	#HANGUL SYLLABLE SSANGPIEUP O HIEUH
+0x96D8	0xBF5C	#HANGUL SYLLABLE SSANGPIEUP WA
+0x96D9	0xBF5D	#HANGUL SYLLABLE SSANGPIEUP WA KIYEOK
+0x96DA	0xBF5E	#HANGUL SYLLABLE SSANGPIEUP WA SSANGKIYEOK
+0x96DB	0xBF5F	#HANGUL SYLLABLE SSANGPIEUP WA KIYEOKSIOS
+0x96DC	0xBF60	#HANGUL SYLLABLE SSANGPIEUP WA NIEUN
+0x96DD	0xBF61	#HANGUL SYLLABLE SSANGPIEUP WA NIEUNCIEUC
+0x96DE	0xBF62	#HANGUL SYLLABLE SSANGPIEUP WA NIEUNHIEUH
+0x96DF	0xBF63	#HANGUL SYLLABLE SSANGPIEUP WA TIKEUT
+0x96E0	0xBF64	#HANGUL SYLLABLE SSANGPIEUP WA RIEUL
+0x96E1	0xBF65	#HANGUL SYLLABLE SSANGPIEUP WA RIEULKIYEOK
+0x96E2	0xBF66	#HANGUL SYLLABLE SSANGPIEUP WA RIEULMIEUM
+0x96E3	0xBF67	#HANGUL SYLLABLE SSANGPIEUP WA RIEULPIEUP
+0x96E4	0xBF68	#HANGUL SYLLABLE SSANGPIEUP WA RIEULSIOS
+0x96E5	0xBF69	#HANGUL SYLLABLE SSANGPIEUP WA RIEULTHIEUTH
+0x96E6	0xBF6A	#HANGUL SYLLABLE SSANGPIEUP WA RIEULPHIEUPH
+0x96E7	0xBF6B	#HANGUL SYLLABLE SSANGPIEUP WA RIEULHIEUH
+0x96E8	0xBF6C	#HANGUL SYLLABLE SSANGPIEUP WA MIEUM
+0x96E9	0xBF6D	#HANGUL SYLLABLE SSANGPIEUP WA PIEUP
+0x96EA	0xBF6E	#HANGUL SYLLABLE SSANGPIEUP WA PIEUPSIOS
+0x96EB	0xBF6F	#HANGUL SYLLABLE SSANGPIEUP WA SIOS
+0x96EC	0xBF70	#HANGUL SYLLABLE SSANGPIEUP WA SSANGSIOS
+0x96ED	0xBF71	#HANGUL SYLLABLE SSANGPIEUP WA IEUNG
+0x96EE	0xBF72	#HANGUL SYLLABLE SSANGPIEUP WA CIEUC
+0x96EF	0xBF73	#HANGUL SYLLABLE SSANGPIEUP WA CHIEUCH
+0x96F0	0xBF74	#HANGUL SYLLABLE SSANGPIEUP WA KHIEUKH
+0x96F1	0xBF75	#HANGUL SYLLABLE SSANGPIEUP WA THIEUTH
+0x96F2	0xBF76	#HANGUL SYLLABLE SSANGPIEUP WA PHIEUPH
+0x96F3	0xBF77	#HANGUL SYLLABLE SSANGPIEUP WA HIEUH
+0x96F4	0xBF78	#HANGUL SYLLABLE SSANGPIEUP WAE
+0x96F5	0xBF79	#HANGUL SYLLABLE SSANGPIEUP WAE KIYEOK
+0x96F6	0xBF7A	#HANGUL SYLLABLE SSANGPIEUP WAE SSANGKIYEOK
+0x96F7	0xBF7B	#HANGUL SYLLABLE SSANGPIEUP WAE KIYEOKSIOS
+0x96F8	0xBF7C	#HANGUL SYLLABLE SSANGPIEUP WAE NIEUN
+0x96F9	0xBF7D	#HANGUL SYLLABLE SSANGPIEUP WAE NIEUNCIEUC
+0x96FA	0xBF7E	#HANGUL SYLLABLE SSANGPIEUP WAE NIEUNHIEUH
+0x96FB	0xBF7F	#HANGUL SYLLABLE SSANGPIEUP WAE TIKEUT
+0x96FC	0xBF80	#HANGUL SYLLABLE SSANGPIEUP WAE RIEUL
+0x96FD	0xBF81	#HANGUL SYLLABLE SSANGPIEUP WAE RIEULKIYEOK
+0x96FE	0xBF82	#HANGUL SYLLABLE SSANGPIEUP WAE RIEULMIEUM
+0x9741	0xBF83	#HANGUL SYLLABLE SSANGPIEUP WAE RIEULPIEUP
+0x9742	0xBF84	#HANGUL SYLLABLE SSANGPIEUP WAE RIEULSIOS
+0x9743	0xBF85	#HANGUL SYLLABLE SSANGPIEUP WAE RIEULTHIEUTH
+0x9744	0xBF86	#HANGUL SYLLABLE SSANGPIEUP WAE RIEULPHIEUPH
+0x9745	0xBF87	#HANGUL SYLLABLE SSANGPIEUP WAE RIEULHIEUH
+0x9746	0xBF88	#HANGUL SYLLABLE SSANGPIEUP WAE MIEUM
+0x9747	0xBF89	#HANGUL SYLLABLE SSANGPIEUP WAE PIEUP
+0x9748	0xBF8A	#HANGUL SYLLABLE SSANGPIEUP WAE PIEUPSIOS
+0x9749	0xBF8B	#HANGUL SYLLABLE SSANGPIEUP WAE SIOS
+0x974A	0xBF8C	#HANGUL SYLLABLE SSANGPIEUP WAE SSANGSIOS
+0x974B	0xBF8D	#HANGUL SYLLABLE SSANGPIEUP WAE IEUNG
+0x974C	0xBF8E	#HANGUL SYLLABLE SSANGPIEUP WAE CIEUC
+0x974D	0xBF8F	#HANGUL SYLLABLE SSANGPIEUP WAE CHIEUCH
+0x974E	0xBF90	#HANGUL SYLLABLE SSANGPIEUP WAE KHIEUKH
+0x974F	0xBF91	#HANGUL SYLLABLE SSANGPIEUP WAE THIEUTH
+0x9750	0xBF92	#HANGUL SYLLABLE SSANGPIEUP WAE PHIEUPH
+0x9751	0xBF93	#HANGUL SYLLABLE SSANGPIEUP WAE HIEUH
+0x9752	0xBF95	#HANGUL SYLLABLE SSANGPIEUP OE KIYEOK
+0x9753	0xBF96	#HANGUL SYLLABLE SSANGPIEUP OE SSANGKIYEOK
+0x9754	0xBF97	#HANGUL SYLLABLE SSANGPIEUP OE KIYEOKSIOS
+0x9755	0xBF98	#HANGUL SYLLABLE SSANGPIEUP OE NIEUN
+0x9756	0xBF99	#HANGUL SYLLABLE SSANGPIEUP OE NIEUNCIEUC
+0x9757	0xBF9A	#HANGUL SYLLABLE SSANGPIEUP OE NIEUNHIEUH
+0x9758	0xBF9B	#HANGUL SYLLABLE SSANGPIEUP OE TIKEUT
+0x9759	0xBF9C	#HANGUL SYLLABLE SSANGPIEUP OE RIEUL
+0x975A	0xBF9D	#HANGUL SYLLABLE SSANGPIEUP OE RIEULKIYEOK
+0x9761	0xBF9E	#HANGUL SYLLABLE SSANGPIEUP OE RIEULMIEUM
+0x9762	0xBF9F	#HANGUL SYLLABLE SSANGPIEUP OE RIEULPIEUP
+0x9763	0xBFA0	#HANGUL SYLLABLE SSANGPIEUP OE RIEULSIOS
+0x9764	0xBFA1	#HANGUL SYLLABLE SSANGPIEUP OE RIEULTHIEUTH
+0x9765	0xBFA2	#HANGUL SYLLABLE SSANGPIEUP OE RIEULPHIEUPH
+0x9766	0xBFA3	#HANGUL SYLLABLE SSANGPIEUP OE RIEULHIEUH
+0x9767	0xBFA4	#HANGUL SYLLABLE SSANGPIEUP OE MIEUM
+0x9768	0xBFA5	#HANGUL SYLLABLE SSANGPIEUP OE PIEUP
+0x9769	0xBFA6	#HANGUL SYLLABLE SSANGPIEUP OE PIEUPSIOS
+0x976A	0xBFA7	#HANGUL SYLLABLE SSANGPIEUP OE SIOS
+0x976B	0xBFA8	#HANGUL SYLLABLE SSANGPIEUP OE SSANGSIOS
+0x976C	0xBFA9	#HANGUL SYLLABLE SSANGPIEUP OE IEUNG
+0x976D	0xBFAA	#HANGUL SYLLABLE SSANGPIEUP OE CIEUC
+0x976E	0xBFAB	#HANGUL SYLLABLE SSANGPIEUP OE CHIEUCH
+0x976F	0xBFAC	#HANGUL SYLLABLE SSANGPIEUP OE KHIEUKH
+0x9770	0xBFAD	#HANGUL SYLLABLE SSANGPIEUP OE THIEUTH
+0x9771	0xBFAE	#HANGUL SYLLABLE SSANGPIEUP OE PHIEUPH
+0x9772	0xBFAF	#HANGUL SYLLABLE SSANGPIEUP OE HIEUH
+0x9773	0xBFB1	#HANGUL SYLLABLE SSANGPIEUP YO KIYEOK
+0x9774	0xBFB2	#HANGUL SYLLABLE SSANGPIEUP YO SSANGKIYEOK
+0x9775	0xBFB3	#HANGUL SYLLABLE SSANGPIEUP YO KIYEOKSIOS
+0x9776	0xBFB4	#HANGUL SYLLABLE SSANGPIEUP YO NIEUN
+0x9777	0xBFB5	#HANGUL SYLLABLE SSANGPIEUP YO NIEUNCIEUC
+0x9778	0xBFB6	#HANGUL SYLLABLE SSANGPIEUP YO NIEUNHIEUH
+0x9779	0xBFB7	#HANGUL SYLLABLE SSANGPIEUP YO TIKEUT
+0x977A	0xBFB8	#HANGUL SYLLABLE SSANGPIEUP YO RIEUL
+0x9781	0xBFB9	#HANGUL SYLLABLE SSANGPIEUP YO RIEULKIYEOK
+0x9782	0xBFBA	#HANGUL SYLLABLE SSANGPIEUP YO RIEULMIEUM
+0x9783	0xBFBB	#HANGUL SYLLABLE SSANGPIEUP YO RIEULPIEUP
+0x9784	0xBFBC	#HANGUL SYLLABLE SSANGPIEUP YO RIEULSIOS
+0x9785	0xBFBD	#HANGUL SYLLABLE SSANGPIEUP YO RIEULTHIEUTH
+0x9786	0xBFBE	#HANGUL SYLLABLE SSANGPIEUP YO RIEULPHIEUPH
+0x9787	0xBFBF	#HANGUL SYLLABLE SSANGPIEUP YO RIEULHIEUH
+0x9788	0xBFC0	#HANGUL SYLLABLE SSANGPIEUP YO MIEUM
+0x9789	0xBFC1	#HANGUL SYLLABLE SSANGPIEUP YO PIEUP
+0x978A	0xBFC2	#HANGUL SYLLABLE SSANGPIEUP YO PIEUPSIOS
+0x978B	0xBFC3	#HANGUL SYLLABLE SSANGPIEUP YO SIOS
+0x978C	0xBFC4	#HANGUL SYLLABLE SSANGPIEUP YO SSANGSIOS
+0x978D	0xBFC6	#HANGUL SYLLABLE SSANGPIEUP YO CIEUC
+0x978E	0xBFC7	#HANGUL SYLLABLE SSANGPIEUP YO CHIEUCH
+0x978F	0xBFC8	#HANGUL SYLLABLE SSANGPIEUP YO KHIEUKH
+0x9790	0xBFC9	#HANGUL SYLLABLE SSANGPIEUP YO THIEUTH
+0x9791	0xBFCA	#HANGUL SYLLABLE SSANGPIEUP YO PHIEUPH
+0x9792	0xBFCB	#HANGUL SYLLABLE SSANGPIEUP YO HIEUH
+0x9793	0xBFCE	#HANGUL SYLLABLE SSANGPIEUP U SSANGKIYEOK
+0x9794	0xBFCF	#HANGUL SYLLABLE SSANGPIEUP U KIYEOKSIOS
+0x9795	0xBFD1	#HANGUL SYLLABLE SSANGPIEUP U NIEUNCIEUC
+0x9796	0xBFD2	#HANGUL SYLLABLE SSANGPIEUP U NIEUNHIEUH
+0x9797	0xBFD3	#HANGUL SYLLABLE SSANGPIEUP U TIKEUT
+0x9798	0xBFD5	#HANGUL SYLLABLE SSANGPIEUP U RIEULKIYEOK
+0x9799	0xBFD6	#HANGUL SYLLABLE SSANGPIEUP U RIEULMIEUM
+0x979A	0xBFD7	#HANGUL SYLLABLE SSANGPIEUP U RIEULPIEUP
+0x979B	0xBFD8	#HANGUL SYLLABLE SSANGPIEUP U RIEULSIOS
+0x979C	0xBFD9	#HANGUL SYLLABLE SSANGPIEUP U RIEULTHIEUTH
+0x979D	0xBFDA	#HANGUL SYLLABLE SSANGPIEUP U RIEULPHIEUPH
+0x979E	0xBFDB	#HANGUL SYLLABLE SSANGPIEUP U RIEULHIEUH
+0x979F	0xBFDD	#HANGUL SYLLABLE SSANGPIEUP U PIEUP
+0x97A0	0xBFDE	#HANGUL SYLLABLE SSANGPIEUP U PIEUPSIOS
+0x97A1	0xBFE0	#HANGUL SYLLABLE SSANGPIEUP U SSANGSIOS
+0x97A2	0xBFE2	#HANGUL SYLLABLE SSANGPIEUP U CIEUC
+0x97A3	0xBFE3	#HANGUL SYLLABLE SSANGPIEUP U CHIEUCH
+0x97A4	0xBFE4	#HANGUL SYLLABLE SSANGPIEUP U KHIEUKH
+0x97A5	0xBFE5	#HANGUL SYLLABLE SSANGPIEUP U THIEUTH
+0x97A6	0xBFE6	#HANGUL SYLLABLE SSANGPIEUP U PHIEUPH
+0x97A7	0xBFE7	#HANGUL SYLLABLE SSANGPIEUP U HIEUH
+0x97A8	0xBFE8	#HANGUL SYLLABLE SSANGPIEUP WEO
+0x97A9	0xBFE9	#HANGUL SYLLABLE SSANGPIEUP WEO KIYEOK
+0x97AA	0xBFEA	#HANGUL SYLLABLE SSANGPIEUP WEO SSANGKIYEOK
+0x97AB	0xBFEB	#HANGUL SYLLABLE SSANGPIEUP WEO KIYEOKSIOS
+0x97AC	0xBFEC	#HANGUL SYLLABLE SSANGPIEUP WEO NIEUN
+0x97AD	0xBFED	#HANGUL SYLLABLE SSANGPIEUP WEO NIEUNCIEUC
+0x97AE	0xBFEE	#HANGUL SYLLABLE SSANGPIEUP WEO NIEUNHIEUH
+0x97AF	0xBFEF	#HANGUL SYLLABLE SSANGPIEUP WEO TIKEUT
+0x97B0	0xBFF0	#HANGUL SYLLABLE SSANGPIEUP WEO RIEUL
+0x97B1	0xBFF1	#HANGUL SYLLABLE SSANGPIEUP WEO RIEULKIYEOK
+0x97B2	0xBFF2	#HANGUL SYLLABLE SSANGPIEUP WEO RIEULMIEUM
+0x97B3	0xBFF3	#HANGUL SYLLABLE SSANGPIEUP WEO RIEULPIEUP
+0x97B4	0xBFF4	#HANGUL SYLLABLE SSANGPIEUP WEO RIEULSIOS
+0x97B5	0xBFF5	#HANGUL SYLLABLE SSANGPIEUP WEO RIEULTHIEUTH
+0x97B6	0xBFF6	#HANGUL SYLLABLE SSANGPIEUP WEO RIEULPHIEUPH
+0x97B7	0xBFF7	#HANGUL SYLLABLE SSANGPIEUP WEO RIEULHIEUH
+0x97B8	0xBFF8	#HANGUL SYLLABLE SSANGPIEUP WEO MIEUM
+0x97B9	0xBFF9	#HANGUL SYLLABLE SSANGPIEUP WEO PIEUP
+0x97BA	0xBFFA	#HANGUL SYLLABLE SSANGPIEUP WEO PIEUPSIOS
+0x97BB	0xBFFB	#HANGUL SYLLABLE SSANGPIEUP WEO SIOS
+0x97BC	0xBFFC	#HANGUL SYLLABLE SSANGPIEUP WEO SSANGSIOS
+0x97BD	0xBFFD	#HANGUL SYLLABLE SSANGPIEUP WEO IEUNG
+0x97BE	0xBFFE	#HANGUL SYLLABLE SSANGPIEUP WEO CIEUC
+0x97BF	0xBFFF	#HANGUL SYLLABLE SSANGPIEUP WEO CHIEUCH
+0x97C0	0xC000	#HANGUL SYLLABLE SSANGPIEUP WEO KHIEUKH
+0x97C1	0xC001	#HANGUL SYLLABLE SSANGPIEUP WEO THIEUTH
+0x97C2	0xC002	#HANGUL SYLLABLE SSANGPIEUP WEO PHIEUPH
+0x97C3	0xC003	#HANGUL SYLLABLE SSANGPIEUP WEO HIEUH
+0x97C4	0xC004	#HANGUL SYLLABLE SSANGPIEUP WE
+0x97C5	0xC005	#HANGUL SYLLABLE SSANGPIEUP WE KIYEOK
+0x97C6	0xC006	#HANGUL SYLLABLE SSANGPIEUP WE SSANGKIYEOK
+0x97C7	0xC007	#HANGUL SYLLABLE SSANGPIEUP WE KIYEOKSIOS
+0x97C8	0xC008	#HANGUL SYLLABLE SSANGPIEUP WE NIEUN
+0x97C9	0xC009	#HANGUL SYLLABLE SSANGPIEUP WE NIEUNCIEUC
+0x97CA	0xC00A	#HANGUL SYLLABLE SSANGPIEUP WE NIEUNHIEUH
+0x97CB	0xC00B	#HANGUL SYLLABLE SSANGPIEUP WE TIKEUT
+0x97CC	0xC00C	#HANGUL SYLLABLE SSANGPIEUP WE RIEUL
+0x97CD	0xC00D	#HANGUL SYLLABLE SSANGPIEUP WE RIEULKIYEOK
+0x97CE	0xC00E	#HANGUL SYLLABLE SSANGPIEUP WE RIEULMIEUM
+0x97CF	0xC00F	#HANGUL SYLLABLE SSANGPIEUP WE RIEULPIEUP
+0x97D0	0xC010	#HANGUL SYLLABLE SSANGPIEUP WE RIEULSIOS
+0x97D1	0xC011	#HANGUL SYLLABLE SSANGPIEUP WE RIEULTHIEUTH
+0x97D2	0xC012	#HANGUL SYLLABLE SSANGPIEUP WE RIEULPHIEUPH
+0x97D3	0xC013	#HANGUL SYLLABLE SSANGPIEUP WE RIEULHIEUH
+0x97D4	0xC014	#HANGUL SYLLABLE SSANGPIEUP WE MIEUM
+0x97D5	0xC015	#HANGUL SYLLABLE SSANGPIEUP WE PIEUP
+0x97D6	0xC016	#HANGUL SYLLABLE SSANGPIEUP WE PIEUPSIOS
+0x97D7	0xC017	#HANGUL SYLLABLE SSANGPIEUP WE SIOS
+0x97D8	0xC018	#HANGUL SYLLABLE SSANGPIEUP WE SSANGSIOS
+0x97D9	0xC019	#HANGUL SYLLABLE SSANGPIEUP WE IEUNG
+0x97DA	0xC01A	#HANGUL SYLLABLE SSANGPIEUP WE CIEUC
+0x97DB	0xC01B	#HANGUL SYLLABLE SSANGPIEUP WE CHIEUCH
+0x97DC	0xC01C	#HANGUL SYLLABLE SSANGPIEUP WE KHIEUKH
+0x97DD	0xC01D	#HANGUL SYLLABLE SSANGPIEUP WE THIEUTH
+0x97DE	0xC01E	#HANGUL SYLLABLE SSANGPIEUP WE PHIEUPH
+0x97DF	0xC01F	#HANGUL SYLLABLE SSANGPIEUP WE HIEUH
+0x97E0	0xC020	#HANGUL SYLLABLE SSANGPIEUP WI
+0x97E1	0xC021	#HANGUL SYLLABLE SSANGPIEUP WI KIYEOK
+0x97E2	0xC022	#HANGUL SYLLABLE SSANGPIEUP WI SSANGKIYEOK
+0x97E3	0xC023	#HANGUL SYLLABLE SSANGPIEUP WI KIYEOKSIOS
+0x97E4	0xC024	#HANGUL SYLLABLE SSANGPIEUP WI NIEUN
+0x97E5	0xC025	#HANGUL SYLLABLE SSANGPIEUP WI NIEUNCIEUC
+0x97E6	0xC026	#HANGUL SYLLABLE SSANGPIEUP WI NIEUNHIEUH
+0x97E7	0xC027	#HANGUL SYLLABLE SSANGPIEUP WI TIKEUT
+0x97E8	0xC028	#HANGUL SYLLABLE SSANGPIEUP WI RIEUL
+0x97E9	0xC029	#HANGUL SYLLABLE SSANGPIEUP WI RIEULKIYEOK
+0x97EA	0xC02A	#HANGUL SYLLABLE SSANGPIEUP WI RIEULMIEUM
+0x97EB	0xC02B	#HANGUL SYLLABLE SSANGPIEUP WI RIEULPIEUP
+0x97EC	0xC02C	#HANGUL SYLLABLE SSANGPIEUP WI RIEULSIOS
+0x97ED	0xC02D	#HANGUL SYLLABLE SSANGPIEUP WI RIEULTHIEUTH
+0x97EE	0xC02E	#HANGUL SYLLABLE SSANGPIEUP WI RIEULPHIEUPH
+0x97EF	0xC02F	#HANGUL SYLLABLE SSANGPIEUP WI RIEULHIEUH
+0x97F0	0xC030	#HANGUL SYLLABLE SSANGPIEUP WI MIEUM
+0x97F1	0xC031	#HANGUL SYLLABLE SSANGPIEUP WI PIEUP
+0x97F2	0xC032	#HANGUL SYLLABLE SSANGPIEUP WI PIEUPSIOS
+0x97F3	0xC033	#HANGUL SYLLABLE SSANGPIEUP WI SIOS
+0x97F4	0xC034	#HANGUL SYLLABLE SSANGPIEUP WI SSANGSIOS
+0x97F5	0xC035	#HANGUL SYLLABLE SSANGPIEUP WI IEUNG
+0x97F6	0xC036	#HANGUL SYLLABLE SSANGPIEUP WI CIEUC
+0x97F7	0xC037	#HANGUL SYLLABLE SSANGPIEUP WI CHIEUCH
+0x97F8	0xC038	#HANGUL SYLLABLE SSANGPIEUP WI KHIEUKH
+0x97F9	0xC039	#HANGUL SYLLABLE SSANGPIEUP WI THIEUTH
+0x97FA	0xC03A	#HANGUL SYLLABLE SSANGPIEUP WI PHIEUPH
+0x97FB	0xC03B	#HANGUL SYLLABLE SSANGPIEUP WI HIEUH
+0x97FC	0xC03D	#HANGUL SYLLABLE SSANGPIEUP YU KIYEOK
+0x97FD	0xC03E	#HANGUL SYLLABLE SSANGPIEUP YU SSANGKIYEOK
+0x97FE	0xC03F	#HANGUL SYLLABLE SSANGPIEUP YU KIYEOKSIOS
+0x9841	0xC040	#HANGUL SYLLABLE SSANGPIEUP YU NIEUN
+0x9842	0xC041	#HANGUL SYLLABLE SSANGPIEUP YU NIEUNCIEUC
+0x9843	0xC042	#HANGUL SYLLABLE SSANGPIEUP YU NIEUNHIEUH
+0x9844	0xC043	#HANGUL SYLLABLE SSANGPIEUP YU TIKEUT
+0x9845	0xC044	#HANGUL SYLLABLE SSANGPIEUP YU RIEUL
+0x9846	0xC045	#HANGUL SYLLABLE SSANGPIEUP YU RIEULKIYEOK
+0x9847	0xC046	#HANGUL SYLLABLE SSANGPIEUP YU RIEULMIEUM
+0x9848	0xC047	#HANGUL SYLLABLE SSANGPIEUP YU RIEULPIEUP
+0x9849	0xC048	#HANGUL SYLLABLE SSANGPIEUP YU RIEULSIOS
+0x984A	0xC049	#HANGUL SYLLABLE SSANGPIEUP YU RIEULTHIEUTH
+0x984B	0xC04A	#HANGUL SYLLABLE SSANGPIEUP YU RIEULPHIEUPH
+0x984C	0xC04B	#HANGUL SYLLABLE SSANGPIEUP YU RIEULHIEUH
+0x984D	0xC04C	#HANGUL SYLLABLE SSANGPIEUP YU MIEUM
+0x984E	0xC04D	#HANGUL SYLLABLE SSANGPIEUP YU PIEUP
+0x984F	0xC04E	#HANGUL SYLLABLE SSANGPIEUP YU PIEUPSIOS
+0x9850	0xC04F	#HANGUL SYLLABLE SSANGPIEUP YU SIOS
+0x9851	0xC050	#HANGUL SYLLABLE SSANGPIEUP YU SSANGSIOS
+0x9852	0xC052	#HANGUL SYLLABLE SSANGPIEUP YU CIEUC
+0x9853	0xC053	#HANGUL SYLLABLE SSANGPIEUP YU CHIEUCH
+0x9854	0xC054	#HANGUL SYLLABLE SSANGPIEUP YU KHIEUKH
+0x9855	0xC055	#HANGUL SYLLABLE SSANGPIEUP YU THIEUTH
+0x9856	0xC056	#HANGUL SYLLABLE SSANGPIEUP YU PHIEUPH
+0x9857	0xC057	#HANGUL SYLLABLE SSANGPIEUP YU HIEUH
+0x9858	0xC059	#HANGUL SYLLABLE SSANGPIEUP EU KIYEOK
+0x9859	0xC05A	#HANGUL SYLLABLE SSANGPIEUP EU SSANGKIYEOK
+0x985A	0xC05B	#HANGUL SYLLABLE SSANGPIEUP EU KIYEOKSIOS
+0x9861	0xC05D	#HANGUL SYLLABLE SSANGPIEUP EU NIEUNCIEUC
+0x9862	0xC05E	#HANGUL SYLLABLE SSANGPIEUP EU NIEUNHIEUH
+0x9863	0xC05F	#HANGUL SYLLABLE SSANGPIEUP EU TIKEUT
+0x9864	0xC061	#HANGUL SYLLABLE SSANGPIEUP EU RIEULKIYEOK
+0x9865	0xC062	#HANGUL SYLLABLE SSANGPIEUP EU RIEULMIEUM
+0x9866	0xC063	#HANGUL SYLLABLE SSANGPIEUP EU RIEULPIEUP
+0x9867	0xC064	#HANGUL SYLLABLE SSANGPIEUP EU RIEULSIOS
+0x9868	0xC065	#HANGUL SYLLABLE SSANGPIEUP EU RIEULTHIEUTH
+0x9869	0xC066	#HANGUL SYLLABLE SSANGPIEUP EU RIEULPHIEUPH
+0x986A	0xC067	#HANGUL SYLLABLE SSANGPIEUP EU RIEULHIEUH
+0x986B	0xC06A	#HANGUL SYLLABLE SSANGPIEUP EU PIEUPSIOS
+0x986C	0xC06B	#HANGUL SYLLABLE SSANGPIEUP EU SIOS
+0x986D	0xC06C	#HANGUL SYLLABLE SSANGPIEUP EU SSANGSIOS
+0x986E	0xC06D	#HANGUL SYLLABLE SSANGPIEUP EU IEUNG
+0x986F	0xC06E	#HANGUL SYLLABLE SSANGPIEUP EU CIEUC
+0x9870	0xC06F	#HANGUL SYLLABLE SSANGPIEUP EU CHIEUCH
+0x9871	0xC070	#HANGUL SYLLABLE SSANGPIEUP EU KHIEUKH
+0x9872	0xC071	#HANGUL SYLLABLE SSANGPIEUP EU THIEUTH
+0x9873	0xC072	#HANGUL SYLLABLE SSANGPIEUP EU PHIEUPH
+0x9874	0xC073	#HANGUL SYLLABLE SSANGPIEUP EU HIEUH
+0x9875	0xC074	#HANGUL SYLLABLE SSANGPIEUP YI
+0x9876	0xC075	#HANGUL SYLLABLE SSANGPIEUP YI KIYEOK
+0x9877	0xC076	#HANGUL SYLLABLE SSANGPIEUP YI SSANGKIYEOK
+0x9878	0xC077	#HANGUL SYLLABLE SSANGPIEUP YI KIYEOKSIOS
+0x9879	0xC078	#HANGUL SYLLABLE SSANGPIEUP YI NIEUN
+0x987A	0xC079	#HANGUL SYLLABLE SSANGPIEUP YI NIEUNCIEUC
+0x9881	0xC07A	#HANGUL SYLLABLE SSANGPIEUP YI NIEUNHIEUH
+0x9882	0xC07B	#HANGUL SYLLABLE SSANGPIEUP YI TIKEUT
+0x9883	0xC07C	#HANGUL SYLLABLE SSANGPIEUP YI RIEUL
+0x9884	0xC07D	#HANGUL SYLLABLE SSANGPIEUP YI RIEULKIYEOK
+0x9885	0xC07E	#HANGUL SYLLABLE SSANGPIEUP YI RIEULMIEUM
+0x9886	0xC07F	#HANGUL SYLLABLE SSANGPIEUP YI RIEULPIEUP
+0x9887	0xC080	#HANGUL SYLLABLE SSANGPIEUP YI RIEULSIOS
+0x9888	0xC081	#HANGUL SYLLABLE SSANGPIEUP YI RIEULTHIEUTH
+0x9889	0xC082	#HANGUL SYLLABLE SSANGPIEUP YI RIEULPHIEUPH
+0x988A	0xC083	#HANGUL SYLLABLE SSANGPIEUP YI RIEULHIEUH
+0x988B	0xC084	#HANGUL SYLLABLE SSANGPIEUP YI MIEUM
+0x988C	0xC085	#HANGUL SYLLABLE SSANGPIEUP YI PIEUP
+0x988D	0xC086	#HANGUL SYLLABLE SSANGPIEUP YI PIEUPSIOS
+0x988E	0xC087	#HANGUL SYLLABLE SSANGPIEUP YI SIOS
+0x988F	0xC088	#HANGUL SYLLABLE SSANGPIEUP YI SSANGSIOS
+0x9890	0xC089	#HANGUL SYLLABLE SSANGPIEUP YI IEUNG
+0x9891	0xC08A	#HANGUL SYLLABLE SSANGPIEUP YI CIEUC
+0x9892	0xC08B	#HANGUL SYLLABLE SSANGPIEUP YI CHIEUCH
+0x9893	0xC08C	#HANGUL SYLLABLE SSANGPIEUP YI KHIEUKH
+0x9894	0xC08D	#HANGUL SYLLABLE SSANGPIEUP YI THIEUTH
+0x9895	0xC08E	#HANGUL SYLLABLE SSANGPIEUP YI PHIEUPH
+0x9896	0xC08F	#HANGUL SYLLABLE SSANGPIEUP YI HIEUH
+0x9897	0xC092	#HANGUL SYLLABLE SSANGPIEUP I SSANGKIYEOK
+0x9898	0xC093	#HANGUL SYLLABLE SSANGPIEUP I KIYEOKSIOS
+0x9899	0xC095	#HANGUL SYLLABLE SSANGPIEUP I NIEUNCIEUC
+0x989A	0xC096	#HANGUL SYLLABLE SSANGPIEUP I NIEUNHIEUH
+0x989B	0xC097	#HANGUL SYLLABLE SSANGPIEUP I TIKEUT
+0x989C	0xC099	#HANGUL SYLLABLE SSANGPIEUP I RIEULKIYEOK
+0x989D	0xC09A	#HANGUL SYLLABLE SSANGPIEUP I RIEULMIEUM
+0x989E	0xC09B	#HANGUL SYLLABLE SSANGPIEUP I RIEULPIEUP
+0x989F	0xC09C	#HANGUL SYLLABLE SSANGPIEUP I RIEULSIOS
+0x98A0	0xC09D	#HANGUL SYLLABLE SSANGPIEUP I RIEULTHIEUTH
+0x98A1	0xC09E	#HANGUL SYLLABLE SSANGPIEUP I RIEULPHIEUPH
+0x98A2	0xC09F	#HANGUL SYLLABLE SSANGPIEUP I RIEULHIEUH
+0x98A3	0xC0A2	#HANGUL SYLLABLE SSANGPIEUP I PIEUPSIOS
+0x98A4	0xC0A4	#HANGUL SYLLABLE SSANGPIEUP I SSANGSIOS
+0x98A5	0xC0A6	#HANGUL SYLLABLE SSANGPIEUP I CIEUC
+0x98A6	0xC0A7	#HANGUL SYLLABLE SSANGPIEUP I CHIEUCH
+0x98A7	0xC0A8	#HANGUL SYLLABLE SSANGPIEUP I KHIEUKH
+0x98A8	0xC0A9	#HANGUL SYLLABLE SSANGPIEUP I THIEUTH
+0x98A9	0xC0AA	#HANGUL SYLLABLE SSANGPIEUP I PHIEUPH
+0x98AA	0xC0AB	#HANGUL SYLLABLE SSANGPIEUP I HIEUH
+0x98AB	0xC0AE	#HANGUL SYLLABLE SIOS A SSANGKIYEOK
+0x98AC	0xC0B1	#HANGUL SYLLABLE SIOS A NIEUNCIEUC
+0x98AD	0xC0B2	#HANGUL SYLLABLE SIOS A NIEUNHIEUH
+0x98AE	0xC0B7	#HANGUL SYLLABLE SIOS A RIEULPIEUP
+0x98AF	0xC0B8	#HANGUL SYLLABLE SIOS A RIEULSIOS
+0x98B0	0xC0B9	#HANGUL SYLLABLE SIOS A RIEULTHIEUTH
+0x98B1	0xC0BA	#HANGUL SYLLABLE SIOS A RIEULPHIEUPH
+0x98B2	0xC0BB	#HANGUL SYLLABLE SIOS A RIEULHIEUH
+0x98B3	0xC0BE	#HANGUL SYLLABLE SIOS A PIEUPSIOS
+0x98B4	0xC0C2	#HANGUL SYLLABLE SIOS A CIEUC
+0x98B5	0xC0C3	#HANGUL SYLLABLE SIOS A CHIEUCH
+0x98B6	0xC0C4	#HANGUL SYLLABLE SIOS A KHIEUKH
+0x98B7	0xC0C6	#HANGUL SYLLABLE SIOS A PHIEUPH
+0x98B8	0xC0C7	#HANGUL SYLLABLE SIOS A HIEUH
+0x98B9	0xC0CA	#HANGUL SYLLABLE SIOS AE SSANGKIYEOK
+0x98BA	0xC0CB	#HANGUL SYLLABLE SIOS AE KIYEOKSIOS
+0x98BB	0xC0CD	#HANGUL SYLLABLE SIOS AE NIEUNCIEUC
+0x98BC	0xC0CE	#HANGUL SYLLABLE SIOS AE NIEUNHIEUH
+0x98BD	0xC0CF	#HANGUL SYLLABLE SIOS AE TIKEUT
+0x98BE	0xC0D1	#HANGUL SYLLABLE SIOS AE RIEULKIYEOK
+0x98BF	0xC0D2	#HANGUL SYLLABLE SIOS AE RIEULMIEUM
+0x98C0	0xC0D3	#HANGUL SYLLABLE SIOS AE RIEULPIEUP
+0x98C1	0xC0D4	#HANGUL SYLLABLE SIOS AE RIEULSIOS
+0x98C2	0xC0D5	#HANGUL SYLLABLE SIOS AE RIEULTHIEUTH
+0x98C3	0xC0D6	#HANGUL SYLLABLE SIOS AE RIEULPHIEUPH
+0x98C4	0xC0D7	#HANGUL SYLLABLE SIOS AE RIEULHIEUH
+0x98C5	0xC0DA	#HANGUL SYLLABLE SIOS AE PIEUPSIOS
+0x98C6	0xC0DE	#HANGUL SYLLABLE SIOS AE CIEUC
+0x98C7	0xC0DF	#HANGUL SYLLABLE SIOS AE CHIEUCH
+0x98C8	0xC0E0	#HANGUL SYLLABLE SIOS AE KHIEUKH
+0x98C9	0xC0E1	#HANGUL SYLLABLE SIOS AE THIEUTH
+0x98CA	0xC0E2	#HANGUL SYLLABLE SIOS AE PHIEUPH
+0x98CB	0xC0E3	#HANGUL SYLLABLE SIOS AE HIEUH
+0x98CC	0xC0E6	#HANGUL SYLLABLE SIOS YA SSANGKIYEOK
+0x98CD	0xC0E7	#HANGUL SYLLABLE SIOS YA KIYEOKSIOS
+0x98CE	0xC0E9	#HANGUL SYLLABLE SIOS YA NIEUNCIEUC
+0x98CF	0xC0EA	#HANGUL SYLLABLE SIOS YA NIEUNHIEUH
+0x98D0	0xC0EB	#HANGUL SYLLABLE SIOS YA TIKEUT
+0x98D1	0xC0ED	#HANGUL SYLLABLE SIOS YA RIEULKIYEOK
+0x98D2	0xC0EE	#HANGUL SYLLABLE SIOS YA RIEULMIEUM
+0x98D3	0xC0EF	#HANGUL SYLLABLE SIOS YA RIEULPIEUP
+0x98D4	0xC0F0	#HANGUL SYLLABLE SIOS YA RIEULSIOS
+0x98D5	0xC0F1	#HANGUL SYLLABLE SIOS YA RIEULTHIEUTH
+0x98D6	0xC0F2	#HANGUL SYLLABLE SIOS YA RIEULPHIEUPH
+0x98D7	0xC0F3	#HANGUL SYLLABLE SIOS YA RIEULHIEUH
+0x98D8	0xC0F6	#HANGUL SYLLABLE SIOS YA PIEUPSIOS
+0x98D9	0xC0F8	#HANGUL SYLLABLE SIOS YA SSANGSIOS
+0x98DA	0xC0FA	#HANGUL SYLLABLE SIOS YA CIEUC
+0x98DB	0xC0FB	#HANGUL SYLLABLE SIOS YA CHIEUCH
+0x98DC	0xC0FC	#HANGUL SYLLABLE SIOS YA KHIEUKH
+0x98DD	0xC0FD	#HANGUL SYLLABLE SIOS YA THIEUTH
+0x98DE	0xC0FE	#HANGUL SYLLABLE SIOS YA PHIEUPH
+0x98DF	0xC0FF	#HANGUL SYLLABLE SIOS YA HIEUH
+0x98E0	0xC101	#HANGUL SYLLABLE SIOS YAE KIYEOK
+0x98E1	0xC102	#HANGUL SYLLABLE SIOS YAE SSANGKIYEOK
+0x98E2	0xC103	#HANGUL SYLLABLE SIOS YAE KIYEOKSIOS
+0x98E3	0xC105	#HANGUL SYLLABLE SIOS YAE NIEUNCIEUC
+0x98E4	0xC106	#HANGUL SYLLABLE SIOS YAE NIEUNHIEUH
+0x98E5	0xC107	#HANGUL SYLLABLE SIOS YAE TIKEUT
+0x98E6	0xC109	#HANGUL SYLLABLE SIOS YAE RIEULKIYEOK
+0x98E7	0xC10A	#HANGUL SYLLABLE SIOS YAE RIEULMIEUM
+0x98E8	0xC10B	#HANGUL SYLLABLE SIOS YAE RIEULPIEUP
+0x98E9	0xC10C	#HANGUL SYLLABLE SIOS YAE RIEULSIOS
+0x98EA	0xC10D	#HANGUL SYLLABLE SIOS YAE RIEULTHIEUTH
+0x98EB	0xC10E	#HANGUL SYLLABLE SIOS YAE RIEULPHIEUPH
+0x98EC	0xC10F	#HANGUL SYLLABLE SIOS YAE RIEULHIEUH
+0x98ED	0xC111	#HANGUL SYLLABLE SIOS YAE PIEUP
+0x98EE	0xC112	#HANGUL SYLLABLE SIOS YAE PIEUPSIOS
+0x98EF	0xC113	#HANGUL SYLLABLE SIOS YAE SIOS
+0x98F0	0xC114	#HANGUL SYLLABLE SIOS YAE SSANGSIOS
+0x98F1	0xC116	#HANGUL SYLLABLE SIOS YAE CIEUC
+0x98F2	0xC117	#HANGUL SYLLABLE SIOS YAE CHIEUCH
+0x98F3	0xC118	#HANGUL SYLLABLE SIOS YAE KHIEUKH
+0x98F4	0xC119	#HANGUL SYLLABLE SIOS YAE THIEUTH
+0x98F5	0xC11A	#HANGUL SYLLABLE SIOS YAE PHIEUPH
+0x98F6	0xC11B	#HANGUL SYLLABLE SIOS YAE HIEUH
+0x98F7	0xC121	#HANGUL SYLLABLE SIOS EO NIEUNCIEUC
+0x98F8	0xC122	#HANGUL SYLLABLE SIOS EO NIEUNHIEUH
+0x98F9	0xC125	#HANGUL SYLLABLE SIOS EO RIEULKIYEOK
+0x98FA	0xC128	#HANGUL SYLLABLE SIOS EO RIEULSIOS
+0x98FB	0xC129	#HANGUL SYLLABLE SIOS EO RIEULTHIEUTH
+0x98FC	0xC12A	#HANGUL SYLLABLE SIOS EO RIEULPHIEUPH
+0x98FD	0xC12B	#HANGUL SYLLABLE SIOS EO RIEULHIEUH
+0x98FE	0xC12E	#HANGUL SYLLABLE SIOS EO PIEUPSIOS
+0x9941	0xC132	#HANGUL SYLLABLE SIOS EO CIEUC
+0x9942	0xC133	#HANGUL SYLLABLE SIOS EO CHIEUCH
+0x9943	0xC134	#HANGUL SYLLABLE SIOS EO KHIEUKH
+0x9944	0xC135	#HANGUL SYLLABLE SIOS EO THIEUTH
+0x9945	0xC137	#HANGUL SYLLABLE SIOS EO HIEUH
+0x9946	0xC13A	#HANGUL SYLLABLE SIOS E SSANGKIYEOK
+0x9947	0xC13B	#HANGUL SYLLABLE SIOS E KIYEOKSIOS
+0x9948	0xC13D	#HANGUL SYLLABLE SIOS E NIEUNCIEUC
+0x9949	0xC13E	#HANGUL SYLLABLE SIOS E NIEUNHIEUH
+0x994A	0xC13F	#HANGUL SYLLABLE SIOS E TIKEUT
+0x994B	0xC141	#HANGUL SYLLABLE SIOS E RIEULKIYEOK
+0x994C	0xC142	#HANGUL SYLLABLE SIOS E RIEULMIEUM
+0x994D	0xC143	#HANGUL SYLLABLE SIOS E RIEULPIEUP
+0x994E	0xC144	#HANGUL SYLLABLE SIOS E RIEULSIOS
+0x994F	0xC145	#HANGUL SYLLABLE SIOS E RIEULTHIEUTH
+0x9950	0xC146	#HANGUL SYLLABLE SIOS E RIEULPHIEUPH
+0x9951	0xC147	#HANGUL SYLLABLE SIOS E RIEULHIEUH
+0x9952	0xC14A	#HANGUL SYLLABLE SIOS E PIEUPSIOS
+0x9953	0xC14E	#HANGUL SYLLABLE SIOS E CIEUC
+0x9954	0xC14F	#HANGUL SYLLABLE SIOS E CHIEUCH
+0x9955	0xC150	#HANGUL SYLLABLE SIOS E KHIEUKH
+0x9956	0xC151	#HANGUL SYLLABLE SIOS E THIEUTH
+0x9957	0xC152	#HANGUL SYLLABLE SIOS E PHIEUPH
+0x9958	0xC153	#HANGUL SYLLABLE SIOS E HIEUH
+0x9959	0xC156	#HANGUL SYLLABLE SIOS YEO SSANGKIYEOK
+0x995A	0xC157	#HANGUL SYLLABLE SIOS YEO KIYEOKSIOS
+0x9961	0xC159	#HANGUL SYLLABLE SIOS YEO NIEUNCIEUC
+0x9962	0xC15A	#HANGUL SYLLABLE SIOS YEO NIEUNHIEUH
+0x9963	0xC15B	#HANGUL SYLLABLE SIOS YEO TIKEUT
+0x9964	0xC15D	#HANGUL SYLLABLE SIOS YEO RIEULKIYEOK
+0x9965	0xC15E	#HANGUL SYLLABLE SIOS YEO RIEULMIEUM
+0x9966	0xC15F	#HANGUL SYLLABLE SIOS YEO RIEULPIEUP
+0x9967	0xC160	#HANGUL SYLLABLE SIOS YEO RIEULSIOS
+0x9968	0xC161	#HANGUL SYLLABLE SIOS YEO RIEULTHIEUTH
+0x9969	0xC162	#HANGUL SYLLABLE SIOS YEO RIEULPHIEUPH
+0x996A	0xC163	#HANGUL SYLLABLE SIOS YEO RIEULHIEUH
+0x996B	0xC166	#HANGUL SYLLABLE SIOS YEO PIEUPSIOS
+0x996C	0xC16A	#HANGUL SYLLABLE SIOS YEO CIEUC
+0x996D	0xC16B	#HANGUL SYLLABLE SIOS YEO CHIEUCH
+0x996E	0xC16C	#HANGUL SYLLABLE SIOS YEO KHIEUKH
+0x996F	0xC16D	#HANGUL SYLLABLE SIOS YEO THIEUTH
+0x9970	0xC16E	#HANGUL SYLLABLE SIOS YEO PHIEUPH
+0x9971	0xC16F	#HANGUL SYLLABLE SIOS YEO HIEUH
+0x9972	0xC171	#HANGUL SYLLABLE SIOS YE KIYEOK
+0x9973	0xC172	#HANGUL SYLLABLE SIOS YE SSANGKIYEOK
+0x9974	0xC173	#HANGUL SYLLABLE SIOS YE KIYEOKSIOS
+0x9975	0xC175	#HANGUL SYLLABLE SIOS YE NIEUNCIEUC
+0x9976	0xC176	#HANGUL SYLLABLE SIOS YE NIEUNHIEUH
+0x9977	0xC177	#HANGUL SYLLABLE SIOS YE TIKEUT
+0x9978	0xC179	#HANGUL SYLLABLE SIOS YE RIEULKIYEOK
+0x9979	0xC17A	#HANGUL SYLLABLE SIOS YE RIEULMIEUM
+0x997A	0xC17B	#HANGUL SYLLABLE SIOS YE RIEULPIEUP
+0x9981	0xC17C	#HANGUL SYLLABLE SIOS YE RIEULSIOS
+0x9982	0xC17D	#HANGUL SYLLABLE SIOS YE RIEULTHIEUTH
+0x9983	0xC17E	#HANGUL SYLLABLE SIOS YE RIEULPHIEUPH
+0x9984	0xC17F	#HANGUL SYLLABLE SIOS YE RIEULHIEUH
+0x9985	0xC180	#HANGUL SYLLABLE SIOS YE MIEUM
+0x9986	0xC181	#HANGUL SYLLABLE SIOS YE PIEUP
+0x9987	0xC182	#HANGUL SYLLABLE SIOS YE PIEUPSIOS
+0x9988	0xC183	#HANGUL SYLLABLE SIOS YE SIOS
+0x9989	0xC184	#HANGUL SYLLABLE SIOS YE SSANGSIOS
+0x998A	0xC186	#HANGUL SYLLABLE SIOS YE CIEUC
+0x998B	0xC187	#HANGUL SYLLABLE SIOS YE CHIEUCH
+0x998C	0xC188	#HANGUL SYLLABLE SIOS YE KHIEUKH
+0x998D	0xC189	#HANGUL SYLLABLE SIOS YE THIEUTH
+0x998E	0xC18A	#HANGUL SYLLABLE SIOS YE PHIEUPH
+0x998F	0xC18B	#HANGUL SYLLABLE SIOS YE HIEUH
+0x9990	0xC18F	#HANGUL SYLLABLE SIOS O KIYEOKSIOS
+0x9991	0xC191	#HANGUL SYLLABLE SIOS O NIEUNCIEUC
+0x9992	0xC192	#HANGUL SYLLABLE SIOS O NIEUNHIEUH
+0x9993	0xC193	#HANGUL SYLLABLE SIOS O TIKEUT
+0x9994	0xC195	#HANGUL SYLLABLE SIOS O RIEULKIYEOK
+0x9995	0xC197	#HANGUL SYLLABLE SIOS O RIEULPIEUP
+0x9996	0xC198	#HANGUL SYLLABLE SIOS O RIEULSIOS
+0x9997	0xC199	#HANGUL SYLLABLE SIOS O RIEULTHIEUTH
+0x9998	0xC19A	#HANGUL SYLLABLE SIOS O RIEULPHIEUPH
+0x9999	0xC19B	#HANGUL SYLLABLE SIOS O RIEULHIEUH
+0x999A	0xC19E	#HANGUL SYLLABLE SIOS O PIEUPSIOS
+0x999B	0xC1A0	#HANGUL SYLLABLE SIOS O SSANGSIOS
+0x999C	0xC1A2	#HANGUL SYLLABLE SIOS O CIEUC
+0x999D	0xC1A3	#HANGUL SYLLABLE SIOS O CHIEUCH
+0x999E	0xC1A4	#HANGUL SYLLABLE SIOS O KHIEUKH
+0x999F	0xC1A6	#HANGUL SYLLABLE SIOS O PHIEUPH
+0x99A0	0xC1A7	#HANGUL SYLLABLE SIOS O HIEUH
+0x99A1	0xC1AA	#HANGUL SYLLABLE SIOS WA SSANGKIYEOK
+0x99A2	0xC1AB	#HANGUL SYLLABLE SIOS WA KIYEOKSIOS
+0x99A3	0xC1AD	#HANGUL SYLLABLE SIOS WA NIEUNCIEUC
+0x99A4	0xC1AE	#HANGUL SYLLABLE SIOS WA NIEUNHIEUH
+0x99A5	0xC1AF	#HANGUL SYLLABLE SIOS WA TIKEUT
+0x99A6	0xC1B1	#HANGUL SYLLABLE SIOS WA RIEULKIYEOK
+0x99A7	0xC1B2	#HANGUL SYLLABLE SIOS WA RIEULMIEUM
+0x99A8	0xC1B3	#HANGUL SYLLABLE SIOS WA RIEULPIEUP
+0x99A9	0xC1B4	#HANGUL SYLLABLE SIOS WA RIEULSIOS
+0x99AA	0xC1B5	#HANGUL SYLLABLE SIOS WA RIEULTHIEUTH
+0x99AB	0xC1B6	#HANGUL SYLLABLE SIOS WA RIEULPHIEUPH
+0x99AC	0xC1B7	#HANGUL SYLLABLE SIOS WA RIEULHIEUH
+0x99AD	0xC1B8	#HANGUL SYLLABLE SIOS WA MIEUM
+0x99AE	0xC1B9	#HANGUL SYLLABLE SIOS WA PIEUP
+0x99AF	0xC1BA	#HANGUL SYLLABLE SIOS WA PIEUPSIOS
+0x99B0	0xC1BB	#HANGUL SYLLABLE SIOS WA SIOS
+0x99B1	0xC1BC	#HANGUL SYLLABLE SIOS WA SSANGSIOS
+0x99B2	0xC1BE	#HANGUL SYLLABLE SIOS WA CIEUC
+0x99B3	0xC1BF	#HANGUL SYLLABLE SIOS WA CHIEUCH
+0x99B4	0xC1C0	#HANGUL SYLLABLE SIOS WA KHIEUKH
+0x99B5	0xC1C1	#HANGUL SYLLABLE SIOS WA THIEUTH
+0x99B6	0xC1C2	#HANGUL SYLLABLE SIOS WA PHIEUPH
+0x99B7	0xC1C3	#HANGUL SYLLABLE SIOS WA HIEUH
+0x99B8	0xC1C5	#HANGUL SYLLABLE SIOS WAE KIYEOK
+0x99B9	0xC1C6	#HANGUL SYLLABLE SIOS WAE SSANGKIYEOK
+0x99BA	0xC1C7	#HANGUL SYLLABLE SIOS WAE KIYEOKSIOS
+0x99BB	0xC1C9	#HANGUL SYLLABLE SIOS WAE NIEUNCIEUC
+0x99BC	0xC1CA	#HANGUL SYLLABLE SIOS WAE NIEUNHIEUH
+0x99BD	0xC1CB	#HANGUL SYLLABLE SIOS WAE TIKEUT
+0x99BE	0xC1CD	#HANGUL SYLLABLE SIOS WAE RIEULKIYEOK
+0x99BF	0xC1CE	#HANGUL SYLLABLE SIOS WAE RIEULMIEUM
+0x99C0	0xC1CF	#HANGUL SYLLABLE SIOS WAE RIEULPIEUP
+0x99C1	0xC1D0	#HANGUL SYLLABLE SIOS WAE RIEULSIOS
+0x99C2	0xC1D1	#HANGUL SYLLABLE SIOS WAE RIEULTHIEUTH
+0x99C3	0xC1D2	#HANGUL SYLLABLE SIOS WAE RIEULPHIEUPH
+0x99C4	0xC1D3	#HANGUL SYLLABLE SIOS WAE RIEULHIEUH
+0x99C5	0xC1D5	#HANGUL SYLLABLE SIOS WAE PIEUP
+0x99C6	0xC1D6	#HANGUL SYLLABLE SIOS WAE PIEUPSIOS
+0x99C7	0xC1D9	#HANGUL SYLLABLE SIOS WAE IEUNG
+0x99C8	0xC1DA	#HANGUL SYLLABLE SIOS WAE CIEUC
+0x99C9	0xC1DB	#HANGUL SYLLABLE SIOS WAE CHIEUCH
+0x99CA	0xC1DC	#HANGUL SYLLABLE SIOS WAE KHIEUKH
+0x99CB	0xC1DD	#HANGUL SYLLABLE SIOS WAE THIEUTH
+0x99CC	0xC1DE	#HANGUL SYLLABLE SIOS WAE PHIEUPH
+0x99CD	0xC1DF	#HANGUL SYLLABLE SIOS WAE HIEUH
+0x99CE	0xC1E1	#HANGUL SYLLABLE SIOS OE KIYEOK
+0x99CF	0xC1E2	#HANGUL SYLLABLE SIOS OE SSANGKIYEOK
+0x99D0	0xC1E3	#HANGUL SYLLABLE SIOS OE KIYEOKSIOS
+0x99D1	0xC1E5	#HANGUL SYLLABLE SIOS OE NIEUNCIEUC
+0x99D2	0xC1E6	#HANGUL SYLLABLE SIOS OE NIEUNHIEUH
+0x99D3	0xC1E7	#HANGUL SYLLABLE SIOS OE TIKEUT
+0x99D4	0xC1E9	#HANGUL SYLLABLE SIOS OE RIEULKIYEOK
+0x99D5	0xC1EA	#HANGUL SYLLABLE SIOS OE RIEULMIEUM
+0x99D6	0xC1EB	#HANGUL SYLLABLE SIOS OE RIEULPIEUP
+0x99D7	0xC1EC	#HANGUL SYLLABLE SIOS OE RIEULSIOS
+0x99D8	0xC1ED	#HANGUL SYLLABLE SIOS OE RIEULTHIEUTH
+0x99D9	0xC1EE	#HANGUL SYLLABLE SIOS OE RIEULPHIEUPH
+0x99DA	0xC1EF	#HANGUL SYLLABLE SIOS OE RIEULHIEUH
+0x99DB	0xC1F2	#HANGUL SYLLABLE SIOS OE PIEUPSIOS
+0x99DC	0xC1F4	#HANGUL SYLLABLE SIOS OE SSANGSIOS
+0x99DD	0xC1F5	#HANGUL SYLLABLE SIOS OE IEUNG
+0x99DE	0xC1F6	#HANGUL SYLLABLE SIOS OE CIEUC
+0x99DF	0xC1F7	#HANGUL SYLLABLE SIOS OE CHIEUCH
+0x99E0	0xC1F8	#HANGUL SYLLABLE SIOS OE KHIEUKH
+0x99E1	0xC1F9	#HANGUL SYLLABLE SIOS OE THIEUTH
+0x99E2	0xC1FA	#HANGUL SYLLABLE SIOS OE PHIEUPH
+0x99E3	0xC1FB	#HANGUL SYLLABLE SIOS OE HIEUH
+0x99E4	0xC1FE	#HANGUL SYLLABLE SIOS YO SSANGKIYEOK
+0x99E5	0xC1FF	#HANGUL SYLLABLE SIOS YO KIYEOKSIOS
+0x99E6	0xC201	#HANGUL SYLLABLE SIOS YO NIEUNCIEUC
+0x99E7	0xC202	#HANGUL SYLLABLE SIOS YO NIEUNHIEUH
+0x99E8	0xC203	#HANGUL SYLLABLE SIOS YO TIKEUT
+0x99E9	0xC205	#HANGUL SYLLABLE SIOS YO RIEULKIYEOK
+0x99EA	0xC206	#HANGUL SYLLABLE SIOS YO RIEULMIEUM
+0x99EB	0xC207	#HANGUL SYLLABLE SIOS YO RIEULPIEUP
+0x99EC	0xC208	#HANGUL SYLLABLE SIOS YO RIEULSIOS
+0x99ED	0xC209	#HANGUL SYLLABLE SIOS YO RIEULTHIEUTH
+0x99EE	0xC20A	#HANGUL SYLLABLE SIOS YO RIEULPHIEUPH
+0x99EF	0xC20B	#HANGUL SYLLABLE SIOS YO RIEULHIEUH
+0x99F0	0xC20E	#HANGUL SYLLABLE SIOS YO PIEUPSIOS
+0x99F1	0xC210	#HANGUL SYLLABLE SIOS YO SSANGSIOS
+0x99F2	0xC212	#HANGUL SYLLABLE SIOS YO CIEUC
+0x99F3	0xC213	#HANGUL SYLLABLE SIOS YO CHIEUCH
+0x99F4	0xC214	#HANGUL SYLLABLE SIOS YO KHIEUKH
+0x99F5	0xC215	#HANGUL SYLLABLE SIOS YO THIEUTH
+0x99F6	0xC216	#HANGUL SYLLABLE SIOS YO PHIEUPH
+0x99F7	0xC217	#HANGUL SYLLABLE SIOS YO HIEUH
+0x99F8	0xC21A	#HANGUL SYLLABLE SIOS U SSANGKIYEOK
+0x99F9	0xC21B	#HANGUL SYLLABLE SIOS U KIYEOKSIOS
+0x99FA	0xC21D	#HANGUL SYLLABLE SIOS U NIEUNCIEUC
+0x99FB	0xC21E	#HANGUL SYLLABLE SIOS U NIEUNHIEUH
+0x99FC	0xC221	#HANGUL SYLLABLE SIOS U RIEULKIYEOK
+0x99FD	0xC222	#HANGUL SYLLABLE SIOS U RIEULMIEUM
+0x99FE	0xC223	#HANGUL SYLLABLE SIOS U RIEULPIEUP
+0x9A41	0xC224	#HANGUL SYLLABLE SIOS U RIEULSIOS
+0x9A42	0xC225	#HANGUL SYLLABLE SIOS U RIEULTHIEUTH
+0x9A43	0xC226	#HANGUL SYLLABLE SIOS U RIEULPHIEUPH
+0x9A44	0xC227	#HANGUL SYLLABLE SIOS U RIEULHIEUH
+0x9A45	0xC22A	#HANGUL SYLLABLE SIOS U PIEUPSIOS
+0x9A46	0xC22C	#HANGUL SYLLABLE SIOS U SSANGSIOS
+0x9A47	0xC22E	#HANGUL SYLLABLE SIOS U CIEUC
+0x9A48	0xC230	#HANGUL SYLLABLE SIOS U KHIEUKH
+0x9A49	0xC233	#HANGUL SYLLABLE SIOS U HIEUH
+0x9A4A	0xC235	#HANGUL SYLLABLE SIOS WEO KIYEOK
+0x9A4B	0xC236	#HANGUL SYLLABLE SIOS WEO SSANGKIYEOK
+0x9A4C	0xC237	#HANGUL SYLLABLE SIOS WEO KIYEOKSIOS
+0x9A4D	0xC238	#HANGUL SYLLABLE SIOS WEO NIEUN
+0x9A4E	0xC239	#HANGUL SYLLABLE SIOS WEO NIEUNCIEUC
+0x9A4F	0xC23A	#HANGUL SYLLABLE SIOS WEO NIEUNHIEUH
+0x9A50	0xC23B	#HANGUL SYLLABLE SIOS WEO TIKEUT
+0x9A51	0xC23C	#HANGUL SYLLABLE SIOS WEO RIEUL
+0x9A52	0xC23D	#HANGUL SYLLABLE SIOS WEO RIEULKIYEOK
+0x9A53	0xC23E	#HANGUL SYLLABLE SIOS WEO RIEULMIEUM
+0x9A54	0xC23F	#HANGUL SYLLABLE SIOS WEO RIEULPIEUP
+0x9A55	0xC240	#HANGUL SYLLABLE SIOS WEO RIEULSIOS
+0x9A56	0xC241	#HANGUL SYLLABLE SIOS WEO RIEULTHIEUTH
+0x9A57	0xC242	#HANGUL SYLLABLE SIOS WEO RIEULPHIEUPH
+0x9A58	0xC243	#HANGUL SYLLABLE SIOS WEO RIEULHIEUH
+0x9A59	0xC244	#HANGUL SYLLABLE SIOS WEO MIEUM
+0x9A5A	0xC245	#HANGUL SYLLABLE SIOS WEO PIEUP
+0x9A61	0xC246	#HANGUL SYLLABLE SIOS WEO PIEUPSIOS
+0x9A62	0xC247	#HANGUL SYLLABLE SIOS WEO SIOS
+0x9A63	0xC249	#HANGUL SYLLABLE SIOS WEO IEUNG
+0x9A64	0xC24A	#HANGUL SYLLABLE SIOS WEO CIEUC
+0x9A65	0xC24B	#HANGUL SYLLABLE SIOS WEO CHIEUCH
+0x9A66	0xC24C	#HANGUL SYLLABLE SIOS WEO KHIEUKH
+0x9A67	0xC24D	#HANGUL SYLLABLE SIOS WEO THIEUTH
+0x9A68	0xC24E	#HANGUL SYLLABLE SIOS WEO PHIEUPH
+0x9A69	0xC24F	#HANGUL SYLLABLE SIOS WEO HIEUH
+0x9A6A	0xC252	#HANGUL SYLLABLE SIOS WE SSANGKIYEOK
+0x9A6B	0xC253	#HANGUL SYLLABLE SIOS WE KIYEOKSIOS
+0x9A6C	0xC255	#HANGUL SYLLABLE SIOS WE NIEUNCIEUC
+0x9A6D	0xC256	#HANGUL SYLLABLE SIOS WE NIEUNHIEUH
+0x9A6E	0xC257	#HANGUL SYLLABLE SIOS WE TIKEUT
+0x9A6F	0xC259	#HANGUL SYLLABLE SIOS WE RIEULKIYEOK
+0x9A70	0xC25A	#HANGUL SYLLABLE SIOS WE RIEULMIEUM
+0x9A71	0xC25B	#HANGUL SYLLABLE SIOS WE RIEULPIEUP
+0x9A72	0xC25C	#HANGUL SYLLABLE SIOS WE RIEULSIOS
+0x9A73	0xC25D	#HANGUL SYLLABLE SIOS WE RIEULTHIEUTH
+0x9A74	0xC25E	#HANGUL SYLLABLE SIOS WE RIEULPHIEUPH
+0x9A75	0xC25F	#HANGUL SYLLABLE SIOS WE RIEULHIEUH
+0x9A76	0xC261	#HANGUL SYLLABLE SIOS WE PIEUP
+0x9A77	0xC262	#HANGUL SYLLABLE SIOS WE PIEUPSIOS
+0x9A78	0xC263	#HANGUL SYLLABLE SIOS WE SIOS
+0x9A79	0xC264	#HANGUL SYLLABLE SIOS WE SSANGSIOS
+0x9A7A	0xC266	#HANGUL SYLLABLE SIOS WE CIEUC
+0x9A81	0xC267	#HANGUL SYLLABLE SIOS WE CHIEUCH
+0x9A82	0xC268	#HANGUL SYLLABLE SIOS WE KHIEUKH
+0x9A83	0xC269	#HANGUL SYLLABLE SIOS WE THIEUTH
+0x9A84	0xC26A	#HANGUL SYLLABLE SIOS WE PHIEUPH
+0x9A85	0xC26B	#HANGUL SYLLABLE SIOS WE HIEUH
+0x9A86	0xC26E	#HANGUL SYLLABLE SIOS WI SSANGKIYEOK
+0x9A87	0xC26F	#HANGUL SYLLABLE SIOS WI KIYEOKSIOS
+0x9A88	0xC271	#HANGUL SYLLABLE SIOS WI NIEUNCIEUC
+0x9A89	0xC272	#HANGUL SYLLABLE SIOS WI NIEUNHIEUH
+0x9A8A	0xC273	#HANGUL SYLLABLE SIOS WI TIKEUT
+0x9A8B	0xC275	#HANGUL SYLLABLE SIOS WI RIEULKIYEOK
+0x9A8C	0xC276	#HANGUL SYLLABLE SIOS WI RIEULMIEUM
+0x9A8D	0xC277	#HANGUL SYLLABLE SIOS WI RIEULPIEUP
+0x9A8E	0xC278	#HANGUL SYLLABLE SIOS WI RIEULSIOS
+0x9A8F	0xC279	#HANGUL SYLLABLE SIOS WI RIEULTHIEUTH
+0x9A90	0xC27A	#HANGUL SYLLABLE SIOS WI RIEULPHIEUPH
+0x9A91	0xC27B	#HANGUL SYLLABLE SIOS WI RIEULHIEUH
+0x9A92	0xC27E	#HANGUL SYLLABLE SIOS WI PIEUPSIOS
+0x9A93	0xC280	#HANGUL SYLLABLE SIOS WI SSANGSIOS
+0x9A94	0xC282	#HANGUL SYLLABLE SIOS WI CIEUC
+0x9A95	0xC283	#HANGUL SYLLABLE SIOS WI CHIEUCH
+0x9A96	0xC284	#HANGUL SYLLABLE SIOS WI KHIEUKH
+0x9A97	0xC285	#HANGUL SYLLABLE SIOS WI THIEUTH
+0x9A98	0xC286	#HANGUL SYLLABLE SIOS WI PHIEUPH
+0x9A99	0xC287	#HANGUL SYLLABLE SIOS WI HIEUH
+0x9A9A	0xC28A	#HANGUL SYLLABLE SIOS YU SSANGKIYEOK
+0x9A9B	0xC28B	#HANGUL SYLLABLE SIOS YU KIYEOKSIOS
+0x9A9C	0xC28C	#HANGUL SYLLABLE SIOS YU NIEUN
+0x9A9D	0xC28D	#HANGUL SYLLABLE SIOS YU NIEUNCIEUC
+0x9A9E	0xC28E	#HANGUL SYLLABLE SIOS YU NIEUNHIEUH
+0x9A9F	0xC28F	#HANGUL SYLLABLE SIOS YU TIKEUT
+0x9AA0	0xC291	#HANGUL SYLLABLE SIOS YU RIEULKIYEOK
+0x9AA1	0xC292	#HANGUL SYLLABLE SIOS YU RIEULMIEUM
+0x9AA2	0xC293	#HANGUL SYLLABLE SIOS YU RIEULPIEUP
+0x9AA3	0xC294	#HANGUL SYLLABLE SIOS YU RIEULSIOS
+0x9AA4	0xC295	#HANGUL SYLLABLE SIOS YU RIEULTHIEUTH
+0x9AA5	0xC296	#HANGUL SYLLABLE SIOS YU RIEULPHIEUPH
+0x9AA6	0xC297	#HANGUL SYLLABLE SIOS YU RIEULHIEUH
+0x9AA7	0xC299	#HANGUL SYLLABLE SIOS YU PIEUP
+0x9AA8	0xC29A	#HANGUL SYLLABLE SIOS YU PIEUPSIOS
+0x9AA9	0xC29C	#HANGUL SYLLABLE SIOS YU SSANGSIOS
+0x9AAA	0xC29E	#HANGUL SYLLABLE SIOS YU CIEUC
+0x9AAB	0xC29F	#HANGUL SYLLABLE SIOS YU CHIEUCH
+0x9AAC	0xC2A0	#HANGUL SYLLABLE SIOS YU KHIEUKH
+0x9AAD	0xC2A1	#HANGUL SYLLABLE SIOS YU THIEUTH
+0x9AAE	0xC2A2	#HANGUL SYLLABLE SIOS YU PHIEUPH
+0x9AAF	0xC2A3	#HANGUL SYLLABLE SIOS YU HIEUH
+0x9AB0	0xC2A6	#HANGUL SYLLABLE SIOS EU SSANGKIYEOK
+0x9AB1	0xC2A7	#HANGUL SYLLABLE SIOS EU KIYEOKSIOS
+0x9AB2	0xC2A9	#HANGUL SYLLABLE SIOS EU NIEUNCIEUC
+0x9AB3	0xC2AA	#HANGUL SYLLABLE SIOS EU NIEUNHIEUH
+0x9AB4	0xC2AB	#HANGUL SYLLABLE SIOS EU TIKEUT
+0x9AB5	0xC2AE	#HANGUL SYLLABLE SIOS EU RIEULMIEUM
+0x9AB6	0xC2AF	#HANGUL SYLLABLE SIOS EU RIEULPIEUP
+0x9AB7	0xC2B0	#HANGUL SYLLABLE SIOS EU RIEULSIOS
+0x9AB8	0xC2B1	#HANGUL SYLLABLE SIOS EU RIEULTHIEUTH
+0x9AB9	0xC2B2	#HANGUL SYLLABLE SIOS EU RIEULPHIEUPH
+0x9ABA	0xC2B3	#HANGUL SYLLABLE SIOS EU RIEULHIEUH
+0x9ABB	0xC2B6	#HANGUL SYLLABLE SIOS EU PIEUPSIOS
+0x9ABC	0xC2B8	#HANGUL SYLLABLE SIOS EU SSANGSIOS
+0x9ABD	0xC2BA	#HANGUL SYLLABLE SIOS EU CIEUC
+0x9ABE	0xC2BB	#HANGUL SYLLABLE SIOS EU CHIEUCH
+0x9ABF	0xC2BC	#HANGUL SYLLABLE SIOS EU KHIEUKH
+0x9AC0	0xC2BD	#HANGUL SYLLABLE SIOS EU THIEUTH
+0x9AC1	0xC2BE	#HANGUL SYLLABLE SIOS EU PHIEUPH
+0x9AC2	0xC2BF	#HANGUL SYLLABLE SIOS EU HIEUH
+0x9AC3	0xC2C0	#HANGUL SYLLABLE SIOS YI
+0x9AC4	0xC2C1	#HANGUL SYLLABLE SIOS YI KIYEOK
+0x9AC5	0xC2C2	#HANGUL SYLLABLE SIOS YI SSANGKIYEOK
+0x9AC6	0xC2C3	#HANGUL SYLLABLE SIOS YI KIYEOKSIOS
+0x9AC7	0xC2C4	#HANGUL SYLLABLE SIOS YI NIEUN
+0x9AC8	0xC2C5	#HANGUL SYLLABLE SIOS YI NIEUNCIEUC
+0x9AC9	0xC2C6	#HANGUL SYLLABLE SIOS YI NIEUNHIEUH
+0x9ACA	0xC2C7	#HANGUL SYLLABLE SIOS YI TIKEUT
+0x9ACB	0xC2C8	#HANGUL SYLLABLE SIOS YI RIEUL
+0x9ACC	0xC2C9	#HANGUL SYLLABLE SIOS YI RIEULKIYEOK
+0x9ACD	0xC2CA	#HANGUL SYLLABLE SIOS YI RIEULMIEUM
+0x9ACE	0xC2CB	#HANGUL SYLLABLE SIOS YI RIEULPIEUP
+0x9ACF	0xC2CC	#HANGUL SYLLABLE SIOS YI RIEULSIOS
+0x9AD0	0xC2CD	#HANGUL SYLLABLE SIOS YI RIEULTHIEUTH
+0x9AD1	0xC2CE	#HANGUL SYLLABLE SIOS YI RIEULPHIEUPH
+0x9AD2	0xC2CF	#HANGUL SYLLABLE SIOS YI RIEULHIEUH
+0x9AD3	0xC2D0	#HANGUL SYLLABLE SIOS YI MIEUM
+0x9AD4	0xC2D1	#HANGUL SYLLABLE SIOS YI PIEUP
+0x9AD5	0xC2D2	#HANGUL SYLLABLE SIOS YI PIEUPSIOS
+0x9AD6	0xC2D3	#HANGUL SYLLABLE SIOS YI SIOS
+0x9AD7	0xC2D4	#HANGUL SYLLABLE SIOS YI SSANGSIOS
+0x9AD8	0xC2D5	#HANGUL SYLLABLE SIOS YI IEUNG
+0x9AD9	0xC2D6	#HANGUL SYLLABLE SIOS YI CIEUC
+0x9ADA	0xC2D7	#HANGUL SYLLABLE SIOS YI CHIEUCH
+0x9ADB	0xC2D8	#HANGUL SYLLABLE SIOS YI KHIEUKH
+0x9ADC	0xC2D9	#HANGUL SYLLABLE SIOS YI THIEUTH
+0x9ADD	0xC2DA	#HANGUL SYLLABLE SIOS YI PHIEUPH
+0x9ADE	0xC2DB	#HANGUL SYLLABLE SIOS YI HIEUH
+0x9ADF	0xC2DE	#HANGUL SYLLABLE SIOS I SSANGKIYEOK
+0x9AE0	0xC2DF	#HANGUL SYLLABLE SIOS I KIYEOKSIOS
+0x9AE1	0xC2E1	#HANGUL SYLLABLE SIOS I NIEUNCIEUC
+0x9AE2	0xC2E2	#HANGUL SYLLABLE SIOS I NIEUNHIEUH
+0x9AE3	0xC2E5	#HANGUL SYLLABLE SIOS I RIEULKIYEOK
+0x9AE4	0xC2E6	#HANGUL SYLLABLE SIOS I RIEULMIEUM
+0x9AE5	0xC2E7	#HANGUL SYLLABLE SIOS I RIEULPIEUP
+0x9AE6	0xC2E8	#HANGUL SYLLABLE SIOS I RIEULSIOS
+0x9AE7	0xC2E9	#HANGUL SYLLABLE SIOS I RIEULTHIEUTH
+0x9AE8	0xC2EA	#HANGUL SYLLABLE SIOS I RIEULPHIEUPH
+0x9AE9	0xC2EE	#HANGUL SYLLABLE SIOS I PIEUPSIOS
+0x9AEA	0xC2F0	#HANGUL SYLLABLE SIOS I SSANGSIOS
+0x9AEB	0xC2F2	#HANGUL SYLLABLE SIOS I CIEUC
+0x9AEC	0xC2F3	#HANGUL SYLLABLE SIOS I CHIEUCH
+0x9AED	0xC2F4	#HANGUL SYLLABLE SIOS I KHIEUKH
+0x9AEE	0xC2F5	#HANGUL SYLLABLE SIOS I THIEUTH
+0x9AEF	0xC2F7	#HANGUL SYLLABLE SIOS I HIEUH
+0x9AF0	0xC2FA	#HANGUL SYLLABLE SSANGSIOS A SSANGKIYEOK
+0x9AF1	0xC2FD	#HANGUL SYLLABLE SSANGSIOS A NIEUNCIEUC
+0x9AF2	0xC2FE	#HANGUL SYLLABLE SSANGSIOS A NIEUNHIEUH
+0x9AF3	0xC2FF	#HANGUL SYLLABLE SSANGSIOS A TIKEUT
+0x9AF4	0xC301	#HANGUL SYLLABLE SSANGSIOS A RIEULKIYEOK
+0x9AF5	0xC302	#HANGUL SYLLABLE SSANGSIOS A RIEULMIEUM
+0x9AF6	0xC303	#HANGUL SYLLABLE SSANGSIOS A RIEULPIEUP
+0x9AF7	0xC304	#HANGUL SYLLABLE SSANGSIOS A RIEULSIOS
+0x9AF8	0xC305	#HANGUL SYLLABLE SSANGSIOS A RIEULTHIEUTH
+0x9AF9	0xC306	#HANGUL SYLLABLE SSANGSIOS A RIEULPHIEUPH
+0x9AFA	0xC307	#HANGUL SYLLABLE SSANGSIOS A RIEULHIEUH
+0x9AFB	0xC30A	#HANGUL SYLLABLE SSANGSIOS A PIEUPSIOS
+0x9AFC	0xC30B	#HANGUL SYLLABLE SSANGSIOS A SIOS
+0x9AFD	0xC30E	#HANGUL SYLLABLE SSANGSIOS A CIEUC
+0x9AFE	0xC30F	#HANGUL SYLLABLE SSANGSIOS A CHIEUCH
+0x9B41	0xC310	#HANGUL SYLLABLE SSANGSIOS A KHIEUKH
+0x9B42	0xC311	#HANGUL SYLLABLE SSANGSIOS A THIEUTH
+0x9B43	0xC312	#HANGUL SYLLABLE SSANGSIOS A PHIEUPH
+0x9B44	0xC316	#HANGUL SYLLABLE SSANGSIOS AE SSANGKIYEOK
+0x9B45	0xC317	#HANGUL SYLLABLE SSANGSIOS AE KIYEOKSIOS
+0x9B46	0xC319	#HANGUL SYLLABLE SSANGSIOS AE NIEUNCIEUC
+0x9B47	0xC31A	#HANGUL SYLLABLE SSANGSIOS AE NIEUNHIEUH
+0x9B48	0xC31B	#HANGUL SYLLABLE SSANGSIOS AE TIKEUT
+0x9B49	0xC31D	#HANGUL SYLLABLE SSANGSIOS AE RIEULKIYEOK
+0x9B4A	0xC31E	#HANGUL SYLLABLE SSANGSIOS AE RIEULMIEUM
+0x9B4B	0xC31F	#HANGUL SYLLABLE SSANGSIOS AE RIEULPIEUP
+0x9B4C	0xC320	#HANGUL SYLLABLE SSANGSIOS AE RIEULSIOS
+0x9B4D	0xC321	#HANGUL SYLLABLE SSANGSIOS AE RIEULTHIEUTH
+0x9B4E	0xC322	#HANGUL SYLLABLE SSANGSIOS AE RIEULPHIEUPH
+0x9B4F	0xC323	#HANGUL SYLLABLE SSANGSIOS AE RIEULHIEUH
+0x9B50	0xC326	#HANGUL SYLLABLE SSANGSIOS AE PIEUPSIOS
+0x9B51	0xC327	#HANGUL SYLLABLE SSANGSIOS AE SIOS
+0x9B52	0xC32A	#HANGUL SYLLABLE SSANGSIOS AE CIEUC
+0x9B53	0xC32B	#HANGUL SYLLABLE SSANGSIOS AE CHIEUCH
+0x9B54	0xC32C	#HANGUL SYLLABLE SSANGSIOS AE KHIEUKH
+0x9B55	0xC32D	#HANGUL SYLLABLE SSANGSIOS AE THIEUTH
+0x9B56	0xC32E	#HANGUL SYLLABLE SSANGSIOS AE PHIEUPH
+0x9B57	0xC32F	#HANGUL SYLLABLE SSANGSIOS AE HIEUH
+0x9B58	0xC330	#HANGUL SYLLABLE SSANGSIOS YA
+0x9B59	0xC331	#HANGUL SYLLABLE SSANGSIOS YA KIYEOK
+0x9B5A	0xC332	#HANGUL SYLLABLE SSANGSIOS YA SSANGKIYEOK
+0x9B61	0xC333	#HANGUL SYLLABLE SSANGSIOS YA KIYEOKSIOS
+0x9B62	0xC334	#HANGUL SYLLABLE SSANGSIOS YA NIEUN
+0x9B63	0xC335	#HANGUL SYLLABLE SSANGSIOS YA NIEUNCIEUC
+0x9B64	0xC336	#HANGUL SYLLABLE SSANGSIOS YA NIEUNHIEUH
+0x9B65	0xC337	#HANGUL SYLLABLE SSANGSIOS YA TIKEUT
+0x9B66	0xC338	#HANGUL SYLLABLE SSANGSIOS YA RIEUL
+0x9B67	0xC339	#HANGUL SYLLABLE SSANGSIOS YA RIEULKIYEOK
+0x9B68	0xC33A	#HANGUL SYLLABLE SSANGSIOS YA RIEULMIEUM
+0x9B69	0xC33B	#HANGUL SYLLABLE SSANGSIOS YA RIEULPIEUP
+0x9B6A	0xC33C	#HANGUL SYLLABLE SSANGSIOS YA RIEULSIOS
+0x9B6B	0xC33D	#HANGUL SYLLABLE SSANGSIOS YA RIEULTHIEUTH
+0x9B6C	0xC33E	#HANGUL SYLLABLE SSANGSIOS YA RIEULPHIEUPH
+0x9B6D	0xC33F	#HANGUL SYLLABLE SSANGSIOS YA RIEULHIEUH
+0x9B6E	0xC340	#HANGUL SYLLABLE SSANGSIOS YA MIEUM
+0x9B6F	0xC341	#HANGUL SYLLABLE SSANGSIOS YA PIEUP
+0x9B70	0xC342	#HANGUL SYLLABLE SSANGSIOS YA PIEUPSIOS
+0x9B71	0xC343	#HANGUL SYLLABLE SSANGSIOS YA SIOS
+0x9B72	0xC344	#HANGUL SYLLABLE SSANGSIOS YA SSANGSIOS
+0x9B73	0xC346	#HANGUL SYLLABLE SSANGSIOS YA CIEUC
+0x9B74	0xC347	#HANGUL SYLLABLE SSANGSIOS YA CHIEUCH
+0x9B75	0xC348	#HANGUL SYLLABLE SSANGSIOS YA KHIEUKH
+0x9B76	0xC349	#HANGUL SYLLABLE SSANGSIOS YA THIEUTH
+0x9B77	0xC34A	#HANGUL SYLLABLE SSANGSIOS YA PHIEUPH
+0x9B78	0xC34B	#HANGUL SYLLABLE SSANGSIOS YA HIEUH
+0x9B79	0xC34C	#HANGUL SYLLABLE SSANGSIOS YAE
+0x9B7A	0xC34D	#HANGUL SYLLABLE SSANGSIOS YAE KIYEOK
+0x9B81	0xC34E	#HANGUL SYLLABLE SSANGSIOS YAE SSANGKIYEOK
+0x9B82	0xC34F	#HANGUL SYLLABLE SSANGSIOS YAE KIYEOKSIOS
+0x9B83	0xC350	#HANGUL SYLLABLE SSANGSIOS YAE NIEUN
+0x9B84	0xC351	#HANGUL SYLLABLE SSANGSIOS YAE NIEUNCIEUC
+0x9B85	0xC352	#HANGUL SYLLABLE SSANGSIOS YAE NIEUNHIEUH
+0x9B86	0xC353	#HANGUL SYLLABLE SSANGSIOS YAE TIKEUT
+0x9B87	0xC354	#HANGUL SYLLABLE SSANGSIOS YAE RIEUL
+0x9B88	0xC355	#HANGUL SYLLABLE SSANGSIOS YAE RIEULKIYEOK
+0x9B89	0xC356	#HANGUL SYLLABLE SSANGSIOS YAE RIEULMIEUM
+0x9B8A	0xC357	#HANGUL SYLLABLE SSANGSIOS YAE RIEULPIEUP
+0x9B8B	0xC358	#HANGUL SYLLABLE SSANGSIOS YAE RIEULSIOS
+0x9B8C	0xC359	#HANGUL SYLLABLE SSANGSIOS YAE RIEULTHIEUTH
+0x9B8D	0xC35A	#HANGUL SYLLABLE SSANGSIOS YAE RIEULPHIEUPH
+0x9B8E	0xC35B	#HANGUL SYLLABLE SSANGSIOS YAE RIEULHIEUH
+0x9B8F	0xC35C	#HANGUL SYLLABLE SSANGSIOS YAE MIEUM
+0x9B90	0xC35D	#HANGUL SYLLABLE SSANGSIOS YAE PIEUP
+0x9B91	0xC35E	#HANGUL SYLLABLE SSANGSIOS YAE PIEUPSIOS
+0x9B92	0xC35F	#HANGUL SYLLABLE SSANGSIOS YAE SIOS
+0x9B93	0xC360	#HANGUL SYLLABLE SSANGSIOS YAE SSANGSIOS
+0x9B94	0xC361	#HANGUL SYLLABLE SSANGSIOS YAE IEUNG
+0x9B95	0xC362	#HANGUL SYLLABLE SSANGSIOS YAE CIEUC
+0x9B96	0xC363	#HANGUL SYLLABLE SSANGSIOS YAE CHIEUCH
+0x9B97	0xC364	#HANGUL SYLLABLE SSANGSIOS YAE KHIEUKH
+0x9B98	0xC365	#HANGUL SYLLABLE SSANGSIOS YAE THIEUTH
+0x9B99	0xC366	#HANGUL SYLLABLE SSANGSIOS YAE PHIEUPH
+0x9B9A	0xC367	#HANGUL SYLLABLE SSANGSIOS YAE HIEUH
+0x9B9B	0xC36A	#HANGUL SYLLABLE SSANGSIOS EO SSANGKIYEOK
+0x9B9C	0xC36B	#HANGUL SYLLABLE SSANGSIOS EO KIYEOKSIOS
+0x9B9D	0xC36D	#HANGUL SYLLABLE SSANGSIOS EO NIEUNCIEUC
+0x9B9E	0xC36E	#HANGUL SYLLABLE SSANGSIOS EO NIEUNHIEUH
+0x9B9F	0xC36F	#HANGUL SYLLABLE SSANGSIOS EO TIKEUT
+0x9BA0	0xC371	#HANGUL SYLLABLE SSANGSIOS EO RIEULKIYEOK
+0x9BA1	0xC373	#HANGUL SYLLABLE SSANGSIOS EO RIEULPIEUP
+0x9BA2	0xC374	#HANGUL SYLLABLE SSANGSIOS EO RIEULSIOS
+0x9BA3	0xC375	#HANGUL SYLLABLE SSANGSIOS EO RIEULTHIEUTH
+0x9BA4	0xC376	#HANGUL SYLLABLE SSANGSIOS EO RIEULPHIEUPH
+0x9BA5	0xC377	#HANGUL SYLLABLE SSANGSIOS EO RIEULHIEUH
+0x9BA6	0xC37A	#HANGUL SYLLABLE SSANGSIOS EO PIEUPSIOS
+0x9BA7	0xC37B	#HANGUL SYLLABLE SSANGSIOS EO SIOS
+0x9BA8	0xC37E	#HANGUL SYLLABLE SSANGSIOS EO CIEUC
+0x9BA9	0xC37F	#HANGUL SYLLABLE SSANGSIOS EO CHIEUCH
+0x9BAA	0xC380	#HANGUL SYLLABLE SSANGSIOS EO KHIEUKH
+0x9BAB	0xC381	#HANGUL SYLLABLE SSANGSIOS EO THIEUTH
+0x9BAC	0xC382	#HANGUL SYLLABLE SSANGSIOS EO PHIEUPH
+0x9BAD	0xC383	#HANGUL SYLLABLE SSANGSIOS EO HIEUH
+0x9BAE	0xC385	#HANGUL SYLLABLE SSANGSIOS E KIYEOK
+0x9BAF	0xC386	#HANGUL SYLLABLE SSANGSIOS E SSANGKIYEOK
+0x9BB0	0xC387	#HANGUL SYLLABLE SSANGSIOS E KIYEOKSIOS
+0x9BB1	0xC389	#HANGUL SYLLABLE SSANGSIOS E NIEUNCIEUC
+0x9BB2	0xC38A	#HANGUL SYLLABLE SSANGSIOS E NIEUNHIEUH
+0x9BB3	0xC38B	#HANGUL SYLLABLE SSANGSIOS E TIKEUT
+0x9BB4	0xC38D	#HANGUL SYLLABLE SSANGSIOS E RIEULKIYEOK
+0x9BB5	0xC38E	#HANGUL SYLLABLE SSANGSIOS E RIEULMIEUM
+0x9BB6	0xC38F	#HANGUL SYLLABLE SSANGSIOS E RIEULPIEUP
+0x9BB7	0xC390	#HANGUL SYLLABLE SSANGSIOS E RIEULSIOS
+0x9BB8	0xC391	#HANGUL SYLLABLE SSANGSIOS E RIEULTHIEUTH
+0x9BB9	0xC392	#HANGUL SYLLABLE SSANGSIOS E RIEULPHIEUPH
+0x9BBA	0xC393	#HANGUL SYLLABLE SSANGSIOS E RIEULHIEUH
+0x9BBB	0xC394	#HANGUL SYLLABLE SSANGSIOS E MIEUM
+0x9BBC	0xC395	#HANGUL SYLLABLE SSANGSIOS E PIEUP
+0x9BBD	0xC396	#HANGUL SYLLABLE SSANGSIOS E PIEUPSIOS
+0x9BBE	0xC397	#HANGUL SYLLABLE SSANGSIOS E SIOS
+0x9BBF	0xC398	#HANGUL SYLLABLE SSANGSIOS E SSANGSIOS
+0x9BC0	0xC399	#HANGUL SYLLABLE SSANGSIOS E IEUNG
+0x9BC1	0xC39A	#HANGUL SYLLABLE SSANGSIOS E CIEUC
+0x9BC2	0xC39B	#HANGUL SYLLABLE SSANGSIOS E CHIEUCH
+0x9BC3	0xC39C	#HANGUL SYLLABLE SSANGSIOS E KHIEUKH
+0x9BC4	0xC39D	#HANGUL SYLLABLE SSANGSIOS E THIEUTH
+0x9BC5	0xC39E	#HANGUL SYLLABLE SSANGSIOS E PHIEUPH
+0x9BC6	0xC39F	#HANGUL SYLLABLE SSANGSIOS E HIEUH
+0x9BC7	0xC3A0	#HANGUL SYLLABLE SSANGSIOS YEO
+0x9BC8	0xC3A1	#HANGUL SYLLABLE SSANGSIOS YEO KIYEOK
+0x9BC9	0xC3A2	#HANGUL SYLLABLE SSANGSIOS YEO SSANGKIYEOK
+0x9BCA	0xC3A3	#HANGUL SYLLABLE SSANGSIOS YEO KIYEOKSIOS
+0x9BCB	0xC3A4	#HANGUL SYLLABLE SSANGSIOS YEO NIEUN
+0x9BCC	0xC3A5	#HANGUL SYLLABLE SSANGSIOS YEO NIEUNCIEUC
+0x9BCD	0xC3A6	#HANGUL SYLLABLE SSANGSIOS YEO NIEUNHIEUH
+0x9BCE	0xC3A7	#HANGUL SYLLABLE SSANGSIOS YEO TIKEUT
+0x9BCF	0xC3A8	#HANGUL SYLLABLE SSANGSIOS YEO RIEUL
+0x9BD0	0xC3A9	#HANGUL SYLLABLE SSANGSIOS YEO RIEULKIYEOK
+0x9BD1	0xC3AA	#HANGUL SYLLABLE SSANGSIOS YEO RIEULMIEUM
+0x9BD2	0xC3AB	#HANGUL SYLLABLE SSANGSIOS YEO RIEULPIEUP
+0x9BD3	0xC3AC	#HANGUL SYLLABLE SSANGSIOS YEO RIEULSIOS
+0x9BD4	0xC3AD	#HANGUL SYLLABLE SSANGSIOS YEO RIEULTHIEUTH
+0x9BD5	0xC3AE	#HANGUL SYLLABLE SSANGSIOS YEO RIEULPHIEUPH
+0x9BD6	0xC3AF	#HANGUL SYLLABLE SSANGSIOS YEO RIEULHIEUH
+0x9BD7	0xC3B0	#HANGUL SYLLABLE SSANGSIOS YEO MIEUM
+0x9BD8	0xC3B1	#HANGUL SYLLABLE SSANGSIOS YEO PIEUP
+0x9BD9	0xC3B2	#HANGUL SYLLABLE SSANGSIOS YEO PIEUPSIOS
+0x9BDA	0xC3B3	#HANGUL SYLLABLE SSANGSIOS YEO SIOS
+0x9BDB	0xC3B4	#HANGUL SYLLABLE SSANGSIOS YEO SSANGSIOS
+0x9BDC	0xC3B5	#HANGUL SYLLABLE SSANGSIOS YEO IEUNG
+0x9BDD	0xC3B6	#HANGUL SYLLABLE SSANGSIOS YEO CIEUC
+0x9BDE	0xC3B7	#HANGUL SYLLABLE SSANGSIOS YEO CHIEUCH
+0x9BDF	0xC3B8	#HANGUL SYLLABLE SSANGSIOS YEO KHIEUKH
+0x9BE0	0xC3B9	#HANGUL SYLLABLE SSANGSIOS YEO THIEUTH
+0x9BE1	0xC3BA	#HANGUL SYLLABLE SSANGSIOS YEO PHIEUPH
+0x9BE2	0xC3BB	#HANGUL SYLLABLE SSANGSIOS YEO HIEUH
+0x9BE3	0xC3BC	#HANGUL SYLLABLE SSANGSIOS YE
+0x9BE4	0xC3BD	#HANGUL SYLLABLE SSANGSIOS YE KIYEOK
+0x9BE5	0xC3BE	#HANGUL SYLLABLE SSANGSIOS YE SSANGKIYEOK
+0x9BE6	0xC3BF	#HANGUL SYLLABLE SSANGSIOS YE KIYEOKSIOS
+0x9BE7	0xC3C1	#HANGUL SYLLABLE SSANGSIOS YE NIEUNCIEUC
+0x9BE8	0xC3C2	#HANGUL SYLLABLE SSANGSIOS YE NIEUNHIEUH
+0x9BE9	0xC3C3	#HANGUL SYLLABLE SSANGSIOS YE TIKEUT
+0x9BEA	0xC3C4	#HANGUL SYLLABLE SSANGSIOS YE RIEUL
+0x9BEB	0xC3C5	#HANGUL SYLLABLE SSANGSIOS YE RIEULKIYEOK
+0x9BEC	0xC3C6	#HANGUL SYLLABLE SSANGSIOS YE RIEULMIEUM
+0x9BED	0xC3C7	#HANGUL SYLLABLE SSANGSIOS YE RIEULPIEUP
+0x9BEE	0xC3C8	#HANGUL SYLLABLE SSANGSIOS YE RIEULSIOS
+0x9BEF	0xC3C9	#HANGUL SYLLABLE SSANGSIOS YE RIEULTHIEUTH
+0x9BF0	0xC3CA	#HANGUL SYLLABLE SSANGSIOS YE RIEULPHIEUPH
+0x9BF1	0xC3CB	#HANGUL SYLLABLE SSANGSIOS YE RIEULHIEUH
+0x9BF2	0xC3CC	#HANGUL SYLLABLE SSANGSIOS YE MIEUM
+0x9BF3	0xC3CD	#HANGUL SYLLABLE SSANGSIOS YE PIEUP
+0x9BF4	0xC3CE	#HANGUL SYLLABLE SSANGSIOS YE PIEUPSIOS
+0x9BF5	0xC3CF	#HANGUL SYLLABLE SSANGSIOS YE SIOS
+0x9BF6	0xC3D0	#HANGUL SYLLABLE SSANGSIOS YE SSANGSIOS
+0x9BF7	0xC3D1	#HANGUL SYLLABLE SSANGSIOS YE IEUNG
+0x9BF8	0xC3D2	#HANGUL SYLLABLE SSANGSIOS YE CIEUC
+0x9BF9	0xC3D3	#HANGUL SYLLABLE SSANGSIOS YE CHIEUCH
+0x9BFA	0xC3D4	#HANGUL SYLLABLE SSANGSIOS YE KHIEUKH
+0x9BFB	0xC3D5	#HANGUL SYLLABLE SSANGSIOS YE THIEUTH
+0x9BFC	0xC3D6	#HANGUL SYLLABLE SSANGSIOS YE PHIEUPH
+0x9BFD	0xC3D7	#HANGUL SYLLABLE SSANGSIOS YE HIEUH
+0x9BFE	0xC3DA	#HANGUL SYLLABLE SSANGSIOS O SSANGKIYEOK
+0x9C41	0xC3DB	#HANGUL SYLLABLE SSANGSIOS O KIYEOKSIOS
+0x9C42	0xC3DD	#HANGUL SYLLABLE SSANGSIOS O NIEUNCIEUC
+0x9C43	0xC3DE	#HANGUL SYLLABLE SSANGSIOS O NIEUNHIEUH
+0x9C44	0xC3E1	#HANGUL SYLLABLE SSANGSIOS O RIEULKIYEOK
+0x9C45	0xC3E3	#HANGUL SYLLABLE SSANGSIOS O RIEULPIEUP
+0x9C46	0xC3E4	#HANGUL SYLLABLE SSANGSIOS O RIEULSIOS
+0x9C47	0xC3E5	#HANGUL SYLLABLE SSANGSIOS O RIEULTHIEUTH
+0x9C48	0xC3E6	#HANGUL SYLLABLE SSANGSIOS O RIEULPHIEUPH
+0x9C49	0xC3E7	#HANGUL SYLLABLE SSANGSIOS O RIEULHIEUH
+0x9C4A	0xC3EA	#HANGUL SYLLABLE SSANGSIOS O PIEUPSIOS
+0x9C4B	0xC3EB	#HANGUL SYLLABLE SSANGSIOS O SIOS
+0x9C4C	0xC3EC	#HANGUL SYLLABLE SSANGSIOS O SSANGSIOS
+0x9C4D	0xC3EE	#HANGUL SYLLABLE SSANGSIOS O CIEUC
+0x9C4E	0xC3EF	#HANGUL SYLLABLE SSANGSIOS O CHIEUCH
+0x9C4F	0xC3F0	#HANGUL SYLLABLE SSANGSIOS O KHIEUKH
+0x9C50	0xC3F1	#HANGUL SYLLABLE SSANGSIOS O THIEUTH
+0x9C51	0xC3F2	#HANGUL SYLLABLE SSANGSIOS O PHIEUPH
+0x9C52	0xC3F3	#HANGUL SYLLABLE SSANGSIOS O HIEUH
+0x9C53	0xC3F6	#HANGUL SYLLABLE SSANGSIOS WA SSANGKIYEOK
+0x9C54	0xC3F7	#HANGUL SYLLABLE SSANGSIOS WA KIYEOKSIOS
+0x9C55	0xC3F9	#HANGUL SYLLABLE SSANGSIOS WA NIEUNCIEUC
+0x9C56	0xC3FA	#HANGUL SYLLABLE SSANGSIOS WA NIEUNHIEUH
+0x9C57	0xC3FB	#HANGUL SYLLABLE SSANGSIOS WA TIKEUT
+0x9C58	0xC3FC	#HANGUL SYLLABLE SSANGSIOS WA RIEUL
+0x9C59	0xC3FD	#HANGUL SYLLABLE SSANGSIOS WA RIEULKIYEOK
+0x9C5A	0xC3FE	#HANGUL SYLLABLE SSANGSIOS WA RIEULMIEUM
+0x9C61	0xC3FF	#HANGUL SYLLABLE SSANGSIOS WA RIEULPIEUP
+0x9C62	0xC400	#HANGUL SYLLABLE SSANGSIOS WA RIEULSIOS
+0x9C63	0xC401	#HANGUL SYLLABLE SSANGSIOS WA RIEULTHIEUTH
+0x9C64	0xC402	#HANGUL SYLLABLE SSANGSIOS WA RIEULPHIEUPH
+0x9C65	0xC403	#HANGUL SYLLABLE SSANGSIOS WA RIEULHIEUH
+0x9C66	0xC404	#HANGUL SYLLABLE SSANGSIOS WA MIEUM
+0x9C67	0xC405	#HANGUL SYLLABLE SSANGSIOS WA PIEUP
+0x9C68	0xC406	#HANGUL SYLLABLE SSANGSIOS WA PIEUPSIOS
+0x9C69	0xC407	#HANGUL SYLLABLE SSANGSIOS WA SIOS
+0x9C6A	0xC409	#HANGUL SYLLABLE SSANGSIOS WA IEUNG
+0x9C6B	0xC40A	#HANGUL SYLLABLE SSANGSIOS WA CIEUC
+0x9C6C	0xC40B	#HANGUL SYLLABLE SSANGSIOS WA CHIEUCH
+0x9C6D	0xC40C	#HANGUL SYLLABLE SSANGSIOS WA KHIEUKH
+0x9C6E	0xC40D	#HANGUL SYLLABLE SSANGSIOS WA THIEUTH
+0x9C6F	0xC40E	#HANGUL SYLLABLE SSANGSIOS WA PHIEUPH
+0x9C70	0xC40F	#HANGUL SYLLABLE SSANGSIOS WA HIEUH
+0x9C71	0xC411	#HANGUL SYLLABLE SSANGSIOS WAE KIYEOK
+0x9C72	0xC412	#HANGUL SYLLABLE SSANGSIOS WAE SSANGKIYEOK
+0x9C73	0xC413	#HANGUL SYLLABLE SSANGSIOS WAE KIYEOKSIOS
+0x9C74	0xC414	#HANGUL SYLLABLE SSANGSIOS WAE NIEUN
+0x9C75	0xC415	#HANGUL SYLLABLE SSANGSIOS WAE NIEUNCIEUC
+0x9C76	0xC416	#HANGUL SYLLABLE SSANGSIOS WAE NIEUNHIEUH
+0x9C77	0xC417	#HANGUL SYLLABLE SSANGSIOS WAE TIKEUT
+0x9C78	0xC418	#HANGUL SYLLABLE SSANGSIOS WAE RIEUL
+0x9C79	0xC419	#HANGUL SYLLABLE SSANGSIOS WAE RIEULKIYEOK
+0x9C7A	0xC41A	#HANGUL SYLLABLE SSANGSIOS WAE RIEULMIEUM
+0x9C81	0xC41B	#HANGUL SYLLABLE SSANGSIOS WAE RIEULPIEUP
+0x9C82	0xC41C	#HANGUL SYLLABLE SSANGSIOS WAE RIEULSIOS
+0x9C83	0xC41D	#HANGUL SYLLABLE SSANGSIOS WAE RIEULTHIEUTH
+0x9C84	0xC41E	#HANGUL SYLLABLE SSANGSIOS WAE RIEULPHIEUPH
+0x9C85	0xC41F	#HANGUL SYLLABLE SSANGSIOS WAE RIEULHIEUH
+0x9C86	0xC420	#HANGUL SYLLABLE SSANGSIOS WAE MIEUM
+0x9C87	0xC421	#HANGUL SYLLABLE SSANGSIOS WAE PIEUP
+0x9C88	0xC422	#HANGUL SYLLABLE SSANGSIOS WAE PIEUPSIOS
+0x9C89	0xC423	#HANGUL SYLLABLE SSANGSIOS WAE SIOS
+0x9C8A	0xC425	#HANGUL SYLLABLE SSANGSIOS WAE IEUNG
+0x9C8B	0xC426	#HANGUL SYLLABLE SSANGSIOS WAE CIEUC
+0x9C8C	0xC427	#HANGUL SYLLABLE SSANGSIOS WAE CHIEUCH
+0x9C8D	0xC428	#HANGUL SYLLABLE SSANGSIOS WAE KHIEUKH
+0x9C8E	0xC429	#HANGUL SYLLABLE SSANGSIOS WAE THIEUTH
+0x9C8F	0xC42A	#HANGUL SYLLABLE SSANGSIOS WAE PHIEUPH
+0x9C90	0xC42B	#HANGUL SYLLABLE SSANGSIOS WAE HIEUH
+0x9C91	0xC42D	#HANGUL SYLLABLE SSANGSIOS OE KIYEOK
+0x9C92	0xC42E	#HANGUL SYLLABLE SSANGSIOS OE SSANGKIYEOK
+0x9C93	0xC42F	#HANGUL SYLLABLE SSANGSIOS OE KIYEOKSIOS
+0x9C94	0xC431	#HANGUL SYLLABLE SSANGSIOS OE NIEUNCIEUC
+0x9C95	0xC432	#HANGUL SYLLABLE SSANGSIOS OE NIEUNHIEUH
+0x9C96	0xC433	#HANGUL SYLLABLE SSANGSIOS OE TIKEUT
+0x9C97	0xC435	#HANGUL SYLLABLE SSANGSIOS OE RIEULKIYEOK
+0x9C98	0xC436	#HANGUL SYLLABLE SSANGSIOS OE RIEULMIEUM
+0x9C99	0xC437	#HANGUL SYLLABLE SSANGSIOS OE RIEULPIEUP
+0x9C9A	0xC438	#HANGUL SYLLABLE SSANGSIOS OE RIEULSIOS
+0x9C9B	0xC439	#HANGUL SYLLABLE SSANGSIOS OE RIEULTHIEUTH
+0x9C9C	0xC43A	#HANGUL SYLLABLE SSANGSIOS OE RIEULPHIEUPH
+0x9C9D	0xC43B	#HANGUL SYLLABLE SSANGSIOS OE RIEULHIEUH
+0x9C9E	0xC43E	#HANGUL SYLLABLE SSANGSIOS OE PIEUPSIOS
+0x9C9F	0xC43F	#HANGUL SYLLABLE SSANGSIOS OE SIOS
+0x9CA0	0xC440	#HANGUL SYLLABLE SSANGSIOS OE SSANGSIOS
+0x9CA1	0xC441	#HANGUL SYLLABLE SSANGSIOS OE IEUNG
+0x9CA2	0xC442	#HANGUL SYLLABLE SSANGSIOS OE CIEUC
+0x9CA3	0xC443	#HANGUL SYLLABLE SSANGSIOS OE CHIEUCH
+0x9CA4	0xC444	#HANGUL SYLLABLE SSANGSIOS OE KHIEUKH
+0x9CA5	0xC445	#HANGUL SYLLABLE SSANGSIOS OE THIEUTH
+0x9CA6	0xC446	#HANGUL SYLLABLE SSANGSIOS OE PHIEUPH
+0x9CA7	0xC447	#HANGUL SYLLABLE SSANGSIOS OE HIEUH
+0x9CA8	0xC449	#HANGUL SYLLABLE SSANGSIOS YO KIYEOK
+0x9CA9	0xC44A	#HANGUL SYLLABLE SSANGSIOS YO SSANGKIYEOK
+0x9CAA	0xC44B	#HANGUL SYLLABLE SSANGSIOS YO KIYEOKSIOS
+0x9CAB	0xC44C	#HANGUL SYLLABLE SSANGSIOS YO NIEUN
+0x9CAC	0xC44D	#HANGUL SYLLABLE SSANGSIOS YO NIEUNCIEUC
+0x9CAD	0xC44E	#HANGUL SYLLABLE SSANGSIOS YO NIEUNHIEUH
+0x9CAE	0xC44F	#HANGUL SYLLABLE SSANGSIOS YO TIKEUT
+0x9CAF	0xC450	#HANGUL SYLLABLE SSANGSIOS YO RIEUL
+0x9CB0	0xC451	#HANGUL SYLLABLE SSANGSIOS YO RIEULKIYEOK
+0x9CB1	0xC452	#HANGUL SYLLABLE SSANGSIOS YO RIEULMIEUM
+0x9CB2	0xC453	#HANGUL SYLLABLE SSANGSIOS YO RIEULPIEUP
+0x9CB3	0xC454	#HANGUL SYLLABLE SSANGSIOS YO RIEULSIOS
+0x9CB4	0xC455	#HANGUL SYLLABLE SSANGSIOS YO RIEULTHIEUTH
+0x9CB5	0xC456	#HANGUL SYLLABLE SSANGSIOS YO RIEULPHIEUPH
+0x9CB6	0xC457	#HANGUL SYLLABLE SSANGSIOS YO RIEULHIEUH
+0x9CB7	0xC458	#HANGUL SYLLABLE SSANGSIOS YO MIEUM
+0x9CB8	0xC459	#HANGUL SYLLABLE SSANGSIOS YO PIEUP
+0x9CB9	0xC45A	#HANGUL SYLLABLE SSANGSIOS YO PIEUPSIOS
+0x9CBA	0xC45B	#HANGUL SYLLABLE SSANGSIOS YO SIOS
+0x9CBB	0xC45C	#HANGUL SYLLABLE SSANGSIOS YO SSANGSIOS
+0x9CBC	0xC45D	#HANGUL SYLLABLE SSANGSIOS YO IEUNG
+0x9CBD	0xC45E	#HANGUL SYLLABLE SSANGSIOS YO CIEUC
+0x9CBE	0xC45F	#HANGUL SYLLABLE SSANGSIOS YO CHIEUCH
+0x9CBF	0xC460	#HANGUL SYLLABLE SSANGSIOS YO KHIEUKH
+0x9CC0	0xC461	#HANGUL SYLLABLE SSANGSIOS YO THIEUTH
+0x9CC1	0xC462	#HANGUL SYLLABLE SSANGSIOS YO PHIEUPH
+0x9CC2	0xC463	#HANGUL SYLLABLE SSANGSIOS YO HIEUH
+0x9CC3	0xC466	#HANGUL SYLLABLE SSANGSIOS U SSANGKIYEOK
+0x9CC4	0xC467	#HANGUL SYLLABLE SSANGSIOS U KIYEOKSIOS
+0x9CC5	0xC469	#HANGUL SYLLABLE SSANGSIOS U NIEUNCIEUC
+0x9CC6	0xC46A	#HANGUL SYLLABLE SSANGSIOS U NIEUNHIEUH
+0x9CC7	0xC46B	#HANGUL SYLLABLE SSANGSIOS U TIKEUT
+0x9CC8	0xC46D	#HANGUL SYLLABLE SSANGSIOS U RIEULKIYEOK
+0x9CC9	0xC46E	#HANGUL SYLLABLE SSANGSIOS U RIEULMIEUM
+0x9CCA	0xC46F	#HANGUL SYLLABLE SSANGSIOS U RIEULPIEUP
+0x9CCB	0xC470	#HANGUL SYLLABLE SSANGSIOS U RIEULSIOS
+0x9CCC	0xC471	#HANGUL SYLLABLE SSANGSIOS U RIEULTHIEUTH
+0x9CCD	0xC472	#HANGUL SYLLABLE SSANGSIOS U RIEULPHIEUPH
+0x9CCE	0xC473	#HANGUL SYLLABLE SSANGSIOS U RIEULHIEUH
+0x9CCF	0xC476	#HANGUL SYLLABLE SSANGSIOS U PIEUPSIOS
+0x9CD0	0xC477	#HANGUL SYLLABLE SSANGSIOS U SIOS
+0x9CD1	0xC478	#HANGUL SYLLABLE SSANGSIOS U SSANGSIOS
+0x9CD2	0xC47A	#HANGUL SYLLABLE SSANGSIOS U CIEUC
+0x9CD3	0xC47B	#HANGUL SYLLABLE SSANGSIOS U CHIEUCH
+0x9CD4	0xC47C	#HANGUL SYLLABLE SSANGSIOS U KHIEUKH
+0x9CD5	0xC47D	#HANGUL SYLLABLE SSANGSIOS U THIEUTH
+0x9CD6	0xC47E	#HANGUL SYLLABLE SSANGSIOS U PHIEUPH
+0x9CD7	0xC47F	#HANGUL SYLLABLE SSANGSIOS U HIEUH
+0x9CD8	0xC481	#HANGUL SYLLABLE SSANGSIOS WEO KIYEOK
+0x9CD9	0xC482	#HANGUL SYLLABLE SSANGSIOS WEO SSANGKIYEOK
+0x9CDA	0xC483	#HANGUL SYLLABLE SSANGSIOS WEO KIYEOKSIOS
+0x9CDB	0xC484	#HANGUL SYLLABLE SSANGSIOS WEO NIEUN
+0x9CDC	0xC485	#HANGUL SYLLABLE SSANGSIOS WEO NIEUNCIEUC
+0x9CDD	0xC486	#HANGUL SYLLABLE SSANGSIOS WEO NIEUNHIEUH
+0x9CDE	0xC487	#HANGUL SYLLABLE SSANGSIOS WEO TIKEUT
+0x9CDF	0xC488	#HANGUL SYLLABLE SSANGSIOS WEO RIEUL
+0x9CE0	0xC489	#HANGUL SYLLABLE SSANGSIOS WEO RIEULKIYEOK
+0x9CE1	0xC48A	#HANGUL SYLLABLE SSANGSIOS WEO RIEULMIEUM
+0x9CE2	0xC48B	#HANGUL SYLLABLE SSANGSIOS WEO RIEULPIEUP
+0x9CE3	0xC48C	#HANGUL SYLLABLE SSANGSIOS WEO RIEULSIOS
+0x9CE4	0xC48D	#HANGUL SYLLABLE SSANGSIOS WEO RIEULTHIEUTH
+0x9CE5	0xC48E	#HANGUL SYLLABLE SSANGSIOS WEO RIEULPHIEUPH
+0x9CE6	0xC48F	#HANGUL SYLLABLE SSANGSIOS WEO RIEULHIEUH
+0x9CE7	0xC490	#HANGUL SYLLABLE SSANGSIOS WEO MIEUM
+0x9CE8	0xC491	#HANGUL SYLLABLE SSANGSIOS WEO PIEUP
+0x9CE9	0xC492	#HANGUL SYLLABLE SSANGSIOS WEO PIEUPSIOS
+0x9CEA	0xC493	#HANGUL SYLLABLE SSANGSIOS WEO SIOS
+0x9CEB	0xC495	#HANGUL SYLLABLE SSANGSIOS WEO IEUNG
+0x9CEC	0xC496	#HANGUL SYLLABLE SSANGSIOS WEO CIEUC
+0x9CED	0xC497	#HANGUL SYLLABLE SSANGSIOS WEO CHIEUCH
+0x9CEE	0xC498	#HANGUL SYLLABLE SSANGSIOS WEO KHIEUKH
+0x9CEF	0xC499	#HANGUL SYLLABLE SSANGSIOS WEO THIEUTH
+0x9CF0	0xC49A	#HANGUL SYLLABLE SSANGSIOS WEO PHIEUPH
+0x9CF1	0xC49B	#HANGUL SYLLABLE SSANGSIOS WEO HIEUH
+0x9CF2	0xC49D	#HANGUL SYLLABLE SSANGSIOS WE KIYEOK
+0x9CF3	0xC49E	#HANGUL SYLLABLE SSANGSIOS WE SSANGKIYEOK
+0x9CF4	0xC49F	#HANGUL SYLLABLE SSANGSIOS WE KIYEOKSIOS
+0x9CF5	0xC4A0	#HANGUL SYLLABLE SSANGSIOS WE NIEUN
+0x9CF6	0xC4A1	#HANGUL SYLLABLE SSANGSIOS WE NIEUNCIEUC
+0x9CF7	0xC4A2	#HANGUL SYLLABLE SSANGSIOS WE NIEUNHIEUH
+0x9CF8	0xC4A3	#HANGUL SYLLABLE SSANGSIOS WE TIKEUT
+0x9CF9	0xC4A4	#HANGUL SYLLABLE SSANGSIOS WE RIEUL
+0x9CFA	0xC4A5	#HANGUL SYLLABLE SSANGSIOS WE RIEULKIYEOK
+0x9CFB	0xC4A6	#HANGUL SYLLABLE SSANGSIOS WE RIEULMIEUM
+0x9CFC	0xC4A7	#HANGUL SYLLABLE SSANGSIOS WE RIEULPIEUP
+0x9CFD	0xC4A8	#HANGUL SYLLABLE SSANGSIOS WE RIEULSIOS
+0x9CFE	0xC4A9	#HANGUL SYLLABLE SSANGSIOS WE RIEULTHIEUTH
+0x9D41	0xC4AA	#HANGUL SYLLABLE SSANGSIOS WE RIEULPHIEUPH
+0x9D42	0xC4AB	#HANGUL SYLLABLE SSANGSIOS WE RIEULHIEUH
+0x9D43	0xC4AC	#HANGUL SYLLABLE SSANGSIOS WE MIEUM
+0x9D44	0xC4AD	#HANGUL SYLLABLE SSANGSIOS WE PIEUP
+0x9D45	0xC4AE	#HANGUL SYLLABLE SSANGSIOS WE PIEUPSIOS
+0x9D46	0xC4AF	#HANGUL SYLLABLE SSANGSIOS WE SIOS
+0x9D47	0xC4B0	#HANGUL SYLLABLE SSANGSIOS WE SSANGSIOS
+0x9D48	0xC4B1	#HANGUL SYLLABLE SSANGSIOS WE IEUNG
+0x9D49	0xC4B2	#HANGUL SYLLABLE SSANGSIOS WE CIEUC
+0x9D4A	0xC4B3	#HANGUL SYLLABLE SSANGSIOS WE CHIEUCH
+0x9D4B	0xC4B4	#HANGUL SYLLABLE SSANGSIOS WE KHIEUKH
+0x9D4C	0xC4B5	#HANGUL SYLLABLE SSANGSIOS WE THIEUTH
+0x9D4D	0xC4B6	#HANGUL SYLLABLE SSANGSIOS WE PHIEUPH
+0x9D4E	0xC4B7	#HANGUL SYLLABLE SSANGSIOS WE HIEUH
+0x9D4F	0xC4B9	#HANGUL SYLLABLE SSANGSIOS WI KIYEOK
+0x9D50	0xC4BA	#HANGUL SYLLABLE SSANGSIOS WI SSANGKIYEOK
+0x9D51	0xC4BB	#HANGUL SYLLABLE SSANGSIOS WI KIYEOKSIOS
+0x9D52	0xC4BD	#HANGUL SYLLABLE SSANGSIOS WI NIEUNCIEUC
+0x9D53	0xC4BE	#HANGUL SYLLABLE SSANGSIOS WI NIEUNHIEUH
+0x9D54	0xC4BF	#HANGUL SYLLABLE SSANGSIOS WI TIKEUT
+0x9D55	0xC4C0	#HANGUL SYLLABLE SSANGSIOS WI RIEUL
+0x9D56	0xC4C1	#HANGUL SYLLABLE SSANGSIOS WI RIEULKIYEOK
+0x9D57	0xC4C2	#HANGUL SYLLABLE SSANGSIOS WI RIEULMIEUM
+0x9D58	0xC4C3	#HANGUL SYLLABLE SSANGSIOS WI RIEULPIEUP
+0x9D59	0xC4C4	#HANGUL SYLLABLE SSANGSIOS WI RIEULSIOS
+0x9D5A	0xC4C5	#HANGUL SYLLABLE SSANGSIOS WI RIEULTHIEUTH
+0x9D61	0xC4C6	#HANGUL SYLLABLE SSANGSIOS WI RIEULPHIEUPH
+0x9D62	0xC4C7	#HANGUL SYLLABLE SSANGSIOS WI RIEULHIEUH
+0x9D63	0xC4C8	#HANGUL SYLLABLE SSANGSIOS WI MIEUM
+0x9D64	0xC4C9	#HANGUL SYLLABLE SSANGSIOS WI PIEUP
+0x9D65	0xC4CA	#HANGUL SYLLABLE SSANGSIOS WI PIEUPSIOS
+0x9D66	0xC4CB	#HANGUL SYLLABLE SSANGSIOS WI SIOS
+0x9D67	0xC4CC	#HANGUL SYLLABLE SSANGSIOS WI SSANGSIOS
+0x9D68	0xC4CD	#HANGUL SYLLABLE SSANGSIOS WI IEUNG
+0x9D69	0xC4CE	#HANGUL SYLLABLE SSANGSIOS WI CIEUC
+0x9D6A	0xC4CF	#HANGUL SYLLABLE SSANGSIOS WI CHIEUCH
+0x9D6B	0xC4D0	#HANGUL SYLLABLE SSANGSIOS WI KHIEUKH
+0x9D6C	0xC4D1	#HANGUL SYLLABLE SSANGSIOS WI THIEUTH
+0x9D6D	0xC4D2	#HANGUL SYLLABLE SSANGSIOS WI PHIEUPH
+0x9D6E	0xC4D3	#HANGUL SYLLABLE SSANGSIOS WI HIEUH
+0x9D6F	0xC4D4	#HANGUL SYLLABLE SSANGSIOS YU
+0x9D70	0xC4D5	#HANGUL SYLLABLE SSANGSIOS YU KIYEOK
+0x9D71	0xC4D6	#HANGUL SYLLABLE SSANGSIOS YU SSANGKIYEOK
+0x9D72	0xC4D7	#HANGUL SYLLABLE SSANGSIOS YU KIYEOKSIOS
+0x9D73	0xC4D8	#HANGUL SYLLABLE SSANGSIOS YU NIEUN
+0x9D74	0xC4D9	#HANGUL SYLLABLE SSANGSIOS YU NIEUNCIEUC
+0x9D75	0xC4DA	#HANGUL SYLLABLE SSANGSIOS YU NIEUNHIEUH
+0x9D76	0xC4DB	#HANGUL SYLLABLE SSANGSIOS YU TIKEUT
+0x9D77	0xC4DC	#HANGUL SYLLABLE SSANGSIOS YU RIEUL
+0x9D78	0xC4DD	#HANGUL SYLLABLE SSANGSIOS YU RIEULKIYEOK
+0x9D79	0xC4DE	#HANGUL SYLLABLE SSANGSIOS YU RIEULMIEUM
+0x9D7A	0xC4DF	#HANGUL SYLLABLE SSANGSIOS YU RIEULPIEUP
+0x9D81	0xC4E0	#HANGUL SYLLABLE SSANGSIOS YU RIEULSIOS
+0x9D82	0xC4E1	#HANGUL SYLLABLE SSANGSIOS YU RIEULTHIEUTH
+0x9D83	0xC4E2	#HANGUL SYLLABLE SSANGSIOS YU RIEULPHIEUPH
+0x9D84	0xC4E3	#HANGUL SYLLABLE SSANGSIOS YU RIEULHIEUH
+0x9D85	0xC4E4	#HANGUL SYLLABLE SSANGSIOS YU MIEUM
+0x9D86	0xC4E5	#HANGUL SYLLABLE SSANGSIOS YU PIEUP
+0x9D87	0xC4E6	#HANGUL SYLLABLE SSANGSIOS YU PIEUPSIOS
+0x9D88	0xC4E7	#HANGUL SYLLABLE SSANGSIOS YU SIOS
+0x9D89	0xC4E8	#HANGUL SYLLABLE SSANGSIOS YU SSANGSIOS
+0x9D8A	0xC4EA	#HANGUL SYLLABLE SSANGSIOS YU CIEUC
+0x9D8B	0xC4EB	#HANGUL SYLLABLE SSANGSIOS YU CHIEUCH
+0x9D8C	0xC4EC	#HANGUL SYLLABLE SSANGSIOS YU KHIEUKH
+0x9D8D	0xC4ED	#HANGUL SYLLABLE SSANGSIOS YU THIEUTH
+0x9D8E	0xC4EE	#HANGUL SYLLABLE SSANGSIOS YU PHIEUPH
+0x9D8F	0xC4EF	#HANGUL SYLLABLE SSANGSIOS YU HIEUH
+0x9D90	0xC4F2	#HANGUL SYLLABLE SSANGSIOS EU SSANGKIYEOK
+0x9D91	0xC4F3	#HANGUL SYLLABLE SSANGSIOS EU KIYEOKSIOS
+0x9D92	0xC4F5	#HANGUL SYLLABLE SSANGSIOS EU NIEUNCIEUC
+0x9D93	0xC4F6	#HANGUL SYLLABLE SSANGSIOS EU NIEUNHIEUH
+0x9D94	0xC4F7	#HANGUL SYLLABLE SSANGSIOS EU TIKEUT
+0x9D95	0xC4F9	#HANGUL SYLLABLE SSANGSIOS EU RIEULKIYEOK
+0x9D96	0xC4FB	#HANGUL SYLLABLE SSANGSIOS EU RIEULPIEUP
+0x9D97	0xC4FC	#HANGUL SYLLABLE SSANGSIOS EU RIEULSIOS
+0x9D98	0xC4FD	#HANGUL SYLLABLE SSANGSIOS EU RIEULTHIEUTH
+0x9D99	0xC4FE	#HANGUL SYLLABLE SSANGSIOS EU RIEULPHIEUPH
+0x9D9A	0xC502	#HANGUL SYLLABLE SSANGSIOS EU PIEUPSIOS
+0x9D9B	0xC503	#HANGUL SYLLABLE SSANGSIOS EU SIOS
+0x9D9C	0xC504	#HANGUL SYLLABLE SSANGSIOS EU SSANGSIOS
+0x9D9D	0xC505	#HANGUL SYLLABLE SSANGSIOS EU IEUNG
+0x9D9E	0xC506	#HANGUL SYLLABLE SSANGSIOS EU CIEUC
+0x9D9F	0xC507	#HANGUL SYLLABLE SSANGSIOS EU CHIEUCH
+0x9DA0	0xC508	#HANGUL SYLLABLE SSANGSIOS EU KHIEUKH
+0x9DA1	0xC509	#HANGUL SYLLABLE SSANGSIOS EU THIEUTH
+0x9DA2	0xC50A	#HANGUL SYLLABLE SSANGSIOS EU PHIEUPH
+0x9DA3	0xC50B	#HANGUL SYLLABLE SSANGSIOS EU HIEUH
+0x9DA4	0xC50D	#HANGUL SYLLABLE SSANGSIOS YI KIYEOK
+0x9DA5	0xC50E	#HANGUL SYLLABLE SSANGSIOS YI SSANGKIYEOK
+0x9DA6	0xC50F	#HANGUL SYLLABLE SSANGSIOS YI KIYEOKSIOS
+0x9DA7	0xC511	#HANGUL SYLLABLE SSANGSIOS YI NIEUNCIEUC
+0x9DA8	0xC512	#HANGUL SYLLABLE SSANGSIOS YI NIEUNHIEUH
+0x9DA9	0xC513	#HANGUL SYLLABLE SSANGSIOS YI TIKEUT
+0x9DAA	0xC515	#HANGUL SYLLABLE SSANGSIOS YI RIEULKIYEOK
+0x9DAB	0xC516	#HANGUL SYLLABLE SSANGSIOS YI RIEULMIEUM
+0x9DAC	0xC517	#HANGUL SYLLABLE SSANGSIOS YI RIEULPIEUP
+0x9DAD	0xC518	#HANGUL SYLLABLE SSANGSIOS YI RIEULSIOS
+0x9DAE	0xC519	#HANGUL SYLLABLE SSANGSIOS YI RIEULTHIEUTH
+0x9DAF	0xC51A	#HANGUL SYLLABLE SSANGSIOS YI RIEULPHIEUPH
+0x9DB0	0xC51B	#HANGUL SYLLABLE SSANGSIOS YI RIEULHIEUH
+0x9DB1	0xC51D	#HANGUL SYLLABLE SSANGSIOS YI PIEUP
+0x9DB2	0xC51E	#HANGUL SYLLABLE SSANGSIOS YI PIEUPSIOS
+0x9DB3	0xC51F	#HANGUL SYLLABLE SSANGSIOS YI SIOS
+0x9DB4	0xC520	#HANGUL SYLLABLE SSANGSIOS YI SSANGSIOS
+0x9DB5	0xC521	#HANGUL SYLLABLE SSANGSIOS YI IEUNG
+0x9DB6	0xC522	#HANGUL SYLLABLE SSANGSIOS YI CIEUC
+0x9DB7	0xC523	#HANGUL SYLLABLE SSANGSIOS YI CHIEUCH
+0x9DB8	0xC524	#HANGUL SYLLABLE SSANGSIOS YI KHIEUKH
+0x9DB9	0xC525	#HANGUL SYLLABLE SSANGSIOS YI THIEUTH
+0x9DBA	0xC526	#HANGUL SYLLABLE SSANGSIOS YI PHIEUPH
+0x9DBB	0xC527	#HANGUL SYLLABLE SSANGSIOS YI HIEUH
+0x9DBC	0xC52A	#HANGUL SYLLABLE SSANGSIOS I SSANGKIYEOK
+0x9DBD	0xC52B	#HANGUL SYLLABLE SSANGSIOS I KIYEOKSIOS
+0x9DBE	0xC52D	#HANGUL SYLLABLE SSANGSIOS I NIEUNCIEUC
+0x9DBF	0xC52E	#HANGUL SYLLABLE SSANGSIOS I NIEUNHIEUH
+0x9DC0	0xC52F	#HANGUL SYLLABLE SSANGSIOS I TIKEUT
+0x9DC1	0xC531	#HANGUL SYLLABLE SSANGSIOS I RIEULKIYEOK
+0x9DC2	0xC532	#HANGUL SYLLABLE SSANGSIOS I RIEULMIEUM
+0x9DC3	0xC533	#HANGUL SYLLABLE SSANGSIOS I RIEULPIEUP
+0x9DC4	0xC534	#HANGUL SYLLABLE SSANGSIOS I RIEULSIOS
+0x9DC5	0xC535	#HANGUL SYLLABLE SSANGSIOS I RIEULTHIEUTH
+0x9DC6	0xC536	#HANGUL SYLLABLE SSANGSIOS I RIEULPHIEUPH
+0x9DC7	0xC537	#HANGUL SYLLABLE SSANGSIOS I RIEULHIEUH
+0x9DC8	0xC53A	#HANGUL SYLLABLE SSANGSIOS I PIEUPSIOS
+0x9DC9	0xC53C	#HANGUL SYLLABLE SSANGSIOS I SSANGSIOS
+0x9DCA	0xC53E	#HANGUL SYLLABLE SSANGSIOS I CIEUC
+0x9DCB	0xC53F	#HANGUL SYLLABLE SSANGSIOS I CHIEUCH
+0x9DCC	0xC540	#HANGUL SYLLABLE SSANGSIOS I KHIEUKH
+0x9DCD	0xC541	#HANGUL SYLLABLE SSANGSIOS I THIEUTH
+0x9DCE	0xC542	#HANGUL SYLLABLE SSANGSIOS I PHIEUPH
+0x9DCF	0xC543	#HANGUL SYLLABLE SSANGSIOS I HIEUH
+0x9DD0	0xC546	#HANGUL SYLLABLE IEUNG A SSANGKIYEOK
+0x9DD1	0xC547	#HANGUL SYLLABLE IEUNG A KIYEOKSIOS
+0x9DD2	0xC54B	#HANGUL SYLLABLE IEUNG A TIKEUT
+0x9DD3	0xC54F	#HANGUL SYLLABLE IEUNG A RIEULPIEUP
+0x9DD4	0xC550	#HANGUL SYLLABLE IEUNG A RIEULSIOS
+0x9DD5	0xC551	#HANGUL SYLLABLE IEUNG A RIEULTHIEUTH
+0x9DD6	0xC552	#HANGUL SYLLABLE IEUNG A RIEULPHIEUPH
+0x9DD7	0xC556	#HANGUL SYLLABLE IEUNG A PIEUPSIOS
+0x9DD8	0xC55A	#HANGUL SYLLABLE IEUNG A CIEUC
+0x9DD9	0xC55B	#HANGUL SYLLABLE IEUNG A CHIEUCH
+0x9DDA	0xC55C	#HANGUL SYLLABLE IEUNG A KHIEUKH
+0x9DDB	0xC55F	#HANGUL SYLLABLE IEUNG A HIEUH
+0x9DDC	0xC562	#HANGUL SYLLABLE IEUNG AE SSANGKIYEOK
+0x9DDD	0xC563	#HANGUL SYLLABLE IEUNG AE KIYEOKSIOS
+0x9DDE	0xC565	#HANGUL SYLLABLE IEUNG AE NIEUNCIEUC
+0x9DDF	0xC566	#HANGUL SYLLABLE IEUNG AE NIEUNHIEUH
+0x9DE0	0xC567	#HANGUL SYLLABLE IEUNG AE TIKEUT
+0x9DE1	0xC569	#HANGUL SYLLABLE IEUNG AE RIEULKIYEOK
+0x9DE2	0xC56A	#HANGUL SYLLABLE IEUNG AE RIEULMIEUM
+0x9DE3	0xC56B	#HANGUL SYLLABLE IEUNG AE RIEULPIEUP
+0x9DE4	0xC56C	#HANGUL SYLLABLE IEUNG AE RIEULSIOS
+0x9DE5	0xC56D	#HANGUL SYLLABLE IEUNG AE RIEULTHIEUTH
+0x9DE6	0xC56E	#HANGUL SYLLABLE IEUNG AE RIEULPHIEUPH
+0x9DE7	0xC56F	#HANGUL SYLLABLE IEUNG AE RIEULHIEUH
+0x9DE8	0xC572	#HANGUL SYLLABLE IEUNG AE PIEUPSIOS
+0x9DE9	0xC576	#HANGUL SYLLABLE IEUNG AE CIEUC
+0x9DEA	0xC577	#HANGUL SYLLABLE IEUNG AE CHIEUCH
+0x9DEB	0xC578	#HANGUL SYLLABLE IEUNG AE KHIEUKH
+0x9DEC	0xC579	#HANGUL SYLLABLE IEUNG AE THIEUTH
+0x9DED	0xC57A	#HANGUL SYLLABLE IEUNG AE PHIEUPH
+0x9DEE	0xC57B	#HANGUL SYLLABLE IEUNG AE HIEUH
+0x9DEF	0xC57E	#HANGUL SYLLABLE IEUNG YA SSANGKIYEOK
+0x9DF0	0xC57F	#HANGUL SYLLABLE IEUNG YA KIYEOKSIOS
+0x9DF1	0xC581	#HANGUL SYLLABLE IEUNG YA NIEUNCIEUC
+0x9DF2	0xC582	#HANGUL SYLLABLE IEUNG YA NIEUNHIEUH
+0x9DF3	0xC583	#HANGUL SYLLABLE IEUNG YA TIKEUT
+0x9DF4	0xC585	#HANGUL SYLLABLE IEUNG YA RIEULKIYEOK
+0x9DF5	0xC586	#HANGUL SYLLABLE IEUNG YA RIEULMIEUM
+0x9DF6	0xC588	#HANGUL SYLLABLE IEUNG YA RIEULSIOS
+0x9DF7	0xC589	#HANGUL SYLLABLE IEUNG YA RIEULTHIEUTH
+0x9DF8	0xC58A	#HANGUL SYLLABLE IEUNG YA RIEULPHIEUPH
+0x9DF9	0xC58B	#HANGUL SYLLABLE IEUNG YA RIEULHIEUH
+0x9DFA	0xC58E	#HANGUL SYLLABLE IEUNG YA PIEUPSIOS
+0x9DFB	0xC590	#HANGUL SYLLABLE IEUNG YA SSANGSIOS
+0x9DFC	0xC592	#HANGUL SYLLABLE IEUNG YA CIEUC
+0x9DFD	0xC593	#HANGUL SYLLABLE IEUNG YA CHIEUCH
+0x9DFE	0xC594	#HANGUL SYLLABLE IEUNG YA KHIEUKH
+0x9E41	0xC596	#HANGUL SYLLABLE IEUNG YA PHIEUPH
+0x9E42	0xC599	#HANGUL SYLLABLE IEUNG YAE KIYEOK
+0x9E43	0xC59A	#HANGUL SYLLABLE IEUNG YAE SSANGKIYEOK
+0x9E44	0xC59B	#HANGUL SYLLABLE IEUNG YAE KIYEOKSIOS
+0x9E45	0xC59D	#HANGUL SYLLABLE IEUNG YAE NIEUNCIEUC
+0x9E46	0xC59E	#HANGUL SYLLABLE IEUNG YAE NIEUNHIEUH
+0x9E47	0xC59F	#HANGUL SYLLABLE IEUNG YAE TIKEUT
+0x9E48	0xC5A1	#HANGUL SYLLABLE IEUNG YAE RIEULKIYEOK
+0x9E49	0xC5A2	#HANGUL SYLLABLE IEUNG YAE RIEULMIEUM
+0x9E4A	0xC5A3	#HANGUL SYLLABLE IEUNG YAE RIEULPIEUP
+0x9E4B	0xC5A4	#HANGUL SYLLABLE IEUNG YAE RIEULSIOS
+0x9E4C	0xC5A5	#HANGUL SYLLABLE IEUNG YAE RIEULTHIEUTH
+0x9E4D	0xC5A6	#HANGUL SYLLABLE IEUNG YAE RIEULPHIEUPH
+0x9E4E	0xC5A7	#HANGUL SYLLABLE IEUNG YAE RIEULHIEUH
+0x9E4F	0xC5A8	#HANGUL SYLLABLE IEUNG YAE MIEUM
+0x9E50	0xC5AA	#HANGUL SYLLABLE IEUNG YAE PIEUPSIOS
+0x9E51	0xC5AB	#HANGUL SYLLABLE IEUNG YAE SIOS
+0x9E52	0xC5AC	#HANGUL SYLLABLE IEUNG YAE SSANGSIOS
+0x9E53	0xC5AD	#HANGUL SYLLABLE IEUNG YAE IEUNG
+0x9E54	0xC5AE	#HANGUL SYLLABLE IEUNG YAE CIEUC
+0x9E55	0xC5AF	#HANGUL SYLLABLE IEUNG YAE CHIEUCH
+0x9E56	0xC5B0	#HANGUL SYLLABLE IEUNG YAE KHIEUKH
+0x9E57	0xC5B1	#HANGUL SYLLABLE IEUNG YAE THIEUTH
+0x9E58	0xC5B2	#HANGUL SYLLABLE IEUNG YAE PHIEUPH
+0x9E59	0xC5B3	#HANGUL SYLLABLE IEUNG YAE HIEUH
+0x9E5A	0xC5B6	#HANGUL SYLLABLE IEUNG EO SSANGKIYEOK
+0x9E61	0xC5B7	#HANGUL SYLLABLE IEUNG EO KIYEOKSIOS
+0x9E62	0xC5BA	#HANGUL SYLLABLE IEUNG EO NIEUNHIEUH
+0x9E63	0xC5BF	#HANGUL SYLLABLE IEUNG EO RIEULPIEUP
+0x9E64	0xC5C0	#HANGUL SYLLABLE IEUNG EO RIEULSIOS
+0x9E65	0xC5C1	#HANGUL SYLLABLE IEUNG EO RIEULTHIEUTH
+0x9E66	0xC5C2	#HANGUL SYLLABLE IEUNG EO RIEULPHIEUPH
+0x9E67	0xC5C3	#HANGUL SYLLABLE IEUNG EO RIEULHIEUH
+0x9E68	0xC5CB	#HANGUL SYLLABLE IEUNG EO CHIEUCH
+0x9E69	0xC5CD	#HANGUL SYLLABLE IEUNG EO THIEUTH
+0x9E6A	0xC5CF	#HANGUL SYLLABLE IEUNG EO HIEUH
+0x9E6B	0xC5D2	#HANGUL SYLLABLE IEUNG E SSANGKIYEOK
+0x9E6C	0xC5D3	#HANGUL SYLLABLE IEUNG E KIYEOKSIOS
+0x9E6D	0xC5D5	#HANGUL SYLLABLE IEUNG E NIEUNCIEUC
+0x9E6E	0xC5D6	#HANGUL SYLLABLE IEUNG E NIEUNHIEUH
+0x9E6F	0xC5D7	#HANGUL SYLLABLE IEUNG E TIKEUT
+0x9E70	0xC5D9	#HANGUL SYLLABLE IEUNG E RIEULKIYEOK
+0x9E71	0xC5DA	#HANGUL SYLLABLE IEUNG E RIEULMIEUM
+0x9E72	0xC5DB	#HANGUL SYLLABLE IEUNG E RIEULPIEUP
+0x9E73	0xC5DC	#HANGUL SYLLABLE IEUNG E RIEULSIOS
+0x9E74	0xC5DD	#HANGUL SYLLABLE IEUNG E RIEULTHIEUTH
+0x9E75	0xC5DE	#HANGUL SYLLABLE IEUNG E RIEULPHIEUPH
+0x9E76	0xC5DF	#HANGUL SYLLABLE IEUNG E RIEULHIEUH
+0x9E77	0xC5E2	#HANGUL SYLLABLE IEUNG E PIEUPSIOS
+0x9E78	0xC5E4	#HANGUL SYLLABLE IEUNG E SSANGSIOS
+0x9E79	0xC5E6	#HANGUL SYLLABLE IEUNG E CIEUC
+0x9E7A	0xC5E7	#HANGUL SYLLABLE IEUNG E CHIEUCH
+0x9E81	0xC5E8	#HANGUL SYLLABLE IEUNG E KHIEUKH
+0x9E82	0xC5E9	#HANGUL SYLLABLE IEUNG E THIEUTH
+0x9E83	0xC5EA	#HANGUL SYLLABLE IEUNG E PHIEUPH
+0x9E84	0xC5EB	#HANGUL SYLLABLE IEUNG E HIEUH
+0x9E85	0xC5EF	#HANGUL SYLLABLE IEUNG YEO KIYEOKSIOS
+0x9E86	0xC5F1	#HANGUL SYLLABLE IEUNG YEO NIEUNCIEUC
+0x9E87	0xC5F2	#HANGUL SYLLABLE IEUNG YEO NIEUNHIEUH
+0x9E88	0xC5F3	#HANGUL SYLLABLE IEUNG YEO TIKEUT
+0x9E89	0xC5F5	#HANGUL SYLLABLE IEUNG YEO RIEULKIYEOK
+0x9E8A	0xC5F8	#HANGUL SYLLABLE IEUNG YEO RIEULSIOS
+0x9E8B	0xC5F9	#HANGUL SYLLABLE IEUNG YEO RIEULTHIEUTH
+0x9E8C	0xC5FA	#HANGUL SYLLABLE IEUNG YEO RIEULPHIEUPH
+0x9E8D	0xC5FB	#HANGUL SYLLABLE IEUNG YEO RIEULHIEUH
+0x9E8E	0xC602	#HANGUL SYLLABLE IEUNG YEO CIEUC
+0x9E8F	0xC603	#HANGUL SYLLABLE IEUNG YEO CHIEUCH
+0x9E90	0xC604	#HANGUL SYLLABLE IEUNG YEO KHIEUKH
+0x9E91	0xC609	#HANGUL SYLLABLE IEUNG YE KIYEOK
+0x9E92	0xC60A	#HANGUL SYLLABLE IEUNG YE SSANGKIYEOK
+0x9E93	0xC60B	#HANGUL SYLLABLE IEUNG YE KIYEOKSIOS
+0x9E94	0xC60D	#HANGUL SYLLABLE IEUNG YE NIEUNCIEUC
+0x9E95	0xC60E	#HANGUL SYLLABLE IEUNG YE NIEUNHIEUH
+0x9E96	0xC60F	#HANGUL SYLLABLE IEUNG YE TIKEUT
+0x9E97	0xC611	#HANGUL SYLLABLE IEUNG YE RIEULKIYEOK
+0x9E98	0xC612	#HANGUL SYLLABLE IEUNG YE RIEULMIEUM
+0x9E99	0xC613	#HANGUL SYLLABLE IEUNG YE RIEULPIEUP
+0x9E9A	0xC614	#HANGUL SYLLABLE IEUNG YE RIEULSIOS
+0x9E9B	0xC615	#HANGUL SYLLABLE IEUNG YE RIEULTHIEUTH
+0x9E9C	0xC616	#HANGUL SYLLABLE IEUNG YE RIEULPHIEUPH
+0x9E9D	0xC617	#HANGUL SYLLABLE IEUNG YE RIEULHIEUH
+0x9E9E	0xC61A	#HANGUL SYLLABLE IEUNG YE PIEUPSIOS
+0x9E9F	0xC61D	#HANGUL SYLLABLE IEUNG YE IEUNG
+0x9EA0	0xC61E	#HANGUL SYLLABLE IEUNG YE CIEUC
+0x9EA1	0xC61F	#HANGUL SYLLABLE IEUNG YE CHIEUCH
+0x9EA2	0xC620	#HANGUL SYLLABLE IEUNG YE KHIEUKH
+0x9EA3	0xC621	#HANGUL SYLLABLE IEUNG YE THIEUTH
+0x9EA4	0xC622	#HANGUL SYLLABLE IEUNG YE PHIEUPH
+0x9EA5	0xC623	#HANGUL SYLLABLE IEUNG YE HIEUH
+0x9EA6	0xC626	#HANGUL SYLLABLE IEUNG O SSANGKIYEOK
+0x9EA7	0xC627	#HANGUL SYLLABLE IEUNG O KIYEOKSIOS
+0x9EA8	0xC629	#HANGUL SYLLABLE IEUNG O NIEUNCIEUC
+0x9EA9	0xC62A	#HANGUL SYLLABLE IEUNG O NIEUNHIEUH
+0x9EAA	0xC62B	#HANGUL SYLLABLE IEUNG O TIKEUT
+0x9EAB	0xC62F	#HANGUL SYLLABLE IEUNG O RIEULPIEUP
+0x9EAC	0xC631	#HANGUL SYLLABLE IEUNG O RIEULTHIEUTH
+0x9EAD	0xC632	#HANGUL SYLLABLE IEUNG O RIEULPHIEUPH
+0x9EAE	0xC636	#HANGUL SYLLABLE IEUNG O PIEUPSIOS
+0x9EAF	0xC638	#HANGUL SYLLABLE IEUNG O SSANGSIOS
+0x9EB0	0xC63A	#HANGUL SYLLABLE IEUNG O CIEUC
+0x9EB1	0xC63C	#HANGUL SYLLABLE IEUNG O KHIEUKH
+0x9EB2	0xC63D	#HANGUL SYLLABLE IEUNG O THIEUTH
+0x9EB3	0xC63E	#HANGUL SYLLABLE IEUNG O PHIEUPH
+0x9EB4	0xC63F	#HANGUL SYLLABLE IEUNG O HIEUH
+0x9EB5	0xC642	#HANGUL SYLLABLE IEUNG WA SSANGKIYEOK
+0x9EB6	0xC643	#HANGUL SYLLABLE IEUNG WA KIYEOKSIOS
+0x9EB7	0xC645	#HANGUL SYLLABLE IEUNG WA NIEUNCIEUC
+0x9EB8	0xC646	#HANGUL SYLLABLE IEUNG WA NIEUNHIEUH
+0x9EB9	0xC647	#HANGUL SYLLABLE IEUNG WA TIKEUT
+0x9EBA	0xC649	#HANGUL SYLLABLE IEUNG WA RIEULKIYEOK
+0x9EBB	0xC64A	#HANGUL SYLLABLE IEUNG WA RIEULMIEUM
+0x9EBC	0xC64B	#HANGUL SYLLABLE IEUNG WA RIEULPIEUP
+0x9EBD	0xC64C	#HANGUL SYLLABLE IEUNG WA RIEULSIOS
+0x9EBE	0xC64D	#HANGUL SYLLABLE IEUNG WA RIEULTHIEUTH
+0x9EBF	0xC64E	#HANGUL SYLLABLE IEUNG WA RIEULPHIEUPH
+0x9EC0	0xC64F	#HANGUL SYLLABLE IEUNG WA RIEULHIEUH
+0x9EC1	0xC652	#HANGUL SYLLABLE IEUNG WA PIEUPSIOS
+0x9EC2	0xC656	#HANGUL SYLLABLE IEUNG WA CIEUC
+0x9EC3	0xC657	#HANGUL SYLLABLE IEUNG WA CHIEUCH
+0x9EC4	0xC658	#HANGUL SYLLABLE IEUNG WA KHIEUKH
+0x9EC5	0xC659	#HANGUL SYLLABLE IEUNG WA THIEUTH
+0x9EC6	0xC65A	#HANGUL SYLLABLE IEUNG WA PHIEUPH
+0x9EC7	0xC65B	#HANGUL SYLLABLE IEUNG WA HIEUH
+0x9EC8	0xC65E	#HANGUL SYLLABLE IEUNG WAE SSANGKIYEOK
+0x9EC9	0xC65F	#HANGUL SYLLABLE IEUNG WAE KIYEOKSIOS
+0x9ECA	0xC661	#HANGUL SYLLABLE IEUNG WAE NIEUNCIEUC
+0x9ECB	0xC662	#HANGUL SYLLABLE IEUNG WAE NIEUNHIEUH
+0x9ECC	0xC663	#HANGUL SYLLABLE IEUNG WAE TIKEUT
+0x9ECD	0xC664	#HANGUL SYLLABLE IEUNG WAE RIEUL
+0x9ECE	0xC665	#HANGUL SYLLABLE IEUNG WAE RIEULKIYEOK
+0x9ECF	0xC666	#HANGUL SYLLABLE IEUNG WAE RIEULMIEUM
+0x9ED0	0xC667	#HANGUL SYLLABLE IEUNG WAE RIEULPIEUP
+0x9ED1	0xC668	#HANGUL SYLLABLE IEUNG WAE RIEULSIOS
+0x9ED2	0xC669	#HANGUL SYLLABLE IEUNG WAE RIEULTHIEUTH
+0x9ED3	0xC66A	#HANGUL SYLLABLE IEUNG WAE RIEULPHIEUPH
+0x9ED4	0xC66B	#HANGUL SYLLABLE IEUNG WAE RIEULHIEUH
+0x9ED5	0xC66D	#HANGUL SYLLABLE IEUNG WAE PIEUP
+0x9ED6	0xC66E	#HANGUL SYLLABLE IEUNG WAE PIEUPSIOS
+0x9ED7	0xC670	#HANGUL SYLLABLE IEUNG WAE SSANGSIOS
+0x9ED8	0xC672	#HANGUL SYLLABLE IEUNG WAE CIEUC
+0x9ED9	0xC673	#HANGUL SYLLABLE IEUNG WAE CHIEUCH
+0x9EDA	0xC674	#HANGUL SYLLABLE IEUNG WAE KHIEUKH
+0x9EDB	0xC675	#HANGUL SYLLABLE IEUNG WAE THIEUTH
+0x9EDC	0xC676	#HANGUL SYLLABLE IEUNG WAE PHIEUPH
+0x9EDD	0xC677	#HANGUL SYLLABLE IEUNG WAE HIEUH
+0x9EDE	0xC67A	#HANGUL SYLLABLE IEUNG OE SSANGKIYEOK
+0x9EDF	0xC67B	#HANGUL SYLLABLE IEUNG OE KIYEOKSIOS
+0x9EE0	0xC67D	#HANGUL SYLLABLE IEUNG OE NIEUNCIEUC
+0x9EE1	0xC67E	#HANGUL SYLLABLE IEUNG OE NIEUNHIEUH
+0x9EE2	0xC67F	#HANGUL SYLLABLE IEUNG OE TIKEUT
+0x9EE3	0xC681	#HANGUL SYLLABLE IEUNG OE RIEULKIYEOK
+0x9EE4	0xC682	#HANGUL SYLLABLE IEUNG OE RIEULMIEUM
+0x9EE5	0xC683	#HANGUL SYLLABLE IEUNG OE RIEULPIEUP
+0x9EE6	0xC684	#HANGUL SYLLABLE IEUNG OE RIEULSIOS
+0x9EE7	0xC685	#HANGUL SYLLABLE IEUNG OE RIEULTHIEUTH
+0x9EE8	0xC686	#HANGUL SYLLABLE IEUNG OE RIEULPHIEUPH
+0x9EE9	0xC687	#HANGUL SYLLABLE IEUNG OE RIEULHIEUH
+0x9EEA	0xC68A	#HANGUL SYLLABLE IEUNG OE PIEUPSIOS
+0x9EEB	0xC68C	#HANGUL SYLLABLE IEUNG OE SSANGSIOS
+0x9EEC	0xC68E	#HANGUL SYLLABLE IEUNG OE CIEUC
+0x9EED	0xC68F	#HANGUL SYLLABLE IEUNG OE CHIEUCH
+0x9EEE	0xC690	#HANGUL SYLLABLE IEUNG OE KHIEUKH
+0x9EEF	0xC691	#HANGUL SYLLABLE IEUNG OE THIEUTH
+0x9EF0	0xC692	#HANGUL SYLLABLE IEUNG OE PHIEUPH
+0x9EF1	0xC693	#HANGUL SYLLABLE IEUNG OE HIEUH
+0x9EF2	0xC696	#HANGUL SYLLABLE IEUNG YO SSANGKIYEOK
+0x9EF3	0xC697	#HANGUL SYLLABLE IEUNG YO KIYEOKSIOS
+0x9EF4	0xC699	#HANGUL SYLLABLE IEUNG YO NIEUNCIEUC
+0x9EF5	0xC69A	#HANGUL SYLLABLE IEUNG YO NIEUNHIEUH
+0x9EF6	0xC69B	#HANGUL SYLLABLE IEUNG YO TIKEUT
+0x9EF7	0xC69D	#HANGUL SYLLABLE IEUNG YO RIEULKIYEOK
+0x9EF8	0xC69E	#HANGUL SYLLABLE IEUNG YO RIEULMIEUM
+0x9EF9	0xC69F	#HANGUL SYLLABLE IEUNG YO RIEULPIEUP
+0x9EFA	0xC6A0	#HANGUL SYLLABLE IEUNG YO RIEULSIOS
+0x9EFB	0xC6A1	#HANGUL SYLLABLE IEUNG YO RIEULTHIEUTH
+0x9EFC	0xC6A2	#HANGUL SYLLABLE IEUNG YO RIEULPHIEUPH
+0x9EFD	0xC6A3	#HANGUL SYLLABLE IEUNG YO RIEULHIEUH
+0x9EFE	0xC6A6	#HANGUL SYLLABLE IEUNG YO PIEUPSIOS
+0x9F41	0xC6A8	#HANGUL SYLLABLE IEUNG YO SSANGSIOS
+0x9F42	0xC6AA	#HANGUL SYLLABLE IEUNG YO CIEUC
+0x9F43	0xC6AB	#HANGUL SYLLABLE IEUNG YO CHIEUCH
+0x9F44	0xC6AC	#HANGUL SYLLABLE IEUNG YO KHIEUKH
+0x9F45	0xC6AD	#HANGUL SYLLABLE IEUNG YO THIEUTH
+0x9F46	0xC6AE	#HANGUL SYLLABLE IEUNG YO PHIEUPH
+0x9F47	0xC6AF	#HANGUL SYLLABLE IEUNG YO HIEUH
+0x9F48	0xC6B2	#HANGUL SYLLABLE IEUNG U SSANGKIYEOK
+0x9F49	0xC6B3	#HANGUL SYLLABLE IEUNG U KIYEOKSIOS
+0x9F4A	0xC6B5	#HANGUL SYLLABLE IEUNG U NIEUNCIEUC
+0x9F4B	0xC6B6	#HANGUL SYLLABLE IEUNG U NIEUNHIEUH
+0x9F4C	0xC6B7	#HANGUL SYLLABLE IEUNG U TIKEUT
+0x9F4D	0xC6BB	#HANGUL SYLLABLE IEUNG U RIEULPIEUP
+0x9F4E	0xC6BC	#HANGUL SYLLABLE IEUNG U RIEULSIOS
+0x9F4F	0xC6BD	#HANGUL SYLLABLE IEUNG U RIEULTHIEUTH
+0x9F50	0xC6BE	#HANGUL SYLLABLE IEUNG U RIEULPHIEUPH
+0x9F51	0xC6BF	#HANGUL SYLLABLE IEUNG U RIEULHIEUH
+0x9F52	0xC6C2	#HANGUL SYLLABLE IEUNG U PIEUPSIOS
+0x9F53	0xC6C4	#HANGUL SYLLABLE IEUNG U SSANGSIOS
+0x9F54	0xC6C6	#HANGUL SYLLABLE IEUNG U CIEUC
+0x9F55	0xC6C7	#HANGUL SYLLABLE IEUNG U CHIEUCH
+0x9F56	0xC6C8	#HANGUL SYLLABLE IEUNG U KHIEUKH
+0x9F57	0xC6C9	#HANGUL SYLLABLE IEUNG U THIEUTH
+0x9F58	0xC6CA	#HANGUL SYLLABLE IEUNG U PHIEUPH
+0x9F59	0xC6CB	#HANGUL SYLLABLE IEUNG U HIEUH
+0x9F5A	0xC6CE	#HANGUL SYLLABLE IEUNG WEO SSANGKIYEOK
+0x9F61	0xC6CF	#HANGUL SYLLABLE IEUNG WEO KIYEOKSIOS
+0x9F62	0xC6D1	#HANGUL SYLLABLE IEUNG WEO NIEUNCIEUC
+0x9F63	0xC6D2	#HANGUL SYLLABLE IEUNG WEO NIEUNHIEUH
+0x9F64	0xC6D3	#HANGUL SYLLABLE IEUNG WEO TIKEUT
+0x9F65	0xC6D5	#HANGUL SYLLABLE IEUNG WEO RIEULKIYEOK
+0x9F66	0xC6D6	#HANGUL SYLLABLE IEUNG WEO RIEULMIEUM
+0x9F67	0xC6D7	#HANGUL SYLLABLE IEUNG WEO RIEULPIEUP
+0x9F68	0xC6D8	#HANGUL SYLLABLE IEUNG WEO RIEULSIOS
+0x9F69	0xC6D9	#HANGUL SYLLABLE IEUNG WEO RIEULTHIEUTH
+0x9F6A	0xC6DA	#HANGUL SYLLABLE IEUNG WEO RIEULPHIEUPH
+0x9F6B	0xC6DB	#HANGUL SYLLABLE IEUNG WEO RIEULHIEUH
+0x9F6C	0xC6DE	#HANGUL SYLLABLE IEUNG WEO PIEUPSIOS
+0x9F6D	0xC6DF	#HANGUL SYLLABLE IEUNG WEO SIOS
+0x9F6E	0xC6E2	#HANGUL SYLLABLE IEUNG WEO CIEUC
+0x9F6F	0xC6E3	#HANGUL SYLLABLE IEUNG WEO CHIEUCH
+0x9F70	0xC6E4	#HANGUL SYLLABLE IEUNG WEO KHIEUKH
+0x9F71	0xC6E5	#HANGUL SYLLABLE IEUNG WEO THIEUTH
+0x9F72	0xC6E6	#HANGUL SYLLABLE IEUNG WEO PHIEUPH
+0x9F73	0xC6E7	#HANGUL SYLLABLE IEUNG WEO HIEUH
+0x9F74	0xC6EA	#HANGUL SYLLABLE IEUNG WE SSANGKIYEOK
+0x9F75	0xC6EB	#HANGUL SYLLABLE IEUNG WE KIYEOKSIOS
+0x9F76	0xC6ED	#HANGUL SYLLABLE IEUNG WE NIEUNCIEUC
+0x9F77	0xC6EE	#HANGUL SYLLABLE IEUNG WE NIEUNHIEUH
+0x9F78	0xC6EF	#HANGUL SYLLABLE IEUNG WE TIKEUT
+0x9F79	0xC6F1	#HANGUL SYLLABLE IEUNG WE RIEULKIYEOK
+0x9F7A	0xC6F2	#HANGUL SYLLABLE IEUNG WE RIEULMIEUM
+0x9F81	0xC6F3	#HANGUL SYLLABLE IEUNG WE RIEULPIEUP
+0x9F82	0xC6F4	#HANGUL SYLLABLE IEUNG WE RIEULSIOS
+0x9F83	0xC6F5	#HANGUL SYLLABLE IEUNG WE RIEULTHIEUTH
+0x9F84	0xC6F6	#HANGUL SYLLABLE IEUNG WE RIEULPHIEUPH
+0x9F85	0xC6F7	#HANGUL SYLLABLE IEUNG WE RIEULHIEUH
+0x9F86	0xC6FA	#HANGUL SYLLABLE IEUNG WE PIEUPSIOS
+0x9F87	0xC6FB	#HANGUL SYLLABLE IEUNG WE SIOS
+0x9F88	0xC6FC	#HANGUL SYLLABLE IEUNG WE SSANGSIOS
+0x9F89	0xC6FE	#HANGUL SYLLABLE IEUNG WE CIEUC
+0x9F8A	0xC6FF	#HANGUL SYLLABLE IEUNG WE CHIEUCH
+0x9F8B	0xC700	#HANGUL SYLLABLE IEUNG WE KHIEUKH
+0x9F8C	0xC701	#HANGUL SYLLABLE IEUNG WE THIEUTH
+0x9F8D	0xC702	#HANGUL SYLLABLE IEUNG WE PHIEUPH
+0x9F8E	0xC703	#HANGUL SYLLABLE IEUNG WE HIEUH
+0x9F8F	0xC706	#HANGUL SYLLABLE IEUNG WI SSANGKIYEOK
+0x9F90	0xC707	#HANGUL SYLLABLE IEUNG WI KIYEOKSIOS
+0x9F91	0xC709	#HANGUL SYLLABLE IEUNG WI NIEUNCIEUC
+0x9F92	0xC70A	#HANGUL SYLLABLE IEUNG WI NIEUNHIEUH
+0x9F93	0xC70B	#HANGUL SYLLABLE IEUNG WI TIKEUT
+0x9F94	0xC70D	#HANGUL SYLLABLE IEUNG WI RIEULKIYEOK
+0x9F95	0xC70E	#HANGUL SYLLABLE IEUNG WI RIEULMIEUM
+0x9F96	0xC70F	#HANGUL SYLLABLE IEUNG WI RIEULPIEUP
+0x9F97	0xC710	#HANGUL SYLLABLE IEUNG WI RIEULSIOS
+0x9F98	0xC711	#HANGUL SYLLABLE IEUNG WI RIEULTHIEUTH
+0x9F99	0xC712	#HANGUL SYLLABLE IEUNG WI RIEULPHIEUPH
+0x9F9A	0xC713	#HANGUL SYLLABLE IEUNG WI RIEULHIEUH
+0x9F9B	0xC716	#HANGUL SYLLABLE IEUNG WI PIEUPSIOS
+0x9F9C	0xC718	#HANGUL SYLLABLE IEUNG WI SSANGSIOS
+0x9F9D	0xC71A	#HANGUL SYLLABLE IEUNG WI CIEUC
+0x9F9E	0xC71B	#HANGUL SYLLABLE IEUNG WI CHIEUCH
+0x9F9F	0xC71C	#HANGUL SYLLABLE IEUNG WI KHIEUKH
+0x9FA0	0xC71D	#HANGUL SYLLABLE IEUNG WI THIEUTH
+0x9FA1	0xC71E	#HANGUL SYLLABLE IEUNG WI PHIEUPH
+0x9FA2	0xC71F	#HANGUL SYLLABLE IEUNG WI HIEUH
+0x9FA3	0xC722	#HANGUL SYLLABLE IEUNG YU SSANGKIYEOK
+0x9FA4	0xC723	#HANGUL SYLLABLE IEUNG YU KIYEOKSIOS
+0x9FA5	0xC725	#HANGUL SYLLABLE IEUNG YU NIEUNCIEUC
+0x9FA6	0xC726	#HANGUL SYLLABLE IEUNG YU NIEUNHIEUH
+0x9FA7	0xC727	#HANGUL SYLLABLE IEUNG YU TIKEUT
+0x9FA8	0xC729	#HANGUL SYLLABLE IEUNG YU RIEULKIYEOK
+0x9FA9	0xC72A	#HANGUL SYLLABLE IEUNG YU RIEULMIEUM
+0x9FAA	0xC72B	#HANGUL SYLLABLE IEUNG YU RIEULPIEUP
+0x9FAB	0xC72C	#HANGUL SYLLABLE IEUNG YU RIEULSIOS
+0x9FAC	0xC72D	#HANGUL SYLLABLE IEUNG YU RIEULTHIEUTH
+0x9FAD	0xC72E	#HANGUL SYLLABLE IEUNG YU RIEULPHIEUPH
+0x9FAE	0xC72F	#HANGUL SYLLABLE IEUNG YU RIEULHIEUH
+0x9FAF	0xC732	#HANGUL SYLLABLE IEUNG YU PIEUPSIOS
+0x9FB0	0xC734	#HANGUL SYLLABLE IEUNG YU SSANGSIOS
+0x9FB1	0xC736	#HANGUL SYLLABLE IEUNG YU CIEUC
+0x9FB2	0xC738	#HANGUL SYLLABLE IEUNG YU KHIEUKH
+0x9FB3	0xC739	#HANGUL SYLLABLE IEUNG YU THIEUTH
+0x9FB4	0xC73A	#HANGUL SYLLABLE IEUNG YU PHIEUPH
+0x9FB5	0xC73B	#HANGUL SYLLABLE IEUNG YU HIEUH
+0x9FB6	0xC73E	#HANGUL SYLLABLE IEUNG EU SSANGKIYEOK
+0x9FB7	0xC73F	#HANGUL SYLLABLE IEUNG EU KIYEOKSIOS
+0x9FB8	0xC741	#HANGUL SYLLABLE IEUNG EU NIEUNCIEUC
+0x9FB9	0xC742	#HANGUL SYLLABLE IEUNG EU NIEUNHIEUH
+0x9FBA	0xC743	#HANGUL SYLLABLE IEUNG EU TIKEUT
+0x9FBB	0xC745	#HANGUL SYLLABLE IEUNG EU RIEULKIYEOK
+0x9FBC	0xC746	#HANGUL SYLLABLE IEUNG EU RIEULMIEUM
+0x9FBD	0xC747	#HANGUL SYLLABLE IEUNG EU RIEULPIEUP
+0x9FBE	0xC748	#HANGUL SYLLABLE IEUNG EU RIEULSIOS
+0x9FBF	0xC749	#HANGUL SYLLABLE IEUNG EU RIEULTHIEUTH
+0x9FC0	0xC74B	#HANGUL SYLLABLE IEUNG EU RIEULHIEUH
+0x9FC1	0xC74E	#HANGUL SYLLABLE IEUNG EU PIEUPSIOS
+0x9FC2	0xC750	#HANGUL SYLLABLE IEUNG EU SSANGSIOS
+0x9FC3	0xC759	#HANGUL SYLLABLE IEUNG YI KIYEOK
+0x9FC4	0xC75A	#HANGUL SYLLABLE IEUNG YI SSANGKIYEOK
+0x9FC5	0xC75B	#HANGUL SYLLABLE IEUNG YI KIYEOKSIOS
+0x9FC6	0xC75D	#HANGUL SYLLABLE IEUNG YI NIEUNCIEUC
+0x9FC7	0xC75E	#HANGUL SYLLABLE IEUNG YI NIEUNHIEUH
+0x9FC8	0xC75F	#HANGUL SYLLABLE IEUNG YI TIKEUT
+0x9FC9	0xC761	#HANGUL SYLLABLE IEUNG YI RIEULKIYEOK
+0x9FCA	0xC762	#HANGUL SYLLABLE IEUNG YI RIEULMIEUM
+0x9FCB	0xC763	#HANGUL SYLLABLE IEUNG YI RIEULPIEUP
+0x9FCC	0xC764	#HANGUL SYLLABLE IEUNG YI RIEULSIOS
+0x9FCD	0xC765	#HANGUL SYLLABLE IEUNG YI RIEULTHIEUTH
+0x9FCE	0xC766	#HANGUL SYLLABLE IEUNG YI RIEULPHIEUPH
+0x9FCF	0xC767	#HANGUL SYLLABLE IEUNG YI RIEULHIEUH
+0x9FD0	0xC769	#HANGUL SYLLABLE IEUNG YI PIEUP
+0x9FD1	0xC76A	#HANGUL SYLLABLE IEUNG YI PIEUPSIOS
+0x9FD2	0xC76C	#HANGUL SYLLABLE IEUNG YI SSANGSIOS
+0x9FD3	0xC76D	#HANGUL SYLLABLE IEUNG YI IEUNG
+0x9FD4	0xC76E	#HANGUL SYLLABLE IEUNG YI CIEUC
+0x9FD5	0xC76F	#HANGUL SYLLABLE IEUNG YI CHIEUCH
+0x9FD6	0xC770	#HANGUL SYLLABLE IEUNG YI KHIEUKH
+0x9FD7	0xC771	#HANGUL SYLLABLE IEUNG YI THIEUTH
+0x9FD8	0xC772	#HANGUL SYLLABLE IEUNG YI PHIEUPH
+0x9FD9	0xC773	#HANGUL SYLLABLE IEUNG YI HIEUH
+0x9FDA	0xC776	#HANGUL SYLLABLE IEUNG I SSANGKIYEOK
+0x9FDB	0xC777	#HANGUL SYLLABLE IEUNG I KIYEOKSIOS
+0x9FDC	0xC779	#HANGUL SYLLABLE IEUNG I NIEUNCIEUC
+0x9FDD	0xC77A	#HANGUL SYLLABLE IEUNG I NIEUNHIEUH
+0x9FDE	0xC77B	#HANGUL SYLLABLE IEUNG I TIKEUT
+0x9FDF	0xC77F	#HANGUL SYLLABLE IEUNG I RIEULPIEUP
+0x9FE0	0xC780	#HANGUL SYLLABLE IEUNG I RIEULSIOS
+0x9FE1	0xC781	#HANGUL SYLLABLE IEUNG I RIEULTHIEUTH
+0x9FE2	0xC782	#HANGUL SYLLABLE IEUNG I RIEULPHIEUPH
+0x9FE3	0xC786	#HANGUL SYLLABLE IEUNG I PIEUPSIOS
+0x9FE4	0xC78B	#HANGUL SYLLABLE IEUNG I CHIEUCH
+0x9FE5	0xC78C	#HANGUL SYLLABLE IEUNG I KHIEUKH
+0x9FE6	0xC78D	#HANGUL SYLLABLE IEUNG I THIEUTH
+0x9FE7	0xC78F	#HANGUL SYLLABLE IEUNG I HIEUH
+0x9FE8	0xC792	#HANGUL SYLLABLE CIEUC A SSANGKIYEOK
+0x9FE9	0xC793	#HANGUL SYLLABLE CIEUC A KIYEOKSIOS
+0x9FEA	0xC795	#HANGUL SYLLABLE CIEUC A NIEUNCIEUC
+0x9FEB	0xC799	#HANGUL SYLLABLE CIEUC A RIEULKIYEOK
+0x9FEC	0xC79B	#HANGUL SYLLABLE CIEUC A RIEULPIEUP
+0x9FED	0xC79C	#HANGUL SYLLABLE CIEUC A RIEULSIOS
+0x9FEE	0xC79D	#HANGUL SYLLABLE CIEUC A RIEULTHIEUTH
+0x9FEF	0xC79E	#HANGUL SYLLABLE CIEUC A RIEULPHIEUPH
+0x9FF0	0xC79F	#HANGUL SYLLABLE CIEUC A RIEULHIEUH
+0x9FF1	0xC7A2	#HANGUL SYLLABLE CIEUC A PIEUPSIOS
+0x9FF2	0xC7A7	#HANGUL SYLLABLE CIEUC A CHIEUCH
+0x9FF3	0xC7A8	#HANGUL SYLLABLE CIEUC A KHIEUKH
+0x9FF4	0xC7A9	#HANGUL SYLLABLE CIEUC A THIEUTH
+0x9FF5	0xC7AA	#HANGUL SYLLABLE CIEUC A PHIEUPH
+0x9FF6	0xC7AB	#HANGUL SYLLABLE CIEUC A HIEUH
+0x9FF7	0xC7AE	#HANGUL SYLLABLE CIEUC AE SSANGKIYEOK
+0x9FF8	0xC7AF	#HANGUL SYLLABLE CIEUC AE KIYEOKSIOS
+0x9FF9	0xC7B1	#HANGUL SYLLABLE CIEUC AE NIEUNCIEUC
+0x9FFA	0xC7B2	#HANGUL SYLLABLE CIEUC AE NIEUNHIEUH
+0x9FFB	0xC7B3	#HANGUL SYLLABLE CIEUC AE TIKEUT
+0x9FFC	0xC7B5	#HANGUL SYLLABLE CIEUC AE RIEULKIYEOK
+0x9FFD	0xC7B6	#HANGUL SYLLABLE CIEUC AE RIEULMIEUM
+0x9FFE	0xC7B7	#HANGUL SYLLABLE CIEUC AE RIEULPIEUP
+0xA041	0xC7B8	#HANGUL SYLLABLE CIEUC AE RIEULSIOS
+0xA042	0xC7B9	#HANGUL SYLLABLE CIEUC AE RIEULTHIEUTH
+0xA043	0xC7BA	#HANGUL SYLLABLE CIEUC AE RIEULPHIEUPH
+0xA044	0xC7BB	#HANGUL SYLLABLE CIEUC AE RIEULHIEUH
+0xA045	0xC7BE	#HANGUL SYLLABLE CIEUC AE PIEUPSIOS
+0xA046	0xC7C2	#HANGUL SYLLABLE CIEUC AE CIEUC
+0xA047	0xC7C3	#HANGUL SYLLABLE CIEUC AE CHIEUCH
+0xA048	0xC7C4	#HANGUL SYLLABLE CIEUC AE KHIEUKH
+0xA049	0xC7C5	#HANGUL SYLLABLE CIEUC AE THIEUTH
+0xA04A	0xC7C6	#HANGUL SYLLABLE CIEUC AE PHIEUPH
+0xA04B	0xC7C7	#HANGUL SYLLABLE CIEUC AE HIEUH
+0xA04C	0xC7CA	#HANGUL SYLLABLE CIEUC YA SSANGKIYEOK
+0xA04D	0xC7CB	#HANGUL SYLLABLE CIEUC YA KIYEOKSIOS
+0xA04E	0xC7CD	#HANGUL SYLLABLE CIEUC YA NIEUNCIEUC
+0xA04F	0xC7CF	#HANGUL SYLLABLE CIEUC YA TIKEUT
+0xA050	0xC7D1	#HANGUL SYLLABLE CIEUC YA RIEULKIYEOK
+0xA051	0xC7D2	#HANGUL SYLLABLE CIEUC YA RIEULMIEUM
+0xA052	0xC7D3	#HANGUL SYLLABLE CIEUC YA RIEULPIEUP
+0xA053	0xC7D4	#HANGUL SYLLABLE CIEUC YA RIEULSIOS
+0xA054	0xC7D5	#HANGUL SYLLABLE CIEUC YA RIEULTHIEUTH
+0xA055	0xC7D6	#HANGUL SYLLABLE CIEUC YA RIEULPHIEUPH
+0xA056	0xC7D7	#HANGUL SYLLABLE CIEUC YA RIEULHIEUH
+0xA057	0xC7D9	#HANGUL SYLLABLE CIEUC YA PIEUP
+0xA058	0xC7DA	#HANGUL SYLLABLE CIEUC YA PIEUPSIOS
+0xA059	0xC7DB	#HANGUL SYLLABLE CIEUC YA SIOS
+0xA05A	0xC7DC	#HANGUL SYLLABLE CIEUC YA SSANGSIOS
+0xA061	0xC7DE	#HANGUL SYLLABLE CIEUC YA CIEUC
+0xA062	0xC7DF	#HANGUL SYLLABLE CIEUC YA CHIEUCH
+0xA063	0xC7E0	#HANGUL SYLLABLE CIEUC YA KHIEUKH
+0xA064	0xC7E1	#HANGUL SYLLABLE CIEUC YA THIEUTH
+0xA065	0xC7E2	#HANGUL SYLLABLE CIEUC YA PHIEUPH
+0xA066	0xC7E3	#HANGUL SYLLABLE CIEUC YA HIEUH
+0xA067	0xC7E5	#HANGUL SYLLABLE CIEUC YAE KIYEOK
+0xA068	0xC7E6	#HANGUL SYLLABLE CIEUC YAE SSANGKIYEOK
+0xA069	0xC7E7	#HANGUL SYLLABLE CIEUC YAE KIYEOKSIOS
+0xA06A	0xC7E9	#HANGUL SYLLABLE CIEUC YAE NIEUNCIEUC
+0xA06B	0xC7EA	#HANGUL SYLLABLE CIEUC YAE NIEUNHIEUH
+0xA06C	0xC7EB	#HANGUL SYLLABLE CIEUC YAE TIKEUT
+0xA06D	0xC7ED	#HANGUL SYLLABLE CIEUC YAE RIEULKIYEOK
+0xA06E	0xC7EE	#HANGUL SYLLABLE CIEUC YAE RIEULMIEUM
+0xA06F	0xC7EF	#HANGUL SYLLABLE CIEUC YAE RIEULPIEUP
+0xA070	0xC7F0	#HANGUL SYLLABLE CIEUC YAE RIEULSIOS
+0xA071	0xC7F1	#HANGUL SYLLABLE CIEUC YAE RIEULTHIEUTH
+0xA072	0xC7F2	#HANGUL SYLLABLE CIEUC YAE RIEULPHIEUPH
+0xA073	0xC7F3	#HANGUL SYLLABLE CIEUC YAE RIEULHIEUH
+0xA074	0xC7F4	#HANGUL SYLLABLE CIEUC YAE MIEUM
+0xA075	0xC7F5	#HANGUL SYLLABLE CIEUC YAE PIEUP
+0xA076	0xC7F6	#HANGUL SYLLABLE CIEUC YAE PIEUPSIOS
+0xA077	0xC7F7	#HANGUL SYLLABLE CIEUC YAE SIOS
+0xA078	0xC7F8	#HANGUL SYLLABLE CIEUC YAE SSANGSIOS
+0xA079	0xC7F9	#HANGUL SYLLABLE CIEUC YAE IEUNG
+0xA07A	0xC7FA	#HANGUL SYLLABLE CIEUC YAE CIEUC
+0xA081	0xC7FB	#HANGUL SYLLABLE CIEUC YAE CHIEUCH
+0xA082	0xC7FC	#HANGUL SYLLABLE CIEUC YAE KHIEUKH
+0xA083	0xC7FD	#HANGUL SYLLABLE CIEUC YAE THIEUTH
+0xA084	0xC7FE	#HANGUL SYLLABLE CIEUC YAE PHIEUPH
+0xA085	0xC7FF	#HANGUL SYLLABLE CIEUC YAE HIEUH
+0xA086	0xC802	#HANGUL SYLLABLE CIEUC EO SSANGKIYEOK
+0xA087	0xC803	#HANGUL SYLLABLE CIEUC EO KIYEOKSIOS
+0xA088	0xC805	#HANGUL SYLLABLE CIEUC EO NIEUNCIEUC
+0xA089	0xC806	#HANGUL SYLLABLE CIEUC EO NIEUNHIEUH
+0xA08A	0xC807	#HANGUL SYLLABLE CIEUC EO TIKEUT
+0xA08B	0xC809	#HANGUL SYLLABLE CIEUC EO RIEULKIYEOK
+0xA08C	0xC80B	#HANGUL SYLLABLE CIEUC EO RIEULPIEUP
+0xA08D	0xC80C	#HANGUL SYLLABLE CIEUC EO RIEULSIOS
+0xA08E	0xC80D	#HANGUL SYLLABLE CIEUC EO RIEULTHIEUTH
+0xA08F	0xC80E	#HANGUL SYLLABLE CIEUC EO RIEULPHIEUPH
+0xA090	0xC80F	#HANGUL SYLLABLE CIEUC EO RIEULHIEUH
+0xA091	0xC812	#HANGUL SYLLABLE CIEUC EO PIEUPSIOS
+0xA092	0xC814	#HANGUL SYLLABLE CIEUC EO SSANGSIOS
+0xA093	0xC817	#HANGUL SYLLABLE CIEUC EO CHIEUCH
+0xA094	0xC818	#HANGUL SYLLABLE CIEUC EO KHIEUKH
+0xA095	0xC819	#HANGUL SYLLABLE CIEUC EO THIEUTH
+0xA096	0xC81A	#HANGUL SYLLABLE CIEUC EO PHIEUPH
+0xA097	0xC81B	#HANGUL SYLLABLE CIEUC EO HIEUH
+0xA098	0xC81E	#HANGUL SYLLABLE CIEUC E SSANGKIYEOK
+0xA099	0xC81F	#HANGUL SYLLABLE CIEUC E KIYEOKSIOS
+0xA09A	0xC821	#HANGUL SYLLABLE CIEUC E NIEUNCIEUC
+0xA09B	0xC822	#HANGUL SYLLABLE CIEUC E NIEUNHIEUH
+0xA09C	0xC823	#HANGUL SYLLABLE CIEUC E TIKEUT
+0xA09D	0xC825	#HANGUL SYLLABLE CIEUC E RIEULKIYEOK
+0xA09E	0xC826	#HANGUL SYLLABLE CIEUC E RIEULMIEUM
+0xA09F	0xC827	#HANGUL SYLLABLE CIEUC E RIEULPIEUP
+0xA0A0	0xC828	#HANGUL SYLLABLE CIEUC E RIEULSIOS
+0xA0A1	0xC829	#HANGUL SYLLABLE CIEUC E RIEULTHIEUTH
+0xA0A2	0xC82A	#HANGUL SYLLABLE CIEUC E RIEULPHIEUPH
+0xA0A3	0xC82B	#HANGUL SYLLABLE CIEUC E RIEULHIEUH
+0xA0A4	0xC82E	#HANGUL SYLLABLE CIEUC E PIEUPSIOS
+0xA0A5	0xC830	#HANGUL SYLLABLE CIEUC E SSANGSIOS
+0xA0A6	0xC832	#HANGUL SYLLABLE CIEUC E CIEUC
+0xA0A7	0xC833	#HANGUL SYLLABLE CIEUC E CHIEUCH
+0xA0A8	0xC834	#HANGUL SYLLABLE CIEUC E KHIEUKH
+0xA0A9	0xC835	#HANGUL SYLLABLE CIEUC E THIEUTH
+0xA0AA	0xC836	#HANGUL SYLLABLE CIEUC E PHIEUPH
+0xA0AB	0xC837	#HANGUL SYLLABLE CIEUC E HIEUH
+0xA0AC	0xC839	#HANGUL SYLLABLE CIEUC YEO KIYEOK
+0xA0AD	0xC83A	#HANGUL SYLLABLE CIEUC YEO SSANGKIYEOK
+0xA0AE	0xC83B	#HANGUL SYLLABLE CIEUC YEO KIYEOKSIOS
+0xA0AF	0xC83D	#HANGUL SYLLABLE CIEUC YEO NIEUNCIEUC
+0xA0B0	0xC83E	#HANGUL SYLLABLE CIEUC YEO NIEUNHIEUH
+0xA0B1	0xC83F	#HANGUL SYLLABLE CIEUC YEO TIKEUT
+0xA0B2	0xC841	#HANGUL SYLLABLE CIEUC YEO RIEULKIYEOK
+0xA0B3	0xC842	#HANGUL SYLLABLE CIEUC YEO RIEULMIEUM
+0xA0B4	0xC843	#HANGUL SYLLABLE CIEUC YEO RIEULPIEUP
+0xA0B5	0xC844	#HANGUL SYLLABLE CIEUC YEO RIEULSIOS
+0xA0B6	0xC845	#HANGUL SYLLABLE CIEUC YEO RIEULTHIEUTH
+0xA0B7	0xC846	#HANGUL SYLLABLE CIEUC YEO RIEULPHIEUPH
+0xA0B8	0xC847	#HANGUL SYLLABLE CIEUC YEO RIEULHIEUH
+0xA0B9	0xC84A	#HANGUL SYLLABLE CIEUC YEO PIEUPSIOS
+0xA0BA	0xC84B	#HANGUL SYLLABLE CIEUC YEO SIOS
+0xA0BB	0xC84E	#HANGUL SYLLABLE CIEUC YEO CIEUC
+0xA0BC	0xC84F	#HANGUL SYLLABLE CIEUC YEO CHIEUCH
+0xA0BD	0xC850	#HANGUL SYLLABLE CIEUC YEO KHIEUKH
+0xA0BE	0xC851	#HANGUL SYLLABLE CIEUC YEO THIEUTH
+0xA0BF	0xC852	#HANGUL SYLLABLE CIEUC YEO PHIEUPH
+0xA0C0	0xC853	#HANGUL SYLLABLE CIEUC YEO HIEUH
+0xA0C1	0xC855	#HANGUL SYLLABLE CIEUC YE KIYEOK
+0xA0C2	0xC856	#HANGUL SYLLABLE CIEUC YE SSANGKIYEOK
+0xA0C3	0xC857	#HANGUL SYLLABLE CIEUC YE KIYEOKSIOS
+0xA0C4	0xC858	#HANGUL SYLLABLE CIEUC YE NIEUN
+0xA0C5	0xC859	#HANGUL SYLLABLE CIEUC YE NIEUNCIEUC
+0xA0C6	0xC85A	#HANGUL SYLLABLE CIEUC YE NIEUNHIEUH
+0xA0C7	0xC85B	#HANGUL SYLLABLE CIEUC YE TIKEUT
+0xA0C8	0xC85C	#HANGUL SYLLABLE CIEUC YE RIEUL
+0xA0C9	0xC85D	#HANGUL SYLLABLE CIEUC YE RIEULKIYEOK
+0xA0CA	0xC85E	#HANGUL SYLLABLE CIEUC YE RIEULMIEUM
+0xA0CB	0xC85F	#HANGUL SYLLABLE CIEUC YE RIEULPIEUP
+0xA0CC	0xC860	#HANGUL SYLLABLE CIEUC YE RIEULSIOS
+0xA0CD	0xC861	#HANGUL SYLLABLE CIEUC YE RIEULTHIEUTH
+0xA0CE	0xC862	#HANGUL SYLLABLE CIEUC YE RIEULPHIEUPH
+0xA0CF	0xC863	#HANGUL SYLLABLE CIEUC YE RIEULHIEUH
+0xA0D0	0xC864	#HANGUL SYLLABLE CIEUC YE MIEUM
+0xA0D1	0xC865	#HANGUL SYLLABLE CIEUC YE PIEUP
+0xA0D2	0xC866	#HANGUL SYLLABLE CIEUC YE PIEUPSIOS
+0xA0D3	0xC867	#HANGUL SYLLABLE CIEUC YE SIOS
+0xA0D4	0xC868	#HANGUL SYLLABLE CIEUC YE SSANGSIOS
+0xA0D5	0xC869	#HANGUL SYLLABLE CIEUC YE IEUNG
+0xA0D6	0xC86A	#HANGUL SYLLABLE CIEUC YE CIEUC
+0xA0D7	0xC86B	#HANGUL SYLLABLE CIEUC YE CHIEUCH
+0xA0D8	0xC86C	#HANGUL SYLLABLE CIEUC YE KHIEUKH
+0xA0D9	0xC86D	#HANGUL SYLLABLE CIEUC YE THIEUTH
+0xA0DA	0xC86E	#HANGUL SYLLABLE CIEUC YE PHIEUPH
+0xA0DB	0xC86F	#HANGUL SYLLABLE CIEUC YE HIEUH
+0xA0DC	0xC872	#HANGUL SYLLABLE CIEUC O SSANGKIYEOK
+0xA0DD	0xC873	#HANGUL SYLLABLE CIEUC O KIYEOKSIOS
+0xA0DE	0xC875	#HANGUL SYLLABLE CIEUC O NIEUNCIEUC
+0xA0DF	0xC876	#HANGUL SYLLABLE CIEUC O NIEUNHIEUH
+0xA0E0	0xC877	#HANGUL SYLLABLE CIEUC O TIKEUT
+0xA0E1	0xC879	#HANGUL SYLLABLE CIEUC O RIEULKIYEOK
+0xA0E2	0xC87B	#HANGUL SYLLABLE CIEUC O RIEULPIEUP
+0xA0E3	0xC87C	#HANGUL SYLLABLE CIEUC O RIEULSIOS
+0xA0E4	0xC87D	#HANGUL SYLLABLE CIEUC O RIEULTHIEUTH
+0xA0E5	0xC87E	#HANGUL SYLLABLE CIEUC O RIEULPHIEUPH
+0xA0E6	0xC87F	#HANGUL SYLLABLE CIEUC O RIEULHIEUH
+0xA0E7	0xC882	#HANGUL SYLLABLE CIEUC O PIEUPSIOS
+0xA0E8	0xC884	#HANGUL SYLLABLE CIEUC O SSANGSIOS
+0xA0E9	0xC888	#HANGUL SYLLABLE CIEUC O KHIEUKH
+0xA0EA	0xC889	#HANGUL SYLLABLE CIEUC O THIEUTH
+0xA0EB	0xC88A	#HANGUL SYLLABLE CIEUC O PHIEUPH
+0xA0EC	0xC88E	#HANGUL SYLLABLE CIEUC WA SSANGKIYEOK
+0xA0ED	0xC88F	#HANGUL SYLLABLE CIEUC WA KIYEOKSIOS
+0xA0EE	0xC890	#HANGUL SYLLABLE CIEUC WA NIEUN
+0xA0EF	0xC891	#HANGUL SYLLABLE CIEUC WA NIEUNCIEUC
+0xA0F0	0xC892	#HANGUL SYLLABLE CIEUC WA NIEUNHIEUH
+0xA0F1	0xC893	#HANGUL SYLLABLE CIEUC WA TIKEUT
+0xA0F2	0xC895	#HANGUL SYLLABLE CIEUC WA RIEULKIYEOK
+0xA0F3	0xC896	#HANGUL SYLLABLE CIEUC WA RIEULMIEUM
+0xA0F4	0xC897	#HANGUL SYLLABLE CIEUC WA RIEULPIEUP
+0xA0F5	0xC898	#HANGUL SYLLABLE CIEUC WA RIEULSIOS
+0xA0F6	0xC899	#HANGUL SYLLABLE CIEUC WA RIEULTHIEUTH
+0xA0F7	0xC89A	#HANGUL SYLLABLE CIEUC WA RIEULPHIEUPH
+0xA0F8	0xC89B	#HANGUL SYLLABLE CIEUC WA RIEULHIEUH
+0xA0F9	0xC89C	#HANGUL SYLLABLE CIEUC WA MIEUM
+0xA0FA	0xC89E	#HANGUL SYLLABLE CIEUC WA PIEUPSIOS
+0xA0FB	0xC8A0	#HANGUL SYLLABLE CIEUC WA SSANGSIOS
+0xA0FC	0xC8A2	#HANGUL SYLLABLE CIEUC WA CIEUC
+0xA0FD	0xC8A3	#HANGUL SYLLABLE CIEUC WA CHIEUCH
+0xA0FE	0xC8A4	#HANGUL SYLLABLE CIEUC WA KHIEUKH
+0xA141	0xC8A5	#HANGUL SYLLABLE CIEUC WA THIEUTH
+0xA142	0xC8A6	#HANGUL SYLLABLE CIEUC WA PHIEUPH
+0xA143	0xC8A7	#HANGUL SYLLABLE CIEUC WA HIEUH
+0xA144	0xC8A9	#HANGUL SYLLABLE CIEUC WAE KIYEOK
+0xA145	0xC8AA	#HANGUL SYLLABLE CIEUC WAE SSANGKIYEOK
+0xA146	0xC8AB	#HANGUL SYLLABLE CIEUC WAE KIYEOKSIOS
+0xA147	0xC8AC	#HANGUL SYLLABLE CIEUC WAE NIEUN
+0xA148	0xC8AD	#HANGUL SYLLABLE CIEUC WAE NIEUNCIEUC
+0xA149	0xC8AE	#HANGUL SYLLABLE CIEUC WAE NIEUNHIEUH
+0xA14A	0xC8AF	#HANGUL SYLLABLE CIEUC WAE TIKEUT
+0xA14B	0xC8B0	#HANGUL SYLLABLE CIEUC WAE RIEUL
+0xA14C	0xC8B1	#HANGUL SYLLABLE CIEUC WAE RIEULKIYEOK
+0xA14D	0xC8B2	#HANGUL SYLLABLE CIEUC WAE RIEULMIEUM
+0xA14E	0xC8B3	#HANGUL SYLLABLE CIEUC WAE RIEULPIEUP
+0xA14F	0xC8B4	#HANGUL SYLLABLE CIEUC WAE RIEULSIOS
+0xA150	0xC8B5	#HANGUL SYLLABLE CIEUC WAE RIEULTHIEUTH
+0xA151	0xC8B6	#HANGUL SYLLABLE CIEUC WAE RIEULPHIEUPH
+0xA152	0xC8B7	#HANGUL SYLLABLE CIEUC WAE RIEULHIEUH
+0xA153	0xC8B8	#HANGUL SYLLABLE CIEUC WAE MIEUM
+0xA154	0xC8B9	#HANGUL SYLLABLE CIEUC WAE PIEUP
+0xA155	0xC8BA	#HANGUL SYLLABLE CIEUC WAE PIEUPSIOS
+0xA156	0xC8BB	#HANGUL SYLLABLE CIEUC WAE SIOS
+0xA157	0xC8BE	#HANGUL SYLLABLE CIEUC WAE CIEUC
+0xA158	0xC8BF	#HANGUL SYLLABLE CIEUC WAE CHIEUCH
+0xA159	0xC8C0	#HANGUL SYLLABLE CIEUC WAE KHIEUKH
+0xA15A	0xC8C1	#HANGUL SYLLABLE CIEUC WAE THIEUTH
+0xA161	0xC8C2	#HANGUL SYLLABLE CIEUC WAE PHIEUPH
+0xA162	0xC8C3	#HANGUL SYLLABLE CIEUC WAE HIEUH
+0xA163	0xC8C5	#HANGUL SYLLABLE CIEUC OE KIYEOK
+0xA164	0xC8C6	#HANGUL SYLLABLE CIEUC OE SSANGKIYEOK
+0xA165	0xC8C7	#HANGUL SYLLABLE CIEUC OE KIYEOKSIOS
+0xA166	0xC8C9	#HANGUL SYLLABLE CIEUC OE NIEUNCIEUC
+0xA167	0xC8CA	#HANGUL SYLLABLE CIEUC OE NIEUNHIEUH
+0xA168	0xC8CB	#HANGUL SYLLABLE CIEUC OE TIKEUT
+0xA169	0xC8CD	#HANGUL SYLLABLE CIEUC OE RIEULKIYEOK
+0xA16A	0xC8CE	#HANGUL SYLLABLE CIEUC OE RIEULMIEUM
+0xA16B	0xC8CF	#HANGUL SYLLABLE CIEUC OE RIEULPIEUP
+0xA16C	0xC8D0	#HANGUL SYLLABLE CIEUC OE RIEULSIOS
+0xA16D	0xC8D1	#HANGUL SYLLABLE CIEUC OE RIEULTHIEUTH
+0xA16E	0xC8D2	#HANGUL SYLLABLE CIEUC OE RIEULPHIEUPH
+0xA16F	0xC8D3	#HANGUL SYLLABLE CIEUC OE RIEULHIEUH
+0xA170	0xC8D6	#HANGUL SYLLABLE CIEUC OE PIEUPSIOS
+0xA171	0xC8D8	#HANGUL SYLLABLE CIEUC OE SSANGSIOS
+0xA172	0xC8DA	#HANGUL SYLLABLE CIEUC OE CIEUC
+0xA173	0xC8DB	#HANGUL SYLLABLE CIEUC OE CHIEUCH
+0xA174	0xC8DC	#HANGUL SYLLABLE CIEUC OE KHIEUKH
+0xA175	0xC8DD	#HANGUL SYLLABLE CIEUC OE THIEUTH
+0xA176	0xC8DE	#HANGUL SYLLABLE CIEUC OE PHIEUPH
+0xA177	0xC8DF	#HANGUL SYLLABLE CIEUC OE HIEUH
+0xA178	0xC8E2	#HANGUL SYLLABLE CIEUC YO SSANGKIYEOK
+0xA179	0xC8E3	#HANGUL SYLLABLE CIEUC YO KIYEOKSIOS
+0xA17A	0xC8E5	#HANGUL SYLLABLE CIEUC YO NIEUNCIEUC
+0xA181	0xC8E6	#HANGUL SYLLABLE CIEUC YO NIEUNHIEUH
+0xA182	0xC8E7	#HANGUL SYLLABLE CIEUC YO TIKEUT
+0xA183	0xC8E8	#HANGUL SYLLABLE CIEUC YO RIEUL
+0xA184	0xC8E9	#HANGUL SYLLABLE CIEUC YO RIEULKIYEOK
+0xA185	0xC8EA	#HANGUL SYLLABLE CIEUC YO RIEULMIEUM
+0xA186	0xC8EB	#HANGUL SYLLABLE CIEUC YO RIEULPIEUP
+0xA187	0xC8EC	#HANGUL SYLLABLE CIEUC YO RIEULSIOS
+0xA188	0xC8ED	#HANGUL SYLLABLE CIEUC YO RIEULTHIEUTH
+0xA189	0xC8EE	#HANGUL SYLLABLE CIEUC YO RIEULPHIEUPH
+0xA18A	0xC8EF	#HANGUL SYLLABLE CIEUC YO RIEULHIEUH
+0xA18B	0xC8F0	#HANGUL SYLLABLE CIEUC YO MIEUM
+0xA18C	0xC8F1	#HANGUL SYLLABLE CIEUC YO PIEUP
+0xA18D	0xC8F2	#HANGUL SYLLABLE CIEUC YO PIEUPSIOS
+0xA18E	0xC8F3	#HANGUL SYLLABLE CIEUC YO SIOS
+0xA18F	0xC8F4	#HANGUL SYLLABLE CIEUC YO SSANGSIOS
+0xA190	0xC8F6	#HANGUL SYLLABLE CIEUC YO CIEUC
+0xA191	0xC8F7	#HANGUL SYLLABLE CIEUC YO CHIEUCH
+0xA192	0xC8F8	#HANGUL SYLLABLE CIEUC YO KHIEUKH
+0xA193	0xC8F9	#HANGUL SYLLABLE CIEUC YO THIEUTH
+0xA194	0xC8FA	#HANGUL SYLLABLE CIEUC YO PHIEUPH
+0xA195	0xC8FB	#HANGUL SYLLABLE CIEUC YO HIEUH
+0xA196	0xC8FE	#HANGUL SYLLABLE CIEUC U SSANGKIYEOK
+0xA197	0xC8FF	#HANGUL SYLLABLE CIEUC U KIYEOKSIOS
+0xA198	0xC901	#HANGUL SYLLABLE CIEUC U NIEUNCIEUC
+0xA199	0xC902	#HANGUL SYLLABLE CIEUC U NIEUNHIEUH
+0xA19A	0xC903	#HANGUL SYLLABLE CIEUC U TIKEUT
+0xA19B	0xC907	#HANGUL SYLLABLE CIEUC U RIEULPIEUP
+0xA19C	0xC908	#HANGUL SYLLABLE CIEUC U RIEULSIOS
+0xA19D	0xC909	#HANGUL SYLLABLE CIEUC U RIEULTHIEUTH
+0xA19E	0xC90A	#HANGUL SYLLABLE CIEUC U RIEULPHIEUPH
+0xA19F	0xC90B	#HANGUL SYLLABLE CIEUC U RIEULHIEUH
+0xA1A0	0xC90E	#HANGUL SYLLABLE CIEUC U PIEUPSIOS
+0xA1A1	0x3000	#IDEOGRAPHIC SPACE
+0xA1A2	0x3001	#IDEOGRAPHIC COMMA
+0xA1A3	0x3002	#IDEOGRAPHIC FULL STOP
+0xA1A4	0x00B7	#MIDDLE DOT
+0xA1A5	0x2025	#TWO DOT LEADER
+0xA1A6	0x2026	#HORIZONTAL ELLIPSIS
+0xA1A7	0x00A8	#DIAERESIS
+0xA1A8	0x3003	#DITTO MARK
+0xA1A9	0x00AD	#SOFT HYPHEN
+0xA1AA	0x2015	#HORIZONTAL BAR
+0xA1AB	0x2225	#PARALLEL TO
+0xA1AC	0xFF3C	#FULLWIDTH REVERSE SOLIDUS
+0xA1AD	0x223C	#TILDE OPERATOR
+0xA1AE	0x2018	#LEFT SINGLE QUOTATION MARK
+0xA1AF	0x2019	#RIGHT SINGLE QUOTATION MARK
+0xA1B0	0x201C	#LEFT DOUBLE QUOTATION MARK
+0xA1B1	0x201D	#RIGHT DOUBLE QUOTATION MARK
+0xA1B2	0x3014	#LEFT TORTOISE SHELL BRACKET
+0xA1B3	0x3015	#RIGHT TORTOISE SHELL BRACKET
+0xA1B4	0x3008	#LEFT ANGLE BRACKET
+0xA1B5	0x3009	#RIGHT ANGLE BRACKET
+0xA1B6	0x300A	#LEFT DOUBLE ANGLE BRACKET
+0xA1B7	0x300B	#RIGHT DOUBLE ANGLE BRACKET
+0xA1B8	0x300C	#LEFT CORNER BRACKET
+0xA1B9	0x300D	#RIGHT CORNER BRACKET
+0xA1BA	0x300E	#LEFT WHITE CORNER BRACKET
+0xA1BB	0x300F	#RIGHT WHITE CORNER BRACKET
+0xA1BC	0x3010	#LEFT BLACK LENTICULAR BRACKET
+0xA1BD	0x3011	#RIGHT BLACK LENTICULAR BRACKET
+0xA1BE	0x00B1	#PLUS-MINUS SIGN
+0xA1BF	0x00D7	#MULTIPLICATION SIGN
+0xA1C0	0x00F7	#DIVISION SIGN
+0xA1C1	0x2260	#NOT EQUAL TO
+0xA1C2	0x2264	#LESS-THAN OR EQUAL TO
+0xA1C3	0x2265	#GREATER-THAN OR EQUAL TO
+0xA1C4	0x221E	#INFINITY
+0xA1C5	0x2234	#THEREFORE
+0xA1C6	0x00B0	#DEGREE SIGN
+0xA1C7	0x2032	#PRIME
+0xA1C8	0x2033	#DOUBLE PRIME
+0xA1C9	0x2103	#DEGREE CELSIUS
+0xA1CA	0x212B	#ANGSTROM SIGN
+0xA1CB	0xFFE0	#FULLWIDTH CENT SIGN
+0xA1CC	0xFFE1	#FULLWIDTH POUND SIGN
+0xA1CD	0xFFE5	#FULLWIDTH YEN SIGN
+0xA1CE	0x2642	#MALE SIGN
+0xA1CF	0x2640	#FEMALE SIGN
+0xA1D0	0x2220	#ANGLE
+0xA1D1	0x22A5	#UP TACK
+0xA1D2	0x2312	#ARC
+0xA1D3	0x2202	#PARTIAL DIFFERENTIAL
+0xA1D4	0x2207	#NABLA
+0xA1D5	0x2261	#IDENTICAL TO
+0xA1D6	0x2252	#APPROXIMATELY EQUAL TO OR THE IMAGE OF
+0xA1D7	0x00A7	#SECTION SIGN
+0xA1D8	0x203B	#REFERENCE MARK
+0xA1D9	0x2606	#WHITE STAR
+0xA1DA	0x2605	#BLACK STAR
+0xA1DB	0x25CB	#WHITE CIRCLE
+0xA1DC	0x25CF	#BLACK CIRCLE
+0xA1DD	0x25CE	#BULLSEYE
+0xA1DE	0x25C7	#WHITE DIAMOND
+0xA1DF	0x25C6	#BLACK DIAMOND
+0xA1E0	0x25A1	#WHITE SQUARE
+0xA1E1	0x25A0	#BLACK SQUARE
+0xA1E2	0x25B3	#WHITE UP-POINTING TRIANGLE
+0xA1E3	0x25B2	#BLACK UP-POINTING TRIANGLE
+0xA1E4	0x25BD	#WHITE DOWN-POINTING TRIANGLE
+0xA1E5	0x25BC	#BLACK DOWN-POINTING TRIANGLE
+0xA1E6	0x2192	#RIGHTWARDS ARROW
+0xA1E7	0x2190	#LEFTWARDS ARROW
+0xA1E8	0x2191	#UPWARDS ARROW
+0xA1E9	0x2193	#DOWNWARDS ARROW
+0xA1EA	0x2194	#LEFT RIGHT ARROW
+0xA1EB	0x3013	#GETA MARK
+0xA1EC	0x226A	#MUCH LESS-THAN
+0xA1ED	0x226B	#MUCH GREATER-THAN
+0xA1EE	0x221A	#SQUARE ROOT
+0xA1EF	0x223D	#REVERSED TILDE
+0xA1F0	0x221D	#PROPORTIONAL TO
+0xA1F1	0x2235	#BECAUSE
+0xA1F2	0x222B	#INTEGRAL
+0xA1F3	0x222C	#DOUBLE INTEGRAL
+0xA1F4	0x2208	#ELEMENT OF
+0xA1F5	0x220B	#CONTAINS AS MEMBER
+0xA1F6	0x2286	#SUBSET OF OR EQUAL TO
+0xA1F7	0x2287	#SUPERSET OF OR EQUAL TO
+0xA1F8	0x2282	#SUBSET OF
+0xA1F9	0x2283	#SUPERSET OF
+0xA1FA	0x222A	#UNION
+0xA1FB	0x2229	#INTERSECTION
+0xA1FC	0x2227	#LOGICAL AND
+0xA1FD	0x2228	#LOGICAL OR
+0xA1FE	0xFFE2	#FULLWIDTH NOT SIGN
+0xA241	0xC910	#HANGUL SYLLABLE CIEUC U SSANGSIOS
+0xA242	0xC912	#HANGUL SYLLABLE CIEUC U CIEUC
+0xA243	0xC913	#HANGUL SYLLABLE CIEUC U CHIEUCH
+0xA244	0xC914	#HANGUL SYLLABLE CIEUC U KHIEUKH
+0xA245	0xC915	#HANGUL SYLLABLE CIEUC U THIEUTH
+0xA246	0xC916	#HANGUL SYLLABLE CIEUC U PHIEUPH
+0xA247	0xC917	#HANGUL SYLLABLE CIEUC U HIEUH
+0xA248	0xC919	#HANGUL SYLLABLE CIEUC WEO KIYEOK
+0xA249	0xC91A	#HANGUL SYLLABLE CIEUC WEO SSANGKIYEOK
+0xA24A	0xC91B	#HANGUL SYLLABLE CIEUC WEO KIYEOKSIOS
+0xA24B	0xC91C	#HANGUL SYLLABLE CIEUC WEO NIEUN
+0xA24C	0xC91D	#HANGUL SYLLABLE CIEUC WEO NIEUNCIEUC
+0xA24D	0xC91E	#HANGUL SYLLABLE CIEUC WEO NIEUNHIEUH
+0xA24E	0xC91F	#HANGUL SYLLABLE CIEUC WEO TIKEUT
+0xA24F	0xC920	#HANGUL SYLLABLE CIEUC WEO RIEUL
+0xA250	0xC921	#HANGUL SYLLABLE CIEUC WEO RIEULKIYEOK
+0xA251	0xC922	#HANGUL SYLLABLE CIEUC WEO RIEULMIEUM
+0xA252	0xC923	#HANGUL SYLLABLE CIEUC WEO RIEULPIEUP
+0xA253	0xC924	#HANGUL SYLLABLE CIEUC WEO RIEULSIOS
+0xA254	0xC925	#HANGUL SYLLABLE CIEUC WEO RIEULTHIEUTH
+0xA255	0xC926	#HANGUL SYLLABLE CIEUC WEO RIEULPHIEUPH
+0xA256	0xC927	#HANGUL SYLLABLE CIEUC WEO RIEULHIEUH
+0xA257	0xC928	#HANGUL SYLLABLE CIEUC WEO MIEUM
+0xA258	0xC929	#HANGUL SYLLABLE CIEUC WEO PIEUP
+0xA259	0xC92A	#HANGUL SYLLABLE CIEUC WEO PIEUPSIOS
+0xA25A	0xC92B	#HANGUL SYLLABLE CIEUC WEO SIOS
+0xA261	0xC92D	#HANGUL SYLLABLE CIEUC WEO IEUNG
+0xA262	0xC92E	#HANGUL SYLLABLE CIEUC WEO CIEUC
+0xA263	0xC92F	#HANGUL SYLLABLE CIEUC WEO CHIEUCH
+0xA264	0xC930	#HANGUL SYLLABLE CIEUC WEO KHIEUKH
+0xA265	0xC931	#HANGUL SYLLABLE CIEUC WEO THIEUTH
+0xA266	0xC932	#HANGUL SYLLABLE CIEUC WEO PHIEUPH
+0xA267	0xC933	#HANGUL SYLLABLE CIEUC WEO HIEUH
+0xA268	0xC935	#HANGUL SYLLABLE CIEUC WE KIYEOK
+0xA269	0xC936	#HANGUL SYLLABLE CIEUC WE SSANGKIYEOK
+0xA26A	0xC937	#HANGUL SYLLABLE CIEUC WE KIYEOKSIOS
+0xA26B	0xC938	#HANGUL SYLLABLE CIEUC WE NIEUN
+0xA26C	0xC939	#HANGUL SYLLABLE CIEUC WE NIEUNCIEUC
+0xA26D	0xC93A	#HANGUL SYLLABLE CIEUC WE NIEUNHIEUH
+0xA26E	0xC93B	#HANGUL SYLLABLE CIEUC WE TIKEUT
+0xA26F	0xC93C	#HANGUL SYLLABLE CIEUC WE RIEUL
+0xA270	0xC93D	#HANGUL SYLLABLE CIEUC WE RIEULKIYEOK
+0xA271	0xC93E	#HANGUL SYLLABLE CIEUC WE RIEULMIEUM
+0xA272	0xC93F	#HANGUL SYLLABLE CIEUC WE RIEULPIEUP
+0xA273	0xC940	#HANGUL SYLLABLE CIEUC WE RIEULSIOS
+0xA274	0xC941	#HANGUL SYLLABLE CIEUC WE RIEULTHIEUTH
+0xA275	0xC942	#HANGUL SYLLABLE CIEUC WE RIEULPHIEUPH
+0xA276	0xC943	#HANGUL SYLLABLE CIEUC WE RIEULHIEUH
+0xA277	0xC944	#HANGUL SYLLABLE CIEUC WE MIEUM
+0xA278	0xC945	#HANGUL SYLLABLE CIEUC WE PIEUP
+0xA279	0xC946	#HANGUL SYLLABLE CIEUC WE PIEUPSIOS
+0xA27A	0xC947	#HANGUL SYLLABLE CIEUC WE SIOS
+0xA281	0xC948	#HANGUL SYLLABLE CIEUC WE SSANGSIOS
+0xA282	0xC949	#HANGUL SYLLABLE CIEUC WE IEUNG
+0xA283	0xC94A	#HANGUL SYLLABLE CIEUC WE CIEUC
+0xA284	0xC94B	#HANGUL SYLLABLE CIEUC WE CHIEUCH
+0xA285	0xC94C	#HANGUL SYLLABLE CIEUC WE KHIEUKH
+0xA286	0xC94D	#HANGUL SYLLABLE CIEUC WE THIEUTH
+0xA287	0xC94E	#HANGUL SYLLABLE CIEUC WE PHIEUPH
+0xA288	0xC94F	#HANGUL SYLLABLE CIEUC WE HIEUH
+0xA289	0xC952	#HANGUL SYLLABLE CIEUC WI SSANGKIYEOK
+0xA28A	0xC953	#HANGUL SYLLABLE CIEUC WI KIYEOKSIOS
+0xA28B	0xC955	#HANGUL SYLLABLE CIEUC WI NIEUNCIEUC
+0xA28C	0xC956	#HANGUL SYLLABLE CIEUC WI NIEUNHIEUH
+0xA28D	0xC957	#HANGUL SYLLABLE CIEUC WI TIKEUT
+0xA28E	0xC959	#HANGUL SYLLABLE CIEUC WI RIEULKIYEOK
+0xA28F	0xC95A	#HANGUL SYLLABLE CIEUC WI RIEULMIEUM
+0xA290	0xC95B	#HANGUL SYLLABLE CIEUC WI RIEULPIEUP
+0xA291	0xC95C	#HANGUL SYLLABLE CIEUC WI RIEULSIOS
+0xA292	0xC95D	#HANGUL SYLLABLE CIEUC WI RIEULTHIEUTH
+0xA293	0xC95E	#HANGUL SYLLABLE CIEUC WI RIEULPHIEUPH
+0xA294	0xC95F	#HANGUL SYLLABLE CIEUC WI RIEULHIEUH
+0xA295	0xC962	#HANGUL SYLLABLE CIEUC WI PIEUPSIOS
+0xA296	0xC964	#HANGUL SYLLABLE CIEUC WI SSANGSIOS
+0xA297	0xC965	#HANGUL SYLLABLE CIEUC WI IEUNG
+0xA298	0xC966	#HANGUL SYLLABLE CIEUC WI CIEUC
+0xA299	0xC967	#HANGUL SYLLABLE CIEUC WI CHIEUCH
+0xA29A	0xC968	#HANGUL SYLLABLE CIEUC WI KHIEUKH
+0xA29B	0xC969	#HANGUL SYLLABLE CIEUC WI THIEUTH
+0xA29C	0xC96A	#HANGUL SYLLABLE CIEUC WI PHIEUPH
+0xA29D	0xC96B	#HANGUL SYLLABLE CIEUC WI HIEUH
+0xA29E	0xC96D	#HANGUL SYLLABLE CIEUC YU KIYEOK
+0xA29F	0xC96E	#HANGUL SYLLABLE CIEUC YU SSANGKIYEOK
+0xA2A0	0xC96F	#HANGUL SYLLABLE CIEUC YU KIYEOKSIOS
+0xA2A1	0x21D2	#RIGHTWARDS DOUBLE ARROW
+0xA2A2	0x21D4	#LEFT RIGHT DOUBLE ARROW
+0xA2A3	0x2200	#FOR ALL
+0xA2A4	0x2203	#THERE EXISTS
+0xA2A5	0x00B4	#ACUTE ACCENT
+0xA2A6	0xFF5E	#FULLWIDTH TILDE
+0xA2A7	0x02C7	#CARON
+0xA2A8	0x02D8	#BREVE
+0xA2A9	0x02DD	#DOUBLE ACUTE ACCENT
+0xA2AA	0x02DA	#RING ABOVE
+0xA2AB	0x02D9	#DOT ABOVE
+0xA2AC	0x00B8	#CEDILLA
+0xA2AD	0x02DB	#OGONEK
+0xA2AE	0x00A1	#INVERTED EXCLAMATION MARK
+0xA2AF	0x00BF	#INVERTED QUESTION MARK
+0xA2B0	0x02D0	#MODIFIER LETTER TRIANGULAR COLON
+0xA2B1	0x222E	#CONTOUR INTEGRAL
+0xA2B2	0x2211	#N-ARY SUMMATION
+0xA2B3	0x220F	#N-ARY PRODUCT
+0xA2B4	0x00A4	#CURRENCY SIGN
+0xA2B5	0x2109	#DEGREE FAHRENHEIT
+0xA2B6	0x2030	#PER MILLE SIGN
+0xA2B7	0x25C1	#WHITE LEFT-POINTING TRIANGLE
+0xA2B8	0x25C0	#BLACK LEFT-POINTING TRIANGLE
+0xA2B9	0x25B7	#WHITE RIGHT-POINTING TRIANGLE
+0xA2BA	0x25B6	#BLACK RIGHT-POINTING TRIANGLE
+0xA2BB	0x2664	#WHITE SPADE SUIT
+0xA2BC	0x2660	#BLACK SPADE SUIT
+0xA2BD	0x2661	#WHITE HEART SUIT
+0xA2BE	0x2665	#BLACK HEART SUIT
+0xA2BF	0x2667	#WHITE CLUB SUIT
+0xA2C0	0x2663	#BLACK CLUB SUIT
+0xA2C1	0x2299	#CIRCLED DOT OPERATOR
+0xA2C2	0x25C8	#WHITE DIAMOND CONTAINING BLACK SMALL DIAMOND
+0xA2C3	0x25A3	#WHITE SQUARE CONTAINING BLACK SMALL SQUARE
+0xA2C4	0x25D0	#CIRCLE WITH LEFT HALF BLACK
+0xA2C5	0x25D1	#CIRCLE WITH RIGHT HALF BLACK
+0xA2C6	0x2592	#MEDIUM SHADE
+0xA2C7	0x25A4	#SQUARE WITH HORIZONTAL FILL
+0xA2C8	0x25A5	#SQUARE WITH VERTICAL FILL
+0xA2C9	0x25A8	#SQUARE WITH UPPER RIGHT TO LOWER LEFT FILL
+0xA2CA	0x25A7	#SQUARE WITH UPPER LEFT TO LOWER RIGHT FILL
+0xA2CB	0x25A6	#SQUARE WITH ORTHOGONAL CROSSHATCH FILL
+0xA2CC	0x25A9	#SQUARE WITH DIAGONAL CROSSHATCH FILL
+0xA2CD	0x2668	#HOT SPRINGS
+0xA2CE	0x260F	#WHITE TELEPHONE
+0xA2CF	0x260E	#BLACK TELEPHONE
+0xA2D0	0x261C	#WHITE LEFT POINTING INDEX
+0xA2D1	0x261E	#WHITE RIGHT POINTING INDEX
+0xA2D2	0x00B6	#PILCROW SIGN
+0xA2D3	0x2020	#DAGGER
+0xA2D4	0x2021	#DOUBLE DAGGER
+0xA2D5	0x2195	#UP DOWN ARROW
+0xA2D6	0x2197	#NORTH EAST ARROW
+0xA2D7	0x2199	#SOUTH WEST ARROW
+0xA2D8	0x2196	#NORTH WEST ARROW
+0xA2D9	0x2198	#SOUTH EAST ARROW
+0xA2DA	0x266D	#MUSIC FLAT SIGN
+0xA2DB	0x2669	#QUARTER NOTE
+0xA2DC	0x266A	#EIGHTH NOTE
+0xA2DD	0x266C	#BEAMED SIXTEENTH NOTES
+0xA2DE	0x327F	#KOREAN STANDARD SYMBOL
+0xA2DF	0x321C	#PARENTHESIZED HANGUL CIEUC U
+0xA2E0	0x2116	#NUMERO SIGN
+0xA2E1	0x33C7	#SQUARE CO
+0xA2E2	0x2122	#TRADE MARK SIGN
+0xA2E3	0x33C2	#SQUARE AM
+0xA2E4	0x33D8	#SQUARE PM
+0xA2E5	0x2121	#TELEPHONE SIGN
+0xA2E6	0x20AC	#EURO SIGN
+0xA2E7	0x00AE	#REGISTERED SIGN
+0xA341	0xC971	#HANGUL SYLLABLE CIEUC YU NIEUNCIEUC
+0xA342	0xC972	#HANGUL SYLLABLE CIEUC YU NIEUNHIEUH
+0xA343	0xC973	#HANGUL SYLLABLE CIEUC YU TIKEUT
+0xA344	0xC975	#HANGUL SYLLABLE CIEUC YU RIEULKIYEOK
+0xA345	0xC976	#HANGUL SYLLABLE CIEUC YU RIEULMIEUM
+0xA346	0xC977	#HANGUL SYLLABLE CIEUC YU RIEULPIEUP
+0xA347	0xC978	#HANGUL SYLLABLE CIEUC YU RIEULSIOS
+0xA348	0xC979	#HANGUL SYLLABLE CIEUC YU RIEULTHIEUTH
+0xA349	0xC97A	#HANGUL SYLLABLE CIEUC YU RIEULPHIEUPH
+0xA34A	0xC97B	#HANGUL SYLLABLE CIEUC YU RIEULHIEUH
+0xA34B	0xC97D	#HANGUL SYLLABLE CIEUC YU PIEUP
+0xA34C	0xC97E	#HANGUL SYLLABLE CIEUC YU PIEUPSIOS
+0xA34D	0xC97F	#HANGUL SYLLABLE CIEUC YU SIOS
+0xA34E	0xC980	#HANGUL SYLLABLE CIEUC YU SSANGSIOS
+0xA34F	0xC981	#HANGUL SYLLABLE CIEUC YU IEUNG
+0xA350	0xC982	#HANGUL SYLLABLE CIEUC YU CIEUC
+0xA351	0xC983	#HANGUL SYLLABLE CIEUC YU CHIEUCH
+0xA352	0xC984	#HANGUL SYLLABLE CIEUC YU KHIEUKH
+0xA353	0xC985	#HANGUL SYLLABLE CIEUC YU THIEUTH
+0xA354	0xC986	#HANGUL SYLLABLE CIEUC YU PHIEUPH
+0xA355	0xC987	#HANGUL SYLLABLE CIEUC YU HIEUH
+0xA356	0xC98A	#HANGUL SYLLABLE CIEUC EU SSANGKIYEOK
+0xA357	0xC98B	#HANGUL SYLLABLE CIEUC EU KIYEOKSIOS
+0xA358	0xC98D	#HANGUL SYLLABLE CIEUC EU NIEUNCIEUC
+0xA359	0xC98E	#HANGUL SYLLABLE CIEUC EU NIEUNHIEUH
+0xA35A	0xC98F	#HANGUL SYLLABLE CIEUC EU TIKEUT
+0xA361	0xC991	#HANGUL SYLLABLE CIEUC EU RIEULKIYEOK
+0xA362	0xC992	#HANGUL SYLLABLE CIEUC EU RIEULMIEUM
+0xA363	0xC993	#HANGUL SYLLABLE CIEUC EU RIEULPIEUP
+0xA364	0xC994	#HANGUL SYLLABLE CIEUC EU RIEULSIOS
+0xA365	0xC995	#HANGUL SYLLABLE CIEUC EU RIEULTHIEUTH
+0xA366	0xC996	#HANGUL SYLLABLE CIEUC EU RIEULPHIEUPH
+0xA367	0xC997	#HANGUL SYLLABLE CIEUC EU RIEULHIEUH
+0xA368	0xC99A	#HANGUL SYLLABLE CIEUC EU PIEUPSIOS
+0xA369	0xC99C	#HANGUL SYLLABLE CIEUC EU SSANGSIOS
+0xA36A	0xC99E	#HANGUL SYLLABLE CIEUC EU CIEUC
+0xA36B	0xC99F	#HANGUL SYLLABLE CIEUC EU CHIEUCH
+0xA36C	0xC9A0	#HANGUL SYLLABLE CIEUC EU KHIEUKH
+0xA36D	0xC9A1	#HANGUL SYLLABLE CIEUC EU THIEUTH
+0xA36E	0xC9A2	#HANGUL SYLLABLE CIEUC EU PHIEUPH
+0xA36F	0xC9A3	#HANGUL SYLLABLE CIEUC EU HIEUH
+0xA370	0xC9A4	#HANGUL SYLLABLE CIEUC YI
+0xA371	0xC9A5	#HANGUL SYLLABLE CIEUC YI KIYEOK
+0xA372	0xC9A6	#HANGUL SYLLABLE CIEUC YI SSANGKIYEOK
+0xA373	0xC9A7	#HANGUL SYLLABLE CIEUC YI KIYEOKSIOS
+0xA374	0xC9A8	#HANGUL SYLLABLE CIEUC YI NIEUN
+0xA375	0xC9A9	#HANGUL SYLLABLE CIEUC YI NIEUNCIEUC
+0xA376	0xC9AA	#HANGUL SYLLABLE CIEUC YI NIEUNHIEUH
+0xA377	0xC9AB	#HANGUL SYLLABLE CIEUC YI TIKEUT
+0xA378	0xC9AC	#HANGUL SYLLABLE CIEUC YI RIEUL
+0xA379	0xC9AD	#HANGUL SYLLABLE CIEUC YI RIEULKIYEOK
+0xA37A	0xC9AE	#HANGUL SYLLABLE CIEUC YI RIEULMIEUM
+0xA381	0xC9AF	#HANGUL SYLLABLE CIEUC YI RIEULPIEUP
+0xA382	0xC9B0	#HANGUL SYLLABLE CIEUC YI RIEULSIOS
+0xA383	0xC9B1	#HANGUL SYLLABLE CIEUC YI RIEULTHIEUTH
+0xA384	0xC9B2	#HANGUL SYLLABLE CIEUC YI RIEULPHIEUPH
+0xA385	0xC9B3	#HANGUL SYLLABLE CIEUC YI RIEULHIEUH
+0xA386	0xC9B4	#HANGUL SYLLABLE CIEUC YI MIEUM
+0xA387	0xC9B5	#HANGUL SYLLABLE CIEUC YI PIEUP
+0xA388	0xC9B6	#HANGUL SYLLABLE CIEUC YI PIEUPSIOS
+0xA389	0xC9B7	#HANGUL SYLLABLE CIEUC YI SIOS
+0xA38A	0xC9B8	#HANGUL SYLLABLE CIEUC YI SSANGSIOS
+0xA38B	0xC9B9	#HANGUL SYLLABLE CIEUC YI IEUNG
+0xA38C	0xC9BA	#HANGUL SYLLABLE CIEUC YI CIEUC
+0xA38D	0xC9BB	#HANGUL SYLLABLE CIEUC YI CHIEUCH
+0xA38E	0xC9BC	#HANGUL SYLLABLE CIEUC YI KHIEUKH
+0xA38F	0xC9BD	#HANGUL SYLLABLE CIEUC YI THIEUTH
+0xA390	0xC9BE	#HANGUL SYLLABLE CIEUC YI PHIEUPH
+0xA391	0xC9BF	#HANGUL SYLLABLE CIEUC YI HIEUH
+0xA392	0xC9C2	#HANGUL SYLLABLE CIEUC I SSANGKIYEOK
+0xA393	0xC9C3	#HANGUL SYLLABLE CIEUC I KIYEOKSIOS
+0xA394	0xC9C5	#HANGUL SYLLABLE CIEUC I NIEUNCIEUC
+0xA395	0xC9C6	#HANGUL SYLLABLE CIEUC I NIEUNHIEUH
+0xA396	0xC9C9	#HANGUL SYLLABLE CIEUC I RIEULKIYEOK
+0xA397	0xC9CB	#HANGUL SYLLABLE CIEUC I RIEULPIEUP
+0xA398	0xC9CC	#HANGUL SYLLABLE CIEUC I RIEULSIOS
+0xA399	0xC9CD	#HANGUL SYLLABLE CIEUC I RIEULTHIEUTH
+0xA39A	0xC9CE	#HANGUL SYLLABLE CIEUC I RIEULPHIEUPH
+0xA39B	0xC9CF	#HANGUL SYLLABLE CIEUC I RIEULHIEUH
+0xA39C	0xC9D2	#HANGUL SYLLABLE CIEUC I PIEUPSIOS
+0xA39D	0xC9D4	#HANGUL SYLLABLE CIEUC I SSANGSIOS
+0xA39E	0xC9D7	#HANGUL SYLLABLE CIEUC I CHIEUCH
+0xA39F	0xC9D8	#HANGUL SYLLABLE CIEUC I KHIEUKH
+0xA3A0	0xC9DB	#HANGUL SYLLABLE CIEUC I HIEUH
+0xA3A1	0xFF01	#FULLWIDTH EXCLAMATION MARK
+0xA3A2	0xFF02	#FULLWIDTH QUOTATION MARK
+0xA3A3	0xFF03	#FULLWIDTH NUMBER SIGN
+0xA3A4	0xFF04	#FULLWIDTH DOLLAR SIGN
+0xA3A5	0xFF05	#FULLWIDTH PERCENT SIGN
+0xA3A6	0xFF06	#FULLWIDTH AMPERSAND
+0xA3A7	0xFF07	#FULLWIDTH APOSTROPHE
+0xA3A8	0xFF08	#FULLWIDTH LEFT PARENTHESIS
+0xA3A9	0xFF09	#FULLWIDTH RIGHT PARENTHESIS
+0xA3AA	0xFF0A	#FULLWIDTH ASTERISK
+0xA3AB	0xFF0B	#FULLWIDTH PLUS SIGN
+0xA3AC	0xFF0C	#FULLWIDTH COMMA
+0xA3AD	0xFF0D	#FULLWIDTH HYPHEN-MINUS
+0xA3AE	0xFF0E	#FULLWIDTH FULL STOP
+0xA3AF	0xFF0F	#FULLWIDTH SOLIDUS
+0xA3B0	0xFF10	#FULLWIDTH DIGIT ZERO
+0xA3B1	0xFF11	#FULLWIDTH DIGIT ONE
+0xA3B2	0xFF12	#FULLWIDTH DIGIT TWO
+0xA3B3	0xFF13	#FULLWIDTH DIGIT THREE
+0xA3B4	0xFF14	#FULLWIDTH DIGIT FOUR
+0xA3B5	0xFF15	#FULLWIDTH DIGIT FIVE
+0xA3B6	0xFF16	#FULLWIDTH DIGIT SIX
+0xA3B7	0xFF17	#FULLWIDTH DIGIT SEVEN
+0xA3B8	0xFF18	#FULLWIDTH DIGIT EIGHT
+0xA3B9	0xFF19	#FULLWIDTH DIGIT NINE
+0xA3BA	0xFF1A	#FULLWIDTH COLON
+0xA3BB	0xFF1B	#FULLWIDTH SEMICOLON
+0xA3BC	0xFF1C	#FULLWIDTH LESS-THAN SIGN
+0xA3BD	0xFF1D	#FULLWIDTH EQUALS SIGN
+0xA3BE	0xFF1E	#FULLWIDTH GREATER-THAN SIGN
+0xA3BF	0xFF1F	#FULLWIDTH QUESTION MARK
+0xA3C0	0xFF20	#FULLWIDTH COMMERCIAL AT
+0xA3C1	0xFF21	#FULLWIDTH LATIN CAPITAL LETTER A
+0xA3C2	0xFF22	#FULLWIDTH LATIN CAPITAL LETTER B
+0xA3C3	0xFF23	#FULLWIDTH LATIN CAPITAL LETTER C
+0xA3C4	0xFF24	#FULLWIDTH LATIN CAPITAL LETTER D
+0xA3C5	0xFF25	#FULLWIDTH LATIN CAPITAL LETTER E
+0xA3C6	0xFF26	#FULLWIDTH LATIN CAPITAL LETTER F
+0xA3C7	0xFF27	#FULLWIDTH LATIN CAPITAL LETTER G
+0xA3C8	0xFF28	#FULLWIDTH LATIN CAPITAL LETTER H
+0xA3C9	0xFF29	#FULLWIDTH LATIN CAPITAL LETTER I
+0xA3CA	0xFF2A	#FULLWIDTH LATIN CAPITAL LETTER J
+0xA3CB	0xFF2B	#FULLWIDTH LATIN CAPITAL LETTER K
+0xA3CC	0xFF2C	#FULLWIDTH LATIN CAPITAL LETTER L
+0xA3CD	0xFF2D	#FULLWIDTH LATIN CAPITAL LETTER M
+0xA3CE	0xFF2E	#FULLWIDTH LATIN CAPITAL LETTER N
+0xA3CF	0xFF2F	#FULLWIDTH LATIN CAPITAL LETTER O
+0xA3D0	0xFF30	#FULLWIDTH LATIN CAPITAL LETTER P
+0xA3D1	0xFF31	#FULLWIDTH LATIN CAPITAL LETTER Q
+0xA3D2	0xFF32	#FULLWIDTH LATIN CAPITAL LETTER R
+0xA3D3	0xFF33	#FULLWIDTH LATIN CAPITAL LETTER S
+0xA3D4	0xFF34	#FULLWIDTH LATIN CAPITAL LETTER T
+0xA3D5	0xFF35	#FULLWIDTH LATIN CAPITAL LETTER U
+0xA3D6	0xFF36	#FULLWIDTH LATIN CAPITAL LETTER V
+0xA3D7	0xFF37	#FULLWIDTH LATIN CAPITAL LETTER W
+0xA3D8	0xFF38	#FULLWIDTH LATIN CAPITAL LETTER X
+0xA3D9	0xFF39	#FULLWIDTH LATIN CAPITAL LETTER Y
+0xA3DA	0xFF3A	#FULLWIDTH LATIN CAPITAL LETTER Z
+0xA3DB	0xFF3B	#FULLWIDTH LEFT SQUARE BRACKET
+0xA3DC	0xFFE6	#FULLWIDTH WON SIGN
+0xA3DD	0xFF3D	#FULLWIDTH RIGHT SQUARE BRACKET
+0xA3DE	0xFF3E	#FULLWIDTH CIRCUMFLEX ACCENT
+0xA3DF	0xFF3F	#FULLWIDTH LOW LINE
+0xA3E0	0xFF40	#FULLWIDTH GRAVE ACCENT
+0xA3E1	0xFF41	#FULLWIDTH LATIN SMALL LETTER A
+0xA3E2	0xFF42	#FULLWIDTH LATIN SMALL LETTER B
+0xA3E3	0xFF43	#FULLWIDTH LATIN SMALL LETTER C
+0xA3E4	0xFF44	#FULLWIDTH LATIN SMALL LETTER D
+0xA3E5	0xFF45	#FULLWIDTH LATIN SMALL LETTER E
+0xA3E6	0xFF46	#FULLWIDTH LATIN SMALL LETTER F
+0xA3E7	0xFF47	#FULLWIDTH LATIN SMALL LETTER G
+0xA3E8	0xFF48	#FULLWIDTH LATIN SMALL LETTER H
+0xA3E9	0xFF49	#FULLWIDTH LATIN SMALL LETTER I
+0xA3EA	0xFF4A	#FULLWIDTH LATIN SMALL LETTER J
+0xA3EB	0xFF4B	#FULLWIDTH LATIN SMALL LETTER K
+0xA3EC	0xFF4C	#FULLWIDTH LATIN SMALL LETTER L
+0xA3ED	0xFF4D	#FULLWIDTH LATIN SMALL LETTER M
+0xA3EE	0xFF4E	#FULLWIDTH LATIN SMALL LETTER N
+0xA3EF	0xFF4F	#FULLWIDTH LATIN SMALL LETTER O
+0xA3F0	0xFF50	#FULLWIDTH LATIN SMALL LETTER P
+0xA3F1	0xFF51	#FULLWIDTH LATIN SMALL LETTER Q
+0xA3F2	0xFF52	#FULLWIDTH LATIN SMALL LETTER R
+0xA3F3	0xFF53	#FULLWIDTH LATIN SMALL LETTER S
+0xA3F4	0xFF54	#FULLWIDTH LATIN SMALL LETTER T
+0xA3F5	0xFF55	#FULLWIDTH LATIN SMALL LETTER U
+0xA3F6	0xFF56	#FULLWIDTH LATIN SMALL LETTER V
+0xA3F7	0xFF57	#FULLWIDTH LATIN SMALL LETTER W
+0xA3F8	0xFF58	#FULLWIDTH LATIN SMALL LETTER X
+0xA3F9	0xFF59	#FULLWIDTH LATIN SMALL LETTER Y
+0xA3FA	0xFF5A	#FULLWIDTH LATIN SMALL LETTER Z
+0xA3FB	0xFF5B	#FULLWIDTH LEFT CURLY BRACKET
+0xA3FC	0xFF5C	#FULLWIDTH VERTICAL LINE
+0xA3FD	0xFF5D	#FULLWIDTH RIGHT CURLY BRACKET
+0xA3FE	0xFFE3	#FULLWIDTH MACRON
+0xA441	0xC9DE	#HANGUL SYLLABLE SSANGCIEUC A SSANGKIYEOK
+0xA442	0xC9DF	#HANGUL SYLLABLE SSANGCIEUC A KIYEOKSIOS
+0xA443	0xC9E1	#HANGUL SYLLABLE SSANGCIEUC A NIEUNCIEUC
+0xA444	0xC9E3	#HANGUL SYLLABLE SSANGCIEUC A TIKEUT
+0xA445	0xC9E5	#HANGUL SYLLABLE SSANGCIEUC A RIEULKIYEOK
+0xA446	0xC9E6	#HANGUL SYLLABLE SSANGCIEUC A RIEULMIEUM
+0xA447	0xC9E8	#HANGUL SYLLABLE SSANGCIEUC A RIEULSIOS
+0xA448	0xC9E9	#HANGUL SYLLABLE SSANGCIEUC A RIEULTHIEUTH
+0xA449	0xC9EA	#HANGUL SYLLABLE SSANGCIEUC A RIEULPHIEUPH
+0xA44A	0xC9EB	#HANGUL SYLLABLE SSANGCIEUC A RIEULHIEUH
+0xA44B	0xC9EE	#HANGUL SYLLABLE SSANGCIEUC A PIEUPSIOS
+0xA44C	0xC9F2	#HANGUL SYLLABLE SSANGCIEUC A CIEUC
+0xA44D	0xC9F3	#HANGUL SYLLABLE SSANGCIEUC A CHIEUCH
+0xA44E	0xC9F4	#HANGUL SYLLABLE SSANGCIEUC A KHIEUKH
+0xA44F	0xC9F5	#HANGUL SYLLABLE SSANGCIEUC A THIEUTH
+0xA450	0xC9F6	#HANGUL SYLLABLE SSANGCIEUC A PHIEUPH
+0xA451	0xC9F7	#HANGUL SYLLABLE SSANGCIEUC A HIEUH
+0xA452	0xC9FA	#HANGUL SYLLABLE SSANGCIEUC AE SSANGKIYEOK
+0xA453	0xC9FB	#HANGUL SYLLABLE SSANGCIEUC AE KIYEOKSIOS
+0xA454	0xC9FD	#HANGUL SYLLABLE SSANGCIEUC AE NIEUNCIEUC
+0xA455	0xC9FE	#HANGUL SYLLABLE SSANGCIEUC AE NIEUNHIEUH
+0xA456	0xC9FF	#HANGUL SYLLABLE SSANGCIEUC AE TIKEUT
+0xA457	0xCA01	#HANGUL SYLLABLE SSANGCIEUC AE RIEULKIYEOK
+0xA458	0xCA02	#HANGUL SYLLABLE SSANGCIEUC AE RIEULMIEUM
+0xA459	0xCA03	#HANGUL SYLLABLE SSANGCIEUC AE RIEULPIEUP
+0xA45A	0xCA04	#HANGUL SYLLABLE SSANGCIEUC AE RIEULSIOS
+0xA461	0xCA05	#HANGUL SYLLABLE SSANGCIEUC AE RIEULTHIEUTH
+0xA462	0xCA06	#HANGUL SYLLABLE SSANGCIEUC AE RIEULPHIEUPH
+0xA463	0xCA07	#HANGUL SYLLABLE SSANGCIEUC AE RIEULHIEUH
+0xA464	0xCA0A	#HANGUL SYLLABLE SSANGCIEUC AE PIEUPSIOS
+0xA465	0xCA0E	#HANGUL SYLLABLE SSANGCIEUC AE CIEUC
+0xA466	0xCA0F	#HANGUL SYLLABLE SSANGCIEUC AE CHIEUCH
+0xA467	0xCA10	#HANGUL SYLLABLE SSANGCIEUC AE KHIEUKH
+0xA468	0xCA11	#HANGUL SYLLABLE SSANGCIEUC AE THIEUTH
+0xA469	0xCA12	#HANGUL SYLLABLE SSANGCIEUC AE PHIEUPH
+0xA46A	0xCA13	#HANGUL SYLLABLE SSANGCIEUC AE HIEUH
+0xA46B	0xCA15	#HANGUL SYLLABLE SSANGCIEUC YA KIYEOK
+0xA46C	0xCA16	#HANGUL SYLLABLE SSANGCIEUC YA SSANGKIYEOK
+0xA46D	0xCA17	#HANGUL SYLLABLE SSANGCIEUC YA KIYEOKSIOS
+0xA46E	0xCA19	#HANGUL SYLLABLE SSANGCIEUC YA NIEUNCIEUC
+0xA46F	0xCA1A	#HANGUL SYLLABLE SSANGCIEUC YA NIEUNHIEUH
+0xA470	0xCA1B	#HANGUL SYLLABLE SSANGCIEUC YA TIKEUT
+0xA471	0xCA1C	#HANGUL SYLLABLE SSANGCIEUC YA RIEUL
+0xA472	0xCA1D	#HANGUL SYLLABLE SSANGCIEUC YA RIEULKIYEOK
+0xA473	0xCA1E	#HANGUL SYLLABLE SSANGCIEUC YA RIEULMIEUM
+0xA474	0xCA1F	#HANGUL SYLLABLE SSANGCIEUC YA RIEULPIEUP
+0xA475	0xCA20	#HANGUL SYLLABLE SSANGCIEUC YA RIEULSIOS
+0xA476	0xCA21	#HANGUL SYLLABLE SSANGCIEUC YA RIEULTHIEUTH
+0xA477	0xCA22	#HANGUL SYLLABLE SSANGCIEUC YA RIEULPHIEUPH
+0xA478	0xCA23	#HANGUL SYLLABLE SSANGCIEUC YA RIEULHIEUH
+0xA479	0xCA24	#HANGUL SYLLABLE SSANGCIEUC YA MIEUM
+0xA47A	0xCA25	#HANGUL SYLLABLE SSANGCIEUC YA PIEUP
+0xA481	0xCA26	#HANGUL SYLLABLE SSANGCIEUC YA PIEUPSIOS
+0xA482	0xCA27	#HANGUL SYLLABLE SSANGCIEUC YA SIOS
+0xA483	0xCA28	#HANGUL SYLLABLE SSANGCIEUC YA SSANGSIOS
+0xA484	0xCA2A	#HANGUL SYLLABLE SSANGCIEUC YA CIEUC
+0xA485	0xCA2B	#HANGUL SYLLABLE SSANGCIEUC YA CHIEUCH
+0xA486	0xCA2C	#HANGUL SYLLABLE SSANGCIEUC YA KHIEUKH
+0xA487	0xCA2D	#HANGUL SYLLABLE SSANGCIEUC YA THIEUTH
+0xA488	0xCA2E	#HANGUL SYLLABLE SSANGCIEUC YA PHIEUPH
+0xA489	0xCA2F	#HANGUL SYLLABLE SSANGCIEUC YA HIEUH
+0xA48A	0xCA30	#HANGUL SYLLABLE SSANGCIEUC YAE
+0xA48B	0xCA31	#HANGUL SYLLABLE SSANGCIEUC YAE KIYEOK
+0xA48C	0xCA32	#HANGUL SYLLABLE SSANGCIEUC YAE SSANGKIYEOK
+0xA48D	0xCA33	#HANGUL SYLLABLE SSANGCIEUC YAE KIYEOKSIOS
+0xA48E	0xCA34	#HANGUL SYLLABLE SSANGCIEUC YAE NIEUN
+0xA48F	0xCA35	#HANGUL SYLLABLE SSANGCIEUC YAE NIEUNCIEUC
+0xA490	0xCA36	#HANGUL SYLLABLE SSANGCIEUC YAE NIEUNHIEUH
+0xA491	0xCA37	#HANGUL SYLLABLE SSANGCIEUC YAE TIKEUT
+0xA492	0xCA38	#HANGUL SYLLABLE SSANGCIEUC YAE RIEUL
+0xA493	0xCA39	#HANGUL SYLLABLE SSANGCIEUC YAE RIEULKIYEOK
+0xA494	0xCA3A	#HANGUL SYLLABLE SSANGCIEUC YAE RIEULMIEUM
+0xA495	0xCA3B	#HANGUL SYLLABLE SSANGCIEUC YAE RIEULPIEUP
+0xA496	0xCA3C	#HANGUL SYLLABLE SSANGCIEUC YAE RIEULSIOS
+0xA497	0xCA3D	#HANGUL SYLLABLE SSANGCIEUC YAE RIEULTHIEUTH
+0xA498	0xCA3E	#HANGUL SYLLABLE SSANGCIEUC YAE RIEULPHIEUPH
+0xA499	0xCA3F	#HANGUL SYLLABLE SSANGCIEUC YAE RIEULHIEUH
+0xA49A	0xCA40	#HANGUL SYLLABLE SSANGCIEUC YAE MIEUM
+0xA49B	0xCA41	#HANGUL SYLLABLE SSANGCIEUC YAE PIEUP
+0xA49C	0xCA42	#HANGUL SYLLABLE SSANGCIEUC YAE PIEUPSIOS
+0xA49D	0xCA43	#HANGUL SYLLABLE SSANGCIEUC YAE SIOS
+0xA49E	0xCA44	#HANGUL SYLLABLE SSANGCIEUC YAE SSANGSIOS
+0xA49F	0xCA45	#HANGUL SYLLABLE SSANGCIEUC YAE IEUNG
+0xA4A0	0xCA46	#HANGUL SYLLABLE SSANGCIEUC YAE CIEUC
+0xA4A1	0x3131	#HANGUL LETTER KIYEOK
+0xA4A2	0x3132	#HANGUL LETTER SSANGKIYEOK
+0xA4A3	0x3133	#HANGUL LETTER KIYEOK-SIOS
+0xA4A4	0x3134	#HANGUL LETTER NIEUN
+0xA4A5	0x3135	#HANGUL LETTER NIEUN-CIEUC
+0xA4A6	0x3136	#HANGUL LETTER NIEUN-HIEUH
+0xA4A7	0x3137	#HANGUL LETTER TIKEUT
+0xA4A8	0x3138	#HANGUL LETTER SSANGTIKEUT
+0xA4A9	0x3139	#HANGUL LETTER RIEUL
+0xA4AA	0x313A	#HANGUL LETTER RIEUL-KIYEOK
+0xA4AB	0x313B	#HANGUL LETTER RIEUL-MIEUM
+0xA4AC	0x313C	#HANGUL LETTER RIEUL-PIEUP
+0xA4AD	0x313D	#HANGUL LETTER RIEUL-SIOS
+0xA4AE	0x313E	#HANGUL LETTER RIEUL-THIEUTH
+0xA4AF	0x313F	#HANGUL LETTER RIEUL-PHIEUPH
+0xA4B0	0x3140	#HANGUL LETTER RIEUL-HIEUH
+0xA4B1	0x3141	#HANGUL LETTER MIEUM
+0xA4B2	0x3142	#HANGUL LETTER PIEUP
+0xA4B3	0x3143	#HANGUL LETTER SSANGPIEUP
+0xA4B4	0x3144	#HANGUL LETTER PIEUP-SIOS
+0xA4B5	0x3145	#HANGUL LETTER SIOS
+0xA4B6	0x3146	#HANGUL LETTER SSANGSIOS
+0xA4B7	0x3147	#HANGUL LETTER IEUNG
+0xA4B8	0x3148	#HANGUL LETTER CIEUC
+0xA4B9	0x3149	#HANGUL LETTER SSANGCIEUC
+0xA4BA	0x314A	#HANGUL LETTER CHIEUCH
+0xA4BB	0x314B	#HANGUL LETTER KHIEUKH
+0xA4BC	0x314C	#HANGUL LETTER THIEUTH
+0xA4BD	0x314D	#HANGUL LETTER PHIEUPH
+0xA4BE	0x314E	#HANGUL LETTER HIEUH
+0xA4BF	0x314F	#HANGUL LETTER A
+0xA4C0	0x3150	#HANGUL LETTER AE
+0xA4C1	0x3151	#HANGUL LETTER YA
+0xA4C2	0x3152	#HANGUL LETTER YAE
+0xA4C3	0x3153	#HANGUL LETTER EO
+0xA4C4	0x3154	#HANGUL LETTER E
+0xA4C5	0x3155	#HANGUL LETTER YEO
+0xA4C6	0x3156	#HANGUL LETTER YE
+0xA4C7	0x3157	#HANGUL LETTER O
+0xA4C8	0x3158	#HANGUL LETTER WA
+0xA4C9	0x3159	#HANGUL LETTER WAE
+0xA4CA	0x315A	#HANGUL LETTER OE
+0xA4CB	0x315B	#HANGUL LETTER YO
+0xA4CC	0x315C	#HANGUL LETTER U
+0xA4CD	0x315D	#HANGUL LETTER WEO
+0xA4CE	0x315E	#HANGUL LETTER WE
+0xA4CF	0x315F	#HANGUL LETTER WI
+0xA4D0	0x3160	#HANGUL LETTER YU
+0xA4D1	0x3161	#HANGUL LETTER EU
+0xA4D2	0x3162	#HANGUL LETTER YI
+0xA4D3	0x3163	#HANGUL LETTER I
+0xA4D4	0x3164	#HANGUL FILLER
+0xA4D5	0x3165	#HANGUL LETTER SSANGNIEUN
+0xA4D6	0x3166	#HANGUL LETTER NIEUN-TIKEUT
+0xA4D7	0x3167	#HANGUL LETTER NIEUN-SIOS
+0xA4D8	0x3168	#HANGUL LETTER NIEUN-PANSIOS
+0xA4D9	0x3169	#HANGUL LETTER RIEUL-KIYEOK-SIOS
+0xA4DA	0x316A	#HANGUL LETTER RIEUL-TIKEUT
+0xA4DB	0x316B	#HANGUL LETTER RIEUL-PIEUP-SIOS
+0xA4DC	0x316C	#HANGUL LETTER RIEUL-PANSIOS
+0xA4DD	0x316D	#HANGUL LETTER RIEUL-YEORINHIEUH
+0xA4DE	0x316E	#HANGUL LETTER MIEUM-PIEUP
+0xA4DF	0x316F	#HANGUL LETTER MIEUM-SIOS
+0xA4E0	0x3170	#HANGUL LETTER MIEUM-PANSIOS
+0xA4E1	0x3171	#HANGUL LETTER KAPYEOUNMIEUM
+0xA4E2	0x3172	#HANGUL LETTER PIEUP-KIYEOK
+0xA4E3	0x3173	#HANGUL LETTER PIEUP-TIKEUT
+0xA4E4	0x3174	#HANGUL LETTER PIEUP-SIOS-KIYEOK
+0xA4E5	0x3175	#HANGUL LETTER PIEUP-SIOS-TIKEUT
+0xA4E6	0x3176	#HANGUL LETTER PIEUP-CIEUC
+0xA4E7	0x3177	#HANGUL LETTER PIEUP-THIEUTH
+0xA4E8	0x3178	#HANGUL LETTER KAPYEOUNPIEUP
+0xA4E9	0x3179	#HANGUL LETTER KAPYEOUNSSANGPIEUP
+0xA4EA	0x317A	#HANGUL LETTER SIOS-KIYEOK
+0xA4EB	0x317B	#HANGUL LETTER SIOS-NIEUN
+0xA4EC	0x317C	#HANGUL LETTER SIOS-TIKEUT
+0xA4ED	0x317D	#HANGUL LETTER SIOS-PIEUP
+0xA4EE	0x317E	#HANGUL LETTER SIOS-CIEUC
+0xA4EF	0x317F	#HANGUL LETTER PANSIOS
+0xA4F0	0x3180	#HANGUL LETTER SSANGIEUNG
+0xA4F1	0x3181	#HANGUL LETTER YESIEUNG
+0xA4F2	0x3182	#HANGUL LETTER YESIEUNG-SIOS
+0xA4F3	0x3183	#HANGUL LETTER YESIEUNG-PANSIOS
+0xA4F4	0x3184	#HANGUL LETTER KAPYEOUNPHIEUPH
+0xA4F5	0x3185	#HANGUL LETTER SSANGHIEUH
+0xA4F6	0x3186	#HANGUL LETTER YEORINHIEUH
+0xA4F7	0x3187	#HANGUL LETTER YO-YA
+0xA4F8	0x3188	#HANGUL LETTER YO-YAE
+0xA4F9	0x3189	#HANGUL LETTER YO-I
+0xA4FA	0x318A	#HANGUL LETTER YU-YEO
+0xA4FB	0x318B	#HANGUL LETTER YU-YE
+0xA4FC	0x318C	#HANGUL LETTER YU-I
+0xA4FD	0x318D	#HANGUL LETTER ARAEA
+0xA4FE	0x318E	#HANGUL LETTER ARAEAE
+0xA541	0xCA47	#HANGUL SYLLABLE SSANGCIEUC YAE CHIEUCH
+0xA542	0xCA48	#HANGUL SYLLABLE SSANGCIEUC YAE KHIEUKH
+0xA543	0xCA49	#HANGUL SYLLABLE SSANGCIEUC YAE THIEUTH
+0xA544	0xCA4A	#HANGUL SYLLABLE SSANGCIEUC YAE PHIEUPH
+0xA545	0xCA4B	#HANGUL SYLLABLE SSANGCIEUC YAE HIEUH
+0xA546	0xCA4E	#HANGUL SYLLABLE SSANGCIEUC EO SSANGKIYEOK
+0xA547	0xCA4F	#HANGUL SYLLABLE SSANGCIEUC EO KIYEOKSIOS
+0xA548	0xCA51	#HANGUL SYLLABLE SSANGCIEUC EO NIEUNCIEUC
+0xA549	0xCA52	#HANGUL SYLLABLE SSANGCIEUC EO NIEUNHIEUH
+0xA54A	0xCA53	#HANGUL SYLLABLE SSANGCIEUC EO TIKEUT
+0xA54B	0xCA55	#HANGUL SYLLABLE SSANGCIEUC EO RIEULKIYEOK
+0xA54C	0xCA56	#HANGUL SYLLABLE SSANGCIEUC EO RIEULMIEUM
+0xA54D	0xCA57	#HANGUL SYLLABLE SSANGCIEUC EO RIEULPIEUP
+0xA54E	0xCA58	#HANGUL SYLLABLE SSANGCIEUC EO RIEULSIOS
+0xA54F	0xCA59	#HANGUL SYLLABLE SSANGCIEUC EO RIEULTHIEUTH
+0xA550	0xCA5A	#HANGUL SYLLABLE SSANGCIEUC EO RIEULPHIEUPH
+0xA551	0xCA5B	#HANGUL SYLLABLE SSANGCIEUC EO RIEULHIEUH
+0xA552	0xCA5E	#HANGUL SYLLABLE SSANGCIEUC EO PIEUPSIOS
+0xA553	0xCA62	#HANGUL SYLLABLE SSANGCIEUC EO CIEUC
+0xA554	0xCA63	#HANGUL SYLLABLE SSANGCIEUC EO CHIEUCH
+0xA555	0xCA64	#HANGUL SYLLABLE SSANGCIEUC EO KHIEUKH
+0xA556	0xCA65	#HANGUL SYLLABLE SSANGCIEUC EO THIEUTH
+0xA557	0xCA66	#HANGUL SYLLABLE SSANGCIEUC EO PHIEUPH
+0xA558	0xCA67	#HANGUL SYLLABLE SSANGCIEUC EO HIEUH
+0xA559	0xCA69	#HANGUL SYLLABLE SSANGCIEUC E KIYEOK
+0xA55A	0xCA6A	#HANGUL SYLLABLE SSANGCIEUC E SSANGKIYEOK
+0xA561	0xCA6B	#HANGUL SYLLABLE SSANGCIEUC E KIYEOKSIOS
+0xA562	0xCA6C	#HANGUL SYLLABLE SSANGCIEUC E NIEUN
+0xA563	0xCA6D	#HANGUL SYLLABLE SSANGCIEUC E NIEUNCIEUC
+0xA564	0xCA6E	#HANGUL SYLLABLE SSANGCIEUC E NIEUNHIEUH
+0xA565	0xCA6F	#HANGUL SYLLABLE SSANGCIEUC E TIKEUT
+0xA566	0xCA70	#HANGUL SYLLABLE SSANGCIEUC E RIEUL
+0xA567	0xCA71	#HANGUL SYLLABLE SSANGCIEUC E RIEULKIYEOK
+0xA568	0xCA72	#HANGUL SYLLABLE SSANGCIEUC E RIEULMIEUM
+0xA569	0xCA73	#HANGUL SYLLABLE SSANGCIEUC E RIEULPIEUP
+0xA56A	0xCA74	#HANGUL SYLLABLE SSANGCIEUC E RIEULSIOS
+0xA56B	0xCA75	#HANGUL SYLLABLE SSANGCIEUC E RIEULTHIEUTH
+0xA56C	0xCA76	#HANGUL SYLLABLE SSANGCIEUC E RIEULPHIEUPH
+0xA56D	0xCA77	#HANGUL SYLLABLE SSANGCIEUC E RIEULHIEUH
+0xA56E	0xCA78	#HANGUL SYLLABLE SSANGCIEUC E MIEUM
+0xA56F	0xCA79	#HANGUL SYLLABLE SSANGCIEUC E PIEUP
+0xA570	0xCA7A	#HANGUL SYLLABLE SSANGCIEUC E PIEUPSIOS
+0xA571	0xCA7B	#HANGUL SYLLABLE SSANGCIEUC E SIOS
+0xA572	0xCA7C	#HANGUL SYLLABLE SSANGCIEUC E SSANGSIOS
+0xA573	0xCA7E	#HANGUL SYLLABLE SSANGCIEUC E CIEUC
+0xA574	0xCA7F	#HANGUL SYLLABLE SSANGCIEUC E CHIEUCH
+0xA575	0xCA80	#HANGUL SYLLABLE SSANGCIEUC E KHIEUKH
+0xA576	0xCA81	#HANGUL SYLLABLE SSANGCIEUC E THIEUTH
+0xA577	0xCA82	#HANGUL SYLLABLE SSANGCIEUC E PHIEUPH
+0xA578	0xCA83	#HANGUL SYLLABLE SSANGCIEUC E HIEUH
+0xA579	0xCA85	#HANGUL SYLLABLE SSANGCIEUC YEO KIYEOK
+0xA57A	0xCA86	#HANGUL SYLLABLE SSANGCIEUC YEO SSANGKIYEOK
+0xA581	0xCA87	#HANGUL SYLLABLE SSANGCIEUC YEO KIYEOKSIOS
+0xA582	0xCA88	#HANGUL SYLLABLE SSANGCIEUC YEO NIEUN
+0xA583	0xCA89	#HANGUL SYLLABLE SSANGCIEUC YEO NIEUNCIEUC
+0xA584	0xCA8A	#HANGUL SYLLABLE SSANGCIEUC YEO NIEUNHIEUH
+0xA585	0xCA8B	#HANGUL SYLLABLE SSANGCIEUC YEO TIKEUT
+0xA586	0xCA8C	#HANGUL SYLLABLE SSANGCIEUC YEO RIEUL
+0xA587	0xCA8D	#HANGUL SYLLABLE SSANGCIEUC YEO RIEULKIYEOK
+0xA588	0xCA8E	#HANGUL SYLLABLE SSANGCIEUC YEO RIEULMIEUM
+0xA589	0xCA8F	#HANGUL SYLLABLE SSANGCIEUC YEO RIEULPIEUP
+0xA58A	0xCA90	#HANGUL SYLLABLE SSANGCIEUC YEO RIEULSIOS
+0xA58B	0xCA91	#HANGUL SYLLABLE SSANGCIEUC YEO RIEULTHIEUTH
+0xA58C	0xCA92	#HANGUL SYLLABLE SSANGCIEUC YEO RIEULPHIEUPH
+0xA58D	0xCA93	#HANGUL SYLLABLE SSANGCIEUC YEO RIEULHIEUH
+0xA58E	0xCA94	#HANGUL SYLLABLE SSANGCIEUC YEO MIEUM
+0xA58F	0xCA95	#HANGUL SYLLABLE SSANGCIEUC YEO PIEUP
+0xA590	0xCA96	#HANGUL SYLLABLE SSANGCIEUC YEO PIEUPSIOS
+0xA591	0xCA97	#HANGUL SYLLABLE SSANGCIEUC YEO SIOS
+0xA592	0xCA99	#HANGUL SYLLABLE SSANGCIEUC YEO IEUNG
+0xA593	0xCA9A	#HANGUL SYLLABLE SSANGCIEUC YEO CIEUC
+0xA594	0xCA9B	#HANGUL SYLLABLE SSANGCIEUC YEO CHIEUCH
+0xA595	0xCA9C	#HANGUL SYLLABLE SSANGCIEUC YEO KHIEUKH
+0xA596	0xCA9D	#HANGUL SYLLABLE SSANGCIEUC YEO THIEUTH
+0xA597	0xCA9E	#HANGUL SYLLABLE SSANGCIEUC YEO PHIEUPH
+0xA598	0xCA9F	#HANGUL SYLLABLE SSANGCIEUC YEO HIEUH
+0xA599	0xCAA0	#HANGUL SYLLABLE SSANGCIEUC YE
+0xA59A	0xCAA1	#HANGUL SYLLABLE SSANGCIEUC YE KIYEOK
+0xA59B	0xCAA2	#HANGUL SYLLABLE SSANGCIEUC YE SSANGKIYEOK
+0xA59C	0xCAA3	#HANGUL SYLLABLE SSANGCIEUC YE KIYEOKSIOS
+0xA59D	0xCAA4	#HANGUL SYLLABLE SSANGCIEUC YE NIEUN
+0xA59E	0xCAA5	#HANGUL SYLLABLE SSANGCIEUC YE NIEUNCIEUC
+0xA59F	0xCAA6	#HANGUL SYLLABLE SSANGCIEUC YE NIEUNHIEUH
+0xA5A0	0xCAA7	#HANGUL SYLLABLE SSANGCIEUC YE TIKEUT
+0xA5A1	0x2170	#SMALL ROMAN NUMERAL ONE
+0xA5A2	0x2171	#SMALL ROMAN NUMERAL TWO
+0xA5A3	0x2172	#SMALL ROMAN NUMERAL THREE
+0xA5A4	0x2173	#SMALL ROMAN NUMERAL FOUR
+0xA5A5	0x2174	#SMALL ROMAN NUMERAL FIVE
+0xA5A6	0x2175	#SMALL ROMAN NUMERAL SIX
+0xA5A7	0x2176	#SMALL ROMAN NUMERAL SEVEN
+0xA5A8	0x2177	#SMALL ROMAN NUMERAL EIGHT
+0xA5A9	0x2178	#SMALL ROMAN NUMERAL NINE
+0xA5AA	0x2179	#SMALL ROMAN NUMERAL TEN
+0xA5B0	0x2160	#ROMAN NUMERAL ONE
+0xA5B1	0x2161	#ROMAN NUMERAL TWO
+0xA5B2	0x2162	#ROMAN NUMERAL THREE
+0xA5B3	0x2163	#ROMAN NUMERAL FOUR
+0xA5B4	0x2164	#ROMAN NUMERAL FIVE
+0xA5B5	0x2165	#ROMAN NUMERAL SIX
+0xA5B6	0x2166	#ROMAN NUMERAL SEVEN
+0xA5B7	0x2167	#ROMAN NUMERAL EIGHT
+0xA5B8	0x2168	#ROMAN NUMERAL NINE
+0xA5B9	0x2169	#ROMAN NUMERAL TEN
+0xA5C1	0x0391	#GREEK CAPITAL LETTER ALPHA
+0xA5C2	0x0392	#GREEK CAPITAL LETTER BETA
+0xA5C3	0x0393	#GREEK CAPITAL LETTER GAMMA
+0xA5C4	0x0394	#GREEK CAPITAL LETTER DELTA
+0xA5C5	0x0395	#GREEK CAPITAL LETTER EPSILON
+0xA5C6	0x0396	#GREEK CAPITAL LETTER ZETA
+0xA5C7	0x0397	#GREEK CAPITAL LETTER ETA
+0xA5C8	0x0398	#GREEK CAPITAL LETTER THETA
+0xA5C9	0x0399	#GREEK CAPITAL LETTER IOTA
+0xA5CA	0x039A	#GREEK CAPITAL LETTER KAPPA
+0xA5CB	0x039B	#GREEK CAPITAL LETTER LAMDA
+0xA5CC	0x039C	#GREEK CAPITAL LETTER MU
+0xA5CD	0x039D	#GREEK CAPITAL LETTER NU
+0xA5CE	0x039E	#GREEK CAPITAL LETTER XI
+0xA5CF	0x039F	#GREEK CAPITAL LETTER OMICRON
+0xA5D0	0x03A0	#GREEK CAPITAL LETTER PI
+0xA5D1	0x03A1	#GREEK CAPITAL LETTER RHO
+0xA5D2	0x03A3	#GREEK CAPITAL LETTER SIGMA
+0xA5D3	0x03A4	#GREEK CAPITAL LETTER TAU
+0xA5D4	0x03A5	#GREEK CAPITAL LETTER UPSILON
+0xA5D5	0x03A6	#GREEK CAPITAL LETTER PHI
+0xA5D6	0x03A7	#GREEK CAPITAL LETTER CHI
+0xA5D7	0x03A8	#GREEK CAPITAL LETTER PSI
+0xA5D8	0x03A9	#GREEK CAPITAL LETTER OMEGA
+0xA5E1	0x03B1	#GREEK SMALL LETTER ALPHA
+0xA5E2	0x03B2	#GREEK SMALL LETTER BETA
+0xA5E3	0x03B3	#GREEK SMALL LETTER GAMMA
+0xA5E4	0x03B4	#GREEK SMALL LETTER DELTA
+0xA5E5	0x03B5	#GREEK SMALL LETTER EPSILON
+0xA5E6	0x03B6	#GREEK SMALL LETTER ZETA
+0xA5E7	0x03B7	#GREEK SMALL LETTER ETA
+0xA5E8	0x03B8	#GREEK SMALL LETTER THETA
+0xA5E9	0x03B9	#GREEK SMALL LETTER IOTA
+0xA5EA	0x03BA	#GREEK SMALL LETTER KAPPA
+0xA5EB	0x03BB	#GREEK SMALL LETTER LAMDA
+0xA5EC	0x03BC	#GREEK SMALL LETTER MU
+0xA5ED	0x03BD	#GREEK SMALL LETTER NU
+0xA5EE	0x03BE	#GREEK SMALL LETTER XI
+0xA5EF	0x03BF	#GREEK SMALL LETTER OMICRON
+0xA5F0	0x03C0	#GREEK SMALL LETTER PI
+0xA5F1	0x03C1	#GREEK SMALL LETTER RHO
+0xA5F2	0x03C3	#GREEK SMALL LETTER SIGMA
+0xA5F3	0x03C4	#GREEK SMALL LETTER TAU
+0xA5F4	0x03C5	#GREEK SMALL LETTER UPSILON
+0xA5F5	0x03C6	#GREEK SMALL LETTER PHI
+0xA5F6	0x03C7	#GREEK SMALL LETTER CHI
+0xA5F7	0x03C8	#GREEK SMALL LETTER PSI
+0xA5F8	0x03C9	#GREEK SMALL LETTER OMEGA
+0xA641	0xCAA8	#HANGUL SYLLABLE SSANGCIEUC YE RIEUL
+0xA642	0xCAA9	#HANGUL SYLLABLE SSANGCIEUC YE RIEULKIYEOK
+0xA643	0xCAAA	#HANGUL SYLLABLE SSANGCIEUC YE RIEULMIEUM
+0xA644	0xCAAB	#HANGUL SYLLABLE SSANGCIEUC YE RIEULPIEUP
+0xA645	0xCAAC	#HANGUL SYLLABLE SSANGCIEUC YE RIEULSIOS
+0xA646	0xCAAD	#HANGUL SYLLABLE SSANGCIEUC YE RIEULTHIEUTH
+0xA647	0xCAAE	#HANGUL SYLLABLE SSANGCIEUC YE RIEULPHIEUPH
+0xA648	0xCAAF	#HANGUL SYLLABLE SSANGCIEUC YE RIEULHIEUH
+0xA649	0xCAB0	#HANGUL SYLLABLE SSANGCIEUC YE MIEUM
+0xA64A	0xCAB1	#HANGUL SYLLABLE SSANGCIEUC YE PIEUP
+0xA64B	0xCAB2	#HANGUL SYLLABLE SSANGCIEUC YE PIEUPSIOS
+0xA64C	0xCAB3	#HANGUL SYLLABLE SSANGCIEUC YE SIOS
+0xA64D	0xCAB4	#HANGUL SYLLABLE SSANGCIEUC YE SSANGSIOS
+0xA64E	0xCAB5	#HANGUL SYLLABLE SSANGCIEUC YE IEUNG
+0xA64F	0xCAB6	#HANGUL SYLLABLE SSANGCIEUC YE CIEUC
+0xA650	0xCAB7	#HANGUL SYLLABLE SSANGCIEUC YE CHIEUCH
+0xA651	0xCAB8	#HANGUL SYLLABLE SSANGCIEUC YE KHIEUKH
+0xA652	0xCAB9	#HANGUL SYLLABLE SSANGCIEUC YE THIEUTH
+0xA653	0xCABA	#HANGUL SYLLABLE SSANGCIEUC YE PHIEUPH
+0xA654	0xCABB	#HANGUL SYLLABLE SSANGCIEUC YE HIEUH
+0xA655	0xCABE	#HANGUL SYLLABLE SSANGCIEUC O SSANGKIYEOK
+0xA656	0xCABF	#HANGUL SYLLABLE SSANGCIEUC O KIYEOKSIOS
+0xA657	0xCAC1	#HANGUL SYLLABLE SSANGCIEUC O NIEUNCIEUC
+0xA658	0xCAC2	#HANGUL SYLLABLE SSANGCIEUC O NIEUNHIEUH
+0xA659	0xCAC3	#HANGUL SYLLABLE SSANGCIEUC O TIKEUT
+0xA65A	0xCAC5	#HANGUL SYLLABLE SSANGCIEUC O RIEULKIYEOK
+0xA661	0xCAC6	#HANGUL SYLLABLE SSANGCIEUC O RIEULMIEUM
+0xA662	0xCAC7	#HANGUL SYLLABLE SSANGCIEUC O RIEULPIEUP
+0xA663	0xCAC8	#HANGUL SYLLABLE SSANGCIEUC O RIEULSIOS
+0xA664	0xCAC9	#HANGUL SYLLABLE SSANGCIEUC O RIEULTHIEUTH
+0xA665	0xCACA	#HANGUL SYLLABLE SSANGCIEUC O RIEULPHIEUPH
+0xA666	0xCACB	#HANGUL SYLLABLE SSANGCIEUC O RIEULHIEUH
+0xA667	0xCACE	#HANGUL SYLLABLE SSANGCIEUC O PIEUPSIOS
+0xA668	0xCAD0	#HANGUL SYLLABLE SSANGCIEUC O SSANGSIOS
+0xA669	0xCAD2	#HANGUL SYLLABLE SSANGCIEUC O CIEUC
+0xA66A	0xCAD4	#HANGUL SYLLABLE SSANGCIEUC O KHIEUKH
+0xA66B	0xCAD5	#HANGUL SYLLABLE SSANGCIEUC O THIEUTH
+0xA66C	0xCAD6	#HANGUL SYLLABLE SSANGCIEUC O PHIEUPH
+0xA66D	0xCAD7	#HANGUL SYLLABLE SSANGCIEUC O HIEUH
+0xA66E	0xCADA	#HANGUL SYLLABLE SSANGCIEUC WA SSANGKIYEOK
+0xA66F	0xCADB	#HANGUL SYLLABLE SSANGCIEUC WA KIYEOKSIOS
+0xA670	0xCADC	#HANGUL SYLLABLE SSANGCIEUC WA NIEUN
+0xA671	0xCADD	#HANGUL SYLLABLE SSANGCIEUC WA NIEUNCIEUC
+0xA672	0xCADE	#HANGUL SYLLABLE SSANGCIEUC WA NIEUNHIEUH
+0xA673	0xCADF	#HANGUL SYLLABLE SSANGCIEUC WA TIKEUT
+0xA674	0xCAE1	#HANGUL SYLLABLE SSANGCIEUC WA RIEULKIYEOK
+0xA675	0xCAE2	#HANGUL SYLLABLE SSANGCIEUC WA RIEULMIEUM
+0xA676	0xCAE3	#HANGUL SYLLABLE SSANGCIEUC WA RIEULPIEUP
+0xA677	0xCAE4	#HANGUL SYLLABLE SSANGCIEUC WA RIEULSIOS
+0xA678	0xCAE5	#HANGUL SYLLABLE SSANGCIEUC WA RIEULTHIEUTH
+0xA679	0xCAE6	#HANGUL SYLLABLE SSANGCIEUC WA RIEULPHIEUPH
+0xA67A	0xCAE7	#HANGUL SYLLABLE SSANGCIEUC WA RIEULHIEUH
+0xA681	0xCAE8	#HANGUL SYLLABLE SSANGCIEUC WA MIEUM
+0xA682	0xCAE9	#HANGUL SYLLABLE SSANGCIEUC WA PIEUP
+0xA683	0xCAEA	#HANGUL SYLLABLE SSANGCIEUC WA PIEUPSIOS
+0xA684	0xCAEB	#HANGUL SYLLABLE SSANGCIEUC WA SIOS
+0xA685	0xCAED	#HANGUL SYLLABLE SSANGCIEUC WA IEUNG
+0xA686	0xCAEE	#HANGUL SYLLABLE SSANGCIEUC WA CIEUC
+0xA687	0xCAEF	#HANGUL SYLLABLE SSANGCIEUC WA CHIEUCH
+0xA688	0xCAF0	#HANGUL SYLLABLE SSANGCIEUC WA KHIEUKH
+0xA689	0xCAF1	#HANGUL SYLLABLE SSANGCIEUC WA THIEUTH
+0xA68A	0xCAF2	#HANGUL SYLLABLE SSANGCIEUC WA PHIEUPH
+0xA68B	0xCAF3	#HANGUL SYLLABLE SSANGCIEUC WA HIEUH
+0xA68C	0xCAF5	#HANGUL SYLLABLE SSANGCIEUC WAE KIYEOK
+0xA68D	0xCAF6	#HANGUL SYLLABLE SSANGCIEUC WAE SSANGKIYEOK
+0xA68E	0xCAF7	#HANGUL SYLLABLE SSANGCIEUC WAE KIYEOKSIOS
+0xA68F	0xCAF8	#HANGUL SYLLABLE SSANGCIEUC WAE NIEUN
+0xA690	0xCAF9	#HANGUL SYLLABLE SSANGCIEUC WAE NIEUNCIEUC
+0xA691	0xCAFA	#HANGUL SYLLABLE SSANGCIEUC WAE NIEUNHIEUH
+0xA692	0xCAFB	#HANGUL SYLLABLE SSANGCIEUC WAE TIKEUT
+0xA693	0xCAFC	#HANGUL SYLLABLE SSANGCIEUC WAE RIEUL
+0xA694	0xCAFD	#HANGUL SYLLABLE SSANGCIEUC WAE RIEULKIYEOK
+0xA695	0xCAFE	#HANGUL SYLLABLE SSANGCIEUC WAE RIEULMIEUM
+0xA696	0xCAFF	#HANGUL SYLLABLE SSANGCIEUC WAE RIEULPIEUP
+0xA697	0xCB00	#HANGUL SYLLABLE SSANGCIEUC WAE RIEULSIOS
+0xA698	0xCB01	#HANGUL SYLLABLE SSANGCIEUC WAE RIEULTHIEUTH
+0xA699	0xCB02	#HANGUL SYLLABLE SSANGCIEUC WAE RIEULPHIEUPH
+0xA69A	0xCB03	#HANGUL SYLLABLE SSANGCIEUC WAE RIEULHIEUH
+0xA69B	0xCB04	#HANGUL SYLLABLE SSANGCIEUC WAE MIEUM
+0xA69C	0xCB05	#HANGUL SYLLABLE SSANGCIEUC WAE PIEUP
+0xA69D	0xCB06	#HANGUL SYLLABLE SSANGCIEUC WAE PIEUPSIOS
+0xA69E	0xCB07	#HANGUL SYLLABLE SSANGCIEUC WAE SIOS
+0xA69F	0xCB09	#HANGUL SYLLABLE SSANGCIEUC WAE IEUNG
+0xA6A0	0xCB0A	#HANGUL SYLLABLE SSANGCIEUC WAE CIEUC
+0xA6A1	0x2500	#BOX DRAWINGS LIGHT HORIZONTAL
+0xA6A2	0x2502	#BOX DRAWINGS LIGHT VERTICAL
+0xA6A3	0x250C	#BOX DRAWINGS LIGHT DOWN AND RIGHT
+0xA6A4	0x2510	#BOX DRAWINGS LIGHT DOWN AND LEFT
+0xA6A5	0x2518	#BOX DRAWINGS LIGHT UP AND LEFT
+0xA6A6	0x2514	#BOX DRAWINGS LIGHT UP AND RIGHT
+0xA6A7	0x251C	#BOX DRAWINGS LIGHT VERTICAL AND RIGHT
+0xA6A8	0x252C	#BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
+0xA6A9	0x2524	#BOX DRAWINGS LIGHT VERTICAL AND LEFT
+0xA6AA	0x2534	#BOX DRAWINGS LIGHT UP AND HORIZONTAL
+0xA6AB	0x253C	#BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
+0xA6AC	0x2501	#BOX DRAWINGS HEAVY HORIZONTAL
+0xA6AD	0x2503	#BOX DRAWINGS HEAVY VERTICAL
+0xA6AE	0x250F	#BOX DRAWINGS HEAVY DOWN AND RIGHT
+0xA6AF	0x2513	#BOX DRAWINGS HEAVY DOWN AND LEFT
+0xA6B0	0x251B	#BOX DRAWINGS HEAVY UP AND LEFT
+0xA6B1	0x2517	#BOX DRAWINGS HEAVY UP AND RIGHT
+0xA6B2	0x2523	#BOX DRAWINGS HEAVY VERTICAL AND RIGHT
+0xA6B3	0x2533	#BOX DRAWINGS HEAVY DOWN AND HORIZONTAL
+0xA6B4	0x252B	#BOX DRAWINGS HEAVY VERTICAL AND LEFT
+0xA6B5	0x253B	#BOX DRAWINGS HEAVY UP AND HORIZONTAL
+0xA6B6	0x254B	#BOX DRAWINGS HEAVY VERTICAL AND HORIZONTAL
+0xA6B7	0x2520	#BOX DRAWINGS VERTICAL HEAVY AND RIGHT LIGHT
+0xA6B8	0x252F	#BOX DRAWINGS DOWN LIGHT AND HORIZONTAL HEAVY
+0xA6B9	0x2528	#BOX DRAWINGS VERTICAL HEAVY AND LEFT LIGHT
+0xA6BA	0x2537	#BOX DRAWINGS UP LIGHT AND HORIZONTAL HEAVY
+0xA6BB	0x253F	#BOX DRAWINGS VERTICAL LIGHT AND HORIZONTAL HEAVY
+0xA6BC	0x251D	#BOX DRAWINGS VERTICAL LIGHT AND RIGHT HEAVY
+0xA6BD	0x2530	#BOX DRAWINGS DOWN HEAVY AND HORIZONTAL LIGHT
+0xA6BE	0x2525	#BOX DRAWINGS VERTICAL LIGHT AND LEFT HEAVY
+0xA6BF	0x2538	#BOX DRAWINGS UP HEAVY AND HORIZONTAL LIGHT
+0xA6C0	0x2542	#BOX DRAWINGS VERTICAL HEAVY AND HORIZONTAL LIGHT
+0xA6C1	0x2512	#BOX DRAWINGS DOWN HEAVY AND LEFT LIGHT
+0xA6C2	0x2511	#BOX DRAWINGS DOWN LIGHT AND LEFT HEAVY
+0xA6C3	0x251A	#BOX DRAWINGS UP HEAVY AND LEFT LIGHT
+0xA6C4	0x2519	#BOX DRAWINGS UP LIGHT AND LEFT HEAVY
+0xA6C5	0x2516	#BOX DRAWINGS UP HEAVY AND RIGHT LIGHT
+0xA6C6	0x2515	#BOX DRAWINGS UP LIGHT AND RIGHT HEAVY
+0xA6C7	0x250E	#BOX DRAWINGS DOWN HEAVY AND RIGHT LIGHT
+0xA6C8	0x250D	#BOX DRAWINGS DOWN LIGHT AND RIGHT HEAVY
+0xA6C9	0x251E	#BOX DRAWINGS UP HEAVY AND RIGHT DOWN LIGHT
+0xA6CA	0x251F	#BOX DRAWINGS DOWN HEAVY AND RIGHT UP LIGHT
+0xA6CB	0x2521	#BOX DRAWINGS DOWN LIGHT AND RIGHT UP HEAVY
+0xA6CC	0x2522	#BOX DRAWINGS UP LIGHT AND RIGHT DOWN HEAVY
+0xA6CD	0x2526	#BOX DRAWINGS UP HEAVY AND LEFT DOWN LIGHT
+0xA6CE	0x2527	#BOX DRAWINGS DOWN HEAVY AND LEFT UP LIGHT
+0xA6CF	0x2529	#BOX DRAWINGS DOWN LIGHT AND LEFT UP HEAVY
+0xA6D0	0x252A	#BOX DRAWINGS UP LIGHT AND LEFT DOWN HEAVY
+0xA6D1	0x252D	#BOX DRAWINGS LEFT HEAVY AND RIGHT DOWN LIGHT
+0xA6D2	0x252E	#BOX DRAWINGS RIGHT HEAVY AND LEFT DOWN LIGHT
+0xA6D3	0x2531	#BOX DRAWINGS RIGHT LIGHT AND LEFT DOWN HEAVY
+0xA6D4	0x2532	#BOX DRAWINGS LEFT LIGHT AND RIGHT DOWN HEAVY
+0xA6D5	0x2535	#BOX DRAWINGS LEFT HEAVY AND RIGHT UP LIGHT
+0xA6D6	0x2536	#BOX DRAWINGS RIGHT HEAVY AND LEFT UP LIGHT
+0xA6D7	0x2539	#BOX DRAWINGS RIGHT LIGHT AND LEFT UP HEAVY
+0xA6D8	0x253A	#BOX DRAWINGS LEFT LIGHT AND RIGHT UP HEAVY
+0xA6D9	0x253D	#BOX DRAWINGS LEFT HEAVY AND RIGHT VERTICAL LIGHT
+0xA6DA	0x253E	#BOX DRAWINGS RIGHT HEAVY AND LEFT VERTICAL LIGHT
+0xA6DB	0x2540	#BOX DRAWINGS UP HEAVY AND DOWN HORIZONTAL LIGHT
+0xA6DC	0x2541	#BOX DRAWINGS DOWN HEAVY AND UP HORIZONTAL LIGHT
+0xA6DD	0x2543	#BOX DRAWINGS LEFT UP HEAVY AND RIGHT DOWN LIGHT
+0xA6DE	0x2544	#BOX DRAWINGS RIGHT UP HEAVY AND LEFT DOWN LIGHT
+0xA6DF	0x2545	#BOX DRAWINGS LEFT DOWN HEAVY AND RIGHT UP LIGHT
+0xA6E0	0x2546	#BOX DRAWINGS RIGHT DOWN HEAVY AND LEFT UP LIGHT
+0xA6E1	0x2547	#BOX DRAWINGS DOWN LIGHT AND UP HORIZONTAL HEAVY
+0xA6E2	0x2548	#BOX DRAWINGS UP LIGHT AND DOWN HORIZONTAL HEAVY
+0xA6E3	0x2549	#BOX DRAWINGS RIGHT LIGHT AND LEFT VERTICAL HEAVY
+0xA6E4	0x254A	#BOX DRAWINGS LEFT LIGHT AND RIGHT VERTICAL HEAVY
+0xA741	0xCB0B	#HANGUL SYLLABLE SSANGCIEUC WAE CHIEUCH
+0xA742	0xCB0C	#HANGUL SYLLABLE SSANGCIEUC WAE KHIEUKH
+0xA743	0xCB0D	#HANGUL SYLLABLE SSANGCIEUC WAE THIEUTH
+0xA744	0xCB0E	#HANGUL SYLLABLE SSANGCIEUC WAE PHIEUPH
+0xA745	0xCB0F	#HANGUL SYLLABLE SSANGCIEUC WAE HIEUH
+0xA746	0xCB11	#HANGUL SYLLABLE SSANGCIEUC OE KIYEOK
+0xA747	0xCB12	#HANGUL SYLLABLE SSANGCIEUC OE SSANGKIYEOK
+0xA748	0xCB13	#HANGUL SYLLABLE SSANGCIEUC OE KIYEOKSIOS
+0xA749	0xCB15	#HANGUL SYLLABLE SSANGCIEUC OE NIEUNCIEUC
+0xA74A	0xCB16	#HANGUL SYLLABLE SSANGCIEUC OE NIEUNHIEUH
+0xA74B	0xCB17	#HANGUL SYLLABLE SSANGCIEUC OE TIKEUT
+0xA74C	0xCB19	#HANGUL SYLLABLE SSANGCIEUC OE RIEULKIYEOK
+0xA74D	0xCB1A	#HANGUL SYLLABLE SSANGCIEUC OE RIEULMIEUM
+0xA74E	0xCB1B	#HANGUL SYLLABLE SSANGCIEUC OE RIEULPIEUP
+0xA74F	0xCB1C	#HANGUL SYLLABLE SSANGCIEUC OE RIEULSIOS
+0xA750	0xCB1D	#HANGUL SYLLABLE SSANGCIEUC OE RIEULTHIEUTH
+0xA751	0xCB1E	#HANGUL SYLLABLE SSANGCIEUC OE RIEULPHIEUPH
+0xA752	0xCB1F	#HANGUL SYLLABLE SSANGCIEUC OE RIEULHIEUH
+0xA753	0xCB22	#HANGUL SYLLABLE SSANGCIEUC OE PIEUPSIOS
+0xA754	0xCB23	#HANGUL SYLLABLE SSANGCIEUC OE SIOS
+0xA755	0xCB24	#HANGUL SYLLABLE SSANGCIEUC OE SSANGSIOS
+0xA756	0xCB25	#HANGUL SYLLABLE SSANGCIEUC OE IEUNG
+0xA757	0xCB26	#HANGUL SYLLABLE SSANGCIEUC OE CIEUC
+0xA758	0xCB27	#HANGUL SYLLABLE SSANGCIEUC OE CHIEUCH
+0xA759	0xCB28	#HANGUL SYLLABLE SSANGCIEUC OE KHIEUKH
+0xA75A	0xCB29	#HANGUL SYLLABLE SSANGCIEUC OE THIEUTH
+0xA761	0xCB2A	#HANGUL SYLLABLE SSANGCIEUC OE PHIEUPH
+0xA762	0xCB2B	#HANGUL SYLLABLE SSANGCIEUC OE HIEUH
+0xA763	0xCB2C	#HANGUL SYLLABLE SSANGCIEUC YO
+0xA764	0xCB2D	#HANGUL SYLLABLE SSANGCIEUC YO KIYEOK
+0xA765	0xCB2E	#HANGUL SYLLABLE SSANGCIEUC YO SSANGKIYEOK
+0xA766	0xCB2F	#HANGUL SYLLABLE SSANGCIEUC YO KIYEOKSIOS
+0xA767	0xCB30	#HANGUL SYLLABLE SSANGCIEUC YO NIEUN
+0xA768	0xCB31	#HANGUL SYLLABLE SSANGCIEUC YO NIEUNCIEUC
+0xA769	0xCB32	#HANGUL SYLLABLE SSANGCIEUC YO NIEUNHIEUH
+0xA76A	0xCB33	#HANGUL SYLLABLE SSANGCIEUC YO TIKEUT
+0xA76B	0xCB34	#HANGUL SYLLABLE SSANGCIEUC YO RIEUL
+0xA76C	0xCB35	#HANGUL SYLLABLE SSANGCIEUC YO RIEULKIYEOK
+0xA76D	0xCB36	#HANGUL SYLLABLE SSANGCIEUC YO RIEULMIEUM
+0xA76E	0xCB37	#HANGUL SYLLABLE SSANGCIEUC YO RIEULPIEUP
+0xA76F	0xCB38	#HANGUL SYLLABLE SSANGCIEUC YO RIEULSIOS
+0xA770	0xCB39	#HANGUL SYLLABLE SSANGCIEUC YO RIEULTHIEUTH
+0xA771	0xCB3A	#HANGUL SYLLABLE SSANGCIEUC YO RIEULPHIEUPH
+0xA772	0xCB3B	#HANGUL SYLLABLE SSANGCIEUC YO RIEULHIEUH
+0xA773	0xCB3C	#HANGUL SYLLABLE SSANGCIEUC YO MIEUM
+0xA774	0xCB3D	#HANGUL SYLLABLE SSANGCIEUC YO PIEUP
+0xA775	0xCB3E	#HANGUL SYLLABLE SSANGCIEUC YO PIEUPSIOS
+0xA776	0xCB3F	#HANGUL SYLLABLE SSANGCIEUC YO SIOS
+0xA777	0xCB40	#HANGUL SYLLABLE SSANGCIEUC YO SSANGSIOS
+0xA778	0xCB42	#HANGUL SYLLABLE SSANGCIEUC YO CIEUC
+0xA779	0xCB43	#HANGUL SYLLABLE SSANGCIEUC YO CHIEUCH
+0xA77A	0xCB44	#HANGUL SYLLABLE SSANGCIEUC YO KHIEUKH
+0xA781	0xCB45	#HANGUL SYLLABLE SSANGCIEUC YO THIEUTH
+0xA782	0xCB46	#HANGUL SYLLABLE SSANGCIEUC YO PHIEUPH
+0xA783	0xCB47	#HANGUL SYLLABLE SSANGCIEUC YO HIEUH
+0xA784	0xCB4A	#HANGUL SYLLABLE SSANGCIEUC U SSANGKIYEOK
+0xA785	0xCB4B	#HANGUL SYLLABLE SSANGCIEUC U KIYEOKSIOS
+0xA786	0xCB4D	#HANGUL SYLLABLE SSANGCIEUC U NIEUNCIEUC
+0xA787	0xCB4E	#HANGUL SYLLABLE SSANGCIEUC U NIEUNHIEUH
+0xA788	0xCB4F	#HANGUL SYLLABLE SSANGCIEUC U TIKEUT
+0xA789	0xCB51	#HANGUL SYLLABLE SSANGCIEUC U RIEULKIYEOK
+0xA78A	0xCB52	#HANGUL SYLLABLE SSANGCIEUC U RIEULMIEUM
+0xA78B	0xCB53	#HANGUL SYLLABLE SSANGCIEUC U RIEULPIEUP
+0xA78C	0xCB54	#HANGUL SYLLABLE SSANGCIEUC U RIEULSIOS
+0xA78D	0xCB55	#HANGUL SYLLABLE SSANGCIEUC U RIEULTHIEUTH
+0xA78E	0xCB56	#HANGUL SYLLABLE SSANGCIEUC U RIEULPHIEUPH
+0xA78F	0xCB57	#HANGUL SYLLABLE SSANGCIEUC U RIEULHIEUH
+0xA790	0xCB5A	#HANGUL SYLLABLE SSANGCIEUC U PIEUPSIOS
+0xA791	0xCB5B	#HANGUL SYLLABLE SSANGCIEUC U SIOS
+0xA792	0xCB5C	#HANGUL SYLLABLE SSANGCIEUC U SSANGSIOS
+0xA793	0xCB5E	#HANGUL SYLLABLE SSANGCIEUC U CIEUC
+0xA794	0xCB5F	#HANGUL SYLLABLE SSANGCIEUC U CHIEUCH
+0xA795	0xCB60	#HANGUL SYLLABLE SSANGCIEUC U KHIEUKH
+0xA796	0xCB61	#HANGUL SYLLABLE SSANGCIEUC U THIEUTH
+0xA797	0xCB62	#HANGUL SYLLABLE SSANGCIEUC U PHIEUPH
+0xA798	0xCB63	#HANGUL SYLLABLE SSANGCIEUC U HIEUH
+0xA799	0xCB65	#HANGUL SYLLABLE SSANGCIEUC WEO KIYEOK
+0xA79A	0xCB66	#HANGUL SYLLABLE SSANGCIEUC WEO SSANGKIYEOK
+0xA79B	0xCB67	#HANGUL SYLLABLE SSANGCIEUC WEO KIYEOKSIOS
+0xA79C	0xCB68	#HANGUL SYLLABLE SSANGCIEUC WEO NIEUN
+0xA79D	0xCB69	#HANGUL SYLLABLE SSANGCIEUC WEO NIEUNCIEUC
+0xA79E	0xCB6A	#HANGUL SYLLABLE SSANGCIEUC WEO NIEUNHIEUH
+0xA79F	0xCB6B	#HANGUL SYLLABLE SSANGCIEUC WEO TIKEUT
+0xA7A0	0xCB6C	#HANGUL SYLLABLE SSANGCIEUC WEO RIEUL
+0xA7A1	0x3395	#SQUARE MU L
+0xA7A2	0x3396	#SQUARE ML
+0xA7A3	0x3397	#SQUARE DL
+0xA7A4	0x2113	#SCRIPT SMALL L
+0xA7A5	0x3398	#SQUARE KL
+0xA7A6	0x33C4	#SQUARE CC
+0xA7A7	0x33A3	#SQUARE MM CUBED
+0xA7A8	0x33A4	#SQUARE CM CUBED
+0xA7A9	0x33A5	#SQUARE M CUBED
+0xA7AA	0x33A6	#SQUARE KM CUBED
+0xA7AB	0x3399	#SQUARE FM
+0xA7AC	0x339A	#SQUARE NM
+0xA7AD	0x339B	#SQUARE MU M
+0xA7AE	0x339C	#SQUARE MM
+0xA7AF	0x339D	#SQUARE CM
+0xA7B0	0x339E	#SQUARE KM
+0xA7B1	0x339F	#SQUARE MM SQUARED
+0xA7B2	0x33A0	#SQUARE CM SQUARED
+0xA7B3	0x33A1	#SQUARE M SQUARED
+0xA7B4	0x33A2	#SQUARE KM SQUARED
+0xA7B5	0x33CA	#SQUARE HA
+0xA7B6	0x338D	#SQUARE MU G
+0xA7B7	0x338E	#SQUARE MG
+0xA7B8	0x338F	#SQUARE KG
+0xA7B9	0x33CF	#SQUARE KT
+0xA7BA	0x3388	#SQUARE CAL
+0xA7BB	0x3389	#SQUARE KCAL
+0xA7BC	0x33C8	#SQUARE DB
+0xA7BD	0x33A7	#SQUARE M OVER S
+0xA7BE	0x33A8	#SQUARE M OVER S SQUARED
+0xA7BF	0x33B0	#SQUARE PS
+0xA7C0	0x33B1	#SQUARE NS
+0xA7C1	0x33B2	#SQUARE MU S
+0xA7C2	0x33B3	#SQUARE MS
+0xA7C3	0x33B4	#SQUARE PV
+0xA7C4	0x33B5	#SQUARE NV
+0xA7C5	0x33B6	#SQUARE MU V
+0xA7C6	0x33B7	#SQUARE MV
+0xA7C7	0x33B8	#SQUARE KV
+0xA7C8	0x33B9	#SQUARE MV MEGA
+0xA7C9	0x3380	#SQUARE PA AMPS
+0xA7CA	0x3381	#SQUARE NA
+0xA7CB	0x3382	#SQUARE MU A
+0xA7CC	0x3383	#SQUARE MA
+0xA7CD	0x3384	#SQUARE KA
+0xA7CE	0x33BA	#SQUARE PW
+0xA7CF	0x33BB	#SQUARE NW
+0xA7D0	0x33BC	#SQUARE MU W
+0xA7D1	0x33BD	#SQUARE MW
+0xA7D2	0x33BE	#SQUARE KW
+0xA7D3	0x33BF	#SQUARE MW MEGA
+0xA7D4	0x3390	#SQUARE HZ
+0xA7D5	0x3391	#SQUARE KHZ
+0xA7D6	0x3392	#SQUARE MHZ
+0xA7D7	0x3393	#SQUARE GHZ
+0xA7D8	0x3394	#SQUARE THZ
+0xA7D9	0x2126	#OHM SIGN
+0xA7DA	0x33C0	#SQUARE K OHM
+0xA7DB	0x33C1	#SQUARE M OHM
+0xA7DC	0x338A	#SQUARE PF
+0xA7DD	0x338B	#SQUARE NF
+0xA7DE	0x338C	#SQUARE MU F
+0xA7DF	0x33D6	#SQUARE MOL
+0xA7E0	0x33C5	#SQUARE CD
+0xA7E1	0x33AD	#SQUARE RAD
+0xA7E2	0x33AE	#SQUARE RAD OVER S
+0xA7E3	0x33AF	#SQUARE RAD OVER S SQUARED
+0xA7E4	0x33DB	#SQUARE SR
+0xA7E5	0x33A9	#SQUARE PA
+0xA7E6	0x33AA	#SQUARE KPA
+0xA7E7	0x33AB	#SQUARE MPA
+0xA7E8	0x33AC	#SQUARE GPA
+0xA7E9	0x33DD	#SQUARE WB
+0xA7EA	0x33D0	#SQUARE LM
+0xA7EB	0x33D3	#SQUARE LX
+0xA7EC	0x33C3	#SQUARE BQ
+0xA7ED	0x33C9	#SQUARE GY
+0xA7EE	0x33DC	#SQUARE SV
+0xA7EF	0x33C6	#SQUARE C OVER KG
+0xA841	0xCB6D	#HANGUL SYLLABLE SSANGCIEUC WEO RIEULKIYEOK
+0xA842	0xCB6E	#HANGUL SYLLABLE SSANGCIEUC WEO RIEULMIEUM
+0xA843	0xCB6F	#HANGUL SYLLABLE SSANGCIEUC WEO RIEULPIEUP
+0xA844	0xCB70	#HANGUL SYLLABLE SSANGCIEUC WEO RIEULSIOS
+0xA845	0xCB71	#HANGUL SYLLABLE SSANGCIEUC WEO RIEULTHIEUTH
+0xA846	0xCB72	#HANGUL SYLLABLE SSANGCIEUC WEO RIEULPHIEUPH
+0xA847	0xCB73	#HANGUL SYLLABLE SSANGCIEUC WEO RIEULHIEUH
+0xA848	0xCB74	#HANGUL SYLLABLE SSANGCIEUC WEO MIEUM
+0xA849	0xCB75	#HANGUL SYLLABLE SSANGCIEUC WEO PIEUP
+0xA84A	0xCB76	#HANGUL SYLLABLE SSANGCIEUC WEO PIEUPSIOS
+0xA84B	0xCB77	#HANGUL SYLLABLE SSANGCIEUC WEO SIOS
+0xA84C	0xCB7A	#HANGUL SYLLABLE SSANGCIEUC WEO CIEUC
+0xA84D	0xCB7B	#HANGUL SYLLABLE SSANGCIEUC WEO CHIEUCH
+0xA84E	0xCB7C	#HANGUL SYLLABLE SSANGCIEUC WEO KHIEUKH
+0xA84F	0xCB7D	#HANGUL SYLLABLE SSANGCIEUC WEO THIEUTH
+0xA850	0xCB7E	#HANGUL SYLLABLE SSANGCIEUC WEO PHIEUPH
+0xA851	0xCB7F	#HANGUL SYLLABLE SSANGCIEUC WEO HIEUH
+0xA852	0xCB80	#HANGUL SYLLABLE SSANGCIEUC WE
+0xA853	0xCB81	#HANGUL SYLLABLE SSANGCIEUC WE KIYEOK
+0xA854	0xCB82	#HANGUL SYLLABLE SSANGCIEUC WE SSANGKIYEOK
+0xA855	0xCB83	#HANGUL SYLLABLE SSANGCIEUC WE KIYEOKSIOS
+0xA856	0xCB84	#HANGUL SYLLABLE SSANGCIEUC WE NIEUN
+0xA857	0xCB85	#HANGUL SYLLABLE SSANGCIEUC WE NIEUNCIEUC
+0xA858	0xCB86	#HANGUL SYLLABLE SSANGCIEUC WE NIEUNHIEUH
+0xA859	0xCB87	#HANGUL SYLLABLE SSANGCIEUC WE TIKEUT
+0xA85A	0xCB88	#HANGUL SYLLABLE SSANGCIEUC WE RIEUL
+0xA861	0xCB89	#HANGUL SYLLABLE SSANGCIEUC WE RIEULKIYEOK
+0xA862	0xCB8A	#HANGUL SYLLABLE SSANGCIEUC WE RIEULMIEUM
+0xA863	0xCB8B	#HANGUL SYLLABLE SSANGCIEUC WE RIEULPIEUP
+0xA864	0xCB8C	#HANGUL SYLLABLE SSANGCIEUC WE RIEULSIOS
+0xA865	0xCB8D	#HANGUL SYLLABLE SSANGCIEUC WE RIEULTHIEUTH
+0xA866	0xCB8E	#HANGUL SYLLABLE SSANGCIEUC WE RIEULPHIEUPH
+0xA867	0xCB8F	#HANGUL SYLLABLE SSANGCIEUC WE RIEULHIEUH
+0xA868	0xCB90	#HANGUL SYLLABLE SSANGCIEUC WE MIEUM
+0xA869	0xCB91	#HANGUL SYLLABLE SSANGCIEUC WE PIEUP
+0xA86A	0xCB92	#HANGUL SYLLABLE SSANGCIEUC WE PIEUPSIOS
+0xA86B	0xCB93	#HANGUL SYLLABLE SSANGCIEUC WE SIOS
+0xA86C	0xCB94	#HANGUL SYLLABLE SSANGCIEUC WE SSANGSIOS
+0xA86D	0xCB95	#HANGUL SYLLABLE SSANGCIEUC WE IEUNG
+0xA86E	0xCB96	#HANGUL SYLLABLE SSANGCIEUC WE CIEUC
+0xA86F	0xCB97	#HANGUL SYLLABLE SSANGCIEUC WE CHIEUCH
+0xA870	0xCB98	#HANGUL SYLLABLE SSANGCIEUC WE KHIEUKH
+0xA871	0xCB99	#HANGUL SYLLABLE SSANGCIEUC WE THIEUTH
+0xA872	0xCB9A	#HANGUL SYLLABLE SSANGCIEUC WE PHIEUPH
+0xA873	0xCB9B	#HANGUL SYLLABLE SSANGCIEUC WE HIEUH
+0xA874	0xCB9D	#HANGUL SYLLABLE SSANGCIEUC WI KIYEOK
+0xA875	0xCB9E	#HANGUL SYLLABLE SSANGCIEUC WI SSANGKIYEOK
+0xA876	0xCB9F	#HANGUL SYLLABLE SSANGCIEUC WI KIYEOKSIOS
+0xA877	0xCBA0	#HANGUL SYLLABLE SSANGCIEUC WI NIEUN
+0xA878	0xCBA1	#HANGUL SYLLABLE SSANGCIEUC WI NIEUNCIEUC
+0xA879	0xCBA2	#HANGUL SYLLABLE SSANGCIEUC WI NIEUNHIEUH
+0xA87A	0xCBA3	#HANGUL SYLLABLE SSANGCIEUC WI TIKEUT
+0xA881	0xCBA4	#HANGUL SYLLABLE SSANGCIEUC WI RIEUL
+0xA882	0xCBA5	#HANGUL SYLLABLE SSANGCIEUC WI RIEULKIYEOK
+0xA883	0xCBA6	#HANGUL SYLLABLE SSANGCIEUC WI RIEULMIEUM
+0xA884	0xCBA7	#HANGUL SYLLABLE SSANGCIEUC WI RIEULPIEUP
+0xA885	0xCBA8	#HANGUL SYLLABLE SSANGCIEUC WI RIEULSIOS
+0xA886	0xCBA9	#HANGUL SYLLABLE SSANGCIEUC WI RIEULTHIEUTH
+0xA887	0xCBAA	#HANGUL SYLLABLE SSANGCIEUC WI RIEULPHIEUPH
+0xA888	0xCBAB	#HANGUL SYLLABLE SSANGCIEUC WI RIEULHIEUH
+0xA889	0xCBAC	#HANGUL SYLLABLE SSANGCIEUC WI MIEUM
+0xA88A	0xCBAD	#HANGUL SYLLABLE SSANGCIEUC WI PIEUP
+0xA88B	0xCBAE	#HANGUL SYLLABLE SSANGCIEUC WI PIEUPSIOS
+0xA88C	0xCBAF	#HANGUL SYLLABLE SSANGCIEUC WI SIOS
+0xA88D	0xCBB0	#HANGUL SYLLABLE SSANGCIEUC WI SSANGSIOS
+0xA88E	0xCBB1	#HANGUL SYLLABLE SSANGCIEUC WI IEUNG
+0xA88F	0xCBB2	#HANGUL SYLLABLE SSANGCIEUC WI CIEUC
+0xA890	0xCBB3	#HANGUL SYLLABLE SSANGCIEUC WI CHIEUCH
+0xA891	0xCBB4	#HANGUL SYLLABLE SSANGCIEUC WI KHIEUKH
+0xA892	0xCBB5	#HANGUL SYLLABLE SSANGCIEUC WI THIEUTH
+0xA893	0xCBB6	#HANGUL SYLLABLE SSANGCIEUC WI PHIEUPH
+0xA894	0xCBB7	#HANGUL SYLLABLE SSANGCIEUC WI HIEUH
+0xA895	0xCBB9	#HANGUL SYLLABLE SSANGCIEUC YU KIYEOK
+0xA896	0xCBBA	#HANGUL SYLLABLE SSANGCIEUC YU SSANGKIYEOK
+0xA897	0xCBBB	#HANGUL SYLLABLE SSANGCIEUC YU KIYEOKSIOS
+0xA898	0xCBBC	#HANGUL SYLLABLE SSANGCIEUC YU NIEUN
+0xA899	0xCBBD	#HANGUL SYLLABLE SSANGCIEUC YU NIEUNCIEUC
+0xA89A	0xCBBE	#HANGUL SYLLABLE SSANGCIEUC YU NIEUNHIEUH
+0xA89B	0xCBBF	#HANGUL SYLLABLE SSANGCIEUC YU TIKEUT
+0xA89C	0xCBC0	#HANGUL SYLLABLE SSANGCIEUC YU RIEUL
+0xA89D	0xCBC1	#HANGUL SYLLABLE SSANGCIEUC YU RIEULKIYEOK
+0xA89E	0xCBC2	#HANGUL SYLLABLE SSANGCIEUC YU RIEULMIEUM
+0xA89F	0xCBC3	#HANGUL SYLLABLE SSANGCIEUC YU RIEULPIEUP
+0xA8A0	0xCBC4	#HANGUL SYLLABLE SSANGCIEUC YU RIEULSIOS
+0xA8A1	0x00C6	#LATIN CAPITAL LETTER AE
+0xA8A2	0x00D0	#LATIN CAPITAL LETTER ETH
+0xA8A3	0x00AA	#FEMININE ORDINAL INDICATOR
+0xA8A4	0x0126	#LATIN CAPITAL LETTER H WITH STROKE
+0xA8A6	0x0132	#LATIN CAPITAL LIGATURE IJ
+0xA8A8	0x013F	#LATIN CAPITAL LETTER L WITH MIDDLE DOT
+0xA8A9	0x0141	#LATIN CAPITAL LETTER L WITH STROKE
+0xA8AA	0x00D8	#LATIN CAPITAL LETTER O WITH STROKE
+0xA8AB	0x0152	#LATIN CAPITAL LIGATURE OE
+0xA8AC	0x00BA	#MASCULINE ORDINAL INDICATOR
+0xA8AD	0x00DE	#LATIN CAPITAL LETTER THORN
+0xA8AE	0x0166	#LATIN CAPITAL LETTER T WITH STROKE
+0xA8AF	0x014A	#LATIN CAPITAL LETTER ENG
+0xA8B1	0x3260	#CIRCLED HANGUL KIYEOK
+0xA8B2	0x3261	#CIRCLED HANGUL NIEUN
+0xA8B3	0x3262	#CIRCLED HANGUL TIKEUT
+0xA8B4	0x3263	#CIRCLED HANGUL RIEUL
+0xA8B5	0x3264	#CIRCLED HANGUL MIEUM
+0xA8B6	0x3265	#CIRCLED HANGUL PIEUP
+0xA8B7	0x3266	#CIRCLED HANGUL SIOS
+0xA8B8	0x3267	#CIRCLED HANGUL IEUNG
+0xA8B9	0x3268	#CIRCLED HANGUL CIEUC
+0xA8BA	0x3269	#CIRCLED HANGUL CHIEUCH
+0xA8BB	0x326A	#CIRCLED HANGUL KHIEUKH
+0xA8BC	0x326B	#CIRCLED HANGUL THIEUTH
+0xA8BD	0x326C	#CIRCLED HANGUL PHIEUPH
+0xA8BE	0x326D	#CIRCLED HANGUL HIEUH
+0xA8BF	0x326E	#CIRCLED HANGUL KIYEOK A
+0xA8C0	0x326F	#CIRCLED HANGUL NIEUN A
+0xA8C1	0x3270	#CIRCLED HANGUL TIKEUT A
+0xA8C2	0x3271	#CIRCLED HANGUL RIEUL A
+0xA8C3	0x3272	#CIRCLED HANGUL MIEUM A
+0xA8C4	0x3273	#CIRCLED HANGUL PIEUP A
+0xA8C5	0x3274	#CIRCLED HANGUL SIOS A
+0xA8C6	0x3275	#CIRCLED HANGUL IEUNG A
+0xA8C7	0x3276	#CIRCLED HANGUL CIEUC A
+0xA8C8	0x3277	#CIRCLED HANGUL CHIEUCH A
+0xA8C9	0x3278	#CIRCLED HANGUL KHIEUKH A
+0xA8CA	0x3279	#CIRCLED HANGUL THIEUTH A
+0xA8CB	0x327A	#CIRCLED HANGUL PHIEUPH A
+0xA8CC	0x327B	#CIRCLED HANGUL HIEUH A
+0xA8CD	0x24D0	#CIRCLED LATIN SMALL LETTER A
+0xA8CE	0x24D1	#CIRCLED LATIN SMALL LETTER B
+0xA8CF	0x24D2	#CIRCLED LATIN SMALL LETTER C
+0xA8D0	0x24D3	#CIRCLED LATIN SMALL LETTER D
+0xA8D1	0x24D4	#CIRCLED LATIN SMALL LETTER E
+0xA8D2	0x24D5	#CIRCLED LATIN SMALL LETTER F
+0xA8D3	0x24D6	#CIRCLED LATIN SMALL LETTER G
+0xA8D4	0x24D7	#CIRCLED LATIN SMALL LETTER H
+0xA8D5	0x24D8	#CIRCLED LATIN SMALL LETTER I
+0xA8D6	0x24D9	#CIRCLED LATIN SMALL LETTER J
+0xA8D7	0x24DA	#CIRCLED LATIN SMALL LETTER K
+0xA8D8	0x24DB	#CIRCLED LATIN SMALL LETTER L
+0xA8D9	0x24DC	#CIRCLED LATIN SMALL LETTER M
+0xA8DA	0x24DD	#CIRCLED LATIN SMALL LETTER N
+0xA8DB	0x24DE	#CIRCLED LATIN SMALL LETTER O
+0xA8DC	0x24DF	#CIRCLED LATIN SMALL LETTER P
+0xA8DD	0x24E0	#CIRCLED LATIN SMALL LETTER Q
+0xA8DE	0x24E1	#CIRCLED LATIN SMALL LETTER R
+0xA8DF	0x24E2	#CIRCLED LATIN SMALL LETTER S
+0xA8E0	0x24E3	#CIRCLED LATIN SMALL LETTER T
+0xA8E1	0x24E4	#CIRCLED LATIN SMALL LETTER U
+0xA8E2	0x24E5	#CIRCLED LATIN SMALL LETTER V
+0xA8E3	0x24E6	#CIRCLED LATIN SMALL LETTER W
+0xA8E4	0x24E7	#CIRCLED LATIN SMALL LETTER X
+0xA8E5	0x24E8	#CIRCLED LATIN SMALL LETTER Y
+0xA8E6	0x24E9	#CIRCLED LATIN SMALL LETTER Z
+0xA8E7	0x2460	#CIRCLED DIGIT ONE
+0xA8E8	0x2461	#CIRCLED DIGIT TWO
+0xA8E9	0x2462	#CIRCLED DIGIT THREE
+0xA8EA	0x2463	#CIRCLED DIGIT FOUR
+0xA8EB	0x2464	#CIRCLED DIGIT FIVE
+0xA8EC	0x2465	#CIRCLED DIGIT SIX
+0xA8ED	0x2466	#CIRCLED DIGIT SEVEN
+0xA8EE	0x2467	#CIRCLED DIGIT EIGHT
+0xA8EF	0x2468	#CIRCLED DIGIT NINE
+0xA8F0	0x2469	#CIRCLED NUMBER TEN
+0xA8F1	0x246A	#CIRCLED NUMBER ELEVEN
+0xA8F2	0x246B	#CIRCLED NUMBER TWELVE
+0xA8F3	0x246C	#CIRCLED NUMBER THIRTEEN
+0xA8F4	0x246D	#CIRCLED NUMBER FOURTEEN
+0xA8F5	0x246E	#CIRCLED NUMBER FIFTEEN
+0xA8F6	0x00BD	#VULGAR FRACTION ONE HALF
+0xA8F7	0x2153	#VULGAR FRACTION ONE THIRD
+0xA8F8	0x2154	#VULGAR FRACTION TWO THIRDS
+0xA8F9	0x00BC	#VULGAR FRACTION ONE QUARTER
+0xA8FA	0x00BE	#VULGAR FRACTION THREE QUARTERS
+0xA8FB	0x215B	#VULGAR FRACTION ONE EIGHTH
+0xA8FC	0x215C	#VULGAR FRACTION THREE EIGHTHS
+0xA8FD	0x215D	#VULGAR FRACTION FIVE EIGHTHS
+0xA8FE	0x215E	#VULGAR FRACTION SEVEN EIGHTHS
+0xA941	0xCBC5	#HANGUL SYLLABLE SSANGCIEUC YU RIEULTHIEUTH
+0xA942	0xCBC6	#HANGUL SYLLABLE SSANGCIEUC YU RIEULPHIEUPH
+0xA943	0xCBC7	#HANGUL SYLLABLE SSANGCIEUC YU RIEULHIEUH
+0xA944	0xCBC8	#HANGUL SYLLABLE SSANGCIEUC YU MIEUM
+0xA945	0xCBC9	#HANGUL SYLLABLE SSANGCIEUC YU PIEUP
+0xA946	0xCBCA	#HANGUL SYLLABLE SSANGCIEUC YU PIEUPSIOS
+0xA947	0xCBCB	#HANGUL SYLLABLE SSANGCIEUC YU SIOS
+0xA948	0xCBCC	#HANGUL SYLLABLE SSANGCIEUC YU SSANGSIOS
+0xA949	0xCBCD	#HANGUL SYLLABLE SSANGCIEUC YU IEUNG
+0xA94A	0xCBCE	#HANGUL SYLLABLE SSANGCIEUC YU CIEUC
+0xA94B	0xCBCF	#HANGUL SYLLABLE SSANGCIEUC YU CHIEUCH
+0xA94C	0xCBD0	#HANGUL SYLLABLE SSANGCIEUC YU KHIEUKH
+0xA94D	0xCBD1	#HANGUL SYLLABLE SSANGCIEUC YU THIEUTH
+0xA94E	0xCBD2	#HANGUL SYLLABLE SSANGCIEUC YU PHIEUPH
+0xA94F	0xCBD3	#HANGUL SYLLABLE SSANGCIEUC YU HIEUH
+0xA950	0xCBD5	#HANGUL SYLLABLE SSANGCIEUC EU KIYEOK
+0xA951	0xCBD6	#HANGUL SYLLABLE SSANGCIEUC EU SSANGKIYEOK
+0xA952	0xCBD7	#HANGUL SYLLABLE SSANGCIEUC EU KIYEOKSIOS
+0xA953	0xCBD8	#HANGUL SYLLABLE SSANGCIEUC EU NIEUN
+0xA954	0xCBD9	#HANGUL SYLLABLE SSANGCIEUC EU NIEUNCIEUC
+0xA955	0xCBDA	#HANGUL SYLLABLE SSANGCIEUC EU NIEUNHIEUH
+0xA956	0xCBDB	#HANGUL SYLLABLE SSANGCIEUC EU TIKEUT
+0xA957	0xCBDC	#HANGUL SYLLABLE SSANGCIEUC EU RIEUL
+0xA958	0xCBDD	#HANGUL SYLLABLE SSANGCIEUC EU RIEULKIYEOK
+0xA959	0xCBDE	#HANGUL SYLLABLE SSANGCIEUC EU RIEULMIEUM
+0xA95A	0xCBDF	#HANGUL SYLLABLE SSANGCIEUC EU RIEULPIEUP
+0xA961	0xCBE0	#HANGUL SYLLABLE SSANGCIEUC EU RIEULSIOS
+0xA962	0xCBE1	#HANGUL SYLLABLE SSANGCIEUC EU RIEULTHIEUTH
+0xA963	0xCBE2	#HANGUL SYLLABLE SSANGCIEUC EU RIEULPHIEUPH
+0xA964	0xCBE3	#HANGUL SYLLABLE SSANGCIEUC EU RIEULHIEUH
+0xA965	0xCBE5	#HANGUL SYLLABLE SSANGCIEUC EU PIEUP
+0xA966	0xCBE6	#HANGUL SYLLABLE SSANGCIEUC EU PIEUPSIOS
+0xA967	0xCBE8	#HANGUL SYLLABLE SSANGCIEUC EU SSANGSIOS
+0xA968	0xCBEA	#HANGUL SYLLABLE SSANGCIEUC EU CIEUC
+0xA969	0xCBEB	#HANGUL SYLLABLE SSANGCIEUC EU CHIEUCH
+0xA96A	0xCBEC	#HANGUL SYLLABLE SSANGCIEUC EU KHIEUKH
+0xA96B	0xCBED	#HANGUL SYLLABLE SSANGCIEUC EU THIEUTH
+0xA96C	0xCBEE	#HANGUL SYLLABLE SSANGCIEUC EU PHIEUPH
+0xA96D	0xCBEF	#HANGUL SYLLABLE SSANGCIEUC EU HIEUH
+0xA96E	0xCBF0	#HANGUL SYLLABLE SSANGCIEUC YI
+0xA96F	0xCBF1	#HANGUL SYLLABLE SSANGCIEUC YI KIYEOK
+0xA970	0xCBF2	#HANGUL SYLLABLE SSANGCIEUC YI SSANGKIYEOK
+0xA971	0xCBF3	#HANGUL SYLLABLE SSANGCIEUC YI KIYEOKSIOS
+0xA972	0xCBF4	#HANGUL SYLLABLE SSANGCIEUC YI NIEUN
+0xA973	0xCBF5	#HANGUL SYLLABLE SSANGCIEUC YI NIEUNCIEUC
+0xA974	0xCBF6	#HANGUL SYLLABLE SSANGCIEUC YI NIEUNHIEUH
+0xA975	0xCBF7	#HANGUL SYLLABLE SSANGCIEUC YI TIKEUT
+0xA976	0xCBF8	#HANGUL SYLLABLE SSANGCIEUC YI RIEUL
+0xA977	0xCBF9	#HANGUL SYLLABLE SSANGCIEUC YI RIEULKIYEOK
+0xA978	0xCBFA	#HANGUL SYLLABLE SSANGCIEUC YI RIEULMIEUM
+0xA979	0xCBFB	#HANGUL SYLLABLE SSANGCIEUC YI RIEULPIEUP
+0xA97A	0xCBFC	#HANGUL SYLLABLE SSANGCIEUC YI RIEULSIOS
+0xA981	0xCBFD	#HANGUL SYLLABLE SSANGCIEUC YI RIEULTHIEUTH
+0xA982	0xCBFE	#HANGUL SYLLABLE SSANGCIEUC YI RIEULPHIEUPH
+0xA983	0xCBFF	#HANGUL SYLLABLE SSANGCIEUC YI RIEULHIEUH
+0xA984	0xCC00	#HANGUL SYLLABLE SSANGCIEUC YI MIEUM
+0xA985	0xCC01	#HANGUL SYLLABLE SSANGCIEUC YI PIEUP
+0xA986	0xCC02	#HANGUL SYLLABLE SSANGCIEUC YI PIEUPSIOS
+0xA987	0xCC03	#HANGUL SYLLABLE SSANGCIEUC YI SIOS
+0xA988	0xCC04	#HANGUL SYLLABLE SSANGCIEUC YI SSANGSIOS
+0xA989	0xCC05	#HANGUL SYLLABLE SSANGCIEUC YI IEUNG
+0xA98A	0xCC06	#HANGUL SYLLABLE SSANGCIEUC YI CIEUC
+0xA98B	0xCC07	#HANGUL SYLLABLE SSANGCIEUC YI CHIEUCH
+0xA98C	0xCC08	#HANGUL SYLLABLE SSANGCIEUC YI KHIEUKH
+0xA98D	0xCC09	#HANGUL SYLLABLE SSANGCIEUC YI THIEUTH
+0xA98E	0xCC0A	#HANGUL SYLLABLE SSANGCIEUC YI PHIEUPH
+0xA98F	0xCC0B	#HANGUL SYLLABLE SSANGCIEUC YI HIEUH
+0xA990	0xCC0E	#HANGUL SYLLABLE SSANGCIEUC I SSANGKIYEOK
+0xA991	0xCC0F	#HANGUL SYLLABLE SSANGCIEUC I KIYEOKSIOS
+0xA992	0xCC11	#HANGUL SYLLABLE SSANGCIEUC I NIEUNCIEUC
+0xA993	0xCC12	#HANGUL SYLLABLE SSANGCIEUC I NIEUNHIEUH
+0xA994	0xCC13	#HANGUL SYLLABLE SSANGCIEUC I TIKEUT
+0xA995	0xCC15	#HANGUL SYLLABLE SSANGCIEUC I RIEULKIYEOK
+0xA996	0xCC16	#HANGUL SYLLABLE SSANGCIEUC I RIEULMIEUM
+0xA997	0xCC17	#HANGUL SYLLABLE SSANGCIEUC I RIEULPIEUP
+0xA998	0xCC18	#HANGUL SYLLABLE SSANGCIEUC I RIEULSIOS
+0xA999	0xCC19	#HANGUL SYLLABLE SSANGCIEUC I RIEULTHIEUTH
+0xA99A	0xCC1A	#HANGUL SYLLABLE SSANGCIEUC I RIEULPHIEUPH
+0xA99B	0xCC1B	#HANGUL SYLLABLE SSANGCIEUC I RIEULHIEUH
+0xA99C	0xCC1E	#HANGUL SYLLABLE SSANGCIEUC I PIEUPSIOS
+0xA99D	0xCC1F	#HANGUL SYLLABLE SSANGCIEUC I SIOS
+0xA99E	0xCC20	#HANGUL SYLLABLE SSANGCIEUC I SSANGSIOS
+0xA99F	0xCC23	#HANGUL SYLLABLE SSANGCIEUC I CHIEUCH
+0xA9A0	0xCC24	#HANGUL SYLLABLE SSANGCIEUC I KHIEUKH
+0xA9A1	0x00E6	#LATIN SMALL LETTER AE
+0xA9A2	0x0111	#LATIN SMALL LETTER D WITH STROKE
+0xA9A3	0x00F0	#LATIN SMALL LETTER ETH
+0xA9A4	0x0127	#LATIN SMALL LETTER H WITH STROKE
+0xA9A5	0x0131	#LATIN SMALL LETTER DOTLESS I
+0xA9A6	0x0133	#LATIN SMALL LIGATURE IJ
+0xA9A7	0x0138	#LATIN SMALL LETTER KRA
+0xA9A8	0x0140	#LATIN SMALL LETTER L WITH MIDDLE DOT
+0xA9A9	0x0142	#LATIN SMALL LETTER L WITH STROKE
+0xA9AA	0x00F8	#LATIN SMALL LETTER O WITH STROKE
+0xA9AB	0x0153	#LATIN SMALL LIGATURE OE
+0xA9AC	0x00DF	#LATIN SMALL LETTER SHARP S
+0xA9AD	0x00FE	#LATIN SMALL LETTER THORN
+0xA9AE	0x0167	#LATIN SMALL LETTER T WITH STROKE
+0xA9AF	0x014B	#LATIN SMALL LETTER ENG
+0xA9B0	0x0149	#LATIN SMALL LETTER N PRECEDED BY APOSTROPHE
+0xA9B1	0x3200	#PARENTHESIZED HANGUL KIYEOK
+0xA9B2	0x3201	#PARENTHESIZED HANGUL NIEUN
+0xA9B3	0x3202	#PARENTHESIZED HANGUL TIKEUT
+0xA9B4	0x3203	#PARENTHESIZED HANGUL RIEUL
+0xA9B5	0x3204	#PARENTHESIZED HANGUL MIEUM
+0xA9B6	0x3205	#PARENTHESIZED HANGUL PIEUP
+0xA9B7	0x3206	#PARENTHESIZED HANGUL SIOS
+0xA9B8	0x3207	#PARENTHESIZED HANGUL IEUNG
+0xA9B9	0x3208	#PARENTHESIZED HANGUL CIEUC
+0xA9BA	0x3209	#PARENTHESIZED HANGUL CHIEUCH
+0xA9BB	0x320A	#PARENTHESIZED HANGUL KHIEUKH
+0xA9BC	0x320B	#PARENTHESIZED HANGUL THIEUTH
+0xA9BD	0x320C	#PARENTHESIZED HANGUL PHIEUPH
+0xA9BE	0x320D	#PARENTHESIZED HANGUL HIEUH
+0xA9BF	0x320E	#PARENTHESIZED HANGUL KIYEOK A
+0xA9C0	0x320F	#PARENTHESIZED HANGUL NIEUN A
+0xA9C1	0x3210	#PARENTHESIZED HANGUL TIKEUT A
+0xA9C2	0x3211	#PARENTHESIZED HANGUL RIEUL A
+0xA9C3	0x3212	#PARENTHESIZED HANGUL MIEUM A
+0xA9C4	0x3213	#PARENTHESIZED HANGUL PIEUP A
+0xA9C5	0x3214	#PARENTHESIZED HANGUL SIOS A
+0xA9C6	0x3215	#PARENTHESIZED HANGUL IEUNG A
+0xA9C7	0x3216	#PARENTHESIZED HANGUL CIEUC A
+0xA9C8	0x3217	#PARENTHESIZED HANGUL CHIEUCH A
+0xA9C9	0x3218	#PARENTHESIZED HANGUL KHIEUKH A
+0xA9CA	0x3219	#PARENTHESIZED HANGUL THIEUTH A
+0xA9CB	0x321A	#PARENTHESIZED HANGUL PHIEUPH A
+0xA9CC	0x321B	#PARENTHESIZED HANGUL HIEUH A
+0xA9CD	0x249C	#PARENTHESIZED LATIN SMALL LETTER A
+0xA9CE	0x249D	#PARENTHESIZED LATIN SMALL LETTER B
+0xA9CF	0x249E	#PARENTHESIZED LATIN SMALL LETTER C
+0xA9D0	0x249F	#PARENTHESIZED LATIN SMALL LETTER D
+0xA9D1	0x24A0	#PARENTHESIZED LATIN SMALL LETTER E
+0xA9D2	0x24A1	#PARENTHESIZED LATIN SMALL LETTER F
+0xA9D3	0x24A2	#PARENTHESIZED LATIN SMALL LETTER G
+0xA9D4	0x24A3	#PARENTHESIZED LATIN SMALL LETTER H
+0xA9D5	0x24A4	#PARENTHESIZED LATIN SMALL LETTER I
+0xA9D6	0x24A5	#PARENTHESIZED LATIN SMALL LETTER J
+0xA9D7	0x24A6	#PARENTHESIZED LATIN SMALL LETTER K
+0xA9D8	0x24A7	#PARENTHESIZED LATIN SMALL LETTER L
+0xA9D9	0x24A8	#PARENTHESIZED LATIN SMALL LETTER M
+0xA9DA	0x24A9	#PARENTHESIZED LATIN SMALL LETTER N
+0xA9DB	0x24AA	#PARENTHESIZED LATIN SMALL LETTER O
+0xA9DC	0x24AB	#PARENTHESIZED LATIN SMALL LETTER P
+0xA9DD	0x24AC	#PARENTHESIZED LATIN SMALL LETTER Q
+0xA9DE	0x24AD	#PARENTHESIZED LATIN SMALL LETTER R
+0xA9DF	0x24AE	#PARENTHESIZED LATIN SMALL LETTER S
+0xA9E0	0x24AF	#PARENTHESIZED LATIN SMALL LETTER T
+0xA9E1	0x24B0	#PARENTHESIZED LATIN SMALL LETTER U
+0xA9E2	0x24B1	#PARENTHESIZED LATIN SMALL LETTER V
+0xA9E3	0x24B2	#PARENTHESIZED LATIN SMALL LETTER W
+0xA9E4	0x24B3	#PARENTHESIZED LATIN SMALL LETTER X
+0xA9E5	0x24B4	#PARENTHESIZED LATIN SMALL LETTER Y
+0xA9E6	0x24B5	#PARENTHESIZED LATIN SMALL LETTER Z
+0xA9E7	0x2474	#PARENTHESIZED DIGIT ONE
+0xA9E8	0x2475	#PARENTHESIZED DIGIT TWO
+0xA9E9	0x2476	#PARENTHESIZED DIGIT THREE
+0xA9EA	0x2477	#PARENTHESIZED DIGIT FOUR
+0xA9EB	0x2478	#PARENTHESIZED DIGIT FIVE
+0xA9EC	0x2479	#PARENTHESIZED DIGIT SIX
+0xA9ED	0x247A	#PARENTHESIZED DIGIT SEVEN
+0xA9EE	0x247B	#PARENTHESIZED DIGIT EIGHT
+0xA9EF	0x247C	#PARENTHESIZED DIGIT NINE
+0xA9F0	0x247D	#PARENTHESIZED NUMBER TEN
+0xA9F1	0x247E	#PARENTHESIZED NUMBER ELEVEN
+0xA9F2	0x247F	#PARENTHESIZED NUMBER TWELVE
+0xA9F3	0x2480	#PARENTHESIZED NUMBER THIRTEEN
+0xA9F4	0x2481	#PARENTHESIZED NUMBER FOURTEEN
+0xA9F5	0x2482	#PARENTHESIZED NUMBER FIFTEEN
+0xA9F6	0x00B9	#SUPERSCRIPT ONE
+0xA9F7	0x00B2	#SUPERSCRIPT TWO
+0xA9F8	0x00B3	#SUPERSCRIPT THREE
+0xA9F9	0x2074	#SUPERSCRIPT FOUR
+0xA9FA	0x207F	#SUPERSCRIPT LATIN SMALL LETTER N
+0xA9FB	0x2081	#SUBSCRIPT ONE
+0xA9FC	0x2082	#SUBSCRIPT TWO
+0xA9FD	0x2083	#SUBSCRIPT THREE
+0xA9FE	0x2084	#SUBSCRIPT FOUR
+0xAA41	0xCC25	#HANGUL SYLLABLE SSANGCIEUC I THIEUTH
+0xAA42	0xCC26	#HANGUL SYLLABLE SSANGCIEUC I PHIEUPH
+0xAA43	0xCC2A	#HANGUL SYLLABLE CHIEUCH A SSANGKIYEOK
+0xAA44	0xCC2B	#HANGUL SYLLABLE CHIEUCH A KIYEOKSIOS
+0xAA45	0xCC2D	#HANGUL SYLLABLE CHIEUCH A NIEUNCIEUC
+0xAA46	0xCC2F	#HANGUL SYLLABLE CHIEUCH A TIKEUT
+0xAA47	0xCC31	#HANGUL SYLLABLE CHIEUCH A RIEULKIYEOK
+0xAA48	0xCC32	#HANGUL SYLLABLE CHIEUCH A RIEULMIEUM
+0xAA49	0xCC33	#HANGUL SYLLABLE CHIEUCH A RIEULPIEUP
+0xAA4A	0xCC34	#HANGUL SYLLABLE CHIEUCH A RIEULSIOS
+0xAA4B	0xCC35	#HANGUL SYLLABLE CHIEUCH A RIEULTHIEUTH
+0xAA4C	0xCC36	#HANGUL SYLLABLE CHIEUCH A RIEULPHIEUPH
+0xAA4D	0xCC37	#HANGUL SYLLABLE CHIEUCH A RIEULHIEUH
+0xAA4E	0xCC3A	#HANGUL SYLLABLE CHIEUCH A PIEUPSIOS
+0xAA4F	0xCC3F	#HANGUL SYLLABLE CHIEUCH A CHIEUCH
+0xAA50	0xCC40	#HANGUL SYLLABLE CHIEUCH A KHIEUKH
+0xAA51	0xCC41	#HANGUL SYLLABLE CHIEUCH A THIEUTH
+0xAA52	0xCC42	#HANGUL SYLLABLE CHIEUCH A PHIEUPH
+0xAA53	0xCC43	#HANGUL SYLLABLE CHIEUCH A HIEUH
+0xAA54	0xCC46	#HANGUL SYLLABLE CHIEUCH AE SSANGKIYEOK
+0xAA55	0xCC47	#HANGUL SYLLABLE CHIEUCH AE KIYEOKSIOS
+0xAA56	0xCC49	#HANGUL SYLLABLE CHIEUCH AE NIEUNCIEUC
+0xAA57	0xCC4A	#HANGUL SYLLABLE CHIEUCH AE NIEUNHIEUH
+0xAA58	0xCC4B	#HANGUL SYLLABLE CHIEUCH AE TIKEUT
+0xAA59	0xCC4D	#HANGUL SYLLABLE CHIEUCH AE RIEULKIYEOK
+0xAA5A	0xCC4E	#HANGUL SYLLABLE CHIEUCH AE RIEULMIEUM
+0xAA61	0xCC4F	#HANGUL SYLLABLE CHIEUCH AE RIEULPIEUP
+0xAA62	0xCC50	#HANGUL SYLLABLE CHIEUCH AE RIEULSIOS
+0xAA63	0xCC51	#HANGUL SYLLABLE CHIEUCH AE RIEULTHIEUTH
+0xAA64	0xCC52	#HANGUL SYLLABLE CHIEUCH AE RIEULPHIEUPH
+0xAA65	0xCC53	#HANGUL SYLLABLE CHIEUCH AE RIEULHIEUH
+0xAA66	0xCC56	#HANGUL SYLLABLE CHIEUCH AE PIEUPSIOS
+0xAA67	0xCC5A	#HANGUL SYLLABLE CHIEUCH AE CIEUC
+0xAA68	0xCC5B	#HANGUL SYLLABLE CHIEUCH AE CHIEUCH
+0xAA69	0xCC5C	#HANGUL SYLLABLE CHIEUCH AE KHIEUKH
+0xAA6A	0xCC5D	#HANGUL SYLLABLE CHIEUCH AE THIEUTH
+0xAA6B	0xCC5E	#HANGUL SYLLABLE CHIEUCH AE PHIEUPH
+0xAA6C	0xCC5F	#HANGUL SYLLABLE CHIEUCH AE HIEUH
+0xAA6D	0xCC61	#HANGUL SYLLABLE CHIEUCH YA KIYEOK
+0xAA6E	0xCC62	#HANGUL SYLLABLE CHIEUCH YA SSANGKIYEOK
+0xAA6F	0xCC63	#HANGUL SYLLABLE CHIEUCH YA KIYEOKSIOS
+0xAA70	0xCC65	#HANGUL SYLLABLE CHIEUCH YA NIEUNCIEUC
+0xAA71	0xCC67	#HANGUL SYLLABLE CHIEUCH YA TIKEUT
+0xAA72	0xCC69	#HANGUL SYLLABLE CHIEUCH YA RIEULKIYEOK
+0xAA73	0xCC6A	#HANGUL SYLLABLE CHIEUCH YA RIEULMIEUM
+0xAA74	0xCC6B	#HANGUL SYLLABLE CHIEUCH YA RIEULPIEUP
+0xAA75	0xCC6C	#HANGUL SYLLABLE CHIEUCH YA RIEULSIOS
+0xAA76	0xCC6D	#HANGUL SYLLABLE CHIEUCH YA RIEULTHIEUTH
+0xAA77	0xCC6E	#HANGUL SYLLABLE CHIEUCH YA RIEULPHIEUPH
+0xAA78	0xCC6F	#HANGUL SYLLABLE CHIEUCH YA RIEULHIEUH
+0xAA79	0xCC71	#HANGUL SYLLABLE CHIEUCH YA PIEUP
+0xAA7A	0xCC72	#HANGUL SYLLABLE CHIEUCH YA PIEUPSIOS
+0xAA81	0xCC73	#HANGUL SYLLABLE CHIEUCH YA SIOS
+0xAA82	0xCC74	#HANGUL SYLLABLE CHIEUCH YA SSANGSIOS
+0xAA83	0xCC76	#HANGUL SYLLABLE CHIEUCH YA CIEUC
+0xAA84	0xCC77	#HANGUL SYLLABLE CHIEUCH YA CHIEUCH
+0xAA85	0xCC78	#HANGUL SYLLABLE CHIEUCH YA KHIEUKH
+0xAA86	0xCC79	#HANGUL SYLLABLE CHIEUCH YA THIEUTH
+0xAA87	0xCC7A	#HANGUL SYLLABLE CHIEUCH YA PHIEUPH
+0xAA88	0xCC7B	#HANGUL SYLLABLE CHIEUCH YA HIEUH
+0xAA89	0xCC7C	#HANGUL SYLLABLE CHIEUCH YAE
+0xAA8A	0xCC7D	#HANGUL SYLLABLE CHIEUCH YAE KIYEOK
+0xAA8B	0xCC7E	#HANGUL SYLLABLE CHIEUCH YAE SSANGKIYEOK
+0xAA8C	0xCC7F	#HANGUL SYLLABLE CHIEUCH YAE KIYEOKSIOS
+0xAA8D	0xCC80	#HANGUL SYLLABLE CHIEUCH YAE NIEUN
+0xAA8E	0xCC81	#HANGUL SYLLABLE CHIEUCH YAE NIEUNCIEUC
+0xAA8F	0xCC82	#HANGUL SYLLABLE CHIEUCH YAE NIEUNHIEUH
+0xAA90	0xCC83	#HANGUL SYLLABLE CHIEUCH YAE TIKEUT
+0xAA91	0xCC84	#HANGUL SYLLABLE CHIEUCH YAE RIEUL
+0xAA92	0xCC85	#HANGUL SYLLABLE CHIEUCH YAE RIEULKIYEOK
+0xAA93	0xCC86	#HANGUL SYLLABLE CHIEUCH YAE RIEULMIEUM
+0xAA94	0xCC87	#HANGUL SYLLABLE CHIEUCH YAE RIEULPIEUP
+0xAA95	0xCC88	#HANGUL SYLLABLE CHIEUCH YAE RIEULSIOS
+0xAA96	0xCC89	#HANGUL SYLLABLE CHIEUCH YAE RIEULTHIEUTH
+0xAA97	0xCC8A	#HANGUL SYLLABLE CHIEUCH YAE RIEULPHIEUPH
+0xAA98	0xCC8B	#HANGUL SYLLABLE CHIEUCH YAE RIEULHIEUH
+0xAA99	0xCC8C	#HANGUL SYLLABLE CHIEUCH YAE MIEUM
+0xAA9A	0xCC8D	#HANGUL SYLLABLE CHIEUCH YAE PIEUP
+0xAA9B	0xCC8E	#HANGUL SYLLABLE CHIEUCH YAE PIEUPSIOS
+0xAA9C	0xCC8F	#HANGUL SYLLABLE CHIEUCH YAE SIOS
+0xAA9D	0xCC90	#HANGUL SYLLABLE CHIEUCH YAE SSANGSIOS
+0xAA9E	0xCC91	#HANGUL SYLLABLE CHIEUCH YAE IEUNG
+0xAA9F	0xCC92	#HANGUL SYLLABLE CHIEUCH YAE CIEUC
+0xAAA0	0xCC93	#HANGUL SYLLABLE CHIEUCH YAE CHIEUCH
+0xAAA1	0x3041	#HIRAGANA LETTER SMALL A
+0xAAA2	0x3042	#HIRAGANA LETTER A
+0xAAA3	0x3043	#HIRAGANA LETTER SMALL I
+0xAAA4	0x3044	#HIRAGANA LETTER I
+0xAAA5	0x3045	#HIRAGANA LETTER SMALL U
+0xAAA6	0x3046	#HIRAGANA LETTER U
+0xAAA7	0x3047	#HIRAGANA LETTER SMALL E
+0xAAA8	0x3048	#HIRAGANA LETTER E
+0xAAA9	0x3049	#HIRAGANA LETTER SMALL O
+0xAAAA	0x304A	#HIRAGANA LETTER O
+0xAAAB	0x304B	#HIRAGANA LETTER KA
+0xAAAC	0x304C	#HIRAGANA LETTER GA
+0xAAAD	0x304D	#HIRAGANA LETTER KI
+0xAAAE	0x304E	#HIRAGANA LETTER GI
+0xAAAF	0x304F	#HIRAGANA LETTER KU
+0xAAB0	0x3050	#HIRAGANA LETTER GU
+0xAAB1	0x3051	#HIRAGANA LETTER KE
+0xAAB2	0x3052	#HIRAGANA LETTER GE
+0xAAB3	0x3053	#HIRAGANA LETTER KO
+0xAAB4	0x3054	#HIRAGANA LETTER GO
+0xAAB5	0x3055	#HIRAGANA LETTER SA
+0xAAB6	0x3056	#HIRAGANA LETTER ZA
+0xAAB7	0x3057	#HIRAGANA LETTER SI
+0xAAB8	0x3058	#HIRAGANA LETTER ZI
+0xAAB9	0x3059	#HIRAGANA LETTER SU
+0xAABA	0x305A	#HIRAGANA LETTER ZU
+0xAABB	0x305B	#HIRAGANA LETTER SE
+0xAABC	0x305C	#HIRAGANA LETTER ZE
+0xAABD	0x305D	#HIRAGANA LETTER SO
+0xAABE	0x305E	#HIRAGANA LETTER ZO
+0xAABF	0x305F	#HIRAGANA LETTER TA
+0xAAC0	0x3060	#HIRAGANA LETTER DA
+0xAAC1	0x3061	#HIRAGANA LETTER TI
+0xAAC2	0x3062	#HIRAGANA LETTER DI
+0xAAC3	0x3063	#HIRAGANA LETTER SMALL TU
+0xAAC4	0x3064	#HIRAGANA LETTER TU
+0xAAC5	0x3065	#HIRAGANA LETTER DU
+0xAAC6	0x3066	#HIRAGANA LETTER TE
+0xAAC7	0x3067	#HIRAGANA LETTER DE
+0xAAC8	0x3068	#HIRAGANA LETTER TO
+0xAAC9	0x3069	#HIRAGANA LETTER DO
+0xAACA	0x306A	#HIRAGANA LETTER NA
+0xAACB	0x306B	#HIRAGANA LETTER NI
+0xAACC	0x306C	#HIRAGANA LETTER NU
+0xAACD	0x306D	#HIRAGANA LETTER NE
+0xAACE	0x306E	#HIRAGANA LETTER NO
+0xAACF	0x306F	#HIRAGANA LETTER HA
+0xAAD0	0x3070	#HIRAGANA LETTER BA
+0xAAD1	0x3071	#HIRAGANA LETTER PA
+0xAAD2	0x3072	#HIRAGANA LETTER HI
+0xAAD3	0x3073	#HIRAGANA LETTER BI
+0xAAD4	0x3074	#HIRAGANA LETTER PI
+0xAAD5	0x3075	#HIRAGANA LETTER HU
+0xAAD6	0x3076	#HIRAGANA LETTER BU
+0xAAD7	0x3077	#HIRAGANA LETTER PU
+0xAAD8	0x3078	#HIRAGANA LETTER HE
+0xAAD9	0x3079	#HIRAGANA LETTER BE
+0xAADA	0x307A	#HIRAGANA LETTER PE
+0xAADB	0x307B	#HIRAGANA LETTER HO
+0xAADC	0x307C	#HIRAGANA LETTER BO
+0xAADD	0x307D	#HIRAGANA LETTER PO
+0xAADE	0x307E	#HIRAGANA LETTER MA
+0xAADF	0x307F	#HIRAGANA LETTER MI
+0xAAE0	0x3080	#HIRAGANA LETTER MU
+0xAAE1	0x3081	#HIRAGANA LETTER ME
+0xAAE2	0x3082	#HIRAGANA LETTER MO
+0xAAE3	0x3083	#HIRAGANA LETTER SMALL YA
+0xAAE4	0x3084	#HIRAGANA LETTER YA
+0xAAE5	0x3085	#HIRAGANA LETTER SMALL YU
+0xAAE6	0x3086	#HIRAGANA LETTER YU
+0xAAE7	0x3087	#HIRAGANA LETTER SMALL YO
+0xAAE8	0x3088	#HIRAGANA LETTER YO
+0xAAE9	0x3089	#HIRAGANA LETTER RA
+0xAAEA	0x308A	#HIRAGANA LETTER RI
+0xAAEB	0x308B	#HIRAGANA LETTER RU
+0xAAEC	0x308C	#HIRAGANA LETTER RE
+0xAAED	0x308D	#HIRAGANA LETTER RO
+0xAAEE	0x308E	#HIRAGANA LETTER SMALL WA
+0xAAEF	0x308F	#HIRAGANA LETTER WA
+0xAAF0	0x3090	#HIRAGANA LETTER WI
+0xAAF1	0x3091	#HIRAGANA LETTER WE
+0xAAF2	0x3092	#HIRAGANA LETTER WO
+0xAAF3	0x3093	#HIRAGANA LETTER N
+0xAB41	0xCC94	#HANGUL SYLLABLE CHIEUCH YAE KHIEUKH
+0xAB42	0xCC95	#HANGUL SYLLABLE CHIEUCH YAE THIEUTH
+0xAB43	0xCC96	#HANGUL SYLLABLE CHIEUCH YAE PHIEUPH
+0xAB44	0xCC97	#HANGUL SYLLABLE CHIEUCH YAE HIEUH
+0xAB45	0xCC9A	#HANGUL SYLLABLE CHIEUCH EO SSANGKIYEOK
+0xAB46	0xCC9B	#HANGUL SYLLABLE CHIEUCH EO KIYEOKSIOS
+0xAB47	0xCC9D	#HANGUL SYLLABLE CHIEUCH EO NIEUNCIEUC
+0xAB48	0xCC9E	#HANGUL SYLLABLE CHIEUCH EO NIEUNHIEUH
+0xAB49	0xCC9F	#HANGUL SYLLABLE CHIEUCH EO TIKEUT
+0xAB4A	0xCCA1	#HANGUL SYLLABLE CHIEUCH EO RIEULKIYEOK
+0xAB4B	0xCCA2	#HANGUL SYLLABLE CHIEUCH EO RIEULMIEUM
+0xAB4C	0xCCA3	#HANGUL SYLLABLE CHIEUCH EO RIEULPIEUP
+0xAB4D	0xCCA4	#HANGUL SYLLABLE CHIEUCH EO RIEULSIOS
+0xAB4E	0xCCA5	#HANGUL SYLLABLE CHIEUCH EO RIEULTHIEUTH
+0xAB4F	0xCCA6	#HANGUL SYLLABLE CHIEUCH EO RIEULPHIEUPH
+0xAB50	0xCCA7	#HANGUL SYLLABLE CHIEUCH EO RIEULHIEUH
+0xAB51	0xCCAA	#HANGUL SYLLABLE CHIEUCH EO PIEUPSIOS
+0xAB52	0xCCAE	#HANGUL SYLLABLE CHIEUCH EO CIEUC
+0xAB53	0xCCAF	#HANGUL SYLLABLE CHIEUCH EO CHIEUCH
+0xAB54	0xCCB0	#HANGUL SYLLABLE CHIEUCH EO KHIEUKH
+0xAB55	0xCCB1	#HANGUL SYLLABLE CHIEUCH EO THIEUTH
+0xAB56	0xCCB2	#HANGUL SYLLABLE CHIEUCH EO PHIEUPH
+0xAB57	0xCCB3	#HANGUL SYLLABLE CHIEUCH EO HIEUH
+0xAB58	0xCCB6	#HANGUL SYLLABLE CHIEUCH E SSANGKIYEOK
+0xAB59	0xCCB7	#HANGUL SYLLABLE CHIEUCH E KIYEOKSIOS
+0xAB5A	0xCCB9	#HANGUL SYLLABLE CHIEUCH E NIEUNCIEUC
+0xAB61	0xCCBA	#HANGUL SYLLABLE CHIEUCH E NIEUNHIEUH
+0xAB62	0xCCBB	#HANGUL SYLLABLE CHIEUCH E TIKEUT
+0xAB63	0xCCBD	#HANGUL SYLLABLE CHIEUCH E RIEULKIYEOK
+0xAB64	0xCCBE	#HANGUL SYLLABLE CHIEUCH E RIEULMIEUM
+0xAB65	0xCCBF	#HANGUL SYLLABLE CHIEUCH E RIEULPIEUP
+0xAB66	0xCCC0	#HANGUL SYLLABLE CHIEUCH E RIEULSIOS
+0xAB67	0xCCC1	#HANGUL SYLLABLE CHIEUCH E RIEULTHIEUTH
+0xAB68	0xCCC2	#HANGUL SYLLABLE CHIEUCH E RIEULPHIEUPH
+0xAB69	0xCCC3	#HANGUL SYLLABLE CHIEUCH E RIEULHIEUH
+0xAB6A	0xCCC6	#HANGUL SYLLABLE CHIEUCH E PIEUPSIOS
+0xAB6B	0xCCC8	#HANGUL SYLLABLE CHIEUCH E SSANGSIOS
+0xAB6C	0xCCCA	#HANGUL SYLLABLE CHIEUCH E CIEUC
+0xAB6D	0xCCCB	#HANGUL SYLLABLE CHIEUCH E CHIEUCH
+0xAB6E	0xCCCC	#HANGUL SYLLABLE CHIEUCH E KHIEUKH
+0xAB6F	0xCCCD	#HANGUL SYLLABLE CHIEUCH E THIEUTH
+0xAB70	0xCCCE	#HANGUL SYLLABLE CHIEUCH E PHIEUPH
+0xAB71	0xCCCF	#HANGUL SYLLABLE CHIEUCH E HIEUH
+0xAB72	0xCCD1	#HANGUL SYLLABLE CHIEUCH YEO KIYEOK
+0xAB73	0xCCD2	#HANGUL SYLLABLE CHIEUCH YEO SSANGKIYEOK
+0xAB74	0xCCD3	#HANGUL SYLLABLE CHIEUCH YEO KIYEOKSIOS
+0xAB75	0xCCD5	#HANGUL SYLLABLE CHIEUCH YEO NIEUNCIEUC
+0xAB76	0xCCD6	#HANGUL SYLLABLE CHIEUCH YEO NIEUNHIEUH
+0xAB77	0xCCD7	#HANGUL SYLLABLE CHIEUCH YEO TIKEUT
+0xAB78	0xCCD8	#HANGUL SYLLABLE CHIEUCH YEO RIEUL
+0xAB79	0xCCD9	#HANGUL SYLLABLE CHIEUCH YEO RIEULKIYEOK
+0xAB7A	0xCCDA	#HANGUL SYLLABLE CHIEUCH YEO RIEULMIEUM
+0xAB81	0xCCDB	#HANGUL SYLLABLE CHIEUCH YEO RIEULPIEUP
+0xAB82	0xCCDC	#HANGUL SYLLABLE CHIEUCH YEO RIEULSIOS
+0xAB83	0xCCDD	#HANGUL SYLLABLE CHIEUCH YEO RIEULTHIEUTH
+0xAB84	0xCCDE	#HANGUL SYLLABLE CHIEUCH YEO RIEULPHIEUPH
+0xAB85	0xCCDF	#HANGUL SYLLABLE CHIEUCH YEO RIEULHIEUH
+0xAB86	0xCCE0	#HANGUL SYLLABLE CHIEUCH YEO MIEUM
+0xAB87	0xCCE1	#HANGUL SYLLABLE CHIEUCH YEO PIEUP
+0xAB88	0xCCE2	#HANGUL SYLLABLE CHIEUCH YEO PIEUPSIOS
+0xAB89	0xCCE3	#HANGUL SYLLABLE CHIEUCH YEO SIOS
+0xAB8A	0xCCE5	#HANGUL SYLLABLE CHIEUCH YEO IEUNG
+0xAB8B	0xCCE6	#HANGUL SYLLABLE CHIEUCH YEO CIEUC
+0xAB8C	0xCCE7	#HANGUL SYLLABLE CHIEUCH YEO CHIEUCH
+0xAB8D	0xCCE8	#HANGUL SYLLABLE CHIEUCH YEO KHIEUKH
+0xAB8E	0xCCE9	#HANGUL SYLLABLE CHIEUCH YEO THIEUTH
+0xAB8F	0xCCEA	#HANGUL SYLLABLE CHIEUCH YEO PHIEUPH
+0xAB90	0xCCEB	#HANGUL SYLLABLE CHIEUCH YEO HIEUH
+0xAB91	0xCCED	#HANGUL SYLLABLE CHIEUCH YE KIYEOK
+0xAB92	0xCCEE	#HANGUL SYLLABLE CHIEUCH YE SSANGKIYEOK
+0xAB93	0xCCEF	#HANGUL SYLLABLE CHIEUCH YE KIYEOKSIOS
+0xAB94	0xCCF1	#HANGUL SYLLABLE CHIEUCH YE NIEUNCIEUC
+0xAB95	0xCCF2	#HANGUL SYLLABLE CHIEUCH YE NIEUNHIEUH
+0xAB96	0xCCF3	#HANGUL SYLLABLE CHIEUCH YE TIKEUT
+0xAB97	0xCCF4	#HANGUL SYLLABLE CHIEUCH YE RIEUL
+0xAB98	0xCCF5	#HANGUL SYLLABLE CHIEUCH YE RIEULKIYEOK
+0xAB99	0xCCF6	#HANGUL SYLLABLE CHIEUCH YE RIEULMIEUM
+0xAB9A	0xCCF7	#HANGUL SYLLABLE CHIEUCH YE RIEULPIEUP
+0xAB9B	0xCCF8	#HANGUL SYLLABLE CHIEUCH YE RIEULSIOS
+0xAB9C	0xCCF9	#HANGUL SYLLABLE CHIEUCH YE RIEULTHIEUTH
+0xAB9D	0xCCFA	#HANGUL SYLLABLE CHIEUCH YE RIEULPHIEUPH
+0xAB9E	0xCCFB	#HANGUL SYLLABLE CHIEUCH YE RIEULHIEUH
+0xAB9F	0xCCFC	#HANGUL SYLLABLE CHIEUCH YE MIEUM
+0xABA0	0xCCFD	#HANGUL SYLLABLE CHIEUCH YE PIEUP
+0xABA1	0x30A1	#KATAKANA LETTER SMALL A
+0xABA2	0x30A2	#KATAKANA LETTER A
+0xABA3	0x30A3	#KATAKANA LETTER SMALL I
+0xABA4	0x30A4	#KATAKANA LETTER I
+0xABA5	0x30A5	#KATAKANA LETTER SMALL U
+0xABA6	0x30A6	#KATAKANA LETTER U
+0xABA7	0x30A7	#KATAKANA LETTER SMALL E
+0xABA8	0x30A8	#KATAKANA LETTER E
+0xABA9	0x30A9	#KATAKANA LETTER SMALL O
+0xABAA	0x30AA	#KATAKANA LETTER O
+0xABAB	0x30AB	#KATAKANA LETTER KA
+0xABAC	0x30AC	#KATAKANA LETTER GA
+0xABAD	0x30AD	#KATAKANA LETTER KI
+0xABAE	0x30AE	#KATAKANA LETTER GI
+0xABAF	0x30AF	#KATAKANA LETTER KU
+0xABB0	0x30B0	#KATAKANA LETTER GU
+0xABB1	0x30B1	#KATAKANA LETTER KE
+0xABB2	0x30B2	#KATAKANA LETTER GE
+0xABB3	0x30B3	#KATAKANA LETTER KO
+0xABB4	0x30B4	#KATAKANA LETTER GO
+0xABB5	0x30B5	#KATAKANA LETTER SA
+0xABB6	0x30B6	#KATAKANA LETTER ZA
+0xABB7	0x30B7	#KATAKANA LETTER SI
+0xABB8	0x30B8	#KATAKANA LETTER ZI
+0xABB9	0x30B9	#KATAKANA LETTER SU
+0xABBA	0x30BA	#KATAKANA LETTER ZU
+0xABBB	0x30BB	#KATAKANA LETTER SE
+0xABBC	0x30BC	#KATAKANA LETTER ZE
+0xABBD	0x30BD	#KATAKANA LETTER SO
+0xABBE	0x30BE	#KATAKANA LETTER ZO
+0xABBF	0x30BF	#KATAKANA LETTER TA
+0xABC0	0x30C0	#KATAKANA LETTER DA
+0xABC1	0x30C1	#KATAKANA LETTER TI
+0xABC2	0x30C2	#KATAKANA LETTER DI
+0xABC3	0x30C3	#KATAKANA LETTER SMALL TU
+0xABC4	0x30C4	#KATAKANA LETTER TU
+0xABC5	0x30C5	#KATAKANA LETTER DU
+0xABC6	0x30C6	#KATAKANA LETTER TE
+0xABC7	0x30C7	#KATAKANA LETTER DE
+0xABC8	0x30C8	#KATAKANA LETTER TO
+0xABC9	0x30C9	#KATAKANA LETTER DO
+0xABCA	0x30CA	#KATAKANA LETTER NA
+0xABCB	0x30CB	#KATAKANA LETTER NI
+0xABCC	0x30CC	#KATAKANA LETTER NU
+0xABCD	0x30CD	#KATAKANA LETTER NE
+0xABCE	0x30CE	#KATAKANA LETTER NO
+0xABCF	0x30CF	#KATAKANA LETTER HA
+0xABD0	0x30D0	#KATAKANA LETTER BA
+0xABD1	0x30D1	#KATAKANA LETTER PA
+0xABD2	0x30D2	#KATAKANA LETTER HI
+0xABD3	0x30D3	#KATAKANA LETTER BI
+0xABD4	0x30D4	#KATAKANA LETTER PI
+0xABD5	0x30D5	#KATAKANA LETTER HU
+0xABD6	0x30D6	#KATAKANA LETTER BU
+0xABD7	0x30D7	#KATAKANA LETTER PU
+0xABD8	0x30D8	#KATAKANA LETTER HE
+0xABD9	0x30D9	#KATAKANA LETTER BE
+0xABDA	0x30DA	#KATAKANA LETTER PE
+0xABDB	0x30DB	#KATAKANA LETTER HO
+0xABDC	0x30DC	#KATAKANA LETTER BO
+0xABDD	0x30DD	#KATAKANA LETTER PO
+0xABDE	0x30DE	#KATAKANA LETTER MA
+0xABDF	0x30DF	#KATAKANA LETTER MI
+0xABE0	0x30E0	#KATAKANA LETTER MU
+0xABE1	0x30E1	#KATAKANA LETTER ME
+0xABE2	0x30E2	#KATAKANA LETTER MO
+0xABE3	0x30E3	#KATAKANA LETTER SMALL YA
+0xABE4	0x30E4	#KATAKANA LETTER YA
+0xABE5	0x30E5	#KATAKANA LETTER SMALL YU
+0xABE6	0x30E6	#KATAKANA LETTER YU
+0xABE7	0x30E7	#KATAKANA LETTER SMALL YO
+0xABE8	0x30E8	#KATAKANA LETTER YO
+0xABE9	0x30E9	#KATAKANA LETTER RA
+0xABEA	0x30EA	#KATAKANA LETTER RI
+0xABEB	0x30EB	#KATAKANA LETTER RU
+0xABEC	0x30EC	#KATAKANA LETTER RE
+0xABED	0x30ED	#KATAKANA LETTER RO
+0xABEE	0x30EE	#KATAKANA LETTER SMALL WA
+0xABEF	0x30EF	#KATAKANA LETTER WA
+0xABF0	0x30F0	#KATAKANA LETTER WI
+0xABF1	0x30F1	#KATAKANA LETTER WE
+0xABF2	0x30F2	#KATAKANA LETTER WO
+0xABF3	0x30F3	#KATAKANA LETTER N
+0xABF4	0x30F4	#KATAKANA LETTER VU
+0xABF5	0x30F5	#KATAKANA LETTER SMALL KA
+0xABF6	0x30F6	#KATAKANA LETTER SMALL KE
+0xAC41	0xCCFE	#HANGUL SYLLABLE CHIEUCH YE PIEUPSIOS
+0xAC42	0xCCFF	#HANGUL SYLLABLE CHIEUCH YE SIOS
+0xAC43	0xCD00	#HANGUL SYLLABLE CHIEUCH YE SSANGSIOS
+0xAC44	0xCD02	#HANGUL SYLLABLE CHIEUCH YE CIEUC
+0xAC45	0xCD03	#HANGUL SYLLABLE CHIEUCH YE CHIEUCH
+0xAC46	0xCD04	#HANGUL SYLLABLE CHIEUCH YE KHIEUKH
+0xAC47	0xCD05	#HANGUL SYLLABLE CHIEUCH YE THIEUTH
+0xAC48	0xCD06	#HANGUL SYLLABLE CHIEUCH YE PHIEUPH
+0xAC49	0xCD07	#HANGUL SYLLABLE CHIEUCH YE HIEUH
+0xAC4A	0xCD0A	#HANGUL SYLLABLE CHIEUCH O SSANGKIYEOK
+0xAC4B	0xCD0B	#HANGUL SYLLABLE CHIEUCH O KIYEOKSIOS
+0xAC4C	0xCD0D	#HANGUL SYLLABLE CHIEUCH O NIEUNCIEUC
+0xAC4D	0xCD0E	#HANGUL SYLLABLE CHIEUCH O NIEUNHIEUH
+0xAC4E	0xCD0F	#HANGUL SYLLABLE CHIEUCH O TIKEUT
+0xAC4F	0xCD11	#HANGUL SYLLABLE CHIEUCH O RIEULKIYEOK
+0xAC50	0xCD12	#HANGUL SYLLABLE CHIEUCH O RIEULMIEUM
+0xAC51	0xCD13	#HANGUL SYLLABLE CHIEUCH O RIEULPIEUP
+0xAC52	0xCD14	#HANGUL SYLLABLE CHIEUCH O RIEULSIOS
+0xAC53	0xCD15	#HANGUL SYLLABLE CHIEUCH O RIEULTHIEUTH
+0xAC54	0xCD16	#HANGUL SYLLABLE CHIEUCH O RIEULPHIEUPH
+0xAC55	0xCD17	#HANGUL SYLLABLE CHIEUCH O RIEULHIEUH
+0xAC56	0xCD1A	#HANGUL SYLLABLE CHIEUCH O PIEUPSIOS
+0xAC57	0xCD1C	#HANGUL SYLLABLE CHIEUCH O SSANGSIOS
+0xAC58	0xCD1E	#HANGUL SYLLABLE CHIEUCH O CIEUC
+0xAC59	0xCD1F	#HANGUL SYLLABLE CHIEUCH O CHIEUCH
+0xAC5A	0xCD20	#HANGUL SYLLABLE CHIEUCH O KHIEUKH
+0xAC61	0xCD21	#HANGUL SYLLABLE CHIEUCH O THIEUTH
+0xAC62	0xCD22	#HANGUL SYLLABLE CHIEUCH O PHIEUPH
+0xAC63	0xCD23	#HANGUL SYLLABLE CHIEUCH O HIEUH
+0xAC64	0xCD25	#HANGUL SYLLABLE CHIEUCH WA KIYEOK
+0xAC65	0xCD26	#HANGUL SYLLABLE CHIEUCH WA SSANGKIYEOK
+0xAC66	0xCD27	#HANGUL SYLLABLE CHIEUCH WA KIYEOKSIOS
+0xAC67	0xCD29	#HANGUL SYLLABLE CHIEUCH WA NIEUNCIEUC
+0xAC68	0xCD2A	#HANGUL SYLLABLE CHIEUCH WA NIEUNHIEUH
+0xAC69	0xCD2B	#HANGUL SYLLABLE CHIEUCH WA TIKEUT
+0xAC6A	0xCD2D	#HANGUL SYLLABLE CHIEUCH WA RIEULKIYEOK
+0xAC6B	0xCD2E	#HANGUL SYLLABLE CHIEUCH WA RIEULMIEUM
+0xAC6C	0xCD2F	#HANGUL SYLLABLE CHIEUCH WA RIEULPIEUP
+0xAC6D	0xCD30	#HANGUL SYLLABLE CHIEUCH WA RIEULSIOS
+0xAC6E	0xCD31	#HANGUL SYLLABLE CHIEUCH WA RIEULTHIEUTH
+0xAC6F	0xCD32	#HANGUL SYLLABLE CHIEUCH WA RIEULPHIEUPH
+0xAC70	0xCD33	#HANGUL SYLLABLE CHIEUCH WA RIEULHIEUH
+0xAC71	0xCD34	#HANGUL SYLLABLE CHIEUCH WA MIEUM
+0xAC72	0xCD35	#HANGUL SYLLABLE CHIEUCH WA PIEUP
+0xAC73	0xCD36	#HANGUL SYLLABLE CHIEUCH WA PIEUPSIOS
+0xAC74	0xCD37	#HANGUL SYLLABLE CHIEUCH WA SIOS
+0xAC75	0xCD38	#HANGUL SYLLABLE CHIEUCH WA SSANGSIOS
+0xAC76	0xCD3A	#HANGUL SYLLABLE CHIEUCH WA CIEUC
+0xAC77	0xCD3B	#HANGUL SYLLABLE CHIEUCH WA CHIEUCH
+0xAC78	0xCD3C	#HANGUL SYLLABLE CHIEUCH WA KHIEUKH
+0xAC79	0xCD3D	#HANGUL SYLLABLE CHIEUCH WA THIEUTH
+0xAC7A	0xCD3E	#HANGUL SYLLABLE CHIEUCH WA PHIEUPH
+0xAC81	0xCD3F	#HANGUL SYLLABLE CHIEUCH WA HIEUH
+0xAC82	0xCD40	#HANGUL SYLLABLE CHIEUCH WAE
+0xAC83	0xCD41	#HANGUL SYLLABLE CHIEUCH WAE KIYEOK
+0xAC84	0xCD42	#HANGUL SYLLABLE CHIEUCH WAE SSANGKIYEOK
+0xAC85	0xCD43	#HANGUL SYLLABLE CHIEUCH WAE KIYEOKSIOS
+0xAC86	0xCD44	#HANGUL SYLLABLE CHIEUCH WAE NIEUN
+0xAC87	0xCD45	#HANGUL SYLLABLE CHIEUCH WAE NIEUNCIEUC
+0xAC88	0xCD46	#HANGUL SYLLABLE CHIEUCH WAE NIEUNHIEUH
+0xAC89	0xCD47	#HANGUL SYLLABLE CHIEUCH WAE TIKEUT
+0xAC8A	0xCD48	#HANGUL SYLLABLE CHIEUCH WAE RIEUL
+0xAC8B	0xCD49	#HANGUL SYLLABLE CHIEUCH WAE RIEULKIYEOK
+0xAC8C	0xCD4A	#HANGUL SYLLABLE CHIEUCH WAE RIEULMIEUM
+0xAC8D	0xCD4B	#HANGUL SYLLABLE CHIEUCH WAE RIEULPIEUP
+0xAC8E	0xCD4C	#HANGUL SYLLABLE CHIEUCH WAE RIEULSIOS
+0xAC8F	0xCD4D	#HANGUL SYLLABLE CHIEUCH WAE RIEULTHIEUTH
+0xAC90	0xCD4E	#HANGUL SYLLABLE CHIEUCH WAE RIEULPHIEUPH
+0xAC91	0xCD4F	#HANGUL SYLLABLE CHIEUCH WAE RIEULHIEUH
+0xAC92	0xCD50	#HANGUL SYLLABLE CHIEUCH WAE MIEUM
+0xAC93	0xCD51	#HANGUL SYLLABLE CHIEUCH WAE PIEUP
+0xAC94	0xCD52	#HANGUL SYLLABLE CHIEUCH WAE PIEUPSIOS
+0xAC95	0xCD53	#HANGUL SYLLABLE CHIEUCH WAE SIOS
+0xAC96	0xCD54	#HANGUL SYLLABLE CHIEUCH WAE SSANGSIOS
+0xAC97	0xCD55	#HANGUL SYLLABLE CHIEUCH WAE IEUNG
+0xAC98	0xCD56	#HANGUL SYLLABLE CHIEUCH WAE CIEUC
+0xAC99	0xCD57	#HANGUL SYLLABLE CHIEUCH WAE CHIEUCH
+0xAC9A	0xCD58	#HANGUL SYLLABLE CHIEUCH WAE KHIEUKH
+0xAC9B	0xCD59	#HANGUL SYLLABLE CHIEUCH WAE THIEUTH
+0xAC9C	0xCD5A	#HANGUL SYLLABLE CHIEUCH WAE PHIEUPH
+0xAC9D	0xCD5B	#HANGUL SYLLABLE CHIEUCH WAE HIEUH
+0xAC9E	0xCD5D	#HANGUL SYLLABLE CHIEUCH OE KIYEOK
+0xAC9F	0xCD5E	#HANGUL SYLLABLE CHIEUCH OE SSANGKIYEOK
+0xACA0	0xCD5F	#HANGUL SYLLABLE CHIEUCH OE KIYEOKSIOS
+0xACA1	0x0410	#CYRILLIC CAPITAL LETTER A
+0xACA2	0x0411	#CYRILLIC CAPITAL LETTER BE
+0xACA3	0x0412	#CYRILLIC CAPITAL LETTER VE
+0xACA4	0x0413	#CYRILLIC CAPITAL LETTER GHE
+0xACA5	0x0414	#CYRILLIC CAPITAL LETTER DE
+0xACA6	0x0415	#CYRILLIC CAPITAL LETTER IE
+0xACA7	0x0401	#CYRILLIC CAPITAL LETTER IO
+0xACA8	0x0416	#CYRILLIC CAPITAL LETTER ZHE
+0xACA9	0x0417	#CYRILLIC CAPITAL LETTER ZE
+0xACAA	0x0418	#CYRILLIC CAPITAL LETTER I
+0xACAB	0x0419	#CYRILLIC CAPITAL LETTER SHORT I
+0xACAC	0x041A	#CYRILLIC CAPITAL LETTER KA
+0xACAD	0x041B	#CYRILLIC CAPITAL LETTER EL
+0xACAE	0x041C	#CYRILLIC CAPITAL LETTER EM
+0xACAF	0x041D	#CYRILLIC CAPITAL LETTER EN
+0xACB0	0x041E	#CYRILLIC CAPITAL LETTER O
+0xACB1	0x041F	#CYRILLIC CAPITAL LETTER PE
+0xACB2	0x0420	#CYRILLIC CAPITAL LETTER ER
+0xACB3	0x0421	#CYRILLIC CAPITAL LETTER ES
+0xACB4	0x0422	#CYRILLIC CAPITAL LETTER TE
+0xACB5	0x0423	#CYRILLIC CAPITAL LETTER U
+0xACB6	0x0424	#CYRILLIC CAPITAL LETTER EF
+0xACB7	0x0425	#CYRILLIC CAPITAL LETTER HA
+0xACB8	0x0426	#CYRILLIC CAPITAL LETTER TSE
+0xACB9	0x0427	#CYRILLIC CAPITAL LETTER CHE
+0xACBA	0x0428	#CYRILLIC CAPITAL LETTER SHA
+0xACBB	0x0429	#CYRILLIC CAPITAL LETTER SHCHA
+0xACBC	0x042A	#CYRILLIC CAPITAL LETTER HARD SIGN
+0xACBD	0x042B	#CYRILLIC CAPITAL LETTER YERU
+0xACBE	0x042C	#CYRILLIC CAPITAL LETTER SOFT SIGN
+0xACBF	0x042D	#CYRILLIC CAPITAL LETTER E
+0xACC0	0x042E	#CYRILLIC CAPITAL LETTER YU
+0xACC1	0x042F	#CYRILLIC CAPITAL LETTER YA
+0xACD1	0x0430	#CYRILLIC SMALL LETTER A
+0xACD2	0x0431	#CYRILLIC SMALL LETTER BE
+0xACD3	0x0432	#CYRILLIC SMALL LETTER VE
+0xACD4	0x0433	#CYRILLIC SMALL LETTER GHE
+0xACD5	0x0434	#CYRILLIC SMALL LETTER DE
+0xACD6	0x0435	#CYRILLIC SMALL LETTER IE
+0xACD7	0x0451	#CYRILLIC SMALL LETTER IO
+0xACD8	0x0436	#CYRILLIC SMALL LETTER ZHE
+0xACD9	0x0437	#CYRILLIC SMALL LETTER ZE
+0xACDA	0x0438	#CYRILLIC SMALL LETTER I
+0xACDB	0x0439	#CYRILLIC SMALL LETTER SHORT I
+0xACDC	0x043A	#CYRILLIC SMALL LETTER KA
+0xACDD	0x043B	#CYRILLIC SMALL LETTER EL
+0xACDE	0x043C	#CYRILLIC SMALL LETTER EM
+0xACDF	0x043D	#CYRILLIC SMALL LETTER EN
+0xACE0	0x043E	#CYRILLIC SMALL LETTER O
+0xACE1	0x043F	#CYRILLIC SMALL LETTER PE
+0xACE2	0x0440	#CYRILLIC SMALL LETTER ER
+0xACE3	0x0441	#CYRILLIC SMALL LETTER ES
+0xACE4	0x0442	#CYRILLIC SMALL LETTER TE
+0xACE5	0x0443	#CYRILLIC SMALL LETTER U
+0xACE6	0x0444	#CYRILLIC SMALL LETTER EF
+0xACE7	0x0445	#CYRILLIC SMALL LETTER HA
+0xACE8	0x0446	#CYRILLIC SMALL LETTER TSE
+0xACE9	0x0447	#CYRILLIC SMALL LETTER CHE
+0xACEA	0x0448	#CYRILLIC SMALL LETTER SHA
+0xACEB	0x0449	#CYRILLIC SMALL LETTER SHCHA
+0xACEC	0x044A	#CYRILLIC SMALL LETTER HARD SIGN
+0xACED	0x044B	#CYRILLIC SMALL LETTER YERU
+0xACEE	0x044C	#CYRILLIC SMALL LETTER SOFT SIGN
+0xACEF	0x044D	#CYRILLIC SMALL LETTER E
+0xACF0	0x044E	#CYRILLIC SMALL LETTER YU
+0xACF1	0x044F	#CYRILLIC SMALL LETTER YA
+0xAD41	0xCD61	#HANGUL SYLLABLE CHIEUCH OE NIEUNCIEUC
+0xAD42	0xCD62	#HANGUL SYLLABLE CHIEUCH OE NIEUNHIEUH
+0xAD43	0xCD63	#HANGUL SYLLABLE CHIEUCH OE TIKEUT
+0xAD44	0xCD65	#HANGUL SYLLABLE CHIEUCH OE RIEULKIYEOK
+0xAD45	0xCD66	#HANGUL SYLLABLE CHIEUCH OE RIEULMIEUM
+0xAD46	0xCD67	#HANGUL SYLLABLE CHIEUCH OE RIEULPIEUP
+0xAD47	0xCD68	#HANGUL SYLLABLE CHIEUCH OE RIEULSIOS
+0xAD48	0xCD69	#HANGUL SYLLABLE CHIEUCH OE RIEULTHIEUTH
+0xAD49	0xCD6A	#HANGUL SYLLABLE CHIEUCH OE RIEULPHIEUPH
+0xAD4A	0xCD6B	#HANGUL SYLLABLE CHIEUCH OE RIEULHIEUH
+0xAD4B	0xCD6E	#HANGUL SYLLABLE CHIEUCH OE PIEUPSIOS
+0xAD4C	0xCD70	#HANGUL SYLLABLE CHIEUCH OE SSANGSIOS
+0xAD4D	0xCD72	#HANGUL SYLLABLE CHIEUCH OE CIEUC
+0xAD4E	0xCD73	#HANGUL SYLLABLE CHIEUCH OE CHIEUCH
+0xAD4F	0xCD74	#HANGUL SYLLABLE CHIEUCH OE KHIEUKH
+0xAD50	0xCD75	#HANGUL SYLLABLE CHIEUCH OE THIEUTH
+0xAD51	0xCD76	#HANGUL SYLLABLE CHIEUCH OE PHIEUPH
+0xAD52	0xCD77	#HANGUL SYLLABLE CHIEUCH OE HIEUH
+0xAD53	0xCD79	#HANGUL SYLLABLE CHIEUCH YO KIYEOK
+0xAD54	0xCD7A	#HANGUL SYLLABLE CHIEUCH YO SSANGKIYEOK
+0xAD55	0xCD7B	#HANGUL SYLLABLE CHIEUCH YO KIYEOKSIOS
+0xAD56	0xCD7C	#HANGUL SYLLABLE CHIEUCH YO NIEUN
+0xAD57	0xCD7D	#HANGUL SYLLABLE CHIEUCH YO NIEUNCIEUC
+0xAD58	0xCD7E	#HANGUL SYLLABLE CHIEUCH YO NIEUNHIEUH
+0xAD59	0xCD7F	#HANGUL SYLLABLE CHIEUCH YO TIKEUT
+0xAD5A	0xCD80	#HANGUL SYLLABLE CHIEUCH YO RIEUL
+0xAD61	0xCD81	#HANGUL SYLLABLE CHIEUCH YO RIEULKIYEOK
+0xAD62	0xCD82	#HANGUL SYLLABLE CHIEUCH YO RIEULMIEUM
+0xAD63	0xCD83	#HANGUL SYLLABLE CHIEUCH YO RIEULPIEUP
+0xAD64	0xCD84	#HANGUL SYLLABLE CHIEUCH YO RIEULSIOS
+0xAD65	0xCD85	#HANGUL SYLLABLE CHIEUCH YO RIEULTHIEUTH
+0xAD66	0xCD86	#HANGUL SYLLABLE CHIEUCH YO RIEULPHIEUPH
+0xAD67	0xCD87	#HANGUL SYLLABLE CHIEUCH YO RIEULHIEUH
+0xAD68	0xCD89	#HANGUL SYLLABLE CHIEUCH YO PIEUP
+0xAD69	0xCD8A	#HANGUL SYLLABLE CHIEUCH YO PIEUPSIOS
+0xAD6A	0xCD8B	#HANGUL SYLLABLE CHIEUCH YO SIOS
+0xAD6B	0xCD8C	#HANGUL SYLLABLE CHIEUCH YO SSANGSIOS
+0xAD6C	0xCD8D	#HANGUL SYLLABLE CHIEUCH YO IEUNG
+0xAD6D	0xCD8E	#HANGUL SYLLABLE CHIEUCH YO CIEUC
+0xAD6E	0xCD8F	#HANGUL SYLLABLE CHIEUCH YO CHIEUCH
+0xAD6F	0xCD90	#HANGUL SYLLABLE CHIEUCH YO KHIEUKH
+0xAD70	0xCD91	#HANGUL SYLLABLE CHIEUCH YO THIEUTH
+0xAD71	0xCD92	#HANGUL SYLLABLE CHIEUCH YO PHIEUPH
+0xAD72	0xCD93	#HANGUL SYLLABLE CHIEUCH YO HIEUH
+0xAD73	0xCD96	#HANGUL SYLLABLE CHIEUCH U SSANGKIYEOK
+0xAD74	0xCD97	#HANGUL SYLLABLE CHIEUCH U KIYEOKSIOS
+0xAD75	0xCD99	#HANGUL SYLLABLE CHIEUCH U NIEUNCIEUC
+0xAD76	0xCD9A	#HANGUL SYLLABLE CHIEUCH U NIEUNHIEUH
+0xAD77	0xCD9B	#HANGUL SYLLABLE CHIEUCH U TIKEUT
+0xAD78	0xCD9D	#HANGUL SYLLABLE CHIEUCH U RIEULKIYEOK
+0xAD79	0xCD9E	#HANGUL SYLLABLE CHIEUCH U RIEULMIEUM
+0xAD7A	0xCD9F	#HANGUL SYLLABLE CHIEUCH U RIEULPIEUP
+0xAD81	0xCDA0	#HANGUL SYLLABLE CHIEUCH U RIEULSIOS
+0xAD82	0xCDA1	#HANGUL SYLLABLE CHIEUCH U RIEULTHIEUTH
+0xAD83	0xCDA2	#HANGUL SYLLABLE CHIEUCH U RIEULPHIEUPH
+0xAD84	0xCDA3	#HANGUL SYLLABLE CHIEUCH U RIEULHIEUH
+0xAD85	0xCDA6	#HANGUL SYLLABLE CHIEUCH U PIEUPSIOS
+0xAD86	0xCDA8	#HANGUL SYLLABLE CHIEUCH U SSANGSIOS
+0xAD87	0xCDAA	#HANGUL SYLLABLE CHIEUCH U CIEUC
+0xAD88	0xCDAB	#HANGUL SYLLABLE CHIEUCH U CHIEUCH
+0xAD89	0xCDAC	#HANGUL SYLLABLE CHIEUCH U KHIEUKH
+0xAD8A	0xCDAD	#HANGUL SYLLABLE CHIEUCH U THIEUTH
+0xAD8B	0xCDAE	#HANGUL SYLLABLE CHIEUCH U PHIEUPH
+0xAD8C	0xCDAF	#HANGUL SYLLABLE CHIEUCH U HIEUH
+0xAD8D	0xCDB1	#HANGUL SYLLABLE CHIEUCH WEO KIYEOK
+0xAD8E	0xCDB2	#HANGUL SYLLABLE CHIEUCH WEO SSANGKIYEOK
+0xAD8F	0xCDB3	#HANGUL SYLLABLE CHIEUCH WEO KIYEOKSIOS
+0xAD90	0xCDB4	#HANGUL SYLLABLE CHIEUCH WEO NIEUN
+0xAD91	0xCDB5	#HANGUL SYLLABLE CHIEUCH WEO NIEUNCIEUC
+0xAD92	0xCDB6	#HANGUL SYLLABLE CHIEUCH WEO NIEUNHIEUH
+0xAD93	0xCDB7	#HANGUL SYLLABLE CHIEUCH WEO TIKEUT
+0xAD94	0xCDB8	#HANGUL SYLLABLE CHIEUCH WEO RIEUL
+0xAD95	0xCDB9	#HANGUL SYLLABLE CHIEUCH WEO RIEULKIYEOK
+0xAD96	0xCDBA	#HANGUL SYLLABLE CHIEUCH WEO RIEULMIEUM
+0xAD97	0xCDBB	#HANGUL SYLLABLE CHIEUCH WEO RIEULPIEUP
+0xAD98	0xCDBC	#HANGUL SYLLABLE CHIEUCH WEO RIEULSIOS
+0xAD99	0xCDBD	#HANGUL SYLLABLE CHIEUCH WEO RIEULTHIEUTH
+0xAD9A	0xCDBE	#HANGUL SYLLABLE CHIEUCH WEO RIEULPHIEUPH
+0xAD9B	0xCDBF	#HANGUL SYLLABLE CHIEUCH WEO RIEULHIEUH
+0xAD9C	0xCDC0	#HANGUL SYLLABLE CHIEUCH WEO MIEUM
+0xAD9D	0xCDC1	#HANGUL SYLLABLE CHIEUCH WEO PIEUP
+0xAD9E	0xCDC2	#HANGUL SYLLABLE CHIEUCH WEO PIEUPSIOS
+0xAD9F	0xCDC3	#HANGUL SYLLABLE CHIEUCH WEO SIOS
+0xADA0	0xCDC5	#HANGUL SYLLABLE CHIEUCH WEO IEUNG
+0xAE41	0xCDC6	#HANGUL SYLLABLE CHIEUCH WEO CIEUC
+0xAE42	0xCDC7	#HANGUL SYLLABLE CHIEUCH WEO CHIEUCH
+0xAE43	0xCDC8	#HANGUL SYLLABLE CHIEUCH WEO KHIEUKH
+0xAE44	0xCDC9	#HANGUL SYLLABLE CHIEUCH WEO THIEUTH
+0xAE45	0xCDCA	#HANGUL SYLLABLE CHIEUCH WEO PHIEUPH
+0xAE46	0xCDCB	#HANGUL SYLLABLE CHIEUCH WEO HIEUH
+0xAE47	0xCDCD	#HANGUL SYLLABLE CHIEUCH WE KIYEOK
+0xAE48	0xCDCE	#HANGUL SYLLABLE CHIEUCH WE SSANGKIYEOK
+0xAE49	0xCDCF	#HANGUL SYLLABLE CHIEUCH WE KIYEOKSIOS
+0xAE4A	0xCDD1	#HANGUL SYLLABLE CHIEUCH WE NIEUNCIEUC
+0xAE4B	0xCDD2	#HANGUL SYLLABLE CHIEUCH WE NIEUNHIEUH
+0xAE4C	0xCDD3	#HANGUL SYLLABLE CHIEUCH WE TIKEUT
+0xAE4D	0xCDD4	#HANGUL SYLLABLE CHIEUCH WE RIEUL
+0xAE4E	0xCDD5	#HANGUL SYLLABLE CHIEUCH WE RIEULKIYEOK
+0xAE4F	0xCDD6	#HANGUL SYLLABLE CHIEUCH WE RIEULMIEUM
+0xAE50	0xCDD7	#HANGUL SYLLABLE CHIEUCH WE RIEULPIEUP
+0xAE51	0xCDD8	#HANGUL SYLLABLE CHIEUCH WE RIEULSIOS
+0xAE52	0xCDD9	#HANGUL SYLLABLE CHIEUCH WE RIEULTHIEUTH
+0xAE53	0xCDDA	#HANGUL SYLLABLE CHIEUCH WE RIEULPHIEUPH
+0xAE54	0xCDDB	#HANGUL SYLLABLE CHIEUCH WE RIEULHIEUH
+0xAE55	0xCDDC	#HANGUL SYLLABLE CHIEUCH WE MIEUM
+0xAE56	0xCDDD	#HANGUL SYLLABLE CHIEUCH WE PIEUP
+0xAE57	0xCDDE	#HANGUL SYLLABLE CHIEUCH WE PIEUPSIOS
+0xAE58	0xCDDF	#HANGUL SYLLABLE CHIEUCH WE SIOS
+0xAE59	0xCDE0	#HANGUL SYLLABLE CHIEUCH WE SSANGSIOS
+0xAE5A	0xCDE1	#HANGUL SYLLABLE CHIEUCH WE IEUNG
+0xAE61	0xCDE2	#HANGUL SYLLABLE CHIEUCH WE CIEUC
+0xAE62	0xCDE3	#HANGUL SYLLABLE CHIEUCH WE CHIEUCH
+0xAE63	0xCDE4	#HANGUL SYLLABLE CHIEUCH WE KHIEUKH
+0xAE64	0xCDE5	#HANGUL SYLLABLE CHIEUCH WE THIEUTH
+0xAE65	0xCDE6	#HANGUL SYLLABLE CHIEUCH WE PHIEUPH
+0xAE66	0xCDE7	#HANGUL SYLLABLE CHIEUCH WE HIEUH
+0xAE67	0xCDE9	#HANGUL SYLLABLE CHIEUCH WI KIYEOK
+0xAE68	0xCDEA	#HANGUL SYLLABLE CHIEUCH WI SSANGKIYEOK
+0xAE69	0xCDEB	#HANGUL SYLLABLE CHIEUCH WI KIYEOKSIOS
+0xAE6A	0xCDED	#HANGUL SYLLABLE CHIEUCH WI NIEUNCIEUC
+0xAE6B	0xCDEE	#HANGUL SYLLABLE CHIEUCH WI NIEUNHIEUH
+0xAE6C	0xCDEF	#HANGUL SYLLABLE CHIEUCH WI TIKEUT
+0xAE6D	0xCDF1	#HANGUL SYLLABLE CHIEUCH WI RIEULKIYEOK
+0xAE6E	0xCDF2	#HANGUL SYLLABLE CHIEUCH WI RIEULMIEUM
+0xAE6F	0xCDF3	#HANGUL SYLLABLE CHIEUCH WI RIEULPIEUP
+0xAE70	0xCDF4	#HANGUL SYLLABLE CHIEUCH WI RIEULSIOS
+0xAE71	0xCDF5	#HANGUL SYLLABLE CHIEUCH WI RIEULTHIEUTH
+0xAE72	0xCDF6	#HANGUL SYLLABLE CHIEUCH WI RIEULPHIEUPH
+0xAE73	0xCDF7	#HANGUL SYLLABLE CHIEUCH WI RIEULHIEUH
+0xAE74	0xCDFA	#HANGUL SYLLABLE CHIEUCH WI PIEUPSIOS
+0xAE75	0xCDFC	#HANGUL SYLLABLE CHIEUCH WI SSANGSIOS
+0xAE76	0xCDFE	#HANGUL SYLLABLE CHIEUCH WI CIEUC
+0xAE77	0xCDFF	#HANGUL SYLLABLE CHIEUCH WI CHIEUCH
+0xAE78	0xCE00	#HANGUL SYLLABLE CHIEUCH WI KHIEUKH
+0xAE79	0xCE01	#HANGUL SYLLABLE CHIEUCH WI THIEUTH
+0xAE7A	0xCE02	#HANGUL SYLLABLE CHIEUCH WI PHIEUPH
+0xAE81	0xCE03	#HANGUL SYLLABLE CHIEUCH WI HIEUH
+0xAE82	0xCE05	#HANGUL SYLLABLE CHIEUCH YU KIYEOK
+0xAE83	0xCE06	#HANGUL SYLLABLE CHIEUCH YU SSANGKIYEOK
+0xAE84	0xCE07	#HANGUL SYLLABLE CHIEUCH YU KIYEOKSIOS
+0xAE85	0xCE09	#HANGUL SYLLABLE CHIEUCH YU NIEUNCIEUC
+0xAE86	0xCE0A	#HANGUL SYLLABLE CHIEUCH YU NIEUNHIEUH
+0xAE87	0xCE0B	#HANGUL SYLLABLE CHIEUCH YU TIKEUT
+0xAE88	0xCE0D	#HANGUL SYLLABLE CHIEUCH YU RIEULKIYEOK
+0xAE89	0xCE0E	#HANGUL SYLLABLE CHIEUCH YU RIEULMIEUM
+0xAE8A	0xCE0F	#HANGUL SYLLABLE CHIEUCH YU RIEULPIEUP
+0xAE8B	0xCE10	#HANGUL SYLLABLE CHIEUCH YU RIEULSIOS
+0xAE8C	0xCE11	#HANGUL SYLLABLE CHIEUCH YU RIEULTHIEUTH
+0xAE8D	0xCE12	#HANGUL SYLLABLE CHIEUCH YU RIEULPHIEUPH
+0xAE8E	0xCE13	#HANGUL SYLLABLE CHIEUCH YU RIEULHIEUH
+0xAE8F	0xCE15	#HANGUL SYLLABLE CHIEUCH YU PIEUP
+0xAE90	0xCE16	#HANGUL SYLLABLE CHIEUCH YU PIEUPSIOS
+0xAE91	0xCE17	#HANGUL SYLLABLE CHIEUCH YU SIOS
+0xAE92	0xCE18	#HANGUL SYLLABLE CHIEUCH YU SSANGSIOS
+0xAE93	0xCE1A	#HANGUL SYLLABLE CHIEUCH YU CIEUC
+0xAE94	0xCE1B	#HANGUL SYLLABLE CHIEUCH YU CHIEUCH
+0xAE95	0xCE1C	#HANGUL SYLLABLE CHIEUCH YU KHIEUKH
+0xAE96	0xCE1D	#HANGUL SYLLABLE CHIEUCH YU THIEUTH
+0xAE97	0xCE1E	#HANGUL SYLLABLE CHIEUCH YU PHIEUPH
+0xAE98	0xCE1F	#HANGUL SYLLABLE CHIEUCH YU HIEUH
+0xAE99	0xCE22	#HANGUL SYLLABLE CHIEUCH EU SSANGKIYEOK
+0xAE9A	0xCE23	#HANGUL SYLLABLE CHIEUCH EU KIYEOKSIOS
+0xAE9B	0xCE25	#HANGUL SYLLABLE CHIEUCH EU NIEUNCIEUC
+0xAE9C	0xCE26	#HANGUL SYLLABLE CHIEUCH EU NIEUNHIEUH
+0xAE9D	0xCE27	#HANGUL SYLLABLE CHIEUCH EU TIKEUT
+0xAE9E	0xCE29	#HANGUL SYLLABLE CHIEUCH EU RIEULKIYEOK
+0xAE9F	0xCE2A	#HANGUL SYLLABLE CHIEUCH EU RIEULMIEUM
+0xAEA0	0xCE2B	#HANGUL SYLLABLE CHIEUCH EU RIEULPIEUP
+0xAF41	0xCE2C	#HANGUL SYLLABLE CHIEUCH EU RIEULSIOS
+0xAF42	0xCE2D	#HANGUL SYLLABLE CHIEUCH EU RIEULTHIEUTH
+0xAF43	0xCE2E	#HANGUL SYLLABLE CHIEUCH EU RIEULPHIEUPH
+0xAF44	0xCE2F	#HANGUL SYLLABLE CHIEUCH EU RIEULHIEUH
+0xAF45	0xCE32	#HANGUL SYLLABLE CHIEUCH EU PIEUPSIOS
+0xAF46	0xCE34	#HANGUL SYLLABLE CHIEUCH EU SSANGSIOS
+0xAF47	0xCE36	#HANGUL SYLLABLE CHIEUCH EU CIEUC
+0xAF48	0xCE37	#HANGUL SYLLABLE CHIEUCH EU CHIEUCH
+0xAF49	0xCE38	#HANGUL SYLLABLE CHIEUCH EU KHIEUKH
+0xAF4A	0xCE39	#HANGUL SYLLABLE CHIEUCH EU THIEUTH
+0xAF4B	0xCE3A	#HANGUL SYLLABLE CHIEUCH EU PHIEUPH
+0xAF4C	0xCE3B	#HANGUL SYLLABLE CHIEUCH EU HIEUH
+0xAF4D	0xCE3C	#HANGUL SYLLABLE CHIEUCH YI
+0xAF4E	0xCE3D	#HANGUL SYLLABLE CHIEUCH YI KIYEOK
+0xAF4F	0xCE3E	#HANGUL SYLLABLE CHIEUCH YI SSANGKIYEOK
+0xAF50	0xCE3F	#HANGUL SYLLABLE CHIEUCH YI KIYEOKSIOS
+0xAF51	0xCE40	#HANGUL SYLLABLE CHIEUCH YI NIEUN
+0xAF52	0xCE41	#HANGUL SYLLABLE CHIEUCH YI NIEUNCIEUC
+0xAF53	0xCE42	#HANGUL SYLLABLE CHIEUCH YI NIEUNHIEUH
+0xAF54	0xCE43	#HANGUL SYLLABLE CHIEUCH YI TIKEUT
+0xAF55	0xCE44	#HANGUL SYLLABLE CHIEUCH YI RIEUL
+0xAF56	0xCE45	#HANGUL SYLLABLE CHIEUCH YI RIEULKIYEOK
+0xAF57	0xCE46	#HANGUL SYLLABLE CHIEUCH YI RIEULMIEUM
+0xAF58	0xCE47	#HANGUL SYLLABLE CHIEUCH YI RIEULPIEUP
+0xAF59	0xCE48	#HANGUL SYLLABLE CHIEUCH YI RIEULSIOS
+0xAF5A	0xCE49	#HANGUL SYLLABLE CHIEUCH YI RIEULTHIEUTH
+0xAF61	0xCE4A	#HANGUL SYLLABLE CHIEUCH YI RIEULPHIEUPH
+0xAF62	0xCE4B	#HANGUL SYLLABLE CHIEUCH YI RIEULHIEUH
+0xAF63	0xCE4C	#HANGUL SYLLABLE CHIEUCH YI MIEUM
+0xAF64	0xCE4D	#HANGUL SYLLABLE CHIEUCH YI PIEUP
+0xAF65	0xCE4E	#HANGUL SYLLABLE CHIEUCH YI PIEUPSIOS
+0xAF66	0xCE4F	#HANGUL SYLLABLE CHIEUCH YI SIOS
+0xAF67	0xCE50	#HANGUL SYLLABLE CHIEUCH YI SSANGSIOS
+0xAF68	0xCE51	#HANGUL SYLLABLE CHIEUCH YI IEUNG
+0xAF69	0xCE52	#HANGUL SYLLABLE CHIEUCH YI CIEUC
+0xAF6A	0xCE53	#HANGUL SYLLABLE CHIEUCH YI CHIEUCH
+0xAF6B	0xCE54	#HANGUL SYLLABLE CHIEUCH YI KHIEUKH
+0xAF6C	0xCE55	#HANGUL SYLLABLE CHIEUCH YI THIEUTH
+0xAF6D	0xCE56	#HANGUL SYLLABLE CHIEUCH YI PHIEUPH
+0xAF6E	0xCE57	#HANGUL SYLLABLE CHIEUCH YI HIEUH
+0xAF6F	0xCE5A	#HANGUL SYLLABLE CHIEUCH I SSANGKIYEOK
+0xAF70	0xCE5B	#HANGUL SYLLABLE CHIEUCH I KIYEOKSIOS
+0xAF71	0xCE5D	#HANGUL SYLLABLE CHIEUCH I NIEUNCIEUC
+0xAF72	0xCE5E	#HANGUL SYLLABLE CHIEUCH I NIEUNHIEUH
+0xAF73	0xCE62	#HANGUL SYLLABLE CHIEUCH I RIEULMIEUM
+0xAF74	0xCE63	#HANGUL SYLLABLE CHIEUCH I RIEULPIEUP
+0xAF75	0xCE64	#HANGUL SYLLABLE CHIEUCH I RIEULSIOS
+0xAF76	0xCE65	#HANGUL SYLLABLE CHIEUCH I RIEULTHIEUTH
+0xAF77	0xCE66	#HANGUL SYLLABLE CHIEUCH I RIEULPHIEUPH
+0xAF78	0xCE67	#HANGUL SYLLABLE CHIEUCH I RIEULHIEUH
+0xAF79	0xCE6A	#HANGUL SYLLABLE CHIEUCH I PIEUPSIOS
+0xAF7A	0xCE6C	#HANGUL SYLLABLE CHIEUCH I SSANGSIOS
+0xAF81	0xCE6E	#HANGUL SYLLABLE CHIEUCH I CIEUC
+0xAF82	0xCE6F	#HANGUL SYLLABLE CHIEUCH I CHIEUCH
+0xAF83	0xCE70	#HANGUL SYLLABLE CHIEUCH I KHIEUKH
+0xAF84	0xCE71	#HANGUL SYLLABLE CHIEUCH I THIEUTH
+0xAF85	0xCE72	#HANGUL SYLLABLE CHIEUCH I PHIEUPH
+0xAF86	0xCE73	#HANGUL SYLLABLE CHIEUCH I HIEUH
+0xAF87	0xCE76	#HANGUL SYLLABLE KHIEUKH A SSANGKIYEOK
+0xAF88	0xCE77	#HANGUL SYLLABLE KHIEUKH A KIYEOKSIOS
+0xAF89	0xCE79	#HANGUL SYLLABLE KHIEUKH A NIEUNCIEUC
+0xAF8A	0xCE7A	#HANGUL SYLLABLE KHIEUKH A NIEUNHIEUH
+0xAF8B	0xCE7B	#HANGUL SYLLABLE KHIEUKH A TIKEUT
+0xAF8C	0xCE7D	#HANGUL SYLLABLE KHIEUKH A RIEULKIYEOK
+0xAF8D	0xCE7E	#HANGUL SYLLABLE KHIEUKH A RIEULMIEUM
+0xAF8E	0xCE7F	#HANGUL SYLLABLE KHIEUKH A RIEULPIEUP
+0xAF8F	0xCE80	#HANGUL SYLLABLE KHIEUKH A RIEULSIOS
+0xAF90	0xCE81	#HANGUL SYLLABLE KHIEUKH A RIEULTHIEUTH
+0xAF91	0xCE82	#HANGUL SYLLABLE KHIEUKH A RIEULPHIEUPH
+0xAF92	0xCE83	#HANGUL SYLLABLE KHIEUKH A RIEULHIEUH
+0xAF93	0xCE86	#HANGUL SYLLABLE KHIEUKH A PIEUPSIOS
+0xAF94	0xCE88	#HANGUL SYLLABLE KHIEUKH A SSANGSIOS
+0xAF95	0xCE8A	#HANGUL SYLLABLE KHIEUKH A CIEUC
+0xAF96	0xCE8B	#HANGUL SYLLABLE KHIEUKH A CHIEUCH
+0xAF97	0xCE8C	#HANGUL SYLLABLE KHIEUKH A KHIEUKH
+0xAF98	0xCE8D	#HANGUL SYLLABLE KHIEUKH A THIEUTH
+0xAF99	0xCE8E	#HANGUL SYLLABLE KHIEUKH A PHIEUPH
+0xAF9A	0xCE8F	#HANGUL SYLLABLE KHIEUKH A HIEUH
+0xAF9B	0xCE92	#HANGUL SYLLABLE KHIEUKH AE SSANGKIYEOK
+0xAF9C	0xCE93	#HANGUL SYLLABLE KHIEUKH AE KIYEOKSIOS
+0xAF9D	0xCE95	#HANGUL SYLLABLE KHIEUKH AE NIEUNCIEUC
+0xAF9E	0xCE96	#HANGUL SYLLABLE KHIEUKH AE NIEUNHIEUH
+0xAF9F	0xCE97	#HANGUL SYLLABLE KHIEUKH AE TIKEUT
+0xAFA0	0xCE99	#HANGUL SYLLABLE KHIEUKH AE RIEULKIYEOK
+0xB041	0xCE9A	#HANGUL SYLLABLE KHIEUKH AE RIEULMIEUM
+0xB042	0xCE9B	#HANGUL SYLLABLE KHIEUKH AE RIEULPIEUP
+0xB043	0xCE9C	#HANGUL SYLLABLE KHIEUKH AE RIEULSIOS
+0xB044	0xCE9D	#HANGUL SYLLABLE KHIEUKH AE RIEULTHIEUTH
+0xB045	0xCE9E	#HANGUL SYLLABLE KHIEUKH AE RIEULPHIEUPH
+0xB046	0xCE9F	#HANGUL SYLLABLE KHIEUKH AE RIEULHIEUH
+0xB047	0xCEA2	#HANGUL SYLLABLE KHIEUKH AE PIEUPSIOS
+0xB048	0xCEA6	#HANGUL SYLLABLE KHIEUKH AE CIEUC
+0xB049	0xCEA7	#HANGUL SYLLABLE KHIEUKH AE CHIEUCH
+0xB04A	0xCEA8	#HANGUL SYLLABLE KHIEUKH AE KHIEUKH
+0xB04B	0xCEA9	#HANGUL SYLLABLE KHIEUKH AE THIEUTH
+0xB04C	0xCEAA	#HANGUL SYLLABLE KHIEUKH AE PHIEUPH
+0xB04D	0xCEAB	#HANGUL SYLLABLE KHIEUKH AE HIEUH
+0xB04E	0xCEAE	#HANGUL SYLLABLE KHIEUKH YA SSANGKIYEOK
+0xB04F	0xCEAF	#HANGUL SYLLABLE KHIEUKH YA KIYEOKSIOS
+0xB050	0xCEB0	#HANGUL SYLLABLE KHIEUKH YA NIEUN
+0xB051	0xCEB1	#HANGUL SYLLABLE KHIEUKH YA NIEUNCIEUC
+0xB052	0xCEB2	#HANGUL SYLLABLE KHIEUKH YA NIEUNHIEUH
+0xB053	0xCEB3	#HANGUL SYLLABLE KHIEUKH YA TIKEUT
+0xB054	0xCEB4	#HANGUL SYLLABLE KHIEUKH YA RIEUL
+0xB055	0xCEB5	#HANGUL SYLLABLE KHIEUKH YA RIEULKIYEOK
+0xB056	0xCEB6	#HANGUL SYLLABLE KHIEUKH YA RIEULMIEUM
+0xB057	0xCEB7	#HANGUL SYLLABLE KHIEUKH YA RIEULPIEUP
+0xB058	0xCEB8	#HANGUL SYLLABLE KHIEUKH YA RIEULSIOS
+0xB059	0xCEB9	#HANGUL SYLLABLE KHIEUKH YA RIEULTHIEUTH
+0xB05A	0xCEBA	#HANGUL SYLLABLE KHIEUKH YA RIEULPHIEUPH
+0xB061	0xCEBB	#HANGUL SYLLABLE KHIEUKH YA RIEULHIEUH
+0xB062	0xCEBC	#HANGUL SYLLABLE KHIEUKH YA MIEUM
+0xB063	0xCEBD	#HANGUL SYLLABLE KHIEUKH YA PIEUP
+0xB064	0xCEBE	#HANGUL SYLLABLE KHIEUKH YA PIEUPSIOS
+0xB065	0xCEBF	#HANGUL SYLLABLE KHIEUKH YA SIOS
+0xB066	0xCEC0	#HANGUL SYLLABLE KHIEUKH YA SSANGSIOS
+0xB067	0xCEC2	#HANGUL SYLLABLE KHIEUKH YA CIEUC
+0xB068	0xCEC3	#HANGUL SYLLABLE KHIEUKH YA CHIEUCH
+0xB069	0xCEC4	#HANGUL SYLLABLE KHIEUKH YA KHIEUKH
+0xB06A	0xCEC5	#HANGUL SYLLABLE KHIEUKH YA THIEUTH
+0xB06B	0xCEC6	#HANGUL SYLLABLE KHIEUKH YA PHIEUPH
+0xB06C	0xCEC7	#HANGUL SYLLABLE KHIEUKH YA HIEUH
+0xB06D	0xCEC8	#HANGUL SYLLABLE KHIEUKH YAE
+0xB06E	0xCEC9	#HANGUL SYLLABLE KHIEUKH YAE KIYEOK
+0xB06F	0xCECA	#HANGUL SYLLABLE KHIEUKH YAE SSANGKIYEOK
+0xB070	0xCECB	#HANGUL SYLLABLE KHIEUKH YAE KIYEOKSIOS
+0xB071	0xCECC	#HANGUL SYLLABLE KHIEUKH YAE NIEUN
+0xB072	0xCECD	#HANGUL SYLLABLE KHIEUKH YAE NIEUNCIEUC
+0xB073	0xCECE	#HANGUL SYLLABLE KHIEUKH YAE NIEUNHIEUH
+0xB074	0xCECF	#HANGUL SYLLABLE KHIEUKH YAE TIKEUT
+0xB075	0xCED0	#HANGUL SYLLABLE KHIEUKH YAE RIEUL
+0xB076	0xCED1	#HANGUL SYLLABLE KHIEUKH YAE RIEULKIYEOK
+0xB077	0xCED2	#HANGUL SYLLABLE KHIEUKH YAE RIEULMIEUM
+0xB078	0xCED3	#HANGUL SYLLABLE KHIEUKH YAE RIEULPIEUP
+0xB079	0xCED4	#HANGUL SYLLABLE KHIEUKH YAE RIEULSIOS
+0xB07A	0xCED5	#HANGUL SYLLABLE KHIEUKH YAE RIEULTHIEUTH
+0xB081	0xCED6	#HANGUL SYLLABLE KHIEUKH YAE RIEULPHIEUPH
+0xB082	0xCED7	#HANGUL SYLLABLE KHIEUKH YAE RIEULHIEUH
+0xB083	0xCED8	#HANGUL SYLLABLE KHIEUKH YAE MIEUM
+0xB084	0xCED9	#HANGUL SYLLABLE KHIEUKH YAE PIEUP
+0xB085	0xCEDA	#HANGUL SYLLABLE KHIEUKH YAE PIEUPSIOS
+0xB086	0xCEDB	#HANGUL SYLLABLE KHIEUKH YAE SIOS
+0xB087	0xCEDC	#HANGUL SYLLABLE KHIEUKH YAE SSANGSIOS
+0xB088	0xCEDD	#HANGUL SYLLABLE KHIEUKH YAE IEUNG
+0xB089	0xCEDE	#HANGUL SYLLABLE KHIEUKH YAE CIEUC
+0xB08A	0xCEDF	#HANGUL SYLLABLE KHIEUKH YAE CHIEUCH
+0xB08B	0xCEE0	#HANGUL SYLLABLE KHIEUKH YAE KHIEUKH
+0xB08C	0xCEE1	#HANGUL SYLLABLE KHIEUKH YAE THIEUTH
+0xB08D	0xCEE2	#HANGUL SYLLABLE KHIEUKH YAE PHIEUPH
+0xB08E	0xCEE3	#HANGUL SYLLABLE KHIEUKH YAE HIEUH
+0xB08F	0xCEE6	#HANGUL SYLLABLE KHIEUKH EO SSANGKIYEOK
+0xB090	0xCEE7	#HANGUL SYLLABLE KHIEUKH EO KIYEOKSIOS
+0xB091	0xCEE9	#HANGUL SYLLABLE KHIEUKH EO NIEUNCIEUC
+0xB092	0xCEEA	#HANGUL SYLLABLE KHIEUKH EO NIEUNHIEUH
+0xB093	0xCEED	#HANGUL SYLLABLE KHIEUKH EO RIEULKIYEOK
+0xB094	0xCEEE	#HANGUL SYLLABLE KHIEUKH EO RIEULMIEUM
+0xB095	0xCEEF	#HANGUL SYLLABLE KHIEUKH EO RIEULPIEUP
+0xB096	0xCEF0	#HANGUL SYLLABLE KHIEUKH EO RIEULSIOS
+0xB097	0xCEF1	#HANGUL SYLLABLE KHIEUKH EO RIEULTHIEUTH
+0xB098	0xCEF2	#HANGUL SYLLABLE KHIEUKH EO RIEULPHIEUPH
+0xB099	0xCEF3	#HANGUL SYLLABLE KHIEUKH EO RIEULHIEUH
+0xB09A	0xCEF6	#HANGUL SYLLABLE KHIEUKH EO PIEUPSIOS
+0xB09B	0xCEFA	#HANGUL SYLLABLE KHIEUKH EO CIEUC
+0xB09C	0xCEFB	#HANGUL SYLLABLE KHIEUKH EO CHIEUCH
+0xB09D	0xCEFC	#HANGUL SYLLABLE KHIEUKH EO KHIEUKH
+0xB09E	0xCEFD	#HANGUL SYLLABLE KHIEUKH EO THIEUTH
+0xB09F	0xCEFE	#HANGUL SYLLABLE KHIEUKH EO PHIEUPH
+0xB0A0	0xCEFF	#HANGUL SYLLABLE KHIEUKH EO HIEUH
+0xB0A1	0xAC00	#HANGUL SYLLABLE KIYEOK A
+0xB0A2	0xAC01	#HANGUL SYLLABLE KIYEOK A KIYEOK
+0xB0A3	0xAC04	#HANGUL SYLLABLE KIYEOK A NIEUN
+0xB0A4	0xAC07	#HANGUL SYLLABLE KIYEOK A TIKEUT
+0xB0A5	0xAC08	#HANGUL SYLLABLE KIYEOK A RIEUL
+0xB0A6	0xAC09	#HANGUL SYLLABLE KIYEOK A RIEULKIYEOK
+0xB0A7	0xAC0A	#HANGUL SYLLABLE KIYEOK A RIEULMIEUM
+0xB0A8	0xAC10	#HANGUL SYLLABLE KIYEOK A MIEUM
+0xB0A9	0xAC11	#HANGUL SYLLABLE KIYEOK A PIEUP
+0xB0AA	0xAC12	#HANGUL SYLLABLE KIYEOK A PIEUPSIOS
+0xB0AB	0xAC13	#HANGUL SYLLABLE KIYEOK A SIOS
+0xB0AC	0xAC14	#HANGUL SYLLABLE KIYEOK A SSANGSIOS
+0xB0AD	0xAC15	#HANGUL SYLLABLE KIYEOK A IEUNG
+0xB0AE	0xAC16	#HANGUL SYLLABLE KIYEOK A CIEUC
+0xB0AF	0xAC17	#HANGUL SYLLABLE KIYEOK A CHIEUCH
+0xB0B0	0xAC19	#HANGUL SYLLABLE KIYEOK A THIEUTH
+0xB0B1	0xAC1A	#HANGUL SYLLABLE KIYEOK A PHIEUPH
+0xB0B2	0xAC1B	#HANGUL SYLLABLE KIYEOK A HIEUH
+0xB0B3	0xAC1C	#HANGUL SYLLABLE KIYEOK AE
+0xB0B4	0xAC1D	#HANGUL SYLLABLE KIYEOK AE KIYEOK
+0xB0B5	0xAC20	#HANGUL SYLLABLE KIYEOK AE NIEUN
+0xB0B6	0xAC24	#HANGUL SYLLABLE KIYEOK AE RIEUL
+0xB0B7	0xAC2C	#HANGUL SYLLABLE KIYEOK AE MIEUM
+0xB0B8	0xAC2D	#HANGUL SYLLABLE KIYEOK AE PIEUP
+0xB0B9	0xAC2F	#HANGUL SYLLABLE KIYEOK AE SIOS
+0xB0BA	0xAC30	#HANGUL SYLLABLE KIYEOK AE SSANGSIOS
+0xB0BB	0xAC31	#HANGUL SYLLABLE KIYEOK AE IEUNG
+0xB0BC	0xAC38	#HANGUL SYLLABLE KIYEOK YA
+0xB0BD	0xAC39	#HANGUL SYLLABLE KIYEOK YA KIYEOK
+0xB0BE	0xAC3C	#HANGUL SYLLABLE KIYEOK YA NIEUN
+0xB0BF	0xAC40	#HANGUL SYLLABLE KIYEOK YA RIEUL
+0xB0C0	0xAC4B	#HANGUL SYLLABLE KIYEOK YA SIOS
+0xB0C1	0xAC4D	#HANGUL SYLLABLE KIYEOK YA IEUNG
+0xB0C2	0xAC54	#HANGUL SYLLABLE KIYEOK YAE
+0xB0C3	0xAC58	#HANGUL SYLLABLE KIYEOK YAE NIEUN
+0xB0C4	0xAC5C	#HANGUL SYLLABLE KIYEOK YAE RIEUL
+0xB0C5	0xAC70	#HANGUL SYLLABLE KIYEOK EO
+0xB0C6	0xAC71	#HANGUL SYLLABLE KIYEOK EO KIYEOK
+0xB0C7	0xAC74	#HANGUL SYLLABLE KIYEOK EO NIEUN
+0xB0C8	0xAC77	#HANGUL SYLLABLE KIYEOK EO TIKEUT
+0xB0C9	0xAC78	#HANGUL SYLLABLE KIYEOK EO RIEUL
+0xB0CA	0xAC7A	#HANGUL SYLLABLE KIYEOK EO RIEULMIEUM
+0xB0CB	0xAC80	#HANGUL SYLLABLE KIYEOK EO MIEUM
+0xB0CC	0xAC81	#HANGUL SYLLABLE KIYEOK EO PIEUP
+0xB0CD	0xAC83	#HANGUL SYLLABLE KIYEOK EO SIOS
+0xB0CE	0xAC84	#HANGUL SYLLABLE KIYEOK EO SSANGSIOS
+0xB0CF	0xAC85	#HANGUL SYLLABLE KIYEOK EO IEUNG
+0xB0D0	0xAC86	#HANGUL SYLLABLE KIYEOK EO CIEUC
+0xB0D1	0xAC89	#HANGUL SYLLABLE KIYEOK EO THIEUTH
+0xB0D2	0xAC8A	#HANGUL SYLLABLE KIYEOK EO PHIEUPH
+0xB0D3	0xAC8B	#HANGUL SYLLABLE KIYEOK EO HIEUH
+0xB0D4	0xAC8C	#HANGUL SYLLABLE KIYEOK E
+0xB0D5	0xAC90	#HANGUL SYLLABLE KIYEOK E NIEUN
+0xB0D6	0xAC94	#HANGUL SYLLABLE KIYEOK E RIEUL
+0xB0D7	0xAC9C	#HANGUL SYLLABLE KIYEOK E MIEUM
+0xB0D8	0xAC9D	#HANGUL SYLLABLE KIYEOK E PIEUP
+0xB0D9	0xAC9F	#HANGUL SYLLABLE KIYEOK E SIOS
+0xB0DA	0xACA0	#HANGUL SYLLABLE KIYEOK E SSANGSIOS
+0xB0DB	0xACA1	#HANGUL SYLLABLE KIYEOK E IEUNG
+0xB0DC	0xACA8	#HANGUL SYLLABLE KIYEOK YEO
+0xB0DD	0xACA9	#HANGUL SYLLABLE KIYEOK YEO KIYEOK
+0xB0DE	0xACAA	#HANGUL SYLLABLE KIYEOK YEO SSANGKIYEOK
+0xB0DF	0xACAC	#HANGUL SYLLABLE KIYEOK YEO NIEUN
+0xB0E0	0xACAF	#HANGUL SYLLABLE KIYEOK YEO TIKEUT
+0xB0E1	0xACB0	#HANGUL SYLLABLE KIYEOK YEO RIEUL
+0xB0E2	0xACB8	#HANGUL SYLLABLE KIYEOK YEO MIEUM
+0xB0E3	0xACB9	#HANGUL SYLLABLE KIYEOK YEO PIEUP
+0xB0E4	0xACBB	#HANGUL SYLLABLE KIYEOK YEO SIOS
+0xB0E5	0xACBC	#HANGUL SYLLABLE KIYEOK YEO SSANGSIOS
+0xB0E6	0xACBD	#HANGUL SYLLABLE KIYEOK YEO IEUNG
+0xB0E7	0xACC1	#HANGUL SYLLABLE KIYEOK YEO THIEUTH
+0xB0E8	0xACC4	#HANGUL SYLLABLE KIYEOK YE
+0xB0E9	0xACC8	#HANGUL SYLLABLE KIYEOK YE NIEUN
+0xB0EA	0xACCC	#HANGUL SYLLABLE KIYEOK YE RIEUL
+0xB0EB	0xACD5	#HANGUL SYLLABLE KIYEOK YE PIEUP
+0xB0EC	0xACD7	#HANGUL SYLLABLE KIYEOK YE SIOS
+0xB0ED	0xACE0	#HANGUL SYLLABLE KIYEOK O
+0xB0EE	0xACE1	#HANGUL SYLLABLE KIYEOK O KIYEOK
+0xB0EF	0xACE4	#HANGUL SYLLABLE KIYEOK O NIEUN
+0xB0F0	0xACE7	#HANGUL SYLLABLE KIYEOK O TIKEUT
+0xB0F1	0xACE8	#HANGUL SYLLABLE KIYEOK O RIEUL
+0xB0F2	0xACEA	#HANGUL SYLLABLE KIYEOK O RIEULMIEUM
+0xB0F3	0xACEC	#HANGUL SYLLABLE KIYEOK O RIEULSIOS
+0xB0F4	0xACEF	#HANGUL SYLLABLE KIYEOK O RIEULHIEUH
+0xB0F5	0xACF0	#HANGUL SYLLABLE KIYEOK O MIEUM
+0xB0F6	0xACF1	#HANGUL SYLLABLE KIYEOK O PIEUP
+0xB0F7	0xACF3	#HANGUL SYLLABLE KIYEOK O SIOS
+0xB0F8	0xACF5	#HANGUL SYLLABLE KIYEOK O IEUNG
+0xB0F9	0xACF6	#HANGUL SYLLABLE KIYEOK O CIEUC
+0xB0FA	0xACFC	#HANGUL SYLLABLE KIYEOK WA
+0xB0FB	0xACFD	#HANGUL SYLLABLE KIYEOK WA KIYEOK
+0xB0FC	0xAD00	#HANGUL SYLLABLE KIYEOK WA NIEUN
+0xB0FD	0xAD04	#HANGUL SYLLABLE KIYEOK WA RIEUL
+0xB0FE	0xAD06	#HANGUL SYLLABLE KIYEOK WA RIEULMIEUM
+0xB141	0xCF02	#HANGUL SYLLABLE KHIEUKH E SSANGKIYEOK
+0xB142	0xCF03	#HANGUL SYLLABLE KHIEUKH E KIYEOKSIOS
+0xB143	0xCF05	#HANGUL SYLLABLE KHIEUKH E NIEUNCIEUC
+0xB144	0xCF06	#HANGUL SYLLABLE KHIEUKH E NIEUNHIEUH
+0xB145	0xCF07	#HANGUL SYLLABLE KHIEUKH E TIKEUT
+0xB146	0xCF09	#HANGUL SYLLABLE KHIEUKH E RIEULKIYEOK
+0xB147	0xCF0A	#HANGUL SYLLABLE KHIEUKH E RIEULMIEUM
+0xB148	0xCF0B	#HANGUL SYLLABLE KHIEUKH E RIEULPIEUP
+0xB149	0xCF0C	#HANGUL SYLLABLE KHIEUKH E RIEULSIOS
+0xB14A	0xCF0D	#HANGUL SYLLABLE KHIEUKH E RIEULTHIEUTH
+0xB14B	0xCF0E	#HANGUL SYLLABLE KHIEUKH E RIEULPHIEUPH
+0xB14C	0xCF0F	#HANGUL SYLLABLE KHIEUKH E RIEULHIEUH
+0xB14D	0xCF12	#HANGUL SYLLABLE KHIEUKH E PIEUPSIOS
+0xB14E	0xCF14	#HANGUL SYLLABLE KHIEUKH E SSANGSIOS
+0xB14F	0xCF16	#HANGUL SYLLABLE KHIEUKH E CIEUC
+0xB150	0xCF17	#HANGUL SYLLABLE KHIEUKH E CHIEUCH
+0xB151	0xCF18	#HANGUL SYLLABLE KHIEUKH E KHIEUKH
+0xB152	0xCF19	#HANGUL SYLLABLE KHIEUKH E THIEUTH
+0xB153	0xCF1A	#HANGUL SYLLABLE KHIEUKH E PHIEUPH
+0xB154	0xCF1B	#HANGUL SYLLABLE KHIEUKH E HIEUH
+0xB155	0xCF1D	#HANGUL SYLLABLE KHIEUKH YEO KIYEOK
+0xB156	0xCF1E	#HANGUL SYLLABLE KHIEUKH YEO SSANGKIYEOK
+0xB157	0xCF1F	#HANGUL SYLLABLE KHIEUKH YEO KIYEOKSIOS
+0xB158	0xCF21	#HANGUL SYLLABLE KHIEUKH YEO NIEUNCIEUC
+0xB159	0xCF22	#HANGUL SYLLABLE KHIEUKH YEO NIEUNHIEUH
+0xB15A	0xCF23	#HANGUL SYLLABLE KHIEUKH YEO TIKEUT
+0xB161	0xCF25	#HANGUL SYLLABLE KHIEUKH YEO RIEULKIYEOK
+0xB162	0xCF26	#HANGUL SYLLABLE KHIEUKH YEO RIEULMIEUM
+0xB163	0xCF27	#HANGUL SYLLABLE KHIEUKH YEO RIEULPIEUP
+0xB164	0xCF28	#HANGUL SYLLABLE KHIEUKH YEO RIEULSIOS
+0xB165	0xCF29	#HANGUL SYLLABLE KHIEUKH YEO RIEULTHIEUTH
+0xB166	0xCF2A	#HANGUL SYLLABLE KHIEUKH YEO RIEULPHIEUPH
+0xB167	0xCF2B	#HANGUL SYLLABLE KHIEUKH YEO RIEULHIEUH
+0xB168	0xCF2E	#HANGUL SYLLABLE KHIEUKH YEO PIEUPSIOS
+0xB169	0xCF32	#HANGUL SYLLABLE KHIEUKH YEO CIEUC
+0xB16A	0xCF33	#HANGUL SYLLABLE KHIEUKH YEO CHIEUCH
+0xB16B	0xCF34	#HANGUL SYLLABLE KHIEUKH YEO KHIEUKH
+0xB16C	0xCF35	#HANGUL SYLLABLE KHIEUKH YEO THIEUTH
+0xB16D	0xCF36	#HANGUL SYLLABLE KHIEUKH YEO PHIEUPH
+0xB16E	0xCF37	#HANGUL SYLLABLE KHIEUKH YEO HIEUH
+0xB16F	0xCF39	#HANGUL SYLLABLE KHIEUKH YE KIYEOK
+0xB170	0xCF3A	#HANGUL SYLLABLE KHIEUKH YE SSANGKIYEOK
+0xB171	0xCF3B	#HANGUL SYLLABLE KHIEUKH YE KIYEOKSIOS
+0xB172	0xCF3C	#HANGUL SYLLABLE KHIEUKH YE NIEUN
+0xB173	0xCF3D	#HANGUL SYLLABLE KHIEUKH YE NIEUNCIEUC
+0xB174	0xCF3E	#HANGUL SYLLABLE KHIEUKH YE NIEUNHIEUH
+0xB175	0xCF3F	#HANGUL SYLLABLE KHIEUKH YE TIKEUT
+0xB176	0xCF40	#HANGUL SYLLABLE KHIEUKH YE RIEUL
+0xB177	0xCF41	#HANGUL SYLLABLE KHIEUKH YE RIEULKIYEOK
+0xB178	0xCF42	#HANGUL SYLLABLE KHIEUKH YE RIEULMIEUM
+0xB179	0xCF43	#HANGUL SYLLABLE KHIEUKH YE RIEULPIEUP
+0xB17A	0xCF44	#HANGUL SYLLABLE KHIEUKH YE RIEULSIOS
+0xB181	0xCF45	#HANGUL SYLLABLE KHIEUKH YE RIEULTHIEUTH
+0xB182	0xCF46	#HANGUL SYLLABLE KHIEUKH YE RIEULPHIEUPH
+0xB183	0xCF47	#HANGUL SYLLABLE KHIEUKH YE RIEULHIEUH
+0xB184	0xCF48	#HANGUL SYLLABLE KHIEUKH YE MIEUM
+0xB185	0xCF49	#HANGUL SYLLABLE KHIEUKH YE PIEUP
+0xB186	0xCF4A	#HANGUL SYLLABLE KHIEUKH YE PIEUPSIOS
+0xB187	0xCF4B	#HANGUL SYLLABLE KHIEUKH YE SIOS
+0xB188	0xCF4C	#HANGUL SYLLABLE KHIEUKH YE SSANGSIOS
+0xB189	0xCF4D	#HANGUL SYLLABLE KHIEUKH YE IEUNG
+0xB18A	0xCF4E	#HANGUL SYLLABLE KHIEUKH YE CIEUC
+0xB18B	0xCF4F	#HANGUL SYLLABLE KHIEUKH YE CHIEUCH
+0xB18C	0xCF50	#HANGUL SYLLABLE KHIEUKH YE KHIEUKH
+0xB18D	0xCF51	#HANGUL SYLLABLE KHIEUKH YE THIEUTH
+0xB18E	0xCF52	#HANGUL SYLLABLE KHIEUKH YE PHIEUPH
+0xB18F	0xCF53	#HANGUL SYLLABLE KHIEUKH YE HIEUH
+0xB190	0xCF56	#HANGUL SYLLABLE KHIEUKH O SSANGKIYEOK
+0xB191	0xCF57	#HANGUL SYLLABLE KHIEUKH O KIYEOKSIOS
+0xB192	0xCF59	#HANGUL SYLLABLE KHIEUKH O NIEUNCIEUC
+0xB193	0xCF5A	#HANGUL SYLLABLE KHIEUKH O NIEUNHIEUH
+0xB194	0xCF5B	#HANGUL SYLLABLE KHIEUKH O TIKEUT
+0xB195	0xCF5D	#HANGUL SYLLABLE KHIEUKH O RIEULKIYEOK
+0xB196	0xCF5E	#HANGUL SYLLABLE KHIEUKH O RIEULMIEUM
+0xB197	0xCF5F	#HANGUL SYLLABLE KHIEUKH O RIEULPIEUP
+0xB198	0xCF60	#HANGUL SYLLABLE KHIEUKH O RIEULSIOS
+0xB199	0xCF61	#HANGUL SYLLABLE KHIEUKH O RIEULTHIEUTH
+0xB19A	0xCF62	#HANGUL SYLLABLE KHIEUKH O RIEULPHIEUPH
+0xB19B	0xCF63	#HANGUL SYLLABLE KHIEUKH O RIEULHIEUH
+0xB19C	0xCF66	#HANGUL SYLLABLE KHIEUKH O PIEUPSIOS
+0xB19D	0xCF68	#HANGUL SYLLABLE KHIEUKH O SSANGSIOS
+0xB19E	0xCF6A	#HANGUL SYLLABLE KHIEUKH O CIEUC
+0xB19F	0xCF6B	#HANGUL SYLLABLE KHIEUKH O CHIEUCH
+0xB1A0	0xCF6C	#HANGUL SYLLABLE KHIEUKH O KHIEUKH
+0xB1A1	0xAD0C	#HANGUL SYLLABLE KIYEOK WA MIEUM
+0xB1A2	0xAD0D	#HANGUL SYLLABLE KIYEOK WA PIEUP
+0xB1A3	0xAD0F	#HANGUL SYLLABLE KIYEOK WA SIOS
+0xB1A4	0xAD11	#HANGUL SYLLABLE KIYEOK WA IEUNG
+0xB1A5	0xAD18	#HANGUL SYLLABLE KIYEOK WAE
+0xB1A6	0xAD1C	#HANGUL SYLLABLE KIYEOK WAE NIEUN
+0xB1A7	0xAD20	#HANGUL SYLLABLE KIYEOK WAE RIEUL
+0xB1A8	0xAD29	#HANGUL SYLLABLE KIYEOK WAE PIEUP
+0xB1A9	0xAD2C	#HANGUL SYLLABLE KIYEOK WAE SSANGSIOS
+0xB1AA	0xAD2D	#HANGUL SYLLABLE KIYEOK WAE IEUNG
+0xB1AB	0xAD34	#HANGUL SYLLABLE KIYEOK OE
+0xB1AC	0xAD35	#HANGUL SYLLABLE KIYEOK OE KIYEOK
+0xB1AD	0xAD38	#HANGUL SYLLABLE KIYEOK OE NIEUN
+0xB1AE	0xAD3C	#HANGUL SYLLABLE KIYEOK OE RIEUL
+0xB1AF	0xAD44	#HANGUL SYLLABLE KIYEOK OE MIEUM
+0xB1B0	0xAD45	#HANGUL SYLLABLE KIYEOK OE PIEUP
+0xB1B1	0xAD47	#HANGUL SYLLABLE KIYEOK OE SIOS
+0xB1B2	0xAD49	#HANGUL SYLLABLE KIYEOK OE IEUNG
+0xB1B3	0xAD50	#HANGUL SYLLABLE KIYEOK YO
+0xB1B4	0xAD54	#HANGUL SYLLABLE KIYEOK YO NIEUN
+0xB1B5	0xAD58	#HANGUL SYLLABLE KIYEOK YO RIEUL
+0xB1B6	0xAD61	#HANGUL SYLLABLE KIYEOK YO PIEUP
+0xB1B7	0xAD63	#HANGUL SYLLABLE KIYEOK YO SIOS
+0xB1B8	0xAD6C	#HANGUL SYLLABLE KIYEOK U
+0xB1B9	0xAD6D	#HANGUL SYLLABLE KIYEOK U KIYEOK
+0xB1BA	0xAD70	#HANGUL SYLLABLE KIYEOK U NIEUN
+0xB1BB	0xAD73	#HANGUL SYLLABLE KIYEOK U TIKEUT
+0xB1BC	0xAD74	#HANGUL SYLLABLE KIYEOK U RIEUL
+0xB1BD	0xAD75	#HANGUL SYLLABLE KIYEOK U RIEULKIYEOK
+0xB1BE	0xAD76	#HANGUL SYLLABLE KIYEOK U RIEULMIEUM
+0xB1BF	0xAD7B	#HANGUL SYLLABLE KIYEOK U RIEULHIEUH
+0xB1C0	0xAD7C	#HANGUL SYLLABLE KIYEOK U MIEUM
+0xB1C1	0xAD7D	#HANGUL SYLLABLE KIYEOK U PIEUP
+0xB1C2	0xAD7F	#HANGUL SYLLABLE KIYEOK U SIOS
+0xB1C3	0xAD81	#HANGUL SYLLABLE KIYEOK U IEUNG
+0xB1C4	0xAD82	#HANGUL SYLLABLE KIYEOK U CIEUC
+0xB1C5	0xAD88	#HANGUL SYLLABLE KIYEOK WEO
+0xB1C6	0xAD89	#HANGUL SYLLABLE KIYEOK WEO KIYEOK
+0xB1C7	0xAD8C	#HANGUL SYLLABLE KIYEOK WEO NIEUN
+0xB1C8	0xAD90	#HANGUL SYLLABLE KIYEOK WEO RIEUL
+0xB1C9	0xAD9C	#HANGUL SYLLABLE KIYEOK WEO SSANGSIOS
+0xB1CA	0xAD9D	#HANGUL SYLLABLE KIYEOK WEO IEUNG
+0xB1CB	0xADA4	#HANGUL SYLLABLE KIYEOK WE
+0xB1CC	0xADB7	#HANGUL SYLLABLE KIYEOK WE SIOS
+0xB1CD	0xADC0	#HANGUL SYLLABLE KIYEOK WI
+0xB1CE	0xADC1	#HANGUL SYLLABLE KIYEOK WI KIYEOK
+0xB1CF	0xADC4	#HANGUL SYLLABLE KIYEOK WI NIEUN
+0xB1D0	0xADC8	#HANGUL SYLLABLE KIYEOK WI RIEUL
+0xB1D1	0xADD0	#HANGUL SYLLABLE KIYEOK WI MIEUM
+0xB1D2	0xADD1	#HANGUL SYLLABLE KIYEOK WI PIEUP
+0xB1D3	0xADD3	#HANGUL SYLLABLE KIYEOK WI SIOS
+0xB1D4	0xADDC	#HANGUL SYLLABLE KIYEOK YU
+0xB1D5	0xADE0	#HANGUL SYLLABLE KIYEOK YU NIEUN
+0xB1D6	0xADE4	#HANGUL SYLLABLE KIYEOK YU RIEUL
+0xB1D7	0xADF8	#HANGUL SYLLABLE KIYEOK EU
+0xB1D8	0xADF9	#HANGUL SYLLABLE KIYEOK EU KIYEOK
+0xB1D9	0xADFC	#HANGUL SYLLABLE KIYEOK EU NIEUN
+0xB1DA	0xADFF	#HANGUL SYLLABLE KIYEOK EU TIKEUT
+0xB1DB	0xAE00	#HANGUL SYLLABLE KIYEOK EU RIEUL
+0xB1DC	0xAE01	#HANGUL SYLLABLE KIYEOK EU RIEULKIYEOK
+0xB1DD	0xAE08	#HANGUL SYLLABLE KIYEOK EU MIEUM
+0xB1DE	0xAE09	#HANGUL SYLLABLE KIYEOK EU PIEUP
+0xB1DF	0xAE0B	#HANGUL SYLLABLE KIYEOK EU SIOS
+0xB1E0	0xAE0D	#HANGUL SYLLABLE KIYEOK EU IEUNG
+0xB1E1	0xAE14	#HANGUL SYLLABLE KIYEOK YI
+0xB1E2	0xAE30	#HANGUL SYLLABLE KIYEOK I
+0xB1E3	0xAE31	#HANGUL SYLLABLE KIYEOK I KIYEOK
+0xB1E4	0xAE34	#HANGUL SYLLABLE KIYEOK I NIEUN
+0xB1E5	0xAE37	#HANGUL SYLLABLE KIYEOK I TIKEUT
+0xB1E6	0xAE38	#HANGUL SYLLABLE KIYEOK I RIEUL
+0xB1E7	0xAE3A	#HANGUL SYLLABLE KIYEOK I RIEULMIEUM
+0xB1E8	0xAE40	#HANGUL SYLLABLE KIYEOK I MIEUM
+0xB1E9	0xAE41	#HANGUL SYLLABLE KIYEOK I PIEUP
+0xB1EA	0xAE43	#HANGUL SYLLABLE KIYEOK I SIOS
+0xB1EB	0xAE45	#HANGUL SYLLABLE KIYEOK I IEUNG
+0xB1EC	0xAE46	#HANGUL SYLLABLE KIYEOK I CIEUC
+0xB1ED	0xAE4A	#HANGUL SYLLABLE KIYEOK I PHIEUPH
+0xB1EE	0xAE4C	#HANGUL SYLLABLE SSANGKIYEOK A
+0xB1EF	0xAE4D	#HANGUL SYLLABLE SSANGKIYEOK A KIYEOK
+0xB1F0	0xAE4E	#HANGUL SYLLABLE SSANGKIYEOK A SSANGKIYEOK
+0xB1F1	0xAE50	#HANGUL SYLLABLE SSANGKIYEOK A NIEUN
+0xB1F2	0xAE54	#HANGUL SYLLABLE SSANGKIYEOK A RIEUL
+0xB1F3	0xAE56	#HANGUL SYLLABLE SSANGKIYEOK A RIEULMIEUM
+0xB1F4	0xAE5C	#HANGUL SYLLABLE SSANGKIYEOK A MIEUM
+0xB1F5	0xAE5D	#HANGUL SYLLABLE SSANGKIYEOK A PIEUP
+0xB1F6	0xAE5F	#HANGUL SYLLABLE SSANGKIYEOK A SIOS
+0xB1F7	0xAE60	#HANGUL SYLLABLE SSANGKIYEOK A SSANGSIOS
+0xB1F8	0xAE61	#HANGUL SYLLABLE SSANGKIYEOK A IEUNG
+0xB1F9	0xAE65	#HANGUL SYLLABLE SSANGKIYEOK A THIEUTH
+0xB1FA	0xAE68	#HANGUL SYLLABLE SSANGKIYEOK AE
+0xB1FB	0xAE69	#HANGUL SYLLABLE SSANGKIYEOK AE KIYEOK
+0xB1FC	0xAE6C	#HANGUL SYLLABLE SSANGKIYEOK AE NIEUN
+0xB1FD	0xAE70	#HANGUL SYLLABLE SSANGKIYEOK AE RIEUL
+0xB1FE	0xAE78	#HANGUL SYLLABLE SSANGKIYEOK AE MIEUM
+0xB241	0xCF6D	#HANGUL SYLLABLE KHIEUKH O THIEUTH
+0xB242	0xCF6E	#HANGUL SYLLABLE KHIEUKH O PHIEUPH
+0xB243	0xCF6F	#HANGUL SYLLABLE KHIEUKH O HIEUH
+0xB244	0xCF72	#HANGUL SYLLABLE KHIEUKH WA SSANGKIYEOK
+0xB245	0xCF73	#HANGUL SYLLABLE KHIEUKH WA KIYEOKSIOS
+0xB246	0xCF75	#HANGUL SYLLABLE KHIEUKH WA NIEUNCIEUC
+0xB247	0xCF76	#HANGUL SYLLABLE KHIEUKH WA NIEUNHIEUH
+0xB248	0xCF77	#HANGUL SYLLABLE KHIEUKH WA TIKEUT
+0xB249	0xCF79	#HANGUL SYLLABLE KHIEUKH WA RIEULKIYEOK
+0xB24A	0xCF7A	#HANGUL SYLLABLE KHIEUKH WA RIEULMIEUM
+0xB24B	0xCF7B	#HANGUL SYLLABLE KHIEUKH WA RIEULPIEUP
+0xB24C	0xCF7C	#HANGUL SYLLABLE KHIEUKH WA RIEULSIOS
+0xB24D	0xCF7D	#HANGUL SYLLABLE KHIEUKH WA RIEULTHIEUTH
+0xB24E	0xCF7E	#HANGUL SYLLABLE KHIEUKH WA RIEULPHIEUPH
+0xB24F	0xCF7F	#HANGUL SYLLABLE KHIEUKH WA RIEULHIEUH
+0xB250	0xCF81	#HANGUL SYLLABLE KHIEUKH WA PIEUP
+0xB251	0xCF82	#HANGUL SYLLABLE KHIEUKH WA PIEUPSIOS
+0xB252	0xCF83	#HANGUL SYLLABLE KHIEUKH WA SIOS
+0xB253	0xCF84	#HANGUL SYLLABLE KHIEUKH WA SSANGSIOS
+0xB254	0xCF86	#HANGUL SYLLABLE KHIEUKH WA CIEUC
+0xB255	0xCF87	#HANGUL SYLLABLE KHIEUKH WA CHIEUCH
+0xB256	0xCF88	#HANGUL SYLLABLE KHIEUKH WA KHIEUKH
+0xB257	0xCF89	#HANGUL SYLLABLE KHIEUKH WA THIEUTH
+0xB258	0xCF8A	#HANGUL SYLLABLE KHIEUKH WA PHIEUPH
+0xB259	0xCF8B	#HANGUL SYLLABLE KHIEUKH WA HIEUH
+0xB25A	0xCF8D	#HANGUL SYLLABLE KHIEUKH WAE KIYEOK
+0xB261	0xCF8E	#HANGUL SYLLABLE KHIEUKH WAE SSANGKIYEOK
+0xB262	0xCF8F	#HANGUL SYLLABLE KHIEUKH WAE KIYEOKSIOS
+0xB263	0xCF90	#HANGUL SYLLABLE KHIEUKH WAE NIEUN
+0xB264	0xCF91	#HANGUL SYLLABLE KHIEUKH WAE NIEUNCIEUC
+0xB265	0xCF92	#HANGUL SYLLABLE KHIEUKH WAE NIEUNHIEUH
+0xB266	0xCF93	#HANGUL SYLLABLE KHIEUKH WAE TIKEUT
+0xB267	0xCF94	#HANGUL SYLLABLE KHIEUKH WAE RIEUL
+0xB268	0xCF95	#HANGUL SYLLABLE KHIEUKH WAE RIEULKIYEOK
+0xB269	0xCF96	#HANGUL SYLLABLE KHIEUKH WAE RIEULMIEUM
+0xB26A	0xCF97	#HANGUL SYLLABLE KHIEUKH WAE RIEULPIEUP
+0xB26B	0xCF98	#HANGUL SYLLABLE KHIEUKH WAE RIEULSIOS
+0xB26C	0xCF99	#HANGUL SYLLABLE KHIEUKH WAE RIEULTHIEUTH
+0xB26D	0xCF9A	#HANGUL SYLLABLE KHIEUKH WAE RIEULPHIEUPH
+0xB26E	0xCF9B	#HANGUL SYLLABLE KHIEUKH WAE RIEULHIEUH
+0xB26F	0xCF9C	#HANGUL SYLLABLE KHIEUKH WAE MIEUM
+0xB270	0xCF9D	#HANGUL SYLLABLE KHIEUKH WAE PIEUP
+0xB271	0xCF9E	#HANGUL SYLLABLE KHIEUKH WAE PIEUPSIOS
+0xB272	0xCF9F	#HANGUL SYLLABLE KHIEUKH WAE SIOS
+0xB273	0xCFA0	#HANGUL SYLLABLE KHIEUKH WAE SSANGSIOS
+0xB274	0xCFA2	#HANGUL SYLLABLE KHIEUKH WAE CIEUC
+0xB275	0xCFA3	#HANGUL SYLLABLE KHIEUKH WAE CHIEUCH
+0xB276	0xCFA4	#HANGUL SYLLABLE KHIEUKH WAE KHIEUKH
+0xB277	0xCFA5	#HANGUL SYLLABLE KHIEUKH WAE THIEUTH
+0xB278	0xCFA6	#HANGUL SYLLABLE KHIEUKH WAE PHIEUPH
+0xB279	0xCFA7	#HANGUL SYLLABLE KHIEUKH WAE HIEUH
+0xB27A	0xCFA9	#HANGUL SYLLABLE KHIEUKH OE KIYEOK
+0xB281	0xCFAA	#HANGUL SYLLABLE KHIEUKH OE SSANGKIYEOK
+0xB282	0xCFAB	#HANGUL SYLLABLE KHIEUKH OE KIYEOKSIOS
+0xB283	0xCFAC	#HANGUL SYLLABLE KHIEUKH OE NIEUN
+0xB284	0xCFAD	#HANGUL SYLLABLE KHIEUKH OE NIEUNCIEUC
+0xB285	0xCFAE	#HANGUL SYLLABLE KHIEUKH OE NIEUNHIEUH
+0xB286	0xCFAF	#HANGUL SYLLABLE KHIEUKH OE TIKEUT
+0xB287	0xCFB1	#HANGUL SYLLABLE KHIEUKH OE RIEULKIYEOK
+0xB288	0xCFB2	#HANGUL SYLLABLE KHIEUKH OE RIEULMIEUM
+0xB289	0xCFB3	#HANGUL SYLLABLE KHIEUKH OE RIEULPIEUP
+0xB28A	0xCFB4	#HANGUL SYLLABLE KHIEUKH OE RIEULSIOS
+0xB28B	0xCFB5	#HANGUL SYLLABLE KHIEUKH OE RIEULTHIEUTH
+0xB28C	0xCFB6	#HANGUL SYLLABLE KHIEUKH OE RIEULPHIEUPH
+0xB28D	0xCFB7	#HANGUL SYLLABLE KHIEUKH OE RIEULHIEUH
+0xB28E	0xCFB8	#HANGUL SYLLABLE KHIEUKH OE MIEUM
+0xB28F	0xCFB9	#HANGUL SYLLABLE KHIEUKH OE PIEUP
+0xB290	0xCFBA	#HANGUL SYLLABLE KHIEUKH OE PIEUPSIOS
+0xB291	0xCFBB	#HANGUL SYLLABLE KHIEUKH OE SIOS
+0xB292	0xCFBC	#HANGUL SYLLABLE KHIEUKH OE SSANGSIOS
+0xB293	0xCFBD	#HANGUL SYLLABLE KHIEUKH OE IEUNG
+0xB294	0xCFBE	#HANGUL SYLLABLE KHIEUKH OE CIEUC
+0xB295	0xCFBF	#HANGUL SYLLABLE KHIEUKH OE CHIEUCH
+0xB296	0xCFC0	#HANGUL SYLLABLE KHIEUKH OE KHIEUKH
+0xB297	0xCFC1	#HANGUL SYLLABLE KHIEUKH OE THIEUTH
+0xB298	0xCFC2	#HANGUL SYLLABLE KHIEUKH OE PHIEUPH
+0xB299	0xCFC3	#HANGUL SYLLABLE KHIEUKH OE HIEUH
+0xB29A	0xCFC5	#HANGUL SYLLABLE KHIEUKH YO KIYEOK
+0xB29B	0xCFC6	#HANGUL SYLLABLE KHIEUKH YO SSANGKIYEOK
+0xB29C	0xCFC7	#HANGUL SYLLABLE KHIEUKH YO KIYEOKSIOS
+0xB29D	0xCFC8	#HANGUL SYLLABLE KHIEUKH YO NIEUN
+0xB29E	0xCFC9	#HANGUL SYLLABLE KHIEUKH YO NIEUNCIEUC
+0xB29F	0xCFCA	#HANGUL SYLLABLE KHIEUKH YO NIEUNHIEUH
+0xB2A0	0xCFCB	#HANGUL SYLLABLE KHIEUKH YO TIKEUT
+0xB2A1	0xAE79	#HANGUL SYLLABLE SSANGKIYEOK AE PIEUP
+0xB2A2	0xAE7B	#HANGUL SYLLABLE SSANGKIYEOK AE SIOS
+0xB2A3	0xAE7C	#HANGUL SYLLABLE SSANGKIYEOK AE SSANGSIOS
+0xB2A4	0xAE7D	#HANGUL SYLLABLE SSANGKIYEOK AE IEUNG
+0xB2A5	0xAE84	#HANGUL SYLLABLE SSANGKIYEOK YA
+0xB2A6	0xAE85	#HANGUL SYLLABLE SSANGKIYEOK YA KIYEOK
+0xB2A7	0xAE8C	#HANGUL SYLLABLE SSANGKIYEOK YA RIEUL
+0xB2A8	0xAEBC	#HANGUL SYLLABLE SSANGKIYEOK EO
+0xB2A9	0xAEBD	#HANGUL SYLLABLE SSANGKIYEOK EO KIYEOK
+0xB2AA	0xAEBE	#HANGUL SYLLABLE SSANGKIYEOK EO SSANGKIYEOK
+0xB2AB	0xAEC0	#HANGUL SYLLABLE SSANGKIYEOK EO NIEUN
+0xB2AC	0xAEC4	#HANGUL SYLLABLE SSANGKIYEOK EO RIEUL
+0xB2AD	0xAECC	#HANGUL SYLLABLE SSANGKIYEOK EO MIEUM
+0xB2AE	0xAECD	#HANGUL SYLLABLE SSANGKIYEOK EO PIEUP
+0xB2AF	0xAECF	#HANGUL SYLLABLE SSANGKIYEOK EO SIOS
+0xB2B0	0xAED0	#HANGUL SYLLABLE SSANGKIYEOK EO SSANGSIOS
+0xB2B1	0xAED1	#HANGUL SYLLABLE SSANGKIYEOK EO IEUNG
+0xB2B2	0xAED8	#HANGUL SYLLABLE SSANGKIYEOK E
+0xB2B3	0xAED9	#HANGUL SYLLABLE SSANGKIYEOK E KIYEOK
+0xB2B4	0xAEDC	#HANGUL SYLLABLE SSANGKIYEOK E NIEUN
+0xB2B5	0xAEE8	#HANGUL SYLLABLE SSANGKIYEOK E MIEUM
+0xB2B6	0xAEEB	#HANGUL SYLLABLE SSANGKIYEOK E SIOS
+0xB2B7	0xAEED	#HANGUL SYLLABLE SSANGKIYEOK E IEUNG
+0xB2B8	0xAEF4	#HANGUL SYLLABLE SSANGKIYEOK YEO
+0xB2B9	0xAEF8	#HANGUL SYLLABLE SSANGKIYEOK YEO NIEUN
+0xB2BA	0xAEFC	#HANGUL SYLLABLE SSANGKIYEOK YEO RIEUL
+0xB2BB	0xAF07	#HANGUL SYLLABLE SSANGKIYEOK YEO SIOS
+0xB2BC	0xAF08	#HANGUL SYLLABLE SSANGKIYEOK YEO SSANGSIOS
+0xB2BD	0xAF0D	#HANGUL SYLLABLE SSANGKIYEOK YEO THIEUTH
+0xB2BE	0xAF10	#HANGUL SYLLABLE SSANGKIYEOK YE
+0xB2BF	0xAF2C	#HANGUL SYLLABLE SSANGKIYEOK O
+0xB2C0	0xAF2D	#HANGUL SYLLABLE SSANGKIYEOK O KIYEOK
+0xB2C1	0xAF30	#HANGUL SYLLABLE SSANGKIYEOK O NIEUN
+0xB2C2	0xAF32	#HANGUL SYLLABLE SSANGKIYEOK O NIEUNHIEUH
+0xB2C3	0xAF34	#HANGUL SYLLABLE SSANGKIYEOK O RIEUL
+0xB2C4	0xAF3C	#HANGUL SYLLABLE SSANGKIYEOK O MIEUM
+0xB2C5	0xAF3D	#HANGUL SYLLABLE SSANGKIYEOK O PIEUP
+0xB2C6	0xAF3F	#HANGUL SYLLABLE SSANGKIYEOK O SIOS
+0xB2C7	0xAF41	#HANGUL SYLLABLE SSANGKIYEOK O IEUNG
+0xB2C8	0xAF42	#HANGUL SYLLABLE SSANGKIYEOK O CIEUC
+0xB2C9	0xAF43	#HANGUL SYLLABLE SSANGKIYEOK O CHIEUCH
+0xB2CA	0xAF48	#HANGUL SYLLABLE SSANGKIYEOK WA
+0xB2CB	0xAF49	#HANGUL SYLLABLE SSANGKIYEOK WA KIYEOK
+0xB2CC	0xAF50	#HANGUL SYLLABLE SSANGKIYEOK WA RIEUL
+0xB2CD	0xAF5C	#HANGUL SYLLABLE SSANGKIYEOK WA SSANGSIOS
+0xB2CE	0xAF5D	#HANGUL SYLLABLE SSANGKIYEOK WA IEUNG
+0xB2CF	0xAF64	#HANGUL SYLLABLE SSANGKIYEOK WAE
+0xB2D0	0xAF65	#HANGUL SYLLABLE SSANGKIYEOK WAE KIYEOK
+0xB2D1	0xAF79	#HANGUL SYLLABLE SSANGKIYEOK WAE IEUNG
+0xB2D2	0xAF80	#HANGUL SYLLABLE SSANGKIYEOK OE
+0xB2D3	0xAF84	#HANGUL SYLLABLE SSANGKIYEOK OE NIEUN
+0xB2D4	0xAF88	#HANGUL SYLLABLE SSANGKIYEOK OE RIEUL
+0xB2D5	0xAF90	#HANGUL SYLLABLE SSANGKIYEOK OE MIEUM
+0xB2D6	0xAF91	#HANGUL SYLLABLE SSANGKIYEOK OE PIEUP
+0xB2D7	0xAF95	#HANGUL SYLLABLE SSANGKIYEOK OE IEUNG
+0xB2D8	0xAF9C	#HANGUL SYLLABLE SSANGKIYEOK YO
+0xB2D9	0xAFB8	#HANGUL SYLLABLE SSANGKIYEOK U
+0xB2DA	0xAFB9	#HANGUL SYLLABLE SSANGKIYEOK U KIYEOK
+0xB2DB	0xAFBC	#HANGUL SYLLABLE SSANGKIYEOK U NIEUN
+0xB2DC	0xAFC0	#HANGUL SYLLABLE SSANGKIYEOK U RIEUL
+0xB2DD	0xAFC7	#HANGUL SYLLABLE SSANGKIYEOK U RIEULHIEUH
+0xB2DE	0xAFC8	#HANGUL SYLLABLE SSANGKIYEOK U MIEUM
+0xB2DF	0xAFC9	#HANGUL SYLLABLE SSANGKIYEOK U PIEUP
+0xB2E0	0xAFCB	#HANGUL SYLLABLE SSANGKIYEOK U SIOS
+0xB2E1	0xAFCD	#HANGUL SYLLABLE SSANGKIYEOK U IEUNG
+0xB2E2	0xAFCE	#HANGUL SYLLABLE SSANGKIYEOK U CIEUC
+0xB2E3	0xAFD4	#HANGUL SYLLABLE SSANGKIYEOK WEO
+0xB2E4	0xAFDC	#HANGUL SYLLABLE SSANGKIYEOK WEO RIEUL
+0xB2E5	0xAFE8	#HANGUL SYLLABLE SSANGKIYEOK WEO SSANGSIOS
+0xB2E6	0xAFE9	#HANGUL SYLLABLE SSANGKIYEOK WEO IEUNG
+0xB2E7	0xAFF0	#HANGUL SYLLABLE SSANGKIYEOK WE
+0xB2E8	0xAFF1	#HANGUL SYLLABLE SSANGKIYEOK WE KIYEOK
+0xB2E9	0xAFF4	#HANGUL SYLLABLE SSANGKIYEOK WE NIEUN
+0xB2EA	0xAFF8	#HANGUL SYLLABLE SSANGKIYEOK WE RIEUL
+0xB2EB	0xB000	#HANGUL SYLLABLE SSANGKIYEOK WE MIEUM
+0xB2EC	0xB001	#HANGUL SYLLABLE SSANGKIYEOK WE PIEUP
+0xB2ED	0xB004	#HANGUL SYLLABLE SSANGKIYEOK WE SSANGSIOS
+0xB2EE	0xB00C	#HANGUL SYLLABLE SSANGKIYEOK WI
+0xB2EF	0xB010	#HANGUL SYLLABLE SSANGKIYEOK WI NIEUN
+0xB2F0	0xB014	#HANGUL SYLLABLE SSANGKIYEOK WI RIEUL
+0xB2F1	0xB01C	#HANGUL SYLLABLE SSANGKIYEOK WI MIEUM
+0xB2F2	0xB01D	#HANGUL SYLLABLE SSANGKIYEOK WI PIEUP
+0xB2F3	0xB028	#HANGUL SYLLABLE SSANGKIYEOK YU
+0xB2F4	0xB044	#HANGUL SYLLABLE SSANGKIYEOK EU
+0xB2F5	0xB045	#HANGUL SYLLABLE SSANGKIYEOK EU KIYEOK
+0xB2F6	0xB048	#HANGUL SYLLABLE SSANGKIYEOK EU NIEUN
+0xB2F7	0xB04A	#HANGUL SYLLABLE SSANGKIYEOK EU NIEUNHIEUH
+0xB2F8	0xB04C	#HANGUL SYLLABLE SSANGKIYEOK EU RIEUL
+0xB2F9	0xB04E	#HANGUL SYLLABLE SSANGKIYEOK EU RIEULMIEUM
+0xB2FA	0xB053	#HANGUL SYLLABLE SSANGKIYEOK EU RIEULHIEUH
+0xB2FB	0xB054	#HANGUL SYLLABLE SSANGKIYEOK EU MIEUM
+0xB2FC	0xB055	#HANGUL SYLLABLE SSANGKIYEOK EU PIEUP
+0xB2FD	0xB057	#HANGUL SYLLABLE SSANGKIYEOK EU SIOS
+0xB2FE	0xB059	#HANGUL SYLLABLE SSANGKIYEOK EU IEUNG
+0xB341	0xCFCC	#HANGUL SYLLABLE KHIEUKH YO RIEUL
+0xB342	0xCFCD	#HANGUL SYLLABLE KHIEUKH YO RIEULKIYEOK
+0xB343	0xCFCE	#HANGUL SYLLABLE KHIEUKH YO RIEULMIEUM
+0xB344	0xCFCF	#HANGUL SYLLABLE KHIEUKH YO RIEULPIEUP
+0xB345	0xCFD0	#HANGUL SYLLABLE KHIEUKH YO RIEULSIOS
+0xB346	0xCFD1	#HANGUL SYLLABLE KHIEUKH YO RIEULTHIEUTH
+0xB347	0xCFD2	#HANGUL SYLLABLE KHIEUKH YO RIEULPHIEUPH
+0xB348	0xCFD3	#HANGUL SYLLABLE KHIEUKH YO RIEULHIEUH
+0xB349	0xCFD4	#HANGUL SYLLABLE KHIEUKH YO MIEUM
+0xB34A	0xCFD5	#HANGUL SYLLABLE KHIEUKH YO PIEUP
+0xB34B	0xCFD6	#HANGUL SYLLABLE KHIEUKH YO PIEUPSIOS
+0xB34C	0xCFD7	#HANGUL SYLLABLE KHIEUKH YO SIOS
+0xB34D	0xCFD8	#HANGUL SYLLABLE KHIEUKH YO SSANGSIOS
+0xB34E	0xCFD9	#HANGUL SYLLABLE KHIEUKH YO IEUNG
+0xB34F	0xCFDA	#HANGUL SYLLABLE KHIEUKH YO CIEUC
+0xB350	0xCFDB	#HANGUL SYLLABLE KHIEUKH YO CHIEUCH
+0xB351	0xCFDC	#HANGUL SYLLABLE KHIEUKH YO KHIEUKH
+0xB352	0xCFDD	#HANGUL SYLLABLE KHIEUKH YO THIEUTH
+0xB353	0xCFDE	#HANGUL SYLLABLE KHIEUKH YO PHIEUPH
+0xB354	0xCFDF	#HANGUL SYLLABLE KHIEUKH YO HIEUH
+0xB355	0xCFE2	#HANGUL SYLLABLE KHIEUKH U SSANGKIYEOK
+0xB356	0xCFE3	#HANGUL SYLLABLE KHIEUKH U KIYEOKSIOS
+0xB357	0xCFE5	#HANGUL SYLLABLE KHIEUKH U NIEUNCIEUC
+0xB358	0xCFE6	#HANGUL SYLLABLE KHIEUKH U NIEUNHIEUH
+0xB359	0xCFE7	#HANGUL SYLLABLE KHIEUKH U TIKEUT
+0xB35A	0xCFE9	#HANGUL SYLLABLE KHIEUKH U RIEULKIYEOK
+0xB361	0xCFEA	#HANGUL SYLLABLE KHIEUKH U RIEULMIEUM
+0xB362	0xCFEB	#HANGUL SYLLABLE KHIEUKH U RIEULPIEUP
+0xB363	0xCFEC	#HANGUL SYLLABLE KHIEUKH U RIEULSIOS
+0xB364	0xCFED	#HANGUL SYLLABLE KHIEUKH U RIEULTHIEUTH
+0xB365	0xCFEE	#HANGUL SYLLABLE KHIEUKH U RIEULPHIEUPH
+0xB366	0xCFEF	#HANGUL SYLLABLE KHIEUKH U RIEULHIEUH
+0xB367	0xCFF2	#HANGUL SYLLABLE KHIEUKH U PIEUPSIOS
+0xB368	0xCFF4	#HANGUL SYLLABLE KHIEUKH U SSANGSIOS
+0xB369	0xCFF6	#HANGUL SYLLABLE KHIEUKH U CIEUC
+0xB36A	0xCFF7	#HANGUL SYLLABLE KHIEUKH U CHIEUCH
+0xB36B	0xCFF8	#HANGUL SYLLABLE KHIEUKH U KHIEUKH
+0xB36C	0xCFF9	#HANGUL SYLLABLE KHIEUKH U THIEUTH
+0xB36D	0xCFFA	#HANGUL SYLLABLE KHIEUKH U PHIEUPH
+0xB36E	0xCFFB	#HANGUL SYLLABLE KHIEUKH U HIEUH
+0xB36F	0xCFFD	#HANGUL SYLLABLE KHIEUKH WEO KIYEOK
+0xB370	0xCFFE	#HANGUL SYLLABLE KHIEUKH WEO SSANGKIYEOK
+0xB371	0xCFFF	#HANGUL SYLLABLE KHIEUKH WEO KIYEOKSIOS
+0xB372	0xD001	#HANGUL SYLLABLE KHIEUKH WEO NIEUNCIEUC
+0xB373	0xD002	#HANGUL SYLLABLE KHIEUKH WEO NIEUNHIEUH
+0xB374	0xD003	#HANGUL SYLLABLE KHIEUKH WEO TIKEUT
+0xB375	0xD005	#HANGUL SYLLABLE KHIEUKH WEO RIEULKIYEOK
+0xB376	0xD006	#HANGUL SYLLABLE KHIEUKH WEO RIEULMIEUM
+0xB377	0xD007	#HANGUL SYLLABLE KHIEUKH WEO RIEULPIEUP
+0xB378	0xD008	#HANGUL SYLLABLE KHIEUKH WEO RIEULSIOS
+0xB379	0xD009	#HANGUL SYLLABLE KHIEUKH WEO RIEULTHIEUTH
+0xB37A	0xD00A	#HANGUL SYLLABLE KHIEUKH WEO RIEULPHIEUPH
+0xB381	0xD00B	#HANGUL SYLLABLE KHIEUKH WEO RIEULHIEUH
+0xB382	0xD00C	#HANGUL SYLLABLE KHIEUKH WEO MIEUM
+0xB383	0xD00D	#HANGUL SYLLABLE KHIEUKH WEO PIEUP
+0xB384	0xD00E	#HANGUL SYLLABLE KHIEUKH WEO PIEUPSIOS
+0xB385	0xD00F	#HANGUL SYLLABLE KHIEUKH WEO SIOS
+0xB386	0xD010	#HANGUL SYLLABLE KHIEUKH WEO SSANGSIOS
+0xB387	0xD012	#HANGUL SYLLABLE KHIEUKH WEO CIEUC
+0xB388	0xD013	#HANGUL SYLLABLE KHIEUKH WEO CHIEUCH
+0xB389	0xD014	#HANGUL SYLLABLE KHIEUKH WEO KHIEUKH
+0xB38A	0xD015	#HANGUL SYLLABLE KHIEUKH WEO THIEUTH
+0xB38B	0xD016	#HANGUL SYLLABLE KHIEUKH WEO PHIEUPH
+0xB38C	0xD017	#HANGUL SYLLABLE KHIEUKH WEO HIEUH
+0xB38D	0xD019	#HANGUL SYLLABLE KHIEUKH WE KIYEOK
+0xB38E	0xD01A	#HANGUL SYLLABLE KHIEUKH WE SSANGKIYEOK
+0xB38F	0xD01B	#HANGUL SYLLABLE KHIEUKH WE KIYEOKSIOS
+0xB390	0xD01C	#HANGUL SYLLABLE KHIEUKH WE NIEUN
+0xB391	0xD01D	#HANGUL SYLLABLE KHIEUKH WE NIEUNCIEUC
+0xB392	0xD01E	#HANGUL SYLLABLE KHIEUKH WE NIEUNHIEUH
+0xB393	0xD01F	#HANGUL SYLLABLE KHIEUKH WE TIKEUT
+0xB394	0xD020	#HANGUL SYLLABLE KHIEUKH WE RIEUL
+0xB395	0xD021	#HANGUL SYLLABLE KHIEUKH WE RIEULKIYEOK
+0xB396	0xD022	#HANGUL SYLLABLE KHIEUKH WE RIEULMIEUM
+0xB397	0xD023	#HANGUL SYLLABLE KHIEUKH WE RIEULPIEUP
+0xB398	0xD024	#HANGUL SYLLABLE KHIEUKH WE RIEULSIOS
+0xB399	0xD025	#HANGUL SYLLABLE KHIEUKH WE RIEULTHIEUTH
+0xB39A	0xD026	#HANGUL SYLLABLE KHIEUKH WE RIEULPHIEUPH
+0xB39B	0xD027	#HANGUL SYLLABLE KHIEUKH WE RIEULHIEUH
+0xB39C	0xD028	#HANGUL SYLLABLE KHIEUKH WE MIEUM
+0xB39D	0xD029	#HANGUL SYLLABLE KHIEUKH WE PIEUP
+0xB39E	0xD02A	#HANGUL SYLLABLE KHIEUKH WE PIEUPSIOS
+0xB39F	0xD02B	#HANGUL SYLLABLE KHIEUKH WE SIOS
+0xB3A0	0xD02C	#HANGUL SYLLABLE KHIEUKH WE SSANGSIOS
+0xB3A1	0xB05D	#HANGUL SYLLABLE SSANGKIYEOK EU THIEUTH
+0xB3A2	0xB07C	#HANGUL SYLLABLE SSANGKIYEOK I
+0xB3A3	0xB07D	#HANGUL SYLLABLE SSANGKIYEOK I KIYEOK
+0xB3A4	0xB080	#HANGUL SYLLABLE SSANGKIYEOK I NIEUN
+0xB3A5	0xB084	#HANGUL SYLLABLE SSANGKIYEOK I RIEUL
+0xB3A6	0xB08C	#HANGUL SYLLABLE SSANGKIYEOK I MIEUM
+0xB3A7	0xB08D	#HANGUL SYLLABLE SSANGKIYEOK I PIEUP
+0xB3A8	0xB08F	#HANGUL SYLLABLE SSANGKIYEOK I SIOS
+0xB3A9	0xB091	#HANGUL SYLLABLE SSANGKIYEOK I IEUNG
+0xB3AA	0xB098	#HANGUL SYLLABLE NIEUN A
+0xB3AB	0xB099	#HANGUL SYLLABLE NIEUN A KIYEOK
+0xB3AC	0xB09A	#HANGUL SYLLABLE NIEUN A SSANGKIYEOK
+0xB3AD	0xB09C	#HANGUL SYLLABLE NIEUN A NIEUN
+0xB3AE	0xB09F	#HANGUL SYLLABLE NIEUN A TIKEUT
+0xB3AF	0xB0A0	#HANGUL SYLLABLE NIEUN A RIEUL
+0xB3B0	0xB0A1	#HANGUL SYLLABLE NIEUN A RIEULKIYEOK
+0xB3B1	0xB0A2	#HANGUL SYLLABLE NIEUN A RIEULMIEUM
+0xB3B2	0xB0A8	#HANGUL SYLLABLE NIEUN A MIEUM
+0xB3B3	0xB0A9	#HANGUL SYLLABLE NIEUN A PIEUP
+0xB3B4	0xB0AB	#HANGUL SYLLABLE NIEUN A SIOS
+0xB3B5	0xB0AC	#HANGUL SYLLABLE NIEUN A SSANGSIOS
+0xB3B6	0xB0AD	#HANGUL SYLLABLE NIEUN A IEUNG
+0xB3B7	0xB0AE	#HANGUL SYLLABLE NIEUN A CIEUC
+0xB3B8	0xB0AF	#HANGUL SYLLABLE NIEUN A CHIEUCH
+0xB3B9	0xB0B1	#HANGUL SYLLABLE NIEUN A THIEUTH
+0xB3BA	0xB0B3	#HANGUL SYLLABLE NIEUN A HIEUH
+0xB3BB	0xB0B4	#HANGUL SYLLABLE NIEUN AE
+0xB3BC	0xB0B5	#HANGUL SYLLABLE NIEUN AE KIYEOK
+0xB3BD	0xB0B8	#HANGUL SYLLABLE NIEUN AE NIEUN
+0xB3BE	0xB0BC	#HANGUL SYLLABLE NIEUN AE RIEUL
+0xB3BF	0xB0C4	#HANGUL SYLLABLE NIEUN AE MIEUM
+0xB3C0	0xB0C5	#HANGUL SYLLABLE NIEUN AE PIEUP
+0xB3C1	0xB0C7	#HANGUL SYLLABLE NIEUN AE SIOS
+0xB3C2	0xB0C8	#HANGUL SYLLABLE NIEUN AE SSANGSIOS
+0xB3C3	0xB0C9	#HANGUL SYLLABLE NIEUN AE IEUNG
+0xB3C4	0xB0D0	#HANGUL SYLLABLE NIEUN YA
+0xB3C5	0xB0D1	#HANGUL SYLLABLE NIEUN YA KIYEOK
+0xB3C6	0xB0D4	#HANGUL SYLLABLE NIEUN YA NIEUN
+0xB3C7	0xB0D8	#HANGUL SYLLABLE NIEUN YA RIEUL
+0xB3C8	0xB0E0	#HANGUL SYLLABLE NIEUN YA MIEUM
+0xB3C9	0xB0E5	#HANGUL SYLLABLE NIEUN YA IEUNG
+0xB3CA	0xB108	#HANGUL SYLLABLE NIEUN EO
+0xB3CB	0xB109	#HANGUL SYLLABLE NIEUN EO KIYEOK
+0xB3CC	0xB10B	#HANGUL SYLLABLE NIEUN EO KIYEOKSIOS
+0xB3CD	0xB10C	#HANGUL SYLLABLE NIEUN EO NIEUN
+0xB3CE	0xB110	#HANGUL SYLLABLE NIEUN EO RIEUL
+0xB3CF	0xB112	#HANGUL SYLLABLE NIEUN EO RIEULMIEUM
+0xB3D0	0xB113	#HANGUL SYLLABLE NIEUN EO RIEULPIEUP
+0xB3D1	0xB118	#HANGUL SYLLABLE NIEUN EO MIEUM
+0xB3D2	0xB119	#HANGUL SYLLABLE NIEUN EO PIEUP
+0xB3D3	0xB11B	#HANGUL SYLLABLE NIEUN EO SIOS
+0xB3D4	0xB11C	#HANGUL SYLLABLE NIEUN EO SSANGSIOS
+0xB3D5	0xB11D	#HANGUL SYLLABLE NIEUN EO IEUNG
+0xB3D6	0xB123	#HANGUL SYLLABLE NIEUN EO HIEUH
+0xB3D7	0xB124	#HANGUL SYLLABLE NIEUN E
+0xB3D8	0xB125	#HANGUL SYLLABLE NIEUN E KIYEOK
+0xB3D9	0xB128	#HANGUL SYLLABLE NIEUN E NIEUN
+0xB3DA	0xB12C	#HANGUL SYLLABLE NIEUN E RIEUL
+0xB3DB	0xB134	#HANGUL SYLLABLE NIEUN E MIEUM
+0xB3DC	0xB135	#HANGUL SYLLABLE NIEUN E PIEUP
+0xB3DD	0xB137	#HANGUL SYLLABLE NIEUN E SIOS
+0xB3DE	0xB138	#HANGUL SYLLABLE NIEUN E SSANGSIOS
+0xB3DF	0xB139	#HANGUL SYLLABLE NIEUN E IEUNG
+0xB3E0	0xB140	#HANGUL SYLLABLE NIEUN YEO
+0xB3E1	0xB141	#HANGUL SYLLABLE NIEUN YEO KIYEOK
+0xB3E2	0xB144	#HANGUL SYLLABLE NIEUN YEO NIEUN
+0xB3E3	0xB148	#HANGUL SYLLABLE NIEUN YEO RIEUL
+0xB3E4	0xB150	#HANGUL SYLLABLE NIEUN YEO MIEUM
+0xB3E5	0xB151	#HANGUL SYLLABLE NIEUN YEO PIEUP
+0xB3E6	0xB154	#HANGUL SYLLABLE NIEUN YEO SSANGSIOS
+0xB3E7	0xB155	#HANGUL SYLLABLE NIEUN YEO IEUNG
+0xB3E8	0xB158	#HANGUL SYLLABLE NIEUN YEO KHIEUKH
+0xB3E9	0xB15C	#HANGUL SYLLABLE NIEUN YE
+0xB3EA	0xB160	#HANGUL SYLLABLE NIEUN YE NIEUN
+0xB3EB	0xB178	#HANGUL SYLLABLE NIEUN O
+0xB3EC	0xB179	#HANGUL SYLLABLE NIEUN O KIYEOK
+0xB3ED	0xB17C	#HANGUL SYLLABLE NIEUN O NIEUN
+0xB3EE	0xB180	#HANGUL SYLLABLE NIEUN O RIEUL
+0xB3EF	0xB182	#HANGUL SYLLABLE NIEUN O RIEULMIEUM
+0xB3F0	0xB188	#HANGUL SYLLABLE NIEUN O MIEUM
+0xB3F1	0xB189	#HANGUL SYLLABLE NIEUN O PIEUP
+0xB3F2	0xB18B	#HANGUL SYLLABLE NIEUN O SIOS
+0xB3F3	0xB18D	#HANGUL SYLLABLE NIEUN O IEUNG
+0xB3F4	0xB192	#HANGUL SYLLABLE NIEUN O PHIEUPH
+0xB3F5	0xB193	#HANGUL SYLLABLE NIEUN O HIEUH
+0xB3F6	0xB194	#HANGUL SYLLABLE NIEUN WA
+0xB3F7	0xB198	#HANGUL SYLLABLE NIEUN WA NIEUN
+0xB3F8	0xB19C	#HANGUL SYLLABLE NIEUN WA RIEUL
+0xB3F9	0xB1A8	#HANGUL SYLLABLE NIEUN WA SSANGSIOS
+0xB3FA	0xB1CC	#HANGUL SYLLABLE NIEUN OE
+0xB3FB	0xB1D0	#HANGUL SYLLABLE NIEUN OE NIEUN
+0xB3FC	0xB1D4	#HANGUL SYLLABLE NIEUN OE RIEUL
+0xB3FD	0xB1DC	#HANGUL SYLLABLE NIEUN OE MIEUM
+0xB3FE	0xB1DD	#HANGUL SYLLABLE NIEUN OE PIEUP
+0xB441	0xD02E	#HANGUL SYLLABLE KHIEUKH WE CIEUC
+0xB442	0xD02F	#HANGUL SYLLABLE KHIEUKH WE CHIEUCH
+0xB443	0xD030	#HANGUL SYLLABLE KHIEUKH WE KHIEUKH
+0xB444	0xD031	#HANGUL SYLLABLE KHIEUKH WE THIEUTH
+0xB445	0xD032	#HANGUL SYLLABLE KHIEUKH WE PHIEUPH
+0xB446	0xD033	#HANGUL SYLLABLE KHIEUKH WE HIEUH
+0xB447	0xD036	#HANGUL SYLLABLE KHIEUKH WI SSANGKIYEOK
+0xB448	0xD037	#HANGUL SYLLABLE KHIEUKH WI KIYEOKSIOS
+0xB449	0xD039	#HANGUL SYLLABLE KHIEUKH WI NIEUNCIEUC
+0xB44A	0xD03A	#HANGUL SYLLABLE KHIEUKH WI NIEUNHIEUH
+0xB44B	0xD03B	#HANGUL SYLLABLE KHIEUKH WI TIKEUT
+0xB44C	0xD03D	#HANGUL SYLLABLE KHIEUKH WI RIEULKIYEOK
+0xB44D	0xD03E	#HANGUL SYLLABLE KHIEUKH WI RIEULMIEUM
+0xB44E	0xD03F	#HANGUL SYLLABLE KHIEUKH WI RIEULPIEUP
+0xB44F	0xD040	#HANGUL SYLLABLE KHIEUKH WI RIEULSIOS
+0xB450	0xD041	#HANGUL SYLLABLE KHIEUKH WI RIEULTHIEUTH
+0xB451	0xD042	#HANGUL SYLLABLE KHIEUKH WI RIEULPHIEUPH
+0xB452	0xD043	#HANGUL SYLLABLE KHIEUKH WI RIEULHIEUH
+0xB453	0xD046	#HANGUL SYLLABLE KHIEUKH WI PIEUPSIOS
+0xB454	0xD048	#HANGUL SYLLABLE KHIEUKH WI SSANGSIOS
+0xB455	0xD04A	#HANGUL SYLLABLE KHIEUKH WI CIEUC
+0xB456	0xD04B	#HANGUL SYLLABLE KHIEUKH WI CHIEUCH
+0xB457	0xD04C	#HANGUL SYLLABLE KHIEUKH WI KHIEUKH
+0xB458	0xD04D	#HANGUL SYLLABLE KHIEUKH WI THIEUTH
+0xB459	0xD04E	#HANGUL SYLLABLE KHIEUKH WI PHIEUPH
+0xB45A	0xD04F	#HANGUL SYLLABLE KHIEUKH WI HIEUH
+0xB461	0xD051	#HANGUL SYLLABLE KHIEUKH YU KIYEOK
+0xB462	0xD052	#HANGUL SYLLABLE KHIEUKH YU SSANGKIYEOK
+0xB463	0xD053	#HANGUL SYLLABLE KHIEUKH YU KIYEOKSIOS
+0xB464	0xD055	#HANGUL SYLLABLE KHIEUKH YU NIEUNCIEUC
+0xB465	0xD056	#HANGUL SYLLABLE KHIEUKH YU NIEUNHIEUH
+0xB466	0xD057	#HANGUL SYLLABLE KHIEUKH YU TIKEUT
+0xB467	0xD059	#HANGUL SYLLABLE KHIEUKH YU RIEULKIYEOK
+0xB468	0xD05A	#HANGUL SYLLABLE KHIEUKH YU RIEULMIEUM
+0xB469	0xD05B	#HANGUL SYLLABLE KHIEUKH YU RIEULPIEUP
+0xB46A	0xD05C	#HANGUL SYLLABLE KHIEUKH YU RIEULSIOS
+0xB46B	0xD05D	#HANGUL SYLLABLE KHIEUKH YU RIEULTHIEUTH
+0xB46C	0xD05E	#HANGUL SYLLABLE KHIEUKH YU RIEULPHIEUPH
+0xB46D	0xD05F	#HANGUL SYLLABLE KHIEUKH YU RIEULHIEUH
+0xB46E	0xD061	#HANGUL SYLLABLE KHIEUKH YU PIEUP
+0xB46F	0xD062	#HANGUL SYLLABLE KHIEUKH YU PIEUPSIOS
+0xB470	0xD063	#HANGUL SYLLABLE KHIEUKH YU SIOS
+0xB471	0xD064	#HANGUL SYLLABLE KHIEUKH YU SSANGSIOS
+0xB472	0xD065	#HANGUL SYLLABLE KHIEUKH YU IEUNG
+0xB473	0xD066	#HANGUL SYLLABLE KHIEUKH YU CIEUC
+0xB474	0xD067	#HANGUL SYLLABLE KHIEUKH YU CHIEUCH
+0xB475	0xD068	#HANGUL SYLLABLE KHIEUKH YU KHIEUKH
+0xB476	0xD069	#HANGUL SYLLABLE KHIEUKH YU THIEUTH
+0xB477	0xD06A	#HANGUL SYLLABLE KHIEUKH YU PHIEUPH
+0xB478	0xD06B	#HANGUL SYLLABLE KHIEUKH YU HIEUH
+0xB479	0xD06E	#HANGUL SYLLABLE KHIEUKH EU SSANGKIYEOK
+0xB47A	0xD06F	#HANGUL SYLLABLE KHIEUKH EU KIYEOKSIOS
+0xB481	0xD071	#HANGUL SYLLABLE KHIEUKH EU NIEUNCIEUC
+0xB482	0xD072	#HANGUL SYLLABLE KHIEUKH EU NIEUNHIEUH
+0xB483	0xD073	#HANGUL SYLLABLE KHIEUKH EU TIKEUT
+0xB484	0xD075	#HANGUL SYLLABLE KHIEUKH EU RIEULKIYEOK
+0xB485	0xD076	#HANGUL SYLLABLE KHIEUKH EU RIEULMIEUM
+0xB486	0xD077	#HANGUL SYLLABLE KHIEUKH EU RIEULPIEUP
+0xB487	0xD078	#HANGUL SYLLABLE KHIEUKH EU RIEULSIOS
+0xB488	0xD079	#HANGUL SYLLABLE KHIEUKH EU RIEULTHIEUTH
+0xB489	0xD07A	#HANGUL SYLLABLE KHIEUKH EU RIEULPHIEUPH
+0xB48A	0xD07B	#HANGUL SYLLABLE KHIEUKH EU RIEULHIEUH
+0xB48B	0xD07E	#HANGUL SYLLABLE KHIEUKH EU PIEUPSIOS
+0xB48C	0xD07F	#HANGUL SYLLABLE KHIEUKH EU SIOS
+0xB48D	0xD080	#HANGUL SYLLABLE KHIEUKH EU SSANGSIOS
+0xB48E	0xD082	#HANGUL SYLLABLE KHIEUKH EU CIEUC
+0xB48F	0xD083	#HANGUL SYLLABLE KHIEUKH EU CHIEUCH
+0xB490	0xD084	#HANGUL SYLLABLE KHIEUKH EU KHIEUKH
+0xB491	0xD085	#HANGUL SYLLABLE KHIEUKH EU THIEUTH
+0xB492	0xD086	#HANGUL SYLLABLE KHIEUKH EU PHIEUPH
+0xB493	0xD087	#HANGUL SYLLABLE KHIEUKH EU HIEUH
+0xB494	0xD088	#HANGUL SYLLABLE KHIEUKH YI
+0xB495	0xD089	#HANGUL SYLLABLE KHIEUKH YI KIYEOK
+0xB496	0xD08A	#HANGUL SYLLABLE KHIEUKH YI SSANGKIYEOK
+0xB497	0xD08B	#HANGUL SYLLABLE KHIEUKH YI KIYEOKSIOS
+0xB498	0xD08C	#HANGUL SYLLABLE KHIEUKH YI NIEUN
+0xB499	0xD08D	#HANGUL SYLLABLE KHIEUKH YI NIEUNCIEUC
+0xB49A	0xD08E	#HANGUL SYLLABLE KHIEUKH YI NIEUNHIEUH
+0xB49B	0xD08F	#HANGUL SYLLABLE KHIEUKH YI TIKEUT
+0xB49C	0xD090	#HANGUL SYLLABLE KHIEUKH YI RIEUL
+0xB49D	0xD091	#HANGUL SYLLABLE KHIEUKH YI RIEULKIYEOK
+0xB49E	0xD092	#HANGUL SYLLABLE KHIEUKH YI RIEULMIEUM
+0xB49F	0xD093	#HANGUL SYLLABLE KHIEUKH YI RIEULPIEUP
+0xB4A0	0xD094	#HANGUL SYLLABLE KHIEUKH YI RIEULSIOS
+0xB4A1	0xB1DF	#HANGUL SYLLABLE NIEUN OE SIOS
+0xB4A2	0xB1E8	#HANGUL SYLLABLE NIEUN YO
+0xB4A3	0xB1E9	#HANGUL SYLLABLE NIEUN YO KIYEOK
+0xB4A4	0xB1EC	#HANGUL SYLLABLE NIEUN YO NIEUN
+0xB4A5	0xB1F0	#HANGUL SYLLABLE NIEUN YO RIEUL
+0xB4A6	0xB1F9	#HANGUL SYLLABLE NIEUN YO PIEUP
+0xB4A7	0xB1FB	#HANGUL SYLLABLE NIEUN YO SIOS
+0xB4A8	0xB1FD	#HANGUL SYLLABLE NIEUN YO IEUNG
+0xB4A9	0xB204	#HANGUL SYLLABLE NIEUN U
+0xB4AA	0xB205	#HANGUL SYLLABLE NIEUN U KIYEOK
+0xB4AB	0xB208	#HANGUL SYLLABLE NIEUN U NIEUN
+0xB4AC	0xB20B	#HANGUL SYLLABLE NIEUN U TIKEUT
+0xB4AD	0xB20C	#HANGUL SYLLABLE NIEUN U RIEUL
+0xB4AE	0xB214	#HANGUL SYLLABLE NIEUN U MIEUM
+0xB4AF	0xB215	#HANGUL SYLLABLE NIEUN U PIEUP
+0xB4B0	0xB217	#HANGUL SYLLABLE NIEUN U SIOS
+0xB4B1	0xB219	#HANGUL SYLLABLE NIEUN U IEUNG
+0xB4B2	0xB220	#HANGUL SYLLABLE NIEUN WEO
+0xB4B3	0xB234	#HANGUL SYLLABLE NIEUN WEO SSANGSIOS
+0xB4B4	0xB23C	#HANGUL SYLLABLE NIEUN WE
+0xB4B5	0xB258	#HANGUL SYLLABLE NIEUN WI
+0xB4B6	0xB25C	#HANGUL SYLLABLE NIEUN WI NIEUN
+0xB4B7	0xB260	#HANGUL SYLLABLE NIEUN WI RIEUL
+0xB4B8	0xB268	#HANGUL SYLLABLE NIEUN WI MIEUM
+0xB4B9	0xB269	#HANGUL SYLLABLE NIEUN WI PIEUP
+0xB4BA	0xB274	#HANGUL SYLLABLE NIEUN YU
+0xB4BB	0xB275	#HANGUL SYLLABLE NIEUN YU KIYEOK
+0xB4BC	0xB27C	#HANGUL SYLLABLE NIEUN YU RIEUL
+0xB4BD	0xB284	#HANGUL SYLLABLE NIEUN YU MIEUM
+0xB4BE	0xB285	#HANGUL SYLLABLE NIEUN YU PIEUP
+0xB4BF	0xB289	#HANGUL SYLLABLE NIEUN YU IEUNG
+0xB4C0	0xB290	#HANGUL SYLLABLE NIEUN EU
+0xB4C1	0xB291	#HANGUL SYLLABLE NIEUN EU KIYEOK
+0xB4C2	0xB294	#HANGUL SYLLABLE NIEUN EU NIEUN
+0xB4C3	0xB298	#HANGUL SYLLABLE NIEUN EU RIEUL
+0xB4C4	0xB299	#HANGUL SYLLABLE NIEUN EU RIEULKIYEOK
+0xB4C5	0xB29A	#HANGUL SYLLABLE NIEUN EU RIEULMIEUM
+0xB4C6	0xB2A0	#HANGUL SYLLABLE NIEUN EU MIEUM
+0xB4C7	0xB2A1	#HANGUL SYLLABLE NIEUN EU PIEUP
+0xB4C8	0xB2A3	#HANGUL SYLLABLE NIEUN EU SIOS
+0xB4C9	0xB2A5	#HANGUL SYLLABLE NIEUN EU IEUNG
+0xB4CA	0xB2A6	#HANGUL SYLLABLE NIEUN EU CIEUC
+0xB4CB	0xB2AA	#HANGUL SYLLABLE NIEUN EU PHIEUPH
+0xB4CC	0xB2AC	#HANGUL SYLLABLE NIEUN YI
+0xB4CD	0xB2B0	#HANGUL SYLLABLE NIEUN YI NIEUN
+0xB4CE	0xB2B4	#HANGUL SYLLABLE NIEUN YI RIEUL
+0xB4CF	0xB2C8	#HANGUL SYLLABLE NIEUN I
+0xB4D0	0xB2C9	#HANGUL SYLLABLE NIEUN I KIYEOK
+0xB4D1	0xB2CC	#HANGUL SYLLABLE NIEUN I NIEUN
+0xB4D2	0xB2D0	#HANGUL SYLLABLE NIEUN I RIEUL
+0xB4D3	0xB2D2	#HANGUL SYLLABLE NIEUN I RIEULMIEUM
+0xB4D4	0xB2D8	#HANGUL SYLLABLE NIEUN I MIEUM
+0xB4D5	0xB2D9	#HANGUL SYLLABLE NIEUN I PIEUP
+0xB4D6	0xB2DB	#HANGUL SYLLABLE NIEUN I SIOS
+0xB4D7	0xB2DD	#HANGUL SYLLABLE NIEUN I IEUNG
+0xB4D8	0xB2E2	#HANGUL SYLLABLE NIEUN I PHIEUPH
+0xB4D9	0xB2E4	#HANGUL SYLLABLE TIKEUT A
+0xB4DA	0xB2E5	#HANGUL SYLLABLE TIKEUT A KIYEOK
+0xB4DB	0xB2E6	#HANGUL SYLLABLE TIKEUT A SSANGKIYEOK
+0xB4DC	0xB2E8	#HANGUL SYLLABLE TIKEUT A NIEUN
+0xB4DD	0xB2EB	#HANGUL SYLLABLE TIKEUT A TIKEUT
+0xB4DE	0xB2EC	#HANGUL SYLLABLE TIKEUT A RIEUL
+0xB4DF	0xB2ED	#HANGUL SYLLABLE TIKEUT A RIEULKIYEOK
+0xB4E0	0xB2EE	#HANGUL SYLLABLE TIKEUT A RIEULMIEUM
+0xB4E1	0xB2EF	#HANGUL SYLLABLE TIKEUT A RIEULPIEUP
+0xB4E2	0xB2F3	#HANGUL SYLLABLE TIKEUT A RIEULHIEUH
+0xB4E3	0xB2F4	#HANGUL SYLLABLE TIKEUT A MIEUM
+0xB4E4	0xB2F5	#HANGUL SYLLABLE TIKEUT A PIEUP
+0xB4E5	0xB2F7	#HANGUL SYLLABLE TIKEUT A SIOS
+0xB4E6	0xB2F8	#HANGUL SYLLABLE TIKEUT A SSANGSIOS
+0xB4E7	0xB2F9	#HANGUL SYLLABLE TIKEUT A IEUNG
+0xB4E8	0xB2FA	#HANGUL SYLLABLE TIKEUT A CIEUC
+0xB4E9	0xB2FB	#HANGUL SYLLABLE TIKEUT A CHIEUCH
+0xB4EA	0xB2FF	#HANGUL SYLLABLE TIKEUT A HIEUH
+0xB4EB	0xB300	#HANGUL SYLLABLE TIKEUT AE
+0xB4EC	0xB301	#HANGUL SYLLABLE TIKEUT AE KIYEOK
+0xB4ED	0xB304	#HANGUL SYLLABLE TIKEUT AE NIEUN
+0xB4EE	0xB308	#HANGUL SYLLABLE TIKEUT AE RIEUL
+0xB4EF	0xB310	#HANGUL SYLLABLE TIKEUT AE MIEUM
+0xB4F0	0xB311	#HANGUL SYLLABLE TIKEUT AE PIEUP
+0xB4F1	0xB313	#HANGUL SYLLABLE TIKEUT AE SIOS
+0xB4F2	0xB314	#HANGUL SYLLABLE TIKEUT AE SSANGSIOS
+0xB4F3	0xB315	#HANGUL SYLLABLE TIKEUT AE IEUNG
+0xB4F4	0xB31C	#HANGUL SYLLABLE TIKEUT YA
+0xB4F5	0xB354	#HANGUL SYLLABLE TIKEUT EO
+0xB4F6	0xB355	#HANGUL SYLLABLE TIKEUT EO KIYEOK
+0xB4F7	0xB356	#HANGUL SYLLABLE TIKEUT EO SSANGKIYEOK
+0xB4F8	0xB358	#HANGUL SYLLABLE TIKEUT EO NIEUN
+0xB4F9	0xB35B	#HANGUL SYLLABLE TIKEUT EO TIKEUT
+0xB4FA	0xB35C	#HANGUL SYLLABLE TIKEUT EO RIEUL
+0xB4FB	0xB35E	#HANGUL SYLLABLE TIKEUT EO RIEULMIEUM
+0xB4FC	0xB35F	#HANGUL SYLLABLE TIKEUT EO RIEULPIEUP
+0xB4FD	0xB364	#HANGUL SYLLABLE TIKEUT EO MIEUM
+0xB4FE	0xB365	#HANGUL SYLLABLE TIKEUT EO PIEUP
+0xB541	0xD095	#HANGUL SYLLABLE KHIEUKH YI RIEULTHIEUTH
+0xB542	0xD096	#HANGUL SYLLABLE KHIEUKH YI RIEULPHIEUPH
+0xB543	0xD097	#HANGUL SYLLABLE KHIEUKH YI RIEULHIEUH
+0xB544	0xD098	#HANGUL SYLLABLE KHIEUKH YI MIEUM
+0xB545	0xD099	#HANGUL SYLLABLE KHIEUKH YI PIEUP
+0xB546	0xD09A	#HANGUL SYLLABLE KHIEUKH YI PIEUPSIOS
+0xB547	0xD09B	#HANGUL SYLLABLE KHIEUKH YI SIOS
+0xB548	0xD09C	#HANGUL SYLLABLE KHIEUKH YI SSANGSIOS
+0xB549	0xD09D	#HANGUL SYLLABLE KHIEUKH YI IEUNG
+0xB54A	0xD09E	#HANGUL SYLLABLE KHIEUKH YI CIEUC
+0xB54B	0xD09F	#HANGUL SYLLABLE KHIEUKH YI CHIEUCH
+0xB54C	0xD0A0	#HANGUL SYLLABLE KHIEUKH YI KHIEUKH
+0xB54D	0xD0A1	#HANGUL SYLLABLE KHIEUKH YI THIEUTH
+0xB54E	0xD0A2	#HANGUL SYLLABLE KHIEUKH YI PHIEUPH
+0xB54F	0xD0A3	#HANGUL SYLLABLE KHIEUKH YI HIEUH
+0xB550	0xD0A6	#HANGUL SYLLABLE KHIEUKH I SSANGKIYEOK
+0xB551	0xD0A7	#HANGUL SYLLABLE KHIEUKH I KIYEOKSIOS
+0xB552	0xD0A9	#HANGUL SYLLABLE KHIEUKH I NIEUNCIEUC
+0xB553	0xD0AA	#HANGUL SYLLABLE KHIEUKH I NIEUNHIEUH
+0xB554	0xD0AB	#HANGUL SYLLABLE KHIEUKH I TIKEUT
+0xB555	0xD0AD	#HANGUL SYLLABLE KHIEUKH I RIEULKIYEOK
+0xB556	0xD0AE	#HANGUL SYLLABLE KHIEUKH I RIEULMIEUM
+0xB557	0xD0AF	#HANGUL SYLLABLE KHIEUKH I RIEULPIEUP
+0xB558	0xD0B0	#HANGUL SYLLABLE KHIEUKH I RIEULSIOS
+0xB559	0xD0B1	#HANGUL SYLLABLE KHIEUKH I RIEULTHIEUTH
+0xB55A	0xD0B2	#HANGUL SYLLABLE KHIEUKH I RIEULPHIEUPH
+0xB561	0xD0B3	#HANGUL SYLLABLE KHIEUKH I RIEULHIEUH
+0xB562	0xD0B6	#HANGUL SYLLABLE KHIEUKH I PIEUPSIOS
+0xB563	0xD0B8	#HANGUL SYLLABLE KHIEUKH I SSANGSIOS
+0xB564	0xD0BA	#HANGUL SYLLABLE KHIEUKH I CIEUC
+0xB565	0xD0BB	#HANGUL SYLLABLE KHIEUKH I CHIEUCH
+0xB566	0xD0BC	#HANGUL SYLLABLE KHIEUKH I KHIEUKH
+0xB567	0xD0BD	#HANGUL SYLLABLE KHIEUKH I THIEUTH
+0xB568	0xD0BE	#HANGUL SYLLABLE KHIEUKH I PHIEUPH
+0xB569	0xD0BF	#HANGUL SYLLABLE KHIEUKH I HIEUH
+0xB56A	0xD0C2	#HANGUL SYLLABLE THIEUTH A SSANGKIYEOK
+0xB56B	0xD0C3	#HANGUL SYLLABLE THIEUTH A KIYEOKSIOS
+0xB56C	0xD0C5	#HANGUL SYLLABLE THIEUTH A NIEUNCIEUC
+0xB56D	0xD0C6	#HANGUL SYLLABLE THIEUTH A NIEUNHIEUH
+0xB56E	0xD0C7	#HANGUL SYLLABLE THIEUTH A TIKEUT
+0xB56F	0xD0CA	#HANGUL SYLLABLE THIEUTH A RIEULMIEUM
+0xB570	0xD0CB	#HANGUL SYLLABLE THIEUTH A RIEULPIEUP
+0xB571	0xD0CC	#HANGUL SYLLABLE THIEUTH A RIEULSIOS
+0xB572	0xD0CD	#HANGUL SYLLABLE THIEUTH A RIEULTHIEUTH
+0xB573	0xD0CE	#HANGUL SYLLABLE THIEUTH A RIEULPHIEUPH
+0xB574	0xD0CF	#HANGUL SYLLABLE THIEUTH A RIEULHIEUH
+0xB575	0xD0D2	#HANGUL SYLLABLE THIEUTH A PIEUPSIOS
+0xB576	0xD0D6	#HANGUL SYLLABLE THIEUTH A CIEUC
+0xB577	0xD0D7	#HANGUL SYLLABLE THIEUTH A CHIEUCH
+0xB578	0xD0D8	#HANGUL SYLLABLE THIEUTH A KHIEUKH
+0xB579	0xD0D9	#HANGUL SYLLABLE THIEUTH A THIEUTH
+0xB57A	0xD0DA	#HANGUL SYLLABLE THIEUTH A PHIEUPH
+0xB581	0xD0DB	#HANGUL SYLLABLE THIEUTH A HIEUH
+0xB582	0xD0DE	#HANGUL SYLLABLE THIEUTH AE SSANGKIYEOK
+0xB583	0xD0DF	#HANGUL SYLLABLE THIEUTH AE KIYEOKSIOS
+0xB584	0xD0E1	#HANGUL SYLLABLE THIEUTH AE NIEUNCIEUC
+0xB585	0xD0E2	#HANGUL SYLLABLE THIEUTH AE NIEUNHIEUH
+0xB586	0xD0E3	#HANGUL SYLLABLE THIEUTH AE TIKEUT
+0xB587	0xD0E5	#HANGUL SYLLABLE THIEUTH AE RIEULKIYEOK
+0xB588	0xD0E6	#HANGUL SYLLABLE THIEUTH AE RIEULMIEUM
+0xB589	0xD0E7	#HANGUL SYLLABLE THIEUTH AE RIEULPIEUP
+0xB58A	0xD0E8	#HANGUL SYLLABLE THIEUTH AE RIEULSIOS
+0xB58B	0xD0E9	#HANGUL SYLLABLE THIEUTH AE RIEULTHIEUTH
+0xB58C	0xD0EA	#HANGUL SYLLABLE THIEUTH AE RIEULPHIEUPH
+0xB58D	0xD0EB	#HANGUL SYLLABLE THIEUTH AE RIEULHIEUH
+0xB58E	0xD0EE	#HANGUL SYLLABLE THIEUTH AE PIEUPSIOS
+0xB58F	0xD0F2	#HANGUL SYLLABLE THIEUTH AE CIEUC
+0xB590	0xD0F3	#HANGUL SYLLABLE THIEUTH AE CHIEUCH
+0xB591	0xD0F4	#HANGUL SYLLABLE THIEUTH AE KHIEUKH
+0xB592	0xD0F5	#HANGUL SYLLABLE THIEUTH AE THIEUTH
+0xB593	0xD0F6	#HANGUL SYLLABLE THIEUTH AE PHIEUPH
+0xB594	0xD0F7	#HANGUL SYLLABLE THIEUTH AE HIEUH
+0xB595	0xD0F9	#HANGUL SYLLABLE THIEUTH YA KIYEOK
+0xB596	0xD0FA	#HANGUL SYLLABLE THIEUTH YA SSANGKIYEOK
+0xB597	0xD0FB	#HANGUL SYLLABLE THIEUTH YA KIYEOKSIOS
+0xB598	0xD0FC	#HANGUL SYLLABLE THIEUTH YA NIEUN
+0xB599	0xD0FD	#HANGUL SYLLABLE THIEUTH YA NIEUNCIEUC
+0xB59A	0xD0FE	#HANGUL SYLLABLE THIEUTH YA NIEUNHIEUH
+0xB59B	0xD0FF	#HANGUL SYLLABLE THIEUTH YA TIKEUT
+0xB59C	0xD100	#HANGUL SYLLABLE THIEUTH YA RIEUL
+0xB59D	0xD101	#HANGUL SYLLABLE THIEUTH YA RIEULKIYEOK
+0xB59E	0xD102	#HANGUL SYLLABLE THIEUTH YA RIEULMIEUM
+0xB59F	0xD103	#HANGUL SYLLABLE THIEUTH YA RIEULPIEUP
+0xB5A0	0xD104	#HANGUL SYLLABLE THIEUTH YA RIEULSIOS
+0xB5A1	0xB367	#HANGUL SYLLABLE TIKEUT EO SIOS
+0xB5A2	0xB369	#HANGUL SYLLABLE TIKEUT EO IEUNG
+0xB5A3	0xB36B	#HANGUL SYLLABLE TIKEUT EO CHIEUCH
+0xB5A4	0xB36E	#HANGUL SYLLABLE TIKEUT EO PHIEUPH
+0xB5A5	0xB370	#HANGUL SYLLABLE TIKEUT E
+0xB5A6	0xB371	#HANGUL SYLLABLE TIKEUT E KIYEOK
+0xB5A7	0xB374	#HANGUL SYLLABLE TIKEUT E NIEUN
+0xB5A8	0xB378	#HANGUL SYLLABLE TIKEUT E RIEUL
+0xB5A9	0xB380	#HANGUL SYLLABLE TIKEUT E MIEUM
+0xB5AA	0xB381	#HANGUL SYLLABLE TIKEUT E PIEUP
+0xB5AB	0xB383	#HANGUL SYLLABLE TIKEUT E SIOS
+0xB5AC	0xB384	#HANGUL SYLLABLE TIKEUT E SSANGSIOS
+0xB5AD	0xB385	#HANGUL SYLLABLE TIKEUT E IEUNG
+0xB5AE	0xB38C	#HANGUL SYLLABLE TIKEUT YEO
+0xB5AF	0xB390	#HANGUL SYLLABLE TIKEUT YEO NIEUN
+0xB5B0	0xB394	#HANGUL SYLLABLE TIKEUT YEO RIEUL
+0xB5B1	0xB3A0	#HANGUL SYLLABLE TIKEUT YEO SSANGSIOS
+0xB5B2	0xB3A1	#HANGUL SYLLABLE TIKEUT YEO IEUNG
+0xB5B3	0xB3A8	#HANGUL SYLLABLE TIKEUT YE
+0xB5B4	0xB3AC	#HANGUL SYLLABLE TIKEUT YE NIEUN
+0xB5B5	0xB3C4	#HANGUL SYLLABLE TIKEUT O
+0xB5B6	0xB3C5	#HANGUL SYLLABLE TIKEUT O KIYEOK
+0xB5B7	0xB3C8	#HANGUL SYLLABLE TIKEUT O NIEUN
+0xB5B8	0xB3CB	#HANGUL SYLLABLE TIKEUT O TIKEUT
+0xB5B9	0xB3CC	#HANGUL SYLLABLE TIKEUT O RIEUL
+0xB5BA	0xB3CE	#HANGUL SYLLABLE TIKEUT O RIEULMIEUM
+0xB5BB	0xB3D0	#HANGUL SYLLABLE TIKEUT O RIEULSIOS
+0xB5BC	0xB3D4	#HANGUL SYLLABLE TIKEUT O MIEUM
+0xB5BD	0xB3D5	#HANGUL SYLLABLE TIKEUT O PIEUP
+0xB5BE	0xB3D7	#HANGUL SYLLABLE TIKEUT O SIOS
+0xB5BF	0xB3D9	#HANGUL SYLLABLE TIKEUT O IEUNG
+0xB5C0	0xB3DB	#HANGUL SYLLABLE TIKEUT O CHIEUCH
+0xB5C1	0xB3DD	#HANGUL SYLLABLE TIKEUT O THIEUTH
+0xB5C2	0xB3E0	#HANGUL SYLLABLE TIKEUT WA
+0xB5C3	0xB3E4	#HANGUL SYLLABLE TIKEUT WA NIEUN
+0xB5C4	0xB3E8	#HANGUL SYLLABLE TIKEUT WA RIEUL
+0xB5C5	0xB3FC	#HANGUL SYLLABLE TIKEUT WAE
+0xB5C6	0xB410	#HANGUL SYLLABLE TIKEUT WAE SSANGSIOS
+0xB5C7	0xB418	#HANGUL SYLLABLE TIKEUT OE
+0xB5C8	0xB41C	#HANGUL SYLLABLE TIKEUT OE NIEUN
+0xB5C9	0xB420	#HANGUL SYLLABLE TIKEUT OE RIEUL
+0xB5CA	0xB428	#HANGUL SYLLABLE TIKEUT OE MIEUM
+0xB5CB	0xB429	#HANGUL SYLLABLE TIKEUT OE PIEUP
+0xB5CC	0xB42B	#HANGUL SYLLABLE TIKEUT OE SIOS
+0xB5CD	0xB434	#HANGUL SYLLABLE TIKEUT YO
+0xB5CE	0xB450	#HANGUL SYLLABLE TIKEUT U
+0xB5CF	0xB451	#HANGUL SYLLABLE TIKEUT U KIYEOK
+0xB5D0	0xB454	#HANGUL SYLLABLE TIKEUT U NIEUN
+0xB5D1	0xB458	#HANGUL SYLLABLE TIKEUT U RIEUL
+0xB5D2	0xB460	#HANGUL SYLLABLE TIKEUT U MIEUM
+0xB5D3	0xB461	#HANGUL SYLLABLE TIKEUT U PIEUP
+0xB5D4	0xB463	#HANGUL SYLLABLE TIKEUT U SIOS
+0xB5D5	0xB465	#HANGUL SYLLABLE TIKEUT U IEUNG
+0xB5D6	0xB46C	#HANGUL SYLLABLE TIKEUT WEO
+0xB5D7	0xB480	#HANGUL SYLLABLE TIKEUT WEO SSANGSIOS
+0xB5D8	0xB488	#HANGUL SYLLABLE TIKEUT WE
+0xB5D9	0xB49D	#HANGUL SYLLABLE TIKEUT WE IEUNG
+0xB5DA	0xB4A4	#HANGUL SYLLABLE TIKEUT WI
+0xB5DB	0xB4A8	#HANGUL SYLLABLE TIKEUT WI NIEUN
+0xB5DC	0xB4AC	#HANGUL SYLLABLE TIKEUT WI RIEUL
+0xB5DD	0xB4B5	#HANGUL SYLLABLE TIKEUT WI PIEUP
+0xB5DE	0xB4B7	#HANGUL SYLLABLE TIKEUT WI SIOS
+0xB5DF	0xB4B9	#HANGUL SYLLABLE TIKEUT WI IEUNG
+0xB5E0	0xB4C0	#HANGUL SYLLABLE TIKEUT YU
+0xB5E1	0xB4C4	#HANGUL SYLLABLE TIKEUT YU NIEUN
+0xB5E2	0xB4C8	#HANGUL SYLLABLE TIKEUT YU RIEUL
+0xB5E3	0xB4D0	#HANGUL SYLLABLE TIKEUT YU MIEUM
+0xB5E4	0xB4D5	#HANGUL SYLLABLE TIKEUT YU IEUNG
+0xB5E5	0xB4DC	#HANGUL SYLLABLE TIKEUT EU
+0xB5E6	0xB4DD	#HANGUL SYLLABLE TIKEUT EU KIYEOK
+0xB5E7	0xB4E0	#HANGUL SYLLABLE TIKEUT EU NIEUN
+0xB5E8	0xB4E3	#HANGUL SYLLABLE TIKEUT EU TIKEUT
+0xB5E9	0xB4E4	#HANGUL SYLLABLE TIKEUT EU RIEUL
+0xB5EA	0xB4E6	#HANGUL SYLLABLE TIKEUT EU RIEULMIEUM
+0xB5EB	0xB4EC	#HANGUL SYLLABLE TIKEUT EU MIEUM
+0xB5EC	0xB4ED	#HANGUL SYLLABLE TIKEUT EU PIEUP
+0xB5ED	0xB4EF	#HANGUL SYLLABLE TIKEUT EU SIOS
+0xB5EE	0xB4F1	#HANGUL SYLLABLE TIKEUT EU IEUNG
+0xB5EF	0xB4F8	#HANGUL SYLLABLE TIKEUT YI
+0xB5F0	0xB514	#HANGUL SYLLABLE TIKEUT I
+0xB5F1	0xB515	#HANGUL SYLLABLE TIKEUT I KIYEOK
+0xB5F2	0xB518	#HANGUL SYLLABLE TIKEUT I NIEUN
+0xB5F3	0xB51B	#HANGUL SYLLABLE TIKEUT I TIKEUT
+0xB5F4	0xB51C	#HANGUL SYLLABLE TIKEUT I RIEUL
+0xB5F5	0xB524	#HANGUL SYLLABLE TIKEUT I MIEUM
+0xB5F6	0xB525	#HANGUL SYLLABLE TIKEUT I PIEUP
+0xB5F7	0xB527	#HANGUL SYLLABLE TIKEUT I SIOS
+0xB5F8	0xB528	#HANGUL SYLLABLE TIKEUT I SSANGSIOS
+0xB5F9	0xB529	#HANGUL SYLLABLE TIKEUT I IEUNG
+0xB5FA	0xB52A	#HANGUL SYLLABLE TIKEUT I CIEUC
+0xB5FB	0xB530	#HANGUL SYLLABLE SSANGTIKEUT A
+0xB5FC	0xB531	#HANGUL SYLLABLE SSANGTIKEUT A KIYEOK
+0xB5FD	0xB534	#HANGUL SYLLABLE SSANGTIKEUT A NIEUN
+0xB5FE	0xB538	#HANGUL SYLLABLE SSANGTIKEUT A RIEUL
+0xB641	0xD105	#HANGUL SYLLABLE THIEUTH YA RIEULTHIEUTH
+0xB642	0xD106	#HANGUL SYLLABLE THIEUTH YA RIEULPHIEUPH
+0xB643	0xD107	#HANGUL SYLLABLE THIEUTH YA RIEULHIEUH
+0xB644	0xD108	#HANGUL SYLLABLE THIEUTH YA MIEUM
+0xB645	0xD109	#HANGUL SYLLABLE THIEUTH YA PIEUP
+0xB646	0xD10A	#HANGUL SYLLABLE THIEUTH YA PIEUPSIOS
+0xB647	0xD10B	#HANGUL SYLLABLE THIEUTH YA SIOS
+0xB648	0xD10C	#HANGUL SYLLABLE THIEUTH YA SSANGSIOS
+0xB649	0xD10E	#HANGUL SYLLABLE THIEUTH YA CIEUC
+0xB64A	0xD10F	#HANGUL SYLLABLE THIEUTH YA CHIEUCH
+0xB64B	0xD110	#HANGUL SYLLABLE THIEUTH YA KHIEUKH
+0xB64C	0xD111	#HANGUL SYLLABLE THIEUTH YA THIEUTH
+0xB64D	0xD112	#HANGUL SYLLABLE THIEUTH YA PHIEUPH
+0xB64E	0xD113	#HANGUL SYLLABLE THIEUTH YA HIEUH
+0xB64F	0xD114	#HANGUL SYLLABLE THIEUTH YAE
+0xB650	0xD115	#HANGUL SYLLABLE THIEUTH YAE KIYEOK
+0xB651	0xD116	#HANGUL SYLLABLE THIEUTH YAE SSANGKIYEOK
+0xB652	0xD117	#HANGUL SYLLABLE THIEUTH YAE KIYEOKSIOS
+0xB653	0xD118	#HANGUL SYLLABLE THIEUTH YAE NIEUN
+0xB654	0xD119	#HANGUL SYLLABLE THIEUTH YAE NIEUNCIEUC
+0xB655	0xD11A	#HANGUL SYLLABLE THIEUTH YAE NIEUNHIEUH
+0xB656	0xD11B	#HANGUL SYLLABLE THIEUTH YAE TIKEUT
+0xB657	0xD11C	#HANGUL SYLLABLE THIEUTH YAE RIEUL
+0xB658	0xD11D	#HANGUL SYLLABLE THIEUTH YAE RIEULKIYEOK
+0xB659	0xD11E	#HANGUL SYLLABLE THIEUTH YAE RIEULMIEUM
+0xB65A	0xD11F	#HANGUL SYLLABLE THIEUTH YAE RIEULPIEUP
+0xB661	0xD120	#HANGUL SYLLABLE THIEUTH YAE RIEULSIOS
+0xB662	0xD121	#HANGUL SYLLABLE THIEUTH YAE RIEULTHIEUTH
+0xB663	0xD122	#HANGUL SYLLABLE THIEUTH YAE RIEULPHIEUPH
+0xB664	0xD123	#HANGUL SYLLABLE THIEUTH YAE RIEULHIEUH
+0xB665	0xD124	#HANGUL SYLLABLE THIEUTH YAE MIEUM
+0xB666	0xD125	#HANGUL SYLLABLE THIEUTH YAE PIEUP
+0xB667	0xD126	#HANGUL SYLLABLE THIEUTH YAE PIEUPSIOS
+0xB668	0xD127	#HANGUL SYLLABLE THIEUTH YAE SIOS
+0xB669	0xD128	#HANGUL SYLLABLE THIEUTH YAE SSANGSIOS
+0xB66A	0xD129	#HANGUL SYLLABLE THIEUTH YAE IEUNG
+0xB66B	0xD12A	#HANGUL SYLLABLE THIEUTH YAE CIEUC
+0xB66C	0xD12B	#HANGUL SYLLABLE THIEUTH YAE CHIEUCH
+0xB66D	0xD12C	#HANGUL SYLLABLE THIEUTH YAE KHIEUKH
+0xB66E	0xD12D	#HANGUL SYLLABLE THIEUTH YAE THIEUTH
+0xB66F	0xD12E	#HANGUL SYLLABLE THIEUTH YAE PHIEUPH
+0xB670	0xD12F	#HANGUL SYLLABLE THIEUTH YAE HIEUH
+0xB671	0xD132	#HANGUL SYLLABLE THIEUTH EO SSANGKIYEOK
+0xB672	0xD133	#HANGUL SYLLABLE THIEUTH EO KIYEOKSIOS
+0xB673	0xD135	#HANGUL SYLLABLE THIEUTH EO NIEUNCIEUC
+0xB674	0xD136	#HANGUL SYLLABLE THIEUTH EO NIEUNHIEUH
+0xB675	0xD137	#HANGUL SYLLABLE THIEUTH EO TIKEUT
+0xB676	0xD139	#HANGUL SYLLABLE THIEUTH EO RIEULKIYEOK
+0xB677	0xD13B	#HANGUL SYLLABLE THIEUTH EO RIEULPIEUP
+0xB678	0xD13C	#HANGUL SYLLABLE THIEUTH EO RIEULSIOS
+0xB679	0xD13D	#HANGUL SYLLABLE THIEUTH EO RIEULTHIEUTH
+0xB67A	0xD13E	#HANGUL SYLLABLE THIEUTH EO RIEULPHIEUPH
+0xB681	0xD13F	#HANGUL SYLLABLE THIEUTH EO RIEULHIEUH
+0xB682	0xD142	#HANGUL SYLLABLE THIEUTH EO PIEUPSIOS
+0xB683	0xD146	#HANGUL SYLLABLE THIEUTH EO CIEUC
+0xB684	0xD147	#HANGUL SYLLABLE THIEUTH EO CHIEUCH
+0xB685	0xD148	#HANGUL SYLLABLE THIEUTH EO KHIEUKH
+0xB686	0xD149	#HANGUL SYLLABLE THIEUTH EO THIEUTH
+0xB687	0xD14A	#HANGUL SYLLABLE THIEUTH EO PHIEUPH
+0xB688	0xD14B	#HANGUL SYLLABLE THIEUTH EO HIEUH
+0xB689	0xD14E	#HANGUL SYLLABLE THIEUTH E SSANGKIYEOK
+0xB68A	0xD14F	#HANGUL SYLLABLE THIEUTH E KIYEOKSIOS
+0xB68B	0xD151	#HANGUL SYLLABLE THIEUTH E NIEUNCIEUC
+0xB68C	0xD152	#HANGUL SYLLABLE THIEUTH E NIEUNHIEUH
+0xB68D	0xD153	#HANGUL SYLLABLE THIEUTH E TIKEUT
+0xB68E	0xD155	#HANGUL SYLLABLE THIEUTH E RIEULKIYEOK
+0xB68F	0xD156	#HANGUL SYLLABLE THIEUTH E RIEULMIEUM
+0xB690	0xD157	#HANGUL SYLLABLE THIEUTH E RIEULPIEUP
+0xB691	0xD158	#HANGUL SYLLABLE THIEUTH E RIEULSIOS
+0xB692	0xD159	#HANGUL SYLLABLE THIEUTH E RIEULTHIEUTH
+0xB693	0xD15A	#HANGUL SYLLABLE THIEUTH E RIEULPHIEUPH
+0xB694	0xD15B	#HANGUL SYLLABLE THIEUTH E RIEULHIEUH
+0xB695	0xD15E	#HANGUL SYLLABLE THIEUTH E PIEUPSIOS
+0xB696	0xD160	#HANGUL SYLLABLE THIEUTH E SSANGSIOS
+0xB697	0xD162	#HANGUL SYLLABLE THIEUTH E CIEUC
+0xB698	0xD163	#HANGUL SYLLABLE THIEUTH E CHIEUCH
+0xB699	0xD164	#HANGUL SYLLABLE THIEUTH E KHIEUKH
+0xB69A	0xD165	#HANGUL SYLLABLE THIEUTH E THIEUTH
+0xB69B	0xD166	#HANGUL SYLLABLE THIEUTH E PHIEUPH
+0xB69C	0xD167	#HANGUL SYLLABLE THIEUTH E HIEUH
+0xB69D	0xD169	#HANGUL SYLLABLE THIEUTH YEO KIYEOK
+0xB69E	0xD16A	#HANGUL SYLLABLE THIEUTH YEO SSANGKIYEOK
+0xB69F	0xD16B	#HANGUL SYLLABLE THIEUTH YEO KIYEOKSIOS
+0xB6A0	0xD16D	#HANGUL SYLLABLE THIEUTH YEO NIEUNCIEUC
+0xB6A1	0xB540	#HANGUL SYLLABLE SSANGTIKEUT A MIEUM
+0xB6A2	0xB541	#HANGUL SYLLABLE SSANGTIKEUT A PIEUP
+0xB6A3	0xB543	#HANGUL SYLLABLE SSANGTIKEUT A SIOS
+0xB6A4	0xB544	#HANGUL SYLLABLE SSANGTIKEUT A SSANGSIOS
+0xB6A5	0xB545	#HANGUL SYLLABLE SSANGTIKEUT A IEUNG
+0xB6A6	0xB54B	#HANGUL SYLLABLE SSANGTIKEUT A HIEUH
+0xB6A7	0xB54C	#HANGUL SYLLABLE SSANGTIKEUT AE
+0xB6A8	0xB54D	#HANGUL SYLLABLE SSANGTIKEUT AE KIYEOK
+0xB6A9	0xB550	#HANGUL SYLLABLE SSANGTIKEUT AE NIEUN
+0xB6AA	0xB554	#HANGUL SYLLABLE SSANGTIKEUT AE RIEUL
+0xB6AB	0xB55C	#HANGUL SYLLABLE SSANGTIKEUT AE MIEUM
+0xB6AC	0xB55D	#HANGUL SYLLABLE SSANGTIKEUT AE PIEUP
+0xB6AD	0xB55F	#HANGUL SYLLABLE SSANGTIKEUT AE SIOS
+0xB6AE	0xB560	#HANGUL SYLLABLE SSANGTIKEUT AE SSANGSIOS
+0xB6AF	0xB561	#HANGUL SYLLABLE SSANGTIKEUT AE IEUNG
+0xB6B0	0xB5A0	#HANGUL SYLLABLE SSANGTIKEUT EO
+0xB6B1	0xB5A1	#HANGUL SYLLABLE SSANGTIKEUT EO KIYEOK
+0xB6B2	0xB5A4	#HANGUL SYLLABLE SSANGTIKEUT EO NIEUN
+0xB6B3	0xB5A8	#HANGUL SYLLABLE SSANGTIKEUT EO RIEUL
+0xB6B4	0xB5AA	#HANGUL SYLLABLE SSANGTIKEUT EO RIEULMIEUM
+0xB6B5	0xB5AB	#HANGUL SYLLABLE SSANGTIKEUT EO RIEULPIEUP
+0xB6B6	0xB5B0	#HANGUL SYLLABLE SSANGTIKEUT EO MIEUM
+0xB6B7	0xB5B1	#HANGUL SYLLABLE SSANGTIKEUT EO PIEUP
+0xB6B8	0xB5B3	#HANGUL SYLLABLE SSANGTIKEUT EO SIOS
+0xB6B9	0xB5B4	#HANGUL SYLLABLE SSANGTIKEUT EO SSANGSIOS
+0xB6BA	0xB5B5	#HANGUL SYLLABLE SSANGTIKEUT EO IEUNG
+0xB6BB	0xB5BB	#HANGUL SYLLABLE SSANGTIKEUT EO HIEUH
+0xB6BC	0xB5BC	#HANGUL SYLLABLE SSANGTIKEUT E
+0xB6BD	0xB5BD	#HANGUL SYLLABLE SSANGTIKEUT E KIYEOK
+0xB6BE	0xB5C0	#HANGUL SYLLABLE SSANGTIKEUT E NIEUN
+0xB6BF	0xB5C4	#HANGUL SYLLABLE SSANGTIKEUT E RIEUL
+0xB6C0	0xB5CC	#HANGUL SYLLABLE SSANGTIKEUT E MIEUM
+0xB6C1	0xB5CD	#HANGUL SYLLABLE SSANGTIKEUT E PIEUP
+0xB6C2	0xB5CF	#HANGUL SYLLABLE SSANGTIKEUT E SIOS
+0xB6C3	0xB5D0	#HANGUL SYLLABLE SSANGTIKEUT E SSANGSIOS
+0xB6C4	0xB5D1	#HANGUL SYLLABLE SSANGTIKEUT E IEUNG
+0xB6C5	0xB5D8	#HANGUL SYLLABLE SSANGTIKEUT YEO
+0xB6C6	0xB5EC	#HANGUL SYLLABLE SSANGTIKEUT YEO SSANGSIOS
+0xB6C7	0xB610	#HANGUL SYLLABLE SSANGTIKEUT O
+0xB6C8	0xB611	#HANGUL SYLLABLE SSANGTIKEUT O KIYEOK
+0xB6C9	0xB614	#HANGUL SYLLABLE SSANGTIKEUT O NIEUN
+0xB6CA	0xB618	#HANGUL SYLLABLE SSANGTIKEUT O RIEUL
+0xB6CB	0xB625	#HANGUL SYLLABLE SSANGTIKEUT O IEUNG
+0xB6CC	0xB62C	#HANGUL SYLLABLE SSANGTIKEUT WA
+0xB6CD	0xB634	#HANGUL SYLLABLE SSANGTIKEUT WA RIEUL
+0xB6CE	0xB648	#HANGUL SYLLABLE SSANGTIKEUT WAE
+0xB6CF	0xB664	#HANGUL SYLLABLE SSANGTIKEUT OE
+0xB6D0	0xB668	#HANGUL SYLLABLE SSANGTIKEUT OE NIEUN
+0xB6D1	0xB69C	#HANGUL SYLLABLE SSANGTIKEUT U
+0xB6D2	0xB69D	#HANGUL SYLLABLE SSANGTIKEUT U KIYEOK
+0xB6D3	0xB6A0	#HANGUL SYLLABLE SSANGTIKEUT U NIEUN
+0xB6D4	0xB6A4	#HANGUL SYLLABLE SSANGTIKEUT U RIEUL
+0xB6D5	0xB6AB	#HANGUL SYLLABLE SSANGTIKEUT U RIEULHIEUH
+0xB6D6	0xB6AC	#HANGUL SYLLABLE SSANGTIKEUT U MIEUM
+0xB6D7	0xB6B1	#HANGUL SYLLABLE SSANGTIKEUT U IEUNG
+0xB6D8	0xB6D4	#HANGUL SYLLABLE SSANGTIKEUT WE
+0xB6D9	0xB6F0	#HANGUL SYLLABLE SSANGTIKEUT WI
+0xB6DA	0xB6F4	#HANGUL SYLLABLE SSANGTIKEUT WI NIEUN
+0xB6DB	0xB6F8	#HANGUL SYLLABLE SSANGTIKEUT WI RIEUL
+0xB6DC	0xB700	#HANGUL SYLLABLE SSANGTIKEUT WI MIEUM
+0xB6DD	0xB701	#HANGUL SYLLABLE SSANGTIKEUT WI PIEUP
+0xB6DE	0xB705	#HANGUL SYLLABLE SSANGTIKEUT WI IEUNG
+0xB6DF	0xB728	#HANGUL SYLLABLE SSANGTIKEUT EU
+0xB6E0	0xB729	#HANGUL SYLLABLE SSANGTIKEUT EU KIYEOK
+0xB6E1	0xB72C	#HANGUL SYLLABLE SSANGTIKEUT EU NIEUN
+0xB6E2	0xB72F	#HANGUL SYLLABLE SSANGTIKEUT EU TIKEUT
+0xB6E3	0xB730	#HANGUL SYLLABLE SSANGTIKEUT EU RIEUL
+0xB6E4	0xB738	#HANGUL SYLLABLE SSANGTIKEUT EU MIEUM
+0xB6E5	0xB739	#HANGUL SYLLABLE SSANGTIKEUT EU PIEUP
+0xB6E6	0xB73B	#HANGUL SYLLABLE SSANGTIKEUT EU SIOS
+0xB6E7	0xB744	#HANGUL SYLLABLE SSANGTIKEUT YI
+0xB6E8	0xB748	#HANGUL SYLLABLE SSANGTIKEUT YI NIEUN
+0xB6E9	0xB74C	#HANGUL SYLLABLE SSANGTIKEUT YI RIEUL
+0xB6EA	0xB754	#HANGUL SYLLABLE SSANGTIKEUT YI MIEUM
+0xB6EB	0xB755	#HANGUL SYLLABLE SSANGTIKEUT YI PIEUP
+0xB6EC	0xB760	#HANGUL SYLLABLE SSANGTIKEUT I
+0xB6ED	0xB764	#HANGUL SYLLABLE SSANGTIKEUT I NIEUN
+0xB6EE	0xB768	#HANGUL SYLLABLE SSANGTIKEUT I RIEUL
+0xB6EF	0xB770	#HANGUL SYLLABLE SSANGTIKEUT I MIEUM
+0xB6F0	0xB771	#HANGUL SYLLABLE SSANGTIKEUT I PIEUP
+0xB6F1	0xB773	#HANGUL SYLLABLE SSANGTIKEUT I SIOS
+0xB6F2	0xB775	#HANGUL SYLLABLE SSANGTIKEUT I IEUNG
+0xB6F3	0xB77C	#HANGUL SYLLABLE RIEUL A
+0xB6F4	0xB77D	#HANGUL SYLLABLE RIEUL A KIYEOK
+0xB6F5	0xB780	#HANGUL SYLLABLE RIEUL A NIEUN
+0xB6F6	0xB784	#HANGUL SYLLABLE RIEUL A RIEUL
+0xB6F7	0xB78C	#HANGUL SYLLABLE RIEUL A MIEUM
+0xB6F8	0xB78D	#HANGUL SYLLABLE RIEUL A PIEUP
+0xB6F9	0xB78F	#HANGUL SYLLABLE RIEUL A SIOS
+0xB6FA	0xB790	#HANGUL SYLLABLE RIEUL A SSANGSIOS
+0xB6FB	0xB791	#HANGUL SYLLABLE RIEUL A IEUNG
+0xB6FC	0xB792	#HANGUL SYLLABLE RIEUL A CIEUC
+0xB6FD	0xB796	#HANGUL SYLLABLE RIEUL A PHIEUPH
+0xB6FE	0xB797	#HANGUL SYLLABLE RIEUL A HIEUH
+0xB741	0xD16E	#HANGUL SYLLABLE THIEUTH YEO NIEUNHIEUH
+0xB742	0xD16F	#HANGUL SYLLABLE THIEUTH YEO TIKEUT
+0xB743	0xD170	#HANGUL SYLLABLE THIEUTH YEO RIEUL
+0xB744	0xD171	#HANGUL SYLLABLE THIEUTH YEO RIEULKIYEOK
+0xB745	0xD172	#HANGUL SYLLABLE THIEUTH YEO RIEULMIEUM
+0xB746	0xD173	#HANGUL SYLLABLE THIEUTH YEO RIEULPIEUP
+0xB747	0xD174	#HANGUL SYLLABLE THIEUTH YEO RIEULSIOS
+0xB748	0xD175	#HANGUL SYLLABLE THIEUTH YEO RIEULTHIEUTH
+0xB749	0xD176	#HANGUL SYLLABLE THIEUTH YEO RIEULPHIEUPH
+0xB74A	0xD177	#HANGUL SYLLABLE THIEUTH YEO RIEULHIEUH
+0xB74B	0xD178	#HANGUL SYLLABLE THIEUTH YEO MIEUM
+0xB74C	0xD179	#HANGUL SYLLABLE THIEUTH YEO PIEUP
+0xB74D	0xD17A	#HANGUL SYLLABLE THIEUTH YEO PIEUPSIOS
+0xB74E	0xD17B	#HANGUL SYLLABLE THIEUTH YEO SIOS
+0xB74F	0xD17D	#HANGUL SYLLABLE THIEUTH YEO IEUNG
+0xB750	0xD17E	#HANGUL SYLLABLE THIEUTH YEO CIEUC
+0xB751	0xD17F	#HANGUL SYLLABLE THIEUTH YEO CHIEUCH
+0xB752	0xD180	#HANGUL SYLLABLE THIEUTH YEO KHIEUKH
+0xB753	0xD181	#HANGUL SYLLABLE THIEUTH YEO THIEUTH
+0xB754	0xD182	#HANGUL SYLLABLE THIEUTH YEO PHIEUPH
+0xB755	0xD183	#HANGUL SYLLABLE THIEUTH YEO HIEUH
+0xB756	0xD185	#HANGUL SYLLABLE THIEUTH YE KIYEOK
+0xB757	0xD186	#HANGUL SYLLABLE THIEUTH YE SSANGKIYEOK
+0xB758	0xD187	#HANGUL SYLLABLE THIEUTH YE KIYEOKSIOS
+0xB759	0xD189	#HANGUL SYLLABLE THIEUTH YE NIEUNCIEUC
+0xB75A	0xD18A	#HANGUL SYLLABLE THIEUTH YE NIEUNHIEUH
+0xB761	0xD18B	#HANGUL SYLLABLE THIEUTH YE TIKEUT
+0xB762	0xD18C	#HANGUL SYLLABLE THIEUTH YE RIEUL
+0xB763	0xD18D	#HANGUL SYLLABLE THIEUTH YE RIEULKIYEOK
+0xB764	0xD18E	#HANGUL SYLLABLE THIEUTH YE RIEULMIEUM
+0xB765	0xD18F	#HANGUL SYLLABLE THIEUTH YE RIEULPIEUP
+0xB766	0xD190	#HANGUL SYLLABLE THIEUTH YE RIEULSIOS
+0xB767	0xD191	#HANGUL SYLLABLE THIEUTH YE RIEULTHIEUTH
+0xB768	0xD192	#HANGUL SYLLABLE THIEUTH YE RIEULPHIEUPH
+0xB769	0xD193	#HANGUL SYLLABLE THIEUTH YE RIEULHIEUH
+0xB76A	0xD194	#HANGUL SYLLABLE THIEUTH YE MIEUM
+0xB76B	0xD195	#HANGUL SYLLABLE THIEUTH YE PIEUP
+0xB76C	0xD196	#HANGUL SYLLABLE THIEUTH YE PIEUPSIOS
+0xB76D	0xD197	#HANGUL SYLLABLE THIEUTH YE SIOS
+0xB76E	0xD198	#HANGUL SYLLABLE THIEUTH YE SSANGSIOS
+0xB76F	0xD199	#HANGUL SYLLABLE THIEUTH YE IEUNG
+0xB770	0xD19A	#HANGUL SYLLABLE THIEUTH YE CIEUC
+0xB771	0xD19B	#HANGUL SYLLABLE THIEUTH YE CHIEUCH
+0xB772	0xD19C	#HANGUL SYLLABLE THIEUTH YE KHIEUKH
+0xB773	0xD19D	#HANGUL SYLLABLE THIEUTH YE THIEUTH
+0xB774	0xD19E	#HANGUL SYLLABLE THIEUTH YE PHIEUPH
+0xB775	0xD19F	#HANGUL SYLLABLE THIEUTH YE HIEUH
+0xB776	0xD1A2	#HANGUL SYLLABLE THIEUTH O SSANGKIYEOK
+0xB777	0xD1A3	#HANGUL SYLLABLE THIEUTH O KIYEOKSIOS
+0xB778	0xD1A5	#HANGUL SYLLABLE THIEUTH O NIEUNCIEUC
+0xB779	0xD1A6	#HANGUL SYLLABLE THIEUTH O NIEUNHIEUH
+0xB77A	0xD1A7	#HANGUL SYLLABLE THIEUTH O TIKEUT
+0xB781	0xD1A9	#HANGUL SYLLABLE THIEUTH O RIEULKIYEOK
+0xB782	0xD1AA	#HANGUL SYLLABLE THIEUTH O RIEULMIEUM
+0xB783	0xD1AB	#HANGUL SYLLABLE THIEUTH O RIEULPIEUP
+0xB784	0xD1AC	#HANGUL SYLLABLE THIEUTH O RIEULSIOS
+0xB785	0xD1AD	#HANGUL SYLLABLE THIEUTH O RIEULTHIEUTH
+0xB786	0xD1AE	#HANGUL SYLLABLE THIEUTH O RIEULPHIEUPH
+0xB787	0xD1AF	#HANGUL SYLLABLE THIEUTH O RIEULHIEUH
+0xB788	0xD1B2	#HANGUL SYLLABLE THIEUTH O PIEUPSIOS
+0xB789	0xD1B4	#HANGUL SYLLABLE THIEUTH O SSANGSIOS
+0xB78A	0xD1B6	#HANGUL SYLLABLE THIEUTH O CIEUC
+0xB78B	0xD1B7	#HANGUL SYLLABLE THIEUTH O CHIEUCH
+0xB78C	0xD1B8	#HANGUL SYLLABLE THIEUTH O KHIEUKH
+0xB78D	0xD1B9	#HANGUL SYLLABLE THIEUTH O THIEUTH
+0xB78E	0xD1BB	#HANGUL SYLLABLE THIEUTH O HIEUH
+0xB78F	0xD1BD	#HANGUL SYLLABLE THIEUTH WA KIYEOK
+0xB790	0xD1BE	#HANGUL SYLLABLE THIEUTH WA SSANGKIYEOK
+0xB791	0xD1BF	#HANGUL SYLLABLE THIEUTH WA KIYEOKSIOS
+0xB792	0xD1C1	#HANGUL SYLLABLE THIEUTH WA NIEUNCIEUC
+0xB793	0xD1C2	#HANGUL SYLLABLE THIEUTH WA NIEUNHIEUH
+0xB794	0xD1C3	#HANGUL SYLLABLE THIEUTH WA TIKEUT
+0xB795	0xD1C4	#HANGUL SYLLABLE THIEUTH WA RIEUL
+0xB796	0xD1C5	#HANGUL SYLLABLE THIEUTH WA RIEULKIYEOK
+0xB797	0xD1C6	#HANGUL SYLLABLE THIEUTH WA RIEULMIEUM
+0xB798	0xD1C7	#HANGUL SYLLABLE THIEUTH WA RIEULPIEUP
+0xB799	0xD1C8	#HANGUL SYLLABLE THIEUTH WA RIEULSIOS
+0xB79A	0xD1C9	#HANGUL SYLLABLE THIEUTH WA RIEULTHIEUTH
+0xB79B	0xD1CA	#HANGUL SYLLABLE THIEUTH WA RIEULPHIEUPH
+0xB79C	0xD1CB	#HANGUL SYLLABLE THIEUTH WA RIEULHIEUH
+0xB79D	0xD1CC	#HANGUL SYLLABLE THIEUTH WA MIEUM
+0xB79E	0xD1CD	#HANGUL SYLLABLE THIEUTH WA PIEUP
+0xB79F	0xD1CE	#HANGUL SYLLABLE THIEUTH WA PIEUPSIOS
+0xB7A0	0xD1CF	#HANGUL SYLLABLE THIEUTH WA SIOS
+0xB7A1	0xB798	#HANGUL SYLLABLE RIEUL AE
+0xB7A2	0xB799	#HANGUL SYLLABLE RIEUL AE KIYEOK
+0xB7A3	0xB79C	#HANGUL SYLLABLE RIEUL AE NIEUN
+0xB7A4	0xB7A0	#HANGUL SYLLABLE RIEUL AE RIEUL
+0xB7A5	0xB7A8	#HANGUL SYLLABLE RIEUL AE MIEUM
+0xB7A6	0xB7A9	#HANGUL SYLLABLE RIEUL AE PIEUP
+0xB7A7	0xB7AB	#HANGUL SYLLABLE RIEUL AE SIOS
+0xB7A8	0xB7AC	#HANGUL SYLLABLE RIEUL AE SSANGSIOS
+0xB7A9	0xB7AD	#HANGUL SYLLABLE RIEUL AE IEUNG
+0xB7AA	0xB7B4	#HANGUL SYLLABLE RIEUL YA
+0xB7AB	0xB7B5	#HANGUL SYLLABLE RIEUL YA KIYEOK
+0xB7AC	0xB7B8	#HANGUL SYLLABLE RIEUL YA NIEUN
+0xB7AD	0xB7C7	#HANGUL SYLLABLE RIEUL YA SIOS
+0xB7AE	0xB7C9	#HANGUL SYLLABLE RIEUL YA IEUNG
+0xB7AF	0xB7EC	#HANGUL SYLLABLE RIEUL EO
+0xB7B0	0xB7ED	#HANGUL SYLLABLE RIEUL EO KIYEOK
+0xB7B1	0xB7F0	#HANGUL SYLLABLE RIEUL EO NIEUN
+0xB7B2	0xB7F4	#HANGUL SYLLABLE RIEUL EO RIEUL
+0xB7B3	0xB7FC	#HANGUL SYLLABLE RIEUL EO MIEUM
+0xB7B4	0xB7FD	#HANGUL SYLLABLE RIEUL EO PIEUP
+0xB7B5	0xB7FF	#HANGUL SYLLABLE RIEUL EO SIOS
+0xB7B6	0xB800	#HANGUL SYLLABLE RIEUL EO SSANGSIOS
+0xB7B7	0xB801	#HANGUL SYLLABLE RIEUL EO IEUNG
+0xB7B8	0xB807	#HANGUL SYLLABLE RIEUL EO HIEUH
+0xB7B9	0xB808	#HANGUL SYLLABLE RIEUL E
+0xB7BA	0xB809	#HANGUL SYLLABLE RIEUL E KIYEOK
+0xB7BB	0xB80C	#HANGUL SYLLABLE RIEUL E NIEUN
+0xB7BC	0xB810	#HANGUL SYLLABLE RIEUL E RIEUL
+0xB7BD	0xB818	#HANGUL SYLLABLE RIEUL E MIEUM
+0xB7BE	0xB819	#HANGUL SYLLABLE RIEUL E PIEUP
+0xB7BF	0xB81B	#HANGUL SYLLABLE RIEUL E SIOS
+0xB7C0	0xB81D	#HANGUL SYLLABLE RIEUL E IEUNG
+0xB7C1	0xB824	#HANGUL SYLLABLE RIEUL YEO
+0xB7C2	0xB825	#HANGUL SYLLABLE RIEUL YEO KIYEOK
+0xB7C3	0xB828	#HANGUL SYLLABLE RIEUL YEO NIEUN
+0xB7C4	0xB82C	#HANGUL SYLLABLE RIEUL YEO RIEUL
+0xB7C5	0xB834	#HANGUL SYLLABLE RIEUL YEO MIEUM
+0xB7C6	0xB835	#HANGUL SYLLABLE RIEUL YEO PIEUP
+0xB7C7	0xB837	#HANGUL SYLLABLE RIEUL YEO SIOS
+0xB7C8	0xB838	#HANGUL SYLLABLE RIEUL YEO SSANGSIOS
+0xB7C9	0xB839	#HANGUL SYLLABLE RIEUL YEO IEUNG
+0xB7CA	0xB840	#HANGUL SYLLABLE RIEUL YE
+0xB7CB	0xB844	#HANGUL SYLLABLE RIEUL YE NIEUN
+0xB7CC	0xB851	#HANGUL SYLLABLE RIEUL YE PIEUP
+0xB7CD	0xB853	#HANGUL SYLLABLE RIEUL YE SIOS
+0xB7CE	0xB85C	#HANGUL SYLLABLE RIEUL O
+0xB7CF	0xB85D	#HANGUL SYLLABLE RIEUL O KIYEOK
+0xB7D0	0xB860	#HANGUL SYLLABLE RIEUL O NIEUN
+0xB7D1	0xB864	#HANGUL SYLLABLE RIEUL O RIEUL
+0xB7D2	0xB86C	#HANGUL SYLLABLE RIEUL O MIEUM
+0xB7D3	0xB86D	#HANGUL SYLLABLE RIEUL O PIEUP
+0xB7D4	0xB86F	#HANGUL SYLLABLE RIEUL O SIOS
+0xB7D5	0xB871	#HANGUL SYLLABLE RIEUL O IEUNG
+0xB7D6	0xB878	#HANGUL SYLLABLE RIEUL WA
+0xB7D7	0xB87C	#HANGUL SYLLABLE RIEUL WA NIEUN
+0xB7D8	0xB88D	#HANGUL SYLLABLE RIEUL WA IEUNG
+0xB7D9	0xB8A8	#HANGUL SYLLABLE RIEUL WAE SSANGSIOS
+0xB7DA	0xB8B0	#HANGUL SYLLABLE RIEUL OE
+0xB7DB	0xB8B4	#HANGUL SYLLABLE RIEUL OE NIEUN
+0xB7DC	0xB8B8	#HANGUL SYLLABLE RIEUL OE RIEUL
+0xB7DD	0xB8C0	#HANGUL SYLLABLE RIEUL OE MIEUM
+0xB7DE	0xB8C1	#HANGUL SYLLABLE RIEUL OE PIEUP
+0xB7DF	0xB8C3	#HANGUL SYLLABLE RIEUL OE SIOS
+0xB7E0	0xB8C5	#HANGUL SYLLABLE RIEUL OE IEUNG
+0xB7E1	0xB8CC	#HANGUL SYLLABLE RIEUL YO
+0xB7E2	0xB8D0	#HANGUL SYLLABLE RIEUL YO NIEUN
+0xB7E3	0xB8D4	#HANGUL SYLLABLE RIEUL YO RIEUL
+0xB7E4	0xB8DD	#HANGUL SYLLABLE RIEUL YO PIEUP
+0xB7E5	0xB8DF	#HANGUL SYLLABLE RIEUL YO SIOS
+0xB7E6	0xB8E1	#HANGUL SYLLABLE RIEUL YO IEUNG
+0xB7E7	0xB8E8	#HANGUL SYLLABLE RIEUL U
+0xB7E8	0xB8E9	#HANGUL SYLLABLE RIEUL U KIYEOK
+0xB7E9	0xB8EC	#HANGUL SYLLABLE RIEUL U NIEUN
+0xB7EA	0xB8F0	#HANGUL SYLLABLE RIEUL U RIEUL
+0xB7EB	0xB8F8	#HANGUL SYLLABLE RIEUL U MIEUM
+0xB7EC	0xB8F9	#HANGUL SYLLABLE RIEUL U PIEUP
+0xB7ED	0xB8FB	#HANGUL SYLLABLE RIEUL U SIOS
+0xB7EE	0xB8FD	#HANGUL SYLLABLE RIEUL U IEUNG
+0xB7EF	0xB904	#HANGUL SYLLABLE RIEUL WEO
+0xB7F0	0xB918	#HANGUL SYLLABLE RIEUL WEO SSANGSIOS
+0xB7F1	0xB920	#HANGUL SYLLABLE RIEUL WE
+0xB7F2	0xB93C	#HANGUL SYLLABLE RIEUL WI
+0xB7F3	0xB93D	#HANGUL SYLLABLE RIEUL WI KIYEOK
+0xB7F4	0xB940	#HANGUL SYLLABLE RIEUL WI NIEUN
+0xB7F5	0xB944	#HANGUL SYLLABLE RIEUL WI RIEUL
+0xB7F6	0xB94C	#HANGUL SYLLABLE RIEUL WI MIEUM
+0xB7F7	0xB94F	#HANGUL SYLLABLE RIEUL WI SIOS
+0xB7F8	0xB951	#HANGUL SYLLABLE RIEUL WI IEUNG
+0xB7F9	0xB958	#HANGUL SYLLABLE RIEUL YU
+0xB7FA	0xB959	#HANGUL SYLLABLE RIEUL YU KIYEOK
+0xB7FB	0xB95C	#HANGUL SYLLABLE RIEUL YU NIEUN
+0xB7FC	0xB960	#HANGUL SYLLABLE RIEUL YU RIEUL
+0xB7FD	0xB968	#HANGUL SYLLABLE RIEUL YU MIEUM
+0xB7FE	0xB969	#HANGUL SYLLABLE RIEUL YU PIEUP
+0xB841	0xD1D0	#HANGUL SYLLABLE THIEUTH WA SSANGSIOS
+0xB842	0xD1D1	#HANGUL SYLLABLE THIEUTH WA IEUNG
+0xB843	0xD1D2	#HANGUL SYLLABLE THIEUTH WA CIEUC
+0xB844	0xD1D3	#HANGUL SYLLABLE THIEUTH WA CHIEUCH
+0xB845	0xD1D4	#HANGUL SYLLABLE THIEUTH WA KHIEUKH
+0xB846	0xD1D5	#HANGUL SYLLABLE THIEUTH WA THIEUTH
+0xB847	0xD1D6	#HANGUL SYLLABLE THIEUTH WA PHIEUPH
+0xB848	0xD1D7	#HANGUL SYLLABLE THIEUTH WA HIEUH
+0xB849	0xD1D9	#HANGUL SYLLABLE THIEUTH WAE KIYEOK
+0xB84A	0xD1DA	#HANGUL SYLLABLE THIEUTH WAE SSANGKIYEOK
+0xB84B	0xD1DB	#HANGUL SYLLABLE THIEUTH WAE KIYEOKSIOS
+0xB84C	0xD1DC	#HANGUL SYLLABLE THIEUTH WAE NIEUN
+0xB84D	0xD1DD	#HANGUL SYLLABLE THIEUTH WAE NIEUNCIEUC
+0xB84E	0xD1DE	#HANGUL SYLLABLE THIEUTH WAE NIEUNHIEUH
+0xB84F	0xD1DF	#HANGUL SYLLABLE THIEUTH WAE TIKEUT
+0xB850	0xD1E0	#HANGUL SYLLABLE THIEUTH WAE RIEUL
+0xB851	0xD1E1	#HANGUL SYLLABLE THIEUTH WAE RIEULKIYEOK
+0xB852	0xD1E2	#HANGUL SYLLABLE THIEUTH WAE RIEULMIEUM
+0xB853	0xD1E3	#HANGUL SYLLABLE THIEUTH WAE RIEULPIEUP
+0xB854	0xD1E4	#HANGUL SYLLABLE THIEUTH WAE RIEULSIOS
+0xB855	0xD1E5	#HANGUL SYLLABLE THIEUTH WAE RIEULTHIEUTH
+0xB856	0xD1E6	#HANGUL SYLLABLE THIEUTH WAE RIEULPHIEUPH
+0xB857	0xD1E7	#HANGUL SYLLABLE THIEUTH WAE RIEULHIEUH
+0xB858	0xD1E8	#HANGUL SYLLABLE THIEUTH WAE MIEUM
+0xB859	0xD1E9	#HANGUL SYLLABLE THIEUTH WAE PIEUP
+0xB85A	0xD1EA	#HANGUL SYLLABLE THIEUTH WAE PIEUPSIOS
+0xB861	0xD1EB	#HANGUL SYLLABLE THIEUTH WAE SIOS
+0xB862	0xD1EC	#HANGUL SYLLABLE THIEUTH WAE SSANGSIOS
+0xB863	0xD1ED	#HANGUL SYLLABLE THIEUTH WAE IEUNG
+0xB864	0xD1EE	#HANGUL SYLLABLE THIEUTH WAE CIEUC
+0xB865	0xD1EF	#HANGUL SYLLABLE THIEUTH WAE CHIEUCH
+0xB866	0xD1F0	#HANGUL SYLLABLE THIEUTH WAE KHIEUKH
+0xB867	0xD1F1	#HANGUL SYLLABLE THIEUTH WAE THIEUTH
+0xB868	0xD1F2	#HANGUL SYLLABLE THIEUTH WAE PHIEUPH
+0xB869	0xD1F3	#HANGUL SYLLABLE THIEUTH WAE HIEUH
+0xB86A	0xD1F5	#HANGUL SYLLABLE THIEUTH OE KIYEOK
+0xB86B	0xD1F6	#HANGUL SYLLABLE THIEUTH OE SSANGKIYEOK
+0xB86C	0xD1F7	#HANGUL SYLLABLE THIEUTH OE KIYEOKSIOS
+0xB86D	0xD1F9	#HANGUL SYLLABLE THIEUTH OE NIEUNCIEUC
+0xB86E	0xD1FA	#HANGUL SYLLABLE THIEUTH OE NIEUNHIEUH
+0xB86F	0xD1FB	#HANGUL SYLLABLE THIEUTH OE TIKEUT
+0xB870	0xD1FC	#HANGUL SYLLABLE THIEUTH OE RIEUL
+0xB871	0xD1FD	#HANGUL SYLLABLE THIEUTH OE RIEULKIYEOK
+0xB872	0xD1FE	#HANGUL SYLLABLE THIEUTH OE RIEULMIEUM
+0xB873	0xD1FF	#HANGUL SYLLABLE THIEUTH OE RIEULPIEUP
+0xB874	0xD200	#HANGUL SYLLABLE THIEUTH OE RIEULSIOS
+0xB875	0xD201	#HANGUL SYLLABLE THIEUTH OE RIEULTHIEUTH
+0xB876	0xD202	#HANGUL SYLLABLE THIEUTH OE RIEULPHIEUPH
+0xB877	0xD203	#HANGUL SYLLABLE THIEUTH OE RIEULHIEUH
+0xB878	0xD204	#HANGUL SYLLABLE THIEUTH OE MIEUM
+0xB879	0xD205	#HANGUL SYLLABLE THIEUTH OE PIEUP
+0xB87A	0xD206	#HANGUL SYLLABLE THIEUTH OE PIEUPSIOS
+0xB881	0xD208	#HANGUL SYLLABLE THIEUTH OE SSANGSIOS
+0xB882	0xD20A	#HANGUL SYLLABLE THIEUTH OE CIEUC
+0xB883	0xD20B	#HANGUL SYLLABLE THIEUTH OE CHIEUCH
+0xB884	0xD20C	#HANGUL SYLLABLE THIEUTH OE KHIEUKH
+0xB885	0xD20D	#HANGUL SYLLABLE THIEUTH OE THIEUTH
+0xB886	0xD20E	#HANGUL SYLLABLE THIEUTH OE PHIEUPH
+0xB887	0xD20F	#HANGUL SYLLABLE THIEUTH OE HIEUH
+0xB888	0xD211	#HANGUL SYLLABLE THIEUTH YO KIYEOK
+0xB889	0xD212	#HANGUL SYLLABLE THIEUTH YO SSANGKIYEOK
+0xB88A	0xD213	#HANGUL SYLLABLE THIEUTH YO KIYEOKSIOS
+0xB88B	0xD214	#HANGUL SYLLABLE THIEUTH YO NIEUN
+0xB88C	0xD215	#HANGUL SYLLABLE THIEUTH YO NIEUNCIEUC
+0xB88D	0xD216	#HANGUL SYLLABLE THIEUTH YO NIEUNHIEUH
+0xB88E	0xD217	#HANGUL SYLLABLE THIEUTH YO TIKEUT
+0xB88F	0xD218	#HANGUL SYLLABLE THIEUTH YO RIEUL
+0xB890	0xD219	#HANGUL SYLLABLE THIEUTH YO RIEULKIYEOK
+0xB891	0xD21A	#HANGUL SYLLABLE THIEUTH YO RIEULMIEUM
+0xB892	0xD21B	#HANGUL SYLLABLE THIEUTH YO RIEULPIEUP
+0xB893	0xD21C	#HANGUL SYLLABLE THIEUTH YO RIEULSIOS
+0xB894	0xD21D	#HANGUL SYLLABLE THIEUTH YO RIEULTHIEUTH
+0xB895	0xD21E	#HANGUL SYLLABLE THIEUTH YO RIEULPHIEUPH
+0xB896	0xD21F	#HANGUL SYLLABLE THIEUTH YO RIEULHIEUH
+0xB897	0xD220	#HANGUL SYLLABLE THIEUTH YO MIEUM
+0xB898	0xD221	#HANGUL SYLLABLE THIEUTH YO PIEUP
+0xB899	0xD222	#HANGUL SYLLABLE THIEUTH YO PIEUPSIOS
+0xB89A	0xD223	#HANGUL SYLLABLE THIEUTH YO SIOS
+0xB89B	0xD224	#HANGUL SYLLABLE THIEUTH YO SSANGSIOS
+0xB89C	0xD225	#HANGUL SYLLABLE THIEUTH YO IEUNG
+0xB89D	0xD226	#HANGUL SYLLABLE THIEUTH YO CIEUC
+0xB89E	0xD227	#HANGUL SYLLABLE THIEUTH YO CHIEUCH
+0xB89F	0xD228	#HANGUL SYLLABLE THIEUTH YO KHIEUKH
+0xB8A0	0xD229	#HANGUL SYLLABLE THIEUTH YO THIEUTH
+0xB8A1	0xB96B	#HANGUL SYLLABLE RIEUL YU SIOS
+0xB8A2	0xB96D	#HANGUL SYLLABLE RIEUL YU IEUNG
+0xB8A3	0xB974	#HANGUL SYLLABLE RIEUL EU
+0xB8A4	0xB975	#HANGUL SYLLABLE RIEUL EU KIYEOK
+0xB8A5	0xB978	#HANGUL SYLLABLE RIEUL EU NIEUN
+0xB8A6	0xB97C	#HANGUL SYLLABLE RIEUL EU RIEUL
+0xB8A7	0xB984	#HANGUL SYLLABLE RIEUL EU MIEUM
+0xB8A8	0xB985	#HANGUL SYLLABLE RIEUL EU PIEUP
+0xB8A9	0xB987	#HANGUL SYLLABLE RIEUL EU SIOS
+0xB8AA	0xB989	#HANGUL SYLLABLE RIEUL EU IEUNG
+0xB8AB	0xB98A	#HANGUL SYLLABLE RIEUL EU CIEUC
+0xB8AC	0xB98D	#HANGUL SYLLABLE RIEUL EU THIEUTH
+0xB8AD	0xB98E	#HANGUL SYLLABLE RIEUL EU PHIEUPH
+0xB8AE	0xB9AC	#HANGUL SYLLABLE RIEUL I
+0xB8AF	0xB9AD	#HANGUL SYLLABLE RIEUL I KIYEOK
+0xB8B0	0xB9B0	#HANGUL SYLLABLE RIEUL I NIEUN
+0xB8B1	0xB9B4	#HANGUL SYLLABLE RIEUL I RIEUL
+0xB8B2	0xB9BC	#HANGUL SYLLABLE RIEUL I MIEUM
+0xB8B3	0xB9BD	#HANGUL SYLLABLE RIEUL I PIEUP
+0xB8B4	0xB9BF	#HANGUL SYLLABLE RIEUL I SIOS
+0xB8B5	0xB9C1	#HANGUL SYLLABLE RIEUL I IEUNG
+0xB8B6	0xB9C8	#HANGUL SYLLABLE MIEUM A
+0xB8B7	0xB9C9	#HANGUL SYLLABLE MIEUM A KIYEOK
+0xB8B8	0xB9CC	#HANGUL SYLLABLE MIEUM A NIEUN
+0xB8B9	0xB9CE	#HANGUL SYLLABLE MIEUM A NIEUNHIEUH
+0xB8BA	0xB9CF	#HANGUL SYLLABLE MIEUM A TIKEUT
+0xB8BB	0xB9D0	#HANGUL SYLLABLE MIEUM A RIEUL
+0xB8BC	0xB9D1	#HANGUL SYLLABLE MIEUM A RIEULKIYEOK
+0xB8BD	0xB9D2	#HANGUL SYLLABLE MIEUM A RIEULMIEUM
+0xB8BE	0xB9D8	#HANGUL SYLLABLE MIEUM A MIEUM
+0xB8BF	0xB9D9	#HANGUL SYLLABLE MIEUM A PIEUP
+0xB8C0	0xB9DB	#HANGUL SYLLABLE MIEUM A SIOS
+0xB8C1	0xB9DD	#HANGUL SYLLABLE MIEUM A IEUNG
+0xB8C2	0xB9DE	#HANGUL SYLLABLE MIEUM A CIEUC
+0xB8C3	0xB9E1	#HANGUL SYLLABLE MIEUM A THIEUTH
+0xB8C4	0xB9E3	#HANGUL SYLLABLE MIEUM A HIEUH
+0xB8C5	0xB9E4	#HANGUL SYLLABLE MIEUM AE
+0xB8C6	0xB9E5	#HANGUL SYLLABLE MIEUM AE KIYEOK
+0xB8C7	0xB9E8	#HANGUL SYLLABLE MIEUM AE NIEUN
+0xB8C8	0xB9EC	#HANGUL SYLLABLE MIEUM AE RIEUL
+0xB8C9	0xB9F4	#HANGUL SYLLABLE MIEUM AE MIEUM
+0xB8CA	0xB9F5	#HANGUL SYLLABLE MIEUM AE PIEUP
+0xB8CB	0xB9F7	#HANGUL SYLLABLE MIEUM AE SIOS
+0xB8CC	0xB9F8	#HANGUL SYLLABLE MIEUM AE SSANGSIOS
+0xB8CD	0xB9F9	#HANGUL SYLLABLE MIEUM AE IEUNG
+0xB8CE	0xB9FA	#HANGUL SYLLABLE MIEUM AE CIEUC
+0xB8CF	0xBA00	#HANGUL SYLLABLE MIEUM YA
+0xB8D0	0xBA01	#HANGUL SYLLABLE MIEUM YA KIYEOK
+0xB8D1	0xBA08	#HANGUL SYLLABLE MIEUM YA RIEUL
+0xB8D2	0xBA15	#HANGUL SYLLABLE MIEUM YA IEUNG
+0xB8D3	0xBA38	#HANGUL SYLLABLE MIEUM EO
+0xB8D4	0xBA39	#HANGUL SYLLABLE MIEUM EO KIYEOK
+0xB8D5	0xBA3C	#HANGUL SYLLABLE MIEUM EO NIEUN
+0xB8D6	0xBA40	#HANGUL SYLLABLE MIEUM EO RIEUL
+0xB8D7	0xBA42	#HANGUL SYLLABLE MIEUM EO RIEULMIEUM
+0xB8D8	0xBA48	#HANGUL SYLLABLE MIEUM EO MIEUM
+0xB8D9	0xBA49	#HANGUL SYLLABLE MIEUM EO PIEUP
+0xB8DA	0xBA4B	#HANGUL SYLLABLE MIEUM EO SIOS
+0xB8DB	0xBA4D	#HANGUL SYLLABLE MIEUM EO IEUNG
+0xB8DC	0xBA4E	#HANGUL SYLLABLE MIEUM EO CIEUC
+0xB8DD	0xBA53	#HANGUL SYLLABLE MIEUM EO HIEUH
+0xB8DE	0xBA54	#HANGUL SYLLABLE MIEUM E
+0xB8DF	0xBA55	#HANGUL SYLLABLE MIEUM E KIYEOK
+0xB8E0	0xBA58	#HANGUL SYLLABLE MIEUM E NIEUN
+0xB8E1	0xBA5C	#HANGUL SYLLABLE MIEUM E RIEUL
+0xB8E2	0xBA64	#HANGUL SYLLABLE MIEUM E MIEUM
+0xB8E3	0xBA65	#HANGUL SYLLABLE MIEUM E PIEUP
+0xB8E4	0xBA67	#HANGUL SYLLABLE MIEUM E SIOS
+0xB8E5	0xBA68	#HANGUL SYLLABLE MIEUM E SSANGSIOS
+0xB8E6	0xBA69	#HANGUL SYLLABLE MIEUM E IEUNG
+0xB8E7	0xBA70	#HANGUL SYLLABLE MIEUM YEO
+0xB8E8	0xBA71	#HANGUL SYLLABLE MIEUM YEO KIYEOK
+0xB8E9	0xBA74	#HANGUL SYLLABLE MIEUM YEO NIEUN
+0xB8EA	0xBA78	#HANGUL SYLLABLE MIEUM YEO RIEUL
+0xB8EB	0xBA83	#HANGUL SYLLABLE MIEUM YEO SIOS
+0xB8EC	0xBA84	#HANGUL SYLLABLE MIEUM YEO SSANGSIOS
+0xB8ED	0xBA85	#HANGUL SYLLABLE MIEUM YEO IEUNG
+0xB8EE	0xBA87	#HANGUL SYLLABLE MIEUM YEO CHIEUCH
+0xB8EF	0xBA8C	#HANGUL SYLLABLE MIEUM YE
+0xB8F0	0xBAA8	#HANGUL SYLLABLE MIEUM O
+0xB8F1	0xBAA9	#HANGUL SYLLABLE MIEUM O KIYEOK
+0xB8F2	0xBAAB	#HANGUL SYLLABLE MIEUM O KIYEOKSIOS
+0xB8F3	0xBAAC	#HANGUL SYLLABLE MIEUM O NIEUN
+0xB8F4	0xBAB0	#HANGUL SYLLABLE MIEUM O RIEUL
+0xB8F5	0xBAB2	#HANGUL SYLLABLE MIEUM O RIEULMIEUM
+0xB8F6	0xBAB8	#HANGUL SYLLABLE MIEUM O MIEUM
+0xB8F7	0xBAB9	#HANGUL SYLLABLE MIEUM O PIEUP
+0xB8F8	0xBABB	#HANGUL SYLLABLE MIEUM O SIOS
+0xB8F9	0xBABD	#HANGUL SYLLABLE MIEUM O IEUNG
+0xB8FA	0xBAC4	#HANGUL SYLLABLE MIEUM WA
+0xB8FB	0xBAC8	#HANGUL SYLLABLE MIEUM WA NIEUN
+0xB8FC	0xBAD8	#HANGUL SYLLABLE MIEUM WA SSANGSIOS
+0xB8FD	0xBAD9	#HANGUL SYLLABLE MIEUM WA IEUNG
+0xB8FE	0xBAFC	#HANGUL SYLLABLE MIEUM OE
+0xB941	0xD22A	#HANGUL SYLLABLE THIEUTH YO PHIEUPH
+0xB942	0xD22B	#HANGUL SYLLABLE THIEUTH YO HIEUH
+0xB943	0xD22E	#HANGUL SYLLABLE THIEUTH U SSANGKIYEOK
+0xB944	0xD22F	#HANGUL SYLLABLE THIEUTH U KIYEOKSIOS
+0xB945	0xD231	#HANGUL SYLLABLE THIEUTH U NIEUNCIEUC
+0xB946	0xD232	#HANGUL SYLLABLE THIEUTH U NIEUNHIEUH
+0xB947	0xD233	#HANGUL SYLLABLE THIEUTH U TIKEUT
+0xB948	0xD235	#HANGUL SYLLABLE THIEUTH U RIEULKIYEOK
+0xB949	0xD236	#HANGUL SYLLABLE THIEUTH U RIEULMIEUM
+0xB94A	0xD237	#HANGUL SYLLABLE THIEUTH U RIEULPIEUP
+0xB94B	0xD238	#HANGUL SYLLABLE THIEUTH U RIEULSIOS
+0xB94C	0xD239	#HANGUL SYLLABLE THIEUTH U RIEULTHIEUTH
+0xB94D	0xD23A	#HANGUL SYLLABLE THIEUTH U RIEULPHIEUPH
+0xB94E	0xD23B	#HANGUL SYLLABLE THIEUTH U RIEULHIEUH
+0xB94F	0xD23E	#HANGUL SYLLABLE THIEUTH U PIEUPSIOS
+0xB950	0xD240	#HANGUL SYLLABLE THIEUTH U SSANGSIOS
+0xB951	0xD242	#HANGUL SYLLABLE THIEUTH U CIEUC
+0xB952	0xD243	#HANGUL SYLLABLE THIEUTH U CHIEUCH
+0xB953	0xD244	#HANGUL SYLLABLE THIEUTH U KHIEUKH
+0xB954	0xD245	#HANGUL SYLLABLE THIEUTH U THIEUTH
+0xB955	0xD246	#HANGUL SYLLABLE THIEUTH U PHIEUPH
+0xB956	0xD247	#HANGUL SYLLABLE THIEUTH U HIEUH
+0xB957	0xD249	#HANGUL SYLLABLE THIEUTH WEO KIYEOK
+0xB958	0xD24A	#HANGUL SYLLABLE THIEUTH WEO SSANGKIYEOK
+0xB959	0xD24B	#HANGUL SYLLABLE THIEUTH WEO KIYEOKSIOS
+0xB95A	0xD24C	#HANGUL SYLLABLE THIEUTH WEO NIEUN
+0xB961	0xD24D	#HANGUL SYLLABLE THIEUTH WEO NIEUNCIEUC
+0xB962	0xD24E	#HANGUL SYLLABLE THIEUTH WEO NIEUNHIEUH
+0xB963	0xD24F	#HANGUL SYLLABLE THIEUTH WEO TIKEUT
+0xB964	0xD250	#HANGUL SYLLABLE THIEUTH WEO RIEUL
+0xB965	0xD251	#HANGUL SYLLABLE THIEUTH WEO RIEULKIYEOK
+0xB966	0xD252	#HANGUL SYLLABLE THIEUTH WEO RIEULMIEUM
+0xB967	0xD253	#HANGUL SYLLABLE THIEUTH WEO RIEULPIEUP
+0xB968	0xD254	#HANGUL SYLLABLE THIEUTH WEO RIEULSIOS
+0xB969	0xD255	#HANGUL SYLLABLE THIEUTH WEO RIEULTHIEUTH
+0xB96A	0xD256	#HANGUL SYLLABLE THIEUTH WEO RIEULPHIEUPH
+0xB96B	0xD257	#HANGUL SYLLABLE THIEUTH WEO RIEULHIEUH
+0xB96C	0xD258	#HANGUL SYLLABLE THIEUTH WEO MIEUM
+0xB96D	0xD259	#HANGUL SYLLABLE THIEUTH WEO PIEUP
+0xB96E	0xD25A	#HANGUL SYLLABLE THIEUTH WEO PIEUPSIOS
+0xB96F	0xD25B	#HANGUL SYLLABLE THIEUTH WEO SIOS
+0xB970	0xD25D	#HANGUL SYLLABLE THIEUTH WEO IEUNG
+0xB971	0xD25E	#HANGUL SYLLABLE THIEUTH WEO CIEUC
+0xB972	0xD25F	#HANGUL SYLLABLE THIEUTH WEO CHIEUCH
+0xB973	0xD260	#HANGUL SYLLABLE THIEUTH WEO KHIEUKH
+0xB974	0xD261	#HANGUL SYLLABLE THIEUTH WEO THIEUTH
+0xB975	0xD262	#HANGUL SYLLABLE THIEUTH WEO PHIEUPH
+0xB976	0xD263	#HANGUL SYLLABLE THIEUTH WEO HIEUH
+0xB977	0xD265	#HANGUL SYLLABLE THIEUTH WE KIYEOK
+0xB978	0xD266	#HANGUL SYLLABLE THIEUTH WE SSANGKIYEOK
+0xB979	0xD267	#HANGUL SYLLABLE THIEUTH WE KIYEOKSIOS
+0xB97A	0xD268	#HANGUL SYLLABLE THIEUTH WE NIEUN
+0xB981	0xD269	#HANGUL SYLLABLE THIEUTH WE NIEUNCIEUC
+0xB982	0xD26A	#HANGUL SYLLABLE THIEUTH WE NIEUNHIEUH
+0xB983	0xD26B	#HANGUL SYLLABLE THIEUTH WE TIKEUT
+0xB984	0xD26C	#HANGUL SYLLABLE THIEUTH WE RIEUL
+0xB985	0xD26D	#HANGUL SYLLABLE THIEUTH WE RIEULKIYEOK
+0xB986	0xD26E	#HANGUL SYLLABLE THIEUTH WE RIEULMIEUM
+0xB987	0xD26F	#HANGUL SYLLABLE THIEUTH WE RIEULPIEUP
+0xB988	0xD270	#HANGUL SYLLABLE THIEUTH WE RIEULSIOS
+0xB989	0xD271	#HANGUL SYLLABLE THIEUTH WE RIEULTHIEUTH
+0xB98A	0xD272	#HANGUL SYLLABLE THIEUTH WE RIEULPHIEUPH
+0xB98B	0xD273	#HANGUL SYLLABLE THIEUTH WE RIEULHIEUH
+0xB98C	0xD274	#HANGUL SYLLABLE THIEUTH WE MIEUM
+0xB98D	0xD275	#HANGUL SYLLABLE THIEUTH WE PIEUP
+0xB98E	0xD276	#HANGUL SYLLABLE THIEUTH WE PIEUPSIOS
+0xB98F	0xD277	#HANGUL SYLLABLE THIEUTH WE SIOS
+0xB990	0xD278	#HANGUL SYLLABLE THIEUTH WE SSANGSIOS
+0xB991	0xD279	#HANGUL SYLLABLE THIEUTH WE IEUNG
+0xB992	0xD27A	#HANGUL SYLLABLE THIEUTH WE CIEUC
+0xB993	0xD27B	#HANGUL SYLLABLE THIEUTH WE CHIEUCH
+0xB994	0xD27C	#HANGUL SYLLABLE THIEUTH WE KHIEUKH
+0xB995	0xD27D	#HANGUL SYLLABLE THIEUTH WE THIEUTH
+0xB996	0xD27E	#HANGUL SYLLABLE THIEUTH WE PHIEUPH
+0xB997	0xD27F	#HANGUL SYLLABLE THIEUTH WE HIEUH
+0xB998	0xD282	#HANGUL SYLLABLE THIEUTH WI SSANGKIYEOK
+0xB999	0xD283	#HANGUL SYLLABLE THIEUTH WI KIYEOKSIOS
+0xB99A	0xD285	#HANGUL SYLLABLE THIEUTH WI NIEUNCIEUC
+0xB99B	0xD286	#HANGUL SYLLABLE THIEUTH WI NIEUNHIEUH
+0xB99C	0xD287	#HANGUL SYLLABLE THIEUTH WI TIKEUT
+0xB99D	0xD289	#HANGUL SYLLABLE THIEUTH WI RIEULKIYEOK
+0xB99E	0xD28A	#HANGUL SYLLABLE THIEUTH WI RIEULMIEUM
+0xB99F	0xD28B	#HANGUL SYLLABLE THIEUTH WI RIEULPIEUP
+0xB9A0	0xD28C	#HANGUL SYLLABLE THIEUTH WI RIEULSIOS
+0xB9A1	0xBB00	#HANGUL SYLLABLE MIEUM OE NIEUN
+0xB9A2	0xBB04	#HANGUL SYLLABLE MIEUM OE RIEUL
+0xB9A3	0xBB0D	#HANGUL SYLLABLE MIEUM OE PIEUP
+0xB9A4	0xBB0F	#HANGUL SYLLABLE MIEUM OE SIOS
+0xB9A5	0xBB11	#HANGUL SYLLABLE MIEUM OE IEUNG
+0xB9A6	0xBB18	#HANGUL SYLLABLE MIEUM YO
+0xB9A7	0xBB1C	#HANGUL SYLLABLE MIEUM YO NIEUN
+0xB9A8	0xBB20	#HANGUL SYLLABLE MIEUM YO RIEUL
+0xB9A9	0xBB29	#HANGUL SYLLABLE MIEUM YO PIEUP
+0xB9AA	0xBB2B	#HANGUL SYLLABLE MIEUM YO SIOS
+0xB9AB	0xBB34	#HANGUL SYLLABLE MIEUM U
+0xB9AC	0xBB35	#HANGUL SYLLABLE MIEUM U KIYEOK
+0xB9AD	0xBB36	#HANGUL SYLLABLE MIEUM U SSANGKIYEOK
+0xB9AE	0xBB38	#HANGUL SYLLABLE MIEUM U NIEUN
+0xB9AF	0xBB3B	#HANGUL SYLLABLE MIEUM U TIKEUT
+0xB9B0	0xBB3C	#HANGUL SYLLABLE MIEUM U RIEUL
+0xB9B1	0xBB3D	#HANGUL SYLLABLE MIEUM U RIEULKIYEOK
+0xB9B2	0xBB3E	#HANGUL SYLLABLE MIEUM U RIEULMIEUM
+0xB9B3	0xBB44	#HANGUL SYLLABLE MIEUM U MIEUM
+0xB9B4	0xBB45	#HANGUL SYLLABLE MIEUM U PIEUP
+0xB9B5	0xBB47	#HANGUL SYLLABLE MIEUM U SIOS
+0xB9B6	0xBB49	#HANGUL SYLLABLE MIEUM U IEUNG
+0xB9B7	0xBB4D	#HANGUL SYLLABLE MIEUM U THIEUTH
+0xB9B8	0xBB4F	#HANGUL SYLLABLE MIEUM U HIEUH
+0xB9B9	0xBB50	#HANGUL SYLLABLE MIEUM WEO
+0xB9BA	0xBB54	#HANGUL SYLLABLE MIEUM WEO NIEUN
+0xB9BB	0xBB58	#HANGUL SYLLABLE MIEUM WEO RIEUL
+0xB9BC	0xBB61	#HANGUL SYLLABLE MIEUM WEO PIEUP
+0xB9BD	0xBB63	#HANGUL SYLLABLE MIEUM WEO SIOS
+0xB9BE	0xBB6C	#HANGUL SYLLABLE MIEUM WE
+0xB9BF	0xBB88	#HANGUL SYLLABLE MIEUM WI
+0xB9C0	0xBB8C	#HANGUL SYLLABLE MIEUM WI NIEUN
+0xB9C1	0xBB90	#HANGUL SYLLABLE MIEUM WI RIEUL
+0xB9C2	0xBBA4	#HANGUL SYLLABLE MIEUM YU
+0xB9C3	0xBBA8	#HANGUL SYLLABLE MIEUM YU NIEUN
+0xB9C4	0xBBAC	#HANGUL SYLLABLE MIEUM YU RIEUL
+0xB9C5	0xBBB4	#HANGUL SYLLABLE MIEUM YU MIEUM
+0xB9C6	0xBBB7	#HANGUL SYLLABLE MIEUM YU SIOS
+0xB9C7	0xBBC0	#HANGUL SYLLABLE MIEUM EU
+0xB9C8	0xBBC4	#HANGUL SYLLABLE MIEUM EU NIEUN
+0xB9C9	0xBBC8	#HANGUL SYLLABLE MIEUM EU RIEUL
+0xB9CA	0xBBD0	#HANGUL SYLLABLE MIEUM EU MIEUM
+0xB9CB	0xBBD3	#HANGUL SYLLABLE MIEUM EU SIOS
+0xB9CC	0xBBF8	#HANGUL SYLLABLE MIEUM I
+0xB9CD	0xBBF9	#HANGUL SYLLABLE MIEUM I KIYEOK
+0xB9CE	0xBBFC	#HANGUL SYLLABLE MIEUM I NIEUN
+0xB9CF	0xBBFF	#HANGUL SYLLABLE MIEUM I TIKEUT
+0xB9D0	0xBC00	#HANGUL SYLLABLE MIEUM I RIEUL
+0xB9D1	0xBC02	#HANGUL SYLLABLE MIEUM I RIEULMIEUM
+0xB9D2	0xBC08	#HANGUL SYLLABLE MIEUM I MIEUM
+0xB9D3	0xBC09	#HANGUL SYLLABLE MIEUM I PIEUP
+0xB9D4	0xBC0B	#HANGUL SYLLABLE MIEUM I SIOS
+0xB9D5	0xBC0C	#HANGUL SYLLABLE MIEUM I SSANGSIOS
+0xB9D6	0xBC0D	#HANGUL SYLLABLE MIEUM I IEUNG
+0xB9D7	0xBC0F	#HANGUL SYLLABLE MIEUM I CHIEUCH
+0xB9D8	0xBC11	#HANGUL SYLLABLE MIEUM I THIEUTH
+0xB9D9	0xBC14	#HANGUL SYLLABLE PIEUP A
+0xB9DA	0xBC15	#HANGUL SYLLABLE PIEUP A KIYEOK
+0xB9DB	0xBC16	#HANGUL SYLLABLE PIEUP A SSANGKIYEOK
+0xB9DC	0xBC17	#HANGUL SYLLABLE PIEUP A KIYEOKSIOS
+0xB9DD	0xBC18	#HANGUL SYLLABLE PIEUP A NIEUN
+0xB9DE	0xBC1B	#HANGUL SYLLABLE PIEUP A TIKEUT
+0xB9DF	0xBC1C	#HANGUL SYLLABLE PIEUP A RIEUL
+0xB9E0	0xBC1D	#HANGUL SYLLABLE PIEUP A RIEULKIYEOK
+0xB9E1	0xBC1E	#HANGUL SYLLABLE PIEUP A RIEULMIEUM
+0xB9E2	0xBC1F	#HANGUL SYLLABLE PIEUP A RIEULPIEUP
+0xB9E3	0xBC24	#HANGUL SYLLABLE PIEUP A MIEUM
+0xB9E4	0xBC25	#HANGUL SYLLABLE PIEUP A PIEUP
+0xB9E5	0xBC27	#HANGUL SYLLABLE PIEUP A SIOS
+0xB9E6	0xBC29	#HANGUL SYLLABLE PIEUP A IEUNG
+0xB9E7	0xBC2D	#HANGUL SYLLABLE PIEUP A THIEUTH
+0xB9E8	0xBC30	#HANGUL SYLLABLE PIEUP AE
+0xB9E9	0xBC31	#HANGUL SYLLABLE PIEUP AE KIYEOK
+0xB9EA	0xBC34	#HANGUL SYLLABLE PIEUP AE NIEUN
+0xB9EB	0xBC38	#HANGUL SYLLABLE PIEUP AE RIEUL
+0xB9EC	0xBC40	#HANGUL SYLLABLE PIEUP AE MIEUM
+0xB9ED	0xBC41	#HANGUL SYLLABLE PIEUP AE PIEUP
+0xB9EE	0xBC43	#HANGUL SYLLABLE PIEUP AE SIOS
+0xB9EF	0xBC44	#HANGUL SYLLABLE PIEUP AE SSANGSIOS
+0xB9F0	0xBC45	#HANGUL SYLLABLE PIEUP AE IEUNG
+0xB9F1	0xBC49	#HANGUL SYLLABLE PIEUP AE THIEUTH
+0xB9F2	0xBC4C	#HANGUL SYLLABLE PIEUP YA
+0xB9F3	0xBC4D	#HANGUL SYLLABLE PIEUP YA KIYEOK
+0xB9F4	0xBC50	#HANGUL SYLLABLE PIEUP YA NIEUN
+0xB9F5	0xBC5D	#HANGUL SYLLABLE PIEUP YA PIEUP
+0xB9F6	0xBC84	#HANGUL SYLLABLE PIEUP EO
+0xB9F7	0xBC85	#HANGUL SYLLABLE PIEUP EO KIYEOK
+0xB9F8	0xBC88	#HANGUL SYLLABLE PIEUP EO NIEUN
+0xB9F9	0xBC8B	#HANGUL SYLLABLE PIEUP EO TIKEUT
+0xB9FA	0xBC8C	#HANGUL SYLLABLE PIEUP EO RIEUL
+0xB9FB	0xBC8E	#HANGUL SYLLABLE PIEUP EO RIEULMIEUM
+0xB9FC	0xBC94	#HANGUL SYLLABLE PIEUP EO MIEUM
+0xB9FD	0xBC95	#HANGUL SYLLABLE PIEUP EO PIEUP
+0xB9FE	0xBC97	#HANGUL SYLLABLE PIEUP EO SIOS
+0xBA41	0xD28D	#HANGUL SYLLABLE THIEUTH WI RIEULTHIEUTH
+0xBA42	0xD28E	#HANGUL SYLLABLE THIEUTH WI RIEULPHIEUPH
+0xBA43	0xD28F	#HANGUL SYLLABLE THIEUTH WI RIEULHIEUH
+0xBA44	0xD292	#HANGUL SYLLABLE THIEUTH WI PIEUPSIOS
+0xBA45	0xD293	#HANGUL SYLLABLE THIEUTH WI SIOS
+0xBA46	0xD294	#HANGUL SYLLABLE THIEUTH WI SSANGSIOS
+0xBA47	0xD296	#HANGUL SYLLABLE THIEUTH WI CIEUC
+0xBA48	0xD297	#HANGUL SYLLABLE THIEUTH WI CHIEUCH
+0xBA49	0xD298	#HANGUL SYLLABLE THIEUTH WI KHIEUKH
+0xBA4A	0xD299	#HANGUL SYLLABLE THIEUTH WI THIEUTH
+0xBA4B	0xD29A	#HANGUL SYLLABLE THIEUTH WI PHIEUPH
+0xBA4C	0xD29B	#HANGUL SYLLABLE THIEUTH WI HIEUH
+0xBA4D	0xD29D	#HANGUL SYLLABLE THIEUTH YU KIYEOK
+0xBA4E	0xD29E	#HANGUL SYLLABLE THIEUTH YU SSANGKIYEOK
+0xBA4F	0xD29F	#HANGUL SYLLABLE THIEUTH YU KIYEOKSIOS
+0xBA50	0xD2A1	#HANGUL SYLLABLE THIEUTH YU NIEUNCIEUC
+0xBA51	0xD2A2	#HANGUL SYLLABLE THIEUTH YU NIEUNHIEUH
+0xBA52	0xD2A3	#HANGUL SYLLABLE THIEUTH YU TIKEUT
+0xBA53	0xD2A5	#HANGUL SYLLABLE THIEUTH YU RIEULKIYEOK
+0xBA54	0xD2A6	#HANGUL SYLLABLE THIEUTH YU RIEULMIEUM
+0xBA55	0xD2A7	#HANGUL SYLLABLE THIEUTH YU RIEULPIEUP
+0xBA56	0xD2A8	#HANGUL SYLLABLE THIEUTH YU RIEULSIOS
+0xBA57	0xD2A9	#HANGUL SYLLABLE THIEUTH YU RIEULTHIEUTH
+0xBA58	0xD2AA	#HANGUL SYLLABLE THIEUTH YU RIEULPHIEUPH
+0xBA59	0xD2AB	#HANGUL SYLLABLE THIEUTH YU RIEULHIEUH
+0xBA5A	0xD2AD	#HANGUL SYLLABLE THIEUTH YU PIEUP
+0xBA61	0xD2AE	#HANGUL SYLLABLE THIEUTH YU PIEUPSIOS
+0xBA62	0xD2AF	#HANGUL SYLLABLE THIEUTH YU SIOS
+0xBA63	0xD2B0	#HANGUL SYLLABLE THIEUTH YU SSANGSIOS
+0xBA64	0xD2B2	#HANGUL SYLLABLE THIEUTH YU CIEUC
+0xBA65	0xD2B3	#HANGUL SYLLABLE THIEUTH YU CHIEUCH
+0xBA66	0xD2B4	#HANGUL SYLLABLE THIEUTH YU KHIEUKH
+0xBA67	0xD2B5	#HANGUL SYLLABLE THIEUTH YU THIEUTH
+0xBA68	0xD2B6	#HANGUL SYLLABLE THIEUTH YU PHIEUPH
+0xBA69	0xD2B7	#HANGUL SYLLABLE THIEUTH YU HIEUH
+0xBA6A	0xD2BA	#HANGUL SYLLABLE THIEUTH EU SSANGKIYEOK
+0xBA6B	0xD2BB	#HANGUL SYLLABLE THIEUTH EU KIYEOKSIOS
+0xBA6C	0xD2BD	#HANGUL SYLLABLE THIEUTH EU NIEUNCIEUC
+0xBA6D	0xD2BE	#HANGUL SYLLABLE THIEUTH EU NIEUNHIEUH
+0xBA6E	0xD2C1	#HANGUL SYLLABLE THIEUTH EU RIEULKIYEOK
+0xBA6F	0xD2C3	#HANGUL SYLLABLE THIEUTH EU RIEULPIEUP
+0xBA70	0xD2C4	#HANGUL SYLLABLE THIEUTH EU RIEULSIOS
+0xBA71	0xD2C5	#HANGUL SYLLABLE THIEUTH EU RIEULTHIEUTH
+0xBA72	0xD2C6	#HANGUL SYLLABLE THIEUTH EU RIEULPHIEUPH
+0xBA73	0xD2C7	#HANGUL SYLLABLE THIEUTH EU RIEULHIEUH
+0xBA74	0xD2CA	#HANGUL SYLLABLE THIEUTH EU PIEUPSIOS
+0xBA75	0xD2CC	#HANGUL SYLLABLE THIEUTH EU SSANGSIOS
+0xBA76	0xD2CD	#HANGUL SYLLABLE THIEUTH EU IEUNG
+0xBA77	0xD2CE	#HANGUL SYLLABLE THIEUTH EU CIEUC
+0xBA78	0xD2CF	#HANGUL SYLLABLE THIEUTH EU CHIEUCH
+0xBA79	0xD2D0	#HANGUL SYLLABLE THIEUTH EU KHIEUKH
+0xBA7A	0xD2D1	#HANGUL SYLLABLE THIEUTH EU THIEUTH
+0xBA81	0xD2D2	#HANGUL SYLLABLE THIEUTH EU PHIEUPH
+0xBA82	0xD2D3	#HANGUL SYLLABLE THIEUTH EU HIEUH
+0xBA83	0xD2D5	#HANGUL SYLLABLE THIEUTH YI KIYEOK
+0xBA84	0xD2D6	#HANGUL SYLLABLE THIEUTH YI SSANGKIYEOK
+0xBA85	0xD2D7	#HANGUL SYLLABLE THIEUTH YI KIYEOKSIOS
+0xBA86	0xD2D9	#HANGUL SYLLABLE THIEUTH YI NIEUNCIEUC
+0xBA87	0xD2DA	#HANGUL SYLLABLE THIEUTH YI NIEUNHIEUH
+0xBA88	0xD2DB	#HANGUL SYLLABLE THIEUTH YI TIKEUT
+0xBA89	0xD2DD	#HANGUL SYLLABLE THIEUTH YI RIEULKIYEOK
+0xBA8A	0xD2DE	#HANGUL SYLLABLE THIEUTH YI RIEULMIEUM
+0xBA8B	0xD2DF	#HANGUL SYLLABLE THIEUTH YI RIEULPIEUP
+0xBA8C	0xD2E0	#HANGUL SYLLABLE THIEUTH YI RIEULSIOS
+0xBA8D	0xD2E1	#HANGUL SYLLABLE THIEUTH YI RIEULTHIEUTH
+0xBA8E	0xD2E2	#HANGUL SYLLABLE THIEUTH YI RIEULPHIEUPH
+0xBA8F	0xD2E3	#HANGUL SYLLABLE THIEUTH YI RIEULHIEUH
+0xBA90	0xD2E6	#HANGUL SYLLABLE THIEUTH YI PIEUPSIOS
+0xBA91	0xD2E7	#HANGUL SYLLABLE THIEUTH YI SIOS
+0xBA92	0xD2E8	#HANGUL SYLLABLE THIEUTH YI SSANGSIOS
+0xBA93	0xD2E9	#HANGUL SYLLABLE THIEUTH YI IEUNG
+0xBA94	0xD2EA	#HANGUL SYLLABLE THIEUTH YI CIEUC
+0xBA95	0xD2EB	#HANGUL SYLLABLE THIEUTH YI CHIEUCH
+0xBA96	0xD2EC	#HANGUL SYLLABLE THIEUTH YI KHIEUKH
+0xBA97	0xD2ED	#HANGUL SYLLABLE THIEUTH YI THIEUTH
+0xBA98	0xD2EE	#HANGUL SYLLABLE THIEUTH YI PHIEUPH
+0xBA99	0xD2EF	#HANGUL SYLLABLE THIEUTH YI HIEUH
+0xBA9A	0xD2F2	#HANGUL SYLLABLE THIEUTH I SSANGKIYEOK
+0xBA9B	0xD2F3	#HANGUL SYLLABLE THIEUTH I KIYEOKSIOS
+0xBA9C	0xD2F5	#HANGUL SYLLABLE THIEUTH I NIEUNCIEUC
+0xBA9D	0xD2F6	#HANGUL SYLLABLE THIEUTH I NIEUNHIEUH
+0xBA9E	0xD2F7	#HANGUL SYLLABLE THIEUTH I TIKEUT
+0xBA9F	0xD2F9	#HANGUL SYLLABLE THIEUTH I RIEULKIYEOK
+0xBAA0	0xD2FA	#HANGUL SYLLABLE THIEUTH I RIEULMIEUM
+0xBAA1	0xBC99	#HANGUL SYLLABLE PIEUP EO IEUNG
+0xBAA2	0xBC9A	#HANGUL SYLLABLE PIEUP EO CIEUC
+0xBAA3	0xBCA0	#HANGUL SYLLABLE PIEUP E
+0xBAA4	0xBCA1	#HANGUL SYLLABLE PIEUP E KIYEOK
+0xBAA5	0xBCA4	#HANGUL SYLLABLE PIEUP E NIEUN
+0xBAA6	0xBCA7	#HANGUL SYLLABLE PIEUP E TIKEUT
+0xBAA7	0xBCA8	#HANGUL SYLLABLE PIEUP E RIEUL
+0xBAA8	0xBCB0	#HANGUL SYLLABLE PIEUP E MIEUM
+0xBAA9	0xBCB1	#HANGUL SYLLABLE PIEUP E PIEUP
+0xBAAA	0xBCB3	#HANGUL SYLLABLE PIEUP E SIOS
+0xBAAB	0xBCB4	#HANGUL SYLLABLE PIEUP E SSANGSIOS
+0xBAAC	0xBCB5	#HANGUL SYLLABLE PIEUP E IEUNG
+0xBAAD	0xBCBC	#HANGUL SYLLABLE PIEUP YEO
+0xBAAE	0xBCBD	#HANGUL SYLLABLE PIEUP YEO KIYEOK
+0xBAAF	0xBCC0	#HANGUL SYLLABLE PIEUP YEO NIEUN
+0xBAB0	0xBCC4	#HANGUL SYLLABLE PIEUP YEO RIEUL
+0xBAB1	0xBCCD	#HANGUL SYLLABLE PIEUP YEO PIEUP
+0xBAB2	0xBCCF	#HANGUL SYLLABLE PIEUP YEO SIOS
+0xBAB3	0xBCD0	#HANGUL SYLLABLE PIEUP YEO SSANGSIOS
+0xBAB4	0xBCD1	#HANGUL SYLLABLE PIEUP YEO IEUNG
+0xBAB5	0xBCD5	#HANGUL SYLLABLE PIEUP YEO THIEUTH
+0xBAB6	0xBCD8	#HANGUL SYLLABLE PIEUP YE
+0xBAB7	0xBCDC	#HANGUL SYLLABLE PIEUP YE NIEUN
+0xBAB8	0xBCF4	#HANGUL SYLLABLE PIEUP O
+0xBAB9	0xBCF5	#HANGUL SYLLABLE PIEUP O KIYEOK
+0xBABA	0xBCF6	#HANGUL SYLLABLE PIEUP O SSANGKIYEOK
+0xBABB	0xBCF8	#HANGUL SYLLABLE PIEUP O NIEUN
+0xBABC	0xBCFC	#HANGUL SYLLABLE PIEUP O RIEUL
+0xBABD	0xBD04	#HANGUL SYLLABLE PIEUP O MIEUM
+0xBABE	0xBD05	#HANGUL SYLLABLE PIEUP O PIEUP
+0xBABF	0xBD07	#HANGUL SYLLABLE PIEUP O SIOS
+0xBAC0	0xBD09	#HANGUL SYLLABLE PIEUP O IEUNG
+0xBAC1	0xBD10	#HANGUL SYLLABLE PIEUP WA
+0xBAC2	0xBD14	#HANGUL SYLLABLE PIEUP WA NIEUN
+0xBAC3	0xBD24	#HANGUL SYLLABLE PIEUP WA SSANGSIOS
+0xBAC4	0xBD2C	#HANGUL SYLLABLE PIEUP WAE
+0xBAC5	0xBD40	#HANGUL SYLLABLE PIEUP WAE SSANGSIOS
+0xBAC6	0xBD48	#HANGUL SYLLABLE PIEUP OE
+0xBAC7	0xBD49	#HANGUL SYLLABLE PIEUP OE KIYEOK
+0xBAC8	0xBD4C	#HANGUL SYLLABLE PIEUP OE NIEUN
+0xBAC9	0xBD50	#HANGUL SYLLABLE PIEUP OE RIEUL
+0xBACA	0xBD58	#HANGUL SYLLABLE PIEUP OE MIEUM
+0xBACB	0xBD59	#HANGUL SYLLABLE PIEUP OE PIEUP
+0xBACC	0xBD64	#HANGUL SYLLABLE PIEUP YO
+0xBACD	0xBD68	#HANGUL SYLLABLE PIEUP YO NIEUN
+0xBACE	0xBD80	#HANGUL SYLLABLE PIEUP U
+0xBACF	0xBD81	#HANGUL SYLLABLE PIEUP U KIYEOK
+0xBAD0	0xBD84	#HANGUL SYLLABLE PIEUP U NIEUN
+0xBAD1	0xBD87	#HANGUL SYLLABLE PIEUP U TIKEUT
+0xBAD2	0xBD88	#HANGUL SYLLABLE PIEUP U RIEUL
+0xBAD3	0xBD89	#HANGUL SYLLABLE PIEUP U RIEULKIYEOK
+0xBAD4	0xBD8A	#HANGUL SYLLABLE PIEUP U RIEULMIEUM
+0xBAD5	0xBD90	#HANGUL SYLLABLE PIEUP U MIEUM
+0xBAD6	0xBD91	#HANGUL SYLLABLE PIEUP U PIEUP
+0xBAD7	0xBD93	#HANGUL SYLLABLE PIEUP U SIOS
+0xBAD8	0xBD95	#HANGUL SYLLABLE PIEUP U IEUNG
+0xBAD9	0xBD99	#HANGUL SYLLABLE PIEUP U THIEUTH
+0xBADA	0xBD9A	#HANGUL SYLLABLE PIEUP U PHIEUPH
+0xBADB	0xBD9C	#HANGUL SYLLABLE PIEUP WEO
+0xBADC	0xBDA4	#HANGUL SYLLABLE PIEUP WEO RIEUL
+0xBADD	0xBDB0	#HANGUL SYLLABLE PIEUP WEO SSANGSIOS
+0xBADE	0xBDB8	#HANGUL SYLLABLE PIEUP WE
+0xBADF	0xBDD4	#HANGUL SYLLABLE PIEUP WI
+0xBAE0	0xBDD5	#HANGUL SYLLABLE PIEUP WI KIYEOK
+0xBAE1	0xBDD8	#HANGUL SYLLABLE PIEUP WI NIEUN
+0xBAE2	0xBDDC	#HANGUL SYLLABLE PIEUP WI RIEUL
+0xBAE3	0xBDE9	#HANGUL SYLLABLE PIEUP WI IEUNG
+0xBAE4	0xBDF0	#HANGUL SYLLABLE PIEUP YU
+0xBAE5	0xBDF4	#HANGUL SYLLABLE PIEUP YU NIEUN
+0xBAE6	0xBDF8	#HANGUL SYLLABLE PIEUP YU RIEUL
+0xBAE7	0xBE00	#HANGUL SYLLABLE PIEUP YU MIEUM
+0xBAE8	0xBE03	#HANGUL SYLLABLE PIEUP YU SIOS
+0xBAE9	0xBE05	#HANGUL SYLLABLE PIEUP YU IEUNG
+0xBAEA	0xBE0C	#HANGUL SYLLABLE PIEUP EU
+0xBAEB	0xBE0D	#HANGUL SYLLABLE PIEUP EU KIYEOK
+0xBAEC	0xBE10	#HANGUL SYLLABLE PIEUP EU NIEUN
+0xBAED	0xBE14	#HANGUL SYLLABLE PIEUP EU RIEUL
+0xBAEE	0xBE1C	#HANGUL SYLLABLE PIEUP EU MIEUM
+0xBAEF	0xBE1D	#HANGUL SYLLABLE PIEUP EU PIEUP
+0xBAF0	0xBE1F	#HANGUL SYLLABLE PIEUP EU SIOS
+0xBAF1	0xBE44	#HANGUL SYLLABLE PIEUP I
+0xBAF2	0xBE45	#HANGUL SYLLABLE PIEUP I KIYEOK
+0xBAF3	0xBE48	#HANGUL SYLLABLE PIEUP I NIEUN
+0xBAF4	0xBE4C	#HANGUL SYLLABLE PIEUP I RIEUL
+0xBAF5	0xBE4E	#HANGUL SYLLABLE PIEUP I RIEULMIEUM
+0xBAF6	0xBE54	#HANGUL SYLLABLE PIEUP I MIEUM
+0xBAF7	0xBE55	#HANGUL SYLLABLE PIEUP I PIEUP
+0xBAF8	0xBE57	#HANGUL SYLLABLE PIEUP I SIOS
+0xBAF9	0xBE59	#HANGUL SYLLABLE PIEUP I IEUNG
+0xBAFA	0xBE5A	#HANGUL SYLLABLE PIEUP I CIEUC
+0xBAFB	0xBE5B	#HANGUL SYLLABLE PIEUP I CHIEUCH
+0xBAFC	0xBE60	#HANGUL SYLLABLE SSANGPIEUP A
+0xBAFD	0xBE61	#HANGUL SYLLABLE SSANGPIEUP A KIYEOK
+0xBAFE	0xBE64	#HANGUL SYLLABLE SSANGPIEUP A NIEUN
+0xBB41	0xD2FB	#HANGUL SYLLABLE THIEUTH I RIEULPIEUP
+0xBB42	0xD2FC	#HANGUL SYLLABLE THIEUTH I RIEULSIOS
+0xBB43	0xD2FD	#HANGUL SYLLABLE THIEUTH I RIEULTHIEUTH
+0xBB44	0xD2FE	#HANGUL SYLLABLE THIEUTH I RIEULPHIEUPH
+0xBB45	0xD2FF	#HANGUL SYLLABLE THIEUTH I RIEULHIEUH
+0xBB46	0xD302	#HANGUL SYLLABLE THIEUTH I PIEUPSIOS
+0xBB47	0xD304	#HANGUL SYLLABLE THIEUTH I SSANGSIOS
+0xBB48	0xD306	#HANGUL SYLLABLE THIEUTH I CIEUC
+0xBB49	0xD307	#HANGUL SYLLABLE THIEUTH I CHIEUCH
+0xBB4A	0xD308	#HANGUL SYLLABLE THIEUTH I KHIEUKH
+0xBB4B	0xD309	#HANGUL SYLLABLE THIEUTH I THIEUTH
+0xBB4C	0xD30A	#HANGUL SYLLABLE THIEUTH I PHIEUPH
+0xBB4D	0xD30B	#HANGUL SYLLABLE THIEUTH I HIEUH
+0xBB4E	0xD30F	#HANGUL SYLLABLE PHIEUPH A KIYEOKSIOS
+0xBB4F	0xD311	#HANGUL SYLLABLE PHIEUPH A NIEUNCIEUC
+0xBB50	0xD312	#HANGUL SYLLABLE PHIEUPH A NIEUNHIEUH
+0xBB51	0xD313	#HANGUL SYLLABLE PHIEUPH A TIKEUT
+0xBB52	0xD315	#HANGUL SYLLABLE PHIEUPH A RIEULKIYEOK
+0xBB53	0xD317	#HANGUL SYLLABLE PHIEUPH A RIEULPIEUP
+0xBB54	0xD318	#HANGUL SYLLABLE PHIEUPH A RIEULSIOS
+0xBB55	0xD319	#HANGUL SYLLABLE PHIEUPH A RIEULTHIEUTH
+0xBB56	0xD31A	#HANGUL SYLLABLE PHIEUPH A RIEULPHIEUPH
+0xBB57	0xD31B	#HANGUL SYLLABLE PHIEUPH A RIEULHIEUH
+0xBB58	0xD31E	#HANGUL SYLLABLE PHIEUPH A PIEUPSIOS
+0xBB59	0xD322	#HANGUL SYLLABLE PHIEUPH A CIEUC
+0xBB5A	0xD323	#HANGUL SYLLABLE PHIEUPH A CHIEUCH
+0xBB61	0xD324	#HANGUL SYLLABLE PHIEUPH A KHIEUKH
+0xBB62	0xD326	#HANGUL SYLLABLE PHIEUPH A PHIEUPH
+0xBB63	0xD327	#HANGUL SYLLABLE PHIEUPH A HIEUH
+0xBB64	0xD32A	#HANGUL SYLLABLE PHIEUPH AE SSANGKIYEOK
+0xBB65	0xD32B	#HANGUL SYLLABLE PHIEUPH AE KIYEOKSIOS
+0xBB66	0xD32D	#HANGUL SYLLABLE PHIEUPH AE NIEUNCIEUC
+0xBB67	0xD32E	#HANGUL SYLLABLE PHIEUPH AE NIEUNHIEUH
+0xBB68	0xD32F	#HANGUL SYLLABLE PHIEUPH AE TIKEUT
+0xBB69	0xD331	#HANGUL SYLLABLE PHIEUPH AE RIEULKIYEOK
+0xBB6A	0xD332	#HANGUL SYLLABLE PHIEUPH AE RIEULMIEUM
+0xBB6B	0xD333	#HANGUL SYLLABLE PHIEUPH AE RIEULPIEUP
+0xBB6C	0xD334	#HANGUL SYLLABLE PHIEUPH AE RIEULSIOS
+0xBB6D	0xD335	#HANGUL SYLLABLE PHIEUPH AE RIEULTHIEUTH
+0xBB6E	0xD336	#HANGUL SYLLABLE PHIEUPH AE RIEULPHIEUPH
+0xBB6F	0xD337	#HANGUL SYLLABLE PHIEUPH AE RIEULHIEUH
+0xBB70	0xD33A	#HANGUL SYLLABLE PHIEUPH AE PIEUPSIOS
+0xBB71	0xD33E	#HANGUL SYLLABLE PHIEUPH AE CIEUC
+0xBB72	0xD33F	#HANGUL SYLLABLE PHIEUPH AE CHIEUCH
+0xBB73	0xD340	#HANGUL SYLLABLE PHIEUPH AE KHIEUKH
+0xBB74	0xD341	#HANGUL SYLLABLE PHIEUPH AE THIEUTH
+0xBB75	0xD342	#HANGUL SYLLABLE PHIEUPH AE PHIEUPH
+0xBB76	0xD343	#HANGUL SYLLABLE PHIEUPH AE HIEUH
+0xBB77	0xD346	#HANGUL SYLLABLE PHIEUPH YA SSANGKIYEOK
+0xBB78	0xD347	#HANGUL SYLLABLE PHIEUPH YA KIYEOKSIOS
+0xBB79	0xD348	#HANGUL SYLLABLE PHIEUPH YA NIEUN
+0xBB7A	0xD349	#HANGUL SYLLABLE PHIEUPH YA NIEUNCIEUC
+0xBB81	0xD34A	#HANGUL SYLLABLE PHIEUPH YA NIEUNHIEUH
+0xBB82	0xD34B	#HANGUL SYLLABLE PHIEUPH YA TIKEUT
+0xBB83	0xD34C	#HANGUL SYLLABLE PHIEUPH YA RIEUL
+0xBB84	0xD34D	#HANGUL SYLLABLE PHIEUPH YA RIEULKIYEOK
+0xBB85	0xD34E	#HANGUL SYLLABLE PHIEUPH YA RIEULMIEUM
+0xBB86	0xD34F	#HANGUL SYLLABLE PHIEUPH YA RIEULPIEUP
+0xBB87	0xD350	#HANGUL SYLLABLE PHIEUPH YA RIEULSIOS
+0xBB88	0xD351	#HANGUL SYLLABLE PHIEUPH YA RIEULTHIEUTH
+0xBB89	0xD352	#HANGUL SYLLABLE PHIEUPH YA RIEULPHIEUPH
+0xBB8A	0xD353	#HANGUL SYLLABLE PHIEUPH YA RIEULHIEUH
+0xBB8B	0xD354	#HANGUL SYLLABLE PHIEUPH YA MIEUM
+0xBB8C	0xD355	#HANGUL SYLLABLE PHIEUPH YA PIEUP
+0xBB8D	0xD356	#HANGUL SYLLABLE PHIEUPH YA PIEUPSIOS
+0xBB8E	0xD357	#HANGUL SYLLABLE PHIEUPH YA SIOS
+0xBB8F	0xD358	#HANGUL SYLLABLE PHIEUPH YA SSANGSIOS
+0xBB90	0xD359	#HANGUL SYLLABLE PHIEUPH YA IEUNG
+0xBB91	0xD35A	#HANGUL SYLLABLE PHIEUPH YA CIEUC
+0xBB92	0xD35B	#HANGUL SYLLABLE PHIEUPH YA CHIEUCH
+0xBB93	0xD35C	#HANGUL SYLLABLE PHIEUPH YA KHIEUKH
+0xBB94	0xD35D	#HANGUL SYLLABLE PHIEUPH YA THIEUTH
+0xBB95	0xD35E	#HANGUL SYLLABLE PHIEUPH YA PHIEUPH
+0xBB96	0xD35F	#HANGUL SYLLABLE PHIEUPH YA HIEUH
+0xBB97	0xD360	#HANGUL SYLLABLE PHIEUPH YAE
+0xBB98	0xD361	#HANGUL SYLLABLE PHIEUPH YAE KIYEOK
+0xBB99	0xD362	#HANGUL SYLLABLE PHIEUPH YAE SSANGKIYEOK
+0xBB9A	0xD363	#HANGUL SYLLABLE PHIEUPH YAE KIYEOKSIOS
+0xBB9B	0xD364	#HANGUL SYLLABLE PHIEUPH YAE NIEUN
+0xBB9C	0xD365	#HANGUL SYLLABLE PHIEUPH YAE NIEUNCIEUC
+0xBB9D	0xD366	#HANGUL SYLLABLE PHIEUPH YAE NIEUNHIEUH
+0xBB9E	0xD367	#HANGUL SYLLABLE PHIEUPH YAE TIKEUT
+0xBB9F	0xD368	#HANGUL SYLLABLE PHIEUPH YAE RIEUL
+0xBBA0	0xD369	#HANGUL SYLLABLE PHIEUPH YAE RIEULKIYEOK
+0xBBA1	0xBE68	#HANGUL SYLLABLE SSANGPIEUP A RIEUL
+0xBBA2	0xBE6A	#HANGUL SYLLABLE SSANGPIEUP A RIEULMIEUM
+0xBBA3	0xBE70	#HANGUL SYLLABLE SSANGPIEUP A MIEUM
+0xBBA4	0xBE71	#HANGUL SYLLABLE SSANGPIEUP A PIEUP
+0xBBA5	0xBE73	#HANGUL SYLLABLE SSANGPIEUP A SIOS
+0xBBA6	0xBE74	#HANGUL SYLLABLE SSANGPIEUP A SSANGSIOS
+0xBBA7	0xBE75	#HANGUL SYLLABLE SSANGPIEUP A IEUNG
+0xBBA8	0xBE7B	#HANGUL SYLLABLE SSANGPIEUP A HIEUH
+0xBBA9	0xBE7C	#HANGUL SYLLABLE SSANGPIEUP AE
+0xBBAA	0xBE7D	#HANGUL SYLLABLE SSANGPIEUP AE KIYEOK
+0xBBAB	0xBE80	#HANGUL SYLLABLE SSANGPIEUP AE NIEUN
+0xBBAC	0xBE84	#HANGUL SYLLABLE SSANGPIEUP AE RIEUL
+0xBBAD	0xBE8C	#HANGUL SYLLABLE SSANGPIEUP AE MIEUM
+0xBBAE	0xBE8D	#HANGUL SYLLABLE SSANGPIEUP AE PIEUP
+0xBBAF	0xBE8F	#HANGUL SYLLABLE SSANGPIEUP AE SIOS
+0xBBB0	0xBE90	#HANGUL SYLLABLE SSANGPIEUP AE SSANGSIOS
+0xBBB1	0xBE91	#HANGUL SYLLABLE SSANGPIEUP AE IEUNG
+0xBBB2	0xBE98	#HANGUL SYLLABLE SSANGPIEUP YA
+0xBBB3	0xBE99	#HANGUL SYLLABLE SSANGPIEUP YA KIYEOK
+0xBBB4	0xBEA8	#HANGUL SYLLABLE SSANGPIEUP YA MIEUM
+0xBBB5	0xBED0	#HANGUL SYLLABLE SSANGPIEUP EO
+0xBBB6	0xBED1	#HANGUL SYLLABLE SSANGPIEUP EO KIYEOK
+0xBBB7	0xBED4	#HANGUL SYLLABLE SSANGPIEUP EO NIEUN
+0xBBB8	0xBED7	#HANGUL SYLLABLE SSANGPIEUP EO TIKEUT
+0xBBB9	0xBED8	#HANGUL SYLLABLE SSANGPIEUP EO RIEUL
+0xBBBA	0xBEE0	#HANGUL SYLLABLE SSANGPIEUP EO MIEUM
+0xBBBB	0xBEE3	#HANGUL SYLLABLE SSANGPIEUP EO SIOS
+0xBBBC	0xBEE4	#HANGUL SYLLABLE SSANGPIEUP EO SSANGSIOS
+0xBBBD	0xBEE5	#HANGUL SYLLABLE SSANGPIEUP EO IEUNG
+0xBBBE	0xBEEC	#HANGUL SYLLABLE SSANGPIEUP E
+0xBBBF	0xBF01	#HANGUL SYLLABLE SSANGPIEUP E IEUNG
+0xBBC0	0xBF08	#HANGUL SYLLABLE SSANGPIEUP YEO
+0xBBC1	0xBF09	#HANGUL SYLLABLE SSANGPIEUP YEO KIYEOK
+0xBBC2	0xBF18	#HANGUL SYLLABLE SSANGPIEUP YEO MIEUM
+0xBBC3	0xBF19	#HANGUL SYLLABLE SSANGPIEUP YEO PIEUP
+0xBBC4	0xBF1B	#HANGUL SYLLABLE SSANGPIEUP YEO SIOS
+0xBBC5	0xBF1C	#HANGUL SYLLABLE SSANGPIEUP YEO SSANGSIOS
+0xBBC6	0xBF1D	#HANGUL SYLLABLE SSANGPIEUP YEO IEUNG
+0xBBC7	0xBF40	#HANGUL SYLLABLE SSANGPIEUP O
+0xBBC8	0xBF41	#HANGUL SYLLABLE SSANGPIEUP O KIYEOK
+0xBBC9	0xBF44	#HANGUL SYLLABLE SSANGPIEUP O NIEUN
+0xBBCA	0xBF48	#HANGUL SYLLABLE SSANGPIEUP O RIEUL
+0xBBCB	0xBF50	#HANGUL SYLLABLE SSANGPIEUP O MIEUM
+0xBBCC	0xBF51	#HANGUL SYLLABLE SSANGPIEUP O PIEUP
+0xBBCD	0xBF55	#HANGUL SYLLABLE SSANGPIEUP O IEUNG
+0xBBCE	0xBF94	#HANGUL SYLLABLE SSANGPIEUP OE
+0xBBCF	0xBFB0	#HANGUL SYLLABLE SSANGPIEUP YO
+0xBBD0	0xBFC5	#HANGUL SYLLABLE SSANGPIEUP YO IEUNG
+0xBBD1	0xBFCC	#HANGUL SYLLABLE SSANGPIEUP U
+0xBBD2	0xBFCD	#HANGUL SYLLABLE SSANGPIEUP U KIYEOK
+0xBBD3	0xBFD0	#HANGUL SYLLABLE SSANGPIEUP U NIEUN
+0xBBD4	0xBFD4	#HANGUL SYLLABLE SSANGPIEUP U RIEUL
+0xBBD5	0xBFDC	#HANGUL SYLLABLE SSANGPIEUP U MIEUM
+0xBBD6	0xBFDF	#HANGUL SYLLABLE SSANGPIEUP U SIOS
+0xBBD7	0xBFE1	#HANGUL SYLLABLE SSANGPIEUP U IEUNG
+0xBBD8	0xC03C	#HANGUL SYLLABLE SSANGPIEUP YU
+0xBBD9	0xC051	#HANGUL SYLLABLE SSANGPIEUP YU IEUNG
+0xBBDA	0xC058	#HANGUL SYLLABLE SSANGPIEUP EU
+0xBBDB	0xC05C	#HANGUL SYLLABLE SSANGPIEUP EU NIEUN
+0xBBDC	0xC060	#HANGUL SYLLABLE SSANGPIEUP EU RIEUL
+0xBBDD	0xC068	#HANGUL SYLLABLE SSANGPIEUP EU MIEUM
+0xBBDE	0xC069	#HANGUL SYLLABLE SSANGPIEUP EU PIEUP
+0xBBDF	0xC090	#HANGUL SYLLABLE SSANGPIEUP I
+0xBBE0	0xC091	#HANGUL SYLLABLE SSANGPIEUP I KIYEOK
+0xBBE1	0xC094	#HANGUL SYLLABLE SSANGPIEUP I NIEUN
+0xBBE2	0xC098	#HANGUL SYLLABLE SSANGPIEUP I RIEUL
+0xBBE3	0xC0A0	#HANGUL SYLLABLE SSANGPIEUP I MIEUM
+0xBBE4	0xC0A1	#HANGUL SYLLABLE SSANGPIEUP I PIEUP
+0xBBE5	0xC0A3	#HANGUL SYLLABLE SSANGPIEUP I SIOS
+0xBBE6	0xC0A5	#HANGUL SYLLABLE SSANGPIEUP I IEUNG
+0xBBE7	0xC0AC	#HANGUL SYLLABLE SIOS A
+0xBBE8	0xC0AD	#HANGUL SYLLABLE SIOS A KIYEOK
+0xBBE9	0xC0AF	#HANGUL SYLLABLE SIOS A KIYEOKSIOS
+0xBBEA	0xC0B0	#HANGUL SYLLABLE SIOS A NIEUN
+0xBBEB	0xC0B3	#HANGUL SYLLABLE SIOS A TIKEUT
+0xBBEC	0xC0B4	#HANGUL SYLLABLE SIOS A RIEUL
+0xBBED	0xC0B5	#HANGUL SYLLABLE SIOS A RIEULKIYEOK
+0xBBEE	0xC0B6	#HANGUL SYLLABLE SIOS A RIEULMIEUM
+0xBBEF	0xC0BC	#HANGUL SYLLABLE SIOS A MIEUM
+0xBBF0	0xC0BD	#HANGUL SYLLABLE SIOS A PIEUP
+0xBBF1	0xC0BF	#HANGUL SYLLABLE SIOS A SIOS
+0xBBF2	0xC0C0	#HANGUL SYLLABLE SIOS A SSANGSIOS
+0xBBF3	0xC0C1	#HANGUL SYLLABLE SIOS A IEUNG
+0xBBF4	0xC0C5	#HANGUL SYLLABLE SIOS A THIEUTH
+0xBBF5	0xC0C8	#HANGUL SYLLABLE SIOS AE
+0xBBF6	0xC0C9	#HANGUL SYLLABLE SIOS AE KIYEOK
+0xBBF7	0xC0CC	#HANGUL SYLLABLE SIOS AE NIEUN
+0xBBF8	0xC0D0	#HANGUL SYLLABLE SIOS AE RIEUL
+0xBBF9	0xC0D8	#HANGUL SYLLABLE SIOS AE MIEUM
+0xBBFA	0xC0D9	#HANGUL SYLLABLE SIOS AE PIEUP
+0xBBFB	0xC0DB	#HANGUL SYLLABLE SIOS AE SIOS
+0xBBFC	0xC0DC	#HANGUL SYLLABLE SIOS AE SSANGSIOS
+0xBBFD	0xC0DD	#HANGUL SYLLABLE SIOS AE IEUNG
+0xBBFE	0xC0E4	#HANGUL SYLLABLE SIOS YA
+0xBC41	0xD36A	#HANGUL SYLLABLE PHIEUPH YAE RIEULMIEUM
+0xBC42	0xD36B	#HANGUL SYLLABLE PHIEUPH YAE RIEULPIEUP
+0xBC43	0xD36C	#HANGUL SYLLABLE PHIEUPH YAE RIEULSIOS
+0xBC44	0xD36D	#HANGUL SYLLABLE PHIEUPH YAE RIEULTHIEUTH
+0xBC45	0xD36E	#HANGUL SYLLABLE PHIEUPH YAE RIEULPHIEUPH
+0xBC46	0xD36F	#HANGUL SYLLABLE PHIEUPH YAE RIEULHIEUH
+0xBC47	0xD370	#HANGUL SYLLABLE PHIEUPH YAE MIEUM
+0xBC48	0xD371	#HANGUL SYLLABLE PHIEUPH YAE PIEUP
+0xBC49	0xD372	#HANGUL SYLLABLE PHIEUPH YAE PIEUPSIOS
+0xBC4A	0xD373	#HANGUL SYLLABLE PHIEUPH YAE SIOS
+0xBC4B	0xD374	#HANGUL SYLLABLE PHIEUPH YAE SSANGSIOS
+0xBC4C	0xD375	#HANGUL SYLLABLE PHIEUPH YAE IEUNG
+0xBC4D	0xD376	#HANGUL SYLLABLE PHIEUPH YAE CIEUC
+0xBC4E	0xD377	#HANGUL SYLLABLE PHIEUPH YAE CHIEUCH
+0xBC4F	0xD378	#HANGUL SYLLABLE PHIEUPH YAE KHIEUKH
+0xBC50	0xD379	#HANGUL SYLLABLE PHIEUPH YAE THIEUTH
+0xBC51	0xD37A	#HANGUL SYLLABLE PHIEUPH YAE PHIEUPH
+0xBC52	0xD37B	#HANGUL SYLLABLE PHIEUPH YAE HIEUH
+0xBC53	0xD37E	#HANGUL SYLLABLE PHIEUPH EO SSANGKIYEOK
+0xBC54	0xD37F	#HANGUL SYLLABLE PHIEUPH EO KIYEOKSIOS
+0xBC55	0xD381	#HANGUL SYLLABLE PHIEUPH EO NIEUNCIEUC
+0xBC56	0xD382	#HANGUL SYLLABLE PHIEUPH EO NIEUNHIEUH
+0xBC57	0xD383	#HANGUL SYLLABLE PHIEUPH EO TIKEUT
+0xBC58	0xD385	#HANGUL SYLLABLE PHIEUPH EO RIEULKIYEOK
+0xBC59	0xD386	#HANGUL SYLLABLE PHIEUPH EO RIEULMIEUM
+0xBC5A	0xD387	#HANGUL SYLLABLE PHIEUPH EO RIEULPIEUP
+0xBC61	0xD388	#HANGUL SYLLABLE PHIEUPH EO RIEULSIOS
+0xBC62	0xD389	#HANGUL SYLLABLE PHIEUPH EO RIEULTHIEUTH
+0xBC63	0xD38A	#HANGUL SYLLABLE PHIEUPH EO RIEULPHIEUPH
+0xBC64	0xD38B	#HANGUL SYLLABLE PHIEUPH EO RIEULHIEUH
+0xBC65	0xD38E	#HANGUL SYLLABLE PHIEUPH EO PIEUPSIOS
+0xBC66	0xD392	#HANGUL SYLLABLE PHIEUPH EO CIEUC
+0xBC67	0xD393	#HANGUL SYLLABLE PHIEUPH EO CHIEUCH
+0xBC68	0xD394	#HANGUL SYLLABLE PHIEUPH EO KHIEUKH
+0xBC69	0xD395	#HANGUL SYLLABLE PHIEUPH EO THIEUTH
+0xBC6A	0xD396	#HANGUL SYLLABLE PHIEUPH EO PHIEUPH
+0xBC6B	0xD397	#HANGUL SYLLABLE PHIEUPH EO HIEUH
+0xBC6C	0xD39A	#HANGUL SYLLABLE PHIEUPH E SSANGKIYEOK
+0xBC6D	0xD39B	#HANGUL SYLLABLE PHIEUPH E KIYEOKSIOS
+0xBC6E	0xD39D	#HANGUL SYLLABLE PHIEUPH E NIEUNCIEUC
+0xBC6F	0xD39E	#HANGUL SYLLABLE PHIEUPH E NIEUNHIEUH
+0xBC70	0xD39F	#HANGUL SYLLABLE PHIEUPH E TIKEUT
+0xBC71	0xD3A1	#HANGUL SYLLABLE PHIEUPH E RIEULKIYEOK
+0xBC72	0xD3A2	#HANGUL SYLLABLE PHIEUPH E RIEULMIEUM
+0xBC73	0xD3A3	#HANGUL SYLLABLE PHIEUPH E RIEULPIEUP
+0xBC74	0xD3A4	#HANGUL SYLLABLE PHIEUPH E RIEULSIOS
+0xBC75	0xD3A5	#HANGUL SYLLABLE PHIEUPH E RIEULTHIEUTH
+0xBC76	0xD3A6	#HANGUL SYLLABLE PHIEUPH E RIEULPHIEUPH
+0xBC77	0xD3A7	#HANGUL SYLLABLE PHIEUPH E RIEULHIEUH
+0xBC78	0xD3AA	#HANGUL SYLLABLE PHIEUPH E PIEUPSIOS
+0xBC79	0xD3AC	#HANGUL SYLLABLE PHIEUPH E SSANGSIOS
+0xBC7A	0xD3AE	#HANGUL SYLLABLE PHIEUPH E CIEUC
+0xBC81	0xD3AF	#HANGUL SYLLABLE PHIEUPH E CHIEUCH
+0xBC82	0xD3B0	#HANGUL SYLLABLE PHIEUPH E KHIEUKH
+0xBC83	0xD3B1	#HANGUL SYLLABLE PHIEUPH E THIEUTH
+0xBC84	0xD3B2	#HANGUL SYLLABLE PHIEUPH E PHIEUPH
+0xBC85	0xD3B3	#HANGUL SYLLABLE PHIEUPH E HIEUH
+0xBC86	0xD3B5	#HANGUL SYLLABLE PHIEUPH YEO KIYEOK
+0xBC87	0xD3B6	#HANGUL SYLLABLE PHIEUPH YEO SSANGKIYEOK
+0xBC88	0xD3B7	#HANGUL SYLLABLE PHIEUPH YEO KIYEOKSIOS
+0xBC89	0xD3B9	#HANGUL SYLLABLE PHIEUPH YEO NIEUNCIEUC
+0xBC8A	0xD3BA	#HANGUL SYLLABLE PHIEUPH YEO NIEUNHIEUH
+0xBC8B	0xD3BB	#HANGUL SYLLABLE PHIEUPH YEO TIKEUT
+0xBC8C	0xD3BD	#HANGUL SYLLABLE PHIEUPH YEO RIEULKIYEOK
+0xBC8D	0xD3BE	#HANGUL SYLLABLE PHIEUPH YEO RIEULMIEUM
+0xBC8E	0xD3BF	#HANGUL SYLLABLE PHIEUPH YEO RIEULPIEUP
+0xBC8F	0xD3C0	#HANGUL SYLLABLE PHIEUPH YEO RIEULSIOS
+0xBC90	0xD3C1	#HANGUL SYLLABLE PHIEUPH YEO RIEULTHIEUTH
+0xBC91	0xD3C2	#HANGUL SYLLABLE PHIEUPH YEO RIEULPHIEUPH
+0xBC92	0xD3C3	#HANGUL SYLLABLE PHIEUPH YEO RIEULHIEUH
+0xBC93	0xD3C6	#HANGUL SYLLABLE PHIEUPH YEO PIEUPSIOS
+0xBC94	0xD3C7	#HANGUL SYLLABLE PHIEUPH YEO SIOS
+0xBC95	0xD3CA	#HANGUL SYLLABLE PHIEUPH YEO CIEUC
+0xBC96	0xD3CB	#HANGUL SYLLABLE PHIEUPH YEO CHIEUCH
+0xBC97	0xD3CC	#HANGUL SYLLABLE PHIEUPH YEO KHIEUKH
+0xBC98	0xD3CD	#HANGUL SYLLABLE PHIEUPH YEO THIEUTH
+0xBC99	0xD3CE	#HANGUL SYLLABLE PHIEUPH YEO PHIEUPH
+0xBC9A	0xD3CF	#HANGUL SYLLABLE PHIEUPH YEO HIEUH
+0xBC9B	0xD3D1	#HANGUL SYLLABLE PHIEUPH YE KIYEOK
+0xBC9C	0xD3D2	#HANGUL SYLLABLE PHIEUPH YE SSANGKIYEOK
+0xBC9D	0xD3D3	#HANGUL SYLLABLE PHIEUPH YE KIYEOKSIOS
+0xBC9E	0xD3D4	#HANGUL SYLLABLE PHIEUPH YE NIEUN
+0xBC9F	0xD3D5	#HANGUL SYLLABLE PHIEUPH YE NIEUNCIEUC
+0xBCA0	0xD3D6	#HANGUL SYLLABLE PHIEUPH YE NIEUNHIEUH
+0xBCA1	0xC0E5	#HANGUL SYLLABLE SIOS YA KIYEOK
+0xBCA2	0xC0E8	#HANGUL SYLLABLE SIOS YA NIEUN
+0xBCA3	0xC0EC	#HANGUL SYLLABLE SIOS YA RIEUL
+0xBCA4	0xC0F4	#HANGUL SYLLABLE SIOS YA MIEUM
+0xBCA5	0xC0F5	#HANGUL SYLLABLE SIOS YA PIEUP
+0xBCA6	0xC0F7	#HANGUL SYLLABLE SIOS YA SIOS
+0xBCA7	0xC0F9	#HANGUL SYLLABLE SIOS YA IEUNG
+0xBCA8	0xC100	#HANGUL SYLLABLE SIOS YAE
+0xBCA9	0xC104	#HANGUL SYLLABLE SIOS YAE NIEUN
+0xBCAA	0xC108	#HANGUL SYLLABLE SIOS YAE RIEUL
+0xBCAB	0xC110	#HANGUL SYLLABLE SIOS YAE MIEUM
+0xBCAC	0xC115	#HANGUL SYLLABLE SIOS YAE IEUNG
+0xBCAD	0xC11C	#HANGUL SYLLABLE SIOS EO
+0xBCAE	0xC11D	#HANGUL SYLLABLE SIOS EO KIYEOK
+0xBCAF	0xC11E	#HANGUL SYLLABLE SIOS EO SSANGKIYEOK
+0xBCB0	0xC11F	#HANGUL SYLLABLE SIOS EO KIYEOKSIOS
+0xBCB1	0xC120	#HANGUL SYLLABLE SIOS EO NIEUN
+0xBCB2	0xC123	#HANGUL SYLLABLE SIOS EO TIKEUT
+0xBCB3	0xC124	#HANGUL SYLLABLE SIOS EO RIEUL
+0xBCB4	0xC126	#HANGUL SYLLABLE SIOS EO RIEULMIEUM
+0xBCB5	0xC127	#HANGUL SYLLABLE SIOS EO RIEULPIEUP
+0xBCB6	0xC12C	#HANGUL SYLLABLE SIOS EO MIEUM
+0xBCB7	0xC12D	#HANGUL SYLLABLE SIOS EO PIEUP
+0xBCB8	0xC12F	#HANGUL SYLLABLE SIOS EO SIOS
+0xBCB9	0xC130	#HANGUL SYLLABLE SIOS EO SSANGSIOS
+0xBCBA	0xC131	#HANGUL SYLLABLE SIOS EO IEUNG
+0xBCBB	0xC136	#HANGUL SYLLABLE SIOS EO PHIEUPH
+0xBCBC	0xC138	#HANGUL SYLLABLE SIOS E
+0xBCBD	0xC139	#HANGUL SYLLABLE SIOS E KIYEOK
+0xBCBE	0xC13C	#HANGUL SYLLABLE SIOS E NIEUN
+0xBCBF	0xC140	#HANGUL SYLLABLE SIOS E RIEUL
+0xBCC0	0xC148	#HANGUL SYLLABLE SIOS E MIEUM
+0xBCC1	0xC149	#HANGUL SYLLABLE SIOS E PIEUP
+0xBCC2	0xC14B	#HANGUL SYLLABLE SIOS E SIOS
+0xBCC3	0xC14C	#HANGUL SYLLABLE SIOS E SSANGSIOS
+0xBCC4	0xC14D	#HANGUL SYLLABLE SIOS E IEUNG
+0xBCC5	0xC154	#HANGUL SYLLABLE SIOS YEO
+0xBCC6	0xC155	#HANGUL SYLLABLE SIOS YEO KIYEOK
+0xBCC7	0xC158	#HANGUL SYLLABLE SIOS YEO NIEUN
+0xBCC8	0xC15C	#HANGUL SYLLABLE SIOS YEO RIEUL
+0xBCC9	0xC164	#HANGUL SYLLABLE SIOS YEO MIEUM
+0xBCCA	0xC165	#HANGUL SYLLABLE SIOS YEO PIEUP
+0xBCCB	0xC167	#HANGUL SYLLABLE SIOS YEO SIOS
+0xBCCC	0xC168	#HANGUL SYLLABLE SIOS YEO SSANGSIOS
+0xBCCD	0xC169	#HANGUL SYLLABLE SIOS YEO IEUNG
+0xBCCE	0xC170	#HANGUL SYLLABLE SIOS YE
+0xBCCF	0xC174	#HANGUL SYLLABLE SIOS YE NIEUN
+0xBCD0	0xC178	#HANGUL SYLLABLE SIOS YE RIEUL
+0xBCD1	0xC185	#HANGUL SYLLABLE SIOS YE IEUNG
+0xBCD2	0xC18C	#HANGUL SYLLABLE SIOS O
+0xBCD3	0xC18D	#HANGUL SYLLABLE SIOS O KIYEOK
+0xBCD4	0xC18E	#HANGUL SYLLABLE SIOS O SSANGKIYEOK
+0xBCD5	0xC190	#HANGUL SYLLABLE SIOS O NIEUN
+0xBCD6	0xC194	#HANGUL SYLLABLE SIOS O RIEUL
+0xBCD7	0xC196	#HANGUL SYLLABLE SIOS O RIEULMIEUM
+0xBCD8	0xC19C	#HANGUL SYLLABLE SIOS O MIEUM
+0xBCD9	0xC19D	#HANGUL SYLLABLE SIOS O PIEUP
+0xBCDA	0xC19F	#HANGUL SYLLABLE SIOS O SIOS
+0xBCDB	0xC1A1	#HANGUL SYLLABLE SIOS O IEUNG
+0xBCDC	0xC1A5	#HANGUL SYLLABLE SIOS O THIEUTH
+0xBCDD	0xC1A8	#HANGUL SYLLABLE SIOS WA
+0xBCDE	0xC1A9	#HANGUL SYLLABLE SIOS WA KIYEOK
+0xBCDF	0xC1AC	#HANGUL SYLLABLE SIOS WA NIEUN
+0xBCE0	0xC1B0	#HANGUL SYLLABLE SIOS WA RIEUL
+0xBCE1	0xC1BD	#HANGUL SYLLABLE SIOS WA IEUNG
+0xBCE2	0xC1C4	#HANGUL SYLLABLE SIOS WAE
+0xBCE3	0xC1C8	#HANGUL SYLLABLE SIOS WAE NIEUN
+0xBCE4	0xC1CC	#HANGUL SYLLABLE SIOS WAE RIEUL
+0xBCE5	0xC1D4	#HANGUL SYLLABLE SIOS WAE MIEUM
+0xBCE6	0xC1D7	#HANGUL SYLLABLE SIOS WAE SIOS
+0xBCE7	0xC1D8	#HANGUL SYLLABLE SIOS WAE SSANGSIOS
+0xBCE8	0xC1E0	#HANGUL SYLLABLE SIOS OE
+0xBCE9	0xC1E4	#HANGUL SYLLABLE SIOS OE NIEUN
+0xBCEA	0xC1E8	#HANGUL SYLLABLE SIOS OE RIEUL
+0xBCEB	0xC1F0	#HANGUL SYLLABLE SIOS OE MIEUM
+0xBCEC	0xC1F1	#HANGUL SYLLABLE SIOS OE PIEUP
+0xBCED	0xC1F3	#HANGUL SYLLABLE SIOS OE SIOS
+0xBCEE	0xC1FC	#HANGUL SYLLABLE SIOS YO
+0xBCEF	0xC1FD	#HANGUL SYLLABLE SIOS YO KIYEOK
+0xBCF0	0xC200	#HANGUL SYLLABLE SIOS YO NIEUN
+0xBCF1	0xC204	#HANGUL SYLLABLE SIOS YO RIEUL
+0xBCF2	0xC20C	#HANGUL SYLLABLE SIOS YO MIEUM
+0xBCF3	0xC20D	#HANGUL SYLLABLE SIOS YO PIEUP
+0xBCF4	0xC20F	#HANGUL SYLLABLE SIOS YO SIOS
+0xBCF5	0xC211	#HANGUL SYLLABLE SIOS YO IEUNG
+0xBCF6	0xC218	#HANGUL SYLLABLE SIOS U
+0xBCF7	0xC219	#HANGUL SYLLABLE SIOS U KIYEOK
+0xBCF8	0xC21C	#HANGUL SYLLABLE SIOS U NIEUN
+0xBCF9	0xC21F	#HANGUL SYLLABLE SIOS U TIKEUT
+0xBCFA	0xC220	#HANGUL SYLLABLE SIOS U RIEUL
+0xBCFB	0xC228	#HANGUL SYLLABLE SIOS U MIEUM
+0xBCFC	0xC229	#HANGUL SYLLABLE SIOS U PIEUP
+0xBCFD	0xC22B	#HANGUL SYLLABLE SIOS U SIOS
+0xBCFE	0xC22D	#HANGUL SYLLABLE SIOS U IEUNG
+0xBD41	0xD3D7	#HANGUL SYLLABLE PHIEUPH YE TIKEUT
+0xBD42	0xD3D9	#HANGUL SYLLABLE PHIEUPH YE RIEULKIYEOK
+0xBD43	0xD3DA	#HANGUL SYLLABLE PHIEUPH YE RIEULMIEUM
+0xBD44	0xD3DB	#HANGUL SYLLABLE PHIEUPH YE RIEULPIEUP
+0xBD45	0xD3DC	#HANGUL SYLLABLE PHIEUPH YE RIEULSIOS
+0xBD46	0xD3DD	#HANGUL SYLLABLE PHIEUPH YE RIEULTHIEUTH
+0xBD47	0xD3DE	#HANGUL SYLLABLE PHIEUPH YE RIEULPHIEUPH
+0xBD48	0xD3DF	#HANGUL SYLLABLE PHIEUPH YE RIEULHIEUH
+0xBD49	0xD3E0	#HANGUL SYLLABLE PHIEUPH YE MIEUM
+0xBD4A	0xD3E2	#HANGUL SYLLABLE PHIEUPH YE PIEUPSIOS
+0xBD4B	0xD3E4	#HANGUL SYLLABLE PHIEUPH YE SSANGSIOS
+0xBD4C	0xD3E5	#HANGUL SYLLABLE PHIEUPH YE IEUNG
+0xBD4D	0xD3E6	#HANGUL SYLLABLE PHIEUPH YE CIEUC
+0xBD4E	0xD3E7	#HANGUL SYLLABLE PHIEUPH YE CHIEUCH
+0xBD4F	0xD3E8	#HANGUL SYLLABLE PHIEUPH YE KHIEUKH
+0xBD50	0xD3E9	#HANGUL SYLLABLE PHIEUPH YE THIEUTH
+0xBD51	0xD3EA	#HANGUL SYLLABLE PHIEUPH YE PHIEUPH
+0xBD52	0xD3EB	#HANGUL SYLLABLE PHIEUPH YE HIEUH
+0xBD53	0xD3EE	#HANGUL SYLLABLE PHIEUPH O SSANGKIYEOK
+0xBD54	0xD3EF	#HANGUL SYLLABLE PHIEUPH O KIYEOKSIOS
+0xBD55	0xD3F1	#HANGUL SYLLABLE PHIEUPH O NIEUNCIEUC
+0xBD56	0xD3F2	#HANGUL SYLLABLE PHIEUPH O NIEUNHIEUH
+0xBD57	0xD3F3	#HANGUL SYLLABLE PHIEUPH O TIKEUT
+0xBD58	0xD3F5	#HANGUL SYLLABLE PHIEUPH O RIEULKIYEOK
+0xBD59	0xD3F6	#HANGUL SYLLABLE PHIEUPH O RIEULMIEUM
+0xBD5A	0xD3F7	#HANGUL SYLLABLE PHIEUPH O RIEULPIEUP
+0xBD61	0xD3F8	#HANGUL SYLLABLE PHIEUPH O RIEULSIOS
+0xBD62	0xD3F9	#HANGUL SYLLABLE PHIEUPH O RIEULTHIEUTH
+0xBD63	0xD3FA	#HANGUL SYLLABLE PHIEUPH O RIEULPHIEUPH
+0xBD64	0xD3FB	#HANGUL SYLLABLE PHIEUPH O RIEULHIEUH
+0xBD65	0xD3FE	#HANGUL SYLLABLE PHIEUPH O PIEUPSIOS
+0xBD66	0xD400	#HANGUL SYLLABLE PHIEUPH O SSANGSIOS
+0xBD67	0xD402	#HANGUL SYLLABLE PHIEUPH O CIEUC
+0xBD68	0xD403	#HANGUL SYLLABLE PHIEUPH O CHIEUCH
+0xBD69	0xD404	#HANGUL SYLLABLE PHIEUPH O KHIEUKH
+0xBD6A	0xD405	#HANGUL SYLLABLE PHIEUPH O THIEUTH
+0xBD6B	0xD406	#HANGUL SYLLABLE PHIEUPH O PHIEUPH
+0xBD6C	0xD407	#HANGUL SYLLABLE PHIEUPH O HIEUH
+0xBD6D	0xD409	#HANGUL SYLLABLE PHIEUPH WA KIYEOK
+0xBD6E	0xD40A	#HANGUL SYLLABLE PHIEUPH WA SSANGKIYEOK
+0xBD6F	0xD40B	#HANGUL SYLLABLE PHIEUPH WA KIYEOKSIOS
+0xBD70	0xD40C	#HANGUL SYLLABLE PHIEUPH WA NIEUN
+0xBD71	0xD40D	#HANGUL SYLLABLE PHIEUPH WA NIEUNCIEUC
+0xBD72	0xD40E	#HANGUL SYLLABLE PHIEUPH WA NIEUNHIEUH
+0xBD73	0xD40F	#HANGUL SYLLABLE PHIEUPH WA TIKEUT
+0xBD74	0xD410	#HANGUL SYLLABLE PHIEUPH WA RIEUL
+0xBD75	0xD411	#HANGUL SYLLABLE PHIEUPH WA RIEULKIYEOK
+0xBD76	0xD412	#HANGUL SYLLABLE PHIEUPH WA RIEULMIEUM
+0xBD77	0xD413	#HANGUL SYLLABLE PHIEUPH WA RIEULPIEUP
+0xBD78	0xD414	#HANGUL SYLLABLE PHIEUPH WA RIEULSIOS
+0xBD79	0xD415	#HANGUL SYLLABLE PHIEUPH WA RIEULTHIEUTH
+0xBD7A	0xD416	#HANGUL SYLLABLE PHIEUPH WA RIEULPHIEUPH
+0xBD81	0xD417	#HANGUL SYLLABLE PHIEUPH WA RIEULHIEUH
+0xBD82	0xD418	#HANGUL SYLLABLE PHIEUPH WA MIEUM
+0xBD83	0xD419	#HANGUL SYLLABLE PHIEUPH WA PIEUP
+0xBD84	0xD41A	#HANGUL SYLLABLE PHIEUPH WA PIEUPSIOS
+0xBD85	0xD41B	#HANGUL SYLLABLE PHIEUPH WA SIOS
+0xBD86	0xD41C	#HANGUL SYLLABLE PHIEUPH WA SSANGSIOS
+0xBD87	0xD41E	#HANGUL SYLLABLE PHIEUPH WA CIEUC
+0xBD88	0xD41F	#HANGUL SYLLABLE PHIEUPH WA CHIEUCH
+0xBD89	0xD420	#HANGUL SYLLABLE PHIEUPH WA KHIEUKH
+0xBD8A	0xD421	#HANGUL SYLLABLE PHIEUPH WA THIEUTH
+0xBD8B	0xD422	#HANGUL SYLLABLE PHIEUPH WA PHIEUPH
+0xBD8C	0xD423	#HANGUL SYLLABLE PHIEUPH WA HIEUH
+0xBD8D	0xD424	#HANGUL SYLLABLE PHIEUPH WAE
+0xBD8E	0xD425	#HANGUL SYLLABLE PHIEUPH WAE KIYEOK
+0xBD8F	0xD426	#HANGUL SYLLABLE PHIEUPH WAE SSANGKIYEOK
+0xBD90	0xD427	#HANGUL SYLLABLE PHIEUPH WAE KIYEOKSIOS
+0xBD91	0xD428	#HANGUL SYLLABLE PHIEUPH WAE NIEUN
+0xBD92	0xD429	#HANGUL SYLLABLE PHIEUPH WAE NIEUNCIEUC
+0xBD93	0xD42A	#HANGUL SYLLABLE PHIEUPH WAE NIEUNHIEUH
+0xBD94	0xD42B	#HANGUL SYLLABLE PHIEUPH WAE TIKEUT
+0xBD95	0xD42C	#HANGUL SYLLABLE PHIEUPH WAE RIEUL
+0xBD96	0xD42D	#HANGUL SYLLABLE PHIEUPH WAE RIEULKIYEOK
+0xBD97	0xD42E	#HANGUL SYLLABLE PHIEUPH WAE RIEULMIEUM
+0xBD98	0xD42F	#HANGUL SYLLABLE PHIEUPH WAE RIEULPIEUP
+0xBD99	0xD430	#HANGUL SYLLABLE PHIEUPH WAE RIEULSIOS
+0xBD9A	0xD431	#HANGUL SYLLABLE PHIEUPH WAE RIEULTHIEUTH
+0xBD9B	0xD432	#HANGUL SYLLABLE PHIEUPH WAE RIEULPHIEUPH
+0xBD9C	0xD433	#HANGUL SYLLABLE PHIEUPH WAE RIEULHIEUH
+0xBD9D	0xD434	#HANGUL SYLLABLE PHIEUPH WAE MIEUM
+0xBD9E	0xD435	#HANGUL SYLLABLE PHIEUPH WAE PIEUP
+0xBD9F	0xD436	#HANGUL SYLLABLE PHIEUPH WAE PIEUPSIOS
+0xBDA0	0xD437	#HANGUL SYLLABLE PHIEUPH WAE SIOS
+0xBDA1	0xC22F	#HANGUL SYLLABLE SIOS U CHIEUCH
+0xBDA2	0xC231	#HANGUL SYLLABLE SIOS U THIEUTH
+0xBDA3	0xC232	#HANGUL SYLLABLE SIOS U PHIEUPH
+0xBDA4	0xC234	#HANGUL SYLLABLE SIOS WEO
+0xBDA5	0xC248	#HANGUL SYLLABLE SIOS WEO SSANGSIOS
+0xBDA6	0xC250	#HANGUL SYLLABLE SIOS WE
+0xBDA7	0xC251	#HANGUL SYLLABLE SIOS WE KIYEOK
+0xBDA8	0xC254	#HANGUL SYLLABLE SIOS WE NIEUN
+0xBDA9	0xC258	#HANGUL SYLLABLE SIOS WE RIEUL
+0xBDAA	0xC260	#HANGUL SYLLABLE SIOS WE MIEUM
+0xBDAB	0xC265	#HANGUL SYLLABLE SIOS WE IEUNG
+0xBDAC	0xC26C	#HANGUL SYLLABLE SIOS WI
+0xBDAD	0xC26D	#HANGUL SYLLABLE SIOS WI KIYEOK
+0xBDAE	0xC270	#HANGUL SYLLABLE SIOS WI NIEUN
+0xBDAF	0xC274	#HANGUL SYLLABLE SIOS WI RIEUL
+0xBDB0	0xC27C	#HANGUL SYLLABLE SIOS WI MIEUM
+0xBDB1	0xC27D	#HANGUL SYLLABLE SIOS WI PIEUP
+0xBDB2	0xC27F	#HANGUL SYLLABLE SIOS WI SIOS
+0xBDB3	0xC281	#HANGUL SYLLABLE SIOS WI IEUNG
+0xBDB4	0xC288	#HANGUL SYLLABLE SIOS YU
+0xBDB5	0xC289	#HANGUL SYLLABLE SIOS YU KIYEOK
+0xBDB6	0xC290	#HANGUL SYLLABLE SIOS YU RIEUL
+0xBDB7	0xC298	#HANGUL SYLLABLE SIOS YU MIEUM
+0xBDB8	0xC29B	#HANGUL SYLLABLE SIOS YU SIOS
+0xBDB9	0xC29D	#HANGUL SYLLABLE SIOS YU IEUNG
+0xBDBA	0xC2A4	#HANGUL SYLLABLE SIOS EU
+0xBDBB	0xC2A5	#HANGUL SYLLABLE SIOS EU KIYEOK
+0xBDBC	0xC2A8	#HANGUL SYLLABLE SIOS EU NIEUN
+0xBDBD	0xC2AC	#HANGUL SYLLABLE SIOS EU RIEUL
+0xBDBE	0xC2AD	#HANGUL SYLLABLE SIOS EU RIEULKIYEOK
+0xBDBF	0xC2B4	#HANGUL SYLLABLE SIOS EU MIEUM
+0xBDC0	0xC2B5	#HANGUL SYLLABLE SIOS EU PIEUP
+0xBDC1	0xC2B7	#HANGUL SYLLABLE SIOS EU SIOS
+0xBDC2	0xC2B9	#HANGUL SYLLABLE SIOS EU IEUNG
+0xBDC3	0xC2DC	#HANGUL SYLLABLE SIOS I
+0xBDC4	0xC2DD	#HANGUL SYLLABLE SIOS I KIYEOK
+0xBDC5	0xC2E0	#HANGUL SYLLABLE SIOS I NIEUN
+0xBDC6	0xC2E3	#HANGUL SYLLABLE SIOS I TIKEUT
+0xBDC7	0xC2E4	#HANGUL SYLLABLE SIOS I RIEUL
+0xBDC8	0xC2EB	#HANGUL SYLLABLE SIOS I RIEULHIEUH
+0xBDC9	0xC2EC	#HANGUL SYLLABLE SIOS I MIEUM
+0xBDCA	0xC2ED	#HANGUL SYLLABLE SIOS I PIEUP
+0xBDCB	0xC2EF	#HANGUL SYLLABLE SIOS I SIOS
+0xBDCC	0xC2F1	#HANGUL SYLLABLE SIOS I IEUNG
+0xBDCD	0xC2F6	#HANGUL SYLLABLE SIOS I PHIEUPH
+0xBDCE	0xC2F8	#HANGUL SYLLABLE SSANGSIOS A
+0xBDCF	0xC2F9	#HANGUL SYLLABLE SSANGSIOS A KIYEOK
+0xBDD0	0xC2FB	#HANGUL SYLLABLE SSANGSIOS A KIYEOKSIOS
+0xBDD1	0xC2FC	#HANGUL SYLLABLE SSANGSIOS A NIEUN
+0xBDD2	0xC300	#HANGUL SYLLABLE SSANGSIOS A RIEUL
+0xBDD3	0xC308	#HANGUL SYLLABLE SSANGSIOS A MIEUM
+0xBDD4	0xC309	#HANGUL SYLLABLE SSANGSIOS A PIEUP
+0xBDD5	0xC30C	#HANGUL SYLLABLE SSANGSIOS A SSANGSIOS
+0xBDD6	0xC30D	#HANGUL SYLLABLE SSANGSIOS A IEUNG
+0xBDD7	0xC313	#HANGUL SYLLABLE SSANGSIOS A HIEUH
+0xBDD8	0xC314	#HANGUL SYLLABLE SSANGSIOS AE
+0xBDD9	0xC315	#HANGUL SYLLABLE SSANGSIOS AE KIYEOK
+0xBDDA	0xC318	#HANGUL SYLLABLE SSANGSIOS AE NIEUN
+0xBDDB	0xC31C	#HANGUL SYLLABLE SSANGSIOS AE RIEUL
+0xBDDC	0xC324	#HANGUL SYLLABLE SSANGSIOS AE MIEUM
+0xBDDD	0xC325	#HANGUL SYLLABLE SSANGSIOS AE PIEUP
+0xBDDE	0xC328	#HANGUL SYLLABLE SSANGSIOS AE SSANGSIOS
+0xBDDF	0xC329	#HANGUL SYLLABLE SSANGSIOS AE IEUNG
+0xBDE0	0xC345	#HANGUL SYLLABLE SSANGSIOS YA IEUNG
+0xBDE1	0xC368	#HANGUL SYLLABLE SSANGSIOS EO
+0xBDE2	0xC369	#HANGUL SYLLABLE SSANGSIOS EO KIYEOK
+0xBDE3	0xC36C	#HANGUL SYLLABLE SSANGSIOS EO NIEUN
+0xBDE4	0xC370	#HANGUL SYLLABLE SSANGSIOS EO RIEUL
+0xBDE5	0xC372	#HANGUL SYLLABLE SSANGSIOS EO RIEULMIEUM
+0xBDE6	0xC378	#HANGUL SYLLABLE SSANGSIOS EO MIEUM
+0xBDE7	0xC379	#HANGUL SYLLABLE SSANGSIOS EO PIEUP
+0xBDE8	0xC37C	#HANGUL SYLLABLE SSANGSIOS EO SSANGSIOS
+0xBDE9	0xC37D	#HANGUL SYLLABLE SSANGSIOS EO IEUNG
+0xBDEA	0xC384	#HANGUL SYLLABLE SSANGSIOS E
+0xBDEB	0xC388	#HANGUL SYLLABLE SSANGSIOS E NIEUN
+0xBDEC	0xC38C	#HANGUL SYLLABLE SSANGSIOS E RIEUL
+0xBDED	0xC3C0	#HANGUL SYLLABLE SSANGSIOS YE NIEUN
+0xBDEE	0xC3D8	#HANGUL SYLLABLE SSANGSIOS O
+0xBDEF	0xC3D9	#HANGUL SYLLABLE SSANGSIOS O KIYEOK
+0xBDF0	0xC3DC	#HANGUL SYLLABLE SSANGSIOS O NIEUN
+0xBDF1	0xC3DF	#HANGUL SYLLABLE SSANGSIOS O TIKEUT
+0xBDF2	0xC3E0	#HANGUL SYLLABLE SSANGSIOS O RIEUL
+0xBDF3	0xC3E2	#HANGUL SYLLABLE SSANGSIOS O RIEULMIEUM
+0xBDF4	0xC3E8	#HANGUL SYLLABLE SSANGSIOS O MIEUM
+0xBDF5	0xC3E9	#HANGUL SYLLABLE SSANGSIOS O PIEUP
+0xBDF6	0xC3ED	#HANGUL SYLLABLE SSANGSIOS O IEUNG
+0xBDF7	0xC3F4	#HANGUL SYLLABLE SSANGSIOS WA
+0xBDF8	0xC3F5	#HANGUL SYLLABLE SSANGSIOS WA KIYEOK
+0xBDF9	0xC3F8	#HANGUL SYLLABLE SSANGSIOS WA NIEUN
+0xBDFA	0xC408	#HANGUL SYLLABLE SSANGSIOS WA SSANGSIOS
+0xBDFB	0xC410	#HANGUL SYLLABLE SSANGSIOS WAE
+0xBDFC	0xC424	#HANGUL SYLLABLE SSANGSIOS WAE SSANGSIOS
+0xBDFD	0xC42C	#HANGUL SYLLABLE SSANGSIOS OE
+0xBDFE	0xC430	#HANGUL SYLLABLE SSANGSIOS OE NIEUN
+0xBE41	0xD438	#HANGUL SYLLABLE PHIEUPH WAE SSANGSIOS
+0xBE42	0xD439	#HANGUL SYLLABLE PHIEUPH WAE IEUNG
+0xBE43	0xD43A	#HANGUL SYLLABLE PHIEUPH WAE CIEUC
+0xBE44	0xD43B	#HANGUL SYLLABLE PHIEUPH WAE CHIEUCH
+0xBE45	0xD43C	#HANGUL SYLLABLE PHIEUPH WAE KHIEUKH
+0xBE46	0xD43D	#HANGUL SYLLABLE PHIEUPH WAE THIEUTH
+0xBE47	0xD43E	#HANGUL SYLLABLE PHIEUPH WAE PHIEUPH
+0xBE48	0xD43F	#HANGUL SYLLABLE PHIEUPH WAE HIEUH
+0xBE49	0xD441	#HANGUL SYLLABLE PHIEUPH OE KIYEOK
+0xBE4A	0xD442	#HANGUL SYLLABLE PHIEUPH OE SSANGKIYEOK
+0xBE4B	0xD443	#HANGUL SYLLABLE PHIEUPH OE KIYEOKSIOS
+0xBE4C	0xD445	#HANGUL SYLLABLE PHIEUPH OE NIEUNCIEUC
+0xBE4D	0xD446	#HANGUL SYLLABLE PHIEUPH OE NIEUNHIEUH
+0xBE4E	0xD447	#HANGUL SYLLABLE PHIEUPH OE TIKEUT
+0xBE4F	0xD448	#HANGUL SYLLABLE PHIEUPH OE RIEUL
+0xBE50	0xD449	#HANGUL SYLLABLE PHIEUPH OE RIEULKIYEOK
+0xBE51	0xD44A	#HANGUL SYLLABLE PHIEUPH OE RIEULMIEUM
+0xBE52	0xD44B	#HANGUL SYLLABLE PHIEUPH OE RIEULPIEUP
+0xBE53	0xD44C	#HANGUL SYLLABLE PHIEUPH OE RIEULSIOS
+0xBE54	0xD44D	#HANGUL SYLLABLE PHIEUPH OE RIEULTHIEUTH
+0xBE55	0xD44E	#HANGUL SYLLABLE PHIEUPH OE RIEULPHIEUPH
+0xBE56	0xD44F	#HANGUL SYLLABLE PHIEUPH OE RIEULHIEUH
+0xBE57	0xD450	#HANGUL SYLLABLE PHIEUPH OE MIEUM
+0xBE58	0xD451	#HANGUL SYLLABLE PHIEUPH OE PIEUP
+0xBE59	0xD452	#HANGUL SYLLABLE PHIEUPH OE PIEUPSIOS
+0xBE5A	0xD453	#HANGUL SYLLABLE PHIEUPH OE SIOS
+0xBE61	0xD454	#HANGUL SYLLABLE PHIEUPH OE SSANGSIOS
+0xBE62	0xD455	#HANGUL SYLLABLE PHIEUPH OE IEUNG
+0xBE63	0xD456	#HANGUL SYLLABLE PHIEUPH OE CIEUC
+0xBE64	0xD457	#HANGUL SYLLABLE PHIEUPH OE CHIEUCH
+0xBE65	0xD458	#HANGUL SYLLABLE PHIEUPH OE KHIEUKH
+0xBE66	0xD459	#HANGUL SYLLABLE PHIEUPH OE THIEUTH
+0xBE67	0xD45A	#HANGUL SYLLABLE PHIEUPH OE PHIEUPH
+0xBE68	0xD45B	#HANGUL SYLLABLE PHIEUPH OE HIEUH
+0xBE69	0xD45D	#HANGUL SYLLABLE PHIEUPH YO KIYEOK
+0xBE6A	0xD45E	#HANGUL SYLLABLE PHIEUPH YO SSANGKIYEOK
+0xBE6B	0xD45F	#HANGUL SYLLABLE PHIEUPH YO KIYEOKSIOS
+0xBE6C	0xD461	#HANGUL SYLLABLE PHIEUPH YO NIEUNCIEUC
+0xBE6D	0xD462	#HANGUL SYLLABLE PHIEUPH YO NIEUNHIEUH
+0xBE6E	0xD463	#HANGUL SYLLABLE PHIEUPH YO TIKEUT
+0xBE6F	0xD465	#HANGUL SYLLABLE PHIEUPH YO RIEULKIYEOK
+0xBE70	0xD466	#HANGUL SYLLABLE PHIEUPH YO RIEULMIEUM
+0xBE71	0xD467	#HANGUL SYLLABLE PHIEUPH YO RIEULPIEUP
+0xBE72	0xD468	#HANGUL SYLLABLE PHIEUPH YO RIEULSIOS
+0xBE73	0xD469	#HANGUL SYLLABLE PHIEUPH YO RIEULTHIEUTH
+0xBE74	0xD46A	#HANGUL SYLLABLE PHIEUPH YO RIEULPHIEUPH
+0xBE75	0xD46B	#HANGUL SYLLABLE PHIEUPH YO RIEULHIEUH
+0xBE76	0xD46C	#HANGUL SYLLABLE PHIEUPH YO MIEUM
+0xBE77	0xD46E	#HANGUL SYLLABLE PHIEUPH YO PIEUPSIOS
+0xBE78	0xD470	#HANGUL SYLLABLE PHIEUPH YO SSANGSIOS
+0xBE79	0xD471	#HANGUL SYLLABLE PHIEUPH YO IEUNG
+0xBE7A	0xD472	#HANGUL SYLLABLE PHIEUPH YO CIEUC
+0xBE81	0xD473	#HANGUL SYLLABLE PHIEUPH YO CHIEUCH
+0xBE82	0xD474	#HANGUL SYLLABLE PHIEUPH YO KHIEUKH
+0xBE83	0xD475	#HANGUL SYLLABLE PHIEUPH YO THIEUTH
+0xBE84	0xD476	#HANGUL SYLLABLE PHIEUPH YO PHIEUPH
+0xBE85	0xD477	#HANGUL SYLLABLE PHIEUPH YO HIEUH
+0xBE86	0xD47A	#HANGUL SYLLABLE PHIEUPH U SSANGKIYEOK
+0xBE87	0xD47B	#HANGUL SYLLABLE PHIEUPH U KIYEOKSIOS
+0xBE88	0xD47D	#HANGUL SYLLABLE PHIEUPH U NIEUNCIEUC
+0xBE89	0xD47E	#HANGUL SYLLABLE PHIEUPH U NIEUNHIEUH
+0xBE8A	0xD481	#HANGUL SYLLABLE PHIEUPH U RIEULKIYEOK
+0xBE8B	0xD483	#HANGUL SYLLABLE PHIEUPH U RIEULPIEUP
+0xBE8C	0xD484	#HANGUL SYLLABLE PHIEUPH U RIEULSIOS
+0xBE8D	0xD485	#HANGUL SYLLABLE PHIEUPH U RIEULTHIEUTH
+0xBE8E	0xD486	#HANGUL SYLLABLE PHIEUPH U RIEULPHIEUPH
+0xBE8F	0xD487	#HANGUL SYLLABLE PHIEUPH U RIEULHIEUH
+0xBE90	0xD48A	#HANGUL SYLLABLE PHIEUPH U PIEUPSIOS
+0xBE91	0xD48C	#HANGUL SYLLABLE PHIEUPH U SSANGSIOS
+0xBE92	0xD48E	#HANGUL SYLLABLE PHIEUPH U CIEUC
+0xBE93	0xD48F	#HANGUL SYLLABLE PHIEUPH U CHIEUCH
+0xBE94	0xD490	#HANGUL SYLLABLE PHIEUPH U KHIEUKH
+0xBE95	0xD491	#HANGUL SYLLABLE PHIEUPH U THIEUTH
+0xBE96	0xD492	#HANGUL SYLLABLE PHIEUPH U PHIEUPH
+0xBE97	0xD493	#HANGUL SYLLABLE PHIEUPH U HIEUH
+0xBE98	0xD495	#HANGUL SYLLABLE PHIEUPH WEO KIYEOK
+0xBE99	0xD496	#HANGUL SYLLABLE PHIEUPH WEO SSANGKIYEOK
+0xBE9A	0xD497	#HANGUL SYLLABLE PHIEUPH WEO KIYEOKSIOS
+0xBE9B	0xD498	#HANGUL SYLLABLE PHIEUPH WEO NIEUN
+0xBE9C	0xD499	#HANGUL SYLLABLE PHIEUPH WEO NIEUNCIEUC
+0xBE9D	0xD49A	#HANGUL SYLLABLE PHIEUPH WEO NIEUNHIEUH
+0xBE9E	0xD49B	#HANGUL SYLLABLE PHIEUPH WEO TIKEUT
+0xBE9F	0xD49C	#HANGUL SYLLABLE PHIEUPH WEO RIEUL
+0xBEA0	0xD49D	#HANGUL SYLLABLE PHIEUPH WEO RIEULKIYEOK
+0xBEA1	0xC434	#HANGUL SYLLABLE SSANGSIOS OE RIEUL
+0xBEA2	0xC43C	#HANGUL SYLLABLE SSANGSIOS OE MIEUM
+0xBEA3	0xC43D	#HANGUL SYLLABLE SSANGSIOS OE PIEUP
+0xBEA4	0xC448	#HANGUL SYLLABLE SSANGSIOS YO
+0xBEA5	0xC464	#HANGUL SYLLABLE SSANGSIOS U
+0xBEA6	0xC465	#HANGUL SYLLABLE SSANGSIOS U KIYEOK
+0xBEA7	0xC468	#HANGUL SYLLABLE SSANGSIOS U NIEUN
+0xBEA8	0xC46C	#HANGUL SYLLABLE SSANGSIOS U RIEUL
+0xBEA9	0xC474	#HANGUL SYLLABLE SSANGSIOS U MIEUM
+0xBEAA	0xC475	#HANGUL SYLLABLE SSANGSIOS U PIEUP
+0xBEAB	0xC479	#HANGUL SYLLABLE SSANGSIOS U IEUNG
+0xBEAC	0xC480	#HANGUL SYLLABLE SSANGSIOS WEO
+0xBEAD	0xC494	#HANGUL SYLLABLE SSANGSIOS WEO SSANGSIOS
+0xBEAE	0xC49C	#HANGUL SYLLABLE SSANGSIOS WE
+0xBEAF	0xC4B8	#HANGUL SYLLABLE SSANGSIOS WI
+0xBEB0	0xC4BC	#HANGUL SYLLABLE SSANGSIOS WI NIEUN
+0xBEB1	0xC4E9	#HANGUL SYLLABLE SSANGSIOS YU IEUNG
+0xBEB2	0xC4F0	#HANGUL SYLLABLE SSANGSIOS EU
+0xBEB3	0xC4F1	#HANGUL SYLLABLE SSANGSIOS EU KIYEOK
+0xBEB4	0xC4F4	#HANGUL SYLLABLE SSANGSIOS EU NIEUN
+0xBEB5	0xC4F8	#HANGUL SYLLABLE SSANGSIOS EU RIEUL
+0xBEB6	0xC4FA	#HANGUL SYLLABLE SSANGSIOS EU RIEULMIEUM
+0xBEB7	0xC4FF	#HANGUL SYLLABLE SSANGSIOS EU RIEULHIEUH
+0xBEB8	0xC500	#HANGUL SYLLABLE SSANGSIOS EU MIEUM
+0xBEB9	0xC501	#HANGUL SYLLABLE SSANGSIOS EU PIEUP
+0xBEBA	0xC50C	#HANGUL SYLLABLE SSANGSIOS YI
+0xBEBB	0xC510	#HANGUL SYLLABLE SSANGSIOS YI NIEUN
+0xBEBC	0xC514	#HANGUL SYLLABLE SSANGSIOS YI RIEUL
+0xBEBD	0xC51C	#HANGUL SYLLABLE SSANGSIOS YI MIEUM
+0xBEBE	0xC528	#HANGUL SYLLABLE SSANGSIOS I
+0xBEBF	0xC529	#HANGUL SYLLABLE SSANGSIOS I KIYEOK
+0xBEC0	0xC52C	#HANGUL SYLLABLE SSANGSIOS I NIEUN
+0xBEC1	0xC530	#HANGUL SYLLABLE SSANGSIOS I RIEUL
+0xBEC2	0xC538	#HANGUL SYLLABLE SSANGSIOS I MIEUM
+0xBEC3	0xC539	#HANGUL SYLLABLE SSANGSIOS I PIEUP
+0xBEC4	0xC53B	#HANGUL SYLLABLE SSANGSIOS I SIOS
+0xBEC5	0xC53D	#HANGUL SYLLABLE SSANGSIOS I IEUNG
+0xBEC6	0xC544	#HANGUL SYLLABLE IEUNG A
+0xBEC7	0xC545	#HANGUL SYLLABLE IEUNG A KIYEOK
+0xBEC8	0xC548	#HANGUL SYLLABLE IEUNG A NIEUN
+0xBEC9	0xC549	#HANGUL SYLLABLE IEUNG A NIEUNCIEUC
+0xBECA	0xC54A	#HANGUL SYLLABLE IEUNG A NIEUNHIEUH
+0xBECB	0xC54C	#HANGUL SYLLABLE IEUNG A RIEUL
+0xBECC	0xC54D	#HANGUL SYLLABLE IEUNG A RIEULKIYEOK
+0xBECD	0xC54E	#HANGUL SYLLABLE IEUNG A RIEULMIEUM
+0xBECE	0xC553	#HANGUL SYLLABLE IEUNG A RIEULHIEUH
+0xBECF	0xC554	#HANGUL SYLLABLE IEUNG A MIEUM
+0xBED0	0xC555	#HANGUL SYLLABLE IEUNG A PIEUP
+0xBED1	0xC557	#HANGUL SYLLABLE IEUNG A SIOS
+0xBED2	0xC558	#HANGUL SYLLABLE IEUNG A SSANGSIOS
+0xBED3	0xC559	#HANGUL SYLLABLE IEUNG A IEUNG
+0xBED4	0xC55D	#HANGUL SYLLABLE IEUNG A THIEUTH
+0xBED5	0xC55E	#HANGUL SYLLABLE IEUNG A PHIEUPH
+0xBED6	0xC560	#HANGUL SYLLABLE IEUNG AE
+0xBED7	0xC561	#HANGUL SYLLABLE IEUNG AE KIYEOK
+0xBED8	0xC564	#HANGUL SYLLABLE IEUNG AE NIEUN
+0xBED9	0xC568	#HANGUL SYLLABLE IEUNG AE RIEUL
+0xBEDA	0xC570	#HANGUL SYLLABLE IEUNG AE MIEUM
+0xBEDB	0xC571	#HANGUL SYLLABLE IEUNG AE PIEUP
+0xBEDC	0xC573	#HANGUL SYLLABLE IEUNG AE SIOS
+0xBEDD	0xC574	#HANGUL SYLLABLE IEUNG AE SSANGSIOS
+0xBEDE	0xC575	#HANGUL SYLLABLE IEUNG AE IEUNG
+0xBEDF	0xC57C	#HANGUL SYLLABLE IEUNG YA
+0xBEE0	0xC57D	#HANGUL SYLLABLE IEUNG YA KIYEOK
+0xBEE1	0xC580	#HANGUL SYLLABLE IEUNG YA NIEUN
+0xBEE2	0xC584	#HANGUL SYLLABLE IEUNG YA RIEUL
+0xBEE3	0xC587	#HANGUL SYLLABLE IEUNG YA RIEULPIEUP
+0xBEE4	0xC58C	#HANGUL SYLLABLE IEUNG YA MIEUM
+0xBEE5	0xC58D	#HANGUL SYLLABLE IEUNG YA PIEUP
+0xBEE6	0xC58F	#HANGUL SYLLABLE IEUNG YA SIOS
+0xBEE7	0xC591	#HANGUL SYLLABLE IEUNG YA IEUNG
+0xBEE8	0xC595	#HANGUL SYLLABLE IEUNG YA THIEUTH
+0xBEE9	0xC597	#HANGUL SYLLABLE IEUNG YA HIEUH
+0xBEEA	0xC598	#HANGUL SYLLABLE IEUNG YAE
+0xBEEB	0xC59C	#HANGUL SYLLABLE IEUNG YAE NIEUN
+0xBEEC	0xC5A0	#HANGUL SYLLABLE IEUNG YAE RIEUL
+0xBEED	0xC5A9	#HANGUL SYLLABLE IEUNG YAE PIEUP
+0xBEEE	0xC5B4	#HANGUL SYLLABLE IEUNG EO
+0xBEEF	0xC5B5	#HANGUL SYLLABLE IEUNG EO KIYEOK
+0xBEF0	0xC5B8	#HANGUL SYLLABLE IEUNG EO NIEUN
+0xBEF1	0xC5B9	#HANGUL SYLLABLE IEUNG EO NIEUNCIEUC
+0xBEF2	0xC5BB	#HANGUL SYLLABLE IEUNG EO TIKEUT
+0xBEF3	0xC5BC	#HANGUL SYLLABLE IEUNG EO RIEUL
+0xBEF4	0xC5BD	#HANGUL SYLLABLE IEUNG EO RIEULKIYEOK
+0xBEF5	0xC5BE	#HANGUL SYLLABLE IEUNG EO RIEULMIEUM
+0xBEF6	0xC5C4	#HANGUL SYLLABLE IEUNG EO MIEUM
+0xBEF7	0xC5C5	#HANGUL SYLLABLE IEUNG EO PIEUP
+0xBEF8	0xC5C6	#HANGUL SYLLABLE IEUNG EO PIEUPSIOS
+0xBEF9	0xC5C7	#HANGUL SYLLABLE IEUNG EO SIOS
+0xBEFA	0xC5C8	#HANGUL SYLLABLE IEUNG EO SSANGSIOS
+0xBEFB	0xC5C9	#HANGUL SYLLABLE IEUNG EO IEUNG
+0xBEFC	0xC5CA	#HANGUL SYLLABLE IEUNG EO CIEUC
+0xBEFD	0xC5CC	#HANGUL SYLLABLE IEUNG EO KHIEUKH
+0xBEFE	0xC5CE	#HANGUL SYLLABLE IEUNG EO PHIEUPH
+0xBF41	0xD49E	#HANGUL SYLLABLE PHIEUPH WEO RIEULMIEUM
+0xBF42	0xD49F	#HANGUL SYLLABLE PHIEUPH WEO RIEULPIEUP
+0xBF43	0xD4A0	#HANGUL SYLLABLE PHIEUPH WEO RIEULSIOS
+0xBF44	0xD4A1	#HANGUL SYLLABLE PHIEUPH WEO RIEULTHIEUTH
+0xBF45	0xD4A2	#HANGUL SYLLABLE PHIEUPH WEO RIEULPHIEUPH
+0xBF46	0xD4A3	#HANGUL SYLLABLE PHIEUPH WEO RIEULHIEUH
+0xBF47	0xD4A4	#HANGUL SYLLABLE PHIEUPH WEO MIEUM
+0xBF48	0xD4A5	#HANGUL SYLLABLE PHIEUPH WEO PIEUP
+0xBF49	0xD4A6	#HANGUL SYLLABLE PHIEUPH WEO PIEUPSIOS
+0xBF4A	0xD4A7	#HANGUL SYLLABLE PHIEUPH WEO SIOS
+0xBF4B	0xD4A8	#HANGUL SYLLABLE PHIEUPH WEO SSANGSIOS
+0xBF4C	0xD4AA	#HANGUL SYLLABLE PHIEUPH WEO CIEUC
+0xBF4D	0xD4AB	#HANGUL SYLLABLE PHIEUPH WEO CHIEUCH
+0xBF4E	0xD4AC	#HANGUL SYLLABLE PHIEUPH WEO KHIEUKH
+0xBF4F	0xD4AD	#HANGUL SYLLABLE PHIEUPH WEO THIEUTH
+0xBF50	0xD4AE	#HANGUL SYLLABLE PHIEUPH WEO PHIEUPH
+0xBF51	0xD4AF	#HANGUL SYLLABLE PHIEUPH WEO HIEUH
+0xBF52	0xD4B0	#HANGUL SYLLABLE PHIEUPH WE
+0xBF53	0xD4B1	#HANGUL SYLLABLE PHIEUPH WE KIYEOK
+0xBF54	0xD4B2	#HANGUL SYLLABLE PHIEUPH WE SSANGKIYEOK
+0xBF55	0xD4B3	#HANGUL SYLLABLE PHIEUPH WE KIYEOKSIOS
+0xBF56	0xD4B4	#HANGUL SYLLABLE PHIEUPH WE NIEUN
+0xBF57	0xD4B5	#HANGUL SYLLABLE PHIEUPH WE NIEUNCIEUC
+0xBF58	0xD4B6	#HANGUL SYLLABLE PHIEUPH WE NIEUNHIEUH
+0xBF59	0xD4B7	#HANGUL SYLLABLE PHIEUPH WE TIKEUT
+0xBF5A	0xD4B8	#HANGUL SYLLABLE PHIEUPH WE RIEUL
+0xBF61	0xD4B9	#HANGUL SYLLABLE PHIEUPH WE RIEULKIYEOK
+0xBF62	0xD4BA	#HANGUL SYLLABLE PHIEUPH WE RIEULMIEUM
+0xBF63	0xD4BB	#HANGUL SYLLABLE PHIEUPH WE RIEULPIEUP
+0xBF64	0xD4BC	#HANGUL SYLLABLE PHIEUPH WE RIEULSIOS
+0xBF65	0xD4BD	#HANGUL SYLLABLE PHIEUPH WE RIEULTHIEUTH
+0xBF66	0xD4BE	#HANGUL SYLLABLE PHIEUPH WE RIEULPHIEUPH
+0xBF67	0xD4BF	#HANGUL SYLLABLE PHIEUPH WE RIEULHIEUH
+0xBF68	0xD4C0	#HANGUL SYLLABLE PHIEUPH WE MIEUM
+0xBF69	0xD4C1	#HANGUL SYLLABLE PHIEUPH WE PIEUP
+0xBF6A	0xD4C2	#HANGUL SYLLABLE PHIEUPH WE PIEUPSIOS
+0xBF6B	0xD4C3	#HANGUL SYLLABLE PHIEUPH WE SIOS
+0xBF6C	0xD4C4	#HANGUL SYLLABLE PHIEUPH WE SSANGSIOS
+0xBF6D	0xD4C5	#HANGUL SYLLABLE PHIEUPH WE IEUNG
+0xBF6E	0xD4C6	#HANGUL SYLLABLE PHIEUPH WE CIEUC
+0xBF6F	0xD4C7	#HANGUL SYLLABLE PHIEUPH WE CHIEUCH
+0xBF70	0xD4C8	#HANGUL SYLLABLE PHIEUPH WE KHIEUKH
+0xBF71	0xD4C9	#HANGUL SYLLABLE PHIEUPH WE THIEUTH
+0xBF72	0xD4CA	#HANGUL SYLLABLE PHIEUPH WE PHIEUPH
+0xBF73	0xD4CB	#HANGUL SYLLABLE PHIEUPH WE HIEUH
+0xBF74	0xD4CD	#HANGUL SYLLABLE PHIEUPH WI KIYEOK
+0xBF75	0xD4CE	#HANGUL SYLLABLE PHIEUPH WI SSANGKIYEOK
+0xBF76	0xD4CF	#HANGUL SYLLABLE PHIEUPH WI KIYEOKSIOS
+0xBF77	0xD4D1	#HANGUL SYLLABLE PHIEUPH WI NIEUNCIEUC
+0xBF78	0xD4D2	#HANGUL SYLLABLE PHIEUPH WI NIEUNHIEUH
+0xBF79	0xD4D3	#HANGUL SYLLABLE PHIEUPH WI TIKEUT
+0xBF7A	0xD4D5	#HANGUL SYLLABLE PHIEUPH WI RIEULKIYEOK
+0xBF81	0xD4D6	#HANGUL SYLLABLE PHIEUPH WI RIEULMIEUM
+0xBF82	0xD4D7	#HANGUL SYLLABLE PHIEUPH WI RIEULPIEUP
+0xBF83	0xD4D8	#HANGUL SYLLABLE PHIEUPH WI RIEULSIOS
+0xBF84	0xD4D9	#HANGUL SYLLABLE PHIEUPH WI RIEULTHIEUTH
+0xBF85	0xD4DA	#HANGUL SYLLABLE PHIEUPH WI RIEULPHIEUPH
+0xBF86	0xD4DB	#HANGUL SYLLABLE PHIEUPH WI RIEULHIEUH
+0xBF87	0xD4DD	#HANGUL SYLLABLE PHIEUPH WI PIEUP
+0xBF88	0xD4DE	#HANGUL SYLLABLE PHIEUPH WI PIEUPSIOS
+0xBF89	0xD4E0	#HANGUL SYLLABLE PHIEUPH WI SSANGSIOS
+0xBF8A	0xD4E1	#HANGUL SYLLABLE PHIEUPH WI IEUNG
+0xBF8B	0xD4E2	#HANGUL SYLLABLE PHIEUPH WI CIEUC
+0xBF8C	0xD4E3	#HANGUL SYLLABLE PHIEUPH WI CHIEUCH
+0xBF8D	0xD4E4	#HANGUL SYLLABLE PHIEUPH WI KHIEUKH
+0xBF8E	0xD4E5	#HANGUL SYLLABLE PHIEUPH WI THIEUTH
+0xBF8F	0xD4E6	#HANGUL SYLLABLE PHIEUPH WI PHIEUPH
+0xBF90	0xD4E7	#HANGUL SYLLABLE PHIEUPH WI HIEUH
+0xBF91	0xD4E9	#HANGUL SYLLABLE PHIEUPH YU KIYEOK
+0xBF92	0xD4EA	#HANGUL SYLLABLE PHIEUPH YU SSANGKIYEOK
+0xBF93	0xD4EB	#HANGUL SYLLABLE PHIEUPH YU KIYEOKSIOS
+0xBF94	0xD4ED	#HANGUL SYLLABLE PHIEUPH YU NIEUNCIEUC
+0xBF95	0xD4EE	#HANGUL SYLLABLE PHIEUPH YU NIEUNHIEUH
+0xBF96	0xD4EF	#HANGUL SYLLABLE PHIEUPH YU TIKEUT
+0xBF97	0xD4F1	#HANGUL SYLLABLE PHIEUPH YU RIEULKIYEOK
+0xBF98	0xD4F2	#HANGUL SYLLABLE PHIEUPH YU RIEULMIEUM
+0xBF99	0xD4F3	#HANGUL SYLLABLE PHIEUPH YU RIEULPIEUP
+0xBF9A	0xD4F4	#HANGUL SYLLABLE PHIEUPH YU RIEULSIOS
+0xBF9B	0xD4F5	#HANGUL SYLLABLE PHIEUPH YU RIEULTHIEUTH
+0xBF9C	0xD4F6	#HANGUL SYLLABLE PHIEUPH YU RIEULPHIEUPH
+0xBF9D	0xD4F7	#HANGUL SYLLABLE PHIEUPH YU RIEULHIEUH
+0xBF9E	0xD4F9	#HANGUL SYLLABLE PHIEUPH YU PIEUP
+0xBF9F	0xD4FA	#HANGUL SYLLABLE PHIEUPH YU PIEUPSIOS
+0xBFA0	0xD4FC	#HANGUL SYLLABLE PHIEUPH YU SSANGSIOS
+0xBFA1	0xC5D0	#HANGUL SYLLABLE IEUNG E
+0xBFA2	0xC5D1	#HANGUL SYLLABLE IEUNG E KIYEOK
+0xBFA3	0xC5D4	#HANGUL SYLLABLE IEUNG E NIEUN
+0xBFA4	0xC5D8	#HANGUL SYLLABLE IEUNG E RIEUL
+0xBFA5	0xC5E0	#HANGUL SYLLABLE IEUNG E MIEUM
+0xBFA6	0xC5E1	#HANGUL SYLLABLE IEUNG E PIEUP
+0xBFA7	0xC5E3	#HANGUL SYLLABLE IEUNG E SIOS
+0xBFA8	0xC5E5	#HANGUL SYLLABLE IEUNG E IEUNG
+0xBFA9	0xC5EC	#HANGUL SYLLABLE IEUNG YEO
+0xBFAA	0xC5ED	#HANGUL SYLLABLE IEUNG YEO KIYEOK
+0xBFAB	0xC5EE	#HANGUL SYLLABLE IEUNG YEO SSANGKIYEOK
+0xBFAC	0xC5F0	#HANGUL SYLLABLE IEUNG YEO NIEUN
+0xBFAD	0xC5F4	#HANGUL SYLLABLE IEUNG YEO RIEUL
+0xBFAE	0xC5F6	#HANGUL SYLLABLE IEUNG YEO RIEULMIEUM
+0xBFAF	0xC5F7	#HANGUL SYLLABLE IEUNG YEO RIEULPIEUP
+0xBFB0	0xC5FC	#HANGUL SYLLABLE IEUNG YEO MIEUM
+0xBFB1	0xC5FD	#HANGUL SYLLABLE IEUNG YEO PIEUP
+0xBFB2	0xC5FE	#HANGUL SYLLABLE IEUNG YEO PIEUPSIOS
+0xBFB3	0xC5FF	#HANGUL SYLLABLE IEUNG YEO SIOS
+0xBFB4	0xC600	#HANGUL SYLLABLE IEUNG YEO SSANGSIOS
+0xBFB5	0xC601	#HANGUL SYLLABLE IEUNG YEO IEUNG
+0xBFB6	0xC605	#HANGUL SYLLABLE IEUNG YEO THIEUTH
+0xBFB7	0xC606	#HANGUL SYLLABLE IEUNG YEO PHIEUPH
+0xBFB8	0xC607	#HANGUL SYLLABLE IEUNG YEO HIEUH
+0xBFB9	0xC608	#HANGUL SYLLABLE IEUNG YE
+0xBFBA	0xC60C	#HANGUL SYLLABLE IEUNG YE NIEUN
+0xBFBB	0xC610	#HANGUL SYLLABLE IEUNG YE RIEUL
+0xBFBC	0xC618	#HANGUL SYLLABLE IEUNG YE MIEUM
+0xBFBD	0xC619	#HANGUL SYLLABLE IEUNG YE PIEUP
+0xBFBE	0xC61B	#HANGUL SYLLABLE IEUNG YE SIOS
+0xBFBF	0xC61C	#HANGUL SYLLABLE IEUNG YE SSANGSIOS
+0xBFC0	0xC624	#HANGUL SYLLABLE IEUNG O
+0xBFC1	0xC625	#HANGUL SYLLABLE IEUNG O KIYEOK
+0xBFC2	0xC628	#HANGUL SYLLABLE IEUNG O NIEUN
+0xBFC3	0xC62C	#HANGUL SYLLABLE IEUNG O RIEUL
+0xBFC4	0xC62D	#HANGUL SYLLABLE IEUNG O RIEULKIYEOK
+0xBFC5	0xC62E	#HANGUL SYLLABLE IEUNG O RIEULMIEUM
+0xBFC6	0xC630	#HANGUL SYLLABLE IEUNG O RIEULSIOS
+0xBFC7	0xC633	#HANGUL SYLLABLE IEUNG O RIEULHIEUH
+0xBFC8	0xC634	#HANGUL SYLLABLE IEUNG O MIEUM
+0xBFC9	0xC635	#HANGUL SYLLABLE IEUNG O PIEUP
+0xBFCA	0xC637	#HANGUL SYLLABLE IEUNG O SIOS
+0xBFCB	0xC639	#HANGUL SYLLABLE IEUNG O IEUNG
+0xBFCC	0xC63B	#HANGUL SYLLABLE IEUNG O CHIEUCH
+0xBFCD	0xC640	#HANGUL SYLLABLE IEUNG WA
+0xBFCE	0xC641	#HANGUL SYLLABLE IEUNG WA KIYEOK
+0xBFCF	0xC644	#HANGUL SYLLABLE IEUNG WA NIEUN
+0xBFD0	0xC648	#HANGUL SYLLABLE IEUNG WA RIEUL
+0xBFD1	0xC650	#HANGUL SYLLABLE IEUNG WA MIEUM
+0xBFD2	0xC651	#HANGUL SYLLABLE IEUNG WA PIEUP
+0xBFD3	0xC653	#HANGUL SYLLABLE IEUNG WA SIOS
+0xBFD4	0xC654	#HANGUL SYLLABLE IEUNG WA SSANGSIOS
+0xBFD5	0xC655	#HANGUL SYLLABLE IEUNG WA IEUNG
+0xBFD6	0xC65C	#HANGUL SYLLABLE IEUNG WAE
+0xBFD7	0xC65D	#HANGUL SYLLABLE IEUNG WAE KIYEOK
+0xBFD8	0xC660	#HANGUL SYLLABLE IEUNG WAE NIEUN
+0xBFD9	0xC66C	#HANGUL SYLLABLE IEUNG WAE MIEUM
+0xBFDA	0xC66F	#HANGUL SYLLABLE IEUNG WAE SIOS
+0xBFDB	0xC671	#HANGUL SYLLABLE IEUNG WAE IEUNG
+0xBFDC	0xC678	#HANGUL SYLLABLE IEUNG OE
+0xBFDD	0xC679	#HANGUL SYLLABLE IEUNG OE KIYEOK
+0xBFDE	0xC67C	#HANGUL SYLLABLE IEUNG OE NIEUN
+0xBFDF	0xC680	#HANGUL SYLLABLE IEUNG OE RIEUL
+0xBFE0	0xC688	#HANGUL SYLLABLE IEUNG OE MIEUM
+0xBFE1	0xC689	#HANGUL SYLLABLE IEUNG OE PIEUP
+0xBFE2	0xC68B	#HANGUL SYLLABLE IEUNG OE SIOS
+0xBFE3	0xC68D	#HANGUL SYLLABLE IEUNG OE IEUNG
+0xBFE4	0xC694	#HANGUL SYLLABLE IEUNG YO
+0xBFE5	0xC695	#HANGUL SYLLABLE IEUNG YO KIYEOK
+0xBFE6	0xC698	#HANGUL SYLLABLE IEUNG YO NIEUN
+0xBFE7	0xC69C	#HANGUL SYLLABLE IEUNG YO RIEUL
+0xBFE8	0xC6A4	#HANGUL SYLLABLE IEUNG YO MIEUM
+0xBFE9	0xC6A5	#HANGUL SYLLABLE IEUNG YO PIEUP
+0xBFEA	0xC6A7	#HANGUL SYLLABLE IEUNG YO SIOS
+0xBFEB	0xC6A9	#HANGUL SYLLABLE IEUNG YO IEUNG
+0xBFEC	0xC6B0	#HANGUL SYLLABLE IEUNG U
+0xBFED	0xC6B1	#HANGUL SYLLABLE IEUNG U KIYEOK
+0xBFEE	0xC6B4	#HANGUL SYLLABLE IEUNG U NIEUN
+0xBFEF	0xC6B8	#HANGUL SYLLABLE IEUNG U RIEUL
+0xBFF0	0xC6B9	#HANGUL SYLLABLE IEUNG U RIEULKIYEOK
+0xBFF1	0xC6BA	#HANGUL SYLLABLE IEUNG U RIEULMIEUM
+0xBFF2	0xC6C0	#HANGUL SYLLABLE IEUNG U MIEUM
+0xBFF3	0xC6C1	#HANGUL SYLLABLE IEUNG U PIEUP
+0xBFF4	0xC6C3	#HANGUL SYLLABLE IEUNG U SIOS
+0xBFF5	0xC6C5	#HANGUL SYLLABLE IEUNG U IEUNG
+0xBFF6	0xC6CC	#HANGUL SYLLABLE IEUNG WEO
+0xBFF7	0xC6CD	#HANGUL SYLLABLE IEUNG WEO KIYEOK
+0xBFF8	0xC6D0	#HANGUL SYLLABLE IEUNG WEO NIEUN
+0xBFF9	0xC6D4	#HANGUL SYLLABLE IEUNG WEO RIEUL
+0xBFFA	0xC6DC	#HANGUL SYLLABLE IEUNG WEO MIEUM
+0xBFFB	0xC6DD	#HANGUL SYLLABLE IEUNG WEO PIEUP
+0xBFFC	0xC6E0	#HANGUL SYLLABLE IEUNG WEO SSANGSIOS
+0xBFFD	0xC6E1	#HANGUL SYLLABLE IEUNG WEO IEUNG
+0xBFFE	0xC6E8	#HANGUL SYLLABLE IEUNG WE
+0xC041	0xD4FE	#HANGUL SYLLABLE PHIEUPH YU CIEUC
+0xC042	0xD4FF	#HANGUL SYLLABLE PHIEUPH YU CHIEUCH
+0xC043	0xD500	#HANGUL SYLLABLE PHIEUPH YU KHIEUKH
+0xC044	0xD501	#HANGUL SYLLABLE PHIEUPH YU THIEUTH
+0xC045	0xD502	#HANGUL SYLLABLE PHIEUPH YU PHIEUPH
+0xC046	0xD503	#HANGUL SYLLABLE PHIEUPH YU HIEUH
+0xC047	0xD505	#HANGUL SYLLABLE PHIEUPH EU KIYEOK
+0xC048	0xD506	#HANGUL SYLLABLE PHIEUPH EU SSANGKIYEOK
+0xC049	0xD507	#HANGUL SYLLABLE PHIEUPH EU KIYEOKSIOS
+0xC04A	0xD509	#HANGUL SYLLABLE PHIEUPH EU NIEUNCIEUC
+0xC04B	0xD50A	#HANGUL SYLLABLE PHIEUPH EU NIEUNHIEUH
+0xC04C	0xD50B	#HANGUL SYLLABLE PHIEUPH EU TIKEUT
+0xC04D	0xD50D	#HANGUL SYLLABLE PHIEUPH EU RIEULKIYEOK
+0xC04E	0xD50E	#HANGUL SYLLABLE PHIEUPH EU RIEULMIEUM
+0xC04F	0xD50F	#HANGUL SYLLABLE PHIEUPH EU RIEULPIEUP
+0xC050	0xD510	#HANGUL SYLLABLE PHIEUPH EU RIEULSIOS
+0xC051	0xD511	#HANGUL SYLLABLE PHIEUPH EU RIEULTHIEUTH
+0xC052	0xD512	#HANGUL SYLLABLE PHIEUPH EU RIEULPHIEUPH
+0xC053	0xD513	#HANGUL SYLLABLE PHIEUPH EU RIEULHIEUH
+0xC054	0xD516	#HANGUL SYLLABLE PHIEUPH EU PIEUPSIOS
+0xC055	0xD518	#HANGUL SYLLABLE PHIEUPH EU SSANGSIOS
+0xC056	0xD519	#HANGUL SYLLABLE PHIEUPH EU IEUNG
+0xC057	0xD51A	#HANGUL SYLLABLE PHIEUPH EU CIEUC
+0xC058	0xD51B	#HANGUL SYLLABLE PHIEUPH EU CHIEUCH
+0xC059	0xD51C	#HANGUL SYLLABLE PHIEUPH EU KHIEUKH
+0xC05A	0xD51D	#HANGUL SYLLABLE PHIEUPH EU THIEUTH
+0xC061	0xD51E	#HANGUL SYLLABLE PHIEUPH EU PHIEUPH
+0xC062	0xD51F	#HANGUL SYLLABLE PHIEUPH EU HIEUH
+0xC063	0xD520	#HANGUL SYLLABLE PHIEUPH YI
+0xC064	0xD521	#HANGUL SYLLABLE PHIEUPH YI KIYEOK
+0xC065	0xD522	#HANGUL SYLLABLE PHIEUPH YI SSANGKIYEOK
+0xC066	0xD523	#HANGUL SYLLABLE PHIEUPH YI KIYEOKSIOS
+0xC067	0xD524	#HANGUL SYLLABLE PHIEUPH YI NIEUN
+0xC068	0xD525	#HANGUL SYLLABLE PHIEUPH YI NIEUNCIEUC
+0xC069	0xD526	#HANGUL SYLLABLE PHIEUPH YI NIEUNHIEUH
+0xC06A	0xD527	#HANGUL SYLLABLE PHIEUPH YI TIKEUT
+0xC06B	0xD528	#HANGUL SYLLABLE PHIEUPH YI RIEUL
+0xC06C	0xD529	#HANGUL SYLLABLE PHIEUPH YI RIEULKIYEOK
+0xC06D	0xD52A	#HANGUL SYLLABLE PHIEUPH YI RIEULMIEUM
+0xC06E	0xD52B	#HANGUL SYLLABLE PHIEUPH YI RIEULPIEUP
+0xC06F	0xD52C	#HANGUL SYLLABLE PHIEUPH YI RIEULSIOS
+0xC070	0xD52D	#HANGUL SYLLABLE PHIEUPH YI RIEULTHIEUTH
+0xC071	0xD52E	#HANGUL SYLLABLE PHIEUPH YI RIEULPHIEUPH
+0xC072	0xD52F	#HANGUL SYLLABLE PHIEUPH YI RIEULHIEUH
+0xC073	0xD530	#HANGUL SYLLABLE PHIEUPH YI MIEUM
+0xC074	0xD531	#HANGUL SYLLABLE PHIEUPH YI PIEUP
+0xC075	0xD532	#HANGUL SYLLABLE PHIEUPH YI PIEUPSIOS
+0xC076	0xD533	#HANGUL SYLLABLE PHIEUPH YI SIOS
+0xC077	0xD534	#HANGUL SYLLABLE PHIEUPH YI SSANGSIOS
+0xC078	0xD535	#HANGUL SYLLABLE PHIEUPH YI IEUNG
+0xC079	0xD536	#HANGUL SYLLABLE PHIEUPH YI CIEUC
+0xC07A	0xD537	#HANGUL SYLLABLE PHIEUPH YI CHIEUCH
+0xC081	0xD538	#HANGUL SYLLABLE PHIEUPH YI KHIEUKH
+0xC082	0xD539	#HANGUL SYLLABLE PHIEUPH YI THIEUTH
+0xC083	0xD53A	#HANGUL SYLLABLE PHIEUPH YI PHIEUPH
+0xC084	0xD53B	#HANGUL SYLLABLE PHIEUPH YI HIEUH
+0xC085	0xD53E	#HANGUL SYLLABLE PHIEUPH I SSANGKIYEOK
+0xC086	0xD53F	#HANGUL SYLLABLE PHIEUPH I KIYEOKSIOS
+0xC087	0xD541	#HANGUL SYLLABLE PHIEUPH I NIEUNCIEUC
+0xC088	0xD542	#HANGUL SYLLABLE PHIEUPH I NIEUNHIEUH
+0xC089	0xD543	#HANGUL SYLLABLE PHIEUPH I TIKEUT
+0xC08A	0xD545	#HANGUL SYLLABLE PHIEUPH I RIEULKIYEOK
+0xC08B	0xD546	#HANGUL SYLLABLE PHIEUPH I RIEULMIEUM
+0xC08C	0xD547	#HANGUL SYLLABLE PHIEUPH I RIEULPIEUP
+0xC08D	0xD548	#HANGUL SYLLABLE PHIEUPH I RIEULSIOS
+0xC08E	0xD549	#HANGUL SYLLABLE PHIEUPH I RIEULTHIEUTH
+0xC08F	0xD54A	#HANGUL SYLLABLE PHIEUPH I RIEULPHIEUPH
+0xC090	0xD54B	#HANGUL SYLLABLE PHIEUPH I RIEULHIEUH
+0xC091	0xD54E	#HANGUL SYLLABLE PHIEUPH I PIEUPSIOS
+0xC092	0xD550	#HANGUL SYLLABLE PHIEUPH I SSANGSIOS
+0xC093	0xD552	#HANGUL SYLLABLE PHIEUPH I CIEUC
+0xC094	0xD553	#HANGUL SYLLABLE PHIEUPH I CHIEUCH
+0xC095	0xD554	#HANGUL SYLLABLE PHIEUPH I KHIEUKH
+0xC096	0xD555	#HANGUL SYLLABLE PHIEUPH I THIEUTH
+0xC097	0xD556	#HANGUL SYLLABLE PHIEUPH I PHIEUPH
+0xC098	0xD557	#HANGUL SYLLABLE PHIEUPH I HIEUH
+0xC099	0xD55A	#HANGUL SYLLABLE HIEUH A SSANGKIYEOK
+0xC09A	0xD55B	#HANGUL SYLLABLE HIEUH A KIYEOKSIOS
+0xC09B	0xD55D	#HANGUL SYLLABLE HIEUH A NIEUNCIEUC
+0xC09C	0xD55E	#HANGUL SYLLABLE HIEUH A NIEUNHIEUH
+0xC09D	0xD55F	#HANGUL SYLLABLE HIEUH A TIKEUT
+0xC09E	0xD561	#HANGUL SYLLABLE HIEUH A RIEULKIYEOK
+0xC09F	0xD562	#HANGUL SYLLABLE HIEUH A RIEULMIEUM
+0xC0A0	0xD563	#HANGUL SYLLABLE HIEUH A RIEULPIEUP
+0xC0A1	0xC6E9	#HANGUL SYLLABLE IEUNG WE KIYEOK
+0xC0A2	0xC6EC	#HANGUL SYLLABLE IEUNG WE NIEUN
+0xC0A3	0xC6F0	#HANGUL SYLLABLE IEUNG WE RIEUL
+0xC0A4	0xC6F8	#HANGUL SYLLABLE IEUNG WE MIEUM
+0xC0A5	0xC6F9	#HANGUL SYLLABLE IEUNG WE PIEUP
+0xC0A6	0xC6FD	#HANGUL SYLLABLE IEUNG WE IEUNG
+0xC0A7	0xC704	#HANGUL SYLLABLE IEUNG WI
+0xC0A8	0xC705	#HANGUL SYLLABLE IEUNG WI KIYEOK
+0xC0A9	0xC708	#HANGUL SYLLABLE IEUNG WI NIEUN
+0xC0AA	0xC70C	#HANGUL SYLLABLE IEUNG WI RIEUL
+0xC0AB	0xC714	#HANGUL SYLLABLE IEUNG WI MIEUM
+0xC0AC	0xC715	#HANGUL SYLLABLE IEUNG WI PIEUP
+0xC0AD	0xC717	#HANGUL SYLLABLE IEUNG WI SIOS
+0xC0AE	0xC719	#HANGUL SYLLABLE IEUNG WI IEUNG
+0xC0AF	0xC720	#HANGUL SYLLABLE IEUNG YU
+0xC0B0	0xC721	#HANGUL SYLLABLE IEUNG YU KIYEOK
+0xC0B1	0xC724	#HANGUL SYLLABLE IEUNG YU NIEUN
+0xC0B2	0xC728	#HANGUL SYLLABLE IEUNG YU RIEUL
+0xC0B3	0xC730	#HANGUL SYLLABLE IEUNG YU MIEUM
+0xC0B4	0xC731	#HANGUL SYLLABLE IEUNG YU PIEUP
+0xC0B5	0xC733	#HANGUL SYLLABLE IEUNG YU SIOS
+0xC0B6	0xC735	#HANGUL SYLLABLE IEUNG YU IEUNG
+0xC0B7	0xC737	#HANGUL SYLLABLE IEUNG YU CHIEUCH
+0xC0B8	0xC73C	#HANGUL SYLLABLE IEUNG EU
+0xC0B9	0xC73D	#HANGUL SYLLABLE IEUNG EU KIYEOK
+0xC0BA	0xC740	#HANGUL SYLLABLE IEUNG EU NIEUN
+0xC0BB	0xC744	#HANGUL SYLLABLE IEUNG EU RIEUL
+0xC0BC	0xC74A	#HANGUL SYLLABLE IEUNG EU RIEULPHIEUPH
+0xC0BD	0xC74C	#HANGUL SYLLABLE IEUNG EU MIEUM
+0xC0BE	0xC74D	#HANGUL SYLLABLE IEUNG EU PIEUP
+0xC0BF	0xC74F	#HANGUL SYLLABLE IEUNG EU SIOS
+0xC0C0	0xC751	#HANGUL SYLLABLE IEUNG EU IEUNG
+0xC0C1	0xC752	#HANGUL SYLLABLE IEUNG EU CIEUC
+0xC0C2	0xC753	#HANGUL SYLLABLE IEUNG EU CHIEUCH
+0xC0C3	0xC754	#HANGUL SYLLABLE IEUNG EU KHIEUKH
+0xC0C4	0xC755	#HANGUL SYLLABLE IEUNG EU THIEUTH
+0xC0C5	0xC756	#HANGUL SYLLABLE IEUNG EU PHIEUPH
+0xC0C6	0xC757	#HANGUL SYLLABLE IEUNG EU HIEUH
+0xC0C7	0xC758	#HANGUL SYLLABLE IEUNG YI
+0xC0C8	0xC75C	#HANGUL SYLLABLE IEUNG YI NIEUN
+0xC0C9	0xC760	#HANGUL SYLLABLE IEUNG YI RIEUL
+0xC0CA	0xC768	#HANGUL SYLLABLE IEUNG YI MIEUM
+0xC0CB	0xC76B	#HANGUL SYLLABLE IEUNG YI SIOS
+0xC0CC	0xC774	#HANGUL SYLLABLE IEUNG I
+0xC0CD	0xC775	#HANGUL SYLLABLE IEUNG I KIYEOK
+0xC0CE	0xC778	#HANGUL SYLLABLE IEUNG I NIEUN
+0xC0CF	0xC77C	#HANGUL SYLLABLE IEUNG I RIEUL
+0xC0D0	0xC77D	#HANGUL SYLLABLE IEUNG I RIEULKIYEOK
+0xC0D1	0xC77E	#HANGUL SYLLABLE IEUNG I RIEULMIEUM
+0xC0D2	0xC783	#HANGUL SYLLABLE IEUNG I RIEULHIEUH
+0xC0D3	0xC784	#HANGUL SYLLABLE IEUNG I MIEUM
+0xC0D4	0xC785	#HANGUL SYLLABLE IEUNG I PIEUP
+0xC0D5	0xC787	#HANGUL SYLLABLE IEUNG I SIOS
+0xC0D6	0xC788	#HANGUL SYLLABLE IEUNG I SSANGSIOS
+0xC0D7	0xC789	#HANGUL SYLLABLE IEUNG I IEUNG
+0xC0D8	0xC78A	#HANGUL SYLLABLE IEUNG I CIEUC
+0xC0D9	0xC78E	#HANGUL SYLLABLE IEUNG I PHIEUPH
+0xC0DA	0xC790	#HANGUL SYLLABLE CIEUC A
+0xC0DB	0xC791	#HANGUL SYLLABLE CIEUC A KIYEOK
+0xC0DC	0xC794	#HANGUL SYLLABLE CIEUC A NIEUN
+0xC0DD	0xC796	#HANGUL SYLLABLE CIEUC A NIEUNHIEUH
+0xC0DE	0xC797	#HANGUL SYLLABLE CIEUC A TIKEUT
+0xC0DF	0xC798	#HANGUL SYLLABLE CIEUC A RIEUL
+0xC0E0	0xC79A	#HANGUL SYLLABLE CIEUC A RIEULMIEUM
+0xC0E1	0xC7A0	#HANGUL SYLLABLE CIEUC A MIEUM
+0xC0E2	0xC7A1	#HANGUL SYLLABLE CIEUC A PIEUP
+0xC0E3	0xC7A3	#HANGUL SYLLABLE CIEUC A SIOS
+0xC0E4	0xC7A4	#HANGUL SYLLABLE CIEUC A SSANGSIOS
+0xC0E5	0xC7A5	#HANGUL SYLLABLE CIEUC A IEUNG
+0xC0E6	0xC7A6	#HANGUL SYLLABLE CIEUC A CIEUC
+0xC0E7	0xC7AC	#HANGUL SYLLABLE CIEUC AE
+0xC0E8	0xC7AD	#HANGUL SYLLABLE CIEUC AE KIYEOK
+0xC0E9	0xC7B0	#HANGUL SYLLABLE CIEUC AE NIEUN
+0xC0EA	0xC7B4	#HANGUL SYLLABLE CIEUC AE RIEUL
+0xC0EB	0xC7BC	#HANGUL SYLLABLE CIEUC AE MIEUM
+0xC0EC	0xC7BD	#HANGUL SYLLABLE CIEUC AE PIEUP
+0xC0ED	0xC7BF	#HANGUL SYLLABLE CIEUC AE SIOS
+0xC0EE	0xC7C0	#HANGUL SYLLABLE CIEUC AE SSANGSIOS
+0xC0EF	0xC7C1	#HANGUL SYLLABLE CIEUC AE IEUNG
+0xC0F0	0xC7C8	#HANGUL SYLLABLE CIEUC YA
+0xC0F1	0xC7C9	#HANGUL SYLLABLE CIEUC YA KIYEOK
+0xC0F2	0xC7CC	#HANGUL SYLLABLE CIEUC YA NIEUN
+0xC0F3	0xC7CE	#HANGUL SYLLABLE CIEUC YA NIEUNHIEUH
+0xC0F4	0xC7D0	#HANGUL SYLLABLE CIEUC YA RIEUL
+0xC0F5	0xC7D8	#HANGUL SYLLABLE CIEUC YA MIEUM
+0xC0F6	0xC7DD	#HANGUL SYLLABLE CIEUC YA IEUNG
+0xC0F7	0xC7E4	#HANGUL SYLLABLE CIEUC YAE
+0xC0F8	0xC7E8	#HANGUL SYLLABLE CIEUC YAE NIEUN
+0xC0F9	0xC7EC	#HANGUL SYLLABLE CIEUC YAE RIEUL
+0xC0FA	0xC800	#HANGUL SYLLABLE CIEUC EO
+0xC0FB	0xC801	#HANGUL SYLLABLE CIEUC EO KIYEOK
+0xC0FC	0xC804	#HANGUL SYLLABLE CIEUC EO NIEUN
+0xC0FD	0xC808	#HANGUL SYLLABLE CIEUC EO RIEUL
+0xC0FE	0xC80A	#HANGUL SYLLABLE CIEUC EO RIEULMIEUM
+0xC141	0xD564	#HANGUL SYLLABLE HIEUH A RIEULSIOS
+0xC142	0xD566	#HANGUL SYLLABLE HIEUH A RIEULPHIEUPH
+0xC143	0xD567	#HANGUL SYLLABLE HIEUH A RIEULHIEUH
+0xC144	0xD56A	#HANGUL SYLLABLE HIEUH A PIEUPSIOS
+0xC145	0xD56C	#HANGUL SYLLABLE HIEUH A SSANGSIOS
+0xC146	0xD56E	#HANGUL SYLLABLE HIEUH A CIEUC
+0xC147	0xD56F	#HANGUL SYLLABLE HIEUH A CHIEUCH
+0xC148	0xD570	#HANGUL SYLLABLE HIEUH A KHIEUKH
+0xC149	0xD571	#HANGUL SYLLABLE HIEUH A THIEUTH
+0xC14A	0xD572	#HANGUL SYLLABLE HIEUH A PHIEUPH
+0xC14B	0xD573	#HANGUL SYLLABLE HIEUH A HIEUH
+0xC14C	0xD576	#HANGUL SYLLABLE HIEUH AE SSANGKIYEOK
+0xC14D	0xD577	#HANGUL SYLLABLE HIEUH AE KIYEOKSIOS
+0xC14E	0xD579	#HANGUL SYLLABLE HIEUH AE NIEUNCIEUC
+0xC14F	0xD57A	#HANGUL SYLLABLE HIEUH AE NIEUNHIEUH
+0xC150	0xD57B	#HANGUL SYLLABLE HIEUH AE TIKEUT
+0xC151	0xD57D	#HANGUL SYLLABLE HIEUH AE RIEULKIYEOK
+0xC152	0xD57E	#HANGUL SYLLABLE HIEUH AE RIEULMIEUM
+0xC153	0xD57F	#HANGUL SYLLABLE HIEUH AE RIEULPIEUP
+0xC154	0xD580	#HANGUL SYLLABLE HIEUH AE RIEULSIOS
+0xC155	0xD581	#HANGUL SYLLABLE HIEUH AE RIEULTHIEUTH
+0xC156	0xD582	#HANGUL SYLLABLE HIEUH AE RIEULPHIEUPH
+0xC157	0xD583	#HANGUL SYLLABLE HIEUH AE RIEULHIEUH
+0xC158	0xD586	#HANGUL SYLLABLE HIEUH AE PIEUPSIOS
+0xC159	0xD58A	#HANGUL SYLLABLE HIEUH AE CIEUC
+0xC15A	0xD58B	#HANGUL SYLLABLE HIEUH AE CHIEUCH
+0xC161	0xD58C	#HANGUL SYLLABLE HIEUH AE KHIEUKH
+0xC162	0xD58D	#HANGUL SYLLABLE HIEUH AE THIEUTH
+0xC163	0xD58E	#HANGUL SYLLABLE HIEUH AE PHIEUPH
+0xC164	0xD58F	#HANGUL SYLLABLE HIEUH AE HIEUH
+0xC165	0xD591	#HANGUL SYLLABLE HIEUH YA KIYEOK
+0xC166	0xD592	#HANGUL SYLLABLE HIEUH YA SSANGKIYEOK
+0xC167	0xD593	#HANGUL SYLLABLE HIEUH YA KIYEOKSIOS
+0xC168	0xD594	#HANGUL SYLLABLE HIEUH YA NIEUN
+0xC169	0xD595	#HANGUL SYLLABLE HIEUH YA NIEUNCIEUC
+0xC16A	0xD596	#HANGUL SYLLABLE HIEUH YA NIEUNHIEUH
+0xC16B	0xD597	#HANGUL SYLLABLE HIEUH YA TIKEUT
+0xC16C	0xD598	#HANGUL SYLLABLE HIEUH YA RIEUL
+0xC16D	0xD599	#HANGUL SYLLABLE HIEUH YA RIEULKIYEOK
+0xC16E	0xD59A	#HANGUL SYLLABLE HIEUH YA RIEULMIEUM
+0xC16F	0xD59B	#HANGUL SYLLABLE HIEUH YA RIEULPIEUP
+0xC170	0xD59C	#HANGUL SYLLABLE HIEUH YA RIEULSIOS
+0xC171	0xD59D	#HANGUL SYLLABLE HIEUH YA RIEULTHIEUTH
+0xC172	0xD59E	#HANGUL SYLLABLE HIEUH YA RIEULPHIEUPH
+0xC173	0xD59F	#HANGUL SYLLABLE HIEUH YA RIEULHIEUH
+0xC174	0xD5A0	#HANGUL SYLLABLE HIEUH YA MIEUM
+0xC175	0xD5A1	#HANGUL SYLLABLE HIEUH YA PIEUP
+0xC176	0xD5A2	#HANGUL SYLLABLE HIEUH YA PIEUPSIOS
+0xC177	0xD5A3	#HANGUL SYLLABLE HIEUH YA SIOS
+0xC178	0xD5A4	#HANGUL SYLLABLE HIEUH YA SSANGSIOS
+0xC179	0xD5A6	#HANGUL SYLLABLE HIEUH YA CIEUC
+0xC17A	0xD5A7	#HANGUL SYLLABLE HIEUH YA CHIEUCH
+0xC181	0xD5A8	#HANGUL SYLLABLE HIEUH YA KHIEUKH
+0xC182	0xD5A9	#HANGUL SYLLABLE HIEUH YA THIEUTH
+0xC183	0xD5AA	#HANGUL SYLLABLE HIEUH YA PHIEUPH
+0xC184	0xD5AB	#HANGUL SYLLABLE HIEUH YA HIEUH
+0xC185	0xD5AC	#HANGUL SYLLABLE HIEUH YAE
+0xC186	0xD5AD	#HANGUL SYLLABLE HIEUH YAE KIYEOK
+0xC187	0xD5AE	#HANGUL SYLLABLE HIEUH YAE SSANGKIYEOK
+0xC188	0xD5AF	#HANGUL SYLLABLE HIEUH YAE KIYEOKSIOS
+0xC189	0xD5B0	#HANGUL SYLLABLE HIEUH YAE NIEUN
+0xC18A	0xD5B1	#HANGUL SYLLABLE HIEUH YAE NIEUNCIEUC
+0xC18B	0xD5B2	#HANGUL SYLLABLE HIEUH YAE NIEUNHIEUH
+0xC18C	0xD5B3	#HANGUL SYLLABLE HIEUH YAE TIKEUT
+0xC18D	0xD5B4	#HANGUL SYLLABLE HIEUH YAE RIEUL
+0xC18E	0xD5B5	#HANGUL SYLLABLE HIEUH YAE RIEULKIYEOK
+0xC18F	0xD5B6	#HANGUL SYLLABLE HIEUH YAE RIEULMIEUM
+0xC190	0xD5B7	#HANGUL SYLLABLE HIEUH YAE RIEULPIEUP
+0xC191	0xD5B8	#HANGUL SYLLABLE HIEUH YAE RIEULSIOS
+0xC192	0xD5B9	#HANGUL SYLLABLE HIEUH YAE RIEULTHIEUTH
+0xC193	0xD5BA	#HANGUL SYLLABLE HIEUH YAE RIEULPHIEUPH
+0xC194	0xD5BB	#HANGUL SYLLABLE HIEUH YAE RIEULHIEUH
+0xC195	0xD5BC	#HANGUL SYLLABLE HIEUH YAE MIEUM
+0xC196	0xD5BD	#HANGUL SYLLABLE HIEUH YAE PIEUP
+0xC197	0xD5BE	#HANGUL SYLLABLE HIEUH YAE PIEUPSIOS
+0xC198	0xD5BF	#HANGUL SYLLABLE HIEUH YAE SIOS
+0xC199	0xD5C0	#HANGUL SYLLABLE HIEUH YAE SSANGSIOS
+0xC19A	0xD5C1	#HANGUL SYLLABLE HIEUH YAE IEUNG
+0xC19B	0xD5C2	#HANGUL SYLLABLE HIEUH YAE CIEUC
+0xC19C	0xD5C3	#HANGUL SYLLABLE HIEUH YAE CHIEUCH
+0xC19D	0xD5C4	#HANGUL SYLLABLE HIEUH YAE KHIEUKH
+0xC19E	0xD5C5	#HANGUL SYLLABLE HIEUH YAE THIEUTH
+0xC19F	0xD5C6	#HANGUL SYLLABLE HIEUH YAE PHIEUPH
+0xC1A0	0xD5C7	#HANGUL SYLLABLE HIEUH YAE HIEUH
+0xC1A1	0xC810	#HANGUL SYLLABLE CIEUC EO MIEUM
+0xC1A2	0xC811	#HANGUL SYLLABLE CIEUC EO PIEUP
+0xC1A3	0xC813	#HANGUL SYLLABLE CIEUC EO SIOS
+0xC1A4	0xC815	#HANGUL SYLLABLE CIEUC EO IEUNG
+0xC1A5	0xC816	#HANGUL SYLLABLE CIEUC EO CIEUC
+0xC1A6	0xC81C	#HANGUL SYLLABLE CIEUC E
+0xC1A7	0xC81D	#HANGUL SYLLABLE CIEUC E KIYEOK
+0xC1A8	0xC820	#HANGUL SYLLABLE CIEUC E NIEUN
+0xC1A9	0xC824	#HANGUL SYLLABLE CIEUC E RIEUL
+0xC1AA	0xC82C	#HANGUL SYLLABLE CIEUC E MIEUM
+0xC1AB	0xC82D	#HANGUL SYLLABLE CIEUC E PIEUP
+0xC1AC	0xC82F	#HANGUL SYLLABLE CIEUC E SIOS
+0xC1AD	0xC831	#HANGUL SYLLABLE CIEUC E IEUNG
+0xC1AE	0xC838	#HANGUL SYLLABLE CIEUC YEO
+0xC1AF	0xC83C	#HANGUL SYLLABLE CIEUC YEO NIEUN
+0xC1B0	0xC840	#HANGUL SYLLABLE CIEUC YEO RIEUL
+0xC1B1	0xC848	#HANGUL SYLLABLE CIEUC YEO MIEUM
+0xC1B2	0xC849	#HANGUL SYLLABLE CIEUC YEO PIEUP
+0xC1B3	0xC84C	#HANGUL SYLLABLE CIEUC YEO SSANGSIOS
+0xC1B4	0xC84D	#HANGUL SYLLABLE CIEUC YEO IEUNG
+0xC1B5	0xC854	#HANGUL SYLLABLE CIEUC YE
+0xC1B6	0xC870	#HANGUL SYLLABLE CIEUC O
+0xC1B7	0xC871	#HANGUL SYLLABLE CIEUC O KIYEOK
+0xC1B8	0xC874	#HANGUL SYLLABLE CIEUC O NIEUN
+0xC1B9	0xC878	#HANGUL SYLLABLE CIEUC O RIEUL
+0xC1BA	0xC87A	#HANGUL SYLLABLE CIEUC O RIEULMIEUM
+0xC1BB	0xC880	#HANGUL SYLLABLE CIEUC O MIEUM
+0xC1BC	0xC881	#HANGUL SYLLABLE CIEUC O PIEUP
+0xC1BD	0xC883	#HANGUL SYLLABLE CIEUC O SIOS
+0xC1BE	0xC885	#HANGUL SYLLABLE CIEUC O IEUNG
+0xC1BF	0xC886	#HANGUL SYLLABLE CIEUC O CIEUC
+0xC1C0	0xC887	#HANGUL SYLLABLE CIEUC O CHIEUCH
+0xC1C1	0xC88B	#HANGUL SYLLABLE CIEUC O HIEUH
+0xC1C2	0xC88C	#HANGUL SYLLABLE CIEUC WA
+0xC1C3	0xC88D	#HANGUL SYLLABLE CIEUC WA KIYEOK
+0xC1C4	0xC894	#HANGUL SYLLABLE CIEUC WA RIEUL
+0xC1C5	0xC89D	#HANGUL SYLLABLE CIEUC WA PIEUP
+0xC1C6	0xC89F	#HANGUL SYLLABLE CIEUC WA SIOS
+0xC1C7	0xC8A1	#HANGUL SYLLABLE CIEUC WA IEUNG
+0xC1C8	0xC8A8	#HANGUL SYLLABLE CIEUC WAE
+0xC1C9	0xC8BC	#HANGUL SYLLABLE CIEUC WAE SSANGSIOS
+0xC1CA	0xC8BD	#HANGUL SYLLABLE CIEUC WAE IEUNG
+0xC1CB	0xC8C4	#HANGUL SYLLABLE CIEUC OE
+0xC1CC	0xC8C8	#HANGUL SYLLABLE CIEUC OE NIEUN
+0xC1CD	0xC8CC	#HANGUL SYLLABLE CIEUC OE RIEUL
+0xC1CE	0xC8D4	#HANGUL SYLLABLE CIEUC OE MIEUM
+0xC1CF	0xC8D5	#HANGUL SYLLABLE CIEUC OE PIEUP
+0xC1D0	0xC8D7	#HANGUL SYLLABLE CIEUC OE SIOS
+0xC1D1	0xC8D9	#HANGUL SYLLABLE CIEUC OE IEUNG
+0xC1D2	0xC8E0	#HANGUL SYLLABLE CIEUC YO
+0xC1D3	0xC8E1	#HANGUL SYLLABLE CIEUC YO KIYEOK
+0xC1D4	0xC8E4	#HANGUL SYLLABLE CIEUC YO NIEUN
+0xC1D5	0xC8F5	#HANGUL SYLLABLE CIEUC YO IEUNG
+0xC1D6	0xC8FC	#HANGUL SYLLABLE CIEUC U
+0xC1D7	0xC8FD	#HANGUL SYLLABLE CIEUC U KIYEOK
+0xC1D8	0xC900	#HANGUL SYLLABLE CIEUC U NIEUN
+0xC1D9	0xC904	#HANGUL SYLLABLE CIEUC U RIEUL
+0xC1DA	0xC905	#HANGUL SYLLABLE CIEUC U RIEULKIYEOK
+0xC1DB	0xC906	#HANGUL SYLLABLE CIEUC U RIEULMIEUM
+0xC1DC	0xC90C	#HANGUL SYLLABLE CIEUC U MIEUM
+0xC1DD	0xC90D	#HANGUL SYLLABLE CIEUC U PIEUP
+0xC1DE	0xC90F	#HANGUL SYLLABLE CIEUC U SIOS
+0xC1DF	0xC911	#HANGUL SYLLABLE CIEUC U IEUNG
+0xC1E0	0xC918	#HANGUL SYLLABLE CIEUC WEO
+0xC1E1	0xC92C	#HANGUL SYLLABLE CIEUC WEO SSANGSIOS
+0xC1E2	0xC934	#HANGUL SYLLABLE CIEUC WE
+0xC1E3	0xC950	#HANGUL SYLLABLE CIEUC WI
+0xC1E4	0xC951	#HANGUL SYLLABLE CIEUC WI KIYEOK
+0xC1E5	0xC954	#HANGUL SYLLABLE CIEUC WI NIEUN
+0xC1E6	0xC958	#HANGUL SYLLABLE CIEUC WI RIEUL
+0xC1E7	0xC960	#HANGUL SYLLABLE CIEUC WI MIEUM
+0xC1E8	0xC961	#HANGUL SYLLABLE CIEUC WI PIEUP
+0xC1E9	0xC963	#HANGUL SYLLABLE CIEUC WI SIOS
+0xC1EA	0xC96C	#HANGUL SYLLABLE CIEUC YU
+0xC1EB	0xC970	#HANGUL SYLLABLE CIEUC YU NIEUN
+0xC1EC	0xC974	#HANGUL SYLLABLE CIEUC YU RIEUL
+0xC1ED	0xC97C	#HANGUL SYLLABLE CIEUC YU MIEUM
+0xC1EE	0xC988	#HANGUL SYLLABLE CIEUC EU
+0xC1EF	0xC989	#HANGUL SYLLABLE CIEUC EU KIYEOK
+0xC1F0	0xC98C	#HANGUL SYLLABLE CIEUC EU NIEUN
+0xC1F1	0xC990	#HANGUL SYLLABLE CIEUC EU RIEUL
+0xC1F2	0xC998	#HANGUL SYLLABLE CIEUC EU MIEUM
+0xC1F3	0xC999	#HANGUL SYLLABLE CIEUC EU PIEUP
+0xC1F4	0xC99B	#HANGUL SYLLABLE CIEUC EU SIOS
+0xC1F5	0xC99D	#HANGUL SYLLABLE CIEUC EU IEUNG
+0xC1F6	0xC9C0	#HANGUL SYLLABLE CIEUC I
+0xC1F7	0xC9C1	#HANGUL SYLLABLE CIEUC I KIYEOK
+0xC1F8	0xC9C4	#HANGUL SYLLABLE CIEUC I NIEUN
+0xC1F9	0xC9C7	#HANGUL SYLLABLE CIEUC I TIKEUT
+0xC1FA	0xC9C8	#HANGUL SYLLABLE CIEUC I RIEUL
+0xC1FB	0xC9CA	#HANGUL SYLLABLE CIEUC I RIEULMIEUM
+0xC1FC	0xC9D0	#HANGUL SYLLABLE CIEUC I MIEUM
+0xC1FD	0xC9D1	#HANGUL SYLLABLE CIEUC I PIEUP
+0xC1FE	0xC9D3	#HANGUL SYLLABLE CIEUC I SIOS
+0xC241	0xD5CA	#HANGUL SYLLABLE HIEUH EO SSANGKIYEOK
+0xC242	0xD5CB	#HANGUL SYLLABLE HIEUH EO KIYEOKSIOS
+0xC243	0xD5CD	#HANGUL SYLLABLE HIEUH EO NIEUNCIEUC
+0xC244	0xD5CE	#HANGUL SYLLABLE HIEUH EO NIEUNHIEUH
+0xC245	0xD5CF	#HANGUL SYLLABLE HIEUH EO TIKEUT
+0xC246	0xD5D1	#HANGUL SYLLABLE HIEUH EO RIEULKIYEOK
+0xC247	0xD5D3	#HANGUL SYLLABLE HIEUH EO RIEULPIEUP
+0xC248	0xD5D4	#HANGUL SYLLABLE HIEUH EO RIEULSIOS
+0xC249	0xD5D5	#HANGUL SYLLABLE HIEUH EO RIEULTHIEUTH
+0xC24A	0xD5D6	#HANGUL SYLLABLE HIEUH EO RIEULPHIEUPH
+0xC24B	0xD5D7	#HANGUL SYLLABLE HIEUH EO RIEULHIEUH
+0xC24C	0xD5DA	#HANGUL SYLLABLE HIEUH EO PIEUPSIOS
+0xC24D	0xD5DC	#HANGUL SYLLABLE HIEUH EO SSANGSIOS
+0xC24E	0xD5DE	#HANGUL SYLLABLE HIEUH EO CIEUC
+0xC24F	0xD5DF	#HANGUL SYLLABLE HIEUH EO CHIEUCH
+0xC250	0xD5E0	#HANGUL SYLLABLE HIEUH EO KHIEUKH
+0xC251	0xD5E1	#HANGUL SYLLABLE HIEUH EO THIEUTH
+0xC252	0xD5E2	#HANGUL SYLLABLE HIEUH EO PHIEUPH
+0xC253	0xD5E3	#HANGUL SYLLABLE HIEUH EO HIEUH
+0xC254	0xD5E6	#HANGUL SYLLABLE HIEUH E SSANGKIYEOK
+0xC255	0xD5E7	#HANGUL SYLLABLE HIEUH E KIYEOKSIOS
+0xC256	0xD5E9	#HANGUL SYLLABLE HIEUH E NIEUNCIEUC
+0xC257	0xD5EA	#HANGUL SYLLABLE HIEUH E NIEUNHIEUH
+0xC258	0xD5EB	#HANGUL SYLLABLE HIEUH E TIKEUT
+0xC259	0xD5ED	#HANGUL SYLLABLE HIEUH E RIEULKIYEOK
+0xC25A	0xD5EE	#HANGUL SYLLABLE HIEUH E RIEULMIEUM
+0xC261	0xD5EF	#HANGUL SYLLABLE HIEUH E RIEULPIEUP
+0xC262	0xD5F0	#HANGUL SYLLABLE HIEUH E RIEULSIOS
+0xC263	0xD5F1	#HANGUL SYLLABLE HIEUH E RIEULTHIEUTH
+0xC264	0xD5F2	#HANGUL SYLLABLE HIEUH E RIEULPHIEUPH
+0xC265	0xD5F3	#HANGUL SYLLABLE HIEUH E RIEULHIEUH
+0xC266	0xD5F6	#HANGUL SYLLABLE HIEUH E PIEUPSIOS
+0xC267	0xD5F8	#HANGUL SYLLABLE HIEUH E SSANGSIOS
+0xC268	0xD5FA	#HANGUL SYLLABLE HIEUH E CIEUC
+0xC269	0xD5FB	#HANGUL SYLLABLE HIEUH E CHIEUCH
+0xC26A	0xD5FC	#HANGUL SYLLABLE HIEUH E KHIEUKH
+0xC26B	0xD5FD	#HANGUL SYLLABLE HIEUH E THIEUTH
+0xC26C	0xD5FE	#HANGUL SYLLABLE HIEUH E PHIEUPH
+0xC26D	0xD5FF	#HANGUL SYLLABLE HIEUH E HIEUH
+0xC26E	0xD602	#HANGUL SYLLABLE HIEUH YEO SSANGKIYEOK
+0xC26F	0xD603	#HANGUL SYLLABLE HIEUH YEO KIYEOKSIOS
+0xC270	0xD605	#HANGUL SYLLABLE HIEUH YEO NIEUNCIEUC
+0xC271	0xD606	#HANGUL SYLLABLE HIEUH YEO NIEUNHIEUH
+0xC272	0xD607	#HANGUL SYLLABLE HIEUH YEO TIKEUT
+0xC273	0xD609	#HANGUL SYLLABLE HIEUH YEO RIEULKIYEOK
+0xC274	0xD60A	#HANGUL SYLLABLE HIEUH YEO RIEULMIEUM
+0xC275	0xD60B	#HANGUL SYLLABLE HIEUH YEO RIEULPIEUP
+0xC276	0xD60C	#HANGUL SYLLABLE HIEUH YEO RIEULSIOS
+0xC277	0xD60D	#HANGUL SYLLABLE HIEUH YEO RIEULTHIEUTH
+0xC278	0xD60E	#HANGUL SYLLABLE HIEUH YEO RIEULPHIEUPH
+0xC279	0xD60F	#HANGUL SYLLABLE HIEUH YEO RIEULHIEUH
+0xC27A	0xD612	#HANGUL SYLLABLE HIEUH YEO PIEUPSIOS
+0xC281	0xD616	#HANGUL SYLLABLE HIEUH YEO CIEUC
+0xC282	0xD617	#HANGUL SYLLABLE HIEUH YEO CHIEUCH
+0xC283	0xD618	#HANGUL SYLLABLE HIEUH YEO KHIEUKH
+0xC284	0xD619	#HANGUL SYLLABLE HIEUH YEO THIEUTH
+0xC285	0xD61A	#HANGUL SYLLABLE HIEUH YEO PHIEUPH
+0xC286	0xD61B	#HANGUL SYLLABLE HIEUH YEO HIEUH
+0xC287	0xD61D	#HANGUL SYLLABLE HIEUH YE KIYEOK
+0xC288	0xD61E	#HANGUL SYLLABLE HIEUH YE SSANGKIYEOK
+0xC289	0xD61F	#HANGUL SYLLABLE HIEUH YE KIYEOKSIOS
+0xC28A	0xD621	#HANGUL SYLLABLE HIEUH YE NIEUNCIEUC
+0xC28B	0xD622	#HANGUL SYLLABLE HIEUH YE NIEUNHIEUH
+0xC28C	0xD623	#HANGUL SYLLABLE HIEUH YE TIKEUT
+0xC28D	0xD625	#HANGUL SYLLABLE HIEUH YE RIEULKIYEOK
+0xC28E	0xD626	#HANGUL SYLLABLE HIEUH YE RIEULMIEUM
+0xC28F	0xD627	#HANGUL SYLLABLE HIEUH YE RIEULPIEUP
+0xC290	0xD628	#HANGUL SYLLABLE HIEUH YE RIEULSIOS
+0xC291	0xD629	#HANGUL SYLLABLE HIEUH YE RIEULTHIEUTH
+0xC292	0xD62A	#HANGUL SYLLABLE HIEUH YE RIEULPHIEUPH
+0xC293	0xD62B	#HANGUL SYLLABLE HIEUH YE RIEULHIEUH
+0xC294	0xD62C	#HANGUL SYLLABLE HIEUH YE MIEUM
+0xC295	0xD62E	#HANGUL SYLLABLE HIEUH YE PIEUPSIOS
+0xC296	0xD62F	#HANGUL SYLLABLE HIEUH YE SIOS
+0xC297	0xD630	#HANGUL SYLLABLE HIEUH YE SSANGSIOS
+0xC298	0xD631	#HANGUL SYLLABLE HIEUH YE IEUNG
+0xC299	0xD632	#HANGUL SYLLABLE HIEUH YE CIEUC
+0xC29A	0xD633	#HANGUL SYLLABLE HIEUH YE CHIEUCH
+0xC29B	0xD634	#HANGUL SYLLABLE HIEUH YE KHIEUKH
+0xC29C	0xD635	#HANGUL SYLLABLE HIEUH YE THIEUTH
+0xC29D	0xD636	#HANGUL SYLLABLE HIEUH YE PHIEUPH
+0xC29E	0xD637	#HANGUL SYLLABLE HIEUH YE HIEUH
+0xC29F	0xD63A	#HANGUL SYLLABLE HIEUH O SSANGKIYEOK
+0xC2A0	0xD63B	#HANGUL SYLLABLE HIEUH O KIYEOKSIOS
+0xC2A1	0xC9D5	#HANGUL SYLLABLE CIEUC I IEUNG
+0xC2A2	0xC9D6	#HANGUL SYLLABLE CIEUC I CIEUC
+0xC2A3	0xC9D9	#HANGUL SYLLABLE CIEUC I THIEUTH
+0xC2A4	0xC9DA	#HANGUL SYLLABLE CIEUC I PHIEUPH
+0xC2A5	0xC9DC	#HANGUL SYLLABLE SSANGCIEUC A
+0xC2A6	0xC9DD	#HANGUL SYLLABLE SSANGCIEUC A KIYEOK
+0xC2A7	0xC9E0	#HANGUL SYLLABLE SSANGCIEUC A NIEUN
+0xC2A8	0xC9E2	#HANGUL SYLLABLE SSANGCIEUC A NIEUNHIEUH
+0xC2A9	0xC9E4	#HANGUL SYLLABLE SSANGCIEUC A RIEUL
+0xC2AA	0xC9E7	#HANGUL SYLLABLE SSANGCIEUC A RIEULPIEUP
+0xC2AB	0xC9EC	#HANGUL SYLLABLE SSANGCIEUC A MIEUM
+0xC2AC	0xC9ED	#HANGUL SYLLABLE SSANGCIEUC A PIEUP
+0xC2AD	0xC9EF	#HANGUL SYLLABLE SSANGCIEUC A SIOS
+0xC2AE	0xC9F0	#HANGUL SYLLABLE SSANGCIEUC A SSANGSIOS
+0xC2AF	0xC9F1	#HANGUL SYLLABLE SSANGCIEUC A IEUNG
+0xC2B0	0xC9F8	#HANGUL SYLLABLE SSANGCIEUC AE
+0xC2B1	0xC9F9	#HANGUL SYLLABLE SSANGCIEUC AE KIYEOK
+0xC2B2	0xC9FC	#HANGUL SYLLABLE SSANGCIEUC AE NIEUN
+0xC2B3	0xCA00	#HANGUL SYLLABLE SSANGCIEUC AE RIEUL
+0xC2B4	0xCA08	#HANGUL SYLLABLE SSANGCIEUC AE MIEUM
+0xC2B5	0xCA09	#HANGUL SYLLABLE SSANGCIEUC AE PIEUP
+0xC2B6	0xCA0B	#HANGUL SYLLABLE SSANGCIEUC AE SIOS
+0xC2B7	0xCA0C	#HANGUL SYLLABLE SSANGCIEUC AE SSANGSIOS
+0xC2B8	0xCA0D	#HANGUL SYLLABLE SSANGCIEUC AE IEUNG
+0xC2B9	0xCA14	#HANGUL SYLLABLE SSANGCIEUC YA
+0xC2BA	0xCA18	#HANGUL SYLLABLE SSANGCIEUC YA NIEUN
+0xC2BB	0xCA29	#HANGUL SYLLABLE SSANGCIEUC YA IEUNG
+0xC2BC	0xCA4C	#HANGUL SYLLABLE SSANGCIEUC EO
+0xC2BD	0xCA4D	#HANGUL SYLLABLE SSANGCIEUC EO KIYEOK
+0xC2BE	0xCA50	#HANGUL SYLLABLE SSANGCIEUC EO NIEUN
+0xC2BF	0xCA54	#HANGUL SYLLABLE SSANGCIEUC EO RIEUL
+0xC2C0	0xCA5C	#HANGUL SYLLABLE SSANGCIEUC EO MIEUM
+0xC2C1	0xCA5D	#HANGUL SYLLABLE SSANGCIEUC EO PIEUP
+0xC2C2	0xCA5F	#HANGUL SYLLABLE SSANGCIEUC EO SIOS
+0xC2C3	0xCA60	#HANGUL SYLLABLE SSANGCIEUC EO SSANGSIOS
+0xC2C4	0xCA61	#HANGUL SYLLABLE SSANGCIEUC EO IEUNG
+0xC2C5	0xCA68	#HANGUL SYLLABLE SSANGCIEUC E
+0xC2C6	0xCA7D	#HANGUL SYLLABLE SSANGCIEUC E IEUNG
+0xC2C7	0xCA84	#HANGUL SYLLABLE SSANGCIEUC YEO
+0xC2C8	0xCA98	#HANGUL SYLLABLE SSANGCIEUC YEO SSANGSIOS
+0xC2C9	0xCABC	#HANGUL SYLLABLE SSANGCIEUC O
+0xC2CA	0xCABD	#HANGUL SYLLABLE SSANGCIEUC O KIYEOK
+0xC2CB	0xCAC0	#HANGUL SYLLABLE SSANGCIEUC O NIEUN
+0xC2CC	0xCAC4	#HANGUL SYLLABLE SSANGCIEUC O RIEUL
+0xC2CD	0xCACC	#HANGUL SYLLABLE SSANGCIEUC O MIEUM
+0xC2CE	0xCACD	#HANGUL SYLLABLE SSANGCIEUC O PIEUP
+0xC2CF	0xCACF	#HANGUL SYLLABLE SSANGCIEUC O SIOS
+0xC2D0	0xCAD1	#HANGUL SYLLABLE SSANGCIEUC O IEUNG
+0xC2D1	0xCAD3	#HANGUL SYLLABLE SSANGCIEUC O CHIEUCH
+0xC2D2	0xCAD8	#HANGUL SYLLABLE SSANGCIEUC WA
+0xC2D3	0xCAD9	#HANGUL SYLLABLE SSANGCIEUC WA KIYEOK
+0xC2D4	0xCAE0	#HANGUL SYLLABLE SSANGCIEUC WA RIEUL
+0xC2D5	0xCAEC	#HANGUL SYLLABLE SSANGCIEUC WA SSANGSIOS
+0xC2D6	0xCAF4	#HANGUL SYLLABLE SSANGCIEUC WAE
+0xC2D7	0xCB08	#HANGUL SYLLABLE SSANGCIEUC WAE SSANGSIOS
+0xC2D8	0xCB10	#HANGUL SYLLABLE SSANGCIEUC OE
+0xC2D9	0xCB14	#HANGUL SYLLABLE SSANGCIEUC OE NIEUN
+0xC2DA	0xCB18	#HANGUL SYLLABLE SSANGCIEUC OE RIEUL
+0xC2DB	0xCB20	#HANGUL SYLLABLE SSANGCIEUC OE MIEUM
+0xC2DC	0xCB21	#HANGUL SYLLABLE SSANGCIEUC OE PIEUP
+0xC2DD	0xCB41	#HANGUL SYLLABLE SSANGCIEUC YO IEUNG
+0xC2DE	0xCB48	#HANGUL SYLLABLE SSANGCIEUC U
+0xC2DF	0xCB49	#HANGUL SYLLABLE SSANGCIEUC U KIYEOK
+0xC2E0	0xCB4C	#HANGUL SYLLABLE SSANGCIEUC U NIEUN
+0xC2E1	0xCB50	#HANGUL SYLLABLE SSANGCIEUC U RIEUL
+0xC2E2	0xCB58	#HANGUL SYLLABLE SSANGCIEUC U MIEUM
+0xC2E3	0xCB59	#HANGUL SYLLABLE SSANGCIEUC U PIEUP
+0xC2E4	0xCB5D	#HANGUL SYLLABLE SSANGCIEUC U IEUNG
+0xC2E5	0xCB64	#HANGUL SYLLABLE SSANGCIEUC WEO
+0xC2E6	0xCB78	#HANGUL SYLLABLE SSANGCIEUC WEO SSANGSIOS
+0xC2E7	0xCB79	#HANGUL SYLLABLE SSANGCIEUC WEO IEUNG
+0xC2E8	0xCB9C	#HANGUL SYLLABLE SSANGCIEUC WI
+0xC2E9	0xCBB8	#HANGUL SYLLABLE SSANGCIEUC YU
+0xC2EA	0xCBD4	#HANGUL SYLLABLE SSANGCIEUC EU
+0xC2EB	0xCBE4	#HANGUL SYLLABLE SSANGCIEUC EU MIEUM
+0xC2EC	0xCBE7	#HANGUL SYLLABLE SSANGCIEUC EU SIOS
+0xC2ED	0xCBE9	#HANGUL SYLLABLE SSANGCIEUC EU IEUNG
+0xC2EE	0xCC0C	#HANGUL SYLLABLE SSANGCIEUC I
+0xC2EF	0xCC0D	#HANGUL SYLLABLE SSANGCIEUC I KIYEOK
+0xC2F0	0xCC10	#HANGUL SYLLABLE SSANGCIEUC I NIEUN
+0xC2F1	0xCC14	#HANGUL SYLLABLE SSANGCIEUC I RIEUL
+0xC2F2	0xCC1C	#HANGUL SYLLABLE SSANGCIEUC I MIEUM
+0xC2F3	0xCC1D	#HANGUL SYLLABLE SSANGCIEUC I PIEUP
+0xC2F4	0xCC21	#HANGUL SYLLABLE SSANGCIEUC I IEUNG
+0xC2F5	0xCC22	#HANGUL SYLLABLE SSANGCIEUC I CIEUC
+0xC2F6	0xCC27	#HANGUL SYLLABLE SSANGCIEUC I HIEUH
+0xC2F7	0xCC28	#HANGUL SYLLABLE CHIEUCH A
+0xC2F8	0xCC29	#HANGUL SYLLABLE CHIEUCH A KIYEOK
+0xC2F9	0xCC2C	#HANGUL SYLLABLE CHIEUCH A NIEUN
+0xC2FA	0xCC2E	#HANGUL SYLLABLE CHIEUCH A NIEUNHIEUH
+0xC2FB	0xCC30	#HANGUL SYLLABLE CHIEUCH A RIEUL
+0xC2FC	0xCC38	#HANGUL SYLLABLE CHIEUCH A MIEUM
+0xC2FD	0xCC39	#HANGUL SYLLABLE CHIEUCH A PIEUP
+0xC2FE	0xCC3B	#HANGUL SYLLABLE CHIEUCH A SIOS
+0xC341	0xD63D	#HANGUL SYLLABLE HIEUH O NIEUNCIEUC
+0xC342	0xD63E	#HANGUL SYLLABLE HIEUH O NIEUNHIEUH
+0xC343	0xD63F	#HANGUL SYLLABLE HIEUH O TIKEUT
+0xC344	0xD641	#HANGUL SYLLABLE HIEUH O RIEULKIYEOK
+0xC345	0xD642	#HANGUL SYLLABLE HIEUH O RIEULMIEUM
+0xC346	0xD643	#HANGUL SYLLABLE HIEUH O RIEULPIEUP
+0xC347	0xD644	#HANGUL SYLLABLE HIEUH O RIEULSIOS
+0xC348	0xD646	#HANGUL SYLLABLE HIEUH O RIEULPHIEUPH
+0xC349	0xD647	#HANGUL SYLLABLE HIEUH O RIEULHIEUH
+0xC34A	0xD64A	#HANGUL SYLLABLE HIEUH O PIEUPSIOS
+0xC34B	0xD64C	#HANGUL SYLLABLE HIEUH O SSANGSIOS
+0xC34C	0xD64E	#HANGUL SYLLABLE HIEUH O CIEUC
+0xC34D	0xD64F	#HANGUL SYLLABLE HIEUH O CHIEUCH
+0xC34E	0xD650	#HANGUL SYLLABLE HIEUH O KHIEUKH
+0xC34F	0xD652	#HANGUL SYLLABLE HIEUH O PHIEUPH
+0xC350	0xD653	#HANGUL SYLLABLE HIEUH O HIEUH
+0xC351	0xD656	#HANGUL SYLLABLE HIEUH WA SSANGKIYEOK
+0xC352	0xD657	#HANGUL SYLLABLE HIEUH WA KIYEOKSIOS
+0xC353	0xD659	#HANGUL SYLLABLE HIEUH WA NIEUNCIEUC
+0xC354	0xD65A	#HANGUL SYLLABLE HIEUH WA NIEUNHIEUH
+0xC355	0xD65B	#HANGUL SYLLABLE HIEUH WA TIKEUT
+0xC356	0xD65D	#HANGUL SYLLABLE HIEUH WA RIEULKIYEOK
+0xC357	0xD65E	#HANGUL SYLLABLE HIEUH WA RIEULMIEUM
+0xC358	0xD65F	#HANGUL SYLLABLE HIEUH WA RIEULPIEUP
+0xC359	0xD660	#HANGUL SYLLABLE HIEUH WA RIEULSIOS
+0xC35A	0xD661	#HANGUL SYLLABLE HIEUH WA RIEULTHIEUTH
+0xC361	0xD662	#HANGUL SYLLABLE HIEUH WA RIEULPHIEUPH
+0xC362	0xD663	#HANGUL SYLLABLE HIEUH WA RIEULHIEUH
+0xC363	0xD664	#HANGUL SYLLABLE HIEUH WA MIEUM
+0xC364	0xD665	#HANGUL SYLLABLE HIEUH WA PIEUP
+0xC365	0xD666	#HANGUL SYLLABLE HIEUH WA PIEUPSIOS
+0xC366	0xD668	#HANGUL SYLLABLE HIEUH WA SSANGSIOS
+0xC367	0xD66A	#HANGUL SYLLABLE HIEUH WA CIEUC
+0xC368	0xD66B	#HANGUL SYLLABLE HIEUH WA CHIEUCH
+0xC369	0xD66C	#HANGUL SYLLABLE HIEUH WA KHIEUKH
+0xC36A	0xD66D	#HANGUL SYLLABLE HIEUH WA THIEUTH
+0xC36B	0xD66E	#HANGUL SYLLABLE HIEUH WA PHIEUPH
+0xC36C	0xD66F	#HANGUL SYLLABLE HIEUH WA HIEUH
+0xC36D	0xD672	#HANGUL SYLLABLE HIEUH WAE SSANGKIYEOK
+0xC36E	0xD673	#HANGUL SYLLABLE HIEUH WAE KIYEOKSIOS
+0xC36F	0xD675	#HANGUL SYLLABLE HIEUH WAE NIEUNCIEUC
+0xC370	0xD676	#HANGUL SYLLABLE HIEUH WAE NIEUNHIEUH
+0xC371	0xD677	#HANGUL SYLLABLE HIEUH WAE TIKEUT
+0xC372	0xD678	#HANGUL SYLLABLE HIEUH WAE RIEUL
+0xC373	0xD679	#HANGUL SYLLABLE HIEUH WAE RIEULKIYEOK
+0xC374	0xD67A	#HANGUL SYLLABLE HIEUH WAE RIEULMIEUM
+0xC375	0xD67B	#HANGUL SYLLABLE HIEUH WAE RIEULPIEUP
+0xC376	0xD67C	#HANGUL SYLLABLE HIEUH WAE RIEULSIOS
+0xC377	0xD67D	#HANGUL SYLLABLE HIEUH WAE RIEULTHIEUTH
+0xC378	0xD67E	#HANGUL SYLLABLE HIEUH WAE RIEULPHIEUPH
+0xC379	0xD67F	#HANGUL SYLLABLE HIEUH WAE RIEULHIEUH
+0xC37A	0xD680	#HANGUL SYLLABLE HIEUH WAE MIEUM
+0xC381	0xD681	#HANGUL SYLLABLE HIEUH WAE PIEUP
+0xC382	0xD682	#HANGUL SYLLABLE HIEUH WAE PIEUPSIOS
+0xC383	0xD684	#HANGUL SYLLABLE HIEUH WAE SSANGSIOS
+0xC384	0xD686	#HANGUL SYLLABLE HIEUH WAE CIEUC
+0xC385	0xD687	#HANGUL SYLLABLE HIEUH WAE CHIEUCH
+0xC386	0xD688	#HANGUL SYLLABLE HIEUH WAE KHIEUKH
+0xC387	0xD689	#HANGUL SYLLABLE HIEUH WAE THIEUTH
+0xC388	0xD68A	#HANGUL SYLLABLE HIEUH WAE PHIEUPH
+0xC389	0xD68B	#HANGUL SYLLABLE HIEUH WAE HIEUH
+0xC38A	0xD68E	#HANGUL SYLLABLE HIEUH OE SSANGKIYEOK
+0xC38B	0xD68F	#HANGUL SYLLABLE HIEUH OE KIYEOKSIOS
+0xC38C	0xD691	#HANGUL SYLLABLE HIEUH OE NIEUNCIEUC
+0xC38D	0xD692	#HANGUL SYLLABLE HIEUH OE NIEUNHIEUH
+0xC38E	0xD693	#HANGUL SYLLABLE HIEUH OE TIKEUT
+0xC38F	0xD695	#HANGUL SYLLABLE HIEUH OE RIEULKIYEOK
+0xC390	0xD696	#HANGUL SYLLABLE HIEUH OE RIEULMIEUM
+0xC391	0xD697	#HANGUL SYLLABLE HIEUH OE RIEULPIEUP
+0xC392	0xD698	#HANGUL SYLLABLE HIEUH OE RIEULSIOS
+0xC393	0xD699	#HANGUL SYLLABLE HIEUH OE RIEULTHIEUTH
+0xC394	0xD69A	#HANGUL SYLLABLE HIEUH OE RIEULPHIEUPH
+0xC395	0xD69B	#HANGUL SYLLABLE HIEUH OE RIEULHIEUH
+0xC396	0xD69C	#HANGUL SYLLABLE HIEUH OE MIEUM
+0xC397	0xD69E	#HANGUL SYLLABLE HIEUH OE PIEUPSIOS
+0xC398	0xD6A0	#HANGUL SYLLABLE HIEUH OE SSANGSIOS
+0xC399	0xD6A2	#HANGUL SYLLABLE HIEUH OE CIEUC
+0xC39A	0xD6A3	#HANGUL SYLLABLE HIEUH OE CHIEUCH
+0xC39B	0xD6A4	#HANGUL SYLLABLE HIEUH OE KHIEUKH
+0xC39C	0xD6A5	#HANGUL SYLLABLE HIEUH OE THIEUTH
+0xC39D	0xD6A6	#HANGUL SYLLABLE HIEUH OE PHIEUPH
+0xC39E	0xD6A7	#HANGUL SYLLABLE HIEUH OE HIEUH
+0xC39F	0xD6A9	#HANGUL SYLLABLE HIEUH YO KIYEOK
+0xC3A0	0xD6AA	#HANGUL SYLLABLE HIEUH YO SSANGKIYEOK
+0xC3A1	0xCC3C	#HANGUL SYLLABLE CHIEUCH A SSANGSIOS
+0xC3A2	0xCC3D	#HANGUL SYLLABLE CHIEUCH A IEUNG
+0xC3A3	0xCC3E	#HANGUL SYLLABLE CHIEUCH A CIEUC
+0xC3A4	0xCC44	#HANGUL SYLLABLE CHIEUCH AE
+0xC3A5	0xCC45	#HANGUL SYLLABLE CHIEUCH AE KIYEOK
+0xC3A6	0xCC48	#HANGUL SYLLABLE CHIEUCH AE NIEUN
+0xC3A7	0xCC4C	#HANGUL SYLLABLE CHIEUCH AE RIEUL
+0xC3A8	0xCC54	#HANGUL SYLLABLE CHIEUCH AE MIEUM
+0xC3A9	0xCC55	#HANGUL SYLLABLE CHIEUCH AE PIEUP
+0xC3AA	0xCC57	#HANGUL SYLLABLE CHIEUCH AE SIOS
+0xC3AB	0xCC58	#HANGUL SYLLABLE CHIEUCH AE SSANGSIOS
+0xC3AC	0xCC59	#HANGUL SYLLABLE CHIEUCH AE IEUNG
+0xC3AD	0xCC60	#HANGUL SYLLABLE CHIEUCH YA
+0xC3AE	0xCC64	#HANGUL SYLLABLE CHIEUCH YA NIEUN
+0xC3AF	0xCC66	#HANGUL SYLLABLE CHIEUCH YA NIEUNHIEUH
+0xC3B0	0xCC68	#HANGUL SYLLABLE CHIEUCH YA RIEUL
+0xC3B1	0xCC70	#HANGUL SYLLABLE CHIEUCH YA MIEUM
+0xC3B2	0xCC75	#HANGUL SYLLABLE CHIEUCH YA IEUNG
+0xC3B3	0xCC98	#HANGUL SYLLABLE CHIEUCH EO
+0xC3B4	0xCC99	#HANGUL SYLLABLE CHIEUCH EO KIYEOK
+0xC3B5	0xCC9C	#HANGUL SYLLABLE CHIEUCH EO NIEUN
+0xC3B6	0xCCA0	#HANGUL SYLLABLE CHIEUCH EO RIEUL
+0xC3B7	0xCCA8	#HANGUL SYLLABLE CHIEUCH EO MIEUM
+0xC3B8	0xCCA9	#HANGUL SYLLABLE CHIEUCH EO PIEUP
+0xC3B9	0xCCAB	#HANGUL SYLLABLE CHIEUCH EO SIOS
+0xC3BA	0xCCAC	#HANGUL SYLLABLE CHIEUCH EO SSANGSIOS
+0xC3BB	0xCCAD	#HANGUL SYLLABLE CHIEUCH EO IEUNG
+0xC3BC	0xCCB4	#HANGUL SYLLABLE CHIEUCH E
+0xC3BD	0xCCB5	#HANGUL SYLLABLE CHIEUCH E KIYEOK
+0xC3BE	0xCCB8	#HANGUL SYLLABLE CHIEUCH E NIEUN
+0xC3BF	0xCCBC	#HANGUL SYLLABLE CHIEUCH E RIEUL
+0xC3C0	0xCCC4	#HANGUL SYLLABLE CHIEUCH E MIEUM
+0xC3C1	0xCCC5	#HANGUL SYLLABLE CHIEUCH E PIEUP
+0xC3C2	0xCCC7	#HANGUL SYLLABLE CHIEUCH E SIOS
+0xC3C3	0xCCC9	#HANGUL SYLLABLE CHIEUCH E IEUNG
+0xC3C4	0xCCD0	#HANGUL SYLLABLE CHIEUCH YEO
+0xC3C5	0xCCD4	#HANGUL SYLLABLE CHIEUCH YEO NIEUN
+0xC3C6	0xCCE4	#HANGUL SYLLABLE CHIEUCH YEO SSANGSIOS
+0xC3C7	0xCCEC	#HANGUL SYLLABLE CHIEUCH YE
+0xC3C8	0xCCF0	#HANGUL SYLLABLE CHIEUCH YE NIEUN
+0xC3C9	0xCD01	#HANGUL SYLLABLE CHIEUCH YE IEUNG
+0xC3CA	0xCD08	#HANGUL SYLLABLE CHIEUCH O
+0xC3CB	0xCD09	#HANGUL SYLLABLE CHIEUCH O KIYEOK
+0xC3CC	0xCD0C	#HANGUL SYLLABLE CHIEUCH O NIEUN
+0xC3CD	0xCD10	#HANGUL SYLLABLE CHIEUCH O RIEUL
+0xC3CE	0xCD18	#HANGUL SYLLABLE CHIEUCH O MIEUM
+0xC3CF	0xCD19	#HANGUL SYLLABLE CHIEUCH O PIEUP
+0xC3D0	0xCD1B	#HANGUL SYLLABLE CHIEUCH O SIOS
+0xC3D1	0xCD1D	#HANGUL SYLLABLE CHIEUCH O IEUNG
+0xC3D2	0xCD24	#HANGUL SYLLABLE CHIEUCH WA
+0xC3D3	0xCD28	#HANGUL SYLLABLE CHIEUCH WA NIEUN
+0xC3D4	0xCD2C	#HANGUL SYLLABLE CHIEUCH WA RIEUL
+0xC3D5	0xCD39	#HANGUL SYLLABLE CHIEUCH WA IEUNG
+0xC3D6	0xCD5C	#HANGUL SYLLABLE CHIEUCH OE
+0xC3D7	0xCD60	#HANGUL SYLLABLE CHIEUCH OE NIEUN
+0xC3D8	0xCD64	#HANGUL SYLLABLE CHIEUCH OE RIEUL
+0xC3D9	0xCD6C	#HANGUL SYLLABLE CHIEUCH OE MIEUM
+0xC3DA	0xCD6D	#HANGUL SYLLABLE CHIEUCH OE PIEUP
+0xC3DB	0xCD6F	#HANGUL SYLLABLE CHIEUCH OE SIOS
+0xC3DC	0xCD71	#HANGUL SYLLABLE CHIEUCH OE IEUNG
+0xC3DD	0xCD78	#HANGUL SYLLABLE CHIEUCH YO
+0xC3DE	0xCD88	#HANGUL SYLLABLE CHIEUCH YO MIEUM
+0xC3DF	0xCD94	#HANGUL SYLLABLE CHIEUCH U
+0xC3E0	0xCD95	#HANGUL SYLLABLE CHIEUCH U KIYEOK
+0xC3E1	0xCD98	#HANGUL SYLLABLE CHIEUCH U NIEUN
+0xC3E2	0xCD9C	#HANGUL SYLLABLE CHIEUCH U RIEUL
+0xC3E3	0xCDA4	#HANGUL SYLLABLE CHIEUCH U MIEUM
+0xC3E4	0xCDA5	#HANGUL SYLLABLE CHIEUCH U PIEUP
+0xC3E5	0xCDA7	#HANGUL SYLLABLE CHIEUCH U SIOS
+0xC3E6	0xCDA9	#HANGUL SYLLABLE CHIEUCH U IEUNG
+0xC3E7	0xCDB0	#HANGUL SYLLABLE CHIEUCH WEO
+0xC3E8	0xCDC4	#HANGUL SYLLABLE CHIEUCH WEO SSANGSIOS
+0xC3E9	0xCDCC	#HANGUL SYLLABLE CHIEUCH WE
+0xC3EA	0xCDD0	#HANGUL SYLLABLE CHIEUCH WE NIEUN
+0xC3EB	0xCDE8	#HANGUL SYLLABLE CHIEUCH WI
+0xC3EC	0xCDEC	#HANGUL SYLLABLE CHIEUCH WI NIEUN
+0xC3ED	0xCDF0	#HANGUL SYLLABLE CHIEUCH WI RIEUL
+0xC3EE	0xCDF8	#HANGUL SYLLABLE CHIEUCH WI MIEUM
+0xC3EF	0xCDF9	#HANGUL SYLLABLE CHIEUCH WI PIEUP
+0xC3F0	0xCDFB	#HANGUL SYLLABLE CHIEUCH WI SIOS
+0xC3F1	0xCDFD	#HANGUL SYLLABLE CHIEUCH WI IEUNG
+0xC3F2	0xCE04	#HANGUL SYLLABLE CHIEUCH YU
+0xC3F3	0xCE08	#HANGUL SYLLABLE CHIEUCH YU NIEUN
+0xC3F4	0xCE0C	#HANGUL SYLLABLE CHIEUCH YU RIEUL
+0xC3F5	0xCE14	#HANGUL SYLLABLE CHIEUCH YU MIEUM
+0xC3F6	0xCE19	#HANGUL SYLLABLE CHIEUCH YU IEUNG
+0xC3F7	0xCE20	#HANGUL SYLLABLE CHIEUCH EU
+0xC3F8	0xCE21	#HANGUL SYLLABLE CHIEUCH EU KIYEOK
+0xC3F9	0xCE24	#HANGUL SYLLABLE CHIEUCH EU NIEUN
+0xC3FA	0xCE28	#HANGUL SYLLABLE CHIEUCH EU RIEUL
+0xC3FB	0xCE30	#HANGUL SYLLABLE CHIEUCH EU MIEUM
+0xC3FC	0xCE31	#HANGUL SYLLABLE CHIEUCH EU PIEUP
+0xC3FD	0xCE33	#HANGUL SYLLABLE CHIEUCH EU SIOS
+0xC3FE	0xCE35	#HANGUL SYLLABLE CHIEUCH EU IEUNG
+0xC441	0xD6AB	#HANGUL SYLLABLE HIEUH YO KIYEOKSIOS
+0xC442	0xD6AD	#HANGUL SYLLABLE HIEUH YO NIEUNCIEUC
+0xC443	0xD6AE	#HANGUL SYLLABLE HIEUH YO NIEUNHIEUH
+0xC444	0xD6AF	#HANGUL SYLLABLE HIEUH YO TIKEUT
+0xC445	0xD6B1	#HANGUL SYLLABLE HIEUH YO RIEULKIYEOK
+0xC446	0xD6B2	#HANGUL SYLLABLE HIEUH YO RIEULMIEUM
+0xC447	0xD6B3	#HANGUL SYLLABLE HIEUH YO RIEULPIEUP
+0xC448	0xD6B4	#HANGUL SYLLABLE HIEUH YO RIEULSIOS
+0xC449	0xD6B5	#HANGUL SYLLABLE HIEUH YO RIEULTHIEUTH
+0xC44A	0xD6B6	#HANGUL SYLLABLE HIEUH YO RIEULPHIEUPH
+0xC44B	0xD6B7	#HANGUL SYLLABLE HIEUH YO RIEULHIEUH
+0xC44C	0xD6B8	#HANGUL SYLLABLE HIEUH YO MIEUM
+0xC44D	0xD6BA	#HANGUL SYLLABLE HIEUH YO PIEUPSIOS
+0xC44E	0xD6BC	#HANGUL SYLLABLE HIEUH YO SSANGSIOS
+0xC44F	0xD6BD	#HANGUL SYLLABLE HIEUH YO IEUNG
+0xC450	0xD6BE	#HANGUL SYLLABLE HIEUH YO CIEUC
+0xC451	0xD6BF	#HANGUL SYLLABLE HIEUH YO CHIEUCH
+0xC452	0xD6C0	#HANGUL SYLLABLE HIEUH YO KHIEUKH
+0xC453	0xD6C1	#HANGUL SYLLABLE HIEUH YO THIEUTH
+0xC454	0xD6C2	#HANGUL SYLLABLE HIEUH YO PHIEUPH
+0xC455	0xD6C3	#HANGUL SYLLABLE HIEUH YO HIEUH
+0xC456	0xD6C6	#HANGUL SYLLABLE HIEUH U SSANGKIYEOK
+0xC457	0xD6C7	#HANGUL SYLLABLE HIEUH U KIYEOKSIOS
+0xC458	0xD6C9	#HANGUL SYLLABLE HIEUH U NIEUNCIEUC
+0xC459	0xD6CA	#HANGUL SYLLABLE HIEUH U NIEUNHIEUH
+0xC45A	0xD6CB	#HANGUL SYLLABLE HIEUH U TIKEUT
+0xC461	0xD6CD	#HANGUL SYLLABLE HIEUH U RIEULKIYEOK
+0xC462	0xD6CE	#HANGUL SYLLABLE HIEUH U RIEULMIEUM
+0xC463	0xD6CF	#HANGUL SYLLABLE HIEUH U RIEULPIEUP
+0xC464	0xD6D0	#HANGUL SYLLABLE HIEUH U RIEULSIOS
+0xC465	0xD6D2	#HANGUL SYLLABLE HIEUH U RIEULPHIEUPH
+0xC466	0xD6D3	#HANGUL SYLLABLE HIEUH U RIEULHIEUH
+0xC467	0xD6D5	#HANGUL SYLLABLE HIEUH U PIEUP
+0xC468	0xD6D6	#HANGUL SYLLABLE HIEUH U PIEUPSIOS
+0xC469	0xD6D8	#HANGUL SYLLABLE HIEUH U SSANGSIOS
+0xC46A	0xD6DA	#HANGUL SYLLABLE HIEUH U CIEUC
+0xC46B	0xD6DB	#HANGUL SYLLABLE HIEUH U CHIEUCH
+0xC46C	0xD6DC	#HANGUL SYLLABLE HIEUH U KHIEUKH
+0xC46D	0xD6DD	#HANGUL SYLLABLE HIEUH U THIEUTH
+0xC46E	0xD6DE	#HANGUL SYLLABLE HIEUH U PHIEUPH
+0xC46F	0xD6DF	#HANGUL SYLLABLE HIEUH U HIEUH
+0xC470	0xD6E1	#HANGUL SYLLABLE HIEUH WEO KIYEOK
+0xC471	0xD6E2	#HANGUL SYLLABLE HIEUH WEO SSANGKIYEOK
+0xC472	0xD6E3	#HANGUL SYLLABLE HIEUH WEO KIYEOKSIOS
+0xC473	0xD6E5	#HANGUL SYLLABLE HIEUH WEO NIEUNCIEUC
+0xC474	0xD6E6	#HANGUL SYLLABLE HIEUH WEO NIEUNHIEUH
+0xC475	0xD6E7	#HANGUL SYLLABLE HIEUH WEO TIKEUT
+0xC476	0xD6E9	#HANGUL SYLLABLE HIEUH WEO RIEULKIYEOK
+0xC477	0xD6EA	#HANGUL SYLLABLE HIEUH WEO RIEULMIEUM
+0xC478	0xD6EB	#HANGUL SYLLABLE HIEUH WEO RIEULPIEUP
+0xC479	0xD6EC	#HANGUL SYLLABLE HIEUH WEO RIEULSIOS
+0xC47A	0xD6ED	#HANGUL SYLLABLE HIEUH WEO RIEULTHIEUTH
+0xC481	0xD6EE	#HANGUL SYLLABLE HIEUH WEO RIEULPHIEUPH
+0xC482	0xD6EF	#HANGUL SYLLABLE HIEUH WEO RIEULHIEUH
+0xC483	0xD6F1	#HANGUL SYLLABLE HIEUH WEO PIEUP
+0xC484	0xD6F2	#HANGUL SYLLABLE HIEUH WEO PIEUPSIOS
+0xC485	0xD6F3	#HANGUL SYLLABLE HIEUH WEO SIOS
+0xC486	0xD6F4	#HANGUL SYLLABLE HIEUH WEO SSANGSIOS
+0xC487	0xD6F6	#HANGUL SYLLABLE HIEUH WEO CIEUC
+0xC488	0xD6F7	#HANGUL SYLLABLE HIEUH WEO CHIEUCH
+0xC489	0xD6F8	#HANGUL SYLLABLE HIEUH WEO KHIEUKH
+0xC48A	0xD6F9	#HANGUL SYLLABLE HIEUH WEO THIEUTH
+0xC48B	0xD6FA	#HANGUL SYLLABLE HIEUH WEO PHIEUPH
+0xC48C	0xD6FB	#HANGUL SYLLABLE HIEUH WEO HIEUH
+0xC48D	0xD6FE	#HANGUL SYLLABLE HIEUH WE SSANGKIYEOK
+0xC48E	0xD6FF	#HANGUL SYLLABLE HIEUH WE KIYEOKSIOS
+0xC48F	0xD701	#HANGUL SYLLABLE HIEUH WE NIEUNCIEUC
+0xC490	0xD702	#HANGUL SYLLABLE HIEUH WE NIEUNHIEUH
+0xC491	0xD703	#HANGUL SYLLABLE HIEUH WE TIKEUT
+0xC492	0xD705	#HANGUL SYLLABLE HIEUH WE RIEULKIYEOK
+0xC493	0xD706	#HANGUL SYLLABLE HIEUH WE RIEULMIEUM
+0xC494	0xD707	#HANGUL SYLLABLE HIEUH WE RIEULPIEUP
+0xC495	0xD708	#HANGUL SYLLABLE HIEUH WE RIEULSIOS
+0xC496	0xD709	#HANGUL SYLLABLE HIEUH WE RIEULTHIEUTH
+0xC497	0xD70A	#HANGUL SYLLABLE HIEUH WE RIEULPHIEUPH
+0xC498	0xD70B	#HANGUL SYLLABLE HIEUH WE RIEULHIEUH
+0xC499	0xD70C	#HANGUL SYLLABLE HIEUH WE MIEUM
+0xC49A	0xD70D	#HANGUL SYLLABLE HIEUH WE PIEUP
+0xC49B	0xD70E	#HANGUL SYLLABLE HIEUH WE PIEUPSIOS
+0xC49C	0xD70F	#HANGUL SYLLABLE HIEUH WE SIOS
+0xC49D	0xD710	#HANGUL SYLLABLE HIEUH WE SSANGSIOS
+0xC49E	0xD712	#HANGUL SYLLABLE HIEUH WE CIEUC
+0xC49F	0xD713	#HANGUL SYLLABLE HIEUH WE CHIEUCH
+0xC4A0	0xD714	#HANGUL SYLLABLE HIEUH WE KHIEUKH
+0xC4A1	0xCE58	#HANGUL SYLLABLE CHIEUCH I
+0xC4A2	0xCE59	#HANGUL SYLLABLE CHIEUCH I KIYEOK
+0xC4A3	0xCE5C	#HANGUL SYLLABLE CHIEUCH I NIEUN
+0xC4A4	0xCE5F	#HANGUL SYLLABLE CHIEUCH I TIKEUT
+0xC4A5	0xCE60	#HANGUL SYLLABLE CHIEUCH I RIEUL
+0xC4A6	0xCE61	#HANGUL SYLLABLE CHIEUCH I RIEULKIYEOK
+0xC4A7	0xCE68	#HANGUL SYLLABLE CHIEUCH I MIEUM
+0xC4A8	0xCE69	#HANGUL SYLLABLE CHIEUCH I PIEUP
+0xC4A9	0xCE6B	#HANGUL SYLLABLE CHIEUCH I SIOS
+0xC4AA	0xCE6D	#HANGUL SYLLABLE CHIEUCH I IEUNG
+0xC4AB	0xCE74	#HANGUL SYLLABLE KHIEUKH A
+0xC4AC	0xCE75	#HANGUL SYLLABLE KHIEUKH A KIYEOK
+0xC4AD	0xCE78	#HANGUL SYLLABLE KHIEUKH A NIEUN
+0xC4AE	0xCE7C	#HANGUL SYLLABLE KHIEUKH A RIEUL
+0xC4AF	0xCE84	#HANGUL SYLLABLE KHIEUKH A MIEUM
+0xC4B0	0xCE85	#HANGUL SYLLABLE KHIEUKH A PIEUP
+0xC4B1	0xCE87	#HANGUL SYLLABLE KHIEUKH A SIOS
+0xC4B2	0xCE89	#HANGUL SYLLABLE KHIEUKH A IEUNG
+0xC4B3	0xCE90	#HANGUL SYLLABLE KHIEUKH AE
+0xC4B4	0xCE91	#HANGUL SYLLABLE KHIEUKH AE KIYEOK
+0xC4B5	0xCE94	#HANGUL SYLLABLE KHIEUKH AE NIEUN
+0xC4B6	0xCE98	#HANGUL SYLLABLE KHIEUKH AE RIEUL
+0xC4B7	0xCEA0	#HANGUL SYLLABLE KHIEUKH AE MIEUM
+0xC4B8	0xCEA1	#HANGUL SYLLABLE KHIEUKH AE PIEUP
+0xC4B9	0xCEA3	#HANGUL SYLLABLE KHIEUKH AE SIOS
+0xC4BA	0xCEA4	#HANGUL SYLLABLE KHIEUKH AE SSANGSIOS
+0xC4BB	0xCEA5	#HANGUL SYLLABLE KHIEUKH AE IEUNG
+0xC4BC	0xCEAC	#HANGUL SYLLABLE KHIEUKH YA
+0xC4BD	0xCEAD	#HANGUL SYLLABLE KHIEUKH YA KIYEOK
+0xC4BE	0xCEC1	#HANGUL SYLLABLE KHIEUKH YA IEUNG
+0xC4BF	0xCEE4	#HANGUL SYLLABLE KHIEUKH EO
+0xC4C0	0xCEE5	#HANGUL SYLLABLE KHIEUKH EO KIYEOK
+0xC4C1	0xCEE8	#HANGUL SYLLABLE KHIEUKH EO NIEUN
+0xC4C2	0xCEEB	#HANGUL SYLLABLE KHIEUKH EO TIKEUT
+0xC4C3	0xCEEC	#HANGUL SYLLABLE KHIEUKH EO RIEUL
+0xC4C4	0xCEF4	#HANGUL SYLLABLE KHIEUKH EO MIEUM
+0xC4C5	0xCEF5	#HANGUL SYLLABLE KHIEUKH EO PIEUP
+0xC4C6	0xCEF7	#HANGUL SYLLABLE KHIEUKH EO SIOS
+0xC4C7	0xCEF8	#HANGUL SYLLABLE KHIEUKH EO SSANGSIOS
+0xC4C8	0xCEF9	#HANGUL SYLLABLE KHIEUKH EO IEUNG
+0xC4C9	0xCF00	#HANGUL SYLLABLE KHIEUKH E
+0xC4CA	0xCF01	#HANGUL SYLLABLE KHIEUKH E KIYEOK
+0xC4CB	0xCF04	#HANGUL SYLLABLE KHIEUKH E NIEUN
+0xC4CC	0xCF08	#HANGUL SYLLABLE KHIEUKH E RIEUL
+0xC4CD	0xCF10	#HANGUL SYLLABLE KHIEUKH E MIEUM
+0xC4CE	0xCF11	#HANGUL SYLLABLE KHIEUKH E PIEUP
+0xC4CF	0xCF13	#HANGUL SYLLABLE KHIEUKH E SIOS
+0xC4D0	0xCF15	#HANGUL SYLLABLE KHIEUKH E IEUNG
+0xC4D1	0xCF1C	#HANGUL SYLLABLE KHIEUKH YEO
+0xC4D2	0xCF20	#HANGUL SYLLABLE KHIEUKH YEO NIEUN
+0xC4D3	0xCF24	#HANGUL SYLLABLE KHIEUKH YEO RIEUL
+0xC4D4	0xCF2C	#HANGUL SYLLABLE KHIEUKH YEO MIEUM
+0xC4D5	0xCF2D	#HANGUL SYLLABLE KHIEUKH YEO PIEUP
+0xC4D6	0xCF2F	#HANGUL SYLLABLE KHIEUKH YEO SIOS
+0xC4D7	0xCF30	#HANGUL SYLLABLE KHIEUKH YEO SSANGSIOS
+0xC4D8	0xCF31	#HANGUL SYLLABLE KHIEUKH YEO IEUNG
+0xC4D9	0xCF38	#HANGUL SYLLABLE KHIEUKH YE
+0xC4DA	0xCF54	#HANGUL SYLLABLE KHIEUKH O
+0xC4DB	0xCF55	#HANGUL SYLLABLE KHIEUKH O KIYEOK
+0xC4DC	0xCF58	#HANGUL SYLLABLE KHIEUKH O NIEUN
+0xC4DD	0xCF5C	#HANGUL SYLLABLE KHIEUKH O RIEUL
+0xC4DE	0xCF64	#HANGUL SYLLABLE KHIEUKH O MIEUM
+0xC4DF	0xCF65	#HANGUL SYLLABLE KHIEUKH O PIEUP
+0xC4E0	0xCF67	#HANGUL SYLLABLE KHIEUKH O SIOS
+0xC4E1	0xCF69	#HANGUL SYLLABLE KHIEUKH O IEUNG
+0xC4E2	0xCF70	#HANGUL SYLLABLE KHIEUKH WA
+0xC4E3	0xCF71	#HANGUL SYLLABLE KHIEUKH WA KIYEOK
+0xC4E4	0xCF74	#HANGUL SYLLABLE KHIEUKH WA NIEUN
+0xC4E5	0xCF78	#HANGUL SYLLABLE KHIEUKH WA RIEUL
+0xC4E6	0xCF80	#HANGUL SYLLABLE KHIEUKH WA MIEUM
+0xC4E7	0xCF85	#HANGUL SYLLABLE KHIEUKH WA IEUNG
+0xC4E8	0xCF8C	#HANGUL SYLLABLE KHIEUKH WAE
+0xC4E9	0xCFA1	#HANGUL SYLLABLE KHIEUKH WAE IEUNG
+0xC4EA	0xCFA8	#HANGUL SYLLABLE KHIEUKH OE
+0xC4EB	0xCFB0	#HANGUL SYLLABLE KHIEUKH OE RIEUL
+0xC4EC	0xCFC4	#HANGUL SYLLABLE KHIEUKH YO
+0xC4ED	0xCFE0	#HANGUL SYLLABLE KHIEUKH U
+0xC4EE	0xCFE1	#HANGUL SYLLABLE KHIEUKH U KIYEOK
+0xC4EF	0xCFE4	#HANGUL SYLLABLE KHIEUKH U NIEUN
+0xC4F0	0xCFE8	#HANGUL SYLLABLE KHIEUKH U RIEUL
+0xC4F1	0xCFF0	#HANGUL SYLLABLE KHIEUKH U MIEUM
+0xC4F2	0xCFF1	#HANGUL SYLLABLE KHIEUKH U PIEUP
+0xC4F3	0xCFF3	#HANGUL SYLLABLE KHIEUKH U SIOS
+0xC4F4	0xCFF5	#HANGUL SYLLABLE KHIEUKH U IEUNG
+0xC4F5	0xCFFC	#HANGUL SYLLABLE KHIEUKH WEO
+0xC4F6	0xD000	#HANGUL SYLLABLE KHIEUKH WEO NIEUN
+0xC4F7	0xD004	#HANGUL SYLLABLE KHIEUKH WEO RIEUL
+0xC4F8	0xD011	#HANGUL SYLLABLE KHIEUKH WEO IEUNG
+0xC4F9	0xD018	#HANGUL SYLLABLE KHIEUKH WE
+0xC4FA	0xD02D	#HANGUL SYLLABLE KHIEUKH WE IEUNG
+0xC4FB	0xD034	#HANGUL SYLLABLE KHIEUKH WI
+0xC4FC	0xD035	#HANGUL SYLLABLE KHIEUKH WI KIYEOK
+0xC4FD	0xD038	#HANGUL SYLLABLE KHIEUKH WI NIEUN
+0xC4FE	0xD03C	#HANGUL SYLLABLE KHIEUKH WI RIEUL
+0xC541	0xD715	#HANGUL SYLLABLE HIEUH WE THIEUTH
+0xC542	0xD716	#HANGUL SYLLABLE HIEUH WE PHIEUPH
+0xC543	0xD717	#HANGUL SYLLABLE HIEUH WE HIEUH
+0xC544	0xD71A	#HANGUL SYLLABLE HIEUH WI SSANGKIYEOK
+0xC545	0xD71B	#HANGUL SYLLABLE HIEUH WI KIYEOKSIOS
+0xC546	0xD71D	#HANGUL SYLLABLE HIEUH WI NIEUNCIEUC
+0xC547	0xD71E	#HANGUL SYLLABLE HIEUH WI NIEUNHIEUH
+0xC548	0xD71F	#HANGUL SYLLABLE HIEUH WI TIKEUT
+0xC549	0xD721	#HANGUL SYLLABLE HIEUH WI RIEULKIYEOK
+0xC54A	0xD722	#HANGUL SYLLABLE HIEUH WI RIEULMIEUM
+0xC54B	0xD723	#HANGUL SYLLABLE HIEUH WI RIEULPIEUP
+0xC54C	0xD724	#HANGUL SYLLABLE HIEUH WI RIEULSIOS
+0xC54D	0xD725	#HANGUL SYLLABLE HIEUH WI RIEULTHIEUTH
+0xC54E	0xD726	#HANGUL SYLLABLE HIEUH WI RIEULPHIEUPH
+0xC54F	0xD727	#HANGUL SYLLABLE HIEUH WI RIEULHIEUH
+0xC550	0xD72A	#HANGUL SYLLABLE HIEUH WI PIEUPSIOS
+0xC551	0xD72C	#HANGUL SYLLABLE HIEUH WI SSANGSIOS
+0xC552	0xD72E	#HANGUL SYLLABLE HIEUH WI CIEUC
+0xC553	0xD72F	#HANGUL SYLLABLE HIEUH WI CHIEUCH
+0xC554	0xD730	#HANGUL SYLLABLE HIEUH WI KHIEUKH
+0xC555	0xD731	#HANGUL SYLLABLE HIEUH WI THIEUTH
+0xC556	0xD732	#HANGUL SYLLABLE HIEUH WI PHIEUPH
+0xC557	0xD733	#HANGUL SYLLABLE HIEUH WI HIEUH
+0xC558	0xD736	#HANGUL SYLLABLE HIEUH YU SSANGKIYEOK
+0xC559	0xD737	#HANGUL SYLLABLE HIEUH YU KIYEOKSIOS
+0xC55A	0xD739	#HANGUL SYLLABLE HIEUH YU NIEUNCIEUC
+0xC561	0xD73A	#HANGUL SYLLABLE HIEUH YU NIEUNHIEUH
+0xC562	0xD73B	#HANGUL SYLLABLE HIEUH YU TIKEUT
+0xC563	0xD73D	#HANGUL SYLLABLE HIEUH YU RIEULKIYEOK
+0xC564	0xD73E	#HANGUL SYLLABLE HIEUH YU RIEULMIEUM
+0xC565	0xD73F	#HANGUL SYLLABLE HIEUH YU RIEULPIEUP
+0xC566	0xD740	#HANGUL SYLLABLE HIEUH YU RIEULSIOS
+0xC567	0xD741	#HANGUL SYLLABLE HIEUH YU RIEULTHIEUTH
+0xC568	0xD742	#HANGUL SYLLABLE HIEUH YU RIEULPHIEUPH
+0xC569	0xD743	#HANGUL SYLLABLE HIEUH YU RIEULHIEUH
+0xC56A	0xD745	#HANGUL SYLLABLE HIEUH YU PIEUP
+0xC56B	0xD746	#HANGUL SYLLABLE HIEUH YU PIEUPSIOS
+0xC56C	0xD748	#HANGUL SYLLABLE HIEUH YU SSANGSIOS
+0xC56D	0xD74A	#HANGUL SYLLABLE HIEUH YU CIEUC
+0xC56E	0xD74B	#HANGUL SYLLABLE HIEUH YU CHIEUCH
+0xC56F	0xD74C	#HANGUL SYLLABLE HIEUH YU KHIEUKH
+0xC570	0xD74D	#HANGUL SYLLABLE HIEUH YU THIEUTH
+0xC571	0xD74E	#HANGUL SYLLABLE HIEUH YU PHIEUPH
+0xC572	0xD74F	#HANGUL SYLLABLE HIEUH YU HIEUH
+0xC573	0xD752	#HANGUL SYLLABLE HIEUH EU SSANGKIYEOK
+0xC574	0xD753	#HANGUL SYLLABLE HIEUH EU KIYEOKSIOS
+0xC575	0xD755	#HANGUL SYLLABLE HIEUH EU NIEUNCIEUC
+0xC576	0xD75A	#HANGUL SYLLABLE HIEUH EU RIEULMIEUM
+0xC577	0xD75B	#HANGUL SYLLABLE HIEUH EU RIEULPIEUP
+0xC578	0xD75C	#HANGUL SYLLABLE HIEUH EU RIEULSIOS
+0xC579	0xD75D	#HANGUL SYLLABLE HIEUH EU RIEULTHIEUTH
+0xC57A	0xD75E	#HANGUL SYLLABLE HIEUH EU RIEULPHIEUPH
+0xC581	0xD75F	#HANGUL SYLLABLE HIEUH EU RIEULHIEUH
+0xC582	0xD762	#HANGUL SYLLABLE HIEUH EU PIEUPSIOS
+0xC583	0xD764	#HANGUL SYLLABLE HIEUH EU SSANGSIOS
+0xC584	0xD766	#HANGUL SYLLABLE HIEUH EU CIEUC
+0xC585	0xD767	#HANGUL SYLLABLE HIEUH EU CHIEUCH
+0xC586	0xD768	#HANGUL SYLLABLE HIEUH EU KHIEUKH
+0xC587	0xD76A	#HANGUL SYLLABLE HIEUH EU PHIEUPH
+0xC588	0xD76B	#HANGUL SYLLABLE HIEUH EU HIEUH
+0xC589	0xD76D	#HANGUL SYLLABLE HIEUH YI KIYEOK
+0xC58A	0xD76E	#HANGUL SYLLABLE HIEUH YI SSANGKIYEOK
+0xC58B	0xD76F	#HANGUL SYLLABLE HIEUH YI KIYEOKSIOS
+0xC58C	0xD771	#HANGUL SYLLABLE HIEUH YI NIEUNCIEUC
+0xC58D	0xD772	#HANGUL SYLLABLE HIEUH YI NIEUNHIEUH
+0xC58E	0xD773	#HANGUL SYLLABLE HIEUH YI TIKEUT
+0xC58F	0xD775	#HANGUL SYLLABLE HIEUH YI RIEULKIYEOK
+0xC590	0xD776	#HANGUL SYLLABLE HIEUH YI RIEULMIEUM
+0xC591	0xD777	#HANGUL SYLLABLE HIEUH YI RIEULPIEUP
+0xC592	0xD778	#HANGUL SYLLABLE HIEUH YI RIEULSIOS
+0xC593	0xD779	#HANGUL SYLLABLE HIEUH YI RIEULTHIEUTH
+0xC594	0xD77A	#HANGUL SYLLABLE HIEUH YI RIEULPHIEUPH
+0xC595	0xD77B	#HANGUL SYLLABLE HIEUH YI RIEULHIEUH
+0xC596	0xD77E	#HANGUL SYLLABLE HIEUH YI PIEUPSIOS
+0xC597	0xD77F	#HANGUL SYLLABLE HIEUH YI SIOS
+0xC598	0xD780	#HANGUL SYLLABLE HIEUH YI SSANGSIOS
+0xC599	0xD782	#HANGUL SYLLABLE HIEUH YI CIEUC
+0xC59A	0xD783	#HANGUL SYLLABLE HIEUH YI CHIEUCH
+0xC59B	0xD784	#HANGUL SYLLABLE HIEUH YI KHIEUKH
+0xC59C	0xD785	#HANGUL SYLLABLE HIEUH YI THIEUTH
+0xC59D	0xD786	#HANGUL SYLLABLE HIEUH YI PHIEUPH
+0xC59E	0xD787	#HANGUL SYLLABLE HIEUH YI HIEUH
+0xC59F	0xD78A	#HANGUL SYLLABLE HIEUH I SSANGKIYEOK
+0xC5A0	0xD78B	#HANGUL SYLLABLE HIEUH I KIYEOKSIOS
+0xC5A1	0xD044	#HANGUL SYLLABLE KHIEUKH WI MIEUM
+0xC5A2	0xD045	#HANGUL SYLLABLE KHIEUKH WI PIEUP
+0xC5A3	0xD047	#HANGUL SYLLABLE KHIEUKH WI SIOS
+0xC5A4	0xD049	#HANGUL SYLLABLE KHIEUKH WI IEUNG
+0xC5A5	0xD050	#HANGUL SYLLABLE KHIEUKH YU
+0xC5A6	0xD054	#HANGUL SYLLABLE KHIEUKH YU NIEUN
+0xC5A7	0xD058	#HANGUL SYLLABLE KHIEUKH YU RIEUL
+0xC5A8	0xD060	#HANGUL SYLLABLE KHIEUKH YU MIEUM
+0xC5A9	0xD06C	#HANGUL SYLLABLE KHIEUKH EU
+0xC5AA	0xD06D	#HANGUL SYLLABLE KHIEUKH EU KIYEOK
+0xC5AB	0xD070	#HANGUL SYLLABLE KHIEUKH EU NIEUN
+0xC5AC	0xD074	#HANGUL SYLLABLE KHIEUKH EU RIEUL
+0xC5AD	0xD07C	#HANGUL SYLLABLE KHIEUKH EU MIEUM
+0xC5AE	0xD07D	#HANGUL SYLLABLE KHIEUKH EU PIEUP
+0xC5AF	0xD081	#HANGUL SYLLABLE KHIEUKH EU IEUNG
+0xC5B0	0xD0A4	#HANGUL SYLLABLE KHIEUKH I
+0xC5B1	0xD0A5	#HANGUL SYLLABLE KHIEUKH I KIYEOK
+0xC5B2	0xD0A8	#HANGUL SYLLABLE KHIEUKH I NIEUN
+0xC5B3	0xD0AC	#HANGUL SYLLABLE KHIEUKH I RIEUL
+0xC5B4	0xD0B4	#HANGUL SYLLABLE KHIEUKH I MIEUM
+0xC5B5	0xD0B5	#HANGUL SYLLABLE KHIEUKH I PIEUP
+0xC5B6	0xD0B7	#HANGUL SYLLABLE KHIEUKH I SIOS
+0xC5B7	0xD0B9	#HANGUL SYLLABLE KHIEUKH I IEUNG
+0xC5B8	0xD0C0	#HANGUL SYLLABLE THIEUTH A
+0xC5B9	0xD0C1	#HANGUL SYLLABLE THIEUTH A KIYEOK
+0xC5BA	0xD0C4	#HANGUL SYLLABLE THIEUTH A NIEUN
+0xC5BB	0xD0C8	#HANGUL SYLLABLE THIEUTH A RIEUL
+0xC5BC	0xD0C9	#HANGUL SYLLABLE THIEUTH A RIEULKIYEOK
+0xC5BD	0xD0D0	#HANGUL SYLLABLE THIEUTH A MIEUM
+0xC5BE	0xD0D1	#HANGUL SYLLABLE THIEUTH A PIEUP
+0xC5BF	0xD0D3	#HANGUL SYLLABLE THIEUTH A SIOS
+0xC5C0	0xD0D4	#HANGUL SYLLABLE THIEUTH A SSANGSIOS
+0xC5C1	0xD0D5	#HANGUL SYLLABLE THIEUTH A IEUNG
+0xC5C2	0xD0DC	#HANGUL SYLLABLE THIEUTH AE
+0xC5C3	0xD0DD	#HANGUL SYLLABLE THIEUTH AE KIYEOK
+0xC5C4	0xD0E0	#HANGUL SYLLABLE THIEUTH AE NIEUN
+0xC5C5	0xD0E4	#HANGUL SYLLABLE THIEUTH AE RIEUL
+0xC5C6	0xD0EC	#HANGUL SYLLABLE THIEUTH AE MIEUM
+0xC5C7	0xD0ED	#HANGUL SYLLABLE THIEUTH AE PIEUP
+0xC5C8	0xD0EF	#HANGUL SYLLABLE THIEUTH AE SIOS
+0xC5C9	0xD0F0	#HANGUL SYLLABLE THIEUTH AE SSANGSIOS
+0xC5CA	0xD0F1	#HANGUL SYLLABLE THIEUTH AE IEUNG
+0xC5CB	0xD0F8	#HANGUL SYLLABLE THIEUTH YA
+0xC5CC	0xD10D	#HANGUL SYLLABLE THIEUTH YA IEUNG
+0xC5CD	0xD130	#HANGUL SYLLABLE THIEUTH EO
+0xC5CE	0xD131	#HANGUL SYLLABLE THIEUTH EO KIYEOK
+0xC5CF	0xD134	#HANGUL SYLLABLE THIEUTH EO NIEUN
+0xC5D0	0xD138	#HANGUL SYLLABLE THIEUTH EO RIEUL
+0xC5D1	0xD13A	#HANGUL SYLLABLE THIEUTH EO RIEULMIEUM
+0xC5D2	0xD140	#HANGUL SYLLABLE THIEUTH EO MIEUM
+0xC5D3	0xD141	#HANGUL SYLLABLE THIEUTH EO PIEUP
+0xC5D4	0xD143	#HANGUL SYLLABLE THIEUTH EO SIOS
+0xC5D5	0xD144	#HANGUL SYLLABLE THIEUTH EO SSANGSIOS
+0xC5D6	0xD145	#HANGUL SYLLABLE THIEUTH EO IEUNG
+0xC5D7	0xD14C	#HANGUL SYLLABLE THIEUTH E
+0xC5D8	0xD14D	#HANGUL SYLLABLE THIEUTH E KIYEOK
+0xC5D9	0xD150	#HANGUL SYLLABLE THIEUTH E NIEUN
+0xC5DA	0xD154	#HANGUL SYLLABLE THIEUTH E RIEUL
+0xC5DB	0xD15C	#HANGUL SYLLABLE THIEUTH E MIEUM
+0xC5DC	0xD15D	#HANGUL SYLLABLE THIEUTH E PIEUP
+0xC5DD	0xD15F	#HANGUL SYLLABLE THIEUTH E SIOS
+0xC5DE	0xD161	#HANGUL SYLLABLE THIEUTH E IEUNG
+0xC5DF	0xD168	#HANGUL SYLLABLE THIEUTH YEO
+0xC5E0	0xD16C	#HANGUL SYLLABLE THIEUTH YEO NIEUN
+0xC5E1	0xD17C	#HANGUL SYLLABLE THIEUTH YEO SSANGSIOS
+0xC5E2	0xD184	#HANGUL SYLLABLE THIEUTH YE
+0xC5E3	0xD188	#HANGUL SYLLABLE THIEUTH YE NIEUN
+0xC5E4	0xD1A0	#HANGUL SYLLABLE THIEUTH O
+0xC5E5	0xD1A1	#HANGUL SYLLABLE THIEUTH O KIYEOK
+0xC5E6	0xD1A4	#HANGUL SYLLABLE THIEUTH O NIEUN
+0xC5E7	0xD1A8	#HANGUL SYLLABLE THIEUTH O RIEUL
+0xC5E8	0xD1B0	#HANGUL SYLLABLE THIEUTH O MIEUM
+0xC5E9	0xD1B1	#HANGUL SYLLABLE THIEUTH O PIEUP
+0xC5EA	0xD1B3	#HANGUL SYLLABLE THIEUTH O SIOS
+0xC5EB	0xD1B5	#HANGUL SYLLABLE THIEUTH O IEUNG
+0xC5EC	0xD1BA	#HANGUL SYLLABLE THIEUTH O PHIEUPH
+0xC5ED	0xD1BC	#HANGUL SYLLABLE THIEUTH WA
+0xC5EE	0xD1C0	#HANGUL SYLLABLE THIEUTH WA NIEUN
+0xC5EF	0xD1D8	#HANGUL SYLLABLE THIEUTH WAE
+0xC5F0	0xD1F4	#HANGUL SYLLABLE THIEUTH OE
+0xC5F1	0xD1F8	#HANGUL SYLLABLE THIEUTH OE NIEUN
+0xC5F2	0xD207	#HANGUL SYLLABLE THIEUTH OE SIOS
+0xC5F3	0xD209	#HANGUL SYLLABLE THIEUTH OE IEUNG
+0xC5F4	0xD210	#HANGUL SYLLABLE THIEUTH YO
+0xC5F5	0xD22C	#HANGUL SYLLABLE THIEUTH U
+0xC5F6	0xD22D	#HANGUL SYLLABLE THIEUTH U KIYEOK
+0xC5F7	0xD230	#HANGUL SYLLABLE THIEUTH U NIEUN
+0xC5F8	0xD234	#HANGUL SYLLABLE THIEUTH U RIEUL
+0xC5F9	0xD23C	#HANGUL SYLLABLE THIEUTH U MIEUM
+0xC5FA	0xD23D	#HANGUL SYLLABLE THIEUTH U PIEUP
+0xC5FB	0xD23F	#HANGUL SYLLABLE THIEUTH U SIOS
+0xC5FC	0xD241	#HANGUL SYLLABLE THIEUTH U IEUNG
+0xC5FD	0xD248	#HANGUL SYLLABLE THIEUTH WEO
+0xC5FE	0xD25C	#HANGUL SYLLABLE THIEUTH WEO SSANGSIOS
+0xC641	0xD78D	#HANGUL SYLLABLE HIEUH I NIEUNCIEUC
+0xC642	0xD78E	#HANGUL SYLLABLE HIEUH I NIEUNHIEUH
+0xC643	0xD78F	#HANGUL SYLLABLE HIEUH I TIKEUT
+0xC644	0xD791	#HANGUL SYLLABLE HIEUH I RIEULKIYEOK
+0xC645	0xD792	#HANGUL SYLLABLE HIEUH I RIEULMIEUM
+0xC646	0xD793	#HANGUL SYLLABLE HIEUH I RIEULPIEUP
+0xC647	0xD794	#HANGUL SYLLABLE HIEUH I RIEULSIOS
+0xC648	0xD795	#HANGUL SYLLABLE HIEUH I RIEULTHIEUTH
+0xC649	0xD796	#HANGUL SYLLABLE HIEUH I RIEULPHIEUPH
+0xC64A	0xD797	#HANGUL SYLLABLE HIEUH I RIEULHIEUH
+0xC64B	0xD79A	#HANGUL SYLLABLE HIEUH I PIEUPSIOS
+0xC64C	0xD79C	#HANGUL SYLLABLE HIEUH I SSANGSIOS
+0xC64D	0xD79E	#HANGUL SYLLABLE HIEUH I CIEUC
+0xC64E	0xD79F	#HANGUL SYLLABLE HIEUH I CHIEUCH
+0xC64F	0xD7A0	#HANGUL SYLLABLE HIEUH I KHIEUKH
+0xC650	0xD7A1	#HANGUL SYLLABLE HIEUH I THIEUTH
+0xC651	0xD7A2	#HANGUL SYLLABLE HIEUH I PHIEUPH
+0xC652	0xD7A3	#HANGUL SYLLABLE HIEUH I HIEUH
+0xC6A1	0xD264	#HANGUL SYLLABLE THIEUTH WE
+0xC6A2	0xD280	#HANGUL SYLLABLE THIEUTH WI
+0xC6A3	0xD281	#HANGUL SYLLABLE THIEUTH WI KIYEOK
+0xC6A4	0xD284	#HANGUL SYLLABLE THIEUTH WI NIEUN
+0xC6A5	0xD288	#HANGUL SYLLABLE THIEUTH WI RIEUL
+0xC6A6	0xD290	#HANGUL SYLLABLE THIEUTH WI MIEUM
+0xC6A7	0xD291	#HANGUL SYLLABLE THIEUTH WI PIEUP
+0xC6A8	0xD295	#HANGUL SYLLABLE THIEUTH WI IEUNG
+0xC6A9	0xD29C	#HANGUL SYLLABLE THIEUTH YU
+0xC6AA	0xD2A0	#HANGUL SYLLABLE THIEUTH YU NIEUN
+0xC6AB	0xD2A4	#HANGUL SYLLABLE THIEUTH YU RIEUL
+0xC6AC	0xD2AC	#HANGUL SYLLABLE THIEUTH YU MIEUM
+0xC6AD	0xD2B1	#HANGUL SYLLABLE THIEUTH YU IEUNG
+0xC6AE	0xD2B8	#HANGUL SYLLABLE THIEUTH EU
+0xC6AF	0xD2B9	#HANGUL SYLLABLE THIEUTH EU KIYEOK
+0xC6B0	0xD2BC	#HANGUL SYLLABLE THIEUTH EU NIEUN
+0xC6B1	0xD2BF	#HANGUL SYLLABLE THIEUTH EU TIKEUT
+0xC6B2	0xD2C0	#HANGUL SYLLABLE THIEUTH EU RIEUL
+0xC6B3	0xD2C2	#HANGUL SYLLABLE THIEUTH EU RIEULMIEUM
+0xC6B4	0xD2C8	#HANGUL SYLLABLE THIEUTH EU MIEUM
+0xC6B5	0xD2C9	#HANGUL SYLLABLE THIEUTH EU PIEUP
+0xC6B6	0xD2CB	#HANGUL SYLLABLE THIEUTH EU SIOS
+0xC6B7	0xD2D4	#HANGUL SYLLABLE THIEUTH YI
+0xC6B8	0xD2D8	#HANGUL SYLLABLE THIEUTH YI NIEUN
+0xC6B9	0xD2DC	#HANGUL SYLLABLE THIEUTH YI RIEUL
+0xC6BA	0xD2E4	#HANGUL SYLLABLE THIEUTH YI MIEUM
+0xC6BB	0xD2E5	#HANGUL SYLLABLE THIEUTH YI PIEUP
+0xC6BC	0xD2F0	#HANGUL SYLLABLE THIEUTH I
+0xC6BD	0xD2F1	#HANGUL SYLLABLE THIEUTH I KIYEOK
+0xC6BE	0xD2F4	#HANGUL SYLLABLE THIEUTH I NIEUN
+0xC6BF	0xD2F8	#HANGUL SYLLABLE THIEUTH I RIEUL
+0xC6C0	0xD300	#HANGUL SYLLABLE THIEUTH I MIEUM
+0xC6C1	0xD301	#HANGUL SYLLABLE THIEUTH I PIEUP
+0xC6C2	0xD303	#HANGUL SYLLABLE THIEUTH I SIOS
+0xC6C3	0xD305	#HANGUL SYLLABLE THIEUTH I IEUNG
+0xC6C4	0xD30C	#HANGUL SYLLABLE PHIEUPH A
+0xC6C5	0xD30D	#HANGUL SYLLABLE PHIEUPH A KIYEOK
+0xC6C6	0xD30E	#HANGUL SYLLABLE PHIEUPH A SSANGKIYEOK
+0xC6C7	0xD310	#HANGUL SYLLABLE PHIEUPH A NIEUN
+0xC6C8	0xD314	#HANGUL SYLLABLE PHIEUPH A RIEUL
+0xC6C9	0xD316	#HANGUL SYLLABLE PHIEUPH A RIEULMIEUM
+0xC6CA	0xD31C	#HANGUL SYLLABLE PHIEUPH A MIEUM
+0xC6CB	0xD31D	#HANGUL SYLLABLE PHIEUPH A PIEUP
+0xC6CC	0xD31F	#HANGUL SYLLABLE PHIEUPH A SIOS
+0xC6CD	0xD320	#HANGUL SYLLABLE PHIEUPH A SSANGSIOS
+0xC6CE	0xD321	#HANGUL SYLLABLE PHIEUPH A IEUNG
+0xC6CF	0xD325	#HANGUL SYLLABLE PHIEUPH A THIEUTH
+0xC6D0	0xD328	#HANGUL SYLLABLE PHIEUPH AE
+0xC6D1	0xD329	#HANGUL SYLLABLE PHIEUPH AE KIYEOK
+0xC6D2	0xD32C	#HANGUL SYLLABLE PHIEUPH AE NIEUN
+0xC6D3	0xD330	#HANGUL SYLLABLE PHIEUPH AE RIEUL
+0xC6D4	0xD338	#HANGUL SYLLABLE PHIEUPH AE MIEUM
+0xC6D5	0xD339	#HANGUL SYLLABLE PHIEUPH AE PIEUP
+0xC6D6	0xD33B	#HANGUL SYLLABLE PHIEUPH AE SIOS
+0xC6D7	0xD33C	#HANGUL SYLLABLE PHIEUPH AE SSANGSIOS
+0xC6D8	0xD33D	#HANGUL SYLLABLE PHIEUPH AE IEUNG
+0xC6D9	0xD344	#HANGUL SYLLABLE PHIEUPH YA
+0xC6DA	0xD345	#HANGUL SYLLABLE PHIEUPH YA KIYEOK
+0xC6DB	0xD37C	#HANGUL SYLLABLE PHIEUPH EO
+0xC6DC	0xD37D	#HANGUL SYLLABLE PHIEUPH EO KIYEOK
+0xC6DD	0xD380	#HANGUL SYLLABLE PHIEUPH EO NIEUN
+0xC6DE	0xD384	#HANGUL SYLLABLE PHIEUPH EO RIEUL
+0xC6DF	0xD38C	#HANGUL SYLLABLE PHIEUPH EO MIEUM
+0xC6E0	0xD38D	#HANGUL SYLLABLE PHIEUPH EO PIEUP
+0xC6E1	0xD38F	#HANGUL SYLLABLE PHIEUPH EO SIOS
+0xC6E2	0xD390	#HANGUL SYLLABLE PHIEUPH EO SSANGSIOS
+0xC6E3	0xD391	#HANGUL SYLLABLE PHIEUPH EO IEUNG
+0xC6E4	0xD398	#HANGUL SYLLABLE PHIEUPH E
+0xC6E5	0xD399	#HANGUL SYLLABLE PHIEUPH E KIYEOK
+0xC6E6	0xD39C	#HANGUL SYLLABLE PHIEUPH E NIEUN
+0xC6E7	0xD3A0	#HANGUL SYLLABLE PHIEUPH E RIEUL
+0xC6E8	0xD3A8	#HANGUL SYLLABLE PHIEUPH E MIEUM
+0xC6E9	0xD3A9	#HANGUL SYLLABLE PHIEUPH E PIEUP
+0xC6EA	0xD3AB	#HANGUL SYLLABLE PHIEUPH E SIOS
+0xC6EB	0xD3AD	#HANGUL SYLLABLE PHIEUPH E IEUNG
+0xC6EC	0xD3B4	#HANGUL SYLLABLE PHIEUPH YEO
+0xC6ED	0xD3B8	#HANGUL SYLLABLE PHIEUPH YEO NIEUN
+0xC6EE	0xD3BC	#HANGUL SYLLABLE PHIEUPH YEO RIEUL
+0xC6EF	0xD3C4	#HANGUL SYLLABLE PHIEUPH YEO MIEUM
+0xC6F0	0xD3C5	#HANGUL SYLLABLE PHIEUPH YEO PIEUP
+0xC6F1	0xD3C8	#HANGUL SYLLABLE PHIEUPH YEO SSANGSIOS
+0xC6F2	0xD3C9	#HANGUL SYLLABLE PHIEUPH YEO IEUNG
+0xC6F3	0xD3D0	#HANGUL SYLLABLE PHIEUPH YE
+0xC6F4	0xD3D8	#HANGUL SYLLABLE PHIEUPH YE RIEUL
+0xC6F5	0xD3E1	#HANGUL SYLLABLE PHIEUPH YE PIEUP
+0xC6F6	0xD3E3	#HANGUL SYLLABLE PHIEUPH YE SIOS
+0xC6F7	0xD3EC	#HANGUL SYLLABLE PHIEUPH O
+0xC6F8	0xD3ED	#HANGUL SYLLABLE PHIEUPH O KIYEOK
+0xC6F9	0xD3F0	#HANGUL SYLLABLE PHIEUPH O NIEUN
+0xC6FA	0xD3F4	#HANGUL SYLLABLE PHIEUPH O RIEUL
+0xC6FB	0xD3FC	#HANGUL SYLLABLE PHIEUPH O MIEUM
+0xC6FC	0xD3FD	#HANGUL SYLLABLE PHIEUPH O PIEUP
+0xC6FD	0xD3FF	#HANGUL SYLLABLE PHIEUPH O SIOS
+0xC6FE	0xD401	#HANGUL SYLLABLE PHIEUPH O IEUNG
+0xC7A1	0xD408	#HANGUL SYLLABLE PHIEUPH WA
+0xC7A2	0xD41D	#HANGUL SYLLABLE PHIEUPH WA IEUNG
+0xC7A3	0xD440	#HANGUL SYLLABLE PHIEUPH OE
+0xC7A4	0xD444	#HANGUL SYLLABLE PHIEUPH OE NIEUN
+0xC7A5	0xD45C	#HANGUL SYLLABLE PHIEUPH YO
+0xC7A6	0xD460	#HANGUL SYLLABLE PHIEUPH YO NIEUN
+0xC7A7	0xD464	#HANGUL SYLLABLE PHIEUPH YO RIEUL
+0xC7A8	0xD46D	#HANGUL SYLLABLE PHIEUPH YO PIEUP
+0xC7A9	0xD46F	#HANGUL SYLLABLE PHIEUPH YO SIOS
+0xC7AA	0xD478	#HANGUL SYLLABLE PHIEUPH U
+0xC7AB	0xD479	#HANGUL SYLLABLE PHIEUPH U KIYEOK
+0xC7AC	0xD47C	#HANGUL SYLLABLE PHIEUPH U NIEUN
+0xC7AD	0xD47F	#HANGUL SYLLABLE PHIEUPH U TIKEUT
+0xC7AE	0xD480	#HANGUL SYLLABLE PHIEUPH U RIEUL
+0xC7AF	0xD482	#HANGUL SYLLABLE PHIEUPH U RIEULMIEUM
+0xC7B0	0xD488	#HANGUL SYLLABLE PHIEUPH U MIEUM
+0xC7B1	0xD489	#HANGUL SYLLABLE PHIEUPH U PIEUP
+0xC7B2	0xD48B	#HANGUL SYLLABLE PHIEUPH U SIOS
+0xC7B3	0xD48D	#HANGUL SYLLABLE PHIEUPH U IEUNG
+0xC7B4	0xD494	#HANGUL SYLLABLE PHIEUPH WEO
+0xC7B5	0xD4A9	#HANGUL SYLLABLE PHIEUPH WEO IEUNG
+0xC7B6	0xD4CC	#HANGUL SYLLABLE PHIEUPH WI
+0xC7B7	0xD4D0	#HANGUL SYLLABLE PHIEUPH WI NIEUN
+0xC7B8	0xD4D4	#HANGUL SYLLABLE PHIEUPH WI RIEUL
+0xC7B9	0xD4DC	#HANGUL SYLLABLE PHIEUPH WI MIEUM
+0xC7BA	0xD4DF	#HANGUL SYLLABLE PHIEUPH WI SIOS
+0xC7BB	0xD4E8	#HANGUL SYLLABLE PHIEUPH YU
+0xC7BC	0xD4EC	#HANGUL SYLLABLE PHIEUPH YU NIEUN
+0xC7BD	0xD4F0	#HANGUL SYLLABLE PHIEUPH YU RIEUL
+0xC7BE	0xD4F8	#HANGUL SYLLABLE PHIEUPH YU MIEUM
+0xC7BF	0xD4FB	#HANGUL SYLLABLE PHIEUPH YU SIOS
+0xC7C0	0xD4FD	#HANGUL SYLLABLE PHIEUPH YU IEUNG
+0xC7C1	0xD504	#HANGUL SYLLABLE PHIEUPH EU
+0xC7C2	0xD508	#HANGUL SYLLABLE PHIEUPH EU NIEUN
+0xC7C3	0xD50C	#HANGUL SYLLABLE PHIEUPH EU RIEUL
+0xC7C4	0xD514	#HANGUL SYLLABLE PHIEUPH EU MIEUM
+0xC7C5	0xD515	#HANGUL SYLLABLE PHIEUPH EU PIEUP
+0xC7C6	0xD517	#HANGUL SYLLABLE PHIEUPH EU SIOS
+0xC7C7	0xD53C	#HANGUL SYLLABLE PHIEUPH I
+0xC7C8	0xD53D	#HANGUL SYLLABLE PHIEUPH I KIYEOK
+0xC7C9	0xD540	#HANGUL SYLLABLE PHIEUPH I NIEUN
+0xC7CA	0xD544	#HANGUL SYLLABLE PHIEUPH I RIEUL
+0xC7CB	0xD54C	#HANGUL SYLLABLE PHIEUPH I MIEUM
+0xC7CC	0xD54D	#HANGUL SYLLABLE PHIEUPH I PIEUP
+0xC7CD	0xD54F	#HANGUL SYLLABLE PHIEUPH I SIOS
+0xC7CE	0xD551	#HANGUL SYLLABLE PHIEUPH I IEUNG
+0xC7CF	0xD558	#HANGUL SYLLABLE HIEUH A
+0xC7D0	0xD559	#HANGUL SYLLABLE HIEUH A KIYEOK
+0xC7D1	0xD55C	#HANGUL SYLLABLE HIEUH A NIEUN
+0xC7D2	0xD560	#HANGUL SYLLABLE HIEUH A RIEUL
+0xC7D3	0xD565	#HANGUL SYLLABLE HIEUH A RIEULTHIEUTH
+0xC7D4	0xD568	#HANGUL SYLLABLE HIEUH A MIEUM
+0xC7D5	0xD569	#HANGUL SYLLABLE HIEUH A PIEUP
+0xC7D6	0xD56B	#HANGUL SYLLABLE HIEUH A SIOS
+0xC7D7	0xD56D	#HANGUL SYLLABLE HIEUH A IEUNG
+0xC7D8	0xD574	#HANGUL SYLLABLE HIEUH AE
+0xC7D9	0xD575	#HANGUL SYLLABLE HIEUH AE KIYEOK
+0xC7DA	0xD578	#HANGUL SYLLABLE HIEUH AE NIEUN
+0xC7DB	0xD57C	#HANGUL SYLLABLE HIEUH AE RIEUL
+0xC7DC	0xD584	#HANGUL SYLLABLE HIEUH AE MIEUM
+0xC7DD	0xD585	#HANGUL SYLLABLE HIEUH AE PIEUP
+0xC7DE	0xD587	#HANGUL SYLLABLE HIEUH AE SIOS
+0xC7DF	0xD588	#HANGUL SYLLABLE HIEUH AE SSANGSIOS
+0xC7E0	0xD589	#HANGUL SYLLABLE HIEUH AE IEUNG
+0xC7E1	0xD590	#HANGUL SYLLABLE HIEUH YA
+0xC7E2	0xD5A5	#HANGUL SYLLABLE HIEUH YA IEUNG
+0xC7E3	0xD5C8	#HANGUL SYLLABLE HIEUH EO
+0xC7E4	0xD5C9	#HANGUL SYLLABLE HIEUH EO KIYEOK
+0xC7E5	0xD5CC	#HANGUL SYLLABLE HIEUH EO NIEUN
+0xC7E6	0xD5D0	#HANGUL SYLLABLE HIEUH EO RIEUL
+0xC7E7	0xD5D2	#HANGUL SYLLABLE HIEUH EO RIEULMIEUM
+0xC7E8	0xD5D8	#HANGUL SYLLABLE HIEUH EO MIEUM
+0xC7E9	0xD5D9	#HANGUL SYLLABLE HIEUH EO PIEUP
+0xC7EA	0xD5DB	#HANGUL SYLLABLE HIEUH EO SIOS
+0xC7EB	0xD5DD	#HANGUL SYLLABLE HIEUH EO IEUNG
+0xC7EC	0xD5E4	#HANGUL SYLLABLE HIEUH E
+0xC7ED	0xD5E5	#HANGUL SYLLABLE HIEUH E KIYEOK
+0xC7EE	0xD5E8	#HANGUL SYLLABLE HIEUH E NIEUN
+0xC7EF	0xD5EC	#HANGUL SYLLABLE HIEUH E RIEUL
+0xC7F0	0xD5F4	#HANGUL SYLLABLE HIEUH E MIEUM
+0xC7F1	0xD5F5	#HANGUL SYLLABLE HIEUH E PIEUP
+0xC7F2	0xD5F7	#HANGUL SYLLABLE HIEUH E SIOS
+0xC7F3	0xD5F9	#HANGUL SYLLABLE HIEUH E IEUNG
+0xC7F4	0xD600	#HANGUL SYLLABLE HIEUH YEO
+0xC7F5	0xD601	#HANGUL SYLLABLE HIEUH YEO KIYEOK
+0xC7F6	0xD604	#HANGUL SYLLABLE HIEUH YEO NIEUN
+0xC7F7	0xD608	#HANGUL SYLLABLE HIEUH YEO RIEUL
+0xC7F8	0xD610	#HANGUL SYLLABLE HIEUH YEO MIEUM
+0xC7F9	0xD611	#HANGUL SYLLABLE HIEUH YEO PIEUP
+0xC7FA	0xD613	#HANGUL SYLLABLE HIEUH YEO SIOS
+0xC7FB	0xD614	#HANGUL SYLLABLE HIEUH YEO SSANGSIOS
+0xC7FC	0xD615	#HANGUL SYLLABLE HIEUH YEO IEUNG
+0xC7FD	0xD61C	#HANGUL SYLLABLE HIEUH YE
+0xC7FE	0xD620	#HANGUL SYLLABLE HIEUH YE NIEUN
+0xC8A1	0xD624	#HANGUL SYLLABLE HIEUH YE RIEUL
+0xC8A2	0xD62D	#HANGUL SYLLABLE HIEUH YE PIEUP
+0xC8A3	0xD638	#HANGUL SYLLABLE HIEUH O
+0xC8A4	0xD639	#HANGUL SYLLABLE HIEUH O KIYEOK
+0xC8A5	0xD63C	#HANGUL SYLLABLE HIEUH O NIEUN
+0xC8A6	0xD640	#HANGUL SYLLABLE HIEUH O RIEUL
+0xC8A7	0xD645	#HANGUL SYLLABLE HIEUH O RIEULTHIEUTH
+0xC8A8	0xD648	#HANGUL SYLLABLE HIEUH O MIEUM
+0xC8A9	0xD649	#HANGUL SYLLABLE HIEUH O PIEUP
+0xC8AA	0xD64B	#HANGUL SYLLABLE HIEUH O SIOS
+0xC8AB	0xD64D	#HANGUL SYLLABLE HIEUH O IEUNG
+0xC8AC	0xD651	#HANGUL SYLLABLE HIEUH O THIEUTH
+0xC8AD	0xD654	#HANGUL SYLLABLE HIEUH WA
+0xC8AE	0xD655	#HANGUL SYLLABLE HIEUH WA KIYEOK
+0xC8AF	0xD658	#HANGUL SYLLABLE HIEUH WA NIEUN
+0xC8B0	0xD65C	#HANGUL SYLLABLE HIEUH WA RIEUL
+0xC8B1	0xD667	#HANGUL SYLLABLE HIEUH WA SIOS
+0xC8B2	0xD669	#HANGUL SYLLABLE HIEUH WA IEUNG
+0xC8B3	0xD670	#HANGUL SYLLABLE HIEUH WAE
+0xC8B4	0xD671	#HANGUL SYLLABLE HIEUH WAE KIYEOK
+0xC8B5	0xD674	#HANGUL SYLLABLE HIEUH WAE NIEUN
+0xC8B6	0xD683	#HANGUL SYLLABLE HIEUH WAE SIOS
+0xC8B7	0xD685	#HANGUL SYLLABLE HIEUH WAE IEUNG
+0xC8B8	0xD68C	#HANGUL SYLLABLE HIEUH OE
+0xC8B9	0xD68D	#HANGUL SYLLABLE HIEUH OE KIYEOK
+0xC8BA	0xD690	#HANGUL SYLLABLE HIEUH OE NIEUN
+0xC8BB	0xD694	#HANGUL SYLLABLE HIEUH OE RIEUL
+0xC8BC	0xD69D	#HANGUL SYLLABLE HIEUH OE PIEUP
+0xC8BD	0xD69F	#HANGUL SYLLABLE HIEUH OE SIOS
+0xC8BE	0xD6A1	#HANGUL SYLLABLE HIEUH OE IEUNG
+0xC8BF	0xD6A8	#HANGUL SYLLABLE HIEUH YO
+0xC8C0	0xD6AC	#HANGUL SYLLABLE HIEUH YO NIEUN
+0xC8C1	0xD6B0	#HANGUL SYLLABLE HIEUH YO RIEUL
+0xC8C2	0xD6B9	#HANGUL SYLLABLE HIEUH YO PIEUP
+0xC8C3	0xD6BB	#HANGUL SYLLABLE HIEUH YO SIOS
+0xC8C4	0xD6C4	#HANGUL SYLLABLE HIEUH U
+0xC8C5	0xD6C5	#HANGUL SYLLABLE HIEUH U KIYEOK
+0xC8C6	0xD6C8	#HANGUL SYLLABLE HIEUH U NIEUN
+0xC8C7	0xD6CC	#HANGUL SYLLABLE HIEUH U RIEUL
+0xC8C8	0xD6D1	#HANGUL SYLLABLE HIEUH U RIEULTHIEUTH
+0xC8C9	0xD6D4	#HANGUL SYLLABLE HIEUH U MIEUM
+0xC8CA	0xD6D7	#HANGUL SYLLABLE HIEUH U SIOS
+0xC8CB	0xD6D9	#HANGUL SYLLABLE HIEUH U IEUNG
+0xC8CC	0xD6E0	#HANGUL SYLLABLE HIEUH WEO
+0xC8CD	0xD6E4	#HANGUL SYLLABLE HIEUH WEO NIEUN
+0xC8CE	0xD6E8	#HANGUL SYLLABLE HIEUH WEO RIEUL
+0xC8CF	0xD6F0	#HANGUL SYLLABLE HIEUH WEO MIEUM
+0xC8D0	0xD6F5	#HANGUL SYLLABLE HIEUH WEO IEUNG
+0xC8D1	0xD6FC	#HANGUL SYLLABLE HIEUH WE
+0xC8D2	0xD6FD	#HANGUL SYLLABLE HIEUH WE KIYEOK
+0xC8D3	0xD700	#HANGUL SYLLABLE HIEUH WE NIEUN
+0xC8D4	0xD704	#HANGUL SYLLABLE HIEUH WE RIEUL
+0xC8D5	0xD711	#HANGUL SYLLABLE HIEUH WE IEUNG
+0xC8D6	0xD718	#HANGUL SYLLABLE HIEUH WI
+0xC8D7	0xD719	#HANGUL SYLLABLE HIEUH WI KIYEOK
+0xC8D8	0xD71C	#HANGUL SYLLABLE HIEUH WI NIEUN
+0xC8D9	0xD720	#HANGUL SYLLABLE HIEUH WI RIEUL
+0xC8DA	0xD728	#HANGUL SYLLABLE HIEUH WI MIEUM
+0xC8DB	0xD729	#HANGUL SYLLABLE HIEUH WI PIEUP
+0xC8DC	0xD72B	#HANGUL SYLLABLE HIEUH WI SIOS
+0xC8DD	0xD72D	#HANGUL SYLLABLE HIEUH WI IEUNG
+0xC8DE	0xD734	#HANGUL SYLLABLE HIEUH YU
+0xC8DF	0xD735	#HANGUL SYLLABLE HIEUH YU KIYEOK
+0xC8E0	0xD738	#HANGUL SYLLABLE HIEUH YU NIEUN
+0xC8E1	0xD73C	#HANGUL SYLLABLE HIEUH YU RIEUL
+0xC8E2	0xD744	#HANGUL SYLLABLE HIEUH YU MIEUM
+0xC8E3	0xD747	#HANGUL SYLLABLE HIEUH YU SIOS
+0xC8E4	0xD749	#HANGUL SYLLABLE HIEUH YU IEUNG
+0xC8E5	0xD750	#HANGUL SYLLABLE HIEUH EU
+0xC8E6	0xD751	#HANGUL SYLLABLE HIEUH EU KIYEOK
+0xC8E7	0xD754	#HANGUL SYLLABLE HIEUH EU NIEUN
+0xC8E8	0xD756	#HANGUL SYLLABLE HIEUH EU NIEUNHIEUH
+0xC8E9	0xD757	#HANGUL SYLLABLE HIEUH EU TIKEUT
+0xC8EA	0xD758	#HANGUL SYLLABLE HIEUH EU RIEUL
+0xC8EB	0xD759	#HANGUL SYLLABLE HIEUH EU RIEULKIYEOK
+0xC8EC	0xD760	#HANGUL SYLLABLE HIEUH EU MIEUM
+0xC8ED	0xD761	#HANGUL SYLLABLE HIEUH EU PIEUP
+0xC8EE	0xD763	#HANGUL SYLLABLE HIEUH EU SIOS
+0xC8EF	0xD765	#HANGUL SYLLABLE HIEUH EU IEUNG
+0xC8F0	0xD769	#HANGUL SYLLABLE HIEUH EU THIEUTH
+0xC8F1	0xD76C	#HANGUL SYLLABLE HIEUH YI
+0xC8F2	0xD770	#HANGUL SYLLABLE HIEUH YI NIEUN
+0xC8F3	0xD774	#HANGUL SYLLABLE HIEUH YI RIEUL
+0xC8F4	0xD77C	#HANGUL SYLLABLE HIEUH YI MIEUM
+0xC8F5	0xD77D	#HANGUL SYLLABLE HIEUH YI PIEUP
+0xC8F6	0xD781	#HANGUL SYLLABLE HIEUH YI IEUNG
+0xC8F7	0xD788	#HANGUL SYLLABLE HIEUH I
+0xC8F8	0xD789	#HANGUL SYLLABLE HIEUH I KIYEOK
+0xC8F9	0xD78C	#HANGUL SYLLABLE HIEUH I NIEUN
+0xC8FA	0xD790	#HANGUL SYLLABLE HIEUH I RIEUL
+0xC8FB	0xD798	#HANGUL SYLLABLE HIEUH I MIEUM
+0xC8FC	0xD799	#HANGUL SYLLABLE HIEUH I PIEUP
+0xC8FD	0xD79B	#HANGUL SYLLABLE HIEUH I SIOS
+0xC8FE	0xD79D	#HANGUL SYLLABLE HIEUH I IEUNG
+0xCAA1	0x4F3D	#CJK UNIFIED IDEOGRAPH
+0xCAA2	0x4F73	#CJK UNIFIED IDEOGRAPH
+0xCAA3	0x5047	#CJK UNIFIED IDEOGRAPH
+0xCAA4	0x50F9	#CJK UNIFIED IDEOGRAPH
+0xCAA5	0x52A0	#CJK UNIFIED IDEOGRAPH
+0xCAA6	0x53EF	#CJK UNIFIED IDEOGRAPH
+0xCAA7	0x5475	#CJK UNIFIED IDEOGRAPH
+0xCAA8	0x54E5	#CJK UNIFIED IDEOGRAPH
+0xCAA9	0x5609	#CJK UNIFIED IDEOGRAPH
+0xCAAA	0x5AC1	#CJK UNIFIED IDEOGRAPH
+0xCAAB	0x5BB6	#CJK UNIFIED IDEOGRAPH
+0xCAAC	0x6687	#CJK UNIFIED IDEOGRAPH
+0xCAAD	0x67B6	#CJK UNIFIED IDEOGRAPH
+0xCAAE	0x67B7	#CJK UNIFIED IDEOGRAPH
+0xCAAF	0x67EF	#CJK UNIFIED IDEOGRAPH
+0xCAB0	0x6B4C	#CJK UNIFIED IDEOGRAPH
+0xCAB1	0x73C2	#CJK UNIFIED IDEOGRAPH
+0xCAB2	0x75C2	#CJK UNIFIED IDEOGRAPH
+0xCAB3	0x7A3C	#CJK UNIFIED IDEOGRAPH
+0xCAB4	0x82DB	#CJK UNIFIED IDEOGRAPH
+0xCAB5	0x8304	#CJK UNIFIED IDEOGRAPH
+0xCAB6	0x8857	#CJK UNIFIED IDEOGRAPH
+0xCAB7	0x8888	#CJK UNIFIED IDEOGRAPH
+0xCAB8	0x8A36	#CJK UNIFIED IDEOGRAPH
+0xCAB9	0x8CC8	#CJK UNIFIED IDEOGRAPH
+0xCABA	0x8DCF	#CJK UNIFIED IDEOGRAPH
+0xCABB	0x8EFB	#CJK UNIFIED IDEOGRAPH
+0xCABC	0x8FE6	#CJK UNIFIED IDEOGRAPH
+0xCABD	0x99D5	#CJK UNIFIED IDEOGRAPH
+0xCABE	0x523B	#CJK UNIFIED IDEOGRAPH
+0xCABF	0x5374	#CJK UNIFIED IDEOGRAPH
+0xCAC0	0x5404	#CJK UNIFIED IDEOGRAPH
+0xCAC1	0x606A	#CJK UNIFIED IDEOGRAPH
+0xCAC2	0x6164	#CJK UNIFIED IDEOGRAPH
+0xCAC3	0x6BBC	#CJK UNIFIED IDEOGRAPH
+0xCAC4	0x73CF	#CJK UNIFIED IDEOGRAPH
+0xCAC5	0x811A	#CJK UNIFIED IDEOGRAPH
+0xCAC6	0x89BA	#CJK UNIFIED IDEOGRAPH
+0xCAC7	0x89D2	#CJK UNIFIED IDEOGRAPH
+0xCAC8	0x95A3	#CJK UNIFIED IDEOGRAPH
+0xCAC9	0x4F83	#CJK UNIFIED IDEOGRAPH
+0xCACA	0x520A	#CJK UNIFIED IDEOGRAPH
+0xCACB	0x58BE	#CJK UNIFIED IDEOGRAPH
+0xCACC	0x5978	#CJK UNIFIED IDEOGRAPH
+0xCACD	0x59E6	#CJK UNIFIED IDEOGRAPH
+0xCACE	0x5E72	#CJK UNIFIED IDEOGRAPH
+0xCACF	0x5E79	#CJK UNIFIED IDEOGRAPH
+0xCAD0	0x61C7	#CJK UNIFIED IDEOGRAPH
+0xCAD1	0x63C0	#CJK UNIFIED IDEOGRAPH
+0xCAD2	0x6746	#CJK UNIFIED IDEOGRAPH
+0xCAD3	0x67EC	#CJK UNIFIED IDEOGRAPH
+0xCAD4	0x687F	#CJK UNIFIED IDEOGRAPH
+0xCAD5	0x6F97	#CJK UNIFIED IDEOGRAPH
+0xCAD6	0x764E	#CJK UNIFIED IDEOGRAPH
+0xCAD7	0x770B	#CJK UNIFIED IDEOGRAPH
+0xCAD8	0x78F5	#CJK UNIFIED IDEOGRAPH
+0xCAD9	0x7A08	#CJK UNIFIED IDEOGRAPH
+0xCADA	0x7AFF	#CJK UNIFIED IDEOGRAPH
+0xCADB	0x7C21	#CJK UNIFIED IDEOGRAPH
+0xCADC	0x809D	#CJK UNIFIED IDEOGRAPH
+0xCADD	0x826E	#CJK UNIFIED IDEOGRAPH
+0xCADE	0x8271	#CJK UNIFIED IDEOGRAPH
+0xCADF	0x8AEB	#CJK UNIFIED IDEOGRAPH
+0xCAE0	0x9593	#CJK UNIFIED IDEOGRAPH
+0xCAE1	0x4E6B	#CJK UNIFIED IDEOGRAPH
+0xCAE2	0x559D	#CJK UNIFIED IDEOGRAPH
+0xCAE3	0x66F7	#CJK UNIFIED IDEOGRAPH
+0xCAE4	0x6E34	#CJK UNIFIED IDEOGRAPH
+0xCAE5	0x78A3	#CJK UNIFIED IDEOGRAPH
+0xCAE6	0x7AED	#CJK UNIFIED IDEOGRAPH
+0xCAE7	0x845B	#CJK UNIFIED IDEOGRAPH
+0xCAE8	0x8910	#CJK UNIFIED IDEOGRAPH
+0xCAE9	0x874E	#CJK UNIFIED IDEOGRAPH
+0xCAEA	0x97A8	#CJK UNIFIED IDEOGRAPH
+0xCAEB	0x52D8	#CJK UNIFIED IDEOGRAPH
+0xCAEC	0x574E	#CJK UNIFIED IDEOGRAPH
+0xCAED	0x582A	#CJK UNIFIED IDEOGRAPH
+0xCAEE	0x5D4C	#CJK UNIFIED IDEOGRAPH
+0xCAEF	0x611F	#CJK UNIFIED IDEOGRAPH
+0xCAF0	0x61BE	#CJK UNIFIED IDEOGRAPH
+0xCAF1	0x6221	#CJK UNIFIED IDEOGRAPH
+0xCAF2	0x6562	#CJK UNIFIED IDEOGRAPH
+0xCAF3	0x67D1	#CJK UNIFIED IDEOGRAPH
+0xCAF4	0x6A44	#CJK UNIFIED IDEOGRAPH
+0xCAF5	0x6E1B	#CJK UNIFIED IDEOGRAPH
+0xCAF6	0x7518	#CJK UNIFIED IDEOGRAPH
+0xCAF7	0x75B3	#CJK UNIFIED IDEOGRAPH
+0xCAF8	0x76E3	#CJK UNIFIED IDEOGRAPH
+0xCAF9	0x77B0	#CJK UNIFIED IDEOGRAPH
+0xCAFA	0x7D3A	#CJK UNIFIED IDEOGRAPH
+0xCAFB	0x90AF	#CJK UNIFIED IDEOGRAPH
+0xCAFC	0x9451	#CJK UNIFIED IDEOGRAPH
+0xCAFD	0x9452	#CJK UNIFIED IDEOGRAPH
+0xCAFE	0x9F95	#CJK UNIFIED IDEOGRAPH
+0xCBA1	0x5323	#CJK UNIFIED IDEOGRAPH
+0xCBA2	0x5CAC	#CJK UNIFIED IDEOGRAPH
+0xCBA3	0x7532	#CJK UNIFIED IDEOGRAPH
+0xCBA4	0x80DB	#CJK UNIFIED IDEOGRAPH
+0xCBA5	0x9240	#CJK UNIFIED IDEOGRAPH
+0xCBA6	0x9598	#CJK UNIFIED IDEOGRAPH
+0xCBA7	0x525B	#CJK UNIFIED IDEOGRAPH
+0xCBA8	0x5808	#CJK UNIFIED IDEOGRAPH
+0xCBA9	0x59DC	#CJK UNIFIED IDEOGRAPH
+0xCBAA	0x5CA1	#CJK UNIFIED IDEOGRAPH
+0xCBAB	0x5D17	#CJK UNIFIED IDEOGRAPH
+0xCBAC	0x5EB7	#CJK UNIFIED IDEOGRAPH
+0xCBAD	0x5F3A	#CJK UNIFIED IDEOGRAPH
+0xCBAE	0x5F4A	#CJK UNIFIED IDEOGRAPH
+0xCBAF	0x6177	#CJK UNIFIED IDEOGRAPH
+0xCBB0	0x6C5F	#CJK UNIFIED IDEOGRAPH
+0xCBB1	0x757A	#CJK UNIFIED IDEOGRAPH
+0xCBB2	0x7586	#CJK UNIFIED IDEOGRAPH
+0xCBB3	0x7CE0	#CJK UNIFIED IDEOGRAPH
+0xCBB4	0x7D73	#CJK UNIFIED IDEOGRAPH
+0xCBB5	0x7DB1	#CJK UNIFIED IDEOGRAPH
+0xCBB6	0x7F8C	#CJK UNIFIED IDEOGRAPH
+0xCBB7	0x8154	#CJK UNIFIED IDEOGRAPH
+0xCBB8	0x8221	#CJK UNIFIED IDEOGRAPH
+0xCBB9	0x8591	#CJK UNIFIED IDEOGRAPH
+0xCBBA	0x8941	#CJK UNIFIED IDEOGRAPH
+0xCBBB	0x8B1B	#CJK UNIFIED IDEOGRAPH
+0xCBBC	0x92FC	#CJK UNIFIED IDEOGRAPH
+0xCBBD	0x964D	#CJK UNIFIED IDEOGRAPH
+0xCBBE	0x9C47	#CJK UNIFIED IDEOGRAPH
+0xCBBF	0x4ECB	#CJK UNIFIED IDEOGRAPH
+0xCBC0	0x4EF7	#CJK UNIFIED IDEOGRAPH
+0xCBC1	0x500B	#CJK UNIFIED IDEOGRAPH
+0xCBC2	0x51F1	#CJK UNIFIED IDEOGRAPH
+0xCBC3	0x584F	#CJK UNIFIED IDEOGRAPH
+0xCBC4	0x6137	#CJK UNIFIED IDEOGRAPH
+0xCBC5	0x613E	#CJK UNIFIED IDEOGRAPH
+0xCBC6	0x6168	#CJK UNIFIED IDEOGRAPH
+0xCBC7	0x6539	#CJK UNIFIED IDEOGRAPH
+0xCBC8	0x69EA	#CJK UNIFIED IDEOGRAPH
+0xCBC9	0x6F11	#CJK UNIFIED IDEOGRAPH
+0xCBCA	0x75A5	#CJK UNIFIED IDEOGRAPH
+0xCBCB	0x7686	#CJK UNIFIED IDEOGRAPH
+0xCBCC	0x76D6	#CJK UNIFIED IDEOGRAPH
+0xCBCD	0x7B87	#CJK UNIFIED IDEOGRAPH
+0xCBCE	0x82A5	#CJK UNIFIED IDEOGRAPH
+0xCBCF	0x84CB	#CJK UNIFIED IDEOGRAPH
+0xCBD0	0xF900	#CJK COMPATIBILITY IDEOGRAPH
+0xCBD1	0x93A7	#CJK UNIFIED IDEOGRAPH
+0xCBD2	0x958B	#CJK UNIFIED IDEOGRAPH
+0xCBD3	0x5580	#CJK UNIFIED IDEOGRAPH
+0xCBD4	0x5BA2	#CJK UNIFIED IDEOGRAPH
+0xCBD5	0x5751	#CJK UNIFIED IDEOGRAPH
+0xCBD6	0xF901	#CJK COMPATIBILITY IDEOGRAPH
+0xCBD7	0x7CB3	#CJK UNIFIED IDEOGRAPH
+0xCBD8	0x7FB9	#CJK UNIFIED IDEOGRAPH
+0xCBD9	0x91B5	#CJK UNIFIED IDEOGRAPH
+0xCBDA	0x5028	#CJK UNIFIED IDEOGRAPH
+0xCBDB	0x53BB	#CJK UNIFIED IDEOGRAPH
+0xCBDC	0x5C45	#CJK UNIFIED IDEOGRAPH
+0xCBDD	0x5DE8	#CJK UNIFIED IDEOGRAPH
+0xCBDE	0x62D2	#CJK UNIFIED IDEOGRAPH
+0xCBDF	0x636E	#CJK UNIFIED IDEOGRAPH
+0xCBE0	0x64DA	#CJK UNIFIED IDEOGRAPH
+0xCBE1	0x64E7	#CJK UNIFIED IDEOGRAPH
+0xCBE2	0x6E20	#CJK UNIFIED IDEOGRAPH
+0xCBE3	0x70AC	#CJK UNIFIED IDEOGRAPH
+0xCBE4	0x795B	#CJK UNIFIED IDEOGRAPH
+0xCBE5	0x8DDD	#CJK UNIFIED IDEOGRAPH
+0xCBE6	0x8E1E	#CJK UNIFIED IDEOGRAPH
+0xCBE7	0xF902	#CJK COMPATIBILITY IDEOGRAPH
+0xCBE8	0x907D	#CJK UNIFIED IDEOGRAPH
+0xCBE9	0x9245	#CJK UNIFIED IDEOGRAPH
+0xCBEA	0x92F8	#CJK UNIFIED IDEOGRAPH
+0xCBEB	0x4E7E	#CJK UNIFIED IDEOGRAPH
+0xCBEC	0x4EF6	#CJK UNIFIED IDEOGRAPH
+0xCBED	0x5065	#CJK UNIFIED IDEOGRAPH
+0xCBEE	0x5DFE	#CJK UNIFIED IDEOGRAPH
+0xCBEF	0x5EFA	#CJK UNIFIED IDEOGRAPH
+0xCBF0	0x6106	#CJK UNIFIED IDEOGRAPH
+0xCBF1	0x6957	#CJK UNIFIED IDEOGRAPH
+0xCBF2	0x8171	#CJK UNIFIED IDEOGRAPH
+0xCBF3	0x8654	#CJK UNIFIED IDEOGRAPH
+0xCBF4	0x8E47	#CJK UNIFIED IDEOGRAPH
+0xCBF5	0x9375	#CJK UNIFIED IDEOGRAPH
+0xCBF6	0x9A2B	#CJK UNIFIED IDEOGRAPH
+0xCBF7	0x4E5E	#CJK UNIFIED IDEOGRAPH
+0xCBF8	0x5091	#CJK UNIFIED IDEOGRAPH
+0xCBF9	0x6770	#CJK UNIFIED IDEOGRAPH
+0xCBFA	0x6840	#CJK UNIFIED IDEOGRAPH
+0xCBFB	0x5109	#CJK UNIFIED IDEOGRAPH
+0xCBFC	0x528D	#CJK UNIFIED IDEOGRAPH
+0xCBFD	0x5292	#CJK UNIFIED IDEOGRAPH
+0xCBFE	0x6AA2	#CJK UNIFIED IDEOGRAPH
+0xCCA1	0x77BC	#CJK UNIFIED IDEOGRAPH
+0xCCA2	0x9210	#CJK UNIFIED IDEOGRAPH
+0xCCA3	0x9ED4	#CJK UNIFIED IDEOGRAPH
+0xCCA4	0x52AB	#CJK UNIFIED IDEOGRAPH
+0xCCA5	0x602F	#CJK UNIFIED IDEOGRAPH
+0xCCA6	0x8FF2	#CJK UNIFIED IDEOGRAPH
+0xCCA7	0x5048	#CJK UNIFIED IDEOGRAPH
+0xCCA8	0x61A9	#CJK UNIFIED IDEOGRAPH
+0xCCA9	0x63ED	#CJK UNIFIED IDEOGRAPH
+0xCCAA	0x64CA	#CJK UNIFIED IDEOGRAPH
+0xCCAB	0x683C	#CJK UNIFIED IDEOGRAPH
+0xCCAC	0x6A84	#CJK UNIFIED IDEOGRAPH
+0xCCAD	0x6FC0	#CJK UNIFIED IDEOGRAPH
+0xCCAE	0x8188	#CJK UNIFIED IDEOGRAPH
+0xCCAF	0x89A1	#CJK UNIFIED IDEOGRAPH
+0xCCB0	0x9694	#CJK UNIFIED IDEOGRAPH
+0xCCB1	0x5805	#CJK UNIFIED IDEOGRAPH
+0xCCB2	0x727D	#CJK UNIFIED IDEOGRAPH
+0xCCB3	0x72AC	#CJK UNIFIED IDEOGRAPH
+0xCCB4	0x7504	#CJK UNIFIED IDEOGRAPH
+0xCCB5	0x7D79	#CJK UNIFIED IDEOGRAPH
+0xCCB6	0x7E6D	#CJK UNIFIED IDEOGRAPH
+0xCCB7	0x80A9	#CJK UNIFIED IDEOGRAPH
+0xCCB8	0x898B	#CJK UNIFIED IDEOGRAPH
+0xCCB9	0x8B74	#CJK UNIFIED IDEOGRAPH
+0xCCBA	0x9063	#CJK UNIFIED IDEOGRAPH
+0xCCBB	0x9D51	#CJK UNIFIED IDEOGRAPH
+0xCCBC	0x6289	#CJK UNIFIED IDEOGRAPH
+0xCCBD	0x6C7A	#CJK UNIFIED IDEOGRAPH
+0xCCBE	0x6F54	#CJK UNIFIED IDEOGRAPH
+0xCCBF	0x7D50	#CJK UNIFIED IDEOGRAPH
+0xCCC0	0x7F3A	#CJK UNIFIED IDEOGRAPH
+0xCCC1	0x8A23	#CJK UNIFIED IDEOGRAPH
+0xCCC2	0x517C	#CJK UNIFIED IDEOGRAPH
+0xCCC3	0x614A	#CJK UNIFIED IDEOGRAPH
+0xCCC4	0x7B9D	#CJK UNIFIED IDEOGRAPH
+0xCCC5	0x8B19	#CJK UNIFIED IDEOGRAPH
+0xCCC6	0x9257	#CJK UNIFIED IDEOGRAPH
+0xCCC7	0x938C	#CJK UNIFIED IDEOGRAPH
+0xCCC8	0x4EAC	#CJK UNIFIED IDEOGRAPH
+0xCCC9	0x4FD3	#CJK UNIFIED IDEOGRAPH
+0xCCCA	0x501E	#CJK UNIFIED IDEOGRAPH
+0xCCCB	0x50BE	#CJK UNIFIED IDEOGRAPH
+0xCCCC	0x5106	#CJK UNIFIED IDEOGRAPH
+0xCCCD	0x52C1	#CJK UNIFIED IDEOGRAPH
+0xCCCE	0x52CD	#CJK UNIFIED IDEOGRAPH
+0xCCCF	0x537F	#CJK UNIFIED IDEOGRAPH
+0xCCD0	0x5770	#CJK UNIFIED IDEOGRAPH
+0xCCD1	0x5883	#CJK UNIFIED IDEOGRAPH
+0xCCD2	0x5E9A	#CJK UNIFIED IDEOGRAPH
+0xCCD3	0x5F91	#CJK UNIFIED IDEOGRAPH
+0xCCD4	0x6176	#CJK UNIFIED IDEOGRAPH
+0xCCD5	0x61AC	#CJK UNIFIED IDEOGRAPH
+0xCCD6	0x64CE	#CJK UNIFIED IDEOGRAPH
+0xCCD7	0x656C	#CJK UNIFIED IDEOGRAPH
+0xCCD8	0x666F	#CJK UNIFIED IDEOGRAPH
+0xCCD9	0x66BB	#CJK UNIFIED IDEOGRAPH
+0xCCDA	0x66F4	#CJK UNIFIED IDEOGRAPH
+0xCCDB	0x6897	#CJK UNIFIED IDEOGRAPH
+0xCCDC	0x6D87	#CJK UNIFIED IDEOGRAPH
+0xCCDD	0x7085	#CJK UNIFIED IDEOGRAPH
+0xCCDE	0x70F1	#CJK UNIFIED IDEOGRAPH
+0xCCDF	0x749F	#CJK UNIFIED IDEOGRAPH
+0xCCE0	0x74A5	#CJK UNIFIED IDEOGRAPH
+0xCCE1	0x74CA	#CJK UNIFIED IDEOGRAPH
+0xCCE2	0x75D9	#CJK UNIFIED IDEOGRAPH
+0xCCE3	0x786C	#CJK UNIFIED IDEOGRAPH
+0xCCE4	0x78EC	#CJK UNIFIED IDEOGRAPH
+0xCCE5	0x7ADF	#CJK UNIFIED IDEOGRAPH
+0xCCE6	0x7AF6	#CJK UNIFIED IDEOGRAPH
+0xCCE7	0x7D45	#CJK UNIFIED IDEOGRAPH
+0xCCE8	0x7D93	#CJK UNIFIED IDEOGRAPH
+0xCCE9	0x8015	#CJK UNIFIED IDEOGRAPH
+0xCCEA	0x803F	#CJK UNIFIED IDEOGRAPH
+0xCCEB	0x811B	#CJK UNIFIED IDEOGRAPH
+0xCCEC	0x8396	#CJK UNIFIED IDEOGRAPH
+0xCCED	0x8B66	#CJK UNIFIED IDEOGRAPH
+0xCCEE	0x8F15	#CJK UNIFIED IDEOGRAPH
+0xCCEF	0x9015	#CJK UNIFIED IDEOGRAPH
+0xCCF0	0x93E1	#CJK UNIFIED IDEOGRAPH
+0xCCF1	0x9803	#CJK UNIFIED IDEOGRAPH
+0xCCF2	0x9838	#CJK UNIFIED IDEOGRAPH
+0xCCF3	0x9A5A	#CJK UNIFIED IDEOGRAPH
+0xCCF4	0x9BE8	#CJK UNIFIED IDEOGRAPH
+0xCCF5	0x4FC2	#CJK UNIFIED IDEOGRAPH
+0xCCF6	0x5553	#CJK UNIFIED IDEOGRAPH
+0xCCF7	0x583A	#CJK UNIFIED IDEOGRAPH
+0xCCF8	0x5951	#CJK UNIFIED IDEOGRAPH
+0xCCF9	0x5B63	#CJK UNIFIED IDEOGRAPH
+0xCCFA	0x5C46	#CJK UNIFIED IDEOGRAPH
+0xCCFB	0x60B8	#CJK UNIFIED IDEOGRAPH
+0xCCFC	0x6212	#CJK UNIFIED IDEOGRAPH
+0xCCFD	0x6842	#CJK UNIFIED IDEOGRAPH
+0xCCFE	0x68B0	#CJK UNIFIED IDEOGRAPH
+0xCDA1	0x68E8	#CJK UNIFIED IDEOGRAPH
+0xCDA2	0x6EAA	#CJK UNIFIED IDEOGRAPH
+0xCDA3	0x754C	#CJK UNIFIED IDEOGRAPH
+0xCDA4	0x7678	#CJK UNIFIED IDEOGRAPH
+0xCDA5	0x78CE	#CJK UNIFIED IDEOGRAPH
+0xCDA6	0x7A3D	#CJK UNIFIED IDEOGRAPH
+0xCDA7	0x7CFB	#CJK UNIFIED IDEOGRAPH
+0xCDA8	0x7E6B	#CJK UNIFIED IDEOGRAPH
+0xCDA9	0x7E7C	#CJK UNIFIED IDEOGRAPH
+0xCDAA	0x8A08	#CJK UNIFIED IDEOGRAPH
+0xCDAB	0x8AA1	#CJK UNIFIED IDEOGRAPH
+0xCDAC	0x8C3F	#CJK UNIFIED IDEOGRAPH
+0xCDAD	0x968E	#CJK UNIFIED IDEOGRAPH
+0xCDAE	0x9DC4	#CJK UNIFIED IDEOGRAPH
+0xCDAF	0x53E4	#CJK UNIFIED IDEOGRAPH
+0xCDB0	0x53E9	#CJK UNIFIED IDEOGRAPH
+0xCDB1	0x544A	#CJK UNIFIED IDEOGRAPH
+0xCDB2	0x5471	#CJK UNIFIED IDEOGRAPH
+0xCDB3	0x56FA	#CJK UNIFIED IDEOGRAPH
+0xCDB4	0x59D1	#CJK UNIFIED IDEOGRAPH
+0xCDB5	0x5B64	#CJK UNIFIED IDEOGRAPH
+0xCDB6	0x5C3B	#CJK UNIFIED IDEOGRAPH
+0xCDB7	0x5EAB	#CJK UNIFIED IDEOGRAPH
+0xCDB8	0x62F7	#CJK UNIFIED IDEOGRAPH
+0xCDB9	0x6537	#CJK UNIFIED IDEOGRAPH
+0xCDBA	0x6545	#CJK UNIFIED IDEOGRAPH
+0xCDBB	0x6572	#CJK UNIFIED IDEOGRAPH
+0xCDBC	0x66A0	#CJK UNIFIED IDEOGRAPH
+0xCDBD	0x67AF	#CJK UNIFIED IDEOGRAPH
+0xCDBE	0x69C1	#CJK UNIFIED IDEOGRAPH
+0xCDBF	0x6CBD	#CJK UNIFIED IDEOGRAPH
+0xCDC0	0x75FC	#CJK UNIFIED IDEOGRAPH
+0xCDC1	0x7690	#CJK UNIFIED IDEOGRAPH
+0xCDC2	0x777E	#CJK UNIFIED IDEOGRAPH
+0xCDC3	0x7A3F	#CJK UNIFIED IDEOGRAPH
+0xCDC4	0x7F94	#CJK UNIFIED IDEOGRAPH
+0xCDC5	0x8003	#CJK UNIFIED IDEOGRAPH
+0xCDC6	0x80A1	#CJK UNIFIED IDEOGRAPH
+0xCDC7	0x818F	#CJK UNIFIED IDEOGRAPH
+0xCDC8	0x82E6	#CJK UNIFIED IDEOGRAPH
+0xCDC9	0x82FD	#CJK UNIFIED IDEOGRAPH
+0xCDCA	0x83F0	#CJK UNIFIED IDEOGRAPH
+0xCDCB	0x85C1	#CJK UNIFIED IDEOGRAPH
+0xCDCC	0x8831	#CJK UNIFIED IDEOGRAPH
+0xCDCD	0x88B4	#CJK UNIFIED IDEOGRAPH
+0xCDCE	0x8AA5	#CJK UNIFIED IDEOGRAPH
+0xCDCF	0xF903	#CJK COMPATIBILITY IDEOGRAPH
+0xCDD0	0x8F9C	#CJK UNIFIED IDEOGRAPH
+0xCDD1	0x932E	#CJK UNIFIED IDEOGRAPH
+0xCDD2	0x96C7	#CJK UNIFIED IDEOGRAPH
+0xCDD3	0x9867	#CJK UNIFIED IDEOGRAPH
+0xCDD4	0x9AD8	#CJK UNIFIED IDEOGRAPH
+0xCDD5	0x9F13	#CJK UNIFIED IDEOGRAPH
+0xCDD6	0x54ED	#CJK UNIFIED IDEOGRAPH
+0xCDD7	0x659B	#CJK UNIFIED IDEOGRAPH
+0xCDD8	0x66F2	#CJK UNIFIED IDEOGRAPH
+0xCDD9	0x688F	#CJK UNIFIED IDEOGRAPH
+0xCDDA	0x7A40	#CJK UNIFIED IDEOGRAPH
+0xCDDB	0x8C37	#CJK UNIFIED IDEOGRAPH
+0xCDDC	0x9D60	#CJK UNIFIED IDEOGRAPH
+0xCDDD	0x56F0	#CJK UNIFIED IDEOGRAPH
+0xCDDE	0x5764	#CJK UNIFIED IDEOGRAPH
+0xCDDF	0x5D11	#CJK UNIFIED IDEOGRAPH
+0xCDE0	0x6606	#CJK UNIFIED IDEOGRAPH
+0xCDE1	0x68B1	#CJK UNIFIED IDEOGRAPH
+0xCDE2	0x68CD	#CJK UNIFIED IDEOGRAPH
+0xCDE3	0x6EFE	#CJK UNIFIED IDEOGRAPH
+0xCDE4	0x7428	#CJK UNIFIED IDEOGRAPH
+0xCDE5	0x889E	#CJK UNIFIED IDEOGRAPH
+0xCDE6	0x9BE4	#CJK UNIFIED IDEOGRAPH
+0xCDE7	0x6C68	#CJK UNIFIED IDEOGRAPH
+0xCDE8	0xF904	#CJK COMPATIBILITY IDEOGRAPH
+0xCDE9	0x9AA8	#CJK UNIFIED IDEOGRAPH
+0xCDEA	0x4F9B	#CJK UNIFIED IDEOGRAPH
+0xCDEB	0x516C	#CJK UNIFIED IDEOGRAPH
+0xCDEC	0x5171	#CJK UNIFIED IDEOGRAPH
+0xCDED	0x529F	#CJK UNIFIED IDEOGRAPH
+0xCDEE	0x5B54	#CJK UNIFIED IDEOGRAPH
+0xCDEF	0x5DE5	#CJK UNIFIED IDEOGRAPH
+0xCDF0	0x6050	#CJK UNIFIED IDEOGRAPH
+0xCDF1	0x606D	#CJK UNIFIED IDEOGRAPH
+0xCDF2	0x62F1	#CJK UNIFIED IDEOGRAPH
+0xCDF3	0x63A7	#CJK UNIFIED IDEOGRAPH
+0xCDF4	0x653B	#CJK UNIFIED IDEOGRAPH
+0xCDF5	0x73D9	#CJK UNIFIED IDEOGRAPH
+0xCDF6	0x7A7A	#CJK UNIFIED IDEOGRAPH
+0xCDF7	0x86A3	#CJK UNIFIED IDEOGRAPH
+0xCDF8	0x8CA2	#CJK UNIFIED IDEOGRAPH
+0xCDF9	0x978F	#CJK UNIFIED IDEOGRAPH
+0xCDFA	0x4E32	#CJK UNIFIED IDEOGRAPH
+0xCDFB	0x5BE1	#CJK UNIFIED IDEOGRAPH
+0xCDFC	0x6208	#CJK UNIFIED IDEOGRAPH
+0xCDFD	0x679C	#CJK UNIFIED IDEOGRAPH
+0xCDFE	0x74DC	#CJK UNIFIED IDEOGRAPH
+0xCEA1	0x79D1	#CJK UNIFIED IDEOGRAPH
+0xCEA2	0x83D3	#CJK UNIFIED IDEOGRAPH
+0xCEA3	0x8A87	#CJK UNIFIED IDEOGRAPH
+0xCEA4	0x8AB2	#CJK UNIFIED IDEOGRAPH
+0xCEA5	0x8DE8	#CJK UNIFIED IDEOGRAPH
+0xCEA6	0x904E	#CJK UNIFIED IDEOGRAPH
+0xCEA7	0x934B	#CJK UNIFIED IDEOGRAPH
+0xCEA8	0x9846	#CJK UNIFIED IDEOGRAPH
+0xCEA9	0x5ED3	#CJK UNIFIED IDEOGRAPH
+0xCEAA	0x69E8	#CJK UNIFIED IDEOGRAPH
+0xCEAB	0x85FF	#CJK UNIFIED IDEOGRAPH
+0xCEAC	0x90ED	#CJK UNIFIED IDEOGRAPH
+0xCEAD	0xF905	#CJK COMPATIBILITY IDEOGRAPH
+0xCEAE	0x51A0	#CJK UNIFIED IDEOGRAPH
+0xCEAF	0x5B98	#CJK UNIFIED IDEOGRAPH
+0xCEB0	0x5BEC	#CJK UNIFIED IDEOGRAPH
+0xCEB1	0x6163	#CJK UNIFIED IDEOGRAPH
+0xCEB2	0x68FA	#CJK UNIFIED IDEOGRAPH
+0xCEB3	0x6B3E	#CJK UNIFIED IDEOGRAPH
+0xCEB4	0x704C	#CJK UNIFIED IDEOGRAPH
+0xCEB5	0x742F	#CJK UNIFIED IDEOGRAPH
+0xCEB6	0x74D8	#CJK UNIFIED IDEOGRAPH
+0xCEB7	0x7BA1	#CJK UNIFIED IDEOGRAPH
+0xCEB8	0x7F50	#CJK UNIFIED IDEOGRAPH
+0xCEB9	0x83C5	#CJK UNIFIED IDEOGRAPH
+0xCEBA	0x89C0	#CJK UNIFIED IDEOGRAPH
+0xCEBB	0x8CAB	#CJK UNIFIED IDEOGRAPH
+0xCEBC	0x95DC	#CJK UNIFIED IDEOGRAPH
+0xCEBD	0x9928	#CJK UNIFIED IDEOGRAPH
+0xCEBE	0x522E	#CJK UNIFIED IDEOGRAPH
+0xCEBF	0x605D	#CJK UNIFIED IDEOGRAPH
+0xCEC0	0x62EC	#CJK UNIFIED IDEOGRAPH
+0xCEC1	0x9002	#CJK UNIFIED IDEOGRAPH
+0xCEC2	0x4F8A	#CJK UNIFIED IDEOGRAPH
+0xCEC3	0x5149	#CJK UNIFIED IDEOGRAPH
+0xCEC4	0x5321	#CJK UNIFIED IDEOGRAPH
+0xCEC5	0x58D9	#CJK UNIFIED IDEOGRAPH
+0xCEC6	0x5EE3	#CJK UNIFIED IDEOGRAPH
+0xCEC7	0x66E0	#CJK UNIFIED IDEOGRAPH
+0xCEC8	0x6D38	#CJK UNIFIED IDEOGRAPH
+0xCEC9	0x709A	#CJK UNIFIED IDEOGRAPH
+0xCECA	0x72C2	#CJK UNIFIED IDEOGRAPH
+0xCECB	0x73D6	#CJK UNIFIED IDEOGRAPH
+0xCECC	0x7B50	#CJK UNIFIED IDEOGRAPH
+0xCECD	0x80F1	#CJK UNIFIED IDEOGRAPH
+0xCECE	0x945B	#CJK UNIFIED IDEOGRAPH
+0xCECF	0x5366	#CJK UNIFIED IDEOGRAPH
+0xCED0	0x639B	#CJK UNIFIED IDEOGRAPH
+0xCED1	0x7F6B	#CJK UNIFIED IDEOGRAPH
+0xCED2	0x4E56	#CJK UNIFIED IDEOGRAPH
+0xCED3	0x5080	#CJK UNIFIED IDEOGRAPH
+0xCED4	0x584A	#CJK UNIFIED IDEOGRAPH
+0xCED5	0x58DE	#CJK UNIFIED IDEOGRAPH
+0xCED6	0x602A	#CJK UNIFIED IDEOGRAPH
+0xCED7	0x6127	#CJK UNIFIED IDEOGRAPH
+0xCED8	0x62D0	#CJK UNIFIED IDEOGRAPH
+0xCED9	0x69D0	#CJK UNIFIED IDEOGRAPH
+0xCEDA	0x9B41	#CJK UNIFIED IDEOGRAPH
+0xCEDB	0x5B8F	#CJK UNIFIED IDEOGRAPH
+0xCEDC	0x7D18	#CJK UNIFIED IDEOGRAPH
+0xCEDD	0x80B1	#CJK UNIFIED IDEOGRAPH
+0xCEDE	0x8F5F	#CJK UNIFIED IDEOGRAPH
+0xCEDF	0x4EA4	#CJK UNIFIED IDEOGRAPH
+0xCEE0	0x50D1	#CJK UNIFIED IDEOGRAPH
+0xCEE1	0x54AC	#CJK UNIFIED IDEOGRAPH
+0xCEE2	0x55AC	#CJK UNIFIED IDEOGRAPH
+0xCEE3	0x5B0C	#CJK UNIFIED IDEOGRAPH
+0xCEE4	0x5DA0	#CJK UNIFIED IDEOGRAPH
+0xCEE5	0x5DE7	#CJK UNIFIED IDEOGRAPH
+0xCEE6	0x652A	#CJK UNIFIED IDEOGRAPH
+0xCEE7	0x654E	#CJK UNIFIED IDEOGRAPH
+0xCEE8	0x6821	#CJK UNIFIED IDEOGRAPH
+0xCEE9	0x6A4B	#CJK UNIFIED IDEOGRAPH
+0xCEEA	0x72E1	#CJK UNIFIED IDEOGRAPH
+0xCEEB	0x768E	#CJK UNIFIED IDEOGRAPH
+0xCEEC	0x77EF	#CJK UNIFIED IDEOGRAPH
+0xCEED	0x7D5E	#CJK UNIFIED IDEOGRAPH
+0xCEEE	0x7FF9	#CJK UNIFIED IDEOGRAPH
+0xCEEF	0x81A0	#CJK UNIFIED IDEOGRAPH
+0xCEF0	0x854E	#CJK UNIFIED IDEOGRAPH
+0xCEF1	0x86DF	#CJK UNIFIED IDEOGRAPH
+0xCEF2	0x8F03	#CJK UNIFIED IDEOGRAPH
+0xCEF3	0x8F4E	#CJK UNIFIED IDEOGRAPH
+0xCEF4	0x90CA	#CJK UNIFIED IDEOGRAPH
+0xCEF5	0x9903	#CJK UNIFIED IDEOGRAPH
+0xCEF6	0x9A55	#CJK UNIFIED IDEOGRAPH
+0xCEF7	0x9BAB	#CJK UNIFIED IDEOGRAPH
+0xCEF8	0x4E18	#CJK UNIFIED IDEOGRAPH
+0xCEF9	0x4E45	#CJK UNIFIED IDEOGRAPH
+0xCEFA	0x4E5D	#CJK UNIFIED IDEOGRAPH
+0xCEFB	0x4EC7	#CJK UNIFIED IDEOGRAPH
+0xCEFC	0x4FF1	#CJK UNIFIED IDEOGRAPH
+0xCEFD	0x5177	#CJK UNIFIED IDEOGRAPH
+0xCEFE	0x52FE	#CJK UNIFIED IDEOGRAPH
+0xCFA1	0x5340	#CJK UNIFIED IDEOGRAPH
+0xCFA2	0x53E3	#CJK UNIFIED IDEOGRAPH
+0xCFA3	0x53E5	#CJK UNIFIED IDEOGRAPH
+0xCFA4	0x548E	#CJK UNIFIED IDEOGRAPH
+0xCFA5	0x5614	#CJK UNIFIED IDEOGRAPH
+0xCFA6	0x5775	#CJK UNIFIED IDEOGRAPH
+0xCFA7	0x57A2	#CJK UNIFIED IDEOGRAPH
+0xCFA8	0x5BC7	#CJK UNIFIED IDEOGRAPH
+0xCFA9	0x5D87	#CJK UNIFIED IDEOGRAPH
+0xCFAA	0x5ED0	#CJK UNIFIED IDEOGRAPH
+0xCFAB	0x61FC	#CJK UNIFIED IDEOGRAPH
+0xCFAC	0x62D8	#CJK UNIFIED IDEOGRAPH
+0xCFAD	0x6551	#CJK UNIFIED IDEOGRAPH
+0xCFAE	0x67B8	#CJK UNIFIED IDEOGRAPH
+0xCFAF	0x67E9	#CJK UNIFIED IDEOGRAPH
+0xCFB0	0x69CB	#CJK UNIFIED IDEOGRAPH
+0xCFB1	0x6B50	#CJK UNIFIED IDEOGRAPH
+0xCFB2	0x6BC6	#CJK UNIFIED IDEOGRAPH
+0xCFB3	0x6BEC	#CJK UNIFIED IDEOGRAPH
+0xCFB4	0x6C42	#CJK UNIFIED IDEOGRAPH
+0xCFB5	0x6E9D	#CJK UNIFIED IDEOGRAPH
+0xCFB6	0x7078	#CJK UNIFIED IDEOGRAPH
+0xCFB7	0x72D7	#CJK UNIFIED IDEOGRAPH
+0xCFB8	0x7396	#CJK UNIFIED IDEOGRAPH
+0xCFB9	0x7403	#CJK UNIFIED IDEOGRAPH
+0xCFBA	0x77BF	#CJK UNIFIED IDEOGRAPH
+0xCFBB	0x77E9	#CJK UNIFIED IDEOGRAPH
+0xCFBC	0x7A76	#CJK UNIFIED IDEOGRAPH
+0xCFBD	0x7D7F	#CJK UNIFIED IDEOGRAPH
+0xCFBE	0x8009	#CJK UNIFIED IDEOGRAPH
+0xCFBF	0x81FC	#CJK UNIFIED IDEOGRAPH
+0xCFC0	0x8205	#CJK UNIFIED IDEOGRAPH
+0xCFC1	0x820A	#CJK UNIFIED IDEOGRAPH
+0xCFC2	0x82DF	#CJK UNIFIED IDEOGRAPH
+0xCFC3	0x8862	#CJK UNIFIED IDEOGRAPH
+0xCFC4	0x8B33	#CJK UNIFIED IDEOGRAPH
+0xCFC5	0x8CFC	#CJK UNIFIED IDEOGRAPH
+0xCFC6	0x8EC0	#CJK UNIFIED IDEOGRAPH
+0xCFC7	0x9011	#CJK UNIFIED IDEOGRAPH
+0xCFC8	0x90B1	#CJK UNIFIED IDEOGRAPH
+0xCFC9	0x9264	#CJK UNIFIED IDEOGRAPH
+0xCFCA	0x92B6	#CJK UNIFIED IDEOGRAPH
+0xCFCB	0x99D2	#CJK UNIFIED IDEOGRAPH
+0xCFCC	0x9A45	#CJK UNIFIED IDEOGRAPH
+0xCFCD	0x9CE9	#CJK UNIFIED IDEOGRAPH
+0xCFCE	0x9DD7	#CJK UNIFIED IDEOGRAPH
+0xCFCF	0x9F9C	#CJK UNIFIED IDEOGRAPH
+0xCFD0	0x570B	#CJK UNIFIED IDEOGRAPH
+0xCFD1	0x5C40	#CJK UNIFIED IDEOGRAPH
+0xCFD2	0x83CA	#CJK UNIFIED IDEOGRAPH
+0xCFD3	0x97A0	#CJK UNIFIED IDEOGRAPH
+0xCFD4	0x97AB	#CJK UNIFIED IDEOGRAPH
+0xCFD5	0x9EB4	#CJK UNIFIED IDEOGRAPH
+0xCFD6	0x541B	#CJK UNIFIED IDEOGRAPH
+0xCFD7	0x7A98	#CJK UNIFIED IDEOGRAPH
+0xCFD8	0x7FA4	#CJK UNIFIED IDEOGRAPH
+0xCFD9	0x88D9	#CJK UNIFIED IDEOGRAPH
+0xCFDA	0x8ECD	#CJK UNIFIED IDEOGRAPH
+0xCFDB	0x90E1	#CJK UNIFIED IDEOGRAPH
+0xCFDC	0x5800	#CJK UNIFIED IDEOGRAPH
+0xCFDD	0x5C48	#CJK UNIFIED IDEOGRAPH
+0xCFDE	0x6398	#CJK UNIFIED IDEOGRAPH
+0xCFDF	0x7A9F	#CJK UNIFIED IDEOGRAPH
+0xCFE0	0x5BAE	#CJK UNIFIED IDEOGRAPH
+0xCFE1	0x5F13	#CJK UNIFIED IDEOGRAPH
+0xCFE2	0x7A79	#CJK UNIFIED IDEOGRAPH
+0xCFE3	0x7AAE	#CJK UNIFIED IDEOGRAPH
+0xCFE4	0x828E	#CJK UNIFIED IDEOGRAPH
+0xCFE5	0x8EAC	#CJK UNIFIED IDEOGRAPH
+0xCFE6	0x5026	#CJK UNIFIED IDEOGRAPH
+0xCFE7	0x5238	#CJK UNIFIED IDEOGRAPH
+0xCFE8	0x52F8	#CJK UNIFIED IDEOGRAPH
+0xCFE9	0x5377	#CJK UNIFIED IDEOGRAPH
+0xCFEA	0x5708	#CJK UNIFIED IDEOGRAPH
+0xCFEB	0x62F3	#CJK UNIFIED IDEOGRAPH
+0xCFEC	0x6372	#CJK UNIFIED IDEOGRAPH
+0xCFED	0x6B0A	#CJK UNIFIED IDEOGRAPH
+0xCFEE	0x6DC3	#CJK UNIFIED IDEOGRAPH
+0xCFEF	0x7737	#CJK UNIFIED IDEOGRAPH
+0xCFF0	0x53A5	#CJK UNIFIED IDEOGRAPH
+0xCFF1	0x7357	#CJK UNIFIED IDEOGRAPH
+0xCFF2	0x8568	#CJK UNIFIED IDEOGRAPH
+0xCFF3	0x8E76	#CJK UNIFIED IDEOGRAPH
+0xCFF4	0x95D5	#CJK UNIFIED IDEOGRAPH
+0xCFF5	0x673A	#CJK UNIFIED IDEOGRAPH
+0xCFF6	0x6AC3	#CJK UNIFIED IDEOGRAPH
+0xCFF7	0x6F70	#CJK UNIFIED IDEOGRAPH
+0xCFF8	0x8A6D	#CJK UNIFIED IDEOGRAPH
+0xCFF9	0x8ECC	#CJK UNIFIED IDEOGRAPH
+0xCFFA	0x994B	#CJK UNIFIED IDEOGRAPH
+0xCFFB	0xF906	#CJK COMPATIBILITY IDEOGRAPH
+0xCFFC	0x6677	#CJK UNIFIED IDEOGRAPH
+0xCFFD	0x6B78	#CJK UNIFIED IDEOGRAPH
+0xCFFE	0x8CB4	#CJK UNIFIED IDEOGRAPH
+0xD0A1	0x9B3C	#CJK UNIFIED IDEOGRAPH
+0xD0A2	0xF907	#CJK COMPATIBILITY IDEOGRAPH
+0xD0A3	0x53EB	#CJK UNIFIED IDEOGRAPH
+0xD0A4	0x572D	#CJK UNIFIED IDEOGRAPH
+0xD0A5	0x594E	#CJK UNIFIED IDEOGRAPH
+0xD0A6	0x63C6	#CJK UNIFIED IDEOGRAPH
+0xD0A7	0x69FB	#CJK UNIFIED IDEOGRAPH
+0xD0A8	0x73EA	#CJK UNIFIED IDEOGRAPH
+0xD0A9	0x7845	#CJK UNIFIED IDEOGRAPH
+0xD0AA	0x7ABA	#CJK UNIFIED IDEOGRAPH
+0xD0AB	0x7AC5	#CJK UNIFIED IDEOGRAPH
+0xD0AC	0x7CFE	#CJK UNIFIED IDEOGRAPH
+0xD0AD	0x8475	#CJK UNIFIED IDEOGRAPH
+0xD0AE	0x898F	#CJK UNIFIED IDEOGRAPH
+0xD0AF	0x8D73	#CJK UNIFIED IDEOGRAPH
+0xD0B0	0x9035	#CJK UNIFIED IDEOGRAPH
+0xD0B1	0x95A8	#CJK UNIFIED IDEOGRAPH
+0xD0B2	0x52FB	#CJK UNIFIED IDEOGRAPH
+0xD0B3	0x5747	#CJK UNIFIED IDEOGRAPH
+0xD0B4	0x7547	#CJK UNIFIED IDEOGRAPH
+0xD0B5	0x7B60	#CJK UNIFIED IDEOGRAPH
+0xD0B6	0x83CC	#CJK UNIFIED IDEOGRAPH
+0xD0B7	0x921E	#CJK UNIFIED IDEOGRAPH
+0xD0B8	0xF908	#CJK COMPATIBILITY IDEOGRAPH
+0xD0B9	0x6A58	#CJK UNIFIED IDEOGRAPH
+0xD0BA	0x514B	#CJK UNIFIED IDEOGRAPH
+0xD0BB	0x524B	#CJK UNIFIED IDEOGRAPH
+0xD0BC	0x5287	#CJK UNIFIED IDEOGRAPH
+0xD0BD	0x621F	#CJK UNIFIED IDEOGRAPH
+0xD0BE	0x68D8	#CJK UNIFIED IDEOGRAPH
+0xD0BF	0x6975	#CJK UNIFIED IDEOGRAPH
+0xD0C0	0x9699	#CJK UNIFIED IDEOGRAPH
+0xD0C1	0x50C5	#CJK UNIFIED IDEOGRAPH
+0xD0C2	0x52A4	#CJK UNIFIED IDEOGRAPH
+0xD0C3	0x52E4	#CJK UNIFIED IDEOGRAPH
+0xD0C4	0x61C3	#CJK UNIFIED IDEOGRAPH
+0xD0C5	0x65A4	#CJK UNIFIED IDEOGRAPH
+0xD0C6	0x6839	#CJK UNIFIED IDEOGRAPH
+0xD0C7	0x69FF	#CJK UNIFIED IDEOGRAPH
+0xD0C8	0x747E	#CJK UNIFIED IDEOGRAPH
+0xD0C9	0x7B4B	#CJK UNIFIED IDEOGRAPH
+0xD0CA	0x82B9	#CJK UNIFIED IDEOGRAPH
+0xD0CB	0x83EB	#CJK UNIFIED IDEOGRAPH
+0xD0CC	0x89B2	#CJK UNIFIED IDEOGRAPH
+0xD0CD	0x8B39	#CJK UNIFIED IDEOGRAPH
+0xD0CE	0x8FD1	#CJK UNIFIED IDEOGRAPH
+0xD0CF	0x9949	#CJK UNIFIED IDEOGRAPH
+0xD0D0	0xF909	#CJK COMPATIBILITY IDEOGRAPH
+0xD0D1	0x4ECA	#CJK UNIFIED IDEOGRAPH
+0xD0D2	0x5997	#CJK UNIFIED IDEOGRAPH
+0xD0D3	0x64D2	#CJK UNIFIED IDEOGRAPH
+0xD0D4	0x6611	#CJK UNIFIED IDEOGRAPH
+0xD0D5	0x6A8E	#CJK UNIFIED IDEOGRAPH
+0xD0D6	0x7434	#CJK UNIFIED IDEOGRAPH
+0xD0D7	0x7981	#CJK UNIFIED IDEOGRAPH
+0xD0D8	0x79BD	#CJK UNIFIED IDEOGRAPH
+0xD0D9	0x82A9	#CJK UNIFIED IDEOGRAPH
+0xD0DA	0x887E	#CJK UNIFIED IDEOGRAPH
+0xD0DB	0x887F	#CJK UNIFIED IDEOGRAPH
+0xD0DC	0x895F	#CJK UNIFIED IDEOGRAPH
+0xD0DD	0xF90A	#CJK COMPATIBILITY IDEOGRAPH
+0xD0DE	0x9326	#CJK UNIFIED IDEOGRAPH
+0xD0DF	0x4F0B	#CJK UNIFIED IDEOGRAPH
+0xD0E0	0x53CA	#CJK UNIFIED IDEOGRAPH
+0xD0E1	0x6025	#CJK UNIFIED IDEOGRAPH
+0xD0E2	0x6271	#CJK UNIFIED IDEOGRAPH
+0xD0E3	0x6C72	#CJK UNIFIED IDEOGRAPH
+0xD0E4	0x7D1A	#CJK UNIFIED IDEOGRAPH
+0xD0E5	0x7D66	#CJK UNIFIED IDEOGRAPH
+0xD0E6	0x4E98	#CJK UNIFIED IDEOGRAPH
+0xD0E7	0x5162	#CJK UNIFIED IDEOGRAPH
+0xD0E8	0x77DC	#CJK UNIFIED IDEOGRAPH
+0xD0E9	0x80AF	#CJK UNIFIED IDEOGRAPH
+0xD0EA	0x4F01	#CJK UNIFIED IDEOGRAPH
+0xD0EB	0x4F0E	#CJK UNIFIED IDEOGRAPH
+0xD0EC	0x5176	#CJK UNIFIED IDEOGRAPH
+0xD0ED	0x5180	#CJK UNIFIED IDEOGRAPH
+0xD0EE	0x55DC	#CJK UNIFIED IDEOGRAPH
+0xD0EF	0x5668	#CJK UNIFIED IDEOGRAPH
+0xD0F0	0x573B	#CJK UNIFIED IDEOGRAPH
+0xD0F1	0x57FA	#CJK UNIFIED IDEOGRAPH
+0xD0F2	0x57FC	#CJK UNIFIED IDEOGRAPH
+0xD0F3	0x5914	#CJK UNIFIED IDEOGRAPH
+0xD0F4	0x5947	#CJK UNIFIED IDEOGRAPH
+0xD0F5	0x5993	#CJK UNIFIED IDEOGRAPH
+0xD0F6	0x5BC4	#CJK UNIFIED IDEOGRAPH
+0xD0F7	0x5C90	#CJK UNIFIED IDEOGRAPH
+0xD0F8	0x5D0E	#CJK UNIFIED IDEOGRAPH
+0xD0F9	0x5DF1	#CJK UNIFIED IDEOGRAPH
+0xD0FA	0x5E7E	#CJK UNIFIED IDEOGRAPH
+0xD0FB	0x5FCC	#CJK UNIFIED IDEOGRAPH
+0xD0FC	0x6280	#CJK UNIFIED IDEOGRAPH
+0xD0FD	0x65D7	#CJK UNIFIED IDEOGRAPH
+0xD0FE	0x65E3	#CJK UNIFIED IDEOGRAPH
+0xD1A1	0x671E	#CJK UNIFIED IDEOGRAPH
+0xD1A2	0x671F	#CJK UNIFIED IDEOGRAPH
+0xD1A3	0x675E	#CJK UNIFIED IDEOGRAPH
+0xD1A4	0x68CB	#CJK UNIFIED IDEOGRAPH
+0xD1A5	0x68C4	#CJK UNIFIED IDEOGRAPH
+0xD1A6	0x6A5F	#CJK UNIFIED IDEOGRAPH
+0xD1A7	0x6B3A	#CJK UNIFIED IDEOGRAPH
+0xD1A8	0x6C23	#CJK UNIFIED IDEOGRAPH
+0xD1A9	0x6C7D	#CJK UNIFIED IDEOGRAPH
+0xD1AA	0x6C82	#CJK UNIFIED IDEOGRAPH
+0xD1AB	0x6DC7	#CJK UNIFIED IDEOGRAPH
+0xD1AC	0x7398	#CJK UNIFIED IDEOGRAPH
+0xD1AD	0x7426	#CJK UNIFIED IDEOGRAPH
+0xD1AE	0x742A	#CJK UNIFIED IDEOGRAPH
+0xD1AF	0x7482	#CJK UNIFIED IDEOGRAPH
+0xD1B0	0x74A3	#CJK UNIFIED IDEOGRAPH
+0xD1B1	0x7578	#CJK UNIFIED IDEOGRAPH
+0xD1B2	0x757F	#CJK UNIFIED IDEOGRAPH
+0xD1B3	0x7881	#CJK UNIFIED IDEOGRAPH
+0xD1B4	0x78EF	#CJK UNIFIED IDEOGRAPH
+0xD1B5	0x7941	#CJK UNIFIED IDEOGRAPH
+0xD1B6	0x7947	#CJK UNIFIED IDEOGRAPH
+0xD1B7	0x7948	#CJK UNIFIED IDEOGRAPH
+0xD1B8	0x797A	#CJK UNIFIED IDEOGRAPH
+0xD1B9	0x7B95	#CJK UNIFIED IDEOGRAPH
+0xD1BA	0x7D00	#CJK UNIFIED IDEOGRAPH
+0xD1BB	0x7DBA	#CJK UNIFIED IDEOGRAPH
+0xD1BC	0x7F88	#CJK UNIFIED IDEOGRAPH
+0xD1BD	0x8006	#CJK UNIFIED IDEOGRAPH
+0xD1BE	0x802D	#CJK UNIFIED IDEOGRAPH
+0xD1BF	0x808C	#CJK UNIFIED IDEOGRAPH
+0xD1C0	0x8A18	#CJK UNIFIED IDEOGRAPH
+0xD1C1	0x8B4F	#CJK UNIFIED IDEOGRAPH
+0xD1C2	0x8C48	#CJK UNIFIED IDEOGRAPH
+0xD1C3	0x8D77	#CJK UNIFIED IDEOGRAPH
+0xD1C4	0x9321	#CJK UNIFIED IDEOGRAPH
+0xD1C5	0x9324	#CJK UNIFIED IDEOGRAPH
+0xD1C6	0x98E2	#CJK UNIFIED IDEOGRAPH
+0xD1C7	0x9951	#CJK UNIFIED IDEOGRAPH
+0xD1C8	0x9A0E	#CJK UNIFIED IDEOGRAPH
+0xD1C9	0x9A0F	#CJK UNIFIED IDEOGRAPH
+0xD1CA	0x9A65	#CJK UNIFIED IDEOGRAPH
+0xD1CB	0x9E92	#CJK UNIFIED IDEOGRAPH
+0xD1CC	0x7DCA	#CJK UNIFIED IDEOGRAPH
+0xD1CD	0x4F76	#CJK UNIFIED IDEOGRAPH
+0xD1CE	0x5409	#CJK UNIFIED IDEOGRAPH
+0xD1CF	0x62EE	#CJK UNIFIED IDEOGRAPH
+0xD1D0	0x6854	#CJK UNIFIED IDEOGRAPH
+0xD1D1	0x91D1	#CJK UNIFIED IDEOGRAPH
+0xD1D2	0x55AB	#CJK UNIFIED IDEOGRAPH
+0xD1D3	0x513A	#CJK UNIFIED IDEOGRAPH
+0xD1D4	0xF90B	#CJK COMPATIBILITY IDEOGRAPH
+0xD1D5	0xF90C	#CJK COMPATIBILITY IDEOGRAPH
+0xD1D6	0x5A1C	#CJK UNIFIED IDEOGRAPH
+0xD1D7	0x61E6	#CJK UNIFIED IDEOGRAPH
+0xD1D8	0xF90D	#CJK COMPATIBILITY IDEOGRAPH
+0xD1D9	0x62CF	#CJK UNIFIED IDEOGRAPH
+0xD1DA	0x62FF	#CJK UNIFIED IDEOGRAPH
+0xD1DB	0xF90E	#CJK COMPATIBILITY IDEOGRAPH
+0xD1DC	0xF90F	#CJK COMPATIBILITY IDEOGRAPH
+0xD1DD	0xF910	#CJK COMPATIBILITY IDEOGRAPH
+0xD1DE	0xF911	#CJK COMPATIBILITY IDEOGRAPH
+0xD1DF	0xF912	#CJK COMPATIBILITY IDEOGRAPH
+0xD1E0	0xF913	#CJK COMPATIBILITY IDEOGRAPH
+0xD1E1	0x90A3	#CJK UNIFIED IDEOGRAPH
+0xD1E2	0xF914	#CJK COMPATIBILITY IDEOGRAPH
+0xD1E3	0xF915	#CJK COMPATIBILITY IDEOGRAPH
+0xD1E4	0xF916	#CJK COMPATIBILITY IDEOGRAPH
+0xD1E5	0xF917	#CJK COMPATIBILITY IDEOGRAPH
+0xD1E6	0xF918	#CJK COMPATIBILITY IDEOGRAPH
+0xD1E7	0x8AFE	#CJK UNIFIED IDEOGRAPH
+0xD1E8	0xF919	#CJK COMPATIBILITY IDEOGRAPH
+0xD1E9	0xF91A	#CJK COMPATIBILITY IDEOGRAPH
+0xD1EA	0xF91B	#CJK COMPATIBILITY IDEOGRAPH
+0xD1EB	0xF91C	#CJK COMPATIBILITY IDEOGRAPH
+0xD1EC	0x6696	#CJK UNIFIED IDEOGRAPH
+0xD1ED	0xF91D	#CJK COMPATIBILITY IDEOGRAPH
+0xD1EE	0x7156	#CJK UNIFIED IDEOGRAPH
+0xD1EF	0xF91E	#CJK COMPATIBILITY IDEOGRAPH
+0xD1F0	0xF91F	#CJK COMPATIBILITY IDEOGRAPH
+0xD1F1	0x96E3	#CJK UNIFIED IDEOGRAPH
+0xD1F2	0xF920	#CJK COMPATIBILITY IDEOGRAPH
+0xD1F3	0x634F	#CJK UNIFIED IDEOGRAPH
+0xD1F4	0x637A	#CJK UNIFIED IDEOGRAPH
+0xD1F5	0x5357	#CJK UNIFIED IDEOGRAPH
+0xD1F6	0xF921	#CJK COMPATIBILITY IDEOGRAPH
+0xD1F7	0x678F	#CJK UNIFIED IDEOGRAPH
+0xD1F8	0x6960	#CJK UNIFIED IDEOGRAPH
+0xD1F9	0x6E73	#CJK UNIFIED IDEOGRAPH
+0xD1FA	0xF922	#CJK COMPATIBILITY IDEOGRAPH
+0xD1FB	0x7537	#CJK UNIFIED IDEOGRAPH
+0xD1FC	0xF923	#CJK COMPATIBILITY IDEOGRAPH
+0xD1FD	0xF924	#CJK COMPATIBILITY IDEOGRAPH
+0xD1FE	0xF925	#CJK COMPATIBILITY IDEOGRAPH
+0xD2A1	0x7D0D	#CJK UNIFIED IDEOGRAPH
+0xD2A2	0xF926	#CJK COMPATIBILITY IDEOGRAPH
+0xD2A3	0xF927	#CJK COMPATIBILITY IDEOGRAPH
+0xD2A4	0x8872	#CJK UNIFIED IDEOGRAPH
+0xD2A5	0x56CA	#CJK UNIFIED IDEOGRAPH
+0xD2A6	0x5A18	#CJK UNIFIED IDEOGRAPH
+0xD2A7	0xF928	#CJK COMPATIBILITY IDEOGRAPH
+0xD2A8	0xF929	#CJK COMPATIBILITY IDEOGRAPH
+0xD2A9	0xF92A	#CJK COMPATIBILITY IDEOGRAPH
+0xD2AA	0xF92B	#CJK COMPATIBILITY IDEOGRAPH
+0xD2AB	0xF92C	#CJK COMPATIBILITY IDEOGRAPH
+0xD2AC	0x4E43	#CJK UNIFIED IDEOGRAPH
+0xD2AD	0xF92D	#CJK COMPATIBILITY IDEOGRAPH
+0xD2AE	0x5167	#CJK UNIFIED IDEOGRAPH
+0xD2AF	0x5948	#CJK UNIFIED IDEOGRAPH
+0xD2B0	0x67F0	#CJK UNIFIED IDEOGRAPH
+0xD2B1	0x8010	#CJK UNIFIED IDEOGRAPH
+0xD2B2	0xF92E	#CJK COMPATIBILITY IDEOGRAPH
+0xD2B3	0x5973	#CJK UNIFIED IDEOGRAPH
+0xD2B4	0x5E74	#CJK UNIFIED IDEOGRAPH
+0xD2B5	0x649A	#CJK UNIFIED IDEOGRAPH
+0xD2B6	0x79CA	#CJK UNIFIED IDEOGRAPH
+0xD2B7	0x5FF5	#CJK UNIFIED IDEOGRAPH
+0xD2B8	0x606C	#CJK UNIFIED IDEOGRAPH
+0xD2B9	0x62C8	#CJK UNIFIED IDEOGRAPH
+0xD2BA	0x637B	#CJK UNIFIED IDEOGRAPH
+0xD2BB	0x5BE7	#CJK UNIFIED IDEOGRAPH
+0xD2BC	0x5BD7	#CJK UNIFIED IDEOGRAPH
+0xD2BD	0x52AA	#CJK UNIFIED IDEOGRAPH
+0xD2BE	0xF92F	#CJK COMPATIBILITY IDEOGRAPH
+0xD2BF	0x5974	#CJK UNIFIED IDEOGRAPH
+0xD2C0	0x5F29	#CJK UNIFIED IDEOGRAPH
+0xD2C1	0x6012	#CJK UNIFIED IDEOGRAPH
+0xD2C2	0xF930	#CJK COMPATIBILITY IDEOGRAPH
+0xD2C3	0xF931	#CJK COMPATIBILITY IDEOGRAPH
+0xD2C4	0xF932	#CJK COMPATIBILITY IDEOGRAPH
+0xD2C5	0x7459	#CJK UNIFIED IDEOGRAPH
+0xD2C6	0xF933	#CJK COMPATIBILITY IDEOGRAPH
+0xD2C7	0xF934	#CJK COMPATIBILITY IDEOGRAPH
+0xD2C8	0xF935	#CJK COMPATIBILITY IDEOGRAPH
+0xD2C9	0xF936	#CJK COMPATIBILITY IDEOGRAPH
+0xD2CA	0xF937	#CJK COMPATIBILITY IDEOGRAPH
+0xD2CB	0xF938	#CJK COMPATIBILITY IDEOGRAPH
+0xD2CC	0x99D1	#CJK UNIFIED IDEOGRAPH
+0xD2CD	0xF939	#CJK COMPATIBILITY IDEOGRAPH
+0xD2CE	0xF93A	#CJK COMPATIBILITY IDEOGRAPH
+0xD2CF	0xF93B	#CJK COMPATIBILITY IDEOGRAPH
+0xD2D0	0xF93C	#CJK COMPATIBILITY IDEOGRAPH
+0xD2D1	0xF93D	#CJK COMPATIBILITY IDEOGRAPH
+0xD2D2	0xF93E	#CJK COMPATIBILITY IDEOGRAPH
+0xD2D3	0xF93F	#CJK COMPATIBILITY IDEOGRAPH
+0xD2D4	0xF940	#CJK COMPATIBILITY IDEOGRAPH
+0xD2D5	0xF941	#CJK COMPATIBILITY IDEOGRAPH
+0xD2D6	0xF942	#CJK COMPATIBILITY IDEOGRAPH
+0xD2D7	0xF943	#CJK COMPATIBILITY IDEOGRAPH
+0xD2D8	0x6FC3	#CJK UNIFIED IDEOGRAPH
+0xD2D9	0xF944	#CJK COMPATIBILITY IDEOGRAPH
+0xD2DA	0xF945	#CJK COMPATIBILITY IDEOGRAPH
+0xD2DB	0x81BF	#CJK UNIFIED IDEOGRAPH
+0xD2DC	0x8FB2	#CJK UNIFIED IDEOGRAPH
+0xD2DD	0x60F1	#CJK UNIFIED IDEOGRAPH
+0xD2DE	0xF946	#CJK COMPATIBILITY IDEOGRAPH
+0xD2DF	0xF947	#CJK COMPATIBILITY IDEOGRAPH
+0xD2E0	0x8166	#CJK UNIFIED IDEOGRAPH
+0xD2E1	0xF948	#CJK COMPATIBILITY IDEOGRAPH
+0xD2E2	0xF949	#CJK COMPATIBILITY IDEOGRAPH
+0xD2E3	0x5C3F	#CJK UNIFIED IDEOGRAPH
+0xD2E4	0xF94A	#CJK COMPATIBILITY IDEOGRAPH
+0xD2E5	0xF94B	#CJK COMPATIBILITY IDEOGRAPH
+0xD2E6	0xF94C	#CJK COMPATIBILITY IDEOGRAPH
+0xD2E7	0xF94D	#CJK COMPATIBILITY IDEOGRAPH
+0xD2E8	0xF94E	#CJK COMPATIBILITY IDEOGRAPH
+0xD2E9	0xF94F	#CJK COMPATIBILITY IDEOGRAPH
+0xD2EA	0xF950	#CJK COMPATIBILITY IDEOGRAPH
+0xD2EB	0xF951	#CJK COMPATIBILITY IDEOGRAPH
+0xD2EC	0x5AE9	#CJK UNIFIED IDEOGRAPH
+0xD2ED	0x8A25	#CJK UNIFIED IDEOGRAPH
+0xD2EE	0x677B	#CJK UNIFIED IDEOGRAPH
+0xD2EF	0x7D10	#CJK UNIFIED IDEOGRAPH
+0xD2F0	0xF952	#CJK COMPATIBILITY IDEOGRAPH
+0xD2F1	0xF953	#CJK COMPATIBILITY IDEOGRAPH
+0xD2F2	0xF954	#CJK COMPATIBILITY IDEOGRAPH
+0xD2F3	0xF955	#CJK COMPATIBILITY IDEOGRAPH
+0xD2F4	0xF956	#CJK COMPATIBILITY IDEOGRAPH
+0xD2F5	0xF957	#CJK COMPATIBILITY IDEOGRAPH
+0xD2F6	0x80FD	#CJK UNIFIED IDEOGRAPH
+0xD2F7	0xF958	#CJK COMPATIBILITY IDEOGRAPH
+0xD2F8	0xF959	#CJK COMPATIBILITY IDEOGRAPH
+0xD2F9	0x5C3C	#CJK UNIFIED IDEOGRAPH
+0xD2FA	0x6CE5	#CJK UNIFIED IDEOGRAPH
+0xD2FB	0x533F	#CJK UNIFIED IDEOGRAPH
+0xD2FC	0x6EBA	#CJK UNIFIED IDEOGRAPH
+0xD2FD	0x591A	#CJK UNIFIED IDEOGRAPH
+0xD2FE	0x8336	#CJK UNIFIED IDEOGRAPH
+0xD3A1	0x4E39	#CJK UNIFIED IDEOGRAPH
+0xD3A2	0x4EB6	#CJK UNIFIED IDEOGRAPH
+0xD3A3	0x4F46	#CJK UNIFIED IDEOGRAPH
+0xD3A4	0x55AE	#CJK UNIFIED IDEOGRAPH
+0xD3A5	0x5718	#CJK UNIFIED IDEOGRAPH
+0xD3A6	0x58C7	#CJK UNIFIED IDEOGRAPH
+0xD3A7	0x5F56	#CJK UNIFIED IDEOGRAPH
+0xD3A8	0x65B7	#CJK UNIFIED IDEOGRAPH
+0xD3A9	0x65E6	#CJK UNIFIED IDEOGRAPH
+0xD3AA	0x6A80	#CJK UNIFIED IDEOGRAPH
+0xD3AB	0x6BB5	#CJK UNIFIED IDEOGRAPH
+0xD3AC	0x6E4D	#CJK UNIFIED IDEOGRAPH
+0xD3AD	0x77ED	#CJK UNIFIED IDEOGRAPH
+0xD3AE	0x7AEF	#CJK UNIFIED IDEOGRAPH
+0xD3AF	0x7C1E	#CJK UNIFIED IDEOGRAPH
+0xD3B0	0x7DDE	#CJK UNIFIED IDEOGRAPH
+0xD3B1	0x86CB	#CJK UNIFIED IDEOGRAPH
+0xD3B2	0x8892	#CJK UNIFIED IDEOGRAPH
+0xD3B3	0x9132	#CJK UNIFIED IDEOGRAPH
+0xD3B4	0x935B	#CJK UNIFIED IDEOGRAPH
+0xD3B5	0x64BB	#CJK UNIFIED IDEOGRAPH
+0xD3B6	0x6FBE	#CJK UNIFIED IDEOGRAPH
+0xD3B7	0x737A	#CJK UNIFIED IDEOGRAPH
+0xD3B8	0x75B8	#CJK UNIFIED IDEOGRAPH
+0xD3B9	0x9054	#CJK UNIFIED IDEOGRAPH
+0xD3BA	0x5556	#CJK UNIFIED IDEOGRAPH
+0xD3BB	0x574D	#CJK UNIFIED IDEOGRAPH
+0xD3BC	0x61BA	#CJK UNIFIED IDEOGRAPH
+0xD3BD	0x64D4	#CJK UNIFIED IDEOGRAPH
+0xD3BE	0x66C7	#CJK UNIFIED IDEOGRAPH
+0xD3BF	0x6DE1	#CJK UNIFIED IDEOGRAPH
+0xD3C0	0x6E5B	#CJK UNIFIED IDEOGRAPH
+0xD3C1	0x6F6D	#CJK UNIFIED IDEOGRAPH
+0xD3C2	0x6FB9	#CJK UNIFIED IDEOGRAPH
+0xD3C3	0x75F0	#CJK UNIFIED IDEOGRAPH
+0xD3C4	0x8043	#CJK UNIFIED IDEOGRAPH
+0xD3C5	0x81BD	#CJK UNIFIED IDEOGRAPH
+0xD3C6	0x8541	#CJK UNIFIED IDEOGRAPH
+0xD3C7	0x8983	#CJK UNIFIED IDEOGRAPH
+0xD3C8	0x8AC7	#CJK UNIFIED IDEOGRAPH
+0xD3C9	0x8B5A	#CJK UNIFIED IDEOGRAPH
+0xD3CA	0x931F	#CJK UNIFIED IDEOGRAPH
+0xD3CB	0x6C93	#CJK UNIFIED IDEOGRAPH
+0xD3CC	0x7553	#CJK UNIFIED IDEOGRAPH
+0xD3CD	0x7B54	#CJK UNIFIED IDEOGRAPH
+0xD3CE	0x8E0F	#CJK UNIFIED IDEOGRAPH
+0xD3CF	0x905D	#CJK UNIFIED IDEOGRAPH
+0xD3D0	0x5510	#CJK UNIFIED IDEOGRAPH
+0xD3D1	0x5802	#CJK UNIFIED IDEOGRAPH
+0xD3D2	0x5858	#CJK UNIFIED IDEOGRAPH
+0xD3D3	0x5E62	#CJK UNIFIED IDEOGRAPH
+0xD3D4	0x6207	#CJK UNIFIED IDEOGRAPH
+0xD3D5	0x649E	#CJK UNIFIED IDEOGRAPH
+0xD3D6	0x68E0	#CJK UNIFIED IDEOGRAPH
+0xD3D7	0x7576	#CJK UNIFIED IDEOGRAPH
+0xD3D8	0x7CD6	#CJK UNIFIED IDEOGRAPH
+0xD3D9	0x87B3	#CJK UNIFIED IDEOGRAPH
+0xD3DA	0x9EE8	#CJK UNIFIED IDEOGRAPH
+0xD3DB	0x4EE3	#CJK UNIFIED IDEOGRAPH
+0xD3DC	0x5788	#CJK UNIFIED IDEOGRAPH
+0xD3DD	0x576E	#CJK UNIFIED IDEOGRAPH
+0xD3DE	0x5927	#CJK UNIFIED IDEOGRAPH
+0xD3DF	0x5C0D	#CJK UNIFIED IDEOGRAPH
+0xD3E0	0x5CB1	#CJK UNIFIED IDEOGRAPH
+0xD3E1	0x5E36	#CJK UNIFIED IDEOGRAPH
+0xD3E2	0x5F85	#CJK UNIFIED IDEOGRAPH
+0xD3E3	0x6234	#CJK UNIFIED IDEOGRAPH
+0xD3E4	0x64E1	#CJK UNIFIED IDEOGRAPH
+0xD3E5	0x73B3	#CJK UNIFIED IDEOGRAPH
+0xD3E6	0x81FA	#CJK UNIFIED IDEOGRAPH
+0xD3E7	0x888B	#CJK UNIFIED IDEOGRAPH
+0xD3E8	0x8CB8	#CJK UNIFIED IDEOGRAPH
+0xD3E9	0x968A	#CJK UNIFIED IDEOGRAPH
+0xD3EA	0x9EDB	#CJK UNIFIED IDEOGRAPH
+0xD3EB	0x5B85	#CJK UNIFIED IDEOGRAPH
+0xD3EC	0x5FB7	#CJK UNIFIED IDEOGRAPH
+0xD3ED	0x60B3	#CJK UNIFIED IDEOGRAPH
+0xD3EE	0x5012	#CJK UNIFIED IDEOGRAPH
+0xD3EF	0x5200	#CJK UNIFIED IDEOGRAPH
+0xD3F0	0x5230	#CJK UNIFIED IDEOGRAPH
+0xD3F1	0x5716	#CJK UNIFIED IDEOGRAPH
+0xD3F2	0x5835	#CJK UNIFIED IDEOGRAPH
+0xD3F3	0x5857	#CJK UNIFIED IDEOGRAPH
+0xD3F4	0x5C0E	#CJK UNIFIED IDEOGRAPH
+0xD3F5	0x5C60	#CJK UNIFIED IDEOGRAPH
+0xD3F6	0x5CF6	#CJK UNIFIED IDEOGRAPH
+0xD3F7	0x5D8B	#CJK UNIFIED IDEOGRAPH
+0xD3F8	0x5EA6	#CJK UNIFIED IDEOGRAPH
+0xD3F9	0x5F92	#CJK UNIFIED IDEOGRAPH
+0xD3FA	0x60BC	#CJK UNIFIED IDEOGRAPH
+0xD3FB	0x6311	#CJK UNIFIED IDEOGRAPH
+0xD3FC	0x6389	#CJK UNIFIED IDEOGRAPH
+0xD3FD	0x6417	#CJK UNIFIED IDEOGRAPH
+0xD3FE	0x6843	#CJK UNIFIED IDEOGRAPH
+0xD4A1	0x68F9	#CJK UNIFIED IDEOGRAPH
+0xD4A2	0x6AC2	#CJK UNIFIED IDEOGRAPH
+0xD4A3	0x6DD8	#CJK UNIFIED IDEOGRAPH
+0xD4A4	0x6E21	#CJK UNIFIED IDEOGRAPH
+0xD4A5	0x6ED4	#CJK UNIFIED IDEOGRAPH
+0xD4A6	0x6FE4	#CJK UNIFIED IDEOGRAPH
+0xD4A7	0x71FE	#CJK UNIFIED IDEOGRAPH
+0xD4A8	0x76DC	#CJK UNIFIED IDEOGRAPH
+0xD4A9	0x7779	#CJK UNIFIED IDEOGRAPH
+0xD4AA	0x79B1	#CJK UNIFIED IDEOGRAPH
+0xD4AB	0x7A3B	#CJK UNIFIED IDEOGRAPH
+0xD4AC	0x8404	#CJK UNIFIED IDEOGRAPH
+0xD4AD	0x89A9	#CJK UNIFIED IDEOGRAPH
+0xD4AE	0x8CED	#CJK UNIFIED IDEOGRAPH
+0xD4AF	0x8DF3	#CJK UNIFIED IDEOGRAPH
+0xD4B0	0x8E48	#CJK UNIFIED IDEOGRAPH
+0xD4B1	0x9003	#CJK UNIFIED IDEOGRAPH
+0xD4B2	0x9014	#CJK UNIFIED IDEOGRAPH
+0xD4B3	0x9053	#CJK UNIFIED IDEOGRAPH
+0xD4B4	0x90FD	#CJK UNIFIED IDEOGRAPH
+0xD4B5	0x934D	#CJK UNIFIED IDEOGRAPH
+0xD4B6	0x9676	#CJK UNIFIED IDEOGRAPH
+0xD4B7	0x97DC	#CJK UNIFIED IDEOGRAPH
+0xD4B8	0x6BD2	#CJK UNIFIED IDEOGRAPH
+0xD4B9	0x7006	#CJK UNIFIED IDEOGRAPH
+0xD4BA	0x7258	#CJK UNIFIED IDEOGRAPH
+0xD4BB	0x72A2	#CJK UNIFIED IDEOGRAPH
+0xD4BC	0x7368	#CJK UNIFIED IDEOGRAPH
+0xD4BD	0x7763	#CJK UNIFIED IDEOGRAPH
+0xD4BE	0x79BF	#CJK UNIFIED IDEOGRAPH
+0xD4BF	0x7BE4	#CJK UNIFIED IDEOGRAPH
+0xD4C0	0x7E9B	#CJK UNIFIED IDEOGRAPH
+0xD4C1	0x8B80	#CJK UNIFIED IDEOGRAPH
+0xD4C2	0x58A9	#CJK UNIFIED IDEOGRAPH
+0xD4C3	0x60C7	#CJK UNIFIED IDEOGRAPH
+0xD4C4	0x6566	#CJK UNIFIED IDEOGRAPH
+0xD4C5	0x65FD	#CJK UNIFIED IDEOGRAPH
+0xD4C6	0x66BE	#CJK UNIFIED IDEOGRAPH
+0xD4C7	0x6C8C	#CJK UNIFIED IDEOGRAPH
+0xD4C8	0x711E	#CJK UNIFIED IDEOGRAPH
+0xD4C9	0x71C9	#CJK UNIFIED IDEOGRAPH
+0xD4CA	0x8C5A	#CJK UNIFIED IDEOGRAPH
+0xD4CB	0x9813	#CJK UNIFIED IDEOGRAPH
+0xD4CC	0x4E6D	#CJK UNIFIED IDEOGRAPH
+0xD4CD	0x7A81	#CJK UNIFIED IDEOGRAPH
+0xD4CE	0x4EDD	#CJK UNIFIED IDEOGRAPH
+0xD4CF	0x51AC	#CJK UNIFIED IDEOGRAPH
+0xD4D0	0x51CD	#CJK UNIFIED IDEOGRAPH
+0xD4D1	0x52D5	#CJK UNIFIED IDEOGRAPH
+0xD4D2	0x540C	#CJK UNIFIED IDEOGRAPH
+0xD4D3	0x61A7	#CJK UNIFIED IDEOGRAPH
+0xD4D4	0x6771	#CJK UNIFIED IDEOGRAPH
+0xD4D5	0x6850	#CJK UNIFIED IDEOGRAPH
+0xD4D6	0x68DF	#CJK UNIFIED IDEOGRAPH
+0xD4D7	0x6D1E	#CJK UNIFIED IDEOGRAPH
+0xD4D8	0x6F7C	#CJK UNIFIED IDEOGRAPH
+0xD4D9	0x75BC	#CJK UNIFIED IDEOGRAPH
+0xD4DA	0x77B3	#CJK UNIFIED IDEOGRAPH
+0xD4DB	0x7AE5	#CJK UNIFIED IDEOGRAPH
+0xD4DC	0x80F4	#CJK UNIFIED IDEOGRAPH
+0xD4DD	0x8463	#CJK UNIFIED IDEOGRAPH
+0xD4DE	0x9285	#CJK UNIFIED IDEOGRAPH
+0xD4DF	0x515C	#CJK UNIFIED IDEOGRAPH
+0xD4E0	0x6597	#CJK UNIFIED IDEOGRAPH
+0xD4E1	0x675C	#CJK UNIFIED IDEOGRAPH
+0xD4E2	0x6793	#CJK UNIFIED IDEOGRAPH
+0xD4E3	0x75D8	#CJK UNIFIED IDEOGRAPH
+0xD4E4	0x7AC7	#CJK UNIFIED IDEOGRAPH
+0xD4E5	0x8373	#CJK UNIFIED IDEOGRAPH
+0xD4E6	0xF95A	#CJK COMPATIBILITY IDEOGRAPH
+0xD4E7	0x8C46	#CJK UNIFIED IDEOGRAPH
+0xD4E8	0x9017	#CJK UNIFIED IDEOGRAPH
+0xD4E9	0x982D	#CJK UNIFIED IDEOGRAPH
+0xD4EA	0x5C6F	#CJK UNIFIED IDEOGRAPH
+0xD4EB	0x81C0	#CJK UNIFIED IDEOGRAPH
+0xD4EC	0x829A	#CJK UNIFIED IDEOGRAPH
+0xD4ED	0x9041	#CJK UNIFIED IDEOGRAPH
+0xD4EE	0x906F	#CJK UNIFIED IDEOGRAPH
+0xD4EF	0x920D	#CJK UNIFIED IDEOGRAPH
+0xD4F0	0x5F97	#CJK UNIFIED IDEOGRAPH
+0xD4F1	0x5D9D	#CJK UNIFIED IDEOGRAPH
+0xD4F2	0x6A59	#CJK UNIFIED IDEOGRAPH
+0xD4F3	0x71C8	#CJK UNIFIED IDEOGRAPH
+0xD4F4	0x767B	#CJK UNIFIED IDEOGRAPH
+0xD4F5	0x7B49	#CJK UNIFIED IDEOGRAPH
+0xD4F6	0x85E4	#CJK UNIFIED IDEOGRAPH
+0xD4F7	0x8B04	#CJK UNIFIED IDEOGRAPH
+0xD4F8	0x9127	#CJK UNIFIED IDEOGRAPH
+0xD4F9	0x9A30	#CJK UNIFIED IDEOGRAPH
+0xD4FA	0x5587	#CJK UNIFIED IDEOGRAPH
+0xD4FB	0x61F6	#CJK UNIFIED IDEOGRAPH
+0xD4FC	0xF95B	#CJK COMPATIBILITY IDEOGRAPH
+0xD4FD	0x7669	#CJK UNIFIED IDEOGRAPH
+0xD4FE	0x7F85	#CJK UNIFIED IDEOGRAPH
+0xD5A1	0x863F	#CJK UNIFIED IDEOGRAPH
+0xD5A2	0x87BA	#CJK UNIFIED IDEOGRAPH
+0xD5A3	0x88F8	#CJK UNIFIED IDEOGRAPH
+0xD5A4	0x908F	#CJK UNIFIED IDEOGRAPH
+0xD5A5	0xF95C	#CJK COMPATIBILITY IDEOGRAPH
+0xD5A6	0x6D1B	#CJK UNIFIED IDEOGRAPH
+0xD5A7	0x70D9	#CJK UNIFIED IDEOGRAPH
+0xD5A8	0x73DE	#CJK UNIFIED IDEOGRAPH
+0xD5A9	0x7D61	#CJK UNIFIED IDEOGRAPH
+0xD5AA	0x843D	#CJK UNIFIED IDEOGRAPH
+0xD5AB	0xF95D	#CJK COMPATIBILITY IDEOGRAPH
+0xD5AC	0x916A	#CJK UNIFIED IDEOGRAPH
+0xD5AD	0x99F1	#CJK UNIFIED IDEOGRAPH
+0xD5AE	0xF95E	#CJK COMPATIBILITY IDEOGRAPH
+0xD5AF	0x4E82	#CJK UNIFIED IDEOGRAPH
+0xD5B0	0x5375	#CJK UNIFIED IDEOGRAPH
+0xD5B1	0x6B04	#CJK UNIFIED IDEOGRAPH
+0xD5B2	0x6B12	#CJK UNIFIED IDEOGRAPH
+0xD5B3	0x703E	#CJK UNIFIED IDEOGRAPH
+0xD5B4	0x721B	#CJK UNIFIED IDEOGRAPH
+0xD5B5	0x862D	#CJK UNIFIED IDEOGRAPH
+0xD5B6	0x9E1E	#CJK UNIFIED IDEOGRAPH
+0xD5B7	0x524C	#CJK UNIFIED IDEOGRAPH
+0xD5B8	0x8FA3	#CJK UNIFIED IDEOGRAPH
+0xD5B9	0x5D50	#CJK UNIFIED IDEOGRAPH
+0xD5BA	0x64E5	#CJK UNIFIED IDEOGRAPH
+0xD5BB	0x652C	#CJK UNIFIED IDEOGRAPH
+0xD5BC	0x6B16	#CJK UNIFIED IDEOGRAPH
+0xD5BD	0x6FEB	#CJK UNIFIED IDEOGRAPH
+0xD5BE	0x7C43	#CJK UNIFIED IDEOGRAPH
+0xD5BF	0x7E9C	#CJK UNIFIED IDEOGRAPH
+0xD5C0	0x85CD	#CJK UNIFIED IDEOGRAPH
+0xD5C1	0x8964	#CJK UNIFIED IDEOGRAPH
+0xD5C2	0x89BD	#CJK UNIFIED IDEOGRAPH
+0xD5C3	0x62C9	#CJK UNIFIED IDEOGRAPH
+0xD5C4	0x81D8	#CJK UNIFIED IDEOGRAPH
+0xD5C5	0x881F	#CJK UNIFIED IDEOGRAPH
+0xD5C6	0x5ECA	#CJK UNIFIED IDEOGRAPH
+0xD5C7	0x6717	#CJK UNIFIED IDEOGRAPH
+0xD5C8	0x6D6A	#CJK UNIFIED IDEOGRAPH
+0xD5C9	0x72FC	#CJK UNIFIED IDEOGRAPH
+0xD5CA	0x7405	#CJK UNIFIED IDEOGRAPH
+0xD5CB	0x746F	#CJK UNIFIED IDEOGRAPH
+0xD5CC	0x8782	#CJK UNIFIED IDEOGRAPH
+0xD5CD	0x90DE	#CJK UNIFIED IDEOGRAPH
+0xD5CE	0x4F86	#CJK UNIFIED IDEOGRAPH
+0xD5CF	0x5D0D	#CJK UNIFIED IDEOGRAPH
+0xD5D0	0x5FA0	#CJK UNIFIED IDEOGRAPH
+0xD5D1	0x840A	#CJK UNIFIED IDEOGRAPH
+0xD5D2	0x51B7	#CJK UNIFIED IDEOGRAPH
+0xD5D3	0x63A0	#CJK UNIFIED IDEOGRAPH
+0xD5D4	0x7565	#CJK UNIFIED IDEOGRAPH
+0xD5D5	0x4EAE	#CJK UNIFIED IDEOGRAPH
+0xD5D6	0x5006	#CJK UNIFIED IDEOGRAPH
+0xD5D7	0x5169	#CJK UNIFIED IDEOGRAPH
+0xD5D8	0x51C9	#CJK UNIFIED IDEOGRAPH
+0xD5D9	0x6881	#CJK UNIFIED IDEOGRAPH
+0xD5DA	0x6A11	#CJK UNIFIED IDEOGRAPH
+0xD5DB	0x7CAE	#CJK UNIFIED IDEOGRAPH
+0xD5DC	0x7CB1	#CJK UNIFIED IDEOGRAPH
+0xD5DD	0x7CE7	#CJK UNIFIED IDEOGRAPH
+0xD5DE	0x826F	#CJK UNIFIED IDEOGRAPH
+0xD5DF	0x8AD2	#CJK UNIFIED IDEOGRAPH
+0xD5E0	0x8F1B	#CJK UNIFIED IDEOGRAPH
+0xD5E1	0x91CF	#CJK UNIFIED IDEOGRAPH
+0xD5E2	0x4FB6	#CJK UNIFIED IDEOGRAPH
+0xD5E3	0x5137	#CJK UNIFIED IDEOGRAPH
+0xD5E4	0x52F5	#CJK UNIFIED IDEOGRAPH
+0xD5E5	0x5442	#CJK UNIFIED IDEOGRAPH
+0xD5E6	0x5EEC	#CJK UNIFIED IDEOGRAPH
+0xD5E7	0x616E	#CJK UNIFIED IDEOGRAPH
+0xD5E8	0x623E	#CJK UNIFIED IDEOGRAPH
+0xD5E9	0x65C5	#CJK UNIFIED IDEOGRAPH
+0xD5EA	0x6ADA	#CJK UNIFIED IDEOGRAPH
+0xD5EB	0x6FFE	#CJK UNIFIED IDEOGRAPH
+0xD5EC	0x792A	#CJK UNIFIED IDEOGRAPH
+0xD5ED	0x85DC	#CJK UNIFIED IDEOGRAPH
+0xD5EE	0x8823	#CJK UNIFIED IDEOGRAPH
+0xD5EF	0x95AD	#CJK UNIFIED IDEOGRAPH
+0xD5F0	0x9A62	#CJK UNIFIED IDEOGRAPH
+0xD5F1	0x9A6A	#CJK UNIFIED IDEOGRAPH
+0xD5F2	0x9E97	#CJK UNIFIED IDEOGRAPH
+0xD5F3	0x9ECE	#CJK UNIFIED IDEOGRAPH
+0xD5F4	0x529B	#CJK UNIFIED IDEOGRAPH
+0xD5F5	0x66C6	#CJK UNIFIED IDEOGRAPH
+0xD5F6	0x6B77	#CJK UNIFIED IDEOGRAPH
+0xD5F7	0x701D	#CJK UNIFIED IDEOGRAPH
+0xD5F8	0x792B	#CJK UNIFIED IDEOGRAPH
+0xD5F9	0x8F62	#CJK UNIFIED IDEOGRAPH
+0xD5FA	0x9742	#CJK UNIFIED IDEOGRAPH
+0xD5FB	0x6190	#CJK UNIFIED IDEOGRAPH
+0xD5FC	0x6200	#CJK UNIFIED IDEOGRAPH
+0xD5FD	0x6523	#CJK UNIFIED IDEOGRAPH
+0xD5FE	0x6F23	#CJK UNIFIED IDEOGRAPH
+0xD6A1	0x7149	#CJK UNIFIED IDEOGRAPH
+0xD6A2	0x7489	#CJK UNIFIED IDEOGRAPH
+0xD6A3	0x7DF4	#CJK UNIFIED IDEOGRAPH
+0xD6A4	0x806F	#CJK UNIFIED IDEOGRAPH
+0xD6A5	0x84EE	#CJK UNIFIED IDEOGRAPH
+0xD6A6	0x8F26	#CJK UNIFIED IDEOGRAPH
+0xD6A7	0x9023	#CJK UNIFIED IDEOGRAPH
+0xD6A8	0x934A	#CJK UNIFIED IDEOGRAPH
+0xD6A9	0x51BD	#CJK UNIFIED IDEOGRAPH
+0xD6AA	0x5217	#CJK UNIFIED IDEOGRAPH
+0xD6AB	0x52A3	#CJK UNIFIED IDEOGRAPH
+0xD6AC	0x6D0C	#CJK UNIFIED IDEOGRAPH
+0xD6AD	0x70C8	#CJK UNIFIED IDEOGRAPH
+0xD6AE	0x88C2	#CJK UNIFIED IDEOGRAPH
+0xD6AF	0x5EC9	#CJK UNIFIED IDEOGRAPH
+0xD6B0	0x6582	#CJK UNIFIED IDEOGRAPH
+0xD6B1	0x6BAE	#CJK UNIFIED IDEOGRAPH
+0xD6B2	0x6FC2	#CJK UNIFIED IDEOGRAPH
+0xD6B3	0x7C3E	#CJK UNIFIED IDEOGRAPH
+0xD6B4	0x7375	#CJK UNIFIED IDEOGRAPH
+0xD6B5	0x4EE4	#CJK UNIFIED IDEOGRAPH
+0xD6B6	0x4F36	#CJK UNIFIED IDEOGRAPH
+0xD6B7	0x56F9	#CJK UNIFIED IDEOGRAPH
+0xD6B8	0xF95F	#CJK COMPATIBILITY IDEOGRAPH
+0xD6B9	0x5CBA	#CJK UNIFIED IDEOGRAPH
+0xD6BA	0x5DBA	#CJK UNIFIED IDEOGRAPH
+0xD6BB	0x601C	#CJK UNIFIED IDEOGRAPH
+0xD6BC	0x73B2	#CJK UNIFIED IDEOGRAPH
+0xD6BD	0x7B2D	#CJK UNIFIED IDEOGRAPH
+0xD6BE	0x7F9A	#CJK UNIFIED IDEOGRAPH
+0xD6BF	0x7FCE	#CJK UNIFIED IDEOGRAPH
+0xD6C0	0x8046	#CJK UNIFIED IDEOGRAPH
+0xD6C1	0x901E	#CJK UNIFIED IDEOGRAPH
+0xD6C2	0x9234	#CJK UNIFIED IDEOGRAPH
+0xD6C3	0x96F6	#CJK UNIFIED IDEOGRAPH
+0xD6C4	0x9748	#CJK UNIFIED IDEOGRAPH
+0xD6C5	0x9818	#CJK UNIFIED IDEOGRAPH
+0xD6C6	0x9F61	#CJK UNIFIED IDEOGRAPH
+0xD6C7	0x4F8B	#CJK UNIFIED IDEOGRAPH
+0xD6C8	0x6FA7	#CJK UNIFIED IDEOGRAPH
+0xD6C9	0x79AE	#CJK UNIFIED IDEOGRAPH
+0xD6CA	0x91B4	#CJK UNIFIED IDEOGRAPH
+0xD6CB	0x96B7	#CJK UNIFIED IDEOGRAPH
+0xD6CC	0x52DE	#CJK UNIFIED IDEOGRAPH
+0xD6CD	0xF960	#CJK COMPATIBILITY IDEOGRAPH
+0xD6CE	0x6488	#CJK UNIFIED IDEOGRAPH
+0xD6CF	0x64C4	#CJK UNIFIED IDEOGRAPH
+0xD6D0	0x6AD3	#CJK UNIFIED IDEOGRAPH
+0xD6D1	0x6F5E	#CJK UNIFIED IDEOGRAPH
+0xD6D2	0x7018	#CJK UNIFIED IDEOGRAPH
+0xD6D3	0x7210	#CJK UNIFIED IDEOGRAPH
+0xD6D4	0x76E7	#CJK UNIFIED IDEOGRAPH
+0xD6D5	0x8001	#CJK UNIFIED IDEOGRAPH
+0xD6D6	0x8606	#CJK UNIFIED IDEOGRAPH
+0xD6D7	0x865C	#CJK UNIFIED IDEOGRAPH
+0xD6D8	0x8DEF	#CJK UNIFIED IDEOGRAPH
+0xD6D9	0x8F05	#CJK UNIFIED IDEOGRAPH
+0xD6DA	0x9732	#CJK UNIFIED IDEOGRAPH
+0xD6DB	0x9B6F	#CJK UNIFIED IDEOGRAPH
+0xD6DC	0x9DFA	#CJK UNIFIED IDEOGRAPH
+0xD6DD	0x9E75	#CJK UNIFIED IDEOGRAPH
+0xD6DE	0x788C	#CJK UNIFIED IDEOGRAPH
+0xD6DF	0x797F	#CJK UNIFIED IDEOGRAPH
+0xD6E0	0x7DA0	#CJK UNIFIED IDEOGRAPH
+0xD6E1	0x83C9	#CJK UNIFIED IDEOGRAPH
+0xD6E2	0x9304	#CJK UNIFIED IDEOGRAPH
+0xD6E3	0x9E7F	#CJK UNIFIED IDEOGRAPH
+0xD6E4	0x9E93	#CJK UNIFIED IDEOGRAPH
+0xD6E5	0x8AD6	#CJK UNIFIED IDEOGRAPH
+0xD6E6	0x58DF	#CJK UNIFIED IDEOGRAPH
+0xD6E7	0x5F04	#CJK UNIFIED IDEOGRAPH
+0xD6E8	0x6727	#CJK UNIFIED IDEOGRAPH
+0xD6E9	0x7027	#CJK UNIFIED IDEOGRAPH
+0xD6EA	0x74CF	#CJK UNIFIED IDEOGRAPH
+0xD6EB	0x7C60	#CJK UNIFIED IDEOGRAPH
+0xD6EC	0x807E	#CJK UNIFIED IDEOGRAPH
+0xD6ED	0x5121	#CJK UNIFIED IDEOGRAPH
+0xD6EE	0x7028	#CJK UNIFIED IDEOGRAPH
+0xD6EF	0x7262	#CJK UNIFIED IDEOGRAPH
+0xD6F0	0x78CA	#CJK UNIFIED IDEOGRAPH
+0xD6F1	0x8CC2	#CJK UNIFIED IDEOGRAPH
+0xD6F2	0x8CDA	#CJK UNIFIED IDEOGRAPH
+0xD6F3	0x8CF4	#CJK UNIFIED IDEOGRAPH
+0xD6F4	0x96F7	#CJK UNIFIED IDEOGRAPH
+0xD6F5	0x4E86	#CJK UNIFIED IDEOGRAPH
+0xD6F6	0x50DA	#CJK UNIFIED IDEOGRAPH
+0xD6F7	0x5BEE	#CJK UNIFIED IDEOGRAPH
+0xD6F8	0x5ED6	#CJK UNIFIED IDEOGRAPH
+0xD6F9	0x6599	#CJK UNIFIED IDEOGRAPH
+0xD6FA	0x71CE	#CJK UNIFIED IDEOGRAPH
+0xD6FB	0x7642	#CJK UNIFIED IDEOGRAPH
+0xD6FC	0x77AD	#CJK UNIFIED IDEOGRAPH
+0xD6FD	0x804A	#CJK UNIFIED IDEOGRAPH
+0xD6FE	0x84FC	#CJK UNIFIED IDEOGRAPH
+0xD7A1	0x907C	#CJK UNIFIED IDEOGRAPH
+0xD7A2	0x9B27	#CJK UNIFIED IDEOGRAPH
+0xD7A3	0x9F8D	#CJK UNIFIED IDEOGRAPH
+0xD7A4	0x58D8	#CJK UNIFIED IDEOGRAPH
+0xD7A5	0x5A41	#CJK UNIFIED IDEOGRAPH
+0xD7A6	0x5C62	#CJK UNIFIED IDEOGRAPH
+0xD7A7	0x6A13	#CJK UNIFIED IDEOGRAPH
+0xD7A8	0x6DDA	#CJK UNIFIED IDEOGRAPH
+0xD7A9	0x6F0F	#CJK UNIFIED IDEOGRAPH
+0xD7AA	0x763B	#CJK UNIFIED IDEOGRAPH
+0xD7AB	0x7D2F	#CJK UNIFIED IDEOGRAPH
+0xD7AC	0x7E37	#CJK UNIFIED IDEOGRAPH
+0xD7AD	0x851E	#CJK UNIFIED IDEOGRAPH
+0xD7AE	0x8938	#CJK UNIFIED IDEOGRAPH
+0xD7AF	0x93E4	#CJK UNIFIED IDEOGRAPH
+0xD7B0	0x964B	#CJK UNIFIED IDEOGRAPH
+0xD7B1	0x5289	#CJK UNIFIED IDEOGRAPH
+0xD7B2	0x65D2	#CJK UNIFIED IDEOGRAPH
+0xD7B3	0x67F3	#CJK UNIFIED IDEOGRAPH
+0xD7B4	0x69B4	#CJK UNIFIED IDEOGRAPH
+0xD7B5	0x6D41	#CJK UNIFIED IDEOGRAPH
+0xD7B6	0x6E9C	#CJK UNIFIED IDEOGRAPH
+0xD7B7	0x700F	#CJK UNIFIED IDEOGRAPH
+0xD7B8	0x7409	#CJK UNIFIED IDEOGRAPH
+0xD7B9	0x7460	#CJK UNIFIED IDEOGRAPH
+0xD7BA	0x7559	#CJK UNIFIED IDEOGRAPH
+0xD7BB	0x7624	#CJK UNIFIED IDEOGRAPH
+0xD7BC	0x786B	#CJK UNIFIED IDEOGRAPH
+0xD7BD	0x8B2C	#CJK UNIFIED IDEOGRAPH
+0xD7BE	0x985E	#CJK UNIFIED IDEOGRAPH
+0xD7BF	0x516D	#CJK UNIFIED IDEOGRAPH
+0xD7C0	0x622E	#CJK UNIFIED IDEOGRAPH
+0xD7C1	0x9678	#CJK UNIFIED IDEOGRAPH
+0xD7C2	0x4F96	#CJK UNIFIED IDEOGRAPH
+0xD7C3	0x502B	#CJK UNIFIED IDEOGRAPH
+0xD7C4	0x5D19	#CJK UNIFIED IDEOGRAPH
+0xD7C5	0x6DEA	#CJK UNIFIED IDEOGRAPH
+0xD7C6	0x7DB8	#CJK UNIFIED IDEOGRAPH
+0xD7C7	0x8F2A	#CJK UNIFIED IDEOGRAPH
+0xD7C8	0x5F8B	#CJK UNIFIED IDEOGRAPH
+0xD7C9	0x6144	#CJK UNIFIED IDEOGRAPH
+0xD7CA	0x6817	#CJK UNIFIED IDEOGRAPH
+0xD7CB	0xF961	#CJK COMPATIBILITY IDEOGRAPH
+0xD7CC	0x9686	#CJK UNIFIED IDEOGRAPH
+0xD7CD	0x52D2	#CJK UNIFIED IDEOGRAPH
+0xD7CE	0x808B	#CJK UNIFIED IDEOGRAPH
+0xD7CF	0x51DC	#CJK UNIFIED IDEOGRAPH
+0xD7D0	0x51CC	#CJK UNIFIED IDEOGRAPH
+0xD7D1	0x695E	#CJK UNIFIED IDEOGRAPH
+0xD7D2	0x7A1C	#CJK UNIFIED IDEOGRAPH
+0xD7D3	0x7DBE	#CJK UNIFIED IDEOGRAPH
+0xD7D4	0x83F1	#CJK UNIFIED IDEOGRAPH
+0xD7D5	0x9675	#CJK UNIFIED IDEOGRAPH
+0xD7D6	0x4FDA	#CJK UNIFIED IDEOGRAPH
+0xD7D7	0x5229	#CJK UNIFIED IDEOGRAPH
+0xD7D8	0x5398	#CJK UNIFIED IDEOGRAPH
+0xD7D9	0x540F	#CJK UNIFIED IDEOGRAPH
+0xD7DA	0x550E	#CJK UNIFIED IDEOGRAPH
+0xD7DB	0x5C65	#CJK UNIFIED IDEOGRAPH
+0xD7DC	0x60A7	#CJK UNIFIED IDEOGRAPH
+0xD7DD	0x674E	#CJK UNIFIED IDEOGRAPH
+0xD7DE	0x68A8	#CJK UNIFIED IDEOGRAPH
+0xD7DF	0x6D6C	#CJK UNIFIED IDEOGRAPH
+0xD7E0	0x7281	#CJK UNIFIED IDEOGRAPH
+0xD7E1	0x72F8	#CJK UNIFIED IDEOGRAPH
+0xD7E2	0x7406	#CJK UNIFIED IDEOGRAPH
+0xD7E3	0x7483	#CJK UNIFIED IDEOGRAPH
+0xD7E4	0xF962	#CJK COMPATIBILITY IDEOGRAPH
+0xD7E5	0x75E2	#CJK UNIFIED IDEOGRAPH
+0xD7E6	0x7C6C	#CJK UNIFIED IDEOGRAPH
+0xD7E7	0x7F79	#CJK UNIFIED IDEOGRAPH
+0xD7E8	0x7FB8	#CJK UNIFIED IDEOGRAPH
+0xD7E9	0x8389	#CJK UNIFIED IDEOGRAPH
+0xD7EA	0x88CF	#CJK UNIFIED IDEOGRAPH
+0xD7EB	0x88E1	#CJK UNIFIED IDEOGRAPH
+0xD7EC	0x91CC	#CJK UNIFIED IDEOGRAPH
+0xD7ED	0x91D0	#CJK UNIFIED IDEOGRAPH
+0xD7EE	0x96E2	#CJK UNIFIED IDEOGRAPH
+0xD7EF	0x9BC9	#CJK UNIFIED IDEOGRAPH
+0xD7F0	0x541D	#CJK UNIFIED IDEOGRAPH
+0xD7F1	0x6F7E	#CJK UNIFIED IDEOGRAPH
+0xD7F2	0x71D0	#CJK UNIFIED IDEOGRAPH
+0xD7F3	0x7498	#CJK UNIFIED IDEOGRAPH
+0xD7F4	0x85FA	#CJK UNIFIED IDEOGRAPH
+0xD7F5	0x8EAA	#CJK UNIFIED IDEOGRAPH
+0xD7F6	0x96A3	#CJK UNIFIED IDEOGRAPH
+0xD7F7	0x9C57	#CJK UNIFIED IDEOGRAPH
+0xD7F8	0x9E9F	#CJK UNIFIED IDEOGRAPH
+0xD7F9	0x6797	#CJK UNIFIED IDEOGRAPH
+0xD7FA	0x6DCB	#CJK UNIFIED IDEOGRAPH
+0xD7FB	0x7433	#CJK UNIFIED IDEOGRAPH
+0xD7FC	0x81E8	#CJK UNIFIED IDEOGRAPH
+0xD7FD	0x9716	#CJK UNIFIED IDEOGRAPH
+0xD7FE	0x782C	#CJK UNIFIED IDEOGRAPH
+0xD8A1	0x7ACB	#CJK UNIFIED IDEOGRAPH
+0xD8A2	0x7B20	#CJK UNIFIED IDEOGRAPH
+0xD8A3	0x7C92	#CJK UNIFIED IDEOGRAPH
+0xD8A4	0x6469	#CJK UNIFIED IDEOGRAPH
+0xD8A5	0x746A	#CJK UNIFIED IDEOGRAPH
+0xD8A6	0x75F2	#CJK UNIFIED IDEOGRAPH
+0xD8A7	0x78BC	#CJK UNIFIED IDEOGRAPH
+0xD8A8	0x78E8	#CJK UNIFIED IDEOGRAPH
+0xD8A9	0x99AC	#CJK UNIFIED IDEOGRAPH
+0xD8AA	0x9B54	#CJK UNIFIED IDEOGRAPH
+0xD8AB	0x9EBB	#CJK UNIFIED IDEOGRAPH
+0xD8AC	0x5BDE	#CJK UNIFIED IDEOGRAPH
+0xD8AD	0x5E55	#CJK UNIFIED IDEOGRAPH
+0xD8AE	0x6F20	#CJK UNIFIED IDEOGRAPH
+0xD8AF	0x819C	#CJK UNIFIED IDEOGRAPH
+0xD8B0	0x83AB	#CJK UNIFIED IDEOGRAPH
+0xD8B1	0x9088	#CJK UNIFIED IDEOGRAPH
+0xD8B2	0x4E07	#CJK UNIFIED IDEOGRAPH
+0xD8B3	0x534D	#CJK UNIFIED IDEOGRAPH
+0xD8B4	0x5A29	#CJK UNIFIED IDEOGRAPH
+0xD8B5	0x5DD2	#CJK UNIFIED IDEOGRAPH
+0xD8B6	0x5F4E	#CJK UNIFIED IDEOGRAPH
+0xD8B7	0x6162	#CJK UNIFIED IDEOGRAPH
+0xD8B8	0x633D	#CJK UNIFIED IDEOGRAPH
+0xD8B9	0x6669	#CJK UNIFIED IDEOGRAPH
+0xD8BA	0x66FC	#CJK UNIFIED IDEOGRAPH
+0xD8BB	0x6EFF	#CJK UNIFIED IDEOGRAPH
+0xD8BC	0x6F2B	#CJK UNIFIED IDEOGRAPH
+0xD8BD	0x7063	#CJK UNIFIED IDEOGRAPH
+0xD8BE	0x779E	#CJK UNIFIED IDEOGRAPH
+0xD8BF	0x842C	#CJK UNIFIED IDEOGRAPH
+0xD8C0	0x8513	#CJK UNIFIED IDEOGRAPH
+0xD8C1	0x883B	#CJK UNIFIED IDEOGRAPH
+0xD8C2	0x8F13	#CJK UNIFIED IDEOGRAPH
+0xD8C3	0x9945	#CJK UNIFIED IDEOGRAPH
+0xD8C4	0x9C3B	#CJK UNIFIED IDEOGRAPH
+0xD8C5	0x551C	#CJK UNIFIED IDEOGRAPH
+0xD8C6	0x62B9	#CJK UNIFIED IDEOGRAPH
+0xD8C7	0x672B	#CJK UNIFIED IDEOGRAPH
+0xD8C8	0x6CAB	#CJK UNIFIED IDEOGRAPH
+0xD8C9	0x8309	#CJK UNIFIED IDEOGRAPH
+0xD8CA	0x896A	#CJK UNIFIED IDEOGRAPH
+0xD8CB	0x977A	#CJK UNIFIED IDEOGRAPH
+0xD8CC	0x4EA1	#CJK UNIFIED IDEOGRAPH
+0xD8CD	0x5984	#CJK UNIFIED IDEOGRAPH
+0xD8CE	0x5FD8	#CJK UNIFIED IDEOGRAPH
+0xD8CF	0x5FD9	#CJK UNIFIED IDEOGRAPH
+0xD8D0	0x671B	#CJK UNIFIED IDEOGRAPH
+0xD8D1	0x7DB2	#CJK UNIFIED IDEOGRAPH
+0xD8D2	0x7F54	#CJK UNIFIED IDEOGRAPH
+0xD8D3	0x8292	#CJK UNIFIED IDEOGRAPH
+0xD8D4	0x832B	#CJK UNIFIED IDEOGRAPH
+0xD8D5	0x83BD	#CJK UNIFIED IDEOGRAPH
+0xD8D6	0x8F1E	#CJK UNIFIED IDEOGRAPH
+0xD8D7	0x9099	#CJK UNIFIED IDEOGRAPH
+0xD8D8	0x57CB	#CJK UNIFIED IDEOGRAPH
+0xD8D9	0x59B9	#CJK UNIFIED IDEOGRAPH
+0xD8DA	0x5A92	#CJK UNIFIED IDEOGRAPH
+0xD8DB	0x5BD0	#CJK UNIFIED IDEOGRAPH
+0xD8DC	0x6627	#CJK UNIFIED IDEOGRAPH
+0xD8DD	0x679A	#CJK UNIFIED IDEOGRAPH
+0xD8DE	0x6885	#CJK UNIFIED IDEOGRAPH
+0xD8DF	0x6BCF	#CJK UNIFIED IDEOGRAPH
+0xD8E0	0x7164	#CJK UNIFIED IDEOGRAPH
+0xD8E1	0x7F75	#CJK UNIFIED IDEOGRAPH
+0xD8E2	0x8CB7	#CJK UNIFIED IDEOGRAPH
+0xD8E3	0x8CE3	#CJK UNIFIED IDEOGRAPH
+0xD8E4	0x9081	#CJK UNIFIED IDEOGRAPH
+0xD8E5	0x9B45	#CJK UNIFIED IDEOGRAPH
+0xD8E6	0x8108	#CJK UNIFIED IDEOGRAPH
+0xD8E7	0x8C8A	#CJK UNIFIED IDEOGRAPH
+0xD8E8	0x964C	#CJK UNIFIED IDEOGRAPH
+0xD8E9	0x9A40	#CJK UNIFIED IDEOGRAPH
+0xD8EA	0x9EA5	#CJK UNIFIED IDEOGRAPH
+0xD8EB	0x5B5F	#CJK UNIFIED IDEOGRAPH
+0xD8EC	0x6C13	#CJK UNIFIED IDEOGRAPH
+0xD8ED	0x731B	#CJK UNIFIED IDEOGRAPH
+0xD8EE	0x76F2	#CJK UNIFIED IDEOGRAPH
+0xD8EF	0x76DF	#CJK UNIFIED IDEOGRAPH
+0xD8F0	0x840C	#CJK UNIFIED IDEOGRAPH
+0xD8F1	0x51AA	#CJK UNIFIED IDEOGRAPH
+0xD8F2	0x8993	#CJK UNIFIED IDEOGRAPH
+0xD8F3	0x514D	#CJK UNIFIED IDEOGRAPH
+0xD8F4	0x5195	#CJK UNIFIED IDEOGRAPH
+0xD8F5	0x52C9	#CJK UNIFIED IDEOGRAPH
+0xD8F6	0x68C9	#CJK UNIFIED IDEOGRAPH
+0xD8F7	0x6C94	#CJK UNIFIED IDEOGRAPH
+0xD8F8	0x7704	#CJK UNIFIED IDEOGRAPH
+0xD8F9	0x7720	#CJK UNIFIED IDEOGRAPH
+0xD8FA	0x7DBF	#CJK UNIFIED IDEOGRAPH
+0xD8FB	0x7DEC	#CJK UNIFIED IDEOGRAPH
+0xD8FC	0x9762	#CJK UNIFIED IDEOGRAPH
+0xD8FD	0x9EB5	#CJK UNIFIED IDEOGRAPH
+0xD8FE	0x6EC5	#CJK UNIFIED IDEOGRAPH
+0xD9A1	0x8511	#CJK UNIFIED IDEOGRAPH
+0xD9A2	0x51A5	#CJK UNIFIED IDEOGRAPH
+0xD9A3	0x540D	#CJK UNIFIED IDEOGRAPH
+0xD9A4	0x547D	#CJK UNIFIED IDEOGRAPH
+0xD9A5	0x660E	#CJK UNIFIED IDEOGRAPH
+0xD9A6	0x669D	#CJK UNIFIED IDEOGRAPH
+0xD9A7	0x6927	#CJK UNIFIED IDEOGRAPH
+0xD9A8	0x6E9F	#CJK UNIFIED IDEOGRAPH
+0xD9A9	0x76BF	#CJK UNIFIED IDEOGRAPH
+0xD9AA	0x7791	#CJK UNIFIED IDEOGRAPH
+0xD9AB	0x8317	#CJK UNIFIED IDEOGRAPH
+0xD9AC	0x84C2	#CJK UNIFIED IDEOGRAPH
+0xD9AD	0x879F	#CJK UNIFIED IDEOGRAPH
+0xD9AE	0x9169	#CJK UNIFIED IDEOGRAPH
+0xD9AF	0x9298	#CJK UNIFIED IDEOGRAPH
+0xD9B0	0x9CF4	#CJK UNIFIED IDEOGRAPH
+0xD9B1	0x8882	#CJK UNIFIED IDEOGRAPH
+0xD9B2	0x4FAE	#CJK UNIFIED IDEOGRAPH
+0xD9B3	0x5192	#CJK UNIFIED IDEOGRAPH
+0xD9B4	0x52DF	#CJK UNIFIED IDEOGRAPH
+0xD9B5	0x59C6	#CJK UNIFIED IDEOGRAPH
+0xD9B6	0x5E3D	#CJK UNIFIED IDEOGRAPH
+0xD9B7	0x6155	#CJK UNIFIED IDEOGRAPH
+0xD9B8	0x6478	#CJK UNIFIED IDEOGRAPH
+0xD9B9	0x6479	#CJK UNIFIED IDEOGRAPH
+0xD9BA	0x66AE	#CJK UNIFIED IDEOGRAPH
+0xD9BB	0x67D0	#CJK UNIFIED IDEOGRAPH
+0xD9BC	0x6A21	#CJK UNIFIED IDEOGRAPH
+0xD9BD	0x6BCD	#CJK UNIFIED IDEOGRAPH
+0xD9BE	0x6BDB	#CJK UNIFIED IDEOGRAPH
+0xD9BF	0x725F	#CJK UNIFIED IDEOGRAPH
+0xD9C0	0x7261	#CJK UNIFIED IDEOGRAPH
+0xD9C1	0x7441	#CJK UNIFIED IDEOGRAPH
+0xD9C2	0x7738	#CJK UNIFIED IDEOGRAPH
+0xD9C3	0x77DB	#CJK UNIFIED IDEOGRAPH
+0xD9C4	0x8017	#CJK UNIFIED IDEOGRAPH
+0xD9C5	0x82BC	#CJK UNIFIED IDEOGRAPH
+0xD9C6	0x8305	#CJK UNIFIED IDEOGRAPH
+0xD9C7	0x8B00	#CJK UNIFIED IDEOGRAPH
+0xD9C8	0x8B28	#CJK UNIFIED IDEOGRAPH
+0xD9C9	0x8C8C	#CJK UNIFIED IDEOGRAPH
+0xD9CA	0x6728	#CJK UNIFIED IDEOGRAPH
+0xD9CB	0x6C90	#CJK UNIFIED IDEOGRAPH
+0xD9CC	0x7267	#CJK UNIFIED IDEOGRAPH
+0xD9CD	0x76EE	#CJK UNIFIED IDEOGRAPH
+0xD9CE	0x7766	#CJK UNIFIED IDEOGRAPH
+0xD9CF	0x7A46	#CJK UNIFIED IDEOGRAPH
+0xD9D0	0x9DA9	#CJK UNIFIED IDEOGRAPH
+0xD9D1	0x6B7F	#CJK UNIFIED IDEOGRAPH
+0xD9D2	0x6C92	#CJK UNIFIED IDEOGRAPH
+0xD9D3	0x5922	#CJK UNIFIED IDEOGRAPH
+0xD9D4	0x6726	#CJK UNIFIED IDEOGRAPH
+0xD9D5	0x8499	#CJK UNIFIED IDEOGRAPH
+0xD9D6	0x536F	#CJK UNIFIED IDEOGRAPH
+0xD9D7	0x5893	#CJK UNIFIED IDEOGRAPH
+0xD9D8	0x5999	#CJK UNIFIED IDEOGRAPH
+0xD9D9	0x5EDF	#CJK UNIFIED IDEOGRAPH
+0xD9DA	0x63CF	#CJK UNIFIED IDEOGRAPH
+0xD9DB	0x6634	#CJK UNIFIED IDEOGRAPH
+0xD9DC	0x6773	#CJK UNIFIED IDEOGRAPH
+0xD9DD	0x6E3A	#CJK UNIFIED IDEOGRAPH
+0xD9DE	0x732B	#CJK UNIFIED IDEOGRAPH
+0xD9DF	0x7AD7	#CJK UNIFIED IDEOGRAPH
+0xD9E0	0x82D7	#CJK UNIFIED IDEOGRAPH
+0xD9E1	0x9328	#CJK UNIFIED IDEOGRAPH
+0xD9E2	0x52D9	#CJK UNIFIED IDEOGRAPH
+0xD9E3	0x5DEB	#CJK UNIFIED IDEOGRAPH
+0xD9E4	0x61AE	#CJK UNIFIED IDEOGRAPH
+0xD9E5	0x61CB	#CJK UNIFIED IDEOGRAPH
+0xD9E6	0x620A	#CJK UNIFIED IDEOGRAPH
+0xD9E7	0x62C7	#CJK UNIFIED IDEOGRAPH
+0xD9E8	0x64AB	#CJK UNIFIED IDEOGRAPH
+0xD9E9	0x65E0	#CJK UNIFIED IDEOGRAPH
+0xD9EA	0x6959	#CJK UNIFIED IDEOGRAPH
+0xD9EB	0x6B66	#CJK UNIFIED IDEOGRAPH
+0xD9EC	0x6BCB	#CJK UNIFIED IDEOGRAPH
+0xD9ED	0x7121	#CJK UNIFIED IDEOGRAPH
+0xD9EE	0x73F7	#CJK UNIFIED IDEOGRAPH
+0xD9EF	0x755D	#CJK UNIFIED IDEOGRAPH
+0xD9F0	0x7E46	#CJK UNIFIED IDEOGRAPH
+0xD9F1	0x821E	#CJK UNIFIED IDEOGRAPH
+0xD9F2	0x8302	#CJK UNIFIED IDEOGRAPH
+0xD9F3	0x856A	#CJK UNIFIED IDEOGRAPH
+0xD9F4	0x8AA3	#CJK UNIFIED IDEOGRAPH
+0xD9F5	0x8CBF	#CJK UNIFIED IDEOGRAPH
+0xD9F6	0x9727	#CJK UNIFIED IDEOGRAPH
+0xD9F7	0x9D61	#CJK UNIFIED IDEOGRAPH
+0xD9F8	0x58A8	#CJK UNIFIED IDEOGRAPH
+0xD9F9	0x9ED8	#CJK UNIFIED IDEOGRAPH
+0xD9FA	0x5011	#CJK UNIFIED IDEOGRAPH
+0xD9FB	0x520E	#CJK UNIFIED IDEOGRAPH
+0xD9FC	0x543B	#CJK UNIFIED IDEOGRAPH
+0xD9FD	0x554F	#CJK UNIFIED IDEOGRAPH
+0xD9FE	0x6587	#CJK UNIFIED IDEOGRAPH
+0xDAA1	0x6C76	#CJK UNIFIED IDEOGRAPH
+0xDAA2	0x7D0A	#CJK UNIFIED IDEOGRAPH
+0xDAA3	0x7D0B	#CJK UNIFIED IDEOGRAPH
+0xDAA4	0x805E	#CJK UNIFIED IDEOGRAPH
+0xDAA5	0x868A	#CJK UNIFIED IDEOGRAPH
+0xDAA6	0x9580	#CJK UNIFIED IDEOGRAPH
+0xDAA7	0x96EF	#CJK UNIFIED IDEOGRAPH
+0xDAA8	0x52FF	#CJK UNIFIED IDEOGRAPH
+0xDAA9	0x6C95	#CJK UNIFIED IDEOGRAPH
+0xDAAA	0x7269	#CJK UNIFIED IDEOGRAPH
+0xDAAB	0x5473	#CJK UNIFIED IDEOGRAPH
+0xDAAC	0x5A9A	#CJK UNIFIED IDEOGRAPH
+0xDAAD	0x5C3E	#CJK UNIFIED IDEOGRAPH
+0xDAAE	0x5D4B	#CJK UNIFIED IDEOGRAPH
+0xDAAF	0x5F4C	#CJK UNIFIED IDEOGRAPH
+0xDAB0	0x5FAE	#CJK UNIFIED IDEOGRAPH
+0xDAB1	0x672A	#CJK UNIFIED IDEOGRAPH
+0xDAB2	0x68B6	#CJK UNIFIED IDEOGRAPH
+0xDAB3	0x6963	#CJK UNIFIED IDEOGRAPH
+0xDAB4	0x6E3C	#CJK UNIFIED IDEOGRAPH
+0xDAB5	0x6E44	#CJK UNIFIED IDEOGRAPH
+0xDAB6	0x7709	#CJK UNIFIED IDEOGRAPH
+0xDAB7	0x7C73	#CJK UNIFIED IDEOGRAPH
+0xDAB8	0x7F8E	#CJK UNIFIED IDEOGRAPH
+0xDAB9	0x8587	#CJK UNIFIED IDEOGRAPH
+0xDABA	0x8B0E	#CJK UNIFIED IDEOGRAPH
+0xDABB	0x8FF7	#CJK UNIFIED IDEOGRAPH
+0xDABC	0x9761	#CJK UNIFIED IDEOGRAPH
+0xDABD	0x9EF4	#CJK UNIFIED IDEOGRAPH
+0xDABE	0x5CB7	#CJK UNIFIED IDEOGRAPH
+0xDABF	0x60B6	#CJK UNIFIED IDEOGRAPH
+0xDAC0	0x610D	#CJK UNIFIED IDEOGRAPH
+0xDAC1	0x61AB	#CJK UNIFIED IDEOGRAPH
+0xDAC2	0x654F	#CJK UNIFIED IDEOGRAPH
+0xDAC3	0x65FB	#CJK UNIFIED IDEOGRAPH
+0xDAC4	0x65FC	#CJK UNIFIED IDEOGRAPH
+0xDAC5	0x6C11	#CJK UNIFIED IDEOGRAPH
+0xDAC6	0x6CEF	#CJK UNIFIED IDEOGRAPH
+0xDAC7	0x739F	#CJK UNIFIED IDEOGRAPH
+0xDAC8	0x73C9	#CJK UNIFIED IDEOGRAPH
+0xDAC9	0x7DE1	#CJK UNIFIED IDEOGRAPH
+0xDACA	0x9594	#CJK UNIFIED IDEOGRAPH
+0xDACB	0x5BC6	#CJK UNIFIED IDEOGRAPH
+0xDACC	0x871C	#CJK UNIFIED IDEOGRAPH
+0xDACD	0x8B10	#CJK UNIFIED IDEOGRAPH
+0xDACE	0x525D	#CJK UNIFIED IDEOGRAPH
+0xDACF	0x535A	#CJK UNIFIED IDEOGRAPH
+0xDAD0	0x62CD	#CJK UNIFIED IDEOGRAPH
+0xDAD1	0x640F	#CJK UNIFIED IDEOGRAPH
+0xDAD2	0x64B2	#CJK UNIFIED IDEOGRAPH
+0xDAD3	0x6734	#CJK UNIFIED IDEOGRAPH
+0xDAD4	0x6A38	#CJK UNIFIED IDEOGRAPH
+0xDAD5	0x6CCA	#CJK UNIFIED IDEOGRAPH
+0xDAD6	0x73C0	#CJK UNIFIED IDEOGRAPH
+0xDAD7	0x749E	#CJK UNIFIED IDEOGRAPH
+0xDAD8	0x7B94	#CJK UNIFIED IDEOGRAPH
+0xDAD9	0x7C95	#CJK UNIFIED IDEOGRAPH
+0xDADA	0x7E1B	#CJK UNIFIED IDEOGRAPH
+0xDADB	0x818A	#CJK UNIFIED IDEOGRAPH
+0xDADC	0x8236	#CJK UNIFIED IDEOGRAPH
+0xDADD	0x8584	#CJK UNIFIED IDEOGRAPH
+0xDADE	0x8FEB	#CJK UNIFIED IDEOGRAPH
+0xDADF	0x96F9	#CJK UNIFIED IDEOGRAPH
+0xDAE0	0x99C1	#CJK UNIFIED IDEOGRAPH
+0xDAE1	0x4F34	#CJK UNIFIED IDEOGRAPH
+0xDAE2	0x534A	#CJK UNIFIED IDEOGRAPH
+0xDAE3	0x53CD	#CJK UNIFIED IDEOGRAPH
+0xDAE4	0x53DB	#CJK UNIFIED IDEOGRAPH
+0xDAE5	0x62CC	#CJK UNIFIED IDEOGRAPH
+0xDAE6	0x642C	#CJK UNIFIED IDEOGRAPH
+0xDAE7	0x6500	#CJK UNIFIED IDEOGRAPH
+0xDAE8	0x6591	#CJK UNIFIED IDEOGRAPH
+0xDAE9	0x69C3	#CJK UNIFIED IDEOGRAPH
+0xDAEA	0x6CEE	#CJK UNIFIED IDEOGRAPH
+0xDAEB	0x6F58	#CJK UNIFIED IDEOGRAPH
+0xDAEC	0x73ED	#CJK UNIFIED IDEOGRAPH
+0xDAED	0x7554	#CJK UNIFIED IDEOGRAPH
+0xDAEE	0x7622	#CJK UNIFIED IDEOGRAPH
+0xDAEF	0x76E4	#CJK UNIFIED IDEOGRAPH
+0xDAF0	0x76FC	#CJK UNIFIED IDEOGRAPH
+0xDAF1	0x78D0	#CJK UNIFIED IDEOGRAPH
+0xDAF2	0x78FB	#CJK UNIFIED IDEOGRAPH
+0xDAF3	0x792C	#CJK UNIFIED IDEOGRAPH
+0xDAF4	0x7D46	#CJK UNIFIED IDEOGRAPH
+0xDAF5	0x822C	#CJK UNIFIED IDEOGRAPH
+0xDAF6	0x87E0	#CJK UNIFIED IDEOGRAPH
+0xDAF7	0x8FD4	#CJK UNIFIED IDEOGRAPH
+0xDAF8	0x9812	#CJK UNIFIED IDEOGRAPH
+0xDAF9	0x98EF	#CJK UNIFIED IDEOGRAPH
+0xDAFA	0x52C3	#CJK UNIFIED IDEOGRAPH
+0xDAFB	0x62D4	#CJK UNIFIED IDEOGRAPH
+0xDAFC	0x64A5	#CJK UNIFIED IDEOGRAPH
+0xDAFD	0x6E24	#CJK UNIFIED IDEOGRAPH
+0xDAFE	0x6F51	#CJK UNIFIED IDEOGRAPH
+0xDBA1	0x767C	#CJK UNIFIED IDEOGRAPH
+0xDBA2	0x8DCB	#CJK UNIFIED IDEOGRAPH
+0xDBA3	0x91B1	#CJK UNIFIED IDEOGRAPH
+0xDBA4	0x9262	#CJK UNIFIED IDEOGRAPH
+0xDBA5	0x9AEE	#CJK UNIFIED IDEOGRAPH
+0xDBA6	0x9B43	#CJK UNIFIED IDEOGRAPH
+0xDBA7	0x5023	#CJK UNIFIED IDEOGRAPH
+0xDBA8	0x508D	#CJK UNIFIED IDEOGRAPH
+0xDBA9	0x574A	#CJK UNIFIED IDEOGRAPH
+0xDBAA	0x59A8	#CJK UNIFIED IDEOGRAPH
+0xDBAB	0x5C28	#CJK UNIFIED IDEOGRAPH
+0xDBAC	0x5E47	#CJK UNIFIED IDEOGRAPH
+0xDBAD	0x5F77	#CJK UNIFIED IDEOGRAPH
+0xDBAE	0x623F	#CJK UNIFIED IDEOGRAPH
+0xDBAF	0x653E	#CJK UNIFIED IDEOGRAPH
+0xDBB0	0x65B9	#CJK UNIFIED IDEOGRAPH
+0xDBB1	0x65C1	#CJK UNIFIED IDEOGRAPH
+0xDBB2	0x6609	#CJK UNIFIED IDEOGRAPH
+0xDBB3	0x678B	#CJK UNIFIED IDEOGRAPH
+0xDBB4	0x699C	#CJK UNIFIED IDEOGRAPH
+0xDBB5	0x6EC2	#CJK UNIFIED IDEOGRAPH
+0xDBB6	0x78C5	#CJK UNIFIED IDEOGRAPH
+0xDBB7	0x7D21	#CJK UNIFIED IDEOGRAPH
+0xDBB8	0x80AA	#CJK UNIFIED IDEOGRAPH
+0xDBB9	0x8180	#CJK UNIFIED IDEOGRAPH
+0xDBBA	0x822B	#CJK UNIFIED IDEOGRAPH
+0xDBBB	0x82B3	#CJK UNIFIED IDEOGRAPH
+0xDBBC	0x84A1	#CJK UNIFIED IDEOGRAPH
+0xDBBD	0x868C	#CJK UNIFIED IDEOGRAPH
+0xDBBE	0x8A2A	#CJK UNIFIED IDEOGRAPH
+0xDBBF	0x8B17	#CJK UNIFIED IDEOGRAPH
+0xDBC0	0x90A6	#CJK UNIFIED IDEOGRAPH
+0xDBC1	0x9632	#CJK UNIFIED IDEOGRAPH
+0xDBC2	0x9F90	#CJK UNIFIED IDEOGRAPH
+0xDBC3	0x500D	#CJK UNIFIED IDEOGRAPH
+0xDBC4	0x4FF3	#CJK UNIFIED IDEOGRAPH
+0xDBC5	0xF963	#CJK COMPATIBILITY IDEOGRAPH
+0xDBC6	0x57F9	#CJK UNIFIED IDEOGRAPH
+0xDBC7	0x5F98	#CJK UNIFIED IDEOGRAPH
+0xDBC8	0x62DC	#CJK UNIFIED IDEOGRAPH
+0xDBC9	0x6392	#CJK UNIFIED IDEOGRAPH
+0xDBCA	0x676F	#CJK UNIFIED IDEOGRAPH
+0xDBCB	0x6E43	#CJK UNIFIED IDEOGRAPH
+0xDBCC	0x7119	#CJK UNIFIED IDEOGRAPH
+0xDBCD	0x76C3	#CJK UNIFIED IDEOGRAPH
+0xDBCE	0x80CC	#CJK UNIFIED IDEOGRAPH
+0xDBCF	0x80DA	#CJK UNIFIED IDEOGRAPH
+0xDBD0	0x88F4	#CJK UNIFIED IDEOGRAPH
+0xDBD1	0x88F5	#CJK UNIFIED IDEOGRAPH
+0xDBD2	0x8919	#CJK UNIFIED IDEOGRAPH
+0xDBD3	0x8CE0	#CJK UNIFIED IDEOGRAPH
+0xDBD4	0x8F29	#CJK UNIFIED IDEOGRAPH
+0xDBD5	0x914D	#CJK UNIFIED IDEOGRAPH
+0xDBD6	0x966A	#CJK UNIFIED IDEOGRAPH
+0xDBD7	0x4F2F	#CJK UNIFIED IDEOGRAPH
+0xDBD8	0x4F70	#CJK UNIFIED IDEOGRAPH
+0xDBD9	0x5E1B	#CJK UNIFIED IDEOGRAPH
+0xDBDA	0x67CF	#CJK UNIFIED IDEOGRAPH
+0xDBDB	0x6822	#CJK UNIFIED IDEOGRAPH
+0xDBDC	0x767D	#CJK UNIFIED IDEOGRAPH
+0xDBDD	0x767E	#CJK UNIFIED IDEOGRAPH
+0xDBDE	0x9B44	#CJK UNIFIED IDEOGRAPH
+0xDBDF	0x5E61	#CJK UNIFIED IDEOGRAPH
+0xDBE0	0x6A0A	#CJK UNIFIED IDEOGRAPH
+0xDBE1	0x7169	#CJK UNIFIED IDEOGRAPH
+0xDBE2	0x71D4	#CJK UNIFIED IDEOGRAPH
+0xDBE3	0x756A	#CJK UNIFIED IDEOGRAPH
+0xDBE4	0xF964	#CJK COMPATIBILITY IDEOGRAPH
+0xDBE5	0x7E41	#CJK UNIFIED IDEOGRAPH
+0xDBE6	0x8543	#CJK UNIFIED IDEOGRAPH
+0xDBE7	0x85E9	#CJK UNIFIED IDEOGRAPH
+0xDBE8	0x98DC	#CJK UNIFIED IDEOGRAPH
+0xDBE9	0x4F10	#CJK UNIFIED IDEOGRAPH
+0xDBEA	0x7B4F	#CJK UNIFIED IDEOGRAPH
+0xDBEB	0x7F70	#CJK UNIFIED IDEOGRAPH
+0xDBEC	0x95A5	#CJK UNIFIED IDEOGRAPH
+0xDBED	0x51E1	#CJK UNIFIED IDEOGRAPH
+0xDBEE	0x5E06	#CJK UNIFIED IDEOGRAPH
+0xDBEF	0x68B5	#CJK UNIFIED IDEOGRAPH
+0xDBF0	0x6C3E	#CJK UNIFIED IDEOGRAPH
+0xDBF1	0x6C4E	#CJK UNIFIED IDEOGRAPH
+0xDBF2	0x6CDB	#CJK UNIFIED IDEOGRAPH
+0xDBF3	0x72AF	#CJK UNIFIED IDEOGRAPH
+0xDBF4	0x7BC4	#CJK UNIFIED IDEOGRAPH
+0xDBF5	0x8303	#CJK UNIFIED IDEOGRAPH
+0xDBF6	0x6CD5	#CJK UNIFIED IDEOGRAPH
+0xDBF7	0x743A	#CJK UNIFIED IDEOGRAPH
+0xDBF8	0x50FB	#CJK UNIFIED IDEOGRAPH
+0xDBF9	0x5288	#CJK UNIFIED IDEOGRAPH
+0xDBFA	0x58C1	#CJK UNIFIED IDEOGRAPH
+0xDBFB	0x64D8	#CJK UNIFIED IDEOGRAPH
+0xDBFC	0x6A97	#CJK UNIFIED IDEOGRAPH
+0xDBFD	0x74A7	#CJK UNIFIED IDEOGRAPH
+0xDBFE	0x7656	#CJK UNIFIED IDEOGRAPH
+0xDCA1	0x78A7	#CJK UNIFIED IDEOGRAPH
+0xDCA2	0x8617	#CJK UNIFIED IDEOGRAPH
+0xDCA3	0x95E2	#CJK UNIFIED IDEOGRAPH
+0xDCA4	0x9739	#CJK UNIFIED IDEOGRAPH
+0xDCA5	0xF965	#CJK COMPATIBILITY IDEOGRAPH
+0xDCA6	0x535E	#CJK UNIFIED IDEOGRAPH
+0xDCA7	0x5F01	#CJK UNIFIED IDEOGRAPH
+0xDCA8	0x8B8A	#CJK UNIFIED IDEOGRAPH
+0xDCA9	0x8FA8	#CJK UNIFIED IDEOGRAPH
+0xDCAA	0x8FAF	#CJK UNIFIED IDEOGRAPH
+0xDCAB	0x908A	#CJK UNIFIED IDEOGRAPH
+0xDCAC	0x5225	#CJK UNIFIED IDEOGRAPH
+0xDCAD	0x77A5	#CJK UNIFIED IDEOGRAPH
+0xDCAE	0x9C49	#CJK UNIFIED IDEOGRAPH
+0xDCAF	0x9F08	#CJK UNIFIED IDEOGRAPH
+0xDCB0	0x4E19	#CJK UNIFIED IDEOGRAPH
+0xDCB1	0x5002	#CJK UNIFIED IDEOGRAPH
+0xDCB2	0x5175	#CJK UNIFIED IDEOGRAPH
+0xDCB3	0x5C5B	#CJK UNIFIED IDEOGRAPH
+0xDCB4	0x5E77	#CJK UNIFIED IDEOGRAPH
+0xDCB5	0x661E	#CJK UNIFIED IDEOGRAPH
+0xDCB6	0x663A	#CJK UNIFIED IDEOGRAPH
+0xDCB7	0x67C4	#CJK UNIFIED IDEOGRAPH
+0xDCB8	0x68C5	#CJK UNIFIED IDEOGRAPH
+0xDCB9	0x70B3	#CJK UNIFIED IDEOGRAPH
+0xDCBA	0x7501	#CJK UNIFIED IDEOGRAPH
+0xDCBB	0x75C5	#CJK UNIFIED IDEOGRAPH
+0xDCBC	0x79C9	#CJK UNIFIED IDEOGRAPH
+0xDCBD	0x7ADD	#CJK UNIFIED IDEOGRAPH
+0xDCBE	0x8F27	#CJK UNIFIED IDEOGRAPH
+0xDCBF	0x9920	#CJK UNIFIED IDEOGRAPH
+0xDCC0	0x9A08	#CJK UNIFIED IDEOGRAPH
+0xDCC1	0x4FDD	#CJK UNIFIED IDEOGRAPH
+0xDCC2	0x5821	#CJK UNIFIED IDEOGRAPH
+0xDCC3	0x5831	#CJK UNIFIED IDEOGRAPH
+0xDCC4	0x5BF6	#CJK UNIFIED IDEOGRAPH
+0xDCC5	0x666E	#CJK UNIFIED IDEOGRAPH
+0xDCC6	0x6B65	#CJK UNIFIED IDEOGRAPH
+0xDCC7	0x6D11	#CJK UNIFIED IDEOGRAPH
+0xDCC8	0x6E7A	#CJK UNIFIED IDEOGRAPH
+0xDCC9	0x6F7D	#CJK UNIFIED IDEOGRAPH
+0xDCCA	0x73E4	#CJK UNIFIED IDEOGRAPH
+0xDCCB	0x752B	#CJK UNIFIED IDEOGRAPH
+0xDCCC	0x83E9	#CJK UNIFIED IDEOGRAPH
+0xDCCD	0x88DC	#CJK UNIFIED IDEOGRAPH
+0xDCCE	0x8913	#CJK UNIFIED IDEOGRAPH
+0xDCCF	0x8B5C	#CJK UNIFIED IDEOGRAPH
+0xDCD0	0x8F14	#CJK UNIFIED IDEOGRAPH
+0xDCD1	0x4F0F	#CJK UNIFIED IDEOGRAPH
+0xDCD2	0x50D5	#CJK UNIFIED IDEOGRAPH
+0xDCD3	0x5310	#CJK UNIFIED IDEOGRAPH
+0xDCD4	0x535C	#CJK UNIFIED IDEOGRAPH
+0xDCD5	0x5B93	#CJK UNIFIED IDEOGRAPH
+0xDCD6	0x5FA9	#CJK UNIFIED IDEOGRAPH
+0xDCD7	0x670D	#CJK UNIFIED IDEOGRAPH
+0xDCD8	0x798F	#CJK UNIFIED IDEOGRAPH
+0xDCD9	0x8179	#CJK UNIFIED IDEOGRAPH
+0xDCDA	0x832F	#CJK UNIFIED IDEOGRAPH
+0xDCDB	0x8514	#CJK UNIFIED IDEOGRAPH
+0xDCDC	0x8907	#CJK UNIFIED IDEOGRAPH
+0xDCDD	0x8986	#CJK UNIFIED IDEOGRAPH
+0xDCDE	0x8F39	#CJK UNIFIED IDEOGRAPH
+0xDCDF	0x8F3B	#CJK UNIFIED IDEOGRAPH
+0xDCE0	0x99A5	#CJK UNIFIED IDEOGRAPH
+0xDCE1	0x9C12	#CJK UNIFIED IDEOGRAPH
+0xDCE2	0x672C	#CJK UNIFIED IDEOGRAPH
+0xDCE3	0x4E76	#CJK UNIFIED IDEOGRAPH
+0xDCE4	0x4FF8	#CJK UNIFIED IDEOGRAPH
+0xDCE5	0x5949	#CJK UNIFIED IDEOGRAPH
+0xDCE6	0x5C01	#CJK UNIFIED IDEOGRAPH
+0xDCE7	0x5CEF	#CJK UNIFIED IDEOGRAPH
+0xDCE8	0x5CF0	#CJK UNIFIED IDEOGRAPH
+0xDCE9	0x6367	#CJK UNIFIED IDEOGRAPH
+0xDCEA	0x68D2	#CJK UNIFIED IDEOGRAPH
+0xDCEB	0x70FD	#CJK UNIFIED IDEOGRAPH
+0xDCEC	0x71A2	#CJK UNIFIED IDEOGRAPH
+0xDCED	0x742B	#CJK UNIFIED IDEOGRAPH
+0xDCEE	0x7E2B	#CJK UNIFIED IDEOGRAPH
+0xDCEF	0x84EC	#CJK UNIFIED IDEOGRAPH
+0xDCF0	0x8702	#CJK UNIFIED IDEOGRAPH
+0xDCF1	0x9022	#CJK UNIFIED IDEOGRAPH
+0xDCF2	0x92D2	#CJK UNIFIED IDEOGRAPH
+0xDCF3	0x9CF3	#CJK UNIFIED IDEOGRAPH
+0xDCF4	0x4E0D	#CJK UNIFIED IDEOGRAPH
+0xDCF5	0x4ED8	#CJK UNIFIED IDEOGRAPH
+0xDCF6	0x4FEF	#CJK UNIFIED IDEOGRAPH
+0xDCF7	0x5085	#CJK UNIFIED IDEOGRAPH
+0xDCF8	0x5256	#CJK UNIFIED IDEOGRAPH
+0xDCF9	0x526F	#CJK UNIFIED IDEOGRAPH
+0xDCFA	0x5426	#CJK UNIFIED IDEOGRAPH
+0xDCFB	0x5490	#CJK UNIFIED IDEOGRAPH
+0xDCFC	0x57E0	#CJK UNIFIED IDEOGRAPH
+0xDCFD	0x592B	#CJK UNIFIED IDEOGRAPH
+0xDCFE	0x5A66	#CJK UNIFIED IDEOGRAPH
+0xDDA1	0x5B5A	#CJK UNIFIED IDEOGRAPH
+0xDDA2	0x5B75	#CJK UNIFIED IDEOGRAPH
+0xDDA3	0x5BCC	#CJK UNIFIED IDEOGRAPH
+0xDDA4	0x5E9C	#CJK UNIFIED IDEOGRAPH
+0xDDA5	0xF966	#CJK COMPATIBILITY IDEOGRAPH
+0xDDA6	0x6276	#CJK UNIFIED IDEOGRAPH
+0xDDA7	0x6577	#CJK UNIFIED IDEOGRAPH
+0xDDA8	0x65A7	#CJK UNIFIED IDEOGRAPH
+0xDDA9	0x6D6E	#CJK UNIFIED IDEOGRAPH
+0xDDAA	0x6EA5	#CJK UNIFIED IDEOGRAPH
+0xDDAB	0x7236	#CJK UNIFIED IDEOGRAPH
+0xDDAC	0x7B26	#CJK UNIFIED IDEOGRAPH
+0xDDAD	0x7C3F	#CJK UNIFIED IDEOGRAPH
+0xDDAE	0x7F36	#CJK UNIFIED IDEOGRAPH
+0xDDAF	0x8150	#CJK UNIFIED IDEOGRAPH
+0xDDB0	0x8151	#CJK UNIFIED IDEOGRAPH
+0xDDB1	0x819A	#CJK UNIFIED IDEOGRAPH
+0xDDB2	0x8240	#CJK UNIFIED IDEOGRAPH
+0xDDB3	0x8299	#CJK UNIFIED IDEOGRAPH
+0xDDB4	0x83A9	#CJK UNIFIED IDEOGRAPH
+0xDDB5	0x8A03	#CJK UNIFIED IDEOGRAPH
+0xDDB6	0x8CA0	#CJK UNIFIED IDEOGRAPH
+0xDDB7	0x8CE6	#CJK UNIFIED IDEOGRAPH
+0xDDB8	0x8CFB	#CJK UNIFIED IDEOGRAPH
+0xDDB9	0x8D74	#CJK UNIFIED IDEOGRAPH
+0xDDBA	0x8DBA	#CJK UNIFIED IDEOGRAPH
+0xDDBB	0x90E8	#CJK UNIFIED IDEOGRAPH
+0xDDBC	0x91DC	#CJK UNIFIED IDEOGRAPH
+0xDDBD	0x961C	#CJK UNIFIED IDEOGRAPH
+0xDDBE	0x9644	#CJK UNIFIED IDEOGRAPH
+0xDDBF	0x99D9	#CJK UNIFIED IDEOGRAPH
+0xDDC0	0x9CE7	#CJK UNIFIED IDEOGRAPH
+0xDDC1	0x5317	#CJK UNIFIED IDEOGRAPH
+0xDDC2	0x5206	#CJK UNIFIED IDEOGRAPH
+0xDDC3	0x5429	#CJK UNIFIED IDEOGRAPH
+0xDDC4	0x5674	#CJK UNIFIED IDEOGRAPH
+0xDDC5	0x58B3	#CJK UNIFIED IDEOGRAPH
+0xDDC6	0x5954	#CJK UNIFIED IDEOGRAPH
+0xDDC7	0x596E	#CJK UNIFIED IDEOGRAPH
+0xDDC8	0x5FFF	#CJK UNIFIED IDEOGRAPH
+0xDDC9	0x61A4	#CJK UNIFIED IDEOGRAPH
+0xDDCA	0x626E	#CJK UNIFIED IDEOGRAPH
+0xDDCB	0x6610	#CJK UNIFIED IDEOGRAPH
+0xDDCC	0x6C7E	#CJK UNIFIED IDEOGRAPH
+0xDDCD	0x711A	#CJK UNIFIED IDEOGRAPH
+0xDDCE	0x76C6	#CJK UNIFIED IDEOGRAPH
+0xDDCF	0x7C89	#CJK UNIFIED IDEOGRAPH
+0xDDD0	0x7CDE	#CJK UNIFIED IDEOGRAPH
+0xDDD1	0x7D1B	#CJK UNIFIED IDEOGRAPH
+0xDDD2	0x82AC	#CJK UNIFIED IDEOGRAPH
+0xDDD3	0x8CC1	#CJK UNIFIED IDEOGRAPH
+0xDDD4	0x96F0	#CJK UNIFIED IDEOGRAPH
+0xDDD5	0xF967	#CJK COMPATIBILITY IDEOGRAPH
+0xDDD6	0x4F5B	#CJK UNIFIED IDEOGRAPH
+0xDDD7	0x5F17	#CJK UNIFIED IDEOGRAPH
+0xDDD8	0x5F7F	#CJK UNIFIED IDEOGRAPH
+0xDDD9	0x62C2	#CJK UNIFIED IDEOGRAPH
+0xDDDA	0x5D29	#CJK UNIFIED IDEOGRAPH
+0xDDDB	0x670B	#CJK UNIFIED IDEOGRAPH
+0xDDDC	0x68DA	#CJK UNIFIED IDEOGRAPH
+0xDDDD	0x787C	#CJK UNIFIED IDEOGRAPH
+0xDDDE	0x7E43	#CJK UNIFIED IDEOGRAPH
+0xDDDF	0x9D6C	#CJK UNIFIED IDEOGRAPH
+0xDDE0	0x4E15	#CJK UNIFIED IDEOGRAPH
+0xDDE1	0x5099	#CJK UNIFIED IDEOGRAPH
+0xDDE2	0x5315	#CJK UNIFIED IDEOGRAPH
+0xDDE3	0x532A	#CJK UNIFIED IDEOGRAPH
+0xDDE4	0x5351	#CJK UNIFIED IDEOGRAPH
+0xDDE5	0x5983	#CJK UNIFIED IDEOGRAPH
+0xDDE6	0x5A62	#CJK UNIFIED IDEOGRAPH
+0xDDE7	0x5E87	#CJK UNIFIED IDEOGRAPH
+0xDDE8	0x60B2	#CJK UNIFIED IDEOGRAPH
+0xDDE9	0x618A	#CJK UNIFIED IDEOGRAPH
+0xDDEA	0x6249	#CJK UNIFIED IDEOGRAPH
+0xDDEB	0x6279	#CJK UNIFIED IDEOGRAPH
+0xDDEC	0x6590	#CJK UNIFIED IDEOGRAPH
+0xDDED	0x6787	#CJK UNIFIED IDEOGRAPH
+0xDDEE	0x69A7	#CJK UNIFIED IDEOGRAPH
+0xDDEF	0x6BD4	#CJK UNIFIED IDEOGRAPH
+0xDDF0	0x6BD6	#CJK UNIFIED IDEOGRAPH
+0xDDF1	0x6BD7	#CJK UNIFIED IDEOGRAPH
+0xDDF2	0x6BD8	#CJK UNIFIED IDEOGRAPH
+0xDDF3	0x6CB8	#CJK UNIFIED IDEOGRAPH
+0xDDF4	0xF968	#CJK COMPATIBILITY IDEOGRAPH
+0xDDF5	0x7435	#CJK UNIFIED IDEOGRAPH
+0xDDF6	0x75FA	#CJK UNIFIED IDEOGRAPH
+0xDDF7	0x7812	#CJK UNIFIED IDEOGRAPH
+0xDDF8	0x7891	#CJK UNIFIED IDEOGRAPH
+0xDDF9	0x79D5	#CJK UNIFIED IDEOGRAPH
+0xDDFA	0x79D8	#CJK UNIFIED IDEOGRAPH
+0xDDFB	0x7C83	#CJK UNIFIED IDEOGRAPH
+0xDDFC	0x7DCB	#CJK UNIFIED IDEOGRAPH
+0xDDFD	0x7FE1	#CJK UNIFIED IDEOGRAPH
+0xDDFE	0x80A5	#CJK UNIFIED IDEOGRAPH
+0xDEA1	0x813E	#CJK UNIFIED IDEOGRAPH
+0xDEA2	0x81C2	#CJK UNIFIED IDEOGRAPH
+0xDEA3	0x83F2	#CJK UNIFIED IDEOGRAPH
+0xDEA4	0x871A	#CJK UNIFIED IDEOGRAPH
+0xDEA5	0x88E8	#CJK UNIFIED IDEOGRAPH
+0xDEA6	0x8AB9	#CJK UNIFIED IDEOGRAPH
+0xDEA7	0x8B6C	#CJK UNIFIED IDEOGRAPH
+0xDEA8	0x8CBB	#CJK UNIFIED IDEOGRAPH
+0xDEA9	0x9119	#CJK UNIFIED IDEOGRAPH
+0xDEAA	0x975E	#CJK UNIFIED IDEOGRAPH
+0xDEAB	0x98DB	#CJK UNIFIED IDEOGRAPH
+0xDEAC	0x9F3B	#CJK UNIFIED IDEOGRAPH
+0xDEAD	0x56AC	#CJK UNIFIED IDEOGRAPH
+0xDEAE	0x5B2A	#CJK UNIFIED IDEOGRAPH
+0xDEAF	0x5F6C	#CJK UNIFIED IDEOGRAPH
+0xDEB0	0x658C	#CJK UNIFIED IDEOGRAPH
+0xDEB1	0x6AB3	#CJK UNIFIED IDEOGRAPH
+0xDEB2	0x6BAF	#CJK UNIFIED IDEOGRAPH
+0xDEB3	0x6D5C	#CJK UNIFIED IDEOGRAPH
+0xDEB4	0x6FF1	#CJK UNIFIED IDEOGRAPH
+0xDEB5	0x7015	#CJK UNIFIED IDEOGRAPH
+0xDEB6	0x725D	#CJK UNIFIED IDEOGRAPH
+0xDEB7	0x73AD	#CJK UNIFIED IDEOGRAPH
+0xDEB8	0x8CA7	#CJK UNIFIED IDEOGRAPH
+0xDEB9	0x8CD3	#CJK UNIFIED IDEOGRAPH
+0xDEBA	0x983B	#CJK UNIFIED IDEOGRAPH
+0xDEBB	0x6191	#CJK UNIFIED IDEOGRAPH
+0xDEBC	0x6C37	#CJK UNIFIED IDEOGRAPH
+0xDEBD	0x8058	#CJK UNIFIED IDEOGRAPH
+0xDEBE	0x9A01	#CJK UNIFIED IDEOGRAPH
+0xDEBF	0x4E4D	#CJK UNIFIED IDEOGRAPH
+0xDEC0	0x4E8B	#CJK UNIFIED IDEOGRAPH
+0xDEC1	0x4E9B	#CJK UNIFIED IDEOGRAPH
+0xDEC2	0x4ED5	#CJK UNIFIED IDEOGRAPH
+0xDEC3	0x4F3A	#CJK UNIFIED IDEOGRAPH
+0xDEC4	0x4F3C	#CJK UNIFIED IDEOGRAPH
+0xDEC5	0x4F7F	#CJK UNIFIED IDEOGRAPH
+0xDEC6	0x4FDF	#CJK UNIFIED IDEOGRAPH
+0xDEC7	0x50FF	#CJK UNIFIED IDEOGRAPH
+0xDEC8	0x53F2	#CJK UNIFIED IDEOGRAPH
+0xDEC9	0x53F8	#CJK UNIFIED IDEOGRAPH
+0xDECA	0x5506	#CJK UNIFIED IDEOGRAPH
+0xDECB	0x55E3	#CJK UNIFIED IDEOGRAPH
+0xDECC	0x56DB	#CJK UNIFIED IDEOGRAPH
+0xDECD	0x58EB	#CJK UNIFIED IDEOGRAPH
+0xDECE	0x5962	#CJK UNIFIED IDEOGRAPH
+0xDECF	0x5A11	#CJK UNIFIED IDEOGRAPH
+0xDED0	0x5BEB	#CJK UNIFIED IDEOGRAPH
+0xDED1	0x5BFA	#CJK UNIFIED IDEOGRAPH
+0xDED2	0x5C04	#CJK UNIFIED IDEOGRAPH
+0xDED3	0x5DF3	#CJK UNIFIED IDEOGRAPH
+0xDED4	0x5E2B	#CJK UNIFIED IDEOGRAPH
+0xDED5	0x5F99	#CJK UNIFIED IDEOGRAPH
+0xDED6	0x601D	#CJK UNIFIED IDEOGRAPH
+0xDED7	0x6368	#CJK UNIFIED IDEOGRAPH
+0xDED8	0x659C	#CJK UNIFIED IDEOGRAPH
+0xDED9	0x65AF	#CJK UNIFIED IDEOGRAPH
+0xDEDA	0x67F6	#CJK UNIFIED IDEOGRAPH
+0xDEDB	0x67FB	#CJK UNIFIED IDEOGRAPH
+0xDEDC	0x68AD	#CJK UNIFIED IDEOGRAPH
+0xDEDD	0x6B7B	#CJK UNIFIED IDEOGRAPH
+0xDEDE	0x6C99	#CJK UNIFIED IDEOGRAPH
+0xDEDF	0x6CD7	#CJK UNIFIED IDEOGRAPH
+0xDEE0	0x6E23	#CJK UNIFIED IDEOGRAPH
+0xDEE1	0x7009	#CJK UNIFIED IDEOGRAPH
+0xDEE2	0x7345	#CJK UNIFIED IDEOGRAPH
+0xDEE3	0x7802	#CJK UNIFIED IDEOGRAPH
+0xDEE4	0x793E	#CJK UNIFIED IDEOGRAPH
+0xDEE5	0x7940	#CJK UNIFIED IDEOGRAPH
+0xDEE6	0x7960	#CJK UNIFIED IDEOGRAPH
+0xDEE7	0x79C1	#CJK UNIFIED IDEOGRAPH
+0xDEE8	0x7BE9	#CJK UNIFIED IDEOGRAPH
+0xDEE9	0x7D17	#CJK UNIFIED IDEOGRAPH
+0xDEEA	0x7D72	#CJK UNIFIED IDEOGRAPH
+0xDEEB	0x8086	#CJK UNIFIED IDEOGRAPH
+0xDEEC	0x820D	#CJK UNIFIED IDEOGRAPH
+0xDEED	0x838E	#CJK UNIFIED IDEOGRAPH
+0xDEEE	0x84D1	#CJK UNIFIED IDEOGRAPH
+0xDEEF	0x86C7	#CJK UNIFIED IDEOGRAPH
+0xDEF0	0x88DF	#CJK UNIFIED IDEOGRAPH
+0xDEF1	0x8A50	#CJK UNIFIED IDEOGRAPH
+0xDEF2	0x8A5E	#CJK UNIFIED IDEOGRAPH
+0xDEF3	0x8B1D	#CJK UNIFIED IDEOGRAPH
+0xDEF4	0x8CDC	#CJK UNIFIED IDEOGRAPH
+0xDEF5	0x8D66	#CJK UNIFIED IDEOGRAPH
+0xDEF6	0x8FAD	#CJK UNIFIED IDEOGRAPH
+0xDEF7	0x90AA	#CJK UNIFIED IDEOGRAPH
+0xDEF8	0x98FC	#CJK UNIFIED IDEOGRAPH
+0xDEF9	0x99DF	#CJK UNIFIED IDEOGRAPH
+0xDEFA	0x9E9D	#CJK UNIFIED IDEOGRAPH
+0xDEFB	0x524A	#CJK UNIFIED IDEOGRAPH
+0xDEFC	0xF969	#CJK COMPATIBILITY IDEOGRAPH
+0xDEFD	0x6714	#CJK UNIFIED IDEOGRAPH
+0xDEFE	0xF96A	#CJK COMPATIBILITY IDEOGRAPH
+0xDFA1	0x5098	#CJK UNIFIED IDEOGRAPH
+0xDFA2	0x522A	#CJK UNIFIED IDEOGRAPH
+0xDFA3	0x5C71	#CJK UNIFIED IDEOGRAPH
+0xDFA4	0x6563	#CJK UNIFIED IDEOGRAPH
+0xDFA5	0x6C55	#CJK UNIFIED IDEOGRAPH
+0xDFA6	0x73CA	#CJK UNIFIED IDEOGRAPH
+0xDFA7	0x7523	#CJK UNIFIED IDEOGRAPH
+0xDFA8	0x759D	#CJK UNIFIED IDEOGRAPH
+0xDFA9	0x7B97	#CJK UNIFIED IDEOGRAPH
+0xDFAA	0x849C	#CJK UNIFIED IDEOGRAPH
+0xDFAB	0x9178	#CJK UNIFIED IDEOGRAPH
+0xDFAC	0x9730	#CJK UNIFIED IDEOGRAPH
+0xDFAD	0x4E77	#CJK UNIFIED IDEOGRAPH
+0xDFAE	0x6492	#CJK UNIFIED IDEOGRAPH
+0xDFAF	0x6BBA	#CJK UNIFIED IDEOGRAPH
+0xDFB0	0x715E	#CJK UNIFIED IDEOGRAPH
+0xDFB1	0x85A9	#CJK UNIFIED IDEOGRAPH
+0xDFB2	0x4E09	#CJK UNIFIED IDEOGRAPH
+0xDFB3	0xF96B	#CJK COMPATIBILITY IDEOGRAPH
+0xDFB4	0x6749	#CJK UNIFIED IDEOGRAPH
+0xDFB5	0x68EE	#CJK UNIFIED IDEOGRAPH
+0xDFB6	0x6E17	#CJK UNIFIED IDEOGRAPH
+0xDFB7	0x829F	#CJK UNIFIED IDEOGRAPH
+0xDFB8	0x8518	#CJK UNIFIED IDEOGRAPH
+0xDFB9	0x886B	#CJK UNIFIED IDEOGRAPH
+0xDFBA	0x63F7	#CJK UNIFIED IDEOGRAPH
+0xDFBB	0x6F81	#CJK UNIFIED IDEOGRAPH
+0xDFBC	0x9212	#CJK UNIFIED IDEOGRAPH
+0xDFBD	0x98AF	#CJK UNIFIED IDEOGRAPH
+0xDFBE	0x4E0A	#CJK UNIFIED IDEOGRAPH
+0xDFBF	0x50B7	#CJK UNIFIED IDEOGRAPH
+0xDFC0	0x50CF	#CJK UNIFIED IDEOGRAPH
+0xDFC1	0x511F	#CJK UNIFIED IDEOGRAPH
+0xDFC2	0x5546	#CJK UNIFIED IDEOGRAPH
+0xDFC3	0x55AA	#CJK UNIFIED IDEOGRAPH
+0xDFC4	0x5617	#CJK UNIFIED IDEOGRAPH
+0xDFC5	0x5B40	#CJK UNIFIED IDEOGRAPH
+0xDFC6	0x5C19	#CJK UNIFIED IDEOGRAPH
+0xDFC7	0x5CE0	#CJK UNIFIED IDEOGRAPH
+0xDFC8	0x5E38	#CJK UNIFIED IDEOGRAPH
+0xDFC9	0x5E8A	#CJK UNIFIED IDEOGRAPH
+0xDFCA	0x5EA0	#CJK UNIFIED IDEOGRAPH
+0xDFCB	0x5EC2	#CJK UNIFIED IDEOGRAPH
+0xDFCC	0x60F3	#CJK UNIFIED IDEOGRAPH
+0xDFCD	0x6851	#CJK UNIFIED IDEOGRAPH
+0xDFCE	0x6A61	#CJK UNIFIED IDEOGRAPH
+0xDFCF	0x6E58	#CJK UNIFIED IDEOGRAPH
+0xDFD0	0x723D	#CJK UNIFIED IDEOGRAPH
+0xDFD1	0x7240	#CJK UNIFIED IDEOGRAPH
+0xDFD2	0x72C0	#CJK UNIFIED IDEOGRAPH
+0xDFD3	0x76F8	#CJK UNIFIED IDEOGRAPH
+0xDFD4	0x7965	#CJK UNIFIED IDEOGRAPH
+0xDFD5	0x7BB1	#CJK UNIFIED IDEOGRAPH
+0xDFD6	0x7FD4	#CJK UNIFIED IDEOGRAPH
+0xDFD7	0x88F3	#CJK UNIFIED IDEOGRAPH
+0xDFD8	0x89F4	#CJK UNIFIED IDEOGRAPH
+0xDFD9	0x8A73	#CJK UNIFIED IDEOGRAPH
+0xDFDA	0x8C61	#CJK UNIFIED IDEOGRAPH
+0xDFDB	0x8CDE	#CJK UNIFIED IDEOGRAPH
+0xDFDC	0x971C	#CJK UNIFIED IDEOGRAPH
+0xDFDD	0x585E	#CJK UNIFIED IDEOGRAPH
+0xDFDE	0x74BD	#CJK UNIFIED IDEOGRAPH
+0xDFDF	0x8CFD	#CJK UNIFIED IDEOGRAPH
+0xDFE0	0x55C7	#CJK UNIFIED IDEOGRAPH
+0xDFE1	0xF96C	#CJK COMPATIBILITY IDEOGRAPH
+0xDFE2	0x7A61	#CJK UNIFIED IDEOGRAPH
+0xDFE3	0x7D22	#CJK UNIFIED IDEOGRAPH
+0xDFE4	0x8272	#CJK UNIFIED IDEOGRAPH
+0xDFE5	0x7272	#CJK UNIFIED IDEOGRAPH
+0xDFE6	0x751F	#CJK UNIFIED IDEOGRAPH
+0xDFE7	0x7525	#CJK UNIFIED IDEOGRAPH
+0xDFE8	0xF96D	#CJK COMPATIBILITY IDEOGRAPH
+0xDFE9	0x7B19	#CJK UNIFIED IDEOGRAPH
+0xDFEA	0x5885	#CJK UNIFIED IDEOGRAPH
+0xDFEB	0x58FB	#CJK UNIFIED IDEOGRAPH
+0xDFEC	0x5DBC	#CJK UNIFIED IDEOGRAPH
+0xDFED	0x5E8F	#CJK UNIFIED IDEOGRAPH
+0xDFEE	0x5EB6	#CJK UNIFIED IDEOGRAPH
+0xDFEF	0x5F90	#CJK UNIFIED IDEOGRAPH
+0xDFF0	0x6055	#CJK UNIFIED IDEOGRAPH
+0xDFF1	0x6292	#CJK UNIFIED IDEOGRAPH
+0xDFF2	0x637F	#CJK UNIFIED IDEOGRAPH
+0xDFF3	0x654D	#CJK UNIFIED IDEOGRAPH
+0xDFF4	0x6691	#CJK UNIFIED IDEOGRAPH
+0xDFF5	0x66D9	#CJK UNIFIED IDEOGRAPH
+0xDFF6	0x66F8	#CJK UNIFIED IDEOGRAPH
+0xDFF7	0x6816	#CJK UNIFIED IDEOGRAPH
+0xDFF8	0x68F2	#CJK UNIFIED IDEOGRAPH
+0xDFF9	0x7280	#CJK UNIFIED IDEOGRAPH
+0xDFFA	0x745E	#CJK UNIFIED IDEOGRAPH
+0xDFFB	0x7B6E	#CJK UNIFIED IDEOGRAPH
+0xDFFC	0x7D6E	#CJK UNIFIED IDEOGRAPH
+0xDFFD	0x7DD6	#CJK UNIFIED IDEOGRAPH
+0xDFFE	0x7F72	#CJK UNIFIED IDEOGRAPH
+0xE0A1	0x80E5	#CJK UNIFIED IDEOGRAPH
+0xE0A2	0x8212	#CJK UNIFIED IDEOGRAPH
+0xE0A3	0x85AF	#CJK UNIFIED IDEOGRAPH
+0xE0A4	0x897F	#CJK UNIFIED IDEOGRAPH
+0xE0A5	0x8A93	#CJK UNIFIED IDEOGRAPH
+0xE0A6	0x901D	#CJK UNIFIED IDEOGRAPH
+0xE0A7	0x92E4	#CJK UNIFIED IDEOGRAPH
+0xE0A8	0x9ECD	#CJK UNIFIED IDEOGRAPH
+0xE0A9	0x9F20	#CJK UNIFIED IDEOGRAPH
+0xE0AA	0x5915	#CJK UNIFIED IDEOGRAPH
+0xE0AB	0x596D	#CJK UNIFIED IDEOGRAPH
+0xE0AC	0x5E2D	#CJK UNIFIED IDEOGRAPH
+0xE0AD	0x60DC	#CJK UNIFIED IDEOGRAPH
+0xE0AE	0x6614	#CJK UNIFIED IDEOGRAPH
+0xE0AF	0x6673	#CJK UNIFIED IDEOGRAPH
+0xE0B0	0x6790	#CJK UNIFIED IDEOGRAPH
+0xE0B1	0x6C50	#CJK UNIFIED IDEOGRAPH
+0xE0B2	0x6DC5	#CJK UNIFIED IDEOGRAPH
+0xE0B3	0x6F5F	#CJK UNIFIED IDEOGRAPH
+0xE0B4	0x77F3	#CJK UNIFIED IDEOGRAPH
+0xE0B5	0x78A9	#CJK UNIFIED IDEOGRAPH
+0xE0B6	0x84C6	#CJK UNIFIED IDEOGRAPH
+0xE0B7	0x91CB	#CJK UNIFIED IDEOGRAPH
+0xE0B8	0x932B	#CJK UNIFIED IDEOGRAPH
+0xE0B9	0x4ED9	#CJK UNIFIED IDEOGRAPH
+0xE0BA	0x50CA	#CJK UNIFIED IDEOGRAPH
+0xE0BB	0x5148	#CJK UNIFIED IDEOGRAPH
+0xE0BC	0x5584	#CJK UNIFIED IDEOGRAPH
+0xE0BD	0x5B0B	#CJK UNIFIED IDEOGRAPH
+0xE0BE	0x5BA3	#CJK UNIFIED IDEOGRAPH
+0xE0BF	0x6247	#CJK UNIFIED IDEOGRAPH
+0xE0C0	0x657E	#CJK UNIFIED IDEOGRAPH
+0xE0C1	0x65CB	#CJK UNIFIED IDEOGRAPH
+0xE0C2	0x6E32	#CJK UNIFIED IDEOGRAPH
+0xE0C3	0x717D	#CJK UNIFIED IDEOGRAPH
+0xE0C4	0x7401	#CJK UNIFIED IDEOGRAPH
+0xE0C5	0x7444	#CJK UNIFIED IDEOGRAPH
+0xE0C6	0x7487	#CJK UNIFIED IDEOGRAPH
+0xE0C7	0x74BF	#CJK UNIFIED IDEOGRAPH
+0xE0C8	0x766C	#CJK UNIFIED IDEOGRAPH
+0xE0C9	0x79AA	#CJK UNIFIED IDEOGRAPH
+0xE0CA	0x7DDA	#CJK UNIFIED IDEOGRAPH
+0xE0CB	0x7E55	#CJK UNIFIED IDEOGRAPH
+0xE0CC	0x7FA8	#CJK UNIFIED IDEOGRAPH
+0xE0CD	0x817A	#CJK UNIFIED IDEOGRAPH
+0xE0CE	0x81B3	#CJK UNIFIED IDEOGRAPH
+0xE0CF	0x8239	#CJK UNIFIED IDEOGRAPH
+0xE0D0	0x861A	#CJK UNIFIED IDEOGRAPH
+0xE0D1	0x87EC	#CJK UNIFIED IDEOGRAPH
+0xE0D2	0x8A75	#CJK UNIFIED IDEOGRAPH
+0xE0D3	0x8DE3	#CJK UNIFIED IDEOGRAPH
+0xE0D4	0x9078	#CJK UNIFIED IDEOGRAPH
+0xE0D5	0x9291	#CJK UNIFIED IDEOGRAPH
+0xE0D6	0x9425	#CJK UNIFIED IDEOGRAPH
+0xE0D7	0x994D	#CJK UNIFIED IDEOGRAPH
+0xE0D8	0x9BAE	#CJK UNIFIED IDEOGRAPH
+0xE0D9	0x5368	#CJK UNIFIED IDEOGRAPH
+0xE0DA	0x5C51	#CJK UNIFIED IDEOGRAPH
+0xE0DB	0x6954	#CJK UNIFIED IDEOGRAPH
+0xE0DC	0x6CC4	#CJK UNIFIED IDEOGRAPH
+0xE0DD	0x6D29	#CJK UNIFIED IDEOGRAPH
+0xE0DE	0x6E2B	#CJK UNIFIED IDEOGRAPH
+0xE0DF	0x820C	#CJK UNIFIED IDEOGRAPH
+0xE0E0	0x859B	#CJK UNIFIED IDEOGRAPH
+0xE0E1	0x893B	#CJK UNIFIED IDEOGRAPH
+0xE0E2	0x8A2D	#CJK UNIFIED IDEOGRAPH
+0xE0E3	0x8AAA	#CJK UNIFIED IDEOGRAPH
+0xE0E4	0x96EA	#CJK UNIFIED IDEOGRAPH
+0xE0E5	0x9F67	#CJK UNIFIED IDEOGRAPH
+0xE0E6	0x5261	#CJK UNIFIED IDEOGRAPH
+0xE0E7	0x66B9	#CJK UNIFIED IDEOGRAPH
+0xE0E8	0x6BB2	#CJK UNIFIED IDEOGRAPH
+0xE0E9	0x7E96	#CJK UNIFIED IDEOGRAPH
+0xE0EA	0x87FE	#CJK UNIFIED IDEOGRAPH
+0xE0EB	0x8D0D	#CJK UNIFIED IDEOGRAPH
+0xE0EC	0x9583	#CJK UNIFIED IDEOGRAPH
+0xE0ED	0x965D	#CJK UNIFIED IDEOGRAPH
+0xE0EE	0x651D	#CJK UNIFIED IDEOGRAPH
+0xE0EF	0x6D89	#CJK UNIFIED IDEOGRAPH
+0xE0F0	0x71EE	#CJK UNIFIED IDEOGRAPH
+0xE0F1	0xF96E	#CJK COMPATIBILITY IDEOGRAPH
+0xE0F2	0x57CE	#CJK UNIFIED IDEOGRAPH
+0xE0F3	0x59D3	#CJK UNIFIED IDEOGRAPH
+0xE0F4	0x5BAC	#CJK UNIFIED IDEOGRAPH
+0xE0F5	0x6027	#CJK UNIFIED IDEOGRAPH
+0xE0F6	0x60FA	#CJK UNIFIED IDEOGRAPH
+0xE0F7	0x6210	#CJK UNIFIED IDEOGRAPH
+0xE0F8	0x661F	#CJK UNIFIED IDEOGRAPH
+0xE0F9	0x665F	#CJK UNIFIED IDEOGRAPH
+0xE0FA	0x7329	#CJK UNIFIED IDEOGRAPH
+0xE0FB	0x73F9	#CJK UNIFIED IDEOGRAPH
+0xE0FC	0x76DB	#CJK UNIFIED IDEOGRAPH
+0xE0FD	0x7701	#CJK UNIFIED IDEOGRAPH
+0xE0FE	0x7B6C	#CJK UNIFIED IDEOGRAPH
+0xE1A1	0x8056	#CJK UNIFIED IDEOGRAPH
+0xE1A2	0x8072	#CJK UNIFIED IDEOGRAPH
+0xE1A3	0x8165	#CJK UNIFIED IDEOGRAPH
+0xE1A4	0x8AA0	#CJK UNIFIED IDEOGRAPH
+0xE1A5	0x9192	#CJK UNIFIED IDEOGRAPH
+0xE1A6	0x4E16	#CJK UNIFIED IDEOGRAPH
+0xE1A7	0x52E2	#CJK UNIFIED IDEOGRAPH
+0xE1A8	0x6B72	#CJK UNIFIED IDEOGRAPH
+0xE1A9	0x6D17	#CJK UNIFIED IDEOGRAPH
+0xE1AA	0x7A05	#CJK UNIFIED IDEOGRAPH
+0xE1AB	0x7B39	#CJK UNIFIED IDEOGRAPH
+0xE1AC	0x7D30	#CJK UNIFIED IDEOGRAPH
+0xE1AD	0xF96F	#CJK COMPATIBILITY IDEOGRAPH
+0xE1AE	0x8CB0	#CJK UNIFIED IDEOGRAPH
+0xE1AF	0x53EC	#CJK UNIFIED IDEOGRAPH
+0xE1B0	0x562F	#CJK UNIFIED IDEOGRAPH
+0xE1B1	0x5851	#CJK UNIFIED IDEOGRAPH
+0xE1B2	0x5BB5	#CJK UNIFIED IDEOGRAPH
+0xE1B3	0x5C0F	#CJK UNIFIED IDEOGRAPH
+0xE1B4	0x5C11	#CJK UNIFIED IDEOGRAPH
+0xE1B5	0x5DE2	#CJK UNIFIED IDEOGRAPH
+0xE1B6	0x6240	#CJK UNIFIED IDEOGRAPH
+0xE1B7	0x6383	#CJK UNIFIED IDEOGRAPH
+0xE1B8	0x6414	#CJK UNIFIED IDEOGRAPH
+0xE1B9	0x662D	#CJK UNIFIED IDEOGRAPH
+0xE1BA	0x68B3	#CJK UNIFIED IDEOGRAPH
+0xE1BB	0x6CBC	#CJK UNIFIED IDEOGRAPH
+0xE1BC	0x6D88	#CJK UNIFIED IDEOGRAPH
+0xE1BD	0x6EAF	#CJK UNIFIED IDEOGRAPH
+0xE1BE	0x701F	#CJK UNIFIED IDEOGRAPH
+0xE1BF	0x70A4	#CJK UNIFIED IDEOGRAPH
+0xE1C0	0x71D2	#CJK UNIFIED IDEOGRAPH
+0xE1C1	0x7526	#CJK UNIFIED IDEOGRAPH
+0xE1C2	0x758F	#CJK UNIFIED IDEOGRAPH
+0xE1C3	0x758E	#CJK UNIFIED IDEOGRAPH
+0xE1C4	0x7619	#CJK UNIFIED IDEOGRAPH
+0xE1C5	0x7B11	#CJK UNIFIED IDEOGRAPH
+0xE1C6	0x7BE0	#CJK UNIFIED IDEOGRAPH
+0xE1C7	0x7C2B	#CJK UNIFIED IDEOGRAPH
+0xE1C8	0x7D20	#CJK UNIFIED IDEOGRAPH
+0xE1C9	0x7D39	#CJK UNIFIED IDEOGRAPH
+0xE1CA	0x852C	#CJK UNIFIED IDEOGRAPH
+0xE1CB	0x856D	#CJK UNIFIED IDEOGRAPH
+0xE1CC	0x8607	#CJK UNIFIED IDEOGRAPH
+0xE1CD	0x8A34	#CJK UNIFIED IDEOGRAPH
+0xE1CE	0x900D	#CJK UNIFIED IDEOGRAPH
+0xE1CF	0x9061	#CJK UNIFIED IDEOGRAPH
+0xE1D0	0x90B5	#CJK UNIFIED IDEOGRAPH
+0xE1D1	0x92B7	#CJK UNIFIED IDEOGRAPH
+0xE1D2	0x97F6	#CJK UNIFIED IDEOGRAPH
+0xE1D3	0x9A37	#CJK UNIFIED IDEOGRAPH
+0xE1D4	0x4FD7	#CJK UNIFIED IDEOGRAPH
+0xE1D5	0x5C6C	#CJK UNIFIED IDEOGRAPH
+0xE1D6	0x675F	#CJK UNIFIED IDEOGRAPH
+0xE1D7	0x6D91	#CJK UNIFIED IDEOGRAPH
+0xE1D8	0x7C9F	#CJK UNIFIED IDEOGRAPH
+0xE1D9	0x7E8C	#CJK UNIFIED IDEOGRAPH
+0xE1DA	0x8B16	#CJK UNIFIED IDEOGRAPH
+0xE1DB	0x8D16	#CJK UNIFIED IDEOGRAPH
+0xE1DC	0x901F	#CJK UNIFIED IDEOGRAPH
+0xE1DD	0x5B6B	#CJK UNIFIED IDEOGRAPH
+0xE1DE	0x5DFD	#CJK UNIFIED IDEOGRAPH
+0xE1DF	0x640D	#CJK UNIFIED IDEOGRAPH
+0xE1E0	0x84C0	#CJK UNIFIED IDEOGRAPH
+0xE1E1	0x905C	#CJK UNIFIED IDEOGRAPH
+0xE1E2	0x98E1	#CJK UNIFIED IDEOGRAPH
+0xE1E3	0x7387	#CJK UNIFIED IDEOGRAPH
+0xE1E4	0x5B8B	#CJK UNIFIED IDEOGRAPH
+0xE1E5	0x609A	#CJK UNIFIED IDEOGRAPH
+0xE1E6	0x677E	#CJK UNIFIED IDEOGRAPH
+0xE1E7	0x6DDE	#CJK UNIFIED IDEOGRAPH
+0xE1E8	0x8A1F	#CJK UNIFIED IDEOGRAPH
+0xE1E9	0x8AA6	#CJK UNIFIED IDEOGRAPH
+0xE1EA	0x9001	#CJK UNIFIED IDEOGRAPH
+0xE1EB	0x980C	#CJK UNIFIED IDEOGRAPH
+0xE1EC	0x5237	#CJK UNIFIED IDEOGRAPH
+0xE1ED	0xF970	#CJK COMPATIBILITY IDEOGRAPH
+0xE1EE	0x7051	#CJK UNIFIED IDEOGRAPH
+0xE1EF	0x788E	#CJK UNIFIED IDEOGRAPH
+0xE1F0	0x9396	#CJK UNIFIED IDEOGRAPH
+0xE1F1	0x8870	#CJK UNIFIED IDEOGRAPH
+0xE1F2	0x91D7	#CJK UNIFIED IDEOGRAPH
+0xE1F3	0x4FEE	#CJK UNIFIED IDEOGRAPH
+0xE1F4	0x53D7	#CJK UNIFIED IDEOGRAPH
+0xE1F5	0x55FD	#CJK UNIFIED IDEOGRAPH
+0xE1F6	0x56DA	#CJK UNIFIED IDEOGRAPH
+0xE1F7	0x5782	#CJK UNIFIED IDEOGRAPH
+0xE1F8	0x58FD	#CJK UNIFIED IDEOGRAPH
+0xE1F9	0x5AC2	#CJK UNIFIED IDEOGRAPH
+0xE1FA	0x5B88	#CJK UNIFIED IDEOGRAPH
+0xE1FB	0x5CAB	#CJK UNIFIED IDEOGRAPH
+0xE1FC	0x5CC0	#CJK UNIFIED IDEOGRAPH
+0xE1FD	0x5E25	#CJK UNIFIED IDEOGRAPH
+0xE1FE	0x6101	#CJK UNIFIED IDEOGRAPH
+0xE2A1	0x620D	#CJK UNIFIED IDEOGRAPH
+0xE2A2	0x624B	#CJK UNIFIED IDEOGRAPH
+0xE2A3	0x6388	#CJK UNIFIED IDEOGRAPH
+0xE2A4	0x641C	#CJK UNIFIED IDEOGRAPH
+0xE2A5	0x6536	#CJK UNIFIED IDEOGRAPH
+0xE2A6	0x6578	#CJK UNIFIED IDEOGRAPH
+0xE2A7	0x6A39	#CJK UNIFIED IDEOGRAPH
+0xE2A8	0x6B8A	#CJK UNIFIED IDEOGRAPH
+0xE2A9	0x6C34	#CJK UNIFIED IDEOGRAPH
+0xE2AA	0x6D19	#CJK UNIFIED IDEOGRAPH
+0xE2AB	0x6F31	#CJK UNIFIED IDEOGRAPH
+0xE2AC	0x71E7	#CJK UNIFIED IDEOGRAPH
+0xE2AD	0x72E9	#CJK UNIFIED IDEOGRAPH
+0xE2AE	0x7378	#CJK UNIFIED IDEOGRAPH
+0xE2AF	0x7407	#CJK UNIFIED IDEOGRAPH
+0xE2B0	0x74B2	#CJK UNIFIED IDEOGRAPH
+0xE2B1	0x7626	#CJK UNIFIED IDEOGRAPH
+0xE2B2	0x7761	#CJK UNIFIED IDEOGRAPH
+0xE2B3	0x79C0	#CJK UNIFIED IDEOGRAPH
+0xE2B4	0x7A57	#CJK UNIFIED IDEOGRAPH
+0xE2B5	0x7AEA	#CJK UNIFIED IDEOGRAPH
+0xE2B6	0x7CB9	#CJK UNIFIED IDEOGRAPH
+0xE2B7	0x7D8F	#CJK UNIFIED IDEOGRAPH
+0xE2B8	0x7DAC	#CJK UNIFIED IDEOGRAPH
+0xE2B9	0x7E61	#CJK UNIFIED IDEOGRAPH
+0xE2BA	0x7F9E	#CJK UNIFIED IDEOGRAPH
+0xE2BB	0x8129	#CJK UNIFIED IDEOGRAPH
+0xE2BC	0x8331	#CJK UNIFIED IDEOGRAPH
+0xE2BD	0x8490	#CJK UNIFIED IDEOGRAPH
+0xE2BE	0x84DA	#CJK UNIFIED IDEOGRAPH
+0xE2BF	0x85EA	#CJK UNIFIED IDEOGRAPH
+0xE2C0	0x8896	#CJK UNIFIED IDEOGRAPH
+0xE2C1	0x8AB0	#CJK UNIFIED IDEOGRAPH
+0xE2C2	0x8B90	#CJK UNIFIED IDEOGRAPH
+0xE2C3	0x8F38	#CJK UNIFIED IDEOGRAPH
+0xE2C4	0x9042	#CJK UNIFIED IDEOGRAPH
+0xE2C5	0x9083	#CJK UNIFIED IDEOGRAPH
+0xE2C6	0x916C	#CJK UNIFIED IDEOGRAPH
+0xE2C7	0x9296	#CJK UNIFIED IDEOGRAPH
+0xE2C8	0x92B9	#CJK UNIFIED IDEOGRAPH
+0xE2C9	0x968B	#CJK UNIFIED IDEOGRAPH
+0xE2CA	0x96A7	#CJK UNIFIED IDEOGRAPH
+0xE2CB	0x96A8	#CJK UNIFIED IDEOGRAPH
+0xE2CC	0x96D6	#CJK UNIFIED IDEOGRAPH
+0xE2CD	0x9700	#CJK UNIFIED IDEOGRAPH
+0xE2CE	0x9808	#CJK UNIFIED IDEOGRAPH
+0xE2CF	0x9996	#CJK UNIFIED IDEOGRAPH
+0xE2D0	0x9AD3	#CJK UNIFIED IDEOGRAPH
+0xE2D1	0x9B1A	#CJK UNIFIED IDEOGRAPH
+0xE2D2	0x53D4	#CJK UNIFIED IDEOGRAPH
+0xE2D3	0x587E	#CJK UNIFIED IDEOGRAPH
+0xE2D4	0x5919	#CJK UNIFIED IDEOGRAPH
+0xE2D5	0x5B70	#CJK UNIFIED IDEOGRAPH
+0xE2D6	0x5BBF	#CJK UNIFIED IDEOGRAPH
+0xE2D7	0x6DD1	#CJK UNIFIED IDEOGRAPH
+0xE2D8	0x6F5A	#CJK UNIFIED IDEOGRAPH
+0xE2D9	0x719F	#CJK UNIFIED IDEOGRAPH
+0xE2DA	0x7421	#CJK UNIFIED IDEOGRAPH
+0xE2DB	0x74B9	#CJK UNIFIED IDEOGRAPH
+0xE2DC	0x8085	#CJK UNIFIED IDEOGRAPH
+0xE2DD	0x83FD	#CJK UNIFIED IDEOGRAPH
+0xE2DE	0x5DE1	#CJK UNIFIED IDEOGRAPH
+0xE2DF	0x5F87	#CJK UNIFIED IDEOGRAPH
+0xE2E0	0x5FAA	#CJK UNIFIED IDEOGRAPH
+0xE2E1	0x6042	#CJK UNIFIED IDEOGRAPH
+0xE2E2	0x65EC	#CJK UNIFIED IDEOGRAPH
+0xE2E3	0x6812	#CJK UNIFIED IDEOGRAPH
+0xE2E4	0x696F	#CJK UNIFIED IDEOGRAPH
+0xE2E5	0x6A53	#CJK UNIFIED IDEOGRAPH
+0xE2E6	0x6B89	#CJK UNIFIED IDEOGRAPH
+0xE2E7	0x6D35	#CJK UNIFIED IDEOGRAPH
+0xE2E8	0x6DF3	#CJK UNIFIED IDEOGRAPH
+0xE2E9	0x73E3	#CJK UNIFIED IDEOGRAPH
+0xE2EA	0x76FE	#CJK UNIFIED IDEOGRAPH
+0xE2EB	0x77AC	#CJK UNIFIED IDEOGRAPH
+0xE2EC	0x7B4D	#CJK UNIFIED IDEOGRAPH
+0xE2ED	0x7D14	#CJK UNIFIED IDEOGRAPH
+0xE2EE	0x8123	#CJK UNIFIED IDEOGRAPH
+0xE2EF	0x821C	#CJK UNIFIED IDEOGRAPH
+0xE2F0	0x8340	#CJK UNIFIED IDEOGRAPH
+0xE2F1	0x84F4	#CJK UNIFIED IDEOGRAPH
+0xE2F2	0x8563	#CJK UNIFIED IDEOGRAPH
+0xE2F3	0x8A62	#CJK UNIFIED IDEOGRAPH
+0xE2F4	0x8AC4	#CJK UNIFIED IDEOGRAPH
+0xE2F5	0x9187	#CJK UNIFIED IDEOGRAPH
+0xE2F6	0x931E	#CJK UNIFIED IDEOGRAPH
+0xE2F7	0x9806	#CJK UNIFIED IDEOGRAPH
+0xE2F8	0x99B4	#CJK UNIFIED IDEOGRAPH
+0xE2F9	0x620C	#CJK UNIFIED IDEOGRAPH
+0xE2FA	0x8853	#CJK UNIFIED IDEOGRAPH
+0xE2FB	0x8FF0	#CJK UNIFIED IDEOGRAPH
+0xE2FC	0x9265	#CJK UNIFIED IDEOGRAPH
+0xE2FD	0x5D07	#CJK UNIFIED IDEOGRAPH
+0xE2FE	0x5D27	#CJK UNIFIED IDEOGRAPH
+0xE3A1	0x5D69	#CJK UNIFIED IDEOGRAPH
+0xE3A2	0x745F	#CJK UNIFIED IDEOGRAPH
+0xE3A3	0x819D	#CJK UNIFIED IDEOGRAPH
+0xE3A4	0x8768	#CJK UNIFIED IDEOGRAPH
+0xE3A5	0x6FD5	#CJK UNIFIED IDEOGRAPH
+0xE3A6	0x62FE	#CJK UNIFIED IDEOGRAPH
+0xE3A7	0x7FD2	#CJK UNIFIED IDEOGRAPH
+0xE3A8	0x8936	#CJK UNIFIED IDEOGRAPH
+0xE3A9	0x8972	#CJK UNIFIED IDEOGRAPH
+0xE3AA	0x4E1E	#CJK UNIFIED IDEOGRAPH
+0xE3AB	0x4E58	#CJK UNIFIED IDEOGRAPH
+0xE3AC	0x50E7	#CJK UNIFIED IDEOGRAPH
+0xE3AD	0x52DD	#CJK UNIFIED IDEOGRAPH
+0xE3AE	0x5347	#CJK UNIFIED IDEOGRAPH
+0xE3AF	0x627F	#CJK UNIFIED IDEOGRAPH
+0xE3B0	0x6607	#CJK UNIFIED IDEOGRAPH
+0xE3B1	0x7E69	#CJK UNIFIED IDEOGRAPH
+0xE3B2	0x8805	#CJK UNIFIED IDEOGRAPH
+0xE3B3	0x965E	#CJK UNIFIED IDEOGRAPH
+0xE3B4	0x4F8D	#CJK UNIFIED IDEOGRAPH
+0xE3B5	0x5319	#CJK UNIFIED IDEOGRAPH
+0xE3B6	0x5636	#CJK UNIFIED IDEOGRAPH
+0xE3B7	0x59CB	#CJK UNIFIED IDEOGRAPH
+0xE3B8	0x5AA4	#CJK UNIFIED IDEOGRAPH
+0xE3B9	0x5C38	#CJK UNIFIED IDEOGRAPH
+0xE3BA	0x5C4E	#CJK UNIFIED IDEOGRAPH
+0xE3BB	0x5C4D	#CJK UNIFIED IDEOGRAPH
+0xE3BC	0x5E02	#CJK UNIFIED IDEOGRAPH
+0xE3BD	0x5F11	#CJK UNIFIED IDEOGRAPH
+0xE3BE	0x6043	#CJK UNIFIED IDEOGRAPH
+0xE3BF	0x65BD	#CJK UNIFIED IDEOGRAPH
+0xE3C0	0x662F	#CJK UNIFIED IDEOGRAPH
+0xE3C1	0x6642	#CJK UNIFIED IDEOGRAPH
+0xE3C2	0x67BE	#CJK UNIFIED IDEOGRAPH
+0xE3C3	0x67F4	#CJK UNIFIED IDEOGRAPH
+0xE3C4	0x731C	#CJK UNIFIED IDEOGRAPH
+0xE3C5	0x77E2	#CJK UNIFIED IDEOGRAPH
+0xE3C6	0x793A	#CJK UNIFIED IDEOGRAPH
+0xE3C7	0x7FC5	#CJK UNIFIED IDEOGRAPH
+0xE3C8	0x8494	#CJK UNIFIED IDEOGRAPH
+0xE3C9	0x84CD	#CJK UNIFIED IDEOGRAPH
+0xE3CA	0x8996	#CJK UNIFIED IDEOGRAPH
+0xE3CB	0x8A66	#CJK UNIFIED IDEOGRAPH
+0xE3CC	0x8A69	#CJK UNIFIED IDEOGRAPH
+0xE3CD	0x8AE1	#CJK UNIFIED IDEOGRAPH
+0xE3CE	0x8C55	#CJK UNIFIED IDEOGRAPH
+0xE3CF	0x8C7A	#CJK UNIFIED IDEOGRAPH
+0xE3D0	0x57F4	#CJK UNIFIED IDEOGRAPH
+0xE3D1	0x5BD4	#CJK UNIFIED IDEOGRAPH
+0xE3D2	0x5F0F	#CJK UNIFIED IDEOGRAPH
+0xE3D3	0x606F	#CJK UNIFIED IDEOGRAPH
+0xE3D4	0x62ED	#CJK UNIFIED IDEOGRAPH
+0xE3D5	0x690D	#CJK UNIFIED IDEOGRAPH
+0xE3D6	0x6B96	#CJK UNIFIED IDEOGRAPH
+0xE3D7	0x6E5C	#CJK UNIFIED IDEOGRAPH
+0xE3D8	0x7184	#CJK UNIFIED IDEOGRAPH
+0xE3D9	0x7BD2	#CJK UNIFIED IDEOGRAPH
+0xE3DA	0x8755	#CJK UNIFIED IDEOGRAPH
+0xE3DB	0x8B58	#CJK UNIFIED IDEOGRAPH
+0xE3DC	0x8EFE	#CJK UNIFIED IDEOGRAPH
+0xE3DD	0x98DF	#CJK UNIFIED IDEOGRAPH
+0xE3DE	0x98FE	#CJK UNIFIED IDEOGRAPH
+0xE3DF	0x4F38	#CJK UNIFIED IDEOGRAPH
+0xE3E0	0x4F81	#CJK UNIFIED IDEOGRAPH
+0xE3E1	0x4FE1	#CJK UNIFIED IDEOGRAPH
+0xE3E2	0x547B	#CJK UNIFIED IDEOGRAPH
+0xE3E3	0x5A20	#CJK UNIFIED IDEOGRAPH
+0xE3E4	0x5BB8	#CJK UNIFIED IDEOGRAPH
+0xE3E5	0x613C	#CJK UNIFIED IDEOGRAPH
+0xE3E6	0x65B0	#CJK UNIFIED IDEOGRAPH
+0xE3E7	0x6668	#CJK UNIFIED IDEOGRAPH
+0xE3E8	0x71FC	#CJK UNIFIED IDEOGRAPH
+0xE3E9	0x7533	#CJK UNIFIED IDEOGRAPH
+0xE3EA	0x795E	#CJK UNIFIED IDEOGRAPH
+0xE3EB	0x7D33	#CJK UNIFIED IDEOGRAPH
+0xE3EC	0x814E	#CJK UNIFIED IDEOGRAPH
+0xE3ED	0x81E3	#CJK UNIFIED IDEOGRAPH
+0xE3EE	0x8398	#CJK UNIFIED IDEOGRAPH
+0xE3EF	0x85AA	#CJK UNIFIED IDEOGRAPH
+0xE3F0	0x85CE	#CJK UNIFIED IDEOGRAPH
+0xE3F1	0x8703	#CJK UNIFIED IDEOGRAPH
+0xE3F2	0x8A0A	#CJK UNIFIED IDEOGRAPH
+0xE3F3	0x8EAB	#CJK UNIFIED IDEOGRAPH
+0xE3F4	0x8F9B	#CJK UNIFIED IDEOGRAPH
+0xE3F5	0xF971	#CJK COMPATIBILITY IDEOGRAPH
+0xE3F6	0x8FC5	#CJK UNIFIED IDEOGRAPH
+0xE3F7	0x5931	#CJK UNIFIED IDEOGRAPH
+0xE3F8	0x5BA4	#CJK UNIFIED IDEOGRAPH
+0xE3F9	0x5BE6	#CJK UNIFIED IDEOGRAPH
+0xE3FA	0x6089	#CJK UNIFIED IDEOGRAPH
+0xE3FB	0x5BE9	#CJK UNIFIED IDEOGRAPH
+0xE3FC	0x5C0B	#CJK UNIFIED IDEOGRAPH
+0xE3FD	0x5FC3	#CJK UNIFIED IDEOGRAPH
+0xE3FE	0x6C81	#CJK UNIFIED IDEOGRAPH
+0xE4A1	0xF972	#CJK COMPATIBILITY IDEOGRAPH
+0xE4A2	0x6DF1	#CJK UNIFIED IDEOGRAPH
+0xE4A3	0x700B	#CJK UNIFIED IDEOGRAPH
+0xE4A4	0x751A	#CJK UNIFIED IDEOGRAPH
+0xE4A5	0x82AF	#CJK UNIFIED IDEOGRAPH
+0xE4A6	0x8AF6	#CJK UNIFIED IDEOGRAPH
+0xE4A7	0x4EC0	#CJK UNIFIED IDEOGRAPH
+0xE4A8	0x5341	#CJK UNIFIED IDEOGRAPH
+0xE4A9	0xF973	#CJK COMPATIBILITY IDEOGRAPH
+0xE4AA	0x96D9	#CJK UNIFIED IDEOGRAPH
+0xE4AB	0x6C0F	#CJK UNIFIED IDEOGRAPH
+0xE4AC	0x4E9E	#CJK UNIFIED IDEOGRAPH
+0xE4AD	0x4FC4	#CJK UNIFIED IDEOGRAPH
+0xE4AE	0x5152	#CJK UNIFIED IDEOGRAPH
+0xE4AF	0x555E	#CJK UNIFIED IDEOGRAPH
+0xE4B0	0x5A25	#CJK UNIFIED IDEOGRAPH
+0xE4B1	0x5CE8	#CJK UNIFIED IDEOGRAPH
+0xE4B2	0x6211	#CJK UNIFIED IDEOGRAPH
+0xE4B3	0x7259	#CJK UNIFIED IDEOGRAPH
+0xE4B4	0x82BD	#CJK UNIFIED IDEOGRAPH
+0xE4B5	0x83AA	#CJK UNIFIED IDEOGRAPH
+0xE4B6	0x86FE	#CJK UNIFIED IDEOGRAPH
+0xE4B7	0x8859	#CJK UNIFIED IDEOGRAPH
+0xE4B8	0x8A1D	#CJK UNIFIED IDEOGRAPH
+0xE4B9	0x963F	#CJK UNIFIED IDEOGRAPH
+0xE4BA	0x96C5	#CJK UNIFIED IDEOGRAPH
+0xE4BB	0x9913	#CJK UNIFIED IDEOGRAPH
+0xE4BC	0x9D09	#CJK UNIFIED IDEOGRAPH
+0xE4BD	0x9D5D	#CJK UNIFIED IDEOGRAPH
+0xE4BE	0x580A	#CJK UNIFIED IDEOGRAPH
+0xE4BF	0x5CB3	#CJK UNIFIED IDEOGRAPH
+0xE4C0	0x5DBD	#CJK UNIFIED IDEOGRAPH
+0xE4C1	0x5E44	#CJK UNIFIED IDEOGRAPH
+0xE4C2	0x60E1	#CJK UNIFIED IDEOGRAPH
+0xE4C3	0x6115	#CJK UNIFIED IDEOGRAPH
+0xE4C4	0x63E1	#CJK UNIFIED IDEOGRAPH
+0xE4C5	0x6A02	#CJK UNIFIED IDEOGRAPH
+0xE4C6	0x6E25	#CJK UNIFIED IDEOGRAPH
+0xE4C7	0x9102	#CJK UNIFIED IDEOGRAPH
+0xE4C8	0x9354	#CJK UNIFIED IDEOGRAPH
+0xE4C9	0x984E	#CJK UNIFIED IDEOGRAPH
+0xE4CA	0x9C10	#CJK UNIFIED IDEOGRAPH
+0xE4CB	0x9F77	#CJK UNIFIED IDEOGRAPH
+0xE4CC	0x5B89	#CJK UNIFIED IDEOGRAPH
+0xE4CD	0x5CB8	#CJK UNIFIED IDEOGRAPH
+0xE4CE	0x6309	#CJK UNIFIED IDEOGRAPH
+0xE4CF	0x664F	#CJK UNIFIED IDEOGRAPH
+0xE4D0	0x6848	#CJK UNIFIED IDEOGRAPH
+0xE4D1	0x773C	#CJK UNIFIED IDEOGRAPH
+0xE4D2	0x96C1	#CJK UNIFIED IDEOGRAPH
+0xE4D3	0x978D	#CJK UNIFIED IDEOGRAPH
+0xE4D4	0x9854	#CJK UNIFIED IDEOGRAPH
+0xE4D5	0x9B9F	#CJK UNIFIED IDEOGRAPH
+0xE4D6	0x65A1	#CJK UNIFIED IDEOGRAPH
+0xE4D7	0x8B01	#CJK UNIFIED IDEOGRAPH
+0xE4D8	0x8ECB	#CJK UNIFIED IDEOGRAPH
+0xE4D9	0x95BC	#CJK UNIFIED IDEOGRAPH
+0xE4DA	0x5535	#CJK UNIFIED IDEOGRAPH
+0xE4DB	0x5CA9	#CJK UNIFIED IDEOGRAPH
+0xE4DC	0x5DD6	#CJK UNIFIED IDEOGRAPH
+0xE4DD	0x5EB5	#CJK UNIFIED IDEOGRAPH
+0xE4DE	0x6697	#CJK UNIFIED IDEOGRAPH
+0xE4DF	0x764C	#CJK UNIFIED IDEOGRAPH
+0xE4E0	0x83F4	#CJK UNIFIED IDEOGRAPH
+0xE4E1	0x95C7	#CJK UNIFIED IDEOGRAPH
+0xE4E2	0x58D3	#CJK UNIFIED IDEOGRAPH
+0xE4E3	0x62BC	#CJK UNIFIED IDEOGRAPH
+0xE4E4	0x72CE	#CJK UNIFIED IDEOGRAPH
+0xE4E5	0x9D28	#CJK UNIFIED IDEOGRAPH
+0xE4E6	0x4EF0	#CJK UNIFIED IDEOGRAPH
+0xE4E7	0x592E	#CJK UNIFIED IDEOGRAPH
+0xE4E8	0x600F	#CJK UNIFIED IDEOGRAPH
+0xE4E9	0x663B	#CJK UNIFIED IDEOGRAPH
+0xE4EA	0x6B83	#CJK UNIFIED IDEOGRAPH
+0xE4EB	0x79E7	#CJK UNIFIED IDEOGRAPH
+0xE4EC	0x9D26	#CJK UNIFIED IDEOGRAPH
+0xE4ED	0x5393	#CJK UNIFIED IDEOGRAPH
+0xE4EE	0x54C0	#CJK UNIFIED IDEOGRAPH
+0xE4EF	0x57C3	#CJK UNIFIED IDEOGRAPH
+0xE4F0	0x5D16	#CJK UNIFIED IDEOGRAPH
+0xE4F1	0x611B	#CJK UNIFIED IDEOGRAPH
+0xE4F2	0x66D6	#CJK UNIFIED IDEOGRAPH
+0xE4F3	0x6DAF	#CJK UNIFIED IDEOGRAPH
+0xE4F4	0x788D	#CJK UNIFIED IDEOGRAPH
+0xE4F5	0x827E	#CJK UNIFIED IDEOGRAPH
+0xE4F6	0x9698	#CJK UNIFIED IDEOGRAPH
+0xE4F7	0x9744	#CJK UNIFIED IDEOGRAPH
+0xE4F8	0x5384	#CJK UNIFIED IDEOGRAPH
+0xE4F9	0x627C	#CJK UNIFIED IDEOGRAPH
+0xE4FA	0x6396	#CJK UNIFIED IDEOGRAPH
+0xE4FB	0x6DB2	#CJK UNIFIED IDEOGRAPH
+0xE4FC	0x7E0A	#CJK UNIFIED IDEOGRAPH
+0xE4FD	0x814B	#CJK UNIFIED IDEOGRAPH
+0xE4FE	0x984D	#CJK UNIFIED IDEOGRAPH
+0xE5A1	0x6AFB	#CJK UNIFIED IDEOGRAPH
+0xE5A2	0x7F4C	#CJK UNIFIED IDEOGRAPH
+0xE5A3	0x9DAF	#CJK UNIFIED IDEOGRAPH
+0xE5A4	0x9E1A	#CJK UNIFIED IDEOGRAPH
+0xE5A5	0x4E5F	#CJK UNIFIED IDEOGRAPH
+0xE5A6	0x503B	#CJK UNIFIED IDEOGRAPH
+0xE5A7	0x51B6	#CJK UNIFIED IDEOGRAPH
+0xE5A8	0x591C	#CJK UNIFIED IDEOGRAPH
+0xE5A9	0x60F9	#CJK UNIFIED IDEOGRAPH
+0xE5AA	0x63F6	#CJK UNIFIED IDEOGRAPH
+0xE5AB	0x6930	#CJK UNIFIED IDEOGRAPH
+0xE5AC	0x723A	#CJK UNIFIED IDEOGRAPH
+0xE5AD	0x8036	#CJK UNIFIED IDEOGRAPH
+0xE5AE	0xF974	#CJK COMPATIBILITY IDEOGRAPH
+0xE5AF	0x91CE	#CJK UNIFIED IDEOGRAPH
+0xE5B0	0x5F31	#CJK UNIFIED IDEOGRAPH
+0xE5B1	0xF975	#CJK COMPATIBILITY IDEOGRAPH
+0xE5B2	0xF976	#CJK COMPATIBILITY IDEOGRAPH
+0xE5B3	0x7D04	#CJK UNIFIED IDEOGRAPH
+0xE5B4	0x82E5	#CJK UNIFIED IDEOGRAPH
+0xE5B5	0x846F	#CJK UNIFIED IDEOGRAPH
+0xE5B6	0x84BB	#CJK UNIFIED IDEOGRAPH
+0xE5B7	0x85E5	#CJK UNIFIED IDEOGRAPH
+0xE5B8	0x8E8D	#CJK UNIFIED IDEOGRAPH
+0xE5B9	0xF977	#CJK COMPATIBILITY IDEOGRAPH
+0xE5BA	0x4F6F	#CJK UNIFIED IDEOGRAPH
+0xE5BB	0xF978	#CJK COMPATIBILITY IDEOGRAPH
+0xE5BC	0xF979	#CJK COMPATIBILITY IDEOGRAPH
+0xE5BD	0x58E4	#CJK UNIFIED IDEOGRAPH
+0xE5BE	0x5B43	#CJK UNIFIED IDEOGRAPH
+0xE5BF	0x6059	#CJK UNIFIED IDEOGRAPH
+0xE5C0	0x63DA	#CJK UNIFIED IDEOGRAPH
+0xE5C1	0x6518	#CJK UNIFIED IDEOGRAPH
+0xE5C2	0x656D	#CJK UNIFIED IDEOGRAPH
+0xE5C3	0x6698	#CJK UNIFIED IDEOGRAPH
+0xE5C4	0xF97A	#CJK COMPATIBILITY IDEOGRAPH
+0xE5C5	0x694A	#CJK UNIFIED IDEOGRAPH
+0xE5C6	0x6A23	#CJK UNIFIED IDEOGRAPH
+0xE5C7	0x6D0B	#CJK UNIFIED IDEOGRAPH
+0xE5C8	0x7001	#CJK UNIFIED IDEOGRAPH
+0xE5C9	0x716C	#CJK UNIFIED IDEOGRAPH
+0xE5CA	0x75D2	#CJK UNIFIED IDEOGRAPH
+0xE5CB	0x760D	#CJK UNIFIED IDEOGRAPH
+0xE5CC	0x79B3	#CJK UNIFIED IDEOGRAPH
+0xE5CD	0x7A70	#CJK UNIFIED IDEOGRAPH
+0xE5CE	0xF97B	#CJK COMPATIBILITY IDEOGRAPH
+0xE5CF	0x7F8A	#CJK UNIFIED IDEOGRAPH
+0xE5D0	0xF97C	#CJK COMPATIBILITY IDEOGRAPH
+0xE5D1	0x8944	#CJK UNIFIED IDEOGRAPH
+0xE5D2	0xF97D	#CJK COMPATIBILITY IDEOGRAPH
+0xE5D3	0x8B93	#CJK UNIFIED IDEOGRAPH
+0xE5D4	0x91C0	#CJK UNIFIED IDEOGRAPH
+0xE5D5	0x967D	#CJK UNIFIED IDEOGRAPH
+0xE5D6	0xF97E	#CJK COMPATIBILITY IDEOGRAPH
+0xE5D7	0x990A	#CJK UNIFIED IDEOGRAPH
+0xE5D8	0x5704	#CJK UNIFIED IDEOGRAPH
+0xE5D9	0x5FA1	#CJK UNIFIED IDEOGRAPH
+0xE5DA	0x65BC	#CJK UNIFIED IDEOGRAPH
+0xE5DB	0x6F01	#CJK UNIFIED IDEOGRAPH
+0xE5DC	0x7600	#CJK UNIFIED IDEOGRAPH
+0xE5DD	0x79A6	#CJK UNIFIED IDEOGRAPH
+0xE5DE	0x8A9E	#CJK UNIFIED IDEOGRAPH
+0xE5DF	0x99AD	#CJK UNIFIED IDEOGRAPH
+0xE5E0	0x9B5A	#CJK UNIFIED IDEOGRAPH
+0xE5E1	0x9F6C	#CJK UNIFIED IDEOGRAPH
+0xE5E2	0x5104	#CJK UNIFIED IDEOGRAPH
+0xE5E3	0x61B6	#CJK UNIFIED IDEOGRAPH
+0xE5E4	0x6291	#CJK UNIFIED IDEOGRAPH
+0xE5E5	0x6A8D	#CJK UNIFIED IDEOGRAPH
+0xE5E6	0x81C6	#CJK UNIFIED IDEOGRAPH
+0xE5E7	0x5043	#CJK UNIFIED IDEOGRAPH
+0xE5E8	0x5830	#CJK UNIFIED IDEOGRAPH
+0xE5E9	0x5F66	#CJK UNIFIED IDEOGRAPH
+0xE5EA	0x7109	#CJK UNIFIED IDEOGRAPH
+0xE5EB	0x8A00	#CJK UNIFIED IDEOGRAPH
+0xE5EC	0x8AFA	#CJK UNIFIED IDEOGRAPH
+0xE5ED	0x5B7C	#CJK UNIFIED IDEOGRAPH
+0xE5EE	0x8616	#CJK UNIFIED IDEOGRAPH
+0xE5EF	0x4FFA	#CJK UNIFIED IDEOGRAPH
+0xE5F0	0x513C	#CJK UNIFIED IDEOGRAPH
+0xE5F1	0x56B4	#CJK UNIFIED IDEOGRAPH
+0xE5F2	0x5944	#CJK UNIFIED IDEOGRAPH
+0xE5F3	0x63A9	#CJK UNIFIED IDEOGRAPH
+0xE5F4	0x6DF9	#CJK UNIFIED IDEOGRAPH
+0xE5F5	0x5DAA	#CJK UNIFIED IDEOGRAPH
+0xE5F6	0x696D	#CJK UNIFIED IDEOGRAPH
+0xE5F7	0x5186	#CJK UNIFIED IDEOGRAPH
+0xE5F8	0x4E88	#CJK UNIFIED IDEOGRAPH
+0xE5F9	0x4F59	#CJK UNIFIED IDEOGRAPH
+0xE5FA	0xF97F	#CJK COMPATIBILITY IDEOGRAPH
+0xE5FB	0xF980	#CJK COMPATIBILITY IDEOGRAPH
+0xE5FC	0xF981	#CJK COMPATIBILITY IDEOGRAPH
+0xE5FD	0x5982	#CJK UNIFIED IDEOGRAPH
+0xE5FE	0xF982	#CJK COMPATIBILITY IDEOGRAPH
+0xE6A1	0xF983	#CJK COMPATIBILITY IDEOGRAPH
+0xE6A2	0x6B5F	#CJK UNIFIED IDEOGRAPH
+0xE6A3	0x6C5D	#CJK UNIFIED IDEOGRAPH
+0xE6A4	0xF984	#CJK COMPATIBILITY IDEOGRAPH
+0xE6A5	0x74B5	#CJK UNIFIED IDEOGRAPH
+0xE6A6	0x7916	#CJK UNIFIED IDEOGRAPH
+0xE6A7	0xF985	#CJK COMPATIBILITY IDEOGRAPH
+0xE6A8	0x8207	#CJK UNIFIED IDEOGRAPH
+0xE6A9	0x8245	#CJK UNIFIED IDEOGRAPH
+0xE6AA	0x8339	#CJK UNIFIED IDEOGRAPH
+0xE6AB	0x8F3F	#CJK UNIFIED IDEOGRAPH
+0xE6AC	0x8F5D	#CJK UNIFIED IDEOGRAPH
+0xE6AD	0xF986	#CJK COMPATIBILITY IDEOGRAPH
+0xE6AE	0x9918	#CJK UNIFIED IDEOGRAPH
+0xE6AF	0xF987	#CJK COMPATIBILITY IDEOGRAPH
+0xE6B0	0xF988	#CJK COMPATIBILITY IDEOGRAPH
+0xE6B1	0xF989	#CJK COMPATIBILITY IDEOGRAPH
+0xE6B2	0x4EA6	#CJK UNIFIED IDEOGRAPH
+0xE6B3	0xF98A	#CJK COMPATIBILITY IDEOGRAPH
+0xE6B4	0x57DF	#CJK UNIFIED IDEOGRAPH
+0xE6B5	0x5F79	#CJK UNIFIED IDEOGRAPH
+0xE6B6	0x6613	#CJK UNIFIED IDEOGRAPH
+0xE6B7	0xF98B	#CJK COMPATIBILITY IDEOGRAPH
+0xE6B8	0xF98C	#CJK COMPATIBILITY IDEOGRAPH
+0xE6B9	0x75AB	#CJK UNIFIED IDEOGRAPH
+0xE6BA	0x7E79	#CJK UNIFIED IDEOGRAPH
+0xE6BB	0x8B6F	#CJK UNIFIED IDEOGRAPH
+0xE6BC	0xF98D	#CJK COMPATIBILITY IDEOGRAPH
+0xE6BD	0x9006	#CJK UNIFIED IDEOGRAPH
+0xE6BE	0x9A5B	#CJK UNIFIED IDEOGRAPH
+0xE6BF	0x56A5	#CJK UNIFIED IDEOGRAPH
+0xE6C0	0x5827	#CJK UNIFIED IDEOGRAPH
+0xE6C1	0x59F8	#CJK UNIFIED IDEOGRAPH
+0xE6C2	0x5A1F	#CJK UNIFIED IDEOGRAPH
+0xE6C3	0x5BB4	#CJK UNIFIED IDEOGRAPH
+0xE6C4	0xF98E	#CJK COMPATIBILITY IDEOGRAPH
+0xE6C5	0x5EF6	#CJK UNIFIED IDEOGRAPH
+0xE6C6	0xF98F	#CJK COMPATIBILITY IDEOGRAPH
+0xE6C7	0xF990	#CJK COMPATIBILITY IDEOGRAPH
+0xE6C8	0x6350	#CJK UNIFIED IDEOGRAPH
+0xE6C9	0x633B	#CJK UNIFIED IDEOGRAPH
+0xE6CA	0xF991	#CJK COMPATIBILITY IDEOGRAPH
+0xE6CB	0x693D	#CJK UNIFIED IDEOGRAPH
+0xE6CC	0x6C87	#CJK UNIFIED IDEOGRAPH
+0xE6CD	0x6CBF	#CJK UNIFIED IDEOGRAPH
+0xE6CE	0x6D8E	#CJK UNIFIED IDEOGRAPH
+0xE6CF	0x6D93	#CJK UNIFIED IDEOGRAPH
+0xE6D0	0x6DF5	#CJK UNIFIED IDEOGRAPH
+0xE6D1	0x6F14	#CJK UNIFIED IDEOGRAPH
+0xE6D2	0xF992	#CJK COMPATIBILITY IDEOGRAPH
+0xE6D3	0x70DF	#CJK UNIFIED IDEOGRAPH
+0xE6D4	0x7136	#CJK UNIFIED IDEOGRAPH
+0xE6D5	0x7159	#CJK UNIFIED IDEOGRAPH
+0xE6D6	0xF993	#CJK COMPATIBILITY IDEOGRAPH
+0xE6D7	0x71C3	#CJK UNIFIED IDEOGRAPH
+0xE6D8	0x71D5	#CJK UNIFIED IDEOGRAPH
+0xE6D9	0xF994	#CJK COMPATIBILITY IDEOGRAPH
+0xE6DA	0x784F	#CJK UNIFIED IDEOGRAPH
+0xE6DB	0x786F	#CJK UNIFIED IDEOGRAPH
+0xE6DC	0xF995	#CJK COMPATIBILITY IDEOGRAPH
+0xE6DD	0x7B75	#CJK UNIFIED IDEOGRAPH
+0xE6DE	0x7DE3	#CJK UNIFIED IDEOGRAPH
+0xE6DF	0xF996	#CJK COMPATIBILITY IDEOGRAPH
+0xE6E0	0x7E2F	#CJK UNIFIED IDEOGRAPH
+0xE6E1	0xF997	#CJK COMPATIBILITY IDEOGRAPH
+0xE6E2	0x884D	#CJK UNIFIED IDEOGRAPH
+0xE6E3	0x8EDF	#CJK UNIFIED IDEOGRAPH
+0xE6E4	0xF998	#CJK COMPATIBILITY IDEOGRAPH
+0xE6E5	0xF999	#CJK COMPATIBILITY IDEOGRAPH
+0xE6E6	0xF99A	#CJK COMPATIBILITY IDEOGRAPH
+0xE6E7	0x925B	#CJK UNIFIED IDEOGRAPH
+0xE6E8	0xF99B	#CJK COMPATIBILITY IDEOGRAPH
+0xE6E9	0x9CF6	#CJK UNIFIED IDEOGRAPH
+0xE6EA	0xF99C	#CJK COMPATIBILITY IDEOGRAPH
+0xE6EB	0xF99D	#CJK COMPATIBILITY IDEOGRAPH
+0xE6EC	0xF99E	#CJK COMPATIBILITY IDEOGRAPH
+0xE6ED	0x6085	#CJK UNIFIED IDEOGRAPH
+0xE6EE	0x6D85	#CJK UNIFIED IDEOGRAPH
+0xE6EF	0xF99F	#CJK COMPATIBILITY IDEOGRAPH
+0xE6F0	0x71B1	#CJK UNIFIED IDEOGRAPH
+0xE6F1	0xF9A0	#CJK COMPATIBILITY IDEOGRAPH
+0xE6F2	0xF9A1	#CJK COMPATIBILITY IDEOGRAPH
+0xE6F3	0x95B1	#CJK UNIFIED IDEOGRAPH
+0xE6F4	0x53AD	#CJK UNIFIED IDEOGRAPH
+0xE6F5	0xF9A2	#CJK COMPATIBILITY IDEOGRAPH
+0xE6F6	0xF9A3	#CJK COMPATIBILITY IDEOGRAPH
+0xE6F7	0xF9A4	#CJK COMPATIBILITY IDEOGRAPH
+0xE6F8	0x67D3	#CJK UNIFIED IDEOGRAPH
+0xE6F9	0xF9A5	#CJK COMPATIBILITY IDEOGRAPH
+0xE6FA	0x708E	#CJK UNIFIED IDEOGRAPH
+0xE6FB	0x7130	#CJK UNIFIED IDEOGRAPH
+0xE6FC	0x7430	#CJK UNIFIED IDEOGRAPH
+0xE6FD	0x8276	#CJK UNIFIED IDEOGRAPH
+0xE6FE	0x82D2	#CJK UNIFIED IDEOGRAPH
+0xE7A1	0xF9A6	#CJK COMPATIBILITY IDEOGRAPH
+0xE7A2	0x95BB	#CJK UNIFIED IDEOGRAPH
+0xE7A3	0x9AE5	#CJK UNIFIED IDEOGRAPH
+0xE7A4	0x9E7D	#CJK UNIFIED IDEOGRAPH
+0xE7A5	0x66C4	#CJK UNIFIED IDEOGRAPH
+0xE7A6	0xF9A7	#CJK COMPATIBILITY IDEOGRAPH
+0xE7A7	0x71C1	#CJK UNIFIED IDEOGRAPH
+0xE7A8	0x8449	#CJK UNIFIED IDEOGRAPH
+0xE7A9	0xF9A8	#CJK COMPATIBILITY IDEOGRAPH
+0xE7AA	0xF9A9	#CJK COMPATIBILITY IDEOGRAPH
+0xE7AB	0x584B	#CJK UNIFIED IDEOGRAPH
+0xE7AC	0xF9AA	#CJK COMPATIBILITY IDEOGRAPH
+0xE7AD	0xF9AB	#CJK COMPATIBILITY IDEOGRAPH
+0xE7AE	0x5DB8	#CJK UNIFIED IDEOGRAPH
+0xE7AF	0x5F71	#CJK UNIFIED IDEOGRAPH
+0xE7B0	0xF9AC	#CJK COMPATIBILITY IDEOGRAPH
+0xE7B1	0x6620	#CJK UNIFIED IDEOGRAPH
+0xE7B2	0x668E	#CJK UNIFIED IDEOGRAPH
+0xE7B3	0x6979	#CJK UNIFIED IDEOGRAPH
+0xE7B4	0x69AE	#CJK UNIFIED IDEOGRAPH
+0xE7B5	0x6C38	#CJK UNIFIED IDEOGRAPH
+0xE7B6	0x6CF3	#CJK UNIFIED IDEOGRAPH
+0xE7B7	0x6E36	#CJK UNIFIED IDEOGRAPH
+0xE7B8	0x6F41	#CJK UNIFIED IDEOGRAPH
+0xE7B9	0x6FDA	#CJK UNIFIED IDEOGRAPH
+0xE7BA	0x701B	#CJK UNIFIED IDEOGRAPH
+0xE7BB	0x702F	#CJK UNIFIED IDEOGRAPH
+0xE7BC	0x7150	#CJK UNIFIED IDEOGRAPH
+0xE7BD	0x71DF	#CJK UNIFIED IDEOGRAPH
+0xE7BE	0x7370	#CJK UNIFIED IDEOGRAPH
+0xE7BF	0xF9AD	#CJK COMPATIBILITY IDEOGRAPH
+0xE7C0	0x745B	#CJK UNIFIED IDEOGRAPH
+0xE7C1	0xF9AE	#CJK COMPATIBILITY IDEOGRAPH
+0xE7C2	0x74D4	#CJK UNIFIED IDEOGRAPH
+0xE7C3	0x76C8	#CJK UNIFIED IDEOGRAPH
+0xE7C4	0x7A4E	#CJK UNIFIED IDEOGRAPH
+0xE7C5	0x7E93	#CJK UNIFIED IDEOGRAPH
+0xE7C6	0xF9AF	#CJK COMPATIBILITY IDEOGRAPH
+0xE7C7	0xF9B0	#CJK COMPATIBILITY IDEOGRAPH
+0xE7C8	0x82F1	#CJK UNIFIED IDEOGRAPH
+0xE7C9	0x8A60	#CJK UNIFIED IDEOGRAPH
+0xE7CA	0x8FCE	#CJK UNIFIED IDEOGRAPH
+0xE7CB	0xF9B1	#CJK COMPATIBILITY IDEOGRAPH
+0xE7CC	0x9348	#CJK UNIFIED IDEOGRAPH
+0xE7CD	0xF9B2	#CJK COMPATIBILITY IDEOGRAPH
+0xE7CE	0x9719	#CJK UNIFIED IDEOGRAPH
+0xE7CF	0xF9B3	#CJK COMPATIBILITY IDEOGRAPH
+0xE7D0	0xF9B4	#CJK COMPATIBILITY IDEOGRAPH
+0xE7D1	0x4E42	#CJK UNIFIED IDEOGRAPH
+0xE7D2	0x502A	#CJK UNIFIED IDEOGRAPH
+0xE7D3	0xF9B5	#CJK COMPATIBILITY IDEOGRAPH
+0xE7D4	0x5208	#CJK UNIFIED IDEOGRAPH
+0xE7D5	0x53E1	#CJK UNIFIED IDEOGRAPH
+0xE7D6	0x66F3	#CJK UNIFIED IDEOGRAPH
+0xE7D7	0x6C6D	#CJK UNIFIED IDEOGRAPH
+0xE7D8	0x6FCA	#CJK UNIFIED IDEOGRAPH
+0xE7D9	0x730A	#CJK UNIFIED IDEOGRAPH
+0xE7DA	0x777F	#CJK UNIFIED IDEOGRAPH
+0xE7DB	0x7A62	#CJK UNIFIED IDEOGRAPH
+0xE7DC	0x82AE	#CJK UNIFIED IDEOGRAPH
+0xE7DD	0x85DD	#CJK UNIFIED IDEOGRAPH
+0xE7DE	0x8602	#CJK UNIFIED IDEOGRAPH
+0xE7DF	0xF9B6	#CJK COMPATIBILITY IDEOGRAPH
+0xE7E0	0x88D4	#CJK UNIFIED IDEOGRAPH
+0xE7E1	0x8A63	#CJK UNIFIED IDEOGRAPH
+0xE7E2	0x8B7D	#CJK UNIFIED IDEOGRAPH
+0xE7E3	0x8C6B	#CJK UNIFIED IDEOGRAPH
+0xE7E4	0xF9B7	#CJK COMPATIBILITY IDEOGRAPH
+0xE7E5	0x92B3	#CJK UNIFIED IDEOGRAPH
+0xE7E6	0xF9B8	#CJK COMPATIBILITY IDEOGRAPH
+0xE7E7	0x9713	#CJK UNIFIED IDEOGRAPH
+0xE7E8	0x9810	#CJK UNIFIED IDEOGRAPH
+0xE7E9	0x4E94	#CJK UNIFIED IDEOGRAPH
+0xE7EA	0x4F0D	#CJK UNIFIED IDEOGRAPH
+0xE7EB	0x4FC9	#CJK UNIFIED IDEOGRAPH
+0xE7EC	0x50B2	#CJK UNIFIED IDEOGRAPH
+0xE7ED	0x5348	#CJK UNIFIED IDEOGRAPH
+0xE7EE	0x543E	#CJK UNIFIED IDEOGRAPH
+0xE7EF	0x5433	#CJK UNIFIED IDEOGRAPH
+0xE7F0	0x55DA	#CJK UNIFIED IDEOGRAPH
+0xE7F1	0x5862	#CJK UNIFIED IDEOGRAPH
+0xE7F2	0x58BA	#CJK UNIFIED IDEOGRAPH
+0xE7F3	0x5967	#CJK UNIFIED IDEOGRAPH
+0xE7F4	0x5A1B	#CJK UNIFIED IDEOGRAPH
+0xE7F5	0x5BE4	#CJK UNIFIED IDEOGRAPH
+0xE7F6	0x609F	#CJK UNIFIED IDEOGRAPH
+0xE7F7	0xF9B9	#CJK COMPATIBILITY IDEOGRAPH
+0xE7F8	0x61CA	#CJK UNIFIED IDEOGRAPH
+0xE7F9	0x6556	#CJK UNIFIED IDEOGRAPH
+0xE7FA	0x65FF	#CJK UNIFIED IDEOGRAPH
+0xE7FB	0x6664	#CJK UNIFIED IDEOGRAPH
+0xE7FC	0x68A7	#CJK UNIFIED IDEOGRAPH
+0xE7FD	0x6C5A	#CJK UNIFIED IDEOGRAPH
+0xE7FE	0x6FB3	#CJK UNIFIED IDEOGRAPH
+0xE8A1	0x70CF	#CJK UNIFIED IDEOGRAPH
+0xE8A2	0x71AC	#CJK UNIFIED IDEOGRAPH
+0xE8A3	0x7352	#CJK UNIFIED IDEOGRAPH
+0xE8A4	0x7B7D	#CJK UNIFIED IDEOGRAPH
+0xE8A5	0x8708	#CJK UNIFIED IDEOGRAPH
+0xE8A6	0x8AA4	#CJK UNIFIED IDEOGRAPH
+0xE8A7	0x9C32	#CJK UNIFIED IDEOGRAPH
+0xE8A8	0x9F07	#CJK UNIFIED IDEOGRAPH
+0xE8A9	0x5C4B	#CJK UNIFIED IDEOGRAPH
+0xE8AA	0x6C83	#CJK UNIFIED IDEOGRAPH
+0xE8AB	0x7344	#CJK UNIFIED IDEOGRAPH
+0xE8AC	0x7389	#CJK UNIFIED IDEOGRAPH
+0xE8AD	0x923A	#CJK UNIFIED IDEOGRAPH
+0xE8AE	0x6EAB	#CJK UNIFIED IDEOGRAPH
+0xE8AF	0x7465	#CJK UNIFIED IDEOGRAPH
+0xE8B0	0x761F	#CJK UNIFIED IDEOGRAPH
+0xE8B1	0x7A69	#CJK UNIFIED IDEOGRAPH
+0xE8B2	0x7E15	#CJK UNIFIED IDEOGRAPH
+0xE8B3	0x860A	#CJK UNIFIED IDEOGRAPH
+0xE8B4	0x5140	#CJK UNIFIED IDEOGRAPH
+0xE8B5	0x58C5	#CJK UNIFIED IDEOGRAPH
+0xE8B6	0x64C1	#CJK UNIFIED IDEOGRAPH
+0xE8B7	0x74EE	#CJK UNIFIED IDEOGRAPH
+0xE8B8	0x7515	#CJK UNIFIED IDEOGRAPH
+0xE8B9	0x7670	#CJK UNIFIED IDEOGRAPH
+0xE8BA	0x7FC1	#CJK UNIFIED IDEOGRAPH
+0xE8BB	0x9095	#CJK UNIFIED IDEOGRAPH
+0xE8BC	0x96CD	#CJK UNIFIED IDEOGRAPH
+0xE8BD	0x9954	#CJK UNIFIED IDEOGRAPH
+0xE8BE	0x6E26	#CJK UNIFIED IDEOGRAPH
+0xE8BF	0x74E6	#CJK UNIFIED IDEOGRAPH
+0xE8C0	0x7AA9	#CJK UNIFIED IDEOGRAPH
+0xE8C1	0x7AAA	#CJK UNIFIED IDEOGRAPH
+0xE8C2	0x81E5	#CJK UNIFIED IDEOGRAPH
+0xE8C3	0x86D9	#CJK UNIFIED IDEOGRAPH
+0xE8C4	0x8778	#CJK UNIFIED IDEOGRAPH
+0xE8C5	0x8A1B	#CJK UNIFIED IDEOGRAPH
+0xE8C6	0x5A49	#CJK UNIFIED IDEOGRAPH
+0xE8C7	0x5B8C	#CJK UNIFIED IDEOGRAPH
+0xE8C8	0x5B9B	#CJK UNIFIED IDEOGRAPH
+0xE8C9	0x68A1	#CJK UNIFIED IDEOGRAPH
+0xE8CA	0x6900	#CJK UNIFIED IDEOGRAPH
+0xE8CB	0x6D63	#CJK UNIFIED IDEOGRAPH
+0xE8CC	0x73A9	#CJK UNIFIED IDEOGRAPH
+0xE8CD	0x7413	#CJK UNIFIED IDEOGRAPH
+0xE8CE	0x742C	#CJK UNIFIED IDEOGRAPH
+0xE8CF	0x7897	#CJK UNIFIED IDEOGRAPH
+0xE8D0	0x7DE9	#CJK UNIFIED IDEOGRAPH
+0xE8D1	0x7FEB	#CJK UNIFIED IDEOGRAPH
+0xE8D2	0x8118	#CJK UNIFIED IDEOGRAPH
+0xE8D3	0x8155	#CJK UNIFIED IDEOGRAPH
+0xE8D4	0x839E	#CJK UNIFIED IDEOGRAPH
+0xE8D5	0x8C4C	#CJK UNIFIED IDEOGRAPH
+0xE8D6	0x962E	#CJK UNIFIED IDEOGRAPH
+0xE8D7	0x9811	#CJK UNIFIED IDEOGRAPH
+0xE8D8	0x66F0	#CJK UNIFIED IDEOGRAPH
+0xE8D9	0x5F80	#CJK UNIFIED IDEOGRAPH
+0xE8DA	0x65FA	#CJK UNIFIED IDEOGRAPH
+0xE8DB	0x6789	#CJK UNIFIED IDEOGRAPH
+0xE8DC	0x6C6A	#CJK UNIFIED IDEOGRAPH
+0xE8DD	0x738B	#CJK UNIFIED IDEOGRAPH
+0xE8DE	0x502D	#CJK UNIFIED IDEOGRAPH
+0xE8DF	0x5A03	#CJK UNIFIED IDEOGRAPH
+0xE8E0	0x6B6A	#CJK UNIFIED IDEOGRAPH
+0xE8E1	0x77EE	#CJK UNIFIED IDEOGRAPH
+0xE8E2	0x5916	#CJK UNIFIED IDEOGRAPH
+0xE8E3	0x5D6C	#CJK UNIFIED IDEOGRAPH
+0xE8E4	0x5DCD	#CJK UNIFIED IDEOGRAPH
+0xE8E5	0x7325	#CJK UNIFIED IDEOGRAPH
+0xE8E6	0x754F	#CJK UNIFIED IDEOGRAPH
+0xE8E7	0xF9BA	#CJK COMPATIBILITY IDEOGRAPH
+0xE8E8	0xF9BB	#CJK COMPATIBILITY IDEOGRAPH
+0xE8E9	0x50E5	#CJK UNIFIED IDEOGRAPH
+0xE8EA	0x51F9	#CJK UNIFIED IDEOGRAPH
+0xE8EB	0x582F	#CJK UNIFIED IDEOGRAPH
+0xE8EC	0x592D	#CJK UNIFIED IDEOGRAPH
+0xE8ED	0x5996	#CJK UNIFIED IDEOGRAPH
+0xE8EE	0x59DA	#CJK UNIFIED IDEOGRAPH
+0xE8EF	0x5BE5	#CJK UNIFIED IDEOGRAPH
+0xE8F0	0xF9BC	#CJK COMPATIBILITY IDEOGRAPH
+0xE8F1	0xF9BD	#CJK COMPATIBILITY IDEOGRAPH
+0xE8F2	0x5DA2	#CJK UNIFIED IDEOGRAPH
+0xE8F3	0x62D7	#CJK UNIFIED IDEOGRAPH
+0xE8F4	0x6416	#CJK UNIFIED IDEOGRAPH
+0xE8F5	0x6493	#CJK UNIFIED IDEOGRAPH
+0xE8F6	0x64FE	#CJK UNIFIED IDEOGRAPH
+0xE8F7	0xF9BE	#CJK COMPATIBILITY IDEOGRAPH
+0xE8F8	0x66DC	#CJK UNIFIED IDEOGRAPH
+0xE8F9	0xF9BF	#CJK COMPATIBILITY IDEOGRAPH
+0xE8FA	0x6A48	#CJK UNIFIED IDEOGRAPH
+0xE8FB	0xF9C0	#CJK COMPATIBILITY IDEOGRAPH
+0xE8FC	0x71FF	#CJK UNIFIED IDEOGRAPH
+0xE8FD	0x7464	#CJK UNIFIED IDEOGRAPH
+0xE8FE	0xF9C1	#CJK COMPATIBILITY IDEOGRAPH
+0xE9A1	0x7A88	#CJK UNIFIED IDEOGRAPH
+0xE9A2	0x7AAF	#CJK UNIFIED IDEOGRAPH
+0xE9A3	0x7E47	#CJK UNIFIED IDEOGRAPH
+0xE9A4	0x7E5E	#CJK UNIFIED IDEOGRAPH
+0xE9A5	0x8000	#CJK UNIFIED IDEOGRAPH
+0xE9A6	0x8170	#CJK UNIFIED IDEOGRAPH
+0xE9A7	0xF9C2	#CJK COMPATIBILITY IDEOGRAPH
+0xE9A8	0x87EF	#CJK UNIFIED IDEOGRAPH
+0xE9A9	0x8981	#CJK UNIFIED IDEOGRAPH
+0xE9AA	0x8B20	#CJK UNIFIED IDEOGRAPH
+0xE9AB	0x9059	#CJK UNIFIED IDEOGRAPH
+0xE9AC	0xF9C3	#CJK COMPATIBILITY IDEOGRAPH
+0xE9AD	0x9080	#CJK UNIFIED IDEOGRAPH
+0xE9AE	0x9952	#CJK UNIFIED IDEOGRAPH
+0xE9AF	0x617E	#CJK UNIFIED IDEOGRAPH
+0xE9B0	0x6B32	#CJK UNIFIED IDEOGRAPH
+0xE9B1	0x6D74	#CJK UNIFIED IDEOGRAPH
+0xE9B2	0x7E1F	#CJK UNIFIED IDEOGRAPH
+0xE9B3	0x8925	#CJK UNIFIED IDEOGRAPH
+0xE9B4	0x8FB1	#CJK UNIFIED IDEOGRAPH
+0xE9B5	0x4FD1	#CJK UNIFIED IDEOGRAPH
+0xE9B6	0x50AD	#CJK UNIFIED IDEOGRAPH
+0xE9B7	0x5197	#CJK UNIFIED IDEOGRAPH
+0xE9B8	0x52C7	#CJK UNIFIED IDEOGRAPH
+0xE9B9	0x57C7	#CJK UNIFIED IDEOGRAPH
+0xE9BA	0x5889	#CJK UNIFIED IDEOGRAPH
+0xE9BB	0x5BB9	#CJK UNIFIED IDEOGRAPH
+0xE9BC	0x5EB8	#CJK UNIFIED IDEOGRAPH
+0xE9BD	0x6142	#CJK UNIFIED IDEOGRAPH
+0xE9BE	0x6995	#CJK UNIFIED IDEOGRAPH
+0xE9BF	0x6D8C	#CJK UNIFIED IDEOGRAPH
+0xE9C0	0x6E67	#CJK UNIFIED IDEOGRAPH
+0xE9C1	0x6EB6	#CJK UNIFIED IDEOGRAPH
+0xE9C2	0x7194	#CJK UNIFIED IDEOGRAPH
+0xE9C3	0x7462	#CJK UNIFIED IDEOGRAPH
+0xE9C4	0x7528	#CJK UNIFIED IDEOGRAPH
+0xE9C5	0x752C	#CJK UNIFIED IDEOGRAPH
+0xE9C6	0x8073	#CJK UNIFIED IDEOGRAPH
+0xE9C7	0x8338	#CJK UNIFIED IDEOGRAPH
+0xE9C8	0x84C9	#CJK UNIFIED IDEOGRAPH
+0xE9C9	0x8E0A	#CJK UNIFIED IDEOGRAPH
+0xE9CA	0x9394	#CJK UNIFIED IDEOGRAPH
+0xE9CB	0x93DE	#CJK UNIFIED IDEOGRAPH
+0xE9CC	0xF9C4	#CJK COMPATIBILITY IDEOGRAPH
+0xE9CD	0x4E8E	#CJK UNIFIED IDEOGRAPH
+0xE9CE	0x4F51	#CJK UNIFIED IDEOGRAPH
+0xE9CF	0x5076	#CJK UNIFIED IDEOGRAPH
+0xE9D0	0x512A	#CJK UNIFIED IDEOGRAPH
+0xE9D1	0x53C8	#CJK UNIFIED IDEOGRAPH
+0xE9D2	0x53CB	#CJK UNIFIED IDEOGRAPH
+0xE9D3	0x53F3	#CJK UNIFIED IDEOGRAPH
+0xE9D4	0x5B87	#CJK UNIFIED IDEOGRAPH
+0xE9D5	0x5BD3	#CJK UNIFIED IDEOGRAPH
+0xE9D6	0x5C24	#CJK UNIFIED IDEOGRAPH
+0xE9D7	0x611A	#CJK UNIFIED IDEOGRAPH
+0xE9D8	0x6182	#CJK UNIFIED IDEOGRAPH
+0xE9D9	0x65F4	#CJK UNIFIED IDEOGRAPH
+0xE9DA	0x725B	#CJK UNIFIED IDEOGRAPH
+0xE9DB	0x7397	#CJK UNIFIED IDEOGRAPH
+0xE9DC	0x7440	#CJK UNIFIED IDEOGRAPH
+0xE9DD	0x76C2	#CJK UNIFIED IDEOGRAPH
+0xE9DE	0x7950	#CJK UNIFIED IDEOGRAPH
+0xE9DF	0x7991	#CJK UNIFIED IDEOGRAPH
+0xE9E0	0x79B9	#CJK UNIFIED IDEOGRAPH
+0xE9E1	0x7D06	#CJK UNIFIED IDEOGRAPH
+0xE9E2	0x7FBD	#CJK UNIFIED IDEOGRAPH
+0xE9E3	0x828B	#CJK UNIFIED IDEOGRAPH
+0xE9E4	0x85D5	#CJK UNIFIED IDEOGRAPH
+0xE9E5	0x865E	#CJK UNIFIED IDEOGRAPH
+0xE9E6	0x8FC2	#CJK UNIFIED IDEOGRAPH
+0xE9E7	0x9047	#CJK UNIFIED IDEOGRAPH
+0xE9E8	0x90F5	#CJK UNIFIED IDEOGRAPH
+0xE9E9	0x91EA	#CJK UNIFIED IDEOGRAPH
+0xE9EA	0x9685	#CJK UNIFIED IDEOGRAPH
+0xE9EB	0x96E8	#CJK UNIFIED IDEOGRAPH
+0xE9EC	0x96E9	#CJK UNIFIED IDEOGRAPH
+0xE9ED	0x52D6	#CJK UNIFIED IDEOGRAPH
+0xE9EE	0x5F67	#CJK UNIFIED IDEOGRAPH
+0xE9EF	0x65ED	#CJK UNIFIED IDEOGRAPH
+0xE9F0	0x6631	#CJK UNIFIED IDEOGRAPH
+0xE9F1	0x682F	#CJK UNIFIED IDEOGRAPH
+0xE9F2	0x715C	#CJK UNIFIED IDEOGRAPH
+0xE9F3	0x7A36	#CJK UNIFIED IDEOGRAPH
+0xE9F4	0x90C1	#CJK UNIFIED IDEOGRAPH
+0xE9F5	0x980A	#CJK UNIFIED IDEOGRAPH
+0xE9F6	0x4E91	#CJK UNIFIED IDEOGRAPH
+0xE9F7	0xF9C5	#CJK COMPATIBILITY IDEOGRAPH
+0xE9F8	0x6A52	#CJK UNIFIED IDEOGRAPH
+0xE9F9	0x6B9E	#CJK UNIFIED IDEOGRAPH
+0xE9FA	0x6F90	#CJK UNIFIED IDEOGRAPH
+0xE9FB	0x7189	#CJK UNIFIED IDEOGRAPH
+0xE9FC	0x8018	#CJK UNIFIED IDEOGRAPH
+0xE9FD	0x82B8	#CJK UNIFIED IDEOGRAPH
+0xE9FE	0x8553	#CJK UNIFIED IDEOGRAPH
+0xEAA1	0x904B	#CJK UNIFIED IDEOGRAPH
+0xEAA2	0x9695	#CJK UNIFIED IDEOGRAPH
+0xEAA3	0x96F2	#CJK UNIFIED IDEOGRAPH
+0xEAA4	0x97FB	#CJK UNIFIED IDEOGRAPH
+0xEAA5	0x851A	#CJK UNIFIED IDEOGRAPH
+0xEAA6	0x9B31	#CJK UNIFIED IDEOGRAPH
+0xEAA7	0x4E90	#CJK UNIFIED IDEOGRAPH
+0xEAA8	0x718A	#CJK UNIFIED IDEOGRAPH
+0xEAA9	0x96C4	#CJK UNIFIED IDEOGRAPH
+0xEAAA	0x5143	#CJK UNIFIED IDEOGRAPH
+0xEAAB	0x539F	#CJK UNIFIED IDEOGRAPH
+0xEAAC	0x54E1	#CJK UNIFIED IDEOGRAPH
+0xEAAD	0x5713	#CJK UNIFIED IDEOGRAPH
+0xEAAE	0x5712	#CJK UNIFIED IDEOGRAPH
+0xEAAF	0x57A3	#CJK UNIFIED IDEOGRAPH
+0xEAB0	0x5A9B	#CJK UNIFIED IDEOGRAPH
+0xEAB1	0x5AC4	#CJK UNIFIED IDEOGRAPH
+0xEAB2	0x5BC3	#CJK UNIFIED IDEOGRAPH
+0xEAB3	0x6028	#CJK UNIFIED IDEOGRAPH
+0xEAB4	0x613F	#CJK UNIFIED IDEOGRAPH
+0xEAB5	0x63F4	#CJK UNIFIED IDEOGRAPH
+0xEAB6	0x6C85	#CJK UNIFIED IDEOGRAPH
+0xEAB7	0x6D39	#CJK UNIFIED IDEOGRAPH
+0xEAB8	0x6E72	#CJK UNIFIED IDEOGRAPH
+0xEAB9	0x6E90	#CJK UNIFIED IDEOGRAPH
+0xEABA	0x7230	#CJK UNIFIED IDEOGRAPH
+0xEABB	0x733F	#CJK UNIFIED IDEOGRAPH
+0xEABC	0x7457	#CJK UNIFIED IDEOGRAPH
+0xEABD	0x82D1	#CJK UNIFIED IDEOGRAPH
+0xEABE	0x8881	#CJK UNIFIED IDEOGRAPH
+0xEABF	0x8F45	#CJK UNIFIED IDEOGRAPH
+0xEAC0	0x9060	#CJK UNIFIED IDEOGRAPH
+0xEAC1	0xF9C6	#CJK COMPATIBILITY IDEOGRAPH
+0xEAC2	0x9662	#CJK UNIFIED IDEOGRAPH
+0xEAC3	0x9858	#CJK UNIFIED IDEOGRAPH
+0xEAC4	0x9D1B	#CJK UNIFIED IDEOGRAPH
+0xEAC5	0x6708	#CJK UNIFIED IDEOGRAPH
+0xEAC6	0x8D8A	#CJK UNIFIED IDEOGRAPH
+0xEAC7	0x925E	#CJK UNIFIED IDEOGRAPH
+0xEAC8	0x4F4D	#CJK UNIFIED IDEOGRAPH
+0xEAC9	0x5049	#CJK UNIFIED IDEOGRAPH
+0xEACA	0x50DE	#CJK UNIFIED IDEOGRAPH
+0xEACB	0x5371	#CJK UNIFIED IDEOGRAPH
+0xEACC	0x570D	#CJK UNIFIED IDEOGRAPH
+0xEACD	0x59D4	#CJK UNIFIED IDEOGRAPH
+0xEACE	0x5A01	#CJK UNIFIED IDEOGRAPH
+0xEACF	0x5C09	#CJK UNIFIED IDEOGRAPH
+0xEAD0	0x6170	#CJK UNIFIED IDEOGRAPH
+0xEAD1	0x6690	#CJK UNIFIED IDEOGRAPH
+0xEAD2	0x6E2D	#CJK UNIFIED IDEOGRAPH
+0xEAD3	0x7232	#CJK UNIFIED IDEOGRAPH
+0xEAD4	0x744B	#CJK UNIFIED IDEOGRAPH
+0xEAD5	0x7DEF	#CJK UNIFIED IDEOGRAPH
+0xEAD6	0x80C3	#CJK UNIFIED IDEOGRAPH
+0xEAD7	0x840E	#CJK UNIFIED IDEOGRAPH
+0xEAD8	0x8466	#CJK UNIFIED IDEOGRAPH
+0xEAD9	0x853F	#CJK UNIFIED IDEOGRAPH
+0xEADA	0x875F	#CJK UNIFIED IDEOGRAPH
+0xEADB	0x885B	#CJK UNIFIED IDEOGRAPH
+0xEADC	0x8918	#CJK UNIFIED IDEOGRAPH
+0xEADD	0x8B02	#CJK UNIFIED IDEOGRAPH
+0xEADE	0x9055	#CJK UNIFIED IDEOGRAPH
+0xEADF	0x97CB	#CJK UNIFIED IDEOGRAPH
+0xEAE0	0x9B4F	#CJK UNIFIED IDEOGRAPH
+0xEAE1	0x4E73	#CJK UNIFIED IDEOGRAPH
+0xEAE2	0x4F91	#CJK UNIFIED IDEOGRAPH
+0xEAE3	0x5112	#CJK UNIFIED IDEOGRAPH
+0xEAE4	0x516A	#CJK UNIFIED IDEOGRAPH
+0xEAE5	0xF9C7	#CJK COMPATIBILITY IDEOGRAPH
+0xEAE6	0x552F	#CJK UNIFIED IDEOGRAPH
+0xEAE7	0x55A9	#CJK UNIFIED IDEOGRAPH
+0xEAE8	0x5B7A	#CJK UNIFIED IDEOGRAPH
+0xEAE9	0x5BA5	#CJK UNIFIED IDEOGRAPH
+0xEAEA	0x5E7C	#CJK UNIFIED IDEOGRAPH
+0xEAEB	0x5E7D	#CJK UNIFIED IDEOGRAPH
+0xEAEC	0x5EBE	#CJK UNIFIED IDEOGRAPH
+0xEAED	0x60A0	#CJK UNIFIED IDEOGRAPH
+0xEAEE	0x60DF	#CJK UNIFIED IDEOGRAPH
+0xEAEF	0x6108	#CJK UNIFIED IDEOGRAPH
+0xEAF0	0x6109	#CJK UNIFIED IDEOGRAPH
+0xEAF1	0x63C4	#CJK UNIFIED IDEOGRAPH
+0xEAF2	0x6538	#CJK UNIFIED IDEOGRAPH
+0xEAF3	0x6709	#CJK UNIFIED IDEOGRAPH
+0xEAF4	0xF9C8	#CJK COMPATIBILITY IDEOGRAPH
+0xEAF5	0x67D4	#CJK UNIFIED IDEOGRAPH
+0xEAF6	0x67DA	#CJK UNIFIED IDEOGRAPH
+0xEAF7	0xF9C9	#CJK COMPATIBILITY IDEOGRAPH
+0xEAF8	0x6961	#CJK UNIFIED IDEOGRAPH
+0xEAF9	0x6962	#CJK UNIFIED IDEOGRAPH
+0xEAFA	0x6CB9	#CJK UNIFIED IDEOGRAPH
+0xEAFB	0x6D27	#CJK UNIFIED IDEOGRAPH
+0xEAFC	0xF9CA	#CJK COMPATIBILITY IDEOGRAPH
+0xEAFD	0x6E38	#CJK UNIFIED IDEOGRAPH
+0xEAFE	0xF9CB	#CJK COMPATIBILITY IDEOGRAPH
+0xEBA1	0x6FE1	#CJK UNIFIED IDEOGRAPH
+0xEBA2	0x7336	#CJK UNIFIED IDEOGRAPH
+0xEBA3	0x7337	#CJK UNIFIED IDEOGRAPH
+0xEBA4	0xF9CC	#CJK COMPATIBILITY IDEOGRAPH
+0xEBA5	0x745C	#CJK UNIFIED IDEOGRAPH
+0xEBA6	0x7531	#CJK UNIFIED IDEOGRAPH
+0xEBA7	0xF9CD	#CJK COMPATIBILITY IDEOGRAPH
+0xEBA8	0x7652	#CJK UNIFIED IDEOGRAPH
+0xEBA9	0xF9CE	#CJK COMPATIBILITY IDEOGRAPH
+0xEBAA	0xF9CF	#CJK COMPATIBILITY IDEOGRAPH
+0xEBAB	0x7DAD	#CJK UNIFIED IDEOGRAPH
+0xEBAC	0x81FE	#CJK UNIFIED IDEOGRAPH
+0xEBAD	0x8438	#CJK UNIFIED IDEOGRAPH
+0xEBAE	0x88D5	#CJK UNIFIED IDEOGRAPH
+0xEBAF	0x8A98	#CJK UNIFIED IDEOGRAPH
+0xEBB0	0x8ADB	#CJK UNIFIED IDEOGRAPH
+0xEBB1	0x8AED	#CJK UNIFIED IDEOGRAPH
+0xEBB2	0x8E30	#CJK UNIFIED IDEOGRAPH
+0xEBB3	0x8E42	#CJK UNIFIED IDEOGRAPH
+0xEBB4	0x904A	#CJK UNIFIED IDEOGRAPH
+0xEBB5	0x903E	#CJK UNIFIED IDEOGRAPH
+0xEBB6	0x907A	#CJK UNIFIED IDEOGRAPH
+0xEBB7	0x9149	#CJK UNIFIED IDEOGRAPH
+0xEBB8	0x91C9	#CJK UNIFIED IDEOGRAPH
+0xEBB9	0x936E	#CJK UNIFIED IDEOGRAPH
+0xEBBA	0xF9D0	#CJK COMPATIBILITY IDEOGRAPH
+0xEBBB	0xF9D1	#CJK COMPATIBILITY IDEOGRAPH
+0xEBBC	0x5809	#CJK UNIFIED IDEOGRAPH
+0xEBBD	0xF9D2	#CJK COMPATIBILITY IDEOGRAPH
+0xEBBE	0x6BD3	#CJK UNIFIED IDEOGRAPH
+0xEBBF	0x8089	#CJK UNIFIED IDEOGRAPH
+0xEBC0	0x80B2	#CJK UNIFIED IDEOGRAPH
+0xEBC1	0xF9D3	#CJK COMPATIBILITY IDEOGRAPH
+0xEBC2	0xF9D4	#CJK COMPATIBILITY IDEOGRAPH
+0xEBC3	0x5141	#CJK UNIFIED IDEOGRAPH
+0xEBC4	0x596B	#CJK UNIFIED IDEOGRAPH
+0xEBC5	0x5C39	#CJK UNIFIED IDEOGRAPH
+0xEBC6	0xF9D5	#CJK COMPATIBILITY IDEOGRAPH
+0xEBC7	0xF9D6	#CJK COMPATIBILITY IDEOGRAPH
+0xEBC8	0x6F64	#CJK UNIFIED IDEOGRAPH
+0xEBC9	0x73A7	#CJK UNIFIED IDEOGRAPH
+0xEBCA	0x80E4	#CJK UNIFIED IDEOGRAPH
+0xEBCB	0x8D07	#CJK UNIFIED IDEOGRAPH
+0xEBCC	0xF9D7	#CJK COMPATIBILITY IDEOGRAPH
+0xEBCD	0x9217	#CJK UNIFIED IDEOGRAPH
+0xEBCE	0x958F	#CJK UNIFIED IDEOGRAPH
+0xEBCF	0xF9D8	#CJK COMPATIBILITY IDEOGRAPH
+0xEBD0	0xF9D9	#CJK COMPATIBILITY IDEOGRAPH
+0xEBD1	0xF9DA	#CJK COMPATIBILITY IDEOGRAPH
+0xEBD2	0xF9DB	#CJK COMPATIBILITY IDEOGRAPH
+0xEBD3	0x807F	#CJK UNIFIED IDEOGRAPH
+0xEBD4	0x620E	#CJK UNIFIED IDEOGRAPH
+0xEBD5	0x701C	#CJK UNIFIED IDEOGRAPH
+0xEBD6	0x7D68	#CJK UNIFIED IDEOGRAPH
+0xEBD7	0x878D	#CJK UNIFIED IDEOGRAPH
+0xEBD8	0xF9DC	#CJK COMPATIBILITY IDEOGRAPH
+0xEBD9	0x57A0	#CJK UNIFIED IDEOGRAPH
+0xEBDA	0x6069	#CJK UNIFIED IDEOGRAPH
+0xEBDB	0x6147	#CJK UNIFIED IDEOGRAPH
+0xEBDC	0x6BB7	#CJK UNIFIED IDEOGRAPH
+0xEBDD	0x8ABE	#CJK UNIFIED IDEOGRAPH
+0xEBDE	0x9280	#CJK UNIFIED IDEOGRAPH
+0xEBDF	0x96B1	#CJK UNIFIED IDEOGRAPH
+0xEBE0	0x4E59	#CJK UNIFIED IDEOGRAPH
+0xEBE1	0x541F	#CJK UNIFIED IDEOGRAPH
+0xEBE2	0x6DEB	#CJK UNIFIED IDEOGRAPH
+0xEBE3	0x852D	#CJK UNIFIED IDEOGRAPH
+0xEBE4	0x9670	#CJK UNIFIED IDEOGRAPH
+0xEBE5	0x97F3	#CJK UNIFIED IDEOGRAPH
+0xEBE6	0x98EE	#CJK UNIFIED IDEOGRAPH
+0xEBE7	0x63D6	#CJK UNIFIED IDEOGRAPH
+0xEBE8	0x6CE3	#CJK UNIFIED IDEOGRAPH
+0xEBE9	0x9091	#CJK UNIFIED IDEOGRAPH
+0xEBEA	0x51DD	#CJK UNIFIED IDEOGRAPH
+0xEBEB	0x61C9	#CJK UNIFIED IDEOGRAPH
+0xEBEC	0x81BA	#CJK UNIFIED IDEOGRAPH
+0xEBED	0x9DF9	#CJK UNIFIED IDEOGRAPH
+0xEBEE	0x4F9D	#CJK UNIFIED IDEOGRAPH
+0xEBEF	0x501A	#CJK UNIFIED IDEOGRAPH
+0xEBF0	0x5100	#CJK UNIFIED IDEOGRAPH
+0xEBF1	0x5B9C	#CJK UNIFIED IDEOGRAPH
+0xEBF2	0x610F	#CJK UNIFIED IDEOGRAPH
+0xEBF3	0x61FF	#CJK UNIFIED IDEOGRAPH
+0xEBF4	0x64EC	#CJK UNIFIED IDEOGRAPH
+0xEBF5	0x6905	#CJK UNIFIED IDEOGRAPH
+0xEBF6	0x6BC5	#CJK UNIFIED IDEOGRAPH
+0xEBF7	0x7591	#CJK UNIFIED IDEOGRAPH
+0xEBF8	0x77E3	#CJK UNIFIED IDEOGRAPH
+0xEBF9	0x7FA9	#CJK UNIFIED IDEOGRAPH
+0xEBFA	0x8264	#CJK UNIFIED IDEOGRAPH
+0xEBFB	0x858F	#CJK UNIFIED IDEOGRAPH
+0xEBFC	0x87FB	#CJK UNIFIED IDEOGRAPH
+0xEBFD	0x8863	#CJK UNIFIED IDEOGRAPH
+0xEBFE	0x8ABC	#CJK UNIFIED IDEOGRAPH
+0xECA1	0x8B70	#CJK UNIFIED IDEOGRAPH
+0xECA2	0x91AB	#CJK UNIFIED IDEOGRAPH
+0xECA3	0x4E8C	#CJK UNIFIED IDEOGRAPH
+0xECA4	0x4EE5	#CJK UNIFIED IDEOGRAPH
+0xECA5	0x4F0A	#CJK UNIFIED IDEOGRAPH
+0xECA6	0xF9DD	#CJK COMPATIBILITY IDEOGRAPH
+0xECA7	0xF9DE	#CJK COMPATIBILITY IDEOGRAPH
+0xECA8	0x5937	#CJK UNIFIED IDEOGRAPH
+0xECA9	0x59E8	#CJK UNIFIED IDEOGRAPH
+0xECAA	0xF9DF	#CJK COMPATIBILITY IDEOGRAPH
+0xECAB	0x5DF2	#CJK UNIFIED IDEOGRAPH
+0xECAC	0x5F1B	#CJK UNIFIED IDEOGRAPH
+0xECAD	0x5F5B	#CJK UNIFIED IDEOGRAPH
+0xECAE	0x6021	#CJK UNIFIED IDEOGRAPH
+0xECAF	0xF9E0	#CJK COMPATIBILITY IDEOGRAPH
+0xECB0	0xF9E1	#CJK COMPATIBILITY IDEOGRAPH
+0xECB1	0xF9E2	#CJK COMPATIBILITY IDEOGRAPH
+0xECB2	0xF9E3	#CJK COMPATIBILITY IDEOGRAPH
+0xECB3	0x723E	#CJK UNIFIED IDEOGRAPH
+0xECB4	0x73E5	#CJK UNIFIED IDEOGRAPH
+0xECB5	0xF9E4	#CJK COMPATIBILITY IDEOGRAPH
+0xECB6	0x7570	#CJK UNIFIED IDEOGRAPH
+0xECB7	0x75CD	#CJK UNIFIED IDEOGRAPH
+0xECB8	0xF9E5	#CJK COMPATIBILITY IDEOGRAPH
+0xECB9	0x79FB	#CJK UNIFIED IDEOGRAPH
+0xECBA	0xF9E6	#CJK COMPATIBILITY IDEOGRAPH
+0xECBB	0x800C	#CJK UNIFIED IDEOGRAPH
+0xECBC	0x8033	#CJK UNIFIED IDEOGRAPH
+0xECBD	0x8084	#CJK UNIFIED IDEOGRAPH
+0xECBE	0x82E1	#CJK UNIFIED IDEOGRAPH
+0xECBF	0x8351	#CJK UNIFIED IDEOGRAPH
+0xECC0	0xF9E7	#CJK COMPATIBILITY IDEOGRAPH
+0xECC1	0xF9E8	#CJK COMPATIBILITY IDEOGRAPH
+0xECC2	0x8CBD	#CJK UNIFIED IDEOGRAPH
+0xECC3	0x8CB3	#CJK UNIFIED IDEOGRAPH
+0xECC4	0x9087	#CJK UNIFIED IDEOGRAPH
+0xECC5	0xF9E9	#CJK COMPATIBILITY IDEOGRAPH
+0xECC6	0xF9EA	#CJK COMPATIBILITY IDEOGRAPH
+0xECC7	0x98F4	#CJK UNIFIED IDEOGRAPH
+0xECC8	0x990C	#CJK UNIFIED IDEOGRAPH
+0xECC9	0xF9EB	#CJK COMPATIBILITY IDEOGRAPH
+0xECCA	0xF9EC	#CJK COMPATIBILITY IDEOGRAPH
+0xECCB	0x7037	#CJK UNIFIED IDEOGRAPH
+0xECCC	0x76CA	#CJK UNIFIED IDEOGRAPH
+0xECCD	0x7FCA	#CJK UNIFIED IDEOGRAPH
+0xECCE	0x7FCC	#CJK UNIFIED IDEOGRAPH
+0xECCF	0x7FFC	#CJK UNIFIED IDEOGRAPH
+0xECD0	0x8B1A	#CJK UNIFIED IDEOGRAPH
+0xECD1	0x4EBA	#CJK UNIFIED IDEOGRAPH
+0xECD2	0x4EC1	#CJK UNIFIED IDEOGRAPH
+0xECD3	0x5203	#CJK UNIFIED IDEOGRAPH
+0xECD4	0x5370	#CJK UNIFIED IDEOGRAPH
+0xECD5	0xF9ED	#CJK COMPATIBILITY IDEOGRAPH
+0xECD6	0x54BD	#CJK UNIFIED IDEOGRAPH
+0xECD7	0x56E0	#CJK UNIFIED IDEOGRAPH
+0xECD8	0x59FB	#CJK UNIFIED IDEOGRAPH
+0xECD9	0x5BC5	#CJK UNIFIED IDEOGRAPH
+0xECDA	0x5F15	#CJK UNIFIED IDEOGRAPH
+0xECDB	0x5FCD	#CJK UNIFIED IDEOGRAPH
+0xECDC	0x6E6E	#CJK UNIFIED IDEOGRAPH
+0xECDD	0xF9EE	#CJK COMPATIBILITY IDEOGRAPH
+0xECDE	0xF9EF	#CJK COMPATIBILITY IDEOGRAPH
+0xECDF	0x7D6A	#CJK UNIFIED IDEOGRAPH
+0xECE0	0x8335	#CJK UNIFIED IDEOGRAPH
+0xECE1	0xF9F0	#CJK COMPATIBILITY IDEOGRAPH
+0xECE2	0x8693	#CJK UNIFIED IDEOGRAPH
+0xECE3	0x8A8D	#CJK UNIFIED IDEOGRAPH
+0xECE4	0xF9F1	#CJK COMPATIBILITY IDEOGRAPH
+0xECE5	0x976D	#CJK UNIFIED IDEOGRAPH
+0xECE6	0x9777	#CJK UNIFIED IDEOGRAPH
+0xECE7	0xF9F2	#CJK COMPATIBILITY IDEOGRAPH
+0xECE8	0xF9F3	#CJK COMPATIBILITY IDEOGRAPH
+0xECE9	0x4E00	#CJK UNIFIED IDEOGRAPH
+0xECEA	0x4F5A	#CJK UNIFIED IDEOGRAPH
+0xECEB	0x4F7E	#CJK UNIFIED IDEOGRAPH
+0xECEC	0x58F9	#CJK UNIFIED IDEOGRAPH
+0xECED	0x65E5	#CJK UNIFIED IDEOGRAPH
+0xECEE	0x6EA2	#CJK UNIFIED IDEOGRAPH
+0xECEF	0x9038	#CJK UNIFIED IDEOGRAPH
+0xECF0	0x93B0	#CJK UNIFIED IDEOGRAPH
+0xECF1	0x99B9	#CJK UNIFIED IDEOGRAPH
+0xECF2	0x4EFB	#CJK UNIFIED IDEOGRAPH
+0xECF3	0x58EC	#CJK UNIFIED IDEOGRAPH
+0xECF4	0x598A	#CJK UNIFIED IDEOGRAPH
+0xECF5	0x59D9	#CJK UNIFIED IDEOGRAPH
+0xECF6	0x6041	#CJK UNIFIED IDEOGRAPH
+0xECF7	0xF9F4	#CJK COMPATIBILITY IDEOGRAPH
+0xECF8	0xF9F5	#CJK COMPATIBILITY IDEOGRAPH
+0xECF9	0x7A14	#CJK UNIFIED IDEOGRAPH
+0xECFA	0xF9F6	#CJK COMPATIBILITY IDEOGRAPH
+0xECFB	0x834F	#CJK UNIFIED IDEOGRAPH
+0xECFC	0x8CC3	#CJK UNIFIED IDEOGRAPH
+0xECFD	0x5165	#CJK UNIFIED IDEOGRAPH
+0xECFE	0x5344	#CJK UNIFIED IDEOGRAPH
+0xEDA1	0xF9F7	#CJK COMPATIBILITY IDEOGRAPH
+0xEDA2	0xF9F8	#CJK COMPATIBILITY IDEOGRAPH
+0xEDA3	0xF9F9	#CJK COMPATIBILITY IDEOGRAPH
+0xEDA4	0x4ECD	#CJK UNIFIED IDEOGRAPH
+0xEDA5	0x5269	#CJK UNIFIED IDEOGRAPH
+0xEDA6	0x5B55	#CJK UNIFIED IDEOGRAPH
+0xEDA7	0x82BF	#CJK UNIFIED IDEOGRAPH
+0xEDA8	0x4ED4	#CJK UNIFIED IDEOGRAPH
+0xEDA9	0x523A	#CJK UNIFIED IDEOGRAPH
+0xEDAA	0x54A8	#CJK UNIFIED IDEOGRAPH
+0xEDAB	0x59C9	#CJK UNIFIED IDEOGRAPH
+0xEDAC	0x59FF	#CJK UNIFIED IDEOGRAPH
+0xEDAD	0x5B50	#CJK UNIFIED IDEOGRAPH
+0xEDAE	0x5B57	#CJK UNIFIED IDEOGRAPH
+0xEDAF	0x5B5C	#CJK UNIFIED IDEOGRAPH
+0xEDB0	0x6063	#CJK UNIFIED IDEOGRAPH
+0xEDB1	0x6148	#CJK UNIFIED IDEOGRAPH
+0xEDB2	0x6ECB	#CJK UNIFIED IDEOGRAPH
+0xEDB3	0x7099	#CJK UNIFIED IDEOGRAPH
+0xEDB4	0x716E	#CJK UNIFIED IDEOGRAPH
+0xEDB5	0x7386	#CJK UNIFIED IDEOGRAPH
+0xEDB6	0x74F7	#CJK UNIFIED IDEOGRAPH
+0xEDB7	0x75B5	#CJK UNIFIED IDEOGRAPH
+0xEDB8	0x78C1	#CJK UNIFIED IDEOGRAPH
+0xEDB9	0x7D2B	#CJK UNIFIED IDEOGRAPH
+0xEDBA	0x8005	#CJK UNIFIED IDEOGRAPH
+0xEDBB	0x81EA	#CJK UNIFIED IDEOGRAPH
+0xEDBC	0x8328	#CJK UNIFIED IDEOGRAPH
+0xEDBD	0x8517	#CJK UNIFIED IDEOGRAPH
+0xEDBE	0x85C9	#CJK UNIFIED IDEOGRAPH
+0xEDBF	0x8AEE	#CJK UNIFIED IDEOGRAPH
+0xEDC0	0x8CC7	#CJK UNIFIED IDEOGRAPH
+0xEDC1	0x96CC	#CJK UNIFIED IDEOGRAPH
+0xEDC2	0x4F5C	#CJK UNIFIED IDEOGRAPH
+0xEDC3	0x52FA	#CJK UNIFIED IDEOGRAPH
+0xEDC4	0x56BC	#CJK UNIFIED IDEOGRAPH
+0xEDC5	0x65AB	#CJK UNIFIED IDEOGRAPH
+0xEDC6	0x6628	#CJK UNIFIED IDEOGRAPH
+0xEDC7	0x707C	#CJK UNIFIED IDEOGRAPH
+0xEDC8	0x70B8	#CJK UNIFIED IDEOGRAPH
+0xEDC9	0x7235	#CJK UNIFIED IDEOGRAPH
+0xEDCA	0x7DBD	#CJK UNIFIED IDEOGRAPH
+0xEDCB	0x828D	#CJK UNIFIED IDEOGRAPH
+0xEDCC	0x914C	#CJK UNIFIED IDEOGRAPH
+0xEDCD	0x96C0	#CJK UNIFIED IDEOGRAPH
+0xEDCE	0x9D72	#CJK UNIFIED IDEOGRAPH
+0xEDCF	0x5B71	#CJK UNIFIED IDEOGRAPH
+0xEDD0	0x68E7	#CJK UNIFIED IDEOGRAPH
+0xEDD1	0x6B98	#CJK UNIFIED IDEOGRAPH
+0xEDD2	0x6F7A	#CJK UNIFIED IDEOGRAPH
+0xEDD3	0x76DE	#CJK UNIFIED IDEOGRAPH
+0xEDD4	0x5C91	#CJK UNIFIED IDEOGRAPH
+0xEDD5	0x66AB	#CJK UNIFIED IDEOGRAPH
+0xEDD6	0x6F5B	#CJK UNIFIED IDEOGRAPH
+0xEDD7	0x7BB4	#CJK UNIFIED IDEOGRAPH
+0xEDD8	0x7C2A	#CJK UNIFIED IDEOGRAPH
+0xEDD9	0x8836	#CJK UNIFIED IDEOGRAPH
+0xEDDA	0x96DC	#CJK UNIFIED IDEOGRAPH
+0xEDDB	0x4E08	#CJK UNIFIED IDEOGRAPH
+0xEDDC	0x4ED7	#CJK UNIFIED IDEOGRAPH
+0xEDDD	0x5320	#CJK UNIFIED IDEOGRAPH
+0xEDDE	0x5834	#CJK UNIFIED IDEOGRAPH
+0xEDDF	0x58BB	#CJK UNIFIED IDEOGRAPH
+0xEDE0	0x58EF	#CJK UNIFIED IDEOGRAPH
+0xEDE1	0x596C	#CJK UNIFIED IDEOGRAPH
+0xEDE2	0x5C07	#CJK UNIFIED IDEOGRAPH
+0xEDE3	0x5E33	#CJK UNIFIED IDEOGRAPH
+0xEDE4	0x5E84	#CJK UNIFIED IDEOGRAPH
+0xEDE5	0x5F35	#CJK UNIFIED IDEOGRAPH
+0xEDE6	0x638C	#CJK UNIFIED IDEOGRAPH
+0xEDE7	0x66B2	#CJK UNIFIED IDEOGRAPH
+0xEDE8	0x6756	#CJK UNIFIED IDEOGRAPH
+0xEDE9	0x6A1F	#CJK UNIFIED IDEOGRAPH
+0xEDEA	0x6AA3	#CJK UNIFIED IDEOGRAPH
+0xEDEB	0x6B0C	#CJK UNIFIED IDEOGRAPH
+0xEDEC	0x6F3F	#CJK UNIFIED IDEOGRAPH
+0xEDED	0x7246	#CJK UNIFIED IDEOGRAPH
+0xEDEE	0xF9FA	#CJK COMPATIBILITY IDEOGRAPH
+0xEDEF	0x7350	#CJK UNIFIED IDEOGRAPH
+0xEDF0	0x748B	#CJK UNIFIED IDEOGRAPH
+0xEDF1	0x7AE0	#CJK UNIFIED IDEOGRAPH
+0xEDF2	0x7CA7	#CJK UNIFIED IDEOGRAPH
+0xEDF3	0x8178	#CJK UNIFIED IDEOGRAPH
+0xEDF4	0x81DF	#CJK UNIFIED IDEOGRAPH
+0xEDF5	0x81E7	#CJK UNIFIED IDEOGRAPH
+0xEDF6	0x838A	#CJK UNIFIED IDEOGRAPH
+0xEDF7	0x846C	#CJK UNIFIED IDEOGRAPH
+0xEDF8	0x8523	#CJK UNIFIED IDEOGRAPH
+0xEDF9	0x8594	#CJK UNIFIED IDEOGRAPH
+0xEDFA	0x85CF	#CJK UNIFIED IDEOGRAPH
+0xEDFB	0x88DD	#CJK UNIFIED IDEOGRAPH
+0xEDFC	0x8D13	#CJK UNIFIED IDEOGRAPH
+0xEDFD	0x91AC	#CJK UNIFIED IDEOGRAPH
+0xEDFE	0x9577	#CJK UNIFIED IDEOGRAPH
+0xEEA1	0x969C	#CJK UNIFIED IDEOGRAPH
+0xEEA2	0x518D	#CJK UNIFIED IDEOGRAPH
+0xEEA3	0x54C9	#CJK UNIFIED IDEOGRAPH
+0xEEA4	0x5728	#CJK UNIFIED IDEOGRAPH
+0xEEA5	0x5BB0	#CJK UNIFIED IDEOGRAPH
+0xEEA6	0x624D	#CJK UNIFIED IDEOGRAPH
+0xEEA7	0x6750	#CJK UNIFIED IDEOGRAPH
+0xEEA8	0x683D	#CJK UNIFIED IDEOGRAPH
+0xEEA9	0x6893	#CJK UNIFIED IDEOGRAPH
+0xEEAA	0x6E3D	#CJK UNIFIED IDEOGRAPH
+0xEEAB	0x6ED3	#CJK UNIFIED IDEOGRAPH
+0xEEAC	0x707D	#CJK UNIFIED IDEOGRAPH
+0xEEAD	0x7E21	#CJK UNIFIED IDEOGRAPH
+0xEEAE	0x88C1	#CJK UNIFIED IDEOGRAPH
+0xEEAF	0x8CA1	#CJK UNIFIED IDEOGRAPH
+0xEEB0	0x8F09	#CJK UNIFIED IDEOGRAPH
+0xEEB1	0x9F4B	#CJK UNIFIED IDEOGRAPH
+0xEEB2	0x9F4E	#CJK UNIFIED IDEOGRAPH
+0xEEB3	0x722D	#CJK UNIFIED IDEOGRAPH
+0xEEB4	0x7B8F	#CJK UNIFIED IDEOGRAPH
+0xEEB5	0x8ACD	#CJK UNIFIED IDEOGRAPH
+0xEEB6	0x931A	#CJK UNIFIED IDEOGRAPH
+0xEEB7	0x4F47	#CJK UNIFIED IDEOGRAPH
+0xEEB8	0x4F4E	#CJK UNIFIED IDEOGRAPH
+0xEEB9	0x5132	#CJK UNIFIED IDEOGRAPH
+0xEEBA	0x5480	#CJK UNIFIED IDEOGRAPH
+0xEEBB	0x59D0	#CJK UNIFIED IDEOGRAPH
+0xEEBC	0x5E95	#CJK UNIFIED IDEOGRAPH
+0xEEBD	0x62B5	#CJK UNIFIED IDEOGRAPH
+0xEEBE	0x6775	#CJK UNIFIED IDEOGRAPH
+0xEEBF	0x696E	#CJK UNIFIED IDEOGRAPH
+0xEEC0	0x6A17	#CJK UNIFIED IDEOGRAPH
+0xEEC1	0x6CAE	#CJK UNIFIED IDEOGRAPH
+0xEEC2	0x6E1A	#CJK UNIFIED IDEOGRAPH
+0xEEC3	0x72D9	#CJK UNIFIED IDEOGRAPH
+0xEEC4	0x732A	#CJK UNIFIED IDEOGRAPH
+0xEEC5	0x75BD	#CJK UNIFIED IDEOGRAPH
+0xEEC6	0x7BB8	#CJK UNIFIED IDEOGRAPH
+0xEEC7	0x7D35	#CJK UNIFIED IDEOGRAPH
+0xEEC8	0x82E7	#CJK UNIFIED IDEOGRAPH
+0xEEC9	0x83F9	#CJK UNIFIED IDEOGRAPH
+0xEECA	0x8457	#CJK UNIFIED IDEOGRAPH
+0xEECB	0x85F7	#CJK UNIFIED IDEOGRAPH
+0xEECC	0x8A5B	#CJK UNIFIED IDEOGRAPH
+0xEECD	0x8CAF	#CJK UNIFIED IDEOGRAPH
+0xEECE	0x8E87	#CJK UNIFIED IDEOGRAPH
+0xEECF	0x9019	#CJK UNIFIED IDEOGRAPH
+0xEED0	0x90B8	#CJK UNIFIED IDEOGRAPH
+0xEED1	0x96CE	#CJK UNIFIED IDEOGRAPH
+0xEED2	0x9F5F	#CJK UNIFIED IDEOGRAPH
+0xEED3	0x52E3	#CJK UNIFIED IDEOGRAPH
+0xEED4	0x540A	#CJK UNIFIED IDEOGRAPH
+0xEED5	0x5AE1	#CJK UNIFIED IDEOGRAPH
+0xEED6	0x5BC2	#CJK UNIFIED IDEOGRAPH
+0xEED7	0x6458	#CJK UNIFIED IDEOGRAPH
+0xEED8	0x6575	#CJK UNIFIED IDEOGRAPH
+0xEED9	0x6EF4	#CJK UNIFIED IDEOGRAPH
+0xEEDA	0x72C4	#CJK UNIFIED IDEOGRAPH
+0xEEDB	0xF9FB	#CJK COMPATIBILITY IDEOGRAPH
+0xEEDC	0x7684	#CJK UNIFIED IDEOGRAPH
+0xEEDD	0x7A4D	#CJK UNIFIED IDEOGRAPH
+0xEEDE	0x7B1B	#CJK UNIFIED IDEOGRAPH
+0xEEDF	0x7C4D	#CJK UNIFIED IDEOGRAPH
+0xEEE0	0x7E3E	#CJK UNIFIED IDEOGRAPH
+0xEEE1	0x7FDF	#CJK UNIFIED IDEOGRAPH
+0xEEE2	0x837B	#CJK UNIFIED IDEOGRAPH
+0xEEE3	0x8B2B	#CJK UNIFIED IDEOGRAPH
+0xEEE4	0x8CCA	#CJK UNIFIED IDEOGRAPH
+0xEEE5	0x8D64	#CJK UNIFIED IDEOGRAPH
+0xEEE6	0x8DE1	#CJK UNIFIED IDEOGRAPH
+0xEEE7	0x8E5F	#CJK UNIFIED IDEOGRAPH
+0xEEE8	0x8FEA	#CJK UNIFIED IDEOGRAPH
+0xEEE9	0x8FF9	#CJK UNIFIED IDEOGRAPH
+0xEEEA	0x9069	#CJK UNIFIED IDEOGRAPH
+0xEEEB	0x93D1	#CJK UNIFIED IDEOGRAPH
+0xEEEC	0x4F43	#CJK UNIFIED IDEOGRAPH
+0xEEED	0x4F7A	#CJK UNIFIED IDEOGRAPH
+0xEEEE	0x50B3	#CJK UNIFIED IDEOGRAPH
+0xEEEF	0x5168	#CJK UNIFIED IDEOGRAPH
+0xEEF0	0x5178	#CJK UNIFIED IDEOGRAPH
+0xEEF1	0x524D	#CJK UNIFIED IDEOGRAPH
+0xEEF2	0x526A	#CJK UNIFIED IDEOGRAPH
+0xEEF3	0x5861	#CJK UNIFIED IDEOGRAPH
+0xEEF4	0x587C	#CJK UNIFIED IDEOGRAPH
+0xEEF5	0x5960	#CJK UNIFIED IDEOGRAPH
+0xEEF6	0x5C08	#CJK UNIFIED IDEOGRAPH
+0xEEF7	0x5C55	#CJK UNIFIED IDEOGRAPH
+0xEEF8	0x5EDB	#CJK UNIFIED IDEOGRAPH
+0xEEF9	0x609B	#CJK UNIFIED IDEOGRAPH
+0xEEFA	0x6230	#CJK UNIFIED IDEOGRAPH
+0xEEFB	0x6813	#CJK UNIFIED IDEOGRAPH
+0xEEFC	0x6BBF	#CJK UNIFIED IDEOGRAPH
+0xEEFD	0x6C08	#CJK UNIFIED IDEOGRAPH
+0xEEFE	0x6FB1	#CJK UNIFIED IDEOGRAPH
+0xEFA1	0x714E	#CJK UNIFIED IDEOGRAPH
+0xEFA2	0x7420	#CJK UNIFIED IDEOGRAPH
+0xEFA3	0x7530	#CJK UNIFIED IDEOGRAPH
+0xEFA4	0x7538	#CJK UNIFIED IDEOGRAPH
+0xEFA5	0x7551	#CJK UNIFIED IDEOGRAPH
+0xEFA6	0x7672	#CJK UNIFIED IDEOGRAPH
+0xEFA7	0x7B4C	#CJK UNIFIED IDEOGRAPH
+0xEFA8	0x7B8B	#CJK UNIFIED IDEOGRAPH
+0xEFA9	0x7BAD	#CJK UNIFIED IDEOGRAPH
+0xEFAA	0x7BC6	#CJK UNIFIED IDEOGRAPH
+0xEFAB	0x7E8F	#CJK UNIFIED IDEOGRAPH
+0xEFAC	0x8A6E	#CJK UNIFIED IDEOGRAPH
+0xEFAD	0x8F3E	#CJK UNIFIED IDEOGRAPH
+0xEFAE	0x8F49	#CJK UNIFIED IDEOGRAPH
+0xEFAF	0x923F	#CJK UNIFIED IDEOGRAPH
+0xEFB0	0x9293	#CJK UNIFIED IDEOGRAPH
+0xEFB1	0x9322	#CJK UNIFIED IDEOGRAPH
+0xEFB2	0x942B	#CJK UNIFIED IDEOGRAPH
+0xEFB3	0x96FB	#CJK UNIFIED IDEOGRAPH
+0xEFB4	0x985A	#CJK UNIFIED IDEOGRAPH
+0xEFB5	0x986B	#CJK UNIFIED IDEOGRAPH
+0xEFB6	0x991E	#CJK UNIFIED IDEOGRAPH
+0xEFB7	0x5207	#CJK UNIFIED IDEOGRAPH
+0xEFB8	0x622A	#CJK UNIFIED IDEOGRAPH
+0xEFB9	0x6298	#CJK UNIFIED IDEOGRAPH
+0xEFBA	0x6D59	#CJK UNIFIED IDEOGRAPH
+0xEFBB	0x7664	#CJK UNIFIED IDEOGRAPH
+0xEFBC	0x7ACA	#CJK UNIFIED IDEOGRAPH
+0xEFBD	0x7BC0	#CJK UNIFIED IDEOGRAPH
+0xEFBE	0x7D76	#CJK UNIFIED IDEOGRAPH
+0xEFBF	0x5360	#CJK UNIFIED IDEOGRAPH
+0xEFC0	0x5CBE	#CJK UNIFIED IDEOGRAPH
+0xEFC1	0x5E97	#CJK UNIFIED IDEOGRAPH
+0xEFC2	0x6F38	#CJK UNIFIED IDEOGRAPH
+0xEFC3	0x70B9	#CJK UNIFIED IDEOGRAPH
+0xEFC4	0x7C98	#CJK UNIFIED IDEOGRAPH
+0xEFC5	0x9711	#CJK UNIFIED IDEOGRAPH
+0xEFC6	0x9B8E	#CJK UNIFIED IDEOGRAPH
+0xEFC7	0x9EDE	#CJK UNIFIED IDEOGRAPH
+0xEFC8	0x63A5	#CJK UNIFIED IDEOGRAPH
+0xEFC9	0x647A	#CJK UNIFIED IDEOGRAPH
+0xEFCA	0x8776	#CJK UNIFIED IDEOGRAPH
+0xEFCB	0x4E01	#CJK UNIFIED IDEOGRAPH
+0xEFCC	0x4E95	#CJK UNIFIED IDEOGRAPH
+0xEFCD	0x4EAD	#CJK UNIFIED IDEOGRAPH
+0xEFCE	0x505C	#CJK UNIFIED IDEOGRAPH
+0xEFCF	0x5075	#CJK UNIFIED IDEOGRAPH
+0xEFD0	0x5448	#CJK UNIFIED IDEOGRAPH
+0xEFD1	0x59C3	#CJK UNIFIED IDEOGRAPH
+0xEFD2	0x5B9A	#CJK UNIFIED IDEOGRAPH
+0xEFD3	0x5E40	#CJK UNIFIED IDEOGRAPH
+0xEFD4	0x5EAD	#CJK UNIFIED IDEOGRAPH
+0xEFD5	0x5EF7	#CJK UNIFIED IDEOGRAPH
+0xEFD6	0x5F81	#CJK UNIFIED IDEOGRAPH
+0xEFD7	0x60C5	#CJK UNIFIED IDEOGRAPH
+0xEFD8	0x633A	#CJK UNIFIED IDEOGRAPH
+0xEFD9	0x653F	#CJK UNIFIED IDEOGRAPH
+0xEFDA	0x6574	#CJK UNIFIED IDEOGRAPH
+0xEFDB	0x65CC	#CJK UNIFIED IDEOGRAPH
+0xEFDC	0x6676	#CJK UNIFIED IDEOGRAPH
+0xEFDD	0x6678	#CJK UNIFIED IDEOGRAPH
+0xEFDE	0x67FE	#CJK UNIFIED IDEOGRAPH
+0xEFDF	0x6968	#CJK UNIFIED IDEOGRAPH
+0xEFE0	0x6A89	#CJK UNIFIED IDEOGRAPH
+0xEFE1	0x6B63	#CJK UNIFIED IDEOGRAPH
+0xEFE2	0x6C40	#CJK UNIFIED IDEOGRAPH
+0xEFE3	0x6DC0	#CJK UNIFIED IDEOGRAPH
+0xEFE4	0x6DE8	#CJK UNIFIED IDEOGRAPH
+0xEFE5	0x6E1F	#CJK UNIFIED IDEOGRAPH
+0xEFE6	0x6E5E	#CJK UNIFIED IDEOGRAPH
+0xEFE7	0x701E	#CJK UNIFIED IDEOGRAPH
+0xEFE8	0x70A1	#CJK UNIFIED IDEOGRAPH
+0xEFE9	0x738E	#CJK UNIFIED IDEOGRAPH
+0xEFEA	0x73FD	#CJK UNIFIED IDEOGRAPH
+0xEFEB	0x753A	#CJK UNIFIED IDEOGRAPH
+0xEFEC	0x775B	#CJK UNIFIED IDEOGRAPH
+0xEFED	0x7887	#CJK UNIFIED IDEOGRAPH
+0xEFEE	0x798E	#CJK UNIFIED IDEOGRAPH
+0xEFEF	0x7A0B	#CJK UNIFIED IDEOGRAPH
+0xEFF0	0x7A7D	#CJK UNIFIED IDEOGRAPH
+0xEFF1	0x7CBE	#CJK UNIFIED IDEOGRAPH
+0xEFF2	0x7D8E	#CJK UNIFIED IDEOGRAPH
+0xEFF3	0x8247	#CJK UNIFIED IDEOGRAPH
+0xEFF4	0x8A02	#CJK UNIFIED IDEOGRAPH
+0xEFF5	0x8AEA	#CJK UNIFIED IDEOGRAPH
+0xEFF6	0x8C9E	#CJK UNIFIED IDEOGRAPH
+0xEFF7	0x912D	#CJK UNIFIED IDEOGRAPH
+0xEFF8	0x914A	#CJK UNIFIED IDEOGRAPH
+0xEFF9	0x91D8	#CJK UNIFIED IDEOGRAPH
+0xEFFA	0x9266	#CJK UNIFIED IDEOGRAPH
+0xEFFB	0x92CC	#CJK UNIFIED IDEOGRAPH
+0xEFFC	0x9320	#CJK UNIFIED IDEOGRAPH
+0xEFFD	0x9706	#CJK UNIFIED IDEOGRAPH
+0xEFFE	0x9756	#CJK UNIFIED IDEOGRAPH
+0xF0A1	0x975C	#CJK UNIFIED IDEOGRAPH
+0xF0A2	0x9802	#CJK UNIFIED IDEOGRAPH
+0xF0A3	0x9F0E	#CJK UNIFIED IDEOGRAPH
+0xF0A4	0x5236	#CJK UNIFIED IDEOGRAPH
+0xF0A5	0x5291	#CJK UNIFIED IDEOGRAPH
+0xF0A6	0x557C	#CJK UNIFIED IDEOGRAPH
+0xF0A7	0x5824	#CJK UNIFIED IDEOGRAPH
+0xF0A8	0x5E1D	#CJK UNIFIED IDEOGRAPH
+0xF0A9	0x5F1F	#CJK UNIFIED IDEOGRAPH
+0xF0AA	0x608C	#CJK UNIFIED IDEOGRAPH
+0xF0AB	0x63D0	#CJK UNIFIED IDEOGRAPH
+0xF0AC	0x68AF	#CJK UNIFIED IDEOGRAPH
+0xF0AD	0x6FDF	#CJK UNIFIED IDEOGRAPH
+0xF0AE	0x796D	#CJK UNIFIED IDEOGRAPH
+0xF0AF	0x7B2C	#CJK UNIFIED IDEOGRAPH
+0xF0B0	0x81CD	#CJK UNIFIED IDEOGRAPH
+0xF0B1	0x85BA	#CJK UNIFIED IDEOGRAPH
+0xF0B2	0x88FD	#CJK UNIFIED IDEOGRAPH
+0xF0B3	0x8AF8	#CJK UNIFIED IDEOGRAPH
+0xF0B4	0x8E44	#CJK UNIFIED IDEOGRAPH
+0xF0B5	0x918D	#CJK UNIFIED IDEOGRAPH
+0xF0B6	0x9664	#CJK UNIFIED IDEOGRAPH
+0xF0B7	0x969B	#CJK UNIFIED IDEOGRAPH
+0xF0B8	0x973D	#CJK UNIFIED IDEOGRAPH
+0xF0B9	0x984C	#CJK UNIFIED IDEOGRAPH
+0xF0BA	0x9F4A	#CJK UNIFIED IDEOGRAPH
+0xF0BB	0x4FCE	#CJK UNIFIED IDEOGRAPH
+0xF0BC	0x5146	#CJK UNIFIED IDEOGRAPH
+0xF0BD	0x51CB	#CJK UNIFIED IDEOGRAPH
+0xF0BE	0x52A9	#CJK UNIFIED IDEOGRAPH
+0xF0BF	0x5632	#CJK UNIFIED IDEOGRAPH
+0xF0C0	0x5F14	#CJK UNIFIED IDEOGRAPH
+0xF0C1	0x5F6B	#CJK UNIFIED IDEOGRAPH
+0xF0C2	0x63AA	#CJK UNIFIED IDEOGRAPH
+0xF0C3	0x64CD	#CJK UNIFIED IDEOGRAPH
+0xF0C4	0x65E9	#CJK UNIFIED IDEOGRAPH
+0xF0C5	0x6641	#CJK UNIFIED IDEOGRAPH
+0xF0C6	0x66FA	#CJK UNIFIED IDEOGRAPH
+0xF0C7	0x66F9	#CJK UNIFIED IDEOGRAPH
+0xF0C8	0x671D	#CJK UNIFIED IDEOGRAPH
+0xF0C9	0x689D	#CJK UNIFIED IDEOGRAPH
+0xF0CA	0x68D7	#CJK UNIFIED IDEOGRAPH
+0xF0CB	0x69FD	#CJK UNIFIED IDEOGRAPH
+0xF0CC	0x6F15	#CJK UNIFIED IDEOGRAPH
+0xF0CD	0x6F6E	#CJK UNIFIED IDEOGRAPH
+0xF0CE	0x7167	#CJK UNIFIED IDEOGRAPH
+0xF0CF	0x71E5	#CJK UNIFIED IDEOGRAPH
+0xF0D0	0x722A	#CJK UNIFIED IDEOGRAPH
+0xF0D1	0x74AA	#CJK UNIFIED IDEOGRAPH
+0xF0D2	0x773A	#CJK UNIFIED IDEOGRAPH
+0xF0D3	0x7956	#CJK UNIFIED IDEOGRAPH
+0xF0D4	0x795A	#CJK UNIFIED IDEOGRAPH
+0xF0D5	0x79DF	#CJK UNIFIED IDEOGRAPH
+0xF0D6	0x7A20	#CJK UNIFIED IDEOGRAPH
+0xF0D7	0x7A95	#CJK UNIFIED IDEOGRAPH
+0xF0D8	0x7C97	#CJK UNIFIED IDEOGRAPH
+0xF0D9	0x7CDF	#CJK UNIFIED IDEOGRAPH
+0xF0DA	0x7D44	#CJK UNIFIED IDEOGRAPH
+0xF0DB	0x7E70	#CJK UNIFIED IDEOGRAPH
+0xF0DC	0x8087	#CJK UNIFIED IDEOGRAPH
+0xF0DD	0x85FB	#CJK UNIFIED IDEOGRAPH
+0xF0DE	0x86A4	#CJK UNIFIED IDEOGRAPH
+0xF0DF	0x8A54	#CJK UNIFIED IDEOGRAPH
+0xF0E0	0x8ABF	#CJK UNIFIED IDEOGRAPH
+0xF0E1	0x8D99	#CJK UNIFIED IDEOGRAPH
+0xF0E2	0x8E81	#CJK UNIFIED IDEOGRAPH
+0xF0E3	0x9020	#CJK UNIFIED IDEOGRAPH
+0xF0E4	0x906D	#CJK UNIFIED IDEOGRAPH
+0xF0E5	0x91E3	#CJK UNIFIED IDEOGRAPH
+0xF0E6	0x963B	#CJK UNIFIED IDEOGRAPH
+0xF0E7	0x96D5	#CJK UNIFIED IDEOGRAPH
+0xF0E8	0x9CE5	#CJK UNIFIED IDEOGRAPH
+0xF0E9	0x65CF	#CJK UNIFIED IDEOGRAPH
+0xF0EA	0x7C07	#CJK UNIFIED IDEOGRAPH
+0xF0EB	0x8DB3	#CJK UNIFIED IDEOGRAPH
+0xF0EC	0x93C3	#CJK UNIFIED IDEOGRAPH
+0xF0ED	0x5B58	#CJK UNIFIED IDEOGRAPH
+0xF0EE	0x5C0A	#CJK UNIFIED IDEOGRAPH
+0xF0EF	0x5352	#CJK UNIFIED IDEOGRAPH
+0xF0F0	0x62D9	#CJK UNIFIED IDEOGRAPH
+0xF0F1	0x731D	#CJK UNIFIED IDEOGRAPH
+0xF0F2	0x5027	#CJK UNIFIED IDEOGRAPH
+0xF0F3	0x5B97	#CJK UNIFIED IDEOGRAPH
+0xF0F4	0x5F9E	#CJK UNIFIED IDEOGRAPH
+0xF0F5	0x60B0	#CJK UNIFIED IDEOGRAPH
+0xF0F6	0x616B	#CJK UNIFIED IDEOGRAPH
+0xF0F7	0x68D5	#CJK UNIFIED IDEOGRAPH
+0xF0F8	0x6DD9	#CJK UNIFIED IDEOGRAPH
+0xF0F9	0x742E	#CJK UNIFIED IDEOGRAPH
+0xF0FA	0x7A2E	#CJK UNIFIED IDEOGRAPH
+0xF0FB	0x7D42	#CJK UNIFIED IDEOGRAPH
+0xF0FC	0x7D9C	#CJK UNIFIED IDEOGRAPH
+0xF0FD	0x7E31	#CJK UNIFIED IDEOGRAPH
+0xF0FE	0x816B	#CJK UNIFIED IDEOGRAPH
+0xF1A1	0x8E2A	#CJK UNIFIED IDEOGRAPH
+0xF1A2	0x8E35	#CJK UNIFIED IDEOGRAPH
+0xF1A3	0x937E	#CJK UNIFIED IDEOGRAPH
+0xF1A4	0x9418	#CJK UNIFIED IDEOGRAPH
+0xF1A5	0x4F50	#CJK UNIFIED IDEOGRAPH
+0xF1A6	0x5750	#CJK UNIFIED IDEOGRAPH
+0xF1A7	0x5DE6	#CJK UNIFIED IDEOGRAPH
+0xF1A8	0x5EA7	#CJK UNIFIED IDEOGRAPH
+0xF1A9	0x632B	#CJK UNIFIED IDEOGRAPH
+0xF1AA	0x7F6A	#CJK UNIFIED IDEOGRAPH
+0xF1AB	0x4E3B	#CJK UNIFIED IDEOGRAPH
+0xF1AC	0x4F4F	#CJK UNIFIED IDEOGRAPH
+0xF1AD	0x4F8F	#CJK UNIFIED IDEOGRAPH
+0xF1AE	0x505A	#CJK UNIFIED IDEOGRAPH
+0xF1AF	0x59DD	#CJK UNIFIED IDEOGRAPH
+0xF1B0	0x80C4	#CJK UNIFIED IDEOGRAPH
+0xF1B1	0x546A	#CJK UNIFIED IDEOGRAPH
+0xF1B2	0x5468	#CJK UNIFIED IDEOGRAPH
+0xF1B3	0x55FE	#CJK UNIFIED IDEOGRAPH
+0xF1B4	0x594F	#CJK UNIFIED IDEOGRAPH
+0xF1B5	0x5B99	#CJK UNIFIED IDEOGRAPH
+0xF1B6	0x5DDE	#CJK UNIFIED IDEOGRAPH
+0xF1B7	0x5EDA	#CJK UNIFIED IDEOGRAPH
+0xF1B8	0x665D	#CJK UNIFIED IDEOGRAPH
+0xF1B9	0x6731	#CJK UNIFIED IDEOGRAPH
+0xF1BA	0x67F1	#CJK UNIFIED IDEOGRAPH
+0xF1BB	0x682A	#CJK UNIFIED IDEOGRAPH
+0xF1BC	0x6CE8	#CJK UNIFIED IDEOGRAPH
+0xF1BD	0x6D32	#CJK UNIFIED IDEOGRAPH
+0xF1BE	0x6E4A	#CJK UNIFIED IDEOGRAPH
+0xF1BF	0x6F8D	#CJK UNIFIED IDEOGRAPH
+0xF1C0	0x70B7	#CJK UNIFIED IDEOGRAPH
+0xF1C1	0x73E0	#CJK UNIFIED IDEOGRAPH
+0xF1C2	0x7587	#CJK UNIFIED IDEOGRAPH
+0xF1C3	0x7C4C	#CJK UNIFIED IDEOGRAPH
+0xF1C4	0x7D02	#CJK UNIFIED IDEOGRAPH
+0xF1C5	0x7D2C	#CJK UNIFIED IDEOGRAPH
+0xF1C6	0x7DA2	#CJK UNIFIED IDEOGRAPH
+0xF1C7	0x821F	#CJK UNIFIED IDEOGRAPH
+0xF1C8	0x86DB	#CJK UNIFIED IDEOGRAPH
+0xF1C9	0x8A3B	#CJK UNIFIED IDEOGRAPH
+0xF1CA	0x8A85	#CJK UNIFIED IDEOGRAPH
+0xF1CB	0x8D70	#CJK UNIFIED IDEOGRAPH
+0xF1CC	0x8E8A	#CJK UNIFIED IDEOGRAPH
+0xF1CD	0x8F33	#CJK UNIFIED IDEOGRAPH
+0xF1CE	0x9031	#CJK UNIFIED IDEOGRAPH
+0xF1CF	0x914E	#CJK UNIFIED IDEOGRAPH
+0xF1D0	0x9152	#CJK UNIFIED IDEOGRAPH
+0xF1D1	0x9444	#CJK UNIFIED IDEOGRAPH
+0xF1D2	0x99D0	#CJK UNIFIED IDEOGRAPH
+0xF1D3	0x7AF9	#CJK UNIFIED IDEOGRAPH
+0xF1D4	0x7CA5	#CJK UNIFIED IDEOGRAPH
+0xF1D5	0x4FCA	#CJK UNIFIED IDEOGRAPH
+0xF1D6	0x5101	#CJK UNIFIED IDEOGRAPH
+0xF1D7	0x51C6	#CJK UNIFIED IDEOGRAPH
+0xF1D8	0x57C8	#CJK UNIFIED IDEOGRAPH
+0xF1D9	0x5BEF	#CJK UNIFIED IDEOGRAPH
+0xF1DA	0x5CFB	#CJK UNIFIED IDEOGRAPH
+0xF1DB	0x6659	#CJK UNIFIED IDEOGRAPH
+0xF1DC	0x6A3D	#CJK UNIFIED IDEOGRAPH
+0xF1DD	0x6D5A	#CJK UNIFIED IDEOGRAPH
+0xF1DE	0x6E96	#CJK UNIFIED IDEOGRAPH
+0xF1DF	0x6FEC	#CJK UNIFIED IDEOGRAPH
+0xF1E0	0x710C	#CJK UNIFIED IDEOGRAPH
+0xF1E1	0x756F	#CJK UNIFIED IDEOGRAPH
+0xF1E2	0x7AE3	#CJK UNIFIED IDEOGRAPH
+0xF1E3	0x8822	#CJK UNIFIED IDEOGRAPH
+0xF1E4	0x9021	#CJK UNIFIED IDEOGRAPH
+0xF1E5	0x9075	#CJK UNIFIED IDEOGRAPH
+0xF1E6	0x96CB	#CJK UNIFIED IDEOGRAPH
+0xF1E7	0x99FF	#CJK UNIFIED IDEOGRAPH
+0xF1E8	0x8301	#CJK UNIFIED IDEOGRAPH
+0xF1E9	0x4E2D	#CJK UNIFIED IDEOGRAPH
+0xF1EA	0x4EF2	#CJK UNIFIED IDEOGRAPH
+0xF1EB	0x8846	#CJK UNIFIED IDEOGRAPH
+0xF1EC	0x91CD	#CJK UNIFIED IDEOGRAPH
+0xF1ED	0x537D	#CJK UNIFIED IDEOGRAPH
+0xF1EE	0x6ADB	#CJK UNIFIED IDEOGRAPH
+0xF1EF	0x696B	#CJK UNIFIED IDEOGRAPH
+0xF1F0	0x6C41	#CJK UNIFIED IDEOGRAPH
+0xF1F1	0x847A	#CJK UNIFIED IDEOGRAPH
+0xF1F2	0x589E	#CJK UNIFIED IDEOGRAPH
+0xF1F3	0x618E	#CJK UNIFIED IDEOGRAPH
+0xF1F4	0x66FE	#CJK UNIFIED IDEOGRAPH
+0xF1F5	0x62EF	#CJK UNIFIED IDEOGRAPH
+0xF1F6	0x70DD	#CJK UNIFIED IDEOGRAPH
+0xF1F7	0x7511	#CJK UNIFIED IDEOGRAPH
+0xF1F8	0x75C7	#CJK UNIFIED IDEOGRAPH
+0xF1F9	0x7E52	#CJK UNIFIED IDEOGRAPH
+0xF1FA	0x84B8	#CJK UNIFIED IDEOGRAPH
+0xF1FB	0x8B49	#CJK UNIFIED IDEOGRAPH
+0xF1FC	0x8D08	#CJK UNIFIED IDEOGRAPH
+0xF1FD	0x4E4B	#CJK UNIFIED IDEOGRAPH
+0xF1FE	0x53EA	#CJK UNIFIED IDEOGRAPH
+0xF2A1	0x54AB	#CJK UNIFIED IDEOGRAPH
+0xF2A2	0x5730	#CJK UNIFIED IDEOGRAPH
+0xF2A3	0x5740	#CJK UNIFIED IDEOGRAPH
+0xF2A4	0x5FD7	#CJK UNIFIED IDEOGRAPH
+0xF2A5	0x6301	#CJK UNIFIED IDEOGRAPH
+0xF2A6	0x6307	#CJK UNIFIED IDEOGRAPH
+0xF2A7	0x646F	#CJK UNIFIED IDEOGRAPH
+0xF2A8	0x652F	#CJK UNIFIED IDEOGRAPH
+0xF2A9	0x65E8	#CJK UNIFIED IDEOGRAPH
+0xF2AA	0x667A	#CJK UNIFIED IDEOGRAPH
+0xF2AB	0x679D	#CJK UNIFIED IDEOGRAPH
+0xF2AC	0x67B3	#CJK UNIFIED IDEOGRAPH
+0xF2AD	0x6B62	#CJK UNIFIED IDEOGRAPH
+0xF2AE	0x6C60	#CJK UNIFIED IDEOGRAPH
+0xF2AF	0x6C9A	#CJK UNIFIED IDEOGRAPH
+0xF2B0	0x6F2C	#CJK UNIFIED IDEOGRAPH
+0xF2B1	0x77E5	#CJK UNIFIED IDEOGRAPH
+0xF2B2	0x7825	#CJK UNIFIED IDEOGRAPH
+0xF2B3	0x7949	#CJK UNIFIED IDEOGRAPH
+0xF2B4	0x7957	#CJK UNIFIED IDEOGRAPH
+0xF2B5	0x7D19	#CJK UNIFIED IDEOGRAPH
+0xF2B6	0x80A2	#CJK UNIFIED IDEOGRAPH
+0xF2B7	0x8102	#CJK UNIFIED IDEOGRAPH
+0xF2B8	0x81F3	#CJK UNIFIED IDEOGRAPH
+0xF2B9	0x829D	#CJK UNIFIED IDEOGRAPH
+0xF2BA	0x82B7	#CJK UNIFIED IDEOGRAPH
+0xF2BB	0x8718	#CJK UNIFIED IDEOGRAPH
+0xF2BC	0x8A8C	#CJK UNIFIED IDEOGRAPH
+0xF2BD	0xF9FC	#CJK COMPATIBILITY IDEOGRAPH
+0xF2BE	0x8D04	#CJK UNIFIED IDEOGRAPH
+0xF2BF	0x8DBE	#CJK UNIFIED IDEOGRAPH
+0xF2C0	0x9072	#CJK UNIFIED IDEOGRAPH
+0xF2C1	0x76F4	#CJK UNIFIED IDEOGRAPH
+0xF2C2	0x7A19	#CJK UNIFIED IDEOGRAPH
+0xF2C3	0x7A37	#CJK UNIFIED IDEOGRAPH
+0xF2C4	0x7E54	#CJK UNIFIED IDEOGRAPH
+0xF2C5	0x8077	#CJK UNIFIED IDEOGRAPH
+0xF2C6	0x5507	#CJK UNIFIED IDEOGRAPH
+0xF2C7	0x55D4	#CJK UNIFIED IDEOGRAPH
+0xF2C8	0x5875	#CJK UNIFIED IDEOGRAPH
+0xF2C9	0x632F	#CJK UNIFIED IDEOGRAPH
+0xF2CA	0x6422	#CJK UNIFIED IDEOGRAPH
+0xF2CB	0x6649	#CJK UNIFIED IDEOGRAPH
+0xF2CC	0x664B	#CJK UNIFIED IDEOGRAPH
+0xF2CD	0x686D	#CJK UNIFIED IDEOGRAPH
+0xF2CE	0x699B	#CJK UNIFIED IDEOGRAPH
+0xF2CF	0x6B84	#CJK UNIFIED IDEOGRAPH
+0xF2D0	0x6D25	#CJK UNIFIED IDEOGRAPH
+0xF2D1	0x6EB1	#CJK UNIFIED IDEOGRAPH
+0xF2D2	0x73CD	#CJK UNIFIED IDEOGRAPH
+0xF2D3	0x7468	#CJK UNIFIED IDEOGRAPH
+0xF2D4	0x74A1	#CJK UNIFIED IDEOGRAPH
+0xF2D5	0x755B	#CJK UNIFIED IDEOGRAPH
+0xF2D6	0x75B9	#CJK UNIFIED IDEOGRAPH
+0xF2D7	0x76E1	#CJK UNIFIED IDEOGRAPH
+0xF2D8	0x771E	#CJK UNIFIED IDEOGRAPH
+0xF2D9	0x778B	#CJK UNIFIED IDEOGRAPH
+0xF2DA	0x79E6	#CJK UNIFIED IDEOGRAPH
+0xF2DB	0x7E09	#CJK UNIFIED IDEOGRAPH
+0xF2DC	0x7E1D	#CJK UNIFIED IDEOGRAPH
+0xF2DD	0x81FB	#CJK UNIFIED IDEOGRAPH
+0xF2DE	0x852F	#CJK UNIFIED IDEOGRAPH
+0xF2DF	0x8897	#CJK UNIFIED IDEOGRAPH
+0xF2E0	0x8A3A	#CJK UNIFIED IDEOGRAPH
+0xF2E1	0x8CD1	#CJK UNIFIED IDEOGRAPH
+0xF2E2	0x8EEB	#CJK UNIFIED IDEOGRAPH
+0xF2E3	0x8FB0	#CJK UNIFIED IDEOGRAPH
+0xF2E4	0x9032	#CJK UNIFIED IDEOGRAPH
+0xF2E5	0x93AD	#CJK UNIFIED IDEOGRAPH
+0xF2E6	0x9663	#CJK UNIFIED IDEOGRAPH
+0xF2E7	0x9673	#CJK UNIFIED IDEOGRAPH
+0xF2E8	0x9707	#CJK UNIFIED IDEOGRAPH
+0xF2E9	0x4F84	#CJK UNIFIED IDEOGRAPH
+0xF2EA	0x53F1	#CJK UNIFIED IDEOGRAPH
+0xF2EB	0x59EA	#CJK UNIFIED IDEOGRAPH
+0xF2EC	0x5AC9	#CJK UNIFIED IDEOGRAPH
+0xF2ED	0x5E19	#CJK UNIFIED IDEOGRAPH
+0xF2EE	0x684E	#CJK UNIFIED IDEOGRAPH
+0xF2EF	0x74C6	#CJK UNIFIED IDEOGRAPH
+0xF2F0	0x75BE	#CJK UNIFIED IDEOGRAPH
+0xF2F1	0x79E9	#CJK UNIFIED IDEOGRAPH
+0xF2F2	0x7A92	#CJK UNIFIED IDEOGRAPH
+0xF2F3	0x81A3	#CJK UNIFIED IDEOGRAPH
+0xF2F4	0x86ED	#CJK UNIFIED IDEOGRAPH
+0xF2F5	0x8CEA	#CJK UNIFIED IDEOGRAPH
+0xF2F6	0x8DCC	#CJK UNIFIED IDEOGRAPH
+0xF2F7	0x8FED	#CJK UNIFIED IDEOGRAPH
+0xF2F8	0x659F	#CJK UNIFIED IDEOGRAPH
+0xF2F9	0x6715	#CJK UNIFIED IDEOGRAPH
+0xF2FA	0xF9FD	#CJK COMPATIBILITY IDEOGRAPH
+0xF2FB	0x57F7	#CJK UNIFIED IDEOGRAPH
+0xF2FC	0x6F57	#CJK UNIFIED IDEOGRAPH
+0xF2FD	0x7DDD	#CJK UNIFIED IDEOGRAPH
+0xF2FE	0x8F2F	#CJK UNIFIED IDEOGRAPH
+0xF3A1	0x93F6	#CJK UNIFIED IDEOGRAPH
+0xF3A2	0x96C6	#CJK UNIFIED IDEOGRAPH
+0xF3A3	0x5FB5	#CJK UNIFIED IDEOGRAPH
+0xF3A4	0x61F2	#CJK UNIFIED IDEOGRAPH
+0xF3A5	0x6F84	#CJK UNIFIED IDEOGRAPH
+0xF3A6	0x4E14	#CJK UNIFIED IDEOGRAPH
+0xF3A7	0x4F98	#CJK UNIFIED IDEOGRAPH
+0xF3A8	0x501F	#CJK UNIFIED IDEOGRAPH
+0xF3A9	0x53C9	#CJK UNIFIED IDEOGRAPH
+0xF3AA	0x55DF	#CJK UNIFIED IDEOGRAPH
+0xF3AB	0x5D6F	#CJK UNIFIED IDEOGRAPH
+0xF3AC	0x5DEE	#CJK UNIFIED IDEOGRAPH
+0xF3AD	0x6B21	#CJK UNIFIED IDEOGRAPH
+0xF3AE	0x6B64	#CJK UNIFIED IDEOGRAPH
+0xF3AF	0x78CB	#CJK UNIFIED IDEOGRAPH
+0xF3B0	0x7B9A	#CJK UNIFIED IDEOGRAPH
+0xF3B1	0xF9FE	#CJK COMPATIBILITY IDEOGRAPH
+0xF3B2	0x8E49	#CJK UNIFIED IDEOGRAPH
+0xF3B3	0x8ECA	#CJK UNIFIED IDEOGRAPH
+0xF3B4	0x906E	#CJK UNIFIED IDEOGRAPH
+0xF3B5	0x6349	#CJK UNIFIED IDEOGRAPH
+0xF3B6	0x643E	#CJK UNIFIED IDEOGRAPH
+0xF3B7	0x7740	#CJK UNIFIED IDEOGRAPH
+0xF3B8	0x7A84	#CJK UNIFIED IDEOGRAPH
+0xF3B9	0x932F	#CJK UNIFIED IDEOGRAPH
+0xF3BA	0x947F	#CJK UNIFIED IDEOGRAPH
+0xF3BB	0x9F6A	#CJK UNIFIED IDEOGRAPH
+0xF3BC	0x64B0	#CJK UNIFIED IDEOGRAPH
+0xF3BD	0x6FAF	#CJK UNIFIED IDEOGRAPH
+0xF3BE	0x71E6	#CJK UNIFIED IDEOGRAPH
+0xF3BF	0x74A8	#CJK UNIFIED IDEOGRAPH
+0xF3C0	0x74DA	#CJK UNIFIED IDEOGRAPH
+0xF3C1	0x7AC4	#CJK UNIFIED IDEOGRAPH
+0xF3C2	0x7C12	#CJK UNIFIED IDEOGRAPH
+0xF3C3	0x7E82	#CJK UNIFIED IDEOGRAPH
+0xF3C4	0x7CB2	#CJK UNIFIED IDEOGRAPH
+0xF3C5	0x7E98	#CJK UNIFIED IDEOGRAPH
+0xF3C6	0x8B9A	#CJK UNIFIED IDEOGRAPH
+0xF3C7	0x8D0A	#CJK UNIFIED IDEOGRAPH
+0xF3C8	0x947D	#CJK UNIFIED IDEOGRAPH
+0xF3C9	0x9910	#CJK UNIFIED IDEOGRAPH
+0xF3CA	0x994C	#CJK UNIFIED IDEOGRAPH
+0xF3CB	0x5239	#CJK UNIFIED IDEOGRAPH
+0xF3CC	0x5BDF	#CJK UNIFIED IDEOGRAPH
+0xF3CD	0x64E6	#CJK UNIFIED IDEOGRAPH
+0xF3CE	0x672D	#CJK UNIFIED IDEOGRAPH
+0xF3CF	0x7D2E	#CJK UNIFIED IDEOGRAPH
+0xF3D0	0x50ED	#CJK UNIFIED IDEOGRAPH
+0xF3D1	0x53C3	#CJK UNIFIED IDEOGRAPH
+0xF3D2	0x5879	#CJK UNIFIED IDEOGRAPH
+0xF3D3	0x6158	#CJK UNIFIED IDEOGRAPH
+0xF3D4	0x6159	#CJK UNIFIED IDEOGRAPH
+0xF3D5	0x61FA	#CJK UNIFIED IDEOGRAPH
+0xF3D6	0x65AC	#CJK UNIFIED IDEOGRAPH
+0xF3D7	0x7AD9	#CJK UNIFIED IDEOGRAPH
+0xF3D8	0x8B92	#CJK UNIFIED IDEOGRAPH
+0xF3D9	0x8B96	#CJK UNIFIED IDEOGRAPH
+0xF3DA	0x5009	#CJK UNIFIED IDEOGRAPH
+0xF3DB	0x5021	#CJK UNIFIED IDEOGRAPH
+0xF3DC	0x5275	#CJK UNIFIED IDEOGRAPH
+0xF3DD	0x5531	#CJK UNIFIED IDEOGRAPH
+0xF3DE	0x5A3C	#CJK UNIFIED IDEOGRAPH
+0xF3DF	0x5EE0	#CJK UNIFIED IDEOGRAPH
+0xF3E0	0x5F70	#CJK UNIFIED IDEOGRAPH
+0xF3E1	0x6134	#CJK UNIFIED IDEOGRAPH
+0xF3E2	0x655E	#CJK UNIFIED IDEOGRAPH
+0xF3E3	0x660C	#CJK UNIFIED IDEOGRAPH
+0xF3E4	0x6636	#CJK UNIFIED IDEOGRAPH
+0xF3E5	0x66A2	#CJK UNIFIED IDEOGRAPH
+0xF3E6	0x69CD	#CJK UNIFIED IDEOGRAPH
+0xF3E7	0x6EC4	#CJK UNIFIED IDEOGRAPH
+0xF3E8	0x6F32	#CJK UNIFIED IDEOGRAPH
+0xF3E9	0x7316	#CJK UNIFIED IDEOGRAPH
+0xF3EA	0x7621	#CJK UNIFIED IDEOGRAPH
+0xF3EB	0x7A93	#CJK UNIFIED IDEOGRAPH
+0xF3EC	0x8139	#CJK UNIFIED IDEOGRAPH
+0xF3ED	0x8259	#CJK UNIFIED IDEOGRAPH
+0xF3EE	0x83D6	#CJK UNIFIED IDEOGRAPH
+0xF3EF	0x84BC	#CJK UNIFIED IDEOGRAPH
+0xF3F0	0x50B5	#CJK UNIFIED IDEOGRAPH
+0xF3F1	0x57F0	#CJK UNIFIED IDEOGRAPH
+0xF3F2	0x5BC0	#CJK UNIFIED IDEOGRAPH
+0xF3F3	0x5BE8	#CJK UNIFIED IDEOGRAPH
+0xF3F4	0x5F69	#CJK UNIFIED IDEOGRAPH
+0xF3F5	0x63A1	#CJK UNIFIED IDEOGRAPH
+0xF3F6	0x7826	#CJK UNIFIED IDEOGRAPH
+0xF3F7	0x7DB5	#CJK UNIFIED IDEOGRAPH
+0xF3F8	0x83DC	#CJK UNIFIED IDEOGRAPH
+0xF3F9	0x8521	#CJK UNIFIED IDEOGRAPH
+0xF3FA	0x91C7	#CJK UNIFIED IDEOGRAPH
+0xF3FB	0x91F5	#CJK UNIFIED IDEOGRAPH
+0xF3FC	0x518A	#CJK UNIFIED IDEOGRAPH
+0xF3FD	0x67F5	#CJK UNIFIED IDEOGRAPH
+0xF3FE	0x7B56	#CJK UNIFIED IDEOGRAPH
+0xF4A1	0x8CAC	#CJK UNIFIED IDEOGRAPH
+0xF4A2	0x51C4	#CJK UNIFIED IDEOGRAPH
+0xF4A3	0x59BB	#CJK UNIFIED IDEOGRAPH
+0xF4A4	0x60BD	#CJK UNIFIED IDEOGRAPH
+0xF4A5	0x8655	#CJK UNIFIED IDEOGRAPH
+0xF4A6	0x501C	#CJK UNIFIED IDEOGRAPH
+0xF4A7	0xF9FF	#CJK COMPATIBILITY IDEOGRAPH
+0xF4A8	0x5254	#CJK UNIFIED IDEOGRAPH
+0xF4A9	0x5C3A	#CJK UNIFIED IDEOGRAPH
+0xF4AA	0x617D	#CJK UNIFIED IDEOGRAPH
+0xF4AB	0x621A	#CJK UNIFIED IDEOGRAPH
+0xF4AC	0x62D3	#CJK UNIFIED IDEOGRAPH
+0xF4AD	0x64F2	#CJK UNIFIED IDEOGRAPH
+0xF4AE	0x65A5	#CJK UNIFIED IDEOGRAPH
+0xF4AF	0x6ECC	#CJK UNIFIED IDEOGRAPH
+0xF4B0	0x7620	#CJK UNIFIED IDEOGRAPH
+0xF4B1	0x810A	#CJK UNIFIED IDEOGRAPH
+0xF4B2	0x8E60	#CJK UNIFIED IDEOGRAPH
+0xF4B3	0x965F	#CJK UNIFIED IDEOGRAPH
+0xF4B4	0x96BB	#CJK UNIFIED IDEOGRAPH
+0xF4B5	0x4EDF	#CJK UNIFIED IDEOGRAPH
+0xF4B6	0x5343	#CJK UNIFIED IDEOGRAPH
+0xF4B7	0x5598	#CJK UNIFIED IDEOGRAPH
+0xF4B8	0x5929	#CJK UNIFIED IDEOGRAPH
+0xF4B9	0x5DDD	#CJK UNIFIED IDEOGRAPH
+0xF4BA	0x64C5	#CJK UNIFIED IDEOGRAPH
+0xF4BB	0x6CC9	#CJK UNIFIED IDEOGRAPH
+0xF4BC	0x6DFA	#CJK UNIFIED IDEOGRAPH
+0xF4BD	0x7394	#CJK UNIFIED IDEOGRAPH
+0xF4BE	0x7A7F	#CJK UNIFIED IDEOGRAPH
+0xF4BF	0x821B	#CJK UNIFIED IDEOGRAPH
+0xF4C0	0x85A6	#CJK UNIFIED IDEOGRAPH
+0xF4C1	0x8CE4	#CJK UNIFIED IDEOGRAPH
+0xF4C2	0x8E10	#CJK UNIFIED IDEOGRAPH
+0xF4C3	0x9077	#CJK UNIFIED IDEOGRAPH
+0xF4C4	0x91E7	#CJK UNIFIED IDEOGRAPH
+0xF4C5	0x95E1	#CJK UNIFIED IDEOGRAPH
+0xF4C6	0x9621	#CJK UNIFIED IDEOGRAPH
+0xF4C7	0x97C6	#CJK UNIFIED IDEOGRAPH
+0xF4C8	0x51F8	#CJK UNIFIED IDEOGRAPH
+0xF4C9	0x54F2	#CJK UNIFIED IDEOGRAPH
+0xF4CA	0x5586	#CJK UNIFIED IDEOGRAPH
+0xF4CB	0x5FB9	#CJK UNIFIED IDEOGRAPH
+0xF4CC	0x64A4	#CJK UNIFIED IDEOGRAPH
+0xF4CD	0x6F88	#CJK UNIFIED IDEOGRAPH
+0xF4CE	0x7DB4	#CJK UNIFIED IDEOGRAPH
+0xF4CF	0x8F1F	#CJK UNIFIED IDEOGRAPH
+0xF4D0	0x8F4D	#CJK UNIFIED IDEOGRAPH
+0xF4D1	0x9435	#CJK UNIFIED IDEOGRAPH
+0xF4D2	0x50C9	#CJK UNIFIED IDEOGRAPH
+0xF4D3	0x5C16	#CJK UNIFIED IDEOGRAPH
+0xF4D4	0x6CBE	#CJK UNIFIED IDEOGRAPH
+0xF4D5	0x6DFB	#CJK UNIFIED IDEOGRAPH
+0xF4D6	0x751B	#CJK UNIFIED IDEOGRAPH
+0xF4D7	0x77BB	#CJK UNIFIED IDEOGRAPH
+0xF4D8	0x7C3D	#CJK UNIFIED IDEOGRAPH
+0xF4D9	0x7C64	#CJK UNIFIED IDEOGRAPH
+0xF4DA	0x8A79	#CJK UNIFIED IDEOGRAPH
+0xF4DB	0x8AC2	#CJK UNIFIED IDEOGRAPH
+0xF4DC	0x581E	#CJK UNIFIED IDEOGRAPH
+0xF4DD	0x59BE	#CJK UNIFIED IDEOGRAPH
+0xF4DE	0x5E16	#CJK UNIFIED IDEOGRAPH
+0xF4DF	0x6377	#CJK UNIFIED IDEOGRAPH
+0xF4E0	0x7252	#CJK UNIFIED IDEOGRAPH
+0xF4E1	0x758A	#CJK UNIFIED IDEOGRAPH
+0xF4E2	0x776B	#CJK UNIFIED IDEOGRAPH
+0xF4E3	0x8ADC	#CJK UNIFIED IDEOGRAPH
+0xF4E4	0x8CBC	#CJK UNIFIED IDEOGRAPH
+0xF4E5	0x8F12	#CJK UNIFIED IDEOGRAPH
+0xF4E6	0x5EF3	#CJK UNIFIED IDEOGRAPH
+0xF4E7	0x6674	#CJK UNIFIED IDEOGRAPH
+0xF4E8	0x6DF8	#CJK UNIFIED IDEOGRAPH
+0xF4E9	0x807D	#CJK UNIFIED IDEOGRAPH
+0xF4EA	0x83C1	#CJK UNIFIED IDEOGRAPH
+0xF4EB	0x8ACB	#CJK UNIFIED IDEOGRAPH
+0xF4EC	0x9751	#CJK UNIFIED IDEOGRAPH
+0xF4ED	0x9BD6	#CJK UNIFIED IDEOGRAPH
+0xF4EE	0xFA00	#CJK COMPATIBILITY IDEOGRAPH
+0xF4EF	0x5243	#CJK UNIFIED IDEOGRAPH
+0xF4F0	0x66FF	#CJK UNIFIED IDEOGRAPH
+0xF4F1	0x6D95	#CJK UNIFIED IDEOGRAPH
+0xF4F2	0x6EEF	#CJK UNIFIED IDEOGRAPH
+0xF4F3	0x7DE0	#CJK UNIFIED IDEOGRAPH
+0xF4F4	0x8AE6	#CJK UNIFIED IDEOGRAPH
+0xF4F5	0x902E	#CJK UNIFIED IDEOGRAPH
+0xF4F6	0x905E	#CJK UNIFIED IDEOGRAPH
+0xF4F7	0x9AD4	#CJK UNIFIED IDEOGRAPH
+0xF4F8	0x521D	#CJK UNIFIED IDEOGRAPH
+0xF4F9	0x527F	#CJK UNIFIED IDEOGRAPH
+0xF4FA	0x54E8	#CJK UNIFIED IDEOGRAPH
+0xF4FB	0x6194	#CJK UNIFIED IDEOGRAPH
+0xF4FC	0x6284	#CJK UNIFIED IDEOGRAPH
+0xF4FD	0x62DB	#CJK UNIFIED IDEOGRAPH
+0xF4FE	0x68A2	#CJK UNIFIED IDEOGRAPH
+0xF5A1	0x6912	#CJK UNIFIED IDEOGRAPH
+0xF5A2	0x695A	#CJK UNIFIED IDEOGRAPH
+0xF5A3	0x6A35	#CJK UNIFIED IDEOGRAPH
+0xF5A4	0x7092	#CJK UNIFIED IDEOGRAPH
+0xF5A5	0x7126	#CJK UNIFIED IDEOGRAPH
+0xF5A6	0x785D	#CJK UNIFIED IDEOGRAPH
+0xF5A7	0x7901	#CJK UNIFIED IDEOGRAPH
+0xF5A8	0x790E	#CJK UNIFIED IDEOGRAPH
+0xF5A9	0x79D2	#CJK UNIFIED IDEOGRAPH
+0xF5AA	0x7A0D	#CJK UNIFIED IDEOGRAPH
+0xF5AB	0x8096	#CJK UNIFIED IDEOGRAPH
+0xF5AC	0x8278	#CJK UNIFIED IDEOGRAPH
+0xF5AD	0x82D5	#CJK UNIFIED IDEOGRAPH
+0xF5AE	0x8349	#CJK UNIFIED IDEOGRAPH
+0xF5AF	0x8549	#CJK UNIFIED IDEOGRAPH
+0xF5B0	0x8C82	#CJK UNIFIED IDEOGRAPH
+0xF5B1	0x8D85	#CJK UNIFIED IDEOGRAPH
+0xF5B2	0x9162	#CJK UNIFIED IDEOGRAPH
+0xF5B3	0x918B	#CJK UNIFIED IDEOGRAPH
+0xF5B4	0x91AE	#CJK UNIFIED IDEOGRAPH
+0xF5B5	0x4FC3	#CJK UNIFIED IDEOGRAPH
+0xF5B6	0x56D1	#CJK UNIFIED IDEOGRAPH
+0xF5B7	0x71ED	#CJK UNIFIED IDEOGRAPH
+0xF5B8	0x77D7	#CJK UNIFIED IDEOGRAPH
+0xF5B9	0x8700	#CJK UNIFIED IDEOGRAPH
+0xF5BA	0x89F8	#CJK UNIFIED IDEOGRAPH
+0xF5BB	0x5BF8	#CJK UNIFIED IDEOGRAPH
+0xF5BC	0x5FD6	#CJK UNIFIED IDEOGRAPH
+0xF5BD	0x6751	#CJK UNIFIED IDEOGRAPH
+0xF5BE	0x90A8	#CJK UNIFIED IDEOGRAPH
+0xF5BF	0x53E2	#CJK UNIFIED IDEOGRAPH
+0xF5C0	0x585A	#CJK UNIFIED IDEOGRAPH
+0xF5C1	0x5BF5	#CJK UNIFIED IDEOGRAPH
+0xF5C2	0x60A4	#CJK UNIFIED IDEOGRAPH
+0xF5C3	0x6181	#CJK UNIFIED IDEOGRAPH
+0xF5C4	0x6460	#CJK UNIFIED IDEOGRAPH
+0xF5C5	0x7E3D	#CJK UNIFIED IDEOGRAPH
+0xF5C6	0x8070	#CJK UNIFIED IDEOGRAPH
+0xF5C7	0x8525	#CJK UNIFIED IDEOGRAPH
+0xF5C8	0x9283	#CJK UNIFIED IDEOGRAPH
+0xF5C9	0x64AE	#CJK UNIFIED IDEOGRAPH
+0xF5CA	0x50AC	#CJK UNIFIED IDEOGRAPH
+0xF5CB	0x5D14	#CJK UNIFIED IDEOGRAPH
+0xF5CC	0x6700	#CJK UNIFIED IDEOGRAPH
+0xF5CD	0x589C	#CJK UNIFIED IDEOGRAPH
+0xF5CE	0x62BD	#CJK UNIFIED IDEOGRAPH
+0xF5CF	0x63A8	#CJK UNIFIED IDEOGRAPH
+0xF5D0	0x690E	#CJK UNIFIED IDEOGRAPH
+0xF5D1	0x6978	#CJK UNIFIED IDEOGRAPH
+0xF5D2	0x6A1E	#CJK UNIFIED IDEOGRAPH
+0xF5D3	0x6E6B	#CJK UNIFIED IDEOGRAPH
+0xF5D4	0x76BA	#CJK UNIFIED IDEOGRAPH
+0xF5D5	0x79CB	#CJK UNIFIED IDEOGRAPH
+0xF5D6	0x82BB	#CJK UNIFIED IDEOGRAPH
+0xF5D7	0x8429	#CJK UNIFIED IDEOGRAPH
+0xF5D8	0x8ACF	#CJK UNIFIED IDEOGRAPH
+0xF5D9	0x8DA8	#CJK UNIFIED IDEOGRAPH
+0xF5DA	0x8FFD	#CJK UNIFIED IDEOGRAPH
+0xF5DB	0x9112	#CJK UNIFIED IDEOGRAPH
+0xF5DC	0x914B	#CJK UNIFIED IDEOGRAPH
+0xF5DD	0x919C	#CJK UNIFIED IDEOGRAPH
+0xF5DE	0x9310	#CJK UNIFIED IDEOGRAPH
+0xF5DF	0x9318	#CJK UNIFIED IDEOGRAPH
+0xF5E0	0x939A	#CJK UNIFIED IDEOGRAPH
+0xF5E1	0x96DB	#CJK UNIFIED IDEOGRAPH
+0xF5E2	0x9A36	#CJK UNIFIED IDEOGRAPH
+0xF5E3	0x9C0D	#CJK UNIFIED IDEOGRAPH
+0xF5E4	0x4E11	#CJK UNIFIED IDEOGRAPH
+0xF5E5	0x755C	#CJK UNIFIED IDEOGRAPH
+0xF5E6	0x795D	#CJK UNIFIED IDEOGRAPH
+0xF5E7	0x7AFA	#CJK UNIFIED IDEOGRAPH
+0xF5E8	0x7B51	#CJK UNIFIED IDEOGRAPH
+0xF5E9	0x7BC9	#CJK UNIFIED IDEOGRAPH
+0xF5EA	0x7E2E	#CJK UNIFIED IDEOGRAPH
+0xF5EB	0x84C4	#CJK UNIFIED IDEOGRAPH
+0xF5EC	0x8E59	#CJK UNIFIED IDEOGRAPH
+0xF5ED	0x8E74	#CJK UNIFIED IDEOGRAPH
+0xF5EE	0x8EF8	#CJK UNIFIED IDEOGRAPH
+0xF5EF	0x9010	#CJK UNIFIED IDEOGRAPH
+0xF5F0	0x6625	#CJK UNIFIED IDEOGRAPH
+0xF5F1	0x693F	#CJK UNIFIED IDEOGRAPH
+0xF5F2	0x7443	#CJK UNIFIED IDEOGRAPH
+0xF5F3	0x51FA	#CJK UNIFIED IDEOGRAPH
+0xF5F4	0x672E	#CJK UNIFIED IDEOGRAPH
+0xF5F5	0x9EDC	#CJK UNIFIED IDEOGRAPH
+0xF5F6	0x5145	#CJK UNIFIED IDEOGRAPH
+0xF5F7	0x5FE0	#CJK UNIFIED IDEOGRAPH
+0xF5F8	0x6C96	#CJK UNIFIED IDEOGRAPH
+0xF5F9	0x87F2	#CJK UNIFIED IDEOGRAPH
+0xF5FA	0x885D	#CJK UNIFIED IDEOGRAPH
+0xF5FB	0x8877	#CJK UNIFIED IDEOGRAPH
+0xF5FC	0x60B4	#CJK UNIFIED IDEOGRAPH
+0xF5FD	0x81B5	#CJK UNIFIED IDEOGRAPH
+0xF5FE	0x8403	#CJK UNIFIED IDEOGRAPH
+0xF6A1	0x8D05	#CJK UNIFIED IDEOGRAPH
+0xF6A2	0x53D6	#CJK UNIFIED IDEOGRAPH
+0xF6A3	0x5439	#CJK UNIFIED IDEOGRAPH
+0xF6A4	0x5634	#CJK UNIFIED IDEOGRAPH
+0xF6A5	0x5A36	#CJK UNIFIED IDEOGRAPH
+0xF6A6	0x5C31	#CJK UNIFIED IDEOGRAPH
+0xF6A7	0x708A	#CJK UNIFIED IDEOGRAPH
+0xF6A8	0x7FE0	#CJK UNIFIED IDEOGRAPH
+0xF6A9	0x805A	#CJK UNIFIED IDEOGRAPH
+0xF6AA	0x8106	#CJK UNIFIED IDEOGRAPH
+0xF6AB	0x81ED	#CJK UNIFIED IDEOGRAPH
+0xF6AC	0x8DA3	#CJK UNIFIED IDEOGRAPH
+0xF6AD	0x9189	#CJK UNIFIED IDEOGRAPH
+0xF6AE	0x9A5F	#CJK UNIFIED IDEOGRAPH
+0xF6AF	0x9DF2	#CJK UNIFIED IDEOGRAPH
+0xF6B0	0x5074	#CJK UNIFIED IDEOGRAPH
+0xF6B1	0x4EC4	#CJK UNIFIED IDEOGRAPH
+0xF6B2	0x53A0	#CJK UNIFIED IDEOGRAPH
+0xF6B3	0x60FB	#CJK UNIFIED IDEOGRAPH
+0xF6B4	0x6E2C	#CJK UNIFIED IDEOGRAPH
+0xF6B5	0x5C64	#CJK UNIFIED IDEOGRAPH
+0xF6B6	0x4F88	#CJK UNIFIED IDEOGRAPH
+0xF6B7	0x5024	#CJK UNIFIED IDEOGRAPH
+0xF6B8	0x55E4	#CJK UNIFIED IDEOGRAPH
+0xF6B9	0x5CD9	#CJK UNIFIED IDEOGRAPH
+0xF6BA	0x5E5F	#CJK UNIFIED IDEOGRAPH
+0xF6BB	0x6065	#CJK UNIFIED IDEOGRAPH
+0xF6BC	0x6894	#CJK UNIFIED IDEOGRAPH
+0xF6BD	0x6CBB	#CJK UNIFIED IDEOGRAPH
+0xF6BE	0x6DC4	#CJK UNIFIED IDEOGRAPH
+0xF6BF	0x71BE	#CJK UNIFIED IDEOGRAPH
+0xF6C0	0x75D4	#CJK UNIFIED IDEOGRAPH
+0xF6C1	0x75F4	#CJK UNIFIED IDEOGRAPH
+0xF6C2	0x7661	#CJK UNIFIED IDEOGRAPH
+0xF6C3	0x7A1A	#CJK UNIFIED IDEOGRAPH
+0xF6C4	0x7A49	#CJK UNIFIED IDEOGRAPH
+0xF6C5	0x7DC7	#CJK UNIFIED IDEOGRAPH
+0xF6C6	0x7DFB	#CJK UNIFIED IDEOGRAPH
+0xF6C7	0x7F6E	#CJK UNIFIED IDEOGRAPH
+0xF6C8	0x81F4	#CJK UNIFIED IDEOGRAPH
+0xF6C9	0x86A9	#CJK UNIFIED IDEOGRAPH
+0xF6CA	0x8F1C	#CJK UNIFIED IDEOGRAPH
+0xF6CB	0x96C9	#CJK UNIFIED IDEOGRAPH
+0xF6CC	0x99B3	#CJK UNIFIED IDEOGRAPH
+0xF6CD	0x9F52	#CJK UNIFIED IDEOGRAPH
+0xF6CE	0x5247	#CJK UNIFIED IDEOGRAPH
+0xF6CF	0x52C5	#CJK UNIFIED IDEOGRAPH
+0xF6D0	0x98ED	#CJK UNIFIED IDEOGRAPH
+0xF6D1	0x89AA	#CJK UNIFIED IDEOGRAPH
+0xF6D2	0x4E03	#CJK UNIFIED IDEOGRAPH
+0xF6D3	0x67D2	#CJK UNIFIED IDEOGRAPH
+0xF6D4	0x6F06	#CJK UNIFIED IDEOGRAPH
+0xF6D5	0x4FB5	#CJK UNIFIED IDEOGRAPH
+0xF6D6	0x5BE2	#CJK UNIFIED IDEOGRAPH
+0xF6D7	0x6795	#CJK UNIFIED IDEOGRAPH
+0xF6D8	0x6C88	#CJK UNIFIED IDEOGRAPH
+0xF6D9	0x6D78	#CJK UNIFIED IDEOGRAPH
+0xF6DA	0x741B	#CJK UNIFIED IDEOGRAPH
+0xF6DB	0x7827	#CJK UNIFIED IDEOGRAPH
+0xF6DC	0x91DD	#CJK UNIFIED IDEOGRAPH
+0xF6DD	0x937C	#CJK UNIFIED IDEOGRAPH
+0xF6DE	0x87C4	#CJK UNIFIED IDEOGRAPH
+0xF6DF	0x79E4	#CJK UNIFIED IDEOGRAPH
+0xF6E0	0x7A31	#CJK UNIFIED IDEOGRAPH
+0xF6E1	0x5FEB	#CJK UNIFIED IDEOGRAPH
+0xF6E2	0x4ED6	#CJK UNIFIED IDEOGRAPH
+0xF6E3	0x54A4	#CJK UNIFIED IDEOGRAPH
+0xF6E4	0x553E	#CJK UNIFIED IDEOGRAPH
+0xF6E5	0x58AE	#CJK UNIFIED IDEOGRAPH
+0xF6E6	0x59A5	#CJK UNIFIED IDEOGRAPH
+0xF6E7	0x60F0	#CJK UNIFIED IDEOGRAPH
+0xF6E8	0x6253	#CJK UNIFIED IDEOGRAPH
+0xF6E9	0x62D6	#CJK UNIFIED IDEOGRAPH
+0xF6EA	0x6736	#CJK UNIFIED IDEOGRAPH
+0xF6EB	0x6955	#CJK UNIFIED IDEOGRAPH
+0xF6EC	0x8235	#CJK UNIFIED IDEOGRAPH
+0xF6ED	0x9640	#CJK UNIFIED IDEOGRAPH
+0xF6EE	0x99B1	#CJK UNIFIED IDEOGRAPH
+0xF6EF	0x99DD	#CJK UNIFIED IDEOGRAPH
+0xF6F0	0x502C	#CJK UNIFIED IDEOGRAPH
+0xF6F1	0x5353	#CJK UNIFIED IDEOGRAPH
+0xF6F2	0x5544	#CJK UNIFIED IDEOGRAPH
+0xF6F3	0x577C	#CJK UNIFIED IDEOGRAPH
+0xF6F4	0xFA01	#CJK COMPATIBILITY IDEOGRAPH
+0xF6F5	0x6258	#CJK UNIFIED IDEOGRAPH
+0xF6F6	0xFA02	#CJK COMPATIBILITY IDEOGRAPH
+0xF6F7	0x64E2	#CJK UNIFIED IDEOGRAPH
+0xF6F8	0x666B	#CJK UNIFIED IDEOGRAPH
+0xF6F9	0x67DD	#CJK UNIFIED IDEOGRAPH
+0xF6FA	0x6FC1	#CJK UNIFIED IDEOGRAPH
+0xF6FB	0x6FEF	#CJK UNIFIED IDEOGRAPH
+0xF6FC	0x7422	#CJK UNIFIED IDEOGRAPH
+0xF6FD	0x7438	#CJK UNIFIED IDEOGRAPH
+0xF6FE	0x8A17	#CJK UNIFIED IDEOGRAPH
+0xF7A1	0x9438	#CJK UNIFIED IDEOGRAPH
+0xF7A2	0x5451	#CJK UNIFIED IDEOGRAPH
+0xF7A3	0x5606	#CJK UNIFIED IDEOGRAPH
+0xF7A4	0x5766	#CJK UNIFIED IDEOGRAPH
+0xF7A5	0x5F48	#CJK UNIFIED IDEOGRAPH
+0xF7A6	0x619A	#CJK UNIFIED IDEOGRAPH
+0xF7A7	0x6B4E	#CJK UNIFIED IDEOGRAPH
+0xF7A8	0x7058	#CJK UNIFIED IDEOGRAPH
+0xF7A9	0x70AD	#CJK UNIFIED IDEOGRAPH
+0xF7AA	0x7DBB	#CJK UNIFIED IDEOGRAPH
+0xF7AB	0x8A95	#CJK UNIFIED IDEOGRAPH
+0xF7AC	0x596A	#CJK UNIFIED IDEOGRAPH
+0xF7AD	0x812B	#CJK UNIFIED IDEOGRAPH
+0xF7AE	0x63A2	#CJK UNIFIED IDEOGRAPH
+0xF7AF	0x7708	#CJK UNIFIED IDEOGRAPH
+0xF7B0	0x803D	#CJK UNIFIED IDEOGRAPH
+0xF7B1	0x8CAA	#CJK UNIFIED IDEOGRAPH
+0xF7B2	0x5854	#CJK UNIFIED IDEOGRAPH
+0xF7B3	0x642D	#CJK UNIFIED IDEOGRAPH
+0xF7B4	0x69BB	#CJK UNIFIED IDEOGRAPH
+0xF7B5	0x5B95	#CJK UNIFIED IDEOGRAPH
+0xF7B6	0x5E11	#CJK UNIFIED IDEOGRAPH
+0xF7B7	0x6E6F	#CJK UNIFIED IDEOGRAPH
+0xF7B8	0xFA03	#CJK COMPATIBILITY IDEOGRAPH
+0xF7B9	0x8569	#CJK UNIFIED IDEOGRAPH
+0xF7BA	0x514C	#CJK UNIFIED IDEOGRAPH
+0xF7BB	0x53F0	#CJK UNIFIED IDEOGRAPH
+0xF7BC	0x592A	#CJK UNIFIED IDEOGRAPH
+0xF7BD	0x6020	#CJK UNIFIED IDEOGRAPH
+0xF7BE	0x614B	#CJK UNIFIED IDEOGRAPH
+0xF7BF	0x6B86	#CJK UNIFIED IDEOGRAPH
+0xF7C0	0x6C70	#CJK UNIFIED IDEOGRAPH
+0xF7C1	0x6CF0	#CJK UNIFIED IDEOGRAPH
+0xF7C2	0x7B1E	#CJK UNIFIED IDEOGRAPH
+0xF7C3	0x80CE	#CJK UNIFIED IDEOGRAPH
+0xF7C4	0x82D4	#CJK UNIFIED IDEOGRAPH
+0xF7C5	0x8DC6	#CJK UNIFIED IDEOGRAPH
+0xF7C6	0x90B0	#CJK UNIFIED IDEOGRAPH
+0xF7C7	0x98B1	#CJK UNIFIED IDEOGRAPH
+0xF7C8	0xFA04	#CJK COMPATIBILITY IDEOGRAPH
+0xF7C9	0x64C7	#CJK UNIFIED IDEOGRAPH
+0xF7CA	0x6FA4	#CJK UNIFIED IDEOGRAPH
+0xF7CB	0x6491	#CJK UNIFIED IDEOGRAPH
+0xF7CC	0x6504	#CJK UNIFIED IDEOGRAPH
+0xF7CD	0x514E	#CJK UNIFIED IDEOGRAPH
+0xF7CE	0x5410	#CJK UNIFIED IDEOGRAPH
+0xF7CF	0x571F	#CJK UNIFIED IDEOGRAPH
+0xF7D0	0x8A0E	#CJK UNIFIED IDEOGRAPH
+0xF7D1	0x615F	#CJK UNIFIED IDEOGRAPH
+0xF7D2	0x6876	#CJK UNIFIED IDEOGRAPH
+0xF7D3	0xFA05	#CJK COMPATIBILITY IDEOGRAPH
+0xF7D4	0x75DB	#CJK UNIFIED IDEOGRAPH
+0xF7D5	0x7B52	#CJK UNIFIED IDEOGRAPH
+0xF7D6	0x7D71	#CJK UNIFIED IDEOGRAPH
+0xF7D7	0x901A	#CJK UNIFIED IDEOGRAPH
+0xF7D8	0x5806	#CJK UNIFIED IDEOGRAPH
+0xF7D9	0x69CC	#CJK UNIFIED IDEOGRAPH
+0xF7DA	0x817F	#CJK UNIFIED IDEOGRAPH
+0xF7DB	0x892A	#CJK UNIFIED IDEOGRAPH
+0xF7DC	0x9000	#CJK UNIFIED IDEOGRAPH
+0xF7DD	0x9839	#CJK UNIFIED IDEOGRAPH
+0xF7DE	0x5078	#CJK UNIFIED IDEOGRAPH
+0xF7DF	0x5957	#CJK UNIFIED IDEOGRAPH
+0xF7E0	0x59AC	#CJK UNIFIED IDEOGRAPH
+0xF7E1	0x6295	#CJK UNIFIED IDEOGRAPH
+0xF7E2	0x900F	#CJK UNIFIED IDEOGRAPH
+0xF7E3	0x9B2A	#CJK UNIFIED IDEOGRAPH
+0xF7E4	0x615D	#CJK UNIFIED IDEOGRAPH
+0xF7E5	0x7279	#CJK UNIFIED IDEOGRAPH
+0xF7E6	0x95D6	#CJK UNIFIED IDEOGRAPH
+0xF7E7	0x5761	#CJK UNIFIED IDEOGRAPH
+0xF7E8	0x5A46	#CJK UNIFIED IDEOGRAPH
+0xF7E9	0x5DF4	#CJK UNIFIED IDEOGRAPH
+0xF7EA	0x628A	#CJK UNIFIED IDEOGRAPH
+0xF7EB	0x64AD	#CJK UNIFIED IDEOGRAPH
+0xF7EC	0x64FA	#CJK UNIFIED IDEOGRAPH
+0xF7ED	0x6777	#CJK UNIFIED IDEOGRAPH
+0xF7EE	0x6CE2	#CJK UNIFIED IDEOGRAPH
+0xF7EF	0x6D3E	#CJK UNIFIED IDEOGRAPH
+0xF7F0	0x722C	#CJK UNIFIED IDEOGRAPH
+0xF7F1	0x7436	#CJK UNIFIED IDEOGRAPH
+0xF7F2	0x7834	#CJK UNIFIED IDEOGRAPH
+0xF7F3	0x7F77	#CJK UNIFIED IDEOGRAPH
+0xF7F4	0x82AD	#CJK UNIFIED IDEOGRAPH
+0xF7F5	0x8DDB	#CJK UNIFIED IDEOGRAPH
+0xF7F6	0x9817	#CJK UNIFIED IDEOGRAPH
+0xF7F7	0x5224	#CJK UNIFIED IDEOGRAPH
+0xF7F8	0x5742	#CJK UNIFIED IDEOGRAPH
+0xF7F9	0x677F	#CJK UNIFIED IDEOGRAPH
+0xF7FA	0x7248	#CJK UNIFIED IDEOGRAPH
+0xF7FB	0x74E3	#CJK UNIFIED IDEOGRAPH
+0xF7FC	0x8CA9	#CJK UNIFIED IDEOGRAPH
+0xF7FD	0x8FA6	#CJK UNIFIED IDEOGRAPH
+0xF7FE	0x9211	#CJK UNIFIED IDEOGRAPH
+0xF8A1	0x962A	#CJK UNIFIED IDEOGRAPH
+0xF8A2	0x516B	#CJK UNIFIED IDEOGRAPH
+0xF8A3	0x53ED	#CJK UNIFIED IDEOGRAPH
+0xF8A4	0x634C	#CJK UNIFIED IDEOGRAPH
+0xF8A5	0x4F69	#CJK UNIFIED IDEOGRAPH
+0xF8A6	0x5504	#CJK UNIFIED IDEOGRAPH
+0xF8A7	0x6096	#CJK UNIFIED IDEOGRAPH
+0xF8A8	0x6557	#CJK UNIFIED IDEOGRAPH
+0xF8A9	0x6C9B	#CJK UNIFIED IDEOGRAPH
+0xF8AA	0x6D7F	#CJK UNIFIED IDEOGRAPH
+0xF8AB	0x724C	#CJK UNIFIED IDEOGRAPH
+0xF8AC	0x72FD	#CJK UNIFIED IDEOGRAPH
+0xF8AD	0x7A17	#CJK UNIFIED IDEOGRAPH
+0xF8AE	0x8987	#CJK UNIFIED IDEOGRAPH
+0xF8AF	0x8C9D	#CJK UNIFIED IDEOGRAPH
+0xF8B0	0x5F6D	#CJK UNIFIED IDEOGRAPH
+0xF8B1	0x6F8E	#CJK UNIFIED IDEOGRAPH
+0xF8B2	0x70F9	#CJK UNIFIED IDEOGRAPH
+0xF8B3	0x81A8	#CJK UNIFIED IDEOGRAPH
+0xF8B4	0x610E	#CJK UNIFIED IDEOGRAPH
+0xF8B5	0x4FBF	#CJK UNIFIED IDEOGRAPH
+0xF8B6	0x504F	#CJK UNIFIED IDEOGRAPH
+0xF8B7	0x6241	#CJK UNIFIED IDEOGRAPH
+0xF8B8	0x7247	#CJK UNIFIED IDEOGRAPH
+0xF8B9	0x7BC7	#CJK UNIFIED IDEOGRAPH
+0xF8BA	0x7DE8	#CJK UNIFIED IDEOGRAPH
+0xF8BB	0x7FE9	#CJK UNIFIED IDEOGRAPH
+0xF8BC	0x904D	#CJK UNIFIED IDEOGRAPH
+0xF8BD	0x97AD	#CJK UNIFIED IDEOGRAPH
+0xF8BE	0x9A19	#CJK UNIFIED IDEOGRAPH
+0xF8BF	0x8CB6	#CJK UNIFIED IDEOGRAPH
+0xF8C0	0x576A	#CJK UNIFIED IDEOGRAPH
+0xF8C1	0x5E73	#CJK UNIFIED IDEOGRAPH
+0xF8C2	0x67B0	#CJK UNIFIED IDEOGRAPH
+0xF8C3	0x840D	#CJK UNIFIED IDEOGRAPH
+0xF8C4	0x8A55	#CJK UNIFIED IDEOGRAPH
+0xF8C5	0x5420	#CJK UNIFIED IDEOGRAPH
+0xF8C6	0x5B16	#CJK UNIFIED IDEOGRAPH
+0xF8C7	0x5E63	#CJK UNIFIED IDEOGRAPH
+0xF8C8	0x5EE2	#CJK UNIFIED IDEOGRAPH
+0xF8C9	0x5F0A	#CJK UNIFIED IDEOGRAPH
+0xF8CA	0x6583	#CJK UNIFIED IDEOGRAPH
+0xF8CB	0x80BA	#CJK UNIFIED IDEOGRAPH
+0xF8CC	0x853D	#CJK UNIFIED IDEOGRAPH
+0xF8CD	0x9589	#CJK UNIFIED IDEOGRAPH
+0xF8CE	0x965B	#CJK UNIFIED IDEOGRAPH
+0xF8CF	0x4F48	#CJK UNIFIED IDEOGRAPH
+0xF8D0	0x5305	#CJK UNIFIED IDEOGRAPH
+0xF8D1	0x530D	#CJK UNIFIED IDEOGRAPH
+0xF8D2	0x530F	#CJK UNIFIED IDEOGRAPH
+0xF8D3	0x5486	#CJK UNIFIED IDEOGRAPH
+0xF8D4	0x54FA	#CJK UNIFIED IDEOGRAPH
+0xF8D5	0x5703	#CJK UNIFIED IDEOGRAPH
+0xF8D6	0x5E03	#CJK UNIFIED IDEOGRAPH
+0xF8D7	0x6016	#CJK UNIFIED IDEOGRAPH
+0xF8D8	0x629B	#CJK UNIFIED IDEOGRAPH
+0xF8D9	0x62B1	#CJK UNIFIED IDEOGRAPH
+0xF8DA	0x6355	#CJK UNIFIED IDEOGRAPH
+0xF8DB	0xFA06	#CJK COMPATIBILITY IDEOGRAPH
+0xF8DC	0x6CE1	#CJK UNIFIED IDEOGRAPH
+0xF8DD	0x6D66	#CJK UNIFIED IDEOGRAPH
+0xF8DE	0x75B1	#CJK UNIFIED IDEOGRAPH
+0xF8DF	0x7832	#CJK UNIFIED IDEOGRAPH
+0xF8E0	0x80DE	#CJK UNIFIED IDEOGRAPH
+0xF8E1	0x812F	#CJK UNIFIED IDEOGRAPH
+0xF8E2	0x82DE	#CJK UNIFIED IDEOGRAPH
+0xF8E3	0x8461	#CJK UNIFIED IDEOGRAPH
+0xF8E4	0x84B2	#CJK UNIFIED IDEOGRAPH
+0xF8E5	0x888D	#CJK UNIFIED IDEOGRAPH
+0xF8E6	0x8912	#CJK UNIFIED IDEOGRAPH
+0xF8E7	0x900B	#CJK UNIFIED IDEOGRAPH
+0xF8E8	0x92EA	#CJK UNIFIED IDEOGRAPH
+0xF8E9	0x98FD	#CJK UNIFIED IDEOGRAPH
+0xF8EA	0x9B91	#CJK UNIFIED IDEOGRAPH
+0xF8EB	0x5E45	#CJK UNIFIED IDEOGRAPH
+0xF8EC	0x66B4	#CJK UNIFIED IDEOGRAPH
+0xF8ED	0x66DD	#CJK UNIFIED IDEOGRAPH
+0xF8EE	0x7011	#CJK UNIFIED IDEOGRAPH
+0xF8EF	0x7206	#CJK UNIFIED IDEOGRAPH
+0xF8F0	0xFA07	#CJK COMPATIBILITY IDEOGRAPH
+0xF8F1	0x4FF5	#CJK UNIFIED IDEOGRAPH
+0xF8F2	0x527D	#CJK UNIFIED IDEOGRAPH
+0xF8F3	0x5F6A	#CJK UNIFIED IDEOGRAPH
+0xF8F4	0x6153	#CJK UNIFIED IDEOGRAPH
+0xF8F5	0x6753	#CJK UNIFIED IDEOGRAPH
+0xF8F6	0x6A19	#CJK UNIFIED IDEOGRAPH
+0xF8F7	0x6F02	#CJK UNIFIED IDEOGRAPH
+0xF8F8	0x74E2	#CJK UNIFIED IDEOGRAPH
+0xF8F9	0x7968	#CJK UNIFIED IDEOGRAPH
+0xF8FA	0x8868	#CJK UNIFIED IDEOGRAPH
+0xF8FB	0x8C79	#CJK UNIFIED IDEOGRAPH
+0xF8FC	0x98C7	#CJK UNIFIED IDEOGRAPH
+0xF8FD	0x98C4	#CJK UNIFIED IDEOGRAPH
+0xF8FE	0x9A43	#CJK UNIFIED IDEOGRAPH
+0xF9A1	0x54C1	#CJK UNIFIED IDEOGRAPH
+0xF9A2	0x7A1F	#CJK UNIFIED IDEOGRAPH
+0xF9A3	0x6953	#CJK UNIFIED IDEOGRAPH
+0xF9A4	0x8AF7	#CJK UNIFIED IDEOGRAPH
+0xF9A5	0x8C4A	#CJK UNIFIED IDEOGRAPH
+0xF9A6	0x98A8	#CJK UNIFIED IDEOGRAPH
+0xF9A7	0x99AE	#CJK UNIFIED IDEOGRAPH
+0xF9A8	0x5F7C	#CJK UNIFIED IDEOGRAPH
+0xF9A9	0x62AB	#CJK UNIFIED IDEOGRAPH
+0xF9AA	0x75B2	#CJK UNIFIED IDEOGRAPH
+0xF9AB	0x76AE	#CJK UNIFIED IDEOGRAPH
+0xF9AC	0x88AB	#CJK UNIFIED IDEOGRAPH
+0xF9AD	0x907F	#CJK UNIFIED IDEOGRAPH
+0xF9AE	0x9642	#CJK UNIFIED IDEOGRAPH
+0xF9AF	0x5339	#CJK UNIFIED IDEOGRAPH
+0xF9B0	0x5F3C	#CJK UNIFIED IDEOGRAPH
+0xF9B1	0x5FC5	#CJK UNIFIED IDEOGRAPH
+0xF9B2	0x6CCC	#CJK UNIFIED IDEOGRAPH
+0xF9B3	0x73CC	#CJK UNIFIED IDEOGRAPH
+0xF9B4	0x7562	#CJK UNIFIED IDEOGRAPH
+0xF9B5	0x758B	#CJK UNIFIED IDEOGRAPH
+0xF9B6	0x7B46	#CJK UNIFIED IDEOGRAPH
+0xF9B7	0x82FE	#CJK UNIFIED IDEOGRAPH
+0xF9B8	0x999D	#CJK UNIFIED IDEOGRAPH
+0xF9B9	0x4E4F	#CJK UNIFIED IDEOGRAPH
+0xF9BA	0x903C	#CJK UNIFIED IDEOGRAPH
+0xF9BB	0x4E0B	#CJK UNIFIED IDEOGRAPH
+0xF9BC	0x4F55	#CJK UNIFIED IDEOGRAPH
+0xF9BD	0x53A6	#CJK UNIFIED IDEOGRAPH
+0xF9BE	0x590F	#CJK UNIFIED IDEOGRAPH
+0xF9BF	0x5EC8	#CJK UNIFIED IDEOGRAPH
+0xF9C0	0x6630	#CJK UNIFIED IDEOGRAPH
+0xF9C1	0x6CB3	#CJK UNIFIED IDEOGRAPH
+0xF9C2	0x7455	#CJK UNIFIED IDEOGRAPH
+0xF9C3	0x8377	#CJK UNIFIED IDEOGRAPH
+0xF9C4	0x8766	#CJK UNIFIED IDEOGRAPH
+0xF9C5	0x8CC0	#CJK UNIFIED IDEOGRAPH
+0xF9C6	0x9050	#CJK UNIFIED IDEOGRAPH
+0xF9C7	0x971E	#CJK UNIFIED IDEOGRAPH
+0xF9C8	0x9C15	#CJK UNIFIED IDEOGRAPH
+0xF9C9	0x58D1	#CJK UNIFIED IDEOGRAPH
+0xF9CA	0x5B78	#CJK UNIFIED IDEOGRAPH
+0xF9CB	0x8650	#CJK UNIFIED IDEOGRAPH
+0xF9CC	0x8B14	#CJK UNIFIED IDEOGRAPH
+0xF9CD	0x9DB4	#CJK UNIFIED IDEOGRAPH
+0xF9CE	0x5BD2	#CJK UNIFIED IDEOGRAPH
+0xF9CF	0x6068	#CJK UNIFIED IDEOGRAPH
+0xF9D0	0x608D	#CJK UNIFIED IDEOGRAPH
+0xF9D1	0x65F1	#CJK UNIFIED IDEOGRAPH
+0xF9D2	0x6C57	#CJK UNIFIED IDEOGRAPH
+0xF9D3	0x6F22	#CJK UNIFIED IDEOGRAPH
+0xF9D4	0x6FA3	#CJK UNIFIED IDEOGRAPH
+0xF9D5	0x701A	#CJK UNIFIED IDEOGRAPH
+0xF9D6	0x7F55	#CJK UNIFIED IDEOGRAPH
+0xF9D7	0x7FF0	#CJK UNIFIED IDEOGRAPH
+0xF9D8	0x9591	#CJK UNIFIED IDEOGRAPH
+0xF9D9	0x9592	#CJK UNIFIED IDEOGRAPH
+0xF9DA	0x9650	#CJK UNIFIED IDEOGRAPH
+0xF9DB	0x97D3	#CJK UNIFIED IDEOGRAPH
+0xF9DC	0x5272	#CJK UNIFIED IDEOGRAPH
+0xF9DD	0x8F44	#CJK UNIFIED IDEOGRAPH
+0xF9DE	0x51FD	#CJK UNIFIED IDEOGRAPH
+0xF9DF	0x542B	#CJK UNIFIED IDEOGRAPH
+0xF9E0	0x54B8	#CJK UNIFIED IDEOGRAPH
+0xF9E1	0x5563	#CJK UNIFIED IDEOGRAPH
+0xF9E2	0x558A	#CJK UNIFIED IDEOGRAPH
+0xF9E3	0x6ABB	#CJK UNIFIED IDEOGRAPH
+0xF9E4	0x6DB5	#CJK UNIFIED IDEOGRAPH
+0xF9E5	0x7DD8	#CJK UNIFIED IDEOGRAPH
+0xF9E6	0x8266	#CJK UNIFIED IDEOGRAPH
+0xF9E7	0x929C	#CJK UNIFIED IDEOGRAPH
+0xF9E8	0x9677	#CJK UNIFIED IDEOGRAPH
+0xF9E9	0x9E79	#CJK UNIFIED IDEOGRAPH
+0xF9EA	0x5408	#CJK UNIFIED IDEOGRAPH
+0xF9EB	0x54C8	#CJK UNIFIED IDEOGRAPH
+0xF9EC	0x76D2	#CJK UNIFIED IDEOGRAPH
+0xF9ED	0x86E4	#CJK UNIFIED IDEOGRAPH
+0xF9EE	0x95A4	#CJK UNIFIED IDEOGRAPH
+0xF9EF	0x95D4	#CJK UNIFIED IDEOGRAPH
+0xF9F0	0x965C	#CJK UNIFIED IDEOGRAPH
+0xF9F1	0x4EA2	#CJK UNIFIED IDEOGRAPH
+0xF9F2	0x4F09	#CJK UNIFIED IDEOGRAPH
+0xF9F3	0x59EE	#CJK UNIFIED IDEOGRAPH
+0xF9F4	0x5AE6	#CJK UNIFIED IDEOGRAPH
+0xF9F5	0x5DF7	#CJK UNIFIED IDEOGRAPH
+0xF9F6	0x6052	#CJK UNIFIED IDEOGRAPH
+0xF9F7	0x6297	#CJK UNIFIED IDEOGRAPH
+0xF9F8	0x676D	#CJK UNIFIED IDEOGRAPH
+0xF9F9	0x6841	#CJK UNIFIED IDEOGRAPH
+0xF9FA	0x6C86	#CJK UNIFIED IDEOGRAPH
+0xF9FB	0x6E2F	#CJK UNIFIED IDEOGRAPH
+0xF9FC	0x7F38	#CJK UNIFIED IDEOGRAPH
+0xF9FD	0x809B	#CJK UNIFIED IDEOGRAPH
+0xF9FE	0x822A	#CJK UNIFIED IDEOGRAPH
+0xFAA1	0xFA08	#CJK COMPATIBILITY IDEOGRAPH
+0xFAA2	0xFA09	#CJK COMPATIBILITY IDEOGRAPH
+0xFAA3	0x9805	#CJK UNIFIED IDEOGRAPH
+0xFAA4	0x4EA5	#CJK UNIFIED IDEOGRAPH
+0xFAA5	0x5055	#CJK UNIFIED IDEOGRAPH
+0xFAA6	0x54B3	#CJK UNIFIED IDEOGRAPH
+0xFAA7	0x5793	#CJK UNIFIED IDEOGRAPH
+0xFAA8	0x595A	#CJK UNIFIED IDEOGRAPH
+0xFAA9	0x5B69	#CJK UNIFIED IDEOGRAPH
+0xFAAA	0x5BB3	#CJK UNIFIED IDEOGRAPH
+0xFAAB	0x61C8	#CJK UNIFIED IDEOGRAPH
+0xFAAC	0x6977	#CJK UNIFIED IDEOGRAPH
+0xFAAD	0x6D77	#CJK UNIFIED IDEOGRAPH
+0xFAAE	0x7023	#CJK UNIFIED IDEOGRAPH
+0xFAAF	0x87F9	#CJK UNIFIED IDEOGRAPH
+0xFAB0	0x89E3	#CJK UNIFIED IDEOGRAPH
+0xFAB1	0x8A72	#CJK UNIFIED IDEOGRAPH
+0xFAB2	0x8AE7	#CJK UNIFIED IDEOGRAPH
+0xFAB3	0x9082	#CJK UNIFIED IDEOGRAPH
+0xFAB4	0x99ED	#CJK UNIFIED IDEOGRAPH
+0xFAB5	0x9AB8	#CJK UNIFIED IDEOGRAPH
+0xFAB6	0x52BE	#CJK UNIFIED IDEOGRAPH
+0xFAB7	0x6838	#CJK UNIFIED IDEOGRAPH
+0xFAB8	0x5016	#CJK UNIFIED IDEOGRAPH
+0xFAB9	0x5E78	#CJK UNIFIED IDEOGRAPH
+0xFABA	0x674F	#CJK UNIFIED IDEOGRAPH
+0xFABB	0x8347	#CJK UNIFIED IDEOGRAPH
+0xFABC	0x884C	#CJK UNIFIED IDEOGRAPH
+0xFABD	0x4EAB	#CJK UNIFIED IDEOGRAPH
+0xFABE	0x5411	#CJK UNIFIED IDEOGRAPH
+0xFABF	0x56AE	#CJK UNIFIED IDEOGRAPH
+0xFAC0	0x73E6	#CJK UNIFIED IDEOGRAPH
+0xFAC1	0x9115	#CJK UNIFIED IDEOGRAPH
+0xFAC2	0x97FF	#CJK UNIFIED IDEOGRAPH
+0xFAC3	0x9909	#CJK UNIFIED IDEOGRAPH
+0xFAC4	0x9957	#CJK UNIFIED IDEOGRAPH
+0xFAC5	0x9999	#CJK UNIFIED IDEOGRAPH
+0xFAC6	0x5653	#CJK UNIFIED IDEOGRAPH
+0xFAC7	0x589F	#CJK UNIFIED IDEOGRAPH
+0xFAC8	0x865B	#CJK UNIFIED IDEOGRAPH
+0xFAC9	0x8A31	#CJK UNIFIED IDEOGRAPH
+0xFACA	0x61B2	#CJK UNIFIED IDEOGRAPH
+0xFACB	0x6AF6	#CJK UNIFIED IDEOGRAPH
+0xFACC	0x737B	#CJK UNIFIED IDEOGRAPH
+0xFACD	0x8ED2	#CJK UNIFIED IDEOGRAPH
+0xFACE	0x6B47	#CJK UNIFIED IDEOGRAPH
+0xFACF	0x96AA	#CJK UNIFIED IDEOGRAPH
+0xFAD0	0x9A57	#CJK UNIFIED IDEOGRAPH
+0xFAD1	0x5955	#CJK UNIFIED IDEOGRAPH
+0xFAD2	0x7200	#CJK UNIFIED IDEOGRAPH
+0xFAD3	0x8D6B	#CJK UNIFIED IDEOGRAPH
+0xFAD4	0x9769	#CJK UNIFIED IDEOGRAPH
+0xFAD5	0x4FD4	#CJK UNIFIED IDEOGRAPH
+0xFAD6	0x5CF4	#CJK UNIFIED IDEOGRAPH
+0xFAD7	0x5F26	#CJK UNIFIED IDEOGRAPH
+0xFAD8	0x61F8	#CJK UNIFIED IDEOGRAPH
+0xFAD9	0x665B	#CJK UNIFIED IDEOGRAPH
+0xFADA	0x6CEB	#CJK UNIFIED IDEOGRAPH
+0xFADB	0x70AB	#CJK UNIFIED IDEOGRAPH
+0xFADC	0x7384	#CJK UNIFIED IDEOGRAPH
+0xFADD	0x73B9	#CJK UNIFIED IDEOGRAPH
+0xFADE	0x73FE	#CJK UNIFIED IDEOGRAPH
+0xFADF	0x7729	#CJK UNIFIED IDEOGRAPH
+0xFAE0	0x774D	#CJK UNIFIED IDEOGRAPH
+0xFAE1	0x7D43	#CJK UNIFIED IDEOGRAPH
+0xFAE2	0x7D62	#CJK UNIFIED IDEOGRAPH
+0xFAE3	0x7E23	#CJK UNIFIED IDEOGRAPH
+0xFAE4	0x8237	#CJK UNIFIED IDEOGRAPH
+0xFAE5	0x8852	#CJK UNIFIED IDEOGRAPH
+0xFAE6	0xFA0A	#CJK COMPATIBILITY IDEOGRAPH
+0xFAE7	0x8CE2	#CJK UNIFIED IDEOGRAPH
+0xFAE8	0x9249	#CJK UNIFIED IDEOGRAPH
+0xFAE9	0x986F	#CJK UNIFIED IDEOGRAPH
+0xFAEA	0x5B51	#CJK UNIFIED IDEOGRAPH
+0xFAEB	0x7A74	#CJK UNIFIED IDEOGRAPH
+0xFAEC	0x8840	#CJK UNIFIED IDEOGRAPH
+0xFAED	0x9801	#CJK UNIFIED IDEOGRAPH
+0xFAEE	0x5ACC	#CJK UNIFIED IDEOGRAPH
+0xFAEF	0x4FE0	#CJK UNIFIED IDEOGRAPH
+0xFAF0	0x5354	#CJK UNIFIED IDEOGRAPH
+0xFAF1	0x593E	#CJK UNIFIED IDEOGRAPH
+0xFAF2	0x5CFD	#CJK UNIFIED IDEOGRAPH
+0xFAF3	0x633E	#CJK UNIFIED IDEOGRAPH
+0xFAF4	0x6D79	#CJK UNIFIED IDEOGRAPH
+0xFAF5	0x72F9	#CJK UNIFIED IDEOGRAPH
+0xFAF6	0x8105	#CJK UNIFIED IDEOGRAPH
+0xFAF7	0x8107	#CJK UNIFIED IDEOGRAPH
+0xFAF8	0x83A2	#CJK UNIFIED IDEOGRAPH
+0xFAF9	0x92CF	#CJK UNIFIED IDEOGRAPH
+0xFAFA	0x9830	#CJK UNIFIED IDEOGRAPH
+0xFAFB	0x4EA8	#CJK UNIFIED IDEOGRAPH
+0xFAFC	0x5144	#CJK UNIFIED IDEOGRAPH
+0xFAFD	0x5211	#CJK UNIFIED IDEOGRAPH
+0xFAFE	0x578B	#CJK UNIFIED IDEOGRAPH
+0xFBA1	0x5F62	#CJK UNIFIED IDEOGRAPH
+0xFBA2	0x6CC2	#CJK UNIFIED IDEOGRAPH
+0xFBA3	0x6ECE	#CJK UNIFIED IDEOGRAPH
+0xFBA4	0x7005	#CJK UNIFIED IDEOGRAPH
+0xFBA5	0x7050	#CJK UNIFIED IDEOGRAPH
+0xFBA6	0x70AF	#CJK UNIFIED IDEOGRAPH
+0xFBA7	0x7192	#CJK UNIFIED IDEOGRAPH
+0xFBA8	0x73E9	#CJK UNIFIED IDEOGRAPH
+0xFBA9	0x7469	#CJK UNIFIED IDEOGRAPH
+0xFBAA	0x834A	#CJK UNIFIED IDEOGRAPH
+0xFBAB	0x87A2	#CJK UNIFIED IDEOGRAPH
+0xFBAC	0x8861	#CJK UNIFIED IDEOGRAPH
+0xFBAD	0x9008	#CJK UNIFIED IDEOGRAPH
+0xFBAE	0x90A2	#CJK UNIFIED IDEOGRAPH
+0xFBAF	0x93A3	#CJK UNIFIED IDEOGRAPH
+0xFBB0	0x99A8	#CJK UNIFIED IDEOGRAPH
+0xFBB1	0x516E	#CJK UNIFIED IDEOGRAPH
+0xFBB2	0x5F57	#CJK UNIFIED IDEOGRAPH
+0xFBB3	0x60E0	#CJK UNIFIED IDEOGRAPH
+0xFBB4	0x6167	#CJK UNIFIED IDEOGRAPH
+0xFBB5	0x66B3	#CJK UNIFIED IDEOGRAPH
+0xFBB6	0x8559	#CJK UNIFIED IDEOGRAPH
+0xFBB7	0x8E4A	#CJK UNIFIED IDEOGRAPH
+0xFBB8	0x91AF	#CJK UNIFIED IDEOGRAPH
+0xFBB9	0x978B	#CJK UNIFIED IDEOGRAPH
+0xFBBA	0x4E4E	#CJK UNIFIED IDEOGRAPH
+0xFBBB	0x4E92	#CJK UNIFIED IDEOGRAPH
+0xFBBC	0x547C	#CJK UNIFIED IDEOGRAPH
+0xFBBD	0x58D5	#CJK UNIFIED IDEOGRAPH
+0xFBBE	0x58FA	#CJK UNIFIED IDEOGRAPH
+0xFBBF	0x597D	#CJK UNIFIED IDEOGRAPH
+0xFBC0	0x5CB5	#CJK UNIFIED IDEOGRAPH
+0xFBC1	0x5F27	#CJK UNIFIED IDEOGRAPH
+0xFBC2	0x6236	#CJK UNIFIED IDEOGRAPH
+0xFBC3	0x6248	#CJK UNIFIED IDEOGRAPH
+0xFBC4	0x660A	#CJK UNIFIED IDEOGRAPH
+0xFBC5	0x6667	#CJK UNIFIED IDEOGRAPH
+0xFBC6	0x6BEB	#CJK UNIFIED IDEOGRAPH
+0xFBC7	0x6D69	#CJK UNIFIED IDEOGRAPH
+0xFBC8	0x6DCF	#CJK UNIFIED IDEOGRAPH
+0xFBC9	0x6E56	#CJK UNIFIED IDEOGRAPH
+0xFBCA	0x6EF8	#CJK UNIFIED IDEOGRAPH
+0xFBCB	0x6F94	#CJK UNIFIED IDEOGRAPH
+0xFBCC	0x6FE0	#CJK UNIFIED IDEOGRAPH
+0xFBCD	0x6FE9	#CJK UNIFIED IDEOGRAPH
+0xFBCE	0x705D	#CJK UNIFIED IDEOGRAPH
+0xFBCF	0x72D0	#CJK UNIFIED IDEOGRAPH
+0xFBD0	0x7425	#CJK UNIFIED IDEOGRAPH
+0xFBD1	0x745A	#CJK UNIFIED IDEOGRAPH
+0xFBD2	0x74E0	#CJK UNIFIED IDEOGRAPH
+0xFBD3	0x7693	#CJK UNIFIED IDEOGRAPH
+0xFBD4	0x795C	#CJK UNIFIED IDEOGRAPH
+0xFBD5	0x7CCA	#CJK UNIFIED IDEOGRAPH
+0xFBD6	0x7E1E	#CJK UNIFIED IDEOGRAPH
+0xFBD7	0x80E1	#CJK UNIFIED IDEOGRAPH
+0xFBD8	0x82A6	#CJK UNIFIED IDEOGRAPH
+0xFBD9	0x846B	#CJK UNIFIED IDEOGRAPH
+0xFBDA	0x84BF	#CJK UNIFIED IDEOGRAPH
+0xFBDB	0x864E	#CJK UNIFIED IDEOGRAPH
+0xFBDC	0x865F	#CJK UNIFIED IDEOGRAPH
+0xFBDD	0x8774	#CJK UNIFIED IDEOGRAPH
+0xFBDE	0x8B77	#CJK UNIFIED IDEOGRAPH
+0xFBDF	0x8C6A	#CJK UNIFIED IDEOGRAPH
+0xFBE0	0x93AC	#CJK UNIFIED IDEOGRAPH
+0xFBE1	0x9800	#CJK UNIFIED IDEOGRAPH
+0xFBE2	0x9865	#CJK UNIFIED IDEOGRAPH
+0xFBE3	0x60D1	#CJK UNIFIED IDEOGRAPH
+0xFBE4	0x6216	#CJK UNIFIED IDEOGRAPH
+0xFBE5	0x9177	#CJK UNIFIED IDEOGRAPH
+0xFBE6	0x5A5A	#CJK UNIFIED IDEOGRAPH
+0xFBE7	0x660F	#CJK UNIFIED IDEOGRAPH
+0xFBE8	0x6DF7	#CJK UNIFIED IDEOGRAPH
+0xFBE9	0x6E3E	#CJK UNIFIED IDEOGRAPH
+0xFBEA	0x743F	#CJK UNIFIED IDEOGRAPH
+0xFBEB	0x9B42	#CJK UNIFIED IDEOGRAPH
+0xFBEC	0x5FFD	#CJK UNIFIED IDEOGRAPH
+0xFBED	0x60DA	#CJK UNIFIED IDEOGRAPH
+0xFBEE	0x7B0F	#CJK UNIFIED IDEOGRAPH
+0xFBEF	0x54C4	#CJK UNIFIED IDEOGRAPH
+0xFBF0	0x5F18	#CJK UNIFIED IDEOGRAPH
+0xFBF1	0x6C5E	#CJK UNIFIED IDEOGRAPH
+0xFBF2	0x6CD3	#CJK UNIFIED IDEOGRAPH
+0xFBF3	0x6D2A	#CJK UNIFIED IDEOGRAPH
+0xFBF4	0x70D8	#CJK UNIFIED IDEOGRAPH
+0xFBF5	0x7D05	#CJK UNIFIED IDEOGRAPH
+0xFBF6	0x8679	#CJK UNIFIED IDEOGRAPH
+0xFBF7	0x8A0C	#CJK UNIFIED IDEOGRAPH
+0xFBF8	0x9D3B	#CJK UNIFIED IDEOGRAPH
+0xFBF9	0x5316	#CJK UNIFIED IDEOGRAPH
+0xFBFA	0x548C	#CJK UNIFIED IDEOGRAPH
+0xFBFB	0x5B05	#CJK UNIFIED IDEOGRAPH
+0xFBFC	0x6A3A	#CJK UNIFIED IDEOGRAPH
+0xFBFD	0x706B	#CJK UNIFIED IDEOGRAPH
+0xFBFE	0x7575	#CJK UNIFIED IDEOGRAPH
+0xFCA1	0x798D	#CJK UNIFIED IDEOGRAPH
+0xFCA2	0x79BE	#CJK UNIFIED IDEOGRAPH
+0xFCA3	0x82B1	#CJK UNIFIED IDEOGRAPH
+0xFCA4	0x83EF	#CJK UNIFIED IDEOGRAPH
+0xFCA5	0x8A71	#CJK UNIFIED IDEOGRAPH
+0xFCA6	0x8B41	#CJK UNIFIED IDEOGRAPH
+0xFCA7	0x8CA8	#CJK UNIFIED IDEOGRAPH
+0xFCA8	0x9774	#CJK UNIFIED IDEOGRAPH
+0xFCA9	0xFA0B	#CJK COMPATIBILITY IDEOGRAPH
+0xFCAA	0x64F4	#CJK UNIFIED IDEOGRAPH
+0xFCAB	0x652B	#CJK UNIFIED IDEOGRAPH
+0xFCAC	0x78BA	#CJK UNIFIED IDEOGRAPH
+0xFCAD	0x78BB	#CJK UNIFIED IDEOGRAPH
+0xFCAE	0x7A6B	#CJK UNIFIED IDEOGRAPH
+0xFCAF	0x4E38	#CJK UNIFIED IDEOGRAPH
+0xFCB0	0x559A	#CJK UNIFIED IDEOGRAPH
+0xFCB1	0x5950	#CJK UNIFIED IDEOGRAPH
+0xFCB2	0x5BA6	#CJK UNIFIED IDEOGRAPH
+0xFCB3	0x5E7B	#CJK UNIFIED IDEOGRAPH
+0xFCB4	0x60A3	#CJK UNIFIED IDEOGRAPH
+0xFCB5	0x63DB	#CJK UNIFIED IDEOGRAPH
+0xFCB6	0x6B61	#CJK UNIFIED IDEOGRAPH
+0xFCB7	0x6665	#CJK UNIFIED IDEOGRAPH
+0xFCB8	0x6853	#CJK UNIFIED IDEOGRAPH
+0xFCB9	0x6E19	#CJK UNIFIED IDEOGRAPH
+0xFCBA	0x7165	#CJK UNIFIED IDEOGRAPH
+0xFCBB	0x74B0	#CJK UNIFIED IDEOGRAPH
+0xFCBC	0x7D08	#CJK UNIFIED IDEOGRAPH
+0xFCBD	0x9084	#CJK UNIFIED IDEOGRAPH
+0xFCBE	0x9A69	#CJK UNIFIED IDEOGRAPH
+0xFCBF	0x9C25	#CJK UNIFIED IDEOGRAPH
+0xFCC0	0x6D3B	#CJK UNIFIED IDEOGRAPH
+0xFCC1	0x6ED1	#CJK UNIFIED IDEOGRAPH
+0xFCC2	0x733E	#CJK UNIFIED IDEOGRAPH
+0xFCC3	0x8C41	#CJK UNIFIED IDEOGRAPH
+0xFCC4	0x95CA	#CJK UNIFIED IDEOGRAPH
+0xFCC5	0x51F0	#CJK UNIFIED IDEOGRAPH
+0xFCC6	0x5E4C	#CJK UNIFIED IDEOGRAPH
+0xFCC7	0x5FA8	#CJK UNIFIED IDEOGRAPH
+0xFCC8	0x604D	#CJK UNIFIED IDEOGRAPH
+0xFCC9	0x60F6	#CJK UNIFIED IDEOGRAPH
+0xFCCA	0x6130	#CJK UNIFIED IDEOGRAPH
+0xFCCB	0x614C	#CJK UNIFIED IDEOGRAPH
+0xFCCC	0x6643	#CJK UNIFIED IDEOGRAPH
+0xFCCD	0x6644	#CJK UNIFIED IDEOGRAPH
+0xFCCE	0x69A5	#CJK UNIFIED IDEOGRAPH
+0xFCCF	0x6CC1	#CJK UNIFIED IDEOGRAPH
+0xFCD0	0x6E5F	#CJK UNIFIED IDEOGRAPH
+0xFCD1	0x6EC9	#CJK UNIFIED IDEOGRAPH
+0xFCD2	0x6F62	#CJK UNIFIED IDEOGRAPH
+0xFCD3	0x714C	#CJK UNIFIED IDEOGRAPH
+0xFCD4	0x749C	#CJK UNIFIED IDEOGRAPH
+0xFCD5	0x7687	#CJK UNIFIED IDEOGRAPH
+0xFCD6	0x7BC1	#CJK UNIFIED IDEOGRAPH
+0xFCD7	0x7C27	#CJK UNIFIED IDEOGRAPH
+0xFCD8	0x8352	#CJK UNIFIED IDEOGRAPH
+0xFCD9	0x8757	#CJK UNIFIED IDEOGRAPH
+0xFCDA	0x9051	#CJK UNIFIED IDEOGRAPH
+0xFCDB	0x968D	#CJK UNIFIED IDEOGRAPH
+0xFCDC	0x9EC3	#CJK UNIFIED IDEOGRAPH
+0xFCDD	0x532F	#CJK UNIFIED IDEOGRAPH
+0xFCDE	0x56DE	#CJK UNIFIED IDEOGRAPH
+0xFCDF	0x5EFB	#CJK UNIFIED IDEOGRAPH
+0xFCE0	0x5F8A	#CJK UNIFIED IDEOGRAPH
+0xFCE1	0x6062	#CJK UNIFIED IDEOGRAPH
+0xFCE2	0x6094	#CJK UNIFIED IDEOGRAPH
+0xFCE3	0x61F7	#CJK UNIFIED IDEOGRAPH
+0xFCE4	0x6666	#CJK UNIFIED IDEOGRAPH
+0xFCE5	0x6703	#CJK UNIFIED IDEOGRAPH
+0xFCE6	0x6A9C	#CJK UNIFIED IDEOGRAPH
+0xFCE7	0x6DEE	#CJK UNIFIED IDEOGRAPH
+0xFCE8	0x6FAE	#CJK UNIFIED IDEOGRAPH
+0xFCE9	0x7070	#CJK UNIFIED IDEOGRAPH
+0xFCEA	0x736A	#CJK UNIFIED IDEOGRAPH
+0xFCEB	0x7E6A	#CJK UNIFIED IDEOGRAPH
+0xFCEC	0x81BE	#CJK UNIFIED IDEOGRAPH
+0xFCED	0x8334	#CJK UNIFIED IDEOGRAPH
+0xFCEE	0x86D4	#CJK UNIFIED IDEOGRAPH
+0xFCEF	0x8AA8	#CJK UNIFIED IDEOGRAPH
+0xFCF0	0x8CC4	#CJK UNIFIED IDEOGRAPH
+0xFCF1	0x5283	#CJK UNIFIED IDEOGRAPH
+0xFCF2	0x7372	#CJK UNIFIED IDEOGRAPH
+0xFCF3	0x5B96	#CJK UNIFIED IDEOGRAPH
+0xFCF4	0x6A6B	#CJK UNIFIED IDEOGRAPH
+0xFCF5	0x9404	#CJK UNIFIED IDEOGRAPH
+0xFCF6	0x54EE	#CJK UNIFIED IDEOGRAPH
+0xFCF7	0x5686	#CJK UNIFIED IDEOGRAPH
+0xFCF8	0x5B5D	#CJK UNIFIED IDEOGRAPH
+0xFCF9	0x6548	#CJK UNIFIED IDEOGRAPH
+0xFCFA	0x6585	#CJK UNIFIED IDEOGRAPH
+0xFCFB	0x66C9	#CJK UNIFIED IDEOGRAPH
+0xFCFC	0x689F	#CJK UNIFIED IDEOGRAPH
+0xFCFD	0x6D8D	#CJK UNIFIED IDEOGRAPH
+0xFCFE	0x6DC6	#CJK UNIFIED IDEOGRAPH
+0xFDA1	0x723B	#CJK UNIFIED IDEOGRAPH
+0xFDA2	0x80B4	#CJK UNIFIED IDEOGRAPH
+0xFDA3	0x9175	#CJK UNIFIED IDEOGRAPH
+0xFDA4	0x9A4D	#CJK UNIFIED IDEOGRAPH
+0xFDA5	0x4FAF	#CJK UNIFIED IDEOGRAPH
+0xFDA6	0x5019	#CJK UNIFIED IDEOGRAPH
+0xFDA7	0x539A	#CJK UNIFIED IDEOGRAPH
+0xFDA8	0x540E	#CJK UNIFIED IDEOGRAPH
+0xFDA9	0x543C	#CJK UNIFIED IDEOGRAPH
+0xFDAA	0x5589	#CJK UNIFIED IDEOGRAPH
+0xFDAB	0x55C5	#CJK UNIFIED IDEOGRAPH
+0xFDAC	0x5E3F	#CJK UNIFIED IDEOGRAPH
+0xFDAD	0x5F8C	#CJK UNIFIED IDEOGRAPH
+0xFDAE	0x673D	#CJK UNIFIED IDEOGRAPH
+0xFDAF	0x7166	#CJK UNIFIED IDEOGRAPH
+0xFDB0	0x73DD	#CJK UNIFIED IDEOGRAPH
+0xFDB1	0x9005	#CJK UNIFIED IDEOGRAPH
+0xFDB2	0x52DB	#CJK UNIFIED IDEOGRAPH
+0xFDB3	0x52F3	#CJK UNIFIED IDEOGRAPH
+0xFDB4	0x5864	#CJK UNIFIED IDEOGRAPH
+0xFDB5	0x58CE	#CJK UNIFIED IDEOGRAPH
+0xFDB6	0x7104	#CJK UNIFIED IDEOGRAPH
+0xFDB7	0x718F	#CJK UNIFIED IDEOGRAPH
+0xFDB8	0x71FB	#CJK UNIFIED IDEOGRAPH
+0xFDB9	0x85B0	#CJK UNIFIED IDEOGRAPH
+0xFDBA	0x8A13	#CJK UNIFIED IDEOGRAPH
+0xFDBB	0x6688	#CJK UNIFIED IDEOGRAPH
+0xFDBC	0x85A8	#CJK UNIFIED IDEOGRAPH
+0xFDBD	0x55A7	#CJK UNIFIED IDEOGRAPH
+0xFDBE	0x6684	#CJK UNIFIED IDEOGRAPH
+0xFDBF	0x714A	#CJK UNIFIED IDEOGRAPH
+0xFDC0	0x8431	#CJK UNIFIED IDEOGRAPH
+0xFDC1	0x5349	#CJK UNIFIED IDEOGRAPH
+0xFDC2	0x5599	#CJK UNIFIED IDEOGRAPH
+0xFDC3	0x6BC1	#CJK UNIFIED IDEOGRAPH
+0xFDC4	0x5F59	#CJK UNIFIED IDEOGRAPH
+0xFDC5	0x5FBD	#CJK UNIFIED IDEOGRAPH
+0xFDC6	0x63EE	#CJK UNIFIED IDEOGRAPH
+0xFDC7	0x6689	#CJK UNIFIED IDEOGRAPH
+0xFDC8	0x7147	#CJK UNIFIED IDEOGRAPH
+0xFDC9	0x8AF1	#CJK UNIFIED IDEOGRAPH
+0xFDCA	0x8F1D	#CJK UNIFIED IDEOGRAPH
+0xFDCB	0x9EBE	#CJK UNIFIED IDEOGRAPH
+0xFDCC	0x4F11	#CJK UNIFIED IDEOGRAPH
+0xFDCD	0x643A	#CJK UNIFIED IDEOGRAPH
+0xFDCE	0x70CB	#CJK UNIFIED IDEOGRAPH
+0xFDCF	0x7566	#CJK UNIFIED IDEOGRAPH
+0xFDD0	0x8667	#CJK UNIFIED IDEOGRAPH
+0xFDD1	0x6064	#CJK UNIFIED IDEOGRAPH
+0xFDD2	0x8B4E	#CJK UNIFIED IDEOGRAPH
+0xFDD3	0x9DF8	#CJK UNIFIED IDEOGRAPH
+0xFDD4	0x5147	#CJK UNIFIED IDEOGRAPH
+0xFDD5	0x51F6	#CJK UNIFIED IDEOGRAPH
+0xFDD6	0x5308	#CJK UNIFIED IDEOGRAPH
+0xFDD7	0x6D36	#CJK UNIFIED IDEOGRAPH
+0xFDD8	0x80F8	#CJK UNIFIED IDEOGRAPH
+0xFDD9	0x9ED1	#CJK UNIFIED IDEOGRAPH
+0xFDDA	0x6615	#CJK UNIFIED IDEOGRAPH
+0xFDDB	0x6B23	#CJK UNIFIED IDEOGRAPH
+0xFDDC	0x7098	#CJK UNIFIED IDEOGRAPH
+0xFDDD	0x75D5	#CJK UNIFIED IDEOGRAPH
+0xFDDE	0x5403	#CJK UNIFIED IDEOGRAPH
+0xFDDF	0x5C79	#CJK UNIFIED IDEOGRAPH
+0xFDE0	0x7D07	#CJK UNIFIED IDEOGRAPH
+0xFDE1	0x8A16	#CJK UNIFIED IDEOGRAPH
+0xFDE2	0x6B20	#CJK UNIFIED IDEOGRAPH
+0xFDE3	0x6B3D	#CJK UNIFIED IDEOGRAPH
+0xFDE4	0x6B46	#CJK UNIFIED IDEOGRAPH
+0xFDE5	0x5438	#CJK UNIFIED IDEOGRAPH
+0xFDE6	0x6070	#CJK UNIFIED IDEOGRAPH
+0xFDE7	0x6D3D	#CJK UNIFIED IDEOGRAPH
+0xFDE8	0x7FD5	#CJK UNIFIED IDEOGRAPH
+0xFDE9	0x8208	#CJK UNIFIED IDEOGRAPH
+0xFDEA	0x50D6	#CJK UNIFIED IDEOGRAPH
+0xFDEB	0x51DE	#CJK UNIFIED IDEOGRAPH
+0xFDEC	0x559C	#CJK UNIFIED IDEOGRAPH
+0xFDED	0x566B	#CJK UNIFIED IDEOGRAPH
+0xFDEE	0x56CD	#CJK UNIFIED IDEOGRAPH
+0xFDEF	0x59EC	#CJK UNIFIED IDEOGRAPH
+0xFDF0	0x5B09	#CJK UNIFIED IDEOGRAPH
+0xFDF1	0x5E0C	#CJK UNIFIED IDEOGRAPH
+0xFDF2	0x6199	#CJK UNIFIED IDEOGRAPH
+0xFDF3	0x6198	#CJK UNIFIED IDEOGRAPH
+0xFDF4	0x6231	#CJK UNIFIED IDEOGRAPH
+0xFDF5	0x665E	#CJK UNIFIED IDEOGRAPH
+0xFDF6	0x66E6	#CJK UNIFIED IDEOGRAPH
+0xFDF7	0x7199	#CJK UNIFIED IDEOGRAPH
+0xFDF8	0x71B9	#CJK UNIFIED IDEOGRAPH
+0xFDF9	0x71BA	#CJK UNIFIED IDEOGRAPH
+0xFDFA	0x72A7	#CJK UNIFIED IDEOGRAPH
+0xFDFB	0x79A7	#CJK UNIFIED IDEOGRAPH
+0xFDFC	0x7A00	#CJK UNIFIED IDEOGRAPH
+0xFDFD	0x7FB2	#CJK UNIFIED IDEOGRAPH
+0xFDFE	0x8A70	#CJK UNIFIED IDEOGRAPH
diff --git a/tools/encoding/cp950.txt b/tools/encoding/cp950.txt
new file mode 100644
index 0000000..7fadbbc
--- /dev/null
+++ b/tools/encoding/cp950.txt
@@ -0,0 +1,13777 @@
+#
+#    Name:     cp950 to Unicode table
+#    Unicode version: 2.0
+#    Table version: 2.01
+#    Table format:  Format A
+#    Date:          1/7/2000
+#
+#    Contact:       cpxlate@microsoft.com
+#
+#    General notes: none
+#
+#    Format: Three tab-separated columns
+#        Column #1 is the cp950 code (in hex)
+#        Column #2 is the Unicode (in hex as 0xXXXX)
+#        Column #3 is the Unicode name (follows a comment sign, '#')
+#
+#    The entries are in cp950 order
+#
+0x00	0x0000	#NULL
+0x01	0x0001	#START OF HEADING
+0x02	0x0002	#START OF TEXT
+0x03	0x0003	#END OF TEXT
+0x04	0x0004	#END OF TRANSMISSION
+0x05	0x0005	#ENQUIRY
+0x06	0x0006	#ACKNOWLEDGE
+0x07	0x0007	#BELL
+0x08	0x0008	#BACKSPACE
+0x09	0x0009	#HORIZONTAL TABULATION
+0x0A	0x000A	#LINE FEED
+0x0B	0x000B	#VERTICAL TABULATION
+0x0C	0x000C	#FORM FEED
+0x0D	0x000D	#CARRIAGE RETURN
+0x0E	0x000E	#SHIFT OUT
+0x0F	0x000F	#SHIFT IN
+0x10	0x0010	#DATA LINK ESCAPE
+0x11	0x0011	#DEVICE CONTROL ONE
+0x12	0x0012	#DEVICE CONTROL TWO
+0x13	0x0013	#DEVICE CONTROL THREE
+0x14	0x0014	#DEVICE CONTROL FOUR
+0x15	0x0015	#NEGATIVE ACKNOWLEDGE
+0x16	0x0016	#SYNCHRONOUS IDLE
+0x17	0x0017	#END OF TRANSMISSION BLOCK
+0x18	0x0018	#CANCEL
+0x19	0x0019	#END OF MEDIUM
+0x1A	0x001A	#SUBSTITUTE
+0x1B	0x001B	#ESCAPE
+0x1C	0x001C	#FILE SEPARATOR
+0x1D	0x001D	#GROUP SEPARATOR
+0x1E	0x001E	#RECORD SEPARATOR
+0x1F	0x001F	#UNIT SEPARATOR
+0x20	0x0020	#SPACE
+0x21	0x0021	#EXCLAMATION MARK
+0x22	0x0022	#QUOTATION MARK
+0x23	0x0023	#NUMBER SIGN
+0x24	0x0024	#DOLLAR SIGN
+0x25	0x0025	#PERCENT SIGN
+0x26	0x0026	#AMPERSAND
+0x27	0x0027	#APOSTROPHE
+0x28	0x0028	#LEFT PARENTHESIS
+0x29	0x0029	#RIGHT PARENTHESIS
+0x2A	0x002A	#ASTERISK
+0x2B	0x002B	#PLUS SIGN
+0x2C	0x002C	#COMMA
+0x2D	0x002D	#HYPHEN-MINUS
+0x2E	0x002E	#FULL STOP
+0x2F	0x002F	#SOLIDUS
+0x30	0x0030	#DIGIT ZERO
+0x31	0x0031	#DIGIT ONE
+0x32	0x0032	#DIGIT TWO
+0x33	0x0033	#DIGIT THREE
+0x34	0x0034	#DIGIT FOUR
+0x35	0x0035	#DIGIT FIVE
+0x36	0x0036	#DIGIT SIX
+0x37	0x0037	#DIGIT SEVEN
+0x38	0x0038	#DIGIT EIGHT
+0x39	0x0039	#DIGIT NINE
+0x3A	0x003A	#COLON
+0x3B	0x003B	#SEMICOLON
+0x3C	0x003C	#LESS-THAN SIGN
+0x3D	0x003D	#EQUALS SIGN
+0x3E	0x003E	#GREATER-THAN SIGN
+0x3F	0x003F	#QUESTION MARK
+0x40	0x0040	#COMMERCIAL AT
+0x41	0x0041	#LATIN CAPITAL LETTER A
+0x42	0x0042	#LATIN CAPITAL LETTER B
+0x43	0x0043	#LATIN CAPITAL LETTER C
+0x44	0x0044	#LATIN CAPITAL LETTER D
+0x45	0x0045	#LATIN CAPITAL LETTER E
+0x46	0x0046	#LATIN CAPITAL LETTER F
+0x47	0x0047	#LATIN CAPITAL LETTER G
+0x48	0x0048	#LATIN CAPITAL LETTER H
+0x49	0x0049	#LATIN CAPITAL LETTER I
+0x4A	0x004A	#LATIN CAPITAL LETTER J
+0x4B	0x004B	#LATIN CAPITAL LETTER K
+0x4C	0x004C	#LATIN CAPITAL LETTER L
+0x4D	0x004D	#LATIN CAPITAL LETTER M
+0x4E	0x004E	#LATIN CAPITAL LETTER N
+0x4F	0x004F	#LATIN CAPITAL LETTER O
+0x50	0x0050	#LATIN CAPITAL LETTER P
+0x51	0x0051	#LATIN CAPITAL LETTER Q
+0x52	0x0052	#LATIN CAPITAL LETTER R
+0x53	0x0053	#LATIN CAPITAL LETTER S
+0x54	0x0054	#LATIN CAPITAL LETTER T
+0x55	0x0055	#LATIN CAPITAL LETTER U
+0x56	0x0056	#LATIN CAPITAL LETTER V
+0x57	0x0057	#LATIN CAPITAL LETTER W
+0x58	0x0058	#LATIN CAPITAL LETTER X
+0x59	0x0059	#LATIN CAPITAL LETTER Y
+0x5A	0x005A	#LATIN CAPITAL LETTER Z
+0x5B	0x005B	#LEFT SQUARE BRACKET
+0x5C	0x005C	#REVERSE SOLIDUS
+0x5D	0x005D	#RIGHT SQUARE BRACKET
+0x5E	0x005E	#CIRCUMFLEX ACCENT
+0x5F	0x005F	#LOW LINE
+0x60	0x0060	#GRAVE ACCENT
+0x61	0x0061	#LATIN SMALL LETTER A
+0x62	0x0062	#LATIN SMALL LETTER B
+0x63	0x0063	#LATIN SMALL LETTER C
+0x64	0x0064	#LATIN SMALL LETTER D
+0x65	0x0065	#LATIN SMALL LETTER E
+0x66	0x0066	#LATIN SMALL LETTER F
+0x67	0x0067	#LATIN SMALL LETTER G
+0x68	0x0068	#LATIN SMALL LETTER H
+0x69	0x0069	#LATIN SMALL LETTER I
+0x6A	0x006A	#LATIN SMALL LETTER J
+0x6B	0x006B	#LATIN SMALL LETTER K
+0x6C	0x006C	#LATIN SMALL LETTER L
+0x6D	0x006D	#LATIN SMALL LETTER M
+0x6E	0x006E	#LATIN SMALL LETTER N
+0x6F	0x006F	#LATIN SMALL LETTER O
+0x70	0x0070	#LATIN SMALL LETTER P
+0x71	0x0071	#LATIN SMALL LETTER Q
+0x72	0x0072	#LATIN SMALL LETTER R
+0x73	0x0073	#LATIN SMALL LETTER S
+0x74	0x0074	#LATIN SMALL LETTER T
+0x75	0x0075	#LATIN SMALL LETTER U
+0x76	0x0076	#LATIN SMALL LETTER V
+0x77	0x0077	#LATIN SMALL LETTER W
+0x78	0x0078	#LATIN SMALL LETTER X
+0x79	0x0079	#LATIN SMALL LETTER Y
+0x7A	0x007A	#LATIN SMALL LETTER Z
+0x7B	0x007B	#LEFT CURLY BRACKET
+0x7C	0x007C	#VERTICAL LINE
+0x7D	0x007D	#RIGHT CURLY BRACKET
+0x7E	0x007E	#TILDE
+0x7F	0x007F	#DELETE
+0x80	      	#UNDEFINED
+0x81	      	#DBCS LEAD BYTE
+0x82	      	#DBCS LEAD BYTE
+0x83	      	#DBCS LEAD BYTE
+0x84	      	#DBCS LEAD BYTE
+0x85	      	#DBCS LEAD BYTE
+0x86	      	#DBCS LEAD BYTE
+0x87	      	#DBCS LEAD BYTE
+0x88	      	#DBCS LEAD BYTE
+0x89	      	#DBCS LEAD BYTE
+0x8A	      	#DBCS LEAD BYTE
+0x8B	      	#DBCS LEAD BYTE
+0x8C	      	#DBCS LEAD BYTE
+0x8D	      	#DBCS LEAD BYTE
+0x8E	      	#DBCS LEAD BYTE
+0x8F	      	#DBCS LEAD BYTE
+0x90	      	#DBCS LEAD BYTE
+0x91	      	#DBCS LEAD BYTE
+0x92	      	#DBCS LEAD BYTE
+0x93	      	#DBCS LEAD BYTE
+0x94	      	#DBCS LEAD BYTE
+0x95	      	#DBCS LEAD BYTE
+0x96	      	#DBCS LEAD BYTE
+0x97	      	#DBCS LEAD BYTE
+0x98	      	#DBCS LEAD BYTE
+0x99	      	#DBCS LEAD BYTE
+0x9A	      	#DBCS LEAD BYTE
+0x9B	      	#DBCS LEAD BYTE
+0x9C	      	#DBCS LEAD BYTE
+0x9D	      	#DBCS LEAD BYTE
+0x9E	      	#DBCS LEAD BYTE
+0x9F	      	#DBCS LEAD BYTE
+0xA0	      	#DBCS LEAD BYTE
+0xA1	      	#DBCS LEAD BYTE
+0xA2	      	#DBCS LEAD BYTE
+0xA3	      	#DBCS LEAD BYTE
+0xA4	      	#DBCS LEAD BYTE
+0xA5	      	#DBCS LEAD BYTE
+0xA6	      	#DBCS LEAD BYTE
+0xA7	      	#DBCS LEAD BYTE
+0xA8	      	#DBCS LEAD BYTE
+0xA9	      	#DBCS LEAD BYTE
+0xAA	      	#DBCS LEAD BYTE
+0xAB	      	#DBCS LEAD BYTE
+0xAC	      	#DBCS LEAD BYTE
+0xAD	      	#DBCS LEAD BYTE
+0xAE	      	#DBCS LEAD BYTE
+0xAF	      	#DBCS LEAD BYTE
+0xB0	      	#DBCS LEAD BYTE
+0xB1	      	#DBCS LEAD BYTE
+0xB2	      	#DBCS LEAD BYTE
+0xB3	      	#DBCS LEAD BYTE
+0xB4	      	#DBCS LEAD BYTE
+0xB5	      	#DBCS LEAD BYTE
+0xB6	      	#DBCS LEAD BYTE
+0xB7	      	#DBCS LEAD BYTE
+0xB8	      	#DBCS LEAD BYTE
+0xB9	      	#DBCS LEAD BYTE
+0xBA	      	#DBCS LEAD BYTE
+0xBB	      	#DBCS LEAD BYTE
+0xBC	      	#DBCS LEAD BYTE
+0xBD	      	#DBCS LEAD BYTE
+0xBE	      	#DBCS LEAD BYTE
+0xBF	      	#DBCS LEAD BYTE
+0xC0	      	#DBCS LEAD BYTE
+0xC1	      	#DBCS LEAD BYTE
+0xC2	      	#DBCS LEAD BYTE
+0xC3	      	#DBCS LEAD BYTE
+0xC4	      	#DBCS LEAD BYTE
+0xC5	      	#DBCS LEAD BYTE
+0xC6	      	#DBCS LEAD BYTE
+0xC7	      	#DBCS LEAD BYTE
+0xC8	      	#DBCS LEAD BYTE
+0xC9	      	#DBCS LEAD BYTE
+0xCA	      	#DBCS LEAD BYTE
+0xCB	      	#DBCS LEAD BYTE
+0xCC	      	#DBCS LEAD BYTE
+0xCD	      	#DBCS LEAD BYTE
+0xCE	      	#DBCS LEAD BYTE
+0xCF	      	#DBCS LEAD BYTE
+0xD0	      	#DBCS LEAD BYTE
+0xD1	      	#DBCS LEAD BYTE
+0xD2	      	#DBCS LEAD BYTE
+0xD3	      	#DBCS LEAD BYTE
+0xD4	      	#DBCS LEAD BYTE
+0xD5	      	#DBCS LEAD BYTE
+0xD6	      	#DBCS LEAD BYTE
+0xD7	      	#DBCS LEAD BYTE
+0xD8	      	#DBCS LEAD BYTE
+0xD9	      	#DBCS LEAD BYTE
+0xDA	      	#DBCS LEAD BYTE
+0xDB	      	#DBCS LEAD BYTE
+0xDC	      	#DBCS LEAD BYTE
+0xDD	      	#DBCS LEAD BYTE
+0xDE	      	#DBCS LEAD BYTE
+0xDF	      	#DBCS LEAD BYTE
+0xE0	      	#DBCS LEAD BYTE
+0xE1	      	#DBCS LEAD BYTE
+0xE2	      	#DBCS LEAD BYTE
+0xE3	      	#DBCS LEAD BYTE
+0xE4	      	#DBCS LEAD BYTE
+0xE5	      	#DBCS LEAD BYTE
+0xE6	      	#DBCS LEAD BYTE
+0xE7	      	#DBCS LEAD BYTE
+0xE8	      	#DBCS LEAD BYTE
+0xE9	      	#DBCS LEAD BYTE
+0xEA	      	#DBCS LEAD BYTE
+0xEB	      	#DBCS LEAD BYTE
+0xEC	      	#DBCS LEAD BYTE
+0xED	      	#DBCS LEAD BYTE
+0xEE	      	#DBCS LEAD BYTE
+0xEF	      	#DBCS LEAD BYTE
+0xF0	      	#DBCS LEAD BYTE
+0xF1	      	#DBCS LEAD BYTE
+0xF2	      	#DBCS LEAD BYTE
+0xF3	      	#DBCS LEAD BYTE
+0xF4	      	#DBCS LEAD BYTE
+0xF5	      	#DBCS LEAD BYTE
+0xF6	      	#DBCS LEAD BYTE
+0xF7	      	#DBCS LEAD BYTE
+0xF8	      	#DBCS LEAD BYTE
+0xF9	      	#DBCS LEAD BYTE
+0xFA	      	#DBCS LEAD BYTE
+0xFB	      	#DBCS LEAD BYTE
+0xFC	      	#DBCS LEAD BYTE
+0xFD	      	#DBCS LEAD BYTE
+0xFE	      	#DBCS LEAD BYTE
+0xFF	      	#UNDEFINED
+0xA140	0x3000	#IDEOGRAPHIC SPACE
+0xA141	0xFF0C	#FULLWIDTH COMMA
+0xA142	0x3001	#IDEOGRAPHIC COMMA
+0xA143	0x3002	#IDEOGRAPHIC FULL STOP
+0xA144	0xFF0E	#FULLWIDTH FULL STOP
+0xA145	0x2027	#HYPHENATION POINT
+0xA146	0xFF1B	#FULLWIDTH SEMICOLON
+0xA147	0xFF1A	#FULLWIDTH COLON
+0xA148	0xFF1F	#FULLWIDTH QUESTION MARK
+0xA149	0xFF01	#FULLWIDTH EXCLAMATION MARK
+0xA14A	0xFE30	#PRESENTATION FORM FOR VERTICAL TWO DOT LEADER
+0xA14B	0x2026	#HORIZONTAL ELLIPSIS
+0xA14C	0x2025	#TWO DOT LEADER
+0xA14D	0xFE50	#SMALL COMMA
+0xA14E	0xFE51	#SMALL IDEOGRAPHIC COMMA
+0xA14F	0xFE52	#SMALL FULL STOP
+0xA150	0x00B7	#MIDDLE DOT
+0xA151	0xFE54	#SMALL SEMICOLON
+0xA152	0xFE55	#SMALL COLON
+0xA153	0xFE56	#SMALL QUESTION MARK
+0xA154	0xFE57	#SMALL EXCLAMATION MARK
+0xA155	0xFF5C	#FULLWIDTH VERTICAL LINE
+0xA156	0x2013	#EN DASH
+0xA157	0xFE31	#PRESENTATION FORM FOR VERTICAL EM DASH
+0xA158	0x2014	#EM DASH
+0xA159	0xFE33	#PRESENTATION FORM FOR VERTICAL LOW LINE
+0xA15A	0x2574	#BOX DRAWINGS LIGHT LEFT
+0xA15B	0xFE34	#PRESENTATION FORM FOR VERTICAL WAVY LOW LINE
+0xA15C	0xFE4F	#WAVY LOW LINE
+0xA15D	0xFF08	#FULLWIDTH LEFT PARENTHESIS
+0xA15E	0xFF09	#FULLWIDTH RIGHT PARENTHESIS
+0xA15F	0xFE35	#PRESENTATION FORM FOR VERTICAL LEFT PARENTHESIS
+0xA160	0xFE36	#PRESENTATION FORM FOR VERTICAL RIGHT PARENTHESIS
+0xA161	0xFF5B	#FULLWIDTH LEFT CURLY BRACKET
+0xA162	0xFF5D	#FULLWIDTH RIGHT CURLY BRACKET
+0xA163	0xFE37	#PRESENTATION FORM FOR VERTICAL LEFT CURLY BRACKET
+0xA164	0xFE38	#PRESENTATION FORM FOR VERTICAL RIGHT CURLY BRACKET
+0xA165	0x3014	#LEFT TORTOISE SHELL BRACKET
+0xA166	0x3015	#RIGHT TORTOISE SHELL BRACKET
+0xA167	0xFE39	#PRESENTATION FORM FOR VERTICAL LEFT TORTOISE SHELL BRACKET
+0xA168	0xFE3A	#PRESENTATION FORM FOR VERTICAL RIGHT TORTOISE SHELL BRACKET
+0xA169	0x3010	#LEFT BLACK LENTICULAR BRACKET
+0xA16A	0x3011	#RIGHT BLACK LENTICULAR BRACKET
+0xA16B	0xFE3B	#PRESENTATION FORM FOR VERTICAL LEFT BLACK LENTICULAR BRACKET
+0xA16C	0xFE3C	#PRESENTATION FORM FOR VERTICAL RIGHT BLACK LENTICULAR BRACKET
+0xA16D	0x300A	#LEFT DOUBLE ANGLE BRACKET
+0xA16E	0x300B	#RIGHT DOUBLE ANGLE BRACKET
+0xA16F	0xFE3D	#PRESENTATION FORM FOR VERTICAL LEFT DOUBLE ANGLE BRACKET
+0xA170	0xFE3E	#PRESENTATION FORM FOR VERTICAL RIGHT DOUBLE ANGLE BRACKET
+0xA171	0x3008	#LEFT ANGLE BRACKET
+0xA172	0x3009	#RIGHT ANGLE BRACKET
+0xA173	0xFE3F	#PRESENTATION FORM FOR VERTICAL LEFT ANGLE BRACKET
+0xA174	0xFE40	#PRESENTATION FORM FOR VERTICAL RIGHT ANGLE BRACKET
+0xA175	0x300C	#LEFT CORNER BRACKET
+0xA176	0x300D	#RIGHT CORNER BRACKET
+0xA177	0xFE41	#PRESENTATION FORM FOR VERTICAL LEFT CORNER BRACKET
+0xA178	0xFE42	#PRESENTATION FORM FOR VERTICAL RIGHT CORNER BRACKET
+0xA179	0x300E	#LEFT WHITE CORNER BRACKET
+0xA17A	0x300F	#RIGHT WHITE CORNER BRACKET
+0xA17B	0xFE43	#PRESENTATION FORM FOR VERTICAL LEFT WHITE CORNER BRACKET
+0xA17C	0xFE44	#PRESENTATION FORM FOR VERTICAL RIGHT WHITE CORNER BRACKET
+0xA17D	0xFE59	#SMALL LEFT PARENTHESIS
+0xA17E	0xFE5A	#SMALL RIGHT PARENTHESIS
+0xA1A1	0xFE5B	#SMALL LEFT CURLY BRACKET
+0xA1A2	0xFE5C	#SMALL RIGHT CURLY BRACKET
+0xA1A3	0xFE5D	#SMALL LEFT TORTOISE SHELL BRACKET
+0xA1A4	0xFE5E	#SMALL RIGHT TORTOISE SHELL BRACKET
+0xA1A5	0x2018	#LEFT SINGLE QUOTATION MARK
+0xA1A6	0x2019	#RIGHT SINGLE QUOTATION MARK
+0xA1A7	0x201C	#LEFT DOUBLE QUOTATION MARK
+0xA1A8	0x201D	#RIGHT DOUBLE QUOTATION MARK
+0xA1A9	0x301D	#REVERSED DOUBLE PRIME QUOTATION MARK
+0xA1AA	0x301E	#DOUBLE PRIME QUOTATION MARK
+0xA1AB	0x2035	#REVERSED PRIME
+0xA1AC	0x2032	#PRIME
+0xA1AD	0xFF03	#FULLWIDTH NUMBER SIGN
+0xA1AE	0xFF06	#FULLWIDTH AMPERSAND
+0xA1AF	0xFF0A	#FULLWIDTH ASTERISK
+0xA1B0	0x203B	#REFERENCE MARK
+0xA1B1	0x00A7	#SECTION SIGN
+0xA1B2	0x3003	#DITTO MARK
+0xA1B3	0x25CB	#WHITE CIRCLE
+0xA1B4	0x25CF	#BLACK CIRCLE
+0xA1B5	0x25B3	#WHITE UP-POINTING TRIANGLE
+0xA1B6	0x25B2	#BLACK UP-POINTING TRIANGLE
+0xA1B7	0x25CE	#BULLSEYE
+0xA1B8	0x2606	#WHITE STAR
+0xA1B9	0x2605	#BLACK STAR
+0xA1BA	0x25C7	#WHITE DIAMOND
+0xA1BB	0x25C6	#BLACK DIAMOND
+0xA1BC	0x25A1	#WHITE SQUARE
+0xA1BD	0x25A0	#BLACK SQUARE
+0xA1BE	0x25BD	#WHITE DOWN-POINTING TRIANGLE
+0xA1BF	0x25BC	#BLACK DOWN-POINTING TRIANGLE
+0xA1C0	0x32A3	#CIRCLED IDEOGRAPH CORRECT
+0xA1C1	0x2105	#CARE OF
+0xA1C2	0x00AF	#MACRON
+0xA1C3	0xFFE3	#FULLWIDTH MACRON
+0xA1C4	0xFF3F	#FULLWIDTH LOW LINE
+0xA1C5	0x02CD	#MODIFIER LETTER LOW MACRON
+0xA1C6	0xFE49	#DASHED OVERLINE
+0xA1C7	0xFE4A	#CENTRELINE OVERLINE
+0xA1C8	0xFE4D	#DASHED LOW LINE
+0xA1C9	0xFE4E	#CENTRELINE LOW LINE
+0xA1CA	0xFE4B	#WAVY OVERLINE
+0xA1CB	0xFE4C	#DOUBLE WAVY OVERLINE
+0xA1CC	0xFE5F	#SMALL NUMBER SIGN
+0xA1CD	0xFE60	#SMALL AMPERSAND
+0xA1CE	0xFE61	#SMALL ASTERISK
+0xA1CF	0xFF0B	#FULLWIDTH PLUS SIGN
+0xA1D0	0xFF0D	#FULLWIDTH HYPHEN-MINUS
+0xA1D1	0x00D7	#MULTIPLICATION SIGN
+0xA1D2	0x00F7	#DIVISION SIGN
+0xA1D3	0x00B1	#PLUS-MINUS SIGN
+0xA1D4	0x221A	#SQUARE ROOT
+0xA1D5	0xFF1C	#FULLWIDTH LESS-THAN SIGN
+0xA1D6	0xFF1E	#FULLWIDTH GREATER-THAN SIGN
+0xA1D7	0xFF1D	#FULLWIDTH EQUALS SIGN
+0xA1D8	0x2266	#LESS-THAN OVER EQUAL TO
+0xA1D9	0x2267	#GREATER-THAN OVER EQUAL TO
+0xA1DA	0x2260	#NOT EQUAL TO
+0xA1DB	0x221E	#INFINITY
+0xA1DC	0x2252	#APPROXIMATELY EQUAL TO OR THE IMAGE OF
+0xA1DD	0x2261	#IDENTICAL TO
+0xA1DE	0xFE62	#SMALL PLUS SIGN
+0xA1DF	0xFE63	#SMALL HYPHEN-MINUS
+0xA1E0	0xFE64	#SMALL LESS-THAN SIGN
+0xA1E1	0xFE65	#SMALL GREATER-THAN SIGN
+0xA1E2	0xFE66	#SMALL EQUALS SIGN
+0xA1E3	0xFF5E	#FULLWIDTH TILDE
+0xA1E4	0x2229	#INTERSECTION
+0xA1E5	0x222A	#UNION
+0xA1E6	0x22A5	#UP TACK
+0xA1E7	0x2220	#ANGLE
+0xA1E8	0x221F	#RIGHT ANGLE
+0xA1E9	0x22BF	#RIGHT TRIANGLE
+0xA1EA	0x33D2	#SQUARE LOG
+0xA1EB	0x33D1	#SQUARE LN
+0xA1EC	0x222B	#INTEGRAL
+0xA1ED	0x222E	#CONTOUR INTEGRAL
+0xA1EE	0x2235	#BECAUSE
+0xA1EF	0x2234	#THEREFORE
+0xA1F0	0x2640	#FEMALE SIGN
+0xA1F1	0x2642	#MALE SIGN
+0xA1F2	0x2295	#CIRCLED PLUS
+0xA1F3	0x2299	#CIRCLED DOT OPERATOR
+0xA1F4	0x2191	#UPWARDS ARROW
+0xA1F5	0x2193	#DOWNWARDS ARROW
+0xA1F6	0x2190	#LEFTWARDS ARROW
+0xA1F7	0x2192	#RIGHTWARDS ARROW
+0xA1F8	0x2196	#NORTH WEST ARROW
+0xA1F9	0x2197	#NORTH EAST ARROW
+0xA1FA	0x2199	#SOUTH WEST ARROW
+0xA1FB	0x2198	#SOUTH EAST ARROW
+0xA1FC	0x2225	#PARALLEL TO
+0xA1FD	0x2223	#DIVIDES
+0xA1FE	0xFF0F	#FULLWIDTH SOLIDUS
+0xA240	0xFF3C	#FULLWIDTH REVERSE SOLIDUS
+0xA241	0x2215	#DIVISION SLASH
+0xA242	0xFE68	#SMALL REVERSE SOLIDUS
+0xA243	0xFF04	#FULLWIDTH DOLLAR SIGN
+0xA244	0xFFE5	#FULLWIDTH YEN SIGN
+0xA245	0x3012	#POSTAL MARK
+0xA246	0xFFE0	#FULLWIDTH CENT SIGN
+0xA247	0xFFE1	#FULLWIDTH POUND SIGN
+0xA248	0xFF05	#FULLWIDTH PERCENT SIGN
+0xA249	0xFF20	#FULLWIDTH COMMERCIAL AT
+0xA24A	0x2103	#DEGREE CELSIUS
+0xA24B	0x2109	#DEGREE FAHRENHEIT
+0xA24C	0xFE69	#SMALL DOLLAR SIGN
+0xA24D	0xFE6A	#SMALL PERCENT SIGN
+0xA24E	0xFE6B	#SMALL COMMERCIAL AT
+0xA24F	0x33D5	#SQUARE MIL
+0xA250	0x339C	#SQUARE MM
+0xA251	0x339D	#SQUARE CM
+0xA252	0x339E	#SQUARE KM
+0xA253	0x33CE	#SQUARE KM CAPITAL
+0xA254	0x33A1	#SQUARE M SQUARED
+0xA255	0x338E	#SQUARE MG
+0xA256	0x338F	#SQUARE KG
+0xA257	0x33C4	#SQUARE CC
+0xA258	0x00B0	#DEGREE SIGN
+0xA259	0x5159	#CJK UNIFIED IDEOGRAPH
+0xA25A	0x515B	#CJK UNIFIED IDEOGRAPH
+0xA25B	0x515E	#CJK UNIFIED IDEOGRAPH
+0xA25C	0x515D	#CJK UNIFIED IDEOGRAPH
+0xA25D	0x5161	#CJK UNIFIED IDEOGRAPH
+0xA25E	0x5163	#CJK UNIFIED IDEOGRAPH
+0xA25F	0x55E7	#CJK UNIFIED IDEOGRAPH
+0xA260	0x74E9	#CJK UNIFIED IDEOGRAPH
+0xA261	0x7CCE	#CJK UNIFIED IDEOGRAPH
+0xA262	0x2581	#LOWER ONE EIGHTH BLOCK
+0xA263	0x2582	#LOWER ONE QUARTER BLOCK
+0xA264	0x2583	#LOWER THREE EIGHTHS BLOCK
+0xA265	0x2584	#LOWER HALF BLOCK
+0xA266	0x2585	#LOWER FIVE EIGHTHS BLOCK
+0xA267	0x2586	#LOWER THREE QUARTERS BLOCK
+0xA268	0x2587	#LOWER SEVEN EIGHTHS BLOCK
+0xA269	0x2588	#FULL BLOCK
+0xA26A	0x258F	#LEFT ONE EIGHTH BLOCK
+0xA26B	0x258E	#LEFT ONE QUARTER BLOCK
+0xA26C	0x258D	#LEFT THREE EIGHTHS BLOCK
+0xA26D	0x258C	#LEFT HALF BLOCK
+0xA26E	0x258B	#LEFT FIVE EIGHTHS BLOCK
+0xA26F	0x258A	#LEFT THREE QUARTERS BLOCK
+0xA270	0x2589	#LEFT SEVEN EIGHTHS BLOCK
+0xA271	0x253C	#BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
+0xA272	0x2534	#BOX DRAWINGS LIGHT UP AND HORIZONTAL
+0xA273	0x252C	#BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
+0xA274	0x2524	#BOX DRAWINGS LIGHT VERTICAL AND LEFT
+0xA275	0x251C	#BOX DRAWINGS LIGHT VERTICAL AND RIGHT
+0xA276	0x2594	#UPPER ONE EIGHTH BLOCK
+0xA277	0x2500	#BOX DRAWINGS LIGHT HORIZONTAL
+0xA278	0x2502	#BOX DRAWINGS LIGHT VERTICAL
+0xA279	0x2595	#RIGHT ONE EIGHTH BLOCK
+0xA27A	0x250C	#BOX DRAWINGS LIGHT DOWN AND RIGHT
+0xA27B	0x2510	#BOX DRAWINGS LIGHT DOWN AND LEFT
+0xA27C	0x2514	#BOX DRAWINGS LIGHT UP AND RIGHT
+0xA27D	0x2518	#BOX DRAWINGS LIGHT UP AND LEFT
+0xA27E	0x256D	#BOX DRAWINGS LIGHT ARC DOWN AND RIGHT
+0xA2A1	0x256E	#BOX DRAWINGS LIGHT ARC DOWN AND LEFT
+0xA2A2	0x2570	#BOX DRAWINGS LIGHT ARC UP AND RIGHT
+0xA2A3	0x256F	#BOX DRAWINGS LIGHT ARC UP AND LEFT
+0xA2A4	0x2550	#BOX DRAWINGS DOUBLE HORIZONTAL
+0xA2A5	0x255E	#BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE
+0xA2A6	0x256A	#BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE
+0xA2A7	0x2561	#BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE
+0xA2A8	0x25E2	#BLACK LOWER RIGHT TRIANGLE
+0xA2A9	0x25E3	#BLACK LOWER LEFT TRIANGLE
+0xA2AA	0x25E5	#BLACK UPPER RIGHT TRIANGLE
+0xA2AB	0x25E4	#BLACK UPPER LEFT TRIANGLE
+0xA2AC	0x2571	#BOX DRAWINGS LIGHT DIAGONAL UPPER RIGHT TO LOWER LEFT
+0xA2AD	0x2572	#BOX DRAWINGS LIGHT DIAGONAL UPPER LEFT TO LOWER RIGHT
+0xA2AE	0x2573	#BOX DRAWINGS LIGHT DIAGONAL CROSS
+0xA2AF	0xFF10	#FULLWIDTH DIGIT ZERO
+0xA2B0	0xFF11	#FULLWIDTH DIGIT ONE
+0xA2B1	0xFF12	#FULLWIDTH DIGIT TWO
+0xA2B2	0xFF13	#FULLWIDTH DIGIT THREE
+0xA2B3	0xFF14	#FULLWIDTH DIGIT FOUR
+0xA2B4	0xFF15	#FULLWIDTH DIGIT FIVE
+0xA2B5	0xFF16	#FULLWIDTH DIGIT SIX
+0xA2B6	0xFF17	#FULLWIDTH DIGIT SEVEN
+0xA2B7	0xFF18	#FULLWIDTH DIGIT EIGHT
+0xA2B8	0xFF19	#FULLWIDTH DIGIT NINE
+0xA2B9	0x2160	#ROMAN NUMERAL ONE
+0xA2BA	0x2161	#ROMAN NUMERAL TWO
+0xA2BB	0x2162	#ROMAN NUMERAL THREE
+0xA2BC	0x2163	#ROMAN NUMERAL FOUR
+0xA2BD	0x2164	#ROMAN NUMERAL FIVE
+0xA2BE	0x2165	#ROMAN NUMERAL SIX
+0xA2BF	0x2166	#ROMAN NUMERAL SEVEN
+0xA2C0	0x2167	#ROMAN NUMERAL EIGHT
+0xA2C1	0x2168	#ROMAN NUMERAL NINE
+0xA2C2	0x2169	#ROMAN NUMERAL TEN
+0xA2C3	0x3021	#HANGZHOU NUMERAL ONE
+0xA2C4	0x3022	#HANGZHOU NUMERAL TWO
+0xA2C5	0x3023	#HANGZHOU NUMERAL THREE
+0xA2C6	0x3024	#HANGZHOU NUMERAL FOUR
+0xA2C7	0x3025	#HANGZHOU NUMERAL FIVE
+0xA2C8	0x3026	#HANGZHOU NUMERAL SIX
+0xA2C9	0x3027	#HANGZHOU NUMERAL SEVEN
+0xA2CA	0x3028	#HANGZHOU NUMERAL EIGHT
+0xA2CB	0x3029	#HANGZHOU NUMERAL NINE
+0xA2CC	0x5341	#CJK UNIFIED IDEOGRAPH
+0xA2CD	0x5344	#CJK UNIFIED IDEOGRAPH
+0xA2CE	0x5345	#CJK UNIFIED IDEOGRAPH
+0xA2CF	0xFF21	#FULLWIDTH LATIN CAPITAL LETTER A
+0xA2D0	0xFF22	#FULLWIDTH LATIN CAPITAL LETTER B
+0xA2D1	0xFF23	#FULLWIDTH LATIN CAPITAL LETTER C
+0xA2D2	0xFF24	#FULLWIDTH LATIN CAPITAL LETTER D
+0xA2D3	0xFF25	#FULLWIDTH LATIN CAPITAL LETTER E
+0xA2D4	0xFF26	#FULLWIDTH LATIN CAPITAL LETTER F
+0xA2D5	0xFF27	#FULLWIDTH LATIN CAPITAL LETTER G
+0xA2D6	0xFF28	#FULLWIDTH LATIN CAPITAL LETTER H
+0xA2D7	0xFF29	#FULLWIDTH LATIN CAPITAL LETTER I
+0xA2D8	0xFF2A	#FULLWIDTH LATIN CAPITAL LETTER J
+0xA2D9	0xFF2B	#FULLWIDTH LATIN CAPITAL LETTER K
+0xA2DA	0xFF2C	#FULLWIDTH LATIN CAPITAL LETTER L
+0xA2DB	0xFF2D	#FULLWIDTH LATIN CAPITAL LETTER M
+0xA2DC	0xFF2E	#FULLWIDTH LATIN CAPITAL LETTER N
+0xA2DD	0xFF2F	#FULLWIDTH LATIN CAPITAL LETTER O
+0xA2DE	0xFF30	#FULLWIDTH LATIN CAPITAL LETTER P
+0xA2DF	0xFF31	#FULLWIDTH LATIN CAPITAL LETTER Q
+0xA2E0	0xFF32	#FULLWIDTH LATIN CAPITAL LETTER R
+0xA2E1	0xFF33	#FULLWIDTH LATIN CAPITAL LETTER S
+0xA2E2	0xFF34	#FULLWIDTH LATIN CAPITAL LETTER T
+0xA2E3	0xFF35	#FULLWIDTH LATIN CAPITAL LETTER U
+0xA2E4	0xFF36	#FULLWIDTH LATIN CAPITAL LETTER V
+0xA2E5	0xFF37	#FULLWIDTH LATIN CAPITAL LETTER W
+0xA2E6	0xFF38	#FULLWIDTH LATIN CAPITAL LETTER X
+0xA2E7	0xFF39	#FULLWIDTH LATIN CAPITAL LETTER Y
+0xA2E8	0xFF3A	#FULLWIDTH LATIN CAPITAL LETTER Z
+0xA2E9	0xFF41	#FULLWIDTH LATIN SMALL LETTER A
+0xA2EA	0xFF42	#FULLWIDTH LATIN SMALL LETTER B
+0xA2EB	0xFF43	#FULLWIDTH LATIN SMALL LETTER C
+0xA2EC	0xFF44	#FULLWIDTH LATIN SMALL LETTER D
+0xA2ED	0xFF45	#FULLWIDTH LATIN SMALL LETTER E
+0xA2EE	0xFF46	#FULLWIDTH LATIN SMALL LETTER F
+0xA2EF	0xFF47	#FULLWIDTH LATIN SMALL LETTER G
+0xA2F0	0xFF48	#FULLWIDTH LATIN SMALL LETTER H
+0xA2F1	0xFF49	#FULLWIDTH LATIN SMALL LETTER I
+0xA2F2	0xFF4A	#FULLWIDTH LATIN SMALL LETTER J
+0xA2F3	0xFF4B	#FULLWIDTH LATIN SMALL LETTER K
+0xA2F4	0xFF4C	#FULLWIDTH LATIN SMALL LETTER L
+0xA2F5	0xFF4D	#FULLWIDTH LATIN SMALL LETTER M
+0xA2F6	0xFF4E	#FULLWIDTH LATIN SMALL LETTER N
+0xA2F7	0xFF4F	#FULLWIDTH LATIN SMALL LETTER O
+0xA2F8	0xFF50	#FULLWIDTH LATIN SMALL LETTER P
+0xA2F9	0xFF51	#FULLWIDTH LATIN SMALL LETTER Q
+0xA2FA	0xFF52	#FULLWIDTH LATIN SMALL LETTER R
+0xA2FB	0xFF53	#FULLWIDTH LATIN SMALL LETTER S
+0xA2FC	0xFF54	#FULLWIDTH LATIN SMALL LETTER T
+0xA2FD	0xFF55	#FULLWIDTH LATIN SMALL LETTER U
+0xA2FE	0xFF56	#FULLWIDTH LATIN SMALL LETTER V
+0xA340	0xFF57	#FULLWIDTH LATIN SMALL LETTER W
+0xA341	0xFF58	#FULLWIDTH LATIN SMALL LETTER X
+0xA342	0xFF59	#FULLWIDTH LATIN SMALL LETTER Y
+0xA343	0xFF5A	#FULLWIDTH LATIN SMALL LETTER Z
+0xA344	0x0391	#GREEK CAPITAL LETTER ALPHA
+0xA345	0x0392	#GREEK CAPITAL LETTER BETA
+0xA346	0x0393	#GREEK CAPITAL LETTER GAMMA
+0xA347	0x0394	#GREEK CAPITAL LETTER DELTA
+0xA348	0x0395	#GREEK CAPITAL LETTER EPSILON
+0xA349	0x0396	#GREEK CAPITAL LETTER ZETA
+0xA34A	0x0397	#GREEK CAPITAL LETTER ETA
+0xA34B	0x0398	#GREEK CAPITAL LETTER THETA
+0xA34C	0x0399	#GREEK CAPITAL LETTER IOTA
+0xA34D	0x039A	#GREEK CAPITAL LETTER KAPPA
+0xA34E	0x039B	#GREEK CAPITAL LETTER LAMDA
+0xA34F	0x039C	#GREEK CAPITAL LETTER MU
+0xA350	0x039D	#GREEK CAPITAL LETTER NU
+0xA351	0x039E	#GREEK CAPITAL LETTER XI
+0xA352	0x039F	#GREEK CAPITAL LETTER OMICRON
+0xA353	0x03A0	#GREEK CAPITAL LETTER PI
+0xA354	0x03A1	#GREEK CAPITAL LETTER RHO
+0xA355	0x03A3	#GREEK CAPITAL LETTER SIGMA
+0xA356	0x03A4	#GREEK CAPITAL LETTER TAU
+0xA357	0x03A5	#GREEK CAPITAL LETTER UPSILON
+0xA358	0x03A6	#GREEK CAPITAL LETTER PHI
+0xA359	0x03A7	#GREEK CAPITAL LETTER CHI
+0xA35A	0x03A8	#GREEK CAPITAL LETTER PSI
+0xA35B	0x03A9	#GREEK CAPITAL LETTER OMEGA
+0xA35C	0x03B1	#GREEK SMALL LETTER ALPHA
+0xA35D	0x03B2	#GREEK SMALL LETTER BETA
+0xA35E	0x03B3	#GREEK SMALL LETTER GAMMA
+0xA35F	0x03B4	#GREEK SMALL LETTER DELTA
+0xA360	0x03B5	#GREEK SMALL LETTER EPSILON
+0xA361	0x03B6	#GREEK SMALL LETTER ZETA
+0xA362	0x03B7	#GREEK SMALL LETTER ETA
+0xA363	0x03B8	#GREEK SMALL LETTER THETA
+0xA364	0x03B9	#GREEK SMALL LETTER IOTA
+0xA365	0x03BA	#GREEK SMALL LETTER KAPPA
+0xA366	0x03BB	#GREEK SMALL LETTER LAMDA
+0xA367	0x03BC	#GREEK SMALL LETTER MU
+0xA368	0x03BD	#GREEK SMALL LETTER NU
+0xA369	0x03BE	#GREEK SMALL LETTER XI
+0xA36A	0x03BF	#GREEK SMALL LETTER OMICRON
+0xA36B	0x03C0	#GREEK SMALL LETTER PI
+0xA36C	0x03C1	#GREEK SMALL LETTER RHO
+0xA36D	0x03C3	#GREEK SMALL LETTER SIGMA
+0xA36E	0x03C4	#GREEK SMALL LETTER TAU
+0xA36F	0x03C5	#GREEK SMALL LETTER UPSILON
+0xA370	0x03C6	#GREEK SMALL LETTER PHI
+0xA371	0x03C7	#GREEK SMALL LETTER CHI
+0xA372	0x03C8	#GREEK SMALL LETTER PSI
+0xA373	0x03C9	#GREEK SMALL LETTER OMEGA
+0xA374	0x3105	#BOPOMOFO LETTER B
+0xA375	0x3106	#BOPOMOFO LETTER P
+0xA376	0x3107	#BOPOMOFO LETTER M
+0xA377	0x3108	#BOPOMOFO LETTER F
+0xA378	0x3109	#BOPOMOFO LETTER D
+0xA379	0x310A	#BOPOMOFO LETTER T
+0xA37A	0x310B	#BOPOMOFO LETTER N
+0xA37B	0x310C	#BOPOMOFO LETTER L
+0xA37C	0x310D	#BOPOMOFO LETTER G
+0xA37D	0x310E	#BOPOMOFO LETTER K
+0xA37E	0x310F	#BOPOMOFO LETTER H
+0xA3A1	0x3110	#BOPOMOFO LETTER J
+0xA3A2	0x3111	#BOPOMOFO LETTER Q
+0xA3A3	0x3112	#BOPOMOFO LETTER X
+0xA3A4	0x3113	#BOPOMOFO LETTER ZH
+0xA3A5	0x3114	#BOPOMOFO LETTER CH
+0xA3A6	0x3115	#BOPOMOFO LETTER SH
+0xA3A7	0x3116	#BOPOMOFO LETTER R
+0xA3A8	0x3117	#BOPOMOFO LETTER Z
+0xA3A9	0x3118	#BOPOMOFO LETTER C
+0xA3AA	0x3119	#BOPOMOFO LETTER S
+0xA3AB	0x311A	#BOPOMOFO LETTER A
+0xA3AC	0x311B	#BOPOMOFO LETTER O
+0xA3AD	0x311C	#BOPOMOFO LETTER E
+0xA3AE	0x311D	#BOPOMOFO LETTER EH
+0xA3AF	0x311E	#BOPOMOFO LETTER AI
+0xA3B0	0x311F	#BOPOMOFO LETTER EI
+0xA3B1	0x3120	#BOPOMOFO LETTER AU
+0xA3B2	0x3121	#BOPOMOFO LETTER OU
+0xA3B3	0x3122	#BOPOMOFO LETTER AN
+0xA3B4	0x3123	#BOPOMOFO LETTER EN
+0xA3B5	0x3124	#BOPOMOFO LETTER ANG
+0xA3B6	0x3125	#BOPOMOFO LETTER ENG
+0xA3B7	0x3126	#BOPOMOFO LETTER ER
+0xA3B8	0x3127	#BOPOMOFO LETTER I
+0xA3B9	0x3128	#BOPOMOFO LETTER U
+0xA3BA	0x3129	#BOPOMOFO LETTER IU
+0xA3BB	0x02D9	#DOT ABOVE
+0xA3BC	0x02C9	#MODIFIER LETTER MACRON
+0xA3BD	0x02CA	#MODIFIER LETTER ACUTE ACCENT
+0xA3BE	0x02C7	#CARON
+0xA3BF	0x02CB	#MODIFIER LETTER GRAVE ACCENT
+0xA3E1	0x20AC	#EURO SIGN
+0xA440	0x4E00	#CJK UNIFIED IDEOGRAPH
+0xA441	0x4E59	#CJK UNIFIED IDEOGRAPH
+0xA442	0x4E01	#CJK UNIFIED IDEOGRAPH
+0xA443	0x4E03	#CJK UNIFIED IDEOGRAPH
+0xA444	0x4E43	#CJK UNIFIED IDEOGRAPH
+0xA445	0x4E5D	#CJK UNIFIED IDEOGRAPH
+0xA446	0x4E86	#CJK UNIFIED IDEOGRAPH
+0xA447	0x4E8C	#CJK UNIFIED IDEOGRAPH
+0xA448	0x4EBA	#CJK UNIFIED IDEOGRAPH
+0xA449	0x513F	#CJK UNIFIED IDEOGRAPH
+0xA44A	0x5165	#CJK UNIFIED IDEOGRAPH
+0xA44B	0x516B	#CJK UNIFIED IDEOGRAPH
+0xA44C	0x51E0	#CJK UNIFIED IDEOGRAPH
+0xA44D	0x5200	#CJK UNIFIED IDEOGRAPH
+0xA44E	0x5201	#CJK UNIFIED IDEOGRAPH
+0xA44F	0x529B	#CJK UNIFIED IDEOGRAPH
+0xA450	0x5315	#CJK UNIFIED IDEOGRAPH
+0xA451	0x5341	#CJK UNIFIED IDEOGRAPH
+0xA452	0x535C	#CJK UNIFIED IDEOGRAPH
+0xA453	0x53C8	#CJK UNIFIED IDEOGRAPH
+0xA454	0x4E09	#CJK UNIFIED IDEOGRAPH
+0xA455	0x4E0B	#CJK UNIFIED IDEOGRAPH
+0xA456	0x4E08	#CJK UNIFIED IDEOGRAPH
+0xA457	0x4E0A	#CJK UNIFIED IDEOGRAPH
+0xA458	0x4E2B	#CJK UNIFIED IDEOGRAPH
+0xA459	0x4E38	#CJK UNIFIED IDEOGRAPH
+0xA45A	0x51E1	#CJK UNIFIED IDEOGRAPH
+0xA45B	0x4E45	#CJK UNIFIED IDEOGRAPH
+0xA45C	0x4E48	#CJK UNIFIED IDEOGRAPH
+0xA45D	0x4E5F	#CJK UNIFIED IDEOGRAPH
+0xA45E	0x4E5E	#CJK UNIFIED IDEOGRAPH
+0xA45F	0x4E8E	#CJK UNIFIED IDEOGRAPH
+0xA460	0x4EA1	#CJK UNIFIED IDEOGRAPH
+0xA461	0x5140	#CJK UNIFIED IDEOGRAPH
+0xA462	0x5203	#CJK UNIFIED IDEOGRAPH
+0xA463	0x52FA	#CJK UNIFIED IDEOGRAPH
+0xA464	0x5343	#CJK UNIFIED IDEOGRAPH
+0xA465	0x53C9	#CJK UNIFIED IDEOGRAPH
+0xA466	0x53E3	#CJK UNIFIED IDEOGRAPH
+0xA467	0x571F	#CJK UNIFIED IDEOGRAPH
+0xA468	0x58EB	#CJK UNIFIED IDEOGRAPH
+0xA469	0x5915	#CJK UNIFIED IDEOGRAPH
+0xA46A	0x5927	#CJK UNIFIED IDEOGRAPH
+0xA46B	0x5973	#CJK UNIFIED IDEOGRAPH
+0xA46C	0x5B50	#CJK UNIFIED IDEOGRAPH
+0xA46D	0x5B51	#CJK UNIFIED IDEOGRAPH
+0xA46E	0x5B53	#CJK UNIFIED IDEOGRAPH
+0xA46F	0x5BF8	#CJK UNIFIED IDEOGRAPH
+0xA470	0x5C0F	#CJK UNIFIED IDEOGRAPH
+0xA471	0x5C22	#CJK UNIFIED IDEOGRAPH
+0xA472	0x5C38	#CJK UNIFIED IDEOGRAPH
+0xA473	0x5C71	#CJK UNIFIED IDEOGRAPH
+0xA474	0x5DDD	#CJK UNIFIED IDEOGRAPH
+0xA475	0x5DE5	#CJK UNIFIED IDEOGRAPH
+0xA476	0x5DF1	#CJK UNIFIED IDEOGRAPH
+0xA477	0x5DF2	#CJK UNIFIED IDEOGRAPH
+0xA478	0x5DF3	#CJK UNIFIED IDEOGRAPH
+0xA479	0x5DFE	#CJK UNIFIED IDEOGRAPH
+0xA47A	0x5E72	#CJK UNIFIED IDEOGRAPH
+0xA47B	0x5EFE	#CJK UNIFIED IDEOGRAPH
+0xA47C	0x5F0B	#CJK UNIFIED IDEOGRAPH
+0xA47D	0x5F13	#CJK UNIFIED IDEOGRAPH
+0xA47E	0x624D	#CJK UNIFIED IDEOGRAPH
+0xA4A1	0x4E11	#CJK UNIFIED IDEOGRAPH
+0xA4A2	0x4E10	#CJK UNIFIED IDEOGRAPH
+0xA4A3	0x4E0D	#CJK UNIFIED IDEOGRAPH
+0xA4A4	0x4E2D	#CJK UNIFIED IDEOGRAPH
+0xA4A5	0x4E30	#CJK UNIFIED IDEOGRAPH
+0xA4A6	0x4E39	#CJK UNIFIED IDEOGRAPH
+0xA4A7	0x4E4B	#CJK UNIFIED IDEOGRAPH
+0xA4A8	0x5C39	#CJK UNIFIED IDEOGRAPH
+0xA4A9	0x4E88	#CJK UNIFIED IDEOGRAPH
+0xA4AA	0x4E91	#CJK UNIFIED IDEOGRAPH
+0xA4AB	0x4E95	#CJK UNIFIED IDEOGRAPH
+0xA4AC	0x4E92	#CJK UNIFIED IDEOGRAPH
+0xA4AD	0x4E94	#CJK UNIFIED IDEOGRAPH
+0xA4AE	0x4EA2	#CJK UNIFIED IDEOGRAPH
+0xA4AF	0x4EC1	#CJK UNIFIED IDEOGRAPH
+0xA4B0	0x4EC0	#CJK UNIFIED IDEOGRAPH
+0xA4B1	0x4EC3	#CJK UNIFIED IDEOGRAPH
+0xA4B2	0x4EC6	#CJK UNIFIED IDEOGRAPH
+0xA4B3	0x4EC7	#CJK UNIFIED IDEOGRAPH
+0xA4B4	0x4ECD	#CJK UNIFIED IDEOGRAPH
+0xA4B5	0x4ECA	#CJK UNIFIED IDEOGRAPH
+0xA4B6	0x4ECB	#CJK UNIFIED IDEOGRAPH
+0xA4B7	0x4EC4	#CJK UNIFIED IDEOGRAPH
+0xA4B8	0x5143	#CJK UNIFIED IDEOGRAPH
+0xA4B9	0x5141	#CJK UNIFIED IDEOGRAPH
+0xA4BA	0x5167	#CJK UNIFIED IDEOGRAPH
+0xA4BB	0x516D	#CJK UNIFIED IDEOGRAPH
+0xA4BC	0x516E	#CJK UNIFIED IDEOGRAPH
+0xA4BD	0x516C	#CJK UNIFIED IDEOGRAPH
+0xA4BE	0x5197	#CJK UNIFIED IDEOGRAPH
+0xA4BF	0x51F6	#CJK UNIFIED IDEOGRAPH
+0xA4C0	0x5206	#CJK UNIFIED IDEOGRAPH
+0xA4C1	0x5207	#CJK UNIFIED IDEOGRAPH
+0xA4C2	0x5208	#CJK UNIFIED IDEOGRAPH
+0xA4C3	0x52FB	#CJK UNIFIED IDEOGRAPH
+0xA4C4	0x52FE	#CJK UNIFIED IDEOGRAPH
+0xA4C5	0x52FF	#CJK UNIFIED IDEOGRAPH
+0xA4C6	0x5316	#CJK UNIFIED IDEOGRAPH
+0xA4C7	0x5339	#CJK UNIFIED IDEOGRAPH
+0xA4C8	0x5348	#CJK UNIFIED IDEOGRAPH
+0xA4C9	0x5347	#CJK UNIFIED IDEOGRAPH
+0xA4CA	0x5345	#CJK UNIFIED IDEOGRAPH
+0xA4CB	0x535E	#CJK UNIFIED IDEOGRAPH
+0xA4CC	0x5384	#CJK UNIFIED IDEOGRAPH
+0xA4CD	0x53CB	#CJK UNIFIED IDEOGRAPH
+0xA4CE	0x53CA	#CJK UNIFIED IDEOGRAPH
+0xA4CF	0x53CD	#CJK UNIFIED IDEOGRAPH
+0xA4D0	0x58EC	#CJK UNIFIED IDEOGRAPH
+0xA4D1	0x5929	#CJK UNIFIED IDEOGRAPH
+0xA4D2	0x592B	#CJK UNIFIED IDEOGRAPH
+0xA4D3	0x592A	#CJK UNIFIED IDEOGRAPH
+0xA4D4	0x592D	#CJK UNIFIED IDEOGRAPH
+0xA4D5	0x5B54	#CJK UNIFIED IDEOGRAPH
+0xA4D6	0x5C11	#CJK UNIFIED IDEOGRAPH
+0xA4D7	0x5C24	#CJK UNIFIED IDEOGRAPH
+0xA4D8	0x5C3A	#CJK UNIFIED IDEOGRAPH
+0xA4D9	0x5C6F	#CJK UNIFIED IDEOGRAPH
+0xA4DA	0x5DF4	#CJK UNIFIED IDEOGRAPH
+0xA4DB	0x5E7B	#CJK UNIFIED IDEOGRAPH
+0xA4DC	0x5EFF	#CJK UNIFIED IDEOGRAPH
+0xA4DD	0x5F14	#CJK UNIFIED IDEOGRAPH
+0xA4DE	0x5F15	#CJK UNIFIED IDEOGRAPH
+0xA4DF	0x5FC3	#CJK UNIFIED IDEOGRAPH
+0xA4E0	0x6208	#CJK UNIFIED IDEOGRAPH
+0xA4E1	0x6236	#CJK UNIFIED IDEOGRAPH
+0xA4E2	0x624B	#CJK UNIFIED IDEOGRAPH
+0xA4E3	0x624E	#CJK UNIFIED IDEOGRAPH
+0xA4E4	0x652F	#CJK UNIFIED IDEOGRAPH
+0xA4E5	0x6587	#CJK UNIFIED IDEOGRAPH
+0xA4E6	0x6597	#CJK UNIFIED IDEOGRAPH
+0xA4E7	0x65A4	#CJK UNIFIED IDEOGRAPH
+0xA4E8	0x65B9	#CJK UNIFIED IDEOGRAPH
+0xA4E9	0x65E5	#CJK UNIFIED IDEOGRAPH
+0xA4EA	0x66F0	#CJK UNIFIED IDEOGRAPH
+0xA4EB	0x6708	#CJK UNIFIED IDEOGRAPH
+0xA4EC	0x6728	#CJK UNIFIED IDEOGRAPH
+0xA4ED	0x6B20	#CJK UNIFIED IDEOGRAPH
+0xA4EE	0x6B62	#CJK UNIFIED IDEOGRAPH
+0xA4EF	0x6B79	#CJK UNIFIED IDEOGRAPH
+0xA4F0	0x6BCB	#CJK UNIFIED IDEOGRAPH
+0xA4F1	0x6BD4	#CJK UNIFIED IDEOGRAPH
+0xA4F2	0x6BDB	#CJK UNIFIED IDEOGRAPH
+0xA4F3	0x6C0F	#CJK UNIFIED IDEOGRAPH
+0xA4F4	0x6C34	#CJK UNIFIED IDEOGRAPH
+0xA4F5	0x706B	#CJK UNIFIED IDEOGRAPH
+0xA4F6	0x722A	#CJK UNIFIED IDEOGRAPH
+0xA4F7	0x7236	#CJK UNIFIED IDEOGRAPH
+0xA4F8	0x723B	#CJK UNIFIED IDEOGRAPH
+0xA4F9	0x7247	#CJK UNIFIED IDEOGRAPH
+0xA4FA	0x7259	#CJK UNIFIED IDEOGRAPH
+0xA4FB	0x725B	#CJK UNIFIED IDEOGRAPH
+0xA4FC	0x72AC	#CJK UNIFIED IDEOGRAPH
+0xA4FD	0x738B	#CJK UNIFIED IDEOGRAPH
+0xA4FE	0x4E19	#CJK UNIFIED IDEOGRAPH
+0xA540	0x4E16	#CJK UNIFIED IDEOGRAPH
+0xA541	0x4E15	#CJK UNIFIED IDEOGRAPH
+0xA542	0x4E14	#CJK UNIFIED IDEOGRAPH
+0xA543	0x4E18	#CJK UNIFIED IDEOGRAPH
+0xA544	0x4E3B	#CJK UNIFIED IDEOGRAPH
+0xA545	0x4E4D	#CJK UNIFIED IDEOGRAPH
+0xA546	0x4E4F	#CJK UNIFIED IDEOGRAPH
+0xA547	0x4E4E	#CJK UNIFIED IDEOGRAPH
+0xA548	0x4EE5	#CJK UNIFIED IDEOGRAPH
+0xA549	0x4ED8	#CJK UNIFIED IDEOGRAPH
+0xA54A	0x4ED4	#CJK UNIFIED IDEOGRAPH
+0xA54B	0x4ED5	#CJK UNIFIED IDEOGRAPH
+0xA54C	0x4ED6	#CJK UNIFIED IDEOGRAPH
+0xA54D	0x4ED7	#CJK UNIFIED IDEOGRAPH
+0xA54E	0x4EE3	#CJK UNIFIED IDEOGRAPH
+0xA54F	0x4EE4	#CJK UNIFIED IDEOGRAPH
+0xA550	0x4ED9	#CJK UNIFIED IDEOGRAPH
+0xA551	0x4EDE	#CJK UNIFIED IDEOGRAPH
+0xA552	0x5145	#CJK UNIFIED IDEOGRAPH
+0xA553	0x5144	#CJK UNIFIED IDEOGRAPH
+0xA554	0x5189	#CJK UNIFIED IDEOGRAPH
+0xA555	0x518A	#CJK UNIFIED IDEOGRAPH
+0xA556	0x51AC	#CJK UNIFIED IDEOGRAPH
+0xA557	0x51F9	#CJK UNIFIED IDEOGRAPH
+0xA558	0x51FA	#CJK UNIFIED IDEOGRAPH
+0xA559	0x51F8	#CJK UNIFIED IDEOGRAPH
+0xA55A	0x520A	#CJK UNIFIED IDEOGRAPH
+0xA55B	0x52A0	#CJK UNIFIED IDEOGRAPH
+0xA55C	0x529F	#CJK UNIFIED IDEOGRAPH
+0xA55D	0x5305	#CJK UNIFIED IDEOGRAPH
+0xA55E	0x5306	#CJK UNIFIED IDEOGRAPH
+0xA55F	0x5317	#CJK UNIFIED IDEOGRAPH
+0xA560	0x531D	#CJK UNIFIED IDEOGRAPH
+0xA561	0x4EDF	#CJK UNIFIED IDEOGRAPH
+0xA562	0x534A	#CJK UNIFIED IDEOGRAPH
+0xA563	0x5349	#CJK UNIFIED IDEOGRAPH
+0xA564	0x5361	#CJK UNIFIED IDEOGRAPH
+0xA565	0x5360	#CJK UNIFIED IDEOGRAPH
+0xA566	0x536F	#CJK UNIFIED IDEOGRAPH
+0xA567	0x536E	#CJK UNIFIED IDEOGRAPH
+0xA568	0x53BB	#CJK UNIFIED IDEOGRAPH
+0xA569	0x53EF	#CJK UNIFIED IDEOGRAPH
+0xA56A	0x53E4	#CJK UNIFIED IDEOGRAPH
+0xA56B	0x53F3	#CJK UNIFIED IDEOGRAPH
+0xA56C	0x53EC	#CJK UNIFIED IDEOGRAPH
+0xA56D	0x53EE	#CJK UNIFIED IDEOGRAPH
+0xA56E	0x53E9	#CJK UNIFIED IDEOGRAPH
+0xA56F	0x53E8	#CJK UNIFIED IDEOGRAPH
+0xA570	0x53FC	#CJK UNIFIED IDEOGRAPH
+0xA571	0x53F8	#CJK UNIFIED IDEOGRAPH
+0xA572	0x53F5	#CJK UNIFIED IDEOGRAPH
+0xA573	0x53EB	#CJK UNIFIED IDEOGRAPH
+0xA574	0x53E6	#CJK UNIFIED IDEOGRAPH
+0xA575	0x53EA	#CJK UNIFIED IDEOGRAPH
+0xA576	0x53F2	#CJK UNIFIED IDEOGRAPH
+0xA577	0x53F1	#CJK UNIFIED IDEOGRAPH
+0xA578	0x53F0	#CJK UNIFIED IDEOGRAPH
+0xA579	0x53E5	#CJK UNIFIED IDEOGRAPH
+0xA57A	0x53ED	#CJK UNIFIED IDEOGRAPH
+0xA57B	0x53FB	#CJK UNIFIED IDEOGRAPH
+0xA57C	0x56DB	#CJK UNIFIED IDEOGRAPH
+0xA57D	0x56DA	#CJK UNIFIED IDEOGRAPH
+0xA57E	0x5916	#CJK UNIFIED IDEOGRAPH
+0xA5A1	0x592E	#CJK UNIFIED IDEOGRAPH
+0xA5A2	0x5931	#CJK UNIFIED IDEOGRAPH
+0xA5A3	0x5974	#CJK UNIFIED IDEOGRAPH
+0xA5A4	0x5976	#CJK UNIFIED IDEOGRAPH
+0xA5A5	0x5B55	#CJK UNIFIED IDEOGRAPH
+0xA5A6	0x5B83	#CJK UNIFIED IDEOGRAPH
+0xA5A7	0x5C3C	#CJK UNIFIED IDEOGRAPH
+0xA5A8	0x5DE8	#CJK UNIFIED IDEOGRAPH
+0xA5A9	0x5DE7	#CJK UNIFIED IDEOGRAPH
+0xA5AA	0x5DE6	#CJK UNIFIED IDEOGRAPH
+0xA5AB	0x5E02	#CJK UNIFIED IDEOGRAPH
+0xA5AC	0x5E03	#CJK UNIFIED IDEOGRAPH
+0xA5AD	0x5E73	#CJK UNIFIED IDEOGRAPH
+0xA5AE	0x5E7C	#CJK UNIFIED IDEOGRAPH
+0xA5AF	0x5F01	#CJK UNIFIED IDEOGRAPH
+0xA5B0	0x5F18	#CJK UNIFIED IDEOGRAPH
+0xA5B1	0x5F17	#CJK UNIFIED IDEOGRAPH
+0xA5B2	0x5FC5	#CJK UNIFIED IDEOGRAPH
+0xA5B3	0x620A	#CJK UNIFIED IDEOGRAPH
+0xA5B4	0x6253	#CJK UNIFIED IDEOGRAPH
+0xA5B5	0x6254	#CJK UNIFIED IDEOGRAPH
+0xA5B6	0x6252	#CJK UNIFIED IDEOGRAPH
+0xA5B7	0x6251	#CJK UNIFIED IDEOGRAPH
+0xA5B8	0x65A5	#CJK UNIFIED IDEOGRAPH
+0xA5B9	0x65E6	#CJK UNIFIED IDEOGRAPH
+0xA5BA	0x672E	#CJK UNIFIED IDEOGRAPH
+0xA5BB	0x672C	#CJK UNIFIED IDEOGRAPH
+0xA5BC	0x672A	#CJK UNIFIED IDEOGRAPH
+0xA5BD	0x672B	#CJK UNIFIED IDEOGRAPH
+0xA5BE	0x672D	#CJK UNIFIED IDEOGRAPH
+0xA5BF	0x6B63	#CJK UNIFIED IDEOGRAPH
+0xA5C0	0x6BCD	#CJK UNIFIED IDEOGRAPH
+0xA5C1	0x6C11	#CJK UNIFIED IDEOGRAPH
+0xA5C2	0x6C10	#CJK UNIFIED IDEOGRAPH
+0xA5C3	0x6C38	#CJK UNIFIED IDEOGRAPH
+0xA5C4	0x6C41	#CJK UNIFIED IDEOGRAPH
+0xA5C5	0x6C40	#CJK UNIFIED IDEOGRAPH
+0xA5C6	0x6C3E	#CJK UNIFIED IDEOGRAPH
+0xA5C7	0x72AF	#CJK UNIFIED IDEOGRAPH
+0xA5C8	0x7384	#CJK UNIFIED IDEOGRAPH
+0xA5C9	0x7389	#CJK UNIFIED IDEOGRAPH
+0xA5CA	0x74DC	#CJK UNIFIED IDEOGRAPH
+0xA5CB	0x74E6	#CJK UNIFIED IDEOGRAPH
+0xA5CC	0x7518	#CJK UNIFIED IDEOGRAPH
+0xA5CD	0x751F	#CJK UNIFIED IDEOGRAPH
+0xA5CE	0x7528	#CJK UNIFIED IDEOGRAPH
+0xA5CF	0x7529	#CJK UNIFIED IDEOGRAPH
+0xA5D0	0x7530	#CJK UNIFIED IDEOGRAPH
+0xA5D1	0x7531	#CJK UNIFIED IDEOGRAPH
+0xA5D2	0x7532	#CJK UNIFIED IDEOGRAPH
+0xA5D3	0x7533	#CJK UNIFIED IDEOGRAPH
+0xA5D4	0x758B	#CJK UNIFIED IDEOGRAPH
+0xA5D5	0x767D	#CJK UNIFIED IDEOGRAPH
+0xA5D6	0x76AE	#CJK UNIFIED IDEOGRAPH
+0xA5D7	0x76BF	#CJK UNIFIED IDEOGRAPH
+0xA5D8	0x76EE	#CJK UNIFIED IDEOGRAPH
+0xA5D9	0x77DB	#CJK UNIFIED IDEOGRAPH
+0xA5DA	0x77E2	#CJK UNIFIED IDEOGRAPH
+0xA5DB	0x77F3	#CJK UNIFIED IDEOGRAPH
+0xA5DC	0x793A	#CJK UNIFIED IDEOGRAPH
+0xA5DD	0x79BE	#CJK UNIFIED IDEOGRAPH
+0xA5DE	0x7A74	#CJK UNIFIED IDEOGRAPH
+0xA5DF	0x7ACB	#CJK UNIFIED IDEOGRAPH
+0xA5E0	0x4E1E	#CJK UNIFIED IDEOGRAPH
+0xA5E1	0x4E1F	#CJK UNIFIED IDEOGRAPH
+0xA5E2	0x4E52	#CJK UNIFIED IDEOGRAPH
+0xA5E3	0x4E53	#CJK UNIFIED IDEOGRAPH
+0xA5E4	0x4E69	#CJK UNIFIED IDEOGRAPH
+0xA5E5	0x4E99	#CJK UNIFIED IDEOGRAPH
+0xA5E6	0x4EA4	#CJK UNIFIED IDEOGRAPH
+0xA5E7	0x4EA6	#CJK UNIFIED IDEOGRAPH
+0xA5E8	0x4EA5	#CJK UNIFIED IDEOGRAPH
+0xA5E9	0x4EFF	#CJK UNIFIED IDEOGRAPH
+0xA5EA	0x4F09	#CJK UNIFIED IDEOGRAPH
+0xA5EB	0x4F19	#CJK UNIFIED IDEOGRAPH
+0xA5EC	0x4F0A	#CJK UNIFIED IDEOGRAPH
+0xA5ED	0x4F15	#CJK UNIFIED IDEOGRAPH
+0xA5EE	0x4F0D	#CJK UNIFIED IDEOGRAPH
+0xA5EF	0x4F10	#CJK UNIFIED IDEOGRAPH
+0xA5F0	0x4F11	#CJK UNIFIED IDEOGRAPH
+0xA5F1	0x4F0F	#CJK UNIFIED IDEOGRAPH
+0xA5F2	0x4EF2	#CJK UNIFIED IDEOGRAPH
+0xA5F3	0x4EF6	#CJK UNIFIED IDEOGRAPH
+0xA5F4	0x4EFB	#CJK UNIFIED IDEOGRAPH
+0xA5F5	0x4EF0	#CJK UNIFIED IDEOGRAPH
+0xA5F6	0x4EF3	#CJK UNIFIED IDEOGRAPH
+0xA5F7	0x4EFD	#CJK UNIFIED IDEOGRAPH
+0xA5F8	0x4F01	#CJK UNIFIED IDEOGRAPH
+0xA5F9	0x4F0B	#CJK UNIFIED IDEOGRAPH
+0xA5FA	0x5149	#CJK UNIFIED IDEOGRAPH
+0xA5FB	0x5147	#CJK UNIFIED IDEOGRAPH
+0xA5FC	0x5146	#CJK UNIFIED IDEOGRAPH
+0xA5FD	0x5148	#CJK UNIFIED IDEOGRAPH
+0xA5FE	0x5168	#CJK UNIFIED IDEOGRAPH
+0xA640	0x5171	#CJK UNIFIED IDEOGRAPH
+0xA641	0x518D	#CJK UNIFIED IDEOGRAPH
+0xA642	0x51B0	#CJK UNIFIED IDEOGRAPH
+0xA643	0x5217	#CJK UNIFIED IDEOGRAPH
+0xA644	0x5211	#CJK UNIFIED IDEOGRAPH
+0xA645	0x5212	#CJK UNIFIED IDEOGRAPH
+0xA646	0x520E	#CJK UNIFIED IDEOGRAPH
+0xA647	0x5216	#CJK UNIFIED IDEOGRAPH
+0xA648	0x52A3	#CJK UNIFIED IDEOGRAPH
+0xA649	0x5308	#CJK UNIFIED IDEOGRAPH
+0xA64A	0x5321	#CJK UNIFIED IDEOGRAPH
+0xA64B	0x5320	#CJK UNIFIED IDEOGRAPH
+0xA64C	0x5370	#CJK UNIFIED IDEOGRAPH
+0xA64D	0x5371	#CJK UNIFIED IDEOGRAPH
+0xA64E	0x5409	#CJK UNIFIED IDEOGRAPH
+0xA64F	0x540F	#CJK UNIFIED IDEOGRAPH
+0xA650	0x540C	#CJK UNIFIED IDEOGRAPH
+0xA651	0x540A	#CJK UNIFIED IDEOGRAPH
+0xA652	0x5410	#CJK UNIFIED IDEOGRAPH
+0xA653	0x5401	#CJK UNIFIED IDEOGRAPH
+0xA654	0x540B	#CJK UNIFIED IDEOGRAPH
+0xA655	0x5404	#CJK UNIFIED IDEOGRAPH
+0xA656	0x5411	#CJK UNIFIED IDEOGRAPH
+0xA657	0x540D	#CJK UNIFIED IDEOGRAPH
+0xA658	0x5408	#CJK UNIFIED IDEOGRAPH
+0xA659	0x5403	#CJK UNIFIED IDEOGRAPH
+0xA65A	0x540E	#CJK UNIFIED IDEOGRAPH
+0xA65B	0x5406	#CJK UNIFIED IDEOGRAPH
+0xA65C	0x5412	#CJK UNIFIED IDEOGRAPH
+0xA65D	0x56E0	#CJK UNIFIED IDEOGRAPH
+0xA65E	0x56DE	#CJK UNIFIED IDEOGRAPH
+0xA65F	0x56DD	#CJK UNIFIED IDEOGRAPH
+0xA660	0x5733	#CJK UNIFIED IDEOGRAPH
+0xA661	0x5730	#CJK UNIFIED IDEOGRAPH
+0xA662	0x5728	#CJK UNIFIED IDEOGRAPH
+0xA663	0x572D	#CJK UNIFIED IDEOGRAPH
+0xA664	0x572C	#CJK UNIFIED IDEOGRAPH
+0xA665	0x572F	#CJK UNIFIED IDEOGRAPH
+0xA666	0x5729	#CJK UNIFIED IDEOGRAPH
+0xA667	0x5919	#CJK UNIFIED IDEOGRAPH
+0xA668	0x591A	#CJK UNIFIED IDEOGRAPH
+0xA669	0x5937	#CJK UNIFIED IDEOGRAPH
+0xA66A	0x5938	#CJK UNIFIED IDEOGRAPH
+0xA66B	0x5984	#CJK UNIFIED IDEOGRAPH
+0xA66C	0x5978	#CJK UNIFIED IDEOGRAPH
+0xA66D	0x5983	#CJK UNIFIED IDEOGRAPH
+0xA66E	0x597D	#CJK UNIFIED IDEOGRAPH
+0xA66F	0x5979	#CJK UNIFIED IDEOGRAPH
+0xA670	0x5982	#CJK UNIFIED IDEOGRAPH
+0xA671	0x5981	#CJK UNIFIED IDEOGRAPH
+0xA672	0x5B57	#CJK UNIFIED IDEOGRAPH
+0xA673	0x5B58	#CJK UNIFIED IDEOGRAPH
+0xA674	0x5B87	#CJK UNIFIED IDEOGRAPH
+0xA675	0x5B88	#CJK UNIFIED IDEOGRAPH
+0xA676	0x5B85	#CJK UNIFIED IDEOGRAPH
+0xA677	0x5B89	#CJK UNIFIED IDEOGRAPH
+0xA678	0x5BFA	#CJK UNIFIED IDEOGRAPH
+0xA679	0x5C16	#CJK UNIFIED IDEOGRAPH
+0xA67A	0x5C79	#CJK UNIFIED IDEOGRAPH
+0xA67B	0x5DDE	#CJK UNIFIED IDEOGRAPH
+0xA67C	0x5E06	#CJK UNIFIED IDEOGRAPH
+0xA67D	0x5E76	#CJK UNIFIED IDEOGRAPH
+0xA67E	0x5E74	#CJK UNIFIED IDEOGRAPH
+0xA6A1	0x5F0F	#CJK UNIFIED IDEOGRAPH
+0xA6A2	0x5F1B	#CJK UNIFIED IDEOGRAPH
+0xA6A3	0x5FD9	#CJK UNIFIED IDEOGRAPH
+0xA6A4	0x5FD6	#CJK UNIFIED IDEOGRAPH
+0xA6A5	0x620E	#CJK UNIFIED IDEOGRAPH
+0xA6A6	0x620C	#CJK UNIFIED IDEOGRAPH
+0xA6A7	0x620D	#CJK UNIFIED IDEOGRAPH
+0xA6A8	0x6210	#CJK UNIFIED IDEOGRAPH
+0xA6A9	0x6263	#CJK UNIFIED IDEOGRAPH
+0xA6AA	0x625B	#CJK UNIFIED IDEOGRAPH
+0xA6AB	0x6258	#CJK UNIFIED IDEOGRAPH
+0xA6AC	0x6536	#CJK UNIFIED IDEOGRAPH
+0xA6AD	0x65E9	#CJK UNIFIED IDEOGRAPH
+0xA6AE	0x65E8	#CJK UNIFIED IDEOGRAPH
+0xA6AF	0x65EC	#CJK UNIFIED IDEOGRAPH
+0xA6B0	0x65ED	#CJK UNIFIED IDEOGRAPH
+0xA6B1	0x66F2	#CJK UNIFIED IDEOGRAPH
+0xA6B2	0x66F3	#CJK UNIFIED IDEOGRAPH
+0xA6B3	0x6709	#CJK UNIFIED IDEOGRAPH
+0xA6B4	0x673D	#CJK UNIFIED IDEOGRAPH
+0xA6B5	0x6734	#CJK UNIFIED IDEOGRAPH
+0xA6B6	0x6731	#CJK UNIFIED IDEOGRAPH
+0xA6B7	0x6735	#CJK UNIFIED IDEOGRAPH
+0xA6B8	0x6B21	#CJK UNIFIED IDEOGRAPH
+0xA6B9	0x6B64	#CJK UNIFIED IDEOGRAPH
+0xA6BA	0x6B7B	#CJK UNIFIED IDEOGRAPH
+0xA6BB	0x6C16	#CJK UNIFIED IDEOGRAPH
+0xA6BC	0x6C5D	#CJK UNIFIED IDEOGRAPH
+0xA6BD	0x6C57	#CJK UNIFIED IDEOGRAPH
+0xA6BE	0x6C59	#CJK UNIFIED IDEOGRAPH
+0xA6BF	0x6C5F	#CJK UNIFIED IDEOGRAPH
+0xA6C0	0x6C60	#CJK UNIFIED IDEOGRAPH
+0xA6C1	0x6C50	#CJK UNIFIED IDEOGRAPH
+0xA6C2	0x6C55	#CJK UNIFIED IDEOGRAPH
+0xA6C3	0x6C61	#CJK UNIFIED IDEOGRAPH
+0xA6C4	0x6C5B	#CJK UNIFIED IDEOGRAPH
+0xA6C5	0x6C4D	#CJK UNIFIED IDEOGRAPH
+0xA6C6	0x6C4E	#CJK UNIFIED IDEOGRAPH
+0xA6C7	0x7070	#CJK UNIFIED IDEOGRAPH
+0xA6C8	0x725F	#CJK UNIFIED IDEOGRAPH
+0xA6C9	0x725D	#CJK UNIFIED IDEOGRAPH
+0xA6CA	0x767E	#CJK UNIFIED IDEOGRAPH
+0xA6CB	0x7AF9	#CJK UNIFIED IDEOGRAPH
+0xA6CC	0x7C73	#CJK UNIFIED IDEOGRAPH
+0xA6CD	0x7CF8	#CJK UNIFIED IDEOGRAPH
+0xA6CE	0x7F36	#CJK UNIFIED IDEOGRAPH
+0xA6CF	0x7F8A	#CJK UNIFIED IDEOGRAPH
+0xA6D0	0x7FBD	#CJK UNIFIED IDEOGRAPH
+0xA6D1	0x8001	#CJK UNIFIED IDEOGRAPH
+0xA6D2	0x8003	#CJK UNIFIED IDEOGRAPH
+0xA6D3	0x800C	#CJK UNIFIED IDEOGRAPH
+0xA6D4	0x8012	#CJK UNIFIED IDEOGRAPH
+0xA6D5	0x8033	#CJK UNIFIED IDEOGRAPH
+0xA6D6	0x807F	#CJK UNIFIED IDEOGRAPH
+0xA6D7	0x8089	#CJK UNIFIED IDEOGRAPH
+0xA6D8	0x808B	#CJK UNIFIED IDEOGRAPH
+0xA6D9	0x808C	#CJK UNIFIED IDEOGRAPH
+0xA6DA	0x81E3	#CJK UNIFIED IDEOGRAPH
+0xA6DB	0x81EA	#CJK UNIFIED IDEOGRAPH
+0xA6DC	0x81F3	#CJK UNIFIED IDEOGRAPH
+0xA6DD	0x81FC	#CJK UNIFIED IDEOGRAPH
+0xA6DE	0x820C	#CJK UNIFIED IDEOGRAPH
+0xA6DF	0x821B	#CJK UNIFIED IDEOGRAPH
+0xA6E0	0x821F	#CJK UNIFIED IDEOGRAPH
+0xA6E1	0x826E	#CJK UNIFIED IDEOGRAPH
+0xA6E2	0x8272	#CJK UNIFIED IDEOGRAPH
+0xA6E3	0x827E	#CJK UNIFIED IDEOGRAPH
+0xA6E4	0x866B	#CJK UNIFIED IDEOGRAPH
+0xA6E5	0x8840	#CJK UNIFIED IDEOGRAPH
+0xA6E6	0x884C	#CJK UNIFIED IDEOGRAPH
+0xA6E7	0x8863	#CJK UNIFIED IDEOGRAPH
+0xA6E8	0x897F	#CJK UNIFIED IDEOGRAPH
+0xA6E9	0x9621	#CJK UNIFIED IDEOGRAPH
+0xA6EA	0x4E32	#CJK UNIFIED IDEOGRAPH
+0xA6EB	0x4EA8	#CJK UNIFIED IDEOGRAPH
+0xA6EC	0x4F4D	#CJK UNIFIED IDEOGRAPH
+0xA6ED	0x4F4F	#CJK UNIFIED IDEOGRAPH
+0xA6EE	0x4F47	#CJK UNIFIED IDEOGRAPH
+0xA6EF	0x4F57	#CJK UNIFIED IDEOGRAPH
+0xA6F0	0x4F5E	#CJK UNIFIED IDEOGRAPH
+0xA6F1	0x4F34	#CJK UNIFIED IDEOGRAPH
+0xA6F2	0x4F5B	#CJK UNIFIED IDEOGRAPH
+0xA6F3	0x4F55	#CJK UNIFIED IDEOGRAPH
+0xA6F4	0x4F30	#CJK UNIFIED IDEOGRAPH
+0xA6F5	0x4F50	#CJK UNIFIED IDEOGRAPH
+0xA6F6	0x4F51	#CJK UNIFIED IDEOGRAPH
+0xA6F7	0x4F3D	#CJK UNIFIED IDEOGRAPH
+0xA6F8	0x4F3A	#CJK UNIFIED IDEOGRAPH
+0xA6F9	0x4F38	#CJK UNIFIED IDEOGRAPH
+0xA6FA	0x4F43	#CJK UNIFIED IDEOGRAPH
+0xA6FB	0x4F54	#CJK UNIFIED IDEOGRAPH
+0xA6FC	0x4F3C	#CJK UNIFIED IDEOGRAPH
+0xA6FD	0x4F46	#CJK UNIFIED IDEOGRAPH
+0xA6FE	0x4F63	#CJK UNIFIED IDEOGRAPH
+0xA740	0x4F5C	#CJK UNIFIED IDEOGRAPH
+0xA741	0x4F60	#CJK UNIFIED IDEOGRAPH
+0xA742	0x4F2F	#CJK UNIFIED IDEOGRAPH
+0xA743	0x4F4E	#CJK UNIFIED IDEOGRAPH
+0xA744	0x4F36	#CJK UNIFIED IDEOGRAPH
+0xA745	0x4F59	#CJK UNIFIED IDEOGRAPH
+0xA746	0x4F5D	#CJK UNIFIED IDEOGRAPH
+0xA747	0x4F48	#CJK UNIFIED IDEOGRAPH
+0xA748	0x4F5A	#CJK UNIFIED IDEOGRAPH
+0xA749	0x514C	#CJK UNIFIED IDEOGRAPH
+0xA74A	0x514B	#CJK UNIFIED IDEOGRAPH
+0xA74B	0x514D	#CJK UNIFIED IDEOGRAPH
+0xA74C	0x5175	#CJK UNIFIED IDEOGRAPH
+0xA74D	0x51B6	#CJK UNIFIED IDEOGRAPH
+0xA74E	0x51B7	#CJK UNIFIED IDEOGRAPH
+0xA74F	0x5225	#CJK UNIFIED IDEOGRAPH
+0xA750	0x5224	#CJK UNIFIED IDEOGRAPH
+0xA751	0x5229	#CJK UNIFIED IDEOGRAPH
+0xA752	0x522A	#CJK UNIFIED IDEOGRAPH
+0xA753	0x5228	#CJK UNIFIED IDEOGRAPH
+0xA754	0x52AB	#CJK UNIFIED IDEOGRAPH
+0xA755	0x52A9	#CJK UNIFIED IDEOGRAPH
+0xA756	0x52AA	#CJK UNIFIED IDEOGRAPH
+0xA757	0x52AC	#CJK UNIFIED IDEOGRAPH
+0xA758	0x5323	#CJK UNIFIED IDEOGRAPH
+0xA759	0x5373	#CJK UNIFIED IDEOGRAPH
+0xA75A	0x5375	#CJK UNIFIED IDEOGRAPH
+0xA75B	0x541D	#CJK UNIFIED IDEOGRAPH
+0xA75C	0x542D	#CJK UNIFIED IDEOGRAPH
+0xA75D	0x541E	#CJK UNIFIED IDEOGRAPH
+0xA75E	0x543E	#CJK UNIFIED IDEOGRAPH
+0xA75F	0x5426	#CJK UNIFIED IDEOGRAPH
+0xA760	0x544E	#CJK UNIFIED IDEOGRAPH
+0xA761	0x5427	#CJK UNIFIED IDEOGRAPH
+0xA762	0x5446	#CJK UNIFIED IDEOGRAPH
+0xA763	0x5443	#CJK UNIFIED IDEOGRAPH
+0xA764	0x5433	#CJK UNIFIED IDEOGRAPH
+0xA765	0x5448	#CJK UNIFIED IDEOGRAPH
+0xA766	0x5442	#CJK UNIFIED IDEOGRAPH
+0xA767	0x541B	#CJK UNIFIED IDEOGRAPH
+0xA768	0x5429	#CJK UNIFIED IDEOGRAPH
+0xA769	0x544A	#CJK UNIFIED IDEOGRAPH
+0xA76A	0x5439	#CJK UNIFIED IDEOGRAPH
+0xA76B	0x543B	#CJK UNIFIED IDEOGRAPH
+0xA76C	0x5438	#CJK UNIFIED IDEOGRAPH
+0xA76D	0x542E	#CJK UNIFIED IDEOGRAPH
+0xA76E	0x5435	#CJK UNIFIED IDEOGRAPH
+0xA76F	0x5436	#CJK UNIFIED IDEOGRAPH
+0xA770	0x5420	#CJK UNIFIED IDEOGRAPH
+0xA771	0x543C	#CJK UNIFIED IDEOGRAPH
+0xA772	0x5440	#CJK UNIFIED IDEOGRAPH
+0xA773	0x5431	#CJK UNIFIED IDEOGRAPH
+0xA774	0x542B	#CJK UNIFIED IDEOGRAPH
+0xA775	0x541F	#CJK UNIFIED IDEOGRAPH
+0xA776	0x542C	#CJK UNIFIED IDEOGRAPH
+0xA777	0x56EA	#CJK UNIFIED IDEOGRAPH
+0xA778	0x56F0	#CJK UNIFIED IDEOGRAPH
+0xA779	0x56E4	#CJK UNIFIED IDEOGRAPH
+0xA77A	0x56EB	#CJK UNIFIED IDEOGRAPH
+0xA77B	0x574A	#CJK UNIFIED IDEOGRAPH
+0xA77C	0x5751	#CJK UNIFIED IDEOGRAPH
+0xA77D	0x5740	#CJK UNIFIED IDEOGRAPH
+0xA77E	0x574D	#CJK UNIFIED IDEOGRAPH
+0xA7A1	0x5747	#CJK UNIFIED IDEOGRAPH
+0xA7A2	0x574E	#CJK UNIFIED IDEOGRAPH
+0xA7A3	0x573E	#CJK UNIFIED IDEOGRAPH
+0xA7A4	0x5750	#CJK UNIFIED IDEOGRAPH
+0xA7A5	0x574F	#CJK UNIFIED IDEOGRAPH
+0xA7A6	0x573B	#CJK UNIFIED IDEOGRAPH
+0xA7A7	0x58EF	#CJK UNIFIED IDEOGRAPH
+0xA7A8	0x593E	#CJK UNIFIED IDEOGRAPH
+0xA7A9	0x599D	#CJK UNIFIED IDEOGRAPH
+0xA7AA	0x5992	#CJK UNIFIED IDEOGRAPH
+0xA7AB	0x59A8	#CJK UNIFIED IDEOGRAPH
+0xA7AC	0x599E	#CJK UNIFIED IDEOGRAPH
+0xA7AD	0x59A3	#CJK UNIFIED IDEOGRAPH
+0xA7AE	0x5999	#CJK UNIFIED IDEOGRAPH
+0xA7AF	0x5996	#CJK UNIFIED IDEOGRAPH
+0xA7B0	0x598D	#CJK UNIFIED IDEOGRAPH
+0xA7B1	0x59A4	#CJK UNIFIED IDEOGRAPH
+0xA7B2	0x5993	#CJK UNIFIED IDEOGRAPH
+0xA7B3	0x598A	#CJK UNIFIED IDEOGRAPH
+0xA7B4	0x59A5	#CJK UNIFIED IDEOGRAPH
+0xA7B5	0x5B5D	#CJK UNIFIED IDEOGRAPH
+0xA7B6	0x5B5C	#CJK UNIFIED IDEOGRAPH
+0xA7B7	0x5B5A	#CJK UNIFIED IDEOGRAPH
+0xA7B8	0x5B5B	#CJK UNIFIED IDEOGRAPH
+0xA7B9	0x5B8C	#CJK UNIFIED IDEOGRAPH
+0xA7BA	0x5B8B	#CJK UNIFIED IDEOGRAPH
+0xA7BB	0x5B8F	#CJK UNIFIED IDEOGRAPH
+0xA7BC	0x5C2C	#CJK UNIFIED IDEOGRAPH
+0xA7BD	0x5C40	#CJK UNIFIED IDEOGRAPH
+0xA7BE	0x5C41	#CJK UNIFIED IDEOGRAPH
+0xA7BF	0x5C3F	#CJK UNIFIED IDEOGRAPH
+0xA7C0	0x5C3E	#CJK UNIFIED IDEOGRAPH
+0xA7C1	0x5C90	#CJK UNIFIED IDEOGRAPH
+0xA7C2	0x5C91	#CJK UNIFIED IDEOGRAPH
+0xA7C3	0x5C94	#CJK UNIFIED IDEOGRAPH
+0xA7C4	0x5C8C	#CJK UNIFIED IDEOGRAPH
+0xA7C5	0x5DEB	#CJK UNIFIED IDEOGRAPH
+0xA7C6	0x5E0C	#CJK UNIFIED IDEOGRAPH
+0xA7C7	0x5E8F	#CJK UNIFIED IDEOGRAPH
+0xA7C8	0x5E87	#CJK UNIFIED IDEOGRAPH
+0xA7C9	0x5E8A	#CJK UNIFIED IDEOGRAPH
+0xA7CA	0x5EF7	#CJK UNIFIED IDEOGRAPH
+0xA7CB	0x5F04	#CJK UNIFIED IDEOGRAPH
+0xA7CC	0x5F1F	#CJK UNIFIED IDEOGRAPH
+0xA7CD	0x5F64	#CJK UNIFIED IDEOGRAPH
+0xA7CE	0x5F62	#CJK UNIFIED IDEOGRAPH
+0xA7CF	0x5F77	#CJK UNIFIED IDEOGRAPH
+0xA7D0	0x5F79	#CJK UNIFIED IDEOGRAPH
+0xA7D1	0x5FD8	#CJK UNIFIED IDEOGRAPH
+0xA7D2	0x5FCC	#CJK UNIFIED IDEOGRAPH
+0xA7D3	0x5FD7	#CJK UNIFIED IDEOGRAPH
+0xA7D4	0x5FCD	#CJK UNIFIED IDEOGRAPH
+0xA7D5	0x5FF1	#CJK UNIFIED IDEOGRAPH
+0xA7D6	0x5FEB	#CJK UNIFIED IDEOGRAPH
+0xA7D7	0x5FF8	#CJK UNIFIED IDEOGRAPH
+0xA7D8	0x5FEA	#CJK UNIFIED IDEOGRAPH
+0xA7D9	0x6212	#CJK UNIFIED IDEOGRAPH
+0xA7DA	0x6211	#CJK UNIFIED IDEOGRAPH
+0xA7DB	0x6284	#CJK UNIFIED IDEOGRAPH
+0xA7DC	0x6297	#CJK UNIFIED IDEOGRAPH
+0xA7DD	0x6296	#CJK UNIFIED IDEOGRAPH
+0xA7DE	0x6280	#CJK UNIFIED IDEOGRAPH
+0xA7DF	0x6276	#CJK UNIFIED IDEOGRAPH
+0xA7E0	0x6289	#CJK UNIFIED IDEOGRAPH
+0xA7E1	0x626D	#CJK UNIFIED IDEOGRAPH
+0xA7E2	0x628A	#CJK UNIFIED IDEOGRAPH
+0xA7E3	0x627C	#CJK UNIFIED IDEOGRAPH
+0xA7E4	0x627E	#CJK UNIFIED IDEOGRAPH
+0xA7E5	0x6279	#CJK UNIFIED IDEOGRAPH
+0xA7E6	0x6273	#CJK UNIFIED IDEOGRAPH
+0xA7E7	0x6292	#CJK UNIFIED IDEOGRAPH
+0xA7E8	0x626F	#CJK UNIFIED IDEOGRAPH
+0xA7E9	0x6298	#CJK UNIFIED IDEOGRAPH
+0xA7EA	0x626E	#CJK UNIFIED IDEOGRAPH
+0xA7EB	0x6295	#CJK UNIFIED IDEOGRAPH
+0xA7EC	0x6293	#CJK UNIFIED IDEOGRAPH
+0xA7ED	0x6291	#CJK UNIFIED IDEOGRAPH
+0xA7EE	0x6286	#CJK UNIFIED IDEOGRAPH
+0xA7EF	0x6539	#CJK UNIFIED IDEOGRAPH
+0xA7F0	0x653B	#CJK UNIFIED IDEOGRAPH
+0xA7F1	0x6538	#CJK UNIFIED IDEOGRAPH
+0xA7F2	0x65F1	#CJK UNIFIED IDEOGRAPH
+0xA7F3	0x66F4	#CJK UNIFIED IDEOGRAPH
+0xA7F4	0x675F	#CJK UNIFIED IDEOGRAPH
+0xA7F5	0x674E	#CJK UNIFIED IDEOGRAPH
+0xA7F6	0x674F	#CJK UNIFIED IDEOGRAPH
+0xA7F7	0x6750	#CJK UNIFIED IDEOGRAPH
+0xA7F8	0x6751	#CJK UNIFIED IDEOGRAPH
+0xA7F9	0x675C	#CJK UNIFIED IDEOGRAPH
+0xA7FA	0x6756	#CJK UNIFIED IDEOGRAPH
+0xA7FB	0x675E	#CJK UNIFIED IDEOGRAPH
+0xA7FC	0x6749	#CJK UNIFIED IDEOGRAPH
+0xA7FD	0x6746	#CJK UNIFIED IDEOGRAPH
+0xA7FE	0x6760	#CJK UNIFIED IDEOGRAPH
+0xA840	0x6753	#CJK UNIFIED IDEOGRAPH
+0xA841	0x6757	#CJK UNIFIED IDEOGRAPH
+0xA842	0x6B65	#CJK UNIFIED IDEOGRAPH
+0xA843	0x6BCF	#CJK UNIFIED IDEOGRAPH
+0xA844	0x6C42	#CJK UNIFIED IDEOGRAPH
+0xA845	0x6C5E	#CJK UNIFIED IDEOGRAPH
+0xA846	0x6C99	#CJK UNIFIED IDEOGRAPH
+0xA847	0x6C81	#CJK UNIFIED IDEOGRAPH
+0xA848	0x6C88	#CJK UNIFIED IDEOGRAPH
+0xA849	0x6C89	#CJK UNIFIED IDEOGRAPH
+0xA84A	0x6C85	#CJK UNIFIED IDEOGRAPH
+0xA84B	0x6C9B	#CJK UNIFIED IDEOGRAPH
+0xA84C	0x6C6A	#CJK UNIFIED IDEOGRAPH
+0xA84D	0x6C7A	#CJK UNIFIED IDEOGRAPH
+0xA84E	0x6C90	#CJK UNIFIED IDEOGRAPH
+0xA84F	0x6C70	#CJK UNIFIED IDEOGRAPH
+0xA850	0x6C8C	#CJK UNIFIED IDEOGRAPH
+0xA851	0x6C68	#CJK UNIFIED IDEOGRAPH
+0xA852	0x6C96	#CJK UNIFIED IDEOGRAPH
+0xA853	0x6C92	#CJK UNIFIED IDEOGRAPH
+0xA854	0x6C7D	#CJK UNIFIED IDEOGRAPH
+0xA855	0x6C83	#CJK UNIFIED IDEOGRAPH
+0xA856	0x6C72	#CJK UNIFIED IDEOGRAPH
+0xA857	0x6C7E	#CJK UNIFIED IDEOGRAPH
+0xA858	0x6C74	#CJK UNIFIED IDEOGRAPH
+0xA859	0x6C86	#CJK UNIFIED IDEOGRAPH
+0xA85A	0x6C76	#CJK UNIFIED IDEOGRAPH
+0xA85B	0x6C8D	#CJK UNIFIED IDEOGRAPH
+0xA85C	0x6C94	#CJK UNIFIED IDEOGRAPH
+0xA85D	0x6C98	#CJK UNIFIED IDEOGRAPH
+0xA85E	0x6C82	#CJK UNIFIED IDEOGRAPH
+0xA85F	0x7076	#CJK UNIFIED IDEOGRAPH
+0xA860	0x707C	#CJK UNIFIED IDEOGRAPH
+0xA861	0x707D	#CJK UNIFIED IDEOGRAPH
+0xA862	0x7078	#CJK UNIFIED IDEOGRAPH
+0xA863	0x7262	#CJK UNIFIED IDEOGRAPH
+0xA864	0x7261	#CJK UNIFIED IDEOGRAPH
+0xA865	0x7260	#CJK UNIFIED IDEOGRAPH
+0xA866	0x72C4	#CJK UNIFIED IDEOGRAPH
+0xA867	0x72C2	#CJK UNIFIED IDEOGRAPH
+0xA868	0x7396	#CJK UNIFIED IDEOGRAPH
+0xA869	0x752C	#CJK UNIFIED IDEOGRAPH
+0xA86A	0x752B	#CJK UNIFIED IDEOGRAPH
+0xA86B	0x7537	#CJK UNIFIED IDEOGRAPH
+0xA86C	0x7538	#CJK UNIFIED IDEOGRAPH
+0xA86D	0x7682	#CJK UNIFIED IDEOGRAPH
+0xA86E	0x76EF	#CJK UNIFIED IDEOGRAPH
+0xA86F	0x77E3	#CJK UNIFIED IDEOGRAPH
+0xA870	0x79C1	#CJK UNIFIED IDEOGRAPH
+0xA871	0x79C0	#CJK UNIFIED IDEOGRAPH
+0xA872	0x79BF	#CJK UNIFIED IDEOGRAPH
+0xA873	0x7A76	#CJK UNIFIED IDEOGRAPH
+0xA874	0x7CFB	#CJK UNIFIED IDEOGRAPH
+0xA875	0x7F55	#CJK UNIFIED IDEOGRAPH
+0xA876	0x8096	#CJK UNIFIED IDEOGRAPH
+0xA877	0x8093	#CJK UNIFIED IDEOGRAPH
+0xA878	0x809D	#CJK UNIFIED IDEOGRAPH
+0xA879	0x8098	#CJK UNIFIED IDEOGRAPH
+0xA87A	0x809B	#CJK UNIFIED IDEOGRAPH
+0xA87B	0x809A	#CJK UNIFIED IDEOGRAPH
+0xA87C	0x80B2	#CJK UNIFIED IDEOGRAPH
+0xA87D	0x826F	#CJK UNIFIED IDEOGRAPH
+0xA87E	0x8292	#CJK UNIFIED IDEOGRAPH
+0xA8A1	0x828B	#CJK UNIFIED IDEOGRAPH
+0xA8A2	0x828D	#CJK UNIFIED IDEOGRAPH
+0xA8A3	0x898B	#CJK UNIFIED IDEOGRAPH
+0xA8A4	0x89D2	#CJK UNIFIED IDEOGRAPH
+0xA8A5	0x8A00	#CJK UNIFIED IDEOGRAPH
+0xA8A6	0x8C37	#CJK UNIFIED IDEOGRAPH
+0xA8A7	0x8C46	#CJK UNIFIED IDEOGRAPH
+0xA8A8	0x8C55	#CJK UNIFIED IDEOGRAPH
+0xA8A9	0x8C9D	#CJK UNIFIED IDEOGRAPH
+0xA8AA	0x8D64	#CJK UNIFIED IDEOGRAPH
+0xA8AB	0x8D70	#CJK UNIFIED IDEOGRAPH
+0xA8AC	0x8DB3	#CJK UNIFIED IDEOGRAPH
+0xA8AD	0x8EAB	#CJK UNIFIED IDEOGRAPH
+0xA8AE	0x8ECA	#CJK UNIFIED IDEOGRAPH
+0xA8AF	0x8F9B	#CJK UNIFIED IDEOGRAPH
+0xA8B0	0x8FB0	#CJK UNIFIED IDEOGRAPH
+0xA8B1	0x8FC2	#CJK UNIFIED IDEOGRAPH
+0xA8B2	0x8FC6	#CJK UNIFIED IDEOGRAPH
+0xA8B3	0x8FC5	#CJK UNIFIED IDEOGRAPH
+0xA8B4	0x8FC4	#CJK UNIFIED IDEOGRAPH
+0xA8B5	0x5DE1	#CJK UNIFIED IDEOGRAPH
+0xA8B6	0x9091	#CJK UNIFIED IDEOGRAPH
+0xA8B7	0x90A2	#CJK UNIFIED IDEOGRAPH
+0xA8B8	0x90AA	#CJK UNIFIED IDEOGRAPH
+0xA8B9	0x90A6	#CJK UNIFIED IDEOGRAPH
+0xA8BA	0x90A3	#CJK UNIFIED IDEOGRAPH
+0xA8BB	0x9149	#CJK UNIFIED IDEOGRAPH
+0xA8BC	0x91C6	#CJK UNIFIED IDEOGRAPH
+0xA8BD	0x91CC	#CJK UNIFIED IDEOGRAPH
+0xA8BE	0x9632	#CJK UNIFIED IDEOGRAPH
+0xA8BF	0x962E	#CJK UNIFIED IDEOGRAPH
+0xA8C0	0x9631	#CJK UNIFIED IDEOGRAPH
+0xA8C1	0x962A	#CJK UNIFIED IDEOGRAPH
+0xA8C2	0x962C	#CJK UNIFIED IDEOGRAPH
+0xA8C3	0x4E26	#CJK UNIFIED IDEOGRAPH
+0xA8C4	0x4E56	#CJK UNIFIED IDEOGRAPH
+0xA8C5	0x4E73	#CJK UNIFIED IDEOGRAPH
+0xA8C6	0x4E8B	#CJK UNIFIED IDEOGRAPH
+0xA8C7	0x4E9B	#CJK UNIFIED IDEOGRAPH
+0xA8C8	0x4E9E	#CJK UNIFIED IDEOGRAPH
+0xA8C9	0x4EAB	#CJK UNIFIED IDEOGRAPH
+0xA8CA	0x4EAC	#CJK UNIFIED IDEOGRAPH
+0xA8CB	0x4F6F	#CJK UNIFIED IDEOGRAPH
+0xA8CC	0x4F9D	#CJK UNIFIED IDEOGRAPH
+0xA8CD	0x4F8D	#CJK UNIFIED IDEOGRAPH
+0xA8CE	0x4F73	#CJK UNIFIED IDEOGRAPH
+0xA8CF	0x4F7F	#CJK UNIFIED IDEOGRAPH
+0xA8D0	0x4F6C	#CJK UNIFIED IDEOGRAPH
+0xA8D1	0x4F9B	#CJK UNIFIED IDEOGRAPH
+0xA8D2	0x4F8B	#CJK UNIFIED IDEOGRAPH
+0xA8D3	0x4F86	#CJK UNIFIED IDEOGRAPH
+0xA8D4	0x4F83	#CJK UNIFIED IDEOGRAPH
+0xA8D5	0x4F70	#CJK UNIFIED IDEOGRAPH
+0xA8D6	0x4F75	#CJK UNIFIED IDEOGRAPH
+0xA8D7	0x4F88	#CJK UNIFIED IDEOGRAPH
+0xA8D8	0x4F69	#CJK UNIFIED IDEOGRAPH
+0xA8D9	0x4F7B	#CJK UNIFIED IDEOGRAPH
+0xA8DA	0x4F96	#CJK UNIFIED IDEOGRAPH
+0xA8DB	0x4F7E	#CJK UNIFIED IDEOGRAPH
+0xA8DC	0x4F8F	#CJK UNIFIED IDEOGRAPH
+0xA8DD	0x4F91	#CJK UNIFIED IDEOGRAPH
+0xA8DE	0x4F7A	#CJK UNIFIED IDEOGRAPH
+0xA8DF	0x5154	#CJK UNIFIED IDEOGRAPH
+0xA8E0	0x5152	#CJK UNIFIED IDEOGRAPH
+0xA8E1	0x5155	#CJK UNIFIED IDEOGRAPH
+0xA8E2	0x5169	#CJK UNIFIED IDEOGRAPH
+0xA8E3	0x5177	#CJK UNIFIED IDEOGRAPH
+0xA8E4	0x5176	#CJK UNIFIED IDEOGRAPH
+0xA8E5	0x5178	#CJK UNIFIED IDEOGRAPH
+0xA8E6	0x51BD	#CJK UNIFIED IDEOGRAPH
+0xA8E7	0x51FD	#CJK UNIFIED IDEOGRAPH
+0xA8E8	0x523B	#CJK UNIFIED IDEOGRAPH
+0xA8E9	0x5238	#CJK UNIFIED IDEOGRAPH
+0xA8EA	0x5237	#CJK UNIFIED IDEOGRAPH
+0xA8EB	0x523A	#CJK UNIFIED IDEOGRAPH
+0xA8EC	0x5230	#CJK UNIFIED IDEOGRAPH
+0xA8ED	0x522E	#CJK UNIFIED IDEOGRAPH
+0xA8EE	0x5236	#CJK UNIFIED IDEOGRAPH
+0xA8EF	0x5241	#CJK UNIFIED IDEOGRAPH
+0xA8F0	0x52BE	#CJK UNIFIED IDEOGRAPH
+0xA8F1	0x52BB	#CJK UNIFIED IDEOGRAPH
+0xA8F2	0x5352	#CJK UNIFIED IDEOGRAPH
+0xA8F3	0x5354	#CJK UNIFIED IDEOGRAPH
+0xA8F4	0x5353	#CJK UNIFIED IDEOGRAPH
+0xA8F5	0x5351	#CJK UNIFIED IDEOGRAPH
+0xA8F6	0x5366	#CJK UNIFIED IDEOGRAPH
+0xA8F7	0x5377	#CJK UNIFIED IDEOGRAPH
+0xA8F8	0x5378	#CJK UNIFIED IDEOGRAPH
+0xA8F9	0x5379	#CJK UNIFIED IDEOGRAPH
+0xA8FA	0x53D6	#CJK UNIFIED IDEOGRAPH
+0xA8FB	0x53D4	#CJK UNIFIED IDEOGRAPH
+0xA8FC	0x53D7	#CJK UNIFIED IDEOGRAPH
+0xA8FD	0x5473	#CJK UNIFIED IDEOGRAPH
+0xA8FE	0x5475	#CJK UNIFIED IDEOGRAPH
+0xA940	0x5496	#CJK UNIFIED IDEOGRAPH
+0xA941	0x5478	#CJK UNIFIED IDEOGRAPH
+0xA942	0x5495	#CJK UNIFIED IDEOGRAPH
+0xA943	0x5480	#CJK UNIFIED IDEOGRAPH
+0xA944	0x547B	#CJK UNIFIED IDEOGRAPH
+0xA945	0x5477	#CJK UNIFIED IDEOGRAPH
+0xA946	0x5484	#CJK UNIFIED IDEOGRAPH
+0xA947	0x5492	#CJK UNIFIED IDEOGRAPH
+0xA948	0x5486	#CJK UNIFIED IDEOGRAPH
+0xA949	0x547C	#CJK UNIFIED IDEOGRAPH
+0xA94A	0x5490	#CJK UNIFIED IDEOGRAPH
+0xA94B	0x5471	#CJK UNIFIED IDEOGRAPH
+0xA94C	0x5476	#CJK UNIFIED IDEOGRAPH
+0xA94D	0x548C	#CJK UNIFIED IDEOGRAPH
+0xA94E	0x549A	#CJK UNIFIED IDEOGRAPH
+0xA94F	0x5462	#CJK UNIFIED IDEOGRAPH
+0xA950	0x5468	#CJK UNIFIED IDEOGRAPH
+0xA951	0x548B	#CJK UNIFIED IDEOGRAPH
+0xA952	0x547D	#CJK UNIFIED IDEOGRAPH
+0xA953	0x548E	#CJK UNIFIED IDEOGRAPH
+0xA954	0x56FA	#CJK UNIFIED IDEOGRAPH
+0xA955	0x5783	#CJK UNIFIED IDEOGRAPH
+0xA956	0x5777	#CJK UNIFIED IDEOGRAPH
+0xA957	0x576A	#CJK UNIFIED IDEOGRAPH
+0xA958	0x5769	#CJK UNIFIED IDEOGRAPH
+0xA959	0x5761	#CJK UNIFIED IDEOGRAPH
+0xA95A	0x5766	#CJK UNIFIED IDEOGRAPH
+0xA95B	0x5764	#CJK UNIFIED IDEOGRAPH
+0xA95C	0x577C	#CJK UNIFIED IDEOGRAPH
+0xA95D	0x591C	#CJK UNIFIED IDEOGRAPH
+0xA95E	0x5949	#CJK UNIFIED IDEOGRAPH
+0xA95F	0x5947	#CJK UNIFIED IDEOGRAPH
+0xA960	0x5948	#CJK UNIFIED IDEOGRAPH
+0xA961	0x5944	#CJK UNIFIED IDEOGRAPH
+0xA962	0x5954	#CJK UNIFIED IDEOGRAPH
+0xA963	0x59BE	#CJK UNIFIED IDEOGRAPH
+0xA964	0x59BB	#CJK UNIFIED IDEOGRAPH
+0xA965	0x59D4	#CJK UNIFIED IDEOGRAPH
+0xA966	0x59B9	#CJK UNIFIED IDEOGRAPH
+0xA967	0x59AE	#CJK UNIFIED IDEOGRAPH
+0xA968	0x59D1	#CJK UNIFIED IDEOGRAPH
+0xA969	0x59C6	#CJK UNIFIED IDEOGRAPH
+0xA96A	0x59D0	#CJK UNIFIED IDEOGRAPH
+0xA96B	0x59CD	#CJK UNIFIED IDEOGRAPH
+0xA96C	0x59CB	#CJK UNIFIED IDEOGRAPH
+0xA96D	0x59D3	#CJK UNIFIED IDEOGRAPH
+0xA96E	0x59CA	#CJK UNIFIED IDEOGRAPH
+0xA96F	0x59AF	#CJK UNIFIED IDEOGRAPH
+0xA970	0x59B3	#CJK UNIFIED IDEOGRAPH
+0xA971	0x59D2	#CJK UNIFIED IDEOGRAPH
+0xA972	0x59C5	#CJK UNIFIED IDEOGRAPH
+0xA973	0x5B5F	#CJK UNIFIED IDEOGRAPH
+0xA974	0x5B64	#CJK UNIFIED IDEOGRAPH
+0xA975	0x5B63	#CJK UNIFIED IDEOGRAPH
+0xA976	0x5B97	#CJK UNIFIED IDEOGRAPH
+0xA977	0x5B9A	#CJK UNIFIED IDEOGRAPH
+0xA978	0x5B98	#CJK UNIFIED IDEOGRAPH
+0xA979	0x5B9C	#CJK UNIFIED IDEOGRAPH
+0xA97A	0x5B99	#CJK UNIFIED IDEOGRAPH
+0xA97B	0x5B9B	#CJK UNIFIED IDEOGRAPH
+0xA97C	0x5C1A	#CJK UNIFIED IDEOGRAPH
+0xA97D	0x5C48	#CJK UNIFIED IDEOGRAPH
+0xA97E	0x5C45	#CJK UNIFIED IDEOGRAPH
+0xA9A1	0x5C46	#CJK UNIFIED IDEOGRAPH
+0xA9A2	0x5CB7	#CJK UNIFIED IDEOGRAPH
+0xA9A3	0x5CA1	#CJK UNIFIED IDEOGRAPH
+0xA9A4	0x5CB8	#CJK UNIFIED IDEOGRAPH
+0xA9A5	0x5CA9	#CJK UNIFIED IDEOGRAPH
+0xA9A6	0x5CAB	#CJK UNIFIED IDEOGRAPH
+0xA9A7	0x5CB1	#CJK UNIFIED IDEOGRAPH
+0xA9A8	0x5CB3	#CJK UNIFIED IDEOGRAPH
+0xA9A9	0x5E18	#CJK UNIFIED IDEOGRAPH
+0xA9AA	0x5E1A	#CJK UNIFIED IDEOGRAPH
+0xA9AB	0x5E16	#CJK UNIFIED IDEOGRAPH
+0xA9AC	0x5E15	#CJK UNIFIED IDEOGRAPH
+0xA9AD	0x5E1B	#CJK UNIFIED IDEOGRAPH
+0xA9AE	0x5E11	#CJK UNIFIED IDEOGRAPH
+0xA9AF	0x5E78	#CJK UNIFIED IDEOGRAPH
+0xA9B0	0x5E9A	#CJK UNIFIED IDEOGRAPH
+0xA9B1	0x5E97	#CJK UNIFIED IDEOGRAPH
+0xA9B2	0x5E9C	#CJK UNIFIED IDEOGRAPH
+0xA9B3	0x5E95	#CJK UNIFIED IDEOGRAPH
+0xA9B4	0x5E96	#CJK UNIFIED IDEOGRAPH
+0xA9B5	0x5EF6	#CJK UNIFIED IDEOGRAPH
+0xA9B6	0x5F26	#CJK UNIFIED IDEOGRAPH
+0xA9B7	0x5F27	#CJK UNIFIED IDEOGRAPH
+0xA9B8	0x5F29	#CJK UNIFIED IDEOGRAPH
+0xA9B9	0x5F80	#CJK UNIFIED IDEOGRAPH
+0xA9BA	0x5F81	#CJK UNIFIED IDEOGRAPH
+0xA9BB	0x5F7F	#CJK UNIFIED IDEOGRAPH
+0xA9BC	0x5F7C	#CJK UNIFIED IDEOGRAPH
+0xA9BD	0x5FDD	#CJK UNIFIED IDEOGRAPH
+0xA9BE	0x5FE0	#CJK UNIFIED IDEOGRAPH
+0xA9BF	0x5FFD	#CJK UNIFIED IDEOGRAPH
+0xA9C0	0x5FF5	#CJK UNIFIED IDEOGRAPH
+0xA9C1	0x5FFF	#CJK UNIFIED IDEOGRAPH
+0xA9C2	0x600F	#CJK UNIFIED IDEOGRAPH
+0xA9C3	0x6014	#CJK UNIFIED IDEOGRAPH
+0xA9C4	0x602F	#CJK UNIFIED IDEOGRAPH
+0xA9C5	0x6035	#CJK UNIFIED IDEOGRAPH
+0xA9C6	0x6016	#CJK UNIFIED IDEOGRAPH
+0xA9C7	0x602A	#CJK UNIFIED IDEOGRAPH
+0xA9C8	0x6015	#CJK UNIFIED IDEOGRAPH
+0xA9C9	0x6021	#CJK UNIFIED IDEOGRAPH
+0xA9CA	0x6027	#CJK UNIFIED IDEOGRAPH
+0xA9CB	0x6029	#CJK UNIFIED IDEOGRAPH
+0xA9CC	0x602B	#CJK UNIFIED IDEOGRAPH
+0xA9CD	0x601B	#CJK UNIFIED IDEOGRAPH
+0xA9CE	0x6216	#CJK UNIFIED IDEOGRAPH
+0xA9CF	0x6215	#CJK UNIFIED IDEOGRAPH
+0xA9D0	0x623F	#CJK UNIFIED IDEOGRAPH
+0xA9D1	0x623E	#CJK UNIFIED IDEOGRAPH
+0xA9D2	0x6240	#CJK UNIFIED IDEOGRAPH
+0xA9D3	0x627F	#CJK UNIFIED IDEOGRAPH
+0xA9D4	0x62C9	#CJK UNIFIED IDEOGRAPH
+0xA9D5	0x62CC	#CJK UNIFIED IDEOGRAPH
+0xA9D6	0x62C4	#CJK UNIFIED IDEOGRAPH
+0xA9D7	0x62BF	#CJK UNIFIED IDEOGRAPH
+0xA9D8	0x62C2	#CJK UNIFIED IDEOGRAPH
+0xA9D9	0x62B9	#CJK UNIFIED IDEOGRAPH
+0xA9DA	0x62D2	#CJK UNIFIED IDEOGRAPH
+0xA9DB	0x62DB	#CJK UNIFIED IDEOGRAPH
+0xA9DC	0x62AB	#CJK UNIFIED IDEOGRAPH
+0xA9DD	0x62D3	#CJK UNIFIED IDEOGRAPH
+0xA9DE	0x62D4	#CJK UNIFIED IDEOGRAPH
+0xA9DF	0x62CB	#CJK UNIFIED IDEOGRAPH
+0xA9E0	0x62C8	#CJK UNIFIED IDEOGRAPH
+0xA9E1	0x62A8	#CJK UNIFIED IDEOGRAPH
+0xA9E2	0x62BD	#CJK UNIFIED IDEOGRAPH
+0xA9E3	0x62BC	#CJK UNIFIED IDEOGRAPH
+0xA9E4	0x62D0	#CJK UNIFIED IDEOGRAPH
+0xA9E5	0x62D9	#CJK UNIFIED IDEOGRAPH
+0xA9E6	0x62C7	#CJK UNIFIED IDEOGRAPH
+0xA9E7	0x62CD	#CJK UNIFIED IDEOGRAPH
+0xA9E8	0x62B5	#CJK UNIFIED IDEOGRAPH
+0xA9E9	0x62DA	#CJK UNIFIED IDEOGRAPH
+0xA9EA	0x62B1	#CJK UNIFIED IDEOGRAPH
+0xA9EB	0x62D8	#CJK UNIFIED IDEOGRAPH
+0xA9EC	0x62D6	#CJK UNIFIED IDEOGRAPH
+0xA9ED	0x62D7	#CJK UNIFIED IDEOGRAPH
+0xA9EE	0x62C6	#CJK UNIFIED IDEOGRAPH
+0xA9EF	0x62AC	#CJK UNIFIED IDEOGRAPH
+0xA9F0	0x62CE	#CJK UNIFIED IDEOGRAPH
+0xA9F1	0x653E	#CJK UNIFIED IDEOGRAPH
+0xA9F2	0x65A7	#CJK UNIFIED IDEOGRAPH
+0xA9F3	0x65BC	#CJK UNIFIED IDEOGRAPH
+0xA9F4	0x65FA	#CJK UNIFIED IDEOGRAPH
+0xA9F5	0x6614	#CJK UNIFIED IDEOGRAPH
+0xA9F6	0x6613	#CJK UNIFIED IDEOGRAPH
+0xA9F7	0x660C	#CJK UNIFIED IDEOGRAPH
+0xA9F8	0x6606	#CJK UNIFIED IDEOGRAPH
+0xA9F9	0x6602	#CJK UNIFIED IDEOGRAPH
+0xA9FA	0x660E	#CJK UNIFIED IDEOGRAPH
+0xA9FB	0x6600	#CJK UNIFIED IDEOGRAPH
+0xA9FC	0x660F	#CJK UNIFIED IDEOGRAPH
+0xA9FD	0x6615	#CJK UNIFIED IDEOGRAPH
+0xA9FE	0x660A	#CJK UNIFIED IDEOGRAPH
+0xAA40	0x6607	#CJK UNIFIED IDEOGRAPH
+0xAA41	0x670D	#CJK UNIFIED IDEOGRAPH
+0xAA42	0x670B	#CJK UNIFIED IDEOGRAPH
+0xAA43	0x676D	#CJK UNIFIED IDEOGRAPH
+0xAA44	0x678B	#CJK UNIFIED IDEOGRAPH
+0xAA45	0x6795	#CJK UNIFIED IDEOGRAPH
+0xAA46	0x6771	#CJK UNIFIED IDEOGRAPH
+0xAA47	0x679C	#CJK UNIFIED IDEOGRAPH
+0xAA48	0x6773	#CJK UNIFIED IDEOGRAPH
+0xAA49	0x6777	#CJK UNIFIED IDEOGRAPH
+0xAA4A	0x6787	#CJK UNIFIED IDEOGRAPH
+0xAA4B	0x679D	#CJK UNIFIED IDEOGRAPH
+0xAA4C	0x6797	#CJK UNIFIED IDEOGRAPH
+0xAA4D	0x676F	#CJK UNIFIED IDEOGRAPH
+0xAA4E	0x6770	#CJK UNIFIED IDEOGRAPH
+0xAA4F	0x677F	#CJK UNIFIED IDEOGRAPH
+0xAA50	0x6789	#CJK UNIFIED IDEOGRAPH
+0xAA51	0x677E	#CJK UNIFIED IDEOGRAPH
+0xAA52	0x6790	#CJK UNIFIED IDEOGRAPH
+0xAA53	0x6775	#CJK UNIFIED IDEOGRAPH
+0xAA54	0x679A	#CJK UNIFIED IDEOGRAPH
+0xAA55	0x6793	#CJK UNIFIED IDEOGRAPH
+0xAA56	0x677C	#CJK UNIFIED IDEOGRAPH
+0xAA57	0x676A	#CJK UNIFIED IDEOGRAPH
+0xAA58	0x6772	#CJK UNIFIED IDEOGRAPH
+0xAA59	0x6B23	#CJK UNIFIED IDEOGRAPH
+0xAA5A	0x6B66	#CJK UNIFIED IDEOGRAPH
+0xAA5B	0x6B67	#CJK UNIFIED IDEOGRAPH
+0xAA5C	0x6B7F	#CJK UNIFIED IDEOGRAPH
+0xAA5D	0x6C13	#CJK UNIFIED IDEOGRAPH
+0xAA5E	0x6C1B	#CJK UNIFIED IDEOGRAPH
+0xAA5F	0x6CE3	#CJK UNIFIED IDEOGRAPH
+0xAA60	0x6CE8	#CJK UNIFIED IDEOGRAPH
+0xAA61	0x6CF3	#CJK UNIFIED IDEOGRAPH
+0xAA62	0x6CB1	#CJK UNIFIED IDEOGRAPH
+0xAA63	0x6CCC	#CJK UNIFIED IDEOGRAPH
+0xAA64	0x6CE5	#CJK UNIFIED IDEOGRAPH
+0xAA65	0x6CB3	#CJK UNIFIED IDEOGRAPH
+0xAA66	0x6CBD	#CJK UNIFIED IDEOGRAPH
+0xAA67	0x6CBE	#CJK UNIFIED IDEOGRAPH
+0xAA68	0x6CBC	#CJK UNIFIED IDEOGRAPH
+0xAA69	0x6CE2	#CJK UNIFIED IDEOGRAPH
+0xAA6A	0x6CAB	#CJK UNIFIED IDEOGRAPH
+0xAA6B	0x6CD5	#CJK UNIFIED IDEOGRAPH
+0xAA6C	0x6CD3	#CJK UNIFIED IDEOGRAPH
+0xAA6D	0x6CB8	#CJK UNIFIED IDEOGRAPH
+0xAA6E	0x6CC4	#CJK UNIFIED IDEOGRAPH
+0xAA6F	0x6CB9	#CJK UNIFIED IDEOGRAPH
+0xAA70	0x6CC1	#CJK UNIFIED IDEOGRAPH
+0xAA71	0x6CAE	#CJK UNIFIED IDEOGRAPH
+0xAA72	0x6CD7	#CJK UNIFIED IDEOGRAPH
+0xAA73	0x6CC5	#CJK UNIFIED IDEOGRAPH
+0xAA74	0x6CF1	#CJK UNIFIED IDEOGRAPH
+0xAA75	0x6CBF	#CJK UNIFIED IDEOGRAPH
+0xAA76	0x6CBB	#CJK UNIFIED IDEOGRAPH
+0xAA77	0x6CE1	#CJK UNIFIED IDEOGRAPH
+0xAA78	0x6CDB	#CJK UNIFIED IDEOGRAPH
+0xAA79	0x6CCA	#CJK UNIFIED IDEOGRAPH
+0xAA7A	0x6CAC	#CJK UNIFIED IDEOGRAPH
+0xAA7B	0x6CEF	#CJK UNIFIED IDEOGRAPH
+0xAA7C	0x6CDC	#CJK UNIFIED IDEOGRAPH
+0xAA7D	0x6CD6	#CJK UNIFIED IDEOGRAPH
+0xAA7E	0x6CE0	#CJK UNIFIED IDEOGRAPH
+0xAAA1	0x7095	#CJK UNIFIED IDEOGRAPH
+0xAAA2	0x708E	#CJK UNIFIED IDEOGRAPH
+0xAAA3	0x7092	#CJK UNIFIED IDEOGRAPH
+0xAAA4	0x708A	#CJK UNIFIED IDEOGRAPH
+0xAAA5	0x7099	#CJK UNIFIED IDEOGRAPH
+0xAAA6	0x722C	#CJK UNIFIED IDEOGRAPH
+0xAAA7	0x722D	#CJK UNIFIED IDEOGRAPH
+0xAAA8	0x7238	#CJK UNIFIED IDEOGRAPH
+0xAAA9	0x7248	#CJK UNIFIED IDEOGRAPH
+0xAAAA	0x7267	#CJK UNIFIED IDEOGRAPH
+0xAAAB	0x7269	#CJK UNIFIED IDEOGRAPH
+0xAAAC	0x72C0	#CJK UNIFIED IDEOGRAPH
+0xAAAD	0x72CE	#CJK UNIFIED IDEOGRAPH
+0xAAAE	0x72D9	#CJK UNIFIED IDEOGRAPH
+0xAAAF	0x72D7	#CJK UNIFIED IDEOGRAPH
+0xAAB0	0x72D0	#CJK UNIFIED IDEOGRAPH
+0xAAB1	0x73A9	#CJK UNIFIED IDEOGRAPH
+0xAAB2	0x73A8	#CJK UNIFIED IDEOGRAPH
+0xAAB3	0x739F	#CJK UNIFIED IDEOGRAPH
+0xAAB4	0x73AB	#CJK UNIFIED IDEOGRAPH
+0xAAB5	0x73A5	#CJK UNIFIED IDEOGRAPH
+0xAAB6	0x753D	#CJK UNIFIED IDEOGRAPH
+0xAAB7	0x759D	#CJK UNIFIED IDEOGRAPH
+0xAAB8	0x7599	#CJK UNIFIED IDEOGRAPH
+0xAAB9	0x759A	#CJK UNIFIED IDEOGRAPH
+0xAABA	0x7684	#CJK UNIFIED IDEOGRAPH
+0xAABB	0x76C2	#CJK UNIFIED IDEOGRAPH
+0xAABC	0x76F2	#CJK UNIFIED IDEOGRAPH
+0xAABD	0x76F4	#CJK UNIFIED IDEOGRAPH
+0xAABE	0x77E5	#CJK UNIFIED IDEOGRAPH
+0xAABF	0x77FD	#CJK UNIFIED IDEOGRAPH
+0xAAC0	0x793E	#CJK UNIFIED IDEOGRAPH
+0xAAC1	0x7940	#CJK UNIFIED IDEOGRAPH
+0xAAC2	0x7941	#CJK UNIFIED IDEOGRAPH
+0xAAC3	0x79C9	#CJK UNIFIED IDEOGRAPH
+0xAAC4	0x79C8	#CJK UNIFIED IDEOGRAPH
+0xAAC5	0x7A7A	#CJK UNIFIED IDEOGRAPH
+0xAAC6	0x7A79	#CJK UNIFIED IDEOGRAPH
+0xAAC7	0x7AFA	#CJK UNIFIED IDEOGRAPH
+0xAAC8	0x7CFE	#CJK UNIFIED IDEOGRAPH
+0xAAC9	0x7F54	#CJK UNIFIED IDEOGRAPH
+0xAACA	0x7F8C	#CJK UNIFIED IDEOGRAPH
+0xAACB	0x7F8B	#CJK UNIFIED IDEOGRAPH
+0xAACC	0x8005	#CJK UNIFIED IDEOGRAPH
+0xAACD	0x80BA	#CJK UNIFIED IDEOGRAPH
+0xAACE	0x80A5	#CJK UNIFIED IDEOGRAPH
+0xAACF	0x80A2	#CJK UNIFIED IDEOGRAPH
+0xAAD0	0x80B1	#CJK UNIFIED IDEOGRAPH
+0xAAD1	0x80A1	#CJK UNIFIED IDEOGRAPH
+0xAAD2	0x80AB	#CJK UNIFIED IDEOGRAPH
+0xAAD3	0x80A9	#CJK UNIFIED IDEOGRAPH
+0xAAD4	0x80B4	#CJK UNIFIED IDEOGRAPH
+0xAAD5	0x80AA	#CJK UNIFIED IDEOGRAPH
+0xAAD6	0x80AF	#CJK UNIFIED IDEOGRAPH
+0xAAD7	0x81E5	#CJK UNIFIED IDEOGRAPH
+0xAAD8	0x81FE	#CJK UNIFIED IDEOGRAPH
+0xAAD9	0x820D	#CJK UNIFIED IDEOGRAPH
+0xAADA	0x82B3	#CJK UNIFIED IDEOGRAPH
+0xAADB	0x829D	#CJK UNIFIED IDEOGRAPH
+0xAADC	0x8299	#CJK UNIFIED IDEOGRAPH
+0xAADD	0x82AD	#CJK UNIFIED IDEOGRAPH
+0xAADE	0x82BD	#CJK UNIFIED IDEOGRAPH
+0xAADF	0x829F	#CJK UNIFIED IDEOGRAPH
+0xAAE0	0x82B9	#CJK UNIFIED IDEOGRAPH
+0xAAE1	0x82B1	#CJK UNIFIED IDEOGRAPH
+0xAAE2	0x82AC	#CJK UNIFIED IDEOGRAPH
+0xAAE3	0x82A5	#CJK UNIFIED IDEOGRAPH
+0xAAE4	0x82AF	#CJK UNIFIED IDEOGRAPH
+0xAAE5	0x82B8	#CJK UNIFIED IDEOGRAPH
+0xAAE6	0x82A3	#CJK UNIFIED IDEOGRAPH
+0xAAE7	0x82B0	#CJK UNIFIED IDEOGRAPH
+0xAAE8	0x82BE	#CJK UNIFIED IDEOGRAPH
+0xAAE9	0x82B7	#CJK UNIFIED IDEOGRAPH
+0xAAEA	0x864E	#CJK UNIFIED IDEOGRAPH
+0xAAEB	0x8671	#CJK UNIFIED IDEOGRAPH
+0xAAEC	0x521D	#CJK UNIFIED IDEOGRAPH
+0xAAED	0x8868	#CJK UNIFIED IDEOGRAPH
+0xAAEE	0x8ECB	#CJK UNIFIED IDEOGRAPH
+0xAAEF	0x8FCE	#CJK UNIFIED IDEOGRAPH
+0xAAF0	0x8FD4	#CJK UNIFIED IDEOGRAPH
+0xAAF1	0x8FD1	#CJK UNIFIED IDEOGRAPH
+0xAAF2	0x90B5	#CJK UNIFIED IDEOGRAPH
+0xAAF3	0x90B8	#CJK UNIFIED IDEOGRAPH
+0xAAF4	0x90B1	#CJK UNIFIED IDEOGRAPH
+0xAAF5	0x90B6	#CJK UNIFIED IDEOGRAPH
+0xAAF6	0x91C7	#CJK UNIFIED IDEOGRAPH
+0xAAF7	0x91D1	#CJK UNIFIED IDEOGRAPH
+0xAAF8	0x9577	#CJK UNIFIED IDEOGRAPH
+0xAAF9	0x9580	#CJK UNIFIED IDEOGRAPH
+0xAAFA	0x961C	#CJK UNIFIED IDEOGRAPH
+0xAAFB	0x9640	#CJK UNIFIED IDEOGRAPH
+0xAAFC	0x963F	#CJK UNIFIED IDEOGRAPH
+0xAAFD	0x963B	#CJK UNIFIED IDEOGRAPH
+0xAAFE	0x9644	#CJK UNIFIED IDEOGRAPH
+0xAB40	0x9642	#CJK UNIFIED IDEOGRAPH
+0xAB41	0x96B9	#CJK UNIFIED IDEOGRAPH
+0xAB42	0x96E8	#CJK UNIFIED IDEOGRAPH
+0xAB43	0x9752	#CJK UNIFIED IDEOGRAPH
+0xAB44	0x975E	#CJK UNIFIED IDEOGRAPH
+0xAB45	0x4E9F	#CJK UNIFIED IDEOGRAPH
+0xAB46	0x4EAD	#CJK UNIFIED IDEOGRAPH
+0xAB47	0x4EAE	#CJK UNIFIED IDEOGRAPH
+0xAB48	0x4FE1	#CJK UNIFIED IDEOGRAPH
+0xAB49	0x4FB5	#CJK UNIFIED IDEOGRAPH
+0xAB4A	0x4FAF	#CJK UNIFIED IDEOGRAPH
+0xAB4B	0x4FBF	#CJK UNIFIED IDEOGRAPH
+0xAB4C	0x4FE0	#CJK UNIFIED IDEOGRAPH
+0xAB4D	0x4FD1	#CJK UNIFIED IDEOGRAPH
+0xAB4E	0x4FCF	#CJK UNIFIED IDEOGRAPH
+0xAB4F	0x4FDD	#CJK UNIFIED IDEOGRAPH
+0xAB50	0x4FC3	#CJK UNIFIED IDEOGRAPH
+0xAB51	0x4FB6	#CJK UNIFIED IDEOGRAPH
+0xAB52	0x4FD8	#CJK UNIFIED IDEOGRAPH
+0xAB53	0x4FDF	#CJK UNIFIED IDEOGRAPH
+0xAB54	0x4FCA	#CJK UNIFIED IDEOGRAPH
+0xAB55	0x4FD7	#CJK UNIFIED IDEOGRAPH
+0xAB56	0x4FAE	#CJK UNIFIED IDEOGRAPH
+0xAB57	0x4FD0	#CJK UNIFIED IDEOGRAPH
+0xAB58	0x4FC4	#CJK UNIFIED IDEOGRAPH
+0xAB59	0x4FC2	#CJK UNIFIED IDEOGRAPH
+0xAB5A	0x4FDA	#CJK UNIFIED IDEOGRAPH
+0xAB5B	0x4FCE	#CJK UNIFIED IDEOGRAPH
+0xAB5C	0x4FDE	#CJK UNIFIED IDEOGRAPH
+0xAB5D	0x4FB7	#CJK UNIFIED IDEOGRAPH
+0xAB5E	0x5157	#CJK UNIFIED IDEOGRAPH
+0xAB5F	0x5192	#CJK UNIFIED IDEOGRAPH
+0xAB60	0x5191	#CJK UNIFIED IDEOGRAPH
+0xAB61	0x51A0	#CJK UNIFIED IDEOGRAPH
+0xAB62	0x524E	#CJK UNIFIED IDEOGRAPH
+0xAB63	0x5243	#CJK UNIFIED IDEOGRAPH
+0xAB64	0x524A	#CJK UNIFIED IDEOGRAPH
+0xAB65	0x524D	#CJK UNIFIED IDEOGRAPH
+0xAB66	0x524C	#CJK UNIFIED IDEOGRAPH
+0xAB67	0x524B	#CJK UNIFIED IDEOGRAPH
+0xAB68	0x5247	#CJK UNIFIED IDEOGRAPH
+0xAB69	0x52C7	#CJK UNIFIED IDEOGRAPH
+0xAB6A	0x52C9	#CJK UNIFIED IDEOGRAPH
+0xAB6B	0x52C3	#CJK UNIFIED IDEOGRAPH
+0xAB6C	0x52C1	#CJK UNIFIED IDEOGRAPH
+0xAB6D	0x530D	#CJK UNIFIED IDEOGRAPH
+0xAB6E	0x5357	#CJK UNIFIED IDEOGRAPH
+0xAB6F	0x537B	#CJK UNIFIED IDEOGRAPH
+0xAB70	0x539A	#CJK UNIFIED IDEOGRAPH
+0xAB71	0x53DB	#CJK UNIFIED IDEOGRAPH
+0xAB72	0x54AC	#CJK UNIFIED IDEOGRAPH
+0xAB73	0x54C0	#CJK UNIFIED IDEOGRAPH
+0xAB74	0x54A8	#CJK UNIFIED IDEOGRAPH
+0xAB75	0x54CE	#CJK UNIFIED IDEOGRAPH
+0xAB76	0x54C9	#CJK UNIFIED IDEOGRAPH
+0xAB77	0x54B8	#CJK UNIFIED IDEOGRAPH
+0xAB78	0x54A6	#CJK UNIFIED IDEOGRAPH
+0xAB79	0x54B3	#CJK UNIFIED IDEOGRAPH
+0xAB7A	0x54C7	#CJK UNIFIED IDEOGRAPH
+0xAB7B	0x54C2	#CJK UNIFIED IDEOGRAPH
+0xAB7C	0x54BD	#CJK UNIFIED IDEOGRAPH
+0xAB7D	0x54AA	#CJK UNIFIED IDEOGRAPH
+0xAB7E	0x54C1	#CJK UNIFIED IDEOGRAPH
+0xABA1	0x54C4	#CJK UNIFIED IDEOGRAPH
+0xABA2	0x54C8	#CJK UNIFIED IDEOGRAPH
+0xABA3	0x54AF	#CJK UNIFIED IDEOGRAPH
+0xABA4	0x54AB	#CJK UNIFIED IDEOGRAPH
+0xABA5	0x54B1	#CJK UNIFIED IDEOGRAPH
+0xABA6	0x54BB	#CJK UNIFIED IDEOGRAPH
+0xABA7	0x54A9	#CJK UNIFIED IDEOGRAPH
+0xABA8	0x54A7	#CJK UNIFIED IDEOGRAPH
+0xABA9	0x54BF	#CJK UNIFIED IDEOGRAPH
+0xABAA	0x56FF	#CJK UNIFIED IDEOGRAPH
+0xABAB	0x5782	#CJK UNIFIED IDEOGRAPH
+0xABAC	0x578B	#CJK UNIFIED IDEOGRAPH
+0xABAD	0x57A0	#CJK UNIFIED IDEOGRAPH
+0xABAE	0x57A3	#CJK UNIFIED IDEOGRAPH
+0xABAF	0x57A2	#CJK UNIFIED IDEOGRAPH
+0xABB0	0x57CE	#CJK UNIFIED IDEOGRAPH
+0xABB1	0x57AE	#CJK UNIFIED IDEOGRAPH
+0xABB2	0x5793	#CJK UNIFIED IDEOGRAPH
+0xABB3	0x5955	#CJK UNIFIED IDEOGRAPH
+0xABB4	0x5951	#CJK UNIFIED IDEOGRAPH
+0xABB5	0x594F	#CJK UNIFIED IDEOGRAPH
+0xABB6	0x594E	#CJK UNIFIED IDEOGRAPH
+0xABB7	0x5950	#CJK UNIFIED IDEOGRAPH
+0xABB8	0x59DC	#CJK UNIFIED IDEOGRAPH
+0xABB9	0x59D8	#CJK UNIFIED IDEOGRAPH
+0xABBA	0x59FF	#CJK UNIFIED IDEOGRAPH
+0xABBB	0x59E3	#CJK UNIFIED IDEOGRAPH
+0xABBC	0x59E8	#CJK UNIFIED IDEOGRAPH
+0xABBD	0x5A03	#CJK UNIFIED IDEOGRAPH
+0xABBE	0x59E5	#CJK UNIFIED IDEOGRAPH
+0xABBF	0x59EA	#CJK UNIFIED IDEOGRAPH
+0xABC0	0x59DA	#CJK UNIFIED IDEOGRAPH
+0xABC1	0x59E6	#CJK UNIFIED IDEOGRAPH
+0xABC2	0x5A01	#CJK UNIFIED IDEOGRAPH
+0xABC3	0x59FB	#CJK UNIFIED IDEOGRAPH
+0xABC4	0x5B69	#CJK UNIFIED IDEOGRAPH
+0xABC5	0x5BA3	#CJK UNIFIED IDEOGRAPH
+0xABC6	0x5BA6	#CJK UNIFIED IDEOGRAPH
+0xABC7	0x5BA4	#CJK UNIFIED IDEOGRAPH
+0xABC8	0x5BA2	#CJK UNIFIED IDEOGRAPH
+0xABC9	0x5BA5	#CJK UNIFIED IDEOGRAPH
+0xABCA	0x5C01	#CJK UNIFIED IDEOGRAPH
+0xABCB	0x5C4E	#CJK UNIFIED IDEOGRAPH
+0xABCC	0x5C4F	#CJK UNIFIED IDEOGRAPH
+0xABCD	0x5C4D	#CJK UNIFIED IDEOGRAPH
+0xABCE	0x5C4B	#CJK UNIFIED IDEOGRAPH
+0xABCF	0x5CD9	#CJK UNIFIED IDEOGRAPH
+0xABD0	0x5CD2	#CJK UNIFIED IDEOGRAPH
+0xABD1	0x5DF7	#CJK UNIFIED IDEOGRAPH
+0xABD2	0x5E1D	#CJK UNIFIED IDEOGRAPH
+0xABD3	0x5E25	#CJK UNIFIED IDEOGRAPH
+0xABD4	0x5E1F	#CJK UNIFIED IDEOGRAPH
+0xABD5	0x5E7D	#CJK UNIFIED IDEOGRAPH
+0xABD6	0x5EA0	#CJK UNIFIED IDEOGRAPH
+0xABD7	0x5EA6	#CJK UNIFIED IDEOGRAPH
+0xABD8	0x5EFA	#CJK UNIFIED IDEOGRAPH
+0xABD9	0x5F08	#CJK UNIFIED IDEOGRAPH
+0xABDA	0x5F2D	#CJK UNIFIED IDEOGRAPH
+0xABDB	0x5F65	#CJK UNIFIED IDEOGRAPH
+0xABDC	0x5F88	#CJK UNIFIED IDEOGRAPH
+0xABDD	0x5F85	#CJK UNIFIED IDEOGRAPH
+0xABDE	0x5F8A	#CJK UNIFIED IDEOGRAPH
+0xABDF	0x5F8B	#CJK UNIFIED IDEOGRAPH
+0xABE0	0x5F87	#CJK UNIFIED IDEOGRAPH
+0xABE1	0x5F8C	#CJK UNIFIED IDEOGRAPH
+0xABE2	0x5F89	#CJK UNIFIED IDEOGRAPH
+0xABE3	0x6012	#CJK UNIFIED IDEOGRAPH
+0xABE4	0x601D	#CJK UNIFIED IDEOGRAPH
+0xABE5	0x6020	#CJK UNIFIED IDEOGRAPH
+0xABE6	0x6025	#CJK UNIFIED IDEOGRAPH
+0xABE7	0x600E	#CJK UNIFIED IDEOGRAPH
+0xABE8	0x6028	#CJK UNIFIED IDEOGRAPH
+0xABE9	0x604D	#CJK UNIFIED IDEOGRAPH
+0xABEA	0x6070	#CJK UNIFIED IDEOGRAPH
+0xABEB	0x6068	#CJK UNIFIED IDEOGRAPH
+0xABEC	0x6062	#CJK UNIFIED IDEOGRAPH
+0xABED	0x6046	#CJK UNIFIED IDEOGRAPH
+0xABEE	0x6043	#CJK UNIFIED IDEOGRAPH
+0xABEF	0x606C	#CJK UNIFIED IDEOGRAPH
+0xABF0	0x606B	#CJK UNIFIED IDEOGRAPH
+0xABF1	0x606A	#CJK UNIFIED IDEOGRAPH
+0xABF2	0x6064	#CJK UNIFIED IDEOGRAPH
+0xABF3	0x6241	#CJK UNIFIED IDEOGRAPH
+0xABF4	0x62DC	#CJK UNIFIED IDEOGRAPH
+0xABF5	0x6316	#CJK UNIFIED IDEOGRAPH
+0xABF6	0x6309	#CJK UNIFIED IDEOGRAPH
+0xABF7	0x62FC	#CJK UNIFIED IDEOGRAPH
+0xABF8	0x62ED	#CJK UNIFIED IDEOGRAPH
+0xABF9	0x6301	#CJK UNIFIED IDEOGRAPH
+0xABFA	0x62EE	#CJK UNIFIED IDEOGRAPH
+0xABFB	0x62FD	#CJK UNIFIED IDEOGRAPH
+0xABFC	0x6307	#CJK UNIFIED IDEOGRAPH
+0xABFD	0x62F1	#CJK UNIFIED IDEOGRAPH
+0xABFE	0x62F7	#CJK UNIFIED IDEOGRAPH
+0xAC40	0x62EF	#CJK UNIFIED IDEOGRAPH
+0xAC41	0x62EC	#CJK UNIFIED IDEOGRAPH
+0xAC42	0x62FE	#CJK UNIFIED IDEOGRAPH
+0xAC43	0x62F4	#CJK UNIFIED IDEOGRAPH
+0xAC44	0x6311	#CJK UNIFIED IDEOGRAPH
+0xAC45	0x6302	#CJK UNIFIED IDEOGRAPH
+0xAC46	0x653F	#CJK UNIFIED IDEOGRAPH
+0xAC47	0x6545	#CJK UNIFIED IDEOGRAPH
+0xAC48	0x65AB	#CJK UNIFIED IDEOGRAPH
+0xAC49	0x65BD	#CJK UNIFIED IDEOGRAPH
+0xAC4A	0x65E2	#CJK UNIFIED IDEOGRAPH
+0xAC4B	0x6625	#CJK UNIFIED IDEOGRAPH
+0xAC4C	0x662D	#CJK UNIFIED IDEOGRAPH
+0xAC4D	0x6620	#CJK UNIFIED IDEOGRAPH
+0xAC4E	0x6627	#CJK UNIFIED IDEOGRAPH
+0xAC4F	0x662F	#CJK UNIFIED IDEOGRAPH
+0xAC50	0x661F	#CJK UNIFIED IDEOGRAPH
+0xAC51	0x6628	#CJK UNIFIED IDEOGRAPH
+0xAC52	0x6631	#CJK UNIFIED IDEOGRAPH
+0xAC53	0x6624	#CJK UNIFIED IDEOGRAPH
+0xAC54	0x66F7	#CJK UNIFIED IDEOGRAPH
+0xAC55	0x67FF	#CJK UNIFIED IDEOGRAPH
+0xAC56	0x67D3	#CJK UNIFIED IDEOGRAPH
+0xAC57	0x67F1	#CJK UNIFIED IDEOGRAPH
+0xAC58	0x67D4	#CJK UNIFIED IDEOGRAPH
+0xAC59	0x67D0	#CJK UNIFIED IDEOGRAPH
+0xAC5A	0x67EC	#CJK UNIFIED IDEOGRAPH
+0xAC5B	0x67B6	#CJK UNIFIED IDEOGRAPH
+0xAC5C	0x67AF	#CJK UNIFIED IDEOGRAPH
+0xAC5D	0x67F5	#CJK UNIFIED IDEOGRAPH
+0xAC5E	0x67E9	#CJK UNIFIED IDEOGRAPH
+0xAC5F	0x67EF	#CJK UNIFIED IDEOGRAPH
+0xAC60	0x67C4	#CJK UNIFIED IDEOGRAPH
+0xAC61	0x67D1	#CJK UNIFIED IDEOGRAPH
+0xAC62	0x67B4	#CJK UNIFIED IDEOGRAPH
+0xAC63	0x67DA	#CJK UNIFIED IDEOGRAPH
+0xAC64	0x67E5	#CJK UNIFIED IDEOGRAPH
+0xAC65	0x67B8	#CJK UNIFIED IDEOGRAPH
+0xAC66	0x67CF	#CJK UNIFIED IDEOGRAPH
+0xAC67	0x67DE	#CJK UNIFIED IDEOGRAPH
+0xAC68	0x67F3	#CJK UNIFIED IDEOGRAPH
+0xAC69	0x67B0	#CJK UNIFIED IDEOGRAPH
+0xAC6A	0x67D9	#CJK UNIFIED IDEOGRAPH
+0xAC6B	0x67E2	#CJK UNIFIED IDEOGRAPH
+0xAC6C	0x67DD	#CJK UNIFIED IDEOGRAPH
+0xAC6D	0x67D2	#CJK UNIFIED IDEOGRAPH
+0xAC6E	0x6B6A	#CJK UNIFIED IDEOGRAPH
+0xAC6F	0x6B83	#CJK UNIFIED IDEOGRAPH
+0xAC70	0x6B86	#CJK UNIFIED IDEOGRAPH
+0xAC71	0x6BB5	#CJK UNIFIED IDEOGRAPH
+0xAC72	0x6BD2	#CJK UNIFIED IDEOGRAPH
+0xAC73	0x6BD7	#CJK UNIFIED IDEOGRAPH
+0xAC74	0x6C1F	#CJK UNIFIED IDEOGRAPH
+0xAC75	0x6CC9	#CJK UNIFIED IDEOGRAPH
+0xAC76	0x6D0B	#CJK UNIFIED IDEOGRAPH
+0xAC77	0x6D32	#CJK UNIFIED IDEOGRAPH
+0xAC78	0x6D2A	#CJK UNIFIED IDEOGRAPH
+0xAC79	0x6D41	#CJK UNIFIED IDEOGRAPH
+0xAC7A	0x6D25	#CJK UNIFIED IDEOGRAPH
+0xAC7B	0x6D0C	#CJK UNIFIED IDEOGRAPH
+0xAC7C	0x6D31	#CJK UNIFIED IDEOGRAPH
+0xAC7D	0x6D1E	#CJK UNIFIED IDEOGRAPH
+0xAC7E	0x6D17	#CJK UNIFIED IDEOGRAPH
+0xACA1	0x6D3B	#CJK UNIFIED IDEOGRAPH
+0xACA2	0x6D3D	#CJK UNIFIED IDEOGRAPH
+0xACA3	0x6D3E	#CJK UNIFIED IDEOGRAPH
+0xACA4	0x6D36	#CJK UNIFIED IDEOGRAPH
+0xACA5	0x6D1B	#CJK UNIFIED IDEOGRAPH
+0xACA6	0x6CF5	#CJK UNIFIED IDEOGRAPH
+0xACA7	0x6D39	#CJK UNIFIED IDEOGRAPH
+0xACA8	0x6D27	#CJK UNIFIED IDEOGRAPH
+0xACA9	0x6D38	#CJK UNIFIED IDEOGRAPH
+0xACAA	0x6D29	#CJK UNIFIED IDEOGRAPH
+0xACAB	0x6D2E	#CJK UNIFIED IDEOGRAPH
+0xACAC	0x6D35	#CJK UNIFIED IDEOGRAPH
+0xACAD	0x6D0E	#CJK UNIFIED IDEOGRAPH
+0xACAE	0x6D2B	#CJK UNIFIED IDEOGRAPH
+0xACAF	0x70AB	#CJK UNIFIED IDEOGRAPH
+0xACB0	0x70BA	#CJK UNIFIED IDEOGRAPH
+0xACB1	0x70B3	#CJK UNIFIED IDEOGRAPH
+0xACB2	0x70AC	#CJK UNIFIED IDEOGRAPH
+0xACB3	0x70AF	#CJK UNIFIED IDEOGRAPH
+0xACB4	0x70AD	#CJK UNIFIED IDEOGRAPH
+0xACB5	0x70B8	#CJK UNIFIED IDEOGRAPH
+0xACB6	0x70AE	#CJK UNIFIED IDEOGRAPH
+0xACB7	0x70A4	#CJK UNIFIED IDEOGRAPH
+0xACB8	0x7230	#CJK UNIFIED IDEOGRAPH
+0xACB9	0x7272	#CJK UNIFIED IDEOGRAPH
+0xACBA	0x726F	#CJK UNIFIED IDEOGRAPH
+0xACBB	0x7274	#CJK UNIFIED IDEOGRAPH
+0xACBC	0x72E9	#CJK UNIFIED IDEOGRAPH
+0xACBD	0x72E0	#CJK UNIFIED IDEOGRAPH
+0xACBE	0x72E1	#CJK UNIFIED IDEOGRAPH
+0xACBF	0x73B7	#CJK UNIFIED IDEOGRAPH
+0xACC0	0x73CA	#CJK UNIFIED IDEOGRAPH
+0xACC1	0x73BB	#CJK UNIFIED IDEOGRAPH
+0xACC2	0x73B2	#CJK UNIFIED IDEOGRAPH
+0xACC3	0x73CD	#CJK UNIFIED IDEOGRAPH
+0xACC4	0x73C0	#CJK UNIFIED IDEOGRAPH
+0xACC5	0x73B3	#CJK UNIFIED IDEOGRAPH
+0xACC6	0x751A	#CJK UNIFIED IDEOGRAPH
+0xACC7	0x752D	#CJK UNIFIED IDEOGRAPH
+0xACC8	0x754F	#CJK UNIFIED IDEOGRAPH
+0xACC9	0x754C	#CJK UNIFIED IDEOGRAPH
+0xACCA	0x754E	#CJK UNIFIED IDEOGRAPH
+0xACCB	0x754B	#CJK UNIFIED IDEOGRAPH
+0xACCC	0x75AB	#CJK UNIFIED IDEOGRAPH
+0xACCD	0x75A4	#CJK UNIFIED IDEOGRAPH
+0xACCE	0x75A5	#CJK UNIFIED IDEOGRAPH
+0xACCF	0x75A2	#CJK UNIFIED IDEOGRAPH
+0xACD0	0x75A3	#CJK UNIFIED IDEOGRAPH
+0xACD1	0x7678	#CJK UNIFIED IDEOGRAPH
+0xACD2	0x7686	#CJK UNIFIED IDEOGRAPH
+0xACD3	0x7687	#CJK UNIFIED IDEOGRAPH
+0xACD4	0x7688	#CJK UNIFIED IDEOGRAPH
+0xACD5	0x76C8	#CJK UNIFIED IDEOGRAPH
+0xACD6	0x76C6	#CJK UNIFIED IDEOGRAPH
+0xACD7	0x76C3	#CJK UNIFIED IDEOGRAPH
+0xACD8	0x76C5	#CJK UNIFIED IDEOGRAPH
+0xACD9	0x7701	#CJK UNIFIED IDEOGRAPH
+0xACDA	0x76F9	#CJK UNIFIED IDEOGRAPH
+0xACDB	0x76F8	#CJK UNIFIED IDEOGRAPH
+0xACDC	0x7709	#CJK UNIFIED IDEOGRAPH
+0xACDD	0x770B	#CJK UNIFIED IDEOGRAPH
+0xACDE	0x76FE	#CJK UNIFIED IDEOGRAPH
+0xACDF	0x76FC	#CJK UNIFIED IDEOGRAPH
+0xACE0	0x7707	#CJK UNIFIED IDEOGRAPH
+0xACE1	0x77DC	#CJK UNIFIED IDEOGRAPH
+0xACE2	0x7802	#CJK UNIFIED IDEOGRAPH
+0xACE3	0x7814	#CJK UNIFIED IDEOGRAPH
+0xACE4	0x780C	#CJK UNIFIED IDEOGRAPH
+0xACE5	0x780D	#CJK UNIFIED IDEOGRAPH
+0xACE6	0x7946	#CJK UNIFIED IDEOGRAPH
+0xACE7	0x7949	#CJK UNIFIED IDEOGRAPH
+0xACE8	0x7948	#CJK UNIFIED IDEOGRAPH
+0xACE9	0x7947	#CJK UNIFIED IDEOGRAPH
+0xACEA	0x79B9	#CJK UNIFIED IDEOGRAPH
+0xACEB	0x79BA	#CJK UNIFIED IDEOGRAPH
+0xACEC	0x79D1	#CJK UNIFIED IDEOGRAPH
+0xACED	0x79D2	#CJK UNIFIED IDEOGRAPH
+0xACEE	0x79CB	#CJK UNIFIED IDEOGRAPH
+0xACEF	0x7A7F	#CJK UNIFIED IDEOGRAPH
+0xACF0	0x7A81	#CJK UNIFIED IDEOGRAPH
+0xACF1	0x7AFF	#CJK UNIFIED IDEOGRAPH
+0xACF2	0x7AFD	#CJK UNIFIED IDEOGRAPH
+0xACF3	0x7C7D	#CJK UNIFIED IDEOGRAPH
+0xACF4	0x7D02	#CJK UNIFIED IDEOGRAPH
+0xACF5	0x7D05	#CJK UNIFIED IDEOGRAPH
+0xACF6	0x7D00	#CJK UNIFIED IDEOGRAPH
+0xACF7	0x7D09	#CJK UNIFIED IDEOGRAPH
+0xACF8	0x7D07	#CJK UNIFIED IDEOGRAPH
+0xACF9	0x7D04	#CJK UNIFIED IDEOGRAPH
+0xACFA	0x7D06	#CJK UNIFIED IDEOGRAPH
+0xACFB	0x7F38	#CJK UNIFIED IDEOGRAPH
+0xACFC	0x7F8E	#CJK UNIFIED IDEOGRAPH
+0xACFD	0x7FBF	#CJK UNIFIED IDEOGRAPH
+0xACFE	0x8004	#CJK UNIFIED IDEOGRAPH
+0xAD40	0x8010	#CJK UNIFIED IDEOGRAPH
+0xAD41	0x800D	#CJK UNIFIED IDEOGRAPH
+0xAD42	0x8011	#CJK UNIFIED IDEOGRAPH
+0xAD43	0x8036	#CJK UNIFIED IDEOGRAPH
+0xAD44	0x80D6	#CJK UNIFIED IDEOGRAPH
+0xAD45	0x80E5	#CJK UNIFIED IDEOGRAPH
+0xAD46	0x80DA	#CJK UNIFIED IDEOGRAPH
+0xAD47	0x80C3	#CJK UNIFIED IDEOGRAPH
+0xAD48	0x80C4	#CJK UNIFIED IDEOGRAPH
+0xAD49	0x80CC	#CJK UNIFIED IDEOGRAPH
+0xAD4A	0x80E1	#CJK UNIFIED IDEOGRAPH
+0xAD4B	0x80DB	#CJK UNIFIED IDEOGRAPH
+0xAD4C	0x80CE	#CJK UNIFIED IDEOGRAPH
+0xAD4D	0x80DE	#CJK UNIFIED IDEOGRAPH
+0xAD4E	0x80E4	#CJK UNIFIED IDEOGRAPH
+0xAD4F	0x80DD	#CJK UNIFIED IDEOGRAPH
+0xAD50	0x81F4	#CJK UNIFIED IDEOGRAPH
+0xAD51	0x8222	#CJK UNIFIED IDEOGRAPH
+0xAD52	0x82E7	#CJK UNIFIED IDEOGRAPH
+0xAD53	0x8303	#CJK UNIFIED IDEOGRAPH
+0xAD54	0x8305	#CJK UNIFIED IDEOGRAPH
+0xAD55	0x82E3	#CJK UNIFIED IDEOGRAPH
+0xAD56	0x82DB	#CJK UNIFIED IDEOGRAPH
+0xAD57	0x82E6	#CJK UNIFIED IDEOGRAPH
+0xAD58	0x8304	#CJK UNIFIED IDEOGRAPH
+0xAD59	0x82E5	#CJK UNIFIED IDEOGRAPH
+0xAD5A	0x8302	#CJK UNIFIED IDEOGRAPH
+0xAD5B	0x8309	#CJK UNIFIED IDEOGRAPH
+0xAD5C	0x82D2	#CJK UNIFIED IDEOGRAPH
+0xAD5D	0x82D7	#CJK UNIFIED IDEOGRAPH
+0xAD5E	0x82F1	#CJK UNIFIED IDEOGRAPH
+0xAD5F	0x8301	#CJK UNIFIED IDEOGRAPH
+0xAD60	0x82DC	#CJK UNIFIED IDEOGRAPH
+0xAD61	0x82D4	#CJK UNIFIED IDEOGRAPH
+0xAD62	0x82D1	#CJK UNIFIED IDEOGRAPH
+0xAD63	0x82DE	#CJK UNIFIED IDEOGRAPH
+0xAD64	0x82D3	#CJK UNIFIED IDEOGRAPH
+0xAD65	0x82DF	#CJK UNIFIED IDEOGRAPH
+0xAD66	0x82EF	#CJK UNIFIED IDEOGRAPH
+0xAD67	0x8306	#CJK UNIFIED IDEOGRAPH
+0xAD68	0x8650	#CJK UNIFIED IDEOGRAPH
+0xAD69	0x8679	#CJK UNIFIED IDEOGRAPH
+0xAD6A	0x867B	#CJK UNIFIED IDEOGRAPH
+0xAD6B	0x867A	#CJK UNIFIED IDEOGRAPH
+0xAD6C	0x884D	#CJK UNIFIED IDEOGRAPH
+0xAD6D	0x886B	#CJK UNIFIED IDEOGRAPH
+0xAD6E	0x8981	#CJK UNIFIED IDEOGRAPH
+0xAD6F	0x89D4	#CJK UNIFIED IDEOGRAPH
+0xAD70	0x8A08	#CJK UNIFIED IDEOGRAPH
+0xAD71	0x8A02	#CJK UNIFIED IDEOGRAPH
+0xAD72	0x8A03	#CJK UNIFIED IDEOGRAPH
+0xAD73	0x8C9E	#CJK UNIFIED IDEOGRAPH
+0xAD74	0x8CA0	#CJK UNIFIED IDEOGRAPH
+0xAD75	0x8D74	#CJK UNIFIED IDEOGRAPH
+0xAD76	0x8D73	#CJK UNIFIED IDEOGRAPH
+0xAD77	0x8DB4	#CJK UNIFIED IDEOGRAPH
+0xAD78	0x8ECD	#CJK UNIFIED IDEOGRAPH
+0xAD79	0x8ECC	#CJK UNIFIED IDEOGRAPH
+0xAD7A	0x8FF0	#CJK UNIFIED IDEOGRAPH
+0xAD7B	0x8FE6	#CJK UNIFIED IDEOGRAPH
+0xAD7C	0x8FE2	#CJK UNIFIED IDEOGRAPH
+0xAD7D	0x8FEA	#CJK UNIFIED IDEOGRAPH
+0xAD7E	0x8FE5	#CJK UNIFIED IDEOGRAPH
+0xADA1	0x8FED	#CJK UNIFIED IDEOGRAPH
+0xADA2	0x8FEB	#CJK UNIFIED IDEOGRAPH
+0xADA3	0x8FE4	#CJK UNIFIED IDEOGRAPH
+0xADA4	0x8FE8	#CJK UNIFIED IDEOGRAPH
+0xADA5	0x90CA	#CJK UNIFIED IDEOGRAPH
+0xADA6	0x90CE	#CJK UNIFIED IDEOGRAPH
+0xADA7	0x90C1	#CJK UNIFIED IDEOGRAPH
+0xADA8	0x90C3	#CJK UNIFIED IDEOGRAPH
+0xADA9	0x914B	#CJK UNIFIED IDEOGRAPH
+0xADAA	0x914A	#CJK UNIFIED IDEOGRAPH
+0xADAB	0x91CD	#CJK UNIFIED IDEOGRAPH
+0xADAC	0x9582	#CJK UNIFIED IDEOGRAPH
+0xADAD	0x9650	#CJK UNIFIED IDEOGRAPH
+0xADAE	0x964B	#CJK UNIFIED IDEOGRAPH
+0xADAF	0x964C	#CJK UNIFIED IDEOGRAPH
+0xADB0	0x964D	#CJK UNIFIED IDEOGRAPH
+0xADB1	0x9762	#CJK UNIFIED IDEOGRAPH
+0xADB2	0x9769	#CJK UNIFIED IDEOGRAPH
+0xADB3	0x97CB	#CJK UNIFIED IDEOGRAPH
+0xADB4	0x97ED	#CJK UNIFIED IDEOGRAPH
+0xADB5	0x97F3	#CJK UNIFIED IDEOGRAPH
+0xADB6	0x9801	#CJK UNIFIED IDEOGRAPH
+0xADB7	0x98A8	#CJK UNIFIED IDEOGRAPH
+0xADB8	0x98DB	#CJK UNIFIED IDEOGRAPH
+0xADB9	0x98DF	#CJK UNIFIED IDEOGRAPH
+0xADBA	0x9996	#CJK UNIFIED IDEOGRAPH
+0xADBB	0x9999	#CJK UNIFIED IDEOGRAPH
+0xADBC	0x4E58	#CJK UNIFIED IDEOGRAPH
+0xADBD	0x4EB3	#CJK UNIFIED IDEOGRAPH
+0xADBE	0x500C	#CJK UNIFIED IDEOGRAPH
+0xADBF	0x500D	#CJK UNIFIED IDEOGRAPH
+0xADC0	0x5023	#CJK UNIFIED IDEOGRAPH
+0xADC1	0x4FEF	#CJK UNIFIED IDEOGRAPH
+0xADC2	0x5026	#CJK UNIFIED IDEOGRAPH
+0xADC3	0x5025	#CJK UNIFIED IDEOGRAPH
+0xADC4	0x4FF8	#CJK UNIFIED IDEOGRAPH
+0xADC5	0x5029	#CJK UNIFIED IDEOGRAPH
+0xADC6	0x5016	#CJK UNIFIED IDEOGRAPH
+0xADC7	0x5006	#CJK UNIFIED IDEOGRAPH
+0xADC8	0x503C	#CJK UNIFIED IDEOGRAPH
+0xADC9	0x501F	#CJK UNIFIED IDEOGRAPH
+0xADCA	0x501A	#CJK UNIFIED IDEOGRAPH
+0xADCB	0x5012	#CJK UNIFIED IDEOGRAPH
+0xADCC	0x5011	#CJK UNIFIED IDEOGRAPH
+0xADCD	0x4FFA	#CJK UNIFIED IDEOGRAPH
+0xADCE	0x5000	#CJK UNIFIED IDEOGRAPH
+0xADCF	0x5014	#CJK UNIFIED IDEOGRAPH
+0xADD0	0x5028	#CJK UNIFIED IDEOGRAPH
+0xADD1	0x4FF1	#CJK UNIFIED IDEOGRAPH
+0xADD2	0x5021	#CJK UNIFIED IDEOGRAPH
+0xADD3	0x500B	#CJK UNIFIED IDEOGRAPH
+0xADD4	0x5019	#CJK UNIFIED IDEOGRAPH
+0xADD5	0x5018	#CJK UNIFIED IDEOGRAPH
+0xADD6	0x4FF3	#CJK UNIFIED IDEOGRAPH
+0xADD7	0x4FEE	#CJK UNIFIED IDEOGRAPH
+0xADD8	0x502D	#CJK UNIFIED IDEOGRAPH
+0xADD9	0x502A	#CJK UNIFIED IDEOGRAPH
+0xADDA	0x4FFE	#CJK UNIFIED IDEOGRAPH
+0xADDB	0x502B	#CJK UNIFIED IDEOGRAPH
+0xADDC	0x5009	#CJK UNIFIED IDEOGRAPH
+0xADDD	0x517C	#CJK UNIFIED IDEOGRAPH
+0xADDE	0x51A4	#CJK UNIFIED IDEOGRAPH
+0xADDF	0x51A5	#CJK UNIFIED IDEOGRAPH
+0xADE0	0x51A2	#CJK UNIFIED IDEOGRAPH
+0xADE1	0x51CD	#CJK UNIFIED IDEOGRAPH
+0xADE2	0x51CC	#CJK UNIFIED IDEOGRAPH
+0xADE3	0x51C6	#CJK UNIFIED IDEOGRAPH
+0xADE4	0x51CB	#CJK UNIFIED IDEOGRAPH
+0xADE5	0x5256	#CJK UNIFIED IDEOGRAPH
+0xADE6	0x525C	#CJK UNIFIED IDEOGRAPH
+0xADE7	0x5254	#CJK UNIFIED IDEOGRAPH
+0xADE8	0x525B	#CJK UNIFIED IDEOGRAPH
+0xADE9	0x525D	#CJK UNIFIED IDEOGRAPH
+0xADEA	0x532A	#CJK UNIFIED IDEOGRAPH
+0xADEB	0x537F	#CJK UNIFIED IDEOGRAPH
+0xADEC	0x539F	#CJK UNIFIED IDEOGRAPH
+0xADED	0x539D	#CJK UNIFIED IDEOGRAPH
+0xADEE	0x53DF	#CJK UNIFIED IDEOGRAPH
+0xADEF	0x54E8	#CJK UNIFIED IDEOGRAPH
+0xADF0	0x5510	#CJK UNIFIED IDEOGRAPH
+0xADF1	0x5501	#CJK UNIFIED IDEOGRAPH
+0xADF2	0x5537	#CJK UNIFIED IDEOGRAPH
+0xADF3	0x54FC	#CJK UNIFIED IDEOGRAPH
+0xADF4	0x54E5	#CJK UNIFIED IDEOGRAPH
+0xADF5	0x54F2	#CJK UNIFIED IDEOGRAPH
+0xADF6	0x5506	#CJK UNIFIED IDEOGRAPH
+0xADF7	0x54FA	#CJK UNIFIED IDEOGRAPH
+0xADF8	0x5514	#CJK UNIFIED IDEOGRAPH
+0xADF9	0x54E9	#CJK UNIFIED IDEOGRAPH
+0xADFA	0x54ED	#CJK UNIFIED IDEOGRAPH
+0xADFB	0x54E1	#CJK UNIFIED IDEOGRAPH
+0xADFC	0x5509	#CJK UNIFIED IDEOGRAPH
+0xADFD	0x54EE	#CJK UNIFIED IDEOGRAPH
+0xADFE	0x54EA	#CJK UNIFIED IDEOGRAPH
+0xAE40	0x54E6	#CJK UNIFIED IDEOGRAPH
+0xAE41	0x5527	#CJK UNIFIED IDEOGRAPH
+0xAE42	0x5507	#CJK UNIFIED IDEOGRAPH
+0xAE43	0x54FD	#CJK UNIFIED IDEOGRAPH
+0xAE44	0x550F	#CJK UNIFIED IDEOGRAPH
+0xAE45	0x5703	#CJK UNIFIED IDEOGRAPH
+0xAE46	0x5704	#CJK UNIFIED IDEOGRAPH
+0xAE47	0x57C2	#CJK UNIFIED IDEOGRAPH
+0xAE48	0x57D4	#CJK UNIFIED IDEOGRAPH
+0xAE49	0x57CB	#CJK UNIFIED IDEOGRAPH
+0xAE4A	0x57C3	#CJK UNIFIED IDEOGRAPH
+0xAE4B	0x5809	#CJK UNIFIED IDEOGRAPH
+0xAE4C	0x590F	#CJK UNIFIED IDEOGRAPH
+0xAE4D	0x5957	#CJK UNIFIED IDEOGRAPH
+0xAE4E	0x5958	#CJK UNIFIED IDEOGRAPH
+0xAE4F	0x595A	#CJK UNIFIED IDEOGRAPH
+0xAE50	0x5A11	#CJK UNIFIED IDEOGRAPH
+0xAE51	0x5A18	#CJK UNIFIED IDEOGRAPH
+0xAE52	0x5A1C	#CJK UNIFIED IDEOGRAPH
+0xAE53	0x5A1F	#CJK UNIFIED IDEOGRAPH
+0xAE54	0x5A1B	#CJK UNIFIED IDEOGRAPH
+0xAE55	0x5A13	#CJK UNIFIED IDEOGRAPH
+0xAE56	0x59EC	#CJK UNIFIED IDEOGRAPH
+0xAE57	0x5A20	#CJK UNIFIED IDEOGRAPH
+0xAE58	0x5A23	#CJK UNIFIED IDEOGRAPH
+0xAE59	0x5A29	#CJK UNIFIED IDEOGRAPH
+0xAE5A	0x5A25	#CJK UNIFIED IDEOGRAPH
+0xAE5B	0x5A0C	#CJK UNIFIED IDEOGRAPH
+0xAE5C	0x5A09	#CJK UNIFIED IDEOGRAPH
+0xAE5D	0x5B6B	#CJK UNIFIED IDEOGRAPH
+0xAE5E	0x5C58	#CJK UNIFIED IDEOGRAPH
+0xAE5F	0x5BB0	#CJK UNIFIED IDEOGRAPH
+0xAE60	0x5BB3	#CJK UNIFIED IDEOGRAPH
+0xAE61	0x5BB6	#CJK UNIFIED IDEOGRAPH
+0xAE62	0x5BB4	#CJK UNIFIED IDEOGRAPH
+0xAE63	0x5BAE	#CJK UNIFIED IDEOGRAPH
+0xAE64	0x5BB5	#CJK UNIFIED IDEOGRAPH
+0xAE65	0x5BB9	#CJK UNIFIED IDEOGRAPH
+0xAE66	0x5BB8	#CJK UNIFIED IDEOGRAPH
+0xAE67	0x5C04	#CJK UNIFIED IDEOGRAPH
+0xAE68	0x5C51	#CJK UNIFIED IDEOGRAPH
+0xAE69	0x5C55	#CJK UNIFIED IDEOGRAPH
+0xAE6A	0x5C50	#CJK UNIFIED IDEOGRAPH
+0xAE6B	0x5CED	#CJK UNIFIED IDEOGRAPH
+0xAE6C	0x5CFD	#CJK UNIFIED IDEOGRAPH
+0xAE6D	0x5CFB	#CJK UNIFIED IDEOGRAPH
+0xAE6E	0x5CEA	#CJK UNIFIED IDEOGRAPH
+0xAE6F	0x5CE8	#CJK UNIFIED IDEOGRAPH
+0xAE70	0x5CF0	#CJK UNIFIED IDEOGRAPH
+0xAE71	0x5CF6	#CJK UNIFIED IDEOGRAPH
+0xAE72	0x5D01	#CJK UNIFIED IDEOGRAPH
+0xAE73	0x5CF4	#CJK UNIFIED IDEOGRAPH
+0xAE74	0x5DEE	#CJK UNIFIED IDEOGRAPH
+0xAE75	0x5E2D	#CJK UNIFIED IDEOGRAPH
+0xAE76	0x5E2B	#CJK UNIFIED IDEOGRAPH
+0xAE77	0x5EAB	#CJK UNIFIED IDEOGRAPH
+0xAE78	0x5EAD	#CJK UNIFIED IDEOGRAPH
+0xAE79	0x5EA7	#CJK UNIFIED IDEOGRAPH
+0xAE7A	0x5F31	#CJK UNIFIED IDEOGRAPH
+0xAE7B	0x5F92	#CJK UNIFIED IDEOGRAPH
+0xAE7C	0x5F91	#CJK UNIFIED IDEOGRAPH
+0xAE7D	0x5F90	#CJK UNIFIED IDEOGRAPH
+0xAE7E	0x6059	#CJK UNIFIED IDEOGRAPH
+0xAEA1	0x6063	#CJK UNIFIED IDEOGRAPH
+0xAEA2	0x6065	#CJK UNIFIED IDEOGRAPH
+0xAEA3	0x6050	#CJK UNIFIED IDEOGRAPH
+0xAEA4	0x6055	#CJK UNIFIED IDEOGRAPH
+0xAEA5	0x606D	#CJK UNIFIED IDEOGRAPH
+0xAEA6	0x6069	#CJK UNIFIED IDEOGRAPH
+0xAEA7	0x606F	#CJK UNIFIED IDEOGRAPH
+0xAEA8	0x6084	#CJK UNIFIED IDEOGRAPH
+0xAEA9	0x609F	#CJK UNIFIED IDEOGRAPH
+0xAEAA	0x609A	#CJK UNIFIED IDEOGRAPH
+0xAEAB	0x608D	#CJK UNIFIED IDEOGRAPH
+0xAEAC	0x6094	#CJK UNIFIED IDEOGRAPH
+0xAEAD	0x608C	#CJK UNIFIED IDEOGRAPH
+0xAEAE	0x6085	#CJK UNIFIED IDEOGRAPH
+0xAEAF	0x6096	#CJK UNIFIED IDEOGRAPH
+0xAEB0	0x6247	#CJK UNIFIED IDEOGRAPH
+0xAEB1	0x62F3	#CJK UNIFIED IDEOGRAPH
+0xAEB2	0x6308	#CJK UNIFIED IDEOGRAPH
+0xAEB3	0x62FF	#CJK UNIFIED IDEOGRAPH
+0xAEB4	0x634E	#CJK UNIFIED IDEOGRAPH
+0xAEB5	0x633E	#CJK UNIFIED IDEOGRAPH
+0xAEB6	0x632F	#CJK UNIFIED IDEOGRAPH
+0xAEB7	0x6355	#CJK UNIFIED IDEOGRAPH
+0xAEB8	0x6342	#CJK UNIFIED IDEOGRAPH
+0xAEB9	0x6346	#CJK UNIFIED IDEOGRAPH
+0xAEBA	0x634F	#CJK UNIFIED IDEOGRAPH
+0xAEBB	0x6349	#CJK UNIFIED IDEOGRAPH
+0xAEBC	0x633A	#CJK UNIFIED IDEOGRAPH
+0xAEBD	0x6350	#CJK UNIFIED IDEOGRAPH
+0xAEBE	0x633D	#CJK UNIFIED IDEOGRAPH
+0xAEBF	0x632A	#CJK UNIFIED IDEOGRAPH
+0xAEC0	0x632B	#CJK UNIFIED IDEOGRAPH
+0xAEC1	0x6328	#CJK UNIFIED IDEOGRAPH
+0xAEC2	0x634D	#CJK UNIFIED IDEOGRAPH
+0xAEC3	0x634C	#CJK UNIFIED IDEOGRAPH
+0xAEC4	0x6548	#CJK UNIFIED IDEOGRAPH
+0xAEC5	0x6549	#CJK UNIFIED IDEOGRAPH
+0xAEC6	0x6599	#CJK UNIFIED IDEOGRAPH
+0xAEC7	0x65C1	#CJK UNIFIED IDEOGRAPH
+0xAEC8	0x65C5	#CJK UNIFIED IDEOGRAPH
+0xAEC9	0x6642	#CJK UNIFIED IDEOGRAPH
+0xAECA	0x6649	#CJK UNIFIED IDEOGRAPH
+0xAECB	0x664F	#CJK UNIFIED IDEOGRAPH
+0xAECC	0x6643	#CJK UNIFIED IDEOGRAPH
+0xAECD	0x6652	#CJK UNIFIED IDEOGRAPH
+0xAECE	0x664C	#CJK UNIFIED IDEOGRAPH
+0xAECF	0x6645	#CJK UNIFIED IDEOGRAPH
+0xAED0	0x6641	#CJK UNIFIED IDEOGRAPH
+0xAED1	0x66F8	#CJK UNIFIED IDEOGRAPH
+0xAED2	0x6714	#CJK UNIFIED IDEOGRAPH
+0xAED3	0x6715	#CJK UNIFIED IDEOGRAPH
+0xAED4	0x6717	#CJK UNIFIED IDEOGRAPH
+0xAED5	0x6821	#CJK UNIFIED IDEOGRAPH
+0xAED6	0x6838	#CJK UNIFIED IDEOGRAPH
+0xAED7	0x6848	#CJK UNIFIED IDEOGRAPH
+0xAED8	0x6846	#CJK UNIFIED IDEOGRAPH
+0xAED9	0x6853	#CJK UNIFIED IDEOGRAPH
+0xAEDA	0x6839	#CJK UNIFIED IDEOGRAPH
+0xAEDB	0x6842	#CJK UNIFIED IDEOGRAPH
+0xAEDC	0x6854	#CJK UNIFIED IDEOGRAPH
+0xAEDD	0x6829	#CJK UNIFIED IDEOGRAPH
+0xAEDE	0x68B3	#CJK UNIFIED IDEOGRAPH
+0xAEDF	0x6817	#CJK UNIFIED IDEOGRAPH
+0xAEE0	0x684C	#CJK UNIFIED IDEOGRAPH
+0xAEE1	0x6851	#CJK UNIFIED IDEOGRAPH
+0xAEE2	0x683D	#CJK UNIFIED IDEOGRAPH
+0xAEE3	0x67F4	#CJK UNIFIED IDEOGRAPH
+0xAEE4	0x6850	#CJK UNIFIED IDEOGRAPH
+0xAEE5	0x6840	#CJK UNIFIED IDEOGRAPH
+0xAEE6	0x683C	#CJK UNIFIED IDEOGRAPH
+0xAEE7	0x6843	#CJK UNIFIED IDEOGRAPH
+0xAEE8	0x682A	#CJK UNIFIED IDEOGRAPH
+0xAEE9	0x6845	#CJK UNIFIED IDEOGRAPH
+0xAEEA	0x6813	#CJK UNIFIED IDEOGRAPH
+0xAEEB	0x6818	#CJK UNIFIED IDEOGRAPH
+0xAEEC	0x6841	#CJK UNIFIED IDEOGRAPH
+0xAEED	0x6B8A	#CJK UNIFIED IDEOGRAPH
+0xAEEE	0x6B89	#CJK UNIFIED IDEOGRAPH
+0xAEEF	0x6BB7	#CJK UNIFIED IDEOGRAPH
+0xAEF0	0x6C23	#CJK UNIFIED IDEOGRAPH
+0xAEF1	0x6C27	#CJK UNIFIED IDEOGRAPH
+0xAEF2	0x6C28	#CJK UNIFIED IDEOGRAPH
+0xAEF3	0x6C26	#CJK UNIFIED IDEOGRAPH
+0xAEF4	0x6C24	#CJK UNIFIED IDEOGRAPH
+0xAEF5	0x6CF0	#CJK UNIFIED IDEOGRAPH
+0xAEF6	0x6D6A	#CJK UNIFIED IDEOGRAPH
+0xAEF7	0x6D95	#CJK UNIFIED IDEOGRAPH
+0xAEF8	0x6D88	#CJK UNIFIED IDEOGRAPH
+0xAEF9	0x6D87	#CJK UNIFIED IDEOGRAPH
+0xAEFA	0x6D66	#CJK UNIFIED IDEOGRAPH
+0xAEFB	0x6D78	#CJK UNIFIED IDEOGRAPH
+0xAEFC	0x6D77	#CJK UNIFIED IDEOGRAPH
+0xAEFD	0x6D59	#CJK UNIFIED IDEOGRAPH
+0xAEFE	0x6D93	#CJK UNIFIED IDEOGRAPH
+0xAF40	0x6D6C	#CJK UNIFIED IDEOGRAPH
+0xAF41	0x6D89	#CJK UNIFIED IDEOGRAPH
+0xAF42	0x6D6E	#CJK UNIFIED IDEOGRAPH
+0xAF43	0x6D5A	#CJK UNIFIED IDEOGRAPH
+0xAF44	0x6D74	#CJK UNIFIED IDEOGRAPH
+0xAF45	0x6D69	#CJK UNIFIED IDEOGRAPH
+0xAF46	0x6D8C	#CJK UNIFIED IDEOGRAPH
+0xAF47	0x6D8A	#CJK UNIFIED IDEOGRAPH
+0xAF48	0x6D79	#CJK UNIFIED IDEOGRAPH
+0xAF49	0x6D85	#CJK UNIFIED IDEOGRAPH
+0xAF4A	0x6D65	#CJK UNIFIED IDEOGRAPH
+0xAF4B	0x6D94	#CJK UNIFIED IDEOGRAPH
+0xAF4C	0x70CA	#CJK UNIFIED IDEOGRAPH
+0xAF4D	0x70D8	#CJK UNIFIED IDEOGRAPH
+0xAF4E	0x70E4	#CJK UNIFIED IDEOGRAPH
+0xAF4F	0x70D9	#CJK UNIFIED IDEOGRAPH
+0xAF50	0x70C8	#CJK UNIFIED IDEOGRAPH
+0xAF51	0x70CF	#CJK UNIFIED IDEOGRAPH
+0xAF52	0x7239	#CJK UNIFIED IDEOGRAPH
+0xAF53	0x7279	#CJK UNIFIED IDEOGRAPH
+0xAF54	0x72FC	#CJK UNIFIED IDEOGRAPH
+0xAF55	0x72F9	#CJK UNIFIED IDEOGRAPH
+0xAF56	0x72FD	#CJK UNIFIED IDEOGRAPH
+0xAF57	0x72F8	#CJK UNIFIED IDEOGRAPH
+0xAF58	0x72F7	#CJK UNIFIED IDEOGRAPH
+0xAF59	0x7386	#CJK UNIFIED IDEOGRAPH
+0xAF5A	0x73ED	#CJK UNIFIED IDEOGRAPH
+0xAF5B	0x7409	#CJK UNIFIED IDEOGRAPH
+0xAF5C	0x73EE	#CJK UNIFIED IDEOGRAPH
+0xAF5D	0x73E0	#CJK UNIFIED IDEOGRAPH
+0xAF5E	0x73EA	#CJK UNIFIED IDEOGRAPH
+0xAF5F	0x73DE	#CJK UNIFIED IDEOGRAPH
+0xAF60	0x7554	#CJK UNIFIED IDEOGRAPH
+0xAF61	0x755D	#CJK UNIFIED IDEOGRAPH
+0xAF62	0x755C	#CJK UNIFIED IDEOGRAPH
+0xAF63	0x755A	#CJK UNIFIED IDEOGRAPH
+0xAF64	0x7559	#CJK UNIFIED IDEOGRAPH
+0xAF65	0x75BE	#CJK UNIFIED IDEOGRAPH
+0xAF66	0x75C5	#CJK UNIFIED IDEOGRAPH
+0xAF67	0x75C7	#CJK UNIFIED IDEOGRAPH
+0xAF68	0x75B2	#CJK UNIFIED IDEOGRAPH
+0xAF69	0x75B3	#CJK UNIFIED IDEOGRAPH
+0xAF6A	0x75BD	#CJK UNIFIED IDEOGRAPH
+0xAF6B	0x75BC	#CJK UNIFIED IDEOGRAPH
+0xAF6C	0x75B9	#CJK UNIFIED IDEOGRAPH
+0xAF6D	0x75C2	#CJK UNIFIED IDEOGRAPH
+0xAF6E	0x75B8	#CJK UNIFIED IDEOGRAPH
+0xAF6F	0x768B	#CJK UNIFIED IDEOGRAPH
+0xAF70	0x76B0	#CJK UNIFIED IDEOGRAPH
+0xAF71	0x76CA	#CJK UNIFIED IDEOGRAPH
+0xAF72	0x76CD	#CJK UNIFIED IDEOGRAPH
+0xAF73	0x76CE	#CJK UNIFIED IDEOGRAPH
+0xAF74	0x7729	#CJK UNIFIED IDEOGRAPH
+0xAF75	0x771F	#CJK UNIFIED IDEOGRAPH
+0xAF76	0x7720	#CJK UNIFIED IDEOGRAPH
+0xAF77	0x7728	#CJK UNIFIED IDEOGRAPH
+0xAF78	0x77E9	#CJK UNIFIED IDEOGRAPH
+0xAF79	0x7830	#CJK UNIFIED IDEOGRAPH
+0xAF7A	0x7827	#CJK UNIFIED IDEOGRAPH
+0xAF7B	0x7838	#CJK UNIFIED IDEOGRAPH
+0xAF7C	0x781D	#CJK UNIFIED IDEOGRAPH
+0xAF7D	0x7834	#CJK UNIFIED IDEOGRAPH
+0xAF7E	0x7837	#CJK UNIFIED IDEOGRAPH
+0xAFA1	0x7825	#CJK UNIFIED IDEOGRAPH
+0xAFA2	0x782D	#CJK UNIFIED IDEOGRAPH
+0xAFA3	0x7820	#CJK UNIFIED IDEOGRAPH
+0xAFA4	0x781F	#CJK UNIFIED IDEOGRAPH
+0xAFA5	0x7832	#CJK UNIFIED IDEOGRAPH
+0xAFA6	0x7955	#CJK UNIFIED IDEOGRAPH
+0xAFA7	0x7950	#CJK UNIFIED IDEOGRAPH
+0xAFA8	0x7960	#CJK UNIFIED IDEOGRAPH
+0xAFA9	0x795F	#CJK UNIFIED IDEOGRAPH
+0xAFAA	0x7956	#CJK UNIFIED IDEOGRAPH
+0xAFAB	0x795E	#CJK UNIFIED IDEOGRAPH
+0xAFAC	0x795D	#CJK UNIFIED IDEOGRAPH
+0xAFAD	0x7957	#CJK UNIFIED IDEOGRAPH
+0xAFAE	0x795A	#CJK UNIFIED IDEOGRAPH
+0xAFAF	0x79E4	#CJK UNIFIED IDEOGRAPH
+0xAFB0	0x79E3	#CJK UNIFIED IDEOGRAPH
+0xAFB1	0x79E7	#CJK UNIFIED IDEOGRAPH
+0xAFB2	0x79DF	#CJK UNIFIED IDEOGRAPH
+0xAFB3	0x79E6	#CJK UNIFIED IDEOGRAPH
+0xAFB4	0x79E9	#CJK UNIFIED IDEOGRAPH
+0xAFB5	0x79D8	#CJK UNIFIED IDEOGRAPH
+0xAFB6	0x7A84	#CJK UNIFIED IDEOGRAPH
+0xAFB7	0x7A88	#CJK UNIFIED IDEOGRAPH
+0xAFB8	0x7AD9	#CJK UNIFIED IDEOGRAPH
+0xAFB9	0x7B06	#CJK UNIFIED IDEOGRAPH
+0xAFBA	0x7B11	#CJK UNIFIED IDEOGRAPH
+0xAFBB	0x7C89	#CJK UNIFIED IDEOGRAPH
+0xAFBC	0x7D21	#CJK UNIFIED IDEOGRAPH
+0xAFBD	0x7D17	#CJK UNIFIED IDEOGRAPH
+0xAFBE	0x7D0B	#CJK UNIFIED IDEOGRAPH
+0xAFBF	0x7D0A	#CJK UNIFIED IDEOGRAPH
+0xAFC0	0x7D20	#CJK UNIFIED IDEOGRAPH
+0xAFC1	0x7D22	#CJK UNIFIED IDEOGRAPH
+0xAFC2	0x7D14	#CJK UNIFIED IDEOGRAPH
+0xAFC3	0x7D10	#CJK UNIFIED IDEOGRAPH
+0xAFC4	0x7D15	#CJK UNIFIED IDEOGRAPH
+0xAFC5	0x7D1A	#CJK UNIFIED IDEOGRAPH
+0xAFC6	0x7D1C	#CJK UNIFIED IDEOGRAPH
+0xAFC7	0x7D0D	#CJK UNIFIED IDEOGRAPH
+0xAFC8	0x7D19	#CJK UNIFIED IDEOGRAPH
+0xAFC9	0x7D1B	#CJK UNIFIED IDEOGRAPH
+0xAFCA	0x7F3A	#CJK UNIFIED IDEOGRAPH
+0xAFCB	0x7F5F	#CJK UNIFIED IDEOGRAPH
+0xAFCC	0x7F94	#CJK UNIFIED IDEOGRAPH
+0xAFCD	0x7FC5	#CJK UNIFIED IDEOGRAPH
+0xAFCE	0x7FC1	#CJK UNIFIED IDEOGRAPH
+0xAFCF	0x8006	#CJK UNIFIED IDEOGRAPH
+0xAFD0	0x8018	#CJK UNIFIED IDEOGRAPH
+0xAFD1	0x8015	#CJK UNIFIED IDEOGRAPH
+0xAFD2	0x8019	#CJK UNIFIED IDEOGRAPH
+0xAFD3	0x8017	#CJK UNIFIED IDEOGRAPH
+0xAFD4	0x803D	#CJK UNIFIED IDEOGRAPH
+0xAFD5	0x803F	#CJK UNIFIED IDEOGRAPH
+0xAFD6	0x80F1	#CJK UNIFIED IDEOGRAPH
+0xAFD7	0x8102	#CJK UNIFIED IDEOGRAPH
+0xAFD8	0x80F0	#CJK UNIFIED IDEOGRAPH
+0xAFD9	0x8105	#CJK UNIFIED IDEOGRAPH
+0xAFDA	0x80ED	#CJK UNIFIED IDEOGRAPH
+0xAFDB	0x80F4	#CJK UNIFIED IDEOGRAPH
+0xAFDC	0x8106	#CJK UNIFIED IDEOGRAPH
+0xAFDD	0x80F8	#CJK UNIFIED IDEOGRAPH
+0xAFDE	0x80F3	#CJK UNIFIED IDEOGRAPH
+0xAFDF	0x8108	#CJK UNIFIED IDEOGRAPH
+0xAFE0	0x80FD	#CJK UNIFIED IDEOGRAPH
+0xAFE1	0x810A	#CJK UNIFIED IDEOGRAPH
+0xAFE2	0x80FC	#CJK UNIFIED IDEOGRAPH
+0xAFE3	0x80EF	#CJK UNIFIED IDEOGRAPH
+0xAFE4	0x81ED	#CJK UNIFIED IDEOGRAPH
+0xAFE5	0x81EC	#CJK UNIFIED IDEOGRAPH
+0xAFE6	0x8200	#CJK UNIFIED IDEOGRAPH
+0xAFE7	0x8210	#CJK UNIFIED IDEOGRAPH
+0xAFE8	0x822A	#CJK UNIFIED IDEOGRAPH
+0xAFE9	0x822B	#CJK UNIFIED IDEOGRAPH
+0xAFEA	0x8228	#CJK UNIFIED IDEOGRAPH
+0xAFEB	0x822C	#CJK UNIFIED IDEOGRAPH
+0xAFEC	0x82BB	#CJK UNIFIED IDEOGRAPH
+0xAFED	0x832B	#CJK UNIFIED IDEOGRAPH
+0xAFEE	0x8352	#CJK UNIFIED IDEOGRAPH
+0xAFEF	0x8354	#CJK UNIFIED IDEOGRAPH
+0xAFF0	0x834A	#CJK UNIFIED IDEOGRAPH
+0xAFF1	0x8338	#CJK UNIFIED IDEOGRAPH
+0xAFF2	0x8350	#CJK UNIFIED IDEOGRAPH
+0xAFF3	0x8349	#CJK UNIFIED IDEOGRAPH
+0xAFF4	0x8335	#CJK UNIFIED IDEOGRAPH
+0xAFF5	0x8334	#CJK UNIFIED IDEOGRAPH
+0xAFF6	0x834F	#CJK UNIFIED IDEOGRAPH
+0xAFF7	0x8332	#CJK UNIFIED IDEOGRAPH
+0xAFF8	0x8339	#CJK UNIFIED IDEOGRAPH
+0xAFF9	0x8336	#CJK UNIFIED IDEOGRAPH
+0xAFFA	0x8317	#CJK UNIFIED IDEOGRAPH
+0xAFFB	0x8340	#CJK UNIFIED IDEOGRAPH
+0xAFFC	0x8331	#CJK UNIFIED IDEOGRAPH
+0xAFFD	0x8328	#CJK UNIFIED IDEOGRAPH
+0xAFFE	0x8343	#CJK UNIFIED IDEOGRAPH
+0xB040	0x8654	#CJK UNIFIED IDEOGRAPH
+0xB041	0x868A	#CJK UNIFIED IDEOGRAPH
+0xB042	0x86AA	#CJK UNIFIED IDEOGRAPH
+0xB043	0x8693	#CJK UNIFIED IDEOGRAPH
+0xB044	0x86A4	#CJK UNIFIED IDEOGRAPH
+0xB045	0x86A9	#CJK UNIFIED IDEOGRAPH
+0xB046	0x868C	#CJK UNIFIED IDEOGRAPH
+0xB047	0x86A3	#CJK UNIFIED IDEOGRAPH
+0xB048	0x869C	#CJK UNIFIED IDEOGRAPH
+0xB049	0x8870	#CJK UNIFIED IDEOGRAPH
+0xB04A	0x8877	#CJK UNIFIED IDEOGRAPH
+0xB04B	0x8881	#CJK UNIFIED IDEOGRAPH
+0xB04C	0x8882	#CJK UNIFIED IDEOGRAPH
+0xB04D	0x887D	#CJK UNIFIED IDEOGRAPH
+0xB04E	0x8879	#CJK UNIFIED IDEOGRAPH
+0xB04F	0x8A18	#CJK UNIFIED IDEOGRAPH
+0xB050	0x8A10	#CJK UNIFIED IDEOGRAPH
+0xB051	0x8A0E	#CJK UNIFIED IDEOGRAPH
+0xB052	0x8A0C	#CJK UNIFIED IDEOGRAPH
+0xB053	0x8A15	#CJK UNIFIED IDEOGRAPH
+0xB054	0x8A0A	#CJK UNIFIED IDEOGRAPH
+0xB055	0x8A17	#CJK UNIFIED IDEOGRAPH
+0xB056	0x8A13	#CJK UNIFIED IDEOGRAPH
+0xB057	0x8A16	#CJK UNIFIED IDEOGRAPH
+0xB058	0x8A0F	#CJK UNIFIED IDEOGRAPH
+0xB059	0x8A11	#CJK UNIFIED IDEOGRAPH
+0xB05A	0x8C48	#CJK UNIFIED IDEOGRAPH
+0xB05B	0x8C7A	#CJK UNIFIED IDEOGRAPH
+0xB05C	0x8C79	#CJK UNIFIED IDEOGRAPH
+0xB05D	0x8CA1	#CJK UNIFIED IDEOGRAPH
+0xB05E	0x8CA2	#CJK UNIFIED IDEOGRAPH
+0xB05F	0x8D77	#CJK UNIFIED IDEOGRAPH
+0xB060	0x8EAC	#CJK UNIFIED IDEOGRAPH
+0xB061	0x8ED2	#CJK UNIFIED IDEOGRAPH
+0xB062	0x8ED4	#CJK UNIFIED IDEOGRAPH
+0xB063	0x8ECF	#CJK UNIFIED IDEOGRAPH
+0xB064	0x8FB1	#CJK UNIFIED IDEOGRAPH
+0xB065	0x9001	#CJK UNIFIED IDEOGRAPH
+0xB066	0x9006	#CJK UNIFIED IDEOGRAPH
+0xB067	0x8FF7	#CJK UNIFIED IDEOGRAPH
+0xB068	0x9000	#CJK UNIFIED IDEOGRAPH
+0xB069	0x8FFA	#CJK UNIFIED IDEOGRAPH
+0xB06A	0x8FF4	#CJK UNIFIED IDEOGRAPH
+0xB06B	0x9003	#CJK UNIFIED IDEOGRAPH
+0xB06C	0x8FFD	#CJK UNIFIED IDEOGRAPH
+0xB06D	0x9005	#CJK UNIFIED IDEOGRAPH
+0xB06E	0x8FF8	#CJK UNIFIED IDEOGRAPH
+0xB06F	0x9095	#CJK UNIFIED IDEOGRAPH
+0xB070	0x90E1	#CJK UNIFIED IDEOGRAPH
+0xB071	0x90DD	#CJK UNIFIED IDEOGRAPH
+0xB072	0x90E2	#CJK UNIFIED IDEOGRAPH
+0xB073	0x9152	#CJK UNIFIED IDEOGRAPH
+0xB074	0x914D	#CJK UNIFIED IDEOGRAPH
+0xB075	0x914C	#CJK UNIFIED IDEOGRAPH
+0xB076	0x91D8	#CJK UNIFIED IDEOGRAPH
+0xB077	0x91DD	#CJK UNIFIED IDEOGRAPH
+0xB078	0x91D7	#CJK UNIFIED IDEOGRAPH
+0xB079	0x91DC	#CJK UNIFIED IDEOGRAPH
+0xB07A	0x91D9	#CJK UNIFIED IDEOGRAPH
+0xB07B	0x9583	#CJK UNIFIED IDEOGRAPH
+0xB07C	0x9662	#CJK UNIFIED IDEOGRAPH
+0xB07D	0x9663	#CJK UNIFIED IDEOGRAPH
+0xB07E	0x9661	#CJK UNIFIED IDEOGRAPH
+0xB0A1	0x965B	#CJK UNIFIED IDEOGRAPH
+0xB0A2	0x965D	#CJK UNIFIED IDEOGRAPH
+0xB0A3	0x9664	#CJK UNIFIED IDEOGRAPH
+0xB0A4	0x9658	#CJK UNIFIED IDEOGRAPH
+0xB0A5	0x965E	#CJK UNIFIED IDEOGRAPH
+0xB0A6	0x96BB	#CJK UNIFIED IDEOGRAPH
+0xB0A7	0x98E2	#CJK UNIFIED IDEOGRAPH
+0xB0A8	0x99AC	#CJK UNIFIED IDEOGRAPH
+0xB0A9	0x9AA8	#CJK UNIFIED IDEOGRAPH
+0xB0AA	0x9AD8	#CJK UNIFIED IDEOGRAPH
+0xB0AB	0x9B25	#CJK UNIFIED IDEOGRAPH
+0xB0AC	0x9B32	#CJK UNIFIED IDEOGRAPH
+0xB0AD	0x9B3C	#CJK UNIFIED IDEOGRAPH
+0xB0AE	0x4E7E	#CJK UNIFIED IDEOGRAPH
+0xB0AF	0x507A	#CJK UNIFIED IDEOGRAPH
+0xB0B0	0x507D	#CJK UNIFIED IDEOGRAPH
+0xB0B1	0x505C	#CJK UNIFIED IDEOGRAPH
+0xB0B2	0x5047	#CJK UNIFIED IDEOGRAPH
+0xB0B3	0x5043	#CJK UNIFIED IDEOGRAPH
+0xB0B4	0x504C	#CJK UNIFIED IDEOGRAPH
+0xB0B5	0x505A	#CJK UNIFIED IDEOGRAPH
+0xB0B6	0x5049	#CJK UNIFIED IDEOGRAPH
+0xB0B7	0x5065	#CJK UNIFIED IDEOGRAPH
+0xB0B8	0x5076	#CJK UNIFIED IDEOGRAPH
+0xB0B9	0x504E	#CJK UNIFIED IDEOGRAPH
+0xB0BA	0x5055	#CJK UNIFIED IDEOGRAPH
+0xB0BB	0x5075	#CJK UNIFIED IDEOGRAPH
+0xB0BC	0x5074	#CJK UNIFIED IDEOGRAPH
+0xB0BD	0x5077	#CJK UNIFIED IDEOGRAPH
+0xB0BE	0x504F	#CJK UNIFIED IDEOGRAPH
+0xB0BF	0x500F	#CJK UNIFIED IDEOGRAPH
+0xB0C0	0x506F	#CJK UNIFIED IDEOGRAPH
+0xB0C1	0x506D	#CJK UNIFIED IDEOGRAPH
+0xB0C2	0x515C	#CJK UNIFIED IDEOGRAPH
+0xB0C3	0x5195	#CJK UNIFIED IDEOGRAPH
+0xB0C4	0x51F0	#CJK UNIFIED IDEOGRAPH
+0xB0C5	0x526A	#CJK UNIFIED IDEOGRAPH
+0xB0C6	0x526F	#CJK UNIFIED IDEOGRAPH
+0xB0C7	0x52D2	#CJK UNIFIED IDEOGRAPH
+0xB0C8	0x52D9	#CJK UNIFIED IDEOGRAPH
+0xB0C9	0x52D8	#CJK UNIFIED IDEOGRAPH
+0xB0CA	0x52D5	#CJK UNIFIED IDEOGRAPH
+0xB0CB	0x5310	#CJK UNIFIED IDEOGRAPH
+0xB0CC	0x530F	#CJK UNIFIED IDEOGRAPH
+0xB0CD	0x5319	#CJK UNIFIED IDEOGRAPH
+0xB0CE	0x533F	#CJK UNIFIED IDEOGRAPH
+0xB0CF	0x5340	#CJK UNIFIED IDEOGRAPH
+0xB0D0	0x533E	#CJK UNIFIED IDEOGRAPH
+0xB0D1	0x53C3	#CJK UNIFIED IDEOGRAPH
+0xB0D2	0x66FC	#CJK UNIFIED IDEOGRAPH
+0xB0D3	0x5546	#CJK UNIFIED IDEOGRAPH
+0xB0D4	0x556A	#CJK UNIFIED IDEOGRAPH
+0xB0D5	0x5566	#CJK UNIFIED IDEOGRAPH
+0xB0D6	0x5544	#CJK UNIFIED IDEOGRAPH
+0xB0D7	0x555E	#CJK UNIFIED IDEOGRAPH
+0xB0D8	0x5561	#CJK UNIFIED IDEOGRAPH
+0xB0D9	0x5543	#CJK UNIFIED IDEOGRAPH
+0xB0DA	0x554A	#CJK UNIFIED IDEOGRAPH
+0xB0DB	0x5531	#CJK UNIFIED IDEOGRAPH
+0xB0DC	0x5556	#CJK UNIFIED IDEOGRAPH
+0xB0DD	0x554F	#CJK UNIFIED IDEOGRAPH
+0xB0DE	0x5555	#CJK UNIFIED IDEOGRAPH
+0xB0DF	0x552F	#CJK UNIFIED IDEOGRAPH
+0xB0E0	0x5564	#CJK UNIFIED IDEOGRAPH
+0xB0E1	0x5538	#CJK UNIFIED IDEOGRAPH
+0xB0E2	0x552E	#CJK UNIFIED IDEOGRAPH
+0xB0E3	0x555C	#CJK UNIFIED IDEOGRAPH
+0xB0E4	0x552C	#CJK UNIFIED IDEOGRAPH
+0xB0E5	0x5563	#CJK UNIFIED IDEOGRAPH
+0xB0E6	0x5533	#CJK UNIFIED IDEOGRAPH
+0xB0E7	0x5541	#CJK UNIFIED IDEOGRAPH
+0xB0E8	0x5557	#CJK UNIFIED IDEOGRAPH
+0xB0E9	0x5708	#CJK UNIFIED IDEOGRAPH
+0xB0EA	0x570B	#CJK UNIFIED IDEOGRAPH
+0xB0EB	0x5709	#CJK UNIFIED IDEOGRAPH
+0xB0EC	0x57DF	#CJK UNIFIED IDEOGRAPH
+0xB0ED	0x5805	#CJK UNIFIED IDEOGRAPH
+0xB0EE	0x580A	#CJK UNIFIED IDEOGRAPH
+0xB0EF	0x5806	#CJK UNIFIED IDEOGRAPH
+0xB0F0	0x57E0	#CJK UNIFIED IDEOGRAPH
+0xB0F1	0x57E4	#CJK UNIFIED IDEOGRAPH
+0xB0F2	0x57FA	#CJK UNIFIED IDEOGRAPH
+0xB0F3	0x5802	#CJK UNIFIED IDEOGRAPH
+0xB0F4	0x5835	#CJK UNIFIED IDEOGRAPH
+0xB0F5	0x57F7	#CJK UNIFIED IDEOGRAPH
+0xB0F6	0x57F9	#CJK UNIFIED IDEOGRAPH
+0xB0F7	0x5920	#CJK UNIFIED IDEOGRAPH
+0xB0F8	0x5962	#CJK UNIFIED IDEOGRAPH
+0xB0F9	0x5A36	#CJK UNIFIED IDEOGRAPH
+0xB0FA	0x5A41	#CJK UNIFIED IDEOGRAPH
+0xB0FB	0x5A49	#CJK UNIFIED IDEOGRAPH
+0xB0FC	0x5A66	#CJK UNIFIED IDEOGRAPH
+0xB0FD	0x5A6A	#CJK UNIFIED IDEOGRAPH
+0xB0FE	0x5A40	#CJK UNIFIED IDEOGRAPH
+0xB140	0x5A3C	#CJK UNIFIED IDEOGRAPH
+0xB141	0x5A62	#CJK UNIFIED IDEOGRAPH
+0xB142	0x5A5A	#CJK UNIFIED IDEOGRAPH
+0xB143	0x5A46	#CJK UNIFIED IDEOGRAPH
+0xB144	0x5A4A	#CJK UNIFIED IDEOGRAPH
+0xB145	0x5B70	#CJK UNIFIED IDEOGRAPH
+0xB146	0x5BC7	#CJK UNIFIED IDEOGRAPH
+0xB147	0x5BC5	#CJK UNIFIED IDEOGRAPH
+0xB148	0x5BC4	#CJK UNIFIED IDEOGRAPH
+0xB149	0x5BC2	#CJK UNIFIED IDEOGRAPH
+0xB14A	0x5BBF	#CJK UNIFIED IDEOGRAPH
+0xB14B	0x5BC6	#CJK UNIFIED IDEOGRAPH
+0xB14C	0x5C09	#CJK UNIFIED IDEOGRAPH
+0xB14D	0x5C08	#CJK UNIFIED IDEOGRAPH
+0xB14E	0x5C07	#CJK UNIFIED IDEOGRAPH
+0xB14F	0x5C60	#CJK UNIFIED IDEOGRAPH
+0xB150	0x5C5C	#CJK UNIFIED IDEOGRAPH
+0xB151	0x5C5D	#CJK UNIFIED IDEOGRAPH
+0xB152	0x5D07	#CJK UNIFIED IDEOGRAPH
+0xB153	0x5D06	#CJK UNIFIED IDEOGRAPH
+0xB154	0x5D0E	#CJK UNIFIED IDEOGRAPH
+0xB155	0x5D1B	#CJK UNIFIED IDEOGRAPH
+0xB156	0x5D16	#CJK UNIFIED IDEOGRAPH
+0xB157	0x5D22	#CJK UNIFIED IDEOGRAPH
+0xB158	0x5D11	#CJK UNIFIED IDEOGRAPH
+0xB159	0x5D29	#CJK UNIFIED IDEOGRAPH
+0xB15A	0x5D14	#CJK UNIFIED IDEOGRAPH
+0xB15B	0x5D19	#CJK UNIFIED IDEOGRAPH
+0xB15C	0x5D24	#CJK UNIFIED IDEOGRAPH
+0xB15D	0x5D27	#CJK UNIFIED IDEOGRAPH
+0xB15E	0x5D17	#CJK UNIFIED IDEOGRAPH
+0xB15F	0x5DE2	#CJK UNIFIED IDEOGRAPH
+0xB160	0x5E38	#CJK UNIFIED IDEOGRAPH
+0xB161	0x5E36	#CJK UNIFIED IDEOGRAPH
+0xB162	0x5E33	#CJK UNIFIED IDEOGRAPH
+0xB163	0x5E37	#CJK UNIFIED IDEOGRAPH
+0xB164	0x5EB7	#CJK UNIFIED IDEOGRAPH
+0xB165	0x5EB8	#CJK UNIFIED IDEOGRAPH
+0xB166	0x5EB6	#CJK UNIFIED IDEOGRAPH
+0xB167	0x5EB5	#CJK UNIFIED IDEOGRAPH
+0xB168	0x5EBE	#CJK UNIFIED IDEOGRAPH
+0xB169	0x5F35	#CJK UNIFIED IDEOGRAPH
+0xB16A	0x5F37	#CJK UNIFIED IDEOGRAPH
+0xB16B	0x5F57	#CJK UNIFIED IDEOGRAPH
+0xB16C	0x5F6C	#CJK UNIFIED IDEOGRAPH
+0xB16D	0x5F69	#CJK UNIFIED IDEOGRAPH
+0xB16E	0x5F6B	#CJK UNIFIED IDEOGRAPH
+0xB16F	0x5F97	#CJK UNIFIED IDEOGRAPH
+0xB170	0x5F99	#CJK UNIFIED IDEOGRAPH
+0xB171	0x5F9E	#CJK UNIFIED IDEOGRAPH
+0xB172	0x5F98	#CJK UNIFIED IDEOGRAPH
+0xB173	0x5FA1	#CJK UNIFIED IDEOGRAPH
+0xB174	0x5FA0	#CJK UNIFIED IDEOGRAPH
+0xB175	0x5F9C	#CJK UNIFIED IDEOGRAPH
+0xB176	0x607F	#CJK UNIFIED IDEOGRAPH
+0xB177	0x60A3	#CJK UNIFIED IDEOGRAPH
+0xB178	0x6089	#CJK UNIFIED IDEOGRAPH
+0xB179	0x60A0	#CJK UNIFIED IDEOGRAPH
+0xB17A	0x60A8	#CJK UNIFIED IDEOGRAPH
+0xB17B	0x60CB	#CJK UNIFIED IDEOGRAPH
+0xB17C	0x60B4	#CJK UNIFIED IDEOGRAPH
+0xB17D	0x60E6	#CJK UNIFIED IDEOGRAPH
+0xB17E	0x60BD	#CJK UNIFIED IDEOGRAPH
+0xB1A1	0x60C5	#CJK UNIFIED IDEOGRAPH
+0xB1A2	0x60BB	#CJK UNIFIED IDEOGRAPH
+0xB1A3	0x60B5	#CJK UNIFIED IDEOGRAPH
+0xB1A4	0x60DC	#CJK UNIFIED IDEOGRAPH
+0xB1A5	0x60BC	#CJK UNIFIED IDEOGRAPH
+0xB1A6	0x60D8	#CJK UNIFIED IDEOGRAPH
+0xB1A7	0x60D5	#CJK UNIFIED IDEOGRAPH
+0xB1A8	0x60C6	#CJK UNIFIED IDEOGRAPH
+0xB1A9	0x60DF	#CJK UNIFIED IDEOGRAPH
+0xB1AA	0x60B8	#CJK UNIFIED IDEOGRAPH
+0xB1AB	0x60DA	#CJK UNIFIED IDEOGRAPH
+0xB1AC	0x60C7	#CJK UNIFIED IDEOGRAPH
+0xB1AD	0x621A	#CJK UNIFIED IDEOGRAPH
+0xB1AE	0x621B	#CJK UNIFIED IDEOGRAPH
+0xB1AF	0x6248	#CJK UNIFIED IDEOGRAPH
+0xB1B0	0x63A0	#CJK UNIFIED IDEOGRAPH
+0xB1B1	0x63A7	#CJK UNIFIED IDEOGRAPH
+0xB1B2	0x6372	#CJK UNIFIED IDEOGRAPH
+0xB1B3	0x6396	#CJK UNIFIED IDEOGRAPH
+0xB1B4	0x63A2	#CJK UNIFIED IDEOGRAPH
+0xB1B5	0x63A5	#CJK UNIFIED IDEOGRAPH
+0xB1B6	0x6377	#CJK UNIFIED IDEOGRAPH
+0xB1B7	0x6367	#CJK UNIFIED IDEOGRAPH
+0xB1B8	0x6398	#CJK UNIFIED IDEOGRAPH
+0xB1B9	0x63AA	#CJK UNIFIED IDEOGRAPH
+0xB1BA	0x6371	#CJK UNIFIED IDEOGRAPH
+0xB1BB	0x63A9	#CJK UNIFIED IDEOGRAPH
+0xB1BC	0x6389	#CJK UNIFIED IDEOGRAPH
+0xB1BD	0x6383	#CJK UNIFIED IDEOGRAPH
+0xB1BE	0x639B	#CJK UNIFIED IDEOGRAPH
+0xB1BF	0x636B	#CJK UNIFIED IDEOGRAPH
+0xB1C0	0x63A8	#CJK UNIFIED IDEOGRAPH
+0xB1C1	0x6384	#CJK UNIFIED IDEOGRAPH
+0xB1C2	0x6388	#CJK UNIFIED IDEOGRAPH
+0xB1C3	0x6399	#CJK UNIFIED IDEOGRAPH
+0xB1C4	0x63A1	#CJK UNIFIED IDEOGRAPH
+0xB1C5	0x63AC	#CJK UNIFIED IDEOGRAPH
+0xB1C6	0x6392	#CJK UNIFIED IDEOGRAPH
+0xB1C7	0x638F	#CJK UNIFIED IDEOGRAPH
+0xB1C8	0x6380	#CJK UNIFIED IDEOGRAPH
+0xB1C9	0x637B	#CJK UNIFIED IDEOGRAPH
+0xB1CA	0x6369	#CJK UNIFIED IDEOGRAPH
+0xB1CB	0x6368	#CJK UNIFIED IDEOGRAPH
+0xB1CC	0x637A	#CJK UNIFIED IDEOGRAPH
+0xB1CD	0x655D	#CJK UNIFIED IDEOGRAPH
+0xB1CE	0x6556	#CJK UNIFIED IDEOGRAPH
+0xB1CF	0x6551	#CJK UNIFIED IDEOGRAPH
+0xB1D0	0x6559	#CJK UNIFIED IDEOGRAPH
+0xB1D1	0x6557	#CJK UNIFIED IDEOGRAPH
+0xB1D2	0x555F	#CJK UNIFIED IDEOGRAPH
+0xB1D3	0x654F	#CJK UNIFIED IDEOGRAPH
+0xB1D4	0x6558	#CJK UNIFIED IDEOGRAPH
+0xB1D5	0x6555	#CJK UNIFIED IDEOGRAPH
+0xB1D6	0x6554	#CJK UNIFIED IDEOGRAPH
+0xB1D7	0x659C	#CJK UNIFIED IDEOGRAPH
+0xB1D8	0x659B	#CJK UNIFIED IDEOGRAPH
+0xB1D9	0x65AC	#CJK UNIFIED IDEOGRAPH
+0xB1DA	0x65CF	#CJK UNIFIED IDEOGRAPH
+0xB1DB	0x65CB	#CJK UNIFIED IDEOGRAPH
+0xB1DC	0x65CC	#CJK UNIFIED IDEOGRAPH
+0xB1DD	0x65CE	#CJK UNIFIED IDEOGRAPH
+0xB1DE	0x665D	#CJK UNIFIED IDEOGRAPH
+0xB1DF	0x665A	#CJK UNIFIED IDEOGRAPH
+0xB1E0	0x6664	#CJK UNIFIED IDEOGRAPH
+0xB1E1	0x6668	#CJK UNIFIED IDEOGRAPH
+0xB1E2	0x6666	#CJK UNIFIED IDEOGRAPH
+0xB1E3	0x665E	#CJK UNIFIED IDEOGRAPH
+0xB1E4	0x66F9	#CJK UNIFIED IDEOGRAPH
+0xB1E5	0x52D7	#CJK UNIFIED IDEOGRAPH
+0xB1E6	0x671B	#CJK UNIFIED IDEOGRAPH
+0xB1E7	0x6881	#CJK UNIFIED IDEOGRAPH
+0xB1E8	0x68AF	#CJK UNIFIED IDEOGRAPH
+0xB1E9	0x68A2	#CJK UNIFIED IDEOGRAPH
+0xB1EA	0x6893	#CJK UNIFIED IDEOGRAPH
+0xB1EB	0x68B5	#CJK UNIFIED IDEOGRAPH
+0xB1EC	0x687F	#CJK UNIFIED IDEOGRAPH
+0xB1ED	0x6876	#CJK UNIFIED IDEOGRAPH
+0xB1EE	0x68B1	#CJK UNIFIED IDEOGRAPH
+0xB1EF	0x68A7	#CJK UNIFIED IDEOGRAPH
+0xB1F0	0x6897	#CJK UNIFIED IDEOGRAPH
+0xB1F1	0x68B0	#CJK UNIFIED IDEOGRAPH
+0xB1F2	0x6883	#CJK UNIFIED IDEOGRAPH
+0xB1F3	0x68C4	#CJK UNIFIED IDEOGRAPH
+0xB1F4	0x68AD	#CJK UNIFIED IDEOGRAPH
+0xB1F5	0x6886	#CJK UNIFIED IDEOGRAPH
+0xB1F6	0x6885	#CJK UNIFIED IDEOGRAPH
+0xB1F7	0x6894	#CJK UNIFIED IDEOGRAPH
+0xB1F8	0x689D	#CJK UNIFIED IDEOGRAPH
+0xB1F9	0x68A8	#CJK UNIFIED IDEOGRAPH
+0xB1FA	0x689F	#CJK UNIFIED IDEOGRAPH
+0xB1FB	0x68A1	#CJK UNIFIED IDEOGRAPH
+0xB1FC	0x6882	#CJK UNIFIED IDEOGRAPH
+0xB1FD	0x6B32	#CJK UNIFIED IDEOGRAPH
+0xB1FE	0x6BBA	#CJK UNIFIED IDEOGRAPH
+0xB240	0x6BEB	#CJK UNIFIED IDEOGRAPH
+0xB241	0x6BEC	#CJK UNIFIED IDEOGRAPH
+0xB242	0x6C2B	#CJK UNIFIED IDEOGRAPH
+0xB243	0x6D8E	#CJK UNIFIED IDEOGRAPH
+0xB244	0x6DBC	#CJK UNIFIED IDEOGRAPH
+0xB245	0x6DF3	#CJK UNIFIED IDEOGRAPH
+0xB246	0x6DD9	#CJK UNIFIED IDEOGRAPH
+0xB247	0x6DB2	#CJK UNIFIED IDEOGRAPH
+0xB248	0x6DE1	#CJK UNIFIED IDEOGRAPH
+0xB249	0x6DCC	#CJK UNIFIED IDEOGRAPH
+0xB24A	0x6DE4	#CJK UNIFIED IDEOGRAPH
+0xB24B	0x6DFB	#CJK UNIFIED IDEOGRAPH
+0xB24C	0x6DFA	#CJK UNIFIED IDEOGRAPH
+0xB24D	0x6E05	#CJK UNIFIED IDEOGRAPH
+0xB24E	0x6DC7	#CJK UNIFIED IDEOGRAPH
+0xB24F	0x6DCB	#CJK UNIFIED IDEOGRAPH
+0xB250	0x6DAF	#CJK UNIFIED IDEOGRAPH
+0xB251	0x6DD1	#CJK UNIFIED IDEOGRAPH
+0xB252	0x6DAE	#CJK UNIFIED IDEOGRAPH
+0xB253	0x6DDE	#CJK UNIFIED IDEOGRAPH
+0xB254	0x6DF9	#CJK UNIFIED IDEOGRAPH
+0xB255	0x6DB8	#CJK UNIFIED IDEOGRAPH
+0xB256	0x6DF7	#CJK UNIFIED IDEOGRAPH
+0xB257	0x6DF5	#CJK UNIFIED IDEOGRAPH
+0xB258	0x6DC5	#CJK UNIFIED IDEOGRAPH
+0xB259	0x6DD2	#CJK UNIFIED IDEOGRAPH
+0xB25A	0x6E1A	#CJK UNIFIED IDEOGRAPH
+0xB25B	0x6DB5	#CJK UNIFIED IDEOGRAPH
+0xB25C	0x6DDA	#CJK UNIFIED IDEOGRAPH
+0xB25D	0x6DEB	#CJK UNIFIED IDEOGRAPH
+0xB25E	0x6DD8	#CJK UNIFIED IDEOGRAPH
+0xB25F	0x6DEA	#CJK UNIFIED IDEOGRAPH
+0xB260	0x6DF1	#CJK UNIFIED IDEOGRAPH
+0xB261	0x6DEE	#CJK UNIFIED IDEOGRAPH
+0xB262	0x6DE8	#CJK UNIFIED IDEOGRAPH
+0xB263	0x6DC6	#CJK UNIFIED IDEOGRAPH
+0xB264	0x6DC4	#CJK UNIFIED IDEOGRAPH
+0xB265	0x6DAA	#CJK UNIFIED IDEOGRAPH
+0xB266	0x6DEC	#CJK UNIFIED IDEOGRAPH
+0xB267	0x6DBF	#CJK UNIFIED IDEOGRAPH
+0xB268	0x6DE6	#CJK UNIFIED IDEOGRAPH
+0xB269	0x70F9	#CJK UNIFIED IDEOGRAPH
+0xB26A	0x7109	#CJK UNIFIED IDEOGRAPH
+0xB26B	0x710A	#CJK UNIFIED IDEOGRAPH
+0xB26C	0x70FD	#CJK UNIFIED IDEOGRAPH
+0xB26D	0x70EF	#CJK UNIFIED IDEOGRAPH
+0xB26E	0x723D	#CJK UNIFIED IDEOGRAPH
+0xB26F	0x727D	#CJK UNIFIED IDEOGRAPH
+0xB270	0x7281	#CJK UNIFIED IDEOGRAPH
+0xB271	0x731C	#CJK UNIFIED IDEOGRAPH
+0xB272	0x731B	#CJK UNIFIED IDEOGRAPH
+0xB273	0x7316	#CJK UNIFIED IDEOGRAPH
+0xB274	0x7313	#CJK UNIFIED IDEOGRAPH
+0xB275	0x7319	#CJK UNIFIED IDEOGRAPH
+0xB276	0x7387	#CJK UNIFIED IDEOGRAPH
+0xB277	0x7405	#CJK UNIFIED IDEOGRAPH
+0xB278	0x740A	#CJK UNIFIED IDEOGRAPH
+0xB279	0x7403	#CJK UNIFIED IDEOGRAPH
+0xB27A	0x7406	#CJK UNIFIED IDEOGRAPH
+0xB27B	0x73FE	#CJK UNIFIED IDEOGRAPH
+0xB27C	0x740D	#CJK UNIFIED IDEOGRAPH
+0xB27D	0x74E0	#CJK UNIFIED IDEOGRAPH
+0xB27E	0x74F6	#CJK UNIFIED IDEOGRAPH
+0xB2A1	0x74F7	#CJK UNIFIED IDEOGRAPH
+0xB2A2	0x751C	#CJK UNIFIED IDEOGRAPH
+0xB2A3	0x7522	#CJK UNIFIED IDEOGRAPH
+0xB2A4	0x7565	#CJK UNIFIED IDEOGRAPH
+0xB2A5	0x7566	#CJK UNIFIED IDEOGRAPH
+0xB2A6	0x7562	#CJK UNIFIED IDEOGRAPH
+0xB2A7	0x7570	#CJK UNIFIED IDEOGRAPH
+0xB2A8	0x758F	#CJK UNIFIED IDEOGRAPH
+0xB2A9	0x75D4	#CJK UNIFIED IDEOGRAPH
+0xB2AA	0x75D5	#CJK UNIFIED IDEOGRAPH
+0xB2AB	0x75B5	#CJK UNIFIED IDEOGRAPH
+0xB2AC	0x75CA	#CJK UNIFIED IDEOGRAPH
+0xB2AD	0x75CD	#CJK UNIFIED IDEOGRAPH
+0xB2AE	0x768E	#CJK UNIFIED IDEOGRAPH
+0xB2AF	0x76D4	#CJK UNIFIED IDEOGRAPH
+0xB2B0	0x76D2	#CJK UNIFIED IDEOGRAPH
+0xB2B1	0x76DB	#CJK UNIFIED IDEOGRAPH
+0xB2B2	0x7737	#CJK UNIFIED IDEOGRAPH
+0xB2B3	0x773E	#CJK UNIFIED IDEOGRAPH
+0xB2B4	0x773C	#CJK UNIFIED IDEOGRAPH
+0xB2B5	0x7736	#CJK UNIFIED IDEOGRAPH
+0xB2B6	0x7738	#CJK UNIFIED IDEOGRAPH
+0xB2B7	0x773A	#CJK UNIFIED IDEOGRAPH
+0xB2B8	0x786B	#CJK UNIFIED IDEOGRAPH
+0xB2B9	0x7843	#CJK UNIFIED IDEOGRAPH
+0xB2BA	0x784E	#CJK UNIFIED IDEOGRAPH
+0xB2BB	0x7965	#CJK UNIFIED IDEOGRAPH
+0xB2BC	0x7968	#CJK UNIFIED IDEOGRAPH
+0xB2BD	0x796D	#CJK UNIFIED IDEOGRAPH
+0xB2BE	0x79FB	#CJK UNIFIED IDEOGRAPH
+0xB2BF	0x7A92	#CJK UNIFIED IDEOGRAPH
+0xB2C0	0x7A95	#CJK UNIFIED IDEOGRAPH
+0xB2C1	0x7B20	#CJK UNIFIED IDEOGRAPH
+0xB2C2	0x7B28	#CJK UNIFIED IDEOGRAPH
+0xB2C3	0x7B1B	#CJK UNIFIED IDEOGRAPH
+0xB2C4	0x7B2C	#CJK UNIFIED IDEOGRAPH
+0xB2C5	0x7B26	#CJK UNIFIED IDEOGRAPH
+0xB2C6	0x7B19	#CJK UNIFIED IDEOGRAPH
+0xB2C7	0x7B1E	#CJK UNIFIED IDEOGRAPH
+0xB2C8	0x7B2E	#CJK UNIFIED IDEOGRAPH
+0xB2C9	0x7C92	#CJK UNIFIED IDEOGRAPH
+0xB2CA	0x7C97	#CJK UNIFIED IDEOGRAPH
+0xB2CB	0x7C95	#CJK UNIFIED IDEOGRAPH
+0xB2CC	0x7D46	#CJK UNIFIED IDEOGRAPH
+0xB2CD	0x7D43	#CJK UNIFIED IDEOGRAPH
+0xB2CE	0x7D71	#CJK UNIFIED IDEOGRAPH
+0xB2CF	0x7D2E	#CJK UNIFIED IDEOGRAPH
+0xB2D0	0x7D39	#CJK UNIFIED IDEOGRAPH
+0xB2D1	0x7D3C	#CJK UNIFIED IDEOGRAPH
+0xB2D2	0x7D40	#CJK UNIFIED IDEOGRAPH
+0xB2D3	0x7D30	#CJK UNIFIED IDEOGRAPH
+0xB2D4	0x7D33	#CJK UNIFIED IDEOGRAPH
+0xB2D5	0x7D44	#CJK UNIFIED IDEOGRAPH
+0xB2D6	0x7D2F	#CJK UNIFIED IDEOGRAPH
+0xB2D7	0x7D42	#CJK UNIFIED IDEOGRAPH
+0xB2D8	0x7D32	#CJK UNIFIED IDEOGRAPH
+0xB2D9	0x7D31	#CJK UNIFIED IDEOGRAPH
+0xB2DA	0x7F3D	#CJK UNIFIED IDEOGRAPH
+0xB2DB	0x7F9E	#CJK UNIFIED IDEOGRAPH
+0xB2DC	0x7F9A	#CJK UNIFIED IDEOGRAPH
+0xB2DD	0x7FCC	#CJK UNIFIED IDEOGRAPH
+0xB2DE	0x7FCE	#CJK UNIFIED IDEOGRAPH
+0xB2DF	0x7FD2	#CJK UNIFIED IDEOGRAPH
+0xB2E0	0x801C	#CJK UNIFIED IDEOGRAPH
+0xB2E1	0x804A	#CJK UNIFIED IDEOGRAPH
+0xB2E2	0x8046	#CJK UNIFIED IDEOGRAPH
+0xB2E3	0x812F	#CJK UNIFIED IDEOGRAPH
+0xB2E4	0x8116	#CJK UNIFIED IDEOGRAPH
+0xB2E5	0x8123	#CJK UNIFIED IDEOGRAPH
+0xB2E6	0x812B	#CJK UNIFIED IDEOGRAPH
+0xB2E7	0x8129	#CJK UNIFIED IDEOGRAPH
+0xB2E8	0x8130	#CJK UNIFIED IDEOGRAPH
+0xB2E9	0x8124	#CJK UNIFIED IDEOGRAPH
+0xB2EA	0x8202	#CJK UNIFIED IDEOGRAPH
+0xB2EB	0x8235	#CJK UNIFIED IDEOGRAPH
+0xB2EC	0x8237	#CJK UNIFIED IDEOGRAPH
+0xB2ED	0x8236	#CJK UNIFIED IDEOGRAPH
+0xB2EE	0x8239	#CJK UNIFIED IDEOGRAPH
+0xB2EF	0x838E	#CJK UNIFIED IDEOGRAPH
+0xB2F0	0x839E	#CJK UNIFIED IDEOGRAPH
+0xB2F1	0x8398	#CJK UNIFIED IDEOGRAPH
+0xB2F2	0x8378	#CJK UNIFIED IDEOGRAPH
+0xB2F3	0x83A2	#CJK UNIFIED IDEOGRAPH
+0xB2F4	0x8396	#CJK UNIFIED IDEOGRAPH
+0xB2F5	0x83BD	#CJK UNIFIED IDEOGRAPH
+0xB2F6	0x83AB	#CJK UNIFIED IDEOGRAPH
+0xB2F7	0x8392	#CJK UNIFIED IDEOGRAPH
+0xB2F8	0x838A	#CJK UNIFIED IDEOGRAPH
+0xB2F9	0x8393	#CJK UNIFIED IDEOGRAPH
+0xB2FA	0x8389	#CJK UNIFIED IDEOGRAPH
+0xB2FB	0x83A0	#CJK UNIFIED IDEOGRAPH
+0xB2FC	0x8377	#CJK UNIFIED IDEOGRAPH
+0xB2FD	0x837B	#CJK UNIFIED IDEOGRAPH
+0xB2FE	0x837C	#CJK UNIFIED IDEOGRAPH
+0xB340	0x8386	#CJK UNIFIED IDEOGRAPH
+0xB341	0x83A7	#CJK UNIFIED IDEOGRAPH
+0xB342	0x8655	#CJK UNIFIED IDEOGRAPH
+0xB343	0x5F6A	#CJK UNIFIED IDEOGRAPH
+0xB344	0x86C7	#CJK UNIFIED IDEOGRAPH
+0xB345	0x86C0	#CJK UNIFIED IDEOGRAPH
+0xB346	0x86B6	#CJK UNIFIED IDEOGRAPH
+0xB347	0x86C4	#CJK UNIFIED IDEOGRAPH
+0xB348	0x86B5	#CJK UNIFIED IDEOGRAPH
+0xB349	0x86C6	#CJK UNIFIED IDEOGRAPH
+0xB34A	0x86CB	#CJK UNIFIED IDEOGRAPH
+0xB34B	0x86B1	#CJK UNIFIED IDEOGRAPH
+0xB34C	0x86AF	#CJK UNIFIED IDEOGRAPH
+0xB34D	0x86C9	#CJK UNIFIED IDEOGRAPH
+0xB34E	0x8853	#CJK UNIFIED IDEOGRAPH
+0xB34F	0x889E	#CJK UNIFIED IDEOGRAPH
+0xB350	0x8888	#CJK UNIFIED IDEOGRAPH
+0xB351	0x88AB	#CJK UNIFIED IDEOGRAPH
+0xB352	0x8892	#CJK UNIFIED IDEOGRAPH
+0xB353	0x8896	#CJK UNIFIED IDEOGRAPH
+0xB354	0x888D	#CJK UNIFIED IDEOGRAPH
+0xB355	0x888B	#CJK UNIFIED IDEOGRAPH
+0xB356	0x8993	#CJK UNIFIED IDEOGRAPH
+0xB357	0x898F	#CJK UNIFIED IDEOGRAPH
+0xB358	0x8A2A	#CJK UNIFIED IDEOGRAPH
+0xB359	0x8A1D	#CJK UNIFIED IDEOGRAPH
+0xB35A	0x8A23	#CJK UNIFIED IDEOGRAPH
+0xB35B	0x8A25	#CJK UNIFIED IDEOGRAPH
+0xB35C	0x8A31	#CJK UNIFIED IDEOGRAPH
+0xB35D	0x8A2D	#CJK UNIFIED IDEOGRAPH
+0xB35E	0x8A1F	#CJK UNIFIED IDEOGRAPH
+0xB35F	0x8A1B	#CJK UNIFIED IDEOGRAPH
+0xB360	0x8A22	#CJK UNIFIED IDEOGRAPH
+0xB361	0x8C49	#CJK UNIFIED IDEOGRAPH
+0xB362	0x8C5A	#CJK UNIFIED IDEOGRAPH
+0xB363	0x8CA9	#CJK UNIFIED IDEOGRAPH
+0xB364	0x8CAC	#CJK UNIFIED IDEOGRAPH
+0xB365	0x8CAB	#CJK UNIFIED IDEOGRAPH
+0xB366	0x8CA8	#CJK UNIFIED IDEOGRAPH
+0xB367	0x8CAA	#CJK UNIFIED IDEOGRAPH
+0xB368	0x8CA7	#CJK UNIFIED IDEOGRAPH
+0xB369	0x8D67	#CJK UNIFIED IDEOGRAPH
+0xB36A	0x8D66	#CJK UNIFIED IDEOGRAPH
+0xB36B	0x8DBE	#CJK UNIFIED IDEOGRAPH
+0xB36C	0x8DBA	#CJK UNIFIED IDEOGRAPH
+0xB36D	0x8EDB	#CJK UNIFIED IDEOGRAPH
+0xB36E	0x8EDF	#CJK UNIFIED IDEOGRAPH
+0xB36F	0x9019	#CJK UNIFIED IDEOGRAPH
+0xB370	0x900D	#CJK UNIFIED IDEOGRAPH
+0xB371	0x901A	#CJK UNIFIED IDEOGRAPH
+0xB372	0x9017	#CJK UNIFIED IDEOGRAPH
+0xB373	0x9023	#CJK UNIFIED IDEOGRAPH
+0xB374	0x901F	#CJK UNIFIED IDEOGRAPH
+0xB375	0x901D	#CJK UNIFIED IDEOGRAPH
+0xB376	0x9010	#CJK UNIFIED IDEOGRAPH
+0xB377	0x9015	#CJK UNIFIED IDEOGRAPH
+0xB378	0x901E	#CJK UNIFIED IDEOGRAPH
+0xB379	0x9020	#CJK UNIFIED IDEOGRAPH
+0xB37A	0x900F	#CJK UNIFIED IDEOGRAPH
+0xB37B	0x9022	#CJK UNIFIED IDEOGRAPH
+0xB37C	0x9016	#CJK UNIFIED IDEOGRAPH
+0xB37D	0x901B	#CJK UNIFIED IDEOGRAPH
+0xB37E	0x9014	#CJK UNIFIED IDEOGRAPH
+0xB3A1	0x90E8	#CJK UNIFIED IDEOGRAPH
+0xB3A2	0x90ED	#CJK UNIFIED IDEOGRAPH
+0xB3A3	0x90FD	#CJK UNIFIED IDEOGRAPH
+0xB3A4	0x9157	#CJK UNIFIED IDEOGRAPH
+0xB3A5	0x91CE	#CJK UNIFIED IDEOGRAPH
+0xB3A6	0x91F5	#CJK UNIFIED IDEOGRAPH
+0xB3A7	0x91E6	#CJK UNIFIED IDEOGRAPH
+0xB3A8	0x91E3	#CJK UNIFIED IDEOGRAPH
+0xB3A9	0x91E7	#CJK UNIFIED IDEOGRAPH
+0xB3AA	0x91ED	#CJK UNIFIED IDEOGRAPH
+0xB3AB	0x91E9	#CJK UNIFIED IDEOGRAPH
+0xB3AC	0x9589	#CJK UNIFIED IDEOGRAPH
+0xB3AD	0x966A	#CJK UNIFIED IDEOGRAPH
+0xB3AE	0x9675	#CJK UNIFIED IDEOGRAPH
+0xB3AF	0x9673	#CJK UNIFIED IDEOGRAPH
+0xB3B0	0x9678	#CJK UNIFIED IDEOGRAPH
+0xB3B1	0x9670	#CJK UNIFIED IDEOGRAPH
+0xB3B2	0x9674	#CJK UNIFIED IDEOGRAPH
+0xB3B3	0x9676	#CJK UNIFIED IDEOGRAPH
+0xB3B4	0x9677	#CJK UNIFIED IDEOGRAPH
+0xB3B5	0x966C	#CJK UNIFIED IDEOGRAPH
+0xB3B6	0x96C0	#CJK UNIFIED IDEOGRAPH
+0xB3B7	0x96EA	#CJK UNIFIED IDEOGRAPH
+0xB3B8	0x96E9	#CJK UNIFIED IDEOGRAPH
+0xB3B9	0x7AE0	#CJK UNIFIED IDEOGRAPH
+0xB3BA	0x7ADF	#CJK UNIFIED IDEOGRAPH
+0xB3BB	0x9802	#CJK UNIFIED IDEOGRAPH
+0xB3BC	0x9803	#CJK UNIFIED IDEOGRAPH
+0xB3BD	0x9B5A	#CJK UNIFIED IDEOGRAPH
+0xB3BE	0x9CE5	#CJK UNIFIED IDEOGRAPH
+0xB3BF	0x9E75	#CJK UNIFIED IDEOGRAPH
+0xB3C0	0x9E7F	#CJK UNIFIED IDEOGRAPH
+0xB3C1	0x9EA5	#CJK UNIFIED IDEOGRAPH
+0xB3C2	0x9EBB	#CJK UNIFIED IDEOGRAPH
+0xB3C3	0x50A2	#CJK UNIFIED IDEOGRAPH
+0xB3C4	0x508D	#CJK UNIFIED IDEOGRAPH
+0xB3C5	0x5085	#CJK UNIFIED IDEOGRAPH
+0xB3C6	0x5099	#CJK UNIFIED IDEOGRAPH
+0xB3C7	0x5091	#CJK UNIFIED IDEOGRAPH
+0xB3C8	0x5080	#CJK UNIFIED IDEOGRAPH
+0xB3C9	0x5096	#CJK UNIFIED IDEOGRAPH
+0xB3CA	0x5098	#CJK UNIFIED IDEOGRAPH
+0xB3CB	0x509A	#CJK UNIFIED IDEOGRAPH
+0xB3CC	0x6700	#CJK UNIFIED IDEOGRAPH
+0xB3CD	0x51F1	#CJK UNIFIED IDEOGRAPH
+0xB3CE	0x5272	#CJK UNIFIED IDEOGRAPH
+0xB3CF	0x5274	#CJK UNIFIED IDEOGRAPH
+0xB3D0	0x5275	#CJK UNIFIED IDEOGRAPH
+0xB3D1	0x5269	#CJK UNIFIED IDEOGRAPH
+0xB3D2	0x52DE	#CJK UNIFIED IDEOGRAPH
+0xB3D3	0x52DD	#CJK UNIFIED IDEOGRAPH
+0xB3D4	0x52DB	#CJK UNIFIED IDEOGRAPH
+0xB3D5	0x535A	#CJK UNIFIED IDEOGRAPH
+0xB3D6	0x53A5	#CJK UNIFIED IDEOGRAPH
+0xB3D7	0x557B	#CJK UNIFIED IDEOGRAPH
+0xB3D8	0x5580	#CJK UNIFIED IDEOGRAPH
+0xB3D9	0x55A7	#CJK UNIFIED IDEOGRAPH
+0xB3DA	0x557C	#CJK UNIFIED IDEOGRAPH
+0xB3DB	0x558A	#CJK UNIFIED IDEOGRAPH
+0xB3DC	0x559D	#CJK UNIFIED IDEOGRAPH
+0xB3DD	0x5598	#CJK UNIFIED IDEOGRAPH
+0xB3DE	0x5582	#CJK UNIFIED IDEOGRAPH
+0xB3DF	0x559C	#CJK UNIFIED IDEOGRAPH
+0xB3E0	0x55AA	#CJK UNIFIED IDEOGRAPH
+0xB3E1	0x5594	#CJK UNIFIED IDEOGRAPH
+0xB3E2	0x5587	#CJK UNIFIED IDEOGRAPH
+0xB3E3	0x558B	#CJK UNIFIED IDEOGRAPH
+0xB3E4	0x5583	#CJK UNIFIED IDEOGRAPH
+0xB3E5	0x55B3	#CJK UNIFIED IDEOGRAPH
+0xB3E6	0x55AE	#CJK UNIFIED IDEOGRAPH
+0xB3E7	0x559F	#CJK UNIFIED IDEOGRAPH
+0xB3E8	0x553E	#CJK UNIFIED IDEOGRAPH
+0xB3E9	0x55B2	#CJK UNIFIED IDEOGRAPH
+0xB3EA	0x559A	#CJK UNIFIED IDEOGRAPH
+0xB3EB	0x55BB	#CJK UNIFIED IDEOGRAPH
+0xB3EC	0x55AC	#CJK UNIFIED IDEOGRAPH
+0xB3ED	0x55B1	#CJK UNIFIED IDEOGRAPH
+0xB3EE	0x557E	#CJK UNIFIED IDEOGRAPH
+0xB3EF	0x5589	#CJK UNIFIED IDEOGRAPH
+0xB3F0	0x55AB	#CJK UNIFIED IDEOGRAPH
+0xB3F1	0x5599	#CJK UNIFIED IDEOGRAPH
+0xB3F2	0x570D	#CJK UNIFIED IDEOGRAPH
+0xB3F3	0x582F	#CJK UNIFIED IDEOGRAPH
+0xB3F4	0x582A	#CJK UNIFIED IDEOGRAPH
+0xB3F5	0x5834	#CJK UNIFIED IDEOGRAPH
+0xB3F6	0x5824	#CJK UNIFIED IDEOGRAPH
+0xB3F7	0x5830	#CJK UNIFIED IDEOGRAPH
+0xB3F8	0x5831	#CJK UNIFIED IDEOGRAPH
+0xB3F9	0x5821	#CJK UNIFIED IDEOGRAPH
+0xB3FA	0x581D	#CJK UNIFIED IDEOGRAPH
+0xB3FB	0x5820	#CJK UNIFIED IDEOGRAPH
+0xB3FC	0x58F9	#CJK UNIFIED IDEOGRAPH
+0xB3FD	0x58FA	#CJK UNIFIED IDEOGRAPH
+0xB3FE	0x5960	#CJK UNIFIED IDEOGRAPH
+0xB440	0x5A77	#CJK UNIFIED IDEOGRAPH
+0xB441	0x5A9A	#CJK UNIFIED IDEOGRAPH
+0xB442	0x5A7F	#CJK UNIFIED IDEOGRAPH
+0xB443	0x5A92	#CJK UNIFIED IDEOGRAPH
+0xB444	0x5A9B	#CJK UNIFIED IDEOGRAPH
+0xB445	0x5AA7	#CJK UNIFIED IDEOGRAPH
+0xB446	0x5B73	#CJK UNIFIED IDEOGRAPH
+0xB447	0x5B71	#CJK UNIFIED IDEOGRAPH
+0xB448	0x5BD2	#CJK UNIFIED IDEOGRAPH
+0xB449	0x5BCC	#CJK UNIFIED IDEOGRAPH
+0xB44A	0x5BD3	#CJK UNIFIED IDEOGRAPH
+0xB44B	0x5BD0	#CJK UNIFIED IDEOGRAPH
+0xB44C	0x5C0A	#CJK UNIFIED IDEOGRAPH
+0xB44D	0x5C0B	#CJK UNIFIED IDEOGRAPH
+0xB44E	0x5C31	#CJK UNIFIED IDEOGRAPH
+0xB44F	0x5D4C	#CJK UNIFIED IDEOGRAPH
+0xB450	0x5D50	#CJK UNIFIED IDEOGRAPH
+0xB451	0x5D34	#CJK UNIFIED IDEOGRAPH
+0xB452	0x5D47	#CJK UNIFIED IDEOGRAPH
+0xB453	0x5DFD	#CJK UNIFIED IDEOGRAPH
+0xB454	0x5E45	#CJK UNIFIED IDEOGRAPH
+0xB455	0x5E3D	#CJK UNIFIED IDEOGRAPH
+0xB456	0x5E40	#CJK UNIFIED IDEOGRAPH
+0xB457	0x5E43	#CJK UNIFIED IDEOGRAPH
+0xB458	0x5E7E	#CJK UNIFIED IDEOGRAPH
+0xB459	0x5ECA	#CJK UNIFIED IDEOGRAPH
+0xB45A	0x5EC1	#CJK UNIFIED IDEOGRAPH
+0xB45B	0x5EC2	#CJK UNIFIED IDEOGRAPH
+0xB45C	0x5EC4	#CJK UNIFIED IDEOGRAPH
+0xB45D	0x5F3C	#CJK UNIFIED IDEOGRAPH
+0xB45E	0x5F6D	#CJK UNIFIED IDEOGRAPH
+0xB45F	0x5FA9	#CJK UNIFIED IDEOGRAPH
+0xB460	0x5FAA	#CJK UNIFIED IDEOGRAPH
+0xB461	0x5FA8	#CJK UNIFIED IDEOGRAPH
+0xB462	0x60D1	#CJK UNIFIED IDEOGRAPH
+0xB463	0x60E1	#CJK UNIFIED IDEOGRAPH
+0xB464	0x60B2	#CJK UNIFIED IDEOGRAPH
+0xB465	0x60B6	#CJK UNIFIED IDEOGRAPH
+0xB466	0x60E0	#CJK UNIFIED IDEOGRAPH
+0xB467	0x611C	#CJK UNIFIED IDEOGRAPH
+0xB468	0x6123	#CJK UNIFIED IDEOGRAPH
+0xB469	0x60FA	#CJK UNIFIED IDEOGRAPH
+0xB46A	0x6115	#CJK UNIFIED IDEOGRAPH
+0xB46B	0x60F0	#CJK UNIFIED IDEOGRAPH
+0xB46C	0x60FB	#CJK UNIFIED IDEOGRAPH
+0xB46D	0x60F4	#CJK UNIFIED IDEOGRAPH
+0xB46E	0x6168	#CJK UNIFIED IDEOGRAPH
+0xB46F	0x60F1	#CJK UNIFIED IDEOGRAPH
+0xB470	0x610E	#CJK UNIFIED IDEOGRAPH
+0xB471	0x60F6	#CJK UNIFIED IDEOGRAPH
+0xB472	0x6109	#CJK UNIFIED IDEOGRAPH
+0xB473	0x6100	#CJK UNIFIED IDEOGRAPH
+0xB474	0x6112	#CJK UNIFIED IDEOGRAPH
+0xB475	0x621F	#CJK UNIFIED IDEOGRAPH
+0xB476	0x6249	#CJK UNIFIED IDEOGRAPH
+0xB477	0x63A3	#CJK UNIFIED IDEOGRAPH
+0xB478	0x638C	#CJK UNIFIED IDEOGRAPH
+0xB479	0x63CF	#CJK UNIFIED IDEOGRAPH
+0xB47A	0x63C0	#CJK UNIFIED IDEOGRAPH
+0xB47B	0x63E9	#CJK UNIFIED IDEOGRAPH
+0xB47C	0x63C9	#CJK UNIFIED IDEOGRAPH
+0xB47D	0x63C6	#CJK UNIFIED IDEOGRAPH
+0xB47E	0x63CD	#CJK UNIFIED IDEOGRAPH
+0xB4A1	0x63D2	#CJK UNIFIED IDEOGRAPH
+0xB4A2	0x63E3	#CJK UNIFIED IDEOGRAPH
+0xB4A3	0x63D0	#CJK UNIFIED IDEOGRAPH
+0xB4A4	0x63E1	#CJK UNIFIED IDEOGRAPH
+0xB4A5	0x63D6	#CJK UNIFIED IDEOGRAPH
+0xB4A6	0x63ED	#CJK UNIFIED IDEOGRAPH
+0xB4A7	0x63EE	#CJK UNIFIED IDEOGRAPH
+0xB4A8	0x6376	#CJK UNIFIED IDEOGRAPH
+0xB4A9	0x63F4	#CJK UNIFIED IDEOGRAPH
+0xB4AA	0x63EA	#CJK UNIFIED IDEOGRAPH
+0xB4AB	0x63DB	#CJK UNIFIED IDEOGRAPH
+0xB4AC	0x6452	#CJK UNIFIED IDEOGRAPH
+0xB4AD	0x63DA	#CJK UNIFIED IDEOGRAPH
+0xB4AE	0x63F9	#CJK UNIFIED IDEOGRAPH
+0xB4AF	0x655E	#CJK UNIFIED IDEOGRAPH
+0xB4B0	0x6566	#CJK UNIFIED IDEOGRAPH
+0xB4B1	0x6562	#CJK UNIFIED IDEOGRAPH
+0xB4B2	0x6563	#CJK UNIFIED IDEOGRAPH
+0xB4B3	0x6591	#CJK UNIFIED IDEOGRAPH
+0xB4B4	0x6590	#CJK UNIFIED IDEOGRAPH
+0xB4B5	0x65AF	#CJK UNIFIED IDEOGRAPH
+0xB4B6	0x666E	#CJK UNIFIED IDEOGRAPH
+0xB4B7	0x6670	#CJK UNIFIED IDEOGRAPH
+0xB4B8	0x6674	#CJK UNIFIED IDEOGRAPH
+0xB4B9	0x6676	#CJK UNIFIED IDEOGRAPH
+0xB4BA	0x666F	#CJK UNIFIED IDEOGRAPH
+0xB4BB	0x6691	#CJK UNIFIED IDEOGRAPH
+0xB4BC	0x667A	#CJK UNIFIED IDEOGRAPH
+0xB4BD	0x667E	#CJK UNIFIED IDEOGRAPH
+0xB4BE	0x6677	#CJK UNIFIED IDEOGRAPH
+0xB4BF	0x66FE	#CJK UNIFIED IDEOGRAPH
+0xB4C0	0x66FF	#CJK UNIFIED IDEOGRAPH
+0xB4C1	0x671F	#CJK UNIFIED IDEOGRAPH
+0xB4C2	0x671D	#CJK UNIFIED IDEOGRAPH
+0xB4C3	0x68FA	#CJK UNIFIED IDEOGRAPH
+0xB4C4	0x68D5	#CJK UNIFIED IDEOGRAPH
+0xB4C5	0x68E0	#CJK UNIFIED IDEOGRAPH
+0xB4C6	0x68D8	#CJK UNIFIED IDEOGRAPH
+0xB4C7	0x68D7	#CJK UNIFIED IDEOGRAPH
+0xB4C8	0x6905	#CJK UNIFIED IDEOGRAPH
+0xB4C9	0x68DF	#CJK UNIFIED IDEOGRAPH
+0xB4CA	0x68F5	#CJK UNIFIED IDEOGRAPH
+0xB4CB	0x68EE	#CJK UNIFIED IDEOGRAPH
+0xB4CC	0x68E7	#CJK UNIFIED IDEOGRAPH
+0xB4CD	0x68F9	#CJK UNIFIED IDEOGRAPH
+0xB4CE	0x68D2	#CJK UNIFIED IDEOGRAPH
+0xB4CF	0x68F2	#CJK UNIFIED IDEOGRAPH
+0xB4D0	0x68E3	#CJK UNIFIED IDEOGRAPH
+0xB4D1	0x68CB	#CJK UNIFIED IDEOGRAPH
+0xB4D2	0x68CD	#CJK UNIFIED IDEOGRAPH
+0xB4D3	0x690D	#CJK UNIFIED IDEOGRAPH
+0xB4D4	0x6912	#CJK UNIFIED IDEOGRAPH
+0xB4D5	0x690E	#CJK UNIFIED IDEOGRAPH
+0xB4D6	0x68C9	#CJK UNIFIED IDEOGRAPH
+0xB4D7	0x68DA	#CJK UNIFIED IDEOGRAPH
+0xB4D8	0x696E	#CJK UNIFIED IDEOGRAPH
+0xB4D9	0x68FB	#CJK UNIFIED IDEOGRAPH
+0xB4DA	0x6B3E	#CJK UNIFIED IDEOGRAPH
+0xB4DB	0x6B3A	#CJK UNIFIED IDEOGRAPH
+0xB4DC	0x6B3D	#CJK UNIFIED IDEOGRAPH
+0xB4DD	0x6B98	#CJK UNIFIED IDEOGRAPH
+0xB4DE	0x6B96	#CJK UNIFIED IDEOGRAPH
+0xB4DF	0x6BBC	#CJK UNIFIED IDEOGRAPH
+0xB4E0	0x6BEF	#CJK UNIFIED IDEOGRAPH
+0xB4E1	0x6C2E	#CJK UNIFIED IDEOGRAPH
+0xB4E2	0x6C2F	#CJK UNIFIED IDEOGRAPH
+0xB4E3	0x6C2C	#CJK UNIFIED IDEOGRAPH
+0xB4E4	0x6E2F	#CJK UNIFIED IDEOGRAPH
+0xB4E5	0x6E38	#CJK UNIFIED IDEOGRAPH
+0xB4E6	0x6E54	#CJK UNIFIED IDEOGRAPH
+0xB4E7	0x6E21	#CJK UNIFIED IDEOGRAPH
+0xB4E8	0x6E32	#CJK UNIFIED IDEOGRAPH
+0xB4E9	0x6E67	#CJK UNIFIED IDEOGRAPH
+0xB4EA	0x6E4A	#CJK UNIFIED IDEOGRAPH
+0xB4EB	0x6E20	#CJK UNIFIED IDEOGRAPH
+0xB4EC	0x6E25	#CJK UNIFIED IDEOGRAPH
+0xB4ED	0x6E23	#CJK UNIFIED IDEOGRAPH
+0xB4EE	0x6E1B	#CJK UNIFIED IDEOGRAPH
+0xB4EF	0x6E5B	#CJK UNIFIED IDEOGRAPH
+0xB4F0	0x6E58	#CJK UNIFIED IDEOGRAPH
+0xB4F1	0x6E24	#CJK UNIFIED IDEOGRAPH
+0xB4F2	0x6E56	#CJK UNIFIED IDEOGRAPH
+0xB4F3	0x6E6E	#CJK UNIFIED IDEOGRAPH
+0xB4F4	0x6E2D	#CJK UNIFIED IDEOGRAPH
+0xB4F5	0x6E26	#CJK UNIFIED IDEOGRAPH
+0xB4F6	0x6E6F	#CJK UNIFIED IDEOGRAPH
+0xB4F7	0x6E34	#CJK UNIFIED IDEOGRAPH
+0xB4F8	0x6E4D	#CJK UNIFIED IDEOGRAPH
+0xB4F9	0x6E3A	#CJK UNIFIED IDEOGRAPH
+0xB4FA	0x6E2C	#CJK UNIFIED IDEOGRAPH
+0xB4FB	0x6E43	#CJK UNIFIED IDEOGRAPH
+0xB4FC	0x6E1D	#CJK UNIFIED IDEOGRAPH
+0xB4FD	0x6E3E	#CJK UNIFIED IDEOGRAPH
+0xB4FE	0x6ECB	#CJK UNIFIED IDEOGRAPH
+0xB540	0x6E89	#CJK UNIFIED IDEOGRAPH
+0xB541	0x6E19	#CJK UNIFIED IDEOGRAPH
+0xB542	0x6E4E	#CJK UNIFIED IDEOGRAPH
+0xB543	0x6E63	#CJK UNIFIED IDEOGRAPH
+0xB544	0x6E44	#CJK UNIFIED IDEOGRAPH
+0xB545	0x6E72	#CJK UNIFIED IDEOGRAPH
+0xB546	0x6E69	#CJK UNIFIED IDEOGRAPH
+0xB547	0x6E5F	#CJK UNIFIED IDEOGRAPH
+0xB548	0x7119	#CJK UNIFIED IDEOGRAPH
+0xB549	0x711A	#CJK UNIFIED IDEOGRAPH
+0xB54A	0x7126	#CJK UNIFIED IDEOGRAPH
+0xB54B	0x7130	#CJK UNIFIED IDEOGRAPH
+0xB54C	0x7121	#CJK UNIFIED IDEOGRAPH
+0xB54D	0x7136	#CJK UNIFIED IDEOGRAPH
+0xB54E	0x716E	#CJK UNIFIED IDEOGRAPH
+0xB54F	0x711C	#CJK UNIFIED IDEOGRAPH
+0xB550	0x724C	#CJK UNIFIED IDEOGRAPH
+0xB551	0x7284	#CJK UNIFIED IDEOGRAPH
+0xB552	0x7280	#CJK UNIFIED IDEOGRAPH
+0xB553	0x7336	#CJK UNIFIED IDEOGRAPH
+0xB554	0x7325	#CJK UNIFIED IDEOGRAPH
+0xB555	0x7334	#CJK UNIFIED IDEOGRAPH
+0xB556	0x7329	#CJK UNIFIED IDEOGRAPH
+0xB557	0x743A	#CJK UNIFIED IDEOGRAPH
+0xB558	0x742A	#CJK UNIFIED IDEOGRAPH
+0xB559	0x7433	#CJK UNIFIED IDEOGRAPH
+0xB55A	0x7422	#CJK UNIFIED IDEOGRAPH
+0xB55B	0x7425	#CJK UNIFIED IDEOGRAPH
+0xB55C	0x7435	#CJK UNIFIED IDEOGRAPH
+0xB55D	0x7436	#CJK UNIFIED IDEOGRAPH
+0xB55E	0x7434	#CJK UNIFIED IDEOGRAPH
+0xB55F	0x742F	#CJK UNIFIED IDEOGRAPH
+0xB560	0x741B	#CJK UNIFIED IDEOGRAPH
+0xB561	0x7426	#CJK UNIFIED IDEOGRAPH
+0xB562	0x7428	#CJK UNIFIED IDEOGRAPH
+0xB563	0x7525	#CJK UNIFIED IDEOGRAPH
+0xB564	0x7526	#CJK UNIFIED IDEOGRAPH
+0xB565	0x756B	#CJK UNIFIED IDEOGRAPH
+0xB566	0x756A	#CJK UNIFIED IDEOGRAPH
+0xB567	0x75E2	#CJK UNIFIED IDEOGRAPH
+0xB568	0x75DB	#CJK UNIFIED IDEOGRAPH
+0xB569	0x75E3	#CJK UNIFIED IDEOGRAPH
+0xB56A	0x75D9	#CJK UNIFIED IDEOGRAPH
+0xB56B	0x75D8	#CJK UNIFIED IDEOGRAPH
+0xB56C	0x75DE	#CJK UNIFIED IDEOGRAPH
+0xB56D	0x75E0	#CJK UNIFIED IDEOGRAPH
+0xB56E	0x767B	#CJK UNIFIED IDEOGRAPH
+0xB56F	0x767C	#CJK UNIFIED IDEOGRAPH
+0xB570	0x7696	#CJK UNIFIED IDEOGRAPH
+0xB571	0x7693	#CJK UNIFIED IDEOGRAPH
+0xB572	0x76B4	#CJK UNIFIED IDEOGRAPH
+0xB573	0x76DC	#CJK UNIFIED IDEOGRAPH
+0xB574	0x774F	#CJK UNIFIED IDEOGRAPH
+0xB575	0x77ED	#CJK UNIFIED IDEOGRAPH
+0xB576	0x785D	#CJK UNIFIED IDEOGRAPH
+0xB577	0x786C	#CJK UNIFIED IDEOGRAPH
+0xB578	0x786F	#CJK UNIFIED IDEOGRAPH
+0xB579	0x7A0D	#CJK UNIFIED IDEOGRAPH
+0xB57A	0x7A08	#CJK UNIFIED IDEOGRAPH
+0xB57B	0x7A0B	#CJK UNIFIED IDEOGRAPH
+0xB57C	0x7A05	#CJK UNIFIED IDEOGRAPH
+0xB57D	0x7A00	#CJK UNIFIED IDEOGRAPH
+0xB57E	0x7A98	#CJK UNIFIED IDEOGRAPH
+0xB5A1	0x7A97	#CJK UNIFIED IDEOGRAPH
+0xB5A2	0x7A96	#CJK UNIFIED IDEOGRAPH
+0xB5A3	0x7AE5	#CJK UNIFIED IDEOGRAPH
+0xB5A4	0x7AE3	#CJK UNIFIED IDEOGRAPH
+0xB5A5	0x7B49	#CJK UNIFIED IDEOGRAPH
+0xB5A6	0x7B56	#CJK UNIFIED IDEOGRAPH
+0xB5A7	0x7B46	#CJK UNIFIED IDEOGRAPH
+0xB5A8	0x7B50	#CJK UNIFIED IDEOGRAPH
+0xB5A9	0x7B52	#CJK UNIFIED IDEOGRAPH
+0xB5AA	0x7B54	#CJK UNIFIED IDEOGRAPH
+0xB5AB	0x7B4D	#CJK UNIFIED IDEOGRAPH
+0xB5AC	0x7B4B	#CJK UNIFIED IDEOGRAPH
+0xB5AD	0x7B4F	#CJK UNIFIED IDEOGRAPH
+0xB5AE	0x7B51	#CJK UNIFIED IDEOGRAPH
+0xB5AF	0x7C9F	#CJK UNIFIED IDEOGRAPH
+0xB5B0	0x7CA5	#CJK UNIFIED IDEOGRAPH
+0xB5B1	0x7D5E	#CJK UNIFIED IDEOGRAPH
+0xB5B2	0x7D50	#CJK UNIFIED IDEOGRAPH
+0xB5B3	0x7D68	#CJK UNIFIED IDEOGRAPH
+0xB5B4	0x7D55	#CJK UNIFIED IDEOGRAPH
+0xB5B5	0x7D2B	#CJK UNIFIED IDEOGRAPH
+0xB5B6	0x7D6E	#CJK UNIFIED IDEOGRAPH
+0xB5B7	0x7D72	#CJK UNIFIED IDEOGRAPH
+0xB5B8	0x7D61	#CJK UNIFIED IDEOGRAPH
+0xB5B9	0x7D66	#CJK UNIFIED IDEOGRAPH
+0xB5BA	0x7D62	#CJK UNIFIED IDEOGRAPH
+0xB5BB	0x7D70	#CJK UNIFIED IDEOGRAPH
+0xB5BC	0x7D73	#CJK UNIFIED IDEOGRAPH
+0xB5BD	0x5584	#CJK UNIFIED IDEOGRAPH
+0xB5BE	0x7FD4	#CJK UNIFIED IDEOGRAPH
+0xB5BF	0x7FD5	#CJK UNIFIED IDEOGRAPH
+0xB5C0	0x800B	#CJK UNIFIED IDEOGRAPH
+0xB5C1	0x8052	#CJK UNIFIED IDEOGRAPH
+0xB5C2	0x8085	#CJK UNIFIED IDEOGRAPH
+0xB5C3	0x8155	#CJK UNIFIED IDEOGRAPH
+0xB5C4	0x8154	#CJK UNIFIED IDEOGRAPH
+0xB5C5	0x814B	#CJK UNIFIED IDEOGRAPH
+0xB5C6	0x8151	#CJK UNIFIED IDEOGRAPH
+0xB5C7	0x814E	#CJK UNIFIED IDEOGRAPH
+0xB5C8	0x8139	#CJK UNIFIED IDEOGRAPH
+0xB5C9	0x8146	#CJK UNIFIED IDEOGRAPH
+0xB5CA	0x813E	#CJK UNIFIED IDEOGRAPH
+0xB5CB	0x814C	#CJK UNIFIED IDEOGRAPH
+0xB5CC	0x8153	#CJK UNIFIED IDEOGRAPH
+0xB5CD	0x8174	#CJK UNIFIED IDEOGRAPH
+0xB5CE	0x8212	#CJK UNIFIED IDEOGRAPH
+0xB5CF	0x821C	#CJK UNIFIED IDEOGRAPH
+0xB5D0	0x83E9	#CJK UNIFIED IDEOGRAPH
+0xB5D1	0x8403	#CJK UNIFIED IDEOGRAPH
+0xB5D2	0x83F8	#CJK UNIFIED IDEOGRAPH
+0xB5D3	0x840D	#CJK UNIFIED IDEOGRAPH
+0xB5D4	0x83E0	#CJK UNIFIED IDEOGRAPH
+0xB5D5	0x83C5	#CJK UNIFIED IDEOGRAPH
+0xB5D6	0x840B	#CJK UNIFIED IDEOGRAPH
+0xB5D7	0x83C1	#CJK UNIFIED IDEOGRAPH
+0xB5D8	0x83EF	#CJK UNIFIED IDEOGRAPH
+0xB5D9	0x83F1	#CJK UNIFIED IDEOGRAPH
+0xB5DA	0x83F4	#CJK UNIFIED IDEOGRAPH
+0xB5DB	0x8457	#CJK UNIFIED IDEOGRAPH
+0xB5DC	0x840A	#CJK UNIFIED IDEOGRAPH
+0xB5DD	0x83F0	#CJK UNIFIED IDEOGRAPH
+0xB5DE	0x840C	#CJK UNIFIED IDEOGRAPH
+0xB5DF	0x83CC	#CJK UNIFIED IDEOGRAPH
+0xB5E0	0x83FD	#CJK UNIFIED IDEOGRAPH
+0xB5E1	0x83F2	#CJK UNIFIED IDEOGRAPH
+0xB5E2	0x83CA	#CJK UNIFIED IDEOGRAPH
+0xB5E3	0x8438	#CJK UNIFIED IDEOGRAPH
+0xB5E4	0x840E	#CJK UNIFIED IDEOGRAPH
+0xB5E5	0x8404	#CJK UNIFIED IDEOGRAPH
+0xB5E6	0x83DC	#CJK UNIFIED IDEOGRAPH
+0xB5E7	0x8407	#CJK UNIFIED IDEOGRAPH
+0xB5E8	0x83D4	#CJK UNIFIED IDEOGRAPH
+0xB5E9	0x83DF	#CJK UNIFIED IDEOGRAPH
+0xB5EA	0x865B	#CJK UNIFIED IDEOGRAPH
+0xB5EB	0x86DF	#CJK UNIFIED IDEOGRAPH
+0xB5EC	0x86D9	#CJK UNIFIED IDEOGRAPH
+0xB5ED	0x86ED	#CJK UNIFIED IDEOGRAPH
+0xB5EE	0x86D4	#CJK UNIFIED IDEOGRAPH
+0xB5EF	0x86DB	#CJK UNIFIED IDEOGRAPH
+0xB5F0	0x86E4	#CJK UNIFIED IDEOGRAPH
+0xB5F1	0x86D0	#CJK UNIFIED IDEOGRAPH
+0xB5F2	0x86DE	#CJK UNIFIED IDEOGRAPH
+0xB5F3	0x8857	#CJK UNIFIED IDEOGRAPH
+0xB5F4	0x88C1	#CJK UNIFIED IDEOGRAPH
+0xB5F5	0x88C2	#CJK UNIFIED IDEOGRAPH
+0xB5F6	0x88B1	#CJK UNIFIED IDEOGRAPH
+0xB5F7	0x8983	#CJK UNIFIED IDEOGRAPH
+0xB5F8	0x8996	#CJK UNIFIED IDEOGRAPH
+0xB5F9	0x8A3B	#CJK UNIFIED IDEOGRAPH
+0xB5FA	0x8A60	#CJK UNIFIED IDEOGRAPH
+0xB5FB	0x8A55	#CJK UNIFIED IDEOGRAPH
+0xB5FC	0x8A5E	#CJK UNIFIED IDEOGRAPH
+0xB5FD	0x8A3C	#CJK UNIFIED IDEOGRAPH
+0xB5FE	0x8A41	#CJK UNIFIED IDEOGRAPH
+0xB640	0x8A54	#CJK UNIFIED IDEOGRAPH
+0xB641	0x8A5B	#CJK UNIFIED IDEOGRAPH
+0xB642	0x8A50	#CJK UNIFIED IDEOGRAPH
+0xB643	0x8A46	#CJK UNIFIED IDEOGRAPH
+0xB644	0x8A34	#CJK UNIFIED IDEOGRAPH
+0xB645	0x8A3A	#CJK UNIFIED IDEOGRAPH
+0xB646	0x8A36	#CJK UNIFIED IDEOGRAPH
+0xB647	0x8A56	#CJK UNIFIED IDEOGRAPH
+0xB648	0x8C61	#CJK UNIFIED IDEOGRAPH
+0xB649	0x8C82	#CJK UNIFIED IDEOGRAPH
+0xB64A	0x8CAF	#CJK UNIFIED IDEOGRAPH
+0xB64B	0x8CBC	#CJK UNIFIED IDEOGRAPH
+0xB64C	0x8CB3	#CJK UNIFIED IDEOGRAPH
+0xB64D	0x8CBD	#CJK UNIFIED IDEOGRAPH
+0xB64E	0x8CC1	#CJK UNIFIED IDEOGRAPH
+0xB64F	0x8CBB	#CJK UNIFIED IDEOGRAPH
+0xB650	0x8CC0	#CJK UNIFIED IDEOGRAPH
+0xB651	0x8CB4	#CJK UNIFIED IDEOGRAPH
+0xB652	0x8CB7	#CJK UNIFIED IDEOGRAPH
+0xB653	0x8CB6	#CJK UNIFIED IDEOGRAPH
+0xB654	0x8CBF	#CJK UNIFIED IDEOGRAPH
+0xB655	0x8CB8	#CJK UNIFIED IDEOGRAPH
+0xB656	0x8D8A	#CJK UNIFIED IDEOGRAPH
+0xB657	0x8D85	#CJK UNIFIED IDEOGRAPH
+0xB658	0x8D81	#CJK UNIFIED IDEOGRAPH
+0xB659	0x8DCE	#CJK UNIFIED IDEOGRAPH
+0xB65A	0x8DDD	#CJK UNIFIED IDEOGRAPH
+0xB65B	0x8DCB	#CJK UNIFIED IDEOGRAPH
+0xB65C	0x8DDA	#CJK UNIFIED IDEOGRAPH
+0xB65D	0x8DD1	#CJK UNIFIED IDEOGRAPH
+0xB65E	0x8DCC	#CJK UNIFIED IDEOGRAPH
+0xB65F	0x8DDB	#CJK UNIFIED IDEOGRAPH
+0xB660	0x8DC6	#CJK UNIFIED IDEOGRAPH
+0xB661	0x8EFB	#CJK UNIFIED IDEOGRAPH
+0xB662	0x8EF8	#CJK UNIFIED IDEOGRAPH
+0xB663	0x8EFC	#CJK UNIFIED IDEOGRAPH
+0xB664	0x8F9C	#CJK UNIFIED IDEOGRAPH
+0xB665	0x902E	#CJK UNIFIED IDEOGRAPH
+0xB666	0x9035	#CJK UNIFIED IDEOGRAPH
+0xB667	0x9031	#CJK UNIFIED IDEOGRAPH
+0xB668	0x9038	#CJK UNIFIED IDEOGRAPH
+0xB669	0x9032	#CJK UNIFIED IDEOGRAPH
+0xB66A	0x9036	#CJK UNIFIED IDEOGRAPH
+0xB66B	0x9102	#CJK UNIFIED IDEOGRAPH
+0xB66C	0x90F5	#CJK UNIFIED IDEOGRAPH
+0xB66D	0x9109	#CJK UNIFIED IDEOGRAPH
+0xB66E	0x90FE	#CJK UNIFIED IDEOGRAPH
+0xB66F	0x9163	#CJK UNIFIED IDEOGRAPH
+0xB670	0x9165	#CJK UNIFIED IDEOGRAPH
+0xB671	0x91CF	#CJK UNIFIED IDEOGRAPH
+0xB672	0x9214	#CJK UNIFIED IDEOGRAPH
+0xB673	0x9215	#CJK UNIFIED IDEOGRAPH
+0xB674	0x9223	#CJK UNIFIED IDEOGRAPH
+0xB675	0x9209	#CJK UNIFIED IDEOGRAPH
+0xB676	0x921E	#CJK UNIFIED IDEOGRAPH
+0xB677	0x920D	#CJK UNIFIED IDEOGRAPH
+0xB678	0x9210	#CJK UNIFIED IDEOGRAPH
+0xB679	0x9207	#CJK UNIFIED IDEOGRAPH
+0xB67A	0x9211	#CJK UNIFIED IDEOGRAPH
+0xB67B	0x9594	#CJK UNIFIED IDEOGRAPH
+0xB67C	0x958F	#CJK UNIFIED IDEOGRAPH
+0xB67D	0x958B	#CJK UNIFIED IDEOGRAPH
+0xB67E	0x9591	#CJK UNIFIED IDEOGRAPH
+0xB6A1	0x9593	#CJK UNIFIED IDEOGRAPH
+0xB6A2	0x9592	#CJK UNIFIED IDEOGRAPH
+0xB6A3	0x958E	#CJK UNIFIED IDEOGRAPH
+0xB6A4	0x968A	#CJK UNIFIED IDEOGRAPH
+0xB6A5	0x968E	#CJK UNIFIED IDEOGRAPH
+0xB6A6	0x968B	#CJK UNIFIED IDEOGRAPH
+0xB6A7	0x967D	#CJK UNIFIED IDEOGRAPH
+0xB6A8	0x9685	#CJK UNIFIED IDEOGRAPH
+0xB6A9	0x9686	#CJK UNIFIED IDEOGRAPH
+0xB6AA	0x968D	#CJK UNIFIED IDEOGRAPH
+0xB6AB	0x9672	#CJK UNIFIED IDEOGRAPH
+0xB6AC	0x9684	#CJK UNIFIED IDEOGRAPH
+0xB6AD	0x96C1	#CJK UNIFIED IDEOGRAPH
+0xB6AE	0x96C5	#CJK UNIFIED IDEOGRAPH
+0xB6AF	0x96C4	#CJK UNIFIED IDEOGRAPH
+0xB6B0	0x96C6	#CJK UNIFIED IDEOGRAPH
+0xB6B1	0x96C7	#CJK UNIFIED IDEOGRAPH
+0xB6B2	0x96EF	#CJK UNIFIED IDEOGRAPH
+0xB6B3	0x96F2	#CJK UNIFIED IDEOGRAPH
+0xB6B4	0x97CC	#CJK UNIFIED IDEOGRAPH
+0xB6B5	0x9805	#CJK UNIFIED IDEOGRAPH
+0xB6B6	0x9806	#CJK UNIFIED IDEOGRAPH
+0xB6B7	0x9808	#CJK UNIFIED IDEOGRAPH
+0xB6B8	0x98E7	#CJK UNIFIED IDEOGRAPH
+0xB6B9	0x98EA	#CJK UNIFIED IDEOGRAPH
+0xB6BA	0x98EF	#CJK UNIFIED IDEOGRAPH
+0xB6BB	0x98E9	#CJK UNIFIED IDEOGRAPH
+0xB6BC	0x98F2	#CJK UNIFIED IDEOGRAPH
+0xB6BD	0x98ED	#CJK UNIFIED IDEOGRAPH
+0xB6BE	0x99AE	#CJK UNIFIED IDEOGRAPH
+0xB6BF	0x99AD	#CJK UNIFIED IDEOGRAPH
+0xB6C0	0x9EC3	#CJK UNIFIED IDEOGRAPH
+0xB6C1	0x9ECD	#CJK UNIFIED IDEOGRAPH
+0xB6C2	0x9ED1	#CJK UNIFIED IDEOGRAPH
+0xB6C3	0x4E82	#CJK UNIFIED IDEOGRAPH
+0xB6C4	0x50AD	#CJK UNIFIED IDEOGRAPH
+0xB6C5	0x50B5	#CJK UNIFIED IDEOGRAPH
+0xB6C6	0x50B2	#CJK UNIFIED IDEOGRAPH
+0xB6C7	0x50B3	#CJK UNIFIED IDEOGRAPH
+0xB6C8	0x50C5	#CJK UNIFIED IDEOGRAPH
+0xB6C9	0x50BE	#CJK UNIFIED IDEOGRAPH
+0xB6CA	0x50AC	#CJK UNIFIED IDEOGRAPH
+0xB6CB	0x50B7	#CJK UNIFIED IDEOGRAPH
+0xB6CC	0x50BB	#CJK UNIFIED IDEOGRAPH
+0xB6CD	0x50AF	#CJK UNIFIED IDEOGRAPH
+0xB6CE	0x50C7	#CJK UNIFIED IDEOGRAPH
+0xB6CF	0x527F	#CJK UNIFIED IDEOGRAPH
+0xB6D0	0x5277	#CJK UNIFIED IDEOGRAPH
+0xB6D1	0x527D	#CJK UNIFIED IDEOGRAPH
+0xB6D2	0x52DF	#CJK UNIFIED IDEOGRAPH
+0xB6D3	0x52E6	#CJK UNIFIED IDEOGRAPH
+0xB6D4	0x52E4	#CJK UNIFIED IDEOGRAPH
+0xB6D5	0x52E2	#CJK UNIFIED IDEOGRAPH
+0xB6D6	0x52E3	#CJK UNIFIED IDEOGRAPH
+0xB6D7	0x532F	#CJK UNIFIED IDEOGRAPH
+0xB6D8	0x55DF	#CJK UNIFIED IDEOGRAPH
+0xB6D9	0x55E8	#CJK UNIFIED IDEOGRAPH
+0xB6DA	0x55D3	#CJK UNIFIED IDEOGRAPH
+0xB6DB	0x55E6	#CJK UNIFIED IDEOGRAPH
+0xB6DC	0x55CE	#CJK UNIFIED IDEOGRAPH
+0xB6DD	0x55DC	#CJK UNIFIED IDEOGRAPH
+0xB6DE	0x55C7	#CJK UNIFIED IDEOGRAPH
+0xB6DF	0x55D1	#CJK UNIFIED IDEOGRAPH
+0xB6E0	0x55E3	#CJK UNIFIED IDEOGRAPH
+0xB6E1	0x55E4	#CJK UNIFIED IDEOGRAPH
+0xB6E2	0x55EF	#CJK UNIFIED IDEOGRAPH
+0xB6E3	0x55DA	#CJK UNIFIED IDEOGRAPH
+0xB6E4	0x55E1	#CJK UNIFIED IDEOGRAPH
+0xB6E5	0x55C5	#CJK UNIFIED IDEOGRAPH
+0xB6E6	0x55C6	#CJK UNIFIED IDEOGRAPH
+0xB6E7	0x55E5	#CJK UNIFIED IDEOGRAPH
+0xB6E8	0x55C9	#CJK UNIFIED IDEOGRAPH
+0xB6E9	0x5712	#CJK UNIFIED IDEOGRAPH
+0xB6EA	0x5713	#CJK UNIFIED IDEOGRAPH
+0xB6EB	0x585E	#CJK UNIFIED IDEOGRAPH
+0xB6EC	0x5851	#CJK UNIFIED IDEOGRAPH
+0xB6ED	0x5858	#CJK UNIFIED IDEOGRAPH
+0xB6EE	0x5857	#CJK UNIFIED IDEOGRAPH
+0xB6EF	0x585A	#CJK UNIFIED IDEOGRAPH
+0xB6F0	0x5854	#CJK UNIFIED IDEOGRAPH
+0xB6F1	0x586B	#CJK UNIFIED IDEOGRAPH
+0xB6F2	0x584C	#CJK UNIFIED IDEOGRAPH
+0xB6F3	0x586D	#CJK UNIFIED IDEOGRAPH
+0xB6F4	0x584A	#CJK UNIFIED IDEOGRAPH
+0xB6F5	0x5862	#CJK UNIFIED IDEOGRAPH
+0xB6F6	0x5852	#CJK UNIFIED IDEOGRAPH
+0xB6F7	0x584B	#CJK UNIFIED IDEOGRAPH
+0xB6F8	0x5967	#CJK UNIFIED IDEOGRAPH
+0xB6F9	0x5AC1	#CJK UNIFIED IDEOGRAPH
+0xB6FA	0x5AC9	#CJK UNIFIED IDEOGRAPH
+0xB6FB	0x5ACC	#CJK UNIFIED IDEOGRAPH
+0xB6FC	0x5ABE	#CJK UNIFIED IDEOGRAPH
+0xB6FD	0x5ABD	#CJK UNIFIED IDEOGRAPH
+0xB6FE	0x5ABC	#CJK UNIFIED IDEOGRAPH
+0xB740	0x5AB3	#CJK UNIFIED IDEOGRAPH
+0xB741	0x5AC2	#CJK UNIFIED IDEOGRAPH
+0xB742	0x5AB2	#CJK UNIFIED IDEOGRAPH
+0xB743	0x5D69	#CJK UNIFIED IDEOGRAPH
+0xB744	0x5D6F	#CJK UNIFIED IDEOGRAPH
+0xB745	0x5E4C	#CJK UNIFIED IDEOGRAPH
+0xB746	0x5E79	#CJK UNIFIED IDEOGRAPH
+0xB747	0x5EC9	#CJK UNIFIED IDEOGRAPH
+0xB748	0x5EC8	#CJK UNIFIED IDEOGRAPH
+0xB749	0x5F12	#CJK UNIFIED IDEOGRAPH
+0xB74A	0x5F59	#CJK UNIFIED IDEOGRAPH
+0xB74B	0x5FAC	#CJK UNIFIED IDEOGRAPH
+0xB74C	0x5FAE	#CJK UNIFIED IDEOGRAPH
+0xB74D	0x611A	#CJK UNIFIED IDEOGRAPH
+0xB74E	0x610F	#CJK UNIFIED IDEOGRAPH
+0xB74F	0x6148	#CJK UNIFIED IDEOGRAPH
+0xB750	0x611F	#CJK UNIFIED IDEOGRAPH
+0xB751	0x60F3	#CJK UNIFIED IDEOGRAPH
+0xB752	0x611B	#CJK UNIFIED IDEOGRAPH
+0xB753	0x60F9	#CJK UNIFIED IDEOGRAPH
+0xB754	0x6101	#CJK UNIFIED IDEOGRAPH
+0xB755	0x6108	#CJK UNIFIED IDEOGRAPH
+0xB756	0x614E	#CJK UNIFIED IDEOGRAPH
+0xB757	0x614C	#CJK UNIFIED IDEOGRAPH
+0xB758	0x6144	#CJK UNIFIED IDEOGRAPH
+0xB759	0x614D	#CJK UNIFIED IDEOGRAPH
+0xB75A	0x613E	#CJK UNIFIED IDEOGRAPH
+0xB75B	0x6134	#CJK UNIFIED IDEOGRAPH
+0xB75C	0x6127	#CJK UNIFIED IDEOGRAPH
+0xB75D	0x610D	#CJK UNIFIED IDEOGRAPH
+0xB75E	0x6106	#CJK UNIFIED IDEOGRAPH
+0xB75F	0x6137	#CJK UNIFIED IDEOGRAPH
+0xB760	0x6221	#CJK UNIFIED IDEOGRAPH
+0xB761	0x6222	#CJK UNIFIED IDEOGRAPH
+0xB762	0x6413	#CJK UNIFIED IDEOGRAPH
+0xB763	0x643E	#CJK UNIFIED IDEOGRAPH
+0xB764	0x641E	#CJK UNIFIED IDEOGRAPH
+0xB765	0x642A	#CJK UNIFIED IDEOGRAPH
+0xB766	0x642D	#CJK UNIFIED IDEOGRAPH
+0xB767	0x643D	#CJK UNIFIED IDEOGRAPH
+0xB768	0x642C	#CJK UNIFIED IDEOGRAPH
+0xB769	0x640F	#CJK UNIFIED IDEOGRAPH
+0xB76A	0x641C	#CJK UNIFIED IDEOGRAPH
+0xB76B	0x6414	#CJK UNIFIED IDEOGRAPH
+0xB76C	0x640D	#CJK UNIFIED IDEOGRAPH
+0xB76D	0x6436	#CJK UNIFIED IDEOGRAPH
+0xB76E	0x6416	#CJK UNIFIED IDEOGRAPH
+0xB76F	0x6417	#CJK UNIFIED IDEOGRAPH
+0xB770	0x6406	#CJK UNIFIED IDEOGRAPH
+0xB771	0x656C	#CJK UNIFIED IDEOGRAPH
+0xB772	0x659F	#CJK UNIFIED IDEOGRAPH
+0xB773	0x65B0	#CJK UNIFIED IDEOGRAPH
+0xB774	0x6697	#CJK UNIFIED IDEOGRAPH
+0xB775	0x6689	#CJK UNIFIED IDEOGRAPH
+0xB776	0x6687	#CJK UNIFIED IDEOGRAPH
+0xB777	0x6688	#CJK UNIFIED IDEOGRAPH
+0xB778	0x6696	#CJK UNIFIED IDEOGRAPH
+0xB779	0x6684	#CJK UNIFIED IDEOGRAPH
+0xB77A	0x6698	#CJK UNIFIED IDEOGRAPH
+0xB77B	0x668D	#CJK UNIFIED IDEOGRAPH
+0xB77C	0x6703	#CJK UNIFIED IDEOGRAPH
+0xB77D	0x6994	#CJK UNIFIED IDEOGRAPH
+0xB77E	0x696D	#CJK UNIFIED IDEOGRAPH
+0xB7A1	0x695A	#CJK UNIFIED IDEOGRAPH
+0xB7A2	0x6977	#CJK UNIFIED IDEOGRAPH
+0xB7A3	0x6960	#CJK UNIFIED IDEOGRAPH
+0xB7A4	0x6954	#CJK UNIFIED IDEOGRAPH
+0xB7A5	0x6975	#CJK UNIFIED IDEOGRAPH
+0xB7A6	0x6930	#CJK UNIFIED IDEOGRAPH
+0xB7A7	0x6982	#CJK UNIFIED IDEOGRAPH
+0xB7A8	0x694A	#CJK UNIFIED IDEOGRAPH
+0xB7A9	0x6968	#CJK UNIFIED IDEOGRAPH
+0xB7AA	0x696B	#CJK UNIFIED IDEOGRAPH
+0xB7AB	0x695E	#CJK UNIFIED IDEOGRAPH
+0xB7AC	0x6953	#CJK UNIFIED IDEOGRAPH
+0xB7AD	0x6979	#CJK UNIFIED IDEOGRAPH
+0xB7AE	0x6986	#CJK UNIFIED IDEOGRAPH
+0xB7AF	0x695D	#CJK UNIFIED IDEOGRAPH
+0xB7B0	0x6963	#CJK UNIFIED IDEOGRAPH
+0xB7B1	0x695B	#CJK UNIFIED IDEOGRAPH
+0xB7B2	0x6B47	#CJK UNIFIED IDEOGRAPH
+0xB7B3	0x6B72	#CJK UNIFIED IDEOGRAPH
+0xB7B4	0x6BC0	#CJK UNIFIED IDEOGRAPH
+0xB7B5	0x6BBF	#CJK UNIFIED IDEOGRAPH
+0xB7B6	0x6BD3	#CJK UNIFIED IDEOGRAPH
+0xB7B7	0x6BFD	#CJK UNIFIED IDEOGRAPH
+0xB7B8	0x6EA2	#CJK UNIFIED IDEOGRAPH
+0xB7B9	0x6EAF	#CJK UNIFIED IDEOGRAPH
+0xB7BA	0x6ED3	#CJK UNIFIED IDEOGRAPH
+0xB7BB	0x6EB6	#CJK UNIFIED IDEOGRAPH
+0xB7BC	0x6EC2	#CJK UNIFIED IDEOGRAPH
+0xB7BD	0x6E90	#CJK UNIFIED IDEOGRAPH
+0xB7BE	0x6E9D	#CJK UNIFIED IDEOGRAPH
+0xB7BF	0x6EC7	#CJK UNIFIED IDEOGRAPH
+0xB7C0	0x6EC5	#CJK UNIFIED IDEOGRAPH
+0xB7C1	0x6EA5	#CJK UNIFIED IDEOGRAPH
+0xB7C2	0x6E98	#CJK UNIFIED IDEOGRAPH
+0xB7C3	0x6EBC	#CJK UNIFIED IDEOGRAPH
+0xB7C4	0x6EBA	#CJK UNIFIED IDEOGRAPH
+0xB7C5	0x6EAB	#CJK UNIFIED IDEOGRAPH
+0xB7C6	0x6ED1	#CJK UNIFIED IDEOGRAPH
+0xB7C7	0x6E96	#CJK UNIFIED IDEOGRAPH
+0xB7C8	0x6E9C	#CJK UNIFIED IDEOGRAPH
+0xB7C9	0x6EC4	#CJK UNIFIED IDEOGRAPH
+0xB7CA	0x6ED4	#CJK UNIFIED IDEOGRAPH
+0xB7CB	0x6EAA	#CJK UNIFIED IDEOGRAPH
+0xB7CC	0x6EA7	#CJK UNIFIED IDEOGRAPH
+0xB7CD	0x6EB4	#CJK UNIFIED IDEOGRAPH
+0xB7CE	0x714E	#CJK UNIFIED IDEOGRAPH
+0xB7CF	0x7159	#CJK UNIFIED IDEOGRAPH
+0xB7D0	0x7169	#CJK UNIFIED IDEOGRAPH
+0xB7D1	0x7164	#CJK UNIFIED IDEOGRAPH
+0xB7D2	0x7149	#CJK UNIFIED IDEOGRAPH
+0xB7D3	0x7167	#CJK UNIFIED IDEOGRAPH
+0xB7D4	0x715C	#CJK UNIFIED IDEOGRAPH
+0xB7D5	0x716C	#CJK UNIFIED IDEOGRAPH
+0xB7D6	0x7166	#CJK UNIFIED IDEOGRAPH
+0xB7D7	0x714C	#CJK UNIFIED IDEOGRAPH
+0xB7D8	0x7165	#CJK UNIFIED IDEOGRAPH
+0xB7D9	0x715E	#CJK UNIFIED IDEOGRAPH
+0xB7DA	0x7146	#CJK UNIFIED IDEOGRAPH
+0xB7DB	0x7168	#CJK UNIFIED IDEOGRAPH
+0xB7DC	0x7156	#CJK UNIFIED IDEOGRAPH
+0xB7DD	0x723A	#CJK UNIFIED IDEOGRAPH
+0xB7DE	0x7252	#CJK UNIFIED IDEOGRAPH
+0xB7DF	0x7337	#CJK UNIFIED IDEOGRAPH
+0xB7E0	0x7345	#CJK UNIFIED IDEOGRAPH
+0xB7E1	0x733F	#CJK UNIFIED IDEOGRAPH
+0xB7E2	0x733E	#CJK UNIFIED IDEOGRAPH
+0xB7E3	0x746F	#CJK UNIFIED IDEOGRAPH
+0xB7E4	0x745A	#CJK UNIFIED IDEOGRAPH
+0xB7E5	0x7455	#CJK UNIFIED IDEOGRAPH
+0xB7E6	0x745F	#CJK UNIFIED IDEOGRAPH
+0xB7E7	0x745E	#CJK UNIFIED IDEOGRAPH
+0xB7E8	0x7441	#CJK UNIFIED IDEOGRAPH
+0xB7E9	0x743F	#CJK UNIFIED IDEOGRAPH
+0xB7EA	0x7459	#CJK UNIFIED IDEOGRAPH
+0xB7EB	0x745B	#CJK UNIFIED IDEOGRAPH
+0xB7EC	0x745C	#CJK UNIFIED IDEOGRAPH
+0xB7ED	0x7576	#CJK UNIFIED IDEOGRAPH
+0xB7EE	0x7578	#CJK UNIFIED IDEOGRAPH
+0xB7EF	0x7600	#CJK UNIFIED IDEOGRAPH
+0xB7F0	0x75F0	#CJK UNIFIED IDEOGRAPH
+0xB7F1	0x7601	#CJK UNIFIED IDEOGRAPH
+0xB7F2	0x75F2	#CJK UNIFIED IDEOGRAPH
+0xB7F3	0x75F1	#CJK UNIFIED IDEOGRAPH
+0xB7F4	0x75FA	#CJK UNIFIED IDEOGRAPH
+0xB7F5	0x75FF	#CJK UNIFIED IDEOGRAPH
+0xB7F6	0x75F4	#CJK UNIFIED IDEOGRAPH
+0xB7F7	0x75F3	#CJK UNIFIED IDEOGRAPH
+0xB7F8	0x76DE	#CJK UNIFIED IDEOGRAPH
+0xB7F9	0x76DF	#CJK UNIFIED IDEOGRAPH
+0xB7FA	0x775B	#CJK UNIFIED IDEOGRAPH
+0xB7FB	0x776B	#CJK UNIFIED IDEOGRAPH
+0xB7FC	0x7766	#CJK UNIFIED IDEOGRAPH
+0xB7FD	0x775E	#CJK UNIFIED IDEOGRAPH
+0xB7FE	0x7763	#CJK UNIFIED IDEOGRAPH
+0xB840	0x7779	#CJK UNIFIED IDEOGRAPH
+0xB841	0x776A	#CJK UNIFIED IDEOGRAPH
+0xB842	0x776C	#CJK UNIFIED IDEOGRAPH
+0xB843	0x775C	#CJK UNIFIED IDEOGRAPH
+0xB844	0x7765	#CJK UNIFIED IDEOGRAPH
+0xB845	0x7768	#CJK UNIFIED IDEOGRAPH
+0xB846	0x7762	#CJK UNIFIED IDEOGRAPH
+0xB847	0x77EE	#CJK UNIFIED IDEOGRAPH
+0xB848	0x788E	#CJK UNIFIED IDEOGRAPH
+0xB849	0x78B0	#CJK UNIFIED IDEOGRAPH
+0xB84A	0x7897	#CJK UNIFIED IDEOGRAPH
+0xB84B	0x7898	#CJK UNIFIED IDEOGRAPH
+0xB84C	0x788C	#CJK UNIFIED IDEOGRAPH
+0xB84D	0x7889	#CJK UNIFIED IDEOGRAPH
+0xB84E	0x787C	#CJK UNIFIED IDEOGRAPH
+0xB84F	0x7891	#CJK UNIFIED IDEOGRAPH
+0xB850	0x7893	#CJK UNIFIED IDEOGRAPH
+0xB851	0x787F	#CJK UNIFIED IDEOGRAPH
+0xB852	0x797A	#CJK UNIFIED IDEOGRAPH
+0xB853	0x797F	#CJK UNIFIED IDEOGRAPH
+0xB854	0x7981	#CJK UNIFIED IDEOGRAPH
+0xB855	0x842C	#CJK UNIFIED IDEOGRAPH
+0xB856	0x79BD	#CJK UNIFIED IDEOGRAPH
+0xB857	0x7A1C	#CJK UNIFIED IDEOGRAPH
+0xB858	0x7A1A	#CJK UNIFIED IDEOGRAPH
+0xB859	0x7A20	#CJK UNIFIED IDEOGRAPH
+0xB85A	0x7A14	#CJK UNIFIED IDEOGRAPH
+0xB85B	0x7A1F	#CJK UNIFIED IDEOGRAPH
+0xB85C	0x7A1E	#CJK UNIFIED IDEOGRAPH
+0xB85D	0x7A9F	#CJK UNIFIED IDEOGRAPH
+0xB85E	0x7AA0	#CJK UNIFIED IDEOGRAPH
+0xB85F	0x7B77	#CJK UNIFIED IDEOGRAPH
+0xB860	0x7BC0	#CJK UNIFIED IDEOGRAPH
+0xB861	0x7B60	#CJK UNIFIED IDEOGRAPH
+0xB862	0x7B6E	#CJK UNIFIED IDEOGRAPH
+0xB863	0x7B67	#CJK UNIFIED IDEOGRAPH
+0xB864	0x7CB1	#CJK UNIFIED IDEOGRAPH
+0xB865	0x7CB3	#CJK UNIFIED IDEOGRAPH
+0xB866	0x7CB5	#CJK UNIFIED IDEOGRAPH
+0xB867	0x7D93	#CJK UNIFIED IDEOGRAPH
+0xB868	0x7D79	#CJK UNIFIED IDEOGRAPH
+0xB869	0x7D91	#CJK UNIFIED IDEOGRAPH
+0xB86A	0x7D81	#CJK UNIFIED IDEOGRAPH
+0xB86B	0x7D8F	#CJK UNIFIED IDEOGRAPH
+0xB86C	0x7D5B	#CJK UNIFIED IDEOGRAPH
+0xB86D	0x7F6E	#CJK UNIFIED IDEOGRAPH
+0xB86E	0x7F69	#CJK UNIFIED IDEOGRAPH
+0xB86F	0x7F6A	#CJK UNIFIED IDEOGRAPH
+0xB870	0x7F72	#CJK UNIFIED IDEOGRAPH
+0xB871	0x7FA9	#CJK UNIFIED IDEOGRAPH
+0xB872	0x7FA8	#CJK UNIFIED IDEOGRAPH
+0xB873	0x7FA4	#CJK UNIFIED IDEOGRAPH
+0xB874	0x8056	#CJK UNIFIED IDEOGRAPH
+0xB875	0x8058	#CJK UNIFIED IDEOGRAPH
+0xB876	0x8086	#CJK UNIFIED IDEOGRAPH
+0xB877	0x8084	#CJK UNIFIED IDEOGRAPH
+0xB878	0x8171	#CJK UNIFIED IDEOGRAPH
+0xB879	0x8170	#CJK UNIFIED IDEOGRAPH
+0xB87A	0x8178	#CJK UNIFIED IDEOGRAPH
+0xB87B	0x8165	#CJK UNIFIED IDEOGRAPH
+0xB87C	0x816E	#CJK UNIFIED IDEOGRAPH
+0xB87D	0x8173	#CJK UNIFIED IDEOGRAPH
+0xB87E	0x816B	#CJK UNIFIED IDEOGRAPH
+0xB8A1	0x8179	#CJK UNIFIED IDEOGRAPH
+0xB8A2	0x817A	#CJK UNIFIED IDEOGRAPH
+0xB8A3	0x8166	#CJK UNIFIED IDEOGRAPH
+0xB8A4	0x8205	#CJK UNIFIED IDEOGRAPH
+0xB8A5	0x8247	#CJK UNIFIED IDEOGRAPH
+0xB8A6	0x8482	#CJK UNIFIED IDEOGRAPH
+0xB8A7	0x8477	#CJK UNIFIED IDEOGRAPH
+0xB8A8	0x843D	#CJK UNIFIED IDEOGRAPH
+0xB8A9	0x8431	#CJK UNIFIED IDEOGRAPH
+0xB8AA	0x8475	#CJK UNIFIED IDEOGRAPH
+0xB8AB	0x8466	#CJK UNIFIED IDEOGRAPH
+0xB8AC	0x846B	#CJK UNIFIED IDEOGRAPH
+0xB8AD	0x8449	#CJK UNIFIED IDEOGRAPH
+0xB8AE	0x846C	#CJK UNIFIED IDEOGRAPH
+0xB8AF	0x845B	#CJK UNIFIED IDEOGRAPH
+0xB8B0	0x843C	#CJK UNIFIED IDEOGRAPH
+0xB8B1	0x8435	#CJK UNIFIED IDEOGRAPH
+0xB8B2	0x8461	#CJK UNIFIED IDEOGRAPH
+0xB8B3	0x8463	#CJK UNIFIED IDEOGRAPH
+0xB8B4	0x8469	#CJK UNIFIED IDEOGRAPH
+0xB8B5	0x846D	#CJK UNIFIED IDEOGRAPH
+0xB8B6	0x8446	#CJK UNIFIED IDEOGRAPH
+0xB8B7	0x865E	#CJK UNIFIED IDEOGRAPH
+0xB8B8	0x865C	#CJK UNIFIED IDEOGRAPH
+0xB8B9	0x865F	#CJK UNIFIED IDEOGRAPH
+0xB8BA	0x86F9	#CJK UNIFIED IDEOGRAPH
+0xB8BB	0x8713	#CJK UNIFIED IDEOGRAPH
+0xB8BC	0x8708	#CJK UNIFIED IDEOGRAPH
+0xB8BD	0x8707	#CJK UNIFIED IDEOGRAPH
+0xB8BE	0x8700	#CJK UNIFIED IDEOGRAPH
+0xB8BF	0x86FE	#CJK UNIFIED IDEOGRAPH
+0xB8C0	0x86FB	#CJK UNIFIED IDEOGRAPH
+0xB8C1	0x8702	#CJK UNIFIED IDEOGRAPH
+0xB8C2	0x8703	#CJK UNIFIED IDEOGRAPH
+0xB8C3	0x8706	#CJK UNIFIED IDEOGRAPH
+0xB8C4	0x870A	#CJK UNIFIED IDEOGRAPH
+0xB8C5	0x8859	#CJK UNIFIED IDEOGRAPH
+0xB8C6	0x88DF	#CJK UNIFIED IDEOGRAPH
+0xB8C7	0x88D4	#CJK UNIFIED IDEOGRAPH
+0xB8C8	0x88D9	#CJK UNIFIED IDEOGRAPH
+0xB8C9	0x88DC	#CJK UNIFIED IDEOGRAPH
+0xB8CA	0x88D8	#CJK UNIFIED IDEOGRAPH
+0xB8CB	0x88DD	#CJK UNIFIED IDEOGRAPH
+0xB8CC	0x88E1	#CJK UNIFIED IDEOGRAPH
+0xB8CD	0x88CA	#CJK UNIFIED IDEOGRAPH
+0xB8CE	0x88D5	#CJK UNIFIED IDEOGRAPH
+0xB8CF	0x88D2	#CJK UNIFIED IDEOGRAPH
+0xB8D0	0x899C	#CJK UNIFIED IDEOGRAPH
+0xB8D1	0x89E3	#CJK UNIFIED IDEOGRAPH
+0xB8D2	0x8A6B	#CJK UNIFIED IDEOGRAPH
+0xB8D3	0x8A72	#CJK UNIFIED IDEOGRAPH
+0xB8D4	0x8A73	#CJK UNIFIED IDEOGRAPH
+0xB8D5	0x8A66	#CJK UNIFIED IDEOGRAPH
+0xB8D6	0x8A69	#CJK UNIFIED IDEOGRAPH
+0xB8D7	0x8A70	#CJK UNIFIED IDEOGRAPH
+0xB8D8	0x8A87	#CJK UNIFIED IDEOGRAPH
+0xB8D9	0x8A7C	#CJK UNIFIED IDEOGRAPH
+0xB8DA	0x8A63	#CJK UNIFIED IDEOGRAPH
+0xB8DB	0x8AA0	#CJK UNIFIED IDEOGRAPH
+0xB8DC	0x8A71	#CJK UNIFIED IDEOGRAPH
+0xB8DD	0x8A85	#CJK UNIFIED IDEOGRAPH
+0xB8DE	0x8A6D	#CJK UNIFIED IDEOGRAPH
+0xB8DF	0x8A62	#CJK UNIFIED IDEOGRAPH
+0xB8E0	0x8A6E	#CJK UNIFIED IDEOGRAPH
+0xB8E1	0x8A6C	#CJK UNIFIED IDEOGRAPH
+0xB8E2	0x8A79	#CJK UNIFIED IDEOGRAPH
+0xB8E3	0x8A7B	#CJK UNIFIED IDEOGRAPH
+0xB8E4	0x8A3E	#CJK UNIFIED IDEOGRAPH
+0xB8E5	0x8A68	#CJK UNIFIED IDEOGRAPH
+0xB8E6	0x8C62	#CJK UNIFIED IDEOGRAPH
+0xB8E7	0x8C8A	#CJK UNIFIED IDEOGRAPH
+0xB8E8	0x8C89	#CJK UNIFIED IDEOGRAPH
+0xB8E9	0x8CCA	#CJK UNIFIED IDEOGRAPH
+0xB8EA	0x8CC7	#CJK UNIFIED IDEOGRAPH
+0xB8EB	0x8CC8	#CJK UNIFIED IDEOGRAPH
+0xB8EC	0x8CC4	#CJK UNIFIED IDEOGRAPH
+0xB8ED	0x8CB2	#CJK UNIFIED IDEOGRAPH
+0xB8EE	0x8CC3	#CJK UNIFIED IDEOGRAPH
+0xB8EF	0x8CC2	#CJK UNIFIED IDEOGRAPH
+0xB8F0	0x8CC5	#CJK UNIFIED IDEOGRAPH
+0xB8F1	0x8DE1	#CJK UNIFIED IDEOGRAPH
+0xB8F2	0x8DDF	#CJK UNIFIED IDEOGRAPH
+0xB8F3	0x8DE8	#CJK UNIFIED IDEOGRAPH
+0xB8F4	0x8DEF	#CJK UNIFIED IDEOGRAPH
+0xB8F5	0x8DF3	#CJK UNIFIED IDEOGRAPH
+0xB8F6	0x8DFA	#CJK UNIFIED IDEOGRAPH
+0xB8F7	0x8DEA	#CJK UNIFIED IDEOGRAPH
+0xB8F8	0x8DE4	#CJK UNIFIED IDEOGRAPH
+0xB8F9	0x8DE6	#CJK UNIFIED IDEOGRAPH
+0xB8FA	0x8EB2	#CJK UNIFIED IDEOGRAPH
+0xB8FB	0x8F03	#CJK UNIFIED IDEOGRAPH
+0xB8FC	0x8F09	#CJK UNIFIED IDEOGRAPH
+0xB8FD	0x8EFE	#CJK UNIFIED IDEOGRAPH
+0xB8FE	0x8F0A	#CJK UNIFIED IDEOGRAPH
+0xB940	0x8F9F	#CJK UNIFIED IDEOGRAPH
+0xB941	0x8FB2	#CJK UNIFIED IDEOGRAPH
+0xB942	0x904B	#CJK UNIFIED IDEOGRAPH
+0xB943	0x904A	#CJK UNIFIED IDEOGRAPH
+0xB944	0x9053	#CJK UNIFIED IDEOGRAPH
+0xB945	0x9042	#CJK UNIFIED IDEOGRAPH
+0xB946	0x9054	#CJK UNIFIED IDEOGRAPH
+0xB947	0x903C	#CJK UNIFIED IDEOGRAPH
+0xB948	0x9055	#CJK UNIFIED IDEOGRAPH
+0xB949	0x9050	#CJK UNIFIED IDEOGRAPH
+0xB94A	0x9047	#CJK UNIFIED IDEOGRAPH
+0xB94B	0x904F	#CJK UNIFIED IDEOGRAPH
+0xB94C	0x904E	#CJK UNIFIED IDEOGRAPH
+0xB94D	0x904D	#CJK UNIFIED IDEOGRAPH
+0xB94E	0x9051	#CJK UNIFIED IDEOGRAPH
+0xB94F	0x903E	#CJK UNIFIED IDEOGRAPH
+0xB950	0x9041	#CJK UNIFIED IDEOGRAPH
+0xB951	0x9112	#CJK UNIFIED IDEOGRAPH
+0xB952	0x9117	#CJK UNIFIED IDEOGRAPH
+0xB953	0x916C	#CJK UNIFIED IDEOGRAPH
+0xB954	0x916A	#CJK UNIFIED IDEOGRAPH
+0xB955	0x9169	#CJK UNIFIED IDEOGRAPH
+0xB956	0x91C9	#CJK UNIFIED IDEOGRAPH
+0xB957	0x9237	#CJK UNIFIED IDEOGRAPH
+0xB958	0x9257	#CJK UNIFIED IDEOGRAPH
+0xB959	0x9238	#CJK UNIFIED IDEOGRAPH
+0xB95A	0x923D	#CJK UNIFIED IDEOGRAPH
+0xB95B	0x9240	#CJK UNIFIED IDEOGRAPH
+0xB95C	0x923E	#CJK UNIFIED IDEOGRAPH
+0xB95D	0x925B	#CJK UNIFIED IDEOGRAPH
+0xB95E	0x924B	#CJK UNIFIED IDEOGRAPH
+0xB95F	0x9264	#CJK UNIFIED IDEOGRAPH
+0xB960	0x9251	#CJK UNIFIED IDEOGRAPH
+0xB961	0x9234	#CJK UNIFIED IDEOGRAPH
+0xB962	0x9249	#CJK UNIFIED IDEOGRAPH
+0xB963	0x924D	#CJK UNIFIED IDEOGRAPH
+0xB964	0x9245	#CJK UNIFIED IDEOGRAPH
+0xB965	0x9239	#CJK UNIFIED IDEOGRAPH
+0xB966	0x923F	#CJK UNIFIED IDEOGRAPH
+0xB967	0x925A	#CJK UNIFIED IDEOGRAPH
+0xB968	0x9598	#CJK UNIFIED IDEOGRAPH
+0xB969	0x9698	#CJK UNIFIED IDEOGRAPH
+0xB96A	0x9694	#CJK UNIFIED IDEOGRAPH
+0xB96B	0x9695	#CJK UNIFIED IDEOGRAPH
+0xB96C	0x96CD	#CJK UNIFIED IDEOGRAPH
+0xB96D	0x96CB	#CJK UNIFIED IDEOGRAPH
+0xB96E	0x96C9	#CJK UNIFIED IDEOGRAPH
+0xB96F	0x96CA	#CJK UNIFIED IDEOGRAPH
+0xB970	0x96F7	#CJK UNIFIED IDEOGRAPH
+0xB971	0x96FB	#CJK UNIFIED IDEOGRAPH
+0xB972	0x96F9	#CJK UNIFIED IDEOGRAPH
+0xB973	0x96F6	#CJK UNIFIED IDEOGRAPH
+0xB974	0x9756	#CJK UNIFIED IDEOGRAPH
+0xB975	0x9774	#CJK UNIFIED IDEOGRAPH
+0xB976	0x9776	#CJK UNIFIED IDEOGRAPH
+0xB977	0x9810	#CJK UNIFIED IDEOGRAPH
+0xB978	0x9811	#CJK UNIFIED IDEOGRAPH
+0xB979	0x9813	#CJK UNIFIED IDEOGRAPH
+0xB97A	0x980A	#CJK UNIFIED IDEOGRAPH
+0xB97B	0x9812	#CJK UNIFIED IDEOGRAPH
+0xB97C	0x980C	#CJK UNIFIED IDEOGRAPH
+0xB97D	0x98FC	#CJK UNIFIED IDEOGRAPH
+0xB97E	0x98F4	#CJK UNIFIED IDEOGRAPH
+0xB9A1	0x98FD	#CJK UNIFIED IDEOGRAPH
+0xB9A2	0x98FE	#CJK UNIFIED IDEOGRAPH
+0xB9A3	0x99B3	#CJK UNIFIED IDEOGRAPH
+0xB9A4	0x99B1	#CJK UNIFIED IDEOGRAPH
+0xB9A5	0x99B4	#CJK UNIFIED IDEOGRAPH
+0xB9A6	0x9AE1	#CJK UNIFIED IDEOGRAPH
+0xB9A7	0x9CE9	#CJK UNIFIED IDEOGRAPH
+0xB9A8	0x9E82	#CJK UNIFIED IDEOGRAPH
+0xB9A9	0x9F0E	#CJK UNIFIED IDEOGRAPH
+0xB9AA	0x9F13	#CJK UNIFIED IDEOGRAPH
+0xB9AB	0x9F20	#CJK UNIFIED IDEOGRAPH
+0xB9AC	0x50E7	#CJK UNIFIED IDEOGRAPH
+0xB9AD	0x50EE	#CJK UNIFIED IDEOGRAPH
+0xB9AE	0x50E5	#CJK UNIFIED IDEOGRAPH
+0xB9AF	0x50D6	#CJK UNIFIED IDEOGRAPH
+0xB9B0	0x50ED	#CJK UNIFIED IDEOGRAPH
+0xB9B1	0x50DA	#CJK UNIFIED IDEOGRAPH
+0xB9B2	0x50D5	#CJK UNIFIED IDEOGRAPH
+0xB9B3	0x50CF	#CJK UNIFIED IDEOGRAPH
+0xB9B4	0x50D1	#CJK UNIFIED IDEOGRAPH
+0xB9B5	0x50F1	#CJK UNIFIED IDEOGRAPH
+0xB9B6	0x50CE	#CJK UNIFIED IDEOGRAPH
+0xB9B7	0x50E9	#CJK UNIFIED IDEOGRAPH
+0xB9B8	0x5162	#CJK UNIFIED IDEOGRAPH
+0xB9B9	0x51F3	#CJK UNIFIED IDEOGRAPH
+0xB9BA	0x5283	#CJK UNIFIED IDEOGRAPH
+0xB9BB	0x5282	#CJK UNIFIED IDEOGRAPH
+0xB9BC	0x5331	#CJK UNIFIED IDEOGRAPH
+0xB9BD	0x53AD	#CJK UNIFIED IDEOGRAPH
+0xB9BE	0x55FE	#CJK UNIFIED IDEOGRAPH
+0xB9BF	0x5600	#CJK UNIFIED IDEOGRAPH
+0xB9C0	0x561B	#CJK UNIFIED IDEOGRAPH
+0xB9C1	0x5617	#CJK UNIFIED IDEOGRAPH
+0xB9C2	0x55FD	#CJK UNIFIED IDEOGRAPH
+0xB9C3	0x5614	#CJK UNIFIED IDEOGRAPH
+0xB9C4	0x5606	#CJK UNIFIED IDEOGRAPH
+0xB9C5	0x5609	#CJK UNIFIED IDEOGRAPH
+0xB9C6	0x560D	#CJK UNIFIED IDEOGRAPH
+0xB9C7	0x560E	#CJK UNIFIED IDEOGRAPH
+0xB9C8	0x55F7	#CJK UNIFIED IDEOGRAPH
+0xB9C9	0x5616	#CJK UNIFIED IDEOGRAPH
+0xB9CA	0x561F	#CJK UNIFIED IDEOGRAPH
+0xB9CB	0x5608	#CJK UNIFIED IDEOGRAPH
+0xB9CC	0x5610	#CJK UNIFIED IDEOGRAPH
+0xB9CD	0x55F6	#CJK UNIFIED IDEOGRAPH
+0xB9CE	0x5718	#CJK UNIFIED IDEOGRAPH
+0xB9CF	0x5716	#CJK UNIFIED IDEOGRAPH
+0xB9D0	0x5875	#CJK UNIFIED IDEOGRAPH
+0xB9D1	0x587E	#CJK UNIFIED IDEOGRAPH
+0xB9D2	0x5883	#CJK UNIFIED IDEOGRAPH
+0xB9D3	0x5893	#CJK UNIFIED IDEOGRAPH
+0xB9D4	0x588A	#CJK UNIFIED IDEOGRAPH
+0xB9D5	0x5879	#CJK UNIFIED IDEOGRAPH
+0xB9D6	0x5885	#CJK UNIFIED IDEOGRAPH
+0xB9D7	0x587D	#CJK UNIFIED IDEOGRAPH
+0xB9D8	0x58FD	#CJK UNIFIED IDEOGRAPH
+0xB9D9	0x5925	#CJK UNIFIED IDEOGRAPH
+0xB9DA	0x5922	#CJK UNIFIED IDEOGRAPH
+0xB9DB	0x5924	#CJK UNIFIED IDEOGRAPH
+0xB9DC	0x596A	#CJK UNIFIED IDEOGRAPH
+0xB9DD	0x5969	#CJK UNIFIED IDEOGRAPH
+0xB9DE	0x5AE1	#CJK UNIFIED IDEOGRAPH
+0xB9DF	0x5AE6	#CJK UNIFIED IDEOGRAPH
+0xB9E0	0x5AE9	#CJK UNIFIED IDEOGRAPH
+0xB9E1	0x5AD7	#CJK UNIFIED IDEOGRAPH
+0xB9E2	0x5AD6	#CJK UNIFIED IDEOGRAPH
+0xB9E3	0x5AD8	#CJK UNIFIED IDEOGRAPH
+0xB9E4	0x5AE3	#CJK UNIFIED IDEOGRAPH
+0xB9E5	0x5B75	#CJK UNIFIED IDEOGRAPH
+0xB9E6	0x5BDE	#CJK UNIFIED IDEOGRAPH
+0xB9E7	0x5BE7	#CJK UNIFIED IDEOGRAPH
+0xB9E8	0x5BE1	#CJK UNIFIED IDEOGRAPH
+0xB9E9	0x5BE5	#CJK UNIFIED IDEOGRAPH
+0xB9EA	0x5BE6	#CJK UNIFIED IDEOGRAPH
+0xB9EB	0x5BE8	#CJK UNIFIED IDEOGRAPH
+0xB9EC	0x5BE2	#CJK UNIFIED IDEOGRAPH
+0xB9ED	0x5BE4	#CJK UNIFIED IDEOGRAPH
+0xB9EE	0x5BDF	#CJK UNIFIED IDEOGRAPH
+0xB9EF	0x5C0D	#CJK UNIFIED IDEOGRAPH
+0xB9F0	0x5C62	#CJK UNIFIED IDEOGRAPH
+0xB9F1	0x5D84	#CJK UNIFIED IDEOGRAPH
+0xB9F2	0x5D87	#CJK UNIFIED IDEOGRAPH
+0xB9F3	0x5E5B	#CJK UNIFIED IDEOGRAPH
+0xB9F4	0x5E63	#CJK UNIFIED IDEOGRAPH
+0xB9F5	0x5E55	#CJK UNIFIED IDEOGRAPH
+0xB9F6	0x5E57	#CJK UNIFIED IDEOGRAPH
+0xB9F7	0x5E54	#CJK UNIFIED IDEOGRAPH
+0xB9F8	0x5ED3	#CJK UNIFIED IDEOGRAPH
+0xB9F9	0x5ED6	#CJK UNIFIED IDEOGRAPH
+0xB9FA	0x5F0A	#CJK UNIFIED IDEOGRAPH
+0xB9FB	0x5F46	#CJK UNIFIED IDEOGRAPH
+0xB9FC	0x5F70	#CJK UNIFIED IDEOGRAPH
+0xB9FD	0x5FB9	#CJK UNIFIED IDEOGRAPH
+0xB9FE	0x6147	#CJK UNIFIED IDEOGRAPH
+0xBA40	0x613F	#CJK UNIFIED IDEOGRAPH
+0xBA41	0x614B	#CJK UNIFIED IDEOGRAPH
+0xBA42	0x6177	#CJK UNIFIED IDEOGRAPH
+0xBA43	0x6162	#CJK UNIFIED IDEOGRAPH
+0xBA44	0x6163	#CJK UNIFIED IDEOGRAPH
+0xBA45	0x615F	#CJK UNIFIED IDEOGRAPH
+0xBA46	0x615A	#CJK UNIFIED IDEOGRAPH
+0xBA47	0x6158	#CJK UNIFIED IDEOGRAPH
+0xBA48	0x6175	#CJK UNIFIED IDEOGRAPH
+0xBA49	0x622A	#CJK UNIFIED IDEOGRAPH
+0xBA4A	0x6487	#CJK UNIFIED IDEOGRAPH
+0xBA4B	0x6458	#CJK UNIFIED IDEOGRAPH
+0xBA4C	0x6454	#CJK UNIFIED IDEOGRAPH
+0xBA4D	0x64A4	#CJK UNIFIED IDEOGRAPH
+0xBA4E	0x6478	#CJK UNIFIED IDEOGRAPH
+0xBA4F	0x645F	#CJK UNIFIED IDEOGRAPH
+0xBA50	0x647A	#CJK UNIFIED IDEOGRAPH
+0xBA51	0x6451	#CJK UNIFIED IDEOGRAPH
+0xBA52	0x6467	#CJK UNIFIED IDEOGRAPH
+0xBA53	0x6434	#CJK UNIFIED IDEOGRAPH
+0xBA54	0x646D	#CJK UNIFIED IDEOGRAPH
+0xBA55	0x647B	#CJK UNIFIED IDEOGRAPH
+0xBA56	0x6572	#CJK UNIFIED IDEOGRAPH
+0xBA57	0x65A1	#CJK UNIFIED IDEOGRAPH
+0xBA58	0x65D7	#CJK UNIFIED IDEOGRAPH
+0xBA59	0x65D6	#CJK UNIFIED IDEOGRAPH
+0xBA5A	0x66A2	#CJK UNIFIED IDEOGRAPH
+0xBA5B	0x66A8	#CJK UNIFIED IDEOGRAPH
+0xBA5C	0x669D	#CJK UNIFIED IDEOGRAPH
+0xBA5D	0x699C	#CJK UNIFIED IDEOGRAPH
+0xBA5E	0x69A8	#CJK UNIFIED IDEOGRAPH
+0xBA5F	0x6995	#CJK UNIFIED IDEOGRAPH
+0xBA60	0x69C1	#CJK UNIFIED IDEOGRAPH
+0xBA61	0x69AE	#CJK UNIFIED IDEOGRAPH
+0xBA62	0x69D3	#CJK UNIFIED IDEOGRAPH
+0xBA63	0x69CB	#CJK UNIFIED IDEOGRAPH
+0xBA64	0x699B	#CJK UNIFIED IDEOGRAPH
+0xBA65	0x69B7	#CJK UNIFIED IDEOGRAPH
+0xBA66	0x69BB	#CJK UNIFIED IDEOGRAPH
+0xBA67	0x69AB	#CJK UNIFIED IDEOGRAPH
+0xBA68	0x69B4	#CJK UNIFIED IDEOGRAPH
+0xBA69	0x69D0	#CJK UNIFIED IDEOGRAPH
+0xBA6A	0x69CD	#CJK UNIFIED IDEOGRAPH
+0xBA6B	0x69AD	#CJK UNIFIED IDEOGRAPH
+0xBA6C	0x69CC	#CJK UNIFIED IDEOGRAPH
+0xBA6D	0x69A6	#CJK UNIFIED IDEOGRAPH
+0xBA6E	0x69C3	#CJK UNIFIED IDEOGRAPH
+0xBA6F	0x69A3	#CJK UNIFIED IDEOGRAPH
+0xBA70	0x6B49	#CJK UNIFIED IDEOGRAPH
+0xBA71	0x6B4C	#CJK UNIFIED IDEOGRAPH
+0xBA72	0x6C33	#CJK UNIFIED IDEOGRAPH
+0xBA73	0x6F33	#CJK UNIFIED IDEOGRAPH
+0xBA74	0x6F14	#CJK UNIFIED IDEOGRAPH
+0xBA75	0x6EFE	#CJK UNIFIED IDEOGRAPH
+0xBA76	0x6F13	#CJK UNIFIED IDEOGRAPH
+0xBA77	0x6EF4	#CJK UNIFIED IDEOGRAPH
+0xBA78	0x6F29	#CJK UNIFIED IDEOGRAPH
+0xBA79	0x6F3E	#CJK UNIFIED IDEOGRAPH
+0xBA7A	0x6F20	#CJK UNIFIED IDEOGRAPH
+0xBA7B	0x6F2C	#CJK UNIFIED IDEOGRAPH
+0xBA7C	0x6F0F	#CJK UNIFIED IDEOGRAPH
+0xBA7D	0x6F02	#CJK UNIFIED IDEOGRAPH
+0xBA7E	0x6F22	#CJK UNIFIED IDEOGRAPH
+0xBAA1	0x6EFF	#CJK UNIFIED IDEOGRAPH
+0xBAA2	0x6EEF	#CJK UNIFIED IDEOGRAPH
+0xBAA3	0x6F06	#CJK UNIFIED IDEOGRAPH
+0xBAA4	0x6F31	#CJK UNIFIED IDEOGRAPH
+0xBAA5	0x6F38	#CJK UNIFIED IDEOGRAPH
+0xBAA6	0x6F32	#CJK UNIFIED IDEOGRAPH
+0xBAA7	0x6F23	#CJK UNIFIED IDEOGRAPH
+0xBAA8	0x6F15	#CJK UNIFIED IDEOGRAPH
+0xBAA9	0x6F2B	#CJK UNIFIED IDEOGRAPH
+0xBAAA	0x6F2F	#CJK UNIFIED IDEOGRAPH
+0xBAAB	0x6F88	#CJK UNIFIED IDEOGRAPH
+0xBAAC	0x6F2A	#CJK UNIFIED IDEOGRAPH
+0xBAAD	0x6EEC	#CJK UNIFIED IDEOGRAPH
+0xBAAE	0x6F01	#CJK UNIFIED IDEOGRAPH
+0xBAAF	0x6EF2	#CJK UNIFIED IDEOGRAPH
+0xBAB0	0x6ECC	#CJK UNIFIED IDEOGRAPH
+0xBAB1	0x6EF7	#CJK UNIFIED IDEOGRAPH
+0xBAB2	0x7194	#CJK UNIFIED IDEOGRAPH
+0xBAB3	0x7199	#CJK UNIFIED IDEOGRAPH
+0xBAB4	0x717D	#CJK UNIFIED IDEOGRAPH
+0xBAB5	0x718A	#CJK UNIFIED IDEOGRAPH
+0xBAB6	0x7184	#CJK UNIFIED IDEOGRAPH
+0xBAB7	0x7192	#CJK UNIFIED IDEOGRAPH
+0xBAB8	0x723E	#CJK UNIFIED IDEOGRAPH
+0xBAB9	0x7292	#CJK UNIFIED IDEOGRAPH
+0xBABA	0x7296	#CJK UNIFIED IDEOGRAPH
+0xBABB	0x7344	#CJK UNIFIED IDEOGRAPH
+0xBABC	0x7350	#CJK UNIFIED IDEOGRAPH
+0xBABD	0x7464	#CJK UNIFIED IDEOGRAPH
+0xBABE	0x7463	#CJK UNIFIED IDEOGRAPH
+0xBABF	0x746A	#CJK UNIFIED IDEOGRAPH
+0xBAC0	0x7470	#CJK UNIFIED IDEOGRAPH
+0xBAC1	0x746D	#CJK UNIFIED IDEOGRAPH
+0xBAC2	0x7504	#CJK UNIFIED IDEOGRAPH
+0xBAC3	0x7591	#CJK UNIFIED IDEOGRAPH
+0xBAC4	0x7627	#CJK UNIFIED IDEOGRAPH
+0xBAC5	0x760D	#CJK UNIFIED IDEOGRAPH
+0xBAC6	0x760B	#CJK UNIFIED IDEOGRAPH
+0xBAC7	0x7609	#CJK UNIFIED IDEOGRAPH
+0xBAC8	0x7613	#CJK UNIFIED IDEOGRAPH
+0xBAC9	0x76E1	#CJK UNIFIED IDEOGRAPH
+0xBACA	0x76E3	#CJK UNIFIED IDEOGRAPH
+0xBACB	0x7784	#CJK UNIFIED IDEOGRAPH
+0xBACC	0x777D	#CJK UNIFIED IDEOGRAPH
+0xBACD	0x777F	#CJK UNIFIED IDEOGRAPH
+0xBACE	0x7761	#CJK UNIFIED IDEOGRAPH
+0xBACF	0x78C1	#CJK UNIFIED IDEOGRAPH
+0xBAD0	0x789F	#CJK UNIFIED IDEOGRAPH
+0xBAD1	0x78A7	#CJK UNIFIED IDEOGRAPH
+0xBAD2	0x78B3	#CJK UNIFIED IDEOGRAPH
+0xBAD3	0x78A9	#CJK UNIFIED IDEOGRAPH
+0xBAD4	0x78A3	#CJK UNIFIED IDEOGRAPH
+0xBAD5	0x798E	#CJK UNIFIED IDEOGRAPH
+0xBAD6	0x798F	#CJK UNIFIED IDEOGRAPH
+0xBAD7	0x798D	#CJK UNIFIED IDEOGRAPH
+0xBAD8	0x7A2E	#CJK UNIFIED IDEOGRAPH
+0xBAD9	0x7A31	#CJK UNIFIED IDEOGRAPH
+0xBADA	0x7AAA	#CJK UNIFIED IDEOGRAPH
+0xBADB	0x7AA9	#CJK UNIFIED IDEOGRAPH
+0xBADC	0x7AED	#CJK UNIFIED IDEOGRAPH
+0xBADD	0x7AEF	#CJK UNIFIED IDEOGRAPH
+0xBADE	0x7BA1	#CJK UNIFIED IDEOGRAPH
+0xBADF	0x7B95	#CJK UNIFIED IDEOGRAPH
+0xBAE0	0x7B8B	#CJK UNIFIED IDEOGRAPH
+0xBAE1	0x7B75	#CJK UNIFIED IDEOGRAPH
+0xBAE2	0x7B97	#CJK UNIFIED IDEOGRAPH
+0xBAE3	0x7B9D	#CJK UNIFIED IDEOGRAPH
+0xBAE4	0x7B94	#CJK UNIFIED IDEOGRAPH
+0xBAE5	0x7B8F	#CJK UNIFIED IDEOGRAPH
+0xBAE6	0x7BB8	#CJK UNIFIED IDEOGRAPH
+0xBAE7	0x7B87	#CJK UNIFIED IDEOGRAPH
+0xBAE8	0x7B84	#CJK UNIFIED IDEOGRAPH
+0xBAE9	0x7CB9	#CJK UNIFIED IDEOGRAPH
+0xBAEA	0x7CBD	#CJK UNIFIED IDEOGRAPH
+0xBAEB	0x7CBE	#CJK UNIFIED IDEOGRAPH
+0xBAEC	0x7DBB	#CJK UNIFIED IDEOGRAPH
+0xBAED	0x7DB0	#CJK UNIFIED IDEOGRAPH
+0xBAEE	0x7D9C	#CJK UNIFIED IDEOGRAPH
+0xBAEF	0x7DBD	#CJK UNIFIED IDEOGRAPH
+0xBAF0	0x7DBE	#CJK UNIFIED IDEOGRAPH
+0xBAF1	0x7DA0	#CJK UNIFIED IDEOGRAPH
+0xBAF2	0x7DCA	#CJK UNIFIED IDEOGRAPH
+0xBAF3	0x7DB4	#CJK UNIFIED IDEOGRAPH
+0xBAF4	0x7DB2	#CJK UNIFIED IDEOGRAPH
+0xBAF5	0x7DB1	#CJK UNIFIED IDEOGRAPH
+0xBAF6	0x7DBA	#CJK UNIFIED IDEOGRAPH
+0xBAF7	0x7DA2	#CJK UNIFIED IDEOGRAPH
+0xBAF8	0x7DBF	#CJK UNIFIED IDEOGRAPH
+0xBAF9	0x7DB5	#CJK UNIFIED IDEOGRAPH
+0xBAFA	0x7DB8	#CJK UNIFIED IDEOGRAPH
+0xBAFB	0x7DAD	#CJK UNIFIED IDEOGRAPH
+0xBAFC	0x7DD2	#CJK UNIFIED IDEOGRAPH
+0xBAFD	0x7DC7	#CJK UNIFIED IDEOGRAPH
+0xBAFE	0x7DAC	#CJK UNIFIED IDEOGRAPH
+0xBB40	0x7F70	#CJK UNIFIED IDEOGRAPH
+0xBB41	0x7FE0	#CJK UNIFIED IDEOGRAPH
+0xBB42	0x7FE1	#CJK UNIFIED IDEOGRAPH
+0xBB43	0x7FDF	#CJK UNIFIED IDEOGRAPH
+0xBB44	0x805E	#CJK UNIFIED IDEOGRAPH
+0xBB45	0x805A	#CJK UNIFIED IDEOGRAPH
+0xBB46	0x8087	#CJK UNIFIED IDEOGRAPH
+0xBB47	0x8150	#CJK UNIFIED IDEOGRAPH
+0xBB48	0x8180	#CJK UNIFIED IDEOGRAPH
+0xBB49	0x818F	#CJK UNIFIED IDEOGRAPH
+0xBB4A	0x8188	#CJK UNIFIED IDEOGRAPH
+0xBB4B	0x818A	#CJK UNIFIED IDEOGRAPH
+0xBB4C	0x817F	#CJK UNIFIED IDEOGRAPH
+0xBB4D	0x8182	#CJK UNIFIED IDEOGRAPH
+0xBB4E	0x81E7	#CJK UNIFIED IDEOGRAPH
+0xBB4F	0x81FA	#CJK UNIFIED IDEOGRAPH
+0xBB50	0x8207	#CJK UNIFIED IDEOGRAPH
+0xBB51	0x8214	#CJK UNIFIED IDEOGRAPH
+0xBB52	0x821E	#CJK UNIFIED IDEOGRAPH
+0xBB53	0x824B	#CJK UNIFIED IDEOGRAPH
+0xBB54	0x84C9	#CJK UNIFIED IDEOGRAPH
+0xBB55	0x84BF	#CJK UNIFIED IDEOGRAPH
+0xBB56	0x84C6	#CJK UNIFIED IDEOGRAPH
+0xBB57	0x84C4	#CJK UNIFIED IDEOGRAPH
+0xBB58	0x8499	#CJK UNIFIED IDEOGRAPH
+0xBB59	0x849E	#CJK UNIFIED IDEOGRAPH
+0xBB5A	0x84B2	#CJK UNIFIED IDEOGRAPH
+0xBB5B	0x849C	#CJK UNIFIED IDEOGRAPH
+0xBB5C	0x84CB	#CJK UNIFIED IDEOGRAPH
+0xBB5D	0x84B8	#CJK UNIFIED IDEOGRAPH
+0xBB5E	0x84C0	#CJK UNIFIED IDEOGRAPH
+0xBB5F	0x84D3	#CJK UNIFIED IDEOGRAPH
+0xBB60	0x8490	#CJK UNIFIED IDEOGRAPH
+0xBB61	0x84BC	#CJK UNIFIED IDEOGRAPH
+0xBB62	0x84D1	#CJK UNIFIED IDEOGRAPH
+0xBB63	0x84CA	#CJK UNIFIED IDEOGRAPH
+0xBB64	0x873F	#CJK UNIFIED IDEOGRAPH
+0xBB65	0x871C	#CJK UNIFIED IDEOGRAPH
+0xBB66	0x873B	#CJK UNIFIED IDEOGRAPH
+0xBB67	0x8722	#CJK UNIFIED IDEOGRAPH
+0xBB68	0x8725	#CJK UNIFIED IDEOGRAPH
+0xBB69	0x8734	#CJK UNIFIED IDEOGRAPH
+0xBB6A	0x8718	#CJK UNIFIED IDEOGRAPH
+0xBB6B	0x8755	#CJK UNIFIED IDEOGRAPH
+0xBB6C	0x8737	#CJK UNIFIED IDEOGRAPH
+0xBB6D	0x8729	#CJK UNIFIED IDEOGRAPH
+0xBB6E	0x88F3	#CJK UNIFIED IDEOGRAPH
+0xBB6F	0x8902	#CJK UNIFIED IDEOGRAPH
+0xBB70	0x88F4	#CJK UNIFIED IDEOGRAPH
+0xBB71	0x88F9	#CJK UNIFIED IDEOGRAPH
+0xBB72	0x88F8	#CJK UNIFIED IDEOGRAPH
+0xBB73	0x88FD	#CJK UNIFIED IDEOGRAPH
+0xBB74	0x88E8	#CJK UNIFIED IDEOGRAPH
+0xBB75	0x891A	#CJK UNIFIED IDEOGRAPH
+0xBB76	0x88EF	#CJK UNIFIED IDEOGRAPH
+0xBB77	0x8AA6	#CJK UNIFIED IDEOGRAPH
+0xBB78	0x8A8C	#CJK UNIFIED IDEOGRAPH
+0xBB79	0x8A9E	#CJK UNIFIED IDEOGRAPH
+0xBB7A	0x8AA3	#CJK UNIFIED IDEOGRAPH
+0xBB7B	0x8A8D	#CJK UNIFIED IDEOGRAPH
+0xBB7C	0x8AA1	#CJK UNIFIED IDEOGRAPH
+0xBB7D	0x8A93	#CJK UNIFIED IDEOGRAPH
+0xBB7E	0x8AA4	#CJK UNIFIED IDEOGRAPH
+0xBBA1	0x8AAA	#CJK UNIFIED IDEOGRAPH
+0xBBA2	0x8AA5	#CJK UNIFIED IDEOGRAPH
+0xBBA3	0x8AA8	#CJK UNIFIED IDEOGRAPH
+0xBBA4	0x8A98	#CJK UNIFIED IDEOGRAPH
+0xBBA5	0x8A91	#CJK UNIFIED IDEOGRAPH
+0xBBA6	0x8A9A	#CJK UNIFIED IDEOGRAPH
+0xBBA7	0x8AA7	#CJK UNIFIED IDEOGRAPH
+0xBBA8	0x8C6A	#CJK UNIFIED IDEOGRAPH
+0xBBA9	0x8C8D	#CJK UNIFIED IDEOGRAPH
+0xBBAA	0x8C8C	#CJK UNIFIED IDEOGRAPH
+0xBBAB	0x8CD3	#CJK UNIFIED IDEOGRAPH
+0xBBAC	0x8CD1	#CJK UNIFIED IDEOGRAPH
+0xBBAD	0x8CD2	#CJK UNIFIED IDEOGRAPH
+0xBBAE	0x8D6B	#CJK UNIFIED IDEOGRAPH
+0xBBAF	0x8D99	#CJK UNIFIED IDEOGRAPH
+0xBBB0	0x8D95	#CJK UNIFIED IDEOGRAPH
+0xBBB1	0x8DFC	#CJK UNIFIED IDEOGRAPH
+0xBBB2	0x8F14	#CJK UNIFIED IDEOGRAPH
+0xBBB3	0x8F12	#CJK UNIFIED IDEOGRAPH
+0xBBB4	0x8F15	#CJK UNIFIED IDEOGRAPH
+0xBBB5	0x8F13	#CJK UNIFIED IDEOGRAPH
+0xBBB6	0x8FA3	#CJK UNIFIED IDEOGRAPH
+0xBBB7	0x9060	#CJK UNIFIED IDEOGRAPH
+0xBBB8	0x9058	#CJK UNIFIED IDEOGRAPH
+0xBBB9	0x905C	#CJK UNIFIED IDEOGRAPH
+0xBBBA	0x9063	#CJK UNIFIED IDEOGRAPH
+0xBBBB	0x9059	#CJK UNIFIED IDEOGRAPH
+0xBBBC	0x905E	#CJK UNIFIED IDEOGRAPH
+0xBBBD	0x9062	#CJK UNIFIED IDEOGRAPH
+0xBBBE	0x905D	#CJK UNIFIED IDEOGRAPH
+0xBBBF	0x905B	#CJK UNIFIED IDEOGRAPH
+0xBBC0	0x9119	#CJK UNIFIED IDEOGRAPH
+0xBBC1	0x9118	#CJK UNIFIED IDEOGRAPH
+0xBBC2	0x911E	#CJK UNIFIED IDEOGRAPH
+0xBBC3	0x9175	#CJK UNIFIED IDEOGRAPH
+0xBBC4	0x9178	#CJK UNIFIED IDEOGRAPH
+0xBBC5	0x9177	#CJK UNIFIED IDEOGRAPH
+0xBBC6	0x9174	#CJK UNIFIED IDEOGRAPH
+0xBBC7	0x9278	#CJK UNIFIED IDEOGRAPH
+0xBBC8	0x9280	#CJK UNIFIED IDEOGRAPH
+0xBBC9	0x9285	#CJK UNIFIED IDEOGRAPH
+0xBBCA	0x9298	#CJK UNIFIED IDEOGRAPH
+0xBBCB	0x9296	#CJK UNIFIED IDEOGRAPH
+0xBBCC	0x927B	#CJK UNIFIED IDEOGRAPH
+0xBBCD	0x9293	#CJK UNIFIED IDEOGRAPH
+0xBBCE	0x929C	#CJK UNIFIED IDEOGRAPH
+0xBBCF	0x92A8	#CJK UNIFIED IDEOGRAPH
+0xBBD0	0x927C	#CJK UNIFIED IDEOGRAPH
+0xBBD1	0x9291	#CJK UNIFIED IDEOGRAPH
+0xBBD2	0x95A1	#CJK UNIFIED IDEOGRAPH
+0xBBD3	0x95A8	#CJK UNIFIED IDEOGRAPH
+0xBBD4	0x95A9	#CJK UNIFIED IDEOGRAPH
+0xBBD5	0x95A3	#CJK UNIFIED IDEOGRAPH
+0xBBD6	0x95A5	#CJK UNIFIED IDEOGRAPH
+0xBBD7	0x95A4	#CJK UNIFIED IDEOGRAPH
+0xBBD8	0x9699	#CJK UNIFIED IDEOGRAPH
+0xBBD9	0x969C	#CJK UNIFIED IDEOGRAPH
+0xBBDA	0x969B	#CJK UNIFIED IDEOGRAPH
+0xBBDB	0x96CC	#CJK UNIFIED IDEOGRAPH
+0xBBDC	0x96D2	#CJK UNIFIED IDEOGRAPH
+0xBBDD	0x9700	#CJK UNIFIED IDEOGRAPH
+0xBBDE	0x977C	#CJK UNIFIED IDEOGRAPH
+0xBBDF	0x9785	#CJK UNIFIED IDEOGRAPH
+0xBBE0	0x97F6	#CJK UNIFIED IDEOGRAPH
+0xBBE1	0x9817	#CJK UNIFIED IDEOGRAPH
+0xBBE2	0x9818	#CJK UNIFIED IDEOGRAPH
+0xBBE3	0x98AF	#CJK UNIFIED IDEOGRAPH
+0xBBE4	0x98B1	#CJK UNIFIED IDEOGRAPH
+0xBBE5	0x9903	#CJK UNIFIED IDEOGRAPH
+0xBBE6	0x9905	#CJK UNIFIED IDEOGRAPH
+0xBBE7	0x990C	#CJK UNIFIED IDEOGRAPH
+0xBBE8	0x9909	#CJK UNIFIED IDEOGRAPH
+0xBBE9	0x99C1	#CJK UNIFIED IDEOGRAPH
+0xBBEA	0x9AAF	#CJK UNIFIED IDEOGRAPH
+0xBBEB	0x9AB0	#CJK UNIFIED IDEOGRAPH
+0xBBEC	0x9AE6	#CJK UNIFIED IDEOGRAPH
+0xBBED	0x9B41	#CJK UNIFIED IDEOGRAPH
+0xBBEE	0x9B42	#CJK UNIFIED IDEOGRAPH
+0xBBEF	0x9CF4	#CJK UNIFIED IDEOGRAPH
+0xBBF0	0x9CF6	#CJK UNIFIED IDEOGRAPH
+0xBBF1	0x9CF3	#CJK UNIFIED IDEOGRAPH
+0xBBF2	0x9EBC	#CJK UNIFIED IDEOGRAPH
+0xBBF3	0x9F3B	#CJK UNIFIED IDEOGRAPH
+0xBBF4	0x9F4A	#CJK UNIFIED IDEOGRAPH
+0xBBF5	0x5104	#CJK UNIFIED IDEOGRAPH
+0xBBF6	0x5100	#CJK UNIFIED IDEOGRAPH
+0xBBF7	0x50FB	#CJK UNIFIED IDEOGRAPH
+0xBBF8	0x50F5	#CJK UNIFIED IDEOGRAPH
+0xBBF9	0x50F9	#CJK UNIFIED IDEOGRAPH
+0xBBFA	0x5102	#CJK UNIFIED IDEOGRAPH
+0xBBFB	0x5108	#CJK UNIFIED IDEOGRAPH
+0xBBFC	0x5109	#CJK UNIFIED IDEOGRAPH
+0xBBFD	0x5105	#CJK UNIFIED IDEOGRAPH
+0xBBFE	0x51DC	#CJK UNIFIED IDEOGRAPH
+0xBC40	0x5287	#CJK UNIFIED IDEOGRAPH
+0xBC41	0x5288	#CJK UNIFIED IDEOGRAPH
+0xBC42	0x5289	#CJK UNIFIED IDEOGRAPH
+0xBC43	0x528D	#CJK UNIFIED IDEOGRAPH
+0xBC44	0x528A	#CJK UNIFIED IDEOGRAPH
+0xBC45	0x52F0	#CJK UNIFIED IDEOGRAPH
+0xBC46	0x53B2	#CJK UNIFIED IDEOGRAPH
+0xBC47	0x562E	#CJK UNIFIED IDEOGRAPH
+0xBC48	0x563B	#CJK UNIFIED IDEOGRAPH
+0xBC49	0x5639	#CJK UNIFIED IDEOGRAPH
+0xBC4A	0x5632	#CJK UNIFIED IDEOGRAPH
+0xBC4B	0x563F	#CJK UNIFIED IDEOGRAPH
+0xBC4C	0x5634	#CJK UNIFIED IDEOGRAPH
+0xBC4D	0x5629	#CJK UNIFIED IDEOGRAPH
+0xBC4E	0x5653	#CJK UNIFIED IDEOGRAPH
+0xBC4F	0x564E	#CJK UNIFIED IDEOGRAPH
+0xBC50	0x5657	#CJK UNIFIED IDEOGRAPH
+0xBC51	0x5674	#CJK UNIFIED IDEOGRAPH
+0xBC52	0x5636	#CJK UNIFIED IDEOGRAPH
+0xBC53	0x562F	#CJK UNIFIED IDEOGRAPH
+0xBC54	0x5630	#CJK UNIFIED IDEOGRAPH
+0xBC55	0x5880	#CJK UNIFIED IDEOGRAPH
+0xBC56	0x589F	#CJK UNIFIED IDEOGRAPH
+0xBC57	0x589E	#CJK UNIFIED IDEOGRAPH
+0xBC58	0x58B3	#CJK UNIFIED IDEOGRAPH
+0xBC59	0x589C	#CJK UNIFIED IDEOGRAPH
+0xBC5A	0x58AE	#CJK UNIFIED IDEOGRAPH
+0xBC5B	0x58A9	#CJK UNIFIED IDEOGRAPH
+0xBC5C	0x58A6	#CJK UNIFIED IDEOGRAPH
+0xBC5D	0x596D	#CJK UNIFIED IDEOGRAPH
+0xBC5E	0x5B09	#CJK UNIFIED IDEOGRAPH
+0xBC5F	0x5AFB	#CJK UNIFIED IDEOGRAPH
+0xBC60	0x5B0B	#CJK UNIFIED IDEOGRAPH
+0xBC61	0x5AF5	#CJK UNIFIED IDEOGRAPH
+0xBC62	0x5B0C	#CJK UNIFIED IDEOGRAPH
+0xBC63	0x5B08	#CJK UNIFIED IDEOGRAPH
+0xBC64	0x5BEE	#CJK UNIFIED IDEOGRAPH
+0xBC65	0x5BEC	#CJK UNIFIED IDEOGRAPH
+0xBC66	0x5BE9	#CJK UNIFIED IDEOGRAPH
+0xBC67	0x5BEB	#CJK UNIFIED IDEOGRAPH
+0xBC68	0x5C64	#CJK UNIFIED IDEOGRAPH
+0xBC69	0x5C65	#CJK UNIFIED IDEOGRAPH
+0xBC6A	0x5D9D	#CJK UNIFIED IDEOGRAPH
+0xBC6B	0x5D94	#CJK UNIFIED IDEOGRAPH
+0xBC6C	0x5E62	#CJK UNIFIED IDEOGRAPH
+0xBC6D	0x5E5F	#CJK UNIFIED IDEOGRAPH
+0xBC6E	0x5E61	#CJK UNIFIED IDEOGRAPH
+0xBC6F	0x5EE2	#CJK UNIFIED IDEOGRAPH
+0xBC70	0x5EDA	#CJK UNIFIED IDEOGRAPH
+0xBC71	0x5EDF	#CJK UNIFIED IDEOGRAPH
+0xBC72	0x5EDD	#CJK UNIFIED IDEOGRAPH
+0xBC73	0x5EE3	#CJK UNIFIED IDEOGRAPH
+0xBC74	0x5EE0	#CJK UNIFIED IDEOGRAPH
+0xBC75	0x5F48	#CJK UNIFIED IDEOGRAPH
+0xBC76	0x5F71	#CJK UNIFIED IDEOGRAPH
+0xBC77	0x5FB7	#CJK UNIFIED IDEOGRAPH
+0xBC78	0x5FB5	#CJK UNIFIED IDEOGRAPH
+0xBC79	0x6176	#CJK UNIFIED IDEOGRAPH
+0xBC7A	0x6167	#CJK UNIFIED IDEOGRAPH
+0xBC7B	0x616E	#CJK UNIFIED IDEOGRAPH
+0xBC7C	0x615D	#CJK UNIFIED IDEOGRAPH
+0xBC7D	0x6155	#CJK UNIFIED IDEOGRAPH
+0xBC7E	0x6182	#CJK UNIFIED IDEOGRAPH
+0xBCA1	0x617C	#CJK UNIFIED IDEOGRAPH
+0xBCA2	0x6170	#CJK UNIFIED IDEOGRAPH
+0xBCA3	0x616B	#CJK UNIFIED IDEOGRAPH
+0xBCA4	0x617E	#CJK UNIFIED IDEOGRAPH
+0xBCA5	0x61A7	#CJK UNIFIED IDEOGRAPH
+0xBCA6	0x6190	#CJK UNIFIED IDEOGRAPH
+0xBCA7	0x61AB	#CJK UNIFIED IDEOGRAPH
+0xBCA8	0x618E	#CJK UNIFIED IDEOGRAPH
+0xBCA9	0x61AC	#CJK UNIFIED IDEOGRAPH
+0xBCAA	0x619A	#CJK UNIFIED IDEOGRAPH
+0xBCAB	0x61A4	#CJK UNIFIED IDEOGRAPH
+0xBCAC	0x6194	#CJK UNIFIED IDEOGRAPH
+0xBCAD	0x61AE	#CJK UNIFIED IDEOGRAPH
+0xBCAE	0x622E	#CJK UNIFIED IDEOGRAPH
+0xBCAF	0x6469	#CJK UNIFIED IDEOGRAPH
+0xBCB0	0x646F	#CJK UNIFIED IDEOGRAPH
+0xBCB1	0x6479	#CJK UNIFIED IDEOGRAPH
+0xBCB2	0x649E	#CJK UNIFIED IDEOGRAPH
+0xBCB3	0x64B2	#CJK UNIFIED IDEOGRAPH
+0xBCB4	0x6488	#CJK UNIFIED IDEOGRAPH
+0xBCB5	0x6490	#CJK UNIFIED IDEOGRAPH
+0xBCB6	0x64B0	#CJK UNIFIED IDEOGRAPH
+0xBCB7	0x64A5	#CJK UNIFIED IDEOGRAPH
+0xBCB8	0x6493	#CJK UNIFIED IDEOGRAPH
+0xBCB9	0x6495	#CJK UNIFIED IDEOGRAPH
+0xBCBA	0x64A9	#CJK UNIFIED IDEOGRAPH
+0xBCBB	0x6492	#CJK UNIFIED IDEOGRAPH
+0xBCBC	0x64AE	#CJK UNIFIED IDEOGRAPH
+0xBCBD	0x64AD	#CJK UNIFIED IDEOGRAPH
+0xBCBE	0x64AB	#CJK UNIFIED IDEOGRAPH
+0xBCBF	0x649A	#CJK UNIFIED IDEOGRAPH
+0xBCC0	0x64AC	#CJK UNIFIED IDEOGRAPH
+0xBCC1	0x6499	#CJK UNIFIED IDEOGRAPH
+0xBCC2	0x64A2	#CJK UNIFIED IDEOGRAPH
+0xBCC3	0x64B3	#CJK UNIFIED IDEOGRAPH
+0xBCC4	0x6575	#CJK UNIFIED IDEOGRAPH
+0xBCC5	0x6577	#CJK UNIFIED IDEOGRAPH
+0xBCC6	0x6578	#CJK UNIFIED IDEOGRAPH
+0xBCC7	0x66AE	#CJK UNIFIED IDEOGRAPH
+0xBCC8	0x66AB	#CJK UNIFIED IDEOGRAPH
+0xBCC9	0x66B4	#CJK UNIFIED IDEOGRAPH
+0xBCCA	0x66B1	#CJK UNIFIED IDEOGRAPH
+0xBCCB	0x6A23	#CJK UNIFIED IDEOGRAPH
+0xBCCC	0x6A1F	#CJK UNIFIED IDEOGRAPH
+0xBCCD	0x69E8	#CJK UNIFIED IDEOGRAPH
+0xBCCE	0x6A01	#CJK UNIFIED IDEOGRAPH
+0xBCCF	0x6A1E	#CJK UNIFIED IDEOGRAPH
+0xBCD0	0x6A19	#CJK UNIFIED IDEOGRAPH
+0xBCD1	0x69FD	#CJK UNIFIED IDEOGRAPH
+0xBCD2	0x6A21	#CJK UNIFIED IDEOGRAPH
+0xBCD3	0x6A13	#CJK UNIFIED IDEOGRAPH
+0xBCD4	0x6A0A	#CJK UNIFIED IDEOGRAPH
+0xBCD5	0x69F3	#CJK UNIFIED IDEOGRAPH
+0xBCD6	0x6A02	#CJK UNIFIED IDEOGRAPH
+0xBCD7	0x6A05	#CJK UNIFIED IDEOGRAPH
+0xBCD8	0x69ED	#CJK UNIFIED IDEOGRAPH
+0xBCD9	0x6A11	#CJK UNIFIED IDEOGRAPH
+0xBCDA	0x6B50	#CJK UNIFIED IDEOGRAPH
+0xBCDB	0x6B4E	#CJK UNIFIED IDEOGRAPH
+0xBCDC	0x6BA4	#CJK UNIFIED IDEOGRAPH
+0xBCDD	0x6BC5	#CJK UNIFIED IDEOGRAPH
+0xBCDE	0x6BC6	#CJK UNIFIED IDEOGRAPH
+0xBCDF	0x6F3F	#CJK UNIFIED IDEOGRAPH
+0xBCE0	0x6F7C	#CJK UNIFIED IDEOGRAPH
+0xBCE1	0x6F84	#CJK UNIFIED IDEOGRAPH
+0xBCE2	0x6F51	#CJK UNIFIED IDEOGRAPH
+0xBCE3	0x6F66	#CJK UNIFIED IDEOGRAPH
+0xBCE4	0x6F54	#CJK UNIFIED IDEOGRAPH
+0xBCE5	0x6F86	#CJK UNIFIED IDEOGRAPH
+0xBCE6	0x6F6D	#CJK UNIFIED IDEOGRAPH
+0xBCE7	0x6F5B	#CJK UNIFIED IDEOGRAPH
+0xBCE8	0x6F78	#CJK UNIFIED IDEOGRAPH
+0xBCE9	0x6F6E	#CJK UNIFIED IDEOGRAPH
+0xBCEA	0x6F8E	#CJK UNIFIED IDEOGRAPH
+0xBCEB	0x6F7A	#CJK UNIFIED IDEOGRAPH
+0xBCEC	0x6F70	#CJK UNIFIED IDEOGRAPH
+0xBCED	0x6F64	#CJK UNIFIED IDEOGRAPH
+0xBCEE	0x6F97	#CJK UNIFIED IDEOGRAPH
+0xBCEF	0x6F58	#CJK UNIFIED IDEOGRAPH
+0xBCF0	0x6ED5	#CJK UNIFIED IDEOGRAPH
+0xBCF1	0x6F6F	#CJK UNIFIED IDEOGRAPH
+0xBCF2	0x6F60	#CJK UNIFIED IDEOGRAPH
+0xBCF3	0x6F5F	#CJK UNIFIED IDEOGRAPH
+0xBCF4	0x719F	#CJK UNIFIED IDEOGRAPH
+0xBCF5	0x71AC	#CJK UNIFIED IDEOGRAPH
+0xBCF6	0x71B1	#CJK UNIFIED IDEOGRAPH
+0xBCF7	0x71A8	#CJK UNIFIED IDEOGRAPH
+0xBCF8	0x7256	#CJK UNIFIED IDEOGRAPH
+0xBCF9	0x729B	#CJK UNIFIED IDEOGRAPH
+0xBCFA	0x734E	#CJK UNIFIED IDEOGRAPH
+0xBCFB	0x7357	#CJK UNIFIED IDEOGRAPH
+0xBCFC	0x7469	#CJK UNIFIED IDEOGRAPH
+0xBCFD	0x748B	#CJK UNIFIED IDEOGRAPH
+0xBCFE	0x7483	#CJK UNIFIED IDEOGRAPH
+0xBD40	0x747E	#CJK UNIFIED IDEOGRAPH
+0xBD41	0x7480	#CJK UNIFIED IDEOGRAPH
+0xBD42	0x757F	#CJK UNIFIED IDEOGRAPH
+0xBD43	0x7620	#CJK UNIFIED IDEOGRAPH
+0xBD44	0x7629	#CJK UNIFIED IDEOGRAPH
+0xBD45	0x761F	#CJK UNIFIED IDEOGRAPH
+0xBD46	0x7624	#CJK UNIFIED IDEOGRAPH
+0xBD47	0x7626	#CJK UNIFIED IDEOGRAPH
+0xBD48	0x7621	#CJK UNIFIED IDEOGRAPH
+0xBD49	0x7622	#CJK UNIFIED IDEOGRAPH
+0xBD4A	0x769A	#CJK UNIFIED IDEOGRAPH
+0xBD4B	0x76BA	#CJK UNIFIED IDEOGRAPH
+0xBD4C	0x76E4	#CJK UNIFIED IDEOGRAPH
+0xBD4D	0x778E	#CJK UNIFIED IDEOGRAPH
+0xBD4E	0x7787	#CJK UNIFIED IDEOGRAPH
+0xBD4F	0x778C	#CJK UNIFIED IDEOGRAPH
+0xBD50	0x7791	#CJK UNIFIED IDEOGRAPH
+0xBD51	0x778B	#CJK UNIFIED IDEOGRAPH
+0xBD52	0x78CB	#CJK UNIFIED IDEOGRAPH
+0xBD53	0x78C5	#CJK UNIFIED IDEOGRAPH
+0xBD54	0x78BA	#CJK UNIFIED IDEOGRAPH
+0xBD55	0x78CA	#CJK UNIFIED IDEOGRAPH
+0xBD56	0x78BE	#CJK UNIFIED IDEOGRAPH
+0xBD57	0x78D5	#CJK UNIFIED IDEOGRAPH
+0xBD58	0x78BC	#CJK UNIFIED IDEOGRAPH
+0xBD59	0x78D0	#CJK UNIFIED IDEOGRAPH
+0xBD5A	0x7A3F	#CJK UNIFIED IDEOGRAPH
+0xBD5B	0x7A3C	#CJK UNIFIED IDEOGRAPH
+0xBD5C	0x7A40	#CJK UNIFIED IDEOGRAPH
+0xBD5D	0x7A3D	#CJK UNIFIED IDEOGRAPH
+0xBD5E	0x7A37	#CJK UNIFIED IDEOGRAPH
+0xBD5F	0x7A3B	#CJK UNIFIED IDEOGRAPH
+0xBD60	0x7AAF	#CJK UNIFIED IDEOGRAPH
+0xBD61	0x7AAE	#CJK UNIFIED IDEOGRAPH
+0xBD62	0x7BAD	#CJK UNIFIED IDEOGRAPH
+0xBD63	0x7BB1	#CJK UNIFIED IDEOGRAPH
+0xBD64	0x7BC4	#CJK UNIFIED IDEOGRAPH
+0xBD65	0x7BB4	#CJK UNIFIED IDEOGRAPH
+0xBD66	0x7BC6	#CJK UNIFIED IDEOGRAPH
+0xBD67	0x7BC7	#CJK UNIFIED IDEOGRAPH
+0xBD68	0x7BC1	#CJK UNIFIED IDEOGRAPH
+0xBD69	0x7BA0	#CJK UNIFIED IDEOGRAPH
+0xBD6A	0x7BCC	#CJK UNIFIED IDEOGRAPH
+0xBD6B	0x7CCA	#CJK UNIFIED IDEOGRAPH
+0xBD6C	0x7DE0	#CJK UNIFIED IDEOGRAPH
+0xBD6D	0x7DF4	#CJK UNIFIED IDEOGRAPH
+0xBD6E	0x7DEF	#CJK UNIFIED IDEOGRAPH
+0xBD6F	0x7DFB	#CJK UNIFIED IDEOGRAPH
+0xBD70	0x7DD8	#CJK UNIFIED IDEOGRAPH
+0xBD71	0x7DEC	#CJK UNIFIED IDEOGRAPH
+0xBD72	0x7DDD	#CJK UNIFIED IDEOGRAPH
+0xBD73	0x7DE8	#CJK UNIFIED IDEOGRAPH
+0xBD74	0x7DE3	#CJK UNIFIED IDEOGRAPH
+0xBD75	0x7DDA	#CJK UNIFIED IDEOGRAPH
+0xBD76	0x7DDE	#CJK UNIFIED IDEOGRAPH
+0xBD77	0x7DE9	#CJK UNIFIED IDEOGRAPH
+0xBD78	0x7D9E	#CJK UNIFIED IDEOGRAPH
+0xBD79	0x7DD9	#CJK UNIFIED IDEOGRAPH
+0xBD7A	0x7DF2	#CJK UNIFIED IDEOGRAPH
+0xBD7B	0x7DF9	#CJK UNIFIED IDEOGRAPH
+0xBD7C	0x7F75	#CJK UNIFIED IDEOGRAPH
+0xBD7D	0x7F77	#CJK UNIFIED IDEOGRAPH
+0xBD7E	0x7FAF	#CJK UNIFIED IDEOGRAPH
+0xBDA1	0x7FE9	#CJK UNIFIED IDEOGRAPH
+0xBDA2	0x8026	#CJK UNIFIED IDEOGRAPH
+0xBDA3	0x819B	#CJK UNIFIED IDEOGRAPH
+0xBDA4	0x819C	#CJK UNIFIED IDEOGRAPH
+0xBDA5	0x819D	#CJK UNIFIED IDEOGRAPH
+0xBDA6	0x81A0	#CJK UNIFIED IDEOGRAPH
+0xBDA7	0x819A	#CJK UNIFIED IDEOGRAPH
+0xBDA8	0x8198	#CJK UNIFIED IDEOGRAPH
+0xBDA9	0x8517	#CJK UNIFIED IDEOGRAPH
+0xBDAA	0x853D	#CJK UNIFIED IDEOGRAPH
+0xBDAB	0x851A	#CJK UNIFIED IDEOGRAPH
+0xBDAC	0x84EE	#CJK UNIFIED IDEOGRAPH
+0xBDAD	0x852C	#CJK UNIFIED IDEOGRAPH
+0xBDAE	0x852D	#CJK UNIFIED IDEOGRAPH
+0xBDAF	0x8513	#CJK UNIFIED IDEOGRAPH
+0xBDB0	0x8511	#CJK UNIFIED IDEOGRAPH
+0xBDB1	0x8523	#CJK UNIFIED IDEOGRAPH
+0xBDB2	0x8521	#CJK UNIFIED IDEOGRAPH
+0xBDB3	0x8514	#CJK UNIFIED IDEOGRAPH
+0xBDB4	0x84EC	#CJK UNIFIED IDEOGRAPH
+0xBDB5	0x8525	#CJK UNIFIED IDEOGRAPH
+0xBDB6	0x84FF	#CJK UNIFIED IDEOGRAPH
+0xBDB7	0x8506	#CJK UNIFIED IDEOGRAPH
+0xBDB8	0x8782	#CJK UNIFIED IDEOGRAPH
+0xBDB9	0x8774	#CJK UNIFIED IDEOGRAPH
+0xBDBA	0x8776	#CJK UNIFIED IDEOGRAPH
+0xBDBB	0x8760	#CJK UNIFIED IDEOGRAPH
+0xBDBC	0x8766	#CJK UNIFIED IDEOGRAPH
+0xBDBD	0x8778	#CJK UNIFIED IDEOGRAPH
+0xBDBE	0x8768	#CJK UNIFIED IDEOGRAPH
+0xBDBF	0x8759	#CJK UNIFIED IDEOGRAPH
+0xBDC0	0x8757	#CJK UNIFIED IDEOGRAPH
+0xBDC1	0x874C	#CJK UNIFIED IDEOGRAPH
+0xBDC2	0x8753	#CJK UNIFIED IDEOGRAPH
+0xBDC3	0x885B	#CJK UNIFIED IDEOGRAPH
+0xBDC4	0x885D	#CJK UNIFIED IDEOGRAPH
+0xBDC5	0x8910	#CJK UNIFIED IDEOGRAPH
+0xBDC6	0x8907	#CJK UNIFIED IDEOGRAPH
+0xBDC7	0x8912	#CJK UNIFIED IDEOGRAPH
+0xBDC8	0x8913	#CJK UNIFIED IDEOGRAPH
+0xBDC9	0x8915	#CJK UNIFIED IDEOGRAPH
+0xBDCA	0x890A	#CJK UNIFIED IDEOGRAPH
+0xBDCB	0x8ABC	#CJK UNIFIED IDEOGRAPH
+0xBDCC	0x8AD2	#CJK UNIFIED IDEOGRAPH
+0xBDCD	0x8AC7	#CJK UNIFIED IDEOGRAPH
+0xBDCE	0x8AC4	#CJK UNIFIED IDEOGRAPH
+0xBDCF	0x8A95	#CJK UNIFIED IDEOGRAPH
+0xBDD0	0x8ACB	#CJK UNIFIED IDEOGRAPH
+0xBDD1	0x8AF8	#CJK UNIFIED IDEOGRAPH
+0xBDD2	0x8AB2	#CJK UNIFIED IDEOGRAPH
+0xBDD3	0x8AC9	#CJK UNIFIED IDEOGRAPH
+0xBDD4	0x8AC2	#CJK UNIFIED IDEOGRAPH
+0xBDD5	0x8ABF	#CJK UNIFIED IDEOGRAPH
+0xBDD6	0x8AB0	#CJK UNIFIED IDEOGRAPH
+0xBDD7	0x8AD6	#CJK UNIFIED IDEOGRAPH
+0xBDD8	0x8ACD	#CJK UNIFIED IDEOGRAPH
+0xBDD9	0x8AB6	#CJK UNIFIED IDEOGRAPH
+0xBDDA	0x8AB9	#CJK UNIFIED IDEOGRAPH
+0xBDDB	0x8ADB	#CJK UNIFIED IDEOGRAPH
+0xBDDC	0x8C4C	#CJK UNIFIED IDEOGRAPH
+0xBDDD	0x8C4E	#CJK UNIFIED IDEOGRAPH
+0xBDDE	0x8C6C	#CJK UNIFIED IDEOGRAPH
+0xBDDF	0x8CE0	#CJK UNIFIED IDEOGRAPH
+0xBDE0	0x8CDE	#CJK UNIFIED IDEOGRAPH
+0xBDE1	0x8CE6	#CJK UNIFIED IDEOGRAPH
+0xBDE2	0x8CE4	#CJK UNIFIED IDEOGRAPH
+0xBDE3	0x8CEC	#CJK UNIFIED IDEOGRAPH
+0xBDE4	0x8CED	#CJK UNIFIED IDEOGRAPH
+0xBDE5	0x8CE2	#CJK UNIFIED IDEOGRAPH
+0xBDE6	0x8CE3	#CJK UNIFIED IDEOGRAPH
+0xBDE7	0x8CDC	#CJK UNIFIED IDEOGRAPH
+0xBDE8	0x8CEA	#CJK UNIFIED IDEOGRAPH
+0xBDE9	0x8CE1	#CJK UNIFIED IDEOGRAPH
+0xBDEA	0x8D6D	#CJK UNIFIED IDEOGRAPH
+0xBDEB	0x8D9F	#CJK UNIFIED IDEOGRAPH
+0xBDEC	0x8DA3	#CJK UNIFIED IDEOGRAPH
+0xBDED	0x8E2B	#CJK UNIFIED IDEOGRAPH
+0xBDEE	0x8E10	#CJK UNIFIED IDEOGRAPH
+0xBDEF	0x8E1D	#CJK UNIFIED IDEOGRAPH
+0xBDF0	0x8E22	#CJK UNIFIED IDEOGRAPH
+0xBDF1	0x8E0F	#CJK UNIFIED IDEOGRAPH
+0xBDF2	0x8E29	#CJK UNIFIED IDEOGRAPH
+0xBDF3	0x8E1F	#CJK UNIFIED IDEOGRAPH
+0xBDF4	0x8E21	#CJK UNIFIED IDEOGRAPH
+0xBDF5	0x8E1E	#CJK UNIFIED IDEOGRAPH
+0xBDF6	0x8EBA	#CJK UNIFIED IDEOGRAPH
+0xBDF7	0x8F1D	#CJK UNIFIED IDEOGRAPH
+0xBDF8	0x8F1B	#CJK UNIFIED IDEOGRAPH
+0xBDF9	0x8F1F	#CJK UNIFIED IDEOGRAPH
+0xBDFA	0x8F29	#CJK UNIFIED IDEOGRAPH
+0xBDFB	0x8F26	#CJK UNIFIED IDEOGRAPH
+0xBDFC	0x8F2A	#CJK UNIFIED IDEOGRAPH
+0xBDFD	0x8F1C	#CJK UNIFIED IDEOGRAPH
+0xBDFE	0x8F1E	#CJK UNIFIED IDEOGRAPH
+0xBE40	0x8F25	#CJK UNIFIED IDEOGRAPH
+0xBE41	0x9069	#CJK UNIFIED IDEOGRAPH
+0xBE42	0x906E	#CJK UNIFIED IDEOGRAPH
+0xBE43	0x9068	#CJK UNIFIED IDEOGRAPH
+0xBE44	0x906D	#CJK UNIFIED IDEOGRAPH
+0xBE45	0x9077	#CJK UNIFIED IDEOGRAPH
+0xBE46	0x9130	#CJK UNIFIED IDEOGRAPH
+0xBE47	0x912D	#CJK UNIFIED IDEOGRAPH
+0xBE48	0x9127	#CJK UNIFIED IDEOGRAPH
+0xBE49	0x9131	#CJK UNIFIED IDEOGRAPH
+0xBE4A	0x9187	#CJK UNIFIED IDEOGRAPH
+0xBE4B	0x9189	#CJK UNIFIED IDEOGRAPH
+0xBE4C	0x918B	#CJK UNIFIED IDEOGRAPH
+0xBE4D	0x9183	#CJK UNIFIED IDEOGRAPH
+0xBE4E	0x92C5	#CJK UNIFIED IDEOGRAPH
+0xBE4F	0x92BB	#CJK UNIFIED IDEOGRAPH
+0xBE50	0x92B7	#CJK UNIFIED IDEOGRAPH
+0xBE51	0x92EA	#CJK UNIFIED IDEOGRAPH
+0xBE52	0x92AC	#CJK UNIFIED IDEOGRAPH
+0xBE53	0x92E4	#CJK UNIFIED IDEOGRAPH
+0xBE54	0x92C1	#CJK UNIFIED IDEOGRAPH
+0xBE55	0x92B3	#CJK UNIFIED IDEOGRAPH
+0xBE56	0x92BC	#CJK UNIFIED IDEOGRAPH
+0xBE57	0x92D2	#CJK UNIFIED IDEOGRAPH
+0xBE58	0x92C7	#CJK UNIFIED IDEOGRAPH
+0xBE59	0x92F0	#CJK UNIFIED IDEOGRAPH
+0xBE5A	0x92B2	#CJK UNIFIED IDEOGRAPH
+0xBE5B	0x95AD	#CJK UNIFIED IDEOGRAPH
+0xBE5C	0x95B1	#CJK UNIFIED IDEOGRAPH
+0xBE5D	0x9704	#CJK UNIFIED IDEOGRAPH
+0xBE5E	0x9706	#CJK UNIFIED IDEOGRAPH
+0xBE5F	0x9707	#CJK UNIFIED IDEOGRAPH
+0xBE60	0x9709	#CJK UNIFIED IDEOGRAPH
+0xBE61	0x9760	#CJK UNIFIED IDEOGRAPH
+0xBE62	0x978D	#CJK UNIFIED IDEOGRAPH
+0xBE63	0x978B	#CJK UNIFIED IDEOGRAPH
+0xBE64	0x978F	#CJK UNIFIED IDEOGRAPH
+0xBE65	0x9821	#CJK UNIFIED IDEOGRAPH
+0xBE66	0x982B	#CJK UNIFIED IDEOGRAPH
+0xBE67	0x981C	#CJK UNIFIED IDEOGRAPH
+0xBE68	0x98B3	#CJK UNIFIED IDEOGRAPH
+0xBE69	0x990A	#CJK UNIFIED IDEOGRAPH
+0xBE6A	0x9913	#CJK UNIFIED IDEOGRAPH
+0xBE6B	0x9912	#CJK UNIFIED IDEOGRAPH
+0xBE6C	0x9918	#CJK UNIFIED IDEOGRAPH
+0xBE6D	0x99DD	#CJK UNIFIED IDEOGRAPH
+0xBE6E	0x99D0	#CJK UNIFIED IDEOGRAPH
+0xBE6F	0x99DF	#CJK UNIFIED IDEOGRAPH
+0xBE70	0x99DB	#CJK UNIFIED IDEOGRAPH
+0xBE71	0x99D1	#CJK UNIFIED IDEOGRAPH
+0xBE72	0x99D5	#CJK UNIFIED IDEOGRAPH
+0xBE73	0x99D2	#CJK UNIFIED IDEOGRAPH
+0xBE74	0x99D9	#CJK UNIFIED IDEOGRAPH
+0xBE75	0x9AB7	#CJK UNIFIED IDEOGRAPH
+0xBE76	0x9AEE	#CJK UNIFIED IDEOGRAPH
+0xBE77	0x9AEF	#CJK UNIFIED IDEOGRAPH
+0xBE78	0x9B27	#CJK UNIFIED IDEOGRAPH
+0xBE79	0x9B45	#CJK UNIFIED IDEOGRAPH
+0xBE7A	0x9B44	#CJK UNIFIED IDEOGRAPH
+0xBE7B	0x9B77	#CJK UNIFIED IDEOGRAPH
+0xBE7C	0x9B6F	#CJK UNIFIED IDEOGRAPH
+0xBE7D	0x9D06	#CJK UNIFIED IDEOGRAPH
+0xBE7E	0x9D09	#CJK UNIFIED IDEOGRAPH
+0xBEA1	0x9D03	#CJK UNIFIED IDEOGRAPH
+0xBEA2	0x9EA9	#CJK UNIFIED IDEOGRAPH
+0xBEA3	0x9EBE	#CJK UNIFIED IDEOGRAPH
+0xBEA4	0x9ECE	#CJK UNIFIED IDEOGRAPH
+0xBEA5	0x58A8	#CJK UNIFIED IDEOGRAPH
+0xBEA6	0x9F52	#CJK UNIFIED IDEOGRAPH
+0xBEA7	0x5112	#CJK UNIFIED IDEOGRAPH
+0xBEA8	0x5118	#CJK UNIFIED IDEOGRAPH
+0xBEA9	0x5114	#CJK UNIFIED IDEOGRAPH
+0xBEAA	0x5110	#CJK UNIFIED IDEOGRAPH
+0xBEAB	0x5115	#CJK UNIFIED IDEOGRAPH
+0xBEAC	0x5180	#CJK UNIFIED IDEOGRAPH
+0xBEAD	0x51AA	#CJK UNIFIED IDEOGRAPH
+0xBEAE	0x51DD	#CJK UNIFIED IDEOGRAPH
+0xBEAF	0x5291	#CJK UNIFIED IDEOGRAPH
+0xBEB0	0x5293	#CJK UNIFIED IDEOGRAPH
+0xBEB1	0x52F3	#CJK UNIFIED IDEOGRAPH
+0xBEB2	0x5659	#CJK UNIFIED IDEOGRAPH
+0xBEB3	0x566B	#CJK UNIFIED IDEOGRAPH
+0xBEB4	0x5679	#CJK UNIFIED IDEOGRAPH
+0xBEB5	0x5669	#CJK UNIFIED IDEOGRAPH
+0xBEB6	0x5664	#CJK UNIFIED IDEOGRAPH
+0xBEB7	0x5678	#CJK UNIFIED IDEOGRAPH
+0xBEB8	0x566A	#CJK UNIFIED IDEOGRAPH
+0xBEB9	0x5668	#CJK UNIFIED IDEOGRAPH
+0xBEBA	0x5665	#CJK UNIFIED IDEOGRAPH
+0xBEBB	0x5671	#CJK UNIFIED IDEOGRAPH
+0xBEBC	0x566F	#CJK UNIFIED IDEOGRAPH
+0xBEBD	0x566C	#CJK UNIFIED IDEOGRAPH
+0xBEBE	0x5662	#CJK UNIFIED IDEOGRAPH
+0xBEBF	0x5676	#CJK UNIFIED IDEOGRAPH
+0xBEC0	0x58C1	#CJK UNIFIED IDEOGRAPH
+0xBEC1	0x58BE	#CJK UNIFIED IDEOGRAPH
+0xBEC2	0x58C7	#CJK UNIFIED IDEOGRAPH
+0xBEC3	0x58C5	#CJK UNIFIED IDEOGRAPH
+0xBEC4	0x596E	#CJK UNIFIED IDEOGRAPH
+0xBEC5	0x5B1D	#CJK UNIFIED IDEOGRAPH
+0xBEC6	0x5B34	#CJK UNIFIED IDEOGRAPH
+0xBEC7	0x5B78	#CJK UNIFIED IDEOGRAPH
+0xBEC8	0x5BF0	#CJK UNIFIED IDEOGRAPH
+0xBEC9	0x5C0E	#CJK UNIFIED IDEOGRAPH
+0xBECA	0x5F4A	#CJK UNIFIED IDEOGRAPH
+0xBECB	0x61B2	#CJK UNIFIED IDEOGRAPH
+0xBECC	0x6191	#CJK UNIFIED IDEOGRAPH
+0xBECD	0x61A9	#CJK UNIFIED IDEOGRAPH
+0xBECE	0x618A	#CJK UNIFIED IDEOGRAPH
+0xBECF	0x61CD	#CJK UNIFIED IDEOGRAPH
+0xBED0	0x61B6	#CJK UNIFIED IDEOGRAPH
+0xBED1	0x61BE	#CJK UNIFIED IDEOGRAPH
+0xBED2	0x61CA	#CJK UNIFIED IDEOGRAPH
+0xBED3	0x61C8	#CJK UNIFIED IDEOGRAPH
+0xBED4	0x6230	#CJK UNIFIED IDEOGRAPH
+0xBED5	0x64C5	#CJK UNIFIED IDEOGRAPH
+0xBED6	0x64C1	#CJK UNIFIED IDEOGRAPH
+0xBED7	0x64CB	#CJK UNIFIED IDEOGRAPH
+0xBED8	0x64BB	#CJK UNIFIED IDEOGRAPH
+0xBED9	0x64BC	#CJK UNIFIED IDEOGRAPH
+0xBEDA	0x64DA	#CJK UNIFIED IDEOGRAPH
+0xBEDB	0x64C4	#CJK UNIFIED IDEOGRAPH
+0xBEDC	0x64C7	#CJK UNIFIED IDEOGRAPH
+0xBEDD	0x64C2	#CJK UNIFIED IDEOGRAPH
+0xBEDE	0x64CD	#CJK UNIFIED IDEOGRAPH
+0xBEDF	0x64BF	#CJK UNIFIED IDEOGRAPH
+0xBEE0	0x64D2	#CJK UNIFIED IDEOGRAPH
+0xBEE1	0x64D4	#CJK UNIFIED IDEOGRAPH
+0xBEE2	0x64BE	#CJK UNIFIED IDEOGRAPH
+0xBEE3	0x6574	#CJK UNIFIED IDEOGRAPH
+0xBEE4	0x66C6	#CJK UNIFIED IDEOGRAPH
+0xBEE5	0x66C9	#CJK UNIFIED IDEOGRAPH
+0xBEE6	0x66B9	#CJK UNIFIED IDEOGRAPH
+0xBEE7	0x66C4	#CJK UNIFIED IDEOGRAPH
+0xBEE8	0x66C7	#CJK UNIFIED IDEOGRAPH
+0xBEE9	0x66B8	#CJK UNIFIED IDEOGRAPH
+0xBEEA	0x6A3D	#CJK UNIFIED IDEOGRAPH
+0xBEEB	0x6A38	#CJK UNIFIED IDEOGRAPH
+0xBEEC	0x6A3A	#CJK UNIFIED IDEOGRAPH
+0xBEED	0x6A59	#CJK UNIFIED IDEOGRAPH
+0xBEEE	0x6A6B	#CJK UNIFIED IDEOGRAPH
+0xBEEF	0x6A58	#CJK UNIFIED IDEOGRAPH
+0xBEF0	0x6A39	#CJK UNIFIED IDEOGRAPH
+0xBEF1	0x6A44	#CJK UNIFIED IDEOGRAPH
+0xBEF2	0x6A62	#CJK UNIFIED IDEOGRAPH
+0xBEF3	0x6A61	#CJK UNIFIED IDEOGRAPH
+0xBEF4	0x6A4B	#CJK UNIFIED IDEOGRAPH
+0xBEF5	0x6A47	#CJK UNIFIED IDEOGRAPH
+0xBEF6	0x6A35	#CJK UNIFIED IDEOGRAPH
+0xBEF7	0x6A5F	#CJK UNIFIED IDEOGRAPH
+0xBEF8	0x6A48	#CJK UNIFIED IDEOGRAPH
+0xBEF9	0x6B59	#CJK UNIFIED IDEOGRAPH
+0xBEFA	0x6B77	#CJK UNIFIED IDEOGRAPH
+0xBEFB	0x6C05	#CJK UNIFIED IDEOGRAPH
+0xBEFC	0x6FC2	#CJK UNIFIED IDEOGRAPH
+0xBEFD	0x6FB1	#CJK UNIFIED IDEOGRAPH
+0xBEFE	0x6FA1	#CJK UNIFIED IDEOGRAPH
+0xBF40	0x6FC3	#CJK UNIFIED IDEOGRAPH
+0xBF41	0x6FA4	#CJK UNIFIED IDEOGRAPH
+0xBF42	0x6FC1	#CJK UNIFIED IDEOGRAPH
+0xBF43	0x6FA7	#CJK UNIFIED IDEOGRAPH
+0xBF44	0x6FB3	#CJK UNIFIED IDEOGRAPH
+0xBF45	0x6FC0	#CJK UNIFIED IDEOGRAPH
+0xBF46	0x6FB9	#CJK UNIFIED IDEOGRAPH
+0xBF47	0x6FB6	#CJK UNIFIED IDEOGRAPH
+0xBF48	0x6FA6	#CJK UNIFIED IDEOGRAPH
+0xBF49	0x6FA0	#CJK UNIFIED IDEOGRAPH
+0xBF4A	0x6FB4	#CJK UNIFIED IDEOGRAPH
+0xBF4B	0x71BE	#CJK UNIFIED IDEOGRAPH
+0xBF4C	0x71C9	#CJK UNIFIED IDEOGRAPH
+0xBF4D	0x71D0	#CJK UNIFIED IDEOGRAPH
+0xBF4E	0x71D2	#CJK UNIFIED IDEOGRAPH
+0xBF4F	0x71C8	#CJK UNIFIED IDEOGRAPH
+0xBF50	0x71D5	#CJK UNIFIED IDEOGRAPH
+0xBF51	0x71B9	#CJK UNIFIED IDEOGRAPH
+0xBF52	0x71CE	#CJK UNIFIED IDEOGRAPH
+0xBF53	0x71D9	#CJK UNIFIED IDEOGRAPH
+0xBF54	0x71DC	#CJK UNIFIED IDEOGRAPH
+0xBF55	0x71C3	#CJK UNIFIED IDEOGRAPH
+0xBF56	0x71C4	#CJK UNIFIED IDEOGRAPH
+0xBF57	0x7368	#CJK UNIFIED IDEOGRAPH
+0xBF58	0x749C	#CJK UNIFIED IDEOGRAPH
+0xBF59	0x74A3	#CJK UNIFIED IDEOGRAPH
+0xBF5A	0x7498	#CJK UNIFIED IDEOGRAPH
+0xBF5B	0x749F	#CJK UNIFIED IDEOGRAPH
+0xBF5C	0x749E	#CJK UNIFIED IDEOGRAPH
+0xBF5D	0x74E2	#CJK UNIFIED IDEOGRAPH
+0xBF5E	0x750C	#CJK UNIFIED IDEOGRAPH
+0xBF5F	0x750D	#CJK UNIFIED IDEOGRAPH
+0xBF60	0x7634	#CJK UNIFIED IDEOGRAPH
+0xBF61	0x7638	#CJK UNIFIED IDEOGRAPH
+0xBF62	0x763A	#CJK UNIFIED IDEOGRAPH
+0xBF63	0x76E7	#CJK UNIFIED IDEOGRAPH
+0xBF64	0x76E5	#CJK UNIFIED IDEOGRAPH
+0xBF65	0x77A0	#CJK UNIFIED IDEOGRAPH
+0xBF66	0x779E	#CJK UNIFIED IDEOGRAPH
+0xBF67	0x779F	#CJK UNIFIED IDEOGRAPH
+0xBF68	0x77A5	#CJK UNIFIED IDEOGRAPH
+0xBF69	0x78E8	#CJK UNIFIED IDEOGRAPH
+0xBF6A	0x78DA	#CJK UNIFIED IDEOGRAPH
+0xBF6B	0x78EC	#CJK UNIFIED IDEOGRAPH
+0xBF6C	0x78E7	#CJK UNIFIED IDEOGRAPH
+0xBF6D	0x79A6	#CJK UNIFIED IDEOGRAPH
+0xBF6E	0x7A4D	#CJK UNIFIED IDEOGRAPH
+0xBF6F	0x7A4E	#CJK UNIFIED IDEOGRAPH
+0xBF70	0x7A46	#CJK UNIFIED IDEOGRAPH
+0xBF71	0x7A4C	#CJK UNIFIED IDEOGRAPH
+0xBF72	0x7A4B	#CJK UNIFIED IDEOGRAPH
+0xBF73	0x7ABA	#CJK UNIFIED IDEOGRAPH
+0xBF74	0x7BD9	#CJK UNIFIED IDEOGRAPH
+0xBF75	0x7C11	#CJK UNIFIED IDEOGRAPH
+0xBF76	0x7BC9	#CJK UNIFIED IDEOGRAPH
+0xBF77	0x7BE4	#CJK UNIFIED IDEOGRAPH
+0xBF78	0x7BDB	#CJK UNIFIED IDEOGRAPH
+0xBF79	0x7BE1	#CJK UNIFIED IDEOGRAPH
+0xBF7A	0x7BE9	#CJK UNIFIED IDEOGRAPH
+0xBF7B	0x7BE6	#CJK UNIFIED IDEOGRAPH
+0xBF7C	0x7CD5	#CJK UNIFIED IDEOGRAPH
+0xBF7D	0x7CD6	#CJK UNIFIED IDEOGRAPH
+0xBF7E	0x7E0A	#CJK UNIFIED IDEOGRAPH
+0xBFA1	0x7E11	#CJK UNIFIED IDEOGRAPH
+0xBFA2	0x7E08	#CJK UNIFIED IDEOGRAPH
+0xBFA3	0x7E1B	#CJK UNIFIED IDEOGRAPH
+0xBFA4	0x7E23	#CJK UNIFIED IDEOGRAPH
+0xBFA5	0x7E1E	#CJK UNIFIED IDEOGRAPH
+0xBFA6	0x7E1D	#CJK UNIFIED IDEOGRAPH
+0xBFA7	0x7E09	#CJK UNIFIED IDEOGRAPH
+0xBFA8	0x7E10	#CJK UNIFIED IDEOGRAPH
+0xBFA9	0x7F79	#CJK UNIFIED IDEOGRAPH
+0xBFAA	0x7FB2	#CJK UNIFIED IDEOGRAPH
+0xBFAB	0x7FF0	#CJK UNIFIED IDEOGRAPH
+0xBFAC	0x7FF1	#CJK UNIFIED IDEOGRAPH
+0xBFAD	0x7FEE	#CJK UNIFIED IDEOGRAPH
+0xBFAE	0x8028	#CJK UNIFIED IDEOGRAPH
+0xBFAF	0x81B3	#CJK UNIFIED IDEOGRAPH
+0xBFB0	0x81A9	#CJK UNIFIED IDEOGRAPH
+0xBFB1	0x81A8	#CJK UNIFIED IDEOGRAPH
+0xBFB2	0x81FB	#CJK UNIFIED IDEOGRAPH
+0xBFB3	0x8208	#CJK UNIFIED IDEOGRAPH
+0xBFB4	0x8258	#CJK UNIFIED IDEOGRAPH
+0xBFB5	0x8259	#CJK UNIFIED IDEOGRAPH
+0xBFB6	0x854A	#CJK UNIFIED IDEOGRAPH
+0xBFB7	0x8559	#CJK UNIFIED IDEOGRAPH
+0xBFB8	0x8548	#CJK UNIFIED IDEOGRAPH
+0xBFB9	0x8568	#CJK UNIFIED IDEOGRAPH
+0xBFBA	0x8569	#CJK UNIFIED IDEOGRAPH
+0xBFBB	0x8543	#CJK UNIFIED IDEOGRAPH
+0xBFBC	0x8549	#CJK UNIFIED IDEOGRAPH
+0xBFBD	0x856D	#CJK UNIFIED IDEOGRAPH
+0xBFBE	0x856A	#CJK UNIFIED IDEOGRAPH
+0xBFBF	0x855E	#CJK UNIFIED IDEOGRAPH
+0xBFC0	0x8783	#CJK UNIFIED IDEOGRAPH
+0xBFC1	0x879F	#CJK UNIFIED IDEOGRAPH
+0xBFC2	0x879E	#CJK UNIFIED IDEOGRAPH
+0xBFC3	0x87A2	#CJK UNIFIED IDEOGRAPH
+0xBFC4	0x878D	#CJK UNIFIED IDEOGRAPH
+0xBFC5	0x8861	#CJK UNIFIED IDEOGRAPH
+0xBFC6	0x892A	#CJK UNIFIED IDEOGRAPH
+0xBFC7	0x8932	#CJK UNIFIED IDEOGRAPH
+0xBFC8	0x8925	#CJK UNIFIED IDEOGRAPH
+0xBFC9	0x892B	#CJK UNIFIED IDEOGRAPH
+0xBFCA	0x8921	#CJK UNIFIED IDEOGRAPH
+0xBFCB	0x89AA	#CJK UNIFIED IDEOGRAPH
+0xBFCC	0x89A6	#CJK UNIFIED IDEOGRAPH
+0xBFCD	0x8AE6	#CJK UNIFIED IDEOGRAPH
+0xBFCE	0x8AFA	#CJK UNIFIED IDEOGRAPH
+0xBFCF	0x8AEB	#CJK UNIFIED IDEOGRAPH
+0xBFD0	0x8AF1	#CJK UNIFIED IDEOGRAPH
+0xBFD1	0x8B00	#CJK UNIFIED IDEOGRAPH
+0xBFD2	0x8ADC	#CJK UNIFIED IDEOGRAPH
+0xBFD3	0x8AE7	#CJK UNIFIED IDEOGRAPH
+0xBFD4	0x8AEE	#CJK UNIFIED IDEOGRAPH
+0xBFD5	0x8AFE	#CJK UNIFIED IDEOGRAPH
+0xBFD6	0x8B01	#CJK UNIFIED IDEOGRAPH
+0xBFD7	0x8B02	#CJK UNIFIED IDEOGRAPH
+0xBFD8	0x8AF7	#CJK UNIFIED IDEOGRAPH
+0xBFD9	0x8AED	#CJK UNIFIED IDEOGRAPH
+0xBFDA	0x8AF3	#CJK UNIFIED IDEOGRAPH
+0xBFDB	0x8AF6	#CJK UNIFIED IDEOGRAPH
+0xBFDC	0x8AFC	#CJK UNIFIED IDEOGRAPH
+0xBFDD	0x8C6B	#CJK UNIFIED IDEOGRAPH
+0xBFDE	0x8C6D	#CJK UNIFIED IDEOGRAPH
+0xBFDF	0x8C93	#CJK UNIFIED IDEOGRAPH
+0xBFE0	0x8CF4	#CJK UNIFIED IDEOGRAPH
+0xBFE1	0x8E44	#CJK UNIFIED IDEOGRAPH
+0xBFE2	0x8E31	#CJK UNIFIED IDEOGRAPH
+0xBFE3	0x8E34	#CJK UNIFIED IDEOGRAPH
+0xBFE4	0x8E42	#CJK UNIFIED IDEOGRAPH
+0xBFE5	0x8E39	#CJK UNIFIED IDEOGRAPH
+0xBFE6	0x8E35	#CJK UNIFIED IDEOGRAPH
+0xBFE7	0x8F3B	#CJK UNIFIED IDEOGRAPH
+0xBFE8	0x8F2F	#CJK UNIFIED IDEOGRAPH
+0xBFE9	0x8F38	#CJK UNIFIED IDEOGRAPH
+0xBFEA	0x8F33	#CJK UNIFIED IDEOGRAPH
+0xBFEB	0x8FA8	#CJK UNIFIED IDEOGRAPH
+0xBFEC	0x8FA6	#CJK UNIFIED IDEOGRAPH
+0xBFED	0x9075	#CJK UNIFIED IDEOGRAPH
+0xBFEE	0x9074	#CJK UNIFIED IDEOGRAPH
+0xBFEF	0x9078	#CJK UNIFIED IDEOGRAPH
+0xBFF0	0x9072	#CJK UNIFIED IDEOGRAPH
+0xBFF1	0x907C	#CJK UNIFIED IDEOGRAPH
+0xBFF2	0x907A	#CJK UNIFIED IDEOGRAPH
+0xBFF3	0x9134	#CJK UNIFIED IDEOGRAPH
+0xBFF4	0x9192	#CJK UNIFIED IDEOGRAPH
+0xBFF5	0x9320	#CJK UNIFIED IDEOGRAPH
+0xBFF6	0x9336	#CJK UNIFIED IDEOGRAPH
+0xBFF7	0x92F8	#CJK UNIFIED IDEOGRAPH
+0xBFF8	0x9333	#CJK UNIFIED IDEOGRAPH
+0xBFF9	0x932F	#CJK UNIFIED IDEOGRAPH
+0xBFFA	0x9322	#CJK UNIFIED IDEOGRAPH
+0xBFFB	0x92FC	#CJK UNIFIED IDEOGRAPH
+0xBFFC	0x932B	#CJK UNIFIED IDEOGRAPH
+0xBFFD	0x9304	#CJK UNIFIED IDEOGRAPH
+0xBFFE	0x931A	#CJK UNIFIED IDEOGRAPH
+0xC040	0x9310	#CJK UNIFIED IDEOGRAPH
+0xC041	0x9326	#CJK UNIFIED IDEOGRAPH
+0xC042	0x9321	#CJK UNIFIED IDEOGRAPH
+0xC043	0x9315	#CJK UNIFIED IDEOGRAPH
+0xC044	0x932E	#CJK UNIFIED IDEOGRAPH
+0xC045	0x9319	#CJK UNIFIED IDEOGRAPH
+0xC046	0x95BB	#CJK UNIFIED IDEOGRAPH
+0xC047	0x96A7	#CJK UNIFIED IDEOGRAPH
+0xC048	0x96A8	#CJK UNIFIED IDEOGRAPH
+0xC049	0x96AA	#CJK UNIFIED IDEOGRAPH
+0xC04A	0x96D5	#CJK UNIFIED IDEOGRAPH
+0xC04B	0x970E	#CJK UNIFIED IDEOGRAPH
+0xC04C	0x9711	#CJK UNIFIED IDEOGRAPH
+0xC04D	0x9716	#CJK UNIFIED IDEOGRAPH
+0xC04E	0x970D	#CJK UNIFIED IDEOGRAPH
+0xC04F	0x9713	#CJK UNIFIED IDEOGRAPH
+0xC050	0x970F	#CJK UNIFIED IDEOGRAPH
+0xC051	0x975B	#CJK UNIFIED IDEOGRAPH
+0xC052	0x975C	#CJK UNIFIED IDEOGRAPH
+0xC053	0x9766	#CJK UNIFIED IDEOGRAPH
+0xC054	0x9798	#CJK UNIFIED IDEOGRAPH
+0xC055	0x9830	#CJK UNIFIED IDEOGRAPH
+0xC056	0x9838	#CJK UNIFIED IDEOGRAPH
+0xC057	0x983B	#CJK UNIFIED IDEOGRAPH
+0xC058	0x9837	#CJK UNIFIED IDEOGRAPH
+0xC059	0x982D	#CJK UNIFIED IDEOGRAPH
+0xC05A	0x9839	#CJK UNIFIED IDEOGRAPH
+0xC05B	0x9824	#CJK UNIFIED IDEOGRAPH
+0xC05C	0x9910	#CJK UNIFIED IDEOGRAPH
+0xC05D	0x9928	#CJK UNIFIED IDEOGRAPH
+0xC05E	0x991E	#CJK UNIFIED IDEOGRAPH
+0xC05F	0x991B	#CJK UNIFIED IDEOGRAPH
+0xC060	0x9921	#CJK UNIFIED IDEOGRAPH
+0xC061	0x991A	#CJK UNIFIED IDEOGRAPH
+0xC062	0x99ED	#CJK UNIFIED IDEOGRAPH
+0xC063	0x99E2	#CJK UNIFIED IDEOGRAPH
+0xC064	0x99F1	#CJK UNIFIED IDEOGRAPH
+0xC065	0x9AB8	#CJK UNIFIED IDEOGRAPH
+0xC066	0x9ABC	#CJK UNIFIED IDEOGRAPH
+0xC067	0x9AFB	#CJK UNIFIED IDEOGRAPH
+0xC068	0x9AED	#CJK UNIFIED IDEOGRAPH
+0xC069	0x9B28	#CJK UNIFIED IDEOGRAPH
+0xC06A	0x9B91	#CJK UNIFIED IDEOGRAPH
+0xC06B	0x9D15	#CJK UNIFIED IDEOGRAPH
+0xC06C	0x9D23	#CJK UNIFIED IDEOGRAPH
+0xC06D	0x9D26	#CJK UNIFIED IDEOGRAPH
+0xC06E	0x9D28	#CJK UNIFIED IDEOGRAPH
+0xC06F	0x9D12	#CJK UNIFIED IDEOGRAPH
+0xC070	0x9D1B	#CJK UNIFIED IDEOGRAPH
+0xC071	0x9ED8	#CJK UNIFIED IDEOGRAPH
+0xC072	0x9ED4	#CJK UNIFIED IDEOGRAPH
+0xC073	0x9F8D	#CJK UNIFIED IDEOGRAPH
+0xC074	0x9F9C	#CJK UNIFIED IDEOGRAPH
+0xC075	0x512A	#CJK UNIFIED IDEOGRAPH
+0xC076	0x511F	#CJK UNIFIED IDEOGRAPH
+0xC077	0x5121	#CJK UNIFIED IDEOGRAPH
+0xC078	0x5132	#CJK UNIFIED IDEOGRAPH
+0xC079	0x52F5	#CJK UNIFIED IDEOGRAPH
+0xC07A	0x568E	#CJK UNIFIED IDEOGRAPH
+0xC07B	0x5680	#CJK UNIFIED IDEOGRAPH
+0xC07C	0x5690	#CJK UNIFIED IDEOGRAPH
+0xC07D	0x5685	#CJK UNIFIED IDEOGRAPH
+0xC07E	0x5687	#CJK UNIFIED IDEOGRAPH
+0xC0A1	0x568F	#CJK UNIFIED IDEOGRAPH
+0xC0A2	0x58D5	#CJK UNIFIED IDEOGRAPH
+0xC0A3	0x58D3	#CJK UNIFIED IDEOGRAPH
+0xC0A4	0x58D1	#CJK UNIFIED IDEOGRAPH
+0xC0A5	0x58CE	#CJK UNIFIED IDEOGRAPH
+0xC0A6	0x5B30	#CJK UNIFIED IDEOGRAPH
+0xC0A7	0x5B2A	#CJK UNIFIED IDEOGRAPH
+0xC0A8	0x5B24	#CJK UNIFIED IDEOGRAPH
+0xC0A9	0x5B7A	#CJK UNIFIED IDEOGRAPH
+0xC0AA	0x5C37	#CJK UNIFIED IDEOGRAPH
+0xC0AB	0x5C68	#CJK UNIFIED IDEOGRAPH
+0xC0AC	0x5DBC	#CJK UNIFIED IDEOGRAPH
+0xC0AD	0x5DBA	#CJK UNIFIED IDEOGRAPH
+0xC0AE	0x5DBD	#CJK UNIFIED IDEOGRAPH
+0xC0AF	0x5DB8	#CJK UNIFIED IDEOGRAPH
+0xC0B0	0x5E6B	#CJK UNIFIED IDEOGRAPH
+0xC0B1	0x5F4C	#CJK UNIFIED IDEOGRAPH
+0xC0B2	0x5FBD	#CJK UNIFIED IDEOGRAPH
+0xC0B3	0x61C9	#CJK UNIFIED IDEOGRAPH
+0xC0B4	0x61C2	#CJK UNIFIED IDEOGRAPH
+0xC0B5	0x61C7	#CJK UNIFIED IDEOGRAPH
+0xC0B6	0x61E6	#CJK UNIFIED IDEOGRAPH
+0xC0B7	0x61CB	#CJK UNIFIED IDEOGRAPH
+0xC0B8	0x6232	#CJK UNIFIED IDEOGRAPH
+0xC0B9	0x6234	#CJK UNIFIED IDEOGRAPH
+0xC0BA	0x64CE	#CJK UNIFIED IDEOGRAPH
+0xC0BB	0x64CA	#CJK UNIFIED IDEOGRAPH
+0xC0BC	0x64D8	#CJK UNIFIED IDEOGRAPH
+0xC0BD	0x64E0	#CJK UNIFIED IDEOGRAPH
+0xC0BE	0x64F0	#CJK UNIFIED IDEOGRAPH
+0xC0BF	0x64E6	#CJK UNIFIED IDEOGRAPH
+0xC0C0	0x64EC	#CJK UNIFIED IDEOGRAPH
+0xC0C1	0x64F1	#CJK UNIFIED IDEOGRAPH
+0xC0C2	0x64E2	#CJK UNIFIED IDEOGRAPH
+0xC0C3	0x64ED	#CJK UNIFIED IDEOGRAPH
+0xC0C4	0x6582	#CJK UNIFIED IDEOGRAPH
+0xC0C5	0x6583	#CJK UNIFIED IDEOGRAPH
+0xC0C6	0x66D9	#CJK UNIFIED IDEOGRAPH
+0xC0C7	0x66D6	#CJK UNIFIED IDEOGRAPH
+0xC0C8	0x6A80	#CJK UNIFIED IDEOGRAPH
+0xC0C9	0x6A94	#CJK UNIFIED IDEOGRAPH
+0xC0CA	0x6A84	#CJK UNIFIED IDEOGRAPH
+0xC0CB	0x6AA2	#CJK UNIFIED IDEOGRAPH
+0xC0CC	0x6A9C	#CJK UNIFIED IDEOGRAPH
+0xC0CD	0x6ADB	#CJK UNIFIED IDEOGRAPH
+0xC0CE	0x6AA3	#CJK UNIFIED IDEOGRAPH
+0xC0CF	0x6A7E	#CJK UNIFIED IDEOGRAPH
+0xC0D0	0x6A97	#CJK UNIFIED IDEOGRAPH
+0xC0D1	0x6A90	#CJK UNIFIED IDEOGRAPH
+0xC0D2	0x6AA0	#CJK UNIFIED IDEOGRAPH
+0xC0D3	0x6B5C	#CJK UNIFIED IDEOGRAPH
+0xC0D4	0x6BAE	#CJK UNIFIED IDEOGRAPH
+0xC0D5	0x6BDA	#CJK UNIFIED IDEOGRAPH
+0xC0D6	0x6C08	#CJK UNIFIED IDEOGRAPH
+0xC0D7	0x6FD8	#CJK UNIFIED IDEOGRAPH
+0xC0D8	0x6FF1	#CJK UNIFIED IDEOGRAPH
+0xC0D9	0x6FDF	#CJK UNIFIED IDEOGRAPH
+0xC0DA	0x6FE0	#CJK UNIFIED IDEOGRAPH
+0xC0DB	0x6FDB	#CJK UNIFIED IDEOGRAPH
+0xC0DC	0x6FE4	#CJK UNIFIED IDEOGRAPH
+0xC0DD	0x6FEB	#CJK UNIFIED IDEOGRAPH
+0xC0DE	0x6FEF	#CJK UNIFIED IDEOGRAPH
+0xC0DF	0x6F80	#CJK UNIFIED IDEOGRAPH
+0xC0E0	0x6FEC	#CJK UNIFIED IDEOGRAPH
+0xC0E1	0x6FE1	#CJK UNIFIED IDEOGRAPH
+0xC0E2	0x6FE9	#CJK UNIFIED IDEOGRAPH
+0xC0E3	0x6FD5	#CJK UNIFIED IDEOGRAPH
+0xC0E4	0x6FEE	#CJK UNIFIED IDEOGRAPH
+0xC0E5	0x6FF0	#CJK UNIFIED IDEOGRAPH
+0xC0E6	0x71E7	#CJK UNIFIED IDEOGRAPH
+0xC0E7	0x71DF	#CJK UNIFIED IDEOGRAPH
+0xC0E8	0x71EE	#CJK UNIFIED IDEOGRAPH
+0xC0E9	0x71E6	#CJK UNIFIED IDEOGRAPH
+0xC0EA	0x71E5	#CJK UNIFIED IDEOGRAPH
+0xC0EB	0x71ED	#CJK UNIFIED IDEOGRAPH
+0xC0EC	0x71EC	#CJK UNIFIED IDEOGRAPH
+0xC0ED	0x71F4	#CJK UNIFIED IDEOGRAPH
+0xC0EE	0x71E0	#CJK UNIFIED IDEOGRAPH
+0xC0EF	0x7235	#CJK UNIFIED IDEOGRAPH
+0xC0F0	0x7246	#CJK UNIFIED IDEOGRAPH
+0xC0F1	0x7370	#CJK UNIFIED IDEOGRAPH
+0xC0F2	0x7372	#CJK UNIFIED IDEOGRAPH
+0xC0F3	0x74A9	#CJK UNIFIED IDEOGRAPH
+0xC0F4	0x74B0	#CJK UNIFIED IDEOGRAPH
+0xC0F5	0x74A6	#CJK UNIFIED IDEOGRAPH
+0xC0F6	0x74A8	#CJK UNIFIED IDEOGRAPH
+0xC0F7	0x7646	#CJK UNIFIED IDEOGRAPH
+0xC0F8	0x7642	#CJK UNIFIED IDEOGRAPH
+0xC0F9	0x764C	#CJK UNIFIED IDEOGRAPH
+0xC0FA	0x76EA	#CJK UNIFIED IDEOGRAPH
+0xC0FB	0x77B3	#CJK UNIFIED IDEOGRAPH
+0xC0FC	0x77AA	#CJK UNIFIED IDEOGRAPH
+0xC0FD	0x77B0	#CJK UNIFIED IDEOGRAPH
+0xC0FE	0x77AC	#CJK UNIFIED IDEOGRAPH
+0xC140	0x77A7	#CJK UNIFIED IDEOGRAPH
+0xC141	0x77AD	#CJK UNIFIED IDEOGRAPH
+0xC142	0x77EF	#CJK UNIFIED IDEOGRAPH
+0xC143	0x78F7	#CJK UNIFIED IDEOGRAPH
+0xC144	0x78FA	#CJK UNIFIED IDEOGRAPH
+0xC145	0x78F4	#CJK UNIFIED IDEOGRAPH
+0xC146	0x78EF	#CJK UNIFIED IDEOGRAPH
+0xC147	0x7901	#CJK UNIFIED IDEOGRAPH
+0xC148	0x79A7	#CJK UNIFIED IDEOGRAPH
+0xC149	0x79AA	#CJK UNIFIED IDEOGRAPH
+0xC14A	0x7A57	#CJK UNIFIED IDEOGRAPH
+0xC14B	0x7ABF	#CJK UNIFIED IDEOGRAPH
+0xC14C	0x7C07	#CJK UNIFIED IDEOGRAPH
+0xC14D	0x7C0D	#CJK UNIFIED IDEOGRAPH
+0xC14E	0x7BFE	#CJK UNIFIED IDEOGRAPH
+0xC14F	0x7BF7	#CJK UNIFIED IDEOGRAPH
+0xC150	0x7C0C	#CJK UNIFIED IDEOGRAPH
+0xC151	0x7BE0	#CJK UNIFIED IDEOGRAPH
+0xC152	0x7CE0	#CJK UNIFIED IDEOGRAPH
+0xC153	0x7CDC	#CJK UNIFIED IDEOGRAPH
+0xC154	0x7CDE	#CJK UNIFIED IDEOGRAPH
+0xC155	0x7CE2	#CJK UNIFIED IDEOGRAPH
+0xC156	0x7CDF	#CJK UNIFIED IDEOGRAPH
+0xC157	0x7CD9	#CJK UNIFIED IDEOGRAPH
+0xC158	0x7CDD	#CJK UNIFIED IDEOGRAPH
+0xC159	0x7E2E	#CJK UNIFIED IDEOGRAPH
+0xC15A	0x7E3E	#CJK UNIFIED IDEOGRAPH
+0xC15B	0x7E46	#CJK UNIFIED IDEOGRAPH
+0xC15C	0x7E37	#CJK UNIFIED IDEOGRAPH
+0xC15D	0x7E32	#CJK UNIFIED IDEOGRAPH
+0xC15E	0x7E43	#CJK UNIFIED IDEOGRAPH
+0xC15F	0x7E2B	#CJK UNIFIED IDEOGRAPH
+0xC160	0x7E3D	#CJK UNIFIED IDEOGRAPH
+0xC161	0x7E31	#CJK UNIFIED IDEOGRAPH
+0xC162	0x7E45	#CJK UNIFIED IDEOGRAPH
+0xC163	0x7E41	#CJK UNIFIED IDEOGRAPH
+0xC164	0x7E34	#CJK UNIFIED IDEOGRAPH
+0xC165	0x7E39	#CJK UNIFIED IDEOGRAPH
+0xC166	0x7E48	#CJK UNIFIED IDEOGRAPH
+0xC167	0x7E35	#CJK UNIFIED IDEOGRAPH
+0xC168	0x7E3F	#CJK UNIFIED IDEOGRAPH
+0xC169	0x7E2F	#CJK UNIFIED IDEOGRAPH
+0xC16A	0x7F44	#CJK UNIFIED IDEOGRAPH
+0xC16B	0x7FF3	#CJK UNIFIED IDEOGRAPH
+0xC16C	0x7FFC	#CJK UNIFIED IDEOGRAPH
+0xC16D	0x8071	#CJK UNIFIED IDEOGRAPH
+0xC16E	0x8072	#CJK UNIFIED IDEOGRAPH
+0xC16F	0x8070	#CJK UNIFIED IDEOGRAPH
+0xC170	0x806F	#CJK UNIFIED IDEOGRAPH
+0xC171	0x8073	#CJK UNIFIED IDEOGRAPH
+0xC172	0x81C6	#CJK UNIFIED IDEOGRAPH
+0xC173	0x81C3	#CJK UNIFIED IDEOGRAPH
+0xC174	0x81BA	#CJK UNIFIED IDEOGRAPH
+0xC175	0x81C2	#CJK UNIFIED IDEOGRAPH
+0xC176	0x81C0	#CJK UNIFIED IDEOGRAPH
+0xC177	0x81BF	#CJK UNIFIED IDEOGRAPH
+0xC178	0x81BD	#CJK UNIFIED IDEOGRAPH
+0xC179	0x81C9	#CJK UNIFIED IDEOGRAPH
+0xC17A	0x81BE	#CJK UNIFIED IDEOGRAPH
+0xC17B	0x81E8	#CJK UNIFIED IDEOGRAPH
+0xC17C	0x8209	#CJK UNIFIED IDEOGRAPH
+0xC17D	0x8271	#CJK UNIFIED IDEOGRAPH
+0xC17E	0x85AA	#CJK UNIFIED IDEOGRAPH
+0xC1A1	0x8584	#CJK UNIFIED IDEOGRAPH
+0xC1A2	0x857E	#CJK UNIFIED IDEOGRAPH
+0xC1A3	0x859C	#CJK UNIFIED IDEOGRAPH
+0xC1A4	0x8591	#CJK UNIFIED IDEOGRAPH
+0xC1A5	0x8594	#CJK UNIFIED IDEOGRAPH
+0xC1A6	0x85AF	#CJK UNIFIED IDEOGRAPH
+0xC1A7	0x859B	#CJK UNIFIED IDEOGRAPH
+0xC1A8	0x8587	#CJK UNIFIED IDEOGRAPH
+0xC1A9	0x85A8	#CJK UNIFIED IDEOGRAPH
+0xC1AA	0x858A	#CJK UNIFIED IDEOGRAPH
+0xC1AB	0x8667	#CJK UNIFIED IDEOGRAPH
+0xC1AC	0x87C0	#CJK UNIFIED IDEOGRAPH
+0xC1AD	0x87D1	#CJK UNIFIED IDEOGRAPH
+0xC1AE	0x87B3	#CJK UNIFIED IDEOGRAPH
+0xC1AF	0x87D2	#CJK UNIFIED IDEOGRAPH
+0xC1B0	0x87C6	#CJK UNIFIED IDEOGRAPH
+0xC1B1	0x87AB	#CJK UNIFIED IDEOGRAPH
+0xC1B2	0x87BB	#CJK UNIFIED IDEOGRAPH
+0xC1B3	0x87BA	#CJK UNIFIED IDEOGRAPH
+0xC1B4	0x87C8	#CJK UNIFIED IDEOGRAPH
+0xC1B5	0x87CB	#CJK UNIFIED IDEOGRAPH
+0xC1B6	0x893B	#CJK UNIFIED IDEOGRAPH
+0xC1B7	0x8936	#CJK UNIFIED IDEOGRAPH
+0xC1B8	0x8944	#CJK UNIFIED IDEOGRAPH
+0xC1B9	0x8938	#CJK UNIFIED IDEOGRAPH
+0xC1BA	0x893D	#CJK UNIFIED IDEOGRAPH
+0xC1BB	0x89AC	#CJK UNIFIED IDEOGRAPH
+0xC1BC	0x8B0E	#CJK UNIFIED IDEOGRAPH
+0xC1BD	0x8B17	#CJK UNIFIED IDEOGRAPH
+0xC1BE	0x8B19	#CJK UNIFIED IDEOGRAPH
+0xC1BF	0x8B1B	#CJK UNIFIED IDEOGRAPH
+0xC1C0	0x8B0A	#CJK UNIFIED IDEOGRAPH
+0xC1C1	0x8B20	#CJK UNIFIED IDEOGRAPH
+0xC1C2	0x8B1D	#CJK UNIFIED IDEOGRAPH
+0xC1C3	0x8B04	#CJK UNIFIED IDEOGRAPH
+0xC1C4	0x8B10	#CJK UNIFIED IDEOGRAPH
+0xC1C5	0x8C41	#CJK UNIFIED IDEOGRAPH
+0xC1C6	0x8C3F	#CJK UNIFIED IDEOGRAPH
+0xC1C7	0x8C73	#CJK UNIFIED IDEOGRAPH
+0xC1C8	0x8CFA	#CJK UNIFIED IDEOGRAPH
+0xC1C9	0x8CFD	#CJK UNIFIED IDEOGRAPH
+0xC1CA	0x8CFC	#CJK UNIFIED IDEOGRAPH
+0xC1CB	0x8CF8	#CJK UNIFIED IDEOGRAPH
+0xC1CC	0x8CFB	#CJK UNIFIED IDEOGRAPH
+0xC1CD	0x8DA8	#CJK UNIFIED IDEOGRAPH
+0xC1CE	0x8E49	#CJK UNIFIED IDEOGRAPH
+0xC1CF	0x8E4B	#CJK UNIFIED IDEOGRAPH
+0xC1D0	0x8E48	#CJK UNIFIED IDEOGRAPH
+0xC1D1	0x8E4A	#CJK UNIFIED IDEOGRAPH
+0xC1D2	0x8F44	#CJK UNIFIED IDEOGRAPH
+0xC1D3	0x8F3E	#CJK UNIFIED IDEOGRAPH
+0xC1D4	0x8F42	#CJK UNIFIED IDEOGRAPH
+0xC1D5	0x8F45	#CJK UNIFIED IDEOGRAPH
+0xC1D6	0x8F3F	#CJK UNIFIED IDEOGRAPH
+0xC1D7	0x907F	#CJK UNIFIED IDEOGRAPH
+0xC1D8	0x907D	#CJK UNIFIED IDEOGRAPH
+0xC1D9	0x9084	#CJK UNIFIED IDEOGRAPH
+0xC1DA	0x9081	#CJK UNIFIED IDEOGRAPH
+0xC1DB	0x9082	#CJK UNIFIED IDEOGRAPH
+0xC1DC	0x9080	#CJK UNIFIED IDEOGRAPH
+0xC1DD	0x9139	#CJK UNIFIED IDEOGRAPH
+0xC1DE	0x91A3	#CJK UNIFIED IDEOGRAPH
+0xC1DF	0x919E	#CJK UNIFIED IDEOGRAPH
+0xC1E0	0x919C	#CJK UNIFIED IDEOGRAPH
+0xC1E1	0x934D	#CJK UNIFIED IDEOGRAPH
+0xC1E2	0x9382	#CJK UNIFIED IDEOGRAPH
+0xC1E3	0x9328	#CJK UNIFIED IDEOGRAPH
+0xC1E4	0x9375	#CJK UNIFIED IDEOGRAPH
+0xC1E5	0x934A	#CJK UNIFIED IDEOGRAPH
+0xC1E6	0x9365	#CJK UNIFIED IDEOGRAPH
+0xC1E7	0x934B	#CJK UNIFIED IDEOGRAPH
+0xC1E8	0x9318	#CJK UNIFIED IDEOGRAPH
+0xC1E9	0x937E	#CJK UNIFIED IDEOGRAPH
+0xC1EA	0x936C	#CJK UNIFIED IDEOGRAPH
+0xC1EB	0x935B	#CJK UNIFIED IDEOGRAPH
+0xC1EC	0x9370	#CJK UNIFIED IDEOGRAPH
+0xC1ED	0x935A	#CJK UNIFIED IDEOGRAPH
+0xC1EE	0x9354	#CJK UNIFIED IDEOGRAPH
+0xC1EF	0x95CA	#CJK UNIFIED IDEOGRAPH
+0xC1F0	0x95CB	#CJK UNIFIED IDEOGRAPH
+0xC1F1	0x95CC	#CJK UNIFIED IDEOGRAPH
+0xC1F2	0x95C8	#CJK UNIFIED IDEOGRAPH
+0xC1F3	0x95C6	#CJK UNIFIED IDEOGRAPH
+0xC1F4	0x96B1	#CJK UNIFIED IDEOGRAPH
+0xC1F5	0x96B8	#CJK UNIFIED IDEOGRAPH
+0xC1F6	0x96D6	#CJK UNIFIED IDEOGRAPH
+0xC1F7	0x971C	#CJK UNIFIED IDEOGRAPH
+0xC1F8	0x971E	#CJK UNIFIED IDEOGRAPH
+0xC1F9	0x97A0	#CJK UNIFIED IDEOGRAPH
+0xC1FA	0x97D3	#CJK UNIFIED IDEOGRAPH
+0xC1FB	0x9846	#CJK UNIFIED IDEOGRAPH
+0xC1FC	0x98B6	#CJK UNIFIED IDEOGRAPH
+0xC1FD	0x9935	#CJK UNIFIED IDEOGRAPH
+0xC1FE	0x9A01	#CJK UNIFIED IDEOGRAPH
+0xC240	0x99FF	#CJK UNIFIED IDEOGRAPH
+0xC241	0x9BAE	#CJK UNIFIED IDEOGRAPH
+0xC242	0x9BAB	#CJK UNIFIED IDEOGRAPH
+0xC243	0x9BAA	#CJK UNIFIED IDEOGRAPH
+0xC244	0x9BAD	#CJK UNIFIED IDEOGRAPH
+0xC245	0x9D3B	#CJK UNIFIED IDEOGRAPH
+0xC246	0x9D3F	#CJK UNIFIED IDEOGRAPH
+0xC247	0x9E8B	#CJK UNIFIED IDEOGRAPH
+0xC248	0x9ECF	#CJK UNIFIED IDEOGRAPH
+0xC249	0x9EDE	#CJK UNIFIED IDEOGRAPH
+0xC24A	0x9EDC	#CJK UNIFIED IDEOGRAPH
+0xC24B	0x9EDD	#CJK UNIFIED IDEOGRAPH
+0xC24C	0x9EDB	#CJK UNIFIED IDEOGRAPH
+0xC24D	0x9F3E	#CJK UNIFIED IDEOGRAPH
+0xC24E	0x9F4B	#CJK UNIFIED IDEOGRAPH
+0xC24F	0x53E2	#CJK UNIFIED IDEOGRAPH
+0xC250	0x5695	#CJK UNIFIED IDEOGRAPH
+0xC251	0x56AE	#CJK UNIFIED IDEOGRAPH
+0xC252	0x58D9	#CJK UNIFIED IDEOGRAPH
+0xC253	0x58D8	#CJK UNIFIED IDEOGRAPH
+0xC254	0x5B38	#CJK UNIFIED IDEOGRAPH
+0xC255	0x5F5D	#CJK UNIFIED IDEOGRAPH
+0xC256	0x61E3	#CJK UNIFIED IDEOGRAPH
+0xC257	0x6233	#CJK UNIFIED IDEOGRAPH
+0xC258	0x64F4	#CJK UNIFIED IDEOGRAPH
+0xC259	0x64F2	#CJK UNIFIED IDEOGRAPH
+0xC25A	0x64FE	#CJK UNIFIED IDEOGRAPH
+0xC25B	0x6506	#CJK UNIFIED IDEOGRAPH
+0xC25C	0x64FA	#CJK UNIFIED IDEOGRAPH
+0xC25D	0x64FB	#CJK UNIFIED IDEOGRAPH
+0xC25E	0x64F7	#CJK UNIFIED IDEOGRAPH
+0xC25F	0x65B7	#CJK UNIFIED IDEOGRAPH
+0xC260	0x66DC	#CJK UNIFIED IDEOGRAPH
+0xC261	0x6726	#CJK UNIFIED IDEOGRAPH
+0xC262	0x6AB3	#CJK UNIFIED IDEOGRAPH
+0xC263	0x6AAC	#CJK UNIFIED IDEOGRAPH
+0xC264	0x6AC3	#CJK UNIFIED IDEOGRAPH
+0xC265	0x6ABB	#CJK UNIFIED IDEOGRAPH
+0xC266	0x6AB8	#CJK UNIFIED IDEOGRAPH
+0xC267	0x6AC2	#CJK UNIFIED IDEOGRAPH
+0xC268	0x6AAE	#CJK UNIFIED IDEOGRAPH
+0xC269	0x6AAF	#CJK UNIFIED IDEOGRAPH
+0xC26A	0x6B5F	#CJK UNIFIED IDEOGRAPH
+0xC26B	0x6B78	#CJK UNIFIED IDEOGRAPH
+0xC26C	0x6BAF	#CJK UNIFIED IDEOGRAPH
+0xC26D	0x7009	#CJK UNIFIED IDEOGRAPH
+0xC26E	0x700B	#CJK UNIFIED IDEOGRAPH
+0xC26F	0x6FFE	#CJK UNIFIED IDEOGRAPH
+0xC270	0x7006	#CJK UNIFIED IDEOGRAPH
+0xC271	0x6FFA	#CJK UNIFIED IDEOGRAPH
+0xC272	0x7011	#CJK UNIFIED IDEOGRAPH
+0xC273	0x700F	#CJK UNIFIED IDEOGRAPH
+0xC274	0x71FB	#CJK UNIFIED IDEOGRAPH
+0xC275	0x71FC	#CJK UNIFIED IDEOGRAPH
+0xC276	0x71FE	#CJK UNIFIED IDEOGRAPH
+0xC277	0x71F8	#CJK UNIFIED IDEOGRAPH
+0xC278	0x7377	#CJK UNIFIED IDEOGRAPH
+0xC279	0x7375	#CJK UNIFIED IDEOGRAPH
+0xC27A	0x74A7	#CJK UNIFIED IDEOGRAPH
+0xC27B	0x74BF	#CJK UNIFIED IDEOGRAPH
+0xC27C	0x7515	#CJK UNIFIED IDEOGRAPH
+0xC27D	0x7656	#CJK UNIFIED IDEOGRAPH
+0xC27E	0x7658	#CJK UNIFIED IDEOGRAPH
+0xC2A1	0x7652	#CJK UNIFIED IDEOGRAPH
+0xC2A2	0x77BD	#CJK UNIFIED IDEOGRAPH
+0xC2A3	0x77BF	#CJK UNIFIED IDEOGRAPH
+0xC2A4	0x77BB	#CJK UNIFIED IDEOGRAPH
+0xC2A5	0x77BC	#CJK UNIFIED IDEOGRAPH
+0xC2A6	0x790E	#CJK UNIFIED IDEOGRAPH
+0xC2A7	0x79AE	#CJK UNIFIED IDEOGRAPH
+0xC2A8	0x7A61	#CJK UNIFIED IDEOGRAPH
+0xC2A9	0x7A62	#CJK UNIFIED IDEOGRAPH
+0xC2AA	0x7A60	#CJK UNIFIED IDEOGRAPH
+0xC2AB	0x7AC4	#CJK UNIFIED IDEOGRAPH
+0xC2AC	0x7AC5	#CJK UNIFIED IDEOGRAPH
+0xC2AD	0x7C2B	#CJK UNIFIED IDEOGRAPH
+0xC2AE	0x7C27	#CJK UNIFIED IDEOGRAPH
+0xC2AF	0x7C2A	#CJK UNIFIED IDEOGRAPH
+0xC2B0	0x7C1E	#CJK UNIFIED IDEOGRAPH
+0xC2B1	0x7C23	#CJK UNIFIED IDEOGRAPH
+0xC2B2	0x7C21	#CJK UNIFIED IDEOGRAPH
+0xC2B3	0x7CE7	#CJK UNIFIED IDEOGRAPH
+0xC2B4	0x7E54	#CJK UNIFIED IDEOGRAPH
+0xC2B5	0x7E55	#CJK UNIFIED IDEOGRAPH
+0xC2B6	0x7E5E	#CJK UNIFIED IDEOGRAPH
+0xC2B7	0x7E5A	#CJK UNIFIED IDEOGRAPH
+0xC2B8	0x7E61	#CJK UNIFIED IDEOGRAPH
+0xC2B9	0x7E52	#CJK UNIFIED IDEOGRAPH
+0xC2BA	0x7E59	#CJK UNIFIED IDEOGRAPH
+0xC2BB	0x7F48	#CJK UNIFIED IDEOGRAPH
+0xC2BC	0x7FF9	#CJK UNIFIED IDEOGRAPH
+0xC2BD	0x7FFB	#CJK UNIFIED IDEOGRAPH
+0xC2BE	0x8077	#CJK UNIFIED IDEOGRAPH
+0xC2BF	0x8076	#CJK UNIFIED IDEOGRAPH
+0xC2C0	0x81CD	#CJK UNIFIED IDEOGRAPH
+0xC2C1	0x81CF	#CJK UNIFIED IDEOGRAPH
+0xC2C2	0x820A	#CJK UNIFIED IDEOGRAPH
+0xC2C3	0x85CF	#CJK UNIFIED IDEOGRAPH
+0xC2C4	0x85A9	#CJK UNIFIED IDEOGRAPH
+0xC2C5	0x85CD	#CJK UNIFIED IDEOGRAPH
+0xC2C6	0x85D0	#CJK UNIFIED IDEOGRAPH
+0xC2C7	0x85C9	#CJK UNIFIED IDEOGRAPH
+0xC2C8	0x85B0	#CJK UNIFIED IDEOGRAPH
+0xC2C9	0x85BA	#CJK UNIFIED IDEOGRAPH
+0xC2CA	0x85B9	#CJK UNIFIED IDEOGRAPH
+0xC2CB	0x85A6	#CJK UNIFIED IDEOGRAPH
+0xC2CC	0x87EF	#CJK UNIFIED IDEOGRAPH
+0xC2CD	0x87EC	#CJK UNIFIED IDEOGRAPH
+0xC2CE	0x87F2	#CJK UNIFIED IDEOGRAPH
+0xC2CF	0x87E0	#CJK UNIFIED IDEOGRAPH
+0xC2D0	0x8986	#CJK UNIFIED IDEOGRAPH
+0xC2D1	0x89B2	#CJK UNIFIED IDEOGRAPH
+0xC2D2	0x89F4	#CJK UNIFIED IDEOGRAPH
+0xC2D3	0x8B28	#CJK UNIFIED IDEOGRAPH
+0xC2D4	0x8B39	#CJK UNIFIED IDEOGRAPH
+0xC2D5	0x8B2C	#CJK UNIFIED IDEOGRAPH
+0xC2D6	0x8B2B	#CJK UNIFIED IDEOGRAPH
+0xC2D7	0x8C50	#CJK UNIFIED IDEOGRAPH
+0xC2D8	0x8D05	#CJK UNIFIED IDEOGRAPH
+0xC2D9	0x8E59	#CJK UNIFIED IDEOGRAPH
+0xC2DA	0x8E63	#CJK UNIFIED IDEOGRAPH
+0xC2DB	0x8E66	#CJK UNIFIED IDEOGRAPH
+0xC2DC	0x8E64	#CJK UNIFIED IDEOGRAPH
+0xC2DD	0x8E5F	#CJK UNIFIED IDEOGRAPH
+0xC2DE	0x8E55	#CJK UNIFIED IDEOGRAPH
+0xC2DF	0x8EC0	#CJK UNIFIED IDEOGRAPH
+0xC2E0	0x8F49	#CJK UNIFIED IDEOGRAPH
+0xC2E1	0x8F4D	#CJK UNIFIED IDEOGRAPH
+0xC2E2	0x9087	#CJK UNIFIED IDEOGRAPH
+0xC2E3	0x9083	#CJK UNIFIED IDEOGRAPH
+0xC2E4	0x9088	#CJK UNIFIED IDEOGRAPH
+0xC2E5	0x91AB	#CJK UNIFIED IDEOGRAPH
+0xC2E6	0x91AC	#CJK UNIFIED IDEOGRAPH
+0xC2E7	0x91D0	#CJK UNIFIED IDEOGRAPH
+0xC2E8	0x9394	#CJK UNIFIED IDEOGRAPH
+0xC2E9	0x938A	#CJK UNIFIED IDEOGRAPH
+0xC2EA	0x9396	#CJK UNIFIED IDEOGRAPH
+0xC2EB	0x93A2	#CJK UNIFIED IDEOGRAPH
+0xC2EC	0x93B3	#CJK UNIFIED IDEOGRAPH
+0xC2ED	0x93AE	#CJK UNIFIED IDEOGRAPH
+0xC2EE	0x93AC	#CJK UNIFIED IDEOGRAPH
+0xC2EF	0x93B0	#CJK UNIFIED IDEOGRAPH
+0xC2F0	0x9398	#CJK UNIFIED IDEOGRAPH
+0xC2F1	0x939A	#CJK UNIFIED IDEOGRAPH
+0xC2F2	0x9397	#CJK UNIFIED IDEOGRAPH
+0xC2F3	0x95D4	#CJK UNIFIED IDEOGRAPH
+0xC2F4	0x95D6	#CJK UNIFIED IDEOGRAPH
+0xC2F5	0x95D0	#CJK UNIFIED IDEOGRAPH
+0xC2F6	0x95D5	#CJK UNIFIED IDEOGRAPH
+0xC2F7	0x96E2	#CJK UNIFIED IDEOGRAPH
+0xC2F8	0x96DC	#CJK UNIFIED IDEOGRAPH
+0xC2F9	0x96D9	#CJK UNIFIED IDEOGRAPH
+0xC2FA	0x96DB	#CJK UNIFIED IDEOGRAPH
+0xC2FB	0x96DE	#CJK UNIFIED IDEOGRAPH
+0xC2FC	0x9724	#CJK UNIFIED IDEOGRAPH
+0xC2FD	0x97A3	#CJK UNIFIED IDEOGRAPH
+0xC2FE	0x97A6	#CJK UNIFIED IDEOGRAPH
+0xC340	0x97AD	#CJK UNIFIED IDEOGRAPH
+0xC341	0x97F9	#CJK UNIFIED IDEOGRAPH
+0xC342	0x984D	#CJK UNIFIED IDEOGRAPH
+0xC343	0x984F	#CJK UNIFIED IDEOGRAPH
+0xC344	0x984C	#CJK UNIFIED IDEOGRAPH
+0xC345	0x984E	#CJK UNIFIED IDEOGRAPH
+0xC346	0x9853	#CJK UNIFIED IDEOGRAPH
+0xC347	0x98BA	#CJK UNIFIED IDEOGRAPH
+0xC348	0x993E	#CJK UNIFIED IDEOGRAPH
+0xC349	0x993F	#CJK UNIFIED IDEOGRAPH
+0xC34A	0x993D	#CJK UNIFIED IDEOGRAPH
+0xC34B	0x992E	#CJK UNIFIED IDEOGRAPH
+0xC34C	0x99A5	#CJK UNIFIED IDEOGRAPH
+0xC34D	0x9A0E	#CJK UNIFIED IDEOGRAPH
+0xC34E	0x9AC1	#CJK UNIFIED IDEOGRAPH
+0xC34F	0x9B03	#CJK UNIFIED IDEOGRAPH
+0xC350	0x9B06	#CJK UNIFIED IDEOGRAPH
+0xC351	0x9B4F	#CJK UNIFIED IDEOGRAPH
+0xC352	0x9B4E	#CJK UNIFIED IDEOGRAPH
+0xC353	0x9B4D	#CJK UNIFIED IDEOGRAPH
+0xC354	0x9BCA	#CJK UNIFIED IDEOGRAPH
+0xC355	0x9BC9	#CJK UNIFIED IDEOGRAPH
+0xC356	0x9BFD	#CJK UNIFIED IDEOGRAPH
+0xC357	0x9BC8	#CJK UNIFIED IDEOGRAPH
+0xC358	0x9BC0	#CJK UNIFIED IDEOGRAPH
+0xC359	0x9D51	#CJK UNIFIED IDEOGRAPH
+0xC35A	0x9D5D	#CJK UNIFIED IDEOGRAPH
+0xC35B	0x9D60	#CJK UNIFIED IDEOGRAPH
+0xC35C	0x9EE0	#CJK UNIFIED IDEOGRAPH
+0xC35D	0x9F15	#CJK UNIFIED IDEOGRAPH
+0xC35E	0x9F2C	#CJK UNIFIED IDEOGRAPH
+0xC35F	0x5133	#CJK UNIFIED IDEOGRAPH
+0xC360	0x56A5	#CJK UNIFIED IDEOGRAPH
+0xC361	0x58DE	#CJK UNIFIED IDEOGRAPH
+0xC362	0x58DF	#CJK UNIFIED IDEOGRAPH
+0xC363	0x58E2	#CJK UNIFIED IDEOGRAPH
+0xC364	0x5BF5	#CJK UNIFIED IDEOGRAPH
+0xC365	0x9F90	#CJK UNIFIED IDEOGRAPH
+0xC366	0x5EEC	#CJK UNIFIED IDEOGRAPH
+0xC367	0x61F2	#CJK UNIFIED IDEOGRAPH
+0xC368	0x61F7	#CJK UNIFIED IDEOGRAPH
+0xC369	0x61F6	#CJK UNIFIED IDEOGRAPH
+0xC36A	0x61F5	#CJK UNIFIED IDEOGRAPH
+0xC36B	0x6500	#CJK UNIFIED IDEOGRAPH
+0xC36C	0x650F	#CJK UNIFIED IDEOGRAPH
+0xC36D	0x66E0	#CJK UNIFIED IDEOGRAPH
+0xC36E	0x66DD	#CJK UNIFIED IDEOGRAPH
+0xC36F	0x6AE5	#CJK UNIFIED IDEOGRAPH
+0xC370	0x6ADD	#CJK UNIFIED IDEOGRAPH
+0xC371	0x6ADA	#CJK UNIFIED IDEOGRAPH
+0xC372	0x6AD3	#CJK UNIFIED IDEOGRAPH
+0xC373	0x701B	#CJK UNIFIED IDEOGRAPH
+0xC374	0x701F	#CJK UNIFIED IDEOGRAPH
+0xC375	0x7028	#CJK UNIFIED IDEOGRAPH
+0xC376	0x701A	#CJK UNIFIED IDEOGRAPH
+0xC377	0x701D	#CJK UNIFIED IDEOGRAPH
+0xC378	0x7015	#CJK UNIFIED IDEOGRAPH
+0xC379	0x7018	#CJK UNIFIED IDEOGRAPH
+0xC37A	0x7206	#CJK UNIFIED IDEOGRAPH
+0xC37B	0x720D	#CJK UNIFIED IDEOGRAPH
+0xC37C	0x7258	#CJK UNIFIED IDEOGRAPH
+0xC37D	0x72A2	#CJK UNIFIED IDEOGRAPH
+0xC37E	0x7378	#CJK UNIFIED IDEOGRAPH
+0xC3A1	0x737A	#CJK UNIFIED IDEOGRAPH
+0xC3A2	0x74BD	#CJK UNIFIED IDEOGRAPH
+0xC3A3	0x74CA	#CJK UNIFIED IDEOGRAPH
+0xC3A4	0x74E3	#CJK UNIFIED IDEOGRAPH
+0xC3A5	0x7587	#CJK UNIFIED IDEOGRAPH
+0xC3A6	0x7586	#CJK UNIFIED IDEOGRAPH
+0xC3A7	0x765F	#CJK UNIFIED IDEOGRAPH
+0xC3A8	0x7661	#CJK UNIFIED IDEOGRAPH
+0xC3A9	0x77C7	#CJK UNIFIED IDEOGRAPH
+0xC3AA	0x7919	#CJK UNIFIED IDEOGRAPH
+0xC3AB	0x79B1	#CJK UNIFIED IDEOGRAPH
+0xC3AC	0x7A6B	#CJK UNIFIED IDEOGRAPH
+0xC3AD	0x7A69	#CJK UNIFIED IDEOGRAPH
+0xC3AE	0x7C3E	#CJK UNIFIED IDEOGRAPH
+0xC3AF	0x7C3F	#CJK UNIFIED IDEOGRAPH
+0xC3B0	0x7C38	#CJK UNIFIED IDEOGRAPH
+0xC3B1	0x7C3D	#CJK UNIFIED IDEOGRAPH
+0xC3B2	0x7C37	#CJK UNIFIED IDEOGRAPH
+0xC3B3	0x7C40	#CJK UNIFIED IDEOGRAPH
+0xC3B4	0x7E6B	#CJK UNIFIED IDEOGRAPH
+0xC3B5	0x7E6D	#CJK UNIFIED IDEOGRAPH
+0xC3B6	0x7E79	#CJK UNIFIED IDEOGRAPH
+0xC3B7	0x7E69	#CJK UNIFIED IDEOGRAPH
+0xC3B8	0x7E6A	#CJK UNIFIED IDEOGRAPH
+0xC3B9	0x7F85	#CJK UNIFIED IDEOGRAPH
+0xC3BA	0x7E73	#CJK UNIFIED IDEOGRAPH
+0xC3BB	0x7FB6	#CJK UNIFIED IDEOGRAPH
+0xC3BC	0x7FB9	#CJK UNIFIED IDEOGRAPH
+0xC3BD	0x7FB8	#CJK UNIFIED IDEOGRAPH
+0xC3BE	0x81D8	#CJK UNIFIED IDEOGRAPH
+0xC3BF	0x85E9	#CJK UNIFIED IDEOGRAPH
+0xC3C0	0x85DD	#CJK UNIFIED IDEOGRAPH
+0xC3C1	0x85EA	#CJK UNIFIED IDEOGRAPH
+0xC3C2	0x85D5	#CJK UNIFIED IDEOGRAPH
+0xC3C3	0x85E4	#CJK UNIFIED IDEOGRAPH
+0xC3C4	0x85E5	#CJK UNIFIED IDEOGRAPH
+0xC3C5	0x85F7	#CJK UNIFIED IDEOGRAPH
+0xC3C6	0x87FB	#CJK UNIFIED IDEOGRAPH
+0xC3C7	0x8805	#CJK UNIFIED IDEOGRAPH
+0xC3C8	0x880D	#CJK UNIFIED IDEOGRAPH
+0xC3C9	0x87F9	#CJK UNIFIED IDEOGRAPH
+0xC3CA	0x87FE	#CJK UNIFIED IDEOGRAPH
+0xC3CB	0x8960	#CJK UNIFIED IDEOGRAPH
+0xC3CC	0x895F	#CJK UNIFIED IDEOGRAPH
+0xC3CD	0x8956	#CJK UNIFIED IDEOGRAPH
+0xC3CE	0x895E	#CJK UNIFIED IDEOGRAPH
+0xC3CF	0x8B41	#CJK UNIFIED IDEOGRAPH
+0xC3D0	0x8B5C	#CJK UNIFIED IDEOGRAPH
+0xC3D1	0x8B58	#CJK UNIFIED IDEOGRAPH
+0xC3D2	0x8B49	#CJK UNIFIED IDEOGRAPH
+0xC3D3	0x8B5A	#CJK UNIFIED IDEOGRAPH
+0xC3D4	0x8B4E	#CJK UNIFIED IDEOGRAPH
+0xC3D5	0x8B4F	#CJK UNIFIED IDEOGRAPH
+0xC3D6	0x8B46	#CJK UNIFIED IDEOGRAPH
+0xC3D7	0x8B59	#CJK UNIFIED IDEOGRAPH
+0xC3D8	0x8D08	#CJK UNIFIED IDEOGRAPH
+0xC3D9	0x8D0A	#CJK UNIFIED IDEOGRAPH
+0xC3DA	0x8E7C	#CJK UNIFIED IDEOGRAPH
+0xC3DB	0x8E72	#CJK UNIFIED IDEOGRAPH
+0xC3DC	0x8E87	#CJK UNIFIED IDEOGRAPH
+0xC3DD	0x8E76	#CJK UNIFIED IDEOGRAPH
+0xC3DE	0x8E6C	#CJK UNIFIED IDEOGRAPH
+0xC3DF	0x8E7A	#CJK UNIFIED IDEOGRAPH
+0xC3E0	0x8E74	#CJK UNIFIED IDEOGRAPH
+0xC3E1	0x8F54	#CJK UNIFIED IDEOGRAPH
+0xC3E2	0x8F4E	#CJK UNIFIED IDEOGRAPH
+0xC3E3	0x8FAD	#CJK UNIFIED IDEOGRAPH
+0xC3E4	0x908A	#CJK UNIFIED IDEOGRAPH
+0xC3E5	0x908B	#CJK UNIFIED IDEOGRAPH
+0xC3E6	0x91B1	#CJK UNIFIED IDEOGRAPH
+0xC3E7	0x91AE	#CJK UNIFIED IDEOGRAPH
+0xC3E8	0x93E1	#CJK UNIFIED IDEOGRAPH
+0xC3E9	0x93D1	#CJK UNIFIED IDEOGRAPH
+0xC3EA	0x93DF	#CJK UNIFIED IDEOGRAPH
+0xC3EB	0x93C3	#CJK UNIFIED IDEOGRAPH
+0xC3EC	0x93C8	#CJK UNIFIED IDEOGRAPH
+0xC3ED	0x93DC	#CJK UNIFIED IDEOGRAPH
+0xC3EE	0x93DD	#CJK UNIFIED IDEOGRAPH
+0xC3EF	0x93D6	#CJK UNIFIED IDEOGRAPH
+0xC3F0	0x93E2	#CJK UNIFIED IDEOGRAPH
+0xC3F1	0x93CD	#CJK UNIFIED IDEOGRAPH
+0xC3F2	0x93D8	#CJK UNIFIED IDEOGRAPH
+0xC3F3	0x93E4	#CJK UNIFIED IDEOGRAPH
+0xC3F4	0x93D7	#CJK UNIFIED IDEOGRAPH
+0xC3F5	0x93E8	#CJK UNIFIED IDEOGRAPH
+0xC3F6	0x95DC	#CJK UNIFIED IDEOGRAPH
+0xC3F7	0x96B4	#CJK UNIFIED IDEOGRAPH
+0xC3F8	0x96E3	#CJK UNIFIED IDEOGRAPH
+0xC3F9	0x972A	#CJK UNIFIED IDEOGRAPH
+0xC3FA	0x9727	#CJK UNIFIED IDEOGRAPH
+0xC3FB	0x9761	#CJK UNIFIED IDEOGRAPH
+0xC3FC	0x97DC	#CJK UNIFIED IDEOGRAPH
+0xC3FD	0x97FB	#CJK UNIFIED IDEOGRAPH
+0xC3FE	0x985E	#CJK UNIFIED IDEOGRAPH
+0xC440	0x9858	#CJK UNIFIED IDEOGRAPH
+0xC441	0x985B	#CJK UNIFIED IDEOGRAPH
+0xC442	0x98BC	#CJK UNIFIED IDEOGRAPH
+0xC443	0x9945	#CJK UNIFIED IDEOGRAPH
+0xC444	0x9949	#CJK UNIFIED IDEOGRAPH
+0xC445	0x9A16	#CJK UNIFIED IDEOGRAPH
+0xC446	0x9A19	#CJK UNIFIED IDEOGRAPH
+0xC447	0x9B0D	#CJK UNIFIED IDEOGRAPH
+0xC448	0x9BE8	#CJK UNIFIED IDEOGRAPH
+0xC449	0x9BE7	#CJK UNIFIED IDEOGRAPH
+0xC44A	0x9BD6	#CJK UNIFIED IDEOGRAPH
+0xC44B	0x9BDB	#CJK UNIFIED IDEOGRAPH
+0xC44C	0x9D89	#CJK UNIFIED IDEOGRAPH
+0xC44D	0x9D61	#CJK UNIFIED IDEOGRAPH
+0xC44E	0x9D72	#CJK UNIFIED IDEOGRAPH
+0xC44F	0x9D6A	#CJK UNIFIED IDEOGRAPH
+0xC450	0x9D6C	#CJK UNIFIED IDEOGRAPH
+0xC451	0x9E92	#CJK UNIFIED IDEOGRAPH
+0xC452	0x9E97	#CJK UNIFIED IDEOGRAPH
+0xC453	0x9E93	#CJK UNIFIED IDEOGRAPH
+0xC454	0x9EB4	#CJK UNIFIED IDEOGRAPH
+0xC455	0x52F8	#CJK UNIFIED IDEOGRAPH
+0xC456	0x56A8	#CJK UNIFIED IDEOGRAPH
+0xC457	0x56B7	#CJK UNIFIED IDEOGRAPH
+0xC458	0x56B6	#CJK UNIFIED IDEOGRAPH
+0xC459	0x56B4	#CJK UNIFIED IDEOGRAPH
+0xC45A	0x56BC	#CJK UNIFIED IDEOGRAPH
+0xC45B	0x58E4	#CJK UNIFIED IDEOGRAPH
+0xC45C	0x5B40	#CJK UNIFIED IDEOGRAPH
+0xC45D	0x5B43	#CJK UNIFIED IDEOGRAPH
+0xC45E	0x5B7D	#CJK UNIFIED IDEOGRAPH
+0xC45F	0x5BF6	#CJK UNIFIED IDEOGRAPH
+0xC460	0x5DC9	#CJK UNIFIED IDEOGRAPH
+0xC461	0x61F8	#CJK UNIFIED IDEOGRAPH
+0xC462	0x61FA	#CJK UNIFIED IDEOGRAPH
+0xC463	0x6518	#CJK UNIFIED IDEOGRAPH
+0xC464	0x6514	#CJK UNIFIED IDEOGRAPH
+0xC465	0x6519	#CJK UNIFIED IDEOGRAPH
+0xC466	0x66E6	#CJK UNIFIED IDEOGRAPH
+0xC467	0x6727	#CJK UNIFIED IDEOGRAPH
+0xC468	0x6AEC	#CJK UNIFIED IDEOGRAPH
+0xC469	0x703E	#CJK UNIFIED IDEOGRAPH
+0xC46A	0x7030	#CJK UNIFIED IDEOGRAPH
+0xC46B	0x7032	#CJK UNIFIED IDEOGRAPH
+0xC46C	0x7210	#CJK UNIFIED IDEOGRAPH
+0xC46D	0x737B	#CJK UNIFIED IDEOGRAPH
+0xC46E	0x74CF	#CJK UNIFIED IDEOGRAPH
+0xC46F	0x7662	#CJK UNIFIED IDEOGRAPH
+0xC470	0x7665	#CJK UNIFIED IDEOGRAPH
+0xC471	0x7926	#CJK UNIFIED IDEOGRAPH
+0xC472	0x792A	#CJK UNIFIED IDEOGRAPH
+0xC473	0x792C	#CJK UNIFIED IDEOGRAPH
+0xC474	0x792B	#CJK UNIFIED IDEOGRAPH
+0xC475	0x7AC7	#CJK UNIFIED IDEOGRAPH
+0xC476	0x7AF6	#CJK UNIFIED IDEOGRAPH
+0xC477	0x7C4C	#CJK UNIFIED IDEOGRAPH
+0xC478	0x7C43	#CJK UNIFIED IDEOGRAPH
+0xC479	0x7C4D	#CJK UNIFIED IDEOGRAPH
+0xC47A	0x7CEF	#CJK UNIFIED IDEOGRAPH
+0xC47B	0x7CF0	#CJK UNIFIED IDEOGRAPH
+0xC47C	0x8FAE	#CJK UNIFIED IDEOGRAPH
+0xC47D	0x7E7D	#CJK UNIFIED IDEOGRAPH
+0xC47E	0x7E7C	#CJK UNIFIED IDEOGRAPH
+0xC4A1	0x7E82	#CJK UNIFIED IDEOGRAPH
+0xC4A2	0x7F4C	#CJK UNIFIED IDEOGRAPH
+0xC4A3	0x8000	#CJK UNIFIED IDEOGRAPH
+0xC4A4	0x81DA	#CJK UNIFIED IDEOGRAPH
+0xC4A5	0x8266	#CJK UNIFIED IDEOGRAPH
+0xC4A6	0x85FB	#CJK UNIFIED IDEOGRAPH
+0xC4A7	0x85F9	#CJK UNIFIED IDEOGRAPH
+0xC4A8	0x8611	#CJK UNIFIED IDEOGRAPH
+0xC4A9	0x85FA	#CJK UNIFIED IDEOGRAPH
+0xC4AA	0x8606	#CJK UNIFIED IDEOGRAPH
+0xC4AB	0x860B	#CJK UNIFIED IDEOGRAPH
+0xC4AC	0x8607	#CJK UNIFIED IDEOGRAPH
+0xC4AD	0x860A	#CJK UNIFIED IDEOGRAPH
+0xC4AE	0x8814	#CJK UNIFIED IDEOGRAPH
+0xC4AF	0x8815	#CJK UNIFIED IDEOGRAPH
+0xC4B0	0x8964	#CJK UNIFIED IDEOGRAPH
+0xC4B1	0x89BA	#CJK UNIFIED IDEOGRAPH
+0xC4B2	0x89F8	#CJK UNIFIED IDEOGRAPH
+0xC4B3	0x8B70	#CJK UNIFIED IDEOGRAPH
+0xC4B4	0x8B6C	#CJK UNIFIED IDEOGRAPH
+0xC4B5	0x8B66	#CJK UNIFIED IDEOGRAPH
+0xC4B6	0x8B6F	#CJK UNIFIED IDEOGRAPH
+0xC4B7	0x8B5F	#CJK UNIFIED IDEOGRAPH
+0xC4B8	0x8B6B	#CJK UNIFIED IDEOGRAPH
+0xC4B9	0x8D0F	#CJK UNIFIED IDEOGRAPH
+0xC4BA	0x8D0D	#CJK UNIFIED IDEOGRAPH
+0xC4BB	0x8E89	#CJK UNIFIED IDEOGRAPH
+0xC4BC	0x8E81	#CJK UNIFIED IDEOGRAPH
+0xC4BD	0x8E85	#CJK UNIFIED IDEOGRAPH
+0xC4BE	0x8E82	#CJK UNIFIED IDEOGRAPH
+0xC4BF	0x91B4	#CJK UNIFIED IDEOGRAPH
+0xC4C0	0x91CB	#CJK UNIFIED IDEOGRAPH
+0xC4C1	0x9418	#CJK UNIFIED IDEOGRAPH
+0xC4C2	0x9403	#CJK UNIFIED IDEOGRAPH
+0xC4C3	0x93FD	#CJK UNIFIED IDEOGRAPH
+0xC4C4	0x95E1	#CJK UNIFIED IDEOGRAPH
+0xC4C5	0x9730	#CJK UNIFIED IDEOGRAPH
+0xC4C6	0x98C4	#CJK UNIFIED IDEOGRAPH
+0xC4C7	0x9952	#CJK UNIFIED IDEOGRAPH
+0xC4C8	0x9951	#CJK UNIFIED IDEOGRAPH
+0xC4C9	0x99A8	#CJK UNIFIED IDEOGRAPH
+0xC4CA	0x9A2B	#CJK UNIFIED IDEOGRAPH
+0xC4CB	0x9A30	#CJK UNIFIED IDEOGRAPH
+0xC4CC	0x9A37	#CJK UNIFIED IDEOGRAPH
+0xC4CD	0x9A35	#CJK UNIFIED IDEOGRAPH
+0xC4CE	0x9C13	#CJK UNIFIED IDEOGRAPH
+0xC4CF	0x9C0D	#CJK UNIFIED IDEOGRAPH
+0xC4D0	0x9E79	#CJK UNIFIED IDEOGRAPH
+0xC4D1	0x9EB5	#CJK UNIFIED IDEOGRAPH
+0xC4D2	0x9EE8	#CJK UNIFIED IDEOGRAPH
+0xC4D3	0x9F2F	#CJK UNIFIED IDEOGRAPH
+0xC4D4	0x9F5F	#CJK UNIFIED IDEOGRAPH
+0xC4D5	0x9F63	#CJK UNIFIED IDEOGRAPH
+0xC4D6	0x9F61	#CJK UNIFIED IDEOGRAPH
+0xC4D7	0x5137	#CJK UNIFIED IDEOGRAPH
+0xC4D8	0x5138	#CJK UNIFIED IDEOGRAPH
+0xC4D9	0x56C1	#CJK UNIFIED IDEOGRAPH
+0xC4DA	0x56C0	#CJK UNIFIED IDEOGRAPH
+0xC4DB	0x56C2	#CJK UNIFIED IDEOGRAPH
+0xC4DC	0x5914	#CJK UNIFIED IDEOGRAPH
+0xC4DD	0x5C6C	#CJK UNIFIED IDEOGRAPH
+0xC4DE	0x5DCD	#CJK UNIFIED IDEOGRAPH
+0xC4DF	0x61FC	#CJK UNIFIED IDEOGRAPH
+0xC4E0	0x61FE	#CJK UNIFIED IDEOGRAPH
+0xC4E1	0x651D	#CJK UNIFIED IDEOGRAPH
+0xC4E2	0x651C	#CJK UNIFIED IDEOGRAPH
+0xC4E3	0x6595	#CJK UNIFIED IDEOGRAPH
+0xC4E4	0x66E9	#CJK UNIFIED IDEOGRAPH
+0xC4E5	0x6AFB	#CJK UNIFIED IDEOGRAPH
+0xC4E6	0x6B04	#CJK UNIFIED IDEOGRAPH
+0xC4E7	0x6AFA	#CJK UNIFIED IDEOGRAPH
+0xC4E8	0x6BB2	#CJK UNIFIED IDEOGRAPH
+0xC4E9	0x704C	#CJK UNIFIED IDEOGRAPH
+0xC4EA	0x721B	#CJK UNIFIED IDEOGRAPH
+0xC4EB	0x72A7	#CJK UNIFIED IDEOGRAPH
+0xC4EC	0x74D6	#CJK UNIFIED IDEOGRAPH
+0xC4ED	0x74D4	#CJK UNIFIED IDEOGRAPH
+0xC4EE	0x7669	#CJK UNIFIED IDEOGRAPH
+0xC4EF	0x77D3	#CJK UNIFIED IDEOGRAPH
+0xC4F0	0x7C50	#CJK UNIFIED IDEOGRAPH
+0xC4F1	0x7E8F	#CJK UNIFIED IDEOGRAPH
+0xC4F2	0x7E8C	#CJK UNIFIED IDEOGRAPH
+0xC4F3	0x7FBC	#CJK UNIFIED IDEOGRAPH
+0xC4F4	0x8617	#CJK UNIFIED IDEOGRAPH
+0xC4F5	0x862D	#CJK UNIFIED IDEOGRAPH
+0xC4F6	0x861A	#CJK UNIFIED IDEOGRAPH
+0xC4F7	0x8823	#CJK UNIFIED IDEOGRAPH
+0xC4F8	0x8822	#CJK UNIFIED IDEOGRAPH
+0xC4F9	0x8821	#CJK UNIFIED IDEOGRAPH
+0xC4FA	0x881F	#CJK UNIFIED IDEOGRAPH
+0xC4FB	0x896A	#CJK UNIFIED IDEOGRAPH
+0xC4FC	0x896C	#CJK UNIFIED IDEOGRAPH
+0xC4FD	0x89BD	#CJK UNIFIED IDEOGRAPH
+0xC4FE	0x8B74	#CJK UNIFIED IDEOGRAPH
+0xC540	0x8B77	#CJK UNIFIED IDEOGRAPH
+0xC541	0x8B7D	#CJK UNIFIED IDEOGRAPH
+0xC542	0x8D13	#CJK UNIFIED IDEOGRAPH
+0xC543	0x8E8A	#CJK UNIFIED IDEOGRAPH
+0xC544	0x8E8D	#CJK UNIFIED IDEOGRAPH
+0xC545	0x8E8B	#CJK UNIFIED IDEOGRAPH
+0xC546	0x8F5F	#CJK UNIFIED IDEOGRAPH
+0xC547	0x8FAF	#CJK UNIFIED IDEOGRAPH
+0xC548	0x91BA	#CJK UNIFIED IDEOGRAPH
+0xC549	0x942E	#CJK UNIFIED IDEOGRAPH
+0xC54A	0x9433	#CJK UNIFIED IDEOGRAPH
+0xC54B	0x9435	#CJK UNIFIED IDEOGRAPH
+0xC54C	0x943A	#CJK UNIFIED IDEOGRAPH
+0xC54D	0x9438	#CJK UNIFIED IDEOGRAPH
+0xC54E	0x9432	#CJK UNIFIED IDEOGRAPH
+0xC54F	0x942B	#CJK UNIFIED IDEOGRAPH
+0xC550	0x95E2	#CJK UNIFIED IDEOGRAPH
+0xC551	0x9738	#CJK UNIFIED IDEOGRAPH
+0xC552	0x9739	#CJK UNIFIED IDEOGRAPH
+0xC553	0x9732	#CJK UNIFIED IDEOGRAPH
+0xC554	0x97FF	#CJK UNIFIED IDEOGRAPH
+0xC555	0x9867	#CJK UNIFIED IDEOGRAPH
+0xC556	0x9865	#CJK UNIFIED IDEOGRAPH
+0xC557	0x9957	#CJK UNIFIED IDEOGRAPH
+0xC558	0x9A45	#CJK UNIFIED IDEOGRAPH
+0xC559	0x9A43	#CJK UNIFIED IDEOGRAPH
+0xC55A	0x9A40	#CJK UNIFIED IDEOGRAPH
+0xC55B	0x9A3E	#CJK UNIFIED IDEOGRAPH
+0xC55C	0x9ACF	#CJK UNIFIED IDEOGRAPH
+0xC55D	0x9B54	#CJK UNIFIED IDEOGRAPH
+0xC55E	0x9B51	#CJK UNIFIED IDEOGRAPH
+0xC55F	0x9C2D	#CJK UNIFIED IDEOGRAPH
+0xC560	0x9C25	#CJK UNIFIED IDEOGRAPH
+0xC561	0x9DAF	#CJK UNIFIED IDEOGRAPH
+0xC562	0x9DB4	#CJK UNIFIED IDEOGRAPH
+0xC563	0x9DC2	#CJK UNIFIED IDEOGRAPH
+0xC564	0x9DB8	#CJK UNIFIED IDEOGRAPH
+0xC565	0x9E9D	#CJK UNIFIED IDEOGRAPH
+0xC566	0x9EEF	#CJK UNIFIED IDEOGRAPH
+0xC567	0x9F19	#CJK UNIFIED IDEOGRAPH
+0xC568	0x9F5C	#CJK UNIFIED IDEOGRAPH
+0xC569	0x9F66	#CJK UNIFIED IDEOGRAPH
+0xC56A	0x9F67	#CJK UNIFIED IDEOGRAPH
+0xC56B	0x513C	#CJK UNIFIED IDEOGRAPH
+0xC56C	0x513B	#CJK UNIFIED IDEOGRAPH
+0xC56D	0x56C8	#CJK UNIFIED IDEOGRAPH
+0xC56E	0x56CA	#CJK UNIFIED IDEOGRAPH
+0xC56F	0x56C9	#CJK UNIFIED IDEOGRAPH
+0xC570	0x5B7F	#CJK UNIFIED IDEOGRAPH
+0xC571	0x5DD4	#CJK UNIFIED IDEOGRAPH
+0xC572	0x5DD2	#CJK UNIFIED IDEOGRAPH
+0xC573	0x5F4E	#CJK UNIFIED IDEOGRAPH
+0xC574	0x61FF	#CJK UNIFIED IDEOGRAPH
+0xC575	0x6524	#CJK UNIFIED IDEOGRAPH
+0xC576	0x6B0A	#CJK UNIFIED IDEOGRAPH
+0xC577	0x6B61	#CJK UNIFIED IDEOGRAPH
+0xC578	0x7051	#CJK UNIFIED IDEOGRAPH
+0xC579	0x7058	#CJK UNIFIED IDEOGRAPH
+0xC57A	0x7380	#CJK UNIFIED IDEOGRAPH
+0xC57B	0x74E4	#CJK UNIFIED IDEOGRAPH
+0xC57C	0x758A	#CJK UNIFIED IDEOGRAPH
+0xC57D	0x766E	#CJK UNIFIED IDEOGRAPH
+0xC57E	0x766C	#CJK UNIFIED IDEOGRAPH
+0xC5A1	0x79B3	#CJK UNIFIED IDEOGRAPH
+0xC5A2	0x7C60	#CJK UNIFIED IDEOGRAPH
+0xC5A3	0x7C5F	#CJK UNIFIED IDEOGRAPH
+0xC5A4	0x807E	#CJK UNIFIED IDEOGRAPH
+0xC5A5	0x807D	#CJK UNIFIED IDEOGRAPH
+0xC5A6	0x81DF	#CJK UNIFIED IDEOGRAPH
+0xC5A7	0x8972	#CJK UNIFIED IDEOGRAPH
+0xC5A8	0x896F	#CJK UNIFIED IDEOGRAPH
+0xC5A9	0x89FC	#CJK UNIFIED IDEOGRAPH
+0xC5AA	0x8B80	#CJK UNIFIED IDEOGRAPH
+0xC5AB	0x8D16	#CJK UNIFIED IDEOGRAPH
+0xC5AC	0x8D17	#CJK UNIFIED IDEOGRAPH
+0xC5AD	0x8E91	#CJK UNIFIED IDEOGRAPH
+0xC5AE	0x8E93	#CJK UNIFIED IDEOGRAPH
+0xC5AF	0x8F61	#CJK UNIFIED IDEOGRAPH
+0xC5B0	0x9148	#CJK UNIFIED IDEOGRAPH
+0xC5B1	0x9444	#CJK UNIFIED IDEOGRAPH
+0xC5B2	0x9451	#CJK UNIFIED IDEOGRAPH
+0xC5B3	0x9452	#CJK UNIFIED IDEOGRAPH
+0xC5B4	0x973D	#CJK UNIFIED IDEOGRAPH
+0xC5B5	0x973E	#CJK UNIFIED IDEOGRAPH
+0xC5B6	0x97C3	#CJK UNIFIED IDEOGRAPH
+0xC5B7	0x97C1	#CJK UNIFIED IDEOGRAPH
+0xC5B8	0x986B	#CJK UNIFIED IDEOGRAPH
+0xC5B9	0x9955	#CJK UNIFIED IDEOGRAPH
+0xC5BA	0x9A55	#CJK UNIFIED IDEOGRAPH
+0xC5BB	0x9A4D	#CJK UNIFIED IDEOGRAPH
+0xC5BC	0x9AD2	#CJK UNIFIED IDEOGRAPH
+0xC5BD	0x9B1A	#CJK UNIFIED IDEOGRAPH
+0xC5BE	0x9C49	#CJK UNIFIED IDEOGRAPH
+0xC5BF	0x9C31	#CJK UNIFIED IDEOGRAPH
+0xC5C0	0x9C3E	#CJK UNIFIED IDEOGRAPH
+0xC5C1	0x9C3B	#CJK UNIFIED IDEOGRAPH
+0xC5C2	0x9DD3	#CJK UNIFIED IDEOGRAPH
+0xC5C3	0x9DD7	#CJK UNIFIED IDEOGRAPH
+0xC5C4	0x9F34	#CJK UNIFIED IDEOGRAPH
+0xC5C5	0x9F6C	#CJK UNIFIED IDEOGRAPH
+0xC5C6	0x9F6A	#CJK UNIFIED IDEOGRAPH
+0xC5C7	0x9F94	#CJK UNIFIED IDEOGRAPH
+0xC5C8	0x56CC	#CJK UNIFIED IDEOGRAPH
+0xC5C9	0x5DD6	#CJK UNIFIED IDEOGRAPH
+0xC5CA	0x6200	#CJK UNIFIED IDEOGRAPH
+0xC5CB	0x6523	#CJK UNIFIED IDEOGRAPH
+0xC5CC	0x652B	#CJK UNIFIED IDEOGRAPH
+0xC5CD	0x652A	#CJK UNIFIED IDEOGRAPH
+0xC5CE	0x66EC	#CJK UNIFIED IDEOGRAPH
+0xC5CF	0x6B10	#CJK UNIFIED IDEOGRAPH
+0xC5D0	0x74DA	#CJK UNIFIED IDEOGRAPH
+0xC5D1	0x7ACA	#CJK UNIFIED IDEOGRAPH
+0xC5D2	0x7C64	#CJK UNIFIED IDEOGRAPH
+0xC5D3	0x7C63	#CJK UNIFIED IDEOGRAPH
+0xC5D4	0x7C65	#CJK UNIFIED IDEOGRAPH
+0xC5D5	0x7E93	#CJK UNIFIED IDEOGRAPH
+0xC5D6	0x7E96	#CJK UNIFIED IDEOGRAPH
+0xC5D7	0x7E94	#CJK UNIFIED IDEOGRAPH
+0xC5D8	0x81E2	#CJK UNIFIED IDEOGRAPH
+0xC5D9	0x8638	#CJK UNIFIED IDEOGRAPH
+0xC5DA	0x863F	#CJK UNIFIED IDEOGRAPH
+0xC5DB	0x8831	#CJK UNIFIED IDEOGRAPH
+0xC5DC	0x8B8A	#CJK UNIFIED IDEOGRAPH
+0xC5DD	0x9090	#CJK UNIFIED IDEOGRAPH
+0xC5DE	0x908F	#CJK UNIFIED IDEOGRAPH
+0xC5DF	0x9463	#CJK UNIFIED IDEOGRAPH
+0xC5E0	0x9460	#CJK UNIFIED IDEOGRAPH
+0xC5E1	0x9464	#CJK UNIFIED IDEOGRAPH
+0xC5E2	0x9768	#CJK UNIFIED IDEOGRAPH
+0xC5E3	0x986F	#CJK UNIFIED IDEOGRAPH
+0xC5E4	0x995C	#CJK UNIFIED IDEOGRAPH
+0xC5E5	0x9A5A	#CJK UNIFIED IDEOGRAPH
+0xC5E6	0x9A5B	#CJK UNIFIED IDEOGRAPH
+0xC5E7	0x9A57	#CJK UNIFIED IDEOGRAPH
+0xC5E8	0x9AD3	#CJK UNIFIED IDEOGRAPH
+0xC5E9	0x9AD4	#CJK UNIFIED IDEOGRAPH
+0xC5EA	0x9AD1	#CJK UNIFIED IDEOGRAPH
+0xC5EB	0x9C54	#CJK UNIFIED IDEOGRAPH
+0xC5EC	0x9C57	#CJK UNIFIED IDEOGRAPH
+0xC5ED	0x9C56	#CJK UNIFIED IDEOGRAPH
+0xC5EE	0x9DE5	#CJK UNIFIED IDEOGRAPH
+0xC5EF	0x9E9F	#CJK UNIFIED IDEOGRAPH
+0xC5F0	0x9EF4	#CJK UNIFIED IDEOGRAPH
+0xC5F1	0x56D1	#CJK UNIFIED IDEOGRAPH
+0xC5F2	0x58E9	#CJK UNIFIED IDEOGRAPH
+0xC5F3	0x652C	#CJK UNIFIED IDEOGRAPH
+0xC5F4	0x705E	#CJK UNIFIED IDEOGRAPH
+0xC5F5	0x7671	#CJK UNIFIED IDEOGRAPH
+0xC5F6	0x7672	#CJK UNIFIED IDEOGRAPH
+0xC5F7	0x77D7	#CJK UNIFIED IDEOGRAPH
+0xC5F8	0x7F50	#CJK UNIFIED IDEOGRAPH
+0xC5F9	0x7F88	#CJK UNIFIED IDEOGRAPH
+0xC5FA	0x8836	#CJK UNIFIED IDEOGRAPH
+0xC5FB	0x8839	#CJK UNIFIED IDEOGRAPH
+0xC5FC	0x8862	#CJK UNIFIED IDEOGRAPH
+0xC5FD	0x8B93	#CJK UNIFIED IDEOGRAPH
+0xC5FE	0x8B92	#CJK UNIFIED IDEOGRAPH
+0xC640	0x8B96	#CJK UNIFIED IDEOGRAPH
+0xC641	0x8277	#CJK UNIFIED IDEOGRAPH
+0xC642	0x8D1B	#CJK UNIFIED IDEOGRAPH
+0xC643	0x91C0	#CJK UNIFIED IDEOGRAPH
+0xC644	0x946A	#CJK UNIFIED IDEOGRAPH
+0xC645	0x9742	#CJK UNIFIED IDEOGRAPH
+0xC646	0x9748	#CJK UNIFIED IDEOGRAPH
+0xC647	0x9744	#CJK UNIFIED IDEOGRAPH
+0xC648	0x97C6	#CJK UNIFIED IDEOGRAPH
+0xC649	0x9870	#CJK UNIFIED IDEOGRAPH
+0xC64A	0x9A5F	#CJK UNIFIED IDEOGRAPH
+0xC64B	0x9B22	#CJK UNIFIED IDEOGRAPH
+0xC64C	0x9B58	#CJK UNIFIED IDEOGRAPH
+0xC64D	0x9C5F	#CJK UNIFIED IDEOGRAPH
+0xC64E	0x9DF9	#CJK UNIFIED IDEOGRAPH
+0xC64F	0x9DFA	#CJK UNIFIED IDEOGRAPH
+0xC650	0x9E7C	#CJK UNIFIED IDEOGRAPH
+0xC651	0x9E7D	#CJK UNIFIED IDEOGRAPH
+0xC652	0x9F07	#CJK UNIFIED IDEOGRAPH
+0xC653	0x9F77	#CJK UNIFIED IDEOGRAPH
+0xC654	0x9F72	#CJK UNIFIED IDEOGRAPH
+0xC655	0x5EF3	#CJK UNIFIED IDEOGRAPH
+0xC656	0x6B16	#CJK UNIFIED IDEOGRAPH
+0xC657	0x7063	#CJK UNIFIED IDEOGRAPH
+0xC658	0x7C6C	#CJK UNIFIED IDEOGRAPH
+0xC659	0x7C6E	#CJK UNIFIED IDEOGRAPH
+0xC65A	0x883B	#CJK UNIFIED IDEOGRAPH
+0xC65B	0x89C0	#CJK UNIFIED IDEOGRAPH
+0xC65C	0x8EA1	#CJK UNIFIED IDEOGRAPH
+0xC65D	0x91C1	#CJK UNIFIED IDEOGRAPH
+0xC65E	0x9472	#CJK UNIFIED IDEOGRAPH
+0xC65F	0x9470	#CJK UNIFIED IDEOGRAPH
+0xC660	0x9871	#CJK UNIFIED IDEOGRAPH
+0xC661	0x995E	#CJK UNIFIED IDEOGRAPH
+0xC662	0x9AD6	#CJK UNIFIED IDEOGRAPH
+0xC663	0x9B23	#CJK UNIFIED IDEOGRAPH
+0xC664	0x9ECC	#CJK UNIFIED IDEOGRAPH
+0xC665	0x7064	#CJK UNIFIED IDEOGRAPH
+0xC666	0x77DA	#CJK UNIFIED IDEOGRAPH
+0xC667	0x8B9A	#CJK UNIFIED IDEOGRAPH
+0xC668	0x9477	#CJK UNIFIED IDEOGRAPH
+0xC669	0x97C9	#CJK UNIFIED IDEOGRAPH
+0xC66A	0x9A62	#CJK UNIFIED IDEOGRAPH
+0xC66B	0x9A65	#CJK UNIFIED IDEOGRAPH
+0xC66C	0x7E9C	#CJK UNIFIED IDEOGRAPH
+0xC66D	0x8B9C	#CJK UNIFIED IDEOGRAPH
+0xC66E	0x8EAA	#CJK UNIFIED IDEOGRAPH
+0xC66F	0x91C5	#CJK UNIFIED IDEOGRAPH
+0xC670	0x947D	#CJK UNIFIED IDEOGRAPH
+0xC671	0x947E	#CJK UNIFIED IDEOGRAPH
+0xC672	0x947C	#CJK UNIFIED IDEOGRAPH
+0xC673	0x9C77	#CJK UNIFIED IDEOGRAPH
+0xC674	0x9C78	#CJK UNIFIED IDEOGRAPH
+0xC675	0x9EF7	#CJK UNIFIED IDEOGRAPH
+0xC676	0x8C54	#CJK UNIFIED IDEOGRAPH
+0xC677	0x947F	#CJK UNIFIED IDEOGRAPH
+0xC678	0x9E1A	#CJK UNIFIED IDEOGRAPH
+0xC679	0x7228	#CJK UNIFIED IDEOGRAPH
+0xC67A	0x9A6A	#CJK UNIFIED IDEOGRAPH
+0xC67B	0x9B31	#CJK UNIFIED IDEOGRAPH
+0xC67C	0x9E1B	#CJK UNIFIED IDEOGRAPH
+0xC67D	0x9E1E	#CJK UNIFIED IDEOGRAPH
+0xC67E	0x7C72	#CJK UNIFIED IDEOGRAPH
+0xC940	0x4E42	#CJK UNIFIED IDEOGRAPH
+0xC941	0x4E5C	#CJK UNIFIED IDEOGRAPH
+0xC942	0x51F5	#CJK UNIFIED IDEOGRAPH
+0xC943	0x531A	#CJK UNIFIED IDEOGRAPH
+0xC944	0x5382	#CJK UNIFIED IDEOGRAPH
+0xC945	0x4E07	#CJK UNIFIED IDEOGRAPH
+0xC946	0x4E0C	#CJK UNIFIED IDEOGRAPH
+0xC947	0x4E47	#CJK UNIFIED IDEOGRAPH
+0xC948	0x4E8D	#CJK UNIFIED IDEOGRAPH
+0xC949	0x56D7	#CJK UNIFIED IDEOGRAPH
+0xC94A	0xFA0C	#CJK COMPATIBILITY IDEOGRAPH
+0xC94B	0x5C6E	#CJK UNIFIED IDEOGRAPH
+0xC94C	0x5F73	#CJK UNIFIED IDEOGRAPH
+0xC94D	0x4E0F	#CJK UNIFIED IDEOGRAPH
+0xC94E	0x5187	#CJK UNIFIED IDEOGRAPH
+0xC94F	0x4E0E	#CJK UNIFIED IDEOGRAPH
+0xC950	0x4E2E	#CJK UNIFIED IDEOGRAPH
+0xC951	0x4E93	#CJK UNIFIED IDEOGRAPH
+0xC952	0x4EC2	#CJK UNIFIED IDEOGRAPH
+0xC953	0x4EC9	#CJK UNIFIED IDEOGRAPH
+0xC954	0x4EC8	#CJK UNIFIED IDEOGRAPH
+0xC955	0x5198	#CJK UNIFIED IDEOGRAPH
+0xC956	0x52FC	#CJK UNIFIED IDEOGRAPH
+0xC957	0x536C	#CJK UNIFIED IDEOGRAPH
+0xC958	0x53B9	#CJK UNIFIED IDEOGRAPH
+0xC959	0x5720	#CJK UNIFIED IDEOGRAPH
+0xC95A	0x5903	#CJK UNIFIED IDEOGRAPH
+0xC95B	0x592C	#CJK UNIFIED IDEOGRAPH
+0xC95C	0x5C10	#CJK UNIFIED IDEOGRAPH
+0xC95D	0x5DFF	#CJK UNIFIED IDEOGRAPH
+0xC95E	0x65E1	#CJK UNIFIED IDEOGRAPH
+0xC95F	0x6BB3	#CJK UNIFIED IDEOGRAPH
+0xC960	0x6BCC	#CJK UNIFIED IDEOGRAPH
+0xC961	0x6C14	#CJK UNIFIED IDEOGRAPH
+0xC962	0x723F	#CJK UNIFIED IDEOGRAPH
+0xC963	0x4E31	#CJK UNIFIED IDEOGRAPH
+0xC964	0x4E3C	#CJK UNIFIED IDEOGRAPH
+0xC965	0x4EE8	#CJK UNIFIED IDEOGRAPH
+0xC966	0x4EDC	#CJK UNIFIED IDEOGRAPH
+0xC967	0x4EE9	#CJK UNIFIED IDEOGRAPH
+0xC968	0x4EE1	#CJK UNIFIED IDEOGRAPH
+0xC969	0x4EDD	#CJK UNIFIED IDEOGRAPH
+0xC96A	0x4EDA	#CJK UNIFIED IDEOGRAPH
+0xC96B	0x520C	#CJK UNIFIED IDEOGRAPH
+0xC96C	0x531C	#CJK UNIFIED IDEOGRAPH
+0xC96D	0x534C	#CJK UNIFIED IDEOGRAPH
+0xC96E	0x5722	#CJK UNIFIED IDEOGRAPH
+0xC96F	0x5723	#CJK UNIFIED IDEOGRAPH
+0xC970	0x5917	#CJK UNIFIED IDEOGRAPH
+0xC971	0x592F	#CJK UNIFIED IDEOGRAPH
+0xC972	0x5B81	#CJK UNIFIED IDEOGRAPH
+0xC973	0x5B84	#CJK UNIFIED IDEOGRAPH
+0xC974	0x5C12	#CJK UNIFIED IDEOGRAPH
+0xC975	0x5C3B	#CJK UNIFIED IDEOGRAPH
+0xC976	0x5C74	#CJK UNIFIED IDEOGRAPH
+0xC977	0x5C73	#CJK UNIFIED IDEOGRAPH
+0xC978	0x5E04	#CJK UNIFIED IDEOGRAPH
+0xC979	0x5E80	#CJK UNIFIED IDEOGRAPH
+0xC97A	0x5E82	#CJK UNIFIED IDEOGRAPH
+0xC97B	0x5FC9	#CJK UNIFIED IDEOGRAPH
+0xC97C	0x6209	#CJK UNIFIED IDEOGRAPH
+0xC97D	0x6250	#CJK UNIFIED IDEOGRAPH
+0xC97E	0x6C15	#CJK UNIFIED IDEOGRAPH
+0xC9A1	0x6C36	#CJK UNIFIED IDEOGRAPH
+0xC9A2	0x6C43	#CJK UNIFIED IDEOGRAPH
+0xC9A3	0x6C3F	#CJK UNIFIED IDEOGRAPH
+0xC9A4	0x6C3B	#CJK UNIFIED IDEOGRAPH
+0xC9A5	0x72AE	#CJK UNIFIED IDEOGRAPH
+0xC9A6	0x72B0	#CJK UNIFIED IDEOGRAPH
+0xC9A7	0x738A	#CJK UNIFIED IDEOGRAPH
+0xC9A8	0x79B8	#CJK UNIFIED IDEOGRAPH
+0xC9A9	0x808A	#CJK UNIFIED IDEOGRAPH
+0xC9AA	0x961E	#CJK UNIFIED IDEOGRAPH
+0xC9AB	0x4F0E	#CJK UNIFIED IDEOGRAPH
+0xC9AC	0x4F18	#CJK UNIFIED IDEOGRAPH
+0xC9AD	0x4F2C	#CJK UNIFIED IDEOGRAPH
+0xC9AE	0x4EF5	#CJK UNIFIED IDEOGRAPH
+0xC9AF	0x4F14	#CJK UNIFIED IDEOGRAPH
+0xC9B0	0x4EF1	#CJK UNIFIED IDEOGRAPH
+0xC9B1	0x4F00	#CJK UNIFIED IDEOGRAPH
+0xC9B2	0x4EF7	#CJK UNIFIED IDEOGRAPH
+0xC9B3	0x4F08	#CJK UNIFIED IDEOGRAPH
+0xC9B4	0x4F1D	#CJK UNIFIED IDEOGRAPH
+0xC9B5	0x4F02	#CJK UNIFIED IDEOGRAPH
+0xC9B6	0x4F05	#CJK UNIFIED IDEOGRAPH
+0xC9B7	0x4F22	#CJK UNIFIED IDEOGRAPH
+0xC9B8	0x4F13	#CJK UNIFIED IDEOGRAPH
+0xC9B9	0x4F04	#CJK UNIFIED IDEOGRAPH
+0xC9BA	0x4EF4	#CJK UNIFIED IDEOGRAPH
+0xC9BB	0x4F12	#CJK UNIFIED IDEOGRAPH
+0xC9BC	0x51B1	#CJK UNIFIED IDEOGRAPH
+0xC9BD	0x5213	#CJK UNIFIED IDEOGRAPH
+0xC9BE	0x5209	#CJK UNIFIED IDEOGRAPH
+0xC9BF	0x5210	#CJK UNIFIED IDEOGRAPH
+0xC9C0	0x52A6	#CJK UNIFIED IDEOGRAPH
+0xC9C1	0x5322	#CJK UNIFIED IDEOGRAPH
+0xC9C2	0x531F	#CJK UNIFIED IDEOGRAPH
+0xC9C3	0x534D	#CJK UNIFIED IDEOGRAPH
+0xC9C4	0x538A	#CJK UNIFIED IDEOGRAPH
+0xC9C5	0x5407	#CJK UNIFIED IDEOGRAPH
+0xC9C6	0x56E1	#CJK UNIFIED IDEOGRAPH
+0xC9C7	0x56DF	#CJK UNIFIED IDEOGRAPH
+0xC9C8	0x572E	#CJK UNIFIED IDEOGRAPH
+0xC9C9	0x572A	#CJK UNIFIED IDEOGRAPH
+0xC9CA	0x5734	#CJK UNIFIED IDEOGRAPH
+0xC9CB	0x593C	#CJK UNIFIED IDEOGRAPH
+0xC9CC	0x5980	#CJK UNIFIED IDEOGRAPH
+0xC9CD	0x597C	#CJK UNIFIED IDEOGRAPH
+0xC9CE	0x5985	#CJK UNIFIED IDEOGRAPH
+0xC9CF	0x597B	#CJK UNIFIED IDEOGRAPH
+0xC9D0	0x597E	#CJK UNIFIED IDEOGRAPH
+0xC9D1	0x5977	#CJK UNIFIED IDEOGRAPH
+0xC9D2	0x597F	#CJK UNIFIED IDEOGRAPH
+0xC9D3	0x5B56	#CJK UNIFIED IDEOGRAPH
+0xC9D4	0x5C15	#CJK UNIFIED IDEOGRAPH
+0xC9D5	0x5C25	#CJK UNIFIED IDEOGRAPH
+0xC9D6	0x5C7C	#CJK UNIFIED IDEOGRAPH
+0xC9D7	0x5C7A	#CJK UNIFIED IDEOGRAPH
+0xC9D8	0x5C7B	#CJK UNIFIED IDEOGRAPH
+0xC9D9	0x5C7E	#CJK UNIFIED IDEOGRAPH
+0xC9DA	0x5DDF	#CJK UNIFIED IDEOGRAPH
+0xC9DB	0x5E75	#CJK UNIFIED IDEOGRAPH
+0xC9DC	0x5E84	#CJK UNIFIED IDEOGRAPH
+0xC9DD	0x5F02	#CJK UNIFIED IDEOGRAPH
+0xC9DE	0x5F1A	#CJK UNIFIED IDEOGRAPH
+0xC9DF	0x5F74	#CJK UNIFIED IDEOGRAPH
+0xC9E0	0x5FD5	#CJK UNIFIED IDEOGRAPH
+0xC9E1	0x5FD4	#CJK UNIFIED IDEOGRAPH
+0xC9E2	0x5FCF	#CJK UNIFIED IDEOGRAPH
+0xC9E3	0x625C	#CJK UNIFIED IDEOGRAPH
+0xC9E4	0x625E	#CJK UNIFIED IDEOGRAPH
+0xC9E5	0x6264	#CJK UNIFIED IDEOGRAPH
+0xC9E6	0x6261	#CJK UNIFIED IDEOGRAPH
+0xC9E7	0x6266	#CJK UNIFIED IDEOGRAPH
+0xC9E8	0x6262	#CJK UNIFIED IDEOGRAPH
+0xC9E9	0x6259	#CJK UNIFIED IDEOGRAPH
+0xC9EA	0x6260	#CJK UNIFIED IDEOGRAPH
+0xC9EB	0x625A	#CJK UNIFIED IDEOGRAPH
+0xC9EC	0x6265	#CJK UNIFIED IDEOGRAPH
+0xC9ED	0x65EF	#CJK UNIFIED IDEOGRAPH
+0xC9EE	0x65EE	#CJK UNIFIED IDEOGRAPH
+0xC9EF	0x673E	#CJK UNIFIED IDEOGRAPH
+0xC9F0	0x6739	#CJK UNIFIED IDEOGRAPH
+0xC9F1	0x6738	#CJK UNIFIED IDEOGRAPH
+0xC9F2	0x673B	#CJK UNIFIED IDEOGRAPH
+0xC9F3	0x673A	#CJK UNIFIED IDEOGRAPH
+0xC9F4	0x673F	#CJK UNIFIED IDEOGRAPH
+0xC9F5	0x673C	#CJK UNIFIED IDEOGRAPH
+0xC9F6	0x6733	#CJK UNIFIED IDEOGRAPH
+0xC9F7	0x6C18	#CJK UNIFIED IDEOGRAPH
+0xC9F8	0x6C46	#CJK UNIFIED IDEOGRAPH
+0xC9F9	0x6C52	#CJK UNIFIED IDEOGRAPH
+0xC9FA	0x6C5C	#CJK UNIFIED IDEOGRAPH
+0xC9FB	0x6C4F	#CJK UNIFIED IDEOGRAPH
+0xC9FC	0x6C4A	#CJK UNIFIED IDEOGRAPH
+0xC9FD	0x6C54	#CJK UNIFIED IDEOGRAPH
+0xC9FE	0x6C4B	#CJK UNIFIED IDEOGRAPH
+0xCA40	0x6C4C	#CJK UNIFIED IDEOGRAPH
+0xCA41	0x7071	#CJK UNIFIED IDEOGRAPH
+0xCA42	0x725E	#CJK UNIFIED IDEOGRAPH
+0xCA43	0x72B4	#CJK UNIFIED IDEOGRAPH
+0xCA44	0x72B5	#CJK UNIFIED IDEOGRAPH
+0xCA45	0x738E	#CJK UNIFIED IDEOGRAPH
+0xCA46	0x752A	#CJK UNIFIED IDEOGRAPH
+0xCA47	0x767F	#CJK UNIFIED IDEOGRAPH
+0xCA48	0x7A75	#CJK UNIFIED IDEOGRAPH
+0xCA49	0x7F51	#CJK UNIFIED IDEOGRAPH
+0xCA4A	0x8278	#CJK UNIFIED IDEOGRAPH
+0xCA4B	0x827C	#CJK UNIFIED IDEOGRAPH
+0xCA4C	0x8280	#CJK UNIFIED IDEOGRAPH
+0xCA4D	0x827D	#CJK UNIFIED IDEOGRAPH
+0xCA4E	0x827F	#CJK UNIFIED IDEOGRAPH
+0xCA4F	0x864D	#CJK UNIFIED IDEOGRAPH
+0xCA50	0x897E	#CJK UNIFIED IDEOGRAPH
+0xCA51	0x9099	#CJK UNIFIED IDEOGRAPH
+0xCA52	0x9097	#CJK UNIFIED IDEOGRAPH
+0xCA53	0x9098	#CJK UNIFIED IDEOGRAPH
+0xCA54	0x909B	#CJK UNIFIED IDEOGRAPH
+0xCA55	0x9094	#CJK UNIFIED IDEOGRAPH
+0xCA56	0x9622	#CJK UNIFIED IDEOGRAPH
+0xCA57	0x9624	#CJK UNIFIED IDEOGRAPH
+0xCA58	0x9620	#CJK UNIFIED IDEOGRAPH
+0xCA59	0x9623	#CJK UNIFIED IDEOGRAPH
+0xCA5A	0x4F56	#CJK UNIFIED IDEOGRAPH
+0xCA5B	0x4F3B	#CJK UNIFIED IDEOGRAPH
+0xCA5C	0x4F62	#CJK UNIFIED IDEOGRAPH
+0xCA5D	0x4F49	#CJK UNIFIED IDEOGRAPH
+0xCA5E	0x4F53	#CJK UNIFIED IDEOGRAPH
+0xCA5F	0x4F64	#CJK UNIFIED IDEOGRAPH
+0xCA60	0x4F3E	#CJK UNIFIED IDEOGRAPH
+0xCA61	0x4F67	#CJK UNIFIED IDEOGRAPH
+0xCA62	0x4F52	#CJK UNIFIED IDEOGRAPH
+0xCA63	0x4F5F	#CJK UNIFIED IDEOGRAPH
+0xCA64	0x4F41	#CJK UNIFIED IDEOGRAPH
+0xCA65	0x4F58	#CJK UNIFIED IDEOGRAPH
+0xCA66	0x4F2D	#CJK UNIFIED IDEOGRAPH
+0xCA67	0x4F33	#CJK UNIFIED IDEOGRAPH
+0xCA68	0x4F3F	#CJK UNIFIED IDEOGRAPH
+0xCA69	0x4F61	#CJK UNIFIED IDEOGRAPH
+0xCA6A	0x518F	#CJK UNIFIED IDEOGRAPH
+0xCA6B	0x51B9	#CJK UNIFIED IDEOGRAPH
+0xCA6C	0x521C	#CJK UNIFIED IDEOGRAPH
+0xCA6D	0x521E	#CJK UNIFIED IDEOGRAPH
+0xCA6E	0x5221	#CJK UNIFIED IDEOGRAPH
+0xCA6F	0x52AD	#CJK UNIFIED IDEOGRAPH
+0xCA70	0x52AE	#CJK UNIFIED IDEOGRAPH
+0xCA71	0x5309	#CJK UNIFIED IDEOGRAPH
+0xCA72	0x5363	#CJK UNIFIED IDEOGRAPH
+0xCA73	0x5372	#CJK UNIFIED IDEOGRAPH
+0xCA74	0x538E	#CJK UNIFIED IDEOGRAPH
+0xCA75	0x538F	#CJK UNIFIED IDEOGRAPH
+0xCA76	0x5430	#CJK UNIFIED IDEOGRAPH
+0xCA77	0x5437	#CJK UNIFIED IDEOGRAPH
+0xCA78	0x542A	#CJK UNIFIED IDEOGRAPH
+0xCA79	0x5454	#CJK UNIFIED IDEOGRAPH
+0xCA7A	0x5445	#CJK UNIFIED IDEOGRAPH
+0xCA7B	0x5419	#CJK UNIFIED IDEOGRAPH
+0xCA7C	0x541C	#CJK UNIFIED IDEOGRAPH
+0xCA7D	0x5425	#CJK UNIFIED IDEOGRAPH
+0xCA7E	0x5418	#CJK UNIFIED IDEOGRAPH
+0xCAA1	0x543D	#CJK UNIFIED IDEOGRAPH
+0xCAA2	0x544F	#CJK UNIFIED IDEOGRAPH
+0xCAA3	0x5441	#CJK UNIFIED IDEOGRAPH
+0xCAA4	0x5428	#CJK UNIFIED IDEOGRAPH
+0xCAA5	0x5424	#CJK UNIFIED IDEOGRAPH
+0xCAA6	0x5447	#CJK UNIFIED IDEOGRAPH
+0xCAA7	0x56EE	#CJK UNIFIED IDEOGRAPH
+0xCAA8	0x56E7	#CJK UNIFIED IDEOGRAPH
+0xCAA9	0x56E5	#CJK UNIFIED IDEOGRAPH
+0xCAAA	0x5741	#CJK UNIFIED IDEOGRAPH
+0xCAAB	0x5745	#CJK UNIFIED IDEOGRAPH
+0xCAAC	0x574C	#CJK UNIFIED IDEOGRAPH
+0xCAAD	0x5749	#CJK UNIFIED IDEOGRAPH
+0xCAAE	0x574B	#CJK UNIFIED IDEOGRAPH
+0xCAAF	0x5752	#CJK UNIFIED IDEOGRAPH
+0xCAB0	0x5906	#CJK UNIFIED IDEOGRAPH
+0xCAB1	0x5940	#CJK UNIFIED IDEOGRAPH
+0xCAB2	0x59A6	#CJK UNIFIED IDEOGRAPH
+0xCAB3	0x5998	#CJK UNIFIED IDEOGRAPH
+0xCAB4	0x59A0	#CJK UNIFIED IDEOGRAPH
+0xCAB5	0x5997	#CJK UNIFIED IDEOGRAPH
+0xCAB6	0x598E	#CJK UNIFIED IDEOGRAPH
+0xCAB7	0x59A2	#CJK UNIFIED IDEOGRAPH
+0xCAB8	0x5990	#CJK UNIFIED IDEOGRAPH
+0xCAB9	0x598F	#CJK UNIFIED IDEOGRAPH
+0xCABA	0x59A7	#CJK UNIFIED IDEOGRAPH
+0xCABB	0x59A1	#CJK UNIFIED IDEOGRAPH
+0xCABC	0x5B8E	#CJK UNIFIED IDEOGRAPH
+0xCABD	0x5B92	#CJK UNIFIED IDEOGRAPH
+0xCABE	0x5C28	#CJK UNIFIED IDEOGRAPH
+0xCABF	0x5C2A	#CJK UNIFIED IDEOGRAPH
+0xCAC0	0x5C8D	#CJK UNIFIED IDEOGRAPH
+0xCAC1	0x5C8F	#CJK UNIFIED IDEOGRAPH
+0xCAC2	0x5C88	#CJK UNIFIED IDEOGRAPH
+0xCAC3	0x5C8B	#CJK UNIFIED IDEOGRAPH
+0xCAC4	0x5C89	#CJK UNIFIED IDEOGRAPH
+0xCAC5	0x5C92	#CJK UNIFIED IDEOGRAPH
+0xCAC6	0x5C8A	#CJK UNIFIED IDEOGRAPH
+0xCAC7	0x5C86	#CJK UNIFIED IDEOGRAPH
+0xCAC8	0x5C93	#CJK UNIFIED IDEOGRAPH
+0xCAC9	0x5C95	#CJK UNIFIED IDEOGRAPH
+0xCACA	0x5DE0	#CJK UNIFIED IDEOGRAPH
+0xCACB	0x5E0A	#CJK UNIFIED IDEOGRAPH
+0xCACC	0x5E0E	#CJK UNIFIED IDEOGRAPH
+0xCACD	0x5E8B	#CJK UNIFIED IDEOGRAPH
+0xCACE	0x5E89	#CJK UNIFIED IDEOGRAPH
+0xCACF	0x5E8C	#CJK UNIFIED IDEOGRAPH
+0xCAD0	0x5E88	#CJK UNIFIED IDEOGRAPH
+0xCAD1	0x5E8D	#CJK UNIFIED IDEOGRAPH
+0xCAD2	0x5F05	#CJK UNIFIED IDEOGRAPH
+0xCAD3	0x5F1D	#CJK UNIFIED IDEOGRAPH
+0xCAD4	0x5F78	#CJK UNIFIED IDEOGRAPH
+0xCAD5	0x5F76	#CJK UNIFIED IDEOGRAPH
+0xCAD6	0x5FD2	#CJK UNIFIED IDEOGRAPH
+0xCAD7	0x5FD1	#CJK UNIFIED IDEOGRAPH
+0xCAD8	0x5FD0	#CJK UNIFIED IDEOGRAPH
+0xCAD9	0x5FED	#CJK UNIFIED IDEOGRAPH
+0xCADA	0x5FE8	#CJK UNIFIED IDEOGRAPH
+0xCADB	0x5FEE	#CJK UNIFIED IDEOGRAPH
+0xCADC	0x5FF3	#CJK UNIFIED IDEOGRAPH
+0xCADD	0x5FE1	#CJK UNIFIED IDEOGRAPH
+0xCADE	0x5FE4	#CJK UNIFIED IDEOGRAPH
+0xCADF	0x5FE3	#CJK UNIFIED IDEOGRAPH
+0xCAE0	0x5FFA	#CJK UNIFIED IDEOGRAPH
+0xCAE1	0x5FEF	#CJK UNIFIED IDEOGRAPH
+0xCAE2	0x5FF7	#CJK UNIFIED IDEOGRAPH
+0xCAE3	0x5FFB	#CJK UNIFIED IDEOGRAPH
+0xCAE4	0x6000	#CJK UNIFIED IDEOGRAPH
+0xCAE5	0x5FF4	#CJK UNIFIED IDEOGRAPH
+0xCAE6	0x623A	#CJK UNIFIED IDEOGRAPH
+0xCAE7	0x6283	#CJK UNIFIED IDEOGRAPH
+0xCAE8	0x628C	#CJK UNIFIED IDEOGRAPH
+0xCAE9	0x628E	#CJK UNIFIED IDEOGRAPH
+0xCAEA	0x628F	#CJK UNIFIED IDEOGRAPH
+0xCAEB	0x6294	#CJK UNIFIED IDEOGRAPH
+0xCAEC	0x6287	#CJK UNIFIED IDEOGRAPH
+0xCAED	0x6271	#CJK UNIFIED IDEOGRAPH
+0xCAEE	0x627B	#CJK UNIFIED IDEOGRAPH
+0xCAEF	0x627A	#CJK UNIFIED IDEOGRAPH
+0xCAF0	0x6270	#CJK UNIFIED IDEOGRAPH
+0xCAF1	0x6281	#CJK UNIFIED IDEOGRAPH
+0xCAF2	0x6288	#CJK UNIFIED IDEOGRAPH
+0xCAF3	0x6277	#CJK UNIFIED IDEOGRAPH
+0xCAF4	0x627D	#CJK UNIFIED IDEOGRAPH
+0xCAF5	0x6272	#CJK UNIFIED IDEOGRAPH
+0xCAF6	0x6274	#CJK UNIFIED IDEOGRAPH
+0xCAF7	0x6537	#CJK UNIFIED IDEOGRAPH
+0xCAF8	0x65F0	#CJK UNIFIED IDEOGRAPH
+0xCAF9	0x65F4	#CJK UNIFIED IDEOGRAPH
+0xCAFA	0x65F3	#CJK UNIFIED IDEOGRAPH
+0xCAFB	0x65F2	#CJK UNIFIED IDEOGRAPH
+0xCAFC	0x65F5	#CJK UNIFIED IDEOGRAPH
+0xCAFD	0x6745	#CJK UNIFIED IDEOGRAPH
+0xCAFE	0x6747	#CJK UNIFIED IDEOGRAPH
+0xCB40	0x6759	#CJK UNIFIED IDEOGRAPH
+0xCB41	0x6755	#CJK UNIFIED IDEOGRAPH
+0xCB42	0x674C	#CJK UNIFIED IDEOGRAPH
+0xCB43	0x6748	#CJK UNIFIED IDEOGRAPH
+0xCB44	0x675D	#CJK UNIFIED IDEOGRAPH
+0xCB45	0x674D	#CJK UNIFIED IDEOGRAPH
+0xCB46	0x675A	#CJK UNIFIED IDEOGRAPH
+0xCB47	0x674B	#CJK UNIFIED IDEOGRAPH
+0xCB48	0x6BD0	#CJK UNIFIED IDEOGRAPH
+0xCB49	0x6C19	#CJK UNIFIED IDEOGRAPH
+0xCB4A	0x6C1A	#CJK UNIFIED IDEOGRAPH
+0xCB4B	0x6C78	#CJK UNIFIED IDEOGRAPH
+0xCB4C	0x6C67	#CJK UNIFIED IDEOGRAPH
+0xCB4D	0x6C6B	#CJK UNIFIED IDEOGRAPH
+0xCB4E	0x6C84	#CJK UNIFIED IDEOGRAPH
+0xCB4F	0x6C8B	#CJK UNIFIED IDEOGRAPH
+0xCB50	0x6C8F	#CJK UNIFIED IDEOGRAPH
+0xCB51	0x6C71	#CJK UNIFIED IDEOGRAPH
+0xCB52	0x6C6F	#CJK UNIFIED IDEOGRAPH
+0xCB53	0x6C69	#CJK UNIFIED IDEOGRAPH
+0xCB54	0x6C9A	#CJK UNIFIED IDEOGRAPH
+0xCB55	0x6C6D	#CJK UNIFIED IDEOGRAPH
+0xCB56	0x6C87	#CJK UNIFIED IDEOGRAPH
+0xCB57	0x6C95	#CJK UNIFIED IDEOGRAPH
+0xCB58	0x6C9C	#CJK UNIFIED IDEOGRAPH
+0xCB59	0x6C66	#CJK UNIFIED IDEOGRAPH
+0xCB5A	0x6C73	#CJK UNIFIED IDEOGRAPH
+0xCB5B	0x6C65	#CJK UNIFIED IDEOGRAPH
+0xCB5C	0x6C7B	#CJK UNIFIED IDEOGRAPH
+0xCB5D	0x6C8E	#CJK UNIFIED IDEOGRAPH
+0xCB5E	0x7074	#CJK UNIFIED IDEOGRAPH
+0xCB5F	0x707A	#CJK UNIFIED IDEOGRAPH
+0xCB60	0x7263	#CJK UNIFIED IDEOGRAPH
+0xCB61	0x72BF	#CJK UNIFIED IDEOGRAPH
+0xCB62	0x72BD	#CJK UNIFIED IDEOGRAPH
+0xCB63	0x72C3	#CJK UNIFIED IDEOGRAPH
+0xCB64	0x72C6	#CJK UNIFIED IDEOGRAPH
+0xCB65	0x72C1	#CJK UNIFIED IDEOGRAPH
+0xCB66	0x72BA	#CJK UNIFIED IDEOGRAPH
+0xCB67	0x72C5	#CJK UNIFIED IDEOGRAPH
+0xCB68	0x7395	#CJK UNIFIED IDEOGRAPH
+0xCB69	0x7397	#CJK UNIFIED IDEOGRAPH
+0xCB6A	0x7393	#CJK UNIFIED IDEOGRAPH
+0xCB6B	0x7394	#CJK UNIFIED IDEOGRAPH
+0xCB6C	0x7392	#CJK UNIFIED IDEOGRAPH
+0xCB6D	0x753A	#CJK UNIFIED IDEOGRAPH
+0xCB6E	0x7539	#CJK UNIFIED IDEOGRAPH
+0xCB6F	0x7594	#CJK UNIFIED IDEOGRAPH
+0xCB70	0x7595	#CJK UNIFIED IDEOGRAPH
+0xCB71	0x7681	#CJK UNIFIED IDEOGRAPH
+0xCB72	0x793D	#CJK UNIFIED IDEOGRAPH
+0xCB73	0x8034	#CJK UNIFIED IDEOGRAPH
+0xCB74	0x8095	#CJK UNIFIED IDEOGRAPH
+0xCB75	0x8099	#CJK UNIFIED IDEOGRAPH
+0xCB76	0x8090	#CJK UNIFIED IDEOGRAPH
+0xCB77	0x8092	#CJK UNIFIED IDEOGRAPH
+0xCB78	0x809C	#CJK UNIFIED IDEOGRAPH
+0xCB79	0x8290	#CJK UNIFIED IDEOGRAPH
+0xCB7A	0x828F	#CJK UNIFIED IDEOGRAPH
+0xCB7B	0x8285	#CJK UNIFIED IDEOGRAPH
+0xCB7C	0x828E	#CJK UNIFIED IDEOGRAPH
+0xCB7D	0x8291	#CJK UNIFIED IDEOGRAPH
+0xCB7E	0x8293	#CJK UNIFIED IDEOGRAPH
+0xCBA1	0x828A	#CJK UNIFIED IDEOGRAPH
+0xCBA2	0x8283	#CJK UNIFIED IDEOGRAPH
+0xCBA3	0x8284	#CJK UNIFIED IDEOGRAPH
+0xCBA4	0x8C78	#CJK UNIFIED IDEOGRAPH
+0xCBA5	0x8FC9	#CJK UNIFIED IDEOGRAPH
+0xCBA6	0x8FBF	#CJK UNIFIED IDEOGRAPH
+0xCBA7	0x909F	#CJK UNIFIED IDEOGRAPH
+0xCBA8	0x90A1	#CJK UNIFIED IDEOGRAPH
+0xCBA9	0x90A5	#CJK UNIFIED IDEOGRAPH
+0xCBAA	0x909E	#CJK UNIFIED IDEOGRAPH
+0xCBAB	0x90A7	#CJK UNIFIED IDEOGRAPH
+0xCBAC	0x90A0	#CJK UNIFIED IDEOGRAPH
+0xCBAD	0x9630	#CJK UNIFIED IDEOGRAPH
+0xCBAE	0x9628	#CJK UNIFIED IDEOGRAPH
+0xCBAF	0x962F	#CJK UNIFIED IDEOGRAPH
+0xCBB0	0x962D	#CJK UNIFIED IDEOGRAPH
+0xCBB1	0x4E33	#CJK UNIFIED IDEOGRAPH
+0xCBB2	0x4F98	#CJK UNIFIED IDEOGRAPH
+0xCBB3	0x4F7C	#CJK UNIFIED IDEOGRAPH
+0xCBB4	0x4F85	#CJK UNIFIED IDEOGRAPH
+0xCBB5	0x4F7D	#CJK UNIFIED IDEOGRAPH
+0xCBB6	0x4F80	#CJK UNIFIED IDEOGRAPH
+0xCBB7	0x4F87	#CJK UNIFIED IDEOGRAPH
+0xCBB8	0x4F76	#CJK UNIFIED IDEOGRAPH
+0xCBB9	0x4F74	#CJK UNIFIED IDEOGRAPH
+0xCBBA	0x4F89	#CJK UNIFIED IDEOGRAPH
+0xCBBB	0x4F84	#CJK UNIFIED IDEOGRAPH
+0xCBBC	0x4F77	#CJK UNIFIED IDEOGRAPH
+0xCBBD	0x4F4C	#CJK UNIFIED IDEOGRAPH
+0xCBBE	0x4F97	#CJK UNIFIED IDEOGRAPH
+0xCBBF	0x4F6A	#CJK UNIFIED IDEOGRAPH
+0xCBC0	0x4F9A	#CJK UNIFIED IDEOGRAPH
+0xCBC1	0x4F79	#CJK UNIFIED IDEOGRAPH
+0xCBC2	0x4F81	#CJK UNIFIED IDEOGRAPH
+0xCBC3	0x4F78	#CJK UNIFIED IDEOGRAPH
+0xCBC4	0x4F90	#CJK UNIFIED IDEOGRAPH
+0xCBC5	0x4F9C	#CJK UNIFIED IDEOGRAPH
+0xCBC6	0x4F94	#CJK UNIFIED IDEOGRAPH
+0xCBC7	0x4F9E	#CJK UNIFIED IDEOGRAPH
+0xCBC8	0x4F92	#CJK UNIFIED IDEOGRAPH
+0xCBC9	0x4F82	#CJK UNIFIED IDEOGRAPH
+0xCBCA	0x4F95	#CJK UNIFIED IDEOGRAPH
+0xCBCB	0x4F6B	#CJK UNIFIED IDEOGRAPH
+0xCBCC	0x4F6E	#CJK UNIFIED IDEOGRAPH
+0xCBCD	0x519E	#CJK UNIFIED IDEOGRAPH
+0xCBCE	0x51BC	#CJK UNIFIED IDEOGRAPH
+0xCBCF	0x51BE	#CJK UNIFIED IDEOGRAPH
+0xCBD0	0x5235	#CJK UNIFIED IDEOGRAPH
+0xCBD1	0x5232	#CJK UNIFIED IDEOGRAPH
+0xCBD2	0x5233	#CJK UNIFIED IDEOGRAPH
+0xCBD3	0x5246	#CJK UNIFIED IDEOGRAPH
+0xCBD4	0x5231	#CJK UNIFIED IDEOGRAPH
+0xCBD5	0x52BC	#CJK UNIFIED IDEOGRAPH
+0xCBD6	0x530A	#CJK UNIFIED IDEOGRAPH
+0xCBD7	0x530B	#CJK UNIFIED IDEOGRAPH
+0xCBD8	0x533C	#CJK UNIFIED IDEOGRAPH
+0xCBD9	0x5392	#CJK UNIFIED IDEOGRAPH
+0xCBDA	0x5394	#CJK UNIFIED IDEOGRAPH
+0xCBDB	0x5487	#CJK UNIFIED IDEOGRAPH
+0xCBDC	0x547F	#CJK UNIFIED IDEOGRAPH
+0xCBDD	0x5481	#CJK UNIFIED IDEOGRAPH
+0xCBDE	0x5491	#CJK UNIFIED IDEOGRAPH
+0xCBDF	0x5482	#CJK UNIFIED IDEOGRAPH
+0xCBE0	0x5488	#CJK UNIFIED IDEOGRAPH
+0xCBE1	0x546B	#CJK UNIFIED IDEOGRAPH
+0xCBE2	0x547A	#CJK UNIFIED IDEOGRAPH
+0xCBE3	0x547E	#CJK UNIFIED IDEOGRAPH
+0xCBE4	0x5465	#CJK UNIFIED IDEOGRAPH
+0xCBE5	0x546C	#CJK UNIFIED IDEOGRAPH
+0xCBE6	0x5474	#CJK UNIFIED IDEOGRAPH
+0xCBE7	0x5466	#CJK UNIFIED IDEOGRAPH
+0xCBE8	0x548D	#CJK UNIFIED IDEOGRAPH
+0xCBE9	0x546F	#CJK UNIFIED IDEOGRAPH
+0xCBEA	0x5461	#CJK UNIFIED IDEOGRAPH
+0xCBEB	0x5460	#CJK UNIFIED IDEOGRAPH
+0xCBEC	0x5498	#CJK UNIFIED IDEOGRAPH
+0xCBED	0x5463	#CJK UNIFIED IDEOGRAPH
+0xCBEE	0x5467	#CJK UNIFIED IDEOGRAPH
+0xCBEF	0x5464	#CJK UNIFIED IDEOGRAPH
+0xCBF0	0x56F7	#CJK UNIFIED IDEOGRAPH
+0xCBF1	0x56F9	#CJK UNIFIED IDEOGRAPH
+0xCBF2	0x576F	#CJK UNIFIED IDEOGRAPH
+0xCBF3	0x5772	#CJK UNIFIED IDEOGRAPH
+0xCBF4	0x576D	#CJK UNIFIED IDEOGRAPH
+0xCBF5	0x576B	#CJK UNIFIED IDEOGRAPH
+0xCBF6	0x5771	#CJK UNIFIED IDEOGRAPH
+0xCBF7	0x5770	#CJK UNIFIED IDEOGRAPH
+0xCBF8	0x5776	#CJK UNIFIED IDEOGRAPH
+0xCBF9	0x5780	#CJK UNIFIED IDEOGRAPH
+0xCBFA	0x5775	#CJK UNIFIED IDEOGRAPH
+0xCBFB	0x577B	#CJK UNIFIED IDEOGRAPH
+0xCBFC	0x5773	#CJK UNIFIED IDEOGRAPH
+0xCBFD	0x5774	#CJK UNIFIED IDEOGRAPH
+0xCBFE	0x5762	#CJK UNIFIED IDEOGRAPH
+0xCC40	0x5768	#CJK UNIFIED IDEOGRAPH
+0xCC41	0x577D	#CJK UNIFIED IDEOGRAPH
+0xCC42	0x590C	#CJK UNIFIED IDEOGRAPH
+0xCC43	0x5945	#CJK UNIFIED IDEOGRAPH
+0xCC44	0x59B5	#CJK UNIFIED IDEOGRAPH
+0xCC45	0x59BA	#CJK UNIFIED IDEOGRAPH
+0xCC46	0x59CF	#CJK UNIFIED IDEOGRAPH
+0xCC47	0x59CE	#CJK UNIFIED IDEOGRAPH
+0xCC48	0x59B2	#CJK UNIFIED IDEOGRAPH
+0xCC49	0x59CC	#CJK UNIFIED IDEOGRAPH
+0xCC4A	0x59C1	#CJK UNIFIED IDEOGRAPH
+0xCC4B	0x59B6	#CJK UNIFIED IDEOGRAPH
+0xCC4C	0x59BC	#CJK UNIFIED IDEOGRAPH
+0xCC4D	0x59C3	#CJK UNIFIED IDEOGRAPH
+0xCC4E	0x59D6	#CJK UNIFIED IDEOGRAPH
+0xCC4F	0x59B1	#CJK UNIFIED IDEOGRAPH
+0xCC50	0x59BD	#CJK UNIFIED IDEOGRAPH
+0xCC51	0x59C0	#CJK UNIFIED IDEOGRAPH
+0xCC52	0x59C8	#CJK UNIFIED IDEOGRAPH
+0xCC53	0x59B4	#CJK UNIFIED IDEOGRAPH
+0xCC54	0x59C7	#CJK UNIFIED IDEOGRAPH
+0xCC55	0x5B62	#CJK UNIFIED IDEOGRAPH
+0xCC56	0x5B65	#CJK UNIFIED IDEOGRAPH
+0xCC57	0x5B93	#CJK UNIFIED IDEOGRAPH
+0xCC58	0x5B95	#CJK UNIFIED IDEOGRAPH
+0xCC59	0x5C44	#CJK UNIFIED IDEOGRAPH
+0xCC5A	0x5C47	#CJK UNIFIED IDEOGRAPH
+0xCC5B	0x5CAE	#CJK UNIFIED IDEOGRAPH
+0xCC5C	0x5CA4	#CJK UNIFIED IDEOGRAPH
+0xCC5D	0x5CA0	#CJK UNIFIED IDEOGRAPH
+0xCC5E	0x5CB5	#CJK UNIFIED IDEOGRAPH
+0xCC5F	0x5CAF	#CJK UNIFIED IDEOGRAPH
+0xCC60	0x5CA8	#CJK UNIFIED IDEOGRAPH
+0xCC61	0x5CAC	#CJK UNIFIED IDEOGRAPH
+0xCC62	0x5C9F	#CJK UNIFIED IDEOGRAPH
+0xCC63	0x5CA3	#CJK UNIFIED IDEOGRAPH
+0xCC64	0x5CAD	#CJK UNIFIED IDEOGRAPH
+0xCC65	0x5CA2	#CJK UNIFIED IDEOGRAPH
+0xCC66	0x5CAA	#CJK UNIFIED IDEOGRAPH
+0xCC67	0x5CA7	#CJK UNIFIED IDEOGRAPH
+0xCC68	0x5C9D	#CJK UNIFIED IDEOGRAPH
+0xCC69	0x5CA5	#CJK UNIFIED IDEOGRAPH
+0xCC6A	0x5CB6	#CJK UNIFIED IDEOGRAPH
+0xCC6B	0x5CB0	#CJK UNIFIED IDEOGRAPH
+0xCC6C	0x5CA6	#CJK UNIFIED IDEOGRAPH
+0xCC6D	0x5E17	#CJK UNIFIED IDEOGRAPH
+0xCC6E	0x5E14	#CJK UNIFIED IDEOGRAPH
+0xCC6F	0x5E19	#CJK UNIFIED IDEOGRAPH
+0xCC70	0x5F28	#CJK UNIFIED IDEOGRAPH
+0xCC71	0x5F22	#CJK UNIFIED IDEOGRAPH
+0xCC72	0x5F23	#CJK UNIFIED IDEOGRAPH
+0xCC73	0x5F24	#CJK UNIFIED IDEOGRAPH
+0xCC74	0x5F54	#CJK UNIFIED IDEOGRAPH
+0xCC75	0x5F82	#CJK UNIFIED IDEOGRAPH
+0xCC76	0x5F7E	#CJK UNIFIED IDEOGRAPH
+0xCC77	0x5F7D	#CJK UNIFIED IDEOGRAPH
+0xCC78	0x5FDE	#CJK UNIFIED IDEOGRAPH
+0xCC79	0x5FE5	#CJK UNIFIED IDEOGRAPH
+0xCC7A	0x602D	#CJK UNIFIED IDEOGRAPH
+0xCC7B	0x6026	#CJK UNIFIED IDEOGRAPH
+0xCC7C	0x6019	#CJK UNIFIED IDEOGRAPH
+0xCC7D	0x6032	#CJK UNIFIED IDEOGRAPH
+0xCC7E	0x600B	#CJK UNIFIED IDEOGRAPH
+0xCCA1	0x6034	#CJK UNIFIED IDEOGRAPH
+0xCCA2	0x600A	#CJK UNIFIED IDEOGRAPH
+0xCCA3	0x6017	#CJK UNIFIED IDEOGRAPH
+0xCCA4	0x6033	#CJK UNIFIED IDEOGRAPH
+0xCCA5	0x601A	#CJK UNIFIED IDEOGRAPH
+0xCCA6	0x601E	#CJK UNIFIED IDEOGRAPH
+0xCCA7	0x602C	#CJK UNIFIED IDEOGRAPH
+0xCCA8	0x6022	#CJK UNIFIED IDEOGRAPH
+0xCCA9	0x600D	#CJK UNIFIED IDEOGRAPH
+0xCCAA	0x6010	#CJK UNIFIED IDEOGRAPH
+0xCCAB	0x602E	#CJK UNIFIED IDEOGRAPH
+0xCCAC	0x6013	#CJK UNIFIED IDEOGRAPH
+0xCCAD	0x6011	#CJK UNIFIED IDEOGRAPH
+0xCCAE	0x600C	#CJK UNIFIED IDEOGRAPH
+0xCCAF	0x6009	#CJK UNIFIED IDEOGRAPH
+0xCCB0	0x601C	#CJK UNIFIED IDEOGRAPH
+0xCCB1	0x6214	#CJK UNIFIED IDEOGRAPH
+0xCCB2	0x623D	#CJK UNIFIED IDEOGRAPH
+0xCCB3	0x62AD	#CJK UNIFIED IDEOGRAPH
+0xCCB4	0x62B4	#CJK UNIFIED IDEOGRAPH
+0xCCB5	0x62D1	#CJK UNIFIED IDEOGRAPH
+0xCCB6	0x62BE	#CJK UNIFIED IDEOGRAPH
+0xCCB7	0x62AA	#CJK UNIFIED IDEOGRAPH
+0xCCB8	0x62B6	#CJK UNIFIED IDEOGRAPH
+0xCCB9	0x62CA	#CJK UNIFIED IDEOGRAPH
+0xCCBA	0x62AE	#CJK UNIFIED IDEOGRAPH
+0xCCBB	0x62B3	#CJK UNIFIED IDEOGRAPH
+0xCCBC	0x62AF	#CJK UNIFIED IDEOGRAPH
+0xCCBD	0x62BB	#CJK UNIFIED IDEOGRAPH
+0xCCBE	0x62A9	#CJK UNIFIED IDEOGRAPH
+0xCCBF	0x62B0	#CJK UNIFIED IDEOGRAPH
+0xCCC0	0x62B8	#CJK UNIFIED IDEOGRAPH
+0xCCC1	0x653D	#CJK UNIFIED IDEOGRAPH
+0xCCC2	0x65A8	#CJK UNIFIED IDEOGRAPH
+0xCCC3	0x65BB	#CJK UNIFIED IDEOGRAPH
+0xCCC4	0x6609	#CJK UNIFIED IDEOGRAPH
+0xCCC5	0x65FC	#CJK UNIFIED IDEOGRAPH
+0xCCC6	0x6604	#CJK UNIFIED IDEOGRAPH
+0xCCC7	0x6612	#CJK UNIFIED IDEOGRAPH
+0xCCC8	0x6608	#CJK UNIFIED IDEOGRAPH
+0xCCC9	0x65FB	#CJK UNIFIED IDEOGRAPH
+0xCCCA	0x6603	#CJK UNIFIED IDEOGRAPH
+0xCCCB	0x660B	#CJK UNIFIED IDEOGRAPH
+0xCCCC	0x660D	#CJK UNIFIED IDEOGRAPH
+0xCCCD	0x6605	#CJK UNIFIED IDEOGRAPH
+0xCCCE	0x65FD	#CJK UNIFIED IDEOGRAPH
+0xCCCF	0x6611	#CJK UNIFIED IDEOGRAPH
+0xCCD0	0x6610	#CJK UNIFIED IDEOGRAPH
+0xCCD1	0x66F6	#CJK UNIFIED IDEOGRAPH
+0xCCD2	0x670A	#CJK UNIFIED IDEOGRAPH
+0xCCD3	0x6785	#CJK UNIFIED IDEOGRAPH
+0xCCD4	0x676C	#CJK UNIFIED IDEOGRAPH
+0xCCD5	0x678E	#CJK UNIFIED IDEOGRAPH
+0xCCD6	0x6792	#CJK UNIFIED IDEOGRAPH
+0xCCD7	0x6776	#CJK UNIFIED IDEOGRAPH
+0xCCD8	0x677B	#CJK UNIFIED IDEOGRAPH
+0xCCD9	0x6798	#CJK UNIFIED IDEOGRAPH
+0xCCDA	0x6786	#CJK UNIFIED IDEOGRAPH
+0xCCDB	0x6784	#CJK UNIFIED IDEOGRAPH
+0xCCDC	0x6774	#CJK UNIFIED IDEOGRAPH
+0xCCDD	0x678D	#CJK UNIFIED IDEOGRAPH
+0xCCDE	0x678C	#CJK UNIFIED IDEOGRAPH
+0xCCDF	0x677A	#CJK UNIFIED IDEOGRAPH
+0xCCE0	0x679F	#CJK UNIFIED IDEOGRAPH
+0xCCE1	0x6791	#CJK UNIFIED IDEOGRAPH
+0xCCE2	0x6799	#CJK UNIFIED IDEOGRAPH
+0xCCE3	0x6783	#CJK UNIFIED IDEOGRAPH
+0xCCE4	0x677D	#CJK UNIFIED IDEOGRAPH
+0xCCE5	0x6781	#CJK UNIFIED IDEOGRAPH
+0xCCE6	0x6778	#CJK UNIFIED IDEOGRAPH
+0xCCE7	0x6779	#CJK UNIFIED IDEOGRAPH
+0xCCE8	0x6794	#CJK UNIFIED IDEOGRAPH
+0xCCE9	0x6B25	#CJK UNIFIED IDEOGRAPH
+0xCCEA	0x6B80	#CJK UNIFIED IDEOGRAPH
+0xCCEB	0x6B7E	#CJK UNIFIED IDEOGRAPH
+0xCCEC	0x6BDE	#CJK UNIFIED IDEOGRAPH
+0xCCED	0x6C1D	#CJK UNIFIED IDEOGRAPH
+0xCCEE	0x6C93	#CJK UNIFIED IDEOGRAPH
+0xCCEF	0x6CEC	#CJK UNIFIED IDEOGRAPH
+0xCCF0	0x6CEB	#CJK UNIFIED IDEOGRAPH
+0xCCF1	0x6CEE	#CJK UNIFIED IDEOGRAPH
+0xCCF2	0x6CD9	#CJK UNIFIED IDEOGRAPH
+0xCCF3	0x6CB6	#CJK UNIFIED IDEOGRAPH
+0xCCF4	0x6CD4	#CJK UNIFIED IDEOGRAPH
+0xCCF5	0x6CAD	#CJK UNIFIED IDEOGRAPH
+0xCCF6	0x6CE7	#CJK UNIFIED IDEOGRAPH
+0xCCF7	0x6CB7	#CJK UNIFIED IDEOGRAPH
+0xCCF8	0x6CD0	#CJK UNIFIED IDEOGRAPH
+0xCCF9	0x6CC2	#CJK UNIFIED IDEOGRAPH
+0xCCFA	0x6CBA	#CJK UNIFIED IDEOGRAPH
+0xCCFB	0x6CC3	#CJK UNIFIED IDEOGRAPH
+0xCCFC	0x6CC6	#CJK UNIFIED IDEOGRAPH
+0xCCFD	0x6CED	#CJK UNIFIED IDEOGRAPH
+0xCCFE	0x6CF2	#CJK UNIFIED IDEOGRAPH
+0xCD40	0x6CD2	#CJK UNIFIED IDEOGRAPH
+0xCD41	0x6CDD	#CJK UNIFIED IDEOGRAPH
+0xCD42	0x6CB4	#CJK UNIFIED IDEOGRAPH
+0xCD43	0x6C8A	#CJK UNIFIED IDEOGRAPH
+0xCD44	0x6C9D	#CJK UNIFIED IDEOGRAPH
+0xCD45	0x6C80	#CJK UNIFIED IDEOGRAPH
+0xCD46	0x6CDE	#CJK UNIFIED IDEOGRAPH
+0xCD47	0x6CC0	#CJK UNIFIED IDEOGRAPH
+0xCD48	0x6D30	#CJK UNIFIED IDEOGRAPH
+0xCD49	0x6CCD	#CJK UNIFIED IDEOGRAPH
+0xCD4A	0x6CC7	#CJK UNIFIED IDEOGRAPH
+0xCD4B	0x6CB0	#CJK UNIFIED IDEOGRAPH
+0xCD4C	0x6CF9	#CJK UNIFIED IDEOGRAPH
+0xCD4D	0x6CCF	#CJK UNIFIED IDEOGRAPH
+0xCD4E	0x6CE9	#CJK UNIFIED IDEOGRAPH
+0xCD4F	0x6CD1	#CJK UNIFIED IDEOGRAPH
+0xCD50	0x7094	#CJK UNIFIED IDEOGRAPH
+0xCD51	0x7098	#CJK UNIFIED IDEOGRAPH
+0xCD52	0x7085	#CJK UNIFIED IDEOGRAPH
+0xCD53	0x7093	#CJK UNIFIED IDEOGRAPH
+0xCD54	0x7086	#CJK UNIFIED IDEOGRAPH
+0xCD55	0x7084	#CJK UNIFIED IDEOGRAPH
+0xCD56	0x7091	#CJK UNIFIED IDEOGRAPH
+0xCD57	0x7096	#CJK UNIFIED IDEOGRAPH
+0xCD58	0x7082	#CJK UNIFIED IDEOGRAPH
+0xCD59	0x709A	#CJK UNIFIED IDEOGRAPH
+0xCD5A	0x7083	#CJK UNIFIED IDEOGRAPH
+0xCD5B	0x726A	#CJK UNIFIED IDEOGRAPH
+0xCD5C	0x72D6	#CJK UNIFIED IDEOGRAPH
+0xCD5D	0x72CB	#CJK UNIFIED IDEOGRAPH
+0xCD5E	0x72D8	#CJK UNIFIED IDEOGRAPH
+0xCD5F	0x72C9	#CJK UNIFIED IDEOGRAPH
+0xCD60	0x72DC	#CJK UNIFIED IDEOGRAPH
+0xCD61	0x72D2	#CJK UNIFIED IDEOGRAPH
+0xCD62	0x72D4	#CJK UNIFIED IDEOGRAPH
+0xCD63	0x72DA	#CJK UNIFIED IDEOGRAPH
+0xCD64	0x72CC	#CJK UNIFIED IDEOGRAPH
+0xCD65	0x72D1	#CJK UNIFIED IDEOGRAPH
+0xCD66	0x73A4	#CJK UNIFIED IDEOGRAPH
+0xCD67	0x73A1	#CJK UNIFIED IDEOGRAPH
+0xCD68	0x73AD	#CJK UNIFIED IDEOGRAPH
+0xCD69	0x73A6	#CJK UNIFIED IDEOGRAPH
+0xCD6A	0x73A2	#CJK UNIFIED IDEOGRAPH
+0xCD6B	0x73A0	#CJK UNIFIED IDEOGRAPH
+0xCD6C	0x73AC	#CJK UNIFIED IDEOGRAPH
+0xCD6D	0x739D	#CJK UNIFIED IDEOGRAPH
+0xCD6E	0x74DD	#CJK UNIFIED IDEOGRAPH
+0xCD6F	0x74E8	#CJK UNIFIED IDEOGRAPH
+0xCD70	0x753F	#CJK UNIFIED IDEOGRAPH
+0xCD71	0x7540	#CJK UNIFIED IDEOGRAPH
+0xCD72	0x753E	#CJK UNIFIED IDEOGRAPH
+0xCD73	0x758C	#CJK UNIFIED IDEOGRAPH
+0xCD74	0x7598	#CJK UNIFIED IDEOGRAPH
+0xCD75	0x76AF	#CJK UNIFIED IDEOGRAPH
+0xCD76	0x76F3	#CJK UNIFIED IDEOGRAPH
+0xCD77	0x76F1	#CJK UNIFIED IDEOGRAPH
+0xCD78	0x76F0	#CJK UNIFIED IDEOGRAPH
+0xCD79	0x76F5	#CJK UNIFIED IDEOGRAPH
+0xCD7A	0x77F8	#CJK UNIFIED IDEOGRAPH
+0xCD7B	0x77FC	#CJK UNIFIED IDEOGRAPH
+0xCD7C	0x77F9	#CJK UNIFIED IDEOGRAPH
+0xCD7D	0x77FB	#CJK UNIFIED IDEOGRAPH
+0xCD7E	0x77FA	#CJK UNIFIED IDEOGRAPH
+0xCDA1	0x77F7	#CJK UNIFIED IDEOGRAPH
+0xCDA2	0x7942	#CJK UNIFIED IDEOGRAPH
+0xCDA3	0x793F	#CJK UNIFIED IDEOGRAPH
+0xCDA4	0x79C5	#CJK UNIFIED IDEOGRAPH
+0xCDA5	0x7A78	#CJK UNIFIED IDEOGRAPH
+0xCDA6	0x7A7B	#CJK UNIFIED IDEOGRAPH
+0xCDA7	0x7AFB	#CJK UNIFIED IDEOGRAPH
+0xCDA8	0x7C75	#CJK UNIFIED IDEOGRAPH
+0xCDA9	0x7CFD	#CJK UNIFIED IDEOGRAPH
+0xCDAA	0x8035	#CJK UNIFIED IDEOGRAPH
+0xCDAB	0x808F	#CJK UNIFIED IDEOGRAPH
+0xCDAC	0x80AE	#CJK UNIFIED IDEOGRAPH
+0xCDAD	0x80A3	#CJK UNIFIED IDEOGRAPH
+0xCDAE	0x80B8	#CJK UNIFIED IDEOGRAPH
+0xCDAF	0x80B5	#CJK UNIFIED IDEOGRAPH
+0xCDB0	0x80AD	#CJK UNIFIED IDEOGRAPH
+0xCDB1	0x8220	#CJK UNIFIED IDEOGRAPH
+0xCDB2	0x82A0	#CJK UNIFIED IDEOGRAPH
+0xCDB3	0x82C0	#CJK UNIFIED IDEOGRAPH
+0xCDB4	0x82AB	#CJK UNIFIED IDEOGRAPH
+0xCDB5	0x829A	#CJK UNIFIED IDEOGRAPH
+0xCDB6	0x8298	#CJK UNIFIED IDEOGRAPH
+0xCDB7	0x829B	#CJK UNIFIED IDEOGRAPH
+0xCDB8	0x82B5	#CJK UNIFIED IDEOGRAPH
+0xCDB9	0x82A7	#CJK UNIFIED IDEOGRAPH
+0xCDBA	0x82AE	#CJK UNIFIED IDEOGRAPH
+0xCDBB	0x82BC	#CJK UNIFIED IDEOGRAPH
+0xCDBC	0x829E	#CJK UNIFIED IDEOGRAPH
+0xCDBD	0x82BA	#CJK UNIFIED IDEOGRAPH
+0xCDBE	0x82B4	#CJK UNIFIED IDEOGRAPH
+0xCDBF	0x82A8	#CJK UNIFIED IDEOGRAPH
+0xCDC0	0x82A1	#CJK UNIFIED IDEOGRAPH
+0xCDC1	0x82A9	#CJK UNIFIED IDEOGRAPH
+0xCDC2	0x82C2	#CJK UNIFIED IDEOGRAPH
+0xCDC3	0x82A4	#CJK UNIFIED IDEOGRAPH
+0xCDC4	0x82C3	#CJK UNIFIED IDEOGRAPH
+0xCDC5	0x82B6	#CJK UNIFIED IDEOGRAPH
+0xCDC6	0x82A2	#CJK UNIFIED IDEOGRAPH
+0xCDC7	0x8670	#CJK UNIFIED IDEOGRAPH
+0xCDC8	0x866F	#CJK UNIFIED IDEOGRAPH
+0xCDC9	0x866D	#CJK UNIFIED IDEOGRAPH
+0xCDCA	0x866E	#CJK UNIFIED IDEOGRAPH
+0xCDCB	0x8C56	#CJK UNIFIED IDEOGRAPH
+0xCDCC	0x8FD2	#CJK UNIFIED IDEOGRAPH
+0xCDCD	0x8FCB	#CJK UNIFIED IDEOGRAPH
+0xCDCE	0x8FD3	#CJK UNIFIED IDEOGRAPH
+0xCDCF	0x8FCD	#CJK UNIFIED IDEOGRAPH
+0xCDD0	0x8FD6	#CJK UNIFIED IDEOGRAPH
+0xCDD1	0x8FD5	#CJK UNIFIED IDEOGRAPH
+0xCDD2	0x8FD7	#CJK UNIFIED IDEOGRAPH
+0xCDD3	0x90B2	#CJK UNIFIED IDEOGRAPH
+0xCDD4	0x90B4	#CJK UNIFIED IDEOGRAPH
+0xCDD5	0x90AF	#CJK UNIFIED IDEOGRAPH
+0xCDD6	0x90B3	#CJK UNIFIED IDEOGRAPH
+0xCDD7	0x90B0	#CJK UNIFIED IDEOGRAPH
+0xCDD8	0x9639	#CJK UNIFIED IDEOGRAPH
+0xCDD9	0x963D	#CJK UNIFIED IDEOGRAPH
+0xCDDA	0x963C	#CJK UNIFIED IDEOGRAPH
+0xCDDB	0x963A	#CJK UNIFIED IDEOGRAPH
+0xCDDC	0x9643	#CJK UNIFIED IDEOGRAPH
+0xCDDD	0x4FCD	#CJK UNIFIED IDEOGRAPH
+0xCDDE	0x4FC5	#CJK UNIFIED IDEOGRAPH
+0xCDDF	0x4FD3	#CJK UNIFIED IDEOGRAPH
+0xCDE0	0x4FB2	#CJK UNIFIED IDEOGRAPH
+0xCDE1	0x4FC9	#CJK UNIFIED IDEOGRAPH
+0xCDE2	0x4FCB	#CJK UNIFIED IDEOGRAPH
+0xCDE3	0x4FC1	#CJK UNIFIED IDEOGRAPH
+0xCDE4	0x4FD4	#CJK UNIFIED IDEOGRAPH
+0xCDE5	0x4FDC	#CJK UNIFIED IDEOGRAPH
+0xCDE6	0x4FD9	#CJK UNIFIED IDEOGRAPH
+0xCDE7	0x4FBB	#CJK UNIFIED IDEOGRAPH
+0xCDE8	0x4FB3	#CJK UNIFIED IDEOGRAPH
+0xCDE9	0x4FDB	#CJK UNIFIED IDEOGRAPH
+0xCDEA	0x4FC7	#CJK UNIFIED IDEOGRAPH
+0xCDEB	0x4FD6	#CJK UNIFIED IDEOGRAPH
+0xCDEC	0x4FBA	#CJK UNIFIED IDEOGRAPH
+0xCDED	0x4FC0	#CJK UNIFIED IDEOGRAPH
+0xCDEE	0x4FB9	#CJK UNIFIED IDEOGRAPH
+0xCDEF	0x4FEC	#CJK UNIFIED IDEOGRAPH
+0xCDF0	0x5244	#CJK UNIFIED IDEOGRAPH
+0xCDF1	0x5249	#CJK UNIFIED IDEOGRAPH
+0xCDF2	0x52C0	#CJK UNIFIED IDEOGRAPH
+0xCDF3	0x52C2	#CJK UNIFIED IDEOGRAPH
+0xCDF4	0x533D	#CJK UNIFIED IDEOGRAPH
+0xCDF5	0x537C	#CJK UNIFIED IDEOGRAPH
+0xCDF6	0x5397	#CJK UNIFIED IDEOGRAPH
+0xCDF7	0x5396	#CJK UNIFIED IDEOGRAPH
+0xCDF8	0x5399	#CJK UNIFIED IDEOGRAPH
+0xCDF9	0x5398	#CJK UNIFIED IDEOGRAPH
+0xCDFA	0x54BA	#CJK UNIFIED IDEOGRAPH
+0xCDFB	0x54A1	#CJK UNIFIED IDEOGRAPH
+0xCDFC	0x54AD	#CJK UNIFIED IDEOGRAPH
+0xCDFD	0x54A5	#CJK UNIFIED IDEOGRAPH
+0xCDFE	0x54CF	#CJK UNIFIED IDEOGRAPH
+0xCE40	0x54C3	#CJK UNIFIED IDEOGRAPH
+0xCE41	0x830D	#CJK UNIFIED IDEOGRAPH
+0xCE42	0x54B7	#CJK UNIFIED IDEOGRAPH
+0xCE43	0x54AE	#CJK UNIFIED IDEOGRAPH
+0xCE44	0x54D6	#CJK UNIFIED IDEOGRAPH
+0xCE45	0x54B6	#CJK UNIFIED IDEOGRAPH
+0xCE46	0x54C5	#CJK UNIFIED IDEOGRAPH
+0xCE47	0x54C6	#CJK UNIFIED IDEOGRAPH
+0xCE48	0x54A0	#CJK UNIFIED IDEOGRAPH
+0xCE49	0x5470	#CJK UNIFIED IDEOGRAPH
+0xCE4A	0x54BC	#CJK UNIFIED IDEOGRAPH
+0xCE4B	0x54A2	#CJK UNIFIED IDEOGRAPH
+0xCE4C	0x54BE	#CJK UNIFIED IDEOGRAPH
+0xCE4D	0x5472	#CJK UNIFIED IDEOGRAPH
+0xCE4E	0x54DE	#CJK UNIFIED IDEOGRAPH
+0xCE4F	0x54B0	#CJK UNIFIED IDEOGRAPH
+0xCE50	0x57B5	#CJK UNIFIED IDEOGRAPH
+0xCE51	0x579E	#CJK UNIFIED IDEOGRAPH
+0xCE52	0x579F	#CJK UNIFIED IDEOGRAPH
+0xCE53	0x57A4	#CJK UNIFIED IDEOGRAPH
+0xCE54	0x578C	#CJK UNIFIED IDEOGRAPH
+0xCE55	0x5797	#CJK UNIFIED IDEOGRAPH
+0xCE56	0x579D	#CJK UNIFIED IDEOGRAPH
+0xCE57	0x579B	#CJK UNIFIED IDEOGRAPH
+0xCE58	0x5794	#CJK UNIFIED IDEOGRAPH
+0xCE59	0x5798	#CJK UNIFIED IDEOGRAPH
+0xCE5A	0x578F	#CJK UNIFIED IDEOGRAPH
+0xCE5B	0x5799	#CJK UNIFIED IDEOGRAPH
+0xCE5C	0x57A5	#CJK UNIFIED IDEOGRAPH
+0xCE5D	0x579A	#CJK UNIFIED IDEOGRAPH
+0xCE5E	0x5795	#CJK UNIFIED IDEOGRAPH
+0xCE5F	0x58F4	#CJK UNIFIED IDEOGRAPH
+0xCE60	0x590D	#CJK UNIFIED IDEOGRAPH
+0xCE61	0x5953	#CJK UNIFIED IDEOGRAPH
+0xCE62	0x59E1	#CJK UNIFIED IDEOGRAPH
+0xCE63	0x59DE	#CJK UNIFIED IDEOGRAPH
+0xCE64	0x59EE	#CJK UNIFIED IDEOGRAPH
+0xCE65	0x5A00	#CJK UNIFIED IDEOGRAPH
+0xCE66	0x59F1	#CJK UNIFIED IDEOGRAPH
+0xCE67	0x59DD	#CJK UNIFIED IDEOGRAPH
+0xCE68	0x59FA	#CJK UNIFIED IDEOGRAPH
+0xCE69	0x59FD	#CJK UNIFIED IDEOGRAPH
+0xCE6A	0x59FC	#CJK UNIFIED IDEOGRAPH
+0xCE6B	0x59F6	#CJK UNIFIED IDEOGRAPH
+0xCE6C	0x59E4	#CJK UNIFIED IDEOGRAPH
+0xCE6D	0x59F2	#CJK UNIFIED IDEOGRAPH
+0xCE6E	0x59F7	#CJK UNIFIED IDEOGRAPH
+0xCE6F	0x59DB	#CJK UNIFIED IDEOGRAPH
+0xCE70	0x59E9	#CJK UNIFIED IDEOGRAPH
+0xCE71	0x59F3	#CJK UNIFIED IDEOGRAPH
+0xCE72	0x59F5	#CJK UNIFIED IDEOGRAPH
+0xCE73	0x59E0	#CJK UNIFIED IDEOGRAPH
+0xCE74	0x59FE	#CJK UNIFIED IDEOGRAPH
+0xCE75	0x59F4	#CJK UNIFIED IDEOGRAPH
+0xCE76	0x59ED	#CJK UNIFIED IDEOGRAPH
+0xCE77	0x5BA8	#CJK UNIFIED IDEOGRAPH
+0xCE78	0x5C4C	#CJK UNIFIED IDEOGRAPH
+0xCE79	0x5CD0	#CJK UNIFIED IDEOGRAPH
+0xCE7A	0x5CD8	#CJK UNIFIED IDEOGRAPH
+0xCE7B	0x5CCC	#CJK UNIFIED IDEOGRAPH
+0xCE7C	0x5CD7	#CJK UNIFIED IDEOGRAPH
+0xCE7D	0x5CCB	#CJK UNIFIED IDEOGRAPH
+0xCE7E	0x5CDB	#CJK UNIFIED IDEOGRAPH
+0xCEA1	0x5CDE	#CJK UNIFIED IDEOGRAPH
+0xCEA2	0x5CDA	#CJK UNIFIED IDEOGRAPH
+0xCEA3	0x5CC9	#CJK UNIFIED IDEOGRAPH
+0xCEA4	0x5CC7	#CJK UNIFIED IDEOGRAPH
+0xCEA5	0x5CCA	#CJK UNIFIED IDEOGRAPH
+0xCEA6	0x5CD6	#CJK UNIFIED IDEOGRAPH
+0xCEA7	0x5CD3	#CJK UNIFIED IDEOGRAPH
+0xCEA8	0x5CD4	#CJK UNIFIED IDEOGRAPH
+0xCEA9	0x5CCF	#CJK UNIFIED IDEOGRAPH
+0xCEAA	0x5CC8	#CJK UNIFIED IDEOGRAPH
+0xCEAB	0x5CC6	#CJK UNIFIED IDEOGRAPH
+0xCEAC	0x5CCE	#CJK UNIFIED IDEOGRAPH
+0xCEAD	0x5CDF	#CJK UNIFIED IDEOGRAPH
+0xCEAE	0x5CF8	#CJK UNIFIED IDEOGRAPH
+0xCEAF	0x5DF9	#CJK UNIFIED IDEOGRAPH
+0xCEB0	0x5E21	#CJK UNIFIED IDEOGRAPH
+0xCEB1	0x5E22	#CJK UNIFIED IDEOGRAPH
+0xCEB2	0x5E23	#CJK UNIFIED IDEOGRAPH
+0xCEB3	0x5E20	#CJK UNIFIED IDEOGRAPH
+0xCEB4	0x5E24	#CJK UNIFIED IDEOGRAPH
+0xCEB5	0x5EB0	#CJK UNIFIED IDEOGRAPH
+0xCEB6	0x5EA4	#CJK UNIFIED IDEOGRAPH
+0xCEB7	0x5EA2	#CJK UNIFIED IDEOGRAPH
+0xCEB8	0x5E9B	#CJK UNIFIED IDEOGRAPH
+0xCEB9	0x5EA3	#CJK UNIFIED IDEOGRAPH
+0xCEBA	0x5EA5	#CJK UNIFIED IDEOGRAPH
+0xCEBB	0x5F07	#CJK UNIFIED IDEOGRAPH
+0xCEBC	0x5F2E	#CJK UNIFIED IDEOGRAPH
+0xCEBD	0x5F56	#CJK UNIFIED IDEOGRAPH
+0xCEBE	0x5F86	#CJK UNIFIED IDEOGRAPH
+0xCEBF	0x6037	#CJK UNIFIED IDEOGRAPH
+0xCEC0	0x6039	#CJK UNIFIED IDEOGRAPH
+0xCEC1	0x6054	#CJK UNIFIED IDEOGRAPH
+0xCEC2	0x6072	#CJK UNIFIED IDEOGRAPH
+0xCEC3	0x605E	#CJK UNIFIED IDEOGRAPH
+0xCEC4	0x6045	#CJK UNIFIED IDEOGRAPH
+0xCEC5	0x6053	#CJK UNIFIED IDEOGRAPH
+0xCEC6	0x6047	#CJK UNIFIED IDEOGRAPH
+0xCEC7	0x6049	#CJK UNIFIED IDEOGRAPH
+0xCEC8	0x605B	#CJK UNIFIED IDEOGRAPH
+0xCEC9	0x604C	#CJK UNIFIED IDEOGRAPH
+0xCECA	0x6040	#CJK UNIFIED IDEOGRAPH
+0xCECB	0x6042	#CJK UNIFIED IDEOGRAPH
+0xCECC	0x605F	#CJK UNIFIED IDEOGRAPH
+0xCECD	0x6024	#CJK UNIFIED IDEOGRAPH
+0xCECE	0x6044	#CJK UNIFIED IDEOGRAPH
+0xCECF	0x6058	#CJK UNIFIED IDEOGRAPH
+0xCED0	0x6066	#CJK UNIFIED IDEOGRAPH
+0xCED1	0x606E	#CJK UNIFIED IDEOGRAPH
+0xCED2	0x6242	#CJK UNIFIED IDEOGRAPH
+0xCED3	0x6243	#CJK UNIFIED IDEOGRAPH
+0xCED4	0x62CF	#CJK UNIFIED IDEOGRAPH
+0xCED5	0x630D	#CJK UNIFIED IDEOGRAPH
+0xCED6	0x630B	#CJK UNIFIED IDEOGRAPH
+0xCED7	0x62F5	#CJK UNIFIED IDEOGRAPH
+0xCED8	0x630E	#CJK UNIFIED IDEOGRAPH
+0xCED9	0x6303	#CJK UNIFIED IDEOGRAPH
+0xCEDA	0x62EB	#CJK UNIFIED IDEOGRAPH
+0xCEDB	0x62F9	#CJK UNIFIED IDEOGRAPH
+0xCEDC	0x630F	#CJK UNIFIED IDEOGRAPH
+0xCEDD	0x630C	#CJK UNIFIED IDEOGRAPH
+0xCEDE	0x62F8	#CJK UNIFIED IDEOGRAPH
+0xCEDF	0x62F6	#CJK UNIFIED IDEOGRAPH
+0xCEE0	0x6300	#CJK UNIFIED IDEOGRAPH
+0xCEE1	0x6313	#CJK UNIFIED IDEOGRAPH
+0xCEE2	0x6314	#CJK UNIFIED IDEOGRAPH
+0xCEE3	0x62FA	#CJK UNIFIED IDEOGRAPH
+0xCEE4	0x6315	#CJK UNIFIED IDEOGRAPH
+0xCEE5	0x62FB	#CJK UNIFIED IDEOGRAPH
+0xCEE6	0x62F0	#CJK UNIFIED IDEOGRAPH
+0xCEE7	0x6541	#CJK UNIFIED IDEOGRAPH
+0xCEE8	0x6543	#CJK UNIFIED IDEOGRAPH
+0xCEE9	0x65AA	#CJK UNIFIED IDEOGRAPH
+0xCEEA	0x65BF	#CJK UNIFIED IDEOGRAPH
+0xCEEB	0x6636	#CJK UNIFIED IDEOGRAPH
+0xCEEC	0x6621	#CJK UNIFIED IDEOGRAPH
+0xCEED	0x6632	#CJK UNIFIED IDEOGRAPH
+0xCEEE	0x6635	#CJK UNIFIED IDEOGRAPH
+0xCEEF	0x661C	#CJK UNIFIED IDEOGRAPH
+0xCEF0	0x6626	#CJK UNIFIED IDEOGRAPH
+0xCEF1	0x6622	#CJK UNIFIED IDEOGRAPH
+0xCEF2	0x6633	#CJK UNIFIED IDEOGRAPH
+0xCEF3	0x662B	#CJK UNIFIED IDEOGRAPH
+0xCEF4	0x663A	#CJK UNIFIED IDEOGRAPH
+0xCEF5	0x661D	#CJK UNIFIED IDEOGRAPH
+0xCEF6	0x6634	#CJK UNIFIED IDEOGRAPH
+0xCEF7	0x6639	#CJK UNIFIED IDEOGRAPH
+0xCEF8	0x662E	#CJK UNIFIED IDEOGRAPH
+0xCEF9	0x670F	#CJK UNIFIED IDEOGRAPH
+0xCEFA	0x6710	#CJK UNIFIED IDEOGRAPH
+0xCEFB	0x67C1	#CJK UNIFIED IDEOGRAPH
+0xCEFC	0x67F2	#CJK UNIFIED IDEOGRAPH
+0xCEFD	0x67C8	#CJK UNIFIED IDEOGRAPH
+0xCEFE	0x67BA	#CJK UNIFIED IDEOGRAPH
+0xCF40	0x67DC	#CJK UNIFIED IDEOGRAPH
+0xCF41	0x67BB	#CJK UNIFIED IDEOGRAPH
+0xCF42	0x67F8	#CJK UNIFIED IDEOGRAPH
+0xCF43	0x67D8	#CJK UNIFIED IDEOGRAPH
+0xCF44	0x67C0	#CJK UNIFIED IDEOGRAPH
+0xCF45	0x67B7	#CJK UNIFIED IDEOGRAPH
+0xCF46	0x67C5	#CJK UNIFIED IDEOGRAPH
+0xCF47	0x67EB	#CJK UNIFIED IDEOGRAPH
+0xCF48	0x67E4	#CJK UNIFIED IDEOGRAPH
+0xCF49	0x67DF	#CJK UNIFIED IDEOGRAPH
+0xCF4A	0x67B5	#CJK UNIFIED IDEOGRAPH
+0xCF4B	0x67CD	#CJK UNIFIED IDEOGRAPH
+0xCF4C	0x67B3	#CJK UNIFIED IDEOGRAPH
+0xCF4D	0x67F7	#CJK UNIFIED IDEOGRAPH
+0xCF4E	0x67F6	#CJK UNIFIED IDEOGRAPH
+0xCF4F	0x67EE	#CJK UNIFIED IDEOGRAPH
+0xCF50	0x67E3	#CJK UNIFIED IDEOGRAPH
+0xCF51	0x67C2	#CJK UNIFIED IDEOGRAPH
+0xCF52	0x67B9	#CJK UNIFIED IDEOGRAPH
+0xCF53	0x67CE	#CJK UNIFIED IDEOGRAPH
+0xCF54	0x67E7	#CJK UNIFIED IDEOGRAPH
+0xCF55	0x67F0	#CJK UNIFIED IDEOGRAPH
+0xCF56	0x67B2	#CJK UNIFIED IDEOGRAPH
+0xCF57	0x67FC	#CJK UNIFIED IDEOGRAPH
+0xCF58	0x67C6	#CJK UNIFIED IDEOGRAPH
+0xCF59	0x67ED	#CJK UNIFIED IDEOGRAPH
+0xCF5A	0x67CC	#CJK UNIFIED IDEOGRAPH
+0xCF5B	0x67AE	#CJK UNIFIED IDEOGRAPH
+0xCF5C	0x67E6	#CJK UNIFIED IDEOGRAPH
+0xCF5D	0x67DB	#CJK UNIFIED IDEOGRAPH
+0xCF5E	0x67FA	#CJK UNIFIED IDEOGRAPH
+0xCF5F	0x67C9	#CJK UNIFIED IDEOGRAPH
+0xCF60	0x67CA	#CJK UNIFIED IDEOGRAPH
+0xCF61	0x67C3	#CJK UNIFIED IDEOGRAPH
+0xCF62	0x67EA	#CJK UNIFIED IDEOGRAPH
+0xCF63	0x67CB	#CJK UNIFIED IDEOGRAPH
+0xCF64	0x6B28	#CJK UNIFIED IDEOGRAPH
+0xCF65	0x6B82	#CJK UNIFIED IDEOGRAPH
+0xCF66	0x6B84	#CJK UNIFIED IDEOGRAPH
+0xCF67	0x6BB6	#CJK UNIFIED IDEOGRAPH
+0xCF68	0x6BD6	#CJK UNIFIED IDEOGRAPH
+0xCF69	0x6BD8	#CJK UNIFIED IDEOGRAPH
+0xCF6A	0x6BE0	#CJK UNIFIED IDEOGRAPH
+0xCF6B	0x6C20	#CJK UNIFIED IDEOGRAPH
+0xCF6C	0x6C21	#CJK UNIFIED IDEOGRAPH
+0xCF6D	0x6D28	#CJK UNIFIED IDEOGRAPH
+0xCF6E	0x6D34	#CJK UNIFIED IDEOGRAPH
+0xCF6F	0x6D2D	#CJK UNIFIED IDEOGRAPH
+0xCF70	0x6D1F	#CJK UNIFIED IDEOGRAPH
+0xCF71	0x6D3C	#CJK UNIFIED IDEOGRAPH
+0xCF72	0x6D3F	#CJK UNIFIED IDEOGRAPH
+0xCF73	0x6D12	#CJK UNIFIED IDEOGRAPH
+0xCF74	0x6D0A	#CJK UNIFIED IDEOGRAPH
+0xCF75	0x6CDA	#CJK UNIFIED IDEOGRAPH
+0xCF76	0x6D33	#CJK UNIFIED IDEOGRAPH
+0xCF77	0x6D04	#CJK UNIFIED IDEOGRAPH
+0xCF78	0x6D19	#CJK UNIFIED IDEOGRAPH
+0xCF79	0x6D3A	#CJK UNIFIED IDEOGRAPH
+0xCF7A	0x6D1A	#CJK UNIFIED IDEOGRAPH
+0xCF7B	0x6D11	#CJK UNIFIED IDEOGRAPH
+0xCF7C	0x6D00	#CJK UNIFIED IDEOGRAPH
+0xCF7D	0x6D1D	#CJK UNIFIED IDEOGRAPH
+0xCF7E	0x6D42	#CJK UNIFIED IDEOGRAPH
+0xCFA1	0x6D01	#CJK UNIFIED IDEOGRAPH
+0xCFA2	0x6D18	#CJK UNIFIED IDEOGRAPH
+0xCFA3	0x6D37	#CJK UNIFIED IDEOGRAPH
+0xCFA4	0x6D03	#CJK UNIFIED IDEOGRAPH
+0xCFA5	0x6D0F	#CJK UNIFIED IDEOGRAPH
+0xCFA6	0x6D40	#CJK UNIFIED IDEOGRAPH
+0xCFA7	0x6D07	#CJK UNIFIED IDEOGRAPH
+0xCFA8	0x6D20	#CJK UNIFIED IDEOGRAPH
+0xCFA9	0x6D2C	#CJK UNIFIED IDEOGRAPH
+0xCFAA	0x6D08	#CJK UNIFIED IDEOGRAPH
+0xCFAB	0x6D22	#CJK UNIFIED IDEOGRAPH
+0xCFAC	0x6D09	#CJK UNIFIED IDEOGRAPH
+0xCFAD	0x6D10	#CJK UNIFIED IDEOGRAPH
+0xCFAE	0x70B7	#CJK UNIFIED IDEOGRAPH
+0xCFAF	0x709F	#CJK UNIFIED IDEOGRAPH
+0xCFB0	0x70BE	#CJK UNIFIED IDEOGRAPH
+0xCFB1	0x70B1	#CJK UNIFIED IDEOGRAPH
+0xCFB2	0x70B0	#CJK UNIFIED IDEOGRAPH
+0xCFB3	0x70A1	#CJK UNIFIED IDEOGRAPH
+0xCFB4	0x70B4	#CJK UNIFIED IDEOGRAPH
+0xCFB5	0x70B5	#CJK UNIFIED IDEOGRAPH
+0xCFB6	0x70A9	#CJK UNIFIED IDEOGRAPH
+0xCFB7	0x7241	#CJK UNIFIED IDEOGRAPH
+0xCFB8	0x7249	#CJK UNIFIED IDEOGRAPH
+0xCFB9	0x724A	#CJK UNIFIED IDEOGRAPH
+0xCFBA	0x726C	#CJK UNIFIED IDEOGRAPH
+0xCFBB	0x7270	#CJK UNIFIED IDEOGRAPH
+0xCFBC	0x7273	#CJK UNIFIED IDEOGRAPH
+0xCFBD	0x726E	#CJK UNIFIED IDEOGRAPH
+0xCFBE	0x72CA	#CJK UNIFIED IDEOGRAPH
+0xCFBF	0x72E4	#CJK UNIFIED IDEOGRAPH
+0xCFC0	0x72E8	#CJK UNIFIED IDEOGRAPH
+0xCFC1	0x72EB	#CJK UNIFIED IDEOGRAPH
+0xCFC2	0x72DF	#CJK UNIFIED IDEOGRAPH
+0xCFC3	0x72EA	#CJK UNIFIED IDEOGRAPH
+0xCFC4	0x72E6	#CJK UNIFIED IDEOGRAPH
+0xCFC5	0x72E3	#CJK UNIFIED IDEOGRAPH
+0xCFC6	0x7385	#CJK UNIFIED IDEOGRAPH
+0xCFC7	0x73CC	#CJK UNIFIED IDEOGRAPH
+0xCFC8	0x73C2	#CJK UNIFIED IDEOGRAPH
+0xCFC9	0x73C8	#CJK UNIFIED IDEOGRAPH
+0xCFCA	0x73C5	#CJK UNIFIED IDEOGRAPH
+0xCFCB	0x73B9	#CJK UNIFIED IDEOGRAPH
+0xCFCC	0x73B6	#CJK UNIFIED IDEOGRAPH
+0xCFCD	0x73B5	#CJK UNIFIED IDEOGRAPH
+0xCFCE	0x73B4	#CJK UNIFIED IDEOGRAPH
+0xCFCF	0x73EB	#CJK UNIFIED IDEOGRAPH
+0xCFD0	0x73BF	#CJK UNIFIED IDEOGRAPH
+0xCFD1	0x73C7	#CJK UNIFIED IDEOGRAPH
+0xCFD2	0x73BE	#CJK UNIFIED IDEOGRAPH
+0xCFD3	0x73C3	#CJK UNIFIED IDEOGRAPH
+0xCFD4	0x73C6	#CJK UNIFIED IDEOGRAPH
+0xCFD5	0x73B8	#CJK UNIFIED IDEOGRAPH
+0xCFD6	0x73CB	#CJK UNIFIED IDEOGRAPH
+0xCFD7	0x74EC	#CJK UNIFIED IDEOGRAPH
+0xCFD8	0x74EE	#CJK UNIFIED IDEOGRAPH
+0xCFD9	0x752E	#CJK UNIFIED IDEOGRAPH
+0xCFDA	0x7547	#CJK UNIFIED IDEOGRAPH
+0xCFDB	0x7548	#CJK UNIFIED IDEOGRAPH
+0xCFDC	0x75A7	#CJK UNIFIED IDEOGRAPH
+0xCFDD	0x75AA	#CJK UNIFIED IDEOGRAPH
+0xCFDE	0x7679	#CJK UNIFIED IDEOGRAPH
+0xCFDF	0x76C4	#CJK UNIFIED IDEOGRAPH
+0xCFE0	0x7708	#CJK UNIFIED IDEOGRAPH
+0xCFE1	0x7703	#CJK UNIFIED IDEOGRAPH
+0xCFE2	0x7704	#CJK UNIFIED IDEOGRAPH
+0xCFE3	0x7705	#CJK UNIFIED IDEOGRAPH
+0xCFE4	0x770A	#CJK UNIFIED IDEOGRAPH
+0xCFE5	0x76F7	#CJK UNIFIED IDEOGRAPH
+0xCFE6	0x76FB	#CJK UNIFIED IDEOGRAPH
+0xCFE7	0x76FA	#CJK UNIFIED IDEOGRAPH
+0xCFE8	0x77E7	#CJK UNIFIED IDEOGRAPH
+0xCFE9	0x77E8	#CJK UNIFIED IDEOGRAPH
+0xCFEA	0x7806	#CJK UNIFIED IDEOGRAPH
+0xCFEB	0x7811	#CJK UNIFIED IDEOGRAPH
+0xCFEC	0x7812	#CJK UNIFIED IDEOGRAPH
+0xCFED	0x7805	#CJK UNIFIED IDEOGRAPH
+0xCFEE	0x7810	#CJK UNIFIED IDEOGRAPH
+0xCFEF	0x780F	#CJK UNIFIED IDEOGRAPH
+0xCFF0	0x780E	#CJK UNIFIED IDEOGRAPH
+0xCFF1	0x7809	#CJK UNIFIED IDEOGRAPH
+0xCFF2	0x7803	#CJK UNIFIED IDEOGRAPH
+0xCFF3	0x7813	#CJK UNIFIED IDEOGRAPH
+0xCFF4	0x794A	#CJK UNIFIED IDEOGRAPH
+0xCFF5	0x794C	#CJK UNIFIED IDEOGRAPH
+0xCFF6	0x794B	#CJK UNIFIED IDEOGRAPH
+0xCFF7	0x7945	#CJK UNIFIED IDEOGRAPH
+0xCFF8	0x7944	#CJK UNIFIED IDEOGRAPH
+0xCFF9	0x79D5	#CJK UNIFIED IDEOGRAPH
+0xCFFA	0x79CD	#CJK UNIFIED IDEOGRAPH
+0xCFFB	0x79CF	#CJK UNIFIED IDEOGRAPH
+0xCFFC	0x79D6	#CJK UNIFIED IDEOGRAPH
+0xCFFD	0x79CE	#CJK UNIFIED IDEOGRAPH
+0xCFFE	0x7A80	#CJK UNIFIED IDEOGRAPH
+0xD040	0x7A7E	#CJK UNIFIED IDEOGRAPH
+0xD041	0x7AD1	#CJK UNIFIED IDEOGRAPH
+0xD042	0x7B00	#CJK UNIFIED IDEOGRAPH
+0xD043	0x7B01	#CJK UNIFIED IDEOGRAPH
+0xD044	0x7C7A	#CJK UNIFIED IDEOGRAPH
+0xD045	0x7C78	#CJK UNIFIED IDEOGRAPH
+0xD046	0x7C79	#CJK UNIFIED IDEOGRAPH
+0xD047	0x7C7F	#CJK UNIFIED IDEOGRAPH
+0xD048	0x7C80	#CJK UNIFIED IDEOGRAPH
+0xD049	0x7C81	#CJK UNIFIED IDEOGRAPH
+0xD04A	0x7D03	#CJK UNIFIED IDEOGRAPH
+0xD04B	0x7D08	#CJK UNIFIED IDEOGRAPH
+0xD04C	0x7D01	#CJK UNIFIED IDEOGRAPH
+0xD04D	0x7F58	#CJK UNIFIED IDEOGRAPH
+0xD04E	0x7F91	#CJK UNIFIED IDEOGRAPH
+0xD04F	0x7F8D	#CJK UNIFIED IDEOGRAPH
+0xD050	0x7FBE	#CJK UNIFIED IDEOGRAPH
+0xD051	0x8007	#CJK UNIFIED IDEOGRAPH
+0xD052	0x800E	#CJK UNIFIED IDEOGRAPH
+0xD053	0x800F	#CJK UNIFIED IDEOGRAPH
+0xD054	0x8014	#CJK UNIFIED IDEOGRAPH
+0xD055	0x8037	#CJK UNIFIED IDEOGRAPH
+0xD056	0x80D8	#CJK UNIFIED IDEOGRAPH
+0xD057	0x80C7	#CJK UNIFIED IDEOGRAPH
+0xD058	0x80E0	#CJK UNIFIED IDEOGRAPH
+0xD059	0x80D1	#CJK UNIFIED IDEOGRAPH
+0xD05A	0x80C8	#CJK UNIFIED IDEOGRAPH
+0xD05B	0x80C2	#CJK UNIFIED IDEOGRAPH
+0xD05C	0x80D0	#CJK UNIFIED IDEOGRAPH
+0xD05D	0x80C5	#CJK UNIFIED IDEOGRAPH
+0xD05E	0x80E3	#CJK UNIFIED IDEOGRAPH
+0xD05F	0x80D9	#CJK UNIFIED IDEOGRAPH
+0xD060	0x80DC	#CJK UNIFIED IDEOGRAPH
+0xD061	0x80CA	#CJK UNIFIED IDEOGRAPH
+0xD062	0x80D5	#CJK UNIFIED IDEOGRAPH
+0xD063	0x80C9	#CJK UNIFIED IDEOGRAPH
+0xD064	0x80CF	#CJK UNIFIED IDEOGRAPH
+0xD065	0x80D7	#CJK UNIFIED IDEOGRAPH
+0xD066	0x80E6	#CJK UNIFIED IDEOGRAPH
+0xD067	0x80CD	#CJK UNIFIED IDEOGRAPH
+0xD068	0x81FF	#CJK UNIFIED IDEOGRAPH
+0xD069	0x8221	#CJK UNIFIED IDEOGRAPH
+0xD06A	0x8294	#CJK UNIFIED IDEOGRAPH
+0xD06B	0x82D9	#CJK UNIFIED IDEOGRAPH
+0xD06C	0x82FE	#CJK UNIFIED IDEOGRAPH
+0xD06D	0x82F9	#CJK UNIFIED IDEOGRAPH
+0xD06E	0x8307	#CJK UNIFIED IDEOGRAPH
+0xD06F	0x82E8	#CJK UNIFIED IDEOGRAPH
+0xD070	0x8300	#CJK UNIFIED IDEOGRAPH
+0xD071	0x82D5	#CJK UNIFIED IDEOGRAPH
+0xD072	0x833A	#CJK UNIFIED IDEOGRAPH
+0xD073	0x82EB	#CJK UNIFIED IDEOGRAPH
+0xD074	0x82D6	#CJK UNIFIED IDEOGRAPH
+0xD075	0x82F4	#CJK UNIFIED IDEOGRAPH
+0xD076	0x82EC	#CJK UNIFIED IDEOGRAPH
+0xD077	0x82E1	#CJK UNIFIED IDEOGRAPH
+0xD078	0x82F2	#CJK UNIFIED IDEOGRAPH
+0xD079	0x82F5	#CJK UNIFIED IDEOGRAPH
+0xD07A	0x830C	#CJK UNIFIED IDEOGRAPH
+0xD07B	0x82FB	#CJK UNIFIED IDEOGRAPH
+0xD07C	0x82F6	#CJK UNIFIED IDEOGRAPH
+0xD07D	0x82F0	#CJK UNIFIED IDEOGRAPH
+0xD07E	0x82EA	#CJK UNIFIED IDEOGRAPH
+0xD0A1	0x82E4	#CJK UNIFIED IDEOGRAPH
+0xD0A2	0x82E0	#CJK UNIFIED IDEOGRAPH
+0xD0A3	0x82FA	#CJK UNIFIED IDEOGRAPH
+0xD0A4	0x82F3	#CJK UNIFIED IDEOGRAPH
+0xD0A5	0x82ED	#CJK UNIFIED IDEOGRAPH
+0xD0A6	0x8677	#CJK UNIFIED IDEOGRAPH
+0xD0A7	0x8674	#CJK UNIFIED IDEOGRAPH
+0xD0A8	0x867C	#CJK UNIFIED IDEOGRAPH
+0xD0A9	0x8673	#CJK UNIFIED IDEOGRAPH
+0xD0AA	0x8841	#CJK UNIFIED IDEOGRAPH
+0xD0AB	0x884E	#CJK UNIFIED IDEOGRAPH
+0xD0AC	0x8867	#CJK UNIFIED IDEOGRAPH
+0xD0AD	0x886A	#CJK UNIFIED IDEOGRAPH
+0xD0AE	0x8869	#CJK UNIFIED IDEOGRAPH
+0xD0AF	0x89D3	#CJK UNIFIED IDEOGRAPH
+0xD0B0	0x8A04	#CJK UNIFIED IDEOGRAPH
+0xD0B1	0x8A07	#CJK UNIFIED IDEOGRAPH
+0xD0B2	0x8D72	#CJK UNIFIED IDEOGRAPH
+0xD0B3	0x8FE3	#CJK UNIFIED IDEOGRAPH
+0xD0B4	0x8FE1	#CJK UNIFIED IDEOGRAPH
+0xD0B5	0x8FEE	#CJK UNIFIED IDEOGRAPH
+0xD0B6	0x8FE0	#CJK UNIFIED IDEOGRAPH
+0xD0B7	0x90F1	#CJK UNIFIED IDEOGRAPH
+0xD0B8	0x90BD	#CJK UNIFIED IDEOGRAPH
+0xD0B9	0x90BF	#CJK UNIFIED IDEOGRAPH
+0xD0BA	0x90D5	#CJK UNIFIED IDEOGRAPH
+0xD0BB	0x90C5	#CJK UNIFIED IDEOGRAPH
+0xD0BC	0x90BE	#CJK UNIFIED IDEOGRAPH
+0xD0BD	0x90C7	#CJK UNIFIED IDEOGRAPH
+0xD0BE	0x90CB	#CJK UNIFIED IDEOGRAPH
+0xD0BF	0x90C8	#CJK UNIFIED IDEOGRAPH
+0xD0C0	0x91D4	#CJK UNIFIED IDEOGRAPH
+0xD0C1	0x91D3	#CJK UNIFIED IDEOGRAPH
+0xD0C2	0x9654	#CJK UNIFIED IDEOGRAPH
+0xD0C3	0x964F	#CJK UNIFIED IDEOGRAPH
+0xD0C4	0x9651	#CJK UNIFIED IDEOGRAPH
+0xD0C5	0x9653	#CJK UNIFIED IDEOGRAPH
+0xD0C6	0x964A	#CJK UNIFIED IDEOGRAPH
+0xD0C7	0x964E	#CJK UNIFIED IDEOGRAPH
+0xD0C8	0x501E	#CJK UNIFIED IDEOGRAPH
+0xD0C9	0x5005	#CJK UNIFIED IDEOGRAPH
+0xD0CA	0x5007	#CJK UNIFIED IDEOGRAPH
+0xD0CB	0x5013	#CJK UNIFIED IDEOGRAPH
+0xD0CC	0x5022	#CJK UNIFIED IDEOGRAPH
+0xD0CD	0x5030	#CJK UNIFIED IDEOGRAPH
+0xD0CE	0x501B	#CJK UNIFIED IDEOGRAPH
+0xD0CF	0x4FF5	#CJK UNIFIED IDEOGRAPH
+0xD0D0	0x4FF4	#CJK UNIFIED IDEOGRAPH
+0xD0D1	0x5033	#CJK UNIFIED IDEOGRAPH
+0xD0D2	0x5037	#CJK UNIFIED IDEOGRAPH
+0xD0D3	0x502C	#CJK UNIFIED IDEOGRAPH
+0xD0D4	0x4FF6	#CJK UNIFIED IDEOGRAPH
+0xD0D5	0x4FF7	#CJK UNIFIED IDEOGRAPH
+0xD0D6	0x5017	#CJK UNIFIED IDEOGRAPH
+0xD0D7	0x501C	#CJK UNIFIED IDEOGRAPH
+0xD0D8	0x5020	#CJK UNIFIED IDEOGRAPH
+0xD0D9	0x5027	#CJK UNIFIED IDEOGRAPH
+0xD0DA	0x5035	#CJK UNIFIED IDEOGRAPH
+0xD0DB	0x502F	#CJK UNIFIED IDEOGRAPH
+0xD0DC	0x5031	#CJK UNIFIED IDEOGRAPH
+0xD0DD	0x500E	#CJK UNIFIED IDEOGRAPH
+0xD0DE	0x515A	#CJK UNIFIED IDEOGRAPH
+0xD0DF	0x5194	#CJK UNIFIED IDEOGRAPH
+0xD0E0	0x5193	#CJK UNIFIED IDEOGRAPH
+0xD0E1	0x51CA	#CJK UNIFIED IDEOGRAPH
+0xD0E2	0x51C4	#CJK UNIFIED IDEOGRAPH
+0xD0E3	0x51C5	#CJK UNIFIED IDEOGRAPH
+0xD0E4	0x51C8	#CJK UNIFIED IDEOGRAPH
+0xD0E5	0x51CE	#CJK UNIFIED IDEOGRAPH
+0xD0E6	0x5261	#CJK UNIFIED IDEOGRAPH
+0xD0E7	0x525A	#CJK UNIFIED IDEOGRAPH
+0xD0E8	0x5252	#CJK UNIFIED IDEOGRAPH
+0xD0E9	0x525E	#CJK UNIFIED IDEOGRAPH
+0xD0EA	0x525F	#CJK UNIFIED IDEOGRAPH
+0xD0EB	0x5255	#CJK UNIFIED IDEOGRAPH
+0xD0EC	0x5262	#CJK UNIFIED IDEOGRAPH
+0xD0ED	0x52CD	#CJK UNIFIED IDEOGRAPH
+0xD0EE	0x530E	#CJK UNIFIED IDEOGRAPH
+0xD0EF	0x539E	#CJK UNIFIED IDEOGRAPH
+0xD0F0	0x5526	#CJK UNIFIED IDEOGRAPH
+0xD0F1	0x54E2	#CJK UNIFIED IDEOGRAPH
+0xD0F2	0x5517	#CJK UNIFIED IDEOGRAPH
+0xD0F3	0x5512	#CJK UNIFIED IDEOGRAPH
+0xD0F4	0x54E7	#CJK UNIFIED IDEOGRAPH
+0xD0F5	0x54F3	#CJK UNIFIED IDEOGRAPH
+0xD0F6	0x54E4	#CJK UNIFIED IDEOGRAPH
+0xD0F7	0x551A	#CJK UNIFIED IDEOGRAPH
+0xD0F8	0x54FF	#CJK UNIFIED IDEOGRAPH
+0xD0F9	0x5504	#CJK UNIFIED IDEOGRAPH
+0xD0FA	0x5508	#CJK UNIFIED IDEOGRAPH
+0xD0FB	0x54EB	#CJK UNIFIED IDEOGRAPH
+0xD0FC	0x5511	#CJK UNIFIED IDEOGRAPH
+0xD0FD	0x5505	#CJK UNIFIED IDEOGRAPH
+0xD0FE	0x54F1	#CJK UNIFIED IDEOGRAPH
+0xD140	0x550A	#CJK UNIFIED IDEOGRAPH
+0xD141	0x54FB	#CJK UNIFIED IDEOGRAPH
+0xD142	0x54F7	#CJK UNIFIED IDEOGRAPH
+0xD143	0x54F8	#CJK UNIFIED IDEOGRAPH
+0xD144	0x54E0	#CJK UNIFIED IDEOGRAPH
+0xD145	0x550E	#CJK UNIFIED IDEOGRAPH
+0xD146	0x5503	#CJK UNIFIED IDEOGRAPH
+0xD147	0x550B	#CJK UNIFIED IDEOGRAPH
+0xD148	0x5701	#CJK UNIFIED IDEOGRAPH
+0xD149	0x5702	#CJK UNIFIED IDEOGRAPH
+0xD14A	0x57CC	#CJK UNIFIED IDEOGRAPH
+0xD14B	0x5832	#CJK UNIFIED IDEOGRAPH
+0xD14C	0x57D5	#CJK UNIFIED IDEOGRAPH
+0xD14D	0x57D2	#CJK UNIFIED IDEOGRAPH
+0xD14E	0x57BA	#CJK UNIFIED IDEOGRAPH
+0xD14F	0x57C6	#CJK UNIFIED IDEOGRAPH
+0xD150	0x57BD	#CJK UNIFIED IDEOGRAPH
+0xD151	0x57BC	#CJK UNIFIED IDEOGRAPH
+0xD152	0x57B8	#CJK UNIFIED IDEOGRAPH
+0xD153	0x57B6	#CJK UNIFIED IDEOGRAPH
+0xD154	0x57BF	#CJK UNIFIED IDEOGRAPH
+0xD155	0x57C7	#CJK UNIFIED IDEOGRAPH
+0xD156	0x57D0	#CJK UNIFIED IDEOGRAPH
+0xD157	0x57B9	#CJK UNIFIED IDEOGRAPH
+0xD158	0x57C1	#CJK UNIFIED IDEOGRAPH
+0xD159	0x590E	#CJK UNIFIED IDEOGRAPH
+0xD15A	0x594A	#CJK UNIFIED IDEOGRAPH
+0xD15B	0x5A19	#CJK UNIFIED IDEOGRAPH
+0xD15C	0x5A16	#CJK UNIFIED IDEOGRAPH
+0xD15D	0x5A2D	#CJK UNIFIED IDEOGRAPH
+0xD15E	0x5A2E	#CJK UNIFIED IDEOGRAPH
+0xD15F	0x5A15	#CJK UNIFIED IDEOGRAPH
+0xD160	0x5A0F	#CJK UNIFIED IDEOGRAPH
+0xD161	0x5A17	#CJK UNIFIED IDEOGRAPH
+0xD162	0x5A0A	#CJK UNIFIED IDEOGRAPH
+0xD163	0x5A1E	#CJK UNIFIED IDEOGRAPH
+0xD164	0x5A33	#CJK UNIFIED IDEOGRAPH
+0xD165	0x5B6C	#CJK UNIFIED IDEOGRAPH
+0xD166	0x5BA7	#CJK UNIFIED IDEOGRAPH
+0xD167	0x5BAD	#CJK UNIFIED IDEOGRAPH
+0xD168	0x5BAC	#CJK UNIFIED IDEOGRAPH
+0xD169	0x5C03	#CJK UNIFIED IDEOGRAPH
+0xD16A	0x5C56	#CJK UNIFIED IDEOGRAPH
+0xD16B	0x5C54	#CJK UNIFIED IDEOGRAPH
+0xD16C	0x5CEC	#CJK UNIFIED IDEOGRAPH
+0xD16D	0x5CFF	#CJK UNIFIED IDEOGRAPH
+0xD16E	0x5CEE	#CJK UNIFIED IDEOGRAPH
+0xD16F	0x5CF1	#CJK UNIFIED IDEOGRAPH
+0xD170	0x5CF7	#CJK UNIFIED IDEOGRAPH
+0xD171	0x5D00	#CJK UNIFIED IDEOGRAPH
+0xD172	0x5CF9	#CJK UNIFIED IDEOGRAPH
+0xD173	0x5E29	#CJK UNIFIED IDEOGRAPH
+0xD174	0x5E28	#CJK UNIFIED IDEOGRAPH
+0xD175	0x5EA8	#CJK UNIFIED IDEOGRAPH
+0xD176	0x5EAE	#CJK UNIFIED IDEOGRAPH
+0xD177	0x5EAA	#CJK UNIFIED IDEOGRAPH
+0xD178	0x5EAC	#CJK UNIFIED IDEOGRAPH
+0xD179	0x5F33	#CJK UNIFIED IDEOGRAPH
+0xD17A	0x5F30	#CJK UNIFIED IDEOGRAPH
+0xD17B	0x5F67	#CJK UNIFIED IDEOGRAPH
+0xD17C	0x605D	#CJK UNIFIED IDEOGRAPH
+0xD17D	0x605A	#CJK UNIFIED IDEOGRAPH
+0xD17E	0x6067	#CJK UNIFIED IDEOGRAPH
+0xD1A1	0x6041	#CJK UNIFIED IDEOGRAPH
+0xD1A2	0x60A2	#CJK UNIFIED IDEOGRAPH
+0xD1A3	0x6088	#CJK UNIFIED IDEOGRAPH
+0xD1A4	0x6080	#CJK UNIFIED IDEOGRAPH
+0xD1A5	0x6092	#CJK UNIFIED IDEOGRAPH
+0xD1A6	0x6081	#CJK UNIFIED IDEOGRAPH
+0xD1A7	0x609D	#CJK UNIFIED IDEOGRAPH
+0xD1A8	0x6083	#CJK UNIFIED IDEOGRAPH
+0xD1A9	0x6095	#CJK UNIFIED IDEOGRAPH
+0xD1AA	0x609B	#CJK UNIFIED IDEOGRAPH
+0xD1AB	0x6097	#CJK UNIFIED IDEOGRAPH
+0xD1AC	0x6087	#CJK UNIFIED IDEOGRAPH
+0xD1AD	0x609C	#CJK UNIFIED IDEOGRAPH
+0xD1AE	0x608E	#CJK UNIFIED IDEOGRAPH
+0xD1AF	0x6219	#CJK UNIFIED IDEOGRAPH
+0xD1B0	0x6246	#CJK UNIFIED IDEOGRAPH
+0xD1B1	0x62F2	#CJK UNIFIED IDEOGRAPH
+0xD1B2	0x6310	#CJK UNIFIED IDEOGRAPH
+0xD1B3	0x6356	#CJK UNIFIED IDEOGRAPH
+0xD1B4	0x632C	#CJK UNIFIED IDEOGRAPH
+0xD1B5	0x6344	#CJK UNIFIED IDEOGRAPH
+0xD1B6	0x6345	#CJK UNIFIED IDEOGRAPH
+0xD1B7	0x6336	#CJK UNIFIED IDEOGRAPH
+0xD1B8	0x6343	#CJK UNIFIED IDEOGRAPH
+0xD1B9	0x63E4	#CJK UNIFIED IDEOGRAPH
+0xD1BA	0x6339	#CJK UNIFIED IDEOGRAPH
+0xD1BB	0x634B	#CJK UNIFIED IDEOGRAPH
+0xD1BC	0x634A	#CJK UNIFIED IDEOGRAPH
+0xD1BD	0x633C	#CJK UNIFIED IDEOGRAPH
+0xD1BE	0x6329	#CJK UNIFIED IDEOGRAPH
+0xD1BF	0x6341	#CJK UNIFIED IDEOGRAPH
+0xD1C0	0x6334	#CJK UNIFIED IDEOGRAPH
+0xD1C1	0x6358	#CJK UNIFIED IDEOGRAPH
+0xD1C2	0x6354	#CJK UNIFIED IDEOGRAPH
+0xD1C3	0x6359	#CJK UNIFIED IDEOGRAPH
+0xD1C4	0x632D	#CJK UNIFIED IDEOGRAPH
+0xD1C5	0x6347	#CJK UNIFIED IDEOGRAPH
+0xD1C6	0x6333	#CJK UNIFIED IDEOGRAPH
+0xD1C7	0x635A	#CJK UNIFIED IDEOGRAPH
+0xD1C8	0x6351	#CJK UNIFIED IDEOGRAPH
+0xD1C9	0x6338	#CJK UNIFIED IDEOGRAPH
+0xD1CA	0x6357	#CJK UNIFIED IDEOGRAPH
+0xD1CB	0x6340	#CJK UNIFIED IDEOGRAPH
+0xD1CC	0x6348	#CJK UNIFIED IDEOGRAPH
+0xD1CD	0x654A	#CJK UNIFIED IDEOGRAPH
+0xD1CE	0x6546	#CJK UNIFIED IDEOGRAPH
+0xD1CF	0x65C6	#CJK UNIFIED IDEOGRAPH
+0xD1D0	0x65C3	#CJK UNIFIED IDEOGRAPH
+0xD1D1	0x65C4	#CJK UNIFIED IDEOGRAPH
+0xD1D2	0x65C2	#CJK UNIFIED IDEOGRAPH
+0xD1D3	0x664A	#CJK UNIFIED IDEOGRAPH
+0xD1D4	0x665F	#CJK UNIFIED IDEOGRAPH
+0xD1D5	0x6647	#CJK UNIFIED IDEOGRAPH
+0xD1D6	0x6651	#CJK UNIFIED IDEOGRAPH
+0xD1D7	0x6712	#CJK UNIFIED IDEOGRAPH
+0xD1D8	0x6713	#CJK UNIFIED IDEOGRAPH
+0xD1D9	0x681F	#CJK UNIFIED IDEOGRAPH
+0xD1DA	0x681A	#CJK UNIFIED IDEOGRAPH
+0xD1DB	0x6849	#CJK UNIFIED IDEOGRAPH
+0xD1DC	0x6832	#CJK UNIFIED IDEOGRAPH
+0xD1DD	0x6833	#CJK UNIFIED IDEOGRAPH
+0xD1DE	0x683B	#CJK UNIFIED IDEOGRAPH
+0xD1DF	0x684B	#CJK UNIFIED IDEOGRAPH
+0xD1E0	0x684F	#CJK UNIFIED IDEOGRAPH
+0xD1E1	0x6816	#CJK UNIFIED IDEOGRAPH
+0xD1E2	0x6831	#CJK UNIFIED IDEOGRAPH
+0xD1E3	0x681C	#CJK UNIFIED IDEOGRAPH
+0xD1E4	0x6835	#CJK UNIFIED IDEOGRAPH
+0xD1E5	0x682B	#CJK UNIFIED IDEOGRAPH
+0xD1E6	0x682D	#CJK UNIFIED IDEOGRAPH
+0xD1E7	0x682F	#CJK UNIFIED IDEOGRAPH
+0xD1E8	0x684E	#CJK UNIFIED IDEOGRAPH
+0xD1E9	0x6844	#CJK UNIFIED IDEOGRAPH
+0xD1EA	0x6834	#CJK UNIFIED IDEOGRAPH
+0xD1EB	0x681D	#CJK UNIFIED IDEOGRAPH
+0xD1EC	0x6812	#CJK UNIFIED IDEOGRAPH
+0xD1ED	0x6814	#CJK UNIFIED IDEOGRAPH
+0xD1EE	0x6826	#CJK UNIFIED IDEOGRAPH
+0xD1EF	0x6828	#CJK UNIFIED IDEOGRAPH
+0xD1F0	0x682E	#CJK UNIFIED IDEOGRAPH
+0xD1F1	0x684D	#CJK UNIFIED IDEOGRAPH
+0xD1F2	0x683A	#CJK UNIFIED IDEOGRAPH
+0xD1F3	0x6825	#CJK UNIFIED IDEOGRAPH
+0xD1F4	0x6820	#CJK UNIFIED IDEOGRAPH
+0xD1F5	0x6B2C	#CJK UNIFIED IDEOGRAPH
+0xD1F6	0x6B2F	#CJK UNIFIED IDEOGRAPH
+0xD1F7	0x6B2D	#CJK UNIFIED IDEOGRAPH
+0xD1F8	0x6B31	#CJK UNIFIED IDEOGRAPH
+0xD1F9	0x6B34	#CJK UNIFIED IDEOGRAPH
+0xD1FA	0x6B6D	#CJK UNIFIED IDEOGRAPH
+0xD1FB	0x8082	#CJK UNIFIED IDEOGRAPH
+0xD1FC	0x6B88	#CJK UNIFIED IDEOGRAPH
+0xD1FD	0x6BE6	#CJK UNIFIED IDEOGRAPH
+0xD1FE	0x6BE4	#CJK UNIFIED IDEOGRAPH
+0xD240	0x6BE8	#CJK UNIFIED IDEOGRAPH
+0xD241	0x6BE3	#CJK UNIFIED IDEOGRAPH
+0xD242	0x6BE2	#CJK UNIFIED IDEOGRAPH
+0xD243	0x6BE7	#CJK UNIFIED IDEOGRAPH
+0xD244	0x6C25	#CJK UNIFIED IDEOGRAPH
+0xD245	0x6D7A	#CJK UNIFIED IDEOGRAPH
+0xD246	0x6D63	#CJK UNIFIED IDEOGRAPH
+0xD247	0x6D64	#CJK UNIFIED IDEOGRAPH
+0xD248	0x6D76	#CJK UNIFIED IDEOGRAPH
+0xD249	0x6D0D	#CJK UNIFIED IDEOGRAPH
+0xD24A	0x6D61	#CJK UNIFIED IDEOGRAPH
+0xD24B	0x6D92	#CJK UNIFIED IDEOGRAPH
+0xD24C	0x6D58	#CJK UNIFIED IDEOGRAPH
+0xD24D	0x6D62	#CJK UNIFIED IDEOGRAPH
+0xD24E	0x6D6D	#CJK UNIFIED IDEOGRAPH
+0xD24F	0x6D6F	#CJK UNIFIED IDEOGRAPH
+0xD250	0x6D91	#CJK UNIFIED IDEOGRAPH
+0xD251	0x6D8D	#CJK UNIFIED IDEOGRAPH
+0xD252	0x6DEF	#CJK UNIFIED IDEOGRAPH
+0xD253	0x6D7F	#CJK UNIFIED IDEOGRAPH
+0xD254	0x6D86	#CJK UNIFIED IDEOGRAPH
+0xD255	0x6D5E	#CJK UNIFIED IDEOGRAPH
+0xD256	0x6D67	#CJK UNIFIED IDEOGRAPH
+0xD257	0x6D60	#CJK UNIFIED IDEOGRAPH
+0xD258	0x6D97	#CJK UNIFIED IDEOGRAPH
+0xD259	0x6D70	#CJK UNIFIED IDEOGRAPH
+0xD25A	0x6D7C	#CJK UNIFIED IDEOGRAPH
+0xD25B	0x6D5F	#CJK UNIFIED IDEOGRAPH
+0xD25C	0x6D82	#CJK UNIFIED IDEOGRAPH
+0xD25D	0x6D98	#CJK UNIFIED IDEOGRAPH
+0xD25E	0x6D2F	#CJK UNIFIED IDEOGRAPH
+0xD25F	0x6D68	#CJK UNIFIED IDEOGRAPH
+0xD260	0x6D8B	#CJK UNIFIED IDEOGRAPH
+0xD261	0x6D7E	#CJK UNIFIED IDEOGRAPH
+0xD262	0x6D80	#CJK UNIFIED IDEOGRAPH
+0xD263	0x6D84	#CJK UNIFIED IDEOGRAPH
+0xD264	0x6D16	#CJK UNIFIED IDEOGRAPH
+0xD265	0x6D83	#CJK UNIFIED IDEOGRAPH
+0xD266	0x6D7B	#CJK UNIFIED IDEOGRAPH
+0xD267	0x6D7D	#CJK UNIFIED IDEOGRAPH
+0xD268	0x6D75	#CJK UNIFIED IDEOGRAPH
+0xD269	0x6D90	#CJK UNIFIED IDEOGRAPH
+0xD26A	0x70DC	#CJK UNIFIED IDEOGRAPH
+0xD26B	0x70D3	#CJK UNIFIED IDEOGRAPH
+0xD26C	0x70D1	#CJK UNIFIED IDEOGRAPH
+0xD26D	0x70DD	#CJK UNIFIED IDEOGRAPH
+0xD26E	0x70CB	#CJK UNIFIED IDEOGRAPH
+0xD26F	0x7F39	#CJK UNIFIED IDEOGRAPH
+0xD270	0x70E2	#CJK UNIFIED IDEOGRAPH
+0xD271	0x70D7	#CJK UNIFIED IDEOGRAPH
+0xD272	0x70D2	#CJK UNIFIED IDEOGRAPH
+0xD273	0x70DE	#CJK UNIFIED IDEOGRAPH
+0xD274	0x70E0	#CJK UNIFIED IDEOGRAPH
+0xD275	0x70D4	#CJK UNIFIED IDEOGRAPH
+0xD276	0x70CD	#CJK UNIFIED IDEOGRAPH
+0xD277	0x70C5	#CJK UNIFIED IDEOGRAPH
+0xD278	0x70C6	#CJK UNIFIED IDEOGRAPH
+0xD279	0x70C7	#CJK UNIFIED IDEOGRAPH
+0xD27A	0x70DA	#CJK UNIFIED IDEOGRAPH
+0xD27B	0x70CE	#CJK UNIFIED IDEOGRAPH
+0xD27C	0x70E1	#CJK UNIFIED IDEOGRAPH
+0xD27D	0x7242	#CJK UNIFIED IDEOGRAPH
+0xD27E	0x7278	#CJK UNIFIED IDEOGRAPH
+0xD2A1	0x7277	#CJK UNIFIED IDEOGRAPH
+0xD2A2	0x7276	#CJK UNIFIED IDEOGRAPH
+0xD2A3	0x7300	#CJK UNIFIED IDEOGRAPH
+0xD2A4	0x72FA	#CJK UNIFIED IDEOGRAPH
+0xD2A5	0x72F4	#CJK UNIFIED IDEOGRAPH
+0xD2A6	0x72FE	#CJK UNIFIED IDEOGRAPH
+0xD2A7	0x72F6	#CJK UNIFIED IDEOGRAPH
+0xD2A8	0x72F3	#CJK UNIFIED IDEOGRAPH
+0xD2A9	0x72FB	#CJK UNIFIED IDEOGRAPH
+0xD2AA	0x7301	#CJK UNIFIED IDEOGRAPH
+0xD2AB	0x73D3	#CJK UNIFIED IDEOGRAPH
+0xD2AC	0x73D9	#CJK UNIFIED IDEOGRAPH
+0xD2AD	0x73E5	#CJK UNIFIED IDEOGRAPH
+0xD2AE	0x73D6	#CJK UNIFIED IDEOGRAPH
+0xD2AF	0x73BC	#CJK UNIFIED IDEOGRAPH
+0xD2B0	0x73E7	#CJK UNIFIED IDEOGRAPH
+0xD2B1	0x73E3	#CJK UNIFIED IDEOGRAPH
+0xD2B2	0x73E9	#CJK UNIFIED IDEOGRAPH
+0xD2B3	0x73DC	#CJK UNIFIED IDEOGRAPH
+0xD2B4	0x73D2	#CJK UNIFIED IDEOGRAPH
+0xD2B5	0x73DB	#CJK UNIFIED IDEOGRAPH
+0xD2B6	0x73D4	#CJK UNIFIED IDEOGRAPH
+0xD2B7	0x73DD	#CJK UNIFIED IDEOGRAPH
+0xD2B8	0x73DA	#CJK UNIFIED IDEOGRAPH
+0xD2B9	0x73D7	#CJK UNIFIED IDEOGRAPH
+0xD2BA	0x73D8	#CJK UNIFIED IDEOGRAPH
+0xD2BB	0x73E8	#CJK UNIFIED IDEOGRAPH
+0xD2BC	0x74DE	#CJK UNIFIED IDEOGRAPH
+0xD2BD	0x74DF	#CJK UNIFIED IDEOGRAPH
+0xD2BE	0x74F4	#CJK UNIFIED IDEOGRAPH
+0xD2BF	0x74F5	#CJK UNIFIED IDEOGRAPH
+0xD2C0	0x7521	#CJK UNIFIED IDEOGRAPH
+0xD2C1	0x755B	#CJK UNIFIED IDEOGRAPH
+0xD2C2	0x755F	#CJK UNIFIED IDEOGRAPH
+0xD2C3	0x75B0	#CJK UNIFIED IDEOGRAPH
+0xD2C4	0x75C1	#CJK UNIFIED IDEOGRAPH
+0xD2C5	0x75BB	#CJK UNIFIED IDEOGRAPH
+0xD2C6	0x75C4	#CJK UNIFIED IDEOGRAPH
+0xD2C7	0x75C0	#CJK UNIFIED IDEOGRAPH
+0xD2C8	0x75BF	#CJK UNIFIED IDEOGRAPH
+0xD2C9	0x75B6	#CJK UNIFIED IDEOGRAPH
+0xD2CA	0x75BA	#CJK UNIFIED IDEOGRAPH
+0xD2CB	0x768A	#CJK UNIFIED IDEOGRAPH
+0xD2CC	0x76C9	#CJK UNIFIED IDEOGRAPH
+0xD2CD	0x771D	#CJK UNIFIED IDEOGRAPH
+0xD2CE	0x771B	#CJK UNIFIED IDEOGRAPH
+0xD2CF	0x7710	#CJK UNIFIED IDEOGRAPH
+0xD2D0	0x7713	#CJK UNIFIED IDEOGRAPH
+0xD2D1	0x7712	#CJK UNIFIED IDEOGRAPH
+0xD2D2	0x7723	#CJK UNIFIED IDEOGRAPH
+0xD2D3	0x7711	#CJK UNIFIED IDEOGRAPH
+0xD2D4	0x7715	#CJK UNIFIED IDEOGRAPH
+0xD2D5	0x7719	#CJK UNIFIED IDEOGRAPH
+0xD2D6	0x771A	#CJK UNIFIED IDEOGRAPH
+0xD2D7	0x7722	#CJK UNIFIED IDEOGRAPH
+0xD2D8	0x7727	#CJK UNIFIED IDEOGRAPH
+0xD2D9	0x7823	#CJK UNIFIED IDEOGRAPH
+0xD2DA	0x782C	#CJK UNIFIED IDEOGRAPH
+0xD2DB	0x7822	#CJK UNIFIED IDEOGRAPH
+0xD2DC	0x7835	#CJK UNIFIED IDEOGRAPH
+0xD2DD	0x782F	#CJK UNIFIED IDEOGRAPH
+0xD2DE	0x7828	#CJK UNIFIED IDEOGRAPH
+0xD2DF	0x782E	#CJK UNIFIED IDEOGRAPH
+0xD2E0	0x782B	#CJK UNIFIED IDEOGRAPH
+0xD2E1	0x7821	#CJK UNIFIED IDEOGRAPH
+0xD2E2	0x7829	#CJK UNIFIED IDEOGRAPH
+0xD2E3	0x7833	#CJK UNIFIED IDEOGRAPH
+0xD2E4	0x782A	#CJK UNIFIED IDEOGRAPH
+0xD2E5	0x7831	#CJK UNIFIED IDEOGRAPH
+0xD2E6	0x7954	#CJK UNIFIED IDEOGRAPH
+0xD2E7	0x795B	#CJK UNIFIED IDEOGRAPH
+0xD2E8	0x794F	#CJK UNIFIED IDEOGRAPH
+0xD2E9	0x795C	#CJK UNIFIED IDEOGRAPH
+0xD2EA	0x7953	#CJK UNIFIED IDEOGRAPH
+0xD2EB	0x7952	#CJK UNIFIED IDEOGRAPH
+0xD2EC	0x7951	#CJK UNIFIED IDEOGRAPH
+0xD2ED	0x79EB	#CJK UNIFIED IDEOGRAPH
+0xD2EE	0x79EC	#CJK UNIFIED IDEOGRAPH
+0xD2EF	0x79E0	#CJK UNIFIED IDEOGRAPH
+0xD2F0	0x79EE	#CJK UNIFIED IDEOGRAPH
+0xD2F1	0x79ED	#CJK UNIFIED IDEOGRAPH
+0xD2F2	0x79EA	#CJK UNIFIED IDEOGRAPH
+0xD2F3	0x79DC	#CJK UNIFIED IDEOGRAPH
+0xD2F4	0x79DE	#CJK UNIFIED IDEOGRAPH
+0xD2F5	0x79DD	#CJK UNIFIED IDEOGRAPH
+0xD2F6	0x7A86	#CJK UNIFIED IDEOGRAPH
+0xD2F7	0x7A89	#CJK UNIFIED IDEOGRAPH
+0xD2F8	0x7A85	#CJK UNIFIED IDEOGRAPH
+0xD2F9	0x7A8B	#CJK UNIFIED IDEOGRAPH
+0xD2FA	0x7A8C	#CJK UNIFIED IDEOGRAPH
+0xD2FB	0x7A8A	#CJK UNIFIED IDEOGRAPH
+0xD2FC	0x7A87	#CJK UNIFIED IDEOGRAPH
+0xD2FD	0x7AD8	#CJK UNIFIED IDEOGRAPH
+0xD2FE	0x7B10	#CJK UNIFIED IDEOGRAPH
+0xD340	0x7B04	#CJK UNIFIED IDEOGRAPH
+0xD341	0x7B13	#CJK UNIFIED IDEOGRAPH
+0xD342	0x7B05	#CJK UNIFIED IDEOGRAPH
+0xD343	0x7B0F	#CJK UNIFIED IDEOGRAPH
+0xD344	0x7B08	#CJK UNIFIED IDEOGRAPH
+0xD345	0x7B0A	#CJK UNIFIED IDEOGRAPH
+0xD346	0x7B0E	#CJK UNIFIED IDEOGRAPH
+0xD347	0x7B09	#CJK UNIFIED IDEOGRAPH
+0xD348	0x7B12	#CJK UNIFIED IDEOGRAPH
+0xD349	0x7C84	#CJK UNIFIED IDEOGRAPH
+0xD34A	0x7C91	#CJK UNIFIED IDEOGRAPH
+0xD34B	0x7C8A	#CJK UNIFIED IDEOGRAPH
+0xD34C	0x7C8C	#CJK UNIFIED IDEOGRAPH
+0xD34D	0x7C88	#CJK UNIFIED IDEOGRAPH
+0xD34E	0x7C8D	#CJK UNIFIED IDEOGRAPH
+0xD34F	0x7C85	#CJK UNIFIED IDEOGRAPH
+0xD350	0x7D1E	#CJK UNIFIED IDEOGRAPH
+0xD351	0x7D1D	#CJK UNIFIED IDEOGRAPH
+0xD352	0x7D11	#CJK UNIFIED IDEOGRAPH
+0xD353	0x7D0E	#CJK UNIFIED IDEOGRAPH
+0xD354	0x7D18	#CJK UNIFIED IDEOGRAPH
+0xD355	0x7D16	#CJK UNIFIED IDEOGRAPH
+0xD356	0x7D13	#CJK UNIFIED IDEOGRAPH
+0xD357	0x7D1F	#CJK UNIFIED IDEOGRAPH
+0xD358	0x7D12	#CJK UNIFIED IDEOGRAPH
+0xD359	0x7D0F	#CJK UNIFIED IDEOGRAPH
+0xD35A	0x7D0C	#CJK UNIFIED IDEOGRAPH
+0xD35B	0x7F5C	#CJK UNIFIED IDEOGRAPH
+0xD35C	0x7F61	#CJK UNIFIED IDEOGRAPH
+0xD35D	0x7F5E	#CJK UNIFIED IDEOGRAPH
+0xD35E	0x7F60	#CJK UNIFIED IDEOGRAPH
+0xD35F	0x7F5D	#CJK UNIFIED IDEOGRAPH
+0xD360	0x7F5B	#CJK UNIFIED IDEOGRAPH
+0xD361	0x7F96	#CJK UNIFIED IDEOGRAPH
+0xD362	0x7F92	#CJK UNIFIED IDEOGRAPH
+0xD363	0x7FC3	#CJK UNIFIED IDEOGRAPH
+0xD364	0x7FC2	#CJK UNIFIED IDEOGRAPH
+0xD365	0x7FC0	#CJK UNIFIED IDEOGRAPH
+0xD366	0x8016	#CJK UNIFIED IDEOGRAPH
+0xD367	0x803E	#CJK UNIFIED IDEOGRAPH
+0xD368	0x8039	#CJK UNIFIED IDEOGRAPH
+0xD369	0x80FA	#CJK UNIFIED IDEOGRAPH
+0xD36A	0x80F2	#CJK UNIFIED IDEOGRAPH
+0xD36B	0x80F9	#CJK UNIFIED IDEOGRAPH
+0xD36C	0x80F5	#CJK UNIFIED IDEOGRAPH
+0xD36D	0x8101	#CJK UNIFIED IDEOGRAPH
+0xD36E	0x80FB	#CJK UNIFIED IDEOGRAPH
+0xD36F	0x8100	#CJK UNIFIED IDEOGRAPH
+0xD370	0x8201	#CJK UNIFIED IDEOGRAPH
+0xD371	0x822F	#CJK UNIFIED IDEOGRAPH
+0xD372	0x8225	#CJK UNIFIED IDEOGRAPH
+0xD373	0x8333	#CJK UNIFIED IDEOGRAPH
+0xD374	0x832D	#CJK UNIFIED IDEOGRAPH
+0xD375	0x8344	#CJK UNIFIED IDEOGRAPH
+0xD376	0x8319	#CJK UNIFIED IDEOGRAPH
+0xD377	0x8351	#CJK UNIFIED IDEOGRAPH
+0xD378	0x8325	#CJK UNIFIED IDEOGRAPH
+0xD379	0x8356	#CJK UNIFIED IDEOGRAPH
+0xD37A	0x833F	#CJK UNIFIED IDEOGRAPH
+0xD37B	0x8341	#CJK UNIFIED IDEOGRAPH
+0xD37C	0x8326	#CJK UNIFIED IDEOGRAPH
+0xD37D	0x831C	#CJK UNIFIED IDEOGRAPH
+0xD37E	0x8322	#CJK UNIFIED IDEOGRAPH
+0xD3A1	0x8342	#CJK UNIFIED IDEOGRAPH
+0xD3A2	0x834E	#CJK UNIFIED IDEOGRAPH
+0xD3A3	0x831B	#CJK UNIFIED IDEOGRAPH
+0xD3A4	0x832A	#CJK UNIFIED IDEOGRAPH
+0xD3A5	0x8308	#CJK UNIFIED IDEOGRAPH
+0xD3A6	0x833C	#CJK UNIFIED IDEOGRAPH
+0xD3A7	0x834D	#CJK UNIFIED IDEOGRAPH
+0xD3A8	0x8316	#CJK UNIFIED IDEOGRAPH
+0xD3A9	0x8324	#CJK UNIFIED IDEOGRAPH
+0xD3AA	0x8320	#CJK UNIFIED IDEOGRAPH
+0xD3AB	0x8337	#CJK UNIFIED IDEOGRAPH
+0xD3AC	0x832F	#CJK UNIFIED IDEOGRAPH
+0xD3AD	0x8329	#CJK UNIFIED IDEOGRAPH
+0xD3AE	0x8347	#CJK UNIFIED IDEOGRAPH
+0xD3AF	0x8345	#CJK UNIFIED IDEOGRAPH
+0xD3B0	0x834C	#CJK UNIFIED IDEOGRAPH
+0xD3B1	0x8353	#CJK UNIFIED IDEOGRAPH
+0xD3B2	0x831E	#CJK UNIFIED IDEOGRAPH
+0xD3B3	0x832C	#CJK UNIFIED IDEOGRAPH
+0xD3B4	0x834B	#CJK UNIFIED IDEOGRAPH
+0xD3B5	0x8327	#CJK UNIFIED IDEOGRAPH
+0xD3B6	0x8348	#CJK UNIFIED IDEOGRAPH
+0xD3B7	0x8653	#CJK UNIFIED IDEOGRAPH
+0xD3B8	0x8652	#CJK UNIFIED IDEOGRAPH
+0xD3B9	0x86A2	#CJK UNIFIED IDEOGRAPH
+0xD3BA	0x86A8	#CJK UNIFIED IDEOGRAPH
+0xD3BB	0x8696	#CJK UNIFIED IDEOGRAPH
+0xD3BC	0x868D	#CJK UNIFIED IDEOGRAPH
+0xD3BD	0x8691	#CJK UNIFIED IDEOGRAPH
+0xD3BE	0x869E	#CJK UNIFIED IDEOGRAPH
+0xD3BF	0x8687	#CJK UNIFIED IDEOGRAPH
+0xD3C0	0x8697	#CJK UNIFIED IDEOGRAPH
+0xD3C1	0x8686	#CJK UNIFIED IDEOGRAPH
+0xD3C2	0x868B	#CJK UNIFIED IDEOGRAPH
+0xD3C3	0x869A	#CJK UNIFIED IDEOGRAPH
+0xD3C4	0x8685	#CJK UNIFIED IDEOGRAPH
+0xD3C5	0x86A5	#CJK UNIFIED IDEOGRAPH
+0xD3C6	0x8699	#CJK UNIFIED IDEOGRAPH
+0xD3C7	0x86A1	#CJK UNIFIED IDEOGRAPH
+0xD3C8	0x86A7	#CJK UNIFIED IDEOGRAPH
+0xD3C9	0x8695	#CJK UNIFIED IDEOGRAPH
+0xD3CA	0x8698	#CJK UNIFIED IDEOGRAPH
+0xD3CB	0x868E	#CJK UNIFIED IDEOGRAPH
+0xD3CC	0x869D	#CJK UNIFIED IDEOGRAPH
+0xD3CD	0x8690	#CJK UNIFIED IDEOGRAPH
+0xD3CE	0x8694	#CJK UNIFIED IDEOGRAPH
+0xD3CF	0x8843	#CJK UNIFIED IDEOGRAPH
+0xD3D0	0x8844	#CJK UNIFIED IDEOGRAPH
+0xD3D1	0x886D	#CJK UNIFIED IDEOGRAPH
+0xD3D2	0x8875	#CJK UNIFIED IDEOGRAPH
+0xD3D3	0x8876	#CJK UNIFIED IDEOGRAPH
+0xD3D4	0x8872	#CJK UNIFIED IDEOGRAPH
+0xD3D5	0x8880	#CJK UNIFIED IDEOGRAPH
+0xD3D6	0x8871	#CJK UNIFIED IDEOGRAPH
+0xD3D7	0x887F	#CJK UNIFIED IDEOGRAPH
+0xD3D8	0x886F	#CJK UNIFIED IDEOGRAPH
+0xD3D9	0x8883	#CJK UNIFIED IDEOGRAPH
+0xD3DA	0x887E	#CJK UNIFIED IDEOGRAPH
+0xD3DB	0x8874	#CJK UNIFIED IDEOGRAPH
+0xD3DC	0x887C	#CJK UNIFIED IDEOGRAPH
+0xD3DD	0x8A12	#CJK UNIFIED IDEOGRAPH
+0xD3DE	0x8C47	#CJK UNIFIED IDEOGRAPH
+0xD3DF	0x8C57	#CJK UNIFIED IDEOGRAPH
+0xD3E0	0x8C7B	#CJK UNIFIED IDEOGRAPH
+0xD3E1	0x8CA4	#CJK UNIFIED IDEOGRAPH
+0xD3E2	0x8CA3	#CJK UNIFIED IDEOGRAPH
+0xD3E3	0x8D76	#CJK UNIFIED IDEOGRAPH
+0xD3E4	0x8D78	#CJK UNIFIED IDEOGRAPH
+0xD3E5	0x8DB5	#CJK UNIFIED IDEOGRAPH
+0xD3E6	0x8DB7	#CJK UNIFIED IDEOGRAPH
+0xD3E7	0x8DB6	#CJK UNIFIED IDEOGRAPH
+0xD3E8	0x8ED1	#CJK UNIFIED IDEOGRAPH
+0xD3E9	0x8ED3	#CJK UNIFIED IDEOGRAPH
+0xD3EA	0x8FFE	#CJK UNIFIED IDEOGRAPH
+0xD3EB	0x8FF5	#CJK UNIFIED IDEOGRAPH
+0xD3EC	0x9002	#CJK UNIFIED IDEOGRAPH
+0xD3ED	0x8FFF	#CJK UNIFIED IDEOGRAPH
+0xD3EE	0x8FFB	#CJK UNIFIED IDEOGRAPH
+0xD3EF	0x9004	#CJK UNIFIED IDEOGRAPH
+0xD3F0	0x8FFC	#CJK UNIFIED IDEOGRAPH
+0xD3F1	0x8FF6	#CJK UNIFIED IDEOGRAPH
+0xD3F2	0x90D6	#CJK UNIFIED IDEOGRAPH
+0xD3F3	0x90E0	#CJK UNIFIED IDEOGRAPH
+0xD3F4	0x90D9	#CJK UNIFIED IDEOGRAPH
+0xD3F5	0x90DA	#CJK UNIFIED IDEOGRAPH
+0xD3F6	0x90E3	#CJK UNIFIED IDEOGRAPH
+0xD3F7	0x90DF	#CJK UNIFIED IDEOGRAPH
+0xD3F8	0x90E5	#CJK UNIFIED IDEOGRAPH
+0xD3F9	0x90D8	#CJK UNIFIED IDEOGRAPH
+0xD3FA	0x90DB	#CJK UNIFIED IDEOGRAPH
+0xD3FB	0x90D7	#CJK UNIFIED IDEOGRAPH
+0xD3FC	0x90DC	#CJK UNIFIED IDEOGRAPH
+0xD3FD	0x90E4	#CJK UNIFIED IDEOGRAPH
+0xD3FE	0x9150	#CJK UNIFIED IDEOGRAPH
+0xD440	0x914E	#CJK UNIFIED IDEOGRAPH
+0xD441	0x914F	#CJK UNIFIED IDEOGRAPH
+0xD442	0x91D5	#CJK UNIFIED IDEOGRAPH
+0xD443	0x91E2	#CJK UNIFIED IDEOGRAPH
+0xD444	0x91DA	#CJK UNIFIED IDEOGRAPH
+0xD445	0x965C	#CJK UNIFIED IDEOGRAPH
+0xD446	0x965F	#CJK UNIFIED IDEOGRAPH
+0xD447	0x96BC	#CJK UNIFIED IDEOGRAPH
+0xD448	0x98E3	#CJK UNIFIED IDEOGRAPH
+0xD449	0x9ADF	#CJK UNIFIED IDEOGRAPH
+0xD44A	0x9B2F	#CJK UNIFIED IDEOGRAPH
+0xD44B	0x4E7F	#CJK UNIFIED IDEOGRAPH
+0xD44C	0x5070	#CJK UNIFIED IDEOGRAPH
+0xD44D	0x506A	#CJK UNIFIED IDEOGRAPH
+0xD44E	0x5061	#CJK UNIFIED IDEOGRAPH
+0xD44F	0x505E	#CJK UNIFIED IDEOGRAPH
+0xD450	0x5060	#CJK UNIFIED IDEOGRAPH
+0xD451	0x5053	#CJK UNIFIED IDEOGRAPH
+0xD452	0x504B	#CJK UNIFIED IDEOGRAPH
+0xD453	0x505D	#CJK UNIFIED IDEOGRAPH
+0xD454	0x5072	#CJK UNIFIED IDEOGRAPH
+0xD455	0x5048	#CJK UNIFIED IDEOGRAPH
+0xD456	0x504D	#CJK UNIFIED IDEOGRAPH
+0xD457	0x5041	#CJK UNIFIED IDEOGRAPH
+0xD458	0x505B	#CJK UNIFIED IDEOGRAPH
+0xD459	0x504A	#CJK UNIFIED IDEOGRAPH
+0xD45A	0x5062	#CJK UNIFIED IDEOGRAPH
+0xD45B	0x5015	#CJK UNIFIED IDEOGRAPH
+0xD45C	0x5045	#CJK UNIFIED IDEOGRAPH
+0xD45D	0x505F	#CJK UNIFIED IDEOGRAPH
+0xD45E	0x5069	#CJK UNIFIED IDEOGRAPH
+0xD45F	0x506B	#CJK UNIFIED IDEOGRAPH
+0xD460	0x5063	#CJK UNIFIED IDEOGRAPH
+0xD461	0x5064	#CJK UNIFIED IDEOGRAPH
+0xD462	0x5046	#CJK UNIFIED IDEOGRAPH
+0xD463	0x5040	#CJK UNIFIED IDEOGRAPH
+0xD464	0x506E	#CJK UNIFIED IDEOGRAPH
+0xD465	0x5073	#CJK UNIFIED IDEOGRAPH
+0xD466	0x5057	#CJK UNIFIED IDEOGRAPH
+0xD467	0x5051	#CJK UNIFIED IDEOGRAPH
+0xD468	0x51D0	#CJK UNIFIED IDEOGRAPH
+0xD469	0x526B	#CJK UNIFIED IDEOGRAPH
+0xD46A	0x526D	#CJK UNIFIED IDEOGRAPH
+0xD46B	0x526C	#CJK UNIFIED IDEOGRAPH
+0xD46C	0x526E	#CJK UNIFIED IDEOGRAPH
+0xD46D	0x52D6	#CJK UNIFIED IDEOGRAPH
+0xD46E	0x52D3	#CJK UNIFIED IDEOGRAPH
+0xD46F	0x532D	#CJK UNIFIED IDEOGRAPH
+0xD470	0x539C	#CJK UNIFIED IDEOGRAPH
+0xD471	0x5575	#CJK UNIFIED IDEOGRAPH
+0xD472	0x5576	#CJK UNIFIED IDEOGRAPH
+0xD473	0x553C	#CJK UNIFIED IDEOGRAPH
+0xD474	0x554D	#CJK UNIFIED IDEOGRAPH
+0xD475	0x5550	#CJK UNIFIED IDEOGRAPH
+0xD476	0x5534	#CJK UNIFIED IDEOGRAPH
+0xD477	0x552A	#CJK UNIFIED IDEOGRAPH
+0xD478	0x5551	#CJK UNIFIED IDEOGRAPH
+0xD479	0x5562	#CJK UNIFIED IDEOGRAPH
+0xD47A	0x5536	#CJK UNIFIED IDEOGRAPH
+0xD47B	0x5535	#CJK UNIFIED IDEOGRAPH
+0xD47C	0x5530	#CJK UNIFIED IDEOGRAPH
+0xD47D	0x5552	#CJK UNIFIED IDEOGRAPH
+0xD47E	0x5545	#CJK UNIFIED IDEOGRAPH
+0xD4A1	0x550C	#CJK UNIFIED IDEOGRAPH
+0xD4A2	0x5532	#CJK UNIFIED IDEOGRAPH
+0xD4A3	0x5565	#CJK UNIFIED IDEOGRAPH
+0xD4A4	0x554E	#CJK UNIFIED IDEOGRAPH
+0xD4A5	0x5539	#CJK UNIFIED IDEOGRAPH
+0xD4A6	0x5548	#CJK UNIFIED IDEOGRAPH
+0xD4A7	0x552D	#CJK UNIFIED IDEOGRAPH
+0xD4A8	0x553B	#CJK UNIFIED IDEOGRAPH
+0xD4A9	0x5540	#CJK UNIFIED IDEOGRAPH
+0xD4AA	0x554B	#CJK UNIFIED IDEOGRAPH
+0xD4AB	0x570A	#CJK UNIFIED IDEOGRAPH
+0xD4AC	0x5707	#CJK UNIFIED IDEOGRAPH
+0xD4AD	0x57FB	#CJK UNIFIED IDEOGRAPH
+0xD4AE	0x5814	#CJK UNIFIED IDEOGRAPH
+0xD4AF	0x57E2	#CJK UNIFIED IDEOGRAPH
+0xD4B0	0x57F6	#CJK UNIFIED IDEOGRAPH
+0xD4B1	0x57DC	#CJK UNIFIED IDEOGRAPH
+0xD4B2	0x57F4	#CJK UNIFIED IDEOGRAPH
+0xD4B3	0x5800	#CJK UNIFIED IDEOGRAPH
+0xD4B4	0x57ED	#CJK UNIFIED IDEOGRAPH
+0xD4B5	0x57FD	#CJK UNIFIED IDEOGRAPH
+0xD4B6	0x5808	#CJK UNIFIED IDEOGRAPH
+0xD4B7	0x57F8	#CJK UNIFIED IDEOGRAPH
+0xD4B8	0x580B	#CJK UNIFIED IDEOGRAPH
+0xD4B9	0x57F3	#CJK UNIFIED IDEOGRAPH
+0xD4BA	0x57CF	#CJK UNIFIED IDEOGRAPH
+0xD4BB	0x5807	#CJK UNIFIED IDEOGRAPH
+0xD4BC	0x57EE	#CJK UNIFIED IDEOGRAPH
+0xD4BD	0x57E3	#CJK UNIFIED IDEOGRAPH
+0xD4BE	0x57F2	#CJK UNIFIED IDEOGRAPH
+0xD4BF	0x57E5	#CJK UNIFIED IDEOGRAPH
+0xD4C0	0x57EC	#CJK UNIFIED IDEOGRAPH
+0xD4C1	0x57E1	#CJK UNIFIED IDEOGRAPH
+0xD4C2	0x580E	#CJK UNIFIED IDEOGRAPH
+0xD4C3	0x57FC	#CJK UNIFIED IDEOGRAPH
+0xD4C4	0x5810	#CJK UNIFIED IDEOGRAPH
+0xD4C5	0x57E7	#CJK UNIFIED IDEOGRAPH
+0xD4C6	0x5801	#CJK UNIFIED IDEOGRAPH
+0xD4C7	0x580C	#CJK UNIFIED IDEOGRAPH
+0xD4C8	0x57F1	#CJK UNIFIED IDEOGRAPH
+0xD4C9	0x57E9	#CJK UNIFIED IDEOGRAPH
+0xD4CA	0x57F0	#CJK UNIFIED IDEOGRAPH
+0xD4CB	0x580D	#CJK UNIFIED IDEOGRAPH
+0xD4CC	0x5804	#CJK UNIFIED IDEOGRAPH
+0xD4CD	0x595C	#CJK UNIFIED IDEOGRAPH
+0xD4CE	0x5A60	#CJK UNIFIED IDEOGRAPH
+0xD4CF	0x5A58	#CJK UNIFIED IDEOGRAPH
+0xD4D0	0x5A55	#CJK UNIFIED IDEOGRAPH
+0xD4D1	0x5A67	#CJK UNIFIED IDEOGRAPH
+0xD4D2	0x5A5E	#CJK UNIFIED IDEOGRAPH
+0xD4D3	0x5A38	#CJK UNIFIED IDEOGRAPH
+0xD4D4	0x5A35	#CJK UNIFIED IDEOGRAPH
+0xD4D5	0x5A6D	#CJK UNIFIED IDEOGRAPH
+0xD4D6	0x5A50	#CJK UNIFIED IDEOGRAPH
+0xD4D7	0x5A5F	#CJK UNIFIED IDEOGRAPH
+0xD4D8	0x5A65	#CJK UNIFIED IDEOGRAPH
+0xD4D9	0x5A6C	#CJK UNIFIED IDEOGRAPH
+0xD4DA	0x5A53	#CJK UNIFIED IDEOGRAPH
+0xD4DB	0x5A64	#CJK UNIFIED IDEOGRAPH
+0xD4DC	0x5A57	#CJK UNIFIED IDEOGRAPH
+0xD4DD	0x5A43	#CJK UNIFIED IDEOGRAPH
+0xD4DE	0x5A5D	#CJK UNIFIED IDEOGRAPH
+0xD4DF	0x5A52	#CJK UNIFIED IDEOGRAPH
+0xD4E0	0x5A44	#CJK UNIFIED IDEOGRAPH
+0xD4E1	0x5A5B	#CJK UNIFIED IDEOGRAPH
+0xD4E2	0x5A48	#CJK UNIFIED IDEOGRAPH
+0xD4E3	0x5A8E	#CJK UNIFIED IDEOGRAPH
+0xD4E4	0x5A3E	#CJK UNIFIED IDEOGRAPH
+0xD4E5	0x5A4D	#CJK UNIFIED IDEOGRAPH
+0xD4E6	0x5A39	#CJK UNIFIED IDEOGRAPH
+0xD4E7	0x5A4C	#CJK UNIFIED IDEOGRAPH
+0xD4E8	0x5A70	#CJK UNIFIED IDEOGRAPH
+0xD4E9	0x5A69	#CJK UNIFIED IDEOGRAPH
+0xD4EA	0x5A47	#CJK UNIFIED IDEOGRAPH
+0xD4EB	0x5A51	#CJK UNIFIED IDEOGRAPH
+0xD4EC	0x5A56	#CJK UNIFIED IDEOGRAPH
+0xD4ED	0x5A42	#CJK UNIFIED IDEOGRAPH
+0xD4EE	0x5A5C	#CJK UNIFIED IDEOGRAPH
+0xD4EF	0x5B72	#CJK UNIFIED IDEOGRAPH
+0xD4F0	0x5B6E	#CJK UNIFIED IDEOGRAPH
+0xD4F1	0x5BC1	#CJK UNIFIED IDEOGRAPH
+0xD4F2	0x5BC0	#CJK UNIFIED IDEOGRAPH
+0xD4F3	0x5C59	#CJK UNIFIED IDEOGRAPH
+0xD4F4	0x5D1E	#CJK UNIFIED IDEOGRAPH
+0xD4F5	0x5D0B	#CJK UNIFIED IDEOGRAPH
+0xD4F6	0x5D1D	#CJK UNIFIED IDEOGRAPH
+0xD4F7	0x5D1A	#CJK UNIFIED IDEOGRAPH
+0xD4F8	0x5D20	#CJK UNIFIED IDEOGRAPH
+0xD4F9	0x5D0C	#CJK UNIFIED IDEOGRAPH
+0xD4FA	0x5D28	#CJK UNIFIED IDEOGRAPH
+0xD4FB	0x5D0D	#CJK UNIFIED IDEOGRAPH
+0xD4FC	0x5D26	#CJK UNIFIED IDEOGRAPH
+0xD4FD	0x5D25	#CJK UNIFIED IDEOGRAPH
+0xD4FE	0x5D0F	#CJK UNIFIED IDEOGRAPH
+0xD540	0x5D30	#CJK UNIFIED IDEOGRAPH
+0xD541	0x5D12	#CJK UNIFIED IDEOGRAPH
+0xD542	0x5D23	#CJK UNIFIED IDEOGRAPH
+0xD543	0x5D1F	#CJK UNIFIED IDEOGRAPH
+0xD544	0x5D2E	#CJK UNIFIED IDEOGRAPH
+0xD545	0x5E3E	#CJK UNIFIED IDEOGRAPH
+0xD546	0x5E34	#CJK UNIFIED IDEOGRAPH
+0xD547	0x5EB1	#CJK UNIFIED IDEOGRAPH
+0xD548	0x5EB4	#CJK UNIFIED IDEOGRAPH
+0xD549	0x5EB9	#CJK UNIFIED IDEOGRAPH
+0xD54A	0x5EB2	#CJK UNIFIED IDEOGRAPH
+0xD54B	0x5EB3	#CJK UNIFIED IDEOGRAPH
+0xD54C	0x5F36	#CJK UNIFIED IDEOGRAPH
+0xD54D	0x5F38	#CJK UNIFIED IDEOGRAPH
+0xD54E	0x5F9B	#CJK UNIFIED IDEOGRAPH
+0xD54F	0x5F96	#CJK UNIFIED IDEOGRAPH
+0xD550	0x5F9F	#CJK UNIFIED IDEOGRAPH
+0xD551	0x608A	#CJK UNIFIED IDEOGRAPH
+0xD552	0x6090	#CJK UNIFIED IDEOGRAPH
+0xD553	0x6086	#CJK UNIFIED IDEOGRAPH
+0xD554	0x60BE	#CJK UNIFIED IDEOGRAPH
+0xD555	0x60B0	#CJK UNIFIED IDEOGRAPH
+0xD556	0x60BA	#CJK UNIFIED IDEOGRAPH
+0xD557	0x60D3	#CJK UNIFIED IDEOGRAPH
+0xD558	0x60D4	#CJK UNIFIED IDEOGRAPH
+0xD559	0x60CF	#CJK UNIFIED IDEOGRAPH
+0xD55A	0x60E4	#CJK UNIFIED IDEOGRAPH
+0xD55B	0x60D9	#CJK UNIFIED IDEOGRAPH
+0xD55C	0x60DD	#CJK UNIFIED IDEOGRAPH
+0xD55D	0x60C8	#CJK UNIFIED IDEOGRAPH
+0xD55E	0x60B1	#CJK UNIFIED IDEOGRAPH
+0xD55F	0x60DB	#CJK UNIFIED IDEOGRAPH
+0xD560	0x60B7	#CJK UNIFIED IDEOGRAPH
+0xD561	0x60CA	#CJK UNIFIED IDEOGRAPH
+0xD562	0x60BF	#CJK UNIFIED IDEOGRAPH
+0xD563	0x60C3	#CJK UNIFIED IDEOGRAPH
+0xD564	0x60CD	#CJK UNIFIED IDEOGRAPH
+0xD565	0x60C0	#CJK UNIFIED IDEOGRAPH
+0xD566	0x6332	#CJK UNIFIED IDEOGRAPH
+0xD567	0x6365	#CJK UNIFIED IDEOGRAPH
+0xD568	0x638A	#CJK UNIFIED IDEOGRAPH
+0xD569	0x6382	#CJK UNIFIED IDEOGRAPH
+0xD56A	0x637D	#CJK UNIFIED IDEOGRAPH
+0xD56B	0x63BD	#CJK UNIFIED IDEOGRAPH
+0xD56C	0x639E	#CJK UNIFIED IDEOGRAPH
+0xD56D	0x63AD	#CJK UNIFIED IDEOGRAPH
+0xD56E	0x639D	#CJK UNIFIED IDEOGRAPH
+0xD56F	0x6397	#CJK UNIFIED IDEOGRAPH
+0xD570	0x63AB	#CJK UNIFIED IDEOGRAPH
+0xD571	0x638E	#CJK UNIFIED IDEOGRAPH
+0xD572	0x636F	#CJK UNIFIED IDEOGRAPH
+0xD573	0x6387	#CJK UNIFIED IDEOGRAPH
+0xD574	0x6390	#CJK UNIFIED IDEOGRAPH
+0xD575	0x636E	#CJK UNIFIED IDEOGRAPH
+0xD576	0x63AF	#CJK UNIFIED IDEOGRAPH
+0xD577	0x6375	#CJK UNIFIED IDEOGRAPH
+0xD578	0x639C	#CJK UNIFIED IDEOGRAPH
+0xD579	0x636D	#CJK UNIFIED IDEOGRAPH
+0xD57A	0x63AE	#CJK UNIFIED IDEOGRAPH
+0xD57B	0x637C	#CJK UNIFIED IDEOGRAPH
+0xD57C	0x63A4	#CJK UNIFIED IDEOGRAPH
+0xD57D	0x633B	#CJK UNIFIED IDEOGRAPH
+0xD57E	0x639F	#CJK UNIFIED IDEOGRAPH
+0xD5A1	0x6378	#CJK UNIFIED IDEOGRAPH
+0xD5A2	0x6385	#CJK UNIFIED IDEOGRAPH
+0xD5A3	0x6381	#CJK UNIFIED IDEOGRAPH
+0xD5A4	0x6391	#CJK UNIFIED IDEOGRAPH
+0xD5A5	0x638D	#CJK UNIFIED IDEOGRAPH
+0xD5A6	0x6370	#CJK UNIFIED IDEOGRAPH
+0xD5A7	0x6553	#CJK UNIFIED IDEOGRAPH
+0xD5A8	0x65CD	#CJK UNIFIED IDEOGRAPH
+0xD5A9	0x6665	#CJK UNIFIED IDEOGRAPH
+0xD5AA	0x6661	#CJK UNIFIED IDEOGRAPH
+0xD5AB	0x665B	#CJK UNIFIED IDEOGRAPH
+0xD5AC	0x6659	#CJK UNIFIED IDEOGRAPH
+0xD5AD	0x665C	#CJK UNIFIED IDEOGRAPH
+0xD5AE	0x6662	#CJK UNIFIED IDEOGRAPH
+0xD5AF	0x6718	#CJK UNIFIED IDEOGRAPH
+0xD5B0	0x6879	#CJK UNIFIED IDEOGRAPH
+0xD5B1	0x6887	#CJK UNIFIED IDEOGRAPH
+0xD5B2	0x6890	#CJK UNIFIED IDEOGRAPH
+0xD5B3	0x689C	#CJK UNIFIED IDEOGRAPH
+0xD5B4	0x686D	#CJK UNIFIED IDEOGRAPH
+0xD5B5	0x686E	#CJK UNIFIED IDEOGRAPH
+0xD5B6	0x68AE	#CJK UNIFIED IDEOGRAPH
+0xD5B7	0x68AB	#CJK UNIFIED IDEOGRAPH
+0xD5B8	0x6956	#CJK UNIFIED IDEOGRAPH
+0xD5B9	0x686F	#CJK UNIFIED IDEOGRAPH
+0xD5BA	0x68A3	#CJK UNIFIED IDEOGRAPH
+0xD5BB	0x68AC	#CJK UNIFIED IDEOGRAPH
+0xD5BC	0x68A9	#CJK UNIFIED IDEOGRAPH
+0xD5BD	0x6875	#CJK UNIFIED IDEOGRAPH
+0xD5BE	0x6874	#CJK UNIFIED IDEOGRAPH
+0xD5BF	0x68B2	#CJK UNIFIED IDEOGRAPH
+0xD5C0	0x688F	#CJK UNIFIED IDEOGRAPH
+0xD5C1	0x6877	#CJK UNIFIED IDEOGRAPH
+0xD5C2	0x6892	#CJK UNIFIED IDEOGRAPH
+0xD5C3	0x687C	#CJK UNIFIED IDEOGRAPH
+0xD5C4	0x686B	#CJK UNIFIED IDEOGRAPH
+0xD5C5	0x6872	#CJK UNIFIED IDEOGRAPH
+0xD5C6	0x68AA	#CJK UNIFIED IDEOGRAPH
+0xD5C7	0x6880	#CJK UNIFIED IDEOGRAPH
+0xD5C8	0x6871	#CJK UNIFIED IDEOGRAPH
+0xD5C9	0x687E	#CJK UNIFIED IDEOGRAPH
+0xD5CA	0x689B	#CJK UNIFIED IDEOGRAPH
+0xD5CB	0x6896	#CJK UNIFIED IDEOGRAPH
+0xD5CC	0x688B	#CJK UNIFIED IDEOGRAPH
+0xD5CD	0x68A0	#CJK UNIFIED IDEOGRAPH
+0xD5CE	0x6889	#CJK UNIFIED IDEOGRAPH
+0xD5CF	0x68A4	#CJK UNIFIED IDEOGRAPH
+0xD5D0	0x6878	#CJK UNIFIED IDEOGRAPH
+0xD5D1	0x687B	#CJK UNIFIED IDEOGRAPH
+0xD5D2	0x6891	#CJK UNIFIED IDEOGRAPH
+0xD5D3	0x688C	#CJK UNIFIED IDEOGRAPH
+0xD5D4	0x688A	#CJK UNIFIED IDEOGRAPH
+0xD5D5	0x687D	#CJK UNIFIED IDEOGRAPH
+0xD5D6	0x6B36	#CJK UNIFIED IDEOGRAPH
+0xD5D7	0x6B33	#CJK UNIFIED IDEOGRAPH
+0xD5D8	0x6B37	#CJK UNIFIED IDEOGRAPH
+0xD5D9	0x6B38	#CJK UNIFIED IDEOGRAPH
+0xD5DA	0x6B91	#CJK UNIFIED IDEOGRAPH
+0xD5DB	0x6B8F	#CJK UNIFIED IDEOGRAPH
+0xD5DC	0x6B8D	#CJK UNIFIED IDEOGRAPH
+0xD5DD	0x6B8E	#CJK UNIFIED IDEOGRAPH
+0xD5DE	0x6B8C	#CJK UNIFIED IDEOGRAPH
+0xD5DF	0x6C2A	#CJK UNIFIED IDEOGRAPH
+0xD5E0	0x6DC0	#CJK UNIFIED IDEOGRAPH
+0xD5E1	0x6DAB	#CJK UNIFIED IDEOGRAPH
+0xD5E2	0x6DB4	#CJK UNIFIED IDEOGRAPH
+0xD5E3	0x6DB3	#CJK UNIFIED IDEOGRAPH
+0xD5E4	0x6E74	#CJK UNIFIED IDEOGRAPH
+0xD5E5	0x6DAC	#CJK UNIFIED IDEOGRAPH
+0xD5E6	0x6DE9	#CJK UNIFIED IDEOGRAPH
+0xD5E7	0x6DE2	#CJK UNIFIED IDEOGRAPH
+0xD5E8	0x6DB7	#CJK UNIFIED IDEOGRAPH
+0xD5E9	0x6DF6	#CJK UNIFIED IDEOGRAPH
+0xD5EA	0x6DD4	#CJK UNIFIED IDEOGRAPH
+0xD5EB	0x6E00	#CJK UNIFIED IDEOGRAPH
+0xD5EC	0x6DC8	#CJK UNIFIED IDEOGRAPH
+0xD5ED	0x6DE0	#CJK UNIFIED IDEOGRAPH
+0xD5EE	0x6DDF	#CJK UNIFIED IDEOGRAPH
+0xD5EF	0x6DD6	#CJK UNIFIED IDEOGRAPH
+0xD5F0	0x6DBE	#CJK UNIFIED IDEOGRAPH
+0xD5F1	0x6DE5	#CJK UNIFIED IDEOGRAPH
+0xD5F2	0x6DDC	#CJK UNIFIED IDEOGRAPH
+0xD5F3	0x6DDD	#CJK UNIFIED IDEOGRAPH
+0xD5F4	0x6DDB	#CJK UNIFIED IDEOGRAPH
+0xD5F5	0x6DF4	#CJK UNIFIED IDEOGRAPH
+0xD5F6	0x6DCA	#CJK UNIFIED IDEOGRAPH
+0xD5F7	0x6DBD	#CJK UNIFIED IDEOGRAPH
+0xD5F8	0x6DED	#CJK UNIFIED IDEOGRAPH
+0xD5F9	0x6DF0	#CJK UNIFIED IDEOGRAPH
+0xD5FA	0x6DBA	#CJK UNIFIED IDEOGRAPH
+0xD5FB	0x6DD5	#CJK UNIFIED IDEOGRAPH
+0xD5FC	0x6DC2	#CJK UNIFIED IDEOGRAPH
+0xD5FD	0x6DCF	#CJK UNIFIED IDEOGRAPH
+0xD5FE	0x6DC9	#CJK UNIFIED IDEOGRAPH
+0xD640	0x6DD0	#CJK UNIFIED IDEOGRAPH
+0xD641	0x6DF2	#CJK UNIFIED IDEOGRAPH
+0xD642	0x6DD3	#CJK UNIFIED IDEOGRAPH
+0xD643	0x6DFD	#CJK UNIFIED IDEOGRAPH
+0xD644	0x6DD7	#CJK UNIFIED IDEOGRAPH
+0xD645	0x6DCD	#CJK UNIFIED IDEOGRAPH
+0xD646	0x6DE3	#CJK UNIFIED IDEOGRAPH
+0xD647	0x6DBB	#CJK UNIFIED IDEOGRAPH
+0xD648	0x70FA	#CJK UNIFIED IDEOGRAPH
+0xD649	0x710D	#CJK UNIFIED IDEOGRAPH
+0xD64A	0x70F7	#CJK UNIFIED IDEOGRAPH
+0xD64B	0x7117	#CJK UNIFIED IDEOGRAPH
+0xD64C	0x70F4	#CJK UNIFIED IDEOGRAPH
+0xD64D	0x710C	#CJK UNIFIED IDEOGRAPH
+0xD64E	0x70F0	#CJK UNIFIED IDEOGRAPH
+0xD64F	0x7104	#CJK UNIFIED IDEOGRAPH
+0xD650	0x70F3	#CJK UNIFIED IDEOGRAPH
+0xD651	0x7110	#CJK UNIFIED IDEOGRAPH
+0xD652	0x70FC	#CJK UNIFIED IDEOGRAPH
+0xD653	0x70FF	#CJK UNIFIED IDEOGRAPH
+0xD654	0x7106	#CJK UNIFIED IDEOGRAPH
+0xD655	0x7113	#CJK UNIFIED IDEOGRAPH
+0xD656	0x7100	#CJK UNIFIED IDEOGRAPH
+0xD657	0x70F8	#CJK UNIFIED IDEOGRAPH
+0xD658	0x70F6	#CJK UNIFIED IDEOGRAPH
+0xD659	0x710B	#CJK UNIFIED IDEOGRAPH
+0xD65A	0x7102	#CJK UNIFIED IDEOGRAPH
+0xD65B	0x710E	#CJK UNIFIED IDEOGRAPH
+0xD65C	0x727E	#CJK UNIFIED IDEOGRAPH
+0xD65D	0x727B	#CJK UNIFIED IDEOGRAPH
+0xD65E	0x727C	#CJK UNIFIED IDEOGRAPH
+0xD65F	0x727F	#CJK UNIFIED IDEOGRAPH
+0xD660	0x731D	#CJK UNIFIED IDEOGRAPH
+0xD661	0x7317	#CJK UNIFIED IDEOGRAPH
+0xD662	0x7307	#CJK UNIFIED IDEOGRAPH
+0xD663	0x7311	#CJK UNIFIED IDEOGRAPH
+0xD664	0x7318	#CJK UNIFIED IDEOGRAPH
+0xD665	0x730A	#CJK UNIFIED IDEOGRAPH
+0xD666	0x7308	#CJK UNIFIED IDEOGRAPH
+0xD667	0x72FF	#CJK UNIFIED IDEOGRAPH
+0xD668	0x730F	#CJK UNIFIED IDEOGRAPH
+0xD669	0x731E	#CJK UNIFIED IDEOGRAPH
+0xD66A	0x7388	#CJK UNIFIED IDEOGRAPH
+0xD66B	0x73F6	#CJK UNIFIED IDEOGRAPH
+0xD66C	0x73F8	#CJK UNIFIED IDEOGRAPH
+0xD66D	0x73F5	#CJK UNIFIED IDEOGRAPH
+0xD66E	0x7404	#CJK UNIFIED IDEOGRAPH
+0xD66F	0x7401	#CJK UNIFIED IDEOGRAPH
+0xD670	0x73FD	#CJK UNIFIED IDEOGRAPH
+0xD671	0x7407	#CJK UNIFIED IDEOGRAPH
+0xD672	0x7400	#CJK UNIFIED IDEOGRAPH
+0xD673	0x73FA	#CJK UNIFIED IDEOGRAPH
+0xD674	0x73FC	#CJK UNIFIED IDEOGRAPH
+0xD675	0x73FF	#CJK UNIFIED IDEOGRAPH
+0xD676	0x740C	#CJK UNIFIED IDEOGRAPH
+0xD677	0x740B	#CJK UNIFIED IDEOGRAPH
+0xD678	0x73F4	#CJK UNIFIED IDEOGRAPH
+0xD679	0x7408	#CJK UNIFIED IDEOGRAPH
+0xD67A	0x7564	#CJK UNIFIED IDEOGRAPH
+0xD67B	0x7563	#CJK UNIFIED IDEOGRAPH
+0xD67C	0x75CE	#CJK UNIFIED IDEOGRAPH
+0xD67D	0x75D2	#CJK UNIFIED IDEOGRAPH
+0xD67E	0x75CF	#CJK UNIFIED IDEOGRAPH
+0xD6A1	0x75CB	#CJK UNIFIED IDEOGRAPH
+0xD6A2	0x75CC	#CJK UNIFIED IDEOGRAPH
+0xD6A3	0x75D1	#CJK UNIFIED IDEOGRAPH
+0xD6A4	0x75D0	#CJK UNIFIED IDEOGRAPH
+0xD6A5	0x768F	#CJK UNIFIED IDEOGRAPH
+0xD6A6	0x7689	#CJK UNIFIED IDEOGRAPH
+0xD6A7	0x76D3	#CJK UNIFIED IDEOGRAPH
+0xD6A8	0x7739	#CJK UNIFIED IDEOGRAPH
+0xD6A9	0x772F	#CJK UNIFIED IDEOGRAPH
+0xD6AA	0x772D	#CJK UNIFIED IDEOGRAPH
+0xD6AB	0x7731	#CJK UNIFIED IDEOGRAPH
+0xD6AC	0x7732	#CJK UNIFIED IDEOGRAPH
+0xD6AD	0x7734	#CJK UNIFIED IDEOGRAPH
+0xD6AE	0x7733	#CJK UNIFIED IDEOGRAPH
+0xD6AF	0x773D	#CJK UNIFIED IDEOGRAPH
+0xD6B0	0x7725	#CJK UNIFIED IDEOGRAPH
+0xD6B1	0x773B	#CJK UNIFIED IDEOGRAPH
+0xD6B2	0x7735	#CJK UNIFIED IDEOGRAPH
+0xD6B3	0x7848	#CJK UNIFIED IDEOGRAPH
+0xD6B4	0x7852	#CJK UNIFIED IDEOGRAPH
+0xD6B5	0x7849	#CJK UNIFIED IDEOGRAPH
+0xD6B6	0x784D	#CJK UNIFIED IDEOGRAPH
+0xD6B7	0x784A	#CJK UNIFIED IDEOGRAPH
+0xD6B8	0x784C	#CJK UNIFIED IDEOGRAPH
+0xD6B9	0x7826	#CJK UNIFIED IDEOGRAPH
+0xD6BA	0x7845	#CJK UNIFIED IDEOGRAPH
+0xD6BB	0x7850	#CJK UNIFIED IDEOGRAPH
+0xD6BC	0x7964	#CJK UNIFIED IDEOGRAPH
+0xD6BD	0x7967	#CJK UNIFIED IDEOGRAPH
+0xD6BE	0x7969	#CJK UNIFIED IDEOGRAPH
+0xD6BF	0x796A	#CJK UNIFIED IDEOGRAPH
+0xD6C0	0x7963	#CJK UNIFIED IDEOGRAPH
+0xD6C1	0x796B	#CJK UNIFIED IDEOGRAPH
+0xD6C2	0x7961	#CJK UNIFIED IDEOGRAPH
+0xD6C3	0x79BB	#CJK UNIFIED IDEOGRAPH
+0xD6C4	0x79FA	#CJK UNIFIED IDEOGRAPH
+0xD6C5	0x79F8	#CJK UNIFIED IDEOGRAPH
+0xD6C6	0x79F6	#CJK UNIFIED IDEOGRAPH
+0xD6C7	0x79F7	#CJK UNIFIED IDEOGRAPH
+0xD6C8	0x7A8F	#CJK UNIFIED IDEOGRAPH
+0xD6C9	0x7A94	#CJK UNIFIED IDEOGRAPH
+0xD6CA	0x7A90	#CJK UNIFIED IDEOGRAPH
+0xD6CB	0x7B35	#CJK UNIFIED IDEOGRAPH
+0xD6CC	0x7B47	#CJK UNIFIED IDEOGRAPH
+0xD6CD	0x7B34	#CJK UNIFIED IDEOGRAPH
+0xD6CE	0x7B25	#CJK UNIFIED IDEOGRAPH
+0xD6CF	0x7B30	#CJK UNIFIED IDEOGRAPH
+0xD6D0	0x7B22	#CJK UNIFIED IDEOGRAPH
+0xD6D1	0x7B24	#CJK UNIFIED IDEOGRAPH
+0xD6D2	0x7B33	#CJK UNIFIED IDEOGRAPH
+0xD6D3	0x7B18	#CJK UNIFIED IDEOGRAPH
+0xD6D4	0x7B2A	#CJK UNIFIED IDEOGRAPH
+0xD6D5	0x7B1D	#CJK UNIFIED IDEOGRAPH
+0xD6D6	0x7B31	#CJK UNIFIED IDEOGRAPH
+0xD6D7	0x7B2B	#CJK UNIFIED IDEOGRAPH
+0xD6D8	0x7B2D	#CJK UNIFIED IDEOGRAPH
+0xD6D9	0x7B2F	#CJK UNIFIED IDEOGRAPH
+0xD6DA	0x7B32	#CJK UNIFIED IDEOGRAPH
+0xD6DB	0x7B38	#CJK UNIFIED IDEOGRAPH
+0xD6DC	0x7B1A	#CJK UNIFIED IDEOGRAPH
+0xD6DD	0x7B23	#CJK UNIFIED IDEOGRAPH
+0xD6DE	0x7C94	#CJK UNIFIED IDEOGRAPH
+0xD6DF	0x7C98	#CJK UNIFIED IDEOGRAPH
+0xD6E0	0x7C96	#CJK UNIFIED IDEOGRAPH
+0xD6E1	0x7CA3	#CJK UNIFIED IDEOGRAPH
+0xD6E2	0x7D35	#CJK UNIFIED IDEOGRAPH
+0xD6E3	0x7D3D	#CJK UNIFIED IDEOGRAPH
+0xD6E4	0x7D38	#CJK UNIFIED IDEOGRAPH
+0xD6E5	0x7D36	#CJK UNIFIED IDEOGRAPH
+0xD6E6	0x7D3A	#CJK UNIFIED IDEOGRAPH
+0xD6E7	0x7D45	#CJK UNIFIED IDEOGRAPH
+0xD6E8	0x7D2C	#CJK UNIFIED IDEOGRAPH
+0xD6E9	0x7D29	#CJK UNIFIED IDEOGRAPH
+0xD6EA	0x7D41	#CJK UNIFIED IDEOGRAPH
+0xD6EB	0x7D47	#CJK UNIFIED IDEOGRAPH
+0xD6EC	0x7D3E	#CJK UNIFIED IDEOGRAPH
+0xD6ED	0x7D3F	#CJK UNIFIED IDEOGRAPH
+0xD6EE	0x7D4A	#CJK UNIFIED IDEOGRAPH
+0xD6EF	0x7D3B	#CJK UNIFIED IDEOGRAPH
+0xD6F0	0x7D28	#CJK UNIFIED IDEOGRAPH
+0xD6F1	0x7F63	#CJK UNIFIED IDEOGRAPH
+0xD6F2	0x7F95	#CJK UNIFIED IDEOGRAPH
+0xD6F3	0x7F9C	#CJK UNIFIED IDEOGRAPH
+0xD6F4	0x7F9D	#CJK UNIFIED IDEOGRAPH
+0xD6F5	0x7F9B	#CJK UNIFIED IDEOGRAPH
+0xD6F6	0x7FCA	#CJK UNIFIED IDEOGRAPH
+0xD6F7	0x7FCB	#CJK UNIFIED IDEOGRAPH
+0xD6F8	0x7FCD	#CJK UNIFIED IDEOGRAPH
+0xD6F9	0x7FD0	#CJK UNIFIED IDEOGRAPH
+0xD6FA	0x7FD1	#CJK UNIFIED IDEOGRAPH
+0xD6FB	0x7FC7	#CJK UNIFIED IDEOGRAPH
+0xD6FC	0x7FCF	#CJK UNIFIED IDEOGRAPH
+0xD6FD	0x7FC9	#CJK UNIFIED IDEOGRAPH
+0xD6FE	0x801F	#CJK UNIFIED IDEOGRAPH
+0xD740	0x801E	#CJK UNIFIED IDEOGRAPH
+0xD741	0x801B	#CJK UNIFIED IDEOGRAPH
+0xD742	0x8047	#CJK UNIFIED IDEOGRAPH
+0xD743	0x8043	#CJK UNIFIED IDEOGRAPH
+0xD744	0x8048	#CJK UNIFIED IDEOGRAPH
+0xD745	0x8118	#CJK UNIFIED IDEOGRAPH
+0xD746	0x8125	#CJK UNIFIED IDEOGRAPH
+0xD747	0x8119	#CJK UNIFIED IDEOGRAPH
+0xD748	0x811B	#CJK UNIFIED IDEOGRAPH
+0xD749	0x812D	#CJK UNIFIED IDEOGRAPH
+0xD74A	0x811F	#CJK UNIFIED IDEOGRAPH
+0xD74B	0x812C	#CJK UNIFIED IDEOGRAPH
+0xD74C	0x811E	#CJK UNIFIED IDEOGRAPH
+0xD74D	0x8121	#CJK UNIFIED IDEOGRAPH
+0xD74E	0x8115	#CJK UNIFIED IDEOGRAPH
+0xD74F	0x8127	#CJK UNIFIED IDEOGRAPH
+0xD750	0x811D	#CJK UNIFIED IDEOGRAPH
+0xD751	0x8122	#CJK UNIFIED IDEOGRAPH
+0xD752	0x8211	#CJK UNIFIED IDEOGRAPH
+0xD753	0x8238	#CJK UNIFIED IDEOGRAPH
+0xD754	0x8233	#CJK UNIFIED IDEOGRAPH
+0xD755	0x823A	#CJK UNIFIED IDEOGRAPH
+0xD756	0x8234	#CJK UNIFIED IDEOGRAPH
+0xD757	0x8232	#CJK UNIFIED IDEOGRAPH
+0xD758	0x8274	#CJK UNIFIED IDEOGRAPH
+0xD759	0x8390	#CJK UNIFIED IDEOGRAPH
+0xD75A	0x83A3	#CJK UNIFIED IDEOGRAPH
+0xD75B	0x83A8	#CJK UNIFIED IDEOGRAPH
+0xD75C	0x838D	#CJK UNIFIED IDEOGRAPH
+0xD75D	0x837A	#CJK UNIFIED IDEOGRAPH
+0xD75E	0x8373	#CJK UNIFIED IDEOGRAPH
+0xD75F	0x83A4	#CJK UNIFIED IDEOGRAPH
+0xD760	0x8374	#CJK UNIFIED IDEOGRAPH
+0xD761	0x838F	#CJK UNIFIED IDEOGRAPH
+0xD762	0x8381	#CJK UNIFIED IDEOGRAPH
+0xD763	0x8395	#CJK UNIFIED IDEOGRAPH
+0xD764	0x8399	#CJK UNIFIED IDEOGRAPH
+0xD765	0x8375	#CJK UNIFIED IDEOGRAPH
+0xD766	0x8394	#CJK UNIFIED IDEOGRAPH
+0xD767	0x83A9	#CJK UNIFIED IDEOGRAPH
+0xD768	0x837D	#CJK UNIFIED IDEOGRAPH
+0xD769	0x8383	#CJK UNIFIED IDEOGRAPH
+0xD76A	0x838C	#CJK UNIFIED IDEOGRAPH
+0xD76B	0x839D	#CJK UNIFIED IDEOGRAPH
+0xD76C	0x839B	#CJK UNIFIED IDEOGRAPH
+0xD76D	0x83AA	#CJK UNIFIED IDEOGRAPH
+0xD76E	0x838B	#CJK UNIFIED IDEOGRAPH
+0xD76F	0x837E	#CJK UNIFIED IDEOGRAPH
+0xD770	0x83A5	#CJK UNIFIED IDEOGRAPH
+0xD771	0x83AF	#CJK UNIFIED IDEOGRAPH
+0xD772	0x8388	#CJK UNIFIED IDEOGRAPH
+0xD773	0x8397	#CJK UNIFIED IDEOGRAPH
+0xD774	0x83B0	#CJK UNIFIED IDEOGRAPH
+0xD775	0x837F	#CJK UNIFIED IDEOGRAPH
+0xD776	0x83A6	#CJK UNIFIED IDEOGRAPH
+0xD777	0x8387	#CJK UNIFIED IDEOGRAPH
+0xD778	0x83AE	#CJK UNIFIED IDEOGRAPH
+0xD779	0x8376	#CJK UNIFIED IDEOGRAPH
+0xD77A	0x839A	#CJK UNIFIED IDEOGRAPH
+0xD77B	0x8659	#CJK UNIFIED IDEOGRAPH
+0xD77C	0x8656	#CJK UNIFIED IDEOGRAPH
+0xD77D	0x86BF	#CJK UNIFIED IDEOGRAPH
+0xD77E	0x86B7	#CJK UNIFIED IDEOGRAPH
+0xD7A1	0x86C2	#CJK UNIFIED IDEOGRAPH
+0xD7A2	0x86C1	#CJK UNIFIED IDEOGRAPH
+0xD7A3	0x86C5	#CJK UNIFIED IDEOGRAPH
+0xD7A4	0x86BA	#CJK UNIFIED IDEOGRAPH
+0xD7A5	0x86B0	#CJK UNIFIED IDEOGRAPH
+0xD7A6	0x86C8	#CJK UNIFIED IDEOGRAPH
+0xD7A7	0x86B9	#CJK UNIFIED IDEOGRAPH
+0xD7A8	0x86B3	#CJK UNIFIED IDEOGRAPH
+0xD7A9	0x86B8	#CJK UNIFIED IDEOGRAPH
+0xD7AA	0x86CC	#CJK UNIFIED IDEOGRAPH
+0xD7AB	0x86B4	#CJK UNIFIED IDEOGRAPH
+0xD7AC	0x86BB	#CJK UNIFIED IDEOGRAPH
+0xD7AD	0x86BC	#CJK UNIFIED IDEOGRAPH
+0xD7AE	0x86C3	#CJK UNIFIED IDEOGRAPH
+0xD7AF	0x86BD	#CJK UNIFIED IDEOGRAPH
+0xD7B0	0x86BE	#CJK UNIFIED IDEOGRAPH
+0xD7B1	0x8852	#CJK UNIFIED IDEOGRAPH
+0xD7B2	0x8889	#CJK UNIFIED IDEOGRAPH
+0xD7B3	0x8895	#CJK UNIFIED IDEOGRAPH
+0xD7B4	0x88A8	#CJK UNIFIED IDEOGRAPH
+0xD7B5	0x88A2	#CJK UNIFIED IDEOGRAPH
+0xD7B6	0x88AA	#CJK UNIFIED IDEOGRAPH
+0xD7B7	0x889A	#CJK UNIFIED IDEOGRAPH
+0xD7B8	0x8891	#CJK UNIFIED IDEOGRAPH
+0xD7B9	0x88A1	#CJK UNIFIED IDEOGRAPH
+0xD7BA	0x889F	#CJK UNIFIED IDEOGRAPH
+0xD7BB	0x8898	#CJK UNIFIED IDEOGRAPH
+0xD7BC	0x88A7	#CJK UNIFIED IDEOGRAPH
+0xD7BD	0x8899	#CJK UNIFIED IDEOGRAPH
+0xD7BE	0x889B	#CJK UNIFIED IDEOGRAPH
+0xD7BF	0x8897	#CJK UNIFIED IDEOGRAPH
+0xD7C0	0x88A4	#CJK UNIFIED IDEOGRAPH
+0xD7C1	0x88AC	#CJK UNIFIED IDEOGRAPH
+0xD7C2	0x888C	#CJK UNIFIED IDEOGRAPH
+0xD7C3	0x8893	#CJK UNIFIED IDEOGRAPH
+0xD7C4	0x888E	#CJK UNIFIED IDEOGRAPH
+0xD7C5	0x8982	#CJK UNIFIED IDEOGRAPH
+0xD7C6	0x89D6	#CJK UNIFIED IDEOGRAPH
+0xD7C7	0x89D9	#CJK UNIFIED IDEOGRAPH
+0xD7C8	0x89D5	#CJK UNIFIED IDEOGRAPH
+0xD7C9	0x8A30	#CJK UNIFIED IDEOGRAPH
+0xD7CA	0x8A27	#CJK UNIFIED IDEOGRAPH
+0xD7CB	0x8A2C	#CJK UNIFIED IDEOGRAPH
+0xD7CC	0x8A1E	#CJK UNIFIED IDEOGRAPH
+0xD7CD	0x8C39	#CJK UNIFIED IDEOGRAPH
+0xD7CE	0x8C3B	#CJK UNIFIED IDEOGRAPH
+0xD7CF	0x8C5C	#CJK UNIFIED IDEOGRAPH
+0xD7D0	0x8C5D	#CJK UNIFIED IDEOGRAPH
+0xD7D1	0x8C7D	#CJK UNIFIED IDEOGRAPH
+0xD7D2	0x8CA5	#CJK UNIFIED IDEOGRAPH
+0xD7D3	0x8D7D	#CJK UNIFIED IDEOGRAPH
+0xD7D4	0x8D7B	#CJK UNIFIED IDEOGRAPH
+0xD7D5	0x8D79	#CJK UNIFIED IDEOGRAPH
+0xD7D6	0x8DBC	#CJK UNIFIED IDEOGRAPH
+0xD7D7	0x8DC2	#CJK UNIFIED IDEOGRAPH
+0xD7D8	0x8DB9	#CJK UNIFIED IDEOGRAPH
+0xD7D9	0x8DBF	#CJK UNIFIED IDEOGRAPH
+0xD7DA	0x8DC1	#CJK UNIFIED IDEOGRAPH
+0xD7DB	0x8ED8	#CJK UNIFIED IDEOGRAPH
+0xD7DC	0x8EDE	#CJK UNIFIED IDEOGRAPH
+0xD7DD	0x8EDD	#CJK UNIFIED IDEOGRAPH
+0xD7DE	0x8EDC	#CJK UNIFIED IDEOGRAPH
+0xD7DF	0x8ED7	#CJK UNIFIED IDEOGRAPH
+0xD7E0	0x8EE0	#CJK UNIFIED IDEOGRAPH
+0xD7E1	0x8EE1	#CJK UNIFIED IDEOGRAPH
+0xD7E2	0x9024	#CJK UNIFIED IDEOGRAPH
+0xD7E3	0x900B	#CJK UNIFIED IDEOGRAPH
+0xD7E4	0x9011	#CJK UNIFIED IDEOGRAPH
+0xD7E5	0x901C	#CJK UNIFIED IDEOGRAPH
+0xD7E6	0x900C	#CJK UNIFIED IDEOGRAPH
+0xD7E7	0x9021	#CJK UNIFIED IDEOGRAPH
+0xD7E8	0x90EF	#CJK UNIFIED IDEOGRAPH
+0xD7E9	0x90EA	#CJK UNIFIED IDEOGRAPH
+0xD7EA	0x90F0	#CJK UNIFIED IDEOGRAPH
+0xD7EB	0x90F4	#CJK UNIFIED IDEOGRAPH
+0xD7EC	0x90F2	#CJK UNIFIED IDEOGRAPH
+0xD7ED	0x90F3	#CJK UNIFIED IDEOGRAPH
+0xD7EE	0x90D4	#CJK UNIFIED IDEOGRAPH
+0xD7EF	0x90EB	#CJK UNIFIED IDEOGRAPH
+0xD7F0	0x90EC	#CJK UNIFIED IDEOGRAPH
+0xD7F1	0x90E9	#CJK UNIFIED IDEOGRAPH
+0xD7F2	0x9156	#CJK UNIFIED IDEOGRAPH
+0xD7F3	0x9158	#CJK UNIFIED IDEOGRAPH
+0xD7F4	0x915A	#CJK UNIFIED IDEOGRAPH
+0xD7F5	0x9153	#CJK UNIFIED IDEOGRAPH
+0xD7F6	0x9155	#CJK UNIFIED IDEOGRAPH
+0xD7F7	0x91EC	#CJK UNIFIED IDEOGRAPH
+0xD7F8	0x91F4	#CJK UNIFIED IDEOGRAPH
+0xD7F9	0x91F1	#CJK UNIFIED IDEOGRAPH
+0xD7FA	0x91F3	#CJK UNIFIED IDEOGRAPH
+0xD7FB	0x91F8	#CJK UNIFIED IDEOGRAPH
+0xD7FC	0x91E4	#CJK UNIFIED IDEOGRAPH
+0xD7FD	0x91F9	#CJK UNIFIED IDEOGRAPH
+0xD7FE	0x91EA	#CJK UNIFIED IDEOGRAPH
+0xD840	0x91EB	#CJK UNIFIED IDEOGRAPH
+0xD841	0x91F7	#CJK UNIFIED IDEOGRAPH
+0xD842	0x91E8	#CJK UNIFIED IDEOGRAPH
+0xD843	0x91EE	#CJK UNIFIED IDEOGRAPH
+0xD844	0x957A	#CJK UNIFIED IDEOGRAPH
+0xD845	0x9586	#CJK UNIFIED IDEOGRAPH
+0xD846	0x9588	#CJK UNIFIED IDEOGRAPH
+0xD847	0x967C	#CJK UNIFIED IDEOGRAPH
+0xD848	0x966D	#CJK UNIFIED IDEOGRAPH
+0xD849	0x966B	#CJK UNIFIED IDEOGRAPH
+0xD84A	0x9671	#CJK UNIFIED IDEOGRAPH
+0xD84B	0x966F	#CJK UNIFIED IDEOGRAPH
+0xD84C	0x96BF	#CJK UNIFIED IDEOGRAPH
+0xD84D	0x976A	#CJK UNIFIED IDEOGRAPH
+0xD84E	0x9804	#CJK UNIFIED IDEOGRAPH
+0xD84F	0x98E5	#CJK UNIFIED IDEOGRAPH
+0xD850	0x9997	#CJK UNIFIED IDEOGRAPH
+0xD851	0x509B	#CJK UNIFIED IDEOGRAPH
+0xD852	0x5095	#CJK UNIFIED IDEOGRAPH
+0xD853	0x5094	#CJK UNIFIED IDEOGRAPH
+0xD854	0x509E	#CJK UNIFIED IDEOGRAPH
+0xD855	0x508B	#CJK UNIFIED IDEOGRAPH
+0xD856	0x50A3	#CJK UNIFIED IDEOGRAPH
+0xD857	0x5083	#CJK UNIFIED IDEOGRAPH
+0xD858	0x508C	#CJK UNIFIED IDEOGRAPH
+0xD859	0x508E	#CJK UNIFIED IDEOGRAPH
+0xD85A	0x509D	#CJK UNIFIED IDEOGRAPH
+0xD85B	0x5068	#CJK UNIFIED IDEOGRAPH
+0xD85C	0x509C	#CJK UNIFIED IDEOGRAPH
+0xD85D	0x5092	#CJK UNIFIED IDEOGRAPH
+0xD85E	0x5082	#CJK UNIFIED IDEOGRAPH
+0xD85F	0x5087	#CJK UNIFIED IDEOGRAPH
+0xD860	0x515F	#CJK UNIFIED IDEOGRAPH
+0xD861	0x51D4	#CJK UNIFIED IDEOGRAPH
+0xD862	0x5312	#CJK UNIFIED IDEOGRAPH
+0xD863	0x5311	#CJK UNIFIED IDEOGRAPH
+0xD864	0x53A4	#CJK UNIFIED IDEOGRAPH
+0xD865	0x53A7	#CJK UNIFIED IDEOGRAPH
+0xD866	0x5591	#CJK UNIFIED IDEOGRAPH
+0xD867	0x55A8	#CJK UNIFIED IDEOGRAPH
+0xD868	0x55A5	#CJK UNIFIED IDEOGRAPH
+0xD869	0x55AD	#CJK UNIFIED IDEOGRAPH
+0xD86A	0x5577	#CJK UNIFIED IDEOGRAPH
+0xD86B	0x5645	#CJK UNIFIED IDEOGRAPH
+0xD86C	0x55A2	#CJK UNIFIED IDEOGRAPH
+0xD86D	0x5593	#CJK UNIFIED IDEOGRAPH
+0xD86E	0x5588	#CJK UNIFIED IDEOGRAPH
+0xD86F	0x558F	#CJK UNIFIED IDEOGRAPH
+0xD870	0x55B5	#CJK UNIFIED IDEOGRAPH
+0xD871	0x5581	#CJK UNIFIED IDEOGRAPH
+0xD872	0x55A3	#CJK UNIFIED IDEOGRAPH
+0xD873	0x5592	#CJK UNIFIED IDEOGRAPH
+0xD874	0x55A4	#CJK UNIFIED IDEOGRAPH
+0xD875	0x557D	#CJK UNIFIED IDEOGRAPH
+0xD876	0x558C	#CJK UNIFIED IDEOGRAPH
+0xD877	0x55A6	#CJK UNIFIED IDEOGRAPH
+0xD878	0x557F	#CJK UNIFIED IDEOGRAPH
+0xD879	0x5595	#CJK UNIFIED IDEOGRAPH
+0xD87A	0x55A1	#CJK UNIFIED IDEOGRAPH
+0xD87B	0x558E	#CJK UNIFIED IDEOGRAPH
+0xD87C	0x570C	#CJK UNIFIED IDEOGRAPH
+0xD87D	0x5829	#CJK UNIFIED IDEOGRAPH
+0xD87E	0x5837	#CJK UNIFIED IDEOGRAPH
+0xD8A1	0x5819	#CJK UNIFIED IDEOGRAPH
+0xD8A2	0x581E	#CJK UNIFIED IDEOGRAPH
+0xD8A3	0x5827	#CJK UNIFIED IDEOGRAPH
+0xD8A4	0x5823	#CJK UNIFIED IDEOGRAPH
+0xD8A5	0x5828	#CJK UNIFIED IDEOGRAPH
+0xD8A6	0x57F5	#CJK UNIFIED IDEOGRAPH
+0xD8A7	0x5848	#CJK UNIFIED IDEOGRAPH
+0xD8A8	0x5825	#CJK UNIFIED IDEOGRAPH
+0xD8A9	0x581C	#CJK UNIFIED IDEOGRAPH
+0xD8AA	0x581B	#CJK UNIFIED IDEOGRAPH
+0xD8AB	0x5833	#CJK UNIFIED IDEOGRAPH
+0xD8AC	0x583F	#CJK UNIFIED IDEOGRAPH
+0xD8AD	0x5836	#CJK UNIFIED IDEOGRAPH
+0xD8AE	0x582E	#CJK UNIFIED IDEOGRAPH
+0xD8AF	0x5839	#CJK UNIFIED IDEOGRAPH
+0xD8B0	0x5838	#CJK UNIFIED IDEOGRAPH
+0xD8B1	0x582D	#CJK UNIFIED IDEOGRAPH
+0xD8B2	0x582C	#CJK UNIFIED IDEOGRAPH
+0xD8B3	0x583B	#CJK UNIFIED IDEOGRAPH
+0xD8B4	0x5961	#CJK UNIFIED IDEOGRAPH
+0xD8B5	0x5AAF	#CJK UNIFIED IDEOGRAPH
+0xD8B6	0x5A94	#CJK UNIFIED IDEOGRAPH
+0xD8B7	0x5A9F	#CJK UNIFIED IDEOGRAPH
+0xD8B8	0x5A7A	#CJK UNIFIED IDEOGRAPH
+0xD8B9	0x5AA2	#CJK UNIFIED IDEOGRAPH
+0xD8BA	0x5A9E	#CJK UNIFIED IDEOGRAPH
+0xD8BB	0x5A78	#CJK UNIFIED IDEOGRAPH
+0xD8BC	0x5AA6	#CJK UNIFIED IDEOGRAPH
+0xD8BD	0x5A7C	#CJK UNIFIED IDEOGRAPH
+0xD8BE	0x5AA5	#CJK UNIFIED IDEOGRAPH
+0xD8BF	0x5AAC	#CJK UNIFIED IDEOGRAPH
+0xD8C0	0x5A95	#CJK UNIFIED IDEOGRAPH
+0xD8C1	0x5AAE	#CJK UNIFIED IDEOGRAPH
+0xD8C2	0x5A37	#CJK UNIFIED IDEOGRAPH
+0xD8C3	0x5A84	#CJK UNIFIED IDEOGRAPH
+0xD8C4	0x5A8A	#CJK UNIFIED IDEOGRAPH
+0xD8C5	0x5A97	#CJK UNIFIED IDEOGRAPH
+0xD8C6	0x5A83	#CJK UNIFIED IDEOGRAPH
+0xD8C7	0x5A8B	#CJK UNIFIED IDEOGRAPH
+0xD8C8	0x5AA9	#CJK UNIFIED IDEOGRAPH
+0xD8C9	0x5A7B	#CJK UNIFIED IDEOGRAPH
+0xD8CA	0x5A7D	#CJK UNIFIED IDEOGRAPH
+0xD8CB	0x5A8C	#CJK UNIFIED IDEOGRAPH
+0xD8CC	0x5A9C	#CJK UNIFIED IDEOGRAPH
+0xD8CD	0x5A8F	#CJK UNIFIED IDEOGRAPH
+0xD8CE	0x5A93	#CJK UNIFIED IDEOGRAPH
+0xD8CF	0x5A9D	#CJK UNIFIED IDEOGRAPH
+0xD8D0	0x5BEA	#CJK UNIFIED IDEOGRAPH
+0xD8D1	0x5BCD	#CJK UNIFIED IDEOGRAPH
+0xD8D2	0x5BCB	#CJK UNIFIED IDEOGRAPH
+0xD8D3	0x5BD4	#CJK UNIFIED IDEOGRAPH
+0xD8D4	0x5BD1	#CJK UNIFIED IDEOGRAPH
+0xD8D5	0x5BCA	#CJK UNIFIED IDEOGRAPH
+0xD8D6	0x5BCE	#CJK UNIFIED IDEOGRAPH
+0xD8D7	0x5C0C	#CJK UNIFIED IDEOGRAPH
+0xD8D8	0x5C30	#CJK UNIFIED IDEOGRAPH
+0xD8D9	0x5D37	#CJK UNIFIED IDEOGRAPH
+0xD8DA	0x5D43	#CJK UNIFIED IDEOGRAPH
+0xD8DB	0x5D6B	#CJK UNIFIED IDEOGRAPH
+0xD8DC	0x5D41	#CJK UNIFIED IDEOGRAPH
+0xD8DD	0x5D4B	#CJK UNIFIED IDEOGRAPH
+0xD8DE	0x5D3F	#CJK UNIFIED IDEOGRAPH
+0xD8DF	0x5D35	#CJK UNIFIED IDEOGRAPH
+0xD8E0	0x5D51	#CJK UNIFIED IDEOGRAPH
+0xD8E1	0x5D4E	#CJK UNIFIED IDEOGRAPH
+0xD8E2	0x5D55	#CJK UNIFIED IDEOGRAPH
+0xD8E3	0x5D33	#CJK UNIFIED IDEOGRAPH
+0xD8E4	0x5D3A	#CJK UNIFIED IDEOGRAPH
+0xD8E5	0x5D52	#CJK UNIFIED IDEOGRAPH
+0xD8E6	0x5D3D	#CJK UNIFIED IDEOGRAPH
+0xD8E7	0x5D31	#CJK UNIFIED IDEOGRAPH
+0xD8E8	0x5D59	#CJK UNIFIED IDEOGRAPH
+0xD8E9	0x5D42	#CJK UNIFIED IDEOGRAPH
+0xD8EA	0x5D39	#CJK UNIFIED IDEOGRAPH
+0xD8EB	0x5D49	#CJK UNIFIED IDEOGRAPH
+0xD8EC	0x5D38	#CJK UNIFIED IDEOGRAPH
+0xD8ED	0x5D3C	#CJK UNIFIED IDEOGRAPH
+0xD8EE	0x5D32	#CJK UNIFIED IDEOGRAPH
+0xD8EF	0x5D36	#CJK UNIFIED IDEOGRAPH
+0xD8F0	0x5D40	#CJK UNIFIED IDEOGRAPH
+0xD8F1	0x5D45	#CJK UNIFIED IDEOGRAPH
+0xD8F2	0x5E44	#CJK UNIFIED IDEOGRAPH
+0xD8F3	0x5E41	#CJK UNIFIED IDEOGRAPH
+0xD8F4	0x5F58	#CJK UNIFIED IDEOGRAPH
+0xD8F5	0x5FA6	#CJK UNIFIED IDEOGRAPH
+0xD8F6	0x5FA5	#CJK UNIFIED IDEOGRAPH
+0xD8F7	0x5FAB	#CJK UNIFIED IDEOGRAPH
+0xD8F8	0x60C9	#CJK UNIFIED IDEOGRAPH
+0xD8F9	0x60B9	#CJK UNIFIED IDEOGRAPH
+0xD8FA	0x60CC	#CJK UNIFIED IDEOGRAPH
+0xD8FB	0x60E2	#CJK UNIFIED IDEOGRAPH
+0xD8FC	0x60CE	#CJK UNIFIED IDEOGRAPH
+0xD8FD	0x60C4	#CJK UNIFIED IDEOGRAPH
+0xD8FE	0x6114	#CJK UNIFIED IDEOGRAPH
+0xD940	0x60F2	#CJK UNIFIED IDEOGRAPH
+0xD941	0x610A	#CJK UNIFIED IDEOGRAPH
+0xD942	0x6116	#CJK UNIFIED IDEOGRAPH
+0xD943	0x6105	#CJK UNIFIED IDEOGRAPH
+0xD944	0x60F5	#CJK UNIFIED IDEOGRAPH
+0xD945	0x6113	#CJK UNIFIED IDEOGRAPH
+0xD946	0x60F8	#CJK UNIFIED IDEOGRAPH
+0xD947	0x60FC	#CJK UNIFIED IDEOGRAPH
+0xD948	0x60FE	#CJK UNIFIED IDEOGRAPH
+0xD949	0x60C1	#CJK UNIFIED IDEOGRAPH
+0xD94A	0x6103	#CJK UNIFIED IDEOGRAPH
+0xD94B	0x6118	#CJK UNIFIED IDEOGRAPH
+0xD94C	0x611D	#CJK UNIFIED IDEOGRAPH
+0xD94D	0x6110	#CJK UNIFIED IDEOGRAPH
+0xD94E	0x60FF	#CJK UNIFIED IDEOGRAPH
+0xD94F	0x6104	#CJK UNIFIED IDEOGRAPH
+0xD950	0x610B	#CJK UNIFIED IDEOGRAPH
+0xD951	0x624A	#CJK UNIFIED IDEOGRAPH
+0xD952	0x6394	#CJK UNIFIED IDEOGRAPH
+0xD953	0x63B1	#CJK UNIFIED IDEOGRAPH
+0xD954	0x63B0	#CJK UNIFIED IDEOGRAPH
+0xD955	0x63CE	#CJK UNIFIED IDEOGRAPH
+0xD956	0x63E5	#CJK UNIFIED IDEOGRAPH
+0xD957	0x63E8	#CJK UNIFIED IDEOGRAPH
+0xD958	0x63EF	#CJK UNIFIED IDEOGRAPH
+0xD959	0x63C3	#CJK UNIFIED IDEOGRAPH
+0xD95A	0x649D	#CJK UNIFIED IDEOGRAPH
+0xD95B	0x63F3	#CJK UNIFIED IDEOGRAPH
+0xD95C	0x63CA	#CJK UNIFIED IDEOGRAPH
+0xD95D	0x63E0	#CJK UNIFIED IDEOGRAPH
+0xD95E	0x63F6	#CJK UNIFIED IDEOGRAPH
+0xD95F	0x63D5	#CJK UNIFIED IDEOGRAPH
+0xD960	0x63F2	#CJK UNIFIED IDEOGRAPH
+0xD961	0x63F5	#CJK UNIFIED IDEOGRAPH
+0xD962	0x6461	#CJK UNIFIED IDEOGRAPH
+0xD963	0x63DF	#CJK UNIFIED IDEOGRAPH
+0xD964	0x63BE	#CJK UNIFIED IDEOGRAPH
+0xD965	0x63DD	#CJK UNIFIED IDEOGRAPH
+0xD966	0x63DC	#CJK UNIFIED IDEOGRAPH
+0xD967	0x63C4	#CJK UNIFIED IDEOGRAPH
+0xD968	0x63D8	#CJK UNIFIED IDEOGRAPH
+0xD969	0x63D3	#CJK UNIFIED IDEOGRAPH
+0xD96A	0x63C2	#CJK UNIFIED IDEOGRAPH
+0xD96B	0x63C7	#CJK UNIFIED IDEOGRAPH
+0xD96C	0x63CC	#CJK UNIFIED IDEOGRAPH
+0xD96D	0x63CB	#CJK UNIFIED IDEOGRAPH
+0xD96E	0x63C8	#CJK UNIFIED IDEOGRAPH
+0xD96F	0x63F0	#CJK UNIFIED IDEOGRAPH
+0xD970	0x63D7	#CJK UNIFIED IDEOGRAPH
+0xD971	0x63D9	#CJK UNIFIED IDEOGRAPH
+0xD972	0x6532	#CJK UNIFIED IDEOGRAPH
+0xD973	0x6567	#CJK UNIFIED IDEOGRAPH
+0xD974	0x656A	#CJK UNIFIED IDEOGRAPH
+0xD975	0x6564	#CJK UNIFIED IDEOGRAPH
+0xD976	0x655C	#CJK UNIFIED IDEOGRAPH
+0xD977	0x6568	#CJK UNIFIED IDEOGRAPH
+0xD978	0x6565	#CJK UNIFIED IDEOGRAPH
+0xD979	0x658C	#CJK UNIFIED IDEOGRAPH
+0xD97A	0x659D	#CJK UNIFIED IDEOGRAPH
+0xD97B	0x659E	#CJK UNIFIED IDEOGRAPH
+0xD97C	0x65AE	#CJK UNIFIED IDEOGRAPH
+0xD97D	0x65D0	#CJK UNIFIED IDEOGRAPH
+0xD97E	0x65D2	#CJK UNIFIED IDEOGRAPH
+0xD9A1	0x667C	#CJK UNIFIED IDEOGRAPH
+0xD9A2	0x666C	#CJK UNIFIED IDEOGRAPH
+0xD9A3	0x667B	#CJK UNIFIED IDEOGRAPH
+0xD9A4	0x6680	#CJK UNIFIED IDEOGRAPH
+0xD9A5	0x6671	#CJK UNIFIED IDEOGRAPH
+0xD9A6	0x6679	#CJK UNIFIED IDEOGRAPH
+0xD9A7	0x666A	#CJK UNIFIED IDEOGRAPH
+0xD9A8	0x6672	#CJK UNIFIED IDEOGRAPH
+0xD9A9	0x6701	#CJK UNIFIED IDEOGRAPH
+0xD9AA	0x690C	#CJK UNIFIED IDEOGRAPH
+0xD9AB	0x68D3	#CJK UNIFIED IDEOGRAPH
+0xD9AC	0x6904	#CJK UNIFIED IDEOGRAPH
+0xD9AD	0x68DC	#CJK UNIFIED IDEOGRAPH
+0xD9AE	0x692A	#CJK UNIFIED IDEOGRAPH
+0xD9AF	0x68EC	#CJK UNIFIED IDEOGRAPH
+0xD9B0	0x68EA	#CJK UNIFIED IDEOGRAPH
+0xD9B1	0x68F1	#CJK UNIFIED IDEOGRAPH
+0xD9B2	0x690F	#CJK UNIFIED IDEOGRAPH
+0xD9B3	0x68D6	#CJK UNIFIED IDEOGRAPH
+0xD9B4	0x68F7	#CJK UNIFIED IDEOGRAPH
+0xD9B5	0x68EB	#CJK UNIFIED IDEOGRAPH
+0xD9B6	0x68E4	#CJK UNIFIED IDEOGRAPH
+0xD9B7	0x68F6	#CJK UNIFIED IDEOGRAPH
+0xD9B8	0x6913	#CJK UNIFIED IDEOGRAPH
+0xD9B9	0x6910	#CJK UNIFIED IDEOGRAPH
+0xD9BA	0x68F3	#CJK UNIFIED IDEOGRAPH
+0xD9BB	0x68E1	#CJK UNIFIED IDEOGRAPH
+0xD9BC	0x6907	#CJK UNIFIED IDEOGRAPH
+0xD9BD	0x68CC	#CJK UNIFIED IDEOGRAPH
+0xD9BE	0x6908	#CJK UNIFIED IDEOGRAPH
+0xD9BF	0x6970	#CJK UNIFIED IDEOGRAPH
+0xD9C0	0x68B4	#CJK UNIFIED IDEOGRAPH
+0xD9C1	0x6911	#CJK UNIFIED IDEOGRAPH
+0xD9C2	0x68EF	#CJK UNIFIED IDEOGRAPH
+0xD9C3	0x68C6	#CJK UNIFIED IDEOGRAPH
+0xD9C4	0x6914	#CJK UNIFIED IDEOGRAPH
+0xD9C5	0x68F8	#CJK UNIFIED IDEOGRAPH
+0xD9C6	0x68D0	#CJK UNIFIED IDEOGRAPH
+0xD9C7	0x68FD	#CJK UNIFIED IDEOGRAPH
+0xD9C8	0x68FC	#CJK UNIFIED IDEOGRAPH
+0xD9C9	0x68E8	#CJK UNIFIED IDEOGRAPH
+0xD9CA	0x690B	#CJK UNIFIED IDEOGRAPH
+0xD9CB	0x690A	#CJK UNIFIED IDEOGRAPH
+0xD9CC	0x6917	#CJK UNIFIED IDEOGRAPH
+0xD9CD	0x68CE	#CJK UNIFIED IDEOGRAPH
+0xD9CE	0x68C8	#CJK UNIFIED IDEOGRAPH
+0xD9CF	0x68DD	#CJK UNIFIED IDEOGRAPH
+0xD9D0	0x68DE	#CJK UNIFIED IDEOGRAPH
+0xD9D1	0x68E6	#CJK UNIFIED IDEOGRAPH
+0xD9D2	0x68F4	#CJK UNIFIED IDEOGRAPH
+0xD9D3	0x68D1	#CJK UNIFIED IDEOGRAPH
+0xD9D4	0x6906	#CJK UNIFIED IDEOGRAPH
+0xD9D5	0x68D4	#CJK UNIFIED IDEOGRAPH
+0xD9D6	0x68E9	#CJK UNIFIED IDEOGRAPH
+0xD9D7	0x6915	#CJK UNIFIED IDEOGRAPH
+0xD9D8	0x6925	#CJK UNIFIED IDEOGRAPH
+0xD9D9	0x68C7	#CJK UNIFIED IDEOGRAPH
+0xD9DA	0x6B39	#CJK UNIFIED IDEOGRAPH
+0xD9DB	0x6B3B	#CJK UNIFIED IDEOGRAPH
+0xD9DC	0x6B3F	#CJK UNIFIED IDEOGRAPH
+0xD9DD	0x6B3C	#CJK UNIFIED IDEOGRAPH
+0xD9DE	0x6B94	#CJK UNIFIED IDEOGRAPH
+0xD9DF	0x6B97	#CJK UNIFIED IDEOGRAPH
+0xD9E0	0x6B99	#CJK UNIFIED IDEOGRAPH
+0xD9E1	0x6B95	#CJK UNIFIED IDEOGRAPH
+0xD9E2	0x6BBD	#CJK UNIFIED IDEOGRAPH
+0xD9E3	0x6BF0	#CJK UNIFIED IDEOGRAPH
+0xD9E4	0x6BF2	#CJK UNIFIED IDEOGRAPH
+0xD9E5	0x6BF3	#CJK UNIFIED IDEOGRAPH
+0xD9E6	0x6C30	#CJK UNIFIED IDEOGRAPH
+0xD9E7	0x6DFC	#CJK UNIFIED IDEOGRAPH
+0xD9E8	0x6E46	#CJK UNIFIED IDEOGRAPH
+0xD9E9	0x6E47	#CJK UNIFIED IDEOGRAPH
+0xD9EA	0x6E1F	#CJK UNIFIED IDEOGRAPH
+0xD9EB	0x6E49	#CJK UNIFIED IDEOGRAPH
+0xD9EC	0x6E88	#CJK UNIFIED IDEOGRAPH
+0xD9ED	0x6E3C	#CJK UNIFIED IDEOGRAPH
+0xD9EE	0x6E3D	#CJK UNIFIED IDEOGRAPH
+0xD9EF	0x6E45	#CJK UNIFIED IDEOGRAPH
+0xD9F0	0x6E62	#CJK UNIFIED IDEOGRAPH
+0xD9F1	0x6E2B	#CJK UNIFIED IDEOGRAPH
+0xD9F2	0x6E3F	#CJK UNIFIED IDEOGRAPH
+0xD9F3	0x6E41	#CJK UNIFIED IDEOGRAPH
+0xD9F4	0x6E5D	#CJK UNIFIED IDEOGRAPH
+0xD9F5	0x6E73	#CJK UNIFIED IDEOGRAPH
+0xD9F6	0x6E1C	#CJK UNIFIED IDEOGRAPH
+0xD9F7	0x6E33	#CJK UNIFIED IDEOGRAPH
+0xD9F8	0x6E4B	#CJK UNIFIED IDEOGRAPH
+0xD9F9	0x6E40	#CJK UNIFIED IDEOGRAPH
+0xD9FA	0x6E51	#CJK UNIFIED IDEOGRAPH
+0xD9FB	0x6E3B	#CJK UNIFIED IDEOGRAPH
+0xD9FC	0x6E03	#CJK UNIFIED IDEOGRAPH
+0xD9FD	0x6E2E	#CJK UNIFIED IDEOGRAPH
+0xD9FE	0x6E5E	#CJK UNIFIED IDEOGRAPH
+0xDA40	0x6E68	#CJK UNIFIED IDEOGRAPH
+0xDA41	0x6E5C	#CJK UNIFIED IDEOGRAPH
+0xDA42	0x6E61	#CJK UNIFIED IDEOGRAPH
+0xDA43	0x6E31	#CJK UNIFIED IDEOGRAPH
+0xDA44	0x6E28	#CJK UNIFIED IDEOGRAPH
+0xDA45	0x6E60	#CJK UNIFIED IDEOGRAPH
+0xDA46	0x6E71	#CJK UNIFIED IDEOGRAPH
+0xDA47	0x6E6B	#CJK UNIFIED IDEOGRAPH
+0xDA48	0x6E39	#CJK UNIFIED IDEOGRAPH
+0xDA49	0x6E22	#CJK UNIFIED IDEOGRAPH
+0xDA4A	0x6E30	#CJK UNIFIED IDEOGRAPH
+0xDA4B	0x6E53	#CJK UNIFIED IDEOGRAPH
+0xDA4C	0x6E65	#CJK UNIFIED IDEOGRAPH
+0xDA4D	0x6E27	#CJK UNIFIED IDEOGRAPH
+0xDA4E	0x6E78	#CJK UNIFIED IDEOGRAPH
+0xDA4F	0x6E64	#CJK UNIFIED IDEOGRAPH
+0xDA50	0x6E77	#CJK UNIFIED IDEOGRAPH
+0xDA51	0x6E55	#CJK UNIFIED IDEOGRAPH
+0xDA52	0x6E79	#CJK UNIFIED IDEOGRAPH
+0xDA53	0x6E52	#CJK UNIFIED IDEOGRAPH
+0xDA54	0x6E66	#CJK UNIFIED IDEOGRAPH
+0xDA55	0x6E35	#CJK UNIFIED IDEOGRAPH
+0xDA56	0x6E36	#CJK UNIFIED IDEOGRAPH
+0xDA57	0x6E5A	#CJK UNIFIED IDEOGRAPH
+0xDA58	0x7120	#CJK UNIFIED IDEOGRAPH
+0xDA59	0x711E	#CJK UNIFIED IDEOGRAPH
+0xDA5A	0x712F	#CJK UNIFIED IDEOGRAPH
+0xDA5B	0x70FB	#CJK UNIFIED IDEOGRAPH
+0xDA5C	0x712E	#CJK UNIFIED IDEOGRAPH
+0xDA5D	0x7131	#CJK UNIFIED IDEOGRAPH
+0xDA5E	0x7123	#CJK UNIFIED IDEOGRAPH
+0xDA5F	0x7125	#CJK UNIFIED IDEOGRAPH
+0xDA60	0x7122	#CJK UNIFIED IDEOGRAPH
+0xDA61	0x7132	#CJK UNIFIED IDEOGRAPH
+0xDA62	0x711F	#CJK UNIFIED IDEOGRAPH
+0xDA63	0x7128	#CJK UNIFIED IDEOGRAPH
+0xDA64	0x713A	#CJK UNIFIED IDEOGRAPH
+0xDA65	0x711B	#CJK UNIFIED IDEOGRAPH
+0xDA66	0x724B	#CJK UNIFIED IDEOGRAPH
+0xDA67	0x725A	#CJK UNIFIED IDEOGRAPH
+0xDA68	0x7288	#CJK UNIFIED IDEOGRAPH
+0xDA69	0x7289	#CJK UNIFIED IDEOGRAPH
+0xDA6A	0x7286	#CJK UNIFIED IDEOGRAPH
+0xDA6B	0x7285	#CJK UNIFIED IDEOGRAPH
+0xDA6C	0x728B	#CJK UNIFIED IDEOGRAPH
+0xDA6D	0x7312	#CJK UNIFIED IDEOGRAPH
+0xDA6E	0x730B	#CJK UNIFIED IDEOGRAPH
+0xDA6F	0x7330	#CJK UNIFIED IDEOGRAPH
+0xDA70	0x7322	#CJK UNIFIED IDEOGRAPH
+0xDA71	0x7331	#CJK UNIFIED IDEOGRAPH
+0xDA72	0x7333	#CJK UNIFIED IDEOGRAPH
+0xDA73	0x7327	#CJK UNIFIED IDEOGRAPH
+0xDA74	0x7332	#CJK UNIFIED IDEOGRAPH
+0xDA75	0x732D	#CJK UNIFIED IDEOGRAPH
+0xDA76	0x7326	#CJK UNIFIED IDEOGRAPH
+0xDA77	0x7323	#CJK UNIFIED IDEOGRAPH
+0xDA78	0x7335	#CJK UNIFIED IDEOGRAPH
+0xDA79	0x730C	#CJK UNIFIED IDEOGRAPH
+0xDA7A	0x742E	#CJK UNIFIED IDEOGRAPH
+0xDA7B	0x742C	#CJK UNIFIED IDEOGRAPH
+0xDA7C	0x7430	#CJK UNIFIED IDEOGRAPH
+0xDA7D	0x742B	#CJK UNIFIED IDEOGRAPH
+0xDA7E	0x7416	#CJK UNIFIED IDEOGRAPH
+0xDAA1	0x741A	#CJK UNIFIED IDEOGRAPH
+0xDAA2	0x7421	#CJK UNIFIED IDEOGRAPH
+0xDAA3	0x742D	#CJK UNIFIED IDEOGRAPH
+0xDAA4	0x7431	#CJK UNIFIED IDEOGRAPH
+0xDAA5	0x7424	#CJK UNIFIED IDEOGRAPH
+0xDAA6	0x7423	#CJK UNIFIED IDEOGRAPH
+0xDAA7	0x741D	#CJK UNIFIED IDEOGRAPH
+0xDAA8	0x7429	#CJK UNIFIED IDEOGRAPH
+0xDAA9	0x7420	#CJK UNIFIED IDEOGRAPH
+0xDAAA	0x7432	#CJK UNIFIED IDEOGRAPH
+0xDAAB	0x74FB	#CJK UNIFIED IDEOGRAPH
+0xDAAC	0x752F	#CJK UNIFIED IDEOGRAPH
+0xDAAD	0x756F	#CJK UNIFIED IDEOGRAPH
+0xDAAE	0x756C	#CJK UNIFIED IDEOGRAPH
+0xDAAF	0x75E7	#CJK UNIFIED IDEOGRAPH
+0xDAB0	0x75DA	#CJK UNIFIED IDEOGRAPH
+0xDAB1	0x75E1	#CJK UNIFIED IDEOGRAPH
+0xDAB2	0x75E6	#CJK UNIFIED IDEOGRAPH
+0xDAB3	0x75DD	#CJK UNIFIED IDEOGRAPH
+0xDAB4	0x75DF	#CJK UNIFIED IDEOGRAPH
+0xDAB5	0x75E4	#CJK UNIFIED IDEOGRAPH
+0xDAB6	0x75D7	#CJK UNIFIED IDEOGRAPH
+0xDAB7	0x7695	#CJK UNIFIED IDEOGRAPH
+0xDAB8	0x7692	#CJK UNIFIED IDEOGRAPH
+0xDAB9	0x76DA	#CJK UNIFIED IDEOGRAPH
+0xDABA	0x7746	#CJK UNIFIED IDEOGRAPH
+0xDABB	0x7747	#CJK UNIFIED IDEOGRAPH
+0xDABC	0x7744	#CJK UNIFIED IDEOGRAPH
+0xDABD	0x774D	#CJK UNIFIED IDEOGRAPH
+0xDABE	0x7745	#CJK UNIFIED IDEOGRAPH
+0xDABF	0x774A	#CJK UNIFIED IDEOGRAPH
+0xDAC0	0x774E	#CJK UNIFIED IDEOGRAPH
+0xDAC1	0x774B	#CJK UNIFIED IDEOGRAPH
+0xDAC2	0x774C	#CJK UNIFIED IDEOGRAPH
+0xDAC3	0x77DE	#CJK UNIFIED IDEOGRAPH
+0xDAC4	0x77EC	#CJK UNIFIED IDEOGRAPH
+0xDAC5	0x7860	#CJK UNIFIED IDEOGRAPH
+0xDAC6	0x7864	#CJK UNIFIED IDEOGRAPH
+0xDAC7	0x7865	#CJK UNIFIED IDEOGRAPH
+0xDAC8	0x785C	#CJK UNIFIED IDEOGRAPH
+0xDAC9	0x786D	#CJK UNIFIED IDEOGRAPH
+0xDACA	0x7871	#CJK UNIFIED IDEOGRAPH
+0xDACB	0x786A	#CJK UNIFIED IDEOGRAPH
+0xDACC	0x786E	#CJK UNIFIED IDEOGRAPH
+0xDACD	0x7870	#CJK UNIFIED IDEOGRAPH
+0xDACE	0x7869	#CJK UNIFIED IDEOGRAPH
+0xDACF	0x7868	#CJK UNIFIED IDEOGRAPH
+0xDAD0	0x785E	#CJK UNIFIED IDEOGRAPH
+0xDAD1	0x7862	#CJK UNIFIED IDEOGRAPH
+0xDAD2	0x7974	#CJK UNIFIED IDEOGRAPH
+0xDAD3	0x7973	#CJK UNIFIED IDEOGRAPH
+0xDAD4	0x7972	#CJK UNIFIED IDEOGRAPH
+0xDAD5	0x7970	#CJK UNIFIED IDEOGRAPH
+0xDAD6	0x7A02	#CJK UNIFIED IDEOGRAPH
+0xDAD7	0x7A0A	#CJK UNIFIED IDEOGRAPH
+0xDAD8	0x7A03	#CJK UNIFIED IDEOGRAPH
+0xDAD9	0x7A0C	#CJK UNIFIED IDEOGRAPH
+0xDADA	0x7A04	#CJK UNIFIED IDEOGRAPH
+0xDADB	0x7A99	#CJK UNIFIED IDEOGRAPH
+0xDADC	0x7AE6	#CJK UNIFIED IDEOGRAPH
+0xDADD	0x7AE4	#CJK UNIFIED IDEOGRAPH
+0xDADE	0x7B4A	#CJK UNIFIED IDEOGRAPH
+0xDADF	0x7B3B	#CJK UNIFIED IDEOGRAPH
+0xDAE0	0x7B44	#CJK UNIFIED IDEOGRAPH
+0xDAE1	0x7B48	#CJK UNIFIED IDEOGRAPH
+0xDAE2	0x7B4C	#CJK UNIFIED IDEOGRAPH
+0xDAE3	0x7B4E	#CJK UNIFIED IDEOGRAPH
+0xDAE4	0x7B40	#CJK UNIFIED IDEOGRAPH
+0xDAE5	0x7B58	#CJK UNIFIED IDEOGRAPH
+0xDAE6	0x7B45	#CJK UNIFIED IDEOGRAPH
+0xDAE7	0x7CA2	#CJK UNIFIED IDEOGRAPH
+0xDAE8	0x7C9E	#CJK UNIFIED IDEOGRAPH
+0xDAE9	0x7CA8	#CJK UNIFIED IDEOGRAPH
+0xDAEA	0x7CA1	#CJK UNIFIED IDEOGRAPH
+0xDAEB	0x7D58	#CJK UNIFIED IDEOGRAPH
+0xDAEC	0x7D6F	#CJK UNIFIED IDEOGRAPH
+0xDAED	0x7D63	#CJK UNIFIED IDEOGRAPH
+0xDAEE	0x7D53	#CJK UNIFIED IDEOGRAPH
+0xDAEF	0x7D56	#CJK UNIFIED IDEOGRAPH
+0xDAF0	0x7D67	#CJK UNIFIED IDEOGRAPH
+0xDAF1	0x7D6A	#CJK UNIFIED IDEOGRAPH
+0xDAF2	0x7D4F	#CJK UNIFIED IDEOGRAPH
+0xDAF3	0x7D6D	#CJK UNIFIED IDEOGRAPH
+0xDAF4	0x7D5C	#CJK UNIFIED IDEOGRAPH
+0xDAF5	0x7D6B	#CJK UNIFIED IDEOGRAPH
+0xDAF6	0x7D52	#CJK UNIFIED IDEOGRAPH
+0xDAF7	0x7D54	#CJK UNIFIED IDEOGRAPH
+0xDAF8	0x7D69	#CJK UNIFIED IDEOGRAPH
+0xDAF9	0x7D51	#CJK UNIFIED IDEOGRAPH
+0xDAFA	0x7D5F	#CJK UNIFIED IDEOGRAPH
+0xDAFB	0x7D4E	#CJK UNIFIED IDEOGRAPH
+0xDAFC	0x7F3E	#CJK UNIFIED IDEOGRAPH
+0xDAFD	0x7F3F	#CJK UNIFIED IDEOGRAPH
+0xDAFE	0x7F65	#CJK UNIFIED IDEOGRAPH
+0xDB40	0x7F66	#CJK UNIFIED IDEOGRAPH
+0xDB41	0x7FA2	#CJK UNIFIED IDEOGRAPH
+0xDB42	0x7FA0	#CJK UNIFIED IDEOGRAPH
+0xDB43	0x7FA1	#CJK UNIFIED IDEOGRAPH
+0xDB44	0x7FD7	#CJK UNIFIED IDEOGRAPH
+0xDB45	0x8051	#CJK UNIFIED IDEOGRAPH
+0xDB46	0x804F	#CJK UNIFIED IDEOGRAPH
+0xDB47	0x8050	#CJK UNIFIED IDEOGRAPH
+0xDB48	0x80FE	#CJK UNIFIED IDEOGRAPH
+0xDB49	0x80D4	#CJK UNIFIED IDEOGRAPH
+0xDB4A	0x8143	#CJK UNIFIED IDEOGRAPH
+0xDB4B	0x814A	#CJK UNIFIED IDEOGRAPH
+0xDB4C	0x8152	#CJK UNIFIED IDEOGRAPH
+0xDB4D	0x814F	#CJK UNIFIED IDEOGRAPH
+0xDB4E	0x8147	#CJK UNIFIED IDEOGRAPH
+0xDB4F	0x813D	#CJK UNIFIED IDEOGRAPH
+0xDB50	0x814D	#CJK UNIFIED IDEOGRAPH
+0xDB51	0x813A	#CJK UNIFIED IDEOGRAPH
+0xDB52	0x81E6	#CJK UNIFIED IDEOGRAPH
+0xDB53	0x81EE	#CJK UNIFIED IDEOGRAPH
+0xDB54	0x81F7	#CJK UNIFIED IDEOGRAPH
+0xDB55	0x81F8	#CJK UNIFIED IDEOGRAPH
+0xDB56	0x81F9	#CJK UNIFIED IDEOGRAPH
+0xDB57	0x8204	#CJK UNIFIED IDEOGRAPH
+0xDB58	0x823C	#CJK UNIFIED IDEOGRAPH
+0xDB59	0x823D	#CJK UNIFIED IDEOGRAPH
+0xDB5A	0x823F	#CJK UNIFIED IDEOGRAPH
+0xDB5B	0x8275	#CJK UNIFIED IDEOGRAPH
+0xDB5C	0x833B	#CJK UNIFIED IDEOGRAPH
+0xDB5D	0x83CF	#CJK UNIFIED IDEOGRAPH
+0xDB5E	0x83F9	#CJK UNIFIED IDEOGRAPH
+0xDB5F	0x8423	#CJK UNIFIED IDEOGRAPH
+0xDB60	0x83C0	#CJK UNIFIED IDEOGRAPH
+0xDB61	0x83E8	#CJK UNIFIED IDEOGRAPH
+0xDB62	0x8412	#CJK UNIFIED IDEOGRAPH
+0xDB63	0x83E7	#CJK UNIFIED IDEOGRAPH
+0xDB64	0x83E4	#CJK UNIFIED IDEOGRAPH
+0xDB65	0x83FC	#CJK UNIFIED IDEOGRAPH
+0xDB66	0x83F6	#CJK UNIFIED IDEOGRAPH
+0xDB67	0x8410	#CJK UNIFIED IDEOGRAPH
+0xDB68	0x83C6	#CJK UNIFIED IDEOGRAPH
+0xDB69	0x83C8	#CJK UNIFIED IDEOGRAPH
+0xDB6A	0x83EB	#CJK UNIFIED IDEOGRAPH
+0xDB6B	0x83E3	#CJK UNIFIED IDEOGRAPH
+0xDB6C	0x83BF	#CJK UNIFIED IDEOGRAPH
+0xDB6D	0x8401	#CJK UNIFIED IDEOGRAPH
+0xDB6E	0x83DD	#CJK UNIFIED IDEOGRAPH
+0xDB6F	0x83E5	#CJK UNIFIED IDEOGRAPH
+0xDB70	0x83D8	#CJK UNIFIED IDEOGRAPH
+0xDB71	0x83FF	#CJK UNIFIED IDEOGRAPH
+0xDB72	0x83E1	#CJK UNIFIED IDEOGRAPH
+0xDB73	0x83CB	#CJK UNIFIED IDEOGRAPH
+0xDB74	0x83CE	#CJK UNIFIED IDEOGRAPH
+0xDB75	0x83D6	#CJK UNIFIED IDEOGRAPH
+0xDB76	0x83F5	#CJK UNIFIED IDEOGRAPH
+0xDB77	0x83C9	#CJK UNIFIED IDEOGRAPH
+0xDB78	0x8409	#CJK UNIFIED IDEOGRAPH
+0xDB79	0x840F	#CJK UNIFIED IDEOGRAPH
+0xDB7A	0x83DE	#CJK UNIFIED IDEOGRAPH
+0xDB7B	0x8411	#CJK UNIFIED IDEOGRAPH
+0xDB7C	0x8406	#CJK UNIFIED IDEOGRAPH
+0xDB7D	0x83C2	#CJK UNIFIED IDEOGRAPH
+0xDB7E	0x83F3	#CJK UNIFIED IDEOGRAPH
+0xDBA1	0x83D5	#CJK UNIFIED IDEOGRAPH
+0xDBA2	0x83FA	#CJK UNIFIED IDEOGRAPH
+0xDBA3	0x83C7	#CJK UNIFIED IDEOGRAPH
+0xDBA4	0x83D1	#CJK UNIFIED IDEOGRAPH
+0xDBA5	0x83EA	#CJK UNIFIED IDEOGRAPH
+0xDBA6	0x8413	#CJK UNIFIED IDEOGRAPH
+0xDBA7	0x83C3	#CJK UNIFIED IDEOGRAPH
+0xDBA8	0x83EC	#CJK UNIFIED IDEOGRAPH
+0xDBA9	0x83EE	#CJK UNIFIED IDEOGRAPH
+0xDBAA	0x83C4	#CJK UNIFIED IDEOGRAPH
+0xDBAB	0x83FB	#CJK UNIFIED IDEOGRAPH
+0xDBAC	0x83D7	#CJK UNIFIED IDEOGRAPH
+0xDBAD	0x83E2	#CJK UNIFIED IDEOGRAPH
+0xDBAE	0x841B	#CJK UNIFIED IDEOGRAPH
+0xDBAF	0x83DB	#CJK UNIFIED IDEOGRAPH
+0xDBB0	0x83FE	#CJK UNIFIED IDEOGRAPH
+0xDBB1	0x86D8	#CJK UNIFIED IDEOGRAPH
+0xDBB2	0x86E2	#CJK UNIFIED IDEOGRAPH
+0xDBB3	0x86E6	#CJK UNIFIED IDEOGRAPH
+0xDBB4	0x86D3	#CJK UNIFIED IDEOGRAPH
+0xDBB5	0x86E3	#CJK UNIFIED IDEOGRAPH
+0xDBB6	0x86DA	#CJK UNIFIED IDEOGRAPH
+0xDBB7	0x86EA	#CJK UNIFIED IDEOGRAPH
+0xDBB8	0x86DD	#CJK UNIFIED IDEOGRAPH
+0xDBB9	0x86EB	#CJK UNIFIED IDEOGRAPH
+0xDBBA	0x86DC	#CJK UNIFIED IDEOGRAPH
+0xDBBB	0x86EC	#CJK UNIFIED IDEOGRAPH
+0xDBBC	0x86E9	#CJK UNIFIED IDEOGRAPH
+0xDBBD	0x86D7	#CJK UNIFIED IDEOGRAPH
+0xDBBE	0x86E8	#CJK UNIFIED IDEOGRAPH
+0xDBBF	0x86D1	#CJK UNIFIED IDEOGRAPH
+0xDBC0	0x8848	#CJK UNIFIED IDEOGRAPH
+0xDBC1	0x8856	#CJK UNIFIED IDEOGRAPH
+0xDBC2	0x8855	#CJK UNIFIED IDEOGRAPH
+0xDBC3	0x88BA	#CJK UNIFIED IDEOGRAPH
+0xDBC4	0x88D7	#CJK UNIFIED IDEOGRAPH
+0xDBC5	0x88B9	#CJK UNIFIED IDEOGRAPH
+0xDBC6	0x88B8	#CJK UNIFIED IDEOGRAPH
+0xDBC7	0x88C0	#CJK UNIFIED IDEOGRAPH
+0xDBC8	0x88BE	#CJK UNIFIED IDEOGRAPH
+0xDBC9	0x88B6	#CJK UNIFIED IDEOGRAPH
+0xDBCA	0x88BC	#CJK UNIFIED IDEOGRAPH
+0xDBCB	0x88B7	#CJK UNIFIED IDEOGRAPH
+0xDBCC	0x88BD	#CJK UNIFIED IDEOGRAPH
+0xDBCD	0x88B2	#CJK UNIFIED IDEOGRAPH
+0xDBCE	0x8901	#CJK UNIFIED IDEOGRAPH
+0xDBCF	0x88C9	#CJK UNIFIED IDEOGRAPH
+0xDBD0	0x8995	#CJK UNIFIED IDEOGRAPH
+0xDBD1	0x8998	#CJK UNIFIED IDEOGRAPH
+0xDBD2	0x8997	#CJK UNIFIED IDEOGRAPH
+0xDBD3	0x89DD	#CJK UNIFIED IDEOGRAPH
+0xDBD4	0x89DA	#CJK UNIFIED IDEOGRAPH
+0xDBD5	0x89DB	#CJK UNIFIED IDEOGRAPH
+0xDBD6	0x8A4E	#CJK UNIFIED IDEOGRAPH
+0xDBD7	0x8A4D	#CJK UNIFIED IDEOGRAPH
+0xDBD8	0x8A39	#CJK UNIFIED IDEOGRAPH
+0xDBD9	0x8A59	#CJK UNIFIED IDEOGRAPH
+0xDBDA	0x8A40	#CJK UNIFIED IDEOGRAPH
+0xDBDB	0x8A57	#CJK UNIFIED IDEOGRAPH
+0xDBDC	0x8A58	#CJK UNIFIED IDEOGRAPH
+0xDBDD	0x8A44	#CJK UNIFIED IDEOGRAPH
+0xDBDE	0x8A45	#CJK UNIFIED IDEOGRAPH
+0xDBDF	0x8A52	#CJK UNIFIED IDEOGRAPH
+0xDBE0	0x8A48	#CJK UNIFIED IDEOGRAPH
+0xDBE1	0x8A51	#CJK UNIFIED IDEOGRAPH
+0xDBE2	0x8A4A	#CJK UNIFIED IDEOGRAPH
+0xDBE3	0x8A4C	#CJK UNIFIED IDEOGRAPH
+0xDBE4	0x8A4F	#CJK UNIFIED IDEOGRAPH
+0xDBE5	0x8C5F	#CJK UNIFIED IDEOGRAPH
+0xDBE6	0x8C81	#CJK UNIFIED IDEOGRAPH
+0xDBE7	0x8C80	#CJK UNIFIED IDEOGRAPH
+0xDBE8	0x8CBA	#CJK UNIFIED IDEOGRAPH
+0xDBE9	0x8CBE	#CJK UNIFIED IDEOGRAPH
+0xDBEA	0x8CB0	#CJK UNIFIED IDEOGRAPH
+0xDBEB	0x8CB9	#CJK UNIFIED IDEOGRAPH
+0xDBEC	0x8CB5	#CJK UNIFIED IDEOGRAPH
+0xDBED	0x8D84	#CJK UNIFIED IDEOGRAPH
+0xDBEE	0x8D80	#CJK UNIFIED IDEOGRAPH
+0xDBEF	0x8D89	#CJK UNIFIED IDEOGRAPH
+0xDBF0	0x8DD8	#CJK UNIFIED IDEOGRAPH
+0xDBF1	0x8DD3	#CJK UNIFIED IDEOGRAPH
+0xDBF2	0x8DCD	#CJK UNIFIED IDEOGRAPH
+0xDBF3	0x8DC7	#CJK UNIFIED IDEOGRAPH
+0xDBF4	0x8DD6	#CJK UNIFIED IDEOGRAPH
+0xDBF5	0x8DDC	#CJK UNIFIED IDEOGRAPH
+0xDBF6	0x8DCF	#CJK UNIFIED IDEOGRAPH
+0xDBF7	0x8DD5	#CJK UNIFIED IDEOGRAPH
+0xDBF8	0x8DD9	#CJK UNIFIED IDEOGRAPH
+0xDBF9	0x8DC8	#CJK UNIFIED IDEOGRAPH
+0xDBFA	0x8DD7	#CJK UNIFIED IDEOGRAPH
+0xDBFB	0x8DC5	#CJK UNIFIED IDEOGRAPH
+0xDBFC	0x8EEF	#CJK UNIFIED IDEOGRAPH
+0xDBFD	0x8EF7	#CJK UNIFIED IDEOGRAPH
+0xDBFE	0x8EFA	#CJK UNIFIED IDEOGRAPH
+0xDC40	0x8EF9	#CJK UNIFIED IDEOGRAPH
+0xDC41	0x8EE6	#CJK UNIFIED IDEOGRAPH
+0xDC42	0x8EEE	#CJK UNIFIED IDEOGRAPH
+0xDC43	0x8EE5	#CJK UNIFIED IDEOGRAPH
+0xDC44	0x8EF5	#CJK UNIFIED IDEOGRAPH
+0xDC45	0x8EE7	#CJK UNIFIED IDEOGRAPH
+0xDC46	0x8EE8	#CJK UNIFIED IDEOGRAPH
+0xDC47	0x8EF6	#CJK UNIFIED IDEOGRAPH
+0xDC48	0x8EEB	#CJK UNIFIED IDEOGRAPH
+0xDC49	0x8EF1	#CJK UNIFIED IDEOGRAPH
+0xDC4A	0x8EEC	#CJK UNIFIED IDEOGRAPH
+0xDC4B	0x8EF4	#CJK UNIFIED IDEOGRAPH
+0xDC4C	0x8EE9	#CJK UNIFIED IDEOGRAPH
+0xDC4D	0x902D	#CJK UNIFIED IDEOGRAPH
+0xDC4E	0x9034	#CJK UNIFIED IDEOGRAPH
+0xDC4F	0x902F	#CJK UNIFIED IDEOGRAPH
+0xDC50	0x9106	#CJK UNIFIED IDEOGRAPH
+0xDC51	0x912C	#CJK UNIFIED IDEOGRAPH
+0xDC52	0x9104	#CJK UNIFIED IDEOGRAPH
+0xDC53	0x90FF	#CJK UNIFIED IDEOGRAPH
+0xDC54	0x90FC	#CJK UNIFIED IDEOGRAPH
+0xDC55	0x9108	#CJK UNIFIED IDEOGRAPH
+0xDC56	0x90F9	#CJK UNIFIED IDEOGRAPH
+0xDC57	0x90FB	#CJK UNIFIED IDEOGRAPH
+0xDC58	0x9101	#CJK UNIFIED IDEOGRAPH
+0xDC59	0x9100	#CJK UNIFIED IDEOGRAPH
+0xDC5A	0x9107	#CJK UNIFIED IDEOGRAPH
+0xDC5B	0x9105	#CJK UNIFIED IDEOGRAPH
+0xDC5C	0x9103	#CJK UNIFIED IDEOGRAPH
+0xDC5D	0x9161	#CJK UNIFIED IDEOGRAPH
+0xDC5E	0x9164	#CJK UNIFIED IDEOGRAPH
+0xDC5F	0x915F	#CJK UNIFIED IDEOGRAPH
+0xDC60	0x9162	#CJK UNIFIED IDEOGRAPH
+0xDC61	0x9160	#CJK UNIFIED IDEOGRAPH
+0xDC62	0x9201	#CJK UNIFIED IDEOGRAPH
+0xDC63	0x920A	#CJK UNIFIED IDEOGRAPH
+0xDC64	0x9225	#CJK UNIFIED IDEOGRAPH
+0xDC65	0x9203	#CJK UNIFIED IDEOGRAPH
+0xDC66	0x921A	#CJK UNIFIED IDEOGRAPH
+0xDC67	0x9226	#CJK UNIFIED IDEOGRAPH
+0xDC68	0x920F	#CJK UNIFIED IDEOGRAPH
+0xDC69	0x920C	#CJK UNIFIED IDEOGRAPH
+0xDC6A	0x9200	#CJK UNIFIED IDEOGRAPH
+0xDC6B	0x9212	#CJK UNIFIED IDEOGRAPH
+0xDC6C	0x91FF	#CJK UNIFIED IDEOGRAPH
+0xDC6D	0x91FD	#CJK UNIFIED IDEOGRAPH
+0xDC6E	0x9206	#CJK UNIFIED IDEOGRAPH
+0xDC6F	0x9204	#CJK UNIFIED IDEOGRAPH
+0xDC70	0x9227	#CJK UNIFIED IDEOGRAPH
+0xDC71	0x9202	#CJK UNIFIED IDEOGRAPH
+0xDC72	0x921C	#CJK UNIFIED IDEOGRAPH
+0xDC73	0x9224	#CJK UNIFIED IDEOGRAPH
+0xDC74	0x9219	#CJK UNIFIED IDEOGRAPH
+0xDC75	0x9217	#CJK UNIFIED IDEOGRAPH
+0xDC76	0x9205	#CJK UNIFIED IDEOGRAPH
+0xDC77	0x9216	#CJK UNIFIED IDEOGRAPH
+0xDC78	0x957B	#CJK UNIFIED IDEOGRAPH
+0xDC79	0x958D	#CJK UNIFIED IDEOGRAPH
+0xDC7A	0x958C	#CJK UNIFIED IDEOGRAPH
+0xDC7B	0x9590	#CJK UNIFIED IDEOGRAPH
+0xDC7C	0x9687	#CJK UNIFIED IDEOGRAPH
+0xDC7D	0x967E	#CJK UNIFIED IDEOGRAPH
+0xDC7E	0x9688	#CJK UNIFIED IDEOGRAPH
+0xDCA1	0x9689	#CJK UNIFIED IDEOGRAPH
+0xDCA2	0x9683	#CJK UNIFIED IDEOGRAPH
+0xDCA3	0x9680	#CJK UNIFIED IDEOGRAPH
+0xDCA4	0x96C2	#CJK UNIFIED IDEOGRAPH
+0xDCA5	0x96C8	#CJK UNIFIED IDEOGRAPH
+0xDCA6	0x96C3	#CJK UNIFIED IDEOGRAPH
+0xDCA7	0x96F1	#CJK UNIFIED IDEOGRAPH
+0xDCA8	0x96F0	#CJK UNIFIED IDEOGRAPH
+0xDCA9	0x976C	#CJK UNIFIED IDEOGRAPH
+0xDCAA	0x9770	#CJK UNIFIED IDEOGRAPH
+0xDCAB	0x976E	#CJK UNIFIED IDEOGRAPH
+0xDCAC	0x9807	#CJK UNIFIED IDEOGRAPH
+0xDCAD	0x98A9	#CJK UNIFIED IDEOGRAPH
+0xDCAE	0x98EB	#CJK UNIFIED IDEOGRAPH
+0xDCAF	0x9CE6	#CJK UNIFIED IDEOGRAPH
+0xDCB0	0x9EF9	#CJK UNIFIED IDEOGRAPH
+0xDCB1	0x4E83	#CJK UNIFIED IDEOGRAPH
+0xDCB2	0x4E84	#CJK UNIFIED IDEOGRAPH
+0xDCB3	0x4EB6	#CJK UNIFIED IDEOGRAPH
+0xDCB4	0x50BD	#CJK UNIFIED IDEOGRAPH
+0xDCB5	0x50BF	#CJK UNIFIED IDEOGRAPH
+0xDCB6	0x50C6	#CJK UNIFIED IDEOGRAPH
+0xDCB7	0x50AE	#CJK UNIFIED IDEOGRAPH
+0xDCB8	0x50C4	#CJK UNIFIED IDEOGRAPH
+0xDCB9	0x50CA	#CJK UNIFIED IDEOGRAPH
+0xDCBA	0x50B4	#CJK UNIFIED IDEOGRAPH
+0xDCBB	0x50C8	#CJK UNIFIED IDEOGRAPH
+0xDCBC	0x50C2	#CJK UNIFIED IDEOGRAPH
+0xDCBD	0x50B0	#CJK UNIFIED IDEOGRAPH
+0xDCBE	0x50C1	#CJK UNIFIED IDEOGRAPH
+0xDCBF	0x50BA	#CJK UNIFIED IDEOGRAPH
+0xDCC0	0x50B1	#CJK UNIFIED IDEOGRAPH
+0xDCC1	0x50CB	#CJK UNIFIED IDEOGRAPH
+0xDCC2	0x50C9	#CJK UNIFIED IDEOGRAPH
+0xDCC3	0x50B6	#CJK UNIFIED IDEOGRAPH
+0xDCC4	0x50B8	#CJK UNIFIED IDEOGRAPH
+0xDCC5	0x51D7	#CJK UNIFIED IDEOGRAPH
+0xDCC6	0x527A	#CJK UNIFIED IDEOGRAPH
+0xDCC7	0x5278	#CJK UNIFIED IDEOGRAPH
+0xDCC8	0x527B	#CJK UNIFIED IDEOGRAPH
+0xDCC9	0x527C	#CJK UNIFIED IDEOGRAPH
+0xDCCA	0x55C3	#CJK UNIFIED IDEOGRAPH
+0xDCCB	0x55DB	#CJK UNIFIED IDEOGRAPH
+0xDCCC	0x55CC	#CJK UNIFIED IDEOGRAPH
+0xDCCD	0x55D0	#CJK UNIFIED IDEOGRAPH
+0xDCCE	0x55CB	#CJK UNIFIED IDEOGRAPH
+0xDCCF	0x55CA	#CJK UNIFIED IDEOGRAPH
+0xDCD0	0x55DD	#CJK UNIFIED IDEOGRAPH
+0xDCD1	0x55C0	#CJK UNIFIED IDEOGRAPH
+0xDCD2	0x55D4	#CJK UNIFIED IDEOGRAPH
+0xDCD3	0x55C4	#CJK UNIFIED IDEOGRAPH
+0xDCD4	0x55E9	#CJK UNIFIED IDEOGRAPH
+0xDCD5	0x55BF	#CJK UNIFIED IDEOGRAPH
+0xDCD6	0x55D2	#CJK UNIFIED IDEOGRAPH
+0xDCD7	0x558D	#CJK UNIFIED IDEOGRAPH
+0xDCD8	0x55CF	#CJK UNIFIED IDEOGRAPH
+0xDCD9	0x55D5	#CJK UNIFIED IDEOGRAPH
+0xDCDA	0x55E2	#CJK UNIFIED IDEOGRAPH
+0xDCDB	0x55D6	#CJK UNIFIED IDEOGRAPH
+0xDCDC	0x55C8	#CJK UNIFIED IDEOGRAPH
+0xDCDD	0x55F2	#CJK UNIFIED IDEOGRAPH
+0xDCDE	0x55CD	#CJK UNIFIED IDEOGRAPH
+0xDCDF	0x55D9	#CJK UNIFIED IDEOGRAPH
+0xDCE0	0x55C2	#CJK UNIFIED IDEOGRAPH
+0xDCE1	0x5714	#CJK UNIFIED IDEOGRAPH
+0xDCE2	0x5853	#CJK UNIFIED IDEOGRAPH
+0xDCE3	0x5868	#CJK UNIFIED IDEOGRAPH
+0xDCE4	0x5864	#CJK UNIFIED IDEOGRAPH
+0xDCE5	0x584F	#CJK UNIFIED IDEOGRAPH
+0xDCE6	0x584D	#CJK UNIFIED IDEOGRAPH
+0xDCE7	0x5849	#CJK UNIFIED IDEOGRAPH
+0xDCE8	0x586F	#CJK UNIFIED IDEOGRAPH
+0xDCE9	0x5855	#CJK UNIFIED IDEOGRAPH
+0xDCEA	0x584E	#CJK UNIFIED IDEOGRAPH
+0xDCEB	0x585D	#CJK UNIFIED IDEOGRAPH
+0xDCEC	0x5859	#CJK UNIFIED IDEOGRAPH
+0xDCED	0x5865	#CJK UNIFIED IDEOGRAPH
+0xDCEE	0x585B	#CJK UNIFIED IDEOGRAPH
+0xDCEF	0x583D	#CJK UNIFIED IDEOGRAPH
+0xDCF0	0x5863	#CJK UNIFIED IDEOGRAPH
+0xDCF1	0x5871	#CJK UNIFIED IDEOGRAPH
+0xDCF2	0x58FC	#CJK UNIFIED IDEOGRAPH
+0xDCF3	0x5AC7	#CJK UNIFIED IDEOGRAPH
+0xDCF4	0x5AC4	#CJK UNIFIED IDEOGRAPH
+0xDCF5	0x5ACB	#CJK UNIFIED IDEOGRAPH
+0xDCF6	0x5ABA	#CJK UNIFIED IDEOGRAPH
+0xDCF7	0x5AB8	#CJK UNIFIED IDEOGRAPH
+0xDCF8	0x5AB1	#CJK UNIFIED IDEOGRAPH
+0xDCF9	0x5AB5	#CJK UNIFIED IDEOGRAPH
+0xDCFA	0x5AB0	#CJK UNIFIED IDEOGRAPH
+0xDCFB	0x5ABF	#CJK UNIFIED IDEOGRAPH
+0xDCFC	0x5AC8	#CJK UNIFIED IDEOGRAPH
+0xDCFD	0x5ABB	#CJK UNIFIED IDEOGRAPH
+0xDCFE	0x5AC6	#CJK UNIFIED IDEOGRAPH
+0xDD40	0x5AB7	#CJK UNIFIED IDEOGRAPH
+0xDD41	0x5AC0	#CJK UNIFIED IDEOGRAPH
+0xDD42	0x5ACA	#CJK UNIFIED IDEOGRAPH
+0xDD43	0x5AB4	#CJK UNIFIED IDEOGRAPH
+0xDD44	0x5AB6	#CJK UNIFIED IDEOGRAPH
+0xDD45	0x5ACD	#CJK UNIFIED IDEOGRAPH
+0xDD46	0x5AB9	#CJK UNIFIED IDEOGRAPH
+0xDD47	0x5A90	#CJK UNIFIED IDEOGRAPH
+0xDD48	0x5BD6	#CJK UNIFIED IDEOGRAPH
+0xDD49	0x5BD8	#CJK UNIFIED IDEOGRAPH
+0xDD4A	0x5BD9	#CJK UNIFIED IDEOGRAPH
+0xDD4B	0x5C1F	#CJK UNIFIED IDEOGRAPH
+0xDD4C	0x5C33	#CJK UNIFIED IDEOGRAPH
+0xDD4D	0x5D71	#CJK UNIFIED IDEOGRAPH
+0xDD4E	0x5D63	#CJK UNIFIED IDEOGRAPH
+0xDD4F	0x5D4A	#CJK UNIFIED IDEOGRAPH
+0xDD50	0x5D65	#CJK UNIFIED IDEOGRAPH
+0xDD51	0x5D72	#CJK UNIFIED IDEOGRAPH
+0xDD52	0x5D6C	#CJK UNIFIED IDEOGRAPH
+0xDD53	0x5D5E	#CJK UNIFIED IDEOGRAPH
+0xDD54	0x5D68	#CJK UNIFIED IDEOGRAPH
+0xDD55	0x5D67	#CJK UNIFIED IDEOGRAPH
+0xDD56	0x5D62	#CJK UNIFIED IDEOGRAPH
+0xDD57	0x5DF0	#CJK UNIFIED IDEOGRAPH
+0xDD58	0x5E4F	#CJK UNIFIED IDEOGRAPH
+0xDD59	0x5E4E	#CJK UNIFIED IDEOGRAPH
+0xDD5A	0x5E4A	#CJK UNIFIED IDEOGRAPH
+0xDD5B	0x5E4D	#CJK UNIFIED IDEOGRAPH
+0xDD5C	0x5E4B	#CJK UNIFIED IDEOGRAPH
+0xDD5D	0x5EC5	#CJK UNIFIED IDEOGRAPH
+0xDD5E	0x5ECC	#CJK UNIFIED IDEOGRAPH
+0xDD5F	0x5EC6	#CJK UNIFIED IDEOGRAPH
+0xDD60	0x5ECB	#CJK UNIFIED IDEOGRAPH
+0xDD61	0x5EC7	#CJK UNIFIED IDEOGRAPH
+0xDD62	0x5F40	#CJK UNIFIED IDEOGRAPH
+0xDD63	0x5FAF	#CJK UNIFIED IDEOGRAPH
+0xDD64	0x5FAD	#CJK UNIFIED IDEOGRAPH
+0xDD65	0x60F7	#CJK UNIFIED IDEOGRAPH
+0xDD66	0x6149	#CJK UNIFIED IDEOGRAPH
+0xDD67	0x614A	#CJK UNIFIED IDEOGRAPH
+0xDD68	0x612B	#CJK UNIFIED IDEOGRAPH
+0xDD69	0x6145	#CJK UNIFIED IDEOGRAPH
+0xDD6A	0x6136	#CJK UNIFIED IDEOGRAPH
+0xDD6B	0x6132	#CJK UNIFIED IDEOGRAPH
+0xDD6C	0x612E	#CJK UNIFIED IDEOGRAPH
+0xDD6D	0x6146	#CJK UNIFIED IDEOGRAPH
+0xDD6E	0x612F	#CJK UNIFIED IDEOGRAPH
+0xDD6F	0x614F	#CJK UNIFIED IDEOGRAPH
+0xDD70	0x6129	#CJK UNIFIED IDEOGRAPH
+0xDD71	0x6140	#CJK UNIFIED IDEOGRAPH
+0xDD72	0x6220	#CJK UNIFIED IDEOGRAPH
+0xDD73	0x9168	#CJK UNIFIED IDEOGRAPH
+0xDD74	0x6223	#CJK UNIFIED IDEOGRAPH
+0xDD75	0x6225	#CJK UNIFIED IDEOGRAPH
+0xDD76	0x6224	#CJK UNIFIED IDEOGRAPH
+0xDD77	0x63C5	#CJK UNIFIED IDEOGRAPH
+0xDD78	0x63F1	#CJK UNIFIED IDEOGRAPH
+0xDD79	0x63EB	#CJK UNIFIED IDEOGRAPH
+0xDD7A	0x6410	#CJK UNIFIED IDEOGRAPH
+0xDD7B	0x6412	#CJK UNIFIED IDEOGRAPH
+0xDD7C	0x6409	#CJK UNIFIED IDEOGRAPH
+0xDD7D	0x6420	#CJK UNIFIED IDEOGRAPH
+0xDD7E	0x6424	#CJK UNIFIED IDEOGRAPH
+0xDDA1	0x6433	#CJK UNIFIED IDEOGRAPH
+0xDDA2	0x6443	#CJK UNIFIED IDEOGRAPH
+0xDDA3	0x641F	#CJK UNIFIED IDEOGRAPH
+0xDDA4	0x6415	#CJK UNIFIED IDEOGRAPH
+0xDDA5	0x6418	#CJK UNIFIED IDEOGRAPH
+0xDDA6	0x6439	#CJK UNIFIED IDEOGRAPH
+0xDDA7	0x6437	#CJK UNIFIED IDEOGRAPH
+0xDDA8	0x6422	#CJK UNIFIED IDEOGRAPH
+0xDDA9	0x6423	#CJK UNIFIED IDEOGRAPH
+0xDDAA	0x640C	#CJK UNIFIED IDEOGRAPH
+0xDDAB	0x6426	#CJK UNIFIED IDEOGRAPH
+0xDDAC	0x6430	#CJK UNIFIED IDEOGRAPH
+0xDDAD	0x6428	#CJK UNIFIED IDEOGRAPH
+0xDDAE	0x6441	#CJK UNIFIED IDEOGRAPH
+0xDDAF	0x6435	#CJK UNIFIED IDEOGRAPH
+0xDDB0	0x642F	#CJK UNIFIED IDEOGRAPH
+0xDDB1	0x640A	#CJK UNIFIED IDEOGRAPH
+0xDDB2	0x641A	#CJK UNIFIED IDEOGRAPH
+0xDDB3	0x6440	#CJK UNIFIED IDEOGRAPH
+0xDDB4	0x6425	#CJK UNIFIED IDEOGRAPH
+0xDDB5	0x6427	#CJK UNIFIED IDEOGRAPH
+0xDDB6	0x640B	#CJK UNIFIED IDEOGRAPH
+0xDDB7	0x63E7	#CJK UNIFIED IDEOGRAPH
+0xDDB8	0x641B	#CJK UNIFIED IDEOGRAPH
+0xDDB9	0x642E	#CJK UNIFIED IDEOGRAPH
+0xDDBA	0x6421	#CJK UNIFIED IDEOGRAPH
+0xDDBB	0x640E	#CJK UNIFIED IDEOGRAPH
+0xDDBC	0x656F	#CJK UNIFIED IDEOGRAPH
+0xDDBD	0x6592	#CJK UNIFIED IDEOGRAPH
+0xDDBE	0x65D3	#CJK UNIFIED IDEOGRAPH
+0xDDBF	0x6686	#CJK UNIFIED IDEOGRAPH
+0xDDC0	0x668C	#CJK UNIFIED IDEOGRAPH
+0xDDC1	0x6695	#CJK UNIFIED IDEOGRAPH
+0xDDC2	0x6690	#CJK UNIFIED IDEOGRAPH
+0xDDC3	0x668B	#CJK UNIFIED IDEOGRAPH
+0xDDC4	0x668A	#CJK UNIFIED IDEOGRAPH
+0xDDC5	0x6699	#CJK UNIFIED IDEOGRAPH
+0xDDC6	0x6694	#CJK UNIFIED IDEOGRAPH
+0xDDC7	0x6678	#CJK UNIFIED IDEOGRAPH
+0xDDC8	0x6720	#CJK UNIFIED IDEOGRAPH
+0xDDC9	0x6966	#CJK UNIFIED IDEOGRAPH
+0xDDCA	0x695F	#CJK UNIFIED IDEOGRAPH
+0xDDCB	0x6938	#CJK UNIFIED IDEOGRAPH
+0xDDCC	0x694E	#CJK UNIFIED IDEOGRAPH
+0xDDCD	0x6962	#CJK UNIFIED IDEOGRAPH
+0xDDCE	0x6971	#CJK UNIFIED IDEOGRAPH
+0xDDCF	0x693F	#CJK UNIFIED IDEOGRAPH
+0xDDD0	0x6945	#CJK UNIFIED IDEOGRAPH
+0xDDD1	0x696A	#CJK UNIFIED IDEOGRAPH
+0xDDD2	0x6939	#CJK UNIFIED IDEOGRAPH
+0xDDD3	0x6942	#CJK UNIFIED IDEOGRAPH
+0xDDD4	0x6957	#CJK UNIFIED IDEOGRAPH
+0xDDD5	0x6959	#CJK UNIFIED IDEOGRAPH
+0xDDD6	0x697A	#CJK UNIFIED IDEOGRAPH
+0xDDD7	0x6948	#CJK UNIFIED IDEOGRAPH
+0xDDD8	0x6949	#CJK UNIFIED IDEOGRAPH
+0xDDD9	0x6935	#CJK UNIFIED IDEOGRAPH
+0xDDDA	0x696C	#CJK UNIFIED IDEOGRAPH
+0xDDDB	0x6933	#CJK UNIFIED IDEOGRAPH
+0xDDDC	0x693D	#CJK UNIFIED IDEOGRAPH
+0xDDDD	0x6965	#CJK UNIFIED IDEOGRAPH
+0xDDDE	0x68F0	#CJK UNIFIED IDEOGRAPH
+0xDDDF	0x6978	#CJK UNIFIED IDEOGRAPH
+0xDDE0	0x6934	#CJK UNIFIED IDEOGRAPH
+0xDDE1	0x6969	#CJK UNIFIED IDEOGRAPH
+0xDDE2	0x6940	#CJK UNIFIED IDEOGRAPH
+0xDDE3	0x696F	#CJK UNIFIED IDEOGRAPH
+0xDDE4	0x6944	#CJK UNIFIED IDEOGRAPH
+0xDDE5	0x6976	#CJK UNIFIED IDEOGRAPH
+0xDDE6	0x6958	#CJK UNIFIED IDEOGRAPH
+0xDDE7	0x6941	#CJK UNIFIED IDEOGRAPH
+0xDDE8	0x6974	#CJK UNIFIED IDEOGRAPH
+0xDDE9	0x694C	#CJK UNIFIED IDEOGRAPH
+0xDDEA	0x693B	#CJK UNIFIED IDEOGRAPH
+0xDDEB	0x694B	#CJK UNIFIED IDEOGRAPH
+0xDDEC	0x6937	#CJK UNIFIED IDEOGRAPH
+0xDDED	0x695C	#CJK UNIFIED IDEOGRAPH
+0xDDEE	0x694F	#CJK UNIFIED IDEOGRAPH
+0xDDEF	0x6951	#CJK UNIFIED IDEOGRAPH
+0xDDF0	0x6932	#CJK UNIFIED IDEOGRAPH
+0xDDF1	0x6952	#CJK UNIFIED IDEOGRAPH
+0xDDF2	0x692F	#CJK UNIFIED IDEOGRAPH
+0xDDF3	0x697B	#CJK UNIFIED IDEOGRAPH
+0xDDF4	0x693C	#CJK UNIFIED IDEOGRAPH
+0xDDF5	0x6B46	#CJK UNIFIED IDEOGRAPH
+0xDDF6	0x6B45	#CJK UNIFIED IDEOGRAPH
+0xDDF7	0x6B43	#CJK UNIFIED IDEOGRAPH
+0xDDF8	0x6B42	#CJK UNIFIED IDEOGRAPH
+0xDDF9	0x6B48	#CJK UNIFIED IDEOGRAPH
+0xDDFA	0x6B41	#CJK UNIFIED IDEOGRAPH
+0xDDFB	0x6B9B	#CJK UNIFIED IDEOGRAPH
+0xDDFC	0xFA0D	#CJK COMPATIBILITY IDEOGRAPH
+0xDDFD	0x6BFB	#CJK UNIFIED IDEOGRAPH
+0xDDFE	0x6BFC	#CJK UNIFIED IDEOGRAPH
+0xDE40	0x6BF9	#CJK UNIFIED IDEOGRAPH
+0xDE41	0x6BF7	#CJK UNIFIED IDEOGRAPH
+0xDE42	0x6BF8	#CJK UNIFIED IDEOGRAPH
+0xDE43	0x6E9B	#CJK UNIFIED IDEOGRAPH
+0xDE44	0x6ED6	#CJK UNIFIED IDEOGRAPH
+0xDE45	0x6EC8	#CJK UNIFIED IDEOGRAPH
+0xDE46	0x6E8F	#CJK UNIFIED IDEOGRAPH
+0xDE47	0x6EC0	#CJK UNIFIED IDEOGRAPH
+0xDE48	0x6E9F	#CJK UNIFIED IDEOGRAPH
+0xDE49	0x6E93	#CJK UNIFIED IDEOGRAPH
+0xDE4A	0x6E94	#CJK UNIFIED IDEOGRAPH
+0xDE4B	0x6EA0	#CJK UNIFIED IDEOGRAPH
+0xDE4C	0x6EB1	#CJK UNIFIED IDEOGRAPH
+0xDE4D	0x6EB9	#CJK UNIFIED IDEOGRAPH
+0xDE4E	0x6EC6	#CJK UNIFIED IDEOGRAPH
+0xDE4F	0x6ED2	#CJK UNIFIED IDEOGRAPH
+0xDE50	0x6EBD	#CJK UNIFIED IDEOGRAPH
+0xDE51	0x6EC1	#CJK UNIFIED IDEOGRAPH
+0xDE52	0x6E9E	#CJK UNIFIED IDEOGRAPH
+0xDE53	0x6EC9	#CJK UNIFIED IDEOGRAPH
+0xDE54	0x6EB7	#CJK UNIFIED IDEOGRAPH
+0xDE55	0x6EB0	#CJK UNIFIED IDEOGRAPH
+0xDE56	0x6ECD	#CJK UNIFIED IDEOGRAPH
+0xDE57	0x6EA6	#CJK UNIFIED IDEOGRAPH
+0xDE58	0x6ECF	#CJK UNIFIED IDEOGRAPH
+0xDE59	0x6EB2	#CJK UNIFIED IDEOGRAPH
+0xDE5A	0x6EBE	#CJK UNIFIED IDEOGRAPH
+0xDE5B	0x6EC3	#CJK UNIFIED IDEOGRAPH
+0xDE5C	0x6EDC	#CJK UNIFIED IDEOGRAPH
+0xDE5D	0x6ED8	#CJK UNIFIED IDEOGRAPH
+0xDE5E	0x6E99	#CJK UNIFIED IDEOGRAPH
+0xDE5F	0x6E92	#CJK UNIFIED IDEOGRAPH
+0xDE60	0x6E8E	#CJK UNIFIED IDEOGRAPH
+0xDE61	0x6E8D	#CJK UNIFIED IDEOGRAPH
+0xDE62	0x6EA4	#CJK UNIFIED IDEOGRAPH
+0xDE63	0x6EA1	#CJK UNIFIED IDEOGRAPH
+0xDE64	0x6EBF	#CJK UNIFIED IDEOGRAPH
+0xDE65	0x6EB3	#CJK UNIFIED IDEOGRAPH
+0xDE66	0x6ED0	#CJK UNIFIED IDEOGRAPH
+0xDE67	0x6ECA	#CJK UNIFIED IDEOGRAPH
+0xDE68	0x6E97	#CJK UNIFIED IDEOGRAPH
+0xDE69	0x6EAE	#CJK UNIFIED IDEOGRAPH
+0xDE6A	0x6EA3	#CJK UNIFIED IDEOGRAPH
+0xDE6B	0x7147	#CJK UNIFIED IDEOGRAPH
+0xDE6C	0x7154	#CJK UNIFIED IDEOGRAPH
+0xDE6D	0x7152	#CJK UNIFIED IDEOGRAPH
+0xDE6E	0x7163	#CJK UNIFIED IDEOGRAPH
+0xDE6F	0x7160	#CJK UNIFIED IDEOGRAPH
+0xDE70	0x7141	#CJK UNIFIED IDEOGRAPH
+0xDE71	0x715D	#CJK UNIFIED IDEOGRAPH
+0xDE72	0x7162	#CJK UNIFIED IDEOGRAPH
+0xDE73	0x7172	#CJK UNIFIED IDEOGRAPH
+0xDE74	0x7178	#CJK UNIFIED IDEOGRAPH
+0xDE75	0x716A	#CJK UNIFIED IDEOGRAPH
+0xDE76	0x7161	#CJK UNIFIED IDEOGRAPH
+0xDE77	0x7142	#CJK UNIFIED IDEOGRAPH
+0xDE78	0x7158	#CJK UNIFIED IDEOGRAPH
+0xDE79	0x7143	#CJK UNIFIED IDEOGRAPH
+0xDE7A	0x714B	#CJK UNIFIED IDEOGRAPH
+0xDE7B	0x7170	#CJK UNIFIED IDEOGRAPH
+0xDE7C	0x715F	#CJK UNIFIED IDEOGRAPH
+0xDE7D	0x7150	#CJK UNIFIED IDEOGRAPH
+0xDE7E	0x7153	#CJK UNIFIED IDEOGRAPH
+0xDEA1	0x7144	#CJK UNIFIED IDEOGRAPH
+0xDEA2	0x714D	#CJK UNIFIED IDEOGRAPH
+0xDEA3	0x715A	#CJK UNIFIED IDEOGRAPH
+0xDEA4	0x724F	#CJK UNIFIED IDEOGRAPH
+0xDEA5	0x728D	#CJK UNIFIED IDEOGRAPH
+0xDEA6	0x728C	#CJK UNIFIED IDEOGRAPH
+0xDEA7	0x7291	#CJK UNIFIED IDEOGRAPH
+0xDEA8	0x7290	#CJK UNIFIED IDEOGRAPH
+0xDEA9	0x728E	#CJK UNIFIED IDEOGRAPH
+0xDEAA	0x733C	#CJK UNIFIED IDEOGRAPH
+0xDEAB	0x7342	#CJK UNIFIED IDEOGRAPH
+0xDEAC	0x733B	#CJK UNIFIED IDEOGRAPH
+0xDEAD	0x733A	#CJK UNIFIED IDEOGRAPH
+0xDEAE	0x7340	#CJK UNIFIED IDEOGRAPH
+0xDEAF	0x734A	#CJK UNIFIED IDEOGRAPH
+0xDEB0	0x7349	#CJK UNIFIED IDEOGRAPH
+0xDEB1	0x7444	#CJK UNIFIED IDEOGRAPH
+0xDEB2	0x744A	#CJK UNIFIED IDEOGRAPH
+0xDEB3	0x744B	#CJK UNIFIED IDEOGRAPH
+0xDEB4	0x7452	#CJK UNIFIED IDEOGRAPH
+0xDEB5	0x7451	#CJK UNIFIED IDEOGRAPH
+0xDEB6	0x7457	#CJK UNIFIED IDEOGRAPH
+0xDEB7	0x7440	#CJK UNIFIED IDEOGRAPH
+0xDEB8	0x744F	#CJK UNIFIED IDEOGRAPH
+0xDEB9	0x7450	#CJK UNIFIED IDEOGRAPH
+0xDEBA	0x744E	#CJK UNIFIED IDEOGRAPH
+0xDEBB	0x7442	#CJK UNIFIED IDEOGRAPH
+0xDEBC	0x7446	#CJK UNIFIED IDEOGRAPH
+0xDEBD	0x744D	#CJK UNIFIED IDEOGRAPH
+0xDEBE	0x7454	#CJK UNIFIED IDEOGRAPH
+0xDEBF	0x74E1	#CJK UNIFIED IDEOGRAPH
+0xDEC0	0x74FF	#CJK UNIFIED IDEOGRAPH
+0xDEC1	0x74FE	#CJK UNIFIED IDEOGRAPH
+0xDEC2	0x74FD	#CJK UNIFIED IDEOGRAPH
+0xDEC3	0x751D	#CJK UNIFIED IDEOGRAPH
+0xDEC4	0x7579	#CJK UNIFIED IDEOGRAPH
+0xDEC5	0x7577	#CJK UNIFIED IDEOGRAPH
+0xDEC6	0x6983	#CJK UNIFIED IDEOGRAPH
+0xDEC7	0x75EF	#CJK UNIFIED IDEOGRAPH
+0xDEC8	0x760F	#CJK UNIFIED IDEOGRAPH
+0xDEC9	0x7603	#CJK UNIFIED IDEOGRAPH
+0xDECA	0x75F7	#CJK UNIFIED IDEOGRAPH
+0xDECB	0x75FE	#CJK UNIFIED IDEOGRAPH
+0xDECC	0x75FC	#CJK UNIFIED IDEOGRAPH
+0xDECD	0x75F9	#CJK UNIFIED IDEOGRAPH
+0xDECE	0x75F8	#CJK UNIFIED IDEOGRAPH
+0xDECF	0x7610	#CJK UNIFIED IDEOGRAPH
+0xDED0	0x75FB	#CJK UNIFIED IDEOGRAPH
+0xDED1	0x75F6	#CJK UNIFIED IDEOGRAPH
+0xDED2	0x75ED	#CJK UNIFIED IDEOGRAPH
+0xDED3	0x75F5	#CJK UNIFIED IDEOGRAPH
+0xDED4	0x75FD	#CJK UNIFIED IDEOGRAPH
+0xDED5	0x7699	#CJK UNIFIED IDEOGRAPH
+0xDED6	0x76B5	#CJK UNIFIED IDEOGRAPH
+0xDED7	0x76DD	#CJK UNIFIED IDEOGRAPH
+0xDED8	0x7755	#CJK UNIFIED IDEOGRAPH
+0xDED9	0x775F	#CJK UNIFIED IDEOGRAPH
+0xDEDA	0x7760	#CJK UNIFIED IDEOGRAPH
+0xDEDB	0x7752	#CJK UNIFIED IDEOGRAPH
+0xDEDC	0x7756	#CJK UNIFIED IDEOGRAPH
+0xDEDD	0x775A	#CJK UNIFIED IDEOGRAPH
+0xDEDE	0x7769	#CJK UNIFIED IDEOGRAPH
+0xDEDF	0x7767	#CJK UNIFIED IDEOGRAPH
+0xDEE0	0x7754	#CJK UNIFIED IDEOGRAPH
+0xDEE1	0x7759	#CJK UNIFIED IDEOGRAPH
+0xDEE2	0x776D	#CJK UNIFIED IDEOGRAPH
+0xDEE3	0x77E0	#CJK UNIFIED IDEOGRAPH
+0xDEE4	0x7887	#CJK UNIFIED IDEOGRAPH
+0xDEE5	0x789A	#CJK UNIFIED IDEOGRAPH
+0xDEE6	0x7894	#CJK UNIFIED IDEOGRAPH
+0xDEE7	0x788F	#CJK UNIFIED IDEOGRAPH
+0xDEE8	0x7884	#CJK UNIFIED IDEOGRAPH
+0xDEE9	0x7895	#CJK UNIFIED IDEOGRAPH
+0xDEEA	0x7885	#CJK UNIFIED IDEOGRAPH
+0xDEEB	0x7886	#CJK UNIFIED IDEOGRAPH
+0xDEEC	0x78A1	#CJK UNIFIED IDEOGRAPH
+0xDEED	0x7883	#CJK UNIFIED IDEOGRAPH
+0xDEEE	0x7879	#CJK UNIFIED IDEOGRAPH
+0xDEEF	0x7899	#CJK UNIFIED IDEOGRAPH
+0xDEF0	0x7880	#CJK UNIFIED IDEOGRAPH
+0xDEF1	0x7896	#CJK UNIFIED IDEOGRAPH
+0xDEF2	0x787B	#CJK UNIFIED IDEOGRAPH
+0xDEF3	0x797C	#CJK UNIFIED IDEOGRAPH
+0xDEF4	0x7982	#CJK UNIFIED IDEOGRAPH
+0xDEF5	0x797D	#CJK UNIFIED IDEOGRAPH
+0xDEF6	0x7979	#CJK UNIFIED IDEOGRAPH
+0xDEF7	0x7A11	#CJK UNIFIED IDEOGRAPH
+0xDEF8	0x7A18	#CJK UNIFIED IDEOGRAPH
+0xDEF9	0x7A19	#CJK UNIFIED IDEOGRAPH
+0xDEFA	0x7A12	#CJK UNIFIED IDEOGRAPH
+0xDEFB	0x7A17	#CJK UNIFIED IDEOGRAPH
+0xDEFC	0x7A15	#CJK UNIFIED IDEOGRAPH
+0xDEFD	0x7A22	#CJK UNIFIED IDEOGRAPH
+0xDEFE	0x7A13	#CJK UNIFIED IDEOGRAPH
+0xDF40	0x7A1B	#CJK UNIFIED IDEOGRAPH
+0xDF41	0x7A10	#CJK UNIFIED IDEOGRAPH
+0xDF42	0x7AA3	#CJK UNIFIED IDEOGRAPH
+0xDF43	0x7AA2	#CJK UNIFIED IDEOGRAPH
+0xDF44	0x7A9E	#CJK UNIFIED IDEOGRAPH
+0xDF45	0x7AEB	#CJK UNIFIED IDEOGRAPH
+0xDF46	0x7B66	#CJK UNIFIED IDEOGRAPH
+0xDF47	0x7B64	#CJK UNIFIED IDEOGRAPH
+0xDF48	0x7B6D	#CJK UNIFIED IDEOGRAPH
+0xDF49	0x7B74	#CJK UNIFIED IDEOGRAPH
+0xDF4A	0x7B69	#CJK UNIFIED IDEOGRAPH
+0xDF4B	0x7B72	#CJK UNIFIED IDEOGRAPH
+0xDF4C	0x7B65	#CJK UNIFIED IDEOGRAPH
+0xDF4D	0x7B73	#CJK UNIFIED IDEOGRAPH
+0xDF4E	0x7B71	#CJK UNIFIED IDEOGRAPH
+0xDF4F	0x7B70	#CJK UNIFIED IDEOGRAPH
+0xDF50	0x7B61	#CJK UNIFIED IDEOGRAPH
+0xDF51	0x7B78	#CJK UNIFIED IDEOGRAPH
+0xDF52	0x7B76	#CJK UNIFIED IDEOGRAPH
+0xDF53	0x7B63	#CJK UNIFIED IDEOGRAPH
+0xDF54	0x7CB2	#CJK UNIFIED IDEOGRAPH
+0xDF55	0x7CB4	#CJK UNIFIED IDEOGRAPH
+0xDF56	0x7CAF	#CJK UNIFIED IDEOGRAPH
+0xDF57	0x7D88	#CJK UNIFIED IDEOGRAPH
+0xDF58	0x7D86	#CJK UNIFIED IDEOGRAPH
+0xDF59	0x7D80	#CJK UNIFIED IDEOGRAPH
+0xDF5A	0x7D8D	#CJK UNIFIED IDEOGRAPH
+0xDF5B	0x7D7F	#CJK UNIFIED IDEOGRAPH
+0xDF5C	0x7D85	#CJK UNIFIED IDEOGRAPH
+0xDF5D	0x7D7A	#CJK UNIFIED IDEOGRAPH
+0xDF5E	0x7D8E	#CJK UNIFIED IDEOGRAPH
+0xDF5F	0x7D7B	#CJK UNIFIED IDEOGRAPH
+0xDF60	0x7D83	#CJK UNIFIED IDEOGRAPH
+0xDF61	0x7D7C	#CJK UNIFIED IDEOGRAPH
+0xDF62	0x7D8C	#CJK UNIFIED IDEOGRAPH
+0xDF63	0x7D94	#CJK UNIFIED IDEOGRAPH
+0xDF64	0x7D84	#CJK UNIFIED IDEOGRAPH
+0xDF65	0x7D7D	#CJK UNIFIED IDEOGRAPH
+0xDF66	0x7D92	#CJK UNIFIED IDEOGRAPH
+0xDF67	0x7F6D	#CJK UNIFIED IDEOGRAPH
+0xDF68	0x7F6B	#CJK UNIFIED IDEOGRAPH
+0xDF69	0x7F67	#CJK UNIFIED IDEOGRAPH
+0xDF6A	0x7F68	#CJK UNIFIED IDEOGRAPH
+0xDF6B	0x7F6C	#CJK UNIFIED IDEOGRAPH
+0xDF6C	0x7FA6	#CJK UNIFIED IDEOGRAPH
+0xDF6D	0x7FA5	#CJK UNIFIED IDEOGRAPH
+0xDF6E	0x7FA7	#CJK UNIFIED IDEOGRAPH
+0xDF6F	0x7FDB	#CJK UNIFIED IDEOGRAPH
+0xDF70	0x7FDC	#CJK UNIFIED IDEOGRAPH
+0xDF71	0x8021	#CJK UNIFIED IDEOGRAPH
+0xDF72	0x8164	#CJK UNIFIED IDEOGRAPH
+0xDF73	0x8160	#CJK UNIFIED IDEOGRAPH
+0xDF74	0x8177	#CJK UNIFIED IDEOGRAPH
+0xDF75	0x815C	#CJK UNIFIED IDEOGRAPH
+0xDF76	0x8169	#CJK UNIFIED IDEOGRAPH
+0xDF77	0x815B	#CJK UNIFIED IDEOGRAPH
+0xDF78	0x8162	#CJK UNIFIED IDEOGRAPH
+0xDF79	0x8172	#CJK UNIFIED IDEOGRAPH
+0xDF7A	0x6721	#CJK UNIFIED IDEOGRAPH
+0xDF7B	0x815E	#CJK UNIFIED IDEOGRAPH
+0xDF7C	0x8176	#CJK UNIFIED IDEOGRAPH
+0xDF7D	0x8167	#CJK UNIFIED IDEOGRAPH
+0xDF7E	0x816F	#CJK UNIFIED IDEOGRAPH
+0xDFA1	0x8144	#CJK UNIFIED IDEOGRAPH
+0xDFA2	0x8161	#CJK UNIFIED IDEOGRAPH
+0xDFA3	0x821D	#CJK UNIFIED IDEOGRAPH
+0xDFA4	0x8249	#CJK UNIFIED IDEOGRAPH
+0xDFA5	0x8244	#CJK UNIFIED IDEOGRAPH
+0xDFA6	0x8240	#CJK UNIFIED IDEOGRAPH
+0xDFA7	0x8242	#CJK UNIFIED IDEOGRAPH
+0xDFA8	0x8245	#CJK UNIFIED IDEOGRAPH
+0xDFA9	0x84F1	#CJK UNIFIED IDEOGRAPH
+0xDFAA	0x843F	#CJK UNIFIED IDEOGRAPH
+0xDFAB	0x8456	#CJK UNIFIED IDEOGRAPH
+0xDFAC	0x8476	#CJK UNIFIED IDEOGRAPH
+0xDFAD	0x8479	#CJK UNIFIED IDEOGRAPH
+0xDFAE	0x848F	#CJK UNIFIED IDEOGRAPH
+0xDFAF	0x848D	#CJK UNIFIED IDEOGRAPH
+0xDFB0	0x8465	#CJK UNIFIED IDEOGRAPH
+0xDFB1	0x8451	#CJK UNIFIED IDEOGRAPH
+0xDFB2	0x8440	#CJK UNIFIED IDEOGRAPH
+0xDFB3	0x8486	#CJK UNIFIED IDEOGRAPH
+0xDFB4	0x8467	#CJK UNIFIED IDEOGRAPH
+0xDFB5	0x8430	#CJK UNIFIED IDEOGRAPH
+0xDFB6	0x844D	#CJK UNIFIED IDEOGRAPH
+0xDFB7	0x847D	#CJK UNIFIED IDEOGRAPH
+0xDFB8	0x845A	#CJK UNIFIED IDEOGRAPH
+0xDFB9	0x8459	#CJK UNIFIED IDEOGRAPH
+0xDFBA	0x8474	#CJK UNIFIED IDEOGRAPH
+0xDFBB	0x8473	#CJK UNIFIED IDEOGRAPH
+0xDFBC	0x845D	#CJK UNIFIED IDEOGRAPH
+0xDFBD	0x8507	#CJK UNIFIED IDEOGRAPH
+0xDFBE	0x845E	#CJK UNIFIED IDEOGRAPH
+0xDFBF	0x8437	#CJK UNIFIED IDEOGRAPH
+0xDFC0	0x843A	#CJK UNIFIED IDEOGRAPH
+0xDFC1	0x8434	#CJK UNIFIED IDEOGRAPH
+0xDFC2	0x847A	#CJK UNIFIED IDEOGRAPH
+0xDFC3	0x8443	#CJK UNIFIED IDEOGRAPH
+0xDFC4	0x8478	#CJK UNIFIED IDEOGRAPH
+0xDFC5	0x8432	#CJK UNIFIED IDEOGRAPH
+0xDFC6	0x8445	#CJK UNIFIED IDEOGRAPH
+0xDFC7	0x8429	#CJK UNIFIED IDEOGRAPH
+0xDFC8	0x83D9	#CJK UNIFIED IDEOGRAPH
+0xDFC9	0x844B	#CJK UNIFIED IDEOGRAPH
+0xDFCA	0x842F	#CJK UNIFIED IDEOGRAPH
+0xDFCB	0x8442	#CJK UNIFIED IDEOGRAPH
+0xDFCC	0x842D	#CJK UNIFIED IDEOGRAPH
+0xDFCD	0x845F	#CJK UNIFIED IDEOGRAPH
+0xDFCE	0x8470	#CJK UNIFIED IDEOGRAPH
+0xDFCF	0x8439	#CJK UNIFIED IDEOGRAPH
+0xDFD0	0x844E	#CJK UNIFIED IDEOGRAPH
+0xDFD1	0x844C	#CJK UNIFIED IDEOGRAPH
+0xDFD2	0x8452	#CJK UNIFIED IDEOGRAPH
+0xDFD3	0x846F	#CJK UNIFIED IDEOGRAPH
+0xDFD4	0x84C5	#CJK UNIFIED IDEOGRAPH
+0xDFD5	0x848E	#CJK UNIFIED IDEOGRAPH
+0xDFD6	0x843B	#CJK UNIFIED IDEOGRAPH
+0xDFD7	0x8447	#CJK UNIFIED IDEOGRAPH
+0xDFD8	0x8436	#CJK UNIFIED IDEOGRAPH
+0xDFD9	0x8433	#CJK UNIFIED IDEOGRAPH
+0xDFDA	0x8468	#CJK UNIFIED IDEOGRAPH
+0xDFDB	0x847E	#CJK UNIFIED IDEOGRAPH
+0xDFDC	0x8444	#CJK UNIFIED IDEOGRAPH
+0xDFDD	0x842B	#CJK UNIFIED IDEOGRAPH
+0xDFDE	0x8460	#CJK UNIFIED IDEOGRAPH
+0xDFDF	0x8454	#CJK UNIFIED IDEOGRAPH
+0xDFE0	0x846E	#CJK UNIFIED IDEOGRAPH
+0xDFE1	0x8450	#CJK UNIFIED IDEOGRAPH
+0xDFE2	0x870B	#CJK UNIFIED IDEOGRAPH
+0xDFE3	0x8704	#CJK UNIFIED IDEOGRAPH
+0xDFE4	0x86F7	#CJK UNIFIED IDEOGRAPH
+0xDFE5	0x870C	#CJK UNIFIED IDEOGRAPH
+0xDFE6	0x86FA	#CJK UNIFIED IDEOGRAPH
+0xDFE7	0x86D6	#CJK UNIFIED IDEOGRAPH
+0xDFE8	0x86F5	#CJK UNIFIED IDEOGRAPH
+0xDFE9	0x874D	#CJK UNIFIED IDEOGRAPH
+0xDFEA	0x86F8	#CJK UNIFIED IDEOGRAPH
+0xDFEB	0x870E	#CJK UNIFIED IDEOGRAPH
+0xDFEC	0x8709	#CJK UNIFIED IDEOGRAPH
+0xDFED	0x8701	#CJK UNIFIED IDEOGRAPH
+0xDFEE	0x86F6	#CJK UNIFIED IDEOGRAPH
+0xDFEF	0x870D	#CJK UNIFIED IDEOGRAPH
+0xDFF0	0x8705	#CJK UNIFIED IDEOGRAPH
+0xDFF1	0x88D6	#CJK UNIFIED IDEOGRAPH
+0xDFF2	0x88CB	#CJK UNIFIED IDEOGRAPH
+0xDFF3	0x88CD	#CJK UNIFIED IDEOGRAPH
+0xDFF4	0x88CE	#CJK UNIFIED IDEOGRAPH
+0xDFF5	0x88DE	#CJK UNIFIED IDEOGRAPH
+0xDFF6	0x88DB	#CJK UNIFIED IDEOGRAPH
+0xDFF7	0x88DA	#CJK UNIFIED IDEOGRAPH
+0xDFF8	0x88CC	#CJK UNIFIED IDEOGRAPH
+0xDFF9	0x88D0	#CJK UNIFIED IDEOGRAPH
+0xDFFA	0x8985	#CJK UNIFIED IDEOGRAPH
+0xDFFB	0x899B	#CJK UNIFIED IDEOGRAPH
+0xDFFC	0x89DF	#CJK UNIFIED IDEOGRAPH
+0xDFFD	0x89E5	#CJK UNIFIED IDEOGRAPH
+0xDFFE	0x89E4	#CJK UNIFIED IDEOGRAPH
+0xE040	0x89E1	#CJK UNIFIED IDEOGRAPH
+0xE041	0x89E0	#CJK UNIFIED IDEOGRAPH
+0xE042	0x89E2	#CJK UNIFIED IDEOGRAPH
+0xE043	0x89DC	#CJK UNIFIED IDEOGRAPH
+0xE044	0x89E6	#CJK UNIFIED IDEOGRAPH
+0xE045	0x8A76	#CJK UNIFIED IDEOGRAPH
+0xE046	0x8A86	#CJK UNIFIED IDEOGRAPH
+0xE047	0x8A7F	#CJK UNIFIED IDEOGRAPH
+0xE048	0x8A61	#CJK UNIFIED IDEOGRAPH
+0xE049	0x8A3F	#CJK UNIFIED IDEOGRAPH
+0xE04A	0x8A77	#CJK UNIFIED IDEOGRAPH
+0xE04B	0x8A82	#CJK UNIFIED IDEOGRAPH
+0xE04C	0x8A84	#CJK UNIFIED IDEOGRAPH
+0xE04D	0x8A75	#CJK UNIFIED IDEOGRAPH
+0xE04E	0x8A83	#CJK UNIFIED IDEOGRAPH
+0xE04F	0x8A81	#CJK UNIFIED IDEOGRAPH
+0xE050	0x8A74	#CJK UNIFIED IDEOGRAPH
+0xE051	0x8A7A	#CJK UNIFIED IDEOGRAPH
+0xE052	0x8C3C	#CJK UNIFIED IDEOGRAPH
+0xE053	0x8C4B	#CJK UNIFIED IDEOGRAPH
+0xE054	0x8C4A	#CJK UNIFIED IDEOGRAPH
+0xE055	0x8C65	#CJK UNIFIED IDEOGRAPH
+0xE056	0x8C64	#CJK UNIFIED IDEOGRAPH
+0xE057	0x8C66	#CJK UNIFIED IDEOGRAPH
+0xE058	0x8C86	#CJK UNIFIED IDEOGRAPH
+0xE059	0x8C84	#CJK UNIFIED IDEOGRAPH
+0xE05A	0x8C85	#CJK UNIFIED IDEOGRAPH
+0xE05B	0x8CCC	#CJK UNIFIED IDEOGRAPH
+0xE05C	0x8D68	#CJK UNIFIED IDEOGRAPH
+0xE05D	0x8D69	#CJK UNIFIED IDEOGRAPH
+0xE05E	0x8D91	#CJK UNIFIED IDEOGRAPH
+0xE05F	0x8D8C	#CJK UNIFIED IDEOGRAPH
+0xE060	0x8D8E	#CJK UNIFIED IDEOGRAPH
+0xE061	0x8D8F	#CJK UNIFIED IDEOGRAPH
+0xE062	0x8D8D	#CJK UNIFIED IDEOGRAPH
+0xE063	0x8D93	#CJK UNIFIED IDEOGRAPH
+0xE064	0x8D94	#CJK UNIFIED IDEOGRAPH
+0xE065	0x8D90	#CJK UNIFIED IDEOGRAPH
+0xE066	0x8D92	#CJK UNIFIED IDEOGRAPH
+0xE067	0x8DF0	#CJK UNIFIED IDEOGRAPH
+0xE068	0x8DE0	#CJK UNIFIED IDEOGRAPH
+0xE069	0x8DEC	#CJK UNIFIED IDEOGRAPH
+0xE06A	0x8DF1	#CJK UNIFIED IDEOGRAPH
+0xE06B	0x8DEE	#CJK UNIFIED IDEOGRAPH
+0xE06C	0x8DD0	#CJK UNIFIED IDEOGRAPH
+0xE06D	0x8DE9	#CJK UNIFIED IDEOGRAPH
+0xE06E	0x8DE3	#CJK UNIFIED IDEOGRAPH
+0xE06F	0x8DE2	#CJK UNIFIED IDEOGRAPH
+0xE070	0x8DE7	#CJK UNIFIED IDEOGRAPH
+0xE071	0x8DF2	#CJK UNIFIED IDEOGRAPH
+0xE072	0x8DEB	#CJK UNIFIED IDEOGRAPH
+0xE073	0x8DF4	#CJK UNIFIED IDEOGRAPH
+0xE074	0x8F06	#CJK UNIFIED IDEOGRAPH
+0xE075	0x8EFF	#CJK UNIFIED IDEOGRAPH
+0xE076	0x8F01	#CJK UNIFIED IDEOGRAPH
+0xE077	0x8F00	#CJK UNIFIED IDEOGRAPH
+0xE078	0x8F05	#CJK UNIFIED IDEOGRAPH
+0xE079	0x8F07	#CJK UNIFIED IDEOGRAPH
+0xE07A	0x8F08	#CJK UNIFIED IDEOGRAPH
+0xE07B	0x8F02	#CJK UNIFIED IDEOGRAPH
+0xE07C	0x8F0B	#CJK UNIFIED IDEOGRAPH
+0xE07D	0x9052	#CJK UNIFIED IDEOGRAPH
+0xE07E	0x903F	#CJK UNIFIED IDEOGRAPH
+0xE0A1	0x9044	#CJK UNIFIED IDEOGRAPH
+0xE0A2	0x9049	#CJK UNIFIED IDEOGRAPH
+0xE0A3	0x903D	#CJK UNIFIED IDEOGRAPH
+0xE0A4	0x9110	#CJK UNIFIED IDEOGRAPH
+0xE0A5	0x910D	#CJK UNIFIED IDEOGRAPH
+0xE0A6	0x910F	#CJK UNIFIED IDEOGRAPH
+0xE0A7	0x9111	#CJK UNIFIED IDEOGRAPH
+0xE0A8	0x9116	#CJK UNIFIED IDEOGRAPH
+0xE0A9	0x9114	#CJK UNIFIED IDEOGRAPH
+0xE0AA	0x910B	#CJK UNIFIED IDEOGRAPH
+0xE0AB	0x910E	#CJK UNIFIED IDEOGRAPH
+0xE0AC	0x916E	#CJK UNIFIED IDEOGRAPH
+0xE0AD	0x916F	#CJK UNIFIED IDEOGRAPH
+0xE0AE	0x9248	#CJK UNIFIED IDEOGRAPH
+0xE0AF	0x9252	#CJK UNIFIED IDEOGRAPH
+0xE0B0	0x9230	#CJK UNIFIED IDEOGRAPH
+0xE0B1	0x923A	#CJK UNIFIED IDEOGRAPH
+0xE0B2	0x9266	#CJK UNIFIED IDEOGRAPH
+0xE0B3	0x9233	#CJK UNIFIED IDEOGRAPH
+0xE0B4	0x9265	#CJK UNIFIED IDEOGRAPH
+0xE0B5	0x925E	#CJK UNIFIED IDEOGRAPH
+0xE0B6	0x9283	#CJK UNIFIED IDEOGRAPH
+0xE0B7	0x922E	#CJK UNIFIED IDEOGRAPH
+0xE0B8	0x924A	#CJK UNIFIED IDEOGRAPH
+0xE0B9	0x9246	#CJK UNIFIED IDEOGRAPH
+0xE0BA	0x926D	#CJK UNIFIED IDEOGRAPH
+0xE0BB	0x926C	#CJK UNIFIED IDEOGRAPH
+0xE0BC	0x924F	#CJK UNIFIED IDEOGRAPH
+0xE0BD	0x9260	#CJK UNIFIED IDEOGRAPH
+0xE0BE	0x9267	#CJK UNIFIED IDEOGRAPH
+0xE0BF	0x926F	#CJK UNIFIED IDEOGRAPH
+0xE0C0	0x9236	#CJK UNIFIED IDEOGRAPH
+0xE0C1	0x9261	#CJK UNIFIED IDEOGRAPH
+0xE0C2	0x9270	#CJK UNIFIED IDEOGRAPH
+0xE0C3	0x9231	#CJK UNIFIED IDEOGRAPH
+0xE0C4	0x9254	#CJK UNIFIED IDEOGRAPH
+0xE0C5	0x9263	#CJK UNIFIED IDEOGRAPH
+0xE0C6	0x9250	#CJK UNIFIED IDEOGRAPH
+0xE0C7	0x9272	#CJK UNIFIED IDEOGRAPH
+0xE0C8	0x924E	#CJK UNIFIED IDEOGRAPH
+0xE0C9	0x9253	#CJK UNIFIED IDEOGRAPH
+0xE0CA	0x924C	#CJK UNIFIED IDEOGRAPH
+0xE0CB	0x9256	#CJK UNIFIED IDEOGRAPH
+0xE0CC	0x9232	#CJK UNIFIED IDEOGRAPH
+0xE0CD	0x959F	#CJK UNIFIED IDEOGRAPH
+0xE0CE	0x959C	#CJK UNIFIED IDEOGRAPH
+0xE0CF	0x959E	#CJK UNIFIED IDEOGRAPH
+0xE0D0	0x959B	#CJK UNIFIED IDEOGRAPH
+0xE0D1	0x9692	#CJK UNIFIED IDEOGRAPH
+0xE0D2	0x9693	#CJK UNIFIED IDEOGRAPH
+0xE0D3	0x9691	#CJK UNIFIED IDEOGRAPH
+0xE0D4	0x9697	#CJK UNIFIED IDEOGRAPH
+0xE0D5	0x96CE	#CJK UNIFIED IDEOGRAPH
+0xE0D6	0x96FA	#CJK UNIFIED IDEOGRAPH
+0xE0D7	0x96FD	#CJK UNIFIED IDEOGRAPH
+0xE0D8	0x96F8	#CJK UNIFIED IDEOGRAPH
+0xE0D9	0x96F5	#CJK UNIFIED IDEOGRAPH
+0xE0DA	0x9773	#CJK UNIFIED IDEOGRAPH
+0xE0DB	0x9777	#CJK UNIFIED IDEOGRAPH
+0xE0DC	0x9778	#CJK UNIFIED IDEOGRAPH
+0xE0DD	0x9772	#CJK UNIFIED IDEOGRAPH
+0xE0DE	0x980F	#CJK UNIFIED IDEOGRAPH
+0xE0DF	0x980D	#CJK UNIFIED IDEOGRAPH
+0xE0E0	0x980E	#CJK UNIFIED IDEOGRAPH
+0xE0E1	0x98AC	#CJK UNIFIED IDEOGRAPH
+0xE0E2	0x98F6	#CJK UNIFIED IDEOGRAPH
+0xE0E3	0x98F9	#CJK UNIFIED IDEOGRAPH
+0xE0E4	0x99AF	#CJK UNIFIED IDEOGRAPH
+0xE0E5	0x99B2	#CJK UNIFIED IDEOGRAPH
+0xE0E6	0x99B0	#CJK UNIFIED IDEOGRAPH
+0xE0E7	0x99B5	#CJK UNIFIED IDEOGRAPH
+0xE0E8	0x9AAD	#CJK UNIFIED IDEOGRAPH
+0xE0E9	0x9AAB	#CJK UNIFIED IDEOGRAPH
+0xE0EA	0x9B5B	#CJK UNIFIED IDEOGRAPH
+0xE0EB	0x9CEA	#CJK UNIFIED IDEOGRAPH
+0xE0EC	0x9CED	#CJK UNIFIED IDEOGRAPH
+0xE0ED	0x9CE7	#CJK UNIFIED IDEOGRAPH
+0xE0EE	0x9E80	#CJK UNIFIED IDEOGRAPH
+0xE0EF	0x9EFD	#CJK UNIFIED IDEOGRAPH
+0xE0F0	0x50E6	#CJK UNIFIED IDEOGRAPH
+0xE0F1	0x50D4	#CJK UNIFIED IDEOGRAPH
+0xE0F2	0x50D7	#CJK UNIFIED IDEOGRAPH
+0xE0F3	0x50E8	#CJK UNIFIED IDEOGRAPH
+0xE0F4	0x50F3	#CJK UNIFIED IDEOGRAPH
+0xE0F5	0x50DB	#CJK UNIFIED IDEOGRAPH
+0xE0F6	0x50EA	#CJK UNIFIED IDEOGRAPH
+0xE0F7	0x50DD	#CJK UNIFIED IDEOGRAPH
+0xE0F8	0x50E4	#CJK UNIFIED IDEOGRAPH
+0xE0F9	0x50D3	#CJK UNIFIED IDEOGRAPH
+0xE0FA	0x50EC	#CJK UNIFIED IDEOGRAPH
+0xE0FB	0x50F0	#CJK UNIFIED IDEOGRAPH
+0xE0FC	0x50EF	#CJK UNIFIED IDEOGRAPH
+0xE0FD	0x50E3	#CJK UNIFIED IDEOGRAPH
+0xE0FE	0x50E0	#CJK UNIFIED IDEOGRAPH
+0xE140	0x51D8	#CJK UNIFIED IDEOGRAPH
+0xE141	0x5280	#CJK UNIFIED IDEOGRAPH
+0xE142	0x5281	#CJK UNIFIED IDEOGRAPH
+0xE143	0x52E9	#CJK UNIFIED IDEOGRAPH
+0xE144	0x52EB	#CJK UNIFIED IDEOGRAPH
+0xE145	0x5330	#CJK UNIFIED IDEOGRAPH
+0xE146	0x53AC	#CJK UNIFIED IDEOGRAPH
+0xE147	0x5627	#CJK UNIFIED IDEOGRAPH
+0xE148	0x5615	#CJK UNIFIED IDEOGRAPH
+0xE149	0x560C	#CJK UNIFIED IDEOGRAPH
+0xE14A	0x5612	#CJK UNIFIED IDEOGRAPH
+0xE14B	0x55FC	#CJK UNIFIED IDEOGRAPH
+0xE14C	0x560F	#CJK UNIFIED IDEOGRAPH
+0xE14D	0x561C	#CJK UNIFIED IDEOGRAPH
+0xE14E	0x5601	#CJK UNIFIED IDEOGRAPH
+0xE14F	0x5613	#CJK UNIFIED IDEOGRAPH
+0xE150	0x5602	#CJK UNIFIED IDEOGRAPH
+0xE151	0x55FA	#CJK UNIFIED IDEOGRAPH
+0xE152	0x561D	#CJK UNIFIED IDEOGRAPH
+0xE153	0x5604	#CJK UNIFIED IDEOGRAPH
+0xE154	0x55FF	#CJK UNIFIED IDEOGRAPH
+0xE155	0x55F9	#CJK UNIFIED IDEOGRAPH
+0xE156	0x5889	#CJK UNIFIED IDEOGRAPH
+0xE157	0x587C	#CJK UNIFIED IDEOGRAPH
+0xE158	0x5890	#CJK UNIFIED IDEOGRAPH
+0xE159	0x5898	#CJK UNIFIED IDEOGRAPH
+0xE15A	0x5886	#CJK UNIFIED IDEOGRAPH
+0xE15B	0x5881	#CJK UNIFIED IDEOGRAPH
+0xE15C	0x587F	#CJK UNIFIED IDEOGRAPH
+0xE15D	0x5874	#CJK UNIFIED IDEOGRAPH
+0xE15E	0x588B	#CJK UNIFIED IDEOGRAPH
+0xE15F	0x587A	#CJK UNIFIED IDEOGRAPH
+0xE160	0x5887	#CJK UNIFIED IDEOGRAPH
+0xE161	0x5891	#CJK UNIFIED IDEOGRAPH
+0xE162	0x588E	#CJK UNIFIED IDEOGRAPH
+0xE163	0x5876	#CJK UNIFIED IDEOGRAPH
+0xE164	0x5882	#CJK UNIFIED IDEOGRAPH
+0xE165	0x5888	#CJK UNIFIED IDEOGRAPH
+0xE166	0x587B	#CJK UNIFIED IDEOGRAPH
+0xE167	0x5894	#CJK UNIFIED IDEOGRAPH
+0xE168	0x588F	#CJK UNIFIED IDEOGRAPH
+0xE169	0x58FE	#CJK UNIFIED IDEOGRAPH
+0xE16A	0x596B	#CJK UNIFIED IDEOGRAPH
+0xE16B	0x5ADC	#CJK UNIFIED IDEOGRAPH
+0xE16C	0x5AEE	#CJK UNIFIED IDEOGRAPH
+0xE16D	0x5AE5	#CJK UNIFIED IDEOGRAPH
+0xE16E	0x5AD5	#CJK UNIFIED IDEOGRAPH
+0xE16F	0x5AEA	#CJK UNIFIED IDEOGRAPH
+0xE170	0x5ADA	#CJK UNIFIED IDEOGRAPH
+0xE171	0x5AED	#CJK UNIFIED IDEOGRAPH
+0xE172	0x5AEB	#CJK UNIFIED IDEOGRAPH
+0xE173	0x5AF3	#CJK UNIFIED IDEOGRAPH
+0xE174	0x5AE2	#CJK UNIFIED IDEOGRAPH
+0xE175	0x5AE0	#CJK UNIFIED IDEOGRAPH
+0xE176	0x5ADB	#CJK UNIFIED IDEOGRAPH
+0xE177	0x5AEC	#CJK UNIFIED IDEOGRAPH
+0xE178	0x5ADE	#CJK UNIFIED IDEOGRAPH
+0xE179	0x5ADD	#CJK UNIFIED IDEOGRAPH
+0xE17A	0x5AD9	#CJK UNIFIED IDEOGRAPH
+0xE17B	0x5AE8	#CJK UNIFIED IDEOGRAPH
+0xE17C	0x5ADF	#CJK UNIFIED IDEOGRAPH
+0xE17D	0x5B77	#CJK UNIFIED IDEOGRAPH
+0xE17E	0x5BE0	#CJK UNIFIED IDEOGRAPH
+0xE1A1	0x5BE3	#CJK UNIFIED IDEOGRAPH
+0xE1A2	0x5C63	#CJK UNIFIED IDEOGRAPH
+0xE1A3	0x5D82	#CJK UNIFIED IDEOGRAPH
+0xE1A4	0x5D80	#CJK UNIFIED IDEOGRAPH
+0xE1A5	0x5D7D	#CJK UNIFIED IDEOGRAPH
+0xE1A6	0x5D86	#CJK UNIFIED IDEOGRAPH
+0xE1A7	0x5D7A	#CJK UNIFIED IDEOGRAPH
+0xE1A8	0x5D81	#CJK UNIFIED IDEOGRAPH
+0xE1A9	0x5D77	#CJK UNIFIED IDEOGRAPH
+0xE1AA	0x5D8A	#CJK UNIFIED IDEOGRAPH
+0xE1AB	0x5D89	#CJK UNIFIED IDEOGRAPH
+0xE1AC	0x5D88	#CJK UNIFIED IDEOGRAPH
+0xE1AD	0x5D7E	#CJK UNIFIED IDEOGRAPH
+0xE1AE	0x5D7C	#CJK UNIFIED IDEOGRAPH
+0xE1AF	0x5D8D	#CJK UNIFIED IDEOGRAPH
+0xE1B0	0x5D79	#CJK UNIFIED IDEOGRAPH
+0xE1B1	0x5D7F	#CJK UNIFIED IDEOGRAPH
+0xE1B2	0x5E58	#CJK UNIFIED IDEOGRAPH
+0xE1B3	0x5E59	#CJK UNIFIED IDEOGRAPH
+0xE1B4	0x5E53	#CJK UNIFIED IDEOGRAPH
+0xE1B5	0x5ED8	#CJK UNIFIED IDEOGRAPH
+0xE1B6	0x5ED1	#CJK UNIFIED IDEOGRAPH
+0xE1B7	0x5ED7	#CJK UNIFIED IDEOGRAPH
+0xE1B8	0x5ECE	#CJK UNIFIED IDEOGRAPH
+0xE1B9	0x5EDC	#CJK UNIFIED IDEOGRAPH
+0xE1BA	0x5ED5	#CJK UNIFIED IDEOGRAPH
+0xE1BB	0x5ED9	#CJK UNIFIED IDEOGRAPH
+0xE1BC	0x5ED2	#CJK UNIFIED IDEOGRAPH
+0xE1BD	0x5ED4	#CJK UNIFIED IDEOGRAPH
+0xE1BE	0x5F44	#CJK UNIFIED IDEOGRAPH
+0xE1BF	0x5F43	#CJK UNIFIED IDEOGRAPH
+0xE1C0	0x5F6F	#CJK UNIFIED IDEOGRAPH
+0xE1C1	0x5FB6	#CJK UNIFIED IDEOGRAPH
+0xE1C2	0x612C	#CJK UNIFIED IDEOGRAPH
+0xE1C3	0x6128	#CJK UNIFIED IDEOGRAPH
+0xE1C4	0x6141	#CJK UNIFIED IDEOGRAPH
+0xE1C5	0x615E	#CJK UNIFIED IDEOGRAPH
+0xE1C6	0x6171	#CJK UNIFIED IDEOGRAPH
+0xE1C7	0x6173	#CJK UNIFIED IDEOGRAPH
+0xE1C8	0x6152	#CJK UNIFIED IDEOGRAPH
+0xE1C9	0x6153	#CJK UNIFIED IDEOGRAPH
+0xE1CA	0x6172	#CJK UNIFIED IDEOGRAPH
+0xE1CB	0x616C	#CJK UNIFIED IDEOGRAPH
+0xE1CC	0x6180	#CJK UNIFIED IDEOGRAPH
+0xE1CD	0x6174	#CJK UNIFIED IDEOGRAPH
+0xE1CE	0x6154	#CJK UNIFIED IDEOGRAPH
+0xE1CF	0x617A	#CJK UNIFIED IDEOGRAPH
+0xE1D0	0x615B	#CJK UNIFIED IDEOGRAPH
+0xE1D1	0x6165	#CJK UNIFIED IDEOGRAPH
+0xE1D2	0x613B	#CJK UNIFIED IDEOGRAPH
+0xE1D3	0x616A	#CJK UNIFIED IDEOGRAPH
+0xE1D4	0x6161	#CJK UNIFIED IDEOGRAPH
+0xE1D5	0x6156	#CJK UNIFIED IDEOGRAPH
+0xE1D6	0x6229	#CJK UNIFIED IDEOGRAPH
+0xE1D7	0x6227	#CJK UNIFIED IDEOGRAPH
+0xE1D8	0x622B	#CJK UNIFIED IDEOGRAPH
+0xE1D9	0x642B	#CJK UNIFIED IDEOGRAPH
+0xE1DA	0x644D	#CJK UNIFIED IDEOGRAPH
+0xE1DB	0x645B	#CJK UNIFIED IDEOGRAPH
+0xE1DC	0x645D	#CJK UNIFIED IDEOGRAPH
+0xE1DD	0x6474	#CJK UNIFIED IDEOGRAPH
+0xE1DE	0x6476	#CJK UNIFIED IDEOGRAPH
+0xE1DF	0x6472	#CJK UNIFIED IDEOGRAPH
+0xE1E0	0x6473	#CJK UNIFIED IDEOGRAPH
+0xE1E1	0x647D	#CJK UNIFIED IDEOGRAPH
+0xE1E2	0x6475	#CJK UNIFIED IDEOGRAPH
+0xE1E3	0x6466	#CJK UNIFIED IDEOGRAPH
+0xE1E4	0x64A6	#CJK UNIFIED IDEOGRAPH
+0xE1E5	0x644E	#CJK UNIFIED IDEOGRAPH
+0xE1E6	0x6482	#CJK UNIFIED IDEOGRAPH
+0xE1E7	0x645E	#CJK UNIFIED IDEOGRAPH
+0xE1E8	0x645C	#CJK UNIFIED IDEOGRAPH
+0xE1E9	0x644B	#CJK UNIFIED IDEOGRAPH
+0xE1EA	0x6453	#CJK UNIFIED IDEOGRAPH
+0xE1EB	0x6460	#CJK UNIFIED IDEOGRAPH
+0xE1EC	0x6450	#CJK UNIFIED IDEOGRAPH
+0xE1ED	0x647F	#CJK UNIFIED IDEOGRAPH
+0xE1EE	0x643F	#CJK UNIFIED IDEOGRAPH
+0xE1EF	0x646C	#CJK UNIFIED IDEOGRAPH
+0xE1F0	0x646B	#CJK UNIFIED IDEOGRAPH
+0xE1F1	0x6459	#CJK UNIFIED IDEOGRAPH
+0xE1F2	0x6465	#CJK UNIFIED IDEOGRAPH
+0xE1F3	0x6477	#CJK UNIFIED IDEOGRAPH
+0xE1F4	0x6573	#CJK UNIFIED IDEOGRAPH
+0xE1F5	0x65A0	#CJK UNIFIED IDEOGRAPH
+0xE1F6	0x66A1	#CJK UNIFIED IDEOGRAPH
+0xE1F7	0x66A0	#CJK UNIFIED IDEOGRAPH
+0xE1F8	0x669F	#CJK UNIFIED IDEOGRAPH
+0xE1F9	0x6705	#CJK UNIFIED IDEOGRAPH
+0xE1FA	0x6704	#CJK UNIFIED IDEOGRAPH
+0xE1FB	0x6722	#CJK UNIFIED IDEOGRAPH
+0xE1FC	0x69B1	#CJK UNIFIED IDEOGRAPH
+0xE1FD	0x69B6	#CJK UNIFIED IDEOGRAPH
+0xE1FE	0x69C9	#CJK UNIFIED IDEOGRAPH
+0xE240	0x69A0	#CJK UNIFIED IDEOGRAPH
+0xE241	0x69CE	#CJK UNIFIED IDEOGRAPH
+0xE242	0x6996	#CJK UNIFIED IDEOGRAPH
+0xE243	0x69B0	#CJK UNIFIED IDEOGRAPH
+0xE244	0x69AC	#CJK UNIFIED IDEOGRAPH
+0xE245	0x69BC	#CJK UNIFIED IDEOGRAPH
+0xE246	0x6991	#CJK UNIFIED IDEOGRAPH
+0xE247	0x6999	#CJK UNIFIED IDEOGRAPH
+0xE248	0x698E	#CJK UNIFIED IDEOGRAPH
+0xE249	0x69A7	#CJK UNIFIED IDEOGRAPH
+0xE24A	0x698D	#CJK UNIFIED IDEOGRAPH
+0xE24B	0x69A9	#CJK UNIFIED IDEOGRAPH
+0xE24C	0x69BE	#CJK UNIFIED IDEOGRAPH
+0xE24D	0x69AF	#CJK UNIFIED IDEOGRAPH
+0xE24E	0x69BF	#CJK UNIFIED IDEOGRAPH
+0xE24F	0x69C4	#CJK UNIFIED IDEOGRAPH
+0xE250	0x69BD	#CJK UNIFIED IDEOGRAPH
+0xE251	0x69A4	#CJK UNIFIED IDEOGRAPH
+0xE252	0x69D4	#CJK UNIFIED IDEOGRAPH
+0xE253	0x69B9	#CJK UNIFIED IDEOGRAPH
+0xE254	0x69CA	#CJK UNIFIED IDEOGRAPH
+0xE255	0x699A	#CJK UNIFIED IDEOGRAPH
+0xE256	0x69CF	#CJK UNIFIED IDEOGRAPH
+0xE257	0x69B3	#CJK UNIFIED IDEOGRAPH
+0xE258	0x6993	#CJK UNIFIED IDEOGRAPH
+0xE259	0x69AA	#CJK UNIFIED IDEOGRAPH
+0xE25A	0x69A1	#CJK UNIFIED IDEOGRAPH
+0xE25B	0x699E	#CJK UNIFIED IDEOGRAPH
+0xE25C	0x69D9	#CJK UNIFIED IDEOGRAPH
+0xE25D	0x6997	#CJK UNIFIED IDEOGRAPH
+0xE25E	0x6990	#CJK UNIFIED IDEOGRAPH
+0xE25F	0x69C2	#CJK UNIFIED IDEOGRAPH
+0xE260	0x69B5	#CJK UNIFIED IDEOGRAPH
+0xE261	0x69A5	#CJK UNIFIED IDEOGRAPH
+0xE262	0x69C6	#CJK UNIFIED IDEOGRAPH
+0xE263	0x6B4A	#CJK UNIFIED IDEOGRAPH
+0xE264	0x6B4D	#CJK UNIFIED IDEOGRAPH
+0xE265	0x6B4B	#CJK UNIFIED IDEOGRAPH
+0xE266	0x6B9E	#CJK UNIFIED IDEOGRAPH
+0xE267	0x6B9F	#CJK UNIFIED IDEOGRAPH
+0xE268	0x6BA0	#CJK UNIFIED IDEOGRAPH
+0xE269	0x6BC3	#CJK UNIFIED IDEOGRAPH
+0xE26A	0x6BC4	#CJK UNIFIED IDEOGRAPH
+0xE26B	0x6BFE	#CJK UNIFIED IDEOGRAPH
+0xE26C	0x6ECE	#CJK UNIFIED IDEOGRAPH
+0xE26D	0x6EF5	#CJK UNIFIED IDEOGRAPH
+0xE26E	0x6EF1	#CJK UNIFIED IDEOGRAPH
+0xE26F	0x6F03	#CJK UNIFIED IDEOGRAPH
+0xE270	0x6F25	#CJK UNIFIED IDEOGRAPH
+0xE271	0x6EF8	#CJK UNIFIED IDEOGRAPH
+0xE272	0x6F37	#CJK UNIFIED IDEOGRAPH
+0xE273	0x6EFB	#CJK UNIFIED IDEOGRAPH
+0xE274	0x6F2E	#CJK UNIFIED IDEOGRAPH
+0xE275	0x6F09	#CJK UNIFIED IDEOGRAPH
+0xE276	0x6F4E	#CJK UNIFIED IDEOGRAPH
+0xE277	0x6F19	#CJK UNIFIED IDEOGRAPH
+0xE278	0x6F1A	#CJK UNIFIED IDEOGRAPH
+0xE279	0x6F27	#CJK UNIFIED IDEOGRAPH
+0xE27A	0x6F18	#CJK UNIFIED IDEOGRAPH
+0xE27B	0x6F3B	#CJK UNIFIED IDEOGRAPH
+0xE27C	0x6F12	#CJK UNIFIED IDEOGRAPH
+0xE27D	0x6EED	#CJK UNIFIED IDEOGRAPH
+0xE27E	0x6F0A	#CJK UNIFIED IDEOGRAPH
+0xE2A1	0x6F36	#CJK UNIFIED IDEOGRAPH
+0xE2A2	0x6F73	#CJK UNIFIED IDEOGRAPH
+0xE2A3	0x6EF9	#CJK UNIFIED IDEOGRAPH
+0xE2A4	0x6EEE	#CJK UNIFIED IDEOGRAPH
+0xE2A5	0x6F2D	#CJK UNIFIED IDEOGRAPH
+0xE2A6	0x6F40	#CJK UNIFIED IDEOGRAPH
+0xE2A7	0x6F30	#CJK UNIFIED IDEOGRAPH
+0xE2A8	0x6F3C	#CJK UNIFIED IDEOGRAPH
+0xE2A9	0x6F35	#CJK UNIFIED IDEOGRAPH
+0xE2AA	0x6EEB	#CJK UNIFIED IDEOGRAPH
+0xE2AB	0x6F07	#CJK UNIFIED IDEOGRAPH
+0xE2AC	0x6F0E	#CJK UNIFIED IDEOGRAPH
+0xE2AD	0x6F43	#CJK UNIFIED IDEOGRAPH
+0xE2AE	0x6F05	#CJK UNIFIED IDEOGRAPH
+0xE2AF	0x6EFD	#CJK UNIFIED IDEOGRAPH
+0xE2B0	0x6EF6	#CJK UNIFIED IDEOGRAPH
+0xE2B1	0x6F39	#CJK UNIFIED IDEOGRAPH
+0xE2B2	0x6F1C	#CJK UNIFIED IDEOGRAPH
+0xE2B3	0x6EFC	#CJK UNIFIED IDEOGRAPH
+0xE2B4	0x6F3A	#CJK UNIFIED IDEOGRAPH
+0xE2B5	0x6F1F	#CJK UNIFIED IDEOGRAPH
+0xE2B6	0x6F0D	#CJK UNIFIED IDEOGRAPH
+0xE2B7	0x6F1E	#CJK UNIFIED IDEOGRAPH
+0xE2B8	0x6F08	#CJK UNIFIED IDEOGRAPH
+0xE2B9	0x6F21	#CJK UNIFIED IDEOGRAPH
+0xE2BA	0x7187	#CJK UNIFIED IDEOGRAPH
+0xE2BB	0x7190	#CJK UNIFIED IDEOGRAPH
+0xE2BC	0x7189	#CJK UNIFIED IDEOGRAPH
+0xE2BD	0x7180	#CJK UNIFIED IDEOGRAPH
+0xE2BE	0x7185	#CJK UNIFIED IDEOGRAPH
+0xE2BF	0x7182	#CJK UNIFIED IDEOGRAPH
+0xE2C0	0x718F	#CJK UNIFIED IDEOGRAPH
+0xE2C1	0x717B	#CJK UNIFIED IDEOGRAPH
+0xE2C2	0x7186	#CJK UNIFIED IDEOGRAPH
+0xE2C3	0x7181	#CJK UNIFIED IDEOGRAPH
+0xE2C4	0x7197	#CJK UNIFIED IDEOGRAPH
+0xE2C5	0x7244	#CJK UNIFIED IDEOGRAPH
+0xE2C6	0x7253	#CJK UNIFIED IDEOGRAPH
+0xE2C7	0x7297	#CJK UNIFIED IDEOGRAPH
+0xE2C8	0x7295	#CJK UNIFIED IDEOGRAPH
+0xE2C9	0x7293	#CJK UNIFIED IDEOGRAPH
+0xE2CA	0x7343	#CJK UNIFIED IDEOGRAPH
+0xE2CB	0x734D	#CJK UNIFIED IDEOGRAPH
+0xE2CC	0x7351	#CJK UNIFIED IDEOGRAPH
+0xE2CD	0x734C	#CJK UNIFIED IDEOGRAPH
+0xE2CE	0x7462	#CJK UNIFIED IDEOGRAPH
+0xE2CF	0x7473	#CJK UNIFIED IDEOGRAPH
+0xE2D0	0x7471	#CJK UNIFIED IDEOGRAPH
+0xE2D1	0x7475	#CJK UNIFIED IDEOGRAPH
+0xE2D2	0x7472	#CJK UNIFIED IDEOGRAPH
+0xE2D3	0x7467	#CJK UNIFIED IDEOGRAPH
+0xE2D4	0x746E	#CJK UNIFIED IDEOGRAPH
+0xE2D5	0x7500	#CJK UNIFIED IDEOGRAPH
+0xE2D6	0x7502	#CJK UNIFIED IDEOGRAPH
+0xE2D7	0x7503	#CJK UNIFIED IDEOGRAPH
+0xE2D8	0x757D	#CJK UNIFIED IDEOGRAPH
+0xE2D9	0x7590	#CJK UNIFIED IDEOGRAPH
+0xE2DA	0x7616	#CJK UNIFIED IDEOGRAPH
+0xE2DB	0x7608	#CJK UNIFIED IDEOGRAPH
+0xE2DC	0x760C	#CJK UNIFIED IDEOGRAPH
+0xE2DD	0x7615	#CJK UNIFIED IDEOGRAPH
+0xE2DE	0x7611	#CJK UNIFIED IDEOGRAPH
+0xE2DF	0x760A	#CJK UNIFIED IDEOGRAPH
+0xE2E0	0x7614	#CJK UNIFIED IDEOGRAPH
+0xE2E1	0x76B8	#CJK UNIFIED IDEOGRAPH
+0xE2E2	0x7781	#CJK UNIFIED IDEOGRAPH
+0xE2E3	0x777C	#CJK UNIFIED IDEOGRAPH
+0xE2E4	0x7785	#CJK UNIFIED IDEOGRAPH
+0xE2E5	0x7782	#CJK UNIFIED IDEOGRAPH
+0xE2E6	0x776E	#CJK UNIFIED IDEOGRAPH
+0xE2E7	0x7780	#CJK UNIFIED IDEOGRAPH
+0xE2E8	0x776F	#CJK UNIFIED IDEOGRAPH
+0xE2E9	0x777E	#CJK UNIFIED IDEOGRAPH
+0xE2EA	0x7783	#CJK UNIFIED IDEOGRAPH
+0xE2EB	0x78B2	#CJK UNIFIED IDEOGRAPH
+0xE2EC	0x78AA	#CJK UNIFIED IDEOGRAPH
+0xE2ED	0x78B4	#CJK UNIFIED IDEOGRAPH
+0xE2EE	0x78AD	#CJK UNIFIED IDEOGRAPH
+0xE2EF	0x78A8	#CJK UNIFIED IDEOGRAPH
+0xE2F0	0x787E	#CJK UNIFIED IDEOGRAPH
+0xE2F1	0x78AB	#CJK UNIFIED IDEOGRAPH
+0xE2F2	0x789E	#CJK UNIFIED IDEOGRAPH
+0xE2F3	0x78A5	#CJK UNIFIED IDEOGRAPH
+0xE2F4	0x78A0	#CJK UNIFIED IDEOGRAPH
+0xE2F5	0x78AC	#CJK UNIFIED IDEOGRAPH
+0xE2F6	0x78A2	#CJK UNIFIED IDEOGRAPH
+0xE2F7	0x78A4	#CJK UNIFIED IDEOGRAPH
+0xE2F8	0x7998	#CJK UNIFIED IDEOGRAPH
+0xE2F9	0x798A	#CJK UNIFIED IDEOGRAPH
+0xE2FA	0x798B	#CJK UNIFIED IDEOGRAPH
+0xE2FB	0x7996	#CJK UNIFIED IDEOGRAPH
+0xE2FC	0x7995	#CJK UNIFIED IDEOGRAPH
+0xE2FD	0x7994	#CJK UNIFIED IDEOGRAPH
+0xE2FE	0x7993	#CJK UNIFIED IDEOGRAPH
+0xE340	0x7997	#CJK UNIFIED IDEOGRAPH
+0xE341	0x7988	#CJK UNIFIED IDEOGRAPH
+0xE342	0x7992	#CJK UNIFIED IDEOGRAPH
+0xE343	0x7990	#CJK UNIFIED IDEOGRAPH
+0xE344	0x7A2B	#CJK UNIFIED IDEOGRAPH
+0xE345	0x7A4A	#CJK UNIFIED IDEOGRAPH
+0xE346	0x7A30	#CJK UNIFIED IDEOGRAPH
+0xE347	0x7A2F	#CJK UNIFIED IDEOGRAPH
+0xE348	0x7A28	#CJK UNIFIED IDEOGRAPH
+0xE349	0x7A26	#CJK UNIFIED IDEOGRAPH
+0xE34A	0x7AA8	#CJK UNIFIED IDEOGRAPH
+0xE34B	0x7AAB	#CJK UNIFIED IDEOGRAPH
+0xE34C	0x7AAC	#CJK UNIFIED IDEOGRAPH
+0xE34D	0x7AEE	#CJK UNIFIED IDEOGRAPH
+0xE34E	0x7B88	#CJK UNIFIED IDEOGRAPH
+0xE34F	0x7B9C	#CJK UNIFIED IDEOGRAPH
+0xE350	0x7B8A	#CJK UNIFIED IDEOGRAPH
+0xE351	0x7B91	#CJK UNIFIED IDEOGRAPH
+0xE352	0x7B90	#CJK UNIFIED IDEOGRAPH
+0xE353	0x7B96	#CJK UNIFIED IDEOGRAPH
+0xE354	0x7B8D	#CJK UNIFIED IDEOGRAPH
+0xE355	0x7B8C	#CJK UNIFIED IDEOGRAPH
+0xE356	0x7B9B	#CJK UNIFIED IDEOGRAPH
+0xE357	0x7B8E	#CJK UNIFIED IDEOGRAPH
+0xE358	0x7B85	#CJK UNIFIED IDEOGRAPH
+0xE359	0x7B98	#CJK UNIFIED IDEOGRAPH
+0xE35A	0x5284	#CJK UNIFIED IDEOGRAPH
+0xE35B	0x7B99	#CJK UNIFIED IDEOGRAPH
+0xE35C	0x7BA4	#CJK UNIFIED IDEOGRAPH
+0xE35D	0x7B82	#CJK UNIFIED IDEOGRAPH
+0xE35E	0x7CBB	#CJK UNIFIED IDEOGRAPH
+0xE35F	0x7CBF	#CJK UNIFIED IDEOGRAPH
+0xE360	0x7CBC	#CJK UNIFIED IDEOGRAPH
+0xE361	0x7CBA	#CJK UNIFIED IDEOGRAPH
+0xE362	0x7DA7	#CJK UNIFIED IDEOGRAPH
+0xE363	0x7DB7	#CJK UNIFIED IDEOGRAPH
+0xE364	0x7DC2	#CJK UNIFIED IDEOGRAPH
+0xE365	0x7DA3	#CJK UNIFIED IDEOGRAPH
+0xE366	0x7DAA	#CJK UNIFIED IDEOGRAPH
+0xE367	0x7DC1	#CJK UNIFIED IDEOGRAPH
+0xE368	0x7DC0	#CJK UNIFIED IDEOGRAPH
+0xE369	0x7DC5	#CJK UNIFIED IDEOGRAPH
+0xE36A	0x7D9D	#CJK UNIFIED IDEOGRAPH
+0xE36B	0x7DCE	#CJK UNIFIED IDEOGRAPH
+0xE36C	0x7DC4	#CJK UNIFIED IDEOGRAPH
+0xE36D	0x7DC6	#CJK UNIFIED IDEOGRAPH
+0xE36E	0x7DCB	#CJK UNIFIED IDEOGRAPH
+0xE36F	0x7DCC	#CJK UNIFIED IDEOGRAPH
+0xE370	0x7DAF	#CJK UNIFIED IDEOGRAPH
+0xE371	0x7DB9	#CJK UNIFIED IDEOGRAPH
+0xE372	0x7D96	#CJK UNIFIED IDEOGRAPH
+0xE373	0x7DBC	#CJK UNIFIED IDEOGRAPH
+0xE374	0x7D9F	#CJK UNIFIED IDEOGRAPH
+0xE375	0x7DA6	#CJK UNIFIED IDEOGRAPH
+0xE376	0x7DAE	#CJK UNIFIED IDEOGRAPH
+0xE377	0x7DA9	#CJK UNIFIED IDEOGRAPH
+0xE378	0x7DA1	#CJK UNIFIED IDEOGRAPH
+0xE379	0x7DC9	#CJK UNIFIED IDEOGRAPH
+0xE37A	0x7F73	#CJK UNIFIED IDEOGRAPH
+0xE37B	0x7FE2	#CJK UNIFIED IDEOGRAPH
+0xE37C	0x7FE3	#CJK UNIFIED IDEOGRAPH
+0xE37D	0x7FE5	#CJK UNIFIED IDEOGRAPH
+0xE37E	0x7FDE	#CJK UNIFIED IDEOGRAPH
+0xE3A1	0x8024	#CJK UNIFIED IDEOGRAPH
+0xE3A2	0x805D	#CJK UNIFIED IDEOGRAPH
+0xE3A3	0x805C	#CJK UNIFIED IDEOGRAPH
+0xE3A4	0x8189	#CJK UNIFIED IDEOGRAPH
+0xE3A5	0x8186	#CJK UNIFIED IDEOGRAPH
+0xE3A6	0x8183	#CJK UNIFIED IDEOGRAPH
+0xE3A7	0x8187	#CJK UNIFIED IDEOGRAPH
+0xE3A8	0x818D	#CJK UNIFIED IDEOGRAPH
+0xE3A9	0x818C	#CJK UNIFIED IDEOGRAPH
+0xE3AA	0x818B	#CJK UNIFIED IDEOGRAPH
+0xE3AB	0x8215	#CJK UNIFIED IDEOGRAPH
+0xE3AC	0x8497	#CJK UNIFIED IDEOGRAPH
+0xE3AD	0x84A4	#CJK UNIFIED IDEOGRAPH
+0xE3AE	0x84A1	#CJK UNIFIED IDEOGRAPH
+0xE3AF	0x849F	#CJK UNIFIED IDEOGRAPH
+0xE3B0	0x84BA	#CJK UNIFIED IDEOGRAPH
+0xE3B1	0x84CE	#CJK UNIFIED IDEOGRAPH
+0xE3B2	0x84C2	#CJK UNIFIED IDEOGRAPH
+0xE3B3	0x84AC	#CJK UNIFIED IDEOGRAPH
+0xE3B4	0x84AE	#CJK UNIFIED IDEOGRAPH
+0xE3B5	0x84AB	#CJK UNIFIED IDEOGRAPH
+0xE3B6	0x84B9	#CJK UNIFIED IDEOGRAPH
+0xE3B7	0x84B4	#CJK UNIFIED IDEOGRAPH
+0xE3B8	0x84C1	#CJK UNIFIED IDEOGRAPH
+0xE3B9	0x84CD	#CJK UNIFIED IDEOGRAPH
+0xE3BA	0x84AA	#CJK UNIFIED IDEOGRAPH
+0xE3BB	0x849A	#CJK UNIFIED IDEOGRAPH
+0xE3BC	0x84B1	#CJK UNIFIED IDEOGRAPH
+0xE3BD	0x84D0	#CJK UNIFIED IDEOGRAPH
+0xE3BE	0x849D	#CJK UNIFIED IDEOGRAPH
+0xE3BF	0x84A7	#CJK UNIFIED IDEOGRAPH
+0xE3C0	0x84BB	#CJK UNIFIED IDEOGRAPH
+0xE3C1	0x84A2	#CJK UNIFIED IDEOGRAPH
+0xE3C2	0x8494	#CJK UNIFIED IDEOGRAPH
+0xE3C3	0x84C7	#CJK UNIFIED IDEOGRAPH
+0xE3C4	0x84CC	#CJK UNIFIED IDEOGRAPH
+0xE3C5	0x849B	#CJK UNIFIED IDEOGRAPH
+0xE3C6	0x84A9	#CJK UNIFIED IDEOGRAPH
+0xE3C7	0x84AF	#CJK UNIFIED IDEOGRAPH
+0xE3C8	0x84A8	#CJK UNIFIED IDEOGRAPH
+0xE3C9	0x84D6	#CJK UNIFIED IDEOGRAPH
+0xE3CA	0x8498	#CJK UNIFIED IDEOGRAPH
+0xE3CB	0x84B6	#CJK UNIFIED IDEOGRAPH
+0xE3CC	0x84CF	#CJK UNIFIED IDEOGRAPH
+0xE3CD	0x84A0	#CJK UNIFIED IDEOGRAPH
+0xE3CE	0x84D7	#CJK UNIFIED IDEOGRAPH
+0xE3CF	0x84D4	#CJK UNIFIED IDEOGRAPH
+0xE3D0	0x84D2	#CJK UNIFIED IDEOGRAPH
+0xE3D1	0x84DB	#CJK UNIFIED IDEOGRAPH
+0xE3D2	0x84B0	#CJK UNIFIED IDEOGRAPH
+0xE3D3	0x8491	#CJK UNIFIED IDEOGRAPH
+0xE3D4	0x8661	#CJK UNIFIED IDEOGRAPH
+0xE3D5	0x8733	#CJK UNIFIED IDEOGRAPH
+0xE3D6	0x8723	#CJK UNIFIED IDEOGRAPH
+0xE3D7	0x8728	#CJK UNIFIED IDEOGRAPH
+0xE3D8	0x876B	#CJK UNIFIED IDEOGRAPH
+0xE3D9	0x8740	#CJK UNIFIED IDEOGRAPH
+0xE3DA	0x872E	#CJK UNIFIED IDEOGRAPH
+0xE3DB	0x871E	#CJK UNIFIED IDEOGRAPH
+0xE3DC	0x8721	#CJK UNIFIED IDEOGRAPH
+0xE3DD	0x8719	#CJK UNIFIED IDEOGRAPH
+0xE3DE	0x871B	#CJK UNIFIED IDEOGRAPH
+0xE3DF	0x8743	#CJK UNIFIED IDEOGRAPH
+0xE3E0	0x872C	#CJK UNIFIED IDEOGRAPH
+0xE3E1	0x8741	#CJK UNIFIED IDEOGRAPH
+0xE3E2	0x873E	#CJK UNIFIED IDEOGRAPH
+0xE3E3	0x8746	#CJK UNIFIED IDEOGRAPH
+0xE3E4	0x8720	#CJK UNIFIED IDEOGRAPH
+0xE3E5	0x8732	#CJK UNIFIED IDEOGRAPH
+0xE3E6	0x872A	#CJK UNIFIED IDEOGRAPH
+0xE3E7	0x872D	#CJK UNIFIED IDEOGRAPH
+0xE3E8	0x873C	#CJK UNIFIED IDEOGRAPH
+0xE3E9	0x8712	#CJK UNIFIED IDEOGRAPH
+0xE3EA	0x873A	#CJK UNIFIED IDEOGRAPH
+0xE3EB	0x8731	#CJK UNIFIED IDEOGRAPH
+0xE3EC	0x8735	#CJK UNIFIED IDEOGRAPH
+0xE3ED	0x8742	#CJK UNIFIED IDEOGRAPH
+0xE3EE	0x8726	#CJK UNIFIED IDEOGRAPH
+0xE3EF	0x8727	#CJK UNIFIED IDEOGRAPH
+0xE3F0	0x8738	#CJK UNIFIED IDEOGRAPH
+0xE3F1	0x8724	#CJK UNIFIED IDEOGRAPH
+0xE3F2	0x871A	#CJK UNIFIED IDEOGRAPH
+0xE3F3	0x8730	#CJK UNIFIED IDEOGRAPH
+0xE3F4	0x8711	#CJK UNIFIED IDEOGRAPH
+0xE3F5	0x88F7	#CJK UNIFIED IDEOGRAPH
+0xE3F6	0x88E7	#CJK UNIFIED IDEOGRAPH
+0xE3F7	0x88F1	#CJK UNIFIED IDEOGRAPH
+0xE3F8	0x88F2	#CJK UNIFIED IDEOGRAPH
+0xE3F9	0x88FA	#CJK UNIFIED IDEOGRAPH
+0xE3FA	0x88FE	#CJK UNIFIED IDEOGRAPH
+0xE3FB	0x88EE	#CJK UNIFIED IDEOGRAPH
+0xE3FC	0x88FC	#CJK UNIFIED IDEOGRAPH
+0xE3FD	0x88F6	#CJK UNIFIED IDEOGRAPH
+0xE3FE	0x88FB	#CJK UNIFIED IDEOGRAPH
+0xE440	0x88F0	#CJK UNIFIED IDEOGRAPH
+0xE441	0x88EC	#CJK UNIFIED IDEOGRAPH
+0xE442	0x88EB	#CJK UNIFIED IDEOGRAPH
+0xE443	0x899D	#CJK UNIFIED IDEOGRAPH
+0xE444	0x89A1	#CJK UNIFIED IDEOGRAPH
+0xE445	0x899F	#CJK UNIFIED IDEOGRAPH
+0xE446	0x899E	#CJK UNIFIED IDEOGRAPH
+0xE447	0x89E9	#CJK UNIFIED IDEOGRAPH
+0xE448	0x89EB	#CJK UNIFIED IDEOGRAPH
+0xE449	0x89E8	#CJK UNIFIED IDEOGRAPH
+0xE44A	0x8AAB	#CJK UNIFIED IDEOGRAPH
+0xE44B	0x8A99	#CJK UNIFIED IDEOGRAPH
+0xE44C	0x8A8B	#CJK UNIFIED IDEOGRAPH
+0xE44D	0x8A92	#CJK UNIFIED IDEOGRAPH
+0xE44E	0x8A8F	#CJK UNIFIED IDEOGRAPH
+0xE44F	0x8A96	#CJK UNIFIED IDEOGRAPH
+0xE450	0x8C3D	#CJK UNIFIED IDEOGRAPH
+0xE451	0x8C68	#CJK UNIFIED IDEOGRAPH
+0xE452	0x8C69	#CJK UNIFIED IDEOGRAPH
+0xE453	0x8CD5	#CJK UNIFIED IDEOGRAPH
+0xE454	0x8CCF	#CJK UNIFIED IDEOGRAPH
+0xE455	0x8CD7	#CJK UNIFIED IDEOGRAPH
+0xE456	0x8D96	#CJK UNIFIED IDEOGRAPH
+0xE457	0x8E09	#CJK UNIFIED IDEOGRAPH
+0xE458	0x8E02	#CJK UNIFIED IDEOGRAPH
+0xE459	0x8DFF	#CJK UNIFIED IDEOGRAPH
+0xE45A	0x8E0D	#CJK UNIFIED IDEOGRAPH
+0xE45B	0x8DFD	#CJK UNIFIED IDEOGRAPH
+0xE45C	0x8E0A	#CJK UNIFIED IDEOGRAPH
+0xE45D	0x8E03	#CJK UNIFIED IDEOGRAPH
+0xE45E	0x8E07	#CJK UNIFIED IDEOGRAPH
+0xE45F	0x8E06	#CJK UNIFIED IDEOGRAPH
+0xE460	0x8E05	#CJK UNIFIED IDEOGRAPH
+0xE461	0x8DFE	#CJK UNIFIED IDEOGRAPH
+0xE462	0x8E00	#CJK UNIFIED IDEOGRAPH
+0xE463	0x8E04	#CJK UNIFIED IDEOGRAPH
+0xE464	0x8F10	#CJK UNIFIED IDEOGRAPH
+0xE465	0x8F11	#CJK UNIFIED IDEOGRAPH
+0xE466	0x8F0E	#CJK UNIFIED IDEOGRAPH
+0xE467	0x8F0D	#CJK UNIFIED IDEOGRAPH
+0xE468	0x9123	#CJK UNIFIED IDEOGRAPH
+0xE469	0x911C	#CJK UNIFIED IDEOGRAPH
+0xE46A	0x9120	#CJK UNIFIED IDEOGRAPH
+0xE46B	0x9122	#CJK UNIFIED IDEOGRAPH
+0xE46C	0x911F	#CJK UNIFIED IDEOGRAPH
+0xE46D	0x911D	#CJK UNIFIED IDEOGRAPH
+0xE46E	0x911A	#CJK UNIFIED IDEOGRAPH
+0xE46F	0x9124	#CJK UNIFIED IDEOGRAPH
+0xE470	0x9121	#CJK UNIFIED IDEOGRAPH
+0xE471	0x911B	#CJK UNIFIED IDEOGRAPH
+0xE472	0x917A	#CJK UNIFIED IDEOGRAPH
+0xE473	0x9172	#CJK UNIFIED IDEOGRAPH
+0xE474	0x9179	#CJK UNIFIED IDEOGRAPH
+0xE475	0x9173	#CJK UNIFIED IDEOGRAPH
+0xE476	0x92A5	#CJK UNIFIED IDEOGRAPH
+0xE477	0x92A4	#CJK UNIFIED IDEOGRAPH
+0xE478	0x9276	#CJK UNIFIED IDEOGRAPH
+0xE479	0x929B	#CJK UNIFIED IDEOGRAPH
+0xE47A	0x927A	#CJK UNIFIED IDEOGRAPH
+0xE47B	0x92A0	#CJK UNIFIED IDEOGRAPH
+0xE47C	0x9294	#CJK UNIFIED IDEOGRAPH
+0xE47D	0x92AA	#CJK UNIFIED IDEOGRAPH
+0xE47E	0x928D	#CJK UNIFIED IDEOGRAPH
+0xE4A1	0x92A6	#CJK UNIFIED IDEOGRAPH
+0xE4A2	0x929A	#CJK UNIFIED IDEOGRAPH
+0xE4A3	0x92AB	#CJK UNIFIED IDEOGRAPH
+0xE4A4	0x9279	#CJK UNIFIED IDEOGRAPH
+0xE4A5	0x9297	#CJK UNIFIED IDEOGRAPH
+0xE4A6	0x927F	#CJK UNIFIED IDEOGRAPH
+0xE4A7	0x92A3	#CJK UNIFIED IDEOGRAPH
+0xE4A8	0x92EE	#CJK UNIFIED IDEOGRAPH
+0xE4A9	0x928E	#CJK UNIFIED IDEOGRAPH
+0xE4AA	0x9282	#CJK UNIFIED IDEOGRAPH
+0xE4AB	0x9295	#CJK UNIFIED IDEOGRAPH
+0xE4AC	0x92A2	#CJK UNIFIED IDEOGRAPH
+0xE4AD	0x927D	#CJK UNIFIED IDEOGRAPH
+0xE4AE	0x9288	#CJK UNIFIED IDEOGRAPH
+0xE4AF	0x92A1	#CJK UNIFIED IDEOGRAPH
+0xE4B0	0x928A	#CJK UNIFIED IDEOGRAPH
+0xE4B1	0x9286	#CJK UNIFIED IDEOGRAPH
+0xE4B2	0x928C	#CJK UNIFIED IDEOGRAPH
+0xE4B3	0x9299	#CJK UNIFIED IDEOGRAPH
+0xE4B4	0x92A7	#CJK UNIFIED IDEOGRAPH
+0xE4B5	0x927E	#CJK UNIFIED IDEOGRAPH
+0xE4B6	0x9287	#CJK UNIFIED IDEOGRAPH
+0xE4B7	0x92A9	#CJK UNIFIED IDEOGRAPH
+0xE4B8	0x929D	#CJK UNIFIED IDEOGRAPH
+0xE4B9	0x928B	#CJK UNIFIED IDEOGRAPH
+0xE4BA	0x922D	#CJK UNIFIED IDEOGRAPH
+0xE4BB	0x969E	#CJK UNIFIED IDEOGRAPH
+0xE4BC	0x96A1	#CJK UNIFIED IDEOGRAPH
+0xE4BD	0x96FF	#CJK UNIFIED IDEOGRAPH
+0xE4BE	0x9758	#CJK UNIFIED IDEOGRAPH
+0xE4BF	0x977D	#CJK UNIFIED IDEOGRAPH
+0xE4C0	0x977A	#CJK UNIFIED IDEOGRAPH
+0xE4C1	0x977E	#CJK UNIFIED IDEOGRAPH
+0xE4C2	0x9783	#CJK UNIFIED IDEOGRAPH
+0xE4C3	0x9780	#CJK UNIFIED IDEOGRAPH
+0xE4C4	0x9782	#CJK UNIFIED IDEOGRAPH
+0xE4C5	0x977B	#CJK UNIFIED IDEOGRAPH
+0xE4C6	0x9784	#CJK UNIFIED IDEOGRAPH
+0xE4C7	0x9781	#CJK UNIFIED IDEOGRAPH
+0xE4C8	0x977F	#CJK UNIFIED IDEOGRAPH
+0xE4C9	0x97CE	#CJK UNIFIED IDEOGRAPH
+0xE4CA	0x97CD	#CJK UNIFIED IDEOGRAPH
+0xE4CB	0x9816	#CJK UNIFIED IDEOGRAPH
+0xE4CC	0x98AD	#CJK UNIFIED IDEOGRAPH
+0xE4CD	0x98AE	#CJK UNIFIED IDEOGRAPH
+0xE4CE	0x9902	#CJK UNIFIED IDEOGRAPH
+0xE4CF	0x9900	#CJK UNIFIED IDEOGRAPH
+0xE4D0	0x9907	#CJK UNIFIED IDEOGRAPH
+0xE4D1	0x999D	#CJK UNIFIED IDEOGRAPH
+0xE4D2	0x999C	#CJK UNIFIED IDEOGRAPH
+0xE4D3	0x99C3	#CJK UNIFIED IDEOGRAPH
+0xE4D4	0x99B9	#CJK UNIFIED IDEOGRAPH
+0xE4D5	0x99BB	#CJK UNIFIED IDEOGRAPH
+0xE4D6	0x99BA	#CJK UNIFIED IDEOGRAPH
+0xE4D7	0x99C2	#CJK UNIFIED IDEOGRAPH
+0xE4D8	0x99BD	#CJK UNIFIED IDEOGRAPH
+0xE4D9	0x99C7	#CJK UNIFIED IDEOGRAPH
+0xE4DA	0x9AB1	#CJK UNIFIED IDEOGRAPH
+0xE4DB	0x9AE3	#CJK UNIFIED IDEOGRAPH
+0xE4DC	0x9AE7	#CJK UNIFIED IDEOGRAPH
+0xE4DD	0x9B3E	#CJK UNIFIED IDEOGRAPH
+0xE4DE	0x9B3F	#CJK UNIFIED IDEOGRAPH
+0xE4DF	0x9B60	#CJK UNIFIED IDEOGRAPH
+0xE4E0	0x9B61	#CJK UNIFIED IDEOGRAPH
+0xE4E1	0x9B5F	#CJK UNIFIED IDEOGRAPH
+0xE4E2	0x9CF1	#CJK UNIFIED IDEOGRAPH
+0xE4E3	0x9CF2	#CJK UNIFIED IDEOGRAPH
+0xE4E4	0x9CF5	#CJK UNIFIED IDEOGRAPH
+0xE4E5	0x9EA7	#CJK UNIFIED IDEOGRAPH
+0xE4E6	0x50FF	#CJK UNIFIED IDEOGRAPH
+0xE4E7	0x5103	#CJK UNIFIED IDEOGRAPH
+0xE4E8	0x5130	#CJK UNIFIED IDEOGRAPH
+0xE4E9	0x50F8	#CJK UNIFIED IDEOGRAPH
+0xE4EA	0x5106	#CJK UNIFIED IDEOGRAPH
+0xE4EB	0x5107	#CJK UNIFIED IDEOGRAPH
+0xE4EC	0x50F6	#CJK UNIFIED IDEOGRAPH
+0xE4ED	0x50FE	#CJK UNIFIED IDEOGRAPH
+0xE4EE	0x510B	#CJK UNIFIED IDEOGRAPH
+0xE4EF	0x510C	#CJK UNIFIED IDEOGRAPH
+0xE4F0	0x50FD	#CJK UNIFIED IDEOGRAPH
+0xE4F1	0x510A	#CJK UNIFIED IDEOGRAPH
+0xE4F2	0x528B	#CJK UNIFIED IDEOGRAPH
+0xE4F3	0x528C	#CJK UNIFIED IDEOGRAPH
+0xE4F4	0x52F1	#CJK UNIFIED IDEOGRAPH
+0xE4F5	0x52EF	#CJK UNIFIED IDEOGRAPH
+0xE4F6	0x5648	#CJK UNIFIED IDEOGRAPH
+0xE4F7	0x5642	#CJK UNIFIED IDEOGRAPH
+0xE4F8	0x564C	#CJK UNIFIED IDEOGRAPH
+0xE4F9	0x5635	#CJK UNIFIED IDEOGRAPH
+0xE4FA	0x5641	#CJK UNIFIED IDEOGRAPH
+0xE4FB	0x564A	#CJK UNIFIED IDEOGRAPH
+0xE4FC	0x5649	#CJK UNIFIED IDEOGRAPH
+0xE4FD	0x5646	#CJK UNIFIED IDEOGRAPH
+0xE4FE	0x5658	#CJK UNIFIED IDEOGRAPH
+0xE540	0x565A	#CJK UNIFIED IDEOGRAPH
+0xE541	0x5640	#CJK UNIFIED IDEOGRAPH
+0xE542	0x5633	#CJK UNIFIED IDEOGRAPH
+0xE543	0x563D	#CJK UNIFIED IDEOGRAPH
+0xE544	0x562C	#CJK UNIFIED IDEOGRAPH
+0xE545	0x563E	#CJK UNIFIED IDEOGRAPH
+0xE546	0x5638	#CJK UNIFIED IDEOGRAPH
+0xE547	0x562A	#CJK UNIFIED IDEOGRAPH
+0xE548	0x563A	#CJK UNIFIED IDEOGRAPH
+0xE549	0x571A	#CJK UNIFIED IDEOGRAPH
+0xE54A	0x58AB	#CJK UNIFIED IDEOGRAPH
+0xE54B	0x589D	#CJK UNIFIED IDEOGRAPH
+0xE54C	0x58B1	#CJK UNIFIED IDEOGRAPH
+0xE54D	0x58A0	#CJK UNIFIED IDEOGRAPH
+0xE54E	0x58A3	#CJK UNIFIED IDEOGRAPH
+0xE54F	0x58AF	#CJK UNIFIED IDEOGRAPH
+0xE550	0x58AC	#CJK UNIFIED IDEOGRAPH
+0xE551	0x58A5	#CJK UNIFIED IDEOGRAPH
+0xE552	0x58A1	#CJK UNIFIED IDEOGRAPH
+0xE553	0x58FF	#CJK UNIFIED IDEOGRAPH
+0xE554	0x5AFF	#CJK UNIFIED IDEOGRAPH
+0xE555	0x5AF4	#CJK UNIFIED IDEOGRAPH
+0xE556	0x5AFD	#CJK UNIFIED IDEOGRAPH
+0xE557	0x5AF7	#CJK UNIFIED IDEOGRAPH
+0xE558	0x5AF6	#CJK UNIFIED IDEOGRAPH
+0xE559	0x5B03	#CJK UNIFIED IDEOGRAPH
+0xE55A	0x5AF8	#CJK UNIFIED IDEOGRAPH
+0xE55B	0x5B02	#CJK UNIFIED IDEOGRAPH
+0xE55C	0x5AF9	#CJK UNIFIED IDEOGRAPH
+0xE55D	0x5B01	#CJK UNIFIED IDEOGRAPH
+0xE55E	0x5B07	#CJK UNIFIED IDEOGRAPH
+0xE55F	0x5B05	#CJK UNIFIED IDEOGRAPH
+0xE560	0x5B0F	#CJK UNIFIED IDEOGRAPH
+0xE561	0x5C67	#CJK UNIFIED IDEOGRAPH
+0xE562	0x5D99	#CJK UNIFIED IDEOGRAPH
+0xE563	0x5D97	#CJK UNIFIED IDEOGRAPH
+0xE564	0x5D9F	#CJK UNIFIED IDEOGRAPH
+0xE565	0x5D92	#CJK UNIFIED IDEOGRAPH
+0xE566	0x5DA2	#CJK UNIFIED IDEOGRAPH
+0xE567	0x5D93	#CJK UNIFIED IDEOGRAPH
+0xE568	0x5D95	#CJK UNIFIED IDEOGRAPH
+0xE569	0x5DA0	#CJK UNIFIED IDEOGRAPH
+0xE56A	0x5D9C	#CJK UNIFIED IDEOGRAPH
+0xE56B	0x5DA1	#CJK UNIFIED IDEOGRAPH
+0xE56C	0x5D9A	#CJK UNIFIED IDEOGRAPH
+0xE56D	0x5D9E	#CJK UNIFIED IDEOGRAPH
+0xE56E	0x5E69	#CJK UNIFIED IDEOGRAPH
+0xE56F	0x5E5D	#CJK UNIFIED IDEOGRAPH
+0xE570	0x5E60	#CJK UNIFIED IDEOGRAPH
+0xE571	0x5E5C	#CJK UNIFIED IDEOGRAPH
+0xE572	0x7DF3	#CJK UNIFIED IDEOGRAPH
+0xE573	0x5EDB	#CJK UNIFIED IDEOGRAPH
+0xE574	0x5EDE	#CJK UNIFIED IDEOGRAPH
+0xE575	0x5EE1	#CJK UNIFIED IDEOGRAPH
+0xE576	0x5F49	#CJK UNIFIED IDEOGRAPH
+0xE577	0x5FB2	#CJK UNIFIED IDEOGRAPH
+0xE578	0x618B	#CJK UNIFIED IDEOGRAPH
+0xE579	0x6183	#CJK UNIFIED IDEOGRAPH
+0xE57A	0x6179	#CJK UNIFIED IDEOGRAPH
+0xE57B	0x61B1	#CJK UNIFIED IDEOGRAPH
+0xE57C	0x61B0	#CJK UNIFIED IDEOGRAPH
+0xE57D	0x61A2	#CJK UNIFIED IDEOGRAPH
+0xE57E	0x6189	#CJK UNIFIED IDEOGRAPH
+0xE5A1	0x619B	#CJK UNIFIED IDEOGRAPH
+0xE5A2	0x6193	#CJK UNIFIED IDEOGRAPH
+0xE5A3	0x61AF	#CJK UNIFIED IDEOGRAPH
+0xE5A4	0x61AD	#CJK UNIFIED IDEOGRAPH
+0xE5A5	0x619F	#CJK UNIFIED IDEOGRAPH
+0xE5A6	0x6192	#CJK UNIFIED IDEOGRAPH
+0xE5A7	0x61AA	#CJK UNIFIED IDEOGRAPH
+0xE5A8	0x61A1	#CJK UNIFIED IDEOGRAPH
+0xE5A9	0x618D	#CJK UNIFIED IDEOGRAPH
+0xE5AA	0x6166	#CJK UNIFIED IDEOGRAPH
+0xE5AB	0x61B3	#CJK UNIFIED IDEOGRAPH
+0xE5AC	0x622D	#CJK UNIFIED IDEOGRAPH
+0xE5AD	0x646E	#CJK UNIFIED IDEOGRAPH
+0xE5AE	0x6470	#CJK UNIFIED IDEOGRAPH
+0xE5AF	0x6496	#CJK UNIFIED IDEOGRAPH
+0xE5B0	0x64A0	#CJK UNIFIED IDEOGRAPH
+0xE5B1	0x6485	#CJK UNIFIED IDEOGRAPH
+0xE5B2	0x6497	#CJK UNIFIED IDEOGRAPH
+0xE5B3	0x649C	#CJK UNIFIED IDEOGRAPH
+0xE5B4	0x648F	#CJK UNIFIED IDEOGRAPH
+0xE5B5	0x648B	#CJK UNIFIED IDEOGRAPH
+0xE5B6	0x648A	#CJK UNIFIED IDEOGRAPH
+0xE5B7	0x648C	#CJK UNIFIED IDEOGRAPH
+0xE5B8	0x64A3	#CJK UNIFIED IDEOGRAPH
+0xE5B9	0x649F	#CJK UNIFIED IDEOGRAPH
+0xE5BA	0x6468	#CJK UNIFIED IDEOGRAPH
+0xE5BB	0x64B1	#CJK UNIFIED IDEOGRAPH
+0xE5BC	0x6498	#CJK UNIFIED IDEOGRAPH
+0xE5BD	0x6576	#CJK UNIFIED IDEOGRAPH
+0xE5BE	0x657A	#CJK UNIFIED IDEOGRAPH
+0xE5BF	0x6579	#CJK UNIFIED IDEOGRAPH
+0xE5C0	0x657B	#CJK UNIFIED IDEOGRAPH
+0xE5C1	0x65B2	#CJK UNIFIED IDEOGRAPH
+0xE5C2	0x65B3	#CJK UNIFIED IDEOGRAPH
+0xE5C3	0x66B5	#CJK UNIFIED IDEOGRAPH
+0xE5C4	0x66B0	#CJK UNIFIED IDEOGRAPH
+0xE5C5	0x66A9	#CJK UNIFIED IDEOGRAPH
+0xE5C6	0x66B2	#CJK UNIFIED IDEOGRAPH
+0xE5C7	0x66B7	#CJK UNIFIED IDEOGRAPH
+0xE5C8	0x66AA	#CJK UNIFIED IDEOGRAPH
+0xE5C9	0x66AF	#CJK UNIFIED IDEOGRAPH
+0xE5CA	0x6A00	#CJK UNIFIED IDEOGRAPH
+0xE5CB	0x6A06	#CJK UNIFIED IDEOGRAPH
+0xE5CC	0x6A17	#CJK UNIFIED IDEOGRAPH
+0xE5CD	0x69E5	#CJK UNIFIED IDEOGRAPH
+0xE5CE	0x69F8	#CJK UNIFIED IDEOGRAPH
+0xE5CF	0x6A15	#CJK UNIFIED IDEOGRAPH
+0xE5D0	0x69F1	#CJK UNIFIED IDEOGRAPH
+0xE5D1	0x69E4	#CJK UNIFIED IDEOGRAPH
+0xE5D2	0x6A20	#CJK UNIFIED IDEOGRAPH
+0xE5D3	0x69FF	#CJK UNIFIED IDEOGRAPH
+0xE5D4	0x69EC	#CJK UNIFIED IDEOGRAPH
+0xE5D5	0x69E2	#CJK UNIFIED IDEOGRAPH
+0xE5D6	0x6A1B	#CJK UNIFIED IDEOGRAPH
+0xE5D7	0x6A1D	#CJK UNIFIED IDEOGRAPH
+0xE5D8	0x69FE	#CJK UNIFIED IDEOGRAPH
+0xE5D9	0x6A27	#CJK UNIFIED IDEOGRAPH
+0xE5DA	0x69F2	#CJK UNIFIED IDEOGRAPH
+0xE5DB	0x69EE	#CJK UNIFIED IDEOGRAPH
+0xE5DC	0x6A14	#CJK UNIFIED IDEOGRAPH
+0xE5DD	0x69F7	#CJK UNIFIED IDEOGRAPH
+0xE5DE	0x69E7	#CJK UNIFIED IDEOGRAPH
+0xE5DF	0x6A40	#CJK UNIFIED IDEOGRAPH
+0xE5E0	0x6A08	#CJK UNIFIED IDEOGRAPH
+0xE5E1	0x69E6	#CJK UNIFIED IDEOGRAPH
+0xE5E2	0x69FB	#CJK UNIFIED IDEOGRAPH
+0xE5E3	0x6A0D	#CJK UNIFIED IDEOGRAPH
+0xE5E4	0x69FC	#CJK UNIFIED IDEOGRAPH
+0xE5E5	0x69EB	#CJK UNIFIED IDEOGRAPH
+0xE5E6	0x6A09	#CJK UNIFIED IDEOGRAPH
+0xE5E7	0x6A04	#CJK UNIFIED IDEOGRAPH
+0xE5E8	0x6A18	#CJK UNIFIED IDEOGRAPH
+0xE5E9	0x6A25	#CJK UNIFIED IDEOGRAPH
+0xE5EA	0x6A0F	#CJK UNIFIED IDEOGRAPH
+0xE5EB	0x69F6	#CJK UNIFIED IDEOGRAPH
+0xE5EC	0x6A26	#CJK UNIFIED IDEOGRAPH
+0xE5ED	0x6A07	#CJK UNIFIED IDEOGRAPH
+0xE5EE	0x69F4	#CJK UNIFIED IDEOGRAPH
+0xE5EF	0x6A16	#CJK UNIFIED IDEOGRAPH
+0xE5F0	0x6B51	#CJK UNIFIED IDEOGRAPH
+0xE5F1	0x6BA5	#CJK UNIFIED IDEOGRAPH
+0xE5F2	0x6BA3	#CJK UNIFIED IDEOGRAPH
+0xE5F3	0x6BA2	#CJK UNIFIED IDEOGRAPH
+0xE5F4	0x6BA6	#CJK UNIFIED IDEOGRAPH
+0xE5F5	0x6C01	#CJK UNIFIED IDEOGRAPH
+0xE5F6	0x6C00	#CJK UNIFIED IDEOGRAPH
+0xE5F7	0x6BFF	#CJK UNIFIED IDEOGRAPH
+0xE5F8	0x6C02	#CJK UNIFIED IDEOGRAPH
+0xE5F9	0x6F41	#CJK UNIFIED IDEOGRAPH
+0xE5FA	0x6F26	#CJK UNIFIED IDEOGRAPH
+0xE5FB	0x6F7E	#CJK UNIFIED IDEOGRAPH
+0xE5FC	0x6F87	#CJK UNIFIED IDEOGRAPH
+0xE5FD	0x6FC6	#CJK UNIFIED IDEOGRAPH
+0xE5FE	0x6F92	#CJK UNIFIED IDEOGRAPH
+0xE640	0x6F8D	#CJK UNIFIED IDEOGRAPH
+0xE641	0x6F89	#CJK UNIFIED IDEOGRAPH
+0xE642	0x6F8C	#CJK UNIFIED IDEOGRAPH
+0xE643	0x6F62	#CJK UNIFIED IDEOGRAPH
+0xE644	0x6F4F	#CJK UNIFIED IDEOGRAPH
+0xE645	0x6F85	#CJK UNIFIED IDEOGRAPH
+0xE646	0x6F5A	#CJK UNIFIED IDEOGRAPH
+0xE647	0x6F96	#CJK UNIFIED IDEOGRAPH
+0xE648	0x6F76	#CJK UNIFIED IDEOGRAPH
+0xE649	0x6F6C	#CJK UNIFIED IDEOGRAPH
+0xE64A	0x6F82	#CJK UNIFIED IDEOGRAPH
+0xE64B	0x6F55	#CJK UNIFIED IDEOGRAPH
+0xE64C	0x6F72	#CJK UNIFIED IDEOGRAPH
+0xE64D	0x6F52	#CJK UNIFIED IDEOGRAPH
+0xE64E	0x6F50	#CJK UNIFIED IDEOGRAPH
+0xE64F	0x6F57	#CJK UNIFIED IDEOGRAPH
+0xE650	0x6F94	#CJK UNIFIED IDEOGRAPH
+0xE651	0x6F93	#CJK UNIFIED IDEOGRAPH
+0xE652	0x6F5D	#CJK UNIFIED IDEOGRAPH
+0xE653	0x6F00	#CJK UNIFIED IDEOGRAPH
+0xE654	0x6F61	#CJK UNIFIED IDEOGRAPH
+0xE655	0x6F6B	#CJK UNIFIED IDEOGRAPH
+0xE656	0x6F7D	#CJK UNIFIED IDEOGRAPH
+0xE657	0x6F67	#CJK UNIFIED IDEOGRAPH
+0xE658	0x6F90	#CJK UNIFIED IDEOGRAPH
+0xE659	0x6F53	#CJK UNIFIED IDEOGRAPH
+0xE65A	0x6F8B	#CJK UNIFIED IDEOGRAPH
+0xE65B	0x6F69	#CJK UNIFIED IDEOGRAPH
+0xE65C	0x6F7F	#CJK UNIFIED IDEOGRAPH
+0xE65D	0x6F95	#CJK UNIFIED IDEOGRAPH
+0xE65E	0x6F63	#CJK UNIFIED IDEOGRAPH
+0xE65F	0x6F77	#CJK UNIFIED IDEOGRAPH
+0xE660	0x6F6A	#CJK UNIFIED IDEOGRAPH
+0xE661	0x6F7B	#CJK UNIFIED IDEOGRAPH
+0xE662	0x71B2	#CJK UNIFIED IDEOGRAPH
+0xE663	0x71AF	#CJK UNIFIED IDEOGRAPH
+0xE664	0x719B	#CJK UNIFIED IDEOGRAPH
+0xE665	0x71B0	#CJK UNIFIED IDEOGRAPH
+0xE666	0x71A0	#CJK UNIFIED IDEOGRAPH
+0xE667	0x719A	#CJK UNIFIED IDEOGRAPH
+0xE668	0x71A9	#CJK UNIFIED IDEOGRAPH
+0xE669	0x71B5	#CJK UNIFIED IDEOGRAPH
+0xE66A	0x719D	#CJK UNIFIED IDEOGRAPH
+0xE66B	0x71A5	#CJK UNIFIED IDEOGRAPH
+0xE66C	0x719E	#CJK UNIFIED IDEOGRAPH
+0xE66D	0x71A4	#CJK UNIFIED IDEOGRAPH
+0xE66E	0x71A1	#CJK UNIFIED IDEOGRAPH
+0xE66F	0x71AA	#CJK UNIFIED IDEOGRAPH
+0xE670	0x719C	#CJK UNIFIED IDEOGRAPH
+0xE671	0x71A7	#CJK UNIFIED IDEOGRAPH
+0xE672	0x71B3	#CJK UNIFIED IDEOGRAPH
+0xE673	0x7298	#CJK UNIFIED IDEOGRAPH
+0xE674	0x729A	#CJK UNIFIED IDEOGRAPH
+0xE675	0x7358	#CJK UNIFIED IDEOGRAPH
+0xE676	0x7352	#CJK UNIFIED IDEOGRAPH
+0xE677	0x735E	#CJK UNIFIED IDEOGRAPH
+0xE678	0x735F	#CJK UNIFIED IDEOGRAPH
+0xE679	0x7360	#CJK UNIFIED IDEOGRAPH
+0xE67A	0x735D	#CJK UNIFIED IDEOGRAPH
+0xE67B	0x735B	#CJK UNIFIED IDEOGRAPH
+0xE67C	0x7361	#CJK UNIFIED IDEOGRAPH
+0xE67D	0x735A	#CJK UNIFIED IDEOGRAPH
+0xE67E	0x7359	#CJK UNIFIED IDEOGRAPH
+0xE6A1	0x7362	#CJK UNIFIED IDEOGRAPH
+0xE6A2	0x7487	#CJK UNIFIED IDEOGRAPH
+0xE6A3	0x7489	#CJK UNIFIED IDEOGRAPH
+0xE6A4	0x748A	#CJK UNIFIED IDEOGRAPH
+0xE6A5	0x7486	#CJK UNIFIED IDEOGRAPH
+0xE6A6	0x7481	#CJK UNIFIED IDEOGRAPH
+0xE6A7	0x747D	#CJK UNIFIED IDEOGRAPH
+0xE6A8	0x7485	#CJK UNIFIED IDEOGRAPH
+0xE6A9	0x7488	#CJK UNIFIED IDEOGRAPH
+0xE6AA	0x747C	#CJK UNIFIED IDEOGRAPH
+0xE6AB	0x7479	#CJK UNIFIED IDEOGRAPH
+0xE6AC	0x7508	#CJK UNIFIED IDEOGRAPH
+0xE6AD	0x7507	#CJK UNIFIED IDEOGRAPH
+0xE6AE	0x757E	#CJK UNIFIED IDEOGRAPH
+0xE6AF	0x7625	#CJK UNIFIED IDEOGRAPH
+0xE6B0	0x761E	#CJK UNIFIED IDEOGRAPH
+0xE6B1	0x7619	#CJK UNIFIED IDEOGRAPH
+0xE6B2	0x761D	#CJK UNIFIED IDEOGRAPH
+0xE6B3	0x761C	#CJK UNIFIED IDEOGRAPH
+0xE6B4	0x7623	#CJK UNIFIED IDEOGRAPH
+0xE6B5	0x761A	#CJK UNIFIED IDEOGRAPH
+0xE6B6	0x7628	#CJK UNIFIED IDEOGRAPH
+0xE6B7	0x761B	#CJK UNIFIED IDEOGRAPH
+0xE6B8	0x769C	#CJK UNIFIED IDEOGRAPH
+0xE6B9	0x769D	#CJK UNIFIED IDEOGRAPH
+0xE6BA	0x769E	#CJK UNIFIED IDEOGRAPH
+0xE6BB	0x769B	#CJK UNIFIED IDEOGRAPH
+0xE6BC	0x778D	#CJK UNIFIED IDEOGRAPH
+0xE6BD	0x778F	#CJK UNIFIED IDEOGRAPH
+0xE6BE	0x7789	#CJK UNIFIED IDEOGRAPH
+0xE6BF	0x7788	#CJK UNIFIED IDEOGRAPH
+0xE6C0	0x78CD	#CJK UNIFIED IDEOGRAPH
+0xE6C1	0x78BB	#CJK UNIFIED IDEOGRAPH
+0xE6C2	0x78CF	#CJK UNIFIED IDEOGRAPH
+0xE6C3	0x78CC	#CJK UNIFIED IDEOGRAPH
+0xE6C4	0x78D1	#CJK UNIFIED IDEOGRAPH
+0xE6C5	0x78CE	#CJK UNIFIED IDEOGRAPH
+0xE6C6	0x78D4	#CJK UNIFIED IDEOGRAPH
+0xE6C7	0x78C8	#CJK UNIFIED IDEOGRAPH
+0xE6C8	0x78C3	#CJK UNIFIED IDEOGRAPH
+0xE6C9	0x78C4	#CJK UNIFIED IDEOGRAPH
+0xE6CA	0x78C9	#CJK UNIFIED IDEOGRAPH
+0xE6CB	0x799A	#CJK UNIFIED IDEOGRAPH
+0xE6CC	0x79A1	#CJK UNIFIED IDEOGRAPH
+0xE6CD	0x79A0	#CJK UNIFIED IDEOGRAPH
+0xE6CE	0x799C	#CJK UNIFIED IDEOGRAPH
+0xE6CF	0x79A2	#CJK UNIFIED IDEOGRAPH
+0xE6D0	0x799B	#CJK UNIFIED IDEOGRAPH
+0xE6D1	0x6B76	#CJK UNIFIED IDEOGRAPH
+0xE6D2	0x7A39	#CJK UNIFIED IDEOGRAPH
+0xE6D3	0x7AB2	#CJK UNIFIED IDEOGRAPH
+0xE6D4	0x7AB4	#CJK UNIFIED IDEOGRAPH
+0xE6D5	0x7AB3	#CJK UNIFIED IDEOGRAPH
+0xE6D6	0x7BB7	#CJK UNIFIED IDEOGRAPH
+0xE6D7	0x7BCB	#CJK UNIFIED IDEOGRAPH
+0xE6D8	0x7BBE	#CJK UNIFIED IDEOGRAPH
+0xE6D9	0x7BAC	#CJK UNIFIED IDEOGRAPH
+0xE6DA	0x7BCE	#CJK UNIFIED IDEOGRAPH
+0xE6DB	0x7BAF	#CJK UNIFIED IDEOGRAPH
+0xE6DC	0x7BB9	#CJK UNIFIED IDEOGRAPH
+0xE6DD	0x7BCA	#CJK UNIFIED IDEOGRAPH
+0xE6DE	0x7BB5	#CJK UNIFIED IDEOGRAPH
+0xE6DF	0x7CC5	#CJK UNIFIED IDEOGRAPH
+0xE6E0	0x7CC8	#CJK UNIFIED IDEOGRAPH
+0xE6E1	0x7CCC	#CJK UNIFIED IDEOGRAPH
+0xE6E2	0x7CCB	#CJK UNIFIED IDEOGRAPH
+0xE6E3	0x7DF7	#CJK UNIFIED IDEOGRAPH
+0xE6E4	0x7DDB	#CJK UNIFIED IDEOGRAPH
+0xE6E5	0x7DEA	#CJK UNIFIED IDEOGRAPH
+0xE6E6	0x7DE7	#CJK UNIFIED IDEOGRAPH
+0xE6E7	0x7DD7	#CJK UNIFIED IDEOGRAPH
+0xE6E8	0x7DE1	#CJK UNIFIED IDEOGRAPH
+0xE6E9	0x7E03	#CJK UNIFIED IDEOGRAPH
+0xE6EA	0x7DFA	#CJK UNIFIED IDEOGRAPH
+0xE6EB	0x7DE6	#CJK UNIFIED IDEOGRAPH
+0xE6EC	0x7DF6	#CJK UNIFIED IDEOGRAPH
+0xE6ED	0x7DF1	#CJK UNIFIED IDEOGRAPH
+0xE6EE	0x7DF0	#CJK UNIFIED IDEOGRAPH
+0xE6EF	0x7DEE	#CJK UNIFIED IDEOGRAPH
+0xE6F0	0x7DDF	#CJK UNIFIED IDEOGRAPH
+0xE6F1	0x7F76	#CJK UNIFIED IDEOGRAPH
+0xE6F2	0x7FAC	#CJK UNIFIED IDEOGRAPH
+0xE6F3	0x7FB0	#CJK UNIFIED IDEOGRAPH
+0xE6F4	0x7FAD	#CJK UNIFIED IDEOGRAPH
+0xE6F5	0x7FED	#CJK UNIFIED IDEOGRAPH
+0xE6F6	0x7FEB	#CJK UNIFIED IDEOGRAPH
+0xE6F7	0x7FEA	#CJK UNIFIED IDEOGRAPH
+0xE6F8	0x7FEC	#CJK UNIFIED IDEOGRAPH
+0xE6F9	0x7FE6	#CJK UNIFIED IDEOGRAPH
+0xE6FA	0x7FE8	#CJK UNIFIED IDEOGRAPH
+0xE6FB	0x8064	#CJK UNIFIED IDEOGRAPH
+0xE6FC	0x8067	#CJK UNIFIED IDEOGRAPH
+0xE6FD	0x81A3	#CJK UNIFIED IDEOGRAPH
+0xE6FE	0x819F	#CJK UNIFIED IDEOGRAPH
+0xE740	0x819E	#CJK UNIFIED IDEOGRAPH
+0xE741	0x8195	#CJK UNIFIED IDEOGRAPH
+0xE742	0x81A2	#CJK UNIFIED IDEOGRAPH
+0xE743	0x8199	#CJK UNIFIED IDEOGRAPH
+0xE744	0x8197	#CJK UNIFIED IDEOGRAPH
+0xE745	0x8216	#CJK UNIFIED IDEOGRAPH
+0xE746	0x824F	#CJK UNIFIED IDEOGRAPH
+0xE747	0x8253	#CJK UNIFIED IDEOGRAPH
+0xE748	0x8252	#CJK UNIFIED IDEOGRAPH
+0xE749	0x8250	#CJK UNIFIED IDEOGRAPH
+0xE74A	0x824E	#CJK UNIFIED IDEOGRAPH
+0xE74B	0x8251	#CJK UNIFIED IDEOGRAPH
+0xE74C	0x8524	#CJK UNIFIED IDEOGRAPH
+0xE74D	0x853B	#CJK UNIFIED IDEOGRAPH
+0xE74E	0x850F	#CJK UNIFIED IDEOGRAPH
+0xE74F	0x8500	#CJK UNIFIED IDEOGRAPH
+0xE750	0x8529	#CJK UNIFIED IDEOGRAPH
+0xE751	0x850E	#CJK UNIFIED IDEOGRAPH
+0xE752	0x8509	#CJK UNIFIED IDEOGRAPH
+0xE753	0x850D	#CJK UNIFIED IDEOGRAPH
+0xE754	0x851F	#CJK UNIFIED IDEOGRAPH
+0xE755	0x850A	#CJK UNIFIED IDEOGRAPH
+0xE756	0x8527	#CJK UNIFIED IDEOGRAPH
+0xE757	0x851C	#CJK UNIFIED IDEOGRAPH
+0xE758	0x84FB	#CJK UNIFIED IDEOGRAPH
+0xE759	0x852B	#CJK UNIFIED IDEOGRAPH
+0xE75A	0x84FA	#CJK UNIFIED IDEOGRAPH
+0xE75B	0x8508	#CJK UNIFIED IDEOGRAPH
+0xE75C	0x850C	#CJK UNIFIED IDEOGRAPH
+0xE75D	0x84F4	#CJK UNIFIED IDEOGRAPH
+0xE75E	0x852A	#CJK UNIFIED IDEOGRAPH
+0xE75F	0x84F2	#CJK UNIFIED IDEOGRAPH
+0xE760	0x8515	#CJK UNIFIED IDEOGRAPH
+0xE761	0x84F7	#CJK UNIFIED IDEOGRAPH
+0xE762	0x84EB	#CJK UNIFIED IDEOGRAPH
+0xE763	0x84F3	#CJK UNIFIED IDEOGRAPH
+0xE764	0x84FC	#CJK UNIFIED IDEOGRAPH
+0xE765	0x8512	#CJK UNIFIED IDEOGRAPH
+0xE766	0x84EA	#CJK UNIFIED IDEOGRAPH
+0xE767	0x84E9	#CJK UNIFIED IDEOGRAPH
+0xE768	0x8516	#CJK UNIFIED IDEOGRAPH
+0xE769	0x84FE	#CJK UNIFIED IDEOGRAPH
+0xE76A	0x8528	#CJK UNIFIED IDEOGRAPH
+0xE76B	0x851D	#CJK UNIFIED IDEOGRAPH
+0xE76C	0x852E	#CJK UNIFIED IDEOGRAPH
+0xE76D	0x8502	#CJK UNIFIED IDEOGRAPH
+0xE76E	0x84FD	#CJK UNIFIED IDEOGRAPH
+0xE76F	0x851E	#CJK UNIFIED IDEOGRAPH
+0xE770	0x84F6	#CJK UNIFIED IDEOGRAPH
+0xE771	0x8531	#CJK UNIFIED IDEOGRAPH
+0xE772	0x8526	#CJK UNIFIED IDEOGRAPH
+0xE773	0x84E7	#CJK UNIFIED IDEOGRAPH
+0xE774	0x84E8	#CJK UNIFIED IDEOGRAPH
+0xE775	0x84F0	#CJK UNIFIED IDEOGRAPH
+0xE776	0x84EF	#CJK UNIFIED IDEOGRAPH
+0xE777	0x84F9	#CJK UNIFIED IDEOGRAPH
+0xE778	0x8518	#CJK UNIFIED IDEOGRAPH
+0xE779	0x8520	#CJK UNIFIED IDEOGRAPH
+0xE77A	0x8530	#CJK UNIFIED IDEOGRAPH
+0xE77B	0x850B	#CJK UNIFIED IDEOGRAPH
+0xE77C	0x8519	#CJK UNIFIED IDEOGRAPH
+0xE77D	0x852F	#CJK UNIFIED IDEOGRAPH
+0xE77E	0x8662	#CJK UNIFIED IDEOGRAPH
+0xE7A1	0x8756	#CJK UNIFIED IDEOGRAPH
+0xE7A2	0x8763	#CJK UNIFIED IDEOGRAPH
+0xE7A3	0x8764	#CJK UNIFIED IDEOGRAPH
+0xE7A4	0x8777	#CJK UNIFIED IDEOGRAPH
+0xE7A5	0x87E1	#CJK UNIFIED IDEOGRAPH
+0xE7A6	0x8773	#CJK UNIFIED IDEOGRAPH
+0xE7A7	0x8758	#CJK UNIFIED IDEOGRAPH
+0xE7A8	0x8754	#CJK UNIFIED IDEOGRAPH
+0xE7A9	0x875B	#CJK UNIFIED IDEOGRAPH
+0xE7AA	0x8752	#CJK UNIFIED IDEOGRAPH
+0xE7AB	0x8761	#CJK UNIFIED IDEOGRAPH
+0xE7AC	0x875A	#CJK UNIFIED IDEOGRAPH
+0xE7AD	0x8751	#CJK UNIFIED IDEOGRAPH
+0xE7AE	0x875E	#CJK UNIFIED IDEOGRAPH
+0xE7AF	0x876D	#CJK UNIFIED IDEOGRAPH
+0xE7B0	0x876A	#CJK UNIFIED IDEOGRAPH
+0xE7B1	0x8750	#CJK UNIFIED IDEOGRAPH
+0xE7B2	0x874E	#CJK UNIFIED IDEOGRAPH
+0xE7B3	0x875F	#CJK UNIFIED IDEOGRAPH
+0xE7B4	0x875D	#CJK UNIFIED IDEOGRAPH
+0xE7B5	0x876F	#CJK UNIFIED IDEOGRAPH
+0xE7B6	0x876C	#CJK UNIFIED IDEOGRAPH
+0xE7B7	0x877A	#CJK UNIFIED IDEOGRAPH
+0xE7B8	0x876E	#CJK UNIFIED IDEOGRAPH
+0xE7B9	0x875C	#CJK UNIFIED IDEOGRAPH
+0xE7BA	0x8765	#CJK UNIFIED IDEOGRAPH
+0xE7BB	0x874F	#CJK UNIFIED IDEOGRAPH
+0xE7BC	0x877B	#CJK UNIFIED IDEOGRAPH
+0xE7BD	0x8775	#CJK UNIFIED IDEOGRAPH
+0xE7BE	0x8762	#CJK UNIFIED IDEOGRAPH
+0xE7BF	0x8767	#CJK UNIFIED IDEOGRAPH
+0xE7C0	0x8769	#CJK UNIFIED IDEOGRAPH
+0xE7C1	0x885A	#CJK UNIFIED IDEOGRAPH
+0xE7C2	0x8905	#CJK UNIFIED IDEOGRAPH
+0xE7C3	0x890C	#CJK UNIFIED IDEOGRAPH
+0xE7C4	0x8914	#CJK UNIFIED IDEOGRAPH
+0xE7C5	0x890B	#CJK UNIFIED IDEOGRAPH
+0xE7C6	0x8917	#CJK UNIFIED IDEOGRAPH
+0xE7C7	0x8918	#CJK UNIFIED IDEOGRAPH
+0xE7C8	0x8919	#CJK UNIFIED IDEOGRAPH
+0xE7C9	0x8906	#CJK UNIFIED IDEOGRAPH
+0xE7CA	0x8916	#CJK UNIFIED IDEOGRAPH
+0xE7CB	0x8911	#CJK UNIFIED IDEOGRAPH
+0xE7CC	0x890E	#CJK UNIFIED IDEOGRAPH
+0xE7CD	0x8909	#CJK UNIFIED IDEOGRAPH
+0xE7CE	0x89A2	#CJK UNIFIED IDEOGRAPH
+0xE7CF	0x89A4	#CJK UNIFIED IDEOGRAPH
+0xE7D0	0x89A3	#CJK UNIFIED IDEOGRAPH
+0xE7D1	0x89ED	#CJK UNIFIED IDEOGRAPH
+0xE7D2	0x89F0	#CJK UNIFIED IDEOGRAPH
+0xE7D3	0x89EC	#CJK UNIFIED IDEOGRAPH
+0xE7D4	0x8ACF	#CJK UNIFIED IDEOGRAPH
+0xE7D5	0x8AC6	#CJK UNIFIED IDEOGRAPH
+0xE7D6	0x8AB8	#CJK UNIFIED IDEOGRAPH
+0xE7D7	0x8AD3	#CJK UNIFIED IDEOGRAPH
+0xE7D8	0x8AD1	#CJK UNIFIED IDEOGRAPH
+0xE7D9	0x8AD4	#CJK UNIFIED IDEOGRAPH
+0xE7DA	0x8AD5	#CJK UNIFIED IDEOGRAPH
+0xE7DB	0x8ABB	#CJK UNIFIED IDEOGRAPH
+0xE7DC	0x8AD7	#CJK UNIFIED IDEOGRAPH
+0xE7DD	0x8ABE	#CJK UNIFIED IDEOGRAPH
+0xE7DE	0x8AC0	#CJK UNIFIED IDEOGRAPH
+0xE7DF	0x8AC5	#CJK UNIFIED IDEOGRAPH
+0xE7E0	0x8AD8	#CJK UNIFIED IDEOGRAPH
+0xE7E1	0x8AC3	#CJK UNIFIED IDEOGRAPH
+0xE7E2	0x8ABA	#CJK UNIFIED IDEOGRAPH
+0xE7E3	0x8ABD	#CJK UNIFIED IDEOGRAPH
+0xE7E4	0x8AD9	#CJK UNIFIED IDEOGRAPH
+0xE7E5	0x8C3E	#CJK UNIFIED IDEOGRAPH
+0xE7E6	0x8C4D	#CJK UNIFIED IDEOGRAPH
+0xE7E7	0x8C8F	#CJK UNIFIED IDEOGRAPH
+0xE7E8	0x8CE5	#CJK UNIFIED IDEOGRAPH
+0xE7E9	0x8CDF	#CJK UNIFIED IDEOGRAPH
+0xE7EA	0x8CD9	#CJK UNIFIED IDEOGRAPH
+0xE7EB	0x8CE8	#CJK UNIFIED IDEOGRAPH
+0xE7EC	0x8CDA	#CJK UNIFIED IDEOGRAPH
+0xE7ED	0x8CDD	#CJK UNIFIED IDEOGRAPH
+0xE7EE	0x8CE7	#CJK UNIFIED IDEOGRAPH
+0xE7EF	0x8DA0	#CJK UNIFIED IDEOGRAPH
+0xE7F0	0x8D9C	#CJK UNIFIED IDEOGRAPH
+0xE7F1	0x8DA1	#CJK UNIFIED IDEOGRAPH
+0xE7F2	0x8D9B	#CJK UNIFIED IDEOGRAPH
+0xE7F3	0x8E20	#CJK UNIFIED IDEOGRAPH
+0xE7F4	0x8E23	#CJK UNIFIED IDEOGRAPH
+0xE7F5	0x8E25	#CJK UNIFIED IDEOGRAPH
+0xE7F6	0x8E24	#CJK UNIFIED IDEOGRAPH
+0xE7F7	0x8E2E	#CJK UNIFIED IDEOGRAPH
+0xE7F8	0x8E15	#CJK UNIFIED IDEOGRAPH
+0xE7F9	0x8E1B	#CJK UNIFIED IDEOGRAPH
+0xE7FA	0x8E16	#CJK UNIFIED IDEOGRAPH
+0xE7FB	0x8E11	#CJK UNIFIED IDEOGRAPH
+0xE7FC	0x8E19	#CJK UNIFIED IDEOGRAPH
+0xE7FD	0x8E26	#CJK UNIFIED IDEOGRAPH
+0xE7FE	0x8E27	#CJK UNIFIED IDEOGRAPH
+0xE840	0x8E14	#CJK UNIFIED IDEOGRAPH
+0xE841	0x8E12	#CJK UNIFIED IDEOGRAPH
+0xE842	0x8E18	#CJK UNIFIED IDEOGRAPH
+0xE843	0x8E13	#CJK UNIFIED IDEOGRAPH
+0xE844	0x8E1C	#CJK UNIFIED IDEOGRAPH
+0xE845	0x8E17	#CJK UNIFIED IDEOGRAPH
+0xE846	0x8E1A	#CJK UNIFIED IDEOGRAPH
+0xE847	0x8F2C	#CJK UNIFIED IDEOGRAPH
+0xE848	0x8F24	#CJK UNIFIED IDEOGRAPH
+0xE849	0x8F18	#CJK UNIFIED IDEOGRAPH
+0xE84A	0x8F1A	#CJK UNIFIED IDEOGRAPH
+0xE84B	0x8F20	#CJK UNIFIED IDEOGRAPH
+0xE84C	0x8F23	#CJK UNIFIED IDEOGRAPH
+0xE84D	0x8F16	#CJK UNIFIED IDEOGRAPH
+0xE84E	0x8F17	#CJK UNIFIED IDEOGRAPH
+0xE84F	0x9073	#CJK UNIFIED IDEOGRAPH
+0xE850	0x9070	#CJK UNIFIED IDEOGRAPH
+0xE851	0x906F	#CJK UNIFIED IDEOGRAPH
+0xE852	0x9067	#CJK UNIFIED IDEOGRAPH
+0xE853	0x906B	#CJK UNIFIED IDEOGRAPH
+0xE854	0x912F	#CJK UNIFIED IDEOGRAPH
+0xE855	0x912B	#CJK UNIFIED IDEOGRAPH
+0xE856	0x9129	#CJK UNIFIED IDEOGRAPH
+0xE857	0x912A	#CJK UNIFIED IDEOGRAPH
+0xE858	0x9132	#CJK UNIFIED IDEOGRAPH
+0xE859	0x9126	#CJK UNIFIED IDEOGRAPH
+0xE85A	0x912E	#CJK UNIFIED IDEOGRAPH
+0xE85B	0x9185	#CJK UNIFIED IDEOGRAPH
+0xE85C	0x9186	#CJK UNIFIED IDEOGRAPH
+0xE85D	0x918A	#CJK UNIFIED IDEOGRAPH
+0xE85E	0x9181	#CJK UNIFIED IDEOGRAPH
+0xE85F	0x9182	#CJK UNIFIED IDEOGRAPH
+0xE860	0x9184	#CJK UNIFIED IDEOGRAPH
+0xE861	0x9180	#CJK UNIFIED IDEOGRAPH
+0xE862	0x92D0	#CJK UNIFIED IDEOGRAPH
+0xE863	0x92C3	#CJK UNIFIED IDEOGRAPH
+0xE864	0x92C4	#CJK UNIFIED IDEOGRAPH
+0xE865	0x92C0	#CJK UNIFIED IDEOGRAPH
+0xE866	0x92D9	#CJK UNIFIED IDEOGRAPH
+0xE867	0x92B6	#CJK UNIFIED IDEOGRAPH
+0xE868	0x92CF	#CJK UNIFIED IDEOGRAPH
+0xE869	0x92F1	#CJK UNIFIED IDEOGRAPH
+0xE86A	0x92DF	#CJK UNIFIED IDEOGRAPH
+0xE86B	0x92D8	#CJK UNIFIED IDEOGRAPH
+0xE86C	0x92E9	#CJK UNIFIED IDEOGRAPH
+0xE86D	0x92D7	#CJK UNIFIED IDEOGRAPH
+0xE86E	0x92DD	#CJK UNIFIED IDEOGRAPH
+0xE86F	0x92CC	#CJK UNIFIED IDEOGRAPH
+0xE870	0x92EF	#CJK UNIFIED IDEOGRAPH
+0xE871	0x92C2	#CJK UNIFIED IDEOGRAPH
+0xE872	0x92E8	#CJK UNIFIED IDEOGRAPH
+0xE873	0x92CA	#CJK UNIFIED IDEOGRAPH
+0xE874	0x92C8	#CJK UNIFIED IDEOGRAPH
+0xE875	0x92CE	#CJK UNIFIED IDEOGRAPH
+0xE876	0x92E6	#CJK UNIFIED IDEOGRAPH
+0xE877	0x92CD	#CJK UNIFIED IDEOGRAPH
+0xE878	0x92D5	#CJK UNIFIED IDEOGRAPH
+0xE879	0x92C9	#CJK UNIFIED IDEOGRAPH
+0xE87A	0x92E0	#CJK UNIFIED IDEOGRAPH
+0xE87B	0x92DE	#CJK UNIFIED IDEOGRAPH
+0xE87C	0x92E7	#CJK UNIFIED IDEOGRAPH
+0xE87D	0x92D1	#CJK UNIFIED IDEOGRAPH
+0xE87E	0x92D3	#CJK UNIFIED IDEOGRAPH
+0xE8A1	0x92B5	#CJK UNIFIED IDEOGRAPH
+0xE8A2	0x92E1	#CJK UNIFIED IDEOGRAPH
+0xE8A3	0x92C6	#CJK UNIFIED IDEOGRAPH
+0xE8A4	0x92B4	#CJK UNIFIED IDEOGRAPH
+0xE8A5	0x957C	#CJK UNIFIED IDEOGRAPH
+0xE8A6	0x95AC	#CJK UNIFIED IDEOGRAPH
+0xE8A7	0x95AB	#CJK UNIFIED IDEOGRAPH
+0xE8A8	0x95AE	#CJK UNIFIED IDEOGRAPH
+0xE8A9	0x95B0	#CJK UNIFIED IDEOGRAPH
+0xE8AA	0x96A4	#CJK UNIFIED IDEOGRAPH
+0xE8AB	0x96A2	#CJK UNIFIED IDEOGRAPH
+0xE8AC	0x96D3	#CJK UNIFIED IDEOGRAPH
+0xE8AD	0x9705	#CJK UNIFIED IDEOGRAPH
+0xE8AE	0x9708	#CJK UNIFIED IDEOGRAPH
+0xE8AF	0x9702	#CJK UNIFIED IDEOGRAPH
+0xE8B0	0x975A	#CJK UNIFIED IDEOGRAPH
+0xE8B1	0x978A	#CJK UNIFIED IDEOGRAPH
+0xE8B2	0x978E	#CJK UNIFIED IDEOGRAPH
+0xE8B3	0x9788	#CJK UNIFIED IDEOGRAPH
+0xE8B4	0x97D0	#CJK UNIFIED IDEOGRAPH
+0xE8B5	0x97CF	#CJK UNIFIED IDEOGRAPH
+0xE8B6	0x981E	#CJK UNIFIED IDEOGRAPH
+0xE8B7	0x981D	#CJK UNIFIED IDEOGRAPH
+0xE8B8	0x9826	#CJK UNIFIED IDEOGRAPH
+0xE8B9	0x9829	#CJK UNIFIED IDEOGRAPH
+0xE8BA	0x9828	#CJK UNIFIED IDEOGRAPH
+0xE8BB	0x9820	#CJK UNIFIED IDEOGRAPH
+0xE8BC	0x981B	#CJK UNIFIED IDEOGRAPH
+0xE8BD	0x9827	#CJK UNIFIED IDEOGRAPH
+0xE8BE	0x98B2	#CJK UNIFIED IDEOGRAPH
+0xE8BF	0x9908	#CJK UNIFIED IDEOGRAPH
+0xE8C0	0x98FA	#CJK UNIFIED IDEOGRAPH
+0xE8C1	0x9911	#CJK UNIFIED IDEOGRAPH
+0xE8C2	0x9914	#CJK UNIFIED IDEOGRAPH
+0xE8C3	0x9916	#CJK UNIFIED IDEOGRAPH
+0xE8C4	0x9917	#CJK UNIFIED IDEOGRAPH
+0xE8C5	0x9915	#CJK UNIFIED IDEOGRAPH
+0xE8C6	0x99DC	#CJK UNIFIED IDEOGRAPH
+0xE8C7	0x99CD	#CJK UNIFIED IDEOGRAPH
+0xE8C8	0x99CF	#CJK UNIFIED IDEOGRAPH
+0xE8C9	0x99D3	#CJK UNIFIED IDEOGRAPH
+0xE8CA	0x99D4	#CJK UNIFIED IDEOGRAPH
+0xE8CB	0x99CE	#CJK UNIFIED IDEOGRAPH
+0xE8CC	0x99C9	#CJK UNIFIED IDEOGRAPH
+0xE8CD	0x99D6	#CJK UNIFIED IDEOGRAPH
+0xE8CE	0x99D8	#CJK UNIFIED IDEOGRAPH
+0xE8CF	0x99CB	#CJK UNIFIED IDEOGRAPH
+0xE8D0	0x99D7	#CJK UNIFIED IDEOGRAPH
+0xE8D1	0x99CC	#CJK UNIFIED IDEOGRAPH
+0xE8D2	0x9AB3	#CJK UNIFIED IDEOGRAPH
+0xE8D3	0x9AEC	#CJK UNIFIED IDEOGRAPH
+0xE8D4	0x9AEB	#CJK UNIFIED IDEOGRAPH
+0xE8D5	0x9AF3	#CJK UNIFIED IDEOGRAPH
+0xE8D6	0x9AF2	#CJK UNIFIED IDEOGRAPH
+0xE8D7	0x9AF1	#CJK UNIFIED IDEOGRAPH
+0xE8D8	0x9B46	#CJK UNIFIED IDEOGRAPH
+0xE8D9	0x9B43	#CJK UNIFIED IDEOGRAPH
+0xE8DA	0x9B67	#CJK UNIFIED IDEOGRAPH
+0xE8DB	0x9B74	#CJK UNIFIED IDEOGRAPH
+0xE8DC	0x9B71	#CJK UNIFIED IDEOGRAPH
+0xE8DD	0x9B66	#CJK UNIFIED IDEOGRAPH
+0xE8DE	0x9B76	#CJK UNIFIED IDEOGRAPH
+0xE8DF	0x9B75	#CJK UNIFIED IDEOGRAPH
+0xE8E0	0x9B70	#CJK UNIFIED IDEOGRAPH
+0xE8E1	0x9B68	#CJK UNIFIED IDEOGRAPH
+0xE8E2	0x9B64	#CJK UNIFIED IDEOGRAPH
+0xE8E3	0x9B6C	#CJK UNIFIED IDEOGRAPH
+0xE8E4	0x9CFC	#CJK UNIFIED IDEOGRAPH
+0xE8E5	0x9CFA	#CJK UNIFIED IDEOGRAPH
+0xE8E6	0x9CFD	#CJK UNIFIED IDEOGRAPH
+0xE8E7	0x9CFF	#CJK UNIFIED IDEOGRAPH
+0xE8E8	0x9CF7	#CJK UNIFIED IDEOGRAPH
+0xE8E9	0x9D07	#CJK UNIFIED IDEOGRAPH
+0xE8EA	0x9D00	#CJK UNIFIED IDEOGRAPH
+0xE8EB	0x9CF9	#CJK UNIFIED IDEOGRAPH
+0xE8EC	0x9CFB	#CJK UNIFIED IDEOGRAPH
+0xE8ED	0x9D08	#CJK UNIFIED IDEOGRAPH
+0xE8EE	0x9D05	#CJK UNIFIED IDEOGRAPH
+0xE8EF	0x9D04	#CJK UNIFIED IDEOGRAPH
+0xE8F0	0x9E83	#CJK UNIFIED IDEOGRAPH
+0xE8F1	0x9ED3	#CJK UNIFIED IDEOGRAPH
+0xE8F2	0x9F0F	#CJK UNIFIED IDEOGRAPH
+0xE8F3	0x9F10	#CJK UNIFIED IDEOGRAPH
+0xE8F4	0x511C	#CJK UNIFIED IDEOGRAPH
+0xE8F5	0x5113	#CJK UNIFIED IDEOGRAPH
+0xE8F6	0x5117	#CJK UNIFIED IDEOGRAPH
+0xE8F7	0x511A	#CJK UNIFIED IDEOGRAPH
+0xE8F8	0x5111	#CJK UNIFIED IDEOGRAPH
+0xE8F9	0x51DE	#CJK UNIFIED IDEOGRAPH
+0xE8FA	0x5334	#CJK UNIFIED IDEOGRAPH
+0xE8FB	0x53E1	#CJK UNIFIED IDEOGRAPH
+0xE8FC	0x5670	#CJK UNIFIED IDEOGRAPH
+0xE8FD	0x5660	#CJK UNIFIED IDEOGRAPH
+0xE8FE	0x566E	#CJK UNIFIED IDEOGRAPH
+0xE940	0x5673	#CJK UNIFIED IDEOGRAPH
+0xE941	0x5666	#CJK UNIFIED IDEOGRAPH
+0xE942	0x5663	#CJK UNIFIED IDEOGRAPH
+0xE943	0x566D	#CJK UNIFIED IDEOGRAPH
+0xE944	0x5672	#CJK UNIFIED IDEOGRAPH
+0xE945	0x565E	#CJK UNIFIED IDEOGRAPH
+0xE946	0x5677	#CJK UNIFIED IDEOGRAPH
+0xE947	0x571C	#CJK UNIFIED IDEOGRAPH
+0xE948	0x571B	#CJK UNIFIED IDEOGRAPH
+0xE949	0x58C8	#CJK UNIFIED IDEOGRAPH
+0xE94A	0x58BD	#CJK UNIFIED IDEOGRAPH
+0xE94B	0x58C9	#CJK UNIFIED IDEOGRAPH
+0xE94C	0x58BF	#CJK UNIFIED IDEOGRAPH
+0xE94D	0x58BA	#CJK UNIFIED IDEOGRAPH
+0xE94E	0x58C2	#CJK UNIFIED IDEOGRAPH
+0xE94F	0x58BC	#CJK UNIFIED IDEOGRAPH
+0xE950	0x58C6	#CJK UNIFIED IDEOGRAPH
+0xE951	0x5B17	#CJK UNIFIED IDEOGRAPH
+0xE952	0x5B19	#CJK UNIFIED IDEOGRAPH
+0xE953	0x5B1B	#CJK UNIFIED IDEOGRAPH
+0xE954	0x5B21	#CJK UNIFIED IDEOGRAPH
+0xE955	0x5B14	#CJK UNIFIED IDEOGRAPH
+0xE956	0x5B13	#CJK UNIFIED IDEOGRAPH
+0xE957	0x5B10	#CJK UNIFIED IDEOGRAPH
+0xE958	0x5B16	#CJK UNIFIED IDEOGRAPH
+0xE959	0x5B28	#CJK UNIFIED IDEOGRAPH
+0xE95A	0x5B1A	#CJK UNIFIED IDEOGRAPH
+0xE95B	0x5B20	#CJK UNIFIED IDEOGRAPH
+0xE95C	0x5B1E	#CJK UNIFIED IDEOGRAPH
+0xE95D	0x5BEF	#CJK UNIFIED IDEOGRAPH
+0xE95E	0x5DAC	#CJK UNIFIED IDEOGRAPH
+0xE95F	0x5DB1	#CJK UNIFIED IDEOGRAPH
+0xE960	0x5DA9	#CJK UNIFIED IDEOGRAPH
+0xE961	0x5DA7	#CJK UNIFIED IDEOGRAPH
+0xE962	0x5DB5	#CJK UNIFIED IDEOGRAPH
+0xE963	0x5DB0	#CJK UNIFIED IDEOGRAPH
+0xE964	0x5DAE	#CJK UNIFIED IDEOGRAPH
+0xE965	0x5DAA	#CJK UNIFIED IDEOGRAPH
+0xE966	0x5DA8	#CJK UNIFIED IDEOGRAPH
+0xE967	0x5DB2	#CJK UNIFIED IDEOGRAPH
+0xE968	0x5DAD	#CJK UNIFIED IDEOGRAPH
+0xE969	0x5DAF	#CJK UNIFIED IDEOGRAPH
+0xE96A	0x5DB4	#CJK UNIFIED IDEOGRAPH
+0xE96B	0x5E67	#CJK UNIFIED IDEOGRAPH
+0xE96C	0x5E68	#CJK UNIFIED IDEOGRAPH
+0xE96D	0x5E66	#CJK UNIFIED IDEOGRAPH
+0xE96E	0x5E6F	#CJK UNIFIED IDEOGRAPH
+0xE96F	0x5EE9	#CJK UNIFIED IDEOGRAPH
+0xE970	0x5EE7	#CJK UNIFIED IDEOGRAPH
+0xE971	0x5EE6	#CJK UNIFIED IDEOGRAPH
+0xE972	0x5EE8	#CJK UNIFIED IDEOGRAPH
+0xE973	0x5EE5	#CJK UNIFIED IDEOGRAPH
+0xE974	0x5F4B	#CJK UNIFIED IDEOGRAPH
+0xE975	0x5FBC	#CJK UNIFIED IDEOGRAPH
+0xE976	0x619D	#CJK UNIFIED IDEOGRAPH
+0xE977	0x61A8	#CJK UNIFIED IDEOGRAPH
+0xE978	0x6196	#CJK UNIFIED IDEOGRAPH
+0xE979	0x61C5	#CJK UNIFIED IDEOGRAPH
+0xE97A	0x61B4	#CJK UNIFIED IDEOGRAPH
+0xE97B	0x61C6	#CJK UNIFIED IDEOGRAPH
+0xE97C	0x61C1	#CJK UNIFIED IDEOGRAPH
+0xE97D	0x61CC	#CJK UNIFIED IDEOGRAPH
+0xE97E	0x61BA	#CJK UNIFIED IDEOGRAPH
+0xE9A1	0x61BF	#CJK UNIFIED IDEOGRAPH
+0xE9A2	0x61B8	#CJK UNIFIED IDEOGRAPH
+0xE9A3	0x618C	#CJK UNIFIED IDEOGRAPH
+0xE9A4	0x64D7	#CJK UNIFIED IDEOGRAPH
+0xE9A5	0x64D6	#CJK UNIFIED IDEOGRAPH
+0xE9A6	0x64D0	#CJK UNIFIED IDEOGRAPH
+0xE9A7	0x64CF	#CJK UNIFIED IDEOGRAPH
+0xE9A8	0x64C9	#CJK UNIFIED IDEOGRAPH
+0xE9A9	0x64BD	#CJK UNIFIED IDEOGRAPH
+0xE9AA	0x6489	#CJK UNIFIED IDEOGRAPH
+0xE9AB	0x64C3	#CJK UNIFIED IDEOGRAPH
+0xE9AC	0x64DB	#CJK UNIFIED IDEOGRAPH
+0xE9AD	0x64F3	#CJK UNIFIED IDEOGRAPH
+0xE9AE	0x64D9	#CJK UNIFIED IDEOGRAPH
+0xE9AF	0x6533	#CJK UNIFIED IDEOGRAPH
+0xE9B0	0x657F	#CJK UNIFIED IDEOGRAPH
+0xE9B1	0x657C	#CJK UNIFIED IDEOGRAPH
+0xE9B2	0x65A2	#CJK UNIFIED IDEOGRAPH
+0xE9B3	0x66C8	#CJK UNIFIED IDEOGRAPH
+0xE9B4	0x66BE	#CJK UNIFIED IDEOGRAPH
+0xE9B5	0x66C0	#CJK UNIFIED IDEOGRAPH
+0xE9B6	0x66CA	#CJK UNIFIED IDEOGRAPH
+0xE9B7	0x66CB	#CJK UNIFIED IDEOGRAPH
+0xE9B8	0x66CF	#CJK UNIFIED IDEOGRAPH
+0xE9B9	0x66BD	#CJK UNIFIED IDEOGRAPH
+0xE9BA	0x66BB	#CJK UNIFIED IDEOGRAPH
+0xE9BB	0x66BA	#CJK UNIFIED IDEOGRAPH
+0xE9BC	0x66CC	#CJK UNIFIED IDEOGRAPH
+0xE9BD	0x6723	#CJK UNIFIED IDEOGRAPH
+0xE9BE	0x6A34	#CJK UNIFIED IDEOGRAPH
+0xE9BF	0x6A66	#CJK UNIFIED IDEOGRAPH
+0xE9C0	0x6A49	#CJK UNIFIED IDEOGRAPH
+0xE9C1	0x6A67	#CJK UNIFIED IDEOGRAPH
+0xE9C2	0x6A32	#CJK UNIFIED IDEOGRAPH
+0xE9C3	0x6A68	#CJK UNIFIED IDEOGRAPH
+0xE9C4	0x6A3E	#CJK UNIFIED IDEOGRAPH
+0xE9C5	0x6A5D	#CJK UNIFIED IDEOGRAPH
+0xE9C6	0x6A6D	#CJK UNIFIED IDEOGRAPH
+0xE9C7	0x6A76	#CJK UNIFIED IDEOGRAPH
+0xE9C8	0x6A5B	#CJK UNIFIED IDEOGRAPH
+0xE9C9	0x6A51	#CJK UNIFIED IDEOGRAPH
+0xE9CA	0x6A28	#CJK UNIFIED IDEOGRAPH
+0xE9CB	0x6A5A	#CJK UNIFIED IDEOGRAPH
+0xE9CC	0x6A3B	#CJK UNIFIED IDEOGRAPH
+0xE9CD	0x6A3F	#CJK UNIFIED IDEOGRAPH
+0xE9CE	0x6A41	#CJK UNIFIED IDEOGRAPH
+0xE9CF	0x6A6A	#CJK UNIFIED IDEOGRAPH
+0xE9D0	0x6A64	#CJK UNIFIED IDEOGRAPH
+0xE9D1	0x6A50	#CJK UNIFIED IDEOGRAPH
+0xE9D2	0x6A4F	#CJK UNIFIED IDEOGRAPH
+0xE9D3	0x6A54	#CJK UNIFIED IDEOGRAPH
+0xE9D4	0x6A6F	#CJK UNIFIED IDEOGRAPH
+0xE9D5	0x6A69	#CJK UNIFIED IDEOGRAPH
+0xE9D6	0x6A60	#CJK UNIFIED IDEOGRAPH
+0xE9D7	0x6A3C	#CJK UNIFIED IDEOGRAPH
+0xE9D8	0x6A5E	#CJK UNIFIED IDEOGRAPH
+0xE9D9	0x6A56	#CJK UNIFIED IDEOGRAPH
+0xE9DA	0x6A55	#CJK UNIFIED IDEOGRAPH
+0xE9DB	0x6A4D	#CJK UNIFIED IDEOGRAPH
+0xE9DC	0x6A4E	#CJK UNIFIED IDEOGRAPH
+0xE9DD	0x6A46	#CJK UNIFIED IDEOGRAPH
+0xE9DE	0x6B55	#CJK UNIFIED IDEOGRAPH
+0xE9DF	0x6B54	#CJK UNIFIED IDEOGRAPH
+0xE9E0	0x6B56	#CJK UNIFIED IDEOGRAPH
+0xE9E1	0x6BA7	#CJK UNIFIED IDEOGRAPH
+0xE9E2	0x6BAA	#CJK UNIFIED IDEOGRAPH
+0xE9E3	0x6BAB	#CJK UNIFIED IDEOGRAPH
+0xE9E4	0x6BC8	#CJK UNIFIED IDEOGRAPH
+0xE9E5	0x6BC7	#CJK UNIFIED IDEOGRAPH
+0xE9E6	0x6C04	#CJK UNIFIED IDEOGRAPH
+0xE9E7	0x6C03	#CJK UNIFIED IDEOGRAPH
+0xE9E8	0x6C06	#CJK UNIFIED IDEOGRAPH
+0xE9E9	0x6FAD	#CJK UNIFIED IDEOGRAPH
+0xE9EA	0x6FCB	#CJK UNIFIED IDEOGRAPH
+0xE9EB	0x6FA3	#CJK UNIFIED IDEOGRAPH
+0xE9EC	0x6FC7	#CJK UNIFIED IDEOGRAPH
+0xE9ED	0x6FBC	#CJK UNIFIED IDEOGRAPH
+0xE9EE	0x6FCE	#CJK UNIFIED IDEOGRAPH
+0xE9EF	0x6FC8	#CJK UNIFIED IDEOGRAPH
+0xE9F0	0x6F5E	#CJK UNIFIED IDEOGRAPH
+0xE9F1	0x6FC4	#CJK UNIFIED IDEOGRAPH
+0xE9F2	0x6FBD	#CJK UNIFIED IDEOGRAPH
+0xE9F3	0x6F9E	#CJK UNIFIED IDEOGRAPH
+0xE9F4	0x6FCA	#CJK UNIFIED IDEOGRAPH
+0xE9F5	0x6FA8	#CJK UNIFIED IDEOGRAPH
+0xE9F6	0x7004	#CJK UNIFIED IDEOGRAPH
+0xE9F7	0x6FA5	#CJK UNIFIED IDEOGRAPH
+0xE9F8	0x6FAE	#CJK UNIFIED IDEOGRAPH
+0xE9F9	0x6FBA	#CJK UNIFIED IDEOGRAPH
+0xE9FA	0x6FAC	#CJK UNIFIED IDEOGRAPH
+0xE9FB	0x6FAA	#CJK UNIFIED IDEOGRAPH
+0xE9FC	0x6FCF	#CJK UNIFIED IDEOGRAPH
+0xE9FD	0x6FBF	#CJK UNIFIED IDEOGRAPH
+0xE9FE	0x6FB8	#CJK UNIFIED IDEOGRAPH
+0xEA40	0x6FA2	#CJK UNIFIED IDEOGRAPH
+0xEA41	0x6FC9	#CJK UNIFIED IDEOGRAPH
+0xEA42	0x6FAB	#CJK UNIFIED IDEOGRAPH
+0xEA43	0x6FCD	#CJK UNIFIED IDEOGRAPH
+0xEA44	0x6FAF	#CJK UNIFIED IDEOGRAPH
+0xEA45	0x6FB2	#CJK UNIFIED IDEOGRAPH
+0xEA46	0x6FB0	#CJK UNIFIED IDEOGRAPH
+0xEA47	0x71C5	#CJK UNIFIED IDEOGRAPH
+0xEA48	0x71C2	#CJK UNIFIED IDEOGRAPH
+0xEA49	0x71BF	#CJK UNIFIED IDEOGRAPH
+0xEA4A	0x71B8	#CJK UNIFIED IDEOGRAPH
+0xEA4B	0x71D6	#CJK UNIFIED IDEOGRAPH
+0xEA4C	0x71C0	#CJK UNIFIED IDEOGRAPH
+0xEA4D	0x71C1	#CJK UNIFIED IDEOGRAPH
+0xEA4E	0x71CB	#CJK UNIFIED IDEOGRAPH
+0xEA4F	0x71D4	#CJK UNIFIED IDEOGRAPH
+0xEA50	0x71CA	#CJK UNIFIED IDEOGRAPH
+0xEA51	0x71C7	#CJK UNIFIED IDEOGRAPH
+0xEA52	0x71CF	#CJK UNIFIED IDEOGRAPH
+0xEA53	0x71BD	#CJK UNIFIED IDEOGRAPH
+0xEA54	0x71D8	#CJK UNIFIED IDEOGRAPH
+0xEA55	0x71BC	#CJK UNIFIED IDEOGRAPH
+0xEA56	0x71C6	#CJK UNIFIED IDEOGRAPH
+0xEA57	0x71DA	#CJK UNIFIED IDEOGRAPH
+0xEA58	0x71DB	#CJK UNIFIED IDEOGRAPH
+0xEA59	0x729D	#CJK UNIFIED IDEOGRAPH
+0xEA5A	0x729E	#CJK UNIFIED IDEOGRAPH
+0xEA5B	0x7369	#CJK UNIFIED IDEOGRAPH
+0xEA5C	0x7366	#CJK UNIFIED IDEOGRAPH
+0xEA5D	0x7367	#CJK UNIFIED IDEOGRAPH
+0xEA5E	0x736C	#CJK UNIFIED IDEOGRAPH
+0xEA5F	0x7365	#CJK UNIFIED IDEOGRAPH
+0xEA60	0x736B	#CJK UNIFIED IDEOGRAPH
+0xEA61	0x736A	#CJK UNIFIED IDEOGRAPH
+0xEA62	0x747F	#CJK UNIFIED IDEOGRAPH
+0xEA63	0x749A	#CJK UNIFIED IDEOGRAPH
+0xEA64	0x74A0	#CJK UNIFIED IDEOGRAPH
+0xEA65	0x7494	#CJK UNIFIED IDEOGRAPH
+0xEA66	0x7492	#CJK UNIFIED IDEOGRAPH
+0xEA67	0x7495	#CJK UNIFIED IDEOGRAPH
+0xEA68	0x74A1	#CJK UNIFIED IDEOGRAPH
+0xEA69	0x750B	#CJK UNIFIED IDEOGRAPH
+0xEA6A	0x7580	#CJK UNIFIED IDEOGRAPH
+0xEA6B	0x762F	#CJK UNIFIED IDEOGRAPH
+0xEA6C	0x762D	#CJK UNIFIED IDEOGRAPH
+0xEA6D	0x7631	#CJK UNIFIED IDEOGRAPH
+0xEA6E	0x763D	#CJK UNIFIED IDEOGRAPH
+0xEA6F	0x7633	#CJK UNIFIED IDEOGRAPH
+0xEA70	0x763C	#CJK UNIFIED IDEOGRAPH
+0xEA71	0x7635	#CJK UNIFIED IDEOGRAPH
+0xEA72	0x7632	#CJK UNIFIED IDEOGRAPH
+0xEA73	0x7630	#CJK UNIFIED IDEOGRAPH
+0xEA74	0x76BB	#CJK UNIFIED IDEOGRAPH
+0xEA75	0x76E6	#CJK UNIFIED IDEOGRAPH
+0xEA76	0x779A	#CJK UNIFIED IDEOGRAPH
+0xEA77	0x779D	#CJK UNIFIED IDEOGRAPH
+0xEA78	0x77A1	#CJK UNIFIED IDEOGRAPH
+0xEA79	0x779C	#CJK UNIFIED IDEOGRAPH
+0xEA7A	0x779B	#CJK UNIFIED IDEOGRAPH
+0xEA7B	0x77A2	#CJK UNIFIED IDEOGRAPH
+0xEA7C	0x77A3	#CJK UNIFIED IDEOGRAPH
+0xEA7D	0x7795	#CJK UNIFIED IDEOGRAPH
+0xEA7E	0x7799	#CJK UNIFIED IDEOGRAPH
+0xEAA1	0x7797	#CJK UNIFIED IDEOGRAPH
+0xEAA2	0x78DD	#CJK UNIFIED IDEOGRAPH
+0xEAA3	0x78E9	#CJK UNIFIED IDEOGRAPH
+0xEAA4	0x78E5	#CJK UNIFIED IDEOGRAPH
+0xEAA5	0x78EA	#CJK UNIFIED IDEOGRAPH
+0xEAA6	0x78DE	#CJK UNIFIED IDEOGRAPH
+0xEAA7	0x78E3	#CJK UNIFIED IDEOGRAPH
+0xEAA8	0x78DB	#CJK UNIFIED IDEOGRAPH
+0xEAA9	0x78E1	#CJK UNIFIED IDEOGRAPH
+0xEAAA	0x78E2	#CJK UNIFIED IDEOGRAPH
+0xEAAB	0x78ED	#CJK UNIFIED IDEOGRAPH
+0xEAAC	0x78DF	#CJK UNIFIED IDEOGRAPH
+0xEAAD	0x78E0	#CJK UNIFIED IDEOGRAPH
+0xEAAE	0x79A4	#CJK UNIFIED IDEOGRAPH
+0xEAAF	0x7A44	#CJK UNIFIED IDEOGRAPH
+0xEAB0	0x7A48	#CJK UNIFIED IDEOGRAPH
+0xEAB1	0x7A47	#CJK UNIFIED IDEOGRAPH
+0xEAB2	0x7AB6	#CJK UNIFIED IDEOGRAPH
+0xEAB3	0x7AB8	#CJK UNIFIED IDEOGRAPH
+0xEAB4	0x7AB5	#CJK UNIFIED IDEOGRAPH
+0xEAB5	0x7AB1	#CJK UNIFIED IDEOGRAPH
+0xEAB6	0x7AB7	#CJK UNIFIED IDEOGRAPH
+0xEAB7	0x7BDE	#CJK UNIFIED IDEOGRAPH
+0xEAB8	0x7BE3	#CJK UNIFIED IDEOGRAPH
+0xEAB9	0x7BE7	#CJK UNIFIED IDEOGRAPH
+0xEABA	0x7BDD	#CJK UNIFIED IDEOGRAPH
+0xEABB	0x7BD5	#CJK UNIFIED IDEOGRAPH
+0xEABC	0x7BE5	#CJK UNIFIED IDEOGRAPH
+0xEABD	0x7BDA	#CJK UNIFIED IDEOGRAPH
+0xEABE	0x7BE8	#CJK UNIFIED IDEOGRAPH
+0xEABF	0x7BF9	#CJK UNIFIED IDEOGRAPH
+0xEAC0	0x7BD4	#CJK UNIFIED IDEOGRAPH
+0xEAC1	0x7BEA	#CJK UNIFIED IDEOGRAPH
+0xEAC2	0x7BE2	#CJK UNIFIED IDEOGRAPH
+0xEAC3	0x7BDC	#CJK UNIFIED IDEOGRAPH
+0xEAC4	0x7BEB	#CJK UNIFIED IDEOGRAPH
+0xEAC5	0x7BD8	#CJK UNIFIED IDEOGRAPH
+0xEAC6	0x7BDF	#CJK UNIFIED IDEOGRAPH
+0xEAC7	0x7CD2	#CJK UNIFIED IDEOGRAPH
+0xEAC8	0x7CD4	#CJK UNIFIED IDEOGRAPH
+0xEAC9	0x7CD7	#CJK UNIFIED IDEOGRAPH
+0xEACA	0x7CD0	#CJK UNIFIED IDEOGRAPH
+0xEACB	0x7CD1	#CJK UNIFIED IDEOGRAPH
+0xEACC	0x7E12	#CJK UNIFIED IDEOGRAPH
+0xEACD	0x7E21	#CJK UNIFIED IDEOGRAPH
+0xEACE	0x7E17	#CJK UNIFIED IDEOGRAPH
+0xEACF	0x7E0C	#CJK UNIFIED IDEOGRAPH
+0xEAD0	0x7E1F	#CJK UNIFIED IDEOGRAPH
+0xEAD1	0x7E20	#CJK UNIFIED IDEOGRAPH
+0xEAD2	0x7E13	#CJK UNIFIED IDEOGRAPH
+0xEAD3	0x7E0E	#CJK UNIFIED IDEOGRAPH
+0xEAD4	0x7E1C	#CJK UNIFIED IDEOGRAPH
+0xEAD5	0x7E15	#CJK UNIFIED IDEOGRAPH
+0xEAD6	0x7E1A	#CJK UNIFIED IDEOGRAPH
+0xEAD7	0x7E22	#CJK UNIFIED IDEOGRAPH
+0xEAD8	0x7E0B	#CJK UNIFIED IDEOGRAPH
+0xEAD9	0x7E0F	#CJK UNIFIED IDEOGRAPH
+0xEADA	0x7E16	#CJK UNIFIED IDEOGRAPH
+0xEADB	0x7E0D	#CJK UNIFIED IDEOGRAPH
+0xEADC	0x7E14	#CJK UNIFIED IDEOGRAPH
+0xEADD	0x7E25	#CJK UNIFIED IDEOGRAPH
+0xEADE	0x7E24	#CJK UNIFIED IDEOGRAPH
+0xEADF	0x7F43	#CJK UNIFIED IDEOGRAPH
+0xEAE0	0x7F7B	#CJK UNIFIED IDEOGRAPH
+0xEAE1	0x7F7C	#CJK UNIFIED IDEOGRAPH
+0xEAE2	0x7F7A	#CJK UNIFIED IDEOGRAPH
+0xEAE3	0x7FB1	#CJK UNIFIED IDEOGRAPH
+0xEAE4	0x7FEF	#CJK UNIFIED IDEOGRAPH
+0xEAE5	0x802A	#CJK UNIFIED IDEOGRAPH
+0xEAE6	0x8029	#CJK UNIFIED IDEOGRAPH
+0xEAE7	0x806C	#CJK UNIFIED IDEOGRAPH
+0xEAE8	0x81B1	#CJK UNIFIED IDEOGRAPH
+0xEAE9	0x81A6	#CJK UNIFIED IDEOGRAPH
+0xEAEA	0x81AE	#CJK UNIFIED IDEOGRAPH
+0xEAEB	0x81B9	#CJK UNIFIED IDEOGRAPH
+0xEAEC	0x81B5	#CJK UNIFIED IDEOGRAPH
+0xEAED	0x81AB	#CJK UNIFIED IDEOGRAPH
+0xEAEE	0x81B0	#CJK UNIFIED IDEOGRAPH
+0xEAEF	0x81AC	#CJK UNIFIED IDEOGRAPH
+0xEAF0	0x81B4	#CJK UNIFIED IDEOGRAPH
+0xEAF1	0x81B2	#CJK UNIFIED IDEOGRAPH
+0xEAF2	0x81B7	#CJK UNIFIED IDEOGRAPH
+0xEAF3	0x81A7	#CJK UNIFIED IDEOGRAPH
+0xEAF4	0x81F2	#CJK UNIFIED IDEOGRAPH
+0xEAF5	0x8255	#CJK UNIFIED IDEOGRAPH
+0xEAF6	0x8256	#CJK UNIFIED IDEOGRAPH
+0xEAF7	0x8257	#CJK UNIFIED IDEOGRAPH
+0xEAF8	0x8556	#CJK UNIFIED IDEOGRAPH
+0xEAF9	0x8545	#CJK UNIFIED IDEOGRAPH
+0xEAFA	0x856B	#CJK UNIFIED IDEOGRAPH
+0xEAFB	0x854D	#CJK UNIFIED IDEOGRAPH
+0xEAFC	0x8553	#CJK UNIFIED IDEOGRAPH
+0xEAFD	0x8561	#CJK UNIFIED IDEOGRAPH
+0xEAFE	0x8558	#CJK UNIFIED IDEOGRAPH
+0xEB40	0x8540	#CJK UNIFIED IDEOGRAPH
+0xEB41	0x8546	#CJK UNIFIED IDEOGRAPH
+0xEB42	0x8564	#CJK UNIFIED IDEOGRAPH
+0xEB43	0x8541	#CJK UNIFIED IDEOGRAPH
+0xEB44	0x8562	#CJK UNIFIED IDEOGRAPH
+0xEB45	0x8544	#CJK UNIFIED IDEOGRAPH
+0xEB46	0x8551	#CJK UNIFIED IDEOGRAPH
+0xEB47	0x8547	#CJK UNIFIED IDEOGRAPH
+0xEB48	0x8563	#CJK UNIFIED IDEOGRAPH
+0xEB49	0x853E	#CJK UNIFIED IDEOGRAPH
+0xEB4A	0x855B	#CJK UNIFIED IDEOGRAPH
+0xEB4B	0x8571	#CJK UNIFIED IDEOGRAPH
+0xEB4C	0x854E	#CJK UNIFIED IDEOGRAPH
+0xEB4D	0x856E	#CJK UNIFIED IDEOGRAPH
+0xEB4E	0x8575	#CJK UNIFIED IDEOGRAPH
+0xEB4F	0x8555	#CJK UNIFIED IDEOGRAPH
+0xEB50	0x8567	#CJK UNIFIED IDEOGRAPH
+0xEB51	0x8560	#CJK UNIFIED IDEOGRAPH
+0xEB52	0x858C	#CJK UNIFIED IDEOGRAPH
+0xEB53	0x8566	#CJK UNIFIED IDEOGRAPH
+0xEB54	0x855D	#CJK UNIFIED IDEOGRAPH
+0xEB55	0x8554	#CJK UNIFIED IDEOGRAPH
+0xEB56	0x8565	#CJK UNIFIED IDEOGRAPH
+0xEB57	0x856C	#CJK UNIFIED IDEOGRAPH
+0xEB58	0x8663	#CJK UNIFIED IDEOGRAPH
+0xEB59	0x8665	#CJK UNIFIED IDEOGRAPH
+0xEB5A	0x8664	#CJK UNIFIED IDEOGRAPH
+0xEB5B	0x879B	#CJK UNIFIED IDEOGRAPH
+0xEB5C	0x878F	#CJK UNIFIED IDEOGRAPH
+0xEB5D	0x8797	#CJK UNIFIED IDEOGRAPH
+0xEB5E	0x8793	#CJK UNIFIED IDEOGRAPH
+0xEB5F	0x8792	#CJK UNIFIED IDEOGRAPH
+0xEB60	0x8788	#CJK UNIFIED IDEOGRAPH
+0xEB61	0x8781	#CJK UNIFIED IDEOGRAPH
+0xEB62	0x8796	#CJK UNIFIED IDEOGRAPH
+0xEB63	0x8798	#CJK UNIFIED IDEOGRAPH
+0xEB64	0x8779	#CJK UNIFIED IDEOGRAPH
+0xEB65	0x8787	#CJK UNIFIED IDEOGRAPH
+0xEB66	0x87A3	#CJK UNIFIED IDEOGRAPH
+0xEB67	0x8785	#CJK UNIFIED IDEOGRAPH
+0xEB68	0x8790	#CJK UNIFIED IDEOGRAPH
+0xEB69	0x8791	#CJK UNIFIED IDEOGRAPH
+0xEB6A	0x879D	#CJK UNIFIED IDEOGRAPH
+0xEB6B	0x8784	#CJK UNIFIED IDEOGRAPH
+0xEB6C	0x8794	#CJK UNIFIED IDEOGRAPH
+0xEB6D	0x879C	#CJK UNIFIED IDEOGRAPH
+0xEB6E	0x879A	#CJK UNIFIED IDEOGRAPH
+0xEB6F	0x8789	#CJK UNIFIED IDEOGRAPH
+0xEB70	0x891E	#CJK UNIFIED IDEOGRAPH
+0xEB71	0x8926	#CJK UNIFIED IDEOGRAPH
+0xEB72	0x8930	#CJK UNIFIED IDEOGRAPH
+0xEB73	0x892D	#CJK UNIFIED IDEOGRAPH
+0xEB74	0x892E	#CJK UNIFIED IDEOGRAPH
+0xEB75	0x8927	#CJK UNIFIED IDEOGRAPH
+0xEB76	0x8931	#CJK UNIFIED IDEOGRAPH
+0xEB77	0x8922	#CJK UNIFIED IDEOGRAPH
+0xEB78	0x8929	#CJK UNIFIED IDEOGRAPH
+0xEB79	0x8923	#CJK UNIFIED IDEOGRAPH
+0xEB7A	0x892F	#CJK UNIFIED IDEOGRAPH
+0xEB7B	0x892C	#CJK UNIFIED IDEOGRAPH
+0xEB7C	0x891F	#CJK UNIFIED IDEOGRAPH
+0xEB7D	0x89F1	#CJK UNIFIED IDEOGRAPH
+0xEB7E	0x8AE0	#CJK UNIFIED IDEOGRAPH
+0xEBA1	0x8AE2	#CJK UNIFIED IDEOGRAPH
+0xEBA2	0x8AF2	#CJK UNIFIED IDEOGRAPH
+0xEBA3	0x8AF4	#CJK UNIFIED IDEOGRAPH
+0xEBA4	0x8AF5	#CJK UNIFIED IDEOGRAPH
+0xEBA5	0x8ADD	#CJK UNIFIED IDEOGRAPH
+0xEBA6	0x8B14	#CJK UNIFIED IDEOGRAPH
+0xEBA7	0x8AE4	#CJK UNIFIED IDEOGRAPH
+0xEBA8	0x8ADF	#CJK UNIFIED IDEOGRAPH
+0xEBA9	0x8AF0	#CJK UNIFIED IDEOGRAPH
+0xEBAA	0x8AC8	#CJK UNIFIED IDEOGRAPH
+0xEBAB	0x8ADE	#CJK UNIFIED IDEOGRAPH
+0xEBAC	0x8AE1	#CJK UNIFIED IDEOGRAPH
+0xEBAD	0x8AE8	#CJK UNIFIED IDEOGRAPH
+0xEBAE	0x8AFF	#CJK UNIFIED IDEOGRAPH
+0xEBAF	0x8AEF	#CJK UNIFIED IDEOGRAPH
+0xEBB0	0x8AFB	#CJK UNIFIED IDEOGRAPH
+0xEBB1	0x8C91	#CJK UNIFIED IDEOGRAPH
+0xEBB2	0x8C92	#CJK UNIFIED IDEOGRAPH
+0xEBB3	0x8C90	#CJK UNIFIED IDEOGRAPH
+0xEBB4	0x8CF5	#CJK UNIFIED IDEOGRAPH
+0xEBB5	0x8CEE	#CJK UNIFIED IDEOGRAPH
+0xEBB6	0x8CF1	#CJK UNIFIED IDEOGRAPH
+0xEBB7	0x8CF0	#CJK UNIFIED IDEOGRAPH
+0xEBB8	0x8CF3	#CJK UNIFIED IDEOGRAPH
+0xEBB9	0x8D6C	#CJK UNIFIED IDEOGRAPH
+0xEBBA	0x8D6E	#CJK UNIFIED IDEOGRAPH
+0xEBBB	0x8DA5	#CJK UNIFIED IDEOGRAPH
+0xEBBC	0x8DA7	#CJK UNIFIED IDEOGRAPH
+0xEBBD	0x8E33	#CJK UNIFIED IDEOGRAPH
+0xEBBE	0x8E3E	#CJK UNIFIED IDEOGRAPH
+0xEBBF	0x8E38	#CJK UNIFIED IDEOGRAPH
+0xEBC0	0x8E40	#CJK UNIFIED IDEOGRAPH
+0xEBC1	0x8E45	#CJK UNIFIED IDEOGRAPH
+0xEBC2	0x8E36	#CJK UNIFIED IDEOGRAPH
+0xEBC3	0x8E3C	#CJK UNIFIED IDEOGRAPH
+0xEBC4	0x8E3D	#CJK UNIFIED IDEOGRAPH
+0xEBC5	0x8E41	#CJK UNIFIED IDEOGRAPH
+0xEBC6	0x8E30	#CJK UNIFIED IDEOGRAPH
+0xEBC7	0x8E3F	#CJK UNIFIED IDEOGRAPH
+0xEBC8	0x8EBD	#CJK UNIFIED IDEOGRAPH
+0xEBC9	0x8F36	#CJK UNIFIED IDEOGRAPH
+0xEBCA	0x8F2E	#CJK UNIFIED IDEOGRAPH
+0xEBCB	0x8F35	#CJK UNIFIED IDEOGRAPH
+0xEBCC	0x8F32	#CJK UNIFIED IDEOGRAPH
+0xEBCD	0x8F39	#CJK UNIFIED IDEOGRAPH
+0xEBCE	0x8F37	#CJK UNIFIED IDEOGRAPH
+0xEBCF	0x8F34	#CJK UNIFIED IDEOGRAPH
+0xEBD0	0x9076	#CJK UNIFIED IDEOGRAPH
+0xEBD1	0x9079	#CJK UNIFIED IDEOGRAPH
+0xEBD2	0x907B	#CJK UNIFIED IDEOGRAPH
+0xEBD3	0x9086	#CJK UNIFIED IDEOGRAPH
+0xEBD4	0x90FA	#CJK UNIFIED IDEOGRAPH
+0xEBD5	0x9133	#CJK UNIFIED IDEOGRAPH
+0xEBD6	0x9135	#CJK UNIFIED IDEOGRAPH
+0xEBD7	0x9136	#CJK UNIFIED IDEOGRAPH
+0xEBD8	0x9193	#CJK UNIFIED IDEOGRAPH
+0xEBD9	0x9190	#CJK UNIFIED IDEOGRAPH
+0xEBDA	0x9191	#CJK UNIFIED IDEOGRAPH
+0xEBDB	0x918D	#CJK UNIFIED IDEOGRAPH
+0xEBDC	0x918F	#CJK UNIFIED IDEOGRAPH
+0xEBDD	0x9327	#CJK UNIFIED IDEOGRAPH
+0xEBDE	0x931E	#CJK UNIFIED IDEOGRAPH
+0xEBDF	0x9308	#CJK UNIFIED IDEOGRAPH
+0xEBE0	0x931F	#CJK UNIFIED IDEOGRAPH
+0xEBE1	0x9306	#CJK UNIFIED IDEOGRAPH
+0xEBE2	0x930F	#CJK UNIFIED IDEOGRAPH
+0xEBE3	0x937A	#CJK UNIFIED IDEOGRAPH
+0xEBE4	0x9338	#CJK UNIFIED IDEOGRAPH
+0xEBE5	0x933C	#CJK UNIFIED IDEOGRAPH
+0xEBE6	0x931B	#CJK UNIFIED IDEOGRAPH
+0xEBE7	0x9323	#CJK UNIFIED IDEOGRAPH
+0xEBE8	0x9312	#CJK UNIFIED IDEOGRAPH
+0xEBE9	0x9301	#CJK UNIFIED IDEOGRAPH
+0xEBEA	0x9346	#CJK UNIFIED IDEOGRAPH
+0xEBEB	0x932D	#CJK UNIFIED IDEOGRAPH
+0xEBEC	0x930E	#CJK UNIFIED IDEOGRAPH
+0xEBED	0x930D	#CJK UNIFIED IDEOGRAPH
+0xEBEE	0x92CB	#CJK UNIFIED IDEOGRAPH
+0xEBEF	0x931D	#CJK UNIFIED IDEOGRAPH
+0xEBF0	0x92FA	#CJK UNIFIED IDEOGRAPH
+0xEBF1	0x9325	#CJK UNIFIED IDEOGRAPH
+0xEBF2	0x9313	#CJK UNIFIED IDEOGRAPH
+0xEBF3	0x92F9	#CJK UNIFIED IDEOGRAPH
+0xEBF4	0x92F7	#CJK UNIFIED IDEOGRAPH
+0xEBF5	0x9334	#CJK UNIFIED IDEOGRAPH
+0xEBF6	0x9302	#CJK UNIFIED IDEOGRAPH
+0xEBF7	0x9324	#CJK UNIFIED IDEOGRAPH
+0xEBF8	0x92FF	#CJK UNIFIED IDEOGRAPH
+0xEBF9	0x9329	#CJK UNIFIED IDEOGRAPH
+0xEBFA	0x9339	#CJK UNIFIED IDEOGRAPH
+0xEBFB	0x9335	#CJK UNIFIED IDEOGRAPH
+0xEBFC	0x932A	#CJK UNIFIED IDEOGRAPH
+0xEBFD	0x9314	#CJK UNIFIED IDEOGRAPH
+0xEBFE	0x930C	#CJK UNIFIED IDEOGRAPH
+0xEC40	0x930B	#CJK UNIFIED IDEOGRAPH
+0xEC41	0x92FE	#CJK UNIFIED IDEOGRAPH
+0xEC42	0x9309	#CJK UNIFIED IDEOGRAPH
+0xEC43	0x9300	#CJK UNIFIED IDEOGRAPH
+0xEC44	0x92FB	#CJK UNIFIED IDEOGRAPH
+0xEC45	0x9316	#CJK UNIFIED IDEOGRAPH
+0xEC46	0x95BC	#CJK UNIFIED IDEOGRAPH
+0xEC47	0x95CD	#CJK UNIFIED IDEOGRAPH
+0xEC48	0x95BE	#CJK UNIFIED IDEOGRAPH
+0xEC49	0x95B9	#CJK UNIFIED IDEOGRAPH
+0xEC4A	0x95BA	#CJK UNIFIED IDEOGRAPH
+0xEC4B	0x95B6	#CJK UNIFIED IDEOGRAPH
+0xEC4C	0x95BF	#CJK UNIFIED IDEOGRAPH
+0xEC4D	0x95B5	#CJK UNIFIED IDEOGRAPH
+0xEC4E	0x95BD	#CJK UNIFIED IDEOGRAPH
+0xEC4F	0x96A9	#CJK UNIFIED IDEOGRAPH
+0xEC50	0x96D4	#CJK UNIFIED IDEOGRAPH
+0xEC51	0x970B	#CJK UNIFIED IDEOGRAPH
+0xEC52	0x9712	#CJK UNIFIED IDEOGRAPH
+0xEC53	0x9710	#CJK UNIFIED IDEOGRAPH
+0xEC54	0x9799	#CJK UNIFIED IDEOGRAPH
+0xEC55	0x9797	#CJK UNIFIED IDEOGRAPH
+0xEC56	0x9794	#CJK UNIFIED IDEOGRAPH
+0xEC57	0x97F0	#CJK UNIFIED IDEOGRAPH
+0xEC58	0x97F8	#CJK UNIFIED IDEOGRAPH
+0xEC59	0x9835	#CJK UNIFIED IDEOGRAPH
+0xEC5A	0x982F	#CJK UNIFIED IDEOGRAPH
+0xEC5B	0x9832	#CJK UNIFIED IDEOGRAPH
+0xEC5C	0x9924	#CJK UNIFIED IDEOGRAPH
+0xEC5D	0x991F	#CJK UNIFIED IDEOGRAPH
+0xEC5E	0x9927	#CJK UNIFIED IDEOGRAPH
+0xEC5F	0x9929	#CJK UNIFIED IDEOGRAPH
+0xEC60	0x999E	#CJK UNIFIED IDEOGRAPH
+0xEC61	0x99EE	#CJK UNIFIED IDEOGRAPH
+0xEC62	0x99EC	#CJK UNIFIED IDEOGRAPH
+0xEC63	0x99E5	#CJK UNIFIED IDEOGRAPH
+0xEC64	0x99E4	#CJK UNIFIED IDEOGRAPH
+0xEC65	0x99F0	#CJK UNIFIED IDEOGRAPH
+0xEC66	0x99E3	#CJK UNIFIED IDEOGRAPH
+0xEC67	0x99EA	#CJK UNIFIED IDEOGRAPH
+0xEC68	0x99E9	#CJK UNIFIED IDEOGRAPH
+0xEC69	0x99E7	#CJK UNIFIED IDEOGRAPH
+0xEC6A	0x9AB9	#CJK UNIFIED IDEOGRAPH
+0xEC6B	0x9ABF	#CJK UNIFIED IDEOGRAPH
+0xEC6C	0x9AB4	#CJK UNIFIED IDEOGRAPH
+0xEC6D	0x9ABB	#CJK UNIFIED IDEOGRAPH
+0xEC6E	0x9AF6	#CJK UNIFIED IDEOGRAPH
+0xEC6F	0x9AFA	#CJK UNIFIED IDEOGRAPH
+0xEC70	0x9AF9	#CJK UNIFIED IDEOGRAPH
+0xEC71	0x9AF7	#CJK UNIFIED IDEOGRAPH
+0xEC72	0x9B33	#CJK UNIFIED IDEOGRAPH
+0xEC73	0x9B80	#CJK UNIFIED IDEOGRAPH
+0xEC74	0x9B85	#CJK UNIFIED IDEOGRAPH
+0xEC75	0x9B87	#CJK UNIFIED IDEOGRAPH
+0xEC76	0x9B7C	#CJK UNIFIED IDEOGRAPH
+0xEC77	0x9B7E	#CJK UNIFIED IDEOGRAPH
+0xEC78	0x9B7B	#CJK UNIFIED IDEOGRAPH
+0xEC79	0x9B82	#CJK UNIFIED IDEOGRAPH
+0xEC7A	0x9B93	#CJK UNIFIED IDEOGRAPH
+0xEC7B	0x9B92	#CJK UNIFIED IDEOGRAPH
+0xEC7C	0x9B90	#CJK UNIFIED IDEOGRAPH
+0xEC7D	0x9B7A	#CJK UNIFIED IDEOGRAPH
+0xEC7E	0x9B95	#CJK UNIFIED IDEOGRAPH
+0xECA1	0x9B7D	#CJK UNIFIED IDEOGRAPH
+0xECA2	0x9B88	#CJK UNIFIED IDEOGRAPH
+0xECA3	0x9D25	#CJK UNIFIED IDEOGRAPH
+0xECA4	0x9D17	#CJK UNIFIED IDEOGRAPH
+0xECA5	0x9D20	#CJK UNIFIED IDEOGRAPH
+0xECA6	0x9D1E	#CJK UNIFIED IDEOGRAPH
+0xECA7	0x9D14	#CJK UNIFIED IDEOGRAPH
+0xECA8	0x9D29	#CJK UNIFIED IDEOGRAPH
+0xECA9	0x9D1D	#CJK UNIFIED IDEOGRAPH
+0xECAA	0x9D18	#CJK UNIFIED IDEOGRAPH
+0xECAB	0x9D22	#CJK UNIFIED IDEOGRAPH
+0xECAC	0x9D10	#CJK UNIFIED IDEOGRAPH
+0xECAD	0x9D19	#CJK UNIFIED IDEOGRAPH
+0xECAE	0x9D1F	#CJK UNIFIED IDEOGRAPH
+0xECAF	0x9E88	#CJK UNIFIED IDEOGRAPH
+0xECB0	0x9E86	#CJK UNIFIED IDEOGRAPH
+0xECB1	0x9E87	#CJK UNIFIED IDEOGRAPH
+0xECB2	0x9EAE	#CJK UNIFIED IDEOGRAPH
+0xECB3	0x9EAD	#CJK UNIFIED IDEOGRAPH
+0xECB4	0x9ED5	#CJK UNIFIED IDEOGRAPH
+0xECB5	0x9ED6	#CJK UNIFIED IDEOGRAPH
+0xECB6	0x9EFA	#CJK UNIFIED IDEOGRAPH
+0xECB7	0x9F12	#CJK UNIFIED IDEOGRAPH
+0xECB8	0x9F3D	#CJK UNIFIED IDEOGRAPH
+0xECB9	0x5126	#CJK UNIFIED IDEOGRAPH
+0xECBA	0x5125	#CJK UNIFIED IDEOGRAPH
+0xECBB	0x5122	#CJK UNIFIED IDEOGRAPH
+0xECBC	0x5124	#CJK UNIFIED IDEOGRAPH
+0xECBD	0x5120	#CJK UNIFIED IDEOGRAPH
+0xECBE	0x5129	#CJK UNIFIED IDEOGRAPH
+0xECBF	0x52F4	#CJK UNIFIED IDEOGRAPH
+0xECC0	0x5693	#CJK UNIFIED IDEOGRAPH
+0xECC1	0x568C	#CJK UNIFIED IDEOGRAPH
+0xECC2	0x568D	#CJK UNIFIED IDEOGRAPH
+0xECC3	0x5686	#CJK UNIFIED IDEOGRAPH
+0xECC4	0x5684	#CJK UNIFIED IDEOGRAPH
+0xECC5	0x5683	#CJK UNIFIED IDEOGRAPH
+0xECC6	0x567E	#CJK UNIFIED IDEOGRAPH
+0xECC7	0x5682	#CJK UNIFIED IDEOGRAPH
+0xECC8	0x567F	#CJK UNIFIED IDEOGRAPH
+0xECC9	0x5681	#CJK UNIFIED IDEOGRAPH
+0xECCA	0x58D6	#CJK UNIFIED IDEOGRAPH
+0xECCB	0x58D4	#CJK UNIFIED IDEOGRAPH
+0xECCC	0x58CF	#CJK UNIFIED IDEOGRAPH
+0xECCD	0x58D2	#CJK UNIFIED IDEOGRAPH
+0xECCE	0x5B2D	#CJK UNIFIED IDEOGRAPH
+0xECCF	0x5B25	#CJK UNIFIED IDEOGRAPH
+0xECD0	0x5B32	#CJK UNIFIED IDEOGRAPH
+0xECD1	0x5B23	#CJK UNIFIED IDEOGRAPH
+0xECD2	0x5B2C	#CJK UNIFIED IDEOGRAPH
+0xECD3	0x5B27	#CJK UNIFIED IDEOGRAPH
+0xECD4	0x5B26	#CJK UNIFIED IDEOGRAPH
+0xECD5	0x5B2F	#CJK UNIFIED IDEOGRAPH
+0xECD6	0x5B2E	#CJK UNIFIED IDEOGRAPH
+0xECD7	0x5B7B	#CJK UNIFIED IDEOGRAPH
+0xECD8	0x5BF1	#CJK UNIFIED IDEOGRAPH
+0xECD9	0x5BF2	#CJK UNIFIED IDEOGRAPH
+0xECDA	0x5DB7	#CJK UNIFIED IDEOGRAPH
+0xECDB	0x5E6C	#CJK UNIFIED IDEOGRAPH
+0xECDC	0x5E6A	#CJK UNIFIED IDEOGRAPH
+0xECDD	0x5FBE	#CJK UNIFIED IDEOGRAPH
+0xECDE	0x5FBB	#CJK UNIFIED IDEOGRAPH
+0xECDF	0x61C3	#CJK UNIFIED IDEOGRAPH
+0xECE0	0x61B5	#CJK UNIFIED IDEOGRAPH
+0xECE1	0x61BC	#CJK UNIFIED IDEOGRAPH
+0xECE2	0x61E7	#CJK UNIFIED IDEOGRAPH
+0xECE3	0x61E0	#CJK UNIFIED IDEOGRAPH
+0xECE4	0x61E5	#CJK UNIFIED IDEOGRAPH
+0xECE5	0x61E4	#CJK UNIFIED IDEOGRAPH
+0xECE6	0x61E8	#CJK UNIFIED IDEOGRAPH
+0xECE7	0x61DE	#CJK UNIFIED IDEOGRAPH
+0xECE8	0x64EF	#CJK UNIFIED IDEOGRAPH
+0xECE9	0x64E9	#CJK UNIFIED IDEOGRAPH
+0xECEA	0x64E3	#CJK UNIFIED IDEOGRAPH
+0xECEB	0x64EB	#CJK UNIFIED IDEOGRAPH
+0xECEC	0x64E4	#CJK UNIFIED IDEOGRAPH
+0xECED	0x64E8	#CJK UNIFIED IDEOGRAPH
+0xECEE	0x6581	#CJK UNIFIED IDEOGRAPH
+0xECEF	0x6580	#CJK UNIFIED IDEOGRAPH
+0xECF0	0x65B6	#CJK UNIFIED IDEOGRAPH
+0xECF1	0x65DA	#CJK UNIFIED IDEOGRAPH
+0xECF2	0x66D2	#CJK UNIFIED IDEOGRAPH
+0xECF3	0x6A8D	#CJK UNIFIED IDEOGRAPH
+0xECF4	0x6A96	#CJK UNIFIED IDEOGRAPH
+0xECF5	0x6A81	#CJK UNIFIED IDEOGRAPH
+0xECF6	0x6AA5	#CJK UNIFIED IDEOGRAPH
+0xECF7	0x6A89	#CJK UNIFIED IDEOGRAPH
+0xECF8	0x6A9F	#CJK UNIFIED IDEOGRAPH
+0xECF9	0x6A9B	#CJK UNIFIED IDEOGRAPH
+0xECFA	0x6AA1	#CJK UNIFIED IDEOGRAPH
+0xECFB	0x6A9E	#CJK UNIFIED IDEOGRAPH
+0xECFC	0x6A87	#CJK UNIFIED IDEOGRAPH
+0xECFD	0x6A93	#CJK UNIFIED IDEOGRAPH
+0xECFE	0x6A8E	#CJK UNIFIED IDEOGRAPH
+0xED40	0x6A95	#CJK UNIFIED IDEOGRAPH
+0xED41	0x6A83	#CJK UNIFIED IDEOGRAPH
+0xED42	0x6AA8	#CJK UNIFIED IDEOGRAPH
+0xED43	0x6AA4	#CJK UNIFIED IDEOGRAPH
+0xED44	0x6A91	#CJK UNIFIED IDEOGRAPH
+0xED45	0x6A7F	#CJK UNIFIED IDEOGRAPH
+0xED46	0x6AA6	#CJK UNIFIED IDEOGRAPH
+0xED47	0x6A9A	#CJK UNIFIED IDEOGRAPH
+0xED48	0x6A85	#CJK UNIFIED IDEOGRAPH
+0xED49	0x6A8C	#CJK UNIFIED IDEOGRAPH
+0xED4A	0x6A92	#CJK UNIFIED IDEOGRAPH
+0xED4B	0x6B5B	#CJK UNIFIED IDEOGRAPH
+0xED4C	0x6BAD	#CJK UNIFIED IDEOGRAPH
+0xED4D	0x6C09	#CJK UNIFIED IDEOGRAPH
+0xED4E	0x6FCC	#CJK UNIFIED IDEOGRAPH
+0xED4F	0x6FA9	#CJK UNIFIED IDEOGRAPH
+0xED50	0x6FF4	#CJK UNIFIED IDEOGRAPH
+0xED51	0x6FD4	#CJK UNIFIED IDEOGRAPH
+0xED52	0x6FE3	#CJK UNIFIED IDEOGRAPH
+0xED53	0x6FDC	#CJK UNIFIED IDEOGRAPH
+0xED54	0x6FED	#CJK UNIFIED IDEOGRAPH
+0xED55	0x6FE7	#CJK UNIFIED IDEOGRAPH
+0xED56	0x6FE6	#CJK UNIFIED IDEOGRAPH
+0xED57	0x6FDE	#CJK UNIFIED IDEOGRAPH
+0xED58	0x6FF2	#CJK UNIFIED IDEOGRAPH
+0xED59	0x6FDD	#CJK UNIFIED IDEOGRAPH
+0xED5A	0x6FE2	#CJK UNIFIED IDEOGRAPH
+0xED5B	0x6FE8	#CJK UNIFIED IDEOGRAPH
+0xED5C	0x71E1	#CJK UNIFIED IDEOGRAPH
+0xED5D	0x71F1	#CJK UNIFIED IDEOGRAPH
+0xED5E	0x71E8	#CJK UNIFIED IDEOGRAPH
+0xED5F	0x71F2	#CJK UNIFIED IDEOGRAPH
+0xED60	0x71E4	#CJK UNIFIED IDEOGRAPH
+0xED61	0x71F0	#CJK UNIFIED IDEOGRAPH
+0xED62	0x71E2	#CJK UNIFIED IDEOGRAPH
+0xED63	0x7373	#CJK UNIFIED IDEOGRAPH
+0xED64	0x736E	#CJK UNIFIED IDEOGRAPH
+0xED65	0x736F	#CJK UNIFIED IDEOGRAPH
+0xED66	0x7497	#CJK UNIFIED IDEOGRAPH
+0xED67	0x74B2	#CJK UNIFIED IDEOGRAPH
+0xED68	0x74AB	#CJK UNIFIED IDEOGRAPH
+0xED69	0x7490	#CJK UNIFIED IDEOGRAPH
+0xED6A	0x74AA	#CJK UNIFIED IDEOGRAPH
+0xED6B	0x74AD	#CJK UNIFIED IDEOGRAPH
+0xED6C	0x74B1	#CJK UNIFIED IDEOGRAPH
+0xED6D	0x74A5	#CJK UNIFIED IDEOGRAPH
+0xED6E	0x74AF	#CJK UNIFIED IDEOGRAPH
+0xED6F	0x7510	#CJK UNIFIED IDEOGRAPH
+0xED70	0x7511	#CJK UNIFIED IDEOGRAPH
+0xED71	0x7512	#CJK UNIFIED IDEOGRAPH
+0xED72	0x750F	#CJK UNIFIED IDEOGRAPH
+0xED73	0x7584	#CJK UNIFIED IDEOGRAPH
+0xED74	0x7643	#CJK UNIFIED IDEOGRAPH
+0xED75	0x7648	#CJK UNIFIED IDEOGRAPH
+0xED76	0x7649	#CJK UNIFIED IDEOGRAPH
+0xED77	0x7647	#CJK UNIFIED IDEOGRAPH
+0xED78	0x76A4	#CJK UNIFIED IDEOGRAPH
+0xED79	0x76E9	#CJK UNIFIED IDEOGRAPH
+0xED7A	0x77B5	#CJK UNIFIED IDEOGRAPH
+0xED7B	0x77AB	#CJK UNIFIED IDEOGRAPH
+0xED7C	0x77B2	#CJK UNIFIED IDEOGRAPH
+0xED7D	0x77B7	#CJK UNIFIED IDEOGRAPH
+0xED7E	0x77B6	#CJK UNIFIED IDEOGRAPH
+0xEDA1	0x77B4	#CJK UNIFIED IDEOGRAPH
+0xEDA2	0x77B1	#CJK UNIFIED IDEOGRAPH
+0xEDA3	0x77A8	#CJK UNIFIED IDEOGRAPH
+0xEDA4	0x77F0	#CJK UNIFIED IDEOGRAPH
+0xEDA5	0x78F3	#CJK UNIFIED IDEOGRAPH
+0xEDA6	0x78FD	#CJK UNIFIED IDEOGRAPH
+0xEDA7	0x7902	#CJK UNIFIED IDEOGRAPH
+0xEDA8	0x78FB	#CJK UNIFIED IDEOGRAPH
+0xEDA9	0x78FC	#CJK UNIFIED IDEOGRAPH
+0xEDAA	0x78F2	#CJK UNIFIED IDEOGRAPH
+0xEDAB	0x7905	#CJK UNIFIED IDEOGRAPH
+0xEDAC	0x78F9	#CJK UNIFIED IDEOGRAPH
+0xEDAD	0x78FE	#CJK UNIFIED IDEOGRAPH
+0xEDAE	0x7904	#CJK UNIFIED IDEOGRAPH
+0xEDAF	0x79AB	#CJK UNIFIED IDEOGRAPH
+0xEDB0	0x79A8	#CJK UNIFIED IDEOGRAPH
+0xEDB1	0x7A5C	#CJK UNIFIED IDEOGRAPH
+0xEDB2	0x7A5B	#CJK UNIFIED IDEOGRAPH
+0xEDB3	0x7A56	#CJK UNIFIED IDEOGRAPH
+0xEDB4	0x7A58	#CJK UNIFIED IDEOGRAPH
+0xEDB5	0x7A54	#CJK UNIFIED IDEOGRAPH
+0xEDB6	0x7A5A	#CJK UNIFIED IDEOGRAPH
+0xEDB7	0x7ABE	#CJK UNIFIED IDEOGRAPH
+0xEDB8	0x7AC0	#CJK UNIFIED IDEOGRAPH
+0xEDB9	0x7AC1	#CJK UNIFIED IDEOGRAPH
+0xEDBA	0x7C05	#CJK UNIFIED IDEOGRAPH
+0xEDBB	0x7C0F	#CJK UNIFIED IDEOGRAPH
+0xEDBC	0x7BF2	#CJK UNIFIED IDEOGRAPH
+0xEDBD	0x7C00	#CJK UNIFIED IDEOGRAPH
+0xEDBE	0x7BFF	#CJK UNIFIED IDEOGRAPH
+0xEDBF	0x7BFB	#CJK UNIFIED IDEOGRAPH
+0xEDC0	0x7C0E	#CJK UNIFIED IDEOGRAPH
+0xEDC1	0x7BF4	#CJK UNIFIED IDEOGRAPH
+0xEDC2	0x7C0B	#CJK UNIFIED IDEOGRAPH
+0xEDC3	0x7BF3	#CJK UNIFIED IDEOGRAPH
+0xEDC4	0x7C02	#CJK UNIFIED IDEOGRAPH
+0xEDC5	0x7C09	#CJK UNIFIED IDEOGRAPH
+0xEDC6	0x7C03	#CJK UNIFIED IDEOGRAPH
+0xEDC7	0x7C01	#CJK UNIFIED IDEOGRAPH
+0xEDC8	0x7BF8	#CJK UNIFIED IDEOGRAPH
+0xEDC9	0x7BFD	#CJK UNIFIED IDEOGRAPH
+0xEDCA	0x7C06	#CJK UNIFIED IDEOGRAPH
+0xEDCB	0x7BF0	#CJK UNIFIED IDEOGRAPH
+0xEDCC	0x7BF1	#CJK UNIFIED IDEOGRAPH
+0xEDCD	0x7C10	#CJK UNIFIED IDEOGRAPH
+0xEDCE	0x7C0A	#CJK UNIFIED IDEOGRAPH
+0xEDCF	0x7CE8	#CJK UNIFIED IDEOGRAPH
+0xEDD0	0x7E2D	#CJK UNIFIED IDEOGRAPH
+0xEDD1	0x7E3C	#CJK UNIFIED IDEOGRAPH
+0xEDD2	0x7E42	#CJK UNIFIED IDEOGRAPH
+0xEDD3	0x7E33	#CJK UNIFIED IDEOGRAPH
+0xEDD4	0x9848	#CJK UNIFIED IDEOGRAPH
+0xEDD5	0x7E38	#CJK UNIFIED IDEOGRAPH
+0xEDD6	0x7E2A	#CJK UNIFIED IDEOGRAPH
+0xEDD7	0x7E49	#CJK UNIFIED IDEOGRAPH
+0xEDD8	0x7E40	#CJK UNIFIED IDEOGRAPH
+0xEDD9	0x7E47	#CJK UNIFIED IDEOGRAPH
+0xEDDA	0x7E29	#CJK UNIFIED IDEOGRAPH
+0xEDDB	0x7E4C	#CJK UNIFIED IDEOGRAPH
+0xEDDC	0x7E30	#CJK UNIFIED IDEOGRAPH
+0xEDDD	0x7E3B	#CJK UNIFIED IDEOGRAPH
+0xEDDE	0x7E36	#CJK UNIFIED IDEOGRAPH
+0xEDDF	0x7E44	#CJK UNIFIED IDEOGRAPH
+0xEDE0	0x7E3A	#CJK UNIFIED IDEOGRAPH
+0xEDE1	0x7F45	#CJK UNIFIED IDEOGRAPH
+0xEDE2	0x7F7F	#CJK UNIFIED IDEOGRAPH
+0xEDE3	0x7F7E	#CJK UNIFIED IDEOGRAPH
+0xEDE4	0x7F7D	#CJK UNIFIED IDEOGRAPH
+0xEDE5	0x7FF4	#CJK UNIFIED IDEOGRAPH
+0xEDE6	0x7FF2	#CJK UNIFIED IDEOGRAPH
+0xEDE7	0x802C	#CJK UNIFIED IDEOGRAPH
+0xEDE8	0x81BB	#CJK UNIFIED IDEOGRAPH
+0xEDE9	0x81C4	#CJK UNIFIED IDEOGRAPH
+0xEDEA	0x81CC	#CJK UNIFIED IDEOGRAPH
+0xEDEB	0x81CA	#CJK UNIFIED IDEOGRAPH
+0xEDEC	0x81C5	#CJK UNIFIED IDEOGRAPH
+0xEDED	0x81C7	#CJK UNIFIED IDEOGRAPH
+0xEDEE	0x81BC	#CJK UNIFIED IDEOGRAPH
+0xEDEF	0x81E9	#CJK UNIFIED IDEOGRAPH
+0xEDF0	0x825B	#CJK UNIFIED IDEOGRAPH
+0xEDF1	0x825A	#CJK UNIFIED IDEOGRAPH
+0xEDF2	0x825C	#CJK UNIFIED IDEOGRAPH
+0xEDF3	0x8583	#CJK UNIFIED IDEOGRAPH
+0xEDF4	0x8580	#CJK UNIFIED IDEOGRAPH
+0xEDF5	0x858F	#CJK UNIFIED IDEOGRAPH
+0xEDF6	0x85A7	#CJK UNIFIED IDEOGRAPH
+0xEDF7	0x8595	#CJK UNIFIED IDEOGRAPH
+0xEDF8	0x85A0	#CJK UNIFIED IDEOGRAPH
+0xEDF9	0x858B	#CJK UNIFIED IDEOGRAPH
+0xEDFA	0x85A3	#CJK UNIFIED IDEOGRAPH
+0xEDFB	0x857B	#CJK UNIFIED IDEOGRAPH
+0xEDFC	0x85A4	#CJK UNIFIED IDEOGRAPH
+0xEDFD	0x859A	#CJK UNIFIED IDEOGRAPH
+0xEDFE	0x859E	#CJK UNIFIED IDEOGRAPH
+0xEE40	0x8577	#CJK UNIFIED IDEOGRAPH
+0xEE41	0x857C	#CJK UNIFIED IDEOGRAPH
+0xEE42	0x8589	#CJK UNIFIED IDEOGRAPH
+0xEE43	0x85A1	#CJK UNIFIED IDEOGRAPH
+0xEE44	0x857A	#CJK UNIFIED IDEOGRAPH
+0xEE45	0x8578	#CJK UNIFIED IDEOGRAPH
+0xEE46	0x8557	#CJK UNIFIED IDEOGRAPH
+0xEE47	0x858E	#CJK UNIFIED IDEOGRAPH
+0xEE48	0x8596	#CJK UNIFIED IDEOGRAPH
+0xEE49	0x8586	#CJK UNIFIED IDEOGRAPH
+0xEE4A	0x858D	#CJK UNIFIED IDEOGRAPH
+0xEE4B	0x8599	#CJK UNIFIED IDEOGRAPH
+0xEE4C	0x859D	#CJK UNIFIED IDEOGRAPH
+0xEE4D	0x8581	#CJK UNIFIED IDEOGRAPH
+0xEE4E	0x85A2	#CJK UNIFIED IDEOGRAPH
+0xEE4F	0x8582	#CJK UNIFIED IDEOGRAPH
+0xEE50	0x8588	#CJK UNIFIED IDEOGRAPH
+0xEE51	0x8585	#CJK UNIFIED IDEOGRAPH
+0xEE52	0x8579	#CJK UNIFIED IDEOGRAPH
+0xEE53	0x8576	#CJK UNIFIED IDEOGRAPH
+0xEE54	0x8598	#CJK UNIFIED IDEOGRAPH
+0xEE55	0x8590	#CJK UNIFIED IDEOGRAPH
+0xEE56	0x859F	#CJK UNIFIED IDEOGRAPH
+0xEE57	0x8668	#CJK UNIFIED IDEOGRAPH
+0xEE58	0x87BE	#CJK UNIFIED IDEOGRAPH
+0xEE59	0x87AA	#CJK UNIFIED IDEOGRAPH
+0xEE5A	0x87AD	#CJK UNIFIED IDEOGRAPH
+0xEE5B	0x87C5	#CJK UNIFIED IDEOGRAPH
+0xEE5C	0x87B0	#CJK UNIFIED IDEOGRAPH
+0xEE5D	0x87AC	#CJK UNIFIED IDEOGRAPH
+0xEE5E	0x87B9	#CJK UNIFIED IDEOGRAPH
+0xEE5F	0x87B5	#CJK UNIFIED IDEOGRAPH
+0xEE60	0x87BC	#CJK UNIFIED IDEOGRAPH
+0xEE61	0x87AE	#CJK UNIFIED IDEOGRAPH
+0xEE62	0x87C9	#CJK UNIFIED IDEOGRAPH
+0xEE63	0x87C3	#CJK UNIFIED IDEOGRAPH
+0xEE64	0x87C2	#CJK UNIFIED IDEOGRAPH
+0xEE65	0x87CC	#CJK UNIFIED IDEOGRAPH
+0xEE66	0x87B7	#CJK UNIFIED IDEOGRAPH
+0xEE67	0x87AF	#CJK UNIFIED IDEOGRAPH
+0xEE68	0x87C4	#CJK UNIFIED IDEOGRAPH
+0xEE69	0x87CA	#CJK UNIFIED IDEOGRAPH
+0xEE6A	0x87B4	#CJK UNIFIED IDEOGRAPH
+0xEE6B	0x87B6	#CJK UNIFIED IDEOGRAPH
+0xEE6C	0x87BF	#CJK UNIFIED IDEOGRAPH
+0xEE6D	0x87B8	#CJK UNIFIED IDEOGRAPH
+0xEE6E	0x87BD	#CJK UNIFIED IDEOGRAPH
+0xEE6F	0x87DE	#CJK UNIFIED IDEOGRAPH
+0xEE70	0x87B2	#CJK UNIFIED IDEOGRAPH
+0xEE71	0x8935	#CJK UNIFIED IDEOGRAPH
+0xEE72	0x8933	#CJK UNIFIED IDEOGRAPH
+0xEE73	0x893C	#CJK UNIFIED IDEOGRAPH
+0xEE74	0x893E	#CJK UNIFIED IDEOGRAPH
+0xEE75	0x8941	#CJK UNIFIED IDEOGRAPH
+0xEE76	0x8952	#CJK UNIFIED IDEOGRAPH
+0xEE77	0x8937	#CJK UNIFIED IDEOGRAPH
+0xEE78	0x8942	#CJK UNIFIED IDEOGRAPH
+0xEE79	0x89AD	#CJK UNIFIED IDEOGRAPH
+0xEE7A	0x89AF	#CJK UNIFIED IDEOGRAPH
+0xEE7B	0x89AE	#CJK UNIFIED IDEOGRAPH
+0xEE7C	0x89F2	#CJK UNIFIED IDEOGRAPH
+0xEE7D	0x89F3	#CJK UNIFIED IDEOGRAPH
+0xEE7E	0x8B1E	#CJK UNIFIED IDEOGRAPH
+0xEEA1	0x8B18	#CJK UNIFIED IDEOGRAPH
+0xEEA2	0x8B16	#CJK UNIFIED IDEOGRAPH
+0xEEA3	0x8B11	#CJK UNIFIED IDEOGRAPH
+0xEEA4	0x8B05	#CJK UNIFIED IDEOGRAPH
+0xEEA5	0x8B0B	#CJK UNIFIED IDEOGRAPH
+0xEEA6	0x8B22	#CJK UNIFIED IDEOGRAPH
+0xEEA7	0x8B0F	#CJK UNIFIED IDEOGRAPH
+0xEEA8	0x8B12	#CJK UNIFIED IDEOGRAPH
+0xEEA9	0x8B15	#CJK UNIFIED IDEOGRAPH
+0xEEAA	0x8B07	#CJK UNIFIED IDEOGRAPH
+0xEEAB	0x8B0D	#CJK UNIFIED IDEOGRAPH
+0xEEAC	0x8B08	#CJK UNIFIED IDEOGRAPH
+0xEEAD	0x8B06	#CJK UNIFIED IDEOGRAPH
+0xEEAE	0x8B1C	#CJK UNIFIED IDEOGRAPH
+0xEEAF	0x8B13	#CJK UNIFIED IDEOGRAPH
+0xEEB0	0x8B1A	#CJK UNIFIED IDEOGRAPH
+0xEEB1	0x8C4F	#CJK UNIFIED IDEOGRAPH
+0xEEB2	0x8C70	#CJK UNIFIED IDEOGRAPH
+0xEEB3	0x8C72	#CJK UNIFIED IDEOGRAPH
+0xEEB4	0x8C71	#CJK UNIFIED IDEOGRAPH
+0xEEB5	0x8C6F	#CJK UNIFIED IDEOGRAPH
+0xEEB6	0x8C95	#CJK UNIFIED IDEOGRAPH
+0xEEB7	0x8C94	#CJK UNIFIED IDEOGRAPH
+0xEEB8	0x8CF9	#CJK UNIFIED IDEOGRAPH
+0xEEB9	0x8D6F	#CJK UNIFIED IDEOGRAPH
+0xEEBA	0x8E4E	#CJK UNIFIED IDEOGRAPH
+0xEEBB	0x8E4D	#CJK UNIFIED IDEOGRAPH
+0xEEBC	0x8E53	#CJK UNIFIED IDEOGRAPH
+0xEEBD	0x8E50	#CJK UNIFIED IDEOGRAPH
+0xEEBE	0x8E4C	#CJK UNIFIED IDEOGRAPH
+0xEEBF	0x8E47	#CJK UNIFIED IDEOGRAPH
+0xEEC0	0x8F43	#CJK UNIFIED IDEOGRAPH
+0xEEC1	0x8F40	#CJK UNIFIED IDEOGRAPH
+0xEEC2	0x9085	#CJK UNIFIED IDEOGRAPH
+0xEEC3	0x907E	#CJK UNIFIED IDEOGRAPH
+0xEEC4	0x9138	#CJK UNIFIED IDEOGRAPH
+0xEEC5	0x919A	#CJK UNIFIED IDEOGRAPH
+0xEEC6	0x91A2	#CJK UNIFIED IDEOGRAPH
+0xEEC7	0x919B	#CJK UNIFIED IDEOGRAPH
+0xEEC8	0x9199	#CJK UNIFIED IDEOGRAPH
+0xEEC9	0x919F	#CJK UNIFIED IDEOGRAPH
+0xEECA	0x91A1	#CJK UNIFIED IDEOGRAPH
+0xEECB	0x919D	#CJK UNIFIED IDEOGRAPH
+0xEECC	0x91A0	#CJK UNIFIED IDEOGRAPH
+0xEECD	0x93A1	#CJK UNIFIED IDEOGRAPH
+0xEECE	0x9383	#CJK UNIFIED IDEOGRAPH
+0xEECF	0x93AF	#CJK UNIFIED IDEOGRAPH
+0xEED0	0x9364	#CJK UNIFIED IDEOGRAPH
+0xEED1	0x9356	#CJK UNIFIED IDEOGRAPH
+0xEED2	0x9347	#CJK UNIFIED IDEOGRAPH
+0xEED3	0x937C	#CJK UNIFIED IDEOGRAPH
+0xEED4	0x9358	#CJK UNIFIED IDEOGRAPH
+0xEED5	0x935C	#CJK UNIFIED IDEOGRAPH
+0xEED6	0x9376	#CJK UNIFIED IDEOGRAPH
+0xEED7	0x9349	#CJK UNIFIED IDEOGRAPH
+0xEED8	0x9350	#CJK UNIFIED IDEOGRAPH
+0xEED9	0x9351	#CJK UNIFIED IDEOGRAPH
+0xEEDA	0x9360	#CJK UNIFIED IDEOGRAPH
+0xEEDB	0x936D	#CJK UNIFIED IDEOGRAPH
+0xEEDC	0x938F	#CJK UNIFIED IDEOGRAPH
+0xEEDD	0x934C	#CJK UNIFIED IDEOGRAPH
+0xEEDE	0x936A	#CJK UNIFIED IDEOGRAPH
+0xEEDF	0x9379	#CJK UNIFIED IDEOGRAPH
+0xEEE0	0x9357	#CJK UNIFIED IDEOGRAPH
+0xEEE1	0x9355	#CJK UNIFIED IDEOGRAPH
+0xEEE2	0x9352	#CJK UNIFIED IDEOGRAPH
+0xEEE3	0x934F	#CJK UNIFIED IDEOGRAPH
+0xEEE4	0x9371	#CJK UNIFIED IDEOGRAPH
+0xEEE5	0x9377	#CJK UNIFIED IDEOGRAPH
+0xEEE6	0x937B	#CJK UNIFIED IDEOGRAPH
+0xEEE7	0x9361	#CJK UNIFIED IDEOGRAPH
+0xEEE8	0x935E	#CJK UNIFIED IDEOGRAPH
+0xEEE9	0x9363	#CJK UNIFIED IDEOGRAPH
+0xEEEA	0x9367	#CJK UNIFIED IDEOGRAPH
+0xEEEB	0x9380	#CJK UNIFIED IDEOGRAPH
+0xEEEC	0x934E	#CJK UNIFIED IDEOGRAPH
+0xEEED	0x9359	#CJK UNIFIED IDEOGRAPH
+0xEEEE	0x95C7	#CJK UNIFIED IDEOGRAPH
+0xEEEF	0x95C0	#CJK UNIFIED IDEOGRAPH
+0xEEF0	0x95C9	#CJK UNIFIED IDEOGRAPH
+0xEEF1	0x95C3	#CJK UNIFIED IDEOGRAPH
+0xEEF2	0x95C5	#CJK UNIFIED IDEOGRAPH
+0xEEF3	0x95B7	#CJK UNIFIED IDEOGRAPH
+0xEEF4	0x96AE	#CJK UNIFIED IDEOGRAPH
+0xEEF5	0x96B0	#CJK UNIFIED IDEOGRAPH
+0xEEF6	0x96AC	#CJK UNIFIED IDEOGRAPH
+0xEEF7	0x9720	#CJK UNIFIED IDEOGRAPH
+0xEEF8	0x971F	#CJK UNIFIED IDEOGRAPH
+0xEEF9	0x9718	#CJK UNIFIED IDEOGRAPH
+0xEEFA	0x971D	#CJK UNIFIED IDEOGRAPH
+0xEEFB	0x9719	#CJK UNIFIED IDEOGRAPH
+0xEEFC	0x979A	#CJK UNIFIED IDEOGRAPH
+0xEEFD	0x97A1	#CJK UNIFIED IDEOGRAPH
+0xEEFE	0x979C	#CJK UNIFIED IDEOGRAPH
+0xEF40	0x979E	#CJK UNIFIED IDEOGRAPH
+0xEF41	0x979D	#CJK UNIFIED IDEOGRAPH
+0xEF42	0x97D5	#CJK UNIFIED IDEOGRAPH
+0xEF43	0x97D4	#CJK UNIFIED IDEOGRAPH
+0xEF44	0x97F1	#CJK UNIFIED IDEOGRAPH
+0xEF45	0x9841	#CJK UNIFIED IDEOGRAPH
+0xEF46	0x9844	#CJK UNIFIED IDEOGRAPH
+0xEF47	0x984A	#CJK UNIFIED IDEOGRAPH
+0xEF48	0x9849	#CJK UNIFIED IDEOGRAPH
+0xEF49	0x9845	#CJK UNIFIED IDEOGRAPH
+0xEF4A	0x9843	#CJK UNIFIED IDEOGRAPH
+0xEF4B	0x9925	#CJK UNIFIED IDEOGRAPH
+0xEF4C	0x992B	#CJK UNIFIED IDEOGRAPH
+0xEF4D	0x992C	#CJK UNIFIED IDEOGRAPH
+0xEF4E	0x992A	#CJK UNIFIED IDEOGRAPH
+0xEF4F	0x9933	#CJK UNIFIED IDEOGRAPH
+0xEF50	0x9932	#CJK UNIFIED IDEOGRAPH
+0xEF51	0x992F	#CJK UNIFIED IDEOGRAPH
+0xEF52	0x992D	#CJK UNIFIED IDEOGRAPH
+0xEF53	0x9931	#CJK UNIFIED IDEOGRAPH
+0xEF54	0x9930	#CJK UNIFIED IDEOGRAPH
+0xEF55	0x9998	#CJK UNIFIED IDEOGRAPH
+0xEF56	0x99A3	#CJK UNIFIED IDEOGRAPH
+0xEF57	0x99A1	#CJK UNIFIED IDEOGRAPH
+0xEF58	0x9A02	#CJK UNIFIED IDEOGRAPH
+0xEF59	0x99FA	#CJK UNIFIED IDEOGRAPH
+0xEF5A	0x99F4	#CJK UNIFIED IDEOGRAPH
+0xEF5B	0x99F7	#CJK UNIFIED IDEOGRAPH
+0xEF5C	0x99F9	#CJK UNIFIED IDEOGRAPH
+0xEF5D	0x99F8	#CJK UNIFIED IDEOGRAPH
+0xEF5E	0x99F6	#CJK UNIFIED IDEOGRAPH
+0xEF5F	0x99FB	#CJK UNIFIED IDEOGRAPH
+0xEF60	0x99FD	#CJK UNIFIED IDEOGRAPH
+0xEF61	0x99FE	#CJK UNIFIED IDEOGRAPH
+0xEF62	0x99FC	#CJK UNIFIED IDEOGRAPH
+0xEF63	0x9A03	#CJK UNIFIED IDEOGRAPH
+0xEF64	0x9ABE	#CJK UNIFIED IDEOGRAPH
+0xEF65	0x9AFE	#CJK UNIFIED IDEOGRAPH
+0xEF66	0x9AFD	#CJK UNIFIED IDEOGRAPH
+0xEF67	0x9B01	#CJK UNIFIED IDEOGRAPH
+0xEF68	0x9AFC	#CJK UNIFIED IDEOGRAPH
+0xEF69	0x9B48	#CJK UNIFIED IDEOGRAPH
+0xEF6A	0x9B9A	#CJK UNIFIED IDEOGRAPH
+0xEF6B	0x9BA8	#CJK UNIFIED IDEOGRAPH
+0xEF6C	0x9B9E	#CJK UNIFIED IDEOGRAPH
+0xEF6D	0x9B9B	#CJK UNIFIED IDEOGRAPH
+0xEF6E	0x9BA6	#CJK UNIFIED IDEOGRAPH
+0xEF6F	0x9BA1	#CJK UNIFIED IDEOGRAPH
+0xEF70	0x9BA5	#CJK UNIFIED IDEOGRAPH
+0xEF71	0x9BA4	#CJK UNIFIED IDEOGRAPH
+0xEF72	0x9B86	#CJK UNIFIED IDEOGRAPH
+0xEF73	0x9BA2	#CJK UNIFIED IDEOGRAPH
+0xEF74	0x9BA0	#CJK UNIFIED IDEOGRAPH
+0xEF75	0x9BAF	#CJK UNIFIED IDEOGRAPH
+0xEF76	0x9D33	#CJK UNIFIED IDEOGRAPH
+0xEF77	0x9D41	#CJK UNIFIED IDEOGRAPH
+0xEF78	0x9D67	#CJK UNIFIED IDEOGRAPH
+0xEF79	0x9D36	#CJK UNIFIED IDEOGRAPH
+0xEF7A	0x9D2E	#CJK UNIFIED IDEOGRAPH
+0xEF7B	0x9D2F	#CJK UNIFIED IDEOGRAPH
+0xEF7C	0x9D31	#CJK UNIFIED IDEOGRAPH
+0xEF7D	0x9D38	#CJK UNIFIED IDEOGRAPH
+0xEF7E	0x9D30	#CJK UNIFIED IDEOGRAPH
+0xEFA1	0x9D45	#CJK UNIFIED IDEOGRAPH
+0xEFA2	0x9D42	#CJK UNIFIED IDEOGRAPH
+0xEFA3	0x9D43	#CJK UNIFIED IDEOGRAPH
+0xEFA4	0x9D3E	#CJK UNIFIED IDEOGRAPH
+0xEFA5	0x9D37	#CJK UNIFIED IDEOGRAPH
+0xEFA6	0x9D40	#CJK UNIFIED IDEOGRAPH
+0xEFA7	0x9D3D	#CJK UNIFIED IDEOGRAPH
+0xEFA8	0x7FF5	#CJK UNIFIED IDEOGRAPH
+0xEFA9	0x9D2D	#CJK UNIFIED IDEOGRAPH
+0xEFAA	0x9E8A	#CJK UNIFIED IDEOGRAPH
+0xEFAB	0x9E89	#CJK UNIFIED IDEOGRAPH
+0xEFAC	0x9E8D	#CJK UNIFIED IDEOGRAPH
+0xEFAD	0x9EB0	#CJK UNIFIED IDEOGRAPH
+0xEFAE	0x9EC8	#CJK UNIFIED IDEOGRAPH
+0xEFAF	0x9EDA	#CJK UNIFIED IDEOGRAPH
+0xEFB0	0x9EFB	#CJK UNIFIED IDEOGRAPH
+0xEFB1	0x9EFF	#CJK UNIFIED IDEOGRAPH
+0xEFB2	0x9F24	#CJK UNIFIED IDEOGRAPH
+0xEFB3	0x9F23	#CJK UNIFIED IDEOGRAPH
+0xEFB4	0x9F22	#CJK UNIFIED IDEOGRAPH
+0xEFB5	0x9F54	#CJK UNIFIED IDEOGRAPH
+0xEFB6	0x9FA0	#CJK UNIFIED IDEOGRAPH
+0xEFB7	0x5131	#CJK UNIFIED IDEOGRAPH
+0xEFB8	0x512D	#CJK UNIFIED IDEOGRAPH
+0xEFB9	0x512E	#CJK UNIFIED IDEOGRAPH
+0xEFBA	0x5698	#CJK UNIFIED IDEOGRAPH
+0xEFBB	0x569C	#CJK UNIFIED IDEOGRAPH
+0xEFBC	0x5697	#CJK UNIFIED IDEOGRAPH
+0xEFBD	0x569A	#CJK UNIFIED IDEOGRAPH
+0xEFBE	0x569D	#CJK UNIFIED IDEOGRAPH
+0xEFBF	0x5699	#CJK UNIFIED IDEOGRAPH
+0xEFC0	0x5970	#CJK UNIFIED IDEOGRAPH
+0xEFC1	0x5B3C	#CJK UNIFIED IDEOGRAPH
+0xEFC2	0x5C69	#CJK UNIFIED IDEOGRAPH
+0xEFC3	0x5C6A	#CJK UNIFIED IDEOGRAPH
+0xEFC4	0x5DC0	#CJK UNIFIED IDEOGRAPH
+0xEFC5	0x5E6D	#CJK UNIFIED IDEOGRAPH
+0xEFC6	0x5E6E	#CJK UNIFIED IDEOGRAPH
+0xEFC7	0x61D8	#CJK UNIFIED IDEOGRAPH
+0xEFC8	0x61DF	#CJK UNIFIED IDEOGRAPH
+0xEFC9	0x61ED	#CJK UNIFIED IDEOGRAPH
+0xEFCA	0x61EE	#CJK UNIFIED IDEOGRAPH
+0xEFCB	0x61F1	#CJK UNIFIED IDEOGRAPH
+0xEFCC	0x61EA	#CJK UNIFIED IDEOGRAPH
+0xEFCD	0x61F0	#CJK UNIFIED IDEOGRAPH
+0xEFCE	0x61EB	#CJK UNIFIED IDEOGRAPH
+0xEFCF	0x61D6	#CJK UNIFIED IDEOGRAPH
+0xEFD0	0x61E9	#CJK UNIFIED IDEOGRAPH
+0xEFD1	0x64FF	#CJK UNIFIED IDEOGRAPH
+0xEFD2	0x6504	#CJK UNIFIED IDEOGRAPH
+0xEFD3	0x64FD	#CJK UNIFIED IDEOGRAPH
+0xEFD4	0x64F8	#CJK UNIFIED IDEOGRAPH
+0xEFD5	0x6501	#CJK UNIFIED IDEOGRAPH
+0xEFD6	0x6503	#CJK UNIFIED IDEOGRAPH
+0xEFD7	0x64FC	#CJK UNIFIED IDEOGRAPH
+0xEFD8	0x6594	#CJK UNIFIED IDEOGRAPH
+0xEFD9	0x65DB	#CJK UNIFIED IDEOGRAPH
+0xEFDA	0x66DA	#CJK UNIFIED IDEOGRAPH
+0xEFDB	0x66DB	#CJK UNIFIED IDEOGRAPH
+0xEFDC	0x66D8	#CJK UNIFIED IDEOGRAPH
+0xEFDD	0x6AC5	#CJK UNIFIED IDEOGRAPH
+0xEFDE	0x6AB9	#CJK UNIFIED IDEOGRAPH
+0xEFDF	0x6ABD	#CJK UNIFIED IDEOGRAPH
+0xEFE0	0x6AE1	#CJK UNIFIED IDEOGRAPH
+0xEFE1	0x6AC6	#CJK UNIFIED IDEOGRAPH
+0xEFE2	0x6ABA	#CJK UNIFIED IDEOGRAPH
+0xEFE3	0x6AB6	#CJK UNIFIED IDEOGRAPH
+0xEFE4	0x6AB7	#CJK UNIFIED IDEOGRAPH
+0xEFE5	0x6AC7	#CJK UNIFIED IDEOGRAPH
+0xEFE6	0x6AB4	#CJK UNIFIED IDEOGRAPH
+0xEFE7	0x6AAD	#CJK UNIFIED IDEOGRAPH
+0xEFE8	0x6B5E	#CJK UNIFIED IDEOGRAPH
+0xEFE9	0x6BC9	#CJK UNIFIED IDEOGRAPH
+0xEFEA	0x6C0B	#CJK UNIFIED IDEOGRAPH
+0xEFEB	0x7007	#CJK UNIFIED IDEOGRAPH
+0xEFEC	0x700C	#CJK UNIFIED IDEOGRAPH
+0xEFED	0x700D	#CJK UNIFIED IDEOGRAPH
+0xEFEE	0x7001	#CJK UNIFIED IDEOGRAPH
+0xEFEF	0x7005	#CJK UNIFIED IDEOGRAPH
+0xEFF0	0x7014	#CJK UNIFIED IDEOGRAPH
+0xEFF1	0x700E	#CJK UNIFIED IDEOGRAPH
+0xEFF2	0x6FFF	#CJK UNIFIED IDEOGRAPH
+0xEFF3	0x7000	#CJK UNIFIED IDEOGRAPH
+0xEFF4	0x6FFB	#CJK UNIFIED IDEOGRAPH
+0xEFF5	0x7026	#CJK UNIFIED IDEOGRAPH
+0xEFF6	0x6FFC	#CJK UNIFIED IDEOGRAPH
+0xEFF7	0x6FF7	#CJK UNIFIED IDEOGRAPH
+0xEFF8	0x700A	#CJK UNIFIED IDEOGRAPH
+0xEFF9	0x7201	#CJK UNIFIED IDEOGRAPH
+0xEFFA	0x71FF	#CJK UNIFIED IDEOGRAPH
+0xEFFB	0x71F9	#CJK UNIFIED IDEOGRAPH
+0xEFFC	0x7203	#CJK UNIFIED IDEOGRAPH
+0xEFFD	0x71FD	#CJK UNIFIED IDEOGRAPH
+0xEFFE	0x7376	#CJK UNIFIED IDEOGRAPH
+0xF040	0x74B8	#CJK UNIFIED IDEOGRAPH
+0xF041	0x74C0	#CJK UNIFIED IDEOGRAPH
+0xF042	0x74B5	#CJK UNIFIED IDEOGRAPH
+0xF043	0x74C1	#CJK UNIFIED IDEOGRAPH
+0xF044	0x74BE	#CJK UNIFIED IDEOGRAPH
+0xF045	0x74B6	#CJK UNIFIED IDEOGRAPH
+0xF046	0x74BB	#CJK UNIFIED IDEOGRAPH
+0xF047	0x74C2	#CJK UNIFIED IDEOGRAPH
+0xF048	0x7514	#CJK UNIFIED IDEOGRAPH
+0xF049	0x7513	#CJK UNIFIED IDEOGRAPH
+0xF04A	0x765C	#CJK UNIFIED IDEOGRAPH
+0xF04B	0x7664	#CJK UNIFIED IDEOGRAPH
+0xF04C	0x7659	#CJK UNIFIED IDEOGRAPH
+0xF04D	0x7650	#CJK UNIFIED IDEOGRAPH
+0xF04E	0x7653	#CJK UNIFIED IDEOGRAPH
+0xF04F	0x7657	#CJK UNIFIED IDEOGRAPH
+0xF050	0x765A	#CJK UNIFIED IDEOGRAPH
+0xF051	0x76A6	#CJK UNIFIED IDEOGRAPH
+0xF052	0x76BD	#CJK UNIFIED IDEOGRAPH
+0xF053	0x76EC	#CJK UNIFIED IDEOGRAPH
+0xF054	0x77C2	#CJK UNIFIED IDEOGRAPH
+0xF055	0x77BA	#CJK UNIFIED IDEOGRAPH
+0xF056	0x78FF	#CJK UNIFIED IDEOGRAPH
+0xF057	0x790C	#CJK UNIFIED IDEOGRAPH
+0xF058	0x7913	#CJK UNIFIED IDEOGRAPH
+0xF059	0x7914	#CJK UNIFIED IDEOGRAPH
+0xF05A	0x7909	#CJK UNIFIED IDEOGRAPH
+0xF05B	0x7910	#CJK UNIFIED IDEOGRAPH
+0xF05C	0x7912	#CJK UNIFIED IDEOGRAPH
+0xF05D	0x7911	#CJK UNIFIED IDEOGRAPH
+0xF05E	0x79AD	#CJK UNIFIED IDEOGRAPH
+0xF05F	0x79AC	#CJK UNIFIED IDEOGRAPH
+0xF060	0x7A5F	#CJK UNIFIED IDEOGRAPH
+0xF061	0x7C1C	#CJK UNIFIED IDEOGRAPH
+0xF062	0x7C29	#CJK UNIFIED IDEOGRAPH
+0xF063	0x7C19	#CJK UNIFIED IDEOGRAPH
+0xF064	0x7C20	#CJK UNIFIED IDEOGRAPH
+0xF065	0x7C1F	#CJK UNIFIED IDEOGRAPH
+0xF066	0x7C2D	#CJK UNIFIED IDEOGRAPH
+0xF067	0x7C1D	#CJK UNIFIED IDEOGRAPH
+0xF068	0x7C26	#CJK UNIFIED IDEOGRAPH
+0xF069	0x7C28	#CJK UNIFIED IDEOGRAPH
+0xF06A	0x7C22	#CJK UNIFIED IDEOGRAPH
+0xF06B	0x7C25	#CJK UNIFIED IDEOGRAPH
+0xF06C	0x7C30	#CJK UNIFIED IDEOGRAPH
+0xF06D	0x7E5C	#CJK UNIFIED IDEOGRAPH
+0xF06E	0x7E50	#CJK UNIFIED IDEOGRAPH
+0xF06F	0x7E56	#CJK UNIFIED IDEOGRAPH
+0xF070	0x7E63	#CJK UNIFIED IDEOGRAPH
+0xF071	0x7E58	#CJK UNIFIED IDEOGRAPH
+0xF072	0x7E62	#CJK UNIFIED IDEOGRAPH
+0xF073	0x7E5F	#CJK UNIFIED IDEOGRAPH
+0xF074	0x7E51	#CJK UNIFIED IDEOGRAPH
+0xF075	0x7E60	#CJK UNIFIED IDEOGRAPH
+0xF076	0x7E57	#CJK UNIFIED IDEOGRAPH
+0xF077	0x7E53	#CJK UNIFIED IDEOGRAPH
+0xF078	0x7FB5	#CJK UNIFIED IDEOGRAPH
+0xF079	0x7FB3	#CJK UNIFIED IDEOGRAPH
+0xF07A	0x7FF7	#CJK UNIFIED IDEOGRAPH
+0xF07B	0x7FF8	#CJK UNIFIED IDEOGRAPH
+0xF07C	0x8075	#CJK UNIFIED IDEOGRAPH
+0xF07D	0x81D1	#CJK UNIFIED IDEOGRAPH
+0xF07E	0x81D2	#CJK UNIFIED IDEOGRAPH
+0xF0A1	0x81D0	#CJK UNIFIED IDEOGRAPH
+0xF0A2	0x825F	#CJK UNIFIED IDEOGRAPH
+0xF0A3	0x825E	#CJK UNIFIED IDEOGRAPH
+0xF0A4	0x85B4	#CJK UNIFIED IDEOGRAPH
+0xF0A5	0x85C6	#CJK UNIFIED IDEOGRAPH
+0xF0A6	0x85C0	#CJK UNIFIED IDEOGRAPH
+0xF0A7	0x85C3	#CJK UNIFIED IDEOGRAPH
+0xF0A8	0x85C2	#CJK UNIFIED IDEOGRAPH
+0xF0A9	0x85B3	#CJK UNIFIED IDEOGRAPH
+0xF0AA	0x85B5	#CJK UNIFIED IDEOGRAPH
+0xF0AB	0x85BD	#CJK UNIFIED IDEOGRAPH
+0xF0AC	0x85C7	#CJK UNIFIED IDEOGRAPH
+0xF0AD	0x85C4	#CJK UNIFIED IDEOGRAPH
+0xF0AE	0x85BF	#CJK UNIFIED IDEOGRAPH
+0xF0AF	0x85CB	#CJK UNIFIED IDEOGRAPH
+0xF0B0	0x85CE	#CJK UNIFIED IDEOGRAPH
+0xF0B1	0x85C8	#CJK UNIFIED IDEOGRAPH
+0xF0B2	0x85C5	#CJK UNIFIED IDEOGRAPH
+0xF0B3	0x85B1	#CJK UNIFIED IDEOGRAPH
+0xF0B4	0x85B6	#CJK UNIFIED IDEOGRAPH
+0xF0B5	0x85D2	#CJK UNIFIED IDEOGRAPH
+0xF0B6	0x8624	#CJK UNIFIED IDEOGRAPH
+0xF0B7	0x85B8	#CJK UNIFIED IDEOGRAPH
+0xF0B8	0x85B7	#CJK UNIFIED IDEOGRAPH
+0xF0B9	0x85BE	#CJK UNIFIED IDEOGRAPH
+0xF0BA	0x8669	#CJK UNIFIED IDEOGRAPH
+0xF0BB	0x87E7	#CJK UNIFIED IDEOGRAPH
+0xF0BC	0x87E6	#CJK UNIFIED IDEOGRAPH
+0xF0BD	0x87E2	#CJK UNIFIED IDEOGRAPH
+0xF0BE	0x87DB	#CJK UNIFIED IDEOGRAPH
+0xF0BF	0x87EB	#CJK UNIFIED IDEOGRAPH
+0xF0C0	0x87EA	#CJK UNIFIED IDEOGRAPH
+0xF0C1	0x87E5	#CJK UNIFIED IDEOGRAPH
+0xF0C2	0x87DF	#CJK UNIFIED IDEOGRAPH
+0xF0C3	0x87F3	#CJK UNIFIED IDEOGRAPH
+0xF0C4	0x87E4	#CJK UNIFIED IDEOGRAPH
+0xF0C5	0x87D4	#CJK UNIFIED IDEOGRAPH
+0xF0C6	0x87DC	#CJK UNIFIED IDEOGRAPH
+0xF0C7	0x87D3	#CJK UNIFIED IDEOGRAPH
+0xF0C8	0x87ED	#CJK UNIFIED IDEOGRAPH
+0xF0C9	0x87D8	#CJK UNIFIED IDEOGRAPH
+0xF0CA	0x87E3	#CJK UNIFIED IDEOGRAPH
+0xF0CB	0x87A4	#CJK UNIFIED IDEOGRAPH
+0xF0CC	0x87D7	#CJK UNIFIED IDEOGRAPH
+0xF0CD	0x87D9	#CJK UNIFIED IDEOGRAPH
+0xF0CE	0x8801	#CJK UNIFIED IDEOGRAPH
+0xF0CF	0x87F4	#CJK UNIFIED IDEOGRAPH
+0xF0D0	0x87E8	#CJK UNIFIED IDEOGRAPH
+0xF0D1	0x87DD	#CJK UNIFIED IDEOGRAPH
+0xF0D2	0x8953	#CJK UNIFIED IDEOGRAPH
+0xF0D3	0x894B	#CJK UNIFIED IDEOGRAPH
+0xF0D4	0x894F	#CJK UNIFIED IDEOGRAPH
+0xF0D5	0x894C	#CJK UNIFIED IDEOGRAPH
+0xF0D6	0x8946	#CJK UNIFIED IDEOGRAPH
+0xF0D7	0x8950	#CJK UNIFIED IDEOGRAPH
+0xF0D8	0x8951	#CJK UNIFIED IDEOGRAPH
+0xF0D9	0x8949	#CJK UNIFIED IDEOGRAPH
+0xF0DA	0x8B2A	#CJK UNIFIED IDEOGRAPH
+0xF0DB	0x8B27	#CJK UNIFIED IDEOGRAPH
+0xF0DC	0x8B23	#CJK UNIFIED IDEOGRAPH
+0xF0DD	0x8B33	#CJK UNIFIED IDEOGRAPH
+0xF0DE	0x8B30	#CJK UNIFIED IDEOGRAPH
+0xF0DF	0x8B35	#CJK UNIFIED IDEOGRAPH
+0xF0E0	0x8B47	#CJK UNIFIED IDEOGRAPH
+0xF0E1	0x8B2F	#CJK UNIFIED IDEOGRAPH
+0xF0E2	0x8B3C	#CJK UNIFIED IDEOGRAPH
+0xF0E3	0x8B3E	#CJK UNIFIED IDEOGRAPH
+0xF0E4	0x8B31	#CJK UNIFIED IDEOGRAPH
+0xF0E5	0x8B25	#CJK UNIFIED IDEOGRAPH
+0xF0E6	0x8B37	#CJK UNIFIED IDEOGRAPH
+0xF0E7	0x8B26	#CJK UNIFIED IDEOGRAPH
+0xF0E8	0x8B36	#CJK UNIFIED IDEOGRAPH
+0xF0E9	0x8B2E	#CJK UNIFIED IDEOGRAPH
+0xF0EA	0x8B24	#CJK UNIFIED IDEOGRAPH
+0xF0EB	0x8B3B	#CJK UNIFIED IDEOGRAPH
+0xF0EC	0x8B3D	#CJK UNIFIED IDEOGRAPH
+0xF0ED	0x8B3A	#CJK UNIFIED IDEOGRAPH
+0xF0EE	0x8C42	#CJK UNIFIED IDEOGRAPH
+0xF0EF	0x8C75	#CJK UNIFIED IDEOGRAPH
+0xF0F0	0x8C99	#CJK UNIFIED IDEOGRAPH
+0xF0F1	0x8C98	#CJK UNIFIED IDEOGRAPH
+0xF0F2	0x8C97	#CJK UNIFIED IDEOGRAPH
+0xF0F3	0x8CFE	#CJK UNIFIED IDEOGRAPH
+0xF0F4	0x8D04	#CJK UNIFIED IDEOGRAPH
+0xF0F5	0x8D02	#CJK UNIFIED IDEOGRAPH
+0xF0F6	0x8D00	#CJK UNIFIED IDEOGRAPH
+0xF0F7	0x8E5C	#CJK UNIFIED IDEOGRAPH
+0xF0F8	0x8E62	#CJK UNIFIED IDEOGRAPH
+0xF0F9	0x8E60	#CJK UNIFIED IDEOGRAPH
+0xF0FA	0x8E57	#CJK UNIFIED IDEOGRAPH
+0xF0FB	0x8E56	#CJK UNIFIED IDEOGRAPH
+0xF0FC	0x8E5E	#CJK UNIFIED IDEOGRAPH
+0xF0FD	0x8E65	#CJK UNIFIED IDEOGRAPH
+0xF0FE	0x8E67	#CJK UNIFIED IDEOGRAPH
+0xF140	0x8E5B	#CJK UNIFIED IDEOGRAPH
+0xF141	0x8E5A	#CJK UNIFIED IDEOGRAPH
+0xF142	0x8E61	#CJK UNIFIED IDEOGRAPH
+0xF143	0x8E5D	#CJK UNIFIED IDEOGRAPH
+0xF144	0x8E69	#CJK UNIFIED IDEOGRAPH
+0xF145	0x8E54	#CJK UNIFIED IDEOGRAPH
+0xF146	0x8F46	#CJK UNIFIED IDEOGRAPH
+0xF147	0x8F47	#CJK UNIFIED IDEOGRAPH
+0xF148	0x8F48	#CJK UNIFIED IDEOGRAPH
+0xF149	0x8F4B	#CJK UNIFIED IDEOGRAPH
+0xF14A	0x9128	#CJK UNIFIED IDEOGRAPH
+0xF14B	0x913A	#CJK UNIFIED IDEOGRAPH
+0xF14C	0x913B	#CJK UNIFIED IDEOGRAPH
+0xF14D	0x913E	#CJK UNIFIED IDEOGRAPH
+0xF14E	0x91A8	#CJK UNIFIED IDEOGRAPH
+0xF14F	0x91A5	#CJK UNIFIED IDEOGRAPH
+0xF150	0x91A7	#CJK UNIFIED IDEOGRAPH
+0xF151	0x91AF	#CJK UNIFIED IDEOGRAPH
+0xF152	0x91AA	#CJK UNIFIED IDEOGRAPH
+0xF153	0x93B5	#CJK UNIFIED IDEOGRAPH
+0xF154	0x938C	#CJK UNIFIED IDEOGRAPH
+0xF155	0x9392	#CJK UNIFIED IDEOGRAPH
+0xF156	0x93B7	#CJK UNIFIED IDEOGRAPH
+0xF157	0x939B	#CJK UNIFIED IDEOGRAPH
+0xF158	0x939D	#CJK UNIFIED IDEOGRAPH
+0xF159	0x9389	#CJK UNIFIED IDEOGRAPH
+0xF15A	0x93A7	#CJK UNIFIED IDEOGRAPH
+0xF15B	0x938E	#CJK UNIFIED IDEOGRAPH
+0xF15C	0x93AA	#CJK UNIFIED IDEOGRAPH
+0xF15D	0x939E	#CJK UNIFIED IDEOGRAPH
+0xF15E	0x93A6	#CJK UNIFIED IDEOGRAPH
+0xF15F	0x9395	#CJK UNIFIED IDEOGRAPH
+0xF160	0x9388	#CJK UNIFIED IDEOGRAPH
+0xF161	0x9399	#CJK UNIFIED IDEOGRAPH
+0xF162	0x939F	#CJK UNIFIED IDEOGRAPH
+0xF163	0x938D	#CJK UNIFIED IDEOGRAPH
+0xF164	0x93B1	#CJK UNIFIED IDEOGRAPH
+0xF165	0x9391	#CJK UNIFIED IDEOGRAPH
+0xF166	0x93B2	#CJK UNIFIED IDEOGRAPH
+0xF167	0x93A4	#CJK UNIFIED IDEOGRAPH
+0xF168	0x93A8	#CJK UNIFIED IDEOGRAPH
+0xF169	0x93B4	#CJK UNIFIED IDEOGRAPH
+0xF16A	0x93A3	#CJK UNIFIED IDEOGRAPH
+0xF16B	0x93A5	#CJK UNIFIED IDEOGRAPH
+0xF16C	0x95D2	#CJK UNIFIED IDEOGRAPH
+0xF16D	0x95D3	#CJK UNIFIED IDEOGRAPH
+0xF16E	0x95D1	#CJK UNIFIED IDEOGRAPH
+0xF16F	0x96B3	#CJK UNIFIED IDEOGRAPH
+0xF170	0x96D7	#CJK UNIFIED IDEOGRAPH
+0xF171	0x96DA	#CJK UNIFIED IDEOGRAPH
+0xF172	0x5DC2	#CJK UNIFIED IDEOGRAPH
+0xF173	0x96DF	#CJK UNIFIED IDEOGRAPH
+0xF174	0x96D8	#CJK UNIFIED IDEOGRAPH
+0xF175	0x96DD	#CJK UNIFIED IDEOGRAPH
+0xF176	0x9723	#CJK UNIFIED IDEOGRAPH
+0xF177	0x9722	#CJK UNIFIED IDEOGRAPH
+0xF178	0x9725	#CJK UNIFIED IDEOGRAPH
+0xF179	0x97AC	#CJK UNIFIED IDEOGRAPH
+0xF17A	0x97AE	#CJK UNIFIED IDEOGRAPH
+0xF17B	0x97A8	#CJK UNIFIED IDEOGRAPH
+0xF17C	0x97AB	#CJK UNIFIED IDEOGRAPH
+0xF17D	0x97A4	#CJK UNIFIED IDEOGRAPH
+0xF17E	0x97AA	#CJK UNIFIED IDEOGRAPH
+0xF1A1	0x97A2	#CJK UNIFIED IDEOGRAPH
+0xF1A2	0x97A5	#CJK UNIFIED IDEOGRAPH
+0xF1A3	0x97D7	#CJK UNIFIED IDEOGRAPH
+0xF1A4	0x97D9	#CJK UNIFIED IDEOGRAPH
+0xF1A5	0x97D6	#CJK UNIFIED IDEOGRAPH
+0xF1A6	0x97D8	#CJK UNIFIED IDEOGRAPH
+0xF1A7	0x97FA	#CJK UNIFIED IDEOGRAPH
+0xF1A8	0x9850	#CJK UNIFIED IDEOGRAPH
+0xF1A9	0x9851	#CJK UNIFIED IDEOGRAPH
+0xF1AA	0x9852	#CJK UNIFIED IDEOGRAPH
+0xF1AB	0x98B8	#CJK UNIFIED IDEOGRAPH
+0xF1AC	0x9941	#CJK UNIFIED IDEOGRAPH
+0xF1AD	0x993C	#CJK UNIFIED IDEOGRAPH
+0xF1AE	0x993A	#CJK UNIFIED IDEOGRAPH
+0xF1AF	0x9A0F	#CJK UNIFIED IDEOGRAPH
+0xF1B0	0x9A0B	#CJK UNIFIED IDEOGRAPH
+0xF1B1	0x9A09	#CJK UNIFIED IDEOGRAPH
+0xF1B2	0x9A0D	#CJK UNIFIED IDEOGRAPH
+0xF1B3	0x9A04	#CJK UNIFIED IDEOGRAPH
+0xF1B4	0x9A11	#CJK UNIFIED IDEOGRAPH
+0xF1B5	0x9A0A	#CJK UNIFIED IDEOGRAPH
+0xF1B6	0x9A05	#CJK UNIFIED IDEOGRAPH
+0xF1B7	0x9A07	#CJK UNIFIED IDEOGRAPH
+0xF1B8	0x9A06	#CJK UNIFIED IDEOGRAPH
+0xF1B9	0x9AC0	#CJK UNIFIED IDEOGRAPH
+0xF1BA	0x9ADC	#CJK UNIFIED IDEOGRAPH
+0xF1BB	0x9B08	#CJK UNIFIED IDEOGRAPH
+0xF1BC	0x9B04	#CJK UNIFIED IDEOGRAPH
+0xF1BD	0x9B05	#CJK UNIFIED IDEOGRAPH
+0xF1BE	0x9B29	#CJK UNIFIED IDEOGRAPH
+0xF1BF	0x9B35	#CJK UNIFIED IDEOGRAPH
+0xF1C0	0x9B4A	#CJK UNIFIED IDEOGRAPH
+0xF1C1	0x9B4C	#CJK UNIFIED IDEOGRAPH
+0xF1C2	0x9B4B	#CJK UNIFIED IDEOGRAPH
+0xF1C3	0x9BC7	#CJK UNIFIED IDEOGRAPH
+0xF1C4	0x9BC6	#CJK UNIFIED IDEOGRAPH
+0xF1C5	0x9BC3	#CJK UNIFIED IDEOGRAPH
+0xF1C6	0x9BBF	#CJK UNIFIED IDEOGRAPH
+0xF1C7	0x9BC1	#CJK UNIFIED IDEOGRAPH
+0xF1C8	0x9BB5	#CJK UNIFIED IDEOGRAPH
+0xF1C9	0x9BB8	#CJK UNIFIED IDEOGRAPH
+0xF1CA	0x9BD3	#CJK UNIFIED IDEOGRAPH
+0xF1CB	0x9BB6	#CJK UNIFIED IDEOGRAPH
+0xF1CC	0x9BC4	#CJK UNIFIED IDEOGRAPH
+0xF1CD	0x9BB9	#CJK UNIFIED IDEOGRAPH
+0xF1CE	0x9BBD	#CJK UNIFIED IDEOGRAPH
+0xF1CF	0x9D5C	#CJK UNIFIED IDEOGRAPH
+0xF1D0	0x9D53	#CJK UNIFIED IDEOGRAPH
+0xF1D1	0x9D4F	#CJK UNIFIED IDEOGRAPH
+0xF1D2	0x9D4A	#CJK UNIFIED IDEOGRAPH
+0xF1D3	0x9D5B	#CJK UNIFIED IDEOGRAPH
+0xF1D4	0x9D4B	#CJK UNIFIED IDEOGRAPH
+0xF1D5	0x9D59	#CJK UNIFIED IDEOGRAPH
+0xF1D6	0x9D56	#CJK UNIFIED IDEOGRAPH
+0xF1D7	0x9D4C	#CJK UNIFIED IDEOGRAPH
+0xF1D8	0x9D57	#CJK UNIFIED IDEOGRAPH
+0xF1D9	0x9D52	#CJK UNIFIED IDEOGRAPH
+0xF1DA	0x9D54	#CJK UNIFIED IDEOGRAPH
+0xF1DB	0x9D5F	#CJK UNIFIED IDEOGRAPH
+0xF1DC	0x9D58	#CJK UNIFIED IDEOGRAPH
+0xF1DD	0x9D5A	#CJK UNIFIED IDEOGRAPH
+0xF1DE	0x9E8E	#CJK UNIFIED IDEOGRAPH
+0xF1DF	0x9E8C	#CJK UNIFIED IDEOGRAPH
+0xF1E0	0x9EDF	#CJK UNIFIED IDEOGRAPH
+0xF1E1	0x9F01	#CJK UNIFIED IDEOGRAPH
+0xF1E2	0x9F00	#CJK UNIFIED IDEOGRAPH
+0xF1E3	0x9F16	#CJK UNIFIED IDEOGRAPH
+0xF1E4	0x9F25	#CJK UNIFIED IDEOGRAPH
+0xF1E5	0x9F2B	#CJK UNIFIED IDEOGRAPH
+0xF1E6	0x9F2A	#CJK UNIFIED IDEOGRAPH
+0xF1E7	0x9F29	#CJK UNIFIED IDEOGRAPH
+0xF1E8	0x9F28	#CJK UNIFIED IDEOGRAPH
+0xF1E9	0x9F4C	#CJK UNIFIED IDEOGRAPH
+0xF1EA	0x9F55	#CJK UNIFIED IDEOGRAPH
+0xF1EB	0x5134	#CJK UNIFIED IDEOGRAPH
+0xF1EC	0x5135	#CJK UNIFIED IDEOGRAPH
+0xF1ED	0x5296	#CJK UNIFIED IDEOGRAPH
+0xF1EE	0x52F7	#CJK UNIFIED IDEOGRAPH
+0xF1EF	0x53B4	#CJK UNIFIED IDEOGRAPH
+0xF1F0	0x56AB	#CJK UNIFIED IDEOGRAPH
+0xF1F1	0x56AD	#CJK UNIFIED IDEOGRAPH
+0xF1F2	0x56A6	#CJK UNIFIED IDEOGRAPH
+0xF1F3	0x56A7	#CJK UNIFIED IDEOGRAPH
+0xF1F4	0x56AA	#CJK UNIFIED IDEOGRAPH
+0xF1F5	0x56AC	#CJK UNIFIED IDEOGRAPH
+0xF1F6	0x58DA	#CJK UNIFIED IDEOGRAPH
+0xF1F7	0x58DD	#CJK UNIFIED IDEOGRAPH
+0xF1F8	0x58DB	#CJK UNIFIED IDEOGRAPH
+0xF1F9	0x5912	#CJK UNIFIED IDEOGRAPH
+0xF1FA	0x5B3D	#CJK UNIFIED IDEOGRAPH
+0xF1FB	0x5B3E	#CJK UNIFIED IDEOGRAPH
+0xF1FC	0x5B3F	#CJK UNIFIED IDEOGRAPH
+0xF1FD	0x5DC3	#CJK UNIFIED IDEOGRAPH
+0xF1FE	0x5E70	#CJK UNIFIED IDEOGRAPH
+0xF240	0x5FBF	#CJK UNIFIED IDEOGRAPH
+0xF241	0x61FB	#CJK UNIFIED IDEOGRAPH
+0xF242	0x6507	#CJK UNIFIED IDEOGRAPH
+0xF243	0x6510	#CJK UNIFIED IDEOGRAPH
+0xF244	0x650D	#CJK UNIFIED IDEOGRAPH
+0xF245	0x6509	#CJK UNIFIED IDEOGRAPH
+0xF246	0x650C	#CJK UNIFIED IDEOGRAPH
+0xF247	0x650E	#CJK UNIFIED IDEOGRAPH
+0xF248	0x6584	#CJK UNIFIED IDEOGRAPH
+0xF249	0x65DE	#CJK UNIFIED IDEOGRAPH
+0xF24A	0x65DD	#CJK UNIFIED IDEOGRAPH
+0xF24B	0x66DE	#CJK UNIFIED IDEOGRAPH
+0xF24C	0x6AE7	#CJK UNIFIED IDEOGRAPH
+0xF24D	0x6AE0	#CJK UNIFIED IDEOGRAPH
+0xF24E	0x6ACC	#CJK UNIFIED IDEOGRAPH
+0xF24F	0x6AD1	#CJK UNIFIED IDEOGRAPH
+0xF250	0x6AD9	#CJK UNIFIED IDEOGRAPH
+0xF251	0x6ACB	#CJK UNIFIED IDEOGRAPH
+0xF252	0x6ADF	#CJK UNIFIED IDEOGRAPH
+0xF253	0x6ADC	#CJK UNIFIED IDEOGRAPH
+0xF254	0x6AD0	#CJK UNIFIED IDEOGRAPH
+0xF255	0x6AEB	#CJK UNIFIED IDEOGRAPH
+0xF256	0x6ACF	#CJK UNIFIED IDEOGRAPH
+0xF257	0x6ACD	#CJK UNIFIED IDEOGRAPH
+0xF258	0x6ADE	#CJK UNIFIED IDEOGRAPH
+0xF259	0x6B60	#CJK UNIFIED IDEOGRAPH
+0xF25A	0x6BB0	#CJK UNIFIED IDEOGRAPH
+0xF25B	0x6C0C	#CJK UNIFIED IDEOGRAPH
+0xF25C	0x7019	#CJK UNIFIED IDEOGRAPH
+0xF25D	0x7027	#CJK UNIFIED IDEOGRAPH
+0xF25E	0x7020	#CJK UNIFIED IDEOGRAPH
+0xF25F	0x7016	#CJK UNIFIED IDEOGRAPH
+0xF260	0x702B	#CJK UNIFIED IDEOGRAPH
+0xF261	0x7021	#CJK UNIFIED IDEOGRAPH
+0xF262	0x7022	#CJK UNIFIED IDEOGRAPH
+0xF263	0x7023	#CJK UNIFIED IDEOGRAPH
+0xF264	0x7029	#CJK UNIFIED IDEOGRAPH
+0xF265	0x7017	#CJK UNIFIED IDEOGRAPH
+0xF266	0x7024	#CJK UNIFIED IDEOGRAPH
+0xF267	0x701C	#CJK UNIFIED IDEOGRAPH
+0xF268	0x702A	#CJK UNIFIED IDEOGRAPH
+0xF269	0x720C	#CJK UNIFIED IDEOGRAPH
+0xF26A	0x720A	#CJK UNIFIED IDEOGRAPH
+0xF26B	0x7207	#CJK UNIFIED IDEOGRAPH
+0xF26C	0x7202	#CJK UNIFIED IDEOGRAPH
+0xF26D	0x7205	#CJK UNIFIED IDEOGRAPH
+0xF26E	0x72A5	#CJK UNIFIED IDEOGRAPH
+0xF26F	0x72A6	#CJK UNIFIED IDEOGRAPH
+0xF270	0x72A4	#CJK UNIFIED IDEOGRAPH
+0xF271	0x72A3	#CJK UNIFIED IDEOGRAPH
+0xF272	0x72A1	#CJK UNIFIED IDEOGRAPH
+0xF273	0x74CB	#CJK UNIFIED IDEOGRAPH
+0xF274	0x74C5	#CJK UNIFIED IDEOGRAPH
+0xF275	0x74B7	#CJK UNIFIED IDEOGRAPH
+0xF276	0x74C3	#CJK UNIFIED IDEOGRAPH
+0xF277	0x7516	#CJK UNIFIED IDEOGRAPH
+0xF278	0x7660	#CJK UNIFIED IDEOGRAPH
+0xF279	0x77C9	#CJK UNIFIED IDEOGRAPH
+0xF27A	0x77CA	#CJK UNIFIED IDEOGRAPH
+0xF27B	0x77C4	#CJK UNIFIED IDEOGRAPH
+0xF27C	0x77F1	#CJK UNIFIED IDEOGRAPH
+0xF27D	0x791D	#CJK UNIFIED IDEOGRAPH
+0xF27E	0x791B	#CJK UNIFIED IDEOGRAPH
+0xF2A1	0x7921	#CJK UNIFIED IDEOGRAPH
+0xF2A2	0x791C	#CJK UNIFIED IDEOGRAPH
+0xF2A3	0x7917	#CJK UNIFIED IDEOGRAPH
+0xF2A4	0x791E	#CJK UNIFIED IDEOGRAPH
+0xF2A5	0x79B0	#CJK UNIFIED IDEOGRAPH
+0xF2A6	0x7A67	#CJK UNIFIED IDEOGRAPH
+0xF2A7	0x7A68	#CJK UNIFIED IDEOGRAPH
+0xF2A8	0x7C33	#CJK UNIFIED IDEOGRAPH
+0xF2A9	0x7C3C	#CJK UNIFIED IDEOGRAPH
+0xF2AA	0x7C39	#CJK UNIFIED IDEOGRAPH
+0xF2AB	0x7C2C	#CJK UNIFIED IDEOGRAPH
+0xF2AC	0x7C3B	#CJK UNIFIED IDEOGRAPH
+0xF2AD	0x7CEC	#CJK UNIFIED IDEOGRAPH
+0xF2AE	0x7CEA	#CJK UNIFIED IDEOGRAPH
+0xF2AF	0x7E76	#CJK UNIFIED IDEOGRAPH
+0xF2B0	0x7E75	#CJK UNIFIED IDEOGRAPH
+0xF2B1	0x7E78	#CJK UNIFIED IDEOGRAPH
+0xF2B2	0x7E70	#CJK UNIFIED IDEOGRAPH
+0xF2B3	0x7E77	#CJK UNIFIED IDEOGRAPH
+0xF2B4	0x7E6F	#CJK UNIFIED IDEOGRAPH
+0xF2B5	0x7E7A	#CJK UNIFIED IDEOGRAPH
+0xF2B6	0x7E72	#CJK UNIFIED IDEOGRAPH
+0xF2B7	0x7E74	#CJK UNIFIED IDEOGRAPH
+0xF2B8	0x7E68	#CJK UNIFIED IDEOGRAPH
+0xF2B9	0x7F4B	#CJK UNIFIED IDEOGRAPH
+0xF2BA	0x7F4A	#CJK UNIFIED IDEOGRAPH
+0xF2BB	0x7F83	#CJK UNIFIED IDEOGRAPH
+0xF2BC	0x7F86	#CJK UNIFIED IDEOGRAPH
+0xF2BD	0x7FB7	#CJK UNIFIED IDEOGRAPH
+0xF2BE	0x7FFD	#CJK UNIFIED IDEOGRAPH
+0xF2BF	0x7FFE	#CJK UNIFIED IDEOGRAPH
+0xF2C0	0x8078	#CJK UNIFIED IDEOGRAPH
+0xF2C1	0x81D7	#CJK UNIFIED IDEOGRAPH
+0xF2C2	0x81D5	#CJK UNIFIED IDEOGRAPH
+0xF2C3	0x8264	#CJK UNIFIED IDEOGRAPH
+0xF2C4	0x8261	#CJK UNIFIED IDEOGRAPH
+0xF2C5	0x8263	#CJK UNIFIED IDEOGRAPH
+0xF2C6	0x85EB	#CJK UNIFIED IDEOGRAPH
+0xF2C7	0x85F1	#CJK UNIFIED IDEOGRAPH
+0xF2C8	0x85ED	#CJK UNIFIED IDEOGRAPH
+0xF2C9	0x85D9	#CJK UNIFIED IDEOGRAPH
+0xF2CA	0x85E1	#CJK UNIFIED IDEOGRAPH
+0xF2CB	0x85E8	#CJK UNIFIED IDEOGRAPH
+0xF2CC	0x85DA	#CJK UNIFIED IDEOGRAPH
+0xF2CD	0x85D7	#CJK UNIFIED IDEOGRAPH
+0xF2CE	0x85EC	#CJK UNIFIED IDEOGRAPH
+0xF2CF	0x85F2	#CJK UNIFIED IDEOGRAPH
+0xF2D0	0x85F8	#CJK UNIFIED IDEOGRAPH
+0xF2D1	0x85D8	#CJK UNIFIED IDEOGRAPH
+0xF2D2	0x85DF	#CJK UNIFIED IDEOGRAPH
+0xF2D3	0x85E3	#CJK UNIFIED IDEOGRAPH
+0xF2D4	0x85DC	#CJK UNIFIED IDEOGRAPH
+0xF2D5	0x85D1	#CJK UNIFIED IDEOGRAPH
+0xF2D6	0x85F0	#CJK UNIFIED IDEOGRAPH
+0xF2D7	0x85E6	#CJK UNIFIED IDEOGRAPH
+0xF2D8	0x85EF	#CJK UNIFIED IDEOGRAPH
+0xF2D9	0x85DE	#CJK UNIFIED IDEOGRAPH
+0xF2DA	0x85E2	#CJK UNIFIED IDEOGRAPH
+0xF2DB	0x8800	#CJK UNIFIED IDEOGRAPH
+0xF2DC	0x87FA	#CJK UNIFIED IDEOGRAPH
+0xF2DD	0x8803	#CJK UNIFIED IDEOGRAPH
+0xF2DE	0x87F6	#CJK UNIFIED IDEOGRAPH
+0xF2DF	0x87F7	#CJK UNIFIED IDEOGRAPH
+0xF2E0	0x8809	#CJK UNIFIED IDEOGRAPH
+0xF2E1	0x880C	#CJK UNIFIED IDEOGRAPH
+0xF2E2	0x880B	#CJK UNIFIED IDEOGRAPH
+0xF2E3	0x8806	#CJK UNIFIED IDEOGRAPH
+0xF2E4	0x87FC	#CJK UNIFIED IDEOGRAPH
+0xF2E5	0x8808	#CJK UNIFIED IDEOGRAPH
+0xF2E6	0x87FF	#CJK UNIFIED IDEOGRAPH
+0xF2E7	0x880A	#CJK UNIFIED IDEOGRAPH
+0xF2E8	0x8802	#CJK UNIFIED IDEOGRAPH
+0xF2E9	0x8962	#CJK UNIFIED IDEOGRAPH
+0xF2EA	0x895A	#CJK UNIFIED IDEOGRAPH
+0xF2EB	0x895B	#CJK UNIFIED IDEOGRAPH
+0xF2EC	0x8957	#CJK UNIFIED IDEOGRAPH
+0xF2ED	0x8961	#CJK UNIFIED IDEOGRAPH
+0xF2EE	0x895C	#CJK UNIFIED IDEOGRAPH
+0xF2EF	0x8958	#CJK UNIFIED IDEOGRAPH
+0xF2F0	0x895D	#CJK UNIFIED IDEOGRAPH
+0xF2F1	0x8959	#CJK UNIFIED IDEOGRAPH
+0xF2F2	0x8988	#CJK UNIFIED IDEOGRAPH
+0xF2F3	0x89B7	#CJK UNIFIED IDEOGRAPH
+0xF2F4	0x89B6	#CJK UNIFIED IDEOGRAPH
+0xF2F5	0x89F6	#CJK UNIFIED IDEOGRAPH
+0xF2F6	0x8B50	#CJK UNIFIED IDEOGRAPH
+0xF2F7	0x8B48	#CJK UNIFIED IDEOGRAPH
+0xF2F8	0x8B4A	#CJK UNIFIED IDEOGRAPH
+0xF2F9	0x8B40	#CJK UNIFIED IDEOGRAPH
+0xF2FA	0x8B53	#CJK UNIFIED IDEOGRAPH
+0xF2FB	0x8B56	#CJK UNIFIED IDEOGRAPH
+0xF2FC	0x8B54	#CJK UNIFIED IDEOGRAPH
+0xF2FD	0x8B4B	#CJK UNIFIED IDEOGRAPH
+0xF2FE	0x8B55	#CJK UNIFIED IDEOGRAPH
+0xF340	0x8B51	#CJK UNIFIED IDEOGRAPH
+0xF341	0x8B42	#CJK UNIFIED IDEOGRAPH
+0xF342	0x8B52	#CJK UNIFIED IDEOGRAPH
+0xF343	0x8B57	#CJK UNIFIED IDEOGRAPH
+0xF344	0x8C43	#CJK UNIFIED IDEOGRAPH
+0xF345	0x8C77	#CJK UNIFIED IDEOGRAPH
+0xF346	0x8C76	#CJK UNIFIED IDEOGRAPH
+0xF347	0x8C9A	#CJK UNIFIED IDEOGRAPH
+0xF348	0x8D06	#CJK UNIFIED IDEOGRAPH
+0xF349	0x8D07	#CJK UNIFIED IDEOGRAPH
+0xF34A	0x8D09	#CJK UNIFIED IDEOGRAPH
+0xF34B	0x8DAC	#CJK UNIFIED IDEOGRAPH
+0xF34C	0x8DAA	#CJK UNIFIED IDEOGRAPH
+0xF34D	0x8DAD	#CJK UNIFIED IDEOGRAPH
+0xF34E	0x8DAB	#CJK UNIFIED IDEOGRAPH
+0xF34F	0x8E6D	#CJK UNIFIED IDEOGRAPH
+0xF350	0x8E78	#CJK UNIFIED IDEOGRAPH
+0xF351	0x8E73	#CJK UNIFIED IDEOGRAPH
+0xF352	0x8E6A	#CJK UNIFIED IDEOGRAPH
+0xF353	0x8E6F	#CJK UNIFIED IDEOGRAPH
+0xF354	0x8E7B	#CJK UNIFIED IDEOGRAPH
+0xF355	0x8EC2	#CJK UNIFIED IDEOGRAPH
+0xF356	0x8F52	#CJK UNIFIED IDEOGRAPH
+0xF357	0x8F51	#CJK UNIFIED IDEOGRAPH
+0xF358	0x8F4F	#CJK UNIFIED IDEOGRAPH
+0xF359	0x8F50	#CJK UNIFIED IDEOGRAPH
+0xF35A	0x8F53	#CJK UNIFIED IDEOGRAPH
+0xF35B	0x8FB4	#CJK UNIFIED IDEOGRAPH
+0xF35C	0x9140	#CJK UNIFIED IDEOGRAPH
+0xF35D	0x913F	#CJK UNIFIED IDEOGRAPH
+0xF35E	0x91B0	#CJK UNIFIED IDEOGRAPH
+0xF35F	0x91AD	#CJK UNIFIED IDEOGRAPH
+0xF360	0x93DE	#CJK UNIFIED IDEOGRAPH
+0xF361	0x93C7	#CJK UNIFIED IDEOGRAPH
+0xF362	0x93CF	#CJK UNIFIED IDEOGRAPH
+0xF363	0x93C2	#CJK UNIFIED IDEOGRAPH
+0xF364	0x93DA	#CJK UNIFIED IDEOGRAPH
+0xF365	0x93D0	#CJK UNIFIED IDEOGRAPH
+0xF366	0x93F9	#CJK UNIFIED IDEOGRAPH
+0xF367	0x93EC	#CJK UNIFIED IDEOGRAPH
+0xF368	0x93CC	#CJK UNIFIED IDEOGRAPH
+0xF369	0x93D9	#CJK UNIFIED IDEOGRAPH
+0xF36A	0x93A9	#CJK UNIFIED IDEOGRAPH
+0xF36B	0x93E6	#CJK UNIFIED IDEOGRAPH
+0xF36C	0x93CA	#CJK UNIFIED IDEOGRAPH
+0xF36D	0x93D4	#CJK UNIFIED IDEOGRAPH
+0xF36E	0x93EE	#CJK UNIFIED IDEOGRAPH
+0xF36F	0x93E3	#CJK UNIFIED IDEOGRAPH
+0xF370	0x93D5	#CJK UNIFIED IDEOGRAPH
+0xF371	0x93C4	#CJK UNIFIED IDEOGRAPH
+0xF372	0x93CE	#CJK UNIFIED IDEOGRAPH
+0xF373	0x93C0	#CJK UNIFIED IDEOGRAPH
+0xF374	0x93D2	#CJK UNIFIED IDEOGRAPH
+0xF375	0x93E7	#CJK UNIFIED IDEOGRAPH
+0xF376	0x957D	#CJK UNIFIED IDEOGRAPH
+0xF377	0x95DA	#CJK UNIFIED IDEOGRAPH
+0xF378	0x95DB	#CJK UNIFIED IDEOGRAPH
+0xF379	0x96E1	#CJK UNIFIED IDEOGRAPH
+0xF37A	0x9729	#CJK UNIFIED IDEOGRAPH
+0xF37B	0x972B	#CJK UNIFIED IDEOGRAPH
+0xF37C	0x972C	#CJK UNIFIED IDEOGRAPH
+0xF37D	0x9728	#CJK UNIFIED IDEOGRAPH
+0xF37E	0x9726	#CJK UNIFIED IDEOGRAPH
+0xF3A1	0x97B3	#CJK UNIFIED IDEOGRAPH
+0xF3A2	0x97B7	#CJK UNIFIED IDEOGRAPH
+0xF3A3	0x97B6	#CJK UNIFIED IDEOGRAPH
+0xF3A4	0x97DD	#CJK UNIFIED IDEOGRAPH
+0xF3A5	0x97DE	#CJK UNIFIED IDEOGRAPH
+0xF3A6	0x97DF	#CJK UNIFIED IDEOGRAPH
+0xF3A7	0x985C	#CJK UNIFIED IDEOGRAPH
+0xF3A8	0x9859	#CJK UNIFIED IDEOGRAPH
+0xF3A9	0x985D	#CJK UNIFIED IDEOGRAPH
+0xF3AA	0x9857	#CJK UNIFIED IDEOGRAPH
+0xF3AB	0x98BF	#CJK UNIFIED IDEOGRAPH
+0xF3AC	0x98BD	#CJK UNIFIED IDEOGRAPH
+0xF3AD	0x98BB	#CJK UNIFIED IDEOGRAPH
+0xF3AE	0x98BE	#CJK UNIFIED IDEOGRAPH
+0xF3AF	0x9948	#CJK UNIFIED IDEOGRAPH
+0xF3B0	0x9947	#CJK UNIFIED IDEOGRAPH
+0xF3B1	0x9943	#CJK UNIFIED IDEOGRAPH
+0xF3B2	0x99A6	#CJK UNIFIED IDEOGRAPH
+0xF3B3	0x99A7	#CJK UNIFIED IDEOGRAPH
+0xF3B4	0x9A1A	#CJK UNIFIED IDEOGRAPH
+0xF3B5	0x9A15	#CJK UNIFIED IDEOGRAPH
+0xF3B6	0x9A25	#CJK UNIFIED IDEOGRAPH
+0xF3B7	0x9A1D	#CJK UNIFIED IDEOGRAPH
+0xF3B8	0x9A24	#CJK UNIFIED IDEOGRAPH
+0xF3B9	0x9A1B	#CJK UNIFIED IDEOGRAPH
+0xF3BA	0x9A22	#CJK UNIFIED IDEOGRAPH
+0xF3BB	0x9A20	#CJK UNIFIED IDEOGRAPH
+0xF3BC	0x9A27	#CJK UNIFIED IDEOGRAPH
+0xF3BD	0x9A23	#CJK UNIFIED IDEOGRAPH
+0xF3BE	0x9A1E	#CJK UNIFIED IDEOGRAPH
+0xF3BF	0x9A1C	#CJK UNIFIED IDEOGRAPH
+0xF3C0	0x9A14	#CJK UNIFIED IDEOGRAPH
+0xF3C1	0x9AC2	#CJK UNIFIED IDEOGRAPH
+0xF3C2	0x9B0B	#CJK UNIFIED IDEOGRAPH
+0xF3C3	0x9B0A	#CJK UNIFIED IDEOGRAPH
+0xF3C4	0x9B0E	#CJK UNIFIED IDEOGRAPH
+0xF3C5	0x9B0C	#CJK UNIFIED IDEOGRAPH
+0xF3C6	0x9B37	#CJK UNIFIED IDEOGRAPH
+0xF3C7	0x9BEA	#CJK UNIFIED IDEOGRAPH
+0xF3C8	0x9BEB	#CJK UNIFIED IDEOGRAPH
+0xF3C9	0x9BE0	#CJK UNIFIED IDEOGRAPH
+0xF3CA	0x9BDE	#CJK UNIFIED IDEOGRAPH
+0xF3CB	0x9BE4	#CJK UNIFIED IDEOGRAPH
+0xF3CC	0x9BE6	#CJK UNIFIED IDEOGRAPH
+0xF3CD	0x9BE2	#CJK UNIFIED IDEOGRAPH
+0xF3CE	0x9BF0	#CJK UNIFIED IDEOGRAPH
+0xF3CF	0x9BD4	#CJK UNIFIED IDEOGRAPH
+0xF3D0	0x9BD7	#CJK UNIFIED IDEOGRAPH
+0xF3D1	0x9BEC	#CJK UNIFIED IDEOGRAPH
+0xF3D2	0x9BDC	#CJK UNIFIED IDEOGRAPH
+0xF3D3	0x9BD9	#CJK UNIFIED IDEOGRAPH
+0xF3D4	0x9BE5	#CJK UNIFIED IDEOGRAPH
+0xF3D5	0x9BD5	#CJK UNIFIED IDEOGRAPH
+0xF3D6	0x9BE1	#CJK UNIFIED IDEOGRAPH
+0xF3D7	0x9BDA	#CJK UNIFIED IDEOGRAPH
+0xF3D8	0x9D77	#CJK UNIFIED IDEOGRAPH
+0xF3D9	0x9D81	#CJK UNIFIED IDEOGRAPH
+0xF3DA	0x9D8A	#CJK UNIFIED IDEOGRAPH
+0xF3DB	0x9D84	#CJK UNIFIED IDEOGRAPH
+0xF3DC	0x9D88	#CJK UNIFIED IDEOGRAPH
+0xF3DD	0x9D71	#CJK UNIFIED IDEOGRAPH
+0xF3DE	0x9D80	#CJK UNIFIED IDEOGRAPH
+0xF3DF	0x9D78	#CJK UNIFIED IDEOGRAPH
+0xF3E0	0x9D86	#CJK UNIFIED IDEOGRAPH
+0xF3E1	0x9D8B	#CJK UNIFIED IDEOGRAPH
+0xF3E2	0x9D8C	#CJK UNIFIED IDEOGRAPH
+0xF3E3	0x9D7D	#CJK UNIFIED IDEOGRAPH
+0xF3E4	0x9D6B	#CJK UNIFIED IDEOGRAPH
+0xF3E5	0x9D74	#CJK UNIFIED IDEOGRAPH
+0xF3E6	0x9D75	#CJK UNIFIED IDEOGRAPH
+0xF3E7	0x9D70	#CJK UNIFIED IDEOGRAPH
+0xF3E8	0x9D69	#CJK UNIFIED IDEOGRAPH
+0xF3E9	0x9D85	#CJK UNIFIED IDEOGRAPH
+0xF3EA	0x9D73	#CJK UNIFIED IDEOGRAPH
+0xF3EB	0x9D7B	#CJK UNIFIED IDEOGRAPH
+0xF3EC	0x9D82	#CJK UNIFIED IDEOGRAPH
+0xF3ED	0x9D6F	#CJK UNIFIED IDEOGRAPH
+0xF3EE	0x9D79	#CJK UNIFIED IDEOGRAPH
+0xF3EF	0x9D7F	#CJK UNIFIED IDEOGRAPH
+0xF3F0	0x9D87	#CJK UNIFIED IDEOGRAPH
+0xF3F1	0x9D68	#CJK UNIFIED IDEOGRAPH
+0xF3F2	0x9E94	#CJK UNIFIED IDEOGRAPH
+0xF3F3	0x9E91	#CJK UNIFIED IDEOGRAPH
+0xF3F4	0x9EC0	#CJK UNIFIED IDEOGRAPH
+0xF3F5	0x9EFC	#CJK UNIFIED IDEOGRAPH
+0xF3F6	0x9F2D	#CJK UNIFIED IDEOGRAPH
+0xF3F7	0x9F40	#CJK UNIFIED IDEOGRAPH
+0xF3F8	0x9F41	#CJK UNIFIED IDEOGRAPH
+0xF3F9	0x9F4D	#CJK UNIFIED IDEOGRAPH
+0xF3FA	0x9F56	#CJK UNIFIED IDEOGRAPH
+0xF3FB	0x9F57	#CJK UNIFIED IDEOGRAPH
+0xF3FC	0x9F58	#CJK UNIFIED IDEOGRAPH
+0xF3FD	0x5337	#CJK UNIFIED IDEOGRAPH
+0xF3FE	0x56B2	#CJK UNIFIED IDEOGRAPH
+0xF440	0x56B5	#CJK UNIFIED IDEOGRAPH
+0xF441	0x56B3	#CJK UNIFIED IDEOGRAPH
+0xF442	0x58E3	#CJK UNIFIED IDEOGRAPH
+0xF443	0x5B45	#CJK UNIFIED IDEOGRAPH
+0xF444	0x5DC6	#CJK UNIFIED IDEOGRAPH
+0xF445	0x5DC7	#CJK UNIFIED IDEOGRAPH
+0xF446	0x5EEE	#CJK UNIFIED IDEOGRAPH
+0xF447	0x5EEF	#CJK UNIFIED IDEOGRAPH
+0xF448	0x5FC0	#CJK UNIFIED IDEOGRAPH
+0xF449	0x5FC1	#CJK UNIFIED IDEOGRAPH
+0xF44A	0x61F9	#CJK UNIFIED IDEOGRAPH
+0xF44B	0x6517	#CJK UNIFIED IDEOGRAPH
+0xF44C	0x6516	#CJK UNIFIED IDEOGRAPH
+0xF44D	0x6515	#CJK UNIFIED IDEOGRAPH
+0xF44E	0x6513	#CJK UNIFIED IDEOGRAPH
+0xF44F	0x65DF	#CJK UNIFIED IDEOGRAPH
+0xF450	0x66E8	#CJK UNIFIED IDEOGRAPH
+0xF451	0x66E3	#CJK UNIFIED IDEOGRAPH
+0xF452	0x66E4	#CJK UNIFIED IDEOGRAPH
+0xF453	0x6AF3	#CJK UNIFIED IDEOGRAPH
+0xF454	0x6AF0	#CJK UNIFIED IDEOGRAPH
+0xF455	0x6AEA	#CJK UNIFIED IDEOGRAPH
+0xF456	0x6AE8	#CJK UNIFIED IDEOGRAPH
+0xF457	0x6AF9	#CJK UNIFIED IDEOGRAPH
+0xF458	0x6AF1	#CJK UNIFIED IDEOGRAPH
+0xF459	0x6AEE	#CJK UNIFIED IDEOGRAPH
+0xF45A	0x6AEF	#CJK UNIFIED IDEOGRAPH
+0xF45B	0x703C	#CJK UNIFIED IDEOGRAPH
+0xF45C	0x7035	#CJK UNIFIED IDEOGRAPH
+0xF45D	0x702F	#CJK UNIFIED IDEOGRAPH
+0xF45E	0x7037	#CJK UNIFIED IDEOGRAPH
+0xF45F	0x7034	#CJK UNIFIED IDEOGRAPH
+0xF460	0x7031	#CJK UNIFIED IDEOGRAPH
+0xF461	0x7042	#CJK UNIFIED IDEOGRAPH
+0xF462	0x7038	#CJK UNIFIED IDEOGRAPH
+0xF463	0x703F	#CJK UNIFIED IDEOGRAPH
+0xF464	0x703A	#CJK UNIFIED IDEOGRAPH
+0xF465	0x7039	#CJK UNIFIED IDEOGRAPH
+0xF466	0x7040	#CJK UNIFIED IDEOGRAPH
+0xF467	0x703B	#CJK UNIFIED IDEOGRAPH
+0xF468	0x7033	#CJK UNIFIED IDEOGRAPH
+0xF469	0x7041	#CJK UNIFIED IDEOGRAPH
+0xF46A	0x7213	#CJK UNIFIED IDEOGRAPH
+0xF46B	0x7214	#CJK UNIFIED IDEOGRAPH
+0xF46C	0x72A8	#CJK UNIFIED IDEOGRAPH
+0xF46D	0x737D	#CJK UNIFIED IDEOGRAPH
+0xF46E	0x737C	#CJK UNIFIED IDEOGRAPH
+0xF46F	0x74BA	#CJK UNIFIED IDEOGRAPH
+0xF470	0x76AB	#CJK UNIFIED IDEOGRAPH
+0xF471	0x76AA	#CJK UNIFIED IDEOGRAPH
+0xF472	0x76BE	#CJK UNIFIED IDEOGRAPH
+0xF473	0x76ED	#CJK UNIFIED IDEOGRAPH
+0xF474	0x77CC	#CJK UNIFIED IDEOGRAPH
+0xF475	0x77CE	#CJK UNIFIED IDEOGRAPH
+0xF476	0x77CF	#CJK UNIFIED IDEOGRAPH
+0xF477	0x77CD	#CJK UNIFIED IDEOGRAPH
+0xF478	0x77F2	#CJK UNIFIED IDEOGRAPH
+0xF479	0x7925	#CJK UNIFIED IDEOGRAPH
+0xF47A	0x7923	#CJK UNIFIED IDEOGRAPH
+0xF47B	0x7927	#CJK UNIFIED IDEOGRAPH
+0xF47C	0x7928	#CJK UNIFIED IDEOGRAPH
+0xF47D	0x7924	#CJK UNIFIED IDEOGRAPH
+0xF47E	0x7929	#CJK UNIFIED IDEOGRAPH
+0xF4A1	0x79B2	#CJK UNIFIED IDEOGRAPH
+0xF4A2	0x7A6E	#CJK UNIFIED IDEOGRAPH
+0xF4A3	0x7A6C	#CJK UNIFIED IDEOGRAPH
+0xF4A4	0x7A6D	#CJK UNIFIED IDEOGRAPH
+0xF4A5	0x7AF7	#CJK UNIFIED IDEOGRAPH
+0xF4A6	0x7C49	#CJK UNIFIED IDEOGRAPH
+0xF4A7	0x7C48	#CJK UNIFIED IDEOGRAPH
+0xF4A8	0x7C4A	#CJK UNIFIED IDEOGRAPH
+0xF4A9	0x7C47	#CJK UNIFIED IDEOGRAPH
+0xF4AA	0x7C45	#CJK UNIFIED IDEOGRAPH
+0xF4AB	0x7CEE	#CJK UNIFIED IDEOGRAPH
+0xF4AC	0x7E7B	#CJK UNIFIED IDEOGRAPH
+0xF4AD	0x7E7E	#CJK UNIFIED IDEOGRAPH
+0xF4AE	0x7E81	#CJK UNIFIED IDEOGRAPH
+0xF4AF	0x7E80	#CJK UNIFIED IDEOGRAPH
+0xF4B0	0x7FBA	#CJK UNIFIED IDEOGRAPH
+0xF4B1	0x7FFF	#CJK UNIFIED IDEOGRAPH
+0xF4B2	0x8079	#CJK UNIFIED IDEOGRAPH
+0xF4B3	0x81DB	#CJK UNIFIED IDEOGRAPH
+0xF4B4	0x81D9	#CJK UNIFIED IDEOGRAPH
+0xF4B5	0x820B	#CJK UNIFIED IDEOGRAPH
+0xF4B6	0x8268	#CJK UNIFIED IDEOGRAPH
+0xF4B7	0x8269	#CJK UNIFIED IDEOGRAPH
+0xF4B8	0x8622	#CJK UNIFIED IDEOGRAPH
+0xF4B9	0x85FF	#CJK UNIFIED IDEOGRAPH
+0xF4BA	0x8601	#CJK UNIFIED IDEOGRAPH
+0xF4BB	0x85FE	#CJK UNIFIED IDEOGRAPH
+0xF4BC	0x861B	#CJK UNIFIED IDEOGRAPH
+0xF4BD	0x8600	#CJK UNIFIED IDEOGRAPH
+0xF4BE	0x85F6	#CJK UNIFIED IDEOGRAPH
+0xF4BF	0x8604	#CJK UNIFIED IDEOGRAPH
+0xF4C0	0x8609	#CJK UNIFIED IDEOGRAPH
+0xF4C1	0x8605	#CJK UNIFIED IDEOGRAPH
+0xF4C2	0x860C	#CJK UNIFIED IDEOGRAPH
+0xF4C3	0x85FD	#CJK UNIFIED IDEOGRAPH
+0xF4C4	0x8819	#CJK UNIFIED IDEOGRAPH
+0xF4C5	0x8810	#CJK UNIFIED IDEOGRAPH
+0xF4C6	0x8811	#CJK UNIFIED IDEOGRAPH
+0xF4C7	0x8817	#CJK UNIFIED IDEOGRAPH
+0xF4C8	0x8813	#CJK UNIFIED IDEOGRAPH
+0xF4C9	0x8816	#CJK UNIFIED IDEOGRAPH
+0xF4CA	0x8963	#CJK UNIFIED IDEOGRAPH
+0xF4CB	0x8966	#CJK UNIFIED IDEOGRAPH
+0xF4CC	0x89B9	#CJK UNIFIED IDEOGRAPH
+0xF4CD	0x89F7	#CJK UNIFIED IDEOGRAPH
+0xF4CE	0x8B60	#CJK UNIFIED IDEOGRAPH
+0xF4CF	0x8B6A	#CJK UNIFIED IDEOGRAPH
+0xF4D0	0x8B5D	#CJK UNIFIED IDEOGRAPH
+0xF4D1	0x8B68	#CJK UNIFIED IDEOGRAPH
+0xF4D2	0x8B63	#CJK UNIFIED IDEOGRAPH
+0xF4D3	0x8B65	#CJK UNIFIED IDEOGRAPH
+0xF4D4	0x8B67	#CJK UNIFIED IDEOGRAPH
+0xF4D5	0x8B6D	#CJK UNIFIED IDEOGRAPH
+0xF4D6	0x8DAE	#CJK UNIFIED IDEOGRAPH
+0xF4D7	0x8E86	#CJK UNIFIED IDEOGRAPH
+0xF4D8	0x8E88	#CJK UNIFIED IDEOGRAPH
+0xF4D9	0x8E84	#CJK UNIFIED IDEOGRAPH
+0xF4DA	0x8F59	#CJK UNIFIED IDEOGRAPH
+0xF4DB	0x8F56	#CJK UNIFIED IDEOGRAPH
+0xF4DC	0x8F57	#CJK UNIFIED IDEOGRAPH
+0xF4DD	0x8F55	#CJK UNIFIED IDEOGRAPH
+0xF4DE	0x8F58	#CJK UNIFIED IDEOGRAPH
+0xF4DF	0x8F5A	#CJK UNIFIED IDEOGRAPH
+0xF4E0	0x908D	#CJK UNIFIED IDEOGRAPH
+0xF4E1	0x9143	#CJK UNIFIED IDEOGRAPH
+0xF4E2	0x9141	#CJK UNIFIED IDEOGRAPH
+0xF4E3	0x91B7	#CJK UNIFIED IDEOGRAPH
+0xF4E4	0x91B5	#CJK UNIFIED IDEOGRAPH
+0xF4E5	0x91B2	#CJK UNIFIED IDEOGRAPH
+0xF4E6	0x91B3	#CJK UNIFIED IDEOGRAPH
+0xF4E7	0x940B	#CJK UNIFIED IDEOGRAPH
+0xF4E8	0x9413	#CJK UNIFIED IDEOGRAPH
+0xF4E9	0x93FB	#CJK UNIFIED IDEOGRAPH
+0xF4EA	0x9420	#CJK UNIFIED IDEOGRAPH
+0xF4EB	0x940F	#CJK UNIFIED IDEOGRAPH
+0xF4EC	0x9414	#CJK UNIFIED IDEOGRAPH
+0xF4ED	0x93FE	#CJK UNIFIED IDEOGRAPH
+0xF4EE	0x9415	#CJK UNIFIED IDEOGRAPH
+0xF4EF	0x9410	#CJK UNIFIED IDEOGRAPH
+0xF4F0	0x9428	#CJK UNIFIED IDEOGRAPH
+0xF4F1	0x9419	#CJK UNIFIED IDEOGRAPH
+0xF4F2	0x940D	#CJK UNIFIED IDEOGRAPH
+0xF4F3	0x93F5	#CJK UNIFIED IDEOGRAPH
+0xF4F4	0x9400	#CJK UNIFIED IDEOGRAPH
+0xF4F5	0x93F7	#CJK UNIFIED IDEOGRAPH
+0xF4F6	0x9407	#CJK UNIFIED IDEOGRAPH
+0xF4F7	0x940E	#CJK UNIFIED IDEOGRAPH
+0xF4F8	0x9416	#CJK UNIFIED IDEOGRAPH
+0xF4F9	0x9412	#CJK UNIFIED IDEOGRAPH
+0xF4FA	0x93FA	#CJK UNIFIED IDEOGRAPH
+0xF4FB	0x9409	#CJK UNIFIED IDEOGRAPH
+0xF4FC	0x93F8	#CJK UNIFIED IDEOGRAPH
+0xF4FD	0x940A	#CJK UNIFIED IDEOGRAPH
+0xF4FE	0x93FF	#CJK UNIFIED IDEOGRAPH
+0xF540	0x93FC	#CJK UNIFIED IDEOGRAPH
+0xF541	0x940C	#CJK UNIFIED IDEOGRAPH
+0xF542	0x93F6	#CJK UNIFIED IDEOGRAPH
+0xF543	0x9411	#CJK UNIFIED IDEOGRAPH
+0xF544	0x9406	#CJK UNIFIED IDEOGRAPH
+0xF545	0x95DE	#CJK UNIFIED IDEOGRAPH
+0xF546	0x95E0	#CJK UNIFIED IDEOGRAPH
+0xF547	0x95DF	#CJK UNIFIED IDEOGRAPH
+0xF548	0x972E	#CJK UNIFIED IDEOGRAPH
+0xF549	0x972F	#CJK UNIFIED IDEOGRAPH
+0xF54A	0x97B9	#CJK UNIFIED IDEOGRAPH
+0xF54B	0x97BB	#CJK UNIFIED IDEOGRAPH
+0xF54C	0x97FD	#CJK UNIFIED IDEOGRAPH
+0xF54D	0x97FE	#CJK UNIFIED IDEOGRAPH
+0xF54E	0x9860	#CJK UNIFIED IDEOGRAPH
+0xF54F	0x9862	#CJK UNIFIED IDEOGRAPH
+0xF550	0x9863	#CJK UNIFIED IDEOGRAPH
+0xF551	0x985F	#CJK UNIFIED IDEOGRAPH
+0xF552	0x98C1	#CJK UNIFIED IDEOGRAPH
+0xF553	0x98C2	#CJK UNIFIED IDEOGRAPH
+0xF554	0x9950	#CJK UNIFIED IDEOGRAPH
+0xF555	0x994E	#CJK UNIFIED IDEOGRAPH
+0xF556	0x9959	#CJK UNIFIED IDEOGRAPH
+0xF557	0x994C	#CJK UNIFIED IDEOGRAPH
+0xF558	0x994B	#CJK UNIFIED IDEOGRAPH
+0xF559	0x9953	#CJK UNIFIED IDEOGRAPH
+0xF55A	0x9A32	#CJK UNIFIED IDEOGRAPH
+0xF55B	0x9A34	#CJK UNIFIED IDEOGRAPH
+0xF55C	0x9A31	#CJK UNIFIED IDEOGRAPH
+0xF55D	0x9A2C	#CJK UNIFIED IDEOGRAPH
+0xF55E	0x9A2A	#CJK UNIFIED IDEOGRAPH
+0xF55F	0x9A36	#CJK UNIFIED IDEOGRAPH
+0xF560	0x9A29	#CJK UNIFIED IDEOGRAPH
+0xF561	0x9A2E	#CJK UNIFIED IDEOGRAPH
+0xF562	0x9A38	#CJK UNIFIED IDEOGRAPH
+0xF563	0x9A2D	#CJK UNIFIED IDEOGRAPH
+0xF564	0x9AC7	#CJK UNIFIED IDEOGRAPH
+0xF565	0x9ACA	#CJK UNIFIED IDEOGRAPH
+0xF566	0x9AC6	#CJK UNIFIED IDEOGRAPH
+0xF567	0x9B10	#CJK UNIFIED IDEOGRAPH
+0xF568	0x9B12	#CJK UNIFIED IDEOGRAPH
+0xF569	0x9B11	#CJK UNIFIED IDEOGRAPH
+0xF56A	0x9C0B	#CJK UNIFIED IDEOGRAPH
+0xF56B	0x9C08	#CJK UNIFIED IDEOGRAPH
+0xF56C	0x9BF7	#CJK UNIFIED IDEOGRAPH
+0xF56D	0x9C05	#CJK UNIFIED IDEOGRAPH
+0xF56E	0x9C12	#CJK UNIFIED IDEOGRAPH
+0xF56F	0x9BF8	#CJK UNIFIED IDEOGRAPH
+0xF570	0x9C40	#CJK UNIFIED IDEOGRAPH
+0xF571	0x9C07	#CJK UNIFIED IDEOGRAPH
+0xF572	0x9C0E	#CJK UNIFIED IDEOGRAPH
+0xF573	0x9C06	#CJK UNIFIED IDEOGRAPH
+0xF574	0x9C17	#CJK UNIFIED IDEOGRAPH
+0xF575	0x9C14	#CJK UNIFIED IDEOGRAPH
+0xF576	0x9C09	#CJK UNIFIED IDEOGRAPH
+0xF577	0x9D9F	#CJK UNIFIED IDEOGRAPH
+0xF578	0x9D99	#CJK UNIFIED IDEOGRAPH
+0xF579	0x9DA4	#CJK UNIFIED IDEOGRAPH
+0xF57A	0x9D9D	#CJK UNIFIED IDEOGRAPH
+0xF57B	0x9D92	#CJK UNIFIED IDEOGRAPH
+0xF57C	0x9D98	#CJK UNIFIED IDEOGRAPH
+0xF57D	0x9D90	#CJK UNIFIED IDEOGRAPH
+0xF57E	0x9D9B	#CJK UNIFIED IDEOGRAPH
+0xF5A1	0x9DA0	#CJK UNIFIED IDEOGRAPH
+0xF5A2	0x9D94	#CJK UNIFIED IDEOGRAPH
+0xF5A3	0x9D9C	#CJK UNIFIED IDEOGRAPH
+0xF5A4	0x9DAA	#CJK UNIFIED IDEOGRAPH
+0xF5A5	0x9D97	#CJK UNIFIED IDEOGRAPH
+0xF5A6	0x9DA1	#CJK UNIFIED IDEOGRAPH
+0xF5A7	0x9D9A	#CJK UNIFIED IDEOGRAPH
+0xF5A8	0x9DA2	#CJK UNIFIED IDEOGRAPH
+0xF5A9	0x9DA8	#CJK UNIFIED IDEOGRAPH
+0xF5AA	0x9D9E	#CJK UNIFIED IDEOGRAPH
+0xF5AB	0x9DA3	#CJK UNIFIED IDEOGRAPH
+0xF5AC	0x9DBF	#CJK UNIFIED IDEOGRAPH
+0xF5AD	0x9DA9	#CJK UNIFIED IDEOGRAPH
+0xF5AE	0x9D96	#CJK UNIFIED IDEOGRAPH
+0xF5AF	0x9DA6	#CJK UNIFIED IDEOGRAPH
+0xF5B0	0x9DA7	#CJK UNIFIED IDEOGRAPH
+0xF5B1	0x9E99	#CJK UNIFIED IDEOGRAPH
+0xF5B2	0x9E9B	#CJK UNIFIED IDEOGRAPH
+0xF5B3	0x9E9A	#CJK UNIFIED IDEOGRAPH
+0xF5B4	0x9EE5	#CJK UNIFIED IDEOGRAPH
+0xF5B5	0x9EE4	#CJK UNIFIED IDEOGRAPH
+0xF5B6	0x9EE7	#CJK UNIFIED IDEOGRAPH
+0xF5B7	0x9EE6	#CJK UNIFIED IDEOGRAPH
+0xF5B8	0x9F30	#CJK UNIFIED IDEOGRAPH
+0xF5B9	0x9F2E	#CJK UNIFIED IDEOGRAPH
+0xF5BA	0x9F5B	#CJK UNIFIED IDEOGRAPH
+0xF5BB	0x9F60	#CJK UNIFIED IDEOGRAPH
+0xF5BC	0x9F5E	#CJK UNIFIED IDEOGRAPH
+0xF5BD	0x9F5D	#CJK UNIFIED IDEOGRAPH
+0xF5BE	0x9F59	#CJK UNIFIED IDEOGRAPH
+0xF5BF	0x9F91	#CJK UNIFIED IDEOGRAPH
+0xF5C0	0x513A	#CJK UNIFIED IDEOGRAPH
+0xF5C1	0x5139	#CJK UNIFIED IDEOGRAPH
+0xF5C2	0x5298	#CJK UNIFIED IDEOGRAPH
+0xF5C3	0x5297	#CJK UNIFIED IDEOGRAPH
+0xF5C4	0x56C3	#CJK UNIFIED IDEOGRAPH
+0xF5C5	0x56BD	#CJK UNIFIED IDEOGRAPH
+0xF5C6	0x56BE	#CJK UNIFIED IDEOGRAPH
+0xF5C7	0x5B48	#CJK UNIFIED IDEOGRAPH
+0xF5C8	0x5B47	#CJK UNIFIED IDEOGRAPH
+0xF5C9	0x5DCB	#CJK UNIFIED IDEOGRAPH
+0xF5CA	0x5DCF	#CJK UNIFIED IDEOGRAPH
+0xF5CB	0x5EF1	#CJK UNIFIED IDEOGRAPH
+0xF5CC	0x61FD	#CJK UNIFIED IDEOGRAPH
+0xF5CD	0x651B	#CJK UNIFIED IDEOGRAPH
+0xF5CE	0x6B02	#CJK UNIFIED IDEOGRAPH
+0xF5CF	0x6AFC	#CJK UNIFIED IDEOGRAPH
+0xF5D0	0x6B03	#CJK UNIFIED IDEOGRAPH
+0xF5D1	0x6AF8	#CJK UNIFIED IDEOGRAPH
+0xF5D2	0x6B00	#CJK UNIFIED IDEOGRAPH
+0xF5D3	0x7043	#CJK UNIFIED IDEOGRAPH
+0xF5D4	0x7044	#CJK UNIFIED IDEOGRAPH
+0xF5D5	0x704A	#CJK UNIFIED IDEOGRAPH
+0xF5D6	0x7048	#CJK UNIFIED IDEOGRAPH
+0xF5D7	0x7049	#CJK UNIFIED IDEOGRAPH
+0xF5D8	0x7045	#CJK UNIFIED IDEOGRAPH
+0xF5D9	0x7046	#CJK UNIFIED IDEOGRAPH
+0xF5DA	0x721D	#CJK UNIFIED IDEOGRAPH
+0xF5DB	0x721A	#CJK UNIFIED IDEOGRAPH
+0xF5DC	0x7219	#CJK UNIFIED IDEOGRAPH
+0xF5DD	0x737E	#CJK UNIFIED IDEOGRAPH
+0xF5DE	0x7517	#CJK UNIFIED IDEOGRAPH
+0xF5DF	0x766A	#CJK UNIFIED IDEOGRAPH
+0xF5E0	0x77D0	#CJK UNIFIED IDEOGRAPH
+0xF5E1	0x792D	#CJK UNIFIED IDEOGRAPH
+0xF5E2	0x7931	#CJK UNIFIED IDEOGRAPH
+0xF5E3	0x792F	#CJK UNIFIED IDEOGRAPH
+0xF5E4	0x7C54	#CJK UNIFIED IDEOGRAPH
+0xF5E5	0x7C53	#CJK UNIFIED IDEOGRAPH
+0xF5E6	0x7CF2	#CJK UNIFIED IDEOGRAPH
+0xF5E7	0x7E8A	#CJK UNIFIED IDEOGRAPH
+0xF5E8	0x7E87	#CJK UNIFIED IDEOGRAPH
+0xF5E9	0x7E88	#CJK UNIFIED IDEOGRAPH
+0xF5EA	0x7E8B	#CJK UNIFIED IDEOGRAPH
+0xF5EB	0x7E86	#CJK UNIFIED IDEOGRAPH
+0xF5EC	0x7E8D	#CJK UNIFIED IDEOGRAPH
+0xF5ED	0x7F4D	#CJK UNIFIED IDEOGRAPH
+0xF5EE	0x7FBB	#CJK UNIFIED IDEOGRAPH
+0xF5EF	0x8030	#CJK UNIFIED IDEOGRAPH
+0xF5F0	0x81DD	#CJK UNIFIED IDEOGRAPH
+0xF5F1	0x8618	#CJK UNIFIED IDEOGRAPH
+0xF5F2	0x862A	#CJK UNIFIED IDEOGRAPH
+0xF5F3	0x8626	#CJK UNIFIED IDEOGRAPH
+0xF5F4	0x861F	#CJK UNIFIED IDEOGRAPH
+0xF5F5	0x8623	#CJK UNIFIED IDEOGRAPH
+0xF5F6	0x861C	#CJK UNIFIED IDEOGRAPH
+0xF5F7	0x8619	#CJK UNIFIED IDEOGRAPH
+0xF5F8	0x8627	#CJK UNIFIED IDEOGRAPH
+0xF5F9	0x862E	#CJK UNIFIED IDEOGRAPH
+0xF5FA	0x8621	#CJK UNIFIED IDEOGRAPH
+0xF5FB	0x8620	#CJK UNIFIED IDEOGRAPH
+0xF5FC	0x8629	#CJK UNIFIED IDEOGRAPH
+0xF5FD	0x861E	#CJK UNIFIED IDEOGRAPH
+0xF5FE	0x8625	#CJK UNIFIED IDEOGRAPH
+0xF640	0x8829	#CJK UNIFIED IDEOGRAPH
+0xF641	0x881D	#CJK UNIFIED IDEOGRAPH
+0xF642	0x881B	#CJK UNIFIED IDEOGRAPH
+0xF643	0x8820	#CJK UNIFIED IDEOGRAPH
+0xF644	0x8824	#CJK UNIFIED IDEOGRAPH
+0xF645	0x881C	#CJK UNIFIED IDEOGRAPH
+0xF646	0x882B	#CJK UNIFIED IDEOGRAPH
+0xF647	0x884A	#CJK UNIFIED IDEOGRAPH
+0xF648	0x896D	#CJK UNIFIED IDEOGRAPH
+0xF649	0x8969	#CJK UNIFIED IDEOGRAPH
+0xF64A	0x896E	#CJK UNIFIED IDEOGRAPH
+0xF64B	0x896B	#CJK UNIFIED IDEOGRAPH
+0xF64C	0x89FA	#CJK UNIFIED IDEOGRAPH
+0xF64D	0x8B79	#CJK UNIFIED IDEOGRAPH
+0xF64E	0x8B78	#CJK UNIFIED IDEOGRAPH
+0xF64F	0x8B45	#CJK UNIFIED IDEOGRAPH
+0xF650	0x8B7A	#CJK UNIFIED IDEOGRAPH
+0xF651	0x8B7B	#CJK UNIFIED IDEOGRAPH
+0xF652	0x8D10	#CJK UNIFIED IDEOGRAPH
+0xF653	0x8D14	#CJK UNIFIED IDEOGRAPH
+0xF654	0x8DAF	#CJK UNIFIED IDEOGRAPH
+0xF655	0x8E8E	#CJK UNIFIED IDEOGRAPH
+0xF656	0x8E8C	#CJK UNIFIED IDEOGRAPH
+0xF657	0x8F5E	#CJK UNIFIED IDEOGRAPH
+0xF658	0x8F5B	#CJK UNIFIED IDEOGRAPH
+0xF659	0x8F5D	#CJK UNIFIED IDEOGRAPH
+0xF65A	0x9146	#CJK UNIFIED IDEOGRAPH
+0xF65B	0x9144	#CJK UNIFIED IDEOGRAPH
+0xF65C	0x9145	#CJK UNIFIED IDEOGRAPH
+0xF65D	0x91B9	#CJK UNIFIED IDEOGRAPH
+0xF65E	0x943F	#CJK UNIFIED IDEOGRAPH
+0xF65F	0x943B	#CJK UNIFIED IDEOGRAPH
+0xF660	0x9436	#CJK UNIFIED IDEOGRAPH
+0xF661	0x9429	#CJK UNIFIED IDEOGRAPH
+0xF662	0x943D	#CJK UNIFIED IDEOGRAPH
+0xF663	0x943C	#CJK UNIFIED IDEOGRAPH
+0xF664	0x9430	#CJK UNIFIED IDEOGRAPH
+0xF665	0x9439	#CJK UNIFIED IDEOGRAPH
+0xF666	0x942A	#CJK UNIFIED IDEOGRAPH
+0xF667	0x9437	#CJK UNIFIED IDEOGRAPH
+0xF668	0x942C	#CJK UNIFIED IDEOGRAPH
+0xF669	0x9440	#CJK UNIFIED IDEOGRAPH
+0xF66A	0x9431	#CJK UNIFIED IDEOGRAPH
+0xF66B	0x95E5	#CJK UNIFIED IDEOGRAPH
+0xF66C	0x95E4	#CJK UNIFIED IDEOGRAPH
+0xF66D	0x95E3	#CJK UNIFIED IDEOGRAPH
+0xF66E	0x9735	#CJK UNIFIED IDEOGRAPH
+0xF66F	0x973A	#CJK UNIFIED IDEOGRAPH
+0xF670	0x97BF	#CJK UNIFIED IDEOGRAPH
+0xF671	0x97E1	#CJK UNIFIED IDEOGRAPH
+0xF672	0x9864	#CJK UNIFIED IDEOGRAPH
+0xF673	0x98C9	#CJK UNIFIED IDEOGRAPH
+0xF674	0x98C6	#CJK UNIFIED IDEOGRAPH
+0xF675	0x98C0	#CJK UNIFIED IDEOGRAPH
+0xF676	0x9958	#CJK UNIFIED IDEOGRAPH
+0xF677	0x9956	#CJK UNIFIED IDEOGRAPH
+0xF678	0x9A39	#CJK UNIFIED IDEOGRAPH
+0xF679	0x9A3D	#CJK UNIFIED IDEOGRAPH
+0xF67A	0x9A46	#CJK UNIFIED IDEOGRAPH
+0xF67B	0x9A44	#CJK UNIFIED IDEOGRAPH
+0xF67C	0x9A42	#CJK UNIFIED IDEOGRAPH
+0xF67D	0x9A41	#CJK UNIFIED IDEOGRAPH
+0xF67E	0x9A3A	#CJK UNIFIED IDEOGRAPH
+0xF6A1	0x9A3F	#CJK UNIFIED IDEOGRAPH
+0xF6A2	0x9ACD	#CJK UNIFIED IDEOGRAPH
+0xF6A3	0x9B15	#CJK UNIFIED IDEOGRAPH
+0xF6A4	0x9B17	#CJK UNIFIED IDEOGRAPH
+0xF6A5	0x9B18	#CJK UNIFIED IDEOGRAPH
+0xF6A6	0x9B16	#CJK UNIFIED IDEOGRAPH
+0xF6A7	0x9B3A	#CJK UNIFIED IDEOGRAPH
+0xF6A8	0x9B52	#CJK UNIFIED IDEOGRAPH
+0xF6A9	0x9C2B	#CJK UNIFIED IDEOGRAPH
+0xF6AA	0x9C1D	#CJK UNIFIED IDEOGRAPH
+0xF6AB	0x9C1C	#CJK UNIFIED IDEOGRAPH
+0xF6AC	0x9C2C	#CJK UNIFIED IDEOGRAPH
+0xF6AD	0x9C23	#CJK UNIFIED IDEOGRAPH
+0xF6AE	0x9C28	#CJK UNIFIED IDEOGRAPH
+0xF6AF	0x9C29	#CJK UNIFIED IDEOGRAPH
+0xF6B0	0x9C24	#CJK UNIFIED IDEOGRAPH
+0xF6B1	0x9C21	#CJK UNIFIED IDEOGRAPH
+0xF6B2	0x9DB7	#CJK UNIFIED IDEOGRAPH
+0xF6B3	0x9DB6	#CJK UNIFIED IDEOGRAPH
+0xF6B4	0x9DBC	#CJK UNIFIED IDEOGRAPH
+0xF6B5	0x9DC1	#CJK UNIFIED IDEOGRAPH
+0xF6B6	0x9DC7	#CJK UNIFIED IDEOGRAPH
+0xF6B7	0x9DCA	#CJK UNIFIED IDEOGRAPH
+0xF6B8	0x9DCF	#CJK UNIFIED IDEOGRAPH
+0xF6B9	0x9DBE	#CJK UNIFIED IDEOGRAPH
+0xF6BA	0x9DC5	#CJK UNIFIED IDEOGRAPH
+0xF6BB	0x9DC3	#CJK UNIFIED IDEOGRAPH
+0xF6BC	0x9DBB	#CJK UNIFIED IDEOGRAPH
+0xF6BD	0x9DB5	#CJK UNIFIED IDEOGRAPH
+0xF6BE	0x9DCE	#CJK UNIFIED IDEOGRAPH
+0xF6BF	0x9DB9	#CJK UNIFIED IDEOGRAPH
+0xF6C0	0x9DBA	#CJK UNIFIED IDEOGRAPH
+0xF6C1	0x9DAC	#CJK UNIFIED IDEOGRAPH
+0xF6C2	0x9DC8	#CJK UNIFIED IDEOGRAPH
+0xF6C3	0x9DB1	#CJK UNIFIED IDEOGRAPH
+0xF6C4	0x9DAD	#CJK UNIFIED IDEOGRAPH
+0xF6C5	0x9DCC	#CJK UNIFIED IDEOGRAPH
+0xF6C6	0x9DB3	#CJK UNIFIED IDEOGRAPH
+0xF6C7	0x9DCD	#CJK UNIFIED IDEOGRAPH
+0xF6C8	0x9DB2	#CJK UNIFIED IDEOGRAPH
+0xF6C9	0x9E7A	#CJK UNIFIED IDEOGRAPH
+0xF6CA	0x9E9C	#CJK UNIFIED IDEOGRAPH
+0xF6CB	0x9EEB	#CJK UNIFIED IDEOGRAPH
+0xF6CC	0x9EEE	#CJK UNIFIED IDEOGRAPH
+0xF6CD	0x9EED	#CJK UNIFIED IDEOGRAPH
+0xF6CE	0x9F1B	#CJK UNIFIED IDEOGRAPH
+0xF6CF	0x9F18	#CJK UNIFIED IDEOGRAPH
+0xF6D0	0x9F1A	#CJK UNIFIED IDEOGRAPH
+0xF6D1	0x9F31	#CJK UNIFIED IDEOGRAPH
+0xF6D2	0x9F4E	#CJK UNIFIED IDEOGRAPH
+0xF6D3	0x9F65	#CJK UNIFIED IDEOGRAPH
+0xF6D4	0x9F64	#CJK UNIFIED IDEOGRAPH
+0xF6D5	0x9F92	#CJK UNIFIED IDEOGRAPH
+0xF6D6	0x4EB9	#CJK UNIFIED IDEOGRAPH
+0xF6D7	0x56C6	#CJK UNIFIED IDEOGRAPH
+0xF6D8	0x56C5	#CJK UNIFIED IDEOGRAPH
+0xF6D9	0x56CB	#CJK UNIFIED IDEOGRAPH
+0xF6DA	0x5971	#CJK UNIFIED IDEOGRAPH
+0xF6DB	0x5B4B	#CJK UNIFIED IDEOGRAPH
+0xF6DC	0x5B4C	#CJK UNIFIED IDEOGRAPH
+0xF6DD	0x5DD5	#CJK UNIFIED IDEOGRAPH
+0xF6DE	0x5DD1	#CJK UNIFIED IDEOGRAPH
+0xF6DF	0x5EF2	#CJK UNIFIED IDEOGRAPH
+0xF6E0	0x6521	#CJK UNIFIED IDEOGRAPH
+0xF6E1	0x6520	#CJK UNIFIED IDEOGRAPH
+0xF6E2	0x6526	#CJK UNIFIED IDEOGRAPH
+0xF6E3	0x6522	#CJK UNIFIED IDEOGRAPH
+0xF6E4	0x6B0B	#CJK UNIFIED IDEOGRAPH
+0xF6E5	0x6B08	#CJK UNIFIED IDEOGRAPH
+0xF6E6	0x6B09	#CJK UNIFIED IDEOGRAPH
+0xF6E7	0x6C0D	#CJK UNIFIED IDEOGRAPH
+0xF6E8	0x7055	#CJK UNIFIED IDEOGRAPH
+0xF6E9	0x7056	#CJK UNIFIED IDEOGRAPH
+0xF6EA	0x7057	#CJK UNIFIED IDEOGRAPH
+0xF6EB	0x7052	#CJK UNIFIED IDEOGRAPH
+0xF6EC	0x721E	#CJK UNIFIED IDEOGRAPH
+0xF6ED	0x721F	#CJK UNIFIED IDEOGRAPH
+0xF6EE	0x72A9	#CJK UNIFIED IDEOGRAPH
+0xF6EF	0x737F	#CJK UNIFIED IDEOGRAPH
+0xF6F0	0x74D8	#CJK UNIFIED IDEOGRAPH
+0xF6F1	0x74D5	#CJK UNIFIED IDEOGRAPH
+0xF6F2	0x74D9	#CJK UNIFIED IDEOGRAPH
+0xF6F3	0x74D7	#CJK UNIFIED IDEOGRAPH
+0xF6F4	0x766D	#CJK UNIFIED IDEOGRAPH
+0xF6F5	0x76AD	#CJK UNIFIED IDEOGRAPH
+0xF6F6	0x7935	#CJK UNIFIED IDEOGRAPH
+0xF6F7	0x79B4	#CJK UNIFIED IDEOGRAPH
+0xF6F8	0x7A70	#CJK UNIFIED IDEOGRAPH
+0xF6F9	0x7A71	#CJK UNIFIED IDEOGRAPH
+0xF6FA	0x7C57	#CJK UNIFIED IDEOGRAPH
+0xF6FB	0x7C5C	#CJK UNIFIED IDEOGRAPH
+0xF6FC	0x7C59	#CJK UNIFIED IDEOGRAPH
+0xF6FD	0x7C5B	#CJK UNIFIED IDEOGRAPH
+0xF6FE	0x7C5A	#CJK UNIFIED IDEOGRAPH
+0xF740	0x7CF4	#CJK UNIFIED IDEOGRAPH
+0xF741	0x7CF1	#CJK UNIFIED IDEOGRAPH
+0xF742	0x7E91	#CJK UNIFIED IDEOGRAPH
+0xF743	0x7F4F	#CJK UNIFIED IDEOGRAPH
+0xF744	0x7F87	#CJK UNIFIED IDEOGRAPH
+0xF745	0x81DE	#CJK UNIFIED IDEOGRAPH
+0xF746	0x826B	#CJK UNIFIED IDEOGRAPH
+0xF747	0x8634	#CJK UNIFIED IDEOGRAPH
+0xF748	0x8635	#CJK UNIFIED IDEOGRAPH
+0xF749	0x8633	#CJK UNIFIED IDEOGRAPH
+0xF74A	0x862C	#CJK UNIFIED IDEOGRAPH
+0xF74B	0x8632	#CJK UNIFIED IDEOGRAPH
+0xF74C	0x8636	#CJK UNIFIED IDEOGRAPH
+0xF74D	0x882C	#CJK UNIFIED IDEOGRAPH
+0xF74E	0x8828	#CJK UNIFIED IDEOGRAPH
+0xF74F	0x8826	#CJK UNIFIED IDEOGRAPH
+0xF750	0x882A	#CJK UNIFIED IDEOGRAPH
+0xF751	0x8825	#CJK UNIFIED IDEOGRAPH
+0xF752	0x8971	#CJK UNIFIED IDEOGRAPH
+0xF753	0x89BF	#CJK UNIFIED IDEOGRAPH
+0xF754	0x89BE	#CJK UNIFIED IDEOGRAPH
+0xF755	0x89FB	#CJK UNIFIED IDEOGRAPH
+0xF756	0x8B7E	#CJK UNIFIED IDEOGRAPH
+0xF757	0x8B84	#CJK UNIFIED IDEOGRAPH
+0xF758	0x8B82	#CJK UNIFIED IDEOGRAPH
+0xF759	0x8B86	#CJK UNIFIED IDEOGRAPH
+0xF75A	0x8B85	#CJK UNIFIED IDEOGRAPH
+0xF75B	0x8B7F	#CJK UNIFIED IDEOGRAPH
+0xF75C	0x8D15	#CJK UNIFIED IDEOGRAPH
+0xF75D	0x8E95	#CJK UNIFIED IDEOGRAPH
+0xF75E	0x8E94	#CJK UNIFIED IDEOGRAPH
+0xF75F	0x8E9A	#CJK UNIFIED IDEOGRAPH
+0xF760	0x8E92	#CJK UNIFIED IDEOGRAPH
+0xF761	0x8E90	#CJK UNIFIED IDEOGRAPH
+0xF762	0x8E96	#CJK UNIFIED IDEOGRAPH
+0xF763	0x8E97	#CJK UNIFIED IDEOGRAPH
+0xF764	0x8F60	#CJK UNIFIED IDEOGRAPH
+0xF765	0x8F62	#CJK UNIFIED IDEOGRAPH
+0xF766	0x9147	#CJK UNIFIED IDEOGRAPH
+0xF767	0x944C	#CJK UNIFIED IDEOGRAPH
+0xF768	0x9450	#CJK UNIFIED IDEOGRAPH
+0xF769	0x944A	#CJK UNIFIED IDEOGRAPH
+0xF76A	0x944B	#CJK UNIFIED IDEOGRAPH
+0xF76B	0x944F	#CJK UNIFIED IDEOGRAPH
+0xF76C	0x9447	#CJK UNIFIED IDEOGRAPH
+0xF76D	0x9445	#CJK UNIFIED IDEOGRAPH
+0xF76E	0x9448	#CJK UNIFIED IDEOGRAPH
+0xF76F	0x9449	#CJK UNIFIED IDEOGRAPH
+0xF770	0x9446	#CJK UNIFIED IDEOGRAPH
+0xF771	0x973F	#CJK UNIFIED IDEOGRAPH
+0xF772	0x97E3	#CJK UNIFIED IDEOGRAPH
+0xF773	0x986A	#CJK UNIFIED IDEOGRAPH
+0xF774	0x9869	#CJK UNIFIED IDEOGRAPH
+0xF775	0x98CB	#CJK UNIFIED IDEOGRAPH
+0xF776	0x9954	#CJK UNIFIED IDEOGRAPH
+0xF777	0x995B	#CJK UNIFIED IDEOGRAPH
+0xF778	0x9A4E	#CJK UNIFIED IDEOGRAPH
+0xF779	0x9A53	#CJK UNIFIED IDEOGRAPH
+0xF77A	0x9A54	#CJK UNIFIED IDEOGRAPH
+0xF77B	0x9A4C	#CJK UNIFIED IDEOGRAPH
+0xF77C	0x9A4F	#CJK UNIFIED IDEOGRAPH
+0xF77D	0x9A48	#CJK UNIFIED IDEOGRAPH
+0xF77E	0x9A4A	#CJK UNIFIED IDEOGRAPH
+0xF7A1	0x9A49	#CJK UNIFIED IDEOGRAPH
+0xF7A2	0x9A52	#CJK UNIFIED IDEOGRAPH
+0xF7A3	0x9A50	#CJK UNIFIED IDEOGRAPH
+0xF7A4	0x9AD0	#CJK UNIFIED IDEOGRAPH
+0xF7A5	0x9B19	#CJK UNIFIED IDEOGRAPH
+0xF7A6	0x9B2B	#CJK UNIFIED IDEOGRAPH
+0xF7A7	0x9B3B	#CJK UNIFIED IDEOGRAPH
+0xF7A8	0x9B56	#CJK UNIFIED IDEOGRAPH
+0xF7A9	0x9B55	#CJK UNIFIED IDEOGRAPH
+0xF7AA	0x9C46	#CJK UNIFIED IDEOGRAPH
+0xF7AB	0x9C48	#CJK UNIFIED IDEOGRAPH
+0xF7AC	0x9C3F	#CJK UNIFIED IDEOGRAPH
+0xF7AD	0x9C44	#CJK UNIFIED IDEOGRAPH
+0xF7AE	0x9C39	#CJK UNIFIED IDEOGRAPH
+0xF7AF	0x9C33	#CJK UNIFIED IDEOGRAPH
+0xF7B0	0x9C41	#CJK UNIFIED IDEOGRAPH
+0xF7B1	0x9C3C	#CJK UNIFIED IDEOGRAPH
+0xF7B2	0x9C37	#CJK UNIFIED IDEOGRAPH
+0xF7B3	0x9C34	#CJK UNIFIED IDEOGRAPH
+0xF7B4	0x9C32	#CJK UNIFIED IDEOGRAPH
+0xF7B5	0x9C3D	#CJK UNIFIED IDEOGRAPH
+0xF7B6	0x9C36	#CJK UNIFIED IDEOGRAPH
+0xF7B7	0x9DDB	#CJK UNIFIED IDEOGRAPH
+0xF7B8	0x9DD2	#CJK UNIFIED IDEOGRAPH
+0xF7B9	0x9DDE	#CJK UNIFIED IDEOGRAPH
+0xF7BA	0x9DDA	#CJK UNIFIED IDEOGRAPH
+0xF7BB	0x9DCB	#CJK UNIFIED IDEOGRAPH
+0xF7BC	0x9DD0	#CJK UNIFIED IDEOGRAPH
+0xF7BD	0x9DDC	#CJK UNIFIED IDEOGRAPH
+0xF7BE	0x9DD1	#CJK UNIFIED IDEOGRAPH
+0xF7BF	0x9DDF	#CJK UNIFIED IDEOGRAPH
+0xF7C0	0x9DE9	#CJK UNIFIED IDEOGRAPH
+0xF7C1	0x9DD9	#CJK UNIFIED IDEOGRAPH
+0xF7C2	0x9DD8	#CJK UNIFIED IDEOGRAPH
+0xF7C3	0x9DD6	#CJK UNIFIED IDEOGRAPH
+0xF7C4	0x9DF5	#CJK UNIFIED IDEOGRAPH
+0xF7C5	0x9DD5	#CJK UNIFIED IDEOGRAPH
+0xF7C6	0x9DDD	#CJK UNIFIED IDEOGRAPH
+0xF7C7	0x9EB6	#CJK UNIFIED IDEOGRAPH
+0xF7C8	0x9EF0	#CJK UNIFIED IDEOGRAPH
+0xF7C9	0x9F35	#CJK UNIFIED IDEOGRAPH
+0xF7CA	0x9F33	#CJK UNIFIED IDEOGRAPH
+0xF7CB	0x9F32	#CJK UNIFIED IDEOGRAPH
+0xF7CC	0x9F42	#CJK UNIFIED IDEOGRAPH
+0xF7CD	0x9F6B	#CJK UNIFIED IDEOGRAPH
+0xF7CE	0x9F95	#CJK UNIFIED IDEOGRAPH
+0xF7CF	0x9FA2	#CJK UNIFIED IDEOGRAPH
+0xF7D0	0x513D	#CJK UNIFIED IDEOGRAPH
+0xF7D1	0x5299	#CJK UNIFIED IDEOGRAPH
+0xF7D2	0x58E8	#CJK UNIFIED IDEOGRAPH
+0xF7D3	0x58E7	#CJK UNIFIED IDEOGRAPH
+0xF7D4	0x5972	#CJK UNIFIED IDEOGRAPH
+0xF7D5	0x5B4D	#CJK UNIFIED IDEOGRAPH
+0xF7D6	0x5DD8	#CJK UNIFIED IDEOGRAPH
+0xF7D7	0x882F	#CJK UNIFIED IDEOGRAPH
+0xF7D8	0x5F4F	#CJK UNIFIED IDEOGRAPH
+0xF7D9	0x6201	#CJK UNIFIED IDEOGRAPH
+0xF7DA	0x6203	#CJK UNIFIED IDEOGRAPH
+0xF7DB	0x6204	#CJK UNIFIED IDEOGRAPH
+0xF7DC	0x6529	#CJK UNIFIED IDEOGRAPH
+0xF7DD	0x6525	#CJK UNIFIED IDEOGRAPH
+0xF7DE	0x6596	#CJK UNIFIED IDEOGRAPH
+0xF7DF	0x66EB	#CJK UNIFIED IDEOGRAPH
+0xF7E0	0x6B11	#CJK UNIFIED IDEOGRAPH
+0xF7E1	0x6B12	#CJK UNIFIED IDEOGRAPH
+0xF7E2	0x6B0F	#CJK UNIFIED IDEOGRAPH
+0xF7E3	0x6BCA	#CJK UNIFIED IDEOGRAPH
+0xF7E4	0x705B	#CJK UNIFIED IDEOGRAPH
+0xF7E5	0x705A	#CJK UNIFIED IDEOGRAPH
+0xF7E6	0x7222	#CJK UNIFIED IDEOGRAPH
+0xF7E7	0x7382	#CJK UNIFIED IDEOGRAPH
+0xF7E8	0x7381	#CJK UNIFIED IDEOGRAPH
+0xF7E9	0x7383	#CJK UNIFIED IDEOGRAPH
+0xF7EA	0x7670	#CJK UNIFIED IDEOGRAPH
+0xF7EB	0x77D4	#CJK UNIFIED IDEOGRAPH
+0xF7EC	0x7C67	#CJK UNIFIED IDEOGRAPH
+0xF7ED	0x7C66	#CJK UNIFIED IDEOGRAPH
+0xF7EE	0x7E95	#CJK UNIFIED IDEOGRAPH
+0xF7EF	0x826C	#CJK UNIFIED IDEOGRAPH
+0xF7F0	0x863A	#CJK UNIFIED IDEOGRAPH
+0xF7F1	0x8640	#CJK UNIFIED IDEOGRAPH
+0xF7F2	0x8639	#CJK UNIFIED IDEOGRAPH
+0xF7F3	0x863C	#CJK UNIFIED IDEOGRAPH
+0xF7F4	0x8631	#CJK UNIFIED IDEOGRAPH
+0xF7F5	0x863B	#CJK UNIFIED IDEOGRAPH
+0xF7F6	0x863E	#CJK UNIFIED IDEOGRAPH
+0xF7F7	0x8830	#CJK UNIFIED IDEOGRAPH
+0xF7F8	0x8832	#CJK UNIFIED IDEOGRAPH
+0xF7F9	0x882E	#CJK UNIFIED IDEOGRAPH
+0xF7FA	0x8833	#CJK UNIFIED IDEOGRAPH
+0xF7FB	0x8976	#CJK UNIFIED IDEOGRAPH
+0xF7FC	0x8974	#CJK UNIFIED IDEOGRAPH
+0xF7FD	0x8973	#CJK UNIFIED IDEOGRAPH
+0xF7FE	0x89FE	#CJK UNIFIED IDEOGRAPH
+0xF840	0x8B8C	#CJK UNIFIED IDEOGRAPH
+0xF841	0x8B8E	#CJK UNIFIED IDEOGRAPH
+0xF842	0x8B8B	#CJK UNIFIED IDEOGRAPH
+0xF843	0x8B88	#CJK UNIFIED IDEOGRAPH
+0xF844	0x8C45	#CJK UNIFIED IDEOGRAPH
+0xF845	0x8D19	#CJK UNIFIED IDEOGRAPH
+0xF846	0x8E98	#CJK UNIFIED IDEOGRAPH
+0xF847	0x8F64	#CJK UNIFIED IDEOGRAPH
+0xF848	0x8F63	#CJK UNIFIED IDEOGRAPH
+0xF849	0x91BC	#CJK UNIFIED IDEOGRAPH
+0xF84A	0x9462	#CJK UNIFIED IDEOGRAPH
+0xF84B	0x9455	#CJK UNIFIED IDEOGRAPH
+0xF84C	0x945D	#CJK UNIFIED IDEOGRAPH
+0xF84D	0x9457	#CJK UNIFIED IDEOGRAPH
+0xF84E	0x945E	#CJK UNIFIED IDEOGRAPH
+0xF84F	0x97C4	#CJK UNIFIED IDEOGRAPH
+0xF850	0x97C5	#CJK UNIFIED IDEOGRAPH
+0xF851	0x9800	#CJK UNIFIED IDEOGRAPH
+0xF852	0x9A56	#CJK UNIFIED IDEOGRAPH
+0xF853	0x9A59	#CJK UNIFIED IDEOGRAPH
+0xF854	0x9B1E	#CJK UNIFIED IDEOGRAPH
+0xF855	0x9B1F	#CJK UNIFIED IDEOGRAPH
+0xF856	0x9B20	#CJK UNIFIED IDEOGRAPH
+0xF857	0x9C52	#CJK UNIFIED IDEOGRAPH
+0xF858	0x9C58	#CJK UNIFIED IDEOGRAPH
+0xF859	0x9C50	#CJK UNIFIED IDEOGRAPH
+0xF85A	0x9C4A	#CJK UNIFIED IDEOGRAPH
+0xF85B	0x9C4D	#CJK UNIFIED IDEOGRAPH
+0xF85C	0x9C4B	#CJK UNIFIED IDEOGRAPH
+0xF85D	0x9C55	#CJK UNIFIED IDEOGRAPH
+0xF85E	0x9C59	#CJK UNIFIED IDEOGRAPH
+0xF85F	0x9C4C	#CJK UNIFIED IDEOGRAPH
+0xF860	0x9C4E	#CJK UNIFIED IDEOGRAPH
+0xF861	0x9DFB	#CJK UNIFIED IDEOGRAPH
+0xF862	0x9DF7	#CJK UNIFIED IDEOGRAPH
+0xF863	0x9DEF	#CJK UNIFIED IDEOGRAPH
+0xF864	0x9DE3	#CJK UNIFIED IDEOGRAPH
+0xF865	0x9DEB	#CJK UNIFIED IDEOGRAPH
+0xF866	0x9DF8	#CJK UNIFIED IDEOGRAPH
+0xF867	0x9DE4	#CJK UNIFIED IDEOGRAPH
+0xF868	0x9DF6	#CJK UNIFIED IDEOGRAPH
+0xF869	0x9DE1	#CJK UNIFIED IDEOGRAPH
+0xF86A	0x9DEE	#CJK UNIFIED IDEOGRAPH
+0xF86B	0x9DE6	#CJK UNIFIED IDEOGRAPH
+0xF86C	0x9DF2	#CJK UNIFIED IDEOGRAPH
+0xF86D	0x9DF0	#CJK UNIFIED IDEOGRAPH
+0xF86E	0x9DE2	#CJK UNIFIED IDEOGRAPH
+0xF86F	0x9DEC	#CJK UNIFIED IDEOGRAPH
+0xF870	0x9DF4	#CJK UNIFIED IDEOGRAPH
+0xF871	0x9DF3	#CJK UNIFIED IDEOGRAPH
+0xF872	0x9DE8	#CJK UNIFIED IDEOGRAPH
+0xF873	0x9DED	#CJK UNIFIED IDEOGRAPH
+0xF874	0x9EC2	#CJK UNIFIED IDEOGRAPH
+0xF875	0x9ED0	#CJK UNIFIED IDEOGRAPH
+0xF876	0x9EF2	#CJK UNIFIED IDEOGRAPH
+0xF877	0x9EF3	#CJK UNIFIED IDEOGRAPH
+0xF878	0x9F06	#CJK UNIFIED IDEOGRAPH
+0xF879	0x9F1C	#CJK UNIFIED IDEOGRAPH
+0xF87A	0x9F38	#CJK UNIFIED IDEOGRAPH
+0xF87B	0x9F37	#CJK UNIFIED IDEOGRAPH
+0xF87C	0x9F36	#CJK UNIFIED IDEOGRAPH
+0xF87D	0x9F43	#CJK UNIFIED IDEOGRAPH
+0xF87E	0x9F4F	#CJK UNIFIED IDEOGRAPH
+0xF8A1	0x9F71	#CJK UNIFIED IDEOGRAPH
+0xF8A2	0x9F70	#CJK UNIFIED IDEOGRAPH
+0xF8A3	0x9F6E	#CJK UNIFIED IDEOGRAPH
+0xF8A4	0x9F6F	#CJK UNIFIED IDEOGRAPH
+0xF8A5	0x56D3	#CJK UNIFIED IDEOGRAPH
+0xF8A6	0x56CD	#CJK UNIFIED IDEOGRAPH
+0xF8A7	0x5B4E	#CJK UNIFIED IDEOGRAPH
+0xF8A8	0x5C6D	#CJK UNIFIED IDEOGRAPH
+0xF8A9	0x652D	#CJK UNIFIED IDEOGRAPH
+0xF8AA	0x66ED	#CJK UNIFIED IDEOGRAPH
+0xF8AB	0x66EE	#CJK UNIFIED IDEOGRAPH
+0xF8AC	0x6B13	#CJK UNIFIED IDEOGRAPH
+0xF8AD	0x705F	#CJK UNIFIED IDEOGRAPH
+0xF8AE	0x7061	#CJK UNIFIED IDEOGRAPH
+0xF8AF	0x705D	#CJK UNIFIED IDEOGRAPH
+0xF8B0	0x7060	#CJK UNIFIED IDEOGRAPH
+0xF8B1	0x7223	#CJK UNIFIED IDEOGRAPH
+0xF8B2	0x74DB	#CJK UNIFIED IDEOGRAPH
+0xF8B3	0x74E5	#CJK UNIFIED IDEOGRAPH
+0xF8B4	0x77D5	#CJK UNIFIED IDEOGRAPH
+0xF8B5	0x7938	#CJK UNIFIED IDEOGRAPH
+0xF8B6	0x79B7	#CJK UNIFIED IDEOGRAPH
+0xF8B7	0x79B6	#CJK UNIFIED IDEOGRAPH
+0xF8B8	0x7C6A	#CJK UNIFIED IDEOGRAPH
+0xF8B9	0x7E97	#CJK UNIFIED IDEOGRAPH
+0xF8BA	0x7F89	#CJK UNIFIED IDEOGRAPH
+0xF8BB	0x826D	#CJK UNIFIED IDEOGRAPH
+0xF8BC	0x8643	#CJK UNIFIED IDEOGRAPH
+0xF8BD	0x8838	#CJK UNIFIED IDEOGRAPH
+0xF8BE	0x8837	#CJK UNIFIED IDEOGRAPH
+0xF8BF	0x8835	#CJK UNIFIED IDEOGRAPH
+0xF8C0	0x884B	#CJK UNIFIED IDEOGRAPH
+0xF8C1	0x8B94	#CJK UNIFIED IDEOGRAPH
+0xF8C2	0x8B95	#CJK UNIFIED IDEOGRAPH
+0xF8C3	0x8E9E	#CJK UNIFIED IDEOGRAPH
+0xF8C4	0x8E9F	#CJK UNIFIED IDEOGRAPH
+0xF8C5	0x8EA0	#CJK UNIFIED IDEOGRAPH
+0xF8C6	0x8E9D	#CJK UNIFIED IDEOGRAPH
+0xF8C7	0x91BE	#CJK UNIFIED IDEOGRAPH
+0xF8C8	0x91BD	#CJK UNIFIED IDEOGRAPH
+0xF8C9	0x91C2	#CJK UNIFIED IDEOGRAPH
+0xF8CA	0x946B	#CJK UNIFIED IDEOGRAPH
+0xF8CB	0x9468	#CJK UNIFIED IDEOGRAPH
+0xF8CC	0x9469	#CJK UNIFIED IDEOGRAPH
+0xF8CD	0x96E5	#CJK UNIFIED IDEOGRAPH
+0xF8CE	0x9746	#CJK UNIFIED IDEOGRAPH
+0xF8CF	0x9743	#CJK UNIFIED IDEOGRAPH
+0xF8D0	0x9747	#CJK UNIFIED IDEOGRAPH
+0xF8D1	0x97C7	#CJK UNIFIED IDEOGRAPH
+0xF8D2	0x97E5	#CJK UNIFIED IDEOGRAPH
+0xF8D3	0x9A5E	#CJK UNIFIED IDEOGRAPH
+0xF8D4	0x9AD5	#CJK UNIFIED IDEOGRAPH
+0xF8D5	0x9B59	#CJK UNIFIED IDEOGRAPH
+0xF8D6	0x9C63	#CJK UNIFIED IDEOGRAPH
+0xF8D7	0x9C67	#CJK UNIFIED IDEOGRAPH
+0xF8D8	0x9C66	#CJK UNIFIED IDEOGRAPH
+0xF8D9	0x9C62	#CJK UNIFIED IDEOGRAPH
+0xF8DA	0x9C5E	#CJK UNIFIED IDEOGRAPH
+0xF8DB	0x9C60	#CJK UNIFIED IDEOGRAPH
+0xF8DC	0x9E02	#CJK UNIFIED IDEOGRAPH
+0xF8DD	0x9DFE	#CJK UNIFIED IDEOGRAPH
+0xF8DE	0x9E07	#CJK UNIFIED IDEOGRAPH
+0xF8DF	0x9E03	#CJK UNIFIED IDEOGRAPH
+0xF8E0	0x9E06	#CJK UNIFIED IDEOGRAPH
+0xF8E1	0x9E05	#CJK UNIFIED IDEOGRAPH
+0xF8E2	0x9E00	#CJK UNIFIED IDEOGRAPH
+0xF8E3	0x9E01	#CJK UNIFIED IDEOGRAPH
+0xF8E4	0x9E09	#CJK UNIFIED IDEOGRAPH
+0xF8E5	0x9DFF	#CJK UNIFIED IDEOGRAPH
+0xF8E6	0x9DFD	#CJK UNIFIED IDEOGRAPH
+0xF8E7	0x9E04	#CJK UNIFIED IDEOGRAPH
+0xF8E8	0x9EA0	#CJK UNIFIED IDEOGRAPH
+0xF8E9	0x9F1E	#CJK UNIFIED IDEOGRAPH
+0xF8EA	0x9F46	#CJK UNIFIED IDEOGRAPH
+0xF8EB	0x9F74	#CJK UNIFIED IDEOGRAPH
+0xF8EC	0x9F75	#CJK UNIFIED IDEOGRAPH
+0xF8ED	0x9F76	#CJK UNIFIED IDEOGRAPH
+0xF8EE	0x56D4	#CJK UNIFIED IDEOGRAPH
+0xF8EF	0x652E	#CJK UNIFIED IDEOGRAPH
+0xF8F0	0x65B8	#CJK UNIFIED IDEOGRAPH
+0xF8F1	0x6B18	#CJK UNIFIED IDEOGRAPH
+0xF8F2	0x6B19	#CJK UNIFIED IDEOGRAPH
+0xF8F3	0x6B17	#CJK UNIFIED IDEOGRAPH
+0xF8F4	0x6B1A	#CJK UNIFIED IDEOGRAPH
+0xF8F5	0x7062	#CJK UNIFIED IDEOGRAPH
+0xF8F6	0x7226	#CJK UNIFIED IDEOGRAPH
+0xF8F7	0x72AA	#CJK UNIFIED IDEOGRAPH
+0xF8F8	0x77D8	#CJK UNIFIED IDEOGRAPH
+0xF8F9	0x77D9	#CJK UNIFIED IDEOGRAPH
+0xF8FA	0x7939	#CJK UNIFIED IDEOGRAPH
+0xF8FB	0x7C69	#CJK UNIFIED IDEOGRAPH
+0xF8FC	0x7C6B	#CJK UNIFIED IDEOGRAPH
+0xF8FD	0x7CF6	#CJK UNIFIED IDEOGRAPH
+0xF8FE	0x7E9A	#CJK UNIFIED IDEOGRAPH
+0xF940	0x7E98	#CJK UNIFIED IDEOGRAPH
+0xF941	0x7E9B	#CJK UNIFIED IDEOGRAPH
+0xF942	0x7E99	#CJK UNIFIED IDEOGRAPH
+0xF943	0x81E0	#CJK UNIFIED IDEOGRAPH
+0xF944	0x81E1	#CJK UNIFIED IDEOGRAPH
+0xF945	0x8646	#CJK UNIFIED IDEOGRAPH
+0xF946	0x8647	#CJK UNIFIED IDEOGRAPH
+0xF947	0x8648	#CJK UNIFIED IDEOGRAPH
+0xF948	0x8979	#CJK UNIFIED IDEOGRAPH
+0xF949	0x897A	#CJK UNIFIED IDEOGRAPH
+0xF94A	0x897C	#CJK UNIFIED IDEOGRAPH
+0xF94B	0x897B	#CJK UNIFIED IDEOGRAPH
+0xF94C	0x89FF	#CJK UNIFIED IDEOGRAPH
+0xF94D	0x8B98	#CJK UNIFIED IDEOGRAPH
+0xF94E	0x8B99	#CJK UNIFIED IDEOGRAPH
+0xF94F	0x8EA5	#CJK UNIFIED IDEOGRAPH
+0xF950	0x8EA4	#CJK UNIFIED IDEOGRAPH
+0xF951	0x8EA3	#CJK UNIFIED IDEOGRAPH
+0xF952	0x946E	#CJK UNIFIED IDEOGRAPH
+0xF953	0x946D	#CJK UNIFIED IDEOGRAPH
+0xF954	0x946F	#CJK UNIFIED IDEOGRAPH
+0xF955	0x9471	#CJK UNIFIED IDEOGRAPH
+0xF956	0x9473	#CJK UNIFIED IDEOGRAPH
+0xF957	0x9749	#CJK UNIFIED IDEOGRAPH
+0xF958	0x9872	#CJK UNIFIED IDEOGRAPH
+0xF959	0x995F	#CJK UNIFIED IDEOGRAPH
+0xF95A	0x9C68	#CJK UNIFIED IDEOGRAPH
+0xF95B	0x9C6E	#CJK UNIFIED IDEOGRAPH
+0xF95C	0x9C6D	#CJK UNIFIED IDEOGRAPH
+0xF95D	0x9E0B	#CJK UNIFIED IDEOGRAPH
+0xF95E	0x9E0D	#CJK UNIFIED IDEOGRAPH
+0xF95F	0x9E10	#CJK UNIFIED IDEOGRAPH
+0xF960	0x9E0F	#CJK UNIFIED IDEOGRAPH
+0xF961	0x9E12	#CJK UNIFIED IDEOGRAPH
+0xF962	0x9E11	#CJK UNIFIED IDEOGRAPH
+0xF963	0x9EA1	#CJK UNIFIED IDEOGRAPH
+0xF964	0x9EF5	#CJK UNIFIED IDEOGRAPH
+0xF965	0x9F09	#CJK UNIFIED IDEOGRAPH
+0xF966	0x9F47	#CJK UNIFIED IDEOGRAPH
+0xF967	0x9F78	#CJK UNIFIED IDEOGRAPH
+0xF968	0x9F7B	#CJK UNIFIED IDEOGRAPH
+0xF969	0x9F7A	#CJK UNIFIED IDEOGRAPH
+0xF96A	0x9F79	#CJK UNIFIED IDEOGRAPH
+0xF96B	0x571E	#CJK UNIFIED IDEOGRAPH
+0xF96C	0x7066	#CJK UNIFIED IDEOGRAPH
+0xF96D	0x7C6F	#CJK UNIFIED IDEOGRAPH
+0xF96E	0x883C	#CJK UNIFIED IDEOGRAPH
+0xF96F	0x8DB2	#CJK UNIFIED IDEOGRAPH
+0xF970	0x8EA6	#CJK UNIFIED IDEOGRAPH
+0xF971	0x91C3	#CJK UNIFIED IDEOGRAPH
+0xF972	0x9474	#CJK UNIFIED IDEOGRAPH
+0xF973	0x9478	#CJK UNIFIED IDEOGRAPH
+0xF974	0x9476	#CJK UNIFIED IDEOGRAPH
+0xF975	0x9475	#CJK UNIFIED IDEOGRAPH
+0xF976	0x9A60	#CJK UNIFIED IDEOGRAPH
+0xF977	0x9C74	#CJK UNIFIED IDEOGRAPH
+0xF978	0x9C73	#CJK UNIFIED IDEOGRAPH
+0xF979	0x9C71	#CJK UNIFIED IDEOGRAPH
+0xF97A	0x9C75	#CJK UNIFIED IDEOGRAPH
+0xF97B	0x9E14	#CJK UNIFIED IDEOGRAPH
+0xF97C	0x9E13	#CJK UNIFIED IDEOGRAPH
+0xF97D	0x9EF6	#CJK UNIFIED IDEOGRAPH
+0xF97E	0x9F0A	#CJK UNIFIED IDEOGRAPH
+0xF9A1	0x9FA4	#CJK UNIFIED IDEOGRAPH
+0xF9A2	0x7068	#CJK UNIFIED IDEOGRAPH
+0xF9A3	0x7065	#CJK UNIFIED IDEOGRAPH
+0xF9A4	0x7CF7	#CJK UNIFIED IDEOGRAPH
+0xF9A5	0x866A	#CJK UNIFIED IDEOGRAPH
+0xF9A6	0x883E	#CJK UNIFIED IDEOGRAPH
+0xF9A7	0x883D	#CJK UNIFIED IDEOGRAPH
+0xF9A8	0x883F	#CJK UNIFIED IDEOGRAPH
+0xF9A9	0x8B9E	#CJK UNIFIED IDEOGRAPH
+0xF9AA	0x8C9C	#CJK UNIFIED IDEOGRAPH
+0xF9AB	0x8EA9	#CJK UNIFIED IDEOGRAPH
+0xF9AC	0x8EC9	#CJK UNIFIED IDEOGRAPH
+0xF9AD	0x974B	#CJK UNIFIED IDEOGRAPH
+0xF9AE	0x9873	#CJK UNIFIED IDEOGRAPH
+0xF9AF	0x9874	#CJK UNIFIED IDEOGRAPH
+0xF9B0	0x98CC	#CJK UNIFIED IDEOGRAPH
+0xF9B1	0x9961	#CJK UNIFIED IDEOGRAPH
+0xF9B2	0x99AB	#CJK UNIFIED IDEOGRAPH
+0xF9B3	0x9A64	#CJK UNIFIED IDEOGRAPH
+0xF9B4	0x9A66	#CJK UNIFIED IDEOGRAPH
+0xF9B5	0x9A67	#CJK UNIFIED IDEOGRAPH
+0xF9B6	0x9B24	#CJK UNIFIED IDEOGRAPH
+0xF9B7	0x9E15	#CJK UNIFIED IDEOGRAPH
+0xF9B8	0x9E17	#CJK UNIFIED IDEOGRAPH
+0xF9B9	0x9F48	#CJK UNIFIED IDEOGRAPH
+0xF9BA	0x6207	#CJK UNIFIED IDEOGRAPH
+0xF9BB	0x6B1E	#CJK UNIFIED IDEOGRAPH
+0xF9BC	0x7227	#CJK UNIFIED IDEOGRAPH
+0xF9BD	0x864C	#CJK UNIFIED IDEOGRAPH
+0xF9BE	0x8EA8	#CJK UNIFIED IDEOGRAPH
+0xF9BF	0x9482	#CJK UNIFIED IDEOGRAPH
+0xF9C0	0x9480	#CJK UNIFIED IDEOGRAPH
+0xF9C1	0x9481	#CJK UNIFIED IDEOGRAPH
+0xF9C2	0x9A69	#CJK UNIFIED IDEOGRAPH
+0xF9C3	0x9A68	#CJK UNIFIED IDEOGRAPH
+0xF9C4	0x9B2E	#CJK UNIFIED IDEOGRAPH
+0xF9C5	0x9E19	#CJK UNIFIED IDEOGRAPH
+0xF9C6	0x7229	#CJK UNIFIED IDEOGRAPH
+0xF9C7	0x864B	#CJK UNIFIED IDEOGRAPH
+0xF9C8	0x8B9F	#CJK UNIFIED IDEOGRAPH
+0xF9C9	0x9483	#CJK UNIFIED IDEOGRAPH
+0xF9CA	0x9C79	#CJK UNIFIED IDEOGRAPH
+0xF9CB	0x9EB7	#CJK UNIFIED IDEOGRAPH
+0xF9CC	0x7675	#CJK UNIFIED IDEOGRAPH
+0xF9CD	0x9A6B	#CJK UNIFIED IDEOGRAPH
+0xF9CE	0x9C7A	#CJK UNIFIED IDEOGRAPH
+0xF9CF	0x9E1D	#CJK UNIFIED IDEOGRAPH
+0xF9D0	0x7069	#CJK UNIFIED IDEOGRAPH
+0xF9D1	0x706A	#CJK UNIFIED IDEOGRAPH
+0xF9D2	0x9EA4	#CJK UNIFIED IDEOGRAPH
+0xF9D3	0x9F7E	#CJK UNIFIED IDEOGRAPH
+0xF9D4	0x9F49	#CJK UNIFIED IDEOGRAPH
+0xF9D5	0x9F98	#CJK UNIFIED IDEOGRAPH
+0xF9D6	0x7881	#CJK UNIFIED IDEOGRAPH
+0xF9D7	0x92B9	#CJK UNIFIED IDEOGRAPH
+0xF9D8	0x88CF	#CJK UNIFIED IDEOGRAPH
+0xF9D9	0x58BB	#CJK UNIFIED IDEOGRAPH
+0xF9DA	0x6052	#CJK UNIFIED IDEOGRAPH
+0xF9DB	0x7CA7	#CJK UNIFIED IDEOGRAPH
+0xF9DC	0x5AFA	#CJK UNIFIED IDEOGRAPH
+0xF9DD	0x2554	#BOX DRAWINGS DOUBLE DOWN AND RIGHT
+0xF9DE	0x2566	#BOX DRAWINGS DOUBLE DOWN AND HORIZONTAL
+0xF9DF	0x2557	#BOX DRAWINGS DOUBLE DOWN AND LEFT
+0xF9E0	0x2560	#BOX DRAWINGS DOUBLE VERTICAL AND RIGHT
+0xF9E1	0x256C	#BOX DRAWINGS DOUBLE VERTICAL AND HORIZONTAL
+0xF9E2	0x2563	#BOX DRAWINGS DOUBLE VERTICAL AND LEFT
+0xF9E3	0x255A	#BOX DRAWINGS DOUBLE UP AND RIGHT
+0xF9E4	0x2569	#BOX DRAWINGS DOUBLE UP AND HORIZONTAL
+0xF9E5	0x255D	#BOX DRAWINGS DOUBLE UP AND LEFT
+0xF9E6	0x2552	#BOX DRAWINGS DOWN SINGLE AND RIGHT DOUBLE
+0xF9E7	0x2564	#BOX DRAWINGS DOWN SINGLE AND HORIZONTAL DOUBLE
+0xF9E8	0x2555	#BOX DRAWINGS DOWN SINGLE AND LEFT DOUBLE
+0xF9E9	0x255E	#BOX DRAWINGS VERTICAL SINGLE AND RIGHT DOUBLE
+0xF9EA	0x256A	#BOX DRAWINGS VERTICAL SINGLE AND HORIZONTAL DOUBLE
+0xF9EB	0x2561	#BOX DRAWINGS VERTICAL SINGLE AND LEFT DOUBLE
+0xF9EC	0x2558	#BOX DRAWINGS UP SINGLE AND RIGHT DOUBLE
+0xF9ED	0x2567	#BOX DRAWINGS UP SINGLE AND HORIZONTAL DOUBLE
+0xF9EE	0x255B	#BOX DRAWINGS UP SINGLE AND LEFT DOUBLE
+0xF9EF	0x2553	#BOX DRAWINGS DOWN DOUBLE AND RIGHT SINGLE
+0xF9F0	0x2565	#BOX DRAWINGS DOWN DOUBLE AND HORIZONTAL SINGLE
+0xF9F1	0x2556	#BOX DRAWINGS DOWN DOUBLE AND LEFT SINGLE
+0xF9F2	0x255F	#BOX DRAWINGS VERTICAL DOUBLE AND RIGHT SINGLE
+0xF9F3	0x256B	#BOX DRAWINGS VERTICAL DOUBLE AND HORIZONTAL SINGLE
+0xF9F4	0x2562	#BOX DRAWINGS VERTICAL DOUBLE AND LEFT SINGLE
+0xF9F5	0x2559	#BOX DRAWINGS UP DOUBLE AND RIGHT SINGLE
+0xF9F6	0x2568	#BOX DRAWINGS UP DOUBLE AND HORIZONTAL SINGLE
+0xF9F7	0x255C	#BOX DRAWINGS UP DOUBLE AND LEFT SINGLE
+0xF9F8	0x2551	#BOX DRAWINGS DOUBLE VERTICAL
+0xF9F9	0x2550	#BOX DRAWINGS DOUBLE HORIZONTAL
+0xF9FA	0x256D	#BOX DRAWINGS LIGHT ARC DOWN AND RIGHT
+0xF9FB	0x256E	#BOX DRAWINGS LIGHT ARC DOWN AND LEFT
+0xF9FC	0x2570	#BOX DRAWINGS LIGHT ARC UP AND RIGHT
+0xF9FD	0x256F	#BOX DRAWINGS LIGHT ARC UP AND LEFT
+0xF9FE	0x2593	#DARK SHADE
diff --git a/tools/encoding/dingbats.txt b/tools/encoding/dingbats.txt
new file mode 100644
index 0000000..334f8d6
--- /dev/null
+++ b/tools/encoding/dingbats.txt
@@ -0,0 +1,250 @@
+#
+# ITC Dingbats, for use on X.  Doesn't have Mac dingbats extensions.
+#
+# This file is derived from:
+#
+#   Name:             MacOS_Dingbats [to Unicode]
+#   Unicode versions: 1.1, 2.0
+#   Table version:    0.2 (from internal ufrm version <4>)
+#   Date:             15 April 1995
+#   Author:           Peter Edberg <edberg1@applelink.apple.com>
+#
+#   Copyright (c) 1995 Apple Computer, Inc.  All Rights reserved.
+#
+#   Apple, the Apple logo, and Macintosh are trademarks of Apple
+#   Computer, Inc., registered in the United States and other countries.
+#   Unicode is a trademark of Unicode Inc. For the sake of brevity,
+#   throughout this document, "Macintosh" can be used to refer to
+#   Macintosh computers and "Unicode" can be used to refer to the
+#   Unicode standard.
+#
+#   Apple makes no warranty or representation, either express or
+#   implied, with respect to these tables, their quality, accuracy, or
+#   fitness for a particular purpose. In no event will Apple be liable
+#   for direct, indirect, special, incidental, or consequential damages
+#   resulting from any defect or inaccuracy in this document or the
+#   accompanying tables.
+#
+#   These mapping tables and character lists are preliminary and
+#   subject to change. Updated tables will be available from the
+#   Unicode Inc. ftp site (unicode.org), the Apple Computer ftp site
+#   (ftp.info.apple.com), the Apple Computer World-Wide Web pages
+#   (http://www.info.apple.com), and possibly on diskette from APDA
+#   (Apple's mail-order distribution service for developers).
+#
+#   Format:
+#   -------
+#
+#   Three tab-separated columns;
+#   '#' begins a comment which continues to the end of the line.
+#     Column #1 is the MacOS Dingbats code (in hex as 0xNN)
+#     Column #2 is the Unicode (in hex as 0xNNNN)
+#     Column #3 is the Unicode name (follows a comment sign, '#')
+#
+#   The entries are in MacOS Dingbats code order.
+#
+#   Several of these mappings require the use of corporate
+#   characters. See the file "MacOS-CorpCharList".
+#
+#   Notes on MacOS Dingbats:
+#   ------------------------
+#
+#   The MacOS Dingbats encoding shares the script code smRoman
+#   (0) with the standard MacOS Roman encoding. To determine if
+#   the Dingbats encoding is being used, you must check if the
+#   font name is "Zapf Dingbats".
+#
+#   The layout of the Dingbats character set is identical to or
+#   a superset of the layout of the Adobe Zapf Dingbats encoding
+#   vector.
+#
+##################
+
+0x20	0x0020	# SPACE
+0x21	0x2701	# UPPER BLADE SCISSORS
+0x22	0x2702	# BLACK SCISSORS
+0x23	0x2703	# LOWER BLADE SCISSORS
+0x24	0x2704	# WHITE SCISSORS
+0x25	0x260E	# BLACK TELEPHONE
+0x26	0x2706	# TELEPHONE LOCATION SIGN
+0x27	0x2707	# TAPE DRIVE
+0x28	0x2708	# AIRPLANE
+0x29	0x2709	# ENVELOPE
+0x2A	0x261B	# BLACK RIGHT POINTING INDEX
+0x2B	0x261E	# WHITE RIGHT POINTING INDEX
+0x2C	0x270C	# VICTORY HAND
+0x2D	0x270D	# WRITING HAND
+0x2E	0x270E	# LOWER RIGHT PENCIL
+0x2F	0x270F	# PENCIL
+0x30	0x2710	# UPPER RIGHT PENCIL
+0x31	0x2711	# WHITE NIB
+0x32	0x2712	# BLACK NIB
+0x33	0x2713	# CHECK MARK
+0x34	0x2714	# HEAVY CHECK MARK
+0x35	0x2715	# MULTIPLICATION X
+0x36	0x2716	# HEAVY MULTIPLICATION X
+0x37	0x2717	# BALLOT X
+0x38	0x2718	# HEAVY BALLOT X
+0x39	0x2719	# OUTLINED GREEK CROSS
+0x3A	0x271A	# HEAVY GREEK CROSS
+0x3B	0x271B	# OPEN CENTRE CROSS
+0x3C	0x271C	# HEAVY OPEN CENTRE CROSS
+0x3D	0x271D	# LATIN CROSS
+0x3E	0x271E	# SHADOWED WHITE LATIN CROSS
+0x3F	0x271F	# OUTLINED LATIN CROSS
+0x40	0x2720	# MALTESE CROSS
+0x41	0x2721	# STAR OF DAVID
+0x42	0x2722	# FOUR TEARDROP-SPOKED ASTERISK
+0x43	0x2723	# FOUR BALLOON-SPOKED ASTERISK
+0x44	0x2724	# HEAVY FOUR BALLOON-SPOKED ASTERISK
+0x45	0x2725	# FOUR CLUB-SPOKED ASTERISK
+0x46	0x2726	# BLACK FOUR POINTED STAR
+0x47	0x2727	# WHITE FOUR POINTED STAR
+0x48	0x2605	# BLACK STAR
+0x49	0x2729	# STRESS OUTLINED WHITE STAR
+0x4A	0x272A	# CIRCLED WHITE STAR
+0x4B	0x272B	# OPEN CENTRE BLACK STAR
+0x4C	0x272C	# BLACK CENTRE WHITE STAR
+0x4D	0x272D	# OUTLINED BLACK STAR
+0x4E	0x272E	# HEAVY OUTLINED BLACK STAR
+0x4F	0x272F	# PINWHEEL STAR
+0x50	0x2730	# SHADOWED WHITE STAR
+0x51	0x2731	# HEAVY ASTERISK
+0x52	0x2732	# OPEN CENTRE ASTERISK
+0x53	0x2733	# EIGHT SPOKED ASTERISK
+0x54	0x2734	# EIGHT POINTED BLACK STAR
+0x55	0x2735	# EIGHT POINTED PINWHEEL STAR
+0x56	0x2736	# SIX POINTED BLACK STAR
+0x57	0x2737	# EIGHT POINTED RECTILINEAR BLACK STAR
+0x58	0x2738	# HEAVY EIGHT POINTED RECTILINEAR BLACK STAR
+0x59	0x2739	# TWELVE POINTED BLACK STAR
+0x5A	0x273A	# SIXTEEN POINTED ASTERISK
+0x5B	0x273B	# TEARDROP-SPOKED ASTERISK
+0x5C	0x273C	# OPEN CENTRE TEARDROP-SPOKED ASTERISK
+0x5D	0x273D	# HEAVY TEARDROP-SPOKED ASTERISK
+0x5E	0x273E	# SIX PETALLED BLACK AND WHITE FLORETTE
+0x5F	0x273F	# BLACK FLORETTE
+0x60	0x2740	# WHITE FLORETTE
+0x61	0x2741	# EIGHT PETALLED OUTLINED BLACK FLORETTE
+0x62	0x2742	# CIRCLED OPEN CENTRE EIGHT POINTED STAR
+0x63	0x2743	# HEAVY TEARDROP-SPOKED PINWHEEL ASTERISK
+0x64	0x2744	# SNOWFLAKE
+0x65	0x2745	# TIGHT TRIFOLIATE SNOWFLAKE
+0x66	0x2746	# HEAVY CHEVRON SNOWFLAKE
+0x67	0x2747	# SPARKLE
+0x68	0x2748	# HEAVY SPARKLE
+0x69	0x2749	# BALLOON-SPOKED ASTERISK
+0x6A	0x274A	# EIGHT TEARDROP-SPOKED PROPELLER ASTERISK
+0x6B	0x274B	# HEAVY EIGHT TEARDROP-SPOKED PROPELLER ASTERISK
+0x6C	0x25CF	# BLACK CIRCLE
+0x6D	0x274D	# SHADOWED WHITE CIRCLE
+0x6E	0x25A0	# BLACK SQUARE
+0x6F	0x274F	# LOWER RIGHT DROP-SHADOWED WHITE SQUARE
+0x70	0x2750	# UPPER RIGHT DROP-SHADOWED WHITE SQUARE
+0x71	0x2751	# LOWER RIGHT SHADOWED WHITE SQUARE
+0x72	0x2752	# UPPER RIGHT SHADOWED WHITE SQUARE
+0x73	0x25B2	# BLACK UP-POINTING TRIANGLE
+0x74	0x25BC	# BLACK DOWN-POINTING TRIANGLE
+0x75	0x25C6	# BLACK DIAMOND
+0x76	0x2756	# BLACK DIAMOND MINUS WHITE X
+0x77	0x25D7	# RIGHT HALF BLACK CIRCLE
+0x78	0x2758	# LIGHT VERTICAL BAR
+0x79	0x2759	# MEDIUM VERTICAL BAR
+0x7A	0x275A	# HEAVY VERTICAL BAR
+0x7B	0x275B	# HEAVY SINGLE TURNED COMMA QUOTATION MARK ORNAMENT
+0x7C	0x275C	# HEAVY SINGLE COMMA QUOTATION MARK ORNAMENT
+0x7D	0x275D	# HEAVY DOUBLE TURNED COMMA QUOTATION MARK ORNAMENT
+0x7E	0x275E	# HEAVY DOUBLE COMMA QUOTATION MARK ORNAMENT
+0xA1	0x2761	# CURVED STEM PARAGRAPH SIGN ORNAMENT
+0xA2	0x2762	# HEAVY EXCLAMATION MARK ORNAMENT
+0xA3	0x2763	# HEAVY HEART EXCLAMATION MARK ORNAMENT
+0xA4	0x2764	# HEAVY BLACK HEART
+0xA5	0x2765	# ROTATED HEAVY BLACK HEART BULLET
+0xA6	0x2766	# FLORAL HEART
+0xA7	0x2767	# ROTATED FLORAL HEART BULLET
+0xA8	0x2663	# BLACK CLUB SUIT
+0xA9	0x2666	# BLACK DIAMOND SUIT
+0xAA	0x2665	# BLACK HEART SUIT
+0xAB	0x2660	# BLACK SPADE SUIT
+0xAC	0x2460	# CIRCLED DIGIT ONE
+0xAD	0x2461	# CIRCLED DIGIT TWO
+0xAE	0x2462	# CIRCLED DIGIT THREE
+0xAF	0x2463	# CIRCLED DIGIT FOUR
+0xB0	0x2464	# CIRCLED DIGIT FIVE
+0xB1	0x2465	# CIRCLED DIGIT SIX
+0xB2	0x2466	# CIRCLED DIGIT SEVEN
+0xB3	0x2467	# CIRCLED DIGIT EIGHT
+0xB4	0x2468	# CIRCLED DIGIT NINE
+0xB5	0x2469	# CIRCLED NUMBER TEN
+0xB6	0x2776	# DINGBAT NEGATIVE CIRCLED DIGIT ONE
+0xB7	0x2777	# DINGBAT NEGATIVE CIRCLED DIGIT TWO
+0xB8	0x2778	# DINGBAT NEGATIVE CIRCLED DIGIT THREE
+0xB9	0x2779	# DINGBAT NEGATIVE CIRCLED DIGIT FOUR
+0xBA	0x277A	# DINGBAT NEGATIVE CIRCLED DIGIT FIVE
+0xBB	0x277B	# DINGBAT NEGATIVE CIRCLED DIGIT SIX
+0xBC	0x277C	# DINGBAT NEGATIVE CIRCLED DIGIT SEVEN
+0xBD	0x277D	# DINGBAT NEGATIVE CIRCLED DIGIT EIGHT
+0xBE	0x277E	# DINGBAT NEGATIVE CIRCLED DIGIT NINE
+0xBF	0x277F	# DINGBAT NEGATIVE CIRCLED NUMBER TEN
+0xC0	0x2780	# DINGBAT CIRCLED SANS-SERIF DIGIT ONE
+0xC1	0x2781	# DINGBAT CIRCLED SANS-SERIF DIGIT TWO
+0xC2	0x2782	# DINGBAT CIRCLED SANS-SERIF DIGIT THREE
+0xC3	0x2783	# DINGBAT CIRCLED SANS-SERIF DIGIT FOUR
+0xC4	0x2784	# DINGBAT CIRCLED SANS-SERIF DIGIT FIVE
+0xC5	0x2785	# DINGBAT CIRCLED SANS-SERIF DIGIT SIX
+0xC6	0x2786	# DINGBAT CIRCLED SANS-SERIF DIGIT SEVEN
+0xC7	0x2787	# DINGBAT CIRCLED SANS-SERIF DIGIT EIGHT
+0xC8	0x2788	# DINGBAT CIRCLED SANS-SERIF DIGIT NINE
+0xC9	0x2789	# DINGBAT CIRCLED SANS-SERIF NUMBER TEN
+0xCA	0x278A	# DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT ONE
+0xCB	0x278B	# DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT TWO
+0xCC	0x278C	# DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT THREE
+0xCD	0x278D	# DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT FOUR
+0xCE	0x278E	# DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT FIVE
+0xCF	0x278F	# DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT SIX
+0xD0	0x2790	# DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT SEVEN
+0xD1	0x2791	# DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT EIGHT
+0xD2	0x2792	# DINGBAT NEGATIVE CIRCLED SANS-SERIF DIGIT NINE
+0xD3	0x2793	# DINGBAT NEGATIVE CIRCLED SANS-SERIF NUMBER TEN
+0xD4	0x2794	# HEAVY WIDE-HEADED RIGHTWARDS ARROW
+0xD5	0x2192	# RIGHTWARDS ARROW
+0xD6	0x2194	# LEFT RIGHT ARROW
+0xD7	0x2195	# UP DOWN ARROW
+0xD8	0x2798	# HEAVY SOUTH EAST ARROW
+0xD9	0x2799	# HEAVY RIGHTWARDS ARROW
+0xDA	0x279A	# HEAVY NORTH EAST ARROW
+0xDB	0x279B	# DRAFTING POINT RIGHTWARDS ARROW
+0xDC	0x279C	# HEAVY ROUND-TIPPED RIGHTWARDS ARROW
+0xDD	0x279D	# TRIANGLE-HEADED RIGHTWARDS ARROW
+0xDE	0x279E	# HEAVY TRIANGLE-HEADED RIGHTWARDS ARROW
+0xDF	0x279F	# DASHED TRIANGLE-HEADED RIGHTWARDS ARROW
+0xE0	0x27A0	# HEAVY DASHED TRIANGLE-HEADED RIGHTWARDS ARROW
+0xE1	0x27A1	# BLACK RIGHTWARDS ARROW
+0xE2	0x27A2	# THREE-D TOP-LIGHTED RIGHTWARDS ARROWHEAD
+0xE3	0x27A3	# THREE-D BOTTOM-LIGHTED RIGHTWARDS ARROWHEAD
+0xE4	0x27A4	# BLACK RIGHTWARDS ARROWHEAD
+0xE5	0x27A5	# HEAVY BLACK CURVED DOWNWARDS AND RIGHTWARDS ARROW
+0xE6	0x27A6	# HEAVY BLACK CURVED UPWARDS AND RIGHTWARDS ARROW
+0xE7	0x27A7	# SQUAT BLACK RIGHTWARDS ARROW
+0xE8	0x27A8	# HEAVY CONCAVE-POINTED BLACK RIGHTWARDS ARROW
+0xE9	0x27A9	# RIGHT-SHADED WHITE RIGHTWARDS ARROW
+0xEA	0x27AA	# LEFT-SHADED WHITE RIGHTWARDS ARROW
+0xEB	0x27AB	# BACK-TILTED SHADOWED WHITE RIGHTWARDS ARROW
+0xEC	0x27AC	# FRONT-TILTED SHADOWED WHITE RIGHTWARDS ARROW
+0xED	0x27AD	# HEAVY LOWER RIGHT-SHADOWED WHITE RIGHTWARDS ARROW
+0xEE	0x27AE	# HEAVY UPPER RIGHT-SHADOWED WHITE RIGHTWARDS ARROW
+0xEF	0x27AF	# NOTCHED LOWER RIGHT-SHADOWED WHITE RIGHTWARDS ARROW
+0xF1	0x27B1	# NOTCHED UPPER RIGHT-SHADOWED WHITE RIGHTWARDS ARROW
+0xF2	0x27B2	# CIRCLED HEAVY WHITE RIGHTWARDS ARROW
+0xF3	0x27B3	# WHITE-FEATHERED RIGHTWARDS ARROW
+0xF4	0x27B4	# BLACK-FEATHERED SOUTH EAST ARROW
+0xF5	0x27B5	# BLACK-FEATHERED RIGHTWARDS ARROW
+0xF6	0x27B6	# BLACK-FEATHERED NORTH EAST ARROW
+0xF7	0x27B7	# HEAVY BLACK-FEATHERED SOUTH EAST ARROW
+0xF8	0x27B8	# HEAVY BLACK-FEATHERED RIGHTWARDS ARROW
+0xF9	0x27B9	# HEAVY BLACK-FEATHERED NORTH EAST ARROW
+0xFA	0x27BA	# TEARDROP-BARBED RIGHTWARDS ARROW
+0xFB	0x27BB	# HEAVY TEARDROP-SHANKED RIGHTWARDS ARROW
+0xFC	0x27BC	# WEDGE-TAILED RIGHTWARDS ARROW
+0xFD	0x27BD	# HEAVY WEDGE-TAILED RIGHTWARDS ARROW
+0xFE	0x27BE	# OPEN OUTLINED RIGHTWARDS ARROW
diff --git a/tools/encoding/ebcdic.txt b/tools/encoding/ebcdic.txt
new file mode 100644
index 0000000..d9fa42e
--- /dev/null
+++ b/tools/encoding/ebcdic.txt
@@ -0,0 +1,289 @@
+#
+#	Name:             EBCDIC (EDF04) to Unicode
+#	Unicode version:  1.1
+#	Table version:    0.1
+#	Table format:     Format A
+#	Date:             1 February 2000
+#	Author:           Jan Nijtmans <j.nijtmans@chello.nl>
+#
+#	Copyright (c) 1999-2000 Jan Nijtmans.  All Rights reserved.
+#
+#	This file is provided as-is.
+#	No claims are made as to fitness for any particular purpose.  No
+#	warranties of any kind are expressed or implied.  The recipient
+#	agrees to determine applicability of information provided.
+#
+#	Recipient is granted the right to make copies in any form for
+#	redistribution and to freely use the information supplied
+#	in the creation of products.
+#
+#	General notes:
+#
+#	Format:  Three tab-separated columns
+#		 Column #1 is the EBCDIC code (in hex as 0xXX)
+#		 Column #2 is the Unicode (in hex as 0xXXXX)
+#		 Column #3 the Unicode name (follows a comment sign, '#')
+#
+#	The entries are in EBCDIC order
+#
+#	source: <file:ebcdic.c> from openssl distribution
+#
+#	Any comments or problems, contact <j.nijtmans@chello.nl>
+#
+0x00	0x0000	#	NUL
+0x01	0x0001	#	SOH
+0x02	0x0002	#	STX
+0x03	0x0003	#	ETX
+0x04	0x0085	#
+0x05	0x0009	#	HT
+0x06	0x0086	#
+0x07	0x007F	#	DEL
+0x08	0x0087	#
+0x09	0x008D	#
+0x0A	0x008E	#
+0x0B	0x000B	#	VT
+0x0C	0x000C	#	FF
+0x0D	0x000D	#	CR
+0x0E	0x000E	#	SO
+0x0F	0x000F	#	SI
+0x10	0x0010	#	DLE
+0x11	0x0011	#	DC1
+0x12	0x0012	#	DC2
+0x13	0x0013	#	DC3
+0x14	0x008F	#
+0x15	0x000A	#	LF
+0x16	0x0008	#	BS
+0x17	0x0097	#
+0x18	0x0018	#	CAN
+0x19	0x0019	#	EM
+0x1A	0x009C	#
+0x1B	0x009D	#
+0x1C	0x001C	#	IFS
+0x1D	0x001D	#	IGS
+0x1E	0x001E	#	IRS
+0x1F	0x001F	#	IUS
+0x20	0x0080	#
+0x21	0x0081	#
+0x22	0x0082	#
+0x23	0x0083	#
+0x24	0x0084	#
+0x25	0x0092	#
+0x26	0x0017	#	ETB
+0x27	0x001B	#	ESC
+0x28	0x0088	#
+0x29	0x0089	#
+0x2A	0x008A	#
+0x2B	0x008B	#
+0x2C	0x008C	#
+0x2D	0x0005	#	ENQ
+0x2E	0x0006	#	ACK
+0x2F	0x0007	#	BEL
+0x30	0x0090	#
+0x31	0x0091	#
+0x32	0x0016	#	SYN
+0x33	0x0093	#
+0x34	0x0094	#
+0x35	0x0095	#
+0x36	0x0096	#
+0x37	0x0004	#	EOT
+0x38	0x0098	#
+0x39	0x0099	#
+0x3A	0x009A	#
+0x3B	0x009B	#
+0x3C	0x0014	#	DC4
+0x3D	0x0015	#	NAK
+0x3E	0x009E	#
+0x3F	0x001A	#	SUB
+0x40	0x0020	#	SPACE
+0x41	0x00A0	#
+0x42	0x00E2	#
+0x43	0x00E4	#
+0x44	0x00E0	#
+0x45	0x00E1	#
+0x46	0x00E3	#
+0x47	0x00E5	#
+0x48	0x00E7	#
+0x49	0x00F1	#
+0x4A	0x0060	#	GRAVE ACCENT
+0x4B	0x002E	#	FULL STOP
+0x4C	0x003C	#	LESS-THAN SIGN
+0x4D	0x0028	#	LEFT PARENTHESIS
+0x4E	0x002B	#	PLUS SIGN
+0x4F	0x007C	#	VERTICAL LINE
+0x50	0x0026	#	AMPERSAND
+0x51	0x00E9	#
+0x52	0x00EA	#
+0x53	0x00EB	#
+0x54	0x00E8	#
+0x55	0x00ED	#
+0x56	0x00EE	#
+0x57	0x00EF	#
+0x58	0x00EC	#
+0x59	0x00DF	#
+0x5A	0x0021	#	EXCLAMATION MARK
+0x5B	0x0024	#	DOLLAR SIGN
+0x5C	0x002A	#	ASTERISK
+0x5D	0x0029	#	RIGHT PARENTHESIS
+0x5E	0x003B	#	SEMICOLON
+0x5F	0x009F	#
+0x60	0x002D	#	HYPHEN-MINUS
+0x61	0x002F	#	SOLIDUS
+0x62	0x00C2	#
+0x63	0x00C4	#
+0x64	0x00C0	#
+0x65	0x00C1	#
+0x66	0x00C3	#
+0x67	0x00C5	#
+0x68	0x00C7	#
+0x69	0x00D1	#
+0x6A	0x005E	#	CIRCUMFLEX ACCENT
+0x6B	0x002C	#	COMMA
+0x6C	0x0025	#	PERCENT SIGN
+0x6D	0x005F	#	LOW LINE
+0x6E	0x003E	#	GREATER-THAN SIGN
+0x6F	0x003F	#	QUESTION MARK
+0x70	0x00F8	#
+0x71	0x00C9	#
+0x72	0x00CA	#
+0x73	0x00CB	#
+0x74	0x00C8	#
+0x75	0x00CD	#
+0x76	0x00CE	#
+0x77	0x00CF	#
+0x78	0x00CC	#
+0x79	0x00A8	#
+0x7A	0x003A	#	COLON
+0x7B	0x0023	#	NUMBER SIGN
+0x7C	0x0040	#	COMMERCIAL AT
+0x7D	0x0027	#	APOSTROPHE
+0x7E	0x003D	#	EQUALS SIGN
+0x7F	0x0022	#	QUOTATION MARK
+0x80	0x00D8	#
+0x81	0x0061	#	LATIN SMALL LETTER A
+0x82	0x0062	#	LATIN SMALL LETTER B
+0x83	0x0063	#	LATIN SMALL LETTER C
+0x84	0x0064	#	LATIN SMALL LETTER D
+0x85	0x0065	#	LATIN SMALL LETTER E
+0x86	0x0066	#	LATIN SMALL LETTER F
+0x87	0x0067	#	LATIN SMALL LETTER G
+0x88	0x0068	#	LATIN SMALL LETTER H
+0x89	0x0069	#	LATIN SMALL LETTER I
+0x8A	0x00AB	#
+0x8B	0x00BB	#
+0x8C	0x00F0	#
+0x8D	0x00FD	#
+0x8E	0x00FE	#
+0x8F	0x00B1	#
+0x90	0x00B0	#
+0x91	0x006A	#	LATIN SMALL LETTER J
+0x92	0x006B	#	LATIN SMALL LETTER K
+0x93	0x006C	#	LATIN SMALL LETTER L
+0x94	0x006D	#	LATIN SMALL LETTER M
+0x95	0x006E	#	LATIN SMALL LETTER N
+0x96	0x006F	#	LATIN SMALL LETTER O
+0x97	0x0070	#	LATIN SMALL LETTER P
+0x98	0x0071	#	LATIN SMALL LETTER Q
+0x99	0x0072	#	LATIN SMALL LETTER R
+0x9A	0x00AA	#
+0x9B	0x00BA	#
+0x9C	0x00E6	#
+0x9D	0x00B8	#
+0x9E	0x00C6	#
+0x9F	0x00A4	#
+0xA0	0x00B5	#
+0xA1	0x00AF	#
+0xA2	0x0073	#	LATIN SMALL LETTER S
+0xA3	0x0074	#	LATIN SMALL LETTER T
+0xA4	0x0075	#	LATIN SMALL LETTER U
+0xA5	0x0076	#	LATIN SMALL LETTER V
+0xA6	0x0077	#	LATIN SMALL LETTER W
+0xA7	0x0078	#	LATIN SMALL LETTER X
+0xA8	0x0079	#	LATIN SMALL LETTER Y
+0xA9	0x007A	#	LATIN SMALL LETTER Z
+0xAA	0x00A1	#
+0xAB	0x00BF	#
+0xAC	0x00D0	#
+0xAD	0x00DD	#
+0xAE	0x00DE	#
+0xAF	0x00AE	#
+0xB0	0x00A2	#
+0xB1	0x00A3	#
+0xB2	0x00A5	#
+0xB3	0x00B7	#
+0xB4	0x00A9	#
+0xB5	0x00A7	#
+0xB6	0x00B6	#
+0xB7	0x00BC	#
+0xB8	0x00BD	#
+0xB9	0x00BE	#
+0xBA	0x00AC	#
+0xBB	0x005B	#	LEFT SQUARE BRACKET
+0xBC	0x005C	#	REVERSE SOLIDUS
+0xBD	0x005D	#	RIGHT SQUARE BRACKET
+0xBE	0x00B4	#
+0xBF	0x00D7	#
+0xC0	0x00F9	#
+0xC1	0x0041	#	LATIN CAPITAL LETTER A
+0xC2	0x0042	#	LATIN CAPITAL LETTER B
+0xC3	0x0043	#	LATIN CAPITAL LETTER C
+0xC4	0x0044	#	LATIN CAPITAL LETTER D
+0xC5	0x0045	#	LATIN CAPITAL LETTER E
+0xC6	0x0046	#	LATIN CAPITAL LETTER F
+0xC7	0x0047	#	LATIN CAPITAL LETTER G
+0xC8	0x0048	#	LATIN CAPITAL LETTER H
+0xC9	0x0049	#	LATIN CAPITAL LETTER I
+0xCA	0x00AD	#
+0xCB	0x00F4	#
+0xCC	0x00F6	#
+0xCD	0x00F2	#
+0xCE	0x00F3	#
+0xCF	0x00F5	#
+0xD0	0x00A6	#
+0xD1	0x004A	#	LATIN CAPITAL LETTER J
+0xD2	0x004B	#	LATIN CAPITAL LETTER K
+0xD3	0x004C	#	LATIN CAPITAL LETTER L
+0xD4	0x004D	#	LATIN CAPITAL LETTER M
+0xD5	0x004E	#	LATIN CAPITAL LETTER N
+0xD6	0x004F	#	LATIN CAPITAL LETTER O
+0xD7	0x0050	#	LATIN CAPITAL LETTER P
+0xD8	0x0051	#	LATIN CAPITAL LETTER Q
+0xD9	0x0052	#	LATIN CAPITAL LETTER R
+0xDA	0x00B9	#
+0xDB	0x00FB	#
+0xDC	0x00FC	#
+0xDD	0x00DB	#
+0xDE	0x00FA	#
+0xDF	0x00FF	#
+0xE0	0x00D9	#
+0xE1	0x00F7	#
+0xE2	0x0053	#	LATIN CAPITAL LETTER S
+0xE3	0x0054	#	LATIN CAPITAL LETTER T
+0xE4	0x0055	#	LATIN CAPITAL LETTER U
+0xE5	0x0056	#	LATIN CAPITAL LETTER V
+0xE6	0x0057	#	LATIN CAPITAL LETTER W
+0xE7	0x0058	#	LATIN CAPITAL LETTER X
+0xE8	0x0059	#	LATIN CAPITAL LETTER Y
+0xE9	0x005A	#	LATIN CAPITAL LETTER Z
+0xEA	0x00B2	#
+0xEB	0x00D4	#
+0xEC	0x00D6	#
+0xED	0x00D2	#
+0xEE	0x00D3	#
+0xEF	0x00D5	#
+0xF0	0x0030	#	DIGIT ZERO
+0xF1	0x0031	#	DIGIT ONE
+0xF2	0x0032	#	DIGIT TWO
+0xF3	0x0033	#	DIGIT THREE
+0xF4	0x0034	#	DIGIT FOUR
+0xF5	0x0035	#	DIGIT FIVE
+0xF6	0x0036	#	DIGIT SIX
+0xF7	0x0037	#	DIGIT SEVEN
+0xF8	0x0038	#	DIGIT EIGHT
+0xF9	0x0039	#	DIGIT NINE
+0xFA	0x00B3	#
+0xFB	0x007B	#	LEFT CURLY BRACKET
+0xFC	0x00DC	#
+0xFD	0x007D	#	RIGHT CURLY BRACKET
+0xFE	0x00DA	#
+0xFF	0x007E	#	TILDE
+
diff --git a/tools/encoding/gb12345.txt b/tools/encoding/gb12345.txt
new file mode 100644
index 0000000..1e06637
--- /dev/null
+++ b/tools/encoding/gb12345.txt
@@ -0,0 +1,7604 @@
+#
+#	Name:             GB12345-80 to Unicode table (complete, hex format)
+#	Unicode version:  1.1
+#	Table version:    0.0d1
+#	Table format:     Format A
+#	Date:             6 December 1993
+#	Author:           Glenn Adams <glenn@metis.com>
+#                     John H. Jenkins <John_Jenkins@taligent.com>
+#
+#	Copyright (c) 1991-1994 Unicode, Inc.  All Rights reserved.
+#
+#	This file is provided as-is by Unicode, Inc. (The Unicode Consortium).
+#	No claims are made as to fitness for any particular purpose.  No
+#	warranties of any kind are expressed or implied.  The recipient
+#	agrees to determine applicability of information provided.  If this
+#	file has been provided on magnetic media by Unicode, Inc., the sole
+#	remedy for any claim will be exchange of defective media within 90
+#	days of receipt.
+#
+#	Recipient is granted the right to make copies in any form for
+#	internal distribution and to freely use the information supplied
+#	in the creation of products supporting Unicode.  Unicode, Inc.
+#	specifically excludes the right to re-distribute this file directly
+#	to third parties or other organizations whether for profit or not.
+#
+#	General notes:
+#
+#	This table contains the data Metis and Taligent currently have on how
+#       GB12345-90 characters map into Unicode.
+#
+#	Format:  Three tab-separated columns
+#		 Column #1 is the GB12345 code (in hex as 0xXXXX)
+#		 Column #2 is the Unicode (in hex as 0xXXXX)
+#		 Column #3 the Unicode name (follows a comment sign, '#')
+#					The official names for Unicode characters U+4E00
+#					to U+9FA5, inclusive, is "CJK UNIFIED IDEOGRAPH-XXXX",
+#					where XXXX is the code point.  Including all these
+#					names in this file increases its size substantially
+#					and needlessly.  The token "<CJK>" is used for the
+#					name of these characters.  If necessary, it can be
+#					expanded algorithmically by a parser or editor.
+#
+#	The entries are in GB12345 order
+#
+#	The following algorithms can be used to change the hex form
+#		of GB12345 to other standard forms:
+#
+#		To change hex to EUC form, add 0x8080
+#		To change hex to kuten form, first subtract 0x2020.  Then
+#			the high and low bytes correspond to the ku and ten of
+#			the kuten form.  For example, 0x2121 -> 0x0101 -> 0101;
+#			0x777E -> 0x575E -> 8794
+#
+#	Any comments or problems, contact <John_Jenkins@taligent.com>
+#
+#
+0x2121	0x3000	# IDEOGRAPHIC SPACE
+0x2122	0x3001	# IDEOGRAPHIC COMMA
+0x2123	0x3002	# IDEOGRAPHIC FULL STOP
+0x2124	0x30FB	# KATAKANA MIDDLE DOT
+0x2125	0x02C9	# MODIFIER LETTER MACRON (Mandarin Chinese first tone)
+0x2126	0x02C7	# CARON (Mandarin Chinese third tone)
+0x2127	0x00A8	# DIAERESIS
+0x2128	0x3003	# DITTO MARK
+0x2129	0x3005	# IDEOGRAPHIC ITERATION MARK
+0x212A	0x2015	# HORIZONTAL BAR
+0x212B	0xFF5E	# FULLWIDTH TILDE
+0x212C	0x2225	# PARALLEL TO
+0x212D	0x2026	# HORIZONTAL ELLIPSIS
+0x212E	0x2018	# LEFT SINGLE QUOTATION MARK
+0x212F	0x2019	# RIGHT SINGLE QUOTATION MARK
+0x2130	0x201C	# LEFT DOUBLE QUOTATION MARK
+0x2131	0x201D	# RIGHT DOUBLE QUOTATION MARK
+0x2132	0x3014	# LEFT TORTOISE SHELL BRACKET
+0x2133	0x3015	# RIGHT TORTOISE SHELL BRACKET
+0x2134	0x3008	# LEFT ANGLE BRACKET
+0x2135	0x3009	# RIGHT ANGLE BRACKET
+0x2136	0x300A	# LEFT DOUBLE ANGLE BRACKET
+0x2137	0x300B	# RIGHT DOUBLE ANGLE BRACKET
+0x2138	0x300C	# LEFT CORNER BRACKET
+0x2139	0x300D	# RIGHT CORNER BRACKET
+0x213A	0x300E	# LEFT WHITE CORNER BRACKET
+0x213B	0x300F	# RIGHT WHITE CORNER BRACKET
+0x213C	0x3016	# LEFT WHITE LENTICULAR BRACKET
+0x213D	0x3017	# RIGHT WHITE LENTICULAR BRACKET
+0x213E	0x3010	# LEFT BLACK LENTICULAR BRACKET
+0x213F	0x3011	# RIGHT BLACK LENTICULAR BRACKET
+0x2140	0x00B1	# PLUS-MINUS SIGN
+0x2141	0x00D7	# MULTIPLICATION SIGN
+0x2142	0x00F7	# DIVISION SIGN
+0x2143	0x2236	# RATIO
+0x2144	0x2227	# LOGICAL AND
+0x2145	0x2228	# LOGICAL OR
+0x2146	0x2211	# N-ARY SUMMATION
+0x2147	0x220F	# N-ARY PRODUCT
+0x2148	0x222A	# UNION
+0x2149	0x2229	# INTERSECTION
+0x214A	0x2208	# ELEMENT OF
+0x214B	0x2237	# PROPORTION
+0x214C	0x221A	# SQUARE ROOT
+0x214D	0x22A5	# UP TACK
+0x214E	0x2225	# PARALLEL TO
+0x214F	0x2220	# ANGLE
+0x2150	0x2312	# ARC
+0x2151	0x2299	# CIRCLED DOT OPERATOR
+0x2152	0x222B	# INTEGRAL
+0x2153	0x222E	# CONTOUR INTEGRAL
+0x2154	0x2261	# IDENTICAL TO
+0x2155	0x224C	# ALL EQUAL TO
+0x2156	0x2248	# ALMOST EQUAL TO
+0x2157	0x223D	# REVERSED TILDE
+0x2158	0x221D	# PROPORTIONAL TO
+0x2159	0x2260	# NOT EQUAL TO
+0x215A	0x226E	# NOT LESS-THAN
+0x215B	0x226F	# NOT GREATER-THAN
+0x215C	0x2264	# LESS-THAN OR EQUAL TO
+0x215D	0x2265	# GREATER-THAN OR EQUAL TO
+0x215E	0x221E	# INFINITY
+0x215F	0x2235	# BECAUSE
+0x2160	0x2234	# THEREFORE
+0x2161	0x2642	# MALE SIGN
+0x2162	0x2640	# FEMALE SIGN
+0x2163	0x00B0	# DEGREE SIGN
+0x2164	0x2032	# PRIME
+0x2165	0x2033	# DOUBLE PRIME
+0x2166	0x2103	# DEGREE CELSIUS
+0x2167	0xFF04	# FULLWIDTH DOLLAR SIGN
+0x2168	0x00A4	# CURRENCY SIGN
+0x2169	0xFFE0	# FULLWIDTH CENT SIGN
+0x216A	0xFFE1	# FULLWIDTH POUND SIGN
+0x216B	0x2030	# PER MILLE SIGN
+0x216C	0x00A7	# SECTION SIGN
+0x216D	0x2116	# NUMERO SIGN
+0x216E	0x2606	# WHITE STAR
+0x216F	0x2605	# BLACK STAR
+0x2170	0x25CB	# WHITE CIRCLE
+0x2171	0x25CF	# BLACK CIRCLE
+0x2172	0x25CE	# BULLSEYE
+0x2173	0x25C7	# WHITE DIAMOND
+0x2174	0x25C6	# BLACK DIAMOND
+0x2175	0x25A1	# WHITE SQUARE
+0x2176	0x25A0	# BLACK SQUARE
+0x2177	0x25B3	# WHITE UP-POINTING TRIANGLE
+0x2178	0x25B2	# BLACK UP-POINTING TRIANGLE
+0x2179	0x203B	# REFERENCE MARK
+0x217A	0x2192	# RIGHTWARDS ARROW
+0x217B	0x2190	# LEFTWARDS ARROW
+0x217C	0x2191	# UPWARDS ARROW
+0x217D	0x2193	# DOWNWARDS ARROW
+0x217E	0x3013	# GETA MARK
+0x2231	0x2488	# DIGIT ONE FULL STOP
+0x2232	0x2489	# DIGIT TWO FULL STOP
+0x2233	0x248A	# DIGIT THREE FULL STOP
+0x2234	0x248B	# DIGIT FOUR FULL STOP
+0x2235	0x248C	# DIGIT FIVE FULL STOP
+0x2236	0x248D	# DIGIT SIX FULL STOP
+0x2237	0x248E	# DIGIT SEVEN FULL STOP
+0x2238	0x248F	# DIGIT EIGHT FULL STOP
+0x2239	0x2490	# DIGIT NINE FULL STOP
+0x223A	0x2491	# NUMBER TEN FULL STOP
+0x223B	0x2492	# NUMBER ELEVEN FULL STOP
+0x223C	0x2493	# NUMBER TWELVE FULL STOP
+0x223D	0x2494	# NUMBER THIRTEEN FULL STOP
+0x223E	0x2495	# NUMBER FOURTEEN FULL STOP
+0x223F	0x2496	# NUMBER FIFTEEN FULL STOP
+0x2240	0x2497	# NUMBER SIXTEEN FULL STOP
+0x2241	0x2498	# NUMBER SEVENTEEN FULL STOP
+0x2242	0x2499	# NUMBER EIGHTEEN FULL STOP
+0x2243	0x249A	# NUMBER NINETEEN FULL STOP
+0x2244	0x249B	# NUMBER TWENTY FULL STOP
+0x2245	0x2474	# PARENTHESIZED DIGIT ONE
+0x2246	0x2475	# PARENTHESIZED DIGIT TWO
+0x2247	0x2476	# PARENTHESIZED DIGIT THREE
+0x2248	0x2477	# PARENTHESIZED DIGIT FOUR
+0x2249	0x2478	# PARENTHESIZED DIGIT FIVE
+0x224A	0x2479	# PARENTHESIZED DIGIT SIX
+0x224B	0x247A	# PARENTHESIZED DIGIT SEVEN
+0x224C	0x247B	# PARENTHESIZED DIGIT EIGHT
+0x224D	0x247C	# PARENTHESIZED DIGIT NINE
+0x224E	0x247D	# PARENTHESIZED NUMBER TEN
+0x224F	0x247E	# PARENTHESIZED NUMBER ELEVEN
+0x2250	0x247F	# PARENTHESIZED NUMBER TWELVE
+0x2251	0x2480	# PARENTHESIZED NUMBER THIRTEEN
+0x2252	0x2481	# PARENTHESIZED NUMBER FOURTEEN
+0x2253	0x2482	# PARENTHESIZED NUMBER FIFTEEN
+0x2254	0x2483	# PARENTHESIZED NUMBER SIXTEEN
+0x2255	0x2484	# PARENTHESIZED NUMBER SEVENTEEN
+0x2256	0x2485	# PARENTHESIZED NUMBER EIGHTEEN
+0x2257	0x2486	# PARENTHESIZED NUMBER NINETEEN
+0x2258	0x2487	# PARENTHESIZED NUMBER TWENTY
+0x2259	0x2460	# CIRCLED DIGIT ONE
+0x225A	0x2461	# CIRCLED DIGIT TWO
+0x225B	0x2462	# CIRCLED DIGIT THREE
+0x225C	0x2463	# CIRCLED DIGIT FOUR
+0x225D	0x2464	# CIRCLED DIGIT FIVE
+0x225E	0x2465	# CIRCLED DIGIT SIX
+0x225F	0x2466	# CIRCLED DIGIT SEVEN
+0x2260	0x2467	# CIRCLED DIGIT EIGHT
+0x2261	0x2468	# CIRCLED DIGIT NINE
+0x2262	0x2469	# CIRCLED NUMBER TEN
+0x2265	0x3220	# PARENTHESIZED IDEOGRAPH ONE
+0x2266	0x3221	# PARENTHESIZED IDEOGRAPH TWO
+0x2267	0x3222	# PARENTHESIZED IDEOGRAPH THREE
+0x2268	0x3223	# PARENTHESIZED IDEOGRAPH FOUR
+0x2269	0x3224	# PARENTHESIZED IDEOGRAPH FIVE
+0x226A	0x3225	# PARENTHESIZED IDEOGRAPH SIX
+0x226B	0x3226	# PARENTHESIZED IDEOGRAPH SEVEN
+0x226C	0x3227	# PARENTHESIZED IDEOGRAPH EIGHT
+0x226D	0x3228	# PARENTHESIZED IDEOGRAPH NINE
+0x226E	0x3229	# PARENTHESIZED IDEOGRAPH TEN
+0x2271	0x2160	# ROMAN NUMERAL ONE
+0x2272	0x2161	# ROMAN NUMERAL TWO
+0x2273	0x2162	# ROMAN NUMERAL THREE
+0x2274	0x2163	# ROMAN NUMERAL FOUR
+0x2275	0x2164	# ROMAN NUMERAL FIVE
+0x2276	0x2165	# ROMAN NUMERAL SIX
+0x2277	0x2166	# ROMAN NUMERAL SEVEN
+0x2278	0x2167	# ROMAN NUMERAL EIGHT
+0x2279	0x2168	# ROMAN NUMERAL NINE
+0x227A	0x2169	# ROMAN NUMERAL TEN
+0x227B	0x216A	# ROMAN NUMERAL ELEVEN
+0x227C	0x216B	# ROMAN NUMERAL TWELVE
+0x2321	0xFF01	# FULLWIDTH EXCLAMATION MARK
+0x2322	0xFF02	# FULLWIDTH QUOTATION MARK
+0x2323	0xFF03	# FULLWIDTH NUMBER SIGN
+0x2324	0xFFE5	# FULLWIDTH YEN SIGN
+0x2325	0xFF05	# FULLWIDTH PERCENT SIGN
+0x2326	0xFF06	# FULLWIDTH AMPERSAND
+0x2327	0xFF07	# FULLWIDTH APOSTROPHE
+0x2328	0xFF08	# FULLWIDTH LEFT PARENTHESIS
+0x2329	0xFF09	# FULLWIDTH RIGHT PARENTHESIS
+0x232A	0xFF0A	# FULLWIDTH ASTERISK
+0x232B	0xFF0B	# FULLWIDTH PLUS SIGN
+0x232C	0xFF0C	# FULLWIDTH COMMA
+0x232D	0xFF0D	# FULLWIDTH HYPHEN-MINUS
+0x232E	0xFF0E	# FULLWIDTH FULL STOP
+0x232F	0xFF0F	# FULLWIDTH SOLIDUS
+0x2330	0xFF10	# FULLWIDTH DIGIT ZERO
+0x2331	0xFF11	# FULLWIDTH DIGIT ONE
+0x2332	0xFF12	# FULLWIDTH DIGIT TWO
+0x2333	0xFF13	# FULLWIDTH DIGIT THREE
+0x2334	0xFF14	# FULLWIDTH DIGIT FOUR
+0x2335	0xFF15	# FULLWIDTH DIGIT FIVE
+0x2336	0xFF16	# FULLWIDTH DIGIT SIX
+0x2337	0xFF17	# FULLWIDTH DIGIT SEVEN
+0x2338	0xFF18	# FULLWIDTH DIGIT EIGHT
+0x2339	0xFF19	# FULLWIDTH DIGIT NINE
+0x233A	0xFF1A	# FULLWIDTH COLON
+0x233B	0xFF1B	# FULLWIDTH SEMICOLON
+0x233C	0xFF1C	# FULLWIDTH LESS-THAN SIGN
+0x233D	0xFF1D	# FULLWIDTH EQUALS SIGN
+0x233E	0xFF1E	# FULLWIDTH GREATER-THAN SIGN
+0x233F	0xFF1F	# FULLWIDTH QUESTION MARK
+0x2340	0xFF20	# FULLWIDTH COMMERCIAL AT
+0x2341	0xFF21	# FULLWIDTH LATIN CAPITAL LETTER A
+0x2342	0xFF22	# FULLWIDTH LATIN CAPITAL LETTER B
+0x2343	0xFF23	# FULLWIDTH LATIN CAPITAL LETTER C
+0x2344	0xFF24	# FULLWIDTH LATIN CAPITAL LETTER D
+0x2345	0xFF25	# FULLWIDTH LATIN CAPITAL LETTER E
+0x2346	0xFF26	# FULLWIDTH LATIN CAPITAL LETTER F
+0x2347	0xFF27	# FULLWIDTH LATIN CAPITAL LETTER G
+0x2348	0xFF28	# FULLWIDTH LATIN CAPITAL LETTER H
+0x2349	0xFF29	# FULLWIDTH LATIN CAPITAL LETTER I
+0x234A	0xFF2A	# FULLWIDTH LATIN CAPITAL LETTER J
+0x234B	0xFF2B	# FULLWIDTH LATIN CAPITAL LETTER K
+0x234C	0xFF2C	# FULLWIDTH LATIN CAPITAL LETTER L
+0x234D	0xFF2D	# FULLWIDTH LATIN CAPITAL LETTER M
+0x234E	0xFF2E	# FULLWIDTH LATIN CAPITAL LETTER N
+0x234F	0xFF2F	# FULLWIDTH LATIN CAPITAL LETTER O
+0x2350	0xFF30	# FULLWIDTH LATIN CAPITAL LETTER P
+0x2351	0xFF31	# FULLWIDTH LATIN CAPITAL LETTER Q
+0x2352	0xFF32	# FULLWIDTH LATIN CAPITAL LETTER R
+0x2353	0xFF33	# FULLWIDTH LATIN CAPITAL LETTER S
+0x2354	0xFF34	# FULLWIDTH LATIN CAPITAL LETTER T
+0x2355	0xFF35	# FULLWIDTH LATIN CAPITAL LETTER U
+0x2356	0xFF36	# FULLWIDTH LATIN CAPITAL LETTER V
+0x2357	0xFF37	# FULLWIDTH LATIN CAPITAL LETTER W
+0x2358	0xFF38	# FULLWIDTH LATIN CAPITAL LETTER X
+0x2359	0xFF39	# FULLWIDTH LATIN CAPITAL LETTER Y
+0x235A	0xFF3A	# FULLWIDTH LATIN CAPITAL LETTER Z
+0x235B	0xFF3B	# FULLWIDTH LEFT SQUARE BRACKET
+0x235C	0xFF3C	# FULLWIDTH REVERSE SOLIDUS
+0x235D	0xFF3D	# FULLWIDTH RIGHT SQUARE BRACKET
+0x235E	0xFF3E	# FULLWIDTH CIRCUMFLEX ACCENT
+0x235F	0xFF3F	# FULLWIDTH LOW LINE
+0x2360	0xFF40	# FULLWIDTH GRAVE ACCENT
+0x2361	0xFF41	# FULLWIDTH LATIN SMALL LETTER A
+0x2362	0xFF42	# FULLWIDTH LATIN SMALL LETTER B
+0x2363	0xFF43	# FULLWIDTH LATIN SMALL LETTER C
+0x2364	0xFF44	# FULLWIDTH LATIN SMALL LETTER D
+0x2365	0xFF45	# FULLWIDTH LATIN SMALL LETTER E
+0x2366	0xFF46	# FULLWIDTH LATIN SMALL LETTER F
+0x2367	0xFF47	# FULLWIDTH LATIN SMALL LETTER G
+0x2368	0xFF48	# FULLWIDTH LATIN SMALL LETTER H
+0x2369	0xFF49	# FULLWIDTH LATIN SMALL LETTER I
+0x236A	0xFF4A	# FULLWIDTH LATIN SMALL LETTER J
+0x236B	0xFF4B	# FULLWIDTH LATIN SMALL LETTER K
+0x236C	0xFF4C	# FULLWIDTH LATIN SMALL LETTER L
+0x236D	0xFF4D	# FULLWIDTH LATIN SMALL LETTER M
+0x236E	0xFF4E	# FULLWIDTH LATIN SMALL LETTER N
+0x236F	0xFF4F	# FULLWIDTH LATIN SMALL LETTER O
+0x2370	0xFF50	# FULLWIDTH LATIN SMALL LETTER P
+0x2371	0xFF51	# FULLWIDTH LATIN SMALL LETTER Q
+0x2372	0xFF52	# FULLWIDTH LATIN SMALL LETTER R
+0x2373	0xFF53	# FULLWIDTH LATIN SMALL LETTER S
+0x2374	0xFF54	# FULLWIDTH LATIN SMALL LETTER T
+0x2375	0xFF55	# FULLWIDTH LATIN SMALL LETTER U
+0x2376	0xFF56	# FULLWIDTH LATIN SMALL LETTER V
+0x2377	0xFF57	# FULLWIDTH LATIN SMALL LETTER W
+0x2378	0xFF58	# FULLWIDTH LATIN SMALL LETTER X
+0x2379	0xFF59	# FULLWIDTH LATIN SMALL LETTER Y
+0x237A	0xFF5A	# FULLWIDTH LATIN SMALL LETTER Z
+0x237B	0xFF5B	# FULLWIDTH LEFT CURLY BRACKET
+0x237C	0xFF5C	# FULLWIDTH VERTICAL LINE
+0x237D	0xFF5D	# FULLWIDTH RIGHT CURLY BRACKET
+0x237E	0xFFE3	# FULLWIDTH MACRON
+0x2421	0x3041	# HIRAGANA LETTER SMALL A
+0x2422	0x3042	# HIRAGANA LETTER A
+0x2423	0x3043	# HIRAGANA LETTER SMALL I
+0x2424	0x3044	# HIRAGANA LETTER I
+0x2425	0x3045	# HIRAGANA LETTER SMALL U
+0x2426	0x3046	# HIRAGANA LETTER U
+0x2427	0x3047	# HIRAGANA LETTER SMALL E
+0x2428	0x3048	# HIRAGANA LETTER E
+0x2429	0x3049	# HIRAGANA LETTER SMALL O
+0x242A	0x304A	# HIRAGANA LETTER O
+0x242B	0x304B	# HIRAGANA LETTER KA
+0x242C	0x304C	# HIRAGANA LETTER GA
+0x242D	0x304D	# HIRAGANA LETTER KI
+0x242E	0x304E	# HIRAGANA LETTER GI
+0x242F	0x304F	# HIRAGANA LETTER KU
+0x2430	0x3050	# HIRAGANA LETTER GU
+0x2431	0x3051	# HIRAGANA LETTER KE
+0x2432	0x3052	# HIRAGANA LETTER GE
+0x2433	0x3053	# HIRAGANA LETTER KO
+0x2434	0x3054	# HIRAGANA LETTER GO
+0x2435	0x3055	# HIRAGANA LETTER SA
+0x2436	0x3056	# HIRAGANA LETTER ZA
+0x2437	0x3057	# HIRAGANA LETTER SI
+0x2438	0x3058	# HIRAGANA LETTER ZI
+0x2439	0x3059	# HIRAGANA LETTER SU
+0x243A	0x305A	# HIRAGANA LETTER ZU
+0x243B	0x305B	# HIRAGANA LETTER SE
+0x243C	0x305C	# HIRAGANA LETTER ZE
+0x243D	0x305D	# HIRAGANA LETTER SO
+0x243E	0x305E	# HIRAGANA LETTER ZO
+0x243F	0x305F	# HIRAGANA LETTER TA
+0x2440	0x3060	# HIRAGANA LETTER DA
+0x2441	0x3061	# HIRAGANA LETTER TI
+0x2442	0x3062	# HIRAGANA LETTER DI
+0x2443	0x3063	# HIRAGANA LETTER SMALL TU
+0x2444	0x3064	# HIRAGANA LETTER TU
+0x2445	0x3065	# HIRAGANA LETTER DU
+0x2446	0x3066	# HIRAGANA LETTER TE
+0x2447	0x3067	# HIRAGANA LETTER DE
+0x2448	0x3068	# HIRAGANA LETTER TO
+0x2449	0x3069	# HIRAGANA LETTER DO
+0x244A	0x306A	# HIRAGANA LETTER NA
+0x244B	0x306B	# HIRAGANA LETTER NI
+0x244C	0x306C	# HIRAGANA LETTER NU
+0x244D	0x306D	# HIRAGANA LETTER NE
+0x244E	0x306E	# HIRAGANA LETTER NO
+0x244F	0x306F	# HIRAGANA LETTER HA
+0x2450	0x3070	# HIRAGANA LETTER BA
+0x2451	0x3071	# HIRAGANA LETTER PA
+0x2452	0x3072	# HIRAGANA LETTER HI
+0x2453	0x3073	# HIRAGANA LETTER BI
+0x2454	0x3074	# HIRAGANA LETTER PI
+0x2455	0x3075	# HIRAGANA LETTER HU
+0x2456	0x3076	# HIRAGANA LETTER BU
+0x2457	0x3077	# HIRAGANA LETTER PU
+0x2458	0x3078	# HIRAGANA LETTER HE
+0x2459	0x3079	# HIRAGANA LETTER BE
+0x245A	0x307A	# HIRAGANA LETTER PE
+0x245B	0x307B	# HIRAGANA LETTER HO
+0x245C	0x307C	# HIRAGANA LETTER BO
+0x245D	0x307D	# HIRAGANA LETTER PO
+0x245E	0x307E	# HIRAGANA LETTER MA
+0x245F	0x307F	# HIRAGANA LETTER MI
+0x2460	0x3080	# HIRAGANA LETTER MU
+0x2461	0x3081	# HIRAGANA LETTER ME
+0x2462	0x3082	# HIRAGANA LETTER MO
+0x2463	0x3083	# HIRAGANA LETTER SMALL YA
+0x2464	0x3084	# HIRAGANA LETTER YA
+0x2465	0x3085	# HIRAGANA LETTER SMALL YU
+0x2466	0x3086	# HIRAGANA LETTER YU
+0x2467	0x3087	# HIRAGANA LETTER SMALL YO
+0x2468	0x3088	# HIRAGANA LETTER YO
+0x2469	0x3089	# HIRAGANA LETTER RA
+0x246A	0x308A	# HIRAGANA LETTER RI
+0x246B	0x308B	# HIRAGANA LETTER RU
+0x246C	0x308C	# HIRAGANA LETTER RE
+0x246D	0x308D	# HIRAGANA LETTER RO
+0x246E	0x308E	# HIRAGANA LETTER SMALL WA
+0x246F	0x308F	# HIRAGANA LETTER WA
+0x2470	0x3090	# HIRAGANA LETTER WI
+0x2471	0x3091	# HIRAGANA LETTER WE
+0x2472	0x3092	# HIRAGANA LETTER WO
+0x2473	0x3093	# HIRAGANA LETTER N
+0x2521	0x30A1	# KATAKANA LETTER SMALL A
+0x2522	0x30A2	# KATAKANA LETTER A
+0x2523	0x30A3	# KATAKANA LETTER SMALL I
+0x2524	0x30A4	# KATAKANA LETTER I
+0x2525	0x30A5	# KATAKANA LETTER SMALL U
+0x2526	0x30A6	# KATAKANA LETTER U
+0x2527	0x30A7	# KATAKANA LETTER SMALL E
+0x2528	0x30A8	# KATAKANA LETTER E
+0x2529	0x30A9	# KATAKANA LETTER SMALL O
+0x252A	0x30AA	# KATAKANA LETTER O
+0x252B	0x30AB	# KATAKANA LETTER KA
+0x252C	0x30AC	# KATAKANA LETTER GA
+0x252D	0x30AD	# KATAKANA LETTER KI
+0x252E	0x30AE	# KATAKANA LETTER GI
+0x252F	0x30AF	# KATAKANA LETTER KU
+0x2530	0x30B0	# KATAKANA LETTER GU
+0x2531	0x30B1	# KATAKANA LETTER KE
+0x2532	0x30B2	# KATAKANA LETTER GE
+0x2533	0x30B3	# KATAKANA LETTER KO
+0x2534	0x30B4	# KATAKANA LETTER GO
+0x2535	0x30B5	# KATAKANA LETTER SA
+0x2536	0x30B6	# KATAKANA LETTER ZA
+0x2537	0x30B7	# KATAKANA LETTER SI
+0x2538	0x30B8	# KATAKANA LETTER ZI
+0x2539	0x30B9	# KATAKANA LETTER SU
+0x253A	0x30BA	# KATAKANA LETTER ZU
+0x253B	0x30BB	# KATAKANA LETTER SE
+0x253C	0x30BC	# KATAKANA LETTER ZE
+0x253D	0x30BD	# KATAKANA LETTER SO
+0x253E	0x30BE	# KATAKANA LETTER ZO
+0x253F	0x30BF	# KATAKANA LETTER TA
+0x2540	0x30C0	# KATAKANA LETTER DA
+0x2541	0x30C1	# KATAKANA LETTER TI
+0x2542	0x30C2	# KATAKANA LETTER DI
+0x2543	0x30C3	# KATAKANA LETTER SMALL TU
+0x2544	0x30C4	# KATAKANA LETTER TU
+0x2545	0x30C5	# KATAKANA LETTER DU
+0x2546	0x30C6	# KATAKANA LETTER TE
+0x2547	0x30C7	# KATAKANA LETTER DE
+0x2548	0x30C8	# KATAKANA LETTER TO
+0x2549	0x30C9	# KATAKANA LETTER DO
+0x254A	0x30CA	# KATAKANA LETTER NA
+0x254B	0x30CB	# KATAKANA LETTER NI
+0x254C	0x30CC	# KATAKANA LETTER NU
+0x254D	0x30CD	# KATAKANA LETTER NE
+0x254E	0x30CE	# KATAKANA LETTER NO
+0x254F	0x30CF	# KATAKANA LETTER HA
+0x2550	0x30D0	# KATAKANA LETTER BA
+0x2551	0x30D1	# KATAKANA LETTER PA
+0x2552	0x30D2	# KATAKANA LETTER HI
+0x2553	0x30D3	# KATAKANA LETTER BI
+0x2554	0x30D4	# KATAKANA LETTER PI
+0x2555	0x30D5	# KATAKANA LETTER HU
+0x2556	0x30D6	# KATAKANA LETTER BU
+0x2557	0x30D7	# KATAKANA LETTER PU
+0x2558	0x30D8	# KATAKANA LETTER HE
+0x2559	0x30D9	# KATAKANA LETTER BE
+0x255A	0x30DA	# KATAKANA LETTER PE
+0x255B	0x30DB	# KATAKANA LETTER HO
+0x255C	0x30DC	# KATAKANA LETTER BO
+0x255D	0x30DD	# KATAKANA LETTER PO
+0x255E	0x30DE	# KATAKANA LETTER MA
+0x255F	0x30DF	# KATAKANA LETTER MI
+0x2560	0x30E0	# KATAKANA LETTER MU
+0x2561	0x30E1	# KATAKANA LETTER ME
+0x2562	0x30E2	# KATAKANA LETTER MO
+0x2563	0x30E3	# KATAKANA LETTER SMALL YA
+0x2564	0x30E4	# KATAKANA LETTER YA
+0x2565	0x30E5	# KATAKANA LETTER SMALL YU
+0x2566	0x30E6	# KATAKANA LETTER YU
+0x2567	0x30E7	# KATAKANA LETTER SMALL YO
+0x2568	0x30E8	# KATAKANA LETTER YO
+0x2569	0x30E9	# KATAKANA LETTER RA
+0x256A	0x30EA	# KATAKANA LETTER RI
+0x256B	0x30EB	# KATAKANA LETTER RU
+0x256C	0x30EC	# KATAKANA LETTER RE
+0x256D	0x30ED	# KATAKANA LETTER RO
+0x256E	0x30EE	# KATAKANA LETTER SMALL WA
+0x256F	0x30EF	# KATAKANA LETTER WA
+0x2570	0x30F0	# KATAKANA LETTER WI
+0x2571	0x30F1	# KATAKANA LETTER WE
+0x2572	0x30F2	# KATAKANA LETTER WO
+0x2573	0x30F3	# KATAKANA LETTER N
+0x2574	0x30F4	# KATAKANA LETTER VU
+0x2575	0x30F5	# KATAKANA LETTER SMALL KA
+0x2576	0x30F6	# KATAKANA LETTER SMALL KE
+0x2621	0x0391	# GREEK CAPITAL LETTER ALPHA
+0x2622	0x0392	# GREEK CAPITAL LETTER BETA
+0x2623	0x0393	# GREEK CAPITAL LETTER GAMMA
+0x2624	0x0394	# GREEK CAPITAL LETTER DELTA
+0x2625	0x0395	# GREEK CAPITAL LETTER EPSILON
+0x2626	0x0396	# GREEK CAPITAL LETTER ZETA
+0x2627	0x0397	# GREEK CAPITAL LETTER ETA
+0x2628	0x0398	# GREEK CAPITAL LETTER THETA
+0x2629	0x0399	# GREEK CAPITAL LETTER IOTA
+0x262A	0x039A	# GREEK CAPITAL LETTER KAPPA
+0x262B	0x039B	# GREEK CAPITAL LETTER LAMDA
+0x262C	0x039C	# GREEK CAPITAL LETTER MU
+0x262D	0x039D	# GREEK CAPITAL LETTER NU
+0x262E	0x039E	# GREEK CAPITAL LETTER XI
+0x262F	0x039F	# GREEK CAPITAL LETTER OMICRON
+0x2630	0x03A0	# GREEK CAPITAL LETTER PI
+0x2631	0x03A1	# GREEK CAPITAL LETTER RHO
+0x2632	0x03A3	# GREEK CAPITAL LETTER SIGMA
+0x2633	0x03A4	# GREEK CAPITAL LETTER TAU
+0x2634	0x03A5	# GREEK CAPITAL LETTER UPSILON
+0x2635	0x03A6	# GREEK CAPITAL LETTER PHI
+0x2636	0x03A7	# GREEK CAPITAL LETTER CHI
+0x2637	0x03A8	# GREEK CAPITAL LETTER PSI
+0x2638	0x03A9	# GREEK CAPITAL LETTER OMEGA
+0x2641	0x03B1	# GREEK SMALL LETTER ALPHA
+0x2642	0x03B2	# GREEK SMALL LETTER BETA
+0x2643	0x03B3	# GREEK SMALL LETTER GAMMA
+0x2644	0x03B4	# GREEK SMALL LETTER DELTA
+0x2645	0x03B5	# GREEK SMALL LETTER EPSILON
+0x2646	0x03B6	# GREEK SMALL LETTER ZETA
+0x2647	0x03B7	# GREEK SMALL LETTER ETA
+0x2648	0x03B8	# GREEK SMALL LETTER THETA
+0x2649	0x03B9	# GREEK SMALL LETTER IOTA
+0x264A	0x03BA	# GREEK SMALL LETTER KAPPA
+0x264B	0x03BB	# GREEK SMALL LETTER LAMDA
+0x264C	0x03BC	# GREEK SMALL LETTER MU
+0x264D	0x03BD	# GREEK SMALL LETTER NU
+0x264E	0x03BE	# GREEK SMALL LETTER XI
+0x264F	0x03BF	# GREEK SMALL LETTER OMICRON
+0x2650	0x03C0	# GREEK SMALL LETTER PI
+0x2651	0x03C1	# GREEK SMALL LETTER RHO
+0x2652	0x03C3	# GREEK SMALL LETTER SIGMA
+0x2653	0x03C4	# GREEK SMALL LETTER TAU
+0x2654	0x03C5	# GREEK SMALL LETTER UPSILON
+0x2655	0x03C6	# GREEK SMALL LETTER PHI
+0x2656	0x03C7	# GREEK SMALL LETTER CHI
+0x2657	0x03C8	# GREEK SMALL LETTER PSI
+0x2658	0x03C9	# GREEK SMALL LETTER OMEGA
+0x2721	0x0410	# CYRILLIC CAPITAL LETTER A
+0x2722	0x0411	# CYRILLIC CAPITAL LETTER BE
+0x2723	0x0412	# CYRILLIC CAPITAL LETTER VE
+0x2724	0x0413	# CYRILLIC CAPITAL LETTER GHE
+0x2725	0x0414	# CYRILLIC CAPITAL LETTER DE
+0x2726	0x0415	# CYRILLIC CAPITAL LETTER IE
+0x2727	0x0401	# CYRILLIC CAPITAL LETTER IO
+0x2728	0x0416	# CYRILLIC CAPITAL LETTER ZHE
+0x2729	0x0417	# CYRILLIC CAPITAL LETTER ZE
+0x272A	0x0418	# CYRILLIC CAPITAL LETTER I
+0x272B	0x0419	# CYRILLIC CAPITAL LETTER SHORT I
+0x272C	0x041A	# CYRILLIC CAPITAL LETTER KA
+0x272D	0x041B	# CYRILLIC CAPITAL LETTER EL
+0x272E	0x041C	# CYRILLIC CAPITAL LETTER EM
+0x272F	0x041D	# CYRILLIC CAPITAL LETTER EN
+0x2730	0x041E	# CYRILLIC CAPITAL LETTER O
+0x2731	0x041F	# CYRILLIC CAPITAL LETTER PE
+0x2732	0x0420	# CYRILLIC CAPITAL LETTER ER
+0x2733	0x0421	# CYRILLIC CAPITAL LETTER ES
+0x2734	0x0422	# CYRILLIC CAPITAL LETTER TE
+0x2735	0x0423	# CYRILLIC CAPITAL LETTER U
+0x2736	0x0424	# CYRILLIC CAPITAL LETTER EF
+0x2737	0x0425	# CYRILLIC CAPITAL LETTER HA
+0x2738	0x0426	# CYRILLIC CAPITAL LETTER TSE
+0x2739	0x0427	# CYRILLIC CAPITAL LETTER CHE
+0x273A	0x0428	# CYRILLIC CAPITAL LETTER SHA
+0x273B	0x0429	# CYRILLIC CAPITAL LETTER SHCHA
+0x273C	0x042A	# CYRILLIC CAPITAL LETTER HARD SIGN
+0x273D	0x042B	# CYRILLIC CAPITAL LETTER YERU
+0x273E	0x042C	# CYRILLIC CAPITAL LETTER SOFT SIGN
+0x273F	0x042D	# CYRILLIC CAPITAL LETTER E
+0x2740	0x042E	# CYRILLIC CAPITAL LETTER YU
+0x2741	0x042F	# CYRILLIC CAPITAL LETTER YA
+0x2751	0x0430	# CYRILLIC SMALL LETTER A
+0x2752	0x0431	# CYRILLIC SMALL LETTER BE
+0x2753	0x0432	# CYRILLIC SMALL LETTER VE
+0x2754	0x0433	# CYRILLIC SMALL LETTER GHE
+0x2755	0x0434	# CYRILLIC SMALL LETTER DE
+0x2756	0x0435	# CYRILLIC SMALL LETTER IE
+0x2757	0x0451	# CYRILLIC SMALL LETTER IO
+0x2758	0x0436	# CYRILLIC SMALL LETTER ZHE
+0x2759	0x0437	# CYRILLIC SMALL LETTER ZE
+0x275A	0x0438	# CYRILLIC SMALL LETTER I
+0x275B	0x0439	# CYRILLIC SMALL LETTER SHORT I
+0x275C	0x043A	# CYRILLIC SMALL LETTER KA
+0x275D	0x043B	# CYRILLIC SMALL LETTER EL
+0x275E	0x043C	# CYRILLIC SMALL LETTER EM
+0x275F	0x043D	# CYRILLIC SMALL LETTER EN
+0x2760	0x043E	# CYRILLIC SMALL LETTER O
+0x2761	0x043F	# CYRILLIC SMALL LETTER PE
+0x2762	0x0440	# CYRILLIC SMALL LETTER ER
+0x2763	0x0441	# CYRILLIC SMALL LETTER ES
+0x2764	0x0442	# CYRILLIC SMALL LETTER TE
+0x2765	0x0443	# CYRILLIC SMALL LETTER U
+0x2766	0x0444	# CYRILLIC SMALL LETTER EF
+0x2767	0x0445	# CYRILLIC SMALL LETTER HA
+0x2768	0x0446	# CYRILLIC SMALL LETTER TSE
+0x2769	0x0447	# CYRILLIC SMALL LETTER CHE
+0x276A	0x0448	# CYRILLIC SMALL LETTER SHA
+0x276B	0x0449	# CYRILLIC SMALL LETTER SHCHA
+0x276C	0x044A	# CYRILLIC SMALL LETTER HARD SIGN
+0x276D	0x044B	# CYRILLIC SMALL LETTER YERU
+0x276E	0x044C	# CYRILLIC SMALL LETTER SOFT SIGN
+0x276F	0x044D	# CYRILLIC SMALL LETTER E
+0x2770	0x044E	# CYRILLIC SMALL LETTER YU
+0x2771	0x044F	# CYRILLIC SMALL LETTER YA
+0x2821	0x0101	# LATIN SMALL LETTER A WITH MACRON
+0x2822	0x00E1	# LATIN SMALL LETTER A WITH ACUTE
+0x2823	0x01CE	# LATIN SMALL LETTER A WITH CARON
+0x2824	0x00E0	# LATIN SMALL LETTER A WITH GRAVE
+0x2825	0x0113	# LATIN SMALL LETTER E WITH MACRON
+0x2826	0x00E9	# LATIN SMALL LETTER E WITH ACUTE
+0x2827	0x011B	# LATIN SMALL LETTER E WITH CARON
+0x2828	0x00E8	# LATIN SMALL LETTER E WITH GRAVE
+0x2829	0x012B	# LATIN SMALL LETTER I WITH MACRON
+0x282A	0x00ED	# LATIN SMALL LETTER I WITH ACUTE
+0x282B	0x01D0	# LATIN SMALL LETTER I WITH CARON
+0x282C	0x00EC	# LATIN SMALL LETTER I WITH GRAVE
+0x282D	0x014D	# LATIN SMALL LETTER O WITH MACRON
+0x282E	0x00F3	# LATIN SMALL LETTER O WITH ACUTE
+0x282F	0x01D2	# LATIN SMALL LETTER O WITH CARON
+0x2830	0x00F2	# LATIN SMALL LETTER O WITH GRAVE
+0x2831	0x016B	# LATIN SMALL LETTER U WITH MACRON
+0x2832	0x00FA	# LATIN SMALL LETTER U WITH ACUTE
+0x2833	0x01D4	# LATIN SMALL LETTER U WITH CARON
+0x2834	0x00F9	# LATIN SMALL LETTER U WITH GRAVE
+0x2835	0x01D6	# LATIN SMALL LETTER U WITH DIAERESIS AND MACRON
+0x2836	0x01D8	# LATIN SMALL LETTER U WITH DIAERESIS AND ACUTE
+0x2837	0x01DA	# LATIN SMALL LETTER U WITH DIAERESIS AND CARON
+0x2838	0x01DC	# LATIN SMALL LETTER U WITH DIAERESIS AND GRAVE
+0x2839	0x00FC	# LATIN SMALL LETTER U WITH DIAERESIS
+0x283A	0x00EA	# LATIN SMALL LETTER E WITH CIRCUMFLEX
+0x2845	0x3105	# BOPOMOFO LETTER B
+0x2846	0x3106	# BOPOMOFO LETTER P
+0x2847	0x3107	# BOPOMOFO LETTER M
+0x2848	0x3108	# BOPOMOFO LETTER F
+0x2849	0x3109	# BOPOMOFO LETTER D
+0x284A	0x310A	# BOPOMOFO LETTER T
+0x284B	0x310B	# BOPOMOFO LETTER N
+0x284C	0x310C	# BOPOMOFO LETTER L
+0x284D	0x310D	# BOPOMOFO LETTER G
+0x284E	0x310E	# BOPOMOFO LETTER K
+0x284F	0x310F	# BOPOMOFO LETTER H
+0x2850	0x3110	# BOPOMOFO LETTER J
+0x2851	0x3111	# BOPOMOFO LETTER Q
+0x2852	0x3112	# BOPOMOFO LETTER X
+0x2853	0x3113	# BOPOMOFO LETTER ZH
+0x2854	0x3114	# BOPOMOFO LETTER CH
+0x2855	0x3115	# BOPOMOFO LETTER SH
+0x2856	0x3116	# BOPOMOFO LETTER R
+0x2857	0x3117	# BOPOMOFO LETTER Z
+0x2858	0x3118	# BOPOMOFO LETTER C
+0x2859	0x3119	# BOPOMOFO LETTER S
+0x285A	0x311A	# BOPOMOFO LETTER A
+0x285B	0x311B	# BOPOMOFO LETTER O
+0x285C	0x311C	# BOPOMOFO LETTER E
+0x285D	0x311D	# BOPOMOFO LETTER EH
+0x285E	0x311E	# BOPOMOFO LETTER AI
+0x285F	0x311F	# BOPOMOFO LETTER EI
+0x2860	0x3120	# BOPOMOFO LETTER AU
+0x2861	0x3121	# BOPOMOFO LETTER OU
+0x2862	0x3122	# BOPOMOFO LETTER AN
+0x2863	0x3123	# BOPOMOFO LETTER EN
+0x2864	0x3124	# BOPOMOFO LETTER ANG
+0x2865	0x3125	# BOPOMOFO LETTER ENG
+0x2866	0x3126	# BOPOMOFO LETTER ER
+0x2867	0x3127	# BOPOMOFO LETTER I
+0x2868	0x3128	# BOPOMOFO LETTER U
+0x2869	0x3129	# BOPOMOFO LETTER IU
+0x2924	0x2500	# BOX DRAWINGS LIGHT HORIZONTAL
+0x2925	0x2501	# BOX DRAWINGS HEAVY HORIZONTAL
+0x2926	0x2502	# BOX DRAWINGS LIGHT VERTICAL
+0x2927	0x2503	# BOX DRAWINGS HEAVY VERTICAL
+0x2928	0x2504	# BOX DRAWINGS LIGHT TRIPLE DASH HORIZONTAL
+0x2929	0x2505	# BOX DRAWINGS HEAVY TRIPLE DASH HORIZONTAL
+0x292A	0x2506	# BOX DRAWINGS LIGHT TRIPLE DASH VERTICAL
+0x292B	0x2507	# BOX DRAWINGS HEAVY TRIPLE DASH VERTICAL
+0x292C	0x2508	# BOX DRAWINGS LIGHT QUADRUPLE DASH HORIZONTAL
+0x292D	0x2509	# BOX DRAWINGS HEAVY QUADRUPLE DASH HORIZONTAL
+0x292E	0x250A	# BOX DRAWINGS LIGHT QUADRUPLE DASH VERTICAL
+0x292F	0x250B	# BOX DRAWINGS HEAVY QUADRUPLE DASH VERTICAL
+0x2930	0x250C	# BOX DRAWINGS LIGHT DOWN AND RIGHT
+0x2931	0x250D	# BOX DRAWINGS DOWN LIGHT AND RIGHT HEAVY
+0x2932	0x250E	# BOX DRAWINGS DOWN HEAVY AND RIGHT LIGHT
+0x2933	0x250F	# BOX DRAWINGS HEAVY DOWN AND RIGHT
+0x2934	0x2510	# BOX DRAWINGS LIGHT DOWN AND LEFT
+0x2935	0x2511	# BOX DRAWINGS DOWN LIGHT AND LEFT HEAVY
+0x2936	0x2512	# BOX DRAWINGS DOWN HEAVY AND LEFT LIGHT
+0x2937	0x2513	# BOX DRAWINGS HEAVY DOWN AND LEFT
+0x2938	0x2514	# BOX DRAWINGS LIGHT UP AND RIGHT
+0x2939	0x2515	# BOX DRAWINGS UP LIGHT AND RIGHT HEAVY
+0x293A	0x2516	# BOX DRAWINGS UP HEAVY AND RIGHT LIGHT
+0x293B	0x2517	# BOX DRAWINGS HEAVY UP AND RIGHT
+0x293C	0x2518	# BOX DRAWINGS LIGHT UP AND LEFT
+0x293D	0x2519	# BOX DRAWINGS UP LIGHT AND LEFT HEAVY
+0x293E	0x251A	# BOX DRAWINGS UP HEAVY AND LEFT LIGHT
+0x293F	0x251B	# BOX DRAWINGS HEAVY UP AND LEFT
+0x2940	0x251C	# BOX DRAWINGS LIGHT VERTICAL AND RIGHT
+0x2941	0x251D	# BOX DRAWINGS VERTICAL LIGHT AND RIGHT HEAVY
+0x2942	0x251E	# BOX DRAWINGS UP HEAVY AND RIGHT DOWN LIGHT
+0x2943	0x251F	# BOX DRAWINGS DOWN HEAVY AND RIGHT UP LIGHT
+0x2944	0x2520	# BOX DRAWINGS VERTICAL HEAVY AND RIGHT LIGHT
+0x2945	0x2521	# BOX DRAWINGS DOWN LIGHT AND RIGHT UP HEAVY
+0x2946	0x2522	# BOX DRAWINGS UP LIGHT AND RIGHT DOWN HEAVY
+0x2947	0x2523	# BOX DRAWINGS HEAVY VERTICAL AND RIGHT
+0x2948	0x2524	# BOX DRAWINGS LIGHT VERTICAL AND LEFT
+0x2949	0x2525	# BOX DRAWINGS VERTICAL LIGHT AND LEFT HEAVY
+0x294A	0x2526	# BOX DRAWINGS UP HEAVY AND LEFT DOWN LIGHT
+0x294B	0x2527	# BOX DRAWINGS DOWN HEAVY AND LEFT UP LIGHT
+0x294C	0x2528	# BOX DRAWINGS VERTICAL HEAVY AND LEFT LIGHT
+0x294D	0x2529	# BOX DRAWINGS DOWN LIGHT AND LEFT UP HEAVY
+0x294E	0x252A	# BOX DRAWINGS UP LIGHT AND LEFT DOWN HEAVY
+0x294F	0x252B	# BOX DRAWINGS HEAVY VERTICAL AND LEFT
+0x2950	0x252C	# BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
+0x2951	0x252D	# BOX DRAWINGS LEFT HEAVY AND RIGHT DOWN LIGHT
+0x2952	0x252E	# BOX DRAWINGS RIGHT HEAVY AND LEFT DOWN LIGHT
+0x2953	0x252F	# BOX DRAWINGS DOWN LIGHT AND HORIZONTAL HEAVY
+0x2954	0x2530	# BOX DRAWINGS DOWN HEAVY AND HORIZONTAL LIGHT
+0x2955	0x2531	# BOX DRAWINGS RIGHT LIGHT AND LEFT DOWN HEAVY
+0x2956	0x2532	# BOX DRAWINGS LEFT LIGHT AND RIGHT DOWN HEAVY
+0x2957	0x2533	# BOX DRAWINGS HEAVY DOWN AND HORIZONTAL
+0x2958	0x2534	# BOX DRAWINGS LIGHT UP AND HORIZONTAL
+0x2959	0x2535	# BOX DRAWINGS LEFT HEAVY AND RIGHT UP LIGHT
+0x295A	0x2536	# BOX DRAWINGS RIGHT HEAVY AND LEFT UP LIGHT
+0x295B	0x2537	# BOX DRAWINGS UP LIGHT AND HORIZONTAL HEAVY
+0x295C	0x2538	# BOX DRAWINGS UP HEAVY AND HORIZONTAL LIGHT
+0x295D	0x2539	# BOX DRAWINGS RIGHT LIGHT AND LEFT UP HEAVY
+0x295E	0x253A	# BOX DRAWINGS LEFT LIGHT AND RIGHT UP HEAVY
+0x295F	0x253B	# BOX DRAWINGS HEAVY UP AND HORIZONTAL
+0x2960	0x253C	# BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
+0x2961	0x253D	# BOX DRAWINGS LEFT HEAVY AND RIGHT VERTICAL LIGHT
+0x2962	0x253E	# BOX DRAWINGS RIGHT HEAVY AND LEFT VERTICAL LIGHT
+0x2963	0x253F	# BOX DRAWINGS VERTICAL LIGHT AND HORIZONTAL HEAVY
+0x2964	0x2540	# BOX DRAWINGS UP HEAVY AND DOWN HORIZONTAL LIGHT
+0x2965	0x2541	# BOX DRAWINGS DOWN HEAVY AND UP HORIZONTAL LIGHT
+0x2966	0x2542	# BOX DRAWINGS VERTICAL HEAVY AND HORIZONTAL LIGHT
+0x2967	0x2543	# BOX DRAWINGS LEFT UP HEAVY AND RIGHT DOWN LIGHT
+0x2968	0x2544	# BOX DRAWINGS RIGHT UP HEAVY AND LEFT DOWN LIGHT
+0x2969	0x2545	# BOX DRAWINGS LEFT DOWN HEAVY AND RIGHT UP LIGHT
+0x296A	0x2546	# BOX DRAWINGS RIGHT DOWN HEAVY AND LEFT UP LIGHT
+0x296B	0x2547	# BOX DRAWINGS DOWN LIGHT AND UP HORIZONTAL HEAVY
+0x296C	0x2548	# BOX DRAWINGS UP LIGHT AND DOWN HORIZONTAL HEAVY
+0x296D	0x2549	# BOX DRAWINGS RIGHT LIGHT AND LEFT VERTICAL HEAVY
+0x296E	0x254A	# BOX DRAWINGS LEFT LIGHT AND RIGHT VERTICAL HEAVY
+0x296F	0x254B	# BOX DRAWINGS HEAVY VERTICAL AND HORIZONTAL
+0x3021	0x554A	# <CJK>
+0x3022	0x963F	# <CJK>
+0x3023	0x57C3	# <CJK>
+0x3024	0x6328	# <CJK>
+0x3025	0x54CE	# <CJK>
+0x3026	0x5509	# <CJK>
+0x3027	0x54C0	# <CJK>
+0x3028	0x769A	# <CJK>
+0x3029	0x764C	# <CJK>
+0x302A	0x85F9	# <CJK>
+0x302B	0x77EE	# <CJK>
+0x302C	0x827E	# <CJK>
+0x302D	0x7919	# <CJK>
+0x302E	0x611B	# <CJK>
+0x302F	0x9698	# <CJK>
+0x3030	0x978D	# <CJK>
+0x3031	0x6C28	# <CJK>
+0x3032	0x5B89	# <CJK>
+0x3033	0x4FFA	# <CJK>
+0x3034	0x6309	# <CJK>
+0x3035	0x6697	# <CJK>
+0x3036	0x5CB8	# <CJK>
+0x3037	0x80FA	# <CJK>
+0x3038	0x6848	# <CJK>
+0x3039	0x9AAF	# <CJK>
+0x303A	0x6602	# <CJK>
+0x303B	0x76CE	# <CJK>
+0x303C	0x51F9	# <CJK>
+0x303D	0x6556	# <CJK>
+0x303E	0x71AC	# <CJK>
+0x303F	0x7FF1	# <CJK>
+0x3040	0x8956	# <CJK>
+0x3041	0x50B2	# <CJK>
+0x3042	0x5965	# <CJK>
+0x3043	0x61CA	# <CJK>
+0x3044	0x6FB3	# <CJK>
+0x3045	0x82AD	# <CJK>
+0x3046	0x634C	# <CJK>
+0x3047	0x6252	# <CJK>
+0x3048	0x53ED	# <CJK>
+0x3049	0x5427	# <CJK>
+0x304A	0x7B06	# <CJK>
+0x304B	0x516B	# <CJK>
+0x304C	0x75A4	# <CJK>
+0x304D	0x5DF4	# <CJK>
+0x304E	0x62D4	# <CJK>
+0x304F	0x8DCB	# <CJK>
+0x3050	0x9776	# <CJK>
+0x3051	0x628A	# <CJK>
+0x3052	0x8019	# <CJK>
+0x3053	0x58E9	# <CJK>
+0x3054	0x9738	# <CJK>
+0x3055	0x7F77	# <CJK>
+0x3056	0x7238	# <CJK>
+0x3057	0x767D	# <CJK>
+0x3058	0x67CF	# <CJK>
+0x3059	0x767E	# <CJK>
+0x305A	0x64FA	# <CJK>
+0x305B	0x4F70	# <CJK>
+0x305C	0x6557	# <CJK>
+0x305D	0x62DC	# <CJK>
+0x305E	0x7A17	# <CJK>
+0x305F	0x6591	# <CJK>
+0x3060	0x73ED	# <CJK>
+0x3061	0x642C	# <CJK>
+0x3062	0x6273	# <CJK>
+0x3063	0x822C	# <CJK>
+0x3064	0x9812	# <CJK>
+0x3065	0x677F	# <CJK>
+0x3066	0x7248	# <CJK>
+0x3067	0x626E	# <CJK>
+0x3068	0x62CC	# <CJK>
+0x3069	0x4F34	# <CJK>
+0x306A	0x74E3	# <CJK>
+0x306B	0x534A	# <CJK>
+0x306C	0x8FA6	# <CJK>
+0x306D	0x7D46	# <CJK>
+0x306E	0x90A6	# <CJK>
+0x306F	0x5E6B	# <CJK>
+0x3070	0x6886	# <CJK>
+0x3071	0x699C	# <CJK>
+0x3072	0x8180	# <CJK>
+0x3073	0x7D81	# <CJK>
+0x3074	0x68D2	# <CJK>
+0x3075	0x78C5	# <CJK>
+0x3076	0x868C	# <CJK>
+0x3077	0x938A	# <CJK>
+0x3078	0x508D	# <CJK>
+0x3079	0x8B17	# <CJK>
+0x307A	0x82DE	# <CJK>
+0x307B	0x80DE	# <CJK>
+0x307C	0x5305	# <CJK>
+0x307D	0x8912	# <CJK>
+0x307E	0x5265	# <CJK>
+0x3121	0x8584	# <CJK>
+0x3122	0x96F9	# <CJK>
+0x3123	0x4FDD	# <CJK>
+0x3124	0x5821	# <CJK>
+0x3125	0x98FD	# <CJK>
+0x3126	0x5BF6	# <CJK>
+0x3127	0x62B1	# <CJK>
+0x3128	0x5831	# <CJK>
+0x3129	0x66B4	# <CJK>
+0x312A	0x8C79	# <CJK>
+0x312B	0x9B91	# <CJK>
+0x312C	0x7206	# <CJK>
+0x312D	0x676F	# <CJK>
+0x312E	0x7891	# <CJK>
+0x312F	0x60B2	# <CJK>
+0x3130	0x5351	# <CJK>
+0x3131	0x5317	# <CJK>
+0x3132	0x8F29	# <CJK>
+0x3133	0x80CC	# <CJK>
+0x3134	0x8C9D	# <CJK>
+0x3135	0x92C7	# <CJK>
+0x3136	0x500D	# <CJK>
+0x3137	0x72FD	# <CJK>
+0x3138	0x5099	# <CJK>
+0x3139	0x618A	# <CJK>
+0x313A	0x7119	# <CJK>
+0x313B	0x88AB	# <CJK>
+0x313C	0x5954	# <CJK>
+0x313D	0x82EF	# <CJK>
+0x313E	0x672C	# <CJK>
+0x313F	0x7B28	# <CJK>
+0x3140	0x5D29	# <CJK>
+0x3141	0x7DB3	# <CJK>
+0x3142	0x752D	# <CJK>
+0x3143	0x6CF5	# <CJK>
+0x3144	0x8E66	# <CJK>
+0x3145	0x8FF8	# <CJK>
+0x3146	0x903C	# <CJK>
+0x3147	0x9F3B	# <CJK>
+0x3148	0x6BD4	# <CJK>
+0x3149	0x9119	# <CJK>
+0x314A	0x7B46	# <CJK>
+0x314B	0x5F7C	# <CJK>
+0x314C	0x78A7	# <CJK>
+0x314D	0x84D6	# <CJK>
+0x314E	0x853D	# <CJK>
+0x314F	0x7562	# <CJK>
+0x3150	0x6583	# <CJK>
+0x3151	0x6BD6	# <CJK>
+0x3152	0x5E63	# <CJK>
+0x3153	0x5E87	# <CJK>
+0x3154	0x75F9	# <CJK>
+0x3155	0x9589	# <CJK>
+0x3156	0x655D	# <CJK>
+0x3157	0x5F0A	# <CJK>
+0x3158	0x5FC5	# <CJK>
+0x3159	0x8F9F	# <CJK>
+0x315A	0x58C1	# <CJK>
+0x315B	0x81C2	# <CJK>
+0x315C	0x907F	# <CJK>
+0x315D	0x965B	# <CJK>
+0x315E	0x97AD	# <CJK>
+0x315F	0x908A	# <CJK>
+0x3160	0x7DE8	# <CJK>
+0x3161	0x8CB6	# <CJK>
+0x3162	0x6241	# <CJK>
+0x3163	0x4FBF	# <CJK>
+0x3164	0x8B8A	# <CJK>
+0x3165	0x535E	# <CJK>
+0x3166	0x8FA8	# <CJK>
+0x3167	0x8FAF	# <CJK>
+0x3168	0x8FAE	# <CJK>
+0x3169	0x904D	# <CJK>
+0x316A	0x6A19	# <CJK>
+0x316B	0x5F6A	# <CJK>
+0x316C	0x8198	# <CJK>
+0x316D	0x8868	# <CJK>
+0x316E	0x9C49	# <CJK>
+0x316F	0x618B	# <CJK>
+0x3170	0x522B	# <CJK>
+0x3171	0x765F	# <CJK>
+0x3172	0x5F6C	# <CJK>
+0x3173	0x658C	# <CJK>
+0x3174	0x7015	# <CJK>
+0x3175	0x6FF1	# <CJK>
+0x3176	0x8CD3	# <CJK>
+0x3177	0x64EF	# <CJK>
+0x3178	0x5175	# <CJK>
+0x3179	0x51B0	# <CJK>
+0x317A	0x67C4	# <CJK>
+0x317B	0x4E19	# <CJK>
+0x317C	0x79C9	# <CJK>
+0x317D	0x9905	# <CJK>
+0x317E	0x70B3	# <CJK>
+0x3221	0x75C5	# <CJK>
+0x3222	0x5E76	# <CJK>
+0x3223	0x73BB	# <CJK>
+0x3224	0x83E0	# <CJK>
+0x3225	0x64AD	# <CJK>
+0x3226	0x64A5	# <CJK>
+0x3227	0x9262	# <CJK>
+0x3228	0x6CE2	# <CJK>
+0x3229	0x535A	# <CJK>
+0x322A	0x52C3	# <CJK>
+0x322B	0x640F	# <CJK>
+0x322C	0x9251	# <CJK>
+0x322D	0x7B94	# <CJK>
+0x322E	0x4F2F	# <CJK>
+0x322F	0x5E1B	# <CJK>
+0x3230	0x8236	# <CJK>
+0x3231	0x8116	# <CJK>
+0x3232	0x818A	# <CJK>
+0x3233	0x6E24	# <CJK>
+0x3234	0x6CCA	# <CJK>
+0x3235	0x99C1	# <CJK>
+0x3236	0x6355	# <CJK>
+0x3237	0x535C	# <CJK>
+0x3238	0x54FA	# <CJK>
+0x3239	0x88DC	# <CJK>
+0x323A	0x57E0	# <CJK>
+0x323B	0x4E0D	# <CJK>
+0x323C	0x5E03	# <CJK>
+0x323D	0x6B65	# <CJK>
+0x323E	0x7C3F	# <CJK>
+0x323F	0x90E8	# <CJK>
+0x3240	0x6016	# <CJK>
+0x3241	0x64E6	# <CJK>
+0x3242	0x731C	# <CJK>
+0x3243	0x88C1	# <CJK>
+0x3244	0x6750	# <CJK>
+0x3245	0x624D	# <CJK>
+0x3246	0x8CA1	# <CJK>
+0x3247	0x776C	# <CJK>
+0x3248	0x8E29	# <CJK>
+0x3249	0x91C7	# <CJK>
+0x324A	0x5F69	# <CJK>
+0x324B	0x83DC	# <CJK>
+0x324C	0x8521	# <CJK>
+0x324D	0x9910	# <CJK>
+0x324E	0x53C3	# <CJK>
+0x324F	0x8836	# <CJK>
+0x3250	0x6B98	# <CJK>
+0x3251	0x615A	# <CJK>
+0x3252	0x6158	# <CJK>
+0x3253	0x71E6	# <CJK>
+0x3254	0x84BC	# <CJK>
+0x3255	0x8259	# <CJK>
+0x3256	0x5009	# <CJK>
+0x3257	0x6EC4	# <CJK>
+0x3258	0x85CF	# <CJK>
+0x3259	0x64CD	# <CJK>
+0x325A	0x7CD9	# <CJK>
+0x325B	0x69FD	# <CJK>
+0x325C	0x66F9	# <CJK>
+0x325D	0x8349	# <CJK>
+0x325E	0x53A0	# <CJK>
+0x325F	0x7B56	# <CJK>
+0x3260	0x5074	# <CJK>
+0x3261	0x518C	# <CJK>
+0x3262	0x6E2C	# <CJK>
+0x3263	0x5C64	# <CJK>
+0x3264	0x8E6D	# <CJK>
+0x3265	0x63D2	# <CJK>
+0x3266	0x53C9	# <CJK>
+0x3267	0x832C	# <CJK>
+0x3268	0x8336	# <CJK>
+0x3269	0x67E5	# <CJK>
+0x326A	0x78B4	# <CJK>
+0x326B	0x643D	# <CJK>
+0x326C	0x5BDF	# <CJK>
+0x326D	0x5C94	# <CJK>
+0x326E	0x5DEE	# <CJK>
+0x326F	0x8A6B	# <CJK>
+0x3270	0x62C6	# <CJK>
+0x3271	0x67F4	# <CJK>
+0x3272	0x8C7A	# <CJK>
+0x3273	0x6519	# <CJK>
+0x3274	0x647B	# <CJK>
+0x3275	0x87EC	# <CJK>
+0x3276	0x995E	# <CJK>
+0x3277	0x8B92	# <CJK>
+0x3278	0x7E8F	# <CJK>
+0x3279	0x93DF	# <CJK>
+0x327A	0x7523	# <CJK>
+0x327B	0x95E1	# <CJK>
+0x327C	0x986B	# <CJK>
+0x327D	0x660C	# <CJK>
+0x327E	0x7316	# <CJK>
+0x3321	0x5834	# <CJK>
+0x3322	0x5617	# <CJK>
+0x3323	0x5E38	# <CJK>
+0x3324	0x9577	# <CJK>
+0x3325	0x511F	# <CJK>
+0x3326	0x8178	# <CJK>
+0x3327	0x5EE0	# <CJK>
+0x3328	0x655E	# <CJK>
+0x3329	0x66A2	# <CJK>
+0x332A	0x5531	# <CJK>
+0x332B	0x5021	# <CJK>
+0x332C	0x8D85	# <CJK>
+0x332D	0x6284	# <CJK>
+0x332E	0x9214	# <CJK>
+0x332F	0x671D	# <CJK>
+0x3330	0x5632	# <CJK>
+0x3331	0x6F6E	# <CJK>
+0x3332	0x5DE2	# <CJK>
+0x3333	0x5435	# <CJK>
+0x3334	0x7092	# <CJK>
+0x3335	0x8ECA	# <CJK>
+0x3336	0x626F	# <CJK>
+0x3337	0x64A4	# <CJK>
+0x3338	0x63A3	# <CJK>
+0x3339	0x5FB9	# <CJK>
+0x333A	0x6F88	# <CJK>
+0x333B	0x90F4	# <CJK>
+0x333C	0x81E3	# <CJK>
+0x333D	0x8FB0	# <CJK>
+0x333E	0x5875	# <CJK>
+0x333F	0x6668	# <CJK>
+0x3340	0x5FF1	# <CJK>
+0x3341	0x6C89	# <CJK>
+0x3342	0x9673	# <CJK>
+0x3343	0x8D81	# <CJK>
+0x3344	0x896F	# <CJK>
+0x3345	0x6491	# <CJK>
+0x3346	0x7A31	# <CJK>
+0x3347	0x57CE	# <CJK>
+0x3348	0x6A59	# <CJK>
+0x3349	0x6210	# <CJK>
+0x334A	0x5448	# <CJK>
+0x334B	0x4E58	# <CJK>
+0x334C	0x7A0B	# <CJK>
+0x334D	0x61F2	# <CJK>
+0x334E	0x6F84	# <CJK>
+0x334F	0x8AA0	# <CJK>
+0x3350	0x627F	# <CJK>
+0x3351	0x901E	# <CJK>
+0x3352	0x9A01	# <CJK>
+0x3353	0x79E4	# <CJK>
+0x3354	0x5403	# <CJK>
+0x3355	0x75F4	# <CJK>
+0x3356	0x6301	# <CJK>
+0x3357	0x5319	# <CJK>
+0x3358	0x6C60	# <CJK>
+0x3359	0x9072	# <CJK>
+0x335A	0x5F1B	# <CJK>
+0x335B	0x99B3	# <CJK>
+0x335C	0x803B	# <CJK>
+0x335D	0x9F52	# <CJK>
+0x335E	0x4F88	# <CJK>
+0x335F	0x5C3A	# <CJK>
+0x3360	0x8D64	# <CJK>
+0x3361	0x7FC5	# <CJK>
+0x3362	0x65A5	# <CJK>
+0x3363	0x71BE	# <CJK>
+0x3364	0x5145	# <CJK>
+0x3365	0x885D	# <CJK>
+0x3366	0x87F2	# <CJK>
+0x3367	0x5D07	# <CJK>
+0x3368	0x5BF5	# <CJK>
+0x3369	0x62BD	# <CJK>
+0x336A	0x916C	# <CJK>
+0x336B	0x7587	# <CJK>
+0x336C	0x8E8A	# <CJK>
+0x336D	0x7A20	# <CJK>
+0x336E	0x6101	# <CJK>
+0x336F	0x7C4C	# <CJK>
+0x3370	0x4EC7	# <CJK>
+0x3371	0x7DA2	# <CJK>
+0x3372	0x7785	# <CJK>
+0x3373	0x919C	# <CJK>
+0x3374	0x81ED	# <CJK>
+0x3375	0x521D	# <CJK>
+0x3376	0x51FA	# <CJK>
+0x3377	0x6A71	# <CJK>
+0x3378	0x53A8	# <CJK>
+0x3379	0x8E87	# <CJK>
+0x337A	0x92E4	# <CJK>
+0x337B	0x96DB	# <CJK>
+0x337C	0x6EC1	# <CJK>
+0x337D	0x9664	# <CJK>
+0x337E	0x695A	# <CJK>
+0x3421	0x790E	# <CJK>
+0x3422	0x5132	# <CJK>
+0x3423	0x77D7	# <CJK>
+0x3424	0x6410	# <CJK>
+0x3425	0x89F8	# <CJK>
+0x3426	0x8655	# <CJK>
+0x3427	0x63E3	# <CJK>
+0x3428	0x5DDD	# <CJK>
+0x3429	0x7A7F	# <CJK>
+0x342A	0x693D	# <CJK>
+0x342B	0x50B3	# <CJK>
+0x342C	0x8239	# <CJK>
+0x342D	0x5598	# <CJK>
+0x342E	0x4E32	# <CJK>
+0x342F	0x7621	# <CJK>
+0x3430	0x7A97	# <CJK>
+0x3431	0x5E62	# <CJK>
+0x3432	0x5E8A	# <CJK>
+0x3433	0x95D6	# <CJK>
+0x3434	0x5275	# <CJK>
+0x3435	0x5439	# <CJK>
+0x3436	0x708A	# <CJK>
+0x3437	0x6376	# <CJK>
+0x3438	0x9318	# <CJK>
+0x3439	0x5782	# <CJK>
+0x343A	0x6625	# <CJK>
+0x343B	0x693F	# <CJK>
+0x343C	0x9187	# <CJK>
+0x343D	0x5507	# <CJK>
+0x343E	0x6DF3	# <CJK>
+0x343F	0x7D14	# <CJK>
+0x3440	0x8822	# <CJK>
+0x3441	0x6233	# <CJK>
+0x3442	0x7DBD	# <CJK>
+0x3443	0x75B5	# <CJK>
+0x3444	0x8328	# <CJK>
+0x3445	0x78C1	# <CJK>
+0x3446	0x96CC	# <CJK>
+0x3447	0x8FAD	# <CJK>
+0x3448	0x6148	# <CJK>
+0x3449	0x74F7	# <CJK>
+0x344A	0x8A5E	# <CJK>
+0x344B	0x6B64	# <CJK>
+0x344C	0x523A	# <CJK>
+0x344D	0x8CDC	# <CJK>
+0x344E	0x6B21	# <CJK>
+0x344F	0x8070	# <CJK>
+0x3450	0x8471	# <CJK>
+0x3451	0x56F1	# <CJK>
+0x3452	0x5306	# <CJK>
+0x3453	0x5F9E	# <CJK>
+0x3454	0x53E2	# <CJK>
+0x3455	0x51D1	# <CJK>
+0x3456	0x7C97	# <CJK>
+0x3457	0x918B	# <CJK>
+0x3458	0x7C07	# <CJK>
+0x3459	0x4FC3	# <CJK>
+0x345A	0x8EA5	# <CJK>
+0x345B	0x7BE1	# <CJK>
+0x345C	0x7AC4	# <CJK>
+0x345D	0x6467	# <CJK>
+0x345E	0x5D14	# <CJK>
+0x345F	0x50AC	# <CJK>
+0x3460	0x8106	# <CJK>
+0x3461	0x7601	# <CJK>
+0x3462	0x7CB9	# <CJK>
+0x3463	0x6DEC	# <CJK>
+0x3464	0x7FE0	# <CJK>
+0x3465	0x6751	# <CJK>
+0x3466	0x5B58	# <CJK>
+0x3467	0x5BF8	# <CJK>
+0x3468	0x78CB	# <CJK>
+0x3469	0x64AE	# <CJK>
+0x346A	0x6413	# <CJK>
+0x346B	0x63AA	# <CJK>
+0x346C	0x632B	# <CJK>
+0x346D	0x932F	# <CJK>
+0x346E	0x642D	# <CJK>
+0x346F	0x9054	# <CJK>
+0x3470	0x7B54	# <CJK>
+0x3471	0x7629	# <CJK>
+0x3472	0x6253	# <CJK>
+0x3473	0x5927	# <CJK>
+0x3474	0x5446	# <CJK>
+0x3475	0x6B79	# <CJK>
+0x3476	0x50A3	# <CJK>
+0x3477	0x6234	# <CJK>
+0x3478	0x5E36	# <CJK>
+0x3479	0x6B86	# <CJK>
+0x347A	0x4EE3	# <CJK>
+0x347B	0x8CB8	# <CJK>
+0x347C	0x888B	# <CJK>
+0x347D	0x5F85	# <CJK>
+0x347E	0x902E	# <CJK>
+0x3521	0x6020	# <CJK>
+0x3522	0x803D	# <CJK>
+0x3523	0x64D4	# <CJK>
+0x3524	0x4E39	# <CJK>
+0x3525	0x55AE	# <CJK>
+0x3526	0x9132	# <CJK>
+0x3527	0x64A3	# <CJK>
+0x3528	0x81BD	# <CJK>
+0x3529	0x65E6	# <CJK>
+0x352A	0x6C2E	# <CJK>
+0x352B	0x4F46	# <CJK>
+0x352C	0x619A	# <CJK>
+0x352D	0x6DE1	# <CJK>
+0x352E	0x8A95	# <CJK>
+0x352F	0x5F48	# <CJK>
+0x3530	0x86CB	# <CJK>
+0x3531	0x7576	# <CJK>
+0x3532	0x64CB	# <CJK>
+0x3533	0x9EE8	# <CJK>
+0x3534	0x8569	# <CJK>
+0x3535	0x6A94	# <CJK>
+0x3536	0x5200	# <CJK>
+0x3537	0x6417	# <CJK>
+0x3538	0x8E48	# <CJK>
+0x3539	0x5012	# <CJK>
+0x353A	0x5CF6	# <CJK>
+0x353B	0x79B1	# <CJK>
+0x353C	0x5C0E	# <CJK>
+0x353D	0x5230	# <CJK>
+0x353E	0x7A3B	# <CJK>
+0x353F	0x60BC	# <CJK>
+0x3540	0x9053	# <CJK>
+0x3541	0x76D7	# <CJK>
+0x3542	0x5FB7	# <CJK>
+0x3543	0x5F97	# <CJK>
+0x3544	0x7684	# <CJK>
+0x3545	0x8E6C	# <CJK>
+0x3546	0x71C8	# <CJK>
+0x3547	0x767B	# <CJK>
+0x3548	0x7B49	# <CJK>
+0x3549	0x77AA	# <CJK>
+0x354A	0x51F3	# <CJK>
+0x354B	0x9127	# <CJK>
+0x354C	0x5824	# <CJK>
+0x354D	0x4F4E	# <CJK>
+0x354E	0x6EF4	# <CJK>
+0x354F	0x8FEA	# <CJK>
+0x3550	0x6575	# <CJK>
+0x3551	0x7B1B	# <CJK>
+0x3552	0x72C4	# <CJK>
+0x3553	0x6ECC	# <CJK>
+0x3554	0x7FDF	# <CJK>
+0x3555	0x5AE1	# <CJK>
+0x3556	0x62B5	# <CJK>
+0x3557	0x5E95	# <CJK>
+0x3558	0x5730	# <CJK>
+0x3559	0x8482	# <CJK>
+0x355A	0x7B2C	# <CJK>
+0x355B	0x5E1D	# <CJK>
+0x355C	0x5F1F	# <CJK>
+0x355D	0x905E	# <CJK>
+0x355E	0x7DE0	# <CJK>
+0x355F	0x985B	# <CJK>
+0x3560	0x6382	# <CJK>
+0x3561	0x6EC7	# <CJK>
+0x3562	0x7898	# <CJK>
+0x3563	0x9EDE	# <CJK>
+0x3564	0x5178	# <CJK>
+0x3565	0x975B	# <CJK>
+0x3566	0x588A	# <CJK>
+0x3567	0x96FB	# <CJK>
+0x3568	0x4F43	# <CJK>
+0x3569	0x7538	# <CJK>
+0x356A	0x5E97	# <CJK>
+0x356B	0x60E6	# <CJK>
+0x356C	0x5960	# <CJK>
+0x356D	0x6FB1	# <CJK>
+0x356E	0x6BBF	# <CJK>
+0x356F	0x7889	# <CJK>
+0x3570	0x53FC	# <CJK>
+0x3571	0x96D5	# <CJK>
+0x3572	0x51CB	# <CJK>
+0x3573	0x5201	# <CJK>
+0x3574	0x6389	# <CJK>
+0x3575	0x540A	# <CJK>
+0x3576	0x91E3	# <CJK>
+0x3577	0x8ABF	# <CJK>
+0x3578	0x8DCC	# <CJK>
+0x3579	0x7239	# <CJK>
+0x357A	0x789F	# <CJK>
+0x357B	0x8776	# <CJK>
+0x357C	0x8FED	# <CJK>
+0x357D	0x8ADC	# <CJK>
+0x357E	0x758A	# <CJK>
+0x3621	0x4E01	# <CJK>
+0x3622	0x76EF	# <CJK>
+0x3623	0x53EE	# <CJK>
+0x3624	0x91D8	# <CJK>
+0x3625	0x9802	# <CJK>
+0x3626	0x9F0E	# <CJK>
+0x3627	0x9320	# <CJK>
+0x3628	0x5B9A	# <CJK>
+0x3629	0x8A02	# <CJK>
+0x362A	0x4E22	# <CJK>
+0x362B	0x6771	# <CJK>
+0x362C	0x51AC	# <CJK>
+0x362D	0x8463	# <CJK>
+0x362E	0x61C2	# <CJK>
+0x362F	0x52D5	# <CJK>
+0x3630	0x68DF	# <CJK>
+0x3631	0x4F97	# <CJK>
+0x3632	0x606B	# <CJK>
+0x3633	0x51CD	# <CJK>
+0x3634	0x6D1E	# <CJK>
+0x3635	0x515C	# <CJK>
+0x3636	0x6296	# <CJK>
+0x3637	0x9B25	# <CJK>
+0x3638	0x9661	# <CJK>
+0x3639	0x8C46	# <CJK>
+0x363A	0x9017	# <CJK>
+0x363B	0x75D8	# <CJK>
+0x363C	0x90FD	# <CJK>
+0x363D	0x7763	# <CJK>
+0x363E	0x6BD2	# <CJK>
+0x363F	0x72A2	# <CJK>
+0x3640	0x7368	# <CJK>
+0x3641	0x8B80	# <CJK>
+0x3642	0x5835	# <CJK>
+0x3643	0x7779	# <CJK>
+0x3644	0x8CED	# <CJK>
+0x3645	0x675C	# <CJK>
+0x3646	0x934D	# <CJK>
+0x3647	0x809A	# <CJK>
+0x3648	0x5EA6	# <CJK>
+0x3649	0x6E21	# <CJK>
+0x364A	0x5992	# <CJK>
+0x364B	0x7AEF	# <CJK>
+0x364C	0x77ED	# <CJK>
+0x364D	0x935B	# <CJK>
+0x364E	0x6BB5	# <CJK>
+0x364F	0x65B7	# <CJK>
+0x3650	0x7DDE	# <CJK>
+0x3651	0x5806	# <CJK>
+0x3652	0x5151	# <CJK>
+0x3653	0x968A	# <CJK>
+0x3654	0x5C0D	# <CJK>
+0x3655	0x58A9	# <CJK>
+0x3656	0x5678	# <CJK>
+0x3657	0x8E72	# <CJK>
+0x3658	0x6566	# <CJK>
+0x3659	0x9813	# <CJK>
+0x365A	0x56E4	# <CJK>
+0x365B	0x920D	# <CJK>
+0x365C	0x76FE	# <CJK>
+0x365D	0x9041	# <CJK>
+0x365E	0x6387	# <CJK>
+0x365F	0x54C6	# <CJK>
+0x3660	0x591A	# <CJK>
+0x3661	0x596A	# <CJK>
+0x3662	0x579B	# <CJK>
+0x3663	0x8EB2	# <CJK>
+0x3664	0x6735	# <CJK>
+0x3665	0x8DFA	# <CJK>
+0x3666	0x8235	# <CJK>
+0x3667	0x5241	# <CJK>
+0x3668	0x60F0	# <CJK>
+0x3669	0x58AE	# <CJK>
+0x366A	0x86FE	# <CJK>
+0x366B	0x5CE8	# <CJK>
+0x366C	0x9D5D	# <CJK>
+0x366D	0x4FC4	# <CJK>
+0x366E	0x984D	# <CJK>
+0x366F	0x8A1B	# <CJK>
+0x3670	0x5A25	# <CJK>
+0x3671	0x60E1	# <CJK>
+0x3672	0x5384	# <CJK>
+0x3673	0x627C	# <CJK>
+0x3674	0x904F	# <CJK>
+0x3675	0x9102	# <CJK>
+0x3676	0x9913	# <CJK>
+0x3677	0x6069	# <CJK>
+0x3678	0x800C	# <CJK>
+0x3679	0x5152	# <CJK>
+0x367A	0x8033	# <CJK>
+0x367B	0x723E	# <CJK>
+0x367C	0x990C	# <CJK>
+0x367D	0x6D31	# <CJK>
+0x367E	0x4E8C	# <CJK>
+0x3721	0x8CB3	# <CJK>
+0x3722	0x767C	# <CJK>
+0x3723	0x7F70	# <CJK>
+0x3724	0x7B4F	# <CJK>
+0x3725	0x4F10	# <CJK>
+0x3726	0x4E4F	# <CJK>
+0x3727	0x95A5	# <CJK>
+0x3728	0x6CD5	# <CJK>
+0x3729	0x73D0	# <CJK>
+0x372A	0x85E9	# <CJK>
+0x372B	0x5E06	# <CJK>
+0x372C	0x756A	# <CJK>
+0x372D	0x7FFB	# <CJK>
+0x372E	0x6A0A	# <CJK>
+0x372F	0x792C	# <CJK>
+0x3730	0x91E9	# <CJK>
+0x3731	0x7E41	# <CJK>
+0x3732	0x51E1	# <CJK>
+0x3733	0x7169	# <CJK>
+0x3734	0x53CD	# <CJK>
+0x3735	0x8FD4	# <CJK>
+0x3736	0x7BC4	# <CJK>
+0x3737	0x8CA9	# <CJK>
+0x3738	0x72AF	# <CJK>
+0x3739	0x98EF	# <CJK>
+0x373A	0x6CDB	# <CJK>
+0x373B	0x574A	# <CJK>
+0x373C	0x82B3	# <CJK>
+0x373D	0x65B9	# <CJK>
+0x373E	0x80AA	# <CJK>
+0x373F	0x623F	# <CJK>
+0x3740	0x9632	# <CJK>
+0x3741	0x59A8	# <CJK>
+0x3742	0x4EFF	# <CJK>
+0x3743	0x8A2A	# <CJK>
+0x3744	0x7D21	# <CJK>
+0x3745	0x653E	# <CJK>
+0x3746	0x83F2	# <CJK>
+0x3747	0x975E	# <CJK>
+0x3748	0x5561	# <CJK>
+0x3749	0x98DB	# <CJK>
+0x374A	0x80A5	# <CJK>
+0x374B	0x532A	# <CJK>
+0x374C	0x8AB9	# <CJK>
+0x374D	0x5420	# <CJK>
+0x374E	0x80BA	# <CJK>
+0x374F	0x5EE2	# <CJK>
+0x3750	0x6CB8	# <CJK>
+0x3751	0x8CBB	# <CJK>
+0x3752	0x82AC	# <CJK>
+0x3753	0x915A	# <CJK>
+0x3754	0x5429	# <CJK>
+0x3755	0x6C1B	# <CJK>
+0x3756	0x5206	# <CJK>
+0x3757	0x7D1B	# <CJK>
+0x3758	0x58B3	# <CJK>
+0x3759	0x711A	# <CJK>
+0x375A	0x6C7E	# <CJK>
+0x375B	0x7C89	# <CJK>
+0x375C	0x596E	# <CJK>
+0x375D	0x4EFD	# <CJK>
+0x375E	0x5FFF	# <CJK>
+0x375F	0x61A4	# <CJK>
+0x3760	0x7CDE	# <CJK>
+0x3761	0x8C50	# <CJK>
+0x3762	0x5C01	# <CJK>
+0x3763	0x6953	# <CJK>
+0x3764	0x8702	# <CJK>
+0x3765	0x5CF0	# <CJK>
+0x3766	0x92D2	# <CJK>
+0x3767	0x98A8	# <CJK>
+0x3768	0x760B	# <CJK>
+0x3769	0x70FD	# <CJK>
+0x376A	0x9022	# <CJK>
+0x376B	0x99AE	# <CJK>
+0x376C	0x7E2B	# <CJK>
+0x376D	0x8AF7	# <CJK>
+0x376E	0x5949	# <CJK>
+0x376F	0x9CF3	# <CJK>
+0x3770	0x4F5B	# <CJK>
+0x3771	0x5426	# <CJK>
+0x3772	0x592B	# <CJK>
+0x3773	0x6577	# <CJK>
+0x3774	0x819A	# <CJK>
+0x3775	0x5B75	# <CJK>
+0x3776	0x6276	# <CJK>
+0x3777	0x62C2	# <CJK>
+0x3778	0x8F3B	# <CJK>
+0x3779	0x5E45	# <CJK>
+0x377A	0x6C1F	# <CJK>
+0x377B	0x7B26	# <CJK>
+0x377C	0x4F0F	# <CJK>
+0x377D	0x4FD8	# <CJK>
+0x377E	0x670D	# <CJK>
+0x3821	0x6D6E	# <CJK>
+0x3822	0x6DAA	# <CJK>
+0x3823	0x798F	# <CJK>
+0x3824	0x88B1	# <CJK>
+0x3825	0x5F17	# <CJK>
+0x3826	0x752B	# <CJK>
+0x3827	0x64AB	# <CJK>
+0x3828	0x8F14	# <CJK>
+0x3829	0x4FEF	# <CJK>
+0x382A	0x91DC	# <CJK>
+0x382B	0x65A7	# <CJK>
+0x382C	0x812F	# <CJK>
+0x382D	0x8151	# <CJK>
+0x382E	0x5E9C	# <CJK>
+0x382F	0x8150	# <CJK>
+0x3830	0x8D74	# <CJK>
+0x3831	0x526F	# <CJK>
+0x3832	0x8986	# <CJK>
+0x3833	0x8CE6	# <CJK>
+0x3834	0x5FA9	# <CJK>
+0x3835	0x5085	# <CJK>
+0x3836	0x4ED8	# <CJK>
+0x3837	0x961C	# <CJK>
+0x3838	0x7236	# <CJK>
+0x3839	0x8179	# <CJK>
+0x383A	0x8CA0	# <CJK>
+0x383B	0x5BCC	# <CJK>
+0x383C	0x8A03	# <CJK>
+0x383D	0x9644	# <CJK>
+0x383E	0x5A66	# <CJK>
+0x383F	0x7E1B	# <CJK>
+0x3840	0x5490	# <CJK>
+0x3841	0x5676	# <CJK>
+0x3842	0x560E	# <CJK>
+0x3843	0x8A72	# <CJK>
+0x3844	0x6539	# <CJK>
+0x3845	0x6982	# <CJK>
+0x3846	0x9223	# <CJK>
+0x3847	0x84CB	# <CJK>
+0x3848	0x6E89	# <CJK>
+0x3849	0x5E79	# <CJK>
+0x384A	0x7518	# <CJK>
+0x384B	0x6746	# <CJK>
+0x384C	0x67D1	# <CJK>
+0x384D	0x7AFF	# <CJK>
+0x384E	0x809D	# <CJK>
+0x384F	0x8D95	# <CJK>
+0x3850	0x611F	# <CJK>
+0x3851	0x79C6	# <CJK>
+0x3852	0x6562	# <CJK>
+0x3853	0x8D1B	# <CJK>
+0x3854	0x5CA1	# <CJK>
+0x3855	0x525B	# <CJK>
+0x3856	0x92FC	# <CJK>
+0x3857	0x7F38	# <CJK>
+0x3858	0x809B	# <CJK>
+0x3859	0x7DB1	# <CJK>
+0x385A	0x5D17	# <CJK>
+0x385B	0x6E2F	# <CJK>
+0x385C	0x6760	# <CJK>
+0x385D	0x7BD9	# <CJK>
+0x385E	0x768B	# <CJK>
+0x385F	0x9AD8	# <CJK>
+0x3860	0x818F	# <CJK>
+0x3861	0x7F94	# <CJK>
+0x3862	0x7CD5	# <CJK>
+0x3863	0x641E	# <CJK>
+0x3864	0x93AC	# <CJK>
+0x3865	0x7A3F	# <CJK>
+0x3866	0x544A	# <CJK>
+0x3867	0x54E5	# <CJK>
+0x3868	0x6B4C	# <CJK>
+0x3869	0x64F1	# <CJK>
+0x386A	0x6208	# <CJK>
+0x386B	0x9D3F	# <CJK>
+0x386C	0x80F3	# <CJK>
+0x386D	0x7599	# <CJK>
+0x386E	0x5272	# <CJK>
+0x386F	0x9769	# <CJK>
+0x3870	0x845B	# <CJK>
+0x3871	0x683C	# <CJK>
+0x3872	0x86E4	# <CJK>
+0x3873	0x95A3	# <CJK>
+0x3874	0x9694	# <CJK>
+0x3875	0x927B	# <CJK>
+0x3876	0x500B	# <CJK>
+0x3877	0x5404	# <CJK>
+0x3878	0x7D66	# <CJK>
+0x3879	0x6839	# <CJK>
+0x387A	0x8DDF	# <CJK>
+0x387B	0x8015	# <CJK>
+0x387C	0x66F4	# <CJK>
+0x387D	0x5E9A	# <CJK>
+0x387E	0x7FB9	# <CJK>
+0x3921	0x57C2	# <CJK>
+0x3922	0x803F	# <CJK>
+0x3923	0x6897	# <CJK>
+0x3924	0x5DE5	# <CJK>
+0x3925	0x653B	# <CJK>
+0x3926	0x529F	# <CJK>
+0x3927	0x606D	# <CJK>
+0x3928	0x9F94	# <CJK>
+0x3929	0x4F9B	# <CJK>
+0x392A	0x8EAC	# <CJK>
+0x392B	0x516C	# <CJK>
+0x392C	0x5BAB	# <CJK>
+0x392D	0x5F13	# <CJK>
+0x392E	0x978F	# <CJK>
+0x392F	0x6C5E	# <CJK>
+0x3930	0x62F1	# <CJK>
+0x3931	0x8CA2	# <CJK>
+0x3932	0x5171	# <CJK>
+0x3933	0x920E	# <CJK>
+0x3934	0x52FE	# <CJK>
+0x3935	0x6E9D	# <CJK>
+0x3936	0x82DF	# <CJK>
+0x3937	0x72D7	# <CJK>
+0x3938	0x57A2	# <CJK>
+0x3939	0x69CB	# <CJK>
+0x393A	0x8CFC	# <CJK>
+0x393B	0x591F	# <CJK>
+0x393C	0x8F9C	# <CJK>
+0x393D	0x83C7	# <CJK>
+0x393E	0x5495	# <CJK>
+0x393F	0x7B8D	# <CJK>
+0x3940	0x4F30	# <CJK>
+0x3941	0x6CBD	# <CJK>
+0x3942	0x5B64	# <CJK>
+0x3943	0x59D1	# <CJK>
+0x3944	0x9F13	# <CJK>
+0x3945	0x53E4	# <CJK>
+0x3946	0x8831	# <CJK>
+0x3947	0x9AA8	# <CJK>
+0x3948	0x8C37	# <CJK>
+0x3949	0x80A1	# <CJK>
+0x394A	0x6545	# <CJK>
+0x394B	0x9867	# <CJK>
+0x394C	0x56FA	# <CJK>
+0x394D	0x96C7	# <CJK>
+0x394E	0x522E	# <CJK>
+0x394F	0x74DC	# <CJK>
+0x3950	0x526E	# <CJK>
+0x3951	0x5BE1	# <CJK>
+0x3952	0x6302	# <CJK>
+0x3953	0x8902	# <CJK>
+0x3954	0x4E56	# <CJK>
+0x3955	0x62D0	# <CJK>
+0x3956	0x602A	# <CJK>
+0x3957	0x68FA	# <CJK>
+0x3958	0x95DC	# <CJK>
+0x3959	0x5B98	# <CJK>
+0x395A	0x51A0	# <CJK>
+0x395B	0x89C0	# <CJK>
+0x395C	0x7BA1	# <CJK>
+0x395D	0x9928	# <CJK>
+0x395E	0x7F50	# <CJK>
+0x395F	0x6163	# <CJK>
+0x3960	0x704C	# <CJK>
+0x3961	0x8CAB	# <CJK>
+0x3962	0x5149	# <CJK>
+0x3963	0x5EE3	# <CJK>
+0x3964	0x901B	# <CJK>
+0x3965	0x7470	# <CJK>
+0x3966	0x898F	# <CJK>
+0x3967	0x572D	# <CJK>
+0x3968	0x7845	# <CJK>
+0x3969	0x6B78	# <CJK>
+0x396A	0x9F9C	# <CJK>
+0x396B	0x95A8	# <CJK>
+0x396C	0x8ECC	# <CJK>
+0x396D	0x9B3C	# <CJK>
+0x396E	0x8A6D	# <CJK>
+0x396F	0x7678	# <CJK>
+0x3970	0x6842	# <CJK>
+0x3971	0x6AC3	# <CJK>
+0x3972	0x8DEA	# <CJK>
+0x3973	0x8CB4	# <CJK>
+0x3974	0x528A	# <CJK>
+0x3975	0x8F25	# <CJK>
+0x3976	0x6EDA	# <CJK>
+0x3977	0x68CD	# <CJK>
+0x3978	0x934B	# <CJK>
+0x3979	0x90ED	# <CJK>
+0x397A	0x570B	# <CJK>
+0x397B	0x679C	# <CJK>
+0x397C	0x88F9	# <CJK>
+0x397D	0x904E	# <CJK>
+0x397E	0x54C8	# <CJK>
+0x3A21	0x9AB8	# <CJK>
+0x3A22	0x5B69	# <CJK>
+0x3A23	0x6D77	# <CJK>
+0x3A24	0x6C26	# <CJK>
+0x3A25	0x4EA5	# <CJK>
+0x3A26	0x5BB3	# <CJK>
+0x3A27	0x99ED	# <CJK>
+0x3A28	0x9163	# <CJK>
+0x3A29	0x61A8	# <CJK>
+0x3A2A	0x90AF	# <CJK>
+0x3A2B	0x97D3	# <CJK>
+0x3A2C	0x542B	# <CJK>
+0x3A2D	0x6DB5	# <CJK>
+0x3A2E	0x5BD2	# <CJK>
+0x3A2F	0x51FD	# <CJK>
+0x3A30	0x558A	# <CJK>
+0x3A31	0x7F55	# <CJK>
+0x3A32	0x7FF0	# <CJK>
+0x3A33	0x64BC	# <CJK>
+0x3A34	0x634D	# <CJK>
+0x3A35	0x65F1	# <CJK>
+0x3A36	0x61BE	# <CJK>
+0x3A37	0x608D	# <CJK>
+0x3A38	0x710A	# <CJK>
+0x3A39	0x6C57	# <CJK>
+0x3A3A	0x6F22	# <CJK>
+0x3A3B	0x592F	# <CJK>
+0x3A3C	0x676D	# <CJK>
+0x3A3D	0x822A	# <CJK>
+0x3A3E	0x58D5	# <CJK>
+0x3A3F	0x568E	# <CJK>
+0x3A40	0x8C6A	# <CJK>
+0x3A41	0x6BEB	# <CJK>
+0x3A42	0x90DD	# <CJK>
+0x3A43	0x597D	# <CJK>
+0x3A44	0x8017	# <CJK>
+0x3A45	0x865F	# <CJK>
+0x3A46	0x6D69	# <CJK>
+0x3A47	0x5475	# <CJK>
+0x3A48	0x559D	# <CJK>
+0x3A49	0x8377	# <CJK>
+0x3A4A	0x83CF	# <CJK>
+0x3A4B	0x6838	# <CJK>
+0x3A4C	0x79BE	# <CJK>
+0x3A4D	0x548C	# <CJK>
+0x3A4E	0x4F55	# <CJK>
+0x3A4F	0x5408	# <CJK>
+0x3A50	0x76D2	# <CJK>
+0x3A51	0x8C89	# <CJK>
+0x3A52	0x95A1	# <CJK>
+0x3A53	0x6CB3	# <CJK>
+0x3A54	0x6DB8	# <CJK>
+0x3A55	0x8D6B	# <CJK>
+0x3A56	0x8910	# <CJK>
+0x3A57	0x9DB4	# <CJK>
+0x3A58	0x8CC0	# <CJK>
+0x3A59	0x563F	# <CJK>
+0x3A5A	0x9ED1	# <CJK>
+0x3A5B	0x75D5	# <CJK>
+0x3A5C	0x5F88	# <CJK>
+0x3A5D	0x72E0	# <CJK>
+0x3A5E	0x6068	# <CJK>
+0x3A5F	0x54FC	# <CJK>
+0x3A60	0x4EA8	# <CJK>
+0x3A61	0x6A2A	# <CJK>
+0x3A62	0x8861	# <CJK>
+0x3A63	0x6052	# <CJK>
+0x3A64	0x8F5F	# <CJK>
+0x3A65	0x54C4	# <CJK>
+0x3A66	0x70D8	# <CJK>
+0x3A67	0x8679	# <CJK>
+0x3A68	0x9D3B	# <CJK>
+0x3A69	0x6D2A	# <CJK>
+0x3A6A	0x5B8F	# <CJK>
+0x3A6B	0x5F18	# <CJK>
+0x3A6C	0x7D05	# <CJK>
+0x3A6D	0x5589	# <CJK>
+0x3A6E	0x4FAF	# <CJK>
+0x3A6F	0x7334	# <CJK>
+0x3A70	0x543C	# <CJK>
+0x3A71	0x539A	# <CJK>
+0x3A72	0x5019	# <CJK>
+0x3A73	0x5F8C	# <CJK>
+0x3A74	0x547C	# <CJK>
+0x3A75	0x4E4E	# <CJK>
+0x3A76	0x5FFD	# <CJK>
+0x3A77	0x745A	# <CJK>
+0x3A78	0x58FA	# <CJK>
+0x3A79	0x846B	# <CJK>
+0x3A7A	0x80E1	# <CJK>
+0x3A7B	0x8774	# <CJK>
+0x3A7C	0x72D0	# <CJK>
+0x3A7D	0x7CCA	# <CJK>
+0x3A7E	0x6E56	# <CJK>
+0x3B21	0x5F27	# <CJK>
+0x3B22	0x864E	# <CJK>
+0x3B23	0x552C	# <CJK>
+0x3B24	0x8B77	# <CJK>
+0x3B25	0x4E92	# <CJK>
+0x3B26	0x6EEC	# <CJK>
+0x3B27	0x6237	# <CJK>
+0x3B28	0x82B1	# <CJK>
+0x3B29	0x5629	# <CJK>
+0x3B2A	0x83EF	# <CJK>
+0x3B2B	0x733E	# <CJK>
+0x3B2C	0x6ED1	# <CJK>
+0x3B2D	0x756B	# <CJK>
+0x3B2E	0x5283	# <CJK>
+0x3B2F	0x5316	# <CJK>
+0x3B30	0x8A71	# <CJK>
+0x3B31	0x69D0	# <CJK>
+0x3B32	0x5F8A	# <CJK>
+0x3B33	0x61F7	# <CJK>
+0x3B34	0x6DEE	# <CJK>
+0x3B35	0x58DE	# <CJK>
+0x3B36	0x6B61	# <CJK>
+0x3B37	0x74B0	# <CJK>
+0x3B38	0x6853	# <CJK>
+0x3B39	0x9084	# <CJK>
+0x3B3A	0x7DE9	# <CJK>
+0x3B3B	0x63DB	# <CJK>
+0x3B3C	0x60A3	# <CJK>
+0x3B3D	0x559A	# <CJK>
+0x3B3E	0x7613	# <CJK>
+0x3B3F	0x8C62	# <CJK>
+0x3B40	0x7165	# <CJK>
+0x3B41	0x6E19	# <CJK>
+0x3B42	0x5BA6	# <CJK>
+0x3B43	0x5E7B	# <CJK>
+0x3B44	0x8352	# <CJK>
+0x3B45	0x614C	# <CJK>
+0x3B46	0x9EC4	# <CJK>
+0x3B47	0x78FA	# <CJK>
+0x3B48	0x8757	# <CJK>
+0x3B49	0x7C27	# <CJK>
+0x3B4A	0x7687	# <CJK>
+0x3B4B	0x51F0	# <CJK>
+0x3B4C	0x60F6	# <CJK>
+0x3B4D	0x714C	# <CJK>
+0x3B4E	0x6643	# <CJK>
+0x3B4F	0x5E4C	# <CJK>
+0x3B50	0x604D	# <CJK>
+0x3B51	0x8B0A	# <CJK>
+0x3B52	0x7070	# <CJK>
+0x3B53	0x63EE	# <CJK>
+0x3B54	0x8F1D	# <CJK>
+0x3B55	0x5FBD	# <CJK>
+0x3B56	0x6062	# <CJK>
+0x3B57	0x86D4	# <CJK>
+0x3B58	0x56DE	# <CJK>
+0x3B59	0x6BC1	# <CJK>
+0x3B5A	0x6094	# <CJK>
+0x3B5B	0x6167	# <CJK>
+0x3B5C	0x5349	# <CJK>
+0x3B5D	0x60E0	# <CJK>
+0x3B5E	0x6666	# <CJK>
+0x3B5F	0x8CC4	# <CJK>
+0x3B60	0x7A62	# <CJK>
+0x3B61	0x6703	# <CJK>
+0x3B62	0x71F4	# <CJK>
+0x3B63	0x532F	# <CJK>
+0x3B64	0x8AF1	# <CJK>
+0x3B65	0x8AA8	# <CJK>
+0x3B66	0x7E6A	# <CJK>
+0x3B67	0x8477	# <CJK>
+0x3B68	0x660F	# <CJK>
+0x3B69	0x5A5A	# <CJK>
+0x3B6A	0x9B42	# <CJK>
+0x3B6B	0x6E3E	# <CJK>
+0x3B6C	0x6DF7	# <CJK>
+0x3B6D	0x8C41	# <CJK>
+0x3B6E	0x6D3B	# <CJK>
+0x3B6F	0x4F19	# <CJK>
+0x3B70	0x706B	# <CJK>
+0x3B71	0x7372	# <CJK>
+0x3B72	0x6216	# <CJK>
+0x3B73	0x60D1	# <CJK>
+0x3B74	0x970D	# <CJK>
+0x3B75	0x8CA8	# <CJK>
+0x3B76	0x798D	# <CJK>
+0x3B77	0x64CA	# <CJK>
+0x3B78	0x573E	# <CJK>
+0x3B79	0x57FA	# <CJK>
+0x3B7A	0x6A5F	# <CJK>
+0x3B7B	0x7578	# <CJK>
+0x3B7C	0x7A3D	# <CJK>
+0x3B7D	0x7A4D	# <CJK>
+0x3B7E	0x7B95	# <CJK>
+0x3C21	0x808C	# <CJK>
+0x3C22	0x9951	# <CJK>
+0x3C23	0x8FF9	# <CJK>
+0x3C24	0x6FC0	# <CJK>
+0x3C25	0x8B4F	# <CJK>
+0x3C26	0x9DC4	# <CJK>
+0x3C27	0x59EC	# <CJK>
+0x3C28	0x7E3E	# <CJK>
+0x3C29	0x7DDD	# <CJK>
+0x3C2A	0x5409	# <CJK>
+0x3C2B	0x6975	# <CJK>
+0x3C2C	0x68D8	# <CJK>
+0x3C2D	0x8F2F	# <CJK>
+0x3C2E	0x7C4D	# <CJK>
+0x3C2F	0x96C6	# <CJK>
+0x3C30	0x53CA	# <CJK>
+0x3C31	0x6025	# <CJK>
+0x3C32	0x75BE	# <CJK>
+0x3C33	0x6C72	# <CJK>
+0x3C34	0x5373	# <CJK>
+0x3C35	0x5AC9	# <CJK>
+0x3C36	0x7D1A	# <CJK>
+0x3C37	0x64E0	# <CJK>
+0x3C38	0x5E7E	# <CJK>
+0x3C39	0x810A	# <CJK>
+0x3C3A	0x5DF1	# <CJK>
+0x3C3B	0x858A	# <CJK>
+0x3C3C	0x6280	# <CJK>
+0x3C3D	0x5180	# <CJK>
+0x3C3E	0x5B63	# <CJK>
+0x3C3F	0x4F0E	# <CJK>
+0x3C40	0x796D	# <CJK>
+0x3C41	0x5291	# <CJK>
+0x3C42	0x60B8	# <CJK>
+0x3C43	0x6FDF	# <CJK>
+0x3C44	0x5BC4	# <CJK>
+0x3C45	0x5BC2	# <CJK>
+0x3C46	0x8A08	# <CJK>
+0x3C47	0x8A18	# <CJK>
+0x3C48	0x65E2	# <CJK>
+0x3C49	0x5FCC	# <CJK>
+0x3C4A	0x969B	# <CJK>
+0x3C4B	0x5993	# <CJK>
+0x3C4C	0x7E7C	# <CJK>
+0x3C4D	0x7D00	# <CJK>
+0x3C4E	0x5609	# <CJK>
+0x3C4F	0x67B7	# <CJK>
+0x3C50	0x593E	# <CJK>
+0x3C51	0x4F73	# <CJK>
+0x3C52	0x5BB6	# <CJK>
+0x3C53	0x52A0	# <CJK>
+0x3C54	0x83A2	# <CJK>
+0x3C55	0x9830	# <CJK>
+0x3C56	0x8CC8	# <CJK>
+0x3C57	0x7532	# <CJK>
+0x3C58	0x9240	# <CJK>
+0x3C59	0x5047	# <CJK>
+0x3C5A	0x7A3C	# <CJK>
+0x3C5B	0x50F9	# <CJK>
+0x3C5C	0x67B6	# <CJK>
+0x3C5D	0x99D5	# <CJK>
+0x3C5E	0x5AC1	# <CJK>
+0x3C5F	0x6BB2	# <CJK>
+0x3C60	0x76E3	# <CJK>
+0x3C61	0x5805	# <CJK>
+0x3C62	0x5C16	# <CJK>
+0x3C63	0x7B8B	# <CJK>
+0x3C64	0x9593	# <CJK>
+0x3C65	0x714E	# <CJK>
+0x3C66	0x517C	# <CJK>
+0x3C67	0x80A9	# <CJK>
+0x3C68	0x8271	# <CJK>
+0x3C69	0x5978	# <CJK>
+0x3C6A	0x7DD8	# <CJK>
+0x3C6B	0x7E6D	# <CJK>
+0x3C6C	0x6AA2	# <CJK>
+0x3C6D	0x67EC	# <CJK>
+0x3C6E	0x78B1	# <CJK>
+0x3C6F	0x9E7C	# <CJK>
+0x3C70	0x63C0	# <CJK>
+0x3C71	0x64BF	# <CJK>
+0x3C72	0x7C21	# <CJK>
+0x3C73	0x5109	# <CJK>
+0x3C74	0x526A	# <CJK>
+0x3C75	0x51CF	# <CJK>
+0x3C76	0x85A6	# <CJK>
+0x3C77	0x6ABB	# <CJK>
+0x3C78	0x9452	# <CJK>
+0x3C79	0x8E10	# <CJK>
+0x3C7A	0x8CE4	# <CJK>
+0x3C7B	0x898B	# <CJK>
+0x3C7C	0x9375	# <CJK>
+0x3C7D	0x7BAD	# <CJK>
+0x3C7E	0x4EF6	# <CJK>
+0x3D21	0x5065	# <CJK>
+0x3D22	0x8266	# <CJK>
+0x3D23	0x528D	# <CJK>
+0x3D24	0x991E	# <CJK>
+0x3D25	0x6F38	# <CJK>
+0x3D26	0x6FFA	# <CJK>
+0x3D27	0x6F97	# <CJK>
+0x3D28	0x5EFA	# <CJK>
+0x3D29	0x50F5	# <CJK>
+0x3D2A	0x59DC	# <CJK>
+0x3D2B	0x5C07	# <CJK>
+0x3D2C	0x6F3F	# <CJK>
+0x3D2D	0x6C5F	# <CJK>
+0x3D2E	0x7586	# <CJK>
+0x3D2F	0x8523	# <CJK>
+0x3D30	0x69F3	# <CJK>
+0x3D31	0x596C	# <CJK>
+0x3D32	0x8B1B	# <CJK>
+0x3D33	0x5320	# <CJK>
+0x3D34	0x91AC	# <CJK>
+0x3D35	0x964D	# <CJK>
+0x3D36	0x8549	# <CJK>
+0x3D37	0x6912	# <CJK>
+0x3D38	0x7901	# <CJK>
+0x3D39	0x7126	# <CJK>
+0x3D3A	0x81A0	# <CJK>
+0x3D3B	0x4EA4	# <CJK>
+0x3D3C	0x90CA	# <CJK>
+0x3D3D	0x6F86	# <CJK>
+0x3D3E	0x9A55	# <CJK>
+0x3D3F	0x5B0C	# <CJK>
+0x3D40	0x56BC	# <CJK>
+0x3D41	0x652A	# <CJK>
+0x3D42	0x9278	# <CJK>
+0x3D43	0x77EF	# <CJK>
+0x3D44	0x50E5	# <CJK>
+0x3D45	0x811A	# <CJK>
+0x3D46	0x72E1	# <CJK>
+0x3D47	0x89D2	# <CJK>
+0x3D48	0x9903	# <CJK>
+0x3D49	0x7E73	# <CJK>
+0x3D4A	0x7D5E	# <CJK>
+0x3D4B	0x527F	# <CJK>
+0x3D4C	0x6559	# <CJK>
+0x3D4D	0x9175	# <CJK>
+0x3D4E	0x8F4E	# <CJK>
+0x3D4F	0x8F03	# <CJK>
+0x3D50	0x53EB	# <CJK>
+0x3D51	0x7A96	# <CJK>
+0x3D52	0x63ED	# <CJK>
+0x3D53	0x63A5	# <CJK>
+0x3D54	0x7686	# <CJK>
+0x3D55	0x79F8	# <CJK>
+0x3D56	0x8857	# <CJK>
+0x3D57	0x968E	# <CJK>
+0x3D58	0x622A	# <CJK>
+0x3D59	0x52AB	# <CJK>
+0x3D5A	0x7BC0	# <CJK>
+0x3D5B	0x6854	# <CJK>
+0x3D5C	0x6770	# <CJK>
+0x3D5D	0x6377	# <CJK>
+0x3D5E	0x776B	# <CJK>
+0x3D5F	0x7AED	# <CJK>
+0x3D60	0x6F54	# <CJK>
+0x3D61	0x7D50	# <CJK>
+0x3D62	0x89E3	# <CJK>
+0x3D63	0x59D0	# <CJK>
+0x3D64	0x6212	# <CJK>
+0x3D65	0x85C9	# <CJK>
+0x3D66	0x82A5	# <CJK>
+0x3D67	0x754C	# <CJK>
+0x3D68	0x501F	# <CJK>
+0x3D69	0x4ECB	# <CJK>
+0x3D6A	0x75A5	# <CJK>
+0x3D6B	0x8AA1	# <CJK>
+0x3D6C	0x5C4A	# <CJK>
+0x3D6D	0x5DFE	# <CJK>
+0x3D6E	0x7B4B	# <CJK>
+0x3D6F	0x65A4	# <CJK>
+0x3D70	0x91D1	# <CJK>
+0x3D71	0x4ECA	# <CJK>
+0x3D72	0x6D25	# <CJK>
+0x3D73	0x895F	# <CJK>
+0x3D74	0x7DCA	# <CJK>
+0x3D75	0x9326	# <CJK>
+0x3D76	0x50C5	# <CJK>
+0x3D77	0x8B39	# <CJK>
+0x3D78	0x9032	# <CJK>
+0x3D79	0x9773	# <CJK>
+0x3D7A	0x6649	# <CJK>
+0x3D7B	0x7981	# <CJK>
+0x3D7C	0x8FD1	# <CJK>
+0x3D7D	0x71FC	# <CJK>
+0x3D7E	0x6D78	# <CJK>
+0x3E21	0x76E1	# <CJK>
+0x3E22	0x52C1	# <CJK>
+0x3E23	0x8346	# <CJK>
+0x3E24	0x5162	# <CJK>
+0x3E25	0x8396	# <CJK>
+0x3E26	0x775B	# <CJK>
+0x3E27	0x6676	# <CJK>
+0x3E28	0x9BE8	# <CJK>
+0x3E29	0x4EAC	# <CJK>
+0x3E2A	0x9A5A	# <CJK>
+0x3E2B	0x7CBE	# <CJK>
+0x3E2C	0x7CB3	# <CJK>
+0x3E2D	0x7D93	# <CJK>
+0x3E2E	0x4E95	# <CJK>
+0x3E2F	0x8B66	# <CJK>
+0x3E30	0x666F	# <CJK>
+0x3E31	0x9838	# <CJK>
+0x3E32	0x975C	# <CJK>
+0x3E33	0x5883	# <CJK>
+0x3E34	0x656C	# <CJK>
+0x3E35	0x93E1	# <CJK>
+0x3E36	0x5F91	# <CJK>
+0x3E37	0x75D9	# <CJK>
+0x3E38	0x9756	# <CJK>
+0x3E39	0x7ADF	# <CJK>
+0x3E3A	0x7AF6	# <CJK>
+0x3E3B	0x51C8	# <CJK>
+0x3E3C	0x70AF	# <CJK>
+0x3E3D	0x7A98	# <CJK>
+0x3E3E	0x63EA	# <CJK>
+0x3E3F	0x7A76	# <CJK>
+0x3E40	0x7CFE	# <CJK>
+0x3E41	0x7396	# <CJK>
+0x3E42	0x97ED	# <CJK>
+0x3E43	0x4E45	# <CJK>
+0x3E44	0x7078	# <CJK>
+0x3E45	0x4E5D	# <CJK>
+0x3E46	0x9152	# <CJK>
+0x3E47	0x53A9	# <CJK>
+0x3E48	0x6551	# <CJK>
+0x3E49	0x820A	# <CJK>
+0x3E4A	0x81FC	# <CJK>
+0x3E4B	0x8205	# <CJK>
+0x3E4C	0x548E	# <CJK>
+0x3E4D	0x5C31	# <CJK>
+0x3E4E	0x759A	# <CJK>
+0x3E4F	0x97A0	# <CJK>
+0x3E50	0x62D8	# <CJK>
+0x3E51	0x72D9	# <CJK>
+0x3E52	0x75BD	# <CJK>
+0x3E53	0x5C45	# <CJK>
+0x3E54	0x99D2	# <CJK>
+0x3E55	0x83CA	# <CJK>
+0x3E56	0x5C40	# <CJK>
+0x3E57	0x5480	# <CJK>
+0x3E58	0x77E9	# <CJK>
+0x3E59	0x8209	# <CJK>
+0x3E5A	0x6CAE	# <CJK>
+0x3E5B	0x805A	# <CJK>
+0x3E5C	0x62D2	# <CJK>
+0x3E5D	0x64DA	# <CJK>
+0x3E5E	0x5DE8	# <CJK>
+0x3E5F	0x5177	# <CJK>
+0x3E60	0x8DDD	# <CJK>
+0x3E61	0x8E1E	# <CJK>
+0x3E62	0x92F8	# <CJK>
+0x3E63	0x4FF1	# <CJK>
+0x3E64	0x53E5	# <CJK>
+0x3E65	0x61FC	# <CJK>
+0x3E66	0x70AC	# <CJK>
+0x3E67	0x5287	# <CJK>
+0x3E68	0x6350	# <CJK>
+0x3E69	0x9D51	# <CJK>
+0x3E6A	0x5A1F	# <CJK>
+0x3E6B	0x5026	# <CJK>
+0x3E6C	0x7737	# <CJK>
+0x3E6D	0x5377	# <CJK>
+0x3E6E	0x7D79	# <CJK>
+0x3E6F	0x6485	# <CJK>
+0x3E70	0x652B	# <CJK>
+0x3E71	0x6289	# <CJK>
+0x3E72	0x6398	# <CJK>
+0x3E73	0x5014	# <CJK>
+0x3E74	0x7235	# <CJK>
+0x3E75	0x89BA	# <CJK>
+0x3E76	0x51B3	# <CJK>
+0x3E77	0x8A23	# <CJK>
+0x3E78	0x7D76	# <CJK>
+0x3E79	0x5747	# <CJK>
+0x3E7A	0x83CC	# <CJK>
+0x3E7B	0x921E	# <CJK>
+0x3E7C	0x8ECD	# <CJK>
+0x3E7D	0x541B	# <CJK>
+0x3E7E	0x5CFB	# <CJK>
+0x3F21	0x4FCA	# <CJK>
+0x3F22	0x7AE3	# <CJK>
+0x3F23	0x6D5A	# <CJK>
+0x3F24	0x90E1	# <CJK>
+0x3F25	0x99FF	# <CJK>
+0x3F26	0x5580	# <CJK>
+0x3F27	0x5496	# <CJK>
+0x3F28	0x5361	# <CJK>
+0x3F29	0x54AF	# <CJK>
+0x3F2A	0x958B	# <CJK>
+0x3F2B	0x63E9	# <CJK>
+0x3F2C	0x6977	# <CJK>
+0x3F2D	0x51F1	# <CJK>
+0x3F2E	0x6168	# <CJK>
+0x3F2F	0x520A	# <CJK>
+0x3F30	0x582A	# <CJK>
+0x3F31	0x52D8	# <CJK>
+0x3F32	0x574E	# <CJK>
+0x3F33	0x780D	# <CJK>
+0x3F34	0x770B	# <CJK>
+0x3F35	0x5EB7	# <CJK>
+0x3F36	0x6177	# <CJK>
+0x3F37	0x7CE0	# <CJK>
+0x3F38	0x625B	# <CJK>
+0x3F39	0x6297	# <CJK>
+0x3F3A	0x4EA2	# <CJK>
+0x3F3B	0x7095	# <CJK>
+0x3F3C	0x8003	# <CJK>
+0x3F3D	0x62F7	# <CJK>
+0x3F3E	0x70E4	# <CJK>
+0x3F3F	0x9760	# <CJK>
+0x3F40	0x5777	# <CJK>
+0x3F41	0x82DB	# <CJK>
+0x3F42	0x67EF	# <CJK>
+0x3F43	0x68F5	# <CJK>
+0x3F44	0x78D5	# <CJK>
+0x3F45	0x9846	# <CJK>
+0x3F46	0x79D1	# <CJK>
+0x3F47	0x6BBB	# <CJK>
+0x3F48	0x54B3	# <CJK>
+0x3F49	0x53EF	# <CJK>
+0x3F4A	0x6E34	# <CJK>
+0x3F4B	0x514B	# <CJK>
+0x3F4C	0x523B	# <CJK>
+0x3F4D	0x5BA2	# <CJK>
+0x3F4E	0x8AB2	# <CJK>
+0x3F4F	0x80AF	# <CJK>
+0x3F50	0x5543	# <CJK>
+0x3F51	0x58BE	# <CJK>
+0x3F52	0x61C7	# <CJK>
+0x3F53	0x5751	# <CJK>
+0x3F54	0x542D	# <CJK>
+0x3F55	0x7A7A	# <CJK>
+0x3F56	0x6050	# <CJK>
+0x3F57	0x5B54	# <CJK>
+0x3F58	0x63A7	# <CJK>
+0x3F59	0x6473	# <CJK>
+0x3F5A	0x53E3	# <CJK>
+0x3F5B	0x6263	# <CJK>
+0x3F5C	0x5BC7	# <CJK>
+0x3F5D	0x67AF	# <CJK>
+0x3F5E	0x54ED	# <CJK>
+0x3F5F	0x7A9F	# <CJK>
+0x3F60	0x82E6	# <CJK>
+0x3F61	0x9177	# <CJK>
+0x3F62	0x5EAB	# <CJK>
+0x3F63	0x8932	# <CJK>
+0x3F64	0x8A87	# <CJK>
+0x3F65	0x57AE	# <CJK>
+0x3F66	0x630E	# <CJK>
+0x3F67	0x8DE8	# <CJK>
+0x3F68	0x80EF	# <CJK>
+0x3F69	0x584A	# <CJK>
+0x3F6A	0x7B77	# <CJK>
+0x3F6B	0x5108	# <CJK>
+0x3F6C	0x5FEB	# <CJK>
+0x3F6D	0x5BEC	# <CJK>
+0x3F6E	0x6B3E	# <CJK>
+0x3F6F	0x5321	# <CJK>
+0x3F70	0x7B50	# <CJK>
+0x3F71	0x72C2	# <CJK>
+0x3F72	0x6846	# <CJK>
+0x3F73	0x7926	# <CJK>
+0x3F74	0x7736	# <CJK>
+0x3F75	0x66E0	# <CJK>
+0x3F76	0x51B5	# <CJK>
+0x3F77	0x8667	# <CJK>
+0x3F78	0x76D4	# <CJK>
+0x3F79	0x5DCB	# <CJK>
+0x3F7A	0x7ABA	# <CJK>
+0x3F7B	0x8475	# <CJK>
+0x3F7C	0x594E	# <CJK>
+0x3F7D	0x9B41	# <CJK>
+0x3F7E	0x5080	# <CJK>
+0x4021	0x994B	# <CJK>
+0x4022	0x6127	# <CJK>
+0x4023	0x6F70	# <CJK>
+0x4024	0x5764	# <CJK>
+0x4025	0x6606	# <CJK>
+0x4026	0x6346	# <CJK>
+0x4027	0x56F0	# <CJK>
+0x4028	0x62EC	# <CJK>
+0x4029	0x64F4	# <CJK>
+0x402A	0x5ED3	# <CJK>
+0x402B	0x95CA	# <CJK>
+0x402C	0x5783	# <CJK>
+0x402D	0x62C9	# <CJK>
+0x402E	0x5587	# <CJK>
+0x402F	0x881F	# <CJK>
+0x4030	0x81D8	# <CJK>
+0x4031	0x8FA3	# <CJK>
+0x4032	0x5566	# <CJK>
+0x4033	0x840A	# <CJK>
+0x4034	0x4F86	# <CJK>
+0x4035	0x8CF4	# <CJK>
+0x4036	0x85CD	# <CJK>
+0x4037	0x5A6A	# <CJK>
+0x4038	0x6B04	# <CJK>
+0x4039	0x6514	# <CJK>
+0x403A	0x7C43	# <CJK>
+0x403B	0x95CC	# <CJK>
+0x403C	0x862D	# <CJK>
+0x403D	0x703E	# <CJK>
+0x403E	0x8B95	# <CJK>
+0x403F	0x652C	# <CJK>
+0x4040	0x89BD	# <CJK>
+0x4041	0x61F6	# <CJK>
+0x4042	0x7E9C	# <CJK>
+0x4043	0x721B	# <CJK>
+0x4044	0x6FEB	# <CJK>
+0x4045	0x7405	# <CJK>
+0x4046	0x6994	# <CJK>
+0x4047	0x72FC	# <CJK>
+0x4048	0x5ECA	# <CJK>
+0x4049	0x90CE	# <CJK>
+0x404A	0x6717	# <CJK>
+0x404B	0x6D6A	# <CJK>
+0x404C	0x6488	# <CJK>
+0x404D	0x52DE	# <CJK>
+0x404E	0x7262	# <CJK>
+0x404F	0x8001	# <CJK>
+0x4050	0x4F6C	# <CJK>
+0x4051	0x59E5	# <CJK>
+0x4052	0x916A	# <CJK>
+0x4053	0x70D9	# <CJK>
+0x4054	0x6F87	# <CJK>
+0x4055	0x52D2	# <CJK>
+0x4056	0x6A02	# <CJK>
+0x4057	0x96F7	# <CJK>
+0x4058	0x9433	# <CJK>
+0x4059	0x857E	# <CJK>
+0x405A	0x78CA	# <CJK>
+0x405B	0x7D2F	# <CJK>
+0x405C	0x5121	# <CJK>
+0x405D	0x58D8	# <CJK>
+0x405E	0x64C2	# <CJK>
+0x405F	0x808B	# <CJK>
+0x4060	0x985E	# <CJK>
+0x4061	0x6CEA	# <CJK>
+0x4062	0x68F1	# <CJK>
+0x4063	0x695E	# <CJK>
+0x4064	0x51B7	# <CJK>
+0x4065	0x5398	# <CJK>
+0x4066	0x68A8	# <CJK>
+0x4067	0x7281	# <CJK>
+0x4068	0x9ECE	# <CJK>
+0x4069	0x7C6C	# <CJK>
+0x406A	0x72F8	# <CJK>
+0x406B	0x96E2	# <CJK>
+0x406C	0x7055	# <CJK>
+0x406D	0x7406	# <CJK>
+0x406E	0x674E	# <CJK>
+0x406F	0x88CF	# <CJK>
+0x4070	0x9BC9	# <CJK>
+0x4071	0x79AE	# <CJK>
+0x4072	0x8389	# <CJK>
+0x4073	0x8354	# <CJK>
+0x4074	0x540F	# <CJK>
+0x4075	0x6817	# <CJK>
+0x4076	0x9E97	# <CJK>
+0x4077	0x53B2	# <CJK>
+0x4078	0x52F5	# <CJK>
+0x4079	0x792B	# <CJK>
+0x407A	0x6B77	# <CJK>
+0x407B	0x5229	# <CJK>
+0x407C	0x5088	# <CJK>
+0x407D	0x4F8B	# <CJK>
+0x407E	0x4FD0	# <CJK>
+0x4121	0x75E2	# <CJK>
+0x4122	0x7ACB	# <CJK>
+0x4123	0x7C92	# <CJK>
+0x4124	0x701D	# <CJK>
+0x4125	0x96B8	# <CJK>
+0x4126	0x529B	# <CJK>
+0x4127	0x7483	# <CJK>
+0x4128	0x54E9	# <CJK>
+0x4129	0x5006	# <CJK>
+0x412A	0x806F	# <CJK>
+0x412B	0x84EE	# <CJK>
+0x412C	0x9023	# <CJK>
+0x412D	0x942E	# <CJK>
+0x412E	0x5EC9	# <CJK>
+0x412F	0x6190	# <CJK>
+0x4130	0x6F23	# <CJK>
+0x4131	0x7C3E	# <CJK>
+0x4132	0x6582	# <CJK>
+0x4133	0x81C9	# <CJK>
+0x4134	0x93C8	# <CJK>
+0x4135	0x6200	# <CJK>
+0x4136	0x7149	# <CJK>
+0x4137	0x7DF4	# <CJK>
+0x4138	0x7CE7	# <CJK>
+0x4139	0x51C9	# <CJK>
+0x413A	0x6881	# <CJK>
+0x413B	0x7CB1	# <CJK>
+0x413C	0x826F	# <CJK>
+0x413D	0x5169	# <CJK>
+0x413E	0x8F1B	# <CJK>
+0x413F	0x91CF	# <CJK>
+0x4140	0x667E	# <CJK>
+0x4141	0x4EAE	# <CJK>
+0x4142	0x8AD2	# <CJK>
+0x4143	0x64A9	# <CJK>
+0x4144	0x804A	# <CJK>
+0x4145	0x50DA	# <CJK>
+0x4146	0x7642	# <CJK>
+0x4147	0x71CE	# <CJK>
+0x4148	0x5BE5	# <CJK>
+0x4149	0x907C	# <CJK>
+0x414A	0x6F66	# <CJK>
+0x414B	0x4E86	# <CJK>
+0x414C	0x6482	# <CJK>
+0x414D	0x9410	# <CJK>
+0x414E	0x5ED6	# <CJK>
+0x414F	0x6599	# <CJK>
+0x4150	0x5217	# <CJK>
+0x4151	0x88C2	# <CJK>
+0x4152	0x70C8	# <CJK>
+0x4153	0x52A3	# <CJK>
+0x4154	0x7375	# <CJK>
+0x4155	0x7433	# <CJK>
+0x4156	0x6797	# <CJK>
+0x4157	0x78F7	# <CJK>
+0x4158	0x9716	# <CJK>
+0x4159	0x81E8	# <CJK>
+0x415A	0x9130	# <CJK>
+0x415B	0x9C57	# <CJK>
+0x415C	0x6DCB	# <CJK>
+0x415D	0x51DB	# <CJK>
+0x415E	0x8CC3	# <CJK>
+0x415F	0x541D	# <CJK>
+0x4160	0x62CE	# <CJK>
+0x4161	0x73B2	# <CJK>
+0x4162	0x83F1	# <CJK>
+0x4163	0x96F6	# <CJK>
+0x4164	0x9F61	# <CJK>
+0x4165	0x9234	# <CJK>
+0x4166	0x4F36	# <CJK>
+0x4167	0x7F9A	# <CJK>
+0x4168	0x51CC	# <CJK>
+0x4169	0x9748	# <CJK>
+0x416A	0x9675	# <CJK>
+0x416B	0x5DBA	# <CJK>
+0x416C	0x9818	# <CJK>
+0x416D	0x53E6	# <CJK>
+0x416E	0x4EE4	# <CJK>
+0x416F	0x6E9C	# <CJK>
+0x4170	0x7409	# <CJK>
+0x4171	0x69B4	# <CJK>
+0x4172	0x786B	# <CJK>
+0x4173	0x993E	# <CJK>
+0x4174	0x7559	# <CJK>
+0x4175	0x5289	# <CJK>
+0x4176	0x7624	# <CJK>
+0x4177	0x6D41	# <CJK>
+0x4178	0x67F3	# <CJK>
+0x4179	0x516D	# <CJK>
+0x417A	0x9F8D	# <CJK>
+0x417B	0x807E	# <CJK>
+0x417C	0x56A8	# <CJK>
+0x417D	0x7C60	# <CJK>
+0x417E	0x7ABF	# <CJK>
+0x4221	0x9686	# <CJK>
+0x4222	0x58DF	# <CJK>
+0x4223	0x650F	# <CJK>
+0x4224	0x96B4	# <CJK>
+0x4225	0x6A13	# <CJK>
+0x4226	0x5A41	# <CJK>
+0x4227	0x645F	# <CJK>
+0x4228	0x7C0D	# <CJK>
+0x4229	0x6F0F	# <CJK>
+0x422A	0x964B	# <CJK>
+0x422B	0x8606	# <CJK>
+0x422C	0x76E7	# <CJK>
+0x422D	0x9871	# <CJK>
+0x422E	0x5EEC	# <CJK>
+0x422F	0x7210	# <CJK>
+0x4230	0x64C4	# <CJK>
+0x4231	0x6EF7	# <CJK>
+0x4232	0x865C	# <CJK>
+0x4233	0x9B6F	# <CJK>
+0x4234	0x9E93	# <CJK>
+0x4235	0x788C	# <CJK>
+0x4236	0x9732	# <CJK>
+0x4237	0x8DEF	# <CJK>
+0x4238	0x8CC2	# <CJK>
+0x4239	0x9E7F	# <CJK>
+0x423A	0x6F5E	# <CJK>
+0x423B	0x7984	# <CJK>
+0x423C	0x9332	# <CJK>
+0x423D	0x9678	# <CJK>
+0x423E	0x622E	# <CJK>
+0x423F	0x9A62	# <CJK>
+0x4240	0x5415	# <CJK>
+0x4241	0x92C1	# <CJK>
+0x4242	0x4FA3	# <CJK>
+0x4243	0x65C5	# <CJK>
+0x4244	0x5C65	# <CJK>
+0x4245	0x5C62	# <CJK>
+0x4246	0x7E37	# <CJK>
+0x4247	0x616E	# <CJK>
+0x4248	0x6C2F	# <CJK>
+0x4249	0x5F8B	# <CJK>
+0x424A	0x7387	# <CJK>
+0x424B	0x6FFE	# <CJK>
+0x424C	0x7DD1	# <CJK>
+0x424D	0x5DD2	# <CJK>
+0x424E	0x6523	# <CJK>
+0x424F	0x5B7F	# <CJK>
+0x4250	0x7064	# <CJK>
+0x4251	0x5375	# <CJK>
+0x4252	0x4E82	# <CJK>
+0x4253	0x63A0	# <CJK>
+0x4254	0x7565	# <CJK>
+0x4255	0x6384	# <CJK>
+0x4256	0x8F2A	# <CJK>
+0x4257	0x502B	# <CJK>
+0x4258	0x4F96	# <CJK>
+0x4259	0x6DEA	# <CJK>
+0x425A	0x7DB8	# <CJK>
+0x425B	0x8AD6	# <CJK>
+0x425C	0x863F	# <CJK>
+0x425D	0x87BA	# <CJK>
+0x425E	0x7F85	# <CJK>
+0x425F	0x908F	# <CJK>
+0x4260	0x947C	# <CJK>
+0x4261	0x7C6E	# <CJK>
+0x4262	0x9A3E	# <CJK>
+0x4263	0x88F8	# <CJK>
+0x4264	0x843D	# <CJK>
+0x4265	0x6D1B	# <CJK>
+0x4266	0x99F1	# <CJK>
+0x4267	0x7D61	# <CJK>
+0x4268	0x5ABD	# <CJK>
+0x4269	0x9EBB	# <CJK>
+0x426A	0x746A	# <CJK>
+0x426B	0x78BC	# <CJK>
+0x426C	0x879E	# <CJK>
+0x426D	0x99AC	# <CJK>
+0x426E	0x99E1	# <CJK>
+0x426F	0x561B	# <CJK>
+0x4270	0x55CE	# <CJK>
+0x4271	0x57CB	# <CJK>
+0x4272	0x8CB7	# <CJK>
+0x4273	0x9EA5	# <CJK>
+0x4274	0x8CE3	# <CJK>
+0x4275	0x9081	# <CJK>
+0x4276	0x8109	# <CJK>
+0x4277	0x779E	# <CJK>
+0x4278	0x9945	# <CJK>
+0x4279	0x883B	# <CJK>
+0x427A	0x6EFF	# <CJK>
+0x427B	0x8513	# <CJK>
+0x427C	0x66FC	# <CJK>
+0x427D	0x6162	# <CJK>
+0x427E	0x6F2B	# <CJK>
+0x4321	0x8B3E	# <CJK>
+0x4322	0x8292	# <CJK>
+0x4323	0x832B	# <CJK>
+0x4324	0x76F2	# <CJK>
+0x4325	0x6C13	# <CJK>
+0x4326	0x5FD9	# <CJK>
+0x4327	0x83BD	# <CJK>
+0x4328	0x732B	# <CJK>
+0x4329	0x8305	# <CJK>
+0x432A	0x9328	# <CJK>
+0x432B	0x6BDB	# <CJK>
+0x432C	0x77DB	# <CJK>
+0x432D	0x925A	# <CJK>
+0x432E	0x536F	# <CJK>
+0x432F	0x8302	# <CJK>
+0x4330	0x5192	# <CJK>
+0x4331	0x5E3D	# <CJK>
+0x4332	0x8C8C	# <CJK>
+0x4333	0x8CBF	# <CJK>
+0x4334	0x9EBD	# <CJK>
+0x4335	0x73AB	# <CJK>
+0x4336	0x679A	# <CJK>
+0x4337	0x6885	# <CJK>
+0x4338	0x9176	# <CJK>
+0x4339	0x9709	# <CJK>
+0x433A	0x7164	# <CJK>
+0x433B	0x6CA1	# <CJK>
+0x433C	0x7709	# <CJK>
+0x433D	0x5A92	# <CJK>
+0x433E	0x9382	# <CJK>
+0x433F	0x6BCF	# <CJK>
+0x4340	0x7F8E	# <CJK>
+0x4341	0x6627	# <CJK>
+0x4342	0x5BD0	# <CJK>
+0x4343	0x59B9	# <CJK>
+0x4344	0x5A9A	# <CJK>
+0x4345	0x9580	# <CJK>
+0x4346	0x60B6	# <CJK>
+0x4347	0x5011	# <CJK>
+0x4348	0x840C	# <CJK>
+0x4349	0x8499	# <CJK>
+0x434A	0x6AAC	# <CJK>
+0x434B	0x76DF	# <CJK>
+0x434C	0x9333	# <CJK>
+0x434D	0x731B	# <CJK>
+0x434E	0x5922	# <CJK>
+0x434F	0x5B5F	# <CJK>
+0x4350	0x772F	# <CJK>
+0x4351	0x919A	# <CJK>
+0x4352	0x9761	# <CJK>
+0x4353	0x7CDC	# <CJK>
+0x4354	0x8FF7	# <CJK>
+0x4355	0x8B0E	# <CJK>
+0x4356	0x5F4C	# <CJK>
+0x4357	0x7C73	# <CJK>
+0x4358	0x79D8	# <CJK>
+0x4359	0x8993	# <CJK>
+0x435A	0x6CCC	# <CJK>
+0x435B	0x871C	# <CJK>
+0x435C	0x5BC6	# <CJK>
+0x435D	0x5E42	# <CJK>
+0x435E	0x68C9	# <CJK>
+0x435F	0x7720	# <CJK>
+0x4360	0x7DBF	# <CJK>
+0x4361	0x5195	# <CJK>
+0x4362	0x514D	# <CJK>
+0x4363	0x52C9	# <CJK>
+0x4364	0x5A29	# <CJK>
+0x4365	0x7DEC	# <CJK>
+0x4366	0x9762	# <CJK>
+0x4367	0x82D7	# <CJK>
+0x4368	0x63CF	# <CJK>
+0x4369	0x7784	# <CJK>
+0x436A	0x85D0	# <CJK>
+0x436B	0x79D2	# <CJK>
+0x436C	0x6E3A	# <CJK>
+0x436D	0x5EDF	# <CJK>
+0x436E	0x5999	# <CJK>
+0x436F	0x8511	# <CJK>
+0x4370	0x6EC5	# <CJK>
+0x4371	0x6C11	# <CJK>
+0x4372	0x62BF	# <CJK>
+0x4373	0x76BF	# <CJK>
+0x4374	0x654F	# <CJK>
+0x4375	0x61AB	# <CJK>
+0x4376	0x95A9	# <CJK>
+0x4377	0x660E	# <CJK>
+0x4378	0x879F	# <CJK>
+0x4379	0x9CF4	# <CJK>
+0x437A	0x9298	# <CJK>
+0x437B	0x540D	# <CJK>
+0x437C	0x547D	# <CJK>
+0x437D	0x8B2C	# <CJK>
+0x437E	0x6478	# <CJK>
+0x4421	0x6479	# <CJK>
+0x4422	0x8611	# <CJK>
+0x4423	0x6A21	# <CJK>
+0x4424	0x819C	# <CJK>
+0x4425	0x78E8	# <CJK>
+0x4426	0x6469	# <CJK>
+0x4427	0x9B54	# <CJK>
+0x4428	0x62B9	# <CJK>
+0x4429	0x672B	# <CJK>
+0x442A	0x83AB	# <CJK>
+0x442B	0x58A8	# <CJK>
+0x442C	0x9ED8	# <CJK>
+0x442D	0x6CAB	# <CJK>
+0x442E	0x6F20	# <CJK>
+0x442F	0x5BDE	# <CJK>
+0x4430	0x964C	# <CJK>
+0x4431	0x8B00	# <CJK>
+0x4432	0x725F	# <CJK>
+0x4433	0x67D0	# <CJK>
+0x4434	0x62C7	# <CJK>
+0x4435	0x7261	# <CJK>
+0x4436	0x755D	# <CJK>
+0x4437	0x59C6	# <CJK>
+0x4438	0x6BCD	# <CJK>
+0x4439	0x5893	# <CJK>
+0x443A	0x66AE	# <CJK>
+0x443B	0x5E55	# <CJK>
+0x443C	0x52DF	# <CJK>
+0x443D	0x6155	# <CJK>
+0x443E	0x6728	# <CJK>
+0x443F	0x76EE	# <CJK>
+0x4440	0x7766	# <CJK>
+0x4441	0x7267	# <CJK>
+0x4442	0x7A46	# <CJK>
+0x4443	0x62FF	# <CJK>
+0x4444	0x54EA	# <CJK>
+0x4445	0x5450	# <CJK>
+0x4446	0x9209	# <CJK>
+0x4447	0x90A3	# <CJK>
+0x4448	0x5A1C	# <CJK>
+0x4449	0x7D0D	# <CJK>
+0x444A	0x6C16	# <CJK>
+0x444B	0x4E43	# <CJK>
+0x444C	0x5976	# <CJK>
+0x444D	0x8010	# <CJK>
+0x444E	0x5948	# <CJK>
+0x444F	0x5357	# <CJK>
+0x4450	0x7537	# <CJK>
+0x4451	0x96E3	# <CJK>
+0x4452	0x56CA	# <CJK>
+0x4453	0x6493	# <CJK>
+0x4454	0x8166	# <CJK>
+0x4455	0x60F1	# <CJK>
+0x4456	0x9B27	# <CJK>
+0x4457	0x6DD6	# <CJK>
+0x4458	0x5462	# <CJK>
+0x4459	0x9912	# <CJK>
+0x445A	0x5185	# <CJK>
+0x445B	0x5AE9	# <CJK>
+0x445C	0x80FD	# <CJK>
+0x445D	0x59AE	# <CJK>
+0x445E	0x9713	# <CJK>
+0x445F	0x502A	# <CJK>
+0x4460	0x6CE5	# <CJK>
+0x4461	0x5C3C	# <CJK>
+0x4462	0x64EC	# <CJK>
+0x4463	0x4F60	# <CJK>
+0x4464	0x533F	# <CJK>
+0x4465	0x81A9	# <CJK>
+0x4466	0x9006	# <CJK>
+0x4467	0x6EBA	# <CJK>
+0x4468	0x852B	# <CJK>
+0x4469	0x62C8	# <CJK>
+0x446A	0x5E74	# <CJK>
+0x446B	0x78BE	# <CJK>
+0x446C	0x6506	# <CJK>
+0x446D	0x637B	# <CJK>
+0x446E	0x5FF5	# <CJK>
+0x446F	0x5A18	# <CJK>
+0x4470	0x91C0	# <CJK>
+0x4471	0x9CE5	# <CJK>
+0x4472	0x5C3F	# <CJK>
+0x4473	0x634F	# <CJK>
+0x4474	0x8076	# <CJK>
+0x4475	0x5B7D	# <CJK>
+0x4476	0x5699	# <CJK>
+0x4477	0x9477	# <CJK>
+0x4478	0x93B3	# <CJK>
+0x4479	0x6D85	# <CJK>
+0x447A	0x60A8	# <CJK>
+0x447B	0x6AB8	# <CJK>
+0x447C	0x7370	# <CJK>
+0x447D	0x51DD	# <CJK>
+0x447E	0x5BE7	# <CJK>
+0x4521	0x64F0	# <CJK>
+0x4522	0x6FD8	# <CJK>
+0x4523	0x725B	# <CJK>
+0x4524	0x626D	# <CJK>
+0x4525	0x9215	# <CJK>
+0x4526	0x7D10	# <CJK>
+0x4527	0x81BF	# <CJK>
+0x4528	0x6FC3	# <CJK>
+0x4529	0x8FB2	# <CJK>
+0x452A	0x5F04	# <CJK>
+0x452B	0x5974	# <CJK>
+0x452C	0x52AA	# <CJK>
+0x452D	0x6012	# <CJK>
+0x452E	0x5973	# <CJK>
+0x452F	0x6696	# <CJK>
+0x4530	0x8650	# <CJK>
+0x4531	0x7627	# <CJK>
+0x4532	0x632A	# <CJK>
+0x4533	0x61E6	# <CJK>
+0x4534	0x7CEF	# <CJK>
+0x4535	0x8AFE	# <CJK>
+0x4536	0x54E6	# <CJK>
+0x4537	0x6B50	# <CJK>
+0x4538	0x9DD7	# <CJK>
+0x4539	0x6BC6	# <CJK>
+0x453A	0x85D5	# <CJK>
+0x453B	0x5614	# <CJK>
+0x453C	0x5076	# <CJK>
+0x453D	0x6F1A	# <CJK>
+0x453E	0x556A	# <CJK>
+0x453F	0x8DB4	# <CJK>
+0x4540	0x722C	# <CJK>
+0x4541	0x5E15	# <CJK>
+0x4542	0x6015	# <CJK>
+0x4543	0x7436	# <CJK>
+0x4544	0x62CD	# <CJK>
+0x4545	0x6392	# <CJK>
+0x4546	0x724C	# <CJK>
+0x4547	0x5F98	# <CJK>
+0x4548	0x6E43	# <CJK>
+0x4549	0x6D3E	# <CJK>
+0x454A	0x6500	# <CJK>
+0x454B	0x6F58	# <CJK>
+0x454C	0x76E4	# <CJK>
+0x454D	0x78D0	# <CJK>
+0x454E	0x76FC	# <CJK>
+0x454F	0x7554	# <CJK>
+0x4550	0x5224	# <CJK>
+0x4551	0x53DB	# <CJK>
+0x4552	0x4E53	# <CJK>
+0x4553	0x9F90	# <CJK>
+0x4554	0x65C1	# <CJK>
+0x4555	0x802A	# <CJK>
+0x4556	0x80D6	# <CJK>
+0x4557	0x629B	# <CJK>
+0x4558	0x5486	# <CJK>
+0x4559	0x5228	# <CJK>
+0x455A	0x70AE	# <CJK>
+0x455B	0x888D	# <CJK>
+0x455C	0x8DD1	# <CJK>
+0x455D	0x6CE1	# <CJK>
+0x455E	0x5478	# <CJK>
+0x455F	0x80DA	# <CJK>
+0x4560	0x57F9	# <CJK>
+0x4561	0x88F4	# <CJK>
+0x4562	0x8CE0	# <CJK>
+0x4563	0x966A	# <CJK>
+0x4564	0x914D	# <CJK>
+0x4565	0x4F69	# <CJK>
+0x4566	0x6C9B	# <CJK>
+0x4567	0x5674	# <CJK>
+0x4568	0x76C6	# <CJK>
+0x4569	0x7830	# <CJK>
+0x456A	0x62A8	# <CJK>
+0x456B	0x70F9	# <CJK>
+0x456C	0x6F8E	# <CJK>
+0x456D	0x5F6D	# <CJK>
+0x456E	0x84EC	# <CJK>
+0x456F	0x68DA	# <CJK>
+0x4570	0x787C	# <CJK>
+0x4571	0x7BF7	# <CJK>
+0x4572	0x81A8	# <CJK>
+0x4573	0x670B	# <CJK>
+0x4574	0x9D6C	# <CJK>
+0x4575	0x6367	# <CJK>
+0x4576	0x78B0	# <CJK>
+0x4577	0x576F	# <CJK>
+0x4578	0x7812	# <CJK>
+0x4579	0x9739	# <CJK>
+0x457A	0x6279	# <CJK>
+0x457B	0x62AB	# <CJK>
+0x457C	0x5288	# <CJK>
+0x457D	0x7435	# <CJK>
+0x457E	0x6BD7	# <CJK>
+0x4621	0x5564	# <CJK>
+0x4622	0x813E	# <CJK>
+0x4623	0x75B2	# <CJK>
+0x4624	0x76AE	# <CJK>
+0x4625	0x5339	# <CJK>
+0x4626	0x75DE	# <CJK>
+0x4627	0x50FB	# <CJK>
+0x4628	0x5C41	# <CJK>
+0x4629	0x8B6C	# <CJK>
+0x462A	0x7BC7	# <CJK>
+0x462B	0x504F	# <CJK>
+0x462C	0x7247	# <CJK>
+0x462D	0x9A19	# <CJK>
+0x462E	0x98C4	# <CJK>
+0x462F	0x6F02	# <CJK>
+0x4630	0x74E2	# <CJK>
+0x4631	0x7968	# <CJK>
+0x4632	0x6487	# <CJK>
+0x4633	0x77A5	# <CJK>
+0x4634	0x62FC	# <CJK>
+0x4635	0x983B	# <CJK>
+0x4636	0x8CA7	# <CJK>
+0x4637	0x54C1	# <CJK>
+0x4638	0x8058	# <CJK>
+0x4639	0x4E52	# <CJK>
+0x463A	0x576A	# <CJK>
+0x463B	0x860B	# <CJK>
+0x463C	0x840D	# <CJK>
+0x463D	0x5E73	# <CJK>
+0x463E	0x6191	# <CJK>
+0x463F	0x74F6	# <CJK>
+0x4640	0x8A55	# <CJK>
+0x4641	0x5C4F	# <CJK>
+0x4642	0x5761	# <CJK>
+0x4643	0x6F51	# <CJK>
+0x4644	0x9817	# <CJK>
+0x4645	0x5A46	# <CJK>
+0x4646	0x7834	# <CJK>
+0x4647	0x9B44	# <CJK>
+0x4648	0x8FEB	# <CJK>
+0x4649	0x7C95	# <CJK>
+0x464A	0x5256	# <CJK>
+0x464B	0x64B2	# <CJK>
+0x464C	0x92EA	# <CJK>
+0x464D	0x50D5	# <CJK>
+0x464E	0x8386	# <CJK>
+0x464F	0x8461	# <CJK>
+0x4650	0x83E9	# <CJK>
+0x4651	0x84B2	# <CJK>
+0x4652	0x57D4	# <CJK>
+0x4653	0x6A38	# <CJK>
+0x4654	0x5703	# <CJK>
+0x4655	0x666E	# <CJK>
+0x4656	0x6D66	# <CJK>
+0x4657	0x8B5C	# <CJK>
+0x4658	0x66DD	# <CJK>
+0x4659	0x7011	# <CJK>
+0x465A	0x671F	# <CJK>
+0x465B	0x6B3A	# <CJK>
+0x465C	0x68F2	# <CJK>
+0x465D	0x621A	# <CJK>
+0x465E	0x59BB	# <CJK>
+0x465F	0x4E03	# <CJK>
+0x4660	0x51C4	# <CJK>
+0x4661	0x6F06	# <CJK>
+0x4662	0x67D2	# <CJK>
+0x4663	0x6C8F	# <CJK>
+0x4664	0x5176	# <CJK>
+0x4665	0x68CB	# <CJK>
+0x4666	0x5947	# <CJK>
+0x4667	0x6B67	# <CJK>
+0x4668	0x7566	# <CJK>
+0x4669	0x5D0E	# <CJK>
+0x466A	0x81CD	# <CJK>
+0x466B	0x9F4A	# <CJK>
+0x466C	0x65D7	# <CJK>
+0x466D	0x7948	# <CJK>
+0x466E	0x7941	# <CJK>
+0x466F	0x9A0E	# <CJK>
+0x4670	0x8D77	# <CJK>
+0x4671	0x8C48	# <CJK>
+0x4672	0x4E5E	# <CJK>
+0x4673	0x4F01	# <CJK>
+0x4674	0x5553	# <CJK>
+0x4675	0x5951	# <CJK>
+0x4676	0x780C	# <CJK>
+0x4677	0x5668	# <CJK>
+0x4678	0x6C23	# <CJK>
+0x4679	0x8FC4	# <CJK>
+0x467A	0x68C4	# <CJK>
+0x467B	0x6C7D	# <CJK>
+0x467C	0x6CE3	# <CJK>
+0x467D	0x8A16	# <CJK>
+0x467E	0x6390	# <CJK>
+0x4721	0x6070	# <CJK>
+0x4722	0x6D3D	# <CJK>
+0x4723	0x727D	# <CJK>
+0x4724	0x6266	# <CJK>
+0x4725	0x91FA	# <CJK>
+0x4726	0x925B	# <CJK>
+0x4727	0x5343	# <CJK>
+0x4728	0x9077	# <CJK>
+0x4729	0x7C3D	# <CJK>
+0x472A	0x4EDF	# <CJK>
+0x472B	0x8B19	# <CJK>
+0x472C	0x4E7E	# <CJK>
+0x472D	0x9ED4	# <CJK>
+0x472E	0x9322	# <CJK>
+0x472F	0x9257	# <CJK>
+0x4730	0x524D	# <CJK>
+0x4731	0x6F5B	# <CJK>
+0x4732	0x9063	# <CJK>
+0x4733	0x6DFA	# <CJK>
+0x4734	0x8B74	# <CJK>
+0x4735	0x5879	# <CJK>
+0x4736	0x5D4C	# <CJK>
+0x4737	0x6B20	# <CJK>
+0x4738	0x6B49	# <CJK>
+0x4739	0x69CD	# <CJK>
+0x473A	0x55C6	# <CJK>
+0x473B	0x8154	# <CJK>
+0x473C	0x7F8C	# <CJK>
+0x473D	0x58BB	# <CJK>
+0x473E	0x8594	# <CJK>
+0x473F	0x5F3A	# <CJK>
+0x4740	0x6436	# <CJK>
+0x4741	0x6A47	# <CJK>
+0x4742	0x936C	# <CJK>
+0x4743	0x6572	# <CJK>
+0x4744	0x6084	# <CJK>
+0x4745	0x6A4B	# <CJK>
+0x4746	0x77A7	# <CJK>
+0x4747	0x55AC	# <CJK>
+0x4748	0x50D1	# <CJK>
+0x4749	0x5DE7	# <CJK>
+0x474A	0x9798	# <CJK>
+0x474B	0x64AC	# <CJK>
+0x474C	0x7FF9	# <CJK>
+0x474D	0x5CED	# <CJK>
+0x474E	0x4FCF	# <CJK>
+0x474F	0x7AC5	# <CJK>
+0x4750	0x5207	# <CJK>
+0x4751	0x8304	# <CJK>
+0x4752	0x4E14	# <CJK>
+0x4753	0x602F	# <CJK>
+0x4754	0x7ACA	# <CJK>
+0x4755	0x6B3D	# <CJK>
+0x4756	0x4FB5	# <CJK>
+0x4757	0x89AA	# <CJK>
+0x4758	0x79E6	# <CJK>
+0x4759	0x7434	# <CJK>
+0x475A	0x52E4	# <CJK>
+0x475B	0x82B9	# <CJK>
+0x475C	0x64D2	# <CJK>
+0x475D	0x79BD	# <CJK>
+0x475E	0x5BE2	# <CJK>
+0x475F	0x6C81	# <CJK>
+0x4760	0x9752	# <CJK>
+0x4761	0x8F15	# <CJK>
+0x4762	0x6C2B	# <CJK>
+0x4763	0x50BE	# <CJK>
+0x4764	0x537F	# <CJK>
+0x4765	0x6E05	# <CJK>
+0x4766	0x64CE	# <CJK>
+0x4767	0x6674	# <CJK>
+0x4768	0x6C30	# <CJK>
+0x4769	0x60C5	# <CJK>
+0x476A	0x9803	# <CJK>
+0x476B	0x8ACB	# <CJK>
+0x476C	0x6176	# <CJK>
+0x476D	0x74CA	# <CJK>
+0x476E	0x7AAE	# <CJK>
+0x476F	0x79CB	# <CJK>
+0x4770	0x4E18	# <CJK>
+0x4771	0x90B1	# <CJK>
+0x4772	0x7403	# <CJK>
+0x4773	0x6C42	# <CJK>
+0x4774	0x56DA	# <CJK>
+0x4775	0x914B	# <CJK>
+0x4776	0x6CC5	# <CJK>
+0x4777	0x8DA8	# <CJK>
+0x4778	0x5340	# <CJK>
+0x4779	0x86C6	# <CJK>
+0x477A	0x66F2	# <CJK>
+0x477B	0x8EC0	# <CJK>
+0x477C	0x5C48	# <CJK>
+0x477D	0x9A45	# <CJK>
+0x477E	0x6E20	# <CJK>
+0x4821	0x53D6	# <CJK>
+0x4822	0x5A36	# <CJK>
+0x4823	0x9F72	# <CJK>
+0x4824	0x8DA3	# <CJK>
+0x4825	0x53BB	# <CJK>
+0x4826	0x5708	# <CJK>
+0x4827	0x9874	# <CJK>
+0x4828	0x6B0A	# <CJK>
+0x4829	0x919B	# <CJK>
+0x482A	0x6CC9	# <CJK>
+0x482B	0x5168	# <CJK>
+0x482C	0x75CA	# <CJK>
+0x482D	0x62F3	# <CJK>
+0x482E	0x72AC	# <CJK>
+0x482F	0x5238	# <CJK>
+0x4830	0x52F8	# <CJK>
+0x4831	0x7F3A	# <CJK>
+0x4832	0x7094	# <CJK>
+0x4833	0x7638	# <CJK>
+0x4834	0x5374	# <CJK>
+0x4835	0x9D72	# <CJK>
+0x4836	0x69B7	# <CJK>
+0x4837	0x78BA	# <CJK>
+0x4838	0x96C0	# <CJK>
+0x4839	0x88D9	# <CJK>
+0x483A	0x7FA4	# <CJK>
+0x483B	0x7136	# <CJK>
+0x483C	0x71C3	# <CJK>
+0x483D	0x5189	# <CJK>
+0x483E	0x67D3	# <CJK>
+0x483F	0x74E4	# <CJK>
+0x4840	0x58E4	# <CJK>
+0x4841	0x6518	# <CJK>
+0x4842	0x56B7	# <CJK>
+0x4843	0x8B93	# <CJK>
+0x4844	0x9952	# <CJK>
+0x4845	0x64FE	# <CJK>
+0x4846	0x7E5E	# <CJK>
+0x4847	0x60F9	# <CJK>
+0x4848	0x71B1	# <CJK>
+0x4849	0x58EC	# <CJK>
+0x484A	0x4EC1	# <CJK>
+0x484B	0x4EBA	# <CJK>
+0x484C	0x5FCD	# <CJK>
+0x484D	0x97CC	# <CJK>
+0x484E	0x4EFB	# <CJK>
+0x484F	0x8A8D	# <CJK>
+0x4850	0x5203	# <CJK>
+0x4851	0x598A	# <CJK>
+0x4852	0x7D09	# <CJK>
+0x4853	0x6254	# <CJK>
+0x4854	0x4ECD	# <CJK>
+0x4855	0x65E5	# <CJK>
+0x4856	0x620E	# <CJK>
+0x4857	0x8338	# <CJK>
+0x4858	0x84C9	# <CJK>
+0x4859	0x69AE	# <CJK>
+0x485A	0x878D	# <CJK>
+0x485B	0x7194	# <CJK>
+0x485C	0x6EB6	# <CJK>
+0x485D	0x5BB9	# <CJK>
+0x485E	0x7D68	# <CJK>
+0x485F	0x5197	# <CJK>
+0x4860	0x63C9	# <CJK>
+0x4861	0x67D4	# <CJK>
+0x4862	0x8089	# <CJK>
+0x4863	0x8339	# <CJK>
+0x4864	0x8815	# <CJK>
+0x4865	0x5112	# <CJK>
+0x4866	0x5B7A	# <CJK>
+0x4867	0x5982	# <CJK>
+0x4868	0x8FB1	# <CJK>
+0x4869	0x4E73	# <CJK>
+0x486A	0x6C5D	# <CJK>
+0x486B	0x5165	# <CJK>
+0x486C	0x8925	# <CJK>
+0x486D	0x8EDF	# <CJK>
+0x486E	0x962E	# <CJK>
+0x486F	0x854A	# <CJK>
+0x4870	0x745E	# <CJK>
+0x4871	0x92ED	# <CJK>
+0x4872	0x958F	# <CJK>
+0x4873	0x6F64	# <CJK>
+0x4874	0x82E5	# <CJK>
+0x4875	0x5F31	# <CJK>
+0x4876	0x6492	# <CJK>
+0x4877	0x7051	# <CJK>
+0x4878	0x85A9	# <CJK>
+0x4879	0x816E	# <CJK>
+0x487A	0x9C13	# <CJK>
+0x487B	0x585E	# <CJK>
+0x487C	0x8CFD	# <CJK>
+0x487D	0x4E09	# <CJK>
+0x487E	0x53C1	# <CJK>
+0x4921	0x5098	# <CJK>
+0x4922	0x6563	# <CJK>
+0x4923	0x6851	# <CJK>
+0x4924	0x55D3	# <CJK>
+0x4925	0x55AA	# <CJK>
+0x4926	0x6414	# <CJK>
+0x4927	0x9A37	# <CJK>
+0x4928	0x6383	# <CJK>
+0x4929	0x5AC2	# <CJK>
+0x492A	0x745F	# <CJK>
+0x492B	0x8272	# <CJK>
+0x492C	0x6F80	# <CJK>
+0x492D	0x68EE	# <CJK>
+0x492E	0x50E7	# <CJK>
+0x492F	0x838E	# <CJK>
+0x4930	0x7802	# <CJK>
+0x4931	0x6BBA	# <CJK>
+0x4932	0x5239	# <CJK>
+0x4933	0x6C99	# <CJK>
+0x4934	0x7D17	# <CJK>
+0x4935	0x50BB	# <CJK>
+0x4936	0x5565	# <CJK>
+0x4937	0x715E	# <CJK>
+0x4938	0x7BE9	# <CJK>
+0x4939	0x66EC	# <CJK>
+0x493A	0x73CA	# <CJK>
+0x493B	0x82EB	# <CJK>
+0x493C	0x6749	# <CJK>
+0x493D	0x5C71	# <CJK>
+0x493E	0x5220	# <CJK>
+0x493F	0x717D	# <CJK>
+0x4940	0x886B	# <CJK>
+0x4941	0x9583	# <CJK>
+0x4942	0x965D	# <CJK>
+0x4943	0x64C5	# <CJK>
+0x4944	0x8D0D	# <CJK>
+0x4945	0x81B3	# <CJK>
+0x4946	0x5584	# <CJK>
+0x4947	0x6C55	# <CJK>
+0x4948	0x6247	# <CJK>
+0x4949	0x7E55	# <CJK>
+0x494A	0x5892	# <CJK>
+0x494B	0x50B7	# <CJK>
+0x494C	0x5546	# <CJK>
+0x494D	0x8CDE	# <CJK>
+0x494E	0x664C	# <CJK>
+0x494F	0x4E0A	# <CJK>
+0x4950	0x5C1A	# <CJK>
+0x4951	0x88F3	# <CJK>
+0x4952	0x68A2	# <CJK>
+0x4953	0x634E	# <CJK>
+0x4954	0x7A0D	# <CJK>
+0x4955	0x71D2	# <CJK>
+0x4956	0x828D	# <CJK>
+0x4957	0x52FA	# <CJK>
+0x4958	0x97F6	# <CJK>
+0x4959	0x5C11	# <CJK>
+0x495A	0x54E8	# <CJK>
+0x495B	0x90B5	# <CJK>
+0x495C	0x7D39	# <CJK>
+0x495D	0x5962	# <CJK>
+0x495E	0x8CD2	# <CJK>
+0x495F	0x86C7	# <CJK>
+0x4960	0x820C	# <CJK>
+0x4961	0x6368	# <CJK>
+0x4962	0x8D66	# <CJK>
+0x4963	0x651D	# <CJK>
+0x4964	0x5C04	# <CJK>
+0x4965	0x61FE	# <CJK>
+0x4966	0x6D89	# <CJK>
+0x4967	0x793E	# <CJK>
+0x4968	0x8A2D	# <CJK>
+0x4969	0x7837	# <CJK>
+0x496A	0x7533	# <CJK>
+0x496B	0x547B	# <CJK>
+0x496C	0x4F38	# <CJK>
+0x496D	0x8EAB	# <CJK>
+0x496E	0x6DF1	# <CJK>
+0x496F	0x5A20	# <CJK>
+0x4970	0x7D33	# <CJK>
+0x4971	0x795E	# <CJK>
+0x4972	0x6C88	# <CJK>
+0x4973	0x5BE9	# <CJK>
+0x4974	0x5B38	# <CJK>
+0x4975	0x751A	# <CJK>
+0x4976	0x814E	# <CJK>
+0x4977	0x614E	# <CJK>
+0x4978	0x6EF2	# <CJK>
+0x4979	0x8072	# <CJK>
+0x497A	0x751F	# <CJK>
+0x497B	0x7525	# <CJK>
+0x497C	0x7272	# <CJK>
+0x497D	0x5347	# <CJK>
+0x497E	0x7E69	# <CJK>
+0x4A21	0x7701	# <CJK>
+0x4A22	0x76DB	# <CJK>
+0x4A23	0x5269	# <CJK>
+0x4A24	0x52DD	# <CJK>
+0x4A25	0x8056	# <CJK>
+0x4A26	0x5E2B	# <CJK>
+0x4A27	0x5931	# <CJK>
+0x4A28	0x7345	# <CJK>
+0x4A29	0x65BD	# <CJK>
+0x4A2A	0x6FD5	# <CJK>
+0x4A2B	0x8A69	# <CJK>
+0x4A2C	0x5C38	# <CJK>
+0x4A2D	0x8671	# <CJK>
+0x4A2E	0x5341	# <CJK>
+0x4A2F	0x77F3	# <CJK>
+0x4A30	0x62FE	# <CJK>
+0x4A31	0x6642	# <CJK>
+0x4A32	0x4EC0	# <CJK>
+0x4A33	0x98DF	# <CJK>
+0x4A34	0x8755	# <CJK>
+0x4A35	0x5BE6	# <CJK>
+0x4A36	0x8B58	# <CJK>
+0x4A37	0x53F2	# <CJK>
+0x4A38	0x77E2	# <CJK>
+0x4A39	0x4F7F	# <CJK>
+0x4A3A	0x5C4E	# <CJK>
+0x4A3B	0x99DB	# <CJK>
+0x4A3C	0x59CB	# <CJK>
+0x4A3D	0x5F0F	# <CJK>
+0x4A3E	0x793A	# <CJK>
+0x4A3F	0x58EB	# <CJK>
+0x4A40	0x4E16	# <CJK>
+0x4A41	0x67FF	# <CJK>
+0x4A42	0x4E8B	# <CJK>
+0x4A43	0x62ED	# <CJK>
+0x4A44	0x8A93	# <CJK>
+0x4A45	0x901D	# <CJK>
+0x4A46	0x52E2	# <CJK>
+0x4A47	0x662F	# <CJK>
+0x4A48	0x55DC	# <CJK>
+0x4A49	0x566C	# <CJK>
+0x4A4A	0x9069	# <CJK>
+0x4A4B	0x4ED5	# <CJK>
+0x4A4C	0x4F8D	# <CJK>
+0x4A4D	0x91CB	# <CJK>
+0x4A4E	0x98FE	# <CJK>
+0x4A4F	0x6C0F	# <CJK>
+0x4A50	0x5E02	# <CJK>
+0x4A51	0x6043	# <CJK>
+0x4A52	0x5BA4	# <CJK>
+0x4A53	0x8996	# <CJK>
+0x4A54	0x8A66	# <CJK>
+0x4A55	0x6536	# <CJK>
+0x4A56	0x624B	# <CJK>
+0x4A57	0x9996	# <CJK>
+0x4A58	0x5B88	# <CJK>
+0x4A59	0x58FD	# <CJK>
+0x4A5A	0x6388	# <CJK>
+0x4A5B	0x552E	# <CJK>
+0x4A5C	0x53D7	# <CJK>
+0x4A5D	0x7626	# <CJK>
+0x4A5E	0x7378	# <CJK>
+0x4A5F	0x852C	# <CJK>
+0x4A60	0x6A1E	# <CJK>
+0x4A61	0x68B3	# <CJK>
+0x4A62	0x6B8A	# <CJK>
+0x4A63	0x6292	# <CJK>
+0x4A64	0x8F38	# <CJK>
+0x4A65	0x53D4	# <CJK>
+0x4A66	0x8212	# <CJK>
+0x4A67	0x6DD1	# <CJK>
+0x4A68	0x758F	# <CJK>
+0x4A69	0x66F8	# <CJK>
+0x4A6A	0x8D16	# <CJK>
+0x4A6B	0x5B70	# <CJK>
+0x4A6C	0x719F	# <CJK>
+0x4A6D	0x85AF	# <CJK>
+0x4A6E	0x6691	# <CJK>
+0x4A6F	0x66D9	# <CJK>
+0x4A70	0x7F72	# <CJK>
+0x4A71	0x8700	# <CJK>
+0x4A72	0x9ECD	# <CJK>
+0x4A73	0x9F20	# <CJK>
+0x4A74	0x5C6C	# <CJK>
+0x4A75	0x8853	# <CJK>
+0x4A76	0x8FF0	# <CJK>
+0x4A77	0x6A39	# <CJK>
+0x4A78	0x675F	# <CJK>
+0x4A79	0x620D	# <CJK>
+0x4A7A	0x7AEA	# <CJK>
+0x4A7B	0x5885	# <CJK>
+0x4A7C	0x5EB6	# <CJK>
+0x4A7D	0x6578	# <CJK>
+0x4A7E	0x6F31	# <CJK>
+0x4B21	0x6055	# <CJK>
+0x4B22	0x5237	# <CJK>
+0x4B23	0x800D	# <CJK>
+0x4B24	0x6454	# <CJK>
+0x4B25	0x8870	# <CJK>
+0x4B26	0x7529	# <CJK>
+0x4B27	0x5E25	# <CJK>
+0x4B28	0x6813	# <CJK>
+0x4B29	0x62F4	# <CJK>
+0x4B2A	0x971C	# <CJK>
+0x4B2B	0x96D9	# <CJK>
+0x4B2C	0x723D	# <CJK>
+0x4B2D	0x8AB0	# <CJK>
+0x4B2E	0x6C34	# <CJK>
+0x4B2F	0x7761	# <CJK>
+0x4B30	0x7A0E	# <CJK>
+0x4B31	0x542E	# <CJK>
+0x4B32	0x77AC	# <CJK>
+0x4B33	0x9806	# <CJK>
+0x4B34	0x821C	# <CJK>
+0x4B35	0x8AAC	# <CJK>
+0x4B36	0x78A9	# <CJK>
+0x4B37	0x6714	# <CJK>
+0x4B38	0x720D	# <CJK>
+0x4B39	0x65AF	# <CJK>
+0x4B3A	0x6495	# <CJK>
+0x4B3B	0x5636	# <CJK>
+0x4B3C	0x601D	# <CJK>
+0x4B3D	0x79C1	# <CJK>
+0x4B3E	0x53F8	# <CJK>
+0x4B3F	0x7D72	# <CJK>
+0x4B40	0x6B7B	# <CJK>
+0x4B41	0x8086	# <CJK>
+0x4B42	0x5BFA	# <CJK>
+0x4B43	0x55E3	# <CJK>
+0x4B44	0x56DB	# <CJK>
+0x4B45	0x4F3A	# <CJK>
+0x4B46	0x4F3C	# <CJK>
+0x4B47	0x98FC	# <CJK>
+0x4B48	0x5DF3	# <CJK>
+0x4B49	0x9B06	# <CJK>
+0x4B4A	0x8073	# <CJK>
+0x4B4B	0x616B	# <CJK>
+0x4B4C	0x980C	# <CJK>
+0x4B4D	0x9001	# <CJK>
+0x4B4E	0x5B8B	# <CJK>
+0x4B4F	0x8A1F	# <CJK>
+0x4B50	0x8AA6	# <CJK>
+0x4B51	0x641C	# <CJK>
+0x4B52	0x8258	# <CJK>
+0x4B53	0x64FB	# <CJK>
+0x4B54	0x55FD	# <CJK>
+0x4B55	0x8607	# <CJK>
+0x4B56	0x9165	# <CJK>
+0x4B57	0x4FD7	# <CJK>
+0x4B58	0x7D20	# <CJK>
+0x4B59	0x901F	# <CJK>
+0x4B5A	0x7C9F	# <CJK>
+0x4B5B	0x50F3	# <CJK>
+0x4B5C	0x5851	# <CJK>
+0x4B5D	0x6EAF	# <CJK>
+0x4B5E	0x5BBF	# <CJK>
+0x4B5F	0x8A34	# <CJK>
+0x4B60	0x8085	# <CJK>
+0x4B61	0x9178	# <CJK>
+0x4B62	0x849C	# <CJK>
+0x4B63	0x7B97	# <CJK>
+0x4B64	0x96D6	# <CJK>
+0x4B65	0x968B	# <CJK>
+0x4B66	0x96A8	# <CJK>
+0x4B67	0x7D8F	# <CJK>
+0x4B68	0x9AD3	# <CJK>
+0x4B69	0x788E	# <CJK>
+0x4B6A	0x6B72	# <CJK>
+0x4B6B	0x7A57	# <CJK>
+0x4B6C	0x9042	# <CJK>
+0x4B6D	0x96A7	# <CJK>
+0x4B6E	0x795F	# <CJK>
+0x4B6F	0x5B6B	# <CJK>
+0x4B70	0x640D	# <CJK>
+0x4B71	0x7B0B	# <CJK>
+0x4B72	0x84D1	# <CJK>
+0x4B73	0x68AD	# <CJK>
+0x4B74	0x5506	# <CJK>
+0x4B75	0x7E2E	# <CJK>
+0x4B76	0x7463	# <CJK>
+0x4B77	0x7D22	# <CJK>
+0x4B78	0x9396	# <CJK>
+0x4B79	0x6240	# <CJK>
+0x4B7A	0x584C	# <CJK>
+0x4B7B	0x4ED6	# <CJK>
+0x4B7C	0x5B83	# <CJK>
+0x4B7D	0x5979	# <CJK>
+0x4B7E	0x5854	# <CJK>
+0x4C21	0x737A	# <CJK>
+0x4C22	0x64BB	# <CJK>
+0x4C23	0x8E4B	# <CJK>
+0x4C24	0x8E0F	# <CJK>
+0x4C25	0x80CE	# <CJK>
+0x4C26	0x82D4	# <CJK>
+0x4C27	0x62AC	# <CJK>
+0x4C28	0x81FA	# <CJK>
+0x4C29	0x6CF0	# <CJK>
+0x4C2A	0x915E	# <CJK>
+0x4C2B	0x592A	# <CJK>
+0x4C2C	0x614B	# <CJK>
+0x4C2D	0x6C70	# <CJK>
+0x4C2E	0x574D	# <CJK>
+0x4C2F	0x6524	# <CJK>
+0x4C30	0x8CAA	# <CJK>
+0x4C31	0x7671	# <CJK>
+0x4C32	0x7058	# <CJK>
+0x4C33	0x58C7	# <CJK>
+0x4C34	0x6A80	# <CJK>
+0x4C35	0x75F0	# <CJK>
+0x4C36	0x6F6D	# <CJK>
+0x4C37	0x8B5A	# <CJK>
+0x4C38	0x8AC7	# <CJK>
+0x4C39	0x5766	# <CJK>
+0x4C3A	0x6BEF	# <CJK>
+0x4C3B	0x8892	# <CJK>
+0x4C3C	0x78B3	# <CJK>
+0x4C3D	0x63A2	# <CJK>
+0x4C3E	0x5606	# <CJK>
+0x4C3F	0x70AD	# <CJK>
+0x4C40	0x6E6F	# <CJK>
+0x4C41	0x5858	# <CJK>
+0x4C42	0x642A	# <CJK>
+0x4C43	0x5802	# <CJK>
+0x4C44	0x68E0	# <CJK>
+0x4C45	0x819B	# <CJK>
+0x4C46	0x5510	# <CJK>
+0x4C47	0x7CD6	# <CJK>
+0x4C48	0x5018	# <CJK>
+0x4C49	0x8EBA	# <CJK>
+0x4C4A	0x6DCC	# <CJK>
+0x4C4B	0x8D9F	# <CJK>
+0x4C4C	0x71D9	# <CJK>
+0x4C4D	0x638F	# <CJK>
+0x4C4E	0x6FE4	# <CJK>
+0x4C4F	0x6ED4	# <CJK>
+0x4C50	0x7E27	# <CJK>
+0x4C51	0x8404	# <CJK>
+0x4C52	0x6843	# <CJK>
+0x4C53	0x9003	# <CJK>
+0x4C54	0x6DD8	# <CJK>
+0x4C55	0x9676	# <CJK>
+0x4C56	0x8A0E	# <CJK>
+0x4C57	0x5957	# <CJK>
+0x4C58	0x7279	# <CJK>
+0x4C59	0x85E4	# <CJK>
+0x4C5A	0x9A30	# <CJK>
+0x4C5B	0x75BC	# <CJK>
+0x4C5C	0x8B04	# <CJK>
+0x4C5D	0x68AF	# <CJK>
+0x4C5E	0x5254	# <CJK>
+0x4C5F	0x8E22	# <CJK>
+0x4C60	0x92BB	# <CJK>
+0x4C61	0x63D0	# <CJK>
+0x4C62	0x984C	# <CJK>
+0x4C63	0x8E44	# <CJK>
+0x4C64	0x557C	# <CJK>
+0x4C65	0x9AD4	# <CJK>
+0x4C66	0x66FF	# <CJK>
+0x4C67	0x568F	# <CJK>
+0x4C68	0x60D5	# <CJK>
+0x4C69	0x6D95	# <CJK>
+0x4C6A	0x5243	# <CJK>
+0x4C6B	0x5C49	# <CJK>
+0x4C6C	0x5929	# <CJK>
+0x4C6D	0x6DFB	# <CJK>
+0x4C6E	0x586B	# <CJK>
+0x4C6F	0x7530	# <CJK>
+0x4C70	0x751C	# <CJK>
+0x4C71	0x606C	# <CJK>
+0x4C72	0x8214	# <CJK>
+0x4C73	0x8146	# <CJK>
+0x4C74	0x6311	# <CJK>
+0x4C75	0x689D	# <CJK>
+0x4C76	0x8FE2	# <CJK>
+0x4C77	0x773A	# <CJK>
+0x4C78	0x8DF3	# <CJK>
+0x4C79	0x8CBC	# <CJK>
+0x4C7A	0x9435	# <CJK>
+0x4C7B	0x5E16	# <CJK>
+0x4C7C	0x5EF3	# <CJK>
+0x4C7D	0x807D	# <CJK>
+0x4C7E	0x70F4	# <CJK>
+0x4D21	0x6C40	# <CJK>
+0x4D22	0x5EF7	# <CJK>
+0x4D23	0x505C	# <CJK>
+0x4D24	0x4EAD	# <CJK>
+0x4D25	0x5EAD	# <CJK>
+0x4D26	0x633A	# <CJK>
+0x4D27	0x8247	# <CJK>
+0x4D28	0x901A	# <CJK>
+0x4D29	0x6850	# <CJK>
+0x4D2A	0x916E	# <CJK>
+0x4D2B	0x77B3	# <CJK>
+0x4D2C	0x540C	# <CJK>
+0x4D2D	0x9285	# <CJK>
+0x4D2E	0x5F64	# <CJK>
+0x4D2F	0x7AE5	# <CJK>
+0x4D30	0x6876	# <CJK>
+0x4D31	0x6345	# <CJK>
+0x4D32	0x7B52	# <CJK>
+0x4D33	0x7D71	# <CJK>
+0x4D34	0x75DB	# <CJK>
+0x4D35	0x5077	# <CJK>
+0x4D36	0x6295	# <CJK>
+0x4D37	0x982D	# <CJK>
+0x4D38	0x900F	# <CJK>
+0x4D39	0x51F8	# <CJK>
+0x4D3A	0x79C3	# <CJK>
+0x4D3B	0x7A81	# <CJK>
+0x4D3C	0x5716	# <CJK>
+0x4D3D	0x5F92	# <CJK>
+0x4D3E	0x9014	# <CJK>
+0x4D3F	0x5857	# <CJK>
+0x4D40	0x5C60	# <CJK>
+0x4D41	0x571F	# <CJK>
+0x4D42	0x5410	# <CJK>
+0x4D43	0x5154	# <CJK>
+0x4D44	0x6E4D	# <CJK>
+0x4D45	0x5718	# <CJK>
+0x4D46	0x63A8	# <CJK>
+0x4D47	0x983D	# <CJK>
+0x4D48	0x817F	# <CJK>
+0x4D49	0x8715	# <CJK>
+0x4D4A	0x892A	# <CJK>
+0x4D4B	0x9000	# <CJK>
+0x4D4C	0x541E	# <CJK>
+0x4D4D	0x5C6F	# <CJK>
+0x4D4E	0x81C0	# <CJK>
+0x4D4F	0x62D6	# <CJK>
+0x4D50	0x6258	# <CJK>
+0x4D51	0x8131	# <CJK>
+0x4D52	0x9D15	# <CJK>
+0x4D53	0x9640	# <CJK>
+0x4D54	0x99B1	# <CJK>
+0x4D55	0x99DD	# <CJK>
+0x4D56	0x6A62	# <CJK>
+0x4D57	0x59A5	# <CJK>
+0x4D58	0x62D3	# <CJK>
+0x4D59	0x553E	# <CJK>
+0x4D5A	0x6316	# <CJK>
+0x4D5B	0x54C7	# <CJK>
+0x4D5C	0x86D9	# <CJK>
+0x4D5D	0x7AAA	# <CJK>
+0x4D5E	0x5A03	# <CJK>
+0x4D5F	0x74E6	# <CJK>
+0x4D60	0x896A	# <CJK>
+0x4D61	0x6B6A	# <CJK>
+0x4D62	0x5916	# <CJK>
+0x4D63	0x8C4C	# <CJK>
+0x4D64	0x5F4E	# <CJK>
+0x4D65	0x7063	# <CJK>
+0x4D66	0x73A9	# <CJK>
+0x4D67	0x9811	# <CJK>
+0x4D68	0x4E38	# <CJK>
+0x4D69	0x70F7	# <CJK>
+0x4D6A	0x5B8C	# <CJK>
+0x4D6B	0x7897	# <CJK>
+0x4D6C	0x633D	# <CJK>
+0x4D6D	0x665A	# <CJK>
+0x4D6E	0x7696	# <CJK>
+0x4D6F	0x60CB	# <CJK>
+0x4D70	0x5B9B	# <CJK>
+0x4D71	0x5A49	# <CJK>
+0x4D72	0x842C	# <CJK>
+0x4D73	0x8155	# <CJK>
+0x4D74	0x6C6A	# <CJK>
+0x4D75	0x738B	# <CJK>
+0x4D76	0x4EA1	# <CJK>
+0x4D77	0x6789	# <CJK>
+0x4D78	0x7DB2	# <CJK>
+0x4D79	0x5F80	# <CJK>
+0x4D7A	0x65FA	# <CJK>
+0x4D7B	0x671B	# <CJK>
+0x4D7C	0x5FD8	# <CJK>
+0x4D7D	0x5984	# <CJK>
+0x4D7E	0x5A01	# <CJK>
+0x4E21	0x5DCD	# <CJK>
+0x4E22	0x5FAE	# <CJK>
+0x4E23	0x5371	# <CJK>
+0x4E24	0x97CB	# <CJK>
+0x4E25	0x9055	# <CJK>
+0x4E26	0x6845	# <CJK>
+0x4E27	0x570D	# <CJK>
+0x4E28	0x552F	# <CJK>
+0x4E29	0x60DF	# <CJK>
+0x4E2A	0x7232	# <CJK>
+0x4E2B	0x6FF0	# <CJK>
+0x4E2C	0x7DAD	# <CJK>
+0x4E2D	0x8466	# <CJK>
+0x4E2E	0x840E	# <CJK>
+0x4E2F	0x59D4	# <CJK>
+0x4E30	0x5049	# <CJK>
+0x4E31	0x50DE	# <CJK>
+0x4E32	0x5C3E	# <CJK>
+0x4E33	0x7DEF	# <CJK>
+0x4E34	0x672A	# <CJK>
+0x4E35	0x851A	# <CJK>
+0x4E36	0x5473	# <CJK>
+0x4E37	0x754F	# <CJK>
+0x4E38	0x80C3	# <CJK>
+0x4E39	0x5582	# <CJK>
+0x4E3A	0x9B4F	# <CJK>
+0x4E3B	0x4F4D	# <CJK>
+0x4E3C	0x6E2D	# <CJK>
+0x4E3D	0x8B02	# <CJK>
+0x4E3E	0x5C09	# <CJK>
+0x4E3F	0x6170	# <CJK>
+0x4E40	0x885B	# <CJK>
+0x4E41	0x761F	# <CJK>
+0x4E42	0x6E29	# <CJK>
+0x4E43	0x868A	# <CJK>
+0x4E44	0x6587	# <CJK>
+0x4E45	0x805E	# <CJK>
+0x4E46	0x7D0B	# <CJK>
+0x4E47	0x543B	# <CJK>
+0x4E48	0x7A69	# <CJK>
+0x4E49	0x7D0A	# <CJK>
+0x4E4A	0x554F	# <CJK>
+0x4E4B	0x55E1	# <CJK>
+0x4E4C	0x7FC1	# <CJK>
+0x4E4D	0x74EE	# <CJK>
+0x4E4E	0x64BE	# <CJK>
+0x4E4F	0x8778	# <CJK>
+0x4E50	0x6E26	# <CJK>
+0x4E51	0x7AA9	# <CJK>
+0x4E52	0x6211	# <CJK>
+0x4E53	0x65A1	# <CJK>
+0x4E54	0x5367	# <CJK>
+0x4E55	0x63E1	# <CJK>
+0x4E56	0x6C83	# <CJK>
+0x4E57	0x5DEB	# <CJK>
+0x4E58	0x55DA	# <CJK>
+0x4E59	0x93A2	# <CJK>
+0x4E5A	0x70CF	# <CJK>
+0x4E5B	0x6C61	# <CJK>
+0x4E5C	0x8AA3	# <CJK>
+0x4E5D	0x5C4B	# <CJK>
+0x4E5E	0x7121	# <CJK>
+0x4E5F	0x856A	# <CJK>
+0x4E60	0x68A7	# <CJK>
+0x4E61	0x543E	# <CJK>
+0x4E62	0x5434	# <CJK>
+0x4E63	0x6BCB	# <CJK>
+0x4E64	0x6B66	# <CJK>
+0x4E65	0x4E94	# <CJK>
+0x4E66	0x6342	# <CJK>
+0x4E67	0x5348	# <CJK>
+0x4E68	0x821E	# <CJK>
+0x4E69	0x4F0D	# <CJK>
+0x4E6A	0x4FAE	# <CJK>
+0x4E6B	0x5862	# <CJK>
+0x4E6C	0x620A	# <CJK>
+0x4E6D	0x9727	# <CJK>
+0x4E6E	0x6664	# <CJK>
+0x4E6F	0x7269	# <CJK>
+0x4E70	0x52FF	# <CJK>
+0x4E71	0x52D9	# <CJK>
+0x4E72	0x609F	# <CJK>
+0x4E73	0x8AA4	# <CJK>
+0x4E74	0x6614	# <CJK>
+0x4E75	0x7199	# <CJK>
+0x4E76	0x6790	# <CJK>
+0x4E77	0x897F	# <CJK>
+0x4E78	0x7852	# <CJK>
+0x4E79	0x77FD	# <CJK>
+0x4E7A	0x6670	# <CJK>
+0x4E7B	0x563B	# <CJK>
+0x4E7C	0x5438	# <CJK>
+0x4E7D	0x932B	# <CJK>
+0x4E7E	0x72A7	# <CJK>
+0x4F21	0x7A00	# <CJK>
+0x4F22	0x606F	# <CJK>
+0x4F23	0x5E0C	# <CJK>
+0x4F24	0x6089	# <CJK>
+0x4F25	0x819D	# <CJK>
+0x4F26	0x5915	# <CJK>
+0x4F27	0x60DC	# <CJK>
+0x4F28	0x7184	# <CJK>
+0x4F29	0x70EF	# <CJK>
+0x4F2A	0x6EAA	# <CJK>
+0x4F2B	0x6C50	# <CJK>
+0x4F2C	0x7280	# <CJK>
+0x4F2D	0x6A84	# <CJK>
+0x4F2E	0x8972	# <CJK>
+0x4F2F	0x5E2D	# <CJK>
+0x4F30	0x7FD2	# <CJK>
+0x4F31	0x5AB3	# <CJK>
+0x4F32	0x559C	# <CJK>
+0x4F33	0x9291	# <CJK>
+0x4F34	0x6D17	# <CJK>
+0x4F35	0x7CFB	# <CJK>
+0x4F36	0x9699	# <CJK>
+0x4F37	0x6232	# <CJK>
+0x4F38	0x7D30	# <CJK>
+0x4F39	0x778E	# <CJK>
+0x4F3A	0x8766	# <CJK>
+0x4F3B	0x5323	# <CJK>
+0x4F3C	0x971E	# <CJK>
+0x4F3D	0x8F44	# <CJK>
+0x4F3E	0x6687	# <CJK>
+0x4F3F	0x5CFD	# <CJK>
+0x4F40	0x4FE0	# <CJK>
+0x4F41	0x72F9	# <CJK>
+0x4F42	0x4E0B	# <CJK>
+0x4F43	0x53A6	# <CJK>
+0x4F44	0x590F	# <CJK>
+0x4F45	0x5687	# <CJK>
+0x4F46	0x6380	# <CJK>
+0x4F47	0x9341	# <CJK>
+0x4F48	0x5148	# <CJK>
+0x4F49	0x4ED9	# <CJK>
+0x4F4A	0x9BAE	# <CJK>
+0x4F4B	0x7E96	# <CJK>
+0x4F4C	0x54B8	# <CJK>
+0x4F4D	0x8CE2	# <CJK>
+0x4F4E	0x929C	# <CJK>
+0x4F4F	0x8237	# <CJK>
+0x4F50	0x9591	# <CJK>
+0x4F51	0x6D8E	# <CJK>
+0x4F52	0x5F26	# <CJK>
+0x4F53	0x5ACC	# <CJK>
+0x4F54	0x986F	# <CJK>
+0x4F55	0x96AA	# <CJK>
+0x4F56	0x73FE	# <CJK>
+0x4F57	0x737B	# <CJK>
+0x4F58	0x7E23	# <CJK>
+0x4F59	0x817A	# <CJK>
+0x4F5A	0x9921	# <CJK>
+0x4F5B	0x7FA1	# <CJK>
+0x4F5C	0x61B2	# <CJK>
+0x4F5D	0x9677	# <CJK>
+0x4F5E	0x9650	# <CJK>
+0x4F5F	0x7DAB	# <CJK>
+0x4F60	0x76F8	# <CJK>
+0x4F61	0x53A2	# <CJK>
+0x4F62	0x9472	# <CJK>
+0x4F63	0x9999	# <CJK>
+0x4F64	0x7BB1	# <CJK>
+0x4F65	0x8944	# <CJK>
+0x4F66	0x6E58	# <CJK>
+0x4F67	0x9109	# <CJK>
+0x4F68	0x7FD4	# <CJK>
+0x4F69	0x7965	# <CJK>
+0x4F6A	0x8A73	# <CJK>
+0x4F6B	0x60F3	# <CJK>
+0x4F6C	0x97FF	# <CJK>
+0x4F6D	0x4EAB	# <CJK>
+0x4F6E	0x9805	# <CJK>
+0x4F6F	0x5DF7	# <CJK>
+0x4F70	0x6A61	# <CJK>
+0x4F71	0x50CF	# <CJK>
+0x4F72	0x5411	# <CJK>
+0x4F73	0x8C61	# <CJK>
+0x4F74	0x856D	# <CJK>
+0x4F75	0x785D	# <CJK>
+0x4F76	0x9704	# <CJK>
+0x4F77	0x524A	# <CJK>
+0x4F78	0x54EE	# <CJK>
+0x4F79	0x56C2	# <CJK>
+0x4F7A	0x92B7	# <CJK>
+0x4F7B	0x6D88	# <CJK>
+0x4F7C	0x5BB5	# <CJK>
+0x4F7D	0x6DC6	# <CJK>
+0x4F7E	0x66C9	# <CJK>
+0x5021	0x5C0F	# <CJK>
+0x5022	0x5B5D	# <CJK>
+0x5023	0x6821	# <CJK>
+0x5024	0x8096	# <CJK>
+0x5025	0x562F	# <CJK>
+0x5026	0x7B11	# <CJK>
+0x5027	0x6548	# <CJK>
+0x5028	0x6954	# <CJK>
+0x5029	0x4E9B	# <CJK>
+0x502A	0x6B47	# <CJK>
+0x502B	0x874E	# <CJK>
+0x502C	0x978B	# <CJK>
+0x502D	0x5354	# <CJK>
+0x502E	0x633E	# <CJK>
+0x502F	0x643A	# <CJK>
+0x5030	0x90AA	# <CJK>
+0x5031	0x659C	# <CJK>
+0x5032	0x8105	# <CJK>
+0x5033	0x8AE7	# <CJK>
+0x5034	0x5BEB	# <CJK>
+0x5035	0x68B0	# <CJK>
+0x5036	0x5378	# <CJK>
+0x5037	0x87F9	# <CJK>
+0x5038	0x61C8	# <CJK>
+0x5039	0x6CC4	# <CJK>
+0x503A	0x7009	# <CJK>
+0x503B	0x8B1D	# <CJK>
+0x503C	0x5C51	# <CJK>
+0x503D	0x85AA	# <CJK>
+0x503E	0x82AF	# <CJK>
+0x503F	0x92C5	# <CJK>
+0x5040	0x6B23	# <CJK>
+0x5041	0x8F9B	# <CJK>
+0x5042	0x65B0	# <CJK>
+0x5043	0x5FFB	# <CJK>
+0x5044	0x5FC3	# <CJK>
+0x5045	0x4FE1	# <CJK>
+0x5046	0x91C1	# <CJK>
+0x5047	0x661F	# <CJK>
+0x5048	0x8165	# <CJK>
+0x5049	0x7329	# <CJK>
+0x504A	0x60FA	# <CJK>
+0x504B	0x8208	# <CJK>
+0x504C	0x5211	# <CJK>
+0x504D	0x578B	# <CJK>
+0x504E	0x5F62	# <CJK>
+0x504F	0x90A2	# <CJK>
+0x5050	0x884C	# <CJK>
+0x5051	0x9192	# <CJK>
+0x5052	0x5E78	# <CJK>
+0x5053	0x674F	# <CJK>
+0x5054	0x6027	# <CJK>
+0x5055	0x59D3	# <CJK>
+0x5056	0x5144	# <CJK>
+0x5057	0x51F6	# <CJK>
+0x5058	0x80F8	# <CJK>
+0x5059	0x5308	# <CJK>
+0x505A	0x6C79	# <CJK>
+0x505B	0x96C4	# <CJK>
+0x505C	0x718A	# <CJK>
+0x505D	0x4F11	# <CJK>
+0x505E	0x4FEE	# <CJK>
+0x505F	0x7F9E	# <CJK>
+0x5060	0x673D	# <CJK>
+0x5061	0x55C5	# <CJK>
+0x5062	0x92B9	# <CJK>
+0x5063	0x79C0	# <CJK>
+0x5064	0x8896	# <CJK>
+0x5065	0x7D89	# <CJK>
+0x5066	0x589F	# <CJK>
+0x5067	0x620C	# <CJK>
+0x5068	0x9700	# <CJK>
+0x5069	0x865A	# <CJK>
+0x506A	0x5618	# <CJK>
+0x506B	0x9808	# <CJK>
+0x506C	0x5F90	# <CJK>
+0x506D	0x8A31	# <CJK>
+0x506E	0x84C4	# <CJK>
+0x506F	0x9157	# <CJK>
+0x5070	0x53D9	# <CJK>
+0x5071	0x65ED	# <CJK>
+0x5072	0x5E8F	# <CJK>
+0x5073	0x755C	# <CJK>
+0x5074	0x6064	# <CJK>
+0x5075	0x7D6E	# <CJK>
+0x5076	0x5A7F	# <CJK>
+0x5077	0x7DD2	# <CJK>
+0x5078	0x7E8C	# <CJK>
+0x5079	0x8ED2	# <CJK>
+0x507A	0x55A7	# <CJK>
+0x507B	0x5BA3	# <CJK>
+0x507C	0x61F8	# <CJK>
+0x507D	0x65CB	# <CJK>
+0x507E	0x7384	# <CJK>
+0x5121	0x9078	# <CJK>
+0x5122	0x766C	# <CJK>
+0x5123	0x7729	# <CJK>
+0x5124	0x7D62	# <CJK>
+0x5125	0x9774	# <CJK>
+0x5126	0x859B	# <CJK>
+0x5127	0x5B78	# <CJK>
+0x5128	0x7A74	# <CJK>
+0x5129	0x96EA	# <CJK>
+0x512A	0x8840	# <CJK>
+0x512B	0x52DB	# <CJK>
+0x512C	0x718F	# <CJK>
+0x512D	0x5FAA	# <CJK>
+0x512E	0x65EC	# <CJK>
+0x512F	0x8A62	# <CJK>
+0x5130	0x5C0B	# <CJK>
+0x5131	0x99B4	# <CJK>
+0x5132	0x5DE1	# <CJK>
+0x5133	0x6B89	# <CJK>
+0x5134	0x6C5B	# <CJK>
+0x5135	0x8A13	# <CJK>
+0x5136	0x8A0A	# <CJK>
+0x5137	0x905C	# <CJK>
+0x5138	0x8FC5	# <CJK>
+0x5139	0x58D3	# <CJK>
+0x513A	0x62BC	# <CJK>
+0x513B	0x9D09	# <CJK>
+0x513C	0x9D28	# <CJK>
+0x513D	0x5440	# <CJK>
+0x513E	0x4E2B	# <CJK>
+0x513F	0x82BD	# <CJK>
+0x5140	0x7259	# <CJK>
+0x5141	0x869C	# <CJK>
+0x5142	0x5D16	# <CJK>
+0x5143	0x8859	# <CJK>
+0x5144	0x6DAF	# <CJK>
+0x5145	0x96C5	# <CJK>
+0x5146	0x555E	# <CJK>
+0x5147	0x4E9E	# <CJK>
+0x5148	0x8A1D	# <CJK>
+0x5149	0x7109	# <CJK>
+0x514A	0x54BD	# <CJK>
+0x514B	0x95B9	# <CJK>
+0x514C	0x70DF	# <CJK>
+0x514D	0x6DF9	# <CJK>
+0x514E	0x9E7D	# <CJK>
+0x514F	0x56B4	# <CJK>
+0x5150	0x7814	# <CJK>
+0x5151	0x8712	# <CJK>
+0x5152	0x5CA9	# <CJK>
+0x5153	0x5EF6	# <CJK>
+0x5154	0x8A00	# <CJK>
+0x5155	0x9854	# <CJK>
+0x5156	0x95BB	# <CJK>
+0x5157	0x708E	# <CJK>
+0x5158	0x6CBF	# <CJK>
+0x5159	0x5944	# <CJK>
+0x515A	0x63A9	# <CJK>
+0x515B	0x773C	# <CJK>
+0x515C	0x884D	# <CJK>
+0x515D	0x6F14	# <CJK>
+0x515E	0x8277	# <CJK>
+0x515F	0x5830	# <CJK>
+0x5160	0x71D5	# <CJK>
+0x5161	0x53AD	# <CJK>
+0x5162	0x786F	# <CJK>
+0x5163	0x96C1	# <CJK>
+0x5164	0x5501	# <CJK>
+0x5165	0x5F66	# <CJK>
+0x5166	0x7130	# <CJK>
+0x5167	0x5BB4	# <CJK>
+0x5168	0x8AFA	# <CJK>
+0x5169	0x9A57	# <CJK>
+0x516A	0x6B83	# <CJK>
+0x516B	0x592E	# <CJK>
+0x516C	0x9D26	# <CJK>
+0x516D	0x79E7	# <CJK>
+0x516E	0x694A	# <CJK>
+0x516F	0x63DA	# <CJK>
+0x5170	0x4F6F	# <CJK>
+0x5171	0x760D	# <CJK>
+0x5172	0x7F8A	# <CJK>
+0x5173	0x6D0B	# <CJK>
+0x5174	0x967D	# <CJK>
+0x5175	0x6C27	# <CJK>
+0x5176	0x4EF0	# <CJK>
+0x5177	0x7662	# <CJK>
+0x5178	0x990A	# <CJK>
+0x5179	0x6A23	# <CJK>
+0x517A	0x6F3E	# <CJK>
+0x517B	0x9080	# <CJK>
+0x517C	0x8170	# <CJK>
+0x517D	0x5996	# <CJK>
+0x517E	0x7476	# <CJK>
+0x5221	0x6447	# <CJK>
+0x5222	0x582F	# <CJK>
+0x5223	0x9065	# <CJK>
+0x5224	0x7A91	# <CJK>
+0x5225	0x8B21	# <CJK>
+0x5226	0x59DA	# <CJK>
+0x5227	0x54AC	# <CJK>
+0x5228	0x8200	# <CJK>
+0x5229	0x85E5	# <CJK>
+0x522A	0x8981	# <CJK>
+0x522B	0x8000	# <CJK>
+0x522C	0x6930	# <CJK>
+0x522D	0x564E	# <CJK>
+0x522E	0x8036	# <CJK>
+0x522F	0x723A	# <CJK>
+0x5230	0x91CE	# <CJK>
+0x5231	0x51B6	# <CJK>
+0x5232	0x4E5F	# <CJK>
+0x5233	0x9801	# <CJK>
+0x5234	0x6396	# <CJK>
+0x5235	0x696D	# <CJK>
+0x5236	0x8449	# <CJK>
+0x5237	0x66F3	# <CJK>
+0x5238	0x814B	# <CJK>
+0x5239	0x591C	# <CJK>
+0x523A	0x6DB2	# <CJK>
+0x523B	0x4E00	# <CJK>
+0x523C	0x58F9	# <CJK>
+0x523D	0x91AB	# <CJK>
+0x523E	0x63D6	# <CJK>
+0x523F	0x92A5	# <CJK>
+0x5240	0x4F9D	# <CJK>
+0x5241	0x4F0A	# <CJK>
+0x5242	0x8863	# <CJK>
+0x5243	0x9824	# <CJK>
+0x5244	0x5937	# <CJK>
+0x5245	0x907A	# <CJK>
+0x5246	0x79FB	# <CJK>
+0x5247	0x5100	# <CJK>
+0x5248	0x80F0	# <CJK>
+0x5249	0x7591	# <CJK>
+0x524A	0x6C82	# <CJK>
+0x524B	0x5B9C	# <CJK>
+0x524C	0x59E8	# <CJK>
+0x524D	0x5F5D	# <CJK>
+0x524E	0x6905	# <CJK>
+0x524F	0x87FB	# <CJK>
+0x5250	0x501A	# <CJK>
+0x5251	0x5DF2	# <CJK>
+0x5252	0x4E59	# <CJK>
+0x5253	0x77E3	# <CJK>
+0x5254	0x4EE5	# <CJK>
+0x5255	0x85DD	# <CJK>
+0x5256	0x6291	# <CJK>
+0x5257	0x6613	# <CJK>
+0x5258	0x9091	# <CJK>
+0x5259	0x5C79	# <CJK>
+0x525A	0x5104	# <CJK>
+0x525B	0x5F79	# <CJK>
+0x525C	0x81C6	# <CJK>
+0x525D	0x9038	# <CJK>
+0x525E	0x8084	# <CJK>
+0x525F	0x75AB	# <CJK>
+0x5260	0x4EA6	# <CJK>
+0x5261	0x88D4	# <CJK>
+0x5262	0x610F	# <CJK>
+0x5263	0x6BC5	# <CJK>
+0x5264	0x61B6	# <CJK>
+0x5265	0x7FA9	# <CJK>
+0x5266	0x76CA	# <CJK>
+0x5267	0x6EA2	# <CJK>
+0x5268	0x8A63	# <CJK>
+0x5269	0x8B70	# <CJK>
+0x526A	0x8ABC	# <CJK>
+0x526B	0x8B6F	# <CJK>
+0x526C	0x5F02	# <CJK>
+0x526D	0x7FFC	# <CJK>
+0x526E	0x7FCC	# <CJK>
+0x526F	0x7E79	# <CJK>
+0x5270	0x8335	# <CJK>
+0x5271	0x852D	# <CJK>
+0x5272	0x56E0	# <CJK>
+0x5273	0x6BB7	# <CJK>
+0x5274	0x97F3	# <CJK>
+0x5275	0x9670	# <CJK>
+0x5276	0x59FB	# <CJK>
+0x5277	0x541F	# <CJK>
+0x5278	0x9280	# <CJK>
+0x5279	0x6DEB	# <CJK>
+0x527A	0x5BC5	# <CJK>
+0x527B	0x98F2	# <CJK>
+0x527C	0x5C39	# <CJK>
+0x527D	0x5F15	# <CJK>
+0x527E	0x96B1	# <CJK>
+0x5321	0x5370	# <CJK>
+0x5322	0x82F1	# <CJK>
+0x5323	0x6AFB	# <CJK>
+0x5324	0x5B30	# <CJK>
+0x5325	0x9DF9	# <CJK>
+0x5326	0x61C9	# <CJK>
+0x5327	0x7E93	# <CJK>
+0x5328	0x7469	# <CJK>
+0x5329	0x87A2	# <CJK>
+0x532A	0x71DF	# <CJK>
+0x532B	0x7192	# <CJK>
+0x532C	0x8805	# <CJK>
+0x532D	0x8FCE	# <CJK>
+0x532E	0x8D0F	# <CJK>
+0x532F	0x76C8	# <CJK>
+0x5330	0x5F71	# <CJK>
+0x5331	0x7A4E	# <CJK>
+0x5332	0x786C	# <CJK>
+0x5333	0x6620	# <CJK>
+0x5334	0x55B2	# <CJK>
+0x5335	0x64C1	# <CJK>
+0x5336	0x50AD	# <CJK>
+0x5337	0x81C3	# <CJK>
+0x5338	0x7670	# <CJK>
+0x5339	0x5EB8	# <CJK>
+0x533A	0x96CD	# <CJK>
+0x533B	0x8E34	# <CJK>
+0x533C	0x86F9	# <CJK>
+0x533D	0x548F	# <CJK>
+0x533E	0x6CF3	# <CJK>
+0x533F	0x6D8C	# <CJK>
+0x5340	0x6C38	# <CJK>
+0x5341	0x607F	# <CJK>
+0x5342	0x52C7	# <CJK>
+0x5343	0x7528	# <CJK>
+0x5344	0x5E7D	# <CJK>
+0x5345	0x512A	# <CJK>
+0x5346	0x60A0	# <CJK>
+0x5347	0x6182	# <CJK>
+0x5348	0x5C24	# <CJK>
+0x5349	0x7531	# <CJK>
+0x534A	0x90F5	# <CJK>
+0x534B	0x923E	# <CJK>
+0x534C	0x7336	# <CJK>
+0x534D	0x6CB9	# <CJK>
+0x534E	0x6E38	# <CJK>
+0x534F	0x9149	# <CJK>
+0x5350	0x6709	# <CJK>
+0x5351	0x53CB	# <CJK>
+0x5352	0x53F3	# <CJK>
+0x5353	0x4F51	# <CJK>
+0x5354	0x91C9	# <CJK>
+0x5355	0x8A98	# <CJK>
+0x5356	0x53C8	# <CJK>
+0x5357	0x5E7C	# <CJK>
+0x5358	0x8FC2	# <CJK>
+0x5359	0x6DE4	# <CJK>
+0x535A	0x4E8E	# <CJK>
+0x535B	0x76C2	# <CJK>
+0x535C	0x6986	# <CJK>
+0x535D	0x865E	# <CJK>
+0x535E	0x611A	# <CJK>
+0x535F	0x8F3F	# <CJK>
+0x5360	0x9918	# <CJK>
+0x5361	0x4FDE	# <CJK>
+0x5362	0x903E	# <CJK>
+0x5363	0x9B5A	# <CJK>
+0x5364	0x6109	# <CJK>
+0x5365	0x6E1D	# <CJK>
+0x5366	0x6F01	# <CJK>
+0x5367	0x9685	# <CJK>
+0x5368	0x4E88	# <CJK>
+0x5369	0x5A31	# <CJK>
+0x536A	0x96E8	# <CJK>
+0x536B	0x8207	# <CJK>
+0x536C	0x5DBC	# <CJK>
+0x536D	0x79B9	# <CJK>
+0x536E	0x5B87	# <CJK>
+0x536F	0x8A9E	# <CJK>
+0x5370	0x7FBD	# <CJK>
+0x5371	0x7389	# <CJK>
+0x5372	0x57DF	# <CJK>
+0x5373	0x828B	# <CJK>
+0x5374	0x9B31	# <CJK>
+0x5375	0x5401	# <CJK>
+0x5376	0x9047	# <CJK>
+0x5377	0x55BB	# <CJK>
+0x5378	0x5CEA	# <CJK>
+0x5379	0x5FA1	# <CJK>
+0x537A	0x6108	# <CJK>
+0x537B	0x6B32	# <CJK>
+0x537C	0x7344	# <CJK>
+0x537D	0x80B2	# <CJK>
+0x537E	0x8B7D	# <CJK>
+0x5421	0x6D74	# <CJK>
+0x5422	0x5BD3	# <CJK>
+0x5423	0x88D5	# <CJK>
+0x5424	0x9810	# <CJK>
+0x5425	0x8C6B	# <CJK>
+0x5426	0x99AD	# <CJK>
+0x5427	0x9D1B	# <CJK>
+0x5428	0x6DF5	# <CJK>
+0x5429	0x51A4	# <CJK>
+0x542A	0x5143	# <CJK>
+0x542B	0x57A3	# <CJK>
+0x542C	0x8881	# <CJK>
+0x542D	0x539F	# <CJK>
+0x542E	0x63F4	# <CJK>
+0x542F	0x8F45	# <CJK>
+0x5430	0x5712	# <CJK>
+0x5431	0x54E1	# <CJK>
+0x5432	0x5713	# <CJK>
+0x5433	0x733F	# <CJK>
+0x5434	0x6E90	# <CJK>
+0x5435	0x7DE3	# <CJK>
+0x5436	0x9060	# <CJK>
+0x5437	0x82D1	# <CJK>
+0x5438	0x9858	# <CJK>
+0x5439	0x6028	# <CJK>
+0x543A	0x9662	# <CJK>
+0x543B	0x66F0	# <CJK>
+0x543C	0x7D04	# <CJK>
+0x543D	0x8D8A	# <CJK>
+0x543E	0x8E8D	# <CJK>
+0x543F	0x9470	# <CJK>
+0x5440	0x5CB3	# <CJK>
+0x5441	0x7CA4	# <CJK>
+0x5442	0x6708	# <CJK>
+0x5443	0x60A6	# <CJK>
+0x5444	0x95B2	# <CJK>
+0x5445	0x8018	# <CJK>
+0x5446	0x96F2	# <CJK>
+0x5447	0x9116	# <CJK>
+0x5448	0x5300	# <CJK>
+0x5449	0x9695	# <CJK>
+0x544A	0x5141	# <CJK>
+0x544B	0x904B	# <CJK>
+0x544C	0x85F4	# <CJK>
+0x544D	0x9196	# <CJK>
+0x544E	0x6688	# <CJK>
+0x544F	0x97F5	# <CJK>
+0x5450	0x5B55	# <CJK>
+0x5451	0x531D	# <CJK>
+0x5452	0x7838	# <CJK>
+0x5453	0x96DC	# <CJK>
+0x5454	0x683D	# <CJK>
+0x5455	0x54C9	# <CJK>
+0x5456	0x707E	# <CJK>
+0x5457	0x5BB0	# <CJK>
+0x5458	0x8F09	# <CJK>
+0x5459	0x518D	# <CJK>
+0x545A	0x5728	# <CJK>
+0x545B	0x54B1	# <CJK>
+0x545C	0x6522	# <CJK>
+0x545D	0x66AB	# <CJK>
+0x545E	0x8D0A	# <CJK>
+0x545F	0x8D1C	# <CJK>
+0x5460	0x81DF	# <CJK>
+0x5461	0x846C	# <CJK>
+0x5462	0x906D	# <CJK>
+0x5463	0x7CDF	# <CJK>
+0x5464	0x947F	# <CJK>
+0x5465	0x85FB	# <CJK>
+0x5466	0x68D7	# <CJK>
+0x5467	0x65E9	# <CJK>
+0x5468	0x6FA1	# <CJK>
+0x5469	0x86A4	# <CJK>
+0x546A	0x8E81	# <CJK>
+0x546B	0x566A	# <CJK>
+0x546C	0x9020	# <CJK>
+0x546D	0x7682	# <CJK>
+0x546E	0x7AC8	# <CJK>
+0x546F	0x71E5	# <CJK>
+0x5470	0x8CAC	# <CJK>
+0x5471	0x64C7	# <CJK>
+0x5472	0x5247	# <CJK>
+0x5473	0x6FA4	# <CJK>
+0x5474	0x8CCA	# <CJK>
+0x5475	0x600E	# <CJK>
+0x5476	0x589E	# <CJK>
+0x5477	0x618E	# <CJK>
+0x5478	0x66FE	# <CJK>
+0x5479	0x8D08	# <CJK>
+0x547A	0x624E	# <CJK>
+0x547B	0x55B3	# <CJK>
+0x547C	0x6E23	# <CJK>
+0x547D	0x672D	# <CJK>
+0x547E	0x8ECB	# <CJK>
+0x5521	0x9358	# <CJK>
+0x5522	0x9598	# <CJK>
+0x5523	0x7728	# <CJK>
+0x5524	0x6805	# <CJK>
+0x5525	0x69A8	# <CJK>
+0x5526	0x548B	# <CJK>
+0x5527	0x4E4D	# <CJK>
+0x5528	0x70B8	# <CJK>
+0x5529	0x8A50	# <CJK>
+0x552A	0x6458	# <CJK>
+0x552B	0x9F4B	# <CJK>
+0x552C	0x5B85	# <CJK>
+0x552D	0x7A84	# <CJK>
+0x552E	0x50B5	# <CJK>
+0x552F	0x5BE8	# <CJK>
+0x5530	0x77BB	# <CJK>
+0x5531	0x6C08	# <CJK>
+0x5532	0x8A79	# <CJK>
+0x5533	0x7C98	# <CJK>
+0x5534	0x6CBE	# <CJK>
+0x5535	0x76DE	# <CJK>
+0x5536	0x65AC	# <CJK>
+0x5537	0x8F3E	# <CJK>
+0x5538	0x5D84	# <CJK>
+0x5539	0x5C55	# <CJK>
+0x553A	0x8638	# <CJK>
+0x553B	0x68E7	# <CJK>
+0x553C	0x5360	# <CJK>
+0x553D	0x6230	# <CJK>
+0x553E	0x7AD9	# <CJK>
+0x553F	0x6E5B	# <CJK>
+0x5540	0x7DBB	# <CJK>
+0x5541	0x6A1F	# <CJK>
+0x5542	0x7AE0	# <CJK>
+0x5543	0x5F70	# <CJK>
+0x5544	0x6F33	# <CJK>
+0x5545	0x5F35	# <CJK>
+0x5546	0x638C	# <CJK>
+0x5547	0x6F32	# <CJK>
+0x5548	0x6756	# <CJK>
+0x5549	0x4E08	# <CJK>
+0x554A	0x5E33	# <CJK>
+0x554B	0x8CEC	# <CJK>
+0x554C	0x4ED7	# <CJK>
+0x554D	0x8139	# <CJK>
+0x554E	0x7634	# <CJK>
+0x554F	0x969C	# <CJK>
+0x5550	0x62DB	# <CJK>
+0x5551	0x662D	# <CJK>
+0x5552	0x627E	# <CJK>
+0x5553	0x6CBC	# <CJK>
+0x5554	0x8D99	# <CJK>
+0x5555	0x7167	# <CJK>
+0x5556	0x7F69	# <CJK>
+0x5557	0x5146	# <CJK>
+0x5558	0x8087	# <CJK>
+0x5559	0x53EC	# <CJK>
+0x555A	0x906E	# <CJK>
+0x555B	0x6298	# <CJK>
+0x555C	0x54F2	# <CJK>
+0x555D	0x87C4	# <CJK>
+0x555E	0x8F4D	# <CJK>
+0x555F	0x8005	# <CJK>
+0x5560	0x937A	# <CJK>
+0x5561	0x8517	# <CJK>
+0x5562	0x9019	# <CJK>
+0x5563	0x6D59	# <CJK>
+0x5564	0x73CD	# <CJK>
+0x5565	0x659F	# <CJK>
+0x5566	0x771F	# <CJK>
+0x5567	0x7504	# <CJK>
+0x5568	0x7827	# <CJK>
+0x5569	0x81FB	# <CJK>
+0x556A	0x8C9E	# <CJK>
+0x556B	0x91DD	# <CJK>
+0x556C	0x5075	# <CJK>
+0x556D	0x6795	# <CJK>
+0x556E	0x75B9	# <CJK>
+0x556F	0x8A3A	# <CJK>
+0x5570	0x9707	# <CJK>
+0x5571	0x632F	# <CJK>
+0x5572	0x93AE	# <CJK>
+0x5573	0x9663	# <CJK>
+0x5574	0x84B8	# <CJK>
+0x5575	0x6399	# <CJK>
+0x5576	0x775C	# <CJK>
+0x5577	0x5F81	# <CJK>
+0x5578	0x7319	# <CJK>
+0x5579	0x722D	# <CJK>
+0x557A	0x6014	# <CJK>
+0x557B	0x6574	# <CJK>
+0x557C	0x62EF	# <CJK>
+0x557D	0x6B63	# <CJK>
+0x557E	0x653F	# <CJK>
+0x5621	0x5E40	# <CJK>
+0x5622	0x7665	# <CJK>
+0x5623	0x912D	# <CJK>
+0x5624	0x8B49	# <CJK>
+0x5625	0x829D	# <CJK>
+0x5626	0x679D	# <CJK>
+0x5627	0x652F	# <CJK>
+0x5628	0x5431	# <CJK>
+0x5629	0x8718	# <CJK>
+0x562A	0x77E5	# <CJK>
+0x562B	0x80A2	# <CJK>
+0x562C	0x8102	# <CJK>
+0x562D	0x6C41	# <CJK>
+0x562E	0x4E4B	# <CJK>
+0x562F	0x7E54	# <CJK>
+0x5630	0x8077	# <CJK>
+0x5631	0x76F4	# <CJK>
+0x5632	0x690D	# <CJK>
+0x5633	0x6B96	# <CJK>
+0x5634	0x57F7	# <CJK>
+0x5635	0x503C	# <CJK>
+0x5636	0x4F84	# <CJK>
+0x5637	0x5740	# <CJK>
+0x5638	0x6307	# <CJK>
+0x5639	0x6B62	# <CJK>
+0x563A	0x8DBE	# <CJK>
+0x563B	0x8879	# <CJK>
+0x563C	0x65E8	# <CJK>
+0x563D	0x7D19	# <CJK>
+0x563E	0x5FD7	# <CJK>
+0x563F	0x646F	# <CJK>
+0x5640	0x64F2	# <CJK>
+0x5641	0x81F3	# <CJK>
+0x5642	0x81F4	# <CJK>
+0x5643	0x7F6E	# <CJK>
+0x5644	0x5E5F	# <CJK>
+0x5645	0x5CD9	# <CJK>
+0x5646	0x5236	# <CJK>
+0x5647	0x667A	# <CJK>
+0x5648	0x79E9	# <CJK>
+0x5649	0x7A1A	# <CJK>
+0x564A	0x8CEA	# <CJK>
+0x564B	0x7099	# <CJK>
+0x564C	0x75D4	# <CJK>
+0x564D	0x6EEF	# <CJK>
+0x564E	0x6CBB	# <CJK>
+0x564F	0x7A92	# <CJK>
+0x5650	0x4E2D	# <CJK>
+0x5651	0x76C5	# <CJK>
+0x5652	0x5FE0	# <CJK>
+0x5653	0x9418	# <CJK>
+0x5654	0x8877	# <CJK>
+0x5655	0x7D42	# <CJK>
+0x5656	0x7A2E	# <CJK>
+0x5657	0x816B	# <CJK>
+0x5658	0x91CD	# <CJK>
+0x5659	0x4EF2	# <CJK>
+0x565A	0x8846	# <CJK>
+0x565B	0x821F	# <CJK>
+0x565C	0x5468	# <CJK>
+0x565D	0x5DDE	# <CJK>
+0x565E	0x6D32	# <CJK>
+0x565F	0x8B05	# <CJK>
+0x5660	0x7CA5	# <CJK>
+0x5661	0x8EF8	# <CJK>
+0x5662	0x8098	# <CJK>
+0x5663	0x5E1A	# <CJK>
+0x5664	0x5492	# <CJK>
+0x5665	0x76BA	# <CJK>
+0x5666	0x5B99	# <CJK>
+0x5667	0x665D	# <CJK>
+0x5668	0x9A5F	# <CJK>
+0x5669	0x73E0	# <CJK>
+0x566A	0x682A	# <CJK>
+0x566B	0x86DB	# <CJK>
+0x566C	0x6731	# <CJK>
+0x566D	0x732A	# <CJK>
+0x566E	0x8AF8	# <CJK>
+0x566F	0x8A85	# <CJK>
+0x5670	0x9010	# <CJK>
+0x5671	0x7AF9	# <CJK>
+0x5672	0x71ED	# <CJK>
+0x5673	0x716E	# <CJK>
+0x5674	0x62C4	# <CJK>
+0x5675	0x77DA	# <CJK>
+0x5676	0x56D1	# <CJK>
+0x5677	0x4E3B	# <CJK>
+0x5678	0x8457	# <CJK>
+0x5679	0x67F1	# <CJK>
+0x567A	0x52A9	# <CJK>
+0x567B	0x86C0	# <CJK>
+0x567C	0x8CAF	# <CJK>
+0x567D	0x9444	# <CJK>
+0x567E	0x7BC9	# <CJK>
+0x5721	0x4F4F	# <CJK>
+0x5722	0x6CE8	# <CJK>
+0x5723	0x795D	# <CJK>
+0x5724	0x99D0	# <CJK>
+0x5725	0x6293	# <CJK>
+0x5726	0x722A	# <CJK>
+0x5727	0x62FD	# <CJK>
+0x5728	0x5C08	# <CJK>
+0x5729	0x78DA	# <CJK>
+0x572A	0x8F49	# <CJK>
+0x572B	0x64B0	# <CJK>
+0x572C	0x8CFA	# <CJK>
+0x572D	0x7BC6	# <CJK>
+0x572E	0x6A01	# <CJK>
+0x572F	0x838A	# <CJK>
+0x5730	0x88DD	# <CJK>
+0x5731	0x599D	# <CJK>
+0x5732	0x649E	# <CJK>
+0x5733	0x58EF	# <CJK>
+0x5734	0x72C0	# <CJK>
+0x5735	0x690E	# <CJK>
+0x5736	0x9310	# <CJK>
+0x5737	0x8FFD	# <CJK>
+0x5738	0x8D05	# <CJK>
+0x5739	0x589C	# <CJK>
+0x573A	0x7DB4	# <CJK>
+0x573B	0x8AC4	# <CJK>
+0x573C	0x6E96	# <CJK>
+0x573D	0x6349	# <CJK>
+0x573E	0x62D9	# <CJK>
+0x573F	0x5353	# <CJK>
+0x5740	0x684C	# <CJK>
+0x5741	0x7422	# <CJK>
+0x5742	0x8301	# <CJK>
+0x5743	0x914C	# <CJK>
+0x5744	0x5544	# <CJK>
+0x5745	0x7740	# <CJK>
+0x5746	0x707C	# <CJK>
+0x5747	0x6FC1	# <CJK>
+0x5748	0x5179	# <CJK>
+0x5749	0x54A8	# <CJK>
+0x574A	0x8CC7	# <CJK>
+0x574B	0x59FF	# <CJK>
+0x574C	0x6ECB	# <CJK>
+0x574D	0x6DC4	# <CJK>
+0x574E	0x5B5C	# <CJK>
+0x574F	0x7D2B	# <CJK>
+0x5750	0x4ED4	# <CJK>
+0x5751	0x7C7D	# <CJK>
+0x5752	0x6ED3	# <CJK>
+0x5753	0x5B50	# <CJK>
+0x5754	0x81EA	# <CJK>
+0x5755	0x6F2C	# <CJK>
+0x5756	0x5B57	# <CJK>
+0x5757	0x9B03	# <CJK>
+0x5758	0x68D5	# <CJK>
+0x5759	0x8E2A	# <CJK>
+0x575A	0x5B97	# <CJK>
+0x575B	0x7D9C	# <CJK>
+0x575C	0x7E3D	# <CJK>
+0x575D	0x7E31	# <CJK>
+0x575E	0x9112	# <CJK>
+0x575F	0x8D70	# <CJK>
+0x5760	0x594F	# <CJK>
+0x5761	0x63CD	# <CJK>
+0x5762	0x79DF	# <CJK>
+0x5763	0x8DB3	# <CJK>
+0x5764	0x5352	# <CJK>
+0x5765	0x65CF	# <CJK>
+0x5766	0x7956	# <CJK>
+0x5767	0x8A5B	# <CJK>
+0x5768	0x963B	# <CJK>
+0x5769	0x7D44	# <CJK>
+0x576A	0x947D	# <CJK>
+0x576B	0x7E82	# <CJK>
+0x576C	0x5634	# <CJK>
+0x576D	0x9189	# <CJK>
+0x576E	0x6700	# <CJK>
+0x576F	0x7F6A	# <CJK>
+0x5770	0x5C0A	# <CJK>
+0x5771	0x9075	# <CJK>
+0x5772	0x6628	# <CJK>
+0x5773	0x5DE6	# <CJK>
+0x5774	0x4F50	# <CJK>
+0x5775	0x67DE	# <CJK>
+0x5776	0x505A	# <CJK>
+0x5777	0x4F5C	# <CJK>
+0x5778	0x5750	# <CJK>
+0x5779	0x5EA7	# <CJK>
+0x5821	0x4E8D	# <CJK>
+0x5822	0x4E0C	# <CJK>
+0x5823	0x5140	# <CJK>
+0x5824	0x4E10	# <CJK>
+0x5825	0x5EFF	# <CJK>
+0x5826	0x5345	# <CJK>
+0x5827	0x4E15	# <CJK>
+0x5828	0x4E98	# <CJK>
+0x5829	0x4E1E	# <CJK>
+0x582A	0x9B32	# <CJK>
+0x582B	0x5B6C	# <CJK>
+0x582C	0x5669	# <CJK>
+0x582D	0x4E28	# <CJK>
+0x582E	0x79BA	# <CJK>
+0x582F	0x4E3F	# <CJK>
+0x5830	0x5315	# <CJK>
+0x5831	0x4E47	# <CJK>
+0x5832	0x592D	# <CJK>
+0x5833	0x723B	# <CJK>
+0x5834	0x536E	# <CJK>
+0x5835	0x6C10	# <CJK>
+0x5836	0x56DF	# <CJK>
+0x5837	0x80E4	# <CJK>
+0x5838	0x9997	# <CJK>
+0x5839	0x6BD3	# <CJK>
+0x583A	0x777E	# <CJK>
+0x583B	0x9F17	# <CJK>
+0x583C	0x4E36	# <CJK>
+0x583D	0x4E9F	# <CJK>
+0x583E	0x9F10	# <CJK>
+0x583F	0x4E5C	# <CJK>
+0x5840	0x4E69	# <CJK>
+0x5841	0x4E93	# <CJK>
+0x5842	0x8288	# <CJK>
+0x5843	0x5B5B	# <CJK>
+0x5844	0x55C7	# <CJK>
+0x5845	0x560F	# <CJK>
+0x5846	0x4EC4	# <CJK>
+0x5847	0x5399	# <CJK>
+0x5848	0x539D	# <CJK>
+0x5849	0x53B4	# <CJK>
+0x584A	0x53A5	# <CJK>
+0x584B	0x53AE	# <CJK>
+0x584C	0x9768	# <CJK>
+0x584D	0x8D0B	# <CJK>
+0x584E	0x531A	# <CJK>
+0x584F	0x53F5	# <CJK>
+0x5850	0x532D	# <CJK>
+0x5851	0x5331	# <CJK>
+0x5852	0x533E	# <CJK>
+0x5853	0x8CFE	# <CJK>
+0x5854	0x5366	# <CJK>
+0x5855	0x5363	# <CJK>
+0x5856	0x5202	# <CJK>
+0x5857	0x5208	# <CJK>
+0x5858	0x520E	# <CJK>
+0x5859	0x5244	# <CJK>
+0x585A	0x5233	# <CJK>
+0x585B	0x528C	# <CJK>
+0x585C	0x5274	# <CJK>
+0x585D	0x524C	# <CJK>
+0x585E	0x525E	# <CJK>
+0x585F	0x5261	# <CJK>
+0x5860	0x525C	# <CJK>
+0x5861	0x84AF	# <CJK>
+0x5862	0x527D	# <CJK>
+0x5863	0x5282	# <CJK>
+0x5864	0x5281	# <CJK>
+0x5865	0x5290	# <CJK>
+0x5866	0x5293	# <CJK>
+0x5867	0x5182	# <CJK>
+0x5868	0x7F54	# <CJK>
+0x5869	0x4EBB	# <CJK>
+0x586A	0x4EC3	# <CJK>
+0x586B	0x4EC9	# <CJK>
+0x586C	0x4EC2	# <CJK>
+0x586D	0x4EE8	# <CJK>
+0x586E	0x4EE1	# <CJK>
+0x586F	0x4EEB	# <CJK>
+0x5870	0x4EDE	# <CJK>
+0x5871	0x50B4	# <CJK>
+0x5872	0x4EF3	# <CJK>
+0x5873	0x4F22	# <CJK>
+0x5874	0x4F64	# <CJK>
+0x5875	0x4EF5	# <CJK>
+0x5876	0x5000	# <CJK>
+0x5877	0x5096	# <CJK>
+0x5878	0x4F09	# <CJK>
+0x5879	0x4F47	# <CJK>
+0x587A	0x4F5E	# <CJK>
+0x587B	0x4F67	# <CJK>
+0x587C	0x6538	# <CJK>
+0x587D	0x4F5A	# <CJK>
+0x587E	0x4F5D	# <CJK>
+0x5921	0x4F5F	# <CJK>
+0x5922	0x4F57	# <CJK>
+0x5923	0x4F32	# <CJK>
+0x5924	0x4F3D	# <CJK>
+0x5925	0x4F76	# <CJK>
+0x5926	0x4F74	# <CJK>
+0x5927	0x4F91	# <CJK>
+0x5928	0x4F89	# <CJK>
+0x5929	0x4F83	# <CJK>
+0x592A	0x4F8F	# <CJK>
+0x592B	0x4F7E	# <CJK>
+0x592C	0x4F7B	# <CJK>
+0x592D	0x5115	# <CJK>
+0x592E	0x4F7C	# <CJK>
+0x592F	0x5102	# <CJK>
+0x5930	0x4F94	# <CJK>
+0x5931	0x5114	# <CJK>
+0x5932	0x513C	# <CJK>
+0x5933	0x5137	# <CJK>
+0x5934	0x4FC5	# <CJK>
+0x5935	0x4FDA	# <CJK>
+0x5936	0x4FE3	# <CJK>
+0x5937	0x4FDC	# <CJK>
+0x5938	0x4FD1	# <CJK>
+0x5939	0x4FDF	# <CJK>
+0x593A	0x4FF8	# <CJK>
+0x593B	0x5029	# <CJK>
+0x593C	0x504C	# <CJK>
+0x593D	0x4FF3	# <CJK>
+0x593E	0x502C	# <CJK>
+0x593F	0x500F	# <CJK>
+0x5940	0x502E	# <CJK>
+0x5941	0x502D	# <CJK>
+0x5942	0x4FFE	# <CJK>
+0x5943	0x501C	# <CJK>
+0x5944	0x500C	# <CJK>
+0x5945	0x5025	# <CJK>
+0x5946	0x5028	# <CJK>
+0x5947	0x50E8	# <CJK>
+0x5948	0x5043	# <CJK>
+0x5949	0x5055	# <CJK>
+0x594A	0x5048	# <CJK>
+0x594B	0x504E	# <CJK>
+0x594C	0x506C	# <CJK>
+0x594D	0x50C2	# <CJK>
+0x594E	0x513B	# <CJK>
+0x594F	0x5110	# <CJK>
+0x5950	0x513A	# <CJK>
+0x5951	0x50BA	# <CJK>
+0x5952	0x50D6	# <CJK>
+0x5953	0x5106	# <CJK>
+0x5954	0x50ED	# <CJK>
+0x5955	0x50EC	# <CJK>
+0x5956	0x50E6	# <CJK>
+0x5957	0x50EE	# <CJK>
+0x5958	0x5107	# <CJK>
+0x5959	0x510B	# <CJK>
+0x595A	0x4EDD	# <CJK>
+0x595B	0x6C3D	# <CJK>
+0x595C	0x4F58	# <CJK>
+0x595D	0x50C9	# <CJK>
+0x595E	0x4FCE	# <CJK>
+0x595F	0x9FA0	# <CJK>
+0x5960	0x6C46	# <CJK>
+0x5961	0x7CF4	# <CJK>
+0x5962	0x516E	# <CJK>
+0x5963	0x5DFD	# <CJK>
+0x5964	0x9ECC	# <CJK>
+0x5965	0x9998	# <CJK>
+0x5966	0x56C5	# <CJK>
+0x5967	0x5914	# <CJK>
+0x5968	0x52F9	# <CJK>
+0x5969	0x530D	# <CJK>
+0x596A	0x8A07	# <CJK>
+0x596B	0x5310	# <CJK>
+0x596C	0x9CEC	# <CJK>
+0x596D	0x5919	# <CJK>
+0x596E	0x5155	# <CJK>
+0x596F	0x4EA0	# <CJK>
+0x5970	0x5156	# <CJK>
+0x5971	0x4EB3	# <CJK>
+0x5972	0x886E	# <CJK>
+0x5973	0x88A4	# <CJK>
+0x5974	0x893B	# <CJK>
+0x5975	0x81E0	# <CJK>
+0x5976	0x88D2	# <CJK>
+0x5977	0x7980	# <CJK>
+0x5978	0x5B34	# <CJK>
+0x5979	0x8803	# <CJK>
+0x597A	0x7FB8	# <CJK>
+0x597B	0x51AB	# <CJK>
+0x597C	0x51B1	# <CJK>
+0x597D	0x51BD	# <CJK>
+0x597E	0x51BC	# <CJK>
+0x5A21	0x51C7	# <CJK>
+0x5A22	0x5196	# <CJK>
+0x5A23	0x51A2	# <CJK>
+0x5A24	0x51A5	# <CJK>
+0x5A25	0x8A01	# <CJK>
+0x5A26	0x8A10	# <CJK>
+0x5A27	0x8A0C	# <CJK>
+0x5A28	0x8A15	# <CJK>
+0x5A29	0x8B33	# <CJK>
+0x5A2A	0x8A4E	# <CJK>
+0x5A2B	0x8A25	# <CJK>
+0x5A2C	0x8A41	# <CJK>
+0x5A2D	0x8A36	# <CJK>
+0x5A2E	0x8A46	# <CJK>
+0x5A2F	0x8A54	# <CJK>
+0x5A30	0x8A58	# <CJK>
+0x5A31	0x8A52	# <CJK>
+0x5A32	0x8A86	# <CJK>
+0x5A33	0x8A84	# <CJK>
+0x5A34	0x8A7F	# <CJK>
+0x5A35	0x8A70	# <CJK>
+0x5A36	0x8A7C	# <CJK>
+0x5A37	0x8A75	# <CJK>
+0x5A38	0x8A6C	# <CJK>
+0x5A39	0x8A6E	# <CJK>
+0x5A3A	0x8ACD	# <CJK>
+0x5A3B	0x8AE2	# <CJK>
+0x5A3C	0x8A61	# <CJK>
+0x5A3D	0x8A9A	# <CJK>
+0x5A3E	0x8AA5	# <CJK>
+0x5A3F	0x8A91	# <CJK>
+0x5A40	0x8A92	# <CJK>
+0x5A41	0x8ACF	# <CJK>
+0x5A42	0x8AD1	# <CJK>
+0x5A43	0x8AC9	# <CJK>
+0x5A44	0x8ADB	# <CJK>
+0x5A45	0x8AD7	# <CJK>
+0x5A46	0x8AC2	# <CJK>
+0x5A47	0x8AB6	# <CJK>
+0x5A48	0x8AF6	# <CJK>
+0x5A49	0x8AEB	# <CJK>
+0x5A4A	0x8B14	# <CJK>
+0x5A4B	0x8B01	# <CJK>
+0x5A4C	0x8AE4	# <CJK>
+0x5A4D	0x8AED	# <CJK>
+0x5A4E	0x8AFC	# <CJK>
+0x5A4F	0x8AF3	# <CJK>
+0x5A50	0x8AE6	# <CJK>
+0x5A51	0x8AEE	# <CJK>
+0x5A52	0x8ADE	# <CJK>
+0x5A53	0x8B28	# <CJK>
+0x5A54	0x8B9C	# <CJK>
+0x5A55	0x8B16	# <CJK>
+0x5A56	0x8B1A	# <CJK>
+0x5A57	0x8B10	# <CJK>
+0x5A58	0x8B2B	# <CJK>
+0x5A59	0x8B2D	# <CJK>
+0x5A5A	0x8B56	# <CJK>
+0x5A5B	0x8B59	# <CJK>
+0x5A5C	0x8B4E	# <CJK>
+0x5A5D	0x8B9E	# <CJK>
+0x5A5E	0x8B6B	# <CJK>
+0x5A5F	0x8B96	# <CJK>
+0x5A60	0x5369	# <CJK>
+0x5A61	0x537A	# <CJK>
+0x5A62	0x961D	# <CJK>
+0x5A63	0x9622	# <CJK>
+0x5A64	0x9621	# <CJK>
+0x5A65	0x9631	# <CJK>
+0x5A66	0x962A	# <CJK>
+0x5A67	0x963D	# <CJK>
+0x5A68	0x963C	# <CJK>
+0x5A69	0x9642	# <CJK>
+0x5A6A	0x9658	# <CJK>
+0x5A6B	0x9654	# <CJK>
+0x5A6C	0x965F	# <CJK>
+0x5A6D	0x9689	# <CJK>
+0x5A6E	0x966C	# <CJK>
+0x5A6F	0x9672	# <CJK>
+0x5A70	0x9674	# <CJK>
+0x5A71	0x9688	# <CJK>
+0x5A72	0x968D	# <CJK>
+0x5A73	0x9697	# <CJK>
+0x5A74	0x96B0	# <CJK>
+0x5A75	0x9097	# <CJK>
+0x5A76	0x909B	# <CJK>
+0x5A77	0x913A	# <CJK>
+0x5A78	0x9099	# <CJK>
+0x5A79	0x9114	# <CJK>
+0x5A7A	0x90A1	# <CJK>
+0x5A7B	0x90B4	# <CJK>
+0x5A7C	0x90B3	# <CJK>
+0x5A7D	0x90B6	# <CJK>
+0x5A7E	0x9134	# <CJK>
+0x5B21	0x90B8	# <CJK>
+0x5B22	0x90B0	# <CJK>
+0x5B23	0x90DF	# <CJK>
+0x5B24	0x90C5	# <CJK>
+0x5B25	0x90BE	# <CJK>
+0x5B26	0x9136	# <CJK>
+0x5B27	0x90C4	# <CJK>
+0x5B28	0x90C7	# <CJK>
+0x5B29	0x9106	# <CJK>
+0x5B2A	0x9148	# <CJK>
+0x5B2B	0x90E2	# <CJK>
+0x5B2C	0x90DC	# <CJK>
+0x5B2D	0x90D7	# <CJK>
+0x5B2E	0x90DB	# <CJK>
+0x5B2F	0x90EB	# <CJK>
+0x5B30	0x90EF	# <CJK>
+0x5B31	0x90FE	# <CJK>
+0x5B32	0x9104	# <CJK>
+0x5B33	0x9122	# <CJK>
+0x5B34	0x911E	# <CJK>
+0x5B35	0x9123	# <CJK>
+0x5B36	0x9131	# <CJK>
+0x5B37	0x912F	# <CJK>
+0x5B38	0x9139	# <CJK>
+0x5B39	0x9143	# <CJK>
+0x5B3A	0x9146	# <CJK>
+0x5B3B	0x82BB	# <CJK>
+0x5B3C	0x5950	# <CJK>
+0x5B3D	0x52F1	# <CJK>
+0x5B3E	0x52AC	# <CJK>
+0x5B3F	0x52AD	# <CJK>
+0x5B40	0x52BE	# <CJK>
+0x5B41	0x54FF	# <CJK>
+0x5B42	0x52D0	# <CJK>
+0x5B43	0x52D6	# <CJK>
+0x5B44	0x52F0	# <CJK>
+0x5B45	0x53DF	# <CJK>
+0x5B46	0x71EE	# <CJK>
+0x5B47	0x77CD	# <CJK>
+0x5B48	0x5EF4	# <CJK>
+0x5B49	0x51F5	# <CJK>
+0x5B4A	0x51FC	# <CJK>
+0x5B4B	0x9B2F	# <CJK>
+0x5B4C	0x53B6	# <CJK>
+0x5B4D	0x5F01	# <CJK>
+0x5B4E	0x755A	# <CJK>
+0x5B4F	0x5DF0	# <CJK>
+0x5B50	0x574C	# <CJK>
+0x5B51	0x580A	# <CJK>
+0x5B52	0x57A1	# <CJK>
+0x5B53	0x587E	# <CJK>
+0x5B54	0x58BC	# <CJK>
+0x5B55	0x58C5	# <CJK>
+0x5B56	0x58D1	# <CJK>
+0x5B57	0x5729	# <CJK>
+0x5B58	0x572C	# <CJK>
+0x5B59	0x572A	# <CJK>
+0x5B5A	0x5733	# <CJK>
+0x5B5B	0x58D9	# <CJK>
+0x5B5C	0x572E	# <CJK>
+0x5B5D	0x572F	# <CJK>
+0x5B5E	0x58E2	# <CJK>
+0x5B5F	0x573B	# <CJK>
+0x5B60	0x5742	# <CJK>
+0x5B61	0x5769	# <CJK>
+0x5B62	0x58E0	# <CJK>
+0x5B63	0x576B	# <CJK>
+0x5B64	0x58DA	# <CJK>
+0x5B65	0x577C	# <CJK>
+0x5B66	0x577B	# <CJK>
+0x5B67	0x5768	# <CJK>
+0x5B68	0x576D	# <CJK>
+0x5B69	0x5776	# <CJK>
+0x5B6A	0x5773	# <CJK>
+0x5B6B	0x57E1	# <CJK>
+0x5B6C	0x57A4	# <CJK>
+0x5B6D	0x578C	# <CJK>
+0x5B6E	0x584F	# <CJK>
+0x5B6F	0x57CF	# <CJK>
+0x5B70	0x57A7	# <CJK>
+0x5B71	0x5816	# <CJK>
+0x5B72	0x5793	# <CJK>
+0x5B73	0x57A0	# <CJK>
+0x5B74	0x57D5	# <CJK>
+0x5B75	0x5852	# <CJK>
+0x5B76	0x581D	# <CJK>
+0x5B77	0x5864	# <CJK>
+0x5B78	0x57D2	# <CJK>
+0x5B79	0x57B8	# <CJK>
+0x5B7A	0x57F4	# <CJK>
+0x5B7B	0x57EF	# <CJK>
+0x5B7C	0x57F8	# <CJK>
+0x5B7D	0x57E4	# <CJK>
+0x5B7E	0x57DD	# <CJK>
+0x5C21	0x580B	# <CJK>
+0x5C22	0x580D	# <CJK>
+0x5C23	0x57FD	# <CJK>
+0x5C24	0x57ED	# <CJK>
+0x5C25	0x5800	# <CJK>
+0x5C26	0x581E	# <CJK>
+0x5C27	0x5819	# <CJK>
+0x5C28	0x5844	# <CJK>
+0x5C29	0x5820	# <CJK>
+0x5C2A	0x5865	# <CJK>
+0x5C2B	0x586C	# <CJK>
+0x5C2C	0x5881	# <CJK>
+0x5C2D	0x5889	# <CJK>
+0x5C2E	0x589A	# <CJK>
+0x5C2F	0x5880	# <CJK>
+0x5C30	0x99A8	# <CJK>
+0x5C31	0x9F19	# <CJK>
+0x5C32	0x61FF	# <CJK>
+0x5C33	0x8279	# <CJK>
+0x5C34	0x827D	# <CJK>
+0x5C35	0x827F	# <CJK>
+0x5C36	0x828F	# <CJK>
+0x5C37	0x828A	# <CJK>
+0x5C38	0x82A8	# <CJK>
+0x5C39	0x8284	# <CJK>
+0x5C3A	0x828E	# <CJK>
+0x5C3B	0x8291	# <CJK>
+0x5C3C	0x858C	# <CJK>
+0x5C3D	0x8299	# <CJK>
+0x5C3E	0x82AB	# <CJK>
+0x5C3F	0x8553	# <CJK>
+0x5C40	0x82BE	# <CJK>
+0x5C41	0x82B0	# <CJK>
+0x5C42	0x85F6	# <CJK>
+0x5C43	0x82CA	# <CJK>
+0x5C44	0x82E3	# <CJK>
+0x5C45	0x8298	# <CJK>
+0x5C46	0x82B7	# <CJK>
+0x5C47	0x82AE	# <CJK>
+0x5C48	0x83A7	# <CJK>
+0x5C49	0x8407	# <CJK>
+0x5C4A	0x84EF	# <CJK>
+0x5C4B	0x82A9	# <CJK>
+0x5C4C	0x82B4	# <CJK>
+0x5C4D	0x82A1	# <CJK>
+0x5C4E	0x82AA	# <CJK>
+0x5C4F	0x829F	# <CJK>
+0x5C50	0x82C4	# <CJK>
+0x5C51	0x82E7	# <CJK>
+0x5C52	0x82A4	# <CJK>
+0x5C53	0x82E1	# <CJK>
+0x5C54	0x8309	# <CJK>
+0x5C55	0x82F7	# <CJK>
+0x5C56	0x82E4	# <CJK>
+0x5C57	0x8622	# <CJK>
+0x5C58	0x8307	# <CJK>
+0x5C59	0x82DC	# <CJK>
+0x5C5A	0x82F4	# <CJK>
+0x5C5B	0x82D2	# <CJK>
+0x5C5C	0x82D8	# <CJK>
+0x5C5D	0x830C	# <CJK>
+0x5C5E	0x82FB	# <CJK>
+0x5C5F	0x82D3	# <CJK>
+0x5C60	0x8526	# <CJK>
+0x5C61	0x831A	# <CJK>
+0x5C62	0x8306	# <CJK>
+0x5C63	0x584B	# <CJK>
+0x5C64	0x7162	# <CJK>
+0x5C65	0x82E0	# <CJK>
+0x5C66	0x82D5	# <CJK>
+0x5C67	0x831C	# <CJK>
+0x5C68	0x8351	# <CJK>
+0x5C69	0x8558	# <CJK>
+0x5C6A	0x84FD	# <CJK>
+0x5C6B	0x8308	# <CJK>
+0x5C6C	0x8392	# <CJK>
+0x5C6D	0x833C	# <CJK>
+0x5C6E	0x8334	# <CJK>
+0x5C6F	0x8331	# <CJK>
+0x5C70	0x839B	# <CJK>
+0x5C71	0x854E	# <CJK>
+0x5C72	0x832F	# <CJK>
+0x5C73	0x834F	# <CJK>
+0x5C74	0x8347	# <CJK>
+0x5C75	0x8343	# <CJK>
+0x5C76	0x8588	# <CJK>
+0x5C77	0x8340	# <CJK>
+0x5C78	0x8317	# <CJK>
+0x5C79	0x85BA	# <CJK>
+0x5C7A	0x832D	# <CJK>
+0x5C7B	0x833A	# <CJK>
+0x5C7C	0x8333	# <CJK>
+0x5C7D	0x7296	# <CJK>
+0x5C7E	0x6ECE	# <CJK>
+0x5D21	0x8541	# <CJK>
+0x5D22	0x831B	# <CJK>
+0x5D23	0x85CE	# <CJK>
+0x5D24	0x8552	# <CJK>
+0x5D25	0x84C0	# <CJK>
+0x5D26	0x8452	# <CJK>
+0x5D27	0x8464	# <CJK>
+0x5D28	0x83B0	# <CJK>
+0x5D29	0x8378	# <CJK>
+0x5D2A	0x8494	# <CJK>
+0x5D2B	0x8435	# <CJK>
+0x5D2C	0x83A0	# <CJK>
+0x5D2D	0x83AA	# <CJK>
+0x5D2E	0x8393	# <CJK>
+0x5D2F	0x839C	# <CJK>
+0x5D30	0x8385	# <CJK>
+0x5D31	0x837C	# <CJK>
+0x5D32	0x859F	# <CJK>
+0x5D33	0x83A9	# <CJK>
+0x5D34	0x837D	# <CJK>
+0x5D35	0x8555	# <CJK>
+0x5D36	0x837B	# <CJK>
+0x5D37	0x8398	# <CJK>
+0x5D38	0x839E	# <CJK>
+0x5D39	0x83A8	# <CJK>
+0x5D3A	0x9DAF	# <CJK>
+0x5D3B	0x8493	# <CJK>
+0x5D3C	0x83C1	# <CJK>
+0x5D3D	0x8401	# <CJK>
+0x5D3E	0x83E5	# <CJK>
+0x5D3F	0x83D8	# <CJK>
+0x5D40	0x5807	# <CJK>
+0x5D41	0x8418	# <CJK>
+0x5D42	0x840B	# <CJK>
+0x5D43	0x83DD	# <CJK>
+0x5D44	0x83FD	# <CJK>
+0x5D45	0x83D6	# <CJK>
+0x5D46	0x841C	# <CJK>
+0x5D47	0x8438	# <CJK>
+0x5D48	0x8411	# <CJK>
+0x5D49	0x8406	# <CJK>
+0x5D4A	0x83D4	# <CJK>
+0x5D4B	0x83DF	# <CJK>
+0x5D4C	0x840F	# <CJK>
+0x5D4D	0x8403	# <CJK>
+0x5D4E	0x83F8	# <CJK>
+0x5D4F	0x83F9	# <CJK>
+0x5D50	0x83EA	# <CJK>
+0x5D51	0x83C5	# <CJK>
+0x5D52	0x83C0	# <CJK>
+0x5D53	0x7E08	# <CJK>
+0x5D54	0x83F0	# <CJK>
+0x5D55	0x83E1	# <CJK>
+0x5D56	0x845C	# <CJK>
+0x5D57	0x8451	# <CJK>
+0x5D58	0x845A	# <CJK>
+0x5D59	0x8459	# <CJK>
+0x5D5A	0x8473	# <CJK>
+0x5D5B	0x8546	# <CJK>
+0x5D5C	0x8488	# <CJK>
+0x5D5D	0x847A	# <CJK>
+0x5D5E	0x8562	# <CJK>
+0x5D5F	0x8478	# <CJK>
+0x5D60	0x843C	# <CJK>
+0x5D61	0x8446	# <CJK>
+0x5D62	0x8469	# <CJK>
+0x5D63	0x8476	# <CJK>
+0x5D64	0x851E	# <CJK>
+0x5D65	0x848E	# <CJK>
+0x5D66	0x8431	# <CJK>
+0x5D67	0x846D	# <CJK>
+0x5D68	0x84C1	# <CJK>
+0x5D69	0x84CD	# <CJK>
+0x5D6A	0x84D0	# <CJK>
+0x5D6B	0x9A40	# <CJK>
+0x5D6C	0x84BD	# <CJK>
+0x5D6D	0x84D3	# <CJK>
+0x5D6E	0x84CA	# <CJK>
+0x5D6F	0x84BF	# <CJK>
+0x5D70	0x84BA	# <CJK>
+0x5D71	0x863A	# <CJK>
+0x5D72	0x84A1	# <CJK>
+0x5D73	0x84B9	# <CJK>
+0x5D74	0x84B4	# <CJK>
+0x5D75	0x8497	# <CJK>
+0x5D76	0x93A3	# <CJK>
+0x5D77	0x8577	# <CJK>
+0x5D78	0x850C	# <CJK>
+0x5D79	0x750D	# <CJK>
+0x5D7A	0x8538	# <CJK>
+0x5D7B	0x84F0	# <CJK>
+0x5D7C	0x861E	# <CJK>
+0x5D7D	0x851F	# <CJK>
+0x5D7E	0x85FA	# <CJK>
+0x5E21	0x8556	# <CJK>
+0x5E22	0x853B	# <CJK>
+0x5E23	0x84FF	# <CJK>
+0x5E24	0x84FC	# <CJK>
+0x5E25	0x8559	# <CJK>
+0x5E26	0x8548	# <CJK>
+0x5E27	0x8568	# <CJK>
+0x5E28	0x8564	# <CJK>
+0x5E29	0x855E	# <CJK>
+0x5E2A	0x857A	# <CJK>
+0x5E2B	0x77A2	# <CJK>
+0x5E2C	0x8543	# <CJK>
+0x5E2D	0x8604	# <CJK>
+0x5E2E	0x857B	# <CJK>
+0x5E2F	0x85A4	# <CJK>
+0x5E30	0x85A8	# <CJK>
+0x5E31	0x8587	# <CJK>
+0x5E32	0x858F	# <CJK>
+0x5E33	0x8579	# <CJK>
+0x5E34	0x85EA	# <CJK>
+0x5E35	0x859C	# <CJK>
+0x5E36	0x8585	# <CJK>
+0x5E37	0x85B9	# <CJK>
+0x5E38	0x85B7	# <CJK>
+0x5E39	0x85B0	# <CJK>
+0x5E3A	0x861A	# <CJK>
+0x5E3B	0x85C1	# <CJK>
+0x5E3C	0x85DC	# <CJK>
+0x5E3D	0x85FF	# <CJK>
+0x5E3E	0x8627	# <CJK>
+0x5E3F	0x8605	# <CJK>
+0x5E40	0x8629	# <CJK>
+0x5E41	0x8616	# <CJK>
+0x5E42	0x863C	# <CJK>
+0x5E43	0x5EFE	# <CJK>
+0x5E44	0x5F08	# <CJK>
+0x5E45	0x593C	# <CJK>
+0x5E46	0x5969	# <CJK>
+0x5E47	0x8037	# <CJK>
+0x5E48	0x5955	# <CJK>
+0x5E49	0x595A	# <CJK>
+0x5E4A	0x5958	# <CJK>
+0x5E4B	0x530F	# <CJK>
+0x5E4C	0x5C22	# <CJK>
+0x5E4D	0x5C25	# <CJK>
+0x5E4E	0x5C2C	# <CJK>
+0x5E4F	0x5C37	# <CJK>
+0x5E50	0x624C	# <CJK>
+0x5E51	0x636B	# <CJK>
+0x5E52	0x6476	# <CJK>
+0x5E53	0x62BB	# <CJK>
+0x5E54	0x62CA	# <CJK>
+0x5E55	0x62DA	# <CJK>
+0x5E56	0x62D7	# <CJK>
+0x5E57	0x62EE	# <CJK>
+0x5E58	0x649F	# <CJK>
+0x5E59	0x62F6	# <CJK>
+0x5E5A	0x6339	# <CJK>
+0x5E5B	0x634B	# <CJK>
+0x5E5C	0x6343	# <CJK>
+0x5E5D	0x63AD	# <CJK>
+0x5E5E	0x63F6	# <CJK>
+0x5E5F	0x6371	# <CJK>
+0x5E60	0x637A	# <CJK>
+0x5E61	0x638E	# <CJK>
+0x5E62	0x6451	# <CJK>
+0x5E63	0x636D	# <CJK>
+0x5E64	0x63AC	# <CJK>
+0x5E65	0x638A	# <CJK>
+0x5E66	0x6369	# <CJK>
+0x5E67	0x63AE	# <CJK>
+0x5E68	0x645C	# <CJK>
+0x5E69	0x63F2	# <CJK>
+0x5E6A	0x63F8	# <CJK>
+0x5E6B	0x63E0	# <CJK>
+0x5E6C	0x64B3	# <CJK>
+0x5E6D	0x63C4	# <CJK>
+0x5E6E	0x63DE	# <CJK>
+0x5E6F	0x63CE	# <CJK>
+0x5E70	0x6452	# <CJK>
+0x5E71	0x63C6	# <CJK>
+0x5E72	0x63BE	# <CJK>
+0x5E73	0x6504	# <CJK>
+0x5E74	0x6441	# <CJK>
+0x5E75	0x640B	# <CJK>
+0x5E76	0x641B	# <CJK>
+0x5E77	0x6420	# <CJK>
+0x5E78	0x640C	# <CJK>
+0x5E79	0x6426	# <CJK>
+0x5E7A	0x6421	# <CJK>
+0x5E7B	0x645E	# <CJK>
+0x5E7C	0x6516	# <CJK>
+0x5E7D	0x646D	# <CJK>
+0x5E7E	0x6496	# <CJK>
+0x5F21	0x647A	# <CJK>
+0x5F22	0x64F7	# <CJK>
+0x5F23	0x64FC	# <CJK>
+0x5F24	0x6499	# <CJK>
+0x5F25	0x651B	# <CJK>
+0x5F26	0x64C0	# <CJK>
+0x5F27	0x64D0	# <CJK>
+0x5F28	0x64D7	# <CJK>
+0x5F29	0x64E4	# <CJK>
+0x5F2A	0x64E2	# <CJK>
+0x5F2B	0x6509	# <CJK>
+0x5F2C	0x6525	# <CJK>
+0x5F2D	0x652E	# <CJK>
+0x5F2E	0x5F0B	# <CJK>
+0x5F2F	0x5FD2	# <CJK>
+0x5F30	0x7519	# <CJK>
+0x5F31	0x5F11	# <CJK>
+0x5F32	0x535F	# <CJK>
+0x5F33	0x53F1	# <CJK>
+0x5F34	0x5630	# <CJK>
+0x5F35	0x53E9	# <CJK>
+0x5F36	0x53E8	# <CJK>
+0x5F37	0x53FB	# <CJK>
+0x5F38	0x5412	# <CJK>
+0x5F39	0x5416	# <CJK>
+0x5F3A	0x5406	# <CJK>
+0x5F3B	0x544B	# <CJK>
+0x5F3C	0x5638	# <CJK>
+0x5F3D	0x56C8	# <CJK>
+0x5F3E	0x5454	# <CJK>
+0x5F3F	0x56A6	# <CJK>
+0x5F40	0x5443	# <CJK>
+0x5F41	0x5421	# <CJK>
+0x5F42	0x5504	# <CJK>
+0x5F43	0x54BC	# <CJK>
+0x5F44	0x5423	# <CJK>
+0x5F45	0x5432	# <CJK>
+0x5F46	0x5482	# <CJK>
+0x5F47	0x5494	# <CJK>
+0x5F48	0x5477	# <CJK>
+0x5F49	0x5471	# <CJK>
+0x5F4A	0x5464	# <CJK>
+0x5F4B	0x549A	# <CJK>
+0x5F4C	0x5680	# <CJK>
+0x5F4D	0x5484	# <CJK>
+0x5F4E	0x5476	# <CJK>
+0x5F4F	0x5466	# <CJK>
+0x5F50	0x565D	# <CJK>
+0x5F51	0x54D0	# <CJK>
+0x5F52	0x54AD	# <CJK>
+0x5F53	0x54C2	# <CJK>
+0x5F54	0x54B4	# <CJK>
+0x5F55	0x5660	# <CJK>
+0x5F56	0x54A7	# <CJK>
+0x5F57	0x54A6	# <CJK>
+0x5F58	0x5635	# <CJK>
+0x5F59	0x55F6	# <CJK>
+0x5F5A	0x5472	# <CJK>
+0x5F5B	0x54A3	# <CJK>
+0x5F5C	0x5666	# <CJK>
+0x5F5D	0x54BB	# <CJK>
+0x5F5E	0x54BF	# <CJK>
+0x5F5F	0x54CC	# <CJK>
+0x5F60	0x5672	# <CJK>
+0x5F61	0x54DA	# <CJK>
+0x5F62	0x568C	# <CJK>
+0x5F63	0x54A9	# <CJK>
+0x5F64	0x54AA	# <CJK>
+0x5F65	0x54A4	# <CJK>
+0x5F66	0x5665	# <CJK>
+0x5F67	0x54CF	# <CJK>
+0x5F68	0x54DE	# <CJK>
+0x5F69	0x561C	# <CJK>
+0x5F6A	0x54E7	# <CJK>
+0x5F6B	0x562E	# <CJK>
+0x5F6C	0x54FD	# <CJK>
+0x5F6D	0x5514	# <CJK>
+0x5F6E	0x54F3	# <CJK>
+0x5F6F	0x55E9	# <CJK>
+0x5F70	0x5523	# <CJK>
+0x5F71	0x550F	# <CJK>
+0x5F72	0x5511	# <CJK>
+0x5F73	0x5527	# <CJK>
+0x5F74	0x552A	# <CJK>
+0x5F75	0x5616	# <CJK>
+0x5F76	0x558F	# <CJK>
+0x5F77	0x55B5	# <CJK>
+0x5F78	0x5549	# <CJK>
+0x5F79	0x56C0	# <CJK>
+0x5F7A	0x5541	# <CJK>
+0x5F7B	0x5555	# <CJK>
+0x5F7C	0x553F	# <CJK>
+0x5F7D	0x5550	# <CJK>
+0x5F7E	0x553C	# <CJK>
+0x6021	0x5537	# <CJK>
+0x6022	0x5556	# <CJK>
+0x6023	0x5575	# <CJK>
+0x6024	0x5576	# <CJK>
+0x6025	0x5577	# <CJK>
+0x6026	0x5533	# <CJK>
+0x6027	0x5530	# <CJK>
+0x6028	0x555C	# <CJK>
+0x6029	0x558B	# <CJK>
+0x602A	0x55D2	# <CJK>
+0x602B	0x5583	# <CJK>
+0x602C	0x55B1	# <CJK>
+0x602D	0x55B9	# <CJK>
+0x602E	0x5588	# <CJK>
+0x602F	0x5581	# <CJK>
+0x6030	0x559F	# <CJK>
+0x6031	0x557E	# <CJK>
+0x6032	0x55D6	# <CJK>
+0x6033	0x5591	# <CJK>
+0x6034	0x557B	# <CJK>
+0x6035	0x55DF	# <CJK>
+0x6036	0x560D	# <CJK>
+0x6037	0x56B3	# <CJK>
+0x6038	0x5594	# <CJK>
+0x6039	0x5599	# <CJK>
+0x603A	0x55EA	# <CJK>
+0x603B	0x55F7	# <CJK>
+0x603C	0x55C9	# <CJK>
+0x603D	0x561F	# <CJK>
+0x603E	0x55D1	# <CJK>
+0x603F	0x56C1	# <CJK>
+0x6040	0x55EC	# <CJK>
+0x6041	0x55D4	# <CJK>
+0x6042	0x55E6	# <CJK>
+0x6043	0x55DD	# <CJK>
+0x6044	0x55C4	# <CJK>
+0x6045	0x55EF	# <CJK>
+0x6046	0x55E5	# <CJK>
+0x6047	0x55F2	# <CJK>
+0x6048	0x566F	# <CJK>
+0x6049	0x55CC	# <CJK>
+0x604A	0x55CD	# <CJK>
+0x604B	0x55E8	# <CJK>
+0x604C	0x55F5	# <CJK>
+0x604D	0x55E4	# <CJK>
+0x604E	0x8F61	# <CJK>
+0x604F	0x561E	# <CJK>
+0x6050	0x5608	# <CJK>
+0x6051	0x560C	# <CJK>
+0x6052	0x5601	# <CJK>
+0x6053	0x56B6	# <CJK>
+0x6054	0x5623	# <CJK>
+0x6055	0x55FE	# <CJK>
+0x6056	0x5600	# <CJK>
+0x6057	0x5627	# <CJK>
+0x6058	0x562D	# <CJK>
+0x6059	0x5658	# <CJK>
+0x605A	0x5639	# <CJK>
+0x605B	0x5657	# <CJK>
+0x605C	0x562C	# <CJK>
+0x605D	0x564D	# <CJK>
+0x605E	0x5662	# <CJK>
+0x605F	0x5659	# <CJK>
+0x6060	0x5695	# <CJK>
+0x6061	0x564C	# <CJK>
+0x6062	0x5654	# <CJK>
+0x6063	0x5686	# <CJK>
+0x6064	0x5664	# <CJK>
+0x6065	0x5671	# <CJK>
+0x6066	0x566B	# <CJK>
+0x6067	0x567B	# <CJK>
+0x6068	0x567C	# <CJK>
+0x6069	0x5685	# <CJK>
+0x606A	0x5693	# <CJK>
+0x606B	0x56AF	# <CJK>
+0x606C	0x56D4	# <CJK>
+0x606D	0x56D7	# <CJK>
+0x606E	0x56DD	# <CJK>
+0x606F	0x56E1	# <CJK>
+0x6070	0x5707	# <CJK>
+0x6071	0x56EB	# <CJK>
+0x6072	0x56F9	# <CJK>
+0x6073	0x56FF	# <CJK>
+0x6074	0x5704	# <CJK>
+0x6075	0x570A	# <CJK>
+0x6076	0x5709	# <CJK>
+0x6077	0x571C	# <CJK>
+0x6078	0x5E43	# <CJK>
+0x6079	0x5E19	# <CJK>
+0x607A	0x5E14	# <CJK>
+0x607B	0x5E11	# <CJK>
+0x607C	0x5E6C	# <CJK>
+0x607D	0x5E58	# <CJK>
+0x607E	0x5E57	# <CJK>
+0x6121	0x5E37	# <CJK>
+0x6122	0x5E44	# <CJK>
+0x6123	0x5E54	# <CJK>
+0x6124	0x5E5B	# <CJK>
+0x6125	0x5E5E	# <CJK>
+0x6126	0x5E61	# <CJK>
+0x6127	0x5C8C	# <CJK>
+0x6128	0x5C7A	# <CJK>
+0x6129	0x5C8D	# <CJK>
+0x612A	0x5C90	# <CJK>
+0x612B	0x5D87	# <CJK>
+0x612C	0x5C88	# <CJK>
+0x612D	0x5CF4	# <CJK>
+0x612E	0x5C99	# <CJK>
+0x612F	0x5C91	# <CJK>
+0x6130	0x5D50	# <CJK>
+0x6131	0x5C9C	# <CJK>
+0x6132	0x5CB5	# <CJK>
+0x6133	0x5CA2	# <CJK>
+0x6134	0x5D2C	# <CJK>
+0x6135	0x5CAC	# <CJK>
+0x6136	0x5CAB	# <CJK>
+0x6137	0x5CB1	# <CJK>
+0x6138	0x5CA3	# <CJK>
+0x6139	0x5CC1	# <CJK>
+0x613A	0x5CB7	# <CJK>
+0x613B	0x5DA7	# <CJK>
+0x613C	0x5CD2	# <CJK>
+0x613D	0x5DA0	# <CJK>
+0x613E	0x5CCB	# <CJK>
+0x613F	0x5D22	# <CJK>
+0x6140	0x5D97	# <CJK>
+0x6141	0x5D0D	# <CJK>
+0x6142	0x5D27	# <CJK>
+0x6143	0x5D26	# <CJK>
+0x6144	0x5D2E	# <CJK>
+0x6145	0x5D24	# <CJK>
+0x6146	0x5D1E	# <CJK>
+0x6147	0x5D06	# <CJK>
+0x6148	0x5D1B	# <CJK>
+0x6149	0x5DB8	# <CJK>
+0x614A	0x5D3E	# <CJK>
+0x614B	0x5D34	# <CJK>
+0x614C	0x5D3D	# <CJK>
+0x614D	0x5D6C	# <CJK>
+0x614E	0x5D5B	# <CJK>
+0x614F	0x5D6F	# <CJK>
+0x6150	0x5D81	# <CJK>
+0x6151	0x5D6B	# <CJK>
+0x6152	0x5D4B	# <CJK>
+0x6153	0x5D4A	# <CJK>
+0x6154	0x5D69	# <CJK>
+0x6155	0x5D74	# <CJK>
+0x6156	0x5D82	# <CJK>
+0x6157	0x5D99	# <CJK>
+0x6158	0x5D9D	# <CJK>
+0x6159	0x8C73	# <CJK>
+0x615A	0x5DB7	# <CJK>
+0x615B	0x5DD4	# <CJK>
+0x615C	0x5F73	# <CJK>
+0x615D	0x5F77	# <CJK>
+0x615E	0x5F82	# <CJK>
+0x615F	0x5F87	# <CJK>
+0x6160	0x5F89	# <CJK>
+0x6161	0x540E	# <CJK>
+0x6162	0x5FA0	# <CJK>
+0x6163	0x5F99	# <CJK>
+0x6164	0x5F9C	# <CJK>
+0x6165	0x5FA8	# <CJK>
+0x6166	0x5FAD	# <CJK>
+0x6167	0x5FB5	# <CJK>
+0x6168	0x5FBC	# <CJK>
+0x6169	0x8862	# <CJK>
+0x616A	0x5F61	# <CJK>
+0x616B	0x72AD	# <CJK>
+0x616C	0x72B0	# <CJK>
+0x616D	0x72B4	# <CJK>
+0x616E	0x7377	# <CJK>
+0x616F	0x7341	# <CJK>
+0x6170	0x72C3	# <CJK>
+0x6171	0x72C1	# <CJK>
+0x6172	0x72CE	# <CJK>
+0x6173	0x72CD	# <CJK>
+0x6174	0x72D2	# <CJK>
+0x6175	0x72E8	# <CJK>
+0x6176	0x736A	# <CJK>
+0x6177	0x72E9	# <CJK>
+0x6178	0x733B	# <CJK>
+0x6179	0x72F4	# <CJK>
+0x617A	0x72F7	# <CJK>
+0x617B	0x7301	# <CJK>
+0x617C	0x72F3	# <CJK>
+0x617D	0x736B	# <CJK>
+0x617E	0x72FA	# <CJK>
+0x6221	0x72FB	# <CJK>
+0x6222	0x7317	# <CJK>
+0x6223	0x7313	# <CJK>
+0x6224	0x7380	# <CJK>
+0x6225	0x730A	# <CJK>
+0x6226	0x731E	# <CJK>
+0x6227	0x731D	# <CJK>
+0x6228	0x737C	# <CJK>
+0x6229	0x7322	# <CJK>
+0x622A	0x7339	# <CJK>
+0x622B	0x7325	# <CJK>
+0x622C	0x732C	# <CJK>
+0x622D	0x7338	# <CJK>
+0x622E	0x7331	# <CJK>
+0x622F	0x7350	# <CJK>
+0x6230	0x734D	# <CJK>
+0x6231	0x7357	# <CJK>
+0x6232	0x7360	# <CJK>
+0x6233	0x736C	# <CJK>
+0x6234	0x736F	# <CJK>
+0x6235	0x737E	# <CJK>
+0x6236	0x821B	# <CJK>
+0x6237	0x5925	# <CJK>
+0x6238	0x98E7	# <CJK>
+0x6239	0x5924	# <CJK>
+0x623A	0x5902	# <CJK>
+0x623B	0x98E0	# <CJK>
+0x623C	0x9933	# <CJK>
+0x623D	0x98E9	# <CJK>
+0x623E	0x993C	# <CJK>
+0x623F	0x98EA	# <CJK>
+0x6240	0x98EB	# <CJK>
+0x6241	0x98ED	# <CJK>
+0x6242	0x98F4	# <CJK>
+0x6243	0x9909	# <CJK>
+0x6244	0x9911	# <CJK>
+0x6245	0x4F59	# <CJK>
+0x6246	0x991B	# <CJK>
+0x6247	0x9937	# <CJK>
+0x6248	0x993F	# <CJK>
+0x6249	0x9943	# <CJK>
+0x624A	0x9948	# <CJK>
+0x624B	0x9949	# <CJK>
+0x624C	0x994A	# <CJK>
+0x624D	0x994C	# <CJK>
+0x624E	0x9962	# <CJK>
+0x624F	0x5E80	# <CJK>
+0x6250	0x5EE1	# <CJK>
+0x6251	0x5E8B	# <CJK>
+0x6252	0x5E96	# <CJK>
+0x6253	0x5EA5	# <CJK>
+0x6254	0x5EA0	# <CJK>
+0x6255	0x5EB9	# <CJK>
+0x6256	0x5EB5	# <CJK>
+0x6257	0x5EBE	# <CJK>
+0x6258	0x5EB3	# <CJK>
+0x6259	0x8CE1	# <CJK>
+0x625A	0x5ED2	# <CJK>
+0x625B	0x5ED1	# <CJK>
+0x625C	0x5EDB	# <CJK>
+0x625D	0x5EE8	# <CJK>
+0x625E	0x5EEA	# <CJK>
+0x625F	0x81BA	# <CJK>
+0x6260	0x5FC4	# <CJK>
+0x6261	0x5FC9	# <CJK>
+0x6262	0x5FD6	# <CJK>
+0x6263	0x61FA	# <CJK>
+0x6264	0x61AE	# <CJK>
+0x6265	0x5FEE	# <CJK>
+0x6266	0x616A	# <CJK>
+0x6267	0x5FE1	# <CJK>
+0x6268	0x5FE4	# <CJK>
+0x6269	0x613E	# <CJK>
+0x626A	0x60B5	# <CJK>
+0x626B	0x6134	# <CJK>
+0x626C	0x5FEA	# <CJK>
+0x626D	0x5FED	# <CJK>
+0x626E	0x5FF8	# <CJK>
+0x626F	0x6019	# <CJK>
+0x6270	0x6035	# <CJK>
+0x6271	0x6026	# <CJK>
+0x6272	0x601B	# <CJK>
+0x6273	0x600F	# <CJK>
+0x6274	0x600D	# <CJK>
+0x6275	0x6029	# <CJK>
+0x6276	0x602B	# <CJK>
+0x6277	0x600A	# <CJK>
+0x6278	0x61CC	# <CJK>
+0x6279	0x6021	# <CJK>
+0x627A	0x615F	# <CJK>
+0x627B	0x61E8	# <CJK>
+0x627C	0x60FB	# <CJK>
+0x627D	0x6137	# <CJK>
+0x627E	0x6042	# <CJK>
+0x6321	0x606A	# <CJK>
+0x6322	0x60F2	# <CJK>
+0x6323	0x6096	# <CJK>
+0x6324	0x609A	# <CJK>
+0x6325	0x6173	# <CJK>
+0x6326	0x609D	# <CJK>
+0x6327	0x6083	# <CJK>
+0x6328	0x6092	# <CJK>
+0x6329	0x608C	# <CJK>
+0x632A	0x609B	# <CJK>
+0x632B	0x611C	# <CJK>
+0x632C	0x60BB	# <CJK>
+0x632D	0x60B1	# <CJK>
+0x632E	0x60DD	# <CJK>
+0x632F	0x60D8	# <CJK>
+0x6330	0x60C6	# <CJK>
+0x6331	0x60DA	# <CJK>
+0x6332	0x60B4	# <CJK>
+0x6333	0x6120	# <CJK>
+0x6334	0x6192	# <CJK>
+0x6335	0x6115	# <CJK>
+0x6336	0x6123	# <CJK>
+0x6337	0x60F4	# <CJK>
+0x6338	0x6100	# <CJK>
+0x6339	0x610E	# <CJK>
+0x633A	0x612B	# <CJK>
+0x633B	0x614A	# <CJK>
+0x633C	0x6175	# <CJK>
+0x633D	0x61AC	# <CJK>
+0x633E	0x6194	# <CJK>
+0x633F	0x61A7	# <CJK>
+0x6340	0x61B7	# <CJK>
+0x6341	0x61D4	# <CJK>
+0x6342	0x61F5	# <CJK>
+0x6343	0x5FDD	# <CJK>
+0x6344	0x96B3	# <CJK>
+0x6345	0x9582	# <CJK>
+0x6346	0x9586	# <CJK>
+0x6347	0x95C8	# <CJK>
+0x6348	0x958E	# <CJK>
+0x6349	0x9594	# <CJK>
+0x634A	0x958C	# <CJK>
+0x634B	0x95E5	# <CJK>
+0x634C	0x95AD	# <CJK>
+0x634D	0x95AB	# <CJK>
+0x634E	0x9B2E	# <CJK>
+0x634F	0x95AC	# <CJK>
+0x6350	0x95BE	# <CJK>
+0x6351	0x95B6	# <CJK>
+0x6352	0x9B29	# <CJK>
+0x6353	0x95BF	# <CJK>
+0x6354	0x95BD	# <CJK>
+0x6355	0x95BC	# <CJK>
+0x6356	0x95C3	# <CJK>
+0x6357	0x95CB	# <CJK>
+0x6358	0x95D4	# <CJK>
+0x6359	0x95D0	# <CJK>
+0x635A	0x95D5	# <CJK>
+0x635B	0x95DE	# <CJK>
+0x635C	0x4E2C	# <CJK>
+0x635D	0x723F	# <CJK>
+0x635E	0x6215	# <CJK>
+0x635F	0x6C35	# <CJK>
+0x6360	0x6C54	# <CJK>
+0x6361	0x6C5C	# <CJK>
+0x6362	0x6C4A	# <CJK>
+0x6363	0x7043	# <CJK>
+0x6364	0x6C85	# <CJK>
+0x6365	0x6C90	# <CJK>
+0x6366	0x6C94	# <CJK>
+0x6367	0x6C8C	# <CJK>
+0x6368	0x6C68	# <CJK>
+0x6369	0x6C69	# <CJK>
+0x636A	0x6C74	# <CJK>
+0x636B	0x6C76	# <CJK>
+0x636C	0x6C86	# <CJK>
+0x636D	0x6F59	# <CJK>
+0x636E	0x6CD0	# <CJK>
+0x636F	0x6CD4	# <CJK>
+0x6370	0x6CAD	# <CJK>
+0x6371	0x7027	# <CJK>
+0x6372	0x7018	# <CJK>
+0x6373	0x6CF1	# <CJK>
+0x6374	0x6CD7	# <CJK>
+0x6375	0x6CB2	# <CJK>
+0x6376	0x6CE0	# <CJK>
+0x6377	0x6CD6	# <CJK>
+0x6378	0x6FFC	# <CJK>
+0x6379	0x6CEB	# <CJK>
+0x637A	0x6CEE	# <CJK>
+0x637B	0x6CB1	# <CJK>
+0x637C	0x6CD3	# <CJK>
+0x637D	0x6CEF	# <CJK>
+0x637E	0x6D87	# <CJK>
+0x6421	0x6D39	# <CJK>
+0x6422	0x6D27	# <CJK>
+0x6423	0x6D0C	# <CJK>
+0x6424	0x6D79	# <CJK>
+0x6425	0x6E5E	# <CJK>
+0x6426	0x6D07	# <CJK>
+0x6427	0x6D04	# <CJK>
+0x6428	0x6D19	# <CJK>
+0x6429	0x6D0E	# <CJK>
+0x642A	0x6D2B	# <CJK>
+0x642B	0x6FAE	# <CJK>
+0x642C	0x6D2E	# <CJK>
+0x642D	0x6D35	# <CJK>
+0x642E	0x6D1A	# <CJK>
+0x642F	0x700F	# <CJK>
+0x6430	0x6EF8	# <CJK>
+0x6431	0x6F6F	# <CJK>
+0x6432	0x6D33	# <CJK>
+0x6433	0x6D91	# <CJK>
+0x6434	0x6D6F	# <CJK>
+0x6435	0x6DF6	# <CJK>
+0x6436	0x6F7F	# <CJK>
+0x6437	0x6D5E	# <CJK>
+0x6438	0x6D93	# <CJK>
+0x6439	0x6D94	# <CJK>
+0x643A	0x6D5C	# <CJK>
+0x643B	0x6D60	# <CJK>
+0x643C	0x6D7C	# <CJK>
+0x643D	0x6D63	# <CJK>
+0x643E	0x6E1A	# <CJK>
+0x643F	0x6DC7	# <CJK>
+0x6440	0x6DC5	# <CJK>
+0x6441	0x6DDE	# <CJK>
+0x6442	0x7006	# <CJK>
+0x6443	0x6DBF	# <CJK>
+0x6444	0x6DE0	# <CJK>
+0x6445	0x6FA0	# <CJK>
+0x6446	0x6DE6	# <CJK>
+0x6447	0x6DDD	# <CJK>
+0x6448	0x6DD9	# <CJK>
+0x6449	0x700B	# <CJK>
+0x644A	0x6DAB	# <CJK>
+0x644B	0x6E0C	# <CJK>
+0x644C	0x6DAE	# <CJK>
+0x644D	0x6E2B	# <CJK>
+0x644E	0x6E6E	# <CJK>
+0x644F	0x6E4E	# <CJK>
+0x6450	0x6E6B	# <CJK>
+0x6451	0x6EB2	# <CJK>
+0x6452	0x6E5F	# <CJK>
+0x6453	0x6E86	# <CJK>
+0x6454	0x6E53	# <CJK>
+0x6455	0x6E54	# <CJK>
+0x6456	0x6E32	# <CJK>
+0x6457	0x6E25	# <CJK>
+0x6458	0x6E44	# <CJK>
+0x6459	0x7067	# <CJK>
+0x645A	0x6EB1	# <CJK>
+0x645B	0x6E98	# <CJK>
+0x645C	0x7044	# <CJK>
+0x645D	0x6F2D	# <CJK>
+0x645E	0x7005	# <CJK>
+0x645F	0x6EA5	# <CJK>
+0x6460	0x6EA7	# <CJK>
+0x6461	0x6EBD	# <CJK>
+0x6462	0x6EBB	# <CJK>
+0x6463	0x6EB7	# <CJK>
+0x6464	0x6F77	# <CJK>
+0x6465	0x6EB4	# <CJK>
+0x6466	0x6ECF	# <CJK>
+0x6467	0x6E8F	# <CJK>
+0x6468	0x6EC2	# <CJK>
+0x6469	0x6E9F	# <CJK>
+0x646A	0x6F62	# <CJK>
+0x646B	0x7020	# <CJK>
+0x646C	0x701F	# <CJK>
+0x646D	0x6F24	# <CJK>
+0x646E	0x6F15	# <CJK>
+0x646F	0x6EF9	# <CJK>
+0x6470	0x6F2F	# <CJK>
+0x6471	0x6F36	# <CJK>
+0x6472	0x7032	# <CJK>
+0x6473	0x6F74	# <CJK>
+0x6474	0x6F2A	# <CJK>
+0x6475	0x6F09	# <CJK>
+0x6476	0x6F29	# <CJK>
+0x6477	0x6F89	# <CJK>
+0x6478	0x6F8D	# <CJK>
+0x6479	0x6F8C	# <CJK>
+0x647A	0x6F78	# <CJK>
+0x647B	0x6F72	# <CJK>
+0x647C	0x6F7C	# <CJK>
+0x647D	0x6F7A	# <CJK>
+0x647E	0x7028	# <CJK>
+0x6521	0x6FC9	# <CJK>
+0x6522	0x6FA7	# <CJK>
+0x6523	0x6FB9	# <CJK>
+0x6524	0x6FB6	# <CJK>
+0x6525	0x6FC2	# <CJK>
+0x6526	0x6FE1	# <CJK>
+0x6527	0x6FEE	# <CJK>
+0x6528	0x6FDE	# <CJK>
+0x6529	0x6FE0	# <CJK>
+0x652A	0x6FEF	# <CJK>
+0x652B	0x701A	# <CJK>
+0x652C	0x7023	# <CJK>
+0x652D	0x701B	# <CJK>
+0x652E	0x7039	# <CJK>
+0x652F	0x7035	# <CJK>
+0x6530	0x705D	# <CJK>
+0x6531	0x705E	# <CJK>
+0x6532	0x5B80	# <CJK>
+0x6533	0x5B84	# <CJK>
+0x6534	0x5B95	# <CJK>
+0x6535	0x5B93	# <CJK>
+0x6536	0x5BA5	# <CJK>
+0x6537	0x5BB8	# <CJK>
+0x6538	0x752F	# <CJK>
+0x6539	0x9A2B	# <CJK>
+0x653A	0x6434	# <CJK>
+0x653B	0x5BE4	# <CJK>
+0x653C	0x5BEE	# <CJK>
+0x653D	0x8930	# <CJK>
+0x653E	0x5BF0	# <CJK>
+0x653F	0x8E47	# <CJK>
+0x6540	0x8B07	# <CJK>
+0x6541	0x8FB6	# <CJK>
+0x6542	0x8FD3	# <CJK>
+0x6543	0x8FD5	# <CJK>
+0x6544	0x8FE5	# <CJK>
+0x6545	0x8FEE	# <CJK>
+0x6546	0x8FE4	# <CJK>
+0x6547	0x9087	# <CJK>
+0x6548	0x8FE6	# <CJK>
+0x6549	0x9015	# <CJK>
+0x654A	0x8FE8	# <CJK>
+0x654B	0x9005	# <CJK>
+0x654C	0x9004	# <CJK>
+0x654D	0x900B	# <CJK>
+0x654E	0x9090	# <CJK>
+0x654F	0x9011	# <CJK>
+0x6550	0x900D	# <CJK>
+0x6551	0x9016	# <CJK>
+0x6552	0x9021	# <CJK>
+0x6553	0x9035	# <CJK>
+0x6554	0x9036	# <CJK>
+0x6555	0x902D	# <CJK>
+0x6556	0x902F	# <CJK>
+0x6557	0x9044	# <CJK>
+0x6558	0x9051	# <CJK>
+0x6559	0x9052	# <CJK>
+0x655A	0x9050	# <CJK>
+0x655B	0x9068	# <CJK>
+0x655C	0x9058	# <CJK>
+0x655D	0x9062	# <CJK>
+0x655E	0x905B	# <CJK>
+0x655F	0x66B9	# <CJK>
+0x6560	0x9074	# <CJK>
+0x6561	0x907D	# <CJK>
+0x6562	0x9082	# <CJK>
+0x6563	0x9088	# <CJK>
+0x6564	0x9083	# <CJK>
+0x6565	0x908B	# <CJK>
+0x6566	0x5F50	# <CJK>
+0x6567	0x5F57	# <CJK>
+0x6568	0x5F56	# <CJK>
+0x6569	0x5F58	# <CJK>
+0x656A	0x5C3B	# <CJK>
+0x656B	0x54AB	# <CJK>
+0x656C	0x5C50	# <CJK>
+0x656D	0x5C59	# <CJK>
+0x656E	0x5B71	# <CJK>
+0x656F	0x5C63	# <CJK>
+0x6570	0x5C68	# <CJK>
+0x6571	0x7FBC	# <CJK>
+0x6572	0x5F33	# <CJK>
+0x6573	0x5F29	# <CJK>
+0x6574	0x5F2D	# <CJK>
+0x6575	0x8274	# <CJK>
+0x6576	0x5F3C	# <CJK>
+0x6577	0x9B3B	# <CJK>
+0x6578	0x5C6E	# <CJK>
+0x6579	0x5981	# <CJK>
+0x657A	0x5983	# <CJK>
+0x657B	0x598D	# <CJK>
+0x657C	0x5AF5	# <CJK>
+0x657D	0x5AD7	# <CJK>
+0x657E	0x59A3	# <CJK>
+0x6621	0x5997	# <CJK>
+0x6622	0x59CA	# <CJK>
+0x6623	0x5B00	# <CJK>
+0x6624	0x599E	# <CJK>
+0x6625	0x59A4	# <CJK>
+0x6626	0x59D2	# <CJK>
+0x6627	0x59B2	# <CJK>
+0x6628	0x59AF	# <CJK>
+0x6629	0x59D7	# <CJK>
+0x662A	0x59BE	# <CJK>
+0x662B	0x5A6D	# <CJK>
+0x662C	0x5B08	# <CJK>
+0x662D	0x59DD	# <CJK>
+0x662E	0x5B4C	# <CJK>
+0x662F	0x59E3	# <CJK>
+0x6630	0x59D8	# <CJK>
+0x6631	0x59F9	# <CJK>
+0x6632	0x5A0C	# <CJK>
+0x6633	0x5A09	# <CJK>
+0x6634	0x5AA7	# <CJK>
+0x6635	0x5AFB	# <CJK>
+0x6636	0x5A11	# <CJK>
+0x6637	0x5A23	# <CJK>
+0x6638	0x5A13	# <CJK>
+0x6639	0x5A40	# <CJK>
+0x663A	0x5A67	# <CJK>
+0x663B	0x5A4A	# <CJK>
+0x663C	0x5A55	# <CJK>
+0x663D	0x5A3C	# <CJK>
+0x663E	0x5A62	# <CJK>
+0x663F	0x5B0B	# <CJK>
+0x6640	0x80EC	# <CJK>
+0x6641	0x5AAA	# <CJK>
+0x6642	0x5A9B	# <CJK>
+0x6643	0x5A77	# <CJK>
+0x6644	0x5A7A	# <CJK>
+0x6645	0x5ABE	# <CJK>
+0x6646	0x5AEB	# <CJK>
+0x6647	0x5AB2	# <CJK>
+0x6648	0x5B21	# <CJK>
+0x6649	0x5B2A	# <CJK>
+0x664A	0x5AB8	# <CJK>
+0x664B	0x5AE0	# <CJK>
+0x664C	0x5AE3	# <CJK>
+0x664D	0x5B19	# <CJK>
+0x664E	0x5AD6	# <CJK>
+0x664F	0x5AE6	# <CJK>
+0x6650	0x5AD8	# <CJK>
+0x6651	0x5ADC	# <CJK>
+0x6652	0x5B09	# <CJK>
+0x6653	0x5B17	# <CJK>
+0x6654	0x5B16	# <CJK>
+0x6655	0x5B32	# <CJK>
+0x6656	0x5B37	# <CJK>
+0x6657	0x5B40	# <CJK>
+0x6658	0x5C15	# <CJK>
+0x6659	0x5C1C	# <CJK>
+0x665A	0x5B5A	# <CJK>
+0x665B	0x5B65	# <CJK>
+0x665C	0x5B73	# <CJK>
+0x665D	0x5B51	# <CJK>
+0x665E	0x5B53	# <CJK>
+0x665F	0x5B62	# <CJK>
+0x6660	0x99D4	# <CJK>
+0x6661	0x99DF	# <CJK>
+0x6662	0x99D9	# <CJK>
+0x6663	0x9A36	# <CJK>
+0x6664	0x9A5B	# <CJK>
+0x6665	0x99D1	# <CJK>
+0x6666	0x99D8	# <CJK>
+0x6667	0x9A4D	# <CJK>
+0x6668	0x9A4A	# <CJK>
+0x6669	0x99E2	# <CJK>
+0x666A	0x9A6A	# <CJK>
+0x666B	0x9A0F	# <CJK>
+0x666C	0x9A0D	# <CJK>
+0x666D	0x9A05	# <CJK>
+0x666E	0x9A42	# <CJK>
+0x666F	0x9A2D	# <CJK>
+0x6670	0x9A16	# <CJK>
+0x6671	0x9A41	# <CJK>
+0x6672	0x9A2E	# <CJK>
+0x6673	0x9A38	# <CJK>
+0x6674	0x9A43	# <CJK>
+0x6675	0x9A44	# <CJK>
+0x6676	0x9A4F	# <CJK>
+0x6677	0x9A65	# <CJK>
+0x6678	0x9A64	# <CJK>
+0x6679	0x7CF9	# <CJK>
+0x667A	0x7D06	# <CJK>
+0x667B	0x7D02	# <CJK>
+0x667C	0x7D07	# <CJK>
+0x667D	0x7D08	# <CJK>
+0x667E	0x7E8A	# <CJK>
+0x6721	0x7D1C	# <CJK>
+0x6722	0x7D15	# <CJK>
+0x6723	0x7D13	# <CJK>
+0x6724	0x7D3A	# <CJK>
+0x6725	0x7D32	# <CJK>
+0x6726	0x7D31	# <CJK>
+0x6727	0x7E10	# <CJK>
+0x6728	0x7D3C	# <CJK>
+0x6729	0x7D40	# <CJK>
+0x672A	0x7D3F	# <CJK>
+0x672B	0x7D5D	# <CJK>
+0x672C	0x7D4E	# <CJK>
+0x672D	0x7D73	# <CJK>
+0x672E	0x7D86	# <CJK>
+0x672F	0x7D83	# <CJK>
+0x6730	0x7D88	# <CJK>
+0x6731	0x7DBE	# <CJK>
+0x6732	0x7DBA	# <CJK>
+0x6733	0x7DCB	# <CJK>
+0x6734	0x7DD4	# <CJK>
+0x6735	0x7DC4	# <CJK>
+0x6736	0x7D9E	# <CJK>
+0x6737	0x7DAC	# <CJK>
+0x6738	0x7DB9	# <CJK>
+0x6739	0x7DA3	# <CJK>
+0x673A	0x7DB0	# <CJK>
+0x673B	0x7DC7	# <CJK>
+0x673C	0x7DD9	# <CJK>
+0x673D	0x7DD7	# <CJK>
+0x673E	0x7DF9	# <CJK>
+0x673F	0x7DF2	# <CJK>
+0x6740	0x7E62	# <CJK>
+0x6741	0x7DE6	# <CJK>
+0x6742	0x7DF6	# <CJK>
+0x6743	0x7DF1	# <CJK>
+0x6744	0x7E0B	# <CJK>
+0x6745	0x7DE1	# <CJK>
+0x6746	0x7E09	# <CJK>
+0x6747	0x7E1D	# <CJK>
+0x6748	0x7E1F	# <CJK>
+0x6749	0x7E1E	# <CJK>
+0x674A	0x7E2D	# <CJK>
+0x674B	0x7E0A	# <CJK>
+0x674C	0x7E11	# <CJK>
+0x674D	0x7E7D	# <CJK>
+0x674E	0x7E39	# <CJK>
+0x674F	0x7E35	# <CJK>
+0x6750	0x7E32	# <CJK>
+0x6751	0x7E46	# <CJK>
+0x6752	0x7E45	# <CJK>
+0x6753	0x7E88	# <CJK>
+0x6754	0x7E5A	# <CJK>
+0x6755	0x7E52	# <CJK>
+0x6756	0x7E6E	# <CJK>
+0x6757	0x7E7E	# <CJK>
+0x6758	0x7E70	# <CJK>
+0x6759	0x7E6F	# <CJK>
+0x675A	0x7E98	# <CJK>
+0x675B	0x5E7A	# <CJK>
+0x675C	0x757F	# <CJK>
+0x675D	0x5DDB	# <CJK>
+0x675E	0x753E	# <CJK>
+0x675F	0x9095	# <CJK>
+0x6760	0x738E	# <CJK>
+0x6761	0x74A3	# <CJK>
+0x6762	0x744B	# <CJK>
+0x6763	0x73A2	# <CJK>
+0x6764	0x739F	# <CJK>
+0x6765	0x73CF	# <CJK>
+0x6766	0x73C2	# <CJK>
+0x6767	0x74CF	# <CJK>
+0x6768	0x73B7	# <CJK>
+0x6769	0x73B3	# <CJK>
+0x676A	0x73C0	# <CJK>
+0x676B	0x73C9	# <CJK>
+0x676C	0x73C8	# <CJK>
+0x676D	0x73E5	# <CJK>
+0x676E	0x73D9	# <CJK>
+0x676F	0x980A	# <CJK>
+0x6770	0x740A	# <CJK>
+0x6771	0x73E9	# <CJK>
+0x6772	0x73E7	# <CJK>
+0x6773	0x73DE	# <CJK>
+0x6774	0x74BD	# <CJK>
+0x6775	0x743F	# <CJK>
+0x6776	0x7489	# <CJK>
+0x6777	0x742A	# <CJK>
+0x6778	0x745B	# <CJK>
+0x6779	0x7426	# <CJK>
+0x677A	0x7425	# <CJK>
+0x677B	0x7428	# <CJK>
+0x677C	0x7430	# <CJK>
+0x677D	0x742E	# <CJK>
+0x677E	0x742C	# <CJK>
+0x6821	0x741B	# <CJK>
+0x6822	0x741A	# <CJK>
+0x6823	0x7441	# <CJK>
+0x6824	0x745C	# <CJK>
+0x6825	0x7457	# <CJK>
+0x6826	0x7455	# <CJK>
+0x6827	0x7459	# <CJK>
+0x6828	0x74A6	# <CJK>
+0x6829	0x746D	# <CJK>
+0x682A	0x747E	# <CJK>
+0x682B	0x749C	# <CJK>
+0x682C	0x74D4	# <CJK>
+0x682D	0x7480	# <CJK>
+0x682E	0x7481	# <CJK>
+0x682F	0x7487	# <CJK>
+0x6830	0x748B	# <CJK>
+0x6831	0x749E	# <CJK>
+0x6832	0x74A8	# <CJK>
+0x6833	0x74A9	# <CJK>
+0x6834	0x7490	# <CJK>
+0x6835	0x74A7	# <CJK>
+0x6836	0x74DA	# <CJK>
+0x6837	0x74BA	# <CJK>
+0x6838	0x97D9	# <CJK>
+0x6839	0x97DE	# <CJK>
+0x683A	0x97DC	# <CJK>
+0x683B	0x674C	# <CJK>
+0x683C	0x6753	# <CJK>
+0x683D	0x675E	# <CJK>
+0x683E	0x6748	# <CJK>
+0x683F	0x69AA	# <CJK>
+0x6840	0x6AEA	# <CJK>
+0x6841	0x6787	# <CJK>
+0x6842	0x676A	# <CJK>
+0x6843	0x6773	# <CJK>
+0x6844	0x6798	# <CJK>
+0x6845	0x6898	# <CJK>
+0x6846	0x6775	# <CJK>
+0x6847	0x68D6	# <CJK>
+0x6848	0x6A05	# <CJK>
+0x6849	0x689F	# <CJK>
+0x684A	0x678B	# <CJK>
+0x684B	0x6777	# <CJK>
+0x684C	0x677C	# <CJK>
+0x684D	0x67F0	# <CJK>
+0x684E	0x6ADB	# <CJK>
+0x684F	0x67D8	# <CJK>
+0x6850	0x6AF3	# <CJK>
+0x6851	0x67E9	# <CJK>
+0x6852	0x67B0	# <CJK>
+0x6853	0x6AE8	# <CJK>
+0x6854	0x67D9	# <CJK>
+0x6855	0x67B5	# <CJK>
+0x6856	0x67DA	# <CJK>
+0x6857	0x67B3	# <CJK>
+0x6858	0x67DD	# <CJK>
+0x6859	0x6800	# <CJK>
+0x685A	0x67C3	# <CJK>
+0x685B	0x67B8	# <CJK>
+0x685C	0x67E2	# <CJK>
+0x685D	0x6ADF	# <CJK>
+0x685E	0x67C1	# <CJK>
+0x685F	0x6A89	# <CJK>
+0x6860	0x6832	# <CJK>
+0x6861	0x6833	# <CJK>
+0x6862	0x690F	# <CJK>
+0x6863	0x6A48	# <CJK>
+0x6864	0x684E	# <CJK>
+0x6865	0x6968	# <CJK>
+0x6866	0x6844	# <CJK>
+0x6867	0x69BF	# <CJK>
+0x6868	0x6883	# <CJK>
+0x6869	0x681D	# <CJK>
+0x686A	0x6855	# <CJK>
+0x686B	0x6A3A	# <CJK>
+0x686C	0x6841	# <CJK>
+0x686D	0x6A9C	# <CJK>
+0x686E	0x6840	# <CJK>
+0x686F	0x6B12	# <CJK>
+0x6870	0x684A	# <CJK>
+0x6871	0x6849	# <CJK>
+0x6872	0x6829	# <CJK>
+0x6873	0x68B5	# <CJK>
+0x6874	0x688F	# <CJK>
+0x6875	0x6874	# <CJK>
+0x6876	0x6877	# <CJK>
+0x6877	0x6893	# <CJK>
+0x6878	0x686B	# <CJK>
+0x6879	0x6B1E	# <CJK>
+0x687A	0x696E	# <CJK>
+0x687B	0x68FC	# <CJK>
+0x687C	0x6ADD	# <CJK>
+0x687D	0x69E7	# <CJK>
+0x687E	0x68F9	# <CJK>
+0x6921	0x6B0F	# <CJK>
+0x6922	0x68F0	# <CJK>
+0x6923	0x690B	# <CJK>
+0x6924	0x6901	# <CJK>
+0x6925	0x6957	# <CJK>
+0x6926	0x68E3	# <CJK>
+0x6927	0x6910	# <CJK>
+0x6928	0x6971	# <CJK>
+0x6929	0x6939	# <CJK>
+0x692A	0x6960	# <CJK>
+0x692B	0x6942	# <CJK>
+0x692C	0x695D	# <CJK>
+0x692D	0x6B16	# <CJK>
+0x692E	0x696B	# <CJK>
+0x692F	0x6980	# <CJK>
+0x6930	0x6998	# <CJK>
+0x6931	0x6978	# <CJK>
+0x6932	0x6934	# <CJK>
+0x6933	0x69CC	# <CJK>
+0x6934	0x6AEC	# <CJK>
+0x6935	0x6ADA	# <CJK>
+0x6936	0x69CE	# <CJK>
+0x6937	0x6AF8	# <CJK>
+0x6938	0x6966	# <CJK>
+0x6939	0x6963	# <CJK>
+0x693A	0x6979	# <CJK>
+0x693B	0x699B	# <CJK>
+0x693C	0x69A7	# <CJK>
+0x693D	0x69BB	# <CJK>
+0x693E	0x69AB	# <CJK>
+0x693F	0x69AD	# <CJK>
+0x6940	0x69D4	# <CJK>
+0x6941	0x69B1	# <CJK>
+0x6942	0x69C1	# <CJK>
+0x6943	0x69CA	# <CJK>
+0x6944	0x6AB3	# <CJK>
+0x6945	0x6995	# <CJK>
+0x6946	0x6AE7	# <CJK>
+0x6947	0x698D	# <CJK>
+0x6948	0x69FF	# <CJK>
+0x6949	0x6AA3	# <CJK>
+0x694A	0x69ED	# <CJK>
+0x694B	0x6A17	# <CJK>
+0x694C	0x6A18	# <CJK>
+0x694D	0x6A65	# <CJK>
+0x694E	0x69F2	# <CJK>
+0x694F	0x6A44	# <CJK>
+0x6950	0x6A3E	# <CJK>
+0x6951	0x6AA0	# <CJK>
+0x6952	0x6A50	# <CJK>
+0x6953	0x6A5B	# <CJK>
+0x6954	0x6A35	# <CJK>
+0x6955	0x6A8E	# <CJK>
+0x6956	0x6AD3	# <CJK>
+0x6957	0x6A3D	# <CJK>
+0x6958	0x6A28	# <CJK>
+0x6959	0x6A58	# <CJK>
+0x695A	0x6ADE	# <CJK>
+0x695B	0x6A91	# <CJK>
+0x695C	0x6A90	# <CJK>
+0x695D	0x6AA9	# <CJK>
+0x695E	0x6A97	# <CJK>
+0x695F	0x6AAB	# <CJK>
+0x6960	0x7337	# <CJK>
+0x6961	0x7352	# <CJK>
+0x6962	0x6B81	# <CJK>
+0x6963	0x6B82	# <CJK>
+0x6964	0x6BA4	# <CJK>
+0x6965	0x6B84	# <CJK>
+0x6966	0x6B9E	# <CJK>
+0x6967	0x6BAE	# <CJK>
+0x6968	0x6B8D	# <CJK>
+0x6969	0x6BAB	# <CJK>
+0x696A	0x6B9B	# <CJK>
+0x696B	0x6BAF	# <CJK>
+0x696C	0x6BAA	# <CJK>
+0x696D	0x8ED4	# <CJK>
+0x696E	0x8EDB	# <CJK>
+0x696F	0x8EF2	# <CJK>
+0x6970	0x8EFB	# <CJK>
+0x6971	0x8F64	# <CJK>
+0x6972	0x8EF9	# <CJK>
+0x6973	0x8EFC	# <CJK>
+0x6974	0x8EEB	# <CJK>
+0x6975	0x8EE4	# <CJK>
+0x6976	0x8F62	# <CJK>
+0x6977	0x8EFA	# <CJK>
+0x6978	0x8EFE	# <CJK>
+0x6979	0x8F0A	# <CJK>
+0x697A	0x8F07	# <CJK>
+0x697B	0x8F05	# <CJK>
+0x697C	0x8F12	# <CJK>
+0x697D	0x8F26	# <CJK>
+0x697E	0x8F1E	# <CJK>
+0x6A21	0x8F1F	# <CJK>
+0x6A22	0x8F1C	# <CJK>
+0x6A23	0x8F33	# <CJK>
+0x6A24	0x8F46	# <CJK>
+0x6A25	0x8F54	# <CJK>
+0x6A26	0x8ECE	# <CJK>
+0x6A27	0x6214	# <CJK>
+0x6A28	0x6227	# <CJK>
+0x6A29	0x621B	# <CJK>
+0x6A2A	0x621F	# <CJK>
+0x6A2B	0x6222	# <CJK>
+0x6A2C	0x6221	# <CJK>
+0x6A2D	0x6225	# <CJK>
+0x6A2E	0x6224	# <CJK>
+0x6A2F	0x6229	# <CJK>
+0x6A30	0x81E7	# <CJK>
+0x6A31	0x750C	# <CJK>
+0x6A32	0x74F4	# <CJK>
+0x6A33	0x74FF	# <CJK>
+0x6A34	0x750F	# <CJK>
+0x6A35	0x7511	# <CJK>
+0x6A36	0x7513	# <CJK>
+0x6A37	0x6534	# <CJK>
+0x6A38	0x65EE	# <CJK>
+0x6A39	0x65EF	# <CJK>
+0x6A3A	0x65F0	# <CJK>
+0x6A3B	0x660A	# <CJK>
+0x6A3C	0x66C7	# <CJK>
+0x6A3D	0x6772	# <CJK>
+0x6A3E	0x6603	# <CJK>
+0x6A3F	0x6615	# <CJK>
+0x6A40	0x6600	# <CJK>
+0x6A41	0x7085	# <CJK>
+0x6A42	0x66F7	# <CJK>
+0x6A43	0x661D	# <CJK>
+0x6A44	0x6634	# <CJK>
+0x6A45	0x6631	# <CJK>
+0x6A46	0x6636	# <CJK>
+0x6A47	0x6635	# <CJK>
+0x6A48	0x8006	# <CJK>
+0x6A49	0x665F	# <CJK>
+0x6A4A	0x66C4	# <CJK>
+0x6A4B	0x6641	# <CJK>
+0x6A4C	0x664F	# <CJK>
+0x6A4D	0x6689	# <CJK>
+0x6A4E	0x6661	# <CJK>
+0x6A4F	0x6657	# <CJK>
+0x6A50	0x6677	# <CJK>
+0x6A51	0x6684	# <CJK>
+0x6A52	0x668C	# <CJK>
+0x6A53	0x66D6	# <CJK>
+0x6A54	0x669D	# <CJK>
+0x6A55	0x66BE	# <CJK>
+0x6A56	0x66DB	# <CJK>
+0x6A57	0x66DC	# <CJK>
+0x6A58	0x66E6	# <CJK>
+0x6A59	0x66E9	# <CJK>
+0x6A5A	0x8CC1	# <CJK>
+0x6A5B	0x8CB0	# <CJK>
+0x6A5C	0x8CBA	# <CJK>
+0x6A5D	0x8CBD	# <CJK>
+0x6A5E	0x8D04	# <CJK>
+0x6A5F	0x8CB2	# <CJK>
+0x6A60	0x8CC5	# <CJK>
+0x6A61	0x8D10	# <CJK>
+0x6A62	0x8CD1	# <CJK>
+0x6A63	0x8CDA	# <CJK>
+0x6A64	0x8CD5	# <CJK>
+0x6A65	0x8CEB	# <CJK>
+0x6A66	0x8CE7	# <CJK>
+0x6A67	0x8CFB	# <CJK>
+0x6A68	0x8998	# <CJK>
+0x6A69	0x89AC	# <CJK>
+0x6A6A	0x89A1	# <CJK>
+0x6A6B	0x89BF	# <CJK>
+0x6A6C	0x89A6	# <CJK>
+0x6A6D	0x89AF	# <CJK>
+0x6A6E	0x89B2	# <CJK>
+0x6A6F	0x89B7	# <CJK>
+0x6A70	0x726E	# <CJK>
+0x6A71	0x729F	# <CJK>
+0x6A72	0x725D	# <CJK>
+0x6A73	0x7266	# <CJK>
+0x6A74	0x726F	# <CJK>
+0x6A75	0x727E	# <CJK>
+0x6A76	0x727F	# <CJK>
+0x6A77	0x7284	# <CJK>
+0x6A78	0x728B	# <CJK>
+0x6A79	0x728D	# <CJK>
+0x6A7A	0x728F	# <CJK>
+0x6A7B	0x7292	# <CJK>
+0x6A7C	0x6308	# <CJK>
+0x6A7D	0x6332	# <CJK>
+0x6A7E	0x63B0	# <CJK>
+0x6B21	0x643F	# <CJK>
+0x6B22	0x64D8	# <CJK>
+0x6B23	0x8004	# <CJK>
+0x6B24	0x6BEA	# <CJK>
+0x6B25	0x6BF3	# <CJK>
+0x6B26	0x6BFD	# <CJK>
+0x6B27	0x6BFF	# <CJK>
+0x6B28	0x6BF9	# <CJK>
+0x6B29	0x6C05	# <CJK>
+0x6B2A	0x6C0C	# <CJK>
+0x6B2B	0x6C06	# <CJK>
+0x6B2C	0x6C0D	# <CJK>
+0x6B2D	0x6C15	# <CJK>
+0x6B2E	0x6C18	# <CJK>
+0x6B2F	0x6C19	# <CJK>
+0x6B30	0x6C1A	# <CJK>
+0x6B31	0x6C21	# <CJK>
+0x6B32	0x6C2C	# <CJK>
+0x6B33	0x6C24	# <CJK>
+0x6B34	0x6C2A	# <CJK>
+0x6B35	0x6C32	# <CJK>
+0x6B36	0x6535	# <CJK>
+0x6B37	0x6555	# <CJK>
+0x6B38	0x656B	# <CJK>
+0x6B39	0x7258	# <CJK>
+0x6B3A	0x7252	# <CJK>
+0x6B3B	0x7256	# <CJK>
+0x6B3C	0x7230	# <CJK>
+0x6B3D	0x8662	# <CJK>
+0x6B3E	0x5216	# <CJK>
+0x6B3F	0x809F	# <CJK>
+0x6B40	0x809C	# <CJK>
+0x6B41	0x8093	# <CJK>
+0x6B42	0x80BC	# <CJK>
+0x6B43	0x670A	# <CJK>
+0x6B44	0x80BD	# <CJK>
+0x6B45	0x80B1	# <CJK>
+0x6B46	0x80AB	# <CJK>
+0x6B47	0x80AD	# <CJK>
+0x6B48	0x80B4	# <CJK>
+0x6B49	0x80B7	# <CJK>
+0x6B4A	0x6727	# <CJK>
+0x6B4B	0x8156	# <CJK>
+0x6B4C	0x80E9	# <CJK>
+0x6B4D	0x81DA	# <CJK>
+0x6B4E	0x80DB	# <CJK>
+0x6B4F	0x80C2	# <CJK>
+0x6B50	0x80C4	# <CJK>
+0x6B51	0x80D9	# <CJK>
+0x6B52	0x80CD	# <CJK>
+0x6B53	0x80D7	# <CJK>
+0x6B54	0x6710	# <CJK>
+0x6B55	0x80DD	# <CJK>
+0x6B56	0x811B	# <CJK>
+0x6B57	0x80F1	# <CJK>
+0x6B58	0x80F4	# <CJK>
+0x6B59	0x80ED	# <CJK>
+0x6B5A	0x81BE	# <CJK>
+0x6B5B	0x810E	# <CJK>
+0x6B5C	0x80F2	# <CJK>
+0x6B5D	0x80FC	# <CJK>
+0x6B5E	0x6715	# <CJK>
+0x6B5F	0x8112	# <CJK>
+0x6B60	0x8C5A	# <CJK>
+0x6B61	0x8161	# <CJK>
+0x6B62	0x811E	# <CJK>
+0x6B63	0x812C	# <CJK>
+0x6B64	0x8118	# <CJK>
+0x6B65	0x8132	# <CJK>
+0x6B66	0x8148	# <CJK>
+0x6B67	0x814C	# <CJK>
+0x6B68	0x8153	# <CJK>
+0x6B69	0x8174	# <CJK>
+0x6B6A	0x8159	# <CJK>
+0x6B6B	0x815A	# <CJK>
+0x6B6C	0x8171	# <CJK>
+0x6B6D	0x8160	# <CJK>
+0x6B6E	0x8169	# <CJK>
+0x6B6F	0x817C	# <CJK>
+0x6B70	0x817D	# <CJK>
+0x6B71	0x816D	# <CJK>
+0x6B72	0x8167	# <CJK>
+0x6B73	0x584D	# <CJK>
+0x6B74	0x5AB5	# <CJK>
+0x6B75	0x8188	# <CJK>
+0x6B76	0x8182	# <CJK>
+0x6B77	0x81CF	# <CJK>
+0x6B78	0x6ED5	# <CJK>
+0x6B79	0x81A3	# <CJK>
+0x6B7A	0x81AA	# <CJK>
+0x6B7B	0x81CC	# <CJK>
+0x6B7C	0x6726	# <CJK>
+0x6B7D	0x81CA	# <CJK>
+0x6B7E	0x81BB	# <CJK>
+0x6C21	0x81C1	# <CJK>
+0x6C22	0x81A6	# <CJK>
+0x6C23	0x6B5F	# <CJK>
+0x6C24	0x6B37	# <CJK>
+0x6C25	0x6B39	# <CJK>
+0x6C26	0x6B43	# <CJK>
+0x6C27	0x6B46	# <CJK>
+0x6C28	0x6B59	# <CJK>
+0x6C29	0x98AE	# <CJK>
+0x6C2A	0x98AF	# <CJK>
+0x6C2B	0x98B6	# <CJK>
+0x6C2C	0x98BC	# <CJK>
+0x6C2D	0x98C6	# <CJK>
+0x6C2E	0x98C8	# <CJK>
+0x6C2F	0x6BB3	# <CJK>
+0x6C30	0x5F40	# <CJK>
+0x6C31	0x8F42	# <CJK>
+0x6C32	0x89F3	# <CJK>
+0x6C33	0x6590	# <CJK>
+0x6C34	0x9F4F	# <CJK>
+0x6C35	0x6595	# <CJK>
+0x6C36	0x65BC	# <CJK>
+0x6C37	0x65C6	# <CJK>
+0x6C38	0x65C4	# <CJK>
+0x6C39	0x65C3	# <CJK>
+0x6C3A	0x65CC	# <CJK>
+0x6C3B	0x65CE	# <CJK>
+0x6C3C	0x65D2	# <CJK>
+0x6C3D	0x65D6	# <CJK>
+0x6C3E	0x716C	# <CJK>
+0x6C3F	0x7152	# <CJK>
+0x6C40	0x7096	# <CJK>
+0x6C41	0x7197	# <CJK>
+0x6C42	0x70BB	# <CJK>
+0x6C43	0x70C0	# <CJK>
+0x6C44	0x70B7	# <CJK>
+0x6C45	0x70AB	# <CJK>
+0x6C46	0x70B1	# <CJK>
+0x6C47	0x71C1	# <CJK>
+0x6C48	0x70CA	# <CJK>
+0x6C49	0x7110	# <CJK>
+0x6C4A	0x7113	# <CJK>
+0x6C4B	0x71DC	# <CJK>
+0x6C4C	0x712F	# <CJK>
+0x6C4D	0x7131	# <CJK>
+0x6C4E	0x7173	# <CJK>
+0x6C4F	0x715C	# <CJK>
+0x6C50	0x7168	# <CJK>
+0x6C51	0x7145	# <CJK>
+0x6C52	0x7172	# <CJK>
+0x6C53	0x714A	# <CJK>
+0x6C54	0x7178	# <CJK>
+0x6C55	0x717A	# <CJK>
+0x6C56	0x7198	# <CJK>
+0x6C57	0x71B3	# <CJK>
+0x6C58	0x71B5	# <CJK>
+0x6C59	0x71A8	# <CJK>
+0x6C5A	0x71A0	# <CJK>
+0x6C5B	0x71E0	# <CJK>
+0x6C5C	0x71D4	# <CJK>
+0x6C5D	0x71E7	# <CJK>
+0x6C5E	0x71F9	# <CJK>
+0x6C5F	0x721D	# <CJK>
+0x6C60	0x7228	# <CJK>
+0x6C61	0x706C	# <CJK>
+0x6C62	0x71FE	# <CJK>
+0x6C63	0x7166	# <CJK>
+0x6C64	0x71B9	# <CJK>
+0x6C65	0x623E	# <CJK>
+0x6C66	0x623D	# <CJK>
+0x6C67	0x6243	# <CJK>
+0x6C68	0x6248	# <CJK>
+0x6C69	0x6249	# <CJK>
+0x6C6A	0x793B	# <CJK>
+0x6C6B	0x7940	# <CJK>
+0x6C6C	0x7946	# <CJK>
+0x6C6D	0x7949	# <CJK>
+0x6C6E	0x795B	# <CJK>
+0x6C6F	0x795C	# <CJK>
+0x6C70	0x7953	# <CJK>
+0x6C71	0x795A	# <CJK>
+0x6C72	0x79B0	# <CJK>
+0x6C73	0x7957	# <CJK>
+0x6C74	0x7960	# <CJK>
+0x6C75	0x798E	# <CJK>
+0x6C76	0x7967	# <CJK>
+0x6C77	0x797A	# <CJK>
+0x6C78	0x79AA	# <CJK>
+0x6C79	0x798A	# <CJK>
+0x6C7A	0x799A	# <CJK>
+0x6C7B	0x79A7	# <CJK>
+0x6C7C	0x79B3	# <CJK>
+0x6C7D	0x5FD1	# <CJK>
+0x6C7E	0x5FD0	# <CJK>
+0x6D21	0x61DF	# <CJK>
+0x6D22	0x605D	# <CJK>
+0x6D23	0x605A	# <CJK>
+0x6D24	0x6067	# <CJK>
+0x6D25	0x6041	# <CJK>
+0x6D26	0x6059	# <CJK>
+0x6D27	0x6063	# <CJK>
+0x6D28	0x6164	# <CJK>
+0x6D29	0x6106	# <CJK>
+0x6D2A	0x610D	# <CJK>
+0x6D2B	0x615D	# <CJK>
+0x6D2C	0x61A9	# <CJK>
+0x6D2D	0x619D	# <CJK>
+0x6D2E	0x61CB	# <CJK>
+0x6D2F	0x61E3	# <CJK>
+0x6D30	0x6207	# <CJK>
+0x6D31	0x8080	# <CJK>
+0x6D32	0x807F	# <CJK>
+0x6D33	0x6C93	# <CJK>
+0x6D34	0x6FA9	# <CJK>
+0x6D35	0x6DFC	# <CJK>
+0x6D36	0x78EF	# <CJK>
+0x6D37	0x77F8	# <CJK>
+0x6D38	0x78AD	# <CJK>
+0x6D39	0x7809	# <CJK>
+0x6D3A	0x7868	# <CJK>
+0x6D3B	0x7818	# <CJK>
+0x6D3C	0x7811	# <CJK>
+0x6D3D	0x65AB	# <CJK>
+0x6D3E	0x782D	# <CJK>
+0x6D3F	0x78B8	# <CJK>
+0x6D40	0x781D	# <CJK>
+0x6D41	0x7839	# <CJK>
+0x6D42	0x792A	# <CJK>
+0x6D43	0x7931	# <CJK>
+0x6D44	0x781F	# <CJK>
+0x6D45	0x783C	# <CJK>
+0x6D46	0x7825	# <CJK>
+0x6D47	0x782C	# <CJK>
+0x6D48	0x7823	# <CJK>
+0x6D49	0x7829	# <CJK>
+0x6D4A	0x784E	# <CJK>
+0x6D4B	0x786D	# <CJK>
+0x6D4C	0x7864	# <CJK>
+0x6D4D	0x78FD	# <CJK>
+0x6D4E	0x7826	# <CJK>
+0x6D4F	0x7850	# <CJK>
+0x6D50	0x7847	# <CJK>
+0x6D51	0x784C	# <CJK>
+0x6D52	0x786A	# <CJK>
+0x6D53	0x78E7	# <CJK>
+0x6D54	0x7893	# <CJK>
+0x6D55	0x789A	# <CJK>
+0x6D56	0x7887	# <CJK>
+0x6D57	0x78E3	# <CJK>
+0x6D58	0x78A1	# <CJK>
+0x6D59	0x78A3	# <CJK>
+0x6D5A	0x78B2	# <CJK>
+0x6D5B	0x78B9	# <CJK>
+0x6D5C	0x78A5	# <CJK>
+0x6D5D	0x78D4	# <CJK>
+0x6D5E	0x78D9	# <CJK>
+0x6D5F	0x78C9	# <CJK>
+0x6D60	0x78EC	# <CJK>
+0x6D61	0x78F2	# <CJK>
+0x6D62	0x7905	# <CJK>
+0x6D63	0x78F4	# <CJK>
+0x6D64	0x7913	# <CJK>
+0x6D65	0x7924	# <CJK>
+0x6D66	0x791E	# <CJK>
+0x6D67	0x7934	# <CJK>
+0x6D68	0x9F95	# <CJK>
+0x6D69	0x9EF9	# <CJK>
+0x6D6A	0x9EFB	# <CJK>
+0x6D6B	0x9EFC	# <CJK>
+0x6D6C	0x76F1	# <CJK>
+0x6D6D	0x7704	# <CJK>
+0x6D6E	0x7798	# <CJK>
+0x6D6F	0x76F9	# <CJK>
+0x6D70	0x7707	# <CJK>
+0x6D71	0x7708	# <CJK>
+0x6D72	0x771A	# <CJK>
+0x6D73	0x7722	# <CJK>
+0x6D74	0x7719	# <CJK>
+0x6D75	0x772D	# <CJK>
+0x6D76	0x7726	# <CJK>
+0x6D77	0x7735	# <CJK>
+0x6D78	0x7738	# <CJK>
+0x6D79	0x775E	# <CJK>
+0x6D7A	0x77BC	# <CJK>
+0x6D7B	0x7747	# <CJK>
+0x6D7C	0x7743	# <CJK>
+0x6D7D	0x775A	# <CJK>
+0x6D7E	0x7768	# <CJK>
+0x6E21	0x7762	# <CJK>
+0x6E22	0x7765	# <CJK>
+0x6E23	0x777F	# <CJK>
+0x6E24	0x778D	# <CJK>
+0x6E25	0x777D	# <CJK>
+0x6E26	0x7780	# <CJK>
+0x6E27	0x778C	# <CJK>
+0x6E28	0x7791	# <CJK>
+0x6E29	0x779F	# <CJK>
+0x6E2A	0x77A0	# <CJK>
+0x6E2B	0x77B0	# <CJK>
+0x6E2C	0x77B5	# <CJK>
+0x6E2D	0x77BD	# <CJK>
+0x6E2E	0x753A	# <CJK>
+0x6E2F	0x7540	# <CJK>
+0x6E30	0x754E	# <CJK>
+0x6E31	0x754B	# <CJK>
+0x6E32	0x7548	# <CJK>
+0x6E33	0x755B	# <CJK>
+0x6E34	0x7572	# <CJK>
+0x6E35	0x7579	# <CJK>
+0x6E36	0x7583	# <CJK>
+0x6E37	0x7F58	# <CJK>
+0x6E38	0x7F61	# <CJK>
+0x6E39	0x7F5F	# <CJK>
+0x6E3A	0x8A48	# <CJK>
+0x6E3B	0x7F68	# <CJK>
+0x6E3C	0x7F86	# <CJK>
+0x6E3D	0x7F71	# <CJK>
+0x6E3E	0x7F79	# <CJK>
+0x6E3F	0x7F88	# <CJK>
+0x6E40	0x7F7E	# <CJK>
+0x6E41	0x76CD	# <CJK>
+0x6E42	0x76E5	# <CJK>
+0x6E43	0x8832	# <CJK>
+0x6E44	0x91D2	# <CJK>
+0x6E45	0x91D3	# <CJK>
+0x6E46	0x91D4	# <CJK>
+0x6E47	0x91D9	# <CJK>
+0x6E48	0x91D7	# <CJK>
+0x6E49	0x91D5	# <CJK>
+0x6E4A	0x91F7	# <CJK>
+0x6E4B	0x91E7	# <CJK>
+0x6E4C	0x91E4	# <CJK>
+0x6E4D	0x9346	# <CJK>
+0x6E4E	0x91F5	# <CJK>
+0x6E4F	0x91F9	# <CJK>
+0x6E50	0x9208	# <CJK>
+0x6E51	0x9226	# <CJK>
+0x6E52	0x9245	# <CJK>
+0x6E53	0x9211	# <CJK>
+0x6E54	0x9210	# <CJK>
+0x6E55	0x9201	# <CJK>
+0x6E56	0x9227	# <CJK>
+0x6E57	0x9204	# <CJK>
+0x6E58	0x9225	# <CJK>
+0x6E59	0x9200	# <CJK>
+0x6E5A	0x923A	# <CJK>
+0x6E5B	0x9266	# <CJK>
+0x6E5C	0x9237	# <CJK>
+0x6E5D	0x9233	# <CJK>
+0x6E5E	0x9255	# <CJK>
+0x6E5F	0x923D	# <CJK>
+0x6E60	0x9238	# <CJK>
+0x6E61	0x925E	# <CJK>
+0x6E62	0x926C	# <CJK>
+0x6E63	0x926D	# <CJK>
+0x6E64	0x923F	# <CJK>
+0x6E65	0x9460	# <CJK>
+0x6E66	0x9230	# <CJK>
+0x6E67	0x9249	# <CJK>
+0x6E68	0x9248	# <CJK>
+0x6E69	0x924D	# <CJK>
+0x6E6A	0x922E	# <CJK>
+0x6E6B	0x9239	# <CJK>
+0x6E6C	0x9438	# <CJK>
+0x6E6D	0x92AC	# <CJK>
+0x6E6E	0x92A0	# <CJK>
+0x6E6F	0x927A	# <CJK>
+0x6E70	0x92AA	# <CJK>
+0x6E71	0x92EE	# <CJK>
+0x6E72	0x92CF	# <CJK>
+0x6E73	0x9403	# <CJK>
+0x6E74	0x92E3	# <CJK>
+0x6E75	0x943A	# <CJK>
+0x6E76	0x92B1	# <CJK>
+0x6E77	0x92A6	# <CJK>
+0x6E78	0x93A7	# <CJK>
+0x6E79	0x9296	# <CJK>
+0x6E7A	0x92CC	# <CJK>
+0x6E7B	0x92A9	# <CJK>
+0x6E7C	0x93F5	# <CJK>
+0x6E7D	0x9293	# <CJK>
+0x6E7E	0x927F	# <CJK>
+0x6F21	0x93A9	# <CJK>
+0x6F22	0x929A	# <CJK>
+0x6F23	0x931A	# <CJK>
+0x6F24	0x92AB	# <CJK>
+0x6F25	0x9283	# <CJK>
+0x6F26	0x940B	# <CJK>
+0x6F27	0x92A8	# <CJK>
+0x6F28	0x92A3	# <CJK>
+0x6F29	0x9412	# <CJK>
+0x6F2A	0x9338	# <CJK>
+0x6F2B	0x92F1	# <CJK>
+0x6F2C	0x93D7	# <CJK>
+0x6F2D	0x92E5	# <CJK>
+0x6F2E	0x92F0	# <CJK>
+0x6F2F	0x92EF	# <CJK>
+0x6F30	0x92E8	# <CJK>
+0x6F31	0x92BC	# <CJK>
+0x6F32	0x92DD	# <CJK>
+0x6F33	0x92F6	# <CJK>
+0x6F34	0x9426	# <CJK>
+0x6F35	0x9427	# <CJK>
+0x6F36	0x92C3	# <CJK>
+0x6F37	0x92DF	# <CJK>
+0x6F38	0x92E6	# <CJK>
+0x6F39	0x9312	# <CJK>
+0x6F3A	0x9306	# <CJK>
+0x6F3B	0x9369	# <CJK>
+0x6F3C	0x931B	# <CJK>
+0x6F3D	0x9340	# <CJK>
+0x6F3E	0x9301	# <CJK>
+0x6F3F	0x9315	# <CJK>
+0x6F40	0x932E	# <CJK>
+0x6F41	0x9343	# <CJK>
+0x6F42	0x9307	# <CJK>
+0x6F43	0x9308	# <CJK>
+0x6F44	0x931F	# <CJK>
+0x6F45	0x9319	# <CJK>
+0x6F46	0x9365	# <CJK>
+0x6F47	0x9347	# <CJK>
+0x6F48	0x9376	# <CJK>
+0x6F49	0x9354	# <CJK>
+0x6F4A	0x9364	# <CJK>
+0x6F4B	0x93AA	# <CJK>
+0x6F4C	0x9370	# <CJK>
+0x6F4D	0x9384	# <CJK>
+0x6F4E	0x93E4	# <CJK>
+0x6F4F	0x93D8	# <CJK>
+0x6F50	0x9428	# <CJK>
+0x6F51	0x9387	# <CJK>
+0x6F52	0x93CC	# <CJK>
+0x6F53	0x9398	# <CJK>
+0x6F54	0x93B8	# <CJK>
+0x6F55	0x93BF	# <CJK>
+0x6F56	0x93A6	# <CJK>
+0x6F57	0x93B0	# <CJK>
+0x6F58	0x93B5	# <CJK>
+0x6F59	0x944C	# <CJK>
+0x6F5A	0x93E2	# <CJK>
+0x6F5B	0x93DC	# <CJK>
+0x6F5C	0x93DD	# <CJK>
+0x6F5D	0x93CD	# <CJK>
+0x6F5E	0x93DE	# <CJK>
+0x6F5F	0x93C3	# <CJK>
+0x6F60	0x93C7	# <CJK>
+0x6F61	0x93D1	# <CJK>
+0x6F62	0x9414	# <CJK>
+0x6F63	0x941D	# <CJK>
+0x6F64	0x93F7	# <CJK>
+0x6F65	0x9465	# <CJK>
+0x6F66	0x9413	# <CJK>
+0x6F67	0x946D	# <CJK>
+0x6F68	0x9420	# <CJK>
+0x6F69	0x9479	# <CJK>
+0x6F6A	0x93F9	# <CJK>
+0x6F6B	0x9419	# <CJK>
+0x6F6C	0x944A	# <CJK>
+0x6F6D	0x9432	# <CJK>
+0x6F6E	0x943F	# <CJK>
+0x6F6F	0x9454	# <CJK>
+0x6F70	0x9463	# <CJK>
+0x6F71	0x937E	# <CJK>
+0x6F72	0x77E7	# <CJK>
+0x6F73	0x77EC	# <CJK>
+0x6F74	0x96C9	# <CJK>
+0x6F75	0x79D5	# <CJK>
+0x6F76	0x79ED	# <CJK>
+0x6F77	0x79E3	# <CJK>
+0x6F78	0x79EB	# <CJK>
+0x6F79	0x7A06	# <CJK>
+0x6F7A	0x5D47	# <CJK>
+0x6F7B	0x7A03	# <CJK>
+0x6F7C	0x7A02	# <CJK>
+0x6F7D	0x7A1E	# <CJK>
+0x6F7E	0x7A14	# <CJK>
+0x7021	0x7A39	# <CJK>
+0x7022	0x7A37	# <CJK>
+0x7023	0x7A61	# <CJK>
+0x7024	0x9ECF	# <CJK>
+0x7025	0x99A5	# <CJK>
+0x7026	0x7A70	# <CJK>
+0x7027	0x7688	# <CJK>
+0x7028	0x768E	# <CJK>
+0x7029	0x7693	# <CJK>
+0x702A	0x7699	# <CJK>
+0x702B	0x76A4	# <CJK>
+0x702C	0x74DE	# <CJK>
+0x702D	0x74E0	# <CJK>
+0x702E	0x752C	# <CJK>
+0x702F	0x9CE9	# <CJK>
+0x7030	0x9CF6	# <CJK>
+0x7031	0x9D07	# <CJK>
+0x7032	0x9D06	# <CJK>
+0x7033	0x9D23	# <CJK>
+0x7034	0x9D87	# <CJK>
+0x7035	0x9E15	# <CJK>
+0x7036	0x9D1D	# <CJK>
+0x7037	0x9D1F	# <CJK>
+0x7038	0x9DE5	# <CJK>
+0x7039	0x9D2F	# <CJK>
+0x703A	0x9DD9	# <CJK>
+0x703B	0x9D30	# <CJK>
+0x703C	0x9D42	# <CJK>
+0x703D	0x9E1E	# <CJK>
+0x703E	0x9D53	# <CJK>
+0x703F	0x9E1D	# <CJK>
+0x7040	0x9D60	# <CJK>
+0x7041	0x9D52	# <CJK>
+0x7042	0x9DF3	# <CJK>
+0x7043	0x9D5C	# <CJK>
+0x7044	0x9D61	# <CJK>
+0x7045	0x9D93	# <CJK>
+0x7046	0x9D6A	# <CJK>
+0x7047	0x9D6F	# <CJK>
+0x7048	0x9D89	# <CJK>
+0x7049	0x9D98	# <CJK>
+0x704A	0x9D9A	# <CJK>
+0x704B	0x9DC0	# <CJK>
+0x704C	0x9DA5	# <CJK>
+0x704D	0x9DA9	# <CJK>
+0x704E	0x9DC2	# <CJK>
+0x704F	0x9DBC	# <CJK>
+0x7050	0x9E1A	# <CJK>
+0x7051	0x9DD3	# <CJK>
+0x7052	0x9DDA	# <CJK>
+0x7053	0x9DEF	# <CJK>
+0x7054	0x9DE6	# <CJK>
+0x7055	0x9DF2	# <CJK>
+0x7056	0x9DF8	# <CJK>
+0x7057	0x9E0C	# <CJK>
+0x7058	0x9DFA	# <CJK>
+0x7059	0x9E1B	# <CJK>
+0x705A	0x7592	# <CJK>
+0x705B	0x7594	# <CJK>
+0x705C	0x7664	# <CJK>
+0x705D	0x7658	# <CJK>
+0x705E	0x759D	# <CJK>
+0x705F	0x7667	# <CJK>
+0x7060	0x75A3	# <CJK>
+0x7061	0x75B3	# <CJK>
+0x7062	0x75B4	# <CJK>
+0x7063	0x75B8	# <CJK>
+0x7064	0x75C4	# <CJK>
+0x7065	0x75B1	# <CJK>
+0x7066	0x75B0	# <CJK>
+0x7067	0x75C3	# <CJK>
+0x7068	0x75C2	# <CJK>
+0x7069	0x7602	# <CJK>
+0x706A	0x75CD	# <CJK>
+0x706B	0x75E3	# <CJK>
+0x706C	0x7646	# <CJK>
+0x706D	0x75E6	# <CJK>
+0x706E	0x75E4	# <CJK>
+0x706F	0x7647	# <CJK>
+0x7070	0x75E7	# <CJK>
+0x7071	0x7603	# <CJK>
+0x7072	0x75F1	# <CJK>
+0x7073	0x75FC	# <CJK>
+0x7074	0x75FF	# <CJK>
+0x7075	0x7610	# <CJK>
+0x7076	0x7600	# <CJK>
+0x7077	0x7649	# <CJK>
+0x7078	0x760C	# <CJK>
+0x7079	0x761E	# <CJK>
+0x707A	0x760A	# <CJK>
+0x707B	0x7625	# <CJK>
+0x707C	0x763B	# <CJK>
+0x707D	0x7615	# <CJK>
+0x707E	0x7619	# <CJK>
+0x7121	0x761B	# <CJK>
+0x7122	0x763C	# <CJK>
+0x7123	0x7622	# <CJK>
+0x7124	0x7620	# <CJK>
+0x7125	0x7640	# <CJK>
+0x7126	0x762D	# <CJK>
+0x7127	0x7630	# <CJK>
+0x7128	0x766D	# <CJK>
+0x7129	0x7635	# <CJK>
+0x712A	0x7643	# <CJK>
+0x712B	0x766E	# <CJK>
+0x712C	0x7633	# <CJK>
+0x712D	0x764D	# <CJK>
+0x712E	0x7669	# <CJK>
+0x712F	0x7654	# <CJK>
+0x7130	0x765C	# <CJK>
+0x7131	0x7656	# <CJK>
+0x7132	0x7672	# <CJK>
+0x7133	0x766F	# <CJK>
+0x7134	0x7FCA	# <CJK>
+0x7135	0x7AE6	# <CJK>
+0x7136	0x7A78	# <CJK>
+0x7137	0x7A79	# <CJK>
+0x7138	0x7A80	# <CJK>
+0x7139	0x7A86	# <CJK>
+0x713A	0x7A88	# <CJK>
+0x713B	0x7A95	# <CJK>
+0x713C	0x7AC7	# <CJK>
+0x713D	0x7AA0	# <CJK>
+0x713E	0x7AAC	# <CJK>
+0x713F	0x7AA8	# <CJK>
+0x7140	0x7AB6	# <CJK>
+0x7141	0x7AB3	# <CJK>
+0x7142	0x8864	# <CJK>
+0x7143	0x8869	# <CJK>
+0x7144	0x8872	# <CJK>
+0x7145	0x887D	# <CJK>
+0x7146	0x887F	# <CJK>
+0x7147	0x8882	# <CJK>
+0x7148	0x88A2	# <CJK>
+0x7149	0x8960	# <CJK>
+0x714A	0x88B7	# <CJK>
+0x714B	0x88BC	# <CJK>
+0x714C	0x88C9	# <CJK>
+0x714D	0x8933	# <CJK>
+0x714E	0x88CE	# <CJK>
+0x714F	0x895D	# <CJK>
+0x7150	0x8947	# <CJK>
+0x7151	0x88F1	# <CJK>
+0x7152	0x891A	# <CJK>
+0x7153	0x88FC	# <CJK>
+0x7154	0x88E8	# <CJK>
+0x7155	0x88FE	# <CJK>
+0x7156	0x88F0	# <CJK>
+0x7157	0x8921	# <CJK>
+0x7158	0x8919	# <CJK>
+0x7159	0x8913	# <CJK>
+0x715A	0x8938	# <CJK>
+0x715B	0x890A	# <CJK>
+0x715C	0x8964	# <CJK>
+0x715D	0x892B	# <CJK>
+0x715E	0x8936	# <CJK>
+0x715F	0x8941	# <CJK>
+0x7160	0x8966	# <CJK>
+0x7161	0x897B	# <CJK>
+0x7162	0x758B	# <CJK>
+0x7163	0x80E5	# <CJK>
+0x7164	0x76B8	# <CJK>
+0x7165	0x76B4	# <CJK>
+0x7166	0x77DC	# <CJK>
+0x7167	0x8012	# <CJK>
+0x7168	0x8014	# <CJK>
+0x7169	0x8016	# <CJK>
+0x716A	0x801C	# <CJK>
+0x716B	0x8020	# <CJK>
+0x716C	0x802E	# <CJK>
+0x716D	0x8025	# <CJK>
+0x716E	0x8026	# <CJK>
+0x716F	0x802C	# <CJK>
+0x7170	0x8029	# <CJK>
+0x7171	0x8028	# <CJK>
+0x7172	0x8031	# <CJK>
+0x7173	0x800B	# <CJK>
+0x7174	0x8035	# <CJK>
+0x7175	0x8043	# <CJK>
+0x7176	0x8046	# <CJK>
+0x7177	0x8079	# <CJK>
+0x7178	0x8052	# <CJK>
+0x7179	0x8075	# <CJK>
+0x717A	0x8071	# <CJK>
+0x717B	0x8983	# <CJK>
+0x717C	0x9807	# <CJK>
+0x717D	0x980E	# <CJK>
+0x717E	0x980F	# <CJK>
+0x7221	0x9821	# <CJK>
+0x7222	0x981C	# <CJK>
+0x7223	0x6F41	# <CJK>
+0x7224	0x9826	# <CJK>
+0x7225	0x9837	# <CJK>
+0x7226	0x984E	# <CJK>
+0x7227	0x9853	# <CJK>
+0x7228	0x9873	# <CJK>
+0x7229	0x9862	# <CJK>
+0x722A	0x9859	# <CJK>
+0x722B	0x9865	# <CJK>
+0x722C	0x986C	# <CJK>
+0x722D	0x9870	# <CJK>
+0x722E	0x864D	# <CJK>
+0x722F	0x8654	# <CJK>
+0x7230	0x866C	# <CJK>
+0x7231	0x87E3	# <CJK>
+0x7232	0x8806	# <CJK>
+0x7233	0x867A	# <CJK>
+0x7234	0x867C	# <CJK>
+0x7235	0x867B	# <CJK>
+0x7236	0x86A8	# <CJK>
+0x7237	0x868D	# <CJK>
+0x7238	0x868B	# <CJK>
+0x7239	0x8706	# <CJK>
+0x723A	0x869D	# <CJK>
+0x723B	0x86A7	# <CJK>
+0x723C	0x86A3	# <CJK>
+0x723D	0x86AA	# <CJK>
+0x723E	0x8693	# <CJK>
+0x723F	0x86A9	# <CJK>
+0x7240	0x86B6	# <CJK>
+0x7241	0x86C4	# <CJK>
+0x7242	0x86B5	# <CJK>
+0x7243	0x8823	# <CJK>
+0x7244	0x86B0	# <CJK>
+0x7245	0x86BA	# <CJK>
+0x7246	0x86B1	# <CJK>
+0x7247	0x86AF	# <CJK>
+0x7248	0x86C9	# <CJK>
+0x7249	0x87F6	# <CJK>
+0x724A	0x86B4	# <CJK>
+0x724B	0x86E9	# <CJK>
+0x724C	0x86FA	# <CJK>
+0x724D	0x87EF	# <CJK>
+0x724E	0x86ED	# <CJK>
+0x724F	0x8784	# <CJK>
+0x7250	0x86D0	# <CJK>
+0x7251	0x8713	# <CJK>
+0x7252	0x86DE	# <CJK>
+0x7253	0x8810	# <CJK>
+0x7254	0x86DF	# <CJK>
+0x7255	0x86D8	# <CJK>
+0x7256	0x86D1	# <CJK>
+0x7257	0x8703	# <CJK>
+0x7258	0x8707	# <CJK>
+0x7259	0x86F8	# <CJK>
+0x725A	0x8708	# <CJK>
+0x725B	0x870A	# <CJK>
+0x725C	0x870D	# <CJK>
+0x725D	0x8709	# <CJK>
+0x725E	0x8723	# <CJK>
+0x725F	0x873B	# <CJK>
+0x7260	0x871E	# <CJK>
+0x7261	0x8725	# <CJK>
+0x7262	0x872E	# <CJK>
+0x7263	0x871A	# <CJK>
+0x7264	0x873E	# <CJK>
+0x7265	0x87C8	# <CJK>
+0x7266	0x8734	# <CJK>
+0x7267	0x8731	# <CJK>
+0x7268	0x8729	# <CJK>
+0x7269	0x8737	# <CJK>
+0x726A	0x873F	# <CJK>
+0x726B	0x8782	# <CJK>
+0x726C	0x8722	# <CJK>
+0x726D	0x877D	# <CJK>
+0x726E	0x8811	# <CJK>
+0x726F	0x877B	# <CJK>
+0x7270	0x8760	# <CJK>
+0x7271	0x8770	# <CJK>
+0x7272	0x874C	# <CJK>
+0x7273	0x876E	# <CJK>
+0x7274	0x878B	# <CJK>
+0x7275	0x8753	# <CJK>
+0x7276	0x8763	# <CJK>
+0x7277	0x87BB	# <CJK>
+0x7278	0x8764	# <CJK>
+0x7279	0x8759	# <CJK>
+0x727A	0x8765	# <CJK>
+0x727B	0x8793	# <CJK>
+0x727C	0x87AF	# <CJK>
+0x727D	0x87CE	# <CJK>
+0x727E	0x87D2	# <CJK>
+0x7321	0x87C6	# <CJK>
+0x7322	0x8788	# <CJK>
+0x7323	0x8785	# <CJK>
+0x7324	0x87AD	# <CJK>
+0x7325	0x8797	# <CJK>
+0x7326	0x8783	# <CJK>
+0x7327	0x87AB	# <CJK>
+0x7328	0x87E5	# <CJK>
+0x7329	0x87AC	# <CJK>
+0x732A	0x87B5	# <CJK>
+0x732B	0x87B3	# <CJK>
+0x732C	0x87CB	# <CJK>
+0x732D	0x87D3	# <CJK>
+0x732E	0x87BD	# <CJK>
+0x732F	0x87D1	# <CJK>
+0x7330	0x87C0	# <CJK>
+0x7331	0x87CA	# <CJK>
+0x7332	0x87DB	# <CJK>
+0x7333	0x87EA	# <CJK>
+0x7334	0x87E0	# <CJK>
+0x7335	0x87EE	# <CJK>
+0x7336	0x8816	# <CJK>
+0x7337	0x8813	# <CJK>
+0x7338	0x87FE	# <CJK>
+0x7339	0x880A	# <CJK>
+0x733A	0x881B	# <CJK>
+0x733B	0x8821	# <CJK>
+0x733C	0x8839	# <CJK>
+0x733D	0x883C	# <CJK>
+0x733E	0x7F36	# <CJK>
+0x733F	0x7F4C	# <CJK>
+0x7340	0x7F44	# <CJK>
+0x7341	0x7F45	# <CJK>
+0x7342	0x8210	# <CJK>
+0x7343	0x7AFA	# <CJK>
+0x7344	0x7AFD	# <CJK>
+0x7345	0x7B08	# <CJK>
+0x7346	0x7BE4	# <CJK>
+0x7347	0x7B04	# <CJK>
+0x7348	0x7B67	# <CJK>
+0x7349	0x7B0A	# <CJK>
+0x734A	0x7B2B	# <CJK>
+0x734B	0x7B0F	# <CJK>
+0x734C	0x7B47	# <CJK>
+0x734D	0x7B38	# <CJK>
+0x734E	0x7B2A	# <CJK>
+0x734F	0x7B19	# <CJK>
+0x7350	0x7B2E	# <CJK>
+0x7351	0x7B31	# <CJK>
+0x7352	0x7B20	# <CJK>
+0x7353	0x7B25	# <CJK>
+0x7354	0x7B24	# <CJK>
+0x7355	0x7B33	# <CJK>
+0x7356	0x7C69	# <CJK>
+0x7357	0x7B1E	# <CJK>
+0x7358	0x7B58	# <CJK>
+0x7359	0x7BF3	# <CJK>
+0x735A	0x7B45	# <CJK>
+0x735B	0x7B75	# <CJK>
+0x735C	0x7B4C	# <CJK>
+0x735D	0x7B8F	# <CJK>
+0x735E	0x7B60	# <CJK>
+0x735F	0x7B6E	# <CJK>
+0x7360	0x7B7B	# <CJK>
+0x7361	0x7B62	# <CJK>
+0x7362	0x7B72	# <CJK>
+0x7363	0x7B71	# <CJK>
+0x7364	0x7B90	# <CJK>
+0x7365	0x7C00	# <CJK>
+0x7366	0x7BCB	# <CJK>
+0x7367	0x7BB8	# <CJK>
+0x7368	0x7BAC	# <CJK>
+0x7369	0x7B9D	# <CJK>
+0x736A	0x7C5C	# <CJK>
+0x736B	0x7B85	# <CJK>
+0x736C	0x7C1E	# <CJK>
+0x736D	0x7B9C	# <CJK>
+0x736E	0x7BA2	# <CJK>
+0x736F	0x7C2B	# <CJK>
+0x7370	0x7BB4	# <CJK>
+0x7371	0x7C23	# <CJK>
+0x7372	0x7BC1	# <CJK>
+0x7373	0x7BCC	# <CJK>
+0x7374	0x7BDD	# <CJK>
+0x7375	0x7BDA	# <CJK>
+0x7376	0x7BE5	# <CJK>
+0x7377	0x7BE6	# <CJK>
+0x7378	0x7BEA	# <CJK>
+0x7379	0x7C0C	# <CJK>
+0x737A	0x7BFE	# <CJK>
+0x737B	0x7BFC	# <CJK>
+0x737C	0x7C0F	# <CJK>
+0x737D	0x7C6A	# <CJK>
+0x737E	0x7C0B	# <CJK>
+0x7421	0x7C1F	# <CJK>
+0x7422	0x7C2A	# <CJK>
+0x7423	0x7C26	# <CJK>
+0x7424	0x7C38	# <CJK>
+0x7425	0x7C5F	# <CJK>
+0x7426	0x7C40	# <CJK>
+0x7427	0x81FE	# <CJK>
+0x7428	0x8201	# <CJK>
+0x7429	0x8202	# <CJK>
+0x742A	0x8204	# <CJK>
+0x742B	0x81EC	# <CJK>
+0x742C	0x8844	# <CJK>
+0x742D	0x8221	# <CJK>
+0x742E	0x8222	# <CJK>
+0x742F	0x8264	# <CJK>
+0x7430	0x822D	# <CJK>
+0x7431	0x822F	# <CJK>
+0x7432	0x8228	# <CJK>
+0x7433	0x822B	# <CJK>
+0x7434	0x8238	# <CJK>
+0x7435	0x826B	# <CJK>
+0x7436	0x8233	# <CJK>
+0x7437	0x8234	# <CJK>
+0x7438	0x823E	# <CJK>
+0x7439	0x8244	# <CJK>
+0x743A	0x8249	# <CJK>
+0x743B	0x824B	# <CJK>
+0x743C	0x824F	# <CJK>
+0x743D	0x825A	# <CJK>
+0x743E	0x825F	# <CJK>
+0x743F	0x8268	# <CJK>
+0x7440	0x887E	# <CJK>
+0x7441	0x88CA	# <CJK>
+0x7442	0x8888	# <CJK>
+0x7443	0x88D8	# <CJK>
+0x7444	0x88DF	# <CJK>
+0x7445	0x895E	# <CJK>
+0x7446	0x7F9D	# <CJK>
+0x7447	0x7FA5	# <CJK>
+0x7448	0x7FA7	# <CJK>
+0x7449	0x7FAF	# <CJK>
+0x744A	0x7FB0	# <CJK>
+0x744B	0x7FB2	# <CJK>
+0x744C	0x7C7C	# <CJK>
+0x744D	0x6549	# <CJK>
+0x744E	0x7C91	# <CJK>
+0x744F	0x7CF2	# <CJK>
+0x7450	0x7CF6	# <CJK>
+0x7451	0x7C9E	# <CJK>
+0x7452	0x7CA2	# <CJK>
+0x7453	0x7CB2	# <CJK>
+0x7454	0x7CBC	# <CJK>
+0x7455	0x7CBD	# <CJK>
+0x7456	0x7CDD	# <CJK>
+0x7457	0x7CC7	# <CJK>
+0x7458	0x7CCC	# <CJK>
+0x7459	0x7CCD	# <CJK>
+0x745A	0x7CC8	# <CJK>
+0x745B	0x7CC5	# <CJK>
+0x745C	0x7CD7	# <CJK>
+0x745D	0x7CE8	# <CJK>
+0x745E	0x826E	# <CJK>
+0x745F	0x66A8	# <CJK>
+0x7460	0x7FBF	# <CJK>
+0x7461	0x7FCE	# <CJK>
+0x7462	0x7FD5	# <CJK>
+0x7463	0x7FE5	# <CJK>
+0x7464	0x7FE1	# <CJK>
+0x7465	0x7FE6	# <CJK>
+0x7466	0x7FE9	# <CJK>
+0x7467	0x7FEE	# <CJK>
+0x7468	0x7FF3	# <CJK>
+0x7469	0x7CF8	# <CJK>
+0x746A	0x7E36	# <CJK>
+0x746B	0x7DA6	# <CJK>
+0x746C	0x7DAE	# <CJK>
+0x746D	0x7E47	# <CJK>
+0x746E	0x7E9B	# <CJK>
+0x746F	0x9EA9	# <CJK>
+0x7470	0x9EB4	# <CJK>
+0x7471	0x8D73	# <CJK>
+0x7472	0x8D84	# <CJK>
+0x7473	0x8D94	# <CJK>
+0x7474	0x8D91	# <CJK>
+0x7475	0x8DB2	# <CJK>
+0x7476	0x8D67	# <CJK>
+0x7477	0x8D6D	# <CJK>
+0x7478	0x8C47	# <CJK>
+0x7479	0x8C49	# <CJK>
+0x747A	0x914A	# <CJK>
+0x747B	0x9150	# <CJK>
+0x747C	0x914E	# <CJK>
+0x747D	0x914F	# <CJK>
+0x747E	0x9164	# <CJK>
+0x7521	0x9162	# <CJK>
+0x7522	0x9161	# <CJK>
+0x7523	0x9170	# <CJK>
+0x7524	0x9169	# <CJK>
+0x7525	0x916F	# <CJK>
+0x7526	0x91C5	# <CJK>
+0x7527	0x91C3	# <CJK>
+0x7528	0x9172	# <CJK>
+0x7529	0x9174	# <CJK>
+0x752A	0x9179	# <CJK>
+0x752B	0x918C	# <CJK>
+0x752C	0x9185	# <CJK>
+0x752D	0x9190	# <CJK>
+0x752E	0x918D	# <CJK>
+0x752F	0x9191	# <CJK>
+0x7530	0x91A2	# <CJK>
+0x7531	0x91A3	# <CJK>
+0x7532	0x91AA	# <CJK>
+0x7533	0x91AD	# <CJK>
+0x7534	0x91AE	# <CJK>
+0x7535	0x91AF	# <CJK>
+0x7536	0x91B5	# <CJK>
+0x7537	0x91B4	# <CJK>
+0x7538	0x91BA	# <CJK>
+0x7539	0x8C55	# <CJK>
+0x753A	0x9E7A	# <CJK>
+0x753B	0x8E89	# <CJK>
+0x753C	0x8DEB	# <CJK>
+0x753D	0x8E05	# <CJK>
+0x753E	0x8E59	# <CJK>
+0x753F	0x8E69	# <CJK>
+0x7540	0x8DB5	# <CJK>
+0x7541	0x8DBF	# <CJK>
+0x7542	0x8DBC	# <CJK>
+0x7543	0x8DBA	# <CJK>
+0x7544	0x8E4C	# <CJK>
+0x7545	0x8DD6	# <CJK>
+0x7546	0x8DD7	# <CJK>
+0x7547	0x8DDA	# <CJK>
+0x7548	0x8E92	# <CJK>
+0x7549	0x8DCE	# <CJK>
+0x754A	0x8DCF	# <CJK>
+0x754B	0x8DDB	# <CJK>
+0x754C	0x8DC6	# <CJK>
+0x754D	0x8DEC	# <CJK>
+0x754E	0x8E7A	# <CJK>
+0x754F	0x8E55	# <CJK>
+0x7550	0x8DE3	# <CJK>
+0x7551	0x8E9A	# <CJK>
+0x7552	0x8E8B	# <CJK>
+0x7553	0x8DE4	# <CJK>
+0x7554	0x8E09	# <CJK>
+0x7555	0x8DFD	# <CJK>
+0x7556	0x8E14	# <CJK>
+0x7557	0x8E1D	# <CJK>
+0x7558	0x8E1F	# <CJK>
+0x7559	0x8E93	# <CJK>
+0x755A	0x8E2E	# <CJK>
+0x755B	0x8E23	# <CJK>
+0x755C	0x8E91	# <CJK>
+0x755D	0x8E3A	# <CJK>
+0x755E	0x8E40	# <CJK>
+0x755F	0x8E39	# <CJK>
+0x7560	0x8E35	# <CJK>
+0x7561	0x8E3D	# <CJK>
+0x7562	0x8E31	# <CJK>
+0x7563	0x8E49	# <CJK>
+0x7564	0x8E41	# <CJK>
+0x7565	0x8E42	# <CJK>
+0x7566	0x8EA1	# <CJK>
+0x7567	0x8E63	# <CJK>
+0x7568	0x8E4A	# <CJK>
+0x7569	0x8E70	# <CJK>
+0x756A	0x8E76	# <CJK>
+0x756B	0x8E7C	# <CJK>
+0x756C	0x8E6F	# <CJK>
+0x756D	0x8E74	# <CJK>
+0x756E	0x8E85	# <CJK>
+0x756F	0x8EAA	# <CJK>
+0x7570	0x8E94	# <CJK>
+0x7571	0x8E90	# <CJK>
+0x7572	0x8EA6	# <CJK>
+0x7573	0x8E9E	# <CJK>
+0x7574	0x8C78	# <CJK>
+0x7575	0x8C82	# <CJK>
+0x7576	0x8C8A	# <CJK>
+0x7577	0x8C85	# <CJK>
+0x7578	0x8C98	# <CJK>
+0x7579	0x8C94	# <CJK>
+0x757A	0x659B	# <CJK>
+0x757B	0x89D6	# <CJK>
+0x757C	0x89F4	# <CJK>
+0x757D	0x89DA	# <CJK>
+0x757E	0x89DC	# <CJK>
+0x7621	0x89E5	# <CJK>
+0x7622	0x89EB	# <CJK>
+0x7623	0x89F6	# <CJK>
+0x7624	0x8A3E	# <CJK>
+0x7625	0x8B26	# <CJK>
+0x7626	0x975A	# <CJK>
+0x7627	0x96E9	# <CJK>
+0x7628	0x9742	# <CJK>
+0x7629	0x96EF	# <CJK>
+0x762A	0x9706	# <CJK>
+0x762B	0x973D	# <CJK>
+0x762C	0x9708	# <CJK>
+0x762D	0x970F	# <CJK>
+0x762E	0x970E	# <CJK>
+0x762F	0x972A	# <CJK>
+0x7630	0x9744	# <CJK>
+0x7631	0x9730	# <CJK>
+0x7632	0x973E	# <CJK>
+0x7633	0x9F54	# <CJK>
+0x7634	0x9F5F	# <CJK>
+0x7635	0x9F59	# <CJK>
+0x7636	0x9F60	# <CJK>
+0x7637	0x9F5C	# <CJK>
+0x7638	0x9F66	# <CJK>
+0x7639	0x9F6C	# <CJK>
+0x763A	0x9F6A	# <CJK>
+0x763B	0x9F77	# <CJK>
+0x763C	0x9EFD	# <CJK>
+0x763D	0x9EFF	# <CJK>
+0x763E	0x9F09	# <CJK>
+0x763F	0x96B9	# <CJK>
+0x7640	0x96BC	# <CJK>
+0x7641	0x96BD	# <CJK>
+0x7642	0x96CE	# <CJK>
+0x7643	0x96D2	# <CJK>
+0x7644	0x77BF	# <CJK>
+0x7645	0x8B8E	# <CJK>
+0x7646	0x928E	# <CJK>
+0x7647	0x947E	# <CJK>
+0x7648	0x92C8	# <CJK>
+0x7649	0x93E8	# <CJK>
+0x764A	0x936A	# <CJK>
+0x764B	0x93CA	# <CJK>
+0x764C	0x938F	# <CJK>
+0x764D	0x943E	# <CJK>
+0x764E	0x946B	# <CJK>
+0x764F	0x9B77	# <CJK>
+0x7650	0x9B74	# <CJK>
+0x7651	0x9B81	# <CJK>
+0x7652	0x9B83	# <CJK>
+0x7653	0x9B8E	# <CJK>
+0x7654	0x9C78	# <CJK>
+0x7655	0x7A4C	# <CJK>
+0x7656	0x9B92	# <CJK>
+0x7657	0x9C5F	# <CJK>
+0x7658	0x9B90	# <CJK>
+0x7659	0x9BAD	# <CJK>
+0x765A	0x9B9A	# <CJK>
+0x765B	0x9BAA	# <CJK>
+0x765C	0x9B9E	# <CJK>
+0x765D	0x9C6D	# <CJK>
+0x765E	0x9BAB	# <CJK>
+0x765F	0x9B9D	# <CJK>
+0x7660	0x9C58	# <CJK>
+0x7661	0x9BC1	# <CJK>
+0x7662	0x9C7A	# <CJK>
+0x7663	0x9C31	# <CJK>
+0x7664	0x9C39	# <CJK>
+0x7665	0x9C23	# <CJK>
+0x7666	0x9C37	# <CJK>
+0x7667	0x9BC0	# <CJK>
+0x7668	0x9BCA	# <CJK>
+0x7669	0x9BC7	# <CJK>
+0x766A	0x9BFD	# <CJK>
+0x766B	0x9BD6	# <CJK>
+0x766C	0x9BEA	# <CJK>
+0x766D	0x9BEB	# <CJK>
+0x766E	0x9BE1	# <CJK>
+0x766F	0x9BE4	# <CJK>
+0x7670	0x9BE7	# <CJK>
+0x7671	0x9BDD	# <CJK>
+0x7672	0x9BE2	# <CJK>
+0x7673	0x9BF0	# <CJK>
+0x7674	0x9BDB	# <CJK>
+0x7675	0x9BF4	# <CJK>
+0x7676	0x9BD4	# <CJK>
+0x7677	0x9C5D	# <CJK>
+0x7678	0x9C08	# <CJK>
+0x7679	0x9C10	# <CJK>
+0x767A	0x9C0D	# <CJK>
+0x767B	0x9C12	# <CJK>
+0x767C	0x9C09	# <CJK>
+0x767D	0x9BFF	# <CJK>
+0x767E	0x9C20	# <CJK>
+0x7721	0x9C32	# <CJK>
+0x7722	0x9C2D	# <CJK>
+0x7723	0x9C28	# <CJK>
+0x7724	0x9C25	# <CJK>
+0x7725	0x9C29	# <CJK>
+0x7726	0x9C33	# <CJK>
+0x7727	0x9C3E	# <CJK>
+0x7728	0x9C48	# <CJK>
+0x7729	0x9C3B	# <CJK>
+0x772A	0x9C35	# <CJK>
+0x772B	0x9C45	# <CJK>
+0x772C	0x9C56	# <CJK>
+0x772D	0x9C54	# <CJK>
+0x772E	0x9C52	# <CJK>
+0x772F	0x9C67	# <CJK>
+0x7730	0x977C	# <CJK>
+0x7731	0x9785	# <CJK>
+0x7732	0x97C3	# <CJK>
+0x7733	0x97BD	# <CJK>
+0x7734	0x9794	# <CJK>
+0x7735	0x97C9	# <CJK>
+0x7736	0x97AB	# <CJK>
+0x7737	0x97A3	# <CJK>
+0x7738	0x97B2	# <CJK>
+0x7739	0x97B4	# <CJK>
+0x773A	0x9AB1	# <CJK>
+0x773B	0x9AB0	# <CJK>
+0x773C	0x9AB7	# <CJK>
+0x773D	0x9DBB	# <CJK>
+0x773E	0x9AB6	# <CJK>
+0x773F	0x9ABA	# <CJK>
+0x7740	0x9ABC	# <CJK>
+0x7741	0x9AC1	# <CJK>
+0x7742	0x9AC0	# <CJK>
+0x7743	0x9ACF	# <CJK>
+0x7744	0x9AC2	# <CJK>
+0x7745	0x9AD6	# <CJK>
+0x7746	0x9AD5	# <CJK>
+0x7747	0x9AD1	# <CJK>
+0x7748	0x9B45	# <CJK>
+0x7749	0x9B43	# <CJK>
+0x774A	0x9B58	# <CJK>
+0x774B	0x9B4E	# <CJK>
+0x774C	0x9B48	# <CJK>
+0x774D	0x9B4D	# <CJK>
+0x774E	0x9B51	# <CJK>
+0x774F	0x9957	# <CJK>
+0x7750	0x995C	# <CJK>
+0x7751	0x992E	# <CJK>
+0x7752	0x9955	# <CJK>
+0x7753	0x9954	# <CJK>
+0x7754	0x9ADF	# <CJK>
+0x7755	0x9AE1	# <CJK>
+0x7756	0x9AE6	# <CJK>
+0x7757	0x9AEF	# <CJK>
+0x7758	0x9AEB	# <CJK>
+0x7759	0x9AFB	# <CJK>
+0x775A	0x9AED	# <CJK>
+0x775B	0x9AF9	# <CJK>
+0x775C	0x9B08	# <CJK>
+0x775D	0x9B0F	# <CJK>
+0x775E	0x9B22	# <CJK>
+0x775F	0x9B1F	# <CJK>
+0x7760	0x9B23	# <CJK>
+0x7761	0x4E48	# <CJK>
+0x7762	0x9EBE	# <CJK>
+0x7763	0x7E3B	# <CJK>
+0x7764	0x9E82	# <CJK>
+0x7765	0x9E87	# <CJK>
+0x7766	0x9E88	# <CJK>
+0x7767	0x9E8B	# <CJK>
+0x7768	0x9E92	# <CJK>
+0x7769	0x93D6	# <CJK>
+0x776A	0x9E9D	# <CJK>
+0x776B	0x9E9F	# <CJK>
+0x776C	0x9EDB	# <CJK>
+0x776D	0x9EDC	# <CJK>
+0x776E	0x9EDD	# <CJK>
+0x776F	0x9EE0	# <CJK>
+0x7770	0x9EDF	# <CJK>
+0x7771	0x9EE2	# <CJK>
+0x7772	0x9EF7	# <CJK>
+0x7773	0x9EE7	# <CJK>
+0x7774	0x9EE5	# <CJK>
+0x7775	0x9EF2	# <CJK>
+0x7776	0x9EEF	# <CJK>
+0x7777	0x9F22	# <CJK>
+0x7778	0x9F2C	# <CJK>
+0x7779	0x9F2F	# <CJK>
+0x777A	0x9F39	# <CJK>
+0x777B	0x9F37	# <CJK>
+0x777C	0x9F3D	# <CJK>
+0x777D	0x9F3E	# <CJK>
+0x777E	0x9F44	# <CJK>
+0x7821	0x896C	# <CJK>
+0x7822	0x95C6	# <CJK>
+0x7823	0x9336	# <CJK>
+0x7824	0x5F46	# <CJK>
+0x7825	0x8514	# <CJK>
+0x7826	0x7E94	# <CJK>
+0x7827	0x5382	# <CJK>
+0x7828	0x51B2	# <CJK>
+0x7829	0x4E11	# <CJK>
+0x782A	0x9F63	# <CJK>
+0x782B	0x5679	# <CJK>
+0x782C	0x515A	# <CJK>
+0x782D	0x6DC0	# <CJK>
+0x782E	0x9F15	# <CJK>
+0x782F	0x6597	# <CJK>
+0x7830	0x5641	# <CJK>
+0x7831	0x9AEE	# <CJK>
+0x7832	0x8303	# <CJK>
+0x7833	0x4E30	# <CJK>
+0x7834	0x8907	# <CJK>
+0x7835	0x5E72	# <CJK>
+0x7836	0x7A40	# <CJK>
+0x7837	0x98B3	# <CJK>
+0x7838	0x5E7F	# <CJK>
+0x7839	0x95A4	# <CJK>
+0x783A	0x9B0D	# <CJK>
+0x783B	0x5212	# <CJK>
+0x783C	0x8FF4	# <CJK>
+0x783D	0x5F59	# <CJK>
+0x783E	0x7A6B	# <CJK>
+0x783F	0x98E2	# <CJK>
+0x7840	0x51E0	# <CJK>
+0x7841	0x50A2	# <CJK>
+0x7842	0x4EF7	# <CJK>
+0x7843	0x8350	# <CJK>
+0x7844	0x8591	# <CJK>
+0x7845	0x5118	# <CJK>
+0x7846	0x636E	# <CJK>
+0x7847	0x6372	# <CJK>
+0x7848	0x524B	# <CJK>
+0x7849	0x5938	# <CJK>
+0x784A	0x774F	# <CJK>
+0x784B	0x8721	# <CJK>
+0x784C	0x814A	# <CJK>
+0x784D	0x7E8D	# <CJK>
+0x784E	0x91CC	# <CJK>
+0x784F	0x66C6	# <CJK>
+0x7850	0x5E18	# <CJK>
+0x7851	0x77AD	# <CJK>
+0x7852	0x9E75	# <CJK>
+0x7853	0x56C9	# <CJK>
+0x7854	0x9EF4	# <CJK>
+0x7855	0x6FDB	# <CJK>
+0x7856	0x61DE	# <CJK>
+0x7857	0x77C7	# <CJK>
+0x7858	0x7030	# <CJK>
+0x7859	0x9EB5	# <CJK>
+0x785A	0x884A	# <CJK>
+0x785B	0x95E2	# <CJK>
+0x785C	0x82F9	# <CJK>
+0x785D	0x51ED	# <CJK>
+0x785E	0x6251	# <CJK>
+0x785F	0x4EC6	# <CJK>
+0x7860	0x6734	# <CJK>
+0x7861	0x97C6	# <CJK>
+0x7862	0x7C64	# <CJK>
+0x7863	0x7E34	# <CJK>
+0x7864	0x97A6	# <CJK>
+0x7865	0x9EAF	# <CJK>
+0x7866	0x786E	# <CJK>
+0x7867	0x820D	# <CJK>
+0x7868	0x672F	# <CJK>
+0x7869	0x677E	# <CJK>
+0x786A	0x56CC	# <CJK>
+0x786B	0x53F0	# <CJK>
+0x786C	0x98B1	# <CJK>
+0x786D	0x6AAF	# <CJK>
+0x786E	0x7F4E	# <CJK>
+0x786F	0x6D82	# <CJK>
+0x7870	0x7CF0	# <CJK>
+0x7871	0x4E07	# <CJK>
+0x7872	0x4FC2	# <CJK>
+0x7873	0x7E6B	# <CJK>
+0x7874	0x9E79	# <CJK>
+0x7875	0x56AE	# <CJK>
+0x7876	0x9B1A	# <CJK>
+0x7877	0x846F	# <CJK>
+0x7878	0x53F6	# <CJK>
+0x7879	0x90C1	# <CJK>
+0x787A	0x79A6	# <CJK>
+0x787B	0x7C72	# <CJK>
+0x787C	0x613F	# <CJK>
+0x787D	0x4E91	# <CJK>
+0x787E	0x9AD2	# <CJK>
+0x7921	0x75C7	# <CJK>
+0x7922	0x96BB	# <CJK>
+0x7923	0x53EA	# <CJK>
+0x7924	0x7DFB	# <CJK>
+0x7925	0x88FD	# <CJK>
+0x7926	0x79CD	# <CJK>
+0x7927	0x7843	# <CJK>
+0x7928	0x7B51	# <CJK>
+0x7929	0x51C6	# <CJK>
diff --git a/tools/encoding/gb1988.txt b/tools/encoding/gb1988.txt
new file mode 100644
index 0000000..800cd68
--- /dev/null
+++ b/tools/encoding/gb1988.txt
@@ -0,0 +1,158 @@
+0x20	0x0020	# SPACE
+0x21	0x0021	# EXCLAMATION MARK
+0x22	0x0022	# QUOTATION MARK
+0x23	0x0023	# NUMBER SIGN
+0x24	0x00A5	# YUAN SIGN
+0x25	0x0025	# PERCENT SIGN
+0x26	0x0026	# AMPERSAND
+0x27	0x0027	# APOSTROPHE
+0x28	0x0028	# LEFT PARENTHESIS
+0x29	0x0029	# RIGHT PARENTHESIS
+0x2A	0x002A	# ASTERISK
+0x2B	0x002B	# PLUS SIGN
+0x2C	0x002C	# COMMA
+0x2D	0x002D	# HYPHEN-MINUS
+0x2E	0x002E	# FULL STOP
+0x2F	0x002F	# SOLIDUS
+0x30	0x0030	# DIGIT ZERO
+0x31	0x0031	# DIGIT ONE
+0x32	0x0032	# DIGIT TWO
+0x33	0x0033	# DIGIT THREE
+0x34	0x0034	# DIGIT FOUR
+0x35	0x0035	# DIGIT FIVE
+0x36	0x0036	# DIGIT SIX
+0x37	0x0037	# DIGIT SEVEN
+0x38	0x0038	# DIGIT EIGHT
+0x39	0x0039	# DIGIT NINE
+0x3A	0x003A	# COLON
+0x3B	0x003B	# SEMICOLON
+0x3C	0x003C	# LESS-THAN SIGN
+0x3D	0x003D	# EQUALS SIGN
+0x3E	0x003E	# GREATER-THAN SIGN
+0x3F	0x003F	# QUESTION MARK
+0x40	0x0040	# COMMERCIAL AT
+0x41	0x0041	# LATIN CAPITAL LETTER A
+0x42	0x0042	# LATIN CAPITAL LETTER B
+0x43	0x0043	# LATIN CAPITAL LETTER C
+0x44	0x0044	# LATIN CAPITAL LETTER D
+0x45	0x0045	# LATIN CAPITAL LETTER E
+0x46	0x0046	# LATIN CAPITAL LETTER F
+0x47	0x0047	# LATIN CAPITAL LETTER G
+0x48	0x0048	# LATIN CAPITAL LETTER H
+0x49	0x0049	# LATIN CAPITAL LETTER I
+0x4A	0x004A	# LATIN CAPITAL LETTER J
+0x4B	0x004B	# LATIN CAPITAL LETTER K
+0x4C	0x004C	# LATIN CAPITAL LETTER L
+0x4D	0x004D	# LATIN CAPITAL LETTER M
+0x4E	0x004E	# LATIN CAPITAL LETTER N
+0x4F	0x004F	# LATIN CAPITAL LETTER O
+0x50	0x0050	# LATIN CAPITAL LETTER P
+0x51	0x0051	# LATIN CAPITAL LETTER Q
+0x52	0x0052	# LATIN CAPITAL LETTER R
+0x53	0x0053	# LATIN CAPITAL LETTER S
+0x54	0x0054	# LATIN CAPITAL LETTER T
+0x55	0x0055	# LATIN CAPITAL LETTER U
+0x56	0x0056	# LATIN CAPITAL LETTER V
+0x57	0x0057	# LATIN CAPITAL LETTER W
+0x58	0x0058	# LATIN CAPITAL LETTER X
+0x59	0x0059	# LATIN CAPITAL LETTER Y
+0x5A	0x005A	# LATIN CAPITAL LETTER Z
+0x5B	0x005B	# LEFT SQUARE BRACKET
+0x5C	0x005C	#REVERSE SOLIDUS (rendered as Halfwidth Yen Sign)
+0x5D	0x005D	# RIGHT SQUARE BRACKET
+0x5E	0x005E	# CIRCUMFLEX ACCENT
+0x5F	0x005F	# LOW LINE
+0x60	0x0060	# GRAVE ACCENT
+0x61	0x0061	# LATIN SMALL LETTER A
+0x62	0x0062	# LATIN SMALL LETTER B
+0x63	0x0063	# LATIN SMALL LETTER C
+0x64	0x0064	# LATIN SMALL LETTER D
+0x65	0x0065	# LATIN SMALL LETTER E
+0x66	0x0066	# LATIN SMALL LETTER F
+0x67	0x0067	# LATIN SMALL LETTER G
+0x68	0x0068	# LATIN SMALL LETTER H
+0x69	0x0069	# LATIN SMALL LETTER I
+0x6A	0x006A	# LATIN SMALL LETTER J
+0x6B	0x006B	# LATIN SMALL LETTER K
+0x6C	0x006C	# LATIN SMALL LETTER L
+0x6D	0x006D	# LATIN SMALL LETTER M
+0x6E	0x006E	# LATIN SMALL LETTER N
+0x6F	0x006F	# LATIN SMALL LETTER O
+0x70	0x0070	# LATIN SMALL LETTER P
+0x71	0x0071	# LATIN SMALL LETTER Q
+0x72	0x0072	# LATIN SMALL LETTER R
+0x73	0x0073	# LATIN SMALL LETTER S
+0x74	0x0074	# LATIN SMALL LETTER T
+0x75	0x0075	# LATIN SMALL LETTER U
+0x76	0x0076	# LATIN SMALL LETTER V
+0x77	0x0077	# LATIN SMALL LETTER W
+0x78	0x0078	# LATIN SMALL LETTER X
+0x79	0x0079	# LATIN SMALL LETTER Y
+0x7A	0x007A	# LATIN SMALL LETTER Z
+0x7B	0x007B	# LEFT CURLY BRACKET
+0x7C	0x007C	# VERTICAL LINE
+0x7D	0x007D	# RIGHT CURLY BRACKET
+0x7E	0x203E	# OVERLINE
+0xA1	0xFF61	# HALFWIDTH IDEOGRAPHIC FULL STOP
+0xA2	0xFF62	# HALFWIDTH LEFT CORNER BRACKET
+0xA3	0xFF63	# HALFWIDTH RIGHT CORNER BRACKET
+0xA4	0xFF64	# HALFWIDTH IDEOGRAPHIC COMMA
+0xA5	0xFF65	# HALFWIDTH KATAKANA MIDDLE DOT
+0xA6	0xFF66	# HALFWIDTH KATAKANA LETTER WO
+0xA7	0xFF67	# HALFWIDTH KATAKANA LETTER SMALL A
+0xA8	0xFF68	# HALFWIDTH KATAKANA LETTER SMALL I
+0xA9	0xFF69	# HALFWIDTH KATAKANA LETTER SMALL U
+0xAA	0xFF6A	# HALFWIDTH KATAKANA LETTER SMALL E
+0xAB	0xFF6B	# HALFWIDTH KATAKANA LETTER SMALL O
+0xAC	0xFF6C	# HALFWIDTH KATAKANA LETTER SMALL YA
+0xAD	0xFF6D	# HALFWIDTH KATAKANA LETTER SMALL YU
+0xAE	0xFF6E	# HALFWIDTH KATAKANA LETTER SMALL YO
+0xAF	0xFF6F	# HALFWIDTH KATAKANA LETTER SMALL TU
+0xB0	0xFF70	# HALFWIDTH KATAKANA-HIRAGANA PROLONGED SOUND MARK
+0xB1	0xFF71	# HALFWIDTH KATAKANA LETTER A
+0xB2	0xFF72	# HALFWIDTH KATAKANA LETTER I
+0xB3	0xFF73	# HALFWIDTH KATAKANA LETTER U
+0xB4	0xFF74	# HALFWIDTH KATAKANA LETTER E
+0xB5	0xFF75	# HALFWIDTH KATAKANA LETTER O
+0xB6	0xFF76	# HALFWIDTH KATAKANA LETTER KA
+0xB7	0xFF77	# HALFWIDTH KATAKANA LETTER KI
+0xB8	0xFF78	# HALFWIDTH KATAKANA LETTER KU
+0xB9	0xFF79	# HALFWIDTH KATAKANA LETTER KE
+0xBA	0xFF7A	# HALFWIDTH KATAKANA LETTER KO
+0xBB	0xFF7B	# HALFWIDTH KATAKANA LETTER SA
+0xBC	0xFF7C	# HALFWIDTH KATAKANA LETTER SI
+0xBD	0xFF7D	# HALFWIDTH KATAKANA LETTER SU
+0xBE	0xFF7E	# HALFWIDTH KATAKANA LETTER SE
+0xBF	0xFF7F	# HALFWIDTH KATAKANA LETTER SO
+0xC0	0xFF80	# HALFWIDTH KATAKANA LETTER TA
+0xC1	0xFF81	# HALFWIDTH KATAKANA LETTER TI
+0xC2	0xFF82	# HALFWIDTH KATAKANA LETTER TU
+0xC3	0xFF83	# HALFWIDTH KATAKANA LETTER TE
+0xC4	0xFF84	# HALFWIDTH KATAKANA LETTER TO
+0xC5	0xFF85	# HALFWIDTH KATAKANA LETTER NA
+0xC6	0xFF86	# HALFWIDTH KATAKANA LETTER NI
+0xC7	0xFF87	# HALFWIDTH KATAKANA LETTER NU
+0xC8	0xFF88	# HALFWIDTH KATAKANA LETTER NE
+0xC9	0xFF89	# HALFWIDTH KATAKANA LETTER NO
+0xCA	0xFF8A	# HALFWIDTH KATAKANA LETTER HA
+0xCB	0xFF8B	# HALFWIDTH KATAKANA LETTER HI
+0xCC	0xFF8C	# HALFWIDTH KATAKANA LETTER HU
+0xCD	0xFF8D	# HALFWIDTH KATAKANA LETTER HE
+0xCE	0xFF8E	# HALFWIDTH KATAKANA LETTER HO
+0xCF	0xFF8F	# HALFWIDTH KATAKANA LETTER MA
+0xD0	0xFF90	# HALFWIDTH KATAKANA LETTER MI
+0xD1	0xFF91	# HALFWIDTH KATAKANA LETTER MU
+0xD2	0xFF92	# HALFWIDTH KATAKANA LETTER ME
+0xD3	0xFF93	# HALFWIDTH KATAKANA LETTER MO
+0xD4	0xFF94	# HALFWIDTH KATAKANA LETTER YA
+0xD5	0xFF95	# HALFWIDTH KATAKANA LETTER YU
+0xD6	0xFF96	# HALFWIDTH KATAKANA LETTER YO
+0xD7	0xFF97	# HALFWIDTH KATAKANA LETTER RA
+0xD8	0xFF98	# HALFWIDTH KATAKANA LETTER RI
+0xD9	0xFF99	# HALFWIDTH KATAKANA LETTER RU
+0xDA	0xFF9A	# HALFWIDTH KATAKANA LETTER RE
+0xDB	0xFF9B	# HALFWIDTH KATAKANA LETTER RO
+0xDC	0xFF9C	# HALFWIDTH KATAKANA LETTER WA
+0xDD	0xFF9D	# HALFWIDTH KATAKANA LETTER N
+0xDE	0xFF9E	# HALFWIDTH KATAKANA VOICED SOUND MARK
+0xDF	0xFF9F	# HALFWIDTH KATAKANA SEMI-VOICED SOUND MARK
diff --git a/tools/encoding/gb2312.txt b/tools/encoding/gb2312.txt
new file mode 100644
index 0000000..fc9f6f0
--- /dev/null
+++ b/tools/encoding/gb2312.txt
@@ -0,0 +1,7513 @@
+# gb2312.txt --
+#
+#	GB2312 to Unicode table (modified)
+#
+# Copyright (c) 1998-1999 by Scriptics Corporation.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+# NOTE: this table has been modified to include the 7-bit ASCII
+# characters that are allowed in GB2312 files.
+#
+#
+#	Name:             GB2312-80 to Unicode table (complete, hex format)
+#	Unicode version:  1.1
+#	Table version:    0.0d2
+#	Table format:     Format A
+#	Date:             6 December 1993
+#	Author:           Glenn Adams <glenn@metis.com>
+#                     John H. Jenkins <John_Jenkins@taligent.com>
+#
+#	Copyright (c) 1991-1994 Unicode, Inc.  All Rights reserved.
+#
+#	This file is provided as-is by Unicode, Inc. (The Unicode Consortium).
+#	No claims are made as to fitness for any particular purpose.  No
+#	warranties of any kind are expressed or implied.  The recipient
+#	agrees to determine applicability of information provided.  If this
+#	file has been provided on magnetic media by Unicode, Inc., the sole
+#	remedy for any claim will be exchange of defective media within 90
+#	days of receipt.
+#
+#	Recipient is granted the right to make copies in any form for
+#	internal distribution and to freely use the information supplied
+#	in the creation of products supporting Unicode.  Unicode, Inc.
+#	specifically excludes the right to re-distribute this file directly
+#	to third parties or other organizations whether for profit or not.
+#
+#	General notes:
+#
+#	This table contains the data Metis and Taligent currently have on how
+#       GB2312-80 characters map into Unicode.
+#
+#	Format:  Three tab-separated columns
+#		 Column #1 is the GB2312 code (in hex as 0xXXXX)
+#		 Column #2 is the Unicode (in hex as 0xXXXX)
+#		 Column #3 the Unicode name (follows a comment sign, '#')
+#					The official names for Unicode characters U+4E00
+#					to U+9FA5, inclusive, is "CJK UNIFIED IDEOGRAPH-XXXX",
+#					where XXXX is the code point.  Including all these
+#					names in this file increases its size substantially
+#					and needlessly.  The token "<CJK>" is used for the
+#					name of these characters.  If necessary, it can be
+#					expanded algorithmically by a parser or editor.
+#
+#	The entries are in GB2312 order
+#
+#	The following algorithms can be used to change the hex form
+#		of GB2312 to other standard forms:
+#
+#		To change hex to EUC form, add 0x8080
+#		To change hex to kuten form, first subtract 0x2020.  Then
+#			the high and low bytes correspond to the ku and ten of
+#			the kuten form.  For example, 0x2121 -> 0x0101 -> 0101;
+#			0x777E -> 0x575E -> 8794
+#
+#	Any comments or problems, contact <John_Jenkins@taligent.com>
+#
+#
+0x2121	0x3000	# IDEOGRAPHIC SPACE
+0x2122	0x3001	# IDEOGRAPHIC COMMA
+0x2123	0x3002	# IDEOGRAPHIC FULL STOP
+0x2124	0x30FB	# KATAKANA MIDDLE DOT
+0x2125	0x02C9	# MODIFIER LETTER MACRON (Mandarin Chinese first tone)
+0x2126	0x02C7	# CARON (Mandarin Chinese third tone)
+0x2127	0x00A8	# DIAERESIS
+0x2128	0x3003	# DITTO MARK
+0x2129	0x3005	# IDEOGRAPHIC ITERATION MARK
+0x212A	0x2015	# HORIZONTAL BAR
+0x212B	0xFF5E	# FULLWIDTH TILDE
+0x212C	0x2225	# PARALLEL TO
+0x212D	0x2026	# HORIZONTAL ELLIPSIS
+0x212E	0x2018	# LEFT SINGLE QUOTATION MARK
+0x212F	0x2019	# RIGHT SINGLE QUOTATION MARK
+0x2130	0x201C	# LEFT DOUBLE QUOTATION MARK
+0x2131	0x201D	# RIGHT DOUBLE QUOTATION MARK
+0x2132	0x3014	# LEFT TORTOISE SHELL BRACKET
+0x2133	0x3015	# RIGHT TORTOISE SHELL BRACKET
+0x2134	0x3008	# LEFT ANGLE BRACKET
+0x2135	0x3009	# RIGHT ANGLE BRACKET
+0x2136	0x300A	# LEFT DOUBLE ANGLE BRACKET
+0x2137	0x300B	# RIGHT DOUBLE ANGLE BRACKET
+0x2138	0x300C	# LEFT CORNER BRACKET
+0x2139	0x300D	# RIGHT CORNER BRACKET
+0x213A	0x300E	# LEFT WHITE CORNER BRACKET
+0x213B	0x300F	# RIGHT WHITE CORNER BRACKET
+0x213C	0x3016	# LEFT WHITE LENTICULAR BRACKET
+0x213D	0x3017	# RIGHT WHITE LENTICULAR BRACKET
+0x213E	0x3010	# LEFT BLACK LENTICULAR BRACKET
+0x213F	0x3011	# RIGHT BLACK LENTICULAR BRACKET
+0x2140	0x00B1	# PLUS-MINUS SIGN
+0x2141	0x00D7	# MULTIPLICATION SIGN
+0x2142	0x00F7	# DIVISION SIGN
+0x2143	0x2236	# RATIO
+0x2144	0x2227	# LOGICAL AND
+0x2145	0x2228	# LOGICAL OR
+0x2146	0x2211	# N-ARY SUMMATION
+0x2147	0x220F	# N-ARY PRODUCT
+0x2148	0x222A	# UNION
+0x2149	0x2229	# INTERSECTION
+0x214A	0x2208	# ELEMENT OF
+0x214B	0x2237	# PROPORTION
+0x214C	0x221A	# SQUARE ROOT
+0x214D	0x22A5	# UP TACK
+0x214E	0x2225	# PARALLEL TO
+0x214F	0x2220	# ANGLE
+0x2150	0x2312	# ARC
+0x2151	0x2299	# CIRCLED DOT OPERATOR
+0x2152	0x222B	# INTEGRAL
+0x2153	0x222E	# CONTOUR INTEGRAL
+0x2154	0x2261	# IDENTICAL TO
+0x2155	0x224C	# ALL EQUAL TO
+0x2156	0x2248	# ALMOST EQUAL TO
+0x2157	0x223D	# REVERSED TILDE
+0x2158	0x221D	# PROPORTIONAL TO
+0x2159	0x2260	# NOT EQUAL TO
+0x215A	0x226E	# NOT LESS-THAN
+0x215B	0x226F	# NOT GREATER-THAN
+0x215C	0x2264	# LESS-THAN OR EQUAL TO
+0x215D	0x2265	# GREATER-THAN OR EQUAL TO
+0x215E	0x221E	# INFINITY
+0x215F	0x2235	# BECAUSE
+0x2160	0x2234	# THEREFORE
+0x2161	0x2642	# MALE SIGN
+0x2162	0x2640	# FEMALE SIGN
+0x2163	0x00B0	# DEGREE SIGN
+0x2164	0x2032	# PRIME
+0x2165	0x2033	# DOUBLE PRIME
+0x2166	0x2103	# DEGREE CELSIUS
+0x2167	0xFF04	# FULLWIDTH DOLLAR SIGN
+0x2168	0x00A4	# CURRENCY SIGN
+0x2169	0xFFE0	# FULLWIDTH CENT SIGN
+0x216A	0xFFE1	# FULLWIDTH POUND SIGN
+0x216B	0x2030	# PER MILLE SIGN
+0x216C	0x00A7	# SECTION SIGN
+0x216D	0x2116	# NUMERO SIGN
+0x216E	0x2606	# WHITE STAR
+0x216F	0x2605	# BLACK STAR
+0x2170	0x25CB	# WHITE CIRCLE
+0x2171	0x25CF	# BLACK CIRCLE
+0x2172	0x25CE	# BULLSEYE
+0x2173	0x25C7	# WHITE DIAMOND
+0x2174	0x25C6	# BLACK DIAMOND
+0x2175	0x25A1	# WHITE SQUARE
+0x2176	0x25A0	# BLACK SQUARE
+0x2177	0x25B3	# WHITE UP-POINTING TRIANGLE
+0x2178	0x25B2	# BLACK UP-POINTING TRIANGLE
+0x2179	0x203B	# REFERENCE MARK
+0x217A	0x2192	# RIGHTWARDS ARROW
+0x217B	0x2190	# LEFTWARDS ARROW
+0x217C	0x2191	# UPWARDS ARROW
+0x217D	0x2193	# DOWNWARDS ARROW
+0x217E	0x3013	# GETA MARK
+0x2231	0x2488	# DIGIT ONE FULL STOP
+0x2232	0x2489	# DIGIT TWO FULL STOP
+0x2233	0x248A	# DIGIT THREE FULL STOP
+0x2234	0x248B	# DIGIT FOUR FULL STOP
+0x2235	0x248C	# DIGIT FIVE FULL STOP
+0x2236	0x248D	# DIGIT SIX FULL STOP
+0x2237	0x248E	# DIGIT SEVEN FULL STOP
+0x2238	0x248F	# DIGIT EIGHT FULL STOP
+0x2239	0x2490	# DIGIT NINE FULL STOP
+0x223A	0x2491	# NUMBER TEN FULL STOP
+0x223B	0x2492	# NUMBER ELEVEN FULL STOP
+0x223C	0x2493	# NUMBER TWELVE FULL STOP
+0x223D	0x2494	# NUMBER THIRTEEN FULL STOP
+0x223E	0x2495	# NUMBER FOURTEEN FULL STOP
+0x223F	0x2496	# NUMBER FIFTEEN FULL STOP
+0x2240	0x2497	# NUMBER SIXTEEN FULL STOP
+0x2241	0x2498	# NUMBER SEVENTEEN FULL STOP
+0x2242	0x2499	# NUMBER EIGHTEEN FULL STOP
+0x2243	0x249A	# NUMBER NINETEEN FULL STOP
+0x2244	0x249B	# NUMBER TWENTY FULL STOP
+0x2245	0x2474	# PARENTHESIZED DIGIT ONE
+0x2246	0x2475	# PARENTHESIZED DIGIT TWO
+0x2247	0x2476	# PARENTHESIZED DIGIT THREE
+0x2248	0x2477	# PARENTHESIZED DIGIT FOUR
+0x2249	0x2478	# PARENTHESIZED DIGIT FIVE
+0x224A	0x2479	# PARENTHESIZED DIGIT SIX
+0x224B	0x247A	# PARENTHESIZED DIGIT SEVEN
+0x224C	0x247B	# PARENTHESIZED DIGIT EIGHT
+0x224D	0x247C	# PARENTHESIZED DIGIT NINE
+0x224E	0x247D	# PARENTHESIZED NUMBER TEN
+0x224F	0x247E	# PARENTHESIZED NUMBER ELEVEN
+0x2250	0x247F	# PARENTHESIZED NUMBER TWELVE
+0x2251	0x2480	# PARENTHESIZED NUMBER THIRTEEN
+0x2252	0x2481	# PARENTHESIZED NUMBER FOURTEEN
+0x2253	0x2482	# PARENTHESIZED NUMBER FIFTEEN
+0x2254	0x2483	# PARENTHESIZED NUMBER SIXTEEN
+0x2255	0x2484	# PARENTHESIZED NUMBER SEVENTEEN
+0x2256	0x2485	# PARENTHESIZED NUMBER EIGHTEEN
+0x2257	0x2486	# PARENTHESIZED NUMBER NINETEEN
+0x2258	0x2487	# PARENTHESIZED NUMBER TWENTY
+0x2259	0x2460	# CIRCLED DIGIT ONE
+0x225A	0x2461	# CIRCLED DIGIT TWO
+0x225B	0x2462	# CIRCLED DIGIT THREE
+0x225C	0x2463	# CIRCLED DIGIT FOUR
+0x225D	0x2464	# CIRCLED DIGIT FIVE
+0x225E	0x2465	# CIRCLED DIGIT SIX
+0x225F	0x2466	# CIRCLED DIGIT SEVEN
+0x2260	0x2467	# CIRCLED DIGIT EIGHT
+0x2261	0x2468	# CIRCLED DIGIT NINE
+0x2262	0x2469	# CIRCLED NUMBER TEN
+0x2265	0x3220	# PARENTHESIZED IDEOGRAPH ONE
+0x2266	0x3221	# PARENTHESIZED IDEOGRAPH TWO
+0x2267	0x3222	# PARENTHESIZED IDEOGRAPH THREE
+0x2268	0x3223	# PARENTHESIZED IDEOGRAPH FOUR
+0x2269	0x3224	# PARENTHESIZED IDEOGRAPH FIVE
+0x226A	0x3225	# PARENTHESIZED IDEOGRAPH SIX
+0x226B	0x3226	# PARENTHESIZED IDEOGRAPH SEVEN
+0x226C	0x3227	# PARENTHESIZED IDEOGRAPH EIGHT
+0x226D	0x3228	# PARENTHESIZED IDEOGRAPH NINE
+0x226E	0x3229	# PARENTHESIZED IDEOGRAPH TEN
+0x2271	0x2160	# ROMAN NUMERAL ONE
+0x2272	0x2161	# ROMAN NUMERAL TWO
+0x2273	0x2162	# ROMAN NUMERAL THREE
+0x2274	0x2163	# ROMAN NUMERAL FOUR
+0x2275	0x2164	# ROMAN NUMERAL FIVE
+0x2276	0x2165	# ROMAN NUMERAL SIX
+0x2277	0x2166	# ROMAN NUMERAL SEVEN
+0x2278	0x2167	# ROMAN NUMERAL EIGHT
+0x2279	0x2168	# ROMAN NUMERAL NINE
+0x227A	0x2169	# ROMAN NUMERAL TEN
+0x227B	0x216A	# ROMAN NUMERAL ELEVEN
+0x227C	0x216B	# ROMAN NUMERAL TWELVE
+0x2321	0xFF01	# FULLWIDTH EXCLAMATION MARK
+0x2322	0xFF02	# FULLWIDTH QUOTATION MARK
+0x2323	0xFF03	# FULLWIDTH NUMBER SIGN
+0x2324	0xFFE5	# FULLWIDTH YEN SIGN
+0x2325	0xFF05	# FULLWIDTH PERCENT SIGN
+0x2326	0xFF06	# FULLWIDTH AMPERSAND
+0x2327	0xFF07	# FULLWIDTH APOSTROPHE
+0x2328	0xFF08	# FULLWIDTH LEFT PARENTHESIS
+0x2329	0xFF09	# FULLWIDTH RIGHT PARENTHESIS
+0x232A	0xFF0A	# FULLWIDTH ASTERISK
+0x232B	0xFF0B	# FULLWIDTH PLUS SIGN
+0x232C	0xFF0C	# FULLWIDTH COMMA
+0x232D	0xFF0D	# FULLWIDTH HYPHEN-MINUS
+0x232E	0xFF0E	# FULLWIDTH FULL STOP
+0x232F	0xFF0F	# FULLWIDTH SOLIDUS
+0x2330	0xFF10	# FULLWIDTH DIGIT ZERO
+0x2331	0xFF11	# FULLWIDTH DIGIT ONE
+0x2332	0xFF12	# FULLWIDTH DIGIT TWO
+0x2333	0xFF13	# FULLWIDTH DIGIT THREE
+0x2334	0xFF14	# FULLWIDTH DIGIT FOUR
+0x2335	0xFF15	# FULLWIDTH DIGIT FIVE
+0x2336	0xFF16	# FULLWIDTH DIGIT SIX
+0x2337	0xFF17	# FULLWIDTH DIGIT SEVEN
+0x2338	0xFF18	# FULLWIDTH DIGIT EIGHT
+0x2339	0xFF19	# FULLWIDTH DIGIT NINE
+0x233A	0xFF1A	# FULLWIDTH COLON
+0x233B	0xFF1B	# FULLWIDTH SEMICOLON
+0x233C	0xFF1C	# FULLWIDTH LESS-THAN SIGN
+0x233D	0xFF1D	# FULLWIDTH EQUALS SIGN
+0x233E	0xFF1E	# FULLWIDTH GREATER-THAN SIGN
+0x233F	0xFF1F	# FULLWIDTH QUESTION MARK
+0x2340	0xFF20	# FULLWIDTH COMMERCIAL AT
+0x2341	0xFF21	# FULLWIDTH LATIN CAPITAL LETTER A
+0x2342	0xFF22	# FULLWIDTH LATIN CAPITAL LETTER B
+0x2343	0xFF23	# FULLWIDTH LATIN CAPITAL LETTER C
+0x2344	0xFF24	# FULLWIDTH LATIN CAPITAL LETTER D
+0x2345	0xFF25	# FULLWIDTH LATIN CAPITAL LETTER E
+0x2346	0xFF26	# FULLWIDTH LATIN CAPITAL LETTER F
+0x2347	0xFF27	# FULLWIDTH LATIN CAPITAL LETTER G
+0x2348	0xFF28	# FULLWIDTH LATIN CAPITAL LETTER H
+0x2349	0xFF29	# FULLWIDTH LATIN CAPITAL LETTER I
+0x234A	0xFF2A	# FULLWIDTH LATIN CAPITAL LETTER J
+0x234B	0xFF2B	# FULLWIDTH LATIN CAPITAL LETTER K
+0x234C	0xFF2C	# FULLWIDTH LATIN CAPITAL LETTER L
+0x234D	0xFF2D	# FULLWIDTH LATIN CAPITAL LETTER M
+0x234E	0xFF2E	# FULLWIDTH LATIN CAPITAL LETTER N
+0x234F	0xFF2F	# FULLWIDTH LATIN CAPITAL LETTER O
+0x2350	0xFF30	# FULLWIDTH LATIN CAPITAL LETTER P
+0x2351	0xFF31	# FULLWIDTH LATIN CAPITAL LETTER Q
+0x2352	0xFF32	# FULLWIDTH LATIN CAPITAL LETTER R
+0x2353	0xFF33	# FULLWIDTH LATIN CAPITAL LETTER S
+0x2354	0xFF34	# FULLWIDTH LATIN CAPITAL LETTER T
+0x2355	0xFF35	# FULLWIDTH LATIN CAPITAL LETTER U
+0x2356	0xFF36	# FULLWIDTH LATIN CAPITAL LETTER V
+0x2357	0xFF37	# FULLWIDTH LATIN CAPITAL LETTER W
+0x2358	0xFF38	# FULLWIDTH LATIN CAPITAL LETTER X
+0x2359	0xFF39	# FULLWIDTH LATIN CAPITAL LETTER Y
+0x235A	0xFF3A	# FULLWIDTH LATIN CAPITAL LETTER Z
+0x235B	0xFF3B	# FULLWIDTH LEFT SQUARE BRACKET
+0x235C	0xFF3C	# FULLWIDTH REVERSE SOLIDUS
+0x235D	0xFF3D	# FULLWIDTH RIGHT SQUARE BRACKET
+0x235E	0xFF3E	# FULLWIDTH CIRCUMFLEX ACCENT
+0x235F	0xFF3F	# FULLWIDTH LOW LINE
+0x2360	0xFF40	# FULLWIDTH GRAVE ACCENT
+0x2361	0xFF41	# FULLWIDTH LATIN SMALL LETTER A
+0x2362	0xFF42	# FULLWIDTH LATIN SMALL LETTER B
+0x2363	0xFF43	# FULLWIDTH LATIN SMALL LETTER C
+0x2364	0xFF44	# FULLWIDTH LATIN SMALL LETTER D
+0x2365	0xFF45	# FULLWIDTH LATIN SMALL LETTER E
+0x2366	0xFF46	# FULLWIDTH LATIN SMALL LETTER F
+0x2367	0xFF47	# FULLWIDTH LATIN SMALL LETTER G
+0x2368	0xFF48	# FULLWIDTH LATIN SMALL LETTER H
+0x2369	0xFF49	# FULLWIDTH LATIN SMALL LETTER I
+0x236A	0xFF4A	# FULLWIDTH LATIN SMALL LETTER J
+0x236B	0xFF4B	# FULLWIDTH LATIN SMALL LETTER K
+0x236C	0xFF4C	# FULLWIDTH LATIN SMALL LETTER L
+0x236D	0xFF4D	# FULLWIDTH LATIN SMALL LETTER M
+0x236E	0xFF4E	# FULLWIDTH LATIN SMALL LETTER N
+0x236F	0xFF4F	# FULLWIDTH LATIN SMALL LETTER O
+0x2370	0xFF50	# FULLWIDTH LATIN SMALL LETTER P
+0x2371	0xFF51	# FULLWIDTH LATIN SMALL LETTER Q
+0x2372	0xFF52	# FULLWIDTH LATIN SMALL LETTER R
+0x2373	0xFF53	# FULLWIDTH LATIN SMALL LETTER S
+0x2374	0xFF54	# FULLWIDTH LATIN SMALL LETTER T
+0x2375	0xFF55	# FULLWIDTH LATIN SMALL LETTER U
+0x2376	0xFF56	# FULLWIDTH LATIN SMALL LETTER V
+0x2377	0xFF57	# FULLWIDTH LATIN SMALL LETTER W
+0x2378	0xFF58	# FULLWIDTH LATIN SMALL LETTER X
+0x2379	0xFF59	# FULLWIDTH LATIN SMALL LETTER Y
+0x237A	0xFF5A	# FULLWIDTH LATIN SMALL LETTER Z
+0x237B	0xFF5B	# FULLWIDTH LEFT CURLY BRACKET
+0x237C	0xFF5C	# FULLWIDTH VERTICAL LINE
+0x237D	0xFF5D	# FULLWIDTH RIGHT CURLY BRACKET
+0x237E	0xFFE3	# FULLWIDTH MACRON
+0x2421	0x3041	# HIRAGANA LETTER SMALL A
+0x2422	0x3042	# HIRAGANA LETTER A
+0x2423	0x3043	# HIRAGANA LETTER SMALL I
+0x2424	0x3044	# HIRAGANA LETTER I
+0x2425	0x3045	# HIRAGANA LETTER SMALL U
+0x2426	0x3046	# HIRAGANA LETTER U
+0x2427	0x3047	# HIRAGANA LETTER SMALL E
+0x2428	0x3048	# HIRAGANA LETTER E
+0x2429	0x3049	# HIRAGANA LETTER SMALL O
+0x242A	0x304A	# HIRAGANA LETTER O
+0x242B	0x304B	# HIRAGANA LETTER KA
+0x242C	0x304C	# HIRAGANA LETTER GA
+0x242D	0x304D	# HIRAGANA LETTER KI
+0x242E	0x304E	# HIRAGANA LETTER GI
+0x242F	0x304F	# HIRAGANA LETTER KU
+0x2430	0x3050	# HIRAGANA LETTER GU
+0x2431	0x3051	# HIRAGANA LETTER KE
+0x2432	0x3052	# HIRAGANA LETTER GE
+0x2433	0x3053	# HIRAGANA LETTER KO
+0x2434	0x3054	# HIRAGANA LETTER GO
+0x2435	0x3055	# HIRAGANA LETTER SA
+0x2436	0x3056	# HIRAGANA LETTER ZA
+0x2437	0x3057	# HIRAGANA LETTER SI
+0x2438	0x3058	# HIRAGANA LETTER ZI
+0x2439	0x3059	# HIRAGANA LETTER SU
+0x243A	0x305A	# HIRAGANA LETTER ZU
+0x243B	0x305B	# HIRAGANA LETTER SE
+0x243C	0x305C	# HIRAGANA LETTER ZE
+0x243D	0x305D	# HIRAGANA LETTER SO
+0x243E	0x305E	# HIRAGANA LETTER ZO
+0x243F	0x305F	# HIRAGANA LETTER TA
+0x2440	0x3060	# HIRAGANA LETTER DA
+0x2441	0x3061	# HIRAGANA LETTER TI
+0x2442	0x3062	# HIRAGANA LETTER DI
+0x2443	0x3063	# HIRAGANA LETTER SMALL TU
+0x2444	0x3064	# HIRAGANA LETTER TU
+0x2445	0x3065	# HIRAGANA LETTER DU
+0x2446	0x3066	# HIRAGANA LETTER TE
+0x2447	0x3067	# HIRAGANA LETTER DE
+0x2448	0x3068	# HIRAGANA LETTER TO
+0x2449	0x3069	# HIRAGANA LETTER DO
+0x244A	0x306A	# HIRAGANA LETTER NA
+0x244B	0x306B	# HIRAGANA LETTER NI
+0x244C	0x306C	# HIRAGANA LETTER NU
+0x244D	0x306D	# HIRAGANA LETTER NE
+0x244E	0x306E	# HIRAGANA LETTER NO
+0x244F	0x306F	# HIRAGANA LETTER HA
+0x2450	0x3070	# HIRAGANA LETTER BA
+0x2451	0x3071	# HIRAGANA LETTER PA
+0x2452	0x3072	# HIRAGANA LETTER HI
+0x2453	0x3073	# HIRAGANA LETTER BI
+0x2454	0x3074	# HIRAGANA LETTER PI
+0x2455	0x3075	# HIRAGANA LETTER HU
+0x2456	0x3076	# HIRAGANA LETTER BU
+0x2457	0x3077	# HIRAGANA LETTER PU
+0x2458	0x3078	# HIRAGANA LETTER HE
+0x2459	0x3079	# HIRAGANA LETTER BE
+0x245A	0x307A	# HIRAGANA LETTER PE
+0x245B	0x307B	# HIRAGANA LETTER HO
+0x245C	0x307C	# HIRAGANA LETTER BO
+0x245D	0x307D	# HIRAGANA LETTER PO
+0x245E	0x307E	# HIRAGANA LETTER MA
+0x245F	0x307F	# HIRAGANA LETTER MI
+0x2460	0x3080	# HIRAGANA LETTER MU
+0x2461	0x3081	# HIRAGANA LETTER ME
+0x2462	0x3082	# HIRAGANA LETTER MO
+0x2463	0x3083	# HIRAGANA LETTER SMALL YA
+0x2464	0x3084	# HIRAGANA LETTER YA
+0x2465	0x3085	# HIRAGANA LETTER SMALL YU
+0x2466	0x3086	# HIRAGANA LETTER YU
+0x2467	0x3087	# HIRAGANA LETTER SMALL YO
+0x2468	0x3088	# HIRAGANA LETTER YO
+0x2469	0x3089	# HIRAGANA LETTER RA
+0x246A	0x308A	# HIRAGANA LETTER RI
+0x246B	0x308B	# HIRAGANA LETTER RU
+0x246C	0x308C	# HIRAGANA LETTER RE
+0x246D	0x308D	# HIRAGANA LETTER RO
+0x246E	0x308E	# HIRAGANA LETTER SMALL WA
+0x246F	0x308F	# HIRAGANA LETTER WA
+0x2470	0x3090	# HIRAGANA LETTER WI
+0x2471	0x3091	# HIRAGANA LETTER WE
+0x2472	0x3092	# HIRAGANA LETTER WO
+0x2473	0x3093	# HIRAGANA LETTER N
+0x2521	0x30A1	# KATAKANA LETTER SMALL A
+0x2522	0x30A2	# KATAKANA LETTER A
+0x2523	0x30A3	# KATAKANA LETTER SMALL I
+0x2524	0x30A4	# KATAKANA LETTER I
+0x2525	0x30A5	# KATAKANA LETTER SMALL U
+0x2526	0x30A6	# KATAKANA LETTER U
+0x2527	0x30A7	# KATAKANA LETTER SMALL E
+0x2528	0x30A8	# KATAKANA LETTER E
+0x2529	0x30A9	# KATAKANA LETTER SMALL O
+0x252A	0x30AA	# KATAKANA LETTER O
+0x252B	0x30AB	# KATAKANA LETTER KA
+0x252C	0x30AC	# KATAKANA LETTER GA
+0x252D	0x30AD	# KATAKANA LETTER KI
+0x252E	0x30AE	# KATAKANA LETTER GI
+0x252F	0x30AF	# KATAKANA LETTER KU
+0x2530	0x30B0	# KATAKANA LETTER GU
+0x2531	0x30B1	# KATAKANA LETTER KE
+0x2532	0x30B2	# KATAKANA LETTER GE
+0x2533	0x30B3	# KATAKANA LETTER KO
+0x2534	0x30B4	# KATAKANA LETTER GO
+0x2535	0x30B5	# KATAKANA LETTER SA
+0x2536	0x30B6	# KATAKANA LETTER ZA
+0x2537	0x30B7	# KATAKANA LETTER SI
+0x2538	0x30B8	# KATAKANA LETTER ZI
+0x2539	0x30B9	# KATAKANA LETTER SU
+0x253A	0x30BA	# KATAKANA LETTER ZU
+0x253B	0x30BB	# KATAKANA LETTER SE
+0x253C	0x30BC	# KATAKANA LETTER ZE
+0x253D	0x30BD	# KATAKANA LETTER SO
+0x253E	0x30BE	# KATAKANA LETTER ZO
+0x253F	0x30BF	# KATAKANA LETTER TA
+0x2540	0x30C0	# KATAKANA LETTER DA
+0x2541	0x30C1	# KATAKANA LETTER TI
+0x2542	0x30C2	# KATAKANA LETTER DI
+0x2543	0x30C3	# KATAKANA LETTER SMALL TU
+0x2544	0x30C4	# KATAKANA LETTER TU
+0x2545	0x30C5	# KATAKANA LETTER DU
+0x2546	0x30C6	# KATAKANA LETTER TE
+0x2547	0x30C7	# KATAKANA LETTER DE
+0x2548	0x30C8	# KATAKANA LETTER TO
+0x2549	0x30C9	# KATAKANA LETTER DO
+0x254A	0x30CA	# KATAKANA LETTER NA
+0x254B	0x30CB	# KATAKANA LETTER NI
+0x254C	0x30CC	# KATAKANA LETTER NU
+0x254D	0x30CD	# KATAKANA LETTER NE
+0x254E	0x30CE	# KATAKANA LETTER NO
+0x254F	0x30CF	# KATAKANA LETTER HA
+0x2550	0x30D0	# KATAKANA LETTER BA
+0x2551	0x30D1	# KATAKANA LETTER PA
+0x2552	0x30D2	# KATAKANA LETTER HI
+0x2553	0x30D3	# KATAKANA LETTER BI
+0x2554	0x30D4	# KATAKANA LETTER PI
+0x2555	0x30D5	# KATAKANA LETTER HU
+0x2556	0x30D6	# KATAKANA LETTER BU
+0x2557	0x30D7	# KATAKANA LETTER PU
+0x2558	0x30D8	# KATAKANA LETTER HE
+0x2559	0x30D9	# KATAKANA LETTER BE
+0x255A	0x30DA	# KATAKANA LETTER PE
+0x255B	0x30DB	# KATAKANA LETTER HO
+0x255C	0x30DC	# KATAKANA LETTER BO
+0x255D	0x30DD	# KATAKANA LETTER PO
+0x255E	0x30DE	# KATAKANA LETTER MA
+0x255F	0x30DF	# KATAKANA LETTER MI
+0x2560	0x30E0	# KATAKANA LETTER MU
+0x2561	0x30E1	# KATAKANA LETTER ME
+0x2562	0x30E2	# KATAKANA LETTER MO
+0x2563	0x30E3	# KATAKANA LETTER SMALL YA
+0x2564	0x30E4	# KATAKANA LETTER YA
+0x2565	0x30E5	# KATAKANA LETTER SMALL YU
+0x2566	0x30E6	# KATAKANA LETTER YU
+0x2567	0x30E7	# KATAKANA LETTER SMALL YO
+0x2568	0x30E8	# KATAKANA LETTER YO
+0x2569	0x30E9	# KATAKANA LETTER RA
+0x256A	0x30EA	# KATAKANA LETTER RI
+0x256B	0x30EB	# KATAKANA LETTER RU
+0x256C	0x30EC	# KATAKANA LETTER RE
+0x256D	0x30ED	# KATAKANA LETTER RO
+0x256E	0x30EE	# KATAKANA LETTER SMALL WA
+0x256F	0x30EF	# KATAKANA LETTER WA
+0x2570	0x30F0	# KATAKANA LETTER WI
+0x2571	0x30F1	# KATAKANA LETTER WE
+0x2572	0x30F2	# KATAKANA LETTER WO
+0x2573	0x30F3	# KATAKANA LETTER N
+0x2574	0x30F4	# KATAKANA LETTER VU
+0x2575	0x30F5	# KATAKANA LETTER SMALL KA
+0x2576	0x30F6	# KATAKANA LETTER SMALL KE
+0x2621	0x0391	# GREEK CAPITAL LETTER ALPHA
+0x2622	0x0392	# GREEK CAPITAL LETTER BETA
+0x2623	0x0393	# GREEK CAPITAL LETTER GAMMA
+0x2624	0x0394	# GREEK CAPITAL LETTER DELTA
+0x2625	0x0395	# GREEK CAPITAL LETTER EPSILON
+0x2626	0x0396	# GREEK CAPITAL LETTER ZETA
+0x2627	0x0397	# GREEK CAPITAL LETTER ETA
+0x2628	0x0398	# GREEK CAPITAL LETTER THETA
+0x2629	0x0399	# GREEK CAPITAL LETTER IOTA
+0x262A	0x039A	# GREEK CAPITAL LETTER KAPPA
+0x262B	0x039B	# GREEK CAPITAL LETTER LAMDA
+0x262C	0x039C	# GREEK CAPITAL LETTER MU
+0x262D	0x039D	# GREEK CAPITAL LETTER NU
+0x262E	0x039E	# GREEK CAPITAL LETTER XI
+0x262F	0x039F	# GREEK CAPITAL LETTER OMICRON
+0x2630	0x03A0	# GREEK CAPITAL LETTER PI
+0x2631	0x03A1	# GREEK CAPITAL LETTER RHO
+0x2632	0x03A3	# GREEK CAPITAL LETTER SIGMA
+0x2633	0x03A4	# GREEK CAPITAL LETTER TAU
+0x2634	0x03A5	# GREEK CAPITAL LETTER UPSILON
+0x2635	0x03A6	# GREEK CAPITAL LETTER PHI
+0x2636	0x03A7	# GREEK CAPITAL LETTER CHI
+0x2637	0x03A8	# GREEK CAPITAL LETTER PSI
+0x2638	0x03A9	# GREEK CAPITAL LETTER OMEGA
+0x2641	0x03B1	# GREEK SMALL LETTER ALPHA
+0x2642	0x03B2	# GREEK SMALL LETTER BETA
+0x2643	0x03B3	# GREEK SMALL LETTER GAMMA
+0x2644	0x03B4	# GREEK SMALL LETTER DELTA
+0x2645	0x03B5	# GREEK SMALL LETTER EPSILON
+0x2646	0x03B6	# GREEK SMALL LETTER ZETA
+0x2647	0x03B7	# GREEK SMALL LETTER ETA
+0x2648	0x03B8	# GREEK SMALL LETTER THETA
+0x2649	0x03B9	# GREEK SMALL LETTER IOTA
+0x264A	0x03BA	# GREEK SMALL LETTER KAPPA
+0x264B	0x03BB	# GREEK SMALL LETTER LAMDA
+0x264C	0x03BC	# GREEK SMALL LETTER MU
+0x264D	0x03BD	# GREEK SMALL LETTER NU
+0x264E	0x03BE	# GREEK SMALL LETTER XI
+0x264F	0x03BF	# GREEK SMALL LETTER OMICRON
+0x2650	0x03C0	# GREEK SMALL LETTER PI
+0x2651	0x03C1	# GREEK SMALL LETTER RHO
+0x2652	0x03C3	# GREEK SMALL LETTER SIGMA
+0x2653	0x03C4	# GREEK SMALL LETTER TAU
+0x2654	0x03C5	# GREEK SMALL LETTER UPSILON
+0x2655	0x03C6	# GREEK SMALL LETTER PHI
+0x2656	0x03C7	# GREEK SMALL LETTER CHI
+0x2657	0x03C8	# GREEK SMALL LETTER PSI
+0x2658	0x03C9	# GREEK SMALL LETTER OMEGA
+0x2721	0x0410	# CYRILLIC CAPITAL LETTER A
+0x2722	0x0411	# CYRILLIC CAPITAL LETTER BE
+0x2723	0x0412	# CYRILLIC CAPITAL LETTER VE
+0x2724	0x0413	# CYRILLIC CAPITAL LETTER GHE
+0x2725	0x0414	# CYRILLIC CAPITAL LETTER DE
+0x2726	0x0415	# CYRILLIC CAPITAL LETTER IE
+0x2727	0x0401	# CYRILLIC CAPITAL LETTER IO
+0x2728	0x0416	# CYRILLIC CAPITAL LETTER ZHE
+0x2729	0x0417	# CYRILLIC CAPITAL LETTER ZE
+0x272A	0x0418	# CYRILLIC CAPITAL LETTER I
+0x272B	0x0419	# CYRILLIC CAPITAL LETTER SHORT I
+0x272C	0x041A	# CYRILLIC CAPITAL LETTER KA
+0x272D	0x041B	# CYRILLIC CAPITAL LETTER EL
+0x272E	0x041C	# CYRILLIC CAPITAL LETTER EM
+0x272F	0x041D	# CYRILLIC CAPITAL LETTER EN
+0x2730	0x041E	# CYRILLIC CAPITAL LETTER O
+0x2731	0x041F	# CYRILLIC CAPITAL LETTER PE
+0x2732	0x0420	# CYRILLIC CAPITAL LETTER ER
+0x2733	0x0421	# CYRILLIC CAPITAL LETTER ES
+0x2734	0x0422	# CYRILLIC CAPITAL LETTER TE
+0x2735	0x0423	# CYRILLIC CAPITAL LETTER U
+0x2736	0x0424	# CYRILLIC CAPITAL LETTER EF
+0x2737	0x0425	# CYRILLIC CAPITAL LETTER HA
+0x2738	0x0426	# CYRILLIC CAPITAL LETTER TSE
+0x2739	0x0427	# CYRILLIC CAPITAL LETTER CHE
+0x273A	0x0428	# CYRILLIC CAPITAL LETTER SHA
+0x273B	0x0429	# CYRILLIC CAPITAL LETTER SHCHA
+0x273C	0x042A	# CYRILLIC CAPITAL LETTER HARD SIGN
+0x273D	0x042B	# CYRILLIC CAPITAL LETTER YERU
+0x273E	0x042C	# CYRILLIC CAPITAL LETTER SOFT SIGN
+0x273F	0x042D	# CYRILLIC CAPITAL LETTER E
+0x2740	0x042E	# CYRILLIC CAPITAL LETTER YU
+0x2741	0x042F	# CYRILLIC CAPITAL LETTER YA
+0x2751	0x0430	# CYRILLIC SMALL LETTER A
+0x2752	0x0431	# CYRILLIC SMALL LETTER BE
+0x2753	0x0432	# CYRILLIC SMALL LETTER VE
+0x2754	0x0433	# CYRILLIC SMALL LETTER GHE
+0x2755	0x0434	# CYRILLIC SMALL LETTER DE
+0x2756	0x0435	# CYRILLIC SMALL LETTER IE
+0x2757	0x0451	# CYRILLIC SMALL LETTER IO
+0x2758	0x0436	# CYRILLIC SMALL LETTER ZHE
+0x2759	0x0437	# CYRILLIC SMALL LETTER ZE
+0x275A	0x0438	# CYRILLIC SMALL LETTER I
+0x275B	0x0439	# CYRILLIC SMALL LETTER SHORT I
+0x275C	0x043A	# CYRILLIC SMALL LETTER KA
+0x275D	0x043B	# CYRILLIC SMALL LETTER EL
+0x275E	0x043C	# CYRILLIC SMALL LETTER EM
+0x275F	0x043D	# CYRILLIC SMALL LETTER EN
+0x2760	0x043E	# CYRILLIC SMALL LETTER O
+0x2761	0x043F	# CYRILLIC SMALL LETTER PE
+0x2762	0x0440	# CYRILLIC SMALL LETTER ER
+0x2763	0x0441	# CYRILLIC SMALL LETTER ES
+0x2764	0x0442	# CYRILLIC SMALL LETTER TE
+0x2765	0x0443	# CYRILLIC SMALL LETTER U
+0x2766	0x0444	# CYRILLIC SMALL LETTER EF
+0x2767	0x0445	# CYRILLIC SMALL LETTER HA
+0x2768	0x0446	# CYRILLIC SMALL LETTER TSE
+0x2769	0x0447	# CYRILLIC SMALL LETTER CHE
+0x276A	0x0448	# CYRILLIC SMALL LETTER SHA
+0x276B	0x0449	# CYRILLIC SMALL LETTER SHCHA
+0x276C	0x044A	# CYRILLIC SMALL LETTER HARD SIGN
+0x276D	0x044B	# CYRILLIC SMALL LETTER YERU
+0x276E	0x044C	# CYRILLIC SMALL LETTER SOFT SIGN
+0x276F	0x044D	# CYRILLIC SMALL LETTER E
+0x2770	0x044E	# CYRILLIC SMALL LETTER YU
+0x2771	0x044F	# CYRILLIC SMALL LETTER YA
+0x2821	0x0101	# LATIN SMALL LETTER A WITH MACRON
+0x2822	0x00E1	# LATIN SMALL LETTER A WITH ACUTE
+0x2823	0x01CE	# LATIN SMALL LETTER A WITH CARON
+0x2824	0x00E0	# LATIN SMALL LETTER A WITH GRAVE
+0x2825	0x0113	# LATIN SMALL LETTER E WITH MACRON
+0x2826	0x00E9	# LATIN SMALL LETTER E WITH ACUTE
+0x2827	0x011B	# LATIN SMALL LETTER E WITH CARON
+0x2828	0x00E8	# LATIN SMALL LETTER E WITH GRAVE
+0x2829	0x012B	# LATIN SMALL LETTER I WITH MACRON
+0x282A	0x00ED	# LATIN SMALL LETTER I WITH ACUTE
+0x282B	0x01D0	# LATIN SMALL LETTER I WITH CARON
+0x282C	0x00EC	# LATIN SMALL LETTER I WITH GRAVE
+0x282D	0x014D	# LATIN SMALL LETTER O WITH MACRON
+0x282E	0x00F3	# LATIN SMALL LETTER O WITH ACUTE
+0x282F	0x01D2	# LATIN SMALL LETTER O WITH CARON
+0x2830	0x00F2	# LATIN SMALL LETTER O WITH GRAVE
+0x2831	0x016B	# LATIN SMALL LETTER U WITH MACRON
+0x2832	0x00FA	# LATIN SMALL LETTER U WITH ACUTE
+0x2833	0x01D4	# LATIN SMALL LETTER U WITH CARON
+0x2834	0x00F9	# LATIN SMALL LETTER U WITH GRAVE
+0x2835	0x01D6	# LATIN SMALL LETTER U WITH DIAERESIS AND MACRON
+0x2836	0x01D8	# LATIN SMALL LETTER U WITH DIAERESIS AND ACUTE
+0x2837	0x01DA	# LATIN SMALL LETTER U WITH DIAERESIS AND CARON
+0x2838	0x01DC	# LATIN SMALL LETTER U WITH DIAERESIS AND GRAVE
+0x2839	0x00FC	# LATIN SMALL LETTER U WITH DIAERESIS
+0x283A	0x00EA	# LATIN SMALL LETTER E WITH CIRCUMFLEX
+0x2845	0x3105	# BOPOMOFO LETTER B
+0x2846	0x3106	# BOPOMOFO LETTER P
+0x2847	0x3107	# BOPOMOFO LETTER M
+0x2848	0x3108	# BOPOMOFO LETTER F
+0x2849	0x3109	# BOPOMOFO LETTER D
+0x284A	0x310A	# BOPOMOFO LETTER T
+0x284B	0x310B	# BOPOMOFO LETTER N
+0x284C	0x310C	# BOPOMOFO LETTER L
+0x284D	0x310D	# BOPOMOFO LETTER G
+0x284E	0x310E	# BOPOMOFO LETTER K
+0x284F	0x310F	# BOPOMOFO LETTER H
+0x2850	0x3110	# BOPOMOFO LETTER J
+0x2851	0x3111	# BOPOMOFO LETTER Q
+0x2852	0x3112	# BOPOMOFO LETTER X
+0x2853	0x3113	# BOPOMOFO LETTER ZH
+0x2854	0x3114	# BOPOMOFO LETTER CH
+0x2855	0x3115	# BOPOMOFO LETTER SH
+0x2856	0x3116	# BOPOMOFO LETTER R
+0x2857	0x3117	# BOPOMOFO LETTER Z
+0x2858	0x3118	# BOPOMOFO LETTER C
+0x2859	0x3119	# BOPOMOFO LETTER S
+0x285A	0x311A	# BOPOMOFO LETTER A
+0x285B	0x311B	# BOPOMOFO LETTER O
+0x285C	0x311C	# BOPOMOFO LETTER E
+0x285D	0x311D	# BOPOMOFO LETTER EH
+0x285E	0x311E	# BOPOMOFO LETTER AI
+0x285F	0x311F	# BOPOMOFO LETTER EI
+0x2860	0x3120	# BOPOMOFO LETTER AU
+0x2861	0x3121	# BOPOMOFO LETTER OU
+0x2862	0x3122	# BOPOMOFO LETTER AN
+0x2863	0x3123	# BOPOMOFO LETTER EN
+0x2864	0x3124	# BOPOMOFO LETTER ANG
+0x2865	0x3125	# BOPOMOFO LETTER ENG
+0x2866	0x3126	# BOPOMOFO LETTER ER
+0x2867	0x3127	# BOPOMOFO LETTER I
+0x2868	0x3128	# BOPOMOFO LETTER U
+0x2869	0x3129	# BOPOMOFO LETTER IU
+0x2924	0x2500	# BOX DRAWINGS LIGHT HORIZONTAL
+0x2925	0x2501	# BOX DRAWINGS HEAVY HORIZONTAL
+0x2926	0x2502	# BOX DRAWINGS LIGHT VERTICAL
+0x2927	0x2503	# BOX DRAWINGS HEAVY VERTICAL
+0x2928	0x2504	# BOX DRAWINGS LIGHT TRIPLE DASH HORIZONTAL
+0x2929	0x2505	# BOX DRAWINGS HEAVY TRIPLE DASH HORIZONTAL
+0x292A	0x2506	# BOX DRAWINGS LIGHT TRIPLE DASH VERTICAL
+0x292B	0x2507	# BOX DRAWINGS HEAVY TRIPLE DASH VERTICAL
+0x292C	0x2508	# BOX DRAWINGS LIGHT QUADRUPLE DASH HORIZONTAL
+0x292D	0x2509	# BOX DRAWINGS HEAVY QUADRUPLE DASH HORIZONTAL
+0x292E	0x250A	# BOX DRAWINGS LIGHT QUADRUPLE DASH VERTICAL
+0x292F	0x250B	# BOX DRAWINGS HEAVY QUADRUPLE DASH VERTICAL
+0x2930	0x250C	# BOX DRAWINGS LIGHT DOWN AND RIGHT
+0x2931	0x250D	# BOX DRAWINGS DOWN LIGHT AND RIGHT HEAVY
+0x2932	0x250E	# BOX DRAWINGS DOWN HEAVY AND RIGHT LIGHT
+0x2933	0x250F	# BOX DRAWINGS HEAVY DOWN AND RIGHT
+0x2934	0x2510	# BOX DRAWINGS LIGHT DOWN AND LEFT
+0x2935	0x2511	# BOX DRAWINGS DOWN LIGHT AND LEFT HEAVY
+0x2936	0x2512	# BOX DRAWINGS DOWN HEAVY AND LEFT LIGHT
+0x2937	0x2513	# BOX DRAWINGS HEAVY DOWN AND LEFT
+0x2938	0x2514	# BOX DRAWINGS LIGHT UP AND RIGHT
+0x2939	0x2515	# BOX DRAWINGS UP LIGHT AND RIGHT HEAVY
+0x293A	0x2516	# BOX DRAWINGS UP HEAVY AND RIGHT LIGHT
+0x293B	0x2517	# BOX DRAWINGS HEAVY UP AND RIGHT
+0x293C	0x2518	# BOX DRAWINGS LIGHT UP AND LEFT
+0x293D	0x2519	# BOX DRAWINGS UP LIGHT AND LEFT HEAVY
+0x293E	0x251A	# BOX DRAWINGS UP HEAVY AND LEFT LIGHT
+0x293F	0x251B	# BOX DRAWINGS HEAVY UP AND LEFT
+0x2940	0x251C	# BOX DRAWINGS LIGHT VERTICAL AND RIGHT
+0x2941	0x251D	# BOX DRAWINGS VERTICAL LIGHT AND RIGHT HEAVY
+0x2942	0x251E	# BOX DRAWINGS UP HEAVY AND RIGHT DOWN LIGHT
+0x2943	0x251F	# BOX DRAWINGS DOWN HEAVY AND RIGHT UP LIGHT
+0x2944	0x2520	# BOX DRAWINGS VERTICAL HEAVY AND RIGHT LIGHT
+0x2945	0x2521	# BOX DRAWINGS DOWN LIGHT AND RIGHT UP HEAVY
+0x2946	0x2522	# BOX DRAWINGS UP LIGHT AND RIGHT DOWN HEAVY
+0x2947	0x2523	# BOX DRAWINGS HEAVY VERTICAL AND RIGHT
+0x2948	0x2524	# BOX DRAWINGS LIGHT VERTICAL AND LEFT
+0x2949	0x2525	# BOX DRAWINGS VERTICAL LIGHT AND LEFT HEAVY
+0x294A	0x2526	# BOX DRAWINGS UP HEAVY AND LEFT DOWN LIGHT
+0x294B	0x2527	# BOX DRAWINGS DOWN HEAVY AND LEFT UP LIGHT
+0x294C	0x2528	# BOX DRAWINGS VERTICAL HEAVY AND LEFT LIGHT
+0x294D	0x2529	# BOX DRAWINGS DOWN LIGHT AND LEFT UP HEAVY
+0x294E	0x252A	# BOX DRAWINGS UP LIGHT AND LEFT DOWN HEAVY
+0x294F	0x252B	# BOX DRAWINGS HEAVY VERTICAL AND LEFT
+0x2950	0x252C	# BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
+0x2951	0x252D	# BOX DRAWINGS LEFT HEAVY AND RIGHT DOWN LIGHT
+0x2952	0x252E	# BOX DRAWINGS RIGHT HEAVY AND LEFT DOWN LIGHT
+0x2953	0x252F	# BOX DRAWINGS DOWN LIGHT AND HORIZONTAL HEAVY
+0x2954	0x2530	# BOX DRAWINGS DOWN HEAVY AND HORIZONTAL LIGHT
+0x2955	0x2531	# BOX DRAWINGS RIGHT LIGHT AND LEFT DOWN HEAVY
+0x2956	0x2532	# BOX DRAWINGS LEFT LIGHT AND RIGHT DOWN HEAVY
+0x2957	0x2533	# BOX DRAWINGS HEAVY DOWN AND HORIZONTAL
+0x2958	0x2534	# BOX DRAWINGS LIGHT UP AND HORIZONTAL
+0x2959	0x2535	# BOX DRAWINGS LEFT HEAVY AND RIGHT UP LIGHT
+0x295A	0x2536	# BOX DRAWINGS RIGHT HEAVY AND LEFT UP LIGHT
+0x295B	0x2537	# BOX DRAWINGS UP LIGHT AND HORIZONTAL HEAVY
+0x295C	0x2538	# BOX DRAWINGS UP HEAVY AND HORIZONTAL LIGHT
+0x295D	0x2539	# BOX DRAWINGS RIGHT LIGHT AND LEFT UP HEAVY
+0x295E	0x253A	# BOX DRAWINGS LEFT LIGHT AND RIGHT UP HEAVY
+0x295F	0x253B	# BOX DRAWINGS HEAVY UP AND HORIZONTAL
+0x2960	0x253C	# BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
+0x2961	0x253D	# BOX DRAWINGS LEFT HEAVY AND RIGHT VERTICAL LIGHT
+0x2962	0x253E	# BOX DRAWINGS RIGHT HEAVY AND LEFT VERTICAL LIGHT
+0x2963	0x253F	# BOX DRAWINGS VERTICAL LIGHT AND HORIZONTAL HEAVY
+0x2964	0x2540	# BOX DRAWINGS UP HEAVY AND DOWN HORIZONTAL LIGHT
+0x2965	0x2541	# BOX DRAWINGS DOWN HEAVY AND UP HORIZONTAL LIGHT
+0x2966	0x2542	# BOX DRAWINGS VERTICAL HEAVY AND HORIZONTAL LIGHT
+0x2967	0x2543	# BOX DRAWINGS LEFT UP HEAVY AND RIGHT DOWN LIGHT
+0x2968	0x2544	# BOX DRAWINGS RIGHT UP HEAVY AND LEFT DOWN LIGHT
+0x2969	0x2545	# BOX DRAWINGS LEFT DOWN HEAVY AND RIGHT UP LIGHT
+0x296A	0x2546	# BOX DRAWINGS RIGHT DOWN HEAVY AND LEFT UP LIGHT
+0x296B	0x2547	# BOX DRAWINGS DOWN LIGHT AND UP HORIZONTAL HEAVY
+0x296C	0x2548	# BOX DRAWINGS UP LIGHT AND DOWN HORIZONTAL HEAVY
+0x296D	0x2549	# BOX DRAWINGS RIGHT LIGHT AND LEFT VERTICAL HEAVY
+0x296E	0x254A	# BOX DRAWINGS LEFT LIGHT AND RIGHT VERTICAL HEAVY
+0x296F	0x254B	# BOX DRAWINGS HEAVY VERTICAL AND HORIZONTAL
+0x3021	0x554A	# <CJK>
+0x3022	0x963F	# <CJK>
+0x3023	0x57C3	# <CJK>
+0x3024	0x6328	# <CJK>
+0x3025	0x54CE	# <CJK>
+0x3026	0x5509	# <CJK>
+0x3027	0x54C0	# <CJK>
+0x3028	0x7691	# <CJK>
+0x3029	0x764C	# <CJK>
+0x302A	0x853C	# <CJK>
+0x302B	0x77EE	# <CJK>
+0x302C	0x827E	# <CJK>
+0x302D	0x788D	# <CJK>
+0x302E	0x7231	# <CJK>
+0x302F	0x9698	# <CJK>
+0x3030	0x978D	# <CJK>
+0x3031	0x6C28	# <CJK>
+0x3032	0x5B89	# <CJK>
+0x3033	0x4FFA	# <CJK>
+0x3034	0x6309	# <CJK>
+0x3035	0x6697	# <CJK>
+0x3036	0x5CB8	# <CJK>
+0x3037	0x80FA	# <CJK>
+0x3038	0x6848	# <CJK>
+0x3039	0x80AE	# <CJK>
+0x303A	0x6602	# <CJK>
+0x303B	0x76CE	# <CJK>
+0x303C	0x51F9	# <CJK>
+0x303D	0x6556	# <CJK>
+0x303E	0x71AC	# <CJK>
+0x303F	0x7FF1	# <CJK>
+0x3040	0x8884	# <CJK>
+0x3041	0x50B2	# <CJK>
+0x3042	0x5965	# <CJK>
+0x3043	0x61CA	# <CJK>
+0x3044	0x6FB3	# <CJK>
+0x3045	0x82AD	# <CJK>
+0x3046	0x634C	# <CJK>
+0x3047	0x6252	# <CJK>
+0x3048	0x53ED	# <CJK>
+0x3049	0x5427	# <CJK>
+0x304A	0x7B06	# <CJK>
+0x304B	0x516B	# <CJK>
+0x304C	0x75A4	# <CJK>
+0x304D	0x5DF4	# <CJK>
+0x304E	0x62D4	# <CJK>
+0x304F	0x8DCB	# <CJK>
+0x3050	0x9776	# <CJK>
+0x3051	0x628A	# <CJK>
+0x3052	0x8019	# <CJK>
+0x3053	0x575D	# <CJK>
+0x3054	0x9738	# <CJK>
+0x3055	0x7F62	# <CJK>
+0x3056	0x7238	# <CJK>
+0x3057	0x767D	# <CJK>
+0x3058	0x67CF	# <CJK>
+0x3059	0x767E	# <CJK>
+0x305A	0x6446	# <CJK>
+0x305B	0x4F70	# <CJK>
+0x305C	0x8D25	# <CJK>
+0x305D	0x62DC	# <CJK>
+0x305E	0x7A17	# <CJK>
+0x305F	0x6591	# <CJK>
+0x3060	0x73ED	# <CJK>
+0x3061	0x642C	# <CJK>
+0x3062	0x6273	# <CJK>
+0x3063	0x822C	# <CJK>
+0x3064	0x9881	# <CJK>
+0x3065	0x677F	# <CJK>
+0x3066	0x7248	# <CJK>
+0x3067	0x626E	# <CJK>
+0x3068	0x62CC	# <CJK>
+0x3069	0x4F34	# <CJK>
+0x306A	0x74E3	# <CJK>
+0x306B	0x534A	# <CJK>
+0x306C	0x529E	# <CJK>
+0x306D	0x7ECA	# <CJK>
+0x306E	0x90A6	# <CJK>
+0x306F	0x5E2E	# <CJK>
+0x3070	0x6886	# <CJK>
+0x3071	0x699C	# <CJK>
+0x3072	0x8180	# <CJK>
+0x3073	0x7ED1	# <CJK>
+0x3074	0x68D2	# <CJK>
+0x3075	0x78C5	# <CJK>
+0x3076	0x868C	# <CJK>
+0x3077	0x9551	# <CJK>
+0x3078	0x508D	# <CJK>
+0x3079	0x8C24	# <CJK>
+0x307A	0x82DE	# <CJK>
+0x307B	0x80DE	# <CJK>
+0x307C	0x5305	# <CJK>
+0x307D	0x8912	# <CJK>
+0x307E	0x5265	# <CJK>
+0x3121	0x8584	# <CJK>
+0x3122	0x96F9	# <CJK>
+0x3123	0x4FDD	# <CJK>
+0x3124	0x5821	# <CJK>
+0x3125	0x9971	# <CJK>
+0x3126	0x5B9D	# <CJK>
+0x3127	0x62B1	# <CJK>
+0x3128	0x62A5	# <CJK>
+0x3129	0x66B4	# <CJK>
+0x312A	0x8C79	# <CJK>
+0x312B	0x9C8D	# <CJK>
+0x312C	0x7206	# <CJK>
+0x312D	0x676F	# <CJK>
+0x312E	0x7891	# <CJK>
+0x312F	0x60B2	# <CJK>
+0x3130	0x5351	# <CJK>
+0x3131	0x5317	# <CJK>
+0x3132	0x8F88	# <CJK>
+0x3133	0x80CC	# <CJK>
+0x3134	0x8D1D	# <CJK>
+0x3135	0x94A1	# <CJK>
+0x3136	0x500D	# <CJK>
+0x3137	0x72C8	# <CJK>
+0x3138	0x5907	# <CJK>
+0x3139	0x60EB	# <CJK>
+0x313A	0x7119	# <CJK>
+0x313B	0x88AB	# <CJK>
+0x313C	0x5954	# <CJK>
+0x313D	0x82EF	# <CJK>
+0x313E	0x672C	# <CJK>
+0x313F	0x7B28	# <CJK>
+0x3140	0x5D29	# <CJK>
+0x3141	0x7EF7	# <CJK>
+0x3142	0x752D	# <CJK>
+0x3143	0x6CF5	# <CJK>
+0x3144	0x8E66	# <CJK>
+0x3145	0x8FF8	# <CJK>
+0x3146	0x903C	# <CJK>
+0x3147	0x9F3B	# <CJK>
+0x3148	0x6BD4	# <CJK>
+0x3149	0x9119	# <CJK>
+0x314A	0x7B14	# <CJK>
+0x314B	0x5F7C	# <CJK>
+0x314C	0x78A7	# <CJK>
+0x314D	0x84D6	# <CJK>
+0x314E	0x853D	# <CJK>
+0x314F	0x6BD5	# <CJK>
+0x3150	0x6BD9	# <CJK>
+0x3151	0x6BD6	# <CJK>
+0x3152	0x5E01	# <CJK>
+0x3153	0x5E87	# <CJK>
+0x3154	0x75F9	# <CJK>
+0x3155	0x95ED	# <CJK>
+0x3156	0x655D	# <CJK>
+0x3157	0x5F0A	# <CJK>
+0x3158	0x5FC5	# <CJK>
+0x3159	0x8F9F	# <CJK>
+0x315A	0x58C1	# <CJK>
+0x315B	0x81C2	# <CJK>
+0x315C	0x907F	# <CJK>
+0x315D	0x965B	# <CJK>
+0x315E	0x97AD	# <CJK>
+0x315F	0x8FB9	# <CJK>
+0x3160	0x7F16	# <CJK>
+0x3161	0x8D2C	# <CJK>
+0x3162	0x6241	# <CJK>
+0x3163	0x4FBF	# <CJK>
+0x3164	0x53D8	# <CJK>
+0x3165	0x535E	# <CJK>
+0x3166	0x8FA8	# <CJK>
+0x3167	0x8FA9	# <CJK>
+0x3168	0x8FAB	# <CJK>
+0x3169	0x904D	# <CJK>
+0x316A	0x6807	# <CJK>
+0x316B	0x5F6A	# <CJK>
+0x316C	0x8198	# <CJK>
+0x316D	0x8868	# <CJK>
+0x316E	0x9CD6	# <CJK>
+0x316F	0x618B	# <CJK>
+0x3170	0x522B	# <CJK>
+0x3171	0x762A	# <CJK>
+0x3172	0x5F6C	# <CJK>
+0x3173	0x658C	# <CJK>
+0x3174	0x6FD2	# <CJK>
+0x3175	0x6EE8	# <CJK>
+0x3176	0x5BBE	# <CJK>
+0x3177	0x6448	# <CJK>
+0x3178	0x5175	# <CJK>
+0x3179	0x51B0	# <CJK>
+0x317A	0x67C4	# <CJK>
+0x317B	0x4E19	# <CJK>
+0x317C	0x79C9	# <CJK>
+0x317D	0x997C	# <CJK>
+0x317E	0x70B3	# <CJK>
+0x3221	0x75C5	# <CJK>
+0x3222	0x5E76	# <CJK>
+0x3223	0x73BB	# <CJK>
+0x3224	0x83E0	# <CJK>
+0x3225	0x64AD	# <CJK>
+0x3226	0x62E8	# <CJK>
+0x3227	0x94B5	# <CJK>
+0x3228	0x6CE2	# <CJK>
+0x3229	0x535A	# <CJK>
+0x322A	0x52C3	# <CJK>
+0x322B	0x640F	# <CJK>
+0x322C	0x94C2	# <CJK>
+0x322D	0x7B94	# <CJK>
+0x322E	0x4F2F	# <CJK>
+0x322F	0x5E1B	# <CJK>
+0x3230	0x8236	# <CJK>
+0x3231	0x8116	# <CJK>
+0x3232	0x818A	# <CJK>
+0x3233	0x6E24	# <CJK>
+0x3234	0x6CCA	# <CJK>
+0x3235	0x9A73	# <CJK>
+0x3236	0x6355	# <CJK>
+0x3237	0x535C	# <CJK>
+0x3238	0x54FA	# <CJK>
+0x3239	0x8865	# <CJK>
+0x323A	0x57E0	# <CJK>
+0x323B	0x4E0D	# <CJK>
+0x323C	0x5E03	# <CJK>
+0x323D	0x6B65	# <CJK>
+0x323E	0x7C3F	# <CJK>
+0x323F	0x90E8	# <CJK>
+0x3240	0x6016	# <CJK>
+0x3241	0x64E6	# <CJK>
+0x3242	0x731C	# <CJK>
+0x3243	0x88C1	# <CJK>
+0x3244	0x6750	# <CJK>
+0x3245	0x624D	# <CJK>
+0x3246	0x8D22	# <CJK>
+0x3247	0x776C	# <CJK>
+0x3248	0x8E29	# <CJK>
+0x3249	0x91C7	# <CJK>
+0x324A	0x5F69	# <CJK>
+0x324B	0x83DC	# <CJK>
+0x324C	0x8521	# <CJK>
+0x324D	0x9910	# <CJK>
+0x324E	0x53C2	# <CJK>
+0x324F	0x8695	# <CJK>
+0x3250	0x6B8B	# <CJK>
+0x3251	0x60ED	# <CJK>
+0x3252	0x60E8	# <CJK>
+0x3253	0x707F	# <CJK>
+0x3254	0x82CD	# <CJK>
+0x3255	0x8231	# <CJK>
+0x3256	0x4ED3	# <CJK>
+0x3257	0x6CA7	# <CJK>
+0x3258	0x85CF	# <CJK>
+0x3259	0x64CD	# <CJK>
+0x325A	0x7CD9	# <CJK>
+0x325B	0x69FD	# <CJK>
+0x325C	0x66F9	# <CJK>
+0x325D	0x8349	# <CJK>
+0x325E	0x5395	# <CJK>
+0x325F	0x7B56	# <CJK>
+0x3260	0x4FA7	# <CJK>
+0x3261	0x518C	# <CJK>
+0x3262	0x6D4B	# <CJK>
+0x3263	0x5C42	# <CJK>
+0x3264	0x8E6D	# <CJK>
+0x3265	0x63D2	# <CJK>
+0x3266	0x53C9	# <CJK>
+0x3267	0x832C	# <CJK>
+0x3268	0x8336	# <CJK>
+0x3269	0x67E5	# <CJK>
+0x326A	0x78B4	# <CJK>
+0x326B	0x643D	# <CJK>
+0x326C	0x5BDF	# <CJK>
+0x326D	0x5C94	# <CJK>
+0x326E	0x5DEE	# <CJK>
+0x326F	0x8BE7	# <CJK>
+0x3270	0x62C6	# <CJK>
+0x3271	0x67F4	# <CJK>
+0x3272	0x8C7A	# <CJK>
+0x3273	0x6400	# <CJK>
+0x3274	0x63BA	# <CJK>
+0x3275	0x8749	# <CJK>
+0x3276	0x998B	# <CJK>
+0x3277	0x8C17	# <CJK>
+0x3278	0x7F20	# <CJK>
+0x3279	0x94F2	# <CJK>
+0x327A	0x4EA7	# <CJK>
+0x327B	0x9610	# <CJK>
+0x327C	0x98A4	# <CJK>
+0x327D	0x660C	# <CJK>
+0x327E	0x7316	# <CJK>
+0x3321	0x573A	# <CJK>
+0x3322	0x5C1D	# <CJK>
+0x3323	0x5E38	# <CJK>
+0x3324	0x957F	# <CJK>
+0x3325	0x507F	# <CJK>
+0x3326	0x80A0	# <CJK>
+0x3327	0x5382	# <CJK>
+0x3328	0x655E	# <CJK>
+0x3329	0x7545	# <CJK>
+0x332A	0x5531	# <CJK>
+0x332B	0x5021	# <CJK>
+0x332C	0x8D85	# <CJK>
+0x332D	0x6284	# <CJK>
+0x332E	0x949E	# <CJK>
+0x332F	0x671D	# <CJK>
+0x3330	0x5632	# <CJK>
+0x3331	0x6F6E	# <CJK>
+0x3332	0x5DE2	# <CJK>
+0x3333	0x5435	# <CJK>
+0x3334	0x7092	# <CJK>
+0x3335	0x8F66	# <CJK>
+0x3336	0x626F	# <CJK>
+0x3337	0x64A4	# <CJK>
+0x3338	0x63A3	# <CJK>
+0x3339	0x5F7B	# <CJK>
+0x333A	0x6F88	# <CJK>
+0x333B	0x90F4	# <CJK>
+0x333C	0x81E3	# <CJK>
+0x333D	0x8FB0	# <CJK>
+0x333E	0x5C18	# <CJK>
+0x333F	0x6668	# <CJK>
+0x3340	0x5FF1	# <CJK>
+0x3341	0x6C89	# <CJK>
+0x3342	0x9648	# <CJK>
+0x3343	0x8D81	# <CJK>
+0x3344	0x886C	# <CJK>
+0x3345	0x6491	# <CJK>
+0x3346	0x79F0	# <CJK>
+0x3347	0x57CE	# <CJK>
+0x3348	0x6A59	# <CJK>
+0x3349	0x6210	# <CJK>
+0x334A	0x5448	# <CJK>
+0x334B	0x4E58	# <CJK>
+0x334C	0x7A0B	# <CJK>
+0x334D	0x60E9	# <CJK>
+0x334E	0x6F84	# <CJK>
+0x334F	0x8BDA	# <CJK>
+0x3350	0x627F	# <CJK>
+0x3351	0x901E	# <CJK>
+0x3352	0x9A8B	# <CJK>
+0x3353	0x79E4	# <CJK>
+0x3354	0x5403	# <CJK>
+0x3355	0x75F4	# <CJK>
+0x3356	0x6301	# <CJK>
+0x3357	0x5319	# <CJK>
+0x3358	0x6C60	# <CJK>
+0x3359	0x8FDF	# <CJK>
+0x335A	0x5F1B	# <CJK>
+0x335B	0x9A70	# <CJK>
+0x335C	0x803B	# <CJK>
+0x335D	0x9F7F	# <CJK>
+0x335E	0x4F88	# <CJK>
+0x335F	0x5C3A	# <CJK>
+0x3360	0x8D64	# <CJK>
+0x3361	0x7FC5	# <CJK>
+0x3362	0x65A5	# <CJK>
+0x3363	0x70BD	# <CJK>
+0x3364	0x5145	# <CJK>
+0x3365	0x51B2	# <CJK>
+0x3366	0x866B	# <CJK>
+0x3367	0x5D07	# <CJK>
+0x3368	0x5BA0	# <CJK>
+0x3369	0x62BD	# <CJK>
+0x336A	0x916C	# <CJK>
+0x336B	0x7574	# <CJK>
+0x336C	0x8E0C	# <CJK>
+0x336D	0x7A20	# <CJK>
+0x336E	0x6101	# <CJK>
+0x336F	0x7B79	# <CJK>
+0x3370	0x4EC7	# <CJK>
+0x3371	0x7EF8	# <CJK>
+0x3372	0x7785	# <CJK>
+0x3373	0x4E11	# <CJK>
+0x3374	0x81ED	# <CJK>
+0x3375	0x521D	# <CJK>
+0x3376	0x51FA	# <CJK>
+0x3377	0x6A71	# <CJK>
+0x3378	0x53A8	# <CJK>
+0x3379	0x8E87	# <CJK>
+0x337A	0x9504	# <CJK>
+0x337B	0x96CF	# <CJK>
+0x337C	0x6EC1	# <CJK>
+0x337D	0x9664	# <CJK>
+0x337E	0x695A	# <CJK>
+0x3421	0x7840	# <CJK>
+0x3422	0x50A8	# <CJK>
+0x3423	0x77D7	# <CJK>
+0x3424	0x6410	# <CJK>
+0x3425	0x89E6	# <CJK>
+0x3426	0x5904	# <CJK>
+0x3427	0x63E3	# <CJK>
+0x3428	0x5DDD	# <CJK>
+0x3429	0x7A7F	# <CJK>
+0x342A	0x693D	# <CJK>
+0x342B	0x4F20	# <CJK>
+0x342C	0x8239	# <CJK>
+0x342D	0x5598	# <CJK>
+0x342E	0x4E32	# <CJK>
+0x342F	0x75AE	# <CJK>
+0x3430	0x7A97	# <CJK>
+0x3431	0x5E62	# <CJK>
+0x3432	0x5E8A	# <CJK>
+0x3433	0x95EF	# <CJK>
+0x3434	0x521B	# <CJK>
+0x3435	0x5439	# <CJK>
+0x3436	0x708A	# <CJK>
+0x3437	0x6376	# <CJK>
+0x3438	0x9524	# <CJK>
+0x3439	0x5782	# <CJK>
+0x343A	0x6625	# <CJK>
+0x343B	0x693F	# <CJK>
+0x343C	0x9187	# <CJK>
+0x343D	0x5507	# <CJK>
+0x343E	0x6DF3	# <CJK>
+0x343F	0x7EAF	# <CJK>
+0x3440	0x8822	# <CJK>
+0x3441	0x6233	# <CJK>
+0x3442	0x7EF0	# <CJK>
+0x3443	0x75B5	# <CJK>
+0x3444	0x8328	# <CJK>
+0x3445	0x78C1	# <CJK>
+0x3446	0x96CC	# <CJK>
+0x3447	0x8F9E	# <CJK>
+0x3448	0x6148	# <CJK>
+0x3449	0x74F7	# <CJK>
+0x344A	0x8BCD	# <CJK>
+0x344B	0x6B64	# <CJK>
+0x344C	0x523A	# <CJK>
+0x344D	0x8D50	# <CJK>
+0x344E	0x6B21	# <CJK>
+0x344F	0x806A	# <CJK>
+0x3450	0x8471	# <CJK>
+0x3451	0x56F1	# <CJK>
+0x3452	0x5306	# <CJK>
+0x3453	0x4ECE	# <CJK>
+0x3454	0x4E1B	# <CJK>
+0x3455	0x51D1	# <CJK>
+0x3456	0x7C97	# <CJK>
+0x3457	0x918B	# <CJK>
+0x3458	0x7C07	# <CJK>
+0x3459	0x4FC3	# <CJK>
+0x345A	0x8E7F	# <CJK>
+0x345B	0x7BE1	# <CJK>
+0x345C	0x7A9C	# <CJK>
+0x345D	0x6467	# <CJK>
+0x345E	0x5D14	# <CJK>
+0x345F	0x50AC	# <CJK>
+0x3460	0x8106	# <CJK>
+0x3461	0x7601	# <CJK>
+0x3462	0x7CB9	# <CJK>
+0x3463	0x6DEC	# <CJK>
+0x3464	0x7FE0	# <CJK>
+0x3465	0x6751	# <CJK>
+0x3466	0x5B58	# <CJK>
+0x3467	0x5BF8	# <CJK>
+0x3468	0x78CB	# <CJK>
+0x3469	0x64AE	# <CJK>
+0x346A	0x6413	# <CJK>
+0x346B	0x63AA	# <CJK>
+0x346C	0x632B	# <CJK>
+0x346D	0x9519	# <CJK>
+0x346E	0x642D	# <CJK>
+0x346F	0x8FBE	# <CJK>
+0x3470	0x7B54	# <CJK>
+0x3471	0x7629	# <CJK>
+0x3472	0x6253	# <CJK>
+0x3473	0x5927	# <CJK>
+0x3474	0x5446	# <CJK>
+0x3475	0x6B79	# <CJK>
+0x3476	0x50A3	# <CJK>
+0x3477	0x6234	# <CJK>
+0x3478	0x5E26	# <CJK>
+0x3479	0x6B86	# <CJK>
+0x347A	0x4EE3	# <CJK>
+0x347B	0x8D37	# <CJK>
+0x347C	0x888B	# <CJK>
+0x347D	0x5F85	# <CJK>
+0x347E	0x902E	# <CJK>
+0x3521	0x6020	# <CJK>
+0x3522	0x803D	# <CJK>
+0x3523	0x62C5	# <CJK>
+0x3524	0x4E39	# <CJK>
+0x3525	0x5355	# <CJK>
+0x3526	0x90F8	# <CJK>
+0x3527	0x63B8	# <CJK>
+0x3528	0x80C6	# <CJK>
+0x3529	0x65E6	# <CJK>
+0x352A	0x6C2E	# <CJK>
+0x352B	0x4F46	# <CJK>
+0x352C	0x60EE	# <CJK>
+0x352D	0x6DE1	# <CJK>
+0x352E	0x8BDE	# <CJK>
+0x352F	0x5F39	# <CJK>
+0x3530	0x86CB	# <CJK>
+0x3531	0x5F53	# <CJK>
+0x3532	0x6321	# <CJK>
+0x3533	0x515A	# <CJK>
+0x3534	0x8361	# <CJK>
+0x3535	0x6863	# <CJK>
+0x3536	0x5200	# <CJK>
+0x3537	0x6363	# <CJK>
+0x3538	0x8E48	# <CJK>
+0x3539	0x5012	# <CJK>
+0x353A	0x5C9B	# <CJK>
+0x353B	0x7977	# <CJK>
+0x353C	0x5BFC	# <CJK>
+0x353D	0x5230	# <CJK>
+0x353E	0x7A3B	# <CJK>
+0x353F	0x60BC	# <CJK>
+0x3540	0x9053	# <CJK>
+0x3541	0x76D7	# <CJK>
+0x3542	0x5FB7	# <CJK>
+0x3543	0x5F97	# <CJK>
+0x3544	0x7684	# <CJK>
+0x3545	0x8E6C	# <CJK>
+0x3546	0x706F	# <CJK>
+0x3547	0x767B	# <CJK>
+0x3548	0x7B49	# <CJK>
+0x3549	0x77AA	# <CJK>
+0x354A	0x51F3	# <CJK>
+0x354B	0x9093	# <CJK>
+0x354C	0x5824	# <CJK>
+0x354D	0x4F4E	# <CJK>
+0x354E	0x6EF4	# <CJK>
+0x354F	0x8FEA	# <CJK>
+0x3550	0x654C	# <CJK>
+0x3551	0x7B1B	# <CJK>
+0x3552	0x72C4	# <CJK>
+0x3553	0x6DA4	# <CJK>
+0x3554	0x7FDF	# <CJK>
+0x3555	0x5AE1	# <CJK>
+0x3556	0x62B5	# <CJK>
+0x3557	0x5E95	# <CJK>
+0x3558	0x5730	# <CJK>
+0x3559	0x8482	# <CJK>
+0x355A	0x7B2C	# <CJK>
+0x355B	0x5E1D	# <CJK>
+0x355C	0x5F1F	# <CJK>
+0x355D	0x9012	# <CJK>
+0x355E	0x7F14	# <CJK>
+0x355F	0x98A0	# <CJK>
+0x3560	0x6382	# <CJK>
+0x3561	0x6EC7	# <CJK>
+0x3562	0x7898	# <CJK>
+0x3563	0x70B9	# <CJK>
+0x3564	0x5178	# <CJK>
+0x3565	0x975B	# <CJK>
+0x3566	0x57AB	# <CJK>
+0x3567	0x7535	# <CJK>
+0x3568	0x4F43	# <CJK>
+0x3569	0x7538	# <CJK>
+0x356A	0x5E97	# <CJK>
+0x356B	0x60E6	# <CJK>
+0x356C	0x5960	# <CJK>
+0x356D	0x6DC0	# <CJK>
+0x356E	0x6BBF	# <CJK>
+0x356F	0x7889	# <CJK>
+0x3570	0x53FC	# <CJK>
+0x3571	0x96D5	# <CJK>
+0x3572	0x51CB	# <CJK>
+0x3573	0x5201	# <CJK>
+0x3574	0x6389	# <CJK>
+0x3575	0x540A	# <CJK>
+0x3576	0x9493	# <CJK>
+0x3577	0x8C03	# <CJK>
+0x3578	0x8DCC	# <CJK>
+0x3579	0x7239	# <CJK>
+0x357A	0x789F	# <CJK>
+0x357B	0x8776	# <CJK>
+0x357C	0x8FED	# <CJK>
+0x357D	0x8C0D	# <CJK>
+0x357E	0x53E0	# <CJK>
+0x3621	0x4E01	# <CJK>
+0x3622	0x76EF	# <CJK>
+0x3623	0x53EE	# <CJK>
+0x3624	0x9489	# <CJK>
+0x3625	0x9876	# <CJK>
+0x3626	0x9F0E	# <CJK>
+0x3627	0x952D	# <CJK>
+0x3628	0x5B9A	# <CJK>
+0x3629	0x8BA2	# <CJK>
+0x362A	0x4E22	# <CJK>
+0x362B	0x4E1C	# <CJK>
+0x362C	0x51AC	# <CJK>
+0x362D	0x8463	# <CJK>
+0x362E	0x61C2	# <CJK>
+0x362F	0x52A8	# <CJK>
+0x3630	0x680B	# <CJK>
+0x3631	0x4F97	# <CJK>
+0x3632	0x606B	# <CJK>
+0x3633	0x51BB	# <CJK>
+0x3634	0x6D1E	# <CJK>
+0x3635	0x515C	# <CJK>
+0x3636	0x6296	# <CJK>
+0x3637	0x6597	# <CJK>
+0x3638	0x9661	# <CJK>
+0x3639	0x8C46	# <CJK>
+0x363A	0x9017	# <CJK>
+0x363B	0x75D8	# <CJK>
+0x363C	0x90FD	# <CJK>
+0x363D	0x7763	# <CJK>
+0x363E	0x6BD2	# <CJK>
+0x363F	0x728A	# <CJK>
+0x3640	0x72EC	# <CJK>
+0x3641	0x8BFB	# <CJK>
+0x3642	0x5835	# <CJK>
+0x3643	0x7779	# <CJK>
+0x3644	0x8D4C	# <CJK>
+0x3645	0x675C	# <CJK>
+0x3646	0x9540	# <CJK>
+0x3647	0x809A	# <CJK>
+0x3648	0x5EA6	# <CJK>
+0x3649	0x6E21	# <CJK>
+0x364A	0x5992	# <CJK>
+0x364B	0x7AEF	# <CJK>
+0x364C	0x77ED	# <CJK>
+0x364D	0x953B	# <CJK>
+0x364E	0x6BB5	# <CJK>
+0x364F	0x65AD	# <CJK>
+0x3650	0x7F0E	# <CJK>
+0x3651	0x5806	# <CJK>
+0x3652	0x5151	# <CJK>
+0x3653	0x961F	# <CJK>
+0x3654	0x5BF9	# <CJK>
+0x3655	0x58A9	# <CJK>
+0x3656	0x5428	# <CJK>
+0x3657	0x8E72	# <CJK>
+0x3658	0x6566	# <CJK>
+0x3659	0x987F	# <CJK>
+0x365A	0x56E4	# <CJK>
+0x365B	0x949D	# <CJK>
+0x365C	0x76FE	# <CJK>
+0x365D	0x9041	# <CJK>
+0x365E	0x6387	# <CJK>
+0x365F	0x54C6	# <CJK>
+0x3660	0x591A	# <CJK>
+0x3661	0x593A	# <CJK>
+0x3662	0x579B	# <CJK>
+0x3663	0x8EB2	# <CJK>
+0x3664	0x6735	# <CJK>
+0x3665	0x8DFA	# <CJK>
+0x3666	0x8235	# <CJK>
+0x3667	0x5241	# <CJK>
+0x3668	0x60F0	# <CJK>
+0x3669	0x5815	# <CJK>
+0x366A	0x86FE	# <CJK>
+0x366B	0x5CE8	# <CJK>
+0x366C	0x9E45	# <CJK>
+0x366D	0x4FC4	# <CJK>
+0x366E	0x989D	# <CJK>
+0x366F	0x8BB9	# <CJK>
+0x3670	0x5A25	# <CJK>
+0x3671	0x6076	# <CJK>
+0x3672	0x5384	# <CJK>
+0x3673	0x627C	# <CJK>
+0x3674	0x904F	# <CJK>
+0x3675	0x9102	# <CJK>
+0x3676	0x997F	# <CJK>
+0x3677	0x6069	# <CJK>
+0x3678	0x800C	# <CJK>
+0x3679	0x513F	# <CJK>
+0x367A	0x8033	# <CJK>
+0x367B	0x5C14	# <CJK>
+0x367C	0x9975	# <CJK>
+0x367D	0x6D31	# <CJK>
+0x367E	0x4E8C	# <CJK>
+0x3721	0x8D30	# <CJK>
+0x3722	0x53D1	# <CJK>
+0x3723	0x7F5A	# <CJK>
+0x3724	0x7B4F	# <CJK>
+0x3725	0x4F10	# <CJK>
+0x3726	0x4E4F	# <CJK>
+0x3727	0x9600	# <CJK>
+0x3728	0x6CD5	# <CJK>
+0x3729	0x73D0	# <CJK>
+0x372A	0x85E9	# <CJK>
+0x372B	0x5E06	# <CJK>
+0x372C	0x756A	# <CJK>
+0x372D	0x7FFB	# <CJK>
+0x372E	0x6A0A	# <CJK>
+0x372F	0x77FE	# <CJK>
+0x3730	0x9492	# <CJK>
+0x3731	0x7E41	# <CJK>
+0x3732	0x51E1	# <CJK>
+0x3733	0x70E6	# <CJK>
+0x3734	0x53CD	# <CJK>
+0x3735	0x8FD4	# <CJK>
+0x3736	0x8303	# <CJK>
+0x3737	0x8D29	# <CJK>
+0x3738	0x72AF	# <CJK>
+0x3739	0x996D	# <CJK>
+0x373A	0x6CDB	# <CJK>
+0x373B	0x574A	# <CJK>
+0x373C	0x82B3	# <CJK>
+0x373D	0x65B9	# <CJK>
+0x373E	0x80AA	# <CJK>
+0x373F	0x623F	# <CJK>
+0x3740	0x9632	# <CJK>
+0x3741	0x59A8	# <CJK>
+0x3742	0x4EFF	# <CJK>
+0x3743	0x8BBF	# <CJK>
+0x3744	0x7EBA	# <CJK>
+0x3745	0x653E	# <CJK>
+0x3746	0x83F2	# <CJK>
+0x3747	0x975E	# <CJK>
+0x3748	0x5561	# <CJK>
+0x3749	0x98DE	# <CJK>
+0x374A	0x80A5	# <CJK>
+0x374B	0x532A	# <CJK>
+0x374C	0x8BFD	# <CJK>
+0x374D	0x5420	# <CJK>
+0x374E	0x80BA	# <CJK>
+0x374F	0x5E9F	# <CJK>
+0x3750	0x6CB8	# <CJK>
+0x3751	0x8D39	# <CJK>
+0x3752	0x82AC	# <CJK>
+0x3753	0x915A	# <CJK>
+0x3754	0x5429	# <CJK>
+0x3755	0x6C1B	# <CJK>
+0x3756	0x5206	# <CJK>
+0x3757	0x7EB7	# <CJK>
+0x3758	0x575F	# <CJK>
+0x3759	0x711A	# <CJK>
+0x375A	0x6C7E	# <CJK>
+0x375B	0x7C89	# <CJK>
+0x375C	0x594B	# <CJK>
+0x375D	0x4EFD	# <CJK>
+0x375E	0x5FFF	# <CJK>
+0x375F	0x6124	# <CJK>
+0x3760	0x7CAA	# <CJK>
+0x3761	0x4E30	# <CJK>
+0x3762	0x5C01	# <CJK>
+0x3763	0x67AB	# <CJK>
+0x3764	0x8702	# <CJK>
+0x3765	0x5CF0	# <CJK>
+0x3766	0x950B	# <CJK>
+0x3767	0x98CE	# <CJK>
+0x3768	0x75AF	# <CJK>
+0x3769	0x70FD	# <CJK>
+0x376A	0x9022	# <CJK>
+0x376B	0x51AF	# <CJK>
+0x376C	0x7F1D	# <CJK>
+0x376D	0x8BBD	# <CJK>
+0x376E	0x5949	# <CJK>
+0x376F	0x51E4	# <CJK>
+0x3770	0x4F5B	# <CJK>
+0x3771	0x5426	# <CJK>
+0x3772	0x592B	# <CJK>
+0x3773	0x6577	# <CJK>
+0x3774	0x80A4	# <CJK>
+0x3775	0x5B75	# <CJK>
+0x3776	0x6276	# <CJK>
+0x3777	0x62C2	# <CJK>
+0x3778	0x8F90	# <CJK>
+0x3779	0x5E45	# <CJK>
+0x377A	0x6C1F	# <CJK>
+0x377B	0x7B26	# <CJK>
+0x377C	0x4F0F	# <CJK>
+0x377D	0x4FD8	# <CJK>
+0x377E	0x670D	# <CJK>
+0x3821	0x6D6E	# <CJK>
+0x3822	0x6DAA	# <CJK>
+0x3823	0x798F	# <CJK>
+0x3824	0x88B1	# <CJK>
+0x3825	0x5F17	# <CJK>
+0x3826	0x752B	# <CJK>
+0x3827	0x629A	# <CJK>
+0x3828	0x8F85	# <CJK>
+0x3829	0x4FEF	# <CJK>
+0x382A	0x91DC	# <CJK>
+0x382B	0x65A7	# <CJK>
+0x382C	0x812F	# <CJK>
+0x382D	0x8151	# <CJK>
+0x382E	0x5E9C	# <CJK>
+0x382F	0x8150	# <CJK>
+0x3830	0x8D74	# <CJK>
+0x3831	0x526F	# <CJK>
+0x3832	0x8986	# <CJK>
+0x3833	0x8D4B	# <CJK>
+0x3834	0x590D	# <CJK>
+0x3835	0x5085	# <CJK>
+0x3836	0x4ED8	# <CJK>
+0x3837	0x961C	# <CJK>
+0x3838	0x7236	# <CJK>
+0x3839	0x8179	# <CJK>
+0x383A	0x8D1F	# <CJK>
+0x383B	0x5BCC	# <CJK>
+0x383C	0x8BA3	# <CJK>
+0x383D	0x9644	# <CJK>
+0x383E	0x5987	# <CJK>
+0x383F	0x7F1A	# <CJK>
+0x3840	0x5490	# <CJK>
+0x3841	0x5676	# <CJK>
+0x3842	0x560E	# <CJK>
+0x3843	0x8BE5	# <CJK>
+0x3844	0x6539	# <CJK>
+0x3845	0x6982	# <CJK>
+0x3846	0x9499	# <CJK>
+0x3847	0x76D6	# <CJK>
+0x3848	0x6E89	# <CJK>
+0x3849	0x5E72	# <CJK>
+0x384A	0x7518	# <CJK>
+0x384B	0x6746	# <CJK>
+0x384C	0x67D1	# <CJK>
+0x384D	0x7AFF	# <CJK>
+0x384E	0x809D	# <CJK>
+0x384F	0x8D76	# <CJK>
+0x3850	0x611F	# <CJK>
+0x3851	0x79C6	# <CJK>
+0x3852	0x6562	# <CJK>
+0x3853	0x8D63	# <CJK>
+0x3854	0x5188	# <CJK>
+0x3855	0x521A	# <CJK>
+0x3856	0x94A2	# <CJK>
+0x3857	0x7F38	# <CJK>
+0x3858	0x809B	# <CJK>
+0x3859	0x7EB2	# <CJK>
+0x385A	0x5C97	# <CJK>
+0x385B	0x6E2F	# <CJK>
+0x385C	0x6760	# <CJK>
+0x385D	0x7BD9	# <CJK>
+0x385E	0x768B	# <CJK>
+0x385F	0x9AD8	# <CJK>
+0x3860	0x818F	# <CJK>
+0x3861	0x7F94	# <CJK>
+0x3862	0x7CD5	# <CJK>
+0x3863	0x641E	# <CJK>
+0x3864	0x9550	# <CJK>
+0x3865	0x7A3F	# <CJK>
+0x3866	0x544A	# <CJK>
+0x3867	0x54E5	# <CJK>
+0x3868	0x6B4C	# <CJK>
+0x3869	0x6401	# <CJK>
+0x386A	0x6208	# <CJK>
+0x386B	0x9E3D	# <CJK>
+0x386C	0x80F3	# <CJK>
+0x386D	0x7599	# <CJK>
+0x386E	0x5272	# <CJK>
+0x386F	0x9769	# <CJK>
+0x3870	0x845B	# <CJK>
+0x3871	0x683C	# <CJK>
+0x3872	0x86E4	# <CJK>
+0x3873	0x9601	# <CJK>
+0x3874	0x9694	# <CJK>
+0x3875	0x94EC	# <CJK>
+0x3876	0x4E2A	# <CJK>
+0x3877	0x5404	# <CJK>
+0x3878	0x7ED9	# <CJK>
+0x3879	0x6839	# <CJK>
+0x387A	0x8DDF	# <CJK>
+0x387B	0x8015	# <CJK>
+0x387C	0x66F4	# <CJK>
+0x387D	0x5E9A	# <CJK>
+0x387E	0x7FB9	# <CJK>
+0x3921	0x57C2	# <CJK>
+0x3922	0x803F	# <CJK>
+0x3923	0x6897	# <CJK>
+0x3924	0x5DE5	# <CJK>
+0x3925	0x653B	# <CJK>
+0x3926	0x529F	# <CJK>
+0x3927	0x606D	# <CJK>
+0x3928	0x9F9A	# <CJK>
+0x3929	0x4F9B	# <CJK>
+0x392A	0x8EAC	# <CJK>
+0x392B	0x516C	# <CJK>
+0x392C	0x5BAB	# <CJK>
+0x392D	0x5F13	# <CJK>
+0x392E	0x5DE9	# <CJK>
+0x392F	0x6C5E	# <CJK>
+0x3930	0x62F1	# <CJK>
+0x3931	0x8D21	# <CJK>
+0x3932	0x5171	# <CJK>
+0x3933	0x94A9	# <CJK>
+0x3934	0x52FE	# <CJK>
+0x3935	0x6C9F	# <CJK>
+0x3936	0x82DF	# <CJK>
+0x3937	0x72D7	# <CJK>
+0x3938	0x57A2	# <CJK>
+0x3939	0x6784	# <CJK>
+0x393A	0x8D2D	# <CJK>
+0x393B	0x591F	# <CJK>
+0x393C	0x8F9C	# <CJK>
+0x393D	0x83C7	# <CJK>
+0x393E	0x5495	# <CJK>
+0x393F	0x7B8D	# <CJK>
+0x3940	0x4F30	# <CJK>
+0x3941	0x6CBD	# <CJK>
+0x3942	0x5B64	# <CJK>
+0x3943	0x59D1	# <CJK>
+0x3944	0x9F13	# <CJK>
+0x3945	0x53E4	# <CJK>
+0x3946	0x86CA	# <CJK>
+0x3947	0x9AA8	# <CJK>
+0x3948	0x8C37	# <CJK>
+0x3949	0x80A1	# <CJK>
+0x394A	0x6545	# <CJK>
+0x394B	0x987E	# <CJK>
+0x394C	0x56FA	# <CJK>
+0x394D	0x96C7	# <CJK>
+0x394E	0x522E	# <CJK>
+0x394F	0x74DC	# <CJK>
+0x3950	0x5250	# <CJK>
+0x3951	0x5BE1	# <CJK>
+0x3952	0x6302	# <CJK>
+0x3953	0x8902	# <CJK>
+0x3954	0x4E56	# <CJK>
+0x3955	0x62D0	# <CJK>
+0x3956	0x602A	# <CJK>
+0x3957	0x68FA	# <CJK>
+0x3958	0x5173	# <CJK>
+0x3959	0x5B98	# <CJK>
+0x395A	0x51A0	# <CJK>
+0x395B	0x89C2	# <CJK>
+0x395C	0x7BA1	# <CJK>
+0x395D	0x9986	# <CJK>
+0x395E	0x7F50	# <CJK>
+0x395F	0x60EF	# <CJK>
+0x3960	0x704C	# <CJK>
+0x3961	0x8D2F	# <CJK>
+0x3962	0x5149	# <CJK>
+0x3963	0x5E7F	# <CJK>
+0x3964	0x901B	# <CJK>
+0x3965	0x7470	# <CJK>
+0x3966	0x89C4	# <CJK>
+0x3967	0x572D	# <CJK>
+0x3968	0x7845	# <CJK>
+0x3969	0x5F52	# <CJK>
+0x396A	0x9F9F	# <CJK>
+0x396B	0x95FA	# <CJK>
+0x396C	0x8F68	# <CJK>
+0x396D	0x9B3C	# <CJK>
+0x396E	0x8BE1	# <CJK>
+0x396F	0x7678	# <CJK>
+0x3970	0x6842	# <CJK>
+0x3971	0x67DC	# <CJK>
+0x3972	0x8DEA	# <CJK>
+0x3973	0x8D35	# <CJK>
+0x3974	0x523D	# <CJK>
+0x3975	0x8F8A	# <CJK>
+0x3976	0x6EDA	# <CJK>
+0x3977	0x68CD	# <CJK>
+0x3978	0x9505	# <CJK>
+0x3979	0x90ED	# <CJK>
+0x397A	0x56FD	# <CJK>
+0x397B	0x679C	# <CJK>
+0x397C	0x88F9	# <CJK>
+0x397D	0x8FC7	# <CJK>
+0x397E	0x54C8	# <CJK>
+0x3A21	0x9AB8	# <CJK>
+0x3A22	0x5B69	# <CJK>
+0x3A23	0x6D77	# <CJK>
+0x3A24	0x6C26	# <CJK>
+0x3A25	0x4EA5	# <CJK>
+0x3A26	0x5BB3	# <CJK>
+0x3A27	0x9A87	# <CJK>
+0x3A28	0x9163	# <CJK>
+0x3A29	0x61A8	# <CJK>
+0x3A2A	0x90AF	# <CJK>
+0x3A2B	0x97E9	# <CJK>
+0x3A2C	0x542B	# <CJK>
+0x3A2D	0x6DB5	# <CJK>
+0x3A2E	0x5BD2	# <CJK>
+0x3A2F	0x51FD	# <CJK>
+0x3A30	0x558A	# <CJK>
+0x3A31	0x7F55	# <CJK>
+0x3A32	0x7FF0	# <CJK>
+0x3A33	0x64BC	# <CJK>
+0x3A34	0x634D	# <CJK>
+0x3A35	0x65F1	# <CJK>
+0x3A36	0x61BE	# <CJK>
+0x3A37	0x608D	# <CJK>
+0x3A38	0x710A	# <CJK>
+0x3A39	0x6C57	# <CJK>
+0x3A3A	0x6C49	# <CJK>
+0x3A3B	0x592F	# <CJK>
+0x3A3C	0x676D	# <CJK>
+0x3A3D	0x822A	# <CJK>
+0x3A3E	0x58D5	# <CJK>
+0x3A3F	0x568E	# <CJK>
+0x3A40	0x8C6A	# <CJK>
+0x3A41	0x6BEB	# <CJK>
+0x3A42	0x90DD	# <CJK>
+0x3A43	0x597D	# <CJK>
+0x3A44	0x8017	# <CJK>
+0x3A45	0x53F7	# <CJK>
+0x3A46	0x6D69	# <CJK>
+0x3A47	0x5475	# <CJK>
+0x3A48	0x559D	# <CJK>
+0x3A49	0x8377	# <CJK>
+0x3A4A	0x83CF	# <CJK>
+0x3A4B	0x6838	# <CJK>
+0x3A4C	0x79BE	# <CJK>
+0x3A4D	0x548C	# <CJK>
+0x3A4E	0x4F55	# <CJK>
+0x3A4F	0x5408	# <CJK>
+0x3A50	0x76D2	# <CJK>
+0x3A51	0x8C89	# <CJK>
+0x3A52	0x9602	# <CJK>
+0x3A53	0x6CB3	# <CJK>
+0x3A54	0x6DB8	# <CJK>
+0x3A55	0x8D6B	# <CJK>
+0x3A56	0x8910	# <CJK>
+0x3A57	0x9E64	# <CJK>
+0x3A58	0x8D3A	# <CJK>
+0x3A59	0x563F	# <CJK>
+0x3A5A	0x9ED1	# <CJK>
+0x3A5B	0x75D5	# <CJK>
+0x3A5C	0x5F88	# <CJK>
+0x3A5D	0x72E0	# <CJK>
+0x3A5E	0x6068	# <CJK>
+0x3A5F	0x54FC	# <CJK>
+0x3A60	0x4EA8	# <CJK>
+0x3A61	0x6A2A	# <CJK>
+0x3A62	0x8861	# <CJK>
+0x3A63	0x6052	# <CJK>
+0x3A64	0x8F70	# <CJK>
+0x3A65	0x54C4	# <CJK>
+0x3A66	0x70D8	# <CJK>
+0x3A67	0x8679	# <CJK>
+0x3A68	0x9E3F	# <CJK>
+0x3A69	0x6D2A	# <CJK>
+0x3A6A	0x5B8F	# <CJK>
+0x3A6B	0x5F18	# <CJK>
+0x3A6C	0x7EA2	# <CJK>
+0x3A6D	0x5589	# <CJK>
+0x3A6E	0x4FAF	# <CJK>
+0x3A6F	0x7334	# <CJK>
+0x3A70	0x543C	# <CJK>
+0x3A71	0x539A	# <CJK>
+0x3A72	0x5019	# <CJK>
+0x3A73	0x540E	# <CJK>
+0x3A74	0x547C	# <CJK>
+0x3A75	0x4E4E	# <CJK>
+0x3A76	0x5FFD	# <CJK>
+0x3A77	0x745A	# <CJK>
+0x3A78	0x58F6	# <CJK>
+0x3A79	0x846B	# <CJK>
+0x3A7A	0x80E1	# <CJK>
+0x3A7B	0x8774	# <CJK>
+0x3A7C	0x72D0	# <CJK>
+0x3A7D	0x7CCA	# <CJK>
+0x3A7E	0x6E56	# <CJK>
+0x3B21	0x5F27	# <CJK>
+0x3B22	0x864E	# <CJK>
+0x3B23	0x552C	# <CJK>
+0x3B24	0x62A4	# <CJK>
+0x3B25	0x4E92	# <CJK>
+0x3B26	0x6CAA	# <CJK>
+0x3B27	0x6237	# <CJK>
+0x3B28	0x82B1	# <CJK>
+0x3B29	0x54D7	# <CJK>
+0x3B2A	0x534E	# <CJK>
+0x3B2B	0x733E	# <CJK>
+0x3B2C	0x6ED1	# <CJK>
+0x3B2D	0x753B	# <CJK>
+0x3B2E	0x5212	# <CJK>
+0x3B2F	0x5316	# <CJK>
+0x3B30	0x8BDD	# <CJK>
+0x3B31	0x69D0	# <CJK>
+0x3B32	0x5F8A	# <CJK>
+0x3B33	0x6000	# <CJK>
+0x3B34	0x6DEE	# <CJK>
+0x3B35	0x574F	# <CJK>
+0x3B36	0x6B22	# <CJK>
+0x3B37	0x73AF	# <CJK>
+0x3B38	0x6853	# <CJK>
+0x3B39	0x8FD8	# <CJK>
+0x3B3A	0x7F13	# <CJK>
+0x3B3B	0x6362	# <CJK>
+0x3B3C	0x60A3	# <CJK>
+0x3B3D	0x5524	# <CJK>
+0x3B3E	0x75EA	# <CJK>
+0x3B3F	0x8C62	# <CJK>
+0x3B40	0x7115	# <CJK>
+0x3B41	0x6DA3	# <CJK>
+0x3B42	0x5BA6	# <CJK>
+0x3B43	0x5E7B	# <CJK>
+0x3B44	0x8352	# <CJK>
+0x3B45	0x614C	# <CJK>
+0x3B46	0x9EC4	# <CJK>
+0x3B47	0x78FA	# <CJK>
+0x3B48	0x8757	# <CJK>
+0x3B49	0x7C27	# <CJK>
+0x3B4A	0x7687	# <CJK>
+0x3B4B	0x51F0	# <CJK>
+0x3B4C	0x60F6	# <CJK>
+0x3B4D	0x714C	# <CJK>
+0x3B4E	0x6643	# <CJK>
+0x3B4F	0x5E4C	# <CJK>
+0x3B50	0x604D	# <CJK>
+0x3B51	0x8C0E	# <CJK>
+0x3B52	0x7070	# <CJK>
+0x3B53	0x6325	# <CJK>
+0x3B54	0x8F89	# <CJK>
+0x3B55	0x5FBD	# <CJK>
+0x3B56	0x6062	# <CJK>
+0x3B57	0x86D4	# <CJK>
+0x3B58	0x56DE	# <CJK>
+0x3B59	0x6BC1	# <CJK>
+0x3B5A	0x6094	# <CJK>
+0x3B5B	0x6167	# <CJK>
+0x3B5C	0x5349	# <CJK>
+0x3B5D	0x60E0	# <CJK>
+0x3B5E	0x6666	# <CJK>
+0x3B5F	0x8D3F	# <CJK>
+0x3B60	0x79FD	# <CJK>
+0x3B61	0x4F1A	# <CJK>
+0x3B62	0x70E9	# <CJK>
+0x3B63	0x6C47	# <CJK>
+0x3B64	0x8BB3	# <CJK>
+0x3B65	0x8BF2	# <CJK>
+0x3B66	0x7ED8	# <CJK>
+0x3B67	0x8364	# <CJK>
+0x3B68	0x660F	# <CJK>
+0x3B69	0x5A5A	# <CJK>
+0x3B6A	0x9B42	# <CJK>
+0x3B6B	0x6D51	# <CJK>
+0x3B6C	0x6DF7	# <CJK>
+0x3B6D	0x8C41	# <CJK>
+0x3B6E	0x6D3B	# <CJK>
+0x3B6F	0x4F19	# <CJK>
+0x3B70	0x706B	# <CJK>
+0x3B71	0x83B7	# <CJK>
+0x3B72	0x6216	# <CJK>
+0x3B73	0x60D1	# <CJK>
+0x3B74	0x970D	# <CJK>
+0x3B75	0x8D27	# <CJK>
+0x3B76	0x7978	# <CJK>
+0x3B77	0x51FB	# <CJK>
+0x3B78	0x573E	# <CJK>
+0x3B79	0x57FA	# <CJK>
+0x3B7A	0x673A	# <CJK>
+0x3B7B	0x7578	# <CJK>
+0x3B7C	0x7A3D	# <CJK>
+0x3B7D	0x79EF	# <CJK>
+0x3B7E	0x7B95	# <CJK>
+0x3C21	0x808C	# <CJK>
+0x3C22	0x9965	# <CJK>
+0x3C23	0x8FF9	# <CJK>
+0x3C24	0x6FC0	# <CJK>
+0x3C25	0x8BA5	# <CJK>
+0x3C26	0x9E21	# <CJK>
+0x3C27	0x59EC	# <CJK>
+0x3C28	0x7EE9	# <CJK>
+0x3C29	0x7F09	# <CJK>
+0x3C2A	0x5409	# <CJK>
+0x3C2B	0x6781	# <CJK>
+0x3C2C	0x68D8	# <CJK>
+0x3C2D	0x8F91	# <CJK>
+0x3C2E	0x7C4D	# <CJK>
+0x3C2F	0x96C6	# <CJK>
+0x3C30	0x53CA	# <CJK>
+0x3C31	0x6025	# <CJK>
+0x3C32	0x75BE	# <CJK>
+0x3C33	0x6C72	# <CJK>
+0x3C34	0x5373	# <CJK>
+0x3C35	0x5AC9	# <CJK>
+0x3C36	0x7EA7	# <CJK>
+0x3C37	0x6324	# <CJK>
+0x3C38	0x51E0	# <CJK>
+0x3C39	0x810A	# <CJK>
+0x3C3A	0x5DF1	# <CJK>
+0x3C3B	0x84DF	# <CJK>
+0x3C3C	0x6280	# <CJK>
+0x3C3D	0x5180	# <CJK>
+0x3C3E	0x5B63	# <CJK>
+0x3C3F	0x4F0E	# <CJK>
+0x3C40	0x796D	# <CJK>
+0x3C41	0x5242	# <CJK>
+0x3C42	0x60B8	# <CJK>
+0x3C43	0x6D4E	# <CJK>
+0x3C44	0x5BC4	# <CJK>
+0x3C45	0x5BC2	# <CJK>
+0x3C46	0x8BA1	# <CJK>
+0x3C47	0x8BB0	# <CJK>
+0x3C48	0x65E2	# <CJK>
+0x3C49	0x5FCC	# <CJK>
+0x3C4A	0x9645	# <CJK>
+0x3C4B	0x5993	# <CJK>
+0x3C4C	0x7EE7	# <CJK>
+0x3C4D	0x7EAA	# <CJK>
+0x3C4E	0x5609	# <CJK>
+0x3C4F	0x67B7	# <CJK>
+0x3C50	0x5939	# <CJK>
+0x3C51	0x4F73	# <CJK>
+0x3C52	0x5BB6	# <CJK>
+0x3C53	0x52A0	# <CJK>
+0x3C54	0x835A	# <CJK>
+0x3C55	0x988A	# <CJK>
+0x3C56	0x8D3E	# <CJK>
+0x3C57	0x7532	# <CJK>
+0x3C58	0x94BE	# <CJK>
+0x3C59	0x5047	# <CJK>
+0x3C5A	0x7A3C	# <CJK>
+0x3C5B	0x4EF7	# <CJK>
+0x3C5C	0x67B6	# <CJK>
+0x3C5D	0x9A7E	# <CJK>
+0x3C5E	0x5AC1	# <CJK>
+0x3C5F	0x6B7C	# <CJK>
+0x3C60	0x76D1	# <CJK>
+0x3C61	0x575A	# <CJK>
+0x3C62	0x5C16	# <CJK>
+0x3C63	0x7B3A	# <CJK>
+0x3C64	0x95F4	# <CJK>
+0x3C65	0x714E	# <CJK>
+0x3C66	0x517C	# <CJK>
+0x3C67	0x80A9	# <CJK>
+0x3C68	0x8270	# <CJK>
+0x3C69	0x5978	# <CJK>
+0x3C6A	0x7F04	# <CJK>
+0x3C6B	0x8327	# <CJK>
+0x3C6C	0x68C0	# <CJK>
+0x3C6D	0x67EC	# <CJK>
+0x3C6E	0x78B1	# <CJK>
+0x3C6F	0x7877	# <CJK>
+0x3C70	0x62E3	# <CJK>
+0x3C71	0x6361	# <CJK>
+0x3C72	0x7B80	# <CJK>
+0x3C73	0x4FED	# <CJK>
+0x3C74	0x526A	# <CJK>
+0x3C75	0x51CF	# <CJK>
+0x3C76	0x8350	# <CJK>
+0x3C77	0x69DB	# <CJK>
+0x3C78	0x9274	# <CJK>
+0x3C79	0x8DF5	# <CJK>
+0x3C7A	0x8D31	# <CJK>
+0x3C7B	0x89C1	# <CJK>
+0x3C7C	0x952E	# <CJK>
+0x3C7D	0x7BAD	# <CJK>
+0x3C7E	0x4EF6	# <CJK>
+0x3D21	0x5065	# <CJK>
+0x3D22	0x8230	# <CJK>
+0x3D23	0x5251	# <CJK>
+0x3D24	0x996F	# <CJK>
+0x3D25	0x6E10	# <CJK>
+0x3D26	0x6E85	# <CJK>
+0x3D27	0x6DA7	# <CJK>
+0x3D28	0x5EFA	# <CJK>
+0x3D29	0x50F5	# <CJK>
+0x3D2A	0x59DC	# <CJK>
+0x3D2B	0x5C06	# <CJK>
+0x3D2C	0x6D46	# <CJK>
+0x3D2D	0x6C5F	# <CJK>
+0x3D2E	0x7586	# <CJK>
+0x3D2F	0x848B	# <CJK>
+0x3D30	0x6868	# <CJK>
+0x3D31	0x5956	# <CJK>
+0x3D32	0x8BB2	# <CJK>
+0x3D33	0x5320	# <CJK>
+0x3D34	0x9171	# <CJK>
+0x3D35	0x964D	# <CJK>
+0x3D36	0x8549	# <CJK>
+0x3D37	0x6912	# <CJK>
+0x3D38	0x7901	# <CJK>
+0x3D39	0x7126	# <CJK>
+0x3D3A	0x80F6	# <CJK>
+0x3D3B	0x4EA4	# <CJK>
+0x3D3C	0x90CA	# <CJK>
+0x3D3D	0x6D47	# <CJK>
+0x3D3E	0x9A84	# <CJK>
+0x3D3F	0x5A07	# <CJK>
+0x3D40	0x56BC	# <CJK>
+0x3D41	0x6405	# <CJK>
+0x3D42	0x94F0	# <CJK>
+0x3D43	0x77EB	# <CJK>
+0x3D44	0x4FA5	# <CJK>
+0x3D45	0x811A	# <CJK>
+0x3D46	0x72E1	# <CJK>
+0x3D47	0x89D2	# <CJK>
+0x3D48	0x997A	# <CJK>
+0x3D49	0x7F34	# <CJK>
+0x3D4A	0x7EDE	# <CJK>
+0x3D4B	0x527F	# <CJK>
+0x3D4C	0x6559	# <CJK>
+0x3D4D	0x9175	# <CJK>
+0x3D4E	0x8F7F	# <CJK>
+0x3D4F	0x8F83	# <CJK>
+0x3D50	0x53EB	# <CJK>
+0x3D51	0x7A96	# <CJK>
+0x3D52	0x63ED	# <CJK>
+0x3D53	0x63A5	# <CJK>
+0x3D54	0x7686	# <CJK>
+0x3D55	0x79F8	# <CJK>
+0x3D56	0x8857	# <CJK>
+0x3D57	0x9636	# <CJK>
+0x3D58	0x622A	# <CJK>
+0x3D59	0x52AB	# <CJK>
+0x3D5A	0x8282	# <CJK>
+0x3D5B	0x6854	# <CJK>
+0x3D5C	0x6770	# <CJK>
+0x3D5D	0x6377	# <CJK>
+0x3D5E	0x776B	# <CJK>
+0x3D5F	0x7AED	# <CJK>
+0x3D60	0x6D01	# <CJK>
+0x3D61	0x7ED3	# <CJK>
+0x3D62	0x89E3	# <CJK>
+0x3D63	0x59D0	# <CJK>
+0x3D64	0x6212	# <CJK>
+0x3D65	0x85C9	# <CJK>
+0x3D66	0x82A5	# <CJK>
+0x3D67	0x754C	# <CJK>
+0x3D68	0x501F	# <CJK>
+0x3D69	0x4ECB	# <CJK>
+0x3D6A	0x75A5	# <CJK>
+0x3D6B	0x8BEB	# <CJK>
+0x3D6C	0x5C4A	# <CJK>
+0x3D6D	0x5DFE	# <CJK>
+0x3D6E	0x7B4B	# <CJK>
+0x3D6F	0x65A4	# <CJK>
+0x3D70	0x91D1	# <CJK>
+0x3D71	0x4ECA	# <CJK>
+0x3D72	0x6D25	# <CJK>
+0x3D73	0x895F	# <CJK>
+0x3D74	0x7D27	# <CJK>
+0x3D75	0x9526	# <CJK>
+0x3D76	0x4EC5	# <CJK>
+0x3D77	0x8C28	# <CJK>
+0x3D78	0x8FDB	# <CJK>
+0x3D79	0x9773	# <CJK>
+0x3D7A	0x664B	# <CJK>
+0x3D7B	0x7981	# <CJK>
+0x3D7C	0x8FD1	# <CJK>
+0x3D7D	0x70EC	# <CJK>
+0x3D7E	0x6D78	# <CJK>
+0x3E21	0x5C3D	# <CJK>
+0x3E22	0x52B2	# <CJK>
+0x3E23	0x8346	# <CJK>
+0x3E24	0x5162	# <CJK>
+0x3E25	0x830E	# <CJK>
+0x3E26	0x775B	# <CJK>
+0x3E27	0x6676	# <CJK>
+0x3E28	0x9CB8	# <CJK>
+0x3E29	0x4EAC	# <CJK>
+0x3E2A	0x60CA	# <CJK>
+0x3E2B	0x7CBE	# <CJK>
+0x3E2C	0x7CB3	# <CJK>
+0x3E2D	0x7ECF	# <CJK>
+0x3E2E	0x4E95	# <CJK>
+0x3E2F	0x8B66	# <CJK>
+0x3E30	0x666F	# <CJK>
+0x3E31	0x9888	# <CJK>
+0x3E32	0x9759	# <CJK>
+0x3E33	0x5883	# <CJK>
+0x3E34	0x656C	# <CJK>
+0x3E35	0x955C	# <CJK>
+0x3E36	0x5F84	# <CJK>
+0x3E37	0x75C9	# <CJK>
+0x3E38	0x9756	# <CJK>
+0x3E39	0x7ADF	# <CJK>
+0x3E3A	0x7ADE	# <CJK>
+0x3E3B	0x51C0	# <CJK>
+0x3E3C	0x70AF	# <CJK>
+0x3E3D	0x7A98	# <CJK>
+0x3E3E	0x63EA	# <CJK>
+0x3E3F	0x7A76	# <CJK>
+0x3E40	0x7EA0	# <CJK>
+0x3E41	0x7396	# <CJK>
+0x3E42	0x97ED	# <CJK>
+0x3E43	0x4E45	# <CJK>
+0x3E44	0x7078	# <CJK>
+0x3E45	0x4E5D	# <CJK>
+0x3E46	0x9152	# <CJK>
+0x3E47	0x53A9	# <CJK>
+0x3E48	0x6551	# <CJK>
+0x3E49	0x65E7	# <CJK>
+0x3E4A	0x81FC	# <CJK>
+0x3E4B	0x8205	# <CJK>
+0x3E4C	0x548E	# <CJK>
+0x3E4D	0x5C31	# <CJK>
+0x3E4E	0x759A	# <CJK>
+0x3E4F	0x97A0	# <CJK>
+0x3E50	0x62D8	# <CJK>
+0x3E51	0x72D9	# <CJK>
+0x3E52	0x75BD	# <CJK>
+0x3E53	0x5C45	# <CJK>
+0x3E54	0x9A79	# <CJK>
+0x3E55	0x83CA	# <CJK>
+0x3E56	0x5C40	# <CJK>
+0x3E57	0x5480	# <CJK>
+0x3E58	0x77E9	# <CJK>
+0x3E59	0x4E3E	# <CJK>
+0x3E5A	0x6CAE	# <CJK>
+0x3E5B	0x805A	# <CJK>
+0x3E5C	0x62D2	# <CJK>
+0x3E5D	0x636E	# <CJK>
+0x3E5E	0x5DE8	# <CJK>
+0x3E5F	0x5177	# <CJK>
+0x3E60	0x8DDD	# <CJK>
+0x3E61	0x8E1E	# <CJK>
+0x3E62	0x952F	# <CJK>
+0x3E63	0x4FF1	# <CJK>
+0x3E64	0x53E5	# <CJK>
+0x3E65	0x60E7	# <CJK>
+0x3E66	0x70AC	# <CJK>
+0x3E67	0x5267	# <CJK>
+0x3E68	0x6350	# <CJK>
+0x3E69	0x9E43	# <CJK>
+0x3E6A	0x5A1F	# <CJK>
+0x3E6B	0x5026	# <CJK>
+0x3E6C	0x7737	# <CJK>
+0x3E6D	0x5377	# <CJK>
+0x3E6E	0x7EE2	# <CJK>
+0x3E6F	0x6485	# <CJK>
+0x3E70	0x652B	# <CJK>
+0x3E71	0x6289	# <CJK>
+0x3E72	0x6398	# <CJK>
+0x3E73	0x5014	# <CJK>
+0x3E74	0x7235	# <CJK>
+0x3E75	0x89C9	# <CJK>
+0x3E76	0x51B3	# <CJK>
+0x3E77	0x8BC0	# <CJK>
+0x3E78	0x7EDD	# <CJK>
+0x3E79	0x5747	# <CJK>
+0x3E7A	0x83CC	# <CJK>
+0x3E7B	0x94A7	# <CJK>
+0x3E7C	0x519B	# <CJK>
+0x3E7D	0x541B	# <CJK>
+0x3E7E	0x5CFB	# <CJK>
+0x3F21	0x4FCA	# <CJK>
+0x3F22	0x7AE3	# <CJK>
+0x3F23	0x6D5A	# <CJK>
+0x3F24	0x90E1	# <CJK>
+0x3F25	0x9A8F	# <CJK>
+0x3F26	0x5580	# <CJK>
+0x3F27	0x5496	# <CJK>
+0x3F28	0x5361	# <CJK>
+0x3F29	0x54AF	# <CJK>
+0x3F2A	0x5F00	# <CJK>
+0x3F2B	0x63E9	# <CJK>
+0x3F2C	0x6977	# <CJK>
+0x3F2D	0x51EF	# <CJK>
+0x3F2E	0x6168	# <CJK>
+0x3F2F	0x520A	# <CJK>
+0x3F30	0x582A	# <CJK>
+0x3F31	0x52D8	# <CJK>
+0x3F32	0x574E	# <CJK>
+0x3F33	0x780D	# <CJK>
+0x3F34	0x770B	# <CJK>
+0x3F35	0x5EB7	# <CJK>
+0x3F36	0x6177	# <CJK>
+0x3F37	0x7CE0	# <CJK>
+0x3F38	0x625B	# <CJK>
+0x3F39	0x6297	# <CJK>
+0x3F3A	0x4EA2	# <CJK>
+0x3F3B	0x7095	# <CJK>
+0x3F3C	0x8003	# <CJK>
+0x3F3D	0x62F7	# <CJK>
+0x3F3E	0x70E4	# <CJK>
+0x3F3F	0x9760	# <CJK>
+0x3F40	0x5777	# <CJK>
+0x3F41	0x82DB	# <CJK>
+0x3F42	0x67EF	# <CJK>
+0x3F43	0x68F5	# <CJK>
+0x3F44	0x78D5	# <CJK>
+0x3F45	0x9897	# <CJK>
+0x3F46	0x79D1	# <CJK>
+0x3F47	0x58F3	# <CJK>
+0x3F48	0x54B3	# <CJK>
+0x3F49	0x53EF	# <CJK>
+0x3F4A	0x6E34	# <CJK>
+0x3F4B	0x514B	# <CJK>
+0x3F4C	0x523B	# <CJK>
+0x3F4D	0x5BA2	# <CJK>
+0x3F4E	0x8BFE	# <CJK>
+0x3F4F	0x80AF	# <CJK>
+0x3F50	0x5543	# <CJK>
+0x3F51	0x57A6	# <CJK>
+0x3F52	0x6073	# <CJK>
+0x3F53	0x5751	# <CJK>
+0x3F54	0x542D	# <CJK>
+0x3F55	0x7A7A	# <CJK>
+0x3F56	0x6050	# <CJK>
+0x3F57	0x5B54	# <CJK>
+0x3F58	0x63A7	# <CJK>
+0x3F59	0x62A0	# <CJK>
+0x3F5A	0x53E3	# <CJK>
+0x3F5B	0x6263	# <CJK>
+0x3F5C	0x5BC7	# <CJK>
+0x3F5D	0x67AF	# <CJK>
+0x3F5E	0x54ED	# <CJK>
+0x3F5F	0x7A9F	# <CJK>
+0x3F60	0x82E6	# <CJK>
+0x3F61	0x9177	# <CJK>
+0x3F62	0x5E93	# <CJK>
+0x3F63	0x88E4	# <CJK>
+0x3F64	0x5938	# <CJK>
+0x3F65	0x57AE	# <CJK>
+0x3F66	0x630E	# <CJK>
+0x3F67	0x8DE8	# <CJK>
+0x3F68	0x80EF	# <CJK>
+0x3F69	0x5757	# <CJK>
+0x3F6A	0x7B77	# <CJK>
+0x3F6B	0x4FA9	# <CJK>
+0x3F6C	0x5FEB	# <CJK>
+0x3F6D	0x5BBD	# <CJK>
+0x3F6E	0x6B3E	# <CJK>
+0x3F6F	0x5321	# <CJK>
+0x3F70	0x7B50	# <CJK>
+0x3F71	0x72C2	# <CJK>
+0x3F72	0x6846	# <CJK>
+0x3F73	0x77FF	# <CJK>
+0x3F74	0x7736	# <CJK>
+0x3F75	0x65F7	# <CJK>
+0x3F76	0x51B5	# <CJK>
+0x3F77	0x4E8F	# <CJK>
+0x3F78	0x76D4	# <CJK>
+0x3F79	0x5CBF	# <CJK>
+0x3F7A	0x7AA5	# <CJK>
+0x3F7B	0x8475	# <CJK>
+0x3F7C	0x594E	# <CJK>
+0x3F7D	0x9B41	# <CJK>
+0x3F7E	0x5080	# <CJK>
+0x4021	0x9988	# <CJK>
+0x4022	0x6127	# <CJK>
+0x4023	0x6E83	# <CJK>
+0x4024	0x5764	# <CJK>
+0x4025	0x6606	# <CJK>
+0x4026	0x6346	# <CJK>
+0x4027	0x56F0	# <CJK>
+0x4028	0x62EC	# <CJK>
+0x4029	0x6269	# <CJK>
+0x402A	0x5ED3	# <CJK>
+0x402B	0x9614	# <CJK>
+0x402C	0x5783	# <CJK>
+0x402D	0x62C9	# <CJK>
+0x402E	0x5587	# <CJK>
+0x402F	0x8721	# <CJK>
+0x4030	0x814A	# <CJK>
+0x4031	0x8FA3	# <CJK>
+0x4032	0x5566	# <CJK>
+0x4033	0x83B1	# <CJK>
+0x4034	0x6765	# <CJK>
+0x4035	0x8D56	# <CJK>
+0x4036	0x84DD	# <CJK>
+0x4037	0x5A6A	# <CJK>
+0x4038	0x680F	# <CJK>
+0x4039	0x62E6	# <CJK>
+0x403A	0x7BEE	# <CJK>
+0x403B	0x9611	# <CJK>
+0x403C	0x5170	# <CJK>
+0x403D	0x6F9C	# <CJK>
+0x403E	0x8C30	# <CJK>
+0x403F	0x63FD	# <CJK>
+0x4040	0x89C8	# <CJK>
+0x4041	0x61D2	# <CJK>
+0x4042	0x7F06	# <CJK>
+0x4043	0x70C2	# <CJK>
+0x4044	0x6EE5	# <CJK>
+0x4045	0x7405	# <CJK>
+0x4046	0x6994	# <CJK>
+0x4047	0x72FC	# <CJK>
+0x4048	0x5ECA	# <CJK>
+0x4049	0x90CE	# <CJK>
+0x404A	0x6717	# <CJK>
+0x404B	0x6D6A	# <CJK>
+0x404C	0x635E	# <CJK>
+0x404D	0x52B3	# <CJK>
+0x404E	0x7262	# <CJK>
+0x404F	0x8001	# <CJK>
+0x4050	0x4F6C	# <CJK>
+0x4051	0x59E5	# <CJK>
+0x4052	0x916A	# <CJK>
+0x4053	0x70D9	# <CJK>
+0x4054	0x6D9D	# <CJK>
+0x4055	0x52D2	# <CJK>
+0x4056	0x4E50	# <CJK>
+0x4057	0x96F7	# <CJK>
+0x4058	0x956D	# <CJK>
+0x4059	0x857E	# <CJK>
+0x405A	0x78CA	# <CJK>
+0x405B	0x7D2F	# <CJK>
+0x405C	0x5121	# <CJK>
+0x405D	0x5792	# <CJK>
+0x405E	0x64C2	# <CJK>
+0x405F	0x808B	# <CJK>
+0x4060	0x7C7B	# <CJK>
+0x4061	0x6CEA	# <CJK>
+0x4062	0x68F1	# <CJK>
+0x4063	0x695E	# <CJK>
+0x4064	0x51B7	# <CJK>
+0x4065	0x5398	# <CJK>
+0x4066	0x68A8	# <CJK>
+0x4067	0x7281	# <CJK>
+0x4068	0x9ECE	# <CJK>
+0x4069	0x7BF1	# <CJK>
+0x406A	0x72F8	# <CJK>
+0x406B	0x79BB	# <CJK>
+0x406C	0x6F13	# <CJK>
+0x406D	0x7406	# <CJK>
+0x406E	0x674E	# <CJK>
+0x406F	0x91CC	# <CJK>
+0x4070	0x9CA4	# <CJK>
+0x4071	0x793C	# <CJK>
+0x4072	0x8389	# <CJK>
+0x4073	0x8354	# <CJK>
+0x4074	0x540F	# <CJK>
+0x4075	0x6817	# <CJK>
+0x4076	0x4E3D	# <CJK>
+0x4077	0x5389	# <CJK>
+0x4078	0x52B1	# <CJK>
+0x4079	0x783E	# <CJK>
+0x407A	0x5386	# <CJK>
+0x407B	0x5229	# <CJK>
+0x407C	0x5088	# <CJK>
+0x407D	0x4F8B	# <CJK>
+0x407E	0x4FD0	# <CJK>
+0x4121	0x75E2	# <CJK>
+0x4122	0x7ACB	# <CJK>
+0x4123	0x7C92	# <CJK>
+0x4124	0x6CA5	# <CJK>
+0x4125	0x96B6	# <CJK>
+0x4126	0x529B	# <CJK>
+0x4127	0x7483	# <CJK>
+0x4128	0x54E9	# <CJK>
+0x4129	0x4FE9	# <CJK>
+0x412A	0x8054	# <CJK>
+0x412B	0x83B2	# <CJK>
+0x412C	0x8FDE	# <CJK>
+0x412D	0x9570	# <CJK>
+0x412E	0x5EC9	# <CJK>
+0x412F	0x601C	# <CJK>
+0x4130	0x6D9F	# <CJK>
+0x4131	0x5E18	# <CJK>
+0x4132	0x655B	# <CJK>
+0x4133	0x8138	# <CJK>
+0x4134	0x94FE	# <CJK>
+0x4135	0x604B	# <CJK>
+0x4136	0x70BC	# <CJK>
+0x4137	0x7EC3	# <CJK>
+0x4138	0x7CAE	# <CJK>
+0x4139	0x51C9	# <CJK>
+0x413A	0x6881	# <CJK>
+0x413B	0x7CB1	# <CJK>
+0x413C	0x826F	# <CJK>
+0x413D	0x4E24	# <CJK>
+0x413E	0x8F86	# <CJK>
+0x413F	0x91CF	# <CJK>
+0x4140	0x667E	# <CJK>
+0x4141	0x4EAE	# <CJK>
+0x4142	0x8C05	# <CJK>
+0x4143	0x64A9	# <CJK>
+0x4144	0x804A	# <CJK>
+0x4145	0x50DA	# <CJK>
+0x4146	0x7597	# <CJK>
+0x4147	0x71CE	# <CJK>
+0x4148	0x5BE5	# <CJK>
+0x4149	0x8FBD	# <CJK>
+0x414A	0x6F66	# <CJK>
+0x414B	0x4E86	# <CJK>
+0x414C	0x6482	# <CJK>
+0x414D	0x9563	# <CJK>
+0x414E	0x5ED6	# <CJK>
+0x414F	0x6599	# <CJK>
+0x4150	0x5217	# <CJK>
+0x4151	0x88C2	# <CJK>
+0x4152	0x70C8	# <CJK>
+0x4153	0x52A3	# <CJK>
+0x4154	0x730E	# <CJK>
+0x4155	0x7433	# <CJK>
+0x4156	0x6797	# <CJK>
+0x4157	0x78F7	# <CJK>
+0x4158	0x9716	# <CJK>
+0x4159	0x4E34	# <CJK>
+0x415A	0x90BB	# <CJK>
+0x415B	0x9CDE	# <CJK>
+0x415C	0x6DCB	# <CJK>
+0x415D	0x51DB	# <CJK>
+0x415E	0x8D41	# <CJK>
+0x415F	0x541D	# <CJK>
+0x4160	0x62CE	# <CJK>
+0x4161	0x73B2	# <CJK>
+0x4162	0x83F1	# <CJK>
+0x4163	0x96F6	# <CJK>
+0x4164	0x9F84	# <CJK>
+0x4165	0x94C3	# <CJK>
+0x4166	0x4F36	# <CJK>
+0x4167	0x7F9A	# <CJK>
+0x4168	0x51CC	# <CJK>
+0x4169	0x7075	# <CJK>
+0x416A	0x9675	# <CJK>
+0x416B	0x5CAD	# <CJK>
+0x416C	0x9886	# <CJK>
+0x416D	0x53E6	# <CJK>
+0x416E	0x4EE4	# <CJK>
+0x416F	0x6E9C	# <CJK>
+0x4170	0x7409	# <CJK>
+0x4171	0x69B4	# <CJK>
+0x4172	0x786B	# <CJK>
+0x4173	0x998F	# <CJK>
+0x4174	0x7559	# <CJK>
+0x4175	0x5218	# <CJK>
+0x4176	0x7624	# <CJK>
+0x4177	0x6D41	# <CJK>
+0x4178	0x67F3	# <CJK>
+0x4179	0x516D	# <CJK>
+0x417A	0x9F99	# <CJK>
+0x417B	0x804B	# <CJK>
+0x417C	0x5499	# <CJK>
+0x417D	0x7B3C	# <CJK>
+0x417E	0x7ABF	# <CJK>
+0x4221	0x9686	# <CJK>
+0x4222	0x5784	# <CJK>
+0x4223	0x62E2	# <CJK>
+0x4224	0x9647	# <CJK>
+0x4225	0x697C	# <CJK>
+0x4226	0x5A04	# <CJK>
+0x4227	0x6402	# <CJK>
+0x4228	0x7BD3	# <CJK>
+0x4229	0x6F0F	# <CJK>
+0x422A	0x964B	# <CJK>
+0x422B	0x82A6	# <CJK>
+0x422C	0x5362	# <CJK>
+0x422D	0x9885	# <CJK>
+0x422E	0x5E90	# <CJK>
+0x422F	0x7089	# <CJK>
+0x4230	0x63B3	# <CJK>
+0x4231	0x5364	# <CJK>
+0x4232	0x864F	# <CJK>
+0x4233	0x9C81	# <CJK>
+0x4234	0x9E93	# <CJK>
+0x4235	0x788C	# <CJK>
+0x4236	0x9732	# <CJK>
+0x4237	0x8DEF	# <CJK>
+0x4238	0x8D42	# <CJK>
+0x4239	0x9E7F	# <CJK>
+0x423A	0x6F5E	# <CJK>
+0x423B	0x7984	# <CJK>
+0x423C	0x5F55	# <CJK>
+0x423D	0x9646	# <CJK>
+0x423E	0x622E	# <CJK>
+0x423F	0x9A74	# <CJK>
+0x4240	0x5415	# <CJK>
+0x4241	0x94DD	# <CJK>
+0x4242	0x4FA3	# <CJK>
+0x4243	0x65C5	# <CJK>
+0x4244	0x5C65	# <CJK>
+0x4245	0x5C61	# <CJK>
+0x4246	0x7F15	# <CJK>
+0x4247	0x8651	# <CJK>
+0x4248	0x6C2F	# <CJK>
+0x4249	0x5F8B	# <CJK>
+0x424A	0x7387	# <CJK>
+0x424B	0x6EE4	# <CJK>
+0x424C	0x7EFF	# <CJK>
+0x424D	0x5CE6	# <CJK>
+0x424E	0x631B	# <CJK>
+0x424F	0x5B6A	# <CJK>
+0x4250	0x6EE6	# <CJK>
+0x4251	0x5375	# <CJK>
+0x4252	0x4E71	# <CJK>
+0x4253	0x63A0	# <CJK>
+0x4254	0x7565	# <CJK>
+0x4255	0x62A1	# <CJK>
+0x4256	0x8F6E	# <CJK>
+0x4257	0x4F26	# <CJK>
+0x4258	0x4ED1	# <CJK>
+0x4259	0x6CA6	# <CJK>
+0x425A	0x7EB6	# <CJK>
+0x425B	0x8BBA	# <CJK>
+0x425C	0x841D	# <CJK>
+0x425D	0x87BA	# <CJK>
+0x425E	0x7F57	# <CJK>
+0x425F	0x903B	# <CJK>
+0x4260	0x9523	# <CJK>
+0x4261	0x7BA9	# <CJK>
+0x4262	0x9AA1	# <CJK>
+0x4263	0x88F8	# <CJK>
+0x4264	0x843D	# <CJK>
+0x4265	0x6D1B	# <CJK>
+0x4266	0x9A86	# <CJK>
+0x4267	0x7EDC	# <CJK>
+0x4268	0x5988	# <CJK>
+0x4269	0x9EBB	# <CJK>
+0x426A	0x739B	# <CJK>
+0x426B	0x7801	# <CJK>
+0x426C	0x8682	# <CJK>
+0x426D	0x9A6C	# <CJK>
+0x426E	0x9A82	# <CJK>
+0x426F	0x561B	# <CJK>
+0x4270	0x5417	# <CJK>
+0x4271	0x57CB	# <CJK>
+0x4272	0x4E70	# <CJK>
+0x4273	0x9EA6	# <CJK>
+0x4274	0x5356	# <CJK>
+0x4275	0x8FC8	# <CJK>
+0x4276	0x8109	# <CJK>
+0x4277	0x7792	# <CJK>
+0x4278	0x9992	# <CJK>
+0x4279	0x86EE	# <CJK>
+0x427A	0x6EE1	# <CJK>
+0x427B	0x8513	# <CJK>
+0x427C	0x66FC	# <CJK>
+0x427D	0x6162	# <CJK>
+0x427E	0x6F2B	# <CJK>
+0x4321	0x8C29	# <CJK>
+0x4322	0x8292	# <CJK>
+0x4323	0x832B	# <CJK>
+0x4324	0x76F2	# <CJK>
+0x4325	0x6C13	# <CJK>
+0x4326	0x5FD9	# <CJK>
+0x4327	0x83BD	# <CJK>
+0x4328	0x732B	# <CJK>
+0x4329	0x8305	# <CJK>
+0x432A	0x951A	# <CJK>
+0x432B	0x6BDB	# <CJK>
+0x432C	0x77DB	# <CJK>
+0x432D	0x94C6	# <CJK>
+0x432E	0x536F	# <CJK>
+0x432F	0x8302	# <CJK>
+0x4330	0x5192	# <CJK>
+0x4331	0x5E3D	# <CJK>
+0x4332	0x8C8C	# <CJK>
+0x4333	0x8D38	# <CJK>
+0x4334	0x4E48	# <CJK>
+0x4335	0x73AB	# <CJK>
+0x4336	0x679A	# <CJK>
+0x4337	0x6885	# <CJK>
+0x4338	0x9176	# <CJK>
+0x4339	0x9709	# <CJK>
+0x433A	0x7164	# <CJK>
+0x433B	0x6CA1	# <CJK>
+0x433C	0x7709	# <CJK>
+0x433D	0x5A92	# <CJK>
+0x433E	0x9541	# <CJK>
+0x433F	0x6BCF	# <CJK>
+0x4340	0x7F8E	# <CJK>
+0x4341	0x6627	# <CJK>
+0x4342	0x5BD0	# <CJK>
+0x4343	0x59B9	# <CJK>
+0x4344	0x5A9A	# <CJK>
+0x4345	0x95E8	# <CJK>
+0x4346	0x95F7	# <CJK>
+0x4347	0x4EEC	# <CJK>
+0x4348	0x840C	# <CJK>
+0x4349	0x8499	# <CJK>
+0x434A	0x6AAC	# <CJK>
+0x434B	0x76DF	# <CJK>
+0x434C	0x9530	# <CJK>
+0x434D	0x731B	# <CJK>
+0x434E	0x68A6	# <CJK>
+0x434F	0x5B5F	# <CJK>
+0x4350	0x772F	# <CJK>
+0x4351	0x919A	# <CJK>
+0x4352	0x9761	# <CJK>
+0x4353	0x7CDC	# <CJK>
+0x4354	0x8FF7	# <CJK>
+0x4355	0x8C1C	# <CJK>
+0x4356	0x5F25	# <CJK>
+0x4357	0x7C73	# <CJK>
+0x4358	0x79D8	# <CJK>
+0x4359	0x89C5	# <CJK>
+0x435A	0x6CCC	# <CJK>
+0x435B	0x871C	# <CJK>
+0x435C	0x5BC6	# <CJK>
+0x435D	0x5E42	# <CJK>
+0x435E	0x68C9	# <CJK>
+0x435F	0x7720	# <CJK>
+0x4360	0x7EF5	# <CJK>
+0x4361	0x5195	# <CJK>
+0x4362	0x514D	# <CJK>
+0x4363	0x52C9	# <CJK>
+0x4364	0x5A29	# <CJK>
+0x4365	0x7F05	# <CJK>
+0x4366	0x9762	# <CJK>
+0x4367	0x82D7	# <CJK>
+0x4368	0x63CF	# <CJK>
+0x4369	0x7784	# <CJK>
+0x436A	0x85D0	# <CJK>
+0x436B	0x79D2	# <CJK>
+0x436C	0x6E3A	# <CJK>
+0x436D	0x5E99	# <CJK>
+0x436E	0x5999	# <CJK>
+0x436F	0x8511	# <CJK>
+0x4370	0x706D	# <CJK>
+0x4371	0x6C11	# <CJK>
+0x4372	0x62BF	# <CJK>
+0x4373	0x76BF	# <CJK>
+0x4374	0x654F	# <CJK>
+0x4375	0x60AF	# <CJK>
+0x4376	0x95FD	# <CJK>
+0x4377	0x660E	# <CJK>
+0x4378	0x879F	# <CJK>
+0x4379	0x9E23	# <CJK>
+0x437A	0x94ED	# <CJK>
+0x437B	0x540D	# <CJK>
+0x437C	0x547D	# <CJK>
+0x437D	0x8C2C	# <CJK>
+0x437E	0x6478	# <CJK>
+0x4421	0x6479	# <CJK>
+0x4422	0x8611	# <CJK>
+0x4423	0x6A21	# <CJK>
+0x4424	0x819C	# <CJK>
+0x4425	0x78E8	# <CJK>
+0x4426	0x6469	# <CJK>
+0x4427	0x9B54	# <CJK>
+0x4428	0x62B9	# <CJK>
+0x4429	0x672B	# <CJK>
+0x442A	0x83AB	# <CJK>
+0x442B	0x58A8	# <CJK>
+0x442C	0x9ED8	# <CJK>
+0x442D	0x6CAB	# <CJK>
+0x442E	0x6F20	# <CJK>
+0x442F	0x5BDE	# <CJK>
+0x4430	0x964C	# <CJK>
+0x4431	0x8C0B	# <CJK>
+0x4432	0x725F	# <CJK>
+0x4433	0x67D0	# <CJK>
+0x4434	0x62C7	# <CJK>
+0x4435	0x7261	# <CJK>
+0x4436	0x4EA9	# <CJK>
+0x4437	0x59C6	# <CJK>
+0x4438	0x6BCD	# <CJK>
+0x4439	0x5893	# <CJK>
+0x443A	0x66AE	# <CJK>
+0x443B	0x5E55	# <CJK>
+0x443C	0x52DF	# <CJK>
+0x443D	0x6155	# <CJK>
+0x443E	0x6728	# <CJK>
+0x443F	0x76EE	# <CJK>
+0x4440	0x7766	# <CJK>
+0x4441	0x7267	# <CJK>
+0x4442	0x7A46	# <CJK>
+0x4443	0x62FF	# <CJK>
+0x4444	0x54EA	# <CJK>
+0x4445	0x5450	# <CJK>
+0x4446	0x94A0	# <CJK>
+0x4447	0x90A3	# <CJK>
+0x4448	0x5A1C	# <CJK>
+0x4449	0x7EB3	# <CJK>
+0x444A	0x6C16	# <CJK>
+0x444B	0x4E43	# <CJK>
+0x444C	0x5976	# <CJK>
+0x444D	0x8010	# <CJK>
+0x444E	0x5948	# <CJK>
+0x444F	0x5357	# <CJK>
+0x4450	0x7537	# <CJK>
+0x4451	0x96BE	# <CJK>
+0x4452	0x56CA	# <CJK>
+0x4453	0x6320	# <CJK>
+0x4454	0x8111	# <CJK>
+0x4455	0x607C	# <CJK>
+0x4456	0x95F9	# <CJK>
+0x4457	0x6DD6	# <CJK>
+0x4458	0x5462	# <CJK>
+0x4459	0x9981	# <CJK>
+0x445A	0x5185	# <CJK>
+0x445B	0x5AE9	# <CJK>
+0x445C	0x80FD	# <CJK>
+0x445D	0x59AE	# <CJK>
+0x445E	0x9713	# <CJK>
+0x445F	0x502A	# <CJK>
+0x4460	0x6CE5	# <CJK>
+0x4461	0x5C3C	# <CJK>
+0x4462	0x62DF	# <CJK>
+0x4463	0x4F60	# <CJK>
+0x4464	0x533F	# <CJK>
+0x4465	0x817B	# <CJK>
+0x4466	0x9006	# <CJK>
+0x4467	0x6EBA	# <CJK>
+0x4468	0x852B	# <CJK>
+0x4469	0x62C8	# <CJK>
+0x446A	0x5E74	# <CJK>
+0x446B	0x78BE	# <CJK>
+0x446C	0x64B5	# <CJK>
+0x446D	0x637B	# <CJK>
+0x446E	0x5FF5	# <CJK>
+0x446F	0x5A18	# <CJK>
+0x4470	0x917F	# <CJK>
+0x4471	0x9E1F	# <CJK>
+0x4472	0x5C3F	# <CJK>
+0x4473	0x634F	# <CJK>
+0x4474	0x8042	# <CJK>
+0x4475	0x5B7D	# <CJK>
+0x4476	0x556E	# <CJK>
+0x4477	0x954A	# <CJK>
+0x4478	0x954D	# <CJK>
+0x4479	0x6D85	# <CJK>
+0x447A	0x60A8	# <CJK>
+0x447B	0x67E0	# <CJK>
+0x447C	0x72DE	# <CJK>
+0x447D	0x51DD	# <CJK>
+0x447E	0x5B81	# <CJK>
+0x4521	0x62E7	# <CJK>
+0x4522	0x6CDE	# <CJK>
+0x4523	0x725B	# <CJK>
+0x4524	0x626D	# <CJK>
+0x4525	0x94AE	# <CJK>
+0x4526	0x7EBD	# <CJK>
+0x4527	0x8113	# <CJK>
+0x4528	0x6D53	# <CJK>
+0x4529	0x519C	# <CJK>
+0x452A	0x5F04	# <CJK>
+0x452B	0x5974	# <CJK>
+0x452C	0x52AA	# <CJK>
+0x452D	0x6012	# <CJK>
+0x452E	0x5973	# <CJK>
+0x452F	0x6696	# <CJK>
+0x4530	0x8650	# <CJK>
+0x4531	0x759F	# <CJK>
+0x4532	0x632A	# <CJK>
+0x4533	0x61E6	# <CJK>
+0x4534	0x7CEF	# <CJK>
+0x4535	0x8BFA	# <CJK>
+0x4536	0x54E6	# <CJK>
+0x4537	0x6B27	# <CJK>
+0x4538	0x9E25	# <CJK>
+0x4539	0x6BB4	# <CJK>
+0x453A	0x85D5	# <CJK>
+0x453B	0x5455	# <CJK>
+0x453C	0x5076	# <CJK>
+0x453D	0x6CA4	# <CJK>
+0x453E	0x556A	# <CJK>
+0x453F	0x8DB4	# <CJK>
+0x4540	0x722C	# <CJK>
+0x4541	0x5E15	# <CJK>
+0x4542	0x6015	# <CJK>
+0x4543	0x7436	# <CJK>
+0x4544	0x62CD	# <CJK>
+0x4545	0x6392	# <CJK>
+0x4546	0x724C	# <CJK>
+0x4547	0x5F98	# <CJK>
+0x4548	0x6E43	# <CJK>
+0x4549	0x6D3E	# <CJK>
+0x454A	0x6500	# <CJK>
+0x454B	0x6F58	# <CJK>
+0x454C	0x76D8	# <CJK>
+0x454D	0x78D0	# <CJK>
+0x454E	0x76FC	# <CJK>
+0x454F	0x7554	# <CJK>
+0x4550	0x5224	# <CJK>
+0x4551	0x53DB	# <CJK>
+0x4552	0x4E53	# <CJK>
+0x4553	0x5E9E	# <CJK>
+0x4554	0x65C1	# <CJK>
+0x4555	0x802A	# <CJK>
+0x4556	0x80D6	# <CJK>
+0x4557	0x629B	# <CJK>
+0x4558	0x5486	# <CJK>
+0x4559	0x5228	# <CJK>
+0x455A	0x70AE	# <CJK>
+0x455B	0x888D	# <CJK>
+0x455C	0x8DD1	# <CJK>
+0x455D	0x6CE1	# <CJK>
+0x455E	0x5478	# <CJK>
+0x455F	0x80DA	# <CJK>
+0x4560	0x57F9	# <CJK>
+0x4561	0x88F4	# <CJK>
+0x4562	0x8D54	# <CJK>
+0x4563	0x966A	# <CJK>
+0x4564	0x914D	# <CJK>
+0x4565	0x4F69	# <CJK>
+0x4566	0x6C9B	# <CJK>
+0x4567	0x55B7	# <CJK>
+0x4568	0x76C6	# <CJK>
+0x4569	0x7830	# <CJK>
+0x456A	0x62A8	# <CJK>
+0x456B	0x70F9	# <CJK>
+0x456C	0x6F8E	# <CJK>
+0x456D	0x5F6D	# <CJK>
+0x456E	0x84EC	# <CJK>
+0x456F	0x68DA	# <CJK>
+0x4570	0x787C	# <CJK>
+0x4571	0x7BF7	# <CJK>
+0x4572	0x81A8	# <CJK>
+0x4573	0x670B	# <CJK>
+0x4574	0x9E4F	# <CJK>
+0x4575	0x6367	# <CJK>
+0x4576	0x78B0	# <CJK>
+0x4577	0x576F	# <CJK>
+0x4578	0x7812	# <CJK>
+0x4579	0x9739	# <CJK>
+0x457A	0x6279	# <CJK>
+0x457B	0x62AB	# <CJK>
+0x457C	0x5288	# <CJK>
+0x457D	0x7435	# <CJK>
+0x457E	0x6BD7	# <CJK>
+0x4621	0x5564	# <CJK>
+0x4622	0x813E	# <CJK>
+0x4623	0x75B2	# <CJK>
+0x4624	0x76AE	# <CJK>
+0x4625	0x5339	# <CJK>
+0x4626	0x75DE	# <CJK>
+0x4627	0x50FB	# <CJK>
+0x4628	0x5C41	# <CJK>
+0x4629	0x8B6C	# <CJK>
+0x462A	0x7BC7	# <CJK>
+0x462B	0x504F	# <CJK>
+0x462C	0x7247	# <CJK>
+0x462D	0x9A97	# <CJK>
+0x462E	0x98D8	# <CJK>
+0x462F	0x6F02	# <CJK>
+0x4630	0x74E2	# <CJK>
+0x4631	0x7968	# <CJK>
+0x4632	0x6487	# <CJK>
+0x4633	0x77A5	# <CJK>
+0x4634	0x62FC	# <CJK>
+0x4635	0x9891	# <CJK>
+0x4636	0x8D2B	# <CJK>
+0x4637	0x54C1	# <CJK>
+0x4638	0x8058	# <CJK>
+0x4639	0x4E52	# <CJK>
+0x463A	0x576A	# <CJK>
+0x463B	0x82F9	# <CJK>
+0x463C	0x840D	# <CJK>
+0x463D	0x5E73	# <CJK>
+0x463E	0x51ED	# <CJK>
+0x463F	0x74F6	# <CJK>
+0x4640	0x8BC4	# <CJK>
+0x4641	0x5C4F	# <CJK>
+0x4642	0x5761	# <CJK>
+0x4643	0x6CFC	# <CJK>
+0x4644	0x9887	# <CJK>
+0x4645	0x5A46	# <CJK>
+0x4646	0x7834	# <CJK>
+0x4647	0x9B44	# <CJK>
+0x4648	0x8FEB	# <CJK>
+0x4649	0x7C95	# <CJK>
+0x464A	0x5256	# <CJK>
+0x464B	0x6251	# <CJK>
+0x464C	0x94FA	# <CJK>
+0x464D	0x4EC6	# <CJK>
+0x464E	0x8386	# <CJK>
+0x464F	0x8461	# <CJK>
+0x4650	0x83E9	# <CJK>
+0x4651	0x84B2	# <CJK>
+0x4652	0x57D4	# <CJK>
+0x4653	0x6734	# <CJK>
+0x4654	0x5703	# <CJK>
+0x4655	0x666E	# <CJK>
+0x4656	0x6D66	# <CJK>
+0x4657	0x8C31	# <CJK>
+0x4658	0x66DD	# <CJK>
+0x4659	0x7011	# <CJK>
+0x465A	0x671F	# <CJK>
+0x465B	0x6B3A	# <CJK>
+0x465C	0x6816	# <CJK>
+0x465D	0x621A	# <CJK>
+0x465E	0x59BB	# <CJK>
+0x465F	0x4E03	# <CJK>
+0x4660	0x51C4	# <CJK>
+0x4661	0x6F06	# <CJK>
+0x4662	0x67D2	# <CJK>
+0x4663	0x6C8F	# <CJK>
+0x4664	0x5176	# <CJK>
+0x4665	0x68CB	# <CJK>
+0x4666	0x5947	# <CJK>
+0x4667	0x6B67	# <CJK>
+0x4668	0x7566	# <CJK>
+0x4669	0x5D0E	# <CJK>
+0x466A	0x8110	# <CJK>
+0x466B	0x9F50	# <CJK>
+0x466C	0x65D7	# <CJK>
+0x466D	0x7948	# <CJK>
+0x466E	0x7941	# <CJK>
+0x466F	0x9A91	# <CJK>
+0x4670	0x8D77	# <CJK>
+0x4671	0x5C82	# <CJK>
+0x4672	0x4E5E	# <CJK>
+0x4673	0x4F01	# <CJK>
+0x4674	0x542F	# <CJK>
+0x4675	0x5951	# <CJK>
+0x4676	0x780C	# <CJK>
+0x4677	0x5668	# <CJK>
+0x4678	0x6C14	# <CJK>
+0x4679	0x8FC4	# <CJK>
+0x467A	0x5F03	# <CJK>
+0x467B	0x6C7D	# <CJK>
+0x467C	0x6CE3	# <CJK>
+0x467D	0x8BAB	# <CJK>
+0x467E	0x6390	# <CJK>
+0x4721	0x6070	# <CJK>
+0x4722	0x6D3D	# <CJK>
+0x4723	0x7275	# <CJK>
+0x4724	0x6266	# <CJK>
+0x4725	0x948E	# <CJK>
+0x4726	0x94C5	# <CJK>
+0x4727	0x5343	# <CJK>
+0x4728	0x8FC1	# <CJK>
+0x4729	0x7B7E	# <CJK>
+0x472A	0x4EDF	# <CJK>
+0x472B	0x8C26	# <CJK>
+0x472C	0x4E7E	# <CJK>
+0x472D	0x9ED4	# <CJK>
+0x472E	0x94B1	# <CJK>
+0x472F	0x94B3	# <CJK>
+0x4730	0x524D	# <CJK>
+0x4731	0x6F5C	# <CJK>
+0x4732	0x9063	# <CJK>
+0x4733	0x6D45	# <CJK>
+0x4734	0x8C34	# <CJK>
+0x4735	0x5811	# <CJK>
+0x4736	0x5D4C	# <CJK>
+0x4737	0x6B20	# <CJK>
+0x4738	0x6B49	# <CJK>
+0x4739	0x67AA	# <CJK>
+0x473A	0x545B	# <CJK>
+0x473B	0x8154	# <CJK>
+0x473C	0x7F8C	# <CJK>
+0x473D	0x5899	# <CJK>
+0x473E	0x8537	# <CJK>
+0x473F	0x5F3A	# <CJK>
+0x4740	0x62A2	# <CJK>
+0x4741	0x6A47	# <CJK>
+0x4742	0x9539	# <CJK>
+0x4743	0x6572	# <CJK>
+0x4744	0x6084	# <CJK>
+0x4745	0x6865	# <CJK>
+0x4746	0x77A7	# <CJK>
+0x4747	0x4E54	# <CJK>
+0x4748	0x4FA8	# <CJK>
+0x4749	0x5DE7	# <CJK>
+0x474A	0x9798	# <CJK>
+0x474B	0x64AC	# <CJK>
+0x474C	0x7FD8	# <CJK>
+0x474D	0x5CED	# <CJK>
+0x474E	0x4FCF	# <CJK>
+0x474F	0x7A8D	# <CJK>
+0x4750	0x5207	# <CJK>
+0x4751	0x8304	# <CJK>
+0x4752	0x4E14	# <CJK>
+0x4753	0x602F	# <CJK>
+0x4754	0x7A83	# <CJK>
+0x4755	0x94A6	# <CJK>
+0x4756	0x4FB5	# <CJK>
+0x4757	0x4EB2	# <CJK>
+0x4758	0x79E6	# <CJK>
+0x4759	0x7434	# <CJK>
+0x475A	0x52E4	# <CJK>
+0x475B	0x82B9	# <CJK>
+0x475C	0x64D2	# <CJK>
+0x475D	0x79BD	# <CJK>
+0x475E	0x5BDD	# <CJK>
+0x475F	0x6C81	# <CJK>
+0x4760	0x9752	# <CJK>
+0x4761	0x8F7B	# <CJK>
+0x4762	0x6C22	# <CJK>
+0x4763	0x503E	# <CJK>
+0x4764	0x537F	# <CJK>
+0x4765	0x6E05	# <CJK>
+0x4766	0x64CE	# <CJK>
+0x4767	0x6674	# <CJK>
+0x4768	0x6C30	# <CJK>
+0x4769	0x60C5	# <CJK>
+0x476A	0x9877	# <CJK>
+0x476B	0x8BF7	# <CJK>
+0x476C	0x5E86	# <CJK>
+0x476D	0x743C	# <CJK>
+0x476E	0x7A77	# <CJK>
+0x476F	0x79CB	# <CJK>
+0x4770	0x4E18	# <CJK>
+0x4771	0x90B1	# <CJK>
+0x4772	0x7403	# <CJK>
+0x4773	0x6C42	# <CJK>
+0x4774	0x56DA	# <CJK>
+0x4775	0x914B	# <CJK>
+0x4776	0x6CC5	# <CJK>
+0x4777	0x8D8B	# <CJK>
+0x4778	0x533A	# <CJK>
+0x4779	0x86C6	# <CJK>
+0x477A	0x66F2	# <CJK>
+0x477B	0x8EAF	# <CJK>
+0x477C	0x5C48	# <CJK>
+0x477D	0x9A71	# <CJK>
+0x477E	0x6E20	# <CJK>
+0x4821	0x53D6	# <CJK>
+0x4822	0x5A36	# <CJK>
+0x4823	0x9F8B	# <CJK>
+0x4824	0x8DA3	# <CJK>
+0x4825	0x53BB	# <CJK>
+0x4826	0x5708	# <CJK>
+0x4827	0x98A7	# <CJK>
+0x4828	0x6743	# <CJK>
+0x4829	0x919B	# <CJK>
+0x482A	0x6CC9	# <CJK>
+0x482B	0x5168	# <CJK>
+0x482C	0x75CA	# <CJK>
+0x482D	0x62F3	# <CJK>
+0x482E	0x72AC	# <CJK>
+0x482F	0x5238	# <CJK>
+0x4830	0x529D	# <CJK>
+0x4831	0x7F3A	# <CJK>
+0x4832	0x7094	# <CJK>
+0x4833	0x7638	# <CJK>
+0x4834	0x5374	# <CJK>
+0x4835	0x9E4A	# <CJK>
+0x4836	0x69B7	# <CJK>
+0x4837	0x786E	# <CJK>
+0x4838	0x96C0	# <CJK>
+0x4839	0x88D9	# <CJK>
+0x483A	0x7FA4	# <CJK>
+0x483B	0x7136	# <CJK>
+0x483C	0x71C3	# <CJK>
+0x483D	0x5189	# <CJK>
+0x483E	0x67D3	# <CJK>
+0x483F	0x74E4	# <CJK>
+0x4840	0x58E4	# <CJK>
+0x4841	0x6518	# <CJK>
+0x4842	0x56B7	# <CJK>
+0x4843	0x8BA9	# <CJK>
+0x4844	0x9976	# <CJK>
+0x4845	0x6270	# <CJK>
+0x4846	0x7ED5	# <CJK>
+0x4847	0x60F9	# <CJK>
+0x4848	0x70ED	# <CJK>
+0x4849	0x58EC	# <CJK>
+0x484A	0x4EC1	# <CJK>
+0x484B	0x4EBA	# <CJK>
+0x484C	0x5FCD	# <CJK>
+0x484D	0x97E7	# <CJK>
+0x484E	0x4EFB	# <CJK>
+0x484F	0x8BA4	# <CJK>
+0x4850	0x5203	# <CJK>
+0x4851	0x598A	# <CJK>
+0x4852	0x7EAB	# <CJK>
+0x4853	0x6254	# <CJK>
+0x4854	0x4ECD	# <CJK>
+0x4855	0x65E5	# <CJK>
+0x4856	0x620E	# <CJK>
+0x4857	0x8338	# <CJK>
+0x4858	0x84C9	# <CJK>
+0x4859	0x8363	# <CJK>
+0x485A	0x878D	# <CJK>
+0x485B	0x7194	# <CJK>
+0x485C	0x6EB6	# <CJK>
+0x485D	0x5BB9	# <CJK>
+0x485E	0x7ED2	# <CJK>
+0x485F	0x5197	# <CJK>
+0x4860	0x63C9	# <CJK>
+0x4861	0x67D4	# <CJK>
+0x4862	0x8089	# <CJK>
+0x4863	0x8339	# <CJK>
+0x4864	0x8815	# <CJK>
+0x4865	0x5112	# <CJK>
+0x4866	0x5B7A	# <CJK>
+0x4867	0x5982	# <CJK>
+0x4868	0x8FB1	# <CJK>
+0x4869	0x4E73	# <CJK>
+0x486A	0x6C5D	# <CJK>
+0x486B	0x5165	# <CJK>
+0x486C	0x8925	# <CJK>
+0x486D	0x8F6F	# <CJK>
+0x486E	0x962E	# <CJK>
+0x486F	0x854A	# <CJK>
+0x4870	0x745E	# <CJK>
+0x4871	0x9510	# <CJK>
+0x4872	0x95F0	# <CJK>
+0x4873	0x6DA6	# <CJK>
+0x4874	0x82E5	# <CJK>
+0x4875	0x5F31	# <CJK>
+0x4876	0x6492	# <CJK>
+0x4877	0x6D12	# <CJK>
+0x4878	0x8428	# <CJK>
+0x4879	0x816E	# <CJK>
+0x487A	0x9CC3	# <CJK>
+0x487B	0x585E	# <CJK>
+0x487C	0x8D5B	# <CJK>
+0x487D	0x4E09	# <CJK>
+0x487E	0x53C1	# <CJK>
+0x4921	0x4F1E	# <CJK>
+0x4922	0x6563	# <CJK>
+0x4923	0x6851	# <CJK>
+0x4924	0x55D3	# <CJK>
+0x4925	0x4E27	# <CJK>
+0x4926	0x6414	# <CJK>
+0x4927	0x9A9A	# <CJK>
+0x4928	0x626B	# <CJK>
+0x4929	0x5AC2	# <CJK>
+0x492A	0x745F	# <CJK>
+0x492B	0x8272	# <CJK>
+0x492C	0x6DA9	# <CJK>
+0x492D	0x68EE	# <CJK>
+0x492E	0x50E7	# <CJK>
+0x492F	0x838E	# <CJK>
+0x4930	0x7802	# <CJK>
+0x4931	0x6740	# <CJK>
+0x4932	0x5239	# <CJK>
+0x4933	0x6C99	# <CJK>
+0x4934	0x7EB1	# <CJK>
+0x4935	0x50BB	# <CJK>
+0x4936	0x5565	# <CJK>
+0x4937	0x715E	# <CJK>
+0x4938	0x7B5B	# <CJK>
+0x4939	0x6652	# <CJK>
+0x493A	0x73CA	# <CJK>
+0x493B	0x82EB	# <CJK>
+0x493C	0x6749	# <CJK>
+0x493D	0x5C71	# <CJK>
+0x493E	0x5220	# <CJK>
+0x493F	0x717D	# <CJK>
+0x4940	0x886B	# <CJK>
+0x4941	0x95EA	# <CJK>
+0x4942	0x9655	# <CJK>
+0x4943	0x64C5	# <CJK>
+0x4944	0x8D61	# <CJK>
+0x4945	0x81B3	# <CJK>
+0x4946	0x5584	# <CJK>
+0x4947	0x6C55	# <CJK>
+0x4948	0x6247	# <CJK>
+0x4949	0x7F2E	# <CJK>
+0x494A	0x5892	# <CJK>
+0x494B	0x4F24	# <CJK>
+0x494C	0x5546	# <CJK>
+0x494D	0x8D4F	# <CJK>
+0x494E	0x664C	# <CJK>
+0x494F	0x4E0A	# <CJK>
+0x4950	0x5C1A	# <CJK>
+0x4951	0x88F3	# <CJK>
+0x4952	0x68A2	# <CJK>
+0x4953	0x634E	# <CJK>
+0x4954	0x7A0D	# <CJK>
+0x4955	0x70E7	# <CJK>
+0x4956	0x828D	# <CJK>
+0x4957	0x52FA	# <CJK>
+0x4958	0x97F6	# <CJK>
+0x4959	0x5C11	# <CJK>
+0x495A	0x54E8	# <CJK>
+0x495B	0x90B5	# <CJK>
+0x495C	0x7ECD	# <CJK>
+0x495D	0x5962	# <CJK>
+0x495E	0x8D4A	# <CJK>
+0x495F	0x86C7	# <CJK>
+0x4960	0x820C	# <CJK>
+0x4961	0x820D	# <CJK>
+0x4962	0x8D66	# <CJK>
+0x4963	0x6444	# <CJK>
+0x4964	0x5C04	# <CJK>
+0x4965	0x6151	# <CJK>
+0x4966	0x6D89	# <CJK>
+0x4967	0x793E	# <CJK>
+0x4968	0x8BBE	# <CJK>
+0x4969	0x7837	# <CJK>
+0x496A	0x7533	# <CJK>
+0x496B	0x547B	# <CJK>
+0x496C	0x4F38	# <CJK>
+0x496D	0x8EAB	# <CJK>
+0x496E	0x6DF1	# <CJK>
+0x496F	0x5A20	# <CJK>
+0x4970	0x7EC5	# <CJK>
+0x4971	0x795E	# <CJK>
+0x4972	0x6C88	# <CJK>
+0x4973	0x5BA1	# <CJK>
+0x4974	0x5A76	# <CJK>
+0x4975	0x751A	# <CJK>
+0x4976	0x80BE	# <CJK>
+0x4977	0x614E	# <CJK>
+0x4978	0x6E17	# <CJK>
+0x4979	0x58F0	# <CJK>
+0x497A	0x751F	# <CJK>
+0x497B	0x7525	# <CJK>
+0x497C	0x7272	# <CJK>
+0x497D	0x5347	# <CJK>
+0x497E	0x7EF3	# <CJK>
+0x4A21	0x7701	# <CJK>
+0x4A22	0x76DB	# <CJK>
+0x4A23	0x5269	# <CJK>
+0x4A24	0x80DC	# <CJK>
+0x4A25	0x5723	# <CJK>
+0x4A26	0x5E08	# <CJK>
+0x4A27	0x5931	# <CJK>
+0x4A28	0x72EE	# <CJK>
+0x4A29	0x65BD	# <CJK>
+0x4A2A	0x6E7F	# <CJK>
+0x4A2B	0x8BD7	# <CJK>
+0x4A2C	0x5C38	# <CJK>
+0x4A2D	0x8671	# <CJK>
+0x4A2E	0x5341	# <CJK>
+0x4A2F	0x77F3	# <CJK>
+0x4A30	0x62FE	# <CJK>
+0x4A31	0x65F6	# <CJK>
+0x4A32	0x4EC0	# <CJK>
+0x4A33	0x98DF	# <CJK>
+0x4A34	0x8680	# <CJK>
+0x4A35	0x5B9E	# <CJK>
+0x4A36	0x8BC6	# <CJK>
+0x4A37	0x53F2	# <CJK>
+0x4A38	0x77E2	# <CJK>
+0x4A39	0x4F7F	# <CJK>
+0x4A3A	0x5C4E	# <CJK>
+0x4A3B	0x9A76	# <CJK>
+0x4A3C	0x59CB	# <CJK>
+0x4A3D	0x5F0F	# <CJK>
+0x4A3E	0x793A	# <CJK>
+0x4A3F	0x58EB	# <CJK>
+0x4A40	0x4E16	# <CJK>
+0x4A41	0x67FF	# <CJK>
+0x4A42	0x4E8B	# <CJK>
+0x4A43	0x62ED	# <CJK>
+0x4A44	0x8A93	# <CJK>
+0x4A45	0x901D	# <CJK>
+0x4A46	0x52BF	# <CJK>
+0x4A47	0x662F	# <CJK>
+0x4A48	0x55DC	# <CJK>
+0x4A49	0x566C	# <CJK>
+0x4A4A	0x9002	# <CJK>
+0x4A4B	0x4ED5	# <CJK>
+0x4A4C	0x4F8D	# <CJK>
+0x4A4D	0x91CA	# <CJK>
+0x4A4E	0x9970	# <CJK>
+0x4A4F	0x6C0F	# <CJK>
+0x4A50	0x5E02	# <CJK>
+0x4A51	0x6043	# <CJK>
+0x4A52	0x5BA4	# <CJK>
+0x4A53	0x89C6	# <CJK>
+0x4A54	0x8BD5	# <CJK>
+0x4A55	0x6536	# <CJK>
+0x4A56	0x624B	# <CJK>
+0x4A57	0x9996	# <CJK>
+0x4A58	0x5B88	# <CJK>
+0x4A59	0x5BFF	# <CJK>
+0x4A5A	0x6388	# <CJK>
+0x4A5B	0x552E	# <CJK>
+0x4A5C	0x53D7	# <CJK>
+0x4A5D	0x7626	# <CJK>
+0x4A5E	0x517D	# <CJK>
+0x4A5F	0x852C	# <CJK>
+0x4A60	0x67A2	# <CJK>
+0x4A61	0x68B3	# <CJK>
+0x4A62	0x6B8A	# <CJK>
+0x4A63	0x6292	# <CJK>
+0x4A64	0x8F93	# <CJK>
+0x4A65	0x53D4	# <CJK>
+0x4A66	0x8212	# <CJK>
+0x4A67	0x6DD1	# <CJK>
+0x4A68	0x758F	# <CJK>
+0x4A69	0x4E66	# <CJK>
+0x4A6A	0x8D4E	# <CJK>
+0x4A6B	0x5B70	# <CJK>
+0x4A6C	0x719F	# <CJK>
+0x4A6D	0x85AF	# <CJK>
+0x4A6E	0x6691	# <CJK>
+0x4A6F	0x66D9	# <CJK>
+0x4A70	0x7F72	# <CJK>
+0x4A71	0x8700	# <CJK>
+0x4A72	0x9ECD	# <CJK>
+0x4A73	0x9F20	# <CJK>
+0x4A74	0x5C5E	# <CJK>
+0x4A75	0x672F	# <CJK>
+0x4A76	0x8FF0	# <CJK>
+0x4A77	0x6811	# <CJK>
+0x4A78	0x675F	# <CJK>
+0x4A79	0x620D	# <CJK>
+0x4A7A	0x7AD6	# <CJK>
+0x4A7B	0x5885	# <CJK>
+0x4A7C	0x5EB6	# <CJK>
+0x4A7D	0x6570	# <CJK>
+0x4A7E	0x6F31	# <CJK>
+0x4B21	0x6055	# <CJK>
+0x4B22	0x5237	# <CJK>
+0x4B23	0x800D	# <CJK>
+0x4B24	0x6454	# <CJK>
+0x4B25	0x8870	# <CJK>
+0x4B26	0x7529	# <CJK>
+0x4B27	0x5E05	# <CJK>
+0x4B28	0x6813	# <CJK>
+0x4B29	0x62F4	# <CJK>
+0x4B2A	0x971C	# <CJK>
+0x4B2B	0x53CC	# <CJK>
+0x4B2C	0x723D	# <CJK>
+0x4B2D	0x8C01	# <CJK>
+0x4B2E	0x6C34	# <CJK>
+0x4B2F	0x7761	# <CJK>
+0x4B30	0x7A0E	# <CJK>
+0x4B31	0x542E	# <CJK>
+0x4B32	0x77AC	# <CJK>
+0x4B33	0x987A	# <CJK>
+0x4B34	0x821C	# <CJK>
+0x4B35	0x8BF4	# <CJK>
+0x4B36	0x7855	# <CJK>
+0x4B37	0x6714	# <CJK>
+0x4B38	0x70C1	# <CJK>
+0x4B39	0x65AF	# <CJK>
+0x4B3A	0x6495	# <CJK>
+0x4B3B	0x5636	# <CJK>
+0x4B3C	0x601D	# <CJK>
+0x4B3D	0x79C1	# <CJK>
+0x4B3E	0x53F8	# <CJK>
+0x4B3F	0x4E1D	# <CJK>
+0x4B40	0x6B7B	# <CJK>
+0x4B41	0x8086	# <CJK>
+0x4B42	0x5BFA	# <CJK>
+0x4B43	0x55E3	# <CJK>
+0x4B44	0x56DB	# <CJK>
+0x4B45	0x4F3A	# <CJK>
+0x4B46	0x4F3C	# <CJK>
+0x4B47	0x9972	# <CJK>
+0x4B48	0x5DF3	# <CJK>
+0x4B49	0x677E	# <CJK>
+0x4B4A	0x8038	# <CJK>
+0x4B4B	0x6002	# <CJK>
+0x4B4C	0x9882	# <CJK>
+0x4B4D	0x9001	# <CJK>
+0x4B4E	0x5B8B	# <CJK>
+0x4B4F	0x8BBC	# <CJK>
+0x4B50	0x8BF5	# <CJK>
+0x4B51	0x641C	# <CJK>
+0x4B52	0x8258	# <CJK>
+0x4B53	0x64DE	# <CJK>
+0x4B54	0x55FD	# <CJK>
+0x4B55	0x82CF	# <CJK>
+0x4B56	0x9165	# <CJK>
+0x4B57	0x4FD7	# <CJK>
+0x4B58	0x7D20	# <CJK>
+0x4B59	0x901F	# <CJK>
+0x4B5A	0x7C9F	# <CJK>
+0x4B5B	0x50F3	# <CJK>
+0x4B5C	0x5851	# <CJK>
+0x4B5D	0x6EAF	# <CJK>
+0x4B5E	0x5BBF	# <CJK>
+0x4B5F	0x8BC9	# <CJK>
+0x4B60	0x8083	# <CJK>
+0x4B61	0x9178	# <CJK>
+0x4B62	0x849C	# <CJK>
+0x4B63	0x7B97	# <CJK>
+0x4B64	0x867D	# <CJK>
+0x4B65	0x968B	# <CJK>
+0x4B66	0x968F	# <CJK>
+0x4B67	0x7EE5	# <CJK>
+0x4B68	0x9AD3	# <CJK>
+0x4B69	0x788E	# <CJK>
+0x4B6A	0x5C81	# <CJK>
+0x4B6B	0x7A57	# <CJK>
+0x4B6C	0x9042	# <CJK>
+0x4B6D	0x96A7	# <CJK>
+0x4B6E	0x795F	# <CJK>
+0x4B6F	0x5B59	# <CJK>
+0x4B70	0x635F	# <CJK>
+0x4B71	0x7B0B	# <CJK>
+0x4B72	0x84D1	# <CJK>
+0x4B73	0x68AD	# <CJK>
+0x4B74	0x5506	# <CJK>
+0x4B75	0x7F29	# <CJK>
+0x4B76	0x7410	# <CJK>
+0x4B77	0x7D22	# <CJK>
+0x4B78	0x9501	# <CJK>
+0x4B79	0x6240	# <CJK>
+0x4B7A	0x584C	# <CJK>
+0x4B7B	0x4ED6	# <CJK>
+0x4B7C	0x5B83	# <CJK>
+0x4B7D	0x5979	# <CJK>
+0x4B7E	0x5854	# <CJK>
+0x4C21	0x736D	# <CJK>
+0x4C22	0x631E	# <CJK>
+0x4C23	0x8E4B	# <CJK>
+0x4C24	0x8E0F	# <CJK>
+0x4C25	0x80CE	# <CJK>
+0x4C26	0x82D4	# <CJK>
+0x4C27	0x62AC	# <CJK>
+0x4C28	0x53F0	# <CJK>
+0x4C29	0x6CF0	# <CJK>
+0x4C2A	0x915E	# <CJK>
+0x4C2B	0x592A	# <CJK>
+0x4C2C	0x6001	# <CJK>
+0x4C2D	0x6C70	# <CJK>
+0x4C2E	0x574D	# <CJK>
+0x4C2F	0x644A	# <CJK>
+0x4C30	0x8D2A	# <CJK>
+0x4C31	0x762B	# <CJK>
+0x4C32	0x6EE9	# <CJK>
+0x4C33	0x575B	# <CJK>
+0x4C34	0x6A80	# <CJK>
+0x4C35	0x75F0	# <CJK>
+0x4C36	0x6F6D	# <CJK>
+0x4C37	0x8C2D	# <CJK>
+0x4C38	0x8C08	# <CJK>
+0x4C39	0x5766	# <CJK>
+0x4C3A	0x6BEF	# <CJK>
+0x4C3B	0x8892	# <CJK>
+0x4C3C	0x78B3	# <CJK>
+0x4C3D	0x63A2	# <CJK>
+0x4C3E	0x53F9	# <CJK>
+0x4C3F	0x70AD	# <CJK>
+0x4C40	0x6C64	# <CJK>
+0x4C41	0x5858	# <CJK>
+0x4C42	0x642A	# <CJK>
+0x4C43	0x5802	# <CJK>
+0x4C44	0x68E0	# <CJK>
+0x4C45	0x819B	# <CJK>
+0x4C46	0x5510	# <CJK>
+0x4C47	0x7CD6	# <CJK>
+0x4C48	0x5018	# <CJK>
+0x4C49	0x8EBA	# <CJK>
+0x4C4A	0x6DCC	# <CJK>
+0x4C4B	0x8D9F	# <CJK>
+0x4C4C	0x70EB	# <CJK>
+0x4C4D	0x638F	# <CJK>
+0x4C4E	0x6D9B	# <CJK>
+0x4C4F	0x6ED4	# <CJK>
+0x4C50	0x7EE6	# <CJK>
+0x4C51	0x8404	# <CJK>
+0x4C52	0x6843	# <CJK>
+0x4C53	0x9003	# <CJK>
+0x4C54	0x6DD8	# <CJK>
+0x4C55	0x9676	# <CJK>
+0x4C56	0x8BA8	# <CJK>
+0x4C57	0x5957	# <CJK>
+0x4C58	0x7279	# <CJK>
+0x4C59	0x85E4	# <CJK>
+0x4C5A	0x817E	# <CJK>
+0x4C5B	0x75BC	# <CJK>
+0x4C5C	0x8A8A	# <CJK>
+0x4C5D	0x68AF	# <CJK>
+0x4C5E	0x5254	# <CJK>
+0x4C5F	0x8E22	# <CJK>
+0x4C60	0x9511	# <CJK>
+0x4C61	0x63D0	# <CJK>
+0x4C62	0x9898	# <CJK>
+0x4C63	0x8E44	# <CJK>
+0x4C64	0x557C	# <CJK>
+0x4C65	0x4F53	# <CJK>
+0x4C66	0x66FF	# <CJK>
+0x4C67	0x568F	# <CJK>
+0x4C68	0x60D5	# <CJK>
+0x4C69	0x6D95	# <CJK>
+0x4C6A	0x5243	# <CJK>
+0x4C6B	0x5C49	# <CJK>
+0x4C6C	0x5929	# <CJK>
+0x4C6D	0x6DFB	# <CJK>
+0x4C6E	0x586B	# <CJK>
+0x4C6F	0x7530	# <CJK>
+0x4C70	0x751C	# <CJK>
+0x4C71	0x606C	# <CJK>
+0x4C72	0x8214	# <CJK>
+0x4C73	0x8146	# <CJK>
+0x4C74	0x6311	# <CJK>
+0x4C75	0x6761	# <CJK>
+0x4C76	0x8FE2	# <CJK>
+0x4C77	0x773A	# <CJK>
+0x4C78	0x8DF3	# <CJK>
+0x4C79	0x8D34	# <CJK>
+0x4C7A	0x94C1	# <CJK>
+0x4C7B	0x5E16	# <CJK>
+0x4C7C	0x5385	# <CJK>
+0x4C7D	0x542C	# <CJK>
+0x4C7E	0x70C3	# <CJK>
+0x4D21	0x6C40	# <CJK>
+0x4D22	0x5EF7	# <CJK>
+0x4D23	0x505C	# <CJK>
+0x4D24	0x4EAD	# <CJK>
+0x4D25	0x5EAD	# <CJK>
+0x4D26	0x633A	# <CJK>
+0x4D27	0x8247	# <CJK>
+0x4D28	0x901A	# <CJK>
+0x4D29	0x6850	# <CJK>
+0x4D2A	0x916E	# <CJK>
+0x4D2B	0x77B3	# <CJK>
+0x4D2C	0x540C	# <CJK>
+0x4D2D	0x94DC	# <CJK>
+0x4D2E	0x5F64	# <CJK>
+0x4D2F	0x7AE5	# <CJK>
+0x4D30	0x6876	# <CJK>
+0x4D31	0x6345	# <CJK>
+0x4D32	0x7B52	# <CJK>
+0x4D33	0x7EDF	# <CJK>
+0x4D34	0x75DB	# <CJK>
+0x4D35	0x5077	# <CJK>
+0x4D36	0x6295	# <CJK>
+0x4D37	0x5934	# <CJK>
+0x4D38	0x900F	# <CJK>
+0x4D39	0x51F8	# <CJK>
+0x4D3A	0x79C3	# <CJK>
+0x4D3B	0x7A81	# <CJK>
+0x4D3C	0x56FE	# <CJK>
+0x4D3D	0x5F92	# <CJK>
+0x4D3E	0x9014	# <CJK>
+0x4D3F	0x6D82	# <CJK>
+0x4D40	0x5C60	# <CJK>
+0x4D41	0x571F	# <CJK>
+0x4D42	0x5410	# <CJK>
+0x4D43	0x5154	# <CJK>
+0x4D44	0x6E4D	# <CJK>
+0x4D45	0x56E2	# <CJK>
+0x4D46	0x63A8	# <CJK>
+0x4D47	0x9893	# <CJK>
+0x4D48	0x817F	# <CJK>
+0x4D49	0x8715	# <CJK>
+0x4D4A	0x892A	# <CJK>
+0x4D4B	0x9000	# <CJK>
+0x4D4C	0x541E	# <CJK>
+0x4D4D	0x5C6F	# <CJK>
+0x4D4E	0x81C0	# <CJK>
+0x4D4F	0x62D6	# <CJK>
+0x4D50	0x6258	# <CJK>
+0x4D51	0x8131	# <CJK>
+0x4D52	0x9E35	# <CJK>
+0x4D53	0x9640	# <CJK>
+0x4D54	0x9A6E	# <CJK>
+0x4D55	0x9A7C	# <CJK>
+0x4D56	0x692D	# <CJK>
+0x4D57	0x59A5	# <CJK>
+0x4D58	0x62D3	# <CJK>
+0x4D59	0x553E	# <CJK>
+0x4D5A	0x6316	# <CJK>
+0x4D5B	0x54C7	# <CJK>
+0x4D5C	0x86D9	# <CJK>
+0x4D5D	0x6D3C	# <CJK>
+0x4D5E	0x5A03	# <CJK>
+0x4D5F	0x74E6	# <CJK>
+0x4D60	0x889C	# <CJK>
+0x4D61	0x6B6A	# <CJK>
+0x4D62	0x5916	# <CJK>
+0x4D63	0x8C4C	# <CJK>
+0x4D64	0x5F2F	# <CJK>
+0x4D65	0x6E7E	# <CJK>
+0x4D66	0x73A9	# <CJK>
+0x4D67	0x987D	# <CJK>
+0x4D68	0x4E38	# <CJK>
+0x4D69	0x70F7	# <CJK>
+0x4D6A	0x5B8C	# <CJK>
+0x4D6B	0x7897	# <CJK>
+0x4D6C	0x633D	# <CJK>
+0x4D6D	0x665A	# <CJK>
+0x4D6E	0x7696	# <CJK>
+0x4D6F	0x60CB	# <CJK>
+0x4D70	0x5B9B	# <CJK>
+0x4D71	0x5A49	# <CJK>
+0x4D72	0x4E07	# <CJK>
+0x4D73	0x8155	# <CJK>
+0x4D74	0x6C6A	# <CJK>
+0x4D75	0x738B	# <CJK>
+0x4D76	0x4EA1	# <CJK>
+0x4D77	0x6789	# <CJK>
+0x4D78	0x7F51	# <CJK>
+0x4D79	0x5F80	# <CJK>
+0x4D7A	0x65FA	# <CJK>
+0x4D7B	0x671B	# <CJK>
+0x4D7C	0x5FD8	# <CJK>
+0x4D7D	0x5984	# <CJK>
+0x4D7E	0x5A01	# <CJK>
+0x4E21	0x5DCD	# <CJK>
+0x4E22	0x5FAE	# <CJK>
+0x4E23	0x5371	# <CJK>
+0x4E24	0x97E6	# <CJK>
+0x4E25	0x8FDD	# <CJK>
+0x4E26	0x6845	# <CJK>
+0x4E27	0x56F4	# <CJK>
+0x4E28	0x552F	# <CJK>
+0x4E29	0x60DF	# <CJK>
+0x4E2A	0x4E3A	# <CJK>
+0x4E2B	0x6F4D	# <CJK>
+0x4E2C	0x7EF4	# <CJK>
+0x4E2D	0x82C7	# <CJK>
+0x4E2E	0x840E	# <CJK>
+0x4E2F	0x59D4	# <CJK>
+0x4E30	0x4F1F	# <CJK>
+0x4E31	0x4F2A	# <CJK>
+0x4E32	0x5C3E	# <CJK>
+0x4E33	0x7EAC	# <CJK>
+0x4E34	0x672A	# <CJK>
+0x4E35	0x851A	# <CJK>
+0x4E36	0x5473	# <CJK>
+0x4E37	0x754F	# <CJK>
+0x4E38	0x80C3	# <CJK>
+0x4E39	0x5582	# <CJK>
+0x4E3A	0x9B4F	# <CJK>
+0x4E3B	0x4F4D	# <CJK>
+0x4E3C	0x6E2D	# <CJK>
+0x4E3D	0x8C13	# <CJK>
+0x4E3E	0x5C09	# <CJK>
+0x4E3F	0x6170	# <CJK>
+0x4E40	0x536B	# <CJK>
+0x4E41	0x761F	# <CJK>
+0x4E42	0x6E29	# <CJK>
+0x4E43	0x868A	# <CJK>
+0x4E44	0x6587	# <CJK>
+0x4E45	0x95FB	# <CJK>
+0x4E46	0x7EB9	# <CJK>
+0x4E47	0x543B	# <CJK>
+0x4E48	0x7A33	# <CJK>
+0x4E49	0x7D0A	# <CJK>
+0x4E4A	0x95EE	# <CJK>
+0x4E4B	0x55E1	# <CJK>
+0x4E4C	0x7FC1	# <CJK>
+0x4E4D	0x74EE	# <CJK>
+0x4E4E	0x631D	# <CJK>
+0x4E4F	0x8717	# <CJK>
+0x4E50	0x6DA1	# <CJK>
+0x4E51	0x7A9D	# <CJK>
+0x4E52	0x6211	# <CJK>
+0x4E53	0x65A1	# <CJK>
+0x4E54	0x5367	# <CJK>
+0x4E55	0x63E1	# <CJK>
+0x4E56	0x6C83	# <CJK>
+0x4E57	0x5DEB	# <CJK>
+0x4E58	0x545C	# <CJK>
+0x4E59	0x94A8	# <CJK>
+0x4E5A	0x4E4C	# <CJK>
+0x4E5B	0x6C61	# <CJK>
+0x4E5C	0x8BEC	# <CJK>
+0x4E5D	0x5C4B	# <CJK>
+0x4E5E	0x65E0	# <CJK>
+0x4E5F	0x829C	# <CJK>
+0x4E60	0x68A7	# <CJK>
+0x4E61	0x543E	# <CJK>
+0x4E62	0x5434	# <CJK>
+0x4E63	0x6BCB	# <CJK>
+0x4E64	0x6B66	# <CJK>
+0x4E65	0x4E94	# <CJK>
+0x4E66	0x6342	# <CJK>
+0x4E67	0x5348	# <CJK>
+0x4E68	0x821E	# <CJK>
+0x4E69	0x4F0D	# <CJK>
+0x4E6A	0x4FAE	# <CJK>
+0x4E6B	0x575E	# <CJK>
+0x4E6C	0x620A	# <CJK>
+0x4E6D	0x96FE	# <CJK>
+0x4E6E	0x6664	# <CJK>
+0x4E6F	0x7269	# <CJK>
+0x4E70	0x52FF	# <CJK>
+0x4E71	0x52A1	# <CJK>
+0x4E72	0x609F	# <CJK>
+0x4E73	0x8BEF	# <CJK>
+0x4E74	0x6614	# <CJK>
+0x4E75	0x7199	# <CJK>
+0x4E76	0x6790	# <CJK>
+0x4E77	0x897F	# <CJK>
+0x4E78	0x7852	# <CJK>
+0x4E79	0x77FD	# <CJK>
+0x4E7A	0x6670	# <CJK>
+0x4E7B	0x563B	# <CJK>
+0x4E7C	0x5438	# <CJK>
+0x4E7D	0x9521	# <CJK>
+0x4E7E	0x727A	# <CJK>
+0x4F21	0x7A00	# <CJK>
+0x4F22	0x606F	# <CJK>
+0x4F23	0x5E0C	# <CJK>
+0x4F24	0x6089	# <CJK>
+0x4F25	0x819D	# <CJK>
+0x4F26	0x5915	# <CJK>
+0x4F27	0x60DC	# <CJK>
+0x4F28	0x7184	# <CJK>
+0x4F29	0x70EF	# <CJK>
+0x4F2A	0x6EAA	# <CJK>
+0x4F2B	0x6C50	# <CJK>
+0x4F2C	0x7280	# <CJK>
+0x4F2D	0x6A84	# <CJK>
+0x4F2E	0x88AD	# <CJK>
+0x4F2F	0x5E2D	# <CJK>
+0x4F30	0x4E60	# <CJK>
+0x4F31	0x5AB3	# <CJK>
+0x4F32	0x559C	# <CJK>
+0x4F33	0x94E3	# <CJK>
+0x4F34	0x6D17	# <CJK>
+0x4F35	0x7CFB	# <CJK>
+0x4F36	0x9699	# <CJK>
+0x4F37	0x620F	# <CJK>
+0x4F38	0x7EC6	# <CJK>
+0x4F39	0x778E	# <CJK>
+0x4F3A	0x867E	# <CJK>
+0x4F3B	0x5323	# <CJK>
+0x4F3C	0x971E	# <CJK>
+0x4F3D	0x8F96	# <CJK>
+0x4F3E	0x6687	# <CJK>
+0x4F3F	0x5CE1	# <CJK>
+0x4F40	0x4FA0	# <CJK>
+0x4F41	0x72ED	# <CJK>
+0x4F42	0x4E0B	# <CJK>
+0x4F43	0x53A6	# <CJK>
+0x4F44	0x590F	# <CJK>
+0x4F45	0x5413	# <CJK>
+0x4F46	0x6380	# <CJK>
+0x4F47	0x9528	# <CJK>
+0x4F48	0x5148	# <CJK>
+0x4F49	0x4ED9	# <CJK>
+0x4F4A	0x9C9C	# <CJK>
+0x4F4B	0x7EA4	# <CJK>
+0x4F4C	0x54B8	# <CJK>
+0x4F4D	0x8D24	# <CJK>
+0x4F4E	0x8854	# <CJK>
+0x4F4F	0x8237	# <CJK>
+0x4F50	0x95F2	# <CJK>
+0x4F51	0x6D8E	# <CJK>
+0x4F52	0x5F26	# <CJK>
+0x4F53	0x5ACC	# <CJK>
+0x4F54	0x663E	# <CJK>
+0x4F55	0x9669	# <CJK>
+0x4F56	0x73B0	# <CJK>
+0x4F57	0x732E	# <CJK>
+0x4F58	0x53BF	# <CJK>
+0x4F59	0x817A	# <CJK>
+0x4F5A	0x9985	# <CJK>
+0x4F5B	0x7FA1	# <CJK>
+0x4F5C	0x5BAA	# <CJK>
+0x4F5D	0x9677	# <CJK>
+0x4F5E	0x9650	# <CJK>
+0x4F5F	0x7EBF	# <CJK>
+0x4F60	0x76F8	# <CJK>
+0x4F61	0x53A2	# <CJK>
+0x4F62	0x9576	# <CJK>
+0x4F63	0x9999	# <CJK>
+0x4F64	0x7BB1	# <CJK>
+0x4F65	0x8944	# <CJK>
+0x4F66	0x6E58	# <CJK>
+0x4F67	0x4E61	# <CJK>
+0x4F68	0x7FD4	# <CJK>
+0x4F69	0x7965	# <CJK>
+0x4F6A	0x8BE6	# <CJK>
+0x4F6B	0x60F3	# <CJK>
+0x4F6C	0x54CD	# <CJK>
+0x4F6D	0x4EAB	# <CJK>
+0x4F6E	0x9879	# <CJK>
+0x4F6F	0x5DF7	# <CJK>
+0x4F70	0x6A61	# <CJK>
+0x4F71	0x50CF	# <CJK>
+0x4F72	0x5411	# <CJK>
+0x4F73	0x8C61	# <CJK>
+0x4F74	0x8427	# <CJK>
+0x4F75	0x785D	# <CJK>
+0x4F76	0x9704	# <CJK>
+0x4F77	0x524A	# <CJK>
+0x4F78	0x54EE	# <CJK>
+0x4F79	0x56A3	# <CJK>
+0x4F7A	0x9500	# <CJK>
+0x4F7B	0x6D88	# <CJK>
+0x4F7C	0x5BB5	# <CJK>
+0x4F7D	0x6DC6	# <CJK>
+0x4F7E	0x6653	# <CJK>
+0x5021	0x5C0F	# <CJK>
+0x5022	0x5B5D	# <CJK>
+0x5023	0x6821	# <CJK>
+0x5024	0x8096	# <CJK>
+0x5025	0x5578	# <CJK>
+0x5026	0x7B11	# <CJK>
+0x5027	0x6548	# <CJK>
+0x5028	0x6954	# <CJK>
+0x5029	0x4E9B	# <CJK>
+0x502A	0x6B47	# <CJK>
+0x502B	0x874E	# <CJK>
+0x502C	0x978B	# <CJK>
+0x502D	0x534F	# <CJK>
+0x502E	0x631F	# <CJK>
+0x502F	0x643A	# <CJK>
+0x5030	0x90AA	# <CJK>
+0x5031	0x659C	# <CJK>
+0x5032	0x80C1	# <CJK>
+0x5033	0x8C10	# <CJK>
+0x5034	0x5199	# <CJK>
+0x5035	0x68B0	# <CJK>
+0x5036	0x5378	# <CJK>
+0x5037	0x87F9	# <CJK>
+0x5038	0x61C8	# <CJK>
+0x5039	0x6CC4	# <CJK>
+0x503A	0x6CFB	# <CJK>
+0x503B	0x8C22	# <CJK>
+0x503C	0x5C51	# <CJK>
+0x503D	0x85AA	# <CJK>
+0x503E	0x82AF	# <CJK>
+0x503F	0x950C	# <CJK>
+0x5040	0x6B23	# <CJK>
+0x5041	0x8F9B	# <CJK>
+0x5042	0x65B0	# <CJK>
+0x5043	0x5FFB	# <CJK>
+0x5044	0x5FC3	# <CJK>
+0x5045	0x4FE1	# <CJK>
+0x5046	0x8845	# <CJK>
+0x5047	0x661F	# <CJK>
+0x5048	0x8165	# <CJK>
+0x5049	0x7329	# <CJK>
+0x504A	0x60FA	# <CJK>
+0x504B	0x5174	# <CJK>
+0x504C	0x5211	# <CJK>
+0x504D	0x578B	# <CJK>
+0x504E	0x5F62	# <CJK>
+0x504F	0x90A2	# <CJK>
+0x5050	0x884C	# <CJK>
+0x5051	0x9192	# <CJK>
+0x5052	0x5E78	# <CJK>
+0x5053	0x674F	# <CJK>
+0x5054	0x6027	# <CJK>
+0x5055	0x59D3	# <CJK>
+0x5056	0x5144	# <CJK>
+0x5057	0x51F6	# <CJK>
+0x5058	0x80F8	# <CJK>
+0x5059	0x5308	# <CJK>
+0x505A	0x6C79	# <CJK>
+0x505B	0x96C4	# <CJK>
+0x505C	0x718A	# <CJK>
+0x505D	0x4F11	# <CJK>
+0x505E	0x4FEE	# <CJK>
+0x505F	0x7F9E	# <CJK>
+0x5060	0x673D	# <CJK>
+0x5061	0x55C5	# <CJK>
+0x5062	0x9508	# <CJK>
+0x5063	0x79C0	# <CJK>
+0x5064	0x8896	# <CJK>
+0x5065	0x7EE3	# <CJK>
+0x5066	0x589F	# <CJK>
+0x5067	0x620C	# <CJK>
+0x5068	0x9700	# <CJK>
+0x5069	0x865A	# <CJK>
+0x506A	0x5618	# <CJK>
+0x506B	0x987B	# <CJK>
+0x506C	0x5F90	# <CJK>
+0x506D	0x8BB8	# <CJK>
+0x506E	0x84C4	# <CJK>
+0x506F	0x9157	# <CJK>
+0x5070	0x53D9	# <CJK>
+0x5071	0x65ED	# <CJK>
+0x5072	0x5E8F	# <CJK>
+0x5073	0x755C	# <CJK>
+0x5074	0x6064	# <CJK>
+0x5075	0x7D6E	# <CJK>
+0x5076	0x5A7F	# <CJK>
+0x5077	0x7EEA	# <CJK>
+0x5078	0x7EED	# <CJK>
+0x5079	0x8F69	# <CJK>
+0x507A	0x55A7	# <CJK>
+0x507B	0x5BA3	# <CJK>
+0x507C	0x60AC	# <CJK>
+0x507D	0x65CB	# <CJK>
+0x507E	0x7384	# <CJK>
+0x5121	0x9009	# <CJK>
+0x5122	0x7663	# <CJK>
+0x5123	0x7729	# <CJK>
+0x5124	0x7EDA	# <CJK>
+0x5125	0x9774	# <CJK>
+0x5126	0x859B	# <CJK>
+0x5127	0x5B66	# <CJK>
+0x5128	0x7A74	# <CJK>
+0x5129	0x96EA	# <CJK>
+0x512A	0x8840	# <CJK>
+0x512B	0x52CB	# <CJK>
+0x512C	0x718F	# <CJK>
+0x512D	0x5FAA	# <CJK>
+0x512E	0x65EC	# <CJK>
+0x512F	0x8BE2	# <CJK>
+0x5130	0x5BFB	# <CJK>
+0x5131	0x9A6F	# <CJK>
+0x5132	0x5DE1	# <CJK>
+0x5133	0x6B89	# <CJK>
+0x5134	0x6C5B	# <CJK>
+0x5135	0x8BAD	# <CJK>
+0x5136	0x8BAF	# <CJK>
+0x5137	0x900A	# <CJK>
+0x5138	0x8FC5	# <CJK>
+0x5139	0x538B	# <CJK>
+0x513A	0x62BC	# <CJK>
+0x513B	0x9E26	# <CJK>
+0x513C	0x9E2D	# <CJK>
+0x513D	0x5440	# <CJK>
+0x513E	0x4E2B	# <CJK>
+0x513F	0x82BD	# <CJK>
+0x5140	0x7259	# <CJK>
+0x5141	0x869C	# <CJK>
+0x5142	0x5D16	# <CJK>
+0x5143	0x8859	# <CJK>
+0x5144	0x6DAF	# <CJK>
+0x5145	0x96C5	# <CJK>
+0x5146	0x54D1	# <CJK>
+0x5147	0x4E9A	# <CJK>
+0x5148	0x8BB6	# <CJK>
+0x5149	0x7109	# <CJK>
+0x514A	0x54BD	# <CJK>
+0x514B	0x9609	# <CJK>
+0x514C	0x70DF	# <CJK>
+0x514D	0x6DF9	# <CJK>
+0x514E	0x76D0	# <CJK>
+0x514F	0x4E25	# <CJK>
+0x5150	0x7814	# <CJK>
+0x5151	0x8712	# <CJK>
+0x5152	0x5CA9	# <CJK>
+0x5153	0x5EF6	# <CJK>
+0x5154	0x8A00	# <CJK>
+0x5155	0x989C	# <CJK>
+0x5156	0x960E	# <CJK>
+0x5157	0x708E	# <CJK>
+0x5158	0x6CBF	# <CJK>
+0x5159	0x5944	# <CJK>
+0x515A	0x63A9	# <CJK>
+0x515B	0x773C	# <CJK>
+0x515C	0x884D	# <CJK>
+0x515D	0x6F14	# <CJK>
+0x515E	0x8273	# <CJK>
+0x515F	0x5830	# <CJK>
+0x5160	0x71D5	# <CJK>
+0x5161	0x538C	# <CJK>
+0x5162	0x781A	# <CJK>
+0x5163	0x96C1	# <CJK>
+0x5164	0x5501	# <CJK>
+0x5165	0x5F66	# <CJK>
+0x5166	0x7130	# <CJK>
+0x5167	0x5BB4	# <CJK>
+0x5168	0x8C1A	# <CJK>
+0x5169	0x9A8C	# <CJK>
+0x516A	0x6B83	# <CJK>
+0x516B	0x592E	# <CJK>
+0x516C	0x9E2F	# <CJK>
+0x516D	0x79E7	# <CJK>
+0x516E	0x6768	# <CJK>
+0x516F	0x626C	# <CJK>
+0x5170	0x4F6F	# <CJK>
+0x5171	0x75A1	# <CJK>
+0x5172	0x7F8A	# <CJK>
+0x5173	0x6D0B	# <CJK>
+0x5174	0x9633	# <CJK>
+0x5175	0x6C27	# <CJK>
+0x5176	0x4EF0	# <CJK>
+0x5177	0x75D2	# <CJK>
+0x5178	0x517B	# <CJK>
+0x5179	0x6837	# <CJK>
+0x517A	0x6F3E	# <CJK>
+0x517B	0x9080	# <CJK>
+0x517C	0x8170	# <CJK>
+0x517D	0x5996	# <CJK>
+0x517E	0x7476	# <CJK>
+0x5221	0x6447	# <CJK>
+0x5222	0x5C27	# <CJK>
+0x5223	0x9065	# <CJK>
+0x5224	0x7A91	# <CJK>
+0x5225	0x8C23	# <CJK>
+0x5226	0x59DA	# <CJK>
+0x5227	0x54AC	# <CJK>
+0x5228	0x8200	# <CJK>
+0x5229	0x836F	# <CJK>
+0x522A	0x8981	# <CJK>
+0x522B	0x8000	# <CJK>
+0x522C	0x6930	# <CJK>
+0x522D	0x564E	# <CJK>
+0x522E	0x8036	# <CJK>
+0x522F	0x7237	# <CJK>
+0x5230	0x91CE	# <CJK>
+0x5231	0x51B6	# <CJK>
+0x5232	0x4E5F	# <CJK>
+0x5233	0x9875	# <CJK>
+0x5234	0x6396	# <CJK>
+0x5235	0x4E1A	# <CJK>
+0x5236	0x53F6	# <CJK>
+0x5237	0x66F3	# <CJK>
+0x5238	0x814B	# <CJK>
+0x5239	0x591C	# <CJK>
+0x523A	0x6DB2	# <CJK>
+0x523B	0x4E00	# <CJK>
+0x523C	0x58F9	# <CJK>
+0x523D	0x533B	# <CJK>
+0x523E	0x63D6	# <CJK>
+0x523F	0x94F1	# <CJK>
+0x5240	0x4F9D	# <CJK>
+0x5241	0x4F0A	# <CJK>
+0x5242	0x8863	# <CJK>
+0x5243	0x9890	# <CJK>
+0x5244	0x5937	# <CJK>
+0x5245	0x9057	# <CJK>
+0x5246	0x79FB	# <CJK>
+0x5247	0x4EEA	# <CJK>
+0x5248	0x80F0	# <CJK>
+0x5249	0x7591	# <CJK>
+0x524A	0x6C82	# <CJK>
+0x524B	0x5B9C	# <CJK>
+0x524C	0x59E8	# <CJK>
+0x524D	0x5F5D	# <CJK>
+0x524E	0x6905	# <CJK>
+0x524F	0x8681	# <CJK>
+0x5250	0x501A	# <CJK>
+0x5251	0x5DF2	# <CJK>
+0x5252	0x4E59	# <CJK>
+0x5253	0x77E3	# <CJK>
+0x5254	0x4EE5	# <CJK>
+0x5255	0x827A	# <CJK>
+0x5256	0x6291	# <CJK>
+0x5257	0x6613	# <CJK>
+0x5258	0x9091	# <CJK>
+0x5259	0x5C79	# <CJK>
+0x525A	0x4EBF	# <CJK>
+0x525B	0x5F79	# <CJK>
+0x525C	0x81C6	# <CJK>
+0x525D	0x9038	# <CJK>
+0x525E	0x8084	# <CJK>
+0x525F	0x75AB	# <CJK>
+0x5260	0x4EA6	# <CJK>
+0x5261	0x88D4	# <CJK>
+0x5262	0x610F	# <CJK>
+0x5263	0x6BC5	# <CJK>
+0x5264	0x5FC6	# <CJK>
+0x5265	0x4E49	# <CJK>
+0x5266	0x76CA	# <CJK>
+0x5267	0x6EA2	# <CJK>
+0x5268	0x8BE3	# <CJK>
+0x5269	0x8BAE	# <CJK>
+0x526A	0x8C0A	# <CJK>
+0x526B	0x8BD1	# <CJK>
+0x526C	0x5F02	# <CJK>
+0x526D	0x7FFC	# <CJK>
+0x526E	0x7FCC	# <CJK>
+0x526F	0x7ECE	# <CJK>
+0x5270	0x8335	# <CJK>
+0x5271	0x836B	# <CJK>
+0x5272	0x56E0	# <CJK>
+0x5273	0x6BB7	# <CJK>
+0x5274	0x97F3	# <CJK>
+0x5275	0x9634	# <CJK>
+0x5276	0x59FB	# <CJK>
+0x5277	0x541F	# <CJK>
+0x5278	0x94F6	# <CJK>
+0x5279	0x6DEB	# <CJK>
+0x527A	0x5BC5	# <CJK>
+0x527B	0x996E	# <CJK>
+0x527C	0x5C39	# <CJK>
+0x527D	0x5F15	# <CJK>
+0x527E	0x9690	# <CJK>
+0x5321	0x5370	# <CJK>
+0x5322	0x82F1	# <CJK>
+0x5323	0x6A31	# <CJK>
+0x5324	0x5A74	# <CJK>
+0x5325	0x9E70	# <CJK>
+0x5326	0x5E94	# <CJK>
+0x5327	0x7F28	# <CJK>
+0x5328	0x83B9	# <CJK>
+0x5329	0x8424	# <CJK>
+0x532A	0x8425	# <CJK>
+0x532B	0x8367	# <CJK>
+0x532C	0x8747	# <CJK>
+0x532D	0x8FCE	# <CJK>
+0x532E	0x8D62	# <CJK>
+0x532F	0x76C8	# <CJK>
+0x5330	0x5F71	# <CJK>
+0x5331	0x9896	# <CJK>
+0x5332	0x786C	# <CJK>
+0x5333	0x6620	# <CJK>
+0x5334	0x54DF	# <CJK>
+0x5335	0x62E5	# <CJK>
+0x5336	0x4F63	# <CJK>
+0x5337	0x81C3	# <CJK>
+0x5338	0x75C8	# <CJK>
+0x5339	0x5EB8	# <CJK>
+0x533A	0x96CD	# <CJK>
+0x533B	0x8E0A	# <CJK>
+0x533C	0x86F9	# <CJK>
+0x533D	0x548F	# <CJK>
+0x533E	0x6CF3	# <CJK>
+0x533F	0x6D8C	# <CJK>
+0x5340	0x6C38	# <CJK>
+0x5341	0x607F	# <CJK>
+0x5342	0x52C7	# <CJK>
+0x5343	0x7528	# <CJK>
+0x5344	0x5E7D	# <CJK>
+0x5345	0x4F18	# <CJK>
+0x5346	0x60A0	# <CJK>
+0x5347	0x5FE7	# <CJK>
+0x5348	0x5C24	# <CJK>
+0x5349	0x7531	# <CJK>
+0x534A	0x90AE	# <CJK>
+0x534B	0x94C0	# <CJK>
+0x534C	0x72B9	# <CJK>
+0x534D	0x6CB9	# <CJK>
+0x534E	0x6E38	# <CJK>
+0x534F	0x9149	# <CJK>
+0x5350	0x6709	# <CJK>
+0x5351	0x53CB	# <CJK>
+0x5352	0x53F3	# <CJK>
+0x5353	0x4F51	# <CJK>
+0x5354	0x91C9	# <CJK>
+0x5355	0x8BF1	# <CJK>
+0x5356	0x53C8	# <CJK>
+0x5357	0x5E7C	# <CJK>
+0x5358	0x8FC2	# <CJK>
+0x5359	0x6DE4	# <CJK>
+0x535A	0x4E8E	# <CJK>
+0x535B	0x76C2	# <CJK>
+0x535C	0x6986	# <CJK>
+0x535D	0x865E	# <CJK>
+0x535E	0x611A	# <CJK>
+0x535F	0x8206	# <CJK>
+0x5360	0x4F59	# <CJK>
+0x5361	0x4FDE	# <CJK>
+0x5362	0x903E	# <CJK>
+0x5363	0x9C7C	# <CJK>
+0x5364	0x6109	# <CJK>
+0x5365	0x6E1D	# <CJK>
+0x5366	0x6E14	# <CJK>
+0x5367	0x9685	# <CJK>
+0x5368	0x4E88	# <CJK>
+0x5369	0x5A31	# <CJK>
+0x536A	0x96E8	# <CJK>
+0x536B	0x4E0E	# <CJK>
+0x536C	0x5C7F	# <CJK>
+0x536D	0x79B9	# <CJK>
+0x536E	0x5B87	# <CJK>
+0x536F	0x8BED	# <CJK>
+0x5370	0x7FBD	# <CJK>
+0x5371	0x7389	# <CJK>
+0x5372	0x57DF	# <CJK>
+0x5373	0x828B	# <CJK>
+0x5374	0x90C1	# <CJK>
+0x5375	0x5401	# <CJK>
+0x5376	0x9047	# <CJK>
+0x5377	0x55BB	# <CJK>
+0x5378	0x5CEA	# <CJK>
+0x5379	0x5FA1	# <CJK>
+0x537A	0x6108	# <CJK>
+0x537B	0x6B32	# <CJK>
+0x537C	0x72F1	# <CJK>
+0x537D	0x80B2	# <CJK>
+0x537E	0x8A89	# <CJK>
+0x5421	0x6D74	# <CJK>
+0x5422	0x5BD3	# <CJK>
+0x5423	0x88D5	# <CJK>
+0x5424	0x9884	# <CJK>
+0x5425	0x8C6B	# <CJK>
+0x5426	0x9A6D	# <CJK>
+0x5427	0x9E33	# <CJK>
+0x5428	0x6E0A	# <CJK>
+0x5429	0x51A4	# <CJK>
+0x542A	0x5143	# <CJK>
+0x542B	0x57A3	# <CJK>
+0x542C	0x8881	# <CJK>
+0x542D	0x539F	# <CJK>
+0x542E	0x63F4	# <CJK>
+0x542F	0x8F95	# <CJK>
+0x5430	0x56ED	# <CJK>
+0x5431	0x5458	# <CJK>
+0x5432	0x5706	# <CJK>
+0x5433	0x733F	# <CJK>
+0x5434	0x6E90	# <CJK>
+0x5435	0x7F18	# <CJK>
+0x5436	0x8FDC	# <CJK>
+0x5437	0x82D1	# <CJK>
+0x5438	0x613F	# <CJK>
+0x5439	0x6028	# <CJK>
+0x543A	0x9662	# <CJK>
+0x543B	0x66F0	# <CJK>
+0x543C	0x7EA6	# <CJK>
+0x543D	0x8D8A	# <CJK>
+0x543E	0x8DC3	# <CJK>
+0x543F	0x94A5	# <CJK>
+0x5440	0x5CB3	# <CJK>
+0x5441	0x7CA4	# <CJK>
+0x5442	0x6708	# <CJK>
+0x5443	0x60A6	# <CJK>
+0x5444	0x9605	# <CJK>
+0x5445	0x8018	# <CJK>
+0x5446	0x4E91	# <CJK>
+0x5447	0x90E7	# <CJK>
+0x5448	0x5300	# <CJK>
+0x5449	0x9668	# <CJK>
+0x544A	0x5141	# <CJK>
+0x544B	0x8FD0	# <CJK>
+0x544C	0x8574	# <CJK>
+0x544D	0x915D	# <CJK>
+0x544E	0x6655	# <CJK>
+0x544F	0x97F5	# <CJK>
+0x5450	0x5B55	# <CJK>
+0x5451	0x531D	# <CJK>
+0x5452	0x7838	# <CJK>
+0x5453	0x6742	# <CJK>
+0x5454	0x683D	# <CJK>
+0x5455	0x54C9	# <CJK>
+0x5456	0x707E	# <CJK>
+0x5457	0x5BB0	# <CJK>
+0x5458	0x8F7D	# <CJK>
+0x5459	0x518D	# <CJK>
+0x545A	0x5728	# <CJK>
+0x545B	0x54B1	# <CJK>
+0x545C	0x6512	# <CJK>
+0x545D	0x6682	# <CJK>
+0x545E	0x8D5E	# <CJK>
+0x545F	0x8D43	# <CJK>
+0x5460	0x810F	# <CJK>
+0x5461	0x846C	# <CJK>
+0x5462	0x906D	# <CJK>
+0x5463	0x7CDF	# <CJK>
+0x5464	0x51FF	# <CJK>
+0x5465	0x85FB	# <CJK>
+0x5466	0x67A3	# <CJK>
+0x5467	0x65E9	# <CJK>
+0x5468	0x6FA1	# <CJK>
+0x5469	0x86A4	# <CJK>
+0x546A	0x8E81	# <CJK>
+0x546B	0x566A	# <CJK>
+0x546C	0x9020	# <CJK>
+0x546D	0x7682	# <CJK>
+0x546E	0x7076	# <CJK>
+0x546F	0x71E5	# <CJK>
+0x5470	0x8D23	# <CJK>
+0x5471	0x62E9	# <CJK>
+0x5472	0x5219	# <CJK>
+0x5473	0x6CFD	# <CJK>
+0x5474	0x8D3C	# <CJK>
+0x5475	0x600E	# <CJK>
+0x5476	0x589E	# <CJK>
+0x5477	0x618E	# <CJK>
+0x5478	0x66FE	# <CJK>
+0x5479	0x8D60	# <CJK>
+0x547A	0x624E	# <CJK>
+0x547B	0x55B3	# <CJK>
+0x547C	0x6E23	# <CJK>
+0x547D	0x672D	# <CJK>
+0x547E	0x8F67	# <CJK>
+0x5521	0x94E1	# <CJK>
+0x5522	0x95F8	# <CJK>
+0x5523	0x7728	# <CJK>
+0x5524	0x6805	# <CJK>
+0x5525	0x69A8	# <CJK>
+0x5526	0x548B	# <CJK>
+0x5527	0x4E4D	# <CJK>
+0x5528	0x70B8	# <CJK>
+0x5529	0x8BC8	# <CJK>
+0x552A	0x6458	# <CJK>
+0x552B	0x658B	# <CJK>
+0x552C	0x5B85	# <CJK>
+0x552D	0x7A84	# <CJK>
+0x552E	0x503A	# <CJK>
+0x552F	0x5BE8	# <CJK>
+0x5530	0x77BB	# <CJK>
+0x5531	0x6BE1	# <CJK>
+0x5532	0x8A79	# <CJK>
+0x5533	0x7C98	# <CJK>
+0x5534	0x6CBE	# <CJK>
+0x5535	0x76CF	# <CJK>
+0x5536	0x65A9	# <CJK>
+0x5537	0x8F97	# <CJK>
+0x5538	0x5D2D	# <CJK>
+0x5539	0x5C55	# <CJK>
+0x553A	0x8638	# <CJK>
+0x553B	0x6808	# <CJK>
+0x553C	0x5360	# <CJK>
+0x553D	0x6218	# <CJK>
+0x553E	0x7AD9	# <CJK>
+0x553F	0x6E5B	# <CJK>
+0x5540	0x7EFD	# <CJK>
+0x5541	0x6A1F	# <CJK>
+0x5542	0x7AE0	# <CJK>
+0x5543	0x5F70	# <CJK>
+0x5544	0x6F33	# <CJK>
+0x5545	0x5F20	# <CJK>
+0x5546	0x638C	# <CJK>
+0x5547	0x6DA8	# <CJK>
+0x5548	0x6756	# <CJK>
+0x5549	0x4E08	# <CJK>
+0x554A	0x5E10	# <CJK>
+0x554B	0x8D26	# <CJK>
+0x554C	0x4ED7	# <CJK>
+0x554D	0x80C0	# <CJK>
+0x554E	0x7634	# <CJK>
+0x554F	0x969C	# <CJK>
+0x5550	0x62DB	# <CJK>
+0x5551	0x662D	# <CJK>
+0x5552	0x627E	# <CJK>
+0x5553	0x6CBC	# <CJK>
+0x5554	0x8D75	# <CJK>
+0x5555	0x7167	# <CJK>
+0x5556	0x7F69	# <CJK>
+0x5557	0x5146	# <CJK>
+0x5558	0x8087	# <CJK>
+0x5559	0x53EC	# <CJK>
+0x555A	0x906E	# <CJK>
+0x555B	0x6298	# <CJK>
+0x555C	0x54F2	# <CJK>
+0x555D	0x86F0	# <CJK>
+0x555E	0x8F99	# <CJK>
+0x555F	0x8005	# <CJK>
+0x5560	0x9517	# <CJK>
+0x5561	0x8517	# <CJK>
+0x5562	0x8FD9	# <CJK>
+0x5563	0x6D59	# <CJK>
+0x5564	0x73CD	# <CJK>
+0x5565	0x659F	# <CJK>
+0x5566	0x771F	# <CJK>
+0x5567	0x7504	# <CJK>
+0x5568	0x7827	# <CJK>
+0x5569	0x81FB	# <CJK>
+0x556A	0x8D1E	# <CJK>
+0x556B	0x9488	# <CJK>
+0x556C	0x4FA6	# <CJK>
+0x556D	0x6795	# <CJK>
+0x556E	0x75B9	# <CJK>
+0x556F	0x8BCA	# <CJK>
+0x5570	0x9707	# <CJK>
+0x5571	0x632F	# <CJK>
+0x5572	0x9547	# <CJK>
+0x5573	0x9635	# <CJK>
+0x5574	0x84B8	# <CJK>
+0x5575	0x6323	# <CJK>
+0x5576	0x7741	# <CJK>
+0x5577	0x5F81	# <CJK>
+0x5578	0x72F0	# <CJK>
+0x5579	0x4E89	# <CJK>
+0x557A	0x6014	# <CJK>
+0x557B	0x6574	# <CJK>
+0x557C	0x62EF	# <CJK>
+0x557D	0x6B63	# <CJK>
+0x557E	0x653F	# <CJK>
+0x5621	0x5E27	# <CJK>
+0x5622	0x75C7	# <CJK>
+0x5623	0x90D1	# <CJK>
+0x5624	0x8BC1	# <CJK>
+0x5625	0x829D	# <CJK>
+0x5626	0x679D	# <CJK>
+0x5627	0x652F	# <CJK>
+0x5628	0x5431	# <CJK>
+0x5629	0x8718	# <CJK>
+0x562A	0x77E5	# <CJK>
+0x562B	0x80A2	# <CJK>
+0x562C	0x8102	# <CJK>
+0x562D	0x6C41	# <CJK>
+0x562E	0x4E4B	# <CJK>
+0x562F	0x7EC7	# <CJK>
+0x5630	0x804C	# <CJK>
+0x5631	0x76F4	# <CJK>
+0x5632	0x690D	# <CJK>
+0x5633	0x6B96	# <CJK>
+0x5634	0x6267	# <CJK>
+0x5635	0x503C	# <CJK>
+0x5636	0x4F84	# <CJK>
+0x5637	0x5740	# <CJK>
+0x5638	0x6307	# <CJK>
+0x5639	0x6B62	# <CJK>
+0x563A	0x8DBE	# <CJK>
+0x563B	0x53EA	# <CJK>
+0x563C	0x65E8	# <CJK>
+0x563D	0x7EB8	# <CJK>
+0x563E	0x5FD7	# <CJK>
+0x563F	0x631A	# <CJK>
+0x5640	0x63B7	# <CJK>
+0x5641	0x81F3	# <CJK>
+0x5642	0x81F4	# <CJK>
+0x5643	0x7F6E	# <CJK>
+0x5644	0x5E1C	# <CJK>
+0x5645	0x5CD9	# <CJK>
+0x5646	0x5236	# <CJK>
+0x5647	0x667A	# <CJK>
+0x5648	0x79E9	# <CJK>
+0x5649	0x7A1A	# <CJK>
+0x564A	0x8D28	# <CJK>
+0x564B	0x7099	# <CJK>
+0x564C	0x75D4	# <CJK>
+0x564D	0x6EDE	# <CJK>
+0x564E	0x6CBB	# <CJK>
+0x564F	0x7A92	# <CJK>
+0x5650	0x4E2D	# <CJK>
+0x5651	0x76C5	# <CJK>
+0x5652	0x5FE0	# <CJK>
+0x5653	0x949F	# <CJK>
+0x5654	0x8877	# <CJK>
+0x5655	0x7EC8	# <CJK>
+0x5656	0x79CD	# <CJK>
+0x5657	0x80BF	# <CJK>
+0x5658	0x91CD	# <CJK>
+0x5659	0x4EF2	# <CJK>
+0x565A	0x4F17	# <CJK>
+0x565B	0x821F	# <CJK>
+0x565C	0x5468	# <CJK>
+0x565D	0x5DDE	# <CJK>
+0x565E	0x6D32	# <CJK>
+0x565F	0x8BCC	# <CJK>
+0x5660	0x7CA5	# <CJK>
+0x5661	0x8F74	# <CJK>
+0x5662	0x8098	# <CJK>
+0x5663	0x5E1A	# <CJK>
+0x5664	0x5492	# <CJK>
+0x5665	0x76B1	# <CJK>
+0x5666	0x5B99	# <CJK>
+0x5667	0x663C	# <CJK>
+0x5668	0x9AA4	# <CJK>
+0x5669	0x73E0	# <CJK>
+0x566A	0x682A	# <CJK>
+0x566B	0x86DB	# <CJK>
+0x566C	0x6731	# <CJK>
+0x566D	0x732A	# <CJK>
+0x566E	0x8BF8	# <CJK>
+0x566F	0x8BDB	# <CJK>
+0x5670	0x9010	# <CJK>
+0x5671	0x7AF9	# <CJK>
+0x5672	0x70DB	# <CJK>
+0x5673	0x716E	# <CJK>
+0x5674	0x62C4	# <CJK>
+0x5675	0x77A9	# <CJK>
+0x5676	0x5631	# <CJK>
+0x5677	0x4E3B	# <CJK>
+0x5678	0x8457	# <CJK>
+0x5679	0x67F1	# <CJK>
+0x567A	0x52A9	# <CJK>
+0x567B	0x86C0	# <CJK>
+0x567C	0x8D2E	# <CJK>
+0x567D	0x94F8	# <CJK>
+0x567E	0x7B51	# <CJK>
+0x5721	0x4F4F	# <CJK>
+0x5722	0x6CE8	# <CJK>
+0x5723	0x795D	# <CJK>
+0x5724	0x9A7B	# <CJK>
+0x5725	0x6293	# <CJK>
+0x5726	0x722A	# <CJK>
+0x5727	0x62FD	# <CJK>
+0x5728	0x4E13	# <CJK>
+0x5729	0x7816	# <CJK>
+0x572A	0x8F6C	# <CJK>
+0x572B	0x64B0	# <CJK>
+0x572C	0x8D5A	# <CJK>
+0x572D	0x7BC6	# <CJK>
+0x572E	0x6869	# <CJK>
+0x572F	0x5E84	# <CJK>
+0x5730	0x88C5	# <CJK>
+0x5731	0x5986	# <CJK>
+0x5732	0x649E	# <CJK>
+0x5733	0x58EE	# <CJK>
+0x5734	0x72B6	# <CJK>
+0x5735	0x690E	# <CJK>
+0x5736	0x9525	# <CJK>
+0x5737	0x8FFD	# <CJK>
+0x5738	0x8D58	# <CJK>
+0x5739	0x5760	# <CJK>
+0x573A	0x7F00	# <CJK>
+0x573B	0x8C06	# <CJK>
+0x573C	0x51C6	# <CJK>
+0x573D	0x6349	# <CJK>
+0x573E	0x62D9	# <CJK>
+0x573F	0x5353	# <CJK>
+0x5740	0x684C	# <CJK>
+0x5741	0x7422	# <CJK>
+0x5742	0x8301	# <CJK>
+0x5743	0x914C	# <CJK>
+0x5744	0x5544	# <CJK>
+0x5745	0x7740	# <CJK>
+0x5746	0x707C	# <CJK>
+0x5747	0x6D4A	# <CJK>
+0x5748	0x5179	# <CJK>
+0x5749	0x54A8	# <CJK>
+0x574A	0x8D44	# <CJK>
+0x574B	0x59FF	# <CJK>
+0x574C	0x6ECB	# <CJK>
+0x574D	0x6DC4	# <CJK>
+0x574E	0x5B5C	# <CJK>
+0x574F	0x7D2B	# <CJK>
+0x5750	0x4ED4	# <CJK>
+0x5751	0x7C7D	# <CJK>
+0x5752	0x6ED3	# <CJK>
+0x5753	0x5B50	# <CJK>
+0x5754	0x81EA	# <CJK>
+0x5755	0x6E0D	# <CJK>
+0x5756	0x5B57	# <CJK>
+0x5757	0x9B03	# <CJK>
+0x5758	0x68D5	# <CJK>
+0x5759	0x8E2A	# <CJK>
+0x575A	0x5B97	# <CJK>
+0x575B	0x7EFC	# <CJK>
+0x575C	0x603B	# <CJK>
+0x575D	0x7EB5	# <CJK>
+0x575E	0x90B9	# <CJK>
+0x575F	0x8D70	# <CJK>
+0x5760	0x594F	# <CJK>
+0x5761	0x63CD	# <CJK>
+0x5762	0x79DF	# <CJK>
+0x5763	0x8DB3	# <CJK>
+0x5764	0x5352	# <CJK>
+0x5765	0x65CF	# <CJK>
+0x5766	0x7956	# <CJK>
+0x5767	0x8BC5	# <CJK>
+0x5768	0x963B	# <CJK>
+0x5769	0x7EC4	# <CJK>
+0x576A	0x94BB	# <CJK>
+0x576B	0x7E82	# <CJK>
+0x576C	0x5634	# <CJK>
+0x576D	0x9189	# <CJK>
+0x576E	0x6700	# <CJK>
+0x576F	0x7F6A	# <CJK>
+0x5770	0x5C0A	# <CJK>
+0x5771	0x9075	# <CJK>
+0x5772	0x6628	# <CJK>
+0x5773	0x5DE6	# <CJK>
+0x5774	0x4F50	# <CJK>
+0x5775	0x67DE	# <CJK>
+0x5776	0x505A	# <CJK>
+0x5777	0x4F5C	# <CJK>
+0x5778	0x5750	# <CJK>
+0x5779	0x5EA7	# <CJK>
+0x5821	0x4E8D	# <CJK>
+0x5822	0x4E0C	# <CJK>
+0x5823	0x5140	# <CJK>
+0x5824	0x4E10	# <CJK>
+0x5825	0x5EFF	# <CJK>
+0x5826	0x5345	# <CJK>
+0x5827	0x4E15	# <CJK>
+0x5828	0x4E98	# <CJK>
+0x5829	0x4E1E	# <CJK>
+0x582A	0x9B32	# <CJK>
+0x582B	0x5B6C	# <CJK>
+0x582C	0x5669	# <CJK>
+0x582D	0x4E28	# <CJK>
+0x582E	0x79BA	# <CJK>
+0x582F	0x4E3F	# <CJK>
+0x5830	0x5315	# <CJK>
+0x5831	0x4E47	# <CJK>
+0x5832	0x592D	# <CJK>
+0x5833	0x723B	# <CJK>
+0x5834	0x536E	# <CJK>
+0x5835	0x6C10	# <CJK>
+0x5836	0x56DF	# <CJK>
+0x5837	0x80E4	# <CJK>
+0x5838	0x9997	# <CJK>
+0x5839	0x6BD3	# <CJK>
+0x583A	0x777E	# <CJK>
+0x583B	0x9F17	# <CJK>
+0x583C	0x4E36	# <CJK>
+0x583D	0x4E9F	# <CJK>
+0x583E	0x9F10	# <CJK>
+0x583F	0x4E5C	# <CJK>
+0x5840	0x4E69	# <CJK>
+0x5841	0x4E93	# <CJK>
+0x5842	0x8288	# <CJK>
+0x5843	0x5B5B	# <CJK>
+0x5844	0x556C	# <CJK>
+0x5845	0x560F	# <CJK>
+0x5846	0x4EC4	# <CJK>
+0x5847	0x538D	# <CJK>
+0x5848	0x539D	# <CJK>
+0x5849	0x53A3	# <CJK>
+0x584A	0x53A5	# <CJK>
+0x584B	0x53AE	# <CJK>
+0x584C	0x9765	# <CJK>
+0x584D	0x8D5D	# <CJK>
+0x584E	0x531A	# <CJK>
+0x584F	0x53F5	# <CJK>
+0x5850	0x5326	# <CJK>
+0x5851	0x532E	# <CJK>
+0x5852	0x533E	# <CJK>
+0x5853	0x8D5C	# <CJK>
+0x5854	0x5366	# <CJK>
+0x5855	0x5363	# <CJK>
+0x5856	0x5202	# <CJK>
+0x5857	0x5208	# <CJK>
+0x5858	0x520E	# <CJK>
+0x5859	0x522D	# <CJK>
+0x585A	0x5233	# <CJK>
+0x585B	0x523F	# <CJK>
+0x585C	0x5240	# <CJK>
+0x585D	0x524C	# <CJK>
+0x585E	0x525E	# <CJK>
+0x585F	0x5261	# <CJK>
+0x5860	0x525C	# <CJK>
+0x5861	0x84AF	# <CJK>
+0x5862	0x527D	# <CJK>
+0x5863	0x5282	# <CJK>
+0x5864	0x5281	# <CJK>
+0x5865	0x5290	# <CJK>
+0x5866	0x5293	# <CJK>
+0x5867	0x5182	# <CJK>
+0x5868	0x7F54	# <CJK>
+0x5869	0x4EBB	# <CJK>
+0x586A	0x4EC3	# <CJK>
+0x586B	0x4EC9	# <CJK>
+0x586C	0x4EC2	# <CJK>
+0x586D	0x4EE8	# <CJK>
+0x586E	0x4EE1	# <CJK>
+0x586F	0x4EEB	# <CJK>
+0x5870	0x4EDE	# <CJK>
+0x5871	0x4F1B	# <CJK>
+0x5872	0x4EF3	# <CJK>
+0x5873	0x4F22	# <CJK>
+0x5874	0x4F64	# <CJK>
+0x5875	0x4EF5	# <CJK>
+0x5876	0x4F25	# <CJK>
+0x5877	0x4F27	# <CJK>
+0x5878	0x4F09	# <CJK>
+0x5879	0x4F2B	# <CJK>
+0x587A	0x4F5E	# <CJK>
+0x587B	0x4F67	# <CJK>
+0x587C	0x6538	# <CJK>
+0x587D	0x4F5A	# <CJK>
+0x587E	0x4F5D	# <CJK>
+0x5921	0x4F5F	# <CJK>
+0x5922	0x4F57	# <CJK>
+0x5923	0x4F32	# <CJK>
+0x5924	0x4F3D	# <CJK>
+0x5925	0x4F76	# <CJK>
+0x5926	0x4F74	# <CJK>
+0x5927	0x4F91	# <CJK>
+0x5928	0x4F89	# <CJK>
+0x5929	0x4F83	# <CJK>
+0x592A	0x4F8F	# <CJK>
+0x592B	0x4F7E	# <CJK>
+0x592C	0x4F7B	# <CJK>
+0x592D	0x4FAA	# <CJK>
+0x592E	0x4F7C	# <CJK>
+0x592F	0x4FAC	# <CJK>
+0x5930	0x4F94	# <CJK>
+0x5931	0x4FE6	# <CJK>
+0x5932	0x4FE8	# <CJK>
+0x5933	0x4FEA	# <CJK>
+0x5934	0x4FC5	# <CJK>
+0x5935	0x4FDA	# <CJK>
+0x5936	0x4FE3	# <CJK>
+0x5937	0x4FDC	# <CJK>
+0x5938	0x4FD1	# <CJK>
+0x5939	0x4FDF	# <CJK>
+0x593A	0x4FF8	# <CJK>
+0x593B	0x5029	# <CJK>
+0x593C	0x504C	# <CJK>
+0x593D	0x4FF3	# <CJK>
+0x593E	0x502C	# <CJK>
+0x593F	0x500F	# <CJK>
+0x5940	0x502E	# <CJK>
+0x5941	0x502D	# <CJK>
+0x5942	0x4FFE	# <CJK>
+0x5943	0x501C	# <CJK>
+0x5944	0x500C	# <CJK>
+0x5945	0x5025	# <CJK>
+0x5946	0x5028	# <CJK>
+0x5947	0x507E	# <CJK>
+0x5948	0x5043	# <CJK>
+0x5949	0x5055	# <CJK>
+0x594A	0x5048	# <CJK>
+0x594B	0x504E	# <CJK>
+0x594C	0x506C	# <CJK>
+0x594D	0x507B	# <CJK>
+0x594E	0x50A5	# <CJK>
+0x594F	0x50A7	# <CJK>
+0x5950	0x50A9	# <CJK>
+0x5951	0x50BA	# <CJK>
+0x5952	0x50D6	# <CJK>
+0x5953	0x5106	# <CJK>
+0x5954	0x50ED	# <CJK>
+0x5955	0x50EC	# <CJK>
+0x5956	0x50E6	# <CJK>
+0x5957	0x50EE	# <CJK>
+0x5958	0x5107	# <CJK>
+0x5959	0x510B	# <CJK>
+0x595A	0x4EDD	# <CJK>
+0x595B	0x6C3D	# <CJK>
+0x595C	0x4F58	# <CJK>
+0x595D	0x4F65	# <CJK>
+0x595E	0x4FCE	# <CJK>
+0x595F	0x9FA0	# <CJK>
+0x5960	0x6C46	# <CJK>
+0x5961	0x7C74	# <CJK>
+0x5962	0x516E	# <CJK>
+0x5963	0x5DFD	# <CJK>
+0x5964	0x9EC9	# <CJK>
+0x5965	0x9998	# <CJK>
+0x5966	0x5181	# <CJK>
+0x5967	0x5914	# <CJK>
+0x5968	0x52F9	# <CJK>
+0x5969	0x530D	# <CJK>
+0x596A	0x8A07	# <CJK>
+0x596B	0x5310	# <CJK>
+0x596C	0x51EB	# <CJK>
+0x596D	0x5919	# <CJK>
+0x596E	0x5155	# <CJK>
+0x596F	0x4EA0	# <CJK>
+0x5970	0x5156	# <CJK>
+0x5971	0x4EB3	# <CJK>
+0x5972	0x886E	# <CJK>
+0x5973	0x88A4	# <CJK>
+0x5974	0x4EB5	# <CJK>
+0x5975	0x8114	# <CJK>
+0x5976	0x88D2	# <CJK>
+0x5977	0x7980	# <CJK>
+0x5978	0x5B34	# <CJK>
+0x5979	0x8803	# <CJK>
+0x597A	0x7FB8	# <CJK>
+0x597B	0x51AB	# <CJK>
+0x597C	0x51B1	# <CJK>
+0x597D	0x51BD	# <CJK>
+0x597E	0x51BC	# <CJK>
+0x5A21	0x51C7	# <CJK>
+0x5A22	0x5196	# <CJK>
+0x5A23	0x51A2	# <CJK>
+0x5A24	0x51A5	# <CJK>
+0x5A25	0x8BA0	# <CJK>
+0x5A26	0x8BA6	# <CJK>
+0x5A27	0x8BA7	# <CJK>
+0x5A28	0x8BAA	# <CJK>
+0x5A29	0x8BB4	# <CJK>
+0x5A2A	0x8BB5	# <CJK>
+0x5A2B	0x8BB7	# <CJK>
+0x5A2C	0x8BC2	# <CJK>
+0x5A2D	0x8BC3	# <CJK>
+0x5A2E	0x8BCB	# <CJK>
+0x5A2F	0x8BCF	# <CJK>
+0x5A30	0x8BCE	# <CJK>
+0x5A31	0x8BD2	# <CJK>
+0x5A32	0x8BD3	# <CJK>
+0x5A33	0x8BD4	# <CJK>
+0x5A34	0x8BD6	# <CJK>
+0x5A35	0x8BD8	# <CJK>
+0x5A36	0x8BD9	# <CJK>
+0x5A37	0x8BDC	# <CJK>
+0x5A38	0x8BDF	# <CJK>
+0x5A39	0x8BE0	# <CJK>
+0x5A3A	0x8BE4	# <CJK>
+0x5A3B	0x8BE8	# <CJK>
+0x5A3C	0x8BE9	# <CJK>
+0x5A3D	0x8BEE	# <CJK>
+0x5A3E	0x8BF0	# <CJK>
+0x5A3F	0x8BF3	# <CJK>
+0x5A40	0x8BF6	# <CJK>
+0x5A41	0x8BF9	# <CJK>
+0x5A42	0x8BFC	# <CJK>
+0x5A43	0x8BFF	# <CJK>
+0x5A44	0x8C00	# <CJK>
+0x5A45	0x8C02	# <CJK>
+0x5A46	0x8C04	# <CJK>
+0x5A47	0x8C07	# <CJK>
+0x5A48	0x8C0C	# <CJK>
+0x5A49	0x8C0F	# <CJK>
+0x5A4A	0x8C11	# <CJK>
+0x5A4B	0x8C12	# <CJK>
+0x5A4C	0x8C14	# <CJK>
+0x5A4D	0x8C15	# <CJK>
+0x5A4E	0x8C16	# <CJK>
+0x5A4F	0x8C19	# <CJK>
+0x5A50	0x8C1B	# <CJK>
+0x5A51	0x8C18	# <CJK>
+0x5A52	0x8C1D	# <CJK>
+0x5A53	0x8C1F	# <CJK>
+0x5A54	0x8C20	# <CJK>
+0x5A55	0x8C21	# <CJK>
+0x5A56	0x8C25	# <CJK>
+0x5A57	0x8C27	# <CJK>
+0x5A58	0x8C2A	# <CJK>
+0x5A59	0x8C2B	# <CJK>
+0x5A5A	0x8C2E	# <CJK>
+0x5A5B	0x8C2F	# <CJK>
+0x5A5C	0x8C32	# <CJK>
+0x5A5D	0x8C33	# <CJK>
+0x5A5E	0x8C35	# <CJK>
+0x5A5F	0x8C36	# <CJK>
+0x5A60	0x5369	# <CJK>
+0x5A61	0x537A	# <CJK>
+0x5A62	0x961D	# <CJK>
+0x5A63	0x9622	# <CJK>
+0x5A64	0x9621	# <CJK>
+0x5A65	0x9631	# <CJK>
+0x5A66	0x962A	# <CJK>
+0x5A67	0x963D	# <CJK>
+0x5A68	0x963C	# <CJK>
+0x5A69	0x9642	# <CJK>
+0x5A6A	0x9649	# <CJK>
+0x5A6B	0x9654	# <CJK>
+0x5A6C	0x965F	# <CJK>
+0x5A6D	0x9667	# <CJK>
+0x5A6E	0x966C	# <CJK>
+0x5A6F	0x9672	# <CJK>
+0x5A70	0x9674	# <CJK>
+0x5A71	0x9688	# <CJK>
+0x5A72	0x968D	# <CJK>
+0x5A73	0x9697	# <CJK>
+0x5A74	0x96B0	# <CJK>
+0x5A75	0x9097	# <CJK>
+0x5A76	0x909B	# <CJK>
+0x5A77	0x909D	# <CJK>
+0x5A78	0x9099	# <CJK>
+0x5A79	0x90AC	# <CJK>
+0x5A7A	0x90A1	# <CJK>
+0x5A7B	0x90B4	# <CJK>
+0x5A7C	0x90B3	# <CJK>
+0x5A7D	0x90B6	# <CJK>
+0x5A7E	0x90BA	# <CJK>
+0x5B21	0x90B8	# <CJK>
+0x5B22	0x90B0	# <CJK>
+0x5B23	0x90CF	# <CJK>
+0x5B24	0x90C5	# <CJK>
+0x5B25	0x90BE	# <CJK>
+0x5B26	0x90D0	# <CJK>
+0x5B27	0x90C4	# <CJK>
+0x5B28	0x90C7	# <CJK>
+0x5B29	0x90D3	# <CJK>
+0x5B2A	0x90E6	# <CJK>
+0x5B2B	0x90E2	# <CJK>
+0x5B2C	0x90DC	# <CJK>
+0x5B2D	0x90D7	# <CJK>
+0x5B2E	0x90DB	# <CJK>
+0x5B2F	0x90EB	# <CJK>
+0x5B30	0x90EF	# <CJK>
+0x5B31	0x90FE	# <CJK>
+0x5B32	0x9104	# <CJK>
+0x5B33	0x9122	# <CJK>
+0x5B34	0x911E	# <CJK>
+0x5B35	0x9123	# <CJK>
+0x5B36	0x9131	# <CJK>
+0x5B37	0x912F	# <CJK>
+0x5B38	0x9139	# <CJK>
+0x5B39	0x9143	# <CJK>
+0x5B3A	0x9146	# <CJK>
+0x5B3B	0x520D	# <CJK>
+0x5B3C	0x5942	# <CJK>
+0x5B3D	0x52A2	# <CJK>
+0x5B3E	0x52AC	# <CJK>
+0x5B3F	0x52AD	# <CJK>
+0x5B40	0x52BE	# <CJK>
+0x5B41	0x54FF	# <CJK>
+0x5B42	0x52D0	# <CJK>
+0x5B43	0x52D6	# <CJK>
+0x5B44	0x52F0	# <CJK>
+0x5B45	0x53DF	# <CJK>
+0x5B46	0x71EE	# <CJK>
+0x5B47	0x77CD	# <CJK>
+0x5B48	0x5EF4	# <CJK>
+0x5B49	0x51F5	# <CJK>
+0x5B4A	0x51FC	# <CJK>
+0x5B4B	0x9B2F	# <CJK>
+0x5B4C	0x53B6	# <CJK>
+0x5B4D	0x5F01	# <CJK>
+0x5B4E	0x755A	# <CJK>
+0x5B4F	0x5DEF	# <CJK>
+0x5B50	0x574C	# <CJK>
+0x5B51	0x57A9	# <CJK>
+0x5B52	0x57A1	# <CJK>
+0x5B53	0x587E	# <CJK>
+0x5B54	0x58BC	# <CJK>
+0x5B55	0x58C5	# <CJK>
+0x5B56	0x58D1	# <CJK>
+0x5B57	0x5729	# <CJK>
+0x5B58	0x572C	# <CJK>
+0x5B59	0x572A	# <CJK>
+0x5B5A	0x5733	# <CJK>
+0x5B5B	0x5739	# <CJK>
+0x5B5C	0x572E	# <CJK>
+0x5B5D	0x572F	# <CJK>
+0x5B5E	0x575C	# <CJK>
+0x5B5F	0x573B	# <CJK>
+0x5B60	0x5742	# <CJK>
+0x5B61	0x5769	# <CJK>
+0x5B62	0x5785	# <CJK>
+0x5B63	0x576B	# <CJK>
+0x5B64	0x5786	# <CJK>
+0x5B65	0x577C	# <CJK>
+0x5B66	0x577B	# <CJK>
+0x5B67	0x5768	# <CJK>
+0x5B68	0x576D	# <CJK>
+0x5B69	0x5776	# <CJK>
+0x5B6A	0x5773	# <CJK>
+0x5B6B	0x57AD	# <CJK>
+0x5B6C	0x57A4	# <CJK>
+0x5B6D	0x578C	# <CJK>
+0x5B6E	0x57B2	# <CJK>
+0x5B6F	0x57CF	# <CJK>
+0x5B70	0x57A7	# <CJK>
+0x5B71	0x57B4	# <CJK>
+0x5B72	0x5793	# <CJK>
+0x5B73	0x57A0	# <CJK>
+0x5B74	0x57D5	# <CJK>
+0x5B75	0x57D8	# <CJK>
+0x5B76	0x57DA	# <CJK>
+0x5B77	0x57D9	# <CJK>
+0x5B78	0x57D2	# <CJK>
+0x5B79	0x57B8	# <CJK>
+0x5B7A	0x57F4	# <CJK>
+0x5B7B	0x57EF	# <CJK>
+0x5B7C	0x57F8	# <CJK>
+0x5B7D	0x57E4	# <CJK>
+0x5B7E	0x57DD	# <CJK>
+0x5C21	0x580B	# <CJK>
+0x5C22	0x580D	# <CJK>
+0x5C23	0x57FD	# <CJK>
+0x5C24	0x57ED	# <CJK>
+0x5C25	0x5800	# <CJK>
+0x5C26	0x581E	# <CJK>
+0x5C27	0x5819	# <CJK>
+0x5C28	0x5844	# <CJK>
+0x5C29	0x5820	# <CJK>
+0x5C2A	0x5865	# <CJK>
+0x5C2B	0x586C	# <CJK>
+0x5C2C	0x5881	# <CJK>
+0x5C2D	0x5889	# <CJK>
+0x5C2E	0x589A	# <CJK>
+0x5C2F	0x5880	# <CJK>
+0x5C30	0x99A8	# <CJK>
+0x5C31	0x9F19	# <CJK>
+0x5C32	0x61FF	# <CJK>
+0x5C33	0x8279	# <CJK>
+0x5C34	0x827D	# <CJK>
+0x5C35	0x827F	# <CJK>
+0x5C36	0x828F	# <CJK>
+0x5C37	0x828A	# <CJK>
+0x5C38	0x82A8	# <CJK>
+0x5C39	0x8284	# <CJK>
+0x5C3A	0x828E	# <CJK>
+0x5C3B	0x8291	# <CJK>
+0x5C3C	0x8297	# <CJK>
+0x5C3D	0x8299	# <CJK>
+0x5C3E	0x82AB	# <CJK>
+0x5C3F	0x82B8	# <CJK>
+0x5C40	0x82BE	# <CJK>
+0x5C41	0x82B0	# <CJK>
+0x5C42	0x82C8	# <CJK>
+0x5C43	0x82CA	# <CJK>
+0x5C44	0x82E3	# <CJK>
+0x5C45	0x8298	# <CJK>
+0x5C46	0x82B7	# <CJK>
+0x5C47	0x82AE	# <CJK>
+0x5C48	0x82CB	# <CJK>
+0x5C49	0x82CC	# <CJK>
+0x5C4A	0x82C1	# <CJK>
+0x5C4B	0x82A9	# <CJK>
+0x5C4C	0x82B4	# <CJK>
+0x5C4D	0x82A1	# <CJK>
+0x5C4E	0x82AA	# <CJK>
+0x5C4F	0x829F	# <CJK>
+0x5C50	0x82C4	# <CJK>
+0x5C51	0x82CE	# <CJK>
+0x5C52	0x82A4	# <CJK>
+0x5C53	0x82E1	# <CJK>
+0x5C54	0x8309	# <CJK>
+0x5C55	0x82F7	# <CJK>
+0x5C56	0x82E4	# <CJK>
+0x5C57	0x830F	# <CJK>
+0x5C58	0x8307	# <CJK>
+0x5C59	0x82DC	# <CJK>
+0x5C5A	0x82F4	# <CJK>
+0x5C5B	0x82D2	# <CJK>
+0x5C5C	0x82D8	# <CJK>
+0x5C5D	0x830C	# <CJK>
+0x5C5E	0x82FB	# <CJK>
+0x5C5F	0x82D3	# <CJK>
+0x5C60	0x8311	# <CJK>
+0x5C61	0x831A	# <CJK>
+0x5C62	0x8306	# <CJK>
+0x5C63	0x8314	# <CJK>
+0x5C64	0x8315	# <CJK>
+0x5C65	0x82E0	# <CJK>
+0x5C66	0x82D5	# <CJK>
+0x5C67	0x831C	# <CJK>
+0x5C68	0x8351	# <CJK>
+0x5C69	0x835B	# <CJK>
+0x5C6A	0x835C	# <CJK>
+0x5C6B	0x8308	# <CJK>
+0x5C6C	0x8392	# <CJK>
+0x5C6D	0x833C	# <CJK>
+0x5C6E	0x8334	# <CJK>
+0x5C6F	0x8331	# <CJK>
+0x5C70	0x839B	# <CJK>
+0x5C71	0x835E	# <CJK>
+0x5C72	0x832F	# <CJK>
+0x5C73	0x834F	# <CJK>
+0x5C74	0x8347	# <CJK>
+0x5C75	0x8343	# <CJK>
+0x5C76	0x835F	# <CJK>
+0x5C77	0x8340	# <CJK>
+0x5C78	0x8317	# <CJK>
+0x5C79	0x8360	# <CJK>
+0x5C7A	0x832D	# <CJK>
+0x5C7B	0x833A	# <CJK>
+0x5C7C	0x8333	# <CJK>
+0x5C7D	0x8366	# <CJK>
+0x5C7E	0x8365	# <CJK>
+0x5D21	0x8368	# <CJK>
+0x5D22	0x831B	# <CJK>
+0x5D23	0x8369	# <CJK>
+0x5D24	0x836C	# <CJK>
+0x5D25	0x836A	# <CJK>
+0x5D26	0x836D	# <CJK>
+0x5D27	0x836E	# <CJK>
+0x5D28	0x83B0	# <CJK>
+0x5D29	0x8378	# <CJK>
+0x5D2A	0x83B3	# <CJK>
+0x5D2B	0x83B4	# <CJK>
+0x5D2C	0x83A0	# <CJK>
+0x5D2D	0x83AA	# <CJK>
+0x5D2E	0x8393	# <CJK>
+0x5D2F	0x839C	# <CJK>
+0x5D30	0x8385	# <CJK>
+0x5D31	0x837C	# <CJK>
+0x5D32	0x83B6	# <CJK>
+0x5D33	0x83A9	# <CJK>
+0x5D34	0x837D	# <CJK>
+0x5D35	0x83B8	# <CJK>
+0x5D36	0x837B	# <CJK>
+0x5D37	0x8398	# <CJK>
+0x5D38	0x839E	# <CJK>
+0x5D39	0x83A8	# <CJK>
+0x5D3A	0x83BA	# <CJK>
+0x5D3B	0x83BC	# <CJK>
+0x5D3C	0x83C1	# <CJK>
+0x5D3D	0x8401	# <CJK>
+0x5D3E	0x83E5	# <CJK>
+0x5D3F	0x83D8	# <CJK>
+0x5D40	0x5807	# <CJK>
+0x5D41	0x8418	# <CJK>
+0x5D42	0x840B	# <CJK>
+0x5D43	0x83DD	# <CJK>
+0x5D44	0x83FD	# <CJK>
+0x5D45	0x83D6	# <CJK>
+0x5D46	0x841C	# <CJK>
+0x5D47	0x8438	# <CJK>
+0x5D48	0x8411	# <CJK>
+0x5D49	0x8406	# <CJK>
+0x5D4A	0x83D4	# <CJK>
+0x5D4B	0x83DF	# <CJK>
+0x5D4C	0x840F	# <CJK>
+0x5D4D	0x8403	# <CJK>
+0x5D4E	0x83F8	# <CJK>
+0x5D4F	0x83F9	# <CJK>
+0x5D50	0x83EA	# <CJK>
+0x5D51	0x83C5	# <CJK>
+0x5D52	0x83C0	# <CJK>
+0x5D53	0x8426	# <CJK>
+0x5D54	0x83F0	# <CJK>
+0x5D55	0x83E1	# <CJK>
+0x5D56	0x845C	# <CJK>
+0x5D57	0x8451	# <CJK>
+0x5D58	0x845A	# <CJK>
+0x5D59	0x8459	# <CJK>
+0x5D5A	0x8473	# <CJK>
+0x5D5B	0x8487	# <CJK>
+0x5D5C	0x8488	# <CJK>
+0x5D5D	0x847A	# <CJK>
+0x5D5E	0x8489	# <CJK>
+0x5D5F	0x8478	# <CJK>
+0x5D60	0x843C	# <CJK>
+0x5D61	0x8446	# <CJK>
+0x5D62	0x8469	# <CJK>
+0x5D63	0x8476	# <CJK>
+0x5D64	0x848C	# <CJK>
+0x5D65	0x848E	# <CJK>
+0x5D66	0x8431	# <CJK>
+0x5D67	0x846D	# <CJK>
+0x5D68	0x84C1	# <CJK>
+0x5D69	0x84CD	# <CJK>
+0x5D6A	0x84D0	# <CJK>
+0x5D6B	0x84E6	# <CJK>
+0x5D6C	0x84BD	# <CJK>
+0x5D6D	0x84D3	# <CJK>
+0x5D6E	0x84CA	# <CJK>
+0x5D6F	0x84BF	# <CJK>
+0x5D70	0x84BA	# <CJK>
+0x5D71	0x84E0	# <CJK>
+0x5D72	0x84A1	# <CJK>
+0x5D73	0x84B9	# <CJK>
+0x5D74	0x84B4	# <CJK>
+0x5D75	0x8497	# <CJK>
+0x5D76	0x84E5	# <CJK>
+0x5D77	0x84E3	# <CJK>
+0x5D78	0x850C	# <CJK>
+0x5D79	0x750D	# <CJK>
+0x5D7A	0x8538	# <CJK>
+0x5D7B	0x84F0	# <CJK>
+0x5D7C	0x8539	# <CJK>
+0x5D7D	0x851F	# <CJK>
+0x5D7E	0x853A	# <CJK>
+0x5E21	0x8556	# <CJK>
+0x5E22	0x853B	# <CJK>
+0x5E23	0x84FF	# <CJK>
+0x5E24	0x84FC	# <CJK>
+0x5E25	0x8559	# <CJK>
+0x5E26	0x8548	# <CJK>
+0x5E27	0x8568	# <CJK>
+0x5E28	0x8564	# <CJK>
+0x5E29	0x855E	# <CJK>
+0x5E2A	0x857A	# <CJK>
+0x5E2B	0x77A2	# <CJK>
+0x5E2C	0x8543	# <CJK>
+0x5E2D	0x8572	# <CJK>
+0x5E2E	0x857B	# <CJK>
+0x5E2F	0x85A4	# <CJK>
+0x5E30	0x85A8	# <CJK>
+0x5E31	0x8587	# <CJK>
+0x5E32	0x858F	# <CJK>
+0x5E33	0x8579	# <CJK>
+0x5E34	0x85AE	# <CJK>
+0x5E35	0x859C	# <CJK>
+0x5E36	0x8585	# <CJK>
+0x5E37	0x85B9	# <CJK>
+0x5E38	0x85B7	# <CJK>
+0x5E39	0x85B0	# <CJK>
+0x5E3A	0x85D3	# <CJK>
+0x5E3B	0x85C1	# <CJK>
+0x5E3C	0x85DC	# <CJK>
+0x5E3D	0x85FF	# <CJK>
+0x5E3E	0x8627	# <CJK>
+0x5E3F	0x8605	# <CJK>
+0x5E40	0x8629	# <CJK>
+0x5E41	0x8616	# <CJK>
+0x5E42	0x863C	# <CJK>
+0x5E43	0x5EFE	# <CJK>
+0x5E44	0x5F08	# <CJK>
+0x5E45	0x593C	# <CJK>
+0x5E46	0x5941	# <CJK>
+0x5E47	0x8037	# <CJK>
+0x5E48	0x5955	# <CJK>
+0x5E49	0x595A	# <CJK>
+0x5E4A	0x5958	# <CJK>
+0x5E4B	0x530F	# <CJK>
+0x5E4C	0x5C22	# <CJK>
+0x5E4D	0x5C25	# <CJK>
+0x5E4E	0x5C2C	# <CJK>
+0x5E4F	0x5C34	# <CJK>
+0x5E50	0x624C	# <CJK>
+0x5E51	0x626A	# <CJK>
+0x5E52	0x629F	# <CJK>
+0x5E53	0x62BB	# <CJK>
+0x5E54	0x62CA	# <CJK>
+0x5E55	0x62DA	# <CJK>
+0x5E56	0x62D7	# <CJK>
+0x5E57	0x62EE	# <CJK>
+0x5E58	0x6322	# <CJK>
+0x5E59	0x62F6	# <CJK>
+0x5E5A	0x6339	# <CJK>
+0x5E5B	0x634B	# <CJK>
+0x5E5C	0x6343	# <CJK>
+0x5E5D	0x63AD	# <CJK>
+0x5E5E	0x63F6	# <CJK>
+0x5E5F	0x6371	# <CJK>
+0x5E60	0x637A	# <CJK>
+0x5E61	0x638E	# <CJK>
+0x5E62	0x63B4	# <CJK>
+0x5E63	0x636D	# <CJK>
+0x5E64	0x63AC	# <CJK>
+0x5E65	0x638A	# <CJK>
+0x5E66	0x6369	# <CJK>
+0x5E67	0x63AE	# <CJK>
+0x5E68	0x63BC	# <CJK>
+0x5E69	0x63F2	# <CJK>
+0x5E6A	0x63F8	# <CJK>
+0x5E6B	0x63E0	# <CJK>
+0x5E6C	0x63FF	# <CJK>
+0x5E6D	0x63C4	# <CJK>
+0x5E6E	0x63DE	# <CJK>
+0x5E6F	0x63CE	# <CJK>
+0x5E70	0x6452	# <CJK>
+0x5E71	0x63C6	# <CJK>
+0x5E72	0x63BE	# <CJK>
+0x5E73	0x6445	# <CJK>
+0x5E74	0x6441	# <CJK>
+0x5E75	0x640B	# <CJK>
+0x5E76	0x641B	# <CJK>
+0x5E77	0x6420	# <CJK>
+0x5E78	0x640C	# <CJK>
+0x5E79	0x6426	# <CJK>
+0x5E7A	0x6421	# <CJK>
+0x5E7B	0x645E	# <CJK>
+0x5E7C	0x6484	# <CJK>
+0x5E7D	0x646D	# <CJK>
+0x5E7E	0x6496	# <CJK>
+0x5F21	0x647A	# <CJK>
+0x5F22	0x64B7	# <CJK>
+0x5F23	0x64B8	# <CJK>
+0x5F24	0x6499	# <CJK>
+0x5F25	0x64BA	# <CJK>
+0x5F26	0x64C0	# <CJK>
+0x5F27	0x64D0	# <CJK>
+0x5F28	0x64D7	# <CJK>
+0x5F29	0x64E4	# <CJK>
+0x5F2A	0x64E2	# <CJK>
+0x5F2B	0x6509	# <CJK>
+0x5F2C	0x6525	# <CJK>
+0x5F2D	0x652E	# <CJK>
+0x5F2E	0x5F0B	# <CJK>
+0x5F2F	0x5FD2	# <CJK>
+0x5F30	0x7519	# <CJK>
+0x5F31	0x5F11	# <CJK>
+0x5F32	0x535F	# <CJK>
+0x5F33	0x53F1	# <CJK>
+0x5F34	0x53FD	# <CJK>
+0x5F35	0x53E9	# <CJK>
+0x5F36	0x53E8	# <CJK>
+0x5F37	0x53FB	# <CJK>
+0x5F38	0x5412	# <CJK>
+0x5F39	0x5416	# <CJK>
+0x5F3A	0x5406	# <CJK>
+0x5F3B	0x544B	# <CJK>
+0x5F3C	0x5452	# <CJK>
+0x5F3D	0x5453	# <CJK>
+0x5F3E	0x5454	# <CJK>
+0x5F3F	0x5456	# <CJK>
+0x5F40	0x5443	# <CJK>
+0x5F41	0x5421	# <CJK>
+0x5F42	0x5457	# <CJK>
+0x5F43	0x5459	# <CJK>
+0x5F44	0x5423	# <CJK>
+0x5F45	0x5432	# <CJK>
+0x5F46	0x5482	# <CJK>
+0x5F47	0x5494	# <CJK>
+0x5F48	0x5477	# <CJK>
+0x5F49	0x5471	# <CJK>
+0x5F4A	0x5464	# <CJK>
+0x5F4B	0x549A	# <CJK>
+0x5F4C	0x549B	# <CJK>
+0x5F4D	0x5484	# <CJK>
+0x5F4E	0x5476	# <CJK>
+0x5F4F	0x5466	# <CJK>
+0x5F50	0x549D	# <CJK>
+0x5F51	0x54D0	# <CJK>
+0x5F52	0x54AD	# <CJK>
+0x5F53	0x54C2	# <CJK>
+0x5F54	0x54B4	# <CJK>
+0x5F55	0x54D2	# <CJK>
+0x5F56	0x54A7	# <CJK>
+0x5F57	0x54A6	# <CJK>
+0x5F58	0x54D3	# <CJK>
+0x5F59	0x54D4	# <CJK>
+0x5F5A	0x5472	# <CJK>
+0x5F5B	0x54A3	# <CJK>
+0x5F5C	0x54D5	# <CJK>
+0x5F5D	0x54BB	# <CJK>
+0x5F5E	0x54BF	# <CJK>
+0x5F5F	0x54CC	# <CJK>
+0x5F60	0x54D9	# <CJK>
+0x5F61	0x54DA	# <CJK>
+0x5F62	0x54DC	# <CJK>
+0x5F63	0x54A9	# <CJK>
+0x5F64	0x54AA	# <CJK>
+0x5F65	0x54A4	# <CJK>
+0x5F66	0x54DD	# <CJK>
+0x5F67	0x54CF	# <CJK>
+0x5F68	0x54DE	# <CJK>
+0x5F69	0x551B	# <CJK>
+0x5F6A	0x54E7	# <CJK>
+0x5F6B	0x5520	# <CJK>
+0x5F6C	0x54FD	# <CJK>
+0x5F6D	0x5514	# <CJK>
+0x5F6E	0x54F3	# <CJK>
+0x5F6F	0x5522	# <CJK>
+0x5F70	0x5523	# <CJK>
+0x5F71	0x550F	# <CJK>
+0x5F72	0x5511	# <CJK>
+0x5F73	0x5527	# <CJK>
+0x5F74	0x552A	# <CJK>
+0x5F75	0x5567	# <CJK>
+0x5F76	0x558F	# <CJK>
+0x5F77	0x55B5	# <CJK>
+0x5F78	0x5549	# <CJK>
+0x5F79	0x556D	# <CJK>
+0x5F7A	0x5541	# <CJK>
+0x5F7B	0x5555	# <CJK>
+0x5F7C	0x553F	# <CJK>
+0x5F7D	0x5550	# <CJK>
+0x5F7E	0x553C	# <CJK>
+0x6021	0x5537	# <CJK>
+0x6022	0x5556	# <CJK>
+0x6023	0x5575	# <CJK>
+0x6024	0x5576	# <CJK>
+0x6025	0x5577	# <CJK>
+0x6026	0x5533	# <CJK>
+0x6027	0x5530	# <CJK>
+0x6028	0x555C	# <CJK>
+0x6029	0x558B	# <CJK>
+0x602A	0x55D2	# <CJK>
+0x602B	0x5583	# <CJK>
+0x602C	0x55B1	# <CJK>
+0x602D	0x55B9	# <CJK>
+0x602E	0x5588	# <CJK>
+0x602F	0x5581	# <CJK>
+0x6030	0x559F	# <CJK>
+0x6031	0x557E	# <CJK>
+0x6032	0x55D6	# <CJK>
+0x6033	0x5591	# <CJK>
+0x6034	0x557B	# <CJK>
+0x6035	0x55DF	# <CJK>
+0x6036	0x55BD	# <CJK>
+0x6037	0x55BE	# <CJK>
+0x6038	0x5594	# <CJK>
+0x6039	0x5599	# <CJK>
+0x603A	0x55EA	# <CJK>
+0x603B	0x55F7	# <CJK>
+0x603C	0x55C9	# <CJK>
+0x603D	0x561F	# <CJK>
+0x603E	0x55D1	# <CJK>
+0x603F	0x55EB	# <CJK>
+0x6040	0x55EC	# <CJK>
+0x6041	0x55D4	# <CJK>
+0x6042	0x55E6	# <CJK>
+0x6043	0x55DD	# <CJK>
+0x6044	0x55C4	# <CJK>
+0x6045	0x55EF	# <CJK>
+0x6046	0x55E5	# <CJK>
+0x6047	0x55F2	# <CJK>
+0x6048	0x55F3	# <CJK>
+0x6049	0x55CC	# <CJK>
+0x604A	0x55CD	# <CJK>
+0x604B	0x55E8	# <CJK>
+0x604C	0x55F5	# <CJK>
+0x604D	0x55E4	# <CJK>
+0x604E	0x8F94	# <CJK>
+0x604F	0x561E	# <CJK>
+0x6050	0x5608	# <CJK>
+0x6051	0x560C	# <CJK>
+0x6052	0x5601	# <CJK>
+0x6053	0x5624	# <CJK>
+0x6054	0x5623	# <CJK>
+0x6055	0x55FE	# <CJK>
+0x6056	0x5600	# <CJK>
+0x6057	0x5627	# <CJK>
+0x6058	0x562D	# <CJK>
+0x6059	0x5658	# <CJK>
+0x605A	0x5639	# <CJK>
+0x605B	0x5657	# <CJK>
+0x605C	0x562C	# <CJK>
+0x605D	0x564D	# <CJK>
+0x605E	0x5662	# <CJK>
+0x605F	0x5659	# <CJK>
+0x6060	0x565C	# <CJK>
+0x6061	0x564C	# <CJK>
+0x6062	0x5654	# <CJK>
+0x6063	0x5686	# <CJK>
+0x6064	0x5664	# <CJK>
+0x6065	0x5671	# <CJK>
+0x6066	0x566B	# <CJK>
+0x6067	0x567B	# <CJK>
+0x6068	0x567C	# <CJK>
+0x6069	0x5685	# <CJK>
+0x606A	0x5693	# <CJK>
+0x606B	0x56AF	# <CJK>
+0x606C	0x56D4	# <CJK>
+0x606D	0x56D7	# <CJK>
+0x606E	0x56DD	# <CJK>
+0x606F	0x56E1	# <CJK>
+0x6070	0x56F5	# <CJK>
+0x6071	0x56EB	# <CJK>
+0x6072	0x56F9	# <CJK>
+0x6073	0x56FF	# <CJK>
+0x6074	0x5704	# <CJK>
+0x6075	0x570A	# <CJK>
+0x6076	0x5709	# <CJK>
+0x6077	0x571C	# <CJK>
+0x6078	0x5E0F	# <CJK>
+0x6079	0x5E19	# <CJK>
+0x607A	0x5E14	# <CJK>
+0x607B	0x5E11	# <CJK>
+0x607C	0x5E31	# <CJK>
+0x607D	0x5E3B	# <CJK>
+0x607E	0x5E3C	# <CJK>
+0x6121	0x5E37	# <CJK>
+0x6122	0x5E44	# <CJK>
+0x6123	0x5E54	# <CJK>
+0x6124	0x5E5B	# <CJK>
+0x6125	0x5E5E	# <CJK>
+0x6126	0x5E61	# <CJK>
+0x6127	0x5C8C	# <CJK>
+0x6128	0x5C7A	# <CJK>
+0x6129	0x5C8D	# <CJK>
+0x612A	0x5C90	# <CJK>
+0x612B	0x5C96	# <CJK>
+0x612C	0x5C88	# <CJK>
+0x612D	0x5C98	# <CJK>
+0x612E	0x5C99	# <CJK>
+0x612F	0x5C91	# <CJK>
+0x6130	0x5C9A	# <CJK>
+0x6131	0x5C9C	# <CJK>
+0x6132	0x5CB5	# <CJK>
+0x6133	0x5CA2	# <CJK>
+0x6134	0x5CBD	# <CJK>
+0x6135	0x5CAC	# <CJK>
+0x6136	0x5CAB	# <CJK>
+0x6137	0x5CB1	# <CJK>
+0x6138	0x5CA3	# <CJK>
+0x6139	0x5CC1	# <CJK>
+0x613A	0x5CB7	# <CJK>
+0x613B	0x5CC4	# <CJK>
+0x613C	0x5CD2	# <CJK>
+0x613D	0x5CE4	# <CJK>
+0x613E	0x5CCB	# <CJK>
+0x613F	0x5CE5	# <CJK>
+0x6140	0x5D02	# <CJK>
+0x6141	0x5D03	# <CJK>
+0x6142	0x5D27	# <CJK>
+0x6143	0x5D26	# <CJK>
+0x6144	0x5D2E	# <CJK>
+0x6145	0x5D24	# <CJK>
+0x6146	0x5D1E	# <CJK>
+0x6147	0x5D06	# <CJK>
+0x6148	0x5D1B	# <CJK>
+0x6149	0x5D58	# <CJK>
+0x614A	0x5D3E	# <CJK>
+0x614B	0x5D34	# <CJK>
+0x614C	0x5D3D	# <CJK>
+0x614D	0x5D6C	# <CJK>
+0x614E	0x5D5B	# <CJK>
+0x614F	0x5D6F	# <CJK>
+0x6150	0x5D5D	# <CJK>
+0x6151	0x5D6B	# <CJK>
+0x6152	0x5D4B	# <CJK>
+0x6153	0x5D4A	# <CJK>
+0x6154	0x5D69	# <CJK>
+0x6155	0x5D74	# <CJK>
+0x6156	0x5D82	# <CJK>
+0x6157	0x5D99	# <CJK>
+0x6158	0x5D9D	# <CJK>
+0x6159	0x8C73	# <CJK>
+0x615A	0x5DB7	# <CJK>
+0x615B	0x5DC5	# <CJK>
+0x615C	0x5F73	# <CJK>
+0x615D	0x5F77	# <CJK>
+0x615E	0x5F82	# <CJK>
+0x615F	0x5F87	# <CJK>
+0x6160	0x5F89	# <CJK>
+0x6161	0x5F8C	# <CJK>
+0x6162	0x5F95	# <CJK>
+0x6163	0x5F99	# <CJK>
+0x6164	0x5F9C	# <CJK>
+0x6165	0x5FA8	# <CJK>
+0x6166	0x5FAD	# <CJK>
+0x6167	0x5FB5	# <CJK>
+0x6168	0x5FBC	# <CJK>
+0x6169	0x8862	# <CJK>
+0x616A	0x5F61	# <CJK>
+0x616B	0x72AD	# <CJK>
+0x616C	0x72B0	# <CJK>
+0x616D	0x72B4	# <CJK>
+0x616E	0x72B7	# <CJK>
+0x616F	0x72B8	# <CJK>
+0x6170	0x72C3	# <CJK>
+0x6171	0x72C1	# <CJK>
+0x6172	0x72CE	# <CJK>
+0x6173	0x72CD	# <CJK>
+0x6174	0x72D2	# <CJK>
+0x6175	0x72E8	# <CJK>
+0x6176	0x72EF	# <CJK>
+0x6177	0x72E9	# <CJK>
+0x6178	0x72F2	# <CJK>
+0x6179	0x72F4	# <CJK>
+0x617A	0x72F7	# <CJK>
+0x617B	0x7301	# <CJK>
+0x617C	0x72F3	# <CJK>
+0x617D	0x7303	# <CJK>
+0x617E	0x72FA	# <CJK>
+0x6221	0x72FB	# <CJK>
+0x6222	0x7317	# <CJK>
+0x6223	0x7313	# <CJK>
+0x6224	0x7321	# <CJK>
+0x6225	0x730A	# <CJK>
+0x6226	0x731E	# <CJK>
+0x6227	0x731D	# <CJK>
+0x6228	0x7315	# <CJK>
+0x6229	0x7322	# <CJK>
+0x622A	0x7339	# <CJK>
+0x622B	0x7325	# <CJK>
+0x622C	0x732C	# <CJK>
+0x622D	0x7338	# <CJK>
+0x622E	0x7331	# <CJK>
+0x622F	0x7350	# <CJK>
+0x6230	0x734D	# <CJK>
+0x6231	0x7357	# <CJK>
+0x6232	0x7360	# <CJK>
+0x6233	0x736C	# <CJK>
+0x6234	0x736F	# <CJK>
+0x6235	0x737E	# <CJK>
+0x6236	0x821B	# <CJK>
+0x6237	0x5925	# <CJK>
+0x6238	0x98E7	# <CJK>
+0x6239	0x5924	# <CJK>
+0x623A	0x5902	# <CJK>
+0x623B	0x9963	# <CJK>
+0x623C	0x9967	# <CJK>
+0x623D	0x9968	# <CJK>
+0x623E	0x9969	# <CJK>
+0x623F	0x996A	# <CJK>
+0x6240	0x996B	# <CJK>
+0x6241	0x996C	# <CJK>
+0x6242	0x9974	# <CJK>
+0x6243	0x9977	# <CJK>
+0x6244	0x997D	# <CJK>
+0x6245	0x9980	# <CJK>
+0x6246	0x9984	# <CJK>
+0x6247	0x9987	# <CJK>
+0x6248	0x998A	# <CJK>
+0x6249	0x998D	# <CJK>
+0x624A	0x9990	# <CJK>
+0x624B	0x9991	# <CJK>
+0x624C	0x9993	# <CJK>
+0x624D	0x9994	# <CJK>
+0x624E	0x9995	# <CJK>
+0x624F	0x5E80	# <CJK>
+0x6250	0x5E91	# <CJK>
+0x6251	0x5E8B	# <CJK>
+0x6252	0x5E96	# <CJK>
+0x6253	0x5EA5	# <CJK>
+0x6254	0x5EA0	# <CJK>
+0x6255	0x5EB9	# <CJK>
+0x6256	0x5EB5	# <CJK>
+0x6257	0x5EBE	# <CJK>
+0x6258	0x5EB3	# <CJK>
+0x6259	0x8D53	# <CJK>
+0x625A	0x5ED2	# <CJK>
+0x625B	0x5ED1	# <CJK>
+0x625C	0x5EDB	# <CJK>
+0x625D	0x5EE8	# <CJK>
+0x625E	0x5EEA	# <CJK>
+0x625F	0x81BA	# <CJK>
+0x6260	0x5FC4	# <CJK>
+0x6261	0x5FC9	# <CJK>
+0x6262	0x5FD6	# <CJK>
+0x6263	0x5FCF	# <CJK>
+0x6264	0x6003	# <CJK>
+0x6265	0x5FEE	# <CJK>
+0x6266	0x6004	# <CJK>
+0x6267	0x5FE1	# <CJK>
+0x6268	0x5FE4	# <CJK>
+0x6269	0x5FFE	# <CJK>
+0x626A	0x6005	# <CJK>
+0x626B	0x6006	# <CJK>
+0x626C	0x5FEA	# <CJK>
+0x626D	0x5FED	# <CJK>
+0x626E	0x5FF8	# <CJK>
+0x626F	0x6019	# <CJK>
+0x6270	0x6035	# <CJK>
+0x6271	0x6026	# <CJK>
+0x6272	0x601B	# <CJK>
+0x6273	0x600F	# <CJK>
+0x6274	0x600D	# <CJK>
+0x6275	0x6029	# <CJK>
+0x6276	0x602B	# <CJK>
+0x6277	0x600A	# <CJK>
+0x6278	0x603F	# <CJK>
+0x6279	0x6021	# <CJK>
+0x627A	0x6078	# <CJK>
+0x627B	0x6079	# <CJK>
+0x627C	0x607B	# <CJK>
+0x627D	0x607A	# <CJK>
+0x627E	0x6042	# <CJK>
+0x6321	0x606A	# <CJK>
+0x6322	0x607D	# <CJK>
+0x6323	0x6096	# <CJK>
+0x6324	0x609A	# <CJK>
+0x6325	0x60AD	# <CJK>
+0x6326	0x609D	# <CJK>
+0x6327	0x6083	# <CJK>
+0x6328	0x6092	# <CJK>
+0x6329	0x608C	# <CJK>
+0x632A	0x609B	# <CJK>
+0x632B	0x60EC	# <CJK>
+0x632C	0x60BB	# <CJK>
+0x632D	0x60B1	# <CJK>
+0x632E	0x60DD	# <CJK>
+0x632F	0x60D8	# <CJK>
+0x6330	0x60C6	# <CJK>
+0x6331	0x60DA	# <CJK>
+0x6332	0x60B4	# <CJK>
+0x6333	0x6120	# <CJK>
+0x6334	0x6126	# <CJK>
+0x6335	0x6115	# <CJK>
+0x6336	0x6123	# <CJK>
+0x6337	0x60F4	# <CJK>
+0x6338	0x6100	# <CJK>
+0x6339	0x610E	# <CJK>
+0x633A	0x612B	# <CJK>
+0x633B	0x614A	# <CJK>
+0x633C	0x6175	# <CJK>
+0x633D	0x61AC	# <CJK>
+0x633E	0x6194	# <CJK>
+0x633F	0x61A7	# <CJK>
+0x6340	0x61B7	# <CJK>
+0x6341	0x61D4	# <CJK>
+0x6342	0x61F5	# <CJK>
+0x6343	0x5FDD	# <CJK>
+0x6344	0x96B3	# <CJK>
+0x6345	0x95E9	# <CJK>
+0x6346	0x95EB	# <CJK>
+0x6347	0x95F1	# <CJK>
+0x6348	0x95F3	# <CJK>
+0x6349	0x95F5	# <CJK>
+0x634A	0x95F6	# <CJK>
+0x634B	0x95FC	# <CJK>
+0x634C	0x95FE	# <CJK>
+0x634D	0x9603	# <CJK>
+0x634E	0x9604	# <CJK>
+0x634F	0x9606	# <CJK>
+0x6350	0x9608	# <CJK>
+0x6351	0x960A	# <CJK>
+0x6352	0x960B	# <CJK>
+0x6353	0x960C	# <CJK>
+0x6354	0x960D	# <CJK>
+0x6355	0x960F	# <CJK>
+0x6356	0x9612	# <CJK>
+0x6357	0x9615	# <CJK>
+0x6358	0x9616	# <CJK>
+0x6359	0x9617	# <CJK>
+0x635A	0x9619	# <CJK>
+0x635B	0x961A	# <CJK>
+0x635C	0x4E2C	# <CJK>
+0x635D	0x723F	# <CJK>
+0x635E	0x6215	# <CJK>
+0x635F	0x6C35	# <CJK>
+0x6360	0x6C54	# <CJK>
+0x6361	0x6C5C	# <CJK>
+0x6362	0x6C4A	# <CJK>
+0x6363	0x6CA3	# <CJK>
+0x6364	0x6C85	# <CJK>
+0x6365	0x6C90	# <CJK>
+0x6366	0x6C94	# <CJK>
+0x6367	0x6C8C	# <CJK>
+0x6368	0x6C68	# <CJK>
+0x6369	0x6C69	# <CJK>
+0x636A	0x6C74	# <CJK>
+0x636B	0x6C76	# <CJK>
+0x636C	0x6C86	# <CJK>
+0x636D	0x6CA9	# <CJK>
+0x636E	0x6CD0	# <CJK>
+0x636F	0x6CD4	# <CJK>
+0x6370	0x6CAD	# <CJK>
+0x6371	0x6CF7	# <CJK>
+0x6372	0x6CF8	# <CJK>
+0x6373	0x6CF1	# <CJK>
+0x6374	0x6CD7	# <CJK>
+0x6375	0x6CB2	# <CJK>
+0x6376	0x6CE0	# <CJK>
+0x6377	0x6CD6	# <CJK>
+0x6378	0x6CFA	# <CJK>
+0x6379	0x6CEB	# <CJK>
+0x637A	0x6CEE	# <CJK>
+0x637B	0x6CB1	# <CJK>
+0x637C	0x6CD3	# <CJK>
+0x637D	0x6CEF	# <CJK>
+0x637E	0x6CFE	# <CJK>
+0x6421	0x6D39	# <CJK>
+0x6422	0x6D27	# <CJK>
+0x6423	0x6D0C	# <CJK>
+0x6424	0x6D43	# <CJK>
+0x6425	0x6D48	# <CJK>
+0x6426	0x6D07	# <CJK>
+0x6427	0x6D04	# <CJK>
+0x6428	0x6D19	# <CJK>
+0x6429	0x6D0E	# <CJK>
+0x642A	0x6D2B	# <CJK>
+0x642B	0x6D4D	# <CJK>
+0x642C	0x6D2E	# <CJK>
+0x642D	0x6D35	# <CJK>
+0x642E	0x6D1A	# <CJK>
+0x642F	0x6D4F	# <CJK>
+0x6430	0x6D52	# <CJK>
+0x6431	0x6D54	# <CJK>
+0x6432	0x6D33	# <CJK>
+0x6433	0x6D91	# <CJK>
+0x6434	0x6D6F	# <CJK>
+0x6435	0x6D9E	# <CJK>
+0x6436	0x6DA0	# <CJK>
+0x6437	0x6D5E	# <CJK>
+0x6438	0x6D93	# <CJK>
+0x6439	0x6D94	# <CJK>
+0x643A	0x6D5C	# <CJK>
+0x643B	0x6D60	# <CJK>
+0x643C	0x6D7C	# <CJK>
+0x643D	0x6D63	# <CJK>
+0x643E	0x6E1A	# <CJK>
+0x643F	0x6DC7	# <CJK>
+0x6440	0x6DC5	# <CJK>
+0x6441	0x6DDE	# <CJK>
+0x6442	0x6E0E	# <CJK>
+0x6443	0x6DBF	# <CJK>
+0x6444	0x6DE0	# <CJK>
+0x6445	0x6E11	# <CJK>
+0x6446	0x6DE6	# <CJK>
+0x6447	0x6DDD	# <CJK>
+0x6448	0x6DD9	# <CJK>
+0x6449	0x6E16	# <CJK>
+0x644A	0x6DAB	# <CJK>
+0x644B	0x6E0C	# <CJK>
+0x644C	0x6DAE	# <CJK>
+0x644D	0x6E2B	# <CJK>
+0x644E	0x6E6E	# <CJK>
+0x644F	0x6E4E	# <CJK>
+0x6450	0x6E6B	# <CJK>
+0x6451	0x6EB2	# <CJK>
+0x6452	0x6E5F	# <CJK>
+0x6453	0x6E86	# <CJK>
+0x6454	0x6E53	# <CJK>
+0x6455	0x6E54	# <CJK>
+0x6456	0x6E32	# <CJK>
+0x6457	0x6E25	# <CJK>
+0x6458	0x6E44	# <CJK>
+0x6459	0x6EDF	# <CJK>
+0x645A	0x6EB1	# <CJK>
+0x645B	0x6E98	# <CJK>
+0x645C	0x6EE0	# <CJK>
+0x645D	0x6F2D	# <CJK>
+0x645E	0x6EE2	# <CJK>
+0x645F	0x6EA5	# <CJK>
+0x6460	0x6EA7	# <CJK>
+0x6461	0x6EBD	# <CJK>
+0x6462	0x6EBB	# <CJK>
+0x6463	0x6EB7	# <CJK>
+0x6464	0x6ED7	# <CJK>
+0x6465	0x6EB4	# <CJK>
+0x6466	0x6ECF	# <CJK>
+0x6467	0x6E8F	# <CJK>
+0x6468	0x6EC2	# <CJK>
+0x6469	0x6E9F	# <CJK>
+0x646A	0x6F62	# <CJK>
+0x646B	0x6F46	# <CJK>
+0x646C	0x6F47	# <CJK>
+0x646D	0x6F24	# <CJK>
+0x646E	0x6F15	# <CJK>
+0x646F	0x6EF9	# <CJK>
+0x6470	0x6F2F	# <CJK>
+0x6471	0x6F36	# <CJK>
+0x6472	0x6F4B	# <CJK>
+0x6473	0x6F74	# <CJK>
+0x6474	0x6F2A	# <CJK>
+0x6475	0x6F09	# <CJK>
+0x6476	0x6F29	# <CJK>
+0x6477	0x6F89	# <CJK>
+0x6478	0x6F8D	# <CJK>
+0x6479	0x6F8C	# <CJK>
+0x647A	0x6F78	# <CJK>
+0x647B	0x6F72	# <CJK>
+0x647C	0x6F7C	# <CJK>
+0x647D	0x6F7A	# <CJK>
+0x647E	0x6FD1	# <CJK>
+0x6521	0x6FC9	# <CJK>
+0x6522	0x6FA7	# <CJK>
+0x6523	0x6FB9	# <CJK>
+0x6524	0x6FB6	# <CJK>
+0x6525	0x6FC2	# <CJK>
+0x6526	0x6FE1	# <CJK>
+0x6527	0x6FEE	# <CJK>
+0x6528	0x6FDE	# <CJK>
+0x6529	0x6FE0	# <CJK>
+0x652A	0x6FEF	# <CJK>
+0x652B	0x701A	# <CJK>
+0x652C	0x7023	# <CJK>
+0x652D	0x701B	# <CJK>
+0x652E	0x7039	# <CJK>
+0x652F	0x7035	# <CJK>
+0x6530	0x704F	# <CJK>
+0x6531	0x705E	# <CJK>
+0x6532	0x5B80	# <CJK>
+0x6533	0x5B84	# <CJK>
+0x6534	0x5B95	# <CJK>
+0x6535	0x5B93	# <CJK>
+0x6536	0x5BA5	# <CJK>
+0x6537	0x5BB8	# <CJK>
+0x6538	0x752F	# <CJK>
+0x6539	0x9A9E	# <CJK>
+0x653A	0x6434	# <CJK>
+0x653B	0x5BE4	# <CJK>
+0x653C	0x5BEE	# <CJK>
+0x653D	0x8930	# <CJK>
+0x653E	0x5BF0	# <CJK>
+0x653F	0x8E47	# <CJK>
+0x6540	0x8B07	# <CJK>
+0x6541	0x8FB6	# <CJK>
+0x6542	0x8FD3	# <CJK>
+0x6543	0x8FD5	# <CJK>
+0x6544	0x8FE5	# <CJK>
+0x6545	0x8FEE	# <CJK>
+0x6546	0x8FE4	# <CJK>
+0x6547	0x8FE9	# <CJK>
+0x6548	0x8FE6	# <CJK>
+0x6549	0x8FF3	# <CJK>
+0x654A	0x8FE8	# <CJK>
+0x654B	0x9005	# <CJK>
+0x654C	0x9004	# <CJK>
+0x654D	0x900B	# <CJK>
+0x654E	0x9026	# <CJK>
+0x654F	0x9011	# <CJK>
+0x6550	0x900D	# <CJK>
+0x6551	0x9016	# <CJK>
+0x6552	0x9021	# <CJK>
+0x6553	0x9035	# <CJK>
+0x6554	0x9036	# <CJK>
+0x6555	0x902D	# <CJK>
+0x6556	0x902F	# <CJK>
+0x6557	0x9044	# <CJK>
+0x6558	0x9051	# <CJK>
+0x6559	0x9052	# <CJK>
+0x655A	0x9050	# <CJK>
+0x655B	0x9068	# <CJK>
+0x655C	0x9058	# <CJK>
+0x655D	0x9062	# <CJK>
+0x655E	0x905B	# <CJK>
+0x655F	0x66B9	# <CJK>
+0x6560	0x9074	# <CJK>
+0x6561	0x907D	# <CJK>
+0x6562	0x9082	# <CJK>
+0x6563	0x9088	# <CJK>
+0x6564	0x9083	# <CJK>
+0x6565	0x908B	# <CJK>
+0x6566	0x5F50	# <CJK>
+0x6567	0x5F57	# <CJK>
+0x6568	0x5F56	# <CJK>
+0x6569	0x5F58	# <CJK>
+0x656A	0x5C3B	# <CJK>
+0x656B	0x54AB	# <CJK>
+0x656C	0x5C50	# <CJK>
+0x656D	0x5C59	# <CJK>
+0x656E	0x5B71	# <CJK>
+0x656F	0x5C63	# <CJK>
+0x6570	0x5C66	# <CJK>
+0x6571	0x7FBC	# <CJK>
+0x6572	0x5F2A	# <CJK>
+0x6573	0x5F29	# <CJK>
+0x6574	0x5F2D	# <CJK>
+0x6575	0x8274	# <CJK>
+0x6576	0x5F3C	# <CJK>
+0x6577	0x9B3B	# <CJK>
+0x6578	0x5C6E	# <CJK>
+0x6579	0x5981	# <CJK>
+0x657A	0x5983	# <CJK>
+0x657B	0x598D	# <CJK>
+0x657C	0x59A9	# <CJK>
+0x657D	0x59AA	# <CJK>
+0x657E	0x59A3	# <CJK>
+0x6621	0x5997	# <CJK>
+0x6622	0x59CA	# <CJK>
+0x6623	0x59AB	# <CJK>
+0x6624	0x599E	# <CJK>
+0x6625	0x59A4	# <CJK>
+0x6626	0x59D2	# <CJK>
+0x6627	0x59B2	# <CJK>
+0x6628	0x59AF	# <CJK>
+0x6629	0x59D7	# <CJK>
+0x662A	0x59BE	# <CJK>
+0x662B	0x5A05	# <CJK>
+0x662C	0x5A06	# <CJK>
+0x662D	0x59DD	# <CJK>
+0x662E	0x5A08	# <CJK>
+0x662F	0x59E3	# <CJK>
+0x6630	0x59D8	# <CJK>
+0x6631	0x59F9	# <CJK>
+0x6632	0x5A0C	# <CJK>
+0x6633	0x5A09	# <CJK>
+0x6634	0x5A32	# <CJK>
+0x6635	0x5A34	# <CJK>
+0x6636	0x5A11	# <CJK>
+0x6637	0x5A23	# <CJK>
+0x6638	0x5A13	# <CJK>
+0x6639	0x5A40	# <CJK>
+0x663A	0x5A67	# <CJK>
+0x663B	0x5A4A	# <CJK>
+0x663C	0x5A55	# <CJK>
+0x663D	0x5A3C	# <CJK>
+0x663E	0x5A62	# <CJK>
+0x663F	0x5A75	# <CJK>
+0x6640	0x80EC	# <CJK>
+0x6641	0x5AAA	# <CJK>
+0x6642	0x5A9B	# <CJK>
+0x6643	0x5A77	# <CJK>
+0x6644	0x5A7A	# <CJK>
+0x6645	0x5ABE	# <CJK>
+0x6646	0x5AEB	# <CJK>
+0x6647	0x5AB2	# <CJK>
+0x6648	0x5AD2	# <CJK>
+0x6649	0x5AD4	# <CJK>
+0x664A	0x5AB8	# <CJK>
+0x664B	0x5AE0	# <CJK>
+0x664C	0x5AE3	# <CJK>
+0x664D	0x5AF1	# <CJK>
+0x664E	0x5AD6	# <CJK>
+0x664F	0x5AE6	# <CJK>
+0x6650	0x5AD8	# <CJK>
+0x6651	0x5ADC	# <CJK>
+0x6652	0x5B09	# <CJK>
+0x6653	0x5B17	# <CJK>
+0x6654	0x5B16	# <CJK>
+0x6655	0x5B32	# <CJK>
+0x6656	0x5B37	# <CJK>
+0x6657	0x5B40	# <CJK>
+0x6658	0x5C15	# <CJK>
+0x6659	0x5C1C	# <CJK>
+0x665A	0x5B5A	# <CJK>
+0x665B	0x5B65	# <CJK>
+0x665C	0x5B73	# <CJK>
+0x665D	0x5B51	# <CJK>
+0x665E	0x5B53	# <CJK>
+0x665F	0x5B62	# <CJK>
+0x6660	0x9A75	# <CJK>
+0x6661	0x9A77	# <CJK>
+0x6662	0x9A78	# <CJK>
+0x6663	0x9A7A	# <CJK>
+0x6664	0x9A7F	# <CJK>
+0x6665	0x9A7D	# <CJK>
+0x6666	0x9A80	# <CJK>
+0x6667	0x9A81	# <CJK>
+0x6668	0x9A85	# <CJK>
+0x6669	0x9A88	# <CJK>
+0x666A	0x9A8A	# <CJK>
+0x666B	0x9A90	# <CJK>
+0x666C	0x9A92	# <CJK>
+0x666D	0x9A93	# <CJK>
+0x666E	0x9A96	# <CJK>
+0x666F	0x9A98	# <CJK>
+0x6670	0x9A9B	# <CJK>
+0x6671	0x9A9C	# <CJK>
+0x6672	0x9A9D	# <CJK>
+0x6673	0x9A9F	# <CJK>
+0x6674	0x9AA0	# <CJK>
+0x6675	0x9AA2	# <CJK>
+0x6676	0x9AA3	# <CJK>
+0x6677	0x9AA5	# <CJK>
+0x6678	0x9AA7	# <CJK>
+0x6679	0x7E9F	# <CJK>
+0x667A	0x7EA1	# <CJK>
+0x667B	0x7EA3	# <CJK>
+0x667C	0x7EA5	# <CJK>
+0x667D	0x7EA8	# <CJK>
+0x667E	0x7EA9	# <CJK>
+0x6721	0x7EAD	# <CJK>
+0x6722	0x7EB0	# <CJK>
+0x6723	0x7EBE	# <CJK>
+0x6724	0x7EC0	# <CJK>
+0x6725	0x7EC1	# <CJK>
+0x6726	0x7EC2	# <CJK>
+0x6727	0x7EC9	# <CJK>
+0x6728	0x7ECB	# <CJK>
+0x6729	0x7ECC	# <CJK>
+0x672A	0x7ED0	# <CJK>
+0x672B	0x7ED4	# <CJK>
+0x672C	0x7ED7	# <CJK>
+0x672D	0x7EDB	# <CJK>
+0x672E	0x7EE0	# <CJK>
+0x672F	0x7EE1	# <CJK>
+0x6730	0x7EE8	# <CJK>
+0x6731	0x7EEB	# <CJK>
+0x6732	0x7EEE	# <CJK>
+0x6733	0x7EEF	# <CJK>
+0x6734	0x7EF1	# <CJK>
+0x6735	0x7EF2	# <CJK>
+0x6736	0x7F0D	# <CJK>
+0x6737	0x7EF6	# <CJK>
+0x6738	0x7EFA	# <CJK>
+0x6739	0x7EFB	# <CJK>
+0x673A	0x7EFE	# <CJK>
+0x673B	0x7F01	# <CJK>
+0x673C	0x7F02	# <CJK>
+0x673D	0x7F03	# <CJK>
+0x673E	0x7F07	# <CJK>
+0x673F	0x7F08	# <CJK>
+0x6740	0x7F0B	# <CJK>
+0x6741	0x7F0C	# <CJK>
+0x6742	0x7F0F	# <CJK>
+0x6743	0x7F11	# <CJK>
+0x6744	0x7F12	# <CJK>
+0x6745	0x7F17	# <CJK>
+0x6746	0x7F19	# <CJK>
+0x6747	0x7F1C	# <CJK>
+0x6748	0x7F1B	# <CJK>
+0x6749	0x7F1F	# <CJK>
+0x674A	0x7F21	# <CJK>
+0x674B	0x7F22	# <CJK>
+0x674C	0x7F23	# <CJK>
+0x674D	0x7F24	# <CJK>
+0x674E	0x7F25	# <CJK>
+0x674F	0x7F26	# <CJK>
+0x6750	0x7F27	# <CJK>
+0x6751	0x7F2A	# <CJK>
+0x6752	0x7F2B	# <CJK>
+0x6753	0x7F2C	# <CJK>
+0x6754	0x7F2D	# <CJK>
+0x6755	0x7F2F	# <CJK>
+0x6756	0x7F30	# <CJK>
+0x6757	0x7F31	# <CJK>
+0x6758	0x7F32	# <CJK>
+0x6759	0x7F33	# <CJK>
+0x675A	0x7F35	# <CJK>
+0x675B	0x5E7A	# <CJK>
+0x675C	0x757F	# <CJK>
+0x675D	0x5DDB	# <CJK>
+0x675E	0x753E	# <CJK>
+0x675F	0x9095	# <CJK>
+0x6760	0x738E	# <CJK>
+0x6761	0x7391	# <CJK>
+0x6762	0x73AE	# <CJK>
+0x6763	0x73A2	# <CJK>
+0x6764	0x739F	# <CJK>
+0x6765	0x73CF	# <CJK>
+0x6766	0x73C2	# <CJK>
+0x6767	0x73D1	# <CJK>
+0x6768	0x73B7	# <CJK>
+0x6769	0x73B3	# <CJK>
+0x676A	0x73C0	# <CJK>
+0x676B	0x73C9	# <CJK>
+0x676C	0x73C8	# <CJK>
+0x676D	0x73E5	# <CJK>
+0x676E	0x73D9	# <CJK>
+0x676F	0x987C	# <CJK>
+0x6770	0x740A	# <CJK>
+0x6771	0x73E9	# <CJK>
+0x6772	0x73E7	# <CJK>
+0x6773	0x73DE	# <CJK>
+0x6774	0x73BA	# <CJK>
+0x6775	0x73F2	# <CJK>
+0x6776	0x740F	# <CJK>
+0x6777	0x742A	# <CJK>
+0x6778	0x745B	# <CJK>
+0x6779	0x7426	# <CJK>
+0x677A	0x7425	# <CJK>
+0x677B	0x7428	# <CJK>
+0x677C	0x7430	# <CJK>
+0x677D	0x742E	# <CJK>
+0x677E	0x742C	# <CJK>
+0x6821	0x741B	# <CJK>
+0x6822	0x741A	# <CJK>
+0x6823	0x7441	# <CJK>
+0x6824	0x745C	# <CJK>
+0x6825	0x7457	# <CJK>
+0x6826	0x7455	# <CJK>
+0x6827	0x7459	# <CJK>
+0x6828	0x7477	# <CJK>
+0x6829	0x746D	# <CJK>
+0x682A	0x747E	# <CJK>
+0x682B	0x749C	# <CJK>
+0x682C	0x748E	# <CJK>
+0x682D	0x7480	# <CJK>
+0x682E	0x7481	# <CJK>
+0x682F	0x7487	# <CJK>
+0x6830	0x748B	# <CJK>
+0x6831	0x749E	# <CJK>
+0x6832	0x74A8	# <CJK>
+0x6833	0x74A9	# <CJK>
+0x6834	0x7490	# <CJK>
+0x6835	0x74A7	# <CJK>
+0x6836	0x74D2	# <CJK>
+0x6837	0x74BA	# <CJK>
+0x6838	0x97EA	# <CJK>
+0x6839	0x97EB	# <CJK>
+0x683A	0x97EC	# <CJK>
+0x683B	0x674C	# <CJK>
+0x683C	0x6753	# <CJK>
+0x683D	0x675E	# <CJK>
+0x683E	0x6748	# <CJK>
+0x683F	0x6769	# <CJK>
+0x6840	0x67A5	# <CJK>
+0x6841	0x6787	# <CJK>
+0x6842	0x676A	# <CJK>
+0x6843	0x6773	# <CJK>
+0x6844	0x6798	# <CJK>
+0x6845	0x67A7	# <CJK>
+0x6846	0x6775	# <CJK>
+0x6847	0x67A8	# <CJK>
+0x6848	0x679E	# <CJK>
+0x6849	0x67AD	# <CJK>
+0x684A	0x678B	# <CJK>
+0x684B	0x6777	# <CJK>
+0x684C	0x677C	# <CJK>
+0x684D	0x67F0	# <CJK>
+0x684E	0x6809	# <CJK>
+0x684F	0x67D8	# <CJK>
+0x6850	0x680A	# <CJK>
+0x6851	0x67E9	# <CJK>
+0x6852	0x67B0	# <CJK>
+0x6853	0x680C	# <CJK>
+0x6854	0x67D9	# <CJK>
+0x6855	0x67B5	# <CJK>
+0x6856	0x67DA	# <CJK>
+0x6857	0x67B3	# <CJK>
+0x6858	0x67DD	# <CJK>
+0x6859	0x6800	# <CJK>
+0x685A	0x67C3	# <CJK>
+0x685B	0x67B8	# <CJK>
+0x685C	0x67E2	# <CJK>
+0x685D	0x680E	# <CJK>
+0x685E	0x67C1	# <CJK>
+0x685F	0x67FD	# <CJK>
+0x6860	0x6832	# <CJK>
+0x6861	0x6833	# <CJK>
+0x6862	0x6860	# <CJK>
+0x6863	0x6861	# <CJK>
+0x6864	0x684E	# <CJK>
+0x6865	0x6862	# <CJK>
+0x6866	0x6844	# <CJK>
+0x6867	0x6864	# <CJK>
+0x6868	0x6883	# <CJK>
+0x6869	0x681D	# <CJK>
+0x686A	0x6855	# <CJK>
+0x686B	0x6866	# <CJK>
+0x686C	0x6841	# <CJK>
+0x686D	0x6867	# <CJK>
+0x686E	0x6840	# <CJK>
+0x686F	0x683E	# <CJK>
+0x6870	0x684A	# <CJK>
+0x6871	0x6849	# <CJK>
+0x6872	0x6829	# <CJK>
+0x6873	0x68B5	# <CJK>
+0x6874	0x688F	# <CJK>
+0x6875	0x6874	# <CJK>
+0x6876	0x6877	# <CJK>
+0x6877	0x6893	# <CJK>
+0x6878	0x686B	# <CJK>
+0x6879	0x68C2	# <CJK>
+0x687A	0x696E	# <CJK>
+0x687B	0x68FC	# <CJK>
+0x687C	0x691F	# <CJK>
+0x687D	0x6920	# <CJK>
+0x687E	0x68F9	# <CJK>
+0x6921	0x6924	# <CJK>
+0x6922	0x68F0	# <CJK>
+0x6923	0x690B	# <CJK>
+0x6924	0x6901	# <CJK>
+0x6925	0x6957	# <CJK>
+0x6926	0x68E3	# <CJK>
+0x6927	0x6910	# <CJK>
+0x6928	0x6971	# <CJK>
+0x6929	0x6939	# <CJK>
+0x692A	0x6960	# <CJK>
+0x692B	0x6942	# <CJK>
+0x692C	0x695D	# <CJK>
+0x692D	0x6984	# <CJK>
+0x692E	0x696B	# <CJK>
+0x692F	0x6980	# <CJK>
+0x6930	0x6998	# <CJK>
+0x6931	0x6978	# <CJK>
+0x6932	0x6934	# <CJK>
+0x6933	0x69CC	# <CJK>
+0x6934	0x6987	# <CJK>
+0x6935	0x6988	# <CJK>
+0x6936	0x69CE	# <CJK>
+0x6937	0x6989	# <CJK>
+0x6938	0x6966	# <CJK>
+0x6939	0x6963	# <CJK>
+0x693A	0x6979	# <CJK>
+0x693B	0x699B	# <CJK>
+0x693C	0x69A7	# <CJK>
+0x693D	0x69BB	# <CJK>
+0x693E	0x69AB	# <CJK>
+0x693F	0x69AD	# <CJK>
+0x6940	0x69D4	# <CJK>
+0x6941	0x69B1	# <CJK>
+0x6942	0x69C1	# <CJK>
+0x6943	0x69CA	# <CJK>
+0x6944	0x69DF	# <CJK>
+0x6945	0x6995	# <CJK>
+0x6946	0x69E0	# <CJK>
+0x6947	0x698D	# <CJK>
+0x6948	0x69FF	# <CJK>
+0x6949	0x6A2F	# <CJK>
+0x694A	0x69ED	# <CJK>
+0x694B	0x6A17	# <CJK>
+0x694C	0x6A18	# <CJK>
+0x694D	0x6A65	# <CJK>
+0x694E	0x69F2	# <CJK>
+0x694F	0x6A44	# <CJK>
+0x6950	0x6A3E	# <CJK>
+0x6951	0x6AA0	# <CJK>
+0x6952	0x6A50	# <CJK>
+0x6953	0x6A5B	# <CJK>
+0x6954	0x6A35	# <CJK>
+0x6955	0x6A8E	# <CJK>
+0x6956	0x6A79	# <CJK>
+0x6957	0x6A3D	# <CJK>
+0x6958	0x6A28	# <CJK>
+0x6959	0x6A58	# <CJK>
+0x695A	0x6A7C	# <CJK>
+0x695B	0x6A91	# <CJK>
+0x695C	0x6A90	# <CJK>
+0x695D	0x6AA9	# <CJK>
+0x695E	0x6A97	# <CJK>
+0x695F	0x6AAB	# <CJK>
+0x6960	0x7337	# <CJK>
+0x6961	0x7352	# <CJK>
+0x6962	0x6B81	# <CJK>
+0x6963	0x6B82	# <CJK>
+0x6964	0x6B87	# <CJK>
+0x6965	0x6B84	# <CJK>
+0x6966	0x6B92	# <CJK>
+0x6967	0x6B93	# <CJK>
+0x6968	0x6B8D	# <CJK>
+0x6969	0x6B9A	# <CJK>
+0x696A	0x6B9B	# <CJK>
+0x696B	0x6BA1	# <CJK>
+0x696C	0x6BAA	# <CJK>
+0x696D	0x8F6B	# <CJK>
+0x696E	0x8F6D	# <CJK>
+0x696F	0x8F71	# <CJK>
+0x6970	0x8F72	# <CJK>
+0x6971	0x8F73	# <CJK>
+0x6972	0x8F75	# <CJK>
+0x6973	0x8F76	# <CJK>
+0x6974	0x8F78	# <CJK>
+0x6975	0x8F77	# <CJK>
+0x6976	0x8F79	# <CJK>
+0x6977	0x8F7A	# <CJK>
+0x6978	0x8F7C	# <CJK>
+0x6979	0x8F7E	# <CJK>
+0x697A	0x8F81	# <CJK>
+0x697B	0x8F82	# <CJK>
+0x697C	0x8F84	# <CJK>
+0x697D	0x8F87	# <CJK>
+0x697E	0x8F8B	# <CJK>
+0x6A21	0x8F8D	# <CJK>
+0x6A22	0x8F8E	# <CJK>
+0x6A23	0x8F8F	# <CJK>
+0x6A24	0x8F98	# <CJK>
+0x6A25	0x8F9A	# <CJK>
+0x6A26	0x8ECE	# <CJK>
+0x6A27	0x620B	# <CJK>
+0x6A28	0x6217	# <CJK>
+0x6A29	0x621B	# <CJK>
+0x6A2A	0x621F	# <CJK>
+0x6A2B	0x6222	# <CJK>
+0x6A2C	0x6221	# <CJK>
+0x6A2D	0x6225	# <CJK>
+0x6A2E	0x6224	# <CJK>
+0x6A2F	0x622C	# <CJK>
+0x6A30	0x81E7	# <CJK>
+0x6A31	0x74EF	# <CJK>
+0x6A32	0x74F4	# <CJK>
+0x6A33	0x74FF	# <CJK>
+0x6A34	0x750F	# <CJK>
+0x6A35	0x7511	# <CJK>
+0x6A36	0x7513	# <CJK>
+0x6A37	0x6534	# <CJK>
+0x6A38	0x65EE	# <CJK>
+0x6A39	0x65EF	# <CJK>
+0x6A3A	0x65F0	# <CJK>
+0x6A3B	0x660A	# <CJK>
+0x6A3C	0x6619	# <CJK>
+0x6A3D	0x6772	# <CJK>
+0x6A3E	0x6603	# <CJK>
+0x6A3F	0x6615	# <CJK>
+0x6A40	0x6600	# <CJK>
+0x6A41	0x7085	# <CJK>
+0x6A42	0x66F7	# <CJK>
+0x6A43	0x661D	# <CJK>
+0x6A44	0x6634	# <CJK>
+0x6A45	0x6631	# <CJK>
+0x6A46	0x6636	# <CJK>
+0x6A47	0x6635	# <CJK>
+0x6A48	0x8006	# <CJK>
+0x6A49	0x665F	# <CJK>
+0x6A4A	0x6654	# <CJK>
+0x6A4B	0x6641	# <CJK>
+0x6A4C	0x664F	# <CJK>
+0x6A4D	0x6656	# <CJK>
+0x6A4E	0x6661	# <CJK>
+0x6A4F	0x6657	# <CJK>
+0x6A50	0x6677	# <CJK>
+0x6A51	0x6684	# <CJK>
+0x6A52	0x668C	# <CJK>
+0x6A53	0x66A7	# <CJK>
+0x6A54	0x669D	# <CJK>
+0x6A55	0x66BE	# <CJK>
+0x6A56	0x66DB	# <CJK>
+0x6A57	0x66DC	# <CJK>
+0x6A58	0x66E6	# <CJK>
+0x6A59	0x66E9	# <CJK>
+0x6A5A	0x8D32	# <CJK>
+0x6A5B	0x8D33	# <CJK>
+0x6A5C	0x8D36	# <CJK>
+0x6A5D	0x8D3B	# <CJK>
+0x6A5E	0x8D3D	# <CJK>
+0x6A5F	0x8D40	# <CJK>
+0x6A60	0x8D45	# <CJK>
+0x6A61	0x8D46	# <CJK>
+0x6A62	0x8D48	# <CJK>
+0x6A63	0x8D49	# <CJK>
+0x6A64	0x8D47	# <CJK>
+0x6A65	0x8D4D	# <CJK>
+0x6A66	0x8D55	# <CJK>
+0x6A67	0x8D59	# <CJK>
+0x6A68	0x89C7	# <CJK>
+0x6A69	0x89CA	# <CJK>
+0x6A6A	0x89CB	# <CJK>
+0x6A6B	0x89CC	# <CJK>
+0x6A6C	0x89CE	# <CJK>
+0x6A6D	0x89CF	# <CJK>
+0x6A6E	0x89D0	# <CJK>
+0x6A6F	0x89D1	# <CJK>
+0x6A70	0x726E	# <CJK>
+0x6A71	0x729F	# <CJK>
+0x6A72	0x725D	# <CJK>
+0x6A73	0x7266	# <CJK>
+0x6A74	0x726F	# <CJK>
+0x6A75	0x727E	# <CJK>
+0x6A76	0x727F	# <CJK>
+0x6A77	0x7284	# <CJK>
+0x6A78	0x728B	# <CJK>
+0x6A79	0x728D	# <CJK>
+0x6A7A	0x728F	# <CJK>
+0x6A7B	0x7292	# <CJK>
+0x6A7C	0x6308	# <CJK>
+0x6A7D	0x6332	# <CJK>
+0x6A7E	0x63B0	# <CJK>
+0x6B21	0x643F	# <CJK>
+0x6B22	0x64D8	# <CJK>
+0x6B23	0x8004	# <CJK>
+0x6B24	0x6BEA	# <CJK>
+0x6B25	0x6BF3	# <CJK>
+0x6B26	0x6BFD	# <CJK>
+0x6B27	0x6BF5	# <CJK>
+0x6B28	0x6BF9	# <CJK>
+0x6B29	0x6C05	# <CJK>
+0x6B2A	0x6C07	# <CJK>
+0x6B2B	0x6C06	# <CJK>
+0x6B2C	0x6C0D	# <CJK>
+0x6B2D	0x6C15	# <CJK>
+0x6B2E	0x6C18	# <CJK>
+0x6B2F	0x6C19	# <CJK>
+0x6B30	0x6C1A	# <CJK>
+0x6B31	0x6C21	# <CJK>
+0x6B32	0x6C29	# <CJK>
+0x6B33	0x6C24	# <CJK>
+0x6B34	0x6C2A	# <CJK>
+0x6B35	0x6C32	# <CJK>
+0x6B36	0x6535	# <CJK>
+0x6B37	0x6555	# <CJK>
+0x6B38	0x656B	# <CJK>
+0x6B39	0x724D	# <CJK>
+0x6B3A	0x7252	# <CJK>
+0x6B3B	0x7256	# <CJK>
+0x6B3C	0x7230	# <CJK>
+0x6B3D	0x8662	# <CJK>
+0x6B3E	0x5216	# <CJK>
+0x6B3F	0x809F	# <CJK>
+0x6B40	0x809C	# <CJK>
+0x6B41	0x8093	# <CJK>
+0x6B42	0x80BC	# <CJK>
+0x6B43	0x670A	# <CJK>
+0x6B44	0x80BD	# <CJK>
+0x6B45	0x80B1	# <CJK>
+0x6B46	0x80AB	# <CJK>
+0x6B47	0x80AD	# <CJK>
+0x6B48	0x80B4	# <CJK>
+0x6B49	0x80B7	# <CJK>
+0x6B4A	0x80E7	# <CJK>
+0x6B4B	0x80E8	# <CJK>
+0x6B4C	0x80E9	# <CJK>
+0x6B4D	0x80EA	# <CJK>
+0x6B4E	0x80DB	# <CJK>
+0x6B4F	0x80C2	# <CJK>
+0x6B50	0x80C4	# <CJK>
+0x6B51	0x80D9	# <CJK>
+0x6B52	0x80CD	# <CJK>
+0x6B53	0x80D7	# <CJK>
+0x6B54	0x6710	# <CJK>
+0x6B55	0x80DD	# <CJK>
+0x6B56	0x80EB	# <CJK>
+0x6B57	0x80F1	# <CJK>
+0x6B58	0x80F4	# <CJK>
+0x6B59	0x80ED	# <CJK>
+0x6B5A	0x810D	# <CJK>
+0x6B5B	0x810E	# <CJK>
+0x6B5C	0x80F2	# <CJK>
+0x6B5D	0x80FC	# <CJK>
+0x6B5E	0x6715	# <CJK>
+0x6B5F	0x8112	# <CJK>
+0x6B60	0x8C5A	# <CJK>
+0x6B61	0x8136	# <CJK>
+0x6B62	0x811E	# <CJK>
+0x6B63	0x812C	# <CJK>
+0x6B64	0x8118	# <CJK>
+0x6B65	0x8132	# <CJK>
+0x6B66	0x8148	# <CJK>
+0x6B67	0x814C	# <CJK>
+0x6B68	0x8153	# <CJK>
+0x6B69	0x8174	# <CJK>
+0x6B6A	0x8159	# <CJK>
+0x6B6B	0x815A	# <CJK>
+0x6B6C	0x8171	# <CJK>
+0x6B6D	0x8160	# <CJK>
+0x6B6E	0x8169	# <CJK>
+0x6B6F	0x817C	# <CJK>
+0x6B70	0x817D	# <CJK>
+0x6B71	0x816D	# <CJK>
+0x6B72	0x8167	# <CJK>
+0x6B73	0x584D	# <CJK>
+0x6B74	0x5AB5	# <CJK>
+0x6B75	0x8188	# <CJK>
+0x6B76	0x8182	# <CJK>
+0x6B77	0x8191	# <CJK>
+0x6B78	0x6ED5	# <CJK>
+0x6B79	0x81A3	# <CJK>
+0x6B7A	0x81AA	# <CJK>
+0x6B7B	0x81CC	# <CJK>
+0x6B7C	0x6726	# <CJK>
+0x6B7D	0x81CA	# <CJK>
+0x6B7E	0x81BB	# <CJK>
+0x6C21	0x81C1	# <CJK>
+0x6C22	0x81A6	# <CJK>
+0x6C23	0x6B24	# <CJK>
+0x6C24	0x6B37	# <CJK>
+0x6C25	0x6B39	# <CJK>
+0x6C26	0x6B43	# <CJK>
+0x6C27	0x6B46	# <CJK>
+0x6C28	0x6B59	# <CJK>
+0x6C29	0x98D1	# <CJK>
+0x6C2A	0x98D2	# <CJK>
+0x6C2B	0x98D3	# <CJK>
+0x6C2C	0x98D5	# <CJK>
+0x6C2D	0x98D9	# <CJK>
+0x6C2E	0x98DA	# <CJK>
+0x6C2F	0x6BB3	# <CJK>
+0x6C30	0x5F40	# <CJK>
+0x6C31	0x6BC2	# <CJK>
+0x6C32	0x89F3	# <CJK>
+0x6C33	0x6590	# <CJK>
+0x6C34	0x9F51	# <CJK>
+0x6C35	0x6593	# <CJK>
+0x6C36	0x65BC	# <CJK>
+0x6C37	0x65C6	# <CJK>
+0x6C38	0x65C4	# <CJK>
+0x6C39	0x65C3	# <CJK>
+0x6C3A	0x65CC	# <CJK>
+0x6C3B	0x65CE	# <CJK>
+0x6C3C	0x65D2	# <CJK>
+0x6C3D	0x65D6	# <CJK>
+0x6C3E	0x7080	# <CJK>
+0x6C3F	0x709C	# <CJK>
+0x6C40	0x7096	# <CJK>
+0x6C41	0x709D	# <CJK>
+0x6C42	0x70BB	# <CJK>
+0x6C43	0x70C0	# <CJK>
+0x6C44	0x70B7	# <CJK>
+0x6C45	0x70AB	# <CJK>
+0x6C46	0x70B1	# <CJK>
+0x6C47	0x70E8	# <CJK>
+0x6C48	0x70CA	# <CJK>
+0x6C49	0x7110	# <CJK>
+0x6C4A	0x7113	# <CJK>
+0x6C4B	0x7116	# <CJK>
+0x6C4C	0x712F	# <CJK>
+0x6C4D	0x7131	# <CJK>
+0x6C4E	0x7173	# <CJK>
+0x6C4F	0x715C	# <CJK>
+0x6C50	0x7168	# <CJK>
+0x6C51	0x7145	# <CJK>
+0x6C52	0x7172	# <CJK>
+0x6C53	0x714A	# <CJK>
+0x6C54	0x7178	# <CJK>
+0x6C55	0x717A	# <CJK>
+0x6C56	0x7198	# <CJK>
+0x6C57	0x71B3	# <CJK>
+0x6C58	0x71B5	# <CJK>
+0x6C59	0x71A8	# <CJK>
+0x6C5A	0x71A0	# <CJK>
+0x6C5B	0x71E0	# <CJK>
+0x6C5C	0x71D4	# <CJK>
+0x6C5D	0x71E7	# <CJK>
+0x6C5E	0x71F9	# <CJK>
+0x6C5F	0x721D	# <CJK>
+0x6C60	0x7228	# <CJK>
+0x6C61	0x706C	# <CJK>
+0x6C62	0x7118	# <CJK>
+0x6C63	0x7166	# <CJK>
+0x6C64	0x71B9	# <CJK>
+0x6C65	0x623E	# <CJK>
+0x6C66	0x623D	# <CJK>
+0x6C67	0x6243	# <CJK>
+0x6C68	0x6248	# <CJK>
+0x6C69	0x6249	# <CJK>
+0x6C6A	0x793B	# <CJK>
+0x6C6B	0x7940	# <CJK>
+0x6C6C	0x7946	# <CJK>
+0x6C6D	0x7949	# <CJK>
+0x6C6E	0x795B	# <CJK>
+0x6C6F	0x795C	# <CJK>
+0x6C70	0x7953	# <CJK>
+0x6C71	0x795A	# <CJK>
+0x6C72	0x7962	# <CJK>
+0x6C73	0x7957	# <CJK>
+0x6C74	0x7960	# <CJK>
+0x6C75	0x796F	# <CJK>
+0x6C76	0x7967	# <CJK>
+0x6C77	0x797A	# <CJK>
+0x6C78	0x7985	# <CJK>
+0x6C79	0x798A	# <CJK>
+0x6C7A	0x799A	# <CJK>
+0x6C7B	0x79A7	# <CJK>
+0x6C7C	0x79B3	# <CJK>
+0x6C7D	0x5FD1	# <CJK>
+0x6C7E	0x5FD0	# <CJK>
+0x6D21	0x603C	# <CJK>
+0x6D22	0x605D	# <CJK>
+0x6D23	0x605A	# <CJK>
+0x6D24	0x6067	# <CJK>
+0x6D25	0x6041	# <CJK>
+0x6D26	0x6059	# <CJK>
+0x6D27	0x6063	# <CJK>
+0x6D28	0x60AB	# <CJK>
+0x6D29	0x6106	# <CJK>
+0x6D2A	0x610D	# <CJK>
+0x6D2B	0x615D	# <CJK>
+0x6D2C	0x61A9	# <CJK>
+0x6D2D	0x619D	# <CJK>
+0x6D2E	0x61CB	# <CJK>
+0x6D2F	0x61D1	# <CJK>
+0x6D30	0x6206	# <CJK>
+0x6D31	0x8080	# <CJK>
+0x6D32	0x807F	# <CJK>
+0x6D33	0x6C93	# <CJK>
+0x6D34	0x6CF6	# <CJK>
+0x6D35	0x6DFC	# <CJK>
+0x6D36	0x77F6	# <CJK>
+0x6D37	0x77F8	# <CJK>
+0x6D38	0x7800	# <CJK>
+0x6D39	0x7809	# <CJK>
+0x6D3A	0x7817	# <CJK>
+0x6D3B	0x7818	# <CJK>
+0x6D3C	0x7811	# <CJK>
+0x6D3D	0x65AB	# <CJK>
+0x6D3E	0x782D	# <CJK>
+0x6D3F	0x781C	# <CJK>
+0x6D40	0x781D	# <CJK>
+0x6D41	0x7839	# <CJK>
+0x6D42	0x783A	# <CJK>
+0x6D43	0x783B	# <CJK>
+0x6D44	0x781F	# <CJK>
+0x6D45	0x783C	# <CJK>
+0x6D46	0x7825	# <CJK>
+0x6D47	0x782C	# <CJK>
+0x6D48	0x7823	# <CJK>
+0x6D49	0x7829	# <CJK>
+0x6D4A	0x784E	# <CJK>
+0x6D4B	0x786D	# <CJK>
+0x6D4C	0x7856	# <CJK>
+0x6D4D	0x7857	# <CJK>
+0x6D4E	0x7826	# <CJK>
+0x6D4F	0x7850	# <CJK>
+0x6D50	0x7847	# <CJK>
+0x6D51	0x784C	# <CJK>
+0x6D52	0x786A	# <CJK>
+0x6D53	0x789B	# <CJK>
+0x6D54	0x7893	# <CJK>
+0x6D55	0x789A	# <CJK>
+0x6D56	0x7887	# <CJK>
+0x6D57	0x789C	# <CJK>
+0x6D58	0x78A1	# <CJK>
+0x6D59	0x78A3	# <CJK>
+0x6D5A	0x78B2	# <CJK>
+0x6D5B	0x78B9	# <CJK>
+0x6D5C	0x78A5	# <CJK>
+0x6D5D	0x78D4	# <CJK>
+0x6D5E	0x78D9	# <CJK>
+0x6D5F	0x78C9	# <CJK>
+0x6D60	0x78EC	# <CJK>
+0x6D61	0x78F2	# <CJK>
+0x6D62	0x7905	# <CJK>
+0x6D63	0x78F4	# <CJK>
+0x6D64	0x7913	# <CJK>
+0x6D65	0x7924	# <CJK>
+0x6D66	0x791E	# <CJK>
+0x6D67	0x7934	# <CJK>
+0x6D68	0x9F9B	# <CJK>
+0x6D69	0x9EF9	# <CJK>
+0x6D6A	0x9EFB	# <CJK>
+0x6D6B	0x9EFC	# <CJK>
+0x6D6C	0x76F1	# <CJK>
+0x6D6D	0x7704	# <CJK>
+0x6D6E	0x770D	# <CJK>
+0x6D6F	0x76F9	# <CJK>
+0x6D70	0x7707	# <CJK>
+0x6D71	0x7708	# <CJK>
+0x6D72	0x771A	# <CJK>
+0x6D73	0x7722	# <CJK>
+0x6D74	0x7719	# <CJK>
+0x6D75	0x772D	# <CJK>
+0x6D76	0x7726	# <CJK>
+0x6D77	0x7735	# <CJK>
+0x6D78	0x7738	# <CJK>
+0x6D79	0x7750	# <CJK>
+0x6D7A	0x7751	# <CJK>
+0x6D7B	0x7747	# <CJK>
+0x6D7C	0x7743	# <CJK>
+0x6D7D	0x775A	# <CJK>
+0x6D7E	0x7768	# <CJK>
+0x6E21	0x7762	# <CJK>
+0x6E22	0x7765	# <CJK>
+0x6E23	0x777F	# <CJK>
+0x6E24	0x778D	# <CJK>
+0x6E25	0x777D	# <CJK>
+0x6E26	0x7780	# <CJK>
+0x6E27	0x778C	# <CJK>
+0x6E28	0x7791	# <CJK>
+0x6E29	0x779F	# <CJK>
+0x6E2A	0x77A0	# <CJK>
+0x6E2B	0x77B0	# <CJK>
+0x6E2C	0x77B5	# <CJK>
+0x6E2D	0x77BD	# <CJK>
+0x6E2E	0x753A	# <CJK>
+0x6E2F	0x7540	# <CJK>
+0x6E30	0x754E	# <CJK>
+0x6E31	0x754B	# <CJK>
+0x6E32	0x7548	# <CJK>
+0x6E33	0x755B	# <CJK>
+0x6E34	0x7572	# <CJK>
+0x6E35	0x7579	# <CJK>
+0x6E36	0x7583	# <CJK>
+0x6E37	0x7F58	# <CJK>
+0x6E38	0x7F61	# <CJK>
+0x6E39	0x7F5F	# <CJK>
+0x6E3A	0x8A48	# <CJK>
+0x6E3B	0x7F68	# <CJK>
+0x6E3C	0x7F74	# <CJK>
+0x6E3D	0x7F71	# <CJK>
+0x6E3E	0x7F79	# <CJK>
+0x6E3F	0x7F81	# <CJK>
+0x6E40	0x7F7E	# <CJK>
+0x6E41	0x76CD	# <CJK>
+0x6E42	0x76E5	# <CJK>
+0x6E43	0x8832	# <CJK>
+0x6E44	0x9485	# <CJK>
+0x6E45	0x9486	# <CJK>
+0x6E46	0x9487	# <CJK>
+0x6E47	0x948B	# <CJK>
+0x6E48	0x948A	# <CJK>
+0x6E49	0x948C	# <CJK>
+0x6E4A	0x948D	# <CJK>
+0x6E4B	0x948F	# <CJK>
+0x6E4C	0x9490	# <CJK>
+0x6E4D	0x9494	# <CJK>
+0x6E4E	0x9497	# <CJK>
+0x6E4F	0x9495	# <CJK>
+0x6E50	0x949A	# <CJK>
+0x6E51	0x949B	# <CJK>
+0x6E52	0x949C	# <CJK>
+0x6E53	0x94A3	# <CJK>
+0x6E54	0x94A4	# <CJK>
+0x6E55	0x94AB	# <CJK>
+0x6E56	0x94AA	# <CJK>
+0x6E57	0x94AD	# <CJK>
+0x6E58	0x94AC	# <CJK>
+0x6E59	0x94AF	# <CJK>
+0x6E5A	0x94B0	# <CJK>
+0x6E5B	0x94B2	# <CJK>
+0x6E5C	0x94B4	# <CJK>
+0x6E5D	0x94B6	# <CJK>
+0x6E5E	0x94B7	# <CJK>
+0x6E5F	0x94B8	# <CJK>
+0x6E60	0x94B9	# <CJK>
+0x6E61	0x94BA	# <CJK>
+0x6E62	0x94BC	# <CJK>
+0x6E63	0x94BD	# <CJK>
+0x6E64	0x94BF	# <CJK>
+0x6E65	0x94C4	# <CJK>
+0x6E66	0x94C8	# <CJK>
+0x6E67	0x94C9	# <CJK>
+0x6E68	0x94CA	# <CJK>
+0x6E69	0x94CB	# <CJK>
+0x6E6A	0x94CC	# <CJK>
+0x6E6B	0x94CD	# <CJK>
+0x6E6C	0x94CE	# <CJK>
+0x6E6D	0x94D0	# <CJK>
+0x6E6E	0x94D1	# <CJK>
+0x6E6F	0x94D2	# <CJK>
+0x6E70	0x94D5	# <CJK>
+0x6E71	0x94D6	# <CJK>
+0x6E72	0x94D7	# <CJK>
+0x6E73	0x94D9	# <CJK>
+0x6E74	0x94D8	# <CJK>
+0x6E75	0x94DB	# <CJK>
+0x6E76	0x94DE	# <CJK>
+0x6E77	0x94DF	# <CJK>
+0x6E78	0x94E0	# <CJK>
+0x6E79	0x94E2	# <CJK>
+0x6E7A	0x94E4	# <CJK>
+0x6E7B	0x94E5	# <CJK>
+0x6E7C	0x94E7	# <CJK>
+0x6E7D	0x94E8	# <CJK>
+0x6E7E	0x94EA	# <CJK>
+0x6F21	0x94E9	# <CJK>
+0x6F22	0x94EB	# <CJK>
+0x6F23	0x94EE	# <CJK>
+0x6F24	0x94EF	# <CJK>
+0x6F25	0x94F3	# <CJK>
+0x6F26	0x94F4	# <CJK>
+0x6F27	0x94F5	# <CJK>
+0x6F28	0x94F7	# <CJK>
+0x6F29	0x94F9	# <CJK>
+0x6F2A	0x94FC	# <CJK>
+0x6F2B	0x94FD	# <CJK>
+0x6F2C	0x94FF	# <CJK>
+0x6F2D	0x9503	# <CJK>
+0x6F2E	0x9502	# <CJK>
+0x6F2F	0x9506	# <CJK>
+0x6F30	0x9507	# <CJK>
+0x6F31	0x9509	# <CJK>
+0x6F32	0x950A	# <CJK>
+0x6F33	0x950D	# <CJK>
+0x6F34	0x950E	# <CJK>
+0x6F35	0x950F	# <CJK>
+0x6F36	0x9512	# <CJK>
+0x6F37	0x9513	# <CJK>
+0x6F38	0x9514	# <CJK>
+0x6F39	0x9515	# <CJK>
+0x6F3A	0x9516	# <CJK>
+0x6F3B	0x9518	# <CJK>
+0x6F3C	0x951B	# <CJK>
+0x6F3D	0x951D	# <CJK>
+0x6F3E	0x951E	# <CJK>
+0x6F3F	0x951F	# <CJK>
+0x6F40	0x9522	# <CJK>
+0x6F41	0x952A	# <CJK>
+0x6F42	0x952B	# <CJK>
+0x6F43	0x9529	# <CJK>
+0x6F44	0x952C	# <CJK>
+0x6F45	0x9531	# <CJK>
+0x6F46	0x9532	# <CJK>
+0x6F47	0x9534	# <CJK>
+0x6F48	0x9536	# <CJK>
+0x6F49	0x9537	# <CJK>
+0x6F4A	0x9538	# <CJK>
+0x6F4B	0x953C	# <CJK>
+0x6F4C	0x953E	# <CJK>
+0x6F4D	0x953F	# <CJK>
+0x6F4E	0x9542	# <CJK>
+0x6F4F	0x9535	# <CJK>
+0x6F50	0x9544	# <CJK>
+0x6F51	0x9545	# <CJK>
+0x6F52	0x9546	# <CJK>
+0x6F53	0x9549	# <CJK>
+0x6F54	0x954C	# <CJK>
+0x6F55	0x954E	# <CJK>
+0x6F56	0x954F	# <CJK>
+0x6F57	0x9552	# <CJK>
+0x6F58	0x9553	# <CJK>
+0x6F59	0x9554	# <CJK>
+0x6F5A	0x9556	# <CJK>
+0x6F5B	0x9557	# <CJK>
+0x6F5C	0x9558	# <CJK>
+0x6F5D	0x9559	# <CJK>
+0x6F5E	0x955B	# <CJK>
+0x6F5F	0x955E	# <CJK>
+0x6F60	0x955F	# <CJK>
+0x6F61	0x955D	# <CJK>
+0x6F62	0x9561	# <CJK>
+0x6F63	0x9562	# <CJK>
+0x6F64	0x9564	# <CJK>
+0x6F65	0x9565	# <CJK>
+0x6F66	0x9566	# <CJK>
+0x6F67	0x9567	# <CJK>
+0x6F68	0x9568	# <CJK>
+0x6F69	0x9569	# <CJK>
+0x6F6A	0x956A	# <CJK>
+0x6F6B	0x956B	# <CJK>
+0x6F6C	0x956C	# <CJK>
+0x6F6D	0x956F	# <CJK>
+0x6F6E	0x9571	# <CJK>
+0x6F6F	0x9572	# <CJK>
+0x6F70	0x9573	# <CJK>
+0x6F71	0x953A	# <CJK>
+0x6F72	0x77E7	# <CJK>
+0x6F73	0x77EC	# <CJK>
+0x6F74	0x96C9	# <CJK>
+0x6F75	0x79D5	# <CJK>
+0x6F76	0x79ED	# <CJK>
+0x6F77	0x79E3	# <CJK>
+0x6F78	0x79EB	# <CJK>
+0x6F79	0x7A06	# <CJK>
+0x6F7A	0x5D47	# <CJK>
+0x6F7B	0x7A03	# <CJK>
+0x6F7C	0x7A02	# <CJK>
+0x6F7D	0x7A1E	# <CJK>
+0x6F7E	0x7A14	# <CJK>
+0x7021	0x7A39	# <CJK>
+0x7022	0x7A37	# <CJK>
+0x7023	0x7A51	# <CJK>
+0x7024	0x9ECF	# <CJK>
+0x7025	0x99A5	# <CJK>
+0x7026	0x7A70	# <CJK>
+0x7027	0x7688	# <CJK>
+0x7028	0x768E	# <CJK>
+0x7029	0x7693	# <CJK>
+0x702A	0x7699	# <CJK>
+0x702B	0x76A4	# <CJK>
+0x702C	0x74DE	# <CJK>
+0x702D	0x74E0	# <CJK>
+0x702E	0x752C	# <CJK>
+0x702F	0x9E20	# <CJK>
+0x7030	0x9E22	# <CJK>
+0x7031	0x9E28	# <CJK>
+0x7032	0x9E29	# <CJK>
+0x7033	0x9E2A	# <CJK>
+0x7034	0x9E2B	# <CJK>
+0x7035	0x9E2C	# <CJK>
+0x7036	0x9E32	# <CJK>
+0x7037	0x9E31	# <CJK>
+0x7038	0x9E36	# <CJK>
+0x7039	0x9E38	# <CJK>
+0x703A	0x9E37	# <CJK>
+0x703B	0x9E39	# <CJK>
+0x703C	0x9E3A	# <CJK>
+0x703D	0x9E3E	# <CJK>
+0x703E	0x9E41	# <CJK>
+0x703F	0x9E42	# <CJK>
+0x7040	0x9E44	# <CJK>
+0x7041	0x9E46	# <CJK>
+0x7042	0x9E47	# <CJK>
+0x7043	0x9E48	# <CJK>
+0x7044	0x9E49	# <CJK>
+0x7045	0x9E4B	# <CJK>
+0x7046	0x9E4C	# <CJK>
+0x7047	0x9E4E	# <CJK>
+0x7048	0x9E51	# <CJK>
+0x7049	0x9E55	# <CJK>
+0x704A	0x9E57	# <CJK>
+0x704B	0x9E5A	# <CJK>
+0x704C	0x9E5B	# <CJK>
+0x704D	0x9E5C	# <CJK>
+0x704E	0x9E5E	# <CJK>
+0x704F	0x9E63	# <CJK>
+0x7050	0x9E66	# <CJK>
+0x7051	0x9E67	# <CJK>
+0x7052	0x9E68	# <CJK>
+0x7053	0x9E69	# <CJK>
+0x7054	0x9E6A	# <CJK>
+0x7055	0x9E6B	# <CJK>
+0x7056	0x9E6C	# <CJK>
+0x7057	0x9E71	# <CJK>
+0x7058	0x9E6D	# <CJK>
+0x7059	0x9E73	# <CJK>
+0x705A	0x7592	# <CJK>
+0x705B	0x7594	# <CJK>
+0x705C	0x7596	# <CJK>
+0x705D	0x75A0	# <CJK>
+0x705E	0x759D	# <CJK>
+0x705F	0x75AC	# <CJK>
+0x7060	0x75A3	# <CJK>
+0x7061	0x75B3	# <CJK>
+0x7062	0x75B4	# <CJK>
+0x7063	0x75B8	# <CJK>
+0x7064	0x75C4	# <CJK>
+0x7065	0x75B1	# <CJK>
+0x7066	0x75B0	# <CJK>
+0x7067	0x75C3	# <CJK>
+0x7068	0x75C2	# <CJK>
+0x7069	0x75D6	# <CJK>
+0x706A	0x75CD	# <CJK>
+0x706B	0x75E3	# <CJK>
+0x706C	0x75E8	# <CJK>
+0x706D	0x75E6	# <CJK>
+0x706E	0x75E4	# <CJK>
+0x706F	0x75EB	# <CJK>
+0x7070	0x75E7	# <CJK>
+0x7071	0x7603	# <CJK>
+0x7072	0x75F1	# <CJK>
+0x7073	0x75FC	# <CJK>
+0x7074	0x75FF	# <CJK>
+0x7075	0x7610	# <CJK>
+0x7076	0x7600	# <CJK>
+0x7077	0x7605	# <CJK>
+0x7078	0x760C	# <CJK>
+0x7079	0x7617	# <CJK>
+0x707A	0x760A	# <CJK>
+0x707B	0x7625	# <CJK>
+0x707C	0x7618	# <CJK>
+0x707D	0x7615	# <CJK>
+0x707E	0x7619	# <CJK>
+0x7121	0x761B	# <CJK>
+0x7122	0x763C	# <CJK>
+0x7123	0x7622	# <CJK>
+0x7124	0x7620	# <CJK>
+0x7125	0x7640	# <CJK>
+0x7126	0x762D	# <CJK>
+0x7127	0x7630	# <CJK>
+0x7128	0x763F	# <CJK>
+0x7129	0x7635	# <CJK>
+0x712A	0x7643	# <CJK>
+0x712B	0x763E	# <CJK>
+0x712C	0x7633	# <CJK>
+0x712D	0x764D	# <CJK>
+0x712E	0x765E	# <CJK>
+0x712F	0x7654	# <CJK>
+0x7130	0x765C	# <CJK>
+0x7131	0x7656	# <CJK>
+0x7132	0x766B	# <CJK>
+0x7133	0x766F	# <CJK>
+0x7134	0x7FCA	# <CJK>
+0x7135	0x7AE6	# <CJK>
+0x7136	0x7A78	# <CJK>
+0x7137	0x7A79	# <CJK>
+0x7138	0x7A80	# <CJK>
+0x7139	0x7A86	# <CJK>
+0x713A	0x7A88	# <CJK>
+0x713B	0x7A95	# <CJK>
+0x713C	0x7AA6	# <CJK>
+0x713D	0x7AA0	# <CJK>
+0x713E	0x7AAC	# <CJK>
+0x713F	0x7AA8	# <CJK>
+0x7140	0x7AAD	# <CJK>
+0x7141	0x7AB3	# <CJK>
+0x7142	0x8864	# <CJK>
+0x7143	0x8869	# <CJK>
+0x7144	0x8872	# <CJK>
+0x7145	0x887D	# <CJK>
+0x7146	0x887F	# <CJK>
+0x7147	0x8882	# <CJK>
+0x7148	0x88A2	# <CJK>
+0x7149	0x88C6	# <CJK>
+0x714A	0x88B7	# <CJK>
+0x714B	0x88BC	# <CJK>
+0x714C	0x88C9	# <CJK>
+0x714D	0x88E2	# <CJK>
+0x714E	0x88CE	# <CJK>
+0x714F	0x88E3	# <CJK>
+0x7150	0x88E5	# <CJK>
+0x7151	0x88F1	# <CJK>
+0x7152	0x891A	# <CJK>
+0x7153	0x88FC	# <CJK>
+0x7154	0x88E8	# <CJK>
+0x7155	0x88FE	# <CJK>
+0x7156	0x88F0	# <CJK>
+0x7157	0x8921	# <CJK>
+0x7158	0x8919	# <CJK>
+0x7159	0x8913	# <CJK>
+0x715A	0x891B	# <CJK>
+0x715B	0x890A	# <CJK>
+0x715C	0x8934	# <CJK>
+0x715D	0x892B	# <CJK>
+0x715E	0x8936	# <CJK>
+0x715F	0x8941	# <CJK>
+0x7160	0x8966	# <CJK>
+0x7161	0x897B	# <CJK>
+0x7162	0x758B	# <CJK>
+0x7163	0x80E5	# <CJK>
+0x7164	0x76B2	# <CJK>
+0x7165	0x76B4	# <CJK>
+0x7166	0x77DC	# <CJK>
+0x7167	0x8012	# <CJK>
+0x7168	0x8014	# <CJK>
+0x7169	0x8016	# <CJK>
+0x716A	0x801C	# <CJK>
+0x716B	0x8020	# <CJK>
+0x716C	0x8022	# <CJK>
+0x716D	0x8025	# <CJK>
+0x716E	0x8026	# <CJK>
+0x716F	0x8027	# <CJK>
+0x7170	0x8029	# <CJK>
+0x7171	0x8028	# <CJK>
+0x7172	0x8031	# <CJK>
+0x7173	0x800B	# <CJK>
+0x7174	0x8035	# <CJK>
+0x7175	0x8043	# <CJK>
+0x7176	0x8046	# <CJK>
+0x7177	0x804D	# <CJK>
+0x7178	0x8052	# <CJK>
+0x7179	0x8069	# <CJK>
+0x717A	0x8071	# <CJK>
+0x717B	0x8983	# <CJK>
+0x717C	0x9878	# <CJK>
+0x717D	0x9880	# <CJK>
+0x717E	0x9883	# <CJK>
+0x7221	0x9889	# <CJK>
+0x7222	0x988C	# <CJK>
+0x7223	0x988D	# <CJK>
+0x7224	0x988F	# <CJK>
+0x7225	0x9894	# <CJK>
+0x7226	0x989A	# <CJK>
+0x7227	0x989B	# <CJK>
+0x7228	0x989E	# <CJK>
+0x7229	0x989F	# <CJK>
+0x722A	0x98A1	# <CJK>
+0x722B	0x98A2	# <CJK>
+0x722C	0x98A5	# <CJK>
+0x722D	0x98A6	# <CJK>
+0x722E	0x864D	# <CJK>
+0x722F	0x8654	# <CJK>
+0x7230	0x866C	# <CJK>
+0x7231	0x866E	# <CJK>
+0x7232	0x867F	# <CJK>
+0x7233	0x867A	# <CJK>
+0x7234	0x867C	# <CJK>
+0x7235	0x867B	# <CJK>
+0x7236	0x86A8	# <CJK>
+0x7237	0x868D	# <CJK>
+0x7238	0x868B	# <CJK>
+0x7239	0x86AC	# <CJK>
+0x723A	0x869D	# <CJK>
+0x723B	0x86A7	# <CJK>
+0x723C	0x86A3	# <CJK>
+0x723D	0x86AA	# <CJK>
+0x723E	0x8693	# <CJK>
+0x723F	0x86A9	# <CJK>
+0x7240	0x86B6	# <CJK>
+0x7241	0x86C4	# <CJK>
+0x7242	0x86B5	# <CJK>
+0x7243	0x86CE	# <CJK>
+0x7244	0x86B0	# <CJK>
+0x7245	0x86BA	# <CJK>
+0x7246	0x86B1	# <CJK>
+0x7247	0x86AF	# <CJK>
+0x7248	0x86C9	# <CJK>
+0x7249	0x86CF	# <CJK>
+0x724A	0x86B4	# <CJK>
+0x724B	0x86E9	# <CJK>
+0x724C	0x86F1	# <CJK>
+0x724D	0x86F2	# <CJK>
+0x724E	0x86ED	# <CJK>
+0x724F	0x86F3	# <CJK>
+0x7250	0x86D0	# <CJK>
+0x7251	0x8713	# <CJK>
+0x7252	0x86DE	# <CJK>
+0x7253	0x86F4	# <CJK>
+0x7254	0x86DF	# <CJK>
+0x7255	0x86D8	# <CJK>
+0x7256	0x86D1	# <CJK>
+0x7257	0x8703	# <CJK>
+0x7258	0x8707	# <CJK>
+0x7259	0x86F8	# <CJK>
+0x725A	0x8708	# <CJK>
+0x725B	0x870A	# <CJK>
+0x725C	0x870D	# <CJK>
+0x725D	0x8709	# <CJK>
+0x725E	0x8723	# <CJK>
+0x725F	0x873B	# <CJK>
+0x7260	0x871E	# <CJK>
+0x7261	0x8725	# <CJK>
+0x7262	0x872E	# <CJK>
+0x7263	0x871A	# <CJK>
+0x7264	0x873E	# <CJK>
+0x7265	0x8748	# <CJK>
+0x7266	0x8734	# <CJK>
+0x7267	0x8731	# <CJK>
+0x7268	0x8729	# <CJK>
+0x7269	0x8737	# <CJK>
+0x726A	0x873F	# <CJK>
+0x726B	0x8782	# <CJK>
+0x726C	0x8722	# <CJK>
+0x726D	0x877D	# <CJK>
+0x726E	0x877E	# <CJK>
+0x726F	0x877B	# <CJK>
+0x7270	0x8760	# <CJK>
+0x7271	0x8770	# <CJK>
+0x7272	0x874C	# <CJK>
+0x7273	0x876E	# <CJK>
+0x7274	0x878B	# <CJK>
+0x7275	0x8753	# <CJK>
+0x7276	0x8763	# <CJK>
+0x7277	0x877C	# <CJK>
+0x7278	0x8764	# <CJK>
+0x7279	0x8759	# <CJK>
+0x727A	0x8765	# <CJK>
+0x727B	0x8793	# <CJK>
+0x727C	0x87AF	# <CJK>
+0x727D	0x87A8	# <CJK>
+0x727E	0x87D2	# <CJK>
+0x7321	0x87C6	# <CJK>
+0x7322	0x8788	# <CJK>
+0x7323	0x8785	# <CJK>
+0x7324	0x87AD	# <CJK>
+0x7325	0x8797	# <CJK>
+0x7326	0x8783	# <CJK>
+0x7327	0x87AB	# <CJK>
+0x7328	0x87E5	# <CJK>
+0x7329	0x87AC	# <CJK>
+0x732A	0x87B5	# <CJK>
+0x732B	0x87B3	# <CJK>
+0x732C	0x87CB	# <CJK>
+0x732D	0x87D3	# <CJK>
+0x732E	0x87BD	# <CJK>
+0x732F	0x87D1	# <CJK>
+0x7330	0x87C0	# <CJK>
+0x7331	0x87CA	# <CJK>
+0x7332	0x87DB	# <CJK>
+0x7333	0x87EA	# <CJK>
+0x7334	0x87E0	# <CJK>
+0x7335	0x87EE	# <CJK>
+0x7336	0x8816	# <CJK>
+0x7337	0x8813	# <CJK>
+0x7338	0x87FE	# <CJK>
+0x7339	0x880A	# <CJK>
+0x733A	0x881B	# <CJK>
+0x733B	0x8821	# <CJK>
+0x733C	0x8839	# <CJK>
+0x733D	0x883C	# <CJK>
+0x733E	0x7F36	# <CJK>
+0x733F	0x7F42	# <CJK>
+0x7340	0x7F44	# <CJK>
+0x7341	0x7F45	# <CJK>
+0x7342	0x8210	# <CJK>
+0x7343	0x7AFA	# <CJK>
+0x7344	0x7AFD	# <CJK>
+0x7345	0x7B08	# <CJK>
+0x7346	0x7B03	# <CJK>
+0x7347	0x7B04	# <CJK>
+0x7348	0x7B15	# <CJK>
+0x7349	0x7B0A	# <CJK>
+0x734A	0x7B2B	# <CJK>
+0x734B	0x7B0F	# <CJK>
+0x734C	0x7B47	# <CJK>
+0x734D	0x7B38	# <CJK>
+0x734E	0x7B2A	# <CJK>
+0x734F	0x7B19	# <CJK>
+0x7350	0x7B2E	# <CJK>
+0x7351	0x7B31	# <CJK>
+0x7352	0x7B20	# <CJK>
+0x7353	0x7B25	# <CJK>
+0x7354	0x7B24	# <CJK>
+0x7355	0x7B33	# <CJK>
+0x7356	0x7B3E	# <CJK>
+0x7357	0x7B1E	# <CJK>
+0x7358	0x7B58	# <CJK>
+0x7359	0x7B5A	# <CJK>
+0x735A	0x7B45	# <CJK>
+0x735B	0x7B75	# <CJK>
+0x735C	0x7B4C	# <CJK>
+0x735D	0x7B5D	# <CJK>
+0x735E	0x7B60	# <CJK>
+0x735F	0x7B6E	# <CJK>
+0x7360	0x7B7B	# <CJK>
+0x7361	0x7B62	# <CJK>
+0x7362	0x7B72	# <CJK>
+0x7363	0x7B71	# <CJK>
+0x7364	0x7B90	# <CJK>
+0x7365	0x7BA6	# <CJK>
+0x7366	0x7BA7	# <CJK>
+0x7367	0x7BB8	# <CJK>
+0x7368	0x7BAC	# <CJK>
+0x7369	0x7B9D	# <CJK>
+0x736A	0x7BA8	# <CJK>
+0x736B	0x7B85	# <CJK>
+0x736C	0x7BAA	# <CJK>
+0x736D	0x7B9C	# <CJK>
+0x736E	0x7BA2	# <CJK>
+0x736F	0x7BAB	# <CJK>
+0x7370	0x7BB4	# <CJK>
+0x7371	0x7BD1	# <CJK>
+0x7372	0x7BC1	# <CJK>
+0x7373	0x7BCC	# <CJK>
+0x7374	0x7BDD	# <CJK>
+0x7375	0x7BDA	# <CJK>
+0x7376	0x7BE5	# <CJK>
+0x7377	0x7BE6	# <CJK>
+0x7378	0x7BEA	# <CJK>
+0x7379	0x7C0C	# <CJK>
+0x737A	0x7BFE	# <CJK>
+0x737B	0x7BFC	# <CJK>
+0x737C	0x7C0F	# <CJK>
+0x737D	0x7C16	# <CJK>
+0x737E	0x7C0B	# <CJK>
+0x7421	0x7C1F	# <CJK>
+0x7422	0x7C2A	# <CJK>
+0x7423	0x7C26	# <CJK>
+0x7424	0x7C38	# <CJK>
+0x7425	0x7C41	# <CJK>
+0x7426	0x7C40	# <CJK>
+0x7427	0x81FE	# <CJK>
+0x7428	0x8201	# <CJK>
+0x7429	0x8202	# <CJK>
+0x742A	0x8204	# <CJK>
+0x742B	0x81EC	# <CJK>
+0x742C	0x8844	# <CJK>
+0x742D	0x8221	# <CJK>
+0x742E	0x8222	# <CJK>
+0x742F	0x8223	# <CJK>
+0x7430	0x822D	# <CJK>
+0x7431	0x822F	# <CJK>
+0x7432	0x8228	# <CJK>
+0x7433	0x822B	# <CJK>
+0x7434	0x8238	# <CJK>
+0x7435	0x823B	# <CJK>
+0x7436	0x8233	# <CJK>
+0x7437	0x8234	# <CJK>
+0x7438	0x823E	# <CJK>
+0x7439	0x8244	# <CJK>
+0x743A	0x8249	# <CJK>
+0x743B	0x824B	# <CJK>
+0x743C	0x824F	# <CJK>
+0x743D	0x825A	# <CJK>
+0x743E	0x825F	# <CJK>
+0x743F	0x8268	# <CJK>
+0x7440	0x887E	# <CJK>
+0x7441	0x8885	# <CJK>
+0x7442	0x8888	# <CJK>
+0x7443	0x88D8	# <CJK>
+0x7444	0x88DF	# <CJK>
+0x7445	0x895E	# <CJK>
+0x7446	0x7F9D	# <CJK>
+0x7447	0x7F9F	# <CJK>
+0x7448	0x7FA7	# <CJK>
+0x7449	0x7FAF	# <CJK>
+0x744A	0x7FB0	# <CJK>
+0x744B	0x7FB2	# <CJK>
+0x744C	0x7C7C	# <CJK>
+0x744D	0x6549	# <CJK>
+0x744E	0x7C91	# <CJK>
+0x744F	0x7C9D	# <CJK>
+0x7450	0x7C9C	# <CJK>
+0x7451	0x7C9E	# <CJK>
+0x7452	0x7CA2	# <CJK>
+0x7453	0x7CB2	# <CJK>
+0x7454	0x7CBC	# <CJK>
+0x7455	0x7CBD	# <CJK>
+0x7456	0x7CC1	# <CJK>
+0x7457	0x7CC7	# <CJK>
+0x7458	0x7CCC	# <CJK>
+0x7459	0x7CCD	# <CJK>
+0x745A	0x7CC8	# <CJK>
+0x745B	0x7CC5	# <CJK>
+0x745C	0x7CD7	# <CJK>
+0x745D	0x7CE8	# <CJK>
+0x745E	0x826E	# <CJK>
+0x745F	0x66A8	# <CJK>
+0x7460	0x7FBF	# <CJK>
+0x7461	0x7FCE	# <CJK>
+0x7462	0x7FD5	# <CJK>
+0x7463	0x7FE5	# <CJK>
+0x7464	0x7FE1	# <CJK>
+0x7465	0x7FE6	# <CJK>
+0x7466	0x7FE9	# <CJK>
+0x7467	0x7FEE	# <CJK>
+0x7468	0x7FF3	# <CJK>
+0x7469	0x7CF8	# <CJK>
+0x746A	0x7D77	# <CJK>
+0x746B	0x7DA6	# <CJK>
+0x746C	0x7DAE	# <CJK>
+0x746D	0x7E47	# <CJK>
+0x746E	0x7E9B	# <CJK>
+0x746F	0x9EB8	# <CJK>
+0x7470	0x9EB4	# <CJK>
+0x7471	0x8D73	# <CJK>
+0x7472	0x8D84	# <CJK>
+0x7473	0x8D94	# <CJK>
+0x7474	0x8D91	# <CJK>
+0x7475	0x8DB1	# <CJK>
+0x7476	0x8D67	# <CJK>
+0x7477	0x8D6D	# <CJK>
+0x7478	0x8C47	# <CJK>
+0x7479	0x8C49	# <CJK>
+0x747A	0x914A	# <CJK>
+0x747B	0x9150	# <CJK>
+0x747C	0x914E	# <CJK>
+0x747D	0x914F	# <CJK>
+0x747E	0x9164	# <CJK>
+0x7521	0x9162	# <CJK>
+0x7522	0x9161	# <CJK>
+0x7523	0x9170	# <CJK>
+0x7524	0x9169	# <CJK>
+0x7525	0x916F	# <CJK>
+0x7526	0x917D	# <CJK>
+0x7527	0x917E	# <CJK>
+0x7528	0x9172	# <CJK>
+0x7529	0x9174	# <CJK>
+0x752A	0x9179	# <CJK>
+0x752B	0x918C	# <CJK>
+0x752C	0x9185	# <CJK>
+0x752D	0x9190	# <CJK>
+0x752E	0x918D	# <CJK>
+0x752F	0x9191	# <CJK>
+0x7530	0x91A2	# <CJK>
+0x7531	0x91A3	# <CJK>
+0x7532	0x91AA	# <CJK>
+0x7533	0x91AD	# <CJK>
+0x7534	0x91AE	# <CJK>
+0x7535	0x91AF	# <CJK>
+0x7536	0x91B5	# <CJK>
+0x7537	0x91B4	# <CJK>
+0x7538	0x91BA	# <CJK>
+0x7539	0x8C55	# <CJK>
+0x753A	0x9E7E	# <CJK>
+0x753B	0x8DB8	# <CJK>
+0x753C	0x8DEB	# <CJK>
+0x753D	0x8E05	# <CJK>
+0x753E	0x8E59	# <CJK>
+0x753F	0x8E69	# <CJK>
+0x7540	0x8DB5	# <CJK>
+0x7541	0x8DBF	# <CJK>
+0x7542	0x8DBC	# <CJK>
+0x7543	0x8DBA	# <CJK>
+0x7544	0x8DC4	# <CJK>
+0x7545	0x8DD6	# <CJK>
+0x7546	0x8DD7	# <CJK>
+0x7547	0x8DDA	# <CJK>
+0x7548	0x8DDE	# <CJK>
+0x7549	0x8DCE	# <CJK>
+0x754A	0x8DCF	# <CJK>
+0x754B	0x8DDB	# <CJK>
+0x754C	0x8DC6	# <CJK>
+0x754D	0x8DEC	# <CJK>
+0x754E	0x8DF7	# <CJK>
+0x754F	0x8DF8	# <CJK>
+0x7550	0x8DE3	# <CJK>
+0x7551	0x8DF9	# <CJK>
+0x7552	0x8DFB	# <CJK>
+0x7553	0x8DE4	# <CJK>
+0x7554	0x8E09	# <CJK>
+0x7555	0x8DFD	# <CJK>
+0x7556	0x8E14	# <CJK>
+0x7557	0x8E1D	# <CJK>
+0x7558	0x8E1F	# <CJK>
+0x7559	0x8E2C	# <CJK>
+0x755A	0x8E2E	# <CJK>
+0x755B	0x8E23	# <CJK>
+0x755C	0x8E2F	# <CJK>
+0x755D	0x8E3A	# <CJK>
+0x755E	0x8E40	# <CJK>
+0x755F	0x8E39	# <CJK>
+0x7560	0x8E35	# <CJK>
+0x7561	0x8E3D	# <CJK>
+0x7562	0x8E31	# <CJK>
+0x7563	0x8E49	# <CJK>
+0x7564	0x8E41	# <CJK>
+0x7565	0x8E42	# <CJK>
+0x7566	0x8E51	# <CJK>
+0x7567	0x8E52	# <CJK>
+0x7568	0x8E4A	# <CJK>
+0x7569	0x8E70	# <CJK>
+0x756A	0x8E76	# <CJK>
+0x756B	0x8E7C	# <CJK>
+0x756C	0x8E6F	# <CJK>
+0x756D	0x8E74	# <CJK>
+0x756E	0x8E85	# <CJK>
+0x756F	0x8E8F	# <CJK>
+0x7570	0x8E94	# <CJK>
+0x7571	0x8E90	# <CJK>
+0x7572	0x8E9C	# <CJK>
+0x7573	0x8E9E	# <CJK>
+0x7574	0x8C78	# <CJK>
+0x7575	0x8C82	# <CJK>
+0x7576	0x8C8A	# <CJK>
+0x7577	0x8C85	# <CJK>
+0x7578	0x8C98	# <CJK>
+0x7579	0x8C94	# <CJK>
+0x757A	0x659B	# <CJK>
+0x757B	0x89D6	# <CJK>
+0x757C	0x89DE	# <CJK>
+0x757D	0x89DA	# <CJK>
+0x757E	0x89DC	# <CJK>
+0x7621	0x89E5	# <CJK>
+0x7622	0x89EB	# <CJK>
+0x7623	0x89EF	# <CJK>
+0x7624	0x8A3E	# <CJK>
+0x7625	0x8B26	# <CJK>
+0x7626	0x9753	# <CJK>
+0x7627	0x96E9	# <CJK>
+0x7628	0x96F3	# <CJK>
+0x7629	0x96EF	# <CJK>
+0x762A	0x9706	# <CJK>
+0x762B	0x9701	# <CJK>
+0x762C	0x9708	# <CJK>
+0x762D	0x970F	# <CJK>
+0x762E	0x970E	# <CJK>
+0x762F	0x972A	# <CJK>
+0x7630	0x972D	# <CJK>
+0x7631	0x9730	# <CJK>
+0x7632	0x973E	# <CJK>
+0x7633	0x9F80	# <CJK>
+0x7634	0x9F83	# <CJK>
+0x7635	0x9F85	# <CJK>
+0x7636	0x9F86	# <CJK>
+0x7637	0x9F87	# <CJK>
+0x7638	0x9F88	# <CJK>
+0x7639	0x9F89	# <CJK>
+0x763A	0x9F8A	# <CJK>
+0x763B	0x9F8C	# <CJK>
+0x763C	0x9EFE	# <CJK>
+0x763D	0x9F0B	# <CJK>
+0x763E	0x9F0D	# <CJK>
+0x763F	0x96B9	# <CJK>
+0x7640	0x96BC	# <CJK>
+0x7641	0x96BD	# <CJK>
+0x7642	0x96CE	# <CJK>
+0x7643	0x96D2	# <CJK>
+0x7644	0x77BF	# <CJK>
+0x7645	0x96E0	# <CJK>
+0x7646	0x928E	# <CJK>
+0x7647	0x92AE	# <CJK>
+0x7648	0x92C8	# <CJK>
+0x7649	0x933E	# <CJK>
+0x764A	0x936A	# <CJK>
+0x764B	0x93CA	# <CJK>
+0x764C	0x938F	# <CJK>
+0x764D	0x943E	# <CJK>
+0x764E	0x946B	# <CJK>
+0x764F	0x9C7F	# <CJK>
+0x7650	0x9C82	# <CJK>
+0x7651	0x9C85	# <CJK>
+0x7652	0x9C86	# <CJK>
+0x7653	0x9C87	# <CJK>
+0x7654	0x9C88	# <CJK>
+0x7655	0x7A23	# <CJK>
+0x7656	0x9C8B	# <CJK>
+0x7657	0x9C8E	# <CJK>
+0x7658	0x9C90	# <CJK>
+0x7659	0x9C91	# <CJK>
+0x765A	0x9C92	# <CJK>
+0x765B	0x9C94	# <CJK>
+0x765C	0x9C95	# <CJK>
+0x765D	0x9C9A	# <CJK>
+0x765E	0x9C9B	# <CJK>
+0x765F	0x9C9E	# <CJK>
+0x7660	0x9C9F	# <CJK>
+0x7661	0x9CA0	# <CJK>
+0x7662	0x9CA1	# <CJK>
+0x7663	0x9CA2	# <CJK>
+0x7664	0x9CA3	# <CJK>
+0x7665	0x9CA5	# <CJK>
+0x7666	0x9CA6	# <CJK>
+0x7667	0x9CA7	# <CJK>
+0x7668	0x9CA8	# <CJK>
+0x7669	0x9CA9	# <CJK>
+0x766A	0x9CAB	# <CJK>
+0x766B	0x9CAD	# <CJK>
+0x766C	0x9CAE	# <CJK>
+0x766D	0x9CB0	# <CJK>
+0x766E	0x9CB1	# <CJK>
+0x766F	0x9CB2	# <CJK>
+0x7670	0x9CB3	# <CJK>
+0x7671	0x9CB4	# <CJK>
+0x7672	0x9CB5	# <CJK>
+0x7673	0x9CB6	# <CJK>
+0x7674	0x9CB7	# <CJK>
+0x7675	0x9CBA	# <CJK>
+0x7676	0x9CBB	# <CJK>
+0x7677	0x9CBC	# <CJK>
+0x7678	0x9CBD	# <CJK>
+0x7679	0x9CC4	# <CJK>
+0x767A	0x9CC5	# <CJK>
+0x767B	0x9CC6	# <CJK>
+0x767C	0x9CC7	# <CJK>
+0x767D	0x9CCA	# <CJK>
+0x767E	0x9CCB	# <CJK>
+0x7721	0x9CCC	# <CJK>
+0x7722	0x9CCD	# <CJK>
+0x7723	0x9CCE	# <CJK>
+0x7724	0x9CCF	# <CJK>
+0x7725	0x9CD0	# <CJK>
+0x7726	0x9CD3	# <CJK>
+0x7727	0x9CD4	# <CJK>
+0x7728	0x9CD5	# <CJK>
+0x7729	0x9CD7	# <CJK>
+0x772A	0x9CD8	# <CJK>
+0x772B	0x9CD9	# <CJK>
+0x772C	0x9CDC	# <CJK>
+0x772D	0x9CDD	# <CJK>
+0x772E	0x9CDF	# <CJK>
+0x772F	0x9CE2	# <CJK>
+0x7730	0x977C	# <CJK>
+0x7731	0x9785	# <CJK>
+0x7732	0x9791	# <CJK>
+0x7733	0x9792	# <CJK>
+0x7734	0x9794	# <CJK>
+0x7735	0x97AF	# <CJK>
+0x7736	0x97AB	# <CJK>
+0x7737	0x97A3	# <CJK>
+0x7738	0x97B2	# <CJK>
+0x7739	0x97B4	# <CJK>
+0x773A	0x9AB1	# <CJK>
+0x773B	0x9AB0	# <CJK>
+0x773C	0x9AB7	# <CJK>
+0x773D	0x9E58	# <CJK>
+0x773E	0x9AB6	# <CJK>
+0x773F	0x9ABA	# <CJK>
+0x7740	0x9ABC	# <CJK>
+0x7741	0x9AC1	# <CJK>
+0x7742	0x9AC0	# <CJK>
+0x7743	0x9AC5	# <CJK>
+0x7744	0x9AC2	# <CJK>
+0x7745	0x9ACB	# <CJK>
+0x7746	0x9ACC	# <CJK>
+0x7747	0x9AD1	# <CJK>
+0x7748	0x9B45	# <CJK>
+0x7749	0x9B43	# <CJK>
+0x774A	0x9B47	# <CJK>
+0x774B	0x9B49	# <CJK>
+0x774C	0x9B48	# <CJK>
+0x774D	0x9B4D	# <CJK>
+0x774E	0x9B51	# <CJK>
+0x774F	0x98E8	# <CJK>
+0x7750	0x990D	# <CJK>
+0x7751	0x992E	# <CJK>
+0x7752	0x9955	# <CJK>
+0x7753	0x9954	# <CJK>
+0x7754	0x9ADF	# <CJK>
+0x7755	0x9AE1	# <CJK>
+0x7756	0x9AE6	# <CJK>
+0x7757	0x9AEF	# <CJK>
+0x7758	0x9AEB	# <CJK>
+0x7759	0x9AFB	# <CJK>
+0x775A	0x9AED	# <CJK>
+0x775B	0x9AF9	# <CJK>
+0x775C	0x9B08	# <CJK>
+0x775D	0x9B0F	# <CJK>
+0x775E	0x9B13	# <CJK>
+0x775F	0x9B1F	# <CJK>
+0x7760	0x9B23	# <CJK>
+0x7761	0x9EBD	# <CJK>
+0x7762	0x9EBE	# <CJK>
+0x7763	0x7E3B	# <CJK>
+0x7764	0x9E82	# <CJK>
+0x7765	0x9E87	# <CJK>
+0x7766	0x9E88	# <CJK>
+0x7767	0x9E8B	# <CJK>
+0x7768	0x9E92	# <CJK>
+0x7769	0x93D6	# <CJK>
+0x776A	0x9E9D	# <CJK>
+0x776B	0x9E9F	# <CJK>
+0x776C	0x9EDB	# <CJK>
+0x776D	0x9EDC	# <CJK>
+0x776E	0x9EDD	# <CJK>
+0x776F	0x9EE0	# <CJK>
+0x7770	0x9EDF	# <CJK>
+0x7771	0x9EE2	# <CJK>
+0x7772	0x9EE9	# <CJK>
+0x7773	0x9EE7	# <CJK>
+0x7774	0x9EE5	# <CJK>
+0x7775	0x9EEA	# <CJK>
+0x7776	0x9EEF	# <CJK>
+0x7777	0x9F22	# <CJK>
+0x7778	0x9F2C	# <CJK>
+0x7779	0x9F2F	# <CJK>
+0x777A	0x9F39	# <CJK>
+0x777B	0x9F37	# <CJK>
+0x777C	0x9F3D	# <CJK>
+0x777D	0x9F3E	# <CJK>
+0x777E	0x9F44	# <CJK>
diff --git a/tools/encoding/iso2022-jp.esc b/tools/encoding/iso2022-jp.esc
new file mode 100644
index 0000000..0317856
--- /dev/null
+++ b/tools/encoding/iso2022-jp.esc
@@ -0,0 +1,10 @@
+name		iso2022-jp
+init		{}
+final		{}
+iso8859-1	\x1b(B
+jis0201		\x1b(J
+jis0208		\x1b$B
+jis0208		\x1b$@
+jis0212		\x1b$(D
+gb2312		\x1b$A
+ksc5601		\x1b$(C
diff --git a/tools/encoding/iso2022-kr.esc b/tools/encoding/iso2022-kr.esc
new file mode 100644
index 0000000..5e5ed4e
--- /dev/null
+++ b/tools/encoding/iso2022-kr.esc
@@ -0,0 +1,5 @@
+name		iso2022-kr
+init		\x1b$)C
+final		{}
+iso8859-1	\x0f
+ksc5601		\x0e
diff --git a/tools/encoding/iso2022.esc b/tools/encoding/iso2022.esc
new file mode 100644
index 0000000..c7f4403
--- /dev/null
+++ b/tools/encoding/iso2022.esc
@@ -0,0 +1,12 @@
+name		iso2022
+init		{}
+final		{}
+iso8859-1	\x1b(B
+jis0201		\x1b(J
+gb1988		\x1b(T
+jis0208		\x1b$B
+jis0208		\x1b$@
+jis0212		\x1b$(D
+gb2312		\x1b$A
+ksc5601		\x1b$(C
+jis0208		\x1b&@\x1b$B
diff --git a/tools/encoding/iso8859-1.txt b/tools/encoding/iso8859-1.txt
new file mode 100644
index 0000000..473ecab
--- /dev/null
+++ b/tools/encoding/iso8859-1.txt
@@ -0,0 +1,303 @@
+#
+#	Name:             ISO/IEC 8859-1:1998 to Unicode
+#	Unicode version:  3.0
+#	Table version:    1.0
+#	Table format:     Format A
+#	Date:             1999 July 27
+#	Authors:          Ken Whistler <kenw@sybase.com>
+#
+#	Copyright (c) 1991-1999 Unicode, Inc.  All Rights reserved.
+#
+#	This file is provided as-is by Unicode, Inc. (The Unicode Consortium).
+#	No claims are made as to fitness for any particular purpose.  No
+#	warranties of any kind are expressed or implied.  The recipient
+#	agrees to determine applicability of information provided.  If this
+#	file has been provided on optical media by Unicode, Inc., the sole
+#	remedy for any claim will be exchange of defective media within 90
+#	days of receipt.
+#
+#	Unicode, Inc. hereby grants the right to freely use the information
+#	supplied in this file in the creation of products supporting the
+#	Unicode Standard, and to make copies of this file in any form for
+#	internal or external distribution as long as this notice remains
+#	attached.
+#
+#	General notes:
+#
+#	This table contains the data the Unicode Consortium has on how
+#       ISO/IEC 8859-1:1998 characters map into Unicode.
+#
+#	Format:  Three tab-separated columns
+#		 Column #1 is the ISO/IEC 8859-1 code (in hex as 0xXX)
+#		 Column #2 is the Unicode (in hex as 0xXXXX)
+#		 Column #3 the Unicode name (follows a comment sign, '#')
+#
+#	The entries are in ISO/IEC 8859-1 order.
+#
+#	Version history
+#	1.0 version updates 0.1 version by adding mappings for all
+#	control characters.
+#
+#	Updated versions of this file may be found in:
+#		<ftp://ftp.unicode.org/Public/MAPPINGS/>
+#
+#	Any comments or problems, contact <errata@unicode.org>
+#	Please note that <errata@unicode.org> is an archival address;
+#	notices will be checked, but do not expect an immediate response.
+#
+0x00	0x0000	#	NULL
+0x01	0x0001	#	START OF HEADING
+0x02	0x0002	#	START OF TEXT
+0x03	0x0003	#	END OF TEXT
+0x04	0x0004	#	END OF TRANSMISSION
+0x05	0x0005	#	ENQUIRY
+0x06	0x0006	#	ACKNOWLEDGE
+0x07	0x0007	#	BELL
+0x08	0x0008	#	BACKSPACE
+0x09	0x0009	#	HORIZONTAL TABULATION
+0x0A	0x000A	#	LINE FEED
+0x0B	0x000B	#	VERTICAL TABULATION
+0x0C	0x000C	#	FORM FEED
+0x0D	0x000D	#	CARRIAGE RETURN
+0x0E	0x000E	#	SHIFT OUT
+0x0F	0x000F	#	SHIFT IN
+0x10	0x0010	#	DATA LINK ESCAPE
+0x11	0x0011	#	DEVICE CONTROL ONE
+0x12	0x0012	#	DEVICE CONTROL TWO
+0x13	0x0013	#	DEVICE CONTROL THREE
+0x14	0x0014	#	DEVICE CONTROL FOUR
+0x15	0x0015	#	NEGATIVE ACKNOWLEDGE
+0x16	0x0016	#	SYNCHRONOUS IDLE
+0x17	0x0017	#	END OF TRANSMISSION BLOCK
+0x18	0x0018	#	CANCEL
+0x19	0x0019	#	END OF MEDIUM
+0x1A	0x001A	#	SUBSTITUTE
+0x1B	0x001B	#	ESCAPE
+0x1C	0x001C	#	FILE SEPARATOR
+0x1D	0x001D	#	GROUP SEPARATOR
+0x1E	0x001E	#	RECORD SEPARATOR
+0x1F	0x001F	#	UNIT SEPARATOR
+0x20	0x0020	#	SPACE
+0x21	0x0021	#	EXCLAMATION MARK
+0x22	0x0022	#	QUOTATION MARK
+0x23	0x0023	#	NUMBER SIGN
+0x24	0x0024	#	DOLLAR SIGN
+0x25	0x0025	#	PERCENT SIGN
+0x26	0x0026	#	AMPERSAND
+0x27	0x0027	#	APOSTROPHE
+0x28	0x0028	#	LEFT PARENTHESIS
+0x29	0x0029	#	RIGHT PARENTHESIS
+0x2A	0x002A	#	ASTERISK
+0x2B	0x002B	#	PLUS SIGN
+0x2C	0x002C	#	COMMA
+0x2D	0x002D	#	HYPHEN-MINUS
+0x2E	0x002E	#	FULL STOP
+0x2F	0x002F	#	SOLIDUS
+0x30	0x0030	#	DIGIT ZERO
+0x31	0x0031	#	DIGIT ONE
+0x32	0x0032	#	DIGIT TWO
+0x33	0x0033	#	DIGIT THREE
+0x34	0x0034	#	DIGIT FOUR
+0x35	0x0035	#	DIGIT FIVE
+0x36	0x0036	#	DIGIT SIX
+0x37	0x0037	#	DIGIT SEVEN
+0x38	0x0038	#	DIGIT EIGHT
+0x39	0x0039	#	DIGIT NINE
+0x3A	0x003A	#	COLON
+0x3B	0x003B	#	SEMICOLON
+0x3C	0x003C	#	LESS-THAN SIGN
+0x3D	0x003D	#	EQUALS SIGN
+0x3E	0x003E	#	GREATER-THAN SIGN
+0x3F	0x003F	#	QUESTION MARK
+0x40	0x0040	#	COMMERCIAL AT
+0x41	0x0041	#	LATIN CAPITAL LETTER A
+0x42	0x0042	#	LATIN CAPITAL LETTER B
+0x43	0x0043	#	LATIN CAPITAL LETTER C
+0x44	0x0044	#	LATIN CAPITAL LETTER D
+0x45	0x0045	#	LATIN CAPITAL LETTER E
+0x46	0x0046	#	LATIN CAPITAL LETTER F
+0x47	0x0047	#	LATIN CAPITAL LETTER G
+0x48	0x0048	#	LATIN CAPITAL LETTER H
+0x49	0x0049	#	LATIN CAPITAL LETTER I
+0x4A	0x004A	#	LATIN CAPITAL LETTER J
+0x4B	0x004B	#	LATIN CAPITAL LETTER K
+0x4C	0x004C	#	LATIN CAPITAL LETTER L
+0x4D	0x004D	#	LATIN CAPITAL LETTER M
+0x4E	0x004E	#	LATIN CAPITAL LETTER N
+0x4F	0x004F	#	LATIN CAPITAL LETTER O
+0x50	0x0050	#	LATIN CAPITAL LETTER P
+0x51	0x0051	#	LATIN CAPITAL LETTER Q
+0x52	0x0052	#	LATIN CAPITAL LETTER R
+0x53	0x0053	#	LATIN CAPITAL LETTER S
+0x54	0x0054	#	LATIN CAPITAL LETTER T
+0x55	0x0055	#	LATIN CAPITAL LETTER U
+0x56	0x0056	#	LATIN CAPITAL LETTER V
+0x57	0x0057	#	LATIN CAPITAL LETTER W
+0x58	0x0058	#	LATIN CAPITAL LETTER X
+0x59	0x0059	#	LATIN CAPITAL LETTER Y
+0x5A	0x005A	#	LATIN CAPITAL LETTER Z
+0x5B	0x005B	#	LEFT SQUARE BRACKET
+0x5C	0x005C	#	REVERSE SOLIDUS
+0x5D	0x005D	#	RIGHT SQUARE BRACKET
+0x5E	0x005E	#	CIRCUMFLEX ACCENT
+0x5F	0x005F	#	LOW LINE
+0x60	0x0060	#	GRAVE ACCENT
+0x61	0x0061	#	LATIN SMALL LETTER A
+0x62	0x0062	#	LATIN SMALL LETTER B
+0x63	0x0063	#	LATIN SMALL LETTER C
+0x64	0x0064	#	LATIN SMALL LETTER D
+0x65	0x0065	#	LATIN SMALL LETTER E
+0x66	0x0066	#	LATIN SMALL LETTER F
+0x67	0x0067	#	LATIN SMALL LETTER G
+0x68	0x0068	#	LATIN SMALL LETTER H
+0x69	0x0069	#	LATIN SMALL LETTER I
+0x6A	0x006A	#	LATIN SMALL LETTER J
+0x6B	0x006B	#	LATIN SMALL LETTER K
+0x6C	0x006C	#	LATIN SMALL LETTER L
+0x6D	0x006D	#	LATIN SMALL LETTER M
+0x6E	0x006E	#	LATIN SMALL LETTER N
+0x6F	0x006F	#	LATIN SMALL LETTER O
+0x70	0x0070	#	LATIN SMALL LETTER P
+0x71	0x0071	#	LATIN SMALL LETTER Q
+0x72	0x0072	#	LATIN SMALL LETTER R
+0x73	0x0073	#	LATIN SMALL LETTER S
+0x74	0x0074	#	LATIN SMALL LETTER T
+0x75	0x0075	#	LATIN SMALL LETTER U
+0x76	0x0076	#	LATIN SMALL LETTER V
+0x77	0x0077	#	LATIN SMALL LETTER W
+0x78	0x0078	#	LATIN SMALL LETTER X
+0x79	0x0079	#	LATIN SMALL LETTER Y
+0x7A	0x007A	#	LATIN SMALL LETTER Z
+0x7B	0x007B	#	LEFT CURLY BRACKET
+0x7C	0x007C	#	VERTICAL LINE
+0x7D	0x007D	#	RIGHT CURLY BRACKET
+0x7E	0x007E	#	TILDE
+0x7F	0x007F	#	DELETE
+0x80	0x0080	#	<control>
+0x81	0x0081	#	<control>
+0x82	0x0082	#	<control>
+0x83	0x0083	#	<control>
+0x84	0x0084	#	<control>
+0x85	0x0085	#	<control>
+0x86	0x0086	#	<control>
+0x87	0x0087	#	<control>
+0x88	0x0088	#	<control>
+0x89	0x0089	#	<control>
+0x8A	0x008A	#	<control>
+0x8B	0x008B	#	<control>
+0x8C	0x008C	#	<control>
+0x8D	0x008D	#	<control>
+0x8E	0x008E	#	<control>
+0x8F	0x008F	#	<control>
+0x90	0x0090	#	<control>
+0x91	0x0091	#	<control>
+0x92	0x0092	#	<control>
+0x93	0x0093	#	<control>
+0x94	0x0094	#	<control>
+0x95	0x0095	#	<control>
+0x96	0x0096	#	<control>
+0x97	0x0097	#	<control>
+0x98	0x0098	#	<control>
+0x99	0x0099	#	<control>
+0x9A	0x009A	#	<control>
+0x9B	0x009B	#	<control>
+0x9C	0x009C	#	<control>
+0x9D	0x009D	#	<control>
+0x9E	0x009E	#	<control>
+0x9F	0x009F	#	<control>
+0xA0	0x00A0	#	NO-BREAK SPACE
+0xA1	0x00A1	#	INVERTED EXCLAMATION MARK
+0xA2	0x00A2	#	CENT SIGN
+0xA3	0x00A3	#	POUND SIGN
+0xA4	0x00A4	#	CURRENCY SIGN
+0xA5	0x00A5	#	YEN SIGN
+0xA6	0x00A6	#	BROKEN BAR
+0xA7	0x00A7	#	SECTION SIGN
+0xA8	0x00A8	#	DIAERESIS
+0xA9	0x00A9	#	COPYRIGHT SIGN
+0xAA	0x00AA	#	FEMININE ORDINAL INDICATOR
+0xAB	0x00AB	#	LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+0xAC	0x00AC	#	NOT SIGN
+0xAD	0x00AD	#	SOFT HYPHEN
+0xAE	0x00AE	#	REGISTERED SIGN
+0xAF	0x00AF	#	MACRON
+0xB0	0x00B0	#	DEGREE SIGN
+0xB1	0x00B1	#	PLUS-MINUS SIGN
+0xB2	0x00B2	#	SUPERSCRIPT TWO
+0xB3	0x00B3	#	SUPERSCRIPT THREE
+0xB4	0x00B4	#	ACUTE ACCENT
+0xB5	0x00B5	#	MICRO SIGN
+0xB6	0x00B6	#	PILCROW SIGN
+0xB7	0x00B7	#	MIDDLE DOT
+0xB8	0x00B8	#	CEDILLA
+0xB9	0x00B9	#	SUPERSCRIPT ONE
+0xBA	0x00BA	#	MASCULINE ORDINAL INDICATOR
+0xBB	0x00BB	#	RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+0xBC	0x00BC	#	VULGAR FRACTION ONE QUARTER
+0xBD	0x00BD	#	VULGAR FRACTION ONE HALF
+0xBE	0x00BE	#	VULGAR FRACTION THREE QUARTERS
+0xBF	0x00BF	#	INVERTED QUESTION MARK
+0xC0	0x00C0	#	LATIN CAPITAL LETTER A WITH GRAVE
+0xC1	0x00C1	#	LATIN CAPITAL LETTER A WITH ACUTE
+0xC2	0x00C2	#	LATIN CAPITAL LETTER A WITH CIRCUMFLEX
+0xC3	0x00C3	#	LATIN CAPITAL LETTER A WITH TILDE
+0xC4	0x00C4	#	LATIN CAPITAL LETTER A WITH DIAERESIS
+0xC5	0x00C5	#	LATIN CAPITAL LETTER A WITH RING ABOVE
+0xC6	0x00C6	#	LATIN CAPITAL LETTER AE
+0xC7	0x00C7	#	LATIN CAPITAL LETTER C WITH CEDILLA
+0xC8	0x00C8	#	LATIN CAPITAL LETTER E WITH GRAVE
+0xC9	0x00C9	#	LATIN CAPITAL LETTER E WITH ACUTE
+0xCA	0x00CA	#	LATIN CAPITAL LETTER E WITH CIRCUMFLEX
+0xCB	0x00CB	#	LATIN CAPITAL LETTER E WITH DIAERESIS
+0xCC	0x00CC	#	LATIN CAPITAL LETTER I WITH GRAVE
+0xCD	0x00CD	#	LATIN CAPITAL LETTER I WITH ACUTE
+0xCE	0x00CE	#	LATIN CAPITAL LETTER I WITH CIRCUMFLEX
+0xCF	0x00CF	#	LATIN CAPITAL LETTER I WITH DIAERESIS
+0xD0	0x00D0	#	LATIN CAPITAL LETTER ETH (Icelandic)
+0xD1	0x00D1	#	LATIN CAPITAL LETTER N WITH TILDE
+0xD2	0x00D2	#	LATIN CAPITAL LETTER O WITH GRAVE
+0xD3	0x00D3	#	LATIN CAPITAL LETTER O WITH ACUTE
+0xD4	0x00D4	#	LATIN CAPITAL LETTER O WITH CIRCUMFLEX
+0xD5	0x00D5	#	LATIN CAPITAL LETTER O WITH TILDE
+0xD6	0x00D6	#	LATIN CAPITAL LETTER O WITH DIAERESIS
+0xD7	0x00D7	#	MULTIPLICATION SIGN
+0xD8	0x00D8	#	LATIN CAPITAL LETTER O WITH STROKE
+0xD9	0x00D9	#	LATIN CAPITAL LETTER U WITH GRAVE
+0xDA	0x00DA	#	LATIN CAPITAL LETTER U WITH ACUTE
+0xDB	0x00DB	#	LATIN CAPITAL LETTER U WITH CIRCUMFLEX
+0xDC	0x00DC	#	LATIN CAPITAL LETTER U WITH DIAERESIS
+0xDD	0x00DD	#	LATIN CAPITAL LETTER Y WITH ACUTE
+0xDE	0x00DE	#	LATIN CAPITAL LETTER THORN (Icelandic)
+0xDF	0x00DF	#	LATIN SMALL LETTER SHARP S (German)
+0xE0	0x00E0	#	LATIN SMALL LETTER A WITH GRAVE
+0xE1	0x00E1	#	LATIN SMALL LETTER A WITH ACUTE
+0xE2	0x00E2	#	LATIN SMALL LETTER A WITH CIRCUMFLEX
+0xE3	0x00E3	#	LATIN SMALL LETTER A WITH TILDE
+0xE4	0x00E4	#	LATIN SMALL LETTER A WITH DIAERESIS
+0xE5	0x00E5	#	LATIN SMALL LETTER A WITH RING ABOVE
+0xE6	0x00E6	#	LATIN SMALL LETTER AE
+0xE7	0x00E7	#	LATIN SMALL LETTER C WITH CEDILLA
+0xE8	0x00E8	#	LATIN SMALL LETTER E WITH GRAVE
+0xE9	0x00E9	#	LATIN SMALL LETTER E WITH ACUTE
+0xEA	0x00EA	#	LATIN SMALL LETTER E WITH CIRCUMFLEX
+0xEB	0x00EB	#	LATIN SMALL LETTER E WITH DIAERESIS
+0xEC	0x00EC	#	LATIN SMALL LETTER I WITH GRAVE
+0xED	0x00ED	#	LATIN SMALL LETTER I WITH ACUTE
+0xEE	0x00EE	#	LATIN SMALL LETTER I WITH CIRCUMFLEX
+0xEF	0x00EF	#	LATIN SMALL LETTER I WITH DIAERESIS
+0xF0	0x00F0	#	LATIN SMALL LETTER ETH (Icelandic)
+0xF1	0x00F1	#	LATIN SMALL LETTER N WITH TILDE
+0xF2	0x00F2	#	LATIN SMALL LETTER O WITH GRAVE
+0xF3	0x00F3	#	LATIN SMALL LETTER O WITH ACUTE
+0xF4	0x00F4	#	LATIN SMALL LETTER O WITH CIRCUMFLEX
+0xF5	0x00F5	#	LATIN SMALL LETTER O WITH TILDE
+0xF6	0x00F6	#	LATIN SMALL LETTER O WITH DIAERESIS
+0xF7	0x00F7	#	DIVISION SIGN
+0xF8	0x00F8	#	LATIN SMALL LETTER O WITH STROKE
+0xF9	0x00F9	#	LATIN SMALL LETTER U WITH GRAVE
+0xFA	0x00FA	#	LATIN SMALL LETTER U WITH ACUTE
+0xFB	0x00FB	#	LATIN SMALL LETTER U WITH CIRCUMFLEX
+0xFC	0x00FC	#	LATIN SMALL LETTER U WITH DIAERESIS
+0xFD	0x00FD	#	LATIN SMALL LETTER Y WITH ACUTE
+0xFE	0x00FE	#	LATIN SMALL LETTER THORN (Icelandic)
+0xFF	0x00FF	#	LATIN SMALL LETTER Y WITH DIAERESIS
diff --git a/tools/encoding/iso8859-10.txt b/tools/encoding/iso8859-10.txt
new file mode 100644
index 0000000..374a42b
--- /dev/null
+++ b/tools/encoding/iso8859-10.txt
@@ -0,0 +1,303 @@
+#
+#	Name:             ISO/IEC 8859-10:1998 to Unicode
+#	Unicode version:  3.0
+#	Table version:    1.1
+#	Table format:     Format A
+#	Date:             1999 October 11
+#	Authors:          Ken Whistler <kenw@sybase.com>
+#
+#	Copyright (c) 1999 Unicode, Inc.  All Rights reserved.
+#
+#	This file is provided as-is by Unicode, Inc. (The Unicode Consortium).
+#	No claims are made as to fitness for any particular purpose.  No
+#	warranties of any kind are expressed or implied.  The recipient
+#	agrees to determine applicability of information provided.  If this
+#	file has been provided on optical media by Unicode, Inc., the sole
+#	remedy for any claim will be exchange of defective media within 90
+#	days of receipt.
+#
+#	Unicode, Inc. hereby grants the right to freely use the information
+#	supplied in this file in the creation of products supporting the
+#	Unicode Standard, and to make copies of this file in any form for
+#	internal or external distribution as long as this notice remains
+#	attached.
+#
+#	General notes:
+#
+#	This table contains the data the Unicode Consortium has on how
+#       ISO/IEC 8859-10:1998 characters map into Unicode.
+#
+#	Format:  Three tab-separated columns
+#		 Column #1 is the ISO/IEC 8859-10 code (in hex as 0xXX)
+#		 Column #2 is the Unicode (in hex as 0xXXXX)
+#		 Column #3 the Unicode name (follows a comment sign, '#')
+#
+#	The entries are in ISO/IEC 8859-10 order.
+#
+#	Version history
+#	1.0 version new.
+#       1.1 corrected mistake in mapping of 0xA4
+#
+#	Updated versions of this file may be found in:
+#		<ftp://ftp.unicode.org/Public/MAPPINGS/>
+#
+#	Any comments or problems, contact <errata@unicode.org>
+#	Please note that <errata@unicode.org> is an archival address;
+#	notices will be checked, but do not expect an immediate response.
+#
+0x00	0x0000	#	NULL
+0x01	0x0001	#	START OF HEADING
+0x02	0x0002	#	START OF TEXT
+0x03	0x0003	#	END OF TEXT
+0x04	0x0004	#	END OF TRANSMISSION
+0x05	0x0005	#	ENQUIRY
+0x06	0x0006	#	ACKNOWLEDGE
+0x07	0x0007	#	BELL
+0x08	0x0008	#	BACKSPACE
+0x09	0x0009	#	HORIZONTAL TABULATION
+0x0A	0x000A	#	LINE FEED
+0x0B	0x000B	#	VERTICAL TABULATION
+0x0C	0x000C	#	FORM FEED
+0x0D	0x000D	#	CARRIAGE RETURN
+0x0E	0x000E	#	SHIFT OUT
+0x0F	0x000F	#	SHIFT IN
+0x10	0x0010	#	DATA LINK ESCAPE
+0x11	0x0011	#	DEVICE CONTROL ONE
+0x12	0x0012	#	DEVICE CONTROL TWO
+0x13	0x0013	#	DEVICE CONTROL THREE
+0x14	0x0014	#	DEVICE CONTROL FOUR
+0x15	0x0015	#	NEGATIVE ACKNOWLEDGE
+0x16	0x0016	#	SYNCHRONOUS IDLE
+0x17	0x0017	#	END OF TRANSMISSION BLOCK
+0x18	0x0018	#	CANCEL
+0x19	0x0019	#	END OF MEDIUM
+0x1A	0x001A	#	SUBSTITUTE
+0x1B	0x001B	#	ESCAPE
+0x1C	0x001C	#	FILE SEPARATOR
+0x1D	0x001D	#	GROUP SEPARATOR
+0x1E	0x001E	#	RECORD SEPARATOR
+0x1F	0x001F	#	UNIT SEPARATOR
+0x20	0x0020	#	SPACE
+0x21	0x0021	#	EXCLAMATION MARK
+0x22	0x0022	#	QUOTATION MARK
+0x23	0x0023	#	NUMBER SIGN
+0x24	0x0024	#	DOLLAR SIGN
+0x25	0x0025	#	PERCENT SIGN
+0x26	0x0026	#	AMPERSAND
+0x27	0x0027	#	APOSTROPHE
+0x28	0x0028	#	LEFT PARENTHESIS
+0x29	0x0029	#	RIGHT PARENTHESIS
+0x2A	0x002A	#	ASTERISK
+0x2B	0x002B	#	PLUS SIGN
+0x2C	0x002C	#	COMMA
+0x2D	0x002D	#	HYPHEN-MINUS
+0x2E	0x002E	#	FULL STOP
+0x2F	0x002F	#	SOLIDUS
+0x30	0x0030	#	DIGIT ZERO
+0x31	0x0031	#	DIGIT ONE
+0x32	0x0032	#	DIGIT TWO
+0x33	0x0033	#	DIGIT THREE
+0x34	0x0034	#	DIGIT FOUR
+0x35	0x0035	#	DIGIT FIVE
+0x36	0x0036	#	DIGIT SIX
+0x37	0x0037	#	DIGIT SEVEN
+0x38	0x0038	#	DIGIT EIGHT
+0x39	0x0039	#	DIGIT NINE
+0x3A	0x003A	#	COLON
+0x3B	0x003B	#	SEMICOLON
+0x3C	0x003C	#	LESS-THAN SIGN
+0x3D	0x003D	#	EQUALS SIGN
+0x3E	0x003E	#	GREATER-THAN SIGN
+0x3F	0x003F	#	QUESTION MARK
+0x40	0x0040	#	COMMERCIAL AT
+0x41	0x0041	#	LATIN CAPITAL LETTER A
+0x42	0x0042	#	LATIN CAPITAL LETTER B
+0x43	0x0043	#	LATIN CAPITAL LETTER C
+0x44	0x0044	#	LATIN CAPITAL LETTER D
+0x45	0x0045	#	LATIN CAPITAL LETTER E
+0x46	0x0046	#	LATIN CAPITAL LETTER F
+0x47	0x0047	#	LATIN CAPITAL LETTER G
+0x48	0x0048	#	LATIN CAPITAL LETTER H
+0x49	0x0049	#	LATIN CAPITAL LETTER I
+0x4A	0x004A	#	LATIN CAPITAL LETTER J
+0x4B	0x004B	#	LATIN CAPITAL LETTER K
+0x4C	0x004C	#	LATIN CAPITAL LETTER L
+0x4D	0x004D	#	LATIN CAPITAL LETTER M
+0x4E	0x004E	#	LATIN CAPITAL LETTER N
+0x4F	0x004F	#	LATIN CAPITAL LETTER O
+0x50	0x0050	#	LATIN CAPITAL LETTER P
+0x51	0x0051	#	LATIN CAPITAL LETTER Q
+0x52	0x0052	#	LATIN CAPITAL LETTER R
+0x53	0x0053	#	LATIN CAPITAL LETTER S
+0x54	0x0054	#	LATIN CAPITAL LETTER T
+0x55	0x0055	#	LATIN CAPITAL LETTER U
+0x56	0x0056	#	LATIN CAPITAL LETTER V
+0x57	0x0057	#	LATIN CAPITAL LETTER W
+0x58	0x0058	#	LATIN CAPITAL LETTER X
+0x59	0x0059	#	LATIN CAPITAL LETTER Y
+0x5A	0x005A	#	LATIN CAPITAL LETTER Z
+0x5B	0x005B	#	LEFT SQUARE BRACKET
+0x5C	0x005C	#	REVERSE SOLIDUS
+0x5D	0x005D	#	RIGHT SQUARE BRACKET
+0x5E	0x005E	#	CIRCUMFLEX ACCENT
+0x5F	0x005F	#	LOW LINE
+0x60	0x0060	#	GRAVE ACCENT
+0x61	0x0061	#	LATIN SMALL LETTER A
+0x62	0x0062	#	LATIN SMALL LETTER B
+0x63	0x0063	#	LATIN SMALL LETTER C
+0x64	0x0064	#	LATIN SMALL LETTER D
+0x65	0x0065	#	LATIN SMALL LETTER E
+0x66	0x0066	#	LATIN SMALL LETTER F
+0x67	0x0067	#	LATIN SMALL LETTER G
+0x68	0x0068	#	LATIN SMALL LETTER H
+0x69	0x0069	#	LATIN SMALL LETTER I
+0x6A	0x006A	#	LATIN SMALL LETTER J
+0x6B	0x006B	#	LATIN SMALL LETTER K
+0x6C	0x006C	#	LATIN SMALL LETTER L
+0x6D	0x006D	#	LATIN SMALL LETTER M
+0x6E	0x006E	#	LATIN SMALL LETTER N
+0x6F	0x006F	#	LATIN SMALL LETTER O
+0x70	0x0070	#	LATIN SMALL LETTER P
+0x71	0x0071	#	LATIN SMALL LETTER Q
+0x72	0x0072	#	LATIN SMALL LETTER R
+0x73	0x0073	#	LATIN SMALL LETTER S
+0x74	0x0074	#	LATIN SMALL LETTER T
+0x75	0x0075	#	LATIN SMALL LETTER U
+0x76	0x0076	#	LATIN SMALL LETTER V
+0x77	0x0077	#	LATIN SMALL LETTER W
+0x78	0x0078	#	LATIN SMALL LETTER X
+0x79	0x0079	#	LATIN SMALL LETTER Y
+0x7A	0x007A	#	LATIN SMALL LETTER Z
+0x7B	0x007B	#	LEFT CURLY BRACKET
+0x7C	0x007C	#	VERTICAL LINE
+0x7D	0x007D	#	RIGHT CURLY BRACKET
+0x7E	0x007E	#	TILDE
+0x7F	0x007F	#	DELETE
+0x80	0x0080	#	<control>
+0x81	0x0081	#	<control>
+0x82	0x0082	#	<control>
+0x83	0x0083	#	<control>
+0x84	0x0084	#	<control>
+0x85	0x0085	#	<control>
+0x86	0x0086	#	<control>
+0x87	0x0087	#	<control>
+0x88	0x0088	#	<control>
+0x89	0x0089	#	<control>
+0x8A	0x008A	#	<control>
+0x8B	0x008B	#	<control>
+0x8C	0x008C	#	<control>
+0x8D	0x008D	#	<control>
+0x8E	0x008E	#	<control>
+0x8F	0x008F	#	<control>
+0x90	0x0090	#	<control>
+0x91	0x0091	#	<control>
+0x92	0x0092	#	<control>
+0x93	0x0093	#	<control>
+0x94	0x0094	#	<control>
+0x95	0x0095	#	<control>
+0x96	0x0096	#	<control>
+0x97	0x0097	#	<control>
+0x98	0x0098	#	<control>
+0x99	0x0099	#	<control>
+0x9A	0x009A	#	<control>
+0x9B	0x009B	#	<control>
+0x9C	0x009C	#	<control>
+0x9D	0x009D	#	<control>
+0x9E	0x009E	#	<control>
+0x9F	0x009F	#	<control>
+0xA0	0x00A0	#	NO-BREAK SPACE
+0xA1	0x0104	#	LATIN CAPITAL LETTER A WITH OGONEK
+0xA2	0x0112	#	LATIN CAPITAL LETTER E WITH MACRON
+0xA3	0x0122	#	LATIN CAPITAL LETTER G WITH CEDILLA
+0xA4	0x012A	#	LATIN CAPITAL LETTER I WITH MACRON
+0xA5	0x0128	#	LATIN CAPITAL LETTER I WITH TILDE
+0xA6	0x0136	#	LATIN CAPITAL LETTER K WITH CEDILLA
+0xA7	0x00A7	#	SECTION SIGN
+0xA8	0x013B	#	LATIN CAPITAL LETTER L WITH CEDILLA
+0xA9	0x0110	#	LATIN CAPITAL LETTER D WITH STROKE
+0xAA	0x0160	#	LATIN CAPITAL LETTER S WITH CARON
+0xAB	0x0166	#	LATIN CAPITAL LETTER T WITH STROKE
+0xAC	0x017D	#	LATIN CAPITAL LETTER Z WITH CARON
+0xAD	0x00AD	#	SOFT HYPHEN
+0xAE	0x016A	#	LATIN CAPITAL LETTER U WITH MACRON
+0xAF	0x014A	#	LATIN CAPITAL LETTER ENG
+0xB0	0x00B0	#	DEGREE SIGN
+0xB1	0x0105	#	LATIN SMALL LETTER A WITH OGONEK
+0xB2	0x0113	#	LATIN SMALL LETTER E WITH MACRON
+0xB3	0x0123	#	LATIN SMALL LETTER G WITH CEDILLA
+0xB4	0x012B	#	LATIN SMALL LETTER I WITH MACRON
+0xB5	0x0129	#	LATIN SMALL LETTER I WITH TILDE
+0xB6	0x0137	#	LATIN SMALL LETTER K WITH CEDILLA
+0xB7	0x00B7	#	MIDDLE DOT
+0xB8	0x013C	#	LATIN SMALL LETTER L WITH CEDILLA
+0xB9	0x0111	#	LATIN SMALL LETTER D WITH STROKE
+0xBA	0x0161	#	LATIN SMALL LETTER S WITH CARON
+0xBB	0x0167	#	LATIN SMALL LETTER T WITH STROKE
+0xBC	0x017E	#	LATIN SMALL LETTER Z WITH CARON
+0xBD	0x2015	#	HORIZONTAL BAR
+0xBE	0x016B	#	LATIN SMALL LETTER U WITH MACRON
+0xBF	0x014B	#	LATIN SMALL LETTER ENG
+0xC0	0x0100	#	LATIN CAPITAL LETTER A WITH MACRON
+0xC1	0x00C1	#	LATIN CAPITAL LETTER A WITH ACUTE
+0xC2	0x00C2	#	LATIN CAPITAL LETTER A WITH CIRCUMFLEX
+0xC3	0x00C3	#	LATIN CAPITAL LETTER A WITH TILDE
+0xC4	0x00C4	#	LATIN CAPITAL LETTER A WITH DIAERESIS
+0xC5	0x00C5	#	LATIN CAPITAL LETTER A WITH RING ABOVE
+0xC6	0x00C6	#	LATIN CAPITAL LETTER AE
+0xC7	0x012E	#	LATIN CAPITAL LETTER I WITH OGONEK
+0xC8	0x010C	#	LATIN CAPITAL LETTER C WITH CARON
+0xC9	0x00C9	#	LATIN CAPITAL LETTER E WITH ACUTE
+0xCA	0x0118	#	LATIN CAPITAL LETTER E WITH OGONEK
+0xCB	0x00CB	#	LATIN CAPITAL LETTER E WITH DIAERESIS
+0xCC	0x0116	#	LATIN CAPITAL LETTER E WITH DOT ABOVE
+0xCD	0x00CD	#	LATIN CAPITAL LETTER I WITH ACUTE
+0xCE	0x00CE	#	LATIN CAPITAL LETTER I WITH CIRCUMFLEX
+0xCF	0x00CF	#	LATIN CAPITAL LETTER I WITH DIAERESIS
+0xD0	0x00D0	#	LATIN CAPITAL LETTER ETH (Icelandic)
+0xD1	0x0145	#	LATIN CAPITAL LETTER N WITH CEDILLA
+0xD2	0x014C	#	LATIN CAPITAL LETTER O WITH MACRON
+0xD3	0x00D3	#	LATIN CAPITAL LETTER O WITH ACUTE
+0xD4	0x00D4	#	LATIN CAPITAL LETTER O WITH CIRCUMFLEX
+0xD5	0x00D5	#	LATIN CAPITAL LETTER O WITH TILDE
+0xD6	0x00D6	#	LATIN CAPITAL LETTER O WITH DIAERESIS
+0xD7	0x0168	#	LATIN CAPITAL LETTER U WITH TILDE
+0xD8	0x00D8	#	LATIN CAPITAL LETTER O WITH STROKE
+0xD9	0x0172	#	LATIN CAPITAL LETTER U WITH OGONEK
+0xDA	0x00DA	#	LATIN CAPITAL LETTER U WITH ACUTE
+0xDB	0x00DB	#	LATIN CAPITAL LETTER U WITH CIRCUMFLEX
+0xDC	0x00DC	#	LATIN CAPITAL LETTER U WITH DIAERESIS
+0xDD	0x00DD	#	LATIN CAPITAL LETTER Y WITH ACUTE
+0xDE	0x00DE	#	LATIN CAPITAL LETTER THORN (Icelandic)
+0xDF	0x00DF	#	LATIN SMALL LETTER SHARP S (German)
+0xE0	0x0101	#	LATIN SMALL LETTER A WITH MACRON
+0xE1	0x00E1	#	LATIN SMALL LETTER A WITH ACUTE
+0xE2	0x00E2	#	LATIN SMALL LETTER A WITH CIRCUMFLEX
+0xE3	0x00E3	#	LATIN SMALL LETTER A WITH TILDE
+0xE4	0x00E4	#	LATIN SMALL LETTER A WITH DIAERESIS
+0xE5	0x00E5	#	LATIN SMALL LETTER A WITH RING ABOVE
+0xE6	0x00E6	#	LATIN SMALL LETTER AE
+0xE7	0x012F	#	LATIN SMALL LETTER I WITH OGONEK
+0xE8	0x010D	#	LATIN SMALL LETTER C WITH CARON
+0xE9	0x00E9	#	LATIN SMALL LETTER E WITH ACUTE
+0xEA	0x0119	#	LATIN SMALL LETTER E WITH OGONEK
+0xEB	0x00EB	#	LATIN SMALL LETTER E WITH DIAERESIS
+0xEC	0x0117	#	LATIN SMALL LETTER E WITH DOT ABOVE
+0xED	0x00ED	#	LATIN SMALL LETTER I WITH ACUTE
+0xEE	0x00EE	#	LATIN SMALL LETTER I WITH CIRCUMFLEX
+0xEF	0x00EF	#	LATIN SMALL LETTER I WITH DIAERESIS
+0xF0	0x00F0	#	LATIN SMALL LETTER ETH (Icelandic)
+0xF1	0x0146	#	LATIN SMALL LETTER N WITH CEDILLA
+0xF2	0x014D	#	LATIN SMALL LETTER O WITH MACRON
+0xF3	0x00F3	#	LATIN SMALL LETTER O WITH ACUTE
+0xF4	0x00F4	#	LATIN SMALL LETTER O WITH CIRCUMFLEX
+0xF5	0x00F5	#	LATIN SMALL LETTER O WITH TILDE
+0xF6	0x00F6	#	LATIN SMALL LETTER O WITH DIAERESIS
+0xF7	0x0169	#	LATIN SMALL LETTER U WITH TILDE
+0xF8	0x00F8	#	LATIN SMALL LETTER O WITH STROKE
+0xF9	0x0173	#	LATIN SMALL LETTER U WITH OGONEK
+0xFA	0x00FA	#	LATIN SMALL LETTER U WITH ACUTE
+0xFB	0x00FB	#	LATIN SMALL LETTER U WITH CIRCUMFLEX
+0xFC	0x00FC	#	LATIN SMALL LETTER U WITH DIAERESIS
+0xFD	0x00FD	#	LATIN SMALL LETTER Y WITH ACUTE
+0xFE	0x00FE	#	LATIN SMALL LETTER THORN (Icelandic)
+0xFF	0x0138	#	LATIN SMALL LETTER KRA
diff --git a/tools/encoding/iso8859-13.txt b/tools/encoding/iso8859-13.txt
new file mode 100644
index 0000000..cd11b53
--- /dev/null
+++ b/tools/encoding/iso8859-13.txt
@@ -0,0 +1,299 @@
+#
+#	Name:             ISO/IEC 8859-13:1998  to Unicode
+#	Unicode version:  3.0
+#	Table version:    1.0
+#	Table format:     Format A
+#	Date:             1999 July 27
+#	Authors:          Ken Whistler <kenw@sybase.com>
+#
+#	Copyright (c) 1998 - 1999 Unicode, Inc.  All Rights reserved.
+#
+#	This file is provided as-is by Unicode, Inc. (The Unicode Consortium).
+#	No claims are made as to fitness for any particular purpose.  No
+#	warranties of any kind are expressed or implied.  The recipient
+#	agrees to determine applicability of information provided.  If this
+#	file has been provided on optical media by Unicode, Inc., the sole
+#	remedy for any claim will be exchange of defective media within 90
+#	days of receipt.
+#
+#	Unicode, Inc. hereby grants the right to freely use the information
+#	supplied in this file in the creation of products supporting the
+#	Unicode Standard, and to make copies of this file in any form for
+#	internal or external distribution as long as this notice remains
+#	attached.
+#
+#	General notes:
+#
+#	This table contains the data the Unicode Consortium has on how
+#       ISO/IEC 8859-13:1998 characters map into Unicode.
+#
+#	Format:  Three tab-separated columns
+#		 Column #1 is the ISO/IEC 8859-13 code (in hex as 0xXX)
+#		 Column #2 is the Unicode (in hex as 0xXXXX)
+#		 Column #3 the Unicode name (follows a comment sign, '#')
+#
+#	The entries are in ISO/IEC 8859-13 order.
+#
+#	Updated versions of this file may be found in:
+#		<ftp://ftp.unicode.org/Public/MAPPINGS/>
+#
+#	Any comments or problems, contact <errata@unicode.org>
+#	Please note that <errata@unicode.org> is an archival address;
+#	notices will be checked, but do not expect an immediate response.
+#
+0x00	0x0000	#	NULL
+0x01	0x0001	#	START OF HEADING
+0x02	0x0002	#	START OF TEXT
+0x03	0x0003	#	END OF TEXT
+0x04	0x0004	#	END OF TRANSMISSION
+0x05	0x0005	#	ENQUIRY
+0x06	0x0006	#	ACKNOWLEDGE
+0x07	0x0007	#	BELL
+0x08	0x0008	#	BACKSPACE
+0x09	0x0009	#	HORIZONTAL TABULATION
+0x0A	0x000A	#	LINE FEED
+0x0B	0x000B	#	VERTICAL TABULATION
+0x0C	0x000C	#	FORM FEED
+0x0D	0x000D	#	CARRIAGE RETURN
+0x0E	0x000E	#	SHIFT OUT
+0x0F	0x000F	#	SHIFT IN
+0x10	0x0010	#	DATA LINK ESCAPE
+0x11	0x0011	#	DEVICE CONTROL ONE
+0x12	0x0012	#	DEVICE CONTROL TWO
+0x13	0x0013	#	DEVICE CONTROL THREE
+0x14	0x0014	#	DEVICE CONTROL FOUR
+0x15	0x0015	#	NEGATIVE ACKNOWLEDGE
+0x16	0x0016	#	SYNCHRONOUS IDLE
+0x17	0x0017	#	END OF TRANSMISSION BLOCK
+0x18	0x0018	#	CANCEL
+0x19	0x0019	#	END OF MEDIUM
+0x1A	0x001A	#	SUBSTITUTE
+0x1B	0x001B	#	ESCAPE
+0x1C	0x001C	#	FILE SEPARATOR
+0x1D	0x001D	#	GROUP SEPARATOR
+0x1E	0x001E	#	RECORD SEPARATOR
+0x1F	0x001F	#	UNIT SEPARATOR
+0x20	0x0020	#	SPACE
+0x21	0x0021	#	EXCLAMATION MARK
+0x22	0x0022	#	QUOTATION MARK
+0x23	0x0023	#	NUMBER SIGN
+0x24	0x0024	#	DOLLAR SIGN
+0x25	0x0025	#	PERCENT SIGN
+0x26	0x0026	#	AMPERSAND
+0x27	0x0027	#	APOSTROPHE
+0x28	0x0028	#	LEFT PARENTHESIS
+0x29	0x0029	#	RIGHT PARENTHESIS
+0x2A	0x002A	#	ASTERISK
+0x2B	0x002B	#	PLUS SIGN
+0x2C	0x002C	#	COMMA
+0x2D	0x002D	#	HYPHEN-MINUS
+0x2E	0x002E	#	FULL STOP
+0x2F	0x002F	#	SOLIDUS
+0x30	0x0030	#	DIGIT ZERO
+0x31	0x0031	#	DIGIT ONE
+0x32	0x0032	#	DIGIT TWO
+0x33	0x0033	#	DIGIT THREE
+0x34	0x0034	#	DIGIT FOUR
+0x35	0x0035	#	DIGIT FIVE
+0x36	0x0036	#	DIGIT SIX
+0x37	0x0037	#	DIGIT SEVEN
+0x38	0x0038	#	DIGIT EIGHT
+0x39	0x0039	#	DIGIT NINE
+0x3A	0x003A	#	COLON
+0x3B	0x003B	#	SEMICOLON
+0x3C	0x003C	#	LESS-THAN SIGN
+0x3D	0x003D	#	EQUALS SIGN
+0x3E	0x003E	#	GREATER-THAN SIGN
+0x3F	0x003F	#	QUESTION MARK
+0x40	0x0040	#	COMMERCIAL AT
+0x41	0x0041	#	LATIN CAPITAL LETTER A
+0x42	0x0042	#	LATIN CAPITAL LETTER B
+0x43	0x0043	#	LATIN CAPITAL LETTER C
+0x44	0x0044	#	LATIN CAPITAL LETTER D
+0x45	0x0045	#	LATIN CAPITAL LETTER E
+0x46	0x0046	#	LATIN CAPITAL LETTER F
+0x47	0x0047	#	LATIN CAPITAL LETTER G
+0x48	0x0048	#	LATIN CAPITAL LETTER H
+0x49	0x0049	#	LATIN CAPITAL LETTER I
+0x4A	0x004A	#	LATIN CAPITAL LETTER J
+0x4B	0x004B	#	LATIN CAPITAL LETTER K
+0x4C	0x004C	#	LATIN CAPITAL LETTER L
+0x4D	0x004D	#	LATIN CAPITAL LETTER M
+0x4E	0x004E	#	LATIN CAPITAL LETTER N
+0x4F	0x004F	#	LATIN CAPITAL LETTER O
+0x50	0x0050	#	LATIN CAPITAL LETTER P
+0x51	0x0051	#	LATIN CAPITAL LETTER Q
+0x52	0x0052	#	LATIN CAPITAL LETTER R
+0x53	0x0053	#	LATIN CAPITAL LETTER S
+0x54	0x0054	#	LATIN CAPITAL LETTER T
+0x55	0x0055	#	LATIN CAPITAL LETTER U
+0x56	0x0056	#	LATIN CAPITAL LETTER V
+0x57	0x0057	#	LATIN CAPITAL LETTER W
+0x58	0x0058	#	LATIN CAPITAL LETTER X
+0x59	0x0059	#	LATIN CAPITAL LETTER Y
+0x5A	0x005A	#	LATIN CAPITAL LETTER Z
+0x5B	0x005B	#	LEFT SQUARE BRACKET
+0x5C	0x005C	#	REVERSE SOLIDUS
+0x5D	0x005D	#	RIGHT SQUARE BRACKET
+0x5E	0x005E	#	CIRCUMFLEX ACCENT
+0x5F	0x005F	#	LOW LINE
+0x60	0x0060	#	GRAVE ACCENT
+0x61	0x0061	#	LATIN SMALL LETTER A
+0x62	0x0062	#	LATIN SMALL LETTER B
+0x63	0x0063	#	LATIN SMALL LETTER C
+0x64	0x0064	#	LATIN SMALL LETTER D
+0x65	0x0065	#	LATIN SMALL LETTER E
+0x66	0x0066	#	LATIN SMALL LETTER F
+0x67	0x0067	#	LATIN SMALL LETTER G
+0x68	0x0068	#	LATIN SMALL LETTER H
+0x69	0x0069	#	LATIN SMALL LETTER I
+0x6A	0x006A	#	LATIN SMALL LETTER J
+0x6B	0x006B	#	LATIN SMALL LETTER K
+0x6C	0x006C	#	LATIN SMALL LETTER L
+0x6D	0x006D	#	LATIN SMALL LETTER M
+0x6E	0x006E	#	LATIN SMALL LETTER N
+0x6F	0x006F	#	LATIN SMALL LETTER O
+0x70	0x0070	#	LATIN SMALL LETTER P
+0x71	0x0071	#	LATIN SMALL LETTER Q
+0x72	0x0072	#	LATIN SMALL LETTER R
+0x73	0x0073	#	LATIN SMALL LETTER S
+0x74	0x0074	#	LATIN SMALL LETTER T
+0x75	0x0075	#	LATIN SMALL LETTER U
+0x76	0x0076	#	LATIN SMALL LETTER V
+0x77	0x0077	#	LATIN SMALL LETTER W
+0x78	0x0078	#	LATIN SMALL LETTER X
+0x79	0x0079	#	LATIN SMALL LETTER Y
+0x7A	0x007A	#	LATIN SMALL LETTER Z
+0x7B	0x007B	#	LEFT CURLY BRACKET
+0x7C	0x007C	#	VERTICAL LINE
+0x7D	0x007D	#	RIGHT CURLY BRACKET
+0x7E	0x007E	#	TILDE
+0x7F	0x007F	#	DELETE
+0x80	0x0080	#	<control>
+0x81	0x0081	#	<control>
+0x82	0x0082	#	<control>
+0x83	0x0083	#	<control>
+0x84	0x0084	#	<control>
+0x85	0x0085	#	<control>
+0x86	0x0086	#	<control>
+0x87	0x0087	#	<control>
+0x88	0x0088	#	<control>
+0x89	0x0089	#	<control>
+0x8A	0x008A	#	<control>
+0x8B	0x008B	#	<control>
+0x8C	0x008C	#	<control>
+0x8D	0x008D	#	<control>
+0x8E	0x008E	#	<control>
+0x8F	0x008F	#	<control>
+0x90	0x0090	#	<control>
+0x91	0x0091	#	<control>
+0x92	0x0092	#	<control>
+0x93	0x0093	#	<control>
+0x94	0x0094	#	<control>
+0x95	0x0095	#	<control>
+0x96	0x0096	#	<control>
+0x97	0x0097	#	<control>
+0x98	0x0098	#	<control>
+0x99	0x0099	#	<control>
+0x9A	0x009A	#	<control>
+0x9B	0x009B	#	<control>
+0x9C	0x009C	#	<control>
+0x9D	0x009D	#	<control>
+0x9E	0x009E	#	<control>
+0x9F	0x009F	#	<control>
+0xA0	0x00A0	#	NO-BREAK SPACE
+0xA1	0x201D	#	RIGHT DOUBLE QUOTATION MARK
+0xA2	0x00A2	#	CENT SIGN
+0xA3	0x00A3	#	POUND SIGN
+0xA4	0x00A4	#	CURRENCY SIGN
+0xA5	0x201E	#	DOUBLE LOW-9 QUOTATION MARK
+0xA6	0x00A6	#	BROKEN BAR
+0xA7	0x00A7	#	SECTION SIGN
+0xA8	0x00D8	#	LATIN CAPITAL LETTER O WITH STROKE
+0xA9	0x00A9	#	COPYRIGHT SIGN
+0xAA	0x0156	#	LATIN CAPITAL LETTER R WITH CEDILLA
+0xAB	0x00AB	#	LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+0xAC	0x00AC	#	NOT SIGN
+0xAD	0x00AD	#	SOFT HYPHEN
+0xAE	0x00AE	#	REGISTERED SIGN
+0xAF	0x00C6	#	LATIN CAPITAL LETTER AE
+0xB0	0x00B0	#	DEGREE SIGN
+0xB1	0x00B1	#	PLUS-MINUS SIGN
+0xB2	0x00B2	#	SUPERSCRIPT TWO
+0xB3	0x00B3	#	SUPERSCRIPT THREE
+0xB4	0x201C	#	LEFT DOUBLE QUOTATION MARK
+0xB5	0x00B5	#	MICRO SIGN
+0xB6	0x00B6	#	PILCROW SIGN
+0xB7	0x00B7	#	MIDDLE DOT
+0xB8	0x00F8	#	LATIN SMALL LETTER O WITH STROKE
+0xB9	0x00B9	#	SUPERSCRIPT ONE
+0xBA	0x0157	#	LATIN SMALL LETTER R WITH CEDILLA
+0xBB	0x00BB	#	RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+0xBC	0x00BC	#	VULGAR FRACTION ONE QUARTER
+0xBD	0x00BD	#	VULGAR FRACTION ONE HALF
+0xBE	0x00BE	#	VULGAR FRACTION THREE QUARTERS
+0xBF	0x00E6	#	LATIN SMALL LETTER AE
+0xC0	0x0104	#	LATIN CAPITAL LETTER A WITH OGONEK
+0xC1	0x012E	#	LATIN CAPITAL LETTER I WITH OGONEK
+0xC2	0x0100	#	LATIN CAPITAL LETTER A WITH MACRON
+0xC3	0x0106	#	LATIN CAPITAL LETTER C WITH ACUTE
+0xC4	0x00C4	#	LATIN CAPITAL LETTER A WITH DIAERESIS
+0xC5	0x00C5	#	LATIN CAPITAL LETTER A WITH RING ABOVE
+0xC6	0x0118	#	LATIN CAPITAL LETTER E WITH OGONEK
+0xC7	0x0112	#	LATIN CAPITAL LETTER E WITH MACRON
+0xC8	0x010C	#	LATIN CAPITAL LETTER C WITH CARON
+0xC9	0x00C9	#	LATIN CAPITAL LETTER E WITH ACUTE
+0xCA	0x0179	#	LATIN CAPITAL LETTER Z WITH ACUTE
+0xCB	0x0116	#	LATIN CAPITAL LETTER E WITH DOT ABOVE
+0xCC	0x0122	#	LATIN CAPITAL LETTER G WITH CEDILLA
+0xCD	0x0136	#	LATIN CAPITAL LETTER K WITH CEDILLA
+0xCE	0x012A	#	LATIN CAPITAL LETTER I WITH MACRON
+0xCF	0x013B	#	LATIN CAPITAL LETTER L WITH CEDILLA
+0xD0	0x0160	#	LATIN CAPITAL LETTER S WITH CARON
+0xD1	0x0143	#	LATIN CAPITAL LETTER N WITH ACUTE
+0xD2	0x0145	#	LATIN CAPITAL LETTER N WITH CEDILLA
+0xD3	0x00D3	#	LATIN CAPITAL LETTER O WITH ACUTE
+0xD4	0x014C	#	LATIN CAPITAL LETTER O WITH MACRON
+0xD5	0x00D5	#	LATIN CAPITAL LETTER O WITH TILDE
+0xD6	0x00D6	#	LATIN CAPITAL LETTER O WITH DIAERESIS
+0xD7	0x00D7	#	MULTIPLICATION SIGN
+0xD8	0x0172	#	LATIN CAPITAL LETTER U WITH OGONEK
+0xD9	0x0141	#	LATIN CAPITAL LETTER L WITH STROKE
+0xDA	0x015A	#	LATIN CAPITAL LETTER S WITH ACUTE
+0xDB	0x016A	#	LATIN CAPITAL LETTER U WITH MACRON
+0xDC	0x00DC	#	LATIN CAPITAL LETTER U WITH DIAERESIS
+0xDD	0x017B	#	LATIN CAPITAL LETTER Z WITH DOT ABOVE
+0xDE	0x017D	#	LATIN CAPITAL LETTER Z WITH CARON
+0xDF	0x00DF	#	LATIN SMALL LETTER SHARP S (German)
+0xE0	0x0105	#	LATIN SMALL LETTER A WITH OGONEK
+0xE1	0x012F	#	LATIN SMALL LETTER I WITH OGONEK
+0xE2	0x0101	#	LATIN SMALL LETTER A WITH MACRON
+0xE3	0x0107	#	LATIN SMALL LETTER C WITH ACUTE
+0xE4	0x00E4	#	LATIN SMALL LETTER A WITH DIAERESIS
+0xE5	0x00E5	#	LATIN SMALL LETTER A WITH RING ABOVE
+0xE6	0x0119	#	LATIN SMALL LETTER E WITH OGONEK
+0xE7	0x0113	#	LATIN SMALL LETTER E WITH MACRON
+0xE8	0x010D	#	LATIN SMALL LETTER C WITH CARON
+0xE9	0x00E9	#	LATIN SMALL LETTER E WITH ACUTE
+0xEA	0x017A	#	LATIN SMALL LETTER Z WITH ACUTE
+0xEB	0x0117	#	LATIN SMALL LETTER E WITH DOT ABOVE
+0xEC	0x0123	#	LATIN SMALL LETTER G WITH CEDILLA
+0xED	0x0137	#	LATIN SMALL LETTER K WITH CEDILLA
+0xEE	0x012B	#	LATIN SMALL LETTER I WITH MACRON
+0xEF	0x013C	#	LATIN SMALL LETTER L WITH CEDILLA
+0xF0	0x0161	#	LATIN SMALL LETTER S WITH CARON
+0xF1	0x0144	#	LATIN SMALL LETTER N WITH ACUTE
+0xF2	0x0146	#	LATIN SMALL LETTER N WITH CEDILLA
+0xF3	0x00F3	#	LATIN SMALL LETTER O WITH ACUTE
+0xF4	0x014D	#	LATIN SMALL LETTER O WITH MACRON
+0xF5	0x00F5	#	LATIN SMALL LETTER O WITH TILDE
+0xF6	0x00F6	#	LATIN SMALL LETTER O WITH DIAERESIS
+0xF7	0x00F7	#	DIVISION SIGN
+0xF8	0x0173	#	LATIN SMALL LETTER U WITH OGONEK
+0xF9	0x0142	#	LATIN SMALL LETTER L WITH STROKE
+0xFA	0x015B	#	LATIN SMALL LETTER S WITH ACUTE
+0xFB	0x016B	#	LATIN SMALL LETTER U WITH MACRON
+0xFC	0x00FC	#	LATIN SMALL LETTER U WITH DIAERESIS
+0xFD	0x017C	#	LATIN SMALL LETTER Z WITH DOT ABOVE
+0xFE	0x017E	#	LATIN SMALL LETTER Z WITH CARON
+0xFF	0x2019	#	RIGHT SINGLE QUOTATION MARK
diff --git a/tools/encoding/iso8859-14.txt b/tools/encoding/iso8859-14.txt
new file mode 100644
index 0000000..36038f4
--- /dev/null
+++ b/tools/encoding/iso8859-14.txt
@@ -0,0 +1,301 @@
+#
+#	Name:             ISO/IEC 8859-14:1998 to Unicode
+#	Unicode version:  3.0
+#	Table version:    1.0
+#	Table format:     Format A
+#	Date:             1999 July 27
+#	Authors:          Markus Kuhn <mkuhn@acm.org>
+#			  Ken Whistler <kenw@sybase.com>
+#
+#	Copyright (c) 1998 - 1999 Unicode, Inc.  All Rights reserved.
+#
+#	This file is provided as-is by Unicode, Inc. (The Unicode Consortium).
+#	No claims are made as to fitness for any particular purpose.  No
+#	warranties of any kind are expressed or implied.  The recipient
+#	agrees to determine applicability of information provided.  If this
+#	file has been provided on optical media by Unicode, Inc., the sole
+#	remedy for any claim will be exchange of defective media within 90
+#	days of receipt.
+#
+#	Unicode, Inc. hereby grants the right to freely use the information
+#	supplied in this file in the creation of products supporting the
+#	Unicode Standard, and to make copies of this file in any form for
+#	internal or external distribution as long as this notice remains
+#	attached.
+#
+#	General notes:
+#
+#	This table contains the data the Unicode Consortium has on how
+#       ISO/IEC 8859-14:1998 characters map into Unicode.
+#
+#	Format:  Three tab-separated columns
+#		 Column #1 is the ISO/IEC 8859-14 code (in hex as 0xXX)
+#		 Column #2 is the Unicode (in hex as 0xXXXX)
+#		 Column #3 the Unicode name (follows a comment sign, '#')
+#
+#	The entries are in ISO/IEC 8859-14 order.
+#
+#	Updated versions of this file may be found in:
+#		<ftp://ftp.unicode.org/Public/MAPPINGS/>
+#
+#	Any comments or problems, contact <errata@unicode.org>
+#	Please note that <errata@unicode.org> is an archival address;
+#	notices will be checked, but do not expect an immediate response.
+#
+0x00	0x0000	#	NULL
+0x01	0x0001	#	START OF HEADING
+0x02	0x0002	#	START OF TEXT
+0x03	0x0003	#	END OF TEXT
+0x04	0x0004	#	END OF TRANSMISSION
+0x05	0x0005	#	ENQUIRY
+0x06	0x0006	#	ACKNOWLEDGE
+0x07	0x0007	#	BELL
+0x08	0x0008	#	BACKSPACE
+0x09	0x0009	#	HORIZONTAL TABULATION
+0x0A	0x000A	#	LINE FEED
+0x0B	0x000B	#	VERTICAL TABULATION
+0x0C	0x000C	#	FORM FEED
+0x0D	0x000D	#	CARRIAGE RETURN
+0x0E	0x000E	#	SHIFT OUT
+0x0F	0x000F	#	SHIFT IN
+0x10	0x0010	#	DATA LINK ESCAPE
+0x11	0x0011	#	DEVICE CONTROL ONE
+0x12	0x0012	#	DEVICE CONTROL TWO
+0x13	0x0013	#	DEVICE CONTROL THREE
+0x14	0x0014	#	DEVICE CONTROL FOUR
+0x15	0x0015	#	NEGATIVE ACKNOWLEDGE
+0x16	0x0016	#	SYNCHRONOUS IDLE
+0x17	0x0017	#	END OF TRANSMISSION BLOCK
+0x18	0x0018	#	CANCEL
+0x19	0x0019	#	END OF MEDIUM
+0x1A	0x001A	#	SUBSTITUTE
+0x1B	0x001B	#	ESCAPE
+0x1C	0x001C	#	FILE SEPARATOR
+0x1D	0x001D	#	GROUP SEPARATOR
+0x1E	0x001E	#	RECORD SEPARATOR
+0x1F	0x001F	#	UNIT SEPARATOR
+0x20	0x0020	#	SPACE
+0x21	0x0021	#	EXCLAMATION MARK
+0x22	0x0022	#	QUOTATION MARK
+0x23	0x0023	#	NUMBER SIGN
+0x24	0x0024	#	DOLLAR SIGN
+0x25	0x0025	#	PERCENT SIGN
+0x26	0x0026	#	AMPERSAND
+0x27	0x0027	#	APOSTROPHE
+0x28	0x0028	#	LEFT PARENTHESIS
+0x29	0x0029	#	RIGHT PARENTHESIS
+0x2A	0x002A	#	ASTERISK
+0x2B	0x002B	#	PLUS SIGN
+0x2C	0x002C	#	COMMA
+0x2D	0x002D	#	HYPHEN-MINUS
+0x2E	0x002E	#	FULL STOP
+0x2F	0x002F	#	SOLIDUS
+0x30	0x0030	#	DIGIT ZERO
+0x31	0x0031	#	DIGIT ONE
+0x32	0x0032	#	DIGIT TWO
+0x33	0x0033	#	DIGIT THREE
+0x34	0x0034	#	DIGIT FOUR
+0x35	0x0035	#	DIGIT FIVE
+0x36	0x0036	#	DIGIT SIX
+0x37	0x0037	#	DIGIT SEVEN
+0x38	0x0038	#	DIGIT EIGHT
+0x39	0x0039	#	DIGIT NINE
+0x3A	0x003A	#	COLON
+0x3B	0x003B	#	SEMICOLON
+0x3C	0x003C	#	LESS-THAN SIGN
+0x3D	0x003D	#	EQUALS SIGN
+0x3E	0x003E	#	GREATER-THAN SIGN
+0x3F	0x003F	#	QUESTION MARK
+0x40	0x0040	#	COMMERCIAL AT
+0x41	0x0041	#	LATIN CAPITAL LETTER A
+0x42	0x0042	#	LATIN CAPITAL LETTER B
+0x43	0x0043	#	LATIN CAPITAL LETTER C
+0x44	0x0044	#	LATIN CAPITAL LETTER D
+0x45	0x0045	#	LATIN CAPITAL LETTER E
+0x46	0x0046	#	LATIN CAPITAL LETTER F
+0x47	0x0047	#	LATIN CAPITAL LETTER G
+0x48	0x0048	#	LATIN CAPITAL LETTER H
+0x49	0x0049	#	LATIN CAPITAL LETTER I
+0x4A	0x004A	#	LATIN CAPITAL LETTER J
+0x4B	0x004B	#	LATIN CAPITAL LETTER K
+0x4C	0x004C	#	LATIN CAPITAL LETTER L
+0x4D	0x004D	#	LATIN CAPITAL LETTER M
+0x4E	0x004E	#	LATIN CAPITAL LETTER N
+0x4F	0x004F	#	LATIN CAPITAL LETTER O
+0x50	0x0050	#	LATIN CAPITAL LETTER P
+0x51	0x0051	#	LATIN CAPITAL LETTER Q
+0x52	0x0052	#	LATIN CAPITAL LETTER R
+0x53	0x0053	#	LATIN CAPITAL LETTER S
+0x54	0x0054	#	LATIN CAPITAL LETTER T
+0x55	0x0055	#	LATIN CAPITAL LETTER U
+0x56	0x0056	#	LATIN CAPITAL LETTER V
+0x57	0x0057	#	LATIN CAPITAL LETTER W
+0x58	0x0058	#	LATIN CAPITAL LETTER X
+0x59	0x0059	#	LATIN CAPITAL LETTER Y
+0x5A	0x005A	#	LATIN CAPITAL LETTER Z
+0x5B	0x005B	#	LEFT SQUARE BRACKET
+0x5C	0x005C	#	REVERSE SOLIDUS
+0x5D	0x005D	#	RIGHT SQUARE BRACKET
+0x5E	0x005E	#	CIRCUMFLEX ACCENT
+0x5F	0x005F	#	LOW LINE
+0x60	0x0060	#	GRAVE ACCENT
+0x61	0x0061	#	LATIN SMALL LETTER A
+0x62	0x0062	#	LATIN SMALL LETTER B
+0x63	0x0063	#	LATIN SMALL LETTER C
+0x64	0x0064	#	LATIN SMALL LETTER D
+0x65	0x0065	#	LATIN SMALL LETTER E
+0x66	0x0066	#	LATIN SMALL LETTER F
+0x67	0x0067	#	LATIN SMALL LETTER G
+0x68	0x0068	#	LATIN SMALL LETTER H
+0x69	0x0069	#	LATIN SMALL LETTER I
+0x6A	0x006A	#	LATIN SMALL LETTER J
+0x6B	0x006B	#	LATIN SMALL LETTER K
+0x6C	0x006C	#	LATIN SMALL LETTER L
+0x6D	0x006D	#	LATIN SMALL LETTER M
+0x6E	0x006E	#	LATIN SMALL LETTER N
+0x6F	0x006F	#	LATIN SMALL LETTER O
+0x70	0x0070	#	LATIN SMALL LETTER P
+0x71	0x0071	#	LATIN SMALL LETTER Q
+0x72	0x0072	#	LATIN SMALL LETTER R
+0x73	0x0073	#	LATIN SMALL LETTER S
+0x74	0x0074	#	LATIN SMALL LETTER T
+0x75	0x0075	#	LATIN SMALL LETTER U
+0x76	0x0076	#	LATIN SMALL LETTER V
+0x77	0x0077	#	LATIN SMALL LETTER W
+0x78	0x0078	#	LATIN SMALL LETTER X
+0x79	0x0079	#	LATIN SMALL LETTER Y
+0x7A	0x007A	#	LATIN SMALL LETTER Z
+0x7B	0x007B	#	LEFT CURLY BRACKET
+0x7C	0x007C	#	VERTICAL LINE
+0x7D	0x007D	#	RIGHT CURLY BRACKET
+0x7E	0x007E	#	TILDE
+0x7F	0x007F	#	DELETE
+0x80	0x0080	#	<control>
+0x81	0x0081	#	<control>
+0x82	0x0082	#	<control>
+0x83	0x0083	#	<control>
+0x84	0x0084	#	<control>
+0x85	0x0085	#	<control>
+0x86	0x0086	#	<control>
+0x87	0x0087	#	<control>
+0x88	0x0088	#	<control>
+0x89	0x0089	#	<control>
+0x8A	0x008A	#	<control>
+0x8B	0x008B	#	<control>
+0x8C	0x008C	#	<control>
+0x8D	0x008D	#	<control>
+0x8E	0x008E	#	<control>
+0x8F	0x008F	#	<control>
+0x90	0x0090	#	<control>
+0x91	0x0091	#	<control>
+0x92	0x0092	#	<control>
+0x93	0x0093	#	<control>
+0x94	0x0094	#	<control>
+0x95	0x0095	#	<control>
+0x96	0x0096	#	<control>
+0x97	0x0097	#	<control>
+0x98	0x0098	#	<control>
+0x99	0x0099	#	<control>
+0x9A	0x009A	#	<control>
+0x9B	0x009B	#	<control>
+0x9C	0x009C	#	<control>
+0x9D	0x009D	#	<control>
+0x9E	0x009E	#	<control>
+0x9F	0x009F	#	<control>
+0xA0	0x00A0	#	NO-BREAK SPACE
+0xA1	0x1E02	#	LATIN CAPITAL LETTER B WITH DOT ABOVE
+0xA2	0x1E03	#	LATIN SMALL LETTER B WITH DOT ABOVE
+0xA3	0x00A3	#	POUND SIGN
+0xA4	0x010A	#	LATIN CAPITAL LETTER C WITH DOT ABOVE
+0xA5	0x010B	#	LATIN SMALL LETTER C WITH DOT ABOVE
+0xA6	0x1E0A	#	LATIN CAPITAL LETTER D WITH DOT ABOVE
+0xA7	0x00A7	#	SECTION SIGN
+0xA8	0x1E80	#	LATIN CAPITAL LETTER W WITH GRAVE
+0xA9	0x00A9	#	COPYRIGHT SIGN
+0xAA	0x1E82	#	LATIN CAPITAL LETTER W WITH ACUTE
+0xAB	0x1E0B	#	LATIN SMALL LETTER D WITH DOT ABOVE
+0xAC	0x1EF2	#	LATIN CAPITAL LETTER Y WITH GRAVE
+0xAD	0x00AD	#	SOFT HYPHEN
+0xAE	0x00AE	#	REGISTERED SIGN
+0xAF	0x0178	#	LATIN CAPITAL LETTER Y WITH DIAERESIS
+0xB0	0x1E1E	#	LATIN CAPITAL LETTER F WITH DOT ABOVE
+0xB1	0x1E1F	#	LATIN SMALL LETTER F WITH DOT ABOVE
+0xB2	0x0120	#	LATIN CAPITAL LETTER G WITH DOT ABOVE
+0xB3	0x0121	#	LATIN SMALL LETTER G WITH DOT ABOVE
+0xB4	0x1E40	#	LATIN CAPITAL LETTER M WITH DOT ABOVE
+0xB5	0x1E41	#	LATIN SMALL LETTER M WITH DOT ABOVE
+0xB6	0x00B6	#	PILCROW SIGN
+0xB7	0x1E56	#	LATIN CAPITAL LETTER P WITH DOT ABOVE
+0xB8	0x1E81	#	LATIN SMALL LETTER W WITH GRAVE
+0xB9	0x1E57	#	LATIN SMALL LETTER P WITH DOT ABOVE
+0xBA	0x1E83	#	LATIN SMALL LETTER W WITH ACUTE
+0xBB	0x1E60	#	LATIN CAPITAL LETTER S WITH DOT ABOVE
+0xBC	0x1EF3	#	LATIN SMALL LETTER Y WITH GRAVE
+0xBD	0x1E84	#	LATIN CAPITAL LETTER W WITH DIAERESIS
+0xBE	0x1E85	#	LATIN SMALL LETTER W WITH DIAERESIS
+0xBF	0x1E61	#	LATIN SMALL LETTER S WITH DOT ABOVE
+0xC0	0x00C0	#	LATIN CAPITAL LETTER A WITH GRAVE
+0xC1	0x00C1	#	LATIN CAPITAL LETTER A WITH ACUTE
+0xC2	0x00C2	#	LATIN CAPITAL LETTER A WITH CIRCUMFLEX
+0xC3	0x00C3	#	LATIN CAPITAL LETTER A WITH TILDE
+0xC4	0x00C4	#	LATIN CAPITAL LETTER A WITH DIAERESIS
+0xC5	0x00C5	#	LATIN CAPITAL LETTER A WITH RING ABOVE
+0xC6	0x00C6	#	LATIN CAPITAL LETTER AE
+0xC7	0x00C7	#	LATIN CAPITAL LETTER C WITH CEDILLA
+0xC8	0x00C8	#	LATIN CAPITAL LETTER E WITH GRAVE
+0xC9	0x00C9	#	LATIN CAPITAL LETTER E WITH ACUTE
+0xCA	0x00CA	#	LATIN CAPITAL LETTER E WITH CIRCUMFLEX
+0xCB	0x00CB	#	LATIN CAPITAL LETTER E WITH DIAERESIS
+0xCC	0x00CC	#	LATIN CAPITAL LETTER I WITH GRAVE
+0xCD	0x00CD	#	LATIN CAPITAL LETTER I WITH ACUTE
+0xCE	0x00CE	#	LATIN CAPITAL LETTER I WITH CIRCUMFLEX
+0xCF	0x00CF	#	LATIN CAPITAL LETTER I WITH DIAERESIS
+0xD0	0x0174	#	LATIN CAPITAL LETTER W WITH CIRCUMFLEX
+0xD1	0x00D1	#	LATIN CAPITAL LETTER N WITH TILDE
+0xD2	0x00D2	#	LATIN CAPITAL LETTER O WITH GRAVE
+0xD3	0x00D3	#	LATIN CAPITAL LETTER O WITH ACUTE
+0xD4	0x00D4	#	LATIN CAPITAL LETTER O WITH CIRCUMFLEX
+0xD5	0x00D5	#	LATIN CAPITAL LETTER O WITH TILDE
+0xD6	0x00D6	#	LATIN CAPITAL LETTER O WITH DIAERESIS
+0xD7	0x1E6A	#	LATIN CAPITAL LETTER T WITH DOT ABOVE
+0xD8	0x00D8	#	LATIN CAPITAL LETTER O WITH STROKE
+0xD9	0x00D9	#	LATIN CAPITAL LETTER U WITH GRAVE
+0xDA	0x00DA	#	LATIN CAPITAL LETTER U WITH ACUTE
+0xDB	0x00DB	#	LATIN CAPITAL LETTER U WITH CIRCUMFLEX
+0xDC	0x00DC	#	LATIN CAPITAL LETTER U WITH DIAERESIS
+0xDD	0x00DD	#	LATIN CAPITAL LETTER Y WITH ACUTE
+0xDE	0x0176	#	LATIN CAPITAL LETTER Y WITH CIRCUMFLEX
+0xDF	0x00DF	#	LATIN SMALL LETTER SHARP S
+0xE0	0x00E0	#	LATIN SMALL LETTER A WITH GRAVE
+0xE1	0x00E1	#	LATIN SMALL LETTER A WITH ACUTE
+0xE2	0x00E2	#	LATIN SMALL LETTER A WITH CIRCUMFLEX
+0xE3	0x00E3	#	LATIN SMALL LETTER A WITH TILDE
+0xE4	0x00E4	#	LATIN SMALL LETTER A WITH DIAERESIS
+0xE5	0x00E5	#	LATIN SMALL LETTER A WITH RING ABOVE
+0xE6	0x00E6	#	LATIN SMALL LETTER AE
+0xE7	0x00E7	#	LATIN SMALL LETTER C WITH CEDILLA
+0xE8	0x00E8	#	LATIN SMALL LETTER E WITH GRAVE
+0xE9	0x00E9	#	LATIN SMALL LETTER E WITH ACUTE
+0xEA	0x00EA	#	LATIN SMALL LETTER E WITH CIRCUMFLEX
+0xEB	0x00EB	#	LATIN SMALL LETTER E WITH DIAERESIS
+0xEC	0x00EC	#	LATIN SMALL LETTER I WITH GRAVE
+0xED	0x00ED	#	LATIN SMALL LETTER I WITH ACUTE
+0xEE	0x00EE	#	LATIN SMALL LETTER I WITH CIRCUMFLEX
+0xEF	0x00EF	#	LATIN SMALL LETTER I WITH DIAERESIS
+0xF0	0x0175	#	LATIN SMALL LETTER W WITH CIRCUMFLEX
+0xF1	0x00F1	#	LATIN SMALL LETTER N WITH TILDE
+0xF2	0x00F2	#	LATIN SMALL LETTER O WITH GRAVE
+0xF3	0x00F3	#	LATIN SMALL LETTER O WITH ACUTE
+0xF4	0x00F4	#	LATIN SMALL LETTER O WITH CIRCUMFLEX
+0xF5	0x00F5	#	LATIN SMALL LETTER O WITH TILDE
+0xF6	0x00F6	#	LATIN SMALL LETTER O WITH DIAERESIS
+0xF7	0x1E6B	#	LATIN SMALL LETTER T WITH DOT ABOVE
+0xF8	0x00F8	#	LATIN SMALL LETTER O WITH STROKE
+0xF9	0x00F9	#	LATIN SMALL LETTER U WITH GRAVE
+0xFA	0x00FA	#	LATIN SMALL LETTER U WITH ACUTE
+0xFB	0x00FB	#	LATIN SMALL LETTER U WITH CIRCUMFLEX
+0xFC	0x00FC	#	LATIN SMALL LETTER U WITH DIAERESIS
+0xFD	0x00FD	#	LATIN SMALL LETTER Y WITH ACUTE
+0xFE	0x0177	#	LATIN SMALL LETTER Y WITH CIRCUMFLEX
+0xFF	0x00FF	#	LATIN SMALL LETTER Y WITH DIAERESIS
+
diff --git a/tools/encoding/iso8859-15.txt b/tools/encoding/iso8859-15.txt
new file mode 100644
index 0000000..1e31970
--- /dev/null
+++ b/tools/encoding/iso8859-15.txt
@@ -0,0 +1,303 @@
+#
+#	Name:             ISO/IEC 8859-15:1999 to Unicode
+#	Unicode version:  3.0
+#	Table version:    1.0
+#	Table format:     Format A
+#	Date:             1999 July 27
+#	Authors:          Markus Kuhn <mkuhn@acm.org>
+#			  Ken Whistler <kenw@sybase.com>
+#
+#	Copyright (c) 1998 - 1999 Unicode, Inc.  All Rights reserved.
+#
+#	This file is provided as-is by Unicode, Inc. (The Unicode Consortium).
+#	No claims are made as to fitness for any particular purpose.  No
+#	warranties of any kind are expressed or implied.  The recipient
+#	agrees to determine applicability of information provided.  If this
+#	file has been provided on optical media by Unicode, Inc., the sole
+#	remedy for any claim will be exchange of defective media within 90
+#	days of receipt.
+#
+#	Unicode, Inc. hereby grants the right to freely use the information
+#	supplied in this file in the creation of products supporting the
+#	Unicode Standard, and to make copies of this file in any form for
+#	internal or external distribution as long as this notice remains
+#	attached.
+#
+#	General notes:
+#
+#	This table contains the data the Unicode Consortium has on how
+#       ISO/IEC 8859-15:1999 characters map into Unicode.
+#
+#	Format:  Three tab-separated columns
+#		 Column #1 is the ISO/IEC 8859-15 code (in hex as 0xXX)
+#		 Column #2 is the Unicode (in hex as 0xXXXX)
+#		 Column #3 the Unicode name (follows a comment sign, '#')
+#
+#	The entries are in ISO/IEC 8859-15 order.
+#
+#	Version history
+#
+#	Updated versions of this file may be found in:
+#		<ftp://ftp.unicode.org/Public/MAPPINGS/>
+#
+#	Any comments or problems, contact <errata@unicode.org>
+#	Please note that <errata@unicode.org> is an archival address;
+#	notices will be checked, but do not expect an immediate response.
+#
+0x00	0x0000	#	NULL
+0x01	0x0001	#	START OF HEADING
+0x02	0x0002	#	START OF TEXT
+0x03	0x0003	#	END OF TEXT
+0x04	0x0004	#	END OF TRANSMISSION
+0x05	0x0005	#	ENQUIRY
+0x06	0x0006	#	ACKNOWLEDGE
+0x07	0x0007	#	BELL
+0x08	0x0008	#	BACKSPACE
+0x09	0x0009	#	HORIZONTAL TABULATION
+0x0A	0x000A	#	LINE FEED
+0x0B	0x000B	#	VERTICAL TABULATION
+0x0C	0x000C	#	FORM FEED
+0x0D	0x000D	#	CARRIAGE RETURN
+0x0E	0x000E	#	SHIFT OUT
+0x0F	0x000F	#	SHIFT IN
+0x10	0x0010	#	DATA LINK ESCAPE
+0x11	0x0011	#	DEVICE CONTROL ONE
+0x12	0x0012	#	DEVICE CONTROL TWO
+0x13	0x0013	#	DEVICE CONTROL THREE
+0x14	0x0014	#	DEVICE CONTROL FOUR
+0x15	0x0015	#	NEGATIVE ACKNOWLEDGE
+0x16	0x0016	#	SYNCHRONOUS IDLE
+0x17	0x0017	#	END OF TRANSMISSION BLOCK
+0x18	0x0018	#	CANCEL
+0x19	0x0019	#	END OF MEDIUM
+0x1A	0x001A	#	SUBSTITUTE
+0x1B	0x001B	#	ESCAPE
+0x1C	0x001C	#	FILE SEPARATOR
+0x1D	0x001D	#	GROUP SEPARATOR
+0x1E	0x001E	#	RECORD SEPARATOR
+0x1F	0x001F	#	UNIT SEPARATOR
+0x20	0x0020	#	SPACE
+0x21	0x0021	#	EXCLAMATION MARK
+0x22	0x0022	#	QUOTATION MARK
+0x23	0x0023	#	NUMBER SIGN
+0x24	0x0024	#	DOLLAR SIGN
+0x25	0x0025	#	PERCENT SIGN
+0x26	0x0026	#	AMPERSAND
+0x27	0x0027	#	APOSTROPHE
+0x28	0x0028	#	LEFT PARENTHESIS
+0x29	0x0029	#	RIGHT PARENTHESIS
+0x2A	0x002A	#	ASTERISK
+0x2B	0x002B	#	PLUS SIGN
+0x2C	0x002C	#	COMMA
+0x2D	0x002D	#	HYPHEN-MINUS
+0x2E	0x002E	#	FULL STOP
+0x2F	0x002F	#	SOLIDUS
+0x30	0x0030	#	DIGIT ZERO
+0x31	0x0031	#	DIGIT ONE
+0x32	0x0032	#	DIGIT TWO
+0x33	0x0033	#	DIGIT THREE
+0x34	0x0034	#	DIGIT FOUR
+0x35	0x0035	#	DIGIT FIVE
+0x36	0x0036	#	DIGIT SIX
+0x37	0x0037	#	DIGIT SEVEN
+0x38	0x0038	#	DIGIT EIGHT
+0x39	0x0039	#	DIGIT NINE
+0x3A	0x003A	#	COLON
+0x3B	0x003B	#	SEMICOLON
+0x3C	0x003C	#	LESS-THAN SIGN
+0x3D	0x003D	#	EQUALS SIGN
+0x3E	0x003E	#	GREATER-THAN SIGN
+0x3F	0x003F	#	QUESTION MARK
+0x40	0x0040	#	COMMERCIAL AT
+0x41	0x0041	#	LATIN CAPITAL LETTER A
+0x42	0x0042	#	LATIN CAPITAL LETTER B
+0x43	0x0043	#	LATIN CAPITAL LETTER C
+0x44	0x0044	#	LATIN CAPITAL LETTER D
+0x45	0x0045	#	LATIN CAPITAL LETTER E
+0x46	0x0046	#	LATIN CAPITAL LETTER F
+0x47	0x0047	#	LATIN CAPITAL LETTER G
+0x48	0x0048	#	LATIN CAPITAL LETTER H
+0x49	0x0049	#	LATIN CAPITAL LETTER I
+0x4A	0x004A	#	LATIN CAPITAL LETTER J
+0x4B	0x004B	#	LATIN CAPITAL LETTER K
+0x4C	0x004C	#	LATIN CAPITAL LETTER L
+0x4D	0x004D	#	LATIN CAPITAL LETTER M
+0x4E	0x004E	#	LATIN CAPITAL LETTER N
+0x4F	0x004F	#	LATIN CAPITAL LETTER O
+0x50	0x0050	#	LATIN CAPITAL LETTER P
+0x51	0x0051	#	LATIN CAPITAL LETTER Q
+0x52	0x0052	#	LATIN CAPITAL LETTER R
+0x53	0x0053	#	LATIN CAPITAL LETTER S
+0x54	0x0054	#	LATIN CAPITAL LETTER T
+0x55	0x0055	#	LATIN CAPITAL LETTER U
+0x56	0x0056	#	LATIN CAPITAL LETTER V
+0x57	0x0057	#	LATIN CAPITAL LETTER W
+0x58	0x0058	#	LATIN CAPITAL LETTER X
+0x59	0x0059	#	LATIN CAPITAL LETTER Y
+0x5A	0x005A	#	LATIN CAPITAL LETTER Z
+0x5B	0x005B	#	LEFT SQUARE BRACKET
+0x5C	0x005C	#	REVERSE SOLIDUS
+0x5D	0x005D	#	RIGHT SQUARE BRACKET
+0x5E	0x005E	#	CIRCUMFLEX ACCENT
+0x5F	0x005F	#	LOW LINE
+0x60	0x0060	#	GRAVE ACCENT
+0x61	0x0061	#	LATIN SMALL LETTER A
+0x62	0x0062	#	LATIN SMALL LETTER B
+0x63	0x0063	#	LATIN SMALL LETTER C
+0x64	0x0064	#	LATIN SMALL LETTER D
+0x65	0x0065	#	LATIN SMALL LETTER E
+0x66	0x0066	#	LATIN SMALL LETTER F
+0x67	0x0067	#	LATIN SMALL LETTER G
+0x68	0x0068	#	LATIN SMALL LETTER H
+0x69	0x0069	#	LATIN SMALL LETTER I
+0x6A	0x006A	#	LATIN SMALL LETTER J
+0x6B	0x006B	#	LATIN SMALL LETTER K
+0x6C	0x006C	#	LATIN SMALL LETTER L
+0x6D	0x006D	#	LATIN SMALL LETTER M
+0x6E	0x006E	#	LATIN SMALL LETTER N
+0x6F	0x006F	#	LATIN SMALL LETTER O
+0x70	0x0070	#	LATIN SMALL LETTER P
+0x71	0x0071	#	LATIN SMALL LETTER Q
+0x72	0x0072	#	LATIN SMALL LETTER R
+0x73	0x0073	#	LATIN SMALL LETTER S
+0x74	0x0074	#	LATIN SMALL LETTER T
+0x75	0x0075	#	LATIN SMALL LETTER U
+0x76	0x0076	#	LATIN SMALL LETTER V
+0x77	0x0077	#	LATIN SMALL LETTER W
+0x78	0x0078	#	LATIN SMALL LETTER X
+0x79	0x0079	#	LATIN SMALL LETTER Y
+0x7A	0x007A	#	LATIN SMALL LETTER Z
+0x7B	0x007B	#	LEFT CURLY BRACKET
+0x7C	0x007C	#	VERTICAL LINE
+0x7D	0x007D	#	RIGHT CURLY BRACKET
+0x7E	0x007E	#	TILDE
+0x7F	0x007F	#	DELETE
+0x80	0x0080	#	<control>
+0x81	0x0081	#	<control>
+0x82	0x0082	#	<control>
+0x83	0x0083	#	<control>
+0x84	0x0084	#	<control>
+0x85	0x0085	#	<control>
+0x86	0x0086	#	<control>
+0x87	0x0087	#	<control>
+0x88	0x0088	#	<control>
+0x89	0x0089	#	<control>
+0x8A	0x008A	#	<control>
+0x8B	0x008B	#	<control>
+0x8C	0x008C	#	<control>
+0x8D	0x008D	#	<control>
+0x8E	0x008E	#	<control>
+0x8F	0x008F	#	<control>
+0x90	0x0090	#	<control>
+0x91	0x0091	#	<control>
+0x92	0x0092	#	<control>
+0x93	0x0093	#	<control>
+0x94	0x0094	#	<control>
+0x95	0x0095	#	<control>
+0x96	0x0096	#	<control>
+0x97	0x0097	#	<control>
+0x98	0x0098	#	<control>
+0x99	0x0099	#	<control>
+0x9A	0x009A	#	<control>
+0x9B	0x009B	#	<control>
+0x9C	0x009C	#	<control>
+0x9D	0x009D	#	<control>
+0x9E	0x009E	#	<control>
+0x9F	0x009F	#	<control>
+0xA0	0x00A0	#	NO-BREAK SPACE
+0xA1	0x00A1	#	INVERTED EXCLAMATION MARK
+0xA2	0x00A2	#	CENT SIGN
+0xA3	0x00A3	#	POUND SIGN
+0xA4	0x20AC	#	EURO SIGN
+0xA5	0x00A5	#	YEN SIGN
+0xA6	0x0160	#	LATIN CAPITAL LETTER S WITH CARON
+0xA7	0x00A7	#	SECTION SIGN
+0xA8	0x0161	#	LATIN SMALL LETTER S WITH CARON
+0xA9	0x00A9	#	COPYRIGHT SIGN
+0xAA	0x00AA	#	FEMININE ORDINAL INDICATOR
+0xAB	0x00AB	#	LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+0xAC	0x00AC	#	NOT SIGN
+0xAD	0x00AD	#	SOFT HYPHEN
+0xAE	0x00AE	#	REGISTERED SIGN
+0xAF	0x00AF	#	MACRON
+0xB0	0x00B0	#	DEGREE SIGN
+0xB1	0x00B1	#	PLUS-MINUS SIGN
+0xB2	0x00B2	#	SUPERSCRIPT TWO
+0xB3	0x00B3	#	SUPERSCRIPT THREE
+0xB4	0x017D	#	LATIN CAPITAL LETTER Z WITH CARON
+0xB5	0x00B5	#	MICRO SIGN
+0xB6	0x00B6	#	PILCROW SIGN
+0xB7	0x00B7	#	MIDDLE DOT
+0xB8	0x017E	#	LATIN SMALL LETTER Z WITH CARON
+0xB9	0x00B9	#	SUPERSCRIPT ONE
+0xBA	0x00BA	#	MASCULINE ORDINAL INDICATOR
+0xBB	0x00BB	#	RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+0xBC	0x0152	#	LATIN CAPITAL LIGATURE OE
+0xBD	0x0153	#	LATIN SMALL LIGATURE OE
+0xBE	0x0178	#	LATIN CAPITAL LETTER Y WITH DIAERESIS
+0xBF	0x00BF	#	INVERTED QUESTION MARK
+0xC0	0x00C0	#	LATIN CAPITAL LETTER A WITH GRAVE
+0xC1	0x00C1	#	LATIN CAPITAL LETTER A WITH ACUTE
+0xC2	0x00C2	#	LATIN CAPITAL LETTER A WITH CIRCUMFLEX
+0xC3	0x00C3	#	LATIN CAPITAL LETTER A WITH TILDE
+0xC4	0x00C4	#	LATIN CAPITAL LETTER A WITH DIAERESIS
+0xC5	0x00C5	#	LATIN CAPITAL LETTER A WITH RING ABOVE
+0xC6	0x00C6	#	LATIN CAPITAL LETTER AE
+0xC7	0x00C7	#	LATIN CAPITAL LETTER C WITH CEDILLA
+0xC8	0x00C8	#	LATIN CAPITAL LETTER E WITH GRAVE
+0xC9	0x00C9	#	LATIN CAPITAL LETTER E WITH ACUTE
+0xCA	0x00CA	#	LATIN CAPITAL LETTER E WITH CIRCUMFLEX
+0xCB	0x00CB	#	LATIN CAPITAL LETTER E WITH DIAERESIS
+0xCC	0x00CC	#	LATIN CAPITAL LETTER I WITH GRAVE
+0xCD	0x00CD	#	LATIN CAPITAL LETTER I WITH ACUTE
+0xCE	0x00CE	#	LATIN CAPITAL LETTER I WITH CIRCUMFLEX
+0xCF	0x00CF	#	LATIN CAPITAL LETTER I WITH DIAERESIS
+0xD0	0x00D0	#	LATIN CAPITAL LETTER ETH
+0xD1	0x00D1	#	LATIN CAPITAL LETTER N WITH TILDE
+0xD2	0x00D2	#	LATIN CAPITAL LETTER O WITH GRAVE
+0xD3	0x00D3	#	LATIN CAPITAL LETTER O WITH ACUTE
+0xD4	0x00D4	#	LATIN CAPITAL LETTER O WITH CIRCUMFLEX
+0xD5	0x00D5	#	LATIN CAPITAL LETTER O WITH TILDE
+0xD6	0x00D6	#	LATIN CAPITAL LETTER O WITH DIAERESIS
+0xD7	0x00D7	#	MULTIPLICATION SIGN
+0xD8	0x00D8	#	LATIN CAPITAL LETTER O WITH STROKE
+0xD9	0x00D9	#	LATIN CAPITAL LETTER U WITH GRAVE
+0xDA	0x00DA	#	LATIN CAPITAL LETTER U WITH ACUTE
+0xDB	0x00DB	#	LATIN CAPITAL LETTER U WITH CIRCUMFLEX
+0xDC	0x00DC	#	LATIN CAPITAL LETTER U WITH DIAERESIS
+0xDD	0x00DD	#	LATIN CAPITAL LETTER Y WITH ACUTE
+0xDE	0x00DE	#	LATIN CAPITAL LETTER THORN
+0xDF	0x00DF	#	LATIN SMALL LETTER SHARP S
+0xE0	0x00E0	#	LATIN SMALL LETTER A WITH GRAVE
+0xE1	0x00E1	#	LATIN SMALL LETTER A WITH ACUTE
+0xE2	0x00E2	#	LATIN SMALL LETTER A WITH CIRCUMFLEX
+0xE3	0x00E3	#	LATIN SMALL LETTER A WITH TILDE
+0xE4	0x00E4	#	LATIN SMALL LETTER A WITH DIAERESIS
+0xE5	0x00E5	#	LATIN SMALL LETTER A WITH RING ABOVE
+0xE6	0x00E6	#	LATIN SMALL LETTER AE
+0xE7	0x00E7	#	LATIN SMALL LETTER C WITH CEDILLA
+0xE8	0x00E8	#	LATIN SMALL LETTER E WITH GRAVE
+0xE9	0x00E9	#	LATIN SMALL LETTER E WITH ACUTE
+0xEA	0x00EA	#	LATIN SMALL LETTER E WITH CIRCUMFLEX
+0xEB	0x00EB	#	LATIN SMALL LETTER E WITH DIAERESIS
+0xEC	0x00EC	#	LATIN SMALL LETTER I WITH GRAVE
+0xED	0x00ED	#	LATIN SMALL LETTER I WITH ACUTE
+0xEE	0x00EE	#	LATIN SMALL LETTER I WITH CIRCUMFLEX
+0xEF	0x00EF	#	LATIN SMALL LETTER I WITH DIAERESIS
+0xF0	0x00F0	#	LATIN SMALL LETTER ETH
+0xF1	0x00F1	#	LATIN SMALL LETTER N WITH TILDE
+0xF2	0x00F2	#	LATIN SMALL LETTER O WITH GRAVE
+0xF3	0x00F3	#	LATIN SMALL LETTER O WITH ACUTE
+0xF4	0x00F4	#	LATIN SMALL LETTER O WITH CIRCUMFLEX
+0xF5	0x00F5	#	LATIN SMALL LETTER O WITH TILDE
+0xF6	0x00F6	#	LATIN SMALL LETTER O WITH DIAERESIS
+0xF7	0x00F7	#	DIVISION SIGN
+0xF8	0x00F8	#	LATIN SMALL LETTER O WITH STROKE
+0xF9	0x00F9	#	LATIN SMALL LETTER U WITH GRAVE
+0xFA	0x00FA	#	LATIN SMALL LETTER U WITH ACUTE
+0xFB	0x00FB	#	LATIN SMALL LETTER U WITH CIRCUMFLEX
+0xFC	0x00FC	#	LATIN SMALL LETTER U WITH DIAERESIS
+0xFD	0x00FD	#	LATIN SMALL LETTER Y WITH ACUTE
+0xFE	0x00FE	#	LATIN SMALL LETTER THORN
+0xFF	0x00FF	#	LATIN SMALL LETTER Y WITH DIAERESIS
+
diff --git a/tools/encoding/iso8859-16.txt b/tools/encoding/iso8859-16.txt
new file mode 100644
index 0000000..5353d74
--- /dev/null
+++ b/tools/encoding/iso8859-16.txt
@@ -0,0 +1,299 @@
+#
+#	Name:             ISO/IEC 8859-16:2001 to Unicode
+#	Unicode version:  3.0
+#	Table version:    1.0
+#	Table format:     Format A
+#	Date:             2001 July 26
+#	Authors:          Markus Kuhn <mkuhn@acm.org>
+#
+#	Copyright (c) 1999-2001 Unicode, Inc.  All Rights reserved.
+#
+#	This file is provided as-is by Unicode, Inc. (The Unicode Consortium).
+#	No claims are made as to fitness for any particular purpose.  No
+#	warranties of any kind are expressed or implied.  The recipient
+#	agrees to determine applicability of information provided.  If this
+#	file has been provided on optical media by Unicode, Inc., the sole
+#	remedy for any claim will be exchange of defective media within 90
+#	days of receipt.
+#
+#	Unicode, Inc. hereby grants the right to freely use the information
+#	supplied in this file in the creation of products supporting the
+#	Unicode Standard, and to make copies of this file in any form for
+#	internal or external distribution as long as this notice remains
+#	attached.
+#
+#	General notes:
+#
+#	This table contains the data the Unicode Consortium has on how
+#       ISO/IEC 8859-16:2001 characters map into Unicode.
+#
+#	Format:  Three tab-separated columns
+#		 Column #1 is the ISO/IEC 8859-16 code (in hex as 0xXX)
+#		 Column #2 is the Unicode (in hex as 0xXXXX)
+#		 Column #3 the Unicode name (follows a comment sign, '#')
+#
+#	The entries are in ISO/IEC 8859-16 order.
+#
+#	Updated versions of this file may be found in:
+#		<ftp://ftp.unicode.org/Public/MAPPINGS/>
+#
+#	Any comments or problems, contact <errata@unicode.org>
+#	Please note that <errata@unicode.org> is an archival address;
+#	notices will be checked, but do not expect an immediate response.
+#
+0x00	0x0000	#	NULL
+0x01	0x0001	#	START OF HEADING
+0x02	0x0002	#	START OF TEXT
+0x03	0x0003	#	END OF TEXT
+0x04	0x0004	#	END OF TRANSMISSION
+0x05	0x0005	#	ENQUIRY
+0x06	0x0006	#	ACKNOWLEDGE
+0x07	0x0007	#	BELL
+0x08	0x0008	#	BACKSPACE
+0x09	0x0009	#	HORIZONTAL TABULATION
+0x0A	0x000A	#	LINE FEED
+0x0B	0x000B	#	VERTICAL TABULATION
+0x0C	0x000C	#	FORM FEED
+0x0D	0x000D	#	CARRIAGE RETURN
+0x0E	0x000E	#	SHIFT OUT
+0x0F	0x000F	#	SHIFT IN
+0x10	0x0010	#	DATA LINK ESCAPE
+0x11	0x0011	#	DEVICE CONTROL ONE
+0x12	0x0012	#	DEVICE CONTROL TWO
+0x13	0x0013	#	DEVICE CONTROL THREE
+0x14	0x0014	#	DEVICE CONTROL FOUR
+0x15	0x0015	#	NEGATIVE ACKNOWLEDGE
+0x16	0x0016	#	SYNCHRONOUS IDLE
+0x17	0x0017	#	END OF TRANSMISSION BLOCK
+0x18	0x0018	#	CANCEL
+0x19	0x0019	#	END OF MEDIUM
+0x1A	0x001A	#	SUBSTITUTE
+0x1B	0x001B	#	ESCAPE
+0x1C	0x001C	#	FILE SEPARATOR
+0x1D	0x001D	#	GROUP SEPARATOR
+0x1E	0x001E	#	RECORD SEPARATOR
+0x1F	0x001F	#	UNIT SEPARATOR
+0x20	0x0020	#	SPACE
+0x21	0x0021	#	EXCLAMATION MARK
+0x22	0x0022	#	QUOTATION MARK
+0x23	0x0023	#	NUMBER SIGN
+0x24	0x0024	#	DOLLAR SIGN
+0x25	0x0025	#	PERCENT SIGN
+0x26	0x0026	#	AMPERSAND
+0x27	0x0027	#	APOSTROPHE
+0x28	0x0028	#	LEFT PARENTHESIS
+0x29	0x0029	#	RIGHT PARENTHESIS
+0x2A	0x002A	#	ASTERISK
+0x2B	0x002B	#	PLUS SIGN
+0x2C	0x002C	#	COMMA
+0x2D	0x002D	#	HYPHEN-MINUS
+0x2E	0x002E	#	FULL STOP
+0x2F	0x002F	#	SOLIDUS
+0x30	0x0030	#	DIGIT ZERO
+0x31	0x0031	#	DIGIT ONE
+0x32	0x0032	#	DIGIT TWO
+0x33	0x0033	#	DIGIT THREE
+0x34	0x0034	#	DIGIT FOUR
+0x35	0x0035	#	DIGIT FIVE
+0x36	0x0036	#	DIGIT SIX
+0x37	0x0037	#	DIGIT SEVEN
+0x38	0x0038	#	DIGIT EIGHT
+0x39	0x0039	#	DIGIT NINE
+0x3A	0x003A	#	COLON
+0x3B	0x003B	#	SEMICOLON
+0x3C	0x003C	#	LESS-THAN SIGN
+0x3D	0x003D	#	EQUALS SIGN
+0x3E	0x003E	#	GREATER-THAN SIGN
+0x3F	0x003F	#	QUESTION MARK
+0x40	0x0040	#	COMMERCIAL AT
+0x41	0x0041	#	LATIN CAPITAL LETTER A
+0x42	0x0042	#	LATIN CAPITAL LETTER B
+0x43	0x0043	#	LATIN CAPITAL LETTER C
+0x44	0x0044	#	LATIN CAPITAL LETTER D
+0x45	0x0045	#	LATIN CAPITAL LETTER E
+0x46	0x0046	#	LATIN CAPITAL LETTER F
+0x47	0x0047	#	LATIN CAPITAL LETTER G
+0x48	0x0048	#	LATIN CAPITAL LETTER H
+0x49	0x0049	#	LATIN CAPITAL LETTER I
+0x4A	0x004A	#	LATIN CAPITAL LETTER J
+0x4B	0x004B	#	LATIN CAPITAL LETTER K
+0x4C	0x004C	#	LATIN CAPITAL LETTER L
+0x4D	0x004D	#	LATIN CAPITAL LETTER M
+0x4E	0x004E	#	LATIN CAPITAL LETTER N
+0x4F	0x004F	#	LATIN CAPITAL LETTER O
+0x50	0x0050	#	LATIN CAPITAL LETTER P
+0x51	0x0051	#	LATIN CAPITAL LETTER Q
+0x52	0x0052	#	LATIN CAPITAL LETTER R
+0x53	0x0053	#	LATIN CAPITAL LETTER S
+0x54	0x0054	#	LATIN CAPITAL LETTER T
+0x55	0x0055	#	LATIN CAPITAL LETTER U
+0x56	0x0056	#	LATIN CAPITAL LETTER V
+0x57	0x0057	#	LATIN CAPITAL LETTER W
+0x58	0x0058	#	LATIN CAPITAL LETTER X
+0x59	0x0059	#	LATIN CAPITAL LETTER Y
+0x5A	0x005A	#	LATIN CAPITAL LETTER Z
+0x5B	0x005B	#	LEFT SQUARE BRACKET
+0x5C	0x005C	#	REVERSE SOLIDUS
+0x5D	0x005D	#	RIGHT SQUARE BRACKET
+0x5E	0x005E	#	CIRCUMFLEX ACCENT
+0x5F	0x005F	#	LOW LINE
+0x60	0x0060	#	GRAVE ACCENT
+0x61	0x0061	#	LATIN SMALL LETTER A
+0x62	0x0062	#	LATIN SMALL LETTER B
+0x63	0x0063	#	LATIN SMALL LETTER C
+0x64	0x0064	#	LATIN SMALL LETTER D
+0x65	0x0065	#	LATIN SMALL LETTER E
+0x66	0x0066	#	LATIN SMALL LETTER F
+0x67	0x0067	#	LATIN SMALL LETTER G
+0x68	0x0068	#	LATIN SMALL LETTER H
+0x69	0x0069	#	LATIN SMALL LETTER I
+0x6A	0x006A	#	LATIN SMALL LETTER J
+0x6B	0x006B	#	LATIN SMALL LETTER K
+0x6C	0x006C	#	LATIN SMALL LETTER L
+0x6D	0x006D	#	LATIN SMALL LETTER M
+0x6E	0x006E	#	LATIN SMALL LETTER N
+0x6F	0x006F	#	LATIN SMALL LETTER O
+0x70	0x0070	#	LATIN SMALL LETTER P
+0x71	0x0071	#	LATIN SMALL LETTER Q
+0x72	0x0072	#	LATIN SMALL LETTER R
+0x73	0x0073	#	LATIN SMALL LETTER S
+0x74	0x0074	#	LATIN SMALL LETTER T
+0x75	0x0075	#	LATIN SMALL LETTER U
+0x76	0x0076	#	LATIN SMALL LETTER V
+0x77	0x0077	#	LATIN SMALL LETTER W
+0x78	0x0078	#	LATIN SMALL LETTER X
+0x79	0x0079	#	LATIN SMALL LETTER Y
+0x7A	0x007A	#	LATIN SMALL LETTER Z
+0x7B	0x007B	#	LEFT CURLY BRACKET
+0x7C	0x007C	#	VERTICAL LINE
+0x7D	0x007D	#	RIGHT CURLY BRACKET
+0x7E	0x007E	#	TILDE
+0x7F	0x007F	#	DELETE
+0x80	0x0080	#	<control>
+0x81	0x0081	#	<control>
+0x82	0x0082	#	<control>
+0x83	0x0083	#	<control>
+0x84	0x0084	#	<control>
+0x85	0x0085	#	<control>
+0x86	0x0086	#	<control>
+0x87	0x0087	#	<control>
+0x88	0x0088	#	<control>
+0x89	0x0089	#	<control>
+0x8A	0x008A	#	<control>
+0x8B	0x008B	#	<control>
+0x8C	0x008C	#	<control>
+0x8D	0x008D	#	<control>
+0x8E	0x008E	#	<control>
+0x8F	0x008F	#	<control>
+0x90	0x0090	#	<control>
+0x91	0x0091	#	<control>
+0x92	0x0092	#	<control>
+0x93	0x0093	#	<control>
+0x94	0x0094	#	<control>
+0x95	0x0095	#	<control>
+0x96	0x0096	#	<control>
+0x97	0x0097	#	<control>
+0x98	0x0098	#	<control>
+0x99	0x0099	#	<control>
+0x9A	0x009A	#	<control>
+0x9B	0x009B	#	<control>
+0x9C	0x009C	#	<control>
+0x9D	0x009D	#	<control>
+0x9E	0x009E	#	<control>
+0x9F	0x009F	#	<control>
+0xA0	0x00A0	#	NO-BREAK SPACE
+0xA1	0x0104	#	LATIN CAPITAL LETTER A WITH OGONEK
+0xA2	0x0105	#	LATIN SMALL LETTER A WITH OGONEK
+0xA3	0x0141	#	LATIN CAPITAL LETTER L WITH STROKE
+0xA4	0x20AC	#	EURO SIGN
+0xA5	0x201E	#	DOUBLE LOW-9 QUOTATION MARK
+0xA6	0x0160	#	LATIN CAPITAL LETTER S WITH CARON
+0xA7	0x00A7	#	SECTION SIGN
+0xA8	0x0161	#	LATIN SMALL LETTER S WITH CARON
+0xA9	0x00A9	#	COPYRIGHT SIGN
+0xAA	0x0218	#	LATIN CAPITAL LETTER S WITH COMMA BELOW
+0xAB	0x00AB	#	LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+0xAC	0x0179	#	LATIN CAPITAL LETTER Z WITH ACUTE
+0xAD	0x00AD	#	SOFT HYPHEN
+0xAE	0x017A	#	LATIN SMALL LETTER Z WITH ACUTE
+0xAF	0x017B	#	LATIN CAPITAL LETTER Z WITH DOT ABOVE
+0xB0	0x00B0	#	DEGREE SIGN
+0xB1	0x00B1	#	PLUS-MINUS SIGN
+0xB2	0x010C	#	LATIN CAPITAL LETTER C WITH CARON
+0xB3	0x0142	#	LATIN SMALL LETTER L WITH STROKE
+0xB4	0x017D	#	LATIN CAPITAL LETTER Z WITH CARON
+0xB5	0x201D	#	RIGHT DOUBLE QUOTATION MARK
+0xB6	0x00B6	#	PILCROW SIGN
+0xB7	0x00B7	#	MIDDLE DOT
+0xB8	0x017E	#	LATIN SMALL LETTER Z WITH CARON
+0xB9	0x010D	#	LATIN SMALL LETTER C WITH CARON
+0xBA	0x0219	#	LATIN SMALL LETTER S WITH COMMA BELOW
+0xBB	0x00BB	#	RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+0xBC	0x0152	#	LATIN CAPITAL LIGATURE OE
+0xBD	0x0153	#	LATIN SMALL LIGATURE OE
+0xBE	0x0178	#	LATIN CAPITAL LETTER Y WITH DIAERESIS
+0xBF	0x017C	#	LATIN SMALL LETTER Z WITH DOT ABOVE
+0xC0	0x00C0	#	LATIN CAPITAL LETTER A WITH GRAVE
+0xC1	0x00C1	#	LATIN CAPITAL LETTER A WITH ACUTE
+0xC2	0x00C2	#	LATIN CAPITAL LETTER A WITH CIRCUMFLEX
+0xC3	0x0102	#	LATIN CAPITAL LETTER A WITH BREVE
+0xC4	0x00C4	#	LATIN CAPITAL LETTER A WITH DIAERESIS
+0xC5	0x0106	#	LATIN CAPITAL LETTER C WITH ACUTE
+0xC6	0x00C6	#	LATIN CAPITAL LETTER AE
+0xC7	0x00C7	#	LATIN CAPITAL LETTER C WITH CEDILLA
+0xC8	0x00C8	#	LATIN CAPITAL LETTER E WITH GRAVE
+0xC9	0x00C9	#	LATIN CAPITAL LETTER E WITH ACUTE
+0xCA	0x00CA	#	LATIN CAPITAL LETTER E WITH CIRCUMFLEX
+0xCB	0x00CB	#	LATIN CAPITAL LETTER E WITH DIAERESIS
+0xCC	0x00CC	#	LATIN CAPITAL LETTER I WITH GRAVE
+0xCD	0x00CD	#	LATIN CAPITAL LETTER I WITH ACUTE
+0xCE	0x00CE	#	LATIN CAPITAL LETTER I WITH CIRCUMFLEX
+0xCF	0x00CF	#	LATIN CAPITAL LETTER I WITH DIAERESIS
+0xD0	0x0110	#	LATIN CAPITAL LETTER D WITH STROKE
+0xD1	0x0143	#	LATIN CAPITAL LETTER N WITH ACUTE
+0xD2	0x00D2	#	LATIN CAPITAL LETTER O WITH GRAVE
+0xD3	0x00D3	#	LATIN CAPITAL LETTER O WITH ACUTE
+0xD4	0x00D4	#	LATIN CAPITAL LETTER O WITH CIRCUMFLEX
+0xD5	0x0150	#	LATIN CAPITAL LETTER O WITH DOUBLE ACUTE
+0xD6	0x00D6	#	LATIN CAPITAL LETTER O WITH DIAERESIS
+0xD7	0x015A	#	LATIN CAPITAL LETTER S WITH ACUTE
+0xD8	0x0170	#	LATIN CAPITAL LETTER U WITH DOUBLE ACUTE
+0xD9	0x00D9	#	LATIN CAPITAL LETTER U WITH GRAVE
+0xDA	0x00DA	#	LATIN CAPITAL LETTER U WITH ACUTE
+0xDB	0x00DB	#	LATIN CAPITAL LETTER U WITH CIRCUMFLEX
+0xDC	0x00DC	#	LATIN CAPITAL LETTER U WITH DIAERESIS
+0xDD	0x0118	#	LATIN CAPITAL LETTER E WITH OGONEK
+0xDE	0x021A	#	LATIN CAPITAL LETTER T WITH COMMA BELOW
+0xDF	0x00DF	#	LATIN SMALL LETTER SHARP S
+0xE0	0x00E0	#	LATIN SMALL LETTER A WITH GRAVE
+0xE1	0x00E1	#	LATIN SMALL LETTER A WITH ACUTE
+0xE2	0x00E2	#	LATIN SMALL LETTER A WITH CIRCUMFLEX
+0xE3	0x0103	#	LATIN SMALL LETTER A WITH BREVE
+0xE4	0x00E4	#	LATIN SMALL LETTER A WITH DIAERESIS
+0xE5	0x0107	#	LATIN SMALL LETTER C WITH ACUTE
+0xE6	0x00E6	#	LATIN SMALL LETTER AE
+0xE7	0x00E7	#	LATIN SMALL LETTER C WITH CEDILLA
+0xE8	0x00E8	#	LATIN SMALL LETTER E WITH GRAVE
+0xE9	0x00E9	#	LATIN SMALL LETTER E WITH ACUTE
+0xEA	0x00EA	#	LATIN SMALL LETTER E WITH CIRCUMFLEX
+0xEB	0x00EB	#	LATIN SMALL LETTER E WITH DIAERESIS
+0xEC	0x00EC	#	LATIN SMALL LETTER I WITH GRAVE
+0xED	0x00ED	#	LATIN SMALL LETTER I WITH ACUTE
+0xEE	0x00EE	#	LATIN SMALL LETTER I WITH CIRCUMFLEX
+0xEF	0x00EF	#	LATIN SMALL LETTER I WITH DIAERESIS
+0xF0	0x0111	#	LATIN SMALL LETTER D WITH STROKE
+0xF1	0x0144	#	LATIN SMALL LETTER N WITH ACUTE
+0xF2	0x00F2	#	LATIN SMALL LETTER O WITH GRAVE
+0xF3	0x00F3	#	LATIN SMALL LETTER O WITH ACUTE
+0xF4	0x00F4	#	LATIN SMALL LETTER O WITH CIRCUMFLEX
+0xF5	0x0151	#	LATIN SMALL LETTER O WITH DOUBLE ACUTE
+0xF6	0x00F6	#	LATIN SMALL LETTER O WITH DIAERESIS
+0xF7	0x015B	#	LATIN SMALL LETTER S WITH ACUTE
+0xF8	0x0171	#	LATIN SMALL LETTER U WITH DOUBLE ACUTE
+0xF9	0x00F9	#	LATIN SMALL LETTER U WITH GRAVE
+0xFA	0x00FA	#	LATIN SMALL LETTER U WITH ACUTE
+0xFB	0x00FB	#	LATIN SMALL LETTER U WITH CIRCUMFLEX
+0xFC	0x00FC	#	LATIN SMALL LETTER U WITH DIAERESIS
+0xFD	0x0119	#	LATIN SMALL LETTER E WITH OGONEK
+0xFE	0x021B	#	LATIN SMALL LETTER T WITH COMMA BELOW
+0xFF	0x00FF	#	LATIN SMALL LETTER Y WITH DIAERESIS
diff --git a/tools/encoding/iso8859-2.txt b/tools/encoding/iso8859-2.txt
new file mode 100644
index 0000000..e45df25
--- /dev/null
+++ b/tools/encoding/iso8859-2.txt
@@ -0,0 +1,303 @@
+#
+#	Name:             ISO 8859-2:1999 to Unicode
+#	Unicode version:  3.0
+#	Table version:    1.0
+#	Table format:     Format A
+#	Date:             1999 July 27
+#	Authors:          Ken Whistler <kenw@sybase.com>
+#
+#	Copyright (c) 1991-1999 Unicode, Inc.  All Rights reserved.
+#
+#	This file is provided as-is by Unicode, Inc. (The Unicode Consortium).
+#	No claims are made as to fitness for any particular purpose.  No
+#	warranties of any kind are expressed or implied.  The recipient
+#	agrees to determine applicability of information provided.  If this
+#	file has been provided on optical media by Unicode, Inc., the sole
+#	remedy for any claim will be exchange of defective media within 90
+#	days of receipt.
+#
+#	Unicode, Inc. hereby grants the right to freely use the information
+#	supplied in this file in the creation of products supporting the
+#	Unicode Standard, and to make copies of this file in any form for
+#	internal or external distribution as long as this notice remains
+#	attached.
+#
+#	General notes:
+#
+#	This table contains the data the Unicode Consortium has on how
+#       ISO/IEC 8859-2:1999 characters map into Unicode.
+#
+#	Format:  Three tab-separated columns
+#		 Column #1 is the ISO/IEC 8859-2 code (in hex as 0xXX)
+#		 Column #2 is the Unicode (in hex as 0xXXXX)
+#		 Column #3 the Unicode name (follows a comment sign, '#')
+#
+#	The entries are in ISO/IEC 8859-2 order.
+#
+#	Version history
+#	1.0 version updates 0.1 version by adding mappings for all
+#	control characters.
+#
+#	Updated versions of this file may be found in:
+#		<ftp://ftp.unicode.org/Public/MAPPINGS/>
+#
+#	Any comments or problems, contact <errata@unicode.org>
+#	Please note that <errata@unicode.org> is an archival address;
+#	notices will be checked, but do not expect an immediate response.
+#
+0x00	0x0000	#	NULL
+0x01	0x0001	#	START OF HEADING
+0x02	0x0002	#	START OF TEXT
+0x03	0x0003	#	END OF TEXT
+0x04	0x0004	#	END OF TRANSMISSION
+0x05	0x0005	#	ENQUIRY
+0x06	0x0006	#	ACKNOWLEDGE
+0x07	0x0007	#	BELL
+0x08	0x0008	#	BACKSPACE
+0x09	0x0009	#	HORIZONTAL TABULATION
+0x0A	0x000A	#	LINE FEED
+0x0B	0x000B	#	VERTICAL TABULATION
+0x0C	0x000C	#	FORM FEED
+0x0D	0x000D	#	CARRIAGE RETURN
+0x0E	0x000E	#	SHIFT OUT
+0x0F	0x000F	#	SHIFT IN
+0x10	0x0010	#	DATA LINK ESCAPE
+0x11	0x0011	#	DEVICE CONTROL ONE
+0x12	0x0012	#	DEVICE CONTROL TWO
+0x13	0x0013	#	DEVICE CONTROL THREE
+0x14	0x0014	#	DEVICE CONTROL FOUR
+0x15	0x0015	#	NEGATIVE ACKNOWLEDGE
+0x16	0x0016	#	SYNCHRONOUS IDLE
+0x17	0x0017	#	END OF TRANSMISSION BLOCK
+0x18	0x0018	#	CANCEL
+0x19	0x0019	#	END OF MEDIUM
+0x1A	0x001A	#	SUBSTITUTE
+0x1B	0x001B	#	ESCAPE
+0x1C	0x001C	#	FILE SEPARATOR
+0x1D	0x001D	#	GROUP SEPARATOR
+0x1E	0x001E	#	RECORD SEPARATOR
+0x1F	0x001F	#	UNIT SEPARATOR
+0x20	0x0020	#	SPACE
+0x21	0x0021	#	EXCLAMATION MARK
+0x22	0x0022	#	QUOTATION MARK
+0x23	0x0023	#	NUMBER SIGN
+0x24	0x0024	#	DOLLAR SIGN
+0x25	0x0025	#	PERCENT SIGN
+0x26	0x0026	#	AMPERSAND
+0x27	0x0027	#	APOSTROPHE
+0x28	0x0028	#	LEFT PARENTHESIS
+0x29	0x0029	#	RIGHT PARENTHESIS
+0x2A	0x002A	#	ASTERISK
+0x2B	0x002B	#	PLUS SIGN
+0x2C	0x002C	#	COMMA
+0x2D	0x002D	#	HYPHEN-MINUS
+0x2E	0x002E	#	FULL STOP
+0x2F	0x002F	#	SOLIDUS
+0x30	0x0030	#	DIGIT ZERO
+0x31	0x0031	#	DIGIT ONE
+0x32	0x0032	#	DIGIT TWO
+0x33	0x0033	#	DIGIT THREE
+0x34	0x0034	#	DIGIT FOUR
+0x35	0x0035	#	DIGIT FIVE
+0x36	0x0036	#	DIGIT SIX
+0x37	0x0037	#	DIGIT SEVEN
+0x38	0x0038	#	DIGIT EIGHT
+0x39	0x0039	#	DIGIT NINE
+0x3A	0x003A	#	COLON
+0x3B	0x003B	#	SEMICOLON
+0x3C	0x003C	#	LESS-THAN SIGN
+0x3D	0x003D	#	EQUALS SIGN
+0x3E	0x003E	#	GREATER-THAN SIGN
+0x3F	0x003F	#	QUESTION MARK
+0x40	0x0040	#	COMMERCIAL AT
+0x41	0x0041	#	LATIN CAPITAL LETTER A
+0x42	0x0042	#	LATIN CAPITAL LETTER B
+0x43	0x0043	#	LATIN CAPITAL LETTER C
+0x44	0x0044	#	LATIN CAPITAL LETTER D
+0x45	0x0045	#	LATIN CAPITAL LETTER E
+0x46	0x0046	#	LATIN CAPITAL LETTER F
+0x47	0x0047	#	LATIN CAPITAL LETTER G
+0x48	0x0048	#	LATIN CAPITAL LETTER H
+0x49	0x0049	#	LATIN CAPITAL LETTER I
+0x4A	0x004A	#	LATIN CAPITAL LETTER J
+0x4B	0x004B	#	LATIN CAPITAL LETTER K
+0x4C	0x004C	#	LATIN CAPITAL LETTER L
+0x4D	0x004D	#	LATIN CAPITAL LETTER M
+0x4E	0x004E	#	LATIN CAPITAL LETTER N
+0x4F	0x004F	#	LATIN CAPITAL LETTER O
+0x50	0x0050	#	LATIN CAPITAL LETTER P
+0x51	0x0051	#	LATIN CAPITAL LETTER Q
+0x52	0x0052	#	LATIN CAPITAL LETTER R
+0x53	0x0053	#	LATIN CAPITAL LETTER S
+0x54	0x0054	#	LATIN CAPITAL LETTER T
+0x55	0x0055	#	LATIN CAPITAL LETTER U
+0x56	0x0056	#	LATIN CAPITAL LETTER V
+0x57	0x0057	#	LATIN CAPITAL LETTER W
+0x58	0x0058	#	LATIN CAPITAL LETTER X
+0x59	0x0059	#	LATIN CAPITAL LETTER Y
+0x5A	0x005A	#	LATIN CAPITAL LETTER Z
+0x5B	0x005B	#	LEFT SQUARE BRACKET
+0x5C	0x005C	#	REVERSE SOLIDUS
+0x5D	0x005D	#	RIGHT SQUARE BRACKET
+0x5E	0x005E	#	CIRCUMFLEX ACCENT
+0x5F	0x005F	#	LOW LINE
+0x60	0x0060	#	GRAVE ACCENT
+0x61	0x0061	#	LATIN SMALL LETTER A
+0x62	0x0062	#	LATIN SMALL LETTER B
+0x63	0x0063	#	LATIN SMALL LETTER C
+0x64	0x0064	#	LATIN SMALL LETTER D
+0x65	0x0065	#	LATIN SMALL LETTER E
+0x66	0x0066	#	LATIN SMALL LETTER F
+0x67	0x0067	#	LATIN SMALL LETTER G
+0x68	0x0068	#	LATIN SMALL LETTER H
+0x69	0x0069	#	LATIN SMALL LETTER I
+0x6A	0x006A	#	LATIN SMALL LETTER J
+0x6B	0x006B	#	LATIN SMALL LETTER K
+0x6C	0x006C	#	LATIN SMALL LETTER L
+0x6D	0x006D	#	LATIN SMALL LETTER M
+0x6E	0x006E	#	LATIN SMALL LETTER N
+0x6F	0x006F	#	LATIN SMALL LETTER O
+0x70	0x0070	#	LATIN SMALL LETTER P
+0x71	0x0071	#	LATIN SMALL LETTER Q
+0x72	0x0072	#	LATIN SMALL LETTER R
+0x73	0x0073	#	LATIN SMALL LETTER S
+0x74	0x0074	#	LATIN SMALL LETTER T
+0x75	0x0075	#	LATIN SMALL LETTER U
+0x76	0x0076	#	LATIN SMALL LETTER V
+0x77	0x0077	#	LATIN SMALL LETTER W
+0x78	0x0078	#	LATIN SMALL LETTER X
+0x79	0x0079	#	LATIN SMALL LETTER Y
+0x7A	0x007A	#	LATIN SMALL LETTER Z
+0x7B	0x007B	#	LEFT CURLY BRACKET
+0x7C	0x007C	#	VERTICAL LINE
+0x7D	0x007D	#	RIGHT CURLY BRACKET
+0x7E	0x007E	#	TILDE
+0x7F	0x007F	#	DELETE
+0x80	0x0080	#	<control>
+0x81	0x0081	#	<control>
+0x82	0x0082	#	<control>
+0x83	0x0083	#	<control>
+0x84	0x0084	#	<control>
+0x85	0x0085	#	<control>
+0x86	0x0086	#	<control>
+0x87	0x0087	#	<control>
+0x88	0x0088	#	<control>
+0x89	0x0089	#	<control>
+0x8A	0x008A	#	<control>
+0x8B	0x008B	#	<control>
+0x8C	0x008C	#	<control>
+0x8D	0x008D	#	<control>
+0x8E	0x008E	#	<control>
+0x8F	0x008F	#	<control>
+0x90	0x0090	#	<control>
+0x91	0x0091	#	<control>
+0x92	0x0092	#	<control>
+0x93	0x0093	#	<control>
+0x94	0x0094	#	<control>
+0x95	0x0095	#	<control>
+0x96	0x0096	#	<control>
+0x97	0x0097	#	<control>
+0x98	0x0098	#	<control>
+0x99	0x0099	#	<control>
+0x9A	0x009A	#	<control>
+0x9B	0x009B	#	<control>
+0x9C	0x009C	#	<control>
+0x9D	0x009D	#	<control>
+0x9E	0x009E	#	<control>
+0x9F	0x009F	#	<control>
+0xA0	0x00A0	#	NO-BREAK SPACE
+0xA1	0x0104	#	LATIN CAPITAL LETTER A WITH OGONEK
+0xA2	0x02D8	#	BREVE
+0xA3	0x0141	#	LATIN CAPITAL LETTER L WITH STROKE
+0xA4	0x00A4	#	CURRENCY SIGN
+0xA5	0x013D	#	LATIN CAPITAL LETTER L WITH CARON
+0xA6	0x015A	#	LATIN CAPITAL LETTER S WITH ACUTE
+0xA7	0x00A7	#	SECTION SIGN
+0xA8	0x00A8	#	DIAERESIS
+0xA9	0x0160	#	LATIN CAPITAL LETTER S WITH CARON
+0xAA	0x015E	#	LATIN CAPITAL LETTER S WITH CEDILLA
+0xAB	0x0164	#	LATIN CAPITAL LETTER T WITH CARON
+0xAC	0x0179	#	LATIN CAPITAL LETTER Z WITH ACUTE
+0xAD	0x00AD	#	SOFT HYPHEN
+0xAE	0x017D	#	LATIN CAPITAL LETTER Z WITH CARON
+0xAF	0x017B	#	LATIN CAPITAL LETTER Z WITH DOT ABOVE
+0xB0	0x00B0	#	DEGREE SIGN
+0xB1	0x0105	#	LATIN SMALL LETTER A WITH OGONEK
+0xB2	0x02DB	#	OGONEK
+0xB3	0x0142	#	LATIN SMALL LETTER L WITH STROKE
+0xB4	0x00B4	#	ACUTE ACCENT
+0xB5	0x013E	#	LATIN SMALL LETTER L WITH CARON
+0xB6	0x015B	#	LATIN SMALL LETTER S WITH ACUTE
+0xB7	0x02C7	#	CARON
+0xB8	0x00B8	#	CEDILLA
+0xB9	0x0161	#	LATIN SMALL LETTER S WITH CARON
+0xBA	0x015F	#	LATIN SMALL LETTER S WITH CEDILLA
+0xBB	0x0165	#	LATIN SMALL LETTER T WITH CARON
+0xBC	0x017A	#	LATIN SMALL LETTER Z WITH ACUTE
+0xBD	0x02DD	#	DOUBLE ACUTE ACCENT
+0xBE	0x017E	#	LATIN SMALL LETTER Z WITH CARON
+0xBF	0x017C	#	LATIN SMALL LETTER Z WITH DOT ABOVE
+0xC0	0x0154	#	LATIN CAPITAL LETTER R WITH ACUTE
+0xC1	0x00C1	#	LATIN CAPITAL LETTER A WITH ACUTE
+0xC2	0x00C2	#	LATIN CAPITAL LETTER A WITH CIRCUMFLEX
+0xC3	0x0102	#	LATIN CAPITAL LETTER A WITH BREVE
+0xC4	0x00C4	#	LATIN CAPITAL LETTER A WITH DIAERESIS
+0xC5	0x0139	#	LATIN CAPITAL LETTER L WITH ACUTE
+0xC6	0x0106	#	LATIN CAPITAL LETTER C WITH ACUTE
+0xC7	0x00C7	#	LATIN CAPITAL LETTER C WITH CEDILLA
+0xC8	0x010C	#	LATIN CAPITAL LETTER C WITH CARON
+0xC9	0x00C9	#	LATIN CAPITAL LETTER E WITH ACUTE
+0xCA	0x0118	#	LATIN CAPITAL LETTER E WITH OGONEK
+0xCB	0x00CB	#	LATIN CAPITAL LETTER E WITH DIAERESIS
+0xCC	0x011A	#	LATIN CAPITAL LETTER E WITH CARON
+0xCD	0x00CD	#	LATIN CAPITAL LETTER I WITH ACUTE
+0xCE	0x00CE	#	LATIN CAPITAL LETTER I WITH CIRCUMFLEX
+0xCF	0x010E	#	LATIN CAPITAL LETTER D WITH CARON
+0xD0	0x0110	#	LATIN CAPITAL LETTER D WITH STROKE
+0xD1	0x0143	#	LATIN CAPITAL LETTER N WITH ACUTE
+0xD2	0x0147	#	LATIN CAPITAL LETTER N WITH CARON
+0xD3	0x00D3	#	LATIN CAPITAL LETTER O WITH ACUTE
+0xD4	0x00D4	#	LATIN CAPITAL LETTER O WITH CIRCUMFLEX
+0xD5	0x0150	#	LATIN CAPITAL LETTER O WITH DOUBLE ACUTE
+0xD6	0x00D6	#	LATIN CAPITAL LETTER O WITH DIAERESIS
+0xD7	0x00D7	#	MULTIPLICATION SIGN
+0xD8	0x0158	#	LATIN CAPITAL LETTER R WITH CARON
+0xD9	0x016E	#	LATIN CAPITAL LETTER U WITH RING ABOVE
+0xDA	0x00DA	#	LATIN CAPITAL LETTER U WITH ACUTE
+0xDB	0x0170	#	LATIN CAPITAL LETTER U WITH DOUBLE ACUTE
+0xDC	0x00DC	#	LATIN CAPITAL LETTER U WITH DIAERESIS
+0xDD	0x00DD	#	LATIN CAPITAL LETTER Y WITH ACUTE
+0xDE	0x0162	#	LATIN CAPITAL LETTER T WITH CEDILLA
+0xDF	0x00DF	#	LATIN SMALL LETTER SHARP S
+0xE0	0x0155	#	LATIN SMALL LETTER R WITH ACUTE
+0xE1	0x00E1	#	LATIN SMALL LETTER A WITH ACUTE
+0xE2	0x00E2	#	LATIN SMALL LETTER A WITH CIRCUMFLEX
+0xE3	0x0103	#	LATIN SMALL LETTER A WITH BREVE
+0xE4	0x00E4	#	LATIN SMALL LETTER A WITH DIAERESIS
+0xE5	0x013A	#	LATIN SMALL LETTER L WITH ACUTE
+0xE6	0x0107	#	LATIN SMALL LETTER C WITH ACUTE
+0xE7	0x00E7	#	LATIN SMALL LETTER C WITH CEDILLA
+0xE8	0x010D	#	LATIN SMALL LETTER C WITH CARON
+0xE9	0x00E9	#	LATIN SMALL LETTER E WITH ACUTE
+0xEA	0x0119	#	LATIN SMALL LETTER E WITH OGONEK
+0xEB	0x00EB	#	LATIN SMALL LETTER E WITH DIAERESIS
+0xEC	0x011B	#	LATIN SMALL LETTER E WITH CARON
+0xED	0x00ED	#	LATIN SMALL LETTER I WITH ACUTE
+0xEE	0x00EE	#	LATIN SMALL LETTER I WITH CIRCUMFLEX
+0xEF	0x010F	#	LATIN SMALL LETTER D WITH CARON
+0xF0	0x0111	#	LATIN SMALL LETTER D WITH STROKE
+0xF1	0x0144	#	LATIN SMALL LETTER N WITH ACUTE
+0xF2	0x0148	#	LATIN SMALL LETTER N WITH CARON
+0xF3	0x00F3	#	LATIN SMALL LETTER O WITH ACUTE
+0xF4	0x00F4	#	LATIN SMALL LETTER O WITH CIRCUMFLEX
+0xF5	0x0151	#	LATIN SMALL LETTER O WITH DOUBLE ACUTE
+0xF6	0x00F6	#	LATIN SMALL LETTER O WITH DIAERESIS
+0xF7	0x00F7	#	DIVISION SIGN
+0xF8	0x0159	#	LATIN SMALL LETTER R WITH CARON
+0xF9	0x016F	#	LATIN SMALL LETTER U WITH RING ABOVE
+0xFA	0x00FA	#	LATIN SMALL LETTER U WITH ACUTE
+0xFB	0x0171	#	LATIN SMALL LETTER U WITH DOUBLE ACUTE
+0xFC	0x00FC	#	LATIN SMALL LETTER U WITH DIAERESIS
+0xFD	0x00FD	#	LATIN SMALL LETTER Y WITH ACUTE
+0xFE	0x0163	#	LATIN SMALL LETTER T WITH CEDILLA
+0xFF	0x02D9	#	DOT ABOVE
diff --git a/tools/encoding/iso8859-3.txt b/tools/encoding/iso8859-3.txt
new file mode 100644
index 0000000..9b6ac69
--- /dev/null
+++ b/tools/encoding/iso8859-3.txt
@@ -0,0 +1,296 @@
+#
+#	Name:             ISO/IEC 8859-3:1999 to Unicode
+#	Unicode version:  3.0
+#	Table version:    1.0
+#	Table format:     Format A
+#	Date:             1999 July 27
+#	Authors:          Ken Whistler <kenw@sybase.com>
+#
+#	Copyright (c) 1991-1999 Unicode, Inc.  All Rights reserved.
+#
+#	This file is provided as-is by Unicode, Inc. (The Unicode Consortium).
+#	No claims are made as to fitness for any particular purpose.  No
+#	warranties of any kind are expressed or implied.  The recipient
+#	agrees to determine applicability of information provided.  If this
+#	file has been provided on optical media by Unicode, Inc., the sole
+#	remedy for any claim will be exchange of defective media within 90
+#	days of receipt.
+#
+#	Unicode, Inc. hereby grants the right to freely use the information
+#	supplied in this file in the creation of products supporting the
+#	Unicode Standard, and to make copies of this file in any form for
+#	internal or external distribution as long as this notice remains
+#	attached.
+#
+#	General notes:
+#
+#	This table contains the data the Unicode Consortium has on how
+#       ISO/IEC 8859-3:1999 characters map into Unicode.
+#
+#	Format:  Three tab-separated columns
+#		 Column #1 is the ISO/IEC 8859-3 code (in hex as 0xXX)
+#		 Column #2 is the Unicode (in hex as 0xXXXX)
+#		 Column #3 the Unicode name (follows a comment sign, '#')
+#
+#	The entries are in ISO/IEC 8859-3 order.
+#
+#	Version history
+#	1.0 version updates 0.1 version by adding mappings for all
+#	control characters.
+#
+#	Updated versions of this file may be found in:
+#		<ftp://ftp.unicode.org/Public/MAPPINGS/>
+#
+#	Any comments or problems, contact <errata@unicode.org>
+#	Please note that <errata@unicode.org> is an archival address;
+#	notices will be checked, but do not expect an immediate response.
+#
+0x00	0x0000	#	NULL
+0x01	0x0001	#	START OF HEADING
+0x02	0x0002	#	START OF TEXT
+0x03	0x0003	#	END OF TEXT
+0x04	0x0004	#	END OF TRANSMISSION
+0x05	0x0005	#	ENQUIRY
+0x06	0x0006	#	ACKNOWLEDGE
+0x07	0x0007	#	BELL
+0x08	0x0008	#	BACKSPACE
+0x09	0x0009	#	HORIZONTAL TABULATION
+0x0A	0x000A	#	LINE FEED
+0x0B	0x000B	#	VERTICAL TABULATION
+0x0C	0x000C	#	FORM FEED
+0x0D	0x000D	#	CARRIAGE RETURN
+0x0E	0x000E	#	SHIFT OUT
+0x0F	0x000F	#	SHIFT IN
+0x10	0x0010	#	DATA LINK ESCAPE
+0x11	0x0011	#	DEVICE CONTROL ONE
+0x12	0x0012	#	DEVICE CONTROL TWO
+0x13	0x0013	#	DEVICE CONTROL THREE
+0x14	0x0014	#	DEVICE CONTROL FOUR
+0x15	0x0015	#	NEGATIVE ACKNOWLEDGE
+0x16	0x0016	#	SYNCHRONOUS IDLE
+0x17	0x0017	#	END OF TRANSMISSION BLOCK
+0x18	0x0018	#	CANCEL
+0x19	0x0019	#	END OF MEDIUM
+0x1A	0x001A	#	SUBSTITUTE
+0x1B	0x001B	#	ESCAPE
+0x1C	0x001C	#	FILE SEPARATOR
+0x1D	0x001D	#	GROUP SEPARATOR
+0x1E	0x001E	#	RECORD SEPARATOR
+0x1F	0x001F	#	UNIT SEPARATOR
+0x20	0x0020	#	SPACE
+0x21	0x0021	#	EXCLAMATION MARK
+0x22	0x0022	#	QUOTATION MARK
+0x23	0x0023	#	NUMBER SIGN
+0x24	0x0024	#	DOLLAR SIGN
+0x25	0x0025	#	PERCENT SIGN
+0x26	0x0026	#	AMPERSAND
+0x27	0x0027	#	APOSTROPHE
+0x28	0x0028	#	LEFT PARENTHESIS
+0x29	0x0029	#	RIGHT PARENTHESIS
+0x2A	0x002A	#	ASTERISK
+0x2B	0x002B	#	PLUS SIGN
+0x2C	0x002C	#	COMMA
+0x2D	0x002D	#	HYPHEN-MINUS
+0x2E	0x002E	#	FULL STOP
+0x2F	0x002F	#	SOLIDUS
+0x30	0x0030	#	DIGIT ZERO
+0x31	0x0031	#	DIGIT ONE
+0x32	0x0032	#	DIGIT TWO
+0x33	0x0033	#	DIGIT THREE
+0x34	0x0034	#	DIGIT FOUR
+0x35	0x0035	#	DIGIT FIVE
+0x36	0x0036	#	DIGIT SIX
+0x37	0x0037	#	DIGIT SEVEN
+0x38	0x0038	#	DIGIT EIGHT
+0x39	0x0039	#	DIGIT NINE
+0x3A	0x003A	#	COLON
+0x3B	0x003B	#	SEMICOLON
+0x3C	0x003C	#	LESS-THAN SIGN
+0x3D	0x003D	#	EQUALS SIGN
+0x3E	0x003E	#	GREATER-THAN SIGN
+0x3F	0x003F	#	QUESTION MARK
+0x40	0x0040	#	COMMERCIAL AT
+0x41	0x0041	#	LATIN CAPITAL LETTER A
+0x42	0x0042	#	LATIN CAPITAL LETTER B
+0x43	0x0043	#	LATIN CAPITAL LETTER C
+0x44	0x0044	#	LATIN CAPITAL LETTER D
+0x45	0x0045	#	LATIN CAPITAL LETTER E
+0x46	0x0046	#	LATIN CAPITAL LETTER F
+0x47	0x0047	#	LATIN CAPITAL LETTER G
+0x48	0x0048	#	LATIN CAPITAL LETTER H
+0x49	0x0049	#	LATIN CAPITAL LETTER I
+0x4A	0x004A	#	LATIN CAPITAL LETTER J
+0x4B	0x004B	#	LATIN CAPITAL LETTER K
+0x4C	0x004C	#	LATIN CAPITAL LETTER L
+0x4D	0x004D	#	LATIN CAPITAL LETTER M
+0x4E	0x004E	#	LATIN CAPITAL LETTER N
+0x4F	0x004F	#	LATIN CAPITAL LETTER O
+0x50	0x0050	#	LATIN CAPITAL LETTER P
+0x51	0x0051	#	LATIN CAPITAL LETTER Q
+0x52	0x0052	#	LATIN CAPITAL LETTER R
+0x53	0x0053	#	LATIN CAPITAL LETTER S
+0x54	0x0054	#	LATIN CAPITAL LETTER T
+0x55	0x0055	#	LATIN CAPITAL LETTER U
+0x56	0x0056	#	LATIN CAPITAL LETTER V
+0x57	0x0057	#	LATIN CAPITAL LETTER W
+0x58	0x0058	#	LATIN CAPITAL LETTER X
+0x59	0x0059	#	LATIN CAPITAL LETTER Y
+0x5A	0x005A	#	LATIN CAPITAL LETTER Z
+0x5B	0x005B	#	LEFT SQUARE BRACKET
+0x5C	0x005C	#	REVERSE SOLIDUS
+0x5D	0x005D	#	RIGHT SQUARE BRACKET
+0x5E	0x005E	#	CIRCUMFLEX ACCENT
+0x5F	0x005F	#	LOW LINE
+0x60	0x0060	#	GRAVE ACCENT
+0x61	0x0061	#	LATIN SMALL LETTER A
+0x62	0x0062	#	LATIN SMALL LETTER B
+0x63	0x0063	#	LATIN SMALL LETTER C
+0x64	0x0064	#	LATIN SMALL LETTER D
+0x65	0x0065	#	LATIN SMALL LETTER E
+0x66	0x0066	#	LATIN SMALL LETTER F
+0x67	0x0067	#	LATIN SMALL LETTER G
+0x68	0x0068	#	LATIN SMALL LETTER H
+0x69	0x0069	#	LATIN SMALL LETTER I
+0x6A	0x006A	#	LATIN SMALL LETTER J
+0x6B	0x006B	#	LATIN SMALL LETTER K
+0x6C	0x006C	#	LATIN SMALL LETTER L
+0x6D	0x006D	#	LATIN SMALL LETTER M
+0x6E	0x006E	#	LATIN SMALL LETTER N
+0x6F	0x006F	#	LATIN SMALL LETTER O
+0x70	0x0070	#	LATIN SMALL LETTER P
+0x71	0x0071	#	LATIN SMALL LETTER Q
+0x72	0x0072	#	LATIN SMALL LETTER R
+0x73	0x0073	#	LATIN SMALL LETTER S
+0x74	0x0074	#	LATIN SMALL LETTER T
+0x75	0x0075	#	LATIN SMALL LETTER U
+0x76	0x0076	#	LATIN SMALL LETTER V
+0x77	0x0077	#	LATIN SMALL LETTER W
+0x78	0x0078	#	LATIN SMALL LETTER X
+0x79	0x0079	#	LATIN SMALL LETTER Y
+0x7A	0x007A	#	LATIN SMALL LETTER Z
+0x7B	0x007B	#	LEFT CURLY BRACKET
+0x7C	0x007C	#	VERTICAL LINE
+0x7D	0x007D	#	RIGHT CURLY BRACKET
+0x7E	0x007E	#	TILDE
+0x7F	0x007F	#	DELETE
+0x80	0x0080	#	<control>
+0x81	0x0081	#	<control>
+0x82	0x0082	#	<control>
+0x83	0x0083	#	<control>
+0x84	0x0084	#	<control>
+0x85	0x0085	#	<control>
+0x86	0x0086	#	<control>
+0x87	0x0087	#	<control>
+0x88	0x0088	#	<control>
+0x89	0x0089	#	<control>
+0x8A	0x008A	#	<control>
+0x8B	0x008B	#	<control>
+0x8C	0x008C	#	<control>
+0x8D	0x008D	#	<control>
+0x8E	0x008E	#	<control>
+0x8F	0x008F	#	<control>
+0x90	0x0090	#	<control>
+0x91	0x0091	#	<control>
+0x92	0x0092	#	<control>
+0x93	0x0093	#	<control>
+0x94	0x0094	#	<control>
+0x95	0x0095	#	<control>
+0x96	0x0096	#	<control>
+0x97	0x0097	#	<control>
+0x98	0x0098	#	<control>
+0x99	0x0099	#	<control>
+0x9A	0x009A	#	<control>
+0x9B	0x009B	#	<control>
+0x9C	0x009C	#	<control>
+0x9D	0x009D	#	<control>
+0x9E	0x009E	#	<control>
+0x9F	0x009F	#	<control>
+0xA0	0x00A0	#	NO-BREAK SPACE
+0xA1	0x0126	#	LATIN CAPITAL LETTER H WITH STROKE
+0xA2	0x02D8	#	BREVE
+0xA3	0x00A3	#	POUND SIGN
+0xA4	0x00A4	#	CURRENCY SIGN
+0xA6	0x0124	#	LATIN CAPITAL LETTER H WITH CIRCUMFLEX
+0xA7	0x00A7	#	SECTION SIGN
+0xA8	0x00A8	#	DIAERESIS
+0xA9	0x0130	#	LATIN CAPITAL LETTER I WITH DOT ABOVE
+0xAA	0x015E	#	LATIN CAPITAL LETTER S WITH CEDILLA
+0xAB	0x011E	#	LATIN CAPITAL LETTER G WITH BREVE
+0xAC	0x0134	#	LATIN CAPITAL LETTER J WITH CIRCUMFLEX
+0xAD	0x00AD	#	SOFT HYPHEN
+0xAF	0x017B	#	LATIN CAPITAL LETTER Z WITH DOT ABOVE
+0xB0	0x00B0	#	DEGREE SIGN
+0xB1	0x0127	#	LATIN SMALL LETTER H WITH STROKE
+0xB2	0x00B2	#	SUPERSCRIPT TWO
+0xB3	0x00B3	#	SUPERSCRIPT THREE
+0xB4	0x00B4	#	ACUTE ACCENT
+0xB5	0x00B5	#	MICRO SIGN
+0xB6	0x0125	#	LATIN SMALL LETTER H WITH CIRCUMFLEX
+0xB7	0x00B7	#	MIDDLE DOT
+0xB8	0x00B8	#	CEDILLA
+0xB9	0x0131	#	LATIN SMALL LETTER DOTLESS I
+0xBA	0x015F	#	LATIN SMALL LETTER S WITH CEDILLA
+0xBB	0x011F	#	LATIN SMALL LETTER G WITH BREVE
+0xBC	0x0135	#	LATIN SMALL LETTER J WITH CIRCUMFLEX
+0xBD	0x00BD	#	VULGAR FRACTION ONE HALF
+0xBF	0x017C	#	LATIN SMALL LETTER Z WITH DOT ABOVE
+0xC0	0x00C0	#	LATIN CAPITAL LETTER A WITH GRAVE
+0xC1	0x00C1	#	LATIN CAPITAL LETTER A WITH ACUTE
+0xC2	0x00C2	#	LATIN CAPITAL LETTER A WITH CIRCUMFLEX
+0xC4	0x00C4	#	LATIN CAPITAL LETTER A WITH DIAERESIS
+0xC5	0x010A	#	LATIN CAPITAL LETTER C WITH DOT ABOVE
+0xC6	0x0108	#	LATIN CAPITAL LETTER C WITH CIRCUMFLEX
+0xC7	0x00C7	#	LATIN CAPITAL LETTER C WITH CEDILLA
+0xC8	0x00C8	#	LATIN CAPITAL LETTER E WITH GRAVE
+0xC9	0x00C9	#	LATIN CAPITAL LETTER E WITH ACUTE
+0xCA	0x00CA	#	LATIN CAPITAL LETTER E WITH CIRCUMFLEX
+0xCB	0x00CB	#	LATIN CAPITAL LETTER E WITH DIAERESIS
+0xCC	0x00CC	#	LATIN CAPITAL LETTER I WITH GRAVE
+0xCD	0x00CD	#	LATIN CAPITAL LETTER I WITH ACUTE
+0xCE	0x00CE	#	LATIN CAPITAL LETTER I WITH CIRCUMFLEX
+0xCF	0x00CF	#	LATIN CAPITAL LETTER I WITH DIAERESIS
+0xD1	0x00D1	#	LATIN CAPITAL LETTER N WITH TILDE
+0xD2	0x00D2	#	LATIN CAPITAL LETTER O WITH GRAVE
+0xD3	0x00D3	#	LATIN CAPITAL LETTER O WITH ACUTE
+0xD4	0x00D4	#	LATIN CAPITAL LETTER O WITH CIRCUMFLEX
+0xD5	0x0120	#	LATIN CAPITAL LETTER G WITH DOT ABOVE
+0xD6	0x00D6	#	LATIN CAPITAL LETTER O WITH DIAERESIS
+0xD7	0x00D7	#	MULTIPLICATION SIGN
+0xD8	0x011C	#	LATIN CAPITAL LETTER G WITH CIRCUMFLEX
+0xD9	0x00D9	#	LATIN CAPITAL LETTER U WITH GRAVE
+0xDA	0x00DA	#	LATIN CAPITAL LETTER U WITH ACUTE
+0xDB	0x00DB	#	LATIN CAPITAL LETTER U WITH CIRCUMFLEX
+0xDC	0x00DC	#	LATIN CAPITAL LETTER U WITH DIAERESIS
+0xDD	0x016C	#	LATIN CAPITAL LETTER U WITH BREVE
+0xDE	0x015C	#	LATIN CAPITAL LETTER S WITH CIRCUMFLEX
+0xDF	0x00DF	#	LATIN SMALL LETTER SHARP S
+0xE0	0x00E0	#	LATIN SMALL LETTER A WITH GRAVE
+0xE1	0x00E1	#	LATIN SMALL LETTER A WITH ACUTE
+0xE2	0x00E2	#	LATIN SMALL LETTER A WITH CIRCUMFLEX
+0xE4	0x00E4	#	LATIN SMALL LETTER A WITH DIAERESIS
+0xE5	0x010B	#	LATIN SMALL LETTER C WITH DOT ABOVE
+0xE6	0x0109	#	LATIN SMALL LETTER C WITH CIRCUMFLEX
+0xE7	0x00E7	#	LATIN SMALL LETTER C WITH CEDILLA
+0xE8	0x00E8	#	LATIN SMALL LETTER E WITH GRAVE
+0xE9	0x00E9	#	LATIN SMALL LETTER E WITH ACUTE
+0xEA	0x00EA	#	LATIN SMALL LETTER E WITH CIRCUMFLEX
+0xEB	0x00EB	#	LATIN SMALL LETTER E WITH DIAERESIS
+0xEC	0x00EC	#	LATIN SMALL LETTER I WITH GRAVE
+0xED	0x00ED	#	LATIN SMALL LETTER I WITH ACUTE
+0xEE	0x00EE	#	LATIN SMALL LETTER I WITH CIRCUMFLEX
+0xEF	0x00EF	#	LATIN SMALL LETTER I WITH DIAERESIS
+0xF1	0x00F1	#	LATIN SMALL LETTER N WITH TILDE
+0xF2	0x00F2	#	LATIN SMALL LETTER O WITH GRAVE
+0xF3	0x00F3	#	LATIN SMALL LETTER O WITH ACUTE
+0xF4	0x00F4	#	LATIN SMALL LETTER O WITH CIRCUMFLEX
+0xF5	0x0121	#	LATIN SMALL LETTER G WITH DOT ABOVE
+0xF6	0x00F6	#	LATIN SMALL LETTER O WITH DIAERESIS
+0xF7	0x00F7	#	DIVISION SIGN
+0xF8	0x011D	#	LATIN SMALL LETTER G WITH CIRCUMFLEX
+0xF9	0x00F9	#	LATIN SMALL LETTER U WITH GRAVE
+0xFA	0x00FA	#	LATIN SMALL LETTER U WITH ACUTE
+0xFB	0x00FB	#	LATIN SMALL LETTER U WITH CIRCUMFLEX
+0xFC	0x00FC	#	LATIN SMALL LETTER U WITH DIAERESIS
+0xFD	0x016D	#	LATIN SMALL LETTER U WITH BREVE
+0xFE	0x015D	#	LATIN SMALL LETTER S WITH CIRCUMFLEX
+0xFF	0x02D9	#	DOT ABOVE
diff --git a/tools/encoding/iso8859-4.txt b/tools/encoding/iso8859-4.txt
new file mode 100644
index 0000000..662e698
--- /dev/null
+++ b/tools/encoding/iso8859-4.txt
@@ -0,0 +1,303 @@
+#
+#	Name:             ISO/IEC 8859-4:1998 to Unicode
+#	Unicode version:  3.0
+#	Table version:    1.0
+#	Table format:     Format A
+#	Date:             1999 July 27
+#	Authors:          Ken Whistler <kenw@sybase.com>
+#
+#	Copyright (c) 1991-1999 Unicode, Inc.  All Rights reserved.
+#
+#	This file is provided as-is by Unicode, Inc. (The Unicode Consortium).
+#	No claims are made as to fitness for any particular purpose.  No
+#	warranties of any kind are expressed or implied.  The recipient
+#	agrees to determine applicability of information provided.  If this
+#	file has been provided on optical media by Unicode, Inc., the sole
+#	remedy for any claim will be exchange of defective media within 90
+#	days of receipt.
+#
+#	Unicode, Inc. hereby grants the right to freely use the information
+#	supplied in this file in the creation of products supporting the
+#	Unicode Standard, and to make copies of this file in any form for
+#	internal or external distribution as long as this notice remains
+#	attached.
+#
+#	General notes:
+#
+#	This table contains the data the Unicode Consortium has on how
+#       ISO/IEC 8859-4:1998 characters map into Unicode.
+#
+#	Format:  Three tab-separated columns
+#		 Column #1 is the ISO/IEC 8859-4 code (in hex as 0xXX)
+#		 Column #2 is the Unicode (in hex as 0xXXXX)
+#		 Column #3 the Unicode name (follows a comment sign, '#')
+#
+#	The entries are in ISO/IEC 8859-4 order.
+#
+#	Version history
+#	1.0 version updates 0.1 version by adding mappings for all
+#	control characters.
+#
+#	Updated versions of this file may be found in:
+#		<ftp://ftp.unicode.org/Public/MAPPINGS/>
+#
+#	Any comments or problems, contact <errata@unicode.org>
+#	Please note that <errata@unicode.org> is an archival address;
+#	notices will be checked, but do not expect an immediate response.
+#
+0x00	0x0000	#	NULL
+0x01	0x0001	#	START OF HEADING
+0x02	0x0002	#	START OF TEXT
+0x03	0x0003	#	END OF TEXT
+0x04	0x0004	#	END OF TRANSMISSION
+0x05	0x0005	#	ENQUIRY
+0x06	0x0006	#	ACKNOWLEDGE
+0x07	0x0007	#	BELL
+0x08	0x0008	#	BACKSPACE
+0x09	0x0009	#	HORIZONTAL TABULATION
+0x0A	0x000A	#	LINE FEED
+0x0B	0x000B	#	VERTICAL TABULATION
+0x0C	0x000C	#	FORM FEED
+0x0D	0x000D	#	CARRIAGE RETURN
+0x0E	0x000E	#	SHIFT OUT
+0x0F	0x000F	#	SHIFT IN
+0x10	0x0010	#	DATA LINK ESCAPE
+0x11	0x0011	#	DEVICE CONTROL ONE
+0x12	0x0012	#	DEVICE CONTROL TWO
+0x13	0x0013	#	DEVICE CONTROL THREE
+0x14	0x0014	#	DEVICE CONTROL FOUR
+0x15	0x0015	#	NEGATIVE ACKNOWLEDGE
+0x16	0x0016	#	SYNCHRONOUS IDLE
+0x17	0x0017	#	END OF TRANSMISSION BLOCK
+0x18	0x0018	#	CANCEL
+0x19	0x0019	#	END OF MEDIUM
+0x1A	0x001A	#	SUBSTITUTE
+0x1B	0x001B	#	ESCAPE
+0x1C	0x001C	#	FILE SEPARATOR
+0x1D	0x001D	#	GROUP SEPARATOR
+0x1E	0x001E	#	RECORD SEPARATOR
+0x1F	0x001F	#	UNIT SEPARATOR
+0x20	0x0020	#	SPACE
+0x21	0x0021	#	EXCLAMATION MARK
+0x22	0x0022	#	QUOTATION MARK
+0x23	0x0023	#	NUMBER SIGN
+0x24	0x0024	#	DOLLAR SIGN
+0x25	0x0025	#	PERCENT SIGN
+0x26	0x0026	#	AMPERSAND
+0x27	0x0027	#	APOSTROPHE
+0x28	0x0028	#	LEFT PARENTHESIS
+0x29	0x0029	#	RIGHT PARENTHESIS
+0x2A	0x002A	#	ASTERISK
+0x2B	0x002B	#	PLUS SIGN
+0x2C	0x002C	#	COMMA
+0x2D	0x002D	#	HYPHEN-MINUS
+0x2E	0x002E	#	FULL STOP
+0x2F	0x002F	#	SOLIDUS
+0x30	0x0030	#	DIGIT ZERO
+0x31	0x0031	#	DIGIT ONE
+0x32	0x0032	#	DIGIT TWO
+0x33	0x0033	#	DIGIT THREE
+0x34	0x0034	#	DIGIT FOUR
+0x35	0x0035	#	DIGIT FIVE
+0x36	0x0036	#	DIGIT SIX
+0x37	0x0037	#	DIGIT SEVEN
+0x38	0x0038	#	DIGIT EIGHT
+0x39	0x0039	#	DIGIT NINE
+0x3A	0x003A	#	COLON
+0x3B	0x003B	#	SEMICOLON
+0x3C	0x003C	#	LESS-THAN SIGN
+0x3D	0x003D	#	EQUALS SIGN
+0x3E	0x003E	#	GREATER-THAN SIGN
+0x3F	0x003F	#	QUESTION MARK
+0x40	0x0040	#	COMMERCIAL AT
+0x41	0x0041	#	LATIN CAPITAL LETTER A
+0x42	0x0042	#	LATIN CAPITAL LETTER B
+0x43	0x0043	#	LATIN CAPITAL LETTER C
+0x44	0x0044	#	LATIN CAPITAL LETTER D
+0x45	0x0045	#	LATIN CAPITAL LETTER E
+0x46	0x0046	#	LATIN CAPITAL LETTER F
+0x47	0x0047	#	LATIN CAPITAL LETTER G
+0x48	0x0048	#	LATIN CAPITAL LETTER H
+0x49	0x0049	#	LATIN CAPITAL LETTER I
+0x4A	0x004A	#	LATIN CAPITAL LETTER J
+0x4B	0x004B	#	LATIN CAPITAL LETTER K
+0x4C	0x004C	#	LATIN CAPITAL LETTER L
+0x4D	0x004D	#	LATIN CAPITAL LETTER M
+0x4E	0x004E	#	LATIN CAPITAL LETTER N
+0x4F	0x004F	#	LATIN CAPITAL LETTER O
+0x50	0x0050	#	LATIN CAPITAL LETTER P
+0x51	0x0051	#	LATIN CAPITAL LETTER Q
+0x52	0x0052	#	LATIN CAPITAL LETTER R
+0x53	0x0053	#	LATIN CAPITAL LETTER S
+0x54	0x0054	#	LATIN CAPITAL LETTER T
+0x55	0x0055	#	LATIN CAPITAL LETTER U
+0x56	0x0056	#	LATIN CAPITAL LETTER V
+0x57	0x0057	#	LATIN CAPITAL LETTER W
+0x58	0x0058	#	LATIN CAPITAL LETTER X
+0x59	0x0059	#	LATIN CAPITAL LETTER Y
+0x5A	0x005A	#	LATIN CAPITAL LETTER Z
+0x5B	0x005B	#	LEFT SQUARE BRACKET
+0x5C	0x005C	#	REVERSE SOLIDUS
+0x5D	0x005D	#	RIGHT SQUARE BRACKET
+0x5E	0x005E	#	CIRCUMFLEX ACCENT
+0x5F	0x005F	#	LOW LINE
+0x60	0x0060	#	GRAVE ACCENT
+0x61	0x0061	#	LATIN SMALL LETTER A
+0x62	0x0062	#	LATIN SMALL LETTER B
+0x63	0x0063	#	LATIN SMALL LETTER C
+0x64	0x0064	#	LATIN SMALL LETTER D
+0x65	0x0065	#	LATIN SMALL LETTER E
+0x66	0x0066	#	LATIN SMALL LETTER F
+0x67	0x0067	#	LATIN SMALL LETTER G
+0x68	0x0068	#	LATIN SMALL LETTER H
+0x69	0x0069	#	LATIN SMALL LETTER I
+0x6A	0x006A	#	LATIN SMALL LETTER J
+0x6B	0x006B	#	LATIN SMALL LETTER K
+0x6C	0x006C	#	LATIN SMALL LETTER L
+0x6D	0x006D	#	LATIN SMALL LETTER M
+0x6E	0x006E	#	LATIN SMALL LETTER N
+0x6F	0x006F	#	LATIN SMALL LETTER O
+0x70	0x0070	#	LATIN SMALL LETTER P
+0x71	0x0071	#	LATIN SMALL LETTER Q
+0x72	0x0072	#	LATIN SMALL LETTER R
+0x73	0x0073	#	LATIN SMALL LETTER S
+0x74	0x0074	#	LATIN SMALL LETTER T
+0x75	0x0075	#	LATIN SMALL LETTER U
+0x76	0x0076	#	LATIN SMALL LETTER V
+0x77	0x0077	#	LATIN SMALL LETTER W
+0x78	0x0078	#	LATIN SMALL LETTER X
+0x79	0x0079	#	LATIN SMALL LETTER Y
+0x7A	0x007A	#	LATIN SMALL LETTER Z
+0x7B	0x007B	#	LEFT CURLY BRACKET
+0x7C	0x007C	#	VERTICAL LINE
+0x7D	0x007D	#	RIGHT CURLY BRACKET
+0x7E	0x007E	#	TILDE
+0x7F	0x007F	#	DELETE
+0x80	0x0080	#	<control>
+0x81	0x0081	#	<control>
+0x82	0x0082	#	<control>
+0x83	0x0083	#	<control>
+0x84	0x0084	#	<control>
+0x85	0x0085	#	<control>
+0x86	0x0086	#	<control>
+0x87	0x0087	#	<control>
+0x88	0x0088	#	<control>
+0x89	0x0089	#	<control>
+0x8A	0x008A	#	<control>
+0x8B	0x008B	#	<control>
+0x8C	0x008C	#	<control>
+0x8D	0x008D	#	<control>
+0x8E	0x008E	#	<control>
+0x8F	0x008F	#	<control>
+0x90	0x0090	#	<control>
+0x91	0x0091	#	<control>
+0x92	0x0092	#	<control>
+0x93	0x0093	#	<control>
+0x94	0x0094	#	<control>
+0x95	0x0095	#	<control>
+0x96	0x0096	#	<control>
+0x97	0x0097	#	<control>
+0x98	0x0098	#	<control>
+0x99	0x0099	#	<control>
+0x9A	0x009A	#	<control>
+0x9B	0x009B	#	<control>
+0x9C	0x009C	#	<control>
+0x9D	0x009D	#	<control>
+0x9E	0x009E	#	<control>
+0x9F	0x009F	#	<control>
+0xA0	0x00A0	#	NO-BREAK SPACE
+0xA1	0x0104	#	LATIN CAPITAL LETTER A WITH OGONEK
+0xA2	0x0138	#	LATIN SMALL LETTER KRA
+0xA3	0x0156	#	LATIN CAPITAL LETTER R WITH CEDILLA
+0xA4	0x00A4	#	CURRENCY SIGN
+0xA5	0x0128	#	LATIN CAPITAL LETTER I WITH TILDE
+0xA6	0x013B	#	LATIN CAPITAL LETTER L WITH CEDILLA
+0xA7	0x00A7	#	SECTION SIGN
+0xA8	0x00A8	#	DIAERESIS
+0xA9	0x0160	#	LATIN CAPITAL LETTER S WITH CARON
+0xAA	0x0112	#	LATIN CAPITAL LETTER E WITH MACRON
+0xAB	0x0122	#	LATIN CAPITAL LETTER G WITH CEDILLA
+0xAC	0x0166	#	LATIN CAPITAL LETTER T WITH STROKE
+0xAD	0x00AD	#	SOFT HYPHEN
+0xAE	0x017D	#	LATIN CAPITAL LETTER Z WITH CARON
+0xAF	0x00AF	#	MACRON
+0xB0	0x00B0	#	DEGREE SIGN
+0xB1	0x0105	#	LATIN SMALL LETTER A WITH OGONEK
+0xB2	0x02DB	#	OGONEK
+0xB3	0x0157	#	LATIN SMALL LETTER R WITH CEDILLA
+0xB4	0x00B4	#	ACUTE ACCENT
+0xB5	0x0129	#	LATIN SMALL LETTER I WITH TILDE
+0xB6	0x013C	#	LATIN SMALL LETTER L WITH CEDILLA
+0xB7	0x02C7	#	CARON
+0xB8	0x00B8	#	CEDILLA
+0xB9	0x0161	#	LATIN SMALL LETTER S WITH CARON
+0xBA	0x0113	#	LATIN SMALL LETTER E WITH MACRON
+0xBB	0x0123	#	LATIN SMALL LETTER G WITH CEDILLA
+0xBC	0x0167	#	LATIN SMALL LETTER T WITH STROKE
+0xBD	0x014A	#	LATIN CAPITAL LETTER ENG
+0xBE	0x017E	#	LATIN SMALL LETTER Z WITH CARON
+0xBF	0x014B	#	LATIN SMALL LETTER ENG
+0xC0	0x0100	#	LATIN CAPITAL LETTER A WITH MACRON
+0xC1	0x00C1	#	LATIN CAPITAL LETTER A WITH ACUTE
+0xC2	0x00C2	#	LATIN CAPITAL LETTER A WITH CIRCUMFLEX
+0xC3	0x00C3	#	LATIN CAPITAL LETTER A WITH TILDE
+0xC4	0x00C4	#	LATIN CAPITAL LETTER A WITH DIAERESIS
+0xC5	0x00C5	#	LATIN CAPITAL LETTER A WITH RING ABOVE
+0xC6	0x00C6	#	LATIN CAPITAL LETTER AE
+0xC7	0x012E	#	LATIN CAPITAL LETTER I WITH OGONEK
+0xC8	0x010C	#	LATIN CAPITAL LETTER C WITH CARON
+0xC9	0x00C9	#	LATIN CAPITAL LETTER E WITH ACUTE
+0xCA	0x0118	#	LATIN CAPITAL LETTER E WITH OGONEK
+0xCB	0x00CB	#	LATIN CAPITAL LETTER E WITH DIAERESIS
+0xCC	0x0116	#	LATIN CAPITAL LETTER E WITH DOT ABOVE
+0xCD	0x00CD	#	LATIN CAPITAL LETTER I WITH ACUTE
+0xCE	0x00CE	#	LATIN CAPITAL LETTER I WITH CIRCUMFLEX
+0xCF	0x012A	#	LATIN CAPITAL LETTER I WITH MACRON
+0xD0	0x0110	#	LATIN CAPITAL LETTER D WITH STROKE
+0xD1	0x0145	#	LATIN CAPITAL LETTER N WITH CEDILLA
+0xD2	0x014C	#	LATIN CAPITAL LETTER O WITH MACRON
+0xD3	0x0136	#	LATIN CAPITAL LETTER K WITH CEDILLA
+0xD4	0x00D4	#	LATIN CAPITAL LETTER O WITH CIRCUMFLEX
+0xD5	0x00D5	#	LATIN CAPITAL LETTER O WITH TILDE
+0xD6	0x00D6	#	LATIN CAPITAL LETTER O WITH DIAERESIS
+0xD7	0x00D7	#	MULTIPLICATION SIGN
+0xD8	0x00D8	#	LATIN CAPITAL LETTER O WITH STROKE
+0xD9	0x0172	#	LATIN CAPITAL LETTER U WITH OGONEK
+0xDA	0x00DA	#	LATIN CAPITAL LETTER U WITH ACUTE
+0xDB	0x00DB	#	LATIN CAPITAL LETTER U WITH CIRCUMFLEX
+0xDC	0x00DC	#	LATIN CAPITAL LETTER U WITH DIAERESIS
+0xDD	0x0168	#	LATIN CAPITAL LETTER U WITH TILDE
+0xDE	0x016A	#	LATIN CAPITAL LETTER U WITH MACRON
+0xDF	0x00DF	#	LATIN SMALL LETTER SHARP S
+0xE0	0x0101	#	LATIN SMALL LETTER A WITH MACRON
+0xE1	0x00E1	#	LATIN SMALL LETTER A WITH ACUTE
+0xE2	0x00E2	#	LATIN SMALL LETTER A WITH CIRCUMFLEX
+0xE3	0x00E3	#	LATIN SMALL LETTER A WITH TILDE
+0xE4	0x00E4	#	LATIN SMALL LETTER A WITH DIAERESIS
+0xE5	0x00E5	#	LATIN SMALL LETTER A WITH RING ABOVE
+0xE6	0x00E6	#	LATIN SMALL LETTER AE
+0xE7	0x012F	#	LATIN SMALL LETTER I WITH OGONEK
+0xE8	0x010D	#	LATIN SMALL LETTER C WITH CARON
+0xE9	0x00E9	#	LATIN SMALL LETTER E WITH ACUTE
+0xEA	0x0119	#	LATIN SMALL LETTER E WITH OGONEK
+0xEB	0x00EB	#	LATIN SMALL LETTER E WITH DIAERESIS
+0xEC	0x0117	#	LATIN SMALL LETTER E WITH DOT ABOVE
+0xED	0x00ED	#	LATIN SMALL LETTER I WITH ACUTE
+0xEE	0x00EE	#	LATIN SMALL LETTER I WITH CIRCUMFLEX
+0xEF	0x012B	#	LATIN SMALL LETTER I WITH MACRON
+0xF0	0x0111	#	LATIN SMALL LETTER D WITH STROKE
+0xF1	0x0146	#	LATIN SMALL LETTER N WITH CEDILLA
+0xF2	0x014D	#	LATIN SMALL LETTER O WITH MACRON
+0xF3	0x0137	#	LATIN SMALL LETTER K WITH CEDILLA
+0xF4	0x00F4	#	LATIN SMALL LETTER O WITH CIRCUMFLEX
+0xF5	0x00F5	#	LATIN SMALL LETTER O WITH TILDE
+0xF6	0x00F6	#	LATIN SMALL LETTER O WITH DIAERESIS
+0xF7	0x00F7	#	DIVISION SIGN
+0xF8	0x00F8	#	LATIN SMALL LETTER O WITH STROKE
+0xF9	0x0173	#	LATIN SMALL LETTER U WITH OGONEK
+0xFA	0x00FA	#	LATIN SMALL LETTER U WITH ACUTE
+0xFB	0x00FB	#	LATIN SMALL LETTER U WITH CIRCUMFLEX
+0xFC	0x00FC	#	LATIN SMALL LETTER U WITH DIAERESIS
+0xFD	0x0169	#	LATIN SMALL LETTER U WITH TILDE
+0xFE	0x016B	#	LATIN SMALL LETTER U WITH MACRON
+0xFF	0x02D9	#	DOT ABOVE
diff --git a/tools/encoding/iso8859-5.txt b/tools/encoding/iso8859-5.txt
new file mode 100644
index 0000000..a7ed1ce
--- /dev/null
+++ b/tools/encoding/iso8859-5.txt
@@ -0,0 +1,303 @@
+#
+#	Name:             ISO 8859-5:1999 to Unicode
+#	Unicode version:  3.0
+#	Table version:    1.0
+#	Table format:     Format A
+#	Date:             1999 July 27
+#	Authors:          Ken Whistler <kenw@sybase.com>
+#
+#	Copyright (c) 1991-1999 Unicode, Inc.  All Rights reserved.
+#
+#	This file is provided as-is by Unicode, Inc. (The Unicode Consortium).
+#	No claims are made as to fitness for any particular purpose.  No
+#	warranties of any kind are expressed or implied.  The recipient
+#	agrees to determine applicability of information provided.  If this
+#	file has been provided on optical media by Unicode, Inc., the sole
+#	remedy for any claim will be exchange of defective media within 90
+#	days of receipt.
+#
+#	Unicode, Inc. hereby grants the right to freely use the information
+#	supplied in this file in the creation of products supporting the
+#	Unicode Standard, and to make copies of this file in any form for
+#	internal or external distribution as long as this notice remains
+#	attached.
+#
+#	General notes:
+#
+#	This table contains the data the Unicode Consortium has on how
+#       ISO/IEC 8859-5:1999 characters map into Unicode.
+#
+#	Format:  Three tab-separated columns
+#		 Column #1 is the ISO/IEC 8859-5 code (in hex as 0xXX)
+#		 Column #2 is the Unicode (in hex as 0xXXXX)
+#		 Column #3 the Unicode name (follows a comment sign, '#')
+#
+#	The entries are in ISO/IEC 8859-5 order.
+#
+#	Version history
+#	1.0 version updates 0.1 version by adding mappings for all
+#	control characters.
+#
+#	Updated versions of this file may be found in:
+#		<ftp://ftp.unicode.org/Public/MAPPINGS/>
+#
+#	Any comments or problems, contact <errata@unicode.org>
+#	Please note that <errata@unicode.org> is an archival address;
+#	notices will be checked, but do not expect an immediate response.
+#
+0x00	0x0000	#	NULL
+0x01	0x0001	#	START OF HEADING
+0x02	0x0002	#	START OF TEXT
+0x03	0x0003	#	END OF TEXT
+0x04	0x0004	#	END OF TRANSMISSION
+0x05	0x0005	#	ENQUIRY
+0x06	0x0006	#	ACKNOWLEDGE
+0x07	0x0007	#	BELL
+0x08	0x0008	#	BACKSPACE
+0x09	0x0009	#	HORIZONTAL TABULATION
+0x0A	0x000A	#	LINE FEED
+0x0B	0x000B	#	VERTICAL TABULATION
+0x0C	0x000C	#	FORM FEED
+0x0D	0x000D	#	CARRIAGE RETURN
+0x0E	0x000E	#	SHIFT OUT
+0x0F	0x000F	#	SHIFT IN
+0x10	0x0010	#	DATA LINK ESCAPE
+0x11	0x0011	#	DEVICE CONTROL ONE
+0x12	0x0012	#	DEVICE CONTROL TWO
+0x13	0x0013	#	DEVICE CONTROL THREE
+0x14	0x0014	#	DEVICE CONTROL FOUR
+0x15	0x0015	#	NEGATIVE ACKNOWLEDGE
+0x16	0x0016	#	SYNCHRONOUS IDLE
+0x17	0x0017	#	END OF TRANSMISSION BLOCK
+0x18	0x0018	#	CANCEL
+0x19	0x0019	#	END OF MEDIUM
+0x1A	0x001A	#	SUBSTITUTE
+0x1B	0x001B	#	ESCAPE
+0x1C	0x001C	#	FILE SEPARATOR
+0x1D	0x001D	#	GROUP SEPARATOR
+0x1E	0x001E	#	RECORD SEPARATOR
+0x1F	0x001F	#	UNIT SEPARATOR
+0x20	0x0020	#	SPACE
+0x21	0x0021	#	EXCLAMATION MARK
+0x22	0x0022	#	QUOTATION MARK
+0x23	0x0023	#	NUMBER SIGN
+0x24	0x0024	#	DOLLAR SIGN
+0x25	0x0025	#	PERCENT SIGN
+0x26	0x0026	#	AMPERSAND
+0x27	0x0027	#	APOSTROPHE
+0x28	0x0028	#	LEFT PARENTHESIS
+0x29	0x0029	#	RIGHT PARENTHESIS
+0x2A	0x002A	#	ASTERISK
+0x2B	0x002B	#	PLUS SIGN
+0x2C	0x002C	#	COMMA
+0x2D	0x002D	#	HYPHEN-MINUS
+0x2E	0x002E	#	FULL STOP
+0x2F	0x002F	#	SOLIDUS
+0x30	0x0030	#	DIGIT ZERO
+0x31	0x0031	#	DIGIT ONE
+0x32	0x0032	#	DIGIT TWO
+0x33	0x0033	#	DIGIT THREE
+0x34	0x0034	#	DIGIT FOUR
+0x35	0x0035	#	DIGIT FIVE
+0x36	0x0036	#	DIGIT SIX
+0x37	0x0037	#	DIGIT SEVEN
+0x38	0x0038	#	DIGIT EIGHT
+0x39	0x0039	#	DIGIT NINE
+0x3A	0x003A	#	COLON
+0x3B	0x003B	#	SEMICOLON
+0x3C	0x003C	#	LESS-THAN SIGN
+0x3D	0x003D	#	EQUALS SIGN
+0x3E	0x003E	#	GREATER-THAN SIGN
+0x3F	0x003F	#	QUESTION MARK
+0x40	0x0040	#	COMMERCIAL AT
+0x41	0x0041	#	LATIN CAPITAL LETTER A
+0x42	0x0042	#	LATIN CAPITAL LETTER B
+0x43	0x0043	#	LATIN CAPITAL LETTER C
+0x44	0x0044	#	LATIN CAPITAL LETTER D
+0x45	0x0045	#	LATIN CAPITAL LETTER E
+0x46	0x0046	#	LATIN CAPITAL LETTER F
+0x47	0x0047	#	LATIN CAPITAL LETTER G
+0x48	0x0048	#	LATIN CAPITAL LETTER H
+0x49	0x0049	#	LATIN CAPITAL LETTER I
+0x4A	0x004A	#	LATIN CAPITAL LETTER J
+0x4B	0x004B	#	LATIN CAPITAL LETTER K
+0x4C	0x004C	#	LATIN CAPITAL LETTER L
+0x4D	0x004D	#	LATIN CAPITAL LETTER M
+0x4E	0x004E	#	LATIN CAPITAL LETTER N
+0x4F	0x004F	#	LATIN CAPITAL LETTER O
+0x50	0x0050	#	LATIN CAPITAL LETTER P
+0x51	0x0051	#	LATIN CAPITAL LETTER Q
+0x52	0x0052	#	LATIN CAPITAL LETTER R
+0x53	0x0053	#	LATIN CAPITAL LETTER S
+0x54	0x0054	#	LATIN CAPITAL LETTER T
+0x55	0x0055	#	LATIN CAPITAL LETTER U
+0x56	0x0056	#	LATIN CAPITAL LETTER V
+0x57	0x0057	#	LATIN CAPITAL LETTER W
+0x58	0x0058	#	LATIN CAPITAL LETTER X
+0x59	0x0059	#	LATIN CAPITAL LETTER Y
+0x5A	0x005A	#	LATIN CAPITAL LETTER Z
+0x5B	0x005B	#	LEFT SQUARE BRACKET
+0x5C	0x005C	#	REVERSE SOLIDUS
+0x5D	0x005D	#	RIGHT SQUARE BRACKET
+0x5E	0x005E	#	CIRCUMFLEX ACCENT
+0x5F	0x005F	#	LOW LINE
+0x60	0x0060	#	GRAVE ACCENT
+0x61	0x0061	#	LATIN SMALL LETTER A
+0x62	0x0062	#	LATIN SMALL LETTER B
+0x63	0x0063	#	LATIN SMALL LETTER C
+0x64	0x0064	#	LATIN SMALL LETTER D
+0x65	0x0065	#	LATIN SMALL LETTER E
+0x66	0x0066	#	LATIN SMALL LETTER F
+0x67	0x0067	#	LATIN SMALL LETTER G
+0x68	0x0068	#	LATIN SMALL LETTER H
+0x69	0x0069	#	LATIN SMALL LETTER I
+0x6A	0x006A	#	LATIN SMALL LETTER J
+0x6B	0x006B	#	LATIN SMALL LETTER K
+0x6C	0x006C	#	LATIN SMALL LETTER L
+0x6D	0x006D	#	LATIN SMALL LETTER M
+0x6E	0x006E	#	LATIN SMALL LETTER N
+0x6F	0x006F	#	LATIN SMALL LETTER O
+0x70	0x0070	#	LATIN SMALL LETTER P
+0x71	0x0071	#	LATIN SMALL LETTER Q
+0x72	0x0072	#	LATIN SMALL LETTER R
+0x73	0x0073	#	LATIN SMALL LETTER S
+0x74	0x0074	#	LATIN SMALL LETTER T
+0x75	0x0075	#	LATIN SMALL LETTER U
+0x76	0x0076	#	LATIN SMALL LETTER V
+0x77	0x0077	#	LATIN SMALL LETTER W
+0x78	0x0078	#	LATIN SMALL LETTER X
+0x79	0x0079	#	LATIN SMALL LETTER Y
+0x7A	0x007A	#	LATIN SMALL LETTER Z
+0x7B	0x007B	#	LEFT CURLY BRACKET
+0x7C	0x007C	#	VERTICAL LINE
+0x7D	0x007D	#	RIGHT CURLY BRACKET
+0x7E	0x007E	#	TILDE
+0x7F	0x007F	#	DELETE
+0x80	0x0080	#	<control>
+0x81	0x0081	#	<control>
+0x82	0x0082	#	<control>
+0x83	0x0083	#	<control>
+0x84	0x0084	#	<control>
+0x85	0x0085	#	<control>
+0x86	0x0086	#	<control>
+0x87	0x0087	#	<control>
+0x88	0x0088	#	<control>
+0x89	0x0089	#	<control>
+0x8A	0x008A	#	<control>
+0x8B	0x008B	#	<control>
+0x8C	0x008C	#	<control>
+0x8D	0x008D	#	<control>
+0x8E	0x008E	#	<control>
+0x8F	0x008F	#	<control>
+0x90	0x0090	#	<control>
+0x91	0x0091	#	<control>
+0x92	0x0092	#	<control>
+0x93	0x0093	#	<control>
+0x94	0x0094	#	<control>
+0x95	0x0095	#	<control>
+0x96	0x0096	#	<control>
+0x97	0x0097	#	<control>
+0x98	0x0098	#	<control>
+0x99	0x0099	#	<control>
+0x9A	0x009A	#	<control>
+0x9B	0x009B	#	<control>
+0x9C	0x009C	#	<control>
+0x9D	0x009D	#	<control>
+0x9E	0x009E	#	<control>
+0x9F	0x009F	#	<control>
+0xA0	0x00A0	#	NO-BREAK SPACE
+0xA1	0x0401	#	CYRILLIC CAPITAL LETTER IO
+0xA2	0x0402	#	CYRILLIC CAPITAL LETTER DJE
+0xA3	0x0403	#	CYRILLIC CAPITAL LETTER GJE
+0xA4	0x0404	#	CYRILLIC CAPITAL LETTER UKRAINIAN IE
+0xA5	0x0405	#	CYRILLIC CAPITAL LETTER DZE
+0xA6	0x0406	#	CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I
+0xA7	0x0407	#	CYRILLIC CAPITAL LETTER YI
+0xA8	0x0408	#	CYRILLIC CAPITAL LETTER JE
+0xA9	0x0409	#	CYRILLIC CAPITAL LETTER LJE
+0xAA	0x040A	#	CYRILLIC CAPITAL LETTER NJE
+0xAB	0x040B	#	CYRILLIC CAPITAL LETTER TSHE
+0xAC	0x040C	#	CYRILLIC CAPITAL LETTER KJE
+0xAD	0x00AD	#	SOFT HYPHEN
+0xAE	0x040E	#	CYRILLIC CAPITAL LETTER SHORT U
+0xAF	0x040F	#	CYRILLIC CAPITAL LETTER DZHE
+0xB0	0x0410	#	CYRILLIC CAPITAL LETTER A
+0xB1	0x0411	#	CYRILLIC CAPITAL LETTER BE
+0xB2	0x0412	#	CYRILLIC CAPITAL LETTER VE
+0xB3	0x0413	#	CYRILLIC CAPITAL LETTER GHE
+0xB4	0x0414	#	CYRILLIC CAPITAL LETTER DE
+0xB5	0x0415	#	CYRILLIC CAPITAL LETTER IE
+0xB6	0x0416	#	CYRILLIC CAPITAL LETTER ZHE
+0xB7	0x0417	#	CYRILLIC CAPITAL LETTER ZE
+0xB8	0x0418	#	CYRILLIC CAPITAL LETTER I
+0xB9	0x0419	#	CYRILLIC CAPITAL LETTER SHORT I
+0xBA	0x041A	#	CYRILLIC CAPITAL LETTER KA
+0xBB	0x041B	#	CYRILLIC CAPITAL LETTER EL
+0xBC	0x041C	#	CYRILLIC CAPITAL LETTER EM
+0xBD	0x041D	#	CYRILLIC CAPITAL LETTER EN
+0xBE	0x041E	#	CYRILLIC CAPITAL LETTER O
+0xBF	0x041F	#	CYRILLIC CAPITAL LETTER PE
+0xC0	0x0420	#	CYRILLIC CAPITAL LETTER ER
+0xC1	0x0421	#	CYRILLIC CAPITAL LETTER ES
+0xC2	0x0422	#	CYRILLIC CAPITAL LETTER TE
+0xC3	0x0423	#	CYRILLIC CAPITAL LETTER U
+0xC4	0x0424	#	CYRILLIC CAPITAL LETTER EF
+0xC5	0x0425	#	CYRILLIC CAPITAL LETTER HA
+0xC6	0x0426	#	CYRILLIC CAPITAL LETTER TSE
+0xC7	0x0427	#	CYRILLIC CAPITAL LETTER CHE
+0xC8	0x0428	#	CYRILLIC CAPITAL LETTER SHA
+0xC9	0x0429	#	CYRILLIC CAPITAL LETTER SHCHA
+0xCA	0x042A	#	CYRILLIC CAPITAL LETTER HARD SIGN
+0xCB	0x042B	#	CYRILLIC CAPITAL LETTER YERU
+0xCC	0x042C	#	CYRILLIC CAPITAL LETTER SOFT SIGN
+0xCD	0x042D	#	CYRILLIC CAPITAL LETTER E
+0xCE	0x042E	#	CYRILLIC CAPITAL LETTER YU
+0xCF	0x042F	#	CYRILLIC CAPITAL LETTER YA
+0xD0	0x0430	#	CYRILLIC SMALL LETTER A
+0xD1	0x0431	#	CYRILLIC SMALL LETTER BE
+0xD2	0x0432	#	CYRILLIC SMALL LETTER VE
+0xD3	0x0433	#	CYRILLIC SMALL LETTER GHE
+0xD4	0x0434	#	CYRILLIC SMALL LETTER DE
+0xD5	0x0435	#	CYRILLIC SMALL LETTER IE
+0xD6	0x0436	#	CYRILLIC SMALL LETTER ZHE
+0xD7	0x0437	#	CYRILLIC SMALL LETTER ZE
+0xD8	0x0438	#	CYRILLIC SMALL LETTER I
+0xD9	0x0439	#	CYRILLIC SMALL LETTER SHORT I
+0xDA	0x043A	#	CYRILLIC SMALL LETTER KA
+0xDB	0x043B	#	CYRILLIC SMALL LETTER EL
+0xDC	0x043C	#	CYRILLIC SMALL LETTER EM
+0xDD	0x043D	#	CYRILLIC SMALL LETTER EN
+0xDE	0x043E	#	CYRILLIC SMALL LETTER O
+0xDF	0x043F	#	CYRILLIC SMALL LETTER PE
+0xE0	0x0440	#	CYRILLIC SMALL LETTER ER
+0xE1	0x0441	#	CYRILLIC SMALL LETTER ES
+0xE2	0x0442	#	CYRILLIC SMALL LETTER TE
+0xE3	0x0443	#	CYRILLIC SMALL LETTER U
+0xE4	0x0444	#	CYRILLIC SMALL LETTER EF
+0xE5	0x0445	#	CYRILLIC SMALL LETTER HA
+0xE6	0x0446	#	CYRILLIC SMALL LETTER TSE
+0xE7	0x0447	#	CYRILLIC SMALL LETTER CHE
+0xE8	0x0448	#	CYRILLIC SMALL LETTER SHA
+0xE9	0x0449	#	CYRILLIC SMALL LETTER SHCHA
+0xEA	0x044A	#	CYRILLIC SMALL LETTER HARD SIGN
+0xEB	0x044B	#	CYRILLIC SMALL LETTER YERU
+0xEC	0x044C	#	CYRILLIC SMALL LETTER SOFT SIGN
+0xED	0x044D	#	CYRILLIC SMALL LETTER E
+0xEE	0x044E	#	CYRILLIC SMALL LETTER YU
+0xEF	0x044F	#	CYRILLIC SMALL LETTER YA
+0xF0	0x2116	#	NUMERO SIGN
+0xF1	0x0451	#	CYRILLIC SMALL LETTER IO
+0xF2	0x0452	#	CYRILLIC SMALL LETTER DJE
+0xF3	0x0453	#	CYRILLIC SMALL LETTER GJE
+0xF4	0x0454	#	CYRILLIC SMALL LETTER UKRAINIAN IE
+0xF5	0x0455	#	CYRILLIC SMALL LETTER DZE
+0xF6	0x0456	#	CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I
+0xF7	0x0457	#	CYRILLIC SMALL LETTER YI
+0xF8	0x0458	#	CYRILLIC SMALL LETTER JE
+0xF9	0x0459	#	CYRILLIC SMALL LETTER LJE
+0xFA	0x045A	#	CYRILLIC SMALL LETTER NJE
+0xFB	0x045B	#	CYRILLIC SMALL LETTER TSHE
+0xFC	0x045C	#	CYRILLIC SMALL LETTER KJE
+0xFD	0x00A7	#	SECTION SIGN
+0xFE	0x045E	#	CYRILLIC SMALL LETTER SHORT U
+0xFF	0x045F	#	CYRILLIC SMALL LETTER DZHE
diff --git a/tools/encoding/iso8859-6.txt b/tools/encoding/iso8859-6.txt
new file mode 100644
index 0000000..69ac7f5
--- /dev/null
+++ b/tools/encoding/iso8859-6.txt
@@ -0,0 +1,260 @@
+#
+#	Name:             ISO 8859-6:1999 to Unicode
+#	Unicode version:  3.0
+#	Table version:    1.0
+#	Table format:     Format A
+#	Date:             1999 July 27
+#	Authors:          Ken Whistler <kenw@sybase.com>
+#
+#	Copyright (c) 1991-1999 Unicode, Inc.  All Rights reserved.
+#
+#	This file is provided as-is by Unicode, Inc. (The Unicode Consortium).
+#	No claims are made as to fitness for any particular purpose.  No
+#	warranties of any kind are expressed or implied.  The recipient
+#	agrees to determine applicability of information provided.  If this
+#	file has been provided on optical media by Unicode, Inc., the sole
+#	remedy for any claim will be exchange of defective media within 90
+#	days of receipt.
+#
+#	Unicode, Inc. hereby grants the right to freely use the information
+#	supplied in this file in the creation of products supporting the
+#	Unicode Standard, and to make copies of this file in any form for
+#	internal or external distribution as long as this notice remains
+#	attached.
+#
+#	General notes:
+#
+#	This table contains the data the Unicode Consortium has on how
+#       ISO/IEC 8859-6:1999 characters map into Unicode.
+#
+#	Format:  Three tab-separated columns
+#		 Column #1 is the ISO/IEC 8859-6 code (in hex as 0xXX)
+#		 Column #2 is the Unicode (in hex as 0xXXXX)
+#		 Column #3 the Unicode name (follows a comment sign, '#')
+#
+#	The entries are in ISO/IEC 8859-6 order.
+#
+#	Version history
+#	1.0 version updates 0.1 version by adding mappings for all
+#	control characters.
+#	0x30..0x39 remapped to the ASCII digits (U+0030..U+0039) instead
+#	of the Arabic digits (U+0660..U+0669).
+#
+#	Updated versions of this file may be found in:
+#		<ftp://ftp.unicode.org/Public/MAPPINGS/>
+#
+#	Any comments or problems, contact <errata@unicode.org>
+#	Please note that <errata@unicode.org> is an archival address;
+#	notices will be checked, but do not expect an immediate response.
+#
+0x00	0x0000	#	NULL
+0x01	0x0001	#	START OF HEADING
+0x02	0x0002	#	START OF TEXT
+0x03	0x0003	#	END OF TEXT
+0x04	0x0004	#	END OF TRANSMISSION
+0x05	0x0005	#	ENQUIRY
+0x06	0x0006	#	ACKNOWLEDGE
+0x07	0x0007	#	BELL
+0x08	0x0008	#	BACKSPACE
+0x09	0x0009	#	HORIZONTAL TABULATION
+0x0A	0x000A	#	LINE FEED
+0x0B	0x000B	#	VERTICAL TABULATION
+0x0C	0x000C	#	FORM FEED
+0x0D	0x000D	#	CARRIAGE RETURN
+0x0E	0x000E	#	SHIFT OUT
+0x0F	0x000F	#	SHIFT IN
+0x10	0x0010	#	DATA LINK ESCAPE
+0x11	0x0011	#	DEVICE CONTROL ONE
+0x12	0x0012	#	DEVICE CONTROL TWO
+0x13	0x0013	#	DEVICE CONTROL THREE
+0x14	0x0014	#	DEVICE CONTROL FOUR
+0x15	0x0015	#	NEGATIVE ACKNOWLEDGE
+0x16	0x0016	#	SYNCHRONOUS IDLE
+0x17	0x0017	#	END OF TRANSMISSION BLOCK
+0x18	0x0018	#	CANCEL
+0x19	0x0019	#	END OF MEDIUM
+0x1A	0x001A	#	SUBSTITUTE
+0x1B	0x001B	#	ESCAPE
+0x1C	0x001C	#	FILE SEPARATOR
+0x1D	0x001D	#	GROUP SEPARATOR
+0x1E	0x001E	#	RECORD SEPARATOR
+0x1F	0x001F	#	UNIT SEPARATOR
+0x20	0x0020	#	SPACE
+0x21	0x0021	#	EXCLAMATION MARK
+0x22	0x0022	#	QUOTATION MARK
+0x23	0x0023	#	NUMBER SIGN
+0x24	0x0024	#	DOLLAR SIGN
+0x25	0x0025	#	PERCENT SIGN
+0x26	0x0026	#	AMPERSAND
+0x27	0x0027	#	APOSTROPHE
+0x28	0x0028	#	LEFT PARENTHESIS
+0x29	0x0029	#	RIGHT PARENTHESIS
+0x2A	0x002A	#	ASTERISK
+0x2B	0x002B	#	PLUS SIGN
+0x2C	0x002C	#	COMMA
+0x2D	0x002D	#	HYPHEN-MINUS
+0x2E	0x002E	#	FULL STOP
+0x2F	0x002F	#	SOLIDUS
+0x30	0x0030	#	DIGIT ZERO
+0x31	0x0031	#	DIGIT ONE
+0x32	0x0032	#	DIGIT TWO
+0x33	0x0033	#	DIGIT THREE
+0x34	0x0034	#	DIGIT FOUR
+0x35	0x0035	#	DIGIT FIVE
+0x36	0x0036	#	DIGIT SIX
+0x37	0x0037	#	DIGIT SEVEN
+0x38	0x0038	#	DIGIT EIGHT
+0x39	0x0039	#	DIGIT NINE
+0x3A	0x003A	#	COLON
+0x3B	0x003B	#	SEMICOLON
+0x3C	0x003C	#	LESS-THAN SIGN
+0x3D	0x003D	#	EQUALS SIGN
+0x3E	0x003E	#	GREATER-THAN SIGN
+0x3F	0x003F	#	QUESTION MARK
+0x40	0x0040	#	COMMERCIAL AT
+0x41	0x0041	#	LATIN CAPITAL LETTER A
+0x42	0x0042	#	LATIN CAPITAL LETTER B
+0x43	0x0043	#	LATIN CAPITAL LETTER C
+0x44	0x0044	#	LATIN CAPITAL LETTER D
+0x45	0x0045	#	LATIN CAPITAL LETTER E
+0x46	0x0046	#	LATIN CAPITAL LETTER F
+0x47	0x0047	#	LATIN CAPITAL LETTER G
+0x48	0x0048	#	LATIN CAPITAL LETTER H
+0x49	0x0049	#	LATIN CAPITAL LETTER I
+0x4A	0x004A	#	LATIN CAPITAL LETTER J
+0x4B	0x004B	#	LATIN CAPITAL LETTER K
+0x4C	0x004C	#	LATIN CAPITAL LETTER L
+0x4D	0x004D	#	LATIN CAPITAL LETTER M
+0x4E	0x004E	#	LATIN CAPITAL LETTER N
+0x4F	0x004F	#	LATIN CAPITAL LETTER O
+0x50	0x0050	#	LATIN CAPITAL LETTER P
+0x51	0x0051	#	LATIN CAPITAL LETTER Q
+0x52	0x0052	#	LATIN CAPITAL LETTER R
+0x53	0x0053	#	LATIN CAPITAL LETTER S
+0x54	0x0054	#	LATIN CAPITAL LETTER T
+0x55	0x0055	#	LATIN CAPITAL LETTER U
+0x56	0x0056	#	LATIN CAPITAL LETTER V
+0x57	0x0057	#	LATIN CAPITAL LETTER W
+0x58	0x0058	#	LATIN CAPITAL LETTER X
+0x59	0x0059	#	LATIN CAPITAL LETTER Y
+0x5A	0x005A	#	LATIN CAPITAL LETTER Z
+0x5B	0x005B	#	LEFT SQUARE BRACKET
+0x5C	0x005C	#	REVERSE SOLIDUS
+0x5D	0x005D	#	RIGHT SQUARE BRACKET
+0x5E	0x005E	#	CIRCUMFLEX ACCENT
+0x5F	0x005F	#	LOW LINE
+0x60	0x0060	#	GRAVE ACCENT
+0x61	0x0061	#	LATIN SMALL LETTER A
+0x62	0x0062	#	LATIN SMALL LETTER B
+0x63	0x0063	#	LATIN SMALL LETTER C
+0x64	0x0064	#	LATIN SMALL LETTER D
+0x65	0x0065	#	LATIN SMALL LETTER E
+0x66	0x0066	#	LATIN SMALL LETTER F
+0x67	0x0067	#	LATIN SMALL LETTER G
+0x68	0x0068	#	LATIN SMALL LETTER H
+0x69	0x0069	#	LATIN SMALL LETTER I
+0x6A	0x006A	#	LATIN SMALL LETTER J
+0x6B	0x006B	#	LATIN SMALL LETTER K
+0x6C	0x006C	#	LATIN SMALL LETTER L
+0x6D	0x006D	#	LATIN SMALL LETTER M
+0x6E	0x006E	#	LATIN SMALL LETTER N
+0x6F	0x006F	#	LATIN SMALL LETTER O
+0x70	0x0070	#	LATIN SMALL LETTER P
+0x71	0x0071	#	LATIN SMALL LETTER Q
+0x72	0x0072	#	LATIN SMALL LETTER R
+0x73	0x0073	#	LATIN SMALL LETTER S
+0x74	0x0074	#	LATIN SMALL LETTER T
+0x75	0x0075	#	LATIN SMALL LETTER U
+0x76	0x0076	#	LATIN SMALL LETTER V
+0x77	0x0077	#	LATIN SMALL LETTER W
+0x78	0x0078	#	LATIN SMALL LETTER X
+0x79	0x0079	#	LATIN SMALL LETTER Y
+0x7A	0x007A	#	LATIN SMALL LETTER Z
+0x7B	0x007B	#	LEFT CURLY BRACKET
+0x7C	0x007C	#	VERTICAL LINE
+0x7D	0x007D	#	RIGHT CURLY BRACKET
+0x7E	0x007E	#	TILDE
+0x7F	0x007F	#	DELETE
+0x80	0x0080	#	<control>
+0x81	0x0081	#	<control>
+0x82	0x0082	#	<control>
+0x83	0x0083	#	<control>
+0x84	0x0084	#	<control>
+0x85	0x0085	#	<control>
+0x86	0x0086	#	<control>
+0x87	0x0087	#	<control>
+0x88	0x0088	#	<control>
+0x89	0x0089	#	<control>
+0x8A	0x008A	#	<control>
+0x8B	0x008B	#	<control>
+0x8C	0x008C	#	<control>
+0x8D	0x008D	#	<control>
+0x8E	0x008E	#	<control>
+0x8F	0x008F	#	<control>
+0x90	0x0090	#	<control>
+0x91	0x0091	#	<control>
+0x92	0x0092	#	<control>
+0x93	0x0093	#	<control>
+0x94	0x0094	#	<control>
+0x95	0x0095	#	<control>
+0x96	0x0096	#	<control>
+0x97	0x0097	#	<control>
+0x98	0x0098	#	<control>
+0x99	0x0099	#	<control>
+0x9A	0x009A	#	<control>
+0x9B	0x009B	#	<control>
+0x9C	0x009C	#	<control>
+0x9D	0x009D	#	<control>
+0x9E	0x009E	#	<control>
+0x9F	0x009F	#	<control>
+0xA0	0x00A0	#	NO-BREAK SPACE
+0xA4	0x00A4	#	CURRENCY SIGN
+0xAC	0x060C	#	ARABIC COMMA
+0xAD	0x00AD	#	SOFT HYPHEN
+0xBB	0x061B	#	ARABIC SEMICOLON
+0xBF	0x061F	#	ARABIC QUESTION MARK
+0xC1	0x0621	#	ARABIC LETTER HAMZA
+0xC2	0x0622	#	ARABIC LETTER ALEF WITH MADDA ABOVE
+0xC3	0x0623	#	ARABIC LETTER ALEF WITH HAMZA ABOVE
+0xC4	0x0624	#	ARABIC LETTER WAW WITH HAMZA ABOVE
+0xC5	0x0625	#	ARABIC LETTER ALEF WITH HAMZA BELOW
+0xC6	0x0626	#	ARABIC LETTER YEH WITH HAMZA ABOVE
+0xC7	0x0627	#	ARABIC LETTER ALEF
+0xC8	0x0628	#	ARABIC LETTER BEH
+0xC9	0x0629	#	ARABIC LETTER TEH MARBUTA
+0xCA	0x062A	#	ARABIC LETTER TEH
+0xCB	0x062B	#	ARABIC LETTER THEH
+0xCC	0x062C	#	ARABIC LETTER JEEM
+0xCD	0x062D	#	ARABIC LETTER HAH
+0xCE	0x062E	#	ARABIC LETTER KHAH
+0xCF	0x062F	#	ARABIC LETTER DAL
+0xD0	0x0630	#	ARABIC LETTER THAL
+0xD1	0x0631	#	ARABIC LETTER REH
+0xD2	0x0632	#	ARABIC LETTER ZAIN
+0xD3	0x0633	#	ARABIC LETTER SEEN
+0xD4	0x0634	#	ARABIC LETTER SHEEN
+0xD5	0x0635	#	ARABIC LETTER SAD
+0xD6	0x0636	#	ARABIC LETTER DAD
+0xD7	0x0637	#	ARABIC LETTER TAH
+0xD8	0x0638	#	ARABIC LETTER ZAH
+0xD9	0x0639	#	ARABIC LETTER AIN
+0xDA	0x063A	#	ARABIC LETTER GHAIN
+0xE0	0x0640	#	ARABIC TATWEEL
+0xE1	0x0641	#	ARABIC LETTER FEH
+0xE2	0x0642	#	ARABIC LETTER QAF
+0xE3	0x0643	#	ARABIC LETTER KAF
+0xE4	0x0644	#	ARABIC LETTER LAM
+0xE5	0x0645	#	ARABIC LETTER MEEM
+0xE6	0x0646	#	ARABIC LETTER NOON
+0xE7	0x0647	#	ARABIC LETTER HEH
+0xE8	0x0648	#	ARABIC LETTER WAW
+0xE9	0x0649	#	ARABIC LETTER ALEF MAKSURA
+0xEA	0x064A	#	ARABIC LETTER YEH
+0xEB	0x064B	#	ARABIC FATHATAN
+0xEC	0x064C	#	ARABIC DAMMATAN
+0xED	0x064D	#	ARABIC KASRATAN
+0xEE	0x064E	#	ARABIC FATHA
+0xEF	0x064F	#	ARABIC DAMMA
+0xF0	0x0650	#	ARABIC KASRA
+0xF1	0x0651	#	ARABIC SHADDA
+0xF2	0x0652	#	ARABIC SUKUN
diff --git a/tools/encoding/iso8859-7.txt b/tools/encoding/iso8859-7.txt
new file mode 100644
index 0000000..52c42d0
--- /dev/null
+++ b/tools/encoding/iso8859-7.txt
@@ -0,0 +1,302 @@
+#
+#	Name:             ISO 8859-7:1987 to Unicode
+#	Unicode version:  3.0
+#	Table version:    1.0
+#	Table format:     Format A
+#	Date:             1999 July 27
+#	Authors:          Ken Whistler <kenw@sybase.com>
+#
+#	Copyright (c) 1991-1999 Unicode, Inc.  All Rights reserved.
+#
+#	This file is provided as-is by Unicode, Inc. (The Unicode Consortium).
+#	No claims are made as to fitness for any particular purpose.  No
+#	warranties of any kind are expressed or implied.  The recipient
+#	agrees to determine applicability of information provided.  If this
+#	file has been provided on optical media by Unicode, Inc., the sole
+#	remedy for any claim will be exchange of defective media within 90
+#	days of receipt.
+#
+#	Unicode, Inc. hereby grants the right to freely use the information
+#	supplied in this file in the creation of products supporting the
+#	Unicode Standard, and to make copies of this file in any form for
+#	internal or external distribution as long as this notice remains
+#	attached.
+#
+#	General notes:
+#
+#	This table contains the data the Unicode Consortium has on how
+#       ISO 8859-7:1987 characters map into Unicode.
+#
+#	ISO 8859-7:1987 is equivalent to ISO-IR-126, ELOT 928,
+#	and ECMA 118.
+#
+#	Format:  Three tab-separated columns
+#		 Column #1 is the ISO 8859-7 code (in hex as 0xXX)
+#		 Column #2 is the Unicode (in hex as 0xXXXX)
+#		 Column #3 the Unicode name (follows a comment sign, '#')
+#
+#	The entries are in ISO 8859-7 order.
+#
+#	Version history
+#	1.0 version updates 0.1 version by adding mappings for all
+#	control characters.
+#	Remap 0xA1 to U+2018 (instead of 0x02BD) to match text of 8859-7
+#	Remap 0xA2 to U+2019 (instead of 0x02BC) to match text of 8859-7
+#
+#	Updated versions of this file may be found in:
+#		<ftp://ftp.unicode.org/Public/MAPPINGS/>
+#
+#	Any comments or problems, contact <errata@unicode.org>
+#	Please note that <errata@unicode.org> is an archival address;
+#	notices will be checked, but do not expect an immediate response.
+#
+0x00	0x0000	#	NULL
+0x01	0x0001	#	START OF HEADING
+0x02	0x0002	#	START OF TEXT
+0x03	0x0003	#	END OF TEXT
+0x04	0x0004	#	END OF TRANSMISSION
+0x05	0x0005	#	ENQUIRY
+0x06	0x0006	#	ACKNOWLEDGE
+0x07	0x0007	#	BELL
+0x08	0x0008	#	BACKSPACE
+0x09	0x0009	#	HORIZONTAL TABULATION
+0x0A	0x000A	#	LINE FEED
+0x0B	0x000B	#	VERTICAL TABULATION
+0x0C	0x000C	#	FORM FEED
+0x0D	0x000D	#	CARRIAGE RETURN
+0x0E	0x000E	#	SHIFT OUT
+0x0F	0x000F	#	SHIFT IN
+0x10	0x0010	#	DATA LINK ESCAPE
+0x11	0x0011	#	DEVICE CONTROL ONE
+0x12	0x0012	#	DEVICE CONTROL TWO
+0x13	0x0013	#	DEVICE CONTROL THREE
+0x14	0x0014	#	DEVICE CONTROL FOUR
+0x15	0x0015	#	NEGATIVE ACKNOWLEDGE
+0x16	0x0016	#	SYNCHRONOUS IDLE
+0x17	0x0017	#	END OF TRANSMISSION BLOCK
+0x18	0x0018	#	CANCEL
+0x19	0x0019	#	END OF MEDIUM
+0x1A	0x001A	#	SUBSTITUTE
+0x1B	0x001B	#	ESCAPE
+0x1C	0x001C	#	FILE SEPARATOR
+0x1D	0x001D	#	GROUP SEPARATOR
+0x1E	0x001E	#	RECORD SEPARATOR
+0x1F	0x001F	#	UNIT SEPARATOR
+0x20	0x0020	#	SPACE
+0x21	0x0021	#	EXCLAMATION MARK
+0x22	0x0022	#	QUOTATION MARK
+0x23	0x0023	#	NUMBER SIGN
+0x24	0x0024	#	DOLLAR SIGN
+0x25	0x0025	#	PERCENT SIGN
+0x26	0x0026	#	AMPERSAND
+0x27	0x0027	#	APOSTROPHE
+0x28	0x0028	#	LEFT PARENTHESIS
+0x29	0x0029	#	RIGHT PARENTHESIS
+0x2A	0x002A	#	ASTERISK
+0x2B	0x002B	#	PLUS SIGN
+0x2C	0x002C	#	COMMA
+0x2D	0x002D	#	HYPHEN-MINUS
+0x2E	0x002E	#	FULL STOP
+0x2F	0x002F	#	SOLIDUS
+0x30	0x0030	#	DIGIT ZERO
+0x31	0x0031	#	DIGIT ONE
+0x32	0x0032	#	DIGIT TWO
+0x33	0x0033	#	DIGIT THREE
+0x34	0x0034	#	DIGIT FOUR
+0x35	0x0035	#	DIGIT FIVE
+0x36	0x0036	#	DIGIT SIX
+0x37	0x0037	#	DIGIT SEVEN
+0x38	0x0038	#	DIGIT EIGHT
+0x39	0x0039	#	DIGIT NINE
+0x3A	0x003A	#	COLON
+0x3B	0x003B	#	SEMICOLON
+0x3C	0x003C	#	LESS-THAN SIGN
+0x3D	0x003D	#	EQUALS SIGN
+0x3E	0x003E	#	GREATER-THAN SIGN
+0x3F	0x003F	#	QUESTION MARK
+0x40	0x0040	#	COMMERCIAL AT
+0x41	0x0041	#	LATIN CAPITAL LETTER A
+0x42	0x0042	#	LATIN CAPITAL LETTER B
+0x43	0x0043	#	LATIN CAPITAL LETTER C
+0x44	0x0044	#	LATIN CAPITAL LETTER D
+0x45	0x0045	#	LATIN CAPITAL LETTER E
+0x46	0x0046	#	LATIN CAPITAL LETTER F
+0x47	0x0047	#	LATIN CAPITAL LETTER G
+0x48	0x0048	#	LATIN CAPITAL LETTER H
+0x49	0x0049	#	LATIN CAPITAL LETTER I
+0x4A	0x004A	#	LATIN CAPITAL LETTER J
+0x4B	0x004B	#	LATIN CAPITAL LETTER K
+0x4C	0x004C	#	LATIN CAPITAL LETTER L
+0x4D	0x004D	#	LATIN CAPITAL LETTER M
+0x4E	0x004E	#	LATIN CAPITAL LETTER N
+0x4F	0x004F	#	LATIN CAPITAL LETTER O
+0x50	0x0050	#	LATIN CAPITAL LETTER P
+0x51	0x0051	#	LATIN CAPITAL LETTER Q
+0x52	0x0052	#	LATIN CAPITAL LETTER R
+0x53	0x0053	#	LATIN CAPITAL LETTER S
+0x54	0x0054	#	LATIN CAPITAL LETTER T
+0x55	0x0055	#	LATIN CAPITAL LETTER U
+0x56	0x0056	#	LATIN CAPITAL LETTER V
+0x57	0x0057	#	LATIN CAPITAL LETTER W
+0x58	0x0058	#	LATIN CAPITAL LETTER X
+0x59	0x0059	#	LATIN CAPITAL LETTER Y
+0x5A	0x005A	#	LATIN CAPITAL LETTER Z
+0x5B	0x005B	#	LEFT SQUARE BRACKET
+0x5C	0x005C	#	REVERSE SOLIDUS
+0x5D	0x005D	#	RIGHT SQUARE BRACKET
+0x5E	0x005E	#	CIRCUMFLEX ACCENT
+0x5F	0x005F	#	LOW LINE
+0x60	0x0060	#	GRAVE ACCENT
+0x61	0x0061	#	LATIN SMALL LETTER A
+0x62	0x0062	#	LATIN SMALL LETTER B
+0x63	0x0063	#	LATIN SMALL LETTER C
+0x64	0x0064	#	LATIN SMALL LETTER D
+0x65	0x0065	#	LATIN SMALL LETTER E
+0x66	0x0066	#	LATIN SMALL LETTER F
+0x67	0x0067	#	LATIN SMALL LETTER G
+0x68	0x0068	#	LATIN SMALL LETTER H
+0x69	0x0069	#	LATIN SMALL LETTER I
+0x6A	0x006A	#	LATIN SMALL LETTER J
+0x6B	0x006B	#	LATIN SMALL LETTER K
+0x6C	0x006C	#	LATIN SMALL LETTER L
+0x6D	0x006D	#	LATIN SMALL LETTER M
+0x6E	0x006E	#	LATIN SMALL LETTER N
+0x6F	0x006F	#	LATIN SMALL LETTER O
+0x70	0x0070	#	LATIN SMALL LETTER P
+0x71	0x0071	#	LATIN SMALL LETTER Q
+0x72	0x0072	#	LATIN SMALL LETTER R
+0x73	0x0073	#	LATIN SMALL LETTER S
+0x74	0x0074	#	LATIN SMALL LETTER T
+0x75	0x0075	#	LATIN SMALL LETTER U
+0x76	0x0076	#	LATIN SMALL LETTER V
+0x77	0x0077	#	LATIN SMALL LETTER W
+0x78	0x0078	#	LATIN SMALL LETTER X
+0x79	0x0079	#	LATIN SMALL LETTER Y
+0x7A	0x007A	#	LATIN SMALL LETTER Z
+0x7B	0x007B	#	LEFT CURLY BRACKET
+0x7C	0x007C	#	VERTICAL LINE
+0x7D	0x007D	#	RIGHT CURLY BRACKET
+0x7E	0x007E	#	TILDE
+0x7F	0x007F	#	DELETE
+0x80	0x0080	#	<control>
+0x81	0x0081	#	<control>
+0x82	0x0082	#	<control>
+0x83	0x0083	#	<control>
+0x84	0x0084	#	<control>
+0x85	0x0085	#	<control>
+0x86	0x0086	#	<control>
+0x87	0x0087	#	<control>
+0x88	0x0088	#	<control>
+0x89	0x0089	#	<control>
+0x8A	0x008A	#	<control>
+0x8B	0x008B	#	<control>
+0x8C	0x008C	#	<control>
+0x8D	0x008D	#	<control>
+0x8E	0x008E	#	<control>
+0x8F	0x008F	#	<control>
+0x90	0x0090	#	<control>
+0x91	0x0091	#	<control>
+0x92	0x0092	#	<control>
+0x93	0x0093	#	<control>
+0x94	0x0094	#	<control>
+0x95	0x0095	#	<control>
+0x96	0x0096	#	<control>
+0x97	0x0097	#	<control>
+0x98	0x0098	#	<control>
+0x99	0x0099	#	<control>
+0x9A	0x009A	#	<control>
+0x9B	0x009B	#	<control>
+0x9C	0x009C	#	<control>
+0x9D	0x009D	#	<control>
+0x9E	0x009E	#	<control>
+0x9F	0x009F	#	<control>
+0xA0	0x00A0	#	NO-BREAK SPACE
+0xA1	0x2018	#	LEFT SINGLE QUOTATION MARK
+0xA2	0x2019	#	RIGHT SINGLE QUOTATION MARK
+0xA3	0x00A3	#	POUND SIGN
+0xA6	0x00A6	#	BROKEN BAR
+0xA7	0x00A7	#	SECTION SIGN
+0xA8	0x00A8	#	DIAERESIS
+0xA9	0x00A9	#	COPYRIGHT SIGN
+0xAB	0x00AB	#	LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+0xAC	0x00AC	#	NOT SIGN
+0xAD	0x00AD	#	SOFT HYPHEN
+0xAF	0x2015	#	HORIZONTAL BAR
+0xB0	0x00B0	#	DEGREE SIGN
+0xB1	0x00B1	#	PLUS-MINUS SIGN
+0xB2	0x00B2	#	SUPERSCRIPT TWO
+0xB3	0x00B3	#	SUPERSCRIPT THREE
+0xB4	0x0384	#	GREEK TONOS
+0xB5	0x0385	#	GREEK DIALYTIKA TONOS
+0xB6	0x0386	#	GREEK CAPITAL LETTER ALPHA WITH TONOS
+0xB7	0x00B7	#	MIDDLE DOT
+0xB8	0x0388	#	GREEK CAPITAL LETTER EPSILON WITH TONOS
+0xB9	0x0389	#	GREEK CAPITAL LETTER ETA WITH TONOS
+0xBA	0x038A	#	GREEK CAPITAL LETTER IOTA WITH TONOS
+0xBB	0x00BB	#	RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+0xBC	0x038C	#	GREEK CAPITAL LETTER OMICRON WITH TONOS
+0xBD	0x00BD	#	VULGAR FRACTION ONE HALF
+0xBE	0x038E	#	GREEK CAPITAL LETTER UPSILON WITH TONOS
+0xBF	0x038F	#	GREEK CAPITAL LETTER OMEGA WITH TONOS
+0xC0	0x0390	#	GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS
+0xC1	0x0391	#	GREEK CAPITAL LETTER ALPHA
+0xC2	0x0392	#	GREEK CAPITAL LETTER BETA
+0xC3	0x0393	#	GREEK CAPITAL LETTER GAMMA
+0xC4	0x0394	#	GREEK CAPITAL LETTER DELTA
+0xC5	0x0395	#	GREEK CAPITAL LETTER EPSILON
+0xC6	0x0396	#	GREEK CAPITAL LETTER ZETA
+0xC7	0x0397	#	GREEK CAPITAL LETTER ETA
+0xC8	0x0398	#	GREEK CAPITAL LETTER THETA
+0xC9	0x0399	#	GREEK CAPITAL LETTER IOTA
+0xCA	0x039A	#	GREEK CAPITAL LETTER KAPPA
+0xCB	0x039B	#	GREEK CAPITAL LETTER LAMDA
+0xCC	0x039C	#	GREEK CAPITAL LETTER MU
+0xCD	0x039D	#	GREEK CAPITAL LETTER NU
+0xCE	0x039E	#	GREEK CAPITAL LETTER XI
+0xCF	0x039F	#	GREEK CAPITAL LETTER OMICRON
+0xD0	0x03A0	#	GREEK CAPITAL LETTER PI
+0xD1	0x03A1	#	GREEK CAPITAL LETTER RHO
+0xD3	0x03A3	#	GREEK CAPITAL LETTER SIGMA
+0xD4	0x03A4	#	GREEK CAPITAL LETTER TAU
+0xD5	0x03A5	#	GREEK CAPITAL LETTER UPSILON
+0xD6	0x03A6	#	GREEK CAPITAL LETTER PHI
+0xD7	0x03A7	#	GREEK CAPITAL LETTER CHI
+0xD8	0x03A8	#	GREEK CAPITAL LETTER PSI
+0xD9	0x03A9	#	GREEK CAPITAL LETTER OMEGA
+0xDA	0x03AA	#	GREEK CAPITAL LETTER IOTA WITH DIALYTIKA
+0xDB	0x03AB	#	GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA
+0xDC	0x03AC	#	GREEK SMALL LETTER ALPHA WITH TONOS
+0xDD	0x03AD	#	GREEK SMALL LETTER EPSILON WITH TONOS
+0xDE	0x03AE	#	GREEK SMALL LETTER ETA WITH TONOS
+0xDF	0x03AF	#	GREEK SMALL LETTER IOTA WITH TONOS
+0xE0	0x03B0	#	GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS
+0xE1	0x03B1	#	GREEK SMALL LETTER ALPHA
+0xE2	0x03B2	#	GREEK SMALL LETTER BETA
+0xE3	0x03B3	#	GREEK SMALL LETTER GAMMA
+0xE4	0x03B4	#	GREEK SMALL LETTER DELTA
+0xE5	0x03B5	#	GREEK SMALL LETTER EPSILON
+0xE6	0x03B6	#	GREEK SMALL LETTER ZETA
+0xE7	0x03B7	#	GREEK SMALL LETTER ETA
+0xE8	0x03B8	#	GREEK SMALL LETTER THETA
+0xE9	0x03B9	#	GREEK SMALL LETTER IOTA
+0xEA	0x03BA	#	GREEK SMALL LETTER KAPPA
+0xEB	0x03BB	#	GREEK SMALL LETTER LAMDA
+0xEC	0x03BC	#	GREEK SMALL LETTER MU
+0xED	0x03BD	#	GREEK SMALL LETTER NU
+0xEE	0x03BE	#	GREEK SMALL LETTER XI
+0xEF	0x03BF	#	GREEK SMALL LETTER OMICRON
+0xF0	0x03C0	#	GREEK SMALL LETTER PI
+0xF1	0x03C1	#	GREEK SMALL LETTER RHO
+0xF2	0x03C2	#	GREEK SMALL LETTER FINAL SIGMA
+0xF3	0x03C3	#	GREEK SMALL LETTER SIGMA
+0xF4	0x03C4	#	GREEK SMALL LETTER TAU
+0xF5	0x03C5	#	GREEK SMALL LETTER UPSILON
+0xF6	0x03C6	#	GREEK SMALL LETTER PHI
+0xF7	0x03C7	#	GREEK SMALL LETTER CHI
+0xF8	0x03C8	#	GREEK SMALL LETTER PSI
+0xF9	0x03C9	#	GREEK SMALL LETTER OMEGA
+0xFA	0x03CA	#	GREEK SMALL LETTER IOTA WITH DIALYTIKA
+0xFB	0x03CB	#	GREEK SMALL LETTER UPSILON WITH DIALYTIKA
+0xFC	0x03CC	#	GREEK SMALL LETTER OMICRON WITH TONOS
+0xFD	0x03CD	#	GREEK SMALL LETTER UPSILON WITH TONOS
+0xFE	0x03CE	#	GREEK SMALL LETTER OMEGA WITH TONOS
diff --git a/tools/encoding/iso8859-8.txt b/tools/encoding/iso8859-8.txt
new file mode 100644
index 0000000..bc8da4c
--- /dev/null
+++ b/tools/encoding/iso8859-8.txt
@@ -0,0 +1,270 @@
+#
+#	Name:             ISO/IEC 8859-8:1999 to Unicode
+#	Unicode version:  3.0
+#	Table version:    1.1
+#	Table format:     Format A
+#	Date:             2000-Jan-03
+#	Authors:          Ken Whistler <kenw@sybase.com>
+#
+#	Copyright (c) 1991-1999 Unicode, Inc.  All Rights reserved.
+#
+#	This file is provided as-is by Unicode, Inc. (The Unicode Consortium).
+#	No claims are made as to fitness for any particular purpose.  No
+#	warranties of any kind are expressed or implied.  The recipient
+#	agrees to determine applicability of information provided.  If this
+#	file has been provided on optical media by Unicode, Inc., the sole
+#	remedy for any claim will be exchange of defective media within 90
+#	days of receipt.
+#
+#	Unicode, Inc. hereby grants the right to freely use the information
+#	supplied in this file in the creation of products supporting the
+#	Unicode Standard, and to make copies of this file in any form for
+#	internal or external distribution as long as this notice remains
+#	attached.
+#
+#	General notes:
+#
+#	This table contains the data the Unicode Consortium has on how
+#       ISO/IEC 8859-8:1999 characters map into Unicode.
+#
+#	Format:  Three tab-separated columns
+#		 Column #1 is the ISO/IEC 8859-8 code (in hex as 0xXX)
+#		 Column #2 is the Unicode (in hex as 0xXXXX)
+#		 Column #3 the Unicode name (follows a comment sign, '#')
+#
+#	The entries are in ISO/IEC 8859-8 order.
+#
+#	Version history
+#	1.0 version updates 0.1 version by adding mappings for all
+#	control characters.
+#       1.1 version updates to the published 8859-8:1999, correcting
+#          the mapping of 0xAF and adding mappings for LRM and RLM.
+#
+#	Updated versions of this file may be found in:
+#		<ftp://ftp.unicode.org/Public/MAPPINGS/>
+#
+#	Any comments or problems, contact <errata@unicode.org>
+#	Please note that <errata@unicode.org> is an archival address;
+#	notices will be checked, but do not expect an immediate response.
+#
+0x00	0x0000	#	NULL
+0x01	0x0001	#	START OF HEADING
+0x02	0x0002	#	START OF TEXT
+0x03	0x0003	#	END OF TEXT
+0x04	0x0004	#	END OF TRANSMISSION
+0x05	0x0005	#	ENQUIRY
+0x06	0x0006	#	ACKNOWLEDGE
+0x07	0x0007	#	BELL
+0x08	0x0008	#	BACKSPACE
+0x09	0x0009	#	HORIZONTAL TABULATION
+0x0A	0x000A	#	LINE FEED
+0x0B	0x000B	#	VERTICAL TABULATION
+0x0C	0x000C	#	FORM FEED
+0x0D	0x000D	#	CARRIAGE RETURN
+0x0E	0x000E	#	SHIFT OUT
+0x0F	0x000F	#	SHIFT IN
+0x10	0x0010	#	DATA LINK ESCAPE
+0x11	0x0011	#	DEVICE CONTROL ONE
+0x12	0x0012	#	DEVICE CONTROL TWO
+0x13	0x0013	#	DEVICE CONTROL THREE
+0x14	0x0014	#	DEVICE CONTROL FOUR
+0x15	0x0015	#	NEGATIVE ACKNOWLEDGE
+0x16	0x0016	#	SYNCHRONOUS IDLE
+0x17	0x0017	#	END OF TRANSMISSION BLOCK
+0x18	0x0018	#	CANCEL
+0x19	0x0019	#	END OF MEDIUM
+0x1A	0x001A	#	SUBSTITUTE
+0x1B	0x001B	#	ESCAPE
+0x1C	0x001C	#	FILE SEPARATOR
+0x1D	0x001D	#	GROUP SEPARATOR
+0x1E	0x001E	#	RECORD SEPARATOR
+0x1F	0x001F	#	UNIT SEPARATOR
+0x20	0x0020	#	SPACE
+0x21	0x0021	#	EXCLAMATION MARK
+0x22	0x0022	#	QUOTATION MARK
+0x23	0x0023	#	NUMBER SIGN
+0x24	0x0024	#	DOLLAR SIGN
+0x25	0x0025	#	PERCENT SIGN
+0x26	0x0026	#	AMPERSAND
+0x27	0x0027	#	APOSTROPHE
+0x28	0x0028	#	LEFT PARENTHESIS
+0x29	0x0029	#	RIGHT PARENTHESIS
+0x2A	0x002A	#	ASTERISK
+0x2B	0x002B	#	PLUS SIGN
+0x2C	0x002C	#	COMMA
+0x2D	0x002D	#	HYPHEN-MINUS
+0x2E	0x002E	#	FULL STOP
+0x2F	0x002F	#	SOLIDUS
+0x30	0x0030	#	DIGIT ZERO
+0x31	0x0031	#	DIGIT ONE
+0x32	0x0032	#	DIGIT TWO
+0x33	0x0033	#	DIGIT THREE
+0x34	0x0034	#	DIGIT FOUR
+0x35	0x0035	#	DIGIT FIVE
+0x36	0x0036	#	DIGIT SIX
+0x37	0x0037	#	DIGIT SEVEN
+0x38	0x0038	#	DIGIT EIGHT
+0x39	0x0039	#	DIGIT NINE
+0x3A	0x003A	#	COLON
+0x3B	0x003B	#	SEMICOLON
+0x3C	0x003C	#	LESS-THAN SIGN
+0x3D	0x003D	#	EQUALS SIGN
+0x3E	0x003E	#	GREATER-THAN SIGN
+0x3F	0x003F	#	QUESTION MARK
+0x40	0x0040	#	COMMERCIAL AT
+0x41	0x0041	#	LATIN CAPITAL LETTER A
+0x42	0x0042	#	LATIN CAPITAL LETTER B
+0x43	0x0043	#	LATIN CAPITAL LETTER C
+0x44	0x0044	#	LATIN CAPITAL LETTER D
+0x45	0x0045	#	LATIN CAPITAL LETTER E
+0x46	0x0046	#	LATIN CAPITAL LETTER F
+0x47	0x0047	#	LATIN CAPITAL LETTER G
+0x48	0x0048	#	LATIN CAPITAL LETTER H
+0x49	0x0049	#	LATIN CAPITAL LETTER I
+0x4A	0x004A	#	LATIN CAPITAL LETTER J
+0x4B	0x004B	#	LATIN CAPITAL LETTER K
+0x4C	0x004C	#	LATIN CAPITAL LETTER L
+0x4D	0x004D	#	LATIN CAPITAL LETTER M
+0x4E	0x004E	#	LATIN CAPITAL LETTER N
+0x4F	0x004F	#	LATIN CAPITAL LETTER O
+0x50	0x0050	#	LATIN CAPITAL LETTER P
+0x51	0x0051	#	LATIN CAPITAL LETTER Q
+0x52	0x0052	#	LATIN CAPITAL LETTER R
+0x53	0x0053	#	LATIN CAPITAL LETTER S
+0x54	0x0054	#	LATIN CAPITAL LETTER T
+0x55	0x0055	#	LATIN CAPITAL LETTER U
+0x56	0x0056	#	LATIN CAPITAL LETTER V
+0x57	0x0057	#	LATIN CAPITAL LETTER W
+0x58	0x0058	#	LATIN CAPITAL LETTER X
+0x59	0x0059	#	LATIN CAPITAL LETTER Y
+0x5A	0x005A	#	LATIN CAPITAL LETTER Z
+0x5B	0x005B	#	LEFT SQUARE BRACKET
+0x5C	0x005C	#	REVERSE SOLIDUS
+0x5D	0x005D	#	RIGHT SQUARE BRACKET
+0x5E	0x005E	#	CIRCUMFLEX ACCENT
+0x5F	0x005F	#	LOW LINE
+0x60	0x0060	#	GRAVE ACCENT
+0x61	0x0061	#	LATIN SMALL LETTER A
+0x62	0x0062	#	LATIN SMALL LETTER B
+0x63	0x0063	#	LATIN SMALL LETTER C
+0x64	0x0064	#	LATIN SMALL LETTER D
+0x65	0x0065	#	LATIN SMALL LETTER E
+0x66	0x0066	#	LATIN SMALL LETTER F
+0x67	0x0067	#	LATIN SMALL LETTER G
+0x68	0x0068	#	LATIN SMALL LETTER H
+0x69	0x0069	#	LATIN SMALL LETTER I
+0x6A	0x006A	#	LATIN SMALL LETTER J
+0x6B	0x006B	#	LATIN SMALL LETTER K
+0x6C	0x006C	#	LATIN SMALL LETTER L
+0x6D	0x006D	#	LATIN SMALL LETTER M
+0x6E	0x006E	#	LATIN SMALL LETTER N
+0x6F	0x006F	#	LATIN SMALL LETTER O
+0x70	0x0070	#	LATIN SMALL LETTER P
+0x71	0x0071	#	LATIN SMALL LETTER Q
+0x72	0x0072	#	LATIN SMALL LETTER R
+0x73	0x0073	#	LATIN SMALL LETTER S
+0x74	0x0074	#	LATIN SMALL LETTER T
+0x75	0x0075	#	LATIN SMALL LETTER U
+0x76	0x0076	#	LATIN SMALL LETTER V
+0x77	0x0077	#	LATIN SMALL LETTER W
+0x78	0x0078	#	LATIN SMALL LETTER X
+0x79	0x0079	#	LATIN SMALL LETTER Y
+0x7A	0x007A	#	LATIN SMALL LETTER Z
+0x7B	0x007B	#	LEFT CURLY BRACKET
+0x7C	0x007C	#	VERTICAL LINE
+0x7D	0x007D	#	RIGHT CURLY BRACKET
+0x7E	0x007E	#	TILDE
+0x7F	0x007F	#	DELETE
+0x80	0x0080	#	<control>
+0x81	0x0081	#	<control>
+0x82	0x0082	#	<control>
+0x83	0x0083	#	<control>
+0x84	0x0084	#	<control>
+0x85	0x0085	#	<control>
+0x86	0x0086	#	<control>
+0x87	0x0087	#	<control>
+0x88	0x0088	#	<control>
+0x89	0x0089	#	<control>
+0x8A	0x008A	#	<control>
+0x8B	0x008B	#	<control>
+0x8C	0x008C	#	<control>
+0x8D	0x008D	#	<control>
+0x8E	0x008E	#	<control>
+0x8F	0x008F	#	<control>
+0x90	0x0090	#	<control>
+0x91	0x0091	#	<control>
+0x92	0x0092	#	<control>
+0x93	0x0093	#	<control>
+0x94	0x0094	#	<control>
+0x95	0x0095	#	<control>
+0x96	0x0096	#	<control>
+0x97	0x0097	#	<control>
+0x98	0x0098	#	<control>
+0x99	0x0099	#	<control>
+0x9A	0x009A	#	<control>
+0x9B	0x009B	#	<control>
+0x9C	0x009C	#	<control>
+0x9D	0x009D	#	<control>
+0x9E	0x009E	#	<control>
+0x9F	0x009F	#	<control>
+0xA0	0x00A0	#	NO-BREAK SPACE
+0xA2	0x00A2	#	CENT SIGN
+0xA3	0x00A3	#	POUND SIGN
+0xA4	0x00A4	#	CURRENCY SIGN
+0xA5	0x00A5	#	YEN SIGN
+0xA6	0x00A6	#	BROKEN BAR
+0xA7	0x00A7	#	SECTION SIGN
+0xA8	0x00A8	#	DIAERESIS
+0xA9	0x00A9	#	COPYRIGHT SIGN
+0xAA	0x00D7	#	MULTIPLICATION SIGN
+0xAB	0x00AB	#	LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+0xAC	0x00AC	#	NOT SIGN
+0xAD	0x00AD	#	SOFT HYPHEN
+0xAE	0x00AE	#	REGISTERED SIGN
+0xAF	0x00AF	#	MACRON
+0xB0	0x00B0	#	DEGREE SIGN
+0xB1	0x00B1	#	PLUS-MINUS SIGN
+0xB2	0x00B2	#	SUPERSCRIPT TWO
+0xB3	0x00B3	#	SUPERSCRIPT THREE
+0xB4	0x00B4	#	ACUTE ACCENT
+0xB5	0x00B5	#	MICRO SIGN
+0xB6	0x00B6	#	PILCROW SIGN
+0xB7	0x00B7	#	MIDDLE DOT
+0xB8	0x00B8	#	CEDILLA
+0xB9	0x00B9	#	SUPERSCRIPT ONE
+0xBA	0x00F7	#	DIVISION SIGN
+0xBB	0x00BB	#	RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+0xBC	0x00BC	#	VULGAR FRACTION ONE QUARTER
+0xBD	0x00BD	#	VULGAR FRACTION ONE HALF
+0xBE	0x00BE	#	VULGAR FRACTION THREE QUARTERS
+0xDF	0x2017	#	DOUBLE LOW LINE
+0xE0	0x05D0	#	HEBREW LETTER ALEF
+0xE1	0x05D1	#	HEBREW LETTER BET
+0xE2	0x05D2	#	HEBREW LETTER GIMEL
+0xE3	0x05D3	#	HEBREW LETTER DALET
+0xE4	0x05D4	#	HEBREW LETTER HE
+0xE5	0x05D5	#	HEBREW LETTER VAV
+0xE6	0x05D6	#	HEBREW LETTER ZAYIN
+0xE7	0x05D7	#	HEBREW LETTER HET
+0xE8	0x05D8	#	HEBREW LETTER TET
+0xE9	0x05D9	#	HEBREW LETTER YOD
+0xEA	0x05DA	#	HEBREW LETTER FINAL KAF
+0xEB	0x05DB	#	HEBREW LETTER KAF
+0xEC	0x05DC	#	HEBREW LETTER LAMED
+0xED	0x05DD	#	HEBREW LETTER FINAL MEM
+0xEE	0x05DE	#	HEBREW LETTER MEM
+0xEF	0x05DF	#	HEBREW LETTER FINAL NUN
+0xF0	0x05E0	#	HEBREW LETTER NUN
+0xF1	0x05E1	#	HEBREW LETTER SAMEKH
+0xF2	0x05E2	#	HEBREW LETTER AYIN
+0xF3	0x05E3	#	HEBREW LETTER FINAL PE
+0xF4	0x05E4	#	HEBREW LETTER PE
+0xF5	0x05E5	#	HEBREW LETTER FINAL TSADI
+0xF6	0x05E6	#	HEBREW LETTER TSADI
+0xF7	0x05E7	#	HEBREW LETTER QOF
+0xF8	0x05E8	#	HEBREW LETTER RESH
+0xF9	0x05E9	#	HEBREW LETTER SHIN
+0xFA	0x05EA	#	HEBREW LETTER TAV
+0xFD	0x200E	#	LEFT-TO-RIGHT MARK
+0xFE	0x200F	#	RIGHT-TO-LEFT MARK
+
diff --git a/tools/encoding/iso8859-9.txt b/tools/encoding/iso8859-9.txt
new file mode 100644
index 0000000..22901f1
--- /dev/null
+++ b/tools/encoding/iso8859-9.txt
@@ -0,0 +1,307 @@
+#
+#	Name:             ISO/IEC 8859-9:1999 to Unicode
+#	Unicode version:  3.0
+#	Table version:    1.0
+#	Table format:     Format A
+#	Date:             1999 July 27
+#	Authors:          Ken Whistler <kenw@sybase.com>
+#
+#	Copyright (c) 1991-1999 Unicode, Inc.  All Rights reserved.
+#
+#	This file is provided as-is by Unicode, Inc. (The Unicode Consortium).
+#	No claims are made as to fitness for any particular purpose.  No
+#	warranties of any kind are expressed or implied.  The recipient
+#	agrees to determine applicability of information provided.  If this
+#	file has been provided on magnetic media by Unicode, Inc., the sole
+#	remedy for any claim will be exchange of defective media within 90
+#	days of receipt.
+#
+#	Unicode, Inc. hereby grants the right to freely use the information
+#	supplied in this file in the creation of products supporting the
+#	Unicode Standard, and to make copies of this file in any form for
+#	internal or external distribution as long as this notice remains
+#	attached.
+#
+#	General notes:
+#
+#	This table contains the data the Unicode Consortium has on how
+#       ISO/IEC 8859-9:1999 characters map into Unicode.
+#
+#	Format:  Three tab-separated columns
+#		 Column #1 is the ISO/IEC 8859-9 code (in hex as 0xXX)
+#		 Column #2 is the Unicode (in hex as 0xXXXX)
+#		 Column #3 the Unicode name (follows a comment sign, '#')
+#
+#	The entries are in ISO/IEC 8859-9 order.
+#
+#	ISO/IEC 8859-9 is also equivalent to ISO-IR-148.
+#
+#	Version history
+#	1.0 version updates 0.1 version by adding mappings for all
+#	control characters.
+#
+#	Updated versions of this file may be found in:
+#		<ftp://ftp.unicode.org/Public/MAPPINGS/>
+#
+#	Any comments or problems, contact <errata@unicode.org>
+#	Please note that <errata@unicode.org> is an archival address;
+#	notices will be checked, but do not expect an immediate response.
+#
+0x00	0x0000	#	NULL
+0x01	0x0001	#	START OF HEADING
+0x02	0x0002	#	START OF TEXT
+0x03	0x0003	#	END OF TEXT
+0x04	0x0004	#	END OF TRANSMISSION
+0x05	0x0005	#	ENQUIRY
+0x06	0x0006	#	ACKNOWLEDGE
+0x07	0x0007	#	BELL
+0x08	0x0008	#	BACKSPACE
+0x09	0x0009	#	HORIZONTAL TABULATION
+0x0A	0x000A	#	LINE FEED
+0x0B	0x000B	#	VERTICAL TABULATION
+0x0C	0x000C	#	FORM FEED
+0x0D	0x000D	#	CARRIAGE RETURN
+0x0E	0x000E	#	SHIFT OUT
+0x0F	0x000F	#	SHIFT IN
+0x10	0x0010	#	DATA LINK ESCAPE
+0x11	0x0011	#	DEVICE CONTROL ONE
+0x12	0x0012	#	DEVICE CONTROL TWO
+0x13	0x0013	#	DEVICE CONTROL THREE
+0x14	0x0014	#	DEVICE CONTROL FOUR
+0x15	0x0015	#	NEGATIVE ACKNOWLEDGE
+0x16	0x0016	#	SYNCHRONOUS IDLE
+0x17	0x0017	#	END OF TRANSMISSION BLOCK
+0x18	0x0018	#	CANCEL
+0x19	0x0019	#	END OF MEDIUM
+0x1A	0x001A	#	SUBSTITUTE
+0x1B	0x001B	#	ESCAPE
+0x1C	0x001C	#	FILE SEPARATOR
+0x1D	0x001D	#	GROUP SEPARATOR
+0x1E	0x001E	#	RECORD SEPARATOR
+0x1F	0x001F	#	UNIT SEPARATOR
+0x20	0x0020	#	SPACE
+0x21	0x0021	#	EXCLAMATION MARK
+0x22	0x0022	#	QUOTATION MARK
+0x23	0x0023	#	NUMBER SIGN
+0x24	0x0024	#	DOLLAR SIGN
+0x25	0x0025	#	PERCENT SIGN
+0x26	0x0026	#	AMPERSAND
+0x27	0x0027	#	APOSTROPHE
+0x28	0x0028	#	LEFT PARENTHESIS
+0x29	0x0029	#	RIGHT PARENTHESIS
+0x2A	0x002A	#	ASTERISK
+0x2B	0x002B	#	PLUS SIGN
+0x2C	0x002C	#	COMMA
+0x2D	0x002D	#	HYPHEN-MINUS
+0x2E	0x002E	#	FULL STOP
+0x2F	0x002F	#	SOLIDUS
+0x30	0x0030	#	DIGIT ZERO
+0x31	0x0031	#	DIGIT ONE
+0x32	0x0032	#	DIGIT TWO
+0x33	0x0033	#	DIGIT THREE
+0x34	0x0034	#	DIGIT FOUR
+0x35	0x0035	#	DIGIT FIVE
+0x36	0x0036	#	DIGIT SIX
+0x37	0x0037	#	DIGIT SEVEN
+0x38	0x0038	#	DIGIT EIGHT
+0x39	0x0039	#	DIGIT NINE
+0x3A	0x003A	#	COLON
+0x3B	0x003B	#	SEMICOLON
+0x3C	0x003C	#	LESS-THAN SIGN
+0x3D	0x003D	#	EQUALS SIGN
+0x3E	0x003E	#	GREATER-THAN SIGN
+0x3F	0x003F	#	QUESTION MARK
+0x40	0x0040	#	COMMERCIAL AT
+0x41	0x0041	#	LATIN CAPITAL LETTER A
+0x42	0x0042	#	LATIN CAPITAL LETTER B
+0x43	0x0043	#	LATIN CAPITAL LETTER C
+0x44	0x0044	#	LATIN CAPITAL LETTER D
+0x45	0x0045	#	LATIN CAPITAL LETTER E
+0x46	0x0046	#	LATIN CAPITAL LETTER F
+0x47	0x0047	#	LATIN CAPITAL LETTER G
+0x48	0x0048	#	LATIN CAPITAL LETTER H
+0x49	0x0049	#	LATIN CAPITAL LETTER I
+0x4A	0x004A	#	LATIN CAPITAL LETTER J
+0x4B	0x004B	#	LATIN CAPITAL LETTER K
+0x4C	0x004C	#	LATIN CAPITAL LETTER L
+0x4D	0x004D	#	LATIN CAPITAL LETTER M
+0x4E	0x004E	#	LATIN CAPITAL LETTER N
+0x4F	0x004F	#	LATIN CAPITAL LETTER O
+0x50	0x0050	#	LATIN CAPITAL LETTER P
+0x51	0x0051	#	LATIN CAPITAL LETTER Q
+0x52	0x0052	#	LATIN CAPITAL LETTER R
+0x53	0x0053	#	LATIN CAPITAL LETTER S
+0x54	0x0054	#	LATIN CAPITAL LETTER T
+0x55	0x0055	#	LATIN CAPITAL LETTER U
+0x56	0x0056	#	LATIN CAPITAL LETTER V
+0x57	0x0057	#	LATIN CAPITAL LETTER W
+0x58	0x0058	#	LATIN CAPITAL LETTER X
+0x59	0x0059	#	LATIN CAPITAL LETTER Y
+0x5A	0x005A	#	LATIN CAPITAL LETTER Z
+0x5B	0x005B	#	LEFT SQUARE BRACKET
+0x5C	0x005C	#	REVERSE SOLIDUS
+0x5D	0x005D	#	RIGHT SQUARE BRACKET
+0x5E	0x005E	#	CIRCUMFLEX ACCENT
+0x5F	0x005F	#	LOW LINE
+0x60	0x0060	#	GRAVE ACCENT
+0x61	0x0061	#	LATIN SMALL LETTER A
+0x62	0x0062	#	LATIN SMALL LETTER B
+0x63	0x0063	#	LATIN SMALL LETTER C
+0x64	0x0064	#	LATIN SMALL LETTER D
+0x65	0x0065	#	LATIN SMALL LETTER E
+0x66	0x0066	#	LATIN SMALL LETTER F
+0x67	0x0067	#	LATIN SMALL LETTER G
+0x68	0x0068	#	LATIN SMALL LETTER H
+0x69	0x0069	#	LATIN SMALL LETTER I
+0x6A	0x006A	#	LATIN SMALL LETTER J
+0x6B	0x006B	#	LATIN SMALL LETTER K
+0x6C	0x006C	#	LATIN SMALL LETTER L
+0x6D	0x006D	#	LATIN SMALL LETTER M
+0x6E	0x006E	#	LATIN SMALL LETTER N
+0x6F	0x006F	#	LATIN SMALL LETTER O
+0x70	0x0070	#	LATIN SMALL LETTER P
+0x71	0x0071	#	LATIN SMALL LETTER Q
+0x72	0x0072	#	LATIN SMALL LETTER R
+0x73	0x0073	#	LATIN SMALL LETTER S
+0x74	0x0074	#	LATIN SMALL LETTER T
+0x75	0x0075	#	LATIN SMALL LETTER U
+0x76	0x0076	#	LATIN SMALL LETTER V
+0x77	0x0077	#	LATIN SMALL LETTER W
+0x78	0x0078	#	LATIN SMALL LETTER X
+0x79	0x0079	#	LATIN SMALL LETTER Y
+0x7A	0x007A	#	LATIN SMALL LETTER Z
+0x7B	0x007B	#	LEFT CURLY BRACKET
+0x7C	0x007C	#	VERTICAL LINE
+0x7D	0x007D	#	RIGHT CURLY BRACKET
+0x7E	0x007E	#	TILDE
+0x7F	0x007F	#	DELETE
+0x80	0x0080	#	<control>
+0x81	0x0081	#	<control>
+0x82	0x0082	#	<control>
+0x83	0x0083	#	<control>
+0x84	0x0084	#	<control>
+0x85	0x0085	#	<control>
+0x86	0x0086	#	<control>
+0x87	0x0087	#	<control>
+0x88	0x0088	#	<control>
+0x89	0x0089	#	<control>
+0x8A	0x008A	#	<control>
+0x8B	0x008B	#	<control>
+0x8C	0x008C	#	<control>
+0x8D	0x008D	#	<control>
+0x8E	0x008E	#	<control>
+0x8F	0x008F	#	<control>
+0x90	0x0090	#	<control>
+0x91	0x0091	#	<control>
+0x92	0x0092	#	<control>
+0x93	0x0093	#	<control>
+0x94	0x0094	#	<control>
+0x95	0x0095	#	<control>
+0x96	0x0096	#	<control>
+0x97	0x0097	#	<control>
+0x98	0x0098	#	<control>
+0x99	0x0099	#	<control>
+0x9A	0x009A	#	<control>
+0x9B	0x009B	#	<control>
+0x9C	0x009C	#	<control>
+0x9D	0x009D	#	<control>
+0x9E	0x009E	#	<control>
+0x9F	0x009F	#	<control>
+0xA0	0x00A0	#	NO-BREAK SPACE
+0xA1	0x00A1	#	INVERTED EXCLAMATION MARK
+0xA2	0x00A2	#	CENT SIGN
+0xA3	0x00A3	#	POUND SIGN
+0xA4	0x00A4	#	CURRENCY SIGN
+0xA5	0x00A5	#	YEN SIGN
+0xA6	0x00A6	#	BROKEN BAR
+0xA7	0x00A7	#	SECTION SIGN
+0xA8	0x00A8	#	DIAERESIS
+0xA9	0x00A9	#	COPYRIGHT SIGN
+0xAA	0x00AA	#	FEMININE ORDINAL INDICATOR
+0xAB	0x00AB	#	LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+0xAC	0x00AC	#	NOT SIGN
+0xAD	0x00AD	#	SOFT HYPHEN
+0xAE	0x00AE	#	REGISTERED SIGN
+0xAF	0x00AF	#	MACRON
+0xB0	0x00B0	#	DEGREE SIGN
+0xB1	0x00B1	#	PLUS-MINUS SIGN
+0xB2	0x00B2	#	SUPERSCRIPT TWO
+0xB3	0x00B3	#	SUPERSCRIPT THREE
+0xB4	0x00B4	#	ACUTE ACCENT
+0xB5	0x00B5	#	MICRO SIGN
+0xB6	0x00B6	#	PILCROW SIGN
+0xB7	0x00B7	#	MIDDLE DOT
+0xB8	0x00B8	#	CEDILLA
+0xB9	0x00B9	#	SUPERSCRIPT ONE
+0xBA	0x00BA	#	MASCULINE ORDINAL INDICATOR
+0xBB	0x00BB	#	RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+0xBC	0x00BC	#	VULGAR FRACTION ONE QUARTER
+0xBD	0x00BD	#	VULGAR FRACTION ONE HALF
+0xBE	0x00BE	#	VULGAR FRACTION THREE QUARTERS
+0xBF	0x00BF	#	INVERTED QUESTION MARK
+0xC0	0x00C0	#	LATIN CAPITAL LETTER A WITH GRAVE
+0xC1	0x00C1	#	LATIN CAPITAL LETTER A WITH ACUTE
+0xC2	0x00C2	#	LATIN CAPITAL LETTER A WITH CIRCUMFLEX
+0xC3	0x00C3	#	LATIN CAPITAL LETTER A WITH TILDE
+0xC4	0x00C4	#	LATIN CAPITAL LETTER A WITH DIAERESIS
+0xC5	0x00C5	#	LATIN CAPITAL LETTER A WITH RING ABOVE
+0xC6	0x00C6	#	LATIN CAPITAL LETTER AE
+0xC7	0x00C7	#	LATIN CAPITAL LETTER C WITH CEDILLA
+0xC8	0x00C8	#	LATIN CAPITAL LETTER E WITH GRAVE
+0xC9	0x00C9	#	LATIN CAPITAL LETTER E WITH ACUTE
+0xCA	0x00CA	#	LATIN CAPITAL LETTER E WITH CIRCUMFLEX
+0xCB	0x00CB	#	LATIN CAPITAL LETTER E WITH DIAERESIS
+0xCC	0x00CC	#	LATIN CAPITAL LETTER I WITH GRAVE
+0xCD	0x00CD	#	LATIN CAPITAL LETTER I WITH ACUTE
+0xCE	0x00CE	#	LATIN CAPITAL LETTER I WITH CIRCUMFLEX
+0xCF	0x00CF	#	LATIN CAPITAL LETTER I WITH DIAERESIS
+0xD0	0x011E	#	LATIN CAPITAL LETTER G WITH BREVE
+0xD1	0x00D1	#	LATIN CAPITAL LETTER N WITH TILDE
+0xD2	0x00D2	#	LATIN CAPITAL LETTER O WITH GRAVE
+0xD3	0x00D3	#	LATIN CAPITAL LETTER O WITH ACUTE
+0xD4	0x00D4	#	LATIN CAPITAL LETTER O WITH CIRCUMFLEX
+0xD5	0x00D5	#	LATIN CAPITAL LETTER O WITH TILDE
+0xD6	0x00D6	#	LATIN CAPITAL LETTER O WITH DIAERESIS
+0xD7	0x00D7	#	MULTIPLICATION SIGN
+0xD8	0x00D8	#	LATIN CAPITAL LETTER O WITH STROKE
+0xD9	0x00D9	#	LATIN CAPITAL LETTER U WITH GRAVE
+0xDA	0x00DA	#	LATIN CAPITAL LETTER U WITH ACUTE
+0xDB	0x00DB	#	LATIN CAPITAL LETTER U WITH CIRCUMFLEX
+0xDC	0x00DC	#	LATIN CAPITAL LETTER U WITH DIAERESIS
+0xDD	0x0130	#	LATIN CAPITAL LETTER I WITH DOT ABOVE
+0xDE	0x015E	#	LATIN CAPITAL LETTER S WITH CEDILLA
+0xDF	0x00DF	#	LATIN SMALL LETTER SHARP S
+0xE0	0x00E0	#	LATIN SMALL LETTER A WITH GRAVE
+0xE1	0x00E1	#	LATIN SMALL LETTER A WITH ACUTE
+0xE2	0x00E2	#	LATIN SMALL LETTER A WITH CIRCUMFLEX
+0xE3	0x00E3	#	LATIN SMALL LETTER A WITH TILDE
+0xE4	0x00E4	#	LATIN SMALL LETTER A WITH DIAERESIS
+0xE5	0x00E5	#	LATIN SMALL LETTER A WITH RING ABOVE
+0xE6	0x00E6	#	LATIN SMALL LETTER AE
+0xE7	0x00E7	#	LATIN SMALL LETTER C WITH CEDILLA
+0xE8	0x00E8	#	LATIN SMALL LETTER E WITH GRAVE
+0xE9	0x00E9	#	LATIN SMALL LETTER E WITH ACUTE
+0xEA	0x00EA	#	LATIN SMALL LETTER E WITH CIRCUMFLEX
+0xEB	0x00EB	#	LATIN SMALL LETTER E WITH DIAERESIS
+0xEC	0x00EC	#	LATIN SMALL LETTER I WITH GRAVE
+0xED	0x00ED	#	LATIN SMALL LETTER I WITH ACUTE
+0xEE	0x00EE	#	LATIN SMALL LETTER I WITH CIRCUMFLEX
+0xEF	0x00EF	#	LATIN SMALL LETTER I WITH DIAERESIS
+0xF0	0x011F	#	LATIN SMALL LETTER G WITH BREVE
+0xF1	0x00F1	#	LATIN SMALL LETTER N WITH TILDE
+0xF2	0x00F2	#	LATIN SMALL LETTER O WITH GRAVE
+0xF3	0x00F3	#	LATIN SMALL LETTER O WITH ACUTE
+0xF4	0x00F4	#	LATIN SMALL LETTER O WITH CIRCUMFLEX
+0xF5	0x00F5	#	LATIN SMALL LETTER O WITH TILDE
+0xF6	0x00F6	#	LATIN SMALL LETTER O WITH DIAERESIS
+0xF7	0x00F7	#	DIVISION SIGN
+0xF8	0x00F8	#	LATIN SMALL LETTER O WITH STROKE
+0xF9	0x00F9	#	LATIN SMALL LETTER U WITH GRAVE
+0xFA	0x00FA	#	LATIN SMALL LETTER U WITH ACUTE
+0xFB	0x00FB	#	LATIN SMALL LETTER U WITH CIRCUMFLEX
+0xFC	0x00FC	#	LATIN SMALL LETTER U WITH DIAERESIS
+0xFD	0x0131	#	LATIN SMALL LETTER DOTLESS I
+0xFE	0x015F	#	LATIN SMALL LETTER S WITH CEDILLA
+0xFF	0x00FF	#	LATIN SMALL LETTER Y WITH DIAERESIS
+
+
diff --git a/tools/encoding/jis0201.txt b/tools/encoding/jis0201.txt
new file mode 100644
index 0000000..d84c98a
--- /dev/null
+++ b/tools/encoding/jis0201.txt
@@ -0,0 +1,202 @@
+#
+#	Name:             JIS X 0201 (1976) to Unicode 1.1 Table
+#	Unicode version:  1.1
+#	Table version:    0.9
+#	Table format:     Format A
+#	Date:             8 March 1994
+#	Authors:          Glenn Adams <glenn@metis.com>
+#                     John H. Jenkins <John_Jenkins@taligent.com>
+#
+#	Copyright (c) 1991-1994 Unicode, Inc.  All Rights reserved.
+#
+#	This file is provided as-is by Unicode, Inc. (The Unicode Consortium).
+#	No claims are made as to fitness for any particular purpose.  No
+#	warranties of any kind are expressed or implied.  The recipient
+#	agrees to determine applicability of information provided.  If this
+#	file has been provided on magnetic media by Unicode, Inc., the sole
+#	remedy for any claim will be exchange of defective media within 90
+#	days of receipt.
+#
+#	Recipient is granted the right to make copies in any form for
+#	internal distribution and to freely use the information supplied
+#	in the creation of products supporting Unicode.  Unicode, Inc.
+#	specifically excludes the right to re-distribute this file directly
+#	to third parties or other organizations whether for profit or not.
+#
+#	General notes:
+#
+#	This table contains the data the Unicode Consortium has on how
+#	single-byte JIS X 0201 characters map into Unicode 1.1
+#	(ISO/IEC 10646:1-1993 UCS-2).
+#
+#	Format:  Three tab-separated columns
+#		Column #1 is the shift JIS code (in hex as 0xXX)
+#		Column #2 is the Unicode (in hex as 0xXXXX)
+#		Column #3 the Unicode (ISO 10646) name (follows a comment sign)
+#
+#	The entries are in JIS order
+#
+#   These mappings are provisional, pending definition of
+#       official mappings by Japanese standards bodies.
+#
+#	Any comments or problems, contact <John_Jenkins@taligent.com>
+#
+#
+0x20	0x0020	# SPACE
+0x21	0x0021	# EXCLAMATION MARK
+0x22	0x0022	# QUOTATION MARK
+0x23	0x0023	# NUMBER SIGN
+0x24	0x0024	# DOLLAR SIGN
+0x25	0x0025	# PERCENT SIGN
+0x26	0x0026	# AMPERSAND
+0x27	0x0027	# APOSTROPHE
+0x28	0x0028	# LEFT PARENTHESIS
+0x29	0x0029	# RIGHT PARENTHESIS
+0x2A	0x002A	# ASTERISK
+0x2B	0x002B	# PLUS SIGN
+0x2C	0x002C	# COMMA
+0x2D	0x002D	# HYPHEN-MINUS
+0x2E	0x002E	# FULL STOP
+0x2F	0x002F	# SOLIDUS
+0x30	0x0030	# DIGIT ZERO
+0x31	0x0031	# DIGIT ONE
+0x32	0x0032	# DIGIT TWO
+0x33	0x0033	# DIGIT THREE
+0x34	0x0034	# DIGIT FOUR
+0x35	0x0035	# DIGIT FIVE
+0x36	0x0036	# DIGIT SIX
+0x37	0x0037	# DIGIT SEVEN
+0x38	0x0038	# DIGIT EIGHT
+0x39	0x0039	# DIGIT NINE
+0x3A	0x003A	# COLON
+0x3B	0x003B	# SEMICOLON
+0x3C	0x003C	# LESS-THAN SIGN
+0x3D	0x003D	# EQUALS SIGN
+0x3E	0x003E	# GREATER-THAN SIGN
+0x3F	0x003F	# QUESTION MARK
+0x40	0x0040	# COMMERCIAL AT
+0x41	0x0041	# LATIN CAPITAL LETTER A
+0x42	0x0042	# LATIN CAPITAL LETTER B
+0x43	0x0043	# LATIN CAPITAL LETTER C
+0x44	0x0044	# LATIN CAPITAL LETTER D
+0x45	0x0045	# LATIN CAPITAL LETTER E
+0x46	0x0046	# LATIN CAPITAL LETTER F
+0x47	0x0047	# LATIN CAPITAL LETTER G
+0x48	0x0048	# LATIN CAPITAL LETTER H
+0x49	0x0049	# LATIN CAPITAL LETTER I
+0x4A	0x004A	# LATIN CAPITAL LETTER J
+0x4B	0x004B	# LATIN CAPITAL LETTER K
+0x4C	0x004C	# LATIN CAPITAL LETTER L
+0x4D	0x004D	# LATIN CAPITAL LETTER M
+0x4E	0x004E	# LATIN CAPITAL LETTER N
+0x4F	0x004F	# LATIN CAPITAL LETTER O
+0x50	0x0050	# LATIN CAPITAL LETTER P
+0x51	0x0051	# LATIN CAPITAL LETTER Q
+0x52	0x0052	# LATIN CAPITAL LETTER R
+0x53	0x0053	# LATIN CAPITAL LETTER S
+0x54	0x0054	# LATIN CAPITAL LETTER T
+0x55	0x0055	# LATIN CAPITAL LETTER U
+0x56	0x0056	# LATIN CAPITAL LETTER V
+0x57	0x0057	# LATIN CAPITAL LETTER W
+0x58	0x0058	# LATIN CAPITAL LETTER X
+0x59	0x0059	# LATIN CAPITAL LETTER Y
+0x5A	0x005A	# LATIN CAPITAL LETTER Z
+0x5B	0x005B	# LEFT SQUARE BRACKET
+0x5C	0x005C	#REVERSE SOLIDUS (rendered as Halfwidth Yen Sign)
+0x5D	0x005D	# RIGHT SQUARE BRACKET
+0x5E	0x005E	# CIRCUMFLEX ACCENT
+0x5F	0x005F	# LOW LINE
+0x60	0x0060	# GRAVE ACCENT
+0x61	0x0061	# LATIN SMALL LETTER A
+0x62	0x0062	# LATIN SMALL LETTER B
+0x63	0x0063	# LATIN SMALL LETTER C
+0x64	0x0064	# LATIN SMALL LETTER D
+0x65	0x0065	# LATIN SMALL LETTER E
+0x66	0x0066	# LATIN SMALL LETTER F
+0x67	0x0067	# LATIN SMALL LETTER G
+0x68	0x0068	# LATIN SMALL LETTER H
+0x69	0x0069	# LATIN SMALL LETTER I
+0x6A	0x006A	# LATIN SMALL LETTER J
+0x6B	0x006B	# LATIN SMALL LETTER K
+0x6C	0x006C	# LATIN SMALL LETTER L
+0x6D	0x006D	# LATIN SMALL LETTER M
+0x6E	0x006E	# LATIN SMALL LETTER N
+0x6F	0x006F	# LATIN SMALL LETTER O
+0x70	0x0070	# LATIN SMALL LETTER P
+0x71	0x0071	# LATIN SMALL LETTER Q
+0x72	0x0072	# LATIN SMALL LETTER R
+0x73	0x0073	# LATIN SMALL LETTER S
+0x74	0x0074	# LATIN SMALL LETTER T
+0x75	0x0075	# LATIN SMALL LETTER U
+0x76	0x0076	# LATIN SMALL LETTER V
+0x77	0x0077	# LATIN SMALL LETTER W
+0x78	0x0078	# LATIN SMALL LETTER X
+0x79	0x0079	# LATIN SMALL LETTER Y
+0x7A	0x007A	# LATIN SMALL LETTER Z
+0x7B	0x007B	# LEFT CURLY BRACKET
+0x7C	0x007C	# VERTICAL LINE
+0x7D	0x007D	# RIGHT CURLY BRACKET
+0x7E	0x203E	# OVERLINE
+0xA1	0xFF61	# HALFWIDTH IDEOGRAPHIC FULL STOP
+0xA2	0xFF62	# HALFWIDTH LEFT CORNER BRACKET
+0xA3	0xFF63	# HALFWIDTH RIGHT CORNER BRACKET
+0xA4	0xFF64	# HALFWIDTH IDEOGRAPHIC COMMA
+0xA5	0xFF65	# HALFWIDTH KATAKANA MIDDLE DOT
+0xA6	0xFF66	# HALFWIDTH KATAKANA LETTER WO
+0xA7	0xFF67	# HALFWIDTH KATAKANA LETTER SMALL A
+0xA8	0xFF68	# HALFWIDTH KATAKANA LETTER SMALL I
+0xA9	0xFF69	# HALFWIDTH KATAKANA LETTER SMALL U
+0xAA	0xFF6A	# HALFWIDTH KATAKANA LETTER SMALL E
+0xAB	0xFF6B	# HALFWIDTH KATAKANA LETTER SMALL O
+0xAC	0xFF6C	# HALFWIDTH KATAKANA LETTER SMALL YA
+0xAD	0xFF6D	# HALFWIDTH KATAKANA LETTER SMALL YU
+0xAE	0xFF6E	# HALFWIDTH KATAKANA LETTER SMALL YO
+0xAF	0xFF6F	# HALFWIDTH KATAKANA LETTER SMALL TU
+0xB0	0xFF70	# HALFWIDTH KATAKANA-HIRAGANA PROLONGED SOUND MARK
+0xB1	0xFF71	# HALFWIDTH KATAKANA LETTER A
+0xB2	0xFF72	# HALFWIDTH KATAKANA LETTER I
+0xB3	0xFF73	# HALFWIDTH KATAKANA LETTER U
+0xB4	0xFF74	# HALFWIDTH KATAKANA LETTER E
+0xB5	0xFF75	# HALFWIDTH KATAKANA LETTER O
+0xB6	0xFF76	# HALFWIDTH KATAKANA LETTER KA
+0xB7	0xFF77	# HALFWIDTH KATAKANA LETTER KI
+0xB8	0xFF78	# HALFWIDTH KATAKANA LETTER KU
+0xB9	0xFF79	# HALFWIDTH KATAKANA LETTER KE
+0xBA	0xFF7A	# HALFWIDTH KATAKANA LETTER KO
+0xBB	0xFF7B	# HALFWIDTH KATAKANA LETTER SA
+0xBC	0xFF7C	# HALFWIDTH KATAKANA LETTER SI
+0xBD	0xFF7D	# HALFWIDTH KATAKANA LETTER SU
+0xBE	0xFF7E	# HALFWIDTH KATAKANA LETTER SE
+0xBF	0xFF7F	# HALFWIDTH KATAKANA LETTER SO
+0xC0	0xFF80	# HALFWIDTH KATAKANA LETTER TA
+0xC1	0xFF81	# HALFWIDTH KATAKANA LETTER TI
+0xC2	0xFF82	# HALFWIDTH KATAKANA LETTER TU
+0xC3	0xFF83	# HALFWIDTH KATAKANA LETTER TE
+0xC4	0xFF84	# HALFWIDTH KATAKANA LETTER TO
+0xC5	0xFF85	# HALFWIDTH KATAKANA LETTER NA
+0xC6	0xFF86	# HALFWIDTH KATAKANA LETTER NI
+0xC7	0xFF87	# HALFWIDTH KATAKANA LETTER NU
+0xC8	0xFF88	# HALFWIDTH KATAKANA LETTER NE
+0xC9	0xFF89	# HALFWIDTH KATAKANA LETTER NO
+0xCA	0xFF8A	# HALFWIDTH KATAKANA LETTER HA
+0xCB	0xFF8B	# HALFWIDTH KATAKANA LETTER HI
+0xCC	0xFF8C	# HALFWIDTH KATAKANA LETTER HU
+0xCD	0xFF8D	# HALFWIDTH KATAKANA LETTER HE
+0xCE	0xFF8E	# HALFWIDTH KATAKANA LETTER HO
+0xCF	0xFF8F	# HALFWIDTH KATAKANA LETTER MA
+0xD0	0xFF90	# HALFWIDTH KATAKANA LETTER MI
+0xD1	0xFF91	# HALFWIDTH KATAKANA LETTER MU
+0xD2	0xFF92	# HALFWIDTH KATAKANA LETTER ME
+0xD3	0xFF93	# HALFWIDTH KATAKANA LETTER MO
+0xD4	0xFF94	# HALFWIDTH KATAKANA LETTER YA
+0xD5	0xFF95	# HALFWIDTH KATAKANA LETTER YU
+0xD6	0xFF96	# HALFWIDTH KATAKANA LETTER YO
+0xD7	0xFF97	# HALFWIDTH KATAKANA LETTER RA
+0xD8	0xFF98	# HALFWIDTH KATAKANA LETTER RI
+0xD9	0xFF99	# HALFWIDTH KATAKANA LETTER RU
+0xDA	0xFF9A	# HALFWIDTH KATAKANA LETTER RE
+0xDB	0xFF9B	# HALFWIDTH KATAKANA LETTER RO
+0xDC	0xFF9C	# HALFWIDTH KATAKANA LETTER WA
+0xDD	0xFF9D	# HALFWIDTH KATAKANA LETTER N
+0xDE	0xFF9E	# HALFWIDTH KATAKANA VOICED SOUND MARK
+0xDF	0xFF9F	# HALFWIDTH KATAKANA SEMI-VOICED SOUND MARK
diff --git a/tools/encoding/jis0208.txt b/tools/encoding/jis0208.txt
new file mode 100644
index 0000000..ef9ce79
--- /dev/null
+++ b/tools/encoding/jis0208.txt
@@ -0,0 +1,6940 @@
+#
+#	Name:             JIS X 0208 (1990) to Unicode
+#	Unicode version:  1.1
+#	Table version:    0.9
+#	Table format:     Format A
+#	Date:             8 March 1994
+#	Authors:          Glenn Adams <glenn@metis.com>
+#                     John H. Jenkins <John_Jenkins@taligent.com>
+#
+#	Copyright (c) 1991-1994 Unicode, Inc.  All Rights reserved.
+#
+#	This file is provided as-is by Unicode, Inc. (The Unicode Consortium).
+#	No claims are made as to fitness for any particular purpose.  No
+#	warranties of any kind are expressed or implied.  The recipient
+#	agrees to determine applicability of information provided.  If this
+#	file has been provided on magnetic media by Unicode, Inc., the sole
+#	remedy for any claim will be exchange of defective media within 90
+#	days of receipt.
+#
+#	Recipient is granted the right to make copies in any form for
+#	internal distribution and to freely use the information supplied
+#	in the creation of products supporting Unicode.  Unicode, Inc.
+#	specifically excludes the right to re-distribute this file directly
+#	to third parties or other organizations whether for profit or not.
+#
+#	General notes:
+#
+#	This table contains the data the Unicode Consortium has on how
+#       JIS X 0208 (1983) characters map into Unicode.
+#
+#	Format:  Four tab-separated columns
+#		 Column #1 is the shift-JIS code (in hex)
+#		 Column #2 is the JIS X 0208 code (in hex as 0xXXXX)
+#		 Column #3 is the Unicode (in hex as 0xXXXX)
+#		 Column #4 the Unicode name (follows a comment sign, '#')
+#					The official names for Unicode characters U+4E00
+#					to U+9FA5, inclusive, is "CJK UNIFIED IDEOGRAPH-XXXX",
+#					where XXXX is the code point.  Including all these
+#					names in this file increases its size substantially
+#					and needlessly.  The token "<CJK>" is used for the
+#					name of these characters.  If necessary, it can be
+#					expanded algorithmically by a parser or editor.
+#
+#	The entries are in JIS X 0208 order
+#
+#	The following algorithms can be used to change the hex form
+#		of JIS 0208 to other standard forms:
+#
+#		To change hex to EUC form, add 0x8080
+#		To change hex to kuten form, first subtract 0x2020.  Then
+#			the high and low bytes correspond to the ku and ten of
+#			the kuten form.  For example, 0x2121 -> 0x0101 -> 0101;
+#			0x7426 -> 0x5406 -> 8406
+#
+#   The kanji mappings are a normative part of ISO/IEC 10646.  The
+#       non-kanji mappings are provisional, pending definition of
+#       official mappings by Japanese standards bodies
+#
+#	Any comments or problems, contact <John_Jenkins@taligent.com>
+#
+#
+0x8140	0x2121	0x3000	# IDEOGRAPHIC SPACE
+0x8141	0x2122	0x3001	# IDEOGRAPHIC COMMA
+0x8142	0x2123	0x3002	# IDEOGRAPHIC FULL STOP
+0x8143	0x2124	0xFF0C	# FULLWIDTH COMMA
+0x8144	0x2125	0xFF0E	# FULLWIDTH FULL STOP
+0x8145	0x2126	0x30FB	# KATAKANA MIDDLE DOT
+0x8146	0x2127	0xFF1A	# FULLWIDTH COLON
+0x8147	0x2128	0xFF1B	# FULLWIDTH SEMICOLON
+0x8148	0x2129	0xFF1F	# FULLWIDTH QUESTION MARK
+0x8149	0x212A	0xFF01	# FULLWIDTH EXCLAMATION MARK
+0x814A	0x212B	0x309B	# KATAKANA-HIRAGANA VOICED SOUND MARK
+0x814B	0x212C	0x309C	# KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK
+0x814C	0x212D	0x00B4	# ACUTE ACCENT
+0x814D	0x212E	0xFF40	# FULLWIDTH GRAVE ACCENT
+0x814E	0x212F	0x00A8	# DIAERESIS
+0x814F	0x2130	0xFF3E	# FULLWIDTH CIRCUMFLEX ACCENT
+0x8150	0x2131	0xFFE3	# FULLWIDTH MACRON
+0x8151	0x2132	0xFF3F	# FULLWIDTH LOW LINE
+0x8152	0x2133	0x30FD	# KATAKANA ITERATION MARK
+0x8153	0x2134	0x30FE	# KATAKANA VOICED ITERATION MARK
+0x8154	0x2135	0x309D	# HIRAGANA ITERATION MARK
+0x8155	0x2136	0x309E	# HIRAGANA VOICED ITERATION MARK
+0x8156	0x2137	0x3003	# DITTO MARK
+0x8157	0x2138	0x4EDD	# <CJK>
+0x8158	0x2139	0x3005	# IDEOGRAPHIC ITERATION MARK
+0x8159	0x213A	0x3006	# IDEOGRAPHIC CLOSING MARK
+0x815A	0x213B	0x3007	# IDEOGRAPHIC NUMBER ZERO
+0x815B	0x213C	0x30FC	# KATAKANA-HIRAGANA PROLONGED SOUND MARK
+0x815C	0x213D	0x2015	# HORIZONTAL BAR
+0x815D	0x213E	0x2010	# HYPHEN
+0x815E	0x213F	0xFF0F	# FULLWIDTH SOLIDUS
+0x815F	0x2140	0xFF3C	# FULLWIDTH REVERSE SOLIDUS
+0x8160	0x2141	0x301C	# WAVE DASH
+0x8161	0x2142	0x2016	# DOUBLE VERTICAL LINE
+0x8162	0x2143	0xFF5C	# FULLWIDTH VERTICAL LINE
+0x8163	0x2144	0x2026	# HORIZONTAL ELLIPSIS
+0x8164	0x2145	0x2025	# TWO DOT LEADER
+0x8165	0x2146	0x2018	# LEFT SINGLE QUOTATION MARK
+0x8166	0x2147	0x2019	# RIGHT SINGLE QUOTATION MARK
+0x8167	0x2148	0x201C	# LEFT DOUBLE QUOTATION MARK
+0x8168	0x2149	0x201D	# RIGHT DOUBLE QUOTATION MARK
+0x8169	0x214A	0xFF08	# FULLWIDTH LEFT PARENTHESIS
+0x816A	0x214B	0xFF09	# FULLWIDTH RIGHT PARENTHESIS
+0x816B	0x214C	0x3014	# LEFT TORTOISE SHELL BRACKET
+0x816C	0x214D	0x3015	# RIGHT TORTOISE SHELL BRACKET
+0x816D	0x214E	0xFF3B	# FULLWIDTH LEFT SQUARE BRACKET
+0x816E	0x214F	0xFF3D	# FULLWIDTH RIGHT SQUARE BRACKET
+0x816F	0x2150	0xFF5B	# FULLWIDTH LEFT CURLY BRACKET
+0x8170	0x2151	0xFF5D	# FULLWIDTH RIGHT CURLY BRACKET
+0x8171	0x2152	0x3008	# LEFT ANGLE BRACKET
+0x8172	0x2153	0x3009	# RIGHT ANGLE BRACKET
+0x8173	0x2154	0x300A	# LEFT DOUBLE ANGLE BRACKET
+0x8174	0x2155	0x300B	# RIGHT DOUBLE ANGLE BRACKET
+0x8175	0x2156	0x300C	# LEFT CORNER BRACKET
+0x8176	0x2157	0x300D	# RIGHT CORNER BRACKET
+0x8177	0x2158	0x300E	# LEFT WHITE CORNER BRACKET
+0x8178	0x2159	0x300F	# RIGHT WHITE CORNER BRACKET
+0x8179	0x215A	0x3010	# LEFT BLACK LENTICULAR BRACKET
+0x817A	0x215B	0x3011	# RIGHT BLACK LENTICULAR BRACKET
+0x817B	0x215C	0xFF0B	# FULLWIDTH PLUS SIGN
+0x817C	0x215D	0x2212	# MINUS SIGN
+0x817D	0x215E	0x00B1	# PLUS-MINUS SIGN
+0x817E	0x215F	0x00D7	# MULTIPLICATION SIGN
+0x8180	0x2160	0x00F7	# DIVISION SIGN
+0x8181	0x2161	0xFF1D	# FULLWIDTH EQUALS SIGN
+0x8182	0x2162	0x2260	# NOT EQUAL TO
+0x8183	0x2163	0xFF1C	# FULLWIDTH LESS-THAN SIGN
+0x8184	0x2164	0xFF1E	# FULLWIDTH GREATER-THAN SIGN
+0x8185	0x2165	0x2266	# LESS-THAN OVER EQUAL TO
+0x8186	0x2166	0x2267	# GREATER-THAN OVER EQUAL TO
+0x8187	0x2167	0x221E	# INFINITY
+0x8188	0x2168	0x2234	# THEREFORE
+0x8189	0x2169	0x2642	# MALE SIGN
+0x818A	0x216A	0x2640	# FEMALE SIGN
+0x818B	0x216B	0x00B0	# DEGREE SIGN
+0x818C	0x216C	0x2032	# PRIME
+0x818D	0x216D	0x2033	# DOUBLE PRIME
+0x818E	0x216E	0x2103	# DEGREE CELSIUS
+0x818F	0x216F	0xFFE5	# FULLWIDTH YEN SIGN
+0x8190	0x2170	0xFF04	# FULLWIDTH DOLLAR SIGN
+0x8191	0x2171	0x00A2	# CENT SIGN
+0x8192	0x2172	0x00A3	# POUND SIGN
+0x8193	0x2173	0xFF05	# FULLWIDTH PERCENT SIGN
+0x8194	0x2174	0xFF03	# FULLWIDTH NUMBER SIGN
+0x8195	0x2175	0xFF06	# FULLWIDTH AMPERSAND
+0x8196	0x2176	0xFF0A	# FULLWIDTH ASTERISK
+0x8197	0x2177	0xFF20	# FULLWIDTH COMMERCIAL AT
+0x8198	0x2178	0x00A7	# SECTION SIGN
+0x8199	0x2179	0x2606	# WHITE STAR
+0x819A	0x217A	0x2605	# BLACK STAR
+0x819B	0x217B	0x25CB	# WHITE CIRCLE
+0x819C	0x217C	0x25CF	# BLACK CIRCLE
+0x819D	0x217D	0x25CE	# BULLSEYE
+0x819E	0x217E	0x25C7	# WHITE DIAMOND
+0x819F	0x2221	0x25C6	# BLACK DIAMOND
+0x81A0	0x2222	0x25A1	# WHITE SQUARE
+0x81A1	0x2223	0x25A0	# BLACK SQUARE
+0x81A2	0x2224	0x25B3	# WHITE UP-POINTING TRIANGLE
+0x81A3	0x2225	0x25B2	# BLACK UP-POINTING TRIANGLE
+0x81A4	0x2226	0x25BD	# WHITE DOWN-POINTING TRIANGLE
+0x81A5	0x2227	0x25BC	# BLACK DOWN-POINTING TRIANGLE
+0x81A6	0x2228	0x203B	# REFERENCE MARK
+0x81A7	0x2229	0x3012	# POSTAL MARK
+0x81A8	0x222A	0x2192	# RIGHTWARDS ARROW
+0x81A9	0x222B	0x2190	# LEFTWARDS ARROW
+0x81AA	0x222C	0x2191	# UPWARDS ARROW
+0x81AB	0x222D	0x2193	# DOWNWARDS ARROW
+0x81AC	0x222E	0x3013	# GETA MARK
+0x81B8	0x223A	0x2208	# ELEMENT OF
+0x81B9	0x223B	0x220B	# CONTAINS AS MEMBER
+0x81BA	0x223C	0x2286	# SUBSET OF OR EQUAL TO
+0x81BB	0x223D	0x2287	# SUPERSET OF OR EQUAL TO
+0x81BC	0x223E	0x2282	# SUBSET OF
+0x81BD	0x223F	0x2283	# SUPERSET OF
+0x81BE	0x2240	0x222A	# UNION
+0x81BF	0x2241	0x2229	# INTERSECTION
+0x81C8	0x224A	0x2227	# LOGICAL AND
+0x81C9	0x224B	0x2228	# LOGICAL OR
+0x81CA	0x224C	0x00AC	# NOT SIGN
+0x81CB	0x224D	0x21D2	# RIGHTWARDS DOUBLE ARROW
+0x81CC	0x224E	0x21D4	# LEFT RIGHT DOUBLE ARROW
+0x81CD	0x224F	0x2200	# FOR ALL
+0x81CE	0x2250	0x2203	# THERE EXISTS
+0x81DA	0x225C	0x2220	# ANGLE
+0x81DB	0x225D	0x22A5	# UP TACK
+0x81DC	0x225E	0x2312	# ARC
+0x81DD	0x225F	0x2202	# PARTIAL DIFFERENTIAL
+0x81DE	0x2260	0x2207	# NABLA
+0x81DF	0x2261	0x2261	# IDENTICAL TO
+0x81E0	0x2262	0x2252	# APPROXIMATELY EQUAL TO OR THE IMAGE OF
+0x81E1	0x2263	0x226A	# MUCH LESS-THAN
+0x81E2	0x2264	0x226B	# MUCH GREATER-THAN
+0x81E3	0x2265	0x221A	# SQUARE ROOT
+0x81E4	0x2266	0x223D	# REVERSED TILDE
+0x81E5	0x2267	0x221D	# PROPORTIONAL TO
+0x81E6	0x2268	0x2235	# BECAUSE
+0x81E7	0x2269	0x222B	# INTEGRAL
+0x81E8	0x226A	0x222C	# DOUBLE INTEGRAL
+0x81F0	0x2272	0x212B	# ANGSTROM SIGN
+0x81F1	0x2273	0x2030	# PER MILLE SIGN
+0x81F2	0x2274	0x266F	# MUSIC SHARP SIGN
+0x81F3	0x2275	0x266D	# MUSIC FLAT SIGN
+0x81F4	0x2276	0x266A	# EIGHTH NOTE
+0x81F5	0x2277	0x2020	# DAGGER
+0x81F6	0x2278	0x2021	# DOUBLE DAGGER
+0x81F7	0x2279	0x00B6	# PILCROW SIGN
+0x81FC	0x227E	0x25EF	# LARGE CIRCLE
+0x824F	0x2330	0xFF10	# FULLWIDTH DIGIT ZERO
+0x8250	0x2331	0xFF11	# FULLWIDTH DIGIT ONE
+0x8251	0x2332	0xFF12	# FULLWIDTH DIGIT TWO
+0x8252	0x2333	0xFF13	# FULLWIDTH DIGIT THREE
+0x8253	0x2334	0xFF14	# FULLWIDTH DIGIT FOUR
+0x8254	0x2335	0xFF15	# FULLWIDTH DIGIT FIVE
+0x8255	0x2336	0xFF16	# FULLWIDTH DIGIT SIX
+0x8256	0x2337	0xFF17	# FULLWIDTH DIGIT SEVEN
+0x8257	0x2338	0xFF18	# FULLWIDTH DIGIT EIGHT
+0x8258	0x2339	0xFF19	# FULLWIDTH DIGIT NINE
+0x8260	0x2341	0xFF21	# FULLWIDTH LATIN CAPITAL LETTER A
+0x8261	0x2342	0xFF22	# FULLWIDTH LATIN CAPITAL LETTER B
+0x8262	0x2343	0xFF23	# FULLWIDTH LATIN CAPITAL LETTER C
+0x8263	0x2344	0xFF24	# FULLWIDTH LATIN CAPITAL LETTER D
+0x8264	0x2345	0xFF25	# FULLWIDTH LATIN CAPITAL LETTER E
+0x8265	0x2346	0xFF26	# FULLWIDTH LATIN CAPITAL LETTER F
+0x8266	0x2347	0xFF27	# FULLWIDTH LATIN CAPITAL LETTER G
+0x8267	0x2348	0xFF28	# FULLWIDTH LATIN CAPITAL LETTER H
+0x8268	0x2349	0xFF29	# FULLWIDTH LATIN CAPITAL LETTER I
+0x8269	0x234A	0xFF2A	# FULLWIDTH LATIN CAPITAL LETTER J
+0x826A	0x234B	0xFF2B	# FULLWIDTH LATIN CAPITAL LETTER K
+0x826B	0x234C	0xFF2C	# FULLWIDTH LATIN CAPITAL LETTER L
+0x826C	0x234D	0xFF2D	# FULLWIDTH LATIN CAPITAL LETTER M
+0x826D	0x234E	0xFF2E	# FULLWIDTH LATIN CAPITAL LETTER N
+0x826E	0x234F	0xFF2F	# FULLWIDTH LATIN CAPITAL LETTER O
+0x826F	0x2350	0xFF30	# FULLWIDTH LATIN CAPITAL LETTER P
+0x8270	0x2351	0xFF31	# FULLWIDTH LATIN CAPITAL LETTER Q
+0x8271	0x2352	0xFF32	# FULLWIDTH LATIN CAPITAL LETTER R
+0x8272	0x2353	0xFF33	# FULLWIDTH LATIN CAPITAL LETTER S
+0x8273	0x2354	0xFF34	# FULLWIDTH LATIN CAPITAL LETTER T
+0x8274	0x2355	0xFF35	# FULLWIDTH LATIN CAPITAL LETTER U
+0x8275	0x2356	0xFF36	# FULLWIDTH LATIN CAPITAL LETTER V
+0x8276	0x2357	0xFF37	# FULLWIDTH LATIN CAPITAL LETTER W
+0x8277	0x2358	0xFF38	# FULLWIDTH LATIN CAPITAL LETTER X
+0x8278	0x2359	0xFF39	# FULLWIDTH LATIN CAPITAL LETTER Y
+0x8279	0x235A	0xFF3A	# FULLWIDTH LATIN CAPITAL LETTER Z
+0x8281	0x2361	0xFF41	# FULLWIDTH LATIN SMALL LETTER A
+0x8282	0x2362	0xFF42	# FULLWIDTH LATIN SMALL LETTER B
+0x8283	0x2363	0xFF43	# FULLWIDTH LATIN SMALL LETTER C
+0x8284	0x2364	0xFF44	# FULLWIDTH LATIN SMALL LETTER D
+0x8285	0x2365	0xFF45	# FULLWIDTH LATIN SMALL LETTER E
+0x8286	0x2366	0xFF46	# FULLWIDTH LATIN SMALL LETTER F
+0x8287	0x2367	0xFF47	# FULLWIDTH LATIN SMALL LETTER G
+0x8288	0x2368	0xFF48	# FULLWIDTH LATIN SMALL LETTER H
+0x8289	0x2369	0xFF49	# FULLWIDTH LATIN SMALL LETTER I
+0x828A	0x236A	0xFF4A	# FULLWIDTH LATIN SMALL LETTER J
+0x828B	0x236B	0xFF4B	# FULLWIDTH LATIN SMALL LETTER K
+0x828C	0x236C	0xFF4C	# FULLWIDTH LATIN SMALL LETTER L
+0x828D	0x236D	0xFF4D	# FULLWIDTH LATIN SMALL LETTER M
+0x828E	0x236E	0xFF4E	# FULLWIDTH LATIN SMALL LETTER N
+0x828F	0x236F	0xFF4F	# FULLWIDTH LATIN SMALL LETTER O
+0x8290	0x2370	0xFF50	# FULLWIDTH LATIN SMALL LETTER P
+0x8291	0x2371	0xFF51	# FULLWIDTH LATIN SMALL LETTER Q
+0x8292	0x2372	0xFF52	# FULLWIDTH LATIN SMALL LETTER R
+0x8293	0x2373	0xFF53	# FULLWIDTH LATIN SMALL LETTER S
+0x8294	0x2374	0xFF54	# FULLWIDTH LATIN SMALL LETTER T
+0x8295	0x2375	0xFF55	# FULLWIDTH LATIN SMALL LETTER U
+0x8296	0x2376	0xFF56	# FULLWIDTH LATIN SMALL LETTER V
+0x8297	0x2377	0xFF57	# FULLWIDTH LATIN SMALL LETTER W
+0x8298	0x2378	0xFF58	# FULLWIDTH LATIN SMALL LETTER X
+0x8299	0x2379	0xFF59	# FULLWIDTH LATIN SMALL LETTER Y
+0x829A	0x237A	0xFF5A	# FULLWIDTH LATIN SMALL LETTER Z
+0x829F	0x2421	0x3041	# HIRAGANA LETTER SMALL A
+0x82A0	0x2422	0x3042	# HIRAGANA LETTER A
+0x82A1	0x2423	0x3043	# HIRAGANA LETTER SMALL I
+0x82A2	0x2424	0x3044	# HIRAGANA LETTER I
+0x82A3	0x2425	0x3045	# HIRAGANA LETTER SMALL U
+0x82A4	0x2426	0x3046	# HIRAGANA LETTER U
+0x82A5	0x2427	0x3047	# HIRAGANA LETTER SMALL E
+0x82A6	0x2428	0x3048	# HIRAGANA LETTER E
+0x82A7	0x2429	0x3049	# HIRAGANA LETTER SMALL O
+0x82A8	0x242A	0x304A	# HIRAGANA LETTER O
+0x82A9	0x242B	0x304B	# HIRAGANA LETTER KA
+0x82AA	0x242C	0x304C	# HIRAGANA LETTER GA
+0x82AB	0x242D	0x304D	# HIRAGANA LETTER KI
+0x82AC	0x242E	0x304E	# HIRAGANA LETTER GI
+0x82AD	0x242F	0x304F	# HIRAGANA LETTER KU
+0x82AE	0x2430	0x3050	# HIRAGANA LETTER GU
+0x82AF	0x2431	0x3051	# HIRAGANA LETTER KE
+0x82B0	0x2432	0x3052	# HIRAGANA LETTER GE
+0x82B1	0x2433	0x3053	# HIRAGANA LETTER KO
+0x82B2	0x2434	0x3054	# HIRAGANA LETTER GO
+0x82B3	0x2435	0x3055	# HIRAGANA LETTER SA
+0x82B4	0x2436	0x3056	# HIRAGANA LETTER ZA
+0x82B5	0x2437	0x3057	# HIRAGANA LETTER SI
+0x82B6	0x2438	0x3058	# HIRAGANA LETTER ZI
+0x82B7	0x2439	0x3059	# HIRAGANA LETTER SU
+0x82B8	0x243A	0x305A	# HIRAGANA LETTER ZU
+0x82B9	0x243B	0x305B	# HIRAGANA LETTER SE
+0x82BA	0x243C	0x305C	# HIRAGANA LETTER ZE
+0x82BB	0x243D	0x305D	# HIRAGANA LETTER SO
+0x82BC	0x243E	0x305E	# HIRAGANA LETTER ZO
+0x82BD	0x243F	0x305F	# HIRAGANA LETTER TA
+0x82BE	0x2440	0x3060	# HIRAGANA LETTER DA
+0x82BF	0x2441	0x3061	# HIRAGANA LETTER TI
+0x82C0	0x2442	0x3062	# HIRAGANA LETTER DI
+0x82C1	0x2443	0x3063	# HIRAGANA LETTER SMALL TU
+0x82C2	0x2444	0x3064	# HIRAGANA LETTER TU
+0x82C3	0x2445	0x3065	# HIRAGANA LETTER DU
+0x82C4	0x2446	0x3066	# HIRAGANA LETTER TE
+0x82C5	0x2447	0x3067	# HIRAGANA LETTER DE
+0x82C6	0x2448	0x3068	# HIRAGANA LETTER TO
+0x82C7	0x2449	0x3069	# HIRAGANA LETTER DO
+0x82C8	0x244A	0x306A	# HIRAGANA LETTER NA
+0x82C9	0x244B	0x306B	# HIRAGANA LETTER NI
+0x82CA	0x244C	0x306C	# HIRAGANA LETTER NU
+0x82CB	0x244D	0x306D	# HIRAGANA LETTER NE
+0x82CC	0x244E	0x306E	# HIRAGANA LETTER NO
+0x82CD	0x244F	0x306F	# HIRAGANA LETTER HA
+0x82CE	0x2450	0x3070	# HIRAGANA LETTER BA
+0x82CF	0x2451	0x3071	# HIRAGANA LETTER PA
+0x82D0	0x2452	0x3072	# HIRAGANA LETTER HI
+0x82D1	0x2453	0x3073	# HIRAGANA LETTER BI
+0x82D2	0x2454	0x3074	# HIRAGANA LETTER PI
+0x82D3	0x2455	0x3075	# HIRAGANA LETTER HU
+0x82D4	0x2456	0x3076	# HIRAGANA LETTER BU
+0x82D5	0x2457	0x3077	# HIRAGANA LETTER PU
+0x82D6	0x2458	0x3078	# HIRAGANA LETTER HE
+0x82D7	0x2459	0x3079	# HIRAGANA LETTER BE
+0x82D8	0x245A	0x307A	# HIRAGANA LETTER PE
+0x82D9	0x245B	0x307B	# HIRAGANA LETTER HO
+0x82DA	0x245C	0x307C	# HIRAGANA LETTER BO
+0x82DB	0x245D	0x307D	# HIRAGANA LETTER PO
+0x82DC	0x245E	0x307E	# HIRAGANA LETTER MA
+0x82DD	0x245F	0x307F	# HIRAGANA LETTER MI
+0x82DE	0x2460	0x3080	# HIRAGANA LETTER MU
+0x82DF	0x2461	0x3081	# HIRAGANA LETTER ME
+0x82E0	0x2462	0x3082	# HIRAGANA LETTER MO
+0x82E1	0x2463	0x3083	# HIRAGANA LETTER SMALL YA
+0x82E2	0x2464	0x3084	# HIRAGANA LETTER YA
+0x82E3	0x2465	0x3085	# HIRAGANA LETTER SMALL YU
+0x82E4	0x2466	0x3086	# HIRAGANA LETTER YU
+0x82E5	0x2467	0x3087	# HIRAGANA LETTER SMALL YO
+0x82E6	0x2468	0x3088	# HIRAGANA LETTER YO
+0x82E7	0x2469	0x3089	# HIRAGANA LETTER RA
+0x82E8	0x246A	0x308A	# HIRAGANA LETTER RI
+0x82E9	0x246B	0x308B	# HIRAGANA LETTER RU
+0x82EA	0x246C	0x308C	# HIRAGANA LETTER RE
+0x82EB	0x246D	0x308D	# HIRAGANA LETTER RO
+0x82EC	0x246E	0x308E	# HIRAGANA LETTER SMALL WA
+0x82ED	0x246F	0x308F	# HIRAGANA LETTER WA
+0x82EE	0x2470	0x3090	# HIRAGANA LETTER WI
+0x82EF	0x2471	0x3091	# HIRAGANA LETTER WE
+0x82F0	0x2472	0x3092	# HIRAGANA LETTER WO
+0x82F1	0x2473	0x3093	# HIRAGANA LETTER N
+0x8340	0x2521	0x30A1	# KATAKANA LETTER SMALL A
+0x8341	0x2522	0x30A2	# KATAKANA LETTER A
+0x8342	0x2523	0x30A3	# KATAKANA LETTER SMALL I
+0x8343	0x2524	0x30A4	# KATAKANA LETTER I
+0x8344	0x2525	0x30A5	# KATAKANA LETTER SMALL U
+0x8345	0x2526	0x30A6	# KATAKANA LETTER U
+0x8346	0x2527	0x30A7	# KATAKANA LETTER SMALL E
+0x8347	0x2528	0x30A8	# KATAKANA LETTER E
+0x8348	0x2529	0x30A9	# KATAKANA LETTER SMALL O
+0x8349	0x252A	0x30AA	# KATAKANA LETTER O
+0x834A	0x252B	0x30AB	# KATAKANA LETTER KA
+0x834B	0x252C	0x30AC	# KATAKANA LETTER GA
+0x834C	0x252D	0x30AD	# KATAKANA LETTER KI
+0x834D	0x252E	0x30AE	# KATAKANA LETTER GI
+0x834E	0x252F	0x30AF	# KATAKANA LETTER KU
+0x834F	0x2530	0x30B0	# KATAKANA LETTER GU
+0x8350	0x2531	0x30B1	# KATAKANA LETTER KE
+0x8351	0x2532	0x30B2	# KATAKANA LETTER GE
+0x8352	0x2533	0x30B3	# KATAKANA LETTER KO
+0x8353	0x2534	0x30B4	# KATAKANA LETTER GO
+0x8354	0x2535	0x30B5	# KATAKANA LETTER SA
+0x8355	0x2536	0x30B6	# KATAKANA LETTER ZA
+0x8356	0x2537	0x30B7	# KATAKANA LETTER SI
+0x8357	0x2538	0x30B8	# KATAKANA LETTER ZI
+0x8358	0x2539	0x30B9	# KATAKANA LETTER SU
+0x8359	0x253A	0x30BA	# KATAKANA LETTER ZU
+0x835A	0x253B	0x30BB	# KATAKANA LETTER SE
+0x835B	0x253C	0x30BC	# KATAKANA LETTER ZE
+0x835C	0x253D	0x30BD	# KATAKANA LETTER SO
+0x835D	0x253E	0x30BE	# KATAKANA LETTER ZO
+0x835E	0x253F	0x30BF	# KATAKANA LETTER TA
+0x835F	0x2540	0x30C0	# KATAKANA LETTER DA
+0x8360	0x2541	0x30C1	# KATAKANA LETTER TI
+0x8361	0x2542	0x30C2	# KATAKANA LETTER DI
+0x8362	0x2543	0x30C3	# KATAKANA LETTER SMALL TU
+0x8363	0x2544	0x30C4	# KATAKANA LETTER TU
+0x8364	0x2545	0x30C5	# KATAKANA LETTER DU
+0x8365	0x2546	0x30C6	# KATAKANA LETTER TE
+0x8366	0x2547	0x30C7	# KATAKANA LETTER DE
+0x8367	0x2548	0x30C8	# KATAKANA LETTER TO
+0x8368	0x2549	0x30C9	# KATAKANA LETTER DO
+0x8369	0x254A	0x30CA	# KATAKANA LETTER NA
+0x836A	0x254B	0x30CB	# KATAKANA LETTER NI
+0x836B	0x254C	0x30CC	# KATAKANA LETTER NU
+0x836C	0x254D	0x30CD	# KATAKANA LETTER NE
+0x836D	0x254E	0x30CE	# KATAKANA LETTER NO
+0x836E	0x254F	0x30CF	# KATAKANA LETTER HA
+0x836F	0x2550	0x30D0	# KATAKANA LETTER BA
+0x8370	0x2551	0x30D1	# KATAKANA LETTER PA
+0x8371	0x2552	0x30D2	# KATAKANA LETTER HI
+0x8372	0x2553	0x30D3	# KATAKANA LETTER BI
+0x8373	0x2554	0x30D4	# KATAKANA LETTER PI
+0x8374	0x2555	0x30D5	# KATAKANA LETTER HU
+0x8375	0x2556	0x30D6	# KATAKANA LETTER BU
+0x8376	0x2557	0x30D7	# KATAKANA LETTER PU
+0x8377	0x2558	0x30D8	# KATAKANA LETTER HE
+0x8378	0x2559	0x30D9	# KATAKANA LETTER BE
+0x8379	0x255A	0x30DA	# KATAKANA LETTER PE
+0x837A	0x255B	0x30DB	# KATAKANA LETTER HO
+0x837B	0x255C	0x30DC	# KATAKANA LETTER BO
+0x837C	0x255D	0x30DD	# KATAKANA LETTER PO
+0x837D	0x255E	0x30DE	# KATAKANA LETTER MA
+0x837E	0x255F	0x30DF	# KATAKANA LETTER MI
+0x8380	0x2560	0x30E0	# KATAKANA LETTER MU
+0x8381	0x2561	0x30E1	# KATAKANA LETTER ME
+0x8382	0x2562	0x30E2	# KATAKANA LETTER MO
+0x8383	0x2563	0x30E3	# KATAKANA LETTER SMALL YA
+0x8384	0x2564	0x30E4	# KATAKANA LETTER YA
+0x8385	0x2565	0x30E5	# KATAKANA LETTER SMALL YU
+0x8386	0x2566	0x30E6	# KATAKANA LETTER YU
+0x8387	0x2567	0x30E7	# KATAKANA LETTER SMALL YO
+0x8388	0x2568	0x30E8	# KATAKANA LETTER YO
+0x8389	0x2569	0x30E9	# KATAKANA LETTER RA
+0x838A	0x256A	0x30EA	# KATAKANA LETTER RI
+0x838B	0x256B	0x30EB	# KATAKANA LETTER RU
+0x838C	0x256C	0x30EC	# KATAKANA LETTER RE
+0x838D	0x256D	0x30ED	# KATAKANA LETTER RO
+0x838E	0x256E	0x30EE	# KATAKANA LETTER SMALL WA
+0x838F	0x256F	0x30EF	# KATAKANA LETTER WA
+0x8390	0x2570	0x30F0	# KATAKANA LETTER WI
+0x8391	0x2571	0x30F1	# KATAKANA LETTER WE
+0x8392	0x2572	0x30F2	# KATAKANA LETTER WO
+0x8393	0x2573	0x30F3	# KATAKANA LETTER N
+0x8394	0x2574	0x30F4	# KATAKANA LETTER VU
+0x8395	0x2575	0x30F5	# KATAKANA LETTER SMALL KA
+0x8396	0x2576	0x30F6	# KATAKANA LETTER SMALL KE
+0x839F	0x2621	0x0391	# GREEK CAPITAL LETTER ALPHA
+0x83A0	0x2622	0x0392	# GREEK CAPITAL LETTER BETA
+0x83A1	0x2623	0x0393	# GREEK CAPITAL LETTER GAMMA
+0x83A2	0x2624	0x0394	# GREEK CAPITAL LETTER DELTA
+0x83A3	0x2625	0x0395	# GREEK CAPITAL LETTER EPSILON
+0x83A4	0x2626	0x0396	# GREEK CAPITAL LETTER ZETA
+0x83A5	0x2627	0x0397	# GREEK CAPITAL LETTER ETA
+0x83A6	0x2628	0x0398	# GREEK CAPITAL LETTER THETA
+0x83A7	0x2629	0x0399	# GREEK CAPITAL LETTER IOTA
+0x83A8	0x262A	0x039A	# GREEK CAPITAL LETTER KAPPA
+0x83A9	0x262B	0x039B	# GREEK CAPITAL LETTER LAMDA
+0x83AA	0x262C	0x039C	# GREEK CAPITAL LETTER MU
+0x83AB	0x262D	0x039D	# GREEK CAPITAL LETTER NU
+0x83AC	0x262E	0x039E	# GREEK CAPITAL LETTER XI
+0x83AD	0x262F	0x039F	# GREEK CAPITAL LETTER OMICRON
+0x83AE	0x2630	0x03A0	# GREEK CAPITAL LETTER PI
+0x83AF	0x2631	0x03A1	# GREEK CAPITAL LETTER RHO
+0x83B0	0x2632	0x03A3	# GREEK CAPITAL LETTER SIGMA
+0x83B1	0x2633	0x03A4	# GREEK CAPITAL LETTER TAU
+0x83B2	0x2634	0x03A5	# GREEK CAPITAL LETTER UPSILON
+0x83B3	0x2635	0x03A6	# GREEK CAPITAL LETTER PHI
+0x83B4	0x2636	0x03A7	# GREEK CAPITAL LETTER CHI
+0x83B5	0x2637	0x03A8	# GREEK CAPITAL LETTER PSI
+0x83B6	0x2638	0x03A9	# GREEK CAPITAL LETTER OMEGA
+0x83BF	0x2641	0x03B1	# GREEK SMALL LETTER ALPHA
+0x83C0	0x2642	0x03B2	# GREEK SMALL LETTER BETA
+0x83C1	0x2643	0x03B3	# GREEK SMALL LETTER GAMMA
+0x83C2	0x2644	0x03B4	# GREEK SMALL LETTER DELTA
+0x83C3	0x2645	0x03B5	# GREEK SMALL LETTER EPSILON
+0x83C4	0x2646	0x03B6	# GREEK SMALL LETTER ZETA
+0x83C5	0x2647	0x03B7	# GREEK SMALL LETTER ETA
+0x83C6	0x2648	0x03B8	# GREEK SMALL LETTER THETA
+0x83C7	0x2649	0x03B9	# GREEK SMALL LETTER IOTA
+0x83C8	0x264A	0x03BA	# GREEK SMALL LETTER KAPPA
+0x83C9	0x264B	0x03BB	# GREEK SMALL LETTER LAMDA
+0x83CA	0x264C	0x03BC	# GREEK SMALL LETTER MU
+0x83CB	0x264D	0x03BD	# GREEK SMALL LETTER NU
+0x83CC	0x264E	0x03BE	# GREEK SMALL LETTER XI
+0x83CD	0x264F	0x03BF	# GREEK SMALL LETTER OMICRON
+0x83CE	0x2650	0x03C0	# GREEK SMALL LETTER PI
+0x83CF	0x2651	0x03C1	# GREEK SMALL LETTER RHO
+0x83D0	0x2652	0x03C3	# GREEK SMALL LETTER SIGMA
+0x83D1	0x2653	0x03C4	# GREEK SMALL LETTER TAU
+0x83D2	0x2654	0x03C5	# GREEK SMALL LETTER UPSILON
+0x83D3	0x2655	0x03C6	# GREEK SMALL LETTER PHI
+0x83D4	0x2656	0x03C7	# GREEK SMALL LETTER CHI
+0x83D5	0x2657	0x03C8	# GREEK SMALL LETTER PSI
+0x83D6	0x2658	0x03C9	# GREEK SMALL LETTER OMEGA
+0x8440	0x2721	0x0410	# CYRILLIC CAPITAL LETTER A
+0x8441	0x2722	0x0411	# CYRILLIC CAPITAL LETTER BE
+0x8442	0x2723	0x0412	# CYRILLIC CAPITAL LETTER VE
+0x8443	0x2724	0x0413	# CYRILLIC CAPITAL LETTER GHE
+0x8444	0x2725	0x0414	# CYRILLIC CAPITAL LETTER DE
+0x8445	0x2726	0x0415	# CYRILLIC CAPITAL LETTER IE
+0x8446	0x2727	0x0401	# CYRILLIC CAPITAL LETTER IO
+0x8447	0x2728	0x0416	# CYRILLIC CAPITAL LETTER ZHE
+0x8448	0x2729	0x0417	# CYRILLIC CAPITAL LETTER ZE
+0x8449	0x272A	0x0418	# CYRILLIC CAPITAL LETTER I
+0x844A	0x272B	0x0419	# CYRILLIC CAPITAL LETTER SHORT I
+0x844B	0x272C	0x041A	# CYRILLIC CAPITAL LETTER KA
+0x844C	0x272D	0x041B	# CYRILLIC CAPITAL LETTER EL
+0x844D	0x272E	0x041C	# CYRILLIC CAPITAL LETTER EM
+0x844E	0x272F	0x041D	# CYRILLIC CAPITAL LETTER EN
+0x844F	0x2730	0x041E	# CYRILLIC CAPITAL LETTER O
+0x8450	0x2731	0x041F	# CYRILLIC CAPITAL LETTER PE
+0x8451	0x2732	0x0420	# CYRILLIC CAPITAL LETTER ER
+0x8452	0x2733	0x0421	# CYRILLIC CAPITAL LETTER ES
+0x8453	0x2734	0x0422	# CYRILLIC CAPITAL LETTER TE
+0x8454	0x2735	0x0423	# CYRILLIC CAPITAL LETTER U
+0x8455	0x2736	0x0424	# CYRILLIC CAPITAL LETTER EF
+0x8456	0x2737	0x0425	# CYRILLIC CAPITAL LETTER HA
+0x8457	0x2738	0x0426	# CYRILLIC CAPITAL LETTER TSE
+0x8458	0x2739	0x0427	# CYRILLIC CAPITAL LETTER CHE
+0x8459	0x273A	0x0428	# CYRILLIC CAPITAL LETTER SHA
+0x845A	0x273B	0x0429	# CYRILLIC CAPITAL LETTER SHCHA
+0x845B	0x273C	0x042A	# CYRILLIC CAPITAL LETTER HARD SIGN
+0x845C	0x273D	0x042B	# CYRILLIC CAPITAL LETTER YERU
+0x845D	0x273E	0x042C	# CYRILLIC CAPITAL LETTER SOFT SIGN
+0x845E	0x273F	0x042D	# CYRILLIC CAPITAL LETTER E
+0x845F	0x2740	0x042E	# CYRILLIC CAPITAL LETTER YU
+0x8460	0x2741	0x042F	# CYRILLIC CAPITAL LETTER YA
+0x8470	0x2751	0x0430	# CYRILLIC SMALL LETTER A
+0x8471	0x2752	0x0431	# CYRILLIC SMALL LETTER BE
+0x8472	0x2753	0x0432	# CYRILLIC SMALL LETTER VE
+0x8473	0x2754	0x0433	# CYRILLIC SMALL LETTER GHE
+0x8474	0x2755	0x0434	# CYRILLIC SMALL LETTER DE
+0x8475	0x2756	0x0435	# CYRILLIC SMALL LETTER IE
+0x8476	0x2757	0x0451	# CYRILLIC SMALL LETTER IO
+0x8477	0x2758	0x0436	# CYRILLIC SMALL LETTER ZHE
+0x8478	0x2759	0x0437	# CYRILLIC SMALL LETTER ZE
+0x8479	0x275A	0x0438	# CYRILLIC SMALL LETTER I
+0x847A	0x275B	0x0439	# CYRILLIC SMALL LETTER SHORT I
+0x847B	0x275C	0x043A	# CYRILLIC SMALL LETTER KA
+0x847C	0x275D	0x043B	# CYRILLIC SMALL LETTER EL
+0x847D	0x275E	0x043C	# CYRILLIC SMALL LETTER EM
+0x847E	0x275F	0x043D	# CYRILLIC SMALL LETTER EN
+0x8480	0x2760	0x043E	# CYRILLIC SMALL LETTER O
+0x8481	0x2761	0x043F	# CYRILLIC SMALL LETTER PE
+0x8482	0x2762	0x0440	# CYRILLIC SMALL LETTER ER
+0x8483	0x2763	0x0441	# CYRILLIC SMALL LETTER ES
+0x8484	0x2764	0x0442	# CYRILLIC SMALL LETTER TE
+0x8485	0x2765	0x0443	# CYRILLIC SMALL LETTER U
+0x8486	0x2766	0x0444	# CYRILLIC SMALL LETTER EF
+0x8487	0x2767	0x0445	# CYRILLIC SMALL LETTER HA
+0x8488	0x2768	0x0446	# CYRILLIC SMALL LETTER TSE
+0x8489	0x2769	0x0447	# CYRILLIC SMALL LETTER CHE
+0x848A	0x276A	0x0448	# CYRILLIC SMALL LETTER SHA
+0x848B	0x276B	0x0449	# CYRILLIC SMALL LETTER SHCHA
+0x848C	0x276C	0x044A	# CYRILLIC SMALL LETTER HARD SIGN
+0x848D	0x276D	0x044B	# CYRILLIC SMALL LETTER YERU
+0x848E	0x276E	0x044C	# CYRILLIC SMALL LETTER SOFT SIGN
+0x848F	0x276F	0x044D	# CYRILLIC SMALL LETTER E
+0x8490	0x2770	0x044E	# CYRILLIC SMALL LETTER YU
+0x8491	0x2771	0x044F	# CYRILLIC SMALL LETTER YA
+0x849F	0x2821	0x2500	# BOX DRAWINGS LIGHT HORIZONTAL
+0x84A0	0x2822	0x2502	# BOX DRAWINGS LIGHT VERTICAL
+0x84A1	0x2823	0x250C	# BOX DRAWINGS LIGHT DOWN AND RIGHT
+0x84A2	0x2824	0x2510	# BOX DRAWINGS LIGHT DOWN AND LEFT
+0x84A3	0x2825	0x2518	# BOX DRAWINGS LIGHT UP AND LEFT
+0x84A4	0x2826	0x2514	# BOX DRAWINGS LIGHT UP AND RIGHT
+0x84A5	0x2827	0x251C	# BOX DRAWINGS LIGHT VERTICAL AND RIGHT
+0x84A6	0x2828	0x252C	# BOX DRAWINGS LIGHT DOWN AND HORIZONTAL
+0x84A7	0x2829	0x2524	# BOX DRAWINGS LIGHT VERTICAL AND LEFT
+0x84A8	0x282A	0x2534	# BOX DRAWINGS LIGHT UP AND HORIZONTAL
+0x84A9	0x282B	0x253C	# BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL
+0x84AA	0x282C	0x2501	# BOX DRAWINGS HEAVY HORIZONTAL
+0x84AB	0x282D	0x2503	# BOX DRAWINGS HEAVY VERTICAL
+0x84AC	0x282E	0x250F	# BOX DRAWINGS HEAVY DOWN AND RIGHT
+0x84AD	0x282F	0x2513	# BOX DRAWINGS HEAVY DOWN AND LEFT
+0x84AE	0x2830	0x251B	# BOX DRAWINGS HEAVY UP AND LEFT
+0x84AF	0x2831	0x2517	# BOX DRAWINGS HEAVY UP AND RIGHT
+0x84B0	0x2832	0x2523	# BOX DRAWINGS HEAVY VERTICAL AND RIGHT
+0x84B1	0x2833	0x2533	# BOX DRAWINGS HEAVY DOWN AND HORIZONTAL
+0x84B2	0x2834	0x252B	# BOX DRAWINGS HEAVY VERTICAL AND LEFT
+0x84B3	0x2835	0x253B	# BOX DRAWINGS HEAVY UP AND HORIZONTAL
+0x84B4	0x2836	0x254B	# BOX DRAWINGS HEAVY VERTICAL AND HORIZONTAL
+0x84B5	0x2837	0x2520	# BOX DRAWINGS VERTICAL HEAVY AND RIGHT LIGHT
+0x84B6	0x2838	0x252F	# BOX DRAWINGS DOWN LIGHT AND HORIZONTAL HEAVY
+0x84B7	0x2839	0x2528	# BOX DRAWINGS VERTICAL HEAVY AND LEFT LIGHT
+0x84B8	0x283A	0x2537	# BOX DRAWINGS UP LIGHT AND HORIZONTAL HEAVY
+0x84B9	0x283B	0x253F	# BOX DRAWINGS VERTICAL LIGHT AND HORIZONTAL HEAVY
+0x84BA	0x283C	0x251D	# BOX DRAWINGS VERTICAL LIGHT AND RIGHT HEAVY
+0x84BB	0x283D	0x2530	# BOX DRAWINGS DOWN HEAVY AND HORIZONTAL LIGHT
+0x84BC	0x283E	0x2525	# BOX DRAWINGS VERTICAL LIGHT AND LEFT HEAVY
+0x84BD	0x283F	0x2538	# BOX DRAWINGS UP HEAVY AND HORIZONTAL LIGHT
+0x84BE	0x2840	0x2542	# BOX DRAWINGS VERTICAL HEAVY AND HORIZONTAL LIGHT
+0x889F	0x3021	0x4E9C	# <CJK>
+0x88A0	0x3022	0x5516	# <CJK>
+0x88A1	0x3023	0x5A03	# <CJK>
+0x88A2	0x3024	0x963F	# <CJK>
+0x88A3	0x3025	0x54C0	# <CJK>
+0x88A4	0x3026	0x611B	# <CJK>
+0x88A5	0x3027	0x6328	# <CJK>
+0x88A6	0x3028	0x59F6	# <CJK>
+0x88A7	0x3029	0x9022	# <CJK>
+0x88A8	0x302A	0x8475	# <CJK>
+0x88A9	0x302B	0x831C	# <CJK>
+0x88AA	0x302C	0x7A50	# <CJK>
+0x88AB	0x302D	0x60AA	# <CJK>
+0x88AC	0x302E	0x63E1	# <CJK>
+0x88AD	0x302F	0x6E25	# <CJK>
+0x88AE	0x3030	0x65ED	# <CJK>
+0x88AF	0x3031	0x8466	# <CJK>
+0x88B0	0x3032	0x82A6	# <CJK>
+0x88B1	0x3033	0x9BF5	# <CJK>
+0x88B2	0x3034	0x6893	# <CJK>
+0x88B3	0x3035	0x5727	# <CJK>
+0x88B4	0x3036	0x65A1	# <CJK>
+0x88B5	0x3037	0x6271	# <CJK>
+0x88B6	0x3038	0x5B9B	# <CJK>
+0x88B7	0x3039	0x59D0	# <CJK>
+0x88B8	0x303A	0x867B	# <CJK>
+0x88B9	0x303B	0x98F4	# <CJK>
+0x88BA	0x303C	0x7D62	# <CJK>
+0x88BB	0x303D	0x7DBE	# <CJK>
+0x88BC	0x303E	0x9B8E	# <CJK>
+0x88BD	0x303F	0x6216	# <CJK>
+0x88BE	0x3040	0x7C9F	# <CJK>
+0x88BF	0x3041	0x88B7	# <CJK>
+0x88C0	0x3042	0x5B89	# <CJK>
+0x88C1	0x3043	0x5EB5	# <CJK>
+0x88C2	0x3044	0x6309	# <CJK>
+0x88C3	0x3045	0x6697	# <CJK>
+0x88C4	0x3046	0x6848	# <CJK>
+0x88C5	0x3047	0x95C7	# <CJK>
+0x88C6	0x3048	0x978D	# <CJK>
+0x88C7	0x3049	0x674F	# <CJK>
+0x88C8	0x304A	0x4EE5	# <CJK>
+0x88C9	0x304B	0x4F0A	# <CJK>
+0x88CA	0x304C	0x4F4D	# <CJK>
+0x88CB	0x304D	0x4F9D	# <CJK>
+0x88CC	0x304E	0x5049	# <CJK>
+0x88CD	0x304F	0x56F2	# <CJK>
+0x88CE	0x3050	0x5937	# <CJK>
+0x88CF	0x3051	0x59D4	# <CJK>
+0x88D0	0x3052	0x5A01	# <CJK>
+0x88D1	0x3053	0x5C09	# <CJK>
+0x88D2	0x3054	0x60DF	# <CJK>
+0x88D3	0x3055	0x610F	# <CJK>
+0x88D4	0x3056	0x6170	# <CJK>
+0x88D5	0x3057	0x6613	# <CJK>
+0x88D6	0x3058	0x6905	# <CJK>
+0x88D7	0x3059	0x70BA	# <CJK>
+0x88D8	0x305A	0x754F	# <CJK>
+0x88D9	0x305B	0x7570	# <CJK>
+0x88DA	0x305C	0x79FB	# <CJK>
+0x88DB	0x305D	0x7DAD	# <CJK>
+0x88DC	0x305E	0x7DEF	# <CJK>
+0x88DD	0x305F	0x80C3	# <CJK>
+0x88DE	0x3060	0x840E	# <CJK>
+0x88DF	0x3061	0x8863	# <CJK>
+0x88E0	0x3062	0x8B02	# <CJK>
+0x88E1	0x3063	0x9055	# <CJK>
+0x88E2	0x3064	0x907A	# <CJK>
+0x88E3	0x3065	0x533B	# <CJK>
+0x88E4	0x3066	0x4E95	# <CJK>
+0x88E5	0x3067	0x4EA5	# <CJK>
+0x88E6	0x3068	0x57DF	# <CJK>
+0x88E7	0x3069	0x80B2	# <CJK>
+0x88E8	0x306A	0x90C1	# <CJK>
+0x88E9	0x306B	0x78EF	# <CJK>
+0x88EA	0x306C	0x4E00	# <CJK>
+0x88EB	0x306D	0x58F1	# <CJK>
+0x88EC	0x306E	0x6EA2	# <CJK>
+0x88ED	0x306F	0x9038	# <CJK>
+0x88EE	0x3070	0x7A32	# <CJK>
+0x88EF	0x3071	0x8328	# <CJK>
+0x88F0	0x3072	0x828B	# <CJK>
+0x88F1	0x3073	0x9C2F	# <CJK>
+0x88F2	0x3074	0x5141	# <CJK>
+0x88F3	0x3075	0x5370	# <CJK>
+0x88F4	0x3076	0x54BD	# <CJK>
+0x88F5	0x3077	0x54E1	# <CJK>
+0x88F6	0x3078	0x56E0	# <CJK>
+0x88F7	0x3079	0x59FB	# <CJK>
+0x88F8	0x307A	0x5F15	# <CJK>
+0x88F9	0x307B	0x98F2	# <CJK>
+0x88FA	0x307C	0x6DEB	# <CJK>
+0x88FB	0x307D	0x80E4	# <CJK>
+0x88FC	0x307E	0x852D	# <CJK>
+0x8940	0x3121	0x9662	# <CJK>
+0x8941	0x3122	0x9670	# <CJK>
+0x8942	0x3123	0x96A0	# <CJK>
+0x8943	0x3124	0x97FB	# <CJK>
+0x8944	0x3125	0x540B	# <CJK>
+0x8945	0x3126	0x53F3	# <CJK>
+0x8946	0x3127	0x5B87	# <CJK>
+0x8947	0x3128	0x70CF	# <CJK>
+0x8948	0x3129	0x7FBD	# <CJK>
+0x8949	0x312A	0x8FC2	# <CJK>
+0x894A	0x312B	0x96E8	# <CJK>
+0x894B	0x312C	0x536F	# <CJK>
+0x894C	0x312D	0x9D5C	# <CJK>
+0x894D	0x312E	0x7ABA	# <CJK>
+0x894E	0x312F	0x4E11	# <CJK>
+0x894F	0x3130	0x7893	# <CJK>
+0x8950	0x3131	0x81FC	# <CJK>
+0x8951	0x3132	0x6E26	# <CJK>
+0x8952	0x3133	0x5618	# <CJK>
+0x8953	0x3134	0x5504	# <CJK>
+0x8954	0x3135	0x6B1D	# <CJK>
+0x8955	0x3136	0x851A	# <CJK>
+0x8956	0x3137	0x9C3B	# <CJK>
+0x8957	0x3138	0x59E5	# <CJK>
+0x8958	0x3139	0x53A9	# <CJK>
+0x8959	0x313A	0x6D66	# <CJK>
+0x895A	0x313B	0x74DC	# <CJK>
+0x895B	0x313C	0x958F	# <CJK>
+0x895C	0x313D	0x5642	# <CJK>
+0x895D	0x313E	0x4E91	# <CJK>
+0x895E	0x313F	0x904B	# <CJK>
+0x895F	0x3140	0x96F2	# <CJK>
+0x8960	0x3141	0x834F	# <CJK>
+0x8961	0x3142	0x990C	# <CJK>
+0x8962	0x3143	0x53E1	# <CJK>
+0x8963	0x3144	0x55B6	# <CJK>
+0x8964	0x3145	0x5B30	# <CJK>
+0x8965	0x3146	0x5F71	# <CJK>
+0x8966	0x3147	0x6620	# <CJK>
+0x8967	0x3148	0x66F3	# <CJK>
+0x8968	0x3149	0x6804	# <CJK>
+0x8969	0x314A	0x6C38	# <CJK>
+0x896A	0x314B	0x6CF3	# <CJK>
+0x896B	0x314C	0x6D29	# <CJK>
+0x896C	0x314D	0x745B	# <CJK>
+0x896D	0x314E	0x76C8	# <CJK>
+0x896E	0x314F	0x7A4E	# <CJK>
+0x896F	0x3150	0x9834	# <CJK>
+0x8970	0x3151	0x82F1	# <CJK>
+0x8971	0x3152	0x885B	# <CJK>
+0x8972	0x3153	0x8A60	# <CJK>
+0x8973	0x3154	0x92ED	# <CJK>
+0x8974	0x3155	0x6DB2	# <CJK>
+0x8975	0x3156	0x75AB	# <CJK>
+0x8976	0x3157	0x76CA	# <CJK>
+0x8977	0x3158	0x99C5	# <CJK>
+0x8978	0x3159	0x60A6	# <CJK>
+0x8979	0x315A	0x8B01	# <CJK>
+0x897A	0x315B	0x8D8A	# <CJK>
+0x897B	0x315C	0x95B2	# <CJK>
+0x897C	0x315D	0x698E	# <CJK>
+0x897D	0x315E	0x53AD	# <CJK>
+0x897E	0x315F	0x5186	# <CJK>
+0x8980	0x3160	0x5712	# <CJK>
+0x8981	0x3161	0x5830	# <CJK>
+0x8982	0x3162	0x5944	# <CJK>
+0x8983	0x3163	0x5BB4	# <CJK>
+0x8984	0x3164	0x5EF6	# <CJK>
+0x8985	0x3165	0x6028	# <CJK>
+0x8986	0x3166	0x63A9	# <CJK>
+0x8987	0x3167	0x63F4	# <CJK>
+0x8988	0x3168	0x6CBF	# <CJK>
+0x8989	0x3169	0x6F14	# <CJK>
+0x898A	0x316A	0x708E	# <CJK>
+0x898B	0x316B	0x7114	# <CJK>
+0x898C	0x316C	0x7159	# <CJK>
+0x898D	0x316D	0x71D5	# <CJK>
+0x898E	0x316E	0x733F	# <CJK>
+0x898F	0x316F	0x7E01	# <CJK>
+0x8990	0x3170	0x8276	# <CJK>
+0x8991	0x3171	0x82D1	# <CJK>
+0x8992	0x3172	0x8597	# <CJK>
+0x8993	0x3173	0x9060	# <CJK>
+0x8994	0x3174	0x925B	# <CJK>
+0x8995	0x3175	0x9D1B	# <CJK>
+0x8996	0x3176	0x5869	# <CJK>
+0x8997	0x3177	0x65BC	# <CJK>
+0x8998	0x3178	0x6C5A	# <CJK>
+0x8999	0x3179	0x7525	# <CJK>
+0x899A	0x317A	0x51F9	# <CJK>
+0x899B	0x317B	0x592E	# <CJK>
+0x899C	0x317C	0x5965	# <CJK>
+0x899D	0x317D	0x5F80	# <CJK>
+0x899E	0x317E	0x5FDC	# <CJK>
+0x899F	0x3221	0x62BC	# <CJK>
+0x89A0	0x3222	0x65FA	# <CJK>
+0x89A1	0x3223	0x6A2A	# <CJK>
+0x89A2	0x3224	0x6B27	# <CJK>
+0x89A3	0x3225	0x6BB4	# <CJK>
+0x89A4	0x3226	0x738B	# <CJK>
+0x89A5	0x3227	0x7FC1	# <CJK>
+0x89A6	0x3228	0x8956	# <CJK>
+0x89A7	0x3229	0x9D2C	# <CJK>
+0x89A8	0x322A	0x9D0E	# <CJK>
+0x89A9	0x322B	0x9EC4	# <CJK>
+0x89AA	0x322C	0x5CA1	# <CJK>
+0x89AB	0x322D	0x6C96	# <CJK>
+0x89AC	0x322E	0x837B	# <CJK>
+0x89AD	0x322F	0x5104	# <CJK>
+0x89AE	0x3230	0x5C4B	# <CJK>
+0x89AF	0x3231	0x61B6	# <CJK>
+0x89B0	0x3232	0x81C6	# <CJK>
+0x89B1	0x3233	0x6876	# <CJK>
+0x89B2	0x3234	0x7261	# <CJK>
+0x89B3	0x3235	0x4E59	# <CJK>
+0x89B4	0x3236	0x4FFA	# <CJK>
+0x89B5	0x3237	0x5378	# <CJK>
+0x89B6	0x3238	0x6069	# <CJK>
+0x89B7	0x3239	0x6E29	# <CJK>
+0x89B8	0x323A	0x7A4F	# <CJK>
+0x89B9	0x323B	0x97F3	# <CJK>
+0x89BA	0x323C	0x4E0B	# <CJK>
+0x89BB	0x323D	0x5316	# <CJK>
+0x89BC	0x323E	0x4EEE	# <CJK>
+0x89BD	0x323F	0x4F55	# <CJK>
+0x89BE	0x3240	0x4F3D	# <CJK>
+0x89BF	0x3241	0x4FA1	# <CJK>
+0x89C0	0x3242	0x4F73	# <CJK>
+0x89C1	0x3243	0x52A0	# <CJK>
+0x89C2	0x3244	0x53EF	# <CJK>
+0x89C3	0x3245	0x5609	# <CJK>
+0x89C4	0x3246	0x590F	# <CJK>
+0x89C5	0x3247	0x5AC1	# <CJK>
+0x89C6	0x3248	0x5BB6	# <CJK>
+0x89C7	0x3249	0x5BE1	# <CJK>
+0x89C8	0x324A	0x79D1	# <CJK>
+0x89C9	0x324B	0x6687	# <CJK>
+0x89CA	0x324C	0x679C	# <CJK>
+0x89CB	0x324D	0x67B6	# <CJK>
+0x89CC	0x324E	0x6B4C	# <CJK>
+0x89CD	0x324F	0x6CB3	# <CJK>
+0x89CE	0x3250	0x706B	# <CJK>
+0x89CF	0x3251	0x73C2	# <CJK>
+0x89D0	0x3252	0x798D	# <CJK>
+0x89D1	0x3253	0x79BE	# <CJK>
+0x89D2	0x3254	0x7A3C	# <CJK>
+0x89D3	0x3255	0x7B87	# <CJK>
+0x89D4	0x3256	0x82B1	# <CJK>
+0x89D5	0x3257	0x82DB	# <CJK>
+0x89D6	0x3258	0x8304	# <CJK>
+0x89D7	0x3259	0x8377	# <CJK>
+0x89D8	0x325A	0x83EF	# <CJK>
+0x89D9	0x325B	0x83D3	# <CJK>
+0x89DA	0x325C	0x8766	# <CJK>
+0x89DB	0x325D	0x8AB2	# <CJK>
+0x89DC	0x325E	0x5629	# <CJK>
+0x89DD	0x325F	0x8CA8	# <CJK>
+0x89DE	0x3260	0x8FE6	# <CJK>
+0x89DF	0x3261	0x904E	# <CJK>
+0x89E0	0x3262	0x971E	# <CJK>
+0x89E1	0x3263	0x868A	# <CJK>
+0x89E2	0x3264	0x4FC4	# <CJK>
+0x89E3	0x3265	0x5CE8	# <CJK>
+0x89E4	0x3266	0x6211	# <CJK>
+0x89E5	0x3267	0x7259	# <CJK>
+0x89E6	0x3268	0x753B	# <CJK>
+0x89E7	0x3269	0x81E5	# <CJK>
+0x89E8	0x326A	0x82BD	# <CJK>
+0x89E9	0x326B	0x86FE	# <CJK>
+0x89EA	0x326C	0x8CC0	# <CJK>
+0x89EB	0x326D	0x96C5	# <CJK>
+0x89EC	0x326E	0x9913	# <CJK>
+0x89ED	0x326F	0x99D5	# <CJK>
+0x89EE	0x3270	0x4ECB	# <CJK>
+0x89EF	0x3271	0x4F1A	# <CJK>
+0x89F0	0x3272	0x89E3	# <CJK>
+0x89F1	0x3273	0x56DE	# <CJK>
+0x89F2	0x3274	0x584A	# <CJK>
+0x89F3	0x3275	0x58CA	# <CJK>
+0x89F4	0x3276	0x5EFB	# <CJK>
+0x89F5	0x3277	0x5FEB	# <CJK>
+0x89F6	0x3278	0x602A	# <CJK>
+0x89F7	0x3279	0x6094	# <CJK>
+0x89F8	0x327A	0x6062	# <CJK>
+0x89F9	0x327B	0x61D0	# <CJK>
+0x89FA	0x327C	0x6212	# <CJK>
+0x89FB	0x327D	0x62D0	# <CJK>
+0x89FC	0x327E	0x6539	# <CJK>
+0x8A40	0x3321	0x9B41	# <CJK>
+0x8A41	0x3322	0x6666	# <CJK>
+0x8A42	0x3323	0x68B0	# <CJK>
+0x8A43	0x3324	0x6D77	# <CJK>
+0x8A44	0x3325	0x7070	# <CJK>
+0x8A45	0x3326	0x754C	# <CJK>
+0x8A46	0x3327	0x7686	# <CJK>
+0x8A47	0x3328	0x7D75	# <CJK>
+0x8A48	0x3329	0x82A5	# <CJK>
+0x8A49	0x332A	0x87F9	# <CJK>
+0x8A4A	0x332B	0x958B	# <CJK>
+0x8A4B	0x332C	0x968E	# <CJK>
+0x8A4C	0x332D	0x8C9D	# <CJK>
+0x8A4D	0x332E	0x51F1	# <CJK>
+0x8A4E	0x332F	0x52BE	# <CJK>
+0x8A4F	0x3330	0x5916	# <CJK>
+0x8A50	0x3331	0x54B3	# <CJK>
+0x8A51	0x3332	0x5BB3	# <CJK>
+0x8A52	0x3333	0x5D16	# <CJK>
+0x8A53	0x3334	0x6168	# <CJK>
+0x8A54	0x3335	0x6982	# <CJK>
+0x8A55	0x3336	0x6DAF	# <CJK>
+0x8A56	0x3337	0x788D	# <CJK>
+0x8A57	0x3338	0x84CB	# <CJK>
+0x8A58	0x3339	0x8857	# <CJK>
+0x8A59	0x333A	0x8A72	# <CJK>
+0x8A5A	0x333B	0x93A7	# <CJK>
+0x8A5B	0x333C	0x9AB8	# <CJK>
+0x8A5C	0x333D	0x6D6C	# <CJK>
+0x8A5D	0x333E	0x99A8	# <CJK>
+0x8A5E	0x333F	0x86D9	# <CJK>
+0x8A5F	0x3340	0x57A3	# <CJK>
+0x8A60	0x3341	0x67FF	# <CJK>
+0x8A61	0x3342	0x86CE	# <CJK>
+0x8A62	0x3343	0x920E	# <CJK>
+0x8A63	0x3344	0x5283	# <CJK>
+0x8A64	0x3345	0x5687	# <CJK>
+0x8A65	0x3346	0x5404	# <CJK>
+0x8A66	0x3347	0x5ED3	# <CJK>
+0x8A67	0x3348	0x62E1	# <CJK>
+0x8A68	0x3349	0x64B9	# <CJK>
+0x8A69	0x334A	0x683C	# <CJK>
+0x8A6A	0x334B	0x6838	# <CJK>
+0x8A6B	0x334C	0x6BBB	# <CJK>
+0x8A6C	0x334D	0x7372	# <CJK>
+0x8A6D	0x334E	0x78BA	# <CJK>
+0x8A6E	0x334F	0x7A6B	# <CJK>
+0x8A6F	0x3350	0x899A	# <CJK>
+0x8A70	0x3351	0x89D2	# <CJK>
+0x8A71	0x3352	0x8D6B	# <CJK>
+0x8A72	0x3353	0x8F03	# <CJK>
+0x8A73	0x3354	0x90ED	# <CJK>
+0x8A74	0x3355	0x95A3	# <CJK>
+0x8A75	0x3356	0x9694	# <CJK>
+0x8A76	0x3357	0x9769	# <CJK>
+0x8A77	0x3358	0x5B66	# <CJK>
+0x8A78	0x3359	0x5CB3	# <CJK>
+0x8A79	0x335A	0x697D	# <CJK>
+0x8A7A	0x335B	0x984D	# <CJK>
+0x8A7B	0x335C	0x984E	# <CJK>
+0x8A7C	0x335D	0x639B	# <CJK>
+0x8A7D	0x335E	0x7B20	# <CJK>
+0x8A7E	0x335F	0x6A2B	# <CJK>
+0x8A80	0x3360	0x6A7F	# <CJK>
+0x8A81	0x3361	0x68B6	# <CJK>
+0x8A82	0x3362	0x9C0D	# <CJK>
+0x8A83	0x3363	0x6F5F	# <CJK>
+0x8A84	0x3364	0x5272	# <CJK>
+0x8A85	0x3365	0x559D	# <CJK>
+0x8A86	0x3366	0x6070	# <CJK>
+0x8A87	0x3367	0x62EC	# <CJK>
+0x8A88	0x3368	0x6D3B	# <CJK>
+0x8A89	0x3369	0x6E07	# <CJK>
+0x8A8A	0x336A	0x6ED1	# <CJK>
+0x8A8B	0x336B	0x845B	# <CJK>
+0x8A8C	0x336C	0x8910	# <CJK>
+0x8A8D	0x336D	0x8F44	# <CJK>
+0x8A8E	0x336E	0x4E14	# <CJK>
+0x8A8F	0x336F	0x9C39	# <CJK>
+0x8A90	0x3370	0x53F6	# <CJK>
+0x8A91	0x3371	0x691B	# <CJK>
+0x8A92	0x3372	0x6A3A	# <CJK>
+0x8A93	0x3373	0x9784	# <CJK>
+0x8A94	0x3374	0x682A	# <CJK>
+0x8A95	0x3375	0x515C	# <CJK>
+0x8A96	0x3376	0x7AC3	# <CJK>
+0x8A97	0x3377	0x84B2	# <CJK>
+0x8A98	0x3378	0x91DC	# <CJK>
+0x8A99	0x3379	0x938C	# <CJK>
+0x8A9A	0x337A	0x565B	# <CJK>
+0x8A9B	0x337B	0x9D28	# <CJK>
+0x8A9C	0x337C	0x6822	# <CJK>
+0x8A9D	0x337D	0x8305	# <CJK>
+0x8A9E	0x337E	0x8431	# <CJK>
+0x8A9F	0x3421	0x7CA5	# <CJK>
+0x8AA0	0x3422	0x5208	# <CJK>
+0x8AA1	0x3423	0x82C5	# <CJK>
+0x8AA2	0x3424	0x74E6	# <CJK>
+0x8AA3	0x3425	0x4E7E	# <CJK>
+0x8AA4	0x3426	0x4F83	# <CJK>
+0x8AA5	0x3427	0x51A0	# <CJK>
+0x8AA6	0x3428	0x5BD2	# <CJK>
+0x8AA7	0x3429	0x520A	# <CJK>
+0x8AA8	0x342A	0x52D8	# <CJK>
+0x8AA9	0x342B	0x52E7	# <CJK>
+0x8AAA	0x342C	0x5DFB	# <CJK>
+0x8AAB	0x342D	0x559A	# <CJK>
+0x8AAC	0x342E	0x582A	# <CJK>
+0x8AAD	0x342F	0x59E6	# <CJK>
+0x8AAE	0x3430	0x5B8C	# <CJK>
+0x8AAF	0x3431	0x5B98	# <CJK>
+0x8AB0	0x3432	0x5BDB	# <CJK>
+0x8AB1	0x3433	0x5E72	# <CJK>
+0x8AB2	0x3434	0x5E79	# <CJK>
+0x8AB3	0x3435	0x60A3	# <CJK>
+0x8AB4	0x3436	0x611F	# <CJK>
+0x8AB5	0x3437	0x6163	# <CJK>
+0x8AB6	0x3438	0x61BE	# <CJK>
+0x8AB7	0x3439	0x63DB	# <CJK>
+0x8AB8	0x343A	0x6562	# <CJK>
+0x8AB9	0x343B	0x67D1	# <CJK>
+0x8ABA	0x343C	0x6853	# <CJK>
+0x8ABB	0x343D	0x68FA	# <CJK>
+0x8ABC	0x343E	0x6B3E	# <CJK>
+0x8ABD	0x343F	0x6B53	# <CJK>
+0x8ABE	0x3440	0x6C57	# <CJK>
+0x8ABF	0x3441	0x6F22	# <CJK>
+0x8AC0	0x3442	0x6F97	# <CJK>
+0x8AC1	0x3443	0x6F45	# <CJK>
+0x8AC2	0x3444	0x74B0	# <CJK>
+0x8AC3	0x3445	0x7518	# <CJK>
+0x8AC4	0x3446	0x76E3	# <CJK>
+0x8AC5	0x3447	0x770B	# <CJK>
+0x8AC6	0x3448	0x7AFF	# <CJK>
+0x8AC7	0x3449	0x7BA1	# <CJK>
+0x8AC8	0x344A	0x7C21	# <CJK>
+0x8AC9	0x344B	0x7DE9	# <CJK>
+0x8ACA	0x344C	0x7F36	# <CJK>
+0x8ACB	0x344D	0x7FF0	# <CJK>
+0x8ACC	0x344E	0x809D	# <CJK>
+0x8ACD	0x344F	0x8266	# <CJK>
+0x8ACE	0x3450	0x839E	# <CJK>
+0x8ACF	0x3451	0x89B3	# <CJK>
+0x8AD0	0x3452	0x8ACC	# <CJK>
+0x8AD1	0x3453	0x8CAB	# <CJK>
+0x8AD2	0x3454	0x9084	# <CJK>
+0x8AD3	0x3455	0x9451	# <CJK>
+0x8AD4	0x3456	0x9593	# <CJK>
+0x8AD5	0x3457	0x9591	# <CJK>
+0x8AD6	0x3458	0x95A2	# <CJK>
+0x8AD7	0x3459	0x9665	# <CJK>
+0x8AD8	0x345A	0x97D3	# <CJK>
+0x8AD9	0x345B	0x9928	# <CJK>
+0x8ADA	0x345C	0x8218	# <CJK>
+0x8ADB	0x345D	0x4E38	# <CJK>
+0x8ADC	0x345E	0x542B	# <CJK>
+0x8ADD	0x345F	0x5CB8	# <CJK>
+0x8ADE	0x3460	0x5DCC	# <CJK>
+0x8ADF	0x3461	0x73A9	# <CJK>
+0x8AE0	0x3462	0x764C	# <CJK>
+0x8AE1	0x3463	0x773C	# <CJK>
+0x8AE2	0x3464	0x5CA9	# <CJK>
+0x8AE3	0x3465	0x7FEB	# <CJK>
+0x8AE4	0x3466	0x8D0B	# <CJK>
+0x8AE5	0x3467	0x96C1	# <CJK>
+0x8AE6	0x3468	0x9811	# <CJK>
+0x8AE7	0x3469	0x9854	# <CJK>
+0x8AE8	0x346A	0x9858	# <CJK>
+0x8AE9	0x346B	0x4F01	# <CJK>
+0x8AEA	0x346C	0x4F0E	# <CJK>
+0x8AEB	0x346D	0x5371	# <CJK>
+0x8AEC	0x346E	0x559C	# <CJK>
+0x8AED	0x346F	0x5668	# <CJK>
+0x8AEE	0x3470	0x57FA	# <CJK>
+0x8AEF	0x3471	0x5947	# <CJK>
+0x8AF0	0x3472	0x5B09	# <CJK>
+0x8AF1	0x3473	0x5BC4	# <CJK>
+0x8AF2	0x3474	0x5C90	# <CJK>
+0x8AF3	0x3475	0x5E0C	# <CJK>
+0x8AF4	0x3476	0x5E7E	# <CJK>
+0x8AF5	0x3477	0x5FCC	# <CJK>
+0x8AF6	0x3478	0x63EE	# <CJK>
+0x8AF7	0x3479	0x673A	# <CJK>
+0x8AF8	0x347A	0x65D7	# <CJK>
+0x8AF9	0x347B	0x65E2	# <CJK>
+0x8AFA	0x347C	0x671F	# <CJK>
+0x8AFB	0x347D	0x68CB	# <CJK>
+0x8AFC	0x347E	0x68C4	# <CJK>
+0x8B40	0x3521	0x6A5F	# <CJK>
+0x8B41	0x3522	0x5E30	# <CJK>
+0x8B42	0x3523	0x6BC5	# <CJK>
+0x8B43	0x3524	0x6C17	# <CJK>
+0x8B44	0x3525	0x6C7D	# <CJK>
+0x8B45	0x3526	0x757F	# <CJK>
+0x8B46	0x3527	0x7948	# <CJK>
+0x8B47	0x3528	0x5B63	# <CJK>
+0x8B48	0x3529	0x7A00	# <CJK>
+0x8B49	0x352A	0x7D00	# <CJK>
+0x8B4A	0x352B	0x5FBD	# <CJK>
+0x8B4B	0x352C	0x898F	# <CJK>
+0x8B4C	0x352D	0x8A18	# <CJK>
+0x8B4D	0x352E	0x8CB4	# <CJK>
+0x8B4E	0x352F	0x8D77	# <CJK>
+0x8B4F	0x3530	0x8ECC	# <CJK>
+0x8B50	0x3531	0x8F1D	# <CJK>
+0x8B51	0x3532	0x98E2	# <CJK>
+0x8B52	0x3533	0x9A0E	# <CJK>
+0x8B53	0x3534	0x9B3C	# <CJK>
+0x8B54	0x3535	0x4E80	# <CJK>
+0x8B55	0x3536	0x507D	# <CJK>
+0x8B56	0x3537	0x5100	# <CJK>
+0x8B57	0x3538	0x5993	# <CJK>
+0x8B58	0x3539	0x5B9C	# <CJK>
+0x8B59	0x353A	0x622F	# <CJK>
+0x8B5A	0x353B	0x6280	# <CJK>
+0x8B5B	0x353C	0x64EC	# <CJK>
+0x8B5C	0x353D	0x6B3A	# <CJK>
+0x8B5D	0x353E	0x72A0	# <CJK>
+0x8B5E	0x353F	0x7591	# <CJK>
+0x8B5F	0x3540	0x7947	# <CJK>
+0x8B60	0x3541	0x7FA9	# <CJK>
+0x8B61	0x3542	0x87FB	# <CJK>
+0x8B62	0x3543	0x8ABC	# <CJK>
+0x8B63	0x3544	0x8B70	# <CJK>
+0x8B64	0x3545	0x63AC	# <CJK>
+0x8B65	0x3546	0x83CA	# <CJK>
+0x8B66	0x3547	0x97A0	# <CJK>
+0x8B67	0x3548	0x5409	# <CJK>
+0x8B68	0x3549	0x5403	# <CJK>
+0x8B69	0x354A	0x55AB	# <CJK>
+0x8B6A	0x354B	0x6854	# <CJK>
+0x8B6B	0x354C	0x6A58	# <CJK>
+0x8B6C	0x354D	0x8A70	# <CJK>
+0x8B6D	0x354E	0x7827	# <CJK>
+0x8B6E	0x354F	0x6775	# <CJK>
+0x8B6F	0x3550	0x9ECD	# <CJK>
+0x8B70	0x3551	0x5374	# <CJK>
+0x8B71	0x3552	0x5BA2	# <CJK>
+0x8B72	0x3553	0x811A	# <CJK>
+0x8B73	0x3554	0x8650	# <CJK>
+0x8B74	0x3555	0x9006	# <CJK>
+0x8B75	0x3556	0x4E18	# <CJK>
+0x8B76	0x3557	0x4E45	# <CJK>
+0x8B77	0x3558	0x4EC7	# <CJK>
+0x8B78	0x3559	0x4F11	# <CJK>
+0x8B79	0x355A	0x53CA	# <CJK>
+0x8B7A	0x355B	0x5438	# <CJK>
+0x8B7B	0x355C	0x5BAE	# <CJK>
+0x8B7C	0x355D	0x5F13	# <CJK>
+0x8B7D	0x355E	0x6025	# <CJK>
+0x8B7E	0x355F	0x6551	# <CJK>
+0x8B80	0x3560	0x673D	# <CJK>
+0x8B81	0x3561	0x6C42	# <CJK>
+0x8B82	0x3562	0x6C72	# <CJK>
+0x8B83	0x3563	0x6CE3	# <CJK>
+0x8B84	0x3564	0x7078	# <CJK>
+0x8B85	0x3565	0x7403	# <CJK>
+0x8B86	0x3566	0x7A76	# <CJK>
+0x8B87	0x3567	0x7AAE	# <CJK>
+0x8B88	0x3568	0x7B08	# <CJK>
+0x8B89	0x3569	0x7D1A	# <CJK>
+0x8B8A	0x356A	0x7CFE	# <CJK>
+0x8B8B	0x356B	0x7D66	# <CJK>
+0x8B8C	0x356C	0x65E7	# <CJK>
+0x8B8D	0x356D	0x725B	# <CJK>
+0x8B8E	0x356E	0x53BB	# <CJK>
+0x8B8F	0x356F	0x5C45	# <CJK>
+0x8B90	0x3570	0x5DE8	# <CJK>
+0x8B91	0x3571	0x62D2	# <CJK>
+0x8B92	0x3572	0x62E0	# <CJK>
+0x8B93	0x3573	0x6319	# <CJK>
+0x8B94	0x3574	0x6E20	# <CJK>
+0x8B95	0x3575	0x865A	# <CJK>
+0x8B96	0x3576	0x8A31	# <CJK>
+0x8B97	0x3577	0x8DDD	# <CJK>
+0x8B98	0x3578	0x92F8	# <CJK>
+0x8B99	0x3579	0x6F01	# <CJK>
+0x8B9A	0x357A	0x79A6	# <CJK>
+0x8B9B	0x357B	0x9B5A	# <CJK>
+0x8B9C	0x357C	0x4EA8	# <CJK>
+0x8B9D	0x357D	0x4EAB	# <CJK>
+0x8B9E	0x357E	0x4EAC	# <CJK>
+0x8B9F	0x3621	0x4F9B	# <CJK>
+0x8BA0	0x3622	0x4FA0	# <CJK>
+0x8BA1	0x3623	0x50D1	# <CJK>
+0x8BA2	0x3624	0x5147	# <CJK>
+0x8BA3	0x3625	0x7AF6	# <CJK>
+0x8BA4	0x3626	0x5171	# <CJK>
+0x8BA5	0x3627	0x51F6	# <CJK>
+0x8BA6	0x3628	0x5354	# <CJK>
+0x8BA7	0x3629	0x5321	# <CJK>
+0x8BA8	0x362A	0x537F	# <CJK>
+0x8BA9	0x362B	0x53EB	# <CJK>
+0x8BAA	0x362C	0x55AC	# <CJK>
+0x8BAB	0x362D	0x5883	# <CJK>
+0x8BAC	0x362E	0x5CE1	# <CJK>
+0x8BAD	0x362F	0x5F37	# <CJK>
+0x8BAE	0x3630	0x5F4A	# <CJK>
+0x8BAF	0x3631	0x602F	# <CJK>
+0x8BB0	0x3632	0x6050	# <CJK>
+0x8BB1	0x3633	0x606D	# <CJK>
+0x8BB2	0x3634	0x631F	# <CJK>
+0x8BB3	0x3635	0x6559	# <CJK>
+0x8BB4	0x3636	0x6A4B	# <CJK>
+0x8BB5	0x3637	0x6CC1	# <CJK>
+0x8BB6	0x3638	0x72C2	# <CJK>
+0x8BB7	0x3639	0x72ED	# <CJK>
+0x8BB8	0x363A	0x77EF	# <CJK>
+0x8BB9	0x363B	0x80F8	# <CJK>
+0x8BBA	0x363C	0x8105	# <CJK>
+0x8BBB	0x363D	0x8208	# <CJK>
+0x8BBC	0x363E	0x854E	# <CJK>
+0x8BBD	0x363F	0x90F7	# <CJK>
+0x8BBE	0x3640	0x93E1	# <CJK>
+0x8BBF	0x3641	0x97FF	# <CJK>
+0x8BC0	0x3642	0x9957	# <CJK>
+0x8BC1	0x3643	0x9A5A	# <CJK>
+0x8BC2	0x3644	0x4EF0	# <CJK>
+0x8BC3	0x3645	0x51DD	# <CJK>
+0x8BC4	0x3646	0x5C2D	# <CJK>
+0x8BC5	0x3647	0x6681	# <CJK>
+0x8BC6	0x3648	0x696D	# <CJK>
+0x8BC7	0x3649	0x5C40	# <CJK>
+0x8BC8	0x364A	0x66F2	# <CJK>
+0x8BC9	0x364B	0x6975	# <CJK>
+0x8BCA	0x364C	0x7389	# <CJK>
+0x8BCB	0x364D	0x6850	# <CJK>
+0x8BCC	0x364E	0x7C81	# <CJK>
+0x8BCD	0x364F	0x50C5	# <CJK>
+0x8BCE	0x3650	0x52E4	# <CJK>
+0x8BCF	0x3651	0x5747	# <CJK>
+0x8BD0	0x3652	0x5DFE	# <CJK>
+0x8BD1	0x3653	0x9326	# <CJK>
+0x8BD2	0x3654	0x65A4	# <CJK>
+0x8BD3	0x3655	0x6B23	# <CJK>
+0x8BD4	0x3656	0x6B3D	# <CJK>
+0x8BD5	0x3657	0x7434	# <CJK>
+0x8BD6	0x3658	0x7981	# <CJK>
+0x8BD7	0x3659	0x79BD	# <CJK>
+0x8BD8	0x365A	0x7B4B	# <CJK>
+0x8BD9	0x365B	0x7DCA	# <CJK>
+0x8BDA	0x365C	0x82B9	# <CJK>
+0x8BDB	0x365D	0x83CC	# <CJK>
+0x8BDC	0x365E	0x887F	# <CJK>
+0x8BDD	0x365F	0x895F	# <CJK>
+0x8BDE	0x3660	0x8B39	# <CJK>
+0x8BDF	0x3661	0x8FD1	# <CJK>
+0x8BE0	0x3662	0x91D1	# <CJK>
+0x8BE1	0x3663	0x541F	# <CJK>
+0x8BE2	0x3664	0x9280	# <CJK>
+0x8BE3	0x3665	0x4E5D	# <CJK>
+0x8BE4	0x3666	0x5036	# <CJK>
+0x8BE5	0x3667	0x53E5	# <CJK>
+0x8BE6	0x3668	0x533A	# <CJK>
+0x8BE7	0x3669	0x72D7	# <CJK>
+0x8BE8	0x366A	0x7396	# <CJK>
+0x8BE9	0x366B	0x77E9	# <CJK>
+0x8BEA	0x366C	0x82E6	# <CJK>
+0x8BEB	0x366D	0x8EAF	# <CJK>
+0x8BEC	0x366E	0x99C6	# <CJK>
+0x8BED	0x366F	0x99C8	# <CJK>
+0x8BEE	0x3670	0x99D2	# <CJK>
+0x8BEF	0x3671	0x5177	# <CJK>
+0x8BF0	0x3672	0x611A	# <CJK>
+0x8BF1	0x3673	0x865E	# <CJK>
+0x8BF2	0x3674	0x55B0	# <CJK>
+0x8BF3	0x3675	0x7A7A	# <CJK>
+0x8BF4	0x3676	0x5076	# <CJK>
+0x8BF5	0x3677	0x5BD3	# <CJK>
+0x8BF6	0x3678	0x9047	# <CJK>
+0x8BF7	0x3679	0x9685	# <CJK>
+0x8BF8	0x367A	0x4E32	# <CJK>
+0x8BF9	0x367B	0x6ADB	# <CJK>
+0x8BFA	0x367C	0x91E7	# <CJK>
+0x8BFB	0x367D	0x5C51	# <CJK>
+0x8BFC	0x367E	0x5C48	# <CJK>
+0x8C40	0x3721	0x6398	# <CJK>
+0x8C41	0x3722	0x7A9F	# <CJK>
+0x8C42	0x3723	0x6C93	# <CJK>
+0x8C43	0x3724	0x9774	# <CJK>
+0x8C44	0x3725	0x8F61	# <CJK>
+0x8C45	0x3726	0x7AAA	# <CJK>
+0x8C46	0x3727	0x718A	# <CJK>
+0x8C47	0x3728	0x9688	# <CJK>
+0x8C48	0x3729	0x7C82	# <CJK>
+0x8C49	0x372A	0x6817	# <CJK>
+0x8C4A	0x372B	0x7E70	# <CJK>
+0x8C4B	0x372C	0x6851	# <CJK>
+0x8C4C	0x372D	0x936C	# <CJK>
+0x8C4D	0x372E	0x52F2	# <CJK>
+0x8C4E	0x372F	0x541B	# <CJK>
+0x8C4F	0x3730	0x85AB	# <CJK>
+0x8C50	0x3731	0x8A13	# <CJK>
+0x8C51	0x3732	0x7FA4	# <CJK>
+0x8C52	0x3733	0x8ECD	# <CJK>
+0x8C53	0x3734	0x90E1	# <CJK>
+0x8C54	0x3735	0x5366	# <CJK>
+0x8C55	0x3736	0x8888	# <CJK>
+0x8C56	0x3737	0x7941	# <CJK>
+0x8C57	0x3738	0x4FC2	# <CJK>
+0x8C58	0x3739	0x50BE	# <CJK>
+0x8C59	0x373A	0x5211	# <CJK>
+0x8C5A	0x373B	0x5144	# <CJK>
+0x8C5B	0x373C	0x5553	# <CJK>
+0x8C5C	0x373D	0x572D	# <CJK>
+0x8C5D	0x373E	0x73EA	# <CJK>
+0x8C5E	0x373F	0x578B	# <CJK>
+0x8C5F	0x3740	0x5951	# <CJK>
+0x8C60	0x3741	0x5F62	# <CJK>
+0x8C61	0x3742	0x5F84	# <CJK>
+0x8C62	0x3743	0x6075	# <CJK>
+0x8C63	0x3744	0x6176	# <CJK>
+0x8C64	0x3745	0x6167	# <CJK>
+0x8C65	0x3746	0x61A9	# <CJK>
+0x8C66	0x3747	0x63B2	# <CJK>
+0x8C67	0x3748	0x643A	# <CJK>
+0x8C68	0x3749	0x656C	# <CJK>
+0x8C69	0x374A	0x666F	# <CJK>
+0x8C6A	0x374B	0x6842	# <CJK>
+0x8C6B	0x374C	0x6E13	# <CJK>
+0x8C6C	0x374D	0x7566	# <CJK>
+0x8C6D	0x374E	0x7A3D	# <CJK>
+0x8C6E	0x374F	0x7CFB	# <CJK>
+0x8C6F	0x3750	0x7D4C	# <CJK>
+0x8C70	0x3751	0x7D99	# <CJK>
+0x8C71	0x3752	0x7E4B	# <CJK>
+0x8C72	0x3753	0x7F6B	# <CJK>
+0x8C73	0x3754	0x830E	# <CJK>
+0x8C74	0x3755	0x834A	# <CJK>
+0x8C75	0x3756	0x86CD	# <CJK>
+0x8C76	0x3757	0x8A08	# <CJK>
+0x8C77	0x3758	0x8A63	# <CJK>
+0x8C78	0x3759	0x8B66	# <CJK>
+0x8C79	0x375A	0x8EFD	# <CJK>
+0x8C7A	0x375B	0x981A	# <CJK>
+0x8C7B	0x375C	0x9D8F	# <CJK>
+0x8C7C	0x375D	0x82B8	# <CJK>
+0x8C7D	0x375E	0x8FCE	# <CJK>
+0x8C7E	0x375F	0x9BE8	# <CJK>
+0x8C80	0x3760	0x5287	# <CJK>
+0x8C81	0x3761	0x621F	# <CJK>
+0x8C82	0x3762	0x6483	# <CJK>
+0x8C83	0x3763	0x6FC0	# <CJK>
+0x8C84	0x3764	0x9699	# <CJK>
+0x8C85	0x3765	0x6841	# <CJK>
+0x8C86	0x3766	0x5091	# <CJK>
+0x8C87	0x3767	0x6B20	# <CJK>
+0x8C88	0x3768	0x6C7A	# <CJK>
+0x8C89	0x3769	0x6F54	# <CJK>
+0x8C8A	0x376A	0x7A74	# <CJK>
+0x8C8B	0x376B	0x7D50	# <CJK>
+0x8C8C	0x376C	0x8840	# <CJK>
+0x8C8D	0x376D	0x8A23	# <CJK>
+0x8C8E	0x376E	0x6708	# <CJK>
+0x8C8F	0x376F	0x4EF6	# <CJK>
+0x8C90	0x3770	0x5039	# <CJK>
+0x8C91	0x3771	0x5026	# <CJK>
+0x8C92	0x3772	0x5065	# <CJK>
+0x8C93	0x3773	0x517C	# <CJK>
+0x8C94	0x3774	0x5238	# <CJK>
+0x8C95	0x3775	0x5263	# <CJK>
+0x8C96	0x3776	0x55A7	# <CJK>
+0x8C97	0x3777	0x570F	# <CJK>
+0x8C98	0x3778	0x5805	# <CJK>
+0x8C99	0x3779	0x5ACC	# <CJK>
+0x8C9A	0x377A	0x5EFA	# <CJK>
+0x8C9B	0x377B	0x61B2	# <CJK>
+0x8C9C	0x377C	0x61F8	# <CJK>
+0x8C9D	0x377D	0x62F3	# <CJK>
+0x8C9E	0x377E	0x6372	# <CJK>
+0x8C9F	0x3821	0x691C	# <CJK>
+0x8CA0	0x3822	0x6A29	# <CJK>
+0x8CA1	0x3823	0x727D	# <CJK>
+0x8CA2	0x3824	0x72AC	# <CJK>
+0x8CA3	0x3825	0x732E	# <CJK>
+0x8CA4	0x3826	0x7814	# <CJK>
+0x8CA5	0x3827	0x786F	# <CJK>
+0x8CA6	0x3828	0x7D79	# <CJK>
+0x8CA7	0x3829	0x770C	# <CJK>
+0x8CA8	0x382A	0x80A9	# <CJK>
+0x8CA9	0x382B	0x898B	# <CJK>
+0x8CAA	0x382C	0x8B19	# <CJK>
+0x8CAB	0x382D	0x8CE2	# <CJK>
+0x8CAC	0x382E	0x8ED2	# <CJK>
+0x8CAD	0x382F	0x9063	# <CJK>
+0x8CAE	0x3830	0x9375	# <CJK>
+0x8CAF	0x3831	0x967A	# <CJK>
+0x8CB0	0x3832	0x9855	# <CJK>
+0x8CB1	0x3833	0x9A13	# <CJK>
+0x8CB2	0x3834	0x9E78	# <CJK>
+0x8CB3	0x3835	0x5143	# <CJK>
+0x8CB4	0x3836	0x539F	# <CJK>
+0x8CB5	0x3837	0x53B3	# <CJK>
+0x8CB6	0x3838	0x5E7B	# <CJK>
+0x8CB7	0x3839	0x5F26	# <CJK>
+0x8CB8	0x383A	0x6E1B	# <CJK>
+0x8CB9	0x383B	0x6E90	# <CJK>
+0x8CBA	0x383C	0x7384	# <CJK>
+0x8CBB	0x383D	0x73FE	# <CJK>
+0x8CBC	0x383E	0x7D43	# <CJK>
+0x8CBD	0x383F	0x8237	# <CJK>
+0x8CBE	0x3840	0x8A00	# <CJK>
+0x8CBF	0x3841	0x8AFA	# <CJK>
+0x8CC0	0x3842	0x9650	# <CJK>
+0x8CC1	0x3843	0x4E4E	# <CJK>
+0x8CC2	0x3844	0x500B	# <CJK>
+0x8CC3	0x3845	0x53E4	# <CJK>
+0x8CC4	0x3846	0x547C	# <CJK>
+0x8CC5	0x3847	0x56FA	# <CJK>
+0x8CC6	0x3848	0x59D1	# <CJK>
+0x8CC7	0x3849	0x5B64	# <CJK>
+0x8CC8	0x384A	0x5DF1	# <CJK>
+0x8CC9	0x384B	0x5EAB	# <CJK>
+0x8CCA	0x384C	0x5F27	# <CJK>
+0x8CCB	0x384D	0x6238	# <CJK>
+0x8CCC	0x384E	0x6545	# <CJK>
+0x8CCD	0x384F	0x67AF	# <CJK>
+0x8CCE	0x3850	0x6E56	# <CJK>
+0x8CCF	0x3851	0x72D0	# <CJK>
+0x8CD0	0x3852	0x7CCA	# <CJK>
+0x8CD1	0x3853	0x88B4	# <CJK>
+0x8CD2	0x3854	0x80A1	# <CJK>
+0x8CD3	0x3855	0x80E1	# <CJK>
+0x8CD4	0x3856	0x83F0	# <CJK>
+0x8CD5	0x3857	0x864E	# <CJK>
+0x8CD6	0x3858	0x8A87	# <CJK>
+0x8CD7	0x3859	0x8DE8	# <CJK>
+0x8CD8	0x385A	0x9237	# <CJK>
+0x8CD9	0x385B	0x96C7	# <CJK>
+0x8CDA	0x385C	0x9867	# <CJK>
+0x8CDB	0x385D	0x9F13	# <CJK>
+0x8CDC	0x385E	0x4E94	# <CJK>
+0x8CDD	0x385F	0x4E92	# <CJK>
+0x8CDE	0x3860	0x4F0D	# <CJK>
+0x8CDF	0x3861	0x5348	# <CJK>
+0x8CE0	0x3862	0x5449	# <CJK>
+0x8CE1	0x3863	0x543E	# <CJK>
+0x8CE2	0x3864	0x5A2F	# <CJK>
+0x8CE3	0x3865	0x5F8C	# <CJK>
+0x8CE4	0x3866	0x5FA1	# <CJK>
+0x8CE5	0x3867	0x609F	# <CJK>
+0x8CE6	0x3868	0x68A7	# <CJK>
+0x8CE7	0x3869	0x6A8E	# <CJK>
+0x8CE8	0x386A	0x745A	# <CJK>
+0x8CE9	0x386B	0x7881	# <CJK>
+0x8CEA	0x386C	0x8A9E	# <CJK>
+0x8CEB	0x386D	0x8AA4	# <CJK>
+0x8CEC	0x386E	0x8B77	# <CJK>
+0x8CED	0x386F	0x9190	# <CJK>
+0x8CEE	0x3870	0x4E5E	# <CJK>
+0x8CEF	0x3871	0x9BC9	# <CJK>
+0x8CF0	0x3872	0x4EA4	# <CJK>
+0x8CF1	0x3873	0x4F7C	# <CJK>
+0x8CF2	0x3874	0x4FAF	# <CJK>
+0x8CF3	0x3875	0x5019	# <CJK>
+0x8CF4	0x3876	0x5016	# <CJK>
+0x8CF5	0x3877	0x5149	# <CJK>
+0x8CF6	0x3878	0x516C	# <CJK>
+0x8CF7	0x3879	0x529F	# <CJK>
+0x8CF8	0x387A	0x52B9	# <CJK>
+0x8CF9	0x387B	0x52FE	# <CJK>
+0x8CFA	0x387C	0x539A	# <CJK>
+0x8CFB	0x387D	0x53E3	# <CJK>
+0x8CFC	0x387E	0x5411	# <CJK>
+0x8D40	0x3921	0x540E	# <CJK>
+0x8D41	0x3922	0x5589	# <CJK>
+0x8D42	0x3923	0x5751	# <CJK>
+0x8D43	0x3924	0x57A2	# <CJK>
+0x8D44	0x3925	0x597D	# <CJK>
+0x8D45	0x3926	0x5B54	# <CJK>
+0x8D46	0x3927	0x5B5D	# <CJK>
+0x8D47	0x3928	0x5B8F	# <CJK>
+0x8D48	0x3929	0x5DE5	# <CJK>
+0x8D49	0x392A	0x5DE7	# <CJK>
+0x8D4A	0x392B	0x5DF7	# <CJK>
+0x8D4B	0x392C	0x5E78	# <CJK>
+0x8D4C	0x392D	0x5E83	# <CJK>
+0x8D4D	0x392E	0x5E9A	# <CJK>
+0x8D4E	0x392F	0x5EB7	# <CJK>
+0x8D4F	0x3930	0x5F18	# <CJK>
+0x8D50	0x3931	0x6052	# <CJK>
+0x8D51	0x3932	0x614C	# <CJK>
+0x8D52	0x3933	0x6297	# <CJK>
+0x8D53	0x3934	0x62D8	# <CJK>
+0x8D54	0x3935	0x63A7	# <CJK>
+0x8D55	0x3936	0x653B	# <CJK>
+0x8D56	0x3937	0x6602	# <CJK>
+0x8D57	0x3938	0x6643	# <CJK>
+0x8D58	0x3939	0x66F4	# <CJK>
+0x8D59	0x393A	0x676D	# <CJK>
+0x8D5A	0x393B	0x6821	# <CJK>
+0x8D5B	0x393C	0x6897	# <CJK>
+0x8D5C	0x393D	0x69CB	# <CJK>
+0x8D5D	0x393E	0x6C5F	# <CJK>
+0x8D5E	0x393F	0x6D2A	# <CJK>
+0x8D5F	0x3940	0x6D69	# <CJK>
+0x8D60	0x3941	0x6E2F	# <CJK>
+0x8D61	0x3942	0x6E9D	# <CJK>
+0x8D62	0x3943	0x7532	# <CJK>
+0x8D63	0x3944	0x7687	# <CJK>
+0x8D64	0x3945	0x786C	# <CJK>
+0x8D65	0x3946	0x7A3F	# <CJK>
+0x8D66	0x3947	0x7CE0	# <CJK>
+0x8D67	0x3948	0x7D05	# <CJK>
+0x8D68	0x3949	0x7D18	# <CJK>
+0x8D69	0x394A	0x7D5E	# <CJK>
+0x8D6A	0x394B	0x7DB1	# <CJK>
+0x8D6B	0x394C	0x8015	# <CJK>
+0x8D6C	0x394D	0x8003	# <CJK>
+0x8D6D	0x394E	0x80AF	# <CJK>
+0x8D6E	0x394F	0x80B1	# <CJK>
+0x8D6F	0x3950	0x8154	# <CJK>
+0x8D70	0x3951	0x818F	# <CJK>
+0x8D71	0x3952	0x822A	# <CJK>
+0x8D72	0x3953	0x8352	# <CJK>
+0x8D73	0x3954	0x884C	# <CJK>
+0x8D74	0x3955	0x8861	# <CJK>
+0x8D75	0x3956	0x8B1B	# <CJK>
+0x8D76	0x3957	0x8CA2	# <CJK>
+0x8D77	0x3958	0x8CFC	# <CJK>
+0x8D78	0x3959	0x90CA	# <CJK>
+0x8D79	0x395A	0x9175	# <CJK>
+0x8D7A	0x395B	0x9271	# <CJK>
+0x8D7B	0x395C	0x783F	# <CJK>
+0x8D7C	0x395D	0x92FC	# <CJK>
+0x8D7D	0x395E	0x95A4	# <CJK>
+0x8D7E	0x395F	0x964D	# <CJK>
+0x8D80	0x3960	0x9805	# <CJK>
+0x8D81	0x3961	0x9999	# <CJK>
+0x8D82	0x3962	0x9AD8	# <CJK>
+0x8D83	0x3963	0x9D3B	# <CJK>
+0x8D84	0x3964	0x525B	# <CJK>
+0x8D85	0x3965	0x52AB	# <CJK>
+0x8D86	0x3966	0x53F7	# <CJK>
+0x8D87	0x3967	0x5408	# <CJK>
+0x8D88	0x3968	0x58D5	# <CJK>
+0x8D89	0x3969	0x62F7	# <CJK>
+0x8D8A	0x396A	0x6FE0	# <CJK>
+0x8D8B	0x396B	0x8C6A	# <CJK>
+0x8D8C	0x396C	0x8F5F	# <CJK>
+0x8D8D	0x396D	0x9EB9	# <CJK>
+0x8D8E	0x396E	0x514B	# <CJK>
+0x8D8F	0x396F	0x523B	# <CJK>
+0x8D90	0x3970	0x544A	# <CJK>
+0x8D91	0x3971	0x56FD	# <CJK>
+0x8D92	0x3972	0x7A40	# <CJK>
+0x8D93	0x3973	0x9177	# <CJK>
+0x8D94	0x3974	0x9D60	# <CJK>
+0x8D95	0x3975	0x9ED2	# <CJK>
+0x8D96	0x3976	0x7344	# <CJK>
+0x8D97	0x3977	0x6F09	# <CJK>
+0x8D98	0x3978	0x8170	# <CJK>
+0x8D99	0x3979	0x7511	# <CJK>
+0x8D9A	0x397A	0x5FFD	# <CJK>
+0x8D9B	0x397B	0x60DA	# <CJK>
+0x8D9C	0x397C	0x9AA8	# <CJK>
+0x8D9D	0x397D	0x72DB	# <CJK>
+0x8D9E	0x397E	0x8FBC	# <CJK>
+0x8D9F	0x3A21	0x6B64	# <CJK>
+0x8DA0	0x3A22	0x9803	# <CJK>
+0x8DA1	0x3A23	0x4ECA	# <CJK>
+0x8DA2	0x3A24	0x56F0	# <CJK>
+0x8DA3	0x3A25	0x5764	# <CJK>
+0x8DA4	0x3A26	0x58BE	# <CJK>
+0x8DA5	0x3A27	0x5A5A	# <CJK>
+0x8DA6	0x3A28	0x6068	# <CJK>
+0x8DA7	0x3A29	0x61C7	# <CJK>
+0x8DA8	0x3A2A	0x660F	# <CJK>
+0x8DA9	0x3A2B	0x6606	# <CJK>
+0x8DAA	0x3A2C	0x6839	# <CJK>
+0x8DAB	0x3A2D	0x68B1	# <CJK>
+0x8DAC	0x3A2E	0x6DF7	# <CJK>
+0x8DAD	0x3A2F	0x75D5	# <CJK>
+0x8DAE	0x3A30	0x7D3A	# <CJK>
+0x8DAF	0x3A31	0x826E	# <CJK>
+0x8DB0	0x3A32	0x9B42	# <CJK>
+0x8DB1	0x3A33	0x4E9B	# <CJK>
+0x8DB2	0x3A34	0x4F50	# <CJK>
+0x8DB3	0x3A35	0x53C9	# <CJK>
+0x8DB4	0x3A36	0x5506	# <CJK>
+0x8DB5	0x3A37	0x5D6F	# <CJK>
+0x8DB6	0x3A38	0x5DE6	# <CJK>
+0x8DB7	0x3A39	0x5DEE	# <CJK>
+0x8DB8	0x3A3A	0x67FB	# <CJK>
+0x8DB9	0x3A3B	0x6C99	# <CJK>
+0x8DBA	0x3A3C	0x7473	# <CJK>
+0x8DBB	0x3A3D	0x7802	# <CJK>
+0x8DBC	0x3A3E	0x8A50	# <CJK>
+0x8DBD	0x3A3F	0x9396	# <CJK>
+0x8DBE	0x3A40	0x88DF	# <CJK>
+0x8DBF	0x3A41	0x5750	# <CJK>
+0x8DC0	0x3A42	0x5EA7	# <CJK>
+0x8DC1	0x3A43	0x632B	# <CJK>
+0x8DC2	0x3A44	0x50B5	# <CJK>
+0x8DC3	0x3A45	0x50AC	# <CJK>
+0x8DC4	0x3A46	0x518D	# <CJK>
+0x8DC5	0x3A47	0x6700	# <CJK>
+0x8DC6	0x3A48	0x54C9	# <CJK>
+0x8DC7	0x3A49	0x585E	# <CJK>
+0x8DC8	0x3A4A	0x59BB	# <CJK>
+0x8DC9	0x3A4B	0x5BB0	# <CJK>
+0x8DCA	0x3A4C	0x5F69	# <CJK>
+0x8DCB	0x3A4D	0x624D	# <CJK>
+0x8DCC	0x3A4E	0x63A1	# <CJK>
+0x8DCD	0x3A4F	0x683D	# <CJK>
+0x8DCE	0x3A50	0x6B73	# <CJK>
+0x8DCF	0x3A51	0x6E08	# <CJK>
+0x8DD0	0x3A52	0x707D	# <CJK>
+0x8DD1	0x3A53	0x91C7	# <CJK>
+0x8DD2	0x3A54	0x7280	# <CJK>
+0x8DD3	0x3A55	0x7815	# <CJK>
+0x8DD4	0x3A56	0x7826	# <CJK>
+0x8DD5	0x3A57	0x796D	# <CJK>
+0x8DD6	0x3A58	0x658E	# <CJK>
+0x8DD7	0x3A59	0x7D30	# <CJK>
+0x8DD8	0x3A5A	0x83DC	# <CJK>
+0x8DD9	0x3A5B	0x88C1	# <CJK>
+0x8DDA	0x3A5C	0x8F09	# <CJK>
+0x8DDB	0x3A5D	0x969B	# <CJK>
+0x8DDC	0x3A5E	0x5264	# <CJK>
+0x8DDD	0x3A5F	0x5728	# <CJK>
+0x8DDE	0x3A60	0x6750	# <CJK>
+0x8DDF	0x3A61	0x7F6A	# <CJK>
+0x8DE0	0x3A62	0x8CA1	# <CJK>
+0x8DE1	0x3A63	0x51B4	# <CJK>
+0x8DE2	0x3A64	0x5742	# <CJK>
+0x8DE3	0x3A65	0x962A	# <CJK>
+0x8DE4	0x3A66	0x583A	# <CJK>
+0x8DE5	0x3A67	0x698A	# <CJK>
+0x8DE6	0x3A68	0x80B4	# <CJK>
+0x8DE7	0x3A69	0x54B2	# <CJK>
+0x8DE8	0x3A6A	0x5D0E	# <CJK>
+0x8DE9	0x3A6B	0x57FC	# <CJK>
+0x8DEA	0x3A6C	0x7895	# <CJK>
+0x8DEB	0x3A6D	0x9DFA	# <CJK>
+0x8DEC	0x3A6E	0x4F5C	# <CJK>
+0x8DED	0x3A6F	0x524A	# <CJK>
+0x8DEE	0x3A70	0x548B	# <CJK>
+0x8DEF	0x3A71	0x643E	# <CJK>
+0x8DF0	0x3A72	0x6628	# <CJK>
+0x8DF1	0x3A73	0x6714	# <CJK>
+0x8DF2	0x3A74	0x67F5	# <CJK>
+0x8DF3	0x3A75	0x7A84	# <CJK>
+0x8DF4	0x3A76	0x7B56	# <CJK>
+0x8DF5	0x3A77	0x7D22	# <CJK>
+0x8DF6	0x3A78	0x932F	# <CJK>
+0x8DF7	0x3A79	0x685C	# <CJK>
+0x8DF8	0x3A7A	0x9BAD	# <CJK>
+0x8DF9	0x3A7B	0x7B39	# <CJK>
+0x8DFA	0x3A7C	0x5319	# <CJK>
+0x8DFB	0x3A7D	0x518A	# <CJK>
+0x8DFC	0x3A7E	0x5237	# <CJK>
+0x8E40	0x3B21	0x5BDF	# <CJK>
+0x8E41	0x3B22	0x62F6	# <CJK>
+0x8E42	0x3B23	0x64AE	# <CJK>
+0x8E43	0x3B24	0x64E6	# <CJK>
+0x8E44	0x3B25	0x672D	# <CJK>
+0x8E45	0x3B26	0x6BBA	# <CJK>
+0x8E46	0x3B27	0x85A9	# <CJK>
+0x8E47	0x3B28	0x96D1	# <CJK>
+0x8E48	0x3B29	0x7690	# <CJK>
+0x8E49	0x3B2A	0x9BD6	# <CJK>
+0x8E4A	0x3B2B	0x634C	# <CJK>
+0x8E4B	0x3B2C	0x9306	# <CJK>
+0x8E4C	0x3B2D	0x9BAB	# <CJK>
+0x8E4D	0x3B2E	0x76BF	# <CJK>
+0x8E4E	0x3B2F	0x6652	# <CJK>
+0x8E4F	0x3B30	0x4E09	# <CJK>
+0x8E50	0x3B31	0x5098	# <CJK>
+0x8E51	0x3B32	0x53C2	# <CJK>
+0x8E52	0x3B33	0x5C71	# <CJK>
+0x8E53	0x3B34	0x60E8	# <CJK>
+0x8E54	0x3B35	0x6492	# <CJK>
+0x8E55	0x3B36	0x6563	# <CJK>
+0x8E56	0x3B37	0x685F	# <CJK>
+0x8E57	0x3B38	0x71E6	# <CJK>
+0x8E58	0x3B39	0x73CA	# <CJK>
+0x8E59	0x3B3A	0x7523	# <CJK>
+0x8E5A	0x3B3B	0x7B97	# <CJK>
+0x8E5B	0x3B3C	0x7E82	# <CJK>
+0x8E5C	0x3B3D	0x8695	# <CJK>
+0x8E5D	0x3B3E	0x8B83	# <CJK>
+0x8E5E	0x3B3F	0x8CDB	# <CJK>
+0x8E5F	0x3B40	0x9178	# <CJK>
+0x8E60	0x3B41	0x9910	# <CJK>
+0x8E61	0x3B42	0x65AC	# <CJK>
+0x8E62	0x3B43	0x66AB	# <CJK>
+0x8E63	0x3B44	0x6B8B	# <CJK>
+0x8E64	0x3B45	0x4ED5	# <CJK>
+0x8E65	0x3B46	0x4ED4	# <CJK>
+0x8E66	0x3B47	0x4F3A	# <CJK>
+0x8E67	0x3B48	0x4F7F	# <CJK>
+0x8E68	0x3B49	0x523A	# <CJK>
+0x8E69	0x3B4A	0x53F8	# <CJK>
+0x8E6A	0x3B4B	0x53F2	# <CJK>
+0x8E6B	0x3B4C	0x55E3	# <CJK>
+0x8E6C	0x3B4D	0x56DB	# <CJK>
+0x8E6D	0x3B4E	0x58EB	# <CJK>
+0x8E6E	0x3B4F	0x59CB	# <CJK>
+0x8E6F	0x3B50	0x59C9	# <CJK>
+0x8E70	0x3B51	0x59FF	# <CJK>
+0x8E71	0x3B52	0x5B50	# <CJK>
+0x8E72	0x3B53	0x5C4D	# <CJK>
+0x8E73	0x3B54	0x5E02	# <CJK>
+0x8E74	0x3B55	0x5E2B	# <CJK>
+0x8E75	0x3B56	0x5FD7	# <CJK>
+0x8E76	0x3B57	0x601D	# <CJK>
+0x8E77	0x3B58	0x6307	# <CJK>
+0x8E78	0x3B59	0x652F	# <CJK>
+0x8E79	0x3B5A	0x5B5C	# <CJK>
+0x8E7A	0x3B5B	0x65AF	# <CJK>
+0x8E7B	0x3B5C	0x65BD	# <CJK>
+0x8E7C	0x3B5D	0x65E8	# <CJK>
+0x8E7D	0x3B5E	0x679D	# <CJK>
+0x8E7E	0x3B5F	0x6B62	# <CJK>
+0x8E80	0x3B60	0x6B7B	# <CJK>
+0x8E81	0x3B61	0x6C0F	# <CJK>
+0x8E82	0x3B62	0x7345	# <CJK>
+0x8E83	0x3B63	0x7949	# <CJK>
+0x8E84	0x3B64	0x79C1	# <CJK>
+0x8E85	0x3B65	0x7CF8	# <CJK>
+0x8E86	0x3B66	0x7D19	# <CJK>
+0x8E87	0x3B67	0x7D2B	# <CJK>
+0x8E88	0x3B68	0x80A2	# <CJK>
+0x8E89	0x3B69	0x8102	# <CJK>
+0x8E8A	0x3B6A	0x81F3	# <CJK>
+0x8E8B	0x3B6B	0x8996	# <CJK>
+0x8E8C	0x3B6C	0x8A5E	# <CJK>
+0x8E8D	0x3B6D	0x8A69	# <CJK>
+0x8E8E	0x3B6E	0x8A66	# <CJK>
+0x8E8F	0x3B6F	0x8A8C	# <CJK>
+0x8E90	0x3B70	0x8AEE	# <CJK>
+0x8E91	0x3B71	0x8CC7	# <CJK>
+0x8E92	0x3B72	0x8CDC	# <CJK>
+0x8E93	0x3B73	0x96CC	# <CJK>
+0x8E94	0x3B74	0x98FC	# <CJK>
+0x8E95	0x3B75	0x6B6F	# <CJK>
+0x8E96	0x3B76	0x4E8B	# <CJK>
+0x8E97	0x3B77	0x4F3C	# <CJK>
+0x8E98	0x3B78	0x4F8D	# <CJK>
+0x8E99	0x3B79	0x5150	# <CJK>
+0x8E9A	0x3B7A	0x5B57	# <CJK>
+0x8E9B	0x3B7B	0x5BFA	# <CJK>
+0x8E9C	0x3B7C	0x6148	# <CJK>
+0x8E9D	0x3B7D	0x6301	# <CJK>
+0x8E9E	0x3B7E	0x6642	# <CJK>
+0x8E9F	0x3C21	0x6B21	# <CJK>
+0x8EA0	0x3C22	0x6ECB	# <CJK>
+0x8EA1	0x3C23	0x6CBB	# <CJK>
+0x8EA2	0x3C24	0x723E	# <CJK>
+0x8EA3	0x3C25	0x74BD	# <CJK>
+0x8EA4	0x3C26	0x75D4	# <CJK>
+0x8EA5	0x3C27	0x78C1	# <CJK>
+0x8EA6	0x3C28	0x793A	# <CJK>
+0x8EA7	0x3C29	0x800C	# <CJK>
+0x8EA8	0x3C2A	0x8033	# <CJK>
+0x8EA9	0x3C2B	0x81EA	# <CJK>
+0x8EAA	0x3C2C	0x8494	# <CJK>
+0x8EAB	0x3C2D	0x8F9E	# <CJK>
+0x8EAC	0x3C2E	0x6C50	# <CJK>
+0x8EAD	0x3C2F	0x9E7F	# <CJK>
+0x8EAE	0x3C30	0x5F0F	# <CJK>
+0x8EAF	0x3C31	0x8B58	# <CJK>
+0x8EB0	0x3C32	0x9D2B	# <CJK>
+0x8EB1	0x3C33	0x7AFA	# <CJK>
+0x8EB2	0x3C34	0x8EF8	# <CJK>
+0x8EB3	0x3C35	0x5B8D	# <CJK>
+0x8EB4	0x3C36	0x96EB	# <CJK>
+0x8EB5	0x3C37	0x4E03	# <CJK>
+0x8EB6	0x3C38	0x53F1	# <CJK>
+0x8EB7	0x3C39	0x57F7	# <CJK>
+0x8EB8	0x3C3A	0x5931	# <CJK>
+0x8EB9	0x3C3B	0x5AC9	# <CJK>
+0x8EBA	0x3C3C	0x5BA4	# <CJK>
+0x8EBB	0x3C3D	0x6089	# <CJK>
+0x8EBC	0x3C3E	0x6E7F	# <CJK>
+0x8EBD	0x3C3F	0x6F06	# <CJK>
+0x8EBE	0x3C40	0x75BE	# <CJK>
+0x8EBF	0x3C41	0x8CEA	# <CJK>
+0x8EC0	0x3C42	0x5B9F	# <CJK>
+0x8EC1	0x3C43	0x8500	# <CJK>
+0x8EC2	0x3C44	0x7BE0	# <CJK>
+0x8EC3	0x3C45	0x5072	# <CJK>
+0x8EC4	0x3C46	0x67F4	# <CJK>
+0x8EC5	0x3C47	0x829D	# <CJK>
+0x8EC6	0x3C48	0x5C61	# <CJK>
+0x8EC7	0x3C49	0x854A	# <CJK>
+0x8EC8	0x3C4A	0x7E1E	# <CJK>
+0x8EC9	0x3C4B	0x820E	# <CJK>
+0x8ECA	0x3C4C	0x5199	# <CJK>
+0x8ECB	0x3C4D	0x5C04	# <CJK>
+0x8ECC	0x3C4E	0x6368	# <CJK>
+0x8ECD	0x3C4F	0x8D66	# <CJK>
+0x8ECE	0x3C50	0x659C	# <CJK>
+0x8ECF	0x3C51	0x716E	# <CJK>
+0x8ED0	0x3C52	0x793E	# <CJK>
+0x8ED1	0x3C53	0x7D17	# <CJK>
+0x8ED2	0x3C54	0x8005	# <CJK>
+0x8ED3	0x3C55	0x8B1D	# <CJK>
+0x8ED4	0x3C56	0x8ECA	# <CJK>
+0x8ED5	0x3C57	0x906E	# <CJK>
+0x8ED6	0x3C58	0x86C7	# <CJK>
+0x8ED7	0x3C59	0x90AA	# <CJK>
+0x8ED8	0x3C5A	0x501F	# <CJK>
+0x8ED9	0x3C5B	0x52FA	# <CJK>
+0x8EDA	0x3C5C	0x5C3A	# <CJK>
+0x8EDB	0x3C5D	0x6753	# <CJK>
+0x8EDC	0x3C5E	0x707C	# <CJK>
+0x8EDD	0x3C5F	0x7235	# <CJK>
+0x8EDE	0x3C60	0x914C	# <CJK>
+0x8EDF	0x3C61	0x91C8	# <CJK>
+0x8EE0	0x3C62	0x932B	# <CJK>
+0x8EE1	0x3C63	0x82E5	# <CJK>
+0x8EE2	0x3C64	0x5BC2	# <CJK>
+0x8EE3	0x3C65	0x5F31	# <CJK>
+0x8EE4	0x3C66	0x60F9	# <CJK>
+0x8EE5	0x3C67	0x4E3B	# <CJK>
+0x8EE6	0x3C68	0x53D6	# <CJK>
+0x8EE7	0x3C69	0x5B88	# <CJK>
+0x8EE8	0x3C6A	0x624B	# <CJK>
+0x8EE9	0x3C6B	0x6731	# <CJK>
+0x8EEA	0x3C6C	0x6B8A	# <CJK>
+0x8EEB	0x3C6D	0x72E9	# <CJK>
+0x8EEC	0x3C6E	0x73E0	# <CJK>
+0x8EED	0x3C6F	0x7A2E	# <CJK>
+0x8EEE	0x3C70	0x816B	# <CJK>
+0x8EEF	0x3C71	0x8DA3	# <CJK>
+0x8EF0	0x3C72	0x9152	# <CJK>
+0x8EF1	0x3C73	0x9996	# <CJK>
+0x8EF2	0x3C74	0x5112	# <CJK>
+0x8EF3	0x3C75	0x53D7	# <CJK>
+0x8EF4	0x3C76	0x546A	# <CJK>
+0x8EF5	0x3C77	0x5BFF	# <CJK>
+0x8EF6	0x3C78	0x6388	# <CJK>
+0x8EF7	0x3C79	0x6A39	# <CJK>
+0x8EF8	0x3C7A	0x7DAC	# <CJK>
+0x8EF9	0x3C7B	0x9700	# <CJK>
+0x8EFA	0x3C7C	0x56DA	# <CJK>
+0x8EFB	0x3C7D	0x53CE	# <CJK>
+0x8EFC	0x3C7E	0x5468	# <CJK>
+0x8F40	0x3D21	0x5B97	# <CJK>
+0x8F41	0x3D22	0x5C31	# <CJK>
+0x8F42	0x3D23	0x5DDE	# <CJK>
+0x8F43	0x3D24	0x4FEE	# <CJK>
+0x8F44	0x3D25	0x6101	# <CJK>
+0x8F45	0x3D26	0x62FE	# <CJK>
+0x8F46	0x3D27	0x6D32	# <CJK>
+0x8F47	0x3D28	0x79C0	# <CJK>
+0x8F48	0x3D29	0x79CB	# <CJK>
+0x8F49	0x3D2A	0x7D42	# <CJK>
+0x8F4A	0x3D2B	0x7E4D	# <CJK>
+0x8F4B	0x3D2C	0x7FD2	# <CJK>
+0x8F4C	0x3D2D	0x81ED	# <CJK>
+0x8F4D	0x3D2E	0x821F	# <CJK>
+0x8F4E	0x3D2F	0x8490	# <CJK>
+0x8F4F	0x3D30	0x8846	# <CJK>
+0x8F50	0x3D31	0x8972	# <CJK>
+0x8F51	0x3D32	0x8B90	# <CJK>
+0x8F52	0x3D33	0x8E74	# <CJK>
+0x8F53	0x3D34	0x8F2F	# <CJK>
+0x8F54	0x3D35	0x9031	# <CJK>
+0x8F55	0x3D36	0x914B	# <CJK>
+0x8F56	0x3D37	0x916C	# <CJK>
+0x8F57	0x3D38	0x96C6	# <CJK>
+0x8F58	0x3D39	0x919C	# <CJK>
+0x8F59	0x3D3A	0x4EC0	# <CJK>
+0x8F5A	0x3D3B	0x4F4F	# <CJK>
+0x8F5B	0x3D3C	0x5145	# <CJK>
+0x8F5C	0x3D3D	0x5341	# <CJK>
+0x8F5D	0x3D3E	0x5F93	# <CJK>
+0x8F5E	0x3D3F	0x620E	# <CJK>
+0x8F5F	0x3D40	0x67D4	# <CJK>
+0x8F60	0x3D41	0x6C41	# <CJK>
+0x8F61	0x3D42	0x6E0B	# <CJK>
+0x8F62	0x3D43	0x7363	# <CJK>
+0x8F63	0x3D44	0x7E26	# <CJK>
+0x8F64	0x3D45	0x91CD	# <CJK>
+0x8F65	0x3D46	0x9283	# <CJK>
+0x8F66	0x3D47	0x53D4	# <CJK>
+0x8F67	0x3D48	0x5919	# <CJK>
+0x8F68	0x3D49	0x5BBF	# <CJK>
+0x8F69	0x3D4A	0x6DD1	# <CJK>
+0x8F6A	0x3D4B	0x795D	# <CJK>
+0x8F6B	0x3D4C	0x7E2E	# <CJK>
+0x8F6C	0x3D4D	0x7C9B	# <CJK>
+0x8F6D	0x3D4E	0x587E	# <CJK>
+0x8F6E	0x3D4F	0x719F	# <CJK>
+0x8F6F	0x3D50	0x51FA	# <CJK>
+0x8F70	0x3D51	0x8853	# <CJK>
+0x8F71	0x3D52	0x8FF0	# <CJK>
+0x8F72	0x3D53	0x4FCA	# <CJK>
+0x8F73	0x3D54	0x5CFB	# <CJK>
+0x8F74	0x3D55	0x6625	# <CJK>
+0x8F75	0x3D56	0x77AC	# <CJK>
+0x8F76	0x3D57	0x7AE3	# <CJK>
+0x8F77	0x3D58	0x821C	# <CJK>
+0x8F78	0x3D59	0x99FF	# <CJK>
+0x8F79	0x3D5A	0x51C6	# <CJK>
+0x8F7A	0x3D5B	0x5FAA	# <CJK>
+0x8F7B	0x3D5C	0x65EC	# <CJK>
+0x8F7C	0x3D5D	0x696F	# <CJK>
+0x8F7D	0x3D5E	0x6B89	# <CJK>
+0x8F7E	0x3D5F	0x6DF3	# <CJK>
+0x8F80	0x3D60	0x6E96	# <CJK>
+0x8F81	0x3D61	0x6F64	# <CJK>
+0x8F82	0x3D62	0x76FE	# <CJK>
+0x8F83	0x3D63	0x7D14	# <CJK>
+0x8F84	0x3D64	0x5DE1	# <CJK>
+0x8F85	0x3D65	0x9075	# <CJK>
+0x8F86	0x3D66	0x9187	# <CJK>
+0x8F87	0x3D67	0x9806	# <CJK>
+0x8F88	0x3D68	0x51E6	# <CJK>
+0x8F89	0x3D69	0x521D	# <CJK>
+0x8F8A	0x3D6A	0x6240	# <CJK>
+0x8F8B	0x3D6B	0x6691	# <CJK>
+0x8F8C	0x3D6C	0x66D9	# <CJK>
+0x8F8D	0x3D6D	0x6E1A	# <CJK>
+0x8F8E	0x3D6E	0x5EB6	# <CJK>
+0x8F8F	0x3D6F	0x7DD2	# <CJK>
+0x8F90	0x3D70	0x7F72	# <CJK>
+0x8F91	0x3D71	0x66F8	# <CJK>
+0x8F92	0x3D72	0x85AF	# <CJK>
+0x8F93	0x3D73	0x85F7	# <CJK>
+0x8F94	0x3D74	0x8AF8	# <CJK>
+0x8F95	0x3D75	0x52A9	# <CJK>
+0x8F96	0x3D76	0x53D9	# <CJK>
+0x8F97	0x3D77	0x5973	# <CJK>
+0x8F98	0x3D78	0x5E8F	# <CJK>
+0x8F99	0x3D79	0x5F90	# <CJK>
+0x8F9A	0x3D7A	0x6055	# <CJK>
+0x8F9B	0x3D7B	0x92E4	# <CJK>
+0x8F9C	0x3D7C	0x9664	# <CJK>
+0x8F9D	0x3D7D	0x50B7	# <CJK>
+0x8F9E	0x3D7E	0x511F	# <CJK>
+0x8F9F	0x3E21	0x52DD	# <CJK>
+0x8FA0	0x3E22	0x5320	# <CJK>
+0x8FA1	0x3E23	0x5347	# <CJK>
+0x8FA2	0x3E24	0x53EC	# <CJK>
+0x8FA3	0x3E25	0x54E8	# <CJK>
+0x8FA4	0x3E26	0x5546	# <CJK>
+0x8FA5	0x3E27	0x5531	# <CJK>
+0x8FA6	0x3E28	0x5617	# <CJK>
+0x8FA7	0x3E29	0x5968	# <CJK>
+0x8FA8	0x3E2A	0x59BE	# <CJK>
+0x8FA9	0x3E2B	0x5A3C	# <CJK>
+0x8FAA	0x3E2C	0x5BB5	# <CJK>
+0x8FAB	0x3E2D	0x5C06	# <CJK>
+0x8FAC	0x3E2E	0x5C0F	# <CJK>
+0x8FAD	0x3E2F	0x5C11	# <CJK>
+0x8FAE	0x3E30	0x5C1A	# <CJK>
+0x8FAF	0x3E31	0x5E84	# <CJK>
+0x8FB0	0x3E32	0x5E8A	# <CJK>
+0x8FB1	0x3E33	0x5EE0	# <CJK>
+0x8FB2	0x3E34	0x5F70	# <CJK>
+0x8FB3	0x3E35	0x627F	# <CJK>
+0x8FB4	0x3E36	0x6284	# <CJK>
+0x8FB5	0x3E37	0x62DB	# <CJK>
+0x8FB6	0x3E38	0x638C	# <CJK>
+0x8FB7	0x3E39	0x6377	# <CJK>
+0x8FB8	0x3E3A	0x6607	# <CJK>
+0x8FB9	0x3E3B	0x660C	# <CJK>
+0x8FBA	0x3E3C	0x662D	# <CJK>
+0x8FBB	0x3E3D	0x6676	# <CJK>
+0x8FBC	0x3E3E	0x677E	# <CJK>
+0x8FBD	0x3E3F	0x68A2	# <CJK>
+0x8FBE	0x3E40	0x6A1F	# <CJK>
+0x8FBF	0x3E41	0x6A35	# <CJK>
+0x8FC0	0x3E42	0x6CBC	# <CJK>
+0x8FC1	0x3E43	0x6D88	# <CJK>
+0x8FC2	0x3E44	0x6E09	# <CJK>
+0x8FC3	0x3E45	0x6E58	# <CJK>
+0x8FC4	0x3E46	0x713C	# <CJK>
+0x8FC5	0x3E47	0x7126	# <CJK>
+0x8FC6	0x3E48	0x7167	# <CJK>
+0x8FC7	0x3E49	0x75C7	# <CJK>
+0x8FC8	0x3E4A	0x7701	# <CJK>
+0x8FC9	0x3E4B	0x785D	# <CJK>
+0x8FCA	0x3E4C	0x7901	# <CJK>
+0x8FCB	0x3E4D	0x7965	# <CJK>
+0x8FCC	0x3E4E	0x79F0	# <CJK>
+0x8FCD	0x3E4F	0x7AE0	# <CJK>
+0x8FCE	0x3E50	0x7B11	# <CJK>
+0x8FCF	0x3E51	0x7CA7	# <CJK>
+0x8FD0	0x3E52	0x7D39	# <CJK>
+0x8FD1	0x3E53	0x8096	# <CJK>
+0x8FD2	0x3E54	0x83D6	# <CJK>
+0x8FD3	0x3E55	0x848B	# <CJK>
+0x8FD4	0x3E56	0x8549	# <CJK>
+0x8FD5	0x3E57	0x885D	# <CJK>
+0x8FD6	0x3E58	0x88F3	# <CJK>
+0x8FD7	0x3E59	0x8A1F	# <CJK>
+0x8FD8	0x3E5A	0x8A3C	# <CJK>
+0x8FD9	0x3E5B	0x8A54	# <CJK>
+0x8FDA	0x3E5C	0x8A73	# <CJK>
+0x8FDB	0x3E5D	0x8C61	# <CJK>
+0x8FDC	0x3E5E	0x8CDE	# <CJK>
+0x8FDD	0x3E5F	0x91A4	# <CJK>
+0x8FDE	0x3E60	0x9266	# <CJK>
+0x8FDF	0x3E61	0x937E	# <CJK>
+0x8FE0	0x3E62	0x9418	# <CJK>
+0x8FE1	0x3E63	0x969C	# <CJK>
+0x8FE2	0x3E64	0x9798	# <CJK>
+0x8FE3	0x3E65	0x4E0A	# <CJK>
+0x8FE4	0x3E66	0x4E08	# <CJK>
+0x8FE5	0x3E67	0x4E1E	# <CJK>
+0x8FE6	0x3E68	0x4E57	# <CJK>
+0x8FE7	0x3E69	0x5197	# <CJK>
+0x8FE8	0x3E6A	0x5270	# <CJK>
+0x8FE9	0x3E6B	0x57CE	# <CJK>
+0x8FEA	0x3E6C	0x5834	# <CJK>
+0x8FEB	0x3E6D	0x58CC	# <CJK>
+0x8FEC	0x3E6E	0x5B22	# <CJK>
+0x8FED	0x3E6F	0x5E38	# <CJK>
+0x8FEE	0x3E70	0x60C5	# <CJK>
+0x8FEF	0x3E71	0x64FE	# <CJK>
+0x8FF0	0x3E72	0x6761	# <CJK>
+0x8FF1	0x3E73	0x6756	# <CJK>
+0x8FF2	0x3E74	0x6D44	# <CJK>
+0x8FF3	0x3E75	0x72B6	# <CJK>
+0x8FF4	0x3E76	0x7573	# <CJK>
+0x8FF5	0x3E77	0x7A63	# <CJK>
+0x8FF6	0x3E78	0x84B8	# <CJK>
+0x8FF7	0x3E79	0x8B72	# <CJK>
+0x8FF8	0x3E7A	0x91B8	# <CJK>
+0x8FF9	0x3E7B	0x9320	# <CJK>
+0x8FFA	0x3E7C	0x5631	# <CJK>
+0x8FFB	0x3E7D	0x57F4	# <CJK>
+0x8FFC	0x3E7E	0x98FE	# <CJK>
+0x9040	0x3F21	0x62ED	# <CJK>
+0x9041	0x3F22	0x690D	# <CJK>
+0x9042	0x3F23	0x6B96	# <CJK>
+0x9043	0x3F24	0x71ED	# <CJK>
+0x9044	0x3F25	0x7E54	# <CJK>
+0x9045	0x3F26	0x8077	# <CJK>
+0x9046	0x3F27	0x8272	# <CJK>
+0x9047	0x3F28	0x89E6	# <CJK>
+0x9048	0x3F29	0x98DF	# <CJK>
+0x9049	0x3F2A	0x8755	# <CJK>
+0x904A	0x3F2B	0x8FB1	# <CJK>
+0x904B	0x3F2C	0x5C3B	# <CJK>
+0x904C	0x3F2D	0x4F38	# <CJK>
+0x904D	0x3F2E	0x4FE1	# <CJK>
+0x904E	0x3F2F	0x4FB5	# <CJK>
+0x904F	0x3F30	0x5507	# <CJK>
+0x9050	0x3F31	0x5A20	# <CJK>
+0x9051	0x3F32	0x5BDD	# <CJK>
+0x9052	0x3F33	0x5BE9	# <CJK>
+0x9053	0x3F34	0x5FC3	# <CJK>
+0x9054	0x3F35	0x614E	# <CJK>
+0x9055	0x3F36	0x632F	# <CJK>
+0x9056	0x3F37	0x65B0	# <CJK>
+0x9057	0x3F38	0x664B	# <CJK>
+0x9058	0x3F39	0x68EE	# <CJK>
+0x9059	0x3F3A	0x699B	# <CJK>
+0x905A	0x3F3B	0x6D78	# <CJK>
+0x905B	0x3F3C	0x6DF1	# <CJK>
+0x905C	0x3F3D	0x7533	# <CJK>
+0x905D	0x3F3E	0x75B9	# <CJK>
+0x905E	0x3F3F	0x771F	# <CJK>
+0x905F	0x3F40	0x795E	# <CJK>
+0x9060	0x3F41	0x79E6	# <CJK>
+0x9061	0x3F42	0x7D33	# <CJK>
+0x9062	0x3F43	0x81E3	# <CJK>
+0x9063	0x3F44	0x82AF	# <CJK>
+0x9064	0x3F45	0x85AA	# <CJK>
+0x9065	0x3F46	0x89AA	# <CJK>
+0x9066	0x3F47	0x8A3A	# <CJK>
+0x9067	0x3F48	0x8EAB	# <CJK>
+0x9068	0x3F49	0x8F9B	# <CJK>
+0x9069	0x3F4A	0x9032	# <CJK>
+0x906A	0x3F4B	0x91DD	# <CJK>
+0x906B	0x3F4C	0x9707	# <CJK>
+0x906C	0x3F4D	0x4EBA	# <CJK>
+0x906D	0x3F4E	0x4EC1	# <CJK>
+0x906E	0x3F4F	0x5203	# <CJK>
+0x906F	0x3F50	0x5875	# <CJK>
+0x9070	0x3F51	0x58EC	# <CJK>
+0x9071	0x3F52	0x5C0B	# <CJK>
+0x9072	0x3F53	0x751A	# <CJK>
+0x9073	0x3F54	0x5C3D	# <CJK>
+0x9074	0x3F55	0x814E	# <CJK>
+0x9075	0x3F56	0x8A0A	# <CJK>
+0x9076	0x3F57	0x8FC5	# <CJK>
+0x9077	0x3F58	0x9663	# <CJK>
+0x9078	0x3F59	0x976D	# <CJK>
+0x9079	0x3F5A	0x7B25	# <CJK>
+0x907A	0x3F5B	0x8ACF	# <CJK>
+0x907B	0x3F5C	0x9808	# <CJK>
+0x907C	0x3F5D	0x9162	# <CJK>
+0x907D	0x3F5E	0x56F3	# <CJK>
+0x907E	0x3F5F	0x53A8	# <CJK>
+0x9080	0x3F60	0x9017	# <CJK>
+0x9081	0x3F61	0x5439	# <CJK>
+0x9082	0x3F62	0x5782	# <CJK>
+0x9083	0x3F63	0x5E25	# <CJK>
+0x9084	0x3F64	0x63A8	# <CJK>
+0x9085	0x3F65	0x6C34	# <CJK>
+0x9086	0x3F66	0x708A	# <CJK>
+0x9087	0x3F67	0x7761	# <CJK>
+0x9088	0x3F68	0x7C8B	# <CJK>
+0x9089	0x3F69	0x7FE0	# <CJK>
+0x908A	0x3F6A	0x8870	# <CJK>
+0x908B	0x3F6B	0x9042	# <CJK>
+0x908C	0x3F6C	0x9154	# <CJK>
+0x908D	0x3F6D	0x9310	# <CJK>
+0x908E	0x3F6E	0x9318	# <CJK>
+0x908F	0x3F6F	0x968F	# <CJK>
+0x9090	0x3F70	0x745E	# <CJK>
+0x9091	0x3F71	0x9AC4	# <CJK>
+0x9092	0x3F72	0x5D07	# <CJK>
+0x9093	0x3F73	0x5D69	# <CJK>
+0x9094	0x3F74	0x6570	# <CJK>
+0x9095	0x3F75	0x67A2	# <CJK>
+0x9096	0x3F76	0x8DA8	# <CJK>
+0x9097	0x3F77	0x96DB	# <CJK>
+0x9098	0x3F78	0x636E	# <CJK>
+0x9099	0x3F79	0x6749	# <CJK>
+0x909A	0x3F7A	0x6919	# <CJK>
+0x909B	0x3F7B	0x83C5	# <CJK>
+0x909C	0x3F7C	0x9817	# <CJK>
+0x909D	0x3F7D	0x96C0	# <CJK>
+0x909E	0x3F7E	0x88FE	# <CJK>
+0x909F	0x4021	0x6F84	# <CJK>
+0x90A0	0x4022	0x647A	# <CJK>
+0x90A1	0x4023	0x5BF8	# <CJK>
+0x90A2	0x4024	0x4E16	# <CJK>
+0x90A3	0x4025	0x702C	# <CJK>
+0x90A4	0x4026	0x755D	# <CJK>
+0x90A5	0x4027	0x662F	# <CJK>
+0x90A6	0x4028	0x51C4	# <CJK>
+0x90A7	0x4029	0x5236	# <CJK>
+0x90A8	0x402A	0x52E2	# <CJK>
+0x90A9	0x402B	0x59D3	# <CJK>
+0x90AA	0x402C	0x5F81	# <CJK>
+0x90AB	0x402D	0x6027	# <CJK>
+0x90AC	0x402E	0x6210	# <CJK>
+0x90AD	0x402F	0x653F	# <CJK>
+0x90AE	0x4030	0x6574	# <CJK>
+0x90AF	0x4031	0x661F	# <CJK>
+0x90B0	0x4032	0x6674	# <CJK>
+0x90B1	0x4033	0x68F2	# <CJK>
+0x90B2	0x4034	0x6816	# <CJK>
+0x90B3	0x4035	0x6B63	# <CJK>
+0x90B4	0x4036	0x6E05	# <CJK>
+0x90B5	0x4037	0x7272	# <CJK>
+0x90B6	0x4038	0x751F	# <CJK>
+0x90B7	0x4039	0x76DB	# <CJK>
+0x90B8	0x403A	0x7CBE	# <CJK>
+0x90B9	0x403B	0x8056	# <CJK>
+0x90BA	0x403C	0x58F0	# <CJK>
+0x90BB	0x403D	0x88FD	# <CJK>
+0x90BC	0x403E	0x897F	# <CJK>
+0x90BD	0x403F	0x8AA0	# <CJK>
+0x90BE	0x4040	0x8A93	# <CJK>
+0x90BF	0x4041	0x8ACB	# <CJK>
+0x90C0	0x4042	0x901D	# <CJK>
+0x90C1	0x4043	0x9192	# <CJK>
+0x90C2	0x4044	0x9752	# <CJK>
+0x90C3	0x4045	0x9759	# <CJK>
+0x90C4	0x4046	0x6589	# <CJK>
+0x90C5	0x4047	0x7A0E	# <CJK>
+0x90C6	0x4048	0x8106	# <CJK>
+0x90C7	0x4049	0x96BB	# <CJK>
+0x90C8	0x404A	0x5E2D	# <CJK>
+0x90C9	0x404B	0x60DC	# <CJK>
+0x90CA	0x404C	0x621A	# <CJK>
+0x90CB	0x404D	0x65A5	# <CJK>
+0x90CC	0x404E	0x6614	# <CJK>
+0x90CD	0x404F	0x6790	# <CJK>
+0x90CE	0x4050	0x77F3	# <CJK>
+0x90CF	0x4051	0x7A4D	# <CJK>
+0x90D0	0x4052	0x7C4D	# <CJK>
+0x90D1	0x4053	0x7E3E	# <CJK>
+0x90D2	0x4054	0x810A	# <CJK>
+0x90D3	0x4055	0x8CAC	# <CJK>
+0x90D4	0x4056	0x8D64	# <CJK>
+0x90D5	0x4057	0x8DE1	# <CJK>
+0x90D6	0x4058	0x8E5F	# <CJK>
+0x90D7	0x4059	0x78A9	# <CJK>
+0x90D8	0x405A	0x5207	# <CJK>
+0x90D9	0x405B	0x62D9	# <CJK>
+0x90DA	0x405C	0x63A5	# <CJK>
+0x90DB	0x405D	0x6442	# <CJK>
+0x90DC	0x405E	0x6298	# <CJK>
+0x90DD	0x405F	0x8A2D	# <CJK>
+0x90DE	0x4060	0x7A83	# <CJK>
+0x90DF	0x4061	0x7BC0	# <CJK>
+0x90E0	0x4062	0x8AAC	# <CJK>
+0x90E1	0x4063	0x96EA	# <CJK>
+0x90E2	0x4064	0x7D76	# <CJK>
+0x90E3	0x4065	0x820C	# <CJK>
+0x90E4	0x4066	0x8749	# <CJK>
+0x90E5	0x4067	0x4ED9	# <CJK>
+0x90E6	0x4068	0x5148	# <CJK>
+0x90E7	0x4069	0x5343	# <CJK>
+0x90E8	0x406A	0x5360	# <CJK>
+0x90E9	0x406B	0x5BA3	# <CJK>
+0x90EA	0x406C	0x5C02	# <CJK>
+0x90EB	0x406D	0x5C16	# <CJK>
+0x90EC	0x406E	0x5DDD	# <CJK>
+0x90ED	0x406F	0x6226	# <CJK>
+0x90EE	0x4070	0x6247	# <CJK>
+0x90EF	0x4071	0x64B0	# <CJK>
+0x90F0	0x4072	0x6813	# <CJK>
+0x90F1	0x4073	0x6834	# <CJK>
+0x90F2	0x4074	0x6CC9	# <CJK>
+0x90F3	0x4075	0x6D45	# <CJK>
+0x90F4	0x4076	0x6D17	# <CJK>
+0x90F5	0x4077	0x67D3	# <CJK>
+0x90F6	0x4078	0x6F5C	# <CJK>
+0x90F7	0x4079	0x714E	# <CJK>
+0x90F8	0x407A	0x717D	# <CJK>
+0x90F9	0x407B	0x65CB	# <CJK>
+0x90FA	0x407C	0x7A7F	# <CJK>
+0x90FB	0x407D	0x7BAD	# <CJK>
+0x90FC	0x407E	0x7DDA	# <CJK>
+0x9140	0x4121	0x7E4A	# <CJK>
+0x9141	0x4122	0x7FA8	# <CJK>
+0x9142	0x4123	0x817A	# <CJK>
+0x9143	0x4124	0x821B	# <CJK>
+0x9144	0x4125	0x8239	# <CJK>
+0x9145	0x4126	0x85A6	# <CJK>
+0x9146	0x4127	0x8A6E	# <CJK>
+0x9147	0x4128	0x8CCE	# <CJK>
+0x9148	0x4129	0x8DF5	# <CJK>
+0x9149	0x412A	0x9078	# <CJK>
+0x914A	0x412B	0x9077	# <CJK>
+0x914B	0x412C	0x92AD	# <CJK>
+0x914C	0x412D	0x9291	# <CJK>
+0x914D	0x412E	0x9583	# <CJK>
+0x914E	0x412F	0x9BAE	# <CJK>
+0x914F	0x4130	0x524D	# <CJK>
+0x9150	0x4131	0x5584	# <CJK>
+0x9151	0x4132	0x6F38	# <CJK>
+0x9152	0x4133	0x7136	# <CJK>
+0x9153	0x4134	0x5168	# <CJK>
+0x9154	0x4135	0x7985	# <CJK>
+0x9155	0x4136	0x7E55	# <CJK>
+0x9156	0x4137	0x81B3	# <CJK>
+0x9157	0x4138	0x7CCE	# <CJK>
+0x9158	0x4139	0x564C	# <CJK>
+0x9159	0x413A	0x5851	# <CJK>
+0x915A	0x413B	0x5CA8	# <CJK>
+0x915B	0x413C	0x63AA	# <CJK>
+0x915C	0x413D	0x66FE	# <CJK>
+0x915D	0x413E	0x66FD	# <CJK>
+0x915E	0x413F	0x695A	# <CJK>
+0x915F	0x4140	0x72D9	# <CJK>
+0x9160	0x4141	0x758F	# <CJK>
+0x9161	0x4142	0x758E	# <CJK>
+0x9162	0x4143	0x790E	# <CJK>
+0x9163	0x4144	0x7956	# <CJK>
+0x9164	0x4145	0x79DF	# <CJK>
+0x9165	0x4146	0x7C97	# <CJK>
+0x9166	0x4147	0x7D20	# <CJK>
+0x9167	0x4148	0x7D44	# <CJK>
+0x9168	0x4149	0x8607	# <CJK>
+0x9169	0x414A	0x8A34	# <CJK>
+0x916A	0x414B	0x963B	# <CJK>
+0x916B	0x414C	0x9061	# <CJK>
+0x916C	0x414D	0x9F20	# <CJK>
+0x916D	0x414E	0x50E7	# <CJK>
+0x916E	0x414F	0x5275	# <CJK>
+0x916F	0x4150	0x53CC	# <CJK>
+0x9170	0x4151	0x53E2	# <CJK>
+0x9171	0x4152	0x5009	# <CJK>
+0x9172	0x4153	0x55AA	# <CJK>
+0x9173	0x4154	0x58EE	# <CJK>
+0x9174	0x4155	0x594F	# <CJK>
+0x9175	0x4156	0x723D	# <CJK>
+0x9176	0x4157	0x5B8B	# <CJK>
+0x9177	0x4158	0x5C64	# <CJK>
+0x9178	0x4159	0x531D	# <CJK>
+0x9179	0x415A	0x60E3	# <CJK>
+0x917A	0x415B	0x60F3	# <CJK>
+0x917B	0x415C	0x635C	# <CJK>
+0x917C	0x415D	0x6383	# <CJK>
+0x917D	0x415E	0x633F	# <CJK>
+0x917E	0x415F	0x63BB	# <CJK>
+0x9180	0x4160	0x64CD	# <CJK>
+0x9181	0x4161	0x65E9	# <CJK>
+0x9182	0x4162	0x66F9	# <CJK>
+0x9183	0x4163	0x5DE3	# <CJK>
+0x9184	0x4164	0x69CD	# <CJK>
+0x9185	0x4165	0x69FD	# <CJK>
+0x9186	0x4166	0x6F15	# <CJK>
+0x9187	0x4167	0x71E5	# <CJK>
+0x9188	0x4168	0x4E89	# <CJK>
+0x9189	0x4169	0x75E9	# <CJK>
+0x918A	0x416A	0x76F8	# <CJK>
+0x918B	0x416B	0x7A93	# <CJK>
+0x918C	0x416C	0x7CDF	# <CJK>
+0x918D	0x416D	0x7DCF	# <CJK>
+0x918E	0x416E	0x7D9C	# <CJK>
+0x918F	0x416F	0x8061	# <CJK>
+0x9190	0x4170	0x8349	# <CJK>
+0x9191	0x4171	0x8358	# <CJK>
+0x9192	0x4172	0x846C	# <CJK>
+0x9193	0x4173	0x84BC	# <CJK>
+0x9194	0x4174	0x85FB	# <CJK>
+0x9195	0x4175	0x88C5	# <CJK>
+0x9196	0x4176	0x8D70	# <CJK>
+0x9197	0x4177	0x9001	# <CJK>
+0x9198	0x4178	0x906D	# <CJK>
+0x9199	0x4179	0x9397	# <CJK>
+0x919A	0x417A	0x971C	# <CJK>
+0x919B	0x417B	0x9A12	# <CJK>
+0x919C	0x417C	0x50CF	# <CJK>
+0x919D	0x417D	0x5897	# <CJK>
+0x919E	0x417E	0x618E	# <CJK>
+0x919F	0x4221	0x81D3	# <CJK>
+0x91A0	0x4222	0x8535	# <CJK>
+0x91A1	0x4223	0x8D08	# <CJK>
+0x91A2	0x4224	0x9020	# <CJK>
+0x91A3	0x4225	0x4FC3	# <CJK>
+0x91A4	0x4226	0x5074	# <CJK>
+0x91A5	0x4227	0x5247	# <CJK>
+0x91A6	0x4228	0x5373	# <CJK>
+0x91A7	0x4229	0x606F	# <CJK>
+0x91A8	0x422A	0x6349	# <CJK>
+0x91A9	0x422B	0x675F	# <CJK>
+0x91AA	0x422C	0x6E2C	# <CJK>
+0x91AB	0x422D	0x8DB3	# <CJK>
+0x91AC	0x422E	0x901F	# <CJK>
+0x91AD	0x422F	0x4FD7	# <CJK>
+0x91AE	0x4230	0x5C5E	# <CJK>
+0x91AF	0x4231	0x8CCA	# <CJK>
+0x91B0	0x4232	0x65CF	# <CJK>
+0x91B1	0x4233	0x7D9A	# <CJK>
+0x91B2	0x4234	0x5352	# <CJK>
+0x91B3	0x4235	0x8896	# <CJK>
+0x91B4	0x4236	0x5176	# <CJK>
+0x91B5	0x4237	0x63C3	# <CJK>
+0x91B6	0x4238	0x5B58	# <CJK>
+0x91B7	0x4239	0x5B6B	# <CJK>
+0x91B8	0x423A	0x5C0A	# <CJK>
+0x91B9	0x423B	0x640D	# <CJK>
+0x91BA	0x423C	0x6751	# <CJK>
+0x91BB	0x423D	0x905C	# <CJK>
+0x91BC	0x423E	0x4ED6	# <CJK>
+0x91BD	0x423F	0x591A	# <CJK>
+0x91BE	0x4240	0x592A	# <CJK>
+0x91BF	0x4241	0x6C70	# <CJK>
+0x91C0	0x4242	0x8A51	# <CJK>
+0x91C1	0x4243	0x553E	# <CJK>
+0x91C2	0x4244	0x5815	# <CJK>
+0x91C3	0x4245	0x59A5	# <CJK>
+0x91C4	0x4246	0x60F0	# <CJK>
+0x91C5	0x4247	0x6253	# <CJK>
+0x91C6	0x4248	0x67C1	# <CJK>
+0x91C7	0x4249	0x8235	# <CJK>
+0x91C8	0x424A	0x6955	# <CJK>
+0x91C9	0x424B	0x9640	# <CJK>
+0x91CA	0x424C	0x99C4	# <CJK>
+0x91CB	0x424D	0x9A28	# <CJK>
+0x91CC	0x424E	0x4F53	# <CJK>
+0x91CD	0x424F	0x5806	# <CJK>
+0x91CE	0x4250	0x5BFE	# <CJK>
+0x91CF	0x4251	0x8010	# <CJK>
+0x91D0	0x4252	0x5CB1	# <CJK>
+0x91D1	0x4253	0x5E2F	# <CJK>
+0x91D2	0x4254	0x5F85	# <CJK>
+0x91D3	0x4255	0x6020	# <CJK>
+0x91D4	0x4256	0x614B	# <CJK>
+0x91D5	0x4257	0x6234	# <CJK>
+0x91D6	0x4258	0x66FF	# <CJK>
+0x91D7	0x4259	0x6CF0	# <CJK>
+0x91D8	0x425A	0x6EDE	# <CJK>
+0x91D9	0x425B	0x80CE	# <CJK>
+0x91DA	0x425C	0x817F	# <CJK>
+0x91DB	0x425D	0x82D4	# <CJK>
+0x91DC	0x425E	0x888B	# <CJK>
+0x91DD	0x425F	0x8CB8	# <CJK>
+0x91DE	0x4260	0x9000	# <CJK>
+0x91DF	0x4261	0x902E	# <CJK>
+0x91E0	0x4262	0x968A	# <CJK>
+0x91E1	0x4263	0x9EDB	# <CJK>
+0x91E2	0x4264	0x9BDB	# <CJK>
+0x91E3	0x4265	0x4EE3	# <CJK>
+0x91E4	0x4266	0x53F0	# <CJK>
+0x91E5	0x4267	0x5927	# <CJK>
+0x91E6	0x4268	0x7B2C	# <CJK>
+0x91E7	0x4269	0x918D	# <CJK>
+0x91E8	0x426A	0x984C	# <CJK>
+0x91E9	0x426B	0x9DF9	# <CJK>
+0x91EA	0x426C	0x6EDD	# <CJK>
+0x91EB	0x426D	0x7027	# <CJK>
+0x91EC	0x426E	0x5353	# <CJK>
+0x91ED	0x426F	0x5544	# <CJK>
+0x91EE	0x4270	0x5B85	# <CJK>
+0x91EF	0x4271	0x6258	# <CJK>
+0x91F0	0x4272	0x629E	# <CJK>
+0x91F1	0x4273	0x62D3	# <CJK>
+0x91F2	0x4274	0x6CA2	# <CJK>
+0x91F3	0x4275	0x6FEF	# <CJK>
+0x91F4	0x4276	0x7422	# <CJK>
+0x91F5	0x4277	0x8A17	# <CJK>
+0x91F6	0x4278	0x9438	# <CJK>
+0x91F7	0x4279	0x6FC1	# <CJK>
+0x91F8	0x427A	0x8AFE	# <CJK>
+0x91F9	0x427B	0x8338	# <CJK>
+0x91FA	0x427C	0x51E7	# <CJK>
+0x91FB	0x427D	0x86F8	# <CJK>
+0x91FC	0x427E	0x53EA	# <CJK>
+0x9240	0x4321	0x53E9	# <CJK>
+0x9241	0x4322	0x4F46	# <CJK>
+0x9242	0x4323	0x9054	# <CJK>
+0x9243	0x4324	0x8FB0	# <CJK>
+0x9244	0x4325	0x596A	# <CJK>
+0x9245	0x4326	0x8131	# <CJK>
+0x9246	0x4327	0x5DFD	# <CJK>
+0x9247	0x4328	0x7AEA	# <CJK>
+0x9248	0x4329	0x8FBF	# <CJK>
+0x9249	0x432A	0x68DA	# <CJK>
+0x924A	0x432B	0x8C37	# <CJK>
+0x924B	0x432C	0x72F8	# <CJK>
+0x924C	0x432D	0x9C48	# <CJK>
+0x924D	0x432E	0x6A3D	# <CJK>
+0x924E	0x432F	0x8AB0	# <CJK>
+0x924F	0x4330	0x4E39	# <CJK>
+0x9250	0x4331	0x5358	# <CJK>
+0x9251	0x4332	0x5606	# <CJK>
+0x9252	0x4333	0x5766	# <CJK>
+0x9253	0x4334	0x62C5	# <CJK>
+0x9254	0x4335	0x63A2	# <CJK>
+0x9255	0x4336	0x65E6	# <CJK>
+0x9256	0x4337	0x6B4E	# <CJK>
+0x9257	0x4338	0x6DE1	# <CJK>
+0x9258	0x4339	0x6E5B	# <CJK>
+0x9259	0x433A	0x70AD	# <CJK>
+0x925A	0x433B	0x77ED	# <CJK>
+0x925B	0x433C	0x7AEF	# <CJK>
+0x925C	0x433D	0x7BAA	# <CJK>
+0x925D	0x433E	0x7DBB	# <CJK>
+0x925E	0x433F	0x803D	# <CJK>
+0x925F	0x4340	0x80C6	# <CJK>
+0x9260	0x4341	0x86CB	# <CJK>
+0x9261	0x4342	0x8A95	# <CJK>
+0x9262	0x4343	0x935B	# <CJK>
+0x9263	0x4344	0x56E3	# <CJK>
+0x9264	0x4345	0x58C7	# <CJK>
+0x9265	0x4346	0x5F3E	# <CJK>
+0x9266	0x4347	0x65AD	# <CJK>
+0x9267	0x4348	0x6696	# <CJK>
+0x9268	0x4349	0x6A80	# <CJK>
+0x9269	0x434A	0x6BB5	# <CJK>
+0x926A	0x434B	0x7537	# <CJK>
+0x926B	0x434C	0x8AC7	# <CJK>
+0x926C	0x434D	0x5024	# <CJK>
+0x926D	0x434E	0x77E5	# <CJK>
+0x926E	0x434F	0x5730	# <CJK>
+0x926F	0x4350	0x5F1B	# <CJK>
+0x9270	0x4351	0x6065	# <CJK>
+0x9271	0x4352	0x667A	# <CJK>
+0x9272	0x4353	0x6C60	# <CJK>
+0x9273	0x4354	0x75F4	# <CJK>
+0x9274	0x4355	0x7A1A	# <CJK>
+0x9275	0x4356	0x7F6E	# <CJK>
+0x9276	0x4357	0x81F4	# <CJK>
+0x9277	0x4358	0x8718	# <CJK>
+0x9278	0x4359	0x9045	# <CJK>
+0x9279	0x435A	0x99B3	# <CJK>
+0x927A	0x435B	0x7BC9	# <CJK>
+0x927B	0x435C	0x755C	# <CJK>
+0x927C	0x435D	0x7AF9	# <CJK>
+0x927D	0x435E	0x7B51	# <CJK>
+0x927E	0x435F	0x84C4	# <CJK>
+0x9280	0x4360	0x9010	# <CJK>
+0x9281	0x4361	0x79E9	# <CJK>
+0x9282	0x4362	0x7A92	# <CJK>
+0x9283	0x4363	0x8336	# <CJK>
+0x9284	0x4364	0x5AE1	# <CJK>
+0x9285	0x4365	0x7740	# <CJK>
+0x9286	0x4366	0x4E2D	# <CJK>
+0x9287	0x4367	0x4EF2	# <CJK>
+0x9288	0x4368	0x5B99	# <CJK>
+0x9289	0x4369	0x5FE0	# <CJK>
+0x928A	0x436A	0x62BD	# <CJK>
+0x928B	0x436B	0x663C	# <CJK>
+0x928C	0x436C	0x67F1	# <CJK>
+0x928D	0x436D	0x6CE8	# <CJK>
+0x928E	0x436E	0x866B	# <CJK>
+0x928F	0x436F	0x8877	# <CJK>
+0x9290	0x4370	0x8A3B	# <CJK>
+0x9291	0x4371	0x914E	# <CJK>
+0x9292	0x4372	0x92F3	# <CJK>
+0x9293	0x4373	0x99D0	# <CJK>
+0x9294	0x4374	0x6A17	# <CJK>
+0x9295	0x4375	0x7026	# <CJK>
+0x9296	0x4376	0x732A	# <CJK>
+0x9297	0x4377	0x82E7	# <CJK>
+0x9298	0x4378	0x8457	# <CJK>
+0x9299	0x4379	0x8CAF	# <CJK>
+0x929A	0x437A	0x4E01	# <CJK>
+0x929B	0x437B	0x5146	# <CJK>
+0x929C	0x437C	0x51CB	# <CJK>
+0x929D	0x437D	0x558B	# <CJK>
+0x929E	0x437E	0x5BF5	# <CJK>
+0x929F	0x4421	0x5E16	# <CJK>
+0x92A0	0x4422	0x5E33	# <CJK>
+0x92A1	0x4423	0x5E81	# <CJK>
+0x92A2	0x4424	0x5F14	# <CJK>
+0x92A3	0x4425	0x5F35	# <CJK>
+0x92A4	0x4426	0x5F6B	# <CJK>
+0x92A5	0x4427	0x5FB4	# <CJK>
+0x92A6	0x4428	0x61F2	# <CJK>
+0x92A7	0x4429	0x6311	# <CJK>
+0x92A8	0x442A	0x66A2	# <CJK>
+0x92A9	0x442B	0x671D	# <CJK>
+0x92AA	0x442C	0x6F6E	# <CJK>
+0x92AB	0x442D	0x7252	# <CJK>
+0x92AC	0x442E	0x753A	# <CJK>
+0x92AD	0x442F	0x773A	# <CJK>
+0x92AE	0x4430	0x8074	# <CJK>
+0x92AF	0x4431	0x8139	# <CJK>
+0x92B0	0x4432	0x8178	# <CJK>
+0x92B1	0x4433	0x8776	# <CJK>
+0x92B2	0x4434	0x8ABF	# <CJK>
+0x92B3	0x4435	0x8ADC	# <CJK>
+0x92B4	0x4436	0x8D85	# <CJK>
+0x92B5	0x4437	0x8DF3	# <CJK>
+0x92B6	0x4438	0x929A	# <CJK>
+0x92B7	0x4439	0x9577	# <CJK>
+0x92B8	0x443A	0x9802	# <CJK>
+0x92B9	0x443B	0x9CE5	# <CJK>
+0x92BA	0x443C	0x52C5	# <CJK>
+0x92BB	0x443D	0x6357	# <CJK>
+0x92BC	0x443E	0x76F4	# <CJK>
+0x92BD	0x443F	0x6715	# <CJK>
+0x92BE	0x4440	0x6C88	# <CJK>
+0x92BF	0x4441	0x73CD	# <CJK>
+0x92C0	0x4442	0x8CC3	# <CJK>
+0x92C1	0x4443	0x93AE	# <CJK>
+0x92C2	0x4444	0x9673	# <CJK>
+0x92C3	0x4445	0x6D25	# <CJK>
+0x92C4	0x4446	0x589C	# <CJK>
+0x92C5	0x4447	0x690E	# <CJK>
+0x92C6	0x4448	0x69CC	# <CJK>
+0x92C7	0x4449	0x8FFD	# <CJK>
+0x92C8	0x444A	0x939A	# <CJK>
+0x92C9	0x444B	0x75DB	# <CJK>
+0x92CA	0x444C	0x901A	# <CJK>
+0x92CB	0x444D	0x585A	# <CJK>
+0x92CC	0x444E	0x6802	# <CJK>
+0x92CD	0x444F	0x63B4	# <CJK>
+0x92CE	0x4450	0x69FB	# <CJK>
+0x92CF	0x4451	0x4F43	# <CJK>
+0x92D0	0x4452	0x6F2C	# <CJK>
+0x92D1	0x4453	0x67D8	# <CJK>
+0x92D2	0x4454	0x8FBB	# <CJK>
+0x92D3	0x4455	0x8526	# <CJK>
+0x92D4	0x4456	0x7DB4	# <CJK>
+0x92D5	0x4457	0x9354	# <CJK>
+0x92D6	0x4458	0x693F	# <CJK>
+0x92D7	0x4459	0x6F70	# <CJK>
+0x92D8	0x445A	0x576A	# <CJK>
+0x92D9	0x445B	0x58F7	# <CJK>
+0x92DA	0x445C	0x5B2C	# <CJK>
+0x92DB	0x445D	0x7D2C	# <CJK>
+0x92DC	0x445E	0x722A	# <CJK>
+0x92DD	0x445F	0x540A	# <CJK>
+0x92DE	0x4460	0x91E3	# <CJK>
+0x92DF	0x4461	0x9DB4	# <CJK>
+0x92E0	0x4462	0x4EAD	# <CJK>
+0x92E1	0x4463	0x4F4E	# <CJK>
+0x92E2	0x4464	0x505C	# <CJK>
+0x92E3	0x4465	0x5075	# <CJK>
+0x92E4	0x4466	0x5243	# <CJK>
+0x92E5	0x4467	0x8C9E	# <CJK>
+0x92E6	0x4468	0x5448	# <CJK>
+0x92E7	0x4469	0x5824	# <CJK>
+0x92E8	0x446A	0x5B9A	# <CJK>
+0x92E9	0x446B	0x5E1D	# <CJK>
+0x92EA	0x446C	0x5E95	# <CJK>
+0x92EB	0x446D	0x5EAD	# <CJK>
+0x92EC	0x446E	0x5EF7	# <CJK>
+0x92ED	0x446F	0x5F1F	# <CJK>
+0x92EE	0x4470	0x608C	# <CJK>
+0x92EF	0x4471	0x62B5	# <CJK>
+0x92F0	0x4472	0x633A	# <CJK>
+0x92F1	0x4473	0x63D0	# <CJK>
+0x92F2	0x4474	0x68AF	# <CJK>
+0x92F3	0x4475	0x6C40	# <CJK>
+0x92F4	0x4476	0x7887	# <CJK>
+0x92F5	0x4477	0x798E	# <CJK>
+0x92F6	0x4478	0x7A0B	# <CJK>
+0x92F7	0x4479	0x7DE0	# <CJK>
+0x92F8	0x447A	0x8247	# <CJK>
+0x92F9	0x447B	0x8A02	# <CJK>
+0x92FA	0x447C	0x8AE6	# <CJK>
+0x92FB	0x447D	0x8E44	# <CJK>
+0x92FC	0x447E	0x9013	# <CJK>
+0x9340	0x4521	0x90B8	# <CJK>
+0x9341	0x4522	0x912D	# <CJK>
+0x9342	0x4523	0x91D8	# <CJK>
+0x9343	0x4524	0x9F0E	# <CJK>
+0x9344	0x4525	0x6CE5	# <CJK>
+0x9345	0x4526	0x6458	# <CJK>
+0x9346	0x4527	0x64E2	# <CJK>
+0x9347	0x4528	0x6575	# <CJK>
+0x9348	0x4529	0x6EF4	# <CJK>
+0x9349	0x452A	0x7684	# <CJK>
+0x934A	0x452B	0x7B1B	# <CJK>
+0x934B	0x452C	0x9069	# <CJK>
+0x934C	0x452D	0x93D1	# <CJK>
+0x934D	0x452E	0x6EBA	# <CJK>
+0x934E	0x452F	0x54F2	# <CJK>
+0x934F	0x4530	0x5FB9	# <CJK>
+0x9350	0x4531	0x64A4	# <CJK>
+0x9351	0x4532	0x8F4D	# <CJK>
+0x9352	0x4533	0x8FED	# <CJK>
+0x9353	0x4534	0x9244	# <CJK>
+0x9354	0x4535	0x5178	# <CJK>
+0x9355	0x4536	0x586B	# <CJK>
+0x9356	0x4537	0x5929	# <CJK>
+0x9357	0x4538	0x5C55	# <CJK>
+0x9358	0x4539	0x5E97	# <CJK>
+0x9359	0x453A	0x6DFB	# <CJK>
+0x935A	0x453B	0x7E8F	# <CJK>
+0x935B	0x453C	0x751C	# <CJK>
+0x935C	0x453D	0x8CBC	# <CJK>
+0x935D	0x453E	0x8EE2	# <CJK>
+0x935E	0x453F	0x985B	# <CJK>
+0x935F	0x4540	0x70B9	# <CJK>
+0x9360	0x4541	0x4F1D	# <CJK>
+0x9361	0x4542	0x6BBF	# <CJK>
+0x9362	0x4543	0x6FB1	# <CJK>
+0x9363	0x4544	0x7530	# <CJK>
+0x9364	0x4545	0x96FB	# <CJK>
+0x9365	0x4546	0x514E	# <CJK>
+0x9366	0x4547	0x5410	# <CJK>
+0x9367	0x4548	0x5835	# <CJK>
+0x9368	0x4549	0x5857	# <CJK>
+0x9369	0x454A	0x59AC	# <CJK>
+0x936A	0x454B	0x5C60	# <CJK>
+0x936B	0x454C	0x5F92	# <CJK>
+0x936C	0x454D	0x6597	# <CJK>
+0x936D	0x454E	0x675C	# <CJK>
+0x936E	0x454F	0x6E21	# <CJK>
+0x936F	0x4550	0x767B	# <CJK>
+0x9370	0x4551	0x83DF	# <CJK>
+0x9371	0x4552	0x8CED	# <CJK>
+0x9372	0x4553	0x9014	# <CJK>
+0x9373	0x4554	0x90FD	# <CJK>
+0x9374	0x4555	0x934D	# <CJK>
+0x9375	0x4556	0x7825	# <CJK>
+0x9376	0x4557	0x783A	# <CJK>
+0x9377	0x4558	0x52AA	# <CJK>
+0x9378	0x4559	0x5EA6	# <CJK>
+0x9379	0x455A	0x571F	# <CJK>
+0x937A	0x455B	0x5974	# <CJK>
+0x937B	0x455C	0x6012	# <CJK>
+0x937C	0x455D	0x5012	# <CJK>
+0x937D	0x455E	0x515A	# <CJK>
+0x937E	0x455F	0x51AC	# <CJK>
+0x9380	0x4560	0x51CD	# <CJK>
+0x9381	0x4561	0x5200	# <CJK>
+0x9382	0x4562	0x5510	# <CJK>
+0x9383	0x4563	0x5854	# <CJK>
+0x9384	0x4564	0x5858	# <CJK>
+0x9385	0x4565	0x5957	# <CJK>
+0x9386	0x4566	0x5B95	# <CJK>
+0x9387	0x4567	0x5CF6	# <CJK>
+0x9388	0x4568	0x5D8B	# <CJK>
+0x9389	0x4569	0x60BC	# <CJK>
+0x938A	0x456A	0x6295	# <CJK>
+0x938B	0x456B	0x642D	# <CJK>
+0x938C	0x456C	0x6771	# <CJK>
+0x938D	0x456D	0x6843	# <CJK>
+0x938E	0x456E	0x68BC	# <CJK>
+0x938F	0x456F	0x68DF	# <CJK>
+0x9390	0x4570	0x76D7	# <CJK>
+0x9391	0x4571	0x6DD8	# <CJK>
+0x9392	0x4572	0x6E6F	# <CJK>
+0x9393	0x4573	0x6D9B	# <CJK>
+0x9394	0x4574	0x706F	# <CJK>
+0x9395	0x4575	0x71C8	# <CJK>
+0x9396	0x4576	0x5F53	# <CJK>
+0x9397	0x4577	0x75D8	# <CJK>
+0x9398	0x4578	0x7977	# <CJK>
+0x9399	0x4579	0x7B49	# <CJK>
+0x939A	0x457A	0x7B54	# <CJK>
+0x939B	0x457B	0x7B52	# <CJK>
+0x939C	0x457C	0x7CD6	# <CJK>
+0x939D	0x457D	0x7D71	# <CJK>
+0x939E	0x457E	0x5230	# <CJK>
+0x939F	0x4621	0x8463	# <CJK>
+0x93A0	0x4622	0x8569	# <CJK>
+0x93A1	0x4623	0x85E4	# <CJK>
+0x93A2	0x4624	0x8A0E	# <CJK>
+0x93A3	0x4625	0x8B04	# <CJK>
+0x93A4	0x4626	0x8C46	# <CJK>
+0x93A5	0x4627	0x8E0F	# <CJK>
+0x93A6	0x4628	0x9003	# <CJK>
+0x93A7	0x4629	0x900F	# <CJK>
+0x93A8	0x462A	0x9419	# <CJK>
+0x93A9	0x462B	0x9676	# <CJK>
+0x93AA	0x462C	0x982D	# <CJK>
+0x93AB	0x462D	0x9A30	# <CJK>
+0x93AC	0x462E	0x95D8	# <CJK>
+0x93AD	0x462F	0x50CD	# <CJK>
+0x93AE	0x4630	0x52D5	# <CJK>
+0x93AF	0x4631	0x540C	# <CJK>
+0x93B0	0x4632	0x5802	# <CJK>
+0x93B1	0x4633	0x5C0E	# <CJK>
+0x93B2	0x4634	0x61A7	# <CJK>
+0x93B3	0x4635	0x649E	# <CJK>
+0x93B4	0x4636	0x6D1E	# <CJK>
+0x93B5	0x4637	0x77B3	# <CJK>
+0x93B6	0x4638	0x7AE5	# <CJK>
+0x93B7	0x4639	0x80F4	# <CJK>
+0x93B8	0x463A	0x8404	# <CJK>
+0x93B9	0x463B	0x9053	# <CJK>
+0x93BA	0x463C	0x9285	# <CJK>
+0x93BB	0x463D	0x5CE0	# <CJK>
+0x93BC	0x463E	0x9D07	# <CJK>
+0x93BD	0x463F	0x533F	# <CJK>
+0x93BE	0x4640	0x5F97	# <CJK>
+0x93BF	0x4641	0x5FB3	# <CJK>
+0x93C0	0x4642	0x6D9C	# <CJK>
+0x93C1	0x4643	0x7279	# <CJK>
+0x93C2	0x4644	0x7763	# <CJK>
+0x93C3	0x4645	0x79BF	# <CJK>
+0x93C4	0x4646	0x7BE4	# <CJK>
+0x93C5	0x4647	0x6BD2	# <CJK>
+0x93C6	0x4648	0x72EC	# <CJK>
+0x93C7	0x4649	0x8AAD	# <CJK>
+0x93C8	0x464A	0x6803	# <CJK>
+0x93C9	0x464B	0x6A61	# <CJK>
+0x93CA	0x464C	0x51F8	# <CJK>
+0x93CB	0x464D	0x7A81	# <CJK>
+0x93CC	0x464E	0x6934	# <CJK>
+0x93CD	0x464F	0x5C4A	# <CJK>
+0x93CE	0x4650	0x9CF6	# <CJK>
+0x93CF	0x4651	0x82EB	# <CJK>
+0x93D0	0x4652	0x5BC5	# <CJK>
+0x93D1	0x4653	0x9149	# <CJK>
+0x93D2	0x4654	0x701E	# <CJK>
+0x93D3	0x4655	0x5678	# <CJK>
+0x93D4	0x4656	0x5C6F	# <CJK>
+0x93D5	0x4657	0x60C7	# <CJK>
+0x93D6	0x4658	0x6566	# <CJK>
+0x93D7	0x4659	0x6C8C	# <CJK>
+0x93D8	0x465A	0x8C5A	# <CJK>
+0x93D9	0x465B	0x9041	# <CJK>
+0x93DA	0x465C	0x9813	# <CJK>
+0x93DB	0x465D	0x5451	# <CJK>
+0x93DC	0x465E	0x66C7	# <CJK>
+0x93DD	0x465F	0x920D	# <CJK>
+0x93DE	0x4660	0x5948	# <CJK>
+0x93DF	0x4661	0x90A3	# <CJK>
+0x93E0	0x4662	0x5185	# <CJK>
+0x93E1	0x4663	0x4E4D	# <CJK>
+0x93E2	0x4664	0x51EA	# <CJK>
+0x93E3	0x4665	0x8599	# <CJK>
+0x93E4	0x4666	0x8B0E	# <CJK>
+0x93E5	0x4667	0x7058	# <CJK>
+0x93E6	0x4668	0x637A	# <CJK>
+0x93E7	0x4669	0x934B	# <CJK>
+0x93E8	0x466A	0x6962	# <CJK>
+0x93E9	0x466B	0x99B4	# <CJK>
+0x93EA	0x466C	0x7E04	# <CJK>
+0x93EB	0x466D	0x7577	# <CJK>
+0x93EC	0x466E	0x5357	# <CJK>
+0x93ED	0x466F	0x6960	# <CJK>
+0x93EE	0x4670	0x8EDF	# <CJK>
+0x93EF	0x4671	0x96E3	# <CJK>
+0x93F0	0x4672	0x6C5D	# <CJK>
+0x93F1	0x4673	0x4E8C	# <CJK>
+0x93F2	0x4674	0x5C3C	# <CJK>
+0x93F3	0x4675	0x5F10	# <CJK>
+0x93F4	0x4676	0x8FE9	# <CJK>
+0x93F5	0x4677	0x5302	# <CJK>
+0x93F6	0x4678	0x8CD1	# <CJK>
+0x93F7	0x4679	0x8089	# <CJK>
+0x93F8	0x467A	0x8679	# <CJK>
+0x93F9	0x467B	0x5EFF	# <CJK>
+0x93FA	0x467C	0x65E5	# <CJK>
+0x93FB	0x467D	0x4E73	# <CJK>
+0x93FC	0x467E	0x5165	# <CJK>
+0x9440	0x4721	0x5982	# <CJK>
+0x9441	0x4722	0x5C3F	# <CJK>
+0x9442	0x4723	0x97EE	# <CJK>
+0x9443	0x4724	0x4EFB	# <CJK>
+0x9444	0x4725	0x598A	# <CJK>
+0x9445	0x4726	0x5FCD	# <CJK>
+0x9446	0x4727	0x8A8D	# <CJK>
+0x9447	0x4728	0x6FE1	# <CJK>
+0x9448	0x4729	0x79B0	# <CJK>
+0x9449	0x472A	0x7962	# <CJK>
+0x944A	0x472B	0x5BE7	# <CJK>
+0x944B	0x472C	0x8471	# <CJK>
+0x944C	0x472D	0x732B	# <CJK>
+0x944D	0x472E	0x71B1	# <CJK>
+0x944E	0x472F	0x5E74	# <CJK>
+0x944F	0x4730	0x5FF5	# <CJK>
+0x9450	0x4731	0x637B	# <CJK>
+0x9451	0x4732	0x649A	# <CJK>
+0x9452	0x4733	0x71C3	# <CJK>
+0x9453	0x4734	0x7C98	# <CJK>
+0x9454	0x4735	0x4E43	# <CJK>
+0x9455	0x4736	0x5EFC	# <CJK>
+0x9456	0x4737	0x4E4B	# <CJK>
+0x9457	0x4738	0x57DC	# <CJK>
+0x9458	0x4739	0x56A2	# <CJK>
+0x9459	0x473A	0x60A9	# <CJK>
+0x945A	0x473B	0x6FC3	# <CJK>
+0x945B	0x473C	0x7D0D	# <CJK>
+0x945C	0x473D	0x80FD	# <CJK>
+0x945D	0x473E	0x8133	# <CJK>
+0x945E	0x473F	0x81BF	# <CJK>
+0x945F	0x4740	0x8FB2	# <CJK>
+0x9460	0x4741	0x8997	# <CJK>
+0x9461	0x4742	0x86A4	# <CJK>
+0x9462	0x4743	0x5DF4	# <CJK>
+0x9463	0x4744	0x628A	# <CJK>
+0x9464	0x4745	0x64AD	# <CJK>
+0x9465	0x4746	0x8987	# <CJK>
+0x9466	0x4747	0x6777	# <CJK>
+0x9467	0x4748	0x6CE2	# <CJK>
+0x9468	0x4749	0x6D3E	# <CJK>
+0x9469	0x474A	0x7436	# <CJK>
+0x946A	0x474B	0x7834	# <CJK>
+0x946B	0x474C	0x5A46	# <CJK>
+0x946C	0x474D	0x7F75	# <CJK>
+0x946D	0x474E	0x82AD	# <CJK>
+0x946E	0x474F	0x99AC	# <CJK>
+0x946F	0x4750	0x4FF3	# <CJK>
+0x9470	0x4751	0x5EC3	# <CJK>
+0x9471	0x4752	0x62DD	# <CJK>
+0x9472	0x4753	0x6392	# <CJK>
+0x9473	0x4754	0x6557	# <CJK>
+0x9474	0x4755	0x676F	# <CJK>
+0x9475	0x4756	0x76C3	# <CJK>
+0x9476	0x4757	0x724C	# <CJK>
+0x9477	0x4758	0x80CC	# <CJK>
+0x9478	0x4759	0x80BA	# <CJK>
+0x9479	0x475A	0x8F29	# <CJK>
+0x947A	0x475B	0x914D	# <CJK>
+0x947B	0x475C	0x500D	# <CJK>
+0x947C	0x475D	0x57F9	# <CJK>
+0x947D	0x475E	0x5A92	# <CJK>
+0x947E	0x475F	0x6885	# <CJK>
+0x9480	0x4760	0x6973	# <CJK>
+0x9481	0x4761	0x7164	# <CJK>
+0x9482	0x4762	0x72FD	# <CJK>
+0x9483	0x4763	0x8CB7	# <CJK>
+0x9484	0x4764	0x58F2	# <CJK>
+0x9485	0x4765	0x8CE0	# <CJK>
+0x9486	0x4766	0x966A	# <CJK>
+0x9487	0x4767	0x9019	# <CJK>
+0x9488	0x4768	0x877F	# <CJK>
+0x9489	0x4769	0x79E4	# <CJK>
+0x948A	0x476A	0x77E7	# <CJK>
+0x948B	0x476B	0x8429	# <CJK>
+0x948C	0x476C	0x4F2F	# <CJK>
+0x948D	0x476D	0x5265	# <CJK>
+0x948E	0x476E	0x535A	# <CJK>
+0x948F	0x476F	0x62CD	# <CJK>
+0x9490	0x4770	0x67CF	# <CJK>
+0x9491	0x4771	0x6CCA	# <CJK>
+0x9492	0x4772	0x767D	# <CJK>
+0x9493	0x4773	0x7B94	# <CJK>
+0x9494	0x4774	0x7C95	# <CJK>
+0x9495	0x4775	0x8236	# <CJK>
+0x9496	0x4776	0x8584	# <CJK>
+0x9497	0x4777	0x8FEB	# <CJK>
+0x9498	0x4778	0x66DD	# <CJK>
+0x9499	0x4779	0x6F20	# <CJK>
+0x949A	0x477A	0x7206	# <CJK>
+0x949B	0x477B	0x7E1B	# <CJK>
+0x949C	0x477C	0x83AB	# <CJK>
+0x949D	0x477D	0x99C1	# <CJK>
+0x949E	0x477E	0x9EA6	# <CJK>
+0x949F	0x4821	0x51FD	# <CJK>
+0x94A0	0x4822	0x7BB1	# <CJK>
+0x94A1	0x4823	0x7872	# <CJK>
+0x94A2	0x4824	0x7BB8	# <CJK>
+0x94A3	0x4825	0x8087	# <CJK>
+0x94A4	0x4826	0x7B48	# <CJK>
+0x94A5	0x4827	0x6AE8	# <CJK>
+0x94A6	0x4828	0x5E61	# <CJK>
+0x94A7	0x4829	0x808C	# <CJK>
+0x94A8	0x482A	0x7551	# <CJK>
+0x94A9	0x482B	0x7560	# <CJK>
+0x94AA	0x482C	0x516B	# <CJK>
+0x94AB	0x482D	0x9262	# <CJK>
+0x94AC	0x482E	0x6E8C	# <CJK>
+0x94AD	0x482F	0x767A	# <CJK>
+0x94AE	0x4830	0x9197	# <CJK>
+0x94AF	0x4831	0x9AEA	# <CJK>
+0x94B0	0x4832	0x4F10	# <CJK>
+0x94B1	0x4833	0x7F70	# <CJK>
+0x94B2	0x4834	0x629C	# <CJK>
+0x94B3	0x4835	0x7B4F	# <CJK>
+0x94B4	0x4836	0x95A5	# <CJK>
+0x94B5	0x4837	0x9CE9	# <CJK>
+0x94B6	0x4838	0x567A	# <CJK>
+0x94B7	0x4839	0x5859	# <CJK>
+0x94B8	0x483A	0x86E4	# <CJK>
+0x94B9	0x483B	0x96BC	# <CJK>
+0x94BA	0x483C	0x4F34	# <CJK>
+0x94BB	0x483D	0x5224	# <CJK>
+0x94BC	0x483E	0x534A	# <CJK>
+0x94BD	0x483F	0x53CD	# <CJK>
+0x94BE	0x4840	0x53DB	# <CJK>
+0x94BF	0x4841	0x5E06	# <CJK>
+0x94C0	0x4842	0x642C	# <CJK>
+0x94C1	0x4843	0x6591	# <CJK>
+0x94C2	0x4844	0x677F	# <CJK>
+0x94C3	0x4845	0x6C3E	# <CJK>
+0x94C4	0x4846	0x6C4E	# <CJK>
+0x94C5	0x4847	0x7248	# <CJK>
+0x94C6	0x4848	0x72AF	# <CJK>
+0x94C7	0x4849	0x73ED	# <CJK>
+0x94C8	0x484A	0x7554	# <CJK>
+0x94C9	0x484B	0x7E41	# <CJK>
+0x94CA	0x484C	0x822C	# <CJK>
+0x94CB	0x484D	0x85E9	# <CJK>
+0x94CC	0x484E	0x8CA9	# <CJK>
+0x94CD	0x484F	0x7BC4	# <CJK>
+0x94CE	0x4850	0x91C6	# <CJK>
+0x94CF	0x4851	0x7169	# <CJK>
+0x94D0	0x4852	0x9812	# <CJK>
+0x94D1	0x4853	0x98EF	# <CJK>
+0x94D2	0x4854	0x633D	# <CJK>
+0x94D3	0x4855	0x6669	# <CJK>
+0x94D4	0x4856	0x756A	# <CJK>
+0x94D5	0x4857	0x76E4	# <CJK>
+0x94D6	0x4858	0x78D0	# <CJK>
+0x94D7	0x4859	0x8543	# <CJK>
+0x94D8	0x485A	0x86EE	# <CJK>
+0x94D9	0x485B	0x532A	# <CJK>
+0x94DA	0x485C	0x5351	# <CJK>
+0x94DB	0x485D	0x5426	# <CJK>
+0x94DC	0x485E	0x5983	# <CJK>
+0x94DD	0x485F	0x5E87	# <CJK>
+0x94DE	0x4860	0x5F7C	# <CJK>
+0x94DF	0x4861	0x60B2	# <CJK>
+0x94E0	0x4862	0x6249	# <CJK>
+0x94E1	0x4863	0x6279	# <CJK>
+0x94E2	0x4864	0x62AB	# <CJK>
+0x94E3	0x4865	0x6590	# <CJK>
+0x94E4	0x4866	0x6BD4	# <CJK>
+0x94E5	0x4867	0x6CCC	# <CJK>
+0x94E6	0x4868	0x75B2	# <CJK>
+0x94E7	0x4869	0x76AE	# <CJK>
+0x94E8	0x486A	0x7891	# <CJK>
+0x94E9	0x486B	0x79D8	# <CJK>
+0x94EA	0x486C	0x7DCB	# <CJK>
+0x94EB	0x486D	0x7F77	# <CJK>
+0x94EC	0x486E	0x80A5	# <CJK>
+0x94ED	0x486F	0x88AB	# <CJK>
+0x94EE	0x4870	0x8AB9	# <CJK>
+0x94EF	0x4871	0x8CBB	# <CJK>
+0x94F0	0x4872	0x907F	# <CJK>
+0x94F1	0x4873	0x975E	# <CJK>
+0x94F2	0x4874	0x98DB	# <CJK>
+0x94F3	0x4875	0x6A0B	# <CJK>
+0x94F4	0x4876	0x7C38	# <CJK>
+0x94F5	0x4877	0x5099	# <CJK>
+0x94F6	0x4878	0x5C3E	# <CJK>
+0x94F7	0x4879	0x5FAE	# <CJK>
+0x94F8	0x487A	0x6787	# <CJK>
+0x94F9	0x487B	0x6BD8	# <CJK>
+0x94FA	0x487C	0x7435	# <CJK>
+0x94FB	0x487D	0x7709	# <CJK>
+0x94FC	0x487E	0x7F8E	# <CJK>
+0x9540	0x4921	0x9F3B	# <CJK>
+0x9541	0x4922	0x67CA	# <CJK>
+0x9542	0x4923	0x7A17	# <CJK>
+0x9543	0x4924	0x5339	# <CJK>
+0x9544	0x4925	0x758B	# <CJK>
+0x9545	0x4926	0x9AED	# <CJK>
+0x9546	0x4927	0x5F66	# <CJK>
+0x9547	0x4928	0x819D	# <CJK>
+0x9548	0x4929	0x83F1	# <CJK>
+0x9549	0x492A	0x8098	# <CJK>
+0x954A	0x492B	0x5F3C	# <CJK>
+0x954B	0x492C	0x5FC5	# <CJK>
+0x954C	0x492D	0x7562	# <CJK>
+0x954D	0x492E	0x7B46	# <CJK>
+0x954E	0x492F	0x903C	# <CJK>
+0x954F	0x4930	0x6867	# <CJK>
+0x9550	0x4931	0x59EB	# <CJK>
+0x9551	0x4932	0x5A9B	# <CJK>
+0x9552	0x4933	0x7D10	# <CJK>
+0x9553	0x4934	0x767E	# <CJK>
+0x9554	0x4935	0x8B2C	# <CJK>
+0x9555	0x4936	0x4FF5	# <CJK>
+0x9556	0x4937	0x5F6A	# <CJK>
+0x9557	0x4938	0x6A19	# <CJK>
+0x9558	0x4939	0x6C37	# <CJK>
+0x9559	0x493A	0x6F02	# <CJK>
+0x955A	0x493B	0x74E2	# <CJK>
+0x955B	0x493C	0x7968	# <CJK>
+0x955C	0x493D	0x8868	# <CJK>
+0x955D	0x493E	0x8A55	# <CJK>
+0x955E	0x493F	0x8C79	# <CJK>
+0x955F	0x4940	0x5EDF	# <CJK>
+0x9560	0x4941	0x63CF	# <CJK>
+0x9561	0x4942	0x75C5	# <CJK>
+0x9562	0x4943	0x79D2	# <CJK>
+0x9563	0x4944	0x82D7	# <CJK>
+0x9564	0x4945	0x9328	# <CJK>
+0x9565	0x4946	0x92F2	# <CJK>
+0x9566	0x4947	0x849C	# <CJK>
+0x9567	0x4948	0x86ED	# <CJK>
+0x9568	0x4949	0x9C2D	# <CJK>
+0x9569	0x494A	0x54C1	# <CJK>
+0x956A	0x494B	0x5F6C	# <CJK>
+0x956B	0x494C	0x658C	# <CJK>
+0x956C	0x494D	0x6D5C	# <CJK>
+0x956D	0x494E	0x7015	# <CJK>
+0x956E	0x494F	0x8CA7	# <CJK>
+0x956F	0x4950	0x8CD3	# <CJK>
+0x9570	0x4951	0x983B	# <CJK>
+0x9571	0x4952	0x654F	# <CJK>
+0x9572	0x4953	0x74F6	# <CJK>
+0x9573	0x4954	0x4E0D	# <CJK>
+0x9574	0x4955	0x4ED8	# <CJK>
+0x9575	0x4956	0x57E0	# <CJK>
+0x9576	0x4957	0x592B	# <CJK>
+0x9577	0x4958	0x5A66	# <CJK>
+0x9578	0x4959	0x5BCC	# <CJK>
+0x9579	0x495A	0x51A8	# <CJK>
+0x957A	0x495B	0x5E03	# <CJK>
+0x957B	0x495C	0x5E9C	# <CJK>
+0x957C	0x495D	0x6016	# <CJK>
+0x957D	0x495E	0x6276	# <CJK>
+0x957E	0x495F	0x6577	# <CJK>
+0x9580	0x4960	0x65A7	# <CJK>
+0x9581	0x4961	0x666E	# <CJK>
+0x9582	0x4962	0x6D6E	# <CJK>
+0x9583	0x4963	0x7236	# <CJK>
+0x9584	0x4964	0x7B26	# <CJK>
+0x9585	0x4965	0x8150	# <CJK>
+0x9586	0x4966	0x819A	# <CJK>
+0x9587	0x4967	0x8299	# <CJK>
+0x9588	0x4968	0x8B5C	# <CJK>
+0x9589	0x4969	0x8CA0	# <CJK>
+0x958A	0x496A	0x8CE6	# <CJK>
+0x958B	0x496B	0x8D74	# <CJK>
+0x958C	0x496C	0x961C	# <CJK>
+0x958D	0x496D	0x9644	# <CJK>
+0x958E	0x496E	0x4FAE	# <CJK>
+0x958F	0x496F	0x64AB	# <CJK>
+0x9590	0x4970	0x6B66	# <CJK>
+0x9591	0x4971	0x821E	# <CJK>
+0x9592	0x4972	0x8461	# <CJK>
+0x9593	0x4973	0x856A	# <CJK>
+0x9594	0x4974	0x90E8	# <CJK>
+0x9595	0x4975	0x5C01	# <CJK>
+0x9596	0x4976	0x6953	# <CJK>
+0x9597	0x4977	0x98A8	# <CJK>
+0x9598	0x4978	0x847A	# <CJK>
+0x9599	0x4979	0x8557	# <CJK>
+0x959A	0x497A	0x4F0F	# <CJK>
+0x959B	0x497B	0x526F	# <CJK>
+0x959C	0x497C	0x5FA9	# <CJK>
+0x959D	0x497D	0x5E45	# <CJK>
+0x959E	0x497E	0x670D	# <CJK>
+0x959F	0x4A21	0x798F	# <CJK>
+0x95A0	0x4A22	0x8179	# <CJK>
+0x95A1	0x4A23	0x8907	# <CJK>
+0x95A2	0x4A24	0x8986	# <CJK>
+0x95A3	0x4A25	0x6DF5	# <CJK>
+0x95A4	0x4A26	0x5F17	# <CJK>
+0x95A5	0x4A27	0x6255	# <CJK>
+0x95A6	0x4A28	0x6CB8	# <CJK>
+0x95A7	0x4A29	0x4ECF	# <CJK>
+0x95A8	0x4A2A	0x7269	# <CJK>
+0x95A9	0x4A2B	0x9B92	# <CJK>
+0x95AA	0x4A2C	0x5206	# <CJK>
+0x95AB	0x4A2D	0x543B	# <CJK>
+0x95AC	0x4A2E	0x5674	# <CJK>
+0x95AD	0x4A2F	0x58B3	# <CJK>
+0x95AE	0x4A30	0x61A4	# <CJK>
+0x95AF	0x4A31	0x626E	# <CJK>
+0x95B0	0x4A32	0x711A	# <CJK>
+0x95B1	0x4A33	0x596E	# <CJK>
+0x95B2	0x4A34	0x7C89	# <CJK>
+0x95B3	0x4A35	0x7CDE	# <CJK>
+0x95B4	0x4A36	0x7D1B	# <CJK>
+0x95B5	0x4A37	0x96F0	# <CJK>
+0x95B6	0x4A38	0x6587	# <CJK>
+0x95B7	0x4A39	0x805E	# <CJK>
+0x95B8	0x4A3A	0x4E19	# <CJK>
+0x95B9	0x4A3B	0x4F75	# <CJK>
+0x95BA	0x4A3C	0x5175	# <CJK>
+0x95BB	0x4A3D	0x5840	# <CJK>
+0x95BC	0x4A3E	0x5E63	# <CJK>
+0x95BD	0x4A3F	0x5E73	# <CJK>
+0x95BE	0x4A40	0x5F0A	# <CJK>
+0x95BF	0x4A41	0x67C4	# <CJK>
+0x95C0	0x4A42	0x4E26	# <CJK>
+0x95C1	0x4A43	0x853D	# <CJK>
+0x95C2	0x4A44	0x9589	# <CJK>
+0x95C3	0x4A45	0x965B	# <CJK>
+0x95C4	0x4A46	0x7C73	# <CJK>
+0x95C5	0x4A47	0x9801	# <CJK>
+0x95C6	0x4A48	0x50FB	# <CJK>
+0x95C7	0x4A49	0x58C1	# <CJK>
+0x95C8	0x4A4A	0x7656	# <CJK>
+0x95C9	0x4A4B	0x78A7	# <CJK>
+0x95CA	0x4A4C	0x5225	# <CJK>
+0x95CB	0x4A4D	0x77A5	# <CJK>
+0x95CC	0x4A4E	0x8511	# <CJK>
+0x95CD	0x4A4F	0x7B86	# <CJK>
+0x95CE	0x4A50	0x504F	# <CJK>
+0x95CF	0x4A51	0x5909	# <CJK>
+0x95D0	0x4A52	0x7247	# <CJK>
+0x95D1	0x4A53	0x7BC7	# <CJK>
+0x95D2	0x4A54	0x7DE8	# <CJK>
+0x95D3	0x4A55	0x8FBA	# <CJK>
+0x95D4	0x4A56	0x8FD4	# <CJK>
+0x95D5	0x4A57	0x904D	# <CJK>
+0x95D6	0x4A58	0x4FBF	# <CJK>
+0x95D7	0x4A59	0x52C9	# <CJK>
+0x95D8	0x4A5A	0x5A29	# <CJK>
+0x95D9	0x4A5B	0x5F01	# <CJK>
+0x95DA	0x4A5C	0x97AD	# <CJK>
+0x95DB	0x4A5D	0x4FDD	# <CJK>
+0x95DC	0x4A5E	0x8217	# <CJK>
+0x95DD	0x4A5F	0x92EA	# <CJK>
+0x95DE	0x4A60	0x5703	# <CJK>
+0x95DF	0x4A61	0x6355	# <CJK>
+0x95E0	0x4A62	0x6B69	# <CJK>
+0x95E1	0x4A63	0x752B	# <CJK>
+0x95E2	0x4A64	0x88DC	# <CJK>
+0x95E3	0x4A65	0x8F14	# <CJK>
+0x95E4	0x4A66	0x7A42	# <CJK>
+0x95E5	0x4A67	0x52DF	# <CJK>
+0x95E6	0x4A68	0x5893	# <CJK>
+0x95E7	0x4A69	0x6155	# <CJK>
+0x95E8	0x4A6A	0x620A	# <CJK>
+0x95E9	0x4A6B	0x66AE	# <CJK>
+0x95EA	0x4A6C	0x6BCD	# <CJK>
+0x95EB	0x4A6D	0x7C3F	# <CJK>
+0x95EC	0x4A6E	0x83E9	# <CJK>
+0x95ED	0x4A6F	0x5023	# <CJK>
+0x95EE	0x4A70	0x4FF8	# <CJK>
+0x95EF	0x4A71	0x5305	# <CJK>
+0x95F0	0x4A72	0x5446	# <CJK>
+0x95F1	0x4A73	0x5831	# <CJK>
+0x95F2	0x4A74	0x5949	# <CJK>
+0x95F3	0x4A75	0x5B9D	# <CJK>
+0x95F4	0x4A76	0x5CF0	# <CJK>
+0x95F5	0x4A77	0x5CEF	# <CJK>
+0x95F6	0x4A78	0x5D29	# <CJK>
+0x95F7	0x4A79	0x5E96	# <CJK>
+0x95F8	0x4A7A	0x62B1	# <CJK>
+0x95F9	0x4A7B	0x6367	# <CJK>
+0x95FA	0x4A7C	0x653E	# <CJK>
+0x95FB	0x4A7D	0x65B9	# <CJK>
+0x95FC	0x4A7E	0x670B	# <CJK>
+0x9640	0x4B21	0x6CD5	# <CJK>
+0x9641	0x4B22	0x6CE1	# <CJK>
+0x9642	0x4B23	0x70F9	# <CJK>
+0x9643	0x4B24	0x7832	# <CJK>
+0x9644	0x4B25	0x7E2B	# <CJK>
+0x9645	0x4B26	0x80DE	# <CJK>
+0x9646	0x4B27	0x82B3	# <CJK>
+0x9647	0x4B28	0x840C	# <CJK>
+0x9648	0x4B29	0x84EC	# <CJK>
+0x9649	0x4B2A	0x8702	# <CJK>
+0x964A	0x4B2B	0x8912	# <CJK>
+0x964B	0x4B2C	0x8A2A	# <CJK>
+0x964C	0x4B2D	0x8C4A	# <CJK>
+0x964D	0x4B2E	0x90A6	# <CJK>
+0x964E	0x4B2F	0x92D2	# <CJK>
+0x964F	0x4B30	0x98FD	# <CJK>
+0x9650	0x4B31	0x9CF3	# <CJK>
+0x9651	0x4B32	0x9D6C	# <CJK>
+0x9652	0x4B33	0x4E4F	# <CJK>
+0x9653	0x4B34	0x4EA1	# <CJK>
+0x9654	0x4B35	0x508D	# <CJK>
+0x9655	0x4B36	0x5256	# <CJK>
+0x9656	0x4B37	0x574A	# <CJK>
+0x9657	0x4B38	0x59A8	# <CJK>
+0x9658	0x4B39	0x5E3D	# <CJK>
+0x9659	0x4B3A	0x5FD8	# <CJK>
+0x965A	0x4B3B	0x5FD9	# <CJK>
+0x965B	0x4B3C	0x623F	# <CJK>
+0x965C	0x4B3D	0x66B4	# <CJK>
+0x965D	0x4B3E	0x671B	# <CJK>
+0x965E	0x4B3F	0x67D0	# <CJK>
+0x965F	0x4B40	0x68D2	# <CJK>
+0x9660	0x4B41	0x5192	# <CJK>
+0x9661	0x4B42	0x7D21	# <CJK>
+0x9662	0x4B43	0x80AA	# <CJK>
+0x9663	0x4B44	0x81A8	# <CJK>
+0x9664	0x4B45	0x8B00	# <CJK>
+0x9665	0x4B46	0x8C8C	# <CJK>
+0x9666	0x4B47	0x8CBF	# <CJK>
+0x9667	0x4B48	0x927E	# <CJK>
+0x9668	0x4B49	0x9632	# <CJK>
+0x9669	0x4B4A	0x5420	# <CJK>
+0x966A	0x4B4B	0x982C	# <CJK>
+0x966B	0x4B4C	0x5317	# <CJK>
+0x966C	0x4B4D	0x50D5	# <CJK>
+0x966D	0x4B4E	0x535C	# <CJK>
+0x966E	0x4B4F	0x58A8	# <CJK>
+0x966F	0x4B50	0x64B2	# <CJK>
+0x9670	0x4B51	0x6734	# <CJK>
+0x9671	0x4B52	0x7267	# <CJK>
+0x9672	0x4B53	0x7766	# <CJK>
+0x9673	0x4B54	0x7A46	# <CJK>
+0x9674	0x4B55	0x91E6	# <CJK>
+0x9675	0x4B56	0x52C3	# <CJK>
+0x9676	0x4B57	0x6CA1	# <CJK>
+0x9677	0x4B58	0x6B86	# <CJK>
+0x9678	0x4B59	0x5800	# <CJK>
+0x9679	0x4B5A	0x5E4C	# <CJK>
+0x967A	0x4B5B	0x5954	# <CJK>
+0x967B	0x4B5C	0x672C	# <CJK>
+0x967C	0x4B5D	0x7FFB	# <CJK>
+0x967D	0x4B5E	0x51E1	# <CJK>
+0x967E	0x4B5F	0x76C6	# <CJK>
+0x9680	0x4B60	0x6469	# <CJK>
+0x9681	0x4B61	0x78E8	# <CJK>
+0x9682	0x4B62	0x9B54	# <CJK>
+0x9683	0x4B63	0x9EBB	# <CJK>
+0x9684	0x4B64	0x57CB	# <CJK>
+0x9685	0x4B65	0x59B9	# <CJK>
+0x9686	0x4B66	0x6627	# <CJK>
+0x9687	0x4B67	0x679A	# <CJK>
+0x9688	0x4B68	0x6BCE	# <CJK>
+0x9689	0x4B69	0x54E9	# <CJK>
+0x968A	0x4B6A	0x69D9	# <CJK>
+0x968B	0x4B6B	0x5E55	# <CJK>
+0x968C	0x4B6C	0x819C	# <CJK>
+0x968D	0x4B6D	0x6795	# <CJK>
+0x968E	0x4B6E	0x9BAA	# <CJK>
+0x968F	0x4B6F	0x67FE	# <CJK>
+0x9690	0x4B70	0x9C52	# <CJK>
+0x9691	0x4B71	0x685D	# <CJK>
+0x9692	0x4B72	0x4EA6	# <CJK>
+0x9693	0x4B73	0x4FE3	# <CJK>
+0x9694	0x4B74	0x53C8	# <CJK>
+0x9695	0x4B75	0x62B9	# <CJK>
+0x9696	0x4B76	0x672B	# <CJK>
+0x9697	0x4B77	0x6CAB	# <CJK>
+0x9698	0x4B78	0x8FC4	# <CJK>
+0x9699	0x4B79	0x4FAD	# <CJK>
+0x969A	0x4B7A	0x7E6D	# <CJK>
+0x969B	0x4B7B	0x9EBF	# <CJK>
+0x969C	0x4B7C	0x4E07	# <CJK>
+0x969D	0x4B7D	0x6162	# <CJK>
+0x969E	0x4B7E	0x6E80	# <CJK>
+0x969F	0x4C21	0x6F2B	# <CJK>
+0x96A0	0x4C22	0x8513	# <CJK>
+0x96A1	0x4C23	0x5473	# <CJK>
+0x96A2	0x4C24	0x672A	# <CJK>
+0x96A3	0x4C25	0x9B45	# <CJK>
+0x96A4	0x4C26	0x5DF3	# <CJK>
+0x96A5	0x4C27	0x7B95	# <CJK>
+0x96A6	0x4C28	0x5CAC	# <CJK>
+0x96A7	0x4C29	0x5BC6	# <CJK>
+0x96A8	0x4C2A	0x871C	# <CJK>
+0x96A9	0x4C2B	0x6E4A	# <CJK>
+0x96AA	0x4C2C	0x84D1	# <CJK>
+0x96AB	0x4C2D	0x7A14	# <CJK>
+0x96AC	0x4C2E	0x8108	# <CJK>
+0x96AD	0x4C2F	0x5999	# <CJK>
+0x96AE	0x4C30	0x7C8D	# <CJK>
+0x96AF	0x4C31	0x6C11	# <CJK>
+0x96B0	0x4C32	0x7720	# <CJK>
+0x96B1	0x4C33	0x52D9	# <CJK>
+0x96B2	0x4C34	0x5922	# <CJK>
+0x96B3	0x4C35	0x7121	# <CJK>
+0x96B4	0x4C36	0x725F	# <CJK>
+0x96B5	0x4C37	0x77DB	# <CJK>
+0x96B6	0x4C38	0x9727	# <CJK>
+0x96B7	0x4C39	0x9D61	# <CJK>
+0x96B8	0x4C3A	0x690B	# <CJK>
+0x96B9	0x4C3B	0x5A7F	# <CJK>
+0x96BA	0x4C3C	0x5A18	# <CJK>
+0x96BB	0x4C3D	0x51A5	# <CJK>
+0x96BC	0x4C3E	0x540D	# <CJK>
+0x96BD	0x4C3F	0x547D	# <CJK>
+0x96BE	0x4C40	0x660E	# <CJK>
+0x96BF	0x4C41	0x76DF	# <CJK>
+0x96C0	0x4C42	0x8FF7	# <CJK>
+0x96C1	0x4C43	0x9298	# <CJK>
+0x96C2	0x4C44	0x9CF4	# <CJK>
+0x96C3	0x4C45	0x59EA	# <CJK>
+0x96C4	0x4C46	0x725D	# <CJK>
+0x96C5	0x4C47	0x6EC5	# <CJK>
+0x96C6	0x4C48	0x514D	# <CJK>
+0x96C7	0x4C49	0x68C9	# <CJK>
+0x96C8	0x4C4A	0x7DBF	# <CJK>
+0x96C9	0x4C4B	0x7DEC	# <CJK>
+0x96CA	0x4C4C	0x9762	# <CJK>
+0x96CB	0x4C4D	0x9EBA	# <CJK>
+0x96CC	0x4C4E	0x6478	# <CJK>
+0x96CD	0x4C4F	0x6A21	# <CJK>
+0x96CE	0x4C50	0x8302	# <CJK>
+0x96CF	0x4C51	0x5984	# <CJK>
+0x96D0	0x4C52	0x5B5F	# <CJK>
+0x96D1	0x4C53	0x6BDB	# <CJK>
+0x96D2	0x4C54	0x731B	# <CJK>
+0x96D3	0x4C55	0x76F2	# <CJK>
+0x96D4	0x4C56	0x7DB2	# <CJK>
+0x96D5	0x4C57	0x8017	# <CJK>
+0x96D6	0x4C58	0x8499	# <CJK>
+0x96D7	0x4C59	0x5132	# <CJK>
+0x96D8	0x4C5A	0x6728	# <CJK>
+0x96D9	0x4C5B	0x9ED9	# <CJK>
+0x96DA	0x4C5C	0x76EE	# <CJK>
+0x96DB	0x4C5D	0x6762	# <CJK>
+0x96DC	0x4C5E	0x52FF	# <CJK>
+0x96DD	0x4C5F	0x9905	# <CJK>
+0x96DE	0x4C60	0x5C24	# <CJK>
+0x96DF	0x4C61	0x623B	# <CJK>
+0x96E0	0x4C62	0x7C7E	# <CJK>
+0x96E1	0x4C63	0x8CB0	# <CJK>
+0x96E2	0x4C64	0x554F	# <CJK>
+0x96E3	0x4C65	0x60B6	# <CJK>
+0x96E4	0x4C66	0x7D0B	# <CJK>
+0x96E5	0x4C67	0x9580	# <CJK>
+0x96E6	0x4C68	0x5301	# <CJK>
+0x96E7	0x4C69	0x4E5F	# <CJK>
+0x96E8	0x4C6A	0x51B6	# <CJK>
+0x96E9	0x4C6B	0x591C	# <CJK>
+0x96EA	0x4C6C	0x723A	# <CJK>
+0x96EB	0x4C6D	0x8036	# <CJK>
+0x96EC	0x4C6E	0x91CE	# <CJK>
+0x96ED	0x4C6F	0x5F25	# <CJK>
+0x96EE	0x4C70	0x77E2	# <CJK>
+0x96EF	0x4C71	0x5384	# <CJK>
+0x96F0	0x4C72	0x5F79	# <CJK>
+0x96F1	0x4C73	0x7D04	# <CJK>
+0x96F2	0x4C74	0x85AC	# <CJK>
+0x96F3	0x4C75	0x8A33	# <CJK>
+0x96F4	0x4C76	0x8E8D	# <CJK>
+0x96F5	0x4C77	0x9756	# <CJK>
+0x96F6	0x4C78	0x67F3	# <CJK>
+0x96F7	0x4C79	0x85AE	# <CJK>
+0x96F8	0x4C7A	0x9453	# <CJK>
+0x96F9	0x4C7B	0x6109	# <CJK>
+0x96FA	0x4C7C	0x6108	# <CJK>
+0x96FB	0x4C7D	0x6CB9	# <CJK>
+0x96FC	0x4C7E	0x7652	# <CJK>
+0x9740	0x4D21	0x8AED	# <CJK>
+0x9741	0x4D22	0x8F38	# <CJK>
+0x9742	0x4D23	0x552F	# <CJK>
+0x9743	0x4D24	0x4F51	# <CJK>
+0x9744	0x4D25	0x512A	# <CJK>
+0x9745	0x4D26	0x52C7	# <CJK>
+0x9746	0x4D27	0x53CB	# <CJK>
+0x9747	0x4D28	0x5BA5	# <CJK>
+0x9748	0x4D29	0x5E7D	# <CJK>
+0x9749	0x4D2A	0x60A0	# <CJK>
+0x974A	0x4D2B	0x6182	# <CJK>
+0x974B	0x4D2C	0x63D6	# <CJK>
+0x974C	0x4D2D	0x6709	# <CJK>
+0x974D	0x4D2E	0x67DA	# <CJK>
+0x974E	0x4D2F	0x6E67	# <CJK>
+0x974F	0x4D30	0x6D8C	# <CJK>
+0x9750	0x4D31	0x7336	# <CJK>
+0x9751	0x4D32	0x7337	# <CJK>
+0x9752	0x4D33	0x7531	# <CJK>
+0x9753	0x4D34	0x7950	# <CJK>
+0x9754	0x4D35	0x88D5	# <CJK>
+0x9755	0x4D36	0x8A98	# <CJK>
+0x9756	0x4D37	0x904A	# <CJK>
+0x9757	0x4D38	0x9091	# <CJK>
+0x9758	0x4D39	0x90F5	# <CJK>
+0x9759	0x4D3A	0x96C4	# <CJK>
+0x975A	0x4D3B	0x878D	# <CJK>
+0x975B	0x4D3C	0x5915	# <CJK>
+0x975C	0x4D3D	0x4E88	# <CJK>
+0x975D	0x4D3E	0x4F59	# <CJK>
+0x975E	0x4D3F	0x4E0E	# <CJK>
+0x975F	0x4D40	0x8A89	# <CJK>
+0x9760	0x4D41	0x8F3F	# <CJK>
+0x9761	0x4D42	0x9810	# <CJK>
+0x9762	0x4D43	0x50AD	# <CJK>
+0x9763	0x4D44	0x5E7C	# <CJK>
+0x9764	0x4D45	0x5996	# <CJK>
+0x9765	0x4D46	0x5BB9	# <CJK>
+0x9766	0x4D47	0x5EB8	# <CJK>
+0x9767	0x4D48	0x63DA	# <CJK>
+0x9768	0x4D49	0x63FA	# <CJK>
+0x9769	0x4D4A	0x64C1	# <CJK>
+0x976A	0x4D4B	0x66DC	# <CJK>
+0x976B	0x4D4C	0x694A	# <CJK>
+0x976C	0x4D4D	0x69D8	# <CJK>
+0x976D	0x4D4E	0x6D0B	# <CJK>
+0x976E	0x4D4F	0x6EB6	# <CJK>
+0x976F	0x4D50	0x7194	# <CJK>
+0x9770	0x4D51	0x7528	# <CJK>
+0x9771	0x4D52	0x7AAF	# <CJK>
+0x9772	0x4D53	0x7F8A	# <CJK>
+0x9773	0x4D54	0x8000	# <CJK>
+0x9774	0x4D55	0x8449	# <CJK>
+0x9775	0x4D56	0x84C9	# <CJK>
+0x9776	0x4D57	0x8981	# <CJK>
+0x9777	0x4D58	0x8B21	# <CJK>
+0x9778	0x4D59	0x8E0A	# <CJK>
+0x9779	0x4D5A	0x9065	# <CJK>
+0x977A	0x4D5B	0x967D	# <CJK>
+0x977B	0x4D5C	0x990A	# <CJK>
+0x977C	0x4D5D	0x617E	# <CJK>
+0x977D	0x4D5E	0x6291	# <CJK>
+0x977E	0x4D5F	0x6B32	# <CJK>
+0x9780	0x4D60	0x6C83	# <CJK>
+0x9781	0x4D61	0x6D74	# <CJK>
+0x9782	0x4D62	0x7FCC	# <CJK>
+0x9783	0x4D63	0x7FFC	# <CJK>
+0x9784	0x4D64	0x6DC0	# <CJK>
+0x9785	0x4D65	0x7F85	# <CJK>
+0x9786	0x4D66	0x87BA	# <CJK>
+0x9787	0x4D67	0x88F8	# <CJK>
+0x9788	0x4D68	0x6765	# <CJK>
+0x9789	0x4D69	0x83B1	# <CJK>
+0x978A	0x4D6A	0x983C	# <CJK>
+0x978B	0x4D6B	0x96F7	# <CJK>
+0x978C	0x4D6C	0x6D1B	# <CJK>
+0x978D	0x4D6D	0x7D61	# <CJK>
+0x978E	0x4D6E	0x843D	# <CJK>
+0x978F	0x4D6F	0x916A	# <CJK>
+0x9790	0x4D70	0x4E71	# <CJK>
+0x9791	0x4D71	0x5375	# <CJK>
+0x9792	0x4D72	0x5D50	# <CJK>
+0x9793	0x4D73	0x6B04	# <CJK>
+0x9794	0x4D74	0x6FEB	# <CJK>
+0x9795	0x4D75	0x85CD	# <CJK>
+0x9796	0x4D76	0x862D	# <CJK>
+0x9797	0x4D77	0x89A7	# <CJK>
+0x9798	0x4D78	0x5229	# <CJK>
+0x9799	0x4D79	0x540F	# <CJK>
+0x979A	0x4D7A	0x5C65	# <CJK>
+0x979B	0x4D7B	0x674E	# <CJK>
+0x979C	0x4D7C	0x68A8	# <CJK>
+0x979D	0x4D7D	0x7406	# <CJK>
+0x979E	0x4D7E	0x7483	# <CJK>
+0x979F	0x4E21	0x75E2	# <CJK>
+0x97A0	0x4E22	0x88CF	# <CJK>
+0x97A1	0x4E23	0x88E1	# <CJK>
+0x97A2	0x4E24	0x91CC	# <CJK>
+0x97A3	0x4E25	0x96E2	# <CJK>
+0x97A4	0x4E26	0x9678	# <CJK>
+0x97A5	0x4E27	0x5F8B	# <CJK>
+0x97A6	0x4E28	0x7387	# <CJK>
+0x97A7	0x4E29	0x7ACB	# <CJK>
+0x97A8	0x4E2A	0x844E	# <CJK>
+0x97A9	0x4E2B	0x63A0	# <CJK>
+0x97AA	0x4E2C	0x7565	# <CJK>
+0x97AB	0x4E2D	0x5289	# <CJK>
+0x97AC	0x4E2E	0x6D41	# <CJK>
+0x97AD	0x4E2F	0x6E9C	# <CJK>
+0x97AE	0x4E30	0x7409	# <CJK>
+0x97AF	0x4E31	0x7559	# <CJK>
+0x97B0	0x4E32	0x786B	# <CJK>
+0x97B1	0x4E33	0x7C92	# <CJK>
+0x97B2	0x4E34	0x9686	# <CJK>
+0x97B3	0x4E35	0x7ADC	# <CJK>
+0x97B4	0x4E36	0x9F8D	# <CJK>
+0x97B5	0x4E37	0x4FB6	# <CJK>
+0x97B6	0x4E38	0x616E	# <CJK>
+0x97B7	0x4E39	0x65C5	# <CJK>
+0x97B8	0x4E3A	0x865C	# <CJK>
+0x97B9	0x4E3B	0x4E86	# <CJK>
+0x97BA	0x4E3C	0x4EAE	# <CJK>
+0x97BB	0x4E3D	0x50DA	# <CJK>
+0x97BC	0x4E3E	0x4E21	# <CJK>
+0x97BD	0x4E3F	0x51CC	# <CJK>
+0x97BE	0x4E40	0x5BEE	# <CJK>
+0x97BF	0x4E41	0x6599	# <CJK>
+0x97C0	0x4E42	0x6881	# <CJK>
+0x97C1	0x4E43	0x6DBC	# <CJK>
+0x97C2	0x4E44	0x731F	# <CJK>
+0x97C3	0x4E45	0x7642	# <CJK>
+0x97C4	0x4E46	0x77AD	# <CJK>
+0x97C5	0x4E47	0x7A1C	# <CJK>
+0x97C6	0x4E48	0x7CE7	# <CJK>
+0x97C7	0x4E49	0x826F	# <CJK>
+0x97C8	0x4E4A	0x8AD2	# <CJK>
+0x97C9	0x4E4B	0x907C	# <CJK>
+0x97CA	0x4E4C	0x91CF	# <CJK>
+0x97CB	0x4E4D	0x9675	# <CJK>
+0x97CC	0x4E4E	0x9818	# <CJK>
+0x97CD	0x4E4F	0x529B	# <CJK>
+0x97CE	0x4E50	0x7DD1	# <CJK>
+0x97CF	0x4E51	0x502B	# <CJK>
+0x97D0	0x4E52	0x5398	# <CJK>
+0x97D1	0x4E53	0x6797	# <CJK>
+0x97D2	0x4E54	0x6DCB	# <CJK>
+0x97D3	0x4E55	0x71D0	# <CJK>
+0x97D4	0x4E56	0x7433	# <CJK>
+0x97D5	0x4E57	0x81E8	# <CJK>
+0x97D6	0x4E58	0x8F2A	# <CJK>
+0x97D7	0x4E59	0x96A3	# <CJK>
+0x97D8	0x4E5A	0x9C57	# <CJK>
+0x97D9	0x4E5B	0x9E9F	# <CJK>
+0x97DA	0x4E5C	0x7460	# <CJK>
+0x97DB	0x4E5D	0x5841	# <CJK>
+0x97DC	0x4E5E	0x6D99	# <CJK>
+0x97DD	0x4E5F	0x7D2F	# <CJK>
+0x97DE	0x4E60	0x985E	# <CJK>
+0x97DF	0x4E61	0x4EE4	# <CJK>
+0x97E0	0x4E62	0x4F36	# <CJK>
+0x97E1	0x4E63	0x4F8B	# <CJK>
+0x97E2	0x4E64	0x51B7	# <CJK>
+0x97E3	0x4E65	0x52B1	# <CJK>
+0x97E4	0x4E66	0x5DBA	# <CJK>
+0x97E5	0x4E67	0x601C	# <CJK>
+0x97E6	0x4E68	0x73B2	# <CJK>
+0x97E7	0x4E69	0x793C	# <CJK>
+0x97E8	0x4E6A	0x82D3	# <CJK>
+0x97E9	0x4E6B	0x9234	# <CJK>
+0x97EA	0x4E6C	0x96B7	# <CJK>
+0x97EB	0x4E6D	0x96F6	# <CJK>
+0x97EC	0x4E6E	0x970A	# <CJK>
+0x97ED	0x4E6F	0x9E97	# <CJK>
+0x97EE	0x4E70	0x9F62	# <CJK>
+0x97EF	0x4E71	0x66A6	# <CJK>
+0x97F0	0x4E72	0x6B74	# <CJK>
+0x97F1	0x4E73	0x5217	# <CJK>
+0x97F2	0x4E74	0x52A3	# <CJK>
+0x97F3	0x4E75	0x70C8	# <CJK>
+0x97F4	0x4E76	0x88C2	# <CJK>
+0x97F5	0x4E77	0x5EC9	# <CJK>
+0x97F6	0x4E78	0x604B	# <CJK>
+0x97F7	0x4E79	0x6190	# <CJK>
+0x97F8	0x4E7A	0x6F23	# <CJK>
+0x97F9	0x4E7B	0x7149	# <CJK>
+0x97FA	0x4E7C	0x7C3E	# <CJK>
+0x97FB	0x4E7D	0x7DF4	# <CJK>
+0x97FC	0x4E7E	0x806F	# <CJK>
+0x9840	0x4F21	0x84EE	# <CJK>
+0x9841	0x4F22	0x9023	# <CJK>
+0x9842	0x4F23	0x932C	# <CJK>
+0x9843	0x4F24	0x5442	# <CJK>
+0x9844	0x4F25	0x9B6F	# <CJK>
+0x9845	0x4F26	0x6AD3	# <CJK>
+0x9846	0x4F27	0x7089	# <CJK>
+0x9847	0x4F28	0x8CC2	# <CJK>
+0x9848	0x4F29	0x8DEF	# <CJK>
+0x9849	0x4F2A	0x9732	# <CJK>
+0x984A	0x4F2B	0x52B4	# <CJK>
+0x984B	0x4F2C	0x5A41	# <CJK>
+0x984C	0x4F2D	0x5ECA	# <CJK>
+0x984D	0x4F2E	0x5F04	# <CJK>
+0x984E	0x4F2F	0x6717	# <CJK>
+0x984F	0x4F30	0x697C	# <CJK>
+0x9850	0x4F31	0x6994	# <CJK>
+0x9851	0x4F32	0x6D6A	# <CJK>
+0x9852	0x4F33	0x6F0F	# <CJK>
+0x9853	0x4F34	0x7262	# <CJK>
+0x9854	0x4F35	0x72FC	# <CJK>
+0x9855	0x4F36	0x7BED	# <CJK>
+0x9856	0x4F37	0x8001	# <CJK>
+0x9857	0x4F38	0x807E	# <CJK>
+0x9858	0x4F39	0x874B	# <CJK>
+0x9859	0x4F3A	0x90CE	# <CJK>
+0x985A	0x4F3B	0x516D	# <CJK>
+0x985B	0x4F3C	0x9E93	# <CJK>
+0x985C	0x4F3D	0x7984	# <CJK>
+0x985D	0x4F3E	0x808B	# <CJK>
+0x985E	0x4F3F	0x9332	# <CJK>
+0x985F	0x4F40	0x8AD6	# <CJK>
+0x9860	0x4F41	0x502D	# <CJK>
+0x9861	0x4F42	0x548C	# <CJK>
+0x9862	0x4F43	0x8A71	# <CJK>
+0x9863	0x4F44	0x6B6A	# <CJK>
+0x9864	0x4F45	0x8CC4	# <CJK>
+0x9865	0x4F46	0x8107	# <CJK>
+0x9866	0x4F47	0x60D1	# <CJK>
+0x9867	0x4F48	0x67A0	# <CJK>
+0x9868	0x4F49	0x9DF2	# <CJK>
+0x9869	0x4F4A	0x4E99	# <CJK>
+0x986A	0x4F4B	0x4E98	# <CJK>
+0x986B	0x4F4C	0x9C10	# <CJK>
+0x986C	0x4F4D	0x8A6B	# <CJK>
+0x986D	0x4F4E	0x85C1	# <CJK>
+0x986E	0x4F4F	0x8568	# <CJK>
+0x986F	0x4F50	0x6900	# <CJK>
+0x9870	0x4F51	0x6E7E	# <CJK>
+0x9871	0x4F52	0x7897	# <CJK>
+0x9872	0x4F53	0x8155	# <CJK>
+0x989F	0x5021	0x5F0C	# <CJK>
+0x98A0	0x5022	0x4E10	# <CJK>
+0x98A1	0x5023	0x4E15	# <CJK>
+0x98A2	0x5024	0x4E2A	# <CJK>
+0x98A3	0x5025	0x4E31	# <CJK>
+0x98A4	0x5026	0x4E36	# <CJK>
+0x98A5	0x5027	0x4E3C	# <CJK>
+0x98A6	0x5028	0x4E3F	# <CJK>
+0x98A7	0x5029	0x4E42	# <CJK>
+0x98A8	0x502A	0x4E56	# <CJK>
+0x98A9	0x502B	0x4E58	# <CJK>
+0x98AA	0x502C	0x4E82	# <CJK>
+0x98AB	0x502D	0x4E85	# <CJK>
+0x98AC	0x502E	0x8C6B	# <CJK>
+0x98AD	0x502F	0x4E8A	# <CJK>
+0x98AE	0x5030	0x8212	# <CJK>
+0x98AF	0x5031	0x5F0D	# <CJK>
+0x98B0	0x5032	0x4E8E	# <CJK>
+0x98B1	0x5033	0x4E9E	# <CJK>
+0x98B2	0x5034	0x4E9F	# <CJK>
+0x98B3	0x5035	0x4EA0	# <CJK>
+0x98B4	0x5036	0x4EA2	# <CJK>
+0x98B5	0x5037	0x4EB0	# <CJK>
+0x98B6	0x5038	0x4EB3	# <CJK>
+0x98B7	0x5039	0x4EB6	# <CJK>
+0x98B8	0x503A	0x4ECE	# <CJK>
+0x98B9	0x503B	0x4ECD	# <CJK>
+0x98BA	0x503C	0x4EC4	# <CJK>
+0x98BB	0x503D	0x4EC6	# <CJK>
+0x98BC	0x503E	0x4EC2	# <CJK>
+0x98BD	0x503F	0x4ED7	# <CJK>
+0x98BE	0x5040	0x4EDE	# <CJK>
+0x98BF	0x5041	0x4EED	# <CJK>
+0x98C0	0x5042	0x4EDF	# <CJK>
+0x98C1	0x5043	0x4EF7	# <CJK>
+0x98C2	0x5044	0x4F09	# <CJK>
+0x98C3	0x5045	0x4F5A	# <CJK>
+0x98C4	0x5046	0x4F30	# <CJK>
+0x98C5	0x5047	0x4F5B	# <CJK>
+0x98C6	0x5048	0x4F5D	# <CJK>
+0x98C7	0x5049	0x4F57	# <CJK>
+0x98C8	0x504A	0x4F47	# <CJK>
+0x98C9	0x504B	0x4F76	# <CJK>
+0x98CA	0x504C	0x4F88	# <CJK>
+0x98CB	0x504D	0x4F8F	# <CJK>
+0x98CC	0x504E	0x4F98	# <CJK>
+0x98CD	0x504F	0x4F7B	# <CJK>
+0x98CE	0x5050	0x4F69	# <CJK>
+0x98CF	0x5051	0x4F70	# <CJK>
+0x98D0	0x5052	0x4F91	# <CJK>
+0x98D1	0x5053	0x4F6F	# <CJK>
+0x98D2	0x5054	0x4F86	# <CJK>
+0x98D3	0x5055	0x4F96	# <CJK>
+0x98D4	0x5056	0x5118	# <CJK>
+0x98D5	0x5057	0x4FD4	# <CJK>
+0x98D6	0x5058	0x4FDF	# <CJK>
+0x98D7	0x5059	0x4FCE	# <CJK>
+0x98D8	0x505A	0x4FD8	# <CJK>
+0x98D9	0x505B	0x4FDB	# <CJK>
+0x98DA	0x505C	0x4FD1	# <CJK>
+0x98DB	0x505D	0x4FDA	# <CJK>
+0x98DC	0x505E	0x4FD0	# <CJK>
+0x98DD	0x505F	0x4FE4	# <CJK>
+0x98DE	0x5060	0x4FE5	# <CJK>
+0x98DF	0x5061	0x501A	# <CJK>
+0x98E0	0x5062	0x5028	# <CJK>
+0x98E1	0x5063	0x5014	# <CJK>
+0x98E2	0x5064	0x502A	# <CJK>
+0x98E3	0x5065	0x5025	# <CJK>
+0x98E4	0x5066	0x5005	# <CJK>
+0x98E5	0x5067	0x4F1C	# <CJK>
+0x98E6	0x5068	0x4FF6	# <CJK>
+0x98E7	0x5069	0x5021	# <CJK>
+0x98E8	0x506A	0x5029	# <CJK>
+0x98E9	0x506B	0x502C	# <CJK>
+0x98EA	0x506C	0x4FFE	# <CJK>
+0x98EB	0x506D	0x4FEF	# <CJK>
+0x98EC	0x506E	0x5011	# <CJK>
+0x98ED	0x506F	0x5006	# <CJK>
+0x98EE	0x5070	0x5043	# <CJK>
+0x98EF	0x5071	0x5047	# <CJK>
+0x98F0	0x5072	0x6703	# <CJK>
+0x98F1	0x5073	0x5055	# <CJK>
+0x98F2	0x5074	0x5050	# <CJK>
+0x98F3	0x5075	0x5048	# <CJK>
+0x98F4	0x5076	0x505A	# <CJK>
+0x98F5	0x5077	0x5056	# <CJK>
+0x98F6	0x5078	0x506C	# <CJK>
+0x98F7	0x5079	0x5078	# <CJK>
+0x98F8	0x507A	0x5080	# <CJK>
+0x98F9	0x507B	0x509A	# <CJK>
+0x98FA	0x507C	0x5085	# <CJK>
+0x98FB	0x507D	0x50B4	# <CJK>
+0x98FC	0x507E	0x50B2	# <CJK>
+0x9940	0x5121	0x50C9	# <CJK>
+0x9941	0x5122	0x50CA	# <CJK>
+0x9942	0x5123	0x50B3	# <CJK>
+0x9943	0x5124	0x50C2	# <CJK>
+0x9944	0x5125	0x50D6	# <CJK>
+0x9945	0x5126	0x50DE	# <CJK>
+0x9946	0x5127	0x50E5	# <CJK>
+0x9947	0x5128	0x50ED	# <CJK>
+0x9948	0x5129	0x50E3	# <CJK>
+0x9949	0x512A	0x50EE	# <CJK>
+0x994A	0x512B	0x50F9	# <CJK>
+0x994B	0x512C	0x50F5	# <CJK>
+0x994C	0x512D	0x5109	# <CJK>
+0x994D	0x512E	0x5101	# <CJK>
+0x994E	0x512F	0x5102	# <CJK>
+0x994F	0x5130	0x5116	# <CJK>
+0x9950	0x5131	0x5115	# <CJK>
+0x9951	0x5132	0x5114	# <CJK>
+0x9952	0x5133	0x511A	# <CJK>
+0x9953	0x5134	0x5121	# <CJK>
+0x9954	0x5135	0x513A	# <CJK>
+0x9955	0x5136	0x5137	# <CJK>
+0x9956	0x5137	0x513C	# <CJK>
+0x9957	0x5138	0x513B	# <CJK>
+0x9958	0x5139	0x513F	# <CJK>
+0x9959	0x513A	0x5140	# <CJK>
+0x995A	0x513B	0x5152	# <CJK>
+0x995B	0x513C	0x514C	# <CJK>
+0x995C	0x513D	0x5154	# <CJK>
+0x995D	0x513E	0x5162	# <CJK>
+0x995E	0x513F	0x7AF8	# <CJK>
+0x995F	0x5140	0x5169	# <CJK>
+0x9960	0x5141	0x516A	# <CJK>
+0x9961	0x5142	0x516E	# <CJK>
+0x9962	0x5143	0x5180	# <CJK>
+0x9963	0x5144	0x5182	# <CJK>
+0x9964	0x5145	0x56D8	# <CJK>
+0x9965	0x5146	0x518C	# <CJK>
+0x9966	0x5147	0x5189	# <CJK>
+0x9967	0x5148	0x518F	# <CJK>
+0x9968	0x5149	0x5191	# <CJK>
+0x9969	0x514A	0x5193	# <CJK>
+0x996A	0x514B	0x5195	# <CJK>
+0x996B	0x514C	0x5196	# <CJK>
+0x996C	0x514D	0x51A4	# <CJK>
+0x996D	0x514E	0x51A6	# <CJK>
+0x996E	0x514F	0x51A2	# <CJK>
+0x996F	0x5150	0x51A9	# <CJK>
+0x9970	0x5151	0x51AA	# <CJK>
+0x9971	0x5152	0x51AB	# <CJK>
+0x9972	0x5153	0x51B3	# <CJK>
+0x9973	0x5154	0x51B1	# <CJK>
+0x9974	0x5155	0x51B2	# <CJK>
+0x9975	0x5156	0x51B0	# <CJK>
+0x9976	0x5157	0x51B5	# <CJK>
+0x9977	0x5158	0x51BD	# <CJK>
+0x9978	0x5159	0x51C5	# <CJK>
+0x9979	0x515A	0x51C9	# <CJK>
+0x997A	0x515B	0x51DB	# <CJK>
+0x997B	0x515C	0x51E0	# <CJK>
+0x997C	0x515D	0x8655	# <CJK>
+0x997D	0x515E	0x51E9	# <CJK>
+0x997E	0x515F	0x51ED	# <CJK>
+0x9980	0x5160	0x51F0	# <CJK>
+0x9981	0x5161	0x51F5	# <CJK>
+0x9982	0x5162	0x51FE	# <CJK>
+0x9983	0x5163	0x5204	# <CJK>
+0x9984	0x5164	0x520B	# <CJK>
+0x9985	0x5165	0x5214	# <CJK>
+0x9986	0x5166	0x520E	# <CJK>
+0x9987	0x5167	0x5227	# <CJK>
+0x9988	0x5168	0x522A	# <CJK>
+0x9989	0x5169	0x522E	# <CJK>
+0x998A	0x516A	0x5233	# <CJK>
+0x998B	0x516B	0x5239	# <CJK>
+0x998C	0x516C	0x524F	# <CJK>
+0x998D	0x516D	0x5244	# <CJK>
+0x998E	0x516E	0x524B	# <CJK>
+0x998F	0x516F	0x524C	# <CJK>
+0x9990	0x5170	0x525E	# <CJK>
+0x9991	0x5171	0x5254	# <CJK>
+0x9992	0x5172	0x526A	# <CJK>
+0x9993	0x5173	0x5274	# <CJK>
+0x9994	0x5174	0x5269	# <CJK>
+0x9995	0x5175	0x5273	# <CJK>
+0x9996	0x5176	0x527F	# <CJK>
+0x9997	0x5177	0x527D	# <CJK>
+0x9998	0x5178	0x528D	# <CJK>
+0x9999	0x5179	0x5294	# <CJK>
+0x999A	0x517A	0x5292	# <CJK>
+0x999B	0x517B	0x5271	# <CJK>
+0x999C	0x517C	0x5288	# <CJK>
+0x999D	0x517D	0x5291	# <CJK>
+0x999E	0x517E	0x8FA8	# <CJK>
+0x999F	0x5221	0x8FA7	# <CJK>
+0x99A0	0x5222	0x52AC	# <CJK>
+0x99A1	0x5223	0x52AD	# <CJK>
+0x99A2	0x5224	0x52BC	# <CJK>
+0x99A3	0x5225	0x52B5	# <CJK>
+0x99A4	0x5226	0x52C1	# <CJK>
+0x99A5	0x5227	0x52CD	# <CJK>
+0x99A6	0x5228	0x52D7	# <CJK>
+0x99A7	0x5229	0x52DE	# <CJK>
+0x99A8	0x522A	0x52E3	# <CJK>
+0x99A9	0x522B	0x52E6	# <CJK>
+0x99AA	0x522C	0x98ED	# <CJK>
+0x99AB	0x522D	0x52E0	# <CJK>
+0x99AC	0x522E	0x52F3	# <CJK>
+0x99AD	0x522F	0x52F5	# <CJK>
+0x99AE	0x5230	0x52F8	# <CJK>
+0x99AF	0x5231	0x52F9	# <CJK>
+0x99B0	0x5232	0x5306	# <CJK>
+0x99B1	0x5233	0x5308	# <CJK>
+0x99B2	0x5234	0x7538	# <CJK>
+0x99B3	0x5235	0x530D	# <CJK>
+0x99B4	0x5236	0x5310	# <CJK>
+0x99B5	0x5237	0x530F	# <CJK>
+0x99B6	0x5238	0x5315	# <CJK>
+0x99B7	0x5239	0x531A	# <CJK>
+0x99B8	0x523A	0x5323	# <CJK>
+0x99B9	0x523B	0x532F	# <CJK>
+0x99BA	0x523C	0x5331	# <CJK>
+0x99BB	0x523D	0x5333	# <CJK>
+0x99BC	0x523E	0x5338	# <CJK>
+0x99BD	0x523F	0x5340	# <CJK>
+0x99BE	0x5240	0x5346	# <CJK>
+0x99BF	0x5241	0x5345	# <CJK>
+0x99C0	0x5242	0x4E17	# <CJK>
+0x99C1	0x5243	0x5349	# <CJK>
+0x99C2	0x5244	0x534D	# <CJK>
+0x99C3	0x5245	0x51D6	# <CJK>
+0x99C4	0x5246	0x535E	# <CJK>
+0x99C5	0x5247	0x5369	# <CJK>
+0x99C6	0x5248	0x536E	# <CJK>
+0x99C7	0x5249	0x5918	# <CJK>
+0x99C8	0x524A	0x537B	# <CJK>
+0x99C9	0x524B	0x5377	# <CJK>
+0x99CA	0x524C	0x5382	# <CJK>
+0x99CB	0x524D	0x5396	# <CJK>
+0x99CC	0x524E	0x53A0	# <CJK>
+0x99CD	0x524F	0x53A6	# <CJK>
+0x99CE	0x5250	0x53A5	# <CJK>
+0x99CF	0x5251	0x53AE	# <CJK>
+0x99D0	0x5252	0x53B0	# <CJK>
+0x99D1	0x5253	0x53B6	# <CJK>
+0x99D2	0x5254	0x53C3	# <CJK>
+0x99D3	0x5255	0x7C12	# <CJK>
+0x99D4	0x5256	0x96D9	# <CJK>
+0x99D5	0x5257	0x53DF	# <CJK>
+0x99D6	0x5258	0x66FC	# <CJK>
+0x99D7	0x5259	0x71EE	# <CJK>
+0x99D8	0x525A	0x53EE	# <CJK>
+0x99D9	0x525B	0x53E8	# <CJK>
+0x99DA	0x525C	0x53ED	# <CJK>
+0x99DB	0x525D	0x53FA	# <CJK>
+0x99DC	0x525E	0x5401	# <CJK>
+0x99DD	0x525F	0x543D	# <CJK>
+0x99DE	0x5260	0x5440	# <CJK>
+0x99DF	0x5261	0x542C	# <CJK>
+0x99E0	0x5262	0x542D	# <CJK>
+0x99E1	0x5263	0x543C	# <CJK>
+0x99E2	0x5264	0x542E	# <CJK>
+0x99E3	0x5265	0x5436	# <CJK>
+0x99E4	0x5266	0x5429	# <CJK>
+0x99E5	0x5267	0x541D	# <CJK>
+0x99E6	0x5268	0x544E	# <CJK>
+0x99E7	0x5269	0x548F	# <CJK>
+0x99E8	0x526A	0x5475	# <CJK>
+0x99E9	0x526B	0x548E	# <CJK>
+0x99EA	0x526C	0x545F	# <CJK>
+0x99EB	0x526D	0x5471	# <CJK>
+0x99EC	0x526E	0x5477	# <CJK>
+0x99ED	0x526F	0x5470	# <CJK>
+0x99EE	0x5270	0x5492	# <CJK>
+0x99EF	0x5271	0x547B	# <CJK>
+0x99F0	0x5272	0x5480	# <CJK>
+0x99F1	0x5273	0x5476	# <CJK>
+0x99F2	0x5274	0x5484	# <CJK>
+0x99F3	0x5275	0x5490	# <CJK>
+0x99F4	0x5276	0x5486	# <CJK>
+0x99F5	0x5277	0x54C7	# <CJK>
+0x99F6	0x5278	0x54A2	# <CJK>
+0x99F7	0x5279	0x54B8	# <CJK>
+0x99F8	0x527A	0x54A5	# <CJK>
+0x99F9	0x527B	0x54AC	# <CJK>
+0x99FA	0x527C	0x54C4	# <CJK>
+0x99FB	0x527D	0x54C8	# <CJK>
+0x99FC	0x527E	0x54A8	# <CJK>
+0x9A40	0x5321	0x54AB	# <CJK>
+0x9A41	0x5322	0x54C2	# <CJK>
+0x9A42	0x5323	0x54A4	# <CJK>
+0x9A43	0x5324	0x54BE	# <CJK>
+0x9A44	0x5325	0x54BC	# <CJK>
+0x9A45	0x5326	0x54D8	# <CJK>
+0x9A46	0x5327	0x54E5	# <CJK>
+0x9A47	0x5328	0x54E6	# <CJK>
+0x9A48	0x5329	0x550F	# <CJK>
+0x9A49	0x532A	0x5514	# <CJK>
+0x9A4A	0x532B	0x54FD	# <CJK>
+0x9A4B	0x532C	0x54EE	# <CJK>
+0x9A4C	0x532D	0x54ED	# <CJK>
+0x9A4D	0x532E	0x54FA	# <CJK>
+0x9A4E	0x532F	0x54E2	# <CJK>
+0x9A4F	0x5330	0x5539	# <CJK>
+0x9A50	0x5331	0x5540	# <CJK>
+0x9A51	0x5332	0x5563	# <CJK>
+0x9A52	0x5333	0x554C	# <CJK>
+0x9A53	0x5334	0x552E	# <CJK>
+0x9A54	0x5335	0x555C	# <CJK>
+0x9A55	0x5336	0x5545	# <CJK>
+0x9A56	0x5337	0x5556	# <CJK>
+0x9A57	0x5338	0x5557	# <CJK>
+0x9A58	0x5339	0x5538	# <CJK>
+0x9A59	0x533A	0x5533	# <CJK>
+0x9A5A	0x533B	0x555D	# <CJK>
+0x9A5B	0x533C	0x5599	# <CJK>
+0x9A5C	0x533D	0x5580	# <CJK>
+0x9A5D	0x533E	0x54AF	# <CJK>
+0x9A5E	0x533F	0x558A	# <CJK>
+0x9A5F	0x5340	0x559F	# <CJK>
+0x9A60	0x5341	0x557B	# <CJK>
+0x9A61	0x5342	0x557E	# <CJK>
+0x9A62	0x5343	0x5598	# <CJK>
+0x9A63	0x5344	0x559E	# <CJK>
+0x9A64	0x5345	0x55AE	# <CJK>
+0x9A65	0x5346	0x557C	# <CJK>
+0x9A66	0x5347	0x5583	# <CJK>
+0x9A67	0x5348	0x55A9	# <CJK>
+0x9A68	0x5349	0x5587	# <CJK>
+0x9A69	0x534A	0x55A8	# <CJK>
+0x9A6A	0x534B	0x55DA	# <CJK>
+0x9A6B	0x534C	0x55C5	# <CJK>
+0x9A6C	0x534D	0x55DF	# <CJK>
+0x9A6D	0x534E	0x55C4	# <CJK>
+0x9A6E	0x534F	0x55DC	# <CJK>
+0x9A6F	0x5350	0x55E4	# <CJK>
+0x9A70	0x5351	0x55D4	# <CJK>
+0x9A71	0x5352	0x5614	# <CJK>
+0x9A72	0x5353	0x55F7	# <CJK>
+0x9A73	0x5354	0x5616	# <CJK>
+0x9A74	0x5355	0x55FE	# <CJK>
+0x9A75	0x5356	0x55FD	# <CJK>
+0x9A76	0x5357	0x561B	# <CJK>
+0x9A77	0x5358	0x55F9	# <CJK>
+0x9A78	0x5359	0x564E	# <CJK>
+0x9A79	0x535A	0x5650	# <CJK>
+0x9A7A	0x535B	0x71DF	# <CJK>
+0x9A7B	0x535C	0x5634	# <CJK>
+0x9A7C	0x535D	0x5636	# <CJK>
+0x9A7D	0x535E	0x5632	# <CJK>
+0x9A7E	0x535F	0x5638	# <CJK>
+0x9A80	0x5360	0x566B	# <CJK>
+0x9A81	0x5361	0x5664	# <CJK>
+0x9A82	0x5362	0x562F	# <CJK>
+0x9A83	0x5363	0x566C	# <CJK>
+0x9A84	0x5364	0x566A	# <CJK>
+0x9A85	0x5365	0x5686	# <CJK>
+0x9A86	0x5366	0x5680	# <CJK>
+0x9A87	0x5367	0x568A	# <CJK>
+0x9A88	0x5368	0x56A0	# <CJK>
+0x9A89	0x5369	0x5694	# <CJK>
+0x9A8A	0x536A	0x568F	# <CJK>
+0x9A8B	0x536B	0x56A5	# <CJK>
+0x9A8C	0x536C	0x56AE	# <CJK>
+0x9A8D	0x536D	0x56B6	# <CJK>
+0x9A8E	0x536E	0x56B4	# <CJK>
+0x9A8F	0x536F	0x56C2	# <CJK>
+0x9A90	0x5370	0x56BC	# <CJK>
+0x9A91	0x5371	0x56C1	# <CJK>
+0x9A92	0x5372	0x56C3	# <CJK>
+0x9A93	0x5373	0x56C0	# <CJK>
+0x9A94	0x5374	0x56C8	# <CJK>
+0x9A95	0x5375	0x56CE	# <CJK>
+0x9A96	0x5376	0x56D1	# <CJK>
+0x9A97	0x5377	0x56D3	# <CJK>
+0x9A98	0x5378	0x56D7	# <CJK>
+0x9A99	0x5379	0x56EE	# <CJK>
+0x9A9A	0x537A	0x56F9	# <CJK>
+0x9A9B	0x537B	0x5700	# <CJK>
+0x9A9C	0x537C	0x56FF	# <CJK>
+0x9A9D	0x537D	0x5704	# <CJK>
+0x9A9E	0x537E	0x5709	# <CJK>
+0x9A9F	0x5421	0x5708	# <CJK>
+0x9AA0	0x5422	0x570B	# <CJK>
+0x9AA1	0x5423	0x570D	# <CJK>
+0x9AA2	0x5424	0x5713	# <CJK>
+0x9AA3	0x5425	0x5718	# <CJK>
+0x9AA4	0x5426	0x5716	# <CJK>
+0x9AA5	0x5427	0x55C7	# <CJK>
+0x9AA6	0x5428	0x571C	# <CJK>
+0x9AA7	0x5429	0x5726	# <CJK>
+0x9AA8	0x542A	0x5737	# <CJK>
+0x9AA9	0x542B	0x5738	# <CJK>
+0x9AAA	0x542C	0x574E	# <CJK>
+0x9AAB	0x542D	0x573B	# <CJK>
+0x9AAC	0x542E	0x5740	# <CJK>
+0x9AAD	0x542F	0x574F	# <CJK>
+0x9AAE	0x5430	0x5769	# <CJK>
+0x9AAF	0x5431	0x57C0	# <CJK>
+0x9AB0	0x5432	0x5788	# <CJK>
+0x9AB1	0x5433	0x5761	# <CJK>
+0x9AB2	0x5434	0x577F	# <CJK>
+0x9AB3	0x5435	0x5789	# <CJK>
+0x9AB4	0x5436	0x5793	# <CJK>
+0x9AB5	0x5437	0x57A0	# <CJK>
+0x9AB6	0x5438	0x57B3	# <CJK>
+0x9AB7	0x5439	0x57A4	# <CJK>
+0x9AB8	0x543A	0x57AA	# <CJK>
+0x9AB9	0x543B	0x57B0	# <CJK>
+0x9ABA	0x543C	0x57C3	# <CJK>
+0x9ABB	0x543D	0x57C6	# <CJK>
+0x9ABC	0x543E	0x57D4	# <CJK>
+0x9ABD	0x543F	0x57D2	# <CJK>
+0x9ABE	0x5440	0x57D3	# <CJK>
+0x9ABF	0x5441	0x580A	# <CJK>
+0x9AC0	0x5442	0x57D6	# <CJK>
+0x9AC1	0x5443	0x57E3	# <CJK>
+0x9AC2	0x5444	0x580B	# <CJK>
+0x9AC3	0x5445	0x5819	# <CJK>
+0x9AC4	0x5446	0x581D	# <CJK>
+0x9AC5	0x5447	0x5872	# <CJK>
+0x9AC6	0x5448	0x5821	# <CJK>
+0x9AC7	0x5449	0x5862	# <CJK>
+0x9AC8	0x544A	0x584B	# <CJK>
+0x9AC9	0x544B	0x5870	# <CJK>
+0x9ACA	0x544C	0x6BC0	# <CJK>
+0x9ACB	0x544D	0x5852	# <CJK>
+0x9ACC	0x544E	0x583D	# <CJK>
+0x9ACD	0x544F	0x5879	# <CJK>
+0x9ACE	0x5450	0x5885	# <CJK>
+0x9ACF	0x5451	0x58B9	# <CJK>
+0x9AD0	0x5452	0x589F	# <CJK>
+0x9AD1	0x5453	0x58AB	# <CJK>
+0x9AD2	0x5454	0x58BA	# <CJK>
+0x9AD3	0x5455	0x58DE	# <CJK>
+0x9AD4	0x5456	0x58BB	# <CJK>
+0x9AD5	0x5457	0x58B8	# <CJK>
+0x9AD6	0x5458	0x58AE	# <CJK>
+0x9AD7	0x5459	0x58C5	# <CJK>
+0x9AD8	0x545A	0x58D3	# <CJK>
+0x9AD9	0x545B	0x58D1	# <CJK>
+0x9ADA	0x545C	0x58D7	# <CJK>
+0x9ADB	0x545D	0x58D9	# <CJK>
+0x9ADC	0x545E	0x58D8	# <CJK>
+0x9ADD	0x545F	0x58E5	# <CJK>
+0x9ADE	0x5460	0x58DC	# <CJK>
+0x9ADF	0x5461	0x58E4	# <CJK>
+0x9AE0	0x5462	0x58DF	# <CJK>
+0x9AE1	0x5463	0x58EF	# <CJK>
+0x9AE2	0x5464	0x58FA	# <CJK>
+0x9AE3	0x5465	0x58F9	# <CJK>
+0x9AE4	0x5466	0x58FB	# <CJK>
+0x9AE5	0x5467	0x58FC	# <CJK>
+0x9AE6	0x5468	0x58FD	# <CJK>
+0x9AE7	0x5469	0x5902	# <CJK>
+0x9AE8	0x546A	0x590A	# <CJK>
+0x9AE9	0x546B	0x5910	# <CJK>
+0x9AEA	0x546C	0x591B	# <CJK>
+0x9AEB	0x546D	0x68A6	# <CJK>
+0x9AEC	0x546E	0x5925	# <CJK>
+0x9AED	0x546F	0x592C	# <CJK>
+0x9AEE	0x5470	0x592D	# <CJK>
+0x9AEF	0x5471	0x5932	# <CJK>
+0x9AF0	0x5472	0x5938	# <CJK>
+0x9AF1	0x5473	0x593E	# <CJK>
+0x9AF2	0x5474	0x7AD2	# <CJK>
+0x9AF3	0x5475	0x5955	# <CJK>
+0x9AF4	0x5476	0x5950	# <CJK>
+0x9AF5	0x5477	0x594E	# <CJK>
+0x9AF6	0x5478	0x595A	# <CJK>
+0x9AF7	0x5479	0x5958	# <CJK>
+0x9AF8	0x547A	0x5962	# <CJK>
+0x9AF9	0x547B	0x5960	# <CJK>
+0x9AFA	0x547C	0x5967	# <CJK>
+0x9AFB	0x547D	0x596C	# <CJK>
+0x9AFC	0x547E	0x5969	# <CJK>
+0x9B40	0x5521	0x5978	# <CJK>
+0x9B41	0x5522	0x5981	# <CJK>
+0x9B42	0x5523	0x599D	# <CJK>
+0x9B43	0x5524	0x4F5E	# <CJK>
+0x9B44	0x5525	0x4FAB	# <CJK>
+0x9B45	0x5526	0x59A3	# <CJK>
+0x9B46	0x5527	0x59B2	# <CJK>
+0x9B47	0x5528	0x59C6	# <CJK>
+0x9B48	0x5529	0x59E8	# <CJK>
+0x9B49	0x552A	0x59DC	# <CJK>
+0x9B4A	0x552B	0x598D	# <CJK>
+0x9B4B	0x552C	0x59D9	# <CJK>
+0x9B4C	0x552D	0x59DA	# <CJK>
+0x9B4D	0x552E	0x5A25	# <CJK>
+0x9B4E	0x552F	0x5A1F	# <CJK>
+0x9B4F	0x5530	0x5A11	# <CJK>
+0x9B50	0x5531	0x5A1C	# <CJK>
+0x9B51	0x5532	0x5A09	# <CJK>
+0x9B52	0x5533	0x5A1A	# <CJK>
+0x9B53	0x5534	0x5A40	# <CJK>
+0x9B54	0x5535	0x5A6C	# <CJK>
+0x9B55	0x5536	0x5A49	# <CJK>
+0x9B56	0x5537	0x5A35	# <CJK>
+0x9B57	0x5538	0x5A36	# <CJK>
+0x9B58	0x5539	0x5A62	# <CJK>
+0x9B59	0x553A	0x5A6A	# <CJK>
+0x9B5A	0x553B	0x5A9A	# <CJK>
+0x9B5B	0x553C	0x5ABC	# <CJK>
+0x9B5C	0x553D	0x5ABE	# <CJK>
+0x9B5D	0x553E	0x5ACB	# <CJK>
+0x9B5E	0x553F	0x5AC2	# <CJK>
+0x9B5F	0x5540	0x5ABD	# <CJK>
+0x9B60	0x5541	0x5AE3	# <CJK>
+0x9B61	0x5542	0x5AD7	# <CJK>
+0x9B62	0x5543	0x5AE6	# <CJK>
+0x9B63	0x5544	0x5AE9	# <CJK>
+0x9B64	0x5545	0x5AD6	# <CJK>
+0x9B65	0x5546	0x5AFA	# <CJK>
+0x9B66	0x5547	0x5AFB	# <CJK>
+0x9B67	0x5548	0x5B0C	# <CJK>
+0x9B68	0x5549	0x5B0B	# <CJK>
+0x9B69	0x554A	0x5B16	# <CJK>
+0x9B6A	0x554B	0x5B32	# <CJK>
+0x9B6B	0x554C	0x5AD0	# <CJK>
+0x9B6C	0x554D	0x5B2A	# <CJK>
+0x9B6D	0x554E	0x5B36	# <CJK>
+0x9B6E	0x554F	0x5B3E	# <CJK>
+0x9B6F	0x5550	0x5B43	# <CJK>
+0x9B70	0x5551	0x5B45	# <CJK>
+0x9B71	0x5552	0x5B40	# <CJK>
+0x9B72	0x5553	0x5B51	# <CJK>
+0x9B73	0x5554	0x5B55	# <CJK>
+0x9B74	0x5555	0x5B5A	# <CJK>
+0x9B75	0x5556	0x5B5B	# <CJK>
+0x9B76	0x5557	0x5B65	# <CJK>
+0x9B77	0x5558	0x5B69	# <CJK>
+0x9B78	0x5559	0x5B70	# <CJK>
+0x9B79	0x555A	0x5B73	# <CJK>
+0x9B7A	0x555B	0x5B75	# <CJK>
+0x9B7B	0x555C	0x5B78	# <CJK>
+0x9B7C	0x555D	0x6588	# <CJK>
+0x9B7D	0x555E	0x5B7A	# <CJK>
+0x9B7E	0x555F	0x5B80	# <CJK>
+0x9B80	0x5560	0x5B83	# <CJK>
+0x9B81	0x5561	0x5BA6	# <CJK>
+0x9B82	0x5562	0x5BB8	# <CJK>
+0x9B83	0x5563	0x5BC3	# <CJK>
+0x9B84	0x5564	0x5BC7	# <CJK>
+0x9B85	0x5565	0x5BC9	# <CJK>
+0x9B86	0x5566	0x5BD4	# <CJK>
+0x9B87	0x5567	0x5BD0	# <CJK>
+0x9B88	0x5568	0x5BE4	# <CJK>
+0x9B89	0x5569	0x5BE6	# <CJK>
+0x9B8A	0x556A	0x5BE2	# <CJK>
+0x9B8B	0x556B	0x5BDE	# <CJK>
+0x9B8C	0x556C	0x5BE5	# <CJK>
+0x9B8D	0x556D	0x5BEB	# <CJK>
+0x9B8E	0x556E	0x5BF0	# <CJK>
+0x9B8F	0x556F	0x5BF6	# <CJK>
+0x9B90	0x5570	0x5BF3	# <CJK>
+0x9B91	0x5571	0x5C05	# <CJK>
+0x9B92	0x5572	0x5C07	# <CJK>
+0x9B93	0x5573	0x5C08	# <CJK>
+0x9B94	0x5574	0x5C0D	# <CJK>
+0x9B95	0x5575	0x5C13	# <CJK>
+0x9B96	0x5576	0x5C20	# <CJK>
+0x9B97	0x5577	0x5C22	# <CJK>
+0x9B98	0x5578	0x5C28	# <CJK>
+0x9B99	0x5579	0x5C38	# <CJK>
+0x9B9A	0x557A	0x5C39	# <CJK>
+0x9B9B	0x557B	0x5C41	# <CJK>
+0x9B9C	0x557C	0x5C46	# <CJK>
+0x9B9D	0x557D	0x5C4E	# <CJK>
+0x9B9E	0x557E	0x5C53	# <CJK>
+0x9B9F	0x5621	0x5C50	# <CJK>
+0x9BA0	0x5622	0x5C4F	# <CJK>
+0x9BA1	0x5623	0x5B71	# <CJK>
+0x9BA2	0x5624	0x5C6C	# <CJK>
+0x9BA3	0x5625	0x5C6E	# <CJK>
+0x9BA4	0x5626	0x4E62	# <CJK>
+0x9BA5	0x5627	0x5C76	# <CJK>
+0x9BA6	0x5628	0x5C79	# <CJK>
+0x9BA7	0x5629	0x5C8C	# <CJK>
+0x9BA8	0x562A	0x5C91	# <CJK>
+0x9BA9	0x562B	0x5C94	# <CJK>
+0x9BAA	0x562C	0x599B	# <CJK>
+0x9BAB	0x562D	0x5CAB	# <CJK>
+0x9BAC	0x562E	0x5CBB	# <CJK>
+0x9BAD	0x562F	0x5CB6	# <CJK>
+0x9BAE	0x5630	0x5CBC	# <CJK>
+0x9BAF	0x5631	0x5CB7	# <CJK>
+0x9BB0	0x5632	0x5CC5	# <CJK>
+0x9BB1	0x5633	0x5CBE	# <CJK>
+0x9BB2	0x5634	0x5CC7	# <CJK>
+0x9BB3	0x5635	0x5CD9	# <CJK>
+0x9BB4	0x5636	0x5CE9	# <CJK>
+0x9BB5	0x5637	0x5CFD	# <CJK>
+0x9BB6	0x5638	0x5CFA	# <CJK>
+0x9BB7	0x5639	0x5CED	# <CJK>
+0x9BB8	0x563A	0x5D8C	# <CJK>
+0x9BB9	0x563B	0x5CEA	# <CJK>
+0x9BBA	0x563C	0x5D0B	# <CJK>
+0x9BBB	0x563D	0x5D15	# <CJK>
+0x9BBC	0x563E	0x5D17	# <CJK>
+0x9BBD	0x563F	0x5D5C	# <CJK>
+0x9BBE	0x5640	0x5D1F	# <CJK>
+0x9BBF	0x5641	0x5D1B	# <CJK>
+0x9BC0	0x5642	0x5D11	# <CJK>
+0x9BC1	0x5643	0x5D14	# <CJK>
+0x9BC2	0x5644	0x5D22	# <CJK>
+0x9BC3	0x5645	0x5D1A	# <CJK>
+0x9BC4	0x5646	0x5D19	# <CJK>
+0x9BC5	0x5647	0x5D18	# <CJK>
+0x9BC6	0x5648	0x5D4C	# <CJK>
+0x9BC7	0x5649	0x5D52	# <CJK>
+0x9BC8	0x564A	0x5D4E	# <CJK>
+0x9BC9	0x564B	0x5D4B	# <CJK>
+0x9BCA	0x564C	0x5D6C	# <CJK>
+0x9BCB	0x564D	0x5D73	# <CJK>
+0x9BCC	0x564E	0x5D76	# <CJK>
+0x9BCD	0x564F	0x5D87	# <CJK>
+0x9BCE	0x5650	0x5D84	# <CJK>
+0x9BCF	0x5651	0x5D82	# <CJK>
+0x9BD0	0x5652	0x5DA2	# <CJK>
+0x9BD1	0x5653	0x5D9D	# <CJK>
+0x9BD2	0x5654	0x5DAC	# <CJK>
+0x9BD3	0x5655	0x5DAE	# <CJK>
+0x9BD4	0x5656	0x5DBD	# <CJK>
+0x9BD5	0x5657	0x5D90	# <CJK>
+0x9BD6	0x5658	0x5DB7	# <CJK>
+0x9BD7	0x5659	0x5DBC	# <CJK>
+0x9BD8	0x565A	0x5DC9	# <CJK>
+0x9BD9	0x565B	0x5DCD	# <CJK>
+0x9BDA	0x565C	0x5DD3	# <CJK>
+0x9BDB	0x565D	0x5DD2	# <CJK>
+0x9BDC	0x565E	0x5DD6	# <CJK>
+0x9BDD	0x565F	0x5DDB	# <CJK>
+0x9BDE	0x5660	0x5DEB	# <CJK>
+0x9BDF	0x5661	0x5DF2	# <CJK>
+0x9BE0	0x5662	0x5DF5	# <CJK>
+0x9BE1	0x5663	0x5E0B	# <CJK>
+0x9BE2	0x5664	0x5E1A	# <CJK>
+0x9BE3	0x5665	0x5E19	# <CJK>
+0x9BE4	0x5666	0x5E11	# <CJK>
+0x9BE5	0x5667	0x5E1B	# <CJK>
+0x9BE6	0x5668	0x5E36	# <CJK>
+0x9BE7	0x5669	0x5E37	# <CJK>
+0x9BE8	0x566A	0x5E44	# <CJK>
+0x9BE9	0x566B	0x5E43	# <CJK>
+0x9BEA	0x566C	0x5E40	# <CJK>
+0x9BEB	0x566D	0x5E4E	# <CJK>
+0x9BEC	0x566E	0x5E57	# <CJK>
+0x9BED	0x566F	0x5E54	# <CJK>
+0x9BEE	0x5670	0x5E5F	# <CJK>
+0x9BEF	0x5671	0x5E62	# <CJK>
+0x9BF0	0x5672	0x5E64	# <CJK>
+0x9BF1	0x5673	0x5E47	# <CJK>
+0x9BF2	0x5674	0x5E75	# <CJK>
+0x9BF3	0x5675	0x5E76	# <CJK>
+0x9BF4	0x5676	0x5E7A	# <CJK>
+0x9BF5	0x5677	0x9EBC	# <CJK>
+0x9BF6	0x5678	0x5E7F	# <CJK>
+0x9BF7	0x5679	0x5EA0	# <CJK>
+0x9BF8	0x567A	0x5EC1	# <CJK>
+0x9BF9	0x567B	0x5EC2	# <CJK>
+0x9BFA	0x567C	0x5EC8	# <CJK>
+0x9BFB	0x567D	0x5ED0	# <CJK>
+0x9BFC	0x567E	0x5ECF	# <CJK>
+0x9C40	0x5721	0x5ED6	# <CJK>
+0x9C41	0x5722	0x5EE3	# <CJK>
+0x9C42	0x5723	0x5EDD	# <CJK>
+0x9C43	0x5724	0x5EDA	# <CJK>
+0x9C44	0x5725	0x5EDB	# <CJK>
+0x9C45	0x5726	0x5EE2	# <CJK>
+0x9C46	0x5727	0x5EE1	# <CJK>
+0x9C47	0x5728	0x5EE8	# <CJK>
+0x9C48	0x5729	0x5EE9	# <CJK>
+0x9C49	0x572A	0x5EEC	# <CJK>
+0x9C4A	0x572B	0x5EF1	# <CJK>
+0x9C4B	0x572C	0x5EF3	# <CJK>
+0x9C4C	0x572D	0x5EF0	# <CJK>
+0x9C4D	0x572E	0x5EF4	# <CJK>
+0x9C4E	0x572F	0x5EF8	# <CJK>
+0x9C4F	0x5730	0x5EFE	# <CJK>
+0x9C50	0x5731	0x5F03	# <CJK>
+0x9C51	0x5732	0x5F09	# <CJK>
+0x9C52	0x5733	0x5F5D	# <CJK>
+0x9C53	0x5734	0x5F5C	# <CJK>
+0x9C54	0x5735	0x5F0B	# <CJK>
+0x9C55	0x5736	0x5F11	# <CJK>
+0x9C56	0x5737	0x5F16	# <CJK>
+0x9C57	0x5738	0x5F29	# <CJK>
+0x9C58	0x5739	0x5F2D	# <CJK>
+0x9C59	0x573A	0x5F38	# <CJK>
+0x9C5A	0x573B	0x5F41	# <CJK>
+0x9C5B	0x573C	0x5F48	# <CJK>
+0x9C5C	0x573D	0x5F4C	# <CJK>
+0x9C5D	0x573E	0x5F4E	# <CJK>
+0x9C5E	0x573F	0x5F2F	# <CJK>
+0x9C5F	0x5740	0x5F51	# <CJK>
+0x9C60	0x5741	0x5F56	# <CJK>
+0x9C61	0x5742	0x5F57	# <CJK>
+0x9C62	0x5743	0x5F59	# <CJK>
+0x9C63	0x5744	0x5F61	# <CJK>
+0x9C64	0x5745	0x5F6D	# <CJK>
+0x9C65	0x5746	0x5F73	# <CJK>
+0x9C66	0x5747	0x5F77	# <CJK>
+0x9C67	0x5748	0x5F83	# <CJK>
+0x9C68	0x5749	0x5F82	# <CJK>
+0x9C69	0x574A	0x5F7F	# <CJK>
+0x9C6A	0x574B	0x5F8A	# <CJK>
+0x9C6B	0x574C	0x5F88	# <CJK>
+0x9C6C	0x574D	0x5F91	# <CJK>
+0x9C6D	0x574E	0x5F87	# <CJK>
+0x9C6E	0x574F	0x5F9E	# <CJK>
+0x9C6F	0x5750	0x5F99	# <CJK>
+0x9C70	0x5751	0x5F98	# <CJK>
+0x9C71	0x5752	0x5FA0	# <CJK>
+0x9C72	0x5753	0x5FA8	# <CJK>
+0x9C73	0x5754	0x5FAD	# <CJK>
+0x9C74	0x5755	0x5FBC	# <CJK>
+0x9C75	0x5756	0x5FD6	# <CJK>
+0x9C76	0x5757	0x5FFB	# <CJK>
+0x9C77	0x5758	0x5FE4	# <CJK>
+0x9C78	0x5759	0x5FF8	# <CJK>
+0x9C79	0x575A	0x5FF1	# <CJK>
+0x9C7A	0x575B	0x5FDD	# <CJK>
+0x9C7B	0x575C	0x60B3	# <CJK>
+0x9C7C	0x575D	0x5FFF	# <CJK>
+0x9C7D	0x575E	0x6021	# <CJK>
+0x9C7E	0x575F	0x6060	# <CJK>
+0x9C80	0x5760	0x6019	# <CJK>
+0x9C81	0x5761	0x6010	# <CJK>
+0x9C82	0x5762	0x6029	# <CJK>
+0x9C83	0x5763	0x600E	# <CJK>
+0x9C84	0x5764	0x6031	# <CJK>
+0x9C85	0x5765	0x601B	# <CJK>
+0x9C86	0x5766	0x6015	# <CJK>
+0x9C87	0x5767	0x602B	# <CJK>
+0x9C88	0x5768	0x6026	# <CJK>
+0x9C89	0x5769	0x600F	# <CJK>
+0x9C8A	0x576A	0x603A	# <CJK>
+0x9C8B	0x576B	0x605A	# <CJK>
+0x9C8C	0x576C	0x6041	# <CJK>
+0x9C8D	0x576D	0x606A	# <CJK>
+0x9C8E	0x576E	0x6077	# <CJK>
+0x9C8F	0x576F	0x605F	# <CJK>
+0x9C90	0x5770	0x604A	# <CJK>
+0x9C91	0x5771	0x6046	# <CJK>
+0x9C92	0x5772	0x604D	# <CJK>
+0x9C93	0x5773	0x6063	# <CJK>
+0x9C94	0x5774	0x6043	# <CJK>
+0x9C95	0x5775	0x6064	# <CJK>
+0x9C96	0x5776	0x6042	# <CJK>
+0x9C97	0x5777	0x606C	# <CJK>
+0x9C98	0x5778	0x606B	# <CJK>
+0x9C99	0x5779	0x6059	# <CJK>
+0x9C9A	0x577A	0x6081	# <CJK>
+0x9C9B	0x577B	0x608D	# <CJK>
+0x9C9C	0x577C	0x60E7	# <CJK>
+0x9C9D	0x577D	0x6083	# <CJK>
+0x9C9E	0x577E	0x609A	# <CJK>
+0x9C9F	0x5821	0x6084	# <CJK>
+0x9CA0	0x5822	0x609B	# <CJK>
+0x9CA1	0x5823	0x6096	# <CJK>
+0x9CA2	0x5824	0x6097	# <CJK>
+0x9CA3	0x5825	0x6092	# <CJK>
+0x9CA4	0x5826	0x60A7	# <CJK>
+0x9CA5	0x5827	0x608B	# <CJK>
+0x9CA6	0x5828	0x60E1	# <CJK>
+0x9CA7	0x5829	0x60B8	# <CJK>
+0x9CA8	0x582A	0x60E0	# <CJK>
+0x9CA9	0x582B	0x60D3	# <CJK>
+0x9CAA	0x582C	0x60B4	# <CJK>
+0x9CAB	0x582D	0x5FF0	# <CJK>
+0x9CAC	0x582E	0x60BD	# <CJK>
+0x9CAD	0x582F	0x60C6	# <CJK>
+0x9CAE	0x5830	0x60B5	# <CJK>
+0x9CAF	0x5831	0x60D8	# <CJK>
+0x9CB0	0x5832	0x614D	# <CJK>
+0x9CB1	0x5833	0x6115	# <CJK>
+0x9CB2	0x5834	0x6106	# <CJK>
+0x9CB3	0x5835	0x60F6	# <CJK>
+0x9CB4	0x5836	0x60F7	# <CJK>
+0x9CB5	0x5837	0x6100	# <CJK>
+0x9CB6	0x5838	0x60F4	# <CJK>
+0x9CB7	0x5839	0x60FA	# <CJK>
+0x9CB8	0x583A	0x6103	# <CJK>
+0x9CB9	0x583B	0x6121	# <CJK>
+0x9CBA	0x583C	0x60FB	# <CJK>
+0x9CBB	0x583D	0x60F1	# <CJK>
+0x9CBC	0x583E	0x610D	# <CJK>
+0x9CBD	0x583F	0x610E	# <CJK>
+0x9CBE	0x5840	0x6147	# <CJK>
+0x9CBF	0x5841	0x613E	# <CJK>
+0x9CC0	0x5842	0x6128	# <CJK>
+0x9CC1	0x5843	0x6127	# <CJK>
+0x9CC2	0x5844	0x614A	# <CJK>
+0x9CC3	0x5845	0x613F	# <CJK>
+0x9CC4	0x5846	0x613C	# <CJK>
+0x9CC5	0x5847	0x612C	# <CJK>
+0x9CC6	0x5848	0x6134	# <CJK>
+0x9CC7	0x5849	0x613D	# <CJK>
+0x9CC8	0x584A	0x6142	# <CJK>
+0x9CC9	0x584B	0x6144	# <CJK>
+0x9CCA	0x584C	0x6173	# <CJK>
+0x9CCB	0x584D	0x6177	# <CJK>
+0x9CCC	0x584E	0x6158	# <CJK>
+0x9CCD	0x584F	0x6159	# <CJK>
+0x9CCE	0x5850	0x615A	# <CJK>
+0x9CCF	0x5851	0x616B	# <CJK>
+0x9CD0	0x5852	0x6174	# <CJK>
+0x9CD1	0x5853	0x616F	# <CJK>
+0x9CD2	0x5854	0x6165	# <CJK>
+0x9CD3	0x5855	0x6171	# <CJK>
+0x9CD4	0x5856	0x615F	# <CJK>
+0x9CD5	0x5857	0x615D	# <CJK>
+0x9CD6	0x5858	0x6153	# <CJK>
+0x9CD7	0x5859	0x6175	# <CJK>
+0x9CD8	0x585A	0x6199	# <CJK>
+0x9CD9	0x585B	0x6196	# <CJK>
+0x9CDA	0x585C	0x6187	# <CJK>
+0x9CDB	0x585D	0x61AC	# <CJK>
+0x9CDC	0x585E	0x6194	# <CJK>
+0x9CDD	0x585F	0x619A	# <CJK>
+0x9CDE	0x5860	0x618A	# <CJK>
+0x9CDF	0x5861	0x6191	# <CJK>
+0x9CE0	0x5862	0x61AB	# <CJK>
+0x9CE1	0x5863	0x61AE	# <CJK>
+0x9CE2	0x5864	0x61CC	# <CJK>
+0x9CE3	0x5865	0x61CA	# <CJK>
+0x9CE4	0x5866	0x61C9	# <CJK>
+0x9CE5	0x5867	0x61F7	# <CJK>
+0x9CE6	0x5868	0x61C8	# <CJK>
+0x9CE7	0x5869	0x61C3	# <CJK>
+0x9CE8	0x586A	0x61C6	# <CJK>
+0x9CE9	0x586B	0x61BA	# <CJK>
+0x9CEA	0x586C	0x61CB	# <CJK>
+0x9CEB	0x586D	0x7F79	# <CJK>
+0x9CEC	0x586E	0x61CD	# <CJK>
+0x9CED	0x586F	0x61E6	# <CJK>
+0x9CEE	0x5870	0x61E3	# <CJK>
+0x9CEF	0x5871	0x61F6	# <CJK>
+0x9CF0	0x5872	0x61FA	# <CJK>
+0x9CF1	0x5873	0x61F4	# <CJK>
+0x9CF2	0x5874	0x61FF	# <CJK>
+0x9CF3	0x5875	0x61FD	# <CJK>
+0x9CF4	0x5876	0x61FC	# <CJK>
+0x9CF5	0x5877	0x61FE	# <CJK>
+0x9CF6	0x5878	0x6200	# <CJK>
+0x9CF7	0x5879	0x6208	# <CJK>
+0x9CF8	0x587A	0x6209	# <CJK>
+0x9CF9	0x587B	0x620D	# <CJK>
+0x9CFA	0x587C	0x620C	# <CJK>
+0x9CFB	0x587D	0x6214	# <CJK>
+0x9CFC	0x587E	0x621B	# <CJK>
+0x9D40	0x5921	0x621E	# <CJK>
+0x9D41	0x5922	0x6221	# <CJK>
+0x9D42	0x5923	0x622A	# <CJK>
+0x9D43	0x5924	0x622E	# <CJK>
+0x9D44	0x5925	0x6230	# <CJK>
+0x9D45	0x5926	0x6232	# <CJK>
+0x9D46	0x5927	0x6233	# <CJK>
+0x9D47	0x5928	0x6241	# <CJK>
+0x9D48	0x5929	0x624E	# <CJK>
+0x9D49	0x592A	0x625E	# <CJK>
+0x9D4A	0x592B	0x6263	# <CJK>
+0x9D4B	0x592C	0x625B	# <CJK>
+0x9D4C	0x592D	0x6260	# <CJK>
+0x9D4D	0x592E	0x6268	# <CJK>
+0x9D4E	0x592F	0x627C	# <CJK>
+0x9D4F	0x5930	0x6282	# <CJK>
+0x9D50	0x5931	0x6289	# <CJK>
+0x9D51	0x5932	0x627E	# <CJK>
+0x9D52	0x5933	0x6292	# <CJK>
+0x9D53	0x5934	0x6293	# <CJK>
+0x9D54	0x5935	0x6296	# <CJK>
+0x9D55	0x5936	0x62D4	# <CJK>
+0x9D56	0x5937	0x6283	# <CJK>
+0x9D57	0x5938	0x6294	# <CJK>
+0x9D58	0x5939	0x62D7	# <CJK>
+0x9D59	0x593A	0x62D1	# <CJK>
+0x9D5A	0x593B	0x62BB	# <CJK>
+0x9D5B	0x593C	0x62CF	# <CJK>
+0x9D5C	0x593D	0x62FF	# <CJK>
+0x9D5D	0x593E	0x62C6	# <CJK>
+0x9D5E	0x593F	0x64D4	# <CJK>
+0x9D5F	0x5940	0x62C8	# <CJK>
+0x9D60	0x5941	0x62DC	# <CJK>
+0x9D61	0x5942	0x62CC	# <CJK>
+0x9D62	0x5943	0x62CA	# <CJK>
+0x9D63	0x5944	0x62C2	# <CJK>
+0x9D64	0x5945	0x62C7	# <CJK>
+0x9D65	0x5946	0x629B	# <CJK>
+0x9D66	0x5947	0x62C9	# <CJK>
+0x9D67	0x5948	0x630C	# <CJK>
+0x9D68	0x5949	0x62EE	# <CJK>
+0x9D69	0x594A	0x62F1	# <CJK>
+0x9D6A	0x594B	0x6327	# <CJK>
+0x9D6B	0x594C	0x6302	# <CJK>
+0x9D6C	0x594D	0x6308	# <CJK>
+0x9D6D	0x594E	0x62EF	# <CJK>
+0x9D6E	0x594F	0x62F5	# <CJK>
+0x9D6F	0x5950	0x6350	# <CJK>
+0x9D70	0x5951	0x633E	# <CJK>
+0x9D71	0x5952	0x634D	# <CJK>
+0x9D72	0x5953	0x641C	# <CJK>
+0x9D73	0x5954	0x634F	# <CJK>
+0x9D74	0x5955	0x6396	# <CJK>
+0x9D75	0x5956	0x638E	# <CJK>
+0x9D76	0x5957	0x6380	# <CJK>
+0x9D77	0x5958	0x63AB	# <CJK>
+0x9D78	0x5959	0x6376	# <CJK>
+0x9D79	0x595A	0x63A3	# <CJK>
+0x9D7A	0x595B	0x638F	# <CJK>
+0x9D7B	0x595C	0x6389	# <CJK>
+0x9D7C	0x595D	0x639F	# <CJK>
+0x9D7D	0x595E	0x63B5	# <CJK>
+0x9D7E	0x595F	0x636B	# <CJK>
+0x9D80	0x5960	0x6369	# <CJK>
+0x9D81	0x5961	0x63BE	# <CJK>
+0x9D82	0x5962	0x63E9	# <CJK>
+0x9D83	0x5963	0x63C0	# <CJK>
+0x9D84	0x5964	0x63C6	# <CJK>
+0x9D85	0x5965	0x63E3	# <CJK>
+0x9D86	0x5966	0x63C9	# <CJK>
+0x9D87	0x5967	0x63D2	# <CJK>
+0x9D88	0x5968	0x63F6	# <CJK>
+0x9D89	0x5969	0x63C4	# <CJK>
+0x9D8A	0x596A	0x6416	# <CJK>
+0x9D8B	0x596B	0x6434	# <CJK>
+0x9D8C	0x596C	0x6406	# <CJK>
+0x9D8D	0x596D	0x6413	# <CJK>
+0x9D8E	0x596E	0x6426	# <CJK>
+0x9D8F	0x596F	0x6436	# <CJK>
+0x9D90	0x5970	0x651D	# <CJK>
+0x9D91	0x5971	0x6417	# <CJK>
+0x9D92	0x5972	0x6428	# <CJK>
+0x9D93	0x5973	0x640F	# <CJK>
+0x9D94	0x5974	0x6467	# <CJK>
+0x9D95	0x5975	0x646F	# <CJK>
+0x9D96	0x5976	0x6476	# <CJK>
+0x9D97	0x5977	0x644E	# <CJK>
+0x9D98	0x5978	0x652A	# <CJK>
+0x9D99	0x5979	0x6495	# <CJK>
+0x9D9A	0x597A	0x6493	# <CJK>
+0x9D9B	0x597B	0x64A5	# <CJK>
+0x9D9C	0x597C	0x64A9	# <CJK>
+0x9D9D	0x597D	0x6488	# <CJK>
+0x9D9E	0x597E	0x64BC	# <CJK>
+0x9D9F	0x5A21	0x64DA	# <CJK>
+0x9DA0	0x5A22	0x64D2	# <CJK>
+0x9DA1	0x5A23	0x64C5	# <CJK>
+0x9DA2	0x5A24	0x64C7	# <CJK>
+0x9DA3	0x5A25	0x64BB	# <CJK>
+0x9DA4	0x5A26	0x64D8	# <CJK>
+0x9DA5	0x5A27	0x64C2	# <CJK>
+0x9DA6	0x5A28	0x64F1	# <CJK>
+0x9DA7	0x5A29	0x64E7	# <CJK>
+0x9DA8	0x5A2A	0x8209	# <CJK>
+0x9DA9	0x5A2B	0x64E0	# <CJK>
+0x9DAA	0x5A2C	0x64E1	# <CJK>
+0x9DAB	0x5A2D	0x62AC	# <CJK>
+0x9DAC	0x5A2E	0x64E3	# <CJK>
+0x9DAD	0x5A2F	0x64EF	# <CJK>
+0x9DAE	0x5A30	0x652C	# <CJK>
+0x9DAF	0x5A31	0x64F6	# <CJK>
+0x9DB0	0x5A32	0x64F4	# <CJK>
+0x9DB1	0x5A33	0x64F2	# <CJK>
+0x9DB2	0x5A34	0x64FA	# <CJK>
+0x9DB3	0x5A35	0x6500	# <CJK>
+0x9DB4	0x5A36	0x64FD	# <CJK>
+0x9DB5	0x5A37	0x6518	# <CJK>
+0x9DB6	0x5A38	0x651C	# <CJK>
+0x9DB7	0x5A39	0x6505	# <CJK>
+0x9DB8	0x5A3A	0x6524	# <CJK>
+0x9DB9	0x5A3B	0x6523	# <CJK>
+0x9DBA	0x5A3C	0x652B	# <CJK>
+0x9DBB	0x5A3D	0x6534	# <CJK>
+0x9DBC	0x5A3E	0x6535	# <CJK>
+0x9DBD	0x5A3F	0x6537	# <CJK>
+0x9DBE	0x5A40	0x6536	# <CJK>
+0x9DBF	0x5A41	0x6538	# <CJK>
+0x9DC0	0x5A42	0x754B	# <CJK>
+0x9DC1	0x5A43	0x6548	# <CJK>
+0x9DC2	0x5A44	0x6556	# <CJK>
+0x9DC3	0x5A45	0x6555	# <CJK>
+0x9DC4	0x5A46	0x654D	# <CJK>
+0x9DC5	0x5A47	0x6558	# <CJK>
+0x9DC6	0x5A48	0x655E	# <CJK>
+0x9DC7	0x5A49	0x655D	# <CJK>
+0x9DC8	0x5A4A	0x6572	# <CJK>
+0x9DC9	0x5A4B	0x6578	# <CJK>
+0x9DCA	0x5A4C	0x6582	# <CJK>
+0x9DCB	0x5A4D	0x6583	# <CJK>
+0x9DCC	0x5A4E	0x8B8A	# <CJK>
+0x9DCD	0x5A4F	0x659B	# <CJK>
+0x9DCE	0x5A50	0x659F	# <CJK>
+0x9DCF	0x5A51	0x65AB	# <CJK>
+0x9DD0	0x5A52	0x65B7	# <CJK>
+0x9DD1	0x5A53	0x65C3	# <CJK>
+0x9DD2	0x5A54	0x65C6	# <CJK>
+0x9DD3	0x5A55	0x65C1	# <CJK>
+0x9DD4	0x5A56	0x65C4	# <CJK>
+0x9DD5	0x5A57	0x65CC	# <CJK>
+0x9DD6	0x5A58	0x65D2	# <CJK>
+0x9DD7	0x5A59	0x65DB	# <CJK>
+0x9DD8	0x5A5A	0x65D9	# <CJK>
+0x9DD9	0x5A5B	0x65E0	# <CJK>
+0x9DDA	0x5A5C	0x65E1	# <CJK>
+0x9DDB	0x5A5D	0x65F1	# <CJK>
+0x9DDC	0x5A5E	0x6772	# <CJK>
+0x9DDD	0x5A5F	0x660A	# <CJK>
+0x9DDE	0x5A60	0x6603	# <CJK>
+0x9DDF	0x5A61	0x65FB	# <CJK>
+0x9DE0	0x5A62	0x6773	# <CJK>
+0x9DE1	0x5A63	0x6635	# <CJK>
+0x9DE2	0x5A64	0x6636	# <CJK>
+0x9DE3	0x5A65	0x6634	# <CJK>
+0x9DE4	0x5A66	0x661C	# <CJK>
+0x9DE5	0x5A67	0x664F	# <CJK>
+0x9DE6	0x5A68	0x6644	# <CJK>
+0x9DE7	0x5A69	0x6649	# <CJK>
+0x9DE8	0x5A6A	0x6641	# <CJK>
+0x9DE9	0x5A6B	0x665E	# <CJK>
+0x9DEA	0x5A6C	0x665D	# <CJK>
+0x9DEB	0x5A6D	0x6664	# <CJK>
+0x9DEC	0x5A6E	0x6667	# <CJK>
+0x9DED	0x5A6F	0x6668	# <CJK>
+0x9DEE	0x5A70	0x665F	# <CJK>
+0x9DEF	0x5A71	0x6662	# <CJK>
+0x9DF0	0x5A72	0x6670	# <CJK>
+0x9DF1	0x5A73	0x6683	# <CJK>
+0x9DF2	0x5A74	0x6688	# <CJK>
+0x9DF3	0x5A75	0x668E	# <CJK>
+0x9DF4	0x5A76	0x6689	# <CJK>
+0x9DF5	0x5A77	0x6684	# <CJK>
+0x9DF6	0x5A78	0x6698	# <CJK>
+0x9DF7	0x5A79	0x669D	# <CJK>
+0x9DF8	0x5A7A	0x66C1	# <CJK>
+0x9DF9	0x5A7B	0x66B9	# <CJK>
+0x9DFA	0x5A7C	0x66C9	# <CJK>
+0x9DFB	0x5A7D	0x66BE	# <CJK>
+0x9DFC	0x5A7E	0x66BC	# <CJK>
+0x9E40	0x5B21	0x66C4	# <CJK>
+0x9E41	0x5B22	0x66B8	# <CJK>
+0x9E42	0x5B23	0x66D6	# <CJK>
+0x9E43	0x5B24	0x66DA	# <CJK>
+0x9E44	0x5B25	0x66E0	# <CJK>
+0x9E45	0x5B26	0x663F	# <CJK>
+0x9E46	0x5B27	0x66E6	# <CJK>
+0x9E47	0x5B28	0x66E9	# <CJK>
+0x9E48	0x5B29	0x66F0	# <CJK>
+0x9E49	0x5B2A	0x66F5	# <CJK>
+0x9E4A	0x5B2B	0x66F7	# <CJK>
+0x9E4B	0x5B2C	0x670F	# <CJK>
+0x9E4C	0x5B2D	0x6716	# <CJK>
+0x9E4D	0x5B2E	0x671E	# <CJK>
+0x9E4E	0x5B2F	0x6726	# <CJK>
+0x9E4F	0x5B30	0x6727	# <CJK>
+0x9E50	0x5B31	0x9738	# <CJK>
+0x9E51	0x5B32	0x672E	# <CJK>
+0x9E52	0x5B33	0x673F	# <CJK>
+0x9E53	0x5B34	0x6736	# <CJK>
+0x9E54	0x5B35	0x6741	# <CJK>
+0x9E55	0x5B36	0x6738	# <CJK>
+0x9E56	0x5B37	0x6737	# <CJK>
+0x9E57	0x5B38	0x6746	# <CJK>
+0x9E58	0x5B39	0x675E	# <CJK>
+0x9E59	0x5B3A	0x6760	# <CJK>
+0x9E5A	0x5B3B	0x6759	# <CJK>
+0x9E5B	0x5B3C	0x6763	# <CJK>
+0x9E5C	0x5B3D	0x6764	# <CJK>
+0x9E5D	0x5B3E	0x6789	# <CJK>
+0x9E5E	0x5B3F	0x6770	# <CJK>
+0x9E5F	0x5B40	0x67A9	# <CJK>
+0x9E60	0x5B41	0x677C	# <CJK>
+0x9E61	0x5B42	0x676A	# <CJK>
+0x9E62	0x5B43	0x678C	# <CJK>
+0x9E63	0x5B44	0x678B	# <CJK>
+0x9E64	0x5B45	0x67A6	# <CJK>
+0x9E65	0x5B46	0x67A1	# <CJK>
+0x9E66	0x5B47	0x6785	# <CJK>
+0x9E67	0x5B48	0x67B7	# <CJK>
+0x9E68	0x5B49	0x67EF	# <CJK>
+0x9E69	0x5B4A	0x67B4	# <CJK>
+0x9E6A	0x5B4B	0x67EC	# <CJK>
+0x9E6B	0x5B4C	0x67B3	# <CJK>
+0x9E6C	0x5B4D	0x67E9	# <CJK>
+0x9E6D	0x5B4E	0x67B8	# <CJK>
+0x9E6E	0x5B4F	0x67E4	# <CJK>
+0x9E6F	0x5B50	0x67DE	# <CJK>
+0x9E70	0x5B51	0x67DD	# <CJK>
+0x9E71	0x5B52	0x67E2	# <CJK>
+0x9E72	0x5B53	0x67EE	# <CJK>
+0x9E73	0x5B54	0x67B9	# <CJK>
+0x9E74	0x5B55	0x67CE	# <CJK>
+0x9E75	0x5B56	0x67C6	# <CJK>
+0x9E76	0x5B57	0x67E7	# <CJK>
+0x9E77	0x5B58	0x6A9C	# <CJK>
+0x9E78	0x5B59	0x681E	# <CJK>
+0x9E79	0x5B5A	0x6846	# <CJK>
+0x9E7A	0x5B5B	0x6829	# <CJK>
+0x9E7B	0x5B5C	0x6840	# <CJK>
+0x9E7C	0x5B5D	0x684D	# <CJK>
+0x9E7D	0x5B5E	0x6832	# <CJK>
+0x9E7E	0x5B5F	0x684E	# <CJK>
+0x9E80	0x5B60	0x68B3	# <CJK>
+0x9E81	0x5B61	0x682B	# <CJK>
+0x9E82	0x5B62	0x6859	# <CJK>
+0x9E83	0x5B63	0x6863	# <CJK>
+0x9E84	0x5B64	0x6877	# <CJK>
+0x9E85	0x5B65	0x687F	# <CJK>
+0x9E86	0x5B66	0x689F	# <CJK>
+0x9E87	0x5B67	0x688F	# <CJK>
+0x9E88	0x5B68	0x68AD	# <CJK>
+0x9E89	0x5B69	0x6894	# <CJK>
+0x9E8A	0x5B6A	0x689D	# <CJK>
+0x9E8B	0x5B6B	0x689B	# <CJK>
+0x9E8C	0x5B6C	0x6883	# <CJK>
+0x9E8D	0x5B6D	0x6AAE	# <CJK>
+0x9E8E	0x5B6E	0x68B9	# <CJK>
+0x9E8F	0x5B6F	0x6874	# <CJK>
+0x9E90	0x5B70	0x68B5	# <CJK>
+0x9E91	0x5B71	0x68A0	# <CJK>
+0x9E92	0x5B72	0x68BA	# <CJK>
+0x9E93	0x5B73	0x690F	# <CJK>
+0x9E94	0x5B74	0x688D	# <CJK>
+0x9E95	0x5B75	0x687E	# <CJK>
+0x9E96	0x5B76	0x6901	# <CJK>
+0x9E97	0x5B77	0x68CA	# <CJK>
+0x9E98	0x5B78	0x6908	# <CJK>
+0x9E99	0x5B79	0x68D8	# <CJK>
+0x9E9A	0x5B7A	0x6922	# <CJK>
+0x9E9B	0x5B7B	0x6926	# <CJK>
+0x9E9C	0x5B7C	0x68E1	# <CJK>
+0x9E9D	0x5B7D	0x690C	# <CJK>
+0x9E9E	0x5B7E	0x68CD	# <CJK>
+0x9E9F	0x5C21	0x68D4	# <CJK>
+0x9EA0	0x5C22	0x68E7	# <CJK>
+0x9EA1	0x5C23	0x68D5	# <CJK>
+0x9EA2	0x5C24	0x6936	# <CJK>
+0x9EA3	0x5C25	0x6912	# <CJK>
+0x9EA4	0x5C26	0x6904	# <CJK>
+0x9EA5	0x5C27	0x68D7	# <CJK>
+0x9EA6	0x5C28	0x68E3	# <CJK>
+0x9EA7	0x5C29	0x6925	# <CJK>
+0x9EA8	0x5C2A	0x68F9	# <CJK>
+0x9EA9	0x5C2B	0x68E0	# <CJK>
+0x9EAA	0x5C2C	0x68EF	# <CJK>
+0x9EAB	0x5C2D	0x6928	# <CJK>
+0x9EAC	0x5C2E	0x692A	# <CJK>
+0x9EAD	0x5C2F	0x691A	# <CJK>
+0x9EAE	0x5C30	0x6923	# <CJK>
+0x9EAF	0x5C31	0x6921	# <CJK>
+0x9EB0	0x5C32	0x68C6	# <CJK>
+0x9EB1	0x5C33	0x6979	# <CJK>
+0x9EB2	0x5C34	0x6977	# <CJK>
+0x9EB3	0x5C35	0x695C	# <CJK>
+0x9EB4	0x5C36	0x6978	# <CJK>
+0x9EB5	0x5C37	0x696B	# <CJK>
+0x9EB6	0x5C38	0x6954	# <CJK>
+0x9EB7	0x5C39	0x697E	# <CJK>
+0x9EB8	0x5C3A	0x696E	# <CJK>
+0x9EB9	0x5C3B	0x6939	# <CJK>
+0x9EBA	0x5C3C	0x6974	# <CJK>
+0x9EBB	0x5C3D	0x693D	# <CJK>
+0x9EBC	0x5C3E	0x6959	# <CJK>
+0x9EBD	0x5C3F	0x6930	# <CJK>
+0x9EBE	0x5C40	0x6961	# <CJK>
+0x9EBF	0x5C41	0x695E	# <CJK>
+0x9EC0	0x5C42	0x695D	# <CJK>
+0x9EC1	0x5C43	0x6981	# <CJK>
+0x9EC2	0x5C44	0x696A	# <CJK>
+0x9EC3	0x5C45	0x69B2	# <CJK>
+0x9EC4	0x5C46	0x69AE	# <CJK>
+0x9EC5	0x5C47	0x69D0	# <CJK>
+0x9EC6	0x5C48	0x69BF	# <CJK>
+0x9EC7	0x5C49	0x69C1	# <CJK>
+0x9EC8	0x5C4A	0x69D3	# <CJK>
+0x9EC9	0x5C4B	0x69BE	# <CJK>
+0x9ECA	0x5C4C	0x69CE	# <CJK>
+0x9ECB	0x5C4D	0x5BE8	# <CJK>
+0x9ECC	0x5C4E	0x69CA	# <CJK>
+0x9ECD	0x5C4F	0x69DD	# <CJK>
+0x9ECE	0x5C50	0x69BB	# <CJK>
+0x9ECF	0x5C51	0x69C3	# <CJK>
+0x9ED0	0x5C52	0x69A7	# <CJK>
+0x9ED1	0x5C53	0x6A2E	# <CJK>
+0x9ED2	0x5C54	0x6991	# <CJK>
+0x9ED3	0x5C55	0x69A0	# <CJK>
+0x9ED4	0x5C56	0x699C	# <CJK>
+0x9ED5	0x5C57	0x6995	# <CJK>
+0x9ED6	0x5C58	0x69B4	# <CJK>
+0x9ED7	0x5C59	0x69DE	# <CJK>
+0x9ED8	0x5C5A	0x69E8	# <CJK>
+0x9ED9	0x5C5B	0x6A02	# <CJK>
+0x9EDA	0x5C5C	0x6A1B	# <CJK>
+0x9EDB	0x5C5D	0x69FF	# <CJK>
+0x9EDC	0x5C5E	0x6B0A	# <CJK>
+0x9EDD	0x5C5F	0x69F9	# <CJK>
+0x9EDE	0x5C60	0x69F2	# <CJK>
+0x9EDF	0x5C61	0x69E7	# <CJK>
+0x9EE0	0x5C62	0x6A05	# <CJK>
+0x9EE1	0x5C63	0x69B1	# <CJK>
+0x9EE2	0x5C64	0x6A1E	# <CJK>
+0x9EE3	0x5C65	0x69ED	# <CJK>
+0x9EE4	0x5C66	0x6A14	# <CJK>
+0x9EE5	0x5C67	0x69EB	# <CJK>
+0x9EE6	0x5C68	0x6A0A	# <CJK>
+0x9EE7	0x5C69	0x6A12	# <CJK>
+0x9EE8	0x5C6A	0x6AC1	# <CJK>
+0x9EE9	0x5C6B	0x6A23	# <CJK>
+0x9EEA	0x5C6C	0x6A13	# <CJK>
+0x9EEB	0x5C6D	0x6A44	# <CJK>
+0x9EEC	0x5C6E	0x6A0C	# <CJK>
+0x9EED	0x5C6F	0x6A72	# <CJK>
+0x9EEE	0x5C70	0x6A36	# <CJK>
+0x9EEF	0x5C71	0x6A78	# <CJK>
+0x9EF0	0x5C72	0x6A47	# <CJK>
+0x9EF1	0x5C73	0x6A62	# <CJK>
+0x9EF2	0x5C74	0x6A59	# <CJK>
+0x9EF3	0x5C75	0x6A66	# <CJK>
+0x9EF4	0x5C76	0x6A48	# <CJK>
+0x9EF5	0x5C77	0x6A38	# <CJK>
+0x9EF6	0x5C78	0x6A22	# <CJK>
+0x9EF7	0x5C79	0x6A90	# <CJK>
+0x9EF8	0x5C7A	0x6A8D	# <CJK>
+0x9EF9	0x5C7B	0x6AA0	# <CJK>
+0x9EFA	0x5C7C	0x6A84	# <CJK>
+0x9EFB	0x5C7D	0x6AA2	# <CJK>
+0x9EFC	0x5C7E	0x6AA3	# <CJK>
+0x9F40	0x5D21	0x6A97	# <CJK>
+0x9F41	0x5D22	0x8617	# <CJK>
+0x9F42	0x5D23	0x6ABB	# <CJK>
+0x9F43	0x5D24	0x6AC3	# <CJK>
+0x9F44	0x5D25	0x6AC2	# <CJK>
+0x9F45	0x5D26	0x6AB8	# <CJK>
+0x9F46	0x5D27	0x6AB3	# <CJK>
+0x9F47	0x5D28	0x6AAC	# <CJK>
+0x9F48	0x5D29	0x6ADE	# <CJK>
+0x9F49	0x5D2A	0x6AD1	# <CJK>
+0x9F4A	0x5D2B	0x6ADF	# <CJK>
+0x9F4B	0x5D2C	0x6AAA	# <CJK>
+0x9F4C	0x5D2D	0x6ADA	# <CJK>
+0x9F4D	0x5D2E	0x6AEA	# <CJK>
+0x9F4E	0x5D2F	0x6AFB	# <CJK>
+0x9F4F	0x5D30	0x6B05	# <CJK>
+0x9F50	0x5D31	0x8616	# <CJK>
+0x9F51	0x5D32	0x6AFA	# <CJK>
+0x9F52	0x5D33	0x6B12	# <CJK>
+0x9F53	0x5D34	0x6B16	# <CJK>
+0x9F54	0x5D35	0x9B31	# <CJK>
+0x9F55	0x5D36	0x6B1F	# <CJK>
+0x9F56	0x5D37	0x6B38	# <CJK>
+0x9F57	0x5D38	0x6B37	# <CJK>
+0x9F58	0x5D39	0x76DC	# <CJK>
+0x9F59	0x5D3A	0x6B39	# <CJK>
+0x9F5A	0x5D3B	0x98EE	# <CJK>
+0x9F5B	0x5D3C	0x6B47	# <CJK>
+0x9F5C	0x5D3D	0x6B43	# <CJK>
+0x9F5D	0x5D3E	0x6B49	# <CJK>
+0x9F5E	0x5D3F	0x6B50	# <CJK>
+0x9F5F	0x5D40	0x6B59	# <CJK>
+0x9F60	0x5D41	0x6B54	# <CJK>
+0x9F61	0x5D42	0x6B5B	# <CJK>
+0x9F62	0x5D43	0x6B5F	# <CJK>
+0x9F63	0x5D44	0x6B61	# <CJK>
+0x9F64	0x5D45	0x6B78	# <CJK>
+0x9F65	0x5D46	0x6B79	# <CJK>
+0x9F66	0x5D47	0x6B7F	# <CJK>
+0x9F67	0x5D48	0x6B80	# <CJK>
+0x9F68	0x5D49	0x6B84	# <CJK>
+0x9F69	0x5D4A	0x6B83	# <CJK>
+0x9F6A	0x5D4B	0x6B8D	# <CJK>
+0x9F6B	0x5D4C	0x6B98	# <CJK>
+0x9F6C	0x5D4D	0x6B95	# <CJK>
+0x9F6D	0x5D4E	0x6B9E	# <CJK>
+0x9F6E	0x5D4F	0x6BA4	# <CJK>
+0x9F6F	0x5D50	0x6BAA	# <CJK>
+0x9F70	0x5D51	0x6BAB	# <CJK>
+0x9F71	0x5D52	0x6BAF	# <CJK>
+0x9F72	0x5D53	0x6BB2	# <CJK>
+0x9F73	0x5D54	0x6BB1	# <CJK>
+0x9F74	0x5D55	0x6BB3	# <CJK>
+0x9F75	0x5D56	0x6BB7	# <CJK>
+0x9F76	0x5D57	0x6BBC	# <CJK>
+0x9F77	0x5D58	0x6BC6	# <CJK>
+0x9F78	0x5D59	0x6BCB	# <CJK>
+0x9F79	0x5D5A	0x6BD3	# <CJK>
+0x9F7A	0x5D5B	0x6BDF	# <CJK>
+0x9F7B	0x5D5C	0x6BEC	# <CJK>
+0x9F7C	0x5D5D	0x6BEB	# <CJK>
+0x9F7D	0x5D5E	0x6BF3	# <CJK>
+0x9F7E	0x5D5F	0x6BEF	# <CJK>
+0x9F80	0x5D60	0x9EBE	# <CJK>
+0x9F81	0x5D61	0x6C08	# <CJK>
+0x9F82	0x5D62	0x6C13	# <CJK>
+0x9F83	0x5D63	0x6C14	# <CJK>
+0x9F84	0x5D64	0x6C1B	# <CJK>
+0x9F85	0x5D65	0x6C24	# <CJK>
+0x9F86	0x5D66	0x6C23	# <CJK>
+0x9F87	0x5D67	0x6C5E	# <CJK>
+0x9F88	0x5D68	0x6C55	# <CJK>
+0x9F89	0x5D69	0x6C62	# <CJK>
+0x9F8A	0x5D6A	0x6C6A	# <CJK>
+0x9F8B	0x5D6B	0x6C82	# <CJK>
+0x9F8C	0x5D6C	0x6C8D	# <CJK>
+0x9F8D	0x5D6D	0x6C9A	# <CJK>
+0x9F8E	0x5D6E	0x6C81	# <CJK>
+0x9F8F	0x5D6F	0x6C9B	# <CJK>
+0x9F90	0x5D70	0x6C7E	# <CJK>
+0x9F91	0x5D71	0x6C68	# <CJK>
+0x9F92	0x5D72	0x6C73	# <CJK>
+0x9F93	0x5D73	0x6C92	# <CJK>
+0x9F94	0x5D74	0x6C90	# <CJK>
+0x9F95	0x5D75	0x6CC4	# <CJK>
+0x9F96	0x5D76	0x6CF1	# <CJK>
+0x9F97	0x5D77	0x6CD3	# <CJK>
+0x9F98	0x5D78	0x6CBD	# <CJK>
+0x9F99	0x5D79	0x6CD7	# <CJK>
+0x9F9A	0x5D7A	0x6CC5	# <CJK>
+0x9F9B	0x5D7B	0x6CDD	# <CJK>
+0x9F9C	0x5D7C	0x6CAE	# <CJK>
+0x9F9D	0x5D7D	0x6CB1	# <CJK>
+0x9F9E	0x5D7E	0x6CBE	# <CJK>
+0x9F9F	0x5E21	0x6CBA	# <CJK>
+0x9FA0	0x5E22	0x6CDB	# <CJK>
+0x9FA1	0x5E23	0x6CEF	# <CJK>
+0x9FA2	0x5E24	0x6CD9	# <CJK>
+0x9FA3	0x5E25	0x6CEA	# <CJK>
+0x9FA4	0x5E26	0x6D1F	# <CJK>
+0x9FA5	0x5E27	0x884D	# <CJK>
+0x9FA6	0x5E28	0x6D36	# <CJK>
+0x9FA7	0x5E29	0x6D2B	# <CJK>
+0x9FA8	0x5E2A	0x6D3D	# <CJK>
+0x9FA9	0x5E2B	0x6D38	# <CJK>
+0x9FAA	0x5E2C	0x6D19	# <CJK>
+0x9FAB	0x5E2D	0x6D35	# <CJK>
+0x9FAC	0x5E2E	0x6D33	# <CJK>
+0x9FAD	0x5E2F	0x6D12	# <CJK>
+0x9FAE	0x5E30	0x6D0C	# <CJK>
+0x9FAF	0x5E31	0x6D63	# <CJK>
+0x9FB0	0x5E32	0x6D93	# <CJK>
+0x9FB1	0x5E33	0x6D64	# <CJK>
+0x9FB2	0x5E34	0x6D5A	# <CJK>
+0x9FB3	0x5E35	0x6D79	# <CJK>
+0x9FB4	0x5E36	0x6D59	# <CJK>
+0x9FB5	0x5E37	0x6D8E	# <CJK>
+0x9FB6	0x5E38	0x6D95	# <CJK>
+0x9FB7	0x5E39	0x6FE4	# <CJK>
+0x9FB8	0x5E3A	0x6D85	# <CJK>
+0x9FB9	0x5E3B	0x6DF9	# <CJK>
+0x9FBA	0x5E3C	0x6E15	# <CJK>
+0x9FBB	0x5E3D	0x6E0A	# <CJK>
+0x9FBC	0x5E3E	0x6DB5	# <CJK>
+0x9FBD	0x5E3F	0x6DC7	# <CJK>
+0x9FBE	0x5E40	0x6DE6	# <CJK>
+0x9FBF	0x5E41	0x6DB8	# <CJK>
+0x9FC0	0x5E42	0x6DC6	# <CJK>
+0x9FC1	0x5E43	0x6DEC	# <CJK>
+0x9FC2	0x5E44	0x6DDE	# <CJK>
+0x9FC3	0x5E45	0x6DCC	# <CJK>
+0x9FC4	0x5E46	0x6DE8	# <CJK>
+0x9FC5	0x5E47	0x6DD2	# <CJK>
+0x9FC6	0x5E48	0x6DC5	# <CJK>
+0x9FC7	0x5E49	0x6DFA	# <CJK>
+0x9FC8	0x5E4A	0x6DD9	# <CJK>
+0x9FC9	0x5E4B	0x6DE4	# <CJK>
+0x9FCA	0x5E4C	0x6DD5	# <CJK>
+0x9FCB	0x5E4D	0x6DEA	# <CJK>
+0x9FCC	0x5E4E	0x6DEE	# <CJK>
+0x9FCD	0x5E4F	0x6E2D	# <CJK>
+0x9FCE	0x5E50	0x6E6E	# <CJK>
+0x9FCF	0x5E51	0x6E2E	# <CJK>
+0x9FD0	0x5E52	0x6E19	# <CJK>
+0x9FD1	0x5E53	0x6E72	# <CJK>
+0x9FD2	0x5E54	0x6E5F	# <CJK>
+0x9FD3	0x5E55	0x6E3E	# <CJK>
+0x9FD4	0x5E56	0x6E23	# <CJK>
+0x9FD5	0x5E57	0x6E6B	# <CJK>
+0x9FD6	0x5E58	0x6E2B	# <CJK>
+0x9FD7	0x5E59	0x6E76	# <CJK>
+0x9FD8	0x5E5A	0x6E4D	# <CJK>
+0x9FD9	0x5E5B	0x6E1F	# <CJK>
+0x9FDA	0x5E5C	0x6E43	# <CJK>
+0x9FDB	0x5E5D	0x6E3A	# <CJK>
+0x9FDC	0x5E5E	0x6E4E	# <CJK>
+0x9FDD	0x5E5F	0x6E24	# <CJK>
+0x9FDE	0x5E60	0x6EFF	# <CJK>
+0x9FDF	0x5E61	0x6E1D	# <CJK>
+0x9FE0	0x5E62	0x6E38	# <CJK>
+0x9FE1	0x5E63	0x6E82	# <CJK>
+0x9FE2	0x5E64	0x6EAA	# <CJK>
+0x9FE3	0x5E65	0x6E98	# <CJK>
+0x9FE4	0x5E66	0x6EC9	# <CJK>
+0x9FE5	0x5E67	0x6EB7	# <CJK>
+0x9FE6	0x5E68	0x6ED3	# <CJK>
+0x9FE7	0x5E69	0x6EBD	# <CJK>
+0x9FE8	0x5E6A	0x6EAF	# <CJK>
+0x9FE9	0x5E6B	0x6EC4	# <CJK>
+0x9FEA	0x5E6C	0x6EB2	# <CJK>
+0x9FEB	0x5E6D	0x6ED4	# <CJK>
+0x9FEC	0x5E6E	0x6ED5	# <CJK>
+0x9FED	0x5E6F	0x6E8F	# <CJK>
+0x9FEE	0x5E70	0x6EA5	# <CJK>
+0x9FEF	0x5E71	0x6EC2	# <CJK>
+0x9FF0	0x5E72	0x6E9F	# <CJK>
+0x9FF1	0x5E73	0x6F41	# <CJK>
+0x9FF2	0x5E74	0x6F11	# <CJK>
+0x9FF3	0x5E75	0x704C	# <CJK>
+0x9FF4	0x5E76	0x6EEC	# <CJK>
+0x9FF5	0x5E77	0x6EF8	# <CJK>
+0x9FF6	0x5E78	0x6EFE	# <CJK>
+0x9FF7	0x5E79	0x6F3F	# <CJK>
+0x9FF8	0x5E7A	0x6EF2	# <CJK>
+0x9FF9	0x5E7B	0x6F31	# <CJK>
+0x9FFA	0x5E7C	0x6EEF	# <CJK>
+0x9FFB	0x5E7D	0x6F32	# <CJK>
+0x9FFC	0x5E7E	0x6ECC	# <CJK>
+0xE040	0x5F21	0x6F3E	# <CJK>
+0xE041	0x5F22	0x6F13	# <CJK>
+0xE042	0x5F23	0x6EF7	# <CJK>
+0xE043	0x5F24	0x6F86	# <CJK>
+0xE044	0x5F25	0x6F7A	# <CJK>
+0xE045	0x5F26	0x6F78	# <CJK>
+0xE046	0x5F27	0x6F81	# <CJK>
+0xE047	0x5F28	0x6F80	# <CJK>
+0xE048	0x5F29	0x6F6F	# <CJK>
+0xE049	0x5F2A	0x6F5B	# <CJK>
+0xE04A	0x5F2B	0x6FF3	# <CJK>
+0xE04B	0x5F2C	0x6F6D	# <CJK>
+0xE04C	0x5F2D	0x6F82	# <CJK>
+0xE04D	0x5F2E	0x6F7C	# <CJK>
+0xE04E	0x5F2F	0x6F58	# <CJK>
+0xE04F	0x5F30	0x6F8E	# <CJK>
+0xE050	0x5F31	0x6F91	# <CJK>
+0xE051	0x5F32	0x6FC2	# <CJK>
+0xE052	0x5F33	0x6F66	# <CJK>
+0xE053	0x5F34	0x6FB3	# <CJK>
+0xE054	0x5F35	0x6FA3	# <CJK>
+0xE055	0x5F36	0x6FA1	# <CJK>
+0xE056	0x5F37	0x6FA4	# <CJK>
+0xE057	0x5F38	0x6FB9	# <CJK>
+0xE058	0x5F39	0x6FC6	# <CJK>
+0xE059	0x5F3A	0x6FAA	# <CJK>
+0xE05A	0x5F3B	0x6FDF	# <CJK>
+0xE05B	0x5F3C	0x6FD5	# <CJK>
+0xE05C	0x5F3D	0x6FEC	# <CJK>
+0xE05D	0x5F3E	0x6FD4	# <CJK>
+0xE05E	0x5F3F	0x6FD8	# <CJK>
+0xE05F	0x5F40	0x6FF1	# <CJK>
+0xE060	0x5F41	0x6FEE	# <CJK>
+0xE061	0x5F42	0x6FDB	# <CJK>
+0xE062	0x5F43	0x7009	# <CJK>
+0xE063	0x5F44	0x700B	# <CJK>
+0xE064	0x5F45	0x6FFA	# <CJK>
+0xE065	0x5F46	0x7011	# <CJK>
+0xE066	0x5F47	0x7001	# <CJK>
+0xE067	0x5F48	0x700F	# <CJK>
+0xE068	0x5F49	0x6FFE	# <CJK>
+0xE069	0x5F4A	0x701B	# <CJK>
+0xE06A	0x5F4B	0x701A	# <CJK>
+0xE06B	0x5F4C	0x6F74	# <CJK>
+0xE06C	0x5F4D	0x701D	# <CJK>
+0xE06D	0x5F4E	0x7018	# <CJK>
+0xE06E	0x5F4F	0x701F	# <CJK>
+0xE06F	0x5F50	0x7030	# <CJK>
+0xE070	0x5F51	0x703E	# <CJK>
+0xE071	0x5F52	0x7032	# <CJK>
+0xE072	0x5F53	0x7051	# <CJK>
+0xE073	0x5F54	0x7063	# <CJK>
+0xE074	0x5F55	0x7099	# <CJK>
+0xE075	0x5F56	0x7092	# <CJK>
+0xE076	0x5F57	0x70AF	# <CJK>
+0xE077	0x5F58	0x70F1	# <CJK>
+0xE078	0x5F59	0x70AC	# <CJK>
+0xE079	0x5F5A	0x70B8	# <CJK>
+0xE07A	0x5F5B	0x70B3	# <CJK>
+0xE07B	0x5F5C	0x70AE	# <CJK>
+0xE07C	0x5F5D	0x70DF	# <CJK>
+0xE07D	0x5F5E	0x70CB	# <CJK>
+0xE07E	0x5F5F	0x70DD	# <CJK>
+0xE080	0x5F60	0x70D9	# <CJK>
+0xE081	0x5F61	0x7109	# <CJK>
+0xE082	0x5F62	0x70FD	# <CJK>
+0xE083	0x5F63	0x711C	# <CJK>
+0xE084	0x5F64	0x7119	# <CJK>
+0xE085	0x5F65	0x7165	# <CJK>
+0xE086	0x5F66	0x7155	# <CJK>
+0xE087	0x5F67	0x7188	# <CJK>
+0xE088	0x5F68	0x7166	# <CJK>
+0xE089	0x5F69	0x7162	# <CJK>
+0xE08A	0x5F6A	0x714C	# <CJK>
+0xE08B	0x5F6B	0x7156	# <CJK>
+0xE08C	0x5F6C	0x716C	# <CJK>
+0xE08D	0x5F6D	0x718F	# <CJK>
+0xE08E	0x5F6E	0x71FB	# <CJK>
+0xE08F	0x5F6F	0x7184	# <CJK>
+0xE090	0x5F70	0x7195	# <CJK>
+0xE091	0x5F71	0x71A8	# <CJK>
+0xE092	0x5F72	0x71AC	# <CJK>
+0xE093	0x5F73	0x71D7	# <CJK>
+0xE094	0x5F74	0x71B9	# <CJK>
+0xE095	0x5F75	0x71BE	# <CJK>
+0xE096	0x5F76	0x71D2	# <CJK>
+0xE097	0x5F77	0x71C9	# <CJK>
+0xE098	0x5F78	0x71D4	# <CJK>
+0xE099	0x5F79	0x71CE	# <CJK>
+0xE09A	0x5F7A	0x71E0	# <CJK>
+0xE09B	0x5F7B	0x71EC	# <CJK>
+0xE09C	0x5F7C	0x71E7	# <CJK>
+0xE09D	0x5F7D	0x71F5	# <CJK>
+0xE09E	0x5F7E	0x71FC	# <CJK>
+0xE09F	0x6021	0x71F9	# <CJK>
+0xE0A0	0x6022	0x71FF	# <CJK>
+0xE0A1	0x6023	0x720D	# <CJK>
+0xE0A2	0x6024	0x7210	# <CJK>
+0xE0A3	0x6025	0x721B	# <CJK>
+0xE0A4	0x6026	0x7228	# <CJK>
+0xE0A5	0x6027	0x722D	# <CJK>
+0xE0A6	0x6028	0x722C	# <CJK>
+0xE0A7	0x6029	0x7230	# <CJK>
+0xE0A8	0x602A	0x7232	# <CJK>
+0xE0A9	0x602B	0x723B	# <CJK>
+0xE0AA	0x602C	0x723C	# <CJK>
+0xE0AB	0x602D	0x723F	# <CJK>
+0xE0AC	0x602E	0x7240	# <CJK>
+0xE0AD	0x602F	0x7246	# <CJK>
+0xE0AE	0x6030	0x724B	# <CJK>
+0xE0AF	0x6031	0x7258	# <CJK>
+0xE0B0	0x6032	0x7274	# <CJK>
+0xE0B1	0x6033	0x727E	# <CJK>
+0xE0B2	0x6034	0x7282	# <CJK>
+0xE0B3	0x6035	0x7281	# <CJK>
+0xE0B4	0x6036	0x7287	# <CJK>
+0xE0B5	0x6037	0x7292	# <CJK>
+0xE0B6	0x6038	0x7296	# <CJK>
+0xE0B7	0x6039	0x72A2	# <CJK>
+0xE0B8	0x603A	0x72A7	# <CJK>
+0xE0B9	0x603B	0x72B9	# <CJK>
+0xE0BA	0x603C	0x72B2	# <CJK>
+0xE0BB	0x603D	0x72C3	# <CJK>
+0xE0BC	0x603E	0x72C6	# <CJK>
+0xE0BD	0x603F	0x72C4	# <CJK>
+0xE0BE	0x6040	0x72CE	# <CJK>
+0xE0BF	0x6041	0x72D2	# <CJK>
+0xE0C0	0x6042	0x72E2	# <CJK>
+0xE0C1	0x6043	0x72E0	# <CJK>
+0xE0C2	0x6044	0x72E1	# <CJK>
+0xE0C3	0x6045	0x72F9	# <CJK>
+0xE0C4	0x6046	0x72F7	# <CJK>
+0xE0C5	0x6047	0x500F	# <CJK>
+0xE0C6	0x6048	0x7317	# <CJK>
+0xE0C7	0x6049	0x730A	# <CJK>
+0xE0C8	0x604A	0x731C	# <CJK>
+0xE0C9	0x604B	0x7316	# <CJK>
+0xE0CA	0x604C	0x731D	# <CJK>
+0xE0CB	0x604D	0x7334	# <CJK>
+0xE0CC	0x604E	0x732F	# <CJK>
+0xE0CD	0x604F	0x7329	# <CJK>
+0xE0CE	0x6050	0x7325	# <CJK>
+0xE0CF	0x6051	0x733E	# <CJK>
+0xE0D0	0x6052	0x734E	# <CJK>
+0xE0D1	0x6053	0x734F	# <CJK>
+0xE0D2	0x6054	0x9ED8	# <CJK>
+0xE0D3	0x6055	0x7357	# <CJK>
+0xE0D4	0x6056	0x736A	# <CJK>
+0xE0D5	0x6057	0x7368	# <CJK>
+0xE0D6	0x6058	0x7370	# <CJK>
+0xE0D7	0x6059	0x7378	# <CJK>
+0xE0D8	0x605A	0x7375	# <CJK>
+0xE0D9	0x605B	0x737B	# <CJK>
+0xE0DA	0x605C	0x737A	# <CJK>
+0xE0DB	0x605D	0x73C8	# <CJK>
+0xE0DC	0x605E	0x73B3	# <CJK>
+0xE0DD	0x605F	0x73CE	# <CJK>
+0xE0DE	0x6060	0x73BB	# <CJK>
+0xE0DF	0x6061	0x73C0	# <CJK>
+0xE0E0	0x6062	0x73E5	# <CJK>
+0xE0E1	0x6063	0x73EE	# <CJK>
+0xE0E2	0x6064	0x73DE	# <CJK>
+0xE0E3	0x6065	0x74A2	# <CJK>
+0xE0E4	0x6066	0x7405	# <CJK>
+0xE0E5	0x6067	0x746F	# <CJK>
+0xE0E6	0x6068	0x7425	# <CJK>
+0xE0E7	0x6069	0x73F8	# <CJK>
+0xE0E8	0x606A	0x7432	# <CJK>
+0xE0E9	0x606B	0x743A	# <CJK>
+0xE0EA	0x606C	0x7455	# <CJK>
+0xE0EB	0x606D	0x743F	# <CJK>
+0xE0EC	0x606E	0x745F	# <CJK>
+0xE0ED	0x606F	0x7459	# <CJK>
+0xE0EE	0x6070	0x7441	# <CJK>
+0xE0EF	0x6071	0x745C	# <CJK>
+0xE0F0	0x6072	0x7469	# <CJK>
+0xE0F1	0x6073	0x7470	# <CJK>
+0xE0F2	0x6074	0x7463	# <CJK>
+0xE0F3	0x6075	0x746A	# <CJK>
+0xE0F4	0x6076	0x7476	# <CJK>
+0xE0F5	0x6077	0x747E	# <CJK>
+0xE0F6	0x6078	0x748B	# <CJK>
+0xE0F7	0x6079	0x749E	# <CJK>
+0xE0F8	0x607A	0x74A7	# <CJK>
+0xE0F9	0x607B	0x74CA	# <CJK>
+0xE0FA	0x607C	0x74CF	# <CJK>
+0xE0FB	0x607D	0x74D4	# <CJK>
+0xE0FC	0x607E	0x73F1	# <CJK>
+0xE140	0x6121	0x74E0	# <CJK>
+0xE141	0x6122	0x74E3	# <CJK>
+0xE142	0x6123	0x74E7	# <CJK>
+0xE143	0x6124	0x74E9	# <CJK>
+0xE144	0x6125	0x74EE	# <CJK>
+0xE145	0x6126	0x74F2	# <CJK>
+0xE146	0x6127	0x74F0	# <CJK>
+0xE147	0x6128	0x74F1	# <CJK>
+0xE148	0x6129	0x74F8	# <CJK>
+0xE149	0x612A	0x74F7	# <CJK>
+0xE14A	0x612B	0x7504	# <CJK>
+0xE14B	0x612C	0x7503	# <CJK>
+0xE14C	0x612D	0x7505	# <CJK>
+0xE14D	0x612E	0x750C	# <CJK>
+0xE14E	0x612F	0x750E	# <CJK>
+0xE14F	0x6130	0x750D	# <CJK>
+0xE150	0x6131	0x7515	# <CJK>
+0xE151	0x6132	0x7513	# <CJK>
+0xE152	0x6133	0x751E	# <CJK>
+0xE153	0x6134	0x7526	# <CJK>
+0xE154	0x6135	0x752C	# <CJK>
+0xE155	0x6136	0x753C	# <CJK>
+0xE156	0x6137	0x7544	# <CJK>
+0xE157	0x6138	0x754D	# <CJK>
+0xE158	0x6139	0x754A	# <CJK>
+0xE159	0x613A	0x7549	# <CJK>
+0xE15A	0x613B	0x755B	# <CJK>
+0xE15B	0x613C	0x7546	# <CJK>
+0xE15C	0x613D	0x755A	# <CJK>
+0xE15D	0x613E	0x7569	# <CJK>
+0xE15E	0x613F	0x7564	# <CJK>
+0xE15F	0x6140	0x7567	# <CJK>
+0xE160	0x6141	0x756B	# <CJK>
+0xE161	0x6142	0x756D	# <CJK>
+0xE162	0x6143	0x7578	# <CJK>
+0xE163	0x6144	0x7576	# <CJK>
+0xE164	0x6145	0x7586	# <CJK>
+0xE165	0x6146	0x7587	# <CJK>
+0xE166	0x6147	0x7574	# <CJK>
+0xE167	0x6148	0x758A	# <CJK>
+0xE168	0x6149	0x7589	# <CJK>
+0xE169	0x614A	0x7582	# <CJK>
+0xE16A	0x614B	0x7594	# <CJK>
+0xE16B	0x614C	0x759A	# <CJK>
+0xE16C	0x614D	0x759D	# <CJK>
+0xE16D	0x614E	0x75A5	# <CJK>
+0xE16E	0x614F	0x75A3	# <CJK>
+0xE16F	0x6150	0x75C2	# <CJK>
+0xE170	0x6151	0x75B3	# <CJK>
+0xE171	0x6152	0x75C3	# <CJK>
+0xE172	0x6153	0x75B5	# <CJK>
+0xE173	0x6154	0x75BD	# <CJK>
+0xE174	0x6155	0x75B8	# <CJK>
+0xE175	0x6156	0x75BC	# <CJK>
+0xE176	0x6157	0x75B1	# <CJK>
+0xE177	0x6158	0x75CD	# <CJK>
+0xE178	0x6159	0x75CA	# <CJK>
+0xE179	0x615A	0x75D2	# <CJK>
+0xE17A	0x615B	0x75D9	# <CJK>
+0xE17B	0x615C	0x75E3	# <CJK>
+0xE17C	0x615D	0x75DE	# <CJK>
+0xE17D	0x615E	0x75FE	# <CJK>
+0xE17E	0x615F	0x75FF	# <CJK>
+0xE180	0x6160	0x75FC	# <CJK>
+0xE181	0x6161	0x7601	# <CJK>
+0xE182	0x6162	0x75F0	# <CJK>
+0xE183	0x6163	0x75FA	# <CJK>
+0xE184	0x6164	0x75F2	# <CJK>
+0xE185	0x6165	0x75F3	# <CJK>
+0xE186	0x6166	0x760B	# <CJK>
+0xE187	0x6167	0x760D	# <CJK>
+0xE188	0x6168	0x7609	# <CJK>
+0xE189	0x6169	0x761F	# <CJK>
+0xE18A	0x616A	0x7627	# <CJK>
+0xE18B	0x616B	0x7620	# <CJK>
+0xE18C	0x616C	0x7621	# <CJK>
+0xE18D	0x616D	0x7622	# <CJK>
+0xE18E	0x616E	0x7624	# <CJK>
+0xE18F	0x616F	0x7634	# <CJK>
+0xE190	0x6170	0x7630	# <CJK>
+0xE191	0x6171	0x763B	# <CJK>
+0xE192	0x6172	0x7647	# <CJK>
+0xE193	0x6173	0x7648	# <CJK>
+0xE194	0x6174	0x7646	# <CJK>
+0xE195	0x6175	0x765C	# <CJK>
+0xE196	0x6176	0x7658	# <CJK>
+0xE197	0x6177	0x7661	# <CJK>
+0xE198	0x6178	0x7662	# <CJK>
+0xE199	0x6179	0x7668	# <CJK>
+0xE19A	0x617A	0x7669	# <CJK>
+0xE19B	0x617B	0x766A	# <CJK>
+0xE19C	0x617C	0x7667	# <CJK>
+0xE19D	0x617D	0x766C	# <CJK>
+0xE19E	0x617E	0x7670	# <CJK>
+0xE19F	0x6221	0x7672	# <CJK>
+0xE1A0	0x6222	0x7676	# <CJK>
+0xE1A1	0x6223	0x7678	# <CJK>
+0xE1A2	0x6224	0x767C	# <CJK>
+0xE1A3	0x6225	0x7680	# <CJK>
+0xE1A4	0x6226	0x7683	# <CJK>
+0xE1A5	0x6227	0x7688	# <CJK>
+0xE1A6	0x6228	0x768B	# <CJK>
+0xE1A7	0x6229	0x768E	# <CJK>
+0xE1A8	0x622A	0x7696	# <CJK>
+0xE1A9	0x622B	0x7693	# <CJK>
+0xE1AA	0x622C	0x7699	# <CJK>
+0xE1AB	0x622D	0x769A	# <CJK>
+0xE1AC	0x622E	0x76B0	# <CJK>
+0xE1AD	0x622F	0x76B4	# <CJK>
+0xE1AE	0x6230	0x76B8	# <CJK>
+0xE1AF	0x6231	0x76B9	# <CJK>
+0xE1B0	0x6232	0x76BA	# <CJK>
+0xE1B1	0x6233	0x76C2	# <CJK>
+0xE1B2	0x6234	0x76CD	# <CJK>
+0xE1B3	0x6235	0x76D6	# <CJK>
+0xE1B4	0x6236	0x76D2	# <CJK>
+0xE1B5	0x6237	0x76DE	# <CJK>
+0xE1B6	0x6238	0x76E1	# <CJK>
+0xE1B7	0x6239	0x76E5	# <CJK>
+0xE1B8	0x623A	0x76E7	# <CJK>
+0xE1B9	0x623B	0x76EA	# <CJK>
+0xE1BA	0x623C	0x862F	# <CJK>
+0xE1BB	0x623D	0x76FB	# <CJK>
+0xE1BC	0x623E	0x7708	# <CJK>
+0xE1BD	0x623F	0x7707	# <CJK>
+0xE1BE	0x6240	0x7704	# <CJK>
+0xE1BF	0x6241	0x7729	# <CJK>
+0xE1C0	0x6242	0x7724	# <CJK>
+0xE1C1	0x6243	0x771E	# <CJK>
+0xE1C2	0x6244	0x7725	# <CJK>
+0xE1C3	0x6245	0x7726	# <CJK>
+0xE1C4	0x6246	0x771B	# <CJK>
+0xE1C5	0x6247	0x7737	# <CJK>
+0xE1C6	0x6248	0x7738	# <CJK>
+0xE1C7	0x6249	0x7747	# <CJK>
+0xE1C8	0x624A	0x775A	# <CJK>
+0xE1C9	0x624B	0x7768	# <CJK>
+0xE1CA	0x624C	0x776B	# <CJK>
+0xE1CB	0x624D	0x775B	# <CJK>
+0xE1CC	0x624E	0x7765	# <CJK>
+0xE1CD	0x624F	0x777F	# <CJK>
+0xE1CE	0x6250	0x777E	# <CJK>
+0xE1CF	0x6251	0x7779	# <CJK>
+0xE1D0	0x6252	0x778E	# <CJK>
+0xE1D1	0x6253	0x778B	# <CJK>
+0xE1D2	0x6254	0x7791	# <CJK>
+0xE1D3	0x6255	0x77A0	# <CJK>
+0xE1D4	0x6256	0x779E	# <CJK>
+0xE1D5	0x6257	0x77B0	# <CJK>
+0xE1D6	0x6258	0x77B6	# <CJK>
+0xE1D7	0x6259	0x77B9	# <CJK>
+0xE1D8	0x625A	0x77BF	# <CJK>
+0xE1D9	0x625B	0x77BC	# <CJK>
+0xE1DA	0x625C	0x77BD	# <CJK>
+0xE1DB	0x625D	0x77BB	# <CJK>
+0xE1DC	0x625E	0x77C7	# <CJK>
+0xE1DD	0x625F	0x77CD	# <CJK>
+0xE1DE	0x6260	0x77D7	# <CJK>
+0xE1DF	0x6261	0x77DA	# <CJK>
+0xE1E0	0x6262	0x77DC	# <CJK>
+0xE1E1	0x6263	0x77E3	# <CJK>
+0xE1E2	0x6264	0x77EE	# <CJK>
+0xE1E3	0x6265	0x77FC	# <CJK>
+0xE1E4	0x6266	0x780C	# <CJK>
+0xE1E5	0x6267	0x7812	# <CJK>
+0xE1E6	0x6268	0x7926	# <CJK>
+0xE1E7	0x6269	0x7820	# <CJK>
+0xE1E8	0x626A	0x792A	# <CJK>
+0xE1E9	0x626B	0x7845	# <CJK>
+0xE1EA	0x626C	0x788E	# <CJK>
+0xE1EB	0x626D	0x7874	# <CJK>
+0xE1EC	0x626E	0x7886	# <CJK>
+0xE1ED	0x626F	0x787C	# <CJK>
+0xE1EE	0x6270	0x789A	# <CJK>
+0xE1EF	0x6271	0x788C	# <CJK>
+0xE1F0	0x6272	0x78A3	# <CJK>
+0xE1F1	0x6273	0x78B5	# <CJK>
+0xE1F2	0x6274	0x78AA	# <CJK>
+0xE1F3	0x6275	0x78AF	# <CJK>
+0xE1F4	0x6276	0x78D1	# <CJK>
+0xE1F5	0x6277	0x78C6	# <CJK>
+0xE1F6	0x6278	0x78CB	# <CJK>
+0xE1F7	0x6279	0x78D4	# <CJK>
+0xE1F8	0x627A	0x78BE	# <CJK>
+0xE1F9	0x627B	0x78BC	# <CJK>
+0xE1FA	0x627C	0x78C5	# <CJK>
+0xE1FB	0x627D	0x78CA	# <CJK>
+0xE1FC	0x627E	0x78EC	# <CJK>
+0xE240	0x6321	0x78E7	# <CJK>
+0xE241	0x6322	0x78DA	# <CJK>
+0xE242	0x6323	0x78FD	# <CJK>
+0xE243	0x6324	0x78F4	# <CJK>
+0xE244	0x6325	0x7907	# <CJK>
+0xE245	0x6326	0x7912	# <CJK>
+0xE246	0x6327	0x7911	# <CJK>
+0xE247	0x6328	0x7919	# <CJK>
+0xE248	0x6329	0x792C	# <CJK>
+0xE249	0x632A	0x792B	# <CJK>
+0xE24A	0x632B	0x7940	# <CJK>
+0xE24B	0x632C	0x7960	# <CJK>
+0xE24C	0x632D	0x7957	# <CJK>
+0xE24D	0x632E	0x795F	# <CJK>
+0xE24E	0x632F	0x795A	# <CJK>
+0xE24F	0x6330	0x7955	# <CJK>
+0xE250	0x6331	0x7953	# <CJK>
+0xE251	0x6332	0x797A	# <CJK>
+0xE252	0x6333	0x797F	# <CJK>
+0xE253	0x6334	0x798A	# <CJK>
+0xE254	0x6335	0x799D	# <CJK>
+0xE255	0x6336	0x79A7	# <CJK>
+0xE256	0x6337	0x9F4B	# <CJK>
+0xE257	0x6338	0x79AA	# <CJK>
+0xE258	0x6339	0x79AE	# <CJK>
+0xE259	0x633A	0x79B3	# <CJK>
+0xE25A	0x633B	0x79B9	# <CJK>
+0xE25B	0x633C	0x79BA	# <CJK>
+0xE25C	0x633D	0x79C9	# <CJK>
+0xE25D	0x633E	0x79D5	# <CJK>
+0xE25E	0x633F	0x79E7	# <CJK>
+0xE25F	0x6340	0x79EC	# <CJK>
+0xE260	0x6341	0x79E1	# <CJK>
+0xE261	0x6342	0x79E3	# <CJK>
+0xE262	0x6343	0x7A08	# <CJK>
+0xE263	0x6344	0x7A0D	# <CJK>
+0xE264	0x6345	0x7A18	# <CJK>
+0xE265	0x6346	0x7A19	# <CJK>
+0xE266	0x6347	0x7A20	# <CJK>
+0xE267	0x6348	0x7A1F	# <CJK>
+0xE268	0x6349	0x7980	# <CJK>
+0xE269	0x634A	0x7A31	# <CJK>
+0xE26A	0x634B	0x7A3B	# <CJK>
+0xE26B	0x634C	0x7A3E	# <CJK>
+0xE26C	0x634D	0x7A37	# <CJK>
+0xE26D	0x634E	0x7A43	# <CJK>
+0xE26E	0x634F	0x7A57	# <CJK>
+0xE26F	0x6350	0x7A49	# <CJK>
+0xE270	0x6351	0x7A61	# <CJK>
+0xE271	0x6352	0x7A62	# <CJK>
+0xE272	0x6353	0x7A69	# <CJK>
+0xE273	0x6354	0x9F9D	# <CJK>
+0xE274	0x6355	0x7A70	# <CJK>
+0xE275	0x6356	0x7A79	# <CJK>
+0xE276	0x6357	0x7A7D	# <CJK>
+0xE277	0x6358	0x7A88	# <CJK>
+0xE278	0x6359	0x7A97	# <CJK>
+0xE279	0x635A	0x7A95	# <CJK>
+0xE27A	0x635B	0x7A98	# <CJK>
+0xE27B	0x635C	0x7A96	# <CJK>
+0xE27C	0x635D	0x7AA9	# <CJK>
+0xE27D	0x635E	0x7AC8	# <CJK>
+0xE27E	0x635F	0x7AB0	# <CJK>
+0xE280	0x6360	0x7AB6	# <CJK>
+0xE281	0x6361	0x7AC5	# <CJK>
+0xE282	0x6362	0x7AC4	# <CJK>
+0xE283	0x6363	0x7ABF	# <CJK>
+0xE284	0x6364	0x9083	# <CJK>
+0xE285	0x6365	0x7AC7	# <CJK>
+0xE286	0x6366	0x7ACA	# <CJK>
+0xE287	0x6367	0x7ACD	# <CJK>
+0xE288	0x6368	0x7ACF	# <CJK>
+0xE289	0x6369	0x7AD5	# <CJK>
+0xE28A	0x636A	0x7AD3	# <CJK>
+0xE28B	0x636B	0x7AD9	# <CJK>
+0xE28C	0x636C	0x7ADA	# <CJK>
+0xE28D	0x636D	0x7ADD	# <CJK>
+0xE28E	0x636E	0x7AE1	# <CJK>
+0xE28F	0x636F	0x7AE2	# <CJK>
+0xE290	0x6370	0x7AE6	# <CJK>
+0xE291	0x6371	0x7AED	# <CJK>
+0xE292	0x6372	0x7AF0	# <CJK>
+0xE293	0x6373	0x7B02	# <CJK>
+0xE294	0x6374	0x7B0F	# <CJK>
+0xE295	0x6375	0x7B0A	# <CJK>
+0xE296	0x6376	0x7B06	# <CJK>
+0xE297	0x6377	0x7B33	# <CJK>
+0xE298	0x6378	0x7B18	# <CJK>
+0xE299	0x6379	0x7B19	# <CJK>
+0xE29A	0x637A	0x7B1E	# <CJK>
+0xE29B	0x637B	0x7B35	# <CJK>
+0xE29C	0x637C	0x7B28	# <CJK>
+0xE29D	0x637D	0x7B36	# <CJK>
+0xE29E	0x637E	0x7B50	# <CJK>
+0xE29F	0x6421	0x7B7A	# <CJK>
+0xE2A0	0x6422	0x7B04	# <CJK>
+0xE2A1	0x6423	0x7B4D	# <CJK>
+0xE2A2	0x6424	0x7B0B	# <CJK>
+0xE2A3	0x6425	0x7B4C	# <CJK>
+0xE2A4	0x6426	0x7B45	# <CJK>
+0xE2A5	0x6427	0x7B75	# <CJK>
+0xE2A6	0x6428	0x7B65	# <CJK>
+0xE2A7	0x6429	0x7B74	# <CJK>
+0xE2A8	0x642A	0x7B67	# <CJK>
+0xE2A9	0x642B	0x7B70	# <CJK>
+0xE2AA	0x642C	0x7B71	# <CJK>
+0xE2AB	0x642D	0x7B6C	# <CJK>
+0xE2AC	0x642E	0x7B6E	# <CJK>
+0xE2AD	0x642F	0x7B9D	# <CJK>
+0xE2AE	0x6430	0x7B98	# <CJK>
+0xE2AF	0x6431	0x7B9F	# <CJK>
+0xE2B0	0x6432	0x7B8D	# <CJK>
+0xE2B1	0x6433	0x7B9C	# <CJK>
+0xE2B2	0x6434	0x7B9A	# <CJK>
+0xE2B3	0x6435	0x7B8B	# <CJK>
+0xE2B4	0x6436	0x7B92	# <CJK>
+0xE2B5	0x6437	0x7B8F	# <CJK>
+0xE2B6	0x6438	0x7B5D	# <CJK>
+0xE2B7	0x6439	0x7B99	# <CJK>
+0xE2B8	0x643A	0x7BCB	# <CJK>
+0xE2B9	0x643B	0x7BC1	# <CJK>
+0xE2BA	0x643C	0x7BCC	# <CJK>
+0xE2BB	0x643D	0x7BCF	# <CJK>
+0xE2BC	0x643E	0x7BB4	# <CJK>
+0xE2BD	0x643F	0x7BC6	# <CJK>
+0xE2BE	0x6440	0x7BDD	# <CJK>
+0xE2BF	0x6441	0x7BE9	# <CJK>
+0xE2C0	0x6442	0x7C11	# <CJK>
+0xE2C1	0x6443	0x7C14	# <CJK>
+0xE2C2	0x6444	0x7BE6	# <CJK>
+0xE2C3	0x6445	0x7BE5	# <CJK>
+0xE2C4	0x6446	0x7C60	# <CJK>
+0xE2C5	0x6447	0x7C00	# <CJK>
+0xE2C6	0x6448	0x7C07	# <CJK>
+0xE2C7	0x6449	0x7C13	# <CJK>
+0xE2C8	0x644A	0x7BF3	# <CJK>
+0xE2C9	0x644B	0x7BF7	# <CJK>
+0xE2CA	0x644C	0x7C17	# <CJK>
+0xE2CB	0x644D	0x7C0D	# <CJK>
+0xE2CC	0x644E	0x7BF6	# <CJK>
+0xE2CD	0x644F	0x7C23	# <CJK>
+0xE2CE	0x6450	0x7C27	# <CJK>
+0xE2CF	0x6451	0x7C2A	# <CJK>
+0xE2D0	0x6452	0x7C1F	# <CJK>
+0xE2D1	0x6453	0x7C37	# <CJK>
+0xE2D2	0x6454	0x7C2B	# <CJK>
+0xE2D3	0x6455	0x7C3D	# <CJK>
+0xE2D4	0x6456	0x7C4C	# <CJK>
+0xE2D5	0x6457	0x7C43	# <CJK>
+0xE2D6	0x6458	0x7C54	# <CJK>
+0xE2D7	0x6459	0x7C4F	# <CJK>
+0xE2D8	0x645A	0x7C40	# <CJK>
+0xE2D9	0x645B	0x7C50	# <CJK>
+0xE2DA	0x645C	0x7C58	# <CJK>
+0xE2DB	0x645D	0x7C5F	# <CJK>
+0xE2DC	0x645E	0x7C64	# <CJK>
+0xE2DD	0x645F	0x7C56	# <CJK>
+0xE2DE	0x6460	0x7C65	# <CJK>
+0xE2DF	0x6461	0x7C6C	# <CJK>
+0xE2E0	0x6462	0x7C75	# <CJK>
+0xE2E1	0x6463	0x7C83	# <CJK>
+0xE2E2	0x6464	0x7C90	# <CJK>
+0xE2E3	0x6465	0x7CA4	# <CJK>
+0xE2E4	0x6466	0x7CAD	# <CJK>
+0xE2E5	0x6467	0x7CA2	# <CJK>
+0xE2E6	0x6468	0x7CAB	# <CJK>
+0xE2E7	0x6469	0x7CA1	# <CJK>
+0xE2E8	0x646A	0x7CA8	# <CJK>
+0xE2E9	0x646B	0x7CB3	# <CJK>
+0xE2EA	0x646C	0x7CB2	# <CJK>
+0xE2EB	0x646D	0x7CB1	# <CJK>
+0xE2EC	0x646E	0x7CAE	# <CJK>
+0xE2ED	0x646F	0x7CB9	# <CJK>
+0xE2EE	0x6470	0x7CBD	# <CJK>
+0xE2EF	0x6471	0x7CC0	# <CJK>
+0xE2F0	0x6472	0x7CC5	# <CJK>
+0xE2F1	0x6473	0x7CC2	# <CJK>
+0xE2F2	0x6474	0x7CD8	# <CJK>
+0xE2F3	0x6475	0x7CD2	# <CJK>
+0xE2F4	0x6476	0x7CDC	# <CJK>
+0xE2F5	0x6477	0x7CE2	# <CJK>
+0xE2F6	0x6478	0x9B3B	# <CJK>
+0xE2F7	0x6479	0x7CEF	# <CJK>
+0xE2F8	0x647A	0x7CF2	# <CJK>
+0xE2F9	0x647B	0x7CF4	# <CJK>
+0xE2FA	0x647C	0x7CF6	# <CJK>
+0xE2FB	0x647D	0x7CFA	# <CJK>
+0xE2FC	0x647E	0x7D06	# <CJK>
+0xE340	0x6521	0x7D02	# <CJK>
+0xE341	0x6522	0x7D1C	# <CJK>
+0xE342	0x6523	0x7D15	# <CJK>
+0xE343	0x6524	0x7D0A	# <CJK>
+0xE344	0x6525	0x7D45	# <CJK>
+0xE345	0x6526	0x7D4B	# <CJK>
+0xE346	0x6527	0x7D2E	# <CJK>
+0xE347	0x6528	0x7D32	# <CJK>
+0xE348	0x6529	0x7D3F	# <CJK>
+0xE349	0x652A	0x7D35	# <CJK>
+0xE34A	0x652B	0x7D46	# <CJK>
+0xE34B	0x652C	0x7D73	# <CJK>
+0xE34C	0x652D	0x7D56	# <CJK>
+0xE34D	0x652E	0x7D4E	# <CJK>
+0xE34E	0x652F	0x7D72	# <CJK>
+0xE34F	0x6530	0x7D68	# <CJK>
+0xE350	0x6531	0x7D6E	# <CJK>
+0xE351	0x6532	0x7D4F	# <CJK>
+0xE352	0x6533	0x7D63	# <CJK>
+0xE353	0x6534	0x7D93	# <CJK>
+0xE354	0x6535	0x7D89	# <CJK>
+0xE355	0x6536	0x7D5B	# <CJK>
+0xE356	0x6537	0x7D8F	# <CJK>
+0xE357	0x6538	0x7D7D	# <CJK>
+0xE358	0x6539	0x7D9B	# <CJK>
+0xE359	0x653A	0x7DBA	# <CJK>
+0xE35A	0x653B	0x7DAE	# <CJK>
+0xE35B	0x653C	0x7DA3	# <CJK>
+0xE35C	0x653D	0x7DB5	# <CJK>
+0xE35D	0x653E	0x7DC7	# <CJK>
+0xE35E	0x653F	0x7DBD	# <CJK>
+0xE35F	0x6540	0x7DAB	# <CJK>
+0xE360	0x6541	0x7E3D	# <CJK>
+0xE361	0x6542	0x7DA2	# <CJK>
+0xE362	0x6543	0x7DAF	# <CJK>
+0xE363	0x6544	0x7DDC	# <CJK>
+0xE364	0x6545	0x7DB8	# <CJK>
+0xE365	0x6546	0x7D9F	# <CJK>
+0xE366	0x6547	0x7DB0	# <CJK>
+0xE367	0x6548	0x7DD8	# <CJK>
+0xE368	0x6549	0x7DDD	# <CJK>
+0xE369	0x654A	0x7DE4	# <CJK>
+0xE36A	0x654B	0x7DDE	# <CJK>
+0xE36B	0x654C	0x7DFB	# <CJK>
+0xE36C	0x654D	0x7DF2	# <CJK>
+0xE36D	0x654E	0x7DE1	# <CJK>
+0xE36E	0x654F	0x7E05	# <CJK>
+0xE36F	0x6550	0x7E0A	# <CJK>
+0xE370	0x6551	0x7E23	# <CJK>
+0xE371	0x6552	0x7E21	# <CJK>
+0xE372	0x6553	0x7E12	# <CJK>
+0xE373	0x6554	0x7E31	# <CJK>
+0xE374	0x6555	0x7E1F	# <CJK>
+0xE375	0x6556	0x7E09	# <CJK>
+0xE376	0x6557	0x7E0B	# <CJK>
+0xE377	0x6558	0x7E22	# <CJK>
+0xE378	0x6559	0x7E46	# <CJK>
+0xE379	0x655A	0x7E66	# <CJK>
+0xE37A	0x655B	0x7E3B	# <CJK>
+0xE37B	0x655C	0x7E35	# <CJK>
+0xE37C	0x655D	0x7E39	# <CJK>
+0xE37D	0x655E	0x7E43	# <CJK>
+0xE37E	0x655F	0x7E37	# <CJK>
+0xE380	0x6560	0x7E32	# <CJK>
+0xE381	0x6561	0x7E3A	# <CJK>
+0xE382	0x6562	0x7E67	# <CJK>
+0xE383	0x6563	0x7E5D	# <CJK>
+0xE384	0x6564	0x7E56	# <CJK>
+0xE385	0x6565	0x7E5E	# <CJK>
+0xE386	0x6566	0x7E59	# <CJK>
+0xE387	0x6567	0x7E5A	# <CJK>
+0xE388	0x6568	0x7E79	# <CJK>
+0xE389	0x6569	0x7E6A	# <CJK>
+0xE38A	0x656A	0x7E69	# <CJK>
+0xE38B	0x656B	0x7E7C	# <CJK>
+0xE38C	0x656C	0x7E7B	# <CJK>
+0xE38D	0x656D	0x7E83	# <CJK>
+0xE38E	0x656E	0x7DD5	# <CJK>
+0xE38F	0x656F	0x7E7D	# <CJK>
+0xE390	0x6570	0x8FAE	# <CJK>
+0xE391	0x6571	0x7E7F	# <CJK>
+0xE392	0x6572	0x7E88	# <CJK>
+0xE393	0x6573	0x7E89	# <CJK>
+0xE394	0x6574	0x7E8C	# <CJK>
+0xE395	0x6575	0x7E92	# <CJK>
+0xE396	0x6576	0x7E90	# <CJK>
+0xE397	0x6577	0x7E93	# <CJK>
+0xE398	0x6578	0x7E94	# <CJK>
+0xE399	0x6579	0x7E96	# <CJK>
+0xE39A	0x657A	0x7E8E	# <CJK>
+0xE39B	0x657B	0x7E9B	# <CJK>
+0xE39C	0x657C	0x7E9C	# <CJK>
+0xE39D	0x657D	0x7F38	# <CJK>
+0xE39E	0x657E	0x7F3A	# <CJK>
+0xE39F	0x6621	0x7F45	# <CJK>
+0xE3A0	0x6622	0x7F4C	# <CJK>
+0xE3A1	0x6623	0x7F4D	# <CJK>
+0xE3A2	0x6624	0x7F4E	# <CJK>
+0xE3A3	0x6625	0x7F50	# <CJK>
+0xE3A4	0x6626	0x7F51	# <CJK>
+0xE3A5	0x6627	0x7F55	# <CJK>
+0xE3A6	0x6628	0x7F54	# <CJK>
+0xE3A7	0x6629	0x7F58	# <CJK>
+0xE3A8	0x662A	0x7F5F	# <CJK>
+0xE3A9	0x662B	0x7F60	# <CJK>
+0xE3AA	0x662C	0x7F68	# <CJK>
+0xE3AB	0x662D	0x7F69	# <CJK>
+0xE3AC	0x662E	0x7F67	# <CJK>
+0xE3AD	0x662F	0x7F78	# <CJK>
+0xE3AE	0x6630	0x7F82	# <CJK>
+0xE3AF	0x6631	0x7F86	# <CJK>
+0xE3B0	0x6632	0x7F83	# <CJK>
+0xE3B1	0x6633	0x7F88	# <CJK>
+0xE3B2	0x6634	0x7F87	# <CJK>
+0xE3B3	0x6635	0x7F8C	# <CJK>
+0xE3B4	0x6636	0x7F94	# <CJK>
+0xE3B5	0x6637	0x7F9E	# <CJK>
+0xE3B6	0x6638	0x7F9D	# <CJK>
+0xE3B7	0x6639	0x7F9A	# <CJK>
+0xE3B8	0x663A	0x7FA3	# <CJK>
+0xE3B9	0x663B	0x7FAF	# <CJK>
+0xE3BA	0x663C	0x7FB2	# <CJK>
+0xE3BB	0x663D	0x7FB9	# <CJK>
+0xE3BC	0x663E	0x7FAE	# <CJK>
+0xE3BD	0x663F	0x7FB6	# <CJK>
+0xE3BE	0x6640	0x7FB8	# <CJK>
+0xE3BF	0x6641	0x8B71	# <CJK>
+0xE3C0	0x6642	0x7FC5	# <CJK>
+0xE3C1	0x6643	0x7FC6	# <CJK>
+0xE3C2	0x6644	0x7FCA	# <CJK>
+0xE3C3	0x6645	0x7FD5	# <CJK>
+0xE3C4	0x6646	0x7FD4	# <CJK>
+0xE3C5	0x6647	0x7FE1	# <CJK>
+0xE3C6	0x6648	0x7FE6	# <CJK>
+0xE3C7	0x6649	0x7FE9	# <CJK>
+0xE3C8	0x664A	0x7FF3	# <CJK>
+0xE3C9	0x664B	0x7FF9	# <CJK>
+0xE3CA	0x664C	0x98DC	# <CJK>
+0xE3CB	0x664D	0x8006	# <CJK>
+0xE3CC	0x664E	0x8004	# <CJK>
+0xE3CD	0x664F	0x800B	# <CJK>
+0xE3CE	0x6650	0x8012	# <CJK>
+0xE3CF	0x6651	0x8018	# <CJK>
+0xE3D0	0x6652	0x8019	# <CJK>
+0xE3D1	0x6653	0x801C	# <CJK>
+0xE3D2	0x6654	0x8021	# <CJK>
+0xE3D3	0x6655	0x8028	# <CJK>
+0xE3D4	0x6656	0x803F	# <CJK>
+0xE3D5	0x6657	0x803B	# <CJK>
+0xE3D6	0x6658	0x804A	# <CJK>
+0xE3D7	0x6659	0x8046	# <CJK>
+0xE3D8	0x665A	0x8052	# <CJK>
+0xE3D9	0x665B	0x8058	# <CJK>
+0xE3DA	0x665C	0x805A	# <CJK>
+0xE3DB	0x665D	0x805F	# <CJK>
+0xE3DC	0x665E	0x8062	# <CJK>
+0xE3DD	0x665F	0x8068	# <CJK>
+0xE3DE	0x6660	0x8073	# <CJK>
+0xE3DF	0x6661	0x8072	# <CJK>
+0xE3E0	0x6662	0x8070	# <CJK>
+0xE3E1	0x6663	0x8076	# <CJK>
+0xE3E2	0x6664	0x8079	# <CJK>
+0xE3E3	0x6665	0x807D	# <CJK>
+0xE3E4	0x6666	0x807F	# <CJK>
+0xE3E5	0x6667	0x8084	# <CJK>
+0xE3E6	0x6668	0x8086	# <CJK>
+0xE3E7	0x6669	0x8085	# <CJK>
+0xE3E8	0x666A	0x809B	# <CJK>
+0xE3E9	0x666B	0x8093	# <CJK>
+0xE3EA	0x666C	0x809A	# <CJK>
+0xE3EB	0x666D	0x80AD	# <CJK>
+0xE3EC	0x666E	0x5190	# <CJK>
+0xE3ED	0x666F	0x80AC	# <CJK>
+0xE3EE	0x6670	0x80DB	# <CJK>
+0xE3EF	0x6671	0x80E5	# <CJK>
+0xE3F0	0x6672	0x80D9	# <CJK>
+0xE3F1	0x6673	0x80DD	# <CJK>
+0xE3F2	0x6674	0x80C4	# <CJK>
+0xE3F3	0x6675	0x80DA	# <CJK>
+0xE3F4	0x6676	0x80D6	# <CJK>
+0xE3F5	0x6677	0x8109	# <CJK>
+0xE3F6	0x6678	0x80EF	# <CJK>
+0xE3F7	0x6679	0x80F1	# <CJK>
+0xE3F8	0x667A	0x811B	# <CJK>
+0xE3F9	0x667B	0x8129	# <CJK>
+0xE3FA	0x667C	0x8123	# <CJK>
+0xE3FB	0x667D	0x812F	# <CJK>
+0xE3FC	0x667E	0x814B	# <CJK>
+0xE440	0x6721	0x968B	# <CJK>
+0xE441	0x6722	0x8146	# <CJK>
+0xE442	0x6723	0x813E	# <CJK>
+0xE443	0x6724	0x8153	# <CJK>
+0xE444	0x6725	0x8151	# <CJK>
+0xE445	0x6726	0x80FC	# <CJK>
+0xE446	0x6727	0x8171	# <CJK>
+0xE447	0x6728	0x816E	# <CJK>
+0xE448	0x6729	0x8165	# <CJK>
+0xE449	0x672A	0x8166	# <CJK>
+0xE44A	0x672B	0x8174	# <CJK>
+0xE44B	0x672C	0x8183	# <CJK>
+0xE44C	0x672D	0x8188	# <CJK>
+0xE44D	0x672E	0x818A	# <CJK>
+0xE44E	0x672F	0x8180	# <CJK>
+0xE44F	0x6730	0x8182	# <CJK>
+0xE450	0x6731	0x81A0	# <CJK>
+0xE451	0x6732	0x8195	# <CJK>
+0xE452	0x6733	0x81A4	# <CJK>
+0xE453	0x6734	0x81A3	# <CJK>
+0xE454	0x6735	0x815F	# <CJK>
+0xE455	0x6736	0x8193	# <CJK>
+0xE456	0x6737	0x81A9	# <CJK>
+0xE457	0x6738	0x81B0	# <CJK>
+0xE458	0x6739	0x81B5	# <CJK>
+0xE459	0x673A	0x81BE	# <CJK>
+0xE45A	0x673B	0x81B8	# <CJK>
+0xE45B	0x673C	0x81BD	# <CJK>
+0xE45C	0x673D	0x81C0	# <CJK>
+0xE45D	0x673E	0x81C2	# <CJK>
+0xE45E	0x673F	0x81BA	# <CJK>
+0xE45F	0x6740	0x81C9	# <CJK>
+0xE460	0x6741	0x81CD	# <CJK>
+0xE461	0x6742	0x81D1	# <CJK>
+0xE462	0x6743	0x81D9	# <CJK>
+0xE463	0x6744	0x81D8	# <CJK>
+0xE464	0x6745	0x81C8	# <CJK>
+0xE465	0x6746	0x81DA	# <CJK>
+0xE466	0x6747	0x81DF	# <CJK>
+0xE467	0x6748	0x81E0	# <CJK>
+0xE468	0x6749	0x81E7	# <CJK>
+0xE469	0x674A	0x81FA	# <CJK>
+0xE46A	0x674B	0x81FB	# <CJK>
+0xE46B	0x674C	0x81FE	# <CJK>
+0xE46C	0x674D	0x8201	# <CJK>
+0xE46D	0x674E	0x8202	# <CJK>
+0xE46E	0x674F	0x8205	# <CJK>
+0xE46F	0x6750	0x8207	# <CJK>
+0xE470	0x6751	0x820A	# <CJK>
+0xE471	0x6752	0x820D	# <CJK>
+0xE472	0x6753	0x8210	# <CJK>
+0xE473	0x6754	0x8216	# <CJK>
+0xE474	0x6755	0x8229	# <CJK>
+0xE475	0x6756	0x822B	# <CJK>
+0xE476	0x6757	0x8238	# <CJK>
+0xE477	0x6758	0x8233	# <CJK>
+0xE478	0x6759	0x8240	# <CJK>
+0xE479	0x675A	0x8259	# <CJK>
+0xE47A	0x675B	0x8258	# <CJK>
+0xE47B	0x675C	0x825D	# <CJK>
+0xE47C	0x675D	0x825A	# <CJK>
+0xE47D	0x675E	0x825F	# <CJK>
+0xE47E	0x675F	0x8264	# <CJK>
+0xE480	0x6760	0x8262	# <CJK>
+0xE481	0x6761	0x8268	# <CJK>
+0xE482	0x6762	0x826A	# <CJK>
+0xE483	0x6763	0x826B	# <CJK>
+0xE484	0x6764	0x822E	# <CJK>
+0xE485	0x6765	0x8271	# <CJK>
+0xE486	0x6766	0x8277	# <CJK>
+0xE487	0x6767	0x8278	# <CJK>
+0xE488	0x6768	0x827E	# <CJK>
+0xE489	0x6769	0x828D	# <CJK>
+0xE48A	0x676A	0x8292	# <CJK>
+0xE48B	0x676B	0x82AB	# <CJK>
+0xE48C	0x676C	0x829F	# <CJK>
+0xE48D	0x676D	0x82BB	# <CJK>
+0xE48E	0x676E	0x82AC	# <CJK>
+0xE48F	0x676F	0x82E1	# <CJK>
+0xE490	0x6770	0x82E3	# <CJK>
+0xE491	0x6771	0x82DF	# <CJK>
+0xE492	0x6772	0x82D2	# <CJK>
+0xE493	0x6773	0x82F4	# <CJK>
+0xE494	0x6774	0x82F3	# <CJK>
+0xE495	0x6775	0x82FA	# <CJK>
+0xE496	0x6776	0x8393	# <CJK>
+0xE497	0x6777	0x8303	# <CJK>
+0xE498	0x6778	0x82FB	# <CJK>
+0xE499	0x6779	0x82F9	# <CJK>
+0xE49A	0x677A	0x82DE	# <CJK>
+0xE49B	0x677B	0x8306	# <CJK>
+0xE49C	0x677C	0x82DC	# <CJK>
+0xE49D	0x677D	0x8309	# <CJK>
+0xE49E	0x677E	0x82D9	# <CJK>
+0xE49F	0x6821	0x8335	# <CJK>
+0xE4A0	0x6822	0x8334	# <CJK>
+0xE4A1	0x6823	0x8316	# <CJK>
+0xE4A2	0x6824	0x8332	# <CJK>
+0xE4A3	0x6825	0x8331	# <CJK>
+0xE4A4	0x6826	0x8340	# <CJK>
+0xE4A5	0x6827	0x8339	# <CJK>
+0xE4A6	0x6828	0x8350	# <CJK>
+0xE4A7	0x6829	0x8345	# <CJK>
+0xE4A8	0x682A	0x832F	# <CJK>
+0xE4A9	0x682B	0x832B	# <CJK>
+0xE4AA	0x682C	0x8317	# <CJK>
+0xE4AB	0x682D	0x8318	# <CJK>
+0xE4AC	0x682E	0x8385	# <CJK>
+0xE4AD	0x682F	0x839A	# <CJK>
+0xE4AE	0x6830	0x83AA	# <CJK>
+0xE4AF	0x6831	0x839F	# <CJK>
+0xE4B0	0x6832	0x83A2	# <CJK>
+0xE4B1	0x6833	0x8396	# <CJK>
+0xE4B2	0x6834	0x8323	# <CJK>
+0xE4B3	0x6835	0x838E	# <CJK>
+0xE4B4	0x6836	0x8387	# <CJK>
+0xE4B5	0x6837	0x838A	# <CJK>
+0xE4B6	0x6838	0x837C	# <CJK>
+0xE4B7	0x6839	0x83B5	# <CJK>
+0xE4B8	0x683A	0x8373	# <CJK>
+0xE4B9	0x683B	0x8375	# <CJK>
+0xE4BA	0x683C	0x83A0	# <CJK>
+0xE4BB	0x683D	0x8389	# <CJK>
+0xE4BC	0x683E	0x83A8	# <CJK>
+0xE4BD	0x683F	0x83F4	# <CJK>
+0xE4BE	0x6840	0x8413	# <CJK>
+0xE4BF	0x6841	0x83EB	# <CJK>
+0xE4C0	0x6842	0x83CE	# <CJK>
+0xE4C1	0x6843	0x83FD	# <CJK>
+0xE4C2	0x6844	0x8403	# <CJK>
+0xE4C3	0x6845	0x83D8	# <CJK>
+0xE4C4	0x6846	0x840B	# <CJK>
+0xE4C5	0x6847	0x83C1	# <CJK>
+0xE4C6	0x6848	0x83F7	# <CJK>
+0xE4C7	0x6849	0x8407	# <CJK>
+0xE4C8	0x684A	0x83E0	# <CJK>
+0xE4C9	0x684B	0x83F2	# <CJK>
+0xE4CA	0x684C	0x840D	# <CJK>
+0xE4CB	0x684D	0x8422	# <CJK>
+0xE4CC	0x684E	0x8420	# <CJK>
+0xE4CD	0x684F	0x83BD	# <CJK>
+0xE4CE	0x6850	0x8438	# <CJK>
+0xE4CF	0x6851	0x8506	# <CJK>
+0xE4D0	0x6852	0x83FB	# <CJK>
+0xE4D1	0x6853	0x846D	# <CJK>
+0xE4D2	0x6854	0x842A	# <CJK>
+0xE4D3	0x6855	0x843C	# <CJK>
+0xE4D4	0x6856	0x855A	# <CJK>
+0xE4D5	0x6857	0x8484	# <CJK>
+0xE4D6	0x6858	0x8477	# <CJK>
+0xE4D7	0x6859	0x846B	# <CJK>
+0xE4D8	0x685A	0x84AD	# <CJK>
+0xE4D9	0x685B	0x846E	# <CJK>
+0xE4DA	0x685C	0x8482	# <CJK>
+0xE4DB	0x685D	0x8469	# <CJK>
+0xE4DC	0x685E	0x8446	# <CJK>
+0xE4DD	0x685F	0x842C	# <CJK>
+0xE4DE	0x6860	0x846F	# <CJK>
+0xE4DF	0x6861	0x8479	# <CJK>
+0xE4E0	0x6862	0x8435	# <CJK>
+0xE4E1	0x6863	0x84CA	# <CJK>
+0xE4E2	0x6864	0x8462	# <CJK>
+0xE4E3	0x6865	0x84B9	# <CJK>
+0xE4E4	0x6866	0x84BF	# <CJK>
+0xE4E5	0x6867	0x849F	# <CJK>
+0xE4E6	0x6868	0x84D9	# <CJK>
+0xE4E7	0x6869	0x84CD	# <CJK>
+0xE4E8	0x686A	0x84BB	# <CJK>
+0xE4E9	0x686B	0x84DA	# <CJK>
+0xE4EA	0x686C	0x84D0	# <CJK>
+0xE4EB	0x686D	0x84C1	# <CJK>
+0xE4EC	0x686E	0x84C6	# <CJK>
+0xE4ED	0x686F	0x84D6	# <CJK>
+0xE4EE	0x6870	0x84A1	# <CJK>
+0xE4EF	0x6871	0x8521	# <CJK>
+0xE4F0	0x6872	0x84FF	# <CJK>
+0xE4F1	0x6873	0x84F4	# <CJK>
+0xE4F2	0x6874	0x8517	# <CJK>
+0xE4F3	0x6875	0x8518	# <CJK>
+0xE4F4	0x6876	0x852C	# <CJK>
+0xE4F5	0x6877	0x851F	# <CJK>
+0xE4F6	0x6878	0x8515	# <CJK>
+0xE4F7	0x6879	0x8514	# <CJK>
+0xE4F8	0x687A	0x84FC	# <CJK>
+0xE4F9	0x687B	0x8540	# <CJK>
+0xE4FA	0x687C	0x8563	# <CJK>
+0xE4FB	0x687D	0x8558	# <CJK>
+0xE4FC	0x687E	0x8548	# <CJK>
+0xE540	0x6921	0x8541	# <CJK>
+0xE541	0x6922	0x8602	# <CJK>
+0xE542	0x6923	0x854B	# <CJK>
+0xE543	0x6924	0x8555	# <CJK>
+0xE544	0x6925	0x8580	# <CJK>
+0xE545	0x6926	0x85A4	# <CJK>
+0xE546	0x6927	0x8588	# <CJK>
+0xE547	0x6928	0x8591	# <CJK>
+0xE548	0x6929	0x858A	# <CJK>
+0xE549	0x692A	0x85A8	# <CJK>
+0xE54A	0x692B	0x856D	# <CJK>
+0xE54B	0x692C	0x8594	# <CJK>
+0xE54C	0x692D	0x859B	# <CJK>
+0xE54D	0x692E	0x85EA	# <CJK>
+0xE54E	0x692F	0x8587	# <CJK>
+0xE54F	0x6930	0x859C	# <CJK>
+0xE550	0x6931	0x8577	# <CJK>
+0xE551	0x6932	0x857E	# <CJK>
+0xE552	0x6933	0x8590	# <CJK>
+0xE553	0x6934	0x85C9	# <CJK>
+0xE554	0x6935	0x85BA	# <CJK>
+0xE555	0x6936	0x85CF	# <CJK>
+0xE556	0x6937	0x85B9	# <CJK>
+0xE557	0x6938	0x85D0	# <CJK>
+0xE558	0x6939	0x85D5	# <CJK>
+0xE559	0x693A	0x85DD	# <CJK>
+0xE55A	0x693B	0x85E5	# <CJK>
+0xE55B	0x693C	0x85DC	# <CJK>
+0xE55C	0x693D	0x85F9	# <CJK>
+0xE55D	0x693E	0x860A	# <CJK>
+0xE55E	0x693F	0x8613	# <CJK>
+0xE55F	0x6940	0x860B	# <CJK>
+0xE560	0x6941	0x85FE	# <CJK>
+0xE561	0x6942	0x85FA	# <CJK>
+0xE562	0x6943	0x8606	# <CJK>
+0xE563	0x6944	0x8622	# <CJK>
+0xE564	0x6945	0x861A	# <CJK>
+0xE565	0x6946	0x8630	# <CJK>
+0xE566	0x6947	0x863F	# <CJK>
+0xE567	0x6948	0x864D	# <CJK>
+0xE568	0x6949	0x4E55	# <CJK>
+0xE569	0x694A	0x8654	# <CJK>
+0xE56A	0x694B	0x865F	# <CJK>
+0xE56B	0x694C	0x8667	# <CJK>
+0xE56C	0x694D	0x8671	# <CJK>
+0xE56D	0x694E	0x8693	# <CJK>
+0xE56E	0x694F	0x86A3	# <CJK>
+0xE56F	0x6950	0x86A9	# <CJK>
+0xE570	0x6951	0x86AA	# <CJK>
+0xE571	0x6952	0x868B	# <CJK>
+0xE572	0x6953	0x868C	# <CJK>
+0xE573	0x6954	0x86B6	# <CJK>
+0xE574	0x6955	0x86AF	# <CJK>
+0xE575	0x6956	0x86C4	# <CJK>
+0xE576	0x6957	0x86C6	# <CJK>
+0xE577	0x6958	0x86B0	# <CJK>
+0xE578	0x6959	0x86C9	# <CJK>
+0xE579	0x695A	0x8823	# <CJK>
+0xE57A	0x695B	0x86AB	# <CJK>
+0xE57B	0x695C	0x86D4	# <CJK>
+0xE57C	0x695D	0x86DE	# <CJK>
+0xE57D	0x695E	0x86E9	# <CJK>
+0xE57E	0x695F	0x86EC	# <CJK>
+0xE580	0x6960	0x86DF	# <CJK>
+0xE581	0x6961	0x86DB	# <CJK>
+0xE582	0x6962	0x86EF	# <CJK>
+0xE583	0x6963	0x8712	# <CJK>
+0xE584	0x6964	0x8706	# <CJK>
+0xE585	0x6965	0x8708	# <CJK>
+0xE586	0x6966	0x8700	# <CJK>
+0xE587	0x6967	0x8703	# <CJK>
+0xE588	0x6968	0x86FB	# <CJK>
+0xE589	0x6969	0x8711	# <CJK>
+0xE58A	0x696A	0x8709	# <CJK>
+0xE58B	0x696B	0x870D	# <CJK>
+0xE58C	0x696C	0x86F9	# <CJK>
+0xE58D	0x696D	0x870A	# <CJK>
+0xE58E	0x696E	0x8734	# <CJK>
+0xE58F	0x696F	0x873F	# <CJK>
+0xE590	0x6970	0x8737	# <CJK>
+0xE591	0x6971	0x873B	# <CJK>
+0xE592	0x6972	0x8725	# <CJK>
+0xE593	0x6973	0x8729	# <CJK>
+0xE594	0x6974	0x871A	# <CJK>
+0xE595	0x6975	0x8760	# <CJK>
+0xE596	0x6976	0x875F	# <CJK>
+0xE597	0x6977	0x8778	# <CJK>
+0xE598	0x6978	0x874C	# <CJK>
+0xE599	0x6979	0x874E	# <CJK>
+0xE59A	0x697A	0x8774	# <CJK>
+0xE59B	0x697B	0x8757	# <CJK>
+0xE59C	0x697C	0x8768	# <CJK>
+0xE59D	0x697D	0x876E	# <CJK>
+0xE59E	0x697E	0x8759	# <CJK>
+0xE59F	0x6A21	0x8753	# <CJK>
+0xE5A0	0x6A22	0x8763	# <CJK>
+0xE5A1	0x6A23	0x876A	# <CJK>
+0xE5A2	0x6A24	0x8805	# <CJK>
+0xE5A3	0x6A25	0x87A2	# <CJK>
+0xE5A4	0x6A26	0x879F	# <CJK>
+0xE5A5	0x6A27	0x8782	# <CJK>
+0xE5A6	0x6A28	0x87AF	# <CJK>
+0xE5A7	0x6A29	0x87CB	# <CJK>
+0xE5A8	0x6A2A	0x87BD	# <CJK>
+0xE5A9	0x6A2B	0x87C0	# <CJK>
+0xE5AA	0x6A2C	0x87D0	# <CJK>
+0xE5AB	0x6A2D	0x96D6	# <CJK>
+0xE5AC	0x6A2E	0x87AB	# <CJK>
+0xE5AD	0x6A2F	0x87C4	# <CJK>
+0xE5AE	0x6A30	0x87B3	# <CJK>
+0xE5AF	0x6A31	0x87C7	# <CJK>
+0xE5B0	0x6A32	0x87C6	# <CJK>
+0xE5B1	0x6A33	0x87BB	# <CJK>
+0xE5B2	0x6A34	0x87EF	# <CJK>
+0xE5B3	0x6A35	0x87F2	# <CJK>
+0xE5B4	0x6A36	0x87E0	# <CJK>
+0xE5B5	0x6A37	0x880F	# <CJK>
+0xE5B6	0x6A38	0x880D	# <CJK>
+0xE5B7	0x6A39	0x87FE	# <CJK>
+0xE5B8	0x6A3A	0x87F6	# <CJK>
+0xE5B9	0x6A3B	0x87F7	# <CJK>
+0xE5BA	0x6A3C	0x880E	# <CJK>
+0xE5BB	0x6A3D	0x87D2	# <CJK>
+0xE5BC	0x6A3E	0x8811	# <CJK>
+0xE5BD	0x6A3F	0x8816	# <CJK>
+0xE5BE	0x6A40	0x8815	# <CJK>
+0xE5BF	0x6A41	0x8822	# <CJK>
+0xE5C0	0x6A42	0x8821	# <CJK>
+0xE5C1	0x6A43	0x8831	# <CJK>
+0xE5C2	0x6A44	0x8836	# <CJK>
+0xE5C3	0x6A45	0x8839	# <CJK>
+0xE5C4	0x6A46	0x8827	# <CJK>
+0xE5C5	0x6A47	0x883B	# <CJK>
+0xE5C6	0x6A48	0x8844	# <CJK>
+0xE5C7	0x6A49	0x8842	# <CJK>
+0xE5C8	0x6A4A	0x8852	# <CJK>
+0xE5C9	0x6A4B	0x8859	# <CJK>
+0xE5CA	0x6A4C	0x885E	# <CJK>
+0xE5CB	0x6A4D	0x8862	# <CJK>
+0xE5CC	0x6A4E	0x886B	# <CJK>
+0xE5CD	0x6A4F	0x8881	# <CJK>
+0xE5CE	0x6A50	0x887E	# <CJK>
+0xE5CF	0x6A51	0x889E	# <CJK>
+0xE5D0	0x6A52	0x8875	# <CJK>
+0xE5D1	0x6A53	0x887D	# <CJK>
+0xE5D2	0x6A54	0x88B5	# <CJK>
+0xE5D3	0x6A55	0x8872	# <CJK>
+0xE5D4	0x6A56	0x8882	# <CJK>
+0xE5D5	0x6A57	0x8897	# <CJK>
+0xE5D6	0x6A58	0x8892	# <CJK>
+0xE5D7	0x6A59	0x88AE	# <CJK>
+0xE5D8	0x6A5A	0x8899	# <CJK>
+0xE5D9	0x6A5B	0x88A2	# <CJK>
+0xE5DA	0x6A5C	0x888D	# <CJK>
+0xE5DB	0x6A5D	0x88A4	# <CJK>
+0xE5DC	0x6A5E	0x88B0	# <CJK>
+0xE5DD	0x6A5F	0x88BF	# <CJK>
+0xE5DE	0x6A60	0x88B1	# <CJK>
+0xE5DF	0x6A61	0x88C3	# <CJK>
+0xE5E0	0x6A62	0x88C4	# <CJK>
+0xE5E1	0x6A63	0x88D4	# <CJK>
+0xE5E2	0x6A64	0x88D8	# <CJK>
+0xE5E3	0x6A65	0x88D9	# <CJK>
+0xE5E4	0x6A66	0x88DD	# <CJK>
+0xE5E5	0x6A67	0x88F9	# <CJK>
+0xE5E6	0x6A68	0x8902	# <CJK>
+0xE5E7	0x6A69	0x88FC	# <CJK>
+0xE5E8	0x6A6A	0x88F4	# <CJK>
+0xE5E9	0x6A6B	0x88E8	# <CJK>
+0xE5EA	0x6A6C	0x88F2	# <CJK>
+0xE5EB	0x6A6D	0x8904	# <CJK>
+0xE5EC	0x6A6E	0x890C	# <CJK>
+0xE5ED	0x6A6F	0x890A	# <CJK>
+0xE5EE	0x6A70	0x8913	# <CJK>
+0xE5EF	0x6A71	0x8943	# <CJK>
+0xE5F0	0x6A72	0x891E	# <CJK>
+0xE5F1	0x6A73	0x8925	# <CJK>
+0xE5F2	0x6A74	0x892A	# <CJK>
+0xE5F3	0x6A75	0x892B	# <CJK>
+0xE5F4	0x6A76	0x8941	# <CJK>
+0xE5F5	0x6A77	0x8944	# <CJK>
+0xE5F6	0x6A78	0x893B	# <CJK>
+0xE5F7	0x6A79	0x8936	# <CJK>
+0xE5F8	0x6A7A	0x8938	# <CJK>
+0xE5F9	0x6A7B	0x894C	# <CJK>
+0xE5FA	0x6A7C	0x891D	# <CJK>
+0xE5FB	0x6A7D	0x8960	# <CJK>
+0xE5FC	0x6A7E	0x895E	# <CJK>
+0xE640	0x6B21	0x8966	# <CJK>
+0xE641	0x6B22	0x8964	# <CJK>
+0xE642	0x6B23	0x896D	# <CJK>
+0xE643	0x6B24	0x896A	# <CJK>
+0xE644	0x6B25	0x896F	# <CJK>
+0xE645	0x6B26	0x8974	# <CJK>
+0xE646	0x6B27	0x8977	# <CJK>
+0xE647	0x6B28	0x897E	# <CJK>
+0xE648	0x6B29	0x8983	# <CJK>
+0xE649	0x6B2A	0x8988	# <CJK>
+0xE64A	0x6B2B	0x898A	# <CJK>
+0xE64B	0x6B2C	0x8993	# <CJK>
+0xE64C	0x6B2D	0x8998	# <CJK>
+0xE64D	0x6B2E	0x89A1	# <CJK>
+0xE64E	0x6B2F	0x89A9	# <CJK>
+0xE64F	0x6B30	0x89A6	# <CJK>
+0xE650	0x6B31	0x89AC	# <CJK>
+0xE651	0x6B32	0x89AF	# <CJK>
+0xE652	0x6B33	0x89B2	# <CJK>
+0xE653	0x6B34	0x89BA	# <CJK>
+0xE654	0x6B35	0x89BD	# <CJK>
+0xE655	0x6B36	0x89BF	# <CJK>
+0xE656	0x6B37	0x89C0	# <CJK>
+0xE657	0x6B38	0x89DA	# <CJK>
+0xE658	0x6B39	0x89DC	# <CJK>
+0xE659	0x6B3A	0x89DD	# <CJK>
+0xE65A	0x6B3B	0x89E7	# <CJK>
+0xE65B	0x6B3C	0x89F4	# <CJK>
+0xE65C	0x6B3D	0x89F8	# <CJK>
+0xE65D	0x6B3E	0x8A03	# <CJK>
+0xE65E	0x6B3F	0x8A16	# <CJK>
+0xE65F	0x6B40	0x8A10	# <CJK>
+0xE660	0x6B41	0x8A0C	# <CJK>
+0xE661	0x6B42	0x8A1B	# <CJK>
+0xE662	0x6B43	0x8A1D	# <CJK>
+0xE663	0x6B44	0x8A25	# <CJK>
+0xE664	0x6B45	0x8A36	# <CJK>
+0xE665	0x6B46	0x8A41	# <CJK>
+0xE666	0x6B47	0x8A5B	# <CJK>
+0xE667	0x6B48	0x8A52	# <CJK>
+0xE668	0x6B49	0x8A46	# <CJK>
+0xE669	0x6B4A	0x8A48	# <CJK>
+0xE66A	0x6B4B	0x8A7C	# <CJK>
+0xE66B	0x6B4C	0x8A6D	# <CJK>
+0xE66C	0x6B4D	0x8A6C	# <CJK>
+0xE66D	0x6B4E	0x8A62	# <CJK>
+0xE66E	0x6B4F	0x8A85	# <CJK>
+0xE66F	0x6B50	0x8A82	# <CJK>
+0xE670	0x6B51	0x8A84	# <CJK>
+0xE671	0x6B52	0x8AA8	# <CJK>
+0xE672	0x6B53	0x8AA1	# <CJK>
+0xE673	0x6B54	0x8A91	# <CJK>
+0xE674	0x6B55	0x8AA5	# <CJK>
+0xE675	0x6B56	0x8AA6	# <CJK>
+0xE676	0x6B57	0x8A9A	# <CJK>
+0xE677	0x6B58	0x8AA3	# <CJK>
+0xE678	0x6B59	0x8AC4	# <CJK>
+0xE679	0x6B5A	0x8ACD	# <CJK>
+0xE67A	0x6B5B	0x8AC2	# <CJK>
+0xE67B	0x6B5C	0x8ADA	# <CJK>
+0xE67C	0x6B5D	0x8AEB	# <CJK>
+0xE67D	0x6B5E	0x8AF3	# <CJK>
+0xE67E	0x6B5F	0x8AE7	# <CJK>
+0xE680	0x6B60	0x8AE4	# <CJK>
+0xE681	0x6B61	0x8AF1	# <CJK>
+0xE682	0x6B62	0x8B14	# <CJK>
+0xE683	0x6B63	0x8AE0	# <CJK>
+0xE684	0x6B64	0x8AE2	# <CJK>
+0xE685	0x6B65	0x8AF7	# <CJK>
+0xE686	0x6B66	0x8ADE	# <CJK>
+0xE687	0x6B67	0x8ADB	# <CJK>
+0xE688	0x6B68	0x8B0C	# <CJK>
+0xE689	0x6B69	0x8B07	# <CJK>
+0xE68A	0x6B6A	0x8B1A	# <CJK>
+0xE68B	0x6B6B	0x8AE1	# <CJK>
+0xE68C	0x6B6C	0x8B16	# <CJK>
+0xE68D	0x6B6D	0x8B10	# <CJK>
+0xE68E	0x6B6E	0x8B17	# <CJK>
+0xE68F	0x6B6F	0x8B20	# <CJK>
+0xE690	0x6B70	0x8B33	# <CJK>
+0xE691	0x6B71	0x97AB	# <CJK>
+0xE692	0x6B72	0x8B26	# <CJK>
+0xE693	0x6B73	0x8B2B	# <CJK>
+0xE694	0x6B74	0x8B3E	# <CJK>
+0xE695	0x6B75	0x8B28	# <CJK>
+0xE696	0x6B76	0x8B41	# <CJK>
+0xE697	0x6B77	0x8B4C	# <CJK>
+0xE698	0x6B78	0x8B4F	# <CJK>
+0xE699	0x6B79	0x8B4E	# <CJK>
+0xE69A	0x6B7A	0x8B49	# <CJK>
+0xE69B	0x6B7B	0x8B56	# <CJK>
+0xE69C	0x6B7C	0x8B5B	# <CJK>
+0xE69D	0x6B7D	0x8B5A	# <CJK>
+0xE69E	0x6B7E	0x8B6B	# <CJK>
+0xE69F	0x6C21	0x8B5F	# <CJK>
+0xE6A0	0x6C22	0x8B6C	# <CJK>
+0xE6A1	0x6C23	0x8B6F	# <CJK>
+0xE6A2	0x6C24	0x8B74	# <CJK>
+0xE6A3	0x6C25	0x8B7D	# <CJK>
+0xE6A4	0x6C26	0x8B80	# <CJK>
+0xE6A5	0x6C27	0x8B8C	# <CJK>
+0xE6A6	0x6C28	0x8B8E	# <CJK>
+0xE6A7	0x6C29	0x8B92	# <CJK>
+0xE6A8	0x6C2A	0x8B93	# <CJK>
+0xE6A9	0x6C2B	0x8B96	# <CJK>
+0xE6AA	0x6C2C	0x8B99	# <CJK>
+0xE6AB	0x6C2D	0x8B9A	# <CJK>
+0xE6AC	0x6C2E	0x8C3A	# <CJK>
+0xE6AD	0x6C2F	0x8C41	# <CJK>
+0xE6AE	0x6C30	0x8C3F	# <CJK>
+0xE6AF	0x6C31	0x8C48	# <CJK>
+0xE6B0	0x6C32	0x8C4C	# <CJK>
+0xE6B1	0x6C33	0x8C4E	# <CJK>
+0xE6B2	0x6C34	0x8C50	# <CJK>
+0xE6B3	0x6C35	0x8C55	# <CJK>
+0xE6B4	0x6C36	0x8C62	# <CJK>
+0xE6B5	0x6C37	0x8C6C	# <CJK>
+0xE6B6	0x6C38	0x8C78	# <CJK>
+0xE6B7	0x6C39	0x8C7A	# <CJK>
+0xE6B8	0x6C3A	0x8C82	# <CJK>
+0xE6B9	0x6C3B	0x8C89	# <CJK>
+0xE6BA	0x6C3C	0x8C85	# <CJK>
+0xE6BB	0x6C3D	0x8C8A	# <CJK>
+0xE6BC	0x6C3E	0x8C8D	# <CJK>
+0xE6BD	0x6C3F	0x8C8E	# <CJK>
+0xE6BE	0x6C40	0x8C94	# <CJK>
+0xE6BF	0x6C41	0x8C7C	# <CJK>
+0xE6C0	0x6C42	0x8C98	# <CJK>
+0xE6C1	0x6C43	0x621D	# <CJK>
+0xE6C2	0x6C44	0x8CAD	# <CJK>
+0xE6C3	0x6C45	0x8CAA	# <CJK>
+0xE6C4	0x6C46	0x8CBD	# <CJK>
+0xE6C5	0x6C47	0x8CB2	# <CJK>
+0xE6C6	0x6C48	0x8CB3	# <CJK>
+0xE6C7	0x6C49	0x8CAE	# <CJK>
+0xE6C8	0x6C4A	0x8CB6	# <CJK>
+0xE6C9	0x6C4B	0x8CC8	# <CJK>
+0xE6CA	0x6C4C	0x8CC1	# <CJK>
+0xE6CB	0x6C4D	0x8CE4	# <CJK>
+0xE6CC	0x6C4E	0x8CE3	# <CJK>
+0xE6CD	0x6C4F	0x8CDA	# <CJK>
+0xE6CE	0x6C50	0x8CFD	# <CJK>
+0xE6CF	0x6C51	0x8CFA	# <CJK>
+0xE6D0	0x6C52	0x8CFB	# <CJK>
+0xE6D1	0x6C53	0x8D04	# <CJK>
+0xE6D2	0x6C54	0x8D05	# <CJK>
+0xE6D3	0x6C55	0x8D0A	# <CJK>
+0xE6D4	0x6C56	0x8D07	# <CJK>
+0xE6D5	0x6C57	0x8D0F	# <CJK>
+0xE6D6	0x6C58	0x8D0D	# <CJK>
+0xE6D7	0x6C59	0x8D10	# <CJK>
+0xE6D8	0x6C5A	0x9F4E	# <CJK>
+0xE6D9	0x6C5B	0x8D13	# <CJK>
+0xE6DA	0x6C5C	0x8CCD	# <CJK>
+0xE6DB	0x6C5D	0x8D14	# <CJK>
+0xE6DC	0x6C5E	0x8D16	# <CJK>
+0xE6DD	0x6C5F	0x8D67	# <CJK>
+0xE6DE	0x6C60	0x8D6D	# <CJK>
+0xE6DF	0x6C61	0x8D71	# <CJK>
+0xE6E0	0x6C62	0x8D73	# <CJK>
+0xE6E1	0x6C63	0x8D81	# <CJK>
+0xE6E2	0x6C64	0x8D99	# <CJK>
+0xE6E3	0x6C65	0x8DC2	# <CJK>
+0xE6E4	0x6C66	0x8DBE	# <CJK>
+0xE6E5	0x6C67	0x8DBA	# <CJK>
+0xE6E6	0x6C68	0x8DCF	# <CJK>
+0xE6E7	0x6C69	0x8DDA	# <CJK>
+0xE6E8	0x6C6A	0x8DD6	# <CJK>
+0xE6E9	0x6C6B	0x8DCC	# <CJK>
+0xE6EA	0x6C6C	0x8DDB	# <CJK>
+0xE6EB	0x6C6D	0x8DCB	# <CJK>
+0xE6EC	0x6C6E	0x8DEA	# <CJK>
+0xE6ED	0x6C6F	0x8DEB	# <CJK>
+0xE6EE	0x6C70	0x8DDF	# <CJK>
+0xE6EF	0x6C71	0x8DE3	# <CJK>
+0xE6F0	0x6C72	0x8DFC	# <CJK>
+0xE6F1	0x6C73	0x8E08	# <CJK>
+0xE6F2	0x6C74	0x8E09	# <CJK>
+0xE6F3	0x6C75	0x8DFF	# <CJK>
+0xE6F4	0x6C76	0x8E1D	# <CJK>
+0xE6F5	0x6C77	0x8E1E	# <CJK>
+0xE6F6	0x6C78	0x8E10	# <CJK>
+0xE6F7	0x6C79	0x8E1F	# <CJK>
+0xE6F8	0x6C7A	0x8E42	# <CJK>
+0xE6F9	0x6C7B	0x8E35	# <CJK>
+0xE6FA	0x6C7C	0x8E30	# <CJK>
+0xE6FB	0x6C7D	0x8E34	# <CJK>
+0xE6FC	0x6C7E	0x8E4A	# <CJK>
+0xE740	0x6D21	0x8E47	# <CJK>
+0xE741	0x6D22	0x8E49	# <CJK>
+0xE742	0x6D23	0x8E4C	# <CJK>
+0xE743	0x6D24	0x8E50	# <CJK>
+0xE744	0x6D25	0x8E48	# <CJK>
+0xE745	0x6D26	0x8E59	# <CJK>
+0xE746	0x6D27	0x8E64	# <CJK>
+0xE747	0x6D28	0x8E60	# <CJK>
+0xE748	0x6D29	0x8E2A	# <CJK>
+0xE749	0x6D2A	0x8E63	# <CJK>
+0xE74A	0x6D2B	0x8E55	# <CJK>
+0xE74B	0x6D2C	0x8E76	# <CJK>
+0xE74C	0x6D2D	0x8E72	# <CJK>
+0xE74D	0x6D2E	0x8E7C	# <CJK>
+0xE74E	0x6D2F	0x8E81	# <CJK>
+0xE74F	0x6D30	0x8E87	# <CJK>
+0xE750	0x6D31	0x8E85	# <CJK>
+0xE751	0x6D32	0x8E84	# <CJK>
+0xE752	0x6D33	0x8E8B	# <CJK>
+0xE753	0x6D34	0x8E8A	# <CJK>
+0xE754	0x6D35	0x8E93	# <CJK>
+0xE755	0x6D36	0x8E91	# <CJK>
+0xE756	0x6D37	0x8E94	# <CJK>
+0xE757	0x6D38	0x8E99	# <CJK>
+0xE758	0x6D39	0x8EAA	# <CJK>
+0xE759	0x6D3A	0x8EA1	# <CJK>
+0xE75A	0x6D3B	0x8EAC	# <CJK>
+0xE75B	0x6D3C	0x8EB0	# <CJK>
+0xE75C	0x6D3D	0x8EC6	# <CJK>
+0xE75D	0x6D3E	0x8EB1	# <CJK>
+0xE75E	0x6D3F	0x8EBE	# <CJK>
+0xE75F	0x6D40	0x8EC5	# <CJK>
+0xE760	0x6D41	0x8EC8	# <CJK>
+0xE761	0x6D42	0x8ECB	# <CJK>
+0xE762	0x6D43	0x8EDB	# <CJK>
+0xE763	0x6D44	0x8EE3	# <CJK>
+0xE764	0x6D45	0x8EFC	# <CJK>
+0xE765	0x6D46	0x8EFB	# <CJK>
+0xE766	0x6D47	0x8EEB	# <CJK>
+0xE767	0x6D48	0x8EFE	# <CJK>
+0xE768	0x6D49	0x8F0A	# <CJK>
+0xE769	0x6D4A	0x8F05	# <CJK>
+0xE76A	0x6D4B	0x8F15	# <CJK>
+0xE76B	0x6D4C	0x8F12	# <CJK>
+0xE76C	0x6D4D	0x8F19	# <CJK>
+0xE76D	0x6D4E	0x8F13	# <CJK>
+0xE76E	0x6D4F	0x8F1C	# <CJK>
+0xE76F	0x6D50	0x8F1F	# <CJK>
+0xE770	0x6D51	0x8F1B	# <CJK>
+0xE771	0x6D52	0x8F0C	# <CJK>
+0xE772	0x6D53	0x8F26	# <CJK>
+0xE773	0x6D54	0x8F33	# <CJK>
+0xE774	0x6D55	0x8F3B	# <CJK>
+0xE775	0x6D56	0x8F39	# <CJK>
+0xE776	0x6D57	0x8F45	# <CJK>
+0xE777	0x6D58	0x8F42	# <CJK>
+0xE778	0x6D59	0x8F3E	# <CJK>
+0xE779	0x6D5A	0x8F4C	# <CJK>
+0xE77A	0x6D5B	0x8F49	# <CJK>
+0xE77B	0x6D5C	0x8F46	# <CJK>
+0xE77C	0x6D5D	0x8F4E	# <CJK>
+0xE77D	0x6D5E	0x8F57	# <CJK>
+0xE77E	0x6D5F	0x8F5C	# <CJK>
+0xE780	0x6D60	0x8F62	# <CJK>
+0xE781	0x6D61	0x8F63	# <CJK>
+0xE782	0x6D62	0x8F64	# <CJK>
+0xE783	0x6D63	0x8F9C	# <CJK>
+0xE784	0x6D64	0x8F9F	# <CJK>
+0xE785	0x6D65	0x8FA3	# <CJK>
+0xE786	0x6D66	0x8FAD	# <CJK>
+0xE787	0x6D67	0x8FAF	# <CJK>
+0xE788	0x6D68	0x8FB7	# <CJK>
+0xE789	0x6D69	0x8FDA	# <CJK>
+0xE78A	0x6D6A	0x8FE5	# <CJK>
+0xE78B	0x6D6B	0x8FE2	# <CJK>
+0xE78C	0x6D6C	0x8FEA	# <CJK>
+0xE78D	0x6D6D	0x8FEF	# <CJK>
+0xE78E	0x6D6E	0x9087	# <CJK>
+0xE78F	0x6D6F	0x8FF4	# <CJK>
+0xE790	0x6D70	0x9005	# <CJK>
+0xE791	0x6D71	0x8FF9	# <CJK>
+0xE792	0x6D72	0x8FFA	# <CJK>
+0xE793	0x6D73	0x9011	# <CJK>
+0xE794	0x6D74	0x9015	# <CJK>
+0xE795	0x6D75	0x9021	# <CJK>
+0xE796	0x6D76	0x900D	# <CJK>
+0xE797	0x6D77	0x901E	# <CJK>
+0xE798	0x6D78	0x9016	# <CJK>
+0xE799	0x6D79	0x900B	# <CJK>
+0xE79A	0x6D7A	0x9027	# <CJK>
+0xE79B	0x6D7B	0x9036	# <CJK>
+0xE79C	0x6D7C	0x9035	# <CJK>
+0xE79D	0x6D7D	0x9039	# <CJK>
+0xE79E	0x6D7E	0x8FF8	# <CJK>
+0xE79F	0x6E21	0x904F	# <CJK>
+0xE7A0	0x6E22	0x9050	# <CJK>
+0xE7A1	0x6E23	0x9051	# <CJK>
+0xE7A2	0x6E24	0x9052	# <CJK>
+0xE7A3	0x6E25	0x900E	# <CJK>
+0xE7A4	0x6E26	0x9049	# <CJK>
+0xE7A5	0x6E27	0x903E	# <CJK>
+0xE7A6	0x6E28	0x9056	# <CJK>
+0xE7A7	0x6E29	0x9058	# <CJK>
+0xE7A8	0x6E2A	0x905E	# <CJK>
+0xE7A9	0x6E2B	0x9068	# <CJK>
+0xE7AA	0x6E2C	0x906F	# <CJK>
+0xE7AB	0x6E2D	0x9076	# <CJK>
+0xE7AC	0x6E2E	0x96A8	# <CJK>
+0xE7AD	0x6E2F	0x9072	# <CJK>
+0xE7AE	0x6E30	0x9082	# <CJK>
+0xE7AF	0x6E31	0x907D	# <CJK>
+0xE7B0	0x6E32	0x9081	# <CJK>
+0xE7B1	0x6E33	0x9080	# <CJK>
+0xE7B2	0x6E34	0x908A	# <CJK>
+0xE7B3	0x6E35	0x9089	# <CJK>
+0xE7B4	0x6E36	0x908F	# <CJK>
+0xE7B5	0x6E37	0x90A8	# <CJK>
+0xE7B6	0x6E38	0x90AF	# <CJK>
+0xE7B7	0x6E39	0x90B1	# <CJK>
+0xE7B8	0x6E3A	0x90B5	# <CJK>
+0xE7B9	0x6E3B	0x90E2	# <CJK>
+0xE7BA	0x6E3C	0x90E4	# <CJK>
+0xE7BB	0x6E3D	0x6248	# <CJK>
+0xE7BC	0x6E3E	0x90DB	# <CJK>
+0xE7BD	0x6E3F	0x9102	# <CJK>
+0xE7BE	0x6E40	0x9112	# <CJK>
+0xE7BF	0x6E41	0x9119	# <CJK>
+0xE7C0	0x6E42	0x9132	# <CJK>
+0xE7C1	0x6E43	0x9130	# <CJK>
+0xE7C2	0x6E44	0x914A	# <CJK>
+0xE7C3	0x6E45	0x9156	# <CJK>
+0xE7C4	0x6E46	0x9158	# <CJK>
+0xE7C5	0x6E47	0x9163	# <CJK>
+0xE7C6	0x6E48	0x9165	# <CJK>
+0xE7C7	0x6E49	0x9169	# <CJK>
+0xE7C8	0x6E4A	0x9173	# <CJK>
+0xE7C9	0x6E4B	0x9172	# <CJK>
+0xE7CA	0x6E4C	0x918B	# <CJK>
+0xE7CB	0x6E4D	0x9189	# <CJK>
+0xE7CC	0x6E4E	0x9182	# <CJK>
+0xE7CD	0x6E4F	0x91A2	# <CJK>
+0xE7CE	0x6E50	0x91AB	# <CJK>
+0xE7CF	0x6E51	0x91AF	# <CJK>
+0xE7D0	0x6E52	0x91AA	# <CJK>
+0xE7D1	0x6E53	0x91B5	# <CJK>
+0xE7D2	0x6E54	0x91B4	# <CJK>
+0xE7D3	0x6E55	0x91BA	# <CJK>
+0xE7D4	0x6E56	0x91C0	# <CJK>
+0xE7D5	0x6E57	0x91C1	# <CJK>
+0xE7D6	0x6E58	0x91C9	# <CJK>
+0xE7D7	0x6E59	0x91CB	# <CJK>
+0xE7D8	0x6E5A	0x91D0	# <CJK>
+0xE7D9	0x6E5B	0x91D6	# <CJK>
+0xE7DA	0x6E5C	0x91DF	# <CJK>
+0xE7DB	0x6E5D	0x91E1	# <CJK>
+0xE7DC	0x6E5E	0x91DB	# <CJK>
+0xE7DD	0x6E5F	0x91FC	# <CJK>
+0xE7DE	0x6E60	0x91F5	# <CJK>
+0xE7DF	0x6E61	0x91F6	# <CJK>
+0xE7E0	0x6E62	0x921E	# <CJK>
+0xE7E1	0x6E63	0x91FF	# <CJK>
+0xE7E2	0x6E64	0x9214	# <CJK>
+0xE7E3	0x6E65	0x922C	# <CJK>
+0xE7E4	0x6E66	0x9215	# <CJK>
+0xE7E5	0x6E67	0x9211	# <CJK>
+0xE7E6	0x6E68	0x925E	# <CJK>
+0xE7E7	0x6E69	0x9257	# <CJK>
+0xE7E8	0x6E6A	0x9245	# <CJK>
+0xE7E9	0x6E6B	0x9249	# <CJK>
+0xE7EA	0x6E6C	0x9264	# <CJK>
+0xE7EB	0x6E6D	0x9248	# <CJK>
+0xE7EC	0x6E6E	0x9295	# <CJK>
+0xE7ED	0x6E6F	0x923F	# <CJK>
+0xE7EE	0x6E70	0x924B	# <CJK>
+0xE7EF	0x6E71	0x9250	# <CJK>
+0xE7F0	0x6E72	0x929C	# <CJK>
+0xE7F1	0x6E73	0x9296	# <CJK>
+0xE7F2	0x6E74	0x9293	# <CJK>
+0xE7F3	0x6E75	0x929B	# <CJK>
+0xE7F4	0x6E76	0x925A	# <CJK>
+0xE7F5	0x6E77	0x92CF	# <CJK>
+0xE7F6	0x6E78	0x92B9	# <CJK>
+0xE7F7	0x6E79	0x92B7	# <CJK>
+0xE7F8	0x6E7A	0x92E9	# <CJK>
+0xE7F9	0x6E7B	0x930F	# <CJK>
+0xE7FA	0x6E7C	0x92FA	# <CJK>
+0xE7FB	0x6E7D	0x9344	# <CJK>
+0xE7FC	0x6E7E	0x932E	# <CJK>
+0xE840	0x6F21	0x9319	# <CJK>
+0xE841	0x6F22	0x9322	# <CJK>
+0xE842	0x6F23	0x931A	# <CJK>
+0xE843	0x6F24	0x9323	# <CJK>
+0xE844	0x6F25	0x933A	# <CJK>
+0xE845	0x6F26	0x9335	# <CJK>
+0xE846	0x6F27	0x933B	# <CJK>
+0xE847	0x6F28	0x935C	# <CJK>
+0xE848	0x6F29	0x9360	# <CJK>
+0xE849	0x6F2A	0x937C	# <CJK>
+0xE84A	0x6F2B	0x936E	# <CJK>
+0xE84B	0x6F2C	0x9356	# <CJK>
+0xE84C	0x6F2D	0x93B0	# <CJK>
+0xE84D	0x6F2E	0x93AC	# <CJK>
+0xE84E	0x6F2F	0x93AD	# <CJK>
+0xE84F	0x6F30	0x9394	# <CJK>
+0xE850	0x6F31	0x93B9	# <CJK>
+0xE851	0x6F32	0x93D6	# <CJK>
+0xE852	0x6F33	0x93D7	# <CJK>
+0xE853	0x6F34	0x93E8	# <CJK>
+0xE854	0x6F35	0x93E5	# <CJK>
+0xE855	0x6F36	0x93D8	# <CJK>
+0xE856	0x6F37	0x93C3	# <CJK>
+0xE857	0x6F38	0x93DD	# <CJK>
+0xE858	0x6F39	0x93D0	# <CJK>
+0xE859	0x6F3A	0x93C8	# <CJK>
+0xE85A	0x6F3B	0x93E4	# <CJK>
+0xE85B	0x6F3C	0x941A	# <CJK>
+0xE85C	0x6F3D	0x9414	# <CJK>
+0xE85D	0x6F3E	0x9413	# <CJK>
+0xE85E	0x6F3F	0x9403	# <CJK>
+0xE85F	0x6F40	0x9407	# <CJK>
+0xE860	0x6F41	0x9410	# <CJK>
+0xE861	0x6F42	0x9436	# <CJK>
+0xE862	0x6F43	0x942B	# <CJK>
+0xE863	0x6F44	0x9435	# <CJK>
+0xE864	0x6F45	0x9421	# <CJK>
+0xE865	0x6F46	0x943A	# <CJK>
+0xE866	0x6F47	0x9441	# <CJK>
+0xE867	0x6F48	0x9452	# <CJK>
+0xE868	0x6F49	0x9444	# <CJK>
+0xE869	0x6F4A	0x945B	# <CJK>
+0xE86A	0x6F4B	0x9460	# <CJK>
+0xE86B	0x6F4C	0x9462	# <CJK>
+0xE86C	0x6F4D	0x945E	# <CJK>
+0xE86D	0x6F4E	0x946A	# <CJK>
+0xE86E	0x6F4F	0x9229	# <CJK>
+0xE86F	0x6F50	0x9470	# <CJK>
+0xE870	0x6F51	0x9475	# <CJK>
+0xE871	0x6F52	0x9477	# <CJK>
+0xE872	0x6F53	0x947D	# <CJK>
+0xE873	0x6F54	0x945A	# <CJK>
+0xE874	0x6F55	0x947C	# <CJK>
+0xE875	0x6F56	0x947E	# <CJK>
+0xE876	0x6F57	0x9481	# <CJK>
+0xE877	0x6F58	0x947F	# <CJK>
+0xE878	0x6F59	0x9582	# <CJK>
+0xE879	0x6F5A	0x9587	# <CJK>
+0xE87A	0x6F5B	0x958A	# <CJK>
+0xE87B	0x6F5C	0x9594	# <CJK>
+0xE87C	0x6F5D	0x9596	# <CJK>
+0xE87D	0x6F5E	0x9598	# <CJK>
+0xE87E	0x6F5F	0x9599	# <CJK>
+0xE880	0x6F60	0x95A0	# <CJK>
+0xE881	0x6F61	0x95A8	# <CJK>
+0xE882	0x6F62	0x95A7	# <CJK>
+0xE883	0x6F63	0x95AD	# <CJK>
+0xE884	0x6F64	0x95BC	# <CJK>
+0xE885	0x6F65	0x95BB	# <CJK>
+0xE886	0x6F66	0x95B9	# <CJK>
+0xE887	0x6F67	0x95BE	# <CJK>
+0xE888	0x6F68	0x95CA	# <CJK>
+0xE889	0x6F69	0x6FF6	# <CJK>
+0xE88A	0x6F6A	0x95C3	# <CJK>
+0xE88B	0x6F6B	0x95CD	# <CJK>
+0xE88C	0x6F6C	0x95CC	# <CJK>
+0xE88D	0x6F6D	0x95D5	# <CJK>
+0xE88E	0x6F6E	0x95D4	# <CJK>
+0xE88F	0x6F6F	0x95D6	# <CJK>
+0xE890	0x6F70	0x95DC	# <CJK>
+0xE891	0x6F71	0x95E1	# <CJK>
+0xE892	0x6F72	0x95E5	# <CJK>
+0xE893	0x6F73	0x95E2	# <CJK>
+0xE894	0x6F74	0x9621	# <CJK>
+0xE895	0x6F75	0x9628	# <CJK>
+0xE896	0x6F76	0x962E	# <CJK>
+0xE897	0x6F77	0x962F	# <CJK>
+0xE898	0x6F78	0x9642	# <CJK>
+0xE899	0x6F79	0x964C	# <CJK>
+0xE89A	0x6F7A	0x964F	# <CJK>
+0xE89B	0x6F7B	0x964B	# <CJK>
+0xE89C	0x6F7C	0x9677	# <CJK>
+0xE89D	0x6F7D	0x965C	# <CJK>
+0xE89E	0x6F7E	0x965E	# <CJK>
+0xE89F	0x7021	0x965D	# <CJK>
+0xE8A0	0x7022	0x965F	# <CJK>
+0xE8A1	0x7023	0x9666	# <CJK>
+0xE8A2	0x7024	0x9672	# <CJK>
+0xE8A3	0x7025	0x966C	# <CJK>
+0xE8A4	0x7026	0x968D	# <CJK>
+0xE8A5	0x7027	0x9698	# <CJK>
+0xE8A6	0x7028	0x9695	# <CJK>
+0xE8A7	0x7029	0x9697	# <CJK>
+0xE8A8	0x702A	0x96AA	# <CJK>
+0xE8A9	0x702B	0x96A7	# <CJK>
+0xE8AA	0x702C	0x96B1	# <CJK>
+0xE8AB	0x702D	0x96B2	# <CJK>
+0xE8AC	0x702E	0x96B0	# <CJK>
+0xE8AD	0x702F	0x96B4	# <CJK>
+0xE8AE	0x7030	0x96B6	# <CJK>
+0xE8AF	0x7031	0x96B8	# <CJK>
+0xE8B0	0x7032	0x96B9	# <CJK>
+0xE8B1	0x7033	0x96CE	# <CJK>
+0xE8B2	0x7034	0x96CB	# <CJK>
+0xE8B3	0x7035	0x96C9	# <CJK>
+0xE8B4	0x7036	0x96CD	# <CJK>
+0xE8B5	0x7037	0x894D	# <CJK>
+0xE8B6	0x7038	0x96DC	# <CJK>
+0xE8B7	0x7039	0x970D	# <CJK>
+0xE8B8	0x703A	0x96D5	# <CJK>
+0xE8B9	0x703B	0x96F9	# <CJK>
+0xE8BA	0x703C	0x9704	# <CJK>
+0xE8BB	0x703D	0x9706	# <CJK>
+0xE8BC	0x703E	0x9708	# <CJK>
+0xE8BD	0x703F	0x9713	# <CJK>
+0xE8BE	0x7040	0x970E	# <CJK>
+0xE8BF	0x7041	0x9711	# <CJK>
+0xE8C0	0x7042	0x970F	# <CJK>
+0xE8C1	0x7043	0x9716	# <CJK>
+0xE8C2	0x7044	0x9719	# <CJK>
+0xE8C3	0x7045	0x9724	# <CJK>
+0xE8C4	0x7046	0x972A	# <CJK>
+0xE8C5	0x7047	0x9730	# <CJK>
+0xE8C6	0x7048	0x9739	# <CJK>
+0xE8C7	0x7049	0x973D	# <CJK>
+0xE8C8	0x704A	0x973E	# <CJK>
+0xE8C9	0x704B	0x9744	# <CJK>
+0xE8CA	0x704C	0x9746	# <CJK>
+0xE8CB	0x704D	0x9748	# <CJK>
+0xE8CC	0x704E	0x9742	# <CJK>
+0xE8CD	0x704F	0x9749	# <CJK>
+0xE8CE	0x7050	0x975C	# <CJK>
+0xE8CF	0x7051	0x9760	# <CJK>
+0xE8D0	0x7052	0x9764	# <CJK>
+0xE8D1	0x7053	0x9766	# <CJK>
+0xE8D2	0x7054	0x9768	# <CJK>
+0xE8D3	0x7055	0x52D2	# <CJK>
+0xE8D4	0x7056	0x976B	# <CJK>
+0xE8D5	0x7057	0x9771	# <CJK>
+0xE8D6	0x7058	0x9779	# <CJK>
+0xE8D7	0x7059	0x9785	# <CJK>
+0xE8D8	0x705A	0x977C	# <CJK>
+0xE8D9	0x705B	0x9781	# <CJK>
+0xE8DA	0x705C	0x977A	# <CJK>
+0xE8DB	0x705D	0x9786	# <CJK>
+0xE8DC	0x705E	0x978B	# <CJK>
+0xE8DD	0x705F	0x978F	# <CJK>
+0xE8DE	0x7060	0x9790	# <CJK>
+0xE8DF	0x7061	0x979C	# <CJK>
+0xE8E0	0x7062	0x97A8	# <CJK>
+0xE8E1	0x7063	0x97A6	# <CJK>
+0xE8E2	0x7064	0x97A3	# <CJK>
+0xE8E3	0x7065	0x97B3	# <CJK>
+0xE8E4	0x7066	0x97B4	# <CJK>
+0xE8E5	0x7067	0x97C3	# <CJK>
+0xE8E6	0x7068	0x97C6	# <CJK>
+0xE8E7	0x7069	0x97C8	# <CJK>
+0xE8E8	0x706A	0x97CB	# <CJK>
+0xE8E9	0x706B	0x97DC	# <CJK>
+0xE8EA	0x706C	0x97ED	# <CJK>
+0xE8EB	0x706D	0x9F4F	# <CJK>
+0xE8EC	0x706E	0x97F2	# <CJK>
+0xE8ED	0x706F	0x7ADF	# <CJK>
+0xE8EE	0x7070	0x97F6	# <CJK>
+0xE8EF	0x7071	0x97F5	# <CJK>
+0xE8F0	0x7072	0x980F	# <CJK>
+0xE8F1	0x7073	0x980C	# <CJK>
+0xE8F2	0x7074	0x9838	# <CJK>
+0xE8F3	0x7075	0x9824	# <CJK>
+0xE8F4	0x7076	0x9821	# <CJK>
+0xE8F5	0x7077	0x9837	# <CJK>
+0xE8F6	0x7078	0x983D	# <CJK>
+0xE8F7	0x7079	0x9846	# <CJK>
+0xE8F8	0x707A	0x984F	# <CJK>
+0xE8F9	0x707B	0x984B	# <CJK>
+0xE8FA	0x707C	0x986B	# <CJK>
+0xE8FB	0x707D	0x986F	# <CJK>
+0xE8FC	0x707E	0x9870	# <CJK>
+0xE940	0x7121	0x9871	# <CJK>
+0xE941	0x7122	0x9874	# <CJK>
+0xE942	0x7123	0x9873	# <CJK>
+0xE943	0x7124	0x98AA	# <CJK>
+0xE944	0x7125	0x98AF	# <CJK>
+0xE945	0x7126	0x98B1	# <CJK>
+0xE946	0x7127	0x98B6	# <CJK>
+0xE947	0x7128	0x98C4	# <CJK>
+0xE948	0x7129	0x98C3	# <CJK>
+0xE949	0x712A	0x98C6	# <CJK>
+0xE94A	0x712B	0x98E9	# <CJK>
+0xE94B	0x712C	0x98EB	# <CJK>
+0xE94C	0x712D	0x9903	# <CJK>
+0xE94D	0x712E	0x9909	# <CJK>
+0xE94E	0x712F	0x9912	# <CJK>
+0xE94F	0x7130	0x9914	# <CJK>
+0xE950	0x7131	0x9918	# <CJK>
+0xE951	0x7132	0x9921	# <CJK>
+0xE952	0x7133	0x991D	# <CJK>
+0xE953	0x7134	0x991E	# <CJK>
+0xE954	0x7135	0x9924	# <CJK>
+0xE955	0x7136	0x9920	# <CJK>
+0xE956	0x7137	0x992C	# <CJK>
+0xE957	0x7138	0x992E	# <CJK>
+0xE958	0x7139	0x993D	# <CJK>
+0xE959	0x713A	0x993E	# <CJK>
+0xE95A	0x713B	0x9942	# <CJK>
+0xE95B	0x713C	0x9949	# <CJK>
+0xE95C	0x713D	0x9945	# <CJK>
+0xE95D	0x713E	0x9950	# <CJK>
+0xE95E	0x713F	0x994B	# <CJK>
+0xE95F	0x7140	0x9951	# <CJK>
+0xE960	0x7141	0x9952	# <CJK>
+0xE961	0x7142	0x994C	# <CJK>
+0xE962	0x7143	0x9955	# <CJK>
+0xE963	0x7144	0x9997	# <CJK>
+0xE964	0x7145	0x9998	# <CJK>
+0xE965	0x7146	0x99A5	# <CJK>
+0xE966	0x7147	0x99AD	# <CJK>
+0xE967	0x7148	0x99AE	# <CJK>
+0xE968	0x7149	0x99BC	# <CJK>
+0xE969	0x714A	0x99DF	# <CJK>
+0xE96A	0x714B	0x99DB	# <CJK>
+0xE96B	0x714C	0x99DD	# <CJK>
+0xE96C	0x714D	0x99D8	# <CJK>
+0xE96D	0x714E	0x99D1	# <CJK>
+0xE96E	0x714F	0x99ED	# <CJK>
+0xE96F	0x7150	0x99EE	# <CJK>
+0xE970	0x7151	0x99F1	# <CJK>
+0xE971	0x7152	0x99F2	# <CJK>
+0xE972	0x7153	0x99FB	# <CJK>
+0xE973	0x7154	0x99F8	# <CJK>
+0xE974	0x7155	0x9A01	# <CJK>
+0xE975	0x7156	0x9A0F	# <CJK>
+0xE976	0x7157	0x9A05	# <CJK>
+0xE977	0x7158	0x99E2	# <CJK>
+0xE978	0x7159	0x9A19	# <CJK>
+0xE979	0x715A	0x9A2B	# <CJK>
+0xE97A	0x715B	0x9A37	# <CJK>
+0xE97B	0x715C	0x9A45	# <CJK>
+0xE97C	0x715D	0x9A42	# <CJK>
+0xE97D	0x715E	0x9A40	# <CJK>
+0xE97E	0x715F	0x9A43	# <CJK>
+0xE980	0x7160	0x9A3E	# <CJK>
+0xE981	0x7161	0x9A55	# <CJK>
+0xE982	0x7162	0x9A4D	# <CJK>
+0xE983	0x7163	0x9A5B	# <CJK>
+0xE984	0x7164	0x9A57	# <CJK>
+0xE985	0x7165	0x9A5F	# <CJK>
+0xE986	0x7166	0x9A62	# <CJK>
+0xE987	0x7167	0x9A65	# <CJK>
+0xE988	0x7168	0x9A64	# <CJK>
+0xE989	0x7169	0x9A69	# <CJK>
+0xE98A	0x716A	0x9A6B	# <CJK>
+0xE98B	0x716B	0x9A6A	# <CJK>
+0xE98C	0x716C	0x9AAD	# <CJK>
+0xE98D	0x716D	0x9AB0	# <CJK>
+0xE98E	0x716E	0x9ABC	# <CJK>
+0xE98F	0x716F	0x9AC0	# <CJK>
+0xE990	0x7170	0x9ACF	# <CJK>
+0xE991	0x7171	0x9AD1	# <CJK>
+0xE992	0x7172	0x9AD3	# <CJK>
+0xE993	0x7173	0x9AD4	# <CJK>
+0xE994	0x7174	0x9ADE	# <CJK>
+0xE995	0x7175	0x9ADF	# <CJK>
+0xE996	0x7176	0x9AE2	# <CJK>
+0xE997	0x7177	0x9AE3	# <CJK>
+0xE998	0x7178	0x9AE6	# <CJK>
+0xE999	0x7179	0x9AEF	# <CJK>
+0xE99A	0x717A	0x9AEB	# <CJK>
+0xE99B	0x717B	0x9AEE	# <CJK>
+0xE99C	0x717C	0x9AF4	# <CJK>
+0xE99D	0x717D	0x9AF1	# <CJK>
+0xE99E	0x717E	0x9AF7	# <CJK>
+0xE99F	0x7221	0x9AFB	# <CJK>
+0xE9A0	0x7222	0x9B06	# <CJK>
+0xE9A1	0x7223	0x9B18	# <CJK>
+0xE9A2	0x7224	0x9B1A	# <CJK>
+0xE9A3	0x7225	0x9B1F	# <CJK>
+0xE9A4	0x7226	0x9B22	# <CJK>
+0xE9A5	0x7227	0x9B23	# <CJK>
+0xE9A6	0x7228	0x9B25	# <CJK>
+0xE9A7	0x7229	0x9B27	# <CJK>
+0xE9A8	0x722A	0x9B28	# <CJK>
+0xE9A9	0x722B	0x9B29	# <CJK>
+0xE9AA	0x722C	0x9B2A	# <CJK>
+0xE9AB	0x722D	0x9B2E	# <CJK>
+0xE9AC	0x722E	0x9B2F	# <CJK>
+0xE9AD	0x722F	0x9B32	# <CJK>
+0xE9AE	0x7230	0x9B44	# <CJK>
+0xE9AF	0x7231	0x9B43	# <CJK>
+0xE9B0	0x7232	0x9B4F	# <CJK>
+0xE9B1	0x7233	0x9B4D	# <CJK>
+0xE9B2	0x7234	0x9B4E	# <CJK>
+0xE9B3	0x7235	0x9B51	# <CJK>
+0xE9B4	0x7236	0x9B58	# <CJK>
+0xE9B5	0x7237	0x9B74	# <CJK>
+0xE9B6	0x7238	0x9B93	# <CJK>
+0xE9B7	0x7239	0x9B83	# <CJK>
+0xE9B8	0x723A	0x9B91	# <CJK>
+0xE9B9	0x723B	0x9B96	# <CJK>
+0xE9BA	0x723C	0x9B97	# <CJK>
+0xE9BB	0x723D	0x9B9F	# <CJK>
+0xE9BC	0x723E	0x9BA0	# <CJK>
+0xE9BD	0x723F	0x9BA8	# <CJK>
+0xE9BE	0x7240	0x9BB4	# <CJK>
+0xE9BF	0x7241	0x9BC0	# <CJK>
+0xE9C0	0x7242	0x9BCA	# <CJK>
+0xE9C1	0x7243	0x9BB9	# <CJK>
+0xE9C2	0x7244	0x9BC6	# <CJK>
+0xE9C3	0x7245	0x9BCF	# <CJK>
+0xE9C4	0x7246	0x9BD1	# <CJK>
+0xE9C5	0x7247	0x9BD2	# <CJK>
+0xE9C6	0x7248	0x9BE3	# <CJK>
+0xE9C7	0x7249	0x9BE2	# <CJK>
+0xE9C8	0x724A	0x9BE4	# <CJK>
+0xE9C9	0x724B	0x9BD4	# <CJK>
+0xE9CA	0x724C	0x9BE1	# <CJK>
+0xE9CB	0x724D	0x9C3A	# <CJK>
+0xE9CC	0x724E	0x9BF2	# <CJK>
+0xE9CD	0x724F	0x9BF1	# <CJK>
+0xE9CE	0x7250	0x9BF0	# <CJK>
+0xE9CF	0x7251	0x9C15	# <CJK>
+0xE9D0	0x7252	0x9C14	# <CJK>
+0xE9D1	0x7253	0x9C09	# <CJK>
+0xE9D2	0x7254	0x9C13	# <CJK>
+0xE9D3	0x7255	0x9C0C	# <CJK>
+0xE9D4	0x7256	0x9C06	# <CJK>
+0xE9D5	0x7257	0x9C08	# <CJK>
+0xE9D6	0x7258	0x9C12	# <CJK>
+0xE9D7	0x7259	0x9C0A	# <CJK>
+0xE9D8	0x725A	0x9C04	# <CJK>
+0xE9D9	0x725B	0x9C2E	# <CJK>
+0xE9DA	0x725C	0x9C1B	# <CJK>
+0xE9DB	0x725D	0x9C25	# <CJK>
+0xE9DC	0x725E	0x9C24	# <CJK>
+0xE9DD	0x725F	0x9C21	# <CJK>
+0xE9DE	0x7260	0x9C30	# <CJK>
+0xE9DF	0x7261	0x9C47	# <CJK>
+0xE9E0	0x7262	0x9C32	# <CJK>
+0xE9E1	0x7263	0x9C46	# <CJK>
+0xE9E2	0x7264	0x9C3E	# <CJK>
+0xE9E3	0x7265	0x9C5A	# <CJK>
+0xE9E4	0x7266	0x9C60	# <CJK>
+0xE9E5	0x7267	0x9C67	# <CJK>
+0xE9E6	0x7268	0x9C76	# <CJK>
+0xE9E7	0x7269	0x9C78	# <CJK>
+0xE9E8	0x726A	0x9CE7	# <CJK>
+0xE9E9	0x726B	0x9CEC	# <CJK>
+0xE9EA	0x726C	0x9CF0	# <CJK>
+0xE9EB	0x726D	0x9D09	# <CJK>
+0xE9EC	0x726E	0x9D08	# <CJK>
+0xE9ED	0x726F	0x9CEB	# <CJK>
+0xE9EE	0x7270	0x9D03	# <CJK>
+0xE9EF	0x7271	0x9D06	# <CJK>
+0xE9F0	0x7272	0x9D2A	# <CJK>
+0xE9F1	0x7273	0x9D26	# <CJK>
+0xE9F2	0x7274	0x9DAF	# <CJK>
+0xE9F3	0x7275	0x9D23	# <CJK>
+0xE9F4	0x7276	0x9D1F	# <CJK>
+0xE9F5	0x7277	0x9D44	# <CJK>
+0xE9F6	0x7278	0x9D15	# <CJK>
+0xE9F7	0x7279	0x9D12	# <CJK>
+0xE9F8	0x727A	0x9D41	# <CJK>
+0xE9F9	0x727B	0x9D3F	# <CJK>
+0xE9FA	0x727C	0x9D3E	# <CJK>
+0xE9FB	0x727D	0x9D46	# <CJK>
+0xE9FC	0x727E	0x9D48	# <CJK>
+0xEA40	0x7321	0x9D5D	# <CJK>
+0xEA41	0x7322	0x9D5E	# <CJK>
+0xEA42	0x7323	0x9D64	# <CJK>
+0xEA43	0x7324	0x9D51	# <CJK>
+0xEA44	0x7325	0x9D50	# <CJK>
+0xEA45	0x7326	0x9D59	# <CJK>
+0xEA46	0x7327	0x9D72	# <CJK>
+0xEA47	0x7328	0x9D89	# <CJK>
+0xEA48	0x7329	0x9D87	# <CJK>
+0xEA49	0x732A	0x9DAB	# <CJK>
+0xEA4A	0x732B	0x9D6F	# <CJK>
+0xEA4B	0x732C	0x9D7A	# <CJK>
+0xEA4C	0x732D	0x9D9A	# <CJK>
+0xEA4D	0x732E	0x9DA4	# <CJK>
+0xEA4E	0x732F	0x9DA9	# <CJK>
+0xEA4F	0x7330	0x9DB2	# <CJK>
+0xEA50	0x7331	0x9DC4	# <CJK>
+0xEA51	0x7332	0x9DC1	# <CJK>
+0xEA52	0x7333	0x9DBB	# <CJK>
+0xEA53	0x7334	0x9DB8	# <CJK>
+0xEA54	0x7335	0x9DBA	# <CJK>
+0xEA55	0x7336	0x9DC6	# <CJK>
+0xEA56	0x7337	0x9DCF	# <CJK>
+0xEA57	0x7338	0x9DC2	# <CJK>
+0xEA58	0x7339	0x9DD9	# <CJK>
+0xEA59	0x733A	0x9DD3	# <CJK>
+0xEA5A	0x733B	0x9DF8	# <CJK>
+0xEA5B	0x733C	0x9DE6	# <CJK>
+0xEA5C	0x733D	0x9DED	# <CJK>
+0xEA5D	0x733E	0x9DEF	# <CJK>
+0xEA5E	0x733F	0x9DFD	# <CJK>
+0xEA5F	0x7340	0x9E1A	# <CJK>
+0xEA60	0x7341	0x9E1B	# <CJK>
+0xEA61	0x7342	0x9E1E	# <CJK>
+0xEA62	0x7343	0x9E75	# <CJK>
+0xEA63	0x7344	0x9E79	# <CJK>
+0xEA64	0x7345	0x9E7D	# <CJK>
+0xEA65	0x7346	0x9E81	# <CJK>
+0xEA66	0x7347	0x9E88	# <CJK>
+0xEA67	0x7348	0x9E8B	# <CJK>
+0xEA68	0x7349	0x9E8C	# <CJK>
+0xEA69	0x734A	0x9E92	# <CJK>
+0xEA6A	0x734B	0x9E95	# <CJK>
+0xEA6B	0x734C	0x9E91	# <CJK>
+0xEA6C	0x734D	0x9E9D	# <CJK>
+0xEA6D	0x734E	0x9EA5	# <CJK>
+0xEA6E	0x734F	0x9EA9	# <CJK>
+0xEA6F	0x7350	0x9EB8	# <CJK>
+0xEA70	0x7351	0x9EAA	# <CJK>
+0xEA71	0x7352	0x9EAD	# <CJK>
+0xEA72	0x7353	0x9761	# <CJK>
+0xEA73	0x7354	0x9ECC	# <CJK>
+0xEA74	0x7355	0x9ECE	# <CJK>
+0xEA75	0x7356	0x9ECF	# <CJK>
+0xEA76	0x7357	0x9ED0	# <CJK>
+0xEA77	0x7358	0x9ED4	# <CJK>
+0xEA78	0x7359	0x9EDC	# <CJK>
+0xEA79	0x735A	0x9EDE	# <CJK>
+0xEA7A	0x735B	0x9EDD	# <CJK>
+0xEA7B	0x735C	0x9EE0	# <CJK>
+0xEA7C	0x735D	0x9EE5	# <CJK>
+0xEA7D	0x735E	0x9EE8	# <CJK>
+0xEA7E	0x735F	0x9EEF	# <CJK>
+0xEA80	0x7360	0x9EF4	# <CJK>
+0xEA81	0x7361	0x9EF6	# <CJK>
+0xEA82	0x7362	0x9EF7	# <CJK>
+0xEA83	0x7363	0x9EF9	# <CJK>
+0xEA84	0x7364	0x9EFB	# <CJK>
+0xEA85	0x7365	0x9EFC	# <CJK>
+0xEA86	0x7366	0x9EFD	# <CJK>
+0xEA87	0x7367	0x9F07	# <CJK>
+0xEA88	0x7368	0x9F08	# <CJK>
+0xEA89	0x7369	0x76B7	# <CJK>
+0xEA8A	0x736A	0x9F15	# <CJK>
+0xEA8B	0x736B	0x9F21	# <CJK>
+0xEA8C	0x736C	0x9F2C	# <CJK>
+0xEA8D	0x736D	0x9F3E	# <CJK>
+0xEA8E	0x736E	0x9F4A	# <CJK>
+0xEA8F	0x736F	0x9F52	# <CJK>
+0xEA90	0x7370	0x9F54	# <CJK>
+0xEA91	0x7371	0x9F63	# <CJK>
+0xEA92	0x7372	0x9F5F	# <CJK>
+0xEA93	0x7373	0x9F60	# <CJK>
+0xEA94	0x7374	0x9F61	# <CJK>
+0xEA95	0x7375	0x9F66	# <CJK>
+0xEA96	0x7376	0x9F67	# <CJK>
+0xEA97	0x7377	0x9F6C	# <CJK>
+0xEA98	0x7378	0x9F6A	# <CJK>
+0xEA99	0x7379	0x9F77	# <CJK>
+0xEA9A	0x737A	0x9F72	# <CJK>
+0xEA9B	0x737B	0x9F76	# <CJK>
+0xEA9C	0x737C	0x9F95	# <CJK>
+0xEA9D	0x737D	0x9F9C	# <CJK>
+0xEA9E	0x737E	0x9FA0	# <CJK>
+0xEA9F	0x7421	0x582F	# <CJK>
+0xEAA0	0x7422	0x69C7	# <CJK>
+0xEAA1	0x7423	0x9059	# <CJK>
+0xEAA2	0x7424	0x7464	# <CJK>
+0xEAA3	0x7425	0x51DC	# <CJK>
+0xEAA4	0x7426	0x7199	# <CJK>
diff --git a/tools/encoding/jis0212.txt b/tools/encoding/jis0212.txt
new file mode 100644
index 0000000..b6d4cb2
--- /dev/null
+++ b/tools/encoding/jis0212.txt
@@ -0,0 +1,6141 @@
+#
+#	Name:             JIS X 0212 (1990) to Unicode
+#	Unicode version:  1.1
+#	Table version:    0.9
+#	Table format:     Format A
+#	Date:             8 March 1994
+#	Authors:          Glenn Adams <glenn@metis.com>
+#                     John H. Jenkins <John_Jenkins@taligent.com>
+#
+#	Copyright (c) 1991-1994 Unicode, Inc.  All Rights reserved.
+#
+#	This file is provided as-is by Unicode, Inc. (The Unicode Consortium).
+#	No claims are made as to fitness for any particular purpose.  No
+#	warranties of any kind are expressed or implied.  The recipient
+#	agrees to determine applicability of information provided.  If this
+#	file has been provided on magnetic media by Unicode, Inc., the sole
+#	remedy for any claim will be exchange of defective media within 90
+#	days of receipt.
+#
+#	Recipient is granted the right to make copies in any form for
+#	internal distribution and to freely use the information supplied
+#	in the creation of products supporting Unicode.  Unicode, Inc.
+#	specifically excludes the right to re-distribute this file directly
+#	to third parties or other organizations whether for profit or not.
+#
+#	General notes:
+#
+#	This table contains the data the Unicode Consortium has on how
+#       JIS X 0212 (1983) characters map into Unicode.
+#
+#	Format:  Three tab-separated columns
+#		 Column #1 is the JIS X 0212 code (in hex as 0xXXXX)
+#		 Column #2 is the Unicode (in hex as 0xXXXX)
+#		 Column #3 the Unicode name (follows a comment sign, '#')
+#					The official names for Unicode characters U+4E00
+#					to U+9FA5, inclusive, is "CJK UNIFIED IDEOGRAPH-XXXX",
+#					where XXXX is the code point.  Including all these
+#					names in this file increases its size substantially
+#					and needlessly.  The token "<CJK>" is used for the
+#					name of these characters.  If necessary, it can be
+#					expanded algorithmically by a parser or editor.
+#
+#	The entries are in JIS X 0212 order
+#
+#	The following algorithms can be used to change the hex form
+#		of JIS 0212 to other standard forms:
+#
+#		To change hex to EUC form, add 0x8080
+#		To change hex to kuten form, first subtract 0x2020.  Then
+#			the high and low bytes correspond to the ku and ten of
+#			the kuten form.  For example, 0x2121 -> 0x0101 -> 0101;
+#			0x6D63 -> 0x4D43 -> 7767
+#
+#   The kanji mappings are a normative part of ISO/IEC 10646.  The
+#       non-kanji mappings are provisional, pending definition of
+#       official mappings by Japanese standards bodies
+#
+#	Any comments or problems, contact <John_Jenkins@taligent.com>
+#
+#	Notes:
+#
+#	1. JIS X 0212 apparently unified the following two symbols
+#	   into a single character at 0x2922:
+#	
+#	   LATIN CAPITAL LETTER D WITH STROKE
+#	   LATIN CAPITAL LETTER ETH
+#
+#	   However, JIS X 0212 maintains the distinction between
+#	   the lowercase forms of these two elements at 0x2942 and 0x2943.
+#	   Given the structre of these JIS encodings, it is clear that
+#	   0x2922 and 0x2942 are intended to be a capital/small pair.
+#	   Consequently, in the Unicode mapping, 0x2922 is treated as
+#	   LATIN CAPITAL LETTER D WITH STROKE.
+#	  
+0x222F	0x02D8	# BREVE
+0x2230	0x02C7	# CARON (Mandarin Chinese third tone)
+0x2231	0x00B8	# CEDILLA
+0x2232	0x02D9	# DOT ABOVE (Mandarin Chinese light tone)
+0x2233	0x02DD	# DOUBLE ACUTE ACCENT
+0x2234	0x00AF	# MACRON
+0x2235	0x02DB	# OGONEK
+0x2236	0x02DA	# RING ABOVE
+0x2237	0x007E	# TILDE
+0x2238	0x0384	# GREEK TONOS
+0x2239	0x0385	# GREEK DIALYTIKA TONOS
+0x2242	0x00A1	# INVERTED EXCLAMATION MARK
+0x2243	0x00A6	# BROKEN BAR
+0x2244	0x00BF	# INVERTED QUESTION MARK
+0x226B	0x00BA	# MASCULINE ORDINAL INDICATOR
+0x226C	0x00AA	# FEMININE ORDINAL INDICATOR
+0x226D	0x00A9	# COPYRIGHT SIGN
+0x226E	0x00AE	# REGISTERED SIGN
+0x226F	0x2122	# TRADE MARK SIGN
+0x2270	0x00A4	# CURRENCY SIGN
+0x2271	0x2116	# NUMERO SIGN
+0x2661	0x0386	# GREEK CAPITAL LETTER ALPHA WITH TONOS
+0x2662	0x0388	# GREEK CAPITAL LETTER EPSILON WITH TONOS
+0x2663	0x0389	# GREEK CAPITAL LETTER ETA WITH TONOS
+0x2664	0x038A	# GREEK CAPITAL LETTER IOTA WITH TONOS
+0x2665	0x03AA	# GREEK CAPITAL LETTER IOTA WITH DIALYTIKA
+0x2667	0x038C	# GREEK CAPITAL LETTER OMICRON WITH TONOS
+0x2669	0x038E	# GREEK CAPITAL LETTER UPSILON WITH TONOS
+0x266A	0x03AB	# GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA
+0x266C	0x038F	# GREEK CAPITAL LETTER OMEGA WITH TONOS
+0x2671	0x03AC	# GREEK SMALL LETTER ALPHA WITH TONOS
+0x2672	0x03AD	# GREEK SMALL LETTER EPSILON WITH TONOS
+0x2673	0x03AE	# GREEK SMALL LETTER ETA WITH TONOS
+0x2674	0x03AF	# GREEK SMALL LETTER IOTA WITH TONOS
+0x2675	0x03CA	# GREEK SMALL LETTER IOTA WITH DIALYTIKA
+0x2676	0x0390	# GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS
+0x2677	0x03CC	# GREEK SMALL LETTER OMICRON WITH TONOS
+0x2678	0x03C2	# GREEK SMALL LETTER FINAL SIGMA
+0x2679	0x03CD	# GREEK SMALL LETTER UPSILON WITH TONOS
+0x267A	0x03CB	# GREEK SMALL LETTER UPSILON WITH DIALYTIKA
+0x267B	0x03B0	# GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS
+0x267C	0x03CE	# GREEK SMALL LETTER OMEGA WITH TONOS
+0x2742	0x0402	# CYRILLIC CAPITAL LETTER DJE
+0x2743	0x0403	# CYRILLIC CAPITAL LETTER GJE
+0x2744	0x0404	# CYRILLIC CAPITAL LETTER UKRAINIAN IE
+0x2745	0x0405	# CYRILLIC CAPITAL LETTER DZE
+0x2746	0x0406	# CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I
+0x2747	0x0407	# CYRILLIC CAPITAL LETTER YI
+0x2748	0x0408	# CYRILLIC CAPITAL LETTER JE
+0x2749	0x0409	# CYRILLIC CAPITAL LETTER LJE
+0x274A	0x040A	# CYRILLIC CAPITAL LETTER NJE
+0x274B	0x040B	# CYRILLIC CAPITAL LETTER TSHE
+0x274C	0x040C	# CYRILLIC CAPITAL LETTER KJE
+0x274D	0x040E	# CYRILLIC CAPITAL LETTER SHORT U
+0x274E	0x040F	# CYRILLIC CAPITAL LETTER DZHE
+0x2772	0x0452	# CYRILLIC SMALL LETTER DJE
+0x2773	0x0453	# CYRILLIC SMALL LETTER GJE
+0x2774	0x0454	# CYRILLIC SMALL LETTER UKRAINIAN IE
+0x2775	0x0455	# CYRILLIC SMALL LETTER DZE
+0x2776	0x0456	# CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I
+0x2777	0x0457	# CYRILLIC SMALL LETTER YI
+0x2778	0x0458	# CYRILLIC SMALL LETTER JE
+0x2779	0x0459	# CYRILLIC SMALL LETTER LJE
+0x277A	0x045A	# CYRILLIC SMALL LETTER NJE
+0x277B	0x045B	# CYRILLIC SMALL LETTER TSHE
+0x277C	0x045C	# CYRILLIC SMALL LETTER KJE
+0x277D	0x045E	# CYRILLIC SMALL LETTER SHORT U
+0x277E	0x045F	# CYRILLIC SMALL LETTER DZHE
+0x2921	0x00C6	# LATIN CAPITAL LIGATURE AE
+0x2922	0x0110	# LATIN CAPITAL LETTER D WITH STROKE
+0x2924	0x0126	# LATIN CAPITAL LETTER H WITH STROKE
+0x2926	0x0132	# LATIN CAPITAL LIGATURE IJ
+0x2928	0x0141	# LATIN CAPITAL LETTER L WITH STROKE
+0x2929	0x013F	# LATIN CAPITAL LETTER L WITH MIDDLE DOT
+0x292B	0x014A	# LATIN CAPITAL LETTER ENG
+0x292C	0x00D8	# LATIN CAPITAL LETTER O WITH STROKE
+0x292D	0x0152	# LATIN CAPITAL LIGATURE OE
+0x292F	0x0166	# LATIN CAPITAL LETTER T WITH STROKE
+0x2930	0x00DE	# LATIN CAPITAL LETTER THORN
+0x2941	0x00E6	# LATIN SMALL LIGATURE AE
+0x2942	0x0111	# LATIN SMALL LETTER D WITH STROKE
+0x2943	0x00F0	# LATIN SMALL LETTER ETH
+0x2944	0x0127	# LATIN SMALL LETTER H WITH STROKE
+0x2945	0x0131	# LATIN SMALL LETTER DOTLESS I
+0x2946	0x0133	# LATIN SMALL LIGATURE IJ
+0x2947	0x0138	# LATIN SMALL LETTER KRA
+0x2948	0x0142	# LATIN SMALL LETTER L WITH STROKE
+0x2949	0x0140	# LATIN SMALL LETTER L WITH MIDDLE DOT
+0x294A	0x0149	# LATIN SMALL LETTER N PRECEDED BY APOSTROPHE
+0x294B	0x014B	# LATIN SMALL LETTER ENG
+0x294C	0x00F8	# LATIN SMALL LETTER O WITH STROKE
+0x294D	0x0153	# LATIN SMALL LIGATURE OE
+0x294E	0x00DF	# LATIN SMALL LETTER SHARP S
+0x294F	0x0167	# LATIN SMALL LETTER T WITH STROKE
+0x2950	0x00FE	# LATIN SMALL LETTER THORN
+0x2A21	0x00C1	# LATIN CAPITAL LETTER A WITH ACUTE
+0x2A22	0x00C0	# LATIN CAPITAL LETTER A WITH GRAVE
+0x2A23	0x00C4	# LATIN CAPITAL LETTER A WITH DIAERESIS
+0x2A24	0x00C2	# LATIN CAPITAL LETTER A WITH CIRCUMFLEX
+0x2A25	0x0102	# LATIN CAPITAL LETTER A WITH BREVE
+0x2A26	0x01CD	# LATIN CAPITAL LETTER A WITH CARON
+0x2A27	0x0100	# LATIN CAPITAL LETTER A WITH MACRON
+0x2A28	0x0104	# LATIN CAPITAL LETTER A WITH OGONEK
+0x2A29	0x00C5	# LATIN CAPITAL LETTER A WITH RING ABOVE
+0x2A2A	0x00C3	# LATIN CAPITAL LETTER A WITH TILDE
+0x2A2B	0x0106	# LATIN CAPITAL LETTER C WITH ACUTE
+0x2A2C	0x0108	# LATIN CAPITAL LETTER C WITH CIRCUMFLEX
+0x2A2D	0x010C	# LATIN CAPITAL LETTER C WITH CARON
+0x2A2E	0x00C7	# LATIN CAPITAL LETTER C WITH CEDILLA
+0x2A2F	0x010A	# LATIN CAPITAL LETTER C WITH DOT ABOVE
+0x2A30	0x010E	# LATIN CAPITAL LETTER D WITH CARON
+0x2A31	0x00C9	# LATIN CAPITAL LETTER E WITH ACUTE
+0x2A32	0x00C8	# LATIN CAPITAL LETTER E WITH GRAVE
+0x2A33	0x00CB	# LATIN CAPITAL LETTER E WITH DIAERESIS
+0x2A34	0x00CA	# LATIN CAPITAL LETTER E WITH CIRCUMFLEX
+0x2A35	0x011A	# LATIN CAPITAL LETTER E WITH CARON
+0x2A36	0x0116	# LATIN CAPITAL LETTER E WITH DOT ABOVE
+0x2A37	0x0112	# LATIN CAPITAL LETTER E WITH MACRON
+0x2A38	0x0118	# LATIN CAPITAL LETTER E WITH OGONEK
+0x2A3A	0x011C	# LATIN CAPITAL LETTER G WITH CIRCUMFLEX
+0x2A3B	0x011E	# LATIN CAPITAL LETTER G WITH BREVE
+0x2A3C	0x0122	# LATIN CAPITAL LETTER G WITH CEDILLA
+0x2A3D	0x0120	# LATIN CAPITAL LETTER G WITH DOT ABOVE
+0x2A3E	0x0124	# LATIN CAPITAL LETTER H WITH CIRCUMFLEX
+0x2A3F	0x00CD	# LATIN CAPITAL LETTER I WITH ACUTE
+0x2A40	0x00CC	# LATIN CAPITAL LETTER I WITH GRAVE
+0x2A41	0x00CF	# LATIN CAPITAL LETTER I WITH DIAERESIS
+0x2A42	0x00CE	# LATIN CAPITAL LETTER I WITH CIRCUMFLEX
+0x2A43	0x01CF	# LATIN CAPITAL LETTER I WITH CARON
+0x2A44	0x0130	# LATIN CAPITAL LETTER I WITH DOT ABOVE
+0x2A45	0x012A	# LATIN CAPITAL LETTER I WITH MACRON
+0x2A46	0x012E	# LATIN CAPITAL LETTER I WITH OGONEK
+0x2A47	0x0128	# LATIN CAPITAL LETTER I WITH TILDE
+0x2A48	0x0134	# LATIN CAPITAL LETTER J WITH CIRCUMFLEX
+0x2A49	0x0136	# LATIN CAPITAL LETTER K WITH CEDILLA
+0x2A4A	0x0139	# LATIN CAPITAL LETTER L WITH ACUTE
+0x2A4B	0x013D	# LATIN CAPITAL LETTER L WITH CARON
+0x2A4C	0x013B	# LATIN CAPITAL LETTER L WITH CEDILLA
+0x2A4D	0x0143	# LATIN CAPITAL LETTER N WITH ACUTE
+0x2A4E	0x0147	# LATIN CAPITAL LETTER N WITH CARON
+0x2A4F	0x0145	# LATIN CAPITAL LETTER N WITH CEDILLA
+0x2A50	0x00D1	# LATIN CAPITAL LETTER N WITH TILDE
+0x2A51	0x00D3	# LATIN CAPITAL LETTER O WITH ACUTE
+0x2A52	0x00D2	# LATIN CAPITAL LETTER O WITH GRAVE
+0x2A53	0x00D6	# LATIN CAPITAL LETTER O WITH DIAERESIS
+0x2A54	0x00D4	# LATIN CAPITAL LETTER O WITH CIRCUMFLEX
+0x2A55	0x01D1	# LATIN CAPITAL LETTER O WITH CARON
+0x2A56	0x0150	# LATIN CAPITAL LETTER O WITH DOUBLE ACUTE
+0x2A57	0x014C	# LATIN CAPITAL LETTER O WITH MACRON
+0x2A58	0x00D5	# LATIN CAPITAL LETTER O WITH TILDE
+0x2A59	0x0154	# LATIN CAPITAL LETTER R WITH ACUTE
+0x2A5A	0x0158	# LATIN CAPITAL LETTER R WITH CARON
+0x2A5B	0x0156	# LATIN CAPITAL LETTER R WITH CEDILLA
+0x2A5C	0x015A	# LATIN CAPITAL LETTER S WITH ACUTE
+0x2A5D	0x015C	# LATIN CAPITAL LETTER S WITH CIRCUMFLEX
+0x2A5E	0x0160	# LATIN CAPITAL LETTER S WITH CARON
+0x2A5F	0x015E	# LATIN CAPITAL LETTER S WITH CEDILLA
+0x2A60	0x0164	# LATIN CAPITAL LETTER T WITH CARON
+0x2A61	0x0162	# LATIN CAPITAL LETTER T WITH CEDILLA
+0x2A62	0x00DA	# LATIN CAPITAL LETTER U WITH ACUTE
+0x2A63	0x00D9	# LATIN CAPITAL LETTER U WITH GRAVE
+0x2A64	0x00DC	# LATIN CAPITAL LETTER U WITH DIAERESIS
+0x2A65	0x00DB	# LATIN CAPITAL LETTER U WITH CIRCUMFLEX
+0x2A66	0x016C	# LATIN CAPITAL LETTER U WITH BREVE
+0x2A67	0x01D3	# LATIN CAPITAL LETTER U WITH CARON
+0x2A68	0x0170	# LATIN CAPITAL LETTER U WITH DOUBLE ACUTE
+0x2A69	0x016A	# LATIN CAPITAL LETTER U WITH MACRON
+0x2A6A	0x0172	# LATIN CAPITAL LETTER U WITH OGONEK
+0x2A6B	0x016E	# LATIN CAPITAL LETTER U WITH RING ABOVE
+0x2A6C	0x0168	# LATIN CAPITAL LETTER U WITH TILDE
+0x2A6D	0x01D7	# LATIN CAPITAL LETTER U WITH DIAERESIS AND ACUTE
+0x2A6E	0x01DB	# LATIN CAPITAL LETTER U WITH DIAERESIS AND GRAVE
+0x2A6F	0x01D9	# LATIN CAPITAL LETTER U WITH DIAERESIS AND CARON
+0x2A70	0x01D5	# LATIN CAPITAL LETTER U WITH DIAERESIS AND MACRON
+0x2A71	0x0174	# LATIN CAPITAL LETTER W WITH CIRCUMFLEX
+0x2A72	0x00DD	# LATIN CAPITAL LETTER Y WITH ACUTE
+0x2A73	0x0178	# LATIN CAPITAL LETTER Y WITH DIAERESIS
+0x2A74	0x0176	# LATIN CAPITAL LETTER Y WITH CIRCUMFLEX
+0x2A75	0x0179	# LATIN CAPITAL LETTER Z WITH ACUTE
+0x2A76	0x017D	# LATIN CAPITAL LETTER Z WITH CARON
+0x2A77	0x017B	# LATIN CAPITAL LETTER Z WITH DOT ABOVE
+0x2B21	0x00E1	# LATIN SMALL LETTER A WITH ACUTE
+0x2B22	0x00E0	# LATIN SMALL LETTER A WITH GRAVE
+0x2B23	0x00E4	# LATIN SMALL LETTER A WITH DIAERESIS
+0x2B24	0x00E2	# LATIN SMALL LETTER A WITH CIRCUMFLEX
+0x2B25	0x0103	# LATIN SMALL LETTER A WITH BREVE
+0x2B26	0x01CE	# LATIN SMALL LETTER A WITH CARON
+0x2B27	0x0101	# LATIN SMALL LETTER A WITH MACRON
+0x2B28	0x0105	# LATIN SMALL LETTER A WITH OGONEK
+0x2B29	0x00E5	# LATIN SMALL LETTER A WITH RING ABOVE
+0x2B2A	0x00E3	# LATIN SMALL LETTER A WITH TILDE
+0x2B2B	0x0107	# LATIN SMALL LETTER C WITH ACUTE
+0x2B2C	0x0109	# LATIN SMALL LETTER C WITH CIRCUMFLEX
+0x2B2D	0x010D	# LATIN SMALL LETTER C WITH CARON
+0x2B2E	0x00E7	# LATIN SMALL LETTER C WITH CEDILLA
+0x2B2F	0x010B	# LATIN SMALL LETTER C WITH DOT ABOVE
+0x2B30	0x010F	# LATIN SMALL LETTER D WITH CARON
+0x2B31	0x00E9	# LATIN SMALL LETTER E WITH ACUTE
+0x2B32	0x00E8	# LATIN SMALL LETTER E WITH GRAVE
+0x2B33	0x00EB	# LATIN SMALL LETTER E WITH DIAERESIS
+0x2B34	0x00EA	# LATIN SMALL LETTER E WITH CIRCUMFLEX
+0x2B35	0x011B	# LATIN SMALL LETTER E WITH CARON
+0x2B36	0x0117	# LATIN SMALL LETTER E WITH DOT ABOVE
+0x2B37	0x0113	# LATIN SMALL LETTER E WITH MACRON
+0x2B38	0x0119	# LATIN SMALL LETTER E WITH OGONEK
+0x2B39	0x01F5	# LATIN SMALL LETTER G WITH ACUTE
+0x2B3A	0x011D	# LATIN SMALL LETTER G WITH CIRCUMFLEX
+0x2B3B	0x011F	# LATIN SMALL LETTER G WITH BREVE
+0x2B3D	0x0121	# LATIN SMALL LETTER G WITH DOT ABOVE
+0x2B3E	0x0125	# LATIN SMALL LETTER H WITH CIRCUMFLEX
+0x2B3F	0x00ED	# LATIN SMALL LETTER I WITH ACUTE
+0x2B40	0x00EC	# LATIN SMALL LETTER I WITH GRAVE
+0x2B41	0x00EF	# LATIN SMALL LETTER I WITH DIAERESIS
+0x2B42	0x00EE	# LATIN SMALL LETTER I WITH CIRCUMFLEX
+0x2B43	0x01D0	# LATIN SMALL LETTER I WITH CARON
+0x2B45	0x012B	# LATIN SMALL LETTER I WITH MACRON
+0x2B46	0x012F	# LATIN SMALL LETTER I WITH OGONEK
+0x2B47	0x0129	# LATIN SMALL LETTER I WITH TILDE
+0x2B48	0x0135	# LATIN SMALL LETTER J WITH CIRCUMFLEX
+0x2B49	0x0137	# LATIN SMALL LETTER K WITH CEDILLA
+0x2B4A	0x013A	# LATIN SMALL LETTER L WITH ACUTE
+0x2B4B	0x013E	# LATIN SMALL LETTER L WITH CARON
+0x2B4C	0x013C	# LATIN SMALL LETTER L WITH CEDILLA
+0x2B4D	0x0144	# LATIN SMALL LETTER N WITH ACUTE
+0x2B4E	0x0148	# LATIN SMALL LETTER N WITH CARON
+0x2B4F	0x0146	# LATIN SMALL LETTER N WITH CEDILLA
+0x2B50	0x00F1	# LATIN SMALL LETTER N WITH TILDE
+0x2B51	0x00F3	# LATIN SMALL LETTER O WITH ACUTE
+0x2B52	0x00F2	# LATIN SMALL LETTER O WITH GRAVE
+0x2B53	0x00F6	# LATIN SMALL LETTER O WITH DIAERESIS
+0x2B54	0x00F4	# LATIN SMALL LETTER O WITH CIRCUMFLEX
+0x2B55	0x01D2	# LATIN SMALL LETTER O WITH CARON
+0x2B56	0x0151	# LATIN SMALL LETTER O WITH DOUBLE ACUTE
+0x2B57	0x014D	# LATIN SMALL LETTER O WITH MACRON
+0x2B58	0x00F5	# LATIN SMALL LETTER O WITH TILDE
+0x2B59	0x0155	# LATIN SMALL LETTER R WITH ACUTE
+0x2B5A	0x0159	# LATIN SMALL LETTER R WITH CARON
+0x2B5B	0x0157	# LATIN SMALL LETTER R WITH CEDILLA
+0x2B5C	0x015B	# LATIN SMALL LETTER S WITH ACUTE
+0x2B5D	0x015D	# LATIN SMALL LETTER S WITH CIRCUMFLEX
+0x2B5E	0x0161	# LATIN SMALL LETTER S WITH CARON
+0x2B5F	0x015F	# LATIN SMALL LETTER S WITH CEDILLA
+0x2B60	0x0165	# LATIN SMALL LETTER T WITH CARON
+0x2B61	0x0163	# LATIN SMALL LETTER T WITH CEDILLA
+0x2B62	0x00FA	# LATIN SMALL LETTER U WITH ACUTE
+0x2B63	0x00F9	# LATIN SMALL LETTER U WITH GRAVE
+0x2B64	0x00FC	# LATIN SMALL LETTER U WITH DIAERESIS
+0x2B65	0x00FB	# LATIN SMALL LETTER U WITH CIRCUMFLEX
+0x2B66	0x016D	# LATIN SMALL LETTER U WITH BREVE
+0x2B67	0x01D4	# LATIN SMALL LETTER U WITH CARON
+0x2B68	0x0171	# LATIN SMALL LETTER U WITH DOUBLE ACUTE
+0x2B69	0x016B	# LATIN SMALL LETTER U WITH MACRON
+0x2B6A	0x0173	# LATIN SMALL LETTER U WITH OGONEK
+0x2B6B	0x016F	# LATIN SMALL LETTER U WITH RING ABOVE
+0x2B6C	0x0169	# LATIN SMALL LETTER U WITH TILDE
+0x2B6D	0x01D8	# LATIN SMALL LETTER U WITH DIAERESIS AND ACUTE
+0x2B6E	0x01DC	# LATIN SMALL LETTER U WITH DIAERESIS AND GRAVE
+0x2B6F	0x01DA	# LATIN SMALL LETTER U WITH DIAERESIS AND CARON
+0x2B70	0x01D6	# LATIN SMALL LETTER U WITH DIAERESIS AND MACRON
+0x2B71	0x0175	# LATIN SMALL LETTER W WITH CIRCUMFLEX
+0x2B72	0x00FD	# LATIN SMALL LETTER Y WITH ACUTE
+0x2B73	0x00FF	# LATIN SMALL LETTER Y WITH DIAERESIS
+0x2B74	0x0177	# LATIN SMALL LETTER Y WITH CIRCUMFLEX
+0x2B75	0x017A	# LATIN SMALL LETTER Z WITH ACUTE
+0x2B76	0x017E	# LATIN SMALL LETTER Z WITH CARON
+0x2B77	0x017C	# LATIN SMALL LETTER Z WITH DOT ABOVE
+0x3021	0x4E02	# <CJK>
+0x3022	0x4E04	# <CJK>
+0x3023	0x4E05	# <CJK>
+0x3024	0x4E0C	# <CJK>
+0x3025	0x4E12	# <CJK>
+0x3026	0x4E1F	# <CJK>
+0x3027	0x4E23	# <CJK>
+0x3028	0x4E24	# <CJK>
+0x3029	0x4E28	# <CJK>
+0x302A	0x4E2B	# <CJK>
+0x302B	0x4E2E	# <CJK>
+0x302C	0x4E2F	# <CJK>
+0x302D	0x4E30	# <CJK>
+0x302E	0x4E35	# <CJK>
+0x302F	0x4E40	# <CJK>
+0x3030	0x4E41	# <CJK>
+0x3031	0x4E44	# <CJK>
+0x3032	0x4E47	# <CJK>
+0x3033	0x4E51	# <CJK>
+0x3034	0x4E5A	# <CJK>
+0x3035	0x4E5C	# <CJK>
+0x3036	0x4E63	# <CJK>
+0x3037	0x4E68	# <CJK>
+0x3038	0x4E69	# <CJK>
+0x3039	0x4E74	# <CJK>
+0x303A	0x4E75	# <CJK>
+0x303B	0x4E79	# <CJK>
+0x303C	0x4E7F	# <CJK>
+0x303D	0x4E8D	# <CJK>
+0x303E	0x4E96	# <CJK>
+0x303F	0x4E97	# <CJK>
+0x3040	0x4E9D	# <CJK>
+0x3041	0x4EAF	# <CJK>
+0x3042	0x4EB9	# <CJK>
+0x3043	0x4EC3	# <CJK>
+0x3044	0x4ED0	# <CJK>
+0x3045	0x4EDA	# <CJK>
+0x3046	0x4EDB	# <CJK>
+0x3047	0x4EE0	# <CJK>
+0x3048	0x4EE1	# <CJK>
+0x3049	0x4EE2	# <CJK>
+0x304A	0x4EE8	# <CJK>
+0x304B	0x4EEF	# <CJK>
+0x304C	0x4EF1	# <CJK>
+0x304D	0x4EF3	# <CJK>
+0x304E	0x4EF5	# <CJK>
+0x304F	0x4EFD	# <CJK>
+0x3050	0x4EFE	# <CJK>
+0x3051	0x4EFF	# <CJK>
+0x3052	0x4F00	# <CJK>
+0x3053	0x4F02	# <CJK>
+0x3054	0x4F03	# <CJK>
+0x3055	0x4F08	# <CJK>
+0x3056	0x4F0B	# <CJK>
+0x3057	0x4F0C	# <CJK>
+0x3058	0x4F12	# <CJK>
+0x3059	0x4F15	# <CJK>
+0x305A	0x4F16	# <CJK>
+0x305B	0x4F17	# <CJK>
+0x305C	0x4F19	# <CJK>
+0x305D	0x4F2E	# <CJK>
+0x305E	0x4F31	# <CJK>
+0x305F	0x4F60	# <CJK>
+0x3060	0x4F33	# <CJK>
+0x3061	0x4F35	# <CJK>
+0x3062	0x4F37	# <CJK>
+0x3063	0x4F39	# <CJK>
+0x3064	0x4F3B	# <CJK>
+0x3065	0x4F3E	# <CJK>
+0x3066	0x4F40	# <CJK>
+0x3067	0x4F42	# <CJK>
+0x3068	0x4F48	# <CJK>
+0x3069	0x4F49	# <CJK>
+0x306A	0x4F4B	# <CJK>
+0x306B	0x4F4C	# <CJK>
+0x306C	0x4F52	# <CJK>
+0x306D	0x4F54	# <CJK>
+0x306E	0x4F56	# <CJK>
+0x306F	0x4F58	# <CJK>
+0x3070	0x4F5F	# <CJK>
+0x3071	0x4F63	# <CJK>
+0x3072	0x4F6A	# <CJK>
+0x3073	0x4F6C	# <CJK>
+0x3074	0x4F6E	# <CJK>
+0x3075	0x4F71	# <CJK>
+0x3076	0x4F77	# <CJK>
+0x3077	0x4F78	# <CJK>
+0x3078	0x4F79	# <CJK>
+0x3079	0x4F7A	# <CJK>
+0x307A	0x4F7D	# <CJK>
+0x307B	0x4F7E	# <CJK>
+0x307C	0x4F81	# <CJK>
+0x307D	0x4F82	# <CJK>
+0x307E	0x4F84	# <CJK>
+0x3121	0x4F85	# <CJK>
+0x3122	0x4F89	# <CJK>
+0x3123	0x4F8A	# <CJK>
+0x3124	0x4F8C	# <CJK>
+0x3125	0x4F8E	# <CJK>
+0x3126	0x4F90	# <CJK>
+0x3127	0x4F92	# <CJK>
+0x3128	0x4F93	# <CJK>
+0x3129	0x4F94	# <CJK>
+0x312A	0x4F97	# <CJK>
+0x312B	0x4F99	# <CJK>
+0x312C	0x4F9A	# <CJK>
+0x312D	0x4F9E	# <CJK>
+0x312E	0x4F9F	# <CJK>
+0x312F	0x4FB2	# <CJK>
+0x3130	0x4FB7	# <CJK>
+0x3131	0x4FB9	# <CJK>
+0x3132	0x4FBB	# <CJK>
+0x3133	0x4FBC	# <CJK>
+0x3134	0x4FBD	# <CJK>
+0x3135	0x4FBE	# <CJK>
+0x3136	0x4FC0	# <CJK>
+0x3137	0x4FC1	# <CJK>
+0x3138	0x4FC5	# <CJK>
+0x3139	0x4FC6	# <CJK>
+0x313A	0x4FC8	# <CJK>
+0x313B	0x4FC9	# <CJK>
+0x313C	0x4FCB	# <CJK>
+0x313D	0x4FCC	# <CJK>
+0x313E	0x4FCD	# <CJK>
+0x313F	0x4FCF	# <CJK>
+0x3140	0x4FD2	# <CJK>
+0x3141	0x4FDC	# <CJK>
+0x3142	0x4FE0	# <CJK>
+0x3143	0x4FE2	# <CJK>
+0x3144	0x4FF0	# <CJK>
+0x3145	0x4FF2	# <CJK>
+0x3146	0x4FFC	# <CJK>
+0x3147	0x4FFD	# <CJK>
+0x3148	0x4FFF	# <CJK>
+0x3149	0x5000	# <CJK>
+0x314A	0x5001	# <CJK>
+0x314B	0x5004	# <CJK>
+0x314C	0x5007	# <CJK>
+0x314D	0x500A	# <CJK>
+0x314E	0x500C	# <CJK>
+0x314F	0x500E	# <CJK>
+0x3150	0x5010	# <CJK>
+0x3151	0x5013	# <CJK>
+0x3152	0x5017	# <CJK>
+0x3153	0x5018	# <CJK>
+0x3154	0x501B	# <CJK>
+0x3155	0x501C	# <CJK>
+0x3156	0x501D	# <CJK>
+0x3157	0x501E	# <CJK>
+0x3158	0x5022	# <CJK>
+0x3159	0x5027	# <CJK>
+0x315A	0x502E	# <CJK>
+0x315B	0x5030	# <CJK>
+0x315C	0x5032	# <CJK>
+0x315D	0x5033	# <CJK>
+0x315E	0x5035	# <CJK>
+0x315F	0x5040	# <CJK>
+0x3160	0x5041	# <CJK>
+0x3161	0x5042	# <CJK>
+0x3162	0x5045	# <CJK>
+0x3163	0x5046	# <CJK>
+0x3164	0x504A	# <CJK>
+0x3165	0x504C	# <CJK>
+0x3166	0x504E	# <CJK>
+0x3167	0x5051	# <CJK>
+0x3168	0x5052	# <CJK>
+0x3169	0x5053	# <CJK>
+0x316A	0x5057	# <CJK>
+0x316B	0x5059	# <CJK>
+0x316C	0x505F	# <CJK>
+0x316D	0x5060	# <CJK>
+0x316E	0x5062	# <CJK>
+0x316F	0x5063	# <CJK>
+0x3170	0x5066	# <CJK>
+0x3171	0x5067	# <CJK>
+0x3172	0x506A	# <CJK>
+0x3173	0x506D	# <CJK>
+0x3174	0x5070	# <CJK>
+0x3175	0x5071	# <CJK>
+0x3176	0x503B	# <CJK>
+0x3177	0x5081	# <CJK>
+0x3178	0x5083	# <CJK>
+0x3179	0x5084	# <CJK>
+0x317A	0x5086	# <CJK>
+0x317B	0x508A	# <CJK>
+0x317C	0x508E	# <CJK>
+0x317D	0x508F	# <CJK>
+0x317E	0x5090	# <CJK>
+0x3221	0x5092	# <CJK>
+0x3222	0x5093	# <CJK>
+0x3223	0x5094	# <CJK>
+0x3224	0x5096	# <CJK>
+0x3225	0x509B	# <CJK>
+0x3226	0x509C	# <CJK>
+0x3227	0x509E	# <CJK>
+0x3228	0x509F	# <CJK>
+0x3229	0x50A0	# <CJK>
+0x322A	0x50A1	# <CJK>
+0x322B	0x50A2	# <CJK>
+0x322C	0x50AA	# <CJK>
+0x322D	0x50AF	# <CJK>
+0x322E	0x50B0	# <CJK>
+0x322F	0x50B9	# <CJK>
+0x3230	0x50BA	# <CJK>
+0x3231	0x50BD	# <CJK>
+0x3232	0x50C0	# <CJK>
+0x3233	0x50C3	# <CJK>
+0x3234	0x50C4	# <CJK>
+0x3235	0x50C7	# <CJK>
+0x3236	0x50CC	# <CJK>
+0x3237	0x50CE	# <CJK>
+0x3238	0x50D0	# <CJK>
+0x3239	0x50D3	# <CJK>
+0x323A	0x50D4	# <CJK>
+0x323B	0x50D8	# <CJK>
+0x323C	0x50DC	# <CJK>
+0x323D	0x50DD	# <CJK>
+0x323E	0x50DF	# <CJK>
+0x323F	0x50E2	# <CJK>
+0x3240	0x50E4	# <CJK>
+0x3241	0x50E6	# <CJK>
+0x3242	0x50E8	# <CJK>
+0x3243	0x50E9	# <CJK>
+0x3244	0x50EF	# <CJK>
+0x3245	0x50F1	# <CJK>
+0x3246	0x50F6	# <CJK>
+0x3247	0x50FA	# <CJK>
+0x3248	0x50FE	# <CJK>
+0x3249	0x5103	# <CJK>
+0x324A	0x5106	# <CJK>
+0x324B	0x5107	# <CJK>
+0x324C	0x5108	# <CJK>
+0x324D	0x510B	# <CJK>
+0x324E	0x510C	# <CJK>
+0x324F	0x510D	# <CJK>
+0x3250	0x510E	# <CJK>
+0x3251	0x50F2	# <CJK>
+0x3252	0x5110	# <CJK>
+0x3253	0x5117	# <CJK>
+0x3254	0x5119	# <CJK>
+0x3255	0x511B	# <CJK>
+0x3256	0x511C	# <CJK>
+0x3257	0x511D	# <CJK>
+0x3258	0x511E	# <CJK>
+0x3259	0x5123	# <CJK>
+0x325A	0x5127	# <CJK>
+0x325B	0x5128	# <CJK>
+0x325C	0x512C	# <CJK>
+0x325D	0x512D	# <CJK>
+0x325E	0x512F	# <CJK>
+0x325F	0x5131	# <CJK>
+0x3260	0x5133	# <CJK>
+0x3261	0x5134	# <CJK>
+0x3262	0x5135	# <CJK>
+0x3263	0x5138	# <CJK>
+0x3264	0x5139	# <CJK>
+0x3265	0x5142	# <CJK>
+0x3266	0x514A	# <CJK>
+0x3267	0x514F	# <CJK>
+0x3268	0x5153	# <CJK>
+0x3269	0x5155	# <CJK>
+0x326A	0x5157	# <CJK>
+0x326B	0x5158	# <CJK>
+0x326C	0x515F	# <CJK>
+0x326D	0x5164	# <CJK>
+0x326E	0x5166	# <CJK>
+0x326F	0x517E	# <CJK>
+0x3270	0x5183	# <CJK>
+0x3271	0x5184	# <CJK>
+0x3272	0x518B	# <CJK>
+0x3273	0x518E	# <CJK>
+0x3274	0x5198	# <CJK>
+0x3275	0x519D	# <CJK>
+0x3276	0x51A1	# <CJK>
+0x3277	0x51A3	# <CJK>
+0x3278	0x51AD	# <CJK>
+0x3279	0x51B8	# <CJK>
+0x327A	0x51BA	# <CJK>
+0x327B	0x51BC	# <CJK>
+0x327C	0x51BE	# <CJK>
+0x327D	0x51BF	# <CJK>
+0x327E	0x51C2	# <CJK>
+0x3321	0x51C8	# <CJK>
+0x3322	0x51CF	# <CJK>
+0x3323	0x51D1	# <CJK>
+0x3324	0x51D2	# <CJK>
+0x3325	0x51D3	# <CJK>
+0x3326	0x51D5	# <CJK>
+0x3327	0x51D8	# <CJK>
+0x3328	0x51DE	# <CJK>
+0x3329	0x51E2	# <CJK>
+0x332A	0x51E5	# <CJK>
+0x332B	0x51EE	# <CJK>
+0x332C	0x51F2	# <CJK>
+0x332D	0x51F3	# <CJK>
+0x332E	0x51F4	# <CJK>
+0x332F	0x51F7	# <CJK>
+0x3330	0x5201	# <CJK>
+0x3331	0x5202	# <CJK>
+0x3332	0x5205	# <CJK>
+0x3333	0x5212	# <CJK>
+0x3334	0x5213	# <CJK>
+0x3335	0x5215	# <CJK>
+0x3336	0x5216	# <CJK>
+0x3337	0x5218	# <CJK>
+0x3338	0x5222	# <CJK>
+0x3339	0x5228	# <CJK>
+0x333A	0x5231	# <CJK>
+0x333B	0x5232	# <CJK>
+0x333C	0x5235	# <CJK>
+0x333D	0x523C	# <CJK>
+0x333E	0x5245	# <CJK>
+0x333F	0x5249	# <CJK>
+0x3340	0x5255	# <CJK>
+0x3341	0x5257	# <CJK>
+0x3342	0x5258	# <CJK>
+0x3343	0x525A	# <CJK>
+0x3344	0x525C	# <CJK>
+0x3345	0x525F	# <CJK>
+0x3346	0x5260	# <CJK>
+0x3347	0x5261	# <CJK>
+0x3348	0x5266	# <CJK>
+0x3349	0x526E	# <CJK>
+0x334A	0x5277	# <CJK>
+0x334B	0x5278	# <CJK>
+0x334C	0x5279	# <CJK>
+0x334D	0x5280	# <CJK>
+0x334E	0x5282	# <CJK>
+0x334F	0x5285	# <CJK>
+0x3350	0x528A	# <CJK>
+0x3351	0x528C	# <CJK>
+0x3352	0x5293	# <CJK>
+0x3353	0x5295	# <CJK>
+0x3354	0x5296	# <CJK>
+0x3355	0x5297	# <CJK>
+0x3356	0x5298	# <CJK>
+0x3357	0x529A	# <CJK>
+0x3358	0x529C	# <CJK>
+0x3359	0x52A4	# <CJK>
+0x335A	0x52A5	# <CJK>
+0x335B	0x52A6	# <CJK>
+0x335C	0x52A7	# <CJK>
+0x335D	0x52AF	# <CJK>
+0x335E	0x52B0	# <CJK>
+0x335F	0x52B6	# <CJK>
+0x3360	0x52B7	# <CJK>
+0x3361	0x52B8	# <CJK>
+0x3362	0x52BA	# <CJK>
+0x3363	0x52BB	# <CJK>
+0x3364	0x52BD	# <CJK>
+0x3365	0x52C0	# <CJK>
+0x3366	0x52C4	# <CJK>
+0x3367	0x52C6	# <CJK>
+0x3368	0x52C8	# <CJK>
+0x3369	0x52CC	# <CJK>
+0x336A	0x52CF	# <CJK>
+0x336B	0x52D1	# <CJK>
+0x336C	0x52D4	# <CJK>
+0x336D	0x52D6	# <CJK>
+0x336E	0x52DB	# <CJK>
+0x336F	0x52DC	# <CJK>
+0x3370	0x52E1	# <CJK>
+0x3371	0x52E5	# <CJK>
+0x3372	0x52E8	# <CJK>
+0x3373	0x52E9	# <CJK>
+0x3374	0x52EA	# <CJK>
+0x3375	0x52EC	# <CJK>
+0x3376	0x52F0	# <CJK>
+0x3377	0x52F1	# <CJK>
+0x3378	0x52F4	# <CJK>
+0x3379	0x52F6	# <CJK>
+0x337A	0x52F7	# <CJK>
+0x337B	0x5300	# <CJK>
+0x337C	0x5303	# <CJK>
+0x337D	0x530A	# <CJK>
+0x337E	0x530B	# <CJK>
+0x3421	0x530C	# <CJK>
+0x3422	0x5311	# <CJK>
+0x3423	0x5313	# <CJK>
+0x3424	0x5318	# <CJK>
+0x3425	0x531B	# <CJK>
+0x3426	0x531C	# <CJK>
+0x3427	0x531E	# <CJK>
+0x3428	0x531F	# <CJK>
+0x3429	0x5325	# <CJK>
+0x342A	0x5327	# <CJK>
+0x342B	0x5328	# <CJK>
+0x342C	0x5329	# <CJK>
+0x342D	0x532B	# <CJK>
+0x342E	0x532C	# <CJK>
+0x342F	0x532D	# <CJK>
+0x3430	0x5330	# <CJK>
+0x3431	0x5332	# <CJK>
+0x3432	0x5335	# <CJK>
+0x3433	0x533C	# <CJK>
+0x3434	0x533D	# <CJK>
+0x3435	0x533E	# <CJK>
+0x3436	0x5342	# <CJK>
+0x3437	0x534C	# <CJK>
+0x3438	0x534B	# <CJK>
+0x3439	0x5359	# <CJK>
+0x343A	0x535B	# <CJK>
+0x343B	0x5361	# <CJK>
+0x343C	0x5363	# <CJK>
+0x343D	0x5365	# <CJK>
+0x343E	0x536C	# <CJK>
+0x343F	0x536D	# <CJK>
+0x3440	0x5372	# <CJK>
+0x3441	0x5379	# <CJK>
+0x3442	0x537E	# <CJK>
+0x3443	0x5383	# <CJK>
+0x3444	0x5387	# <CJK>
+0x3445	0x5388	# <CJK>
+0x3446	0x538E	# <CJK>
+0x3447	0x5393	# <CJK>
+0x3448	0x5394	# <CJK>
+0x3449	0x5399	# <CJK>
+0x344A	0x539D	# <CJK>
+0x344B	0x53A1	# <CJK>
+0x344C	0x53A4	# <CJK>
+0x344D	0x53AA	# <CJK>
+0x344E	0x53AB	# <CJK>
+0x344F	0x53AF	# <CJK>
+0x3450	0x53B2	# <CJK>
+0x3451	0x53B4	# <CJK>
+0x3452	0x53B5	# <CJK>
+0x3453	0x53B7	# <CJK>
+0x3454	0x53B8	# <CJK>
+0x3455	0x53BA	# <CJK>
+0x3456	0x53BD	# <CJK>
+0x3457	0x53C0	# <CJK>
+0x3458	0x53C5	# <CJK>
+0x3459	0x53CF	# <CJK>
+0x345A	0x53D2	# <CJK>
+0x345B	0x53D3	# <CJK>
+0x345C	0x53D5	# <CJK>
+0x345D	0x53DA	# <CJK>
+0x345E	0x53DD	# <CJK>
+0x345F	0x53DE	# <CJK>
+0x3460	0x53E0	# <CJK>
+0x3461	0x53E6	# <CJK>
+0x3462	0x53E7	# <CJK>
+0x3463	0x53F5	# <CJK>
+0x3464	0x5402	# <CJK>
+0x3465	0x5413	# <CJK>
+0x3466	0x541A	# <CJK>
+0x3467	0x5421	# <CJK>
+0x3468	0x5427	# <CJK>
+0x3469	0x5428	# <CJK>
+0x346A	0x542A	# <CJK>
+0x346B	0x542F	# <CJK>
+0x346C	0x5431	# <CJK>
+0x346D	0x5434	# <CJK>
+0x346E	0x5435	# <CJK>
+0x346F	0x5443	# <CJK>
+0x3470	0x5444	# <CJK>
+0x3471	0x5447	# <CJK>
+0x3472	0x544D	# <CJK>
+0x3473	0x544F	# <CJK>
+0x3474	0x545E	# <CJK>
+0x3475	0x5462	# <CJK>
+0x3476	0x5464	# <CJK>
+0x3477	0x5466	# <CJK>
+0x3478	0x5467	# <CJK>
+0x3479	0x5469	# <CJK>
+0x347A	0x546B	# <CJK>
+0x347B	0x546D	# <CJK>
+0x347C	0x546E	# <CJK>
+0x347D	0x5474	# <CJK>
+0x347E	0x547F	# <CJK>
+0x3521	0x5481	# <CJK>
+0x3522	0x5483	# <CJK>
+0x3523	0x5485	# <CJK>
+0x3524	0x5488	# <CJK>
+0x3525	0x5489	# <CJK>
+0x3526	0x548D	# <CJK>
+0x3527	0x5491	# <CJK>
+0x3528	0x5495	# <CJK>
+0x3529	0x5496	# <CJK>
+0x352A	0x549C	# <CJK>
+0x352B	0x549F	# <CJK>
+0x352C	0x54A1	# <CJK>
+0x352D	0x54A6	# <CJK>
+0x352E	0x54A7	# <CJK>
+0x352F	0x54A9	# <CJK>
+0x3530	0x54AA	# <CJK>
+0x3531	0x54AD	# <CJK>
+0x3532	0x54AE	# <CJK>
+0x3533	0x54B1	# <CJK>
+0x3534	0x54B7	# <CJK>
+0x3535	0x54B9	# <CJK>
+0x3536	0x54BA	# <CJK>
+0x3537	0x54BB	# <CJK>
+0x3538	0x54BF	# <CJK>
+0x3539	0x54C6	# <CJK>
+0x353A	0x54CA	# <CJK>
+0x353B	0x54CD	# <CJK>
+0x353C	0x54CE	# <CJK>
+0x353D	0x54E0	# <CJK>
+0x353E	0x54EA	# <CJK>
+0x353F	0x54EC	# <CJK>
+0x3540	0x54EF	# <CJK>
+0x3541	0x54F6	# <CJK>
+0x3542	0x54FC	# <CJK>
+0x3543	0x54FE	# <CJK>
+0x3544	0x54FF	# <CJK>
+0x3545	0x5500	# <CJK>
+0x3546	0x5501	# <CJK>
+0x3547	0x5505	# <CJK>
+0x3548	0x5508	# <CJK>
+0x3549	0x5509	# <CJK>
+0x354A	0x550C	# <CJK>
+0x354B	0x550D	# <CJK>
+0x354C	0x550E	# <CJK>
+0x354D	0x5515	# <CJK>
+0x354E	0x552A	# <CJK>
+0x354F	0x552B	# <CJK>
+0x3550	0x5532	# <CJK>
+0x3551	0x5535	# <CJK>
+0x3552	0x5536	# <CJK>
+0x3553	0x553B	# <CJK>
+0x3554	0x553C	# <CJK>
+0x3555	0x553D	# <CJK>
+0x3556	0x5541	# <CJK>
+0x3557	0x5547	# <CJK>
+0x3558	0x5549	# <CJK>
+0x3559	0x554A	# <CJK>
+0x355A	0x554D	# <CJK>
+0x355B	0x5550	# <CJK>
+0x355C	0x5551	# <CJK>
+0x355D	0x5558	# <CJK>
+0x355E	0x555A	# <CJK>
+0x355F	0x555B	# <CJK>
+0x3560	0x555E	# <CJK>
+0x3561	0x5560	# <CJK>
+0x3562	0x5561	# <CJK>
+0x3563	0x5564	# <CJK>
+0x3564	0x5566	# <CJK>
+0x3565	0x557F	# <CJK>
+0x3566	0x5581	# <CJK>
+0x3567	0x5582	# <CJK>
+0x3568	0x5586	# <CJK>
+0x3569	0x5588	# <CJK>
+0x356A	0x558E	# <CJK>
+0x356B	0x558F	# <CJK>
+0x356C	0x5591	# <CJK>
+0x356D	0x5592	# <CJK>
+0x356E	0x5593	# <CJK>
+0x356F	0x5594	# <CJK>
+0x3570	0x5597	# <CJK>
+0x3571	0x55A3	# <CJK>
+0x3572	0x55A4	# <CJK>
+0x3573	0x55AD	# <CJK>
+0x3574	0x55B2	# <CJK>
+0x3575	0x55BF	# <CJK>
+0x3576	0x55C1	# <CJK>
+0x3577	0x55C3	# <CJK>
+0x3578	0x55C6	# <CJK>
+0x3579	0x55C9	# <CJK>
+0x357A	0x55CB	# <CJK>
+0x357B	0x55CC	# <CJK>
+0x357C	0x55CE	# <CJK>
+0x357D	0x55D1	# <CJK>
+0x357E	0x55D2	# <CJK>
+0x3621	0x55D3	# <CJK>
+0x3622	0x55D7	# <CJK>
+0x3623	0x55D8	# <CJK>
+0x3624	0x55DB	# <CJK>
+0x3625	0x55DE	# <CJK>
+0x3626	0x55E2	# <CJK>
+0x3627	0x55E9	# <CJK>
+0x3628	0x55F6	# <CJK>
+0x3629	0x55FF	# <CJK>
+0x362A	0x5605	# <CJK>
+0x362B	0x5608	# <CJK>
+0x362C	0x560A	# <CJK>
+0x362D	0x560D	# <CJK>
+0x362E	0x560E	# <CJK>
+0x362F	0x560F	# <CJK>
+0x3630	0x5610	# <CJK>
+0x3631	0x5611	# <CJK>
+0x3632	0x5612	# <CJK>
+0x3633	0x5619	# <CJK>
+0x3634	0x562C	# <CJK>
+0x3635	0x5630	# <CJK>
+0x3636	0x5633	# <CJK>
+0x3637	0x5635	# <CJK>
+0x3638	0x5637	# <CJK>
+0x3639	0x5639	# <CJK>
+0x363A	0x563B	# <CJK>
+0x363B	0x563C	# <CJK>
+0x363C	0x563D	# <CJK>
+0x363D	0x563F	# <CJK>
+0x363E	0x5640	# <CJK>
+0x363F	0x5641	# <CJK>
+0x3640	0x5643	# <CJK>
+0x3641	0x5644	# <CJK>
+0x3642	0x5646	# <CJK>
+0x3643	0x5649	# <CJK>
+0x3644	0x564B	# <CJK>
+0x3645	0x564D	# <CJK>
+0x3646	0x564F	# <CJK>
+0x3647	0x5654	# <CJK>
+0x3648	0x565E	# <CJK>
+0x3649	0x5660	# <CJK>
+0x364A	0x5661	# <CJK>
+0x364B	0x5662	# <CJK>
+0x364C	0x5663	# <CJK>
+0x364D	0x5666	# <CJK>
+0x364E	0x5669	# <CJK>
+0x364F	0x566D	# <CJK>
+0x3650	0x566F	# <CJK>
+0x3651	0x5671	# <CJK>
+0x3652	0x5672	# <CJK>
+0x3653	0x5675	# <CJK>
+0x3654	0x5684	# <CJK>
+0x3655	0x5685	# <CJK>
+0x3656	0x5688	# <CJK>
+0x3657	0x568B	# <CJK>
+0x3658	0x568C	# <CJK>
+0x3659	0x5695	# <CJK>
+0x365A	0x5699	# <CJK>
+0x365B	0x569A	# <CJK>
+0x365C	0x569D	# <CJK>
+0x365D	0x569E	# <CJK>
+0x365E	0x569F	# <CJK>
+0x365F	0x56A6	# <CJK>
+0x3660	0x56A7	# <CJK>
+0x3661	0x56A8	# <CJK>
+0x3662	0x56A9	# <CJK>
+0x3663	0x56AB	# <CJK>
+0x3664	0x56AC	# <CJK>
+0x3665	0x56AD	# <CJK>
+0x3666	0x56B1	# <CJK>
+0x3667	0x56B3	# <CJK>
+0x3668	0x56B7	# <CJK>
+0x3669	0x56BE	# <CJK>
+0x366A	0x56C5	# <CJK>
+0x366B	0x56C9	# <CJK>
+0x366C	0x56CA	# <CJK>
+0x366D	0x56CB	# <CJK>
+0x366E	0x56CF	# <CJK>
+0x366F	0x56D0	# <CJK>
+0x3670	0x56CC	# <CJK>
+0x3671	0x56CD	# <CJK>
+0x3672	0x56D9	# <CJK>
+0x3673	0x56DC	# <CJK>
+0x3674	0x56DD	# <CJK>
+0x3675	0x56DF	# <CJK>
+0x3676	0x56E1	# <CJK>
+0x3677	0x56E4	# <CJK>
+0x3678	0x56E5	# <CJK>
+0x3679	0x56E6	# <CJK>
+0x367A	0x56E7	# <CJK>
+0x367B	0x56E8	# <CJK>
+0x367C	0x56F1	# <CJK>
+0x367D	0x56EB	# <CJK>
+0x367E	0x56ED	# <CJK>
+0x3721	0x56F6	# <CJK>
+0x3722	0x56F7	# <CJK>
+0x3723	0x5701	# <CJK>
+0x3724	0x5702	# <CJK>
+0x3725	0x5707	# <CJK>
+0x3726	0x570A	# <CJK>
+0x3727	0x570C	# <CJK>
+0x3728	0x5711	# <CJK>
+0x3729	0x5715	# <CJK>
+0x372A	0x571A	# <CJK>
+0x372B	0x571B	# <CJK>
+0x372C	0x571D	# <CJK>
+0x372D	0x5720	# <CJK>
+0x372E	0x5722	# <CJK>
+0x372F	0x5723	# <CJK>
+0x3730	0x5724	# <CJK>
+0x3731	0x5725	# <CJK>
+0x3732	0x5729	# <CJK>
+0x3733	0x572A	# <CJK>
+0x3734	0x572C	# <CJK>
+0x3735	0x572E	# <CJK>
+0x3736	0x572F	# <CJK>
+0x3737	0x5733	# <CJK>
+0x3738	0x5734	# <CJK>
+0x3739	0x573D	# <CJK>
+0x373A	0x573E	# <CJK>
+0x373B	0x573F	# <CJK>
+0x373C	0x5745	# <CJK>
+0x373D	0x5746	# <CJK>
+0x373E	0x574C	# <CJK>
+0x373F	0x574D	# <CJK>
+0x3740	0x5752	# <CJK>
+0x3741	0x5762	# <CJK>
+0x3742	0x5765	# <CJK>
+0x3743	0x5767	# <CJK>
+0x3744	0x5768	# <CJK>
+0x3745	0x576B	# <CJK>
+0x3746	0x576D	# <CJK>
+0x3747	0x576E	# <CJK>
+0x3748	0x576F	# <CJK>
+0x3749	0x5770	# <CJK>
+0x374A	0x5771	# <CJK>
+0x374B	0x5773	# <CJK>
+0x374C	0x5774	# <CJK>
+0x374D	0x5775	# <CJK>
+0x374E	0x5777	# <CJK>
+0x374F	0x5779	# <CJK>
+0x3750	0x577A	# <CJK>
+0x3751	0x577B	# <CJK>
+0x3752	0x577C	# <CJK>
+0x3753	0x577E	# <CJK>
+0x3754	0x5781	# <CJK>
+0x3755	0x5783	# <CJK>
+0x3756	0x578C	# <CJK>
+0x3757	0x5794	# <CJK>
+0x3758	0x5797	# <CJK>
+0x3759	0x5799	# <CJK>
+0x375A	0x579A	# <CJK>
+0x375B	0x579C	# <CJK>
+0x375C	0x579D	# <CJK>
+0x375D	0x579E	# <CJK>
+0x375E	0x579F	# <CJK>
+0x375F	0x57A1	# <CJK>
+0x3760	0x5795	# <CJK>
+0x3761	0x57A7	# <CJK>
+0x3762	0x57A8	# <CJK>
+0x3763	0x57A9	# <CJK>
+0x3764	0x57AC	# <CJK>
+0x3765	0x57B8	# <CJK>
+0x3766	0x57BD	# <CJK>
+0x3767	0x57C7	# <CJK>
+0x3768	0x57C8	# <CJK>
+0x3769	0x57CC	# <CJK>
+0x376A	0x57CF	# <CJK>
+0x376B	0x57D5	# <CJK>
+0x376C	0x57DD	# <CJK>
+0x376D	0x57DE	# <CJK>
+0x376E	0x57E4	# <CJK>
+0x376F	0x57E6	# <CJK>
+0x3770	0x57E7	# <CJK>
+0x3771	0x57E9	# <CJK>
+0x3772	0x57ED	# <CJK>
+0x3773	0x57F0	# <CJK>
+0x3774	0x57F5	# <CJK>
+0x3775	0x57F6	# <CJK>
+0x3776	0x57F8	# <CJK>
+0x3777	0x57FD	# <CJK>
+0x3778	0x57FE	# <CJK>
+0x3779	0x57FF	# <CJK>
+0x377A	0x5803	# <CJK>
+0x377B	0x5804	# <CJK>
+0x377C	0x5808	# <CJK>
+0x377D	0x5809	# <CJK>
+0x377E	0x57E1	# <CJK>
+0x3821	0x580C	# <CJK>
+0x3822	0x580D	# <CJK>
+0x3823	0x581B	# <CJK>
+0x3824	0x581E	# <CJK>
+0x3825	0x581F	# <CJK>
+0x3826	0x5820	# <CJK>
+0x3827	0x5826	# <CJK>
+0x3828	0x5827	# <CJK>
+0x3829	0x582D	# <CJK>
+0x382A	0x5832	# <CJK>
+0x382B	0x5839	# <CJK>
+0x382C	0x583F	# <CJK>
+0x382D	0x5849	# <CJK>
+0x382E	0x584C	# <CJK>
+0x382F	0x584D	# <CJK>
+0x3830	0x584F	# <CJK>
+0x3831	0x5850	# <CJK>
+0x3832	0x5855	# <CJK>
+0x3833	0x585F	# <CJK>
+0x3834	0x5861	# <CJK>
+0x3835	0x5864	# <CJK>
+0x3836	0x5867	# <CJK>
+0x3837	0x5868	# <CJK>
+0x3838	0x5878	# <CJK>
+0x3839	0x587C	# <CJK>
+0x383A	0x587F	# <CJK>
+0x383B	0x5880	# <CJK>
+0x383C	0x5881	# <CJK>
+0x383D	0x5887	# <CJK>
+0x383E	0x5888	# <CJK>
+0x383F	0x5889	# <CJK>
+0x3840	0x588A	# <CJK>
+0x3841	0x588C	# <CJK>
+0x3842	0x588D	# <CJK>
+0x3843	0x588F	# <CJK>
+0x3844	0x5890	# <CJK>
+0x3845	0x5894	# <CJK>
+0x3846	0x5896	# <CJK>
+0x3847	0x589D	# <CJK>
+0x3848	0x58A0	# <CJK>
+0x3849	0x58A1	# <CJK>
+0x384A	0x58A2	# <CJK>
+0x384B	0x58A6	# <CJK>
+0x384C	0x58A9	# <CJK>
+0x384D	0x58B1	# <CJK>
+0x384E	0x58B2	# <CJK>
+0x384F	0x58C4	# <CJK>
+0x3850	0x58BC	# <CJK>
+0x3851	0x58C2	# <CJK>
+0x3852	0x58C8	# <CJK>
+0x3853	0x58CD	# <CJK>
+0x3854	0x58CE	# <CJK>
+0x3855	0x58D0	# <CJK>
+0x3856	0x58D2	# <CJK>
+0x3857	0x58D4	# <CJK>
+0x3858	0x58D6	# <CJK>
+0x3859	0x58DA	# <CJK>
+0x385A	0x58DD	# <CJK>
+0x385B	0x58E1	# <CJK>
+0x385C	0x58E2	# <CJK>
+0x385D	0x58E9	# <CJK>
+0x385E	0x58F3	# <CJK>
+0x385F	0x5905	# <CJK>
+0x3860	0x5906	# <CJK>
+0x3861	0x590B	# <CJK>
+0x3862	0x590C	# <CJK>
+0x3863	0x5912	# <CJK>
+0x3864	0x5913	# <CJK>
+0x3865	0x5914	# <CJK>
+0x3866	0x8641	# <CJK>
+0x3867	0x591D	# <CJK>
+0x3868	0x5921	# <CJK>
+0x3869	0x5923	# <CJK>
+0x386A	0x5924	# <CJK>
+0x386B	0x5928	# <CJK>
+0x386C	0x592F	# <CJK>
+0x386D	0x5930	# <CJK>
+0x386E	0x5933	# <CJK>
+0x386F	0x5935	# <CJK>
+0x3870	0x5936	# <CJK>
+0x3871	0x593F	# <CJK>
+0x3872	0x5943	# <CJK>
+0x3873	0x5946	# <CJK>
+0x3874	0x5952	# <CJK>
+0x3875	0x5953	# <CJK>
+0x3876	0x5959	# <CJK>
+0x3877	0x595B	# <CJK>
+0x3878	0x595D	# <CJK>
+0x3879	0x595E	# <CJK>
+0x387A	0x595F	# <CJK>
+0x387B	0x5961	# <CJK>
+0x387C	0x5963	# <CJK>
+0x387D	0x596B	# <CJK>
+0x387E	0x596D	# <CJK>
+0x3921	0x596F	# <CJK>
+0x3922	0x5972	# <CJK>
+0x3923	0x5975	# <CJK>
+0x3924	0x5976	# <CJK>
+0x3925	0x5979	# <CJK>
+0x3926	0x597B	# <CJK>
+0x3927	0x597C	# <CJK>
+0x3928	0x598B	# <CJK>
+0x3929	0x598C	# <CJK>
+0x392A	0x598E	# <CJK>
+0x392B	0x5992	# <CJK>
+0x392C	0x5995	# <CJK>
+0x392D	0x5997	# <CJK>
+0x392E	0x599F	# <CJK>
+0x392F	0x59A4	# <CJK>
+0x3930	0x59A7	# <CJK>
+0x3931	0x59AD	# <CJK>
+0x3932	0x59AE	# <CJK>
+0x3933	0x59AF	# <CJK>
+0x3934	0x59B0	# <CJK>
+0x3935	0x59B3	# <CJK>
+0x3936	0x59B7	# <CJK>
+0x3937	0x59BA	# <CJK>
+0x3938	0x59BC	# <CJK>
+0x3939	0x59C1	# <CJK>
+0x393A	0x59C3	# <CJK>
+0x393B	0x59C4	# <CJK>
+0x393C	0x59C8	# <CJK>
+0x393D	0x59CA	# <CJK>
+0x393E	0x59CD	# <CJK>
+0x393F	0x59D2	# <CJK>
+0x3940	0x59DD	# <CJK>
+0x3941	0x59DE	# <CJK>
+0x3942	0x59DF	# <CJK>
+0x3943	0x59E3	# <CJK>
+0x3944	0x59E4	# <CJK>
+0x3945	0x59E7	# <CJK>
+0x3946	0x59EE	# <CJK>
+0x3947	0x59EF	# <CJK>
+0x3948	0x59F1	# <CJK>
+0x3949	0x59F2	# <CJK>
+0x394A	0x59F4	# <CJK>
+0x394B	0x59F7	# <CJK>
+0x394C	0x5A00	# <CJK>
+0x394D	0x5A04	# <CJK>
+0x394E	0x5A0C	# <CJK>
+0x394F	0x5A0D	# <CJK>
+0x3950	0x5A0E	# <CJK>
+0x3951	0x5A12	# <CJK>
+0x3952	0x5A13	# <CJK>
+0x3953	0x5A1E	# <CJK>
+0x3954	0x5A23	# <CJK>
+0x3955	0x5A24	# <CJK>
+0x3956	0x5A27	# <CJK>
+0x3957	0x5A28	# <CJK>
+0x3958	0x5A2A	# <CJK>
+0x3959	0x5A2D	# <CJK>
+0x395A	0x5A30	# <CJK>
+0x395B	0x5A44	# <CJK>
+0x395C	0x5A45	# <CJK>
+0x395D	0x5A47	# <CJK>
+0x395E	0x5A48	# <CJK>
+0x395F	0x5A4C	# <CJK>
+0x3960	0x5A50	# <CJK>
+0x3961	0x5A55	# <CJK>
+0x3962	0x5A5E	# <CJK>
+0x3963	0x5A63	# <CJK>
+0x3964	0x5A65	# <CJK>
+0x3965	0x5A67	# <CJK>
+0x3966	0x5A6D	# <CJK>
+0x3967	0x5A77	# <CJK>
+0x3968	0x5A7A	# <CJK>
+0x3969	0x5A7B	# <CJK>
+0x396A	0x5A7E	# <CJK>
+0x396B	0x5A8B	# <CJK>
+0x396C	0x5A90	# <CJK>
+0x396D	0x5A93	# <CJK>
+0x396E	0x5A96	# <CJK>
+0x396F	0x5A99	# <CJK>
+0x3970	0x5A9C	# <CJK>
+0x3971	0x5A9E	# <CJK>
+0x3972	0x5A9F	# <CJK>
+0x3973	0x5AA0	# <CJK>
+0x3974	0x5AA2	# <CJK>
+0x3975	0x5AA7	# <CJK>
+0x3976	0x5AAC	# <CJK>
+0x3977	0x5AB1	# <CJK>
+0x3978	0x5AB2	# <CJK>
+0x3979	0x5AB3	# <CJK>
+0x397A	0x5AB5	# <CJK>
+0x397B	0x5AB8	# <CJK>
+0x397C	0x5ABA	# <CJK>
+0x397D	0x5ABB	# <CJK>
+0x397E	0x5ABF	# <CJK>
+0x3A21	0x5AC4	# <CJK>
+0x3A22	0x5AC6	# <CJK>
+0x3A23	0x5AC8	# <CJK>
+0x3A24	0x5ACF	# <CJK>
+0x3A25	0x5ADA	# <CJK>
+0x3A26	0x5ADC	# <CJK>
+0x3A27	0x5AE0	# <CJK>
+0x3A28	0x5AE5	# <CJK>
+0x3A29	0x5AEA	# <CJK>
+0x3A2A	0x5AEE	# <CJK>
+0x3A2B	0x5AF5	# <CJK>
+0x3A2C	0x5AF6	# <CJK>
+0x3A2D	0x5AFD	# <CJK>
+0x3A2E	0x5B00	# <CJK>
+0x3A2F	0x5B01	# <CJK>
+0x3A30	0x5B08	# <CJK>
+0x3A31	0x5B17	# <CJK>
+0x3A32	0x5B34	# <CJK>
+0x3A33	0x5B19	# <CJK>
+0x3A34	0x5B1B	# <CJK>
+0x3A35	0x5B1D	# <CJK>
+0x3A36	0x5B21	# <CJK>
+0x3A37	0x5B25	# <CJK>
+0x3A38	0x5B2D	# <CJK>
+0x3A39	0x5B38	# <CJK>
+0x3A3A	0x5B41	# <CJK>
+0x3A3B	0x5B4B	# <CJK>
+0x3A3C	0x5B4C	# <CJK>
+0x3A3D	0x5B52	# <CJK>
+0x3A3E	0x5B56	# <CJK>
+0x3A3F	0x5B5E	# <CJK>
+0x3A40	0x5B68	# <CJK>
+0x3A41	0x5B6E	# <CJK>
+0x3A42	0x5B6F	# <CJK>
+0x3A43	0x5B7C	# <CJK>
+0x3A44	0x5B7D	# <CJK>
+0x3A45	0x5B7E	# <CJK>
+0x3A46	0x5B7F	# <CJK>
+0x3A47	0x5B81	# <CJK>
+0x3A48	0x5B84	# <CJK>
+0x3A49	0x5B86	# <CJK>
+0x3A4A	0x5B8A	# <CJK>
+0x3A4B	0x5B8E	# <CJK>
+0x3A4C	0x5B90	# <CJK>
+0x3A4D	0x5B91	# <CJK>
+0x3A4E	0x5B93	# <CJK>
+0x3A4F	0x5B94	# <CJK>
+0x3A50	0x5B96	# <CJK>
+0x3A51	0x5BA8	# <CJK>
+0x3A52	0x5BA9	# <CJK>
+0x3A53	0x5BAC	# <CJK>
+0x3A54	0x5BAD	# <CJK>
+0x3A55	0x5BAF	# <CJK>
+0x3A56	0x5BB1	# <CJK>
+0x3A57	0x5BB2	# <CJK>
+0x3A58	0x5BB7	# <CJK>
+0x3A59	0x5BBA	# <CJK>
+0x3A5A	0x5BBC	# <CJK>
+0x3A5B	0x5BC0	# <CJK>
+0x3A5C	0x5BC1	# <CJK>
+0x3A5D	0x5BCD	# <CJK>
+0x3A5E	0x5BCF	# <CJK>
+0x3A5F	0x5BD6	# <CJK>
+0x3A60	0x5BD7	# <CJK>
+0x3A61	0x5BD8	# <CJK>
+0x3A62	0x5BD9	# <CJK>
+0x3A63	0x5BDA	# <CJK>
+0x3A64	0x5BE0	# <CJK>
+0x3A65	0x5BEF	# <CJK>
+0x3A66	0x5BF1	# <CJK>
+0x3A67	0x5BF4	# <CJK>
+0x3A68	0x5BFD	# <CJK>
+0x3A69	0x5C0C	# <CJK>
+0x3A6A	0x5C17	# <CJK>
+0x3A6B	0x5C1E	# <CJK>
+0x3A6C	0x5C1F	# <CJK>
+0x3A6D	0x5C23	# <CJK>
+0x3A6E	0x5C26	# <CJK>
+0x3A6F	0x5C29	# <CJK>
+0x3A70	0x5C2B	# <CJK>
+0x3A71	0x5C2C	# <CJK>
+0x3A72	0x5C2E	# <CJK>
+0x3A73	0x5C30	# <CJK>
+0x3A74	0x5C32	# <CJK>
+0x3A75	0x5C35	# <CJK>
+0x3A76	0x5C36	# <CJK>
+0x3A77	0x5C59	# <CJK>
+0x3A78	0x5C5A	# <CJK>
+0x3A79	0x5C5C	# <CJK>
+0x3A7A	0x5C62	# <CJK>
+0x3A7B	0x5C63	# <CJK>
+0x3A7C	0x5C67	# <CJK>
+0x3A7D	0x5C68	# <CJK>
+0x3A7E	0x5C69	# <CJK>
+0x3B21	0x5C6D	# <CJK>
+0x3B22	0x5C70	# <CJK>
+0x3B23	0x5C74	# <CJK>
+0x3B24	0x5C75	# <CJK>
+0x3B25	0x5C7A	# <CJK>
+0x3B26	0x5C7B	# <CJK>
+0x3B27	0x5C7C	# <CJK>
+0x3B28	0x5C7D	# <CJK>
+0x3B29	0x5C87	# <CJK>
+0x3B2A	0x5C88	# <CJK>
+0x3B2B	0x5C8A	# <CJK>
+0x3B2C	0x5C8F	# <CJK>
+0x3B2D	0x5C92	# <CJK>
+0x3B2E	0x5C9D	# <CJK>
+0x3B2F	0x5C9F	# <CJK>
+0x3B30	0x5CA0	# <CJK>
+0x3B31	0x5CA2	# <CJK>
+0x3B32	0x5CA3	# <CJK>
+0x3B33	0x5CA6	# <CJK>
+0x3B34	0x5CAA	# <CJK>
+0x3B35	0x5CB2	# <CJK>
+0x3B36	0x5CB4	# <CJK>
+0x3B37	0x5CB5	# <CJK>
+0x3B38	0x5CBA	# <CJK>
+0x3B39	0x5CC9	# <CJK>
+0x3B3A	0x5CCB	# <CJK>
+0x3B3B	0x5CD2	# <CJK>
+0x3B3C	0x5CDD	# <CJK>
+0x3B3D	0x5CD7	# <CJK>
+0x3B3E	0x5CEE	# <CJK>
+0x3B3F	0x5CF1	# <CJK>
+0x3B40	0x5CF2	# <CJK>
+0x3B41	0x5CF4	# <CJK>
+0x3B42	0x5D01	# <CJK>
+0x3B43	0x5D06	# <CJK>
+0x3B44	0x5D0D	# <CJK>
+0x3B45	0x5D12	# <CJK>
+0x3B46	0x5D2B	# <CJK>
+0x3B47	0x5D23	# <CJK>
+0x3B48	0x5D24	# <CJK>
+0x3B49	0x5D26	# <CJK>
+0x3B4A	0x5D27	# <CJK>
+0x3B4B	0x5D31	# <CJK>
+0x3B4C	0x5D34	# <CJK>
+0x3B4D	0x5D39	# <CJK>
+0x3B4E	0x5D3D	# <CJK>
+0x3B4F	0x5D3F	# <CJK>
+0x3B50	0x5D42	# <CJK>
+0x3B51	0x5D43	# <CJK>
+0x3B52	0x5D46	# <CJK>
+0x3B53	0x5D48	# <CJK>
+0x3B54	0x5D55	# <CJK>
+0x3B55	0x5D51	# <CJK>
+0x3B56	0x5D59	# <CJK>
+0x3B57	0x5D4A	# <CJK>
+0x3B58	0x5D5F	# <CJK>
+0x3B59	0x5D60	# <CJK>
+0x3B5A	0x5D61	# <CJK>
+0x3B5B	0x5D62	# <CJK>
+0x3B5C	0x5D64	# <CJK>
+0x3B5D	0x5D6A	# <CJK>
+0x3B5E	0x5D6D	# <CJK>
+0x3B5F	0x5D70	# <CJK>
+0x3B60	0x5D79	# <CJK>
+0x3B61	0x5D7A	# <CJK>
+0x3B62	0x5D7E	# <CJK>
+0x3B63	0x5D7F	# <CJK>
+0x3B64	0x5D81	# <CJK>
+0x3B65	0x5D83	# <CJK>
+0x3B66	0x5D88	# <CJK>
+0x3B67	0x5D8A	# <CJK>
+0x3B68	0x5D92	# <CJK>
+0x3B69	0x5D93	# <CJK>
+0x3B6A	0x5D94	# <CJK>
+0x3B6B	0x5D95	# <CJK>
+0x3B6C	0x5D99	# <CJK>
+0x3B6D	0x5D9B	# <CJK>
+0x3B6E	0x5D9F	# <CJK>
+0x3B6F	0x5DA0	# <CJK>
+0x3B70	0x5DA7	# <CJK>
+0x3B71	0x5DAB	# <CJK>
+0x3B72	0x5DB0	# <CJK>
+0x3B73	0x5DB4	# <CJK>
+0x3B74	0x5DB8	# <CJK>
+0x3B75	0x5DB9	# <CJK>
+0x3B76	0x5DC3	# <CJK>
+0x3B77	0x5DC7	# <CJK>
+0x3B78	0x5DCB	# <CJK>
+0x3B79	0x5DD0	# <CJK>
+0x3B7A	0x5DCE	# <CJK>
+0x3B7B	0x5DD8	# <CJK>
+0x3B7C	0x5DD9	# <CJK>
+0x3B7D	0x5DE0	# <CJK>
+0x3B7E	0x5DE4	# <CJK>
+0x3C21	0x5DE9	# <CJK>
+0x3C22	0x5DF8	# <CJK>
+0x3C23	0x5DF9	# <CJK>
+0x3C24	0x5E00	# <CJK>
+0x3C25	0x5E07	# <CJK>
+0x3C26	0x5E0D	# <CJK>
+0x3C27	0x5E12	# <CJK>
+0x3C28	0x5E14	# <CJK>
+0x3C29	0x5E15	# <CJK>
+0x3C2A	0x5E18	# <CJK>
+0x3C2B	0x5E1F	# <CJK>
+0x3C2C	0x5E20	# <CJK>
+0x3C2D	0x5E2E	# <CJK>
+0x3C2E	0x5E28	# <CJK>
+0x3C2F	0x5E32	# <CJK>
+0x3C30	0x5E35	# <CJK>
+0x3C31	0x5E3E	# <CJK>
+0x3C32	0x5E4B	# <CJK>
+0x3C33	0x5E50	# <CJK>
+0x3C34	0x5E49	# <CJK>
+0x3C35	0x5E51	# <CJK>
+0x3C36	0x5E56	# <CJK>
+0x3C37	0x5E58	# <CJK>
+0x3C38	0x5E5B	# <CJK>
+0x3C39	0x5E5C	# <CJK>
+0x3C3A	0x5E5E	# <CJK>
+0x3C3B	0x5E68	# <CJK>
+0x3C3C	0x5E6A	# <CJK>
+0x3C3D	0x5E6B	# <CJK>
+0x3C3E	0x5E6C	# <CJK>
+0x3C3F	0x5E6D	# <CJK>
+0x3C40	0x5E6E	# <CJK>
+0x3C41	0x5E70	# <CJK>
+0x3C42	0x5E80	# <CJK>
+0x3C43	0x5E8B	# <CJK>
+0x3C44	0x5E8E	# <CJK>
+0x3C45	0x5EA2	# <CJK>
+0x3C46	0x5EA4	# <CJK>
+0x3C47	0x5EA5	# <CJK>
+0x3C48	0x5EA8	# <CJK>
+0x3C49	0x5EAA	# <CJK>
+0x3C4A	0x5EAC	# <CJK>
+0x3C4B	0x5EB1	# <CJK>
+0x3C4C	0x5EB3	# <CJK>
+0x3C4D	0x5EBD	# <CJK>
+0x3C4E	0x5EBE	# <CJK>
+0x3C4F	0x5EBF	# <CJK>
+0x3C50	0x5EC6	# <CJK>
+0x3C51	0x5ECC	# <CJK>
+0x3C52	0x5ECB	# <CJK>
+0x3C53	0x5ECE	# <CJK>
+0x3C54	0x5ED1	# <CJK>
+0x3C55	0x5ED2	# <CJK>
+0x3C56	0x5ED4	# <CJK>
+0x3C57	0x5ED5	# <CJK>
+0x3C58	0x5EDC	# <CJK>
+0x3C59	0x5EDE	# <CJK>
+0x3C5A	0x5EE5	# <CJK>
+0x3C5B	0x5EEB	# <CJK>
+0x3C5C	0x5F02	# <CJK>
+0x3C5D	0x5F06	# <CJK>
+0x3C5E	0x5F07	# <CJK>
+0x3C5F	0x5F08	# <CJK>
+0x3C60	0x5F0E	# <CJK>
+0x3C61	0x5F19	# <CJK>
+0x3C62	0x5F1C	# <CJK>
+0x3C63	0x5F1D	# <CJK>
+0x3C64	0x5F21	# <CJK>
+0x3C65	0x5F22	# <CJK>
+0x3C66	0x5F23	# <CJK>
+0x3C67	0x5F24	# <CJK>
+0x3C68	0x5F28	# <CJK>
+0x3C69	0x5F2B	# <CJK>
+0x3C6A	0x5F2C	# <CJK>
+0x3C6B	0x5F2E	# <CJK>
+0x3C6C	0x5F30	# <CJK>
+0x3C6D	0x5F34	# <CJK>
+0x3C6E	0x5F36	# <CJK>
+0x3C6F	0x5F3B	# <CJK>
+0x3C70	0x5F3D	# <CJK>
+0x3C71	0x5F3F	# <CJK>
+0x3C72	0x5F40	# <CJK>
+0x3C73	0x5F44	# <CJK>
+0x3C74	0x5F45	# <CJK>
+0x3C75	0x5F47	# <CJK>
+0x3C76	0x5F4D	# <CJK>
+0x3C77	0x5F50	# <CJK>
+0x3C78	0x5F54	# <CJK>
+0x3C79	0x5F58	# <CJK>
+0x3C7A	0x5F5B	# <CJK>
+0x3C7B	0x5F60	# <CJK>
+0x3C7C	0x5F63	# <CJK>
+0x3C7D	0x5F64	# <CJK>
+0x3C7E	0x5F67	# <CJK>
+0x3D21	0x5F6F	# <CJK>
+0x3D22	0x5F72	# <CJK>
+0x3D23	0x5F74	# <CJK>
+0x3D24	0x5F75	# <CJK>
+0x3D25	0x5F78	# <CJK>
+0x3D26	0x5F7A	# <CJK>
+0x3D27	0x5F7D	# <CJK>
+0x3D28	0x5F7E	# <CJK>
+0x3D29	0x5F89	# <CJK>
+0x3D2A	0x5F8D	# <CJK>
+0x3D2B	0x5F8F	# <CJK>
+0x3D2C	0x5F96	# <CJK>
+0x3D2D	0x5F9C	# <CJK>
+0x3D2E	0x5F9D	# <CJK>
+0x3D2F	0x5FA2	# <CJK>
+0x3D30	0x5FA7	# <CJK>
+0x3D31	0x5FAB	# <CJK>
+0x3D32	0x5FA4	# <CJK>
+0x3D33	0x5FAC	# <CJK>
+0x3D34	0x5FAF	# <CJK>
+0x3D35	0x5FB0	# <CJK>
+0x3D36	0x5FB1	# <CJK>
+0x3D37	0x5FB8	# <CJK>
+0x3D38	0x5FC4	# <CJK>
+0x3D39	0x5FC7	# <CJK>
+0x3D3A	0x5FC8	# <CJK>
+0x3D3B	0x5FC9	# <CJK>
+0x3D3C	0x5FCB	# <CJK>
+0x3D3D	0x5FD0	# <CJK>
+0x3D3E	0x5FD1	# <CJK>
+0x3D3F	0x5FD2	# <CJK>
+0x3D40	0x5FD3	# <CJK>
+0x3D41	0x5FD4	# <CJK>
+0x3D42	0x5FDE	# <CJK>
+0x3D43	0x5FE1	# <CJK>
+0x3D44	0x5FE2	# <CJK>
+0x3D45	0x5FE8	# <CJK>
+0x3D46	0x5FE9	# <CJK>
+0x3D47	0x5FEA	# <CJK>
+0x3D48	0x5FEC	# <CJK>
+0x3D49	0x5FED	# <CJK>
+0x3D4A	0x5FEE	# <CJK>
+0x3D4B	0x5FEF	# <CJK>
+0x3D4C	0x5FF2	# <CJK>
+0x3D4D	0x5FF3	# <CJK>
+0x3D4E	0x5FF6	# <CJK>
+0x3D4F	0x5FFA	# <CJK>
+0x3D50	0x5FFC	# <CJK>
+0x3D51	0x6007	# <CJK>
+0x3D52	0x600A	# <CJK>
+0x3D53	0x600D	# <CJK>
+0x3D54	0x6013	# <CJK>
+0x3D55	0x6014	# <CJK>
+0x3D56	0x6017	# <CJK>
+0x3D57	0x6018	# <CJK>
+0x3D58	0x601A	# <CJK>
+0x3D59	0x601F	# <CJK>
+0x3D5A	0x6024	# <CJK>
+0x3D5B	0x602D	# <CJK>
+0x3D5C	0x6033	# <CJK>
+0x3D5D	0x6035	# <CJK>
+0x3D5E	0x6040	# <CJK>
+0x3D5F	0x6047	# <CJK>
+0x3D60	0x6048	# <CJK>
+0x3D61	0x6049	# <CJK>
+0x3D62	0x604C	# <CJK>
+0x3D63	0x6051	# <CJK>
+0x3D64	0x6054	# <CJK>
+0x3D65	0x6056	# <CJK>
+0x3D66	0x6057	# <CJK>
+0x3D67	0x605D	# <CJK>
+0x3D68	0x6061	# <CJK>
+0x3D69	0x6067	# <CJK>
+0x3D6A	0x6071	# <CJK>
+0x3D6B	0x607E	# <CJK>
+0x3D6C	0x607F	# <CJK>
+0x3D6D	0x6082	# <CJK>
+0x3D6E	0x6086	# <CJK>
+0x3D6F	0x6088	# <CJK>
+0x3D70	0x608A	# <CJK>
+0x3D71	0x608E	# <CJK>
+0x3D72	0x6091	# <CJK>
+0x3D73	0x6093	# <CJK>
+0x3D74	0x6095	# <CJK>
+0x3D75	0x6098	# <CJK>
+0x3D76	0x609D	# <CJK>
+0x3D77	0x609E	# <CJK>
+0x3D78	0x60A2	# <CJK>
+0x3D79	0x60A4	# <CJK>
+0x3D7A	0x60A5	# <CJK>
+0x3D7B	0x60A8	# <CJK>
+0x3D7C	0x60B0	# <CJK>
+0x3D7D	0x60B1	# <CJK>
+0x3D7E	0x60B7	# <CJK>
+0x3E21	0x60BB	# <CJK>
+0x3E22	0x60BE	# <CJK>
+0x3E23	0x60C2	# <CJK>
+0x3E24	0x60C4	# <CJK>
+0x3E25	0x60C8	# <CJK>
+0x3E26	0x60C9	# <CJK>
+0x3E27	0x60CA	# <CJK>
+0x3E28	0x60CB	# <CJK>
+0x3E29	0x60CE	# <CJK>
+0x3E2A	0x60CF	# <CJK>
+0x3E2B	0x60D4	# <CJK>
+0x3E2C	0x60D5	# <CJK>
+0x3E2D	0x60D9	# <CJK>
+0x3E2E	0x60DB	# <CJK>
+0x3E2F	0x60DD	# <CJK>
+0x3E30	0x60DE	# <CJK>
+0x3E31	0x60E2	# <CJK>
+0x3E32	0x60E5	# <CJK>
+0x3E33	0x60F2	# <CJK>
+0x3E34	0x60F5	# <CJK>
+0x3E35	0x60F8	# <CJK>
+0x3E36	0x60FC	# <CJK>
+0x3E37	0x60FD	# <CJK>
+0x3E38	0x6102	# <CJK>
+0x3E39	0x6107	# <CJK>
+0x3E3A	0x610A	# <CJK>
+0x3E3B	0x610C	# <CJK>
+0x3E3C	0x6110	# <CJK>
+0x3E3D	0x6111	# <CJK>
+0x3E3E	0x6112	# <CJK>
+0x3E3F	0x6113	# <CJK>
+0x3E40	0x6114	# <CJK>
+0x3E41	0x6116	# <CJK>
+0x3E42	0x6117	# <CJK>
+0x3E43	0x6119	# <CJK>
+0x3E44	0x611C	# <CJK>
+0x3E45	0x611E	# <CJK>
+0x3E46	0x6122	# <CJK>
+0x3E47	0x612A	# <CJK>
+0x3E48	0x612B	# <CJK>
+0x3E49	0x6130	# <CJK>
+0x3E4A	0x6131	# <CJK>
+0x3E4B	0x6135	# <CJK>
+0x3E4C	0x6136	# <CJK>
+0x3E4D	0x6137	# <CJK>
+0x3E4E	0x6139	# <CJK>
+0x3E4F	0x6141	# <CJK>
+0x3E50	0x6145	# <CJK>
+0x3E51	0x6146	# <CJK>
+0x3E52	0x6149	# <CJK>
+0x3E53	0x615E	# <CJK>
+0x3E54	0x6160	# <CJK>
+0x3E55	0x616C	# <CJK>
+0x3E56	0x6172	# <CJK>
+0x3E57	0x6178	# <CJK>
+0x3E58	0x617B	# <CJK>
+0x3E59	0x617C	# <CJK>
+0x3E5A	0x617F	# <CJK>
+0x3E5B	0x6180	# <CJK>
+0x3E5C	0x6181	# <CJK>
+0x3E5D	0x6183	# <CJK>
+0x3E5E	0x6184	# <CJK>
+0x3E5F	0x618B	# <CJK>
+0x3E60	0x618D	# <CJK>
+0x3E61	0x6192	# <CJK>
+0x3E62	0x6193	# <CJK>
+0x3E63	0x6197	# <CJK>
+0x3E64	0x6198	# <CJK>
+0x3E65	0x619C	# <CJK>
+0x3E66	0x619D	# <CJK>
+0x3E67	0x619F	# <CJK>
+0x3E68	0x61A0	# <CJK>
+0x3E69	0x61A5	# <CJK>
+0x3E6A	0x61A8	# <CJK>
+0x3E6B	0x61AA	# <CJK>
+0x3E6C	0x61AD	# <CJK>
+0x3E6D	0x61B8	# <CJK>
+0x3E6E	0x61B9	# <CJK>
+0x3E6F	0x61BC	# <CJK>
+0x3E70	0x61C0	# <CJK>
+0x3E71	0x61C1	# <CJK>
+0x3E72	0x61C2	# <CJK>
+0x3E73	0x61CE	# <CJK>
+0x3E74	0x61CF	# <CJK>
+0x3E75	0x61D5	# <CJK>
+0x3E76	0x61DC	# <CJK>
+0x3E77	0x61DD	# <CJK>
+0x3E78	0x61DE	# <CJK>
+0x3E79	0x61DF	# <CJK>
+0x3E7A	0x61E1	# <CJK>
+0x3E7B	0x61E2	# <CJK>
+0x3E7C	0x61E7	# <CJK>
+0x3E7D	0x61E9	# <CJK>
+0x3E7E	0x61E5	# <CJK>
+0x3F21	0x61EC	# <CJK>
+0x3F22	0x61ED	# <CJK>
+0x3F23	0x61EF	# <CJK>
+0x3F24	0x6201	# <CJK>
+0x3F25	0x6203	# <CJK>
+0x3F26	0x6204	# <CJK>
+0x3F27	0x6207	# <CJK>
+0x3F28	0x6213	# <CJK>
+0x3F29	0x6215	# <CJK>
+0x3F2A	0x621C	# <CJK>
+0x3F2B	0x6220	# <CJK>
+0x3F2C	0x6222	# <CJK>
+0x3F2D	0x6223	# <CJK>
+0x3F2E	0x6227	# <CJK>
+0x3F2F	0x6229	# <CJK>
+0x3F30	0x622B	# <CJK>
+0x3F31	0x6239	# <CJK>
+0x3F32	0x623D	# <CJK>
+0x3F33	0x6242	# <CJK>
+0x3F34	0x6243	# <CJK>
+0x3F35	0x6244	# <CJK>
+0x3F36	0x6246	# <CJK>
+0x3F37	0x624C	# <CJK>
+0x3F38	0x6250	# <CJK>
+0x3F39	0x6251	# <CJK>
+0x3F3A	0x6252	# <CJK>
+0x3F3B	0x6254	# <CJK>
+0x3F3C	0x6256	# <CJK>
+0x3F3D	0x625A	# <CJK>
+0x3F3E	0x625C	# <CJK>
+0x3F3F	0x6264	# <CJK>
+0x3F40	0x626D	# <CJK>
+0x3F41	0x626F	# <CJK>
+0x3F42	0x6273	# <CJK>
+0x3F43	0x627A	# <CJK>
+0x3F44	0x627D	# <CJK>
+0x3F45	0x628D	# <CJK>
+0x3F46	0x628E	# <CJK>
+0x3F47	0x628F	# <CJK>
+0x3F48	0x6290	# <CJK>
+0x3F49	0x62A6	# <CJK>
+0x3F4A	0x62A8	# <CJK>
+0x3F4B	0x62B3	# <CJK>
+0x3F4C	0x62B6	# <CJK>
+0x3F4D	0x62B7	# <CJK>
+0x3F4E	0x62BA	# <CJK>
+0x3F4F	0x62BE	# <CJK>
+0x3F50	0x62BF	# <CJK>
+0x3F51	0x62C4	# <CJK>
+0x3F52	0x62CE	# <CJK>
+0x3F53	0x62D5	# <CJK>
+0x3F54	0x62D6	# <CJK>
+0x3F55	0x62DA	# <CJK>
+0x3F56	0x62EA	# <CJK>
+0x3F57	0x62F2	# <CJK>
+0x3F58	0x62F4	# <CJK>
+0x3F59	0x62FC	# <CJK>
+0x3F5A	0x62FD	# <CJK>
+0x3F5B	0x6303	# <CJK>
+0x3F5C	0x6304	# <CJK>
+0x3F5D	0x630A	# <CJK>
+0x3F5E	0x630B	# <CJK>
+0x3F5F	0x630D	# <CJK>
+0x3F60	0x6310	# <CJK>
+0x3F61	0x6313	# <CJK>
+0x3F62	0x6316	# <CJK>
+0x3F63	0x6318	# <CJK>
+0x3F64	0x6329	# <CJK>
+0x3F65	0x632A	# <CJK>
+0x3F66	0x632D	# <CJK>
+0x3F67	0x6335	# <CJK>
+0x3F68	0x6336	# <CJK>
+0x3F69	0x6339	# <CJK>
+0x3F6A	0x633C	# <CJK>
+0x3F6B	0x6341	# <CJK>
+0x3F6C	0x6342	# <CJK>
+0x3F6D	0x6343	# <CJK>
+0x3F6E	0x6344	# <CJK>
+0x3F6F	0x6346	# <CJK>
+0x3F70	0x634A	# <CJK>
+0x3F71	0x634B	# <CJK>
+0x3F72	0x634E	# <CJK>
+0x3F73	0x6352	# <CJK>
+0x3F74	0x6353	# <CJK>
+0x3F75	0x6354	# <CJK>
+0x3F76	0x6358	# <CJK>
+0x3F77	0x635B	# <CJK>
+0x3F78	0x6365	# <CJK>
+0x3F79	0x6366	# <CJK>
+0x3F7A	0x636C	# <CJK>
+0x3F7B	0x636D	# <CJK>
+0x3F7C	0x6371	# <CJK>
+0x3F7D	0x6374	# <CJK>
+0x3F7E	0x6375	# <CJK>
+0x4021	0x6378	# <CJK>
+0x4022	0x637C	# <CJK>
+0x4023	0x637D	# <CJK>
+0x4024	0x637F	# <CJK>
+0x4025	0x6382	# <CJK>
+0x4026	0x6384	# <CJK>
+0x4027	0x6387	# <CJK>
+0x4028	0x638A	# <CJK>
+0x4029	0x6390	# <CJK>
+0x402A	0x6394	# <CJK>
+0x402B	0x6395	# <CJK>
+0x402C	0x6399	# <CJK>
+0x402D	0x639A	# <CJK>
+0x402E	0x639E	# <CJK>
+0x402F	0x63A4	# <CJK>
+0x4030	0x63A6	# <CJK>
+0x4031	0x63AD	# <CJK>
+0x4032	0x63AE	# <CJK>
+0x4033	0x63AF	# <CJK>
+0x4034	0x63BD	# <CJK>
+0x4035	0x63C1	# <CJK>
+0x4036	0x63C5	# <CJK>
+0x4037	0x63C8	# <CJK>
+0x4038	0x63CE	# <CJK>
+0x4039	0x63D1	# <CJK>
+0x403A	0x63D3	# <CJK>
+0x403B	0x63D4	# <CJK>
+0x403C	0x63D5	# <CJK>
+0x403D	0x63DC	# <CJK>
+0x403E	0x63E0	# <CJK>
+0x403F	0x63E5	# <CJK>
+0x4040	0x63EA	# <CJK>
+0x4041	0x63EC	# <CJK>
+0x4042	0x63F2	# <CJK>
+0x4043	0x63F3	# <CJK>
+0x4044	0x63F5	# <CJK>
+0x4045	0x63F8	# <CJK>
+0x4046	0x63F9	# <CJK>
+0x4047	0x6409	# <CJK>
+0x4048	0x640A	# <CJK>
+0x4049	0x6410	# <CJK>
+0x404A	0x6412	# <CJK>
+0x404B	0x6414	# <CJK>
+0x404C	0x6418	# <CJK>
+0x404D	0x641E	# <CJK>
+0x404E	0x6420	# <CJK>
+0x404F	0x6422	# <CJK>
+0x4050	0x6424	# <CJK>
+0x4051	0x6425	# <CJK>
+0x4052	0x6429	# <CJK>
+0x4053	0x642A	# <CJK>
+0x4054	0x642F	# <CJK>
+0x4055	0x6430	# <CJK>
+0x4056	0x6435	# <CJK>
+0x4057	0x643D	# <CJK>
+0x4058	0x643F	# <CJK>
+0x4059	0x644B	# <CJK>
+0x405A	0x644F	# <CJK>
+0x405B	0x6451	# <CJK>
+0x405C	0x6452	# <CJK>
+0x405D	0x6453	# <CJK>
+0x405E	0x6454	# <CJK>
+0x405F	0x645A	# <CJK>
+0x4060	0x645B	# <CJK>
+0x4061	0x645C	# <CJK>
+0x4062	0x645D	# <CJK>
+0x4063	0x645F	# <CJK>
+0x4064	0x6460	# <CJK>
+0x4065	0x6461	# <CJK>
+0x4066	0x6463	# <CJK>
+0x4067	0x646D	# <CJK>
+0x4068	0x6473	# <CJK>
+0x4069	0x6474	# <CJK>
+0x406A	0x647B	# <CJK>
+0x406B	0x647D	# <CJK>
+0x406C	0x6485	# <CJK>
+0x406D	0x6487	# <CJK>
+0x406E	0x648F	# <CJK>
+0x406F	0x6490	# <CJK>
+0x4070	0x6491	# <CJK>
+0x4071	0x6498	# <CJK>
+0x4072	0x6499	# <CJK>
+0x4073	0x649B	# <CJK>
+0x4074	0x649D	# <CJK>
+0x4075	0x649F	# <CJK>
+0x4076	0x64A1	# <CJK>
+0x4077	0x64A3	# <CJK>
+0x4078	0x64A6	# <CJK>
+0x4079	0x64A8	# <CJK>
+0x407A	0x64AC	# <CJK>
+0x407B	0x64B3	# <CJK>
+0x407C	0x64BD	# <CJK>
+0x407D	0x64BE	# <CJK>
+0x407E	0x64BF	# <CJK>
+0x4121	0x64C4	# <CJK>
+0x4122	0x64C9	# <CJK>
+0x4123	0x64CA	# <CJK>
+0x4124	0x64CB	# <CJK>
+0x4125	0x64CC	# <CJK>
+0x4126	0x64CE	# <CJK>
+0x4127	0x64D0	# <CJK>
+0x4128	0x64D1	# <CJK>
+0x4129	0x64D5	# <CJK>
+0x412A	0x64D7	# <CJK>
+0x412B	0x64E4	# <CJK>
+0x412C	0x64E5	# <CJK>
+0x412D	0x64E9	# <CJK>
+0x412E	0x64EA	# <CJK>
+0x412F	0x64ED	# <CJK>
+0x4130	0x64F0	# <CJK>
+0x4131	0x64F5	# <CJK>
+0x4132	0x64F7	# <CJK>
+0x4133	0x64FB	# <CJK>
+0x4134	0x64FF	# <CJK>
+0x4135	0x6501	# <CJK>
+0x4136	0x6504	# <CJK>
+0x4137	0x6508	# <CJK>
+0x4138	0x6509	# <CJK>
+0x4139	0x650A	# <CJK>
+0x413A	0x650F	# <CJK>
+0x413B	0x6513	# <CJK>
+0x413C	0x6514	# <CJK>
+0x413D	0x6516	# <CJK>
+0x413E	0x6519	# <CJK>
+0x413F	0x651B	# <CJK>
+0x4140	0x651E	# <CJK>
+0x4141	0x651F	# <CJK>
+0x4142	0x6522	# <CJK>
+0x4143	0x6526	# <CJK>
+0x4144	0x6529	# <CJK>
+0x4145	0x652E	# <CJK>
+0x4146	0x6531	# <CJK>
+0x4147	0x653A	# <CJK>
+0x4148	0x653C	# <CJK>
+0x4149	0x653D	# <CJK>
+0x414A	0x6543	# <CJK>
+0x414B	0x6547	# <CJK>
+0x414C	0x6549	# <CJK>
+0x414D	0x6550	# <CJK>
+0x414E	0x6552	# <CJK>
+0x414F	0x6554	# <CJK>
+0x4150	0x655F	# <CJK>
+0x4151	0x6560	# <CJK>
+0x4152	0x6567	# <CJK>
+0x4153	0x656B	# <CJK>
+0x4154	0x657A	# <CJK>
+0x4155	0x657D	# <CJK>
+0x4156	0x6581	# <CJK>
+0x4157	0x6585	# <CJK>
+0x4158	0x658A	# <CJK>
+0x4159	0x6592	# <CJK>
+0x415A	0x6595	# <CJK>
+0x415B	0x6598	# <CJK>
+0x415C	0x659D	# <CJK>
+0x415D	0x65A0	# <CJK>
+0x415E	0x65A3	# <CJK>
+0x415F	0x65A6	# <CJK>
+0x4160	0x65AE	# <CJK>
+0x4161	0x65B2	# <CJK>
+0x4162	0x65B3	# <CJK>
+0x4163	0x65B4	# <CJK>
+0x4164	0x65BF	# <CJK>
+0x4165	0x65C2	# <CJK>
+0x4166	0x65C8	# <CJK>
+0x4167	0x65C9	# <CJK>
+0x4168	0x65CE	# <CJK>
+0x4169	0x65D0	# <CJK>
+0x416A	0x65D4	# <CJK>
+0x416B	0x65D6	# <CJK>
+0x416C	0x65D8	# <CJK>
+0x416D	0x65DF	# <CJK>
+0x416E	0x65F0	# <CJK>
+0x416F	0x65F2	# <CJK>
+0x4170	0x65F4	# <CJK>
+0x4171	0x65F5	# <CJK>
+0x4172	0x65F9	# <CJK>
+0x4173	0x65FE	# <CJK>
+0x4174	0x65FF	# <CJK>
+0x4175	0x6600	# <CJK>
+0x4176	0x6604	# <CJK>
+0x4177	0x6608	# <CJK>
+0x4178	0x6609	# <CJK>
+0x4179	0x660D	# <CJK>
+0x417A	0x6611	# <CJK>
+0x417B	0x6612	# <CJK>
+0x417C	0x6615	# <CJK>
+0x417D	0x6616	# <CJK>
+0x417E	0x661D	# <CJK>
+0x4221	0x661E	# <CJK>
+0x4222	0x6621	# <CJK>
+0x4223	0x6622	# <CJK>
+0x4224	0x6623	# <CJK>
+0x4225	0x6624	# <CJK>
+0x4226	0x6626	# <CJK>
+0x4227	0x6629	# <CJK>
+0x4228	0x662A	# <CJK>
+0x4229	0x662B	# <CJK>
+0x422A	0x662C	# <CJK>
+0x422B	0x662E	# <CJK>
+0x422C	0x6630	# <CJK>
+0x422D	0x6631	# <CJK>
+0x422E	0x6633	# <CJK>
+0x422F	0x6639	# <CJK>
+0x4230	0x6637	# <CJK>
+0x4231	0x6640	# <CJK>
+0x4232	0x6645	# <CJK>
+0x4233	0x6646	# <CJK>
+0x4234	0x664A	# <CJK>
+0x4235	0x664C	# <CJK>
+0x4236	0x6651	# <CJK>
+0x4237	0x664E	# <CJK>
+0x4238	0x6657	# <CJK>
+0x4239	0x6658	# <CJK>
+0x423A	0x6659	# <CJK>
+0x423B	0x665B	# <CJK>
+0x423C	0x665C	# <CJK>
+0x423D	0x6660	# <CJK>
+0x423E	0x6661	# <CJK>
+0x423F	0x66FB	# <CJK>
+0x4240	0x666A	# <CJK>
+0x4241	0x666B	# <CJK>
+0x4242	0x666C	# <CJK>
+0x4243	0x667E	# <CJK>
+0x4244	0x6673	# <CJK>
+0x4245	0x6675	# <CJK>
+0x4246	0x667F	# <CJK>
+0x4247	0x6677	# <CJK>
+0x4248	0x6678	# <CJK>
+0x4249	0x6679	# <CJK>
+0x424A	0x667B	# <CJK>
+0x424B	0x6680	# <CJK>
+0x424C	0x667C	# <CJK>
+0x424D	0x668B	# <CJK>
+0x424E	0x668C	# <CJK>
+0x424F	0x668D	# <CJK>
+0x4250	0x6690	# <CJK>
+0x4251	0x6692	# <CJK>
+0x4252	0x6699	# <CJK>
+0x4253	0x669A	# <CJK>
+0x4254	0x669B	# <CJK>
+0x4255	0x669C	# <CJK>
+0x4256	0x669F	# <CJK>
+0x4257	0x66A0	# <CJK>
+0x4258	0x66A4	# <CJK>
+0x4259	0x66AD	# <CJK>
+0x425A	0x66B1	# <CJK>
+0x425B	0x66B2	# <CJK>
+0x425C	0x66B5	# <CJK>
+0x425D	0x66BB	# <CJK>
+0x425E	0x66BF	# <CJK>
+0x425F	0x66C0	# <CJK>
+0x4260	0x66C2	# <CJK>
+0x4261	0x66C3	# <CJK>
+0x4262	0x66C8	# <CJK>
+0x4263	0x66CC	# <CJK>
+0x4264	0x66CE	# <CJK>
+0x4265	0x66CF	# <CJK>
+0x4266	0x66D4	# <CJK>
+0x4267	0x66DB	# <CJK>
+0x4268	0x66DF	# <CJK>
+0x4269	0x66E8	# <CJK>
+0x426A	0x66EB	# <CJK>
+0x426B	0x66EC	# <CJK>
+0x426C	0x66EE	# <CJK>
+0x426D	0x66FA	# <CJK>
+0x426E	0x6705	# <CJK>
+0x426F	0x6707	# <CJK>
+0x4270	0x670E	# <CJK>
+0x4271	0x6713	# <CJK>
+0x4272	0x6719	# <CJK>
+0x4273	0x671C	# <CJK>
+0x4274	0x6720	# <CJK>
+0x4275	0x6722	# <CJK>
+0x4276	0x6733	# <CJK>
+0x4277	0x673E	# <CJK>
+0x4278	0x6745	# <CJK>
+0x4279	0x6747	# <CJK>
+0x427A	0x6748	# <CJK>
+0x427B	0x674C	# <CJK>
+0x427C	0x6754	# <CJK>
+0x427D	0x6755	# <CJK>
+0x427E	0x675D	# <CJK>
+0x4321	0x6766	# <CJK>
+0x4322	0x676C	# <CJK>
+0x4323	0x676E	# <CJK>
+0x4324	0x6774	# <CJK>
+0x4325	0x6776	# <CJK>
+0x4326	0x677B	# <CJK>
+0x4327	0x6781	# <CJK>
+0x4328	0x6784	# <CJK>
+0x4329	0x678E	# <CJK>
+0x432A	0x678F	# <CJK>
+0x432B	0x6791	# <CJK>
+0x432C	0x6793	# <CJK>
+0x432D	0x6796	# <CJK>
+0x432E	0x6798	# <CJK>
+0x432F	0x6799	# <CJK>
+0x4330	0x679B	# <CJK>
+0x4331	0x67B0	# <CJK>
+0x4332	0x67B1	# <CJK>
+0x4333	0x67B2	# <CJK>
+0x4334	0x67B5	# <CJK>
+0x4335	0x67BB	# <CJK>
+0x4336	0x67BC	# <CJK>
+0x4337	0x67BD	# <CJK>
+0x4338	0x67F9	# <CJK>
+0x4339	0x67C0	# <CJK>
+0x433A	0x67C2	# <CJK>
+0x433B	0x67C3	# <CJK>
+0x433C	0x67C5	# <CJK>
+0x433D	0x67C8	# <CJK>
+0x433E	0x67C9	# <CJK>
+0x433F	0x67D2	# <CJK>
+0x4340	0x67D7	# <CJK>
+0x4341	0x67D9	# <CJK>
+0x4342	0x67DC	# <CJK>
+0x4343	0x67E1	# <CJK>
+0x4344	0x67E6	# <CJK>
+0x4345	0x67F0	# <CJK>
+0x4346	0x67F2	# <CJK>
+0x4347	0x67F6	# <CJK>
+0x4348	0x67F7	# <CJK>
+0x4349	0x6852	# <CJK>
+0x434A	0x6814	# <CJK>
+0x434B	0x6819	# <CJK>
+0x434C	0x681D	# <CJK>
+0x434D	0x681F	# <CJK>
+0x434E	0x6828	# <CJK>
+0x434F	0x6827	# <CJK>
+0x4350	0x682C	# <CJK>
+0x4351	0x682D	# <CJK>
+0x4352	0x682F	# <CJK>
+0x4353	0x6830	# <CJK>
+0x4354	0x6831	# <CJK>
+0x4355	0x6833	# <CJK>
+0x4356	0x683B	# <CJK>
+0x4357	0x683F	# <CJK>
+0x4358	0x6844	# <CJK>
+0x4359	0x6845	# <CJK>
+0x435A	0x684A	# <CJK>
+0x435B	0x684C	# <CJK>
+0x435C	0x6855	# <CJK>
+0x435D	0x6857	# <CJK>
+0x435E	0x6858	# <CJK>
+0x435F	0x685B	# <CJK>
+0x4360	0x686B	# <CJK>
+0x4361	0x686E	# <CJK>
+0x4362	0x686F	# <CJK>
+0x4363	0x6870	# <CJK>
+0x4364	0x6871	# <CJK>
+0x4365	0x6872	# <CJK>
+0x4366	0x6875	# <CJK>
+0x4367	0x6879	# <CJK>
+0x4368	0x687A	# <CJK>
+0x4369	0x687B	# <CJK>
+0x436A	0x687C	# <CJK>
+0x436B	0x6882	# <CJK>
+0x436C	0x6884	# <CJK>
+0x436D	0x6886	# <CJK>
+0x436E	0x6888	# <CJK>
+0x436F	0x6896	# <CJK>
+0x4370	0x6898	# <CJK>
+0x4371	0x689A	# <CJK>
+0x4372	0x689C	# <CJK>
+0x4373	0x68A1	# <CJK>
+0x4374	0x68A3	# <CJK>
+0x4375	0x68A5	# <CJK>
+0x4376	0x68A9	# <CJK>
+0x4377	0x68AA	# <CJK>
+0x4378	0x68AE	# <CJK>
+0x4379	0x68B2	# <CJK>
+0x437A	0x68BB	# <CJK>
+0x437B	0x68C5	# <CJK>
+0x437C	0x68C8	# <CJK>
+0x437D	0x68CC	# <CJK>
+0x437E	0x68CF	# <CJK>
+0x4421	0x68D0	# <CJK>
+0x4422	0x68D1	# <CJK>
+0x4423	0x68D3	# <CJK>
+0x4424	0x68D6	# <CJK>
+0x4425	0x68D9	# <CJK>
+0x4426	0x68DC	# <CJK>
+0x4427	0x68DD	# <CJK>
+0x4428	0x68E5	# <CJK>
+0x4429	0x68E8	# <CJK>
+0x442A	0x68EA	# <CJK>
+0x442B	0x68EB	# <CJK>
+0x442C	0x68EC	# <CJK>
+0x442D	0x68ED	# <CJK>
+0x442E	0x68F0	# <CJK>
+0x442F	0x68F1	# <CJK>
+0x4430	0x68F5	# <CJK>
+0x4431	0x68F6	# <CJK>
+0x4432	0x68FB	# <CJK>
+0x4433	0x68FC	# <CJK>
+0x4434	0x68FD	# <CJK>
+0x4435	0x6906	# <CJK>
+0x4436	0x6909	# <CJK>
+0x4437	0x690A	# <CJK>
+0x4438	0x6910	# <CJK>
+0x4439	0x6911	# <CJK>
+0x443A	0x6913	# <CJK>
+0x443B	0x6916	# <CJK>
+0x443C	0x6917	# <CJK>
+0x443D	0x6931	# <CJK>
+0x443E	0x6933	# <CJK>
+0x443F	0x6935	# <CJK>
+0x4440	0x6938	# <CJK>
+0x4441	0x693B	# <CJK>
+0x4442	0x6942	# <CJK>
+0x4443	0x6945	# <CJK>
+0x4444	0x6949	# <CJK>
+0x4445	0x694E	# <CJK>
+0x4446	0x6957	# <CJK>
+0x4447	0x695B	# <CJK>
+0x4448	0x6963	# <CJK>
+0x4449	0x6964	# <CJK>
+0x444A	0x6965	# <CJK>
+0x444B	0x6966	# <CJK>
+0x444C	0x6968	# <CJK>
+0x444D	0x6969	# <CJK>
+0x444E	0x696C	# <CJK>
+0x444F	0x6970	# <CJK>
+0x4450	0x6971	# <CJK>
+0x4451	0x6972	# <CJK>
+0x4452	0x697A	# <CJK>
+0x4453	0x697B	# <CJK>
+0x4454	0x697F	# <CJK>
+0x4455	0x6980	# <CJK>
+0x4456	0x698D	# <CJK>
+0x4457	0x6992	# <CJK>
+0x4458	0x6996	# <CJK>
+0x4459	0x6998	# <CJK>
+0x445A	0x69A1	# <CJK>
+0x445B	0x69A5	# <CJK>
+0x445C	0x69A6	# <CJK>
+0x445D	0x69A8	# <CJK>
+0x445E	0x69AB	# <CJK>
+0x445F	0x69AD	# <CJK>
+0x4460	0x69AF	# <CJK>
+0x4461	0x69B7	# <CJK>
+0x4462	0x69B8	# <CJK>
+0x4463	0x69BA	# <CJK>
+0x4464	0x69BC	# <CJK>
+0x4465	0x69C5	# <CJK>
+0x4466	0x69C8	# <CJK>
+0x4467	0x69D1	# <CJK>
+0x4468	0x69D6	# <CJK>
+0x4469	0x69D7	# <CJK>
+0x446A	0x69E2	# <CJK>
+0x446B	0x69E5	# <CJK>
+0x446C	0x69EE	# <CJK>
+0x446D	0x69EF	# <CJK>
+0x446E	0x69F1	# <CJK>
+0x446F	0x69F3	# <CJK>
+0x4470	0x69F5	# <CJK>
+0x4471	0x69FE	# <CJK>
+0x4472	0x6A00	# <CJK>
+0x4473	0x6A01	# <CJK>
+0x4474	0x6A03	# <CJK>
+0x4475	0x6A0F	# <CJK>
+0x4476	0x6A11	# <CJK>
+0x4477	0x6A15	# <CJK>
+0x4478	0x6A1A	# <CJK>
+0x4479	0x6A1D	# <CJK>
+0x447A	0x6A20	# <CJK>
+0x447B	0x6A24	# <CJK>
+0x447C	0x6A28	# <CJK>
+0x447D	0x6A30	# <CJK>
+0x447E	0x6A32	# <CJK>
+0x4521	0x6A34	# <CJK>
+0x4522	0x6A37	# <CJK>
+0x4523	0x6A3B	# <CJK>
+0x4524	0x6A3E	# <CJK>
+0x4525	0x6A3F	# <CJK>
+0x4526	0x6A45	# <CJK>
+0x4527	0x6A46	# <CJK>
+0x4528	0x6A49	# <CJK>
+0x4529	0x6A4A	# <CJK>
+0x452A	0x6A4E	# <CJK>
+0x452B	0x6A50	# <CJK>
+0x452C	0x6A51	# <CJK>
+0x452D	0x6A52	# <CJK>
+0x452E	0x6A55	# <CJK>
+0x452F	0x6A56	# <CJK>
+0x4530	0x6A5B	# <CJK>
+0x4531	0x6A64	# <CJK>
+0x4532	0x6A67	# <CJK>
+0x4533	0x6A6A	# <CJK>
+0x4534	0x6A71	# <CJK>
+0x4535	0x6A73	# <CJK>
+0x4536	0x6A7E	# <CJK>
+0x4537	0x6A81	# <CJK>
+0x4538	0x6A83	# <CJK>
+0x4539	0x6A86	# <CJK>
+0x453A	0x6A87	# <CJK>
+0x453B	0x6A89	# <CJK>
+0x453C	0x6A8B	# <CJK>
+0x453D	0x6A91	# <CJK>
+0x453E	0x6A9B	# <CJK>
+0x453F	0x6A9D	# <CJK>
+0x4540	0x6A9E	# <CJK>
+0x4541	0x6A9F	# <CJK>
+0x4542	0x6AA5	# <CJK>
+0x4543	0x6AAB	# <CJK>
+0x4544	0x6AAF	# <CJK>
+0x4545	0x6AB0	# <CJK>
+0x4546	0x6AB1	# <CJK>
+0x4547	0x6AB4	# <CJK>
+0x4548	0x6ABD	# <CJK>
+0x4549	0x6ABE	# <CJK>
+0x454A	0x6ABF	# <CJK>
+0x454B	0x6AC6	# <CJK>
+0x454C	0x6AC9	# <CJK>
+0x454D	0x6AC8	# <CJK>
+0x454E	0x6ACC	# <CJK>
+0x454F	0x6AD0	# <CJK>
+0x4550	0x6AD4	# <CJK>
+0x4551	0x6AD5	# <CJK>
+0x4552	0x6AD6	# <CJK>
+0x4553	0x6ADC	# <CJK>
+0x4554	0x6ADD	# <CJK>
+0x4555	0x6AE4	# <CJK>
+0x4556	0x6AE7	# <CJK>
+0x4557	0x6AEC	# <CJK>
+0x4558	0x6AF0	# <CJK>
+0x4559	0x6AF1	# <CJK>
+0x455A	0x6AF2	# <CJK>
+0x455B	0x6AFC	# <CJK>
+0x455C	0x6AFD	# <CJK>
+0x455D	0x6B02	# <CJK>
+0x455E	0x6B03	# <CJK>
+0x455F	0x6B06	# <CJK>
+0x4560	0x6B07	# <CJK>
+0x4561	0x6B09	# <CJK>
+0x4562	0x6B0F	# <CJK>
+0x4563	0x6B10	# <CJK>
+0x4564	0x6B11	# <CJK>
+0x4565	0x6B17	# <CJK>
+0x4566	0x6B1B	# <CJK>
+0x4567	0x6B1E	# <CJK>
+0x4568	0x6B24	# <CJK>
+0x4569	0x6B28	# <CJK>
+0x456A	0x6B2B	# <CJK>
+0x456B	0x6B2C	# <CJK>
+0x456C	0x6B2F	# <CJK>
+0x456D	0x6B35	# <CJK>
+0x456E	0x6B36	# <CJK>
+0x456F	0x6B3B	# <CJK>
+0x4570	0x6B3F	# <CJK>
+0x4571	0x6B46	# <CJK>
+0x4572	0x6B4A	# <CJK>
+0x4573	0x6B4D	# <CJK>
+0x4574	0x6B52	# <CJK>
+0x4575	0x6B56	# <CJK>
+0x4576	0x6B58	# <CJK>
+0x4577	0x6B5D	# <CJK>
+0x4578	0x6B60	# <CJK>
+0x4579	0x6B67	# <CJK>
+0x457A	0x6B6B	# <CJK>
+0x457B	0x6B6E	# <CJK>
+0x457C	0x6B70	# <CJK>
+0x457D	0x6B75	# <CJK>
+0x457E	0x6B7D	# <CJK>
+0x4621	0x6B7E	# <CJK>
+0x4622	0x6B82	# <CJK>
+0x4623	0x6B85	# <CJK>
+0x4624	0x6B97	# <CJK>
+0x4625	0x6B9B	# <CJK>
+0x4626	0x6B9F	# <CJK>
+0x4627	0x6BA0	# <CJK>
+0x4628	0x6BA2	# <CJK>
+0x4629	0x6BA3	# <CJK>
+0x462A	0x6BA8	# <CJK>
+0x462B	0x6BA9	# <CJK>
+0x462C	0x6BAC	# <CJK>
+0x462D	0x6BAD	# <CJK>
+0x462E	0x6BAE	# <CJK>
+0x462F	0x6BB0	# <CJK>
+0x4630	0x6BB8	# <CJK>
+0x4631	0x6BB9	# <CJK>
+0x4632	0x6BBD	# <CJK>
+0x4633	0x6BBE	# <CJK>
+0x4634	0x6BC3	# <CJK>
+0x4635	0x6BC4	# <CJK>
+0x4636	0x6BC9	# <CJK>
+0x4637	0x6BCC	# <CJK>
+0x4638	0x6BD6	# <CJK>
+0x4639	0x6BDA	# <CJK>
+0x463A	0x6BE1	# <CJK>
+0x463B	0x6BE3	# <CJK>
+0x463C	0x6BE6	# <CJK>
+0x463D	0x6BE7	# <CJK>
+0x463E	0x6BEE	# <CJK>
+0x463F	0x6BF1	# <CJK>
+0x4640	0x6BF7	# <CJK>
+0x4641	0x6BF9	# <CJK>
+0x4642	0x6BFF	# <CJK>
+0x4643	0x6C02	# <CJK>
+0x4644	0x6C04	# <CJK>
+0x4645	0x6C05	# <CJK>
+0x4646	0x6C09	# <CJK>
+0x4647	0x6C0D	# <CJK>
+0x4648	0x6C0E	# <CJK>
+0x4649	0x6C10	# <CJK>
+0x464A	0x6C12	# <CJK>
+0x464B	0x6C19	# <CJK>
+0x464C	0x6C1F	# <CJK>
+0x464D	0x6C26	# <CJK>
+0x464E	0x6C27	# <CJK>
+0x464F	0x6C28	# <CJK>
+0x4650	0x6C2C	# <CJK>
+0x4651	0x6C2E	# <CJK>
+0x4652	0x6C33	# <CJK>
+0x4653	0x6C35	# <CJK>
+0x4654	0x6C36	# <CJK>
+0x4655	0x6C3A	# <CJK>
+0x4656	0x6C3B	# <CJK>
+0x4657	0x6C3F	# <CJK>
+0x4658	0x6C4A	# <CJK>
+0x4659	0x6C4B	# <CJK>
+0x465A	0x6C4D	# <CJK>
+0x465B	0x6C4F	# <CJK>
+0x465C	0x6C52	# <CJK>
+0x465D	0x6C54	# <CJK>
+0x465E	0x6C59	# <CJK>
+0x465F	0x6C5B	# <CJK>
+0x4660	0x6C5C	# <CJK>
+0x4661	0x6C6B	# <CJK>
+0x4662	0x6C6D	# <CJK>
+0x4663	0x6C6F	# <CJK>
+0x4664	0x6C74	# <CJK>
+0x4665	0x6C76	# <CJK>
+0x4666	0x6C78	# <CJK>
+0x4667	0x6C79	# <CJK>
+0x4668	0x6C7B	# <CJK>
+0x4669	0x6C85	# <CJK>
+0x466A	0x6C86	# <CJK>
+0x466B	0x6C87	# <CJK>
+0x466C	0x6C89	# <CJK>
+0x466D	0x6C94	# <CJK>
+0x466E	0x6C95	# <CJK>
+0x466F	0x6C97	# <CJK>
+0x4670	0x6C98	# <CJK>
+0x4671	0x6C9C	# <CJK>
+0x4672	0x6C9F	# <CJK>
+0x4673	0x6CB0	# <CJK>
+0x4674	0x6CB2	# <CJK>
+0x4675	0x6CB4	# <CJK>
+0x4676	0x6CC2	# <CJK>
+0x4677	0x6CC6	# <CJK>
+0x4678	0x6CCD	# <CJK>
+0x4679	0x6CCF	# <CJK>
+0x467A	0x6CD0	# <CJK>
+0x467B	0x6CD1	# <CJK>
+0x467C	0x6CD2	# <CJK>
+0x467D	0x6CD4	# <CJK>
+0x467E	0x6CD6	# <CJK>
+0x4721	0x6CDA	# <CJK>
+0x4722	0x6CDC	# <CJK>
+0x4723	0x6CE0	# <CJK>
+0x4724	0x6CE7	# <CJK>
+0x4725	0x6CE9	# <CJK>
+0x4726	0x6CEB	# <CJK>
+0x4727	0x6CEC	# <CJK>
+0x4728	0x6CEE	# <CJK>
+0x4729	0x6CF2	# <CJK>
+0x472A	0x6CF4	# <CJK>
+0x472B	0x6D04	# <CJK>
+0x472C	0x6D07	# <CJK>
+0x472D	0x6D0A	# <CJK>
+0x472E	0x6D0E	# <CJK>
+0x472F	0x6D0F	# <CJK>
+0x4730	0x6D11	# <CJK>
+0x4731	0x6D13	# <CJK>
+0x4732	0x6D1A	# <CJK>
+0x4733	0x6D26	# <CJK>
+0x4734	0x6D27	# <CJK>
+0x4735	0x6D28	# <CJK>
+0x4736	0x6C67	# <CJK>
+0x4737	0x6D2E	# <CJK>
+0x4738	0x6D2F	# <CJK>
+0x4739	0x6D31	# <CJK>
+0x473A	0x6D39	# <CJK>
+0x473B	0x6D3C	# <CJK>
+0x473C	0x6D3F	# <CJK>
+0x473D	0x6D57	# <CJK>
+0x473E	0x6D5E	# <CJK>
+0x473F	0x6D5F	# <CJK>
+0x4740	0x6D61	# <CJK>
+0x4741	0x6D65	# <CJK>
+0x4742	0x6D67	# <CJK>
+0x4743	0x6D6F	# <CJK>
+0x4744	0x6D70	# <CJK>
+0x4745	0x6D7C	# <CJK>
+0x4746	0x6D82	# <CJK>
+0x4747	0x6D87	# <CJK>
+0x4748	0x6D91	# <CJK>
+0x4749	0x6D92	# <CJK>
+0x474A	0x6D94	# <CJK>
+0x474B	0x6D96	# <CJK>
+0x474C	0x6D97	# <CJK>
+0x474D	0x6D98	# <CJK>
+0x474E	0x6DAA	# <CJK>
+0x474F	0x6DAC	# <CJK>
+0x4750	0x6DB4	# <CJK>
+0x4751	0x6DB7	# <CJK>
+0x4752	0x6DB9	# <CJK>
+0x4753	0x6DBD	# <CJK>
+0x4754	0x6DBF	# <CJK>
+0x4755	0x6DC4	# <CJK>
+0x4756	0x6DC8	# <CJK>
+0x4757	0x6DCA	# <CJK>
+0x4758	0x6DCE	# <CJK>
+0x4759	0x6DCF	# <CJK>
+0x475A	0x6DD6	# <CJK>
+0x475B	0x6DDB	# <CJK>
+0x475C	0x6DDD	# <CJK>
+0x475D	0x6DDF	# <CJK>
+0x475E	0x6DE0	# <CJK>
+0x475F	0x6DE2	# <CJK>
+0x4760	0x6DE5	# <CJK>
+0x4761	0x6DE9	# <CJK>
+0x4762	0x6DEF	# <CJK>
+0x4763	0x6DF0	# <CJK>
+0x4764	0x6DF4	# <CJK>
+0x4765	0x6DF6	# <CJK>
+0x4766	0x6DFC	# <CJK>
+0x4767	0x6E00	# <CJK>
+0x4768	0x6E04	# <CJK>
+0x4769	0x6E1E	# <CJK>
+0x476A	0x6E22	# <CJK>
+0x476B	0x6E27	# <CJK>
+0x476C	0x6E32	# <CJK>
+0x476D	0x6E36	# <CJK>
+0x476E	0x6E39	# <CJK>
+0x476F	0x6E3B	# <CJK>
+0x4770	0x6E3C	# <CJK>
+0x4771	0x6E44	# <CJK>
+0x4772	0x6E45	# <CJK>
+0x4773	0x6E48	# <CJK>
+0x4774	0x6E49	# <CJK>
+0x4775	0x6E4B	# <CJK>
+0x4776	0x6E4F	# <CJK>
+0x4777	0x6E51	# <CJK>
+0x4778	0x6E52	# <CJK>
+0x4779	0x6E53	# <CJK>
+0x477A	0x6E54	# <CJK>
+0x477B	0x6E57	# <CJK>
+0x477C	0x6E5C	# <CJK>
+0x477D	0x6E5D	# <CJK>
+0x477E	0x6E5E	# <CJK>
+0x4821	0x6E62	# <CJK>
+0x4822	0x6E63	# <CJK>
+0x4823	0x6E68	# <CJK>
+0x4824	0x6E73	# <CJK>
+0x4825	0x6E7B	# <CJK>
+0x4826	0x6E7D	# <CJK>
+0x4827	0x6E8D	# <CJK>
+0x4828	0x6E93	# <CJK>
+0x4829	0x6E99	# <CJK>
+0x482A	0x6EA0	# <CJK>
+0x482B	0x6EA7	# <CJK>
+0x482C	0x6EAD	# <CJK>
+0x482D	0x6EAE	# <CJK>
+0x482E	0x6EB1	# <CJK>
+0x482F	0x6EB3	# <CJK>
+0x4830	0x6EBB	# <CJK>
+0x4831	0x6EBF	# <CJK>
+0x4832	0x6EC0	# <CJK>
+0x4833	0x6EC1	# <CJK>
+0x4834	0x6EC3	# <CJK>
+0x4835	0x6EC7	# <CJK>
+0x4836	0x6EC8	# <CJK>
+0x4837	0x6ECA	# <CJK>
+0x4838	0x6ECD	# <CJK>
+0x4839	0x6ECE	# <CJK>
+0x483A	0x6ECF	# <CJK>
+0x483B	0x6EEB	# <CJK>
+0x483C	0x6EED	# <CJK>
+0x483D	0x6EEE	# <CJK>
+0x483E	0x6EF9	# <CJK>
+0x483F	0x6EFB	# <CJK>
+0x4840	0x6EFD	# <CJK>
+0x4841	0x6F04	# <CJK>
+0x4842	0x6F08	# <CJK>
+0x4843	0x6F0A	# <CJK>
+0x4844	0x6F0C	# <CJK>
+0x4845	0x6F0D	# <CJK>
+0x4846	0x6F16	# <CJK>
+0x4847	0x6F18	# <CJK>
+0x4848	0x6F1A	# <CJK>
+0x4849	0x6F1B	# <CJK>
+0x484A	0x6F26	# <CJK>
+0x484B	0x6F29	# <CJK>
+0x484C	0x6F2A	# <CJK>
+0x484D	0x6F2F	# <CJK>
+0x484E	0x6F30	# <CJK>
+0x484F	0x6F33	# <CJK>
+0x4850	0x6F36	# <CJK>
+0x4851	0x6F3B	# <CJK>
+0x4852	0x6F3C	# <CJK>
+0x4853	0x6F2D	# <CJK>
+0x4854	0x6F4F	# <CJK>
+0x4855	0x6F51	# <CJK>
+0x4856	0x6F52	# <CJK>
+0x4857	0x6F53	# <CJK>
+0x4858	0x6F57	# <CJK>
+0x4859	0x6F59	# <CJK>
+0x485A	0x6F5A	# <CJK>
+0x485B	0x6F5D	# <CJK>
+0x485C	0x6F5E	# <CJK>
+0x485D	0x6F61	# <CJK>
+0x485E	0x6F62	# <CJK>
+0x485F	0x6F68	# <CJK>
+0x4860	0x6F6C	# <CJK>
+0x4861	0x6F7D	# <CJK>
+0x4862	0x6F7E	# <CJK>
+0x4863	0x6F83	# <CJK>
+0x4864	0x6F87	# <CJK>
+0x4865	0x6F88	# <CJK>
+0x4866	0x6F8B	# <CJK>
+0x4867	0x6F8C	# <CJK>
+0x4868	0x6F8D	# <CJK>
+0x4869	0x6F90	# <CJK>
+0x486A	0x6F92	# <CJK>
+0x486B	0x6F93	# <CJK>
+0x486C	0x6F94	# <CJK>
+0x486D	0x6F96	# <CJK>
+0x486E	0x6F9A	# <CJK>
+0x486F	0x6F9F	# <CJK>
+0x4870	0x6FA0	# <CJK>
+0x4871	0x6FA5	# <CJK>
+0x4872	0x6FA6	# <CJK>
+0x4873	0x6FA7	# <CJK>
+0x4874	0x6FA8	# <CJK>
+0x4875	0x6FAE	# <CJK>
+0x4876	0x6FAF	# <CJK>
+0x4877	0x6FB0	# <CJK>
+0x4878	0x6FB5	# <CJK>
+0x4879	0x6FB6	# <CJK>
+0x487A	0x6FBC	# <CJK>
+0x487B	0x6FC5	# <CJK>
+0x487C	0x6FC7	# <CJK>
+0x487D	0x6FC8	# <CJK>
+0x487E	0x6FCA	# <CJK>
+0x4921	0x6FDA	# <CJK>
+0x4922	0x6FDE	# <CJK>
+0x4923	0x6FE8	# <CJK>
+0x4924	0x6FE9	# <CJK>
+0x4925	0x6FF0	# <CJK>
+0x4926	0x6FF5	# <CJK>
+0x4927	0x6FF9	# <CJK>
+0x4928	0x6FFC	# <CJK>
+0x4929	0x6FFD	# <CJK>
+0x492A	0x7000	# <CJK>
+0x492B	0x7005	# <CJK>
+0x492C	0x7006	# <CJK>
+0x492D	0x7007	# <CJK>
+0x492E	0x700D	# <CJK>
+0x492F	0x7017	# <CJK>
+0x4930	0x7020	# <CJK>
+0x4931	0x7023	# <CJK>
+0x4932	0x702F	# <CJK>
+0x4933	0x7034	# <CJK>
+0x4934	0x7037	# <CJK>
+0x4935	0x7039	# <CJK>
+0x4936	0x703C	# <CJK>
+0x4937	0x7043	# <CJK>
+0x4938	0x7044	# <CJK>
+0x4939	0x7048	# <CJK>
+0x493A	0x7049	# <CJK>
+0x493B	0x704A	# <CJK>
+0x493C	0x704B	# <CJK>
+0x493D	0x7054	# <CJK>
+0x493E	0x7055	# <CJK>
+0x493F	0x705D	# <CJK>
+0x4940	0x705E	# <CJK>
+0x4941	0x704E	# <CJK>
+0x4942	0x7064	# <CJK>
+0x4943	0x7065	# <CJK>
+0x4944	0x706C	# <CJK>
+0x4945	0x706E	# <CJK>
+0x4946	0x7075	# <CJK>
+0x4947	0x7076	# <CJK>
+0x4948	0x707E	# <CJK>
+0x4949	0x7081	# <CJK>
+0x494A	0x7085	# <CJK>
+0x494B	0x7086	# <CJK>
+0x494C	0x7094	# <CJK>
+0x494D	0x7095	# <CJK>
+0x494E	0x7096	# <CJK>
+0x494F	0x7097	# <CJK>
+0x4950	0x7098	# <CJK>
+0x4951	0x709B	# <CJK>
+0x4952	0x70A4	# <CJK>
+0x4953	0x70AB	# <CJK>
+0x4954	0x70B0	# <CJK>
+0x4955	0x70B1	# <CJK>
+0x4956	0x70B4	# <CJK>
+0x4957	0x70B7	# <CJK>
+0x4958	0x70CA	# <CJK>
+0x4959	0x70D1	# <CJK>
+0x495A	0x70D3	# <CJK>
+0x495B	0x70D4	# <CJK>
+0x495C	0x70D5	# <CJK>
+0x495D	0x70D6	# <CJK>
+0x495E	0x70D8	# <CJK>
+0x495F	0x70DC	# <CJK>
+0x4960	0x70E4	# <CJK>
+0x4961	0x70FA	# <CJK>
+0x4962	0x7103	# <CJK>
+0x4963	0x7104	# <CJK>
+0x4964	0x7105	# <CJK>
+0x4965	0x7106	# <CJK>
+0x4966	0x7107	# <CJK>
+0x4967	0x710B	# <CJK>
+0x4968	0x710C	# <CJK>
+0x4969	0x710F	# <CJK>
+0x496A	0x711E	# <CJK>
+0x496B	0x7120	# <CJK>
+0x496C	0x712B	# <CJK>
+0x496D	0x712D	# <CJK>
+0x496E	0x712F	# <CJK>
+0x496F	0x7130	# <CJK>
+0x4970	0x7131	# <CJK>
+0x4971	0x7138	# <CJK>
+0x4972	0x7141	# <CJK>
+0x4973	0x7145	# <CJK>
+0x4974	0x7146	# <CJK>
+0x4975	0x7147	# <CJK>
+0x4976	0x714A	# <CJK>
+0x4977	0x714B	# <CJK>
+0x4978	0x7150	# <CJK>
+0x4979	0x7152	# <CJK>
+0x497A	0x7157	# <CJK>
+0x497B	0x715A	# <CJK>
+0x497C	0x715C	# <CJK>
+0x497D	0x715E	# <CJK>
+0x497E	0x7160	# <CJK>
+0x4A21	0x7168	# <CJK>
+0x4A22	0x7179	# <CJK>
+0x4A23	0x7180	# <CJK>
+0x4A24	0x7185	# <CJK>
+0x4A25	0x7187	# <CJK>
+0x4A26	0x718C	# <CJK>
+0x4A27	0x7192	# <CJK>
+0x4A28	0x719A	# <CJK>
+0x4A29	0x719B	# <CJK>
+0x4A2A	0x71A0	# <CJK>
+0x4A2B	0x71A2	# <CJK>
+0x4A2C	0x71AF	# <CJK>
+0x4A2D	0x71B0	# <CJK>
+0x4A2E	0x71B2	# <CJK>
+0x4A2F	0x71B3	# <CJK>
+0x4A30	0x71BA	# <CJK>
+0x4A31	0x71BF	# <CJK>
+0x4A32	0x71C0	# <CJK>
+0x4A33	0x71C1	# <CJK>
+0x4A34	0x71C4	# <CJK>
+0x4A35	0x71CB	# <CJK>
+0x4A36	0x71CC	# <CJK>
+0x4A37	0x71D3	# <CJK>
+0x4A38	0x71D6	# <CJK>
+0x4A39	0x71D9	# <CJK>
+0x4A3A	0x71DA	# <CJK>
+0x4A3B	0x71DC	# <CJK>
+0x4A3C	0x71F8	# <CJK>
+0x4A3D	0x71FE	# <CJK>
+0x4A3E	0x7200	# <CJK>
+0x4A3F	0x7207	# <CJK>
+0x4A40	0x7208	# <CJK>
+0x4A41	0x7209	# <CJK>
+0x4A42	0x7213	# <CJK>
+0x4A43	0x7217	# <CJK>
+0x4A44	0x721A	# <CJK>
+0x4A45	0x721D	# <CJK>
+0x4A46	0x721F	# <CJK>
+0x4A47	0x7224	# <CJK>
+0x4A48	0x722B	# <CJK>
+0x4A49	0x722F	# <CJK>
+0x4A4A	0x7234	# <CJK>
+0x4A4B	0x7238	# <CJK>
+0x4A4C	0x7239	# <CJK>
+0x4A4D	0x7241	# <CJK>
+0x4A4E	0x7242	# <CJK>
+0x4A4F	0x7243	# <CJK>
+0x4A50	0x7245	# <CJK>
+0x4A51	0x724E	# <CJK>
+0x4A52	0x724F	# <CJK>
+0x4A53	0x7250	# <CJK>
+0x4A54	0x7253	# <CJK>
+0x4A55	0x7255	# <CJK>
+0x4A56	0x7256	# <CJK>
+0x4A57	0x725A	# <CJK>
+0x4A58	0x725C	# <CJK>
+0x4A59	0x725E	# <CJK>
+0x4A5A	0x7260	# <CJK>
+0x4A5B	0x7263	# <CJK>
+0x4A5C	0x7268	# <CJK>
+0x4A5D	0x726B	# <CJK>
+0x4A5E	0x726E	# <CJK>
+0x4A5F	0x726F	# <CJK>
+0x4A60	0x7271	# <CJK>
+0x4A61	0x7277	# <CJK>
+0x4A62	0x7278	# <CJK>
+0x4A63	0x727B	# <CJK>
+0x4A64	0x727C	# <CJK>
+0x4A65	0x727F	# <CJK>
+0x4A66	0x7284	# <CJK>
+0x4A67	0x7289	# <CJK>
+0x4A68	0x728D	# <CJK>
+0x4A69	0x728E	# <CJK>
+0x4A6A	0x7293	# <CJK>
+0x4A6B	0x729B	# <CJK>
+0x4A6C	0x72A8	# <CJK>
+0x4A6D	0x72AD	# <CJK>
+0x4A6E	0x72AE	# <CJK>
+0x4A6F	0x72B1	# <CJK>
+0x4A70	0x72B4	# <CJK>
+0x4A71	0x72BE	# <CJK>
+0x4A72	0x72C1	# <CJK>
+0x4A73	0x72C7	# <CJK>
+0x4A74	0x72C9	# <CJK>
+0x4A75	0x72CC	# <CJK>
+0x4A76	0x72D5	# <CJK>
+0x4A77	0x72D6	# <CJK>
+0x4A78	0x72D8	# <CJK>
+0x4A79	0x72DF	# <CJK>
+0x4A7A	0x72E5	# <CJK>
+0x4A7B	0x72F3	# <CJK>
+0x4A7C	0x72F4	# <CJK>
+0x4A7D	0x72FA	# <CJK>
+0x4A7E	0x72FB	# <CJK>
+0x4B21	0x72FE	# <CJK>
+0x4B22	0x7302	# <CJK>
+0x4B23	0x7304	# <CJK>
+0x4B24	0x7305	# <CJK>
+0x4B25	0x7307	# <CJK>
+0x4B26	0x730B	# <CJK>
+0x4B27	0x730D	# <CJK>
+0x4B28	0x7312	# <CJK>
+0x4B29	0x7313	# <CJK>
+0x4B2A	0x7318	# <CJK>
+0x4B2B	0x7319	# <CJK>
+0x4B2C	0x731E	# <CJK>
+0x4B2D	0x7322	# <CJK>
+0x4B2E	0x7324	# <CJK>
+0x4B2F	0x7327	# <CJK>
+0x4B30	0x7328	# <CJK>
+0x4B31	0x732C	# <CJK>
+0x4B32	0x7331	# <CJK>
+0x4B33	0x7332	# <CJK>
+0x4B34	0x7335	# <CJK>
+0x4B35	0x733A	# <CJK>
+0x4B36	0x733B	# <CJK>
+0x4B37	0x733D	# <CJK>
+0x4B38	0x7343	# <CJK>
+0x4B39	0x734D	# <CJK>
+0x4B3A	0x7350	# <CJK>
+0x4B3B	0x7352	# <CJK>
+0x4B3C	0x7356	# <CJK>
+0x4B3D	0x7358	# <CJK>
+0x4B3E	0x735D	# <CJK>
+0x4B3F	0x735E	# <CJK>
+0x4B40	0x735F	# <CJK>
+0x4B41	0x7360	# <CJK>
+0x4B42	0x7366	# <CJK>
+0x4B43	0x7367	# <CJK>
+0x4B44	0x7369	# <CJK>
+0x4B45	0x736B	# <CJK>
+0x4B46	0x736C	# <CJK>
+0x4B47	0x736E	# <CJK>
+0x4B48	0x736F	# <CJK>
+0x4B49	0x7371	# <CJK>
+0x4B4A	0x7377	# <CJK>
+0x4B4B	0x7379	# <CJK>
+0x4B4C	0x737C	# <CJK>
+0x4B4D	0x7380	# <CJK>
+0x4B4E	0x7381	# <CJK>
+0x4B4F	0x7383	# <CJK>
+0x4B50	0x7385	# <CJK>
+0x4B51	0x7386	# <CJK>
+0x4B52	0x738E	# <CJK>
+0x4B53	0x7390	# <CJK>
+0x4B54	0x7393	# <CJK>
+0x4B55	0x7395	# <CJK>
+0x4B56	0x7397	# <CJK>
+0x4B57	0x7398	# <CJK>
+0x4B58	0x739C	# <CJK>
+0x4B59	0x739E	# <CJK>
+0x4B5A	0x739F	# <CJK>
+0x4B5B	0x73A0	# <CJK>
+0x4B5C	0x73A2	# <CJK>
+0x4B5D	0x73A5	# <CJK>
+0x4B5E	0x73A6	# <CJK>
+0x4B5F	0x73AA	# <CJK>
+0x4B60	0x73AB	# <CJK>
+0x4B61	0x73AD	# <CJK>
+0x4B62	0x73B5	# <CJK>
+0x4B63	0x73B7	# <CJK>
+0x4B64	0x73B9	# <CJK>
+0x4B65	0x73BC	# <CJK>
+0x4B66	0x73BD	# <CJK>
+0x4B67	0x73BF	# <CJK>
+0x4B68	0x73C5	# <CJK>
+0x4B69	0x73C6	# <CJK>
+0x4B6A	0x73C9	# <CJK>
+0x4B6B	0x73CB	# <CJK>
+0x4B6C	0x73CC	# <CJK>
+0x4B6D	0x73CF	# <CJK>
+0x4B6E	0x73D2	# <CJK>
+0x4B6F	0x73D3	# <CJK>
+0x4B70	0x73D6	# <CJK>
+0x4B71	0x73D9	# <CJK>
+0x4B72	0x73DD	# <CJK>
+0x4B73	0x73E1	# <CJK>
+0x4B74	0x73E3	# <CJK>
+0x4B75	0x73E6	# <CJK>
+0x4B76	0x73E7	# <CJK>
+0x4B77	0x73E9	# <CJK>
+0x4B78	0x73F4	# <CJK>
+0x4B79	0x73F5	# <CJK>
+0x4B7A	0x73F7	# <CJK>
+0x4B7B	0x73F9	# <CJK>
+0x4B7C	0x73FA	# <CJK>
+0x4B7D	0x73FB	# <CJK>
+0x4B7E	0x73FD	# <CJK>
+0x4C21	0x73FF	# <CJK>
+0x4C22	0x7400	# <CJK>
+0x4C23	0x7401	# <CJK>
+0x4C24	0x7404	# <CJK>
+0x4C25	0x7407	# <CJK>
+0x4C26	0x740A	# <CJK>
+0x4C27	0x7411	# <CJK>
+0x4C28	0x741A	# <CJK>
+0x4C29	0x741B	# <CJK>
+0x4C2A	0x7424	# <CJK>
+0x4C2B	0x7426	# <CJK>
+0x4C2C	0x7428	# <CJK>
+0x4C2D	0x7429	# <CJK>
+0x4C2E	0x742A	# <CJK>
+0x4C2F	0x742B	# <CJK>
+0x4C30	0x742C	# <CJK>
+0x4C31	0x742D	# <CJK>
+0x4C32	0x742E	# <CJK>
+0x4C33	0x742F	# <CJK>
+0x4C34	0x7430	# <CJK>
+0x4C35	0x7431	# <CJK>
+0x4C36	0x7439	# <CJK>
+0x4C37	0x7440	# <CJK>
+0x4C38	0x7443	# <CJK>
+0x4C39	0x7444	# <CJK>
+0x4C3A	0x7446	# <CJK>
+0x4C3B	0x7447	# <CJK>
+0x4C3C	0x744B	# <CJK>
+0x4C3D	0x744D	# <CJK>
+0x4C3E	0x7451	# <CJK>
+0x4C3F	0x7452	# <CJK>
+0x4C40	0x7457	# <CJK>
+0x4C41	0x745D	# <CJK>
+0x4C42	0x7462	# <CJK>
+0x4C43	0x7466	# <CJK>
+0x4C44	0x7467	# <CJK>
+0x4C45	0x7468	# <CJK>
+0x4C46	0x746B	# <CJK>
+0x4C47	0x746D	# <CJK>
+0x4C48	0x746E	# <CJK>
+0x4C49	0x7471	# <CJK>
+0x4C4A	0x7472	# <CJK>
+0x4C4B	0x7480	# <CJK>
+0x4C4C	0x7481	# <CJK>
+0x4C4D	0x7485	# <CJK>
+0x4C4E	0x7486	# <CJK>
+0x4C4F	0x7487	# <CJK>
+0x4C50	0x7489	# <CJK>
+0x4C51	0x748F	# <CJK>
+0x4C52	0x7490	# <CJK>
+0x4C53	0x7491	# <CJK>
+0x4C54	0x7492	# <CJK>
+0x4C55	0x7498	# <CJK>
+0x4C56	0x7499	# <CJK>
+0x4C57	0x749A	# <CJK>
+0x4C58	0x749C	# <CJK>
+0x4C59	0x749F	# <CJK>
+0x4C5A	0x74A0	# <CJK>
+0x4C5B	0x74A1	# <CJK>
+0x4C5C	0x74A3	# <CJK>
+0x4C5D	0x74A6	# <CJK>
+0x4C5E	0x74A8	# <CJK>
+0x4C5F	0x74A9	# <CJK>
+0x4C60	0x74AA	# <CJK>
+0x4C61	0x74AB	# <CJK>
+0x4C62	0x74AE	# <CJK>
+0x4C63	0x74AF	# <CJK>
+0x4C64	0x74B1	# <CJK>
+0x4C65	0x74B2	# <CJK>
+0x4C66	0x74B5	# <CJK>
+0x4C67	0x74B9	# <CJK>
+0x4C68	0x74BB	# <CJK>
+0x4C69	0x74BF	# <CJK>
+0x4C6A	0x74C8	# <CJK>
+0x4C6B	0x74C9	# <CJK>
+0x4C6C	0x74CC	# <CJK>
+0x4C6D	0x74D0	# <CJK>
+0x4C6E	0x74D3	# <CJK>
+0x4C6F	0x74D8	# <CJK>
+0x4C70	0x74DA	# <CJK>
+0x4C71	0x74DB	# <CJK>
+0x4C72	0x74DE	# <CJK>
+0x4C73	0x74DF	# <CJK>
+0x4C74	0x74E4	# <CJK>
+0x4C75	0x74E8	# <CJK>
+0x4C76	0x74EA	# <CJK>
+0x4C77	0x74EB	# <CJK>
+0x4C78	0x74EF	# <CJK>
+0x4C79	0x74F4	# <CJK>
+0x4C7A	0x74FA	# <CJK>
+0x4C7B	0x74FB	# <CJK>
+0x4C7C	0x74FC	# <CJK>
+0x4C7D	0x74FF	# <CJK>
+0x4C7E	0x7506	# <CJK>
+0x4D21	0x7512	# <CJK>
+0x4D22	0x7516	# <CJK>
+0x4D23	0x7517	# <CJK>
+0x4D24	0x7520	# <CJK>
+0x4D25	0x7521	# <CJK>
+0x4D26	0x7524	# <CJK>
+0x4D27	0x7527	# <CJK>
+0x4D28	0x7529	# <CJK>
+0x4D29	0x752A	# <CJK>
+0x4D2A	0x752F	# <CJK>
+0x4D2B	0x7536	# <CJK>
+0x4D2C	0x7539	# <CJK>
+0x4D2D	0x753D	# <CJK>
+0x4D2E	0x753E	# <CJK>
+0x4D2F	0x753F	# <CJK>
+0x4D30	0x7540	# <CJK>
+0x4D31	0x7543	# <CJK>
+0x4D32	0x7547	# <CJK>
+0x4D33	0x7548	# <CJK>
+0x4D34	0x754E	# <CJK>
+0x4D35	0x7550	# <CJK>
+0x4D36	0x7552	# <CJK>
+0x4D37	0x7557	# <CJK>
+0x4D38	0x755E	# <CJK>
+0x4D39	0x755F	# <CJK>
+0x4D3A	0x7561	# <CJK>
+0x4D3B	0x756F	# <CJK>
+0x4D3C	0x7571	# <CJK>
+0x4D3D	0x7579	# <CJK>
+0x4D3E	0x757A	# <CJK>
+0x4D3F	0x757B	# <CJK>
+0x4D40	0x757C	# <CJK>
+0x4D41	0x757D	# <CJK>
+0x4D42	0x757E	# <CJK>
+0x4D43	0x7581	# <CJK>
+0x4D44	0x7585	# <CJK>
+0x4D45	0x7590	# <CJK>
+0x4D46	0x7592	# <CJK>
+0x4D47	0x7593	# <CJK>
+0x4D48	0x7595	# <CJK>
+0x4D49	0x7599	# <CJK>
+0x4D4A	0x759C	# <CJK>
+0x4D4B	0x75A2	# <CJK>
+0x4D4C	0x75A4	# <CJK>
+0x4D4D	0x75B4	# <CJK>
+0x4D4E	0x75BA	# <CJK>
+0x4D4F	0x75BF	# <CJK>
+0x4D50	0x75C0	# <CJK>
+0x4D51	0x75C1	# <CJK>
+0x4D52	0x75C4	# <CJK>
+0x4D53	0x75C6	# <CJK>
+0x4D54	0x75CC	# <CJK>
+0x4D55	0x75CE	# <CJK>
+0x4D56	0x75CF	# <CJK>
+0x4D57	0x75D7	# <CJK>
+0x4D58	0x75DC	# <CJK>
+0x4D59	0x75DF	# <CJK>
+0x4D5A	0x75E0	# <CJK>
+0x4D5B	0x75E1	# <CJK>
+0x4D5C	0x75E4	# <CJK>
+0x4D5D	0x75E7	# <CJK>
+0x4D5E	0x75EC	# <CJK>
+0x4D5F	0x75EE	# <CJK>
+0x4D60	0x75EF	# <CJK>
+0x4D61	0x75F1	# <CJK>
+0x4D62	0x75F9	# <CJK>
+0x4D63	0x7600	# <CJK>
+0x4D64	0x7602	# <CJK>
+0x4D65	0x7603	# <CJK>
+0x4D66	0x7604	# <CJK>
+0x4D67	0x7607	# <CJK>
+0x4D68	0x7608	# <CJK>
+0x4D69	0x760A	# <CJK>
+0x4D6A	0x760C	# <CJK>
+0x4D6B	0x760F	# <CJK>
+0x4D6C	0x7612	# <CJK>
+0x4D6D	0x7613	# <CJK>
+0x4D6E	0x7615	# <CJK>
+0x4D6F	0x7616	# <CJK>
+0x4D70	0x7619	# <CJK>
+0x4D71	0x761B	# <CJK>
+0x4D72	0x761C	# <CJK>
+0x4D73	0x761D	# <CJK>
+0x4D74	0x761E	# <CJK>
+0x4D75	0x7623	# <CJK>
+0x4D76	0x7625	# <CJK>
+0x4D77	0x7626	# <CJK>
+0x4D78	0x7629	# <CJK>
+0x4D79	0x762D	# <CJK>
+0x4D7A	0x7632	# <CJK>
+0x4D7B	0x7633	# <CJK>
+0x4D7C	0x7635	# <CJK>
+0x4D7D	0x7638	# <CJK>
+0x4D7E	0x7639	# <CJK>
+0x4E21	0x763A	# <CJK>
+0x4E22	0x763C	# <CJK>
+0x4E23	0x764A	# <CJK>
+0x4E24	0x7640	# <CJK>
+0x4E25	0x7641	# <CJK>
+0x4E26	0x7643	# <CJK>
+0x4E27	0x7644	# <CJK>
+0x4E28	0x7645	# <CJK>
+0x4E29	0x7649	# <CJK>
+0x4E2A	0x764B	# <CJK>
+0x4E2B	0x7655	# <CJK>
+0x4E2C	0x7659	# <CJK>
+0x4E2D	0x765F	# <CJK>
+0x4E2E	0x7664	# <CJK>
+0x4E2F	0x7665	# <CJK>
+0x4E30	0x766D	# <CJK>
+0x4E31	0x766E	# <CJK>
+0x4E32	0x766F	# <CJK>
+0x4E33	0x7671	# <CJK>
+0x4E34	0x7674	# <CJK>
+0x4E35	0x7681	# <CJK>
+0x4E36	0x7685	# <CJK>
+0x4E37	0x768C	# <CJK>
+0x4E38	0x768D	# <CJK>
+0x4E39	0x7695	# <CJK>
+0x4E3A	0x769B	# <CJK>
+0x4E3B	0x769C	# <CJK>
+0x4E3C	0x769D	# <CJK>
+0x4E3D	0x769F	# <CJK>
+0x4E3E	0x76A0	# <CJK>
+0x4E3F	0x76A2	# <CJK>
+0x4E40	0x76A3	# <CJK>
+0x4E41	0x76A4	# <CJK>
+0x4E42	0x76A5	# <CJK>
+0x4E43	0x76A6	# <CJK>
+0x4E44	0x76A7	# <CJK>
+0x4E45	0x76A8	# <CJK>
+0x4E46	0x76AA	# <CJK>
+0x4E47	0x76AD	# <CJK>
+0x4E48	0x76BD	# <CJK>
+0x4E49	0x76C1	# <CJK>
+0x4E4A	0x76C5	# <CJK>
+0x4E4B	0x76C9	# <CJK>
+0x4E4C	0x76CB	# <CJK>
+0x4E4D	0x76CC	# <CJK>
+0x4E4E	0x76CE	# <CJK>
+0x4E4F	0x76D4	# <CJK>
+0x4E50	0x76D9	# <CJK>
+0x4E51	0x76E0	# <CJK>
+0x4E52	0x76E6	# <CJK>
+0x4E53	0x76E8	# <CJK>
+0x4E54	0x76EC	# <CJK>
+0x4E55	0x76F0	# <CJK>
+0x4E56	0x76F1	# <CJK>
+0x4E57	0x76F6	# <CJK>
+0x4E58	0x76F9	# <CJK>
+0x4E59	0x76FC	# <CJK>
+0x4E5A	0x7700	# <CJK>
+0x4E5B	0x7706	# <CJK>
+0x4E5C	0x770A	# <CJK>
+0x4E5D	0x770E	# <CJK>
+0x4E5E	0x7712	# <CJK>
+0x4E5F	0x7714	# <CJK>
+0x4E60	0x7715	# <CJK>
+0x4E61	0x7717	# <CJK>
+0x4E62	0x7719	# <CJK>
+0x4E63	0x771A	# <CJK>
+0x4E64	0x771C	# <CJK>
+0x4E65	0x7722	# <CJK>
+0x4E66	0x7728	# <CJK>
+0x4E67	0x772D	# <CJK>
+0x4E68	0x772E	# <CJK>
+0x4E69	0x772F	# <CJK>
+0x4E6A	0x7734	# <CJK>
+0x4E6B	0x7735	# <CJK>
+0x4E6C	0x7736	# <CJK>
+0x4E6D	0x7739	# <CJK>
+0x4E6E	0x773D	# <CJK>
+0x4E6F	0x773E	# <CJK>
+0x4E70	0x7742	# <CJK>
+0x4E71	0x7745	# <CJK>
+0x4E72	0x7746	# <CJK>
+0x4E73	0x774A	# <CJK>
+0x4E74	0x774D	# <CJK>
+0x4E75	0x774E	# <CJK>
+0x4E76	0x774F	# <CJK>
+0x4E77	0x7752	# <CJK>
+0x4E78	0x7756	# <CJK>
+0x4E79	0x7757	# <CJK>
+0x4E7A	0x775C	# <CJK>
+0x4E7B	0x775E	# <CJK>
+0x4E7C	0x775F	# <CJK>
+0x4E7D	0x7760	# <CJK>
+0x4E7E	0x7762	# <CJK>
+0x4F21	0x7764	# <CJK>
+0x4F22	0x7767	# <CJK>
+0x4F23	0x776A	# <CJK>
+0x4F24	0x776C	# <CJK>
+0x4F25	0x7770	# <CJK>
+0x4F26	0x7772	# <CJK>
+0x4F27	0x7773	# <CJK>
+0x4F28	0x7774	# <CJK>
+0x4F29	0x777A	# <CJK>
+0x4F2A	0x777D	# <CJK>
+0x4F2B	0x7780	# <CJK>
+0x4F2C	0x7784	# <CJK>
+0x4F2D	0x778C	# <CJK>
+0x4F2E	0x778D	# <CJK>
+0x4F2F	0x7794	# <CJK>
+0x4F30	0x7795	# <CJK>
+0x4F31	0x7796	# <CJK>
+0x4F32	0x779A	# <CJK>
+0x4F33	0x779F	# <CJK>
+0x4F34	0x77A2	# <CJK>
+0x4F35	0x77A7	# <CJK>
+0x4F36	0x77AA	# <CJK>
+0x4F37	0x77AE	# <CJK>
+0x4F38	0x77AF	# <CJK>
+0x4F39	0x77B1	# <CJK>
+0x4F3A	0x77B5	# <CJK>
+0x4F3B	0x77BE	# <CJK>
+0x4F3C	0x77C3	# <CJK>
+0x4F3D	0x77C9	# <CJK>
+0x4F3E	0x77D1	# <CJK>
+0x4F3F	0x77D2	# <CJK>
+0x4F40	0x77D5	# <CJK>
+0x4F41	0x77D9	# <CJK>
+0x4F42	0x77DE	# <CJK>
+0x4F43	0x77DF	# <CJK>
+0x4F44	0x77E0	# <CJK>
+0x4F45	0x77E4	# <CJK>
+0x4F46	0x77E6	# <CJK>
+0x4F47	0x77EA	# <CJK>
+0x4F48	0x77EC	# <CJK>
+0x4F49	0x77F0	# <CJK>
+0x4F4A	0x77F1	# <CJK>
+0x4F4B	0x77F4	# <CJK>
+0x4F4C	0x77F8	# <CJK>
+0x4F4D	0x77FB	# <CJK>
+0x4F4E	0x7805	# <CJK>
+0x4F4F	0x7806	# <CJK>
+0x4F50	0x7809	# <CJK>
+0x4F51	0x780D	# <CJK>
+0x4F52	0x780E	# <CJK>
+0x4F53	0x7811	# <CJK>
+0x4F54	0x781D	# <CJK>
+0x4F55	0x7821	# <CJK>
+0x4F56	0x7822	# <CJK>
+0x4F57	0x7823	# <CJK>
+0x4F58	0x782D	# <CJK>
+0x4F59	0x782E	# <CJK>
+0x4F5A	0x7830	# <CJK>
+0x4F5B	0x7835	# <CJK>
+0x4F5C	0x7837	# <CJK>
+0x4F5D	0x7843	# <CJK>
+0x4F5E	0x7844	# <CJK>
+0x4F5F	0x7847	# <CJK>
+0x4F60	0x7848	# <CJK>
+0x4F61	0x784C	# <CJK>
+0x4F62	0x784E	# <CJK>
+0x4F63	0x7852	# <CJK>
+0x4F64	0x785C	# <CJK>
+0x4F65	0x785E	# <CJK>
+0x4F66	0x7860	# <CJK>
+0x4F67	0x7861	# <CJK>
+0x4F68	0x7863	# <CJK>
+0x4F69	0x7864	# <CJK>
+0x4F6A	0x7868	# <CJK>
+0x4F6B	0x786A	# <CJK>
+0x4F6C	0x786E	# <CJK>
+0x4F6D	0x787A	# <CJK>
+0x4F6E	0x787E	# <CJK>
+0x4F6F	0x788A	# <CJK>
+0x4F70	0x788F	# <CJK>
+0x4F71	0x7894	# <CJK>
+0x4F72	0x7898	# <CJK>
+0x4F73	0x78A1	# <CJK>
+0x4F74	0x789D	# <CJK>
+0x4F75	0x789E	# <CJK>
+0x4F76	0x789F	# <CJK>
+0x4F77	0x78A4	# <CJK>
+0x4F78	0x78A8	# <CJK>
+0x4F79	0x78AC	# <CJK>
+0x4F7A	0x78AD	# <CJK>
+0x4F7B	0x78B0	# <CJK>
+0x4F7C	0x78B1	# <CJK>
+0x4F7D	0x78B2	# <CJK>
+0x4F7E	0x78B3	# <CJK>
+0x5021	0x78BB	# <CJK>
+0x5022	0x78BD	# <CJK>
+0x5023	0x78BF	# <CJK>
+0x5024	0x78C7	# <CJK>
+0x5025	0x78C8	# <CJK>
+0x5026	0x78C9	# <CJK>
+0x5027	0x78CC	# <CJK>
+0x5028	0x78CE	# <CJK>
+0x5029	0x78D2	# <CJK>
+0x502A	0x78D3	# <CJK>
+0x502B	0x78D5	# <CJK>
+0x502C	0x78D6	# <CJK>
+0x502D	0x78E4	# <CJK>
+0x502E	0x78DB	# <CJK>
+0x502F	0x78DF	# <CJK>
+0x5030	0x78E0	# <CJK>
+0x5031	0x78E1	# <CJK>
+0x5032	0x78E6	# <CJK>
+0x5033	0x78EA	# <CJK>
+0x5034	0x78F2	# <CJK>
+0x5035	0x78F3	# <CJK>
+0x5036	0x7900	# <CJK>
+0x5037	0x78F6	# <CJK>
+0x5038	0x78F7	# <CJK>
+0x5039	0x78FA	# <CJK>
+0x503A	0x78FB	# <CJK>
+0x503B	0x78FF	# <CJK>
+0x503C	0x7906	# <CJK>
+0x503D	0x790C	# <CJK>
+0x503E	0x7910	# <CJK>
+0x503F	0x791A	# <CJK>
+0x5040	0x791C	# <CJK>
+0x5041	0x791E	# <CJK>
+0x5042	0x791F	# <CJK>
+0x5043	0x7920	# <CJK>
+0x5044	0x7925	# <CJK>
+0x5045	0x7927	# <CJK>
+0x5046	0x7929	# <CJK>
+0x5047	0x792D	# <CJK>
+0x5048	0x7931	# <CJK>
+0x5049	0x7934	# <CJK>
+0x504A	0x7935	# <CJK>
+0x504B	0x793B	# <CJK>
+0x504C	0x793D	# <CJK>
+0x504D	0x793F	# <CJK>
+0x504E	0x7944	# <CJK>
+0x504F	0x7945	# <CJK>
+0x5050	0x7946	# <CJK>
+0x5051	0x794A	# <CJK>
+0x5052	0x794B	# <CJK>
+0x5053	0x794F	# <CJK>
+0x5054	0x7951	# <CJK>
+0x5055	0x7954	# <CJK>
+0x5056	0x7958	# <CJK>
+0x5057	0x795B	# <CJK>
+0x5058	0x795C	# <CJK>
+0x5059	0x7967	# <CJK>
+0x505A	0x7969	# <CJK>
+0x505B	0x796B	# <CJK>
+0x505C	0x7972	# <CJK>
+0x505D	0x7979	# <CJK>
+0x505E	0x797B	# <CJK>
+0x505F	0x797C	# <CJK>
+0x5060	0x797E	# <CJK>
+0x5061	0x798B	# <CJK>
+0x5062	0x798C	# <CJK>
+0x5063	0x7991	# <CJK>
+0x5064	0x7993	# <CJK>
+0x5065	0x7994	# <CJK>
+0x5066	0x7995	# <CJK>
+0x5067	0x7996	# <CJK>
+0x5068	0x7998	# <CJK>
+0x5069	0x799B	# <CJK>
+0x506A	0x799C	# <CJK>
+0x506B	0x79A1	# <CJK>
+0x506C	0x79A8	# <CJK>
+0x506D	0x79A9	# <CJK>
+0x506E	0x79AB	# <CJK>
+0x506F	0x79AF	# <CJK>
+0x5070	0x79B1	# <CJK>
+0x5071	0x79B4	# <CJK>
+0x5072	0x79B8	# <CJK>
+0x5073	0x79BB	# <CJK>
+0x5074	0x79C2	# <CJK>
+0x5075	0x79C4	# <CJK>
+0x5076	0x79C7	# <CJK>
+0x5077	0x79C8	# <CJK>
+0x5078	0x79CA	# <CJK>
+0x5079	0x79CF	# <CJK>
+0x507A	0x79D4	# <CJK>
+0x507B	0x79D6	# <CJK>
+0x507C	0x79DA	# <CJK>
+0x507D	0x79DD	# <CJK>
+0x507E	0x79DE	# <CJK>
+0x5121	0x79E0	# <CJK>
+0x5122	0x79E2	# <CJK>
+0x5123	0x79E5	# <CJK>
+0x5124	0x79EA	# <CJK>
+0x5125	0x79EB	# <CJK>
+0x5126	0x79ED	# <CJK>
+0x5127	0x79F1	# <CJK>
+0x5128	0x79F8	# <CJK>
+0x5129	0x79FC	# <CJK>
+0x512A	0x7A02	# <CJK>
+0x512B	0x7A03	# <CJK>
+0x512C	0x7A07	# <CJK>
+0x512D	0x7A09	# <CJK>
+0x512E	0x7A0A	# <CJK>
+0x512F	0x7A0C	# <CJK>
+0x5130	0x7A11	# <CJK>
+0x5131	0x7A15	# <CJK>
+0x5132	0x7A1B	# <CJK>
+0x5133	0x7A1E	# <CJK>
+0x5134	0x7A21	# <CJK>
+0x5135	0x7A27	# <CJK>
+0x5136	0x7A2B	# <CJK>
+0x5137	0x7A2D	# <CJK>
+0x5138	0x7A2F	# <CJK>
+0x5139	0x7A30	# <CJK>
+0x513A	0x7A34	# <CJK>
+0x513B	0x7A35	# <CJK>
+0x513C	0x7A38	# <CJK>
+0x513D	0x7A39	# <CJK>
+0x513E	0x7A3A	# <CJK>
+0x513F	0x7A44	# <CJK>
+0x5140	0x7A45	# <CJK>
+0x5141	0x7A47	# <CJK>
+0x5142	0x7A48	# <CJK>
+0x5143	0x7A4C	# <CJK>
+0x5144	0x7A55	# <CJK>
+0x5145	0x7A56	# <CJK>
+0x5146	0x7A59	# <CJK>
+0x5147	0x7A5C	# <CJK>
+0x5148	0x7A5D	# <CJK>
+0x5149	0x7A5F	# <CJK>
+0x514A	0x7A60	# <CJK>
+0x514B	0x7A65	# <CJK>
+0x514C	0x7A67	# <CJK>
+0x514D	0x7A6A	# <CJK>
+0x514E	0x7A6D	# <CJK>
+0x514F	0x7A75	# <CJK>
+0x5150	0x7A78	# <CJK>
+0x5151	0x7A7E	# <CJK>
+0x5152	0x7A80	# <CJK>
+0x5153	0x7A82	# <CJK>
+0x5154	0x7A85	# <CJK>
+0x5155	0x7A86	# <CJK>
+0x5156	0x7A8A	# <CJK>
+0x5157	0x7A8B	# <CJK>
+0x5158	0x7A90	# <CJK>
+0x5159	0x7A91	# <CJK>
+0x515A	0x7A94	# <CJK>
+0x515B	0x7A9E	# <CJK>
+0x515C	0x7AA0	# <CJK>
+0x515D	0x7AA3	# <CJK>
+0x515E	0x7AAC	# <CJK>
+0x515F	0x7AB3	# <CJK>
+0x5160	0x7AB5	# <CJK>
+0x5161	0x7AB9	# <CJK>
+0x5162	0x7ABB	# <CJK>
+0x5163	0x7ABC	# <CJK>
+0x5164	0x7AC6	# <CJK>
+0x5165	0x7AC9	# <CJK>
+0x5166	0x7ACC	# <CJK>
+0x5167	0x7ACE	# <CJK>
+0x5168	0x7AD1	# <CJK>
+0x5169	0x7ADB	# <CJK>
+0x516A	0x7AE8	# <CJK>
+0x516B	0x7AE9	# <CJK>
+0x516C	0x7AEB	# <CJK>
+0x516D	0x7AEC	# <CJK>
+0x516E	0x7AF1	# <CJK>
+0x516F	0x7AF4	# <CJK>
+0x5170	0x7AFB	# <CJK>
+0x5171	0x7AFD	# <CJK>
+0x5172	0x7AFE	# <CJK>
+0x5173	0x7B07	# <CJK>
+0x5174	0x7B14	# <CJK>
+0x5175	0x7B1F	# <CJK>
+0x5176	0x7B23	# <CJK>
+0x5177	0x7B27	# <CJK>
+0x5178	0x7B29	# <CJK>
+0x5179	0x7B2A	# <CJK>
+0x517A	0x7B2B	# <CJK>
+0x517B	0x7B2D	# <CJK>
+0x517C	0x7B2E	# <CJK>
+0x517D	0x7B2F	# <CJK>
+0x517E	0x7B30	# <CJK>
+0x5221	0x7B31	# <CJK>
+0x5222	0x7B34	# <CJK>
+0x5223	0x7B3D	# <CJK>
+0x5224	0x7B3F	# <CJK>
+0x5225	0x7B40	# <CJK>
+0x5226	0x7B41	# <CJK>
+0x5227	0x7B47	# <CJK>
+0x5228	0x7B4E	# <CJK>
+0x5229	0x7B55	# <CJK>
+0x522A	0x7B60	# <CJK>
+0x522B	0x7B64	# <CJK>
+0x522C	0x7B66	# <CJK>
+0x522D	0x7B69	# <CJK>
+0x522E	0x7B6A	# <CJK>
+0x522F	0x7B6D	# <CJK>
+0x5230	0x7B6F	# <CJK>
+0x5231	0x7B72	# <CJK>
+0x5232	0x7B73	# <CJK>
+0x5233	0x7B77	# <CJK>
+0x5234	0x7B84	# <CJK>
+0x5235	0x7B89	# <CJK>
+0x5236	0x7B8E	# <CJK>
+0x5237	0x7B90	# <CJK>
+0x5238	0x7B91	# <CJK>
+0x5239	0x7B96	# <CJK>
+0x523A	0x7B9B	# <CJK>
+0x523B	0x7B9E	# <CJK>
+0x523C	0x7BA0	# <CJK>
+0x523D	0x7BA5	# <CJK>
+0x523E	0x7BAC	# <CJK>
+0x523F	0x7BAF	# <CJK>
+0x5240	0x7BB0	# <CJK>
+0x5241	0x7BB2	# <CJK>
+0x5242	0x7BB5	# <CJK>
+0x5243	0x7BB6	# <CJK>
+0x5244	0x7BBA	# <CJK>
+0x5245	0x7BBB	# <CJK>
+0x5246	0x7BBC	# <CJK>
+0x5247	0x7BBD	# <CJK>
+0x5248	0x7BC2	# <CJK>
+0x5249	0x7BC5	# <CJK>
+0x524A	0x7BC8	# <CJK>
+0x524B	0x7BCA	# <CJK>
+0x524C	0x7BD4	# <CJK>
+0x524D	0x7BD6	# <CJK>
+0x524E	0x7BD7	# <CJK>
+0x524F	0x7BD9	# <CJK>
+0x5250	0x7BDA	# <CJK>
+0x5251	0x7BDB	# <CJK>
+0x5252	0x7BE8	# <CJK>
+0x5253	0x7BEA	# <CJK>
+0x5254	0x7BF2	# <CJK>
+0x5255	0x7BF4	# <CJK>
+0x5256	0x7BF5	# <CJK>
+0x5257	0x7BF8	# <CJK>
+0x5258	0x7BF9	# <CJK>
+0x5259	0x7BFA	# <CJK>
+0x525A	0x7BFC	# <CJK>
+0x525B	0x7BFE	# <CJK>
+0x525C	0x7C01	# <CJK>
+0x525D	0x7C02	# <CJK>
+0x525E	0x7C03	# <CJK>
+0x525F	0x7C04	# <CJK>
+0x5260	0x7C06	# <CJK>
+0x5261	0x7C09	# <CJK>
+0x5262	0x7C0B	# <CJK>
+0x5263	0x7C0C	# <CJK>
+0x5264	0x7C0E	# <CJK>
+0x5265	0x7C0F	# <CJK>
+0x5266	0x7C19	# <CJK>
+0x5267	0x7C1B	# <CJK>
+0x5268	0x7C20	# <CJK>
+0x5269	0x7C25	# <CJK>
+0x526A	0x7C26	# <CJK>
+0x526B	0x7C28	# <CJK>
+0x526C	0x7C2C	# <CJK>
+0x526D	0x7C31	# <CJK>
+0x526E	0x7C33	# <CJK>
+0x526F	0x7C34	# <CJK>
+0x5270	0x7C36	# <CJK>
+0x5271	0x7C39	# <CJK>
+0x5272	0x7C3A	# <CJK>
+0x5273	0x7C46	# <CJK>
+0x5274	0x7C4A	# <CJK>
+0x5275	0x7C55	# <CJK>
+0x5276	0x7C51	# <CJK>
+0x5277	0x7C52	# <CJK>
+0x5278	0x7C53	# <CJK>
+0x5279	0x7C59	# <CJK>
+0x527A	0x7C5A	# <CJK>
+0x527B	0x7C5B	# <CJK>
+0x527C	0x7C5C	# <CJK>
+0x527D	0x7C5D	# <CJK>
+0x527E	0x7C5E	# <CJK>
+0x5321	0x7C61	# <CJK>
+0x5322	0x7C63	# <CJK>
+0x5323	0x7C67	# <CJK>
+0x5324	0x7C69	# <CJK>
+0x5325	0x7C6D	# <CJK>
+0x5326	0x7C6E	# <CJK>
+0x5327	0x7C70	# <CJK>
+0x5328	0x7C72	# <CJK>
+0x5329	0x7C79	# <CJK>
+0x532A	0x7C7C	# <CJK>
+0x532B	0x7C7D	# <CJK>
+0x532C	0x7C86	# <CJK>
+0x532D	0x7C87	# <CJK>
+0x532E	0x7C8F	# <CJK>
+0x532F	0x7C94	# <CJK>
+0x5330	0x7C9E	# <CJK>
+0x5331	0x7CA0	# <CJK>
+0x5332	0x7CA6	# <CJK>
+0x5333	0x7CB0	# <CJK>
+0x5334	0x7CB6	# <CJK>
+0x5335	0x7CB7	# <CJK>
+0x5336	0x7CBA	# <CJK>
+0x5337	0x7CBB	# <CJK>
+0x5338	0x7CBC	# <CJK>
+0x5339	0x7CBF	# <CJK>
+0x533A	0x7CC4	# <CJK>
+0x533B	0x7CC7	# <CJK>
+0x533C	0x7CC8	# <CJK>
+0x533D	0x7CC9	# <CJK>
+0x533E	0x7CCD	# <CJK>
+0x533F	0x7CCF	# <CJK>
+0x5340	0x7CD3	# <CJK>
+0x5341	0x7CD4	# <CJK>
+0x5342	0x7CD5	# <CJK>
+0x5343	0x7CD7	# <CJK>
+0x5344	0x7CD9	# <CJK>
+0x5345	0x7CDA	# <CJK>
+0x5346	0x7CDD	# <CJK>
+0x5347	0x7CE6	# <CJK>
+0x5348	0x7CE9	# <CJK>
+0x5349	0x7CEB	# <CJK>
+0x534A	0x7CF5	# <CJK>
+0x534B	0x7D03	# <CJK>
+0x534C	0x7D07	# <CJK>
+0x534D	0x7D08	# <CJK>
+0x534E	0x7D09	# <CJK>
+0x534F	0x7D0F	# <CJK>
+0x5350	0x7D11	# <CJK>
+0x5351	0x7D12	# <CJK>
+0x5352	0x7D13	# <CJK>
+0x5353	0x7D16	# <CJK>
+0x5354	0x7D1D	# <CJK>
+0x5355	0x7D1E	# <CJK>
+0x5356	0x7D23	# <CJK>
+0x5357	0x7D26	# <CJK>
+0x5358	0x7D2A	# <CJK>
+0x5359	0x7D2D	# <CJK>
+0x535A	0x7D31	# <CJK>
+0x535B	0x7D3C	# <CJK>
+0x535C	0x7D3D	# <CJK>
+0x535D	0x7D3E	# <CJK>
+0x535E	0x7D40	# <CJK>
+0x535F	0x7D41	# <CJK>
+0x5360	0x7D47	# <CJK>
+0x5361	0x7D48	# <CJK>
+0x5362	0x7D4D	# <CJK>
+0x5363	0x7D51	# <CJK>
+0x5364	0x7D53	# <CJK>
+0x5365	0x7D57	# <CJK>
+0x5366	0x7D59	# <CJK>
+0x5367	0x7D5A	# <CJK>
+0x5368	0x7D5C	# <CJK>
+0x5369	0x7D5D	# <CJK>
+0x536A	0x7D65	# <CJK>
+0x536B	0x7D67	# <CJK>
+0x536C	0x7D6A	# <CJK>
+0x536D	0x7D70	# <CJK>
+0x536E	0x7D78	# <CJK>
+0x536F	0x7D7A	# <CJK>
+0x5370	0x7D7B	# <CJK>
+0x5371	0x7D7F	# <CJK>
+0x5372	0x7D81	# <CJK>
+0x5373	0x7D82	# <CJK>
+0x5374	0x7D83	# <CJK>
+0x5375	0x7D85	# <CJK>
+0x5376	0x7D86	# <CJK>
+0x5377	0x7D88	# <CJK>
+0x5378	0x7D8B	# <CJK>
+0x5379	0x7D8C	# <CJK>
+0x537A	0x7D8D	# <CJK>
+0x537B	0x7D91	# <CJK>
+0x537C	0x7D96	# <CJK>
+0x537D	0x7D97	# <CJK>
+0x537E	0x7D9D	# <CJK>
+0x5421	0x7D9E	# <CJK>
+0x5422	0x7DA6	# <CJK>
+0x5423	0x7DA7	# <CJK>
+0x5424	0x7DAA	# <CJK>
+0x5425	0x7DB3	#